add Tizen ARM reference patches devel/v3.10-ltsi
authorMyungJoo Ham <myungjoo.ham@samsung.com>
Thu, 20 Mar 2014 06:29:15 +0000 (15:29 +0900)
committerMyungJoo Ham <myungjoo.ham@samsung.com>
Thu, 20 Mar 2014 06:29:15 +0000 (15:29 +0900)
- Imported 20140319.065243:
author Jonghwa Lee <jonghwa3.lee@samsung.com>
Wed, 19 Mar 2014 00:55:10 +0900 (00:55 +0900)
committer Jonghwa Lee <jonghwa3.lee@samsung.com>
Wed, 19 Mar 2014 01:13:40 +0900 (01:13 +0900)
commit 7464f7e4fed02c10aa619746890bdd96b1b43fc3

Based on Linux 3.10.19 LTS.

Change-Id: I17572de4952319a6815c18379bdbe35b1db0a88c
Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
1302 files changed:
patches.tizen/0001-ARM-EXYNOS-Fail-l2x0-cache-initialization-if-DT-base.patch [new file with mode: 0644]
patches.tizen/0002-ARM-EXYNOS-Add-secure-firmware-support-to-l2x0-initi.patch [new file with mode: 0644]
patches.tizen/0003-ARM-dts-exynos4-Add-DT-nodes-for-L2-cache-controller.patch [new file with mode: 0644]
patches.tizen/0004-fs-jbd2-force-commit-to-free-jbd2-s-cma-isolated-pag.patch [new file with mode: 0644]
patches.tizen/0005-fs-buffer.c-Revoke-LRU-when-trying-to-drop-buffers.patch [new file with mode: 0644]
patches.tizen/0006-mm-cma-allocate-pages-from-CMA-if-NR_FREE_PAGES-appr.patch [new file with mode: 0644]
patches.tizen/0007-usb-gadget-s3c-hsotg-Add-device-tree-based-instantia.patch [new file with mode: 0644]
patches.tizen/0008-usb-phy-samsung-Select-common-driver-part-implicitly.patch [new file with mode: 0644]
patches.tizen/0009-usb-phy-samsung-Use-clk_get-to-get-reference-clock.patch [new file with mode: 0644]
patches.tizen/0010-usb-phy-samsung-Consolidate-reference-clock-rate-han.patch [new file with mode: 0644]
patches.tizen/0011-usb-phy-samsung-Pass-set_isolation-callback-through-.patch [new file with mode: 0644]
patches.tizen/0012-usb-phy-samsung-Pass-enable-disable-callbacks-throug.patch [new file with mode: 0644]
patches.tizen/0013-usb-phy-samsung-Add-support-for-USB-2.0-PHY-on-Exyno.patch [new file with mode: 0644]
patches.tizen/0014-ARM-dts-exynos4-Add-node-for-hsotg.patch [new file with mode: 0644]
patches.tizen/0015-iommu-exynos-do-not-include-removed-header.patch [new file with mode: 0644]
patches.tizen/0016-iommu-exynos-add-missing-cache-flush-for-removed-pag.patch [new file with mode: 0644]
patches.tizen/0017-iommu-exynos-fix-page-table-maintenance.patch [new file with mode: 0644]
patches.tizen/0018-iommu-exynos-allocate-lv2-page-table-from-own-slab.patch [new file with mode: 0644]
patches.tizen/0019-clk-exynos5250-add-gate-clock-descriptions-of-System.patch [new file with mode: 0644]
patches.tizen/0020-ARM-dts-Add-description-of-System-MMU-of-Exynos-SoCs.patch [new file with mode: 0644]
patches.tizen/0021-iommu-exynos-support-for-device-tree.patch [new file with mode: 0644]
patches.tizen/0022-iommu-exynos-remove-prefetch-buffer-setting-when-ena.patch [new file with mode: 0644]
patches.tizen/0023-iommu-exynos-remove-custom-fault-handler.patch [new file with mode: 0644]
patches.tizen/0024-iommu-exynos-add-bus-notifier-for-registering-System.patch [new file with mode: 0644]
patches.tizen/0025-iommu-exynos-change-rwlock-to-spinlock.patch [new file with mode: 0644]
patches.tizen/0026-iommu-exynos-return-0-if-iommu_attach_device-success.patch [new file with mode: 0644]
patches.tizen/0027-drivers-base-add-notifier-for-failed-driver-bind.patch [new file with mode: 0644]
patches.tizen/0028-ARM-dts-Add-dts-for-exynos4412-slp_pq-board.patch [new file with mode: 0644]
patches.tizen/0029-ARM-dts-exynos4210-trats-Add-node-for-USB-gadget.patch [new file with mode: 0644]
patches.tizen/0030-ARM-dts-exynos4-Add-node-for-USB-PHY.patch [new file with mode: 0644]
patches.tizen/0031-ARM-dts-exynos4-Move-usbphy-node-to-SoC-specific-dts.patch [new file with mode: 0644]
patches.tizen/0032-ARM-dts-exynos4210-trats-Enable-USB-PHY-node.patch [new file with mode: 0644]
patches.tizen/0033-ARM-dts-exynos4412-slp_pq-Enable-USB-PHY-node.patch [new file with mode: 0644]
patches.tizen/0034-ARM-dts-exynos4210-trats-Add-display-support-on-Trat.patch [new file with mode: 0644]
patches.tizen/0035-ARM-dts-exynos4210-trats-Fix-vdd_arm-regulator-name.patch [new file with mode: 0644]
patches.tizen/0036-drm-exynos-fimd-clear-channel-before-enabling-iommu.patch [new file with mode: 0644]
patches.tizen/0037-ARM-EXYNOS-add-ARM_HAS_SG_CHAIN-config.patch [new file with mode: 0644]
patches.tizen/0038-ARM-EXYNOS-select-ARM_DMA_USE_IOMMU-for-MACH_EXYNOS4.patch [new file with mode: 0644]
patches.tizen/0039-ARM-dts-exynos4412-slp_pq-add-fimd-iommu-support.patch [new file with mode: 0644]
patches.tizen/0040-ARM-DTS-SLP-PQ-add-drm-virtual-display-node.patch [new file with mode: 0644]
patches.tizen/0041-drm-exynos-add-dt-match-table-for-vidi-module.patch [new file with mode: 0644]
patches.tizen/0042-ARM-dts-exynos4210-trats-Add-nodes-for-xxti-and-xusb.patch [new file with mode: 0644]
patches.tizen/0043-ARM-dts-exynos4412-slp_pq-Add-nodes-for-xxti-and-xus.patch [new file with mode: 0644]
patches.tizen/0044-ARM-dts-exynos4-Add-clock-lookups-to-hsotg-node.patch [new file with mode: 0644]
patches.tizen/0045-V4L-s5c73m3-Initial-device-tree-support.patch [new file with mode: 0644]
patches.tizen/0046-s5c73m3-Disable-boot_from_rom.patch [new file with mode: 0644]
patches.tizen/0047-ARM-dts-Add-camera-to-node-exynos4.dtsi.patch [new file with mode: 0644]
patches.tizen/0048-ARM-dts-Add-ISP-power-domain-node-for-Exynos4x12.patch [new file with mode: 0644]
patches.tizen/0049-ARM-dts-Add-FIMC-and-MIPI-CSIS-device-nodes-for-Exyn.patch [new file with mode: 0644]
patches.tizen/0050-ARM-dts-Correct-camera-pinctrl-nodes-for-Exynos4x12-.patch [new file with mode: 0644]
patches.tizen/0051-ARM-dts-Add-camera-device-nodes-for-PQ-board.patch [new file with mode: 0644]
patches.tizen/0052-ARM-EXYNOS-change-the-value-of-EXYNOS4X12_ISP_LOWPWR.patch [new file with mode: 0644]
patches.tizen/0053-ARM-dts-Add-pinctrl-entries-for-FIMC-IS-peripherals.patch [new file with mode: 0644]
patches.tizen/0054-ARM-dts-Add-pinctrl-property-to-fimc-is-node-for-PQ-.patch [new file with mode: 0644]
patches.tizen/0055-ARM-dts-Add-MFC-node-for-Exynos4-SoC-series.patch [new file with mode: 0644]
patches.tizen/0056-ARM-dts-Add-camera-clocks-definitions-to-exynos4-x12.patch [new file with mode: 0644]
patches.tizen/0057-v4l2-videobuf2-dc-fix-support-for-mappings-without-s.patch [new file with mode: 0644]
patches.tizen/0058-regulator-max77693-Add-regulator-driver-for-max77693.patch [new file with mode: 0644]
patches.tizen/0059-regulator-Remove-const-from-declation-of-reg_desc-in.patch [new file with mode: 0644]
patches.tizen/0060-regulator-max77693-Remove-no-longer-supported-__dev-.patch [new file with mode: 0644]
patches.tizen/0061-drivers-dma-contiguous-clean-source-code-and-prepare.patch [new file with mode: 0644]
patches.tizen/0062-drivers-of-add-function-to-scan-fdt-nodes-given-by-p.patch [new file with mode: 0644]
patches.tizen/0063-drivers-of-add-initialization-code-for-dma-reserved-.patch [new file with mode: 0644]
patches.tizen/0064-ARM-init-add-support-for-reserved-memory-defined-by-.patch [new file with mode: 0644]
patches.tizen/0065-ARM-Exynos-replace-custom-MFC-reserved-memory-handli.patch [new file with mode: 0644]
patches.tizen/0066-media-s5p-mfc-remove-DT-hacks-and-simplify-initializ.patch [new file with mode: 0644]
patches.tizen/0067-media-s5p-mfc-add-support-for-runtime-pm-for-memport.patch [new file with mode: 0644]
patches.tizen/0068-ARM-Exynos-enable-CMA-and-MFC-for-SLP_PQ-board.patch [new file with mode: 0644]
patches.tizen/0069-video-add-display-core.patch [new file with mode: 0644]
patches.tizen/0070-ARM-Exynos4-fix-DSIM-support.patch [new file with mode: 0644]
patches.tizen/0071-ARM-EXYNOS-Make-MACH_EXYNOS4_DT-select-S5P_SETUP_MIP.patch [new file with mode: 0644]
patches.tizen/0072-video-display-Add-exynos-dsi-video-source-driver.patch [new file with mode: 0644]
patches.tizen/0073-video-display-Add-panel-s6d6aa1-driver.patch [new file with mode: 0644]
patches.tizen/0074-video-display-Add-panel-s6e8aa0-driver.patch [new file with mode: 0644]
patches.tizen/0075-ARM-dts-exynos4-Add-node-for-exynos-dsi-to-exynos4.d.patch [new file with mode: 0644]
patches.tizen/0076-ARM-dts-exynos4412-slp_pq-Update-display-nodes-for-C.patch [new file with mode: 0644]
patches.tizen/0077-ARM-dts-exynos4210-trats-Update-display-nodes-for-CD.patch [new file with mode: 0644]
patches.tizen/0078-ARM-dts-Add-dts-file-for-exynos4412-redwood-board.patch [new file with mode: 0644]
patches.tizen/0079-ARM-dts-Add-dts-file-for-exynos4412-m0-board.patch [new file with mode: 0644]
patches.tizen/0080-USB-s3c-hsotg-fix-Kconfig-dependency.patch [new file with mode: 0644]
patches.tizen/0081-ARM-dts-Correct-FIMC-clocks-definitions-for-Exynos42.patch [new file with mode: 0644]
patches.tizen/0082-ARM-dts-Remove-unnecessary-properties-in-PQ-camera-n.patch [new file with mode: 0644]
patches.tizen/0083-ARM-dts-Add-FIMC-nodes-for-Exynos4210-Trats-board.patch [new file with mode: 0644]
patches.tizen/0084-ARM-dts-Add-CMA-region-definitions-and-enable-MFC-fo.patch [new file with mode: 0644]
patches.tizen/0085-ARM-dts-Add-empty-camera-pinctrl-property-for-Trats-.patch [new file with mode: 0644]
patches.tizen/0086-ARM-dts-Add-missing-MIPI-CSIS-clock-properties-for-E.patch [new file with mode: 0644]
patches.tizen/0087-misc-add-global-lock-driver-for-TIZEN.patch [new file with mode: 0644]
patches.tizen/0088-drm-exynos-add-EXYNOS_DISPLAY_TYPE_LCD-for-TIZEN.patch [new file with mode: 0644]
patches.tizen/0089-ARM-dts-exynos4210-trats-enable-invert-feature-of-to.patch [new file with mode: 0644]
patches.tizen/0090-clk-samsung-exynos4-List-available-mux-clocks.patch [new file with mode: 0644]
patches.tizen/0091-ARM-dts-exynos4x12-Disable-handling-of-ISP-power-dom.patch [new file with mode: 0644]
patches.tizen/0092-ARM-dts-exynos4412-redwood-Enable-MFC-and-CMA.patch [new file with mode: 0644]
patches.tizen/0093-ARM-EXYNOS-Add-sec_debug-module-stub.patch [new file with mode: 0644]
patches.tizen/0094-cpufreq-Define-cpufreq-as-a-platform-device.patch [new file with mode: 0644]
patches.tizen/0095-cpufreq-exynos-Save-struct-device-in-driver-data.patch [new file with mode: 0644]
patches.tizen/0096-cpufreq-exynos-Use-device-based-lookup-for-vdd_arm-r.patch [new file with mode: 0644]
patches.tizen/0097-cpufreq-Adjust-exynos4x12-cpufreq-to-work-with-v3.8-.patch [new file with mode: 0644]
patches.tizen/0098-cpufreq-exynos4x12-Parse-frequency-table-from-device.patch [new file with mode: 0644]
patches.tizen/0099-ARM-dts-exynos4x12-Add-cpufreq-node.patch [new file with mode: 0644]
patches.tizen/0100-ARM-dts-exynos4x12-slp_pq-Add-cpufreq-node.patch [new file with mode: 0644]
patches.tizen/0101-clock-Support-for-A-M-PLL-s-35xx-set_rate-and-round_.patch [new file with mode: 0644]
patches.tizen/0102-cpufreq-Replace-set_apll-code-with-common-clock-fram.patch [new file with mode: 0644]
patches.tizen/0103-clk-samsung-pll-Add-support-for-PLL45xx-rate-setting.patch [new file with mode: 0644]
patches.tizen/0104-cpufreq-exynos4210-Use-device-based-lookup-for-clock.patch [new file with mode: 0644]
patches.tizen/0105-cpufreq-exynos4210-Use-common-clock-operations-for-A.patch [new file with mode: 0644]
patches.tizen/0106-ARM-dts-exynos4210-Add-cpufreq-node.patch [new file with mode: 0644]
patches.tizen/0107-ARM-dts-exynos4210-trats-Add-cpufreq-node.patch [new file with mode: 0644]
patches.tizen/0108-ARM-dts-exynos4210-trats-Use-board-name-for-BUCK1-re.patch [new file with mode: 0644]
patches.tizen/0109-clk-samsung-pll-Do-not-return-error-codes-in-round_r.patch [new file with mode: 0644]
patches.tizen/0110-ARM-dts-exynos4412-slp_pq-Correct-cpufreq-device-nod.patch [new file with mode: 0644]
patches.tizen/0111-clk-samsung-pll-Add-support-for-PLL36xx-rate-configu.patch [new file with mode: 0644]
patches.tizen/0112-clk-samsung-exynos4-Allow-rate-setting-propagation-t.patch [new file with mode: 0644]
patches.tizen/0113-clk-samsung-exynos4-Fix-clock-registration-order.patch [new file with mode: 0644]
patches.tizen/0114-clk-samsung-exynos4-Add-support-for-PLL46xx-rate-con.patch [new file with mode: 0644]
patches.tizen/0115-gpu-arm-Import-new-mali400-drivers-from-exynos-3.4-d.patch [new file with mode: 0644]
patches.tizen/0116-gpu-arm-mali400-mali-Do-not-use-non-existent-VM_RESE.patch [new file with mode: 0644]
patches.tizen/0117-gpu-arm-mali400-ump-Do-not-use-non-existent-VM_RESER.patch [new file with mode: 0644]
patches.tizen/0118-gpu-arm-mali400-mali-Remove-useless-platforms.patch [new file with mode: 0644]
patches.tizen/0119-gpu-arm-mali400-ump-Remove-call-to-flush_all_cpu_cac.patch [new file with mode: 0644]
patches.tizen/0120-gpu-arm-mali400-Add-support-for-Device-Tree.patch [new file with mode: 0644]
patches.tizen/0121-gpu-arm-mali400-mali-Add-exynos4-platform-code.patch [new file with mode: 0644]
patches.tizen/0122-gpu-arm-mali400-ump-Fix-forced-recompilation-of-some.patch [new file with mode: 0644]
patches.tizen/0123-ARM-dts-exynos4-Add-gpu-node-for-ARM-Mali-400.patch [new file with mode: 0644]
patches.tizen/0124-ARM-dts-exynos4412-slp_pq-Add-gpu-node-for-ARM-Mali-.patch [new file with mode: 0644]
patches.tizen/0125-ARM-dts-exynos4210-trats-Add-G3D-voltage-regulator.patch [new file with mode: 0644]
patches.tizen/0126-ARM-dts-exynos4210-trats-Add-gpu-node-for-ARM-Mali-4.patch [new file with mode: 0644]
patches.tizen/0127-ARM-dts-exynos4412-redwood-Add-gpu-node-for-ARM-Mali.patch [new file with mode: 0644]
patches.tizen/0128-ARM-dts-add-mshc-controller-node-for-Exynos4x12-SoCs.patch [new file with mode: 0644]
patches.tizen/0129-ARM-dts-added-cam_port_a-to-exynos4210-pinctrl.patch [new file with mode: 0644]
patches.tizen/0130-ARM-dts-added-trats-m5mols-camera-support.patch [new file with mode: 0644]
patches.tizen/0131-m5mols-improved-power-on-routine.patch [new file with mode: 0644]
patches.tizen/0132-m5mols-device-initialization-moved-to-V4L2-registere.patch [new file with mode: 0644]
patches.tizen/0133-m5mols-added-device-tree-support.patch [new file with mode: 0644]
patches.tizen/0134-ARM-dts-exynos4210-trats-add-s5k5baf-sensor-support.patch [new file with mode: 0644]
patches.tizen/0135-ASoC-samsung-Add-pinctrl-support-to-I2S-driver.patch [new file with mode: 0644]
patches.tizen/0136-ARM-dts-Use-generic-DMA-bindings-for-Exynos4-SPI-dev.patch [new file with mode: 0644]
patches.tizen/0137-ARM-dts-Add-I2S-device-nodes-for-Exynos4-SoCs.patch [new file with mode: 0644]
patches.tizen/0138-clk-Add-Exynos-Audio-Subsystem-clocks-driver.patch [new file with mode: 0644]
patches.tizen/0139-regulator-wm8994-Enable-device-tree-based-driver-mat.patch [new file with mode: 0644]
patches.tizen/0140-ARM-dts-Add-Exynos-Audio-Subsystem-clock-controller-.patch [new file with mode: 0644]
patches.tizen/0141-sound-samsung-i2s-Correct-I2S-clock-handling.patch [new file with mode: 0644]
patches.tizen/0142-clk-samsung-exynos4-Add-support-for-CLKOUT.patch [new file with mode: 0644]
patches.tizen/0143-ARM-dts-exynos4-Add-clkout-Device-Tree-node.patch [new file with mode: 0644]
patches.tizen/0144-sound-soc-codecs-Import-Yamaha-YMU823-MC1N2-codec-dr.patch [new file with mode: 0644]
patches.tizen/0145-sound-soc-samsung-Add-Trats-platform-audio-driver.patch [new file with mode: 0644]
patches.tizen/0146-ARM-dts-exynos4210-trats-Add-LDO1-regulator-node.patch [new file with mode: 0644]
patches.tizen/0147-ARM-dts-exynos4210-trats-Add-nodes-for-audio-hardwar.patch [new file with mode: 0644]
patches.tizen/0148-cpufreq-Make-ARM_EXYNOS-_CPUFREQ-depend-on-ARM_EXYNO.patch [new file with mode: 0644]
patches.tizen/0149-power-max8997-charger-Fix-getting-platform-data.patch [new file with mode: 0644]
patches.tizen/0150-ARM-dts-exynos4210-trats-Add-node-for-max17042-batte.patch [new file with mode: 0644]
patches.tizen/0151-gpu-drm-exynos-fimd-Fix-parsing-video-mode-from-inco.patch [new file with mode: 0644]
patches.tizen/0152-gpu-drm-exynos-fimd-Parse-display-physical-size-from.patch [new file with mode: 0644]
patches.tizen/0153-ARM-dts-exynos4210-trats-Add-physical-display-size-p.patch [new file with mode: 0644]
patches.tizen/0154-ARM-dts-exynos4412-redwood-Add-physical-display-size.patch [new file with mode: 0644]
patches.tizen/0155-ARM-dts-exynos4412-slp_pq-Add-physical-display-size-.patch [new file with mode: 0644]
patches.tizen/0156-ARM-dts-exynos4412-redwood-added-rear-camera-support.patch [new file with mode: 0644]
patches.tizen/0157-mfd-wm8994-irq-Enable-initialization-with-NULL-platf.patch [new file with mode: 0644]
patches.tizen/0158-sound-Add-exynos4-wm1811-machine-driver.patch [new file with mode: 0644]
patches.tizen/0159-ARM-dts-Add-audio-device-nodes-for-PQ-board.patch [new file with mode: 0644]
patches.tizen/0160-ARM-dts-Move-isp-i2c-node-to-root-level.patch [new file with mode: 0644]
patches.tizen/0161-ARM-dts-Add-pmu-subnode-for-Exynos4-fimc-is-device.patch [new file with mode: 0644]
patches.tizen/0162-m5mols-Fix-regulator_enable-errors-handling.patch [new file with mode: 0644]
patches.tizen/0163-ARM-dts-exynos-re-enabled-ISP-power-domain.patch [new file with mode: 0644]
patches.tizen/0164-sound-exynos4_wm1811-Disable-suspend-code-for-uninit.patch [new file with mode: 0644]
patches.tizen/0165-ARM-dts-Add-detailed-FIMC-properties-to-exynos4x12.d.patch [new file with mode: 0644]
patches.tizen/0166-ARM-dts-Add-detailed-FIMC-properties-to-exynos4210.d.patch [new file with mode: 0644]
patches.tizen/0167-ARM-dts-PQ-mipi-csis-clock-frequency-correction.patch [new file with mode: 0644]
patches.tizen/0168-ARM-dts-exynos4-Update-i2c-isp-node-in-exynos4412-sl.patch [new file with mode: 0644]
patches.tizen/0169-ARM-dts-Add-SYSREG-block-node-for-Exynos4-SoC-series.patch [new file with mode: 0644]
patches.tizen/0170-ARM-dts-exynos4-Add-sysreg-properties-to-fimc-nodes.patch [new file with mode: 0644]
patches.tizen/0171-ARM-dts-exynos4-Move-fimc-lite-nodes-to-root-level.patch [new file with mode: 0644]
patches.tizen/0172-ARM-dts-exynos4-Make-ISP-I2C1-device-node-a-child-of.patch [new file with mode: 0644]
patches.tizen/0173-ARM-configs-Add-tizen_defconfig.patch [new file with mode: 0644]
patches.tizen/0174-ARM-i2c-s3c2410-register-resume-early-function.patch [new file with mode: 0644]
patches.tizen/0175-ARM-dts-exynos4412-redwood-Add-menu-key.patch [new file with mode: 0644]
patches.tizen/0176-ARM-DISPLAY-support-suspend-resume-for-mipi-dsi-of-D.patch [new file with mode: 0644]
patches.tizen/0177-ARM-dts-change-mdma-clock-node-of-4x12.patch [new file with mode: 0644]
patches.tizen/0178-ARM-dts-exynos4210-trats-Adjust-regulator-configurat.patch [new file with mode: 0644]
patches.tizen/0179-ARM-EXYNOS-Fix-incorrect-usage-of-S5P_ARM_CORE1_-reg.patch [new file with mode: 0644]
patches.tizen/0180-video-display-panel-s6e8aa0-Add-support-for-suspend-.patch [new file with mode: 0644]
patches.tizen/0181-video-display-panel-s6d6aa1-Add-support-for-suspend-.patch [new file with mode: 0644]
patches.tizen/0182-packaging-add-.spec-file-to-generate-kernel-headers.patch [new file with mode: 0644]
patches.tizen/0183-ARM-dts-Add-ak8975-device-node-for-PQ-M0-board.patch [new file with mode: 0644]
patches.tizen/0184-ARM-dts-Add-I2C-bus-and-the-device-node-for-LPS331-s.patch [new file with mode: 0644]
patches.tizen/0185-ARM-dts-Add-clock-properties-to-ISP-I2C-node-in-exyn.patch [new file with mode: 0644]
patches.tizen/0186-ARM-dts-Add-missing-clocks-to-fimc-is-node-in-exynos.patch [new file with mode: 0644]
patches.tizen/0187-dts-pq-Add-max77693-s-initial-data-to-pq-s-device-tr.patch [new file with mode: 0644]
patches.tizen/0188-mfd-max77693-Support-device-tree-in-max77693-mfd-dri.patch [new file with mode: 0644]
patches.tizen/0189-power-max77693-Add-max77693-charger-dirver.patch [new file with mode: 0644]
patches.tizen/0190-regulator-max77693-Support-to-parse-data-from-device.patch [new file with mode: 0644]
patches.tizen/0191-mfd-max77686-Fix-NULL-pointer-error-of-max77686-plat.patch [new file with mode: 0644]
patches.tizen/0192-power-max77693-Add-kernel-configuation-of-Max77693-c.patch [new file with mode: 0644]
patches.tizen/0193-ARM-clock-cpufreq-Correct-MPLL-clock-and-DTS-binding.patch [new file with mode: 0644]
patches.tizen/0194-ARM-dts-Update-ISP-clocks-in-exyno4x12.dtsi.patch [new file with mode: 0644]
patches.tizen/0195-ARM-dts-Update-the-wm1811-codec-node-in-exynos4412-s.patch [new file with mode: 0644]
patches.tizen/0196-iio-ak8975-Add-support-for-gpios-DT-property.patch [new file with mode: 0644]
patches.tizen/0197-iio-ak8975-Implement-data-ready-interrupt-handling.patch [new file with mode: 0644]
patches.tizen/0198-video-display-panel-s6e8aa0-support-others-panel-ver.patch [new file with mode: 0644]
patches.tizen/0199-drm-exynos-Remove-MODULE_DEVICE_TABLE-table-from-vid.patch [new file with mode: 0644]
patches.tizen/0200-exynos4-is-Add-fimc-parent-clock-setup.patch [new file with mode: 0644]
patches.tizen/0201-exynos4-is-Add-csis-parent-clock-setup.patch [new file with mode: 0644]
patches.tizen/0202-media-media-Rename-media_entity_remote_source-to-med.patch [new file with mode: 0644]
patches.tizen/0203-exynos4-is-Fix-example-dts-in-.-bindings-samsung-fim.patch [new file with mode: 0644]
patches.tizen/0204-media-media-Add-a-function-removing-all-links-of-a-m.patch [new file with mode: 0644]
patches.tizen/0205-media-V4L-Remove-all-links-of-the-media-entity-when-.patch [new file with mode: 0644]
patches.tizen/0206-s5c73m3-Do-not-ignore-errors-from-regulator_enable.patch [new file with mode: 0644]
patches.tizen/0207-media-exynos4-is-Remove-redundant-NULL-check-in-fimc.patch [new file with mode: 0644]
patches.tizen/0208-media-exynos4-is-Remove-platform_device_id-table-at-.patch [new file with mode: 0644]
patches.tizen/0209-media-exynos4-is-Correct-querycap-ioctl-handling-at-.patch [new file with mode: 0644]
patches.tizen/0210-media-exynos4-is-Staticize-local-symbols.patch [new file with mode: 0644]
patches.tizen/0211-media-exynos4-is-Move-common-functions-to-a-separate.patch [new file with mode: 0644]
patches.tizen/0212-media-exynos4-is-Add-struct-exynos_video_entity.patch [new file with mode: 0644]
patches.tizen/0213-media-exynos4-is-Preserve-state-of-controls-between-.patch [new file with mode: 0644]
patches.tizen/0214-media-exynos4-is-Media-graph-video-device-locking-re.patch [new file with mode: 0644]
patches.tizen/0215-media-exynos4-is-Do-not-use-asynchronous-runtime-PM-.patch [new file with mode: 0644]
patches.tizen/0216-media-exynos4-is-Use-common-exynos_media_pipeline-da.patch [new file with mode: 0644]
patches.tizen/0217-media-exynos4-is-Remove-WARN_ON-from-__fimc_pipeline.patch [new file with mode: 0644]
patches.tizen/0218-media-exynos4-is-Fix-sensor-subdev-FIMC-notification.patch [new file with mode: 0644]
patches.tizen/0219-media-exynos4-is-Add-locking-at-fimc-lite-subdev-unr.patch [new file with mode: 0644]
patches.tizen/0220-media-exynos4-is-Remove-leftovers-of-non-dt-FIMC-LIT.patch [new file with mode: 0644]
patches.tizen/0221-media-exynos4-is-Simplify-bitmask-usage.patch [new file with mode: 0644]
patches.tizen/0222-media-exynos4-is-Remove-unused-code.patch [new file with mode: 0644]
patches.tizen/0223-media-exynos4-is-Refactor-vidioc_s_fmt-vidioc_try_fm.patch [new file with mode: 0644]
patches.tizen/0224-media-exynos4-is-Move-__fimc_videoc_querycap-functio.patch [new file with mode: 0644]
patches.tizen/0225-media-exynos4-is-Add-isp_dbg-macro.patch [new file with mode: 0644]
patches.tizen/0226-media-media-Change-media-device-link_notify-behaviou.patch [new file with mode: 0644]
patches.tizen/0227-media-exynos4-is-Extend-link_notify-handler-to-suppo.patch [new file with mode: 0644]
patches.tizen/0228-clk-exynos4-Add-clock-entries-for-TMU.patch [new file with mode: 0644]
patches.tizen/0229-ARM-dts-thermal-exynos4-TMU-device-tree-support-for-.patch [new file with mode: 0644]
patches.tizen/0230-Thermal-exynos-Support-for-TMU-regulator-defined-at-.patch [new file with mode: 0644]
patches.tizen/0231-ARM-dts-thermal-exynos4-Add-documentation-for-Exynos.patch [new file with mode: 0644]
patches.tizen/0232-ARM-dts-thermal-exynos4-TMU-voltage-regulator-suppor.patch [new file with mode: 0644]
patches.tizen/0233-ARM-dts-Support-device-tree-of-fuel-gauge-max77693-i.patch [new file with mode: 0644]
patches.tizen/0234-fuelgauge-max1704xx-Fix-max17042-driver-to-work-prop.patch [new file with mode: 0644]
patches.tizen/0235-ARM-dts-Modify-lps331ap-device-node-for-PQ-M0-board.patch [new file with mode: 0644]
patches.tizen/0236-arm-dts-Update-max77686-s-device-tree-for-M0-PQ.patch [new file with mode: 0644]
patches.tizen/0237-s5k5baf-add-camera-sensor-driver.patch [new file with mode: 0644]
patches.tizen/0238-ARM-dts-exynos4210-trats.patch [new file with mode: 0644]
patches.tizen/0239-power-max17042-Fix-deadlock-caused-by-deferred-initi.patch [new file with mode: 0644]
patches.tizen/0240-ARM-dts-exynos4210-trats-Add-aliases-for-bit-banged-.patch [new file with mode: 0644]
patches.tizen/0241-ARM-dts-exynos4412-slp_pq-Add-aliases-for-bit-banged.patch [new file with mode: 0644]
patches.tizen/0242-ARM-dts-Correct-aclk400_mcuisp-clock-index-at-fimc-i.patch [new file with mode: 0644]
patches.tizen/0243-gpu-mali-Remove-Exynos-PM-domain-checks-in-debug-cod.patch [new file with mode: 0644]
patches.tizen/0244-drm-exynos-add-device-tree-support-for-rotator.patch [new file with mode: 0644]
patches.tizen/0245-ARM-dts-add-a-rotator-node-for-exynos4.patch [new file with mode: 0644]
patches.tizen/0246-ARM-dts-enable-rotator-node-for-redwood.patch [new file with mode: 0644]
patches.tizen/0247-drm-exynos-add-dt-binding-documentation-for-rotator.patch [new file with mode: 0644]
patches.tizen/0248-drm-exynos-add-g2d-compatible-node-for-exynos4212.patch [new file with mode: 0644]
patches.tizen/0249-ARM-dts-Add-g2d-clock-properties.patch [new file with mode: 0644]
patches.tizen/0250-ARM-dts-enable-g2d-device-for-redwood.patch [new file with mode: 0644]
patches.tizen/0251-ARM-dts-usbphy-add-SYSREG-reg-info-for-exynos4x12.patch [new file with mode: 0644]
patches.tizen/0252-ARM-configs-Update-tizen_defconfig.patch [new file with mode: 0644]
patches.tizen/0253-regulator-max77693-Modify-platform-deivce-id-accordi.patch [new file with mode: 0644]
patches.tizen/0254-regulator-max77693-Pass-of_node-when-regulator-is-re.patch [new file with mode: 0644]
patches.tizen/0255-regulator-max77693-Do-code-clean.patch [new file with mode: 0644]
patches.tizen/0256-clk-Prevent-potential-null-pointer-dereference-in-cl.patch [new file with mode: 0644]
patches.tizen/0257-clk-exynos4-Add-CLK_GET_RATE_NOCACHE-flag-for-the-Ex.patch [new file with mode: 0644]
patches.tizen/0258-ARM-dts-Add-camera-device-nodes-for-M0-rev-1.1-board.patch [new file with mode: 0644]
patches.tizen/0259-iio-st_accel-Add-DT-bindings.patch [new file with mode: 0644]
patches.tizen/0260-iio-st_gyro-Add-DT-bindings.patch [new file with mode: 0644]
patches.tizen/0261-iio-st_sensors-Add-handling-of-multiple-interrupts.patch [new file with mode: 0644]
patches.tizen/0262-iio-st_sensors-Add-threshold-events-support.patch [new file with mode: 0644]
patches.tizen/0263-iio-accel-Add-event-subsystem-to-st_accel-driver.patch [new file with mode: 0644]
patches.tizen/0264-ARM-dts-exnos4412-redwood.dts-Add-lsm330dlc-node-for.patch [new file with mode: 0644]
patches.tizen/0265-ARM-dts-exynos-slp_pq.dts-Add-lsm330dlc-node-for-slp.patch [new file with mode: 0644]
patches.tizen/0266-ARM-dts-enable-sd-card.patch [new file with mode: 0644]
patches.tizen/0267-iio-Add-driver-for-the-LPS331AP-barometer-sensor.patch [new file with mode: 0644]
patches.tizen/0268-iio-Add-driver-for-the-gp2ap002a00f-light-proximity-.patch [new file with mode: 0644]
patches.tizen/0269-ARM-dts-Add-gp2ap002a00f-device-node-for-PQ-M0-board.patch [new file with mode: 0644]
patches.tizen/0270-nfc-pn544-i2c-Add-DT-bindings.patch [new file with mode: 0644]
patches.tizen/0271-nfc-pn544-i2c-Remove-unused-gpio_irq.patch [new file with mode: 0644]
patches.tizen/0272-nfc-pn544-i2c-Fix-pn544_hci_i2c_write-resend-cmd.patch [new file with mode: 0644]
patches.tizen/0273-ARM-dts-Add-nfc-node-for-PQ-board.patch [new file with mode: 0644]
patches.tizen/0274-tizen_defconfig-update.patch [new file with mode: 0644]
patches.tizen/0275-media-exynos4-is-Drop-drvdata-handling-in-fimc-lite-.patch [new file with mode: 0644]
patches.tizen/0276-media-exynos4-is-Add-Exynos5250-SoC-support-to-fimc-.patch [new file with mode: 0644]
patches.tizen/0277-media-exynos4-is-Add-support-for-Exynos5250-MIPI-CSI.patch [new file with mode: 0644]
patches.tizen/0278-media-exynos4-is-Change-fimc-is-firmware-file-names.patch [new file with mode: 0644]
patches.tizen/0279-media-exynos4-is-Fix-format-propagation-on-FIMC-LITE.patch [new file with mode: 0644]
patches.tizen/0280-media-exynos4-is-Set-valid-initial-format-at-FIMC-LI.patch [new file with mode: 0644]
patches.tizen/0281-media-exynos4-is-Fix-format-propagation-on-FIMC-IS-I.patch [new file with mode: 0644]
patches.tizen/0282-media-exynos4-is-Set-valid-initial-format-on-FIMC-IS.patch [new file with mode: 0644]
patches.tizen/0283-media-exynos4-is-Set-valid-initial-format-on-FIMC.n-.patch [new file with mode: 0644]
patches.tizen/0284-media-exynos4-is-Correct-colorspace-handling-at-FIMC.patch [new file with mode: 0644]
patches.tizen/0285-exynos4-is-Add-the-FIMC-IS-ISP-capture-DMA-driver.patch [new file with mode: 0644]
patches.tizen/0286-ARM-dts-Add-MIPI-PHY-node-to-exynos4.dtsi.patch [new file with mode: 0644]
patches.tizen/0287-drivers-phy-add-generic-PHY-framework.patch [new file with mode: 0644]
patches.tizen/0288-phy-Add-driver-for-Exynos-MIPI-CSIS-DSIM-DPHYs.patch [new file with mode: 0644]
patches.tizen/0289-video-exynos_mipi_dsim-Use-the-generic-PHY-driver.patch [new file with mode: 0644]
patches.tizen/0290-media-exynos4-is-Use-the-generic-MIPI-CSIS-PHY-drive.patch [new file with mode: 0644]
patches.tizen/0291-ARM-Samsung-Remove-the-MIPI-PHY-setup-code.patch [new file with mode: 0644]
patches.tizen/0292-video-exynos_dsi-Use-generic-PHY-driver.patch [new file with mode: 0644]
patches.tizen/0293-tizen_defconfig-update.patch [new file with mode: 0644]
patches.tizen/0294-clk-honor-CLK_GET_RATE_NOCACHE-in-clk_set_rate.patch [new file with mode: 0644]
patches.tizen/0295-ARM-dts-Add-missing-I2C-controller-node-alias-for-GP.patch [new file with mode: 0644]
patches.tizen/0296-mmc-sdhci-s3c-revert-fix-missing-clock-for-gpio-card.patch [new file with mode: 0644]
patches.tizen/0297-ARM-dts-Remove-redundant-sysreg-node-from-exynos4.dt.patch [new file with mode: 0644]
patches.tizen/0298-mmc-sdhci-s3c-remove-the-duplicated-calling-sequence.patch [new file with mode: 0644]
patches.tizen/0299-exynos4-is-Handle-suspend-resume-of-fimc-is-i2c-corr.patch [new file with mode: 0644]
patches.tizen/0300-exynos4-is-Ungate-uart-clocks-on-system-suspend.patch [new file with mode: 0644]
patches.tizen/0301-ARM-dts-exynos4210-origen-Add-device-nodes-for-USB-g.patch [new file with mode: 0644]
patches.tizen/0302-ARM-dts-exynos4-Add-node-for-EHCI.patch [new file with mode: 0644]
patches.tizen/0303-HACK-ARM-dts-exynos4412-slp_pq-Keep-HSIC-regulators-.patch [new file with mode: 0644]
patches.tizen/0304-ARM-dts-exynos4412-slp_pq-Enable-EHCI-controller.patch [new file with mode: 0644]
patches.tizen/0305-ARM-dts-exynos4x12-Extend-usbphy-reg-property-to-cov.patch [new file with mode: 0644]
patches.tizen/0306-ARM-DTS-exynos4210-origen-Add-MAX8997-node-entry.patch [new file with mode: 0644]
patches.tizen/0307-ARM-dts-exynos4210-origen-Add-device-node-for-ehci-c.patch [new file with mode: 0644]
patches.tizen/0308-ARM-dts-exynos4210-origen-Use-real-regulators-for-US.patch [new file with mode: 0644]
patches.tizen/0309-usb-ehci-s5p-Create-EHCI-OHCI-power-control-sysfs.patch [new file with mode: 0644]
patches.tizen/0310-usb-ehci-s5p-Fix-device-tree-compatible-string-for-e.patch [new file with mode: 0644]
patches.tizen/0311-ARM-dts-Enable-ehci-for-exynos4412-redwood.dts.patch [new file with mode: 0644]
patches.tizen/0312-usb-s3c-hsotg-Changing-MAC-interface-to-8-bit.patch [new file with mode: 0644]
patches.tizen/0313-usb-ehci-s5p-Add-support-for-HSIC-to-the-Exynos-4x12.patch [new file with mode: 0644]
patches.tizen/0314-modem_if-Add-modem_if-driver-files.patch [new file with mode: 0644]
patches.tizen/0315-modem_if-Remove-linux-cma.h-use.patch [new file with mode: 0644]
patches.tizen/0316-modem_if-Add-modem.h-to-include-linux-platform_data.patch [new file with mode: 0644]
patches.tizen/0317-modem_if-Modification-of-the-modem-driver-to-compile.patch [new file with mode: 0644]
patches.tizen/0318-modem_if-device_tree-Add-modem_if-to-exynos4412-slp_.patch [new file with mode: 0644]
patches.tizen/0319-modem_if-Move-code-from-board-m0-modems.c-to-the-mod.patch [new file with mode: 0644]
patches.tizen/0320-modem_if-Comment-out-enable_wake_irq-in-modem-driver.patch [new file with mode: 0644]
patches.tizen/0321-usb-ehci-s5p-Add-s5p_ehci_configurate-needed-by-mode.patch [new file with mode: 0644]
patches.tizen/0322-modem_if-Move-code-from-board-m0-modems.c-to-the-xmm.patch [new file with mode: 0644]
patches.tizen/0323-modem_if-ifdef-wake_lock-support-in-the-modem-driver.patch [new file with mode: 0644]
patches.tizen/0324-modem_if-Change-net-device-name-choice-mechanism.patch [new file with mode: 0644]
patches.tizen/0325-modem_if-Add-modem-drivers-to-Kconfig-and-Makefile.patch [new file with mode: 0644]
patches.tizen/0326-ARM-dts-exynos4412-redwood-Add-device-nodes-for-mode.patch [new file with mode: 0644]
patches.tizen/0327-tizen_defconfig-update.patch [new file with mode: 0644]
patches.tizen/0328-clk-samsung-exynos4-Do-not-disable-ISP-bus-clocks.patch [new file with mode: 0644]
patches.tizen/0329-ARM-EXYNOS-pm-Move-call-to-flush_cache_all-before-ou.patch [new file with mode: 0644]
patches.tizen/0330-ARM-EXYNOS-Add-support-for-firmware-assisted-suspend.patch [new file with mode: 0644]
patches.tizen/0331-pinctrl-samsung-Parse-pin-groups-before-calling-pinc.patch [new file with mode: 0644]
patches.tizen/0332-ARM-dts-exynos4412-slp_pq-Add-sleep-mode-pin-configu.patch [new file with mode: 0644]
patches.tizen/0333-regulator-Handle-suspend-and-resume-of-regulators.patch [new file with mode: 0644]
patches.tizen/0334-regulator-of-Parse-regulator-state-in-mem-mode-from-.patch [new file with mode: 0644]
patches.tizen/0335-regulator-max77686-Add-set_suspend_enable-callback-f.patch [new file with mode: 0644]
patches.tizen/0336-regulator-max77686-Fix-suspend-mode-settings-of-regu.patch [new file with mode: 0644]
patches.tizen/0337-ARM-dts-exynos4412-slp_pq-Add-regulator-states-in-me.patch [new file with mode: 0644]
patches.tizen/0338-clocksource-exynos_mct-Register-sched_clock.patch [new file with mode: 0644]
patches.tizen/0339-tty-serial-samsung-Remove-useless-checks-in-suspend-.patch [new file with mode: 0644]
patches.tizen/0340-ARM-firmware-Add-L2X0-resume-operation.patch [new file with mode: 0644]
patches.tizen/0341-ARM-EXYNOS-firmware-Implement-l2x0_resume-operation.patch [new file with mode: 0644]
patches.tizen/0342-ARM-EXYNOS-Move-L2X0-cache-resume-to-SoC-PM-code.patch [new file with mode: 0644]
patches.tizen/0343-ARM-EXYNOS-pm-Add-support-for-firmware-based-L2X0-re.patch [new file with mode: 0644]
patches.tizen/0344-ARM-EXYNOS-firmware-Surround-l2x0-ops-with-an-ifdef.patch [new file with mode: 0644]
patches.tizen/0345-charger_manager-Workaround-for-supporting-platform-d.patch [new file with mode: 0644]
patches.tizen/0346-power-charger-manager-regulator_get-never-returns-NU.patch [new file with mode: 0644]
patches.tizen/0347-power-charger-manager-Fix-a-bug-when-it-unregisters-.patch [new file with mode: 0644]
patches.tizen/0348-ARM-config-Update-tizen_defconfig.patch [new file with mode: 0644]
patches.tizen/0349-ARM-DTS-update-device-tree-for-for-charger_manager.patch [new file with mode: 0644]
patches.tizen/0350-arch-Make-__mutex_fastpath_lock_retval-return-whethe.patch [new file with mode: 0644]
patches.tizen/0351-mutex-Add-support-for-wound-wait-style-locks.patch [new file with mode: 0644]
patches.tizen/0352-mutex-Add-w-w-mutex-slowpath-debugging.patch [new file with mode: 0644]
patches.tizen/0353-dmabuf-sync-add-buffer-synchronization-framework.patch [new file with mode: 0644]
patches.tizen/0354-dmabuf-sync-add-cache-operation-feature.patch [new file with mode: 0644]
patches.tizen/0355-dma-buf-add-lock-callback-for-fcntl-system-call.patch [new file with mode: 0644]
patches.tizen/0356-drm-exynos-export-a-gem-into-dmabuf-fd-with-O_RDWR.patch [new file with mode: 0644]
patches.tizen/0357-drm-exynos-add-cache-operation-backend-callbacks.patch [new file with mode: 0644]
patches.tizen/0358-perf-tools-Fix-bug-in-isupper-and-islower.patch [new file with mode: 0644]
patches.tizen/0359-perf-hists-Fix-an-invalid-memory-free-on-he-branch_i.patch [new file with mode: 0644]
patches.tizen/0360-perf-hists-Free-unused-mem-info-of-a-matched-hist-en.patch [new file with mode: 0644]
patches.tizen/0361-perf-report-Fix-alignment-of-symbol-column-when-v-is.patch [new file with mode: 0644]
patches.tizen/0362-perf-sort-Introduce-sort__mode-variable.patch [new file with mode: 0644]
patches.tizen/0363-perf-sort-Factor-out-common-code-in-sort_dimension__.patch [new file with mode: 0644]
patches.tizen/0364-perf-sort-Separate-out-memory-specific-sort-keys.patch [new file with mode: 0644]
patches.tizen/0365-perf-sort-Consolidate-sort_entry__setup_elide.patch [new file with mode: 0644]
patches.tizen/0366-perf-archive-Fix-typo-on-Documentation.patch [new file with mode: 0644]
patches.tizen/0367-perf-sort-Reorder-HISTC_SRCLINE-index.patch [new file with mode: 0644]
patches.tizen/0368-perf-sort-Cleanup-sort__has_sym-setting.patch [new file with mode: 0644]
patches.tizen/0369-perf-top-Use-sort__has_sym.patch [new file with mode: 0644]
patches.tizen/0370-perf-hists-browser-Use-sort__has_sym.patch [new file with mode: 0644]
patches.tizen/0371-perf-tools-Fix-tab-vs-spaces-issue-in-Makefile-ifdef.patch [new file with mode: 0644]
patches.tizen/0372-perf-tests-Fix-compile-errors-in-bp_signal-files.patch [new file with mode: 0644]
patches.tizen/0373-perf-record-handle-death-by-SIGTERM.patch [new file with mode: 0644]
patches.tizen/0374-perf-top-Fix-E-option-behavior.patch [new file with mode: 0644]
patches.tizen/0375-perf-top-Fix-percent-output-when-no-samples-collecte.patch [new file with mode: 0644]
patches.tizen/0376-perf-top-Get-rid-of-_threaded-functions.patch [new file with mode: 0644]
patches.tizen/0377-perf-hists-Move-locking-to-its-call-sites.patch [new file with mode: 0644]
patches.tizen/0378-perf-report-Don-t-bother-locking-when-adding-hist-en.patch [new file with mode: 0644]
patches.tizen/0379-perf-report-Add-percent-limit-option.patch [new file with mode: 0644]
patches.tizen/0380-perf-top-Add-percent-limit-option.patch [new file with mode: 0644]
patches.tizen/0381-perf-report-Add-report.percent-limit-config-variable.patch [new file with mode: 0644]
patches.tizen/0382-perf-diff-Use-internal-rb-tree-for-hists__precompute.patch [new file with mode: 0644]
patches.tizen/0383-perf-hists-Rename-hist_entry__add_pair-arguments.patch [new file with mode: 0644]
patches.tizen/0384-perf-test-Fix-typo.patch [new file with mode: 0644]
patches.tizen/0385-perf-evsel-Fix-printing-of-perf_event_paranoid-messa.patch [new file with mode: 0644]
patches.tizen/0386-perf-kvm-Handle-realloc-failures.patch [new file with mode: 0644]
patches.tizen/0387-perf-stats-Fix-divide-by-0-in-variance.patch [new file with mode: 0644]
patches.tizen/0388-perf-tools-Save-parent-pid-in-thread-struct.patch [new file with mode: 0644]
patches.tizen/0389-perf-tools-Add-automated-make-test-suite.patch [new file with mode: 0644]
patches.tizen/0390-perf-tools-Move-arch-check-into-config-Makefile.patch [new file with mode: 0644]
patches.tizen/0391-perf-tools-Move-programs-check-into-config-Makefile.patch [new file with mode: 0644]
patches.tizen/0392-perf-tools-Move-compiler-and-linker-flags-check-into.patch [new file with mode: 0644]
patches.tizen/0393-perf-tools-Move-libelf-check-config-into-config-Make.patch [new file with mode: 0644]
patches.tizen/0394-perf-tools-Move-libdw-check-config-into-config-Makef.patch [new file with mode: 0644]
patches.tizen/0395-perf-tools-Move-libunwind-check-config-into-config-M.patch [new file with mode: 0644]
patches.tizen/0396-perf-tools-Move-libaudit-check-config-into-config-Ma.patch [new file with mode: 0644]
patches.tizen/0397-perf-tools-Move-slang-check-config-into-config-Makef.patch [new file with mode: 0644]
patches.tizen/0398-perf-tools-Move-gtk2-check-config-into-config-Makefi.patch [new file with mode: 0644]
patches.tizen/0399-perf-tools-Move-libperl-check-config-into-config-Mak.patch [new file with mode: 0644]
patches.tizen/0400-perf-tools-Move-libpython-check-config-into-config-M.patch [new file with mode: 0644]
patches.tizen/0401-perf-tools-Move-libbfd-check-config-into-config-Make.patch [new file with mode: 0644]
patches.tizen/0402-perf-tools-Move-stdlib-check-config-into-config-Make.patch [new file with mode: 0644]
patches.tizen/0403-perf-tools-Move-libnuma-check-config-into-config-Mak.patch [new file with mode: 0644]
patches.tizen/0404-perf-tools-Move-paths-config-into-config-Makefile.patch [new file with mode: 0644]
patches.tizen/0405-perf-tools-Final-touches-for-CHK-config-move.patch [new file with mode: 0644]
patches.tizen/0406-perf-tests-Fix-attr-test-for-record-d-option.patch [new file with mode: 0644]
patches.tizen/0407-perf-tests-Fix-exclude_guest-exclude_host-checking-f.patch [new file with mode: 0644]
patches.tizen/0408-perf-tools-Remove-frozen-from-perf_header-struct.patch [new file with mode: 0644]
patches.tizen/0409-perf-tools-Remove-cwdlen-from-struct-perf_session.patch [new file with mode: 0644]
patches.tizen/0410-tools-lib-lk-Respect-CROSS_COMPILE.patch [new file with mode: 0644]
patches.tizen/0411-perf-Power7-Make-CPI-stack-events-available-in-sysfs.patch [new file with mode: 0644]
patches.tizen/0412-perf-Power7-Update-testing-ABI-to-list-CPI-stack-eve.patch [new file with mode: 0644]
patches.tizen/0413-perf-Expand-definition-of-sysfs-format-attribute.patch [new file with mode: 0644]
patches.tizen/0414-perf-evlist-Reset-SIGTERM-handler-in-workload-child-.patch [new file with mode: 0644]
patches.tizen/0415-perf-tools-Merge-all-CFLAGS-make-variable-into-CFLAG.patch [new file with mode: 0644]
patches.tizen/0416-perf-tools-Merge-all-LDFLAGS-make-variable-into-LDFL.patch [new file with mode: 0644]
patches.tizen/0417-perf-tools-Switch-to-full-path-C-include-directories.patch [new file with mode: 0644]
patches.tizen/0418-perf-tools-Add-NO_BIONIC-variable-to-confiure-bionic.patch [new file with mode: 0644]
patches.tizen/0419-perf-tools-Replace-tabs-with-spaces-for-all-non-comm.patch [new file with mode: 0644]
patches.tizen/0420-perf-tools-Replace-multiple-line-assignment-with-mul.patch [new file with mode: 0644]
patches.tizen/0421-perf-tools-Remove-Makefile-STRIP-assignment.patch [new file with mode: 0644]
patches.tizen/0422-perf-tools-Add-missing-liblk.a-dependency-for-python.patch [new file with mode: 0644]
patches.tizen/0423-dts-arm-add-arm-pmu-node-for-exynos4412.patch [new file with mode: 0644]
patches.tizen/0424-clk-samsung-fix-section-mismatch-from-audio-subsyste.patch [new file with mode: 0644]
patches.tizen/0425-max77693_charger-fix-section-mismatch.patch [new file with mode: 0644]
patches.tizen/0426-cpufreq-exynos-fix-section-mismatch.patch [new file with mode: 0644]
patches.tizen/0427-dmabuf-sync-fix-sync-lock-to-multiple-read.patch [new file with mode: 0644]
patches.tizen/0428-dmabuf-sync-remove-unnecessary-the-use-of-mutex-lock.patch [new file with mode: 0644]
patches.tizen/0429-dmabuf-sync-add-private-backend-callbacks.patch [new file with mode: 0644]
patches.tizen/0430-drm-exynos-fix-module-build-error.patch [new file with mode: 0644]
patches.tizen/0431-ARM-dts-exynos4412-slp_pq-add-fimd-iommu-related-pro.patch [new file with mode: 0644]
patches.tizen/0432-ARM-configs-update-tizen_defconfig.patch [new file with mode: 0644]
patches.tizen/0433-drm-exynos-consider-common-clock-framework-to-g2d-dr.patch [new file with mode: 0644]
patches.tizen/0434-ARM-dts-exynos4412-slp_pq-add-device-node-for-g2d-io.patch [new file with mode: 0644]
patches.tizen/0435-mmc-dw_mmc-fix-error-return-code-in-dw_mci_probe.patch [new file with mode: 0644]
patches.tizen/0436-mmc-dw_mmc-clear-IDSTS-register-when-initialize-IDMA.patch [new file with mode: 0644]
patches.tizen/0437-mmc-dw_mmc-change-the-macro-name-from-DTO-to-DRTO.patch [new file with mode: 0644]
patches.tizen/0438-mmc-dw_mmc-Handle-late-vmmc-regulators-with-EPROBE_D.patch [new file with mode: 0644]
patches.tizen/0439-mmc-dw_mmc-Add-the-ability-to-set-the-ciu-clock-freq.patch [new file with mode: 0644]
patches.tizen/0440-ARM-dts-enable-dw-mmc-controlle-instead-of-sdhci-con.patch [new file with mode: 0644]
patches.tizen/0441-ARM-dts-updated-the-dwmmc-device-tree-for-clk-name.patch [new file with mode: 0644]
patches.tizen/0442-clock-clk-exynos4-set-the-CLK_SET_RATE_PARENT-for-mm.patch [new file with mode: 0644]
patches.tizen/0443-ARM-tizen_defconfig-enable-the-exynos-dw-mmc.patch [new file with mode: 0644]
patches.tizen/0444-drm-exynos-add-runtime-pm-interfaces-to-g2d-driver.patch [new file with mode: 0644]
patches.tizen/0445-extcon-max77693-Fix-bug-related-to-MAX77693-irq-when.patch [new file with mode: 0644]
patches.tizen/0446-ARM-dts-exynos4412-redwood-Add-i2c-node-for-MAX77693.patch [new file with mode: 0644]
patches.tizen/0447-ARM-tizen_defconfig-enable-unsafe-resume-config.patch [new file with mode: 0644]
patches.tizen/0448-mmc-Makefile-change-the-init-sequence-for-indexing-m.patch [new file with mode: 0644]
patches.tizen/0449-ARM-dts-exynos4412-m0-update-gpio-keys-configuration.patch [new file with mode: 0644]
patches.tizen/0450-f2fs-fix-inconsistency-of-block-count-during-recover.patch [new file with mode: 0644]
patches.tizen/0451-f2fs-fix-the-inconsistent-state-of-data-pages.patch [new file with mode: 0644]
patches.tizen/0452-f2fs-remove-redundant-assignment.patch [new file with mode: 0644]
patches.tizen/0453-f2fs-fix-por_doing-variable-coverage.patch [new file with mode: 0644]
patches.tizen/0454-f2fs-fix-BUG_ON-during-f2fs_evict_inode-dir.patch [new file with mode: 0644]
patches.tizen/0455-f2fs-remove-unnecessary-por_doing-check.patch [new file with mode: 0644]
patches.tizen/0456-f2fs-skip-get_node_page-if-locked-node-page-is-passe.patch [new file with mode: 0644]
patches.tizen/0457-f2fs-change-get_new_data_page-to-pass-a-locked-node-.patch [new file with mode: 0644]
patches.tizen/0458-f2fs-update-inode-page-after-creation.patch [new file with mode: 0644]
patches.tizen/0459-f2fs-add-debug-msgs-in-the-recovery-routine.patch [new file with mode: 0644]
patches.tizen/0460-f2fs-lockdep-annotate-mutex_lock_all.patch [new file with mode: 0644]
patches.tizen/0461-f2fs-remove-unecessary-variable-and-code.patch [new file with mode: 0644]
patches.tizen/0462-f2fs-use-list_for_each_entry-rather-than-list_for_ea.patch [new file with mode: 0644]
patches.tizen/0463-f2fs-reorganize-f2fs_vm_page_mkwrite.patch [new file with mode: 0644]
patches.tizen/0464-f2fs-remove-unnecessary-kmap-kunmap-operations.patch [new file with mode: 0644]
patches.tizen/0465-f2fs-fix-to-unlock-page-before-exit.patch [new file with mode: 0644]
patches.tizen/0466-f2fs-don-t-do-checkpoint-if-error-is-occurred.patch [new file with mode: 0644]
patches.tizen/0467-f2fs-avoid-RECLAIM_FS-ON-W-deadlock.patch [new file with mode: 0644]
patches.tizen/0468-f2fs-add-f2fs_readonly.patch [new file with mode: 0644]
patches.tizen/0469-f2fs-fix-wrong-condition-check.patch [new file with mode: 0644]
patches.tizen/0470-f2fs-reuse-the-locked-dnode-page-and-its-inode.patch [new file with mode: 0644]
patches.tizen/0471-f2fs-fix-to-handle-do_recover_data-errors.patch [new file with mode: 0644]
patches.tizen/0472-f2fs-should-not-make_bad_inode-on-f2fs_link-failure.patch [new file with mode: 0644]
patches.tizen/0473-f2fs-use-ihold.patch [new file with mode: 0644]
patches.tizen/0474-f2fs-dereferencing-an-ERR_PTR.patch [new file with mode: 0644]
patches.tizen/0475-f2fs-align-data-types-between-on-disk-and-in-memory-.patch [new file with mode: 0644]
patches.tizen/0476-f2fs-push-some-variables-to-debug-part.patch [new file with mode: 0644]
patches.tizen/0477-f2fs-remove-unneeded-initializations-in-f2fs_parent_.patch [new file with mode: 0644]
patches.tizen/0478-f2fs-optimize-several-routines-in-node.h.patch [new file with mode: 0644]
patches.tizen/0479-f2fs-return-proper-error-from-start_gc_thread.patch [new file with mode: 0644]
patches.tizen/0480-f2fs-iput-only-if-whole-data-blocks-are-flushed.patch [new file with mode: 0644]
patches.tizen/0481-f2fs-fix-dentry-recovery-routine.patch [new file with mode: 0644]
patches.tizen/0482-f2fs-fix-incorrect-iputs-during-the-dentry-recovery.patch [new file with mode: 0644]
patches.tizen/0483-f2fs-cover-cp_file-information-with-ilock.patch [new file with mode: 0644]
patches.tizen/0484-f2fs-handle-errors-from-get_node_page-calls.patch [new file with mode: 0644]
patches.tizen/0485-f2fs-reorganise-the-function-get_victim_by_default.patch [new file with mode: 0644]
patches.tizen/0486-f2fs-fix-iget-iput-of-dir-during-recovery.patch [new file with mode: 0644]
patches.tizen/0487-f2fs-support-xattr-security-labels.patch [new file with mode: 0644]
patches.tizen/0488-f2fs-set-sb-s_fs_info-before-calling-parse_options.patch [new file with mode: 0644]
patches.tizen/0489-f2fs-fix-i_blocks-translation-on-various-types-of-fi.patch [new file with mode: 0644]
patches.tizen/0490-f2fs-sync-dir-i_size-with-its-block-allocation.patch [new file with mode: 0644]
patches.tizen/0491-f2fs-use-the-F2FS-specific-flags-in-f2fs_ioctl.patch [new file with mode: 0644]
patches.tizen/0492-f2fs-optimise-the-truncate_data_blocks_range-range.patch [new file with mode: 0644]
patches.tizen/0493-f2fs-avoid-freqeunt-write_inode-calls.patch [new file with mode: 0644]
patches.tizen/0494-f2fs-remove-unnecessary-parameter-offset-from-__add_.patch [new file with mode: 0644]
patches.tizen/0495-f2fs-make-locate_dirty_segment-as-static.patch [new file with mode: 0644]
patches.tizen/0496-f2fs-optimize-do_write_data_page.patch [new file with mode: 0644]
patches.tizen/0497-f2fs-recover-wrong-pino-after-checkpoint-during-fsyn.patch [new file with mode: 0644]
patches.tizen/0498-f2fs-add-remount_fs-callback-support.patch [new file with mode: 0644]
patches.tizen/0499-f2fs-fix-crc-endian-conversion.patch [new file with mode: 0644]
patches.tizen/0500-f2fs-fix-an-endian-conversion-bug-detected-by-sparse.patch [new file with mode: 0644]
patches.tizen/0501-f2fs-optimize-the-init_dirty_segmap-function.patch [new file with mode: 0644]
patches.tizen/0502-f2fs-code-cleanup-and-simplify-in-func-find-add-_gc_.patch [new file with mode: 0644]
patches.tizen/0503-f2fs-remove-reusing-any-prefree-segments.patch [new file with mode: 0644]
patches.tizen/0504-f2fs-remove-the-unused-argument-sbi-of-func-destroy_.patch [new file with mode: 0644]
patches.tizen/0505-f2fs-fix-to-recover-i_size-from-roll-forward.patch [new file with mode: 0644]
patches.tizen/0506-ARM-dts-Add-dts-file-for-exynos4412-redwoodlte-board.patch [new file with mode: 0644]
patches.tizen/0507-f2fs-recover-date-requested-by-fdatasync.patch [new file with mode: 0644]
patches.tizen/0508-f2fs-add-description-for-fsck.f2fs-and-dump.f2fs.patch [new file with mode: 0644]
patches.tizen/0509-f2fs-add-proc-entry-to-monitor-current-usage-of-segm.patch [new file with mode: 0644]
patches.tizen/0510-f2fs-add-a-help-func-F2FS_STAT-to-get-the-f2fs_stat_.patch [new file with mode: 0644]
patches.tizen/0511-f2fs-introduce-help-function-F2FS_NODE.patch [new file with mode: 0644]
patches.tizen/0512-f2fs-update-file-name-in-the-inode-block-during-f2fs.patch [new file with mode: 0644]
patches.tizen/0513-f2fs-fix-i_name-during-f2fs_sync_file.patch [new file with mode: 0644]
patches.tizen/0514-f2fs-use-seq_puts-seq_putc-rather-than-seq_printf-wh.patch [new file with mode: 0644]
patches.tizen/0515-f2fs-use-list_for_each-rather-than-list_for_each_saf.patch [new file with mode: 0644]
patches.tizen/0516-f2fs-move-bio_private-allocation-out-of-f2fs_bio_all.patch [new file with mode: 0644]
patches.tizen/0517-f2fs-fix-handling-orphan-inodes.patch [new file with mode: 0644]
patches.tizen/0518-mmc-dw_mmc-add-the-specified-capabilities2-of-the-co.patch [new file with mode: 0644]
patches.tizen/0519-mmc-dw_mmc-exynos-supporte-the-packed-command.patch [new file with mode: 0644]
patches.tizen/0520-DT-support-l5f31188-panel.patch [new file with mode: 0644]
patches.tizen/0521-ARM-dts-remove-repeated-code-and-bug-fix.patch [new file with mode: 0644]
patches.tizen/0522-video-display-panel-s6d6aa1-remove-useless-function.patch [new file with mode: 0644]
patches.tizen/0523-ARM-dts-redwood-correct-gpio_key-interrupt-control.patch [new file with mode: 0644]
patches.tizen/0524-clk-exynos4-Add-additional-G2D-clocks.patch [new file with mode: 0644]
patches.tizen/0525-dmabuf-sync-add-select-system-call-support.patch [new file with mode: 0644]
patches.tizen/0526-ARM-tizen_defconfig-enable-mcs_touchkey-config.patch [new file with mode: 0644]
patches.tizen/0527-TRATS2-dts-exynos4412-m0.dts-Add-mcs-touchkey-node.patch [new file with mode: 0644]
patches.tizen/0528-Input-mcs_touchkey-Add-parse-DT-function-from-device.patch [new file with mode: 0644]
patches.tizen/0529-debugfs-add-get-set-for-atomic-types.patch [new file with mode: 0644]
patches.tizen/0530-zbud-add-to-mm.patch [new file with mode: 0644]
patches.tizen/0531-zswap-add-to-mm.patch [new file with mode: 0644]
patches.tizen/0532-zswap-add-documentation.patch [new file with mode: 0644]
patches.tizen/0533-dma-buf-return-POLLIN-POLLOUT-instead-of-POLLERR.patch [new file with mode: 0644]
patches.tizen/0534-iio-add-proximity-light-sensor-cm36651-driver-to-Kco.patch [new file with mode: 0644]
patches.tizen/0535-ARM-tizen_defconfig-add-cm36651-proxmity-light-senso.patch [new file with mode: 0644]
patches.tizen/0536-TRATS2-dts-exynos4412-m0.dts-Add-cm36651-proximity-l.patch [new file with mode: 0644]
patches.tizen/0537-iio-add-proximity-light-sensor-cm36651-driver.patch [new file with mode: 0644]
patches.tizen/0538-drm-exynos-Add-missing-includes.patch [new file with mode: 0644]
patches.tizen/0539-drm-exynos-Remove-module.h-header-inclusion.patch [new file with mode: 0644]
patches.tizen/0540-drm-exynos-Add-missing-of.h-header-include.patch [new file with mode: 0644]
patches.tizen/0541-drm-exynos-Remove-redundant-error-messages.patch [new file with mode: 0644]
patches.tizen/0542-drm-exynos-Add-NULL-pointer-check.patch [new file with mode: 0644]
patches.tizen/0543-drm-exynos-fix-fimd-pixel-format-setting.patch [new file with mode: 0644]
patches.tizen/0544-drm-exynos-fix-WINDOWS_NR-checking-to-vidi-driver.patch [new file with mode: 0644]
patches.tizen/0545-drm-exynos-remove-ignoring-return-value-warning-in-h.patch [new file with mode: 0644]
patches.tizen/0546-drm-exynos-Remove-redundant-use-of-of_match_ptr-macr.patch [new file with mode: 0644]
patches.tizen/0547-drm-exynos-do-not-use-mode_set_base-function-directl.patch [new file with mode: 0644]
patches.tizen/0548-drm-exynos-fimd-Hold-pointer-to-driver-data-in-conte.patch [new file with mode: 0644]
patches.tizen/0549-drm-exynos-fimd-Add-support-for-FIMD-versions-withou.patch [new file with mode: 0644]
patches.tizen/0550-drm-exynos-fimd-Add-support-for-FIMD-variants-with-c.patch [new file with mode: 0644]
patches.tizen/0551-drm-exynos-fimd-Add-support-for-S3C64xx-SoCs.patch [new file with mode: 0644]
patches.tizen/0552-drm-exynos-hdmi-use-drm_display_mode-to-check-the-su.patch [new file with mode: 0644]
patches.tizen/0553-drm-exynos-Remove-tracking-log-functions.patch [new file with mode: 0644]
patches.tizen/0554-drm-exynos-check-a-pixel-format-to-a-particular-wind.patch [new file with mode: 0644]
patches.tizen/0555-drm-exynos-use-drm_calloc_large-when-allocates-point.patch [new file with mode: 0644]
patches.tizen/0556-drm-exynos-remove-duplicated-error-routine-and-unnec.patch [new file with mode: 0644]
patches.tizen/0557-drm-exynos-add-exynos_drm_gem_get_dmabuf-function.patch [new file with mode: 0644]
patches.tizen/0558-drm-exynos-add-dmabuf-sync-support-for-g2d-driver.patch [new file with mode: 0644]
patches.tizen/0559-vt-disable-console-blank.patch [new file with mode: 0644]
patches.tizen/0560-mfd-max8998-Add-irq-domain-support.patch [new file with mode: 0644]
patches.tizen/0561-regulator-max8998-Use-arrays-for-specifying-voltages.patch [new file with mode: 0644]
patches.tizen/0562-mfd-max8998-Add-support-for-Device-Tree.patch [new file with mode: 0644]
patches.tizen/0563-dts-universal-c210-board.patch [new file with mode: 0644]
patches.tizen/0564-drm-exynos-fimd-disable-windows-before-registering-d.patch [new file with mode: 0644]
patches.tizen/0565-drm-exynos-simplify-and-unify-subdrivers-registratio.patch [new file with mode: 0644]
patches.tizen/0566-drm-exynos-add-support-for-separate-iommu-mapping-ma.patch [new file with mode: 0644]
patches.tizen/0567-iommu-exynos-remove-support-for-combined-sysmmu-cont.patch [new file with mode: 0644]
patches.tizen/0568-iommu-exynos-remove-support-for-multiple-sysmmu-s-pe.patch [new file with mode: 0644]
patches.tizen/0569-iommu-exynos-simplify-some-functions.patch [new file with mode: 0644]
patches.tizen/0570-iommu-exynos-register-iommu-aware-dma-ops-for-client.patch [new file with mode: 0644]
patches.tizen/0571-iommu-exynos-add-dummy-driver-for-enabling-runtime-p.patch [new file with mode: 0644]
patches.tizen/0572-ARM-Exynos4-add-clocks-for-SYSMMU-controller-and-ena.patch [new file with mode: 0644]
patches.tizen/0573-ARM-Exynos4-dts-disable-CMA-support-for-MFC-obsolete.patch [new file with mode: 0644]
patches.tizen/0574-ARM-dts-Add-missing-aliases-for-I2C-bus-controllers-.patch [new file with mode: 0644]
patches.tizen/0575-exynos4-is-Fix-compressed-format-setting-in-fimc-cap.patch [new file with mode: 0644]
patches.tizen/0576-s5c73m3-Set-default-data-plane-lengths-for-interleav.patch [new file with mode: 0644]
patches.tizen/0577-brcmfmac-Add-generic-platform-support.patch [new file with mode: 0644]
patches.tizen/0578-clk-max77686-Correct-callback-used-for-checking-cloc.patch [new file with mode: 0644]
patches.tizen/0579-clk-max77686-Provide-.recalc_rate-operation.patch [new file with mode: 0644]
patches.tizen/0580-mfd-max77686-Enable-register-cache.patch [new file with mode: 0644]
patches.tizen/0581-clk-max77686-Refactor-successful-exit-of-probe-funct.patch [new file with mode: 0644]
patches.tizen/0582-clk-max77686-Make-max77686_clk_register-return-struc.patch [new file with mode: 0644]
patches.tizen/0583-clk-max77686-Fix-clean-up-in-error-and-remove-paths.patch [new file with mode: 0644]
patches.tizen/0584-clk-max77686-Refactor-driver-data-handling.patch [new file with mode: 0644]
patches.tizen/0585-clk-max77686-Register-OF-clock-provider.patch [new file with mode: 0644]
patches.tizen/0586-of-irq-Pass-trigger-type-in-IRQ-resource-flags.patch [new file with mode: 0644]
patches.tizen/0587-ARM-dts-exynos4412-slp_pq-Allow-using-max77686-as-cl.patch [new file with mode: 0644]
patches.tizen/0588-ARM-dts-exynos4412-slp_pq-Enable-WLAN-chip.patch [new file with mode: 0644]
patches.tizen/0589-s5p-jpeg-Add-initial-device-tree-support-for-S5PV210.patch [new file with mode: 0644]
patches.tizen/0590-ARM-dts-exynos4412-slp_pq-always-turn-on-ESAFEOUT1.patch [new file with mode: 0644]
patches.tizen/0591-dmabuf-sync-update-it-to-patch-v8.patch [new file with mode: 0644]
patches.tizen/0592-usb-phy-samsung-do-not-check-otg-host-to-clear-it.patch [new file with mode: 0644]
patches.tizen/0593-usb-ehci-s5p-specify-host-mode-to-phy-driver.patch [new file with mode: 0644]
patches.tizen/0594-usb-gadget-s3c-hsotg-specify-device-mode-before-init.patch [new file with mode: 0644]
patches.tizen/0595-ARM-dts-exynos4x12-add-usb-sysreg-node.patch [new file with mode: 0644]
patches.tizen/0596-Revert-drm-exynos-add-dt-binding-documentation-for-r.patch [new file with mode: 0644]
patches.tizen/0597-Revert-ARM-dts-add-a-rotator-node-for-exynos4.patch [new file with mode: 0644]
patches.tizen/0598-Revert-drm-exynos-add-device-tree-support-for-rotato.patch [new file with mode: 0644]
patches.tizen/0599-drm-exynos-add-device-tree-support-for-rotator.patch [new file with mode: 0644]
patches.tizen/0600-ARM-dts-Add-rotator-node-for-exynos4210.patch [new file with mode: 0644]
patches.tizen/0601-ARM-dts-Add-rotator-node-for-exynos4x12.patch [new file with mode: 0644]
patches.tizen/0602-ARM-dts-Add-rotator-node-for-exynos5250.patch [new file with mode: 0644]
patches.tizen/0603-ARM-dts-exynos4x12-specify-iommu-node-for-rotator.patch [new file with mode: 0644]
patches.tizen/0604-Revert-ARM-dts-exynos4x12-add-usb-sysreg-node.patch [new file with mode: 0644]
patches.tizen/0605-usb-gadget-u_ether-convert-into-module.patch [new file with mode: 0644]
patches.tizen/0606-usb-gadget-rndis-convert-into-module.patch [new file with mode: 0644]
patches.tizen/0607-usb-gadget-u_ether-construct-with-default-values-and.patch [new file with mode: 0644]
patches.tizen/0608-usb-gadget-f_ncm-convert-to-new-function-interface-w.patch [new file with mode: 0644]
patches.tizen/0609-usb-gadget-ncm-convert-to-new-function-interface.patch [new file with mode: 0644]
patches.tizen/0610-usb-gadget-f_ncm-remove-compatibility-layer.patch [new file with mode: 0644]
patches.tizen/0611-usb-gadget-f_ncm-use-usb_gstrings_attach.patch [new file with mode: 0644]
patches.tizen/0612-usb-gadget-f_ncm-add-configfs-support.patch [new file with mode: 0644]
patches.tizen/0613-usb-gadget-add-helpers-for-configfs-support-for-USB-.patch [new file with mode: 0644]
patches.tizen/0614-usb-gadget-f_ecm-convert-to-new-function-interface-w.patch [new file with mode: 0644]
patches.tizen/0615-usb-gadget-cdc2-convert-to-new-interface-of-f_ecm.patch [new file with mode: 0644]
patches.tizen/0616-usb-gadget-f_ecm-use-usb_gstrings_attach.patch [new file with mode: 0644]
patches.tizen/0617-usb-gadget-f_ecm-add-configfs-support.patch [new file with mode: 0644]
patches.tizen/0618-usb-gadget-f_obex-use-usb_gstrings_attach.patch [new file with mode: 0644]
patches.tizen/0619-usb-gadget-nokia-convert-to-new-interface-of-f_obex.patch [new file with mode: 0644]
patches.tizen/0620-usb-gadget-f_obex-remove-compatibility-layer.patch [new file with mode: 0644]
patches.tizen/0621-usb-gadget-phonet-move-global-dev-variable-to-its-us.patch [new file with mode: 0644]
patches.tizen/0622-usb-gadget-f_phonet-convert-to-new-function-interfac.patch [new file with mode: 0644]
patches.tizen/0623-usb-gadget-nokia-convert-to-new-interface-of-f_phone.patch [new file with mode: 0644]
patches.tizen/0624-usb-gadget-f_phonet-remove-compatibility-layer.patch [new file with mode: 0644]
patches.tizen/0625-usb-gadget-nokia-convert-to-new-interface-of-f_ecm.patch [new file with mode: 0644]
patches.tizen/0626-usb-gadget-f_phonet-add-configfs-support.patch [new file with mode: 0644]
patches.tizen/0627-usb-gadget-u_ether-allow-getting-binary-form-host-ad.patch [new file with mode: 0644]
patches.tizen/0628-usb-gadget-ether-convert-to-new-interface-of-f_ecm.patch [new file with mode: 0644]
patches.tizen/0629-usb-gadget-f_eem-convert-to-new-function-interface-w.patch [new file with mode: 0644]
patches.tizen/0630-usb-gadget-ether-convert-to-new-interface-of-f_eem.patch [new file with mode: 0644]
patches.tizen/0631-usb-gadget-f_eem-remove-compatibility-layer.patch [new file with mode: 0644]
patches.tizen/0632-usb-gadget-f_eem-use-usb_gstrings_attach.patch [new file with mode: 0644]
patches.tizen/0633-usb-gadget-f_eem-add-configfs-support.patch [new file with mode: 0644]
patches.tizen/0634-usb-gadget-multi-Remove-unused-include.patch [new file with mode: 0644]
patches.tizen/0635-usb-gadget-f_subset-convert-to-new-function-interfac.patch [new file with mode: 0644]
patches.tizen/0636-usb-gadget-ether-convert-to-new-interface-of-f_subse.patch [new file with mode: 0644]
patches.tizen/0637-usb-gadget-f_subset-use-usb_gstrings_attach.patch [new file with mode: 0644]
patches.tizen/0638-usb-gadget-f_subset-add-configfs-support.patch [new file with mode: 0644]
patches.tizen/0639-usb-gadget-f_rndis-convert-to-new-function-interface.patch [new file with mode: 0644]
patches.tizen/0640-usb-gadget-ether-convert-to-new-interface-of-f_rndis.patch [new file with mode: 0644]
patches.tizen/0641-usb-gadget-rndis-init-exit-rndis-at-module-load-unlo.patch [new file with mode: 0644]
patches.tizen/0642-usb-gadget-f_rndis-use-usb_gstrings_attach.patch [new file with mode: 0644]
patches.tizen/0643-usb-gadget-f_rndis-add-configfs-support.patch [new file with mode: 0644]
patches.tizen/0644-usb-gadget-f_mass_storage-fix-default-product-name.patch [new file with mode: 0644]
patches.tizen/0645-usb-gadget-Kconfig-fix-separate-building-of-configfs.patch [new file with mode: 0644]
patches.tizen/0646-usb-gadget-f_ecm-fix-missing-unlock-on-error-in-ecm_.patch [new file with mode: 0644]
patches.tizen/0647-usb-gadget-f_ncm-fix-missing-unlock-on-error-in-ncm_.patch [new file with mode: 0644]
patches.tizen/0648-usb-gadget-f_subset-fix-missing-unlock-on-error-in-g.patch [new file with mode: 0644]
patches.tizen/0649-usb-gadget-Kconfig-Fix-configfs-based-RNDIS-function.patch [new file with mode: 0644]
patches.tizen/0650-usb-gadget-ether-put_usb_function-on-unbind.patch [new file with mode: 0644]
patches.tizen/0651-usb-gadget-free-opts-struct-on-error-recovery.patch [new file with mode: 0644]
patches.tizen/0652-usb-gadget-multi-fix-error-return-code-in-cdc_do_con.patch [new file with mode: 0644]
patches.tizen/0653-usb-gadget-f_phonet-remove-unused-preprocessor-condi.patch [new file with mode: 0644]
patches.tizen/0654-usb-gadget-cdc2-fix-conversion-to-new-interface-of-f.patch [new file with mode: 0644]
patches.tizen/0655-usb-gadget-configfs-keep-a-function-if-it-is-not-suc.patch [new file with mode: 0644]
patches.tizen/0656-usb-gadget-configfs-add-a-method-to-unregister-the-g.patch [new file with mode: 0644]
patches.tizen/0657-usb-gadget-create-a-utility-module-for-mass_storage.patch [new file with mode: 0644]
patches.tizen/0658-usb-gadget-f_mass_storage-factor-out-a-header-file.patch [new file with mode: 0644]
patches.tizen/0659-usb-gadget-f_mass_storage-add-a-level-of-indirection.patch [new file with mode: 0644]
patches.tizen/0660-usb-gadget-f_mass_storage-use-usb_gstrings_attach.patch [new file with mode: 0644]
patches.tizen/0661-usb-gadget-f_mass_storage-split-fsg_common-initializ.patch [new file with mode: 0644]
patches.tizen/0662-usb-gadget-f_mass_storage-use-fsg_common_setup-in-fs.patch [new file with mode: 0644]
patches.tizen/0663-usb-gadget-f_mass_storage-use-fsg_common_set_num_buf.patch [new file with mode: 0644]
patches.tizen/0664-usb-gadget-f_mass_storage-use-fsg_common_set_nluns-i.patch [new file with mode: 0644]
patches.tizen/0665-usb-gadget-f_mass_storage-use-fsg_common_set_ops-_pr.patch [new file with mode: 0644]
patches.tizen/0666-usb-gadget-f_mass_storage-use-fsg_common_set_cdev-in.patch [new file with mode: 0644]
patches.tizen/0667-usb-gadget-f_mass_storage-use-fsg_common_create_luns.patch [new file with mode: 0644]
patches.tizen/0668-usb-gadget-f_mass_storage-use-fsg_common_set_inquiry.patch [new file with mode: 0644]
patches.tizen/0669-usb-gadget-f_mass_storage-use-fsg_common_run_thread-.patch [new file with mode: 0644]
patches.tizen/0670-usb-gadget-f_mass_storage-convert-to-new-function-in.patch [new file with mode: 0644]
patches.tizen/0671-usb-gadget-mass_storage-convert-to-new-interface-of-.patch [new file with mode: 0644]
patches.tizen/0672-usb-gadget-storage_common-make-attribute-operations-.patch [new file with mode: 0644]
patches.tizen/0673-usb-gadget-storage_common-add-methods-to-show-store-.patch [new file with mode: 0644]
patches.tizen/0674-usb-gadget-f_mass_storage-add-configfs-support.patch [new file with mode: 0644]
patches.tizen/0675-usb-gadget-acm_ms-convert-to-new-interface-of-f_mass.patch [new file with mode: 0644]
patches.tizen/0676-usb-gadget-multi-convert-to-new-interface-of-f_ecm.patch [new file with mode: 0644]
patches.tizen/0677-usb-gadget-multi-convert-to-new-interface-of-f_rndis.patch [new file with mode: 0644]
patches.tizen/0678-usb-gadget-multi-convert-to-new-interface-of-f_mass_.patch [new file with mode: 0644]
patches.tizen/0679-usb-gadget-f_mass_storage-remove-compatibility-layer.patch [new file with mode: 0644]
patches.tizen/0680-usb-gadget-mass_storage-merge-usb_f_mass_storage-mod.patch [new file with mode: 0644]
patches.tizen/0681-clk-Provide-not-locked-variant-of-of_clk_get_from_pr.patch [new file with mode: 0644]
patches.tizen/0682-clkdev-Fix-race-condition-in-clock-lookup-from-devic.patch [new file with mode: 0644]
patches.tizen/0683-clk-Add-common-__clk_get-__clk_put-implementations.patch [new file with mode: 0644]
patches.tizen/0684-clk-Assign-module-owner-of-a-clock-being-registered.patch [new file with mode: 0644]
patches.tizen/0685-clk-Implement-clk_unregister.patch [new file with mode: 0644]
patches.tizen/0686-media-V4L2-add-temporary-clock-helpers.patch [new file with mode: 0644]
patches.tizen/0687-media-V4L2-add-a-device-pointer-to-struct-v4l2_subde.patch [new file with mode: 0644]
patches.tizen/0688-media-V4L2-support-asynchronous-subdevice-registrati.patch [new file with mode: 0644]
patches.tizen/0689-media-V4L2-fix-compilation-if-CONFIG_I2C-is-undefine.patch [new file with mode: 0644]
patches.tizen/0690-media-V4L-Drop-bus_type-check-in-v4l2-async-match-fu.patch [new file with mode: 0644]
patches.tizen/0691-media-V4L-Rename-v4l2_async_bus_-to-v4l2_async_match.patch [new file with mode: 0644]
patches.tizen/0692-media-V4L-Add-V4L2_ASYNC_MATCH_OF-subdev-matching-ty.patch [new file with mode: 0644]
patches.tizen/0693-media-V4L-Rename-subdev-field-of-struct-v4l2_async_n.patch [new file with mode: 0644]
patches.tizen/0694-media-V4L-Merge-struct-v4l2_async_subdev_list-with-s.patch [new file with mode: 0644]
patches.tizen/0695-media-v4l-of-Use-of_get_child_by_name.patch [new file with mode: 0644]
patches.tizen/0696-media-v4l-of-Drop-acquired-reference-to-node-when-ge.patch [new file with mode: 0644]
patches.tizen/0697-media-v4l-async-Make-it-safe-to-unregister-unregiste.patch [new file with mode: 0644]
patches.tizen/0698-media-v4l2-async-Use-proper-list-head-for-iteration-.patch [new file with mode: 0644]
patches.tizen/0699-media-media-OF-add-sync-on-green-active-property.patch [new file with mode: 0644]
patches.tizen/0700-media-exynos4-is-Fix-potential-NULL-pointer-derefere.patch [new file with mode: 0644]
patches.tizen/0701-media-exynos4-is-Initialize-the-ISP-subdev-sd-owner-.patch [new file with mode: 0644]
patches.tizen/0702-media-exynos4-is-Add-missing-MODULE_LICENSE-for-exyn.patch [new file with mode: 0644]
patches.tizen/0703-media-exynos4-is-Add-missing-v4l2_device_unregister-.patch [new file with mode: 0644]
patches.tizen/0704-media-exynos4-is-Simplify-sclk_cam-clocks-handling.patch [new file with mode: 0644]
patches.tizen/0705-media-exynos4-is-Annotate-unused-functions.patch [new file with mode: 0644]
patches.tizen/0706-media-exynos4-is-Print-error-message-on-timeout.patch [new file with mode: 0644]
patches.tizen/0707-media-exynos4-is-Ensure-the-FIMC-gate-clock-is-disab.patch [new file with mode: 0644]
patches.tizen/0708-media-V4L-s5c73m3-Add-format-propagation-for-TRY-for.patch [new file with mode: 0644]
patches.tizen/0709-dma-pl330-rip-out-broken-redundant-ID-probing.patch [new file with mode: 0644]
patches.tizen/0710-dma-pl330-use-dma_addr_t-for-describing-bus-addresse.patch [new file with mode: 0644]
patches.tizen/0711-ARM-tizen_defconfig-disable-s5p-ehci.patch [new file with mode: 0644]
patches.tizen/0712-spi-spi-s3c64xx-Remove-platform-dependent-code.patch [new file with mode: 0644]
patches.tizen/0713-spi-spi-s3c64xx-Correct-functions-namespacing.patch [new file with mode: 0644]
patches.tizen/0714-spi-spi-s3c64xx-Refactor-dma-sections.patch [new file with mode: 0644]
patches.tizen/0715-spi-spi-s3c64xx-Add-coherent-buffers-for-dma-transfe.patch [new file with mode: 0644]
patches.tizen/0716-spi-spi-s3c64xx-s3c64xx_prepare_dma-clean-up.patch [new file with mode: 0644]
patches.tizen/0717-spi-spi-s3c64xx-Remove-unused-code.patch [new file with mode: 0644]
patches.tizen/0718-media-s5c73m3-Change-SPI-write-packet-size.patch [new file with mode: 0644]
patches.tizen/0719-media-s5c73m3-s5c73m3_spi_write-clean-up.patch [new file with mode: 0644]
patches.tizen/0720-V4L-s5k6a3-Add-DT-binding-documentation.patch [new file with mode: 0644]
patches.tizen/0721-V4L-Add-driver-for-s5k6a3-image-sensor.patch [new file with mode: 0644]
patches.tizen/0722-V4L-s5k6a3-Add-support-for-asynchronous-subdev-regis.patch [new file with mode: 0644]
patches.tizen/0723-Revert-V4L-s5c73m3-Initial-device-tree-support.patch [new file with mode: 0644]
patches.tizen/0724-media-s5c73m3-Convert-to-devm_gpio_request_one.patch [new file with mode: 0644]
patches.tizen/0725-ARM-dts-Add-missing-data-lanes-property-for-exynos44.patch [new file with mode: 0644]
patches.tizen/0726-ARM-dts-Add-clock-cells-property-to-camera-node-in-e.patch [new file with mode: 0644]
patches.tizen/0727-ARM-dts-Add-clock-properties-for-camera-sensors-on-e.patch [new file with mode: 0644]
patches.tizen/0728-ARM-dts-Update-s5c73m3-sensor-gpio-properties-for-ex.patch [new file with mode: 0644]
patches.tizen/0729-V4L-s5c73m3-Add-device-tree-support.patch [new file with mode: 0644]
patches.tizen/0730-exynos4-is-Add-clock-provider-for-the-external-clock.patch [new file with mode: 0644]
patches.tizen/0731-exynos4-is-Use-external-s5k6a3-sensor-driver.patch [new file with mode: 0644]
patches.tizen/0732-exynos4-is-Add-support-for-asynchronous-sensor-subdd.patch [new file with mode: 0644]
patches.tizen/0733-Revert-s5k5baf-add-camera-sensor-driver.patch [new file with mode: 0644]
patches.tizen/0734-Revert-m5mols-added-device-tree-support.patch [new file with mode: 0644]
patches.tizen/0735-Revert-m5mols-device-initialization-moved-to-V4L2-re.patch [new file with mode: 0644]
patches.tizen/0736-media-media-i2c-Convert-to-gpio_request_one.patch [new file with mode: 0644]
patches.tizen/0737-media-media-i2c-Convert-to-devm_kzalloc.patch [new file with mode: 0644]
patches.tizen/0738-media-media-i2c-Convert-to-devm_gpio_request_one.patch [new file with mode: 0644]
patches.tizen/0739-media-media-i2c-Convert-to-devm_regulator_bulk_get.patch [new file with mode: 0644]
patches.tizen/0740-media-m5mols-Convert-to-devm_request_irq.patch [new file with mode: 0644]
patches.tizen/0741-ARM-dts-exynos4210-trats-update-clocks-and-gpios-in-.patch [new file with mode: 0644]
patches.tizen/0742-s5k5baf-add-camera-sensor-driver.patch [new file with mode: 0644]
patches.tizen/0743-m5mols-change-module-name-to-lowercase.patch [new file with mode: 0644]
patches.tizen/0744-m5mols-add-device-tree-support.patch [new file with mode: 0644]
patches.tizen/0745-m5mols-add-clock-support.patch [new file with mode: 0644]
patches.tizen/0746-m5mols-add-async-subdev-registration.patch [new file with mode: 0644]
patches.tizen/0747-ARM-dts-exynos4210-trats-change-compatible-for-m5mol.patch [new file with mode: 0644]
patches.tizen/0748-ARM-dts-exynos4210-trats-modify-m5mols-node-accordin.patch [new file with mode: 0644]
patches.tizen/0749-exynos4-is-Fix-the-writeback-clocks-handling.patch [new file with mode: 0644]
patches.tizen/0750-tizen_defconfig-update.patch [new file with mode: 0644]
patches.tizen/0751-Revert-video-exynos_dsi-Use-generic-PHY-driver.patch [new file with mode: 0644]
patches.tizen/0752-Revert-media-exynos4-is-Use-the-generic-MIPI-CSIS-PH.patch [new file with mode: 0644]
patches.tizen/0753-Revert-phy-Add-driver-for-Exynos-MIPI-CSIS-DSIM-DPHY.patch [new file with mode: 0644]
patches.tizen/0754-Revert-drivers-phy-add-generic-PHY-framework.patch [new file with mode: 0644]
patches.tizen/0755-drivers-phy-add-generic-PHY-framework.patch [new file with mode: 0644]
patches.tizen/0756-phy-Add-driver-for-Exynos-MIPI-CSIS-DSIM-DPHYs.patch [new file with mode: 0644]
patches.tizen/0757-media-exynos4-is-Use-the-generic-MIPI-CSIS-PHY-drive.patch [new file with mode: 0644]
patches.tizen/0758-video-exynos_dsi-Use-generic-PHY-driver.patch [new file with mode: 0644]
patches.tizen/0759-ARM-dts-Add-node-aliases-for-ISP_I2C-bus-controllers.patch [new file with mode: 0644]
patches.tizen/0760-ARM-dts-Add-common-jpeg-codec-node-for-Exynos4-SoCs.patch [new file with mode: 0644]
patches.tizen/0761-tizen_defconfig-update.patch [new file with mode: 0644]
patches.tizen/0762-HACK-usb-gadget-Fix-enumeration-on-boot.patch [new file with mode: 0644]
patches.tizen/0763-usb-s3c-hsotg-do-not-disconnect-gadget-when-receivin.patch [new file with mode: 0644]
patches.tizen/0764-WIP-usb-gadget-add-slp-composite-gadget.patch [new file with mode: 0644]
patches.tizen/0765-phy-Add-new-Exynos-USB-PHY-driver.patch [new file with mode: 0644]
patches.tizen/0766-usb-ehci-s5p-Change-to-use-phy-provided-by-the-gener.patch [new file with mode: 0644]
patches.tizen/0767-usb-s3c-hsotg-Use-the-new-Exynos-USB-phy-driver-with.patch [new file with mode: 0644]
patches.tizen/0768-ARM-dts-Add-new-USB-PHY-driver-to-dts-of-exynos4412-.patch [new file with mode: 0644]
patches.tizen/0769-tizen_defconfig-update.patch [new file with mode: 0644]
patches.tizen/0770-drm-exynos-fixed-YCbCr-start-addresses-port-for-inpu.patch [new file with mode: 0644]
patches.tizen/0771-mmc-dw-mmc-check-whether-card-is-busy-or-not-before-.patch [new file with mode: 0644]
patches.tizen/0772-phy-Correct-Exynos-USB-PHY-device-tree-documentation.patch [new file with mode: 0644]
patches.tizen/0773-ARM-dts-Correct-USB-PHY-use-in-exynos4412-slp_pq.dts.patch [new file with mode: 0644]
patches.tizen/0774-mmc-core-Update-the-ext-csd.rev-check-for-eMMC5.1.patch [new file with mode: 0644]
patches.tizen/0775-drivers-usb-s3c-hsotg-fix-gadget-unregistering.patch [new file with mode: 0644]
patches.tizen/0776-usb-gadget-s3c-hsotg-fix-non-dt-build.patch [new file with mode: 0644]
patches.tizen/0777-USB-gadget-s3c-hsotg-fix-protocol-stall-handling.patch [new file with mode: 0644]
patches.tizen/0778-USB-gadget-s3c-hsotg-fix-dedicated-fifos-handling.patch [new file with mode: 0644]
patches.tizen/0779-USB-gadget-s3c-hsotg-fix-clear-feature-ENDPOINT_HALT.patch [new file with mode: 0644]
patches.tizen/0780-ARM-EXYNOS-Avoid-potential-invalid-genpd-pointer-der.patch [new file with mode: 0644]
patches.tizen/0781-exynos4-is-Enable-registration-of-fimc-lite-devices-.patch [new file with mode: 0644]
patches.tizen/0782-exynos4-is-Do-not-unnecessarily-activate-fimc-lite-d.patch [new file with mode: 0644]
patches.tizen/0783-exynos4-is-Do-not-unnecessarily-activate-fimc-device.patch [new file with mode: 0644]
patches.tizen/0784-exynos4-is-Do-not-unnecessarily-activate-fimc-is-dev.patch [new file with mode: 0644]
patches.tizen/0785-exynos4-is-Make-fimc-lite-dependency-on-fimc-is-expl.patch [new file with mode: 0644]
patches.tizen/0786-ARM-exynos-Make-fimc-lite-nodes-children-of-fimc-is-.patch [new file with mode: 0644]
patches.tizen/0787-exynos4-is-Disable-ISP-UART-clock-gating.patch [new file with mode: 0644]
patches.tizen/0788-ARM-dts-Assign-correct-UART-gate-clock-to-Exynos4x12.patch [new file with mode: 0644]
patches.tizen/0789-Revert-exynos4-is-Ungate-uart-clocks-on-system-suspe.patch [new file with mode: 0644]
patches.tizen/0790-dmaengine-add-dma_slave_get_caps-api.patch [new file with mode: 0644]
patches.tizen/0791-dma-pl330-Implement-device_slave_caps.patch [new file with mode: 0644]
patches.tizen/0792-dmaengine-add-interface-of-dma_get_slave_channel.patch [new file with mode: 0644]
patches.tizen/0793-dma-pl330-split-off-common-code-to-give-back-descrip.patch [new file with mode: 0644]
patches.tizen/0794-dmaengine-make-dma_submit_error-return-an-error-code.patch [new file with mode: 0644]
patches.tizen/0795-dma-pl330-Fix-handling-of-TERMINATE_ALL-while-proces.patch [new file with mode: 0644]
patches.tizen/0796-dmaengine-dma_slave_caps-remove-sg-entries.patch [new file with mode: 0644]
patches.tizen/0797-dmaengine-pl330-use-dma_set_max_seg_size-to-set-the-.patch [new file with mode: 0644]
patches.tizen/0798-dts-arm-add-missing-clock-properties-to-MCT-for-Exyn.patch [new file with mode: 0644]
patches.tizen/0799-extcon-Add-extcon-port-driver-to-maintain-compatibil.patch [new file with mode: 0644]
patches.tizen/0800-extcon-max77693-Define-dock-constant-to-remove-compi.patch [new file with mode: 0644]
patches.tizen/0801-extcon-Add-extcon-port-platform-device-to-update-uev.patch [new file with mode: 0644]
patches.tizen/0802-tizen-Update-default-configuration-to-enable-extcon-.patch [new file with mode: 0644]
patches.tizen/0803-WIP-extcon-do-not-update-cable-state-if-notifier-can.patch [new file with mode: 0644]
patches.tizen/0804-drm-Add-drm-backlight-subsystem-support.patch [new file with mode: 0644]
patches.tizen/0805-drm-exynos-support-drm-backlight-dpms-on-off.patch [new file with mode: 0644]
patches.tizen/0806-usb-gadget-slp-remove-rndis_init.patch [new file with mode: 0644]
patches.tizen/0807-V4L-Add-mem2mem-ioctl-and-file-operation-helpers.patch [new file with mode: 0644]
patches.tizen/0808-s5p-jpeg-Initialize-vfd_decoder-vfl_dir-field.patch [new file with mode: 0644]
patches.tizen/0809-s5p-jpeg-Use-mem-to-mem-ioctl-helpers.patch [new file with mode: 0644]
patches.tizen/0810-s5p-jpeg-Add-support-for-Exynos4x12.patch [new file with mode: 0644]
patches.tizen/0811-video-cdf-panel-support-lcd-class-operations-for-s6d.patch [new file with mode: 0644]
patches.tizen/0812-arm-dst-add-SLP-Pegasus-Dual-board-for-testing-Exyno.patch [new file with mode: 0644]
patches.tizen/0813-ARM-dts-Correct-audio-clock-number-in-exynos4412-slp.patch [new file with mode: 0644]
patches.tizen/0814-vrange-Add-basic-data-structure-and-functions.patch [new file with mode: 0644]
patches.tizen/0815-vrange-Add-vrange-support-to-mm_structs.patch [new file with mode: 0644]
patches.tizen/0816-vrange-Clear-volatility-on-new-mmaps.patch [new file with mode: 0644]
patches.tizen/0817-vrange-Add-support-for-volatile-ranges-on-file-mappi.patch [new file with mode: 0644]
patches.tizen/0818-vrange-Add-new-vrange-2-system-call.patch [new file with mode: 0644]
patches.tizen/0819-vrange-Add-basic-functions-to-purge-volatile-pages.patch [new file with mode: 0644]
patches.tizen/0820-vrange-Purge-vrange-anon-pages-when-memory-is-tight.patch [new file with mode: 0644]
patches.tizen/0821-vrange-Send-SIGBUS-when-user-try-to-access-purged-pa.patch [new file with mode: 0644]
patches.tizen/0822-vrange-Allocate-vroot-dynamically.patch [new file with mode: 0644]
patches.tizen/0823-vrange-Add-vrange-LRU-list-for-purging.patch [new file with mode: 0644]
patches.tizen/0824-vrange-Add-vrange-shrinking-basic-functions-for-swap.patch [new file with mode: 0644]
patches.tizen/0825-vrange-Purging-vrange-anon-pages-from-shrinker.patch [new file with mode: 0644]
patches.tizen/0826-vrange-Support-background-purging-for-vrange-file.patch [new file with mode: 0644]
patches.tizen/0827-vrange-Add-vmstat-counter-about-purged-page.patch [new file with mode: 0644]
patches.tizen/0828-vrange-Add-ARM-vrange-syscall.patch [new file with mode: 0644]
patches.tizen/0829-devfreq-exynos4-Support-DT-in-exynos4-busfreq-driver.patch [new file with mode: 0644]
patches.tizen/0830-dts-exynos4x12-Add-device-tree-node-for-exynos4-busf.patch [new file with mode: 0644]
patches.tizen/0831-WORKAROUND-Temporary-workaround-for-Suspend-To-Ram.patch [new file with mode: 0644]
patches.tizen/0832-ARM-defconfig-enable-the-mmc-clock-gating-config.patch [new file with mode: 0644]
patches.tizen/0833-arm-exynos-Fix-SFR-base-address-of-DMC-in-EXYNOS4-se.patch [new file with mode: 0644]
patches.tizen/0834-regulator-max77686-Support-DVS-control-in-max77686-r.patch [new file with mode: 0644]
patches.tizen/0835-ehci-s5p-Use-device-tree-to-get-name-of-desired-phy.patch [new file with mode: 0644]
patches.tizen/0836-dts-arm-Add-dts-file-for-the-exynos4412-odroidx2-boa.patch [new file with mode: 0644]
patches.tizen/0837-dts-arm-Add-support-for-new-Exynos-USB-phy-driver-to.patch [new file with mode: 0644]
patches.tizen/0838-ehci-s5p-Add-power-regulator-support.patch [new file with mode: 0644]
patches.tizen/0839-ehci-s5p-Add-second-clock-to-the-ehci-s5p-driver.patch [new file with mode: 0644]
patches.tizen/0840-dts-arm-Add-voltage-regulator-and-additional-clock-s.patch [new file with mode: 0644]
patches.tizen/0841-phy-exynos-usb-Fix-referenct-counting.patch [new file with mode: 0644]
patches.tizen/0842-phy-exynos-Change-order-of-initialization-of-phy-in-.patch [new file with mode: 0644]
patches.tizen/0843-regulator-dts-slp-PD-MAX8997-device-tree-nodes-defin.patch [new file with mode: 0644]
patches.tizen/0844-ARM-cpufreq-Parse-CPUFREQ-s-voltage-table-passed-as-.patch [new file with mode: 0644]
patches.tizen/0845-ARM-clk-exynos-pll35xx-Extend-pll35xx_set_rate-to-su.patch [new file with mode: 0644]
patches.tizen/0846-cpufreq-exynos4x12-Support-the-frequency-change-only.patch [new file with mode: 0644]
patches.tizen/0847-cosmetic-Remove-extern-from-exynos_of_parse_freq_tab.patch [new file with mode: 0644]
patches.tizen/0848-dts-cpufreq-exynos4212-pegasusD-Enable-support-for-c.patch [new file with mode: 0644]
patches.tizen/0849-dts-thermal-exynos4212-pegasusD-Device-tree-node-def.patch [new file with mode: 0644]
patches.tizen/0850-dts-exynos4412-redwood-Adjust-REDWOOD-dts-to-support.patch [new file with mode: 0644]
patches.tizen/0851-usb-gadget-Refcount-for-gadget-pullup.patch [new file with mode: 0644]
patches.tizen/0852-Revert-HACK-usb-gadget-Fix-enumeration-on-boot.patch [new file with mode: 0644]
patches.tizen/0853-drivers-iommu-add-workaround-for-multiple-suspend-re.patch [new file with mode: 0644]
patches.tizen/0854-media-fimc-fix-clock-management-in-suspend-resume-pa.patch [new file with mode: 0644]
patches.tizen/0855-media-s5p-jpeg-fix-clock-management-in-suspend-resum.patch [new file with mode: 0644]
patches.tizen/0856-exynos_drm_ipp-fix-get-property-IOCTL.patch [new file with mode: 0644]
patches.tizen/0857-exynos_drm-replace-enums-by-__u32-in-structs-used-in.patch [new file with mode: 0644]
patches.tizen/0858-exynos_drm_fimc-simplify-pre-scaler-ratio-calculatio.patch [new file with mode: 0644]
patches.tizen/0859-exynos_drm_fimc-rename-fimc_handle_irq-to-fimc_mask_.patch [new file with mode: 0644]
patches.tizen/0860-exynos_drm_fimc-replace-hw-access-macros-with-functi.patch [new file with mode: 0644]
patches.tizen/0861-exynos_drm_fimc-replace-mutex-by-spinlock.patch [new file with mode: 0644]
patches.tizen/0862-exynos_drm_fimc-simplify-and-rename-fimc_dst_get_buf.patch [new file with mode: 0644]
patches.tizen/0863-charger-max77693-code-cleaning.patch [new file with mode: 0644]
patches.tizen/0864-charger-max77693-Fix-initial-charger-configuration-p.patch [new file with mode: 0644]
patches.tizen/0865-charger-manager-Make-charge_now-node-under-batter-sy.patch [new file with mode: 0644]
patches.tizen/0866-extcon-Add-an-API-to-get-extcon-device-from-dt-node.patch [new file with mode: 0644]
patches.tizen/0867-extcon-Add-EXPORT_SYMBOL_GPL-for-exported-functions.patch [new file with mode: 0644]
patches.tizen/0868-mfd-max77693-Add-max77693-pmuic-compatible.patch [new file with mode: 0644]
patches.tizen/0869-dts-Add-extcon-phandle-to-hsotg-node.patch [new file with mode: 0644]
patches.tizen/0870-dts-exynos4412-slp_pq-Remove-regulator_always_on-for.patch [new file with mode: 0644]
patches.tizen/0871-phy-exynos-usb-Remove-ref-counting-for-additional-re.patch [new file with mode: 0644]
patches.tizen/0872-s3c-hsotg-Regulator-switching-fix.patch [new file with mode: 0644]
patches.tizen/0873-s3c-hsotg-Fix-driver-context-storing.patch [new file with mode: 0644]
patches.tizen/0874-usb-gadget-udc-core-Add-extcon-hanling-to-reduce-pow.patch [new file with mode: 0644]
patches.tizen/0875-extcon-Extcon-load-time-modification.patch [new file with mode: 0644]
patches.tizen/0876-Fuel-Guague-MAX17042-Use-regmap-to-interface-with-in.patch [new file with mode: 0644]
patches.tizen/0877-M0-charging-Make-to-charge-battery-fully.patch [new file with mode: 0644]
patches.tizen/0878-charger-manager-Add-cm_chg_add_prorperty-macro.patch [new file with mode: 0644]
patches.tizen/0879-charger-manager-Replace-kzalloc-to-devm_kzalloc-and-.patch [new file with mode: 0644]
patches.tizen/0880-charger-manager-Add-default-battery-temperature-chec.patch [new file with mode: 0644]
patches.tizen/0881-battery-max17042-7-Fix-temperature-unit-to-milli-cen.patch [new file with mode: 0644]
patches.tizen/0882-drivers-s3c-hsotg-add-proper-suspend-resume-support.patch [new file with mode: 0644]
patches.tizen/0883-charger-manager-Parse-charger_desc-from-device-tree.patch [new file with mode: 0644]
patches.tizen/0884-drm-exynos-add-support-ARGB8888-for-ipp-fimc.patch [new file with mode: 0644]
patches.tizen/0885-drm-exynos-fix-to-calculate-offset-of-each-plane-for.patch [new file with mode: 0644]
patches.tizen/0886-ARM-dts-exynos4412-spl_pq-rename-the-fixed-regulator.patch [new file with mode: 0644]
patches.tizen/0887-mmc-dw_mmc-add-the-platdat-for-descriptor-number.patch [new file with mode: 0644]
patches.tizen/0888-ARM-dts-exynos4412_slp_pq-add-the-desc_num-for-mshc.patch [new file with mode: 0644]
patches.tizen/0889-ARM-atags_to_fdt-Add-support-for-passing-serial-numb.patch [new file with mode: 0644]
patches.tizen/0890-OF-fdt-Add-support-for-parsing-system-serial-number-.patch [new file with mode: 0644]
patches.tizen/0891-drivers-s3c-hsotg-fix-regulator-enable-sequence-in-r.patch [new file with mode: 0644]
patches.tizen/0892-drivers-s3c-hsotg-fix-incorrect-condition-for-clear_.patch [new file with mode: 0644]
patches.tizen/0893-drivers-s3c-hsotg-hide-some-not-really-needed-debug-.patch [new file with mode: 0644]
patches.tizen/0894-mmc-core-change-the-clkgate_delay-value-from-0-to-3.patch [new file with mode: 0644]
patches.tizen/0895-exynos-drm_fimd-support-lcdblk-system-register-contr.patch [new file with mode: 0644]
patches.tizen/0896-exynos-drm_fimd-remove-duplicated-clock-control-for-.patch [new file with mode: 0644]
patches.tizen/0897-display-panels-remove-duplicated-display_entity_set_.patch [new file with mode: 0644]
patches.tizen/0898-Revert-battery-max17042-7-Fix-temperature-unit-to-mi.patch [new file with mode: 0644]
patches.tizen/0899-charger-manager-Fix-unit-of-temperature-to-deci-cent.patch [new file with mode: 0644]
patches.tizen/0900-ADC-EXYNOS4412-Update-DT-and-board-configuration-to-.patch [new file with mode: 0644]
patches.tizen/0901-ntc_thermistor-Update-DT-and-board-configuration-to-.patch [new file with mode: 0644]
patches.tizen/0902-regulator-max77686-Correct-GPIOs-for-BUCK2-DVS-setti.patch [new file with mode: 0644]
patches.tizen/0903-cosmetic-max77686-Remove-unused-variable.patch [new file with mode: 0644]
patches.tizen/0904-cpufreq-Don-t-create-empty-sys-devices-system-cpu-cp.patch [new file with mode: 0644]
patches.tizen/0905-cpufreq-Store-cpufreq-policies-in-a-list.patch [new file with mode: 0644]
patches.tizen/0906-cpufreq-Add-boost-frequency-support-in-core.patch [new file with mode: 0644]
patches.tizen/0907-cpufreq-acpi-x86-Adjust-the-acpi-cpufreq.c-code-to-w.patch [new file with mode: 0644]
patches.tizen/0908-cpufreq-exynos-Extend-Exynos-cpufreq-driver-to-suppo.patch [new file with mode: 0644]
patches.tizen/0909-thermal-boost-Automatic-enable-disable-of-BOOST-feat.patch [new file with mode: 0644]
patches.tizen/0910-cpufreq-boost-Kconfig-Enable-software-managed-BOOST-.patch [new file with mode: 0644]
patches.tizen/0911-Documentation-cpufreq-boost-Update-BOOST-documentati.patch [new file with mode: 0644]
patches.tizen/0912-cpufreq-exynos4x12-Change-L0-driver-data-to-CPUFREQ_.patch [new file with mode: 0644]
patches.tizen/0913-ARM-exynos-Enable-boost-mode-for-exynos4412-redwood-.patch [new file with mode: 0644]
patches.tizen/0914-BOOST-Core-code-compliant-with-v9-of-the-patch.patch [new file with mode: 0644]
patches.tizen/0915-tizen-config-Enable-THERMAL-and-BOOST.patch [new file with mode: 0644]
patches.tizen/0916-mmc-sdhci-s3c-Use-mmc_gpio_request_cd-function.patch [new file with mode: 0644]
patches.tizen/0917-Revert-Thermal-exynos-Support-for-TMU-regulator-defi.patch [new file with mode: 0644]
patches.tizen/0918-Thermal-armada_thermal-Remove-redundant-platform_set.patch [new file with mode: 0644]
patches.tizen/0919-Thermal-dove_thermal-Remove-redundant-platform_set_d.patch [new file with mode: 0644]
patches.tizen/0920-Thermal-exynos-Remove-redundant-platform_set_drvdata.patch [new file with mode: 0644]
patches.tizen/0921-Thermal-kirkwood-Remove-redundant-platform_set_drvda.patch [new file with mode: 0644]
patches.tizen/0922-Thermal-rcar-Remove-redundant-platform_set_drvdata.patch [new file with mode: 0644]
patches.tizen/0923-Thermal-spear-Remove-redundant-platform_set_drvdata.patch [new file with mode: 0644]
patches.tizen/0924-drivers-thermal-don-t-check-resource-with-devm_iorem.patch [new file with mode: 0644]
patches.tizen/0925-Thermal-spear_thermal-convert-to-devm_ioremap_resour.patch [new file with mode: 0644]
patches.tizen/0926-thermal-rcar-Fix-typo-in-probe-information-message.patch [new file with mode: 0644]
patches.tizen/0927-thermal-cut-the-spaces-when-user-sets-policy.patch [new file with mode: 0644]
patches.tizen/0928-Thermal-core-Ask-.get_trip_temp-to-register-thermal-.patch [new file with mode: 0644]
patches.tizen/0929-Thermal-don-t-check-resource-with-devm_ioremap_resou.patch [new file with mode: 0644]
patches.tizen/0930-thermal-introduce-TI-SoC-thermal-driver.patch [new file with mode: 0644]
patches.tizen/0931-Thermal-armada-Remove-redundant-use-of-of_match_ptr.patch [new file with mode: 0644]
patches.tizen/0932-Thermal-dove-Remove-redundant-use-of-of_match_ptr.patch [new file with mode: 0644]
patches.tizen/0933-Thermal-kirkwood-Remove-redundant-use-of-of_match_pt.patch [new file with mode: 0644]
patches.tizen/0934-Thermal-spear-Remove-redundant-use-of-of_match_ptr.patch [new file with mode: 0644]
patches.tizen/0935-thermal-cpu_cooling-fix-descend-check-in-get_propert.patch [new file with mode: 0644]
patches.tizen/0936-thermal-ti-soc-thermal-remove-external-heat-while-ex.patch [new file with mode: 0644]
patches.tizen/0937-thermal-ti-soc-thermal-freeze-FSM-while-computing-tr.patch [new file with mode: 0644]
patches.tizen/0938-thermal-ti-soc-thermal-remove-usage-of-IS_ERR_OR_NUL.patch [new file with mode: 0644]
patches.tizen/0939-thermal-ti-soc-thermal-add-thermal-data-for-DRA752-c.patch [new file with mode: 0644]
patches.tizen/0940-thermal-ti-soc-thermal-add-dra752-chip-to-device-tab.patch [new file with mode: 0644]
patches.tizen/0941-thermal-consider-emul_temperature-while-computing-tr.patch [new file with mode: 0644]
patches.tizen/0942-Thermal-CPU-Package-temperature-thermal.patch [new file with mode: 0644]
patches.tizen/0943-thermal-fix-x86_pkg_temp_thermal.c-build-and-Kconfig.patch [new file with mode: 0644]
patches.tizen/0944-thermal-exynos-Support-both-EXYNOS4X12-SoCs.patch [new file with mode: 0644]
patches.tizen/0945-thermal-ti-soc-thermal-use-standard-GPIO-DT-bindings.patch [new file with mode: 0644]
patches.tizen/0946-Thermal-x86-package-temp-thermal-crash.patch [new file with mode: 0644]
patches.tizen/0947-Thermal-x86_pkg_temp-fix-krealloc-misuse-in-in-pkg_t.patch [new file with mode: 0644]
patches.tizen/0948-Thermal-x86_pkg_temp-Limit-number-of-pkg-temp-zones.patch [new file with mode: 0644]
patches.tizen/0949-Thermal-Fix-lockup-of-cpu_down.patch [new file with mode: 0644]
patches.tizen/0950-thermal-add-imx-thermal-driver-support.patch [new file with mode: 0644]
patches.tizen/0951-thermal-exynos-Moving-exynos-thermal-files-into-sams.patch [new file with mode: 0644]
patches.tizen/0952-thermal-exynos-Use-ARCH_HAS_BANDGAP-config-to-know-t.patch [new file with mode: 0644]
patches.tizen/0953-thermal-exynos-Remove-un-necessary-CPU_THERMAL-depen.patch [new file with mode: 0644]
patches.tizen/0954-thermal-exynos-Bifurcate-exynos-thermal-common-and-t.patch [new file with mode: 0644]
patches.tizen/0955-thermal-exynos-Rename-exynos_thermal.c-to-exynos_tmu.patch [new file with mode: 0644]
patches.tizen/0956-thermal-exynos-Move-exynos_thermal.h-from-include-to.patch [new file with mode: 0644]
patches.tizen/0957-thermal-exynos-Bifurcate-exynos-tmu-driver-and-confi.patch [new file with mode: 0644]
patches.tizen/0958-thermal-exynos-Add-missing-definations-and-code-clea.patch [new file with mode: 0644]
patches.tizen/0959-thermal-exynos-Add-extra-entries-in-the-tmu-platform.patch [new file with mode: 0644]
patches.tizen/0960-thermal-exynos-Move-register-definitions-from-driver.patch [new file with mode: 0644]
patches.tizen/0961-thermal-exynos-Support-thermal-tripping.patch [new file with mode: 0644]
patches.tizen/0962-thermal-exynos-Fix-to-clear-only-the-generated-inter.patch [new file with mode: 0644]
patches.tizen/0963-thermal-exynos-Add-support-for-instance-based-regist.patch [new file with mode: 0644]
patches.tizen/0964-thermal-exynos-Modify-private_data-to-appropriate-na.patch [new file with mode: 0644]
patches.tizen/0965-thermal-exynos-Return-success-even-if-no-cooling-dat.patch [new file with mode: 0644]
patches.tizen/0966-thermal-exynos-Make-the-zone-handling-use-trip-infor.patch [new file with mode: 0644]
patches.tizen/0967-thermal-exynos-Remove-non-DT-based-support.patch [new file with mode: 0644]
patches.tizen/0968-thermal-exynos-Add-support-to-handle-many-instances-.patch [new file with mode: 0644]
patches.tizen/0969-thermal-exynos-Add-TMU-features-to-check-instead-of-.patch [new file with mode: 0644]
patches.tizen/0970-thermal-exynos-use-device-resource-management-infras.patch [new file with mode: 0644]
patches.tizen/0971-thermal-exynos-Add-support-to-access-common-register.patch [new file with mode: 0644]
patches.tizen/0972-thermal-exynos-Add-driver-support-for-exynos5440-TMU.patch [new file with mode: 0644]
patches.tizen/0973-thermal-exynos-Add-thermal-configuration-data-for-ex.patch [new file with mode: 0644]
patches.tizen/0974-thermal-exynos-Fix-to-set-the-second-point-correctio.patch [new file with mode: 0644]
patches.tizen/0975-thermal-exynos-Add-hardware-mode-thermal-calibration.patch [new file with mode: 0644]
patches.tizen/0976-thermal-exynos-Support-for-TMU-regulator-defined-at-.patch [new file with mode: 0644]
patches.tizen/0977-thermal-imx-dynamic-passive-and-SoC-specific-critica.patch [new file with mode: 0644]
patches.tizen/0978-thermal-imx-implement-thermal-alarm-interrupt-handli.patch [new file with mode: 0644]
patches.tizen/0979-thermal-exynos_tmu-fix-wrong-error-check-for-mapped-.patch [new file with mode: 0644]
patches.tizen/0980-Thermal-cpu_cooling-Return-directly-for-the-cpu-out-.patch [new file with mode: 0644]
patches.tizen/0981-thermal-step_wise-cdev-only-needs-update-on-a-new-ta.patch [new file with mode: 0644]
patches.tizen/0982-thermal-step_wise-return-instance-target-by-default.patch [new file with mode: 0644]
patches.tizen/0983-thermal-ti-soc-thermal-Initialize-counter_delay-fiel.patch [new file with mode: 0644]
patches.tizen/0984-thermal-ti-soc-thermal-Set-the-bandgap-mask-counter-.patch [new file with mode: 0644]
patches.tizen/0985-thermal-ti-soc-thermal-Ensure-to-compute-thermal-tre.patch [new file with mode: 0644]
patches.tizen/0986-thermal-exynos-Fix-typos-in-Kconfig.patch [new file with mode: 0644]
patches.tizen/0987-thermal-exynos-Fix-potential-NULL-pointer-dereferenc.patch [new file with mode: 0644]
patches.tizen/0988-thermal-exynos-Clean-up-non-DT-remnants.patch [new file with mode: 0644]
patches.tizen/0989-thermal-hwmon-move-hwmon-support-to-single-file.patch [new file with mode: 0644]
patches.tizen/0990-drivers-thermal-parent-virtual-hwmon-with-thermal-zo.patch [new file with mode: 0644]
patches.tizen/0991-drivers-thermal-make-usage-of-CONFIG_THERMAL_HWMON-o.patch [new file with mode: 0644]
patches.tizen/0992-thermal-thermal_core-allow-binding-with-limits-on-bi.patch [new file with mode: 0644]
patches.tizen/0993-drivers-thermal-add-check-when-unregistering-cpu-coo.patch [new file with mode: 0644]
patches.tizen/0994-dts-Fix-exynos4x12-dts-file-to-get-thermal-sensor-re.patch [new file with mode: 0644]
patches.tizen/0995-Documentation-thermal-Explain-the-exynos-thermal-dri.patch [new file with mode: 0644]
patches.tizen/0996-thermal-Add-ommitted-codes-from-merging.patch [new file with mode: 0644]
patches.tizen/0997-Introduce-CONFIG_ARCH_HAS_BANDGAP-and-ARCH_EXYNOS4-5.patch [new file with mode: 0644]
patches.tizen/0998-thermal-EXYNOS-always-register-TMU-driver-with-core-.patch [new file with mode: 0644]
patches.tizen/0999-thermal-exynos-Set-MUX-bits-in-tmu-s-control-registe.patch [new file with mode: 0644]
patches.tizen/1000-Revert-thermal-exynos-Set-MUX-bits-in-tmu-s-control-.patch [new file with mode: 0644]
patches.tizen/1001-thermal-exynos-Remove-check-for-thermal-device-point.patch [new file with mode: 0644]
patches.tizen/1002-thermal-exynos-Provide-separate-TMU-data-for-Exynos4.patch [new file with mode: 0644]
patches.tizen/1003-thermal-exynos-Provide-initial-setting-for-TMU-s-tes.patch [new file with mode: 0644]
patches.tizen/1004-pwm-devm-alloc-correct-pointer-size.patch [new file with mode: 0644]
patches.tizen/1005-pwm-Add-sysfs-interface.patch [new file with mode: 0644]
patches.tizen/1006-pwm-Use-the-DT-macro-directly-when-parsing-PWM-DT-fl.patch [new file with mode: 0644]
patches.tizen/1007-pwm-samsung-Rename-to-pwm-samsung-legacy.patch [new file with mode: 0644]
patches.tizen/1008-pwm-Add-new-pwm-samsung-driver.patch [new file with mode: 0644]
patches.tizen/1009-pwm-Remove-superseded-pwm-samsung-legacy-driver.patch [new file with mode: 0644]
patches.tizen/1010-pwm-Add-PWM-polarity-flag-macro-for-DT.patch [new file with mode: 0644]
patches.tizen/1011-ARM-dts-add-clocks-and-enable-pwm-for-exynos4.patch [new file with mode: 0644]
patches.tizen/1012-pwm-samsung-memory-leak-bugfix-in-pwm_samsung_free.patch [new file with mode: 0644]
patches.tizen/1013-arm-Thumb-ARM-signal-handling-setup-skips-the-a-few-.patch [new file with mode: 0644]
patches.tizen/1014-mmc-sdhci-s3c-Revised-sdhci_s3c_remove-function.patch [new file with mode: 0644]
patches.tizen/1015-config-tizen-Enable-CONFIG_BRCMFMAC-for-supporting-W.patch [new file with mode: 0644]
patches.tizen/1016-cpufreq-M0-Allow-sailable-frequency-up-to-1.4Ghz-M0.patch [new file with mode: 0644]
patches.tizen/1017-cpufreq-LAB-Introduce-new-cpufreq-LAB-Legaccy-Applic.patch [new file with mode: 0644]
patches.tizen/1018-cpufreq-lab-Enable-overclocking-in-LAB.patch [new file with mode: 0644]
patches.tizen/1019-cpufreq-exysnos-Fix-the-way-of-enabling-boost-in-exy.patch [new file with mode: 0644]
patches.tizen/1020-cpufreq-lab-Fix-codes-for-correct-working-of-lab-gov.patch [new file with mode: 0644]
patches.tizen/1021-mmc-sdhci-s3c-Add-irq_set_wake-function.patch [new file with mode: 0644]
patches.tizen/1022-gpu-arm-mali400-ump-Fix-svn-revision-check.patch [new file with mode: 0644]
patches.tizen/1023-packaging-Bump-version.patch [new file with mode: 0644]
patches.tizen/1024-mali-Support-build-to-different-objdir-O.patch [new file with mode: 0644]
patches.tizen/1025-update-linux-kernel.spec-file-to-fix-build-problems.patch [new file with mode: 0644]
patches.tizen/1026-tizen-update-default-config-to-use-slp-gadget.patch [new file with mode: 0644]
patches.tizen/1027-gpu-arm-mali400-support-gpu-frequency-profiling.patch [new file with mode: 0644]
patches.tizen/1028-arch-ARM-dts-add-support-for-exynos4210-usbphy-drive.patch [new file with mode: 0644]
patches.tizen/1029-USB-gadget-s3c-hsotg-fix-spinlock-locking.patch [new file with mode: 0644]
patches.tizen/1030-USB-gadget-s3c-hsotg-fix-disconnect-handling.patch [new file with mode: 0644]
patches.tizen/1031-Include-kernel-configuration-in-kernel-image.patch [new file with mode: 0644]
patches.tizen/1032-Enable-RTC-chips-on-M0-devices.patch [new file with mode: 0644]
patches.tizen/1033-video-display-panel-s6d6aa1-Use-devm_kzalloc-to-allo.patch [new file with mode: 0644]
patches.tizen/1034-video-display-panel-s6e8aa0-Use-devm_kzalloc-to-allo.patch [new file with mode: 0644]
patches.tizen/1035-mmc-sdhci-pltfm-Use-devm_ioremap_resource.patch [new file with mode: 0644]
patches.tizen/1036-mfd-max77693-Fix-mapping-IRQ-during-mask-unmask.patch [new file with mode: 0644]
patches.tizen/1037-mmc-sdhci-s3c-sdhci-s3c-driver-use-sdhci-pltfm.patch [new file with mode: 0644]
patches.tizen/1038-dts-exynos4x12-fix-clock-properties.patch [new file with mode: 0644]
patches.tizen/1039-pinctrl-exynos-Add-spinlocks-to-irq_mask-and-irq_unm.patch [new file with mode: 0644]
patches.tizen/1040-pinctrl-exynos-reorder-xyz_irq_unmask-so-future-patc.patch [new file with mode: 0644]
patches.tizen/1041-pinctrl-exynos-ack-level-triggered-interrupts-before.patch [new file with mode: 0644]
patches.tizen/1042-clk-samsung-exynos4-Propagate-rate-change-of-SPI-div.patch [new file with mode: 0644]
patches.tizen/1043-Smack-Local-IPv6-port-based-controls.patch [new file with mode: 0644]
patches.tizen/1044-Smack-Improve-access-check-performance.patch [new file with mode: 0644]
patches.tizen/1045-Smack-Add-smkfstransmute-mount-option.patch [new file with mode: 0644]
patches.tizen/1046-Smack-Fix-possible-NULL-pointer-dereference-at-smk_n.patch [new file with mode: 0644]
patches.tizen/1047-Smack-Fix-the-bug-smackcipso-can-t-set-CIPSO-correct.patch [new file with mode: 0644]
patches.tizen/1048-Security-Add-Hook-to-test-if-the-particular-xattr-is.patch [new file with mode: 0644]
patches.tizen/1049-xattr-Constify-name-member-of-struct-xattr.patch [new file with mode: 0644]
patches.tizen/1050-security-smack-fix-memleak-in-smk_write_rules_list.patch [new file with mode: 0644]
patches.tizen/1051-security-smack-add-a-hash-table-to-quicken-smk_find_.patch [new file with mode: 0644]
patches.tizen/1052-Smack-network-label-match-fix.patch [new file with mode: 0644]
patches.tizen/1053-Smack-IPv6-casting-error-fix-for-3.11.patch [new file with mode: 0644]
patches.tizen/1054-Smack-parse-multiple-rules-per-write-to-load2-up-to-.patch [new file with mode: 0644]
patches.tizen/1055-Smack-Implement-lock-security-mode.patch [new file with mode: 0644]
patches.tizen/1056-Smack-Ptrace-access-check-mode.patch [new file with mode: 0644]
patches.tizen/1057-Smack-Cgroup-filesystem-access.patch [new file with mode: 0644]
patches.tizen/1058-linux-kernel-and-linux-kernel-modules-ABI-tools.patch [new file with mode: 0644]
patches.tizen/1059-linux-kernel-and-linux-kernel-modules-ABI-next-chang.patch [new file with mode: 0644]
patches.tizen/1060-abi-checker-tool-directory-location-update.patch [new file with mode: 0644]
patches.tizen/1061-Smack-Make-the-syslog-control-configurable.patch [new file with mode: 0644]
patches.tizen/1062-Smack-change-rule-cap-check.patch [new file with mode: 0644]
patches.tizen/1063-Revert-abi-checker-tool-directory-location-update.patch [new file with mode: 0644]
patches.tizen/1064-Revert-linux-kernel-and-linux-kernel-modules-ABI-nex.patch [new file with mode: 0644]
patches.tizen/1065-Revert-linux-kernel-and-linux-kernel-modules-ABI-too.patch [new file with mode: 0644]
patches.tizen/1066-video-display-s6e8aa0-adjust-brightness-value-to-dri.patch [new file with mode: 0644]
patches.tizen/1067-spec-file-update-to-build-output-uImage-and-Device-T.patch [new file with mode: 0644]
patches.tizen/1068-video-display-s6e8aa0-remove-duplicated-mtp-read-fun.patch [new file with mode: 0644]
patches.tizen/1069-video-display-s6e8aa0-change-power-off-sequence-to-r.patch [new file with mode: 0644]
patches.tizen/1070-iio-st_gyro-Prevent-register-threshold-events.patch [new file with mode: 0644]
patches.tizen/1071-iio-cm36651-Rebased-light-proximity-sensor-driver.patch [new file with mode: 0644]
patches.tizen/1072-USB-gadget-s3c-hsotg-skip-suspend-and-resume-when-us.patch [new file with mode: 0644]
patches.tizen/1073-usb-gadget-slp-fix-wrong-destory-function.patch [new file with mode: 0644]
patches.tizen/1074-USB-gadget-s3c-hsotg-fix-maxpacket-size-in-s3c_hsotg.patch [new file with mode: 0644]
patches.tizen/1075-USB-gadget-s3c-hsotg-add-flush-TX-FIFO-when-kill-all.patch [new file with mode: 0644]
patches.tizen/1076-drivers-clk-samsung-fix-build-dependency-for-exynos4.patch [new file with mode: 0644]
patches.tizen/1077-drivers-mmc-s3c-sdhci-select-required-sdhci-platform.patch [new file with mode: 0644]
patches.tizen/1078-extcon-max77693-Differentiate-info-message-for-easie.patch [new file with mode: 0644]
patches.tizen/1079-extcon-max77693-Force-using-UART-path-for-jig.patch [new file with mode: 0644]
patches.tizen/1080-mmc-dw_mmc-change-the-blk-setting-value-for-eMMC.patch [new file with mode: 0644]
patches.tizen/1081-spec-file-cleanup-and-linux-kernel-sources-package-r.patch [new file with mode: 0644]
patches.tizen/1082-Bring-kernel-packaging-in-line-with-ivi-s-kernel.patch [new file with mode: 0644]
patches.tizen/1083-Split-uImage-on-clean-uImage-and-Device-Tree-blob.patch [new file with mode: 0644]
patches.tizen/1084-Revert-usb-gadget-mass_storage-merge-usb_f_mass_stor.patch [new file with mode: 0644]
patches.tizen/1085-Revert-usb-gadget-f_mass_storage-remove-compatibilit.patch [new file with mode: 0644]
patches.tizen/1086-Revert-usb-gadget-multi-convert-to-new-interface-of-.patch [new file with mode: 0644]
patches.tizen/1087-Revert-usb-gadget-multi-convert-to-new-interface-of-.patch [new file with mode: 0644]
patches.tizen/1088-Revert-usb-gadget-multi-convert-to-new-interface-of-.patch [new file with mode: 0644]
patches.tizen/1089-Revert-usb-gadget-acm_ms-convert-to-new-interface-of.patch [new file with mode: 0644]
patches.tizen/1090-Revert-usb-gadget-f_mass_storage-add-configfs-suppor.patch [new file with mode: 0644]
patches.tizen/1091-Revert-usb-gadget-storage_common-add-methods-to-show.patch [new file with mode: 0644]
patches.tizen/1092-Revert-usb-gadget-storage_common-make-attribute-oper.patch [new file with mode: 0644]
patches.tizen/1093-Revert-usb-gadget-mass_storage-convert-to-new-interf.patch [new file with mode: 0644]
patches.tizen/1094-Revert-usb-gadget-f_mass_storage-convert-to-new-func.patch [new file with mode: 0644]
patches.tizen/1095-Revert-usb-gadget-f_mass_storage-use-fsg_common_run_.patch [new file with mode: 0644]
patches.tizen/1096-Revert-usb-gadget-f_mass_storage-use-fsg_common_set_.patch [new file with mode: 0644]
patches.tizen/1097-Revert-usb-gadget-f_mass_storage-use-fsg_common_crea.patch [new file with mode: 0644]
patches.tizen/1098-Revert-usb-gadget-f_mass_storage-use-fsg_common_set_.patch [new file with mode: 0644]
patches.tizen/1099-Revert-usb-gadget-f_mass_storage-use-fsg_common_set_.patch [new file with mode: 0644]
patches.tizen/1100-Revert-usb-gadget-f_mass_storage-use-fsg_common_set_.patch [new file with mode: 0644]
patches.tizen/1101-Revert-usb-gadget-f_mass_storage-use-fsg_common_set_.patch [new file with mode: 0644]
patches.tizen/1102-Revert-usb-gadget-f_mass_storage-use-fsg_common_setu.patch [new file with mode: 0644]
patches.tizen/1103-Revert-usb-gadget-f_mass_storage-split-fsg_common-in.patch [new file with mode: 0644]
patches.tizen/1104-Revert-usb-gadget-f_mass_storage-use-usb_gstrings_at.patch [new file with mode: 0644]
patches.tizen/1105-Revert-usb-gadget-f_mass_storage-add-a-level-of-indi.patch [new file with mode: 0644]
patches.tizen/1106-Revert-usb-gadget-f_mass_storage-factor-out-a-header.patch [new file with mode: 0644]
patches.tizen/1107-Revert-usb-gadget-create-a-utility-module-for-mass_s.patch [new file with mode: 0644]
patches.tizen/1108-USB-gadget-fix-up-comment.patch [new file with mode: 0644]
patches.tizen/1109-usb-gadget-f_mass_storage-use-NULL-instead-of-0.patch [new file with mode: 0644]
patches.tizen/1110-usb-gadget-rndis-Staticize-rndis_init-rndis_exit.patch [new file with mode: 0644]
patches.tizen/1111-sysfs.h-add-__ATTR_RW-macro.patch [new file with mode: 0644]
patches.tizen/1112-driver-core-device.h-add-RW-and-RO-attribute-macros.patch [new file with mode: 0644]
patches.tizen/1113-USB-gadget-audit-sysfs-attribute-permissions.patch [new file with mode: 0644]
patches.tizen/1114-usb-gadget-gadgetfs-potential-use-after-free-in-unbi.patch [new file with mode: 0644]
patches.tizen/1115-usb-gadget-add-__ref-for-rndis_config_register-and-c.patch [new file with mode: 0644]
patches.tizen/1116-usb-gadget-f_ecm-Staticize-ecm_alloc.patch [new file with mode: 0644]
patches.tizen/1117-usb-gadget-f_eem-Staticize-eem_alloc.patch [new file with mode: 0644]
patches.tizen/1118-usb-gadget-f_mass_storage-reset-endpoint-driver-data.patch [new file with mode: 0644]
patches.tizen/1119-usb-g_ffs-fix-compilation-warning.patch [new file with mode: 0644]
patches.tizen/1120-usb-gadget-f_fs-fix-error-handling.patch [new file with mode: 0644]
patches.tizen/1121-usb-gadget-zero-Add-flexible-auto-remote-wakeup-test.patch [new file with mode: 0644]
patches.tizen/1122-usb-gadget-Use-ERR_CAST-inlined-function-instead-of-.patch [new file with mode: 0644]
patches.tizen/1123-usb-gadget-create-a-utility-module-for-mass_storage.patch [new file with mode: 0644]
patches.tizen/1124-usb-gadget-f_mass_storage-factor-out-a-header-file.patch [new file with mode: 0644]
patches.tizen/1125-usb-gadget-f_mass_storage-add-a-level-of-indirection.patch [new file with mode: 0644]
patches.tizen/1126-usb-gadget-f_mass_storage-use-usb_gstrings_attach.patch [new file with mode: 0644]
patches.tizen/1127-usb-gadget-f_mass_storage-create-_fsg_common_free_bu.patch [new file with mode: 0644]
patches.tizen/1128-usb-gadget-f_mass_storage-make-sysfs-interface-optio.patch [new file with mode: 0644]
patches.tizen/1129-usb-gadget-f_mass_storage-create-fsg_common_setup-fo.patch [new file with mode: 0644]
patches.tizen/1130-usb-gadget-f_mass_storage-create-fsg_common_set_num_.patch [new file with mode: 0644]
patches.tizen/1131-usb-gadget-f_mass_storage-create-lun-handling-helper.patch [new file with mode: 0644]
patches.tizen/1132-usb-gadget-f_mass_storage-create-fsg_common_set_cdev.patch [new file with mode: 0644]
patches.tizen/1133-usb-gadget-f_mass_storage-create-lun-creation-helper.patch [new file with mode: 0644]
patches.tizen/1134-usb-gadget-f_mass_storage-create-fsg_common_set_inqu.patch [new file with mode: 0644]
patches.tizen/1135-usb-gadget-f_mass_storage-create-fsg_common_run_thre.patch [new file with mode: 0644]
patches.tizen/1136-usb-gadget-f_mass_storage-convert-to-new-function-in.patch [new file with mode: 0644]
patches.tizen/1137-usb-gadget-mass_storage-convert-to-new-interface-of-.patch [new file with mode: 0644]
patches.tizen/1138-usb-gadget-storage_common-make-attribute-operations-.patch [new file with mode: 0644]
patches.tizen/1139-usb-gadget-storage_common-add-methods-to-show-store-.patch [new file with mode: 0644]
patches.tizen/1140-usb-gadget-f_mass_storage-add-configfs-support.patch [new file with mode: 0644]
patches.tizen/1141-usb-gadget-acm_ms-convert-to-new-interface-of-f_mass.patch [new file with mode: 0644]
patches.tizen/1142-usb-gadget-multi-convert-to-new-interface-of-f_ecm.patch [new file with mode: 0644]
patches.tizen/1143-usb-gadget-multi-convert-to-new-interface-of-f_rndis.patch [new file with mode: 0644]
patches.tizen/1144-usb-gadget-multi-convert-to-new-interface-of-f_mass_.patch [new file with mode: 0644]
patches.tizen/1145-usb-gadget-f_mass_storage-remove-compatibility-layer.patch [new file with mode: 0644]
patches.tizen/1146-usb-gadget-mass_storage-merge-usb_f_mass_storage-mod.patch [new file with mode: 0644]
patches.tizen/1147-usb-gadget-storage_common-use-strtobool-instead-of-k.patch [new file with mode: 0644]
patches.tizen/1148-usb-gadget-storage_common-pass-filesem-to-fsg_store_.patch [new file with mode: 0644]
patches.tizen/1149-usb-gadget-f_mass_storage-style-corrections-cleanup-.patch [new file with mode: 0644]
patches.tizen/1150-usb-gadget-f_mass_storage-use-string-literal-as-form.patch [new file with mode: 0644]
patches.tizen/1151-usb-gadget-update-some-out-of-date-comments.patch [new file with mode: 0644]
patches.tizen/1152-usb-gadget-composite-redirect-setup-requests.patch [new file with mode: 0644]
patches.tizen/1153-usb-gadget-factor-out-alloc_ep_req.patch [new file with mode: 0644]
patches.tizen/1154-usb-gadget-f_loopback-add-configfs-support.patch [new file with mode: 0644]
patches.tizen/1155-usb-gadget-f_sourcesink-add-configfs-support.patch [new file with mode: 0644]
patches.tizen/1156-usb-gadget-move-bitflags-to-the-end-of-usb_gadget-st.patch [new file with mode: 0644]
patches.tizen/1157-usb-gadget-add-quirk_ep_out_aligned_size-field-to-st.patch [new file with mode: 0644]
patches.tizen/1158-usb-gadget-f_fs-remove-loop-from-I-O-function.patch [new file with mode: 0644]
patches.tizen/1159-usb-f_fs-check-quirk-to-pad-epout-buf-size-when-not-.patch [new file with mode: 0644]
patches.tizen/1160-usb-gadget-configfs-allow-setting-function-instance-.patch [new file with mode: 0644]
patches.tizen/1161-usb-gadget-g_ffs-remove-a-reduntant-gfs_ether_setup-.patch [new file with mode: 0644]
patches.tizen/1162-usb-gadget-g_ffs-convert-to-new-interface-of-f_ecm.patch [new file with mode: 0644]
patches.tizen/1163-usb-gadget-f_ecm-remove-compatibility-layer.patch [new file with mode: 0644]
patches.tizen/1164-usb-gadget-g_ffs-convert-to-new-interface-of-f_subse.patch [new file with mode: 0644]
patches.tizen/1165-usb-gadget-f_subset-remove-compatibility-layer.patch [new file with mode: 0644]
patches.tizen/1166-usb-gadget-g_ffs-convert-to-new-interface-of-f_rndis.patch [new file with mode: 0644]
patches.tizen/1167-usb-gadget-f_rndis-remove-compatibility-layer.patch [new file with mode: 0644]
patches.tizen/1168-usb-gadget-rndis-merge-u_rndis.ko-with-usb_f_rndis.k.patch [new file with mode: 0644]
patches.tizen/1169-usb-gadget-FunctionFS-Remove-VLAIS-usage-from-gadget.patch [new file with mode: 0644]
patches.tizen/1170-usb-gadget-FunctionFS-create-utility-file.patch [new file with mode: 0644]
patches.tizen/1171-usb-gadget-FunctionFS-add-devices-management-code.patch [new file with mode: 0644]
patches.tizen/1172-usb-gadget-FunctionFS-convert-to-new-function-interf.patch [new file with mode: 0644]
patches.tizen/1173-usb-gadget-g_ffs-convert-to-new-interface-of-f_fs.patch [new file with mode: 0644]
patches.tizen/1174-usb-gadget-FunctionFS-Remove-compatibility-layer.patch [new file with mode: 0644]
patches.tizen/1175-usb-gadget-FunctionFS-add-configfs-support.patch [new file with mode: 0644]
patches.tizen/1176-usb-gadget-f_fs-fix-sparse-warning.patch [new file with mode: 0644]
patches.tizen/1177-usb-gadget-nokia-fix-error-recovery-path-for-optiona.patch [new file with mode: 0644]
patches.tizen/1178-usb-gadget-f_loopback-Fix-sparse-warning.patch [new file with mode: 0644]
patches.tizen/1179-usb-gadget-f_mass_storage-Fix-sparse-warning.patch [new file with mode: 0644]
patches.tizen/1180-usb-gadget-f_ncm-Fix-sparse-warning.patch [new file with mode: 0644]
patches.tizen/1181-usb-gadget-f_obex-Fix-sparse-warning.patch [new file with mode: 0644]
patches.tizen/1182-usb-gadget-f_phonet-Fix-sparse-warning.patch [new file with mode: 0644]
patches.tizen/1183-usb-gadget-f_serial-Fix-sparse-warning.patch [new file with mode: 0644]
patches.tizen/1184-usb-gadget-f_sourcesink-Fix-sparse-warning.patch [new file with mode: 0644]
patches.tizen/1185-usb-gadget-composite-reset-delayed_status-on-reset_c.patch [new file with mode: 0644]
patches.tizen/1186-usb-gadget-f_mass_storage-fix-mass-storage-dependenc.patch [new file with mode: 0644]
patches.tizen/1187-usb-gadget-mass-storage-fix-return-of-delayed-status.patch [new file with mode: 0644]
patches.tizen/1188-usb-gadget-zero-module-parameters-can-be-static.patch [new file with mode: 0644]
patches.tizen/1189-usb-gadget-f_mass_storage-call-try_to_freeze-only-wh.patch [new file with mode: 0644]
patches.tizen/1190-usb-gadget-configfs-include-appropriate-header-file-.patch [new file with mode: 0644]
patches.tizen/1191-usb-gadget-should-use-u16-type-variable-to-store-Max.patch [new file with mode: 0644]
patches.tizen/1192-usb-gadget-fix-up-some-comments-about-CONFIG_USB_DEB.patch [new file with mode: 0644]
patches.tizen/1193-usb-gadget-FunctionFS-dereference-ffs_dev-conditiona.patch [new file with mode: 0644]
patches.tizen/1194-usb-gadget-code-cleanup.patch [new file with mode: 0644]
patches.tizen/1195-usb-gadget-FunctionFS-staticize-functions-used-only-.patch [new file with mode: 0644]
patches.tizen/1196-usb-gadget-FunctionFS-use-consistent-naming-with-reg.patch [new file with mode: 0644]
patches.tizen/1197-usb-gadget-fix-NULL-pointer-dereference.patch [new file with mode: 0644]
patches.tizen/1198-Add-dependency-on-kernel-package-in-kernel-devel-pac.patch [new file with mode: 0644]
patches.tizen/1199-tizen-packaging-support-perf-build.patch [new file with mode: 0644]
patches.tizen/1200-usb-gadget-temporarily-turn-off-rndis-from-slp-gadge.patch [new file with mode: 0644]
patches.tizen/1201-usb-gadget-adapt-slp-to-new-interface-of-rndis.patch [new file with mode: 0644]
patches.tizen/1202-usb-gadget-eliminate-memory-leak-in-slp-gadget.patch [new file with mode: 0644]
patches.tizen/1203-spec-add-missing-build-dependences-and-output-packag.patch [new file with mode: 0644]
patches.tizen/1204-Revert-WORKAROUND-Temporary-workaround-for-Suspend-T.patch [new file with mode: 0644]
patches.tizen/1205-clk-exynos4-Keep-chipid-clock-enabled.patch [new file with mode: 0644]
patches.tizen/1206-pm-exynos-Skip-re-enabling-L2-cache-for-early-waking.patch [new file with mode: 0644]
patches.tizen/1207-iio-ak8975-Fix-calculation-formula-for-convert-micro.patch [new file with mode: 0644]
patches.tizen/1208-iio-ak8975-Add-device-name.patch [new file with mode: 0644]
patches.tizen/1209-video-display-s6e8aa0-fix-a-erratum-in-gamma-table.patch [new file with mode: 0644]
patches.tizen/1210-cpufreq-boost-Provide-support-for-BOOST-on-linux-3.1.patch [new file with mode: 0644]
patches.tizen/1211-cpufreq-boost-trats2-Define-boost_freq-attribute-for.patch [new file with mode: 0644]
patches.tizen/1212-usb-gadget-functionfs-fix-typo-in-the-enum-variable.patch [new file with mode: 0644]
patches.tizen/1213-usb-gadget-functionfs-replace-FFS_SETUP_STATUS-with-.patch [new file with mode: 0644]
patches.tizen/1214-usb-gadget-f_fs-fix-setup-request-handling.patch [new file with mode: 0644]
patches.tizen/1215-usb-gadget-f_fs-add-poll-for-endpoint-0.patch [new file with mode: 0644]
patches.tizen/1216-usb-gadget-f_fs-add-aio-support.patch [new file with mode: 0644]
patches.tizen/1217-tools-usb-aio-example-applications.patch [new file with mode: 0644]
patches.tizen/1218-phy-Add-exynos-phy-driver.patch [new file with mode: 0644]
patches.tizen/1219-misc-add-sii9234-driver.patch [new file with mode: 0644]
patches.tizen/1220-clk-exynos4-export-sclk_hdmiphy-clock.patch [new file with mode: 0644]
patches.tizen/1221-clk-propagate-parent-change-up-one-level.patch [new file with mode: 0644]
patches.tizen/1222-clk-exynos4-enable-clk_set_parent-propagation-for-sc.patch [new file with mode: 0644]
patches.tizen/1223-drm-exynos-hdmi-use-hdmiphy-as-PHY.patch [new file with mode: 0644]
patches.tizen/1224-drm-exynos-hdmi-simplify-extracting-hpd-gpio-from-DT.patch [new file with mode: 0644]
patches.tizen/1225-drm-exynos-migrate-to-Common-Clock-Framework.patch [new file with mode: 0644]
patches.tizen/1226-drm-exynos-add-compatibles-for-HDMI-and-Mixer-chips-.patch [new file with mode: 0644]
patches.tizen/1227-drm-exynos-hdmi-add-support-for-pixel-clock-limitati.patch [new file with mode: 0644]
patches.tizen/1228-arm-dts-exynos4-add-i2c-controller-for-HDMIPHY.patch [new file with mode: 0644]
patches.tizen/1229-arm-dts-exynos4-add-HDMI-devices.patch [new file with mode: 0644]
patches.tizen/1230-arm-dts-universal_c210-add-HDMI-devices.patch [new file with mode: 0644]
patches.tizen/1231-arm-dts-exynos4412-slp-pq-add-HDMI-devices.patch [new file with mode: 0644]
patches.tizen/1232-arm-config-tizen-enable-HDMI-drivers.patch [new file with mode: 0644]
patches.tizen/1233-usb-gadget-Enable-rndis-in-the-slp-gadget-driver.patch [new file with mode: 0644]
patches.tizen/1234-arm-dts-cleanup-entries-for-usb-phy-for-Exynos4.patch [new file with mode: 0644]
patches.tizen/1235-ARM-exynos-dts-cleanup-the-dts-file-for-trats2.patch [new file with mode: 0644]
patches.tizen/1236-mm-page_alloc-fix-freeing-of-MIGRATE_RESERVE-migrate.patch [new file with mode: 0644]
patches.tizen/1237-userns-Allow-PR_CAPBSET_DROP-in-a-user-namespace.patch [new file with mode: 0644]
patches.tizen/1238-clocksource-exynos4-Fix-wrong-bit-operation-in-exyno.patch [new file with mode: 0644]
patches.tizen/1239-cpufreq-ondemand-Change-the-calculation-of-target-fr.patch [new file with mode: 0644]
patches.tizen/1240-cpufreq-dts-trats2-Remove-redundant-definitions-of-c.patch [new file with mode: 0644]
patches.tizen/1241-boost-dts-trats2-Define-boost_freq-attribute-for-cpu.patch [new file with mode: 0644]
patches.tizen/1242-cpufreq-conservative-Provide-correct-pointer-for-con.patch [new file with mode: 0644]
patches.tizen/1243-dts-odroid-x2-add-support-for-multimedia-blocks.patch [new file with mode: 0644]
patches.tizen/1244-arm-dts-exynos4412-odroidx2-add-HDMI-devices.patch [new file with mode: 0644]
patches.tizen/1245-ARM-defconfig-Add-tizen_odroidx2_defconfig.patch [new file with mode: 0644]
patches.tizen/1246-exynos4-is-Register-v4l2_async-notifier-only-when-se.patch [new file with mode: 0644]
patches.tizen/1247-Fix-building-RPM-with-tar-1.27-and-renamed-m0-dtb.patch [new file with mode: 0644]
patches.tizen/1248-math64-New-separate-div64_u64_rem-helper.patch [new file with mode: 0644]
patches.tizen/1249-Enable-FHANDLE-needed-by-systemd-209.patch [new file with mode: 0644]
patches.tizen/1250-ARM-defconfig-update-tizen_odroidx2_defconfig.patch [new file with mode: 0644]
patches.tizen/1251-ARM-odroidx2-enable-P3V3-fixed-regulator-to-always-o.patch [new file with mode: 0644]
patches.tizen/1252-ARM-odroidx2-update-defconfig.patch [new file with mode: 0644]
patches.tizen/1253-au0828-fix-i2c-clock-speed-for-DViCO-FusionHDTV7.patch [new file with mode: 0644]
patches.tizen/1254-ARM-odroidx2-update-defconfig-for-DViCO-FusionHDTV-U.patch [new file with mode: 0644]
patches.tizen/1255-phy-exynos-add-delay-after-reset-phy-for-usb-host.patch [new file with mode: 0644]
patches.tizen/1256-usb-misc-usb3503-Add-to-select-the-ports-to-disable.patch [new file with mode: 0644]
patches.tizen/1257-usb-misc-usb3503-Adding-device-tree-entry-disabled-p.patch [new file with mode: 0644]
patches.tizen/1258-usb-misc-usb3503-Fix-up-whitespace.patch [new file with mode: 0644]
patches.tizen/1259-usb-misc-usb3503-Remove-100ms-sleep-on-reset-conform.patch [new file with mode: 0644]
patches.tizen/1260-usb-misc-usb3503-use-dev_get_platdata.patch [new file with mode: 0644]
patches.tizen/1261-usb-misc-Fix-swapped-properties-in-usb3503-DT-parsin.patch [new file with mode: 0644]
patches.tizen/1262-ARM-dts-exynos4412-fix-usb3503-swapped-gpio-properti.patch [new file with mode: 0644]
patches.tizen/1263-usb-misc-usb3503-Convert-to-devm_-APIs.patch [new file with mode: 0644]
patches.tizen/1264-usb-misc-usb3503-Use-gpio_set_value_cansleep.patch [new file with mode: 0644]
patches.tizen/1265-usb-misc-usb3503-Actively-manage-Hub-Connect-GPIO.patch [new file with mode: 0644]
patches.tizen/1266-usb-misc-usb3503-Convert-to-regmap.patch [new file with mode: 0644]
patches.tizen/1267-usb-misc-usb3503-Factor-out-I2C-probe.patch [new file with mode: 0644]
patches.tizen/1268-usb-misc-usb3503-Fix-typos-in-error-messages.patch [new file with mode: 0644]
patches.tizen/1269-usb-misc-usb3503-Default-to-hub-mode.patch [new file with mode: 0644]
patches.tizen/1270-usb-misc-usb3503-Add-USB3503A-to-the-compatible-list.patch [new file with mode: 0644]
patches.tizen/1271-usb-misc-usb3503-Support-operation-with-no-I2C-contr.patch [new file with mode: 0644]
patches.tizen/1272-drivers-power-hide-some-excessive-debugs.patch [new file with mode: 0644]
patches.tizen/1273-iio-common-st-Prevent-disable-after-read-info-raw-da.patch [new file with mode: 0644]
patches.tizen/1274-cpufreq-LAB-Kconfig-Make-LAB-dependent-on-the-ONDEMA.patch [new file with mode: 0644]
patches.tizen/1275-cpufreq-LAB-Kconfig-Do-not-allow-LAB-to-be-build-as-.patch [new file with mode: 0644]
patches.tizen/1276-cpufreq-LAB-core-Remove-code-responsible-for-removin.patch [new file with mode: 0644]
patches.tizen/1277-cpufreq-LAB-ondemand-REMOVE-from-LAB-governor-code-d.patch [new file with mode: 0644]
patches.tizen/1278-cpufreq-LAB-core-Redesign-of-LAB-code-to-work-on-top.patch [new file with mode: 0644]
patches.tizen/1279-cpufreq-LAB-ondemand-Ondemand-governor-adjustments-n.patch [new file with mode: 0644]
patches.tizen/1280-cpufreq-LAB-cpufreq_governor-Remove-redundant-LAB-co.patch [new file with mode: 0644]
patches.tizen/1281-cpufreq-LAB-ondemand-Enable-usage-of-ONDEMAND-specif.patch [new file with mode: 0644]
patches.tizen/1282-cpufreq-LAB-dts-trats2-Add-attributes-necessary-for-.patch [new file with mode: 0644]
patches.tizen/1283-cpufreq-LAB-cosmetic-Cosmetic-code-cleanup.patch [new file with mode: 0644]
patches.tizen/1284-cpufreq-LAB-Replace-NR_CPUS-with-num_possible_cpus-f.patch [new file with mode: 0644]
patches.tizen/1285-ARM-dts-odroidx2-remove-obsoleted-register-debug-nod.patch [new file with mode: 0644]
patches.tizen/1286-ARM-dts-odroidx2-add-mali-gpu-and-cpu-freq.patch [new file with mode: 0644]
patches.tizen/1287-ARM-odroidx2-update-defconfig.patch [new file with mode: 0644]
patches.tizen/1288-dts-arm-odroidx2-add-support-for-external-buttons.patch [new file with mode: 0644]
patches.tizen/1289-ARM-odroidx2-update-defconfig-to-fix-the-number-of-c.patch [new file with mode: 0644]
patches.tizen/1290-cpufreq-LAB-Remove-MODULE_-macros-since-it-is-not-po.patch [new file with mode: 0644]
patches.tizen/1291-dts-exynos4412-trats2-Remove-unused-device-node-on-t.patch [new file with mode: 0644]
patches.tizen/1292-ARM-dts-fix-base-address-of-sysmmu_tv-for-exynos4.patch [new file with mode: 0644]
patches.tizen/1293-ARM-odroidx2-update-defconfig-to-enable-ANDROID_LOGG.patch [new file with mode: 0644]
patches.tizen/1294-media-s5p-mfc-Add-support-for-V4L2_MEMORY_DMABUF-typ.patch [new file with mode: 0644]
patches.tizen/1295-ARM-odroidx2-update-defconfig-to-enable-DRM_EXYNOS_F.patch [new file with mode: 0644]
patches.tizen/1296-ARM-EXYNOS-register-master-power-domain-for-genpd-fr.patch [new file with mode: 0644]
patches.tizen/1297-ARM-dts-odroidx2-remove-fimd-node.patch [new file with mode: 0644]
patches.tizen/1298-extcon-max77693-Fix-inaccurate-extcon-event-for-JIG-.patch [new file with mode: 0644]
patches.tizen/1299-Revert-extcon-max77693-Fix-inaccurate-extcon-event-f.patch [new file with mode: 0644]
patches.tizen/1300-Revert-extcon-max77693-Force-using-UART-path-for-jig.patch [new file with mode: 0644]
patches.tizen/1301-Revert-extcon-max77693-Fix-bug-related-to-MAX77693-i.patch [new file with mode: 0644]
patches.tizen/1302-extcon-max77693-Fix-a-bug-occured-at-changing-ADC-de.patch [new file with mode: 0644]

diff --git a/patches.tizen/0001-ARM-EXYNOS-Fail-l2x0-cache-initialization-if-DT-base.patch b/patches.tizen/0001-ARM-EXYNOS-Fail-l2x0-cache-initialization-if-DT-base.patch
new file mode 100644 (file)
index 0000000..c1e705b
--- /dev/null
@@ -0,0 +1,38 @@
+From cf01114c6e953bcbcf1fc2a9474eedb71e4f3a9b Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 12 Sep 2012 15:30:32 +0200
+Subject: [PATCH 0001/1302] ARM: EXYNOS: Fail l2x0 cache initialization if
+ DT-based init fails
+
+On DT-based boards, DT decides whether to enable l2x0 cache controller
+or not.
+
+This patch modifies Exynos l2x0 cache initialization code to fail if
+l2x0_of_init fails.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/mach-exynos/common.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
+index f7e504b..5bb6b26 100644
+--- a/arch/arm/mach-exynos/common.c
++++ b/arch/arm/mach-exynos/common.c
+@@ -560,8 +560,10 @@ static int __init exynos4_l2x0_cache_init(void)
+       if (soc_is_exynos5250() || soc_is_exynos5440())
+               return 0;
+-      ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK);
+-      if (!ret) {
++      if (of_have_populated_dt()) {
++              ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK);
++              if (ret)
++                      return ret;
+               l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs);
+               clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long));
+               return 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0002-ARM-EXYNOS-Add-secure-firmware-support-to-l2x0-initi.patch b/patches.tizen/0002-ARM-EXYNOS-Add-secure-firmware-support-to-l2x0-initi.patch
new file mode 100644 (file)
index 0000000..05d199a
--- /dev/null
@@ -0,0 +1,60 @@
+From 156f9542badc0700e9759ec0a8c1660aead1092d Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 12 Sep 2012 15:35:58 +0200
+Subject: [PATCH 0002/1302] ARM: EXYNOS: Add secure firmware support to l2x0
+ initialization
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/mach-exynos/common.c   | 3 +++
+ arch/arm/mach-exynos/firmware.c | 8 ++++++++
+ 2 files changed, 11 insertions(+)
+
+diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
+index 5bb6b26..02fb4a1 100644
+--- a/arch/arm/mach-exynos/common.c
++++ b/arch/arm/mach-exynos/common.c
+@@ -33,6 +33,7 @@
+ #include <asm/proc-fns.h>
+ #include <asm/exception.h>
++#include <asm/firmware.h>
+ #include <asm/hardware/cache-l2x0.h>
+ #include <asm/mach/map.h>
+ #include <asm/mach/irq.h>
+@@ -560,6 +561,8 @@ static int __init exynos4_l2x0_cache_init(void)
+       if (soc_is_exynos5250() || soc_is_exynos5440())
+               return 0;
++      call_firmware_op(l2x0_init);
++
+       if (of_have_populated_dt()) {
+               ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK);
+               if (ret)
+diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
+index ed11f10..da5fb26 100644
+--- a/arch/arm/mach-exynos/firmware.c
++++ b/arch/arm/mach-exynos/firmware.c
+@@ -40,10 +40,18 @@ static int exynos_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
+       return 0;
+ }
++static int exynos_l2x0_init(void)
++{
++      exynos_smc(SMC_CMD_L2X0INVALL, 0, 0, 0);
++      exynos_smc(SMC_CMD_L2X0CTRL, 1, 0, 0);
++      return 0;
++}
++
+ static const struct firmware_ops exynos_firmware_ops = {
+       .do_idle                = exynos_do_idle,
+       .set_cpu_boot_addr      = exynos_set_cpu_boot_addr,
+       .cpu_boot               = exynos_cpu_boot,
++      .l2x0_init      = exynos_l2x0_init,
+ };
+ void __init exynos_firmware_init(void)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0003-ARM-dts-exynos4-Add-DT-nodes-for-L2-cache-controller.patch b/patches.tizen/0003-ARM-dts-exynos4-Add-DT-nodes-for-L2-cache-controller.patch
new file mode 100644 (file)
index 0000000..249b51e
--- /dev/null
@@ -0,0 +1,64 @@
+From fd0079387c13066ea0ef1f9d6f7f863fd16cc69f Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 12 Sep 2012 15:36:39 +0200
+Subject: [PATCH 0003/1302] ARM: dts: exynos4: Add DT nodes for L2 cache
+ controller
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi    | 6 ++++++
+ arch/arm/boot/dts/exynos4210.dtsi | 4 ++++
+ arch/arm/boot/dts/exynos4x12.dtsi | 4 ++++
+ 3 files changed, 14 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index 359694c..b90bab3 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -92,6 +92,12 @@
+               reg = <0x10010000 0x400>;
+       };
++      cache-controller@0x10502000 {
++              compatible = "arm,pl310-cache";
++              reg = <0x10502000 0x1000>;
++              arm,tag-latency = <1 1 0>;
++      };
++
+       watchdog@10060000 {
+               compatible = "samsung,s3c2410-wdt";
+               reg = <0x10060000 0x100>;
+diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
+index 54710de..ef707bd 100644
+--- a/arch/arm/boot/dts/exynos4210.dtsi
++++ b/arch/arm/boot/dts/exynos4210.dtsi
+@@ -48,6 +48,10 @@
+                            <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>;
+       };
++      cache-controller@0x10502000 {
++              arm,data-latency = <1 1 0>;
++      };
++
+       mct@10050000 {
+               compatible = "samsung,exynos4210-mct";
+               reg = <0x10050000 0x800>;
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index e3380a7..4afda47 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -36,6 +36,10 @@
+                            <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>;
+       };
++      cache-controller@0x10502000 {
++              arm,data-latency = <1 2 0>;
++      };
++
+       clock: clock-controller@0x10030000 {
+               compatible = "samsung,exynos4412-clock";
+               reg = <0x10030000 0x20000>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0004-fs-jbd2-force-commit-to-free-jbd2-s-cma-isolated-pag.patch b/patches.tizen/0004-fs-jbd2-force-commit-to-free-jbd2-s-cma-isolated-pag.patch
new file mode 100644 (file)
index 0000000..0d968b1
--- /dev/null
@@ -0,0 +1,42 @@
+From 429ab036e5b0de2292a4b2c207acde3bd436092a Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Tue, 4 Sep 2012 10:44:49 +0200
+Subject: [PATCH 0004/1302] fs: jbd2: force commit to free jbd2's cma/isolated
+ page
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/jbd2/transaction.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
+index e0c0bc2..ca188f5 100644
+--- a/fs/jbd2/transaction.c
++++ b/fs/jbd2/transaction.c
+@@ -1776,8 +1776,22 @@ int jbd2_journal_try_to_free_buffers(journal_t *journal,
+               __journal_try_to_free_buffer(journal, bh);
+               jbd2_journal_put_journal_head(jh);
+               jbd_unlock_bh_state(bh);
++
++#ifndef CONFIG_CMA
+               if (buffer_jbd(bh))
+                       goto busy;
++#else
++              if (buffer_jbd(bh)) {
++                      unsigned mt = get_pageblock_migratetype(page);
++                      /*
++                       * Workaround: In case of CMA page, just commit journal.
++                      */
++                      if (mt == MIGRATE_ISOLATE || mt == MIGRATE_CMA)
++                              jbd2_journal_force_commit(journal);
++                      else
++                              goto busy;
++              }
++#endif
+       } while ((bh = bh->b_this_page) != head);
+       ret = try_to_free_buffers(page);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0005-fs-buffer.c-Revoke-LRU-when-trying-to-drop-buffers.patch b/patches.tizen/0005-fs-buffer.c-Revoke-LRU-when-trying-to-drop-buffers.patch
new file mode 100644 (file)
index 0000000..41a0caf
--- /dev/null
@@ -0,0 +1,95 @@
+From e2154558e6cea6a813e53e8b1c1f346d9b050d5b Mon Sep 17 00:00:00 2001
+From: Laura Abbott <lauraa@codeaurora.org>
+Date: Wed, 12 Sep 2012 09:36:16 +0200
+Subject: [PATCH 0005/1302] fs/buffer.c: Revoke LRU when trying to drop buffers
+
+When a buffer is added to the LRU list, a reference is taken which is
+not dropped until the buffer is evicted from the LRU list. This is the
+correct behavior, however this LRU reference will prevent the buffer
+from being dropped. This means that the buffer can't actually be dropped
+until it is selected for eviction. There's no bound on the time spent
+on the LRU list, which means that the buffer may be undroppable for
+very long periods of time. Given that migration involves dropping
+buffers, the associated page is now unmigratible for long periods of
+time as well. CMA relies on being able to migrate a specific range
+of pages, so these these types of failures make CMA significantly
+less reliable, especially under high filesystem usage.
+
+Rather than waiting for the LRU algorithm to eventually kick out
+the buffer, explicitly remove the buffer from the LRU list when trying
+to drop it. There is still the possibility that the buffer
+could be added back on the list, but that indicates the buffer is
+still in use and would probably have other 'in use' indicates to
+prevent dropping.
+
+Signed-off-by: Laura Abbott <lauraa@codeaurora.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/buffer.c | 38 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 38 insertions(+)
+
+diff --git a/fs/buffer.c b/fs/buffer.c
+index d2a4d1b..087816b 100644
+--- a/fs/buffer.c
++++ b/fs/buffer.c
+@@ -1413,12 +1413,49 @@ static bool has_bh_in_lru(int cpu, void *dummy)
+       return 0;
+ }
++static void __evict_bh_lru(void *arg)
++{
++      struct bh_lru *b = &get_cpu_var(bh_lrus);
++      struct buffer_head *bh = arg;
++      int i;
++
++      for (i = 0; i < BH_LRU_SIZE; i++) {
++              if (b->bhs[i] == bh) {
++                      brelse(b->bhs[i]);
++                      b->bhs[i] = NULL;
++                      goto out;
++              }
++      }
++out:
++      put_cpu_var(bh_lrus);
++}
++
++static bool bh_exists_in_lru(int cpu, void *arg)
++{
++      struct bh_lru *b = per_cpu_ptr(&bh_lrus, cpu);
++      struct buffer_head *bh = arg;
++      int i;
++
++      for (i = 0; i < BH_LRU_SIZE; i++) {
++              if (b->bhs[i] == bh)
++                      return 1;
++      }
++
++      return 0;
++
++}
+ void invalidate_bh_lrus(void)
+ {
+       on_each_cpu_cond(has_bh_in_lru, invalidate_bh_lru, NULL, 1, GFP_KERNEL);
+ }
+ EXPORT_SYMBOL_GPL(invalidate_bh_lrus);
++void evict_bh_lrus(struct buffer_head *bh)
++{
++      on_each_cpu_cond(bh_exists_in_lru, __evict_bh_lru, bh, 1, GFP_ATOMIC);
++}
++EXPORT_SYMBOL_GPL(evict_bh_lrus);
++
+ void set_bh_page(struct buffer_head *bh,
+               struct page *page, unsigned long offset)
+ {
+@@ -3140,6 +3177,7 @@ drop_buffers(struct page *page, struct buffer_head **buffers_to_free)
+       bh = head;
+       do {
++              evict_bh_lrus(bh);
+               if (buffer_write_io_error(bh) && page->mapping)
+                       set_bit(AS_EIO, &page->mapping->flags);
+               if (buffer_busy(bh))
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0006-mm-cma-allocate-pages-from-CMA-if-NR_FREE_PAGES-appr.patch b/patches.tizen/0006-mm-cma-allocate-pages-from-CMA-if-NR_FREE_PAGES-appr.patch
new file mode 100644 (file)
index 0000000..baa43d8
--- /dev/null
@@ -0,0 +1,46 @@
+From 2aeb96c2467ab83034cc2344db35be7c042343ee Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Fri, 9 Nov 2012 16:04:23 +0100
+Subject: [PATCH 0006/1302] mm: cma: allocate pages from CMA if NR_FREE_PAGES
+ approaches low water mark
+
+It has been observed that system tends to keep a lot of CMA free pages
+even in very high memory pressure use cases. The CMA fallback for movable
+pages is used very rarely, only when system is completely pruned from
+MOVABLE pages, what usually means that the out-of-memory even will be
+triggered very soon. To avoid such situation and make better use of CMA
+pages, a heuristics is introduced which turns on CMA fallback for movable
+pages when the real number of free pages (excluding CMA free pages)
+approaches low water mark.
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Reviewed-by: Kyungmin Park <kyungmin.park@samsung.com>
+CC: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ mm/page_alloc.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index 2ee0fd3..bb92575 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -1099,6 +1099,15 @@ static struct page *__rmqueue(struct zone *zone, unsigned int order,
+ {
+       struct page *page;
++#ifdef CONFIG_CMA
++      unsigned long nr_free = zone_page_state(zone, NR_FREE_PAGES);
++      unsigned long nr_cma_free = zone_page_state(zone, NR_FREE_CMA_PAGES);
++
++      if (migratetype == MIGRATE_MOVABLE && nr_cma_free &&
++          nr_free - nr_cma_free < 2 * low_wmark_pages(zone))
++              migratetype = MIGRATE_CMA;
++#endif /* CONFIG_CMA */
++
+ retry_reserve:
+       page = __rmqueue_smallest(zone, order, migratetype);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0007-usb-gadget-s3c-hsotg-Add-device-tree-based-instantia.patch b/patches.tizen/0007-usb-gadget-s3c-hsotg-Add-device-tree-based-instantia.patch
new file mode 100644 (file)
index 0000000..3181921
--- /dev/null
@@ -0,0 +1,44 @@
+From d2cff49885392b7551d7866fa9708c25b81bf215 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Tue, 11 Sep 2012 13:36:51 +0200
+Subject: [PATCH 0007/1302] usb: gadget: s3c-hsotg: Add device tree-based
+ instantiation
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/s3c-hsotg.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
+index af22f24..8fd9681 100644
+--- a/drivers/usb/gadget/s3c-hsotg.c
++++ b/drivers/usb/gadget/s3c-hsotg.c
+@@ -29,6 +29,7 @@
+ #include <linux/slab.h>
+ #include <linux/clk.h>
+ #include <linux/regulator/consumer.h>
++#include <linux/of_platform.h>
+ #include <linux/usb/ch9.h>
+ #include <linux/usb/gadget.h>
+@@ -3648,10 +3649,17 @@ static int s3c_hsotg_remove(struct platform_device *pdev)
+ #define s3c_hsotg_resume NULL
+ #endif
++static const struct of_device_id s3c_hsotg_of_ids[] = {
++      { .compatible = "samsung,s3c-hsotg", },
++      { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, s3c_hsotg_of_ids);
++
+ static struct platform_driver s3c_hsotg_driver = {
+       .driver         = {
+               .name   = "s3c-hsotg",
+               .owner  = THIS_MODULE,
++              .of_match_table = s3c_hsotg_of_ids,
+       },
+       .probe          = s3c_hsotg_probe,
+       .remove         = s3c_hsotg_remove,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0008-usb-phy-samsung-Select-common-driver-part-implicitly.patch b/patches.tizen/0008-usb-phy-samsung-Select-common-driver-part-implicitly.patch
new file mode 100644 (file)
index 0000000..f62d5e0
--- /dev/null
@@ -0,0 +1,36 @@
+From 8457ce3c61cea74b7f69262e398ba235242edadd Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Mon, 25 Mar 2013 15:48:47 +0100
+Subject: [PATCH 0008/1302] usb: phy: samsung: Select common driver part
+ implicitly
+
+Since phy-samsung-usb library can be used only by phy-samsung-usb2 and
+phy-samsung-usb3 drivers, there is no need to give explicit control over
+its Kconfig symbol.
+
+This patch makes CONFIG_SAMSUNG_USBPHY symbol hidden and selected
+implicitly by CONFIG_SAMSUNG_USB2PHY and CONFIG_SAMSUNG_USB3PHY.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/phy/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
+index 2311b1e..a5a9552 100644
+--- a/drivers/usb/phy/Kconfig
++++ b/drivers/usb/phy/Kconfig
+@@ -92,7 +92,7 @@ config OMAP_USB3
+         on/off the PHY.
+ config SAMSUNG_USBPHY
+-      tristate "Samsung USB PHY Driver"
++      tristate
+       help
+         Enable this to support Samsung USB phy helper driver for Samsung SoCs.
+         This driver provides common interface to interact, for Samsung USB 2.0 PHY
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0009-usb-phy-samsung-Use-clk_get-to-get-reference-clock.patch b/patches.tizen/0009-usb-phy-samsung-Use-clk_get-to-get-reference-clock.patch
new file mode 100644 (file)
index 0000000..7a1a5ed
--- /dev/null
@@ -0,0 +1,38 @@
+From 75e1b6b4a47930f988adba7072dd929b22c37d67 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Mon, 25 Mar 2013 19:36:22 +0100
+Subject: [PATCH 0009/1302] usb: phy: samsung: Use clk_get to get reference
+ clock
+
+There is no need to use devm_clk_get to get a clock that is being put
+at the end of the function.
+
+This patch changes the code getting reference clock to use clk_get
+instead of useless in this case devm_clk_get.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/phy/phy-samsung-usb.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/phy/phy-samsung-usb.c b/drivers/usb/phy/phy-samsung-usb.c
+index 7b118ee5..62cdb7e 100644
+--- a/drivers/usb/phy/phy-samsung-usb.c
++++ b/drivers/usb/phy/phy-samsung-usb.c
+@@ -175,9 +175,9 @@ int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
+        * external crystal clock XXTI
+        */
+       if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250)
+-              ref_clk = devm_clk_get(sphy->dev, "ext_xtal");
++              ref_clk = clk_get(sphy->dev, "ext_xtal");
+       else
+-              ref_clk = devm_clk_get(sphy->dev, "xusbxti");
++              ref_clk = clk_get(sphy->dev, "xusbxti");
+       if (IS_ERR(ref_clk)) {
+               dev_err(sphy->dev, "Failed to get reference clock\n");
+               return PTR_ERR(ref_clk);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0010-usb-phy-samsung-Consolidate-reference-clock-rate-han.patch b/patches.tizen/0010-usb-phy-samsung-Consolidate-reference-clock-rate-han.patch
new file mode 100644 (file)
index 0000000..e0e22d7
--- /dev/null
@@ -0,0 +1,252 @@
+From 3abf3521ded9d23d57d5ee8e0a8520363de5fc9a Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Mon, 25 Mar 2013 16:15:55 +0100
+Subject: [PATCH 0010/1302] usb: phy: samsung: Consolidate reference clock rate
+ handling
+
+This patch cleans up handling of reference clock rate in Samsung USB PHY
+drivers. It is mostly a cosmetic change but improves error handling in
+case of failing to get reference clock or invalid clock rate.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/phy/phy-samsung-usb.c  | 114 ++++++++++++++++++++++---------------
+ drivers/usb/phy/phy-samsung-usb.h  |   7 +++
+ drivers/usb/phy/phy-samsung-usb2.c |   8 ++-
+ drivers/usb/phy/phy-samsung-usb3.c |   6 +-
+ 4 files changed, 86 insertions(+), 49 deletions(-)
+
+diff --git a/drivers/usb/phy/phy-samsung-usb.c b/drivers/usb/phy/phy-samsung-usb.c
+index 62cdb7e..c40ea32 100644
+--- a/drivers/usb/phy/phy-samsung-usb.c
++++ b/drivers/usb/phy/phy-samsung-usb.c
+@@ -162,13 +162,76 @@ int samsung_usbphy_set_type(struct usb_phy *phy,
+ }
+ EXPORT_SYMBOL_GPL(samsung_usbphy_set_type);
++int samsung_usbphy_rate_to_clksel_64xx(struct samsung_usbphy *sphy,
++                                                      unsigned long rate)
++{
++      unsigned int clksel;
++
++      switch (rate) {
++      case 12 * MHZ:
++              clksel = PHYCLK_CLKSEL_12M;
++              break;
++      case 24 * MHZ:
++              clksel = PHYCLK_CLKSEL_24M;
++              break;
++      case 48 * MHZ:
++              clksel = PHYCLK_CLKSEL_48M;
++              break;
++      default:
++              dev_err(sphy->dev,
++                      "Invalid reference clock frequency: %lu\n", rate);
++              return -EINVAL;
++      }
++
++      return clksel;
++}
++EXPORT_SYMBOL_GPL(samsung_usbphy_rate_to_clksel_64xx);
++
++int samsung_usbphy_rate_to_clksel_4x12(struct samsung_usbphy *sphy,
++                                                      unsigned long rate)
++{
++      unsigned int clksel;
++
++      switch (rate) {
++      case 9600 * KHZ:
++              clksel = FSEL_CLKSEL_9600K;
++              break;
++      case 10 * MHZ:
++              clksel = FSEL_CLKSEL_10M;
++              break;
++      case 12 * MHZ:
++              clksel = FSEL_CLKSEL_12M;
++              break;
++      case 19200 * KHZ:
++              clksel = FSEL_CLKSEL_19200K;
++              break;
++      case 20 * MHZ:
++              clksel = FSEL_CLKSEL_20M;
++              break;
++      case 24 * MHZ:
++              clksel = FSEL_CLKSEL_24M;
++              break;
++      case 50 * MHZ:
++              clksel = FSEL_CLKSEL_50M;
++              break;
++      default:
++              dev_err(sphy->dev,
++                      "Invalid reference clock frequency: %lu\n", rate);
++              return -EINVAL;
++      }
++
++      return clksel;
++}
++EXPORT_SYMBOL_GPL(samsung_usbphy_rate_to_clksel_4x12);
++
+ /*
+  * Returns reference clock frequency selection value
+  */
+ int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
+ {
+       struct clk *ref_clk;
+-      int refclk_freq = 0;
++      unsigned long rate;
++      int refclk_freq;
+       /*
+        * In exynos5250 USB host and device PHY use
+@@ -183,52 +246,9 @@ int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
+               return PTR_ERR(ref_clk);
+       }
+-      if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250) {
+-              /* set clock frequency for PLL */
+-              switch (clk_get_rate(ref_clk)) {
+-              case 9600 * KHZ:
+-                      refclk_freq = FSEL_CLKSEL_9600K;
+-                      break;
+-              case 10 * MHZ:
+-                      refclk_freq = FSEL_CLKSEL_10M;
+-                      break;
+-              case 12 * MHZ:
+-                      refclk_freq = FSEL_CLKSEL_12M;
+-                      break;
+-              case 19200 * KHZ:
+-                      refclk_freq = FSEL_CLKSEL_19200K;
+-                      break;
+-              case 20 * MHZ:
+-                      refclk_freq = FSEL_CLKSEL_20M;
+-                      break;
+-              case 50 * MHZ:
+-                      refclk_freq = FSEL_CLKSEL_50M;
+-                      break;
+-              case 24 * MHZ:
+-              default:
+-                      /* default reference clock */
+-                      refclk_freq = FSEL_CLKSEL_24M;
+-                      break;
+-              }
+-      } else {
+-              switch (clk_get_rate(ref_clk)) {
+-              case 12 * MHZ:
+-                      refclk_freq = PHYCLK_CLKSEL_12M;
+-                      break;
+-              case 24 * MHZ:
+-                      refclk_freq = PHYCLK_CLKSEL_24M;
+-                      break;
+-              case 48 * MHZ:
+-                      refclk_freq = PHYCLK_CLKSEL_48M;
+-                      break;
+-              default:
+-                      if (sphy->drv_data->cpu_type == TYPE_S3C64XX)
+-                              refclk_freq = PHYCLK_CLKSEL_48M;
+-                      else
+-                              refclk_freq = PHYCLK_CLKSEL_24M;
+-                      break;
+-              }
+-      }
++      rate = clk_get_rate(ref_clk);
++      refclk_freq = sphy->drv_data->rate_to_clksel(sphy, rate);
++
+       clk_put(ref_clk);
+       return refclk_freq;
+diff --git a/drivers/usb/phy/phy-samsung-usb.h b/drivers/usb/phy/phy-samsung-usb.h
+index 70a9cae..0336f6b 100644
+--- a/drivers/usb/phy/phy-samsung-usb.h
++++ b/drivers/usb/phy/phy-samsung-usb.h
+@@ -244,6 +244,8 @@ enum samsung_cpu_type {
+       TYPE_EXYNOS5250,
+ };
++struct samsung_usbphy;
++
+ /*
+  * struct samsung_usbphy_drvdata - driver data for various SoC variants
+  * @cpu_type: machine identifier
+@@ -268,6 +270,7 @@ struct samsung_usbphy_drvdata {
+       int hostphy_en_mask;
+       u32 devphy_reg_offset;
+       u32 hostphy_reg_offset;
++      int (*rate_to_clksel)(struct samsung_usbphy *, unsigned long);
+ };
+ /*
+@@ -325,3 +328,7 @@ extern void samsung_usbphy_cfg_sel(struct samsung_usbphy *sphy);
+ extern int samsung_usbphy_set_type(struct usb_phy *phy,
+                                       enum samsung_usb_phy_type phy_type);
+ extern int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy);
++extern int samsung_usbphy_rate_to_clksel_64xx(struct samsung_usbphy *sphy,
++                                                      unsigned long rate);
++extern int samsung_usbphy_rate_to_clksel_4x12(struct samsung_usbphy *sphy,
++                                                      unsigned long rate);
+diff --git a/drivers/usb/phy/phy-samsung-usb2.c b/drivers/usb/phy/phy-samsung-usb2.c
+index 9d5e273..be6031d 100644
+--- a/drivers/usb/phy/phy-samsung-usb2.c
++++ b/drivers/usb/phy/phy-samsung-usb2.c
+@@ -408,7 +408,10 @@ static int samsung_usb2phy_probe(struct platform_device *pdev)
+       sphy->phy.label         = "samsung-usb2phy";
+       sphy->phy.init          = samsung_usb2phy_init;
+       sphy->phy.shutdown      = samsung_usb2phy_shutdown;
+-      sphy->ref_clk_freq      = samsung_usbphy_get_refclk_freq(sphy);
++
++      sphy->ref_clk_freq = samsung_usbphy_get_refclk_freq(sphy);
++      if (sphy->ref_clk_freq < 0)
++              return -EINVAL;
+       sphy->phy.otg           = otg;
+       sphy->phy.otg->phy      = &sphy->phy;
+@@ -438,18 +441,21 @@ static int samsung_usb2phy_remove(struct platform_device *pdev)
+ static const struct samsung_usbphy_drvdata usb2phy_s3c64xx = {
+       .cpu_type               = TYPE_S3C64XX,
+       .devphy_en_mask         = S3C64XX_USBPHY_ENABLE,
++      .rate_to_clksel         = samsung_usbphy_rate_to_clksel_64xx,
+ };
+ static const struct samsung_usbphy_drvdata usb2phy_exynos4 = {
+       .cpu_type               = TYPE_EXYNOS4210,
+       .devphy_en_mask         = EXYNOS_USBPHY_ENABLE,
+       .hostphy_en_mask        = EXYNOS_USBPHY_ENABLE,
++      .rate_to_clksel         = samsung_usbphy_rate_to_clksel_64xx,
+ };
+ static struct samsung_usbphy_drvdata usb2phy_exynos5 = {
+       .cpu_type               = TYPE_EXYNOS5250,
+       .hostphy_en_mask        = EXYNOS_USBPHY_ENABLE,
+       .hostphy_reg_offset     = EXYNOS_USBHOST_PHY_CTRL_OFFSET,
++      .rate_to_clksel         = samsung_usbphy_rate_to_clksel_4x12,
+ };
+ #ifdef CONFIG_OF
+diff --git a/drivers/usb/phy/phy-samsung-usb3.c b/drivers/usb/phy/phy-samsung-usb3.c
+index 5a9efcb..ec44b35 100644
+--- a/drivers/usb/phy/phy-samsung-usb3.c
++++ b/drivers/usb/phy/phy-samsung-usb3.c
+@@ -274,7 +274,10 @@ static int samsung_usb3phy_probe(struct platform_device *pdev)
+       sphy->phy.init          = samsung_usb3phy_init;
+       sphy->phy.shutdown      = samsung_usb3phy_shutdown;
+       sphy->drv_data          = samsung_usbphy_get_driver_data(pdev);
+-      sphy->ref_clk_freq      = samsung_usbphy_get_refclk_freq(sphy);
++
++      sphy->ref_clk_freq = samsung_usbphy_get_refclk_freq(sphy);
++      if (sphy->ref_clk_freq < 0)
++              return -EINVAL;
+       spin_lock_init(&sphy->lock);
+@@ -300,6 +303,7 @@ static int samsung_usb3phy_remove(struct platform_device *pdev)
+ static struct samsung_usbphy_drvdata usb3phy_exynos5 = {
+       .cpu_type               = TYPE_EXYNOS5250,
+       .devphy_en_mask         = EXYNOS_USBPHY_ENABLE,
++      .rate_to_clksel         = samsung_usbphy_rate_to_clksel_4x12,
+ };
+ #ifdef CONFIG_OF
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0011-usb-phy-samsung-Pass-set_isolation-callback-through-.patch b/patches.tizen/0011-usb-phy-samsung-Pass-set_isolation-callback-through-.patch
new file mode 100644 (file)
index 0000000..a717f63
--- /dev/null
@@ -0,0 +1,188 @@
+From 1fd2b2ad555a88707683d0241d2ae71874b553a6 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Mon, 25 Mar 2013 16:40:52 +0100
+Subject: [PATCH 0011/1302] usb: phy: samsung: Pass set_isolation callback
+ through driver data
+
+This patch extends driver data structure with set_isolation callback,
+which allows to remove the need for checking for SoC type in a switch
+statement.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/phy/phy-samsung-usb.c  | 36 ++++++++----------------------------
+ drivers/usb/phy/phy-samsung-usb.h  |  4 +++-
+ drivers/usb/phy/phy-samsung-usb2.c | 11 +++++++----
+ drivers/usb/phy/phy-samsung-usb3.c |  7 +++++--
+ 4 files changed, 23 insertions(+), 35 deletions(-)
+
+diff --git a/drivers/usb/phy/phy-samsung-usb.c b/drivers/usb/phy/phy-samsung-usb.c
+index c40ea32..7a1ed90 100644
+--- a/drivers/usb/phy/phy-samsung-usb.c
++++ b/drivers/usb/phy/phy-samsung-usb.c
+@@ -73,7 +73,7 @@ EXPORT_SYMBOL_GPL(samsung_usbphy_parse_dt);
+  * Here 'on = true' would mean USB PHY block is isolated, hence
+  * de-activated and vice-versa.
+  */
+-void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy, bool on)
++void samsung_usbphy_set_isolation_4210(struct samsung_usbphy *sphy, bool on)
+ {
+       void __iomem *reg = NULL;
+       u32 reg_val;
+@@ -84,32 +84,12 @@ void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy, bool on)
+               return;
+       }
+-      switch (sphy->drv_data->cpu_type) {
+-      case TYPE_S3C64XX:
+-              /*
+-               * Do nothing: We will add here once S3C64xx goes for DT support
+-               */
+-              break;
+-      case TYPE_EXYNOS4210:
+-              /*
+-               * Fall through since exynos4210 and exynos5250 have similar
+-               * register architecture: two separate registers for host and
+-               * device phy control with enable bit at position 0.
+-               */
+-      case TYPE_EXYNOS5250:
+-              if (sphy->phy_type == USB_PHY_TYPE_DEVICE) {
+-                      reg = sphy->pmuregs +
+-                              sphy->drv_data->devphy_reg_offset;
+-                      en_mask = sphy->drv_data->devphy_en_mask;
+-              } else if (sphy->phy_type == USB_PHY_TYPE_HOST) {
+-                      reg = sphy->pmuregs +
+-                              sphy->drv_data->hostphy_reg_offset;
+-                      en_mask = sphy->drv_data->hostphy_en_mask;
+-              }
+-              break;
+-      default:
+-              dev_err(sphy->dev, "Invalid SoC type\n");
+-              return;
++      if (sphy->phy_type == USB_PHY_TYPE_DEVICE) {
++              reg = sphy->pmuregs + sphy->drv_data->devphy_reg_offset;
++              en_mask = sphy->drv_data->devphy_en_mask;
++      } else if (sphy->phy_type == USB_PHY_TYPE_HOST) {
++              reg = sphy->pmuregs + sphy->drv_data->hostphy_reg_offset;
++              en_mask = sphy->drv_data->hostphy_en_mask;
+       }
+       reg_val = readl(reg);
+@@ -121,7 +101,7 @@ void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy, bool on)
+       writel(reg_val, reg);
+ }
+-EXPORT_SYMBOL_GPL(samsung_usbphy_set_isolation);
++EXPORT_SYMBOL_GPL(samsung_usbphy_set_isolation_4210);
+ /*
+  * Configure the mode of working of usb-phy here: HOST/DEVICE.
+diff --git a/drivers/usb/phy/phy-samsung-usb.h b/drivers/usb/phy/phy-samsung-usb.h
+index 0336f6b..5203784 100644
+--- a/drivers/usb/phy/phy-samsung-usb.h
++++ b/drivers/usb/phy/phy-samsung-usb.h
+@@ -271,6 +271,7 @@ struct samsung_usbphy_drvdata {
+       u32 devphy_reg_offset;
+       u32 hostphy_reg_offset;
+       int (*rate_to_clksel)(struct samsung_usbphy *, unsigned long);
++      void (*set_isolation)(struct samsung_usbphy *, bool);
+ };
+ /*
+@@ -323,7 +324,8 @@ static inline const struct samsung_usbphy_drvdata
+ }
+ extern int samsung_usbphy_parse_dt(struct samsung_usbphy *sphy);
+-extern void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy, bool on);
++extern void samsung_usbphy_set_isolation_4210(struct samsung_usbphy *sphy,
++                                                              bool on);
+ extern void samsung_usbphy_cfg_sel(struct samsung_usbphy *sphy);
+ extern int samsung_usbphy_set_type(struct usb_phy *phy,
+                                       enum samsung_usb_phy_type phy_type);
+diff --git a/drivers/usb/phy/phy-samsung-usb2.c b/drivers/usb/phy/phy-samsung-usb2.c
+index be6031d..a01247e 100644
+--- a/drivers/usb/phy/phy-samsung-usb2.c
++++ b/drivers/usb/phy/phy-samsung-usb2.c
+@@ -284,8 +284,8 @@ static int samsung_usb2phy_init(struct usb_phy *phy)
+       /* Disable phy isolation */
+       if (sphy->plat && sphy->plat->pmu_isolation)
+               sphy->plat->pmu_isolation(false);
+-      else
+-              samsung_usbphy_set_isolation(sphy, false);
++      else if (sphy->drv_data->set_isolation)
++              sphy->drv_data->set_isolation(sphy, false);
+       /* Selecting Host/OTG mode; After reset USB2.0PHY_CFG: HOST */
+       samsung_usbphy_cfg_sel(sphy);
+@@ -342,8 +342,8 @@ static void samsung_usb2phy_shutdown(struct usb_phy *phy)
+       /* Enable phy isolation */
+       if (sphy->plat && sphy->plat->pmu_isolation)
+               sphy->plat->pmu_isolation(true);
+-      else
+-              samsung_usbphy_set_isolation(sphy, true);
++      else if (sphy->drv_data->set_isolation)
++              sphy->drv_data->set_isolation(sphy, true);
+       spin_unlock_irqrestore(&sphy->lock, flags);
+@@ -442,6 +442,7 @@ static const struct samsung_usbphy_drvdata usb2phy_s3c64xx = {
+       .cpu_type               = TYPE_S3C64XX,
+       .devphy_en_mask         = S3C64XX_USBPHY_ENABLE,
+       .rate_to_clksel         = samsung_usbphy_rate_to_clksel_64xx,
++      .set_isolation          = NULL, /* TODO */
+ };
+ static const struct samsung_usbphy_drvdata usb2phy_exynos4 = {
+@@ -449,6 +450,7 @@ static const struct samsung_usbphy_drvdata usb2phy_exynos4 = {
+       .devphy_en_mask         = EXYNOS_USBPHY_ENABLE,
+       .hostphy_en_mask        = EXYNOS_USBPHY_ENABLE,
+       .rate_to_clksel         = samsung_usbphy_rate_to_clksel_64xx,
++      .set_isolation          = samsung_usbphy_set_isolation_4210,
+ };
+ static struct samsung_usbphy_drvdata usb2phy_exynos5 = {
+@@ -456,6 +458,7 @@ static struct samsung_usbphy_drvdata usb2phy_exynos5 = {
+       .hostphy_en_mask        = EXYNOS_USBPHY_ENABLE,
+       .hostphy_reg_offset     = EXYNOS_USBHOST_PHY_CTRL_OFFSET,
+       .rate_to_clksel         = samsung_usbphy_rate_to_clksel_4x12,
++      .set_isolation          = samsung_usbphy_set_isolation_4210,
+ };
+ #ifdef CONFIG_OF
+diff --git a/drivers/usb/phy/phy-samsung-usb3.c b/drivers/usb/phy/phy-samsung-usb3.c
+index ec44b35..3a30a5e 100644
+--- a/drivers/usb/phy/phy-samsung-usb3.c
++++ b/drivers/usb/phy/phy-samsung-usb3.c
+@@ -184,7 +184,8 @@ static int samsung_usb3phy_init(struct usb_phy *phy)
+       samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_DEVICE);
+       /* Disable phy isolation */
+-      samsung_usbphy_set_isolation(sphy, false);
++      if (sphy->drv_data->set_isolation)
++              sphy->drv_data->set_isolation(sphy, false);
+       /* Initialize usb phy registers */
+       samsung_exynos5_usb3phy_enable(sphy);
+@@ -221,7 +222,8 @@ static void samsung_usb3phy_shutdown(struct usb_phy *phy)
+       samsung_exynos5_usb3phy_disable(sphy);
+       /* Enable phy isolation */
+-      samsung_usbphy_set_isolation(sphy, true);
++      if (sphy->drv_data->set_isolation)
++              sphy->drv_data->set_isolation(sphy, true);
+       spin_unlock_irqrestore(&sphy->lock, flags);
+@@ -304,6 +306,7 @@ static struct samsung_usbphy_drvdata usb3phy_exynos5 = {
+       .cpu_type               = TYPE_EXYNOS5250,
+       .devphy_en_mask         = EXYNOS_USBPHY_ENABLE,
+       .rate_to_clksel         = samsung_usbphy_rate_to_clksel_4x12,
++      .set_isolation          = samsung_usbphy_set_isolation_4210,
+ };
+ #ifdef CONFIG_OF
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0012-usb-phy-samsung-Pass-enable-disable-callbacks-throug.patch b/patches.tizen/0012-usb-phy-samsung-Pass-enable-disable-callbacks-throug.patch
new file mode 100644 (file)
index 0000000..00a0c7a
--- /dev/null
@@ -0,0 +1,139 @@
+From 0b1ad1c2d3320a3e31f3f66e4a1c29d6763006cb Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Mon, 25 Mar 2013 16:57:32 +0100
+Subject: [PATCH 0012/1302] usb: phy: samsung: Pass enable/disable callbacks
+ through driver data
+
+To remove unnecessary if statements, this patch introduces phy_enable
+and phy_disable callbacks in driver data structure that implement
+SoC-specific PHY initialization and deinitialization.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/phy/phy-samsung-usb.h  |  2 ++
+ drivers/usb/phy/phy-samsung-usb2.c | 16 ++++++++--------
+ drivers/usb/phy/phy-samsung-usb3.c | 10 +++++-----
+ 3 files changed, 15 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/usb/phy/phy-samsung-usb.h b/drivers/usb/phy/phy-samsung-usb.h
+index 5203784..31e2ec3 100644
+--- a/drivers/usb/phy/phy-samsung-usb.h
++++ b/drivers/usb/phy/phy-samsung-usb.h
+@@ -272,6 +272,8 @@ struct samsung_usbphy_drvdata {
+       u32 hostphy_reg_offset;
+       int (*rate_to_clksel)(struct samsung_usbphy *, unsigned long);
+       void (*set_isolation)(struct samsung_usbphy *, bool);
++      void (*phy_enable)(struct samsung_usbphy *);
++      void (*phy_disable)(struct samsung_usbphy *);
+ };
+ /*
+diff --git a/drivers/usb/phy/phy-samsung-usb2.c b/drivers/usb/phy/phy-samsung-usb2.c
+index a01247e..1c3abd4 100644
+--- a/drivers/usb/phy/phy-samsung-usb2.c
++++ b/drivers/usb/phy/phy-samsung-usb2.c
+@@ -291,10 +291,7 @@ static int samsung_usb2phy_init(struct usb_phy *phy)
+       samsung_usbphy_cfg_sel(sphy);
+       /* Initialize usb phy registers */
+-      if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250)
+-              samsung_exynos5_usb2phy_enable(sphy);
+-      else
+-              samsung_usb2phy_enable(sphy);
++      sphy->drv_data->phy_enable(sphy);
+       spin_unlock_irqrestore(&sphy->lock, flags);
+@@ -334,10 +331,7 @@ static void samsung_usb2phy_shutdown(struct usb_phy *phy)
+       }
+       /* De-initialize usb phy registers */
+-      if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250)
+-              samsung_exynos5_usb2phy_disable(sphy);
+-      else
+-              samsung_usb2phy_disable(sphy);
++      sphy->drv_data->phy_disable(sphy);
+       /* Enable phy isolation */
+       if (sphy->plat && sphy->plat->pmu_isolation)
+@@ -443,6 +437,8 @@ static const struct samsung_usbphy_drvdata usb2phy_s3c64xx = {
+       .devphy_en_mask         = S3C64XX_USBPHY_ENABLE,
+       .rate_to_clksel         = samsung_usbphy_rate_to_clksel_64xx,
+       .set_isolation          = NULL, /* TODO */
++      .phy_enable             = samsung_usb2phy_enable,
++      .phy_disable            = samsung_usb2phy_disable,
+ };
+ static const struct samsung_usbphy_drvdata usb2phy_exynos4 = {
+@@ -451,6 +447,8 @@ static const struct samsung_usbphy_drvdata usb2phy_exynos4 = {
+       .hostphy_en_mask        = EXYNOS_USBPHY_ENABLE,
+       .rate_to_clksel         = samsung_usbphy_rate_to_clksel_64xx,
+       .set_isolation          = samsung_usbphy_set_isolation_4210,
++      .phy_enable             = samsung_usb2phy_enable,
++      .phy_disable            = samsung_usb2phy_disable,
+ };
+ static struct samsung_usbphy_drvdata usb2phy_exynos5 = {
+@@ -459,6 +457,8 @@ static struct samsung_usbphy_drvdata usb2phy_exynos5 = {
+       .hostphy_reg_offset     = EXYNOS_USBHOST_PHY_CTRL_OFFSET,
+       .rate_to_clksel         = samsung_usbphy_rate_to_clksel_4x12,
+       .set_isolation          = samsung_usbphy_set_isolation_4210,
++      .phy_enable             = samsung_exynos5_usb2phy_enable,
++      .phy_disable            = samsung_exynos5_usb2phy_disable,
+ };
+ #ifdef CONFIG_OF
+diff --git a/drivers/usb/phy/phy-samsung-usb3.c b/drivers/usb/phy/phy-samsung-usb3.c
+index 3a30a5e..300e0cf 100644
+--- a/drivers/usb/phy/phy-samsung-usb3.c
++++ b/drivers/usb/phy/phy-samsung-usb3.c
+@@ -65,7 +65,7 @@ static u32 samsung_usb3phy_set_refclk(struct samsung_usbphy *sphy)
+       return reg;
+ }
+-static int samsung_exynos5_usb3phy_enable(struct samsung_usbphy *sphy)
++static void samsung_exynos5_usb3phy_enable(struct samsung_usbphy *sphy)
+ {
+       void __iomem *regs = sphy->regs;
+       u32 phyparam0;
+@@ -133,8 +133,6 @@ static int samsung_exynos5_usb3phy_enable(struct samsung_usbphy *sphy)
+       phyclkrst &= ~(PHYCLKRST_PORTRESET);
+       writel(phyclkrst, regs + EXYNOS5_DRD_PHYCLKRST);
+-
+-      return 0;
+ }
+ static void samsung_exynos5_usb3phy_disable(struct samsung_usbphy *sphy)
+@@ -188,7 +186,7 @@ static int samsung_usb3phy_init(struct usb_phy *phy)
+               sphy->drv_data->set_isolation(sphy, false);
+       /* Initialize usb phy registers */
+-      samsung_exynos5_usb3phy_enable(sphy);
++      sphy->drv_data->phy_enable(sphy);
+       spin_unlock_irqrestore(&sphy->lock, flags);
+@@ -219,7 +217,7 @@ static void samsung_usb3phy_shutdown(struct usb_phy *phy)
+       samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_DEVICE);
+       /* De-initialize usb phy registers */
+-      samsung_exynos5_usb3phy_disable(sphy);
++      sphy->drv_data->phy_disable(sphy);
+       /* Enable phy isolation */
+       if (sphy->drv_data->set_isolation)
+@@ -307,6 +305,8 @@ static struct samsung_usbphy_drvdata usb3phy_exynos5 = {
+       .devphy_en_mask         = EXYNOS_USBPHY_ENABLE,
+       .rate_to_clksel         = samsung_usbphy_rate_to_clksel_4x12,
+       .set_isolation          = samsung_usbphy_set_isolation_4210,
++      .phy_enable             = samsung_exynos5_usb3phy_enable,
++      .phy_disable            = samsung_exynos5_usb3phy_disable,
+ };
+ #ifdef CONFIG_OF
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0013-usb-phy-samsung-Add-support-for-USB-2.0-PHY-on-Exyno.patch b/patches.tizen/0013-usb-phy-samsung-Add-support-for-USB-2.0-PHY-on-Exyno.patch
new file mode 100644 (file)
index 0000000..30c8891
--- /dev/null
@@ -0,0 +1,88 @@
+From b02d45e230000601faad72811548bb3d93203152 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Mon, 25 Mar 2013 17:39:07 +0100
+Subject: [PATCH 0013/1302] usb: phy: samsung: Add support for USB 2.0 PHY on
+ Exynos 4x12
+
+This patch adds driver data for Exynos 4x12 USB 2.0 PHY.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/phy/phy-samsung-usb.h  |  1 +
+ drivers/usb/phy/phy-samsung-usb2.c | 18 ++++++++++++++++++
+ 2 files changed, 19 insertions(+)
+
+diff --git a/drivers/usb/phy/phy-samsung-usb.h b/drivers/usb/phy/phy-samsung-usb.h
+index 31e2ec3..585d12f 100644
+--- a/drivers/usb/phy/phy-samsung-usb.h
++++ b/drivers/usb/phy/phy-samsung-usb.h
+@@ -241,6 +241,7 @@
+ enum samsung_cpu_type {
+       TYPE_S3C64XX,
+       TYPE_EXYNOS4210,
++      TYPE_EXYNOS4X12,
+       TYPE_EXYNOS5250,
+ };
+diff --git a/drivers/usb/phy/phy-samsung-usb2.c b/drivers/usb/phy/phy-samsung-usb2.c
+index 1c3abd4..03180c0 100644
+--- a/drivers/usb/phy/phy-samsung-usb2.c
++++ b/drivers/usb/phy/phy-samsung-usb2.c
+@@ -177,6 +177,7 @@ static void samsung_usb2phy_enable(struct samsung_usbphy *sphy)
+               rstcon |= RSTCON_SWRST;
+               break;
+       case TYPE_EXYNOS4210:
++      case TYPE_EXYNOS4X12:
+               phypwr &= ~PHYPWR_NORMAL_MASK_PHY0;
+               rstcon |= RSTCON_SWRST;
+       default:
+@@ -240,6 +241,7 @@ static void samsung_usb2phy_disable(struct samsung_usbphy *sphy)
+               phypwr |= PHYPWR_NORMAL_MASK;
+               break;
+       case TYPE_EXYNOS4210:
++      case TYPE_EXYNOS4X12:
+               phypwr |= PHYPWR_NORMAL_MASK_PHY0;
+       default:
+               break;
+@@ -451,6 +453,16 @@ static const struct samsung_usbphy_drvdata usb2phy_exynos4 = {
+       .phy_disable            = samsung_usb2phy_disable,
+ };
++static const struct samsung_usbphy_drvdata usb2phy_exynos4x12 = {
++      .cpu_type               = TYPE_EXYNOS4X12,
++      .devphy_en_mask         = EXYNOS_USBPHY_ENABLE,
++      .hostphy_en_mask        = EXYNOS_USBPHY_ENABLE,
++      .rate_to_clksel         = samsung_usbphy_rate_to_clksel_4x12,
++      .set_isolation          = samsung_usbphy_set_isolation_4210,
++      .phy_enable             = samsung_usb2phy_enable,
++      .phy_disable            = samsung_usb2phy_disable,
++};
++
+ static struct samsung_usbphy_drvdata usb2phy_exynos5 = {
+       .cpu_type               = TYPE_EXYNOS5250,
+       .hostphy_en_mask        = EXYNOS_USBPHY_ENABLE,
+@@ -470,6 +482,9 @@ static const struct of_device_id samsung_usbphy_dt_match[] = {
+               .compatible = "samsung,exynos4210-usb2phy",
+               .data = &usb2phy_exynos4,
+       }, {
++              .compatible = "samsung,exynos4x12-usb2phy",
++              .data = &usb2phy_exynos4x12,
++      }, {
+               .compatible = "samsung,exynos5250-usb2phy",
+               .data = &usb2phy_exynos5
+       },
+@@ -486,6 +501,9 @@ static struct platform_device_id samsung_usbphy_driver_ids[] = {
+               .name           = "exynos4210-usb2phy",
+               .driver_data    = (unsigned long)&usb2phy_exynos4,
+       }, {
++              .name           = "exynos4x12-usb2phy",
++              .driver_data    = (unsigned long)&usb2phy_exynos4x12,
++      }, {
+               .name           = "exynos5250-usb2phy",
+               .driver_data    = (unsigned long)&usb2phy_exynos5,
+       },
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0014-ARM-dts-exynos4-Add-node-for-hsotg.patch b/patches.tizen/0014-ARM-dts-exynos4-Add-node-for-hsotg.patch
new file mode 100644 (file)
index 0000000..92425a8
--- /dev/null
@@ -0,0 +1,32 @@
+From 23b3d46f3bfbd2f3f1a53b5210a986667300e25b Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Tue, 11 Sep 2012 13:37:40 +0200
+Subject: [PATCH 0014/1302] ARM: dts: exynos4: Add node for hsotg
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index b90bab3..5f57f59 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -350,6 +350,13 @@
+               status = "disabled";
+       };
++      hsotg@12480000 {
++              compatible = "samsung,s3c-hsotg";
++              reg = <0x12480000 0x20000>;
++              interrupts = <0 71 0>;
++              status = "disabled";
++      };
++
+       amba {
+               #address-cells = <1>;
+               #size-cells = <1>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0015-iommu-exynos-do-not-include-removed-header.patch b/patches.tizen/0015-iommu-exynos-do-not-include-removed-header.patch
new file mode 100644 (file)
index 0000000..f249702
--- /dev/null
@@ -0,0 +1,37 @@
+From cbffb3bc2d93c6b044332fc24fce091cedef80ff Mon Sep 17 00:00:00 2001
+From: Cho KyongHo <pullip.cho@samsung.com>
+Date: Fri, 26 Jul 2013 20:26:10 +0900
+Subject: [PATCH 0015/1302] iommu/exynos: do not include removed header
+
+This commit remove <mach/sysmmu.h> which is removed.
+
+Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iommu/exynos-iommu.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
+index 3f32d64..233f382 100644
+--- a/drivers/iommu/exynos-iommu.c
++++ b/drivers/iommu/exynos-iommu.c
+@@ -12,6 +12,7 @@
+ #define DEBUG
+ #endif
++#include <linux/kernel.h>
+ #include <linux/io.h>
+ #include <linux/interrupt.h>
+ #include <linux/platform_device.h>
+@@ -29,8 +30,6 @@
+ #include <asm/cacheflush.h>
+ #include <asm/pgtable.h>
+-#include <mach/sysmmu.h>
+-
+ /* We does not consider super section mapping (16MB) */
+ #define SECT_ORDER 20
+ #define LPAGE_ORDER 16
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0016-iommu-exynos-add-missing-cache-flush-for-removed-pag.patch b/patches.tizen/0016-iommu-exynos-add-missing-cache-flush-for-removed-pag.patch
new file mode 100644 (file)
index 0000000..118a322
--- /dev/null
@@ -0,0 +1,40 @@
+From bc5501f6b0afe076af0f30845221dbb4834c6ed4 Mon Sep 17 00:00:00 2001
+From: Cho KyongHo <pullip.cho@samsung.com>
+Date: Fri, 26 Jul 2013 20:26:28 +0900
+Subject: [PATCH 0016/1302] iommu/exynos: add missing cache flush for removed
+ page table entries
+
+This commit adds cache flush for removed small and large page entries
+in exynos_iommu_unmap(). Missing cache flush of removed page table
+entries can cause missing page fault interrupt when a master IP
+accesses an unmapped area.
+
+Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iommu/exynos-iommu.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
+index 233f382..e3be3e5 100644
+--- a/drivers/iommu/exynos-iommu.c
++++ b/drivers/iommu/exynos-iommu.c
+@@ -1002,6 +1002,7 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain,
+       if (lv2ent_small(ent)) {
+               *ent = 0;
+               size = SPAGE_SIZE;
++              pgtable_flush(ent, ent +1);
+               priv->lv2entcnt[lv1ent_offset(iova)] += 1;
+               goto done;
+       }
+@@ -1010,6 +1011,7 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain,
+       BUG_ON(size < LPAGE_SIZE);
+       memset(ent, 0, sizeof(*ent) * SPAGES_PER_LPAGE);
++      pgtable_flush(ent, ent + SPAGES_PER_LPAGE);
+       size = LPAGE_SIZE;
+       priv->lv2entcnt[lv1ent_offset(iova)] += SPAGES_PER_LPAGE;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0017-iommu-exynos-fix-page-table-maintenance.patch b/patches.tizen/0017-iommu-exynos-fix-page-table-maintenance.patch
new file mode 100644 (file)
index 0000000..481b43c
--- /dev/null
@@ -0,0 +1,151 @@
+From e16855c6f3919791b9ffc0d7471843df045e43ca Mon Sep 17 00:00:00 2001
+From: Cho KyongHo <pullip.cho@samsung.com>
+Date: Fri, 26 Jul 2013 20:27:11 +0900
+Subject: [PATCH 0017/1302] iommu/exynos: fix page table maintenance
+
+This prevents allocating lv2 page table for the lv1 page table entry
+that already has 1MB page mapping. In addition some BUG_ON() is
+changed to WARN_ON().
+
+Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iommu/exynos-iommu.c | 52 +++++++++++++++++++++++++++++++-------------
+ 1 file changed, 37 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
+index e3be3e5..6c4ecce 100644
+--- a/drivers/iommu/exynos-iommu.c
++++ b/drivers/iommu/exynos-iommu.c
+@@ -52,11 +52,11 @@
+ #define lv2ent_large(pent) ((*(pent) & 3) == 1)
+ #define section_phys(sent) (*(sent) & SECT_MASK)
+-#define section_offs(iova) ((iova) & 0xFFFFF)
++#define section_offs(iova) ((iova) & ~SECT_MASK)
+ #define lpage_phys(pent) (*(pent) & LPAGE_MASK)
+-#define lpage_offs(iova) ((iova) & 0xFFFF)
++#define lpage_offs(iova) ((iova) & ~LPAGE_MASK)
+ #define spage_phys(pent) (*(pent) & SPAGE_MASK)
+-#define spage_offs(iova) ((iova) & 0xFFF)
++#define spage_offs(iova) ((iova) & ~SPAGE_MASK)
+ #define lv1ent_offset(iova) ((iova) >> SECT_ORDER)
+ #define lv2ent_offset(iova) (((iova) & 0xFF000) >> SPAGE_ORDER)
+@@ -862,12 +862,14 @@ static unsigned long *alloc_lv2entry(unsigned long *sent, unsigned long iova,
+               pent = kzalloc(LV2TABLE_SIZE, GFP_ATOMIC);
+               BUG_ON((unsigned long)pent & (LV2TABLE_SIZE - 1));
+               if (!pent)
+-                      return NULL;
++                      return ERR_PTR(-ENOMEM);
+               *sent = mk_lv1ent_page(__pa(pent));
+               *pgcounter = NUM_LV2ENTRIES;
+               pgtable_flush(pent, pent + NUM_LV2ENTRIES);
+               pgtable_flush(sent, sent + 1);
++      } else if (lv1ent_section(sent)) {
++              return ERR_PTR(-EADDRINUSE);
+       }
+       return page_entry(sent, iova);
+@@ -894,6 +896,12 @@ static int lv1set_section(unsigned long *sent, phys_addr_t paddr, short *pgcnt)
+       return 0;
+ }
++static void clear_page_table(unsigned long *ent, int n)
++{
++      if (n > 0)
++              memset(ent, 0, sizeof(*ent) * n);
++}
++
+ static int lv2set_page(unsigned long *pent, phys_addr_t paddr, size_t size,
+                                                               short *pgcnt)
+ {
+@@ -908,7 +916,7 @@ static int lv2set_page(unsigned long *pent, phys_addr_t paddr, size_t size,
+               int i;
+               for (i = 0; i < SPAGES_PER_LPAGE; i++, pent++) {
+                       if (!lv2ent_fault(pent)) {
+-                              memset(pent, 0, sizeof(*pent) * i);
++                              clear_page_table(pent - i, i);
+                               return -EADDRINUSE;
+                       }
+@@ -944,17 +952,16 @@ static int exynos_iommu_map(struct iommu_domain *domain, unsigned long iova,
+               pent = alloc_lv2entry(entry, iova,
+                                       &priv->lv2entcnt[lv1ent_offset(iova)]);
+-              if (!pent)
+-                      ret = -ENOMEM;
++              if (IS_ERR(pent))
++                      ret = PTR_ERR(pent);
+               else
+                       ret = lv2set_page(pent, paddr, size,
+                                       &priv->lv2entcnt[lv1ent_offset(iova)]);
+       }
+-      if (ret) {
+-              pr_debug("%s: Failed to map iova 0x%lx/0x%x bytes\n",
+-                                                      __func__, iova, size);
+-      }
++      if (ret)
++              pr_err("%s: Failed(%d) to map 0x%#x bytes @ %#lx\n",
++                      __func__, ret, size, iova);
+       spin_unlock_irqrestore(&priv->pgtablelock, flags);
+@@ -968,6 +975,7 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain,
+       struct sysmmu_drvdata *data;
+       unsigned long flags;
+       unsigned long *ent;
++      size_t err_pgsize;
+       BUG_ON(priv->pgtable == NULL);
+@@ -976,7 +984,10 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain,
+       ent = section_entry(priv->pgtable, iova);
+       if (lv1ent_section(ent)) {
+-              BUG_ON(size < SECT_SIZE);
++              if (WARN_ON(size < SECT_SIZE)) {
++                      err_pgsize = SECT_SIZE;
++                      goto err;
++              }
+               *ent = 0;
+               pgtable_flush(ent, ent + 1);
+@@ -1008,9 +1019,12 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain,
+       }
+       /* lv1ent_large(ent) == true here */
+-      BUG_ON(size < LPAGE_SIZE);
++      if (WARN_ON(size < LPAGE_SIZE)) {
++              err_pgsize = LPAGE_SIZE;
++              goto err;
++      }
+-      memset(ent, 0, sizeof(*ent) * SPAGES_PER_LPAGE);
++      clear_page_table(ent, SPAGES_PER_LPAGE);
+       pgtable_flush(ent, ent + SPAGES_PER_LPAGE);
+       size = LPAGE_SIZE;
+@@ -1023,8 +1037,16 @@ done:
+               sysmmu_tlb_invalidate_entry(data->dev, iova);
+       spin_unlock_irqrestore(&priv->lock, flags);
+-
+       return size;
++err:
++      spin_unlock_irqrestore(&priv->pgtablelock, flags);
++
++      pr_err("%s: Failed due to size(%#x) @ %#lx is"\
++              " smaller than page size %#x\n",
++              __func__, size, iova, err_pgsize);
++
++      return 0;
++
+ }
+ static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *domain,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0018-iommu-exynos-allocate-lv2-page-table-from-own-slab.patch b/patches.tizen/0018-iommu-exynos-allocate-lv2-page-table-from-own-slab.patch
new file mode 100644 (file)
index 0000000..bb5a914
--- /dev/null
@@ -0,0 +1,84 @@
+From 429942a268e534b39ddbe819cbd8c5641c7bbf38 Mon Sep 17 00:00:00 2001
+From: Cho KyongHo <pullip.cho@samsung.com>
+Date: Fri, 26 Jul 2013 20:27:29 +0900
+Subject: [PATCH 0018/1302] iommu/exynos: allocate lv2 page table from own slab
+
+Since kmalloc() does not guarantee that the allignment of 1KiB when it
+allocates 1KiB, it is required to allocate lv2 page table from own
+slab that guarantees alignment of 1KiB
+
+Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iommu/exynos-iommu.c | 24 ++++++++++++++++++++----
+ 1 file changed, 20 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
+index 6c4ecce..093eea5 100644
+--- a/drivers/iommu/exynos-iommu.c
++++ b/drivers/iommu/exynos-iommu.c
+@@ -100,6 +100,8 @@
+ #define REG_PB1_SADDR         0x054
+ #define REG_PB1_EADDR         0x058
++static struct kmem_cache *lv2table_kmem_cache;
++
+ static unsigned long *section_entry(unsigned long *pgtable, unsigned long iova)
+ {
+       return pgtable + lv1ent_offset(iova);
+@@ -765,7 +767,8 @@ static void exynos_iommu_domain_destroy(struct iommu_domain *domain)
+       for (i = 0; i < NUM_LV1ENTRIES; i++)
+               if (lv1ent_page(priv->pgtable + i))
+-                      kfree(__va(lv2table_base(priv->pgtable + i)));
++                      kmem_cache_free(lv2table_kmem_cache,
++                                      __va(lv2table_base(priv->pgtable + i)));
+       free_pages((unsigned long)priv->pgtable, 2);
+       free_pages((unsigned long)priv->lv2entcnt, 1);
+@@ -859,7 +862,7 @@ static unsigned long *alloc_lv2entry(unsigned long *sent, unsigned long iova,
+       if (lv1ent_fault(sent)) {
+               unsigned long *pent;
+-              pent = kzalloc(LV2TABLE_SIZE, GFP_ATOMIC);
++              pent = kmem_cache_zalloc(lv2table_kmem_cache, GFP_ATOMIC);
+               BUG_ON((unsigned long)pent & (LV2TABLE_SIZE - 1));
+               if (!pent)
+                       return ERR_PTR(-ENOMEM);
+@@ -884,7 +887,7 @@ static int lv1set_section(unsigned long *sent, phys_addr_t paddr, short *pgcnt)
+               if (*pgcnt != NUM_LV2ENTRIES)
+                       return -EADDRINUSE;
+-              kfree(page_entry(sent, 0));
++              kmem_cache_free(lv2table_kmem_cache, page_entry(sent, 0));
+               *pgcnt = 0;
+       }
+@@ -1092,10 +1095,23 @@ static int __init exynos_iommu_init(void)
+ {
+       int ret;
++      lv2table_kmem_cache = kmem_cache_create("exynos-iommu-lv2table",
++                              LV2TABLE_SIZE, LV2TABLE_SIZE, 0, NULL);
++      if (!lv2table_kmem_cache) {
++              pr_err("%s: Failed to create kmem cache\n", __func__);
++              return -ENOMEM;
++      }
++
+       ret = platform_driver_register(&exynos_sysmmu_driver);
+       if (ret == 0)
+-              bus_set_iommu(&platform_bus_type, &exynos_iommu_ops);
++              ret = bus_set_iommu(&platform_bus_type, &exynos_iommu_ops);
++
++      if (ret) {
++              pr_err("%s: Failed to register exynos-iommu driver.\n",
++                                                              __func__);
++              kmem_cache_destroy(lv2table_kmem_cache);
++      }
+       return ret;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0019-clk-exynos5250-add-gate-clock-descriptions-of-System.patch b/patches.tizen/0019-clk-exynos5250-add-gate-clock-descriptions-of-System.patch
new file mode 100644 (file)
index 0000000..e68990e
--- /dev/null
@@ -0,0 +1,157 @@
+From c25040eec6251a3cd2f82d7dc7133c29fd019a6e Mon Sep 17 00:00:00 2001
+From: Cho KyongHo <pullip.cho@samsung.com>
+Date: Fri, 26 Jul 2013 20:27:54 +0900
+Subject: [PATCH 0019/1302] clk: exynos5250: add gate clock descriptions of
+ System MMU
+
+This adds gate clocks of all System MMUs and their master IPs
+that are not apeared in clk-exynos5250.c
+
+Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/clock/exynos5250-clock.txt | 28 ++++++++++-
+ drivers/clk/samsung/clk-exynos5250.c               | 57 ++++++++++++++++++----
+ 2 files changed, 75 insertions(+), 10 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/clock/exynos5250-clock.txt b/Documentation/devicetree/bindings/clock/exynos5250-clock.txt
+index 781a627..df49694 100644
+--- a/Documentation/devicetree/bindings/clock/exynos5250-clock.txt
++++ b/Documentation/devicetree/bindings/clock/exynos5250-clock.txt
+@@ -154,7 +154,33 @@ clock which they consume.
+   dsim0                       341
+   dp                  342
+   mixer                       343
+-  hdmi                        345
++  hdmi                        344
++  camif_top           345
++  smmu_fimc_lite0     346
++  smmu_fimc_lite1     347
++  smmu_fimc_lite2     348
++  smmu_tv             349
++  smmu_fimd1          350
++  smmu_2d             351
++  fimc_isp            352
++  fimc_drc            353
++  fimc_fd             354
++  fimc_scc            355
++  fimc_scp            356
++  fimc_mcuctl         357
++  fimc_odc            358
++  fimc_dis            359
++  fimc_3dnr           360
++  smmu_fimc_isp               361
++  smmu_fimc_drc               362
++  smmu_fimc_fd                363
++  smmu_fimc_scc               364
++  smmu_fimc_scp               365
++  smmu_fimc_mcuctl    366
++  smmu_fimc_odc               367
++  smmu_fimc_dis0      368
++  smmu_fimc_dis1      369
++  smmu_fimc_3dnr      370
+ Example 1: An example of a clock controller node is listed below.
+diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
+index 22d7699..e242bde 100644
+--- a/drivers/clk/samsung/clk-exynos5250.c
++++ b/drivers/clk/samsung/clk-exynos5250.c
+@@ -53,12 +53,15 @@
+ #define DIV_PERIC3            0x10564
+ #define DIV_PERIC4            0x10568
+ #define DIV_PERIC5            0x1056c
++#define GATE_IP_ISP0          0x0C800
++#define GATE_IP_ISP1          0x0C800
+ #define GATE_IP_GSCL          0x10920
+ #define GATE_IP_MFC           0x1092c
+ #define GATE_IP_GEN           0x10934
+ #define GATE_IP_FSYS          0x10944
+ #define GATE_IP_PERIC         0x10950
+ #define GATE_IP_PERIS         0x10960
++#define GATE_IP_ACP           0x18800
+ #define SRC_CDREX             0x20200
+ #define PLL_DIV2_SEL          0x20a24
+ #define GATE_IP_DISP1         0x10928
+@@ -100,6 +103,14 @@ enum exynos5250_clks {
+       tzpc2, tzpc3, tzpc4, tzpc5, tzpc6, tzpc7, tzpc8, tzpc9, hdmi_cec, mct,
+       wdt, rtc, tmu, fimd1, mie1, dsim0, dp, mixer, hdmi,
++      camif_top, smmu_fimc_lite0, smmu_fimc_lite1, smmu_fimc_lite2,
++      smmu_tv, smmu_fimd1, smmu_2d,
++      fimc_isp, fimc_drc, fimc_fd, fimc_scc, fimc_scp, fimc_mcuctl, fimc_odc,
++      fimc_dis, fimc_3dnr,
++      smmu_fimc_isp, smmu_fimc_drc, smmu_fimc_fd, smmu_fimc_scc,
++      smmu_fimc_scp, smmu_fimc_mcuctl, smmu_fimc_odc, smmu_fimc_dis0,
++      smmu_fimc_dis1, smmu_fimc_3dnr,
++
+       nr_clks,
+ };
+@@ -320,19 +331,26 @@ struct samsung_gate_clock exynos5250_gate_clks[] __initdata = {
+       GATE(gscl3, "gscl3", "aclk266", GATE_IP_GSCL, 3, 0, 0),
+       GATE(gscl_wa, "gscl_wa", "div_gscl_wa", GATE_IP_GSCL, 5, 0, 0),
+       GATE(gscl_wb, "gscl_wb", "div_gscl_wb", GATE_IP_GSCL, 6, 0, 0),
+-      GATE(smmu_gscl0, "smmu_gscl0", "aclk266", GATE_IP_GSCL, 7, 0, 0),
+-      GATE(smmu_gscl1, "smmu_gscl1", "aclk266", GATE_IP_GSCL, 8, 0, 0),
+-      GATE(smmu_gscl2, "smmu_gscl2", "aclk266", GATE_IP_GSCL, 9, 0, 0),
+-      GATE(smmu_gscl3, "smmu_gscl3", "aclk266", GATE_IP_GSCL, 10, 0, 0),
++      GATE(smmu_gscl0, "smmu_gscl0", "none", GATE_IP_GSCL, 7, 0, 0),
++      GATE(smmu_gscl1, "smmu_gscl1", "none", GATE_IP_GSCL, 8, 0, 0),
++      GATE(smmu_gscl2, "smmu_gscl2", "none", GATE_IP_GSCL, 9, 0, 0),
++      GATE(smmu_gscl3, "smmu_gscl3", "none", GATE_IP_GSCL, 10, 0, 0),
++      GATE(camif_top, "camif_top", "aclk266", GATE_IP_GSCL, 4, 0, 0),
++      GATE(smmu_fimc_lite0, "smmu_fimc_lite0", "none",
++                                              GATE_IP_GSCL, 12, 0, 0),
++      GATE(smmu_fimc_lite1, "smmu_fimc_lite1", "none",
++                                              GATE_IP_GSCL, 13, 0, 0),
++      GATE(smmu_fimc_lite2, "smmu_fimc_lite2", "none",
++                                              GATE_IP_GSCL, 14, 0, 0),
+       GATE(mfc, "mfc", "aclk333", GATE_IP_MFC, 0, 0, 0),
+-      GATE(smmu_mfcl, "smmu_mfcl", "aclk333", GATE_IP_MFC, 1, 0, 0),
+-      GATE(smmu_mfcr, "smmu_mfcr", "aclk333", GATE_IP_MFC, 2, 0, 0),
++      GATE(smmu_mfcr, "smmu_mfcr", "none", GATE_IP_MFC, 1, 0, 0),
++      GATE(smmu_mfcl, "smmu_mfcl", "none", GATE_IP_MFC, 2, 0, 0),
+       GATE(rotator, "rotator", "aclk266", GATE_IP_GEN, 1, 0, 0),
+       GATE(jpeg, "jpeg", "aclk166", GATE_IP_GEN, 2, 0, 0),
+       GATE(mdma1, "mdma1", "aclk266", GATE_IP_GEN, 4, 0, 0),
+-      GATE(smmu_rotator, "smmu_rotator", "aclk266", GATE_IP_GEN, 6, 0, 0),
+-      GATE(smmu_jpeg, "smmu_jpeg", "aclk166", GATE_IP_GEN, 7, 0, 0),
+-      GATE(smmu_mdma1, "smmu_mdma1", "aclk266", GATE_IP_GEN, 9, 0, 0),
++      GATE(smmu_rotator, "smmu_rotator", "none", GATE_IP_GEN, 6, 0, 0),
++      GATE(smmu_jpeg, "smmu_jpeg", "none", GATE_IP_GEN, 7, 0, 0),
++      GATE(smmu_mdma1, "smmu_mdma1", "none", GATE_IP_GEN, 9, 0, 0),
+       GATE(pdma0, "pdma0", "aclk200", GATE_IP_FSYS, 1, 0, 0),
+       GATE(pdma1, "pdma1", "aclk200", GATE_IP_FSYS, 2, 0, 0),
+       GATE(sata, "sata", "aclk200", GATE_IP_FSYS, 6, 0, 0),
+@@ -462,6 +480,27 @@ struct samsung_gate_clock exynos5250_gate_clks[] __initdata = {
+       GATE(dp, "dp", "aclk200", GATE_IP_DISP1, 4, 0, 0),
+       GATE(mixer, "mixer", "aclk200", GATE_IP_DISP1, 5, 0, 0),
+       GATE(hdmi, "hdmi", "aclk200", GATE_IP_DISP1, 6, 0, 0),
++      GATE(smmu_tv, "smmu_tv", "none", GATE_IP_DISP1, 2, 0, 0),
++      GATE(smmu_fimd1, "smmu_fimd1", "none", GATE_IP_DISP1, 8, 0, 0),
++
++      GATE(smmu_fimc_isp, "smmu_fimc_isp", "none", GATE_IP_ISP0, 8, 0, 0),
++      GATE(smmu_fimc_drc, "smmu_fimc_drc", "none", GATE_IP_ISP0, 9, 0, 0),
++      GATE(smmu_fimc_fd, "smmu_fimc_fd", "none", GATE_IP_ISP0, 10, 0, 0),
++      GATE(smmu_fimc_scc, "smmu_fimc_scc", "none",
++                                                      GATE_IP_ISP0, 11, 0, 0),
++      GATE(smmu_fimc_scp, "smmu_fimc_scp", "none",
++                                                      GATE_IP_ISP0, 12, 0, 0),
++      GATE(smmu_fimc_mcuctl, "smmu_fimc_mcuctl", "none",
++                                                      GATE_IP_ISP0, 13, 0, 0),
++      GATE(smmu_fimc_odc, "smmu_fimc_odc", "none", GATE_IP_ISP1, 4, 0, 0),
++      GATE(smmu_fimc_dis0, "smmu_fimc_dis0", "none",
++                                                      GATE_IP_ISP1, 5, 0, 0),
++      GATE(smmu_fimc_dis1, "smmu_fimc_dis1", "none",
++                                                      GATE_IP_ISP1, 6, 0, 0),
++      GATE(smmu_fimc_3dnr, "smmu_fimc_3dnr", "none",
++                                                      GATE_IP_ISP1, 7, 0, 0),
++
++      GATE(smmu_2d, "smmu_2d", "none", GATE_IP_ACP, 7, 0, 0),
+ };
+ static __initdata struct of_device_id ext_clk_match[] = {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0020-ARM-dts-Add-description-of-System-MMU-of-Exynos-SoCs.patch b/patches.tizen/0020-ARM-dts-Add-description-of-System-MMU-of-Exynos-SoCs.patch
new file mode 100644 (file)
index 0000000..968f3e8
--- /dev/null
@@ -0,0 +1,738 @@
+From aedbf55d2d2ee9fc3f1b87608f4410882f89e456 Mon Sep 17 00:00:00 2001
+From: Cho KyongHo <pullip.cho@samsung.com>
+Date: Fri, 26 Jul 2013 20:28:19 +0900
+Subject: [PATCH 0020/1302] ARM: dts: Add description of System MMU of Exynos
+ SoCs
+
+Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../bindings/iommu/samsung,exynos4210-sysmmu.txt   | 103 ++++++++
+ arch/arm/boot/dts/exynos4.dtsi                     | 122 +++++++++
+ arch/arm/boot/dts/exynos4210.dtsi                  |  25 ++
+ arch/arm/boot/dts/exynos4x12.dtsi                  |  76 ++++++
+ arch/arm/boot/dts/exynos5250.dtsi                  | 291 +++++++++++++++++++++
+ 5 files changed, 617 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/iommu/samsung,exynos4210-sysmmu.txt
+
+diff --git a/Documentation/devicetree/bindings/iommu/samsung,exynos4210-sysmmu.txt b/Documentation/devicetree/bindings/iommu/samsung,exynos4210-sysmmu.txt
+new file mode 100644
+index 0000000..92f0a33
+--- /dev/null
++++ b/Documentation/devicetree/bindings/iommu/samsung,exynos4210-sysmmu.txt
+@@ -0,0 +1,103 @@
++Samsung Exynos4210 IOMMU H/W, System MMU (System Memory Management Unit)
++
++Samsung's Exynos architecture contains System MMU that enables scattered
++physical memory chunks visible as a contiguous region to DMA-capable peripheral
++devices like MFC, FIMC, FIMD, GScaler, FIMC-IS and so forth.
++
++System MMU is a sort of IOMMU and support identical translation table format to
++ARMv7 translation tables with minimum set of page properties including access
++permissions, shareability and security protection. In addition, System MMU has
++another capabilities like L2 TLB or block-fetch buffers to minimize translation
++latency.
++
++A System MMU is dedicated to a single master peripheral device.  Thus, it is
++important to specify the correct System MMU in the device node of its master
++device. Whereas a System MMU is dedicated to a master device, the master device
++may have more than one System MMU.
++
++Required properties:
++- compatible: Should be "samsung,exynos4210-sysmmu"
++- reg: A tuple of base address and size of System MMU registers.
++- interrupt-parent: The phandle of the interrupt controller of System MMU
++- interrupts: A tuple of numbers that indicates the interrupt source.
++- clock-names: Should be "sysmmu" if the System MMU is needed to gate its clock.
++               Please refer to the following documents:
++             Documentation/devicetree/bindings/clock/clock-bindings.txt
++             Documentation/devicetree/bindings/clock/exynos4-clock.txt
++             Documentation/devicetree/bindings/clock/exynos5250-clock.txt
++             Optional "master" if the clock to the System MMU is gated by
++             another gate clock other than "sysmmu". The System MMU driver
++             sets "master" the parent of "sysmmu".
++             Exynos4 SoCs, there needs no "master" clocks.
++             Exynos5 SoCs, some System MMUs must have "master" clocks.
++- clocks: Required if the System MMU is needed to gate its clock.
++        Please refer to the documents listed above.
++- samsung,power-domain: Required if the System MMU is needed to gate its power.
++        Please refer to the following document:
++        Documentation/devicetree/bindings/arm/exynos/power_domain.txt
++
++Required properties for the master peripheral devices:
++- iommu: phandles to the System MMUs of the device
++
++Examples:
++A System MMU is dedicated to a single master device.
++      gsc_0:  gsc@0x13e00000 {
++              compatible = "samsung,exynos5-gsc";
++              reg = <0x13e00000 0x1000>;
++              interrupts = <0 85 0>;
++              samsung,power-domain = <&pd_gsc>;
++              clocks = <&clock 256>;
++              clock-names = "gscl";
++              iommu = <&sysmmu_gsc1>;
++      };
++
++      sysmmu_gsc0: sysmmu@13E80000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x13E80000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-gsc0";
++              interrupts = <2 0>;
++              clock-names = "sysmmu", "master";
++              clocks = <&clock 262>, <&clock 256>;
++              samsung,power-domain = <&pd_gsc>;
++              status = "ok";
++      };
++
++MFC has 2 System MMUs for each port that MFC is attached. Thus it seems natural
++to define 2 System MMUs for each port of the MFC:
++
++      mfc: codec@13400000 {
++              compatible = "samsung,mfc-v5";
++              reg = <0x13400000 0x10000>;
++              interrupts = <0 94 0>;
++              samsung,power-domain = <&pd_mfc>;
++              clocks = <&clock 170>, <&clock 273>;
++              clock-names = "sclk_mfc", "mfc";
++              status = "ok";
++              iommu = <&sysmmu_mfc_l>, <&sysmmu_mfc_r>;
++      };
++
++      sysmmu_mfc_l: sysmmu@13620000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x13620000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-mfc-l";
++              interrupts = <5 5>;
++              clock-names = "sysmmu";
++              clocks = <&clock 274>;
++              samsung,power-domain = <&pd_mfc>;
++              status = "ok";
++      };
++
++      sysmmu_mfc_r: sysmmu@13630000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x13630000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-mfc-r";
++              interrupts = <5 6>;
++              clock-names = "sysmmu";
++              clocks = <&clock 275>;
++              samsung,power-domain = <&pd_mfc>;
++              status = "ok";
++      };
++
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index 5f57f59..77ac4af 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -167,6 +167,7 @@
+               interrupts = <0 94 0>;
+               samsung,power-domain = <&pd_mfc>;
+               status = "disabled";
++              iommu = <&sysmmu_mfc_l>, <&sysmmu_mfc_r>;
+       };
+       serial@13800000 {
+@@ -408,5 +409,126 @@
+               clock-names = "sclk_fimd", "fimd";
+               samsung,power-domain = <&pd_lcd0>;
+               status = "disabled";
++              iommu = <&sysmmu_fimd0>;
++      };
++
++      sysmmu_mfc_l: sysmmu@13620000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x13620000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-mfc-l";
++              interrupts = <5 5>;
++              clock-names = "sysmmu";
++              clocks = <&clock 274>;
++              samsung,power-domain = <&pd_mfc>;
++              status = "ok";
++      };
++
++      sysmmu_mfc_r: sysmmu@13630000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x13630000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-mfc-r";
++              interrupts = <5 6>;
++              clock-names = "sysmmu";
++              clocks = <&clock 275>;
++              samsung,power-domain = <&pd_mfc>;
++              status = "ok";
++      };
++
++      sysmmu_tv: sysmmu@13E20000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x13E20000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-tv";
++              interrupts = <5 4>;
++              clock-names = "sysmmu";
++              clocks = <&clock 272>;
++              samsung,power-domain = <&pd_tv>;
++              status = "ok";
++      };
++
++      sysmmu_fimc0: sysmmu@11A20000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x11A20000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-fimc0";
++              interrupts = <4 2>;
++              clock-names = "sysmmu";
++              clocks = <&clock 263>;
++              samsung,power-domain = <&pd_cam>;
++              status = "ok";
++      };
++
++      sysmmu_fimc1: sysmmu@11A30000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x11A30000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-fimc1";
++              interrupts = <4 3>;
++              clock-names = "sysmmu";
++              clocks = <&clock 264>;
++              samsung,power-domain = <&pd_cam>;
++              status = "ok";
++      };
++
++      sysmmu_fimc2: sysmmu@11A40000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x11A40000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-fimc2";
++              interrupts = <4 4>;
++              clock-names = "sysmmu";
++              clocks = <&clock 265>;
++              samsung,power-domain = <&pd_cam>;
++              status = "ok";
++      };
++
++      sysmmu_fimc3: sysmmu@11A50000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x11A50000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-fimc3";
++              interrupts = <4 5>;
++              clock-names = "sysmmu";
++              clocks = <&clock 266>;
++              samsung,power-domain = <&pd_cam>;
++              status = "ok";
++      };
++
++      sysmmu_jpeg: sysmmu@11A60000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x11A60000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-jpeg";
++              interrupts = <4 6>;
++              clock-names = "sysmmu";
++              clocks = <&clock 267>;
++              samsung,power-domain = <&pd_cam>;
++              status = "ok";
++      };
++
++      sysmmu_rotator: sysmmu@12A30000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x12A30000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-rotator";
++              interrupts = <5 0>;
++              clock-names = "sysmmu";
++              clocks = <&clock 281>;
++              samsung,power-domain = <&pd_lcd0>;
++              status = "ok";
++      };
++
++      sysmmu_fimd0: sysmmu@11E20000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x11E20000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-fimd0";
++              interrupts = <5 2>;
++              clock-names = "sysmmu";
++              clocks = <&clock 287>;
++              samsung,power-domain = <&pd_lcd0>;
++              status = "ok";
+       };
+ };
+diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
+index ef707bd..7ab619e 100644
+--- a/arch/arm/boot/dts/exynos4210.dtsi
++++ b/arch/arm/boot/dts/exynos4210.dtsi
+@@ -123,5 +123,30 @@
+               reg = <0x12800000 0x1000>;
+               interrupts = <0 89 0>;
+               status = "disabled";
++              iommu = <&sysmmu_g2d>;
++      };
++
++      sysmmu_g2d: sysmmu@12A20000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x12A20000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-g2d";
++              interrupts = <4 7>;
++              clock-names = "sysmmu";
++              clocks = <&clock 280>;
++              samsung,power-domain = <&pd_lcd0>;
++              status = "ok";
++      };
++
++      sysmmu_fimd1: sysmmu@12220000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-fimd1";
++              reg = <0x12220000 0x1000>;
++              interrupts = <5 3>;
++              clock-names = "sysmmu";
++              clocks = <&clock 291>;
++              samsung,power-domain = <&pd_lcd1>;
++              status = "ok";
+       };
+ };
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index 4afda47..3bf2d09 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -83,4 +83,80 @@
+               interrupts = <0 89 0>;
+               status = "disabled";
+       };
++
++      sysmmu_g2d: sysmmu@10A40000{
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x10A40000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-g2d";
++              interrupts = <4 7>;
++              clock-names = "sysmmu";
++              status = "ok";
++      };
++
++      sysmmu_fimc_isp: sysmmu@12260000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x12260000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-fimc_isp";
++              interrupts = <16 2>;
++              clock-names = "sysmmu";
++              clocks = <&clock 362>;
++              status = "ok";
++      };
++
++      sysmmu_fimc_drc: sysmmu@12270000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x12270000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-fimc_drc";
++              interrupts = <16 3>;
++              clock-names = "sysmmu";
++              clocks = <&clock 363>;
++              status = "ok";
++      };
++
++      sysmmu_fimc_fd: sysmmu@122A0000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x122A0000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-fimc_fd";
++              interrupts = <16 4>;
++              clock-names = "sysmmu";
++              clocks = <&clock 364>;
++              status = "ok";
++      };
++
++      sysmmu_fimc_mcuctl: sysmmu@122B0000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x122B0000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-fimc_mcuctl";
++              interrupts = <16 5>;
++              clock-names = "sysmmu";
++              clocks = <&clock 376>;
++              status = "ok";
++      };
++
++      sysmmu_fimc_lite0: sysmmu@123B0000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x123B0000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-fimc_lite0";
++              interrupts = <16 0>;
++              clock-names = "sysmmu";
++              clocks = <&clock 366>;
++              status = "ok";
++      };
++
++      sysmmu_fimc_lite1: sysmmu@123C0000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x123C0000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-fimc_lite1";
++              interrupts = <16 1>;
++              clock-names = "sysmmu";
++              clocks = <&clock 365>;
++              status = "ok";
++      };
+ };
+diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
+index fc9fb3d..130d23d 100644
+--- a/arch/arm/boot/dts/exynos5250.dtsi
++++ b/arch/arm/boot/dts/exynos5250.dtsi
+@@ -66,6 +66,16 @@
+               reg = <0x10044040 0x20>;
+       };
++      pd_isp: mfc-power-domain@0x10044020 {
++              compatible = "samsung,exynos4210-pd";
++              reg = <0x10044020 0x20>;
++      };
++
++      pd_disp1: mfc-power-domain@0x100440A0 {
++              compatible = "samsung,exynos4210-pd";
++              reg = <0x100440A0 0x20>;
++      };
++
+       clock: clock-controller@0x10010000 {
+               compatible = "samsung,exynos5250-clock";
+               reg = <0x10010000 0x30000>;
+@@ -180,6 +190,7 @@
+               reg = <0x11000000 0x10000>;
+               interrupts = <0 96 0>;
+               samsung,power-domain = <&pd_mfc>;
++              iommu = <&sysmmu_mfc_l &sysmmu_mfc_l>;
+       };
+       rtc {
+@@ -571,6 +582,7 @@
+               samsung,power-domain = <&pd_gsc>;
+               clocks = <&clock 256>;
+               clock-names = "gscl";
++              iommu = <&sysmmu_gsc1>;
+       };
+       gsc_1:  gsc@0x13e10000 {
+@@ -580,6 +592,7 @@
+               samsung,power-domain = <&pd_gsc>;
+               clocks = <&clock 257>;
+               clock-names = "gscl";
++              iommu = <&sysmmu_gsc1>;
+       };
+       gsc_2:  gsc@0x13e20000 {
+@@ -589,6 +602,7 @@
+               samsung,power-domain = <&pd_gsc>;
+               clocks = <&clock 258>;
+               clock-names = "gscl";
++              iommu = <&sysmmu_gsc2>;
+       };
+       gsc_3:  gsc@0x13e30000 {
+@@ -598,6 +612,7 @@
+               samsung,power-domain = <&pd_gsc>;
+               clocks = <&clock 259>;
+               clock-names = "gscl";
++              iommu = <&sysmmu_gsc3>;
+       };
+       hdmi {
+@@ -614,6 +629,7 @@
+               compatible = "samsung,exynos5-mixer";
+               reg = <0x14450000 0x10000>;
+               interrupts = <0 94 0>;
++              iommu = <&sysmmu_tv>;
+       };
+       dp-controller {
+@@ -638,5 +654,280 @@
+               interrupts = <18 4>, <18 5>, <18 6>;
+               clocks = <&clock 133>, <&clock 339>;
+               clock-names = "sclk_fimd", "fimd";
++              iommu = <&sysmmu_fimd1>;
++      };
++
++      sysmmu_mfc_l: sysmmu@11210000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x11210000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-mfc_l";
++              interrupts = <8 5>;
++              clock-names = "sysmmu", "master";
++              clocks = <&clock 267>, <&clock 266>;
++              samsung,power-domain = <&pd_mfc>;
++              status = "ok";
++      };
++
++      sysmmu_mfc_r: sysmmu@11200000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x11200000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-mfc_r";
++              interrupts = <6 2>;
++              clock-names = "sysmmu", "master";
++              clocks = <&clock 268>, <&clock 266>;
++              samsung,power-domain = <&pd_mfc>;
++              status = "ok";
++      };
++
++      sysmmu_tv: sysmmu@14650000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x14650000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-tv";
++              interrupts = <7 4>;
++              clock-names = "sysmmu";
++              clocks = <&clock 349>;
++              samsung,power-domain = <&pd_disp1>;
++              status = "ok";
++      };
++
++      sysmmu_gsc0: sysmmu@13E80000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x13E80000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-gsc0";
++              interrupts = <2 0>;
++              clock-names = "sysmmu", "master";
++              clocks = <&clock 262>, <&clock 256>;
++              samsung,power-domain = <&pd_gsc>;
++              status = "ok";
++      };
++
++      sysmmu_gsc1: sysmmu@13E90000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x13E90000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-gsc1";
++              interrupts = <2 2>;
++              clock-names = "sysmmu", "master";
++              clocks = <&clock 263>, <&clock 257>;
++              samsung,power-domain = <&pd_gsc>;
++              status = "ok";
++      };
++
++      sysmmu_gsc2: sysmmu@13EA0000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x13EA0000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-gsc2";
++              interrupts = <2 4>;
++              clock-names = "sysmmu", "master";
++              clocks = <&clock 264>, <&clock 258>;
++              samsung,power-domain = <&pd_gsc>;
++              status = "ok";
++      };
++
++      sysmmu_gsc3: sysmmu@13EB0000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x13EB0000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-gsc3";
++              interrupts = <2 6>;
++              clock-names = "sysmmu", "master";
++              clocks = <&clock 265>, <&clock 259>;
++              samsung,power-domain = <&pd_gsc>;
++              status = "ok";
++      };
++
++      sysmmu_fimd1: sysmmu@14640000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x14640000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-fimd1";
++              interrupts = <3 2>;
++              clock-names = "sysmmu";
++              clocks = <&clock 350>;
++              samsung,power-domain = <&pd_disp1>;
++              status = "ok";
++      };
++
++      sysmmu_rotator: sysmmu@11D40000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x11D40000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-rotator";
++              interrupts = <4 0>;
++              clock-names = "sysmmu";
++              clocks = <&clock 272>;
++              status = "ok";
++      };
++
++      sysmmu_fimc_isp: sysmmu@13260000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x13260000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-fimc_isp";
++              interrupts = <10 6>;
++              clock-names = "sysmmu";
++              clocks = <&clock 361>;
++              samsung,power-domain = <&pd_isp>;
++              status = "ok";
++      };
++
++      sysmmu_fimc_drc: sysmmu@13270000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x13270000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-fimc_drc";
++              interrupts = <11 6>;
++              clock-names = "sysmmu";
++              clocks = <&clock 362>;
++              samsung,power-domain = <&pd_isp>;
++              status = "ok";
++      };
++
++      sysmmu_fimc_fd: sysmmu@132A0000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x132A0000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-fimc_fd";
++              interrupts = <5 0>;
++              clock-names = "sysmmu";
++              clocks = <&clock 363>;
++              samsung,power-domain = <&pd_isp>;
++              status = "ok";
++      };
++
++      sysmmu_fimc_scc: sysmmu@13280000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x13280000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-fimc_scalerc";
++              interrupts = <5 2>;
++              clock-names = "sysmmu";
++              clocks = <&clock 364>;
++              samsung,power-domain = <&pd_isp>;
++              status = "ok";
++      };
++
++      sysmmu_fimc_scp: sysmmu@13290000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x13290000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-fimc_scalerp";
++              interrupts = <3 6>;
++              clock-names = "sysmmu";
++              clocks = <&clock 365>;
++              samsung,power-domain = <&pd_isp>;
++              status = "ok";
++      };
++
++      sysmmu_fimc_mcuctl: sysmmu@132B0000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x132B0000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-fimc_mcuctl";
++              interrupts = <5 4>;
++              clock-names = "sysmmu";
++              clocks = <&clock 366>;
++              samsung,power-domain = <&pd_isp>;
++              status = "ok";
++      };
++
++      sysmmu_fimc_odc: sysmmu@132C0000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x132C0000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-fimc_odc";
++              interrupts = <11 0>;
++              clock-names = "sysmmu";
++              clocks = <&clock 367>;
++              samsung,power-domain = <&pd_isp>;
++              status = "ok";
++      };
++
++      sysmmu_fimc_dis0: sysmmu@132D0000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x132D0000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-fimc_dis0";
++              interrupts = <10 4>;
++              clock-names = "sysmmu";
++              clocks = <&clock 368>;
++              samsung,power-domain = <&pd_isp>;
++              status = "ok";
++      };
++
++      sysmmu_fimc_dis1: sysmmu@132E0000{
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x132E0000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-fimc_dis1";
++              interrupts = <9 4>;
++              clock-names = "sysmmu";
++              clocks = <&clock 369>;
++              samsung,power-domain = <&pd_isp>;
++              status = "ok";
++      };
++
++      sysmmu_fimc_3dnr: sysmmu@132F0000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x132F0000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-fimc_3dnr";
++              interrupts = <5 6>;
++              clock-names = "sysmmu";
++              clocks = <&clock 370>;
++              samsung,power-domain = <&pd_isp>;
++              status = "ok";
++      };
++
++      sysmmu_fimc_lite0: sysmmu@13C40000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x13C40000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-fimc_lite0";
++              interrupts = <3 4>;
++              clock-names = "sysmmu", "master";
++              clocks = <&clock 346>, <&clock 345>;
++              samsung,power-domain = <&pd_gsc>;
++              status = "ok";
++      };
++
++      sysmmu_fimc_lite1: sysmmu@13C50000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x13C50000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-fimc_lite1";
++              interrupts = <24 1>;
++              clock-names = "sysmmu", "master";
++              clocks = <&clock 347>, <&clock 345>;
++              samsung,power-domain = <&pd_gsc>;
++              status = "ok";
++      };
++
++      sysmmu_fimc_jpeg: sysmmu@11F20000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x11F20000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-jpeg";
++              interrupts = <4 2>;
++              clock-names = "sysmmu", "master";
++              clocks = <&clock 273>, <&clock 270>;
++              samsung,power-domain = <&pd_gsc>;
++              status = "ok";
++      };
++
++      sysmmu_fimc_2d: sysmmu@10A60000 {
++              compatible = "samsung,exynos4210-sysmmu";
++              reg = <0x10A60000 0x1000>;
++              interrupt-parent = <&combiner>;
++              interrupt-names = "sysmmu-2d";
++              interrupts = <24 5>;
++              clock-names = "sysmmu";
++              clocks = <&clock 361>;
++              status = "ok";
+       };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0021-iommu-exynos-support-for-device-tree.patch b/patches.tizen/0021-iommu-exynos-support-for-device-tree.patch
new file mode 100644 (file)
index 0000000..bccd0ca
--- /dev/null
@@ -0,0 +1,371 @@
+From 04b137b2e5937b599851436409535c65971d0538 Mon Sep 17 00:00:00 2001
+From: Cho KyongHo <pullip.cho@samsung.com>
+Date: Fri, 26 Jul 2013 20:28:36 +0900
+Subject: [PATCH 0021/1302] iommu/exynos: support for device tree
+
+This commit adds device tree support for System MMU.
+This also include the following changes and enhancements:
+
+* use managed device helper functions.
+Simplyfies System MMU device driver.
+
+* use only a single clock descriptor.
+System MMU device descriptor is seperate if it is imposible to make
+a single clock descriptor to make a device descriptor for a group of
+System MMUs.
+
+* removed dbgname member from sysmmu_drvdata structure.
+debugging kernel message for a System MMU is distinguisheable with the
+name of device descroptors.
+
+Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iommu/Kconfig        |   5 +-
+ drivers/iommu/exynos-iommu.c | 182 ++++++++++++++++---------------------------
+ 2 files changed, 70 insertions(+), 117 deletions(-)
+
+diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
+index c332fb9..d45f3c9 100644
+--- a/drivers/iommu/Kconfig
++++ b/drivers/iommu/Kconfig
+@@ -168,16 +168,15 @@ config TEGRA_IOMMU_SMMU
+ config EXYNOS_IOMMU
+       bool "Exynos IOMMU Support"
+-      depends on ARCH_EXYNOS && EXYNOS_DEV_SYSMMU
++      depends on ARCH_EXYNOS
+       select IOMMU_API
++      default n
+       help
+         Support for the IOMMU(System MMU) of Samsung Exynos application
+         processor family. This enables H/W multimedia accellerators to see
+         non-linear physical memory chunks as a linear memory in their
+         address spaces
+-        If unsure, say N here.
+-
+ config EXYNOS_IOMMU_DEBUG
+       bool "Debugging log for Exynos IOMMU"
+       depends on EXYNOS_IOMMU
+diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
+index 093eea5..cfc02ed 100644
+--- a/drivers/iommu/exynos-iommu.c
++++ b/drivers/iommu/exynos-iommu.c
+@@ -26,6 +26,7 @@
+ #include <linux/list.h>
+ #include <linux/memblock.h>
+ #include <linux/export.h>
++#include <linux/of.h>
+ #include <asm/cacheflush.h>
+ #include <asm/pgtable.h>
+@@ -170,15 +171,14 @@ struct sysmmu_drvdata {
+       struct list_head node; /* entry of exynos_iommu_domain.clients */
+       struct device *sysmmu;  /* System MMU's device descriptor */
+       struct device *dev;     /* Owner of system MMU */
+-      char *dbgname;
+       int nsfrs;
+-      void __iomem **sfrbases;
+-      struct clk *clk[2];
++      struct clk *clk;
+       int activations;
+       rwlock_t lock;
+       struct iommu_domain *domain;
+       sysmmu_fault_handler_t fault_handler;
+       unsigned long pgtable;
++      void __iomem *sfrbases[0];
+ };
+ static bool set_sysmmu_active(struct sysmmu_drvdata *data)
+@@ -385,8 +385,8 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
+       if (!ret && (itype != SYSMMU_FAULT_UNKNOWN))
+               __raw_writel(1 << itype, data->sfrbases[i] + REG_INT_CLEAR);
+       else
+-              dev_dbg(data->sysmmu, "(%s) %s is not handled.\n",
+-                              data->dbgname, sysmmu_fault_name[itype]);
++              dev_dbg(data->sysmmu, "%s is not handled.\n",
++                              sysmmu_fault_name[itype]);
+       if (itype != SYSMMU_FAULT_UNKNOWN)
+               sysmmu_unblock(data->sfrbases[i]);
+@@ -410,10 +410,8 @@ static bool __exynos_sysmmu_disable(struct sysmmu_drvdata *data)
+       for (i = 0; i < data->nsfrs; i++)
+               __raw_writel(CTRL_DISABLE, data->sfrbases[i] + REG_MMU_CTRL);
+-      if (data->clk[1])
+-              clk_disable(data->clk[1]);
+-      if (data->clk[0])
+-              clk_disable(data->clk[0]);
++      if (data->clk)
++              clk_disable(data->clk);
+       disabled = true;
+       data->pgtable = 0;
+@@ -422,10 +420,10 @@ finish:
+       write_unlock_irqrestore(&data->lock, flags);
+       if (disabled)
+-              dev_dbg(data->sysmmu, "(%s) Disabled\n", data->dbgname);
++              dev_dbg(data->sysmmu, "Disabled\n");
+       else
+-              dev_dbg(data->sysmmu, "(%s) %d times left to be disabled\n",
+-                                      data->dbgname, data->activations);
++              dev_dbg(data->sysmmu, "%d times left to be disabled\n",
++                                      data->activations);
+       return disabled;
+ }
+@@ -452,14 +450,12 @@ static int __exynos_sysmmu_enable(struct sysmmu_drvdata *data,
+                       ret = 1;
+               }
+-              dev_dbg(data->sysmmu, "(%s) Already enabled\n", data->dbgname);
++              dev_dbg(data->sysmmu, "Already enabled\n");
+               goto finish;
+       }
+-      if (data->clk[0])
+-              clk_enable(data->clk[0]);
+-      if (data->clk[1])
+-              clk_enable(data->clk[1]);
++      if (data->clk)
++              clk_enable(data->clk);
+       data->pgtable = pgtable;
+@@ -479,7 +475,7 @@ static int __exynos_sysmmu_enable(struct sysmmu_drvdata *data,
+       data->domain = domain;
+-      dev_dbg(data->sysmmu, "(%s) Enabled\n", data->dbgname);
++      dev_dbg(data->sysmmu, "Enabled\n");
+ finish:
+       write_unlock_irqrestore(&data->lock, flags);
+@@ -495,7 +491,7 @@ int exynos_sysmmu_enable(struct device *dev, unsigned long pgtable)
+       ret = pm_runtime_get_sync(data->sysmmu);
+       if (ret < 0) {
+-              dev_dbg(data->sysmmu, "(%s) Failed to enable\n", data->dbgname);
++              dev_dbg(data->sysmmu, "Failed to enable\n");
+               return ret;
+       }
+@@ -503,8 +499,8 @@ int exynos_sysmmu_enable(struct device *dev, unsigned long pgtable)
+       if (WARN_ON(ret < 0)) {
+               pm_runtime_put(data->sysmmu);
+               dev_err(data->sysmmu,
+-                      "(%s) Already enabled with page table %#lx\n",
+-                      data->dbgname, data->pgtable);
++                      "Already enabled with page table %#lx\n",
++                      data->pgtable);
+       } else {
+               data->dev = dev;
+       }
+@@ -540,9 +536,7 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, unsigned long iova)
+                       }
+               }
+       } else {
+-              dev_dbg(data->sysmmu,
+-                      "(%s) Disabled. Skipping invalidating TLB.\n",
+-                      data->dbgname);
++              dev_dbg(data->sysmmu, "Disabled. Skipping invalidating TLB.\n");
+       }
+       read_unlock_irqrestore(&data->lock, flags);
+@@ -564,141 +558,101 @@ void exynos_sysmmu_tlb_invalidate(struct device *dev)
+                       }
+               }
+       } else {
+-              dev_dbg(data->sysmmu,
+-                      "(%s) Disabled. Skipping invalidating TLB.\n",
+-                      data->dbgname);
++              dev_dbg(data->sysmmu, "Disabled. Skipping invalidating TLB.\n");
+       }
+       read_unlock_irqrestore(&data->lock, flags);
+ }
+-static int exynos_sysmmu_probe(struct platform_device *pdev)
++static int __init exynos_sysmmu_probe(struct platform_device *pdev)
+ {
+       int i, ret;
+-      struct device *dev;
++      struct device *dev = &pdev->dev;
+       struct sysmmu_drvdata *data;
+-      dev = &pdev->dev;
+-
+-      data = kzalloc(sizeof(*data), GFP_KERNEL);
+-      if (!data) {
+-              dev_dbg(dev, "Not enough memory\n");
+-              ret = -ENOMEM;
+-              goto err_alloc;
++      if (pdev->num_resources == 0) {
++              dev_err(dev, "No System MMU resource defined\n");
++              return -ENODEV;
+       }
+-      ret = dev_set_drvdata(dev, data);
+-      if (ret) {
+-              dev_dbg(dev, "Unabled to initialize driver data\n");
+-              goto err_init;
++      data = devm_kzalloc(dev,
++                      sizeof(*data) +
++                      sizeof(*data->sfrbases) * (pdev->num_resources / 2),
++                      GFP_KERNEL);
++      if (!data) {
++              dev_err(dev, "Not enough memory for initialization\n");
++              return -ENOMEM;
+       }
+       data->nsfrs = pdev->num_resources / 2;
+-      data->sfrbases = kmalloc(sizeof(*data->sfrbases) * data->nsfrs,
+-                                                              GFP_KERNEL);
+-      if (data->sfrbases == NULL) {
+-              dev_dbg(dev, "Not enough memory\n");
+-              ret = -ENOMEM;
+-              goto err_init;
+-      }
+       for (i = 0; i < data->nsfrs; i++) {
+               struct resource *res;
++
+               res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+               if (!res) {
+-                      dev_dbg(dev, "Unable to find IOMEM region\n");
+-                      ret = -ENOENT;
+-                      goto err_res;
++                      dev_err(dev, "Unable to find IOMEM region\n");
++                      return -ENOENT;
+               }
+-              data->sfrbases[i] = ioremap(res->start, resource_size(res));
++              data->sfrbases[i] = devm_request_and_ioremap(dev, res);
+               if (!data->sfrbases[i]) {
+-                      dev_dbg(dev, "Unable to map IOMEM @ PA:%#x\n",
+-                                                      res->start);
+-                      ret = -ENOENT;
+-                      goto err_res;
++                      dev_err(dev, "Unable to map IOMEM @ %#x\n", res->start);
++                      return -EBUSY;
+               }
+       }
+       for (i = 0; i < data->nsfrs; i++) {
+-              ret = platform_get_irq(pdev, i);
+-              if (ret <= 0) {
+-                      dev_dbg(dev, "Unable to find IRQ resource\n");
+-                      goto err_irq;
++              int irq;
++
++              irq = platform_get_irq(pdev, i);
++              if (irq <= 0) {
++                      dev_err(dev, "Unable to find IRQ resource\n");
++                      return -ENOENT;
+               }
+-              ret = request_irq(ret, exynos_sysmmu_irq, 0,
+-                                      dev_name(dev), data);
++              ret = devm_request_irq(dev, irq, exynos_sysmmu_irq,
++                                      0, dev_name(dev), data);
+               if (ret) {
+-                      dev_dbg(dev, "Unabled to register interrupt handler\n");
+-                      goto err_irq;
++                      dev_err(dev, "Unable to register handler to irq %d\n",
++                              irq);
++                      return ret;
+               }
+       }
+-      if (dev_get_platdata(dev)) {
+-              char *deli, *beg;
+-              struct sysmmu_platform_data *platdata = dev_get_platdata(dev);
+-
+-              beg = platdata->clockname;
+-
+-              for (deli = beg; (*deli != '\0') && (*deli != ','); deli++)
+-                      /* NOTHING */;
+-
+-              if (*deli == '\0')
+-                      deli = NULL;
+-              else
+-                      *deli = '\0';
+-
+-              data->clk[0] = clk_get(dev, beg);
+-              if (IS_ERR(data->clk[0])) {
+-                      data->clk[0] = NULL;
+-                      dev_dbg(dev, "No clock descriptor registered\n");
+-              }
++      pm_runtime_enable(dev);
+-              if (data->clk[0] && deli) {
+-                      *deli = ',';
+-                      data->clk[1] = clk_get(dev, deli + 1);
+-                      if (IS_ERR(data->clk[1]))
+-                              data->clk[1] = NULL;
+-              }
++      __set_fault_handler(data, &default_fault_handler);
+-              data->dbgname = platdata->dbgname;
++      data->sysmmu = dev;
++      data->clk = devm_clk_get(dev, "sysmmu");
++      if (IS_ERR(data->clk)) {
++              dev_info(dev, "No gate clock found!\n");
++              data->clk = NULL;
+       }
+-      data->sysmmu = dev;
+       rwlock_init(&data->lock);
+       INIT_LIST_HEAD(&data->node);
+-      __set_fault_handler(data, &default_fault_handler);
+-
+-      if (dev->parent)
+-              pm_runtime_enable(dev);
++      platform_set_drvdata(pdev, data);
++      dev_dbg(dev, "Probed and initialized\n");
+-      dev_dbg(dev, "(%s) Initialized\n", data->dbgname);
+-      return 0;
+-err_irq:
+-      while (i-- > 0) {
+-              int irq;
+-
+-              irq = platform_get_irq(pdev, i);
+-              free_irq(irq, data);
+-      }
+-err_res:
+-      while (data->nsfrs-- > 0)
+-              iounmap(data->sfrbases[data->nsfrs]);
+-      kfree(data->sfrbases);
+-err_init:
+-      kfree(data);
+-err_alloc:
+-      dev_err(dev, "Failed to initialize\n");
+       return ret;
+ }
+-static struct platform_driver exynos_sysmmu_driver = {
+-      .probe          = exynos_sysmmu_probe,
+-      .driver         = {
++#ifdef CONFIG_OF
++static struct of_device_id sysmmu_of_match[] __initconst = {
++      { .compatible   = "samsung,exynos4210-sysmmu", },
++      { },
++};
++#endif
++
++static struct platform_driver exynos_sysmmu_driver __refdata = {
++      .probe  = exynos_sysmmu_probe,
++      .driver = {
+               .owner          = THIS_MODULE,
+               .name           = "exynos-sysmmu",
++              .of_match_table = of_match_ptr(sysmmu_of_match),
+       }
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0022-iommu-exynos-remove-prefetch-buffer-setting-when-ena.patch b/patches.tizen/0022-iommu-exynos-remove-prefetch-buffer-setting-when-ena.patch
new file mode 100644 (file)
index 0000000..f2a6b1a
--- /dev/null
@@ -0,0 +1,88 @@
+From 502cdfe01e48640471d866215e432f0a7f67544e Mon Sep 17 00:00:00 2001
+From: Cho KyongHo <pullip.cho@samsung.com>
+Date: Fri, 26 Jul 2013 20:28:49 +0900
+Subject: [PATCH 0022/1302] iommu/exynos: remove prefetch buffer setting when
+ enabling System MMU
+
+Prefetch buffer must be handled accurately, exact range of a buffer,
+frame by frame manually. Otherwise, it may causes page fault or
+deadlock in System MMU.
+Thus this patch removes prefetch buffer setting when System MMU is
+initialized(enabled).
+
+Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iommu/exynos-iommu.c | 32 +++++++++++++++++++++++++++-----
+ 1 file changed, 27 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
+index cfc02ed..87f6bb7 100644
+--- a/drivers/iommu/exynos-iommu.c
++++ b/drivers/iommu/exynos-iommu.c
+@@ -80,6 +80,8 @@
+ #define CTRL_BLOCK    0x7
+ #define CTRL_DISABLE  0x0
++#define CFG_FLPDCACHE (1 << 20) /* System MMU 3.2+ only */
++
+ #define REG_MMU_CTRL          0x000
+ #define REG_MMU_CFG           0x004
+ #define REG_MMU_STATUS                0x008
+@@ -96,6 +98,9 @@
+ #define REG_MMU_VERSION               0x034
++#define MMU_MAJ_VER(reg)      (reg >> 28)
++#define MMU_MIN_VER(reg)      ((reg >> 21) & 0x7F)
++
+ #define REG_PB0_SADDR         0x04C
+ #define REG_PB0_EADDR         0x050
+ #define REG_PB1_SADDR         0x054
+@@ -200,6 +205,22 @@ static bool is_sysmmu_active(struct sysmmu_drvdata *data)
+       return data->activations > 0;
+ }
++static unsigned int __sysmmu_version(struct sysmmu_drvdata *data,
++                                   int idx, unsigned int *minor)
++{
++      unsigned long major;
++
++      major = readl(data->sfrbases[idx] + REG_MMU_VERSION);
++
++      if (minor)
++              *minor = MMU_MIN_VER(major);
++
++      if (MMU_MAJ_VER(major) > 3)
++              return 1;
++
++      return MMU_MAJ_VER(major);
++}
++
+ static void sysmmu_unblock(void __iomem *sfrbase)
+ {
+       __raw_writel(CTRL_ENABLE, sfrbase + REG_MMU_CTRL);
+@@ -460,14 +481,15 @@ static int __exynos_sysmmu_enable(struct sysmmu_drvdata *data,
+       data->pgtable = pgtable;
+       for (i = 0; i < data->nsfrs; i++) {
++              unsigned int min;
++
+               __sysmmu_set_ptbase(data->sfrbases[i], pgtable);
+-              if ((readl(data->sfrbases[i] + REG_MMU_VERSION) >> 28) == 3) {
+-                      /* System MMU version is 3.x */
+-                      __raw_writel((1 << 12) | (2 << 28),
++              if ((__sysmmu_version(data, i, &min) == 3) && (min > 1)) {
++                      unsigned long cfg;
++                      cfg = __raw_readl(data->sfrbases[i] + REG_MMU_CFG);
++                      __raw_writel(cfg | CFG_FLPDCACHE,
+                                       data->sfrbases[i] + REG_MMU_CFG);
+-                      __sysmmu_set_prefbuf(data->sfrbases[i], 0, -1, 0);
+-                      __sysmmu_set_prefbuf(data->sfrbases[i], 0, -1, 1);
+               }
+               __raw_writel(CTRL_ENABLE, data->sfrbases[i] + REG_MMU_CTRL);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0023-iommu-exynos-remove-custom-fault-handler.patch b/patches.tizen/0023-iommu-exynos-remove-custom-fault-handler.patch
new file mode 100644 (file)
index 0000000..cd90d3e
--- /dev/null
@@ -0,0 +1,160 @@
+From 4cd7a209da2bf86ed038833232f757990828c0f7 Mon Sep 17 00:00:00 2001
+From: Cho KyongHo <pullip.cho@samsung.com>
+Date: Fri, 26 Jul 2013 20:29:06 +0900
+Subject: [PATCH 0023/1302] iommu/exynos: remove custom fault handler
+
+This commit removes custom fault handler. The device drivers that
+need to register fault handler can register
+with iommu_set_fault_handler().
+
+Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iommu/exynos-iommu.c | 71 +++++++++++---------------------------------
+ 1 file changed, 17 insertions(+), 54 deletions(-)
+
+diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
+index 87f6bb7..f9853fe 100644
+--- a/drivers/iommu/exynos-iommu.c
++++ b/drivers/iommu/exynos-iommu.c
+@@ -131,16 +131,6 @@ enum exynos_sysmmu_inttype {
+       SYSMMU_FAULTS_NUM
+ };
+-/*
+- * @itype: type of fault.
+- * @pgtable_base: the physical address of page table base. This is 0 if @itype
+- *                is SYSMMU_BUSERROR.
+- * @fault_addr: the device (virtual) address that the System MMU tried to
+- *             translated. This is 0 if @itype is SYSMMU_BUSERROR.
+- */
+-typedef int (*sysmmu_fault_handler_t)(enum exynos_sysmmu_inttype itype,
+-                      unsigned long pgtable_base, unsigned long fault_addr);
+-
+ static unsigned short fault_reg_offset[SYSMMU_FAULTS_NUM] = {
+       REG_PAGE_FAULT_ADDR,
+       REG_AR_FAULT_ADDR,
+@@ -181,7 +171,6 @@ struct sysmmu_drvdata {
+       int activations;
+       rwlock_t lock;
+       struct iommu_domain *domain;
+-      sysmmu_fault_handler_t fault_handler;
+       unsigned long pgtable;
+       void __iomem *sfrbases[0];
+ };
+@@ -313,34 +302,17 @@ finish:
+       read_unlock_irqrestore(&data->lock, flags);
+ }
+-static void __set_fault_handler(struct sysmmu_drvdata *data,
+-                                      sysmmu_fault_handler_t handler)
+-{
+-      unsigned long flags;
+-
+-      write_lock_irqsave(&data->lock, flags);
+-      data->fault_handler = handler;
+-      write_unlock_irqrestore(&data->lock, flags);
+-}
+-
+-void exynos_sysmmu_set_fault_handler(struct device *dev,
+-                                      sysmmu_fault_handler_t handler)
+-{
+-      struct sysmmu_drvdata *data = dev_get_drvdata(dev->archdata.iommu);
+-
+-      __set_fault_handler(data, handler);
+-}
+-
+-static int default_fault_handler(enum exynos_sysmmu_inttype itype,
+-                   unsigned long pgtable_base, unsigned long fault_addr)
++static void show_fault_information(const char *name,
++              enum exynos_sysmmu_inttype itype,
++              unsigned long pgtable_base, unsigned long fault_addr)
+ {
+       unsigned long *ent;
+       if ((itype >= SYSMMU_FAULTS_NUM) || (itype < SYSMMU_PAGEFAULT))
+               itype = SYSMMU_FAULT_UNKNOWN;
+-      pr_err("%s occurred at 0x%lx(Page table base: 0x%lx)\n",
+-                      sysmmu_fault_name[itype], fault_addr, pgtable_base);
++      pr_err("%s occurred at 0x%lx by %s(Page table base: 0x%lx)\n",
++              sysmmu_fault_name[itype], fault_addr, name, pgtable_base);
+       ent = section_entry(__va(pgtable_base), fault_addr);
+       pr_err("\tLv1 entry: 0x%lx\n", *ent);
+@@ -353,16 +325,12 @@ static int default_fault_handler(enum exynos_sysmmu_inttype itype,
+       pr_err("Generating Kernel OOPS... because it is unrecoverable.\n");
+       BUG();
+-
+-      return 0;
+ }
+ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
+ {
+       /* SYSMMU is in blocked when interrupt occurred. */
+       struct sysmmu_drvdata *data = dev_id;
+-      struct resource *irqres;
+-      struct platform_device *pdev;
+       enum exynos_sysmmu_inttype itype;
+       unsigned long addr = -1;
+@@ -372,14 +340,15 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
+       WARN_ON(!is_sysmmu_active(data));
+-      pdev = to_platform_device(data->sysmmu);
+-      for (i = 0; i < (pdev->num_resources / 2); i++) {
+-              irqres = platform_get_resource(pdev, IORESOURCE_IRQ, i);
++      for (i = 0; i < data->nsfrs; i++) {
++              struct resource *irqres;
++              irqres = platform_get_resource(to_platform_device(data->sysmmu),
++                                              IORESOURCE_IRQ, i);
+               if (irqres && ((int)irqres->start == irq))
+                       break;
+       }
+-      if (i == pdev->num_resources) {
++      if (i == data->nsfrs) {
+               itype = SYSMMU_FAULT_UNKNOWN;
+       } else {
+               itype = (enum exynos_sysmmu_inttype)
+@@ -395,19 +364,15 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
+               ret = report_iommu_fault(data->domain, data->dev,
+                               addr, itype);
+-      if ((ret == -ENOSYS) && data->fault_handler) {
+-              unsigned long base = data->pgtable;
+-              if (itype != SYSMMU_FAULT_UNKNOWN)
+-                      base = __raw_readl(
+-                                      data->sfrbases[i] + REG_PT_BASE_ADDR);
+-              ret = data->fault_handler(itype, base, addr);
+-      }
+-
+       if (!ret && (itype != SYSMMU_FAULT_UNKNOWN))
+               __raw_writel(1 << itype, data->sfrbases[i] + REG_INT_CLEAR);
+-      else
+-              dev_dbg(data->sysmmu, "%s is not handled.\n",
+-                              sysmmu_fault_name[itype]);
++      else {
++              unsigned long ba = data->pgtable;
++              if (itype != SYSMMU_FAULT_UNKNOWN)
++                      ba = __raw_readl(data->sfrbases[i] + REG_PT_BASE_ADDR);
++              show_fault_information(dev_name(data->sysmmu),
++                                      itype, ba, addr);
++      }
+       if (itype != SYSMMU_FAULT_UNKNOWN)
+               sysmmu_unblock(data->sfrbases[i]);
+@@ -644,8 +609,6 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev)
+       pm_runtime_enable(dev);
+-      __set_fault_handler(data, &default_fault_handler);
+-
+       data->sysmmu = dev;
+       data->clk = devm_clk_get(dev, "sysmmu");
+       if (IS_ERR(data->clk)) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0024-iommu-exynos-add-bus-notifier-for-registering-System.patch b/patches.tizen/0024-iommu-exynos-add-bus-notifier-for-registering-System.patch
new file mode 100644 (file)
index 0000000..e4335de
--- /dev/null
@@ -0,0 +1,987 @@
+From 9f3387f3b3b2acc4042eb81e7f86123c4a308280 Mon Sep 17 00:00:00 2001
+From: Cho KyongHo <pullip.cho@samsung.com>
+Date: Fri, 26 Jul 2013 20:30:17 +0900
+Subject: [PATCH 0024/1302] iommu/exynos: add bus notifier for registering
+ System MMU
+
+When a device driver is registered, all constructs to handle System MMU
+is prepared by bus notifier call.
+
+Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iommu/exynos-iommu.c | 708 +++++++++++++++++++++++++++++++++----------
+ 1 file changed, 552 insertions(+), 156 deletions(-)
+
+diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
+index f9853fe..c62c244 100644
+--- a/drivers/iommu/exynos-iommu.c
++++ b/drivers/iommu/exynos-iommu.c
+@@ -27,6 +27,9 @@
+ #include <linux/memblock.h>
+ #include <linux/export.h>
+ #include <linux/of.h>
++#include <linux/of_platform.h>
++#include <linux/pm_domain.h>
++#include <linux/notifier.h>
+ #include <asm/cacheflush.h>
+ #include <asm/pgtable.h>
+@@ -80,7 +83,13 @@
+ #define CTRL_BLOCK    0x7
+ #define CTRL_DISABLE  0x0
++#define CFG_LRU               0x1
++#define CFG_QOS(n)    ((n & 0xF) << 7)
++#define CFG_MASK      0x0150FFFF /* Selecting bit 0-15, 20, 22 and 24 */
++#define CFG_ACGEN     (1 << 24) /* System MMU 3.3 only */
++#define CFG_SYSSEL    (1 << 22) /* System MMU 3.2 only */
+ #define CFG_FLPDCACHE (1 << 20) /* System MMU 3.2+ only */
++#define CFG_SHAREABLE (1 << 12) /* System MMU 3.x only */
+ #define REG_MMU_CTRL          0x000
+ #define REG_MMU_CFG           0x004
+@@ -154,6 +163,14 @@ static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
+       "UNKNOWN FAULT"
+ };
++struct exynos_iommu_client {
++      struct list_head node;  /* entry of exynos_iommu_domain.clients */
++      struct device *dev;
++      spinlock_t lock;
++      int num_sysmmu;
++      struct device *sysmmu[0];
++};
++
+ struct exynos_iommu_domain {
+       struct list_head clients; /* list of sysmmu_drvdata.node */
+       unsigned long *pgtable; /* lv1 page table, 16KB */
+@@ -165,12 +182,14 @@ struct exynos_iommu_domain {
+ struct sysmmu_drvdata {
+       struct list_head node; /* entry of exynos_iommu_domain.clients */
+       struct device *sysmmu;  /* System MMU's device descriptor */
+-      struct device *dev;     /* Owner of system MMU */
++      struct device *master;  /* Owner of system MMU */
+       int nsfrs;
+       struct clk *clk;
++      struct clk *clk_master;
+       int activations;
+       rwlock_t lock;
+       struct iommu_domain *domain;
++      bool runtime_active;
+       unsigned long pgtable;
+       void __iomem *sfrbases[0];
+ };
+@@ -245,7 +264,6 @@ static void __sysmmu_tlb_invalidate_entry(void __iomem *sfrbase,
+ static void __sysmmu_set_ptbase(void __iomem *sfrbase,
+                                      unsigned long pgd)
+ {
+-      __raw_writel(0x1, sfrbase + REG_MMU_CFG); /* 16KB LV1, LRU */
+       __raw_writel(pgd, sfrbase + REG_PT_BASE_ADDR);
+       __sysmmu_tlb_invalidate(sfrbase);
+@@ -273,6 +291,7 @@ void exynos_sysmmu_set_prefbuf(struct device *dev,
+       if (!is_sysmmu_active(data))
+               goto finish;
++      clk_enable(data->clk_master);
+       for (i = 0; i < data->nsfrs; i++) {
+               if ((readl(data->sfrbases[i] + REG_MMU_VERSION) >> 28) == 3) {
+                       if (!sysmmu_block(data->sfrbases[i]))
+@@ -298,6 +317,7 @@ void exynos_sysmmu_set_prefbuf(struct device *dev,
+                       sysmmu_unblock(data->sfrbases[i]);
+               }
+       }
++      clk_disable(data->clk_master);
+ finish:
+       read_unlock_irqrestore(&data->lock, flags);
+ }
+@@ -331,12 +351,13 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
+ {
+       /* SYSMMU is in blocked when interrupt occurred. */
+       struct sysmmu_drvdata *data = dev_id;
++      struct exynos_iommu_client *client = NULL;
+       enum exynos_sysmmu_inttype itype;
+       unsigned long addr = -1;
+-
+       int i, ret = -ENOSYS;
+-      read_lock(&data->lock);
++      if (data->master)
++              client = data->master->archdata.iommu;
+       WARN_ON(!is_sysmmu_active(data));
+@@ -348,6 +369,10 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
+                       break;
+       }
++      if (client)
++              spin_lock(&client->lock);
++      read_lock(&data->lock);
++
+       if (i == data->nsfrs) {
+               itype = SYSMMU_FAULT_UNKNOWN;
+       } else {
+@@ -361,7 +386,7 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
+       }
+       if (data->domain)
+-              ret = report_iommu_fault(data->domain, data->dev,
++              ret = report_iommu_fault(data->domain, data->master,
+                               addr, itype);
+       if (!ret && (itype != SYSMMU_FAULT_UNKNOWN))
+@@ -378,177 +403,251 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
+               sysmmu_unblock(data->sfrbases[i]);
+       read_unlock(&data->lock);
++      if (client)
++              spin_unlock(&client->lock);
+       return IRQ_HANDLED;
+ }
+-static bool __exynos_sysmmu_disable(struct sysmmu_drvdata *data)
++static void __sysmmu_disable_nocount(struct sysmmu_drvdata *data)
+ {
+-      unsigned long flags;
+-      bool disabled = false;
+       int i;
+-      write_lock_irqsave(&data->lock, flags);
++      clk_enable(data->clk_master);
++      for (i = 0; i < data->nsfrs; i++) {
++              __raw_writel(CTRL_DISABLE,
++                              data->sfrbases[i] + REG_MMU_CTRL);
++              __raw_writel(0, data->sfrbases[i] + REG_MMU_CFG);
++      }
+-      if (!set_sysmmu_inactive(data))
+-              goto finish;
++      clk_disable(data->clk);
++      clk_disable(data->clk_master);
++}
+-      for (i = 0; i < data->nsfrs; i++)
+-              __raw_writel(CTRL_DISABLE, data->sfrbases[i] + REG_MMU_CTRL);
++static bool __sysmmu_disable(struct sysmmu_drvdata *data)
++{
++      bool disabled;
++      unsigned long flags;
+-      if (data->clk)
+-              clk_disable(data->clk);
++      write_lock_irqsave(&data->lock, flags);
+-      disabled = true;
+-      data->pgtable = 0;
+-      data->domain = NULL;
+-finish:
+-      write_unlock_irqrestore(&data->lock, flags);
++      disabled = set_sysmmu_inactive(data);
++
++      if (disabled) {
++              data->pgtable = 0;
++              data->domain = NULL;
++
++              if (data->runtime_active)
++                      __sysmmu_disable_nocount(data);
+-      if (disabled)
+               dev_dbg(data->sysmmu, "Disabled\n");
+-      else
+-              dev_dbg(data->sysmmu, "%d times left to be disabled\n",
++      } else  {
++              dev_dbg(data->sysmmu, "%d times left to disable\n",
+                                       data->activations);
++      }
++
++      write_unlock_irqrestore(&data->lock, flags);
+       return disabled;
+ }
+-/* __exynos_sysmmu_enable: Enables System MMU
+- *
+- * returns -error if an error occurred and System MMU is not enabled,
+- * 0 if the System MMU has been just enabled and 1 if System MMU was already
+- * enabled before.
+- */
+-static int __exynos_sysmmu_enable(struct sysmmu_drvdata *data,
++
++static void __sysmmu_init_config(struct sysmmu_drvdata *data, int idx)
++{
++      unsigned long cfg = CFG_LRU | CFG_QOS(15);
++      int maj, min = 0;
++
++      maj = __sysmmu_version(data, idx, &min);
++      if (maj == 3) {
++              if (min > 1) {
++                      cfg |= CFG_FLPDCACHE;
++                      cfg |= (min == 2) ? CFG_SYSSEL : CFG_ACGEN;
++              }
++      }
++
++      __raw_writel(cfg, data->sfrbases[idx] + REG_MMU_CFG);
++}
++
++static void __sysmmu_enable_nocount(struct sysmmu_drvdata *data)
++{
++      int i;
++
++      clk_enable(data->clk_master);
++      clk_enable(data->clk);
++
++      for (i = 0; i < data->nsfrs; i++) {
++              __raw_writel(CTRL_BLOCK, data->sfrbases[i] + REG_MMU_CTRL);
++
++              __sysmmu_init_config(data, i);
++
++              __sysmmu_set_ptbase(data->sfrbases[i], data->pgtable);
++
++              __raw_writel(CTRL_ENABLE, data->sfrbases[i] + REG_MMU_CTRL);
++      }
++      clk_disable(data->clk_master);
++}
++
++static int __sysmmu_enable(struct sysmmu_drvdata *data,
+                       unsigned long pgtable, struct iommu_domain *domain)
+ {
+-      int i, ret = 0;
++      int ret = 0;
+       unsigned long flags;
+       write_lock_irqsave(&data->lock, flags);
++      if (set_sysmmu_active(data)) {
++              data->pgtable = pgtable;
++              data->domain = domain;
+-      if (!set_sysmmu_active(data)) {
+-              if (WARN_ON(pgtable != data->pgtable)) {
+-                      ret = -EBUSY;
+-                      set_sysmmu_inactive(data);
+-              } else {
+-                      ret = 1;
+-              }
++              if (data->runtime_active)
++                      __sysmmu_enable_nocount(data);
+-              dev_dbg(data->sysmmu, "Already enabled\n");
+-              goto finish;
++              dev_dbg(data->sysmmu, "Enabled\n");
++      } else {
++              ret = (pgtable == data->pgtable) ? 1 : -EBUSY;
++
++              dev_dbg(data->sysmmu, "already enabled\n");
+       }
+-      if (data->clk)
+-              clk_enable(data->clk);
++      if (WARN_ON(ret < 0))
++              set_sysmmu_inactive(data); /* decrement count */
+-      data->pgtable = pgtable;
++      write_unlock_irqrestore(&data->lock, flags);
+-      for (i = 0; i < data->nsfrs; i++) {
+-              unsigned int min;
++      return ret;
++}
+-              __sysmmu_set_ptbase(data->sfrbases[i], pgtable);
++/* __exynos_sysmmu_enable: Enables System MMU
++ *
++ * returns -error if an error occurred and System MMU is not enabled,
++ * 0 if the System MMU has been just enabled and 1 if System MMU was already
++ * enabled before.
++ */
++static int __exynos_sysmmu_enable(struct device *dev, unsigned long pgtable,
++                                struct iommu_domain *domain)
++{
++      int ret = 0;
++      unsigned long flags;
++      struct exynos_iommu_client *client = dev->archdata.iommu;
++      int i;
+-              if ((__sysmmu_version(data, i, &min) == 3) && (min > 1)) {
+-                      unsigned long cfg;
+-                      cfg = __raw_readl(data->sfrbases[i] + REG_MMU_CFG);
+-                      __raw_writel(cfg | CFG_FLPDCACHE,
+-                                      data->sfrbases[i] + REG_MMU_CFG);
+-              }
++      if (WARN_ON(!client))
++              return -ENODEV;
+-              __raw_writel(CTRL_ENABLE, data->sfrbases[i] + REG_MMU_CTRL);
+-      }
++      spin_lock_irqsave(&client->lock, flags);
+-      data->domain = domain;
++      for (i = 0; i < client->num_sysmmu; i++) {
++              struct sysmmu_drvdata *data =
++                              dev_get_drvdata(client->sysmmu[i]);
++              ret = __sysmmu_enable(data, pgtable, domain);
++              if (ret < 0) {
++                      int j;
++                      for (j = 0; j < i; j++)
++                              __sysmmu_disable(data);
++                      break;
++              } else {
++                      data->master = dev;
++              }
++      }
+-      dev_dbg(data->sysmmu, "Enabled\n");
+-finish:
+-      write_unlock_irqrestore(&data->lock, flags);
++      spin_unlock_irqrestore(&client->lock, flags);
+       return ret;
+ }
+ int exynos_sysmmu_enable(struct device *dev, unsigned long pgtable)
+ {
+-      struct sysmmu_drvdata *data = dev_get_drvdata(dev->archdata.iommu);
+       int ret;
+       BUG_ON(!memblock_is_memory(pgtable));
+-      ret = pm_runtime_get_sync(data->sysmmu);
+-      if (ret < 0) {
+-              dev_dbg(data->sysmmu, "Failed to enable\n");
+-              return ret;
+-      }
+-
+-      ret = __exynos_sysmmu_enable(data, pgtable, NULL);
+-      if (WARN_ON(ret < 0)) {
+-              pm_runtime_put(data->sysmmu);
+-              dev_err(data->sysmmu,
+-                      "Already enabled with page table %#lx\n",
+-                      data->pgtable);
+-      } else {
+-              data->dev = dev;
+-      }
++      ret = __exynos_sysmmu_enable(dev, pgtable, NULL);
+       return ret;
+ }
+ static bool exynos_sysmmu_disable(struct device *dev)
+ {
+-      struct sysmmu_drvdata *data = dev_get_drvdata(dev->archdata.iommu);
+-      bool disabled;
++      unsigned long flags;
++      bool disabled = true;
++      struct exynos_iommu_client *client = dev->archdata.iommu;
++      int i;
+-      disabled = __exynos_sysmmu_disable(data);
+-      pm_runtime_put(data->sysmmu);
++      if (WARN_ON(!client))
++              return true;
++
++      spin_lock_irqsave(&client->lock, flags);
++
++      /* Every call to __sysmmu_disable() must return same result */
++      for (i = 0; i < client->num_sysmmu; i++) {
++              struct sysmmu_drvdata *data =
++                              dev_get_drvdata(client->sysmmu[i]);
++              disabled = __sysmmu_disable(data);
++              if (disabled)
++                      data->master = NULL;
++      }
++
++      spin_unlock_irqrestore(&client->lock, flags);
+       return disabled;
+ }
+ static void sysmmu_tlb_invalidate_entry(struct device *dev, unsigned long iova)
+ {
+-      unsigned long flags;
+-      struct sysmmu_drvdata *data = dev_get_drvdata(dev->archdata.iommu);
++      struct exynos_iommu_client *client = dev->archdata.iommu;
++      int i;
+-      read_lock_irqsave(&data->lock, flags);
++      for (i = 0; i < client->num_sysmmu; i++) {
++              unsigned long flags;
++              struct sysmmu_drvdata *data;
+-      if (is_sysmmu_active(data)) {
+-              int i;
+-              for (i = 0; i < data->nsfrs; i++) {
+-                      if (sysmmu_block(data->sfrbases[i])) {
++              data = dev_get_drvdata(client->sysmmu[i]);
++
++              read_lock_irqsave(&data->lock, flags);
++              if (is_sysmmu_active(data) && data->runtime_active) {
++                      int i;
++                      clk_enable(data->clk_master);
++                      for (i = 0; i < data->nsfrs; i++)
+                               __sysmmu_tlb_invalidate_entry(
+                                               data->sfrbases[i], iova);
+-                              sysmmu_unblock(data->sfrbases[i]);
+-                      }
++                      clk_disable(data->clk_master);
++              } else {
++                      dev_dbg(dev,
++                              "disabled. Skipping TLB invalidation @ %#lx\n",
++                              iova);
+               }
+-      } else {
+-              dev_dbg(data->sysmmu, "Disabled. Skipping invalidating TLB.\n");
++              read_unlock_irqrestore(&data->lock, flags);
+       }
+-
+-      read_unlock_irqrestore(&data->lock, flags);
+ }
+ void exynos_sysmmu_tlb_invalidate(struct device *dev)
+ {
+-      unsigned long flags;
+-      struct sysmmu_drvdata *data = dev_get_drvdata(dev->archdata.iommu);
+-
+-      read_lock_irqsave(&data->lock, flags);
++      struct exynos_iommu_client *client = dev->archdata.iommu;
++      int i;
+-      if (is_sysmmu_active(data)) {
+-              int i;
+-              for (i = 0; i < data->nsfrs; i++) {
+-                      if (sysmmu_block(data->sfrbases[i])) {
+-                              __sysmmu_tlb_invalidate(data->sfrbases[i]);
+-                              sysmmu_unblock(data->sfrbases[i]);
++      for (i = 0; i < client->num_sysmmu; i++) {
++              unsigned long flags;
++              struct sysmmu_drvdata *data;
++
++              data = dev_get_drvdata(client->sysmmu[i]);
++
++              read_lock_irqsave(&data->lock, flags);
++              if (is_sysmmu_active(data) &&
++                              data->runtime_active) {
++                      int i;
++                      for (i = 0; i < data->nsfrs; i++) {
++                              clk_enable(data->clk_master);
++                              if (sysmmu_block(data->sfrbases[i])) {
++                                      __sysmmu_tlb_invalidate(
++                                                      data->sfrbases[i]);
++                                      sysmmu_unblock(data->sfrbases[i]);
++                              }
++                              clk_disable(data->clk_master);
+                       }
++              } else {
++                      dev_dbg(dev, "disabled. Skipping TLB invalidation\n");
+               }
+-      } else {
+-              dev_dbg(data->sysmmu, "Disabled. Skipping invalidating TLB.\n");
++              read_unlock_irqrestore(&data->lock, flags);
+       }
+-
+-      read_unlock_irqrestore(&data->lock, flags);
+ }
+ static int __init exynos_sysmmu_probe(struct platform_device *pdev)
+@@ -610,12 +709,32 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev)
+       pm_runtime_enable(dev);
+       data->sysmmu = dev;
++
+       data->clk = devm_clk_get(dev, "sysmmu");
+       if (IS_ERR(data->clk)) {
+               dev_info(dev, "No gate clock found!\n");
+               data->clk = NULL;
+       }
++      ret = clk_prepare(data->clk);
++      if (ret) {
++              dev_err(dev, "Failed to prepare clk\n");
++              return ret;
++      }
++
++      data->clk_master = devm_clk_get(dev, "master");
++      if (IS_ERR(data->clk_master))
++              data->clk_master = NULL;
++
++      ret = clk_prepare(data->clk_master);
++      if (ret) {
++              clk_unprepare(data->clk);
++              dev_err(dev, "Failed to prepare master's clk\n");
++              return ret;
++      }
++
++      data->runtime_active = !pm_runtime_enabled(dev);
++
+       rwlock_init(&data->lock);
+       INIT_LIST_HEAD(&data->node);
+@@ -625,6 +744,34 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev)
+       return ret;
+ }
++#ifdef CONFIG_PM_SLEEP
++static int sysmmu_suspend(struct device *dev)
++{
++      struct sysmmu_drvdata *data = dev_get_drvdata(dev);
++      unsigned long flags;
++      read_lock_irqsave(&data->lock, flags);
++      if (is_sysmmu_active(data) &&
++              (!pm_runtime_enabled(dev) || data->runtime_active))
++              __sysmmu_disable_nocount(data);
++      read_unlock_irqrestore(&data->lock, flags);
++      return 0;
++}
++
++static int sysmmu_resume(struct device *dev)
++{
++      struct sysmmu_drvdata *data = dev_get_drvdata(dev);
++      unsigned long flags;
++      read_lock_irqsave(&data->lock, flags);
++      if (is_sysmmu_active(data) &&
++              (!pm_runtime_enabled(dev) || data->runtime_active))
++              __sysmmu_enable_nocount(data);
++      read_unlock_irqrestore(&data->lock, flags);
++      return 0;
++}
++#endif
++
++static SIMPLE_DEV_PM_OPS(sysmmu_pm_ops, sysmmu_suspend, sysmmu_resume);
++
+ #ifdef CONFIG_OF
+ static struct of_device_id sysmmu_of_match[] __initconst = {
+       { .compatible   = "samsung,exynos4210-sysmmu", },
+@@ -637,6 +784,7 @@ static struct platform_driver exynos_sysmmu_driver __refdata = {
+       .driver = {
+               .owner          = THIS_MODULE,
+               .name           = "exynos-sysmmu",
++              .pm             = &sysmmu_pm_ops,
+               .of_match_table = of_match_ptr(sysmmu_of_match),
+       }
+ };
+@@ -689,7 +837,7 @@ err_pgtable:
+ static void exynos_iommu_domain_destroy(struct iommu_domain *domain)
+ {
+       struct exynos_iommu_domain *priv = domain->priv;
+-      struct sysmmu_drvdata *data;
++      struct exynos_iommu_client *client;
+       unsigned long flags;
+       int i;
+@@ -697,11 +845,14 @@ static void exynos_iommu_domain_destroy(struct iommu_domain *domain)
+       spin_lock_irqsave(&priv->lock, flags);
+-      list_for_each_entry(data, &priv->clients, node) {
+-              while (!exynos_sysmmu_disable(data->dev))
++      list_for_each_entry(client, &priv->clients, node) {
++              while (!exynos_sysmmu_disable(client->dev))
+                       ; /* until System MMU is actually disabled */
+       }
++      while (!list_empty(&priv->clients))
++              list_del_init(priv->clients.next);
++
+       spin_unlock_irqrestore(&priv->lock, flags);
+       for (i = 0; i < NUM_LV1ENTRIES; i++)
+@@ -718,41 +869,26 @@ static void exynos_iommu_domain_destroy(struct iommu_domain *domain)
+ static int exynos_iommu_attach_device(struct iommu_domain *domain,
+                                  struct device *dev)
+ {
+-      struct sysmmu_drvdata *data = dev_get_drvdata(dev->archdata.iommu);
++      struct exynos_iommu_client *client = dev->archdata.iommu;
+       struct exynos_iommu_domain *priv = domain->priv;
+       unsigned long flags;
+       int ret;
+-      ret = pm_runtime_get_sync(data->sysmmu);
+-      if (ret < 0)
+-              return ret;
+-
+-      ret = 0;
+-
+       spin_lock_irqsave(&priv->lock, flags);
+-      ret = __exynos_sysmmu_enable(data, __pa(priv->pgtable), domain);
+-
+-      if (ret == 0) {
+-              /* 'data->node' must not be appeared in priv->clients */
+-              BUG_ON(!list_empty(&data->node));
+-              data->dev = dev;
+-              list_add_tail(&data->node, &priv->clients);
+-      }
++      ret = __exynos_sysmmu_enable(dev, __pa(priv->pgtable), domain);
++      if (ret == 0)
++              list_add_tail(&client->node, &priv->clients);
+       spin_unlock_irqrestore(&priv->lock, flags);
+-      if (ret < 0) {
++      if (ret < 0)
+               dev_err(dev, "%s: Failed to attach IOMMU with pgtable %#lx\n",
+                               __func__, __pa(priv->pgtable));
+-              pm_runtime_put(data->sysmmu);
+-      } else if (ret > 0) {
+-              dev_dbg(dev, "%s: IOMMU with pgtable 0x%lx already attached\n",
+-                                      __func__, __pa(priv->pgtable));
+-      } else {
+-              dev_dbg(dev, "%s: Attached new IOMMU with pgtable 0x%lx\n",
+-                                      __func__, __pa(priv->pgtable));
+-      }
++      else
++              dev_dbg(dev, "%s: Attached IOMMU with pgtable 0x%lx%s\n",
++                                      __func__, __pa(priv->pgtable),
++                                      (ret == 0) ? "" : ", again");
+       return ret;
+ }
+@@ -760,39 +896,27 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
+ static void exynos_iommu_detach_device(struct iommu_domain *domain,
+                                   struct device *dev)
+ {
+-      struct sysmmu_drvdata *data = dev_get_drvdata(dev->archdata.iommu);
++      struct exynos_iommu_client *client = NULL;
+       struct exynos_iommu_domain *priv = domain->priv;
+-      struct list_head *pos;
+       unsigned long flags;
+-      bool found = false;
+       spin_lock_irqsave(&priv->lock, flags);
+-      list_for_each(pos, &priv->clients) {
+-              if (list_entry(pos, struct sysmmu_drvdata, node) == data) {
+-                      found = true;
++      list_for_each_entry(client, &priv->clients, node) {
++              if (client == dev->archdata.iommu) {
++                      if (exynos_sysmmu_disable(dev))
++                              list_del_init(&client->node);
+                       break;
+               }
+       }
+-      if (!found)
+-              goto finish;
++      spin_unlock_irqrestore(&priv->lock, flags);
+-      if (__exynos_sysmmu_disable(data)) {
++      if (client == dev->archdata.iommu)
+               dev_dbg(dev, "%s: Detached IOMMU with pgtable %#lx\n",
+                                       __func__, __pa(priv->pgtable));
+-              list_del_init(&data->node);
+-
+-      } else {
+-              dev_dbg(dev, "%s: Detaching IOMMU with pgtable %#lx delayed",
+-                                      __func__, __pa(priv->pgtable));
+-      }
+-
+-finish:
+-      spin_unlock_irqrestore(&priv->lock, flags);
+-
+-      if (found)
+-              pm_runtime_put(data->sysmmu);
++      else
++              dev_dbg(dev, "%s: No IOMMU is attached\n", __func__);
+ }
+ static unsigned long *alloc_lv2entry(unsigned long *sent, unsigned long iova,
+@@ -914,7 +1038,7 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain,
+                                              unsigned long iova, size_t size)
+ {
+       struct exynos_iommu_domain *priv = domain->priv;
+-      struct sysmmu_drvdata *data;
++      struct exynos_iommu_client *client;
+       unsigned long flags;
+       unsigned long *ent;
+       size_t err_pgsize;
+@@ -975,8 +1099,8 @@ done:
+       spin_unlock_irqrestore(&priv->pgtablelock, flags);
+       spin_lock_irqsave(&priv->lock, flags);
+-      list_for_each_entry(data, &priv->clients, node)
+-              sysmmu_tlb_invalidate_entry(data->dev, iova);
++      list_for_each_entry(client, &priv->clients, node)
++              sysmmu_tlb_invalidate_entry(client->dev, iova);
+       spin_unlock_irqrestore(&priv->lock, flags);
+       return size;
+@@ -1055,3 +1179,275 @@ static int __init exynos_iommu_init(void)
+       return ret;
+ }
+ subsys_initcall(exynos_iommu_init);
++
++#ifdef CONFIG_PM_SLEEP
++static int sysmmu_pm_genpd_suspend(struct device *dev)
++{
++      struct exynos_iommu_client *client = dev->archdata.iommu;
++      int ret = 0;
++      int i;
++
++      for (i = 0; i < client->num_sysmmu; i++) {
++              ret = pm_generic_suspend(client->sysmmu[i]);
++              if (ret)
++                      break;
++      }
++
++      if (!ret)
++              ret = pm_generic_suspend(dev);
++
++      if (ret) {
++              int j;
++
++              for (j = 0; j < i; j++)
++                      pm_generic_resume(client->sysmmu[j]);
++      }
++
++      return ret;
++}
++
++static int sysmmu_pm_genpd_resume(struct device *dev)
++{
++      struct exynos_iommu_client *client = dev->archdata.iommu;
++      int ret = 0;
++      int i;
++
++      for (i = 0; i < client->num_sysmmu; i++) {
++              ret = pm_generic_resume(client->sysmmu[i]);
++              if (ret)
++                      break;
++      }
++
++      if (!ret)
++              ret = pm_generic_resume(dev);
++
++      if (ret) {
++              int j;
++
++              for (j = 0; j < i; j++)
++                      pm_generic_suspend(client->sysmmu[j]);
++      }
++
++      return ret;
++}
++#endif
++
++#ifdef CONFIG_PM_RUNTIME
++static void sysmmu_restore_state(struct device *sysmmu)
++{
++      struct sysmmu_drvdata *data = dev_get_drvdata(sysmmu);
++      unsigned long flags;
++
++      spin_lock_irqsave(&data->lock, flags);
++      data->runtime_active = true;
++      if (is_sysmmu_active(data))
++              __sysmmu_enable_nocount(data);
++      spin_unlock_irqrestore(&data->lock, flags);
++}
++
++static void sysmmu_save_state(struct device *sysmmu)
++{
++      struct sysmmu_drvdata *data = dev_get_drvdata(sysmmu);
++      unsigned long flags;
++
++      spin_lock_irqsave(&data->lock, flags);
++      if (is_sysmmu_active(data))
++              __sysmmu_disable_nocount(data);
++      data->runtime_active = false;
++      spin_unlock_irqrestore(&data->lock, flags);
++}
++
++static int sysmmu_pm_genpd_save_state(struct device *dev)
++{
++      struct exynos_iommu_client *client = dev->archdata.iommu;
++      int (*cb)(struct device *__dev);
++      int i;
++
++      if (dev->type && dev->type->pm)
++              cb = dev->type->pm->runtime_suspend;
++      else if (dev->class && dev->class->pm)
++              cb = dev->class->pm->runtime_suspend;
++      else if (dev->bus && dev->bus->pm)
++              cb = dev->bus->pm->runtime_suspend;
++      else
++              cb = NULL;
++
++      if (!cb && dev->driver && dev->driver->pm)
++              cb = dev->driver->pm->runtime_suspend;
++
++      if (cb) {
++              int ret;
++
++              ret = cb(dev);
++              if (ret)
++                      return ret;
++      }
++
++      for (i = 0; i < client->num_sysmmu; i++)
++              sysmmu_save_state(client->sysmmu[i]);
++
++      return 0;
++}
++
++static int sysmmu_pm_genpd_restore_state(struct device *dev)
++{
++      struct exynos_iommu_client *client = dev->archdata.iommu;
++      int (*cb)(struct device *__dev);
++      int i;
++
++      if (dev->type && dev->type->pm)
++              cb = dev->type->pm->runtime_resume;
++      else if (dev->class && dev->class->pm)
++              cb = dev->class->pm->runtime_resume;
++      else if (dev->bus && dev->bus->pm)
++              cb = dev->bus->pm->runtime_resume;
++      else
++              cb = NULL;
++
++      if (!cb && dev->driver && dev->driver->pm)
++              cb = dev->driver->pm->runtime_resume;
++
++      for (i = 0; i < client->num_sysmmu; i++)
++              sysmmu_restore_state(client->sysmmu[i]);
++
++      if (cb) {
++              int ret;
++              ret = cb(dev);
++              if (ret) {
++                      for (i = 0; i < client->num_sysmmu; i++)
++                              sysmmu_save_state(client->sysmmu[i]);
++                      return ret;
++              }
++      }
++
++      return 0;
++}
++#endif
++
++#ifdef CONFIG_PM_GENERIC_DOMAINS
++struct gpd_dev_ops sysmmu_devpm_ops = {
++#ifdef CONFIG_PM_RUNTIME
++      .save_state = &sysmmu_pm_genpd_save_state,
++      .restore_state = &sysmmu_pm_genpd_restore_state,
++#endif
++#ifdef CONFIG_PM_SLEEP
++      .suspend = &sysmmu_pm_genpd_suspend,
++      .resume = &sysmmu_pm_genpd_resume,
++#endif
++};
++#endif /* CONFIG_PM_GENERIC_DOMAINS */
++
++static int sysmmu_hook_driver_register(struct notifier_block *nb,
++                                      unsigned long val,
++                                      void *p)
++{
++      struct device *dev = p;
++
++      switch (val) {
++      case BUS_NOTIFY_BIND_DRIVER:
++      {
++              int i = 0;
++              int size = 0;
++              const __be32 *phandle;
++              struct exynos_iommu_client *client;
++
++              phandle = of_get_property(dev->of_node, "iommu", &size);
++              if (!phandle)
++                      break;
++
++              size = size / sizeof(*phandle); /* number of elements */
++
++              client = devm_kzalloc(dev, sizeof(*client) * size, GFP_KERNEL);
++              if (!client) {
++                      dev_err(dev, "No Memory for exynos_iommu_client\n");
++                      return -ENOMEM;
++              }
++
++              client->num_sysmmu = size;
++              client->dev = dev;
++              INIT_LIST_HEAD(&client->node);
++              spin_lock_init(&client->lock);
++
++              for (i = 0; i < size; i++) {
++                      struct device_node *np;
++                      struct platform_device *sysmmu;
++
++                      /* this always success: see above of_find_property() */
++                      np = of_parse_phandle(dev->of_node, "iommu", i);
++
++                      sysmmu = of_find_device_by_node(np);
++                      if (!sysmmu) {
++                              dev_err(dev,
++                                      "sysmmu node '%s' is not found\n",
++                                      np->name);
++                              break;
++                      }
++
++                      client->sysmmu[i] = &sysmmu->dev;
++              }
++
++              if (i < size) {
++                      while (--i >= 0)
++                              of_node_put(client->sysmmu[i]->of_node);
++                      devm_kfree(dev, client);
++                      return -ENODEV;
++              }
++
++              i = pm_genpd_add_callbacks(dev, &sysmmu_devpm_ops, NULL);
++              if (i && (i != -ENOSYS)) {
++                      dev_err(dev,
++                              "Failed to register 'dev_pm_ops' for iommu\n");
++                      devm_kfree(dev, client);
++                      return i;
++              }
++
++              dev->archdata.iommu = client;
++              break;
++      }
++      case BUS_NOTIFY_BOUND_DRIVER:
++      {
++              struct exynos_iommu_client *client = dev->archdata.iommu;
++              if (dev->archdata.iommu &&
++                              (!pm_runtime_enabled(dev) ||
++                                       IS_ERR(dev_to_genpd(dev)))) {
++                      int i;
++                      for (i = 0; i < client->num_sysmmu; i++) {
++                              struct sysmmu_drvdata *data;
++                              pm_runtime_disable(client->sysmmu[i]);
++                              data = dev_get_drvdata(client->sysmmu[i]);
++                              if (!data)
++                                      continue;
++                              data->runtime_active =
++                                      !pm_runtime_enabled(data->sysmmu);
++                              if (data->runtime_active &&
++                                              is_sysmmu_active(data))
++                                      __sysmmu_enable_nocount(data);
++                      }
++              }
++              break;
++      }
++      case BUS_NOTIFY_UNBOUND_DRIVER:
++      {
++              if (dev->archdata.iommu) {
++                      __pm_genpd_remove_callbacks(dev, false);
++
++                      devm_kfree(dev, dev->archdata.iommu);
++
++                      dev->archdata.iommu = NULL;
++              }
++              break;
++      }
++      } /* switch (val) */
++
++      return 0;
++}
++
++static struct notifier_block sysmmu_notifier = {
++      .notifier_call = &sysmmu_hook_driver_register,
++};
++
++static int __init exynos_iommu_prepare(void)
++{
++      return bus_register_notifier(&platform_bus_type, &sysmmu_notifier);
++}
++arch_initcall(exynos_iommu_prepare);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0025-iommu-exynos-change-rwlock-to-spinlock.patch b/patches.tizen/0025-iommu-exynos-change-rwlock-to-spinlock.patch
new file mode 100644 (file)
index 0000000..b20c902
--- /dev/null
@@ -0,0 +1,175 @@
+From 065720fe8b38f878bfa03ec80fb2c677db36c5f6 Mon Sep 17 00:00:00 2001
+From: Cho KyongHo <pullip.cho@samsung.com>
+Date: Fri, 26 Jul 2013 20:30:42 +0900
+Subject: [PATCH 0025/1302] iommu/exynos: change rwlock to spinlock
+
+Since acquiring read_lock is not more frequent than write_lock, it is
+not beneficial to use rwlock, this commit changes rwlock to spinlock.
+
+Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iommu/exynos-iommu.c | 36 ++++++++++++++++++------------------
+ 1 file changed, 18 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
+index c62c244..51e5b35 100644
+--- a/drivers/iommu/exynos-iommu.c
++++ b/drivers/iommu/exynos-iommu.c
+@@ -187,7 +187,7 @@ struct sysmmu_drvdata {
+       struct clk *clk;
+       struct clk *clk_master;
+       int activations;
+-      rwlock_t lock;
++      spinlock_t lock;
+       struct iommu_domain *domain;
+       bool runtime_active;
+       unsigned long pgtable;
+@@ -287,7 +287,7 @@ void exynos_sysmmu_set_prefbuf(struct device *dev,
+       BUG_ON((base0 + size0) <= base0);
+       BUG_ON((size1 > 0) && ((base1 + size1) <= base1));
+-      read_lock_irqsave(&data->lock, flags);
++      spin_lock_irqsave(&data->lock, flags);
+       if (!is_sysmmu_active(data))
+               goto finish;
+@@ -319,7 +319,7 @@ void exynos_sysmmu_set_prefbuf(struct device *dev,
+       }
+       clk_disable(data->clk_master);
+ finish:
+-      read_unlock_irqrestore(&data->lock, flags);
++      spin_unlock_irqrestore(&data->lock, flags);
+ }
+ static void show_fault_information(const char *name,
+@@ -371,7 +371,7 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
+       if (client)
+               spin_lock(&client->lock);
+-      read_lock(&data->lock);
++      spin_lock(&data->lock);
+       if (i == data->nsfrs) {
+               itype = SYSMMU_FAULT_UNKNOWN;
+@@ -402,7 +402,7 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
+       if (itype != SYSMMU_FAULT_UNKNOWN)
+               sysmmu_unblock(data->sfrbases[i]);
+-      read_unlock(&data->lock);
++      spin_unlock(&data->lock);
+       if (client)
+               spin_unlock(&client->lock);
+@@ -429,7 +429,7 @@ static bool __sysmmu_disable(struct sysmmu_drvdata *data)
+       bool disabled;
+       unsigned long flags;
+-      write_lock_irqsave(&data->lock, flags);
++      spin_lock_irqsave(&data->lock, flags);
+       disabled = set_sysmmu_inactive(data);
+@@ -446,7 +446,7 @@ static bool __sysmmu_disable(struct sysmmu_drvdata *data)
+                                       data->activations);
+       }
+-      write_unlock_irqrestore(&data->lock, flags);
++      spin_unlock_irqrestore(&data->lock, flags);
+       return disabled;
+ }
+@@ -493,7 +493,7 @@ static int __sysmmu_enable(struct sysmmu_drvdata *data,
+       int ret = 0;
+       unsigned long flags;
+-      write_lock_irqsave(&data->lock, flags);
++      spin_lock_irqsave(&data->lock, flags);
+       if (set_sysmmu_active(data)) {
+               data->pgtable = pgtable;
+               data->domain = domain;
+@@ -511,7 +511,7 @@ static int __sysmmu_enable(struct sysmmu_drvdata *data,
+       if (WARN_ON(ret < 0))
+               set_sysmmu_inactive(data); /* decrement count */
+-      write_unlock_irqrestore(&data->lock, flags);
++      spin_unlock_irqrestore(&data->lock, flags);
+       return ret;
+ }
+@@ -602,7 +602,7 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, unsigned long iova)
+               data = dev_get_drvdata(client->sysmmu[i]);
+-              read_lock_irqsave(&data->lock, flags);
++              spin_lock_irqsave(&data->lock, flags);
+               if (is_sysmmu_active(data) && data->runtime_active) {
+                       int i;
+                       clk_enable(data->clk_master);
+@@ -615,7 +615,7 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, unsigned long iova)
+                               "disabled. Skipping TLB invalidation @ %#lx\n",
+                               iova);
+               }
+-              read_unlock_irqrestore(&data->lock, flags);
++              spin_unlock_irqrestore(&data->lock, flags);
+       }
+ }
+@@ -630,7 +630,7 @@ void exynos_sysmmu_tlb_invalidate(struct device *dev)
+               data = dev_get_drvdata(client->sysmmu[i]);
+-              read_lock_irqsave(&data->lock, flags);
++              spin_lock_irqsave(&data->lock, flags);
+               if (is_sysmmu_active(data) &&
+                               data->runtime_active) {
+                       int i;
+@@ -646,7 +646,7 @@ void exynos_sysmmu_tlb_invalidate(struct device *dev)
+               } else {
+                       dev_dbg(dev, "disabled. Skipping TLB invalidation\n");
+               }
+-              read_unlock_irqrestore(&data->lock, flags);
++              spin_unlock_irqrestore(&data->lock, flags);
+       }
+ }
+@@ -735,7 +735,7 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev)
+       data->runtime_active = !pm_runtime_enabled(dev);
+-      rwlock_init(&data->lock);
++      spin_lock_init(&data->lock);
+       INIT_LIST_HEAD(&data->node);
+       platform_set_drvdata(pdev, data);
+@@ -749,11 +749,11 @@ static int sysmmu_suspend(struct device *dev)
+ {
+       struct sysmmu_drvdata *data = dev_get_drvdata(dev);
+       unsigned long flags;
+-      read_lock_irqsave(&data->lock, flags);
++      spin_lock_irqsave(&data->lock, flags);
+       if (is_sysmmu_active(data) &&
+               (!pm_runtime_enabled(dev) || data->runtime_active))
+               __sysmmu_disable_nocount(data);
+-      read_unlock_irqrestore(&data->lock, flags);
++      spin_unlock_irqrestore(&data->lock, flags);
+       return 0;
+ }
+@@ -761,11 +761,11 @@ static int sysmmu_resume(struct device *dev)
+ {
+       struct sysmmu_drvdata *data = dev_get_drvdata(dev);
+       unsigned long flags;
+-      read_lock_irqsave(&data->lock, flags);
++      spin_lock_irqsave(&data->lock, flags);
+       if (is_sysmmu_active(data) &&
+               (!pm_runtime_enabled(dev) || data->runtime_active))
+               __sysmmu_enable_nocount(data);
+-      read_unlock_irqrestore(&data->lock, flags);
++      spin_unlock_irqrestore(&data->lock, flags);
+       return 0;
+ }
+ #endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0026-iommu-exynos-return-0-if-iommu_attach_device-success.patch b/patches.tizen/0026-iommu-exynos-return-0-if-iommu_attach_device-success.patch
new file mode 100644 (file)
index 0000000..0caa0a0
--- /dev/null
@@ -0,0 +1,53 @@
+From 0ef8e7b01cbbbca10b0b289935a2ebac3603e948 Mon Sep 17 00:00:00 2001
+From: Cho KyongHo <pullip.cho@samsung.com>
+Date: Fri, 26 Jul 2013 20:31:01 +0900
+Subject: [PATCH 0026/1302] iommu/exynos: return 0 if iommu_attach_device()
+ successes
+
+iommu_attach_device() against exynos-iommu positive integer on success
+if the caller calls iommu_attach_device() with the same iommu_domain
+multiple times without call to iommu_detach_device() to inform the
+caller how many calls to iommu_detach_device() to really detach iommu.
+
+However the convention of the return value of success of common API is
+zero, this patch makes iommu_attach_device() call against exynos-iommu
+always return zero if the given device is successfully attached to
+the given iommu_domain even though it is already attached to the same
+iommu_domain.
+
+Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iommu/exynos-iommu.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
+index 51e5b35..6eed6d6 100644
+--- a/drivers/iommu/exynos-iommu.c
++++ b/drivers/iommu/exynos-iommu.c
+@@ -882,15 +882,16 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
+       spin_unlock_irqrestore(&priv->lock, flags);
+-      if (ret < 0)
++      if (ret < 0) {
+               dev_err(dev, "%s: Failed to attach IOMMU with pgtable %#lx\n",
+                               __func__, __pa(priv->pgtable));
+-      else
+-              dev_dbg(dev, "%s: Attached IOMMU with pgtable 0x%lx%s\n",
+-                                      __func__, __pa(priv->pgtable),
+-                                      (ret == 0) ? "" : ", again");
++              return ret;
++      }
+-      return ret;
++      dev_dbg(dev, "%s: Attached IOMMU with pgtable 0x%lx%s\n",
++              __func__, __pa(priv->pgtable), (ret == 0) ? "" : ", again");
++
++      return 0;
+ }
+ static void exynos_iommu_detach_device(struct iommu_domain *domain,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0027-drivers-base-add-notifier-for-failed-driver-bind.patch b/patches.tizen/0027-drivers-base-add-notifier-for-failed-driver-bind.patch
new file mode 100644 (file)
index 0000000..d7e27e2
--- /dev/null
@@ -0,0 +1,75 @@
+From 24773097d72de6063c612ffea60b814c914df977 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Thu, 8 Aug 2013 11:05:57 +0200
+Subject: [PATCH 0027/1302] drivers: base: add notifier for failed driver bind
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/base/dd.c      | 10 +++++++---
+ include/linux/device.h |  4 +++-
+ 2 files changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/base/dd.c b/drivers/base/dd.c
+index 35fa368..2c8a0d6 100644
+--- a/drivers/base/dd.c
++++ b/drivers/base/dd.c
+@@ -224,10 +224,14 @@ static int driver_sysfs_add(struct device *dev)
+       return ret;
+ }
+-static void driver_sysfs_remove(struct device *dev)
++static void driver_sysfs_remove(struct device *dev, int failed)
+ {
+       struct device_driver *drv = dev->driver;
++      if (failed && dev->bus)
++              blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
++                                           BUS_NOTIFY_BIND_FAILED, dev);
++
+       if (drv) {
+               sysfs_remove_link(&drv->p->kobj, kobject_name(&dev->kobj));
+               sysfs_remove_link(&dev->kobj, "driver");
+@@ -302,7 +306,7 @@ static int really_probe(struct device *dev, struct device_driver *drv)
+ probe_failed:
+       devres_release_all(dev);
+-      driver_sysfs_remove(dev);
++      driver_sysfs_remove(dev, true);
+       dev->driver = NULL;
+       dev_set_drvdata(dev, NULL);
+@@ -492,7 +496,7 @@ static void __device_release_driver(struct device *dev)
+       if (drv) {
+               pm_runtime_get_sync(dev);
+-              driver_sysfs_remove(dev);
++              driver_sysfs_remove(dev, false);
+               if (dev->bus)
+                       blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
+diff --git a/include/linux/device.h b/include/linux/device.h
+index c0a1261..1ce409f 100644
+--- a/include/linux/device.h
++++ b/include/linux/device.h
+@@ -161,7 +161,7 @@ extern int bus_register_notifier(struct bus_type *bus,
+ extern int bus_unregister_notifier(struct bus_type *bus,
+                                  struct notifier_block *nb);
+-/* All 4 notifers below get called with the target struct device *
++/* All 7 notifers below get called with the target struct device *
+  * as an argument. Note that those functions are likely to be called
+  * with the device lock held in the core, so be careful.
+  */
+@@ -174,6 +174,8 @@ extern int bus_unregister_notifier(struct bus_type *bus,
+                                                     unbound */
+ #define BUS_NOTIFY_UNBOUND_DRIVER     0x00000006 /* driver is unbound
+                                                     from the device */
++#define BUS_NOTIFY_BIND_FAILED                0x00000007 /* driver failed to bind
++                                                    to device */
+ extern struct kset *bus_get_kset(struct bus_type *bus);
+ extern struct klist *bus_get_device_klist(struct bus_type *bus);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0028-ARM-dts-Add-dts-for-exynos4412-slp_pq-board.patch b/patches.tizen/0028-ARM-dts-Add-dts-for-exynos4412-slp_pq-board.patch
new file mode 100644 (file)
index 0000000..871d8c8
--- /dev/null
@@ -0,0 +1,497 @@
+From df8f759acbf72ed37f298a113bfd77825630e5f7 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Tue, 11 Sep 2012 14:27:22 +0200
+Subject: [PATCH 0028/1302] ARM: dts: Add dts for exynos4412-slp_pq board
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/Makefile              |   1 +
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 463 ++++++++++++++++++++++++++++++++
+ 2 files changed, 464 insertions(+)
+ create mode 100644 arch/arm/boot/dts/exynos4412-slp_pq.dts
+
+diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
+index f0895c5..ecdfe00 100644
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -52,6 +52,7 @@ dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \
+       exynos4210-universal_c210.dtb \
+       exynos4412-odroidx.dtb \
+       exynos4412-smdk4412.dtb \
++      exynos4412-slp_pq.dtb \
+       exynos4412-origen.dtb \
+       exynos5250-arndale.dtb \
+       exynos5440-sd5v1.dtb \
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+new file mode 100644
+index 0000000..8d9d2fb
+--- /dev/null
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -0,0 +1,463 @@
++/*
++ * Samsung's Exynos4412 based SLP PQ board device tree source
++ *
++ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
++ *            http://www.samsung.com
++ *
++ * Device tree source file for Samsung's SLP PQ board which is based on
++ * Samsung's Exynos4412 SoC.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++*/
++
++/dts-v1/;
++/include/ "exynos4412.dtsi"
++
++/ {
++      model = "Samsung SLP PQ based on Exynos4412";
++      compatible = "samsung,slp_pq", "samsung,exynos4412";
++
++      memory {
++              reg =  <0x40000000 0x10000000
++                      0x50000000 0x10000000
++                      0x60000000 0x10000000
++                      0x70000000 0x10000000>;
++      };
++
++      chosen {
++              bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rootwait earlyprintk panic=5";
++      };
++
++      firmware@0204F000 {
++              compatible = "samsung,secure-firmware";
++              reg = <0x0204F000 0x1000>;
++      };
++
++      vemmc_reg: voltage-regulator@0 {
++              compatible = "regulator-fixed";
++              regulator-name = "VMEM_VDD_2.8V";
++              regulator-min-microvolt = <2800000>;
++              regulator-max-microvolt = <2800000>;
++              gpio = <&gpk0 2 0>;
++              enable-active-high;
++      };
++
++      sdhci_emmc: sdhci@12510000 {
++              bus-width = <8>;
++              non-removable;
++              pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus8>;
++              pinctrl-names = "default";
++              vmmc-supply = <&vemmc_reg>;
++              status = "okay";
++      };
++
++      serial@13800000 {
++              status = "okay";
++      };
++
++      serial@13810000 {
++              status = "okay";
++      };
++
++      serial@13820000 {
++              status = "okay";
++      };
++
++      serial@13830000 {
++              status = "okay";
++      };
++
++      gpio-keys@0 {
++              compatible = "gpio-keys";
++
++              key@114 {
++                      interrupt-parent = <&gpj1>;
++                      interrupts = <2 0>;
++                      gpios = <&gpj1 2 1>;
++                      linux,code = <114>;
++                      label = "volume down";
++                      debounce-interval = <10>;
++              };
++
++              key@115 {
++                      interrupt-parent = <&gpj1>;
++                      interrupts = <1 0>;
++                      gpios = <&gpj1 1 1>;
++                      linux,code = <115>;
++                      label = "volume up";
++                      debounce-interval = <10>;
++              };
++
++              key@116 {
++                      interrupt-parent = <&gpx2>;
++                      interrupts = <7 0>;
++                      gpios = <&gpx2 7 1>;
++                      linux,code = <116>;
++                      label = "power";
++                      debounce-interval = <10>;
++                      gpio-key,wakeup;
++              };
++      };
++
++      i2c@13890000 {
++              samsung,i2c-sda-delay = <100>;
++              samsung,i2c-slave-addr = <0x10>;
++              samsung,i2c-max-bus-freq = <400000>;
++              pinctrl-0 = <&i2c3_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              mms114-touchscreen@48 {
++                      compatible = "melfas,mms114";
++                      reg = <0x48>;
++                      interrupt-parent = <&gpm2>;
++                      interrupts = <3 2>;
++                      x-size = <720>;
++                      y-size = <1280>;
++                      avdd-supply = <&ldo23_reg>;
++                      vdd-supply = <&ldo24_reg>;
++              };
++      };
++
++      i2c@138D0000 {
++              samsung,i2c-sda-delay = <100>;
++              samsung,i2c-slave-addr = <0x10>;
++              samsung,i2c-max-bus-freq = <100000>;
++              pinctrl-0 = <&i2c7_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              max77686_pmic@09 {
++                      compatible = "maxim,max77686";
++                      interrupt-parent = <&gpx0>;
++                      interrupts = <7 0>;
++                      reg = <0x09>;
++
++                      voltage-regulators {
++                              ldo1_reg: ldo@1 {
++                                      regulator-compatible = "LDO1";
++                                      regulator-name = "VALIVE_1.0V_AP";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo2_reg: ldo@2 {
++                                      regulator-compatible = "LDO2";
++                                      regulator-name = "VM1M2_1.2V_AP";
++                                      regulator-min-microvolt = <1200000>;
++                                      regulator-max-microvolt = <1200000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo3_reg: ldo@3 {
++                                      regulator-compatible = "LDO3";
++                                      regulator-name = "VCC_1.8V_AP";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo4_reg: ldo@4 {
++                                      regulator-compatible = "LDO4";
++                                      regulator-name = "VCC_2.8V_AP";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo5_reg: ldo@5 {
++                                      regulator-compatible = "LDO5";
++                                      regulator-name = "VCC_1.8V_IO";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo6_reg: ldo@6 {
++                                      regulator-compatible = "LDO6";
++                                      regulator-name = "VMPLL_1.0V_AP";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo7_reg: ldo@7 {
++                                      regulator-compatible = "LDO7";
++                                      regulator-name = "VPLL_1.0V_AP";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo8_reg: ldo@8 {
++                                      regulator-compatible = "LDO8";
++                                      regulator-name = "VMIPI_1.0V";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                              };
++
++                              ldo9_reg: ldo@9 {
++                                      regulator-compatible = "LDO9";
++                                      regulator-name = "CAM_ISP_MIPI_1.2V";
++                                      regulator-min-microvolt = <1200000>;
++                                      regulator-max-microvolt = <1200000>;
++                              };
++
++                              ldo10_reg: ldo@10 {
++                                      regulator-compatible = "LDO10";
++                                      regulator-name = "VMIPI_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                              };
++
++                              ldo11_reg: ldo@11 {
++                                      regulator-compatible = "LDO11";
++                                      regulator-name = "VABB1_1.95V";
++                                      regulator-min-microvolt = <1950000>;
++                                      regulator-max-microvolt = <1950000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo12_reg: ldo@12 {
++                                      regulator-compatible = "LDO12";
++                                      regulator-name = "VUOTG_3.0V";
++                                      regulator-min-microvolt = <3000000>;
++                                      regulator-max-microvolt = <3000000>;
++                              };
++
++                              ldo13_reg: ldo@13 {
++                                      regulator-compatible = "LDO13";
++                                      regulator-name = "NFC_AVDD_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                              };
++
++                              ldo14_reg: ldo@14 {
++                                      regulator-compatible = "LDO14";
++                                      regulator-name = "VABB2_1.95V";
++                                      regulator-min-microvolt = <1950000>;
++                                      regulator-max-microvolt = <1950000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo15_reg: ldo@15 {
++                                      regulator-compatible = "LDO15";
++                                      regulator-name = "VHSIC_1.0V";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                              };
++
++                              ldo16_reg: ldo@16 {
++                                      regulator-compatible = "LDO16";
++                                      regulator-name = "VHSIC_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                              };
++
++                              ldo17_reg: ldo@17 {
++                                      regulator-compatible = "LDO17";
++                                      regulator-name = "CAM_SENSOR_CORE_1.2V";
++                                      regulator-min-microvolt = <1200000>;
++                                      regulator-max-microvolt = <1200000>;
++                              };
++
++                              ldo18_reg: ldo@18 {
++                                      regulator-compatible = "LDO18";
++                                      regulator-name = "CAM_ISP_SEN_IO_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                              };
++
++                              ldo19_reg: ldo@19 {
++                                      regulator-compatible = "LDO19";
++                                      regulator-name = "VT_CAM_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                              };
++
++                              ldo20_reg: ldo@20 {
++                                      regulator-compatible = "LDO20";
++                                      regulator-name = "VDDQ_PRE_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                              };
++
++                              ldo21_reg: ldo@21 {
++                                      regulator-compatible = "LDO21";
++                                      regulator-name = "VTF_2.8V";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
++                              };
++
++                              ldo22_reg: ldo@22 {
++                                      regulator-compatible = "LDO22";
++                                      regulator-name = "VMEM_VDD_2.8V";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo23_reg: ldo@23 {
++                                      regulator-compatible = "LDO23";
++                                      regulator-name = "TSP_AVDD_3.3V";
++                                      regulator-min-microvolt = <3300000>;
++                                      regulator-max-microvolt = <3300000>;
++                              };
++
++                              ldo24_reg: ldo@24 {
++                                      regulator-compatible = "LDO24";
++                                      regulator-name = "TSP_VDD_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                              };
++
++                              ldo25_reg: ldo@25 {
++                                      regulator-compatible = "LDO25";
++                                      regulator-name = "LCD_VCC_3.3V";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
++                              };
++
++                              ldo26_reg: ldo@26 {
++                                      regulator-compatible = "LDO26";
++                                      regulator-name = "MOTOR_VCC_3.0V";
++                                      regulator-min-microvolt = <3000000>;
++                                      regulator-max-microvolt = <3000000>;
++                              };
++
++                              buck1_reg: buck@1 {
++                                      regulator-compatible = "BUCK1";
++                                      regulator-name = "vdd_mif";
++                                      regulator-min-microvolt = <850000>;
++                                      regulator-max-microvolt = <1100000>;
++                                      regulator-always-on;
++                                      regulator-boot-on;
++                              };
++
++                              buck2_reg: buck@2 {
++                                      regulator-compatible = "BUCK2";
++                                      regulator-name = "vdd_arm";
++                                      regulator-min-microvolt = <850000>;
++                                      regulator-max-microvolt = <1500000>;
++                                      regulator-always-on;
++                                      regulator-boot-on;
++                              };
++
++                              buck3_reg: buck@3 {
++                                      regulator-compatible = "BUCK3";
++                                      regulator-name = "vdd_int";
++                                      regulator-min-microvolt = <850000>;
++                                      regulator-max-microvolt = <1150000>;
++                                      regulator-always-on;
++                                      regulator-boot-on;
++                              };
++
++                              buck4_reg: buck@4 {
++                                      regulator-compatible = "BUCK4";
++                                      regulator-name = "vdd_g3d";
++                                      regulator-min-microvolt = <850000>;
++                                      regulator-max-microvolt = <1150000>;
++                                      regulator-boot-on;
++                              };
++
++                              buck5_reg: buck@5 {
++                                      regulator-compatible = "BUCK5";
++                                      regulator-name = "VMEM_1.2V_AP";
++                                      regulator-min-microvolt = <1200000>;
++                                      regulator-max-microvolt = <1200000>;
++                                      regulator-always-on;
++                              };
++
++                              buck6_reg: buck@6 {
++                                      regulator-compatible = "BUCK6";
++                                      regulator-name = "VCC_SUB_1.35V";
++                                      regulator-min-microvolt = <1350000>;
++                                      regulator-max-microvolt = <1350000>;
++                                      regulator-always-on;
++                              };
++                              buck7_reg: buck@7 {
++                                      regulator-compatible = "BUCK7";
++                                      regulator-name = "VCC_SUB_2.0V";
++                                      regulator-min-microvolt = <2000000>;
++                                      regulator-max-microvolt = <2000000>;
++                                      regulator-always-on;
++                              };
++
++                              buck8_reg: buck@8 {
++                                      regulator-compatible = "BUCK8";
++                                      regulator-name = "VMEM_VDDF_3.0V";
++                                      regulator-min-microvolt = <2850000>;
++                                      regulator-max-microvolt = <2850000>;
++                                      regulator-always-on;
++                              };
++
++                              buck9_reg: buck@9 {
++                                      regulator-compatible = "BUCK9";
++                                      regulator-name = "CAM_ISP_CORE_1.2V";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1200000>;
++                              };
++                      };
++              };
++      };
++
++      lcd_vdd3_reg: voltage-regulator@1 {
++              compatible = "regulator-fixed";
++              regulator-name = "LCD_VDD_2.2V";
++              regulator-min-microvolt = <2200000>;
++              regulator-max-microvolt = <2200000>;
++              gpio = <&gpc0 1 0>;
++              enable-active-high;
++      };
++
++      fimd0_lcd: panel {
++              compatible = "s6e8ax0";
++              reset-gpio = <&gpy4 5 0>;
++              reset-delay = <25>;
++              power-off-delay = <0>;
++              power-on-delay= <0>;
++              vdd3-supply = <&lcd_vdd3_reg>;
++              vci-supply = <&ldo25_reg>;
++              lcd-htiming = <5 5 5 720>;
++              lcd-vtiming = <1 13 2 1280>;
++              supports-mipi-panel;
++      };
++
++      mipi-dsim@11C80000 {
++              video-interface;
++              virtual-channel = <0>;
++              pixel-format = <7>;
++              burst-mode = <1>;
++              bus-width = <4>;
++              cmd-allow = <0xf>;
++              pms-setting = <12 250 0>;
++              pll-stable-time = <500>;
++              escape-clock = <10000000>;
++              stop-holding-count = <0x7ff>;
++              bta-timeout = <0xff>;
++              rx-timeout = <0xffff>;
++              vdd11-supply = <&ldo8_reg>;
++              vdd18-supply = <&ldo10_reg>;
++              panel-info = <&fimd0_lcd>;
++              status = "okay";
++      };
++
++      fimd@11c00000 {
++              samsung,fimd-display = <&fimd0_lcd>;
++              samsung,fimd-vidout-rgb;
++              samsung,fimd-inv-vclk;
++              samsung,fimd-frame-rate = <60>;
++              samsung,default-window = <3>;
++              samsung,fimd-win-bpp = <32>;
++              status = "okay";
++      };
++
++      hsotg@12480000 {
++              status = "okay";
++              vusb_d-supply = <&ldo15_reg>;
++              vusb_a-supply = <&ldo12_reg>;
++      };
++};
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0029-ARM-dts-exynos4210-trats-Add-node-for-USB-gadget.patch b/patches.tizen/0029-ARM-dts-exynos4210-trats-Add-node-for-USB-gadget.patch
new file mode 100644 (file)
index 0000000..7d6f816
--- /dev/null
@@ -0,0 +1,31 @@
+From 68497a23742fedc0dd4b05df6a7d60c7464aec01 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 4 Oct 2012 12:11:55 +0200
+Subject: [PATCH 0029/1302] ARM: dts: exynos4210-trats: Add node for USB gadget
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index 9a14484..ce729c7 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -290,6 +290,12 @@
+               };
+       };
++      hsotg@12480000 {
++              status = "okay";
++              vusb_d-supply = <&vusb_reg>;
++              vusb_a-supply = <&vusbdac_reg>;
++      };
++
+       fixed-rate-clocks {
+               xxti {
+                       compatible = "samsung,clock-xxti";
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0030-ARM-dts-exynos4-Add-node-for-USB-PHY.patch b/patches.tizen/0030-ARM-dts-exynos4-Add-node-for-USB-PHY.patch
new file mode 100644 (file)
index 0000000..1671109
--- /dev/null
@@ -0,0 +1,38 @@
+From 3b12494a4b8938874ae77d4d8acb5a577876d444 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 28 Dec 2012 16:44:10 +0100
+Subject: [PATCH 0030/1302] ARM: dts: exynos4: Add node for USB PHY
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index 77ac4af..9ef9926 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -351,6 +351,19 @@
+               status = "disabled";
+       };
++      usbphy@125B0000 {
++              compatible = "samsung,exynos4210-usbphy";
++              reg = <0x125B0000 0x100>;
++              ranges;
++              #address-cells = <1>;
++              #size-cells = <1>;
++              status = "disabled";
++
++              usbphy-sys {
++                      reg = <0x10020704 0x8>;
++              };
++      };
++
+       hsotg@12480000 {
+               compatible = "samsung,s3c-hsotg";
+               reg = <0x12480000 0x20000>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0031-ARM-dts-exynos4-Move-usbphy-node-to-SoC-specific-dts.patch b/patches.tizen/0031-ARM-dts-exynos4-Move-usbphy-node-to-SoC-specific-dts.patch
new file mode 100644 (file)
index 0000000..076ad5f
--- /dev/null
@@ -0,0 +1,92 @@
+From bd8c4646ef517e146f6c58cfc7a23962fc9b815c Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Mon, 7 Jan 2013 15:52:58 +0100
+Subject: [PATCH 0031/1302] ARM: dts: exynos4: Move usbphy node to SoC-specific
+ dts files
+
+USB PHY of Exynos4210 and Exynos4x12 require different compatible
+strings, making usbphy node SoC-specific.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi    | 13 -------------
+ arch/arm/boot/dts/exynos4210.dtsi | 15 +++++++++++++++
+ arch/arm/boot/dts/exynos4x12.dtsi | 15 +++++++++++++++
+ 3 files changed, 30 insertions(+), 13 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index 9ef9926..77ac4af 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -351,19 +351,6 @@
+               status = "disabled";
+       };
+-      usbphy@125B0000 {
+-              compatible = "samsung,exynos4210-usbphy";
+-              reg = <0x125B0000 0x100>;
+-              ranges;
+-              #address-cells = <1>;
+-              #size-cells = <1>;
+-              status = "disabled";
+-
+-              usbphy-sys {
+-                      reg = <0x10020704 0x8>;
+-              };
+-      };
+-
+       hsotg@12480000 {
+               compatible = "samsung,s3c-hsotg";
+               reg = <0x12480000 0x20000>;
+diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
+index 7ab619e..501708a 100644
+--- a/arch/arm/boot/dts/exynos4210.dtsi
++++ b/arch/arm/boot/dts/exynos4210.dtsi
+@@ -149,4 +149,19 @@
+               samsung,power-domain = <&pd_lcd1>;
+               status = "ok";
+       };
++
++      usbphy@125B0000 {
++              compatible = "samsung,exynos4210-usb2phy";
++              reg = <0x125B0000 0x100>;
++              ranges;
++              #address-cells = <1>;
++              #size-cells = <1>;
++              clocks = <&clock 305>;
++              clock-names = "otg";
++              status = "disabled";
++
++              usbphy-sys {
++                      reg = <0x10020704 0x8>;
++              };
++      };
+ };
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index 3bf2d09..6aca431 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -159,4 +159,19 @@
+               clocks = <&clock 365>;
+               status = "ok";
+       };
++
++      usbphy@125B0000 {
++              compatible = "samsung,exynos4x12-usb2phy";
++              reg = <0x125B0000 0x100>;
++              ranges;
++              #address-cells = <1>;
++              #size-cells = <1>;
++              clocks = <&clock 305>;
++              clock-names = "otg";
++              status = "disabled";
++
++              usbphy-sys {
++                      reg = <0x10020704 0x8>;
++              };
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0032-ARM-dts-exynos4210-trats-Enable-USB-PHY-node.patch b/patches.tizen/0032-ARM-dts-exynos4210-trats-Enable-USB-PHY-node.patch
new file mode 100644 (file)
index 0000000..be2e2f2
--- /dev/null
@@ -0,0 +1,29 @@
+From e7f5f027bc00faa267d4cf315b0f18bf4f0e5f34 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 28 Dec 2012 16:44:39 +0100
+Subject: [PATCH 0032/1302] ARM: dts: exynos4210-trats: Enable USB PHY node
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index ce729c7..a413897 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -290,6 +290,10 @@
+               };
+       };
++      usbphy@125B0000 {
++              status = "okay";
++      };
++
+       hsotg@12480000 {
+               status = "okay";
+               vusb_d-supply = <&vusb_reg>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0033-ARM-dts-exynos4412-slp_pq-Enable-USB-PHY-node.patch b/patches.tizen/0033-ARM-dts-exynos4412-slp_pq-Enable-USB-PHY-node.patch
new file mode 100644 (file)
index 0000000..0161d3c
--- /dev/null
@@ -0,0 +1,29 @@
+From dbfa49a283a249931538719422911eebe82b6c4e Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 28 Dec 2012 16:44:57 +0100
+Subject: [PATCH 0033/1302] ARM: dts: exynos4412-slp_pq: Enable USB PHY node
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 8d9d2fb..bd34a51 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -455,6 +455,10 @@
+               status = "okay";
+       };
++      usbphy@125B0000 {
++              status = "okay";
++      };
++
+       hsotg@12480000 {
+               status = "okay";
+               vusb_d-supply = <&ldo15_reg>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0034-ARM-dts-exynos4210-trats-Add-display-support-on-Trat.patch b/patches.tizen/0034-ARM-dts-exynos4210-trats-Add-display-support-on-Trat.patch
new file mode 100644 (file)
index 0000000..6ba02c4
--- /dev/null
@@ -0,0 +1,74 @@
+From 128e292dc4439c5584af2479841157a985d0c2e7 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 31 Aug 2012 12:32:35 +0200
+Subject: [PATCH 0034/1302] ARM: dts: exynos4210-trats: Add display support on
+ Trats
+
+This commit adds nodes and attributes necessary to enable support of
+MIPI DSIM, LCD and FIMD on Trats board.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+
+Conflicts:
+       arch/arm/boot/dts/exynos4210-trats.dts
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 43 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 43 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index a413897..39fcc8a 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -311,4 +311,47 @@
+                       clock-frequency = <24000000>;
+               };
+       };
++
++      fimd0_lcd: panel {
++              compatible = "s6e8ax0";
++              panel-reverse;
++              reset-gpio = <&gpy4 5 0>;
++              reset-delay = <25>;
++              power-off-delay = <0>;
++              power-on-delay= <0>;
++              vdd3-supply = <&vcclcd_reg>;
++              vci-supply = <&vlcd_reg>;
++              lcd-htiming = <5 5 5 720>;
++              lcd-vtiming = <1 13 2 1280>;
++              supports-mipi-panel;
++      };
++
++      mipi-dsim@11C80000 {
++              video-interface;
++              virtual-channel = <0>;
++              pixel-format = <7>;
++              burst-mode = <1>;
++              bus-width = <4>;
++              cmd-allow = <0xf>;
++              pms-setting = <12 250 0>;
++              pll-stable-time = <500>;
++              escape-clock = <10000000>;
++              stop-holding-count = <0x7ff>;
++              bta-timeout = <0xff>;
++              rx-timeout = <0xffff>;
++              vdd11-supply = <&vusb_reg>;
++              vdd18-supply = <&vmipi_reg>;
++              panel-info = <&fimd0_lcd>;
++              status = "okay";
++      };
++
++      fimd@11c00000 {
++              samsung,fimd-display = <&fimd0_lcd>;
++              samsung,fimd-vidout-rgb;
++              samsung,fimd-inv-vclk;
++              samsung,fimd-frame-rate = <60>;
++              samsung,default-window = <3>;
++              samsung,fimd-win-bpp = <32>;
++              status = "okay";
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0035-ARM-dts-exynos4210-trats-Fix-vdd_arm-regulator-name.patch b/patches.tizen/0035-ARM-dts-exynos4210-trats-Fix-vdd_arm-regulator-name.patch
new file mode 100644 (file)
index 0000000..aa3362a
--- /dev/null
@@ -0,0 +1,28 @@
+From 98d6d2ec0a2217c908e92b8440793b61fcd3ce55 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 3 Jan 2013 17:53:55 +0100
+Subject: [PATCH 0035/1302] ARM: dts: exynos4210-trats: Fix vdd_arm regulator
+ name
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index 39fcc8a..c49ec79 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -244,7 +244,7 @@
+                               };
+                               varm_breg: BUCK1 {
+-                                   regulator-name = "VARM_1.2V_C210";
++                                   regulator-name = "vdd_arm";
+                                    regulator-min-microvolt = <900000>;
+                                    regulator-max-microvolt = <1350000>;
+                                    regulator-always-on;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0036-drm-exynos-fimd-clear-channel-before-enabling-iommu.patch b/patches.tizen/0036-drm-exynos-fimd-clear-channel-before-enabling-iommu.patch
new file mode 100644 (file)
index 0000000..bb2c472
--- /dev/null
@@ -0,0 +1,72 @@
+From 3d8e597cc926df5641751736edc3f0d9d21e1eba Mon Sep 17 00:00:00 2001
+From: Akshu Agrawal <akshu.a@samsung.com>
+Date: Wed, 26 Dec 2012 06:27:41 -0500
+Subject: [PATCH 0036/1302] drm/exynos: fimd: clear channel before enabling
+ iommu
+
+If any fimd channel was already active, initializing iommu will result
+in a PAGE FAULT (e.g. u-boot could have turned on the display and
+not disabled it before the kernel starts). This patch checks if any
+channel is active before initializing iommu and disables it.
+
+Signed-off-by: Akshu Agrawal <akshu.a@samsung.com>
+Signed-off-by: Prathyush K <prathyush.k@samsung.com>
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_fimd.c | 31 +++++++++++++++++++++++++++++--
+ 1 file changed, 29 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+index 97c61db..8ffbe2d 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+@@ -695,6 +695,28 @@ out:
+       return IRQ_HANDLED;
+ }
++static void fimd_clear_channel(struct device *dev)
++{
++      struct fimd_context *ctx = get_fimd_context(dev);
++      int win, ch_enabled = 0;
++
++      DRM_DEBUG_KMS("%s\n", __FILE__);
++
++      /* Check if any channel is enabled */
++      for (win = 0; win < WINDOWS_NR; win++) {
++              u32 val = readl(ctx->regs + SHADOWCON);
++              if (val & SHADOWCON_CHx_ENABLE(win)) {
++                      val &= ~SHADOWCON_CHx_ENABLE(win);
++                      writel(val, ctx->regs + SHADOWCON);
++                      ch_enabled = 1;
++              }
++      }
++
++      /* Wait for vsync, as disable channel takes effect at next vsync */
++      if (ch_enabled)
++              fimd_wait_for_vblank(dev);
++}
++
+ static int fimd_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
+ {
+       DRM_DEBUG_KMS("%s\n", __FILE__);
+@@ -717,9 +739,14 @@ static int fimd_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
+       drm_dev->vblank_disable_allowed = 1;
+       /* attach this sub driver to iommu mapping if supported. */
+-      if (is_drm_iommu_supported(drm_dev))
++      if (is_drm_iommu_supported(drm_dev)) {
++              /*
++               * If any channel is already active, iommu will throw
++               * a PAGE FAULT when enabled. So clear any channel if enabled.
++               */
++              fimd_clear_channel(dev);
+               drm_iommu_attach_device(drm_dev, dev);
+-
++      }
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0037-ARM-EXYNOS-add-ARM_HAS_SG_CHAIN-config.patch b/patches.tizen/0037-ARM-EXYNOS-add-ARM_HAS_SG_CHAIN-config.patch
new file mode 100644 (file)
index 0000000..c34dccb
--- /dev/null
@@ -0,0 +1,26 @@
+From a0a270f57148a54699e09241278a211397909862 Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Thu, 3 Jan 2013 14:00:30 +0900
+Subject: [PATCH 0037/1302] ARM: EXYNOS: add ARM_HAS_SG_CHAIN config
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/plat-samsung/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
+index f8ed2de..a072524 100644
+--- a/arch/arm/plat-samsung/Kconfig
++++ b/arch/arm/plat-samsung/Kconfig
+@@ -22,6 +22,7 @@ config PLAT_S5P
+       select ARM_VIC if !ARCH_EXYNOS
+       select GIC_NON_BANKED if ARCH_EXYNOS4
+       select NO_IOPORT
++      select ARM_HAS_SG_CHAIN
+       select PLAT_SAMSUNG
+       select S3C_GPIO_TRACK
+       select S5P_GPIO_DRVSTR
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0038-ARM-EXYNOS-select-ARM_DMA_USE_IOMMU-for-MACH_EXYNOS4.patch b/patches.tizen/0038-ARM-EXYNOS-select-ARM_DMA_USE_IOMMU-for-MACH_EXYNOS4.patch
new file mode 100644 (file)
index 0000000..efc6caf
--- /dev/null
@@ -0,0 +1,31 @@
+From 98aa4c80a62ac52748d81a6457e5ae0fa1e256b1 Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Thu, 3 Jan 2013 19:01:41 +0900
+Subject: [PATCH 0038/1302] ARM: EXYNOS: select ARM_DMA_USE_IOMMU for
+ MACH_EXYNOS4_DT
+
+if EXYNOS_IOMMU is enabled then ARM_DMA_USE_IOMMU
+will be enabled also.
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/mach-exynos/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
+index ff18fc2..0020f87 100644
+--- a/arch/arm/mach-exynos/Kconfig
++++ b/arch/arm/mach-exynos/Kconfig
+@@ -417,6 +417,7 @@ config MACH_EXYNOS4_DT
+       select PINCTRL_EXYNOS
+       select S5P_DEV_MFC
+       select USE_OF
++      select ARM_DMA_USE_IOMMU if EXYNOS_IOMMU
+       help
+         Machine support for Samsung Exynos4 machine with device tree enabled.
+         Select this if a fdt blob is available for the Exynos4 SoC based board.
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0039-ARM-dts-exynos4412-slp_pq-add-fimd-iommu-support.patch b/patches.tizen/0039-ARM-dts-exynos4412-slp_pq-add-fimd-iommu-support.patch
new file mode 100644 (file)
index 0000000..0c0e83e
--- /dev/null
@@ -0,0 +1,29 @@
+From 6eb924c0471b1709f33496cf76c632132cec33f2 Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Thu, 3 Jan 2013 19:03:19 +0900
+Subject: [PATCH 0039/1302] ARM: dts: exynos4412-slp_pq: add fimd iommu support
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index bd34a51..d506149 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -455,6 +455,10 @@
+               status = "okay";
+       };
++      sysmmu-fimd0 {
++              mmu-master = <&fimd>;
++      };
++
+       usbphy@125B0000 {
+               status = "okay";
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0040-ARM-DTS-SLP-PQ-add-drm-virtual-display-node.patch b/patches.tizen/0040-ARM-DTS-SLP-PQ-add-drm-virtual-display-node.patch
new file mode 100644 (file)
index 0000000..55030ef
--- /dev/null
@@ -0,0 +1,29 @@
+From ecfb835fff3829e3fa8da3ce5f81bf800a551cf2 Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Fri, 4 Jan 2013 16:25:52 +0900
+Subject: [PATCH 0040/1302] ARM: DTS: SLP-PQ: add drm virtual display node.
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index d506149..fe5a458 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -455,6 +455,10 @@
+               status = "okay";
+       };
++      vidi {
++              compatible = "samsung,exynos-drm-vidi";
++      };
++
+       sysmmu-fimd0 {
+               mmu-master = <&fimd>;
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0041-drm-exynos-add-dt-match-table-for-vidi-module.patch b/patches.tizen/0041-drm-exynos-add-dt-match-table-for-vidi-module.patch
new file mode 100644 (file)
index 0000000..414c33a
--- /dev/null
@@ -0,0 +1,40 @@
+From b96dacd547b581341447efd317da886856802878 Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Fri, 4 Jan 2013 16:27:03 +0900
+Subject: [PATCH 0041/1302] drm/exynos: add dt match table for vidi module.
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_vidi.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+index 24376c1..c966e23 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+@@ -85,6 +85,14 @@ static const char fake_edid_info[] = {
+       0x00, 0x00, 0x00, 0x06
+ };
++#ifdef CONFIG_OF
++static const struct of_device_id vidi_driver_dt_match[] = {
++      { .compatible = "samsung,exynos-drm-vidi" },
++      {},
++};
++MODULE_DEVICE_TABLE(of, vidi_driver_dt_match);
++#endif
++
+ static bool vidi_display_is_connected(struct device *dev)
+ {
+       struct vidi_context *ctx = get_vidi_context(dev);
+@@ -664,5 +672,6 @@ struct platform_driver vidi_driver = {
+               .name   = "exynos-drm-vidi",
+               .owner  = THIS_MODULE,
+               .pm     = &vidi_pm_ops,
++              .of_match_table = of_match_ptr(vidi_driver_dt_match),
+       },
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0042-ARM-dts-exynos4210-trats-Add-nodes-for-xxti-and-xusb.patch b/patches.tizen/0042-ARM-dts-exynos4210-trats-Add-nodes-for-xxti-and-xusb.patch
new file mode 100644 (file)
index 0000000..197bba1
--- /dev/null
@@ -0,0 +1,38 @@
+From 52add51cd571f8ddb8870f0ce64e731a6452d31f Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Mon, 7 Jan 2013 18:09:08 +0100
+Subject: [PATCH 0042/1302] ARM: dts: exynos4210-trats: Add nodes for xxti and
+ xusbxti clocks
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index c49ec79..f9a57fd 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -30,6 +30,18 @@
+               bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rootwait earlyprintk panic=5";
+       };
++      fixed-rate-clocks {
++              xxti {
++                      compatible = "samsung,clock-xxti", "fixed-clock";
++                      clock-frequency = <0>;
++              };
++
++              xusbxti {
++                      compatible = "samsung,clock-xusbxti", "fixed-clock";
++                      clock-frequency = <24000000>;
++              };
++      };
++
+       vemmc_reg: voltage-regulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "VMEM_VDD_2.8V";
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0043-ARM-dts-exynos4412-slp_pq-Add-nodes-for-xxti-and-xus.patch b/patches.tizen/0043-ARM-dts-exynos4412-slp_pq-Add-nodes-for-xxti-and-xus.patch
new file mode 100644 (file)
index 0000000..30b5ce8
--- /dev/null
@@ -0,0 +1,38 @@
+From d1bb3d04acad2d7dd21e195603ae4e4b1b83d289 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Mon, 7 Jan 2013 18:10:22 +0100
+Subject: [PATCH 0043/1302] ARM: dts: exynos4412-slp_pq: Add nodes for xxti and
+ xusbxti clocks
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index fe5a458..e28bc60 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -35,6 +35,18 @@
+               reg = <0x0204F000 0x1000>;
+       };
++      fixed-rate-clocks {
++              xxti {
++                      compatible = "samsung,clock-xxti", "fixed-clock";
++                      clock-frequency = <0>;
++              };
++
++              xusbxti {
++                      compatible = "samsung,clock-xusbxti", "fixed-clock";
++                      clock-frequency = <24000000>;
++              };
++      };
++
+       vemmc_reg: voltage-regulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "VMEM_VDD_2.8V";
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0044-ARM-dts-exynos4-Add-clock-lookups-to-hsotg-node.patch b/patches.tizen/0044-ARM-dts-exynos4-Add-clock-lookups-to-hsotg-node.patch
new file mode 100644 (file)
index 0000000..e3adaa3
--- /dev/null
@@ -0,0 +1,27 @@
+From 142965e2afd8cee8efbad05a8699d686a1af9a81 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Mon, 7 Jan 2013 18:23:04 +0100
+Subject: [PATCH 0044/1302] ARM: dts: exynos4: Add clock lookups to hsotg node
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index 77ac4af..3b09373 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -355,6 +355,8 @@
+               compatible = "samsung,s3c-hsotg";
+               reg = <0x12480000 0x20000>;
+               interrupts = <0 71 0>;
++              clocks = <&clock 305>;
++              clock-names = "otg";
+               status = "disabled";
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0045-V4L-s5c73m3-Initial-device-tree-support.patch b/patches.tizen/0045-V4L-s5c73m3-Initial-device-tree-support.patch
new file mode 100644 (file)
index 0000000..4319053
--- /dev/null
@@ -0,0 +1,223 @@
+From cd7aa493bbb6b0b92acca162b143eeab23ef2c85 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 23 Jan 2013 12:32:05 +0100
+Subject: [PATCH 0045/1302] V4L: s5c73m3: Initial device tree support
+
+Add OF match table for the I2C client and SPI device driver,
+and GPIO handling for DT. This is minimum required to make
+the driver work with DT.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/s5c73m3/s5c73m3-core.c | 110 +++++++++++++++++++++----------
+ drivers/media/i2c/s5c73m3/s5c73m3-spi.c  |   6 ++
+ 2 files changed, 81 insertions(+), 35 deletions(-)
+
+diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+index 9eac531..e6ce92a 100644
+--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
++++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+@@ -23,6 +23,7 @@
+ #include <linux/init.h>
+ #include <linux/media.h>
+ #include <linux/module.h>
++#include <linux/of_gpio.h>
+ #include <linux/regulator/consumer.h>
+ #include <linux/slab.h>
+ #include <linux/spi/spi.h>
+@@ -1511,17 +1512,28 @@ static const struct v4l2_subdev_ops oif_subdev_ops = {
+       .video  = &s5c73m3_oif_video_ops,
+ };
+-static int s5c73m3_configure_gpio(int nr, int val, const char *name)
++/*
++ * GPIO control helpers
++ */
++static int s5c73m3_configure_gpio(struct s5c73m3_gpio *gpio, int idx,
++                                const char *name, struct device_node *node)
+ {
+-      unsigned long flags = val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+-      int ret;
++      enum of_gpio_flags of_flags;
++      unsigned long flags;
++
++      if (node) {
++              gpio->gpio = of_get_gpio_flags(node, idx, &of_flags);
++              gpio->level = !(of_flags & OF_GPIO_ACTIVE_LOW);
++      }
+-      if (!gpio_is_valid(nr))
++      if (!gpio_is_valid(gpio->gpio))
+               return 0;
+-      ret = gpio_request_one(nr, flags, name);
+-      if (!ret)
+-              gpio_export(nr, 0);
+-      return ret;
++
++      flags = gpio->level ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
++      pr_debug("gpio[%d]: %d, flags: %#lx, of_flags: %#x\n",
++               idx, gpio->gpio, flags, of_flags);
++
++      return gpio_request_one(gpio->gpio, flags, name);
+ }
+ static int s5c73m3_free_gpios(struct s5c73m3 *state)
+@@ -1538,33 +1550,59 @@ static int s5c73m3_free_gpios(struct s5c73m3 *state)
+ }
+ static int s5c73m3_configure_gpios(struct s5c73m3 *state,
+-                                 const struct s5c73m3_platform_data *pdata)
++                                 struct device *dev)
+ {
+-      const struct s5c73m3_gpio *gpio = &pdata->gpio_stby;
++      const struct s5c73m3_platform_data *pdata = dev->platform_data;
++      struct s5c73m3_gpio gpio;
+       int ret;
+       state->gpio[STBY].gpio = -EINVAL;
+       state->gpio[RST].gpio  = -EINVAL;
+-      ret = s5c73m3_configure_gpio(gpio->gpio, gpio->level, "S5C73M3_STBY");
+-      if (ret) {
+-              s5c73m3_free_gpios(state);
+-              return ret;
++      if (pdata)
++              gpio = pdata->gpio_stby;
++      else
++              gpio.gpio = -EINVAL;
++      ret = s5c73m3_configure_gpio(&gpio, STBY, "S5C73M3_STBY",
++                                   dev->of_node);
++      if (!ret) {
++              state->gpio[STBY] = gpio;
++              if (gpio_is_valid(gpio.gpio))
++                      gpio_set_value(gpio.gpio, 0);
++              if (pdata)
++                      gpio = pdata->gpio_reset;
++              else
++                      gpio.gpio = -EINVAL;
++              ret = s5c73m3_configure_gpio(&gpio, RST, "S5C73M3_RST",
++                                           dev->of_node);
++              if (!ret && gpio_is_valid(gpio.gpio))
++                      gpio_set_value(gpio.gpio, 0);
+       }
+-      state->gpio[STBY] = *gpio;
+-      if (gpio_is_valid(gpio->gpio))
+-              gpio_set_value(gpio->gpio, 0);
+-
+-      gpio = &pdata->gpio_reset;
+-      ret = s5c73m3_configure_gpio(gpio->gpio, gpio->level, "S5C73M3_RST");
+-      if (ret) {
++      if (!ret)
++              state->gpio[RST] = gpio;
++      else
+               s5c73m3_free_gpios(state);
+-              return ret;
++
++      return ret;
++}
++
++static int s5c73m3_get_platform_data(struct s5c73m3 *state, struct device *dev)
++{
++      const struct s5c73m3_platform_data *pdata = dev->platform_data;
++      struct device_node *node = dev->of_node;
++
++      if (!node) {
++              if (!pdata) {
++                      dev_err(dev, "Platform data not specified\n");
++                      return -EINVAL;
++              }
++
++              state->mclk_frequency = pdata->mclk_frequency;
++              state->bus_type = pdata->bus_type;
++              return 0;
+       }
+-      state->gpio[RST] = *gpio;
+-      if (gpio_is_valid(gpio->gpio))
+-              gpio_set_value(gpio->gpio, 0);
++      of_property_read_u32(node, "clock-frequency", &state->mclk_frequency);
+       return 0;
+ }
+@@ -1572,21 +1610,19 @@ static int s5c73m3_probe(struct i2c_client *client,
+                               const struct i2c_device_id *id)
+ {
+       struct device *dev = &client->dev;
+-      const struct s5c73m3_platform_data *pdata = client->dev.platform_data;
+       struct v4l2_subdev *sd;
+       struct v4l2_subdev *oif_sd;
+       struct s5c73m3 *state;
+       int ret, i;
+-      if (pdata == NULL) {
+-              dev_err(&client->dev, "Platform data not specified\n");
+-              return -EINVAL;
+-      }
+-
+       state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
+       if (!state)
+               return -ENOMEM;
++      ret = s5c73m3_get_platform_data(state, dev);
++      if (ret < 0)
++              return ret;
++
+       mutex_init(&state->lock);
+       sd = &state->sensor_sd;
+       oif_sd = &state->oif_sd;
+@@ -1624,10 +1660,7 @@ static int s5c73m3_probe(struct i2c_client *client,
+       if (ret < 0)
+               return ret;
+-      state->mclk_frequency = pdata->mclk_frequency;
+-      state->bus_type = pdata->bus_type;
+-
+-      ret = s5c73m3_configure_gpios(state, pdata);
++      ret = s5c73m3_configure_gpios(state, dev);
+       if (ret)
+               goto out_err1;
+@@ -1699,8 +1732,15 @@ static const struct i2c_device_id s5c73m3_id[] = {
+ };
+ MODULE_DEVICE_TABLE(i2c, s5c73m3_id);
++static const struct of_device_id s5c73m3_of_match[] = {
++      { .compatible = "samsung,s5c73m3" },
++      { }
++};
++MODULE_DEVICE_TABLE(of, s5c73m3_of_match);
++
+ static struct i2c_driver s5c73m3_i2c_driver = {
+       .driver = {
++              .of_match_table = s5c73m3_of_match,
+               .name   = DRIVER_NAME,
+       },
+       .probe          = s5c73m3_probe,
+diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-spi.c b/drivers/media/i2c/s5c73m3/s5c73m3-spi.c
+index 6f3a9c0..cd1074f 100644
+--- a/drivers/media/i2c/s5c73m3/s5c73m3-spi.c
++++ b/drivers/media/i2c/s5c73m3/s5c73m3-spi.c
+@@ -27,6 +27,11 @@
+ #define S5C73M3_SPI_DRV_NAME "S5C73M3-SPI"
++static const struct of_device_id s5c73m3_spi_ids[] = {
++      { .compatible = "samsung,s5c73m3" },
++      { }
++};
++
+ enum spi_direction {
+       SPI_DIR_RX,
+       SPI_DIR_TX
+@@ -146,6 +151,7 @@ int s5c73m3_register_spi_driver(struct s5c73m3 *state)
+       spidrv->driver.name = S5C73M3_SPI_DRV_NAME;
+       spidrv->driver.bus = &spi_bus_type;
+       spidrv->driver.owner = THIS_MODULE;
++      spidrv->driver.of_match_table = s5c73m3_spi_ids;
+       return spi_register_driver(spidrv);
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0046-s5c73m3-Disable-boot_from_rom.patch b/patches.tizen/0046-s5c73m3-Disable-boot_from_rom.patch
new file mode 100644 (file)
index 0000000..3d7522d
--- /dev/null
@@ -0,0 +1,29 @@
+From 0f0fce93bf74031922d9a6041f86b2e8b599f3f9 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 23 Jan 2013 12:37:03 +0100
+Subject: [PATCH 0046/1302] s5c73m3: Disable boot_from_rom
+
+Boot from FROM memory is only for the mainline kernel.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/s5c73m3/s5c73m3-core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+index e6ce92a..77f59fa 100644
+--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
++++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+@@ -40,7 +40,7 @@
+ int s5c73m3_dbg;
+ module_param_named(debug, s5c73m3_dbg, int, 0644);
+-static int boot_from_rom = 1;
++static int boot_from_rom = 0;
+ module_param(boot_from_rom, int, 0644);
+ static int update_fw;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0047-ARM-dts-Add-camera-to-node-exynos4.dtsi.patch b/patches.tizen/0047-ARM-dts-Add-camera-to-node-exynos4.dtsi.patch
new file mode 100644 (file)
index 0000000..7c4ebe5
--- /dev/null
@@ -0,0 +1,99 @@
+From 37f865b3f66b6b564f44b3c46eb7834022767cca Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 24 Oct 2012 17:00:57 +0200
+Subject: [PATCH 0047/1302] ARM: dts: Add camera to node exynos4.dtsi
+
+This patch adds common FIMC device nodes for all Exynos4 SoCs.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi | 64 ++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 64 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index 3b09373..5a3955b 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -36,6 +36,12 @@
+               i2c5 = &i2c_5;
+               i2c6 = &i2c_6;
+               i2c7 = &i2c_7;
++              csis0 = &csis_0;
++              csis1 = &csis_1;
++              fimc0 = &fimc_0;
++              fimc1 = &fimc_1;
++              fimc2 = &fimc_2;
++              fimc3 = &fimc_3;
+       };
+       chipid@10000000 {
+@@ -98,6 +104,64 @@
+               arm,tag-latency = <1 1 0>;
+       };
++      camera {
++              compatible = "samsung,fimc", "simple-bus";
++              status = "disabled";
++              #address-cells = <1>;
++              #size-cells = <1>;
++              ranges;
++
++              fimc_0: fimc@11800000 {
++                      compatible = "samsung,exynos4210-fimc";
++                      reg = <0x11800000 0x1000>;
++                      interrupts = <0 84 0>;
++                      samsung,power-domain = <&pd_cam>;
++                      status = "disabled";
++              };
++
++              fimc_1: fimc@11810000 {
++                      compatible = "samsung,exynos4210-fimc";
++                      reg = <0x11810000 0x1000>;
++                      interrupts = <0 85 0>;
++                      samsung,power-domain = <&pd_cam>;
++                      status = "disabled";
++              };
++
++              fimc_2: fimc@11820000 {
++                      compatible = "samsung,exynos4210-fimc";
++                      reg = <0x11820000 0x1000>;
++                      interrupts = <0 86 0>;
++                      samsung,power-domain = <&pd_cam>;
++                      status = "disabled";
++              };
++
++              fimc_3: fimc@11830000 {
++                      compatible = "samsung,exynos4210-fimc";
++                      reg = <0x11830000 0x1000>;
++                      interrupts = <0 87 0>;
++                      samsung,power-domain = <&pd_cam>;
++                      status = "disabled";
++              };
++
++              csis_0: csis@11880000 {
++                      compatible = "samsung,exynos4210-csis";
++                      reg = <0x11880000 0x4000>;
++                      interrupts = <0 78 0>;
++                      bus-width = <4>;
++                      samsung,power-domain = <&pd_cam>;
++                      status = "disabled";
++              };
++
++              csis_1: csis@11890000 {
++                      compatible = "samsung,exynos4210-csis";
++                      reg = <0x11890000 0x4000>;
++                      interrupts = <0 80 0>;
++                      bus-width = <2>;
++                      samsung,power-domain = <&pd_cam>;
++                      status = "disabled";
++              };
++      };
++
+       watchdog@10060000 {
+               compatible = "samsung,s3c2410-wdt";
+               reg = <0x10060000 0x100>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0048-ARM-dts-Add-ISP-power-domain-node-for-Exynos4x12.patch b/patches.tizen/0048-ARM-dts-Add-ISP-power-domain-node-for-Exynos4x12.patch
new file mode 100644 (file)
index 0000000..605bb79
--- /dev/null
@@ -0,0 +1,34 @@
+From 1e881c2001e9d00c04a0cef8887d093c0027e76b Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Mon, 10 Dec 2012 15:23:38 +0100
+Subject: [PATCH 0048/1302] ARM: dts: Add ISP power domain node for Exynos4x12
+
+The ISP power domain is a common power domain for fimc-lite
+and fimc-is (ISP) devices.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12.dtsi | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index 6aca431..2a5ac7b 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -28,6 +28,11 @@
+               pinctrl3 = &pinctrl_3;
+       };
++      pd_isp: isp-power-domain@10023CA0 {
++              compatible = "samsung,exynos4210-pd";
++              reg = <0x10023CA0 0x20>;
++      };
++
+       combiner:interrupt-controller@10440000 {
+               interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
+                            <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0049-ARM-dts-Add-FIMC-and-MIPI-CSIS-device-nodes-for-Exyn.patch b/patches.tizen/0049-ARM-dts-Add-FIMC-and-MIPI-CSIS-device-nodes-for-Exyn.patch
new file mode 100644 (file)
index 0000000..391d528
--- /dev/null
@@ -0,0 +1,85 @@
+From 13abd305c654983547b8cd6a1e13641a570ddd74 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Mon, 7 Jan 2013 17:13:58 +0100
+Subject: [PATCH 0049/1302] ARM: dts: Add FIMC and MIPI CSIS device nodes for
+ Exynos4x12
+
+Add common camera node and fimc nodes specific to Exynos4212 and
+Exynos4412 SoCs. fimc-is is a node for the Exynos4x12 FIMC-IS
+subsystem and fimc-lite nodes are created as its child nodes,
+among others due to FIMC-LITE device dependencies on FIMC-IS
+related clocks.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12.dtsi | 47 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 47 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index 2a5ac7b..3b4a16b 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -26,6 +26,8 @@
+               pinctrl1 = &pinctrl_1;
+               pinctrl2 = &pinctrl_2;
+               pinctrl3 = &pinctrl_3;
++              fimc-lite0 = &fimc_lite_0;
++              fimc-lite1 = &fimc_lite_1;
+       };
+       pd_isp: isp-power-domain@10023CA0 {
+@@ -179,4 +181,49 @@
+                       reg = <0x10020704 0x8>;
+               };
+       };
++
++      camera {
++              fimc_0: fimc@11800000 {
++                      compatible = "samsung,exynos4212-fimc";
++              };
++
++              fimc_1: fimc@11810000 {
++                      compatible = "samsung,exynos4212-fimc";
++              };
++
++              fimc_2: fimc@11820000 {
++                      compatible = "samsung,exynos4212-fimc";
++              };
++
++              fimc_3: fimc@11830000 {
++                      compatible = "samsung,exynos4212-fimc";
++              };
++
++              fimc_is: fimc-is@12000000 {
++                      compatible = "samsung,exynos4212-fimc-is", "simple-bus";
++                      reg = <0x12000000 0x260000>;
++                      interrupts = <0 90 0>, <0 95 0>;
++                      samsung,power-domain = <&pd_isp>;
++                      status = "disabled";
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++                      ranges;
++
++                      fimc_lite_0: fimc-lite@12390000 {
++                              compatible = "samsung,exynos4212-fimc-lite";
++                              reg = <0x12390000 0x1000>;
++                              interrupts = <0 105 0>;
++                              samsung,power-domain = <&pd_isp>;
++                              status = "disabled";
++                      };
++
++                      fimc_lite_1: fimc-lite@123A0000 {
++                              compatible = "samsung,exynos4212-fimc-lite";
++                              reg = <0x123A0000 0x1000>;
++                              interrupts = <0 106 0>;
++                              samsung,power-domain = <&pd_isp>;
++                              status = "disabled";
++                      };
++              };
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0050-ARM-dts-Correct-camera-pinctrl-nodes-for-Exynos4x12-.patch b/patches.tizen/0050-ARM-dts-Correct-camera-pinctrl-nodes-for-Exynos4x12-.patch
new file mode 100644 (file)
index 0000000..0206548
--- /dev/null
@@ -0,0 +1,90 @@
+From ac696fa80bf5addd9bb72d7e07903f19c71dbfb0 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 24 Oct 2012 16:42:12 +0200
+Subject: [PATCH 0050/1302] ARM: dts: Correct camera pinctrl nodes for
+ Exynos4x12 SoCs
+
+Add separate nodes for the CAMCLK pin and turn off pull-up on camera
+ports A, B. The video bus pins and the clock output (CAMCLK) pin need
+separate nodes since full camera port is not used in some configurations,
+e.g. for MIPI CSI-2 bus on CAMCLK is required and data/clock signal
+use separate dedicated pins.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12-pinctrl.dtsi | 40 +++++++++++++++++++++++++------
+ 1 file changed, 33 insertions(+), 7 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi b/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi
+index 099cec7..950ef30 100644
+--- a/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi
++++ b/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi
+@@ -401,13 +401,26 @@
+                       samsung,pin-drv = <0>;
+               };
+-              cam_port_a: cam-port-a {
++              cam_port_a_io: cam-port-a-io {
+                       samsung,pins = "gpj0-0", "gpj0-1", "gpj0-2", "gpj0-3",
+                                       "gpj0-4", "gpj0-5", "gpj0-6", "gpj0-7",
+-                                      "gpj1-0", "gpj1-1", "gpj1-2", "gpj1-3",
+-                                      "gpj1-4";
++                                      "gpj1-0", "gpj1-1", "gpj1-2", "gpj1-4";
+                       samsung,pin-function = <2>;
+-                      samsung,pin-pud = <3>;
++                      samsung,pin-pud = <0>;
++                      samsung,pin-drv = <0>;
++              };
++
++              cam_port_a_clk_active: cam-port-a-clk-active {
++                      samsung,pins = "gpj1-3";
++                      samsung,pin-function = <2>;
++                      samsung,pin-pud = <0>;
++                      samsung,pin-drv = <3>;
++              };
++
++              cam_port_a_clk_idle: cam-port-a-clk-idle {
++                      samsung,pins = "gpj1-3";
++                      samsung,pin-function = <0>;
++                      samsung,pin-pud = <0>;
+                       samsung,pin-drv = <0>;
+               };
+       };
+@@ -834,16 +847,29 @@
+                       samsung,pin-drv = <0>;
+               };
+-              cam_port_b: cam-port-b {
++              cam_port_b_io: cam-port-b-io {
+                       samsung,pins = "gpm0-0", "gpm0-1", "gpm0-2", "gpm0-3",
+                                       "gpm0-4", "gpm0-5", "gpm0-6", "gpm0-7",
+-                                      "gpm1-0", "gpm1-1", "gpm2-0", "gpm2-1",
+-                                      "gpm2-2";
++                                      "gpm1-0", "gpm1-1", "gpm2-0", "gpm2-1";
+                       samsung,pin-function = <3>;
+                       samsung,pin-pud = <3>;
+                       samsung,pin-drv = <0>;
+               };
++              cam_port_b_clk_active: cam-port-b-clk-active {
++                      samsung,pins = "gpm2-2";
++                      samsung,pin-function = <3>;
++                      samsung,pin-pud = <0>;
++                      samsung,pin-drv = <3>;
++              };
++
++              cam_port_b_clk_idle: cam-port-b-clk-idle {
++                      samsung,pins = "gpm2-2";
++                      samsung,pin-function = <0>;
++                      samsung,pin-pud = <0>;
++                      samsung,pin-drv = <0>;
++              };
++
+               eint0: ext-int0 {
+                       samsung,pins = "gpx0-0";
+                       samsung,pin-function = <0xf>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0051-ARM-dts-Add-camera-device-nodes-for-PQ-board.patch b/patches.tizen/0051-ARM-dts-Add-camera-device-nodes-for-PQ-board.patch
new file mode 100644 (file)
index 0000000..fe7c638
--- /dev/null
@@ -0,0 +1,225 @@
+From b58b47b20440051cb5351aad2f25acbce85e7e09 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 6 Feb 2013 18:34:42 +0100
+Subject: [PATCH 0051/1302] ARM: dts: Add camera device nodes for PQ board
+
+This patch adds all nodes for camera devices on an example Exynos4412 SoC
+based board. This is all what's required in the board dts file to enable
+rear facing camera (S5C73M3 sensor).
+
+The aliases node contains entries required for the camera processing
+data path entity drivers.
+
+The sensor nodes use standard port/remote-endpoint nodes convention.
+Internal SoC links between entities are not specified this way and
+are coded in the driver instead.
+
+The S5C73M3 sensor uses two control buses: I2C and SPI. There are
+two, i2c_0 and spi_1 bus controller child nodes assigned to it.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 173 ++++++++++++++++++++++++++++++++
+ 1 file changed, 173 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index e28bc60..fa47f9a 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -113,6 +113,35 @@
+               };
+       };
++      i2c_0: i2c@13860000 {
++              samsung,i2c-sda-delay = <100>;
++              samsung,i2c-slave-addr = <0x10>;
++              samsung,i2c-max-bus-freq = <400000>;
++              pinctrl-0 = <&i2c0_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              s5c73m3@3c {
++                      compatible = "samsung,s5c73m3";
++                      reg = <0x3c>;
++                      gpios = <&gpm0 1 1>, /* ISP_STANDBY */
++                              <&gpf1 3 1>; /* ISP_RESET */
++                      vdd-int-supply = <&buck9_reg>;
++                      vddio-cis-supply = <&ldo9_reg>;
++                      vdda-supply = <&ldo17_reg>;
++                      vddio-host-supply = <&ldo18_reg>;
++                      vdd-af-supply = <&cam_af_reg>;
++                      vdd-reg-supply = <&cam_io_reg>;
++                      clock-frequency = <24000000>;
++
++                      port {
++                              s5c73m3_ep: endpoint {
++                                      remote-endpoint = <&csis0_ep>;
++                              };
++                      };
++              };
++      };
++
+       i2c@13890000 {
+               samsung,i2c-sda-delay = <100>;
+               samsung,i2c-slave-addr = <0x10>;
+@@ -425,6 +454,34 @@
+               enable-active-high;
+       };
++      cam_af_reg: voltage-regulator@2 {
++              compatible = "regulator-fixed";
++              regulator-name = "CAM_AF";
++              regulator-min-microvolt = <2800000>;
++              regulator-max-microvolt = <2800000>;
++              gpio = <&gpm0 4 0>;
++              enable-active-high;
++      };
++
++      cam_io_reg: voltage-regulator@3 {
++              compatible = "regulator-fixed";
++              regulator-name = "CAM_SENSOR_A";
++              regulator-min-microvolt = <2800000>;
++              regulator-max-microvolt = <2800000>;
++              gpio = <&gpm0 2 0>;
++              enable-active-high;
++      };
++
++      cam_isp_core_reg: voltage-regulator@4 {
++              compatible = "regulator-fixed";
++              regulator-name = "CAM_ISP_CORE_1.2V_EN";
++              regulator-min-microvolt = <1200000>;
++              regulator-max-microvolt = <1200000>;
++              gpio = <&gpm0 3 0>;
++              enable-active-high;
++              regulator-always-on;
++      };
++
+       fimd0_lcd: panel {
+               compatible = "s6e8ax0";
+               reset-gpio = <&gpy4 5 0>;
+@@ -484,4 +541,120 @@
+               vusb_d-supply = <&ldo15_reg>;
+               vusb_a-supply = <&ldo12_reg>;
+       };
++
++      spi_1: spi@13930000 {
++              pinctrl-names = "default";
++              pinctrl-0 = <&spi1_bus>;
++              status = "okay";
++
++              s5c73m3_spi: s5c73m3 {
++                      compatible = "samsung,s5c73m3";
++                      spi-max-frequency = <50000000>;
++                      reg = <0>;
++                      controller-data {
++                              cs-gpio = <&gpb 5 0>;
++                              samsung,spi-feedback-delay = <2>;
++                      };
++              };
++      };
++
++      camera {
++              compatible = "samsung,fimc", "simple-bus";
++              status = "okay";
++
++              pinctrl-names = "default", "inactive";
++              pinctrl-0 = <&cam_port_a_clk_active>;
++              pinctrl-1 = <&cam_port_a_clk_idle>;
++
++              fimc_0: fimc@11800000 {
++                      clock-frequency = <176000000>;
++                      status = "okay";
++              };
++
++              fimc_1: fimc@11810000 {
++                      clock-frequency = <176000000>;
++                      status = "okay";
++              };
++
++              fimc_2: fimc@11820000 {
++                      clock-frequency = <176000000>;
++                      status = "okay";
++              };
++
++              fimc_3: fimc@11830000 {
++                      clock-frequency = <176000000>;
++                      status = "okay";
++              };
++
++              csis_0: csis@11880000 {
++                      status = "okay";
++                      vddcore-supply = <&ldo8_reg>;
++                      vddio-supply = <&ldo10_reg>;
++                      clock-frequency = <160000000>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++
++                      /* Camera C (3) MIPI CSI-2 (CSIS0) */
++                      port@3 {
++                              reg = <3>;
++                              csis0_ep: endpoint {
++                                      remote-endpoint = <&s5c73m3_ep>;
++                                      data-lanes = <1 2 3 4>;
++                                      samsung,csis-hs-settle = <12>;
++                              };
++                      };
++              };
++
++              csis_1: csis@11890000 {
++                      status = "okay";
++                      vddcore-supply = <&ldo8_reg>;
++                      vddio-supply = <&ldo10_reg>;
++                      clock-frequency = <160000000>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++
++                      /* Camera D (4) MIPI CSI-2 (CSIS1) */
++                      port@4 {
++                              reg = <4>;
++                              csis1_ep: endpoint {
++                                      remote-endpoint = <&is_s5k6a3_ep>;
++                                      data-lanes = <1>;
++                                      samsung,csis-hs-settle = <18>;
++                                      samsung,csis-wclk;
++                              };
++                      };
++              };
++
++              fimc-is@12000000 {
++                      status = "okay";
++
++                      fimc_lite_0: fimc-lite@12390000 {
++                              status = "okay";
++                      };
++
++                      fimc_lite_1: fimc-lite@123A0000 {
++                              status = "okay";
++                      };
++
++                      fimc-is-i2c@0 {
++                              #address-cells = <1>;
++                              #size-cells = <0>;
++
++                              s5k6a3@10 {
++                                      compatible = "samsung,s5k6a3";
++                                      reg = <0x10>;
++                                      svdda-supply = <&cam_io_reg>;
++                                      svddio-supply = <&ldo19_reg>;
++                                      clock-frequency = <24000000>;
++                                      gpios = <&gpm1 6 0>;
++                                      port {
++                                              is_s5k6a3_ep: endpoint {
++                                                      remote-endpoint = <&csis1_ep>;
++                                                      data-lanes = <1>;
++                                              };
++                                      };
++                              };
++                      };
++              };
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0052-ARM-EXYNOS-change-the-value-of-EXYNOS4X12_ISP_LOWPWR.patch b/patches.tizen/0052-ARM-EXYNOS-change-the-value-of-EXYNOS4X12_ISP_LOWPWR.patch
new file mode 100644 (file)
index 0000000..c45bedd
--- /dev/null
@@ -0,0 +1,34 @@
+From 143103659b069afb92881584f7f3d777a6d8ee6a Mon Sep 17 00:00:00 2001
+From: Younghwan Joo <yhwan.joo@samsung.com>
+Date: Thu, 15 Nov 2012 21:02:27 +0900
+Subject: [PATCH 0052/1302] ARM: EXYNOS: change the value of
+ EXYNOS4X12_ISP_LOWPWR
+
+This patch is to fix the value of EXYNOS4X12_ISP_LOWPWR register
+to zero at AFTR mode. It ensure the sub selection mux of mcuisp400
+and isp200 reset a default position after power down
+
+Signed-off-by: Younghwan Joo <yhwan.joo@samsung.com>
+Signed-off-by: JaeYong Shin <jy2.shin@samsung.com>
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/mach-exynos/pmu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c
+index 97d6885..21cef18 100644
+--- a/arch/arm/mach-exynos/pmu.c
++++ b/arch/arm/mach-exynos/pmu.c
+@@ -140,7 +140,7 @@ static struct exynos_pmu_conf exynos4x12_pmu_config[] = {
+       { S5P_CMU_RESET_MFC_LOWPWR,             { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_RESET_G3D_LOWPWR,             { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_RESET_LCD0_LOWPWR,            { 0x1, 0x0, 0x0 } },
+-      { S5P_CMU_RESET_ISP_LOWPWR,             { 0x1, 0x0, 0x0 } },
++      { S5P_CMU_RESET_ISP_LOWPWR,             { 0x0, 0x0, 0x0 } },
+       { S5P_CMU_RESET_MAUDIO_LOWPWR,          { 0x1, 0x1, 0x0 } },
+       { S5P_CMU_RESET_GPS_LOWPWR,             { 0x1, 0x0, 0x0 } },
+       { S5P_TOP_BUS_LOWPWR,                   { 0x3, 0x0, 0x0 } },
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0053-ARM-dts-Add-pinctrl-entries-for-FIMC-IS-peripherals.patch b/patches.tizen/0053-ARM-dts-Add-pinctrl-entries-for-FIMC-IS-peripherals.patch
new file mode 100644 (file)
index 0000000..77710f7
--- /dev/null
@@ -0,0 +1,47 @@
+From 67f415c5868ecfb99ced79a4805cb9cc07c2ce3a Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Mon, 7 Jan 2013 20:27:53 +0100
+Subject: [PATCH 0053/1302] ARM: dts: Add pinctrl entries for FIMC-IS
+ peripherals
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12-pinctrl.dtsi | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi b/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi
+index 950ef30..b4919a6 100644
+--- a/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi
++++ b/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi
+@@ -904,6 +904,27 @@
+                       samsung,pin-pud = <0>;
+                       samsung,pin-drv = <0>;
+               };
++
++              fimc_is_i2c0: fimc-is-i2c0 {
++                      samsung,pins = "gpm4-0", "gpm4-1";
++                      samsung,pin-function = <2>;
++                      samsung,pin-pud = <0>;
++                      samsung,pin-drv = <0>;
++              };
++
++              fimc_is_i2c1: fimc-is-i2c1 {
++                      samsung,pins = "gpm4-2", "gpm4-3";
++                      samsung,pin-function = <2>;
++                      samsung,pin-pud = <0>;
++                      samsung,pin-drv = <0>;
++              };
++
++              fimc_is_uart: fimc-is-uart {
++                      samsung,pins = "gpm3-5", "gpm3-7";
++                      samsung,pin-function = <3>;
++                      samsung,pin-pud = <0>;
++                      samsung,pin-drv = <0>;
++              };
+       };
+       pinctrl@03860000 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0054-ARM-dts-Add-pinctrl-property-to-fimc-is-node-for-PQ-.patch b/patches.tizen/0054-ARM-dts-Add-pinctrl-property-to-fimc-is-node-for-PQ-.patch
new file mode 100644 (file)
index 0000000..40eebfd
--- /dev/null
@@ -0,0 +1,35 @@
+From a6bd16a03a97317a3d79977ced76b0f6b345f553 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 23 Jan 2013 17:25:56 +0100
+Subject: [PATCH 0054/1302] ARM: dts: Add pinctrl property to fimc-is node for
+ PQ board
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index fa47f9a..3ff029f 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -627,6 +627,8 @@
+               fimc-is@12000000 {
+                       status = "okay";
++                      pinctrl-0 = <&fimc_is_i2c0 &fimc_is_i2c1 &fimc_is_uart>;
++                      pinctrl-names = "default";
+                       fimc_lite_0: fimc-lite@12390000 {
+                               status = "okay";
+@@ -637,6 +639,7 @@
+                       };
+                       fimc-is-i2c@0 {
++                              /* compatible = "samsung,exynos4212-is-i2c"; */
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0055-ARM-dts-Add-MFC-node-for-Exynos4-SoC-series.patch b/patches.tizen/0055-ARM-dts-Add-MFC-node-for-Exynos4-SoC-series.patch
new file mode 100644 (file)
index 0000000..2836ea1
--- /dev/null
@@ -0,0 +1,27 @@
+From d1934f1b374955632b5cc71c2628e048bfe38a5b Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Tue, 29 Jan 2013 14:44:19 +0100
+Subject: [PATCH 0055/1302] ARM: dts: Add MFC node for Exynos4 SoC series
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index 5a3955b..e81937c 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -230,6 +230,8 @@
+               reg = <0x13400000 0x10000>;
+               interrupts = <0 94 0>;
+               samsung,power-domain = <&pd_mfc>;
++              clocks = <&clock 273>, <&clock 170>;
++              clock-names = "mfc", "sclk_mfc";
+               status = "disabled";
+               iommu = <&sysmmu_mfc_l>, <&sysmmu_mfc_r>;
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0056-ARM-dts-Add-camera-clocks-definitions-to-exynos4-x12.patch b/patches.tizen/0056-ARM-dts-Add-camera-clocks-definitions-to-exynos4-x12.patch
new file mode 100644 (file)
index 0000000..45af53d
--- /dev/null
@@ -0,0 +1,122 @@
+From 2804ec5fe10232797945a2fd0239175c88aef877 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 18 Jan 2013 19:14:50 +0100
+Subject: [PATCH 0056/1302] ARM: dts: Add camera clocks definitions to
+ exynos4/x12.dtsi
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi    | 17 +++++++++++++++++
+ arch/arm/boot/dts/exynos4x12.dtsi |  8 ++++++++
+ 2 files changed, 25 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index e81937c..758e321 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -106,16 +106,23 @@
+       camera {
+               compatible = "samsung,fimc", "simple-bus";
++              clocks = <&clock 132>, <&clock 133>, <&clock 351>, <&clock 352>,
++                       <&clock 388>, <&clock 389>, <&clock 17>;
++              clock-names = "sclk_cam0", "sclk_cam1", "pxl_async0",
++                          "pxl_async1", "mux_cam0", "mux_cam1", "parent";
+               status = "disabled";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
++
+               fimc_0: fimc@11800000 {
+                       compatible = "samsung,exynos4210-fimc";
+                       reg = <0x11800000 0x1000>;
+                       interrupts = <0 84 0>;
+                       samsung,power-domain = <&pd_cam>;
++                      clocks = <&clock 256>, <&clock 128>, <&clock 384>, <&clock 17>;
++                      clock-names = "fimc", "sclk_fimc", "mux", "parent";
+                       status = "disabled";
+               };
+@@ -124,6 +131,8 @@
+                       reg = <0x11810000 0x1000>;
+                       interrupts = <0 85 0>;
+                       samsung,power-domain = <&pd_cam>;
++                      clocks = <&clock 257>, <&clock 129>, <&clock 385>, <&clock 17>;
++                      clock-names = "fimc", "sclk_fimc", "mux", "parent";
+                       status = "disabled";
+               };
+@@ -132,6 +141,8 @@
+                       reg = <0x11820000 0x1000>;
+                       interrupts = <0 86 0>;
+                       samsung,power-domain = <&pd_cam>;
++                      clocks = <&clock 258>, <&clock 130>, <&clock 386>, <&clock 17>;
++                      clock-names = "fimc", "sclk_fimc", "mux", "parent";
+                       status = "disabled";
+               };
+@@ -140,6 +151,8 @@
+                       reg = <0x11830000 0x1000>;
+                       interrupts = <0 87 0>;
+                       samsung,power-domain = <&pd_cam>;
++                      clocks = <&clock 259>, <&clock 131>, <&clock 387>, <&clock 17>;
++                      clock-names = "fimc", "sclk_fimc", "mux", "parent";
+                       status = "disabled";
+               };
+@@ -149,6 +162,8 @@
+                       interrupts = <0 78 0>;
+                       bus-width = <4>;
+                       samsung,power-domain = <&pd_cam>;
++                      clocks = <&clock 260>, <&clock 134>, <&clock 390>, <&clock 17>;
++                      clock-names = "csis", "sclk_csis", "mux", "parent";
+                       status = "disabled";
+               };
+@@ -158,6 +173,8 @@
+                       interrupts = <0 80 0>;
+                       bus-width = <2>;
+                       samsung,power-domain = <&pd_cam>;
++                      clocks = <&clock 261>, <&clock 135>, <&clock 391>, <&clock 17>;
++                      clock-names = "csis", "sclk_csis", "mux", "parent";
+                       status = "disabled";
+               };
+       };
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index 3b4a16b..621301c 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -204,6 +204,10 @@
+                       reg = <0x12000000 0x260000>;
+                       interrupts = <0 90 0>, <0 95 0>;
+                       samsung,power-domain = <&pd_isp>;
++                      clocks = <&clock 353>, <&clock 354>, <&clock 355>,
++                               <&clock 356>, <&clock 342>, <&clock 17>;
++                      clock-names = "flite0", "flite1", "ppmuispx",
++                              "ppmuispmx", "sysreg", "mpll";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+@@ -214,6 +218,8 @@
+                               reg = <0x12390000 0x1000>;
+                               interrupts = <0 105 0>;
+                               samsung,power-domain = <&pd_isp>;
++                              clocks = <&clock 353>;
++                              clock-names = "flite";
+                               status = "disabled";
+                       };
+@@ -222,6 +228,8 @@
+                               reg = <0x123A0000 0x1000>;
+                               interrupts = <0 106 0>;
+                               samsung,power-domain = <&pd_isp>;
++                              clocks = <&clock 354>;
++                              clock-names = "flite";
+                               status = "disabled";
+                       };
+               };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0057-v4l2-videobuf2-dc-fix-support-for-mappings-without-s.patch b/patches.tizen/0057-v4l2-videobuf2-dc-fix-support-for-mappings-without-s.patch
new file mode 100644 (file)
index 0000000..57e0d74
--- /dev/null
@@ -0,0 +1,148 @@
+From 77698aad341f20e451cbde6c125bf1485a21a772 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Fri, 7 Jun 2013 14:09:29 +0200
+Subject: [PATCH 0057/1302] v4l2: videobuf2-dc: fix support for mappings
+ without struct page in userptr mode
+
+Earlier version of dma-contig allocator in user ptr mode assumed that in
+all cases DMA address equals physical address. This was just a special case.
+Commit e15dab752d4c588544ccabdbe020a7cc092e23c8 introduced correct support
+for converting userpage to dma address, but unfortunately it broke the
+support for simple dma address = physical address for the case, when given
+physical frame has no struct page associated with it (this happens if one
+use for example dma_declare_coherent api or other reserved memory approach).
+This commit restores support for such cases.
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/v4l2-core/videobuf2-dma-contig.c | 87 ++++++++++++++++++++++++--
+ 1 file changed, 82 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c
+index fd56f25..efdaca4 100644
+--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
++++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
+@@ -423,6 +423,39 @@ static inline int vma_is_io(struct vm_area_struct *vma)
+       return !!(vma->vm_flags & (VM_IO | VM_PFNMAP));
+ }
++static int vb2_dc_get_user_pfn(unsigned long start, int n_pages,
++      struct vm_area_struct *vma, unsigned long *res)
++{
++      unsigned long pfn, start_pfn, prev_pfn;
++      unsigned int i;
++      int ret;
++
++      if (!vma_is_io(vma))
++              return -EFAULT;
++
++      ret = follow_pfn(vma, start, &pfn);
++      if (ret)
++              return ret;
++
++      start_pfn = pfn;
++      start += PAGE_SIZE;
++
++      for (i = 1; i < n_pages; ++i, start += PAGE_SIZE) {
++              prev_pfn = pfn;
++              ret = follow_pfn(vma, start, &pfn);
++
++              if (ret) {
++                      pr_err("no page for address %lu\n", start);
++                      return ret;
++              }
++              if (pfn != prev_pfn + 1)
++                      return -EINVAL;
++      }
++
++      *res = start_pfn;
++      return 0;
++}
++
+ static int vb2_dc_get_user_pages(unsigned long start, struct page **pages,
+       int n_pages, struct vm_area_struct *vma, int write)
+ {
+@@ -433,6 +466,9 @@ static int vb2_dc_get_user_pages(unsigned long start, struct page **pages,
+                       unsigned long pfn;
+                       int ret = follow_pfn(vma, start, &pfn);
++                      if (!pfn_valid(pfn))
++                              return -EINVAL;
++
+                       if (ret) {
+                               pr_err("no page for address %lu\n", start);
+                               return ret;
+@@ -468,16 +504,49 @@ static void vb2_dc_put_userptr(void *buf_priv)
+       struct vb2_dc_buf *buf = buf_priv;
+       struct sg_table *sgt = buf->dma_sgt;
+-      dma_unmap_sg(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir);
+-      if (!vma_is_io(buf->vma))
+-              vb2_dc_sgt_foreach_page(sgt, vb2_dc_put_dirty_page);
++      if (sgt) {
++              dma_unmap_sg(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir);
++              if (!vma_is_io(buf->vma))
++                      vb2_dc_sgt_foreach_page(sgt, vb2_dc_put_dirty_page);
+-      sg_free_table(sgt);
+-      kfree(sgt);
++              sg_free_table(sgt);
++              kfree(sgt);
++      }
+       vb2_put_vma(buf->vma);
+       kfree(buf);
+ }
++/*
++ * For some kind of reserved memory there might be no struct page available,
++ * so all that can be done to support such 'pages' is to try to convert
++ * pfn to dma address or at the last resort just assume that
++ * dma address == physical address (like it has been assumed in earlier version
++ * of videobuf2-dma-contig
++ */
++
++#ifdef __arch_pfn_to_dma
++static inline dma_addr_t vb2_dc_pfn_to_dma(struct device *dev, unsigned long pfn)
++{
++      return (dma_addr_t)__arch_pfn_to_dma(dev, pfn);
++}
++#elsif defined(__pfn_to_bus)
++static inline dma_addr_t vb2_dc_pfn_to_dma(struct device *dev, unsigned long pfn)
++{
++      return (dma_addr_t)__pfn_to_bus(pfn);
++}
++#elsif defined(__pfn_to_phys)
++static inline dma_addr_t vb2_dc_pfn_to_dma(struct device *dev, unsigned long pfn)
++{
++      return (dma_addr_t)__pfn_to_phys(pfn);
++}
++#else
++static inline dma_addr_t vb2_dc_pfn_to_dma(struct device *dev, unsigned long pfn)
++{
++      /* really, we cannot do anything better at this point */
++      return (dma_addr_t)(pfn) << PAGE_SHIFT;
++}
++#endif
++
+ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr,
+       unsigned long size, int write)
+ {
+@@ -548,6 +617,14 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr,
+       /* extract page list from userspace mapping */
+       ret = vb2_dc_get_user_pages(start, pages, n_pages, vma, write);
+       if (ret) {
++              unsigned long pfn;
++              if (vb2_dc_get_user_pfn(start, n_pages, vma, &pfn) == 0) {
++                      buf->dma_addr = vb2_dc_pfn_to_dma(buf->dev, pfn);
++                      buf->size = size;
++                      kfree(pages);
++                      return buf;
++              }
++
+               pr_err("failed to get user pages\n");
+               goto fail_vma;
+       }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0058-regulator-max77693-Add-regulator-driver-for-max77693.patch b/patches.tizen/0058-regulator-max77693-Add-regulator-driver-for-max77693.patch
new file mode 100644 (file)
index 0000000..1a62d95
--- /dev/null
@@ -0,0 +1,922 @@
+From 7dab7958135d40a36bf865e08a0f4e6dd7af975b Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Thu, 7 Feb 2013 15:04:33 +0900
+Subject: [PATCH 0058/1302] regulator: max77693: Add regulator driver for
+ max77693
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/regulator/Kconfig            |   8 +
+ drivers/regulator/Makefile           |   1 +
+ drivers/regulator/max77693.c         | 792 +++++++++++++++++++++++++++++++++++
+ include/linux/mfd/max77693-private.h |  14 +
+ include/linux/mfd/max77693.h         |  27 ++
+ 5 files changed, 842 insertions(+)
+ create mode 100644 drivers/regulator/max77693.c
+
+diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
+index 8bb2644..c50864c 100644
+--- a/drivers/regulator/Kconfig
++++ b/drivers/regulator/Kconfig
+@@ -250,6 +250,14 @@ config REGULATOR_MAX77686
+         via I2C bus. The provided regulator is suitable for
+         Exynos-4 chips to control VARM and VINT voltages.
++config REGULATOR_MAX77693
++      tristate "Maxim 77693 regulator"
++      depends on MFD_MAX77693
++      help
++        This driver controls a Maxim 77693 regulator
++        via I2C bus. The provided regulator supports Safeout LDOs
++        and can be used to supply low voltage related to USB systems.
++
+ config REGULATOR_PCAP
+       tristate "Motorola PCAP2 regulator driver"
+       depends on EZX_PCAP
+diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
+index 47a34ff..a4094cd 100644
+--- a/drivers/regulator/Makefile
++++ b/drivers/regulator/Makefile
+@@ -41,6 +41,7 @@ obj-$(CONFIG_REGULATOR_MAX8973) += max8973-regulator.o
+ obj-$(CONFIG_REGULATOR_MAX8997) += max8997.o
+ obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o
+ obj-$(CONFIG_REGULATOR_MAX77686) += max77686.o
++obj-$(CONFIG_REGULATOR_MAX77693) += max77693.o
+ obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
+ obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
+ obj-$(CONFIG_REGULATOR_MC13XXX_CORE) +=  mc13xxx-regulator-core.o
+diff --git a/drivers/regulator/max77693.c b/drivers/regulator/max77693.c
+new file mode 100644
+index 0000000..85776b2
+--- /dev/null
++++ b/drivers/regulator/max77693.c
+@@ -0,0 +1,792 @@
++/*
++ * max77693.c - Regulator driver for the Maxim 77693
++ *
++ * Copyright (C) 2011 Samsung Electronics
++ * Sukdong Kim <sukdong.kim@smasung.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
++ * This driver is based on max8997.c
++ */
++
++#include <linux/bug.h>
++#include <linux/delay.h>
++#include <linux/err.h>
++#include <linux/gpio.h>
++#include <linux/slab.h>
++#include <linux/platform_device.h>
++#include <linux/module.h>
++#include <linux/export.h>
++#include <linux/regulator/driver.h>
++#include <linux/regulator/machine.h>
++#include <linux/mfd/max77693.h>
++#include <linux/mfd/max77693-private.h>
++
++struct max77693_data {
++      struct device *dev;
++      struct max77693_dev *iodev;
++      int num_regulators;
++      struct regulator_dev **rdev;
++
++      u8 saved_states[MAX77693_REG_MAX];
++};
++
++struct voltage_map_desc {
++      int min;
++      int max;
++      int step;
++      unsigned int n_bits;
++};
++
++/* current map in mA */
++static const struct voltage_map_desc charger_current_map_desc = {
++      .min = 60, .max = 2580, .step = 20, .n_bits = 7,
++};
++
++static const struct voltage_map_desc topoff_current_map_desc = {
++      .min = 50, .max = 200, .step = 10, .n_bits = 4,
++};
++
++static const struct voltage_map_desc *reg_voltage_map[] = {
++      [MAX77693_ESAFEOUT1] = NULL,
++      [MAX77693_ESAFEOUT2] = NULL,
++      [MAX77693_CHARGER] = &charger_current_map_desc,
++};
++
++static inline int max77693_get_rid(struct regulator_dev *rdev)
++{
++      dev_info(&rdev->dev, "func:%s\n", __func__);
++      return rdev_get_id(rdev);
++}
++
++static int max77693_list_voltage_safeout(struct regulator_dev *rdev,
++                                       unsigned int selector)
++{
++      int rid = max77693_get_rid(rdev);
++      dev_info(&rdev->dev, "func:%s\n", __func__);
++      if (rid == MAX77693_ESAFEOUT1 || rid == MAX77693_ESAFEOUT2) {
++              switch (selector) {
++              case 0:
++                      return 4850000;
++              case 1:
++                      return 4900000;
++              case 2:
++                      return 4950000;
++              case 3:
++                      return 3300000;
++              default:
++                      return -EINVAL;
++              }
++      }
++
++      return -EINVAL;
++}
++
++static int max77693_get_enable_register(struct regulator_dev *rdev,
++                                      int *reg, int *mask, int *pattern)
++{
++      int rid = max77693_get_rid(rdev);
++      dev_info(&rdev->dev, "func:%s\n", __func__);
++      switch (rid) {
++      case MAX77693_ESAFEOUT1...MAX77693_ESAFEOUT2:
++              *reg = MAX77693_CHG_REG_SAFEOUT_CTRL;
++              *mask = 0x40 << (rid - MAX77693_ESAFEOUT1);
++              *pattern = 0x40 << (rid - MAX77693_ESAFEOUT1);
++              break;
++      case MAX77693_CHARGER:
++              *reg = MAX77693_CHG_REG_CHG_CNFG_00;
++              *mask = 0xf;
++              *pattern = 0x5;
++              break;
++      default:
++              /* Not controllable or not exists */
++              return -EINVAL;
++      }
++
++      return 0;
++}
++
++static int max77693_get_disable_register(struct regulator_dev *rdev,
++                                      int *reg, int *mask, int *pattern)
++{
++      int rid = max77693_get_rid(rdev);
++      dev_info(&rdev->dev, "func:%s\n", __func__);
++      switch (rid) {
++      case MAX77693_ESAFEOUT1...MAX77693_ESAFEOUT2:
++              *reg = MAX77693_CHG_REG_SAFEOUT_CTRL;
++              *mask = 0x40 << (rid - MAX77693_ESAFEOUT1);
++              *pattern = 0x00;
++              break;
++      case MAX77693_CHARGER:
++              *reg = MAX77693_CHG_REG_CHG_CNFG_00;
++              *mask = 0xf;
++              *pattern = 0x00;
++              break;
++      default:
++              /* Not controllable or not exists */
++              return -EINVAL;
++      }
++
++      return 0;
++}
++
++static int max77693_reg_is_enabled(struct regulator_dev *rdev)
++{
++      int ret, reg, mask, pattern;
++      u8 val;
++      dev_info(&rdev->dev, "func:%s\n", __func__);
++      ret = max77693_get_enable_register(rdev, &reg, &mask, &pattern);
++      if (ret == -EINVAL)
++              return 1;       /* "not controllable" */
++      else if (ret)
++              return ret;
++
++      ret = max77693_read_reg(rdev->regmap, reg, &val);
++      if (ret)
++              return ret;
++
++      return (val & mask) == pattern;
++}
++
++static int max77693_reg_enable(struct regulator_dev *rdev)
++{
++      int ret, reg, mask, pattern;
++      dev_info(&rdev->dev, "func:%s\n", __func__);
++      ret = max77693_get_enable_register(rdev, &reg, &mask, &pattern);
++      if (ret)
++              return ret;
++
++      return max77693_update_reg(rdev->regmap, reg, pattern, mask);
++}
++
++static int max77693_reg_disable(struct regulator_dev *rdev)
++{
++      int ret, reg, mask, pattern;
++      dev_info(&rdev->dev, "func:%s\n", __func__);
++      ret = max77693_get_disable_register(rdev, &reg, &mask, &pattern);
++      if (ret)
++              return ret;
++
++      return max77693_update_reg(rdev->regmap, reg, pattern, mask);
++}
++
++static int max77693_get_voltage_register(struct regulator_dev *rdev,
++                                       int *_reg, int *_shift, int *_mask)
++{
++      int rid = max77693_get_rid(rdev);
++      int reg, shift = 0, mask = 0x3f;
++      dev_info(&rdev->dev, "func:%s\n", __func__);
++      switch (rid) {
++      case MAX77693_ESAFEOUT1...MAX77693_ESAFEOUT2:
++              reg = MAX77693_CHG_REG_SAFEOUT_CTRL;
++              shift = (rid == MAX77693_ESAFEOUT2) ? 2 : 0;
++              mask = 0x3;
++              break;
++      case MAX77693_CHARGER:
++              reg = MAX77693_CHG_REG_CHG_CNFG_09;
++              shift = 0;
++              mask = 0x7f;
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      *_reg = reg;
++      *_shift = shift;
++      *_mask = mask;
++
++      return 0;
++}
++
++static int max77693_list_voltage(struct regulator_dev *rdev,
++                               unsigned int selector)
++{
++      const struct voltage_map_desc *desc;
++      int rid = max77693_get_rid(rdev);
++      int val;
++      dev_info(&rdev->dev, "func:%s\n", __func__);
++      if (rid >= ARRAY_SIZE(reg_voltage_map) || rid < 0)
++              return -EINVAL;
++
++      desc = reg_voltage_map[rid];
++      if (desc == NULL)
++              return -EINVAL;
++
++      /* the first four codes for charger current are all 60mA */
++      if (rid == MAX77693_CHARGER) {
++              if (selector <= 3)
++                      selector = 0;
++              else
++                      selector -= 3;
++      }
++
++      val = desc->min + desc->step * selector;
++      if (val > desc->max)
++              return -EINVAL;
++
++      return val * 1000;
++}
++
++static int max77693_get_voltage(struct regulator_dev *rdev)
++{
++      int reg, shift, mask, ret;
++
++      u8 val;
++      dev_info(&rdev->dev, "func:%s\n", __func__);
++      ret = max77693_get_voltage_register(rdev, &reg, &shift, &mask);
++      if (ret)
++              return ret;
++
++      ret = max77693_read_reg(rdev->regmap, reg, &val);
++      if (ret)
++              return ret;
++
++      val >>= shift;
++      val &= mask;
++
++      if (rdev->desc && rdev->desc->ops && rdev->desc->ops->list_voltage)
++              return rdev->desc->ops->list_voltage(rdev, val);
++
++      /*
++       * max77693_list_voltage returns value for any rdev with voltage_map,
++       * which works for "CHARGER" and "CHARGER TOPOFF" that do not have
++       * list_voltage ops (they are current regulators).
++       */
++      return max77693_list_voltage(rdev, val);
++}
++
++static inline int max77693_get_voltage_proper_val(
++              const struct voltage_map_desc *desc,
++              int min_vol, int max_vol)
++{
++      int i = 0;
++
++      if (desc == NULL)
++              return -EINVAL;
++
++      if (max_vol < desc->min || min_vol > desc->max)
++              return -EINVAL;
++
++      while (desc->min + desc->step * i < min_vol &&
++                      desc->min + desc->step * i < desc->max)
++              i++;
++
++      if (desc->min + desc->step * i > max_vol)
++              return -EINVAL;
++
++      if (i >= (1 << desc->n_bits))
++              return -EINVAL;
++
++      return i;
++}
++
++static int max77693_set_voltage(struct regulator_dev *rdev,
++                              int min_uV, int max_uV)
++{
++      int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
++      const struct voltage_map_desc *desc;
++      int rid = max77693_get_rid(rdev);
++      int reg, shift = 0, mask, ret;
++      int i;
++      u8 org;
++
++      switch (rid) {
++      case MAX77693_CHARGER:
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      desc = reg_voltage_map[rid];
++
++      i = max77693_get_voltage_proper_val(desc, min_vol, max_vol);
++      if (i < 0)
++              return i;
++
++      ret = max77693_get_voltage_register(rdev, &reg, &shift, &mask);
++      if (ret)
++              return ret;
++
++      max77693_read_reg(rdev->regmap, reg, &org);
++      org = (org & mask) >> shift;
++
++      /* the first four codes for charger current are all 60mA */
++      if (rid == MAX77693_CHARGER)
++              i += 3;
++
++      ret = max77693_update_reg(rdev->regmap, reg, i << shift, mask << shift);
++
++      return ret;
++}
++
++static const int safeoutvolt[] = {
++      3300000,
++      4850000,
++      4900000,
++      4950000,
++};
++
++/* For SAFEOUT1 and SAFEOUT2 */
++static int max77693_set_voltage_safeout(struct regulator_dev *rdev,
++                                      int min_uV, int max_uV,
++                                      unsigned *selector)
++{
++      int rid = max77693_get_rid(rdev);
++      int reg, shift = 0, mask, ret;
++      int i = 0;
++      u8 val;
++      dev_info(&rdev->dev, "func:%s\n", __func__);
++      if (rid != MAX77693_ESAFEOUT1 && rid != MAX77693_ESAFEOUT2)
++              return -EINVAL;
++
++      for (i = 0; i < ARRAY_SIZE(safeoutvolt); i++) {
++              if (min_uV <= safeoutvolt[i] && max_uV >= safeoutvolt[i])
++                      break;
++      }
++
++      if (i >= ARRAY_SIZE(safeoutvolt))
++              return -EINVAL;
++
++      if (i == 0)
++              val = 0x3;
++      else
++              val = i - 1;
++
++      ret = max77693_get_voltage_register(rdev, &reg, &shift, &mask);
++      if (ret)
++              return ret;
++
++      ret = max77693_update_reg(rdev->regmap, reg, val << shift, mask << shift);
++      *selector = val;
++
++      return ret;
++}
++
++static int max77693_reg_enable_suspend(struct regulator_dev *rdev)
++{
++      dev_info(&rdev->dev, "func:%s\n", __func__);
++      return 0;
++}
++
++static int max77693_reg_disable_suspend(struct regulator_dev *rdev)
++{
++      struct max77693_data *max77693 = rdev_get_drvdata(rdev);
++      int ret, reg, mask, pattern;
++      int rid = max77693_get_rid(rdev);
++      dev_info(&rdev->dev, "func:%s\n", __func__);
++      ret = max77693_get_disable_register(rdev, &reg, &mask, &pattern);
++      if (ret)
++              return ret;
++
++      max77693_read_reg(rdev->regmap, reg, &max77693->saved_states[rid]);
++
++      dev_dbg(&rdev->dev, "Full Power-Off for %s (%xh -> %xh)\n",
++              rdev->desc->name, max77693->saved_states[rid] & mask,
++              (~pattern) & mask);
++      return max77693_update_reg(rdev->regmap, reg, pattern, mask);
++}
++
++/*
++ * max77693_muic_is_enable_otg - Check the power state of otg
++ * @rdev: the instance for voltage/current regulator class device
++ */
++static bool max77693_muic_is_enable_otg(struct regulator_dev *rdev)
++{
++      u8 chg_cnfg_00;
++      u8 mask;
++      u8 state;
++
++      /* OTG on, boost on, DIS_MUIC_CTRL=1 */
++      max77693_read_reg(rdev->regmap,
++              MAX77693_CHG_REG_CHG_CNFG_00, &chg_cnfg_00);
++
++      mask = (CHG_CNFG_00_OTG_MASK
++                      | CHG_CNFG_00_BOOST_MASK
++                      | CHG_CNFG_00_DIS_MUIC_CTRL_MASK);
++
++      state = chg_cnfg_00 & mask;
++
++      if (state == mask)
++              return true;
++      else
++              return false;
++}
++
++/*
++ * max77693_muic_is_enable_usb - Check the power state of usb
++ * @rdev: the instance for voltage/current regulator class device
++ */
++static bool max77693_muic_is_enable_usb(struct regulator_dev *rdev)
++{
++      u8 chg_cnfg_00;
++      bool state = false;
++
++      max77693_read_reg(rdev->regmap,
++              MAX77693_CHG_REG_CHG_CNFG_00, &chg_cnfg_00);
++
++      if (chg_cnfg_00 == 0x05)
++              state = true;
++      else if (chg_cnfg_00 == 0x04)
++              state = false;
++
++      return state;
++}
++
++/*
++ * max77693_muic_enable_otg - Enable/disable otg feature on max77693
++ * @rdev: the instance for voltage/current regulator class device
++ * @enable: the state of otg feature (true: ON, false: OFF)
++ */
++static void max77693_muic_enable_otg(struct regulator_dev *rdev, int enable)
++{
++      struct max77693_data *max77693 = rdev_get_drvdata(rdev);
++      struct regmap *regmap_muic = max77693->iodev->regmap_muic;
++      static u8 chg_int_state; /* Restore charger interrupt states */
++      u8 int_mask;
++      u8 cdetctrl1;
++      u8 chg_cnfg_00;
++
++      dev_info(&rdev->dev, "enable(%d)\n", enable);
++
++      /*
++       * FIXME: This function write/read directly the register of max77693
++       *      charger device. It has dependency between muic and charger
++       *      device. The dependency between two device have to be removed.
++       *      - MAX77693_CHG_REG_CHG_CNFG_00 : control charger/OTG/buck/boost
++       *      - MAX77693_CHG_REG_CHG_INT_MASK
++       */
++      if (enable) {
++              /* disable charger interrupt */
++              max77693_read_reg(rdev->regmap,
++                      MAX77693_CHG_REG_CHG_INT_MASK, &int_mask);
++              chg_int_state = int_mask;
++              int_mask |= (1 << 4);   /* disable chgin intr */
++              int_mask |= (1 << 6);   /* disable chg */
++              int_mask &= ~(1 << 0);  /* enable byp intr */
++              max77693_write_reg(rdev->regmap,
++                      MAX77693_CHG_REG_CHG_INT_MASK, int_mask);
++
++              /* disable charger detection */
++              max77693_read_reg(regmap_muic,
++                      MAX77693_MUIC_REG_CDETCTRL1, &cdetctrl1);
++              cdetctrl1 &= ~(1 << 0);
++              max77693_write_reg(regmap_muic,
++                      MAX77693_MUIC_REG_CDETCTRL1, cdetctrl1);
++
++              /* OTG on, boost on, DIS_MUIC_CTRL=1 */
++              max77693_read_reg(rdev->regmap,
++                      MAX77693_CHG_REG_CHG_CNFG_00, &chg_cnfg_00);
++              chg_cnfg_00 &= ~(CHG_CNFG_00_CHG_MASK
++                              | CHG_CNFG_00_OTG_MASK
++                              | CHG_CNFG_00_BUCK_MASK
++                              | CHG_CNFG_00_BOOST_MASK
++                              | CHG_CNFG_00_DIS_MUIC_CTRL_MASK);
++              chg_cnfg_00 |= (CHG_CNFG_00_OTG_MASK
++                              | CHG_CNFG_00_BOOST_MASK
++                              | CHG_CNFG_00_DIS_MUIC_CTRL_MASK);
++              max77693_write_reg(rdev->regmap,
++                      MAX77693_CHG_REG_CHG_CNFG_00, chg_cnfg_00);
++      } else {
++              /* OTG off, boost off, (buck on),
++                 DIS_MUIC_CTRL = 0 unless CHG_ENA = 1 */
++              max77693_read_reg(rdev->regmap,
++                      MAX77693_CHG_REG_CHG_CNFG_00, &chg_cnfg_00);
++              chg_cnfg_00 &= ~(CHG_CNFG_00_OTG_MASK
++                              | CHG_CNFG_00_BOOST_MASK
++                              | CHG_CNFG_00_DIS_MUIC_CTRL_MASK);
++              chg_cnfg_00 |= CHG_CNFG_00_BUCK_MASK;
++              max77693_write_reg(rdev->regmap,
++                      MAX77693_CHG_REG_CHG_CNFG_00, chg_cnfg_00);
++
++              mdelay(50);
++
++              /* enable charger detection */
++              max77693_read_reg(regmap_muic,
++                      MAX77693_MUIC_REG_CDETCTRL1, &cdetctrl1);
++              cdetctrl1 |= (1 << 0);
++              max77693_write_reg(regmap_muic,
++                      MAX77693_MUIC_REG_CDETCTRL1, cdetctrl1);
++
++              /* enable charger interrupt */
++              max77693_write_reg(rdev->regmap,
++                      MAX77693_CHG_REG_CHG_INT_MASK, chg_int_state);
++              max77693_read_reg(rdev->regmap,
++                      MAX77693_CHG_REG_CHG_INT_MASK, &int_mask);
++      }
++
++      dev_info(&rdev->dev,
++              "INT_MASK(0x%x), CDETCTRL1(0x%x), CHG_CNFG_00(0x%x)\n",
++              int_mask, cdetctrl1, chg_cnfg_00);
++}
++
++/*
++ * max77693_muic_enable_powered_usb - Enable/disable usb feature on max77693
++ * @rdev: the instance for voltage/current regulator class device
++ * @enable: the state of USB feature (true: ON, false: OFF)
++ */
++static void max77693_muic_enable_usb(struct regulator_dev *rdev, int enable)
++{
++      dev_info(&rdev->dev, "enable(%d)\n", enable);
++
++      if (enable) {
++              /* OTG on, boost on */
++              max77693_write_reg(rdev->regmap,
++                      MAX77693_CHG_REG_CHG_CNFG_00, 0x05);
++
++              max77693_write_reg(rdev->regmap,
++                      MAX77693_CHG_REG_CHG_CNFG_02, 0x0E);
++      } else {
++              /* OTG off, boost off, (buck on) */
++              max77693_write_reg(rdev->regmap,
++                      MAX77693_CHG_REG_CHG_CNFG_00, 0x04);
++      }
++}
++
++static int max77693_usb_is_enabled(struct regulator_dev *rdev)
++{
++      struct regulator_desc *desc = rdev->desc;
++      int ret;
++
++      switch (desc->id) {
++      case MAX77693_USBHOST:
++              ret = max77693_muic_is_enable_otg(rdev);
++              break;
++      case MAX77693_USB:
++              ret = max77693_muic_is_enable_usb(rdev);
++              break;
++      default:
++              ret = -EINVAL;
++      }
++
++      return ret;
++}
++
++static int max77693_usb_enable(struct regulator_dev *rdev)
++{
++      struct regulator_desc *desc = rdev->desc;
++
++      switch (desc->id) {
++      case MAX77693_USBHOST:
++              max77693_muic_enable_otg(rdev, true);
++              break;
++      case MAX77693_USB:
++              max77693_muic_enable_usb(rdev, true);
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      return 0;
++}
++
++static int max77693_usb_disable(struct regulator_dev *rdev)
++{
++      struct regulator_desc *desc = rdev->desc;
++
++      switch (desc->id) {
++      case MAX77693_USBHOST:
++              max77693_muic_enable_otg(rdev, false);
++              break;
++      case MAX77693_USB:
++              max77693_muic_enable_usb(rdev, false);
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      return 0;
++}
++
++static struct regulator_ops max77693_safeout_ops = {
++      .list_voltage = max77693_list_voltage_safeout,
++      .is_enabled = max77693_reg_is_enabled,
++      .enable = max77693_reg_enable,
++      .disable = max77693_reg_disable,
++      .get_voltage = max77693_get_voltage,
++      .set_voltage = max77693_set_voltage_safeout,
++      .set_suspend_enable = max77693_reg_enable_suspend,
++      .set_suspend_disable = max77693_reg_disable_suspend,
++};
++
++static struct regulator_ops max77693_charger_ops = {
++      .is_enabled             = max77693_reg_is_enabled,
++      .enable                 = max77693_reg_enable,
++      .disable                = max77693_reg_disable,
++      .get_current_limit      = max77693_get_voltage,
++      .set_current_limit      = max77693_set_voltage,
++};
++
++static struct regulator_ops max77693_usb_ops = {
++      .is_enabled             = max77693_usb_is_enabled,
++      .enable                 = max77693_usb_enable,
++      .disable                = max77693_usb_disable,
++};
++
++static struct regulator_desc regulators[] = {
++      {
++              .name = "ESAFEOUT1",
++              .id = MAX77693_ESAFEOUT1,
++              .ops = &max77693_safeout_ops,
++              .type = REGULATOR_VOLTAGE,
++              .owner = THIS_MODULE,
++              .n_voltages = 4,
++      }, {
++              .name = "ESAFEOUT2",
++              .id = MAX77693_ESAFEOUT2,
++              .ops = &max77693_safeout_ops,
++              .type = REGULATOR_VOLTAGE,
++              .owner = THIS_MODULE,
++              .n_voltages = 4,
++      }, {
++              .name = "CHARGER",
++              .id = MAX77693_CHARGER,
++              .ops = &max77693_charger_ops,
++              .type = REGULATOR_CURRENT,
++              .owner = THIS_MODULE,
++      }, {
++              .name = "USBHOST",
++              .id = MAX77693_USBHOST,
++              .ops = &max77693_usb_ops,
++              .type = REGULATOR_CURRENT,
++              .owner = THIS_MODULE,
++      }, {
++              .name = "USB",
++              .id = MAX77693_USB,
++              .ops = &max77693_usb_ops,
++              .type = REGULATOR_CURRENT,
++              .owner = THIS_MODULE,
++      },
++};
++
++static __devinit int max77693_pmic_probe(struct platform_device *pdev)
++{
++      struct max77693_dev *iodev = dev_get_drvdata(pdev->dev.parent);
++      struct max77693_platform_data *pdata = dev_get_platdata(iodev->dev);
++      struct max77693_data *max77693;
++      int i, ret, size;
++      struct regulator_config config = {};
++
++      dev_info(&pdev->dev, "%s\n", __func__);
++      if (!pdata) {
++              pr_info("[%s:%d] !pdata\n", __FILE__, __LINE__);
++              dev_err(pdev->dev.parent, "No platform init data supplied.\n");
++              return -ENODEV;
++      }
++
++      max77693 = devm_kzalloc(&pdev->dev, sizeof(struct max77693_data),
++                              GFP_KERNEL);
++      if (!max77693) {
++              pr_info("[%s:%d] if (!max77693)\n", __FILE__, __LINE__);
++              return -ENOMEM;
++      }
++      size = sizeof(struct regulator_dev *) * pdata->num_regulators;
++      max77693->rdev =devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
++      if (!max77693->rdev) {
++              pr_info("[%s:%d] if (!max77693->rdev)\n", __FILE__, __LINE__);
++              return -ENOMEM;
++      }
++
++      max77693->dev = &pdev->dev;
++      max77693->iodev = iodev;
++      max77693->num_regulators = pdata->num_regulators;
++
++      config.dev = &pdev->dev;
++      config.regmap = iodev->regmap;
++      config.driver_data = max77693;
++      platform_set_drvdata(pdev, max77693);
++
++      pr_info("[%s:%d] pdata->num_regulators:%d\n", __FILE__, __LINE__,
++              pdata->num_regulators);
++      for (i = 0; i < pdata->num_regulators; i++) {
++              const struct voltage_map_desc *desc;
++              int id = pdata->regulators[i].id;
++
++              config.init_data = pdata->regulators[i].initdata;
++
++              pr_info("[%s:%d] for in pdata->num_regulators:%d\n", __FILE__,
++                      __LINE__, pdata->num_regulators);
++              desc = reg_voltage_map[id];
++              if (id == MAX77693_ESAFEOUT1 || id == MAX77693_ESAFEOUT2)
++                      regulators[id].n_voltages = 4;
++
++              max77693->rdev[i] = regulator_register(&regulators[id], &config);
++              if (IS_ERR(max77693->rdev[i])) {
++                      ret = PTR_ERR(max77693->rdev[i]);
++                      dev_err(max77693->dev, "regulator init failed for %d\n",
++                              id);
++                      max77693->rdev[i] = NULL;
++                      goto err;
++              }
++      }
++
++      return 0;
++ err:
++      pr_info("[%s:%d] err:\n", __FILE__, __LINE__);
++      while (--i >= 0)
++              regulator_unregister(max77693->rdev[i]);
++
++      return ret;
++}
++
++static int __devexit max77693_pmic_remove(struct platform_device *pdev)
++{
++      struct max77693_data *max77693 = platform_get_drvdata(pdev);
++      struct regulator_dev **rdev = max77693->rdev;
++      int i;
++      dev_info(&pdev->dev, "%s\n", __func__);
++      for (i = 0; i < max77693->num_regulators; i++)
++              if (rdev[i])
++                      regulator_unregister(rdev[i]);
++
++      return 0;
++}
++
++static const struct platform_device_id max77693_pmic_id[] = {
++      {"max77693-safeout", 0},
++      {},
++};
++
++MODULE_DEVICE_TABLE(platform, max77693_pmic_id);
++
++static struct platform_driver max77693_pmic_driver = {
++      .driver = {
++                 .name = "max77693-safeout",
++                 .owner = THIS_MODULE,
++                 },
++      .probe = max77693_pmic_probe,
++      .remove = __devexit_p(max77693_pmic_remove),
++      .id_table = max77693_pmic_id,
++};
++
++static int __init max77693_pmic_init(void)
++{
++      return platform_driver_register(&max77693_pmic_driver);
++}
++#ifdef CONFIG_FAST_RESUME
++beforeresume_initcall(max77693_pmic_init);
++#else
++subsys_initcall(max77693_pmic_init);
++#endif
++
++static void __exit max77693_pmic_cleanup(void)
++{
++      platform_driver_unregister(&max77693_pmic_driver);
++}
++
++module_exit(max77693_pmic_cleanup);
++
++MODULE_DESCRIPTION("MAXIM 77693 Regulator Driver");
++MODULE_AUTHOR("Sukdong Kim <Sukdong.Kim@samsung.com>");
++MODULE_LICENSE("GPL");
+diff --git a/include/linux/mfd/max77693-private.h b/include/linux/mfd/max77693-private.h
+index 1aa4f13..e005fb2 100644
+--- a/include/linux/mfd/max77693-private.h
++++ b/include/linux/mfd/max77693-private.h
+@@ -238,6 +238,20 @@ enum max77693_haptic_reg {
+       MAX77693_HAPTIC_REG_END,
+ };
++/* MAX77693 CHG_CNFG_00 register */
++#define CHG_CNFG_00_MODE_SHIFT                0
++#define CHG_CNFG_00_CHG_SHIFT         0
++#define CHG_CNFG_00_OTG_SHIFT         1
++#define CHG_CNFG_00_BUCK_SHIFT                2
++#define CHG_CNFG_00_BOOST_SHIFT               3
++#define CHG_CNFG_00_DIS_MUIC_CTRL_SHIFT       5
++#define CHG_CNFG_00_MODE_MASK         (0xf << CHG_CNFG_00_MODE_SHIFT)
++#define CHG_CNFG_00_CHG_MASK          (1 << CHG_CNFG_00_CHG_SHIFT)
++#define CHG_CNFG_00_OTG_MASK          (1 << CHG_CNFG_00_OTG_SHIFT)
++#define CHG_CNFG_00_BUCK_MASK         (1 << CHG_CNFG_00_BUCK_SHIFT)
++#define CHG_CNFG_00_BOOST_MASK                (1 << CHG_CNFG_00_BOOST_SHIFT)
++#define CHG_CNFG_00_DIS_MUIC_CTRL_MASK        (1 << CHG_CNFG_00_DIS_MUIC_CTRL_SHIFT)
++
+ enum max77693_irq_source {
+       LED_INT = 0,
+       TOPSYS_INT,
+diff --git a/include/linux/mfd/max77693.h b/include/linux/mfd/max77693.h
+index 3109a6c..77d8207 100644
+--- a/include/linux/mfd/max77693.h
++++ b/include/linux/mfd/max77693.h
+@@ -30,6 +30,25 @@
+ #ifndef __LINUX_MFD_MAX77693_H
+ #define __LINUX_MFD_MAX77693_H
++/* MAX77686 regulator IDs */
++enum max77693_regulators {
++      MAX77693_ESAFEOUT1 = 0,
++      MAX77693_ESAFEOUT2,
++
++      MAX77693_CHARGER,
++
++      MAX77693_USBHOST,
++      MAX77693_USB,
++
++      MAX77693_REG_MAX,
++};
++
++struct max77693_regulator_data {
++      int id;
++      struct regulator_init_data *initdata;
++      struct device_node *of_node;
++};
++
+ struct max77693_reg_data {
+       u8 addr;
+       u8 data;
+@@ -50,9 +69,17 @@ struct max77693_muic_platform_data {
+ };
+ struct max77693_platform_data {
++      /* IRQ */
++      int irq_base;
++      int irq_gpio;
+       int wakeup;
++      struct max77693_muic_data *muic;
++      bool (*is_default_uart_path_cp) (void);
++      struct max77693_regulator_data *regulators;
++      int num_regulators;
+       /* muic data */
+       struct max77693_muic_platform_data *muic_data;
+ };
++
+ #endif        /* __LINUX_MFD_MAX77693_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0059-regulator-Remove-const-from-declation-of-reg_desc-in.patch b/patches.tizen/0059-regulator-Remove-const-from-declation-of-reg_desc-in.patch
new file mode 100644 (file)
index 0000000..d0b3ddf
--- /dev/null
@@ -0,0 +1,28 @@
+From a3da11597a364184fe87c05c3bd188a5a03aa103 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Thu, 7 Feb 2013 15:05:27 +0900
+Subject: [PATCH 0059/1302] regulator: Remove const from declation of reg_desc
+ in regulator_dev.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/regulator/driver.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
+index 6700cc9..18e961c 100644
+--- a/include/linux/regulator/driver.h
++++ b/include/linux/regulator/driver.h
+@@ -279,7 +279,7 @@ struct regulator_config {
+  * no other direct access).
+  */
+ struct regulator_dev {
+-      const struct regulator_desc *desc;
++      struct regulator_desc *desc;
+       int exclusive;
+       u32 use_count;
+       u32 open_count;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0060-regulator-max77693-Remove-no-longer-supported-__dev-.patch b/patches.tizen/0060-regulator-max77693-Remove-no-longer-supported-__dev-.patch
new file mode 100644 (file)
index 0000000..b083098
--- /dev/null
@@ -0,0 +1,57 @@
+From 6a85cf9b89737284e3839c86760e3379bf77ed91 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 8 Feb 2013 19:26:33 +0100
+Subject: [PATCH 0060/1302] regulator: max77693: Remove no longer supported
+ __dev* attributes
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This patch fixes following build error:
+
+drivers/regulator/max77693.c:673: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘int’
+drivers/regulator/max77693.c:743: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘max77693_pmic_remove’
+drivers/regulator/max77693.c:768: error: ‘max77693_pmic_probe’ undeclared here (not in a function)
+drivers/regulator/max77693.c:769: error: implicit declaration of function ‘__devexit_p’
+drivers/regulator/max77693.c:769: error: ‘max77693_pmic_remove’ undeclared here (not in a function)
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/regulator/max77693.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/regulator/max77693.c b/drivers/regulator/max77693.c
+index 85776b2..0720ea8 100644
+--- a/drivers/regulator/max77693.c
++++ b/drivers/regulator/max77693.c
+@@ -670,7 +670,7 @@ static struct regulator_desc regulators[] = {
+       },
+ };
+-static __devinit int max77693_pmic_probe(struct platform_device *pdev)
++static int max77693_pmic_probe(struct platform_device *pdev)
+ {
+       struct max77693_dev *iodev = dev_get_drvdata(pdev->dev.parent);
+       struct max77693_platform_data *pdata = dev_get_platdata(iodev->dev);
+@@ -740,7 +740,7 @@ static __devinit int max77693_pmic_probe(struct platform_device *pdev)
+       return ret;
+ }
+-static int __devexit max77693_pmic_remove(struct platform_device *pdev)
++static int max77693_pmic_remove(struct platform_device *pdev)
+ {
+       struct max77693_data *max77693 = platform_get_drvdata(pdev);
+       struct regulator_dev **rdev = max77693->rdev;
+@@ -766,7 +766,7 @@ static struct platform_driver max77693_pmic_driver = {
+                  .owner = THIS_MODULE,
+                  },
+       .probe = max77693_pmic_probe,
+-      .remove = __devexit_p(max77693_pmic_remove),
++      .remove = max77693_pmic_remove,
+       .id_table = max77693_pmic_id,
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0061-drivers-dma-contiguous-clean-source-code-and-prepare.patch b/patches.tizen/0061-drivers-dma-contiguous-clean-source-code-and-prepare.patch
new file mode 100644 (file)
index 0000000..474ded6
--- /dev/null
@@ -0,0 +1,374 @@
+From 367c289a22ce314d28d39e5a42fc161f500f97a5 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Mon, 29 Jul 2013 14:31:45 +0200
+Subject: [PATCH 0061/1302] drivers: dma-contiguous: clean source code and
+ prepare for device tree
+
+This patch cleans the initialization of dma contiguous framework. The
+all-in-one dma_declare_contiguous() function is now separated into
+dma_contiguous_reserve_area() which only steals the the memory from
+memblock allocator and dma_contiguous_add_device() function, which
+assigns given device to the specified reserved memory area. This improves
+the flexibility in defining contiguous memory areas and assigning device
+to them, because now it is possible to assign more than one device to
+the given contiguous memory area. Such split in initialization procedure
+is also required for upcoming device tree support.
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Acked-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/include/asm/dma-contiguous.h |   1 -
+ arch/x86/include/asm/dma-contiguous.h |   1 -
+ drivers/base/dma-contiguous.c         | 119 +++++++++++++---------------------
+ include/asm-generic/dma-contiguous.h  |  28 --------
+ include/linux/dma-contiguous.h        |  55 +++++++++++++++-
+ 5 files changed, 97 insertions(+), 107 deletions(-)
+ delete mode 100644 include/asm-generic/dma-contiguous.h
+
+diff --git a/arch/arm/include/asm/dma-contiguous.h b/arch/arm/include/asm/dma-contiguous.h
+index 3ed37b4..63277bc 100644
+--- a/arch/arm/include/asm/dma-contiguous.h
++++ b/arch/arm/include/asm/dma-contiguous.h
+@@ -5,7 +5,6 @@
+ #ifdef CONFIG_CMA
+ #include <linux/types.h>
+-#include <asm-generic/dma-contiguous.h>
+ void dma_contiguous_early_fixup(phys_addr_t base, unsigned long size);
+diff --git a/arch/x86/include/asm/dma-contiguous.h b/arch/x86/include/asm/dma-contiguous.h
+index c092416..b4b38ba 100644
+--- a/arch/x86/include/asm/dma-contiguous.h
++++ b/arch/x86/include/asm/dma-contiguous.h
+@@ -4,7 +4,6 @@
+ #ifdef __KERNEL__
+ #include <linux/types.h>
+-#include <asm-generic/dma-contiguous.h>
+ static inline void
+ dma_contiguous_early_fixup(phys_addr_t base, unsigned long size) { }
+diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
+index 0ca5442..4b94c91 100644
+--- a/drivers/base/dma-contiguous.c
++++ b/drivers/base/dma-contiguous.c
+@@ -96,7 +96,7 @@ static inline __maybe_unused phys_addr_t cma_early_percent_memory(void)
+ #endif
+ /**
+- * dma_contiguous_reserve() - reserve area for contiguous memory handling
++ * dma_contiguous_reserve() - reserve area(s) for contiguous memory handling
+  * @limit: End address of the reserved memory (optional, 0 for any).
+  *
+  * This function reserves memory from early allocator. It should be
+@@ -124,22 +124,29 @@ void __init dma_contiguous_reserve(phys_addr_t limit)
+ #endif
+       }
+-      if (selected_size) {
++      if (selected_size && !dma_contiguous_default_area) {
+               pr_debug("%s: reserving %ld MiB for global area\n", __func__,
+                        (unsigned long)selected_size / SZ_1M);
+-              dma_declare_contiguous(NULL, selected_size, 0, limit);
++              dma_contiguous_reserve_area(selected_size, 0, limit,
++                                          &dma_contiguous_default_area);
+       }
+ };
+ static DEFINE_MUTEX(cma_mutex);
+-static __init int cma_activate_area(unsigned long base_pfn, unsigned long count)
++static __init int cma_activate_area(struct cma *cma)
+ {
+-      unsigned long pfn = base_pfn;
+-      unsigned i = count >> pageblock_order;
++      int bitmap_size = BITS_TO_LONGS(cma->count) * sizeof(long);
++      unsigned long base_pfn = cma->base_pfn, pfn = base_pfn;
++      unsigned i = cma->count >> pageblock_order;
+       struct zone *zone;
++      cma->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
++
++      if (!cma->bitmap)
++              return -ENOMEM;
++
+       WARN_ON_ONCE(!pfn_valid(pfn));
+       zone = page_zone(pfn_to_page(pfn));
+@@ -153,92 +160,53 @@ static __init int cma_activate_area(unsigned long base_pfn, unsigned long count)
+               }
+               init_cma_reserved_pageblock(pfn_to_page(base_pfn));
+       } while (--i);
+-      return 0;
+-}
+-
+-static __init struct cma *cma_create_area(unsigned long base_pfn,
+-                                   unsigned long count)
+-{
+-      int bitmap_size = BITS_TO_LONGS(count) * sizeof(long);
+-      struct cma *cma;
+-      int ret = -ENOMEM;
+-
+-      pr_debug("%s(base %08lx, count %lx)\n", __func__, base_pfn, count);
+-
+-      cma = kmalloc(sizeof *cma, GFP_KERNEL);
+-      if (!cma)
+-              return ERR_PTR(-ENOMEM);
+-
+-      cma->base_pfn = base_pfn;
+-      cma->count = count;
+-      cma->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
+-      if (!cma->bitmap)
+-              goto no_mem;
+-
+-      ret = cma_activate_area(base_pfn, count);
+-      if (ret)
+-              goto error;
+-
+-      pr_debug("%s: returned %p\n", __func__, (void *)cma);
+-      return cma;
+-
+-error:
+-      kfree(cma->bitmap);
+-no_mem:
+-      kfree(cma);
+-      return ERR_PTR(ret);
++      return 0;
+ }
+-static struct cma_reserved {
+-      phys_addr_t start;
+-      unsigned long size;
+-      struct device *dev;
+-} cma_reserved[MAX_CMA_AREAS] __initdata;
+-static unsigned cma_reserved_count __initdata;
++static struct cma cma_areas[MAX_CMA_AREAS];
++static unsigned cma_area_count;
+ static int __init cma_init_reserved_areas(void)
+ {
+-      struct cma_reserved *r = cma_reserved;
+-      unsigned i = cma_reserved_count;
+-
+-      pr_debug("%s()\n", __func__);
++      int i;
+-      for (; i; --i, ++r) {
+-              struct cma *cma;
+-              cma = cma_create_area(PFN_DOWN(r->start),
+-                                    r->size >> PAGE_SHIFT);
+-              if (!IS_ERR(cma))
+-                      dev_set_cma_area(r->dev, cma);
++      for (i = 0; i < cma_area_count; i++) {
++              int ret = cma_activate_area(&cma_areas[i]);
++              if (ret)
++                      return ret;
+       }
++
+       return 0;
+ }
+ core_initcall(cma_init_reserved_areas);
+ /**
+- * dma_declare_contiguous() - reserve area for contiguous memory handling
+- *                          for particular device
+- * @dev:   Pointer to device structure.
+- * @size:  Size of the reserved memory.
+- * @base:  Start address of the reserved memory (optional, 0 for any).
++ * dma_contiguous_reserve_area() - reserve custom contiguous area
++ * @size: Size of the reserved area (in bytes),
++ * @base: Base address of the reserved area optional, use 0 for any
+  * @limit: End address of the reserved memory (optional, 0 for any).
++ * @res_cma: Pointer to store the created cma region.
+  *
+- * This function reserves memory for specified device. It should be
+- * called by board specific code when early allocator (memblock or bootmem)
+- * is still activate.
++ * This function reserves memory from early allocator. It should be
++ * called by arch specific code once the early allocator (memblock or bootmem)
++ * has been activated and all other subsystems have already allocated/reserved
++ * memory. This function allows to create custom reserved areas for specific
++ * devices.
+  */
+-int __init dma_declare_contiguous(struct device *dev, phys_addr_t size,
+-                                phys_addr_t base, phys_addr_t limit)
++int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
++                                     phys_addr_t limit, struct cma **res_cma)
+ {
+-      struct cma_reserved *r = &cma_reserved[cma_reserved_count];
++      struct cma *cma = &cma_areas[cma_area_count];
+       phys_addr_t alignment;
++      int ret = 0;
+       pr_debug("%s(size %lx, base %08lx, limit %08lx)\n", __func__,
+                (unsigned long)size, (unsigned long)base,
+                (unsigned long)limit);
+       /* Sanity checks */
+-      if (cma_reserved_count == ARRAY_SIZE(cma_reserved)) {
++      if (cma_area_count == ARRAY_SIZE(cma_areas)) {
+               pr_err("Not enough slots for CMA reserved regions!\n");
+               return -ENOSPC;
+       }
+@@ -256,7 +224,7 @@ int __init dma_declare_contiguous(struct device *dev, phys_addr_t size,
+       if (base) {
+               if (memblock_is_region_reserved(base, size) ||
+                   memblock_reserve(base, size) < 0) {
+-                      base = -EBUSY;
++                      ret = -EBUSY;
+                       goto err;
+               }
+       } else {
+@@ -266,7 +234,7 @@ int __init dma_declare_contiguous(struct device *dev, phys_addr_t size,
+                */
+               phys_addr_t addr = __memblock_alloc_base(size, alignment, limit);
+               if (!addr) {
+-                      base = -ENOMEM;
++                      ret = -ENOMEM;
+                       goto err;
+               } else {
+                       base = addr;
+@@ -277,10 +245,11 @@ int __init dma_declare_contiguous(struct device *dev, phys_addr_t size,
+        * Each reserved area must be initialised later, when more kernel
+        * subsystems (like slab allocator) are available.
+        */
+-      r->start = base;
+-      r->size = size;
+-      r->dev = dev;
+-      cma_reserved_count++;
++      cma->base_pfn = PFN_DOWN(base);
++      cma->count = size >> PAGE_SHIFT;
++      *res_cma = cma;
++      cma_area_count++;
++
+       pr_info("CMA: reserved %ld MiB at %08lx\n", (unsigned long)size / SZ_1M,
+               (unsigned long)base);
+@@ -289,7 +258,7 @@ int __init dma_declare_contiguous(struct device *dev, phys_addr_t size,
+       return 0;
+ err:
+       pr_err("CMA: failed to reserve %ld MiB\n", (unsigned long)size / SZ_1M);
+-      return base;
++      return ret;
+ }
+ /**
+diff --git a/include/asm-generic/dma-contiguous.h b/include/asm-generic/dma-contiguous.h
+deleted file mode 100644
+index 294b1e7..0000000
+--- a/include/asm-generic/dma-contiguous.h
++++ /dev/null
+@@ -1,28 +0,0 @@
+-#ifndef ASM_DMA_CONTIGUOUS_H
+-#define ASM_DMA_CONTIGUOUS_H
+-
+-#ifdef __KERNEL__
+-#ifdef CONFIG_CMA
+-
+-#include <linux/device.h>
+-#include <linux/dma-contiguous.h>
+-
+-static inline struct cma *dev_get_cma_area(struct device *dev)
+-{
+-      if (dev && dev->cma_area)
+-              return dev->cma_area;
+-      return dma_contiguous_default_area;
+-}
+-
+-static inline void dev_set_cma_area(struct device *dev, struct cma *cma)
+-{
+-      if (dev)
+-              dev->cma_area = cma;
+-      if (!dev && !dma_contiguous_default_area)
+-              dma_contiguous_default_area = cma;
+-}
+-
+-#endif
+-#endif
+-
+-#endif
+diff --git a/include/linux/dma-contiguous.h b/include/linux/dma-contiguous.h
+index 01b5c84..9439659 100644
+--- a/include/linux/dma-contiguous.h
++++ b/include/linux/dma-contiguous.h
+@@ -67,9 +67,48 @@ struct device;
+ extern struct cma *dma_contiguous_default_area;
++static inline struct cma *dev_get_cma_area(struct device *dev)
++{
++      if (dev && dev->cma_area)
++              return dev->cma_area;
++      return dma_contiguous_default_area;
++}
++
++static inline void dev_set_cma_area(struct device *dev, struct cma *cma)
++{
++      if (dev)
++              dev->cma_area = cma;
++}
++
+ void dma_contiguous_reserve(phys_addr_t addr_limit);
+-int dma_declare_contiguous(struct device *dev, phys_addr_t size,
+-                         phys_addr_t base, phys_addr_t limit);
++
++int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
++                                     phys_addr_t limit, struct cma **res_cma);
++
++/**
++ * dma_declare_contiguous() - reserve area for contiguous memory handling
++ *                          for particular device
++ * @dev:   Pointer to device structure.
++ * @size:  Size of the reserved memory.
++ * @base:  Start address of the reserved memory (optional, 0 for any).
++ * @limit: End address of the reserved memory (optional, 0 for any).
++ *
++ * This function reserves memory for specified device. It should be
++ * called by board specific code when early allocator (memblock or bootmem)
++ * is still activate.
++ */
++
++static inline int dma_declare_contiguous(struct device *dev, phys_addr_t size,
++                                       phys_addr_t base, phys_addr_t limit)
++{
++      struct cma *cma;
++      int ret;
++      ret = dma_contiguous_reserve_area(size, base, limit, &cma);
++      if (ret == 0)
++              dev_set_cma_area(dev, cma);
++
++      return ret;
++}
+ struct page *dma_alloc_from_contiguous(struct device *dev, int count,
+                                      unsigned int order);
+@@ -80,8 +119,20 @@ bool dma_release_from_contiguous(struct device *dev, struct page *pages,
+ #define MAX_CMA_AREAS (0)
++static inline struct cma *dev_get_cma_area(struct device *dev)
++{
++      return NULL;
++}
++
++static inline void dev_set_cma_area(struct device *dev, struct cma *cma) { }
++
+ static inline void dma_contiguous_reserve(phys_addr_t limit) { }
++static inline int dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
++                                     phys_addr_t limit, struct cma **res_cma) {
++      return -ENOSYS;
++}
++
+ static inline
+ int dma_declare_contiguous(struct device *dev, phys_addr_t size,
+                          phys_addr_t base, phys_addr_t limit)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0062-drivers-of-add-function-to-scan-fdt-nodes-given-by-p.patch b/patches.tizen/0062-drivers-of-add-function-to-scan-fdt-nodes-given-by-p.patch
new file mode 100644 (file)
index 0000000..6aef65f
--- /dev/null
@@ -0,0 +1,123 @@
+From 2b839619fd9dbf284c7f0108358ddce411b4736a Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Thu, 27 Jun 2013 10:32:15 +0200
+Subject: [PATCH 0062/1302] drivers: of: add function to scan fdt nodes given
+ by path
+
+Add a function to scan the flattened device-tree starting from the
+node given by the path. It is used to extract information (like reserved
+memory), which is required on early boot before we can unflatten the tree.
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Acked-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/of/fdt.c       | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/of_fdt.h |  3 ++
+ 2 files changed, 79 insertions(+)
+
+diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
+index 1187737..a829c28 100644
+--- a/drivers/of/fdt.c
++++ b/drivers/of/fdt.c
+@@ -545,6 +545,82 @@ int __init of_flat_dt_match(unsigned long node, const char *const *compat)
+       return of_fdt_match(initial_boot_params, node, compat);
+ }
++struct fdt_scan_status {
++      const char *name;
++      int namelen;
++      int depth;
++      int found;
++      int (*iterator)(unsigned long node, const char *uname, int depth, void *data);
++      void *data;
++};
++
++/**
++ * fdt_scan_node_by_path - iterator for of_scan_flat_dt_by_path function
++ */
++static int __init fdt_scan_node_by_path(unsigned long node, const char *uname,
++                                      int depth, void *data)
++{
++      struct fdt_scan_status *st = data;
++
++      /*
++       * if scan at the requested fdt node has been completed,
++       * return -ENXIO to abort further scanning
++       */
++      if (depth <= st->depth)
++              return -ENXIO;
++
++      /* requested fdt node has been found, so call iterator function */
++      if (st->found)
++              return st->iterator(node, uname, depth, st->data);
++
++      /* check if scanning automata is entering next level of fdt nodes */
++      if (depth == st->depth + 1 &&
++          strncmp(st->name, uname, st->namelen) == 0 &&
++          uname[st->namelen] == 0) {
++              st->depth += 1;
++              if (st->name[st->namelen] == 0) {
++                      st->found = 1;
++              } else {
++                      const char *next = st->name + st->namelen + 1;
++                      st->name = next;
++                      st->namelen = strcspn(next, "/");
++              }
++              return 0;
++      }
++
++      /* scan next fdt node */
++      return 0;
++}
++
++/**
++ * of_scan_flat_dt_by_path - scan flattened tree blob and call callback on each
++ *                         child of the given path.
++ * @path: path to start searching for children
++ * @it: callback function
++ * @data: context data pointer
++ *
++ * This function is used to scan the flattened device-tree starting from the
++ * node given by path. It is used to extract information (like reserved
++ * memory), which is required on ealy boot before we can unflatten the tree.
++ */
++int __init of_scan_flat_dt_by_path(const char *path,
++      int (*it)(unsigned long node, const char *name, int depth, void *data),
++      void *data)
++{
++      struct fdt_scan_status st = {path, 0, -1, 0, it, data};
++      int ret = 0;
++
++      if (initial_boot_params)
++                ret = of_scan_flat_dt(fdt_scan_node_by_path, &st);
++
++      if (!st.found)
++              return -ENOENT;
++      else if (ret == -ENXIO) /* scan has been completed */
++              return 0;
++      else
++              return ret;
++}
++
+ #ifdef CONFIG_BLK_DEV_INITRD
+ /**
+  * early_init_dt_check_for_initrd - Decode initrd location from flat tree
+diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
+index ed136ad..19f26f8 100644
+--- a/include/linux/of_fdt.h
++++ b/include/linux/of_fdt.h
+@@ -90,6 +90,9 @@ extern void *of_get_flat_dt_prop(unsigned long node, const char *name,
+ extern int of_flat_dt_is_compatible(unsigned long node, const char *name);
+ extern int of_flat_dt_match(unsigned long node, const char *const *matches);
+ extern unsigned long of_get_flat_dt_root(void);
++extern int of_scan_flat_dt_by_path(const char *path,
++      int (*it)(unsigned long node, const char *name, int depth, void *data),
++      void *data);
+ extern int early_init_dt_scan_chosen(unsigned long node, const char *uname,
+                                    int depth, void *data);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0063-drivers-of-add-initialization-code-for-dma-reserved-.patch b/patches.tizen/0063-drivers-of-add-initialization-code-for-dma-reserved-.patch
new file mode 100644 (file)
index 0000000..7ddcccc
--- /dev/null
@@ -0,0 +1,476 @@
+From fed4a78691e457cc623545dec81fb759cd45a402 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Mon, 29 Jul 2013 14:09:55 +0200
+Subject: [PATCH 0063/1302] drivers: of: add initialization code for dma
+ reserved memory
+
+This patch adds device tree support for contiguous and reserved memory
+regions defined in device tree.
+
+Large memory blocks can be reliably reserved only during early boot.
+This must happen before the whole memory management subsystem is
+initialized, because we need to ensure that the given contiguous blocks
+are not yet allocated by kernel. Also it must happen before kernel
+mappings for the whole low memory are created, to ensure that there will
+be no mappings (for reserved blocks) or mapping with special properties
+can be created (for CMA blocks). This all happens before device tree
+structures are unflattened, so we need to get reserved memory layout
+directly from fdt.
+
+Later, those reserved memory regions are assigned to devices on each
+device structure initialization.
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Acked-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/devicetree/bindings/memory.txt | 166 +++++++++++++++++++++++++
+ drivers/of/Kconfig                           |   6 +
+ drivers/of/Makefile                          |   1 +
+ drivers/of/of_reserved_mem.c                 | 175 +++++++++++++++++++++++++++
+ drivers/of/platform.c                        |   5 +
+ include/linux/of_reserved_mem.h              |  14 +++
+ 6 files changed, 367 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/memory.txt
+ create mode 100644 drivers/of/of_reserved_mem.c
+ create mode 100644 include/linux/of_reserved_mem.h
+
+diff --git a/Documentation/devicetree/bindings/memory.txt b/Documentation/devicetree/bindings/memory.txt
+new file mode 100644
+index 0000000..90e9627
+--- /dev/null
++++ b/Documentation/devicetree/bindings/memory.txt
+@@ -0,0 +1,166 @@
++*** Memory binding ***
++
++The /memory node provides basic information about the address and size
++of the physical memory. This node is usually filled or updated by the
++bootloader, depending on the actual memory configuration of the given
++hardware.
++
++The memory layout is described by the following node:
++
++/ {
++      #address-cells = <(n)>;
++      #size-cells = <(m)>;
++      memory {
++              device_type = "memory";
++              reg =  <(baseaddr1) (size1)
++                      (baseaddr2) (size2)
++                      ...
++                      (baseaddrN) (sizeN)>;
++      };
++      ...
++};
++
++A memory node follows the typical device tree rules for "reg" property:
++n:            number of cells used to store base address value
++m:            number of cells used to store size value
++baseaddrX:    defines a base address of the defined memory bank
++sizeX:                the size of the defined memory bank
++
++
++More than one memory bank can be defined.
++
++
++*** Reserved memory regions ***
++
++In /memory/reserved-memory node one can create additional nodes
++describing particular reserved (excluded from normal use) memory
++regions. Such memory regions are usually designed for the special usage
++by various device drivers. A good example are contiguous memory
++allocations or memory sharing with other operating system on the same
++hardware board. Those special memory regions might depend on the board
++configuration and devices used on the target system.
++
++Parameters for each memory region can be encoded into the device tree
++with the following convention:
++
++[(label):] (name) {
++      compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++      reg = <(address) (size)>;
++      (linux,default-contiguous-region);
++};
++
++compatible:   "linux,contiguous-memory-region" - enables binding of this
++              region to Contiguous Memory Allocator (special region for
++              contiguous memory allocations, shared with movable system
++              memory, Linux kernel-specific), alternatively if
++              "reserved-memory-region" - compatibility is defined, given
++              region is assigned for exclusive usage for by the respective
++              devices
++
++reg:          standard property defining the base address and size of
++              the memory region
++
++linux,default-contiguous-region: property indicating that the region
++              is the default region for all contiguous memory
++              allocations, Linux specific (optional)
++
++It is optional to specify the base address, so if one wants to use
++autoconfiguration of the base address, '0' can be specified as a base
++address in the 'reg' property.
++
++The /memory/reserved-memory node must contain the same #address-cells
++and #size-cells value as the root node.
++
++
++*** Device node's properties ***
++
++Once regions in the /memory/reserved-memory node have been defined, they
++can be assigned to device nodes to enable respective device drivers to
++access them. The following properties are defined:
++
++memory-region = <&phandle_to_defined_region>;
++
++This property indicates that the device driver should use the memory
++region pointed by the given phandle.
++
++
++*** Example ***
++
++This example defines a memory consisting of 4 memory banks. 3 contiguous
++regions are defined for Linux kernel, one default of all device drivers
++(named contig_mem, placed at 0x72000000, 64MiB), one dedicated to the
++framebuffer device (labelled display_mem, placed at 0x78000000, 8MiB)
++and one for multimedia processing (labelled multimedia_mem, placed at
++0x77000000, 64MiB). 'display_mem' region is then assigned to fb@12300000
++device for DMA memory allocations (Linux kernel drivers will use CMA is
++available or dma-exclusive usage otherwise). 'multimedia_mem' is
++assigned to scaler@12500000 and codec@12600000 devices for contiguous
++memory allocations when CMA driver is enabled.
++
++The reason for creating a separate region for framebuffer device is to
++match the framebuffer base address to the one configured by bootloader,
++so once Linux kernel drivers starts no glitches on the displayed boot
++logo appears. Scaller and codec drivers should share the memory
++allocations.
++
++/ {
++      #address-cells = <1>;
++      #size-cells = <1>;
++
++      /* ... */
++
++      memory {
++              reg =  <0x40000000 0x10000000
++                      0x50000000 0x10000000
++                      0x60000000 0x10000000
++                      0x70000000 0x10000000>;
++
++              reserved-memory {
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      /*
++                       * global autoconfigured region for contiguous allocations
++                       * (used only with Contiguous Memory Allocator)
++                       */
++                      contig_region@0 {
++                              compatible = "linux,contiguous-memory-region";
++                              reg = <0x0 0x4000000>;
++                              linux,default-contiguous-region;
++                      };
++
++                      /*
++                       * special region for framebuffer
++                       */
++                      display_mem: region@78000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x78000000 0x800000>;
++                      };
++
++                      /*
++                       * special region for multimedia processing devices
++                       */
++                      multimedia_mem: region@77000000 {
++                              compatible = "linux,contiguous-memory-region";
++                              reg = <0x77000000 0x4000000>;
++                      };
++              };
++      };
++
++      /* ... */
++
++      fb0: fb@12300000 {
++              status = "okay";
++              memory-region = <&display_mem>;
++      };
++
++      scaler: scaler@12500000 {
++              status = "okay";
++              memory-region = <&multimedia_mem>;
++      };
++
++      codec: codec@12600000 {
++              status = "okay";
++              memory-region = <&multimedia_mem>;
++      };
++};
+diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
+index d37bfcf..be0c62d 100644
+--- a/drivers/of/Kconfig
++++ b/drivers/of/Kconfig
+@@ -83,4 +83,10 @@ config OF_MTD
+       depends on MTD
+       def_bool y
++config OF_RESERVED_MEM
++      depends on CMA || (HAVE_GENERIC_DMA_COHERENT && HAVE_MEMBLOCK)
++      def_bool y
++      help
++        Initialization code for DMA reserved memory
++
+ endmenu # OF
+diff --git a/drivers/of/Makefile b/drivers/of/Makefile
+index e027f44..8098b4d 100644
+--- a/drivers/of/Makefile
++++ b/drivers/of/Makefile
+@@ -11,3 +11,4 @@ obj-$(CONFIG_OF_MDIO)        += of_mdio.o
+ obj-$(CONFIG_OF_PCI)  += of_pci.o
+ obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
+ obj-$(CONFIG_OF_MTD)  += of_mtd.o
++obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
+diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
+new file mode 100644
+index 0000000..95563d33
+--- /dev/null
++++ b/drivers/of/of_reserved_mem.c
+@@ -0,0 +1,175 @@
++/*
++ * Device tree based initialization code for reserved memory.
++ *
++ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
++ *            http://www.samsung.com
++ * Author: Marek Szyprowski <m.szyprowski@samsung.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 optional) any later version of the license.
++ */
++
++#include <asm/dma-contiguous.h>
++
++#include <linux/memblock.h>
++#include <linux/err.h>
++#include <linux/of.h>
++#include <linux/of_fdt.h>
++#include <linux/of_platform.h>
++#include <linux/mm.h>
++#include <linux/sizes.h>
++#include <linux/mm_types.h>
++#include <linux/dma-contiguous.h>
++#include <linux/dma-mapping.h>
++#include <linux/of_reserved_mem.h>
++
++#define MAX_RESERVED_REGIONS  16
++struct reserved_mem {
++      phys_addr_t             base;
++      unsigned long           size;
++      struct cma              *cma;
++      char                    name[32];
++};
++static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
++static int reserved_mem_count;
++
++static int __init fdt_scan_reserved_mem(unsigned long node, const char *uname,
++                                      int depth, void *data)
++{
++      struct reserved_mem *rmem = &reserved_mem[reserved_mem_count];
++      phys_addr_t base, size;
++      int is_cma, is_reserved;
++      unsigned long len;
++      const char *status;
++      __be32 *prop;
++
++      is_cma = IS_ENABLED(CONFIG_CMA) &&
++             of_flat_dt_is_compatible(node, "linux,contiguous-memory-region");
++      is_reserved = of_flat_dt_is_compatible(node, "reserved-memory-region");
++
++      if (!is_reserved && !is_cma) {
++              /* ignore node and scan next one */
++              return 0;
++      }
++
++      status = of_get_flat_dt_prop(node, "status", &len);
++      if (status && strcmp(status, "okay") != 0) {
++              /* ignore disabled node nad scan next one */
++              return 0;
++      }
++
++      prop = of_get_flat_dt_prop(node, "reg", &len);
++      if (!prop || (len < (dt_root_size_cells + dt_root_addr_cells) *
++                           sizeof(__be32))) {
++              pr_err("Reserved mem: node %s, incorrect \"reg\" property\n",
++                     uname);
++              /* ignore node and scan next one */
++              return 0;
++      }
++      base = dt_mem_next_cell(dt_root_addr_cells, &prop);
++      size = dt_mem_next_cell(dt_root_size_cells, &prop);
++
++      if (!size) {
++              /* ignore node and scan next one */
++              return 0;
++      }
++
++      pr_info("Reserved mem: found %s, memory base %lx, size %ld MiB\n",
++              uname, (unsigned long)base, (unsigned long)size / SZ_1M);
++
++      if (reserved_mem_count == ARRAY_SIZE(reserved_mem))
++              return -ENOSPC;
++
++      rmem->base = base;
++      rmem->size = size;
++      strlcpy(rmem->name, uname, sizeof(rmem->name));
++
++      if (is_cma) {
++              struct cma *cma;
++              if (dma_contiguous_reserve_area(size, base, 0, &cma) == 0) {
++                      rmem->cma = cma;
++                      reserved_mem_count++;
++                      if (of_get_flat_dt_prop(node,
++                                              "linux,default-contiguous-region",
++                                              NULL))
++                              dma_contiguous_default_area = cma;
++              }
++      } else if (is_reserved) {
++              if (memblock_remove(base, size) == 0)
++                      reserved_mem_count++;
++              else
++                      pr_err("Failed to reserve memory for %s\n", uname);
++      }
++
++      return 0;
++}
++
++static struct reserved_mem *get_dma_memory_region(struct device *dev)
++{
++      struct device_node *node;
++      const char *name;
++      int i;
++
++      node = of_parse_phandle(dev->of_node, "memory-region", 0);
++      if (!node)
++              return NULL;
++
++      name = kbasename(node->full_name);
++      for (i = 0; i < reserved_mem_count; i++)
++              if (strcmp(name, reserved_mem[i].name) == 0)
++                      return &reserved_mem[i];
++      return NULL;
++}
++
++/**
++ * of_reserved_mem_device_init() - assign reserved memory region to given device
++ *
++ * This function assign memory region pointed by "memory-region" device tree
++ * property to the given device.
++ */
++void of_reserved_mem_device_init(struct device *dev)
++{
++      struct reserved_mem *region = get_dma_memory_region(dev);
++      if (!region)
++              return;
++
++      if (region->cma) {
++              dev_set_cma_area(dev, region->cma);
++              pr_info("Assigned CMA %s to %s device\n", region->name,
++                      dev_name(dev));
++      } else {
++              if (dma_declare_coherent_memory(dev, region->base, region->base,
++                  region->size, DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) != 0)
++                      pr_info("Declared reserved memory %s to %s device\n",
++                              region->name, dev_name(dev));
++      }
++}
++
++/**
++ * of_reserved_mem_device_release() - release reserved memory device structures
++ *
++ * This function releases structures allocated for memory region handling for
++ * the given device.
++ */
++void of_reserved_mem_device_release(struct device *dev)
++{
++      struct reserved_mem *region = get_dma_memory_region(dev);
++      if (!region && !region->cma)
++              dma_release_declared_memory(dev);
++}
++
++/**
++ * early_init_dt_scan_reserved_mem() - create reserved memory regions
++ *
++ * This function grabs memory from early allocator for device exclusive use
++ * defined in device tree structures. It should be called by arch specific code
++ * once the early allocator (memblock) has been activated and all other
++ * subsystems have already allocated/reserved memory.
++ */
++void __init early_init_dt_scan_reserved_mem(void)
++{
++      of_scan_flat_dt_by_path("/memory/reserved-memory",
++                              fdt_scan_reserved_mem, NULL);
++}
+diff --git a/drivers/of/platform.c b/drivers/of/platform.c
+index e0a6514..1e4e91d 100644
+--- a/drivers/of/platform.c
++++ b/drivers/of/platform.c
+@@ -21,6 +21,7 @@
+ #include <linux/of_device.h>
+ #include <linux/of_irq.h>
+ #include <linux/of_platform.h>
++#include <linux/of_reserved_mem.h>
+ #include <linux/platform_device.h>
+ const struct of_device_id of_default_bus_match_table[] = {
+@@ -196,6 +197,7 @@ EXPORT_SYMBOL(of_device_alloc);
+  * Returns pointer to created platform device, or NULL if a device was not
+  * registered.  Unavailable devices will not get registered.
+  */
++
+ struct platform_device *of_platform_device_create_pdata(
+                                       struct device_node *np,
+                                       const char *bus_id,
+@@ -218,6 +220,8 @@ struct platform_device *of_platform_device_create_pdata(
+       dev->dev.bus = &platform_bus_type;
+       dev->dev.platform_data = platform_data;
++      of_reserved_mem_device_init(&dev->dev);
++
+       /* We do not fill the DMA ops for platform devices by default.
+        * This is currently the responsibility of the platform code
+        * to do such, possibly using a device notifier
+@@ -225,6 +229,7 @@ struct platform_device *of_platform_device_create_pdata(
+       if (of_device_add(dev) != 0) {
+               platform_device_put(dev);
++              of_reserved_mem_device_release(&dev->dev);
+               return NULL;
+       }
+diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
+new file mode 100644
+index 0000000..c841282
+--- /dev/null
++++ b/include/linux/of_reserved_mem.h
+@@ -0,0 +1,14 @@
++#ifndef __OF_RESERVED_MEM_H
++#define __OF_RESERVED_MEM_H
++
++#ifdef CONFIG_OF_RESERVED_MEM
++void of_reserved_mem_device_init(struct device *dev);
++void of_reserved_mem_device_release(struct device *dev);
++void early_init_dt_scan_reserved_mem(void);
++#else
++static inline void of_reserved_mem_device_init(struct device *dev) { }
++static inline void of_reserved_mem_device_release(struct device *dev) { }
++static inline void early_init_dt_scan_reserved_mem(void) { }
++#endif
++
++#endif /* __OF_RESERVED_MEM_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0064-ARM-init-add-support-for-reserved-memory-defined-by-.patch b/patches.tizen/0064-ARM-init-add-support-for-reserved-memory-defined-by-.patch
new file mode 100644 (file)
index 0000000..f517720
--- /dev/null
@@ -0,0 +1,41 @@
+From bf351bd86848b4e105ab7a5ab17fea7f903eb85c Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Fri, 9 Aug 2013 13:01:08 +0200
+Subject: [PATCH 0064/1302] ARM: init: add support for reserved memory defined
+ by device tree
+
+Enable reserved memory initialization from device tree.
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Acked-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/mm/init.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
+index 0ecc43f..2d2f919 100644
+--- a/arch/arm/mm/init.c
++++ b/arch/arm/mm/init.c
+@@ -17,6 +17,7 @@
+ #include <linux/nodemask.h>
+ #include <linux/initrd.h>
+ #include <linux/of_fdt.h>
++#include <linux/of_reserved_mem.h>
+ #include <linux/highmem.h>
+ #include <linux/gfp.h>
+ #include <linux/memblock.h>
+@@ -376,6 +377,8 @@ void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
+       if (mdesc->reserve)
+               mdesc->reserve();
++      early_init_dt_scan_reserved_mem();
++
+       /*
+        * reserve memory for DMA contigouos allocations,
+        * must come from DMA area inside low memory
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0065-ARM-Exynos-replace-custom-MFC-reserved-memory-handli.patch b/patches.tizen/0065-ARM-Exynos-replace-custom-MFC-reserved-memory-handli.patch
new file mode 100644 (file)
index 0000000..05a1970
--- /dev/null
@@ -0,0 +1,606 @@
+From 07bb8821302c68164f6f5cb9f12cdd5dedf14c5a Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Tue, 30 Jul 2013 15:23:55 +0200
+Subject: [PATCH 0065/1302] ARM: Exynos: replace custom MFC reserved memory
+ handling with generic code
+
+MFC driver use custom bindings for managing reserved memory. Those bindings
+are not really specific to MFC device and no even well discussed. They can
+be easily replaced with generic, platform independent code for handling
+reserved and contiguous memory.
+
+Two additional child devices for each memory port (AXI master) are
+introduced to let one assign some properties to each of them. Later one
+can also use them to assign properties related to SYSMMU controllers,
+which can be used to manage the limited dma window provided by those
+memory ports.
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/media/s5p-mfc.txt          | 63 ++++++++++++++++++----
+ arch/arm/boot/dts/exynos4.dtsi                     | 12 +++++
+ arch/arm/boot/dts/exynos4210-origen.dts            | 25 ++++++++-
+ arch/arm/boot/dts/exynos4210-smdkv310.dts          | 25 ++++++++-
+ arch/arm/boot/dts/exynos4412-origen.dts            | 25 ++++++++-
+ arch/arm/boot/dts/exynos4412-smdk4412.dts          | 25 ++++++++-
+ arch/arm/boot/dts/exynos5250-arndale.dts           | 26 ++++++++-
+ arch/arm/boot/dts/exynos5250-smdk5250.dts          | 26 ++++++++-
+ arch/arm/boot/dts/exynos5250.dtsi                  | 13 +++++
+ arch/arm/mach-exynos/mach-exynos4-dt.c             | 16 ------
+ arch/arm/mach-exynos/mach-exynos5-dt.c             | 17 ------
+ arch/arm/plat-samsung/include/plat/mfc.h           | 11 ----
+ arch/arm/plat-samsung/s5p-dev-mfc.c                | 32 -----------
+ 13 files changed, 219 insertions(+), 97 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/media/s5p-mfc.txt b/Documentation/devicetree/bindings/media/s5p-mfc.txt
+index bf0182d..a1f6192 100644
+--- a/Documentation/devicetree/bindings/media/s5p-mfc.txt
++++ b/Documentation/devicetree/bindings/media/s5p-mfc.txt
+@@ -6,39 +6,84 @@ The MFC device driver is a v4l2 driver which can encode/decode
+ video raw/elementary streams and has support for all popular
+ video codecs.
++The MFC device is connected to system bus with two memory ports (AXI
++masters) for better performance. Those memory ports are modelled as
++separate child devices, so one can assign some properties to them (like
++memory region for dma buffer allocation or sysmmu controller).
++
+ Required properties:
+   - compatible : value should be either one among the following
+       (a) "samsung,mfc-v5" for MFC v5 present in Exynos4 SoCs
+       (b) "samsung,mfc-v6" for MFC v6 present in Exynos5 SoCs
++      and additionally "simple-bus" to correctly initialize child
++      devices for memory ports (AXI masters)
+   - reg : Physical base address of the IP registers and length of memory
+         mapped region.
+   - interrupts : MFC interrupt number to the CPU.
+-  - samsung,mfc-r : Base address of the first memory bank used by MFC
+-                  for DMA contiguous memory allocation and its size.
+-
+-  - samsung,mfc-l : Base address of the second memory bank used by MFC
+-                  for DMA contiguous memory allocation and its size.
+-
+ Optional properties:
+   - samsung,power-domain : power-domain property defined with a phandle
+                          to respective power domain.
++Two child nodes must be defined for MFC device. Their names must be
++following: "memport-r" and "memport-l" ("right" and "left"). Required
++properties:
++  - compatible : value should be "samsung,memport"
++  - dma-memory-region : optional property with a phandle to respective memory
++                      region (see devicetree/bindings/memory.txt), if no region
++                      is defined, sysmmu controller must be used for managing
++                      limited dma window of each memory port.
++
++
+ Example:
+ SoC specific DT entry:
+ mfc: codec@13400000 {
+-      compatible = "samsung,mfc-v5";
++      compatible = "samsung,mfc-v5", "simple-bus";
+       reg = <0x13400000 0x10000>;
+       interrupts = <0 94 0>;
+       samsung,power-domain = <&pd_mfc>;
++      status = "disabled";
++
++      mfc_r: memport-r {
++              compatible = "samsung,memport";
++      };
++
++      mfc_l: memport-l {
++              compatible = "samsung,memport";
++      };
+ };
+ Board specific DT entry:
++memory {
++      /* ... */
++      reserved-memory {
++              #address-cells = <1>;
++              #size-cells = <1>;
++
++              mfc_l_mem: mfc_l_region@43000000 {
++                      compatible = "contiguous-memory-region", "reserved-memory-region";
++                      reg = <0x43000000 0x1000000>;
++              };
++
++              mfc_r_mem: mfc_r_region@52000000 {
++                      compatible = "contiguous-memory-region", "reserved-memory-region";
++                      reg = <0x52000000 0x1000000>;
++              };
++      };
++};
++
+ codec@13400000 {
+-      samsung,mfc-r = <0x43000000 0x800000>;
+-      samsung,mfc-l = <0x51000000 0x800000>;
++      status = "okay";
++
++      memport-r {
++              dma-memory-region = <&mfc_r_mem>;
++      };
++
++      memport-l {
++              dma-memory-region = <&mfc_l_mem>;
++      };
+ };
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index 758e321..f54231d 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -249,8 +249,20 @@
+               samsung,power-domain = <&pd_mfc>;
+               clocks = <&clock 273>, <&clock 170>;
+               clock-names = "mfc", "sclk_mfc";
++              #address-cells = <1>;
++              #size-cells = <0>;
+               status = "disabled";
+               iommu = <&sysmmu_mfc_l>, <&sysmmu_mfc_r>;
++
++              mfc_l: memport@0 {
++                      compatible = "samsung,memport";
++                      reg = <0>;
++              };
++
++              mfc_r: memport@1 {
++                      compatible = "samsung,memport";
++                      reg = <1>;
++              };
+       };
+       serial@13800000 {
+diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts
+index 524b908..ab598e9 100644
+--- a/arch/arm/boot/dts/exynos4210-origen.dts
++++ b/arch/arm/boot/dts/exynos4210-origen.dts
+@@ -26,6 +26,21 @@
+                      0x50000000 0x10000000
+                      0x60000000 0x10000000
+                      0x70000000 0x10000000>;
++
++              reserved-memory {
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      mfc_l_mem: mfc_l_region@43000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x43000000 0x1000000>;
++                      };
++
++                      mfc_r_mem: mfc_r_region@51000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x51000000 0x1000000>;
++                      };
++              };
+       };
+       chosen {
+@@ -62,9 +77,15 @@
+       };
+       codec@13400000 {
+-              samsung,mfc-r = <0x43000000 0x800000>;
+-              samsung,mfc-l = <0x51000000 0x800000>;
+               status = "okay";
++
++              memport@0 {
++                      memory-region = <&mfc_l_mem>;
++              };
++
++              memport@1 {
++                      memory-region = <&mfc_r_mem>;
++              };
+       };
+       serial@13800000 {
+diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts b/arch/arm/boot/dts/exynos4210-smdkv310.dts
+index 91332b7..85672ea 100644
+--- a/arch/arm/boot/dts/exynos4210-smdkv310.dts
++++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts
+@@ -23,6 +23,21 @@
+       memory {
+               reg = <0x40000000 0x80000000>;
++
++              reserved-memory {
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      mfc_l_mem: mfc_l_region@43000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x43000000 0x1000000>;
++                      };
++
++                      mfc_r_mem: mfc_r_region@51000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x51000000 0x1000000>;
++                      };
++              };
+       };
+       chosen {
+@@ -41,9 +56,15 @@
+       };
+       codec@13400000 {
+-              samsung,mfc-r = <0x43000000 0x800000>;
+-              samsung,mfc-l = <0x51000000 0x800000>;
+               status = "okay";
++
++              memport@0 {
++                      memory-region = <&mfc_l_mem>;
++              };
++
++              memport@1 {
++                      memory-region = <&mfc_r_mem>;
++              };
+       };
+       serial@13800000 {
+diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts
+index 1c21bad..5d43b7d 100644
+--- a/arch/arm/boot/dts/exynos4412-origen.dts
++++ b/arch/arm/boot/dts/exynos4412-origen.dts
+@@ -21,6 +21,21 @@
+       memory {
+               reg = <0x40000000 0x40000000>;
++
++              reserved-memory {
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      mfc_l_mem: mfc_l_region@43000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x43000000 0x1000000>;
++                      };
++
++                      mfc_r_mem: mfc_r_region@51000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x51000000 0x1000000>;
++                      };
++              };
+       };
+       chosen {
+@@ -67,9 +82,15 @@
+       };
+       codec@13400000 {
+-              samsung,mfc-r = <0x43000000 0x800000>;
+-              samsung,mfc-l = <0x51000000 0x800000>;
+               status = "okay";
++
++              memport@0 {
++                      memory-region = <&mfc_l_mem>;
++              };
++
++              memport@1 {
++                      memory-region = <&mfc_r_mem>;
++              };
+       };
+       fimd@11c00000 {
+diff --git a/arch/arm/boot/dts/exynos4412-smdk4412.dts b/arch/arm/boot/dts/exynos4412-smdk4412.dts
+index dd56431..591212a 100644
+--- a/arch/arm/boot/dts/exynos4412-smdk4412.dts
++++ b/arch/arm/boot/dts/exynos4412-smdk4412.dts
+@@ -21,6 +21,21 @@
+       memory {
+               reg = <0x40000000 0x40000000>;
++
++              reserved-memory {
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      mfc_l_mem: mfc_l_region@43000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x43000000 0x1000000>;
++                      };
++
++                      mfc_r_mem: mfc_r_region@51000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x51000000 0x1000000>;
++                      };
++              };
+       };
+       chosen {
+@@ -43,9 +58,15 @@
+       };
+       codec@13400000 {
+-              samsung,mfc-r = <0x43000000 0x800000>;
+-              samsung,mfc-l = <0x51000000 0x800000>;
+               status = "okay";
++
++              memport@0 {
++                      memory-region = <&mfc_l_mem>;
++              };
++
++              memport@1 {
++                      memory-region = <&mfc_r_mem>;
++              };
+       };
+       serial@13800000 {
+diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
+index 02cfc76..4e96891 100644
+--- a/arch/arm/boot/dts/exynos5250-arndale.dts
++++ b/arch/arm/boot/dts/exynos5250-arndale.dts
+@@ -18,6 +18,21 @@
+       memory {
+               reg = <0x40000000 0x80000000>;
++
++              reserved-memory {
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      mfc_l_mem: mfc_l_region@43000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x43000000 0x1000000>;
++                      };
++
++                      mfc_r_mem: mfc_r_region@51000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x51000000 0x1000000>;
++                      };
++              };
+       };
+       chosen {
+@@ -25,8 +40,15 @@
+       };
+       codec@11000000 {
+-              samsung,mfc-r = <0x43000000 0x800000>;
+-              samsung,mfc-l = <0x51000000 0x800000>;
++              status = "okay";
++
++              memport@0 {
++                      memory-region = <&mfc_l_mem>;
++              };
++
++              memport@1 {
++                      memory-region = <&mfc_r_mem>;
++              };
+       };
+       i2c@12C60000 {
+diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
+index 3e0c792..da6860e 100644
+--- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
++++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
+@@ -21,6 +21,21 @@
+       memory {
+               reg = <0x40000000 0x80000000>;
++
++              reserved-memory {
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      mfc_l_mem: mfc_l_region@43000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x43000000 0x1000000>;
++                      };
++
++                      mfc_r_mem: mfc_r_region@51000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x51000000 0x1000000>;
++                      };
++              };
+       };
+       chosen {
+@@ -190,8 +205,15 @@
+       };
+       codec@11000000 {
+-              samsung,mfc-r = <0x43000000 0x800000>;
+-              samsung,mfc-l = <0x51000000 0x800000>;
++              status = "okay";
++
++              memport@0 {
++                      memory-region = <&mfc_l_mem>;
++              };
++
++              memport@1 {
++                      memory-region = <&mfc_r_mem>;
++              };
+       };
+       i2s0: i2s@03830000 {
+diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
+index 130d23d..c49d73e 100644
+--- a/arch/arm/boot/dts/exynos5250.dtsi
++++ b/arch/arm/boot/dts/exynos5250.dtsi
+@@ -191,6 +191,19 @@
+               interrupts = <0 96 0>;
+               samsung,power-domain = <&pd_mfc>;
+               iommu = <&sysmmu_mfc_l &sysmmu_mfc_l>;
++              #address-cells = <1>;
++              #size-cells = <0>;
++              status = "disabled";
++
++              mfc_l: memport@0 {
++                      compatible = "samsung,memport";
++                      reg = <0>;
++              };
++
++              mfc_r: memport@1 {
++                      compatible = "samsung,memport";
++                      reg = <1>;
++              };
+       };
+       rtc {
+diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c
+index b9ed834..5a609a4 100644
+--- a/arch/arm/mach-exynos/mach-exynos4-dt.c
++++ b/arch/arm/mach-exynos/mach-exynos4-dt.c
+@@ -13,13 +13,10 @@
+ #include <linux/kernel.h>
+ #include <linux/of_platform.h>
+-#include <linux/of_fdt.h>
+ #include <linux/serial_core.h>
+-#include <linux/memblock.h>
+ #include <linux/clocksource.h>
+ #include <asm/mach/arch.h>
+-#include <plat/mfc.h>
+ #include "common.h"
+@@ -40,18 +37,6 @@ static char const *exynos4_dt_compat[] __initdata = {
+       NULL
+ };
+-static void __init exynos4_reserve(void)
+-{
+-#ifdef CONFIG_S5P_DEV_MFC
+-      struct s5p_mfc_dt_meminfo mfc_mem;
+-
+-      /* Reserve memory for MFC only if it's available */
+-      mfc_mem.compatible = "samsung,mfc-v5";
+-      if (of_scan_flat_dt(s5p_fdt_find_mfc_mem, &mfc_mem))
+-              s5p_mfc_reserve_mem(mfc_mem.roff, mfc_mem.rsize, mfc_mem.loff,
+-                              mfc_mem.lsize);
+-#endif
+-}
+ DT_MACHINE_START(EXYNOS4210_DT, "Samsung Exynos4 (Flattened Device Tree)")
+       /* Maintainer: Thomas Abraham <thomas.abraham@linaro.org> */
+       .smp            = smp_ops(exynos_smp_ops),
+@@ -63,5 +48,4 @@ DT_MACHINE_START(EXYNOS4210_DT, "Samsung Exynos4 (Flattened Device Tree)")
+       .init_time      = exynos_init_time,
+       .dt_compat      = exynos4_dt_compat,
+       .restart        = exynos4_restart,
+-      .reserve        = exynos4_reserve,
+ MACHINE_END
+diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c
+index 753b94f..45d4c19 100644
+--- a/arch/arm/mach-exynos/mach-exynos5-dt.c
++++ b/arch/arm/mach-exynos/mach-exynos5-dt.c
+@@ -10,16 +10,13 @@
+ */
+ #include <linux/of_platform.h>
+-#include <linux/of_fdt.h>
+ #include <linux/memblock.h>
+-#include <linux/io.h>
+ #include <linux/clocksource.h>
+ #include <asm/mach/arch.h>
+ #include <mach/regs-pmu.h>
+ #include <plat/cpu.h>
+-#include <plat/mfc.h>
+ #include "common.h"
+@@ -61,19 +58,6 @@ static char const *exynos5_dt_compat[] __initdata = {
+       NULL
+ };
+-static void __init exynos5_reserve(void)
+-{
+-#ifdef CONFIG_S5P_DEV_MFC
+-      struct s5p_mfc_dt_meminfo mfc_mem;
+-
+-      /* Reserve memory for MFC only if it's available */
+-      mfc_mem.compatible = "samsung,mfc-v6";
+-      if (of_scan_flat_dt(s5p_fdt_find_mfc_mem, &mfc_mem))
+-              s5p_mfc_reserve_mem(mfc_mem.roff, mfc_mem.rsize, mfc_mem.loff,
+-                              mfc_mem.lsize);
+-#endif
+-}
+-
+ DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)")
+       /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+       .init_irq       = exynos5_init_irq,
+@@ -84,5 +68,4 @@ DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)")
+       .init_time      = exynos_init_time,
+       .dt_compat      = exynos5_dt_compat,
+       .restart        = exynos5_restart,
+-      .reserve        = exynos5_reserve,
+ MACHINE_END
+diff --git a/arch/arm/plat-samsung/include/plat/mfc.h b/arch/arm/plat-samsung/include/plat/mfc.h
+index e6d7c42..ac13227 100644
+--- a/arch/arm/plat-samsung/include/plat/mfc.h
++++ b/arch/arm/plat-samsung/include/plat/mfc.h
+@@ -10,14 +10,6 @@
+ #ifndef __PLAT_SAMSUNG_MFC_H
+ #define __PLAT_SAMSUNG_MFC_H __FILE__
+-struct s5p_mfc_dt_meminfo {
+-      unsigned long   loff;
+-      unsigned long   lsize;
+-      unsigned long   roff;
+-      unsigned long   rsize;
+-      char            *compatible;
+-};
+-
+ /**
+  * s5p_mfc_reserve_mem - function to early reserve memory for MFC driver
+  * @rbase:    base address for MFC 'right' memory interface
+@@ -32,7 +24,4 @@ struct s5p_mfc_dt_meminfo {
+ void __init s5p_mfc_reserve_mem(phys_addr_t rbase, unsigned int rsize,
+                               phys_addr_t lbase, unsigned int lsize);
+-int __init s5p_fdt_find_mfc_mem(unsigned long node, const char *uname,
+-                              int depth, void *data);
+-
+ #endif /* __PLAT_SAMSUNG_MFC_H */
+diff --git a/arch/arm/plat-samsung/s5p-dev-mfc.c b/arch/arm/plat-samsung/s5p-dev-mfc.c
+index a93fb6f..c941175 100644
+--- a/arch/arm/plat-samsung/s5p-dev-mfc.c
++++ b/arch/arm/plat-samsung/s5p-dev-mfc.c
+@@ -111,35 +111,3 @@ static int __init s5p_mfc_memory_init(void)
+       return 0;
+ }
+ device_initcall(s5p_mfc_memory_init);
+-
+-#ifdef CONFIG_OF
+-int __init s5p_fdt_find_mfc_mem(unsigned long node, const char *uname,
+-                              int depth, void *data)
+-{
+-      __be32 *prop;
+-      unsigned long len;
+-      struct s5p_mfc_dt_meminfo *mfc_mem = data;
+-
+-      if (!data)
+-              return 0;
+-
+-      if (!of_flat_dt_is_compatible(node, mfc_mem->compatible))
+-              return 0;
+-
+-      prop = of_get_flat_dt_prop(node, "samsung,mfc-l", &len);
+-      if (!prop || (len != 2 * sizeof(unsigned long)))
+-              return 0;
+-
+-      mfc_mem->loff = be32_to_cpu(prop[0]);
+-      mfc_mem->lsize = be32_to_cpu(prop[1]);
+-
+-      prop = of_get_flat_dt_prop(node, "samsung,mfc-r", &len);
+-      if (!prop || (len != 2 * sizeof(unsigned long)))
+-              return 0;
+-
+-      mfc_mem->roff = be32_to_cpu(prop[0]);
+-      mfc_mem->rsize = be32_to_cpu(prop[1]);
+-
+-      return 1;
+-}
+-#endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0066-media-s5p-mfc-remove-DT-hacks-and-simplify-initializ.patch b/patches.tizen/0066-media-s5p-mfc-remove-DT-hacks-and-simplify-initializ.patch
new file mode 100644 (file)
index 0000000..98b0362
--- /dev/null
@@ -0,0 +1,139 @@
+From c65168d81237700101afa3f9901d4e32ed6ae6e6 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Tue, 12 Feb 2013 14:03:29 +0100
+Subject: [PATCH 0066/1302] media: s5p-mfc: remove DT hacks and simplify
+ initialization code
+
+This patch removes custom initialization of reserved memory regions from
+s5p-mfc driver. Memory initialization can be now handled by generic
+code.
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/s5p-mfc/s5p_mfc.c | 89 ++++++++++----------------------
+ 1 file changed, 27 insertions(+), 62 deletions(-)
+
+diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
+index d12faa6..264830c 100644
+--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
++++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
+@@ -22,6 +22,7 @@
+ #include <media/v4l2-event.h>
+ #include <linux/workqueue.h>
+ #include <linux/of.h>
++#include <linux/of_platform.h>
+ #include <media/videobuf2-core.h>
+ #include "s5p_mfc_common.h"
+ #include "s5p_mfc_ctrl.h"
+@@ -1007,55 +1008,20 @@ static const struct v4l2_file_operations s5p_mfc_fops = {
+       .mmap = s5p_mfc_mmap,
+ };
++static const char *s5p_mfc_children_names[] = {"s5p-mfc-l", "s5p-mfc-r"};
++enum { MFC_PORT_L, MFC_PORT_R};
++
+ static int match_child(struct device *dev, void *data)
+ {
+-      if (!dev_name(dev))
+-              return 0;
+-      return !strcmp(dev_name(dev), (char *)data);
++      const __be32 *reg = of_get_property(dev->of_node, "reg", NULL);
++      int num = (int)data;
++
++      return (strcmp(dev_name(dev), s5p_mfc_children_names[num]) == 0 ||
++              (reg && be32_to_cpup(reg) == num));
+ }
+ static void *mfc_get_drv_data(struct platform_device *pdev);
+-static int s5p_mfc_alloc_memdevs(struct s5p_mfc_dev *dev)
+-{
+-      unsigned int mem_info[2] = { };
+-
+-      dev->mem_dev_l = devm_kzalloc(&dev->plat_dev->dev,
+-                      sizeof(struct device), GFP_KERNEL);
+-      if (!dev->mem_dev_l) {
+-              mfc_err("Not enough memory\n");
+-              return -ENOMEM;
+-      }
+-      device_initialize(dev->mem_dev_l);
+-      of_property_read_u32_array(dev->plat_dev->dev.of_node,
+-                      "samsung,mfc-l", mem_info, 2);
+-      if (dma_declare_coherent_memory(dev->mem_dev_l, mem_info[0],
+-                              mem_info[0], mem_info[1],
+-                              DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) == 0) {
+-              mfc_err("Failed to declare coherent memory for\n"
+-              "MFC device\n");
+-              return -ENOMEM;
+-      }
+-
+-      dev->mem_dev_r = devm_kzalloc(&dev->plat_dev->dev,
+-                      sizeof(struct device), GFP_KERNEL);
+-      if (!dev->mem_dev_r) {
+-              mfc_err("Not enough memory\n");
+-              return -ENOMEM;
+-      }
+-      device_initialize(dev->mem_dev_r);
+-      of_property_read_u32_array(dev->plat_dev->dev.of_node,
+-                      "samsung,mfc-r", mem_info, 2);
+-      if (dma_declare_coherent_memory(dev->mem_dev_r, mem_info[0],
+-                              mem_info[0], mem_info[1],
+-                              DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) == 0) {
+-              pr_err("Failed to declare coherent memory for\n"
+-              "MFC device\n");
+-              return -ENOMEM;
+-      }
+-      return 0;
+-}
+-
+ /* MFC probe function */
+ static int s5p_mfc_probe(struct platform_device *pdev)
+ {
+@@ -1107,25 +1073,24 @@ static int s5p_mfc_probe(struct platform_device *pdev)
+               goto err_res;
+       }
+-      if (pdev->dev.of_node) {
+-              ret = s5p_mfc_alloc_memdevs(dev);
+-              if (ret < 0)
+-                      goto err_res;
+-      } else {
+-              dev->mem_dev_l = device_find_child(&dev->plat_dev->dev,
+-                              "s5p-mfc-l", match_child);
+-              if (!dev->mem_dev_l) {
+-                      mfc_err("Mem child (L) device get failed\n");
+-                      ret = -ENODEV;
+-                      goto err_res;
+-              }
+-              dev->mem_dev_r = device_find_child(&dev->plat_dev->dev,
+-                              "s5p-mfc-r", match_child);
+-              if (!dev->mem_dev_r) {
+-                      mfc_err("Mem child (R) device get failed\n");
+-                      ret = -ENODEV;
+-                      goto err_res;
+-              }
++      ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
++      if (ret)
++              goto err_res;
++
++      dev->mem_dev_l = device_find_child(&dev->plat_dev->dev,
++                                         (void *)MFC_PORT_L, match_child);
++      if (!dev->mem_dev_l) {
++              mfc_err("Mem child (L) device get failed\n");
++              ret = -ENODEV;
++              goto err_res;
++      }
++
++      dev->mem_dev_r = device_find_child(&dev->plat_dev->dev,
++                                         (void *)MFC_PORT_R, match_child);
++      if (!dev->mem_dev_r) {
++              mfc_err("Mem child (R) device get failed\n");
++              ret = -ENODEV;
++              goto err_res;
+       }
+       dev->alloc_ctx[0] = vb2_dma_contig_init_ctx(dev->mem_dev_l);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0067-media-s5p-mfc-add-support-for-runtime-pm-for-memport.patch b/patches.tizen/0067-media-s5p-mfc-add-support-for-runtime-pm-for-memport.patch
new file mode 100644 (file)
index 0000000..43b1834
--- /dev/null
@@ -0,0 +1,41 @@
+From 3af45eb4248355694ce11db1dc0e4748967b1d0d Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Wed, 7 Aug 2013 11:01:53 +0200
+Subject: [PATCH 0067/1302] media: s5p-mfc: add support for runtime pm for
+ memport client devices
+
+Client device for handling memory/dma operations for right and left memory
+port (memory bank) require runtime pm handling for correct operation. Add
+required calls to power_on/power_off functions.
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/s5p-mfc/s5p_mfc_pm.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c
+index 11d5f1d..9e238528 100644
+--- a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c
++++ b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c
+@@ -97,6 +97,8 @@ void s5p_mfc_clock_off(void)
+ int s5p_mfc_power_on(void)
+ {
+ #ifdef CONFIG_PM_RUNTIME
++      pm_runtime_get_sync(p_dev->mem_dev_l);
++      pm_runtime_get_sync(p_dev->mem_dev_r);
+       return pm_runtime_get_sync(pm->device);
+ #else
+       atomic_set(&pm->power, 1);
+@@ -107,6 +109,8 @@ int s5p_mfc_power_on(void)
+ int s5p_mfc_power_off(void)
+ {
+ #ifdef CONFIG_PM_RUNTIME
++      pm_runtime_put_sync(p_dev->mem_dev_l);
++      pm_runtime_put_sync(p_dev->mem_dev_r);
+       return pm_runtime_put_sync(pm->device);
+ #else
+       atomic_set(&pm->power, 0);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0068-ARM-Exynos-enable-CMA-and-MFC-for-SLP_PQ-board.patch b/patches.tizen/0068-ARM-Exynos-enable-CMA-and-MFC-for-SLP_PQ-board.patch
new file mode 100644 (file)
index 0000000..4534dc7
--- /dev/null
@@ -0,0 +1,76 @@
+From 9cf39785eafddc045870cdc1145ad6949383610b Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Tue, 20 Aug 2013 14:59:04 +0200
+Subject: [PATCH 0068/1302] ARM: Exynos: enable CMA and MFC for SLP_PQ board
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 39 +++++++++++++++++++++++++++++++++
+ 1 file changed, 39 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 3ff029f..8d96f53 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -24,6 +24,32 @@
+                       0x50000000 0x10000000
+                       0x60000000 0x10000000
+                       0x70000000 0x10000000>;
++
++              reserved-memory {
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      contig_mem: region@71000000 {
++                              compatible = "linux,contiguous-memory-region";
++                              reg = <0x71000000 0x0c000000>;
++                              linux,default-contiguous-region;
++                      };
++
++                      fimc_mem: region@70000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x70000000 0x1000000>;
++                      };
++
++                      mfc_l_mem: mfc_l_region@43000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x43000000 0x1000000>;
++                      };
++
++                      mfc_r_mem: mfc_r_region@51000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x51000000 0x1000000>;
++                      };
++              };
+       };
+       chosen {
+@@ -629,6 +655,7 @@
+                       status = "okay";
+                       pinctrl-0 = <&fimc_is_i2c0 &fimc_is_i2c1 &fimc_is_uart>;
+                       pinctrl-names = "default";
++                      memory-region = <&fimc_mem>;
+                       fimc_lite_0: fimc-lite@12390000 {
+                               status = "okay";
+@@ -660,4 +687,16 @@
+                       };
+               };
+       };
++
++      codec@13400000 {
++              status = "okay";
++
++              memport@0 {
++                      memory-region = <&mfc_l_mem>;
++              };
++
++              memport@1 {
++                      memory-region = <&mfc_r_mem>;
++              };
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0069-video-add-display-core.patch b/patches.tizen/0069-video-add-display-core.patch
new file mode 100644 (file)
index 0000000..f365b02
--- /dev/null
@@ -0,0 +1,607 @@
+From b2cb1021a14bd49b42467f3e0aa412f9410dee37 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 30 Jan 2013 11:07:46 +0100
+Subject: [PATCH 0069/1302] video: add display-core
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/video/Kconfig                |   1 +
+ drivers/video/Makefile               |   1 +
+ drivers/video/display/Kconfig        |  10 ++
+ drivers/video/display/Makefile       |   1 +
+ drivers/video/display/display-core.c | 295 +++++++++++++++++++++++++++++++++++
+ include/video/display.h              | 230 +++++++++++++++++++++++++++
+ 6 files changed, 538 insertions(+)
+ create mode 100644 drivers/video/display/Kconfig
+ create mode 100644 drivers/video/display/Makefile
+ create mode 100644 drivers/video/display/display-core.c
+ create mode 100644 include/video/display.h
+
+diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
+index 2e937bd..6d9788d 100644
+--- a/drivers/video/Kconfig
++++ b/drivers/video/Kconfig
+@@ -2475,6 +2475,7 @@ source "drivers/video/omap2/Kconfig"
+ source "drivers/video/exynos/Kconfig"
+ source "drivers/video/mmp/Kconfig"
+ source "drivers/video/backlight/Kconfig"
++source "drivers/video/display/Kconfig"
+ if VT
+       source "drivers/video/console/Kconfig"
+diff --git a/drivers/video/Makefile b/drivers/video/Makefile
+index e8bae8d..d7fd4a2 100644
+--- a/drivers/video/Makefile
++++ b/drivers/video/Makefile
+@@ -15,6 +15,7 @@ fb-objs                           := $(fb-y)
+ obj-$(CONFIG_VT)                += console/
+ obj-$(CONFIG_LOGO)              += logo/
+ obj-y                           += backlight/
++obj-y                           += display/
+ obj-$(CONFIG_EXYNOS_VIDEO)     += exynos/
+diff --git a/drivers/video/display/Kconfig b/drivers/video/display/Kconfig
+new file mode 100644
+index 0000000..477192d
+--- /dev/null
++++ b/drivers/video/display/Kconfig
+@@ -0,0 +1,10 @@
++menuconfig DISPLAY_CORE
++      tristate "Display Core"
++      ---help---
++        Support common display framework for graphics devices.
++
++if DISPLAY_CORE
++
++
++
++endif # DISPLAY_CORE
+diff --git a/drivers/video/display/Makefile b/drivers/video/display/Makefile
+new file mode 100644
+index 0000000..bd93496
+--- /dev/null
++++ b/drivers/video/display/Makefile
+@@ -0,0 +1 @@
++obj-$(CONFIG_DISPLAY_CORE) += display-core.o
+diff --git a/drivers/video/display/display-core.c b/drivers/video/display/display-core.c
+new file mode 100644
+index 0000000..9c93aae
+--- /dev/null
++++ b/drivers/video/display/display-core.c
+@@ -0,0 +1,295 @@
++/*
++ * Display Core
++ *
++ * Copyright (C) 2012 Renesas Solutions Corp.
++ *
++ * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.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/export.h>
++#include <linux/kernel.h>
++#include <linux/list.h>
++#include <linux/module.h>
++#include <linux/mutex.h>
++#include <linux/of.h>
++
++#include <video/display.h>
++#include <video/videomode.h>
++
++static struct video_source *video_source_bind(struct display_entity *entity);
++static void video_source_unbind(struct display_entity *entity);
++
++/* -----------------------------------------------------------------------------
++ * Display Entity
++ */
++
++static LIST_HEAD(display_entity_list);
++static DEFINE_MUTEX(display_entity_mutex);
++
++struct display_entity *display_entity_get_first(void)
++{
++      /* FIXME: Don't we need some locking here? */
++
++      if (list_empty(&display_entity_list))
++              return NULL;
++
++      return list_first_entry(&display_entity_list, struct display_entity,
++                      list);
++}
++EXPORT_SYMBOL(display_entity_get_first);
++
++int display_entity_set_state(struct display_entity *entity,
++                           enum display_entity_state state)
++{
++      int ret;
++
++      if (entity->state == state)
++              return 0;
++
++      if (!entity->ops || !entity->ops->set_state)
++              return 0;
++
++      ret = entity->ops->set_state(entity, state);
++      if (ret < 0)
++              return ret;
++
++      entity->state = state;
++      return 0;
++}
++EXPORT_SYMBOL_GPL(display_entity_set_state);
++
++int display_entity_get_modes(struct display_entity *entity,
++                           const struct videomode **modes)
++{
++      if (!entity->ops || !entity->ops->get_modes)
++              return 0;
++
++      return entity->ops->get_modes(entity, modes);
++}
++EXPORT_SYMBOL_GPL(display_entity_get_modes);
++
++int display_entity_get_size(struct display_entity *entity,
++                          unsigned int *width, unsigned int *height)
++{
++      if (!entity->ops || !entity->ops->get_size)
++              return -EOPNOTSUPP;
++
++      return entity->ops->get_size(entity, width, height);
++}
++EXPORT_SYMBOL_GPL(display_entity_get_size);
++
++int display_entity_get_params(struct display_entity *entity,
++                            struct display_entity_interface_params *params)
++{
++      if (!entity->ops || !entity->ops->get_params)
++              return -EOPNOTSUPP;
++
++      return entity->ops->get_params(entity, params);
++}
++EXPORT_SYMBOL_GPL(display_entity_get_params);
++
++static void display_entity_release(struct kref *ref)
++{
++      struct display_entity *entity =
++              container_of(ref, struct display_entity, ref);
++
++      if (entity->release)
++              entity->release(entity);
++}
++
++struct display_entity *display_entity_get(struct display_entity *entity)
++{
++      if (entity == NULL)
++              return NULL;
++
++      kref_get(&entity->ref);
++      return entity;
++}
++EXPORT_SYMBOL_GPL(display_entity_get);
++
++void display_entity_put(struct display_entity *entity)
++{
++      kref_put(&entity->ref, display_entity_release);
++}
++EXPORT_SYMBOL_GPL(display_entity_put);
++
++int __must_check __display_entity_register(struct display_entity *entity,
++                                         struct module *owner)
++{
++      struct video_source *src;
++
++      kref_init(&entity->ref);
++      entity->owner = owner;
++      entity->state = DISPLAY_ENTITY_STATE_OFF;
++      entity->source = NULL;
++
++      src = video_source_bind(entity);
++      if (!src)
++              return -EPROBE_DEFER;
++
++      mutex_lock(&display_entity_mutex);
++      list_add(&entity->list, &display_entity_list);
++      mutex_unlock(&display_entity_mutex);
++
++      return 0;
++}
++EXPORT_SYMBOL_GPL(__display_entity_register);
++
++void display_entity_unregister(struct display_entity *entity)
++{
++      video_source_unbind(entity);
++
++      mutex_lock(&display_entity_mutex);
++
++      list_del(&entity->list);
++      mutex_unlock(&display_entity_mutex);
++
++      display_entity_put(entity);
++}
++EXPORT_SYMBOL_GPL(display_entity_unregister);
++
++/* -----------------------------------------------------------------------------
++ * Video Source
++ */
++
++static LIST_HEAD(video_source_list);
++static DEFINE_MUTEX(video_source_mutex);
++
++static void video_source_release(struct kref *ref)
++{
++      struct video_source *src =
++              container_of(ref, struct video_source, ref);
++
++      if (src->release)
++              src->release(src);
++}
++
++static struct video_source *video_source_get(struct video_source *src)
++{
++      if (src == NULL)
++              return NULL;
++
++      kref_get(&src->ref);
++      if (!try_module_get(src->owner)) {
++              kref_put(&src->ref, video_source_release);
++              return NULL;
++      }
++
++      return src;
++}
++
++static void video_source_put(struct video_source *src)
++{
++      module_put(src->owner);
++      kref_put(&src->ref, video_source_release);
++}
++
++int __must_check __video_source_register(struct video_source *src,
++                                                      struct module *owner)
++{
++      kref_init(&src->ref);
++      src->owner = owner;
++
++      mutex_lock(&video_source_mutex);
++      list_add(&src->list, &video_source_list);
++
++      mutex_unlock(&video_source_mutex);
++
++      return 0;
++}
++EXPORT_SYMBOL_GPL(__video_source_register);
++
++void video_source_unregister(struct video_source *src)
++{
++      mutex_lock(&video_source_mutex);
++
++      list_del(&src->list);
++      mutex_unlock(&video_source_mutex);
++
++      kref_put(&src->ref, video_source_release);
++}
++EXPORT_SYMBOL_GPL(video_source_unregister);
++
++static struct video_source *video_source_bind(struct display_entity *entity)
++{
++      struct video_source *src = NULL;
++      int ret;
++
++      if (entity->source)
++              return entity->source;
++
++      mutex_lock(&video_source_mutex);
++
++      if (entity->of_node) {
++              struct device_node *np;
++
++              np = of_parse_phandle(entity->of_node, "video-source", 0);
++              if (!np)
++                      goto unlock;
++
++              list_for_each_entry(src, &video_source_list, list) {
++                      if (src->of_node == np)
++                              goto found;
++              }
++
++              src = NULL;
++              goto unlock;
++      }
++
++      if (!entity->src_name)
++              goto unlock;
++
++      list_for_each_entry(src, &video_source_list, list) {
++              if (src->id != entity->src_id)
++                      continue;
++              if (!strcmp(src->name, entity->src_name))
++                      goto found;
++      }
++
++      src = NULL;
++      goto unlock;
++
++found:
++      video_source_get(src);
++
++      if (src->common_ops->bind) {
++              ret = src->common_ops->bind(src, entity);
++              if (ret != 0) {
++                      video_source_put(src);
++                      src = NULL;
++                      goto unlock;
++              }
++      }
++
++      src->sink = entity;
++      entity->source = src;
++
++unlock:
++      mutex_unlock(&video_source_mutex);
++
++      return src;
++}
++
++static void video_source_unbind(struct display_entity *entity)
++{
++      struct video_source *src = entity->source;
++
++      if (!src)
++              return;
++
++      if (src->common_ops && src->common_ops->unbind)
++              src->common_ops->unbind(src, entity);
++
++      src->sink = NULL;
++      entity->source = NULL;
++
++      video_source_put(src);
++}
++
++MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
++MODULE_DESCRIPTION("Display Core");
++MODULE_LICENSE("GPL");
+diff --git a/include/video/display.h b/include/video/display.h
+new file mode 100644
+index 0000000..11d7032
+--- /dev/null
++++ b/include/video/display.h
+@@ -0,0 +1,230 @@
++/*
++ * Display Core
++ *
++ * Copyright (C) 2012 Renesas Solutions Corp.
++ *
++ * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.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 __DISPLAY_H__
++#define __DISPLAY_H__
++
++#include <linux/kref.h>
++#include <linux/list.h>
++#include <linux/module.h>
++#include <video/omapdss.h>
++
++struct display_entity;
++struct video_source;
++struct videomode;
++
++/* -----------------------------------------------------------------------------
++ * Display Entity
++ */
++
++/* Hack to get the first registered display entity */
++struct display_entity *display_entity_get_first(void);
++
++enum display_entity_state {
++      DISPLAY_ENTITY_STATE_OFF,
++      DISPLAY_ENTITY_STATE_STANDBY,
++      DISPLAY_ENTITY_STATE_ON,
++};
++
++enum display_entity_interface_type {
++      DISPLAY_ENTITY_INTERFACE_DPI,
++      DISPLAY_ENTITY_INTERFACE_DSI,
++};
++
++#define DSI_MODE_VIDEO                        (1 << 0)
++#define DSI_MODE_VIDEO_BURST          (1 << 1)
++#define DSI_MODE_VIDEO_SYNC_PULSE     (1 << 2)
++#define DSI_MODE_VIDEO_AUTO_VERT      (1 << 3)
++#define DSI_MODE_VIDEO_HSE            (1 << 4)
++#define DSI_MODE_VIDEO_HFP            (1 << 5)
++#define DSI_MODE_VIDEO_HBP            (1 << 6)
++#define DSI_MODE_VIDEO_HSA            (1 << 7)
++#define DSI_MODE_VSYNC_FLUSH          (1 << 8)
++#define DSI_MODE_EOT_PACKET           (1 << 9)
++
++enum mipi_dsi_pixel_format {
++      DSI_FMT_RGB888,
++      DSI_FMT_RGB666,
++      DSI_FMT_RGB666_PACKED,
++      DSI_FMT_RGB565,
++};
++
++struct mipi_dsi_interface_params {
++      enum mipi_dsi_pixel_format format;
++      unsigned long mode;
++      unsigned long hs_clk_freq;
++      unsigned long esc_clk_freq;
++      unsigned char data_lanes;
++      unsigned char cmd_allow;
++};
++
++struct display_entity_interface_params {
++      enum display_entity_interface_type type;
++      union {
++              struct mipi_dsi_interface_params dsi;
++      } p;
++};
++
++struct display_entity_control_ops {
++      int (*set_state)(struct display_entity *ent,
++                       enum display_entity_state state);
++      int (*update)(struct display_entity *ent,
++                      void (*callback)(int, void *), void *data);
++      int (*get_modes)(struct display_entity *ent,
++                       const struct videomode **modes);
++      int (*get_params)(struct display_entity *ent,
++                        struct display_entity_interface_params *params);
++      int (*get_size)(struct display_entity *ent,
++                      unsigned int *width, unsigned int *height);
++};
++
++struct display_entity {
++      struct list_head list;
++      struct device *dev;
++      struct device_node *of_node;
++      struct module *owner;
++      struct kref ref;
++
++      const char *src_name;
++      int src_id;
++      struct video_source *source;
++
++      const struct display_entity_control_ops *ops;
++
++      void(*release)(struct display_entity *ent);
++
++      enum display_entity_state state;
++};
++
++int display_entity_set_state(struct display_entity *entity,
++                           enum display_entity_state state);
++int display_entity_get_params(struct display_entity *entity,
++                            struct display_entity_interface_params *params);
++int display_entity_get_modes(struct display_entity *entity,
++                           const struct videomode **modes);
++int display_entity_get_size(struct display_entity *entity,
++                          unsigned int *width, unsigned int *height);
++
++struct display_entity *display_entity_get(struct display_entity *entity);
++void display_entity_put(struct display_entity *entity);
++
++int __must_check __display_entity_register(struct display_entity *entity,
++                                         struct module *owner);
++void display_entity_unregister(struct display_entity *entity);
++
++#define display_entity_register(display_entity) \
++      __display_entity_register(display_entity, THIS_MODULE)
++
++
++/* -----------------------------------------------------------------------------
++ * Video Source
++ */
++
++enum video_source_stream_state {
++      DISPLAY_ENTITY_STREAM_STOPPED,
++      DISPLAY_ENTITY_STREAM_CONTINUOUS,
++};
++
++struct common_video_source_ops {
++      int (*set_stream)(struct video_source *src,
++                       enum video_source_stream_state state);
++      int (*bind)(struct video_source *src, struct display_entity *sink);
++      int (*unbind)(struct video_source *src, struct display_entity *sink);
++};
++
++struct dpi_video_source_ops {
++      int (*set_videomode)(struct video_source *src,
++                      const struct videomode *vm);
++      int (*set_data_lines)(struct video_source *src, int lines);
++};
++
++struct dsi_video_source_ops {
++      /* enable/disable dsi bus */
++      int (*enable)(struct video_source *src);
++      int (*disable)(struct video_source *src);
++
++      /* bus configuration */
++      int (*configure_pins)(struct video_source *src,
++                      const struct omap_dsi_pin_config *pins);
++      int (*set_clocks)(struct video_source *src,
++                      unsigned long ddr_clk,
++                      unsigned long lp_clk);
++      /* NOTE: Do we really need configure_pins and set_clocks here? */
++
++      void (*enable_hs)(struct video_source *src, bool enable);
++
++      /* data transfer */
++      int (*dcs_write)(struct video_source *src, int channel,
++                      const u8 *data, size_t len);
++      int (*dcs_read)(struct video_source *src, int channel, u8 dcs_cmd,
++                      u8 *data, size_t len);
++      /* NOTE: Do we need more write and read types? */
++
++      int (*update)(struct video_source *src, int channel,
++                      void (*callback)(int, void *), void *data);
++};
++
++struct dvi_video_source_ops {
++      int (*set_videomode)(struct video_source *src,
++                      const struct videomode *vm);
++};
++
++struct video_source {
++      struct list_head list;
++      struct device *dev;
++      struct device_node *of_node;
++      struct module *owner;
++      struct kref ref;
++
++      struct display_entity *sink;
++
++      const char *name;
++      int id;
++
++      const struct common_video_source_ops *common_ops;
++
++      union {
++              const struct dpi_video_source_ops *dpi;
++              const struct dsi_video_source_ops *dsi;
++              const struct dvi_video_source_ops *dvi;
++      } ops;
++
++      void(*release)(struct video_source *src);
++};
++
++static inline int dsi_dcs_write(struct video_source *src, int channel,
++                                              const u8 *data, size_t len)
++{
++      if (!src->ops.dsi || !src->ops.dsi->dcs_write)
++              return -EINVAL;
++
++      return src->ops.dsi->dcs_write(src, channel, data, len);
++}
++
++static inline int dsi_dcs_read(struct video_source *src, int channel,
++                                      u8 dcs_cmd, u8 *data, size_t len)
++{
++      if (!src->ops.dsi || !src->ops.dsi->dcs_read)
++              return -EINVAL;
++
++      return src->ops.dsi->dcs_read(src, channel, dcs_cmd, data, len);
++}
++
++
++#define video_source_register(video_source) \
++      __video_source_register(video_source, THIS_MODULE)
++
++int __must_check __video_source_register(struct video_source *entity,
++                                                      struct module *owner);
++void video_source_unregister(struct video_source *entity);
++
++#endif /* __DISPLAY_H__ */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0070-ARM-Exynos4-fix-DSIM-support.patch b/patches.tizen/0070-ARM-Exynos4-fix-DSIM-support.patch
new file mode 100644 (file)
index 0000000..ff4874b
--- /dev/null
@@ -0,0 +1,60 @@
+From 774da9c5183102b16aaa6a1d660be84d4c0f7270 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Mon, 11 Jun 2012 13:27:17 +0200
+Subject: [PATCH 0070/1302] ARM: Exynos4: fix DSIM support
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/mach-exynos/include/mach/irqs.h | 2 ++
+ arch/arm/mach-exynos/include/mach/map.h  | 1 +
+ include/video/exynos_mipi_dsim.h         | 3 +++
+ 3 files changed, 6 insertions(+)
+
+diff --git a/arch/arm/mach-exynos/include/mach/irqs.h b/arch/arm/mach-exynos/include/mach/irqs.h
+index c72f59d..34ee14c 100644
+--- a/arch/arm/mach-exynos/include/mach/irqs.h
++++ b/arch/arm/mach-exynos/include/mach/irqs.h
+@@ -96,6 +96,7 @@
+ #define EXYNOS4_IRQ_DWMCI             IRQ_SPI(77)
+ #define EXYNOS4_IRQ_MIPI_CSIS0                IRQ_SPI(78)
++#define EXYNOS4_IRQ_MIPI_DSI0         IRQ_SPI(79)
+ #define EXYNOS4_IRQ_MIPI_CSIS1                IRQ_SPI(80)
+ #define EXYNOS4_IRQ_ONENAND_AUDI      IRQ_SPI(82)
+@@ -217,6 +218,7 @@
+ #define IRQ_HSMMC3                    EXYNOS4_IRQ_HSMMC3
+ #define IRQ_MIPI_CSIS0                        EXYNOS4_IRQ_MIPI_CSIS0
++#define IRQ_MIPI_DSI0                 EXYNOS4_IRQ_MIPI_DSI0
+ #define IRQ_ONENAND_AUDI              EXYNOS4_IRQ_ONENAND_AUDI
+diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
+index 92b29bb..e721398 100644
+--- a/arch/arm/mach-exynos/include/mach/map.h
++++ b/arch/arm/mach-exynos/include/mach/map.h
+@@ -179,6 +179,7 @@
+ #define EXYNOS4_PA_MIPI_CSIS1         0x11890000
+ #define EXYNOS4_PA_FIMD0              0x11C00000
++#define EXYNOS4_PA_DSIM0              0x11C80000
+ #define EXYNOS4_PA_HSMMC(x)           (0x12510000 + ((x) * 0x10000))
+ #define EXYNOS4_PA_DWMCI              0x12550000
+diff --git a/include/video/exynos_mipi_dsim.h b/include/video/exynos_mipi_dsim.h
+index 89dc88a..c6b1bf5 100644
+--- a/include/video/exynos_mipi_dsim.h
++++ b/include/video/exynos_mipi_dsim.h
+@@ -356,4 +356,7 @@ int exynos_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device
+  */
+ int exynos_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver
+                                               *lcd_drv);
++
++int s5p_dsim_phy_enable(struct platform_device *pdev, bool on);
++
+ #endif /* _EXYNOS_MIPI_DSIM_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0071-ARM-EXYNOS-Make-MACH_EXYNOS4_DT-select-S5P_SETUP_MIP.patch b/patches.tizen/0071-ARM-EXYNOS-Make-MACH_EXYNOS4_DT-select-S5P_SETUP_MIP.patch
new file mode 100644 (file)
index 0000000..a04fab6
--- /dev/null
@@ -0,0 +1,30 @@
+From 550324cea23c113ae343a7c3e27111811ee95a2b Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Mon, 3 Sep 2012 15:51:26 +0200
+Subject: [PATCH 0071/1302] ARM: EXYNOS: Make MACH_EXYNOS4_DT select
+ S5P_SETUP_MIPIPHY
+
+S5P_SETUP_MIPIPHY is needed for device tree support of MIPI DSI on
+Exynos4.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/mach-exynos/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
+index 0020f87..3ea8c7d 100644
+--- a/arch/arm/mach-exynos/Kconfig
++++ b/arch/arm/mach-exynos/Kconfig
+@@ -416,6 +416,7 @@ config MACH_EXYNOS4_DT
+       select PINCTRL
+       select PINCTRL_EXYNOS
+       select S5P_DEV_MFC
++      select S5P_SETUP_MIPIPHY
+       select USE_OF
+       select ARM_DMA_USE_IOMMU if EXYNOS_IOMMU
+       help
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0072-video-display-Add-exynos-dsi-video-source-driver.patch b/patches.tizen/0072-video-display-Add-exynos-dsi-video-source-driver.patch
new file mode 100644 (file)
index 0000000..93171df
--- /dev/null
@@ -0,0 +1,1429 @@
+From f4ddeff2f3e1f1790913d95529ca68cd57019c54 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Mon, 28 Jan 2013 15:24:28 +0100
+Subject: [PATCH 0072/1302] video: display: Add exynos-dsi video source driver
+
+This patch adds new driver for DSI master block available in Samsung
+Exynos SoCs. The driver is designed and written specifically for Common
+Display Framework.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/video/display/Kconfig             |    3 +
+ drivers/video/display/Makefile            |    1 +
+ drivers/video/display/source-exynos_dsi.c | 1333 +++++++++++++++++++++++++++++
+ include/video/exynos_dsi.h                |   41 +
+ 4 files changed, 1378 insertions(+)
+ create mode 100644 drivers/video/display/source-exynos_dsi.c
+ create mode 100644 include/video/exynos_dsi.h
+
+diff --git a/drivers/video/display/Kconfig b/drivers/video/display/Kconfig
+index 477192d..b14527a 100644
+--- a/drivers/video/display/Kconfig
++++ b/drivers/video/display/Kconfig
+@@ -6,5 +6,8 @@ menuconfig DISPLAY_CORE
+ if DISPLAY_CORE
++config DISPLAY_SOURCE_EXYNOS_DSI
++      tristate "Samsung SoC MIPI DSI Master"
++
+ endif # DISPLAY_CORE
+diff --git a/drivers/video/display/Makefile b/drivers/video/display/Makefile
+index bd93496..40a283a 100644
+--- a/drivers/video/display/Makefile
++++ b/drivers/video/display/Makefile
+@@ -1 +1,2 @@
+ obj-$(CONFIG_DISPLAY_CORE) += display-core.o
++obj-$(CONFIG_DISPLAY_SOURCE_EXYNOS_DSI) += source-exynos_dsi.o
+diff --git a/drivers/video/display/source-exynos_dsi.c b/drivers/video/display/source-exynos_dsi.c
+new file mode 100644
+index 0000000..145d57b
+--- /dev/null
++++ b/drivers/video/display/source-exynos_dsi.c
+@@ -0,0 +1,1333 @@
++/*
++ * Samsung SoC MIPI DSI Master driver.
++ *
++ * Copyright (c) 2012 Samsung Electronics Co., Ltd
++ *
++ * Contacts: Tomasz Figa <t.figa@samsung.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/clk.h>
++#include <linux/completion.h>
++#include <linux/delay.h>
++#include <linux/errno.h>
++#include <linux/fb.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/irq.h>
++#include <linux/kernel.h>
++#include <linux/list.h>
++#include <linux/memory.h>
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/pm_runtime.h>
++#include <linux/regulator/consumer.h>
++#include <linux/spinlock.h>
++#include <linux/wait.h>
++
++#include <video/display.h>
++#include <video/exynos_dsi.h>
++#include <video/mipi_display.h>
++#include <video/videomode.h>
++
++#define DSIM_STATUS_REG               0x0     /* Status register */
++#define DSIM_SWRST_REG                0x4     /* Software reset register */
++#define DSIM_CLKCTRL_REG      0x8     /* Clock control register */
++#define DSIM_TIMEOUT_REG      0xc     /* Time out register */
++#define DSIM_CONFIG_REG               0x10    /* Configuration register */
++#define DSIM_ESCMODE_REG      0x14    /* Escape mode register */
++
++/* Main display image resolution register */
++#define DSIM_MDRESOL_REG      0x18
++#define DSIM_MVPORCH_REG      0x1c    /* Main display Vporch register */
++#define DSIM_MHPORCH_REG      0x20    /* Main display Hporch register */
++#define DSIM_MSYNC_REG                0x24    /* Main display sync area register */
++
++/* Sub display image resolution register */
++#define DSIM_SDRESOL_REG      0x28
++#define DSIM_INTSRC_REG               0x2c    /* Interrupt source register */
++#define DSIM_INTMSK_REG               0x30    /* Interrupt mask register */
++#define DSIM_PKTHDR_REG               0x34    /* Packet Header FIFO register */
++#define DSIM_PAYLOAD_REG      0x38    /* Payload FIFO register */
++#define DSIM_RXFIFO_REG               0x3c    /* Read FIFO register */
++#define DSIM_FIFOTHLD_REG     0x40    /* FIFO threshold level register */
++#define DSIM_FIFOCTRL_REG     0x44    /* FIFO status and control register */
++
++/* FIFO memory AC characteristic register */
++#define DSIM_PLLCTRL_REG      0x4c    /* PLL control register */
++#define DSIM_PLLTMR_REG               0x50    /* PLL timer register */
++#define DSIM_PHYACCHR_REG     0x54    /* D-PHY AC characteristic register */
++#define DSIM_PHYACCHR1_REG    0x58    /* D-PHY AC characteristic register1 */
++
++/* DSIM_STATUS */
++#define DSIM_STOP_STATE_DAT(x)                (((x) & 0xf) << 0)
++#define DSIM_STOP_STATE_CLK           (1 << 8)
++#define DSIM_TX_READY_HS_CLK          (1 << 10)
++#define DSIM_PLL_STABLE                       (1 << 31)
++
++/* DSIM_SWRST */
++#define DSIM_FUNCRST                  (1 << 16)
++#define DSIM_SWRST                    (1 << 0)
++
++/* DSIM_TIMEOUT */
++#define DSIM_LPDR_TOUT(x)             ((x) << 0)
++#define DSIM_BTA_TOUT(x)              ((x) << 16)
++
++/* DSIM_CLKCTRL */
++#define DSIM_ESC_PRESCALER(x)         (((x) & 0xffff) << 0)
++#define DSIM_ESC_PRESCALER_MASK               (0xffff << 0)
++#define DSIM_LANE_ESC_CLK_EN_CLK      (1 << 19)
++#define DSIM_LANE_ESC_CLK_EN_DATA(x)  (((x) & 0xf) << 20)
++#define DSIM_LANE_ESC_CLK_EN_DATA_MASK        (0xf << 20)
++#define DSIM_BYTE_CLKEN                       (1 << 24)
++#define DSIM_BYTE_CLK_SRC(x)          (((x) & 0x3) << 25)
++#define DSIM_BYTE_CLK_SRC_MASK                (0x3 << 25)
++#define DSIM_PLL_BYPASS                       (1 << 27)
++#define DSIM_ESC_CLKEN                        (1 << 28)
++#define DSIM_TX_REQUEST_HSCLK         (1 << 31)
++
++/* DSIM_CONFIG */
++#define DSIM_LANE_EN_CLK              (1 << 0)
++#define DSIM_LANE_EN(x)                       (((x) & 0xf) << 1)
++#define DSIM_NUM_OF_DATA_LANE(x)      (((x) & 0x3) << 5)
++#define DSIM_SUB_PIX_FORMAT(x)                (((x) & 0x7) << 8)
++#define DSIM_MAIN_PIX_FORMAT_MASK     (0x7 << 12)
++#define DSIM_MAIN_PIX_FORMAT_RGB888   (0x7 << 12)
++#define DSIM_MAIN_PIX_FORMAT_RGB666   (0x6 << 12)
++#define DSIM_MAIN_PIX_FORMAT_RGB666_P (0x5 << 12)
++#define DSIM_MAIN_PIX_FORMAT_RGB565   (0x4 << 12)
++#define DSIM_SUB_VC                   (((x) & 0x3) << 16)
++#define DSIM_MAIN_VC                  (((x) & 0x3) << 18)
++#define DSIM_HSA_MODE                 (1 << 20)
++#define DSIM_HBP_MODE                 (1 << 21)
++#define DSIM_HFP_MODE                 (1 << 22)
++#define DSIM_HSE_MODE                 (1 << 23)
++#define DSIM_AUTO_MODE                        (1 << 24)
++#define DSIM_VIDEO_MODE                       (1 << 25)
++#define DSIM_BURST_MODE                       (1 << 26)
++#define DSIM_SYNC_INFORM              (1 << 27)
++#define DSIM_EOT_DISABLE              (1 << 28)
++#define DSIM_MFLUSH_VS                        (1 << 29)
++
++/* DSIM_ESCMODE */
++#define DSIM_TX_TRIGGER_RST           (1 << 4)
++#define DSIM_TX_LPDT_LP                       (1 << 6)
++#define DSIM_CMD_LPDT_LP              (1 << 7)
++#define DSIM_FORCE_BTA                        (1 << 16)
++#define DSIM_FORCE_STOP_STATE         (1 << 20)
++#define DSIM_STOP_STATE_CNT(x)                (((x) & 0x7ff) << 21)
++#define DSIM_STOP_STATE_CNT_MASK      (0x7ff << 21)
++
++/* DSIM_MDRESOL */
++#define DSIM_MAIN_STAND_BY            (1 << 31)
++#define DSIM_MAIN_VRESOL(x)           (((x) & 0x7ff) << 16)
++#define DSIM_MAIN_HRESOL(x)           (((x) & 0X7ff) << 0)
++
++/* DSIM_MVPORCH */
++#define DSIM_CMD_ALLOW(x)             ((x) << 28)
++#define DSIM_STABLE_VFP(x)            ((x) << 16)
++#define DSIM_MAIN_VBP(x)              ((x) << 0)
++#define DSIM_CMD_ALLOW_MASK           (0xf << 28)
++#define DSIM_STABLE_VFP_MASK          (0x7ff << 16)
++#define DSIM_MAIN_VBP_MASK            (0x7ff << 0)
++
++/* DSIM_MHPORCH */
++#define DSIM_MAIN_HFP(x)              ((x) << 16)
++#define DSIM_MAIN_HBP(x)              ((x) << 0)
++#define DSIM_MAIN_HFP_MASK            ((0xffff) << 16)
++#define DSIM_MAIN_HBP_MASK            ((0xffff) << 0)
++
++/* DSIM_MSYNC */
++#define DSIM_MAIN_VSA(x)              ((x) << 22)
++#define DSIM_MAIN_HSA(x)              ((x) << 0)
++#define DSIM_MAIN_VSA_MASK            ((0x3ff) << 22)
++#define DSIM_MAIN_HSA_MASK            ((0xffff) << 0)
++
++/* DSIM_SDRESOL */
++#define DSIM_SUB_STANDY(x)            ((x) << 31)
++#define DSIM_SUB_VRESOL(x)            ((x) << 16)
++#define DSIM_SUB_HRESOL(x)            ((x) << 0)
++#define DSIM_SUB_STANDY_MASK          ((0x1) << 31)
++#define DSIM_SUB_VRESOL_MASK          ((0x7ff) << 16)
++#define DSIM_SUB_HRESOL_MASK          ((0x7ff) << 0)
++
++/* DSIM_INTSRC */
++#define DSIM_INT_PLL_STABLE           (1 << 31)
++#define DSIM_INT_SW_RST_RELEASE               (1 << 30)
++#define DSIM_INT_SFR_FIFO_EMPTY               (1 << 29)
++#define DSIM_INT_BTA                  (1 << 25)
++#define DSIM_INT_FRAME_DONE           (1 << 24)
++#define DSIM_INT_RX_TIMEOUT           (1 << 21)
++#define DSIM_INT_BTA_TIMEOUT          (1 << 20)
++#define DSIM_INT_RX_DONE              (1 << 18)
++#define DSIM_INT_RX_TE                        (1 << 17)
++#define DSIM_INT_RX_ACK                       (1 << 16)
++#define DSIM_INT_RX_ECC_ERR           (1 << 15)
++#define DSIM_INT_RX_CRC_ERR           (1 << 14)
++
++/* DSIM_FIFOCTRL */
++#define DSIM_FULL_H_SFR                       (1 << 23)
++
++/* DSIM_PHYACCHR */
++#define DSIM_AFC_EN                   (1 << 14)
++#define DSIM_AFC_CTL(x)                       (((x) & 0x7) << 5)
++
++/* DSIM_PLLCTRL */
++#define DSIM_FREQ_BAND(x)             ((x) << 24)
++#define DSIM_PLL_EN                   (1 << 23)
++#define DSIM_PLL_P(x)                 ((x) << 13)
++#define DSIM_PLL_M(x)                 ((x) << 4)
++#define DSIM_PLL_S(x)                 ((x) << 1)
++
++#define DSI_MAX_BUS_WIDTH             4
++#define DSI_NUM_VIRTUAL_CHANNELS      4
++#define DSI_TX_FIFO_SIZE              2048
++#define DSI_RX_FIFO_SIZE              256
++#define DSI_XFER_TIMEOUT_MS           100
++#define DSI_RX_FIFO_EMPTY             0x30800002
++
++enum exynos_dsi_transfer_type {
++      EXYNOS_DSI_TX,
++      EXYNOS_DSI_RX,
++};
++
++struct exynos_dsi_transfer {
++      struct list_head list;
++      struct completion completed;
++      int result;
++      u8 type;
++      u8 data[2];
++
++      const u8 *tx_payload;
++      u16 tx_len;
++      u16 tx_done;
++
++      u8 *rx_payload;
++      u16 rx_len;
++      u16 rx_done;
++};
++
++struct exynos_dsi {
++      struct video_source out;
++      struct mipi_dsi_interface_params params;
++      bool streaming;
++      bool enabled;
++
++      struct platform_device *pdev;
++      struct device *dev;
++      struct resource *res;
++      struct clk *pll_clk;
++      struct clk *bus_clk;
++      unsigned int irq;
++      void __iomem *reg_base;
++      struct regulator_bulk_data supplies[2];
++      struct exynos_dsi_platform_data *pd;
++
++      spinlock_t transfer_lock;
++      struct list_head transfer_list;
++};
++
++#define src_to_dsi(src)               container_of(src, struct exynos_dsi, out)
++
++/*
++ * H/W control
++ */
++
++static void exynos_dsi_reset(struct exynos_dsi *dsi)
++{
++      writel(DSIM_SWRST, dsi->reg_base + DSIM_SWRST_REG);
++
++      udelay(10);
++}
++
++#ifndef MHZ
++#define MHZ   (1000*1000)
++#endif
++
++static const unsigned long freq_bands[] = {
++      100 * MHZ, 120 * MHZ, 160 * MHZ, 200 * MHZ,
++      270 * MHZ, 320 * MHZ, 390 * MHZ, 450 * MHZ,
++      510 * MHZ, 560 * MHZ, 640 * MHZ, 690 * MHZ,
++      770 * MHZ, 870 * MHZ, 950 * MHZ,
++};
++
++static const int afc_settings[] = {
++      1, 0, 3, 2, 5, 4,
++};
++
++static unsigned long exynos_dsi_pll_find_pms(struct exynos_dsi *dsi,
++              unsigned long fin, unsigned long fout, u8 *p, u16 *m, u8 *s)
++{
++      unsigned long best_freq = 0;
++      u32 min_delta = 0xffffffff;
++      u8 p_min, p_max;
++      u8 _p, best_p;
++      u16 _m, best_m;
++      u8 _s, best_s;
++
++      p_min = DIV_ROUND_UP(fin, (12 * MHZ));
++      p_max = fin / (6 * MHZ);
++
++      for (_p = p_min; _p <= p_max; ++_p) {
++              for (_s = 0; _s <= 5; ++_s) {
++                      u64 tmp;
++                      u32 delta;
++                      u16 div;
++
++                      tmp = (u64)fout * (_p << _s);
++                      do_div(tmp, fin);
++                      _m = tmp;
++                      if (_m < 41 || _m > 125)
++                              continue;
++
++                      tmp = (u64)_m * fin;
++                      do_div(tmp, _p);
++                      if (tmp < 500 * MHZ || tmp > 1000 * MHZ)
++                              continue;
++
++                      tmp = (u64)_m * fin;
++                      div = (_p << _s);
++                      do_div(tmp, div);
++
++                      delta = abs(fout - tmp);
++                      if (delta < min_delta) {
++                              best_p = _p;
++                              best_m = _m;
++                              best_s = _s;
++                              min_delta = delta;
++                              best_freq = tmp;
++                      }
++              }
++      }
++
++      if (best_freq) {
++              *p = best_p;
++              *m = best_m;
++              *s = best_s;
++      }
++
++      return best_freq;
++}
++
++static unsigned long exynos_dsi_set_pll(struct exynos_dsi *dsi,
++                                                      unsigned long freq)
++{
++      unsigned long fin, fout, fin_pll;
++      int timeout;
++      u8 p;
++      u16 m;
++      u8 s;
++      int band;
++      int afc;
++      u32 reg;
++
++      clk_set_rate(dsi->pll_clk, dsi->pd->pll_clk_rate);
++
++      fin = clk_get_rate(dsi->pll_clk);
++      if (!fin) {
++              dev_err(dsi->dev, "failed to get PLL clock frequency\n");
++              return 0;
++      }
++
++      dev_dbg(dsi->dev, "PLL input frequency: %lu\n", fin);
++
++      fout = exynos_dsi_pll_find_pms(dsi, fin, freq, &p, &m, &s);
++      if (!fout) {
++              dev_err(dsi->dev,
++                      "failed to find PLL coefficients for requested frequency\n");
++              return -EFAULT;
++      }
++
++      dev_dbg(dsi->dev, "PLL freq %lu, (p %d, m %d, s %d)\n", fout, p, m, s);
++
++      for (band = 0; band < ARRAY_SIZE(freq_bands); ++band)
++              if (fout < freq_bands[band])
++                      break;
++
++      fin_pll = DIV_ROUND_CLOSEST(fin, p);
++      fin_pll /= MHZ;
++      if (fin_pll > 6)
++              fin_pll -= 6;
++      else
++              fin_pll = 0;
++      if (fin_pll >= ARRAY_SIZE(afc_settings))
++              fin_pll = ARRAY_SIZE(afc_settings) - 1;
++
++      afc = afc_settings[fin_pll];
++
++      dev_dbg(dsi->dev, "freq band %d, afc_setting %d\n", band, afc);
++
++      writel(dsi->pd->pll_stable_time, dsi->reg_base + DSIM_PLLTMR_REG);
++
++      reg = DSIM_AFC_CTL(afc) | DSIM_AFC_EN;
++      writel(reg, dsi->reg_base + DSIM_PHYACCHR_REG);
++
++      reg = DSIM_FREQ_BAND(band) | DSIM_PLL_EN
++                      | DSIM_PLL_P(p) | DSIM_PLL_M(m) | DSIM_PLL_S(s);
++      writel(reg, dsi->reg_base + DSIM_PLLCTRL_REG);
++
++      timeout = 1000;
++      do {
++              if (timeout-- == 0) {
++                      dev_err(dsi->dev, "PLL failed to stabilize\n");
++                      return -EFAULT;
++              }
++              reg = readl(dsi->reg_base + DSIM_STATUS_REG);
++      } while ((reg & DSIM_PLL_STABLE) == 0);
++
++      return fout;
++}
++
++static int exynos_dsi_enable_clock(struct exynos_dsi *dsi)
++{
++      unsigned long hs_clk, byte_clk, esc_clk;
++      unsigned long esc_div;
++      u32 reg;
++
++      hs_clk = exynos_dsi_set_pll(dsi, dsi->params.hs_clk_freq);
++      if (!hs_clk) {
++              dev_err(dsi->dev, "failed to configure DSI PLL\n");
++              return -EFAULT;
++      }
++
++      byte_clk = hs_clk / 8;
++      esc_div = DIV_ROUND_UP(byte_clk, dsi->params.esc_clk_freq);
++      esc_clk = byte_clk / esc_div;
++
++      if (esc_clk > 20 * MHZ) {
++              ++esc_div;
++              esc_clk = byte_clk / esc_div;
++      }
++
++      dev_dbg(dsi->dev, "hs_clk = %lu, byte_clk = %lu, esc_clk = %lu\n",
++                                              hs_clk, byte_clk, esc_clk);
++
++      reg = readl(dsi->reg_base + DSIM_CLKCTRL_REG);
++      reg &= ~(DSIM_ESC_PRESCALER_MASK | DSIM_LANE_ESC_CLK_EN_CLK
++                      | DSIM_LANE_ESC_CLK_EN_DATA_MASK | DSIM_PLL_BYPASS
++                      | DSIM_BYTE_CLK_SRC_MASK);
++      reg |= DSIM_ESC_CLKEN | DSIM_BYTE_CLKEN
++                      | DSIM_ESC_PRESCALER(esc_div)
++                      | DSIM_LANE_ESC_CLK_EN_CLK
++                      | DSIM_LANE_ESC_CLK_EN_DATA(dsi->params.data_lanes)
++                      | DSIM_BYTE_CLK_SRC(0)
++                      | DSIM_TX_REQUEST_HSCLK;
++      writel(reg, dsi->reg_base + DSIM_CLKCTRL_REG);
++
++      return 0;
++}
++
++static void exynos_dsi_disable_clock(struct exynos_dsi *dsi)
++{
++      u32 reg;
++
++      reg = readl(dsi->reg_base + DSIM_CLKCTRL_REG);
++      reg &= ~(DSIM_LANE_ESC_CLK_EN_CLK | DSIM_LANE_ESC_CLK_EN_DATA_MASK |
++                      DSIM_ESC_CLKEN | DSIM_BYTE_CLKEN);
++      writel(reg, dsi->reg_base + DSIM_CLKCTRL_REG);
++
++      reg = readl(dsi->reg_base + DSIM_PLLCTRL_REG);
++      reg &= ~DSIM_PLL_EN;
++      writel(reg, dsi->reg_base + DSIM_PLLCTRL_REG);
++}
++
++static int exynos_dsi_init_link(struct exynos_dsi *dsi)
++{
++      u32 reg;
++      int timeout;
++
++      /* Initialize FIFO pointers */
++      reg = readl(dsi->reg_base + DSIM_FIFOCTRL_REG);
++      reg &= ~0x1f;
++      writel(reg, dsi->reg_base + DSIM_FIFOCTRL_REG);
++
++      usleep_range(10000, 10000);
++
++      reg |= 0x1f;
++      writel(reg, dsi->reg_base + DSIM_FIFOCTRL_REG);
++
++      usleep_range(10000, 10000);
++
++      /* DSI configuration */
++      reg = 0;
++
++      if (dsi->params.mode & DSI_MODE_VIDEO) {
++              reg |= DSIM_VIDEO_MODE;
++
++              if (!(dsi->params.mode & DSI_MODE_VSYNC_FLUSH))
++                      reg |= DSIM_MFLUSH_VS;
++              if (!(dsi->params.mode & DSI_MODE_EOT_PACKET))
++                      reg |= DSIM_EOT_DISABLE;
++              if (dsi->params.mode & DSI_MODE_VIDEO_SYNC_PULSE)
++                      reg |= DSIM_SYNC_INFORM;
++              if (dsi->params.mode & DSI_MODE_VIDEO_BURST)
++                      reg |= DSIM_BURST_MODE;
++              if (dsi->params.mode & DSI_MODE_VIDEO_AUTO_VERT)
++                      reg |= DSIM_AUTO_MODE;
++              if (dsi->params.mode & DSI_MODE_VIDEO_HSE)
++                      reg |= DSIM_HSE_MODE;
++              if (!(dsi->params.mode & DSI_MODE_VIDEO_HFP))
++                      reg |= DSIM_HFP_MODE;
++              if (!(dsi->params.mode & DSI_MODE_VIDEO_HBP))
++                      reg |= DSIM_HBP_MODE;
++              if (!(dsi->params.mode & DSI_MODE_VIDEO_HSA))
++                      reg |= DSIM_HSA_MODE;
++      }
++
++      switch (dsi->params.format) {
++      case DSI_FMT_RGB888:
++              reg |= DSIM_MAIN_PIX_FORMAT_RGB888;
++              break;
++      case DSI_FMT_RGB666:
++              reg |= DSIM_MAIN_PIX_FORMAT_RGB666;
++              break;
++      case DSI_FMT_RGB666_PACKED:
++              reg |= DSIM_MAIN_PIX_FORMAT_RGB666_P;
++              break;
++      case DSI_FMT_RGB565:
++              reg |= DSIM_MAIN_PIX_FORMAT_RGB565;
++              break;
++      default:
++              dev_err(dsi->dev, "invalid pixel format\n");
++              return -EINVAL;
++      }
++
++      switch (dsi->params.data_lanes) {
++      case 0x1:
++              reg |= DSIM_NUM_OF_DATA_LANE(0);
++              break;
++      case 0x3:
++              reg |= DSIM_NUM_OF_DATA_LANE(1);
++              break;
++      case 0x7:
++              reg |= DSIM_NUM_OF_DATA_LANE(2);
++              break;
++      case 0xf:
++              reg |= DSIM_NUM_OF_DATA_LANE(3);
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      writel(reg, dsi->reg_base + DSIM_CONFIG_REG);
++
++      reg |= DSIM_LANE_EN_CLK;
++      writel(reg, dsi->reg_base + DSIM_CONFIG_REG);
++
++      reg |= DSIM_LANE_EN(dsi->params.data_lanes);
++      writel(reg, dsi->reg_base + DSIM_CONFIG_REG);
++
++      /* Clock configuration */
++      exynos_dsi_enable_clock(dsi);
++
++      /* Check clock and data lane state are stop state */
++      timeout = 100;
++      do {
++              if (timeout-- == 0) {
++                      dev_err(dsi->dev, "waiting for bus lanes timed out\n");
++                      return -EFAULT;
++              }
++
++              reg = readl(dsi->reg_base + DSIM_STATUS_REG);
++              if ((reg & DSIM_STOP_STATE_DAT(dsi->params.data_lanes))
++                  != DSIM_STOP_STATE_DAT(dsi->params.data_lanes))
++                      continue;
++      } while (!(reg & (DSIM_STOP_STATE_CLK | DSIM_TX_READY_HS_CLK)));
++
++      reg = readl(dsi->reg_base + DSIM_ESCMODE_REG);
++      reg &= ~DSIM_STOP_STATE_CNT_MASK;
++      reg |= DSIM_STOP_STATE_CNT(dsi->pd->stop_holding_cnt);
++      writel(reg, dsi->reg_base + DSIM_ESCMODE_REG);
++
++      reg = DSIM_BTA_TOUT(dsi->pd->bta_timeout)
++                                      | DSIM_LPDR_TOUT(dsi->pd->rx_timeout);
++      writel(reg, dsi->reg_base + DSIM_TIMEOUT_REG);
++
++      return 0;
++}
++
++static int exynos_dsi_set_display_mode(struct exynos_dsi *dsi)
++{
++      const struct videomode *mode;
++      u32 reg;
++      int ret;
++
++      ret = display_entity_get_modes(dsi->out.sink, &mode);
++      if (ret < 0) {
++              dev_err(dsi->dev, "failed to get display video mode\n");
++              return ret;
++      }
++
++      if (dsi->params.mode & DSI_MODE_VIDEO) {
++              reg = DSIM_CMD_ALLOW(dsi->params.cmd_allow)
++                      | DSIM_STABLE_VFP(mode->vfront_porch)
++                      | DSIM_MAIN_VBP(mode->vback_porch);
++              writel(reg, dsi->reg_base + DSIM_MVPORCH_REG);
++
++              reg = DSIM_MAIN_HFP(mode->hfront_porch)
++                      | DSIM_MAIN_HBP(mode->hback_porch);
++              writel(reg, dsi->reg_base + DSIM_MHPORCH_REG);
++
++              reg = DSIM_MAIN_VSA(mode->vsync_len)
++                      | DSIM_MAIN_HSA(mode->hsync_len);
++              writel(reg, dsi->reg_base + DSIM_MSYNC_REG);
++      }
++
++      reg = DSIM_MAIN_HRESOL(mode->hactive) | DSIM_MAIN_VRESOL(mode->vactive);
++      writel(reg, dsi->reg_base + DSIM_MDRESOL_REG);
++
++      dev_dbg(dsi->dev, "LCD width = %d, height = %d\n",
++                                              mode->hactive, mode->vactive);
++
++      return 0;
++}
++
++static void exynos_dsi_set_display_enable(struct exynos_dsi *dsi, bool enable)
++{
++      u32 reg;
++
++      reg = readl(dsi->reg_base + DSIM_MDRESOL_REG);
++      if (enable)
++              reg |= DSIM_MAIN_STAND_BY;
++      else
++              reg &= ~DSIM_MAIN_STAND_BY;
++      writel(reg, dsi->reg_base + DSIM_MDRESOL_REG);
++}
++
++/*
++ * FIFO
++ */
++
++static int exynos_dsi_wait_for_hdr_fifo(struct exynos_dsi *dsi)
++{
++      int timeout = 20000;
++
++      do {
++              u32 reg = readl(dsi->reg_base + DSIM_FIFOCTRL_REG);
++
++              if (!(reg & DSIM_FULL_H_SFR))
++                      return 0;
++
++              if (!cond_resched())
++                      usleep_range(950, 1050);
++      } while (--timeout);
++
++      return -ETIMEDOUT;
++}
++
++static void exynos_dsi_send_to_fifo(struct exynos_dsi *dsi,
++                                      struct exynos_dsi_transfer *xfer)
++{
++      const u8 *payload = xfer->tx_payload + xfer->tx_done;
++      u16 length = xfer->tx_len - xfer->tx_done;
++      bool first = !xfer->tx_done;
++      u32 reg;
++
++      dev_dbg(dsi->dev,
++              "< xfer %p, tx_len %u, tx_done %u, rx_len %u, rx_done %u\n",
++              xfer, xfer->tx_len, xfer->tx_done, xfer->rx_len, xfer->rx_done);
++
++      if (length > DSI_TX_FIFO_SIZE)
++              length = DSI_TX_FIFO_SIZE;
++
++      xfer->tx_done += length;
++
++      /* Send payload */
++      while (length >= 4) {
++              reg = (payload[3] << 24) | (payload[2] << 16)
++                                      | (payload[1] << 8) | payload[0];
++              writel(reg, dsi->reg_base + DSIM_PAYLOAD_REG);
++              payload += 4;
++              length -= 4;
++      }
++
++      reg = 0;
++      switch (length) {
++      case 3:
++              reg |= payload[2] << 16;
++              /* Fall through */
++      case 2:
++              reg |= payload[1] << 8;
++              /* Fall through */
++      case 1:
++              reg |= payload[0];
++              writel(reg, dsi->reg_base + DSIM_PAYLOAD_REG);
++              break;
++      case 0:
++              /* Do nothing */
++              break;
++      }
++
++      /* Send packet header */
++      if (!first)
++              return;
++
++      if (xfer->rx_len) {
++              reg = (xfer->rx_len << 8)
++                              | MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE;
++              if (exynos_dsi_wait_for_hdr_fifo(dsi)) {
++                      dev_err(dsi->dev,
++                                      "waiting for header FIFO timed out\n");
++                      return;
++              }
++              writel(reg, dsi->reg_base + DSIM_PKTHDR_REG);
++      }
++
++      reg = (xfer->data[1] << 16) | (xfer->data[0] << 8) | xfer->type;
++      if (exynos_dsi_wait_for_hdr_fifo(dsi)) {
++              dev_err(dsi->dev, "waiting for header FIFO timed out\n");
++              return;
++      }
++      writel(reg, dsi->reg_base + DSIM_PKTHDR_REG);
++}
++
++static void exynos_dsi_read_from_fifo(struct exynos_dsi *dsi,
++                                      struct exynos_dsi_transfer *xfer)
++{
++      u8 *payload = xfer->rx_payload + xfer->rx_done;
++      bool first = !xfer->rx_done;
++      u16 length;
++      u32 reg;
++
++      if (first) {
++              reg = readl(dsi->reg_base + DSIM_RXFIFO_REG);
++
++              switch (reg & 0x3f) {
++              case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE:
++              case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE:
++                      if (xfer->rx_len >= 2) {
++                              payload[1] = reg >> 16;
++                              ++xfer->rx_done;
++                      }
++                      /* Fall through */
++              case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE:
++              case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE:
++                      payload[0] = reg >> 8;
++                      ++xfer->rx_done;
++                      xfer->rx_len = xfer->rx_done;
++                      xfer->result = 0;
++                      goto clear_fifo;
++              }
++
++              length = (reg >> 8) & 0xffff;
++              if (length > xfer->rx_len) {
++                      dev_err(dsi->dev,
++                              "response too long (expected %u, got %u bytes)\n",
++                              xfer->rx_len, length);
++                      xfer->rx_len = 0;
++                      xfer->rx_done = 0;
++                      xfer->result = -EFAULT;
++                      goto clear_fifo;
++              }
++              if (length < xfer->rx_len)
++                      xfer->rx_len = length;
++      }
++
++      length = xfer->rx_len - xfer->rx_done;
++      xfer->rx_done += length;
++
++      /* Receive payload */
++      while (length >= 4) {
++              reg = readl(dsi->reg_base + DSIM_RXFIFO_REG);
++              payload[0] = (reg >>  0) & 0xff;
++              payload[1] = (reg >>  8) & 0xff;
++              payload[2] = (reg >> 16) & 0xff;
++              payload[3] = (reg >> 24) & 0xff;
++              payload += 4;
++              length -= 4;
++      }
++
++      if (length) {
++              reg = readl(dsi->reg_base + DSIM_RXFIFO_REG);
++              switch (length) {
++              case 3:
++                      payload[2] = (reg >> 16) & 0xff;
++                      /* Fall through */
++              case 2:
++                      payload[1] = (reg >> 8) & 0xff;
++                      /* Fall through */
++              case 1:
++                      payload[0] = reg & 0xff;
++              }
++      }
++
++      if (xfer->rx_done == xfer->rx_len)
++              xfer->result = 0;
++
++clear_fifo:
++      length = DSI_RX_FIFO_SIZE / 4;
++      do {
++              reg = readl(dsi->reg_base + DSIM_RXFIFO_REG);
++              if (reg == DSI_RX_FIFO_EMPTY)
++                      break;
++      } while (--length);
++}
++
++/*
++ * Transfer
++ */
++
++static void exynos_dsi_transfer_start(struct exynos_dsi *dsi)
++{
++      unsigned long flags;
++      struct exynos_dsi_transfer *xfer;
++      bool start = false;
++
++again:
++      spin_lock_irqsave(&dsi->transfer_lock, flags);
++
++      if (list_empty(&dsi->transfer_list)) {
++              spin_unlock_irqrestore(&dsi->transfer_lock, flags);
++              return;
++      }
++
++      xfer = list_first_entry(&dsi->transfer_list,
++                                      struct exynos_dsi_transfer, list);
++
++      spin_unlock_irqrestore(&dsi->transfer_lock, flags);
++
++      if (xfer->tx_len && xfer->tx_done == xfer->tx_len)
++              /* waiting for RX */
++              return;
++
++      exynos_dsi_send_to_fifo(dsi, xfer);
++
++      if (xfer->tx_len || xfer->rx_len)
++              return;
++
++      xfer->result = 0;
++      complete(&xfer->completed);
++
++      spin_lock_irqsave(&dsi->transfer_lock, flags);
++
++      list_del_init(&xfer->list);
++      start = !list_empty(&dsi->transfer_list);
++
++      spin_unlock_irqrestore(&dsi->transfer_lock, flags);
++
++      if (start)
++              goto again;
++}
++
++static bool exynos_dsi_transfer_finish(struct exynos_dsi *dsi)
++{
++      struct exynos_dsi_transfer *xfer;
++      unsigned long flags;
++      bool start = true;
++
++      spin_lock_irqsave(&dsi->transfer_lock, flags);
++
++      if (list_empty(&dsi->transfer_list)) {
++              spin_unlock_irqrestore(&dsi->transfer_lock, flags);
++              dev_warn(dsi->dev, "unexpected TX/RX interrupt\n");
++              return false;
++      }
++
++      xfer = list_first_entry(&dsi->transfer_list,
++                                      struct exynos_dsi_transfer, list);
++
++      spin_unlock_irqrestore(&dsi->transfer_lock, flags);
++
++      dev_dbg(dsi->dev,
++              "> xfer %p, tx_len %u, tx_done %u, rx_len %u, rx_done %u\n",
++              xfer, xfer->tx_len, xfer->tx_done, xfer->rx_len, xfer->rx_done);
++
++      if (xfer->tx_done != xfer->tx_len)
++              return true;
++
++      if (xfer->rx_done != xfer->rx_len)
++              exynos_dsi_read_from_fifo(dsi, xfer);
++
++      if (xfer->rx_done != xfer->rx_len)
++              return true;
++
++      spin_lock_irqsave(&dsi->transfer_lock, flags);
++
++      list_del_init(&xfer->list);
++      start = !list_empty(&dsi->transfer_list);
++
++      spin_unlock_irqrestore(&dsi->transfer_lock, flags);
++
++      if (!xfer->rx_len)
++              xfer->result = 0;
++      complete(&xfer->completed);
++
++      return start;
++}
++
++static void exynos_dsi_remove_transfer(struct exynos_dsi *dsi,
++                                      struct exynos_dsi_transfer *xfer)
++{
++      unsigned long flags;
++      bool start;
++
++      spin_lock_irqsave(&dsi->transfer_lock, flags);
++
++      if (!list_empty(&dsi->transfer_list)
++          && xfer == list_first_entry(&dsi->transfer_list,
++                                      struct exynos_dsi_transfer, list)) {
++              list_del_init(&xfer->list);
++              start = !list_empty(&dsi->transfer_list);
++              spin_unlock_irqrestore(&dsi->transfer_lock, flags);
++              if (start)
++                      exynos_dsi_transfer_start(dsi);
++              return;
++      }
++
++      list_del_init(&xfer->list);
++
++      spin_unlock_irqrestore(&dsi->transfer_lock, flags);
++}
++
++static int exynos_dsi_transfer(struct exynos_dsi *dsi,
++                                      struct exynos_dsi_transfer *xfer)
++{
++      unsigned long flags;
++      bool stopped;
++
++      xfer->tx_done = 0;
++      xfer->rx_done = 0;
++      xfer->result = -ETIMEDOUT;
++      init_completion(&xfer->completed);
++
++      spin_lock_irqsave(&dsi->transfer_lock, flags);
++
++      stopped = list_empty(&dsi->transfer_list);
++      list_add_tail(&xfer->list, &dsi->transfer_list);
++
++      spin_unlock_irqrestore(&dsi->transfer_lock, flags);
++
++      if (stopped)
++              exynos_dsi_transfer_start(dsi);
++
++      wait_for_completion_timeout(&xfer->completed,
++                              msecs_to_jiffies(DSI_XFER_TIMEOUT_MS));
++      if (xfer->result == -ETIMEDOUT) {
++              exynos_dsi_remove_transfer(dsi, xfer);
++              dev_err(dsi->dev, "xfer timed out\n");
++              return -ETIMEDOUT;
++      }
++
++      /* Also covers hardware timeout condition */
++      return xfer->result;
++}
++
++/*
++ * Interrupt handler
++ */
++
++static irqreturn_t exynos_dsi_irq(int irq, void *dev_id)
++{
++      struct exynos_dsi *dsi = dev_id;
++      u32 status;
++
++      status = readl(dsi->reg_base + DSIM_INTSRC_REG);
++      writel(status, dsi->reg_base + DSIM_INTSRC_REG);
++
++      dev_dbg(dsi->dev, "%s: status = %08x\n", __func__, status);
++
++      if (status & DSIM_INT_SW_RST_RELEASE) {
++              u32 mask = ~(DSIM_INT_RX_DONE | DSIM_INT_SFR_FIFO_EMPTY);
++              writel(mask, dsi->reg_base + DSIM_INTMSK_REG);
++              return IRQ_HANDLED;
++      }
++
++      if (exynos_dsi_transfer_finish(dsi))
++              exynos_dsi_transfer_start(dsi);
++
++      return IRQ_HANDLED;
++}
++
++/*
++ * Display source
++ */
++
++static int exynos_dsi_set_stream(struct video_source *src,
++                                      enum video_source_stream_state state)
++{
++      struct exynos_dsi *dsi = src_to_dsi(src);
++
++      if (pm_runtime_suspended(dsi->dev))
++              return -EINVAL;
++
++      switch (state) {
++      case DISPLAY_ENTITY_STREAM_STOPPED:
++              exynos_dsi_set_display_enable(dsi, false);
++              dsi->streaming = false;
++              break;
++
++      case DISPLAY_ENTITY_STREAM_CONTINUOUS:
++              exynos_dsi_set_display_mode(dsi);
++              exynos_dsi_set_display_enable(dsi, true);
++              dsi->streaming = true;
++              break;
++
++      default:
++              return -EINVAL;
++      }
++
++      return 0;
++}
++
++/* enable/disable dsi bus */
++static int exynos_dsi_enable(struct video_source *src)
++{
++      struct display_entity_interface_params params;
++      struct exynos_dsi *dsi = src_to_dsi(src);
++      int ret;
++
++      if (dsi->enabled)
++              return 0;
++
++      ret = display_entity_get_params(src->sink, &params);
++      if (ret < 0)
++              return ret;
++      dsi->params = params.p.dsi;
++
++      regulator_bulk_enable(ARRAY_SIZE(dsi->supplies), dsi->supplies);
++
++      clk_prepare_enable(dsi->bus_clk);
++      clk_prepare_enable(dsi->pll_clk);
++
++      if (dsi->pd->phy_enable)
++              dsi->pd->phy_enable(dsi->pdev, true);
++
++      exynos_dsi_reset(dsi);
++      exynos_dsi_init_link(dsi);
++
++      dsi->enabled = true;
++
++      return 0;
++}
++
++static int exynos_dsi_disable(struct video_source *src)
++{
++      struct exynos_dsi *dsi = src_to_dsi(src);
++
++      if (!dsi->enabled)
++              return 0;
++
++      if (dsi->streaming)
++              return -EBUSY;
++
++      dsi->enabled = false;
++
++      exynos_dsi_disable_clock(dsi);
++
++      if (dsi->pd->phy_enable)
++              dsi->pd->phy_enable(dsi->pdev, false);
++
++      clk_disable_unprepare(dsi->pll_clk);
++      clk_disable_unprepare(dsi->bus_clk);
++
++      regulator_bulk_disable(ARRAY_SIZE(dsi->supplies), dsi->supplies);
++
++      return 0;
++}
++
++/* data transfer */
++static int exynos_dsi_dcs_write(struct video_source *src, int channel,
++                                              const u8 *data, size_t len)
++{
++      struct exynos_dsi *dsi = src_to_dsi(src);
++      struct exynos_dsi_transfer xfer;
++
++      if (!len)
++              return -EINVAL;
++
++      switch (len) {
++      case 1:
++              len = 0;
++              xfer.type = MIPI_DSI_DCS_SHORT_WRITE;
++              xfer.data[0] = data[0];
++              xfer.data[1] = 0;
++              break;
++      case 2:
++              len = 0;
++              xfer.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM;
++              xfer.data[0] = data[0];
++              xfer.data[1] = data[1];
++              break;
++      default:
++              xfer.type = MIPI_DSI_DCS_LONG_WRITE;
++              xfer.data[0] = len & 0xff;
++              xfer.data[1] = len >> 8;
++      }
++
++      xfer.tx_payload = data;
++      xfer.tx_len = len;
++      xfer.rx_len = 0;
++
++      return exynos_dsi_transfer(dsi, &xfer);
++}
++
++static int exynos_dsi_dcs_read(struct video_source *src,
++                              int channel, u8 dcs_cmd, u8 *data, size_t len)
++{
++      struct exynos_dsi *dsi = src_to_dsi(src);
++      struct exynos_dsi_transfer xfer;
++
++      xfer.type = MIPI_DSI_DCS_READ;
++      xfer.tx_len = 0;
++      xfer.rx_payload = data;
++      xfer.rx_len = len;
++      xfer.data[0] = dcs_cmd;
++      xfer.data[1] = 0x00;
++
++      return exynos_dsi_transfer(dsi, &xfer);
++}
++
++static const struct common_video_source_ops exynos_dsi_common_ops = {
++      .set_stream = exynos_dsi_set_stream,
++};
++
++static const struct dsi_video_source_ops exynos_dsi_ops = {
++      .enable = exynos_dsi_enable,
++      .disable = exynos_dsi_disable,
++
++      .dcs_write = exynos_dsi_dcs_write,
++      .dcs_read = exynos_dsi_dcs_read,
++};
++
++#ifdef CONFIG_OF
++/*
++ * Device Tree
++ */
++
++static int (* const of_phy_enables[])(struct platform_device *, bool) = {
++#ifdef CONFIG_S5P_SETUP_MIPIPHY
++      [0] = s5p_dsim_phy_enable,
++#endif
++};
++
++static struct exynos_dsi_platform_data *exynos_dsi_parse_dt(
++                                              struct platform_device *pdev)
++{
++      struct device_node *node = pdev->dev.of_node;
++      struct exynos_dsi_platform_data *dsi_pd;
++      struct device *dev = &pdev->dev;
++      const __be32 *prop_data;
++      u32 val;
++
++      dsi_pd = kzalloc(sizeof(*dsi_pd), GFP_KERNEL);
++      if (!dsi_pd) {
++              dev_err(dev, "failed to allocate dsi platform data\n");
++              return NULL;
++      }
++
++      prop_data = of_get_property(node, "samsung,phy-type", NULL);
++      if (!prop_data) {
++              dev_err(dev, "failed to get phy-type property\n");
++              goto err_free_pd;
++      }
++
++      val = be32_to_cpu(*prop_data);
++      if (val >= ARRAY_SIZE(of_phy_enables) || !of_phy_enables[val]) {
++              dev_err(dev, "Invalid phy-type %u\n", val);
++              goto err_free_pd;
++      }
++      dsi_pd->phy_enable = of_phy_enables[val];
++
++      prop_data = of_get_property(node, "samsung,pll-stable-time", NULL);
++      if (!prop_data) {
++              dev_err(dev, "failed to get pll-stable-time property\n");
++              goto err_free_pd;
++      }
++      dsi_pd->pll_stable_time = be32_to_cpu(*prop_data);
++
++      prop_data = of_get_property(node, "samsung,stop-holding-count", NULL);
++      if (!prop_data) {
++              dev_err(dev, "failed to get stop-holding-count property\n");
++              goto err_free_pd;
++      }
++      dsi_pd->stop_holding_cnt = be32_to_cpu(*prop_data);
++
++      prop_data = of_get_property(node, "samsung,bta-timeout", NULL);
++      if (!prop_data) {
++              dev_err(dev, "failed to get bta-timeout property\n");
++              goto err_free_pd;
++      }
++      dsi_pd->bta_timeout = be32_to_cpu(*prop_data);
++
++      prop_data = of_get_property(node, "samsung,rx-timeout", NULL);
++      if (!prop_data) {
++              dev_err(dev, "failed to get rx-timeout property\n");
++              goto err_free_pd;
++      }
++      dsi_pd->rx_timeout = be32_to_cpu(*prop_data);
++
++      prop_data = of_get_property(node, "samsung,pll-clk-freq", NULL);
++      if (!prop_data) {
++              dev_err(dev, "failed to get pll-clk-freq property\n");
++              goto err_free_pd;
++      }
++      dsi_pd->pll_clk_rate = be32_to_cpu(*prop_data);
++
++      return dsi_pd;
++
++err_free_pd:
++      kfree(dsi_pd);
++
++      return NULL;
++}
++
++static struct of_device_id exynos_dsi_of_match[] = {
++      { .compatible = "samsung,exynos4210-mipi-dsi" },
++      { }
++};
++
++MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);
++#else
++static struct exynos_dsi_platform_data *exynos_dsi_parse_dt(
++                                              struct platform_device *pdev)
++{
++      return NULL;
++}
++#endif
++
++/*
++ * Platform driver
++ */
++
++static int exynos_dsi_probe(struct platform_device *pdev)
++{
++      struct resource *res;
++      struct exynos_dsi *dsi;
++      int ret;
++
++      dsi = devm_kzalloc(&pdev->dev, sizeof(*dsi), GFP_KERNEL);
++      if (!dsi) {
++              dev_err(&pdev->dev, "failed to allocate dsi object.\n");
++              return -ENOMEM;
++      }
++
++      spin_lock_init(&dsi->transfer_lock);
++      INIT_LIST_HEAD(&dsi->transfer_list);
++
++      dsi->pdev = pdev;
++      dsi->dev = &pdev->dev;
++      dsi->pd = pdev->dev.platform_data;
++
++      if (dsi->pd == NULL && pdev->dev.of_node)
++              dsi->pd = exynos_dsi_parse_dt(pdev);
++
++      if (dsi->pd == NULL) {
++              dev_err(&pdev->dev, "failed to get platform data for dsi.\n");
++              return -EINVAL;
++      }
++
++      dsi->supplies[0].supply = "vdd11";
++      dsi->supplies[1].supply = "vdd18";
++      ret = devm_regulator_bulk_get(&pdev->dev,
++                              ARRAY_SIZE(dsi->supplies), dsi->supplies);
++      if (ret) {
++              dev_err(&pdev->dev, "Failed to get regulators: %d\n", ret);
++              return ret;
++      }
++
++      dsi->pll_clk = devm_clk_get(&pdev->dev, "pll_clk");
++      if (IS_ERR(dsi->pll_clk)) {
++              dev_err(&pdev->dev, "failed to get dsi pll input clock\n");
++              return -ENODEV;
++      }
++
++      dsi->bus_clk = devm_clk_get(&pdev->dev, "bus_clk");
++      if (IS_ERR(dsi->bus_clk)) {
++              dev_err(&pdev->dev, "failed to get dsi bus clock\n");
++              return -ENODEV;
++      }
++
++      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      if (!res) {
++              dev_err(&pdev->dev, "failed to get io memory region\n");
++              return -ENODEV;
++      }
++
++      dsi->reg_base = devm_request_and_ioremap(&pdev->dev, res);
++      if (!dsi->reg_base) {
++              dev_err(&pdev->dev, "failed to remap io region\n");
++              return -ENOMEM;
++      }
++
++      platform_set_drvdata(pdev, dsi);
++
++      dsi->irq = platform_get_irq(pdev, 0);
++      if (dsi->irq < 0) {
++              dev_err(&pdev->dev, "failed to request dsi irq resource\n");
++              return -EINVAL;
++      }
++
++      ret = devm_request_threaded_irq(&pdev->dev, dsi->irq, NULL,
++              exynos_dsi_irq, IRQF_ONESHOT, dev_name(&pdev->dev), dsi);
++      if (ret) {
++              dev_err(&pdev->dev, "failed to request dsi irq\n");
++              return ret;
++      }
++
++      dsi->out.name = dev_name(&pdev->dev);
++      dsi->out.id = -1;
++      dsi->out.of_node = pdev->dev.of_node;
++      dsi->out.common_ops = &exynos_dsi_common_ops;
++      dsi->out.ops.dsi = &exynos_dsi_ops;
++
++      ret = video_source_register(&dsi->out);
++      if (ret) {
++              dev_err(&pdev->dev, "failed to register video source\n");
++              return ret;
++      }
++
++      return 0;
++}
++
++static int exynos_dsi_remove(struct platform_device *pdev)
++{
++      struct exynos_dsi *dsi = platform_get_drvdata(pdev);
++
++      video_source_unregister(&dsi->out);
++
++      return 0;
++}
++
++/*
++ * Power management
++ */
++
++static int exynos_dsi_suspend(struct device *dev)
++{
++      struct exynos_dsi *dsi = dev_get_drvdata(dev);
++
++      if (dsi->enabled)
++              return -EBUSY;
++
++      return 0;
++}
++
++static const struct dev_pm_ops exynos_dsi_pm_ops = {
++      SET_SYSTEM_SLEEP_PM_OPS(exynos_dsi_suspend, NULL)
++};
++
++/*
++ * Module
++ */
++
++static struct platform_driver exynos_dsi_driver = {
++      .probe = exynos_dsi_probe,
++      .remove = exynos_dsi_remove,
++      .driver = {
++                 .name = "exynos-dsi",
++                 .owner = THIS_MODULE,
++                 .pm = &exynos_dsi_pm_ops,
++                 .of_match_table = of_match_ptr(exynos_dsi_of_match),
++      },
++};
++
++module_platform_driver(exynos_dsi_driver);
++
++MODULE_AUTHOR("Tomasz Figa <t.figa@samsung.com>");
++MODULE_DESCRIPTION("Samsung SoC MIPI DSI Master");
++MODULE_LICENSE("GPL");
+diff --git a/include/video/exynos_dsi.h b/include/video/exynos_dsi.h
+new file mode 100644
+index 0000000..95e1568
+--- /dev/null
++++ b/include/video/exynos_dsi.h
+@@ -0,0 +1,41 @@
++/* include/video/exynos_mipi_dsim.h
++ *
++ * Platform data header for Samsung SoC MIPI-DSIM.
++ *
++ * Copyright (c) 2012 Samsung Electronics Co., Ltd
++ *
++ * InKi Dae <inki.dae@samsung.com>
++ * Donghwa Lee <dh09.lee@samsung.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 _EXYNOS_MIPI_DSIM_H
++#define _EXYNOS_MIPI_DSIM_H
++
++#include <linux/device.h>
++
++/*
++ * struct exynos_dsi_platform_data - interface to platform data
++ *    for mipi-dsi driver.
++ *
++ * TODO
++ */
++struct exynos_dsi_platform_data {
++      unsigned int enabled;
++
++      int (*phy_enable)(struct platform_device *pdev, bool on);
++
++      unsigned int pll_stable_time;
++      unsigned long pll_clk_rate;
++      unsigned long esc_clk_rate;
++      unsigned short stop_holding_cnt;
++      unsigned char bta_timeout;
++      unsigned short rx_timeout;
++};
++
++int s5p_dsim_phy_enable(struct platform_device *pdev, bool on);
++
++#endif /* _EXYNOS_MIPI_DSIM_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0073-video-display-Add-panel-s6d6aa1-driver.patch b/patches.tizen/0073-video-display-Add-panel-s6d6aa1-driver.patch
new file mode 100644 (file)
index 0000000..2a091c0
--- /dev/null
@@ -0,0 +1,867 @@
+From ffcbcd8403733d876f2998b918809646c7ab9c97 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Tue, 5 Feb 2013 15:57:50 +0100
+Subject: [PATCH 0073/1302] video: display: Add panel-s6d6aa1 driver
+
+This patch adds a CDF-compliant panel driver for S6D6AA1 DSI LCD panel.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/video/display/Kconfig         |   4 +
+ drivers/video/display/Makefile        |   1 +
+ drivers/video/display/panel-s6d6aa1.c | 769 ++++++++++++++++++++++++++++++++++
+ include/video/panel-s6d6aa1.h         |  42 ++
+ 4 files changed, 816 insertions(+)
+ create mode 100644 drivers/video/display/panel-s6d6aa1.c
+ create mode 100644 include/video/panel-s6d6aa1.h
+
+diff --git a/drivers/video/display/Kconfig b/drivers/video/display/Kconfig
+index b14527a..3fb3d2c 100644
+--- a/drivers/video/display/Kconfig
++++ b/drivers/video/display/Kconfig
+@@ -5,6 +5,10 @@ menuconfig DISPLAY_CORE
+ if DISPLAY_CORE
++config DISPLAY_PANEL_S6D6AA1
++      tristate "S6D6AA1 DSI video mode panel"
++      select OF_VIDEOMODE
++
+ config DISPLAY_SOURCE_EXYNOS_DSI
+       tristate "Samsung SoC MIPI DSI Master"
+diff --git a/drivers/video/display/Makefile b/drivers/video/display/Makefile
+index 40a283a..eb9ec2d 100644
+--- a/drivers/video/display/Makefile
++++ b/drivers/video/display/Makefile
+@@ -1,2 +1,3 @@
+ obj-$(CONFIG_DISPLAY_CORE) += display-core.o
++obj-$(CONFIG_DISPLAY_PANEL_S6D6AA1) += panel-s6d6aa1.o
+ obj-$(CONFIG_DISPLAY_SOURCE_EXYNOS_DSI) += source-exynos_dsi.o
+diff --git a/drivers/video/display/panel-s6d6aa1.c b/drivers/video/display/panel-s6d6aa1.c
+new file mode 100644
+index 0000000..d62def9
+--- /dev/null
++++ b/drivers/video/display/panel-s6d6aa1.c
+@@ -0,0 +1,769 @@
++/* linux/drivers/video/backlight/s6d6aa1.c
++ *
++ * MIPI-DSI based s6d6aa1 TFT-LCD 4.77 inch panel driver.
++ *
++ * Joongmock Shin <jmock.shin@samsung.com>
++ * Eunchul Kim <chulspro.kim@samsung.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/module.h>
++#include <linux/kernel.h>
++
++#include <linux/backlight.h>
++#include <linux/ctype.h>
++#include <linux/delay.h>
++#include <linux/errno.h>
++#include <linux/fb.h>
++#include <linux/firmware.h>
++#include <linux/gpio.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/irq.h>
++#include <linux/lcd.h>
++#include <linux/mutex.h>
++#include <linux/of.h>
++#include <linux/of_gpio.h>
++#include <linux/platform_device.h>
++#include <linux/regulator/consumer.h>
++#include <linux/wait.h>
++
++#include <video/display.h>
++#include <video/mipi_display.h>
++#include <video/of_videomode.h>
++#include <video/panel-s6d6aa1.h>
++
++#define MAX_BRIGHTNESS                69
++#define DSCTL_VFLIP           1 << 7
++#define DSCTL_HFLIP           1 << 6
++
++/* white magic mode */
++enum wm_mode {
++      WM_MODE_MIN = 0x00,
++      WM_MODE_NORMAL = WM_MODE_MIN,
++      WM_MODE_CONSERVATIVE,
++      WM_MODE_MEDIUM,
++      WM_MODE_AGGRESSIVE,
++      WM_MODE_OUTDOOR,
++      WM_MODE_MAX = WM_MODE_OUTDOOR
++};
++
++struct s6d6aa1 {
++      struct display_entity entity;
++      struct device *dev;
++
++      struct s6d6aa1_platform_data *pdata;
++      struct backlight_device *bd;
++      struct regulator_bulk_data supplies[2];
++
++      unsigned int    ver;
++      unsigned int    power;
++      enum wm_mode    wm_mode;
++
++      unsigned int reset_gpio;
++};
++
++#define to_panel(p)   container_of(p, struct s6d6aa1, entity)
++
++static void s6d6aa1_sleep_in(struct s6d6aa1 *lcd)
++{
++      static const unsigned char data_to_send[] = {
++              0x10, 0x00, 0x00
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6d6aa1_sleep_out(struct s6d6aa1 *lcd)
++{
++      static const unsigned char data_to_send[] = {
++              0x11, 0x00, 0x00
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6d6aa1_register_access_dis_1(struct s6d6aa1 *lcd)
++{
++      const unsigned char data_to_send[] = {
++              0xF0, 0xA5, 0xA5
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6d6aa1_register_access_dis_2(struct s6d6aa1 *lcd)
++{
++      const unsigned char data_to_send[] = {
++              0xF1, 0xA5, 0xA5
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6d6aa1_apply_level_1_key(struct s6d6aa1 *lcd)
++{
++      const unsigned char data_to_send[] = {
++              0xF0, 0x5A, 0x5A
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6d6aa1_apply_level_2_key(struct s6d6aa1 *lcd)
++{
++      const unsigned char data_to_send[] = {
++              0xF1, 0x5A, 0x5A
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6d6aa1_read_id(struct s6d6aa1 *lcd, u8 *mtp_id)
++{
++      dsi_dcs_read(lcd->entity.source, 0,
++                      0xDA, &mtp_id[0], 1);
++      dsi_dcs_read(lcd->entity.source, 0,
++                      0xDB, &mtp_id[1], 1);
++      dsi_dcs_read(lcd->entity.source, 0,
++                      0xDC, &mtp_id[2], 1);
++}
++
++static void s6d6aa1_write_ddb(struct s6d6aa1 *lcd)
++{
++      const unsigned char data_to_send[] = {
++              0xB4, 0x59, 0x10, 0x10, 0x00
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6d6aa1_bcm_mode(struct s6d6aa1 *lcd)
++{
++      static const unsigned char data_to_send[] = {
++              0xC1, 0x03, 0x00
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6d6aa1_wrbl_ctl(struct s6d6aa1 *lcd)
++{
++      const unsigned char data_to_send[] = {
++              0xC3, 0x7C, 0x00, 0x22
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6d6aa1_sony_ip_setting(struct s6d6aa1 *lcd)
++{
++      const unsigned char data_to_send1[] = {
++              0xC4, 0x7C, 0xE6, 0x7C, 0xE6, 0x7C, 0xE6, 0x7C,
++              0x7C, 0x05, 0x0F, 0x1F, 0x01, 0x00, 0x00,
++      };
++      const unsigned char data_to_send2[] = {
++              0xC5, 0x80, 0x80, 0x80, 0x41, 0x43, 0x34,
++              0x80, 0x80, 0x01, 0xFF, 0x25, 0x58, 0x50,
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send1, ARRAY_SIZE(data_to_send1));
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send2, ARRAY_SIZE(data_to_send2));
++}
++
++static void s6d6aa1_disp_ctl(struct s6d6aa1 *lcd)
++{
++      static unsigned char data_to_send[3] = {
++              0x36, 0x00, 0x00
++      };
++
++      if (lcd->pdata->flip_vertical)
++              data_to_send[1] |= DSCTL_VFLIP;
++
++      if (lcd->pdata->flip_horizontal)
++              data_to_send[1] |= DSCTL_HFLIP;
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6d6aa1_source_ctl(struct s6d6aa1 *lcd)
++{
++      const unsigned char data_to_send[] = {
++              0xF2, 0x03, 0x03, 0x91, 0x85
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6d6aa1_pwr_ctl(struct s6d6aa1 *lcd)
++{
++      const unsigned char data_to_send[] = {
++              0xF4, 0x04, 0x0B, 0x07, 0x07, 0x10, 0x14, 0x0D, 0x0C,
++              0xAD, 0x00, 0x33, 0x33
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6d6aa1_panel_ctl(struct s6d6aa1 *lcd, int high_freq)
++{
++      const unsigned char data_to_send[] = {
++              0xF6, 0x0B, 0x11, 0x0F, 0x25, 0x0A, 0x00, 0x13, 0x22,
++              0x1B, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03,
++              0x12, 0x32, 0x51
++      };
++
++      /* ToDo : Low requency control */
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6d6aa1_mount_ctl(struct s6d6aa1 *lcd)
++{
++      static const unsigned char data_to_send[] = {
++              0xF7, 0x00, 0x00
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static int s6d6aa1_gamma_ctrl(struct s6d6aa1 *lcd)
++{
++      const unsigned char data_to_send1[] = {
++              0xFA, 0x9C, 0xBF, 0x1A, 0xD6, 0xE3, 0xE3, 0x1B,
++              0xDA, 0x9B, 0x16, 0x51, 0x12, 0x15, 0xD9, 0x9B,
++              0x1A, 0xDD, 0x62, 0x2D, 0x79, 0x6A, 0x2C, 0x7F,
++              0x11, 0x09, 0x53, 0x91, 0x09, 0x08, 0xCA, 0x06,
++              0x07, 0x89, 0x0D, 0x52, 0xD5, 0x16, 0xD9, 0x1C,
++              0x1E, 0x9E, 0xC1, 0x0F, 0xFF, 0xD7, 0x53, 0x61,
++              0xE2, 0x5A, 0x9A, 0xDC, 0x5A, 0x97, 0x99, 0x5D,
++              0x21, 0xE5, 0x26, 0xE9, 0x2C, 0x2A, 0x2A, 0x4F,
++      };
++
++      const unsigned char data_to_send2[] = {
++              0xFB, 0x9C, 0xBF, 0x1A, 0xD6, 0xE3, 0xE3, 0x1B,
++              0xDA, 0x9B, 0x16, 0x51, 0x12, 0x15, 0xD9, 0x9B,
++              0x1A, 0xDD, 0x62, 0x2D, 0x79, 0x6A, 0x2C, 0x7F,
++              0x11, 0x09, 0x53, 0x91, 0x09, 0x08, 0xCA, 0x06,
++              0x07, 0x89, 0x0D, 0x52, 0xD5, 0x16, 0xD9, 0x1C,
++              0x1E, 0x9E, 0xC1, 0x0F, 0xFF, 0xD7, 0x53, 0x61,
++              0xE2, 0x5A, 0x9A, 0xDC, 0x5A, 0x97, 0x99, 0x5D,
++              0x21, 0xE5, 0x26, 0xE9, 0x2C, 0x2A, 0x2A, 0x4F,
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send1, ARRAY_SIZE(data_to_send1));
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send2, ARRAY_SIZE(data_to_send2));
++
++      return 0;
++}
++
++static int s6d6aa1_panel_init(struct s6d6aa1 *lcd)
++{
++      s6d6aa1_sleep_out(lcd);
++
++      msleep(140);
++
++      s6d6aa1_write_ddb(lcd);
++      s6d6aa1_bcm_mode(lcd);
++      s6d6aa1_wrbl_ctl(lcd);
++      s6d6aa1_sony_ip_setting(lcd);
++      s6d6aa1_disp_ctl(lcd);
++      s6d6aa1_source_ctl(lcd);
++      s6d6aa1_pwr_ctl(lcd);
++      s6d6aa1_panel_ctl(lcd, 1);
++      s6d6aa1_mount_ctl(lcd);
++
++      s6d6aa1_gamma_ctrl(lcd);
++
++      return 0;
++}
++
++static void s6d6aa1_write_disbv(struct s6d6aa1 *lcd,
++                              unsigned int brightness)
++{
++      static unsigned char data_to_send[3] = {
++              0x51, 0x00, 0x00
++      };
++
++      data_to_send[1] = brightness;
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6d6aa1_write_ctrld(struct s6d6aa1 *lcd)
++{
++      static const unsigned char data_to_send[] = {
++              0x53, 0x2C, 0x00
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6d6aa1_write_cabc(struct s6d6aa1 *lcd,
++                      enum wm_mode wm_mode)
++{
++      static unsigned char data_to_send[3] = {
++              0x55, 0x00, 0x00
++      };
++
++      data_to_send[1] = wm_mode;
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6d6aa1_display_on(struct s6d6aa1 *lcd)
++{
++      static const unsigned char data_to_send[] = {
++              0x29, 0x00, 0x00
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6d6aa1_display_off(struct s6d6aa1 *lcd)
++{
++      static const unsigned char data_to_send[] = {
++              0x28, 0x00, 0x00
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6d6aa1_brightness_ctrl(struct s6d6aa1 *lcd,
++                              unsigned int brightness)
++{
++      const unsigned int convert_table[] = {
++              8, 9, 11, 13, 15, 17, 19, 21, 23, 25,
++              27, 29, 31, 33, 35, 37, 39, 41, 43, 45,
++              47, 49, 51, 53, 55, 57, 59, 61, 63, 65,
++              67, 69, 71, 73, 75, 77, 79, 81, 83, 85,
++              87, 89, 91, 93, 95, 97, 99, 101, 103, 105,
++              107, 109, 111, 113, 115, 117, 119, 121, 123, 125,
++              127, 130, 133, 136, 139, 142, 145, 149, 152, 155,
++              158, 161, 164, 167, 170, 173, 176, 179, 182, 185,
++              189, 192, 195, 198, 201, 204, 207, 210, 213, 216,
++              219, 222, 225, 228, 232, 235, 238, 241, 244, 247,
++              250,
++      };
++
++      if (brightness > ARRAY_SIZE(convert_table)-1)
++              brightness = convert_table[ARRAY_SIZE(convert_table)-1];
++      else
++              brightness = convert_table[brightness];
++
++      s6d6aa1_write_disbv(lcd, brightness);
++}
++
++static int s6d6aa1_get_brightness(struct backlight_device *bd)
++{
++      return bd->props.brightness;
++}
++
++static int s6d6aa1_set_brightness(struct backlight_device *bd)
++{
++      int brightness = bd->props.brightness;
++      struct s6d6aa1 *lcd = bl_get_data(bd);
++      enum display_entity_state state;
++      int ret;
++
++      if (bd->props.power == FB_BLANK_POWERDOWN
++          || bd->props.state & BL_CORE_SUSPENDED)
++              state = DISPLAY_ENTITY_STATE_OFF;
++      else if (bd->props.power != FB_BLANK_UNBLANK)
++              state = DISPLAY_ENTITY_STATE_STANDBY;
++      else
++              state = DISPLAY_ENTITY_STATE_ON;
++
++      if (brightness < 0 || brightness > bd->props.max_brightness) {
++              dev_err(lcd->dev,
++                      "lcd brightness should be between 0 and %d.\n",
++                      MAX_BRIGHTNESS);
++              return -EINVAL;
++      }
++
++      ret = display_entity_set_state(&lcd->entity, state);
++      if (ret)
++              return ret;
++
++      if (state == DISPLAY_ENTITY_STATE_OFF)
++              return 0;
++
++      s6d6aa1_brightness_ctrl(lcd, brightness);
++
++      return 0;
++}
++
++static const struct backlight_ops s6d6aa1_backlight_ops = {
++      .options = BL_CORE_SUSPENDRESUME,
++      .get_brightness = s6d6aa1_get_brightness,
++      .update_status = s6d6aa1_set_brightness,
++};
++
++static int s6d6aa1_check_mtp(struct s6d6aa1 *lcd)
++{
++      u8 mtp_id[3] = {0, };
++
++      s6d6aa1_apply_level_1_key(lcd);
++      s6d6aa1_apply_level_2_key(lcd);
++
++      s6d6aa1_read_id(lcd, mtp_id);
++      if (mtp_id[0] == 0x00) {
++              dev_err(lcd->dev, "read id failed\n");
++              return -EIO;
++      }
++
++      s6d6aa1_register_access_dis_1(lcd);
++      s6d6aa1_register_access_dis_2(lcd);
++
++      lcd->ver = mtp_id[1];
++      dev_info(lcd->dev, "Read ID : 0x%2x, 0x%2x, 0x%2x\n",
++              mtp_id[0], mtp_id[1], mtp_id[2]);
++
++      return 0;
++}
++
++static void s6d6aa1_set_sequence(struct s6d6aa1 *lcd)
++{
++      struct backlight_device *bd = lcd->bd;
++      int brightness = bd->props.brightness;
++
++      s6d6aa1_check_mtp(lcd);
++      s6d6aa1_panel_init(lcd);
++      s6d6aa1_brightness_ctrl(lcd, brightness);
++      s6d6aa1_write_ctrld(lcd);
++      s6d6aa1_write_cabc(lcd, lcd->wm_mode);
++      s6d6aa1_display_on(lcd);
++
++      dev_info(lcd->dev, "%s:done.\n", __func__);
++}
++
++#ifdef CONFIG_OF
++static int s6d6aa1_generic_reset(struct device *dev)
++{
++      struct s6d6aa1 *lcd = dev_get_drvdata(dev);
++
++      gpio_set_value(lcd->reset_gpio, 1);
++      usleep_range(1000, 2000);
++      gpio_set_value(lcd->reset_gpio, 0);
++      usleep_range(1000, 2000);
++      gpio_set_value(lcd->reset_gpio, 1);
++
++      return 0;
++}
++
++static struct s6d6aa1_platform_data *s6d6aa1_parse_dt(struct s6d6aa1 *lcd)
++{
++      struct device_node *node = lcd->dev->of_node;
++      struct s6d6aa1_platform_data *data;
++      const __be32 *prop_data;
++      int ret;
++
++      data = devm_kzalloc(lcd->dev, sizeof(*data), GFP_KERNEL);
++      if (!data) {
++              dev_err(lcd->dev, "failed to allocate platform data.\n");
++              return NULL;
++      }
++
++      ret = of_get_videomode(node, &data->mode, 0);
++      if (ret) {
++              dev_err(lcd->dev, "failed to read video mode from DT\n");
++              return NULL;
++      }
++
++      lcd->reset_gpio = of_get_named_gpio(node, "reset-gpio", 0);
++      if (lcd->reset_gpio < 0)
++              return NULL;
++
++      prop_data = of_get_property(node, "reset-delay", NULL);
++      if (!prop_data)
++              return NULL;
++      data->reset_delay = be32_to_cpu(*prop_data);
++
++      prop_data = of_get_property(node, "power-on-delay", NULL);
++      if (!prop_data)
++              return NULL;
++      data->power_on_delay = be32_to_cpu(*prop_data);
++
++      if (of_find_property(node, "flip-horizontal", NULL))
++              data->flip_horizontal = true;
++
++      if (of_find_property(node, "flip-vertical", NULL))
++              data->flip_vertical = true;
++
++      data->reset = s6d6aa1_generic_reset;
++
++      return data;
++}
++
++static struct of_device_id s6d6aa1_of_match[] = {
++      { .compatible = "samsung,s6d6aa1" },
++      { }
++};
++
++MODULE_DEVICE_TABLE(of, s6d6aa1_of_match);
++#else
++static struct s6d6aa1_platform_data *s6d6aa1_parse_dt(struct s6d6aa1 *lcd)
++{
++      return NULL;
++}
++#endif
++
++static const struct display_entity_interface_params s6d6aa1_params = {
++      .type = DISPLAY_ENTITY_INTERFACE_DSI,
++      .p.dsi = {
++              .format = DSI_FMT_RGB888,
++              .mode = DSI_MODE_VIDEO | DSI_MODE_VIDEO_BURST
++                      | DSI_MODE_VIDEO_HFP | DSI_MODE_VIDEO_HBP
++                      | DSI_MODE_VIDEO_HSA | DSI_MODE_EOT_PACKET
++                      | DSI_MODE_VSYNC_FLUSH,
++              .data_lanes = 0xf,
++              .hs_clk_freq = 500000000,
++              .esc_clk_freq = 10000000,
++      },
++};
++
++static void s6d6aa1_power_on(struct s6d6aa1 *panel)
++{
++      struct video_source *src = panel->entity.source;
++
++      regulator_bulk_enable(ARRAY_SIZE(panel->supplies),
++                                              panel->supplies);
++
++      msleep(panel->pdata->power_on_delay);
++
++      /* lcd reset */
++      if (panel->pdata->reset)
++              panel->pdata->reset(panel->dev);
++
++      msleep(panel->pdata->reset_delay);
++
++      src->ops.dsi->enable(src);
++
++      s6d6aa1_set_sequence(panel);
++}
++
++static void s6d6aa1_power_off(struct s6d6aa1 *panel)
++{
++      struct video_source *src = panel->entity.source;
++
++      s6d6aa1_sleep_in(panel);
++      s6d6aa1_display_off(panel);
++
++      src->ops.dsi->disable(src);
++
++      regulator_bulk_disable(ARRAY_SIZE(panel->supplies),
++                                              panel->supplies);
++}
++
++static int s6d6aa1_set_state(struct display_entity *entity,
++                          enum display_entity_state state)
++{
++      struct s6d6aa1 *panel = to_panel(entity);
++      struct video_source *src = panel->entity.source;
++
++      switch (state) {
++      case DISPLAY_ENTITY_STATE_OFF:
++              if (entity->state == DISPLAY_ENTITY_STATE_ON)
++                      src->common_ops->set_stream(src,
++                                              DISPLAY_ENTITY_STREAM_STOPPED);
++              s6d6aa1_power_off(panel);
++              break;
++
++      case DISPLAY_ENTITY_STATE_STANDBY:
++              if (entity->state == DISPLAY_ENTITY_STATE_OFF)
++                      s6d6aa1_power_on(panel);
++
++              s6d6aa1_display_off(panel);
++              s6d6aa1_sleep_in(panel);
++              msleep(30);
++
++              if (entity->state == DISPLAY_ENTITY_STATE_ON)
++                      src->common_ops->set_stream(src,
++                                              DISPLAY_ENTITY_STREAM_STOPPED);
++              break;
++
++      case DISPLAY_ENTITY_STATE_ON:
++              if (entity->state == DISPLAY_ENTITY_STATE_OFF)
++                      s6d6aa1_power_on(panel);
++
++              src->common_ops->set_stream(src,
++                                      DISPLAY_ENTITY_STREAM_CONTINUOUS);
++
++              if (entity->state == DISPLAY_ENTITY_STATE_STANDBY) {
++                      s6d6aa1_sleep_out(panel);
++                      s6d6aa1_display_on(panel);
++              }
++              break;
++
++      default:
++              break;
++      }
++
++      return 0;
++}
++
++static int s6d6aa1_get_modes(struct display_entity *entity,
++                          const struct videomode **modes)
++{
++      struct s6d6aa1 *panel = to_panel(entity);
++
++      *modes = &panel->pdata->mode;
++      return 1;
++}
++
++static int s6d6aa1_get_size(struct display_entity *entity,
++                         unsigned int *width, unsigned int *height)
++{
++      struct s6d6aa1 *panel = to_panel(entity);
++
++      *width = panel->pdata->width;
++      *height = panel->pdata->height;
++      return 0;
++}
++
++static int s6d6aa1_get_params(struct display_entity *entity,
++                              struct display_entity_interface_params *params)
++{
++      *params = s6d6aa1_params;
++      return 0;
++}
++
++static const struct display_entity_control_ops s6d6aa1_control_ops = {
++      .set_state = s6d6aa1_set_state,
++      .get_modes = s6d6aa1_get_modes,
++      .get_size = s6d6aa1_get_size,
++      .get_params = s6d6aa1_get_params,
++};
++
++static void s6d6aa1_release(struct display_entity *entity)
++{
++      struct s6d6aa1 *panel = to_panel(entity);
++
++      backlight_device_unregister(panel->bd);
++      regulator_bulk_free(ARRAY_SIZE(panel->supplies), panel->supplies);
++      kfree(panel);
++}
++
++static int s6d6aa1_probe(struct platform_device *pdev)
++{
++      struct s6d6aa1 *lcd;
++      int ret;
++
++      lcd = kzalloc(sizeof(struct s6d6aa1), GFP_KERNEL);
++      if (!lcd) {
++              dev_err(&pdev->dev, "failed to allocate s6d6aa1 structure.\n");
++              return -ENOMEM;
++      }
++
++      lcd->dev = &pdev->dev;
++      lcd->pdata = (struct s6d6aa1_platform_data *)pdev->dev.platform_data;
++
++      if (!lcd->pdata) {
++              lcd->pdata = s6d6aa1_parse_dt(lcd);
++              if (!lcd->pdata) {
++                      dev_err(&pdev->dev, "failed to find platform data\n");
++                      return -ENODEV;
++              }
++      }
++
++      lcd->supplies[0].supply = "vddi";
++      lcd->supplies[1].supply = "vdd";
++      ret = regulator_bulk_get(&pdev->dev,
++                              ARRAY_SIZE(lcd->supplies), lcd->supplies);
++      if (ret) {
++              dev_err(&pdev->dev, "Failed to get regulators: %d\n", ret);
++              goto err_regulator_bulk_get;
++      }
++
++      lcd->bd = backlight_device_register("s6d6aa1", &pdev->dev, lcd,
++                      &s6d6aa1_backlight_ops, NULL);
++      if (IS_ERR(lcd->bd)) {
++              dev_err(&pdev->dev, "failed to register backlight ops.\n");
++              ret = PTR_ERR(lcd->bd);
++              goto err_backlight_register;
++      }
++
++      lcd->wm_mode = WM_MODE_NORMAL;
++
++      lcd->bd->props.max_brightness = MAX_BRIGHTNESS;
++      lcd->bd->props.brightness = MAX_BRIGHTNESS;
++
++      lcd->entity.of_node = pdev->dev.of_node;
++      lcd->entity.dev = &pdev->dev;
++      lcd->entity.release = s6d6aa1_release;
++      lcd->entity.ops = &s6d6aa1_control_ops;
++
++      platform_set_drvdata(pdev, lcd);
++
++      ret = display_entity_register(&lcd->entity);
++      if (ret < 0)
++              goto err_display_register;
++
++      display_entity_set_state(&lcd->entity, DISPLAY_ENTITY_STATE_ON);
++
++      dev_dbg(&pdev->dev, "probed s6d6aa1 panel driver.\n");
++
++      return 0;
++
++err_display_register:
++      backlight_device_unregister(lcd->bd);
++err_backlight_register:
++      regulator_bulk_free(ARRAY_SIZE(lcd->supplies), lcd->supplies);
++err_regulator_bulk_get:
++      kfree(lcd);
++
++      return ret;
++}
++
++static int s6d6aa1_remove(struct platform_device *dev)
++{
++      struct s6d6aa1 *lcd = platform_get_drvdata(dev);
++
++      platform_set_drvdata(dev, NULL);
++      display_entity_unregister(&lcd->entity);
++
++      return 0;
++}
++
++static struct platform_driver s6d6aa1_driver = {
++      .probe = s6d6aa1_probe,
++      .remove = s6d6aa1_remove,
++      .driver = {
++              .name = "panel_s6d6aa1",
++              .owner = THIS_MODULE,
++              .of_match_table = of_match_ptr(s6d6aa1_of_match),
++      },
++};
++module_platform_driver(s6d6aa1_driver);
++
++MODULE_AUTHOR("Joongmock Shin <jmock.shin@samsung.com>");
++MODULE_AUTHOR("Eunchul Kim <chulspro.kim@samsung.com>");
++MODULE_AUTHOR("Tomasz Figa <t.figa@samsung.com>");
++MODULE_DESCRIPTION("MIPI-DSI based s6d6aa1 TFT-LCD Panel Driver");
++MODULE_LICENSE("GPL");
+diff --git a/include/video/panel-s6d6aa1.h b/include/video/panel-s6d6aa1.h
+new file mode 100644
+index 0000000..2bc9ce2
+--- /dev/null
++++ b/include/video/panel-s6d6aa1.h
+@@ -0,0 +1,42 @@
++/*
++ * Renesas R61505-based Display Panels
++ *
++ * Copyright (C) 2012 Renesas Solutions Corp.
++ *
++ * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.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 __PANEL_S6E8AX0_H__
++#define __PANEL_S6E8AX0_H__
++
++#include <video/videomode.h>
++
++struct s6d6aa1_platform_data {
++      unsigned long width;            /* Panel width in mm */
++      unsigned long height;           /* Panel height in mm */
++      struct videomode mode;
++
++      /* reset lcd panel device. */
++      int (*reset)(struct device *dev);
++
++      /* it indicates whether lcd panel was enabled
++         from bootloader or not. */
++      int lcd_enabled;
++      /* it means delay for stable time when it becomes low to high
++         or high to low that is dependent on whether reset gpio is
++         low active or high active. */
++      unsigned int reset_delay;
++      /* stable time needing to become lcd power on. */
++      unsigned int power_on_delay;
++      /* stable time needing to become lcd power off. */
++      unsigned int power_off_delay;
++      /* panel is reversed */
++      bool flip_vertical;
++      bool flip_horizontal;
++};
++
++#endif /* __PANEL_S6E8AX0_H__ */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0074-video-display-Add-panel-s6e8aa0-driver.patch b/patches.tizen/0074-video-display-Add-panel-s6e8aa0-driver.patch
new file mode 100644 (file)
index 0000000..1d93320
--- /dev/null
@@ -0,0 +1,1346 @@
+From ed844820879ae481d985c7556ee7f330edaed92b Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 6 Feb 2013 17:11:57 +0100
+Subject: [PATCH 0074/1302] video: display: Add panel-s6e8aa0 driver
+
+This patch adds a CDF-compliant panel driver for S6E8AA0 DSI
+LCD panel.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/video/display/Kconfig         |    3 +
+ drivers/video/display/Makefile        |    1 +
+ drivers/video/display/panel-s6e8aa0.c | 1247 +++++++++++++++++++++++++++++++++
+ include/video/panel-s6e8aa0.h         |   42 ++
+ 4 files changed, 1293 insertions(+)
+ create mode 100644 drivers/video/display/panel-s6e8aa0.c
+ create mode 100644 include/video/panel-s6e8aa0.h
+
+diff --git a/drivers/video/display/Kconfig b/drivers/video/display/Kconfig
+index 3fb3d2c..49f6dab 100644
+--- a/drivers/video/display/Kconfig
++++ b/drivers/video/display/Kconfig
+@@ -9,6 +9,9 @@ config DISPLAY_PANEL_S6D6AA1
+       tristate "S6D6AA1 DSI video mode panel"
+       select OF_VIDEOMODE
++config DISPLAY_PANEL_S6E8AA0
++      tristate "S6E8AA0 DSI video mode panel"
++      select OF_VIDEOMODE
+ config DISPLAY_SOURCE_EXYNOS_DSI
+       tristate "Samsung SoC MIPI DSI Master"
+diff --git a/drivers/video/display/Makefile b/drivers/video/display/Makefile
+index eb9ec2d..55ab711 100644
+--- a/drivers/video/display/Makefile
++++ b/drivers/video/display/Makefile
+@@ -1,3 +1,4 @@
+ obj-$(CONFIG_DISPLAY_CORE) += display-core.o
+ obj-$(CONFIG_DISPLAY_PANEL_S6D6AA1) += panel-s6d6aa1.o
++obj-$(CONFIG_DISPLAY_PANEL_S6E8AA0) += panel-s6e8aa0.o
+ obj-$(CONFIG_DISPLAY_SOURCE_EXYNOS_DSI) += source-exynos_dsi.o
+diff --git a/drivers/video/display/panel-s6e8aa0.c b/drivers/video/display/panel-s6e8aa0.c
+new file mode 100644
+index 0000000..59c1ec9
+--- /dev/null
++++ b/drivers/video/display/panel-s6e8aa0.c
+@@ -0,0 +1,1247 @@
++/* linux/drivers/video/s6e8aa0.c
++ *
++ * MIPI-DSI based s6e8aa0 AMOLED lcd 5.3 inch panel driver.
++ *
++ * Inki Dae, <inki.dae@samsung.com>
++ * Donghwa Lee, <dh09.lee@samsung.com>
++ * Joongmock Shin <jmock.shin@samsung.com>
++ * Eunchul Kim <chulspro.kim@samsung.com>
++ * Tomasz Figa <t.figa@samsung.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/module.h>
++#include <linux/kernel.h>
++
++#include <linux/backlight.h>
++#include <linux/ctype.h>
++#include <linux/delay.h>
++#include <linux/errno.h>
++#include <linux/fb.h>
++#include <linux/gpio.h>
++#include <linux/lcd.h>
++#include <linux/mutex.h>
++#include <linux/of.h>
++#include <linux/of_gpio.h>
++#include <linux/platform_device.h>
++#include <linux/regulator/consumer.h>
++
++#include <video/display.h>
++#include <video/mipi_display.h>
++#include <video/of_videomode.h>
++#include <video/panel-s6e8aa0.h>
++
++#define LDI_MTP_LENGTH                        24
++#define GAMMA_LEVEL_NUM                       25
++#define GAMMA_TABLE_LEN                       26
++#define S6E8AA0_PANEL_COND_LEN                39
++
++/* 1 */
++#define PANELCTL_SS_MASK              (1 << 5)
++#define PANELCTL_SS_1_800             (0 << 5)
++#define PANELCTL_SS_800_1             (1 << 5)
++#define PANELCTL_GTCON_MASK           (7 << 2)
++#define PANELCTL_GTCON_110            (6 << 2)
++#define PANELCTL_GTCON_111            (7 << 2)
++/* LTPS */
++/* 30 */
++#define PANELCTL_CLK1_CON_MASK                (7 << 3)
++#define PANELCTL_CLK1_000             (0 << 3)
++#define PANELCTL_CLK1_001             (1 << 3)
++#define PANELCTL_CLK2_CON_MASK                (7 << 0)
++#define PANELCTL_CLK2_000             (0 << 0)
++#define PANELCTL_CLK2_001             (1 << 0)
++/* 31 */
++#define PANELCTL_INT1_CON_MASK                (7 << 3)
++#define PANELCTL_INT1_000             (0 << 3)
++#define PANELCTL_INT1_001             (1 << 3)
++#define PANELCTL_INT2_CON_MASK                (7 << 0)
++#define PANELCTL_INT2_000             (0 << 0)
++#define PANELCTL_INT2_001             (1 << 0)
++/* 32 */
++#define PANELCTL_BICTL_CON_MASK               (7 << 3)
++#define PANELCTL_BICTL_000            (0 << 3)
++#define PANELCTL_BICTL_001            (1 << 3)
++#define PANELCTL_BICTLB_CON_MASK      (7 << 0)
++#define PANELCTL_BICTLB_000           (0 << 0)
++#define PANELCTL_BICTLB_001           (1 << 0)
++/* 36 */
++#define PANELCTL_EM_CLK1_CON_MASK     (7 << 3)
++#define PANELCTL_EM_CLK1_110          (6 << 3)
++#define PANELCTL_EM_CLK1_111          (7 << 3)
++#define PANELCTL_EM_CLK1B_CON_MASK    (7 << 0)
++#define PANELCTL_EM_CLK1B_110         (6 << 0)
++#define PANELCTL_EM_CLK1B_111         (7 << 0)
++/* 37 */
++#define PANELCTL_EM_CLK2_CON_MASK     (7 << 3)
++#define PANELCTL_EM_CLK2_110          (6 << 3)
++#define PANELCTL_EM_CLK2_111          (7 << 3)
++#define PANELCTL_EM_CLK2B_CON_MASK    (7 << 0)
++#define PANELCTL_EM_CLK2B_110         (6 << 0)
++#define PANELCTL_EM_CLK2B_111         (7 << 0)
++/* 38 */
++#define PANELCTL_EM_INT1_CON_MASK     (7 << 3)
++#define PANELCTL_EM_INT1_000          (0 << 3)
++#define PANELCTL_EM_INT1_001          (1 << 3)
++#define PANELCTL_EM_INT2_CON_MASK     (7 << 0)
++#define PANELCTL_EM_INT2_000          (0 << 0)
++#define PANELCTL_EM_INT2_001          (1 << 0)
++
++#define AID_DISABLE                   (0x4)
++#define AID_1                         (0x5)
++#define AID_2                         (0x6)
++#define AID_3                         (0x7)
++
++typedef u8 s6e8aa0_gamma_table[GAMMA_TABLE_LEN];
++
++struct s6e8aa0 {
++      struct display_entity entity;
++      struct device *dev;
++
++      struct s6e8aa0_platform_data *pdata;
++      struct backlight_device *bd;
++      struct lcd_device *ld;
++      struct regulator_bulk_data supplies[2];
++
++      unsigned int id;
++      unsigned int aid;
++      const struct s6e8aa0_variant *variant;
++
++      unsigned int reset_gpio;
++
++      int power;
++      int brightness;
++      struct mutex mutex;
++};
++
++struct s6e8aa0_variant {
++      u8 version;
++
++      int (*panel_cond_set)(struct s6e8aa0 *);
++      const u8 *panel_cond_table;
++      size_t panel_cond_len;
++
++      const u8 *pentile_ctl_table;
++      size_t pentile_ctl_len;
++
++      const u8 *power_ctl_table;
++      size_t power_ctl_len;
++
++      int (*elvss_nvm_set)(struct s6e8aa0 *);
++      const u8 *elvss_nvm_table;
++      size_t elvss_nvm_len;
++
++      int (*brightness_set)(struct s6e8aa0 *);
++      const s6e8aa0_gamma_table *gamma_tables;
++};
++
++#define to_panel(p)   container_of(p, struct s6e8aa0, entity)
++
++static void s6e8aa0_apply_level_1_key(struct s6e8aa0 *lcd)
++{
++      const u8 data_to_send[] = {
++              0xf0, 0x5a, 0x5a
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static u8 s6e8aa0_apply_aid_panel_cond(unsigned int aid)
++{
++      u8 ret;
++
++      switch (aid) {
++      case AID_1:
++              ret = 0x60;
++              break;
++      case AID_2:
++              ret = 0x80;
++              break;
++      case AID_3:
++              ret = 0xA0;
++              break;
++      default:
++              ret = 0x04;
++              break;
++      }
++
++      return ret;
++}
++
++static const u8 s6e8aa0_panel_cond_v32[S6E8AA0_PANEL_COND_LEN] = {
++      0xf8, 0x19, 0x35, 0x00, 0x00, 0x00, 0x94, 0x00, 0x3c,
++      0x78, 0x10, 0x27, 0x08, 0x6e, 0x00, 0x00, 0x00, 0x00,
++      0x04, 0x08, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07,
++      0x23, 0x6e, 0xc0, 0xc1, 0x01, 0x81, 0xc1, 0x00, 0xc3,
++      0xf6, 0xf6, 0xc1
++};
++
++static int s6e8aa0_panel_cond_set(struct s6e8aa0 *lcd)
++{
++      const struct s6e8aa0_variant *variant = lcd->variant;
++
++      return dsi_dcs_write(lcd->entity.source,
++                      0, variant->panel_cond_table, variant->panel_cond_len);
++}
++
++static int s6e8aa0_panel_cond_set_v142(struct s6e8aa0 *lcd)
++{
++      static u8 data_to_send[] = {
++              0xf8, 0x3d, 0x35, 0x00, 0x00, 0x00, 0x93, 0x00, 0x3c,
++              0x78, 0x08, 0x27, 0x7d, 0x3f, 0x00, 0x00, 0x00, 0x20,
++              0x04, 0x08, 0x6e, 0x00, 0x00, 0x00, 0x02, 0x07, 0x07,
++              0x23, 0x23, 0xc0, 0xc8, 0x08, 0x48, 0xc1, 0x00, 0xc1,
++              0xff, 0xff, 0xc8
++      };
++
++      data_to_send[18] = s6e8aa0_apply_aid_panel_cond(lcd->aid);
++
++      if (lcd->pdata->flip_vertical) {
++              /* GTCON */
++              data_to_send[1] &= ~(PANELCTL_GTCON_MASK);
++              data_to_send[1] |= (PANELCTL_GTCON_110);
++      }
++
++      if (lcd->pdata->flip_horizontal) {
++              /* SS */
++              data_to_send[1] &= ~(PANELCTL_SS_MASK);
++              data_to_send[1] |= (PANELCTL_SS_1_800);
++      }
++
++      if (lcd->pdata->flip_horizontal || lcd->pdata->flip_vertical) {
++              /* CLK1,2_CON */
++              data_to_send[30] &= ~(PANELCTL_CLK1_CON_MASK |
++                      PANELCTL_CLK2_CON_MASK);
++              data_to_send[30] |= (PANELCTL_CLK1_000 | PANELCTL_CLK2_001);
++
++              /* INT1,2_CON */
++              data_to_send[31] &= ~(PANELCTL_INT1_CON_MASK |
++                      PANELCTL_INT2_CON_MASK);
++              data_to_send[31] |= (PANELCTL_INT1_000 | PANELCTL_INT2_001);
++
++              /* BICTL,B_CON */
++              data_to_send[32] &= ~(PANELCTL_BICTL_CON_MASK |
++                      PANELCTL_BICTLB_CON_MASK);
++              data_to_send[32] |= (PANELCTL_BICTL_000 |
++                      PANELCTL_BICTLB_001);
++
++              /* EM_CLK1,1B_CON */
++              data_to_send[36] &= ~(PANELCTL_EM_CLK1_CON_MASK |
++                      PANELCTL_EM_CLK1B_CON_MASK);
++              data_to_send[36] |= (PANELCTL_EM_CLK1_110 |
++                      PANELCTL_EM_CLK1B_110);
++
++              /* EM_CLK2,2B_CON */
++              data_to_send[37] &= ~(PANELCTL_EM_CLK2_CON_MASK |
++                      PANELCTL_EM_CLK2B_CON_MASK);
++              data_to_send[37] |= (PANELCTL_EM_CLK2_110 |
++                      PANELCTL_EM_CLK2B_110);
++
++              /* EM_INT1,2_CON */
++              data_to_send[38] &= ~(PANELCTL_EM_INT1_CON_MASK |
++                      PANELCTL_EM_INT2_CON_MASK);
++              data_to_send[38] |= (PANELCTL_EM_INT1_000 |
++                      PANELCTL_EM_INT2_001);
++      }
++
++      return dsi_dcs_write(lcd->entity.source,
++                                      0, data_to_send, sizeof(data_to_send));
++}
++
++static void s6e8aa0_display_condition_set(struct s6e8aa0 *lcd)
++{
++      static const u8 data_to_send[] = {
++              0xf2, 0x80, 0x03, 0x0d
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6e8aa0_etc_source_control(struct s6e8aa0 *lcd)
++{
++      static const u8 data_to_send[] = {
++              0xf6, 0x00, 0x02, 0x00
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static u8 s6e8aa0_pentile_ctl_table[] = {
++      0xb6, 0x0c, 0x02, 0x03, 0x32, 0xff, 0x44, 0x44, 0xc0, 0x00
++};
++
++static u8 s6e8aa0_pentile_ctl_table_v32[] = {
++      0xb6, 0x0c, 0x02, 0x03, 0x32, 0xc0, 0x44, 0x44, 0xc0, 0x00
++};
++
++static int s6e8aa0_etc_pentile_control(struct s6e8aa0 *lcd)
++{
++      const struct s6e8aa0_variant *variant = lcd->variant;
++
++      return dsi_dcs_write(lcd->entity.source, 0,
++                      variant->pentile_ctl_table, variant->pentile_ctl_len);
++}
++
++static const u8 s6e8aa0_power_ctl_table[] = {
++      0xf4, 0xcf, 0x0a, 0x12, 0x10, 0x1e, 0x33, 0x02
++};
++
++static const u8 s6e8aa0_power_ctl_table_v32[] = {
++      0xf4, 0xcf, 0x0a, 0x15, 0x10, 0x19, 0x33, 0x02
++};
++
++static int s6e8aa0_etc_power_control(struct s6e8aa0 *lcd)
++{
++      const struct s6e8aa0_variant *variant = lcd->variant;
++
++      return dsi_dcs_write(lcd->entity.source, 0,
++                      variant->power_ctl_table, variant->power_ctl_len);
++}
++
++static int s6e8aa0_etc_elvss_control(struct s6e8aa0 *lcd)
++{
++      u8 data_to_send[] = {
++              0xb1, 0x04, 0x00
++      };
++
++      if (lcd->id == 0x00)
++              data_to_send[2] = 0x95;
++
++      return dsi_dcs_write(lcd->entity.source, 0,
++                              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static const u8 s6e8aa0_elvss_nvm_table_v32[] = {
++      0xd9, 0x14, 0x40, 0x0c, 0xcb, 0xce, 0x6e, 0xc4, 0x07,
++      0x40, 0x41, 0xc1, 0x00, 0x60, 0x19
++};
++
++static int s6e8aa0_elvss_nvm_set(struct s6e8aa0 *lcd)
++{
++      const struct s6e8aa0_variant *variant = lcd->variant;
++
++      return dsi_dcs_write(lcd->entity.source, 0,
++              variant->elvss_nvm_table, variant->elvss_nvm_len);
++};
++
++static int s6e8aa0_elvss_nvm_set_v142(struct s6e8aa0 *lcd)
++{
++      u8 data_to_send[] = {
++              0xd9, 0x14, 0x40, 0x0c, 0xcb, 0xce, 0x6e, 0xc4, 0x0f,
++              0x40, 0x41, 0xd9, 0x00, 0x60, 0x19
++      };
++
++      switch (lcd->brightness) {
++      case 0 ... 6: /* 30cd ~ 100cd */
++              data_to_send[11] = 0xdf;
++              break;
++      case 7 ... 11: /* 120cd ~ 150cd */
++              data_to_send[11] = 0xdd;
++              break;
++      case 12 ... 15: /* 180cd ~ 210cd */
++              data_to_send[11] = 0xd9;
++              break;
++      case 16 ... 24: /* 240cd ~ 300cd */
++              data_to_send[11] = 0xd0;
++              break;
++      }
++
++      return dsi_dcs_write(lcd->entity.source, 0,
++                              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6e8aa0_sleep_in(struct s6e8aa0 *lcd)
++{
++      static const u8 data_to_send[] = {
++              0x10
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6e8aa0_sleep_out(struct s6e8aa0 *lcd)
++{
++      static const u8 data_to_send[] = {
++              0x11
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6e8aa0_display_on(struct s6e8aa0 *lcd)
++{
++      static const u8 data_to_send[] = {
++              0x29
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6e8aa0_display_off(struct s6e8aa0 *lcd)
++{
++      static const u8 data_to_send[] = {
++              0x28
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6e8aa0_apply_level_2_key(struct s6e8aa0 *lcd)
++{
++      const u8 data_to_send[] = {
++              0xfc, 0x5a, 0x5a
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6e8aa0_enable_mtp_register(struct s6e8aa0 *lcd)
++{
++      static const u8 data_to_send[] = {
++              0xf1, 0x5a, 0x5a
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++                              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6e8aa0_disable_mtp_register(struct s6e8aa0 *lcd)
++{
++      static const u8 data_to_send[] = {
++              0xf1, 0xa5, 0xa5
++      };
++
++      dsi_dcs_write(lcd->entity.source, 0,
++                              data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void s6e8aa0_read_id(struct s6e8aa0 *lcd, u8 *mtp_id)
++{
++      unsigned int addr = 0xd1;       /* MTP ID */
++
++      dsi_dcs_read(lcd->entity.source, 0, addr, mtp_id, 3);
++}
++
++static unsigned int s6e8aa0_read_mtp(struct s6e8aa0 *lcd, u8 *mtp_data)
++{
++      unsigned int ret;
++      unsigned int addr = 0xd3;       /* MTP addr */
++
++      s6e8aa0_enable_mtp_register(lcd);
++
++      ret = dsi_dcs_read(lcd->entity.source, 0, addr,
++                                              mtp_data, LDI_MTP_LENGTH);
++      if (ret)
++              dev_err(lcd->dev, "%s: dsi read error\n", __func__);
++
++      s6e8aa0_disable_mtp_register(lcd);
++
++      return ret;
++}
++
++static const s6e8aa0_gamma_table s6e8aa0_gamma_tables_v142[GAMMA_LEVEL_NUM] = {
++      {
++              0xfa, 0x01, 0x71, 0x31, 0x7b, 0x62, 0x55, 0x55,
++              0xaf, 0xb1, 0xb1, 0xbd, 0xce, 0xb7, 0x9a, 0xb1,
++              0x90, 0xb2, 0xc4, 0xae, 0x00, 0x60, 0x00, 0x40,
++              0x00, 0x70,
++      }, {
++              0xfa, 0x01, 0x71, 0x31, 0x7b, 0x74, 0x68, 0x69,
++              0xb8, 0xc1, 0xb7, 0xbd, 0xcd, 0xb8, 0x93, 0xab,
++              0x88, 0xb4, 0xc4, 0xb1, 0x00, 0x6b, 0x00, 0x4d,
++              0x00, 0x7d,
++      }, {
++              0xfa, 0x01, 0x71, 0x31, 0x7b, 0x95, 0x8a, 0x89,
++              0xb4, 0xc6, 0xb2, 0xc5, 0xd2, 0xbf, 0x90, 0xa8,
++              0x85, 0xb5, 0xc4, 0xb3, 0x00, 0x7b, 0x00, 0x5d,
++              0x00, 0x8f,
++      }, {
++              0xfa, 0x01, 0x71, 0x31, 0x7b, 0x9f, 0x98, 0x92,
++              0xb3, 0xc4, 0xb0, 0xbc, 0xcc, 0xb4, 0x91, 0xa6,
++              0x87, 0xb5, 0xc5, 0xb4, 0x00, 0x87, 0x00, 0x6a,
++              0x00, 0x9e,
++      }, {
++              0xfa, 0x01, 0x71, 0x31, 0x7b, 0x99, 0x93, 0x8b,
++              0xb2, 0xc2, 0xb0, 0xbd, 0xce, 0xb4, 0x90, 0xa6,
++              0x87, 0xb3, 0xc3, 0xb2, 0x00, 0x8d, 0x00, 0x70,
++              0x00, 0xa4,
++      }, {
++              0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa7, 0xa5, 0x99,
++              0xb2, 0xc2, 0xb0, 0xbb, 0xcd, 0xb1, 0x93, 0xa7,
++              0x8a, 0xb2, 0xc1, 0xb0, 0x00, 0x92, 0x00, 0x75,
++              0x00, 0xaa,
++      }, {
++              0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa0, 0xa0, 0x93,
++              0xb6, 0xc4, 0xb4, 0xb5, 0xc8, 0xaa, 0x94, 0xa9,
++              0x8c, 0xb2, 0xc0, 0xb0, 0x00, 0x97, 0x00, 0x7a,
++              0x00, 0xaf,
++      }, {
++              0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa3, 0xa7, 0x96,
++              0xb3, 0xc2, 0xb0, 0xba, 0xcb, 0xb0, 0x94, 0xa8,
++              0x8c, 0xb0, 0xbf, 0xaf, 0x00, 0x9f, 0x00, 0x83,
++              0x00, 0xb9,
++      }, {
++              0xfa, 0x01, 0x71, 0x31, 0x7b, 0x9d, 0xa2, 0x90,
++              0xb6, 0xc5, 0xb3, 0xb8, 0xc9, 0xae, 0x94, 0xa8,
++              0x8d, 0xaf, 0xbd, 0xad, 0x00, 0xa4, 0x00, 0x88,
++              0x00, 0xbf,
++      }, {
++              0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa6, 0xac, 0x97,
++              0xb4, 0xc4, 0xb1, 0xbb, 0xcb, 0xb2, 0x93, 0xa7,
++              0x8d, 0xae, 0xbc, 0xad, 0x00, 0xa7, 0x00, 0x8c,
++              0x00, 0xc3,
++      }, {
++              0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa2, 0xa9, 0x93,
++              0xb6, 0xc5, 0xb2, 0xba, 0xc9, 0xb0, 0x93, 0xa7,
++              0x8d, 0xae, 0xbb, 0xac, 0x00, 0xab, 0x00, 0x90,
++              0x00, 0xc8,
++      }, {
++              0xfa, 0x01, 0x71, 0x31, 0x7b, 0x9e, 0xa6, 0x8f,
++              0xb7, 0xc6, 0xb3, 0xb8, 0xc8, 0xb0, 0x93, 0xa6,
++              0x8c, 0xae, 0xbb, 0xad, 0x00, 0xae, 0x00, 0x93,
++              0x00, 0xcc,
++      }, {
++              0xfa, 0x01, 0x71, 0x31, 0x7b, 0xab, 0xb4, 0x9c,
++              0xb3, 0xc3, 0xaf, 0xb7, 0xc7, 0xaf, 0x93, 0xa6,
++              0x8c, 0xaf, 0xbc, 0xad, 0x00, 0xb1, 0x00, 0x97,
++              0x00, 0xcf,
++      }, {
++              0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa6, 0xb1, 0x98,
++              0xb1, 0xc2, 0xab, 0xba, 0xc9, 0xb2, 0x93, 0xa6,
++              0x8d, 0xae, 0xba, 0xab, 0x00, 0xb5, 0x00, 0x9b,
++              0x00, 0xd4,
++      }, {
++              0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa3, 0xae, 0x94,
++              0xb2, 0xc3, 0xac, 0xbb, 0xca, 0xb4, 0x91, 0xa4,
++              0x8a, 0xae, 0xba, 0xac, 0x00, 0xb8, 0x00, 0x9e,
++              0x00, 0xd8,
++      }, {
++              0xfa, 0x01, 0x71, 0x31, 0x7b, 0xab, 0xb7, 0x9c,
++              0xae, 0xc0, 0xa9, 0xba, 0xc9, 0xb3, 0x92, 0xa5,
++              0x8b, 0xad, 0xb9, 0xab, 0x00, 0xbb, 0x00, 0xa1,
++              0x00, 0xdc,
++      }, {
++              0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa7, 0xb4, 0x97,
++              0xb0, 0xc1, 0xaa, 0xb9, 0xc8, 0xb2, 0x92, 0xa5,
++              0x8c, 0xae, 0xb9, 0xab, 0x00, 0xbe, 0x00, 0xa4,
++              0x00, 0xdf,
++      }, {
++              0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa3, 0xb0, 0x94,
++              0xb0, 0xc2, 0xab, 0xbb, 0xc9, 0xb3, 0x91, 0xa4,
++              0x8b, 0xad, 0xb8, 0xaa, 0x00, 0xc1, 0x00, 0xa8,
++              0x00, 0xe2,
++      }, {
++              0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa3, 0xb0, 0x94,
++              0xae, 0xbf, 0xa8, 0xb9, 0xc8, 0xb3, 0x92, 0xa4,
++              0x8b, 0xad, 0xb7, 0xa9, 0x00, 0xc4, 0x00, 0xab,
++              0x00, 0xe6,
++      }, {
++              0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa7, 0xb6, 0x98,
++              0xaf, 0xc0, 0xa8, 0xb8, 0xc7, 0xb2, 0x93, 0xa5,
++              0x8d, 0xad, 0xb7, 0xa9, 0x00, 0xc7, 0x00, 0xae,
++              0x00, 0xe9,
++      }, {
++              0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa4, 0xb3, 0x95,
++              0xaf, 0xc1, 0xa9, 0xb9, 0xc8, 0xb3, 0x92, 0xa4,
++              0x8b, 0xad, 0xb7, 0xaa, 0x00, 0xc9, 0x00, 0xb0,
++              0x00, 0xec,
++      }, {
++              0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa4, 0xb3, 0x95,
++              0xac, 0xbe, 0xa6, 0xbb, 0xc9, 0xb4, 0x90, 0xa3,
++              0x8a, 0xad, 0xb7, 0xa9, 0x00, 0xcc, 0x00, 0xb4,
++              0x00, 0xf0,
++      }, {
++              0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa0, 0xb0, 0x91,
++              0xae, 0xc0, 0xa6, 0xba, 0xc8, 0xb4, 0x91, 0xa4,
++              0x8b, 0xad, 0xb7, 0xa9, 0x00, 0xcf, 0x00, 0xb7,
++              0x00, 0xf3,
++      }, {
++              0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa7, 0xb8, 0x98,
++              0xab, 0xbd, 0xa4, 0xbb, 0xc9, 0xb5, 0x91, 0xa3,
++              0x8b, 0xac, 0xb6, 0xa8, 0x00, 0xd1, 0x00, 0xb9,
++              0x00, 0xf6,
++      }, {
++              0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa4, 0xb5, 0x95,
++              0xa9, 0xbc, 0xa1, 0xbb, 0xc9, 0xb5, 0x91, 0xa3,
++              0x8a, 0xad, 0xb6, 0xa8, 0x00, 0xd6, 0x00, 0xbf,
++              0x00, 0xfc,
++      },
++};
++
++static const s6e8aa0_gamma_table s6e8aa0_gamma_tables_v32[GAMMA_LEVEL_NUM] = {
++      {
++              0xfa, 0x01, 0x43, 0x14, 0x45, 0x72, 0x5e, 0x6b,
++              0xa1, 0xa7, 0x9a, 0xb4, 0xcb, 0xb8, 0x92, 0xac,
++              0x97, 0xb4, 0xc3, 0xb5, 0x00, 0x4e, 0x00, 0x37,
++              0x00, 0x58,
++      }, {
++              0xfa, 0x01, 0x43, 0x14, 0x45, 0x85, 0x71, 0x7d,
++              0xa6, 0xb6, 0xa1, 0xb5, 0xca, 0xba, 0x93, 0xac,
++              0x98, 0xb2, 0xc0, 0xaf, 0x00, 0x59, 0x00, 0x43,
++              0x00, 0x64,
++      }, {
++              0xfa, 0x01, 0x43, 0x14, 0x45, 0xa4, 0x94, 0x9e,
++              0xa0, 0xbb, 0x9c, 0xc3, 0xd2, 0xc6, 0x93, 0xaa,
++              0x95, 0xb7, 0xc2, 0xb4, 0x00, 0x65, 0x00, 0x50,
++              0x00, 0x74,
++      }, {
++              0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xa1, 0xa6,
++              0xa0, 0xb9, 0x9b, 0xc3, 0xd1, 0xc8, 0x90, 0xa6,
++              0x90, 0xbb, 0xc3, 0xb7, 0x00, 0x6f, 0x00, 0x5b,
++              0x00, 0x80,
++      }, {
++              0xfa, 0x01, 0x43, 0x14, 0x45, 0xa6, 0x9d, 0x9f,
++              0x9f, 0xb8, 0x9a, 0xc7, 0xd5, 0xcc, 0x90, 0xa5,
++              0x8f, 0xb8, 0xc1, 0xb6, 0x00, 0x74, 0x00, 0x60,
++              0x00, 0x85,
++      }, {
++              0xfa, 0x01, 0x43, 0x14, 0x45, 0xb3, 0xae, 0xae,
++              0x9e, 0xb7, 0x9a, 0xc8, 0xd6, 0xce, 0x91, 0xa6,
++              0x90, 0xb6, 0xc0, 0xb3, 0x00, 0x78, 0x00, 0x65,
++              0x00, 0x8a,
++      }, {
++              0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xa9, 0xa8,
++              0xa3, 0xb9, 0x9e, 0xc4, 0xd3, 0xcb, 0x94, 0xa6,
++              0x90, 0xb6, 0xbf, 0xb3, 0x00, 0x7c, 0x00, 0x69,
++              0x00, 0x8e,
++      }, {
++              0xfa, 0x01, 0x43, 0x14, 0x45, 0xaf, 0xaf, 0xa9,
++              0xa5, 0xbc, 0xa2, 0xc7, 0xd5, 0xcd, 0x93, 0xa5,
++              0x8f, 0xb4, 0xbd, 0xb1, 0x00, 0x83, 0x00, 0x70,
++              0x00, 0x96,
++      }, {
++              0xfa, 0x01, 0x43, 0x14, 0x45, 0xa9, 0xab, 0xa3,
++              0xaa, 0xbf, 0xa7, 0xc5, 0xd3, 0xcb, 0x93, 0xa5,
++              0x8f, 0xb2, 0xbb, 0xb0, 0x00, 0x86, 0x00, 0x74,
++              0x00, 0x9b,
++      }, {
++              0xfa, 0x01, 0x43, 0x14, 0x45, 0xb1, 0xb5, 0xab,
++              0xab, 0xc0, 0xa9, 0xc7, 0xd4, 0xcc, 0x94, 0xa4,
++              0x8f, 0xb1, 0xbb, 0xaf, 0x00, 0x8a, 0x00, 0x77,
++              0x00, 0x9e,
++      }, {
++              0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xb2, 0xa7,
++              0xae, 0xc2, 0xab, 0xc5, 0xd3, 0xca, 0x93, 0xa4,
++              0x8f, 0xb1, 0xba, 0xae, 0x00, 0x8d, 0x00, 0x7b,
++              0x00, 0xa2,
++      }, {
++              0xfa, 0x01, 0x43, 0x14, 0x45, 0xa9, 0xaf, 0xa3,
++              0xb0, 0xc3, 0xae, 0xc4, 0xd1, 0xc8, 0x93, 0xa4,
++              0x8f, 0xb1, 0xba, 0xaf, 0x00, 0x8f, 0x00, 0x7d,
++              0x00, 0xa5,
++      }, {
++              0xfa, 0x01, 0x43, 0x14, 0x45, 0xb4, 0xbd, 0xaf,
++              0xae, 0xc1, 0xab, 0xc2, 0xd0, 0xc6, 0x94, 0xa4,
++              0x8f, 0xb1, 0xba, 0xaf, 0x00, 0x92, 0x00, 0x80,
++              0x00, 0xa8,
++      }, {
++              0xfa, 0x01, 0x43, 0x14, 0x45, 0xb0, 0xb9, 0xac,
++              0xad, 0xc1, 0xab, 0xc4, 0xd1, 0xc7, 0x95, 0xa4,
++              0x90, 0xb0, 0xb9, 0xad, 0x00, 0x95, 0x00, 0x84,
++              0x00, 0xac,
++      }, {
++              0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xb6, 0xa7,
++              0xaf, 0xc2, 0xae, 0xc5, 0xd1, 0xc7, 0x93, 0xa3,
++              0x8e, 0xb0, 0xb9, 0xad, 0x00, 0x98, 0x00, 0x86,
++              0x00, 0xaf,
++      }, {
++              0xfa, 0x01, 0x43, 0x14, 0x45, 0xb4, 0xbf, 0xaf,
++              0xad, 0xc1, 0xab, 0xc3, 0xd0, 0xc6, 0x94, 0xa3,
++              0x8f, 0xaf, 0xb8, 0xac, 0x00, 0x9a, 0x00, 0x89,
++              0x00, 0xb2,
++      }, {
++              0xfa, 0x01, 0x43, 0x14, 0x45, 0xb0, 0xbc, 0xac,
++              0xaf, 0xc2, 0xad, 0xc2, 0xcf, 0xc4, 0x94, 0xa3,
++              0x90, 0xaf, 0xb8, 0xad, 0x00, 0x9c, 0x00, 0x8b,
++              0x00, 0xb5,
++      }, {
++              0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xb9, 0xa7,
++              0xb1, 0xc4, 0xaf, 0xc3, 0xcf, 0xc5, 0x94, 0xa3,
++              0x8f, 0xae, 0xb7, 0xac, 0x00, 0x9f, 0x00, 0x8e,
++              0x00, 0xb8,
++      }, {
++              0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xb9, 0xa7,
++              0xaf, 0xc2, 0xad, 0xc1, 0xce, 0xc3, 0x95, 0xa3,
++              0x90, 0xad, 0xb6, 0xab, 0x00, 0xa2, 0x00, 0x91,
++              0x00, 0xbb,
++      }, {
++              0xfa, 0x01, 0x43, 0x14, 0x45, 0xb1, 0xbe, 0xac,
++              0xb1, 0xc4, 0xaf, 0xc1, 0xcd, 0xc1, 0x95, 0xa4,
++              0x91, 0xad, 0xb6, 0xab, 0x00, 0xa4, 0x00, 0x93,
++              0x00, 0xbd,
++      }, {
++              0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xbb, 0xa8,
++              0xb3, 0xc5, 0xb2, 0xc1, 0xcd, 0xc2, 0x95, 0xa3,
++              0x90, 0xad, 0xb6, 0xab, 0x00, 0xa6, 0x00, 0x95,
++              0x00, 0xc0,
++      }, {
++              0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xbb, 0xa8,
++              0xb0, 0xc3, 0xaf, 0xc2, 0xce, 0xc2, 0x94, 0xa2,
++              0x90, 0xac, 0xb6, 0xab, 0x00, 0xa8, 0x00, 0x98,
++              0x00, 0xc3,
++      }, {
++              0xfa, 0x01, 0x43, 0x14, 0x45, 0xa9, 0xb8, 0xa5,
++              0xb3, 0xc5, 0xb2, 0xc1, 0xcc, 0xc0, 0x95, 0xa2,
++              0x90, 0xad, 0xb6, 0xab, 0x00, 0xaa, 0x00, 0x9a,
++              0x00, 0xc5,
++      }, {
++              0xfa, 0x01, 0x43, 0x14, 0x45, 0xb0, 0xc0, 0xac,
++              0xb0, 0xc3, 0xaf, 0xc1, 0xcd, 0xc1, 0x95, 0xa2,
++              0x90, 0xac, 0xb5, 0xa9, 0x00, 0xac, 0x00, 0x9c,
++              0x00, 0xc8,
++      }, {
++              0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xbd, 0xa8,
++              0xaf, 0xc2, 0xaf, 0xc1, 0xcc, 0xc0, 0x95, 0xa2,
++              0x90, 0xac, 0xb5, 0xaa, 0x00, 0xb1, 0x00, 0xa1,
++              0x00, 0xcc,
++      },
++};
++
++static int s6e8aa0_brightness_set(struct s6e8aa0 *lcd)
++{
++      static const u8 data_to_send[] = {
++              0xf7, 0x03
++      };
++      const struct s6e8aa0_variant *variant = lcd->variant;
++      int ret;
++
++      ret = dsi_dcs_write(lcd->entity.source, 0,
++                              variant->gamma_tables[lcd->brightness],
++                              sizeof(variant->gamma_tables[lcd->brightness]));
++      if (ret < 0)
++              return ret;
++
++      /* update gamma table. */
++      ret = dsi_dcs_write(lcd->entity.source, 0, data_to_send,
++                                              ARRAY_SIZE(data_to_send));
++      if (ret < 0)
++              return ret;
++
++      return 0;
++}
++
++static int s6e8aa0_brightness_set_v142(struct s6e8aa0 *lcd)
++{
++      const struct s6e8aa0_variant *variant = lcd->variant;
++      int ret;
++
++      ret = variant->elvss_nvm_set(lcd);
++      if (ret < 0)
++              return ret;
++
++      return s6e8aa0_brightness_set(lcd);
++}
++
++static int s6e8aa0_panel_init(struct s6e8aa0 *lcd)
++{
++      const struct s6e8aa0_variant *variant = lcd->variant;
++
++      s6e8aa0_apply_level_1_key(lcd);
++      s6e8aa0_apply_level_2_key(lcd);
++      msleep(20);
++
++      s6e8aa0_sleep_out(lcd);
++      msleep(40);
++
++      variant->panel_cond_set(lcd);
++      s6e8aa0_display_condition_set(lcd);
++
++      s6e8aa0_brightness_set(lcd);
++
++      s6e8aa0_etc_source_control(lcd);
++      s6e8aa0_etc_pentile_control(lcd);
++      variant->elvss_nvm_set(lcd);
++      s6e8aa0_etc_power_control(lcd);
++      s6e8aa0_etc_elvss_control(lcd);
++      msleep(lcd->pdata->init_delay);
++
++      dev_dbg(lcd->dev, "panel init sequence done.\n");
++
++      return 0;
++}
++
++static int s6e8aa0_get_brightness(struct backlight_device *bd)
++{
++      return bd->props.brightness;
++}
++
++static int s6e8aa0_update_status(struct backlight_device *bd)
++{
++      struct s6e8aa0 *lcd = bl_get_data(bd);
++      const struct s6e8aa0_variant *variant = lcd->variant;
++      int ret;
++
++      mutex_lock(&lcd->mutex);
++
++      lcd->brightness = bd->props.brightness;
++
++      if (lcd->entity.state != DISPLAY_ENTITY_STATE_ON)
++              goto unlock;
++
++      ret = variant->brightness_set(lcd);
++      if (ret) {
++              dev_err(lcd->dev, "lcd brightness setting failed.\n");
++              goto unlock;
++      }
++
++unlock:
++      mutex_unlock(&lcd->mutex);
++
++      return 0;
++}
++
++static const struct backlight_ops s6e8aa0_backlight_ops = {
++      .get_brightness = s6e8aa0_get_brightness,
++      .update_status = s6e8aa0_update_status,
++};
++
++static int s6e8aa0_set_power(struct lcd_device *ld, int power)
++{
++      struct s6e8aa0 *lcd = lcd_get_data(ld);
++      enum display_entity_state state;
++      int ret = 0;
++
++      mutex_lock(&lcd->mutex);
++
++      switch (power) {
++      case FB_BLANK_UNBLANK:
++              state = DISPLAY_ENTITY_STATE_ON;
++              break;
++      case FB_BLANK_POWERDOWN:
++              state = DISPLAY_ENTITY_STATE_OFF;
++              break;
++      default:
++              state = DISPLAY_ENTITY_STATE_STANDBY;
++      }
++
++      ret = display_entity_set_state(&lcd->entity, state);
++      if (ret)
++              goto unlock;
++
++      lcd->power = power;
++
++unlock:
++      mutex_unlock(&lcd->mutex);
++
++      return ret;
++}
++
++static int s6e8aa0_get_power(struct lcd_device *ld)
++{
++      struct s6e8aa0 *lcd = lcd_get_data(ld);
++
++      return lcd->power;
++}
++
++static struct lcd_ops s6e8aa0_lcd_ops = {
++      .set_power = s6e8aa0_set_power,
++      .get_power = s6e8aa0_get_power,
++};
++
++static const struct s6e8aa0_variant s6e8aa0_variants[] = {
++      {
++              .version = 32,
++              .panel_cond_set = s6e8aa0_panel_cond_set,
++              .panel_cond_table = s6e8aa0_panel_cond_v32,
++              .panel_cond_len = ARRAY_SIZE(s6e8aa0_panel_cond_v32),
++              .pentile_ctl_table = s6e8aa0_pentile_ctl_table_v32,
++              .pentile_ctl_len = ARRAY_SIZE(s6e8aa0_pentile_ctl_table_v32),
++              .power_ctl_table = s6e8aa0_power_ctl_table_v32,
++              .power_ctl_len = ARRAY_SIZE(s6e8aa0_power_ctl_table_v32),
++              .elvss_nvm_set = s6e8aa0_elvss_nvm_set,
++              .elvss_nvm_table = s6e8aa0_elvss_nvm_table_v32,
++              .elvss_nvm_len = ARRAY_SIZE(s6e8aa0_elvss_nvm_table_v32),
++              .brightness_set = s6e8aa0_brightness_set,
++              .gamma_tables = s6e8aa0_gamma_tables_v32,
++      }, {
++              .version = 142,
++              .panel_cond_set = s6e8aa0_panel_cond_set_v142,
++              .pentile_ctl_table = s6e8aa0_pentile_ctl_table,
++              .pentile_ctl_len = ARRAY_SIZE(s6e8aa0_pentile_ctl_table),
++              .power_ctl_table = s6e8aa0_power_ctl_table,
++              .power_ctl_len = ARRAY_SIZE(s6e8aa0_power_ctl_table),
++              .elvss_nvm_set = s6e8aa0_elvss_nvm_set_v142,
++              .brightness_set = s6e8aa0_brightness_set_v142,
++              .gamma_tables = s6e8aa0_gamma_tables_v142,
++      }
++};
++
++static int s6e8aa0_check_mtp(struct s6e8aa0 *lcd)
++{
++      int ret;
++      u8 mtp_data[LDI_MTP_LENGTH] = {0, };
++      u8 mtp_id[3] = {0, };
++      int i;
++
++      s6e8aa0_read_id(lcd, mtp_id);
++      if (mtp_id[0] == 0x00) {
++              dev_err(lcd->dev, "read id failed\n");
++              return -EIO;
++      }
++
++      dev_info(lcd->dev, "Read ID : 0x%2x, 0x%2x, 0x%2x\n",
++                                      mtp_id[0], mtp_id[1], mtp_id[2]);
++
++      if (mtp_id[2] == 0x33)
++              dev_dbg(lcd->dev,
++                      "ID-3 is 0xff does not support dynamic elvss\n");
++      else {
++              dev_dbg(lcd->dev,
++                      "ID-3 is 0x%x support dynamic elvss\n", mtp_id[2]);
++              dev_dbg(lcd->dev, "Dynamic ELVSS Information\n");
++      }
++
++      for (i = 0; i < ARRAY_SIZE(s6e8aa0_variants); ++i) {
++              if (mtp_id[1] == s6e8aa0_variants[i].version)
++                      break;
++      }
++      if (i >= ARRAY_SIZE(s6e8aa0_variants)) {
++              dev_err(lcd->dev, "unsupported display version %d\n",
++                                                              mtp_id[1]);
++              return -EINVAL;
++      }
++
++      lcd->variant = &s6e8aa0_variants[i];
++      lcd->id = mtp_id[2];
++      lcd->aid = (mtp_id[2] >> 5);
++
++      ret = s6e8aa0_read_mtp(lcd, mtp_data);
++      if (ret) {
++              dev_err(lcd->dev, "read mtp failed\n");
++              return -EIO;
++      }
++
++      return 0;
++}
++
++static int s6e8aa0_set_sequence(struct s6e8aa0 *lcd)
++{
++      int ret;
++
++      ret = s6e8aa0_check_mtp(lcd);
++      if (ret < 0)
++              return ret;
++
++      s6e8aa0_panel_init(lcd);
++      s6e8aa0_display_on(lcd);
++
++      dev_dbg(lcd->dev, "%s:done.\n", __func__);
++
++      return 0;
++}
++
++#ifdef CONFIG_OF
++static int s6e8aa0_generic_reset(struct device *dev)
++{
++      struct s6e8aa0 *lcd = dev_get_drvdata(dev);
++
++      gpio_set_value(lcd->reset_gpio, 1);
++      usleep_range(10000, 11000);
++      gpio_set_value(lcd->reset_gpio, 0);
++      usleep_range(10000, 11000);
++      gpio_set_value(lcd->reset_gpio, 1);
++
++      return 0;
++}
++
++static struct s6e8aa0_platform_data *s6e8aa0_parse_dt(struct s6e8aa0 *lcd)
++{
++      struct device_node *node = lcd->dev->of_node;
++      struct s6e8aa0_platform_data *data;
++      const __be32 *prop_data;
++      int ret;
++
++      data = devm_kzalloc(lcd->dev, sizeof(*data), GFP_KERNEL);
++      if (!data) {
++              dev_err(lcd->dev, "failed to allocate platform data.\n");
++              return NULL;
++      }
++
++      ret = of_get_videomode(node, &data->mode, 0);
++      if (ret) {
++              dev_err(lcd->dev, "failed to read video mode from DT\n");
++              return NULL;
++      }
++
++      lcd->reset_gpio = of_get_named_gpio(node, "reset-gpio", 0);
++      if (lcd->reset_gpio < 0)
++              return NULL;
++
++      prop_data = of_get_property(node, "reset-delay", NULL);
++      if (!prop_data)
++              return NULL;
++      data->reset_delay = be32_to_cpu(*prop_data);
++
++      prop_data = of_get_property(node, "power-on-delay", NULL);
++      if (!prop_data)
++              return NULL;
++      data->power_on_delay = be32_to_cpu(*prop_data);
++
++      prop_data = of_get_property(node, "init-delay", NULL);
++      if (!prop_data)
++              return NULL;
++      data->init_delay = be32_to_cpu(*prop_data);
++
++      if (of_find_property(node, "flip-horizontal", NULL))
++              data->flip_horizontal = true;
++
++      if (of_find_property(node, "flip-vertical", NULL))
++              data->flip_vertical = true;
++
++      data->reset = s6e8aa0_generic_reset;
++
++      return data;
++}
++
++static struct of_device_id s6e8aa0_of_match[] = {
++      { .compatible = "samsung,s6e8aa0" },
++      { }
++};
++
++MODULE_DEVICE_TABLE(of, s6e8aa0_of_match);
++#else
++static struct s6e8aa0_platform_data *s6e8aa0_parse_dt(struct s6e8aa0 *lcd)
++{
++      return NULL;
++}
++#endif
++
++static const struct display_entity_interface_params s6e8aa0_params = {
++      .type = DISPLAY_ENTITY_INTERFACE_DSI,
++      .p.dsi = {
++              .format = DSI_FMT_RGB888,
++              .mode = DSI_MODE_VIDEO | DSI_MODE_VIDEO_BURST
++                      | DSI_MODE_VIDEO_HFP | DSI_MODE_VIDEO_HBP
++                      | DSI_MODE_VIDEO_HSA | DSI_MODE_EOT_PACKET
++                      | DSI_MODE_VSYNC_FLUSH,
++              .data_lanes = 0xf,
++              .hs_clk_freq = 500000000,
++              .esc_clk_freq = 20000000,
++      },
++};
++
++static void s6e8aa0_power_on(struct s6e8aa0 *panel)
++{
++      struct video_source *src = panel->entity.source;
++
++      regulator_bulk_enable(ARRAY_SIZE(panel->supplies),
++                                              panel->supplies);
++
++      msleep(panel->pdata->power_on_delay);
++
++      /* lcd reset */
++      if (panel->pdata->reset)
++              panel->pdata->reset(panel->dev);
++
++      msleep(panel->pdata->reset_delay);
++
++      src->ops.dsi->enable(src);
++
++      s6e8aa0_set_sequence(panel);
++}
++
++static void s6e8aa0_power_off(struct s6e8aa0 *panel)
++{
++      struct video_source *src = panel->entity.source;
++
++      s6e8aa0_sleep_in(panel);
++      s6e8aa0_display_off(panel);
++
++      src->ops.dsi->disable(src);
++
++      regulator_bulk_disable(ARRAY_SIZE(panel->supplies),
++                                              panel->supplies);
++}
++
++static int s6e8aa0_set_state(struct display_entity *entity,
++                          enum display_entity_state state)
++{
++      struct s6e8aa0 *panel = to_panel(entity);
++      struct video_source *src = panel->entity.source;
++
++      switch (state) {
++      case DISPLAY_ENTITY_STATE_STANDBY:
++      case DISPLAY_ENTITY_STATE_OFF:
++              if (entity->state != DISPLAY_ENTITY_STATE_ON)
++                      break;
++              src->common_ops->set_stream(src, DISPLAY_ENTITY_STREAM_STOPPED);
++              s6e8aa0_power_off(panel);
++              break;
++
++      case DISPLAY_ENTITY_STATE_ON:
++              s6e8aa0_power_on(panel);
++              src->common_ops->set_stream(src,
++                                      DISPLAY_ENTITY_STREAM_CONTINUOUS);
++              break;
++
++      default:
++              break;
++      }
++
++      return 0;
++}
++
++static int s6e8aa0_get_modes(struct display_entity *entity,
++                          const struct videomode **modes)
++{
++      struct s6e8aa0 *panel = to_panel(entity);
++
++      *modes = &panel->pdata->mode;
++      return 1;
++}
++
++static int s6e8aa0_get_size(struct display_entity *entity,
++                         unsigned int *width, unsigned int *height)
++{
++      struct s6e8aa0 *panel = to_panel(entity);
++
++      *width = panel->pdata->width;
++      *height = panel->pdata->height;
++      return 0;
++}
++
++static int s6e8aa0_get_params(struct display_entity *entity,
++                              struct display_entity_interface_params *params)
++{
++      *params = s6e8aa0_params;
++      return 0;
++}
++
++static const struct display_entity_control_ops s6e8aa0_control_ops = {
++      .set_state = s6e8aa0_set_state,
++      .get_modes = s6e8aa0_get_modes,
++      .get_size = s6e8aa0_get_size,
++      .get_params = s6e8aa0_get_params,
++};
++
++static void s6e8aa0_release(struct display_entity *entity)
++{
++      struct s6e8aa0 *panel = to_panel(entity);
++
++      regulator_bulk_free(ARRAY_SIZE(panel->supplies), panel->supplies);
++      kfree(panel);
++}
++
++static int s6e8aa0_probe(struct platform_device *pdev)
++{
++      struct s6e8aa0 *lcd;
++      int ret;
++
++      lcd = kzalloc(sizeof(struct s6e8aa0), GFP_KERNEL);
++      if (!lcd) {
++              dev_err(&pdev->dev, "failed to allocate s6e8aa0 structure.\n");
++              return -ENOMEM;
++      }
++
++      lcd->dev = &pdev->dev;
++      lcd->pdata = (struct s6e8aa0_platform_data *)pdev->dev.platform_data;
++
++      if (!lcd->pdata) {
++              lcd->pdata = s6e8aa0_parse_dt(lcd);
++              if (!lcd->pdata) {
++                      dev_err(&pdev->dev, "failed to find platform data\n");
++                      return -ENODEV;
++              }
++      }
++
++      lcd->supplies[0].supply = "vdd3";
++      lcd->supplies[1].supply = "vci";
++      ret = regulator_bulk_get(&pdev->dev,
++                              ARRAY_SIZE(lcd->supplies), lcd->supplies);
++      if (ret) {
++              dev_err(&pdev->dev, "Failed to get regulators: %d\n", ret);
++              goto err_regulator_bulk_get;
++      }
++
++      lcd->ld = lcd_device_register("s6e8aa0", &pdev->dev, lcd,
++                      &s6e8aa0_lcd_ops);
++      if (IS_ERR(lcd->ld)) {
++              dev_err(lcd->dev, "failed to register lcd ops.\n");
++              ret = PTR_ERR(lcd->ld);
++              goto err_lcd_register;
++      }
++
++      lcd->bd = backlight_device_register("s6e8aa0-bl", &pdev->dev, lcd,
++                      &s6e8aa0_backlight_ops, NULL);
++      if (IS_ERR(lcd->bd)) {
++              dev_err(&pdev->dev, "failed to register backlight ops.\n");
++              ret = PTR_ERR(lcd->bd);
++              goto err_backlight_register;
++      }
++
++      mutex_init(&lcd->mutex);
++
++      lcd->bd->props.max_brightness = GAMMA_LEVEL_NUM - 1;
++      lcd->bd->props.brightness = GAMMA_LEVEL_NUM - 1;
++      lcd->brightness = GAMMA_LEVEL_NUM - 1;
++
++      lcd->entity.of_node = pdev->dev.of_node;
++      lcd->entity.dev = &pdev->dev;
++      lcd->entity.release = s6e8aa0_release;
++      lcd->entity.ops = &s6e8aa0_control_ops;
++
++      platform_set_drvdata(pdev, lcd);
++
++      ret = display_entity_register(&lcd->entity);
++      if (ret < 0)
++              goto err_display_register;
++
++      display_entity_set_state(&lcd->entity, DISPLAY_ENTITY_STATE_ON);
++
++      dev_dbg(&pdev->dev, "probed s6e8aa0 panel driver.\n");
++
++      return 0;
++
++err_display_register:
++      backlight_device_unregister(lcd->bd);
++err_backlight_register:
++      lcd_device_unregister(lcd->ld);
++err_lcd_register:
++      regulator_bulk_free(ARRAY_SIZE(lcd->supplies), lcd->supplies);
++err_regulator_bulk_get:
++      kfree(lcd);
++
++      return ret;
++}
++
++static int s6e8aa0_remove(struct platform_device *pdev)
++{
++      struct s6e8aa0 *lcd = platform_get_drvdata(pdev);
++
++      backlight_device_unregister(lcd->bd);
++      lcd_device_unregister(lcd->ld);
++      platform_set_drvdata(pdev, NULL);
++      display_entity_unregister(&lcd->entity);
++
++      return 0;
++}
++
++static struct platform_driver s6e8aa0_driver = {
++      .probe = s6e8aa0_probe,
++      .remove = s6e8aa0_remove,
++      .driver = {
++              .name = "panel_s6e8aa0",
++              .owner = THIS_MODULE,
++              .of_match_table = of_match_ptr(s6e8aa0_of_match),
++      },
++};
++module_platform_driver(s6e8aa0_driver);
++
++MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>");
++MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
++MODULE_AUTHOR("Joongmock Shin <jmock.shin@samsung.com>");
++MODULE_AUTHOR("Eunchul Kim <chulspro.kim@samsung.com>");
++MODULE_AUTHOR("Tomasz Figa <t.figa@samsung.com>");
++MODULE_DESCRIPTION("MIPI-DSI based s6e8aa0 AMOLED LCD Panel Driver");
++MODULE_LICENSE("GPL");
+diff --git a/include/video/panel-s6e8aa0.h b/include/video/panel-s6e8aa0.h
+new file mode 100644
+index 0000000..8a32de8
+--- /dev/null
++++ b/include/video/panel-s6e8aa0.h
+@@ -0,0 +1,42 @@
++/*
++ * Renesas R61505-based Display Panels
++ *
++ * Copyright (C) 2012 Renesas Solutions Corp.
++ *
++ * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.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 __PANEL_S6E8AX0_H__
++#define __PANEL_S6E8AX0_H__
++
++#include <video/videomode.h>
++
++struct s6e8aa0_platform_data {
++      unsigned long width;            /* Panel width in mm */
++      unsigned long height;           /* Panel height in mm */
++      struct videomode mode;
++
++      /* reset lcd panel device. */
++      int (*reset)(struct device *dev);
++
++      /* it indicates whether lcd panel was enabled
++         from bootloader or not. */
++      int lcd_enabled;
++      /* it means delay for stable time when it becomes low to high
++         or high to low that is dependent on whether reset gpio is
++         low active or high active. */
++      unsigned int reset_delay;
++      /* stable time needing to become lcd power on. */
++      unsigned int power_on_delay;
++      /* stable time needing to become lcd power off. */
++      unsigned int init_delay;
++      /* panel is reversed */
++      bool flip_vertical;
++      bool flip_horizontal;
++};
++
++#endif /* __PANEL_S6E8AX0_H__ */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0075-ARM-dts-exynos4-Add-node-for-exynos-dsi-to-exynos4.d.patch b/patches.tizen/0075-ARM-dts-exynos4-Add-node-for-exynos-dsi-to-exynos4.d.patch
new file mode 100644 (file)
index 0000000..2f55c8f
--- /dev/null
@@ -0,0 +1,44 @@
+From 065a5942e662795021ead854b1771d2fd63f99be Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 31 Aug 2012 12:26:33 +0200
+Subject: [PATCH 0075/1302] ARM: dts: exynos4: Add node for exynos-dsi to
+ exynos4.dtsi
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+
+ARM: dts: exynos4: Update DSI node for new driver
+
+This patch updates DSI controller node in exynos4.dtsi for new
+exynos-dsi driver.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index f54231d..631c36d 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -104,6 +104,17 @@
+               arm,tag-latency = <1 1 0>;
+       };
++      dsi_0: dsi@11C80000 {
++              compatible = "samsung,exynos4210-mipi-dsi";
++              reg = <0x11C80000 0x10000>;
++              interrupts = <0 79 0>;
++              samsung,phy-type = <0>;
++              samsung,power-domain = <&pd_lcd0>;
++              clocks = <&clock 286>, <&clock 143>;
++              clock-names = "bus_clk", "pll_clk";
++              status = "disabled";
++      };
++
+       camera {
+               compatible = "samsung,fimc", "simple-bus";
+               clocks = <&clock 132>, <&clock 133>, <&clock 351>, <&clock 352>,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0076-ARM-dts-exynos4412-slp_pq-Update-display-nodes-for-C.patch b/patches.tizen/0076-ARM-dts-exynos4412-slp_pq-Update-display-nodes-for-C.patch
new file mode 100644 (file)
index 0000000..d7cbcfa
--- /dev/null
@@ -0,0 +1,85 @@
+From 3cfe4b178d6cbb324aba8e59d1d5d61676441961 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Mon, 28 Jan 2013 15:37:43 +0100
+Subject: [PATCH 0076/1302] ARM: dts: exynos4412-slp_pq: Update display nodes
+ for CDF
+
+This patch updates display device nodes in exynos4412-slp_pq.dts to be
+compatible with new drivers using Common Display Framework.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 49 +++++++++++++++++++--------------
+ 1 file changed, 28 insertions(+), 21 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 8d96f53..5a2b70b 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -509,34 +509,41 @@
+       };
+       fimd0_lcd: panel {
+-              compatible = "s6e8ax0";
++              compatible = "samsung,s6e8aa0";
+               reset-gpio = <&gpy4 5 0>;
+-              reset-delay = <25>;
+-              power-off-delay = <0>;
+-              power-on-delay= <0>;
++              power-on-delay= <50>;
++              reset-delay = <100>;
++              init-delay = <100>;
+               vdd3-supply = <&lcd_vdd3_reg>;
+               vci-supply = <&ldo25_reg>;
+-              lcd-htiming = <5 5 5 720>;
+-              lcd-vtiming = <1 13 2 1280>;
+-              supports-mipi-panel;
++              video-source = <&dsi_0>;
++
++              display-timings {
++                      native-mode = <&timing0>;
++
++                      timing0: timing-0 {
++                              clock-frequency = <0>;
++                              hactive = <720>;
++                              vactive = <1280>;
++                              hfront-porch = <5>;
++                              hback-porch = <5>;
++                              hsync-len = <5>;
++                              vfront-porch = <13>;
++                              vback-porch = <1>;
++                              vsync-len = <2>;
++                      };
++              };
+       };
+-      mipi-dsim@11C80000 {
+-              video-interface;
+-              virtual-channel = <0>;
+-              pixel-format = <7>;
+-              burst-mode = <1>;
+-              bus-width = <4>;
+-              cmd-allow = <0xf>;
+-              pms-setting = <12 250 0>;
+-              pll-stable-time = <500>;
+-              escape-clock = <10000000>;
+-              stop-holding-count = <0x7ff>;
+-              bta-timeout = <0xff>;
+-              rx-timeout = <0xffff>;
++      dsi_0: dsi@11C80000 {
++              samsung,pll-stable-time = <500>;
++              samsung,stop-holding-count = <0x7ff>;
++              samsung,bta-timeout = <0xff>;
++              samsung,rx-timeout = <0xffff>;
++              samsung,pll-clk-freq = <24000000>;
++              samsung,cmd-allow = <0xf>;
+               vdd11-supply = <&ldo8_reg>;
+               vdd18-supply = <&ldo10_reg>;
+-              panel-info = <&fimd0_lcd>;
+               status = "okay";
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0077-ARM-dts-exynos4210-trats-Update-display-nodes-for-CD.patch b/patches.tizen/0077-ARM-dts-exynos4210-trats-Update-display-nodes-for-CD.patch
new file mode 100644 (file)
index 0000000..bdf1957
--- /dev/null
@@ -0,0 +1,89 @@
+From 50fd9898bd016ee18b87642eab7356a5eca7cb27 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 6 Feb 2013 17:16:35 +0100
+Subject: [PATCH 0077/1302] ARM: dts: exynos4210-trats: Update display nodes
+ for CDF
+
+This patch updates DSI controller and LCD panel nodes in device tree
+source of exynos4210-trats board for new exynos-dsi and s6e8ax0 drivers
+using Common Display Framework.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 52 ++++++++++++++++++++--------------
+ 1 file changed, 30 insertions(+), 22 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index f9a57fd..c339f2a 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -325,35 +325,43 @@
+       };
+       fimd0_lcd: panel {
+-              compatible = "s6e8ax0";
+-              panel-reverse;
++              compatible = "samsung,s6e8aa0";
+               reset-gpio = <&gpy4 5 0>;
+-              reset-delay = <25>;
+-              power-off-delay = <0>;
+-              power-on-delay= <0>;
++              power-on-delay= <50>;
++              reset-delay = <100>;
++              init-delay = <100>;
+               vdd3-supply = <&vcclcd_reg>;
+               vci-supply = <&vlcd_reg>;
+-              lcd-htiming = <5 5 5 720>;
+-              lcd-vtiming = <1 13 2 1280>;
+-              supports-mipi-panel;
++              video-source = <&dsi_0>;
++              flip-horizontal;
++              flip-vertical;
++
++              display-timings {
++                      native-mode = <&timing0>;
++
++                      timing0: timing-0 {
++                              clock-frequency = <0>;
++                              hactive = <720>;
++                              vactive = <1280>;
++                              hfront-porch = <5>;
++                              hback-porch = <5>;
++                              hsync-len = <5>;
++                              vfront-porch = <13>;
++                              vback-porch = <1>;
++                              vsync-len = <2>;
++                      };
++              };
+       };
+-      mipi-dsim@11C80000 {
+-              video-interface;
+-              virtual-channel = <0>;
+-              pixel-format = <7>;
+-              burst-mode = <1>;
+-              bus-width = <4>;
+-              cmd-allow = <0xf>;
+-              pms-setting = <12 250 0>;
+-              pll-stable-time = <500>;
+-              escape-clock = <10000000>;
+-              stop-holding-count = <0x7ff>;
+-              bta-timeout = <0xff>;
+-              rx-timeout = <0xffff>;
++      dsi_0: dsi@11C80000 {
++              samsung,pll-stable-time = <500>;
++              samsung,stop-holding-count = <0x7ff>;
++              samsung,bta-timeout = <0xff>;
++              samsung,rx-timeout = <0xffff>;
++              samsung,pll-clk-freq = <24000000>;
++              samsung,cmd-allow = <0xf>;
+               vdd11-supply = <&vusb_reg>;
+               vdd18-supply = <&vmipi_reg>;
+-              panel-info = <&fimd0_lcd>;
+               status = "okay";
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0078-ARM-dts-Add-dts-file-for-exynos4412-redwood-board.patch b/patches.tizen/0078-ARM-dts-Add-dts-file-for-exynos4412-redwood-board.patch
new file mode 100644 (file)
index 0000000..40d1fb3
--- /dev/null
@@ -0,0 +1,532 @@
+From adb6cc2102823aa7ab37867b7884c0e0a2d98ee4 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Tue, 5 Feb 2013 15:59:06 +0100
+Subject: [PATCH 0078/1302] ARM: dts: Add dts file for exynos4412-redwood board
+
+This patch adds a basic dts file for Redwood board based on Exynos 4412
+SoC.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/Makefile               |   1 +
+ arch/arm/boot/dts/exynos4412-redwood.dts | 495 +++++++++++++++++++++++++++++++
+ 2 files changed, 496 insertions(+)
+ create mode 100644 arch/arm/boot/dts/exynos4412-redwood.dts
+
+diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
+index ecdfe00..eb86706 100644
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -51,6 +51,7 @@ dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \
+       exynos4210-trats.dtb \
+       exynos4210-universal_c210.dtb \
+       exynos4412-odroidx.dtb \
++      exynos4412-redwood.dtb \
+       exynos4412-smdk4412.dtb \
+       exynos4412-slp_pq.dtb \
+       exynos4412-origen.dtb \
+diff --git a/arch/arm/boot/dts/exynos4412-redwood.dts b/arch/arm/boot/dts/exynos4412-redwood.dts
+new file mode 100644
+index 0000000..78e763a
+--- /dev/null
++++ b/arch/arm/boot/dts/exynos4412-redwood.dts
+@@ -0,0 +1,495 @@
++/*
++ * Samsung's Exynos4412 based  board device tree source
++ *
++ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
++ *            http://www.samsung.com
++ *
++ * Device tree source file for Samsung's Redwood board which is based on
++ * Samsung's Exynos4412 SoC.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++*/
++
++/dts-v1/;
++/include/ "exynos4412.dtsi"
++
++/ {
++      model = "Samsung Redwood based on Exynos4412";
++      compatible = "samsung,redwood", "samsung,exynos4412";
++
++      memory {
++              reg =  <0x40000000 0x10000000
++                      0x50000000 0x10000000
++                      0x60000000 0x10000000
++                      0x70000000 0x10000000>;
++      };
++
++      chosen {
++              bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rootwait earlyprintk panic=5";
++      };
++
++      firmware@0204F000 {
++              compatible = "samsung,secure-firmware";
++              reg = <0x0204F000 0x1000>;
++      };
++
++      fixed-rate-clocks {
++              xxti {
++                      compatible = "samsung,clock-xxti", "fixed-clock";
++                      clock-frequency = <0>;
++              };
++
++              xusbxti {
++                      compatible = "samsung,clock-xusbxti", "fixed-clock";
++                      clock-frequency = <24000000>;
++              };
++      };
++
++      vemmc_reg: voltage-regulator@0 {
++              compatible = "regulator-fixed";
++              regulator-name = "VMEM_VDD_2.8V";
++              regulator-min-microvolt = <2800000>;
++              regulator-max-microvolt = <2800000>;
++              gpio = <&gpk0 2 0>;
++              enable-active-high;
++      };
++
++      sdhci_emmc: sdhci@12510000 {
++              bus-width = <8>;
++              non-removable;
++              pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus8>;
++              pinctrl-names = "default";
++              vmmc-supply = <&vemmc_reg>;
++              status = "okay";
++      };
++
++      serial@13800000 {
++              status = "okay";
++      };
++
++      serial@13810000 {
++              status = "okay";
++      };
++
++      serial@13820000 {
++              status = "okay";
++      };
++
++      serial@13830000 {
++              status = "okay";
++      };
++
++      gpio-keys@0 {
++              compatible = "gpio-keys";
++
++              key@114 {
++                      interrupt-parent = <&gpj1>;
++                      interrupts = <2 0>;
++                      gpios = <&gpj1 2 1>;
++                      linux,code = <114>;
++                      label = "volume down";
++                      debounce-interval = <10>;
++              };
++
++              key@115 {
++                      interrupt-parent = <&gpj1>;
++                      interrupts = <1 0>;
++                      gpios = <&gpj1 1 1>;
++                      linux,code = <115>;
++                      label = "volume up";
++                      debounce-interval = <10>;
++              };
++
++              key@116 {
++                      interrupt-parent = <&gpx2>;
++                      interrupts = <7 0>;
++                      gpios = <&gpx2 7 1>;
++                      linux,code = <116>;
++                      label = "power";
++                      debounce-interval = <10>;
++                      gpio-key,wakeup;
++              };
++      };
++
++      i2c@13890000 {
++              samsung,i2c-sda-delay = <100>;
++              samsung,i2c-slave-addr = <0x10>;
++              samsung,i2c-max-bus-freq = <400000>;
++              pinctrl-0 = <&i2c3_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              mms114-touchscreen@48 {
++                      compatible = "melfas,mms114";
++                      reg = <0x48>;
++                      interrupt-parent = <&gpm2>;
++                      interrupts = <3 2>;
++                      x-size = <720>;
++                      y-size = <1280>;
++                      avdd-supply = <&ldo23_reg>;
++                      vdd-supply = <&ldo24_reg>;
++              };
++      };
++
++      i2c@138D0000 {
++              samsung,i2c-sda-delay = <100>;
++              samsung,i2c-slave-addr = <0x10>;
++              samsung,i2c-max-bus-freq = <100000>;
++              pinctrl-0 = <&i2c7_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              max77686_pmic@09 {
++                      compatible = "maxim,max77686";
++                      interrupt-parent = <&gpx0>;
++                      interrupts = <7 0>;
++                      reg = <0x09>;
++
++                      voltage-regulators {
++                              ldo1_reg: ldo@1 {
++                                      regulator-compatible = "LDO1";
++                                      regulator-name = "VALIVE_1.0V_AP";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo2_reg: ldo@2 {
++                                      regulator-compatible = "LDO2";
++                                      regulator-name = "VM1M2_1.2V_AP";
++                                      regulator-min-microvolt = <1200000>;
++                                      regulator-max-microvolt = <1200000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo3_reg: ldo@3 {
++                                      regulator-compatible = "LDO3";
++                                      regulator-name = "VCC_1.8V_AP";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo4_reg: ldo@4 {
++                                      regulator-compatible = "LDO4";
++                                      regulator-name = "VCC_2.8V_AP";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo5_reg: ldo@5 {
++                                      regulator-compatible = "LDO5";
++                                      regulator-name = "VCC_1.8V_IO";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo6_reg: ldo@6 {
++                                      regulator-compatible = "LDO6";
++                                      regulator-name = "VMPLL_1.0V_AP";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo7_reg: ldo@7 {
++                                      regulator-compatible = "LDO7";
++                                      regulator-name = "VPLL_1.0V_AP";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo8_reg: ldo@8 {
++                                      regulator-compatible = "LDO8";
++                                      regulator-name = "VMIPI_1.0V";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                              };
++
++                              ldo9_reg: ldo@9 {
++                                      regulator-compatible = "LDO9";
++                                      regulator-name = "CAM_ISP_MIPI_1.2V";
++                                      regulator-min-microvolt = <1200000>;
++                                      regulator-max-microvolt = <1200000>;
++                              };
++
++                              ldo10_reg: ldo@10 {
++                                      regulator-compatible = "LDO10";
++                                      regulator-name = "VMIPI_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                              };
++
++                              ldo11_reg: ldo@11 {
++                                      regulator-compatible = "LDO11";
++                                      regulator-name = "VABB1_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo12_reg: ldo@12 {
++                                      regulator-compatible = "LDO12";
++                                      regulator-name = "VUOTG_3.0V";
++                                      regulator-min-microvolt = <3000000>;
++                                      regulator-max-microvolt = <3000000>;
++                              };
++
++                              ldo13_reg: ldo@13 {
++                                      regulator-compatible = "LDO13";
++                                      regulator-name = "NFC_AVDD_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                              };
++
++                              ldo14_reg: ldo@14 {
++                                      regulator-compatible = "LDO14";
++                                      regulator-name = "VABB2_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo15_reg: ldo@15 {
++                                      regulator-compatible = "LDO15";
++                                      regulator-name = "VHSIC_1.0V";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                              };
++
++                              ldo16_reg: ldo@16 {
++                                      regulator-compatible = "LDO16";
++                                      regulator-name = "VHSIC_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                              };
++
++                              ldo17_reg: ldo@17 {
++                                      regulator-compatible = "LDO17";
++                                      regulator-name = "CAM_SENSOR_CORE_1.2V";
++                                      regulator-min-microvolt = <1200000>;
++                                      regulator-max-microvolt = <1200000>;
++                              };
++
++                              ldo18_reg: ldo@18 {
++                                      regulator-compatible = "LDO18";
++                                      regulator-name = "CAM_ISP_SENSOR_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                              };
++
++                              ldo19_reg: ldo@19 {
++                                      regulator-compatible = "LDO19";
++                                      regulator-name = "VT_CAM_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                              };
++
++                              ldo20_reg: ldo@20 {
++                                      regulator-compatible = "LDO20";
++                                      regulator-name = "VDDQ_PRE_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                              };
++
++                              ldo21_reg: ldo@21 {
++                                      regulator-compatible = "LDO21";
++                                      regulator-name = "VTF_2.8V";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
++                              };
++
++                              ldo22_reg: ldo@22 {
++                                      regulator-compatible = "LDO22";
++                                      regulator-name = "VMEM_VDD_2.8V";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo23_reg: ldo@23 {
++                                      regulator-compatible = "LDO23";
++                                      regulator-name = "TSP_AVDD_3.3V";
++                                      regulator-min-microvolt = <3300000>;
++                                      regulator-max-microvolt = <3300000>;
++                              };
++
++                              ldo24_reg: ldo@24 {
++                                      regulator-compatible = "LDO24";
++                                      regulator-name = "VDD_1.8V_TSP";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                              };
++
++                              ldo25_reg: ldo@25 {
++                                      regulator-compatible = "LDO25";
++                                      regulator-name = "LED_A_2.8V";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
++                              };
++
++                              ldo26_reg: ldo@26 {
++                                      regulator-compatible = "LDO26";
++                                      regulator-name = "MOTOR_VCC_3.0V";
++                                      regulator-min-microvolt = <3000000>;
++                                      regulator-max-microvolt = <3000000>;
++                              };
++
++                              buck1_reg: buck@1 {
++                                      regulator-compatible = "BUCK1";
++                                      regulator-name = "vdd_mif";
++                                      regulator-min-microvolt = <850000>;
++                                      regulator-max-microvolt = <1100000>;
++                                      regulator-always-on;
++                                      regulator-boot-on;
++                              };
++
++                              buck2_reg: buck@2 {
++                                      regulator-compatible = "BUCK2";
++                                      regulator-name = "vdd_arm";
++                                      regulator-min-microvolt = <850000>;
++                                      regulator-max-microvolt = <1500000>;
++                                      regulator-always-on;
++                                      regulator-boot-on;
++                              };
++
++                              buck3_reg: buck@3 {
++                                      regulator-compatible = "BUCK3";
++                                      regulator-name = "vdd_int";
++                                      regulator-min-microvolt = <850000>;
++                                      regulator-max-microvolt = <1150000>;
++                                      regulator-always-on;
++                                      regulator-boot-on;
++                              };
++
++                              buck4_reg: buck@4 {
++                                      regulator-compatible = "BUCK4";
++                                      regulator-name = "vdd_g3d";
++                                      regulator-min-microvolt = <850000>;
++                                      regulator-max-microvolt = <1150000>;
++                                      regulator-boot-on;
++                              };
++
++                              buck5_reg: buck@5 {
++                                      regulator-compatible = "BUCK5";
++                                      regulator-name = "VMEM_1.2V_AP";
++                                      regulator-min-microvolt = <1200000>;
++                                      regulator-max-microvolt = <1200000>;
++                                      regulator-always-on;
++                              };
++
++                              buck6_reg: buck@6 {
++                                      regulator-compatible = "BUCK6";
++                                      regulator-name = "VCC_SUB_1.35V";
++                                      regulator-min-microvolt = <1350000>;
++                                      regulator-max-microvolt = <1350000>;
++                                      regulator-always-on;
++                              };
++                              buck7_reg: buck@7 {
++                                      regulator-compatible = "BUCK7";
++                                      regulator-name = "VCC_SUB_2.0V";
++                                      regulator-min-microvolt = <2000000>;
++                                      regulator-max-microvolt = <2000000>;
++                                      regulator-always-on;
++                              };
++
++                              buck8_reg: buck@8 {
++                                      regulator-compatible = "BUCK8";
++                                      regulator-name = "VMEM_VDDF_3.0V";
++                                      regulator-min-microvolt = <2850000>;
++                                      regulator-max-microvolt = <2850000>;
++                                      regulator-always-on;
++                              };
++
++                              buck9_reg: buck@9 {
++                                      regulator-compatible = "BUCK9";
++                                      regulator-name = "CAM_ISP_CORE_1.2V";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1200000>;
++                              };
++                      };
++              };
++      };
++
++      lcd_vdd_reg: voltage-regulator@1 {
++              compatible = "regulator-fixed";
++              regulator-name = "LCD_VDD_5.0V";
++              regulator-min-microvolt = <5000000>;
++              regulator-max-microvolt = <5000000>;
++              gpio = <&gpm0 0 0>;
++              enable-active-high;
++      };
++
++      fimd0_lcd: panel {
++              compatible = "samsung,s6d6aa1";
++              reset-gpio = <&gpf2 1 0>;
++              reset-delay = <100>;
++              power-on-delay= <50>;
++              vdd-supply = <&lcd_vdd_reg>;
++              vddi-supply = <&ldo5_reg>;
++              video-source = <&dsi_0>;
++              flip-horizontal;
++              flip-vertical;
++
++              display-timings {
++                      native-mode = <&timing0>;
++
++                      timing0: timing-0 {
++                              clock-frequency = <0>;
++                              hactive = <720>;
++                              vactive = <1280>;
++                              hfront-porch = <60>;
++                              hback-porch = <60>;
++                              hsync-len = <3>;
++                              vfront-porch = <36>;
++                              vback-porch = <2>;
++                              vsync-len = <2>;
++                      };
++              };
++      };
++
++      dsi_0: dsi@11C80000 {
++              samsung,pll-stable-time = <500>;
++              samsung,stop-holding-count = <0x7ff>;
++              samsung,bta-timeout = <0xff>;
++              samsung,rx-timeout = <0xffff>;
++              samsung,pll-clk-freq = <24000000>;
++              samsung,cmd-allow = <0xf>;
++              vdd11-supply = <&ldo8_reg>;
++              vdd18-supply = <&ldo10_reg>;
++              status = "okay";
++      };
++
++      fimd@11c00000 {
++              samsung,fimd-display = <&fimd0_lcd>;
++              samsung,fimd-vidout-rgb;
++              samsung,fimd-inv-vclk;
++              samsung,fimd-frame-rate = <60>;
++              samsung,default-window = <3>;
++              samsung,fimd-win-bpp = <32>;
++              status = "okay";
++      };
++
++      vidi {
++              compatible = "samsung,exynos-drm-vidi";
++      };
++
++      sysmmu-fimd0 {
++              mmu-master = <&fimd>;
++      };
++
++      usbphy@125B0000 {
++              status = "okay";
++      };
++
++      hsotg@12480000 {
++              status = "okay";
++              vusb_d-supply = <&ldo15_reg>;
++              vusb_a-supply = <&ldo12_reg>;
++      };
++};
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0079-ARM-dts-Add-dts-file-for-exynos4412-m0-board.patch b/patches.tizen/0079-ARM-dts-Add-dts-file-for-exynos4412-m0-board.patch
new file mode 100644 (file)
index 0000000..c1696a4
--- /dev/null
@@ -0,0 +1,59 @@
+From 0432c42736661441f35e6e4161af41bca9af8ee1 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Tue, 5 Feb 2013 15:59:06 +0100
+Subject: [PATCH 0079/1302] ARM: dts: Add dts file for exynos4412-m0 board
+
+This patch adds a basic dts file for M0 board based on Exynos 4412
+SoC.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/Makefile          |  1 +
+ arch/arm/boot/dts/exynos4412-m0.dts | 22 ++++++++++++++++++++++
+ 2 files changed, 23 insertions(+)
+ create mode 100644 arch/arm/boot/dts/exynos4412-m0.dts
+
+diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
+index eb86706..00fe583 100644
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -50,6 +50,7 @@ dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \
+       exynos4210-smdkv310.dtb \
+       exynos4210-trats.dtb \
+       exynos4210-universal_c210.dtb \
++      exynos4412-m0.dtb \
+       exynos4412-odroidx.dtb \
+       exynos4412-redwood.dtb \
+       exynos4412-smdk4412.dtb \
+diff --git a/arch/arm/boot/dts/exynos4412-m0.dts b/arch/arm/boot/dts/exynos4412-m0.dts
+new file mode 100644
+index 0000000..300ce10
+--- /dev/null
++++ b/arch/arm/boot/dts/exynos4412-m0.dts
+@@ -0,0 +1,22 @@
++/*
++ * Samsung's Exynos4412 based M0 board device tree source
++ *
++ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
++ *            http://www.samsung.com
++ *
++ * Device tree source file for Samsung's M0 board which is based on
++ * Samsung's Exynos4412 SoC.
++ *
++ * 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/ "exynos4412-slp_pq.dts"
++
++/ {
++      model = "Samsung M0 based on Exynos4412";
++      compatible = "samsung,m0", "samsung,exynos4412";
++
++      /* Nothing to override here yet. */
++};
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0080-USB-s3c-hsotg-fix-Kconfig-dependency.patch b/patches.tizen/0080-USB-s3c-hsotg-fix-Kconfig-dependency.patch
new file mode 100644 (file)
index 0000000..711eada
--- /dev/null
@@ -0,0 +1,27 @@
+From 6c69ec59de88161d1b9117f5dedce17b1738e42e Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Tue, 12 Feb 2013 11:51:18 +0100
+Subject: [PATCH 0080/1302] USB: s3c-hsotg: fix Kconfig dependency
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index f41aa0d..cefb5d6 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -271,7 +271,7 @@ config USB_PXA27X
+ config USB_S3C_HSOTG
+       tristate "S3C HS/OtG USB Device controller"
+-      depends on S3C_DEV_USB_HSOTG
++      depends on PLAT_SAMSUNG
+       help
+         The Samsung S3C64XX USB2.0 high-speed gadget controller
+         integrated into the S3C64XX series SoC.
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0081-ARM-dts-Correct-FIMC-clocks-definitions-for-Exynos42.patch b/patches.tizen/0081-ARM-dts-Correct-FIMC-clocks-definitions-for-Exynos42.patch
new file mode 100644 (file)
index 0000000..58de326
--- /dev/null
@@ -0,0 +1,163 @@
+From 057a9f8c61f3538e7f18009b764dcf95eac72653 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 13 Feb 2013 12:24:42 +0100
+Subject: [PATCH 0081/1302] ARM: dts: Correct FIMC clocks definitions for
+ Exynos4210
+
+Set sclk_mpll as parent clock for FIMC and camera clocks
+for Exynos4210 and mout_mpll_user_t for Exynos4x12.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi    | 16 ----------------
+ arch/arm/boot/dts/exynos4210.dtsi | 27 +++++++++++++++++++++++++++
+ arch/arm/boot/dts/exynos4x12.dtsi | 13 +++++++++++++
+ 3 files changed, 40 insertions(+), 16 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index 631c36d..3876b12 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -117,10 +117,6 @@
+       camera {
+               compatible = "samsung,fimc", "simple-bus";
+-              clocks = <&clock 132>, <&clock 133>, <&clock 351>, <&clock 352>,
+-                       <&clock 388>, <&clock 389>, <&clock 17>;
+-              clock-names = "sclk_cam0", "sclk_cam1", "pxl_async0",
+-                          "pxl_async1", "mux_cam0", "mux_cam1", "parent";
+               status = "disabled";
+               #address-cells = <1>;
+               #size-cells = <1>;
+@@ -132,8 +128,6 @@
+                       reg = <0x11800000 0x1000>;
+                       interrupts = <0 84 0>;
+                       samsung,power-domain = <&pd_cam>;
+-                      clocks = <&clock 256>, <&clock 128>, <&clock 384>, <&clock 17>;
+-                      clock-names = "fimc", "sclk_fimc", "mux", "parent";
+                       status = "disabled";
+               };
+@@ -142,8 +136,6 @@
+                       reg = <0x11810000 0x1000>;
+                       interrupts = <0 85 0>;
+                       samsung,power-domain = <&pd_cam>;
+-                      clocks = <&clock 257>, <&clock 129>, <&clock 385>, <&clock 17>;
+-                      clock-names = "fimc", "sclk_fimc", "mux", "parent";
+                       status = "disabled";
+               };
+@@ -152,8 +144,6 @@
+                       reg = <0x11820000 0x1000>;
+                       interrupts = <0 86 0>;
+                       samsung,power-domain = <&pd_cam>;
+-                      clocks = <&clock 258>, <&clock 130>, <&clock 386>, <&clock 17>;
+-                      clock-names = "fimc", "sclk_fimc", "mux", "parent";
+                       status = "disabled";
+               };
+@@ -162,8 +152,6 @@
+                       reg = <0x11830000 0x1000>;
+                       interrupts = <0 87 0>;
+                       samsung,power-domain = <&pd_cam>;
+-                      clocks = <&clock 259>, <&clock 131>, <&clock 387>, <&clock 17>;
+-                      clock-names = "fimc", "sclk_fimc", "mux", "parent";
+                       status = "disabled";
+               };
+@@ -173,8 +161,6 @@
+                       interrupts = <0 78 0>;
+                       bus-width = <4>;
+                       samsung,power-domain = <&pd_cam>;
+-                      clocks = <&clock 260>, <&clock 134>, <&clock 390>, <&clock 17>;
+-                      clock-names = "csis", "sclk_csis", "mux", "parent";
+                       status = "disabled";
+               };
+@@ -184,8 +170,6 @@
+                       interrupts = <0 80 0>;
+                       bus-width = <2>;
+                       samsung,power-domain = <&pd_cam>;
+-                      clocks = <&clock 261>, <&clock 135>, <&clock 391>, <&clock 17>;
+-                      clock-names = "csis", "sclk_csis", "mux", "parent";
+                       status = "disabled";
+               };
+       };
+diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
+index 501708a..5f1a54b 100644
+--- a/arch/arm/boot/dts/exynos4210.dtsi
++++ b/arch/arm/boot/dts/exynos4210.dtsi
+@@ -164,4 +164,31 @@
+                       reg = <0x10020704 0x8>;
+               };
+       };
++
++      camera {
++              clocks = <&clock 132>, <&clock 133>, <&clock 351>, <&clock 352>,
++                       <&clock 388>, <&clock 389>, <&clock 9>;
++              clock-names = "sclk_cam0", "sclk_cam1", "pxl_async0",
++                          "pxl_async1", "mux_cam0", "mux_cam1", "parent";
++
++              fimc_0: fimc@11800000 {
++                      clocks = <&clock 256>, <&clock 128>, <&clock 384>, <&clock 9>;
++                      clock-names = "fimc", "sclk_fimc", "mux", "parent";
++              };
++
++              fimc_1: fimc@11810000 {
++                      clocks = <&clock 257>, <&clock 129>, <&clock 385>, <&clock 9>;
++                      clock-names = "fimc", "sclk_fimc", "mux", "parent";
++              };
++
++              fimc_2: fimc@11820000 {
++                      clocks = <&clock 258>, <&clock 130>, <&clock 386>, <&clock 9>;
++                      clock-names = "fimc", "sclk_fimc", "mux", "parent";
++              };
++
++              fimc_3: fimc@11830000 {
++                      clocks = <&clock 259>, <&clock 131>, <&clock 387>, <&clock 9>;
++                      clock-names = "fimc", "sclk_fimc", "mux", "parent";
++              };
++      };
+ };
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index 621301c..1ae99fc 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -183,20 +183,33 @@
+       };
+       camera {
++              clocks = <&clock 132>, <&clock 133>, <&clock 351>, <&clock 352>,
++                       <&clock 388>, <&clock 389>, <&clock 17>;
++              clock-names = "sclk_cam0", "sclk_cam1", "pxl_async0",
++                          "pxl_async1", "mux_cam0", "mux_cam1", "parent";
++
+               fimc_0: fimc@11800000 {
+                       compatible = "samsung,exynos4212-fimc";
++                      clocks = <&clock 256>, <&clock 128>, <&clock 384>, <&clock 17>;
++                      clock-names = "fimc", "sclk_fimc", "mux", "parent";
+               };
+               fimc_1: fimc@11810000 {
+                       compatible = "samsung,exynos4212-fimc";
++                      clocks = <&clock 257>, <&clock 129>, <&clock 385>, <&clock 17>;
++                      clock-names = "fimc", "sclk_fimc", "mux", "parent";
+               };
+               fimc_2: fimc@11820000 {
+                       compatible = "samsung,exynos4212-fimc";
++                      clocks = <&clock 258>, <&clock 130>, <&clock 386>, <&clock 17>;
++                      clock-names = "fimc", "sclk_fimc", "mux", "parent";
+               };
+               fimc_3: fimc@11830000 {
+                       compatible = "samsung,exynos4212-fimc";
++                      clocks = <&clock 259>, <&clock 131>, <&clock 387>, <&clock 17>;
++                      clock-names = "fimc", "sclk_fimc", "mux", "parent";
+               };
+               fimc_is: fimc-is@12000000 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0082-ARM-dts-Remove-unnecessary-properties-in-PQ-camera-n.patch b/patches.tizen/0082-ARM-dts-Remove-unnecessary-properties-in-PQ-camera-n.patch
new file mode 100644 (file)
index 0000000..0634bf5
--- /dev/null
@@ -0,0 +1,33 @@
+From 592c12d9c5e17fc9efb95050d908395ca4448ed9 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 13 Feb 2013 12:26:09 +0100
+Subject: [PATCH 0082/1302] ARM: dts: Remove unnecessary properties in PQ
+ camera node
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 5a2b70b..966e071 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -592,12 +592,10 @@
+       };
+       camera {
+-              compatible = "samsung,fimc", "simple-bus";
+               status = "okay";
+-              pinctrl-names = "default", "inactive";
++              pinctrl-names = "default";
+               pinctrl-0 = <&cam_port_a_clk_active>;
+-              pinctrl-1 = <&cam_port_a_clk_idle>;
+               fimc_0: fimc@11800000 {
+                       clock-frequency = <176000000>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0083-ARM-dts-Add-FIMC-nodes-for-Exynos4210-Trats-board.patch b/patches.tizen/0083-ARM-dts-Add-FIMC-nodes-for-Exynos4210-Trats-board.patch
new file mode 100644 (file)
index 0000000..fa60189
--- /dev/null
@@ -0,0 +1,43 @@
+From fa53fcf03220a1f330f4b98abfdef8ccda53a21a Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 13 Feb 2013 12:26:45 +0100
+Subject: [PATCH 0083/1302] ARM: dts: Add FIMC nodes for Exynos4210 Trats board
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index c339f2a..64e0775 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -374,4 +374,24 @@
+               samsung,fimd-win-bpp = <32>;
+               status = "okay";
+       };
++
++      camera {
++              status = "okay";
++
++              fimc_0: fimc@11800000 {
++                      status = "okay";
++              };
++
++              fimc_1: fimc@11810000 {
++                      status = "okay";
++              };
++
++              fimc_2: fimc@11820000 {
++                      status = "okay";
++              };
++
++              fimc_3: fimc@11830000 {
++                      status = "okay";
++              };
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0084-ARM-dts-Add-CMA-region-definitions-and-enable-MFC-fo.patch b/patches.tizen/0084-ARM-dts-Add-CMA-region-definitions-and-enable-MFC-fo.patch
new file mode 100644 (file)
index 0000000..5ee53e2
--- /dev/null
@@ -0,0 +1,64 @@
+From c8101bcbe132a6b10c7c6401adf5b0ae78743b36 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Wed, 3 Jul 2013 08:54:47 +0200
+Subject: [PATCH 0084/1302] ARM: dts: Add CMA region definitions and enable MFC
+ for Trats board
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 33 +++++++++++++++++++++++++++++++++
+ 1 file changed, 33 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index 64e0775..e1ac388 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -24,6 +24,27 @@
+                       0x50000000 0x10000000
+                       0x60000000 0x10000000
+                       0x70000000 0x10000000>;
++
++              reserved-memory {
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      contig_mem: region@72000000 {
++                              compatible = "linux,contiguous-memory-region";
++                              reg = <0x72000000 0xc000000>;
++                              linux,default-contiguous-region;
++                      };
++
++                      mfc_l_mem: mfc_l_region@43000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x43000000 0x1000000>;
++                      };
++
++                      mfc_r_mem: mfc_r_region@51000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x51000000 0x1000000>;
++                      };
++              };
+       };
+       chosen {
+@@ -394,4 +415,16 @@
+                       status = "okay";
+               };
+       };
++
++      mfc: codec@13400000 {
++              status = "okay";
++
++              memport@0 {
++                      memory-region = <&mfc_l_mem>;
++              };
++
++              memport@1 {
++                      memory-region = <&mfc_r_mem>;
++              };
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0085-ARM-dts-Add-empty-camera-pinctrl-property-for-Trats-.patch b/patches.tizen/0085-ARM-dts-Add-empty-camera-pinctrl-property-for-Trats-.patch
new file mode 100644 (file)
index 0000000..4076aef
--- /dev/null
@@ -0,0 +1,29 @@
+From 463a43dec8034a7e7659c7465c5b9a36e6eb8d44 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 13 Feb 2013 12:52:52 +0100
+Subject: [PATCH 0085/1302] ARM: dts: Add empty camera pinctrl property for
+ Trats board
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index e1ac388..e316890 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -399,6 +399,9 @@
+       camera {
+               status = "okay";
++              pinctrl-names = "default";
++              pinctrl-0 = <>; /* TODO */
++
+               fimc_0: fimc@11800000 {
+                       status = "okay";
+               };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0086-ARM-dts-Add-missing-MIPI-CSIS-clock-properties-for-E.patch b/patches.tizen/0086-ARM-dts-Add-missing-MIPI-CSIS-clock-properties-for-E.patch
new file mode 100644 (file)
index 0000000..121d075
--- /dev/null
@@ -0,0 +1,61 @@
+From bbe3f016e7af0062d8d93372036c4c1b5ed935bc Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 13 Feb 2013 15:56:30 +0100
+Subject: [PATCH 0086/1302] ARM: dts: Add missing MIPI-CSIS clock properties
+ for Exynos4 SoCs
+
+Add MIPI-CSIS clock properties missing in commit
+c266c6dc5fb3c597d0e1a706438aa64797ca249b
+ARM: dts: Correct FIMC clocks definitions for Exynos4210
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210.dtsi | 10 ++++++++++
+ arch/arm/boot/dts/exynos4x12.dtsi | 10 ++++++++++
+ 2 files changed, 20 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
+index 5f1a54b..99cb43e 100644
+--- a/arch/arm/boot/dts/exynos4210.dtsi
++++ b/arch/arm/boot/dts/exynos4210.dtsi
+@@ -190,5 +190,15 @@
+                       clocks = <&clock 259>, <&clock 131>, <&clock 387>, <&clock 9>;
+                       clock-names = "fimc", "sclk_fimc", "mux", "parent";
+               };
++
++              csis_0: csis@11880000 {
++                      clocks = <&clock 260>, <&clock 134>, <&clock 390>, <&clock 9>;
++                      clock-names = "csis", "sclk_csis", "mux", "parent";
++              };
++
++              csis_1: csis@11890000 {
++                      clocks = <&clock 261>, <&clock 135>, <&clock 391>, <&clock 9>;
++                      clock-names = "csis", "sclk_csis", "mux", "parent";
++              };
+       };
+ };
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index 1ae99fc..636c2f4 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -212,6 +212,16 @@
+                       clock-names = "fimc", "sclk_fimc", "mux", "parent";
+               };
++              csis_0: csis@11880000 {
++                      clocks = <&clock 260>, <&clock 134>, <&clock 390>, <&clock 17>;
++                      clock-names = "csis", "sclk_csis", "mux", "parent";
++              };
++
++              csis_1: csis@11890000 {
++                      clocks = <&clock 261>, <&clock 135>, <&clock 391>, <&clock 17>;
++                      clock-names = "csis", "sclk_csis", "mux", "parent";
++              };
++
+               fimc_is: fimc-is@12000000 {
+                       compatible = "samsung,exynos4212-fimc-is", "simple-bus";
+                       reg = <0x12000000 0x260000>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0087-misc-add-global-lock-driver-for-TIZEN.patch b/patches.tizen/0087-misc-add-global-lock-driver-for-TIZEN.patch
new file mode 100644 (file)
index 0000000..75d5d73
--- /dev/null
@@ -0,0 +1,1006 @@
+From 48157cf3e946012590ce957f0a973fc3c65f670a Mon Sep 17 00:00:00 2001
+From: Joonyoung Shim <jy0922.shim@samsung.com>
+Date: Tue, 29 Jan 2013 17:00:09 +0900
+Subject: [PATCH 0087/1302] misc: add global lock driver for TIZEN
+
+Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/misc/Kconfig           |   5 +
+ drivers/misc/Makefile          |   1 +
+ drivers/misc/slp_global_lock.c | 900 +++++++++++++++++++++++++++++++++++++++++
+ drivers/misc/slp_global_lock.h |  49 +++
+ 4 files changed, 955 insertions(+)
+ create mode 100644 drivers/misc/slp_global_lock.c
+ create mode 100644 drivers/misc/slp_global_lock.h
+
+diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
+index c002d86..378b0f3 100644
+--- a/drivers/misc/Kconfig
++++ b/drivers/misc/Kconfig
+@@ -518,6 +518,11 @@ config LATTICE_ECP3_CONFIG
+         If unsure, say N.
++config SLP_GLOBAL_LOCK
++      bool "SLP Global Lock"
++      help
++        This supports global lock feature for SLP.
++
+ config SRAM
+       bool "Generic on-chip SRAM driver"
+       depends on HAS_IOMEM
+diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
+index c235d5b..0cadf27 100644
+--- a/drivers/misc/Makefile
++++ b/drivers/misc/Makefile
+@@ -52,4 +52,5 @@ obj-$(CONFIG_ALTERA_STAPL)   +=altera-stapl/
+ obj-$(CONFIG_INTEL_MEI)               += mei/
+ obj-$(CONFIG_VMWARE_VMCI)     += vmw_vmci/
+ obj-$(CONFIG_LATTICE_ECP3_CONFIG)     += lattice-ecp3-config.o
++obj-$(CONFIG_SLP_GLOBAL_LOCK) += slp_global_lock.o
+ obj-$(CONFIG_SRAM)            += sram.o
+diff --git a/drivers/misc/slp_global_lock.c b/drivers/misc/slp_global_lock.c
+new file mode 100644
+index 0000000..4e78e79
+--- /dev/null
++++ b/drivers/misc/slp_global_lock.c
+@@ -0,0 +1,900 @@
++/*
++ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/fs.h>
++#include <linux/major.h>
++#include <linux/device.h>
++#include <linux/list.h>
++#include <linux/hash.h>
++#include <linux/slab.h>
++#include <linux/gfp.h>
++#include <linux/wait.h>
++#include <linux/jiffies.h>
++#include <asm/current.h>
++#include <linux/sched.h>
++
++#include "slp_global_lock.h"
++
++#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
++#include "mali_osk.h"
++#include "mali_osk_profiling.h"
++#endif
++
++#define SGL_WARN(x, y...)     printk(KERN_INFO "[SGL_WARN(%d,%d)](%s):%d " x " \n" , current->tgid, current->pid, __FUNCTION__, __LINE__, ##y)
++#define SGL_INFO(x, y...)     printk(KERN_INFO "[SGL_INFO] " x , ##y)
++
++#if 0 /* LOG */
++
++#define SGL_LOG(x, y...)      printk(KERN_INFO "[SGL_LOG(%d,%d)](%s):%d " x " \n" , current->tgid, current->pid, __FUNCTION__, __LINE__, ##y);
++#define SGL_DEBUG(x, y...)    printk(KERN_INFO "[SGL_DEBUG(%d,%d)](%s):%d " x " \n" , current->tgid, current->pid, __FUNCTION__, __LINE__, ##y);
++
++#else
++
++#define SGL_LOG(x, y...)
++#define SGL_DEBUG(x, y...)
++
++#endif
++
++static struct sgl_global {
++      int major;
++      struct class            *class;
++      struct device           *device;
++      void                            *locks;                 /* global lock table */
++      int                                     refcnt;                 /* ref count of sgl_global */
++      struct mutex            mutex;
++} sgl_global;
++
++struct sgl_session_data {
++      void                            *inited_locks;  /* per session initialized locks */
++      void                            *locked_locks;  /* per session locked locks */
++};
++
++struct sgl_lock {
++      unsigned int            key;                    /* key of this lock */
++      unsigned int            timeout_ms;             /* timeout in ms */
++      unsigned int            refcnt;                 /* ref count of initialization */
++      wait_queue_head_t       waiting_queue;  /* waiting queue */
++      struct list_head        waiting_list;   /* waiting list */
++      struct mutex            waiting_list_mutex;
++      unsigned int            locked;                 /* flag if this lock is locked */
++      unsigned int            owner;                  /* session data */
++
++      struct mutex            data_mutex;
++      unsigned int            user_data1;
++      unsigned int            user_data2;
++
++      pid_t                   owner_pid;
++      pid_t                   owner_tid;
++};
++
++/**************** hash code start ***************/
++#define SGL_HASH_BITS         4
++#define SGL_HASH_ENTRIES      (1 << SGL_HASH_BITS)
++
++struct sgl_hash_head {
++      struct hlist_head       head;                   /* hash_head */
++      struct mutex            mutex;
++};
++
++struct sgl_hash_node {
++      unsigned int            key;                    /* key for lock. must be same as lock->key */
++      struct sgl_lock         *lock;                  /* lock object */
++      struct hlist_node       node;                   /* hash node */
++};
++
++static const char sgl_dev_name[] = "slp_global_lock";
++
++/* find the sgl_lock object with key in the hash table */
++static struct sgl_hash_node *sgl_hash_get_node(struct sgl_hash_head *hash, unsigned int key)
++{
++      struct sgl_hash_head *hash_head = &hash[hash_32(key, SGL_HASH_BITS)];
++      struct sgl_hash_node *hash_node = NULL;
++      struct sgl_hash_node *found = NULL;
++
++      struct hlist_head *head = &hash_head->head;
++
++      SGL_LOG("key %d", key);
++
++      mutex_lock(&hash_head->mutex);
++      hlist_for_each_entry(hash_node, head, node) {
++              if (hash_node->key == key) {
++                      found = hash_node;
++                      break;
++              }
++      }
++      mutex_unlock(&hash_head->mutex);
++
++      SGL_LOG("hash_node: %p", hash_node);
++
++      return found;
++}
++
++/* insert the hash entry */
++static struct sgl_hash_node *sgl_hash_insert_node(struct sgl_hash_head *hash, unsigned int key)
++{
++      struct sgl_hash_head *hash_head = &hash[hash_32(key, SGL_HASH_BITS)];
++      struct sgl_hash_node *hash_node;
++
++      struct hlist_head *head = &hash_head->head;
++
++      SGL_LOG("key %d", key);
++
++      hash_node = kzalloc(sizeof(struct sgl_hash_node), GFP_KERNEL);
++      if (hash_node == NULL)
++              return NULL;
++
++      INIT_HLIST_NODE(&hash_node->node);
++      mutex_lock(&hash_head->mutex);
++      hlist_add_head(&hash_node->node, head);
++      mutex_unlock(&hash_head->mutex);
++
++      hash_node->key = key;
++
++      SGL_LOG();
++
++      return hash_node;
++}
++
++/* remove the hash entry */
++static int sgl_hash_remove_node(struct sgl_hash_head *hash, unsigned int key)
++{
++      struct sgl_hash_head *hash_head = &hash[hash_32(key, SGL_HASH_BITS)];
++      struct sgl_hash_node *hash_node;
++
++      struct hlist_head *head = &hash_head->head;
++
++      int err = -ENOENT;
++
++      SGL_LOG("key %d", key);
++
++      mutex_lock(&hash_head->mutex);
++      hlist_for_each_entry(hash_node, head, node) {
++              if (hash_node->key == key) {
++                      hlist_del(&hash_node->node);
++                      kfree(hash_node);
++                      err = 0;
++                      break;
++              }
++      }
++      mutex_unlock(&hash_head->mutex);
++
++      SGL_LOG();
++
++      return err;
++}
++
++static int sgl_hash_cleanup_nodes(struct sgl_hash_head *hash, int (*lock_cleanup_func)(struct sgl_lock *))
++{
++      struct sgl_hash_node *hash_node;
++
++      struct hlist_head *head;
++
++      int i;
++      int err = 0;
++
++      SGL_LOG();
++
++      for (i = 0; i < SGL_HASH_ENTRIES; i++) {
++              head = &hash[i].head;
++              mutex_lock(&hash->mutex);
++              while (!hlist_empty(head)) {
++                      hash_node = hlist_entry(head->first, struct sgl_hash_node, node);
++                      if (lock_cleanup_func(hash_node->lock) < 0)
++                              err = -EBADRQC;
++                      hlist_del(&hash_node->node);
++                      kfree(hash_node);
++              }
++              mutex_unlock(&hash->mutex);
++      }
++
++      SGL_LOG();
++
++      return err;
++}
++
++/* allocate the hash table */
++static struct sgl_hash_head *sgl_hash_create_table(void)
++{
++      struct sgl_hash_head *hash;
++
++      int i;
++
++      SGL_LOG();
++
++      hash = kzalloc(sizeof(struct sgl_hash_head) * SGL_HASH_ENTRIES, GFP_KERNEL);
++      if (hash == NULL)
++              return NULL;
++
++      for (i = 0; i < SGL_HASH_ENTRIES; i++) {
++              INIT_HLIST_HEAD(&hash[i].head);
++              mutex_init(&hash[i].mutex);
++      }
++
++      SGL_LOG();
++
++      return hash;
++}
++
++/* release the hash table */
++static void sgl_hash_destroy_table(struct sgl_hash_head *hash)
++{
++      SGL_LOG();
++
++      kfree(hash);
++
++      SGL_LOG();
++
++      return;
++}
++
++/**************** hash code end ***************/
++
++static struct sgl_lock *sgl_get_lock(void *locks, unsigned int key)
++{
++      struct sgl_hash_node *hash_node;
++
++      hash_node = sgl_hash_get_node((struct sgl_hash_head *)locks, key);
++      if (hash_node == NULL) {
++              return NULL;
++      }
++
++      return hash_node->lock;
++}
++
++static int sgl_insert_lock(void *locks, struct sgl_lock *lock)
++{
++      struct sgl_hash_node *hash_node;
++
++      hash_node = sgl_hash_insert_node((struct sgl_hash_head *)locks, lock->key);
++      if (hash_node == NULL)
++              return -ENOMEM;
++      hash_node->lock = lock;
++
++      return 0;
++}
++
++static int sgl_remove_lock(void *locks, unsigned int key)
++{
++      int err;
++
++      err = sgl_hash_remove_node((struct sgl_hash_head *)locks, key);
++
++      return err;
++}
++
++static int sgl_cleanup_locks(void *locks, int (*lock_cleanup_func)(struct sgl_lock *))
++{
++      int err = 0;
++
++      err = sgl_hash_cleanup_nodes((struct sgl_hash_head *)locks, lock_cleanup_func);
++
++      return err;
++}
++
++static void *sgl_create_locks(void)
++{
++      return (void *)sgl_hash_create_table();
++}
++
++static void sgl_destroy_locks(void *locks)
++{
++      sgl_hash_destroy_table((struct sgl_hash_head *)locks);
++      return;
++}
++/********** lock - hash glue code end *********/
++
++
++static int sgl_lock_lock(struct sgl_session_data *session_data, unsigned int key)
++{
++      struct sgl_lock *lock;
++
++      struct list_head waiting_entry;
++
++      unsigned long jiffies;
++      long ret = 0;
++
++      SGL_LOG("key: %d", key);
++
++      mutex_lock(&sgl_global.mutex);
++      lock = sgl_get_lock(sgl_global.locks, key);
++      if (lock == NULL) {
++              if (sgl_get_lock(session_data->inited_locks, key))
++                      sgl_remove_lock(session_data->inited_locks, key);
++
++              if (sgl_get_lock(session_data->locked_locks, key))
++                      sgl_remove_lock(session_data->locked_locks, key);
++              mutex_unlock(&sgl_global.mutex);
++              SGL_WARN("lock is not in the global locks");
++              return -ENOENT;
++      }
++
++      lock = sgl_get_lock(session_data->inited_locks, key);
++      if (lock == NULL) {
++              mutex_unlock(&sgl_global.mutex);
++              SGL_WARN("lock is not in the inited locks");
++              return -ENOENT;
++      }
++      mutex_unlock(&sgl_global.mutex);
++
++      INIT_LIST_HEAD(&waiting_entry);
++      mutex_lock(&lock->data_mutex);
++      lock->refcnt++;
++      mutex_unlock(&lock->data_mutex);
++      mutex_lock(&lock->waiting_list_mutex);
++      list_add_tail(&waiting_entry, &lock->waiting_list);
++      mutex_unlock(&lock->waiting_list_mutex);
++
++      jiffies = msecs_to_jiffies(lock->timeout_ms);
++
++#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
++    _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE |
++                               MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
++                               MALI_PROFILING_EVENT_REASON_SINGLE_SW_GLOBAL_TRY_LOCK,
++                               _mali_osk_get_pid(), _mali_osk_get_tid(), key, 0, 0);
++#endif
++
++      SGL_LOG();
++
++      ret = wait_event_timeout(lock->waiting_queue,
++                      ((lock->locked == 0)
++                      && lock->waiting_list.next == &waiting_entry),
++                      jiffies);
++      if (ret == 0) {
++              SGL_WARN("timed out, key: %d, owner(%d, %d)",
++                              key, lock->owner_pid, lock->owner_tid);
++              mutex_lock(&lock->data_mutex);
++              lock->refcnt--;
++              mutex_unlock(&lock->data_mutex);
++              mutex_lock(&lock->waiting_list_mutex);
++              list_del(&waiting_entry);
++              mutex_unlock(&lock->waiting_list_mutex);
++              return -ETIMEDOUT;
++      }
++
++      SGL_LOG();
++
++      mutex_lock(&lock->data_mutex);
++      lock->owner = (unsigned int)session_data;
++      lock->locked = 1;
++      lock->owner_pid = current->tgid;
++      lock->owner_tid = current->pid;
++      mutex_unlock(&lock->data_mutex);
++
++      mutex_lock(&lock->waiting_list_mutex);
++      list_del(&waiting_entry);
++      mutex_unlock(&lock->waiting_list_mutex);
++
++      /* add to the locked lock */
++      sgl_insert_lock(session_data->locked_locks, lock);
++
++#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
++    _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE |
++                               MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
++                               MALI_PROFILING_EVENT_REASON_SINGLE_SW_GLOBAL_LOCK,
++                               _mali_osk_get_pid(), _mali_osk_get_tid(), key, 0, 0);
++#endif
++
++      SGL_LOG();
++
++      return 0;
++}
++
++static int _sgl_unlock_lock(struct sgl_lock *lock)
++{
++      SGL_LOG();
++
++      if (lock == NULL) {
++              SGL_WARN("lock == NULL");
++              return -EBADRQC;
++      }
++      mutex_lock(&lock->data_mutex);
++
++      if (lock->locked == 0) {
++              mutex_unlock(&lock->data_mutex);
++              SGL_WARN("tried to unlock not-locked lock");
++              return -EBADRQC;
++      }
++
++      lock->owner = 0;
++      lock->locked = 0;
++      lock->owner_pid = 0;
++      lock->owner_tid = 0;
++      lock->refcnt--;
++
++      if (waitqueue_active(&lock->waiting_queue)) {
++              wake_up(&lock->waiting_queue);
++      }
++      mutex_unlock(&lock->data_mutex);
++
++      SGL_LOG();
++
++      return 0;
++}
++
++static int sgl_unlock_lock(struct sgl_session_data *session_data, unsigned int key)
++{
++      struct sgl_lock *lock;
++
++      int err = -ENOENT;
++
++      SGL_LOG("key: %d", key);
++
++      mutex_lock(&sgl_global.mutex);
++      lock = sgl_get_lock(sgl_global.locks, key);
++      if (lock == NULL) {
++              if (sgl_get_lock(session_data->inited_locks, key))
++                      sgl_remove_lock(session_data->inited_locks, key);
++
++              if (sgl_get_lock(session_data->locked_locks, key))
++                      sgl_remove_lock(session_data->locked_locks, key);
++              mutex_unlock(&sgl_global.mutex);
++              SGL_WARN("lock is not in the global locks");
++              return -ENOENT;
++      }
++
++      lock = sgl_get_lock(session_data->inited_locks, key);
++      if (lock == NULL) {
++              mutex_unlock(&sgl_global.mutex);
++              SGL_WARN("lock is not in the inited locks");
++              return -ENOENT;
++      }
++      mutex_unlock(&sgl_global.mutex);
++
++      mutex_lock(&lock->data_mutex);
++      if (lock->owner != (unsigned int)session_data) {
++              mutex_unlock(&lock->data_mutex);
++              SGL_WARN("tried to unlock the lock not-owned by calling session");
++              return -EBADRQC;
++      }
++      mutex_unlock(&lock->data_mutex);
++      sgl_remove_lock(session_data->locked_locks, key);
++      err = _sgl_unlock_lock(lock);
++      if (err < 0)
++              SGL_WARN("_sgl_unlock_lock() failed");
++
++#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
++    _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE |
++                               MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
++                               MALI_PROFILING_EVENT_REASON_SINGLE_SW_GLOBAL_UNLOCK,
++                               _mali_osk_get_pid(), _mali_osk_get_tid(), key, 0, 0);
++#endif
++
++
++      if (err < 0)
++              SGL_WARN("sgl_remove_lock() failed");
++
++      SGL_LOG();
++
++      return err;
++}
++
++static int sgl_init_lock(struct sgl_session_data *session_data, struct sgl_attribute *attr)
++{
++      struct sgl_lock *lock;
++
++      int err = 0;
++
++      SGL_LOG("key: %d", attr->key);
++
++      mutex_lock(&sgl_global.mutex);
++
++      lock = sgl_get_lock(sgl_global.locks, attr->key);
++      if (lock == NULL) {
++              /* allocate and add to the global table if this is the first initialization */
++              lock = kzalloc(sizeof(struct sgl_lock), GFP_KERNEL);
++              if (lock == NULL) {
++                      err = -ENOMEM;
++                      goto out_unlock;
++              }
++
++              lock->key = attr->key;
++
++              err = sgl_insert_lock(sgl_global.locks, lock);
++              if (err < 0)
++                      goto out_unlock;
++
++              /* default timeout value is 16ms */
++              lock->timeout_ms = attr->timeout_ms ? attr->timeout_ms : 16;
++
++              init_waitqueue_head(&lock->waiting_queue);
++              INIT_LIST_HEAD(&lock->waiting_list);
++              mutex_init(&lock->waiting_list_mutex);
++              mutex_init(&lock->data_mutex);
++      }
++      mutex_lock(&lock->data_mutex);
++      lock->refcnt++;
++      mutex_unlock(&lock->data_mutex);
++
++      /* add to the inited locks */
++      err = sgl_insert_lock(session_data->inited_locks, lock);
++
++out_unlock:
++
++      mutex_unlock(&sgl_global.mutex);
++
++      SGL_LOG();
++
++      return err;
++}
++
++static int _sgl_destroy_lock(struct sgl_lock *lock)
++{
++      int err = 0;
++
++      SGL_LOG();
++
++      if (lock == NULL) {
++              SGL_WARN("lock == NULL");
++              return -EBADRQC;
++      }
++
++      mutex_lock(&lock->data_mutex);
++      lock->refcnt--;
++      if (lock->refcnt == 0) {
++              mutex_unlock(&lock->data_mutex);
++              err = sgl_remove_lock(sgl_global.locks, lock->key);
++              if (err < 0)
++                      return err;
++
++              kfree(lock);
++      } else
++              mutex_unlock(&lock->data_mutex);
++
++      SGL_LOG();
++
++      return err;
++}
++
++static int sgl_destroy_lock(struct sgl_session_data *session_data, unsigned int key)
++{
++      struct sgl_lock *lock;
++
++      int err = 0;
++
++      SGL_LOG();
++
++      mutex_lock(&sgl_global.mutex);
++
++      lock = sgl_get_lock(sgl_global.locks, key);
++      if (lock == NULL) {
++              SGL_WARN("lock is not in the global locks");
++              err = -ENOENT;
++              goto out_unlock;
++      }
++      if (!sgl_get_lock(session_data->inited_locks, key)) {
++              SGL_WARN("lock is not in the inited locks");
++              err = -ENOENT;
++              goto out_unlock;
++      }
++
++      /* check if lock is still locked */
++      if (sgl_get_lock(session_data->locked_locks, key)) {
++              SGL_WARN("destroy failed. lock is still locked");
++              err = -EBUSY;
++              goto out_unlock;
++      }
++
++      err = _sgl_destroy_lock(lock);
++      if (err < 0)
++              goto out_unlock;
++
++      /* remove from the inited lock */
++      err = sgl_remove_lock(session_data->inited_locks, key);
++      if (err < 0)
++              goto out_unlock;
++
++out_unlock:
++
++      mutex_unlock(&sgl_global.mutex);
++
++      SGL_LOG();
++
++      return err;
++}
++
++static int sgl_set_data(struct sgl_session_data *session_data, struct sgl_user_data *user_data)
++{
++      struct sgl_lock *lock;
++      int ret = 0;
++      unsigned int key = user_data->key;
++
++      SGL_LOG("key: %d", key);
++
++      mutex_lock(&sgl_global.mutex);
++
++      lock = sgl_get_lock(sgl_global.locks, key);
++      if (lock == NULL) {
++              SGL_WARN("lock is not in the inited locks");
++              mutex_unlock(&sgl_global.mutex);
++              return -ENOENT;
++      }
++      mutex_lock(&lock->data_mutex);
++      lock->user_data1 = user_data->data1;
++      lock->user_data2 = user_data->data2;
++      user_data->locked = lock->locked;
++      mutex_unlock(&lock->data_mutex);
++      mutex_unlock(&sgl_global.mutex);
++
++      SGL_LOG();
++
++      return ret;
++}
++
++static int sgl_get_data(struct sgl_session_data *session_data, struct sgl_user_data *user_data)
++{
++      struct sgl_lock *lock;
++      int ret = 0;
++      unsigned int key = user_data->key;
++
++      SGL_LOG("key: %d", key);
++      mutex_lock(&sgl_global.mutex);
++
++      lock = sgl_get_lock(sgl_global.locks, key);
++      if (lock == NULL) {
++              SGL_WARN("lock is not in the inited locks");
++              mutex_unlock(&sgl_global.mutex);
++              return -ENOENT;
++      }
++      mutex_lock(&lock->data_mutex);
++      user_data->data1 = lock->user_data1;
++      user_data->data2 = lock->user_data2;
++      user_data->locked = lock->locked;
++      mutex_unlock(&lock->data_mutex);
++      mutex_unlock(&sgl_global.mutex);
++
++      SGL_LOG();
++
++      return ret;
++}
++
++static void sgl_dump_locks(void)
++{
++      int i;
++      SGL_INFO("SLP_GLOBAL_LOCK DUMP START\n");
++      mutex_lock(&sgl_global.mutex);
++      for (i = 0; i < SGL_HASH_ENTRIES; i++) {
++              struct sgl_hash_head *shead;
++              struct sgl_hash_node *snode;
++              struct hlist_head *hhead;
++
++              shead = &((struct sgl_hash_head *)sgl_global.locks)[i];
++              if (!shead)
++                      continue;
++              mutex_lock(&shead->mutex);
++              hhead = &shead->head;
++              hlist_for_each_entry(snode, hhead, node) {
++                      struct sgl_lock *lock = snode->lock;
++                      mutex_lock(&lock->data_mutex);
++                      SGL_INFO("lock key: %d, refcnt: %d, owner_pid: %d, owner_tid: %d\n",
++                                      lock->key, lock->refcnt, lock->owner_pid, lock->owner_tid);
++                      mutex_unlock(&lock->data_mutex);
++              }
++              mutex_unlock(&shead->mutex);
++      }
++      mutex_unlock(&sgl_global.mutex);
++      SGL_INFO("SLP_GLOBAL_LOCK DUMP END\n");
++}
++
++#ifdef HAVE_UNLOCKED_IOCTL
++static long sgl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
++#else
++static int sgl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
++#endif
++{
++      struct sgl_session_data *session_data = (struct sgl_session_data *)file->private_data;
++
++      int err = 0;
++
++      SGL_LOG();
++
++      switch (cmd) {
++      case SGL_IOC_INIT_LOCK:
++              /* destroy lock with attribute */
++              err = sgl_init_lock(session_data, (struct sgl_attribute *)arg);
++              break;
++      case SGL_IOC_DESTROY_LOCK:
++              /* destroy lock with id(=arg) */
++              err = sgl_destroy_lock(session_data, (unsigned int)arg);
++              break;
++      case SGL_IOC_LOCK_LOCK:
++              /* lock lock with id(=arg) */
++              err = sgl_lock_lock(session_data, (unsigned int)arg);
++              break;
++      case SGL_IOC_UNLOCK_LOCK:
++              /* unlock lock with id(=arg) */
++              err = sgl_unlock_lock(session_data, (unsigned int)arg);
++              break;
++      case SGL_IOC_SET_DATA:
++              err = sgl_set_data(session_data, (struct sgl_user_data *)arg);
++              break;
++      case SGL_IOC_GET_DATA:
++              err = sgl_get_data(session_data, (struct sgl_user_data *)arg);
++              break;
++      case SGL_IOC_DUMP_LOCKS:
++              sgl_dump_locks();
++              break;
++      default:
++                      SGL_WARN("unknown type of ioctl command");
++              break;
++      }
++
++      SGL_LOG();
++
++    return err;
++}
++
++static int sgl_open(struct inode *inode, struct file *file)
++{
++      struct sgl_session_data *session_data;
++
++      SGL_LOG();
++
++      /* init per thread data using file->private_data*/
++      session_data = kzalloc(sizeof(struct sgl_session_data), GFP_KERNEL);
++      if (session_data == NULL)
++              goto err_session_data;
++
++      session_data->inited_locks = sgl_create_locks();
++      if (session_data->inited_locks == NULL) {
++              goto err_inited_locks;
++      }
++
++      session_data->locked_locks = sgl_create_locks();
++      if (session_data->locked_locks == NULL) {
++              goto err_locked_locks;
++      }
++
++      file->private_data = (void *)session_data;
++
++      sgl_global.refcnt++;
++
++      SGL_LOG();
++
++    return 0;
++
++err_locked_locks:
++      sgl_destroy_locks(session_data->inited_locks);
++err_inited_locks:
++      kfree(session_data);
++err_session_data:
++      SGL_WARN();
++      return -ENOMEM;
++}
++
++static int sgl_release(struct inode *inode, struct file *file)
++{
++      struct sgl_session_data *session_data = file->private_data;
++
++      int err = 0;
++
++      SGL_LOG();
++
++      mutex_lock(&sgl_global.mutex);
++
++      /* clean up the locked locks */
++      if (sgl_cleanup_locks(session_data->locked_locks, _sgl_unlock_lock))
++              SGL_WARN("clean-up locked locks failed");
++
++      /* clean up the inited locks */
++      if (sgl_cleanup_locks(session_data->inited_locks, _sgl_destroy_lock))
++              SGL_WARN("clean-up inited locks failed");
++
++      /* clean up per thread data */
++      file->private_data = NULL;
++
++      sgl_destroy_locks(session_data->locked_locks);
++      sgl_destroy_locks(session_data->inited_locks);
++
++      kfree(session_data);
++
++      mutex_unlock(&sgl_global.mutex);
++      sgl_global.refcnt--;
++      if (sgl_global.refcnt == 0) {
++              /* destroy global lock table */
++              sgl_destroy_locks(sgl_global.locks);
++
++          device_destroy(sgl_global.class, MKDEV(sgl_global.major, 0));
++          class_destroy(sgl_global.class);
++          unregister_chrdev(sgl_global.major, sgl_dev_name);
++      }
++
++      SGL_LOG();
++
++    return err;
++}
++
++static const struct file_operations sgl_ops = {
++      .owner = THIS_MODULE,
++    .open = sgl_open,
++    .release = sgl_release,
++#ifdef HAVE_UNLOCKED_IOCTL
++      .unlocked_ioctl = sgl_ioctl,
++#else
++      .ioctl = sgl_ioctl,
++#endif
++};
++
++static int __init sgl_init(void)
++{
++      int err = 0;
++
++      SGL_LOG();
++
++      memset(&sgl_global, 0, sizeof(struct sgl_global));
++
++      sgl_global.major = SGL_MAJOR;
++      err = register_chrdev(sgl_global.major, sgl_dev_name, &sgl_ops);
++      if (err < 0)
++              goto err_register_chrdev;
++
++    sgl_global.class = class_create(THIS_MODULE, sgl_dev_name);
++      if (IS_ERR(sgl_global.class)) {
++              err = PTR_ERR(sgl_global.class);
++              goto err_class_create;
++      }
++
++    sgl_global.device = device_create(sgl_global.class, NULL, MKDEV(sgl_global.major, 0), NULL, sgl_dev_name);
++      if (IS_ERR(sgl_global.device)) {
++              err = PTR_ERR(sgl_global.device);
++              goto err_device_create;
++      }
++
++      /* create the global lock table */
++      sgl_global.locks = sgl_create_locks();
++      if (sgl_global.locks == NULL) {
++              err = -ENOMEM;
++              goto err_create_locks;
++      }
++
++      mutex_init(&sgl_global.mutex);
++
++      sgl_global.refcnt++;
++
++      SGL_LOG();
++
++    return 0;
++
++err_create_locks:
++err_device_create:
++    class_unregister(sgl_global.class);
++err_class_create:
++    unregister_chrdev(sgl_global.major, sgl_dev_name);
++err_register_chrdev:
++      SGL_WARN();
++      return err;
++}
++
++void sgl_exit(void)
++{
++      SGL_LOG();
++
++      sgl_global.refcnt--;
++      if (sgl_global.refcnt == 0) {
++              mutex_destroy(&sgl_global.mutex);
++
++              /* destroy global lock table */
++              sgl_destroy_locks(sgl_global.locks);
++
++          device_destroy(sgl_global.class, MKDEV(sgl_global.major, 0));
++          class_destroy(sgl_global.class);
++          unregister_chrdev(sgl_global.major, sgl_dev_name);
++      }
++
++      SGL_LOG();
++
++    return;
++}
++
++module_init(sgl_init);
++module_exit(sgl_exit);
++
++MODULE_LICENSE("GPL");
+diff --git a/drivers/misc/slp_global_lock.h b/drivers/misc/slp_global_lock.h
+new file mode 100644
+index 0000000..db4d585
+--- /dev/null
++++ b/drivers/misc/slp_global_lock.h
+@@ -0,0 +1,49 @@
++/*
++ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __SLP_GLOBAL_LOCK_H__
++#define __SLP_GLOBAL_LOCK_H__
++
++#include <linux/ioctl.h>
++
++#define SGL_IOC_BASE  0x32
++#define SGL_MAJOR     224
++
++struct sgl_attribute {
++      unsigned int key;
++      unsigned int timeout_ms;
++};
++
++struct sgl_user_data {
++      unsigned int key;
++      unsigned int data1;
++      unsigned int data2;
++      unsigned int locked;
++};
++
++typedef enum {
++      _SGL_INIT_LOCK = 1,
++      _SGL_DESTROY_LOCK,
++      _SGL_LOCK_LOCK,
++      _SGL_UNLOCK_LOCK,
++      _SGL_SET_DATA,
++      _SGL_GET_DATA,
++      _SGL_DUMP_LOCKS,
++} _sgl_ioctls;
++
++#define SGL_IOC_INIT_LOCK                     _IOW(SGL_IOC_BASE, _SGL_INIT_LOCK, struct sgl_attribute *)
++#define SGL_IOC_DESTROY_LOCK          _IOW(SGL_IOC_BASE, _SGL_DESTROY_LOCK, unsigned int)
++#define SGL_IOC_LOCK_LOCK                     _IOW(SGL_IOC_BASE, _SGL_LOCK_LOCK, unsigned int)
++#define SGL_IOC_UNLOCK_LOCK                   _IOW(SGL_IOC_BASE, _SGL_UNLOCK_LOCK, unsigned int)
++#define SGL_IOC_SET_DATA                      _IOW(SGL_IOC_BASE, _SGL_SET_DATA, struct sgl_user_data *)
++#define SGL_IOC_GET_DATA                      _IOW(SGL_IOC_BASE, _SGL_GET_DATA, struct sgl_user_data *)
++#define SGL_IOC_DUMP_LOCKS                    _IOW(SGL_IOC_BASE, _SGL_DUMP_LOCKS, void *)
++
++#endif /* __SLP_GLOBAL_LOCK_H__ */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0088-drm-exynos-add-EXYNOS_DISPLAY_TYPE_LCD-for-TIZEN.patch b/patches.tizen/0088-drm-exynos-add-EXYNOS_DISPLAY_TYPE_LCD-for-TIZEN.patch
new file mode 100644 (file)
index 0000000..1e1e609
--- /dev/null
@@ -0,0 +1,28 @@
+From c50a96316b3edc34b4a1917bdaa274a10cc23cdb Mon Sep 17 00:00:00 2001
+From: Joonyoung Shim <jy0922.shim@samsung.com>
+Date: Tue, 29 Jan 2013 17:00:54 +0900
+Subject: [PATCH 0088/1302] drm/exynos: add EXYNOS_DISPLAY_TYPE_LCD for TIZEN
+
+Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_connector.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c
+index 8bcc13a..e5c1a01 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_connector.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c
+@@ -342,6 +342,9 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
+               type = DRM_MODE_CONNECTOR_VIRTUAL;
+               connector->polled = DRM_CONNECTOR_POLL_HPD;
+               break;
++      case EXYNOS_DISPLAY_TYPE_LCD:
++              type = DRM_MODE_CONNECTOR_LVDS;
++              break;
+       default:
+               type = DRM_MODE_CONNECTOR_Unknown;
+               break;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0089-ARM-dts-exynos4210-trats-enable-invert-feature-of-to.patch b/patches.tizen/0089-ARM-dts-exynos4210-trats-enable-invert-feature-of-to.patch
new file mode 100644 (file)
index 0000000..a6aa6f6
--- /dev/null
@@ -0,0 +1,28 @@
+From 663b2c110e7f0c7f8cba19d23e39b610f4528689 Mon Sep 17 00:00:00 2001
+From: Joonyoung Shim <jy0922.shim@samsung.com>
+Date: Tue, 29 Jan 2013 17:02:04 +0900
+Subject: [PATCH 0089/1302] ARM: dts: exynos4210-trats: enable invert feature
+ of touchscreen
+
+Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index e316890..444474b 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -154,6 +154,8 @@
+                       interrupts = <4 2>;
+                       x-size = <720>;
+                       y-size = <1280>;
++                      x-invert;
++                      y-invert;
+                       avdd-supply = <&tsp_reg>;
+                       vdd-supply = <&tsp_reg>;
+               };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0090-clk-samsung-exynos4-List-available-mux-clocks.patch b/patches.tizen/0090-clk-samsung-exynos4-List-available-mux-clocks.patch
new file mode 100644 (file)
index 0000000..1b926e1
--- /dev/null
@@ -0,0 +1,42 @@
+From 79bcf0dae5ff46365a8ddd6e20665ac783319b4c Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 14 Feb 2013 11:01:18 +0100
+Subject: [PATCH 0090/1302] clk: samsung: exynos4: List available mux clocks
+
+This patch adds missing mux clocks to Device Tree binding documentation
+of Exynos4 clock driver.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/devicetree/bindings/clock/exynos4-clock.txt | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/clock/exynos4-clock.txt b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
+index ea5e26f..da82f71 100644
+--- a/Documentation/devicetree/bindings/clock/exynos4-clock.txt
++++ b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
+@@ -267,6 +267,20 @@ Exynos4 SoC and this is specified where applicable.
+   div_aclk400_mcuisp  455     Exynos4x12
++                      [Mux Clocks]
++
++      Clock           ID      SoC (if specific)
++      -----------------------------------------------
++
++      mout_fimc0      384
++      mout_fimc1      385
++      mout_fimc2      386
++      mout_fimc3      387
++      mout_cam0       388
++      mout_cam1       389
++      mout_csis0      390
++      mout_csis1      391
++
+ Example 1: An example of a clock controller node is listed below.
+       clock: clock-controller@0x10030000 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0091-ARM-dts-exynos4x12-Disable-handling-of-ISP-power-dom.patch b/patches.tizen/0091-ARM-dts-exynos4x12-Disable-handling-of-ISP-power-dom.patch
new file mode 100644 (file)
index 0000000..38c94ab
--- /dev/null
@@ -0,0 +1,36 @@
+From d8cb4d3221fa83513d86b4fee362f50bc71c5e0c Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 21 Feb 2013 12:34:22 +0100
+Subject: [PATCH 0091/1302] ARM: dts: exynos4x12: Disable handling of ISP power
+ domain
+
+ISP power domain needs special handling and in current state disabling
+it crashes the system. This patch disables ISP power domain handling
+until it gets fixed.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12.dtsi | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index 636c2f4..8d0e3d83 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -31,7 +31,11 @@
+       };
+       pd_isp: isp-power-domain@10023CA0 {
+-              compatible = "samsung,exynos4210-pd";
++              /*
++               * FIXME: ISP power domain needs special handling
++               * (Implement proper ISP power domain on/off sequence)
++               */
++              /* compatible = "samsung,exynos4210-pd"; */
+               reg = <0x10023CA0 0x20>;
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0092-ARM-dts-exynos4412-redwood-Enable-MFC-and-CMA.patch b/patches.tizen/0092-ARM-dts-exynos4412-redwood-Enable-MFC-and-CMA.patch
new file mode 100644 (file)
index 0000000..a8c1d58
--- /dev/null
@@ -0,0 +1,66 @@
+From 83c699a919e970620472a4479002deebc744f56b Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Tue, 20 Aug 2013 15:15:13 +0200
+Subject: [PATCH 0092/1302] ARM: dts: exynos4412-redwood: Enable MFC and CMA
+
+This patch adds device tree nodes for MFC and its CMA memory regions
+to enable MFC/DRM/MALI support on Redwood board.
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-redwood.dts | 33 ++++++++++++++++++++++++++++++++
+ 1 file changed, 33 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-redwood.dts b/arch/arm/boot/dts/exynos4412-redwood.dts
+index 78e763a..ac6ef14 100644
+--- a/arch/arm/boot/dts/exynos4412-redwood.dts
++++ b/arch/arm/boot/dts/exynos4412-redwood.dts
+@@ -24,6 +24,27 @@
+                       0x50000000 0x10000000
+                       0x60000000 0x10000000
+                       0x70000000 0x10000000>;
++
++              reserved-memory {
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      contig_mem: region@71000000 {
++                              compatible = "linux,contiguous-memory-region";
++                              reg = <0x71000000 0x0c000000>;
++                              linux,default-contiguous-region;
++                      };
++
++                      mfc_l_mem: mfc_l_region@43000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x43000000 0x1000000>;
++                      };
++
++                      mfc_r_mem: mfc_r_region@51000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x51000000 0x1000000>;
++                      };
++              };
+       };
+       chosen {
+@@ -492,4 +513,16 @@
+               vusb_d-supply = <&ldo15_reg>;
+               vusb_a-supply = <&ldo12_reg>;
+       };
++
++      mfc: codec@13400000 {
++              status = "okay";
++
++              memport@0 {
++                      memory-region = <&mfc_l_mem>;
++              };
++
++              memport@1 {
++                      memory-region = <&mfc_r_mem>;
++              };
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0093-ARM-EXYNOS-Add-sec_debug-module-stub.patch b/patches.tizen/0093-ARM-EXYNOS-Add-sec_debug-module-stub.patch
new file mode 100644 (file)
index 0000000..4cc7866
--- /dev/null
@@ -0,0 +1,87 @@
+From 3ce7d0062c9797b19935b780390036f995bc876a Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 21 Feb 2013 16:25:00 +0100
+Subject: [PATCH 0093/1302] ARM: EXYNOS: Add sec_debug module stub
+
+This patch adds simple stub for sec_debug module to allow unmodified
+Tizen images to be booted.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/mach-exynos/Kconfig     |  5 +++++
+ arch/arm/mach-exynos/Makefile    |  1 +
+ arch/arm/mach-exynos/sec_debug.c | 33 +++++++++++++++++++++++++++++++++
+ 3 files changed, 39 insertions(+)
+ create mode 100644 arch/arm/mach-exynos/sec_debug.c
+
+diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
+index 3ea8c7d..549cb32 100644
+--- a/arch/arm/mach-exynos/Kconfig
++++ b/arch/arm/mach-exynos/Kconfig
+@@ -183,6 +183,11 @@ config EXYNOS_SETUP_SPI
+       help
+         Common setup code for SPI GPIO configurations.
++config SEC_DEBUG
++      bool "Enable sec_debug stub"
++      help
++        Stub module for sec_debug functionality required in Tizen.
++
+ # machine support
+ if ARCH_EXYNOS4
+diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
+index b09b027..9e63a19 100644
+--- a/arch/arm/mach-exynos/Makefile
++++ b/arch/arm/mach-exynos/Makefile
+@@ -26,6 +26,7 @@ obj-$(CONFIG_HOTPLUG_CPU)    += hotplug.o
+ obj-$(CONFIG_ARCH_EXYNOS)     += exynos-smc.o
+ obj-$(CONFIG_ARCH_EXYNOS)     += firmware.o
++obj-$(CONFIG_SEC_DEBUG)               += sec_debug.o
+ plus_sec := $(call as-instr,.arch_extension sec,+sec)
+ AFLAGS_exynos-smc.o           :=-Wa,-march=armv7-a$(plus_sec)
+diff --git a/arch/arm/mach-exynos/sec_debug.c b/arch/arm/mach-exynos/sec_debug.c
+new file mode 100644
+index 0000000..3973858
+--- /dev/null
++++ b/arch/arm/mach-exynos/sec_debug.c
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
++ *            http://www.samsung.com
++ *
++ * sec_debug module stub for Tizen compatibility
++ *
++ * 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/kernel.h>
++#include <linux/module.h>
++
++union sec_debug_level_t {
++      struct {
++              u16 kernel_fault;
++              u16 user_fault;
++      } en;
++      u32 uint_val;
++};
++
++/* enable/disable sec_debug feature
++ * level = 0 when enable = 0 && enable_user = 0
++ * level = 1 when enable = 1 && enable_user = 0
++ * level = 0x10001 when enable = 1 && enable_user = 1
++ * The other cases are not considered
++ */
++union sec_debug_level_t sec_debug_level = { .en.kernel_fault = 1, };
++
++module_param_named(enable, sec_debug_level.en.kernel_fault, ushort, 0644);
++module_param_named(enable_user, sec_debug_level.en.user_fault, ushort, 0644);
++module_param_named(level, sec_debug_level.uint_val, uint, 0644);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0094-cpufreq-Define-cpufreq-as-a-platform-device.patch b/patches.tizen/0094-cpufreq-Define-cpufreq-as-a-platform-device.patch
new file mode 100644 (file)
index 0000000..b7ac6c5
--- /dev/null
@@ -0,0 +1,92 @@
+From 3f3a5827ceeb9c5cbdb32825c802d8a13952f530 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Thu, 14 Feb 2013 19:41:39 +0100
+Subject: [PATCH 0094/1302] cpufreq: Define cpufreq as a platform device
+
+Now the cpufreq has been defined as a platform device. It will facilitate
+binding to parameters passed via device tree.
+
+We shall tweak the cpufreq configuration via board dependent dts files,
+not per platform specific files.
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi   |  4 ++++
+ drivers/cpufreq/exynos-cpufreq.c | 35 ++++++++++++++++++++++++++++++++++-
+ 2 files changed, 38 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index 3876b12..5a6bf05 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -623,4 +623,8 @@
+               samsung,power-domain = <&pd_lcd0>;
+               status = "ok";
+       };
++
++      cpufreq {
++              compatible = "samsung,exynos-cpufreq";
++      };
+ };
+diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c
+index 475b4f6..976598f 100644
+--- a/drivers/cpufreq/exynos-cpufreq.c
++++ b/drivers/cpufreq/exynos-cpufreq.c
+@@ -17,6 +17,9 @@
+ #include <linux/regulator/consumer.h>
+ #include <linux/cpufreq.h>
+ #include <linux/suspend.h>
++#include <linux/export.h>
++#include <linux/of.h>
++#include <linux/of_platform.h>
+ #include <plat/cpu.h>
+@@ -279,7 +282,16 @@ static struct cpufreq_driver exynos_driver = {
+ #endif
+ };
+-static int __init exynos_cpufreq_init(void)
++/* Device Tree Support for CPU freq */
++
++#ifdef CONFIG_OF
++static struct of_device_id exynos_cpufreq_of_match[] __initconst = {
++      { .compatible = "samsung,exynos-cpufreq", },
++      { },
++};
++#endif
++
++static int __init exynos_cpufreq_probe(struct platform_device *pdev)
+ {
+       int ret = -EINVAL;
+@@ -329,4 +341,25 @@ err_vdd_arm:
+       pr_debug("%s: failed initialization\n", __func__);
+       return -EINVAL;
+ }
++
++static struct platform_driver exynos_cpufreq_driver = {
++      .probe          = exynos_cpufreq_probe,
++      .driver         = {
++              .owner          = THIS_MODULE,
++              .name           = "exynos-cpufreq",
++              .of_match_table = of_match_ptr(exynos_cpufreq_of_match),
++      }
++};
++
++static int __init exynos_cpufreq_init(void)
++{
++      int ret;
++      ret = platform_driver_register(&exynos_cpufreq_driver);
++      if (ret) {
++              pr_err("%s: Failed to register CPUFREQ driver\n", __func__);
++      }
++
++      return ret;
++}
++
+ late_initcall(exynos_cpufreq_init);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0095-cpufreq-exynos-Save-struct-device-in-driver-data.patch b/patches.tizen/0095-cpufreq-exynos-Save-struct-device-in-driver-data.patch
new file mode 100644 (file)
index 0000000..64edb5b
--- /dev/null
@@ -0,0 +1,43 @@
+From ccf862f26867abbefe2e6e8e5a8d8ab9a4492f13 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 1 Mar 2013 18:07:56 +0100
+Subject: [PATCH 0095/1302] cpufreq: exynos: Save struct device in driver data
+
+This patch adds dev field in exynos cpufreq driver data to allow Device
+Tree based clock and regulator lookups.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/exynos-cpufreq.c | 2 ++
+ drivers/cpufreq/exynos-cpufreq.h | 1 +
+ 2 files changed, 3 insertions(+)
+
+diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c
+index 976598f..4450711 100644
+--- a/drivers/cpufreq/exynos-cpufreq.c
++++ b/drivers/cpufreq/exynos-cpufreq.c
+@@ -299,6 +299,8 @@ static int __init exynos_cpufreq_probe(struct platform_device *pdev)
+       if (!exynos_info)
+               return -ENOMEM;
++      exynos_info->dev = &pdev->dev;
++
+       if (soc_is_exynos4210())
+               ret = exynos4210_cpufreq_init(exynos_info);
+       else if (soc_is_exynos4212() || soc_is_exynos4412())
+diff --git a/drivers/cpufreq/exynos-cpufreq.h b/drivers/cpufreq/exynos-cpufreq.h
+index 92b852e..1d45a61 100644
+--- a/drivers/cpufreq/exynos-cpufreq.h
++++ b/drivers/cpufreq/exynos-cpufreq.h
+@@ -34,6 +34,7 @@ struct apll_freq {
+ };
+ struct exynos_dvfs_info {
++      struct device *dev;
+       unsigned long   mpll_freq_khz;
+       unsigned int    pll_safe_idx;
+       struct clk      *cpu_clk;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0096-cpufreq-exynos-Use-device-based-lookup-for-vdd_arm-r.patch b/patches.tizen/0096-cpufreq-exynos-Use-device-based-lookup-for-vdd_arm-r.patch
new file mode 100644 (file)
index 0000000..6ffeaef
--- /dev/null
@@ -0,0 +1,31 @@
+From 7cd2e24890b00774e82569d8150aaa6ed870e90d Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 1 Mar 2013 18:09:39 +0100
+Subject: [PATCH 0096/1302] cpufreq: exynos: Use device-based lookup for
+ vdd_arm regulator
+
+This patch adds device-based lookup of vdd_arm regulator to allow lookup
+using Device Tree.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/exynos-cpufreq.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c
+index 4450711..ee4b947 100644
+--- a/drivers/cpufreq/exynos-cpufreq.c
++++ b/drivers/cpufreq/exynos-cpufreq.c
+@@ -318,7 +318,7 @@ static int __init exynos_cpufreq_probe(struct platform_device *pdev)
+               goto err_vdd_arm;
+       }
+-      arm_regulator = regulator_get(NULL, "vdd_arm");
++      arm_regulator = regulator_get(exynos_info->dev, "vdd_arm");
+       if (IS_ERR(arm_regulator)) {
+               pr_err("%s: failed to get resource vdd_arm\n", __func__);
+               goto err_vdd_arm;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0097-cpufreq-Adjust-exynos4x12-cpufreq-to-work-with-v3.8-.patch b/patches.tizen/0097-cpufreq-Adjust-exynos4x12-cpufreq-to-work-with-v3.8-.patch
new file mode 100644 (file)
index 0000000..d7b6e55
--- /dev/null
@@ -0,0 +1,99 @@
+From 5f65d507d1813b217fe8e693c5c0646b6e20fb0b Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Wed, 13 Feb 2013 17:50:12 +0100
+Subject: [PATCH 0097/1302] cpufreq: Adjust exynos4x12 cpufreq to work with
+ v3.8-mobile (with common clocks)
+
+It was needed to change the clock names to reflect clock change on the
+Exynos4412 device (especially arm_clk, mout_core") and add device-based
+lookup to allow getting clocks from device tree.
+
+Tested-on: Exynos4412 Proxima PQ (rev.1.1)
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/exynos4x12-cpufreq.c | 31 +++++++++++++++----------------
+ 1 file changed, 15 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/cpufreq/exynos4x12-cpufreq.c b/drivers/cpufreq/exynos4x12-cpufreq.c
+index 08b7477..972e949 100644
+--- a/drivers/cpufreq/exynos4x12-cpufreq.c
++++ b/drivers/cpufreq/exynos4x12-cpufreq.c
+@@ -22,8 +22,8 @@
+ #include "exynos-cpufreq.h"
+ static struct clk *cpu_clk;
+-static struct clk *moutcore;
+-static struct clk *mout_mpll;
++static struct clk *mout_core;
++static struct clk *sclk_mpll;
+ static struct clk *mout_apll;
+ static unsigned int exynos4x12_volt_table[] = {
+@@ -131,7 +131,7 @@ static void exynos4x12_set_apll(unsigned int index)
+       unsigned int tmp, pdiv;
+       /* 1. MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */
+-      clk_set_parent(moutcore, mout_mpll);
++      clk_set_parent(mout_core, sclk_mpll);
+       do {
+               cpu_relax();
+@@ -158,7 +158,7 @@ static void exynos4x12_set_apll(unsigned int index)
+       } while (!(tmp & (0x1 << EXYNOS4_APLLCON0_LOCKED_SHIFT)));
+       /* 5. MUX_CORE_SEL = APLL */
+-      clk_set_parent(moutcore, mout_apll);
++      clk_set_parent(mout_core, mout_apll);
+       do {
+               cpu_relax();
+@@ -219,22 +219,21 @@ static void exynos4x12_set_frequency(unsigned int old_index,
+ int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
+ {
+       unsigned long rate;
+-
+-      cpu_clk = clk_get(NULL, "armclk");
++      cpu_clk = clk_get(info->dev, "arm_clk");
+       if (IS_ERR(cpu_clk))
+               return PTR_ERR(cpu_clk);
+-      moutcore = clk_get(NULL, "moutcore");
+-      if (IS_ERR(moutcore))
++      mout_core = clk_get(info->dev, "mout_core");
++      if (IS_ERR(mout_core))
+               goto err_moutcore;
+-      mout_mpll = clk_get(NULL, "mout_mpll");
+-      if (IS_ERR(mout_mpll))
+-              goto err_mout_mpll;
++      sclk_mpll = clk_get(info->dev, "sclk_mpll_user_c");
++      if (IS_ERR(sclk_mpll))
++              goto err_sclk_mpll;
+-      rate = clk_get_rate(mout_mpll) / 1000;
++      rate = clk_get_rate(sclk_mpll) / 1000;
+-      mout_apll = clk_get(NULL, "mout_apll");
++      mout_apll = clk_get(info->dev, "mout_apll");
+       if (IS_ERR(mout_apll))
+               goto err_mout_apll;
+@@ -255,9 +254,9 @@ int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
+       return 0;
+ err_mout_apll:
+-      clk_put(mout_mpll);
+-err_mout_mpll:
+-      clk_put(moutcore);
++      clk_put(sclk_mpll);
++err_sclk_mpll:
++      clk_put(mout_core);
+ err_moutcore:
+       clk_put(cpu_clk);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0098-cpufreq-exynos4x12-Parse-frequency-table-from-device.patch b/patches.tizen/0098-cpufreq-exynos4x12-Parse-frequency-table-from-device.patch
new file mode 100644 (file)
index 0000000..d547686
--- /dev/null
@@ -0,0 +1,131 @@
+From e0403302ade4a5e920ce44d86e22d9281cca43da Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Thu, 14 Feb 2013 19:43:20 +0100
+Subject: [PATCH 0098/1302] cpufreq: exynos4x12: Parse frequency table from
+ device tree
+
+Proxima PQ (rev1.1) can run stable at frequencies not higher than 1100 MHz.
+In the current code (exynos4x12-cpufreq) frequency up to 1400 MHz
+can be set (which shall work for REDWOOD).
+
+For the Proxima PQ frequency table has been modified and passed via device
+tree.
+
+Tested-on: Proxima PQ rev1.1
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/exynos-cpufreq.c     | 66 ++++++++++++++++++++++++++++++++++++
+ drivers/cpufreq/exynos-cpufreq.h     |  2 ++
+ drivers/cpufreq/exynos4x12-cpufreq.c |  6 +++-
+ 3 files changed, 73 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c
+index ee4b947..3197d88 100644
+--- a/drivers/cpufreq/exynos-cpufreq.c
++++ b/drivers/cpufreq/exynos-cpufreq.c
+@@ -284,6 +284,72 @@ static struct cpufreq_driver exynos_driver = {
+ /* Device Tree Support for CPU freq */
++struct cpufreq_frequency_table *exynos_of_parse_freq_table(
++              struct exynos_dvfs_info *info, const char *property_name)
++{
++      struct device_node *node = info->dev->of_node;
++      struct cpufreq_frequency_table *ft, *ret = NULL;
++      struct property *pp;
++      int len, num, i = 0;
++      u32 *of_f_tab;
++
++      if (!node)
++              return NULL;
++
++      pp = of_find_property(node, property_name, &len);
++      if (!pp) {
++              pr_debug("%s: Property: %s not found\n", __func__,
++                       property_name);
++              goto err;
++      }
++
++      if (len == 0) {
++              pr_debug("%s: Length wrong value!\n", __func__);
++              goto err;
++      }
++
++      of_f_tab = kzalloc(len, GFP_KERNEL);
++      if (!of_f_tab) {
++              pr_err("%s: Allocation failed\n", __func__);
++              goto err;
++      }
++
++      num = len / sizeof(u32);
++
++      if (of_property_read_u32_array(node, pp->name, of_f_tab, num)) {
++              pr_err("%s: Property: %s cannot be read!\n", __func__,
++                     pp->name);
++              goto err_of_f_tab;
++      }
++
++      /* Here + 2 is required for CPUFREQ_ENTRY_INVALID and
++         CPUFREQ_TABLE_END  */
++      ft = kzalloc(sizeof(struct cpufreq_frequency_table) * (num + 2),
++                   GFP_KERNEL);
++      if (!ft) {
++              pr_err("%s: Allocation failed\n", __func__);
++              goto err_of_f_tab;
++      }
++
++      ft[0].index = L0;
++      ft[0].frequency = CPUFREQ_ENTRY_INVALID;
++
++      for (i = 1; i <= num; i++) {
++              ft[i].index = i;
++              ft[i].frequency = of_f_tab[i-1];
++      }
++
++      ft[i].index = 0;
++      ft[i].frequency = CPUFREQ_TABLE_END;
++
++      ret = ft;
++
++ err_of_f_tab:
++      kfree(of_f_tab);
++ err:
++      return ret;
++}
++
+ #ifdef CONFIG_OF
+ static struct of_device_id exynos_cpufreq_of_match[] __initconst = {
+       { .compatible = "samsung,exynos-cpufreq", },
+diff --git a/drivers/cpufreq/exynos-cpufreq.h b/drivers/cpufreq/exynos-cpufreq.h
+index 1d45a61..4e08ba7 100644
+--- a/drivers/cpufreq/exynos-cpufreq.h
++++ b/drivers/cpufreq/exynos-cpufreq.h
+@@ -47,3 +47,5 @@ struct exynos_dvfs_info {
+ extern int exynos4210_cpufreq_init(struct exynos_dvfs_info *);
+ extern int exynos4x12_cpufreq_init(struct exynos_dvfs_info *);
+ extern int exynos5250_cpufreq_init(struct exynos_dvfs_info *);
++extern struct cpufreq_frequency_table *exynos_of_parse_freq_table(
++              struct exynos_dvfs_info *info, const char *property_name);
+diff --git a/drivers/cpufreq/exynos4x12-cpufreq.c b/drivers/cpufreq/exynos4x12-cpufreq.c
+index 972e949..70999b2 100644
+--- a/drivers/cpufreq/exynos4x12-cpufreq.c
++++ b/drivers/cpufreq/exynos4x12-cpufreq.c
+@@ -247,7 +247,11 @@ int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
+       info->pll_safe_idx = L7;
+       info->cpu_clk = cpu_clk;
+       info->volt_table = exynos4x12_volt_table;
+-      info->freq_table = exynos4x12_freq_table;
++
++      info->freq_table = exynos_of_parse_freq_table(info, "freq_table");
++      if (!info->freq_table)
++              info->freq_table = exynos4x12_freq_table;
++
+       info->set_freq = exynos4x12_set_frequency;
+       info->need_apll_change = exynos4x12_pms_change;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0099-ARM-dts-exynos4x12-Add-cpufreq-node.patch b/patches.tizen/0099-ARM-dts-exynos4x12-Add-cpufreq-node.patch
new file mode 100644 (file)
index 0000000..092395d
--- /dev/null
@@ -0,0 +1,34 @@
+From 57f04eaa7a1fe0a1b84815bc1b4d46f9a9019443 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Tue, 19 Mar 2013 15:24:14 +0100
+Subject: [PATCH 0099/1302] ARM: dts: exynos4x12: Add cpufreq node
+
+This patch adds cpufreq node with SoC specific paramaters for
+cpufreq-exynos driver.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12.dtsi | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index 8d0e3d83..c0edb05 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -261,4 +261,12 @@
+                       };
+               };
+       };
++
++      cpufreq {
++              compatible = "samsung,exynos-cpufreq";
++              clocks = <&clock 12>, <&clock 19>, <&clock 9>, <&clock 20>;
++              clock-names = "arm_clk", "mout_core", "mout_mpll_user_c",
++                                                              "mout_apll";
++              status = "disabled";
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0100-ARM-dts-exynos4x12-slp_pq-Add-cpufreq-node.patch b/patches.tizen/0100-ARM-dts-exynos4x12-slp_pq-Add-cpufreq-node.patch
new file mode 100644 (file)
index 0000000..8f5f501
--- /dev/null
@@ -0,0 +1,35 @@
+From 6a203ad7678af13bae3191b96e533be2e53c191a Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Tue, 19 Mar 2013 15:25:52 +0100
+Subject: [PATCH 0100/1302] ARM: dts: exynos4x12-slp_pq: Add cpufreq node
+
+This patch adds cpufreq node with board-specific parameters to enable
+CPU frequency scaling on SLP PQ board.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 966e071..69a6184 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -704,4 +704,13 @@
+                       memory-region = <&mfc_r_mem>;
+               };
+       };
++
++      cpufreq {
++              /* 4294967295 is a ~0 representation with u32 */
++              freq_table = <4294967295 4294967295 4294967295 1100000 1000000
++                           900000 800000 700000 600000 500000 400000 300000
++                           200000>;
++              vdd_arm-supply = <&buck2_reg>;
++              status = "okay";
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0101-clock-Support-for-A-M-PLL-s-35xx-set_rate-and-round_.patch b/patches.tizen/0101-clock-Support-for-A-M-PLL-s-35xx-set_rate-and-round_.patch
new file mode 100644 (file)
index 0000000..966e108
--- /dev/null
@@ -0,0 +1,281 @@
+From e5db4cbd85631ee15124600aafbf64f02f0a412b Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Mon, 25 Feb 2013 16:40:46 +0100
+Subject: [PATCH 0101/1302] clock: Support for [A|M]PLL's (35xx) set_rate and
+ round_rate functions
+
+Support for [A|M]PLL's [set|round]_rate functions has been added.
+Now simple call to clk_set_rate is responsible for setting proper
+frequency.
+
+This commit allows for further refactoring of exynos4x12-cpufreq.c code.
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+
+clk: Fix bug on setting xpll's pms value in clk-pll.c
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/samsung/clk-exynos4.c |  25 +++++++-
+ drivers/clk/samsung/clk-pll.c     | 120 +++++++++++++++++++++++++++++++++++---
+ drivers/clk/samsung/clk-pll.h     |  13 ++++-
+ 3 files changed, 146 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
+index 3c1f888..1fc01de 100644
+--- a/drivers/clk/samsung/clk-exynos4.c
++++ b/drivers/clk/samsung/clk-exynos4.c
+@@ -97,12 +97,14 @@
+ #define GATE_IP_PERIL         0xc950
+ #define E4210_GATE_IP_PERIR   0xc960
+ #define GATE_BLOCK            0xc970
++#define E4X12_MPLL_LOCK               0x10008
+ #define E4X12_MPLL_CON0               0x10108
+ #define SRC_DMC                       0x10200
+ #define SRC_MASK_DMC          0x10300
+ #define DIV_DMC0              0x10500
+ #define DIV_DMC1              0x10504
+ #define GATE_IP_DMC           0x10900
++#define APLL_LOCK             0x14000
+ #define APLL_CON0             0x14100
+ #define E4210_MPLL_CON0               0x14108
+ #define SRC_CPU                       0x14200
+@@ -983,6 +985,25 @@ static __initdata struct of_device_id ext_clk_match[] = {
+       {},
+ };
++/* PLLs PMS values */
++struct pll_pms pll35xx_exynos4412_pms[] = {
++      {.p = 4, .m = 250, .s = 0},
++      {.p = 3, .m = 175, .s = 0},
++      {.p = 6, .m = 325, .s = 0},
++      {.p = 4, .m = 200, .s = 0},
++      {.p = 6, .m = 275, .s = 0},
++      {.p = 3, .m = 125, .s = 0},
++      {.p = 4, .m = 150, .s = 0},
++      {.p = 3, .m = 100, .s = 0},
++      {.p = 3, .m = 175, .s = 1},
++      {.p = 4, .m = 200, .s = 1},
++      {.p = 3, .m = 125, .s = 1},
++      {.p = 3, .m = 100, .s = 1},
++      {.p = 4, .m = 200, .s = 2},
++      {.p = 3, .m = 100, .s = 2},
++      {.f_out = F_OUT_INVAL},
++};
++
+ /* register exynos4 clocks */
+ void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc exynos4_soc, void __iomem *reg_base, unsigned long xom)
+ {
+@@ -1021,9 +1042,9 @@ void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc exynos4_so
+                                       reg_base + VPLL_CON0, pll_4650c);
+       } else {
+               apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll",
+-                                      reg_base + APLL_CON0);
++                      reg_base + APLL_LOCK, pll35xx_exynos4412_pms);
+               mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll",
+-                                      reg_base + E4X12_MPLL_CON0);
++                      reg_base + E4X12_MPLL_LOCK, pll35xx_exynos4412_pms);
+               epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll",
+                                       reg_base + EPLL_CON0);
+               vpll = samsung_clk_register_pll36xx("fout_vpll", "fin_pll",
+diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
+index 362f12d..15b4882 100644
+--- a/drivers/clk/samsung/clk-pll.c
++++ b/drivers/clk/samsung/clk-pll.c
+@@ -24,11 +24,38 @@
+ #define PLL35XX_PDIV_SHIFT      (8)
+ #define PLL35XX_SDIV_SHIFT      (0)
++#define PLL35XX_PLL_LOCK        0x0
++#define PLL35XX_PLL_LOCK_CONST  270
++#define PLL35XX_PLL_CON0        0x100
++#define PLL35XX_LOCKED_SHIFT    29
++#define PLL35XX_LOCKED          (1 << PLL35XX_LOCKED_SHIFT)
++
+ struct samsung_clk_pll35xx {
+       struct clk_hw           hw;
+-      const void __iomem      *con_reg;
++      const void __iomem      *base_reg;
++      struct pll_pms          *pms;
+ };
++static int get_index(unsigned long rate, struct pll_pms *pms)
++{
++      int i;
++
++      for (i = 0; pms[i].f_out != F_OUT_INVAL; i++)
++              if (pms[i].f_out == rate)
++                      return i;
++
++      return -EINVAL;
++}
++
++static inline unsigned long samsung_pll35xx_calc_f_out(u64 f_in,
++                                                          int p, int m, int s)
++{
++      f_in *= m;
++      do_div(f_in, (p << s));
++
++      return (unsigned long) f_in;
++}
++
+ #define to_clk_pll35xx(_hw) container_of(_hw, struct samsung_clk_pll35xx, hw)
+ static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
+@@ -36,29 +63,95 @@ static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
+ {
+       struct samsung_clk_pll35xx *pll = to_clk_pll35xx(hw);
+       u32 mdiv, pdiv, sdiv, pll_con;
+-      u64 fvco = parent_rate;
+-      pll_con = __raw_readl(pll->con_reg);
++      pll_con = __raw_readl(pll->base_reg + PLL35XX_PLL_CON0);
+       mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
+       pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
+       sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK;
+-      fvco *= mdiv;
+-      do_div(fvco, (pdiv << sdiv));
++      return samsung_pll35xx_calc_f_out(parent_rate, pdiv, mdiv, sdiv);
++}
+-      return (unsigned long)fvco;
++static long samsung_pll35xx_round_rate(struct clk_hw *hw,
++                              unsigned long drate, unsigned long *prate)
++{
++      struct samsung_clk_pll35xx *pll = to_clk_pll35xx(hw);
++      struct pll_pms *pms = pll->pms;
++      int i;
++
++      if (!pms) {
++              pr_err("%s: no pms table passed", __func__);
++              return -ENOTSUPP;
++      }
++
++      for (i = 0; pms[i].f_out != F_OUT_INVAL; i++)
++              if (drate >= pms[i].f_out)
++                      return pms[i].f_out;
++
++      return -EINVAL;
++}
++
++static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
++                              unsigned long prate)
++{
++      struct samsung_clk_pll35xx *pll = to_clk_pll35xx(hw);
++      u32 p = 0, m = 0, s = 0, tmp = 0;
++      struct pll_pms *pms = pll->pms;
++      int index;
++
++      if (!pms) {
++              pr_err("%s: no pms table passed", __func__);
++              return -ENOTSUPP;
++      }
++
++      index = get_index(drate, pll->pms);
++
++      /* Define PLL lock time */
++      p = pms[index].p;
++      __raw_writel((p * PLL35XX_PLL_LOCK_CONST),
++                   (u32*) (pll->base_reg + PLL35XX_PLL_LOCK));
++
++      /* Change PLL PMS */
++      m = pms[index].m;
++      s = pms[index].s;
++
++      tmp = __raw_readl(pll->base_reg + PLL35XX_PLL_CON0);
++      tmp &= ~((PLL35XX_PDIV_MASK << PLL35XX_PDIV_SHIFT) |
++              (PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT) |
++              (PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT));
++      tmp |= (p << PLL35XX_PDIV_SHIFT) | (m << PLL35XX_MDIV_SHIFT) |
++              (s << PLL35XX_SDIV_SHIFT);
++      __raw_writel(tmp, (u32*) (pll->base_reg  + PLL35XX_PLL_CON0));
++
++      /* Wait for locking */
++      do {
++              cpu_relax();
++              tmp = __raw_readl(pll->base_reg + PLL35XX_PLL_CON0);
++      } while (!(tmp & PLL35XX_LOCKED));
++
++      return 0;
+ }
+ static const struct clk_ops samsung_pll35xx_clk_ops = {
+       .recalc_rate = samsung_pll35xx_recalc_rate,
++      .round_rate = samsung_pll35xx_round_rate,
++      .set_rate = samsung_pll35xx_set_rate,
+ };
+-struct clk * __init samsung_clk_register_pll35xx(const char *name,
+-                      const char *pname, const void __iomem *con_reg)
++struct clk * __init
++samsung_clk_register_pll35xx(const char *name,
++                           const char *pname, const void __iomem *base_reg,
++                           struct pll_pms *pms)
+ {
+       struct samsung_clk_pll35xx *pll;
+       struct clk *clk;
+       struct clk_init_data init;
++      int i;
++
++      if (!pms) {
++              pr_err("%s:  %s\n", __func__, name);
++              return NULL;
++      }
+       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+       if (!pll) {
+@@ -73,7 +166,8 @@ struct clk * __init samsung_clk_register_pll35xx(const char *name,
+       init.num_parents = 1;
+       pll->hw.init = &init;
+-      pll->con_reg = con_reg;
++      pll->base_reg = base_reg;
++      pll->pms = pms;
+       clk = clk_register(NULL, &pll->hw);
+       if (IS_ERR(clk)) {
+@@ -85,6 +179,14 @@ struct clk * __init samsung_clk_register_pll35xx(const char *name,
+       if (clk_register_clkdev(clk, name, NULL))
+               pr_err("%s: failed to register lookup for %s", __func__, name);
++      /* Fill in received frequency table */
++      for (i = 0; pms[i].f_out != F_OUT_INVAL; i++)
++              pms[i].f_out =
++                      samsung_pll35xx_calc_f_out(clk_get_rate(clk_get_parent(clk)),
++                                                      pms[i].p,
++                                                      pms[i].m,
++                                                      pms[i].s);
++
+       return clk;
+ }
+diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
+index f33786e..3ce3657 100644
+--- a/drivers/clk/samsung/clk-pll.h
++++ b/drivers/clk/samsung/clk-pll.h
+@@ -24,8 +24,19 @@ enum pll46xx_type {
+       pll_4650c,
+ };
++struct pll_pms {
++      unsigned int f_out;
++      int p;
++      int m;
++      int s;
++      int k;
++};
++
++#define F_OUT_INVAL ~0
++
+ extern struct clk * __init samsung_clk_register_pll35xx(const char *name,
+-                      const char *pname, const void __iomem *con_reg);
++                      const char *pname, const void __iomem *base_reg,
++                      struct pll_pms *pms);
+ extern struct clk * __init samsung_clk_register_pll36xx(const char *name,
+                       const char *pname, const void __iomem *con_reg);
+ extern struct clk * __init samsung_clk_register_pll45xx(const char *name,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0102-cpufreq-Replace-set_apll-code-with-common-clock-fram.patch b/patches.tizen/0102-cpufreq-Replace-set_apll-code-with-common-clock-fram.patch
new file mode 100644 (file)
index 0000000..1153a11
--- /dev/null
@@ -0,0 +1,70 @@
+From 7835f526b3206e93921d2cb92b44b90cb3585fa4 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Mon, 25 Feb 2013 19:02:33 +0100
+Subject: [PATCH 0102/1302] cpufreq: Replace set_apll code with common clock
+ framework's  clk_set_rate()
+
+This commit is a first step for moving common clock's framework code
+from exynos4x12-cpufreq.c to common clock framework.
+
+Tested-at: Trats (U1HD) (Exynos4210), Proxima PQ, Redwood (Exynos4412)
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/exynos4x12-cpufreq.c | 28 +++++++---------------------
+ 1 file changed, 7 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/cpufreq/exynos4x12-cpufreq.c b/drivers/cpufreq/exynos4x12-cpufreq.c
+index 70999b2..02d5353 100644
+--- a/drivers/cpufreq/exynos4x12-cpufreq.c
++++ b/drivers/cpufreq/exynos4x12-cpufreq.c
+@@ -128,11 +128,13 @@ static void exynos4x12_set_clkdiv(unsigned int div_index)
+ static void exynos4x12_set_apll(unsigned int index)
+ {
+-      unsigned int tmp, pdiv;
++      unsigned int tmp, freq = apll_freq_4x12[index].freq * 1000;
++      struct clk *clk;
+-      /* 1. MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */
+-      clk_set_parent(mout_core, sclk_mpll);
++      clk = clk_get_parent(mout_apll);
++      /* MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */
++      clk_set_parent(mout_core, sclk_mpll);
+       do {
+               cpu_relax();
+               tmp = (__raw_readl(EXYNOS4_CLKMUX_STATCPU)
+@@ -140,26 +142,10 @@ static void exynos4x12_set_apll(unsigned int index)
+               tmp &= 0x7;
+       } while (tmp != 0x2);
+-      /* 2. Set APLL Lock time */
+-      pdiv = ((apll_freq_4x12[index].mps >> 8) & 0x3f);
+-
+-      __raw_writel((pdiv * 250), EXYNOS4_APLL_LOCK);
+-
+-      /* 3. Change PLL PMS values */
+-      tmp = __raw_readl(EXYNOS4_APLL_CON0);
+-      tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0));
+-      tmp |= apll_freq_4x12[index].mps;
+-      __raw_writel(tmp, EXYNOS4_APLL_CON0);
++      clk_set_rate(clk, freq);
+-      /* 4. wait_lock_time */
+-      do {
+-              cpu_relax();
+-              tmp = __raw_readl(EXYNOS4_APLL_CON0);
+-      } while (!(tmp & (0x1 << EXYNOS4_APLLCON0_LOCKED_SHIFT)));
+-
+-      /* 5. MUX_CORE_SEL = APLL */
++      /* MUX_CORE_SEL = APLL */
+       clk_set_parent(mout_core, mout_apll);
+-
+       do {
+               cpu_relax();
+               tmp = __raw_readl(EXYNOS4_CLKMUX_STATCPU);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0103-clk-samsung-pll-Add-support-for-PLL45xx-rate-setting.patch b/patches.tizen/0103-clk-samsung-pll-Add-support-for-PLL45xx-rate-setting.patch
new file mode 100644 (file)
index 0000000..13971e3
--- /dev/null
@@ -0,0 +1,261 @@
+From ceb433fcca2897de34d73f7091ff848600fff434 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 1 Mar 2013 17:53:53 +0100
+Subject: [PATCH 0103/1302] clk: samsung: pll: Add support for PLL45xx rate
+ setting
+
+This patch adds support for setting rate of PLL45xx based on PMS table
+received from SoC-specific code.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/samsung/clk-exynos4.c |  18 +++++-
+ drivers/clk/samsung/clk-pll.c     | 114 ++++++++++++++++++++++++++++++++++----
+ drivers/clk/samsung/clk-pll.h     |   5 +-
+ 3 files changed, 122 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
+index 1fc01de..a396705 100644
+--- a/drivers/clk/samsung/clk-exynos4.c
++++ b/drivers/clk/samsung/clk-exynos4.c
+@@ -105,6 +105,7 @@
+ #define DIV_DMC1              0x10504
+ #define GATE_IP_DMC           0x10900
+ #define APLL_LOCK             0x14000
++#define E4210_MPLL_LOCK               0x14008
+ #define APLL_CON0             0x14100
+ #define E4210_MPLL_CON0               0x14108
+ #define SRC_CPU                       0x14200
+@@ -1004,6 +1005,17 @@ struct pll_pms pll35xx_exynos4412_pms[] = {
+       {.f_out = F_OUT_INVAL},
+ };
++struct pll_pms pll45xx_exynos4210_pll45xx_pms[] = {
++      {.p =  6, .m = 250, .s = 1, .afc = 28}, /* 1000 MHz */
++      {.p =  6, .m = 200, .s = 1, .afc = 28}, /* 800 MHz */
++      {.p = 14, .m = 389, .s = 1, .afc = 13}, /* 667 MHz */
++      {.p =  4, .m = 100, .s = 1, .afc = 13}, /* 600 MHz */
++      {.p = 24, .m = 533, .s = 1, .afc =  5}, /* 533 MHz */
++      {.p =  6, .m = 200, .s = 3, .afc = 28}, /* 200 MHz */
++      {.p =  6, .m = 200, .s = 2, .afc = 28}, /* 400 MHz */
++      {.f_out = F_OUT_INVAL},
++};
++
+ /* register exynos4 clocks */
+ void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc exynos4_soc, void __iomem *reg_base, unsigned long xom)
+ {
+@@ -1033,9 +1045,11 @@ void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc exynos4_so
+       if (exynos4_soc == EXYNOS4210) {
+               apll = samsung_clk_register_pll45xx("fout_apll", "fin_pll",
+-                                      reg_base + APLL_CON0, pll_4508);
++                                      reg_base + APLL_LOCK, pll_4508,
++                                      pll45xx_exynos4210_pll45xx_pms);
+               mpll = samsung_clk_register_pll45xx("fout_mpll", "fin_pll",
+-                                      reg_base + E4210_MPLL_CON0, pll_4508);
++                                      reg_base + E4210_MPLL_LOCK, pll_4508,
++                                      pll45xx_exynos4210_pll45xx_pms);
+               epll = samsung_clk_register_pll46xx("fout_epll", "fin_pll",
+                                       reg_base + EPLL_CON0, pll_4600);
+               vpll = samsung_clk_register_pll46xx("fout_vpll", "mout_vpllsrc",
+diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
+index 15b4882..26292d4 100644
+--- a/drivers/clk/samsung/clk-pll.c
++++ b/drivers/clk/samsung/clk-pll.c
+@@ -277,50 +277,135 @@ struct clk * __init samsung_clk_register_pll36xx(const char *name,
+ #define PLL45XX_MDIV_MASK     (0x3FF)
+ #define PLL45XX_PDIV_MASK     (0x3F)
+ #define PLL45XX_SDIV_MASK     (0x7)
++#define PLL45XX_AFC_MASK      0x1f
+ #define PLL45XX_MDIV_SHIFT    (16)
+ #define PLL45XX_PDIV_SHIFT    (8)
+ #define PLL45XX_SDIV_SHIFT    (0)
++#define PLL45XX_AFC_SHIFT     0
++
++#define PLL45XX_PLL_LOCK        0x0
++#define PLL45XX_PLL_LOCK_CONST  7200
++#define PLL45XX_PLL_CON0        0x100
++#define PLL45XX_PLL_CON1        0x104
++#define PLL45XX_LOCKED_SHIFT    29
++#define PLL45XX_LOCKED          (1 << PLL35XX_LOCKED_SHIFT)
+ struct samsung_clk_pll45xx {
+       struct clk_hw           hw;
+       enum pll45xx_type       type;
+-      const void __iomem      *con_reg;
++      void __iomem            *base_reg;
++      struct pll_pms          *pms;
+ };
+ #define to_clk_pll45xx(_hw) container_of(_hw, struct samsung_clk_pll45xx, hw)
++static inline unsigned long samsung_pll45xx_calc_f_out(
++              struct samsung_clk_pll45xx *pll, u64 f_in, int p, int m, int s)
++{
++      if (pll->type == pll_4508)
++              s = s - 1;
++
++      f_in *= m;
++      do_div(f_in, (p << s));
++
++      return (unsigned long)f_in;
++}
++
+ static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,
+                               unsigned long parent_rate)
+ {
+       struct samsung_clk_pll45xx *pll = to_clk_pll45xx(hw);
+       u32 mdiv, pdiv, sdiv, pll_con;
+-      u64 fvco = parent_rate;
+-      pll_con = __raw_readl(pll->con_reg);
++      pll_con = __raw_readl(pll->base_reg + PLL45XX_PLL_CON0);
+       mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
+       pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
+       sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
+-      if (pll->type == pll_4508)
+-              sdiv = sdiv - 1;
++      return samsung_pll45xx_calc_f_out(pll, parent_rate, pdiv, mdiv, sdiv);
++}
+-      fvco *= mdiv;
+-      do_div(fvco, (pdiv << sdiv));
++static long samsung_pll45xx_round_rate(struct clk_hw *hw,
++                              unsigned long drate, unsigned long *prate)
++{
++      struct samsung_clk_pll45xx *pll = to_clk_pll45xx(hw);
++      struct pll_pms *pms = pll->pms;
++      int i;
+-      return (unsigned long)fvco;
++      if (!pms) {
++              pr_err("%s: no pms table passed", __func__);
++              return samsung_pll45xx_recalc_rate(hw, *prate);
++      }
++
++      for (i = 0; pms[i].f_out != F_OUT_INVAL; i++)
++              if (drate >= pms[i].f_out)
++                      return pms[i].f_out;
++
++      return samsung_pll45xx_recalc_rate(hw, *prate);
++}
++
++static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate,
++                              unsigned long prate)
++{
++      struct samsung_clk_pll45xx *pll = to_clk_pll45xx(hw);
++      u32 p = 0, m = 0, s = 0, tmp = 0;
++      u32 afc;
++      struct pll_pms *pms = pll->pms;
++      int index;
++
++      if (!pms) {
++              pr_err("%s: no pms table passed", __func__);
++              return -ENOTSUPP;
++      }
++
++      index = get_index(drate, pll->pms);
++
++      /* Define PLL lock time */
++      __raw_writel(PLL45XX_PLL_LOCK_CONST, pll->base_reg + PLL45XX_PLL_LOCK);
++
++      /* Change PLL PMS */
++      p = pms[index].p;
++      m = pms[index].m;
++      s = pms[index].s;
++      afc = pms[index].afc;
++
++      tmp = __raw_readl(pll->base_reg + PLL45XX_PLL_CON0);
++      tmp &= ~((PLL45XX_PDIV_MASK << PLL45XX_PDIV_SHIFT) |
++              (PLL45XX_MDIV_MASK << PLL45XX_MDIV_SHIFT) |
++              (PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT));
++      tmp |= (p << PLL45XX_PDIV_SHIFT) | (m << PLL45XX_MDIV_SHIFT) |
++              (s << PLL45XX_SDIV_SHIFT);
++      __raw_writel(tmp, pll->base_reg + PLL45XX_PLL_CON0);
++
++      tmp = __raw_readl(pll->base_reg + PLL45XX_PLL_CON1);
++      tmp &= ~(PLL45XX_AFC_MASK << PLL45XX_AFC_SHIFT);
++      tmp |= (afc << PLL45XX_AFC_SHIFT);
++      __raw_writel(tmp, pll->base_reg + PLL45XX_PLL_CON1);
++
++      /* Wait for locking */
++      do {
++              cpu_relax();
++              tmp = __raw_readl(pll->base_reg + PLL45XX_PLL_CON0);
++      } while (!(tmp & PLL45XX_LOCKED));
++
++      return 0;
+ }
+ static const struct clk_ops samsung_pll45xx_clk_ops = {
+       .recalc_rate = samsung_pll45xx_recalc_rate,
++      .round_rate = samsung_pll45xx_round_rate,
++      .set_rate = samsung_pll45xx_set_rate,
+ };
+ struct clk * __init samsung_clk_register_pll45xx(const char *name,
+-                      const char *pname, const void __iomem *con_reg,
+-                      enum pll45xx_type type)
++                      const char *pname, void __iomem *base_reg,
++                      enum pll45xx_type type, struct pll_pms *pms)
+ {
+       struct samsung_clk_pll45xx *pll;
+       struct clk *clk;
+       struct clk_init_data init;
++      unsigned long parent_rate;
++      int i;
+       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+       if (!pll) {
+@@ -335,8 +420,9 @@ struct clk * __init samsung_clk_register_pll45xx(const char *name,
+       init.num_parents = 1;
+       pll->hw.init = &init;
+-      pll->con_reg = con_reg;
++      pll->base_reg = base_reg;
+       pll->type = type;
++      pll->pms = pms;
+       clk = clk_register(NULL, &pll->hw);
+       if (IS_ERR(clk)) {
+@@ -348,6 +434,12 @@ struct clk * __init samsung_clk_register_pll45xx(const char *name,
+       if (clk_register_clkdev(clk, name, NULL))
+               pr_err("%s: failed to register lookup for %s", __func__, name);
++      /* Fill in received frequency table */
++      parent_rate = clk_get_rate(clk_get_parent(clk));
++      for (i = 0; pms[i].f_out != F_OUT_INVAL; i++)
++              pms[i].f_out = samsung_pll45xx_calc_f_out(pll, parent_rate,
++                                              pms[i].p, pms[i].m, pms[i].s);
++
+       return clk;
+ }
+diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
+index 3ce3657..25e322d 100644
+--- a/drivers/clk/samsung/clk-pll.h
++++ b/drivers/clk/samsung/clk-pll.h
+@@ -30,6 +30,7 @@ struct pll_pms {
+       int m;
+       int s;
+       int k;
++      int afc;
+ };
+ #define F_OUT_INVAL ~0
+@@ -40,8 +41,8 @@ extern struct clk * __init samsung_clk_register_pll35xx(const char *name,
+ extern struct clk * __init samsung_clk_register_pll36xx(const char *name,
+                       const char *pname, const void __iomem *con_reg);
+ extern struct clk * __init samsung_clk_register_pll45xx(const char *name,
+-                      const char *pname, const void __iomem *con_reg,
+-                      enum pll45xx_type type);
++                      const char *pname, void __iomem *base_reg,
++                      enum pll45xx_type type, struct pll_pms *pms);
+ extern struct clk * __init samsung_clk_register_pll46xx(const char *name,
+                       const char *pname, const void __iomem *con_reg,
+                       enum pll46xx_type type);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0104-cpufreq-exynos4210-Use-device-based-lookup-for-clock.patch b/patches.tizen/0104-cpufreq-exynos4210-Use-device-based-lookup-for-clock.patch
new file mode 100644 (file)
index 0000000..803c8c7
--- /dev/null
@@ -0,0 +1,48 @@
+From 49744cf0958a7e924b009ef0f3d6c44a838558ba Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 1 Mar 2013 18:10:53 +0100
+Subject: [PATCH 0104/1302] cpufreq: exynos4210: Use device-based lookup for
+ clocks
+
+This patch adds device-based lookup of clocks to allow lookup using
+Device Tree.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/exynos4210-cpufreq.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/cpufreq/exynos4210-cpufreq.c b/drivers/cpufreq/exynos4210-cpufreq.c
+index add7fbe..7e4c886 100644
+--- a/drivers/cpufreq/exynos4210-cpufreq.c
++++ b/drivers/cpufreq/exynos4210-cpufreq.c
+@@ -169,21 +169,21 @@ int exynos4210_cpufreq_init(struct exynos_dvfs_info *info)
+ {
+       unsigned long rate;
+-      cpu_clk = clk_get(NULL, "armclk");
++      cpu_clk = clk_get(info->dev, "armclk");
+       if (IS_ERR(cpu_clk))
+               return PTR_ERR(cpu_clk);
+-      moutcore = clk_get(NULL, "moutcore");
++      moutcore = clk_get(info->dev, "moutcore");
+       if (IS_ERR(moutcore))
+               goto err_moutcore;
+-      mout_mpll = clk_get(NULL, "mout_mpll");
++      mout_mpll = clk_get(info->dev, "mout_mpll");
+       if (IS_ERR(mout_mpll))
+               goto err_mout_mpll;
+       rate = clk_get_rate(mout_mpll) / 1000;
+-      mout_apll = clk_get(NULL, "mout_apll");
++      mout_apll = clk_get(info->dev, "mout_apll");
+       if (IS_ERR(mout_apll))
+               goto err_mout_apll;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0105-cpufreq-exynos4210-Use-common-clock-operations-for-A.patch b/patches.tizen/0105-cpufreq-exynos4210-Use-common-clock-operations-for-A.patch
new file mode 100644 (file)
index 0000000..5a8c3bd
--- /dev/null
@@ -0,0 +1,51 @@
+From 550c560b330312e6240d2eae18a1d1be41d387aa Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 1 Mar 2013 18:12:02 +0100
+Subject: [PATCH 0105/1302] cpufreq: exynos4210: Use common clock operations
+ for APLL configuration
+
+This patch modifies the driver to use clk_set_rate for setting the rate
+of APLL.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/exynos4210-cpufreq.c | 15 ++-------------
+ 1 file changed, 2 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/cpufreq/exynos4210-cpufreq.c b/drivers/cpufreq/exynos4210-cpufreq.c
+index 7e4c886..05a2d67 100644
+--- a/drivers/cpufreq/exynos4210-cpufreq.c
++++ b/drivers/cpufreq/exynos4210-cpufreq.c
+@@ -81,6 +81,7 @@ static void exynos4210_set_clkdiv(unsigned int div_index)
+ static void exynos4210_set_apll(unsigned int index)
+ {
++      unsigned long freq = apll_freq_4210[index].freq * 1000;
+       unsigned int tmp;
+       /* 1. MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */
+@@ -92,19 +93,7 @@ static void exynos4210_set_apll(unsigned int index)
+               tmp &= 0x7;
+       } while (tmp != 0x2);
+-      /* 2. Set APLL Lock time */
+-      __raw_writel(EXYNOS4_APLL_LOCKTIME, EXYNOS4_APLL_LOCK);
+-
+-      /* 3. Change PLL PMS values */
+-      tmp = __raw_readl(EXYNOS4_APLL_CON0);
+-      tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0));
+-      tmp |= apll_freq_4210[index].mps;
+-      __raw_writel(tmp, EXYNOS4_APLL_CON0);
+-
+-      /* 4. wait_lock_time */
+-      do {
+-              tmp = __raw_readl(EXYNOS4_APLL_CON0);
+-      } while (!(tmp & (0x1 << EXYNOS4_APLLCON0_LOCKED_SHIFT)));
++      clk_set_rate(mout_apll, freq);
+       /* 5. MUX_CORE_SEL = APLL */
+       clk_set_parent(moutcore, mout_apll);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0106-ARM-dts-exynos4210-Add-cpufreq-node.patch b/patches.tizen/0106-ARM-dts-exynos4210-Add-cpufreq-node.patch
new file mode 100644 (file)
index 0000000..034eb47
--- /dev/null
@@ -0,0 +1,33 @@
+From 7aafa05910f47ffe21886eceaebb943003ae9080 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 1 Mar 2013 18:15:05 +0100
+Subject: [PATCH 0106/1302] ARM: dts: exynos4210: Add cpufreq node
+
+This patch adds cpufreq node with SoC specific parameters of cpufreq
+driver.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210.dtsi | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
+index 99cb43e..750b320 100644
+--- a/arch/arm/boot/dts/exynos4210.dtsi
++++ b/arch/arm/boot/dts/exynos4210.dtsi
+@@ -201,4 +201,11 @@
+                       clock-names = "csis", "sclk_csis", "mux", "parent";
+               };
+       };
++
++      cpufreq {
++              compatible = "samsung,exynos-cpufreq";
++              clocks = <&clock 12>, <&clock 19>, <&clock 9>, <&clock 20>;
++              clock-names = "armclk", "moutcore", "mout_mpll", "mout_apll";
++              status = "disabled";
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0107-ARM-dts-exynos4210-trats-Add-cpufreq-node.patch b/patches.tizen/0107-ARM-dts-exynos4210-trats-Add-cpufreq-node.patch
new file mode 100644 (file)
index 0000000..176b3bb
--- /dev/null
@@ -0,0 +1,32 @@
+From 375871f8df3c63f973f1d9f21c55f0618e87b682 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 1 Mar 2013 18:15:48 +0100
+Subject: [PATCH 0107/1302] ARM: dts: exynos4210-trats: Add cpufreq node
+
+This patch adds cpufreq node with board-specific parameters to enable
+CPU frequency scaling on Trats board.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index 444474b..6f444d2 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -432,4 +432,10 @@
+                       memory-region = <&mfc_r_mem>;
+               };
+       };
++
++      cpufreq {
++              /* No freq_table property to use default table. */
++              vdd_arm-supply = <&varm_breg>;
++              status = "okay";
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0108-ARM-dts-exynos4210-trats-Use-board-name-for-BUCK1-re.patch b/patches.tizen/0108-ARM-dts-exynos4210-trats-Use-board-name-for-BUCK1-re.patch
new file mode 100644 (file)
index 0000000..c88c398
--- /dev/null
@@ -0,0 +1,31 @@
+From 38d50de50f84d82065bb3c94aa0bfe70740c5d79 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 1 Mar 2013 18:16:30 +0100
+Subject: [PATCH 0108/1302] ARM: dts: exynos4210-trats: Use board name for
+ BUCK1 regulator
+
+This patch removes the workaround originally required for cpufreq and
+sets BUCK1 regulator name to name specified in board schematics.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index 6f444d2..4b90ae3 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -279,7 +279,7 @@
+                               };
+                               varm_breg: BUCK1 {
+-                                   regulator-name = "vdd_arm";
++                                   regulator-name = "VARM_1.2V_C210";
+                                    regulator-min-microvolt = <900000>;
+                                    regulator-max-microvolt = <1350000>;
+                                    regulator-always-on;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0109-clk-samsung-pll-Do-not-return-error-codes-in-round_r.patch b/patches.tizen/0109-clk-samsung-pll-Do-not-return-error-codes-in-round_r.patch
new file mode 100644 (file)
index 0000000..d5d6ed2
--- /dev/null
@@ -0,0 +1,40 @@
+From 9505285498d443a51c86d042e09acc2036a92479 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 1 Mar 2013 18:28:31 +0100
+Subject: [PATCH 0109/1302] clk: samsung: pll: Do not return error codes in
+ round_rate callback
+
+This patch modifies pll35xx round_rate callback to return current
+frequency instead of error codes to avoid problems caused by clock core
+using error codes as frequencies.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/samsung/clk-pll.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
+index 26292d4..1abdfba 100644
+--- a/drivers/clk/samsung/clk-pll.c
++++ b/drivers/clk/samsung/clk-pll.c
+@@ -81,14 +81,14 @@ static long samsung_pll35xx_round_rate(struct clk_hw *hw,
+       if (!pms) {
+               pr_err("%s: no pms table passed", __func__);
+-              return -ENOTSUPP;
++              return samsung_pll35xx_recalc_rate(hw, *prate);
+       }
+       for (i = 0; pms[i].f_out != F_OUT_INVAL; i++)
+               if (drate >= pms[i].f_out)
+                       return pms[i].f_out;
+-      return -EINVAL;
++      return samsung_pll35xx_recalc_rate(hw, *prate);
+ }
+ static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0110-ARM-dts-exynos4412-slp_pq-Correct-cpufreq-device-nod.patch b/patches.tizen/0110-ARM-dts-exynos4412-slp_pq-Correct-cpufreq-device-nod.patch
new file mode 100644 (file)
index 0000000..e807458
--- /dev/null
@@ -0,0 +1,28 @@
+From c1771a6e83689f51293e3531dd75fcab8a69f8e9 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Mon, 4 Mar 2013 13:13:47 +0100
+Subject: [PATCH 0110/1302] ARM: dts: exynos4412-slp_pq: Correct cpufreq device
+ node
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 69a6184..653ef3b 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -706,8 +706,7 @@
+       };
+       cpufreq {
+-              /* 4294967295 is a ~0 representation with u32 */
+-              freq_table = <4294967295 4294967295 4294967295 1100000 1000000
++              freq_table = <0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 1100000 1000000
+                            900000 800000 700000 600000 500000 400000 300000
+                            200000>;
+               vdd_arm-supply = <&buck2_reg>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0111-clk-samsung-pll-Add-support-for-PLL36xx-rate-configu.patch b/patches.tizen/0111-clk-samsung-pll-Add-support-for-PLL36xx-rate-configu.patch
new file mode 100644 (file)
index 0000000..dcc7dd5
--- /dev/null
@@ -0,0 +1,274 @@
+From fbfd319bf4c69480811d937557f191ec753212a0 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Mon, 13 May 2013 17:51:59 +0200
+Subject: [PATCH 0111/1302] clk: samsung: pll: Add support for PLL36xx rate
+ configuration
+
+This patch adds implementation of round_rate and set_rate operations of
+PLL36xx PLLs used on Exynos 4x12 SoCs as EPLL and VPLL.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/samsung/clk-exynos4.c |  26 +++++++-
+ drivers/clk/samsung/clk-pll.c     | 122 ++++++++++++++++++++++++++++++++++----
+ drivers/clk/samsung/clk-pll.h     |   5 +-
+ 3 files changed, 138 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
+index a396705..da1ced2 100644
+--- a/drivers/clk/samsung/clk-exynos4.c
++++ b/drivers/clk/samsung/clk-exynos4.c
+@@ -1005,6 +1005,28 @@ struct pll_pms pll35xx_exynos4412_pms[] = {
+       {.f_out = F_OUT_INVAL},
+ };
++static struct pll_pms exynos4_epll_pms[] = {
++      { .p = 3, .m = 48, .s = 1, .k =     0 },
++      { .p = 3, .m = 45, .s = 1, .k = 10381 },
++      { .p = 3, .m = 45, .s = 1, .k =     0 },
++      { .p = 3, .m = 73, .s = 3, .k = 47710 },
++      { .p = 4, .m = 90, .s = 3, .k = 20762 },
++      { .p = 3, .m = 49, .s = 3, .k =  9961 },
++      { .p = 3, .m = 45, .s = 3, .k = 10381 },
++      { .f_out = F_OUT_INVAL },
++};
++
++static struct pll_pms exynos4_vpll_pms[] = {
++      { .p = 3, .m = 133, .s = 1, .k = 16384, .mrr =  0 },
++      { .p = 3, .m = 110, .s = 1, .k =     0, .mrr =  0 },
++      { .p = 3, .m = 175, .s = 2, .k =     0, .mrr =  0 },
++      { .p = 3, .m = 133, .s = 2, .k =     0, .mrr =  0 },
++      { .p = 3, .m = 160, .s = 3, .k =     0, .mrr =  0 },
++      { .p = 3, .m =  53, .s = 2, .k =  1024, .mrr = 17 },
++      { .p = 3, .m =  53, .s = 3, .k =  1024, .mrr = 17 },
++      { .f_out = F_OUT_INVAL },
++};
++
+ struct pll_pms pll45xx_exynos4210_pll45xx_pms[] = {
+       {.p =  6, .m = 250, .s = 1, .afc = 28}, /* 1000 MHz */
+       {.p =  6, .m = 200, .s = 1, .afc = 28}, /* 800 MHz */
+@@ -1060,9 +1082,9 @@ void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc exynos4_so
+               mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll",
+                       reg_base + E4X12_MPLL_LOCK, pll35xx_exynos4412_pms);
+               epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll",
+-                                      reg_base + EPLL_CON0);
++                              reg_base + EPLL_LOCK, exynos4_epll_pms);
+               vpll = samsung_clk_register_pll36xx("fout_vpll", "fin_pll",
+-                                      reg_base + VPLL_CON0);
++                              reg_base + VPLL_LOCK, exynos4_vpll_pms);
+       }
+       samsung_clk_add_lookup(apll, fout_apll);
+diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
+index 1abdfba..86a6423 100644
+--- a/drivers/clk/samsung/clk-pll.c
++++ b/drivers/clk/samsung/clk-pll.c
+@@ -41,7 +41,7 @@ static int get_index(unsigned long rate, struct pll_pms *pms)
+       int i;
+       for (i = 0; pms[i].f_out != F_OUT_INVAL; i++)
+-              if (pms[i].f_out == rate)
++              if (pms[i].f_out <= rate)
+                       return i;
+       return -EINVAL;
+@@ -198,15 +198,39 @@ samsung_clk_register_pll35xx(const char *name,
+ #define PLL36XX_MDIV_MASK     (0x1FF)
+ #define PLL36XX_PDIV_MASK     (0x3F)
+ #define PLL36XX_SDIV_MASK     (0x7)
++#define PLL36XX_MFR_MASK      0xff
++#define PLL36XX_MRR_MASK      0x1f
++#define PLL36XX_KDIV_SHIFT    0
+ #define PLL36XX_MDIV_SHIFT    (16)
+ #define PLL36XX_PDIV_SHIFT    (8)
+ #define PLL36XX_SDIV_SHIFT    (0)
++#define PLL36XX_MFR_SHIFT     16
++#define PLL36XX_MRR_SHIFT     24
++
++#define PLL36XX_PLL_LOCK      0x0
++#define PLL36XX_PLL_CON0      0x100
++#define PLL36XX_PLL_CON1      0x104
++#define PLL36XX_PLL_CON2      0x108
++
++#define PLL36XX_PLL_LOCK_CONST        3000
++#define PLL36XX_PLL_CON0_LOCKED       (1 << 29)
++
+ struct samsung_clk_pll36xx {
+-      struct clk_hw           hw;
+-      const void __iomem      *con_reg;
++      struct clk_hw   hw;
++      void __iomem    *base;
++      struct pll_pms  *pms;
+ };
++static inline unsigned long samsung_pll36xx_calc_f_out(u64 f_in,
++                                              u32 p, u32 m, u32 s, u32 k)
++{
++      f_in *= (m << 16) + k;
++      do_div(f_in, (p << s));
++
++      return (unsigned long)(f_in >> 16);
++}
++
+ #define to_clk_pll36xx(_hw) container_of(_hw, struct samsung_clk_pll36xx, hw)
+ static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
+@@ -215,32 +239,99 @@ static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
+       struct samsung_clk_pll36xx *pll = to_clk_pll36xx(hw);
+       u32 mdiv, pdiv, sdiv, pll_con0, pll_con1;
+       s16 kdiv;
+-      u64 fvco = parent_rate;
+-      pll_con0 = __raw_readl(pll->con_reg);
+-      pll_con1 = __raw_readl(pll->con_reg + 4);
++      pll_con0 = __raw_readl(pll->base + PLL36XX_PLL_CON0);
++      pll_con1 = __raw_readl(pll->base + PLL36XX_PLL_CON1);
+       mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
+       pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
+       sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK;
+       kdiv = (s16)(pll_con1 & PLL36XX_KDIV_MASK);
+-      fvco *= (mdiv << 16) + kdiv;
+-      do_div(fvco, (pdiv << sdiv));
+-      fvco >>= 16;
++      return samsung_pll36xx_calc_f_out(parent_rate, pdiv, mdiv, sdiv, kdiv);
++}
+-      return (unsigned long)fvco;
++static long samsung_pll36xx_round_rate(struct clk_hw *hw,
++                              unsigned long drate, unsigned long *prate)
++{
++      struct samsung_clk_pll36xx *pll = to_clk_pll36xx(hw);
++      struct pll_pms *pms = pll->pms;
++      int i;
++
++      if (!pms) {
++              pr_err("%s: no pms table passed", __func__);
++              return samsung_pll36xx_recalc_rate(hw, *prate);
++      }
++
++      i = get_index(drate, pms);
++      if (i >= 0)
++              return pms[i].f_out;
++
++      return samsung_pll36xx_recalc_rate(hw, *prate);
++}
++
++static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
++                              unsigned long prate)
++{
++      struct samsung_clk_pll36xx *pll = to_clk_pll36xx(hw);
++      struct pll_pms *pms = pll->pms;
++      u32 tmp;
++      int index;
++
++      if (!pms) {
++              pr_err("%s: no pms table passed", __func__);
++              return -ENOTSUPP;
++      }
++
++      index = get_index(drate, pms);
++      if (index < 0)
++              return index;
++
++      /* Define PLL lock time */
++      __raw_writel(pms[index].p * PLL36XX_PLL_LOCK_CONST,
++                                      pll->base + PLL36XX_PLL_LOCK);
++
++      /* Change PLL divisors */
++      tmp = __raw_readl(pll->base + PLL36XX_PLL_CON0);
++      tmp &= ~((PLL36XX_PDIV_MASK << PLL36XX_PDIV_SHIFT) |
++              (PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT) |
++              (PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT));
++      tmp |= (pms[index].p << PLL36XX_PDIV_SHIFT) |
++              (pms[index].m << PLL36XX_MDIV_SHIFT) |
++              (pms[index].s << PLL36XX_SDIV_SHIFT);
++      __raw_writel(tmp, pll->base + PLL36XX_PLL_CON0);
++
++      tmp = __raw_readl(pll->base + PLL36XX_PLL_CON1);
++      tmp &= ~((PLL36XX_KDIV_MASK << PLL36XX_KDIV_SHIFT) |
++              (PLL36XX_MFR_MASK << PLL36XX_MFR_SHIFT) |
++              (PLL36XX_MRR_MASK << PLL36XX_MRR_SHIFT));
++      tmp |= (pms[index].k << PLL36XX_KDIV_SHIFT) |
++              (pms[index].mrr << PLL36XX_MRR_SHIFT) |
++              (pms[index].mfr << PLL36XX_MFR_SHIFT);
++      __raw_writel(tmp, pll->base + PLL36XX_PLL_CON1);
++
++      /* Wait for locking */
++      do {
++              cpu_relax();
++              tmp = __raw_readl(pll->base + PLL36XX_PLL_CON0);
++      } while (!(tmp & PLL36XX_PLL_CON0_LOCKED));
++
++      return 0;
+ }
+ static const struct clk_ops samsung_pll36xx_clk_ops = {
+       .recalc_rate = samsung_pll36xx_recalc_rate,
++      .round_rate = samsung_pll36xx_round_rate,
++      .set_rate = samsung_pll36xx_set_rate,
+ };
+ struct clk * __init samsung_clk_register_pll36xx(const char *name,
+-                      const char *pname, const void __iomem *con_reg)
++              const char *pname, void __iomem *base, struct pll_pms *pms)
+ {
+       struct samsung_clk_pll36xx *pll;
+       struct clk *clk;
+       struct clk_init_data init;
++      unsigned long parent_rate;
++      unsigned int i;
+       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+       if (!pll) {
+@@ -255,7 +346,8 @@ struct clk * __init samsung_clk_register_pll36xx(const char *name,
+       init.num_parents = 1;
+       pll->hw.init = &init;
+-      pll->con_reg = con_reg;
++      pll->base = base;
++      pll->pms = pms;
+       clk = clk_register(NULL, &pll->hw);
+       if (IS_ERR(clk)) {
+@@ -267,6 +359,12 @@ struct clk * __init samsung_clk_register_pll36xx(const char *name,
+       if (clk_register_clkdev(clk, name, NULL))
+               pr_err("%s: failed to register lookup for %s", __func__, name);
++      /* Fill in received frequency table */
++      parent_rate = clk_get_rate(clk_get_parent(clk));
++      for (i = 0; pms[i].f_out != F_OUT_INVAL; i++)
++              pms[i].f_out = samsung_pll36xx_calc_f_out(parent_rate,
++                                      pms[i].p, pms[i].m, pms[i].s, pms[i].k);
++
+       return clk;
+ }
+diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
+index 25e322d..3fae687 100644
+--- a/drivers/clk/samsung/clk-pll.h
++++ b/drivers/clk/samsung/clk-pll.h
+@@ -31,6 +31,8 @@ struct pll_pms {
+       int s;
+       int k;
+       int afc;
++      int mfr;
++      int mrr;
+ };
+ #define F_OUT_INVAL ~0
+@@ -39,7 +41,8 @@ extern struct clk * __init samsung_clk_register_pll35xx(const char *name,
+                       const char *pname, const void __iomem *base_reg,
+                       struct pll_pms *pms);
+ extern struct clk * __init samsung_clk_register_pll36xx(const char *name,
+-                      const char *pname, const void __iomem *con_reg);
++                      const char *pname, void __iomem *base,
++                      struct pll_pms *pms);
+ extern struct clk * __init samsung_clk_register_pll45xx(const char *name,
+                       const char *pname, void __iomem *base_reg,
+                       enum pll45xx_type type, struct pll_pms *pms);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0112-clk-samsung-exynos4-Allow-rate-setting-propagation-t.patch b/patches.tizen/0112-clk-samsung-exynos4-Allow-rate-setting-propagation-t.patch
new file mode 100644 (file)
index 0000000..7337222
--- /dev/null
@@ -0,0 +1,44 @@
+From 25867130bc090ad014a6ee94574f30e8f8d8e5d1 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Mon, 13 May 2013 17:54:36 +0200
+Subject: [PATCH 0112/1302] clk: samsung: exynos4: Allow rate setting
+ propagation through sclk_vpll
+
+This patch adds CLK_SET_RATE_PARENT flag to sclk_vpll to allow rate
+configuration of VPLL on Exynos4210 and Exynos4x12.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/samsung/clk-exynos4.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
+index da1ced2..67685bf 100644
+--- a/drivers/clk/samsung/clk-exynos4.c
++++ b/drivers/clk/samsung/clk-exynos4.c
+@@ -391,8 +391,8 @@ struct samsung_mux_clock exynos4210_mux_clks[] __initdata = {
+       MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, SRC_CPU, 8, 1, "sclk_mpll"),
+       MUX_A(mout_core, "mout_core", mout_core_p4210,
+                       SRC_CPU, 16, 1, "mout_core"),
+-      MUX_A(sclk_vpll, "sclk_vpll", sclk_vpll_p4210,
+-                      SRC_TOP0, 8, 1, "sclk_vpll"),
++      __MUX(sclk_vpll, NULL, "sclk_vpll", sclk_vpll_p4210,
++                      SRC_TOP0, 8, 1, CLK_SET_RATE_PARENT, 0, "sclk_vpll"),
+       MUX(mout_fimc0, "mout_fimc0", group1_p4210, SRC_CAM, 0, 4),
+       MUX(mout_fimc1, "mout_fimc1", group1_p4210, SRC_CAM, 4, 4),
+       MUX(mout_fimc2, "mout_fimc2", group1_p4210, SRC_CAM, 8, 4),
+@@ -450,8 +450,8 @@ struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = {
+       MUX(none, "mout_jpeg", mout_jpeg_p, E4X12_SRC_CAM1, 8, 1),
+       MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p,
+                       SRC_DMC, 12, 1, "sclk_mpll"),
+-      MUX_A(sclk_vpll, "sclk_vpll", mout_vpll_p,
+-                      SRC_TOP0, 8, 1, "sclk_vpll"),
++      __MUX(sclk_vpll, NULL, "sclk_vpll", mout_vpll_p,
++                      SRC_TOP0, 8, 1, CLK_SET_RATE_PARENT, 0, "sclk_vpll"),
+       MUX(mout_core, "mout_core", mout_core_p4x12, SRC_CPU, 16, 1),
+       MUX(mout_fimc0, "mout_fimc0", group1_p4x12, SRC_CAM, 0, 4),
+       MUX(mout_fimc1, "mout_fimc1", group1_p4x12, SRC_CAM, 4, 4),
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0113-clk-samsung-exynos4-Fix-clock-registration-order.patch b/patches.tizen/0113-clk-samsung-exynos4-Fix-clock-registration-order.patch
new file mode 100644 (file)
index 0000000..6859035
--- /dev/null
@@ -0,0 +1,54 @@
+From 078a809ba09aaeaae24b9092fd6be033478b2b4a Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Tue, 14 May 2013 19:17:33 +0200
+Subject: [PATCH 0113/1302] clk: samsung: exynos4: Fix clock registration order
+
+This patch moves registration of fixed clocks and Exynos4210-specific
+mux clocks before PLL registration, because some of those clocks are
+needed for Exynos4210 PLL initialization.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/samsung/clk-exynos4.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
+index 67685bf..8572652 100644
+--- a/drivers/clk/samsung/clk-exynos4.c
++++ b/drivers/clk/samsung/clk-exynos4.c
+@@ -1064,8 +1064,13 @@ void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc exynos4_so
+                       ext_clk_match);
+       exynos4_clk_register_finpll(xom);
++      samsung_clk_register_fixed_rate(exynos4_fixed_rate_clks,
++                      ARRAY_SIZE(exynos4_fixed_rate_clks));
+       if (exynos4_soc == EXYNOS4210) {
++              samsung_clk_register_mux(exynos4210_mux_clks,
++                                      ARRAY_SIZE(exynos4210_mux_clks));
++
+               apll = samsung_clk_register_pll45xx("fout_apll", "fin_pll",
+                                       reg_base + APLL_LOCK, pll_4508,
+                                       pll45xx_exynos4210_pll45xx_pms);
+@@ -1092,8 +1097,6 @@ void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc exynos4_so
+       samsung_clk_add_lookup(epll, fout_epll);
+       samsung_clk_add_lookup(vpll, fout_vpll);
+-      samsung_clk_register_fixed_rate(exynos4_fixed_rate_clks,
+-                      ARRAY_SIZE(exynos4_fixed_rate_clks));
+       samsung_clk_register_mux(exynos4_mux_clks,
+                       ARRAY_SIZE(exynos4_mux_clks));
+       samsung_clk_register_div(exynos4_div_clks,
+@@ -1104,8 +1107,6 @@ void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc exynos4_so
+       if (exynos4_soc == EXYNOS4210) {
+               samsung_clk_register_fixed_rate(exynos4210_fixed_rate_clks,
+                       ARRAY_SIZE(exynos4210_fixed_rate_clks));
+-              samsung_clk_register_mux(exynos4210_mux_clks,
+-                      ARRAY_SIZE(exynos4210_mux_clks));
+               samsung_clk_register_div(exynos4210_div_clks,
+                       ARRAY_SIZE(exynos4210_div_clks));
+               samsung_clk_register_gate(exynos4210_gate_clks,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0114-clk-samsung-exynos4-Add-support-for-PLL46xx-rate-con.patch b/patches.tizen/0114-clk-samsung-exynos4-Add-support-for-PLL46xx-rate-con.patch
new file mode 100644 (file)
index 0000000..78c9605
--- /dev/null
@@ -0,0 +1,235 @@
+From d87c869d7b002395837ae1ca7e37b67301785a67 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Tue, 14 May 2013 19:20:03 +0200
+Subject: [PATCH 0114/1302] clk: samsung: exynos4: Add support for PLL46xx rate
+ configuration
+
+This patch adds support for rate configuration of PLL46xx, which is used
+for EPLL and VPLL on Exynos4210.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/samsung/clk-exynos4.c |   6 +-
+ drivers/clk/samsung/clk-pll.c     | 124 ++++++++++++++++++++++++++++++++++----
+ drivers/clk/samsung/clk-pll.h     |   4 +-
+ 3 files changed, 117 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
+index 8572652..f2a338f 100644
+--- a/drivers/clk/samsung/clk-exynos4.c
++++ b/drivers/clk/samsung/clk-exynos4.c
+@@ -1078,9 +1078,11 @@ void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc exynos4_so
+                                       reg_base + E4210_MPLL_LOCK, pll_4508,
+                                       pll45xx_exynos4210_pll45xx_pms);
+               epll = samsung_clk_register_pll46xx("fout_epll", "fin_pll",
+-                                      reg_base + EPLL_CON0, pll_4600);
++                                      reg_base + EPLL_LOCK, pll_4600,
++                                      exynos4_epll_pms);
+               vpll = samsung_clk_register_pll46xx("fout_vpll", "mout_vpllsrc",
+-                                      reg_base + VPLL_CON0, pll_4650c);
++                                      reg_base + VPLL_LOCK, pll_4650c,
++                                      exynos4_vpll_pms);
+       } else {
+               apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll",
+                       reg_base + APLL_LOCK, pll35xx_exynos4412_pms);
+diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
+index 86a6423..6be496a 100644
+--- a/drivers/clk/samsung/clk-pll.c
++++ b/drivers/clk/samsung/clk-pll.c
+@@ -554,50 +554,141 @@ struct clk * __init samsung_clk_register_pll45xx(const char *name,
+ #define PLL46XX_KDIV_MASK     (0xFFFF)
+ #define PLL4650C_KDIV_MASK    (0xFFF)
++#define PLL46XX_MFR_MASK      0x3f
++#define PLL46XX_MRR_MASK      0x1f
+ #define PLL46XX_KDIV_SHIFT    (0)
++#define PLL46XX_MFR_SHIFT     16
++#define PLL46XX_MRR_SHIFT     24
++
++#define PLL46XX_PLL_LOCK      0x0
++#define PLL46XX_PLL_CON0      0x100
++#define PLL46XX_PLL_CON1      0x104
++
++#define PLL46XX_PLL_LOCK_CONST        3000
++#define PLL46XX_PLL_CON0_LOCKED       (1 << 29)
+ struct samsung_clk_pll46xx {
+       struct clk_hw           hw;
+       enum pll46xx_type       type;
+-      const void __iomem      *con_reg;
++      void __iomem            *base;
++      struct pll_pms          *pms;
+ };
+ #define to_clk_pll46xx(_hw) container_of(_hw, struct samsung_clk_pll46xx, hw)
++static inline unsigned long samsung_pll46xx_calc_f_out(u64 f_in,
++                      u32 p, u32 m, u32 s, u32 k, enum pll46xx_type type)
++{
++      u8 shift = (type == pll_4600) ? 16 : 10;
++
++      f_in *= (m << shift) + k;
++      do_div(f_in, (p << s));
++
++      return (unsigned long)(f_in >> shift);
++}
++
+ static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,
+                               unsigned long parent_rate)
+ {
+       struct samsung_clk_pll46xx *pll = to_clk_pll46xx(hw);
+-      u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1, shift;
+-      u64 fvco = parent_rate;
++      u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
+-      pll_con0 = __raw_readl(pll->con_reg);
+-      pll_con1 = __raw_readl(pll->con_reg + 4);
++      pll_con0 = __raw_readl(pll->base + PLL46XX_PLL_CON0);
++      pll_con1 = __raw_readl(pll->base + PLL46XX_PLL_CON1);
+       mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
+       pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
+       sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
+       kdiv = pll->type == pll_4650c ? pll_con1 & PLL4650C_KDIV_MASK :
+                                       pll_con1 & PLL46XX_KDIV_MASK;
+-      shift = pll->type == pll_4600 ? 16 : 10;
+-      fvco *= (mdiv << shift) + kdiv;
+-      do_div(fvco, (pdiv << sdiv));
+-      fvco >>= shift;
++      return samsung_pll46xx_calc_f_out(parent_rate,
++                                      pdiv, mdiv, sdiv, kdiv, pll->type);
++}
+-      return (unsigned long)fvco;
++static long samsung_pll46xx_round_rate(struct clk_hw *hw,
++                              unsigned long drate, unsigned long *prate)
++{
++      struct samsung_clk_pll46xx *pll = to_clk_pll46xx(hw);
++      struct pll_pms *pms = pll->pms;
++      int i;
++
++      if (!pms) {
++              pr_err("%s: no pms table passed", __func__);
++              return samsung_pll46xx_recalc_rate(hw, *prate);
++      }
++
++      i = get_index(drate, pms);
++      if (i >= 0)
++              return pms[i].f_out;
++
++      return samsung_pll46xx_recalc_rate(hw, *prate);
++}
++
++static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
++                              unsigned long prate)
++{
++      struct samsung_clk_pll46xx *pll = to_clk_pll46xx(hw);
++      struct pll_pms *pms = pll->pms;
++      u32 tmp;
++      int index;
++
++      if (!pms) {
++              pr_err("%s: no pms table passed", __func__);
++              return -ENOTSUPP;
++      }
++
++      index = get_index(drate, pms);
++      if (index < 0)
++              return index;
++
++      /* Define PLL lock time */
++      __raw_writel(pms[index].p * PLL46XX_PLL_LOCK_CONST,
++                                      pll->base + PLL46XX_PLL_LOCK);
++
++      /* Change PLL divisors */
++      tmp = __raw_readl(pll->base + PLL46XX_PLL_CON0);
++      tmp &= ~((PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) |
++              (PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
++              (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT));
++      tmp |= (pms[index].p << PLL46XX_PDIV_SHIFT) |
++              (pms[index].m << PLL46XX_MDIV_SHIFT) |
++              (pms[index].s << PLL46XX_SDIV_SHIFT);
++      __raw_writel(tmp, pll->base + PLL46XX_PLL_CON0);
++
++      tmp = __raw_readl(pll->base + PLL46XX_PLL_CON1);
++      tmp &= ~((PLL46XX_KDIV_MASK << PLL46XX_KDIV_SHIFT) |
++              (PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT) |
++              (PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT));
++      tmp |= (pms[index].k << PLL46XX_KDIV_SHIFT) |
++              (pms[index].mrr << PLL46XX_MRR_SHIFT) |
++              (pms[index].mfr << PLL46XX_MFR_SHIFT);
++      __raw_writel(tmp, pll->base + PLL46XX_PLL_CON1);
++
++      /* Wait for locking */
++      do {
++              cpu_relax();
++              tmp = __raw_readl(pll->base + PLL46XX_PLL_CON0);
++      } while (!(tmp & PLL46XX_PLL_CON0_LOCKED));
++
++      return 0;
+ }
++
+ static const struct clk_ops samsung_pll46xx_clk_ops = {
+       .recalc_rate = samsung_pll46xx_recalc_rate,
++      .round_rate = samsung_pll46xx_round_rate,
++      .set_rate = samsung_pll46xx_set_rate,
+ };
+ struct clk * __init samsung_clk_register_pll46xx(const char *name,
+-                      const char *pname, const void __iomem *con_reg,
+-                      enum pll46xx_type type)
++                              const char *pname, void __iomem *base,
++                              enum pll46xx_type type, struct pll_pms *pms)
+ {
+       struct samsung_clk_pll46xx *pll;
+       struct clk *clk;
+       struct clk_init_data init;
++      unsigned long parent_rate;
++      unsigned int i;
+       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+       if (!pll) {
+@@ -612,8 +703,9 @@ struct clk * __init samsung_clk_register_pll46xx(const char *name,
+       init.num_parents = 1;
+       pll->hw.init = &init;
+-      pll->con_reg = con_reg;
++      pll->base = base;
+       pll->type = type;
++      pll->pms = pms;
+       clk = clk_register(NULL, &pll->hw);
+       if (IS_ERR(clk)) {
+@@ -625,6 +717,12 @@ struct clk * __init samsung_clk_register_pll46xx(const char *name,
+       if (clk_register_clkdev(clk, name, NULL))
+               pr_err("%s: failed to register lookup for %s", __func__, name);
++      /* Fill in received frequency table */
++      parent_rate = clk_get_rate(clk_get_parent(clk));
++      for (i = 0; pms[i].f_out != F_OUT_INVAL; i++)
++              pms[i].f_out = samsung_pll46xx_calc_f_out(parent_rate,
++                              pms[i].p, pms[i].m, pms[i].s, pms[i].k, type);
++
+       return clk;
+ }
+diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
+index 3fae687..c00c2bd 100644
+--- a/drivers/clk/samsung/clk-pll.h
++++ b/drivers/clk/samsung/clk-pll.h
+@@ -47,8 +47,8 @@ extern struct clk * __init samsung_clk_register_pll45xx(const char *name,
+                       const char *pname, void __iomem *base_reg,
+                       enum pll45xx_type type, struct pll_pms *pms);
+ extern struct clk * __init samsung_clk_register_pll46xx(const char *name,
+-                      const char *pname, const void __iomem *con_reg,
+-                      enum pll46xx_type type);
++                      const char *pname, void __iomem *base,
++                      enum pll46xx_type type, struct pll_pms *pms);
+ extern struct clk * __init samsung_clk_register_pll2550x(const char *name,
+                       const char *pname, const void __iomem *reg_base,
+                       const unsigned long offset);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0115-gpu-arm-Import-new-mali400-drivers-from-exynos-3.4-d.patch b/patches.tizen/0115-gpu-arm-Import-new-mali400-drivers-from-exynos-3.4-d.patch
new file mode 100644 (file)
index 0000000..39fc10e
--- /dev/null
@@ -0,0 +1,37316 @@
+From 4a8727866652ccb97490ae96a7fcf8a24e79c7e6 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Mon, 11 Feb 2013 17:53:37 +0100
+Subject: [PATCH 0115/1302] gpu: arm: Import new mali400 drivers from
+ exynos-3.4-dev tree
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/Makefile                               |    2 +
+ drivers/gpu/arm/Kconfig                            |   17 +
+ drivers/gpu/arm/mali400/Kconfig                    |   16 +
+ drivers/gpu/arm/mali400/Makefile                   |    4 +
+ drivers/gpu/arm/mali400/mali/Kbuild                |  190 +++
+ drivers/gpu/arm/mali400/mali/Kconfig               |   55 +
+ drivers/gpu/arm/mali400/mali/MALI_CONFIGURATION    |   24 +
+ drivers/gpu/arm/mali400/mali/Makefile              |  127 ++
+ .../gpu/arm/mali400/mali/__malidrv_build_info.c    |    1 +
+ .../arm/mali400/mali/common/mali_block_allocator.c |  390 +++++
+ .../arm/mali400/mali/common/mali_block_allocator.h |   18 +
+ .../gpu/arm/mali400/mali/common/mali_broadcast.c   |  117 ++
+ .../gpu/arm/mali400/mali/common/mali_broadcast.h   |   34 +
+ .../mali400/mali/common/mali_device_pause_resume.c |   42 +
+ .../mali400/mali/common/mali_device_pause_resume.h |   31 +
+ drivers/gpu/arm/mali400/mali/common/mali_dlbu.c    |  214 +++
+ drivers/gpu/arm/mali400/mali/common/mali_dlbu.h    |   38 +
+ drivers/gpu/arm/mali400/mali/common/mali_gp.c      |  364 ++++
+ drivers/gpu/arm/mali400/mali/common/mali_gp.h      |   96 ++
+ drivers/gpu/arm/mali400/mali/common/mali_gp_job.c  |  116 ++
+ drivers/gpu/arm/mali400/mali/common/mali_gp_job.h  |  152 ++
+ .../arm/mali400/mali/common/mali_gp_scheduler.c    |  474 +++++
+ .../arm/mali400/mali/common/mali_gp_scheduler.h    |   44 +
+ drivers/gpu/arm/mali400/mali/common/mali_group.c   | 1803 +++++++++++++++++++
+ drivers/gpu/arm/mali400/mali/common/mali_group.h   |  210 +++
+ drivers/gpu/arm/mali400/mali/common/mali_hw_core.c |   47 +
+ drivers/gpu/arm/mali400/mali/common/mali_hw_core.h |  104 ++
+ .../arm/mali400/mali/common/mali_kernel_common.h   |  186 ++
+ .../gpu/arm/mali400/mali/common/mali_kernel_core.c | 1150 +++++++++++++
+ .../gpu/arm/mali400/mali/common/mali_kernel_core.h |   37 +
+ .../mali/common/mali_kernel_descriptor_mapping.c   |  184 ++
+ .../mali/common/mali_kernel_descriptor_mapping.h   |  101 ++
+ .../arm/mali400/mali/common/mali_kernel_mem_os.c   |  353 ++++
+ .../arm/mali400/mali/common/mali_kernel_mem_os.h   |   37 +
+ .../mali/common/mali_kernel_memory_engine.c        |  375 ++++
+ .../mali/common/mali_kernel_memory_engine.h        |  152 ++
+ .../mali400/mali/common/mali_kernel_utilization.c  |  275 +++
+ .../mali400/mali/common/mali_kernel_utilization.h  |   53 +
+ .../arm/mali400/mali/common/mali_kernel_vsync.c    |   51 +
+ .../gpu/arm/mali400/mali/common/mali_l2_cache.c    |  474 +++++
+ .../gpu/arm/mali400/mali/common/mali_l2_cache.h    |   56 +
+ .../arm/mali400/mali/common/mali_mem_validation.c  |   71 +
+ .../arm/mali400/mali/common/mali_mem_validation.h  |   19 +
+ drivers/gpu/arm/mali400/mali/common/mali_memory.c  | 1297 ++++++++++++++
+ drivers/gpu/arm/mali400/mali/common/mali_memory.h  |   86 +
+ drivers/gpu/arm/mali400/mali/common/mali_mmu.c     |  444 +++++
+ drivers/gpu/arm/mali400/mali/common/mali_mmu.h     |  130 ++
+ .../mali400/mali/common/mali_mmu_page_directory.c  |  522 ++++++
+ .../mali400/mali/common/mali_mmu_page_directory.h  |  100 ++
+ drivers/gpu/arm/mali400/mali/common/mali_osk.h     | 1804 ++++++++++++++++++++
+ .../gpu/arm/mali400/mali/common/mali_osk_bitops.h  |  166 ++
+ .../gpu/arm/mali400/mali/common/mali_osk_list.h    |  183 ++
+ .../gpu/arm/mali400/mali/common/mali_osk_mali.h    |  243 +++
+ .../arm/mali400/mali/common/mali_osk_profiling.h   |  140 ++
+ drivers/gpu/arm/mali400/mali/common/mali_pm.c      |  106 ++
+ drivers/gpu/arm/mali400/mali/common/mali_pm.h      |   36 +
+ drivers/gpu/arm/mali400/mali/common/mali_pmu.c     |  197 +++
+ drivers/gpu/arm/mali400/mali/common/mali_pmu.h     |   70 +
+ drivers/gpu/arm/mali400/mali/common/mali_pp.c      |  515 ++++++
+ drivers/gpu/arm/mali400/mali/common/mali_pp.h      |  103 ++
+ drivers/gpu/arm/mali400/mali/common/mali_pp_job.c  |  137 ++
+ drivers/gpu/arm/mali400/mali/common/mali_pp_job.h  |  313 ++++
+ .../arm/mali400/mali/common/mali_pp_scheduler.c    | 1335 +++++++++++++++
+ .../arm/mali400/mali/common/mali_pp_scheduler.h    |   57 +
+ .../gpu/arm/mali400/mali/common/mali_scheduler.c   |   36 +
+ .../gpu/arm/mali400/mali/common/mali_scheduler.h   |   47 +
+ drivers/gpu/arm/mali400/mali/common/mali_session.c |   47 +
+ drivers/gpu/arm/mali400/mali/common/mali_session.h |   75 +
+ drivers/gpu/arm/mali400/mali/common/mali_ukk.h     |  620 +++++++
+ .../mali400/mali/common/mali_user_settings_db.c    |   88 +
+ .../mali400/mali/common/mali_user_settings_db.h    |   40 +
+ .../mali400/mali/include/linux/mali/mali_utgard.h  |  337 ++++
+ .../mali/include/linux/mali/mali_utgard_counters.h |  264 +++
+ .../mali/include/linux/mali/mali_utgard_ioctl.h    |   88 +
+ .../linux/mali/mali_utgard_profiling_events.h      |  167 ++
+ .../mali/include/linux/mali/mali_utgard_uk_types.h | 1132 ++++++++++++
+ .../mali/linux/license/gpl/mali_kernel_license.h   |   31 +
+ drivers/gpu/arm/mali400/mali/linux/mali_dma_buf.c  |  389 +++++
+ drivers/gpu/arm/mali400/mali/linux/mali_dma_buf.h  |   29 +
+ .../gpu/arm/mali400/mali/linux/mali_kernel_linux.c |  755 ++++++++
+ .../gpu/arm/mali400/mali/linux/mali_kernel_linux.h |   37 +
+ .../gpu/arm/mali400/mali/linux/mali_kernel_sysfs.c | 1442 ++++++++++++++++
+ .../gpu/arm/mali400/mali/linux/mali_kernel_sysfs.h |   30 +
+ .../mali400/mali/linux/mali_linux_pm_testsuite.h   |   32 +
+ .../gpu/arm/mali400/mali/linux/mali_linux_trace.h  |  126 ++
+ .../gpu/arm/mali400/mali/linux/mali_osk_atomics.c  |   55 +
+ drivers/gpu/arm/mali400/mali/linux/mali_osk_irq.c  |  133 ++
+ .../gpu/arm/mali400/mali/linux/mali_osk_locks.c    |  333 ++++
+ .../mali400/mali/linux/mali_osk_low_level_mem.c    |  719 ++++++++
+ drivers/gpu/arm/mali400/mali/linux/mali_osk_mali.c |  110 ++
+ drivers/gpu/arm/mali400/mali/linux/mali_osk_math.c |   22 +
+ .../gpu/arm/mali400/mali/linux/mali_osk_memory.c   |   61 +
+ drivers/gpu/arm/mali400/mali/linux/mali_osk_misc.c |   64 +
+ .../arm/mali400/mali/linux/mali_osk_notification.c |  186 ++
+ drivers/gpu/arm/mali400/mali/linux/mali_osk_pm.c   |  103 ++
+ .../arm/mali400/mali/linux/mali_osk_profiling.c    |  260 +++
+ .../gpu/arm/mali400/mali/linux/mali_osk_specific.h |  148 ++
+ drivers/gpu/arm/mali400/mali/linux/mali_osk_time.c |   51 +
+ .../gpu/arm/mali400/mali/linux/mali_osk_timers.c   |   77 +
+ .../arm/mali400/mali/linux/mali_osk_wait_queue.c   |   73 +
+ drivers/gpu/arm/mali400/mali/linux/mali_osk_wq.c   |  118 ++
+ .../mali400/mali/linux/mali_pmu_power_up_down.c    |   65 +
+ .../arm/mali400/mali/linux/mali_profiling_events.h |   17 +
+ .../mali400/mali/linux/mali_profiling_internal.c   |  300 ++++
+ .../mali400/mali/linux/mali_profiling_internal.h   |   36 +
+ drivers/gpu/arm/mali400/mali/linux/mali_sync.c     |  199 +++
+ drivers/gpu/arm/mali400/mali/linux/mali_sync.h     |   81 +
+ .../gpu/arm/mali400/mali/linux/mali_sync_user.c    |  159 ++
+ drivers/gpu/arm/mali400/mali/linux/mali_uk_types.h |   17 +
+ drivers/gpu/arm/mali400/mali/linux/mali_ukk_core.c |  153 ++
+ drivers/gpu/arm/mali400/mali/linux/mali_ukk_gp.c   |   88 +
+ drivers/gpu/arm/mali400/mali/linux/mali_ukk_mem.c  |  259 +++
+ drivers/gpu/arm/mali400/mali/linux/mali_ukk_pp.c   |   85 +
+ .../arm/mali400/mali/linux/mali_ukk_profiling.c    |  181 ++
+ .../gpu/arm/mali400/mali/linux/mali_ukk_vsync.c    |   41 +
+ .../gpu/arm/mali400/mali/linux/mali_ukk_wrappers.h |   75 +
+ drivers/gpu/arm/mali400/mali/platform/arm/arm.c    |  209 +++
+ .../mali400/mali/platform/default/mali_platform.c  |   41 +
+ .../arm/mali400/mali/platform/exynos4/exynos4.c    |  320 ++++
+ .../mali400/mali/platform/exynos4/exynos4_pmm.c    |  849 +++++++++
+ .../mali400/mali/platform/exynos4/exynos4_pmm.h    |   86 +
+ .../gpu/arm/mali400/mali/platform/mali_platform.h  |  153 ++
+ .../mali400/mali/platform/pegasus-m400/exynos4.c   |  273 +++
+ .../mali/platform/pegasus-m400/exynos4_pmm.c       |  842 +++++++++
+ .../mali/platform/pegasus-m400/exynos4_pmm.h       |   86 +
+ .../arm/mali400/mali/platform/redwood/exynos4.c    |  272 +++
+ .../mali400/mali/platform/redwood/exynos4_pmm.c    | 1010 +++++++++++
+ .../mali400/mali/platform/redwood/exynos4_pmm.h    |   96 ++
+ drivers/gpu/arm/mali400/mali/regs/mali_200_regs.h  |  128 ++
+ drivers/gpu/arm/mali400/mali/regs/mali_gp_regs.h   |  173 ++
+ .../mali/timestamp-arm11-cc/mali_timestamp.c       |   13 +
+ .../mali/timestamp-arm11-cc/mali_timestamp.h       |   48 +
+ .../mali/timestamp-default/mali_timestamp.c        |   13 +
+ .../mali/timestamp-default/mali_timestamp.h        |   26 +
+ drivers/gpu/arm/mali400/ump/Kbuild                 |   76 +
+ drivers/gpu/arm/mali400/ump/Kconfig                |    7 +
+ drivers/gpu/arm/mali400/ump/Makefile               |   67 +
+ drivers/gpu/arm/mali400/ump/Makefile.common        |   20 +
+ .../gpu/arm/mali400/ump/arch-pb-virtex5/config.h   |   18 +
+ .../gpu/arm/mali400/ump/arch-pegasus-m400/config.h |   22 +
+ drivers/gpu/arm/mali400/ump/arch-release/config.h  |   22 +
+ drivers/gpu/arm/mali400/ump/arch/arch-release      |    1 +
+ drivers/gpu/arm/mali400/ump/arch/config.h          |   22 +
+ .../gpu/arm/mali400/ump/common/ump_kernel_api.c    |  580 +++++++
+ .../gpu/arm/mali400/ump/common/ump_kernel_common.c |  416 +++++
+ .../gpu/arm/mali400/ump/common/ump_kernel_common.h |  128 ++
+ .../ump/common/ump_kernel_descriptor_mapping.c     |  166 ++
+ .../ump/common/ump_kernel_descriptor_mapping.h     |   91 +
+ .../mali400/ump/common/ump_kernel_memory_backend.h |   52 +
+ .../arm/mali400/ump/common/ump_kernel_ref_drv.c    |  197 +++
+ .../gpu/arm/mali400/ump/common/ump_kernel_types.h  |   58 +
+ drivers/gpu/arm/mali400/ump/common/ump_osk.h       |   51 +
+ drivers/gpu/arm/mali400/ump/common/ump_ukk.h       |   61 +
+ .../arm/mali400/ump/include/ump_kernel_interface.h |  236 +++
+ .../ump/include/ump_kernel_interface_ref_drv.h     |   35 +
+ .../arm/mali400/ump/include/ump_kernel_platform.h  |   48 +
+ drivers/gpu/arm/mali400/ump/include/ump_uk_types.h |  218 +++
+ .../ump/linux/license/gpl/ump_kernel_license.h     |   31 +
+ drivers/gpu/arm/mali400/ump/linux/ump_ioctl.h      |   62 +
+ .../gpu/arm/mali400/ump/linux/ump_kernel_linux.c   |  454 +++++
+ .../gpu/arm/mali400/ump/linux/ump_kernel_linux.h   |   18 +
+ .../linux/ump_kernel_memory_backend_dedicated.c    |  288 ++++
+ .../linux/ump_kernel_memory_backend_dedicated.h    |   23 +
+ .../ump/linux/ump_kernel_memory_backend_os.c       |  261 +++
+ .../ump/linux/ump_kernel_memory_backend_os.h       |   23 +
+ .../gpu/arm/mali400/ump/linux/ump_memory_backend.c |   78 +
+ .../gpu/arm/mali400/ump/linux/ump_osk_atomics.c    |   27 +
+ .../arm/mali400/ump/linux/ump_osk_low_level_mem.c  |  352 ++++
+ drivers/gpu/arm/mali400/ump/linux/ump_osk_misc.c   |   37 +
+ .../arm/mali400/ump/linux/ump_ukk_ref_wrappers.c   |  254 +++
+ .../arm/mali400/ump/linux/ump_ukk_ref_wrappers.h   |   43 +
+ .../gpu/arm/mali400/ump/linux/ump_ukk_wrappers.c   |  306 ++++
+ .../gpu/arm/mali400/ump/linux/ump_ukk_wrappers.h   |   47 +
+ drivers/video/Kconfig                              |    2 +
+ 174 files changed, 35905 insertions(+)
+ create mode 100644 drivers/gpu/arm/Kconfig
+ create mode 100644 drivers/gpu/arm/mali400/Kconfig
+ create mode 100644 drivers/gpu/arm/mali400/Makefile
+ create mode 100644 drivers/gpu/arm/mali400/mali/Kbuild
+ create mode 100644 drivers/gpu/arm/mali400/mali/Kconfig
+ create mode 100644 drivers/gpu/arm/mali400/mali/MALI_CONFIGURATION
+ create mode 100644 drivers/gpu/arm/mali400/mali/Makefile
+ create mode 100644 drivers/gpu/arm/mali400/mali/__malidrv_build_info.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_block_allocator.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_block_allocator.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_broadcast.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_broadcast.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_device_pause_resume.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_device_pause_resume.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_dlbu.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_dlbu.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_gp.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_gp.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_gp_job.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_gp_job.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_gp_scheduler.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_gp_scheduler.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_group.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_group.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_hw_core.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_hw_core.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_kernel_common.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_kernel_core.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_kernel_core.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_kernel_descriptor_mapping.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_kernel_descriptor_mapping.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_kernel_mem_os.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_kernel_mem_os.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_kernel_memory_engine.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_kernel_memory_engine.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_kernel_utilization.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_kernel_utilization.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_kernel_vsync.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_l2_cache.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_l2_cache.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_mem_validation.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_mem_validation.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_memory.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_memory.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_mmu.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_mmu.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_mmu_page_directory.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_mmu_page_directory.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_osk.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_osk_bitops.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_osk_list.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_osk_mali.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_osk_profiling.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_pm.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_pm.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_pmu.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_pmu.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_pp.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_pp.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_pp_job.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_pp_job.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_pp_scheduler.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_pp_scheduler.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_scheduler.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_scheduler.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_session.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_session.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_ukk.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_user_settings_db.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/common/mali_user_settings_db.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/include/linux/mali/mali_utgard.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/include/linux/mali/mali_utgard_counters.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/include/linux/mali/mali_utgard_ioctl.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/include/linux/mali/mali_utgard_profiling_events.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/include/linux/mali/mali_utgard_uk_types.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/license/gpl/mali_kernel_license.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_dma_buf.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_dma_buf.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_kernel_linux.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_kernel_linux.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_kernel_sysfs.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_kernel_sysfs.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_linux_pm_testsuite.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_linux_trace.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_osk_atomics.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_osk_irq.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_osk_locks.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_osk_low_level_mem.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_osk_mali.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_osk_math.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_osk_memory.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_osk_misc.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_osk_notification.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_osk_pm.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_osk_profiling.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_osk_specific.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_osk_time.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_osk_timers.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_osk_wait_queue.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_osk_wq.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_pmu_power_up_down.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_profiling_events.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_profiling_internal.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_profiling_internal.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_sync.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_sync.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_sync_user.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_uk_types.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_ukk_core.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_ukk_gp.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_ukk_mem.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_ukk_pp.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_ukk_profiling.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_ukk_vsync.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/linux/mali_ukk_wrappers.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/platform/arm/arm.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/platform/default/mali_platform.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4_pmm.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4_pmm.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/platform/mali_platform.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/platform/pegasus-m400/exynos4.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/platform/pegasus-m400/exynos4_pmm.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/platform/pegasus-m400/exynos4_pmm.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/platform/redwood/exynos4.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/platform/redwood/exynos4_pmm.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/platform/redwood/exynos4_pmm.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/regs/mali_200_regs.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/regs/mali_gp_regs.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/timestamp-arm11-cc/mali_timestamp.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/timestamp-arm11-cc/mali_timestamp.h
+ create mode 100644 drivers/gpu/arm/mali400/mali/timestamp-default/mali_timestamp.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/timestamp-default/mali_timestamp.h
+ create mode 100644 drivers/gpu/arm/mali400/ump/Kbuild
+ create mode 100644 drivers/gpu/arm/mali400/ump/Kconfig
+ create mode 100644 drivers/gpu/arm/mali400/ump/Makefile
+ create mode 100644 drivers/gpu/arm/mali400/ump/Makefile.common
+ create mode 100644 drivers/gpu/arm/mali400/ump/arch-pb-virtex5/config.h
+ create mode 100644 drivers/gpu/arm/mali400/ump/arch-pegasus-m400/config.h
+ create mode 100644 drivers/gpu/arm/mali400/ump/arch-release/config.h
+ create mode 120000 drivers/gpu/arm/mali400/ump/arch/arch-release
+ create mode 100644 drivers/gpu/arm/mali400/ump/arch/config.h
+ create mode 100644 drivers/gpu/arm/mali400/ump/common/ump_kernel_api.c
+ create mode 100644 drivers/gpu/arm/mali400/ump/common/ump_kernel_common.c
+ create mode 100644 drivers/gpu/arm/mali400/ump/common/ump_kernel_common.h
+ create mode 100644 drivers/gpu/arm/mali400/ump/common/ump_kernel_descriptor_mapping.c
+ create mode 100644 drivers/gpu/arm/mali400/ump/common/ump_kernel_descriptor_mapping.h
+ create mode 100644 drivers/gpu/arm/mali400/ump/common/ump_kernel_memory_backend.h
+ create mode 100644 drivers/gpu/arm/mali400/ump/common/ump_kernel_ref_drv.c
+ create mode 100644 drivers/gpu/arm/mali400/ump/common/ump_kernel_types.h
+ create mode 100644 drivers/gpu/arm/mali400/ump/common/ump_osk.h
+ create mode 100644 drivers/gpu/arm/mali400/ump/common/ump_ukk.h
+ create mode 100644 drivers/gpu/arm/mali400/ump/include/ump_kernel_interface.h
+ create mode 100644 drivers/gpu/arm/mali400/ump/include/ump_kernel_interface_ref_drv.h
+ create mode 100644 drivers/gpu/arm/mali400/ump/include/ump_kernel_platform.h
+ create mode 100644 drivers/gpu/arm/mali400/ump/include/ump_uk_types.h
+ create mode 100644 drivers/gpu/arm/mali400/ump/linux/license/gpl/ump_kernel_license.h
+ create mode 100644 drivers/gpu/arm/mali400/ump/linux/ump_ioctl.h
+ create mode 100644 drivers/gpu/arm/mali400/ump/linux/ump_kernel_linux.c
+ create mode 100644 drivers/gpu/arm/mali400/ump/linux/ump_kernel_linux.h
+ create mode 100644 drivers/gpu/arm/mali400/ump/linux/ump_kernel_memory_backend_dedicated.c
+ create mode 100644 drivers/gpu/arm/mali400/ump/linux/ump_kernel_memory_backend_dedicated.h
+ create mode 100644 drivers/gpu/arm/mali400/ump/linux/ump_kernel_memory_backend_os.c
+ create mode 100644 drivers/gpu/arm/mali400/ump/linux/ump_kernel_memory_backend_os.h
+ create mode 100644 drivers/gpu/arm/mali400/ump/linux/ump_memory_backend.c
+ create mode 100644 drivers/gpu/arm/mali400/ump/linux/ump_osk_atomics.c
+ create mode 100644 drivers/gpu/arm/mali400/ump/linux/ump_osk_low_level_mem.c
+ create mode 100644 drivers/gpu/arm/mali400/ump/linux/ump_osk_misc.c
+ create mode 100644 drivers/gpu/arm/mali400/ump/linux/ump_ukk_ref_wrappers.c
+ create mode 100644 drivers/gpu/arm/mali400/ump/linux/ump_ukk_ref_wrappers.h
+ create mode 100644 drivers/gpu/arm/mali400/ump/linux/ump_ukk_wrappers.c
+ create mode 100644 drivers/gpu/arm/mali400/ump/linux/ump_ukk_wrappers.h
+
+diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
+index d8a22c2..ed1b5df 100644
+--- a/drivers/gpu/Makefile
++++ b/drivers/gpu/Makefile
+@@ -1,2 +1,4 @@
+ obj-y                 += drm/ vga/
++obj-y                 += arm/mali400/
+ obj-$(CONFIG_TEGRA_HOST1X)    += host1x/
++
+diff --git a/drivers/gpu/arm/Kconfig b/drivers/gpu/arm/Kconfig
+new file mode 100644
+index 0000000..3f33b8f
+--- /dev/null
++++ b/drivers/gpu/arm/Kconfig
+@@ -0,0 +1,17 @@
++#
++# (C) COPYRIGHT 2012 ARM Limited. All rights reserved.
++#
++# This program is free software and is provided to you under the terms of the GNU General Public License version 2
++# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++#
++# A copy of the licence is included with the program, and can also be obtained from Free Software
++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++#
++#
++
++
++menu "ARM GPU Configuration"
++
++source "drivers/gpu/arm/mali400/Kconfig"
++
++endmenu
+diff --git a/drivers/gpu/arm/mali400/Kconfig b/drivers/gpu/arm/mali400/Kconfig
+new file mode 100644
+index 0000000..22fba4a
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/Kconfig
+@@ -0,0 +1,16 @@
++source "drivers/gpu/arm/mali400/mali/Kconfig"
++
++config VIDEO_SAMSUNG
++      bool "Samsung Multimedia Devices"
++      depends on VIDEO_CAPTURE_DRIVERS && VIDEO_V4L2
++      select VIDEO_FIXED_MINOR_RANGES
++      default n
++      help
++        This is a representative video4linux configuration for Samsung multimedia devices.
++
++config VIDEO_SAMSUNG_V4L2
++      bool "V4L2 API for digital camera to be contributed by samsung"
++      depends on VIDEO_DEV && VIDEO_SAMSUNG
++      default n
++      help
++        This feature is for new V4L2 APIs all about digital camera
+diff --git a/drivers/gpu/arm/mali400/Makefile b/drivers/gpu/arm/mali400/Makefile
+new file mode 100644
+index 0000000..ad5fa73
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/Makefile
+@@ -0,0 +1,4 @@
++obj-$(CONFIG_MALI400) += ump/
++obj-$(CONFIG_MALI400) += mali/
++
++EXTRA_CFLAGS += -Idrivers/gpu/arm/mali400
+diff --git a/drivers/gpu/arm/mali400/mali/Kbuild b/drivers/gpu/arm/mali400/mali/Kbuild
+new file mode 100644
+index 0000000..8c6e1f0
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/Kbuild
+@@ -0,0 +1,190 @@
++#
++# Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++#
++# This program is free software and is provided to you under the terms of the GNU General Public License version 2
++# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++#
++# A copy of the licence is included with the program, and can also be obtained from Free Software
++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++#
++
++# This file is called by the Linux build system.
++
++# set up defaults if not defined by the user
++TIMESTAMP ?= default
++OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB ?= 16
++USING_GPU_UTILIZATION ?= 1
++PROFILING_SKIP_PP_JOBS ?= 0
++PROFILING_SKIP_PP_AND_GP_JOBS ?= 0
++MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP ?= 0
++MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED ?= 0
++MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS ?= 0
++MALI_UPPER_HALF_SCHEDULING ?= 1
++# MALI_SEC 
++# Include the mapping between TARGET_PLATFORM and KDIR + MALI_PLATFORM
++TARGET_PLATFORM=redwood
++include $(src)/MALI_CONFIGURATION
++MALI_PLATFORM = $(MALI_PLATFORM-$(TARGET_PLATFORM))
++EXTRA_DEFINES += -DMALI_FAKE_PLATFORM_DEVICE=1
++MALI_PLATFORM_FILES = $(subst $(src)/,,$(wildcard $(src)/platform/$(MALI_PLATFORM)/*.c))
++
++# For customer releases the Linux Device Drivers will be provided as ARM proprietary and GPL releases:
++# The ARM proprietary product will only include the license/proprietary directory
++# The GPL product will only include the license/gpl directory
++ifeq ($(wildcard $(src)/linux/license/gpl/*),)
++    ccflags-y += -I$(src)/linux/license/proprietary
++    ifeq ($(CONFIG_MALI400_PROFILING),y)
++        $(error Profiling is incompatible with non-GPL license)
++    endif
++    ifeq ($(CONFIG_PM_RUNTIME),y)
++        $(error Runtime PM is incompatible with non-GPL license)
++    endif
++    ifeq ($(CONFIG_DMA_SHARED_BUFFER),y)
++        $(error DMA-BUF is incompatible with non-GPL license)
++    endif
++    $(error Linux Device integration is incompatible with non-GPL license)
++else
++    ccflags-y += -I$(src)/linux/license/gpl
++endif
++
++mali-y += \
++      linux/mali_osk_atomics.o \
++      linux/mali_osk_irq.o \
++      linux/mali_osk_wq.o \
++      linux/mali_osk_locks.o \
++      linux/mali_osk_wait_queue.o \
++      linux/mali_osk_low_level_mem.o \
++      linux/mali_osk_math.o \
++      linux/mali_osk_memory.o \
++      linux/mali_osk_misc.o \
++      linux/mali_osk_mali.o \
++      linux/mali_osk_notification.o \
++      linux/mali_osk_time.o \
++      linux/mali_osk_timers.o
++
++mali-y += \
++      linux/mali_ukk_mem.o \
++      linux/mali_ukk_gp.o \
++      linux/mali_ukk_pp.o \
++      linux/mali_ukk_core.o
++
++# Source files which always are included in a build
++mali-y += \
++      common/mali_kernel_core.o \
++      linux/mali_kernel_linux.o \
++      common/mali_kernel_descriptor_mapping.o \
++      common/mali_session.o \
++      common/mali_device_pause_resume.o \
++      common/mali_kernel_vsync.o \
++      linux/mali_ukk_vsync.o \
++      linux/mali_kernel_sysfs.o \
++      common/mali_mmu.o \
++      common/mali_mmu_page_directory.o \
++      common/mali_memory.o \
++      common/mali_kernel_memory_engine.o \
++      common/mali_block_allocator.o \
++      common/mali_kernel_mem_os.o \
++      common/mali_mem_validation.o \
++      common/mali_hw_core.o \
++      common/mali_gp.o \
++      common/mali_pp.o \
++      common/mali_pp_job.o \
++      common/mali_gp_job.o \
++      common/mali_scheduler.o \
++      common/mali_gp_scheduler.o \
++      common/mali_pp_scheduler.o \
++      common/mali_group.o \
++      common/mali_dlbu.o \
++      common/mali_broadcast.o \
++      common/mali_pm.o \
++      common/mali_pmu.o \
++      common/mali_user_settings_db.o \
++      common/mali_kernel_utilization.o \
++      common/mali_l2_cache.o \
++      linux/mali_osk_pm.o \
++      linux/mali_pmu_power_up_down.o \
++      __malidrv_build_info.o
++
++ifneq ($(MALI_PLATFORM_FILES),)
++      mali-y += $(MALI_PLATFORM_FILES:.c=.o)
++endif
++
++mali-$(CONFIG_MALI400_PROFILING) += linux/mali_ukk_profiling.o
++mali-$(CONFIG_MALI400_PROFILING) += linux/mali_osk_profiling.o
++
++mali-$(CONFIG_MALI400_INTERNAL_PROFILING) += linux/mali_profiling_internal.o timestamp-$(TIMESTAMP)/mali_timestamp.o
++ccflags-$(CONFIG_MALI400_INTERNAL_PROFILING) += -I$(src)/timestamp-$(TIMESTAMP)
++
++mali-$(CONFIG_DMA_SHARED_BUFFER) += linux/mali_dma_buf.o
++mali-$(CONFIG_SYNC) += linux/mali_sync.o linux/mali_sync_user.o
++
++# Tell the Linux build system from which .o file to create the kernel module
++obj-$(CONFIG_MALI400) := mali.o
++
++ccflags-y += $(EXTRA_DEFINES)
++
++# Set up our defines, which will be passed to gcc
++ccflags-y += -DPROFILING_SKIP_PP_JOBS=$(PROFILING_SKIP_PP_JOBS)
++ccflags-y += -DPROFILING_SKIP_PP_AND_GP_JOBS=$(PROFILING_SKIP_PP_AND_GP_JOBS)
++
++ccflags-y += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP)
++ccflags-y += -DMALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED=$(MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED)
++ccflags-y += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS)
++ccflags-y += -DMALI_STATE_TRACKING=1
++ccflags-y += -DMALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=$(OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB)
++ccflags-y += -DUSING_GPU_UTILIZATION=$(USING_GPU_UTILIZATION)
++
++ifeq ($(MALI_UPPER_HALF_SCHEDULING),1)
++      ccflags-y += -DMALI_UPPER_HALF_SCHEDULING
++endif
++
++ccflags-$(CONFIG_MALI400_UMP) += -I$(src)/../../ump/include/ump
++ccflags-$(CONFIG_MALI400_DEBUG) += -DDEBUG
++
++# Use our defines when compiling
++ccflags-y += -I$(src) -I$(src)/include -I$(src)/common -I$(src)/linux -I$(src)/platform
++# MALI_SEC 
++ccflags-y += -I$(src)/../ump/include
++
++# Get subversion revision number, fall back to only ${MALI_RELEASE_NAME} if no svn info is available
++MALI_RELEASE_NAME=$(shell cat $(src)/.version 2> /dev/null)
++
++SVN_INFO = (cd $(src); (svn info || git svn info || \
++      echo -e "\nURL: $(MALI_RELEASE_NAME)\n" \
++      "Last Changed Rev: $(MALI_RELEASE_NAME)\n" \
++      "Last Changed Date: $(MALI_RELEASE_NAME)") 2>/dev/null)
++
++SVN_REV := $(shell (cd $(src); echo "$(SVN_INFO)" | grep '^Revision: '| sed -e 's/^Revision: //' ) 2>/dev/null )
++ifeq ($(SVN_REV),)
++SVN_REV := $(MALI_RELEASE_NAME)
++else
++SVN_REV := $(MALI_RELEASE_NAME)-r$(SVN_REV)
++endif
++
++ccflags-y += -DSVN_REV_STRING=\"$(SVN_REV)\"
++
++VERSION_STRINGS :=
++VERSION_STRINGS += API_VERSION=$(shell cd $(src); grep "\#define _MALI_API_VERSION" $(FILES_PREFIX)include/linux/mali/mali_utgard_uk_types.h | cut -d' ' -f 3 )
++VERSION_STRINGS += REPO_URL=$(shell $(SVN_INFO) | grep '^URL: ' | cut -d: -f2- | cut -b2-)
++VERSION_STRINGS += REVISION=$(SVN_REV)
++VERSION_STRINGS += CHANGED_REVISION=$(shell $(SVN_INFO) | grep '^Last Changed Rev: ' | cut -d: -f2- | cut -b2-)
++VERSION_STRINGS += CHANGE_DATE=$(shell $(SVN_INFO) | grep '^Last Changed Date: ' | cut -d: -f2- | cut -b2-)
++VERSION_STRINGS += BUILD_DATE=$(shell date)
++ifdef CONFIG_MALI400_DEBUG
++VERSION_STRINGS += BUILD=debug
++else
++VERSION_STRINGS += BUILD=release
++endif
++VERSION_STRINGS += TARGET_PLATFORM=$(TARGET_PLATFORM)
++VERSION_STRINGS += MALI_PLATFORM=$(MALI_PLATFORM)
++VERSION_STRINGS += KDIR=$(KDIR)
++VERSION_STRINGS += OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=$(OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB)
++VERSION_STRINGS += USING_UMP=$(CONFIG_MALI400_UMP)
++VERSION_STRINGS += USING_PROFILING=$(CONFIG_MALI400_PROFILING)
++VERSION_STRINGS += USING_INTERNAL_PROFILING=$(CONFIG_MALI400_INTERNAL_PROFILING)
++VERSION_STRINGS += USING_GPU_UTILIZATION=$(USING_GPU_UTILIZATION)
++VERSION_STRINGS += MALI_UPPER_HALF_SCHEDULING=$(MALI_UPPER_HALF_SCHEDULING)
++
++# Create file with Mali driver configuration
++$(src)/__malidrv_build_info.c:
++      @echo 'const char *__malidrv_build_info(void) { return "malidrv: $(VERSION_STRINGS)";}' > $(src)/__malidrv_build_info.c
+diff --git a/drivers/gpu/arm/mali400/mali/Kconfig b/drivers/gpu/arm/mali400/mali/Kconfig
+new file mode 100644
+index 0000000..f7d39cc
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/Kconfig
+@@ -0,0 +1,55 @@
++menuconfig MALI400
++      tristate "Mali-300/400/450 support"
++      default n
++      depends on ARM
++      select DMA_SHARED_BUFFER
++      ---help---
++        This enables support for the ARM Mali-300, Mali-400, and Mali-450
++        GPUs.
++
++        To compile this driver as a module, choose M here: the module will be
++        called mali.
++
++config MALI400_DEBUG
++      bool "Enable debug in Mali driver"
++      depends on MALI400
++      ---help---
++        This enabled extra debug checks and messages in the Mali driver.
++
++config MALI400_PROFILING
++      bool "Enable Mali profiling"
++      depends on MALI400
++      select TRACEPOINTS
++      default n
++      ---help---
++        This enables gator profiling of Mali GPU events.
++
++config MALI400_INTERNAL_PROFILING
++      bool "Enable internal Mali profiling API"
++      depends on MALI400_PROFILING
++      default n
++      ---help---
++        This enables the internal legacy Mali profiling API.
++
++config MALI400_UMP
++      bool "Enable UMP support"
++      depends on MALI400
++      default n
++      ---help---
++        This enables support for the UMP memory sharing API in the Mali driver.
++
++source "drivers/gpu/arm/mali400/ump/Kconfig"
++
++config MALI_DVFS
++      bool "Enables mali DVFS"
++      depends on MALI400 && PM
++      default n
++      ---help---
++              This enables Mali driver DVFS.
++
++config SLP_MALI_DBG
++      bool "Enable mali debug"
++      depends on MALI400
++      default y
++      ---help---
++              This enables the panic when mali register is accessed without power on
+diff --git a/drivers/gpu/arm/mali400/mali/MALI_CONFIGURATION b/drivers/gpu/arm/mali400/mali/MALI_CONFIGURATION
+new file mode 100644
+index 0000000..9926768
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/MALI_CONFIGURATION
+@@ -0,0 +1,24 @@
++# Location of default kernels
++KDIR-odroida:=/projects/pr297/linux/odroid-a/current/linux
++KDIR-odroidpc:=/projects/pr297/linux/odroid-pc/current/linux
++KDIR-odroidq:=/projects/pr297/linux/odroid-q/current/linux
++KDIR-orion:=/projects/pr297/linux/orion/current/linux
++KDIR-pegasus:=/projects/pr297/linux/pegasus-smdk/current/linux
++KDIR-tcc8900:=/projects/pr297/linux/tcc8900/current/linux
++KDIR-pb11mp:=/projects/pr297/linux/pb11mp/current/linux
++KDIR-vea9:=/projects/pr297/linux/vea9/current/linux
++KDIR-snowball:=/no/default/kernel/yet
++
++# Name of platform directory with platform specific code (should be built into kernel on a real system) 
++MALI_PLATFORM-odroida=exynos4
++MALI_PLATFORM-odroidpc=exynos4
++MALI_PLATFORM-odroidq=exynos4
++MALI_PLATFORM-orion=exynos4
++MALI_PLATFORM-pegasus=exynos4
++# MALI_SEC 
++MALI_PLATFORM-pegasus-m400=pegasus-m400
++MALI_PLATFORM-redwood=redwood
++MALI_PLATFORM-tcc8900=tcc8900
++MALI_PLATFORM-pb11mp=arm
++MALI_PLATFORM-vea9=arm
++MALI_PLATFORM-snowball=ux500
+diff --git a/drivers/gpu/arm/mali400/mali/Makefile b/drivers/gpu/arm/mali400/mali/Makefile
+new file mode 100644
+index 0000000..9cdfd44
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/Makefile
+@@ -0,0 +1,127 @@
++#
++# Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++#
++# This program is free software and is provided to you under the terms of the GNU General Public License version 2
++# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++#
++# A copy of the licence is included with the program, and can also be obtained from Free Software
++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++#
++
++USE_UMPV2=0
++USING_PROFILING ?= 1
++USING_INTERNAL_PROFILING ?= 0
++
++# The Makefile sets up "arch" based on the CONFIG, creates the version info
++# string and the __malidrv_build_info.c file, and then call the Linux build
++# system to actually build the driver. After that point the Kbuild file takes
++# over.
++
++# set up defaults if not defined by the user
++ARCH ?= arm
++
++OSKOS=linux
++FILES_PREFIX=
++
++check_cc2 = \
++      $(shell if $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; \
++      then \
++              echo "$(2)"; \
++      else \
++              echo "$(3)"; \
++      fi ;)
++
++# This conditional makefile exports the global definition ARM_INTERNAL_BUILD. Customer releases will not include arm_internal.mak
++-include ../../../arm_internal.mak
++
++# Give warning of old config parameters are used
++ifneq ($(CONFIG),)
++$(warning "You have specified the CONFIG variable which is no longer in used. Use TARGET_PLATFORM instead.")
++endif
++
++ifneq ($(CPU),)
++$(warning "You have specified the CPU variable which is no longer in used. Use TARGET_PLATFORM instead.")
++endif
++
++# Include the mapping between TARGET_PLATFORM and KDIR + MALI_PLATFORM
++-include MALI_CONFIGURATION
++export KDIR ?= $(KDIR-$(TARGET_PLATFORM))
++export MALI_PLATFORM ?= $(MALI_PLATFORM-$(TARGET_PLATFORM))
++
++ifneq ($(TARGET_PLATFORM),)
++ifeq ($(MALI_PLATFORM),)
++$(error "Invalid TARGET_PLATFORM: $(TARGET_PLATFORM)")
++endif
++endif
++
++# validate lookup result
++ifeq ($(KDIR),)
++$(error No KDIR found for platform $(TARGET_PLATFORM))
++endif
++
++
++ifeq ($(USING_UMP),1)
++export CONFIG_MALI400_UMP=y
++export EXTRA_DEFINES += -DCONFIG_MALI400_UMP=1
++ifeq ($(USE_UMPV2),1)
++UMP_SYMVERS_FILE ?= ../umpv2/Module.symvers
++else
++UMP_SYMVERS_FILE ?= ../ump/Module.symvers
++endif
++KBUILD_EXTRA_SYMBOLS = $(realpath $(UMP_SYMVERS_FILE))
++$(warning $(KBUILD_EXTRA_SYMBOLS))
++endif
++
++# Define host system directory
++KDIR-$(shell uname -m):=/lib/modules/$(shell uname -r)/build
++
++include $(KDIR)/.config
++
++ifeq ($(ARCH), arm)
++# when compiling for ARM we're cross compiling
++export CROSS_COMPILE ?= $(call check_cc2, arm-linux-gnueabi-gcc, arm-linux-gnueabi-, arm-none-linux-gnueabi-)
++endif
++
++# report detected/selected settings
++ifdef ARM_INTERNAL_BUILD
++$(warning TARGET_PLATFORM $(TARGET_PLATFORM))
++$(warning KDIR $(KDIR))
++$(warning MALI_PLATFORM $(MALI_PLATFORM))
++endif
++
++# Set up build config
++export CONFIG_MALI400=m
++
++ifneq ($(MALI_PLATFORM),)
++export EXTRA_DEFINES += -DMALI_FAKE_PLATFORM_DEVICE=1
++export MALI_PLATFORM_FILES = $(wildcard platform/$(MALI_PLATFORM)/*.c)
++endif
++
++ifeq ($(USING_PROFILING),1)
++ifeq ($(CONFIG_TRACEPOINTS),)
++$(warning CONFIG_TRACEPOINTS reqired for profiling)
++else
++export CONFIG_MALI400_PROFILING=y
++export EXTRA_DEFINES += -DCONFIG_MALI400_PROFILING=1
++ifeq ($(USING_INTERNAL_PROFILING),1)
++export CONFIG_MALI400_INTERNAL_PROFILING=y
++export EXTRA_DEFINES += -DCONFIG_MALI400_INTERNAL_PROFILING=1
++endif
++endif
++endif
++
++ifneq ($(BUILD),release)
++export CONFIG_MALI400_DEBUG=y
++endif
++
++all: $(UMP_SYMVERS_FILE)
++      $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) modules
++      @rm $(FILES_PREFIX)__malidrv_build_info.c $(FILES_PREFIX)__malidrv_build_info.o
++
++clean:
++      $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) clean
++
++kernelrelease:
++      $(MAKE) ARCH=$(ARCH) -C $(KDIR) kernelrelease
++
++export CONFIG KBUILD_EXTRA_SYMBOLS
+diff --git a/drivers/gpu/arm/mali400/mali/__malidrv_build_info.c b/drivers/gpu/arm/mali400/mali/__malidrv_build_info.c
+new file mode 100644
+index 0000000..ed3062f
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/__malidrv_build_info.c
+@@ -0,0 +1 @@
++const char *__malidrv_build_info(void) { return "malidrv:  API_VERSION=19 REPO_URL=r3p2-01rel0 REVISION=r3p2-01rel0 CHANGED_REVISION= CHANGE_DATE= BUILD_DATE=Mon Dec 17 14:01:05 KST 2012 BUILD=release TARGET_PLATFORM=pegasus-m400 MALI_PLATFORM=pegasus-m400 KDIR= OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=16 USING_UMP=y USING_PROFILING= USING_INTERNAL_PROFILING= USING_GPU_UTILIZATION=1 MALI_UPPER_HALF_SCHEDULING=1";}
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_block_allocator.c b/drivers/gpu/arm/mali400/mali/common/mali_block_allocator.c
+new file mode 100644
+index 0000000..3f9a692
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_block_allocator.c
+@@ -0,0 +1,390 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++#include "mali_kernel_common.h"
++#include "mali_kernel_memory_engine.h"
++#include "mali_block_allocator.h"
++#include "mali_osk.h"
++
++#define MALI_BLOCK_SIZE (256UL * 1024UL)  /* 256 kB, remember to keep the ()s */
++
++typedef struct block_info
++{
++      struct block_info * next;
++} block_info;
++
++/* The structure used as the handle produced by block_allocator_allocate,
++ * and removed by block_allocator_release */
++typedef struct block_allocator_allocation
++{
++      /* The list will be released in reverse order */
++      block_info *last_allocated;
++      mali_allocation_engine * engine;
++      mali_memory_allocation * descriptor;
++      u32 start_offset;
++      u32 mapping_length;
++} block_allocator_allocation;
++
++
++typedef struct block_allocator
++{
++    _mali_osk_lock_t *mutex;
++      block_info * all_blocks;
++      block_info * first_free;
++      u32 base;
++      u32 cpu_usage_adjust;
++      u32 num_blocks;
++} block_allocator;
++
++MALI_STATIC_INLINE u32 get_phys(block_allocator * info, block_info * block);
++static mali_physical_memory_allocation_result block_allocator_allocate(void* ctx, mali_allocation_engine * engine,  mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info);
++static void block_allocator_release(void * ctx, void * handle);
++static mali_physical_memory_allocation_result block_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block);
++static void block_allocator_release_page_table_block( mali_page_table_block *page_table_block );
++static void block_allocator_destroy(mali_physical_memory_allocator * allocator);
++static u32 block_allocator_stat(mali_physical_memory_allocator * allocator);
++
++mali_physical_memory_allocator * mali_block_allocator_create(u32 base_address, u32 cpu_usage_adjust, u32 size, const char *name)
++{
++      mali_physical_memory_allocator * allocator;
++      block_allocator * info;
++      u32 usable_size;
++      u32 num_blocks;
++
++      usable_size = size & ~(MALI_BLOCK_SIZE - 1);
++      MALI_DEBUG_PRINT(3, ("Mali block allocator create for region starting at 0x%08X length 0x%08X\n", base_address, size));
++      MALI_DEBUG_PRINT(4, ("%d usable bytes\n", usable_size));
++      num_blocks = usable_size / MALI_BLOCK_SIZE;
++      MALI_DEBUG_PRINT(4, ("which becomes %d blocks\n", num_blocks));
++
++      if (usable_size == 0)
++      {
++              MALI_DEBUG_PRINT(1, ("Memory block of size %d is unusable\n", size));
++              return NULL;
++      }
++
++      allocator = _mali_osk_malloc(sizeof(mali_physical_memory_allocator));
++      if (NULL != allocator)
++      {
++              info = _mali_osk_malloc(sizeof(block_allocator));
++              if (NULL != info)
++              {
++            info->mutex = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED, 0, _MALI_OSK_LOCK_ORDER_MEM_INFO);
++            if (NULL != info->mutex)
++            {
++                      info->all_blocks = _mali_osk_malloc(sizeof(block_info) * num_blocks);
++                          if (NULL != info->all_blocks)
++                          {
++                                  u32 i;
++                                  info->first_free = NULL;
++                                  info->num_blocks = num_blocks;
++
++                                  info->base = base_address;
++                                  info->cpu_usage_adjust = cpu_usage_adjust;
++
++                                  for ( i = 0; i < num_blocks; i++)
++                                  {
++                                          info->all_blocks[i].next = info->first_free;
++                                          info->first_free = &info->all_blocks[i];
++                                  }
++
++                                  allocator->allocate = block_allocator_allocate;
++                                  allocator->allocate_page_table_block = block_allocator_allocate_page_table_block;
++                                  allocator->destroy = block_allocator_destroy;
++                                  allocator->stat = block_allocator_stat;
++                                  allocator->ctx = info;
++                                      allocator->name = name;
++
++                                  return allocator;
++                          }
++                _mali_osk_lock_term(info->mutex);
++            }
++                      _mali_osk_free(info);
++              }
++              _mali_osk_free(allocator);
++      }
++
++      return NULL;
++}
++
++static void block_allocator_destroy(mali_physical_memory_allocator * allocator)
++{
++      block_allocator * info;
++      MALI_DEBUG_ASSERT_POINTER(allocator);
++      MALI_DEBUG_ASSERT_POINTER(allocator->ctx);
++      info = (block_allocator*)allocator->ctx;
++
++      _mali_osk_free(info->all_blocks);
++    _mali_osk_lock_term(info->mutex);
++      _mali_osk_free(info);
++      _mali_osk_free(allocator);
++}
++
++MALI_STATIC_INLINE u32 get_phys(block_allocator * info, block_info * block)
++{
++      return info->base + ((block - info->all_blocks) * MALI_BLOCK_SIZE);
++}
++
++static mali_physical_memory_allocation_result block_allocator_allocate(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info)
++{
++      block_allocator * info;
++      u32 left;
++      block_info * last_allocated = NULL;
++      mali_physical_memory_allocation_result result = MALI_MEM_ALLOC_NONE;
++      block_allocator_allocation *ret_allocation;
++
++      MALI_DEBUG_ASSERT_POINTER(ctx);
++      MALI_DEBUG_ASSERT_POINTER(descriptor);
++      MALI_DEBUG_ASSERT_POINTER(offset);
++      MALI_DEBUG_ASSERT_POINTER(alloc_info);
++
++      info = (block_allocator*)ctx;
++      left = descriptor->size - *offset;
++      MALI_DEBUG_ASSERT(0 != left);
++
++      if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) return MALI_MEM_ALLOC_INTERNAL_FAILURE;
++
++      ret_allocation = _mali_osk_malloc( sizeof(block_allocator_allocation) );
++
++      if ( NULL == ret_allocation )
++      {
++              /* Failure; try another allocator by returning MALI_MEM_ALLOC_NONE */
++              _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
++              return result;
++      }
++
++      ret_allocation->start_offset = *offset;
++      ret_allocation->mapping_length = 0;
++
++      while ((left > 0) && (info->first_free))
++      {
++              block_info * block;
++              u32 phys_addr;
++              u32 padding;
++              u32 current_mapping_size;
++
++              block = info->first_free;
++              info->first_free = info->first_free->next;
++              block->next = last_allocated;
++              last_allocated = block;
++
++              phys_addr = get_phys(info, block);
++
++              padding = *offset & (MALI_BLOCK_SIZE-1);
++
++              if (MALI_BLOCK_SIZE - padding < left)
++              {
++                      current_mapping_size = MALI_BLOCK_SIZE - padding;
++              }
++              else
++              {
++                      current_mapping_size = left;
++              }
++
++              if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, phys_addr + padding, info->cpu_usage_adjust, current_mapping_size))
++              {
++                      MALI_DEBUG_PRINT(1, ("Mapping of physical memory  failed\n"));
++                      result = MALI_MEM_ALLOC_INTERNAL_FAILURE;
++                      mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->start_offset, ret_allocation->mapping_length, (_mali_osk_mem_mapregion_flags_t)0);
++
++                      /* release all memory back to the pool */
++                      while (last_allocated)
++                      {
++                              /* This relinks every block we've just allocated back into the free-list */
++                              block = last_allocated->next;
++                              last_allocated->next = info->first_free;
++                              info->first_free = last_allocated;
++                              last_allocated = block;
++                      }
++
++                      break;
++              }
++
++              *offset += current_mapping_size;
++              left -= current_mapping_size;
++              ret_allocation->mapping_length += current_mapping_size;
++      }
++
++      _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
++
++      if (last_allocated)
++      {
++              if (left) result = MALI_MEM_ALLOC_PARTIAL;
++              else result = MALI_MEM_ALLOC_FINISHED;
++
++              /* Record all the information about this allocation */
++              ret_allocation->last_allocated = last_allocated;
++              ret_allocation->engine = engine;
++              ret_allocation->descriptor = descriptor;
++
++              alloc_info->ctx = info;
++              alloc_info->handle = ret_allocation;
++              alloc_info->release = block_allocator_release;
++      }
++      else
++      {
++              /* Free the allocation information - nothing to be passed back */
++              _mali_osk_free( ret_allocation );
++      }
++
++      return result;
++}
++
++static void block_allocator_release(void * ctx, void * handle)
++{
++      block_allocator * info;
++      block_info * block, * next;
++      block_allocator_allocation *allocation;
++
++      MALI_DEBUG_ASSERT_POINTER(ctx);
++      MALI_DEBUG_ASSERT_POINTER(handle);
++
++      info = (block_allocator*)ctx;
++      allocation = (block_allocator_allocation*)handle;
++      block = allocation->last_allocated;
++
++      MALI_DEBUG_ASSERT_POINTER(block);
++
++      if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW))
++      {
++              MALI_DEBUG_PRINT(1, ("allocator release: Failed to get mutex\n"));
++              return;
++      }
++
++      /* unmap */
++      mali_allocation_engine_unmap_physical(allocation->engine, allocation->descriptor, allocation->start_offset, allocation->mapping_length, (_mali_osk_mem_mapregion_flags_t)0);
++
++      while (block)
++      {
++              MALI_DEBUG_ASSERT(!((block < info->all_blocks) || (block > (info->all_blocks + info->num_blocks))));
++
++              next = block->next;
++
++              /* relink into free-list */
++              block->next = info->first_free;
++              info->first_free = block;
++
++              /* advance the loop */
++              block = next;
++      }
++
++      _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
++
++      _mali_osk_free( allocation );
++}
++
++
++static mali_physical_memory_allocation_result block_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block)
++{
++      block_allocator * info;
++      mali_physical_memory_allocation_result result = MALI_MEM_ALLOC_INTERNAL_FAILURE;
++
++      MALI_DEBUG_ASSERT_POINTER(ctx);
++      MALI_DEBUG_ASSERT_POINTER(block);
++      info = (block_allocator*)ctx;
++
++      if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) return MALI_MEM_ALLOC_INTERNAL_FAILURE;
++
++      if (NULL != info->first_free)
++      {
++              void * virt;
++              u32 phys;
++              u32 size;
++              block_info * alloc;
++              alloc = info->first_free;
++
++              phys = get_phys(info, alloc); /* Does not modify info or alloc */
++              size = MALI_BLOCK_SIZE; /* Must be multiple of MALI_MMU_PAGE_SIZE */
++              virt = _mali_osk_mem_mapioregion( phys, size, "Mali block allocator page tables" );
++
++              /* Failure of _mali_osk_mem_mapioregion will result in MALI_MEM_ALLOC_INTERNAL_FAILURE,
++               * because it's unlikely another allocator will be able to map in. */
++
++              if ( NULL != virt )
++              {
++                      block->ctx = info; /* same as incoming ctx */
++                      block->handle = alloc;
++                      block->phys_base = phys;
++                      block->size = size;
++                      block->release = block_allocator_release_page_table_block;
++                      block->mapping = virt;
++
++                      info->first_free = alloc->next;
++
++                      alloc->next = NULL; /* Could potentially link many blocks together instead */
++
++                      result = MALI_MEM_ALLOC_FINISHED;
++              }
++      }
++      else result = MALI_MEM_ALLOC_NONE;
++
++      _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
++
++      return result;
++}
++
++
++static void block_allocator_release_page_table_block( mali_page_table_block *page_table_block )
++{
++      block_allocator * info;
++      block_info * block, * next;
++
++      MALI_DEBUG_ASSERT_POINTER( page_table_block );
++
++      info = (block_allocator*)page_table_block->ctx;
++      block = (block_info*)page_table_block->handle;
++
++      MALI_DEBUG_ASSERT_POINTER(info);
++      MALI_DEBUG_ASSERT_POINTER(block);
++
++
++      if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW))
++      {
++              MALI_DEBUG_PRINT(1, ("allocator release: Failed to get mutex\n"));
++              return;
++      }
++
++      /* Unmap all the physical memory at once */
++      _mali_osk_mem_unmapioregion( page_table_block->phys_base, page_table_block->size, page_table_block->mapping );
++
++      /** @note This loop handles the case where more than one block_info was linked.
++       * Probably unnecessary for page table block releasing. */
++      while (block)
++      {
++              next = block->next;
++
++              MALI_DEBUG_ASSERT(!((block < info->all_blocks) || (block > (info->all_blocks + info->num_blocks))));
++
++              block->next = info->first_free;
++              info->first_free = block;
++
++              block = next;
++      }
++
++      _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
++}
++
++static u32 block_allocator_stat(mali_physical_memory_allocator * allocator)
++{
++      block_allocator * info;
++      block_info *block;
++      u32 free_blocks = 0;
++
++      MALI_DEBUG_ASSERT_POINTER(allocator);
++
++      info = (block_allocator*)allocator->ctx;
++      block = info->first_free;
++
++      while(block)
++      {
++              free_blocks++;
++              block = block->next;
++      }
++      return (info->num_blocks - free_blocks) * MALI_BLOCK_SIZE;
++}
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_block_allocator.h b/drivers/gpu/arm/mali400/mali/common/mali_block_allocator.h
+new file mode 100644
+index 0000000..9978271
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_block_allocator.h
+@@ -0,0 +1,18 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_BLOCK_ALLOCATOR_H__
++#define __MALI_BLOCK_ALLOCATOR_H__
++
++#include "mali_kernel_memory_engine.h"
++
++mali_physical_memory_allocator * mali_block_allocator_create(u32 base_address, u32 cpu_usage_adjust, u32 size, const char *name);
++
++#endif /* __MALI_BLOCK_ALLOCATOR_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_broadcast.c b/drivers/gpu/arm/mali400/mali/common/mali_broadcast.c
+new file mode 100644
+index 0000000..450c903
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_broadcast.c
+@@ -0,0 +1,117 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_broadcast.h"
++#include "mali_kernel_common.h"
++#include "mali_osk.h"
++
++static const int bcast_unit_reg_size = 0x1000;
++static const int bcast_unit_addr_broadcast_mask = 0x0;
++static const int bcast_unit_addr_irq_override_mask = 0x4;
++
++struct mali_bcast_unit
++{
++      struct mali_hw_core hw_core;
++      u32 current_mask;
++};
++
++struct mali_bcast_unit *mali_bcast_unit_create(const _mali_osk_resource_t *resource)
++{
++      struct mali_bcast_unit *bcast_unit = NULL;
++
++      MALI_DEBUG_ASSERT_POINTER(resource);
++      MALI_DEBUG_PRINT(2, ("Mali Broadcast unit: Creating Mali Broadcast unit: %s\n", resource->description));
++
++      bcast_unit = _mali_osk_malloc(sizeof(struct mali_bcast_unit));
++      if (NULL == bcast_unit)
++      {
++              return NULL;
++      }
++
++      if (_MALI_OSK_ERR_OK == mali_hw_core_create(&bcast_unit->hw_core, resource, bcast_unit_reg_size))
++      {
++              bcast_unit->current_mask = 0;
++              mali_bcast_reset(bcast_unit);
++
++              return bcast_unit;
++      }
++      else
++      {
++              MALI_PRINT_ERROR(("Mali Broadcast unit: Failed to allocate memory for Broadcast unit\n"));
++      }
++
++      return NULL;
++}
++
++void mali_bcast_unit_delete(struct mali_bcast_unit *bcast_unit)
++{
++      MALI_DEBUG_ASSERT_POINTER(bcast_unit);
++
++      mali_hw_core_delete(&bcast_unit->hw_core);
++      _mali_osk_free(bcast_unit);
++}
++
++void mali_bcast_add_group(struct mali_bcast_unit *bcast_unit, struct mali_group *group)
++{
++      u32 core_id;
++      u32 broadcast_mask;
++
++      MALI_DEBUG_ASSERT_POINTER(bcast_unit);
++      MALI_DEBUG_ASSERT_POINTER(group);
++
++      core_id = mali_pp_core_get_id(mali_group_get_pp_core(group));
++      broadcast_mask = bcast_unit->current_mask;
++
++      /* set the bit corresponding to the group's core's id to 1 */
++      core_id = 1 << core_id;
++      broadcast_mask |= (core_id); /* add PP core to broadcast */
++      broadcast_mask |= (core_id << 16); /* add MMU to broadcast */
++
++      /* store mask so we can restore on reset */
++      bcast_unit->current_mask = broadcast_mask;
++
++      mali_bcast_reset(bcast_unit);
++}
++
++void mali_bcast_remove_group(struct mali_bcast_unit *bcast_unit, struct mali_group *group)
++{
++      u32 core_id;
++      u32 broadcast_mask;
++
++      MALI_DEBUG_ASSERT_POINTER(bcast_unit);
++      MALI_DEBUG_ASSERT_POINTER(group);
++
++      core_id = mali_pp_core_get_id(mali_group_get_pp_core(group));
++      broadcast_mask = bcast_unit->current_mask;
++
++      /* set the bit corresponding to the group's core's id to 0 */
++      core_id = 1 << core_id;
++      broadcast_mask &= ~((core_id << 16) | core_id);
++
++      /* store mask so we can restore on reset */
++      bcast_unit->current_mask = broadcast_mask;
++
++      mali_bcast_reset(bcast_unit);
++}
++
++void mali_bcast_reset(struct mali_bcast_unit *bcast_unit)
++{
++      MALI_DEBUG_ASSERT_POINTER(bcast_unit);
++
++      /* set broadcast mask */
++      mali_hw_core_register_write(&bcast_unit->hw_core,
++                                  bcast_unit_addr_broadcast_mask,
++                                  bcast_unit->current_mask);
++
++      /* set IRQ override mask */
++      mali_hw_core_register_write(&bcast_unit->hw_core,
++                                  bcast_unit_addr_irq_override_mask,
++                                  bcast_unit->current_mask & 0xFF);
++}
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_broadcast.h b/drivers/gpu/arm/mali400/mali/common/mali_broadcast.h
+new file mode 100644
+index 0000000..a6ccde5
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_broadcast.h
+@@ -0,0 +1,34 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/*
++ *  Interface for the broadcast unit on Mali-450.
++ *
++ * - Represents up to 8 ¡¿ (MMU + PP) pairs.
++ * - Supports dynamically changing which (MMU + PP) pairs receive the broadcast by
++ *   setting a mask.
++ */
++
++#include "mali_hw_core.h"
++#include "mali_group.h"
++
++struct mali_bcast_unit;
++
++struct mali_bcast_unit *mali_bcast_unit_create(const _mali_osk_resource_t *resource);
++void mali_bcast_unit_delete(struct mali_bcast_unit *bcast_unit);
++
++/* Add a group to the list of (MMU + PP) pairs broadcasts go out to. */
++void mali_bcast_add_group(struct mali_bcast_unit *bcast_unit, struct mali_group *group);
++
++/* Remove a group to the list of (MMU + PP) pairs broadcasts go out to. */
++void mali_bcast_remove_group(struct mali_bcast_unit *bcast_unit, struct mali_group *group);
++
++/* Re-set cached mask. This needs to be called after having been suspended. */
++void mali_bcast_reset(struct mali_bcast_unit *bcast_unit);
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_device_pause_resume.c b/drivers/gpu/arm/mali400/mali/common/mali_device_pause_resume.c
+new file mode 100644
+index 0000000..74c545f
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_device_pause_resume.c
+@@ -0,0 +1,42 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_device_pause_resume.c
++ * Implementation of the Mali pause/resume functionality
++ */
++
++#include "mali_gp_scheduler.h"
++#include "mali_pp_scheduler.h"
++#include "mali_group.h"
++
++void mali_dev_pause(mali_bool *power_is_on)
++{
++      mali_bool power_is_on_tmp;
++
++      /* Locking the current power state - so it will not switch from being ON to OFF, but it might remain OFF */
++      power_is_on_tmp = _mali_osk_pm_dev_ref_add_no_power_on();
++      if (NULL != power_is_on)
++      {
++              *power_is_on = power_is_on_tmp;
++      }
++
++      mali_gp_scheduler_suspend();
++      mali_pp_scheduler_suspend();
++}
++
++void mali_dev_resume(void)
++{
++      mali_gp_scheduler_resume();
++      mali_pp_scheduler_resume();
++
++      /* Release our PM reference, as it is now safe to turn of the GPU again */
++      _mali_osk_pm_dev_ref_dec_no_power_on();
++}
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_device_pause_resume.h b/drivers/gpu/arm/mali400/mali/common/mali_device_pause_resume.h
+new file mode 100644
+index 0000000..86b30c4
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_device_pause_resume.h
+@@ -0,0 +1,31 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_DEVICE_PAUSE_RESUME_H__
++#define __MALI_DEVICE_PAUSE_RESUME_H__
++
++#include "mali_osk.h"
++
++/**
++ * Pause the scheduling and power state changes of Mali device driver.
++ * mali_dev_resume() must always be called as soon as possible after this function
++ * in order to resume normal operation of the Mali driver.
++ *
++ * @param power_is_on Receives the power current status of Mali GPU. MALI_TRUE if GPU is powered on
++ */
++void mali_dev_pause(mali_bool *power_is_on);
++
++/**
++ * Resume scheduling and allow power changes in Mali device driver.
++ * This must always be called after mali_dev_pause().
++ */
++void mali_dev_resume(void);
++
++#endif /* __MALI_DEVICE_PAUSE_RESUME_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_dlbu.c b/drivers/gpu/arm/mali400/mali/common/mali_dlbu.c
+new file mode 100644
+index 0000000..b75c75c
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_dlbu.c
+@@ -0,0 +1,214 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_dlbu.h"
++#include "mali_memory.h"
++#include "mali_pp.h"
++#include "mali_group.h"
++#include "mali_osk.h"
++#include "mali_hw_core.h"
++
++/**
++ * Size of DLBU registers in bytes
++ */
++#define MALI_DLBU_SIZE 0x400
++
++u32 mali_dlbu_phys_addr = 0;
++static mali_io_address mali_dlbu_cpu_addr = 0;
++
++/**
++ * DLBU register numbers
++ * Used in the register read/write routines.
++ * See the hardware documentation for more information about each register
++ */
++typedef enum mali_dlbu_register {
++      MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR = 0x0000, /**< Master tile list physical base address;
++                                                           31:12 Physical address to the page used for the DLBU
++                                                           0 DLBU enable - set this bit to 1 enables the AXI bus
++                                                           between PPs and L2s, setting to 0 disables the router and
++                                                           no further transactions are sent to DLBU */
++      MALI_DLBU_REGISTER_MASTER_TLLIST_VADDR     = 0x0004, /**< Master tile list virtual base address;
++                                                           31:12 Virtual address to the page used for the DLBU */
++      MALI_DLBU_REGISTER_TLLIST_VBASEADDR        = 0x0008, /**< Tile list virtual base address;
++                                                           31:12 Virtual address to the tile list. This address is used when
++                                                           calculating the call address sent to PP.*/
++      MALI_DLBU_REGISTER_FB_DIM                  = 0x000C, /**< Framebuffer dimension;
++                                                           23:16 Number of tiles in Y direction-1
++                                                           7:0 Number of tiles in X direction-1 */
++      MALI_DLBU_REGISTER_TLLIST_CONF             = 0x0010, /**< Tile list configuration;
++                                                           29:28 select the size of each allocated block: 0=128 bytes, 1=256, 2=512, 3=1024
++                                                           21:16 2^n number of tiles to be binned to one tile list in Y direction
++                                                           5:0 2^n number of tiles to be binned to one tile list in X direction */
++      MALI_DLBU_REGISTER_START_TILE_POS          = 0x0014, /**< Start tile positions;
++                                                           31:24 start position in Y direction for group 1
++                                                           23:16 start position in X direction for group 1
++                                                           15:8 start position in Y direction for group 0
++                                                           7:0 start position in X direction for group 0 */
++      MALI_DLBU_REGISTER_PP_ENABLE_MASK          = 0x0018, /**< PP enable mask;
++                                                           7 enable PP7 for load balancing
++                                                           6 enable PP6 for load balancing
++                                                           5 enable PP5 for load balancing
++                                                           4 enable PP4 for load balancing
++                                                           3 enable PP3 for load balancing
++                                                           2 enable PP2 for load balancing
++                                                           1 enable PP1 for load balancing
++                                                           0 enable PP0 for load balancing */
++} mali_dlbu_register;
++
++typedef enum
++{
++      PP0ENABLE = 0,
++      PP1ENABLE,
++      PP2ENABLE,
++      PP3ENABLE,
++      PP4ENABLE,
++      PP5ENABLE,
++      PP6ENABLE,
++      PP7ENABLE
++} mali_dlbu_pp_enable;
++
++struct mali_dlbu_core
++{
++      struct mali_hw_core     hw_core;           /**< Common for all HW cores */
++      u32                     pp_cores_mask;     /**< This is a mask for the PP cores whose operation will be controlled by LBU
++                                                    see MALI_DLBU_REGISTER_PP_ENABLE_MASK register */
++};
++
++_mali_osk_errcode_t mali_dlbu_initialize(void)
++{
++
++      MALI_DEBUG_PRINT(2, ("Mali DLBU: Initializing\n"));
++
++      if (_MALI_OSK_ERR_OK == mali_mmu_get_table_page(&mali_dlbu_phys_addr, &mali_dlbu_cpu_addr))
++      {
++              MALI_SUCCESS;
++      }
++
++      return _MALI_OSK_ERR_FAULT;
++}
++
++void mali_dlbu_terminate(void)
++{
++      MALI_DEBUG_PRINT(3, ("Mali DLBU: terminating\n"));
++
++      mali_mmu_release_table_page(mali_dlbu_phys_addr);
++}
++
++struct mali_dlbu_core *mali_dlbu_create(const _mali_osk_resource_t * resource)
++{
++      struct mali_dlbu_core *core = NULL;
++
++      MALI_DEBUG_PRINT(2, ("Mali DLBU: Creating Mali dynamic load balancing unit: %s\n", resource->description));
++
++      core = _mali_osk_malloc(sizeof(struct mali_dlbu_core));
++      if (NULL != core)
++      {
++              if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALI_DLBU_SIZE))
++              {
++                      core->pp_cores_mask = 0;
++                      if (_MALI_OSK_ERR_OK == mali_dlbu_reset(core))
++                      {
++                              return core;
++                      }
++                      MALI_PRINT_ERROR(("Failed to reset DLBU %s\n", core->hw_core.description));
++                      mali_hw_core_delete(&core->hw_core);
++              }
++
++              _mali_osk_free(core);
++      }
++      else
++      {
++              MALI_PRINT_ERROR(("Mali DLBU: Failed to allocate memory for DLBU core\n"));
++      }
++
++      return NULL;
++}
++
++void mali_dlbu_delete(struct mali_dlbu_core *dlbu)
++{
++      MALI_DEBUG_ASSERT_POINTER(dlbu);
++
++      mali_dlbu_reset(dlbu);
++      mali_hw_core_delete(&dlbu->hw_core);
++      _mali_osk_free(dlbu);
++}
++
++_mali_osk_errcode_t mali_dlbu_reset(struct mali_dlbu_core *dlbu)
++{
++      u32 dlbu_registers[7];
++      _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
++      MALI_DEBUG_ASSERT_POINTER(dlbu);
++
++      MALI_DEBUG_PRINT(4, ("Mali DLBU: mali_dlbu_reset: %s\n", dlbu->hw_core.description));
++
++      dlbu_registers[0] = mali_dlbu_phys_addr | 1; /* bit 0 enables the whole core */
++      dlbu_registers[1] = MALI_DLBU_VIRT_ADDR;
++      dlbu_registers[2] = 0;
++      dlbu_registers[3] = 0;
++      dlbu_registers[4] = 0;
++      dlbu_registers[5] = 0;
++      dlbu_registers[6] = dlbu->pp_cores_mask;
++
++      /* write reset values to core registers */
++      mali_hw_core_register_write_array_relaxed(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR, dlbu_registers, 7);
++
++      err = _MALI_OSK_ERR_OK;
++
++      return err;
++}
++
++void mali_dlbu_add_group(struct mali_dlbu_core *dlbu, struct mali_group *group)
++{
++      struct mali_pp_core *pp_core;
++      u32 core_id;
++
++      MALI_DEBUG_ASSERT_POINTER( dlbu );
++      MALI_DEBUG_ASSERT_POINTER( group );
++
++      pp_core = mali_group_get_pp_core(group);
++      core_id = mali_pp_core_get_id(pp_core);
++
++      dlbu->pp_cores_mask |= (0x1 << core_id);
++      MALI_DEBUG_PRINT(3, ("Mali DLBU: Adding core[%d] New mask= 0x%02x\n",core_id , dlbu->pp_cores_mask));
++
++      mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, dlbu->pp_cores_mask);
++}
++
++/* Remove a group from the DLBU */
++void mali_dlbu_remove_group(struct mali_dlbu_core *dlbu, struct mali_group *group)
++{
++      struct mali_pp_core *pp_core;
++      u32 core_id;
++
++      MALI_DEBUG_ASSERT_POINTER( dlbu );
++      MALI_DEBUG_ASSERT_POINTER( group );
++
++      pp_core = mali_group_get_pp_core(group);
++      core_id = mali_pp_core_get_id(pp_core);
++
++      dlbu->pp_cores_mask &= ~(0x1 << core_id);
++              MALI_DEBUG_PRINT(3, ("Mali DLBU: Removing core[%d] New mask= 0x%02x\n", core_id, dlbu->pp_cores_mask));
++
++      mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, dlbu->pp_cores_mask);
++}
++
++/* Configure the DLBU for \a job. This needs to be done before the job is started on the groups in the DLBU. */
++void mali_dlbu_config_job(struct mali_dlbu_core *dlbu, struct mali_pp_job *job)
++{
++      u32 *registers;
++      MALI_DEBUG_ASSERT(job);
++      registers = mali_pp_job_get_dlbu_registers(job);
++      MALI_DEBUG_PRINT(4, ("Mali DLBU: Starting job\n"));
++
++      /* Writing 4 registers:
++       * DLBU registers except the first two (written once at DLBU initialisation / reset) and the PP_ENABLE_MASK register */
++      mali_hw_core_register_write_array_relaxed(&dlbu->hw_core, MALI_DLBU_REGISTER_TLLIST_VBASEADDR, registers, 4);
++
++}
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_dlbu.h b/drivers/gpu/arm/mali400/mali/common/mali_dlbu.h
+new file mode 100644
+index 0000000..dfb86d5
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_dlbu.h
+@@ -0,0 +1,38 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_DLBU_H__
++#define __MALI_DLBU_H__
++
++#define MALI_DLBU_VIRT_ADDR 0xFFF00000 /* master tile virtual address fixed at this value and mapped into every session */
++
++#include "mali_osk.h"
++
++struct mali_pp_job;
++struct mali_group;
++
++extern u32 mali_dlbu_phys_addr;
++
++struct mali_dlbu_core;
++
++_mali_osk_errcode_t mali_dlbu_initialize(void);
++void mali_dlbu_terminate(void);
++
++struct mali_dlbu_core *mali_dlbu_create(const _mali_osk_resource_t * resource);
++void mali_dlbu_delete(struct mali_dlbu_core *dlbu);
++
++_mali_osk_errcode_t mali_dlbu_reset(struct mali_dlbu_core *dlbu);
++
++void mali_dlbu_add_group(struct mali_dlbu_core *dlbu, struct mali_group *group);
++void mali_dlbu_remove_group(struct mali_dlbu_core *dlbu, struct mali_group *group);
++
++void mali_dlbu_config_job(struct mali_dlbu_core *dlbu, struct mali_pp_job *job);
++
++#endif /* __MALI_DLBU_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_gp.c b/drivers/gpu/arm/mali400/mali/common/mali_gp.c
+new file mode 100644
+index 0000000..92ede3f
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_gp.c
+@@ -0,0 +1,364 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_gp.h"
++#include "mali_hw_core.h"
++#include "mali_group.h"
++#include "mali_osk.h"
++#include "regs/mali_gp_regs.h"
++#include "mali_kernel_common.h"
++#include "mali_kernel_core.h"
++#if defined(CONFIG_MALI400_PROFILING)
++#include "mali_osk_profiling.h"
++#endif
++
++static struct mali_gp_core *mali_global_gp_core = NULL;
++
++/* Interrupt handlers */
++static void mali_gp_irq_probe_trigger(void *data);
++static _mali_osk_errcode_t mali_gp_irq_probe_ack(void *data);
++
++struct mali_gp_core *mali_gp_create(const _mali_osk_resource_t * resource, struct mali_group *group)
++{
++      struct mali_gp_core* core = NULL;
++
++      MALI_DEBUG_ASSERT(NULL == mali_global_gp_core);
++      MALI_DEBUG_PRINT(2, ("Mali GP: Creating Mali GP core: %s\n", resource->description));
++
++      core = _mali_osk_malloc(sizeof(struct mali_gp_core));
++      if (NULL != core)
++      {
++              core->counter_src0_used = MALI_HW_CORE_NO_COUNTER;
++              core->counter_src1_used = MALI_HW_CORE_NO_COUNTER;
++              if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALIGP2_REGISTER_ADDRESS_SPACE_SIZE))
++              {
++                      _mali_osk_errcode_t ret;
++
++                      ret = mali_gp_reset(core);
++
++                      if (_MALI_OSK_ERR_OK == ret)
++                      {
++                              ret = mali_group_add_gp_core(group, core);
++                              if (_MALI_OSK_ERR_OK == ret)
++                              {
++                                      /* Setup IRQ handlers (which will do IRQ probing if needed) */
++                                      core->irq = _mali_osk_irq_init(resource->irq,
++                                                                     mali_group_upper_half_gp,
++                                                                     group,
++                                                                     mali_gp_irq_probe_trigger,
++                                                                     mali_gp_irq_probe_ack,
++                                                                     core,
++                                                                     "mali_gp_irq_handlers");
++                                      if (NULL != core->irq)
++                                      {
++                                              MALI_DEBUG_PRINT(4, ("Mali GP: set global gp core from 0x%08X to 0x%08X\n", mali_global_gp_core, core));
++                                              mali_global_gp_core = core;
++
++                                              return core;
++                                      }
++                                      else
++                                      {
++                                              MALI_PRINT_ERROR(("Mali GP: Failed to setup interrupt handlers for GP core %s\n", core->hw_core.description));
++                                      }
++                                      mali_group_remove_gp_core(group);
++                              }
++                              else
++                              {
++                                      MALI_PRINT_ERROR(("Mali GP: Failed to add core %s to group\n", core->hw_core.description));
++                              }
++                      }
++                      mali_hw_core_delete(&core->hw_core);
++              }
++
++              _mali_osk_free(core);
++      }
++      else
++      {
++              MALI_PRINT_ERROR(("Failed to allocate memory for GP core\n"));
++      }
++
++      return NULL;
++}
++
++void mali_gp_delete(struct mali_gp_core *core)
++{
++      MALI_DEBUG_ASSERT_POINTER(core);
++
++      _mali_osk_irq_term(core->irq);
++      mali_hw_core_delete(&core->hw_core);
++      mali_global_gp_core = NULL;
++      _mali_osk_free(core);
++}
++
++void mali_gp_stop_bus(struct mali_gp_core *core)
++{
++      MALI_DEBUG_ASSERT_POINTER(core);
++
++      mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_STOP_BUS);
++}
++
++_mali_osk_errcode_t mali_gp_stop_bus_wait(struct mali_gp_core *core)
++{
++      int i;
++
++      MALI_DEBUG_ASSERT_POINTER(core);
++
++      /* Send the stop bus command. */
++      mali_gp_stop_bus(core);
++
++      /* Wait for bus to be stopped */
++      for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++)
++      {
++              if (mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS) & MALIGP2_REG_VAL_STATUS_BUS_STOPPED)
++              {
++                      break;
++              }
++      }
++
++      if (MALI_REG_POLL_COUNT_FAST == i)
++      {
++              MALI_PRINT_ERROR(("Mali GP: Failed to stop bus on %s\n", core->hw_core.description));
++              return _MALI_OSK_ERR_FAULT;
++      }
++      return _MALI_OSK_ERR_OK;
++}
++
++void mali_gp_hard_reset(struct mali_gp_core *core)
++{
++      const u32 reset_wait_target_register = MALIGP2_REG_ADDR_MGMT_WRITE_BOUND_LOW;
++      const u32 reset_invalid_value = 0xC0FFE000;
++      const u32 reset_check_value = 0xC01A0000;
++      const u32 reset_default_value = 0;
++      int i;
++
++      MALI_DEBUG_ASSERT_POINTER(core);
++      MALI_DEBUG_PRINT(4, ("Mali GP: Hard reset of core %s\n", core->hw_core.description));
++
++      mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, reset_invalid_value);
++
++      mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_RESET);
++
++      for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++)
++      {
++              mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, reset_check_value);
++              if (reset_check_value == mali_hw_core_register_read(&core->hw_core, reset_wait_target_register))
++              {
++                      break;
++              }
++      }
++
++      if (MALI_REG_POLL_COUNT_FAST == i)
++      {
++              MALI_PRINT_ERROR(("Mali GP: The hard reset loop didn't work, unable to recover\n"));
++      }
++
++      mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, reset_default_value); /* set it back to the default */
++      /* Re-enable interrupts */
++      mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL);
++      mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED);
++
++}
++
++void mali_gp_reset_async(struct mali_gp_core *core)
++{
++      MALI_DEBUG_ASSERT_POINTER(core);
++
++      MALI_DEBUG_PRINT(4, ("Mali GP: Reset of core %s\n", core->hw_core.description));
++
++      mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, 0); /* disable the IRQs */
++      mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALI400GP_REG_VAL_IRQ_RESET_COMPLETED);
++      mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALI400GP_REG_VAL_CMD_SOFT_RESET);
++
++}
++
++_mali_osk_errcode_t mali_gp_reset_wait(struct mali_gp_core *core)
++{
++      int i;
++      u32 rawstat = 0;
++
++      MALI_DEBUG_ASSERT_POINTER(core);
++
++      for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++)
++      {
++              rawstat = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT);
++              if (rawstat & MALI400GP_REG_VAL_IRQ_RESET_COMPLETED)
++              {
++                      break;
++              }
++      }
++
++      if (i == MALI_REG_POLL_COUNT_FAST)
++      {
++              MALI_PRINT_ERROR(("Mali GP: Failed to reset core %s, rawstat: 0x%08x\n",
++                               core->hw_core.description, rawstat));
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      /* Re-enable interrupts */
++      mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL);
++      mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED);
++
++      return _MALI_OSK_ERR_OK;
++}
++
++_mali_osk_errcode_t mali_gp_reset(struct mali_gp_core *core)
++{
++      mali_gp_reset_async(core);
++      return mali_gp_reset_wait(core);
++}
++
++void mali_gp_job_start(struct mali_gp_core *core, struct mali_gp_job *job)
++{
++      u32 startcmd = 0;
++      u32 *frame_registers = mali_gp_job_get_frame_registers(job);
++
++      core->counter_src0_used = mali_gp_job_get_perf_counter_src0(job);
++      core->counter_src1_used = mali_gp_job_get_perf_counter_src1(job);
++
++      MALI_DEBUG_ASSERT_POINTER(core);
++
++      if (mali_gp_job_has_vs_job(job))
++      {
++              startcmd |= (u32) MALIGP2_REG_VAL_CMD_START_VS;
++      }
++
++      if (mali_gp_job_has_plbu_job(job))
++      {
++              startcmd |= (u32) MALIGP2_REG_VAL_CMD_START_PLBU;
++      }
++
++      MALI_DEBUG_ASSERT(0 != startcmd);
++
++      mali_hw_core_register_write_array_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR, frame_registers, MALIGP2_NUM_REGS_FRAME);
++
++      if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used)
++      {
++              mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used);
++              mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE);
++      }
++      if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used)
++      {
++              mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used);
++              mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE);
++      }
++
++      MALI_DEBUG_PRINT(3, ("Mali GP: Starting job (0x%08x) on core %s with command 0x%08X\n", job, core->hw_core.description, startcmd));
++
++      /* Barrier to make sure the previous register write is finished */
++      _mali_osk_write_mem_barrier();
++
++      /* This is the command that starts the core. */
++      mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, startcmd);
++
++      /* Barrier to make sure the previous register write is finished */
++      _mali_osk_write_mem_barrier();
++}
++
++void mali_gp_resume_with_new_heap(struct mali_gp_core *core, u32 start_addr, u32 end_addr)
++{
++      u32 irq_readout;
++
++      MALI_DEBUG_ASSERT_POINTER(core);
++
++      irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT);
++
++      if (irq_readout & MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM)
++      {
++              mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, (MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | MALIGP2_REG_VAL_IRQ_HANG));
++              mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED); /* re-enable interrupts */
++              mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR, start_addr);
++              mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR, end_addr);
++
++              MALI_DEBUG_PRINT(3, ("Mali GP: Resuming job\n"));
++
++              mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_UPDATE_PLBU_ALLOC);
++              _mali_osk_write_mem_barrier();
++      }
++      /*
++       * else: core has been reset between PLBU_OUT_OF_MEM interrupt and this new heap response.
++       * A timeout or a page fault on Mali-200 PP core can cause this behaviour.
++       */
++}
++
++u32 mali_gp_core_get_version(struct mali_gp_core *core)
++{
++      MALI_DEBUG_ASSERT_POINTER(core);
++      return mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_VERSION);
++}
++
++struct mali_gp_core *mali_gp_get_global_gp_core(void)
++{
++      return mali_global_gp_core;
++}
++
++/* ------------- interrupt handling below ------------------ */
++static void mali_gp_irq_probe_trigger(void *data)
++{
++      struct mali_gp_core *core = (struct mali_gp_core *)data;
++
++      mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED);
++      mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT, MALIGP2_REG_VAL_CMD_FORCE_HANG);
++      _mali_osk_mem_barrier();
++}
++
++static _mali_osk_errcode_t mali_gp_irq_probe_ack(void *data)
++{
++      struct mali_gp_core *core = (struct mali_gp_core *)data;
++      u32 irq_readout;
++
++      irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_STAT);
++      if (MALIGP2_REG_VAL_IRQ_FORCE_HANG & irq_readout)
++      {
++              mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_FORCE_HANG);
++              _mali_osk_mem_barrier();
++              return _MALI_OSK_ERR_OK;
++      }
++
++      return _MALI_OSK_ERR_FAULT;
++}
++
++/* ------ local helper functions below --------- */
++#if MALI_STATE_TRACKING
++u32 mali_gp_dump_state(struct mali_gp_core *core, char *buf, u32 size)
++{
++      int n = 0;
++
++      n += _mali_osk_snprintf(buf + n, size - n, "\tGP: %s\n", core->hw_core.description);
++
++      return n;
++}
++#endif
++
++void mali_gp_update_performance_counters(struct mali_gp_core *core, struct mali_gp_job *job, mali_bool suspend)
++{
++      u32 val0 = 0;
++      u32 val1 = 0;
++
++      if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used)
++      {
++              val0 = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE);
++              mali_gp_job_set_perf_counter_value0(job, val0);
++
++#if defined(CONFIG_MALI400_PROFILING)
++              _mali_osk_profiling_report_hw_counter(COUNTER_VP_C0, val0);
++#endif
++
++      }
++
++      if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used)
++      {
++              val1 = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE);
++              mali_gp_job_set_perf_counter_value1(job, val1);
++
++#if defined(CONFIG_MALI400_PROFILING)
++              _mali_osk_profiling_report_hw_counter(COUNTER_VP_C1, val1);
++#endif
++      }
++}
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_gp.h b/drivers/gpu/arm/mali400/mali/common/mali_gp.h
+new file mode 100644
+index 0000000..aa246fd
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_gp.h
+@@ -0,0 +1,96 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_GP_H__
++#define __MALI_GP_H__
++
++#include "mali_osk.h"
++#include "mali_gp_job.h"
++#include "mali_hw_core.h"
++#include "regs/mali_gp_regs.h"
++
++struct mali_group;
++
++/**
++ * Definition of the GP core struct
++ * Used to track a GP core in the system.
++ */
++struct mali_gp_core
++{
++      struct mali_hw_core  hw_core;           /**< Common for all HW cores */
++      _mali_osk_irq_t     *irq;               /**< IRQ handler */
++      u32                  counter_src0_used; /**< The selected performance counter 0 when a job is running */
++      u32                  counter_src1_used; /**< The selected performance counter 1 when a job is running */
++};
++
++_mali_osk_errcode_t mali_gp_initialize(void);
++void mali_gp_terminate(void);
++
++struct mali_gp_core *mali_gp_create(const _mali_osk_resource_t * resource, struct mali_group *group);
++void mali_gp_delete(struct mali_gp_core *core);
++
++void mali_gp_stop_bus(struct mali_gp_core *core);
++_mali_osk_errcode_t mali_gp_stop_bus_wait(struct mali_gp_core *core);
++void mali_gp_reset_async(struct mali_gp_core *core);
++_mali_osk_errcode_t mali_gp_reset_wait(struct mali_gp_core *core);
++void mali_gp_hard_reset(struct mali_gp_core *core);
++_mali_osk_errcode_t mali_gp_reset(struct mali_gp_core *core);
++
++void mali_gp_job_start(struct mali_gp_core *core, struct mali_gp_job *job);
++void mali_gp_resume_with_new_heap(struct mali_gp_core *core, u32 start_addr, u32 end_addr);
++
++u32 mali_gp_core_get_version(struct mali_gp_core *core);
++
++struct mali_gp_core *mali_gp_get_global_gp_core(void);
++
++u32 mali_gp_dump_state(struct mali_gp_core *core, char *buf, u32 size);
++
++void mali_gp_update_performance_counters(struct mali_gp_core *core, struct mali_gp_job *job, mali_bool suspend);
++
++/*** Accessor functions ***/
++MALI_STATIC_INLINE const char *mali_gp_get_hw_core_desc(struct mali_gp_core *core)
++{
++      return core->hw_core.description;
++}
++
++/*** Register reading/writing functions ***/
++MALI_STATIC_INLINE u32 mali_gp_get_int_stat(struct mali_gp_core *core)
++{
++      return mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_STAT);
++}
++
++MALI_STATIC_INLINE void mali_gp_mask_all_interrupts(struct mali_gp_core *core)
++{
++      mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_NONE);
++}
++
++MALI_STATIC_INLINE u32 mali_gp_read_rawstat(struct mali_gp_core *core)
++{
++      return mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT) & MALIGP2_REG_VAL_IRQ_MASK_USED;
++}
++
++MALI_STATIC_INLINE u32 mali_gp_read_core_status(struct mali_gp_core *core)
++{
++      return mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS);
++}
++
++MALI_STATIC_INLINE void mali_gp_enable_interrupts(struct mali_gp_core *core, u32 irq_exceptions)
++{
++      /* Enable all interrupts, except those specified in irq_exceptions */
++      mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK,
++                                  MALIGP2_REG_VAL_IRQ_MASK_USED & ~irq_exceptions);
++}
++
++MALI_STATIC_INLINE u32 mali_gp_read_plbu_alloc_start_addr(struct mali_gp_core *core)
++{
++      return mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR);
++}
++
++#endif /* __MALI_GP_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_gp_job.c b/drivers/gpu/arm/mali400/mali/common/mali_gp_job.c
+new file mode 100644
+index 0000000..7136526
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_gp_job.c
+@@ -0,0 +1,116 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_gp_job.h"
++#include "mali_osk.h"
++#include "mali_osk_list.h"
++#include "mali_uk_types.h"
++
++static u32 gp_counter_src0 = MALI_HW_CORE_NO_COUNTER;      /**< Performance counter 0, MALI_HW_CORE_NO_COUNTER for disabled */
++static u32 gp_counter_src1 = MALI_HW_CORE_NO_COUNTER;         /**< Performance counter 1, MALI_HW_CORE_NO_COUNTER for disabled */
++
++struct mali_gp_job *mali_gp_job_create(struct mali_session_data *session, _mali_uk_gp_start_job_s *uargs, u32 id)
++{
++      struct mali_gp_job *job;
++      u32 perf_counter_flag;
++
++      job = _mali_osk_malloc(sizeof(struct mali_gp_job));
++      if (NULL != job)
++      {
++              job->finished_notification = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_FINISHED, sizeof(_mali_uk_gp_job_finished_s));
++              if (NULL == job->finished_notification)
++              {
++                      _mali_osk_free(job);
++                      return NULL;
++              }
++
++              job->oom_notification = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_STALLED, sizeof(_mali_uk_gp_job_suspended_s));
++              if (NULL == job->oom_notification)
++              {
++                      _mali_osk_notification_delete(job->finished_notification);
++                      _mali_osk_free(job);
++                      return NULL;
++              }
++
++              if (0 != copy_from_user(&job->uargs, uargs, sizeof(_mali_uk_gp_start_job_s)))
++              {
++                      _mali_osk_notification_delete(job->finished_notification);
++                      _mali_osk_notification_delete(job->oom_notification);
++                      _mali_osk_free(job);
++                      return NULL;
++              }
++
++              perf_counter_flag = mali_gp_job_get_perf_counter_flag(job);
++
++              /* case when no counters came from user space
++               * so pass the debugfs / DS-5 provided global ones to the job object */
++              if (!((perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE) ||
++                              (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE)))
++              {
++                      mali_gp_job_set_perf_counter_src0(job, mali_gp_job_get_gp_counter_src0());
++                      mali_gp_job_set_perf_counter_src1(job, mali_gp_job_get_gp_counter_src1());
++              }
++
++              _mali_osk_list_init(&job->list);
++              job->session = session;
++              job->id = id;
++              job->heap_current_addr = job->uargs.frame_registers[4];
++              job->perf_counter_value0 = 0;
++              job->perf_counter_value1 = 0;
++              job->pid = _mali_osk_get_pid();
++              job->tid = _mali_osk_get_tid();
++
++              return job;
++      }
++
++      return NULL;
++}
++
++void mali_gp_job_delete(struct mali_gp_job *job)
++{
++
++      /* de-allocate the pre-allocated oom notifications */
++      if (NULL != job->oom_notification)
++      {
++              _mali_osk_notification_delete(job->oom_notification);
++              job->oom_notification = NULL;
++      }
++      if (NULL != job->finished_notification)
++      {
++              _mali_osk_notification_delete(job->finished_notification);
++              job->finished_notification = NULL;
++      }
++
++      _mali_osk_free(job);
++}
++
++u32 mali_gp_job_get_gp_counter_src0(void)
++{
++      return gp_counter_src0;
++}
++
++mali_bool mali_gp_job_set_gp_counter_src0(u32 counter)
++{
++      gp_counter_src0 = counter;
++
++      return MALI_TRUE;
++}
++
++u32 mali_gp_job_get_gp_counter_src1(void)
++{
++      return gp_counter_src1;
++}
++
++mali_bool mali_gp_job_set_gp_counter_src1(u32 counter)
++{
++      gp_counter_src1 = counter;
++
++      return MALI_TRUE;
++}
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_gp_job.h b/drivers/gpu/arm/mali400/mali/common/mali_gp_job.h
+new file mode 100644
+index 0000000..13258c5
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_gp_job.h
+@@ -0,0 +1,152 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_GP_JOB_H__
++#define __MALI_GP_JOB_H__
++
++#include "mali_osk.h"
++#include "mali_osk_list.h"
++#include "mali_uk_types.h"
++#include "mali_session.h"
++
++/**
++ * The structure represents a GP job, including all sub-jobs
++ * (This struct unfortunately needs to be public because of how the _mali_osk_list_*
++ * mechanism works)
++ */
++struct mali_gp_job
++{
++      _mali_osk_list_t list;                             /**< Used to link jobs together in the scheduler queue */
++      struct mali_session_data *session;                 /**< Session which submitted this job */
++      _mali_uk_gp_start_job_s uargs;                     /**< Arguments from user space */
++      u32 id;                                            /**< identifier for this job in kernel space (sequential numbering) */
++      u32 heap_current_addr;                             /**< Holds the current HEAP address when the job has completed */
++      u32 perf_counter_value0;                           /**< Value of performance counter 0 (to be returned to user space) */
++      u32 perf_counter_value1;                           /**< Value of performance counter 1 (to be returned to user space) */
++      u32 pid;                                           /**< Process ID of submitting process */
++      u32 tid;                                           /**< Thread ID of submitting thread */
++      _mali_osk_notification_t *finished_notification;   /**< Notification sent back to userspace on job complete */
++      _mali_osk_notification_t *oom_notification;        /**< Notification sent back to userspace on OOM */
++};
++
++struct mali_gp_job *mali_gp_job_create(struct mali_session_data *session, _mali_uk_gp_start_job_s *uargs, u32 id);
++void mali_gp_job_delete(struct mali_gp_job *job);
++
++u32 mali_gp_job_get_gp_counter_src0(void);
++mali_bool mali_gp_job_set_gp_counter_src0(u32 counter);
++u32 mali_gp_job_get_gp_counter_src1(void);
++mali_bool mali_gp_job_set_gp_counter_src1(u32 counter);
++
++MALI_STATIC_INLINE u32 mali_gp_job_get_id(struct mali_gp_job *job)
++{
++      return (NULL == job) ? 0 : job->id;
++}
++
++MALI_STATIC_INLINE u32 mali_gp_job_get_user_id(struct mali_gp_job *job)
++{
++      return job->uargs.user_job_ptr;
++}
++
++MALI_STATIC_INLINE u32 mali_gp_job_get_frame_builder_id(struct mali_gp_job *job)
++{
++      return job->uargs.frame_builder_id;
++}
++
++MALI_STATIC_INLINE u32 mali_gp_job_get_flush_id(struct mali_gp_job *job)
++{
++      return job->uargs.flush_id;
++}
++
++MALI_STATIC_INLINE u32 mali_gp_job_get_pid(struct mali_gp_job *job)
++{
++      return job->pid;
++}
++
++MALI_STATIC_INLINE u32 mali_gp_job_get_tid(struct mali_gp_job *job)
++{
++      return job->tid;
++}
++
++MALI_STATIC_INLINE u32* mali_gp_job_get_frame_registers(struct mali_gp_job *job)
++{
++      return job->uargs.frame_registers;
++}
++
++MALI_STATIC_INLINE struct mali_session_data *mali_gp_job_get_session(struct mali_gp_job *job)
++{
++      return job->session;
++}
++
++MALI_STATIC_INLINE mali_bool mali_gp_job_has_vs_job(struct mali_gp_job *job)
++{
++      return (job->uargs.frame_registers[0] != job->uargs.frame_registers[1]) ? MALI_TRUE : MALI_FALSE;
++}
++
++MALI_STATIC_INLINE mali_bool mali_gp_job_has_plbu_job(struct mali_gp_job *job)
++{
++      return (job->uargs.frame_registers[2] != job->uargs.frame_registers[3]) ? MALI_TRUE : MALI_FALSE;
++}
++
++MALI_STATIC_INLINE u32 mali_gp_job_get_current_heap_addr(struct mali_gp_job *job)
++{
++      return job->heap_current_addr;
++}
++
++MALI_STATIC_INLINE void mali_gp_job_set_current_heap_addr(struct mali_gp_job *job, u32 heap_addr)
++{
++      job->heap_current_addr = heap_addr;
++}
++
++MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_flag(struct mali_gp_job *job)
++{
++      return job->uargs.perf_counter_flag;
++}
++
++MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_src0(struct mali_gp_job *job)
++{
++      return job->uargs.perf_counter_src0;
++}
++
++MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_src1(struct mali_gp_job *job)
++{
++      return job->uargs.perf_counter_src1;
++}
++
++MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_value0(struct mali_gp_job *job)
++{
++      return job->perf_counter_value0;
++}
++
++MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_value1(struct mali_gp_job *job)
++{
++      return job->perf_counter_value1;
++}
++
++MALI_STATIC_INLINE void mali_gp_job_set_perf_counter_src0(struct mali_gp_job *job, u32 src)
++{
++      job->uargs.perf_counter_src0 = src;
++}
++
++MALI_STATIC_INLINE void mali_gp_job_set_perf_counter_src1(struct mali_gp_job *job, u32 src)
++{
++      job->uargs.perf_counter_src1 = src;
++}
++
++MALI_STATIC_INLINE void mali_gp_job_set_perf_counter_value0(struct mali_gp_job *job, u32 value)
++{
++      job->perf_counter_value0 = value;
++}
++
++MALI_STATIC_INLINE void mali_gp_job_set_perf_counter_value1(struct mali_gp_job *job, u32 value)
++{
++      job->perf_counter_value1 = value;
++}
++
++#endif /* __MALI_GP_JOB_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_gp_scheduler.c b/drivers/gpu/arm/mali400/mali/common/mali_gp_scheduler.c
+new file mode 100644
+index 0000000..81e9447
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_gp_scheduler.c
+@@ -0,0 +1,474 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_gp_scheduler.h"
++#include "mali_kernel_common.h"
++#include "mali_osk.h"
++#include "mali_osk_list.h"
++#include "mali_scheduler.h"
++#include "mali_gp.h"
++#include "mali_gp_job.h"
++#include "mali_group.h"
++#include "mali_pm.h"
++
++enum mali_gp_slot_state
++{
++      MALI_GP_SLOT_STATE_IDLE,
++      MALI_GP_SLOT_STATE_WORKING,
++};
++
++/* A render slot is an entity which jobs can be scheduled onto */
++struct mali_gp_slot
++{
++      struct mali_group *group;
++      /*
++       * We keep track of the state here as well as in the group object
++       * so we don't need to take the group lock so often (and also avoid clutter with the working lock)
++       */
++      enum mali_gp_slot_state state;
++      u32 returned_cookie;
++};
++
++static u32 gp_version = 0;
++static _MALI_OSK_LIST_HEAD(job_queue);                          /* List of jobs with some unscheduled work */
++static struct mali_gp_slot slot;
++
++/* Variables to allow safe pausing of the scheduler */
++static _mali_osk_wait_queue_t *gp_scheduler_working_wait_queue = NULL;
++static u32 pause_count = 0;
++
++static mali_bool mali_gp_scheduler_is_suspended(void);
++
++static _mali_osk_lock_t *gp_scheduler_lock = NULL;
++/* Contains tid of thread that locked the scheduler or 0, if not locked */
++
++_mali_osk_errcode_t mali_gp_scheduler_initialize(void)
++{
++      u32 num_groups;
++      u32 i;
++
++      _MALI_OSK_INIT_LIST_HEAD(&job_queue);
++
++      gp_scheduler_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_SCHEDULER);
++      if (NULL == gp_scheduler_lock)
++      {
++              return _MALI_OSK_ERR_NOMEM;
++      }
++
++      gp_scheduler_working_wait_queue = _mali_osk_wait_queue_init();
++      if (NULL == gp_scheduler_working_wait_queue)
++      {
++              _mali_osk_lock_term(gp_scheduler_lock);
++              return _MALI_OSK_ERR_NOMEM;
++      }
++
++      /* Find all the available GP cores */
++      num_groups = mali_group_get_glob_num_groups();
++      for (i = 0; i < num_groups; i++)
++      {
++              struct mali_group *group = mali_group_get_glob_group(i);
++
++              struct mali_gp_core *gp_core = mali_group_get_gp_core(group);
++              if (NULL != gp_core)
++              {
++                      if (0 == gp_version)
++                      {
++                              /* Retrieve GP version */
++                              gp_version = mali_gp_core_get_version(gp_core);
++                      }
++                      slot.group = group;
++                      slot.state = MALI_GP_SLOT_STATE_IDLE;
++                      break; /* There is only one GP, no point in looking for more */
++              }
++      }
++
++      return _MALI_OSK_ERR_OK;
++}
++
++void mali_gp_scheduler_terminate(void)
++{
++      MALI_DEBUG_ASSERT(MALI_GP_SLOT_STATE_IDLE == slot.state);
++      MALI_DEBUG_ASSERT_POINTER(slot.group);
++      mali_group_delete(slot.group);
++
++      _mali_osk_wait_queue_term(gp_scheduler_working_wait_queue);
++      _mali_osk_lock_term(gp_scheduler_lock);
++}
++
++MALI_STATIC_INLINE void mali_gp_scheduler_lock(void)
++{
++      if(_MALI_OSK_ERR_OK != _mali_osk_lock_wait(gp_scheduler_lock, _MALI_OSK_LOCKMODE_RW))
++      {
++              /* Non-interruptable lock failed: this should never happen. */
++              MALI_DEBUG_ASSERT(0);
++      }
++      MALI_DEBUG_PRINT(5, ("Mali GP scheduler: GP scheduler lock taken\n"));
++}
++
++MALI_STATIC_INLINE void mali_gp_scheduler_unlock(void)
++{
++      MALI_DEBUG_PRINT(5, ("Mali GP scheduler: Releasing GP scheduler lock\n"));
++      _mali_osk_lock_signal(gp_scheduler_lock, _MALI_OSK_LOCKMODE_RW);
++}
++
++#ifdef DEBUG
++MALI_STATIC_INLINE void mali_gp_scheduler_assert_locked(void)
++{
++      MALI_DEBUG_ASSERT_LOCK_HELD(gp_scheduler_lock);
++}
++#define MALI_ASSERT_GP_SCHEDULER_LOCKED() mali_gp_scheduler_assert_locked()
++#else
++#define MALI_ASSERT_GP_SCHEDULER_LOCKED()
++#endif
++
++static void mali_gp_scheduler_schedule(void)
++{
++      struct mali_gp_job *job;
++
++      mali_gp_scheduler_lock();
++
++      if (0 < pause_count || MALI_GP_SLOT_STATE_IDLE != slot.state || _mali_osk_list_empty(&job_queue))
++      {
++              MALI_DEBUG_PRINT(4, ("Mali GP scheduler: Nothing to schedule (paused=%u, idle slots=%u)\n",
++                                   pause_count, MALI_GP_SLOT_STATE_IDLE == slot.state ? 1 : 0));
++              mali_gp_scheduler_unlock();
++              return; /* Nothing to do, so early out */
++      }
++
++      /* Get (and remove) next job in queue */
++      job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_gp_job, list);
++      _mali_osk_list_del(&job->list);
++
++      /* Mark slot as busy */
++      slot.state = MALI_GP_SLOT_STATE_WORKING;
++
++      mali_gp_scheduler_unlock();
++
++      MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Starting job %u (0x%08X)\n", mali_gp_job_get_id(job), job));
++
++      mali_group_lock(slot.group);
++
++      if (_MALI_OSK_ERR_OK != mali_group_start_gp_job(slot.group, job))
++      {
++              MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Failed to start GP job\n"));
++              MALI_DEBUG_ASSERT(0); /* @@@@ todo: this cant fail on Mali-300+, no need to implement put back of job */
++      }
++
++      mali_group_unlock(slot.group);
++}
++
++/* @@@@ todo: pass the job in as a param to this function, so that we don't have to take the scheduler lock again */
++static void mali_gp_scheduler_schedule_on_group(struct mali_group *group)
++{
++      struct mali_gp_job *job;
++
++      MALI_DEBUG_ASSERT_LOCK_HELD(group->lock);
++      MALI_DEBUG_ASSERT_LOCK_HELD(gp_scheduler_lock);
++
++      if (0 < pause_count || MALI_GP_SLOT_STATE_IDLE != slot.state || _mali_osk_list_empty(&job_queue))
++      {
++              mali_gp_scheduler_unlock();
++              MALI_DEBUG_PRINT(4, ("Mali GP scheduler: Nothing to schedule (paused=%u, idle slots=%u)\n",
++                                   pause_count, MALI_GP_SLOT_STATE_IDLE == slot.state ? 1 : 0));
++              return; /* Nothing to do, so early out */
++      }
++
++      /* Get (and remove) next job in queue */
++      job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_gp_job, list);
++      _mali_osk_list_del(&job->list);
++
++      /* Mark slot as busy */
++      slot.state = MALI_GP_SLOT_STATE_WORKING;
++
++      mali_gp_scheduler_unlock();
++
++      MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Starting job %u (0x%08X)\n", mali_gp_job_get_id(job), job));
++
++      if (_MALI_OSK_ERR_OK != mali_group_start_gp_job(slot.group, job))
++      {
++              MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Failed to start GP job\n"));
++              MALI_DEBUG_ASSERT(0); /* @@@@ todo: this cant fail on Mali-300+, no need to implement put back of job */
++      }
++}
++
++static void mali_gp_scheduler_return_job_to_user(struct mali_gp_job *job, mali_bool success)
++{
++      _mali_uk_gp_job_finished_s *jobres = job->finished_notification->result_buffer;
++      _mali_osk_memset(jobres, 0, sizeof(_mali_uk_gp_job_finished_s)); /* @@@@ can be removed once we initialize all members in this struct */
++      jobres->user_job_ptr = mali_gp_job_get_user_id(job);
++      if (MALI_TRUE == success)
++      {
++              jobres->status = _MALI_UK_JOB_STATUS_END_SUCCESS;
++      }
++      else
++      {
++              jobres->status = _MALI_UK_JOB_STATUS_END_UNKNOWN_ERR;
++      }
++
++      jobres->heap_current_addr = mali_gp_job_get_current_heap_addr(job);
++      jobres->perf_counter0 = mali_gp_job_get_perf_counter_value0(job);
++      jobres->perf_counter1 = mali_gp_job_get_perf_counter_value1(job);
++
++      mali_session_send_notification(mali_gp_job_get_session(job), job->finished_notification);
++      job->finished_notification = NULL;
++
++      mali_gp_job_delete(job);
++}
++
++void mali_gp_scheduler_job_done(struct mali_group *group, struct mali_gp_job *job, mali_bool success)
++{
++      MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Job %u (0x%08X) completed (%s)\n", mali_gp_job_get_id(job), job, success ? "success" : "failure"));
++
++      mali_gp_scheduler_return_job_to_user(job, success);
++
++      mali_gp_scheduler_lock();
++
++      /* Mark slot as idle again */
++      slot.state = MALI_GP_SLOT_STATE_IDLE;
++
++      /* If paused, then this was the last job, so wake up sleeping workers */
++      if (pause_count > 0)
++      {
++              _mali_osk_wait_queue_wake_up(gp_scheduler_working_wait_queue);
++      }
++
++      mali_gp_scheduler_schedule_on_group(group);
++
++      /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */
++      mali_pm_core_event(MALI_CORE_EVENT_GP_STOP);
++}
++
++void mali_gp_scheduler_oom(struct mali_group *group, struct mali_gp_job *job)
++{
++      _mali_uk_gp_job_suspended_s * jobres;
++      _mali_osk_notification_t * notification;
++
++      mali_gp_scheduler_lock();
++
++      notification = job->oom_notification;
++      job->oom_notification = NULL;
++      slot.returned_cookie = mali_gp_job_get_id(job);
++
++      jobres = (_mali_uk_gp_job_suspended_s *)notification->result_buffer;
++      jobres->user_job_ptr = mali_gp_job_get_user_id(job);
++      jobres->cookie = mali_gp_job_get_id(job);
++
++      mali_gp_scheduler_unlock();
++
++      jobres->reason = _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY;
++
++      mali_session_send_notification(mali_gp_job_get_session(job), notification);
++
++      /*
++      * If this function failed, then we could return the job to user space right away,
++      * but there is a job timer anyway that will do that eventually.
++      * This is not exactly a common case anyway.
++      */
++}
++
++void mali_gp_scheduler_suspend(void)
++{
++      mali_gp_scheduler_lock();
++      pause_count++; /* Increment the pause_count so that no more jobs will be scheduled */
++      mali_gp_scheduler_unlock();
++
++      _mali_osk_wait_queue_wait_event(gp_scheduler_working_wait_queue, mali_gp_scheduler_is_suspended);
++}
++
++void mali_gp_scheduler_resume(void)
++{
++      mali_gp_scheduler_lock();
++      pause_count--; /* Decrement pause_count to allow scheduling again (if it reaches 0) */
++      mali_gp_scheduler_unlock();
++      if (0 == pause_count)
++      {
++              mali_gp_scheduler_schedule();
++      }
++}
++
++_mali_osk_errcode_t _mali_ukk_gp_start_job(void *ctx, _mali_uk_gp_start_job_s *uargs)
++{
++      struct mali_session_data *session;
++      struct mali_gp_job *job;
++
++      MALI_DEBUG_ASSERT_POINTER(uargs);
++      MALI_DEBUG_ASSERT_POINTER(ctx);
++
++      session = (struct mali_session_data*)ctx;
++
++      job = mali_gp_job_create(session, uargs, mali_scheduler_get_new_id());
++      if (NULL == job)
++      {
++              return _MALI_OSK_ERR_NOMEM;
++      }
++
++#if PROFILING_SKIP_PP_AND_GP_JOBS
++#warning GP jobs will not be executed
++      mali_gp_scheduler_return_job_to_user(job, MALI_TRUE);
++      return _MALI_OSK_ERR_OK;
++#endif
++
++      mali_pm_core_event(MALI_CORE_EVENT_GP_START);
++
++      mali_gp_scheduler_lock();
++      _mali_osk_list_addtail(&job->list, &job_queue);
++      mali_gp_scheduler_unlock();
++
++      MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Job %u (0x%08X) queued\n", mali_gp_job_get_id(job), job));
++
++      mali_gp_scheduler_schedule();
++
++      return _MALI_OSK_ERR_OK;
++}
++
++_mali_osk_errcode_t _mali_ukk_get_gp_number_of_cores(_mali_uk_get_gp_number_of_cores_s *args)
++{
++      MALI_DEBUG_ASSERT_POINTER(args);
++      MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
++      args->number_of_cores = 1;
++      return _MALI_OSK_ERR_OK;
++}
++
++_mali_osk_errcode_t _mali_ukk_get_gp_core_version(_mali_uk_get_gp_core_version_s *args)
++{
++      MALI_DEBUG_ASSERT_POINTER(args);
++      MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
++      args->version = gp_version;
++      return _MALI_OSK_ERR_OK;
++}
++
++_mali_osk_errcode_t _mali_ukk_gp_suspend_response(_mali_uk_gp_suspend_response_s *args)
++{
++      struct mali_session_data *session;
++      struct mali_gp_job *resumed_job;
++      _mali_osk_notification_t *new_notification = 0;
++
++      MALI_DEBUG_ASSERT_POINTER(args);
++
++      if (NULL == args->ctx)
++      {
++              return _MALI_OSK_ERR_INVALID_ARGS;
++      }
++
++      session = (struct mali_session_data*)args->ctx;
++      if (NULL == session)
++      {
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      if (_MALIGP_JOB_RESUME_WITH_NEW_HEAP == args->code)
++      {
++              new_notification = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_STALLED, sizeof(_mali_uk_gp_job_suspended_s));
++
++              if (NULL == new_notification)
++              {
++                      MALI_PRINT_ERROR(("Mali GP scheduler: Failed to allocate notification object. Will abort GP job.\n"));
++                      mali_group_lock(slot.group);
++                      mali_group_abort_gp_job(slot.group, args->cookie);
++                      mali_group_unlock(slot.group);
++                      return _MALI_OSK_ERR_FAULT;
++              }
++      }
++
++      mali_group_lock(slot.group);
++
++      if (_MALIGP_JOB_RESUME_WITH_NEW_HEAP == args->code)
++      {
++              MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Resuming job %u with new heap; 0x%08X - 0x%08X\n", args->cookie, args->arguments[0], args->arguments[1]));
++
++              resumed_job = mali_group_resume_gp_with_new_heap(slot.group, args->cookie, args->arguments[0], args->arguments[1]);
++              if (NULL != resumed_job)
++              {
++                      /* @@@@ todo: move this and other notification handling into the job object itself */
++                      resumed_job->oom_notification = new_notification;
++                      mali_group_unlock(slot.group);
++                      return _MALI_OSK_ERR_OK;
++              }
++              else
++              {
++                      mali_group_unlock(slot.group);
++                      _mali_osk_notification_delete(new_notification);
++                      return _MALI_OSK_ERR_FAULT;
++              }
++      }
++
++      MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Aborting job %u, no new heap provided\n", args->cookie));
++      mali_group_abort_gp_job(slot.group, args->cookie);
++      mali_group_unlock(slot.group);
++      return _MALI_OSK_ERR_OK;
++}
++
++void mali_gp_scheduler_abort_session(struct mali_session_data *session)
++{
++      struct mali_gp_job *job, *tmp;
++
++      mali_gp_scheduler_lock();
++      MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Aborting all jobs from session 0x%08x\n", session));
++
++      /* Check queue for jobs and remove */
++      _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &job_queue, struct mali_gp_job, list)
++      {
++              if (mali_gp_job_get_session(job) == session)
++              {
++                      MALI_DEBUG_PRINT(4, ("Mali GP scheduler: Removing GP job 0x%08x from queue\n", job));
++                      _mali_osk_list_del(&(job->list));
++                      mali_gp_job_delete(job);
++
++                      mali_pm_core_event(MALI_CORE_EVENT_GP_STOP);
++              }
++      }
++
++      mali_gp_scheduler_unlock();
++
++      mali_group_abort_session(slot.group, session);
++}
++
++static mali_bool mali_gp_scheduler_is_suspended(void)
++{
++      mali_bool ret;
++
++      mali_gp_scheduler_lock();
++      ret = pause_count > 0 && slot.state == MALI_GP_SLOT_STATE_IDLE;
++      mali_gp_scheduler_unlock();
++
++      return ret;
++}
++
++
++#if MALI_STATE_TRACKING
++u32 mali_gp_scheduler_dump_state(char *buf, u32 size)
++{
++      int n = 0;
++
++      n += _mali_osk_snprintf(buf + n, size - n, "GP\n");
++      n += _mali_osk_snprintf(buf + n, size - n, "\tQueue is %s\n", _mali_osk_list_empty(&job_queue) ? "empty" : "not empty");
++
++      n += mali_group_dump_state(slot.group, buf + n, size - n);
++      n += _mali_osk_snprintf(buf + n, size - n, "\n");
++
++      return n;
++}
++#endif
++
++void mali_gp_scheduler_reset_all_groups(void)
++{
++      if (NULL != slot.group)
++      {
++              mali_group_reset(slot.group);
++      }
++}
++
++void mali_gp_scheduler_zap_all_active(struct mali_session_data *session)
++{
++      if (NULL != slot.group)
++      {
++              mali_group_zap_session(slot.group, session);
++      }
++}
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_gp_scheduler.h b/drivers/gpu/arm/mali400/mali/common/mali_gp_scheduler.h
+new file mode 100644
+index 0000000..dccf9f3
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_gp_scheduler.h
+@@ -0,0 +1,44 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_GP_SCHEDULER_H__
++#define __MALI_GP_SCHEDULER_H__
++
++#include "mali_osk.h"
++#include "mali_gp_job.h"
++#include "mali_group.h"
++
++_mali_osk_errcode_t mali_gp_scheduler_initialize(void);
++void mali_gp_scheduler_terminate(void);
++
++void mali_gp_scheduler_job_done(struct mali_group *group, struct mali_gp_job *job, mali_bool success);
++void mali_gp_scheduler_oom(struct mali_group *group, struct mali_gp_job *job);
++void mali_gp_scheduler_abort_session(struct mali_session_data *session);
++u32 mali_gp_scheduler_dump_state(char *buf, u32 size);
++
++void mali_gp_scheduler_suspend(void);
++void mali_gp_scheduler_resume(void);
++
++/**
++ * @brief Reset all groups
++ *
++ * This function resets all groups known by the GP scheuduler. This must be
++ * called after the Mali HW has been powered on in order to reset the HW.
++ */
++void mali_gp_scheduler_reset_all_groups(void);
++
++/**
++ * @brief Zap TLB on all groups with \a session active
++ *
++ * The scheculer will zap the session on all groups it owns.
++ */
++void mali_gp_scheduler_zap_all_active(struct mali_session_data *session);
++
++#endif /* __MALI_GP_SCHEDULER_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_group.c b/drivers/gpu/arm/mali400/mali/common/mali_group.c
+new file mode 100644
+index 0000000..0034f9b
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_group.c
+@@ -0,0 +1,1803 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_kernel_common.h"
++#include "mali_group.h"
++#include "mali_osk.h"
++#include "mali_l2_cache.h"
++#include "mali_gp.h"
++#include "mali_pp.h"
++#include "mali_mmu.h"
++#include "mali_dlbu.h"
++#include "mali_broadcast.h"
++#include "mali_gp_scheduler.h"
++#include "mali_pp_scheduler.h"
++#include "mali_kernel_core.h"
++#include "mali_osk_profiling.h"
++
++static void mali_group_bottom_half_mmu(void *data);
++static void mali_group_bottom_half_gp(void *data);
++static void mali_group_bottom_half_pp(void *data);
++
++static void mali_group_timeout(void *data);
++static void mali_group_reset_pp(struct mali_group *group);
++
++#if defined(CONFIG_MALI400_PROFILING)
++static void mali_group_report_l2_cache_counters_per_core(struct mali_group *group, u32 core_num);
++#endif /* #if defined(CONFIG_MALI400_PROFILING) */
++
++/*
++ * The group object is the most important object in the device driver,
++ * and acts as the center of many HW operations.
++ * The reason for this is that operations on the MMU will affect all
++ * cores connected to this MMU (a group is defined by the MMU and the
++ * cores which are connected to this).
++ * The group lock is thus the most important lock, followed by the
++ * GP and PP scheduler locks. They must be taken in the following
++ * order:
++ * GP/PP lock first, then group lock(s).
++ */
++
++static struct mali_group *mali_global_groups[MALI_MAX_NUMBER_OF_GROUPS];
++static u32 mali_global_num_groups = 0;
++
++enum mali_group_activate_pd_status
++{
++      MALI_GROUP_ACTIVATE_PD_STATUS_FAILED,
++      MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD,
++      MALI_GROUP_ACTIVATE_PD_STATUS_OK_SWITCHED_PD,
++};
++
++/* local helper functions */
++static enum mali_group_activate_pd_status mali_group_activate_page_directory(struct mali_group *group, struct mali_session_data *session);
++static void mali_group_deactivate_page_directory(struct mali_group *group, struct mali_session_data *session);
++static void mali_group_remove_session_if_unused(struct mali_group *group, struct mali_session_data *session);
++static void mali_group_recovery_reset(struct mali_group *group);
++static void mali_group_mmu_page_fault(struct mali_group *group);
++
++static void mali_group_post_process_job_pp(struct mali_group *group);
++static void mali_group_post_process_job_gp(struct mali_group *group, mali_bool suspend);
++
++void mali_group_lock(struct mali_group *group)
++{
++      if(_MALI_OSK_ERR_OK != _mali_osk_lock_wait(group->lock, _MALI_OSK_LOCKMODE_RW))
++      {
++              /* Non-interruptable lock failed: this should never happen. */
++              MALI_DEBUG_ASSERT(0);
++      }
++      MALI_DEBUG_PRINT(5, ("Mali group: Group lock taken 0x%08X\n", group));
++}
++
++void mali_group_unlock(struct mali_group *group)
++{
++      MALI_DEBUG_PRINT(5, ("Mali group: Releasing group lock 0x%08X\n", group));
++      _mali_osk_lock_signal(group->lock, _MALI_OSK_LOCKMODE_RW);
++}
++
++#ifdef DEBUG
++void mali_group_assert_locked(struct mali_group *group)
++{
++      MALI_DEBUG_ASSERT_LOCK_HELD(group->lock);
++}
++#endif
++
++
++struct mali_group *mali_group_create(struct mali_l2_cache_core *core, struct mali_dlbu_core *dlbu, struct mali_bcast_unit *bcast)
++{
++      struct mali_group *group = NULL;
++      _mali_osk_lock_flags_t lock_flags;
++
++#if defined(MALI_UPPER_HALF_SCHEDULING)
++      lock_flags = _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE;
++#else
++      lock_flags = _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE;
++#endif
++
++      if (mali_global_num_groups >= MALI_MAX_NUMBER_OF_GROUPS)
++      {
++              MALI_PRINT_ERROR(("Mali group: Too many group objects created\n"));
++              return NULL;
++      }
++
++      group = _mali_osk_calloc(1, sizeof(struct mali_group));
++      if (NULL != group)
++      {
++              group->timeout_timer = _mali_osk_timer_init();
++
++              if (NULL != group->timeout_timer)
++              {
++                      _mali_osk_lock_order_t order;
++                      _mali_osk_timer_setcallback(group->timeout_timer, mali_group_timeout, (void *)group);
++
++                      if (NULL != dlbu)
++                      {
++                              order = _MALI_OSK_LOCK_ORDER_GROUP_VIRTUAL;
++                      }
++                      else
++                      {
++                              order = _MALI_OSK_LOCK_ORDER_GROUP;
++                      }
++
++                      group->lock = _mali_osk_lock_init(lock_flags, 0, order);
++                      if (NULL != group->lock)
++                      {
++                              group->l2_cache_core[0] = core;
++                              group->session = NULL;
++                              group->page_dir_ref_count = 0;
++                              group->power_is_on = MALI_TRUE;
++                              group->state = MALI_GROUP_STATE_IDLE;
++                              _mali_osk_list_init(&group->group_list);
++                              _mali_osk_list_init(&group->pp_scheduler_list);
++                              group->parent_group = NULL;
++                              group->l2_cache_core_ref_count[0] = 0;
++                              group->l2_cache_core_ref_count[1] = 0;
++                              group->bcast_core = bcast;
++                              group->dlbu_core = dlbu;
++
++                              mali_global_groups[mali_global_num_groups] = group;
++                              mali_global_num_groups++;
++
++                              return group;
++                      }
++            _mali_osk_timer_term(group->timeout_timer);
++              }
++              _mali_osk_free(group);
++      }
++
++      return NULL;
++}
++
++_mali_osk_errcode_t mali_group_add_mmu_core(struct mali_group *group, struct mali_mmu_core* mmu_core)
++{
++      /* This group object now owns the MMU core object */
++      group->mmu= mmu_core;
++      group->bottom_half_work_mmu = _mali_osk_wq_create_work(mali_group_bottom_half_mmu, group);
++      if (NULL == group->bottom_half_work_mmu)
++      {
++              return _MALI_OSK_ERR_FAULT;
++      }
++      return _MALI_OSK_ERR_OK;
++}
++
++void mali_group_remove_mmu_core(struct mali_group *group)
++{
++      /* This group object no longer owns the MMU core object */
++      group->mmu = NULL;
++      if (NULL != group->bottom_half_work_mmu)
++      {
++              _mali_osk_wq_delete_work(group->bottom_half_work_mmu);
++      }
++}
++
++_mali_osk_errcode_t mali_group_add_gp_core(struct mali_group *group, struct mali_gp_core* gp_core)
++{
++      /* This group object now owns the GP core object */
++      group->gp_core = gp_core;
++      group->bottom_half_work_gp = _mali_osk_wq_create_work(mali_group_bottom_half_gp, group);
++      if (NULL == group->bottom_half_work_gp)
++      {
++              return _MALI_OSK_ERR_FAULT;
++      }
++      return _MALI_OSK_ERR_OK;
++}
++
++void mali_group_remove_gp_core(struct mali_group *group)
++{
++      /* This group object no longer owns the GP core object */
++      group->gp_core = NULL;
++      if (NULL != group->bottom_half_work_gp)
++      {
++              _mali_osk_wq_delete_work(group->bottom_half_work_gp);
++      }
++}
++
++_mali_osk_errcode_t mali_group_add_pp_core(struct mali_group *group, struct mali_pp_core* pp_core)
++{
++      /* This group object now owns the PP core object */
++      group->pp_core = pp_core;
++      group->bottom_half_work_pp = _mali_osk_wq_create_work(mali_group_bottom_half_pp, group);
++      if (NULL == group->bottom_half_work_pp)
++      {
++              return _MALI_OSK_ERR_FAULT;
++      }
++      return _MALI_OSK_ERR_OK;
++}
++
++void mali_group_remove_pp_core(struct mali_group *group)
++{
++      /* This group object no longer owns the PP core object */
++      group->pp_core = NULL;
++      if (NULL != group->bottom_half_work_pp)
++      {
++              _mali_osk_wq_delete_work(group->bottom_half_work_pp);
++      }
++}
++
++void mali_group_delete(struct mali_group *group)
++{
++      u32 i;
++
++      MALI_DEBUG_PRINT(4, ("Deleting group %p\n", group));
++
++      MALI_DEBUG_ASSERT(NULL == group->parent_group);
++
++      /* Delete the resources that this group owns */
++      if (NULL != group->gp_core)
++      {
++              mali_gp_delete(group->gp_core);
++      }
++
++      if (NULL != group->pp_core)
++      {
++              mali_pp_delete(group->pp_core);
++      }
++
++      if (NULL != group->mmu)
++      {
++              mali_mmu_delete(group->mmu);
++      }
++
++      if (mali_group_is_virtual(group))
++      {
++              /* Remove all groups from virtual group */
++              struct mali_group *child;
++              struct mali_group *temp;
++
++              _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list)
++              {
++                      child->parent_group = NULL;
++                      mali_group_delete(child);
++              }
++
++              mali_dlbu_delete(group->dlbu_core);
++
++              if (NULL != group->bcast_core)
++              {
++                      mali_bcast_unit_delete(group->bcast_core);
++              }
++      }
++
++      for (i = 0; i < MALI_MAX_NUMBER_OF_GROUPS; i++)
++      {
++              if (mali_global_groups[i] == group)
++              {
++                      mali_global_groups[i] = NULL;
++                      mali_global_num_groups--;
++
++                      if (i != mali_global_num_groups)
++                      {
++                              /* We removed a group from the middle of the array -- move the last
++                               * group to the current position to close the gap */
++                              mali_global_groups[i] = mali_global_groups[mali_global_num_groups];
++                              mali_global_groups[mali_global_num_groups] = NULL;
++                      }
++
++                      break;
++              }
++      }
++
++      if (NULL != group->timeout_timer)
++      {
++              _mali_osk_timer_del(group->timeout_timer);
++              _mali_osk_timer_term(group->timeout_timer);
++      }
++
++      if (NULL != group->bottom_half_work_mmu)
++      {
++              _mali_osk_wq_delete_work(group->bottom_half_work_mmu);
++      }
++
++      if (NULL != group->bottom_half_work_gp)
++      {
++              _mali_osk_wq_delete_work(group->bottom_half_work_gp);
++      }
++
++      if (NULL != group->bottom_half_work_pp)
++      {
++              _mali_osk_wq_delete_work(group->bottom_half_work_pp);
++      }
++
++      _mali_osk_lock_term(group->lock);
++
++      _mali_osk_free(group);
++}
++
++MALI_DEBUG_CODE(static void mali_group_print_virtual(struct mali_group *vgroup)
++{
++      u32 i;
++      struct mali_group *group;
++      struct mali_group *temp;
++
++      MALI_DEBUG_PRINT(4, ("Virtual group %p\n", vgroup));
++      MALI_DEBUG_PRINT(4, ("l2_cache_core[0] = %p, ref = %d\n", vgroup->l2_cache_core[0], vgroup->l2_cache_core_ref_count[0]));
++      MALI_DEBUG_PRINT(4, ("l2_cache_core[1] = %p, ref = %d\n", vgroup->l2_cache_core[1], vgroup->l2_cache_core_ref_count[1]));
++
++      i = 0;
++      _MALI_OSK_LIST_FOREACHENTRY(group, temp, &vgroup->group_list, struct mali_group, group_list)
++      {
++              MALI_DEBUG_PRINT(4, ("[%d] %p, l2_cache_core[0] = %p\n", i, group, group->l2_cache_core[0]));
++              i++;
++      }
++})
++
++/**
++ * @brief Add child group to virtual group parent
++ *
++ * Before calling this function, child must have it's state set to JOINING_VIRTUAL
++ * to ensure it's not touched during the transition period. When this function returns,
++ * child's state will be IN_VIRTUAL.
++ */
++void mali_group_add_group(struct mali_group *parent, struct mali_group *child)
++{
++      mali_bool found;
++      u32 i;
++
++      MALI_DEBUG_PRINT(3, ("Adding group %p to virtual group %p\n", child, parent));
++
++      MALI_ASSERT_GROUP_LOCKED(parent);
++
++      MALI_DEBUG_ASSERT(mali_group_is_virtual(parent));
++      MALI_DEBUG_ASSERT(!mali_group_is_virtual(child));
++      MALI_DEBUG_ASSERT(NULL == child->parent_group);
++      MALI_DEBUG_ASSERT(MALI_GROUP_STATE_JOINING_VIRTUAL == child->state);
++
++      _mali_osk_list_addtail(&child->group_list, &parent->group_list);
++
++      child->state = MALI_GROUP_STATE_IN_VIRTUAL;
++      child->parent_group = parent;
++
++      MALI_DEBUG_ASSERT_POINTER(child->l2_cache_core[0]);
++
++      MALI_DEBUG_PRINT(4, ("parent->l2_cache_core: [0] = %p, [1] = %p\n", parent->l2_cache_core[0], parent->l2_cache_core[1]));
++      MALI_DEBUG_PRINT(4, ("child->l2_cache_core: [0] = %p, [1] = %p\n", child->l2_cache_core[0], child->l2_cache_core[1]));
++
++      /* Keep track of the L2 cache cores of child groups */
++      found = MALI_FALSE;
++      for (i = 0; i < 2; i++)
++      {
++              if (parent->l2_cache_core[i] == child->l2_cache_core[0])
++              {
++                      MALI_DEBUG_ASSERT(parent->l2_cache_core_ref_count[i] > 0);
++                      parent->l2_cache_core_ref_count[i]++;
++                      found = MALI_TRUE;
++              }
++      }
++
++      if (!found)
++      {
++              /* First time we see this L2 cache, add it to our list */
++              i = (NULL == parent->l2_cache_core[0]) ? 0 : 1;
++
++              MALI_DEBUG_PRINT(4, ("First time we see l2_cache %p. Adding to [%d] = %p\n", child->l2_cache_core[0], i, parent->l2_cache_core[i]));
++
++              MALI_DEBUG_ASSERT(NULL == parent->l2_cache_core[i]);
++
++              parent->l2_cache_core[i] = child->l2_cache_core[0];
++              parent->l2_cache_core_ref_count[i]++;
++      }
++
++      /* Update Broadcast Unit and DLBU */
++      mali_bcast_add_group(parent->bcast_core, child);
++      mali_dlbu_add_group(parent->dlbu_core, child);
++
++      /* Update MMU */
++      MALI_DEBUG_ASSERT(0 == child->page_dir_ref_count);
++      if (parent->session == child->session)
++      {
++              mali_mmu_zap_tlb(child->mmu);
++      }
++      else
++      {
++              child->session = NULL;
++
++              if (NULL == parent->session)
++              {
++                      mali_mmu_activate_empty_page_directory(child->mmu);
++              }
++              else
++              {
++
++                      mali_bool activate_success = mali_mmu_activate_page_directory(child->mmu,
++                              mali_session_get_page_directory(parent->session));
++                      MALI_DEBUG_ASSERT(activate_success);
++                      MALI_IGNORE(activate_success);
++              }
++      }
++      child->session = NULL;
++
++      /* Start job on child when parent is active */
++      if (NULL != parent->pp_running_job)
++      {
++              struct mali_pp_job *job = parent->pp_running_job;
++              MALI_DEBUG_PRINT(3, ("Group %x joining running job %d on virtual group %x\n",
++                                   child, mali_pp_job_get_id(job), parent));
++              MALI_DEBUG_ASSERT(MALI_GROUP_STATE_WORKING == parent->state);
++              mali_pp_job_start(child->pp_core, job, mali_pp_core_get_id(child->pp_core), MALI_TRUE);
++
++              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|
++                                            MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(child->pp_core))|
++                                            MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH,
++                                            mali_pp_job_get_frame_builder_id(job), mali_pp_job_get_flush_id(job), 0, 0, 0);
++
++              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|
++                                            MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(child->pp_core))|
++                                            MALI_PROFILING_EVENT_REASON_START_STOP_HW_VIRTUAL,
++                                            mali_pp_job_get_pid(job), mali_pp_job_get_tid(job), 0, 0, 0);
++      }
++
++      MALI_DEBUG_CODE(mali_group_print_virtual(parent);)
++}
++
++/**
++ * @brief Remove child group from virtual group parent
++ *
++ * After the child is removed, it's state will be LEAVING_VIRTUAL and must be set
++ * to IDLE before it can be used.
++ */
++void mali_group_remove_group(struct mali_group *parent, struct mali_group *child)
++{
++      u32 i;
++
++      MALI_ASSERT_GROUP_LOCKED(parent);
++
++      MALI_DEBUG_PRINT(3, ("Removing group %p from virtual group %p\n", child, parent));
++
++      MALI_DEBUG_ASSERT(mali_group_is_virtual(parent));
++      MALI_DEBUG_ASSERT(!mali_group_is_virtual(child));
++      MALI_DEBUG_ASSERT(parent == child->parent_group);
++      MALI_DEBUG_ASSERT(MALI_GROUP_STATE_IN_VIRTUAL == child->state);
++      /* Removing groups while running is not yet supported. */
++      MALI_DEBUG_ASSERT(MALI_GROUP_STATE_IDLE == parent->state);
++
++      mali_group_lock(child);
++
++      /* Update Broadcast Unit and DLBU */
++      mali_bcast_remove_group(parent->bcast_core, child);
++      mali_dlbu_remove_group(parent->dlbu_core, child);
++
++      _mali_osk_list_delinit(&child->group_list);
++
++      child->session = parent->session;
++      child->parent_group = NULL;
++      child->state = MALI_GROUP_STATE_LEAVING_VIRTUAL;
++
++      /* Keep track of the L2 cache cores of child groups */
++      i = (child->l2_cache_core[0] == parent->l2_cache_core[0]) ? 0 : 1;
++
++      MALI_DEBUG_ASSERT(child->l2_cache_core[0] == parent->l2_cache_core[i]);
++
++      parent->l2_cache_core_ref_count[i]--;
++
++      if (parent->l2_cache_core_ref_count[i] == 0)
++      {
++              parent->l2_cache_core[i] = NULL;
++      }
++
++      MALI_DEBUG_CODE(mali_group_print_virtual(parent));
++
++      mali_group_unlock(child);
++}
++
++struct mali_group *mali_group_acquire_group(struct mali_group *parent)
++{
++      struct mali_group *child;
++
++      MALI_ASSERT_GROUP_LOCKED(parent);
++
++      MALI_DEBUG_ASSERT(mali_group_is_virtual(parent));
++      MALI_DEBUG_ASSERT(!_mali_osk_list_empty(&parent->group_list));
++
++      child = _MALI_OSK_LIST_ENTRY(parent->group_list.prev, struct mali_group, group_list);
++
++      mali_group_remove_group(parent, child);
++
++      return child;
++}
++
++void mali_group_reset(struct mali_group *group)
++{
++      /*
++       * This function should not be used to abort jobs,
++       * currently only called during insmod and PM resume
++       */
++      MALI_DEBUG_ASSERT(NULL == group->gp_running_job);
++      MALI_DEBUG_ASSERT(NULL == group->pp_running_job);
++
++      mali_group_lock(group);
++
++      group->session = NULL;
++
++      if (NULL != group->mmu)
++      {
++              mali_mmu_reset(group->mmu);
++      }
++
++      if (NULL != group->gp_core)
++      {
++              mali_gp_reset(group->gp_core);
++      }
++
++      if (NULL != group->pp_core)
++      {
++              mali_group_reset_pp(group);
++      }
++
++      mali_group_unlock(group);
++}
++
++struct mali_gp_core* mali_group_get_gp_core(struct mali_group *group)
++{
++      return group->gp_core;
++}
++
++struct mali_pp_core* mali_group_get_pp_core(struct mali_group *group)
++{
++      return group->pp_core;
++}
++
++_mali_osk_errcode_t mali_group_start_gp_job(struct mali_group *group, struct mali_gp_job *job)
++{
++      struct mali_session_data *session;
++      enum mali_group_activate_pd_status activate_status;
++
++      MALI_ASSERT_GROUP_LOCKED(group);
++      MALI_DEBUG_ASSERT(MALI_GROUP_STATE_IDLE == group->state);
++
++      session = mali_gp_job_get_session(job);
++
++      if (NULL != group->l2_cache_core[0])
++      {
++              mali_l2_cache_invalidate_all_conditional(group->l2_cache_core[0], mali_gp_job_get_id(job));
++      }
++
++      activate_status = mali_group_activate_page_directory(group, session);
++      if (MALI_GROUP_ACTIVATE_PD_STATUS_FAILED != activate_status)
++      {
++              /* if session is NOT kept Zapping is done as part of session switch */
++              if (MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD == activate_status)
++              {
++                      mali_mmu_zap_tlb_without_stall(group->mmu);
++              }
++              mali_gp_job_start(group->gp_core, job);
++
++              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
++                              MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0) |
++                              MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH,
++                      mali_gp_job_get_frame_builder_id(job), mali_gp_job_get_flush_id(job), 0, 0, 0);
++              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START |
++                              MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0),
++                              mali_gp_job_get_pid(job), mali_gp_job_get_tid(job), 0, 0, 0);
++#if defined(CONFIG_MALI400_PROFILING)
++              if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[0])) &&
++                              (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[0])))
++                      mali_group_report_l2_cache_counters_per_core(group, 0);
++#endif /* #if defined(CONFIG_MALI400_PROFILING) */
++
++              group->gp_running_job = job;
++              group->state = MALI_GROUP_STATE_WORKING;
++
++              /* Setup the timeout timer value and save the job id for the job running on the gp core */
++              _mali_osk_timer_mod(group->timeout_timer, _mali_osk_time_mstoticks(mali_max_job_runtime));
++
++              return _MALI_OSK_ERR_OK;
++      }
++
++      return _MALI_OSK_ERR_FAULT;
++}
++
++_mali_osk_errcode_t mali_group_start_pp_job(struct mali_group *group, struct mali_pp_job *job, u32 sub_job)
++{
++      struct mali_session_data *session;
++      enum mali_group_activate_pd_status activate_status;
++
++      MALI_ASSERT_GROUP_LOCKED(group);
++      MALI_DEBUG_ASSERT(MALI_GROUP_STATE_IDLE == group->state);
++
++      session = mali_pp_job_get_session(job);
++
++      if (NULL != group->l2_cache_core[0])
++      {
++              mali_l2_cache_invalidate_all_conditional(group->l2_cache_core[0], mali_pp_job_get_id(job));
++      }
++
++      if (NULL != group->l2_cache_core[1])
++      {
++              mali_l2_cache_invalidate_all_conditional(group->l2_cache_core[1], mali_pp_job_get_id(job));
++      }
++
++      activate_status = mali_group_activate_page_directory(group, session);
++      if (MALI_GROUP_ACTIVATE_PD_STATUS_FAILED != activate_status)
++      {
++              /* if session is NOT kept Zapping is done as part of session switch */
++              if (MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD == activate_status)
++              {
++                      MALI_DEBUG_PRINT(3, ("PP starting job PD_Switch 0 Flush 1 Zap 1\n"));
++                      mali_mmu_zap_tlb_without_stall(group->mmu);
++              }
++
++              if (mali_group_is_virtual(group))
++              {
++                      struct mali_group *child;
++                      struct mali_group *temp;
++                      u32 core_num = 0;
++
++                      /* Configure DLBU for the job */
++                      mali_dlbu_config_job(group->dlbu_core, job);
++
++                      /* Write stack address for each child group */
++                      _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list)
++                      {
++                              mali_pp_write_addr_stack(child->pp_core, job);
++                              core_num++;
++                      }
++              }
++
++              mali_pp_job_start(group->pp_core, job, sub_job, MALI_FALSE);
++
++              /* if the group is virtual, loop through physical groups which belong to this group
++               * and call profiling events for its cores as virtual */
++              if (MALI_TRUE == mali_group_is_virtual(group))
++              {
++                      struct mali_group *child;
++                      struct mali_group *temp;
++
++                      _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list)
++                      {
++                              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|
++                                                            MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(child->pp_core))|
++                                                            MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH,
++                                                            mali_pp_job_get_frame_builder_id(job), mali_pp_job_get_flush_id(job), 0, 0, 0);
++
++                              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|
++                                                            MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(child->pp_core))|
++                                                            MALI_PROFILING_EVENT_REASON_START_STOP_HW_VIRTUAL,
++                                                            mali_pp_job_get_pid(job), mali_pp_job_get_tid(job), 0, 0, 0);
++                      }
++#if defined(CONFIG_MALI400_PROFILING)
++                      if (0 != group->l2_cache_core_ref_count[0])
++                      {
++                              if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[0])) &&
++                                                                      (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[0])))
++                              {
++                                      mali_group_report_l2_cache_counters_per_core(group, mali_l2_cache_get_id(group->l2_cache_core[0]));
++                              }
++                      }
++                      if (0 != group->l2_cache_core_ref_count[1])
++                      {
++                              if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[1])) &&
++                                                                      (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[1])))
++                              {
++                                      mali_group_report_l2_cache_counters_per_core(group, mali_l2_cache_get_id(group->l2_cache_core[1]));
++                              }
++                      }
++#endif /* #if defined(CONFIG_MALI400_PROFILING) */
++              }
++              else /* group is physical - call profiling events for physical cores */
++              {
++                      _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|
++                                                    MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(group->pp_core))|
++                                                    MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH,
++                                                    mali_pp_job_get_frame_builder_id(job), mali_pp_job_get_flush_id(job), 0, 0, 0);
++
++                      _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|
++                                                    MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(group->pp_core))|
++                                                    MALI_PROFILING_EVENT_REASON_START_STOP_HW_PHYSICAL,
++                                                    mali_pp_job_get_pid(job), mali_pp_job_get_tid(job), 0, 0, 0);
++#if defined(CONFIG_MALI400_PROFILING)
++                      if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[0])) &&
++                                      (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[0])))
++                      {
++                              mali_group_report_l2_cache_counters_per_core(group, mali_l2_cache_get_id(group->l2_cache_core[0]));
++                      }
++#endif /* #if defined(CONFIG_MALI400_PROFILING) */
++              }
++              group->pp_running_job = job;
++              group->pp_running_sub_job = sub_job;
++              group->state = MALI_GROUP_STATE_WORKING;
++
++              /* Setup the timeout timer value and save the job id for the job running on the pp core */
++              _mali_osk_timer_mod(group->timeout_timer, _mali_osk_time_mstoticks(mali_max_job_runtime));
++
++              return _MALI_OSK_ERR_OK;
++      }
++
++      return _MALI_OSK_ERR_FAULT;
++}
++
++struct mali_gp_job *mali_group_resume_gp_with_new_heap(struct mali_group *group, u32 job_id, u32 start_addr, u32 end_addr)
++{
++      MALI_ASSERT_GROUP_LOCKED(group);
++
++      if (group->state != MALI_GROUP_STATE_OOM ||
++          mali_gp_job_get_id(group->gp_running_job) != job_id)
++      {
++              return NULL; /* Illegal request or job has already been aborted */
++      }
++
++      if (NULL != group->l2_cache_core[0])
++      {
++              mali_l2_cache_invalidate_all_force(group->l2_cache_core[0]);
++      }
++
++      mali_mmu_zap_tlb_without_stall(group->mmu);
++
++      mali_gp_resume_with_new_heap(group->gp_core, start_addr, end_addr);
++
++      _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_RESUME|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0), 0, 0, 0, 0, 0);
++
++      group->state = MALI_GROUP_STATE_WORKING;
++
++      return group->gp_running_job;
++}
++
++static void mali_group_reset_pp(struct mali_group *group)
++{
++      struct mali_group *child;
++      struct mali_group *temp;
++
++      /* TODO: If we *know* that the group is idle, this could be faster. */
++
++      mali_pp_reset_async(group->pp_core);
++
++//    if (!mali_group_is_virtual(group) || NULL == group->pp_running_job) //LWJ
++/* MALI_SEC */
++      if (!mali_group_is_virtual(group) || NULL != group->pp_running_job)
++      {
++              /* This is a physical group or an idle virtual group -- simply wait for
++               * the reset to complete. */
++              mali_pp_reset_wait(group->pp_core);
++      }
++      else /* virtual group */
++      {
++              /* Loop through all members of this virtual group and wait until they
++               * are done resetting.
++               */
++              _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list)
++              {
++                      mali_pp_reset_wait(child->pp_core);
++              }
++      }
++}
++
++static void mali_group_complete_pp(struct mali_group *group, mali_bool success)
++{
++      struct mali_pp_job *pp_job_to_return;
++      u32 pp_sub_job_to_return;
++
++      MALI_DEBUG_ASSERT_POINTER(group->pp_core);
++      MALI_DEBUG_ASSERT_POINTER(group->pp_running_job);
++      MALI_ASSERT_GROUP_LOCKED(group);
++
++      mali_group_post_process_job_pp(group);
++
++      mali_pp_reset_async(group->pp_core);
++
++      pp_job_to_return = group->pp_running_job;
++      pp_sub_job_to_return = group->pp_running_sub_job;
++      group->state = MALI_GROUP_STATE_IDLE;
++      group->pp_running_job = NULL;
++
++      mali_group_deactivate_page_directory(group, group->session);
++
++      if (_MALI_OSK_ERR_OK != mali_pp_reset_wait(group->pp_core))
++      {
++              MALI_DEBUG_PRINT(3, ("Mali group: Failed to reset PP, need to reset entire group\n"));
++
++              mali_group_recovery_reset(group);
++      }
++
++      mali_pp_scheduler_job_done(group, pp_job_to_return, pp_sub_job_to_return, success);
++}
++
++static void mali_group_complete_gp(struct mali_group *group, mali_bool success)
++{
++      struct mali_gp_job *gp_job_to_return;
++
++      MALI_DEBUG_ASSERT_POINTER(group->gp_core);
++      MALI_DEBUG_ASSERT_POINTER(group->gp_running_job);
++      MALI_ASSERT_GROUP_LOCKED(group);
++
++      mali_group_post_process_job_gp(group, MALI_FALSE);
++
++      mali_gp_reset_async(group->gp_core);
++
++      gp_job_to_return = group->gp_running_job;
++      group->state = MALI_GROUP_STATE_IDLE;
++      group->gp_running_job = NULL;
++
++      mali_group_deactivate_page_directory(group, group->session);
++
++      if (_MALI_OSK_ERR_OK != mali_gp_reset_wait(group->gp_core))
++      {
++              MALI_DEBUG_PRINT(3, ("Mali group: Failed to reset GP, need to reset entire group\n"));
++
++              mali_group_recovery_reset(group);
++      }
++
++      mali_gp_scheduler_job_done(group, gp_job_to_return, success);
++}
++
++void mali_group_abort_gp_job(struct mali_group *group, u32 job_id)
++{
++      MALI_ASSERT_GROUP_LOCKED(group);
++
++      if (group->state == MALI_GROUP_STATE_IDLE ||
++          mali_gp_job_get_id(group->gp_running_job) != job_id)
++      {
++              return; /* No need to cancel or job has already been aborted or completed */
++      }
++
++      mali_group_complete_gp(group, MALI_FALSE);
++}
++
++static void mali_group_abort_pp_job(struct mali_group *group, u32 job_id)
++{
++      MALI_ASSERT_GROUP_LOCKED(group);
++
++      if (group->state == MALI_GROUP_STATE_IDLE ||
++          mali_pp_job_get_id(group->pp_running_job) != job_id)
++      {
++              return; /* No need to cancel or job has already been aborted or completed */
++      }
++
++      mali_group_complete_pp(group, MALI_FALSE);
++}
++
++void mali_group_abort_session(struct mali_group *group, struct mali_session_data *session)
++{
++      struct mali_gp_job *gp_job;
++      struct mali_pp_job *pp_job;
++      u32 gp_job_id = 0;
++      u32 pp_job_id = 0;
++      mali_bool abort_pp = MALI_FALSE;
++      mali_bool abort_gp = MALI_FALSE;
++
++      mali_group_lock(group);
++
++      if (mali_group_is_in_virtual(group))
++      {
++              /* Group is member of a virtual group, don't touch it! */
++              mali_group_unlock(group);
++              return;
++      }
++
++      gp_job = group->gp_running_job;
++      pp_job = group->pp_running_job;
++
++      if ((NULL != gp_job) && (mali_gp_job_get_session(gp_job) == session))
++      {
++              MALI_DEBUG_PRINT(4, ("Aborting GP job 0x%08x from session 0x%08x\n", gp_job, session));
++
++              gp_job_id = mali_gp_job_get_id(gp_job);
++              abort_gp = MALI_TRUE;
++      }
++
++      if ((NULL != pp_job) && (mali_pp_job_get_session(pp_job) == session))
++      {
++              MALI_DEBUG_PRINT(4, ("Mali group: Aborting PP job 0x%08x from session 0x%08x\n", pp_job, session));
++
++              pp_job_id = mali_pp_job_get_id(pp_job);
++              abort_pp = MALI_TRUE;
++      }
++
++//    if (0 != abort_gp) //LWJ ORG
++      if (abort_gp)
++      {
++              mali_group_abort_gp_job(group, gp_job_id);
++      }
++//    if (0 != abort_pp) //LWJ ORG
++      if (abort_pp)
++      {
++              mali_group_abort_pp_job(group, pp_job_id);
++      }
++
++      mali_group_remove_session_if_unused(group, session);
++
++      mali_group_unlock(group);
++}
++
++struct mali_group *mali_group_get_glob_group(u32 index)
++{
++      if(mali_global_num_groups > index)
++      {
++              return mali_global_groups[index];
++      }
++
++      return NULL;
++}
++
++u32 mali_group_get_glob_num_groups(void)
++{
++      return mali_global_num_groups;
++}
++
++static enum mali_group_activate_pd_status mali_group_activate_page_directory(struct mali_group *group, struct mali_session_data *session)
++{
++      enum mali_group_activate_pd_status retval;
++      MALI_ASSERT_GROUP_LOCKED(group);
++
++      MALI_DEBUG_PRINT(5, ("Mali group: Activating page directory 0x%08X from session 0x%08X on group 0x%08X\n", mali_session_get_page_directory(session), session, group));
++      MALI_DEBUG_ASSERT(0 <= group->page_dir_ref_count);
++
++      if (0 != group->page_dir_ref_count)
++      {
++              if (group->session != session)
++              {
++                      MALI_DEBUG_PRINT(4, ("Mali group: Activating session FAILED: 0x%08x on group 0x%08X. Existing session: 0x%08x\n", session, group, group->session));
++                      return MALI_GROUP_ACTIVATE_PD_STATUS_FAILED;
++              }
++              else
++              {
++                      MALI_DEBUG_PRINT(4, ("Mali group: Activating session already activated: 0x%08x on group 0x%08X. New Ref: %d\n", session, group, 1+group->page_dir_ref_count));
++                      retval = MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD;
++
++              }
++      }
++      else
++      {
++              /* There might be another session here, but it is ok to overwrite it since group->page_dir_ref_count==0 */
++              if (group->session != session)
++              {
++                      mali_bool activate_success;
++                      MALI_DEBUG_PRINT(5, ("Mali group: Activate session: %08x previous: %08x on group 0x%08X. Ref: %d\n", session, group->session, group, 1+group->page_dir_ref_count));
++
++                      activate_success = mali_mmu_activate_page_directory(group->mmu, mali_session_get_page_directory(session));
++                      MALI_DEBUG_ASSERT(activate_success);
++                      if ( MALI_FALSE== activate_success ) return MALI_GROUP_ACTIVATE_PD_STATUS_FAILED;
++                      group->session = session;
++                      retval = MALI_GROUP_ACTIVATE_PD_STATUS_OK_SWITCHED_PD;
++              }
++              else
++              {
++                      MALI_DEBUG_PRINT(4, ("Mali group: Activate existing session 0x%08X on group 0x%08X. Ref: %d\n", session->page_directory, group, 1+group->page_dir_ref_count));
++                      retval = MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD;
++              }
++      }
++
++      group->page_dir_ref_count++;
++      return retval;
++}
++
++static void mali_group_deactivate_page_directory(struct mali_group *group, struct mali_session_data *session)
++{
++      MALI_ASSERT_GROUP_LOCKED(group);
++
++      MALI_DEBUG_ASSERT(0 < group->page_dir_ref_count);
++      MALI_DEBUG_ASSERT(session == group->session);
++
++      group->page_dir_ref_count--;
++
++      /* As an optimization, the MMU still points to the group->session even if (0 == group->page_dir_ref_count),
++         and we do not call mali_mmu_activate_empty_page_directory(group->mmu); */
++      MALI_DEBUG_ASSERT(0 <= group->page_dir_ref_count);
++}
++
++static void mali_group_remove_session_if_unused(struct mali_group *group, struct mali_session_data *session)
++{
++      MALI_ASSERT_GROUP_LOCKED(group);
++
++      if (0 == group->page_dir_ref_count)
++      {
++              MALI_DEBUG_ASSERT(MALI_GROUP_STATE_WORKING != group->state);
++
++              if (group->session == session)
++              {
++                      MALI_DEBUG_ASSERT(MALI_TRUE == group->power_is_on);
++                      MALI_DEBUG_PRINT(3, ("Mali group: Deactivating unused session 0x%08X on group %08X\n", session, group));
++                      mali_mmu_activate_empty_page_directory(group->mmu);
++                      group->session = NULL;
++              }
++      }
++}
++
++void mali_group_power_on(void)
++{
++      int i;
++      for (i = 0; i < mali_global_num_groups; i++)
++      {
++              struct mali_group *group = mali_global_groups[i];
++              mali_group_lock(group);
++              MALI_DEBUG_ASSERT(MALI_GROUP_STATE_IDLE == group->state);
++              group->power_is_on = MALI_TRUE;
++
++              if (NULL != group->l2_cache_core[0])
++              {
++                      mali_l2_cache_power_is_enabled_set(group->l2_cache_core[0], MALI_TRUE);
++              }
++
++              if (NULL != group->l2_cache_core[1])
++              {
++                      mali_l2_cache_power_is_enabled_set(group->l2_cache_core[1], MALI_TRUE);
++              }
++
++              mali_group_unlock(group);
++      }
++      MALI_DEBUG_PRINT(4,("group: POWER ON\n"));
++}
++
++mali_bool mali_group_power_is_on(struct mali_group *group)
++{
++      MALI_ASSERT_GROUP_LOCKED(group);
++      return group->power_is_on;
++}
++
++void mali_group_power_off(void)
++{
++      int i;
++      /* It is necessary to set group->session = NULL; so that the powered off MMU is not written to on map /unmap */
++      /* It is necessary to set group->power_is_on=MALI_FALSE so that pending bottom_halves does not access powered off cores. */
++      for (i = 0; i < mali_global_num_groups; i++)
++      {
++              struct mali_group *group = mali_global_groups[i];
++              mali_group_lock(group);
++              MALI_DEBUG_ASSERT(MALI_GROUP_STATE_IDLE == group->state);
++              group->session = NULL;
++              group->power_is_on = MALI_FALSE;
++
++              if (NULL != group->l2_cache_core[0])
++              {
++                      mali_l2_cache_power_is_enabled_set(group->l2_cache_core[0], MALI_FALSE);
++              }
++
++              if (NULL != group->l2_cache_core[1])
++              {
++                      mali_l2_cache_power_is_enabled_set(group->l2_cache_core[1], MALI_FALSE);
++              }
++
++              mali_group_unlock(group);
++      }
++      MALI_DEBUG_PRINT(4,("group: POWER OFF\n"));
++}
++
++
++static void mali_group_recovery_reset(struct mali_group *group)
++{
++      MALI_ASSERT_GROUP_LOCKED(group);
++
++      /* Stop cores, bus stop */
++      if (NULL != group->pp_core)
++      {
++              mali_pp_stop_bus(group->pp_core);
++      }
++      else
++      {
++              mali_gp_stop_bus(group->gp_core);
++      }
++
++      /* Flush MMU and clear page fault (if any) */
++      mali_mmu_activate_fault_flush_page_directory(group->mmu);
++      mali_mmu_page_fault_done(group->mmu);
++
++      /* Wait for cores to stop bus, then do a hard reset on them */
++      if (NULL != group->pp_core)
++      {
++              if (mali_group_is_virtual(group))
++              {
++                      struct mali_group *child, *temp;
++
++                      _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list)
++                      {
++                              mali_pp_stop_bus_wait(child->pp_core);
++                              mali_pp_hard_reset(child->pp_core);
++                      }
++              }
++              else
++              {
++                      mali_pp_stop_bus_wait(group->pp_core);
++                      mali_pp_hard_reset(group->pp_core);
++              }
++      }
++      else
++      {
++              mali_gp_stop_bus_wait(group->gp_core);
++              mali_gp_hard_reset(group->gp_core);
++      }
++
++      /* Reset MMU */
++      mali_mmu_reset(group->mmu);
++      group->session = NULL;
++}
++
++#if MALI_STATE_TRACKING
++u32 mali_group_dump_state(struct mali_group *group, char *buf, u32 size)
++{
++      int n = 0;
++
++      n += _mali_osk_snprintf(buf + n, size - n, "Group: %p\n", group);
++      n += _mali_osk_snprintf(buf + n, size - n, "\tstate: %d\n", group->state);
++      if (group->gp_core)
++      {
++              n += mali_gp_dump_state(group->gp_core, buf + n, size - n);
++              n += _mali_osk_snprintf(buf + n, size - n, "\tGP job: %p\n", group->gp_running_job);
++      }
++      if (group->pp_core)
++      {
++              n += mali_pp_dump_state(group->pp_core, buf + n, size - n);
++              n += _mali_osk_snprintf(buf + n, size - n, "\tPP job: %p, subjob %d \n",
++                                      group->pp_running_job, group->pp_running_sub_job);
++      }
++
++      return n;
++}
++#endif
++
++static void mali_group_mmu_page_fault(struct mali_group *group)
++{
++      MALI_ASSERT_GROUP_LOCKED(group);
++
++      if (NULL != group->pp_core)
++      {
++              struct mali_pp_job *pp_job_to_return;
++              u32 pp_sub_job_to_return;
++
++              MALI_DEBUG_ASSERT_POINTER(group->pp_running_job);
++
++              mali_group_post_process_job_pp(group);
++
++              pp_job_to_return = group->pp_running_job;
++              pp_sub_job_to_return = group->pp_running_sub_job;
++              group->state = MALI_GROUP_STATE_IDLE;
++              group->pp_running_job = NULL;
++
++              mali_group_deactivate_page_directory(group, group->session);
++
++              mali_group_recovery_reset(group); /* This will also clear the page fault itself */
++
++              mali_pp_scheduler_job_done(group, pp_job_to_return, pp_sub_job_to_return, MALI_FALSE);
++      }
++      else
++      {
++              struct mali_gp_job *gp_job_to_return;
++
++              MALI_DEBUG_ASSERT_POINTER(group->gp_running_job);
++
++              mali_group_post_process_job_gp(group, MALI_FALSE);
++
++              gp_job_to_return = group->gp_running_job;
++              group->state = MALI_GROUP_STATE_IDLE;
++              group->gp_running_job = NULL;
++
++              mali_group_deactivate_page_directory(group, group->session);
++
++              mali_group_recovery_reset(group); /* This will also clear the page fault itself */
++
++              mali_gp_scheduler_job_done(group, gp_job_to_return, MALI_FALSE);
++      }
++}
++
++_mali_osk_errcode_t mali_group_upper_half_mmu(void * data)
++{
++      struct mali_group *group = (struct mali_group *)data;
++      struct mali_mmu_core *mmu = group->mmu;
++      u32 int_stat;
++
++      MALI_DEBUG_ASSERT_POINTER(mmu);
++
++      /* Check if it was our device which caused the interrupt (we could be sharing the IRQ line) */
++      int_stat = mali_mmu_get_int_status(mmu);
++      if (0 != int_stat)
++      {
++              struct mali_group *parent = group->parent_group;
++
++              /* page fault or bus error, we thread them both in the same way */
++              mali_mmu_mask_all_interrupts(mmu);
++              if (NULL == parent)
++              {
++                      _mali_osk_wq_schedule_work(group->bottom_half_work_mmu);
++              }
++              else
++              {
++                      _mali_osk_wq_schedule_work(parent->bottom_half_work_mmu);
++              }
++              return _MALI_OSK_ERR_OK;
++      }
++
++      return _MALI_OSK_ERR_FAULT;
++}
++
++static void mali_group_bottom_half_mmu(void * data)
++{
++      struct mali_group *group = (struct mali_group *)data;
++      struct mali_mmu_core *mmu = group->mmu;
++      u32 rawstat;
++      u32 status;
++
++      MALI_DEBUG_ASSERT_POINTER(mmu);
++
++      mali_group_lock(group);
++
++      /* TODO: Remove some of these asserts? Will we ever end up in
++       * "physical" bottom half for a member of the virtual group? */
++      MALI_DEBUG_ASSERT(NULL == group->parent_group);
++      MALI_DEBUG_ASSERT(!mali_group_is_in_virtual(group));
++
++      if ( MALI_FALSE == mali_group_power_is_on(group) )
++      {
++              MALI_PRINT_ERROR(("Interrupt bottom half of %s when core is OFF.", mmu->hw_core.description));
++              mali_group_unlock(group);
++              return;
++      }
++
++      rawstat = mali_mmu_get_rawstat(mmu);
++      status = mali_mmu_get_status(mmu);
++
++      MALI_DEBUG_PRINT(4, ("Mali MMU: Bottom half, interrupt 0x%08X, status 0x%08X\n", rawstat, status));
++
++      if (rawstat & (MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR))
++      {
++              /* An actual page fault has occurred. */
++              u32 fault_address = mali_mmu_get_page_fault_addr(mmu);
++              MALI_DEBUG_PRINT(2,("Mali MMU: Page fault detected at 0x%x from bus id %d of type %s on %s\n",
++                               (void*)fault_address,
++                               (status >> 6) & 0x1F,
++                               (status & 32) ? "write" : "read",
++                               mmu->hw_core.description));
++              MALI_IGNORE(fault_address);
++
++              mali_group_mmu_page_fault(group);
++      }
++
++      mali_group_unlock(group);
++}
++
++_mali_osk_errcode_t mali_group_upper_half_gp(void *data)
++{
++      struct mali_group *group = (struct mali_group *)data;
++      struct mali_gp_core *core = group->gp_core;
++      u32 irq_readout;
++
++      irq_readout = mali_gp_get_int_stat(core);
++
++      if (MALIGP2_REG_VAL_IRQ_MASK_NONE != irq_readout)
++      {
++              /* Mask out all IRQs from this core until IRQ is handled */
++              mali_gp_mask_all_interrupts(core);
++
++              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0)|MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT, irq_readout, 0, 0, 0, 0);
++
++              /* We do need to handle this in a bottom half */
++              _mali_osk_wq_schedule_work(group->bottom_half_work_gp);
++              return _MALI_OSK_ERR_OK;
++      }
++
++      return _MALI_OSK_ERR_FAULT;
++}
++
++static void mali_group_bottom_half_gp(void *data)
++{
++      struct mali_group *group = (struct mali_group *)data;
++      u32 irq_readout;
++      u32 irq_errors;
++
++      _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF, 0, _mali_osk_get_tid(), MALI_PROFILING_MAKE_EVENT_DATA_CORE_GP(0), 0, 0);
++
++      mali_group_lock(group);
++
++      if ( MALI_FALSE == mali_group_power_is_on(group) )
++      {
++              MALI_PRINT_ERROR(("Mali group: Interrupt bottom half of %s when core is OFF.", mali_gp_get_hw_core_desc(group->gp_core)));
++              mali_group_unlock(group);
++              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF, 0, _mali_osk_get_tid(), 0, 0, 0);
++              return;
++      }
++
++      irq_readout = mali_gp_read_rawstat(group->gp_core);
++
++      MALI_DEBUG_PRINT(4, ("Mali group: GP bottom half IRQ 0x%08X from core %s\n", irq_readout, mali_gp_get_hw_core_desc(group->gp_core)));
++
++      if (irq_readout & (MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST|MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST))
++      {
++              u32 core_status = mali_gp_read_core_status(group->gp_core);
++              if (0 == (core_status & MALIGP2_REG_VAL_STATUS_MASK_ACTIVE))
++              {
++                      MALI_DEBUG_PRINT(4, ("Mali group: GP job completed, calling group handler\n"));
++                      group->core_timed_out = MALI_FALSE;
++                      _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
++                                                    MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
++                                                    MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
++                                                    0, _mali_osk_get_tid(), 0, 0, 0);
++                      mali_group_complete_gp(group, MALI_TRUE);
++                      mali_group_unlock(group);
++                      return;
++              }
++      }
++
++      /*
++       * Now lets look at the possible error cases (IRQ indicating error or timeout)
++       * END_CMD_LST, HANG and PLBU_OOM interrupts are not considered error.
++       */
++      irq_errors = irq_readout & ~(MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST|MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST|MALIGP2_REG_VAL_IRQ_HANG|MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM);
++      if (0 != irq_errors)
++      {
++              MALI_PRINT_ERROR(("Mali group: Unknown interrupt 0x%08X from core %s, aborting job\n", irq_readout, mali_gp_get_hw_core_desc(group->gp_core)));
++              group->core_timed_out = MALI_FALSE;
++              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
++                                            MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
++                                            MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
++                                            0, _mali_osk_get_tid(), 0, 0, 0);
++              mali_group_complete_gp(group, MALI_FALSE);
++              mali_group_unlock(group);
++              return;
++      }
++      else if (group->core_timed_out) /* SW timeout */
++      {
++              group->core_timed_out = MALI_FALSE;
++              if (!_mali_osk_timer_pending(group->timeout_timer) && NULL != group->gp_running_job)
++              {
++                      MALI_PRINT(("Mali group: Job %d timed out\n", mali_gp_job_get_id(group->gp_running_job)));
++                      mali_group_complete_gp(group, MALI_FALSE);
++                      mali_group_unlock(group);
++                      return;
++              }
++      }
++      else if (irq_readout & MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM)
++      {
++              /* GP wants more memory in order to continue. */
++              MALI_DEBUG_PRINT(3, ("Mali group: PLBU needs more heap memory\n"));
++
++              group->state = MALI_GROUP_STATE_OOM;
++              mali_group_unlock(group); /* Nothing to do on the HW side, so just release group lock right away */
++              mali_gp_scheduler_oom(group, group->gp_running_job);
++              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF, 0, _mali_osk_get_tid(), 0, 0, 0);
++              return;
++      }
++
++      /*
++       * The only way to get here is if we only got one of two needed END_CMD_LST
++       * interrupts. Enable all but not the complete interrupt that has been
++       * received and continue to run.
++       */
++      mali_gp_enable_interrupts(group->gp_core, irq_readout & (MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST|MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST));
++      mali_group_unlock(group);
++
++      _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF, 0, _mali_osk_get_tid(), 0, 0, 0);
++}
++
++static void mali_group_post_process_job_gp(struct mali_group *group, mali_bool suspend)
++{
++      /* Stop the timeout timer. */
++      _mali_osk_timer_del_async(group->timeout_timer);
++
++      if (NULL == group->gp_running_job)
++      {
++              /* Nothing to do */
++              return;
++      }
++
++      mali_gp_update_performance_counters(group->gp_core, group->gp_running_job, suspend);
++
++#if defined(CONFIG_MALI400_PROFILING)
++      if (suspend)
++      {
++              /* @@@@ todo: test this case and see if it is still working*/
++              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SUSPEND|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0),
++                                            mali_gp_job_get_perf_counter_value0(group->gp_running_job),
++                                            mali_gp_job_get_perf_counter_value1(group->gp_running_job),
++                                            mali_gp_job_get_perf_counter_src0(group->gp_running_job) | (mali_gp_job_get_perf_counter_src1(group->gp_running_job) << 8),
++                                            0, 0);
++      }
++      else
++      {
++              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0),
++                                            mali_gp_job_get_perf_counter_value0(group->gp_running_job),
++                                            mali_gp_job_get_perf_counter_value1(group->gp_running_job),
++                                            mali_gp_job_get_perf_counter_src0(group->gp_running_job) | (mali_gp_job_get_perf_counter_src1(group->gp_running_job) << 8),
++                                            0, 0);
++
++              if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[0])) &&
++                              (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[0])))
++                      mali_group_report_l2_cache_counters_per_core(group, 0);
++      }
++#endif
++
++      mali_gp_job_set_current_heap_addr(group->gp_running_job,
++                                        mali_gp_read_plbu_alloc_start_addr(group->gp_core));
++}
++
++_mali_osk_errcode_t mali_group_upper_half_pp(void *data)
++{
++      struct mali_group *group = (struct mali_group *)data;
++      struct mali_pp_core *core = group->pp_core;
++      u32 irq_readout;
++
++      /*
++       * For Mali-450 there is one particular case we need to watch out for:
++       *
++       * Criteria 1) this function call can be due to a shared interrupt,
++       * and not necessary because this core signaled an interrupt.
++       * Criteria 2) this core is a part of a virtual group, and thus it should
++       * not do any post processing.
++       * Criteria 3) this core has actually indicated that is has completed by
++       * having set raw_stat/int_stat registers to != 0
++       *
++       * If all this criteria is meet, then we could incorrectly start post
++       * processing on the wrong group object (this should only happen on the
++       * parent group)
++       */
++#if !defined(MALI_UPPER_HALF_SCHEDULING)
++      if (mali_group_is_in_virtual(group))
++      {
++              /*
++               * This check is done without the group lock held, which could lead to
++               * a potential race. This is however ok, since we will safely re-check
++               * this with the group lock held at a later stage. This is just an
++               * early out which will strongly benefit shared IRQ systems.
++               */
++              return _MALI_OSK_ERR_OK;
++      }
++#endif
++
++      irq_readout = mali_pp_get_int_stat(core);
++      if (MALI200_REG_VAL_IRQ_MASK_NONE != irq_readout)
++      {
++              /* Mask out all IRQs from this core until IRQ is handled */
++              mali_pp_mask_all_interrupts(core);
++
++#if defined(CONFIG_MALI400_PROFILING)
++              /* Currently no support for this interrupt event for the virtual PP core */
++              if (!mali_group_is_virtual(group))
++              {
++                      _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
++                                                    MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_id) |
++                                                    MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT,
++                                                    irq_readout, 0, 0, 0, 0);
++              }
++#endif
++
++#if defined(MALI_UPPER_HALF_SCHEDULING)
++              if (irq_readout & MALI200_REG_VAL_IRQ_END_OF_FRAME)
++              {
++                      _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START |
++                                                    MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
++                                                    MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
++                                                    0, 0, MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(core->core_id), 0, 0);
++
++                      MALI_DEBUG_PRINT(3, ("Mali PP: Job completed, calling group handler from upper half\n"));
++
++                      mali_group_lock(group);
++
++                      /* Read int stat again */
++                      irq_readout = mali_pp_read_rawstat(core);
++                      if (!(irq_readout & MALI200_REG_VAL_IRQ_END_OF_FRAME))
++                      {
++                              /* There was nothing to do */
++                              mali_pp_enable_interrupts(core);
++                              mali_group_unlock(group);
++                              return _MALI_OSK_ERR_OK;
++                      }
++
++                      if (mali_group_is_in_virtual(group))
++                      {
++                              /* We're member of a virtual group, so interrupt should be handled by the virtual group */
++                              mali_pp_enable_interrupts(core);
++                              mali_group_unlock(group);
++                              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
++                                                            MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
++                                                            MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
++                                                            0, 0, MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(core->core_id), 0, 0);
++                              return _MALI_OSK_ERR_FAULT;
++                      }
++
++                      _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
++                                                    MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
++                                                    MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
++                                                    0, 0, MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(core->core_id), 0, 0);
++
++                      mali_group_complete_pp(group, MALI_TRUE);
++                      /* No need to enable interrupts again, since the core will be reset while completing the job */
++
++                      mali_group_unlock(group);
++
++                      return _MALI_OSK_ERR_OK;
++              }
++#endif
++
++              /* We do need to handle this in a bottom half */
++              _mali_osk_wq_schedule_work(group->bottom_half_work_pp);
++              return _MALI_OSK_ERR_OK;
++      }
++
++      return _MALI_OSK_ERR_FAULT;
++}
++
++static void mali_group_bottom_half_pp(void *data)
++{
++      struct mali_group *group = (struct mali_group *)data;
++      struct mali_pp_core *core = group->pp_core;
++      u32 irq_readout;
++      u32 irq_errors;
++
++      _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START |
++                                    MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
++                                    MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
++                                    0, _mali_osk_get_tid(), MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(core->core_id), 0, 0);
++
++      mali_group_lock(group);
++
++      if (mali_group_is_in_virtual(group))
++      {
++              /* We're member of a virtual group, so interrupt should be handled by the virtual group */
++              mali_pp_enable_interrupts(core);
++              mali_group_unlock(group);
++              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
++                                            MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
++                                            MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
++                                            0, _mali_osk_get_tid(), 0, 0, 0);
++              return;
++      }
++
++      if ( MALI_FALSE == mali_group_power_is_on(group) )
++      {
++              MALI_PRINT_ERROR(("Interrupt bottom half of %s when core is OFF.", mali_pp_get_hw_core_desc(core)));
++              mali_group_unlock(group);
++              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
++                                            MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
++                                            MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
++                                            0, _mali_osk_get_tid(), 0, 0, 0);
++              return;
++      }
++
++      irq_readout = mali_pp_read_rawstat(group->pp_core);
++
++      MALI_DEBUG_PRINT(4, ("Mali PP: Bottom half IRQ 0x%08X from core %s\n", irq_readout, mali_pp_get_hw_core_desc(group->pp_core)));
++
++      if (irq_readout & MALI200_REG_VAL_IRQ_END_OF_FRAME)
++      {
++              MALI_DEBUG_PRINT(3, ("Mali PP: Job completed, calling group handler\n"));
++              group->core_timed_out = MALI_FALSE;
++              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
++                                            MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
++                                            MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
++                                            0, _mali_osk_get_tid(), 0, 0, 0);
++              mali_group_complete_pp(group, MALI_TRUE);
++              mali_group_unlock(group);
++              return;
++      }
++
++      /*
++       * Now lets look at the possible error cases (IRQ indicating error or timeout)
++       * END_OF_FRAME and HANG interrupts are not considered error.
++       */
++      irq_errors = irq_readout & ~(MALI200_REG_VAL_IRQ_END_OF_FRAME|MALI200_REG_VAL_IRQ_HANG);
++      if (0 != irq_errors)
++      {
++              MALI_PRINT_ERROR(("Mali PP: Unknown interrupt 0x%08X from core %s, aborting job\n",
++                                irq_readout, mali_pp_get_hw_core_desc(group->pp_core)));
++              group->core_timed_out = MALI_FALSE;
++              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
++                                            MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
++                                            MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
++                                            0, _mali_osk_get_tid(), 0, 0, 0);
++              mali_group_complete_pp(group, MALI_FALSE);
++              mali_group_unlock(group);
++              return;
++      }
++      else if (group->core_timed_out) /* SW timeout */
++      {
++              group->core_timed_out = MALI_FALSE;
++              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
++                                            MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
++                                            MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
++                                            0, _mali_osk_get_tid(), 0, 0, 0);
++              if (!_mali_osk_timer_pending(group->timeout_timer) && NULL != group->pp_running_job)
++              {
++                      MALI_PRINT(("Mali PP: Job %d timed out on core %s\n",
++                                  mali_pp_job_get_id(group->pp_running_job), mali_pp_get_hw_core_desc(core)));
++                      mali_group_complete_pp(group, MALI_FALSE);
++                      mali_group_unlock(group);
++              }
++              else
++              {
++                      mali_group_unlock(group);
++              }
++              return;
++      }
++
++      /*
++       * We should never get here, re-enable interrupts and continue
++       */
++      if (0 == irq_readout)
++      {
++              MALI_DEBUG_PRINT(3, ("Mali group: No interrupt found on core %s\n",
++                                  mali_pp_get_hw_core_desc(group->pp_core)));
++      }
++      else
++      {
++              MALI_PRINT_ERROR(("Mali group: Unhandled PP interrupt 0x%08X on %s\n", irq_readout,
++                                  mali_pp_get_hw_core_desc(group->pp_core)));
++      }
++      mali_pp_enable_interrupts(core);
++      mali_group_unlock(group);
++
++      _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
++                                    MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
++                                    MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
++                                    0, _mali_osk_get_tid(), 0, 0, 0);
++}
++
++static void mali_group_post_process_job_pp(struct mali_group *group)
++{
++      MALI_ASSERT_GROUP_LOCKED(group);
++
++      /* Stop the timeout timer. */
++      _mali_osk_timer_del_async(group->timeout_timer);
++
++      /*todo add stop SW counters profiling*/
++
++      if (NULL != group->pp_running_job)
++      {
++              if (MALI_TRUE == mali_group_is_virtual(group))
++              {
++                      struct mali_group *child;
++                      struct mali_group *temp;
++
++                      /* update performance counters from each physical pp core within this virtual group */
++                      _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list)
++                      {
++                              mali_pp_update_performance_counters(child->pp_core, group->pp_running_job, group->pp_running_sub_job);
++                      }
++
++#if defined(CONFIG_MALI400_PROFILING)
++                      /* send profiling data per physical core */
++                      _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list)
++                      {
++                              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|
++                                                            MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(child->pp_core))|
++                                                            MALI_PROFILING_EVENT_REASON_START_STOP_HW_VIRTUAL,
++                                                            mali_pp_job_get_perf_counter_value0(group->pp_running_job, mali_pp_core_get_id(child->pp_core)),
++                                                            mali_pp_job_get_perf_counter_value1(group->pp_running_job, mali_pp_core_get_id(child->pp_core)),
++                                                            mali_pp_job_get_perf_counter_src0(group->pp_running_job) | (mali_pp_job_get_perf_counter_src1(group->pp_running_job) << 8),
++                                                            0, 0);
++                      }
++                      if (0 != group->l2_cache_core_ref_count[0])
++                      {
++                              if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[0])) &&
++                                                                      (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[0])))
++                              {
++                                      mali_group_report_l2_cache_counters_per_core(group, mali_l2_cache_get_id(group->l2_cache_core[0]));
++                              }
++                      }
++                      if (0 != group->l2_cache_core_ref_count[1])
++                      {
++                              if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[1])) &&
++                                                                      (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[1])))
++                              {
++                                      mali_group_report_l2_cache_counters_per_core(group, mali_l2_cache_get_id(group->l2_cache_core[1]));
++                              }
++                      }
++
++#endif
++              }
++              else
++              {
++                      /* update performance counters for a physical group's pp core */
++                      mali_pp_update_performance_counters(group->pp_core, group->pp_running_job, group->pp_running_sub_job);
++
++#if defined(CONFIG_MALI400_PROFILING)
++                      _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|
++                                                    MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(group->pp_core))|
++                                                    MALI_PROFILING_EVENT_REASON_START_STOP_HW_PHYSICAL,
++                                                    mali_pp_job_get_perf_counter_value0(group->pp_running_job, group->pp_running_sub_job),
++                                                    mali_pp_job_get_perf_counter_value1(group->pp_running_job, group->pp_running_sub_job),
++                                                    mali_pp_job_get_perf_counter_src0(group->pp_running_job) | (mali_pp_job_get_perf_counter_src1(group->pp_running_job) << 8),
++                                                    0, 0);
++                      if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[0])) &&
++                                      (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[0])))
++                      {
++                              mali_group_report_l2_cache_counters_per_core(group, mali_l2_cache_get_id(group->l2_cache_core[0]));
++                      }
++#endif
++              }
++      }
++}
++
++static void mali_group_timeout(void *data)
++{
++      struct mali_group *group = (struct mali_group *)data;
++
++      group->core_timed_out = MALI_TRUE;
++
++      if (NULL != group->gp_core)
++      {
++              MALI_DEBUG_PRINT(2, ("Mali group: TIMEOUT on %s\n", mali_gp_get_hw_core_desc(group->gp_core)));
++              _mali_osk_wq_schedule_work(group->bottom_half_work_gp);
++      }
++      else
++      {
++              MALI_DEBUG_PRINT(2, ("Mali group: TIMEOUT on %s\n", mali_pp_get_hw_core_desc(group->pp_core)));
++              _mali_osk_wq_schedule_work(group->bottom_half_work_pp);
++      }
++}
++
++void mali_group_zap_session(struct mali_group *group, struct mali_session_data *session)
++{
++      MALI_DEBUG_ASSERT_POINTER(group);
++      MALI_DEBUG_ASSERT_POINTER(session);
++
++      /* Early out - safe even if mutex is not held */
++      if (group->session != session) return;
++
++      mali_group_lock(group);
++
++      mali_group_remove_session_if_unused(group, session);
++
++      if (group->session == session)
++      {
++              /* The Zap also does the stall and disable_stall */
++              mali_bool zap_success = mali_mmu_zap_tlb(group->mmu);
++              if (MALI_TRUE != zap_success)
++              {
++                      MALI_DEBUG_PRINT(2, ("Mali memory unmap failed. Doing pagefault handling.\n"));
++                      mali_group_mmu_page_fault(group);
++              }
++      }
++
++      mali_group_unlock(group);
++}
++
++#if defined(CONFIG_MALI400_PROFILING)
++static void mali_group_report_l2_cache_counters_per_core(struct mali_group *group, u32 core_num)
++{
++      u32 source0 = 0;
++      u32 value0 = 0;
++      u32 source1 = 0;
++      u32 value1 = 0;
++      u32 profiling_channel = 0;
++
++      switch(core_num)
++      {
++              case 0: profiling_channel = MALI_PROFILING_EVENT_TYPE_SINGLE |
++                              MALI_PROFILING_EVENT_CHANNEL_GPU |
++                              MALI_PROFILING_EVENT_REASON_SINGLE_GPU_L20_COUNTERS;
++                              break;
++              case 1: profiling_channel = MALI_PROFILING_EVENT_TYPE_SINGLE |
++                              MALI_PROFILING_EVENT_CHANNEL_GPU |
++                              MALI_PROFILING_EVENT_REASON_SINGLE_GPU_L21_COUNTERS;
++                              break;
++              case 2: profiling_channel = MALI_PROFILING_EVENT_TYPE_SINGLE |
++                              MALI_PROFILING_EVENT_CHANNEL_GPU |
++                              MALI_PROFILING_EVENT_REASON_SINGLE_GPU_L22_COUNTERS;
++                              break;
++              default: profiling_channel = MALI_PROFILING_EVENT_TYPE_SINGLE |
++                              MALI_PROFILING_EVENT_CHANNEL_GPU |
++                              MALI_PROFILING_EVENT_REASON_SINGLE_GPU_L20_COUNTERS;
++                              break;
++      }
++
++      if (0 == core_num)
++      {
++              mali_l2_cache_core_get_counter_values(group->l2_cache_core[0], &source0, &value0, &source1, &value1);
++      }
++      if (1 == core_num)
++      {
++              if (1 == mali_l2_cache_get_id(group->l2_cache_core[0]))
++              {
++                      mali_l2_cache_core_get_counter_values(group->l2_cache_core[0], &source0, &value0, &source1, &value1);
++              }
++              else if (1 == mali_l2_cache_get_id(group->l2_cache_core[1]))
++              {
++                      mali_l2_cache_core_get_counter_values(group->l2_cache_core[1], &source0, &value0, &source1, &value1);
++              }
++      }
++      if (2 == core_num)
++      {
++              if (2 == mali_l2_cache_get_id(group->l2_cache_core[0]))
++              {
++                      mali_l2_cache_core_get_counter_values(group->l2_cache_core[0], &source0, &value0, &source1, &value1);
++              }
++              else if (2 == mali_l2_cache_get_id(group->l2_cache_core[1]))
++              {
++                      mali_l2_cache_core_get_counter_values(group->l2_cache_core[1], &source0, &value0, &source1, &value1);
++              }
++      }
++
++      _mali_osk_profiling_add_event(profiling_channel, source1 << 8 | source0, value0, value1, 0, 0);
++}
++#endif /* #if defined(CONFIG_MALI400_PROFILING) */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_group.h b/drivers/gpu/arm/mali400/mali/common/mali_group.h
+new file mode 100644
+index 0000000..7a40da2
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_group.h
+@@ -0,0 +1,210 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_GROUP_H__
++#define __MALI_GROUP_H__
++
++#include "linux/jiffies.h"
++#include "mali_osk.h"
++#include "mali_l2_cache.h"
++#include "mali_mmu.h"
++#include "mali_gp.h"
++#include "mali_pp.h"
++#include "mali_session.h"
++
++/* max runtime [ms] for a core job - used by timeout timers  */
++#define MAX_RUNTIME 5000
++/** @brief A mali group object represents a MMU and a PP and/or a GP core.
++ *
++ */
++#define MALI_MAX_NUMBER_OF_GROUPS 10
++
++enum mali_group_core_state
++{
++      MALI_GROUP_STATE_IDLE,
++      MALI_GROUP_STATE_WORKING,
++      MALI_GROUP_STATE_OOM,
++      MALI_GROUP_STATE_IN_VIRTUAL,
++      MALI_GROUP_STATE_JOINING_VIRTUAL,
++      MALI_GROUP_STATE_LEAVING_VIRTUAL,
++};
++
++/**
++ * The structure represents a render group
++ * A render group is defined by all the cores that share the same Mali MMU
++ */
++
++struct mali_group
++{
++      struct mali_mmu_core        *mmu;
++      struct mali_session_data    *session;
++      int                         page_dir_ref_count;
++
++      mali_bool                   power_is_on;
++      enum mali_group_core_state  state; /* @@@@ TODO: include power_is_on in this state? */
++
++      struct mali_gp_core         *gp_core;
++      struct mali_gp_job          *gp_running_job;
++
++      struct mali_pp_core         *pp_core;
++      struct mali_pp_job          *pp_running_job;
++      u32                         pp_running_sub_job;
++
++      struct mali_l2_cache_core   *l2_cache_core[2];
++      u32                         l2_cache_core_ref_count[2];
++
++      struct mali_dlbu_core       *dlbu_core;
++      struct mali_bcast_unit      *bcast_core;
++
++      _mali_osk_lock_t            *lock;
++
++      _mali_osk_list_t            pp_scheduler_list;
++
++      /* List used for virtual groups. For a virtual group, the list represents the
++       * head element. */
++      _mali_osk_list_t            group_list;
++
++      /* Parent virtual group (if any) */
++      struct mali_group           *parent_group;
++
++      _mali_osk_wq_work_t         *bottom_half_work_mmu;
++      _mali_osk_wq_work_t         *bottom_half_work_gp;
++      _mali_osk_wq_work_t         *bottom_half_work_pp;
++
++      _mali_osk_timer_t           *timeout_timer;
++      mali_bool                   core_timed_out;
++};
++
++/** @brief Create a new Mali group object
++ *
++ * @param cluster Pointer to the cluster to which the group is connected.
++ * @param mmu Pointer to the MMU that defines this group
++ * @return A pointer to a new group object
++ */
++struct mali_group *mali_group_create(struct mali_l2_cache_core *core,
++                                     struct mali_dlbu_core *dlbu,
++                                   struct mali_bcast_unit *bcast);
++
++_mali_osk_errcode_t mali_group_add_mmu_core(struct mali_group *group, struct mali_mmu_core* mmu_core);
++void mali_group_remove_mmu_core(struct mali_group *group);
++
++_mali_osk_errcode_t mali_group_add_gp_core(struct mali_group *group, struct mali_gp_core* gp_core);
++void mali_group_remove_gp_core(struct mali_group *group);
++
++_mali_osk_errcode_t mali_group_add_pp_core(struct mali_group *group, struct mali_pp_core* pp_core);
++void mali_group_remove_pp_core(struct mali_group *group);
++
++void mali_group_delete(struct mali_group *group);
++
++/** @brief Virtual groups */
++void mali_group_add_group(struct mali_group *parent, struct mali_group *child);
++void mali_group_remove_group(struct mali_group *parent, struct mali_group *child);
++struct mali_group *mali_group_acquire_group(struct mali_group *parent);
++
++MALI_STATIC_INLINE mali_bool mali_group_is_virtual(struct mali_group *group)
++{
++      return (NULL != group->dlbu_core);
++}
++
++/** @brief Check if a group is considered as part of a virtual group
++ *
++ * @note A group is considered to be "part of" a virtual group also during the transition
++ *       in to / out of the virtual group.
++ */
++MALI_STATIC_INLINE mali_bool mali_group_is_in_virtual(struct mali_group *group)
++{
++      return (MALI_GROUP_STATE_IN_VIRTUAL == group->state ||
++              MALI_GROUP_STATE_JOINING_VIRTUAL == group->state ||
++              MALI_GROUP_STATE_LEAVING_VIRTUAL == group->state);
++}
++
++/** @brief Reset group
++ *
++ * This function will reset the entire group, including all the cores present in the group.
++ *
++ * @param group Pointer to the group to reset
++ */
++void mali_group_reset(struct mali_group *group);
++
++/** @brief Zap MMU TLB on all groups
++ *
++ * Zap TLB on group if \a session is active.
++ */
++void mali_group_zap_session(struct mali_group* group, struct mali_session_data *session);
++
++/** @brief Get pointer to GP core object
++ */
++struct mali_gp_core* mali_group_get_gp_core(struct mali_group *group);
++
++/** @brief Get pointer to PP core object
++ */
++struct mali_pp_core* mali_group_get_pp_core(struct mali_group *group);
++
++/** @brief Lock group object
++ *
++ * Most group functions will lock the group object themselves. The expection is
++ * the group_bottom_half which requires the group to be locked on entry.
++ *
++ * @param group Pointer to group to lock
++ */
++void mali_group_lock(struct mali_group *group);
++
++/** @brief Unlock group object
++ *
++ * @param group Pointer to group to unlock
++ */
++void mali_group_unlock(struct mali_group *group);
++#ifdef DEBUG
++void mali_group_assert_locked(struct mali_group *group);
++#define MALI_ASSERT_GROUP_LOCKED(group) mali_group_assert_locked(group)
++#else
++#define MALI_ASSERT_GROUP_LOCKED(group)
++#endif
++
++/** @brief Start GP job
++ */
++_mali_osk_errcode_t mali_group_start_gp_job(struct mali_group *group, struct mali_gp_job *job);
++/** @brief Start fragment of PP job
++ */
++_mali_osk_errcode_t mali_group_start_pp_job(struct mali_group *group, struct mali_pp_job *job, u32 sub_job);
++
++/** @brief Resume GP job that suspended waiting for more heap memory
++ */
++struct mali_gp_job *mali_group_resume_gp_with_new_heap(struct mali_group *group, u32 job_id, u32 start_addr, u32 end_addr);
++/** @brief Abort GP job
++ *
++ * Used to abort suspended OOM jobs when user space failed to allocte more memory.
++ */
++void mali_group_abort_gp_job(struct mali_group *group, u32 job_id);
++/** @brief Abort all GP jobs from \a session
++ *
++ * Used on session close when terminating all running and queued jobs from \a session.
++ */
++void mali_group_abort_session(struct mali_group *group, struct mali_session_data *session);
++
++void mali_group_power_on(void);
++void mali_group_power_off(void);
++mali_bool mali_group_power_is_on(struct mali_group *group);
++
++struct mali_group *mali_group_get_glob_group(u32 index);
++u32 mali_group_get_glob_num_groups(void);
++
++u32 mali_group_dump_state(struct mali_group *group, char *buf, u32 size);
++
++/* MMU-related functions */
++_mali_osk_errcode_t mali_group_upper_half_mmu(void * data);
++
++/* GP-related functions */
++_mali_osk_errcode_t mali_group_upper_half_gp(void *data);
++
++/* PP-related functions */
++_mali_osk_errcode_t mali_group_upper_half_pp(void *data);
++
++#endif /* __MALI_GROUP_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_hw_core.c b/drivers/gpu/arm/mali400/mali/common/mali_hw_core.c
+new file mode 100644
+index 0000000..264f3ae
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_hw_core.c
+@@ -0,0 +1,47 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_hw_core.h"
++#include "mali_osk.h"
++#include "mali_kernel_common.h"
++
++_mali_osk_errcode_t mali_hw_core_create(struct mali_hw_core *core, const _mali_osk_resource_t *resource, u32 reg_size)
++{
++      core->phys_addr = resource->base;
++      core->description = resource->description;
++      core->size = reg_size;
++
++      if (_MALI_OSK_ERR_OK == _mali_osk_mem_reqregion(core->phys_addr, core->size, core->description))
++      {
++              core->mapped_registers = _mali_osk_mem_mapioregion(core->phys_addr, core->size, core->description);
++              if (NULL != core->mapped_registers)
++              {
++                      return _MALI_OSK_ERR_OK;
++              }
++              else
++              {
++                      MALI_PRINT_ERROR(("Failed to map memory region for core %s at phys_addr 0x%08X\n", core->description, core->phys_addr));
++              }
++              _mali_osk_mem_unreqregion(core->phys_addr, core->size);
++      }
++      else
++      {
++              MALI_PRINT_ERROR(("Failed to request memory region for core %s at phys_addr 0x%08X\n", core->description, core->phys_addr));
++      }
++
++      return _MALI_OSK_ERR_FAULT;
++}
++
++void mali_hw_core_delete(struct mali_hw_core *core)
++{
++      _mali_osk_mem_unmapioregion(core->phys_addr, core->size, core->mapped_registers);
++      core->mapped_registers = NULL;
++      _mali_osk_mem_unreqregion(core->phys_addr, core->size);
++}
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_hw_core.h b/drivers/gpu/arm/mali400/mali/common/mali_hw_core.h
+new file mode 100644
+index 0000000..bea4266
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_hw_core.h
+@@ -0,0 +1,104 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_HW_CORE_H__
++#define __MALI_HW_CORE_H__
++
++#include "mali_osk.h"
++#include "mali_kernel_common.h"
++
++/**
++ * The common parts for all Mali HW cores (GP, PP, MMU, L2 and PMU)
++ * This struct is embedded inside all core specific structs.
++ */
++struct mali_hw_core
++{
++      u32 phys_addr;                    /**< Physical address of the registers */
++      u32 size;                         /**< Size of registers */
++      mali_io_address mapped_registers; /**< Virtual mapping of the registers */
++      const char* description;          /**< Name of unit (as specified in device configuration) */
++};
++
++#define MALI_REG_POLL_COUNT_FAST 1000
++#define MALI_REG_POLL_COUNT_SLOW 1000000
++
++_mali_osk_errcode_t mali_hw_core_create(struct mali_hw_core *core, const _mali_osk_resource_t *resource, u32 reg_size);
++void mali_hw_core_delete(struct mali_hw_core *core);
++
++MALI_STATIC_INLINE u32 mali_hw_core_register_read(struct mali_hw_core *core, u32 relative_address)
++{
++      u32 read_val;
++      read_val = _mali_osk_mem_ioread32(core->mapped_registers, relative_address);
++      MALI_DEBUG_PRINT(6, ("register_read for core %s, relative addr=0x%04X, val=0x%08X\n",
++                           core->description, relative_address, read_val));
++      return read_val;
++}
++
++MALI_STATIC_INLINE void mali_hw_core_register_write_relaxed(struct mali_hw_core *core, u32 relative_address, u32 new_val)
++{
++      MALI_DEBUG_PRINT(6, ("register_write_relaxed for core %s, relative addr=0x%04X, val=0x%08X\n",
++                            core->description, relative_address, new_val));
++      _mali_osk_mem_iowrite32_relaxed(core->mapped_registers, relative_address, new_val);
++}
++
++/* Conditionally write a register.
++ * The register will only be written if the new value is different from the old_value.
++ * If the new value is different, the old value will also be updated */
++MALI_STATIC_INLINE void mali_hw_core_register_write_relaxed_conditional(struct mali_hw_core *core, u32 relative_address, u32 new_val, const u32 old_val)
++{
++      MALI_DEBUG_PRINT(6, ("register_write_relaxed for core %s, relative addr=0x%04X, val=0x%08X\n",
++                            core->description, relative_address, new_val));
++      if(old_val != new_val)
++      {
++              _mali_osk_mem_iowrite32_relaxed(core->mapped_registers, relative_address, new_val);
++      }
++}
++
++
++MALI_STATIC_INLINE void mali_hw_core_register_write(struct mali_hw_core *core, u32 relative_address, u32 new_val)
++{
++      MALI_DEBUG_PRINT(6, ("register_write for core %s, relative addr=0x%04X, val=0x%08X\n",
++                            core->description, relative_address, new_val));
++      _mali_osk_mem_iowrite32(core->mapped_registers, relative_address, new_val);
++}
++
++MALI_STATIC_INLINE void mali_hw_core_register_write_array_relaxed(struct mali_hw_core *core, u32 relative_address, u32 *write_array, u32 nr_of_regs)
++{
++      u32 i;
++      MALI_DEBUG_PRINT(6, ("register_write_array: for core %s, relative addr=0x%04X, nr of regs=%u\n",
++                           core->description,relative_address, nr_of_regs));
++
++      /* Do not use burst writes against the registers */
++      for (i = 0; i< nr_of_regs; i++)
++      {
++              mali_hw_core_register_write_relaxed(core, relative_address + i*4, write_array[i]);
++      }
++}
++
++/* Conditionally write a set of registers.
++ * The register will only be written if the new value is different from the old_value.
++ * If the new value is different, the old value will also be updated */
++MALI_STATIC_INLINE void mali_hw_core_register_write_array_relaxed_conditional(struct mali_hw_core *core, u32 relative_address, u32 *write_array, u32 nr_of_regs, const u32* old_array)
++{
++      u32 i;
++      MALI_DEBUG_PRINT(6, ("register_write_array: for core %s, relative addr=0x%04X, nr of regs=%u\n",
++                           core->description,relative_address, nr_of_regs));
++
++      /* Do not use burst writes against the registers */
++      for (i = 0; i< nr_of_regs; i++)
++      {
++              if(old_array[i] != write_array[i])
++              {
++                      mali_hw_core_register_write_relaxed(core, relative_address + i*4, write_array[i]);
++              }
++      }
++}
++
++#endif /* __MALI_HW_CORE_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_kernel_common.h b/drivers/gpu/arm/mali400/mali/common/mali_kernel_common.h
+new file mode 100644
+index 0000000..6d60d11
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_kernel_common.h
+@@ -0,0 +1,186 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_KERNEL_COMMON_H__
++#define __MALI_KERNEL_COMMON_H__
++
++#include "mali_osk.h"
++
++/* Make sure debug is defined when it should be */
++#ifndef DEBUG
++      #if defined(_DEBUG)
++              #define DEBUG
++      #endif
++#endif
++
++/* MALI_SEC */
++/* Macro for generating a kernel panic.
++ * Turned on off by compile-time Makefile settings
++ */
++#if defined(USING_KERNEL_PANIC)
++#include <linux/kernel.h>
++      #define MALI_PANIC(fmt, args...) panic( fmt, ## args );
++#else
++      #define MALI_PANIC(fmt, args...) 
++#endif
++
++/* The file include several useful macros for error checking, debugging and printing.
++ * - MALI_PRINTF(...)           Do not use this function: Will be included in Release builds.
++ * - MALI_DEBUG_PRINT(nr, (X) ) Prints the second argument if nr<=MALI_DEBUG_LEVEL.
++ * - MALI_DEBUG_ERROR( (X) )    Prints an errortext, a source trace, and the given error message.
++ * - MALI_DEBUG_ASSERT(exp,(X)) If the asserted expr is false, the program will exit.
++ * - MALI_DEBUG_ASSERT_POINTER(pointer)  Triggers if the pointer is a zero pointer.
++ * - MALI_DEBUG_CODE( X )       The code inside the macro is only compiled in Debug builds.
++ *
++ * The (X) means that you must add an extra parenthesis around the argumentlist.
++ *
++ * The  printf function: MALI_PRINTF(...) is routed to _mali_osk_debugmsg
++ *
++ * Suggested range for the DEBUG-LEVEL is [1:6] where
++ * [1:2] Is messages with highest priority, indicate possible errors.
++ * [3:4] Is messages with medium priority, output important variables.
++ * [5:6] Is messages with low priority, used during extensive debugging.
++ */
++
++ /**
++ *  Fundamental error macro. Reports an error code. This is abstracted to allow us to
++ *  easily switch to a different error reporting method if we want, and also to allow
++ *  us to search for error returns easily.
++ *
++ *  Note no closing semicolon - this is supplied in typical usage:
++ *
++ *  MALI_ERROR(MALI_ERROR_OUT_OF_MEMORY);
++ */
++#define MALI_ERROR(error_code) return (error_code)
++
++/**
++ *  Basic error macro, to indicate success.
++ *  Note no closing semicolon - this is supplied in typical usage:
++ *
++ *  MALI_SUCCESS;
++ */
++#define MALI_SUCCESS MALI_ERROR(_MALI_OSK_ERR_OK)
++
++/**
++ *    Basic error macro. This checks whether the given condition is true, and if not returns
++ *    from this function with the supplied error code. This is a macro so that we can override it
++ *    for stress testing.
++ *
++ *    Note that this uses the do-while-0 wrapping to ensure that we don't get problems with dangling
++ *    else clauses. Note also no closing semicolon - this is supplied in typical usage:
++ *
++ *    MALI_CHECK((p!=NULL), ERROR_NO_OBJECT);
++ */
++#define MALI_CHECK(condition, error_code) do { if(!(condition)) MALI_ERROR(error_code); } while(0)
++
++/**
++ *    Error propagation macro. If the expression given is anything other than _MALI_OSK_NO_ERROR,
++ *    then the value is returned from the enclosing function as an error code. This effectively
++ *    acts as a guard clause, and propagates error values up the call stack. This uses a
++ *    temporary value to ensure that the error expression is not evaluated twice.
++ *  If the counter for forcing a failure has been set using _mali_force_error, this error will be
++ *  returned without evaluating the expression in MALI_CHECK_NO_ERROR
++ */
++#define MALI_CHECK_NO_ERROR(expression) \
++    do { _mali_osk_errcode_t _check_no_error_result=(expression); \
++         if(_check_no_error_result != _MALI_OSK_ERR_OK) \
++         MALI_ERROR(_check_no_error_result); \
++    } while(0)
++
++/**
++ *  Pointer check macro. Checks non-null pointer.
++ */
++#define MALI_CHECK_NON_NULL(pointer, error_code) MALI_CHECK( ((pointer)!=NULL), (error_code) )
++
++/**
++ *    Error macro with goto. This checks whether the given condition is true, and if not jumps
++ *    to the specified label using a goto. The label must therefore be local to the function in
++ *    which this macro appears. This is most usually used to execute some clean-up code before
++ *    exiting with a call to ERROR.
++ *
++ *    Like the other macros, this is a macro to allow us to override the condition if we wish,
++ *    e.g. to force an error during stress testing.
++ */
++#define MALI_CHECK_GOTO(condition, label) do { if(!(condition)) goto label; } while(0)
++
++/**
++ *  Explicitly ignore a parameter passed into a function, to suppress compiler warnings.
++ *  Should only be used with parameter names.
++ */
++#define MALI_IGNORE(x) x=x
++
++#define MALI_PRINTF(args) _mali_osk_dbgmsg args;
++
++#define MALI_PRINT_ERROR(args) do{ \
++      MALI_PRINTF(("Mali: ERR: %s\n" ,__FILE__)); \
++      MALI_PRINTF(("           %s()%4d\n           ", __FUNCTION__, __LINE__)) ; \
++      MALI_PRINTF(args); \
++      MALI_PRINTF(("\n")); \
++      } while(0)
++
++#define MALI_PRINT(args) do{ \
++      MALI_PRINTF(("Mali: ")); \
++      MALI_PRINTF(args); \
++      } while (0)
++
++#ifdef DEBUG
++#ifndef mali_debug_level
++extern int mali_debug_level;
++#endif
++
++#define MALI_DEBUG_CODE(code) code
++#define MALI_DEBUG_PRINT(level, args)  do { \
++      if((level) <=  mali_debug_level)\
++        {MALI_PRINTF(("Mali<" #level ">: ")); MALI_PRINTF(args); } \
++      } while (0)
++
++#define MALI_DEBUG_PRINT_ERROR(args) MALI_PRINT_ERROR(args)
++
++#define MALI_DEBUG_PRINT_IF(level,condition,args)  \
++      if((condition)&&((level) <=  mali_debug_level))\
++        {MALI_PRINTF(("Mali<" #level ">: ")); MALI_PRINTF(args); }
++
++#define MALI_DEBUG_PRINT_ELSE(level, args)\
++      else if((level) <=  mali_debug_level)\
++    { MALI_PRINTF(("Mali<" #level ">: ")); MALI_PRINTF(args); }
++
++/**
++ * @note these variants of DEBUG ASSERTS will cause a debugger breakpoint
++ * to be entered (see _mali_osk_break() ). An alternative would be to call
++ * _mali_osk_abort(), on OSs that support it.
++ */
++#define MALI_DEBUG_PRINT_ASSERT(condition, args) do  {if( !(condition)) { MALI_PRINT_ERROR(args); _mali_osk_break(); } } while(0)
++#define MALI_DEBUG_ASSERT_POINTER(pointer) do  {if( (pointer)== NULL) {MALI_PRINT_ERROR(("NULL pointer " #pointer)); _mali_osk_break();} } while(0)
++#define MALI_DEBUG_ASSERT(condition) do  {if( !(condition)) {MALI_PRINT_ERROR(("ASSERT failed: " #condition )); _mali_osk_break();} } while(0)
++
++#else /* DEBUG */
++
++#define MALI_DEBUG_CODE(code)
++#define MALI_DEBUG_PRINT(string,args) do {} while(0)
++#define MALI_DEBUG_PRINT_ERROR(args) do {} while(0)
++#define MALI_DEBUG_PRINT_IF(level,condition,args) do {} while(0)
++#define MALI_DEBUG_PRINT_ELSE(level,condition,args) do {} while(0)
++#define MALI_DEBUG_PRINT_ASSERT(condition,args) do {} while(0)
++#define MALI_DEBUG_ASSERT_POINTER(pointer) do {} while(0)
++#define MALI_DEBUG_ASSERT(condition) do {} while(0)
++
++#endif /* DEBUG */
++
++/**
++ * variables from user space cannot be dereferenced from kernel space; tagging them
++ * with __user allows the GCC compiler to generate a warning. Other compilers may
++ * not support this so we define it here as an empty macro if the compiler doesn't
++ * define it.
++ */
++#ifndef __user
++#define __user
++#endif
++
++#endif /* __MALI_KERNEL_COMMON_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_kernel_core.c b/drivers/gpu/arm/mali400/mali/common/mali_kernel_core.c
+new file mode 100644
+index 0000000..731d122
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_kernel_core.c
+@@ -0,0 +1,1150 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_kernel_common.h"
++#include "mali_session.h"
++#include "mali_osk.h"
++#include "mali_osk_mali.h"
++#include "mali_ukk.h"
++#include "mali_kernel_core.h"
++#include "mali_memory.h"
++#include "mali_mem_validation.h"
++#include "mali_mmu.h"
++#include "mali_mmu_page_directory.h"
++#include "mali_dlbu.h"
++#include "mali_broadcast.h"
++#include "mali_gp.h"
++#include "mali_pp.h"
++#include "mali_gp_scheduler.h"
++#include "mali_pp_scheduler.h"
++#include "mali_group.h"
++#include "mali_pm.h"
++#include "mali_pmu.h"
++#include "mali_scheduler.h"
++#include "mali_kernel_utilization.h"
++#include "mali_l2_cache.h"
++#if defined(CONFIG_MALI400_PROFILING)
++#include "mali_osk_profiling.h"
++#endif
++#if defined(CONFIG_MALI400_INTERNAL_PROFILING)
++#include "mali_profiling_internal.h"
++#endif
++
++
++/* Mali GPU memory. Real values come from module parameter or from device specific data */
++int mali_dedicated_mem_start = 0;
++int mali_dedicated_mem_size = 0;
++int mali_shared_mem_size = 0;
++
++/* Frame buffer memory to be accessible by Mali GPU */
++int mali_fb_start = 0;
++int mali_fb_size = 0;
++
++/** Start profiling from module load? */
++int mali_boot_profiling = 0;
++
++/** Limits for the number of PP cores behind each L2 cache. */
++int mali_max_pp_cores_group_1 = 0xFF;
++int mali_max_pp_cores_group_2 = 0xFF;
++
++int mali_inited_pp_cores_group_1 = 0;
++int mali_inited_pp_cores_group_2 = 0;
++
++static _mali_product_id_t global_product_id = _MALI_PRODUCT_ID_UNKNOWN;
++static u32 global_gpu_base_address = 0;
++static u32 global_gpu_major_version = 0;
++static u32 global_gpu_minor_version = 0;
++
++/* MALI_SEC */
++static u32 first_pp_offset = 0;
++
++#define HANG_CHECK_MSECS_DEFAULT 500 /* 500 ms */
++#define WATCHDOG_MSECS_DEFAULT 4000 /* 4 s */
++
++/* timer related */
++int mali_max_job_runtime = WATCHDOG_MSECS_DEFAULT;
++int mali_hang_check_interval = HANG_CHECK_MSECS_DEFAULT;
++
++static _mali_osk_errcode_t mali_parse_product_info(void)
++{
++      /*
++       * Mali-200 has the PP core first, while Mali-300, Mali-400 and Mali-450 have the GP core first.
++       * Look at the version register for the first PP core in order to determine the GPU HW revision.
++       */
++
++      u32 first_pp_offset;
++      _mali_osk_resource_t first_pp_resource;
++
++      global_gpu_base_address = _mali_osk_resource_base_address();
++      if (0 == global_gpu_base_address)
++      {
++              return _MALI_OSK_ERR_ITEM_NOT_FOUND;
++      }
++
++      /* Find out where the first PP core is located */
++      if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x8000, NULL))
++      {
++              /* Mali-300/400/450 */
++              first_pp_offset = 0x8000;
++      }
++      else
++      {
++              /* Mali-200 */
++              first_pp_offset = 0x0000;
++      }
++
++      /* Find the first PP core resource (again) */
++      if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + first_pp_offset, &first_pp_resource))
++      {
++              /* Create a dummy PP object for this core so that we can read the version register */
++              struct mali_group *group = mali_group_create(NULL, NULL, NULL);
++              if (NULL != group)
++              {
++                      struct mali_pp_core *pp_core = mali_pp_create(&first_pp_resource, group, MALI_FALSE);
++                      if (NULL != pp_core)
++                      {
++                              u32 pp_version = mali_pp_core_get_version(pp_core);
++                              mali_group_delete(group);
++
++                              global_gpu_major_version = (pp_version >> 8) & 0xFF;
++                              global_gpu_minor_version = pp_version & 0xFF;
++
++                              switch (pp_version >> 16)
++                              {
++                                      case MALI200_PP_PRODUCT_ID:
++                                              global_product_id = _MALI_PRODUCT_ID_MALI200;
++                                              MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-200 r%up%u\n", global_gpu_major_version, global_gpu_minor_version));
++                                              break;
++                                      case MALI300_PP_PRODUCT_ID:
++                                              global_product_id = _MALI_PRODUCT_ID_MALI300;
++                                              MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-300 r%up%u\n", global_gpu_major_version, global_gpu_minor_version));
++                                              break;
++                                      case MALI400_PP_PRODUCT_ID:
++                                              global_product_id = _MALI_PRODUCT_ID_MALI400;
++                                              MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-400 MP r%up%u\n", global_gpu_major_version, global_gpu_minor_version));
++                                              break;
++                                      case MALI450_PP_PRODUCT_ID:
++                                              global_product_id = _MALI_PRODUCT_ID_MALI450;
++                                              MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-450 MP r%up%u\n", global_gpu_major_version, global_gpu_minor_version));
++                                              break;
++                                      default:
++                                              MALI_DEBUG_PRINT(2, ("Found unknown Mali GPU (r%up%u)\n", global_gpu_major_version, global_gpu_minor_version));
++                                              return _MALI_OSK_ERR_FAULT;
++                              }
++
++                              return _MALI_OSK_ERR_OK;
++                      }
++                      else
++                      {
++                              MALI_PRINT_ERROR(("Failed to create initial PP object\n"));
++                      }
++              }
++              else
++              {
++                      MALI_PRINT_ERROR(("Failed to create initial group object\n"));
++              }
++      }
++      else
++      {
++              MALI_PRINT_ERROR(("First PP core not specified in config file\n"));
++      }
++
++      return _MALI_OSK_ERR_FAULT;
++}
++
++
++void mali_resource_count(u32 *pp_count, u32 *l2_count)
++{
++      *pp_count = 0;
++      *l2_count = 0;
++
++      if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x08000, NULL))
++      {
++              ++(*pp_count);
++      }
++      if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x0A000, NULL))
++      {
++              ++(*pp_count);
++      }
++      if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x0C000, NULL))
++      {
++              ++(*pp_count);
++      }
++      if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x0E000, NULL))
++      {
++              ++(*pp_count);
++      }
++      if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x28000, NULL))
++      {
++              ++(*pp_count);
++      }
++      if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x2A000, NULL))
++      {
++              ++(*pp_count);
++      }
++      if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x2C000, NULL))
++      {
++              ++(*pp_count);
++      }
++      if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x2E000, NULL))
++      {
++              ++(*pp_count);
++      }
++
++      if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x1000, NULL))
++      {
++              ++(*l2_count);
++      }
++      if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x10000, NULL))
++      {
++              ++(*l2_count);
++      }
++      if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x11000, NULL))
++      {
++              ++(*l2_count);
++      }
++}
++
++static void mali_delete_l2_cache_cores(void)
++{
++      u32 i;
++      u32 number_of_l2_ccores = mali_l2_cache_core_get_glob_num_l2_cores();
++
++      for (i = 0; i < number_of_l2_ccores; i++)
++      {
++              mali_l2_cache_delete(mali_l2_cache_core_get_glob_l2_core(i));
++      }
++}
++
++static _mali_osk_errcode_t mali_create_l2_cache_core(_mali_osk_resource_t *resource)
++{
++      if (NULL != resource)
++      {
++              struct mali_l2_cache_core *l2_cache;
++
++              MALI_DEBUG_PRINT(3, ("Found L2 cache %s\n", resource->description));
++
++              l2_cache = mali_l2_cache_create(resource);
++              if (NULL == l2_cache)
++              {
++                      MALI_PRINT_ERROR(("Failed to create L2 cache object\n"));
++                      return _MALI_OSK_ERR_FAULT;
++              }
++      }
++      MALI_DEBUG_PRINT(3, ("Created L2 cache core object\n"));
++
++      return _MALI_OSK_ERR_OK;
++}
++
++static _mali_osk_errcode_t mali_parse_config_l2_cache(void)
++{
++      if (_MALI_PRODUCT_ID_MALI200 == global_product_id)
++      {
++              /* Create dummy L2 cache - nothing happens here!!! */
++              return mali_create_l2_cache_core(NULL);
++      }
++      else if (_MALI_PRODUCT_ID_MALI300 == global_product_id || _MALI_PRODUCT_ID_MALI400 == global_product_id)
++      {
++              _mali_osk_resource_t l2_resource;
++              if (_MALI_OSK_ERR_OK != _mali_osk_resource_find(global_gpu_base_address + 0x1000, &l2_resource))
++              {
++                      MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache in config file\n"));
++                      return _MALI_OSK_ERR_FAULT;
++              }
++
++              return mali_create_l2_cache_core(&l2_resource);
++      }
++      else if (_MALI_PRODUCT_ID_MALI450 == global_product_id)
++      {
++              /*
++               * L2 for GP    at 0x10000
++               * L2 for PP0-3 at 0x01000
++               * L2 for PP4-7 at 0x11000 (optional)
++               */
++
++              _mali_osk_resource_t l2_gp_resource;
++              _mali_osk_resource_t l2_pp_grp0_resource;
++              _mali_osk_resource_t l2_pp_grp1_resource;
++
++              /* Make cluster for GP's L2 */
++              if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x10000, &l2_gp_resource))
++              {
++                      _mali_osk_errcode_t ret;
++                      MALI_DEBUG_PRINT(3, ("Creating Mali-450 L2 cache core for GP\n"));
++                      ret = mali_create_l2_cache_core(&l2_gp_resource);
++                      if (_MALI_OSK_ERR_OK != ret)
++                      {
++                              return ret;
++                      }
++              }
++              else
++              {
++                      MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache for GP in config file\n"));
++                      return _MALI_OSK_ERR_FAULT;
++              }
++
++              /* Make cluster for first PP core group */
++              if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x1000, &l2_pp_grp0_resource))
++              {
++                      _mali_osk_errcode_t ret;
++                      MALI_DEBUG_PRINT(3, ("Creating Mali-450 L2 cache core for PP group 0\n"));
++                      ret = mali_create_l2_cache_core(&l2_pp_grp0_resource);
++                      if (_MALI_OSK_ERR_OK != ret)
++                      {
++                              return ret;
++                      }
++              }
++              else
++              {
++                      MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache for PP group 0 in config file\n"));
++                      return _MALI_OSK_ERR_FAULT;
++              }
++
++              /* Second PP core group is optional, don't fail if we don't find it */
++              if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x11000, &l2_pp_grp1_resource))
++              {
++                      _mali_osk_errcode_t ret;
++                      MALI_DEBUG_PRINT(3, ("Creating Mali-450 L2 cache core for PP group 1\n"));
++                      ret = mali_create_l2_cache_core(&l2_pp_grp1_resource);
++                      if (_MALI_OSK_ERR_OK != ret)
++                      {
++                              return ret;
++                      }
++              }
++      }
++
++      return _MALI_OSK_ERR_OK;
++}
++
++static _mali_osk_errcode_t mali_create_group(struct mali_l2_cache_core *cache,
++                                             _mali_osk_resource_t *resource_mmu,
++                                             _mali_osk_resource_t *resource_gp,
++                                             _mali_osk_resource_t *resource_pp)
++{
++      struct mali_mmu_core *mmu;
++      struct mali_group *group;
++
++      MALI_DEBUG_PRINT(3, ("Starting new group for MMU %s\n", resource_mmu->description));
++
++      /* Create the group object */
++      group = mali_group_create(cache, NULL, NULL);
++      if (NULL == group)
++      {
++              MALI_PRINT_ERROR(("Failed to create group object for MMU %s\n", resource_mmu->description));
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      /* Create the MMU object inside group */
++      mmu = mali_mmu_create(resource_mmu, group, MALI_FALSE);
++      if (NULL == mmu)
++      {
++              MALI_PRINT_ERROR(("Failed to create MMU object\n"));
++              mali_group_delete(group);
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      if (NULL != resource_gp)
++      {
++              /* Create the GP core object inside this group */
++              struct mali_gp_core *gp_core = mali_gp_create(resource_gp, group);
++              if (NULL == gp_core)
++              {
++                      /* No need to clean up now, as we will clean up everything linked in from the cluster when we fail this function */
++                      MALI_PRINT_ERROR(("Failed to create GP object\n"));
++                      mali_group_delete(group);
++                      return _MALI_OSK_ERR_FAULT;
++              }
++      }
++
++      if (NULL != resource_pp)
++      {
++              struct mali_pp_core *pp_core;
++
++              /* Create the PP core object inside this group */
++              pp_core = mali_pp_create(resource_pp, group, MALI_FALSE);
++              if (NULL == pp_core)
++              {
++                      /* No need to clean up now, as we will clean up everything linked in from the cluster when we fail this function */
++                      MALI_PRINT_ERROR(("Failed to create PP object\n"));
++                      mali_group_delete(group);
++                      return _MALI_OSK_ERR_FAULT;
++              }
++      }
++
++      /* Reset group */
++      mali_group_reset(group);
++
++      return _MALI_OSK_ERR_OK;
++}
++
++static _mali_osk_errcode_t mali_create_virtual_group(_mali_osk_resource_t *resource_mmu_pp_bcast,
++                                                    _mali_osk_resource_t *resource_pp_bcast,
++                                                    _mali_osk_resource_t *resource_dlbu,
++                                                    _mali_osk_resource_t *resource_bcast)
++{
++      struct mali_mmu_core *mmu_pp_bcast_core;
++      struct mali_pp_core *pp_bcast_core;
++      struct mali_dlbu_core *dlbu_core;
++      struct mali_bcast_unit *bcast_core;
++      struct mali_group *group;
++
++      MALI_DEBUG_PRINT(2, ("Starting new virtual group for MMU PP broadcast core %s\n", resource_mmu_pp_bcast->description));
++
++      /* Create the DLBU core object */
++      dlbu_core = mali_dlbu_create(resource_dlbu);
++      if (NULL == dlbu_core)
++      {
++              MALI_PRINT_ERROR(("Failed to create DLBU object \n"));
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      /* Create the Broadcast unit core */
++      bcast_core = mali_bcast_unit_create(resource_bcast);
++      if (NULL == bcast_core)
++      {
++              MALI_PRINT_ERROR(("Failed to create Broadcast unit object!\n"));
++              mali_dlbu_delete(dlbu_core);
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      /* Create the group object */
++      group = mali_group_create(NULL, dlbu_core, bcast_core);
++      if (NULL == group)
++      {
++              MALI_PRINT_ERROR(("Failed to create group object for MMU PP broadcast core %s\n", resource_mmu_pp_bcast->description));
++              mali_bcast_unit_delete(bcast_core);
++              mali_dlbu_delete(dlbu_core);
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      /* Create the MMU object inside group */
++      mmu_pp_bcast_core = mali_mmu_create(resource_mmu_pp_bcast, group, MALI_TRUE);
++      if (NULL == mmu_pp_bcast_core)
++      {
++              MALI_PRINT_ERROR(("Failed to create MMU PP broadcast object\n"));
++              mali_group_delete(group);
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      /* Create the PP core object inside this group */
++      pp_bcast_core = mali_pp_create(resource_pp_bcast, group, MALI_TRUE);
++      if (NULL == pp_bcast_core)
++      {
++              /* No need to clean up now, as we will clean up everything linked in from the cluster when we fail this function */
++              MALI_PRINT_ERROR(("Failed to create PP object\n"));
++              mali_group_delete(group);
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      return _MALI_OSK_ERR_OK;
++}
++
++static _mali_osk_errcode_t mali_parse_config_groups(void)
++{
++      if (_MALI_PRODUCT_ID_MALI200 == global_product_id)
++      {
++              _mali_osk_errcode_t err;
++              _mali_osk_resource_t resource_gp;
++              _mali_osk_resource_t resource_pp;
++              _mali_osk_resource_t resource_mmu;
++
++              MALI_DEBUG_ASSERT(1 == mali_l2_cache_core_get_glob_num_l2_cores());
++
++              if (_MALI_OSK_ERR_OK != _mali_osk_resource_find(global_gpu_base_address + 0x02000, &resource_gp) ||
++                  _MALI_OSK_ERR_OK != _mali_osk_resource_find(global_gpu_base_address + 0x00000, &resource_pp) ||
++                  _MALI_OSK_ERR_OK != _mali_osk_resource_find(global_gpu_base_address + 0x03000, &resource_mmu))
++              {
++                      /* Missing mandatory core(s) */
++                      return _MALI_OSK_ERR_FAULT;
++              }
++
++              err = mali_create_group(mali_l2_cache_core_get_glob_l2_core(0), &resource_mmu, &resource_gp, &resource_pp);
++              if (err == _MALI_OSK_ERR_OK)
++              {
++                      mali_inited_pp_cores_group_1++;
++                      mali_max_pp_cores_group_1 = mali_inited_pp_cores_group_1; /* always 1 */
++                      mali_max_pp_cores_group_2 = mali_inited_pp_cores_group_2; /* always zero */
++              }
++
++              return err;
++      }
++      else if (_MALI_PRODUCT_ID_MALI300 == global_product_id ||
++               _MALI_PRODUCT_ID_MALI400 == global_product_id ||
++               _MALI_PRODUCT_ID_MALI450 == global_product_id)
++      {
++              _mali_osk_errcode_t err;
++              int cluster_id_gp = 0;
++              int cluster_id_pp_grp0 = 0;
++              int cluster_id_pp_grp1 = 0;
++              int i;
++
++              _mali_osk_resource_t resource_gp;
++              _mali_osk_resource_t resource_gp_mmu;
++              _mali_osk_resource_t resource_pp[8];
++              _mali_osk_resource_t resource_pp_mmu[8];
++              _mali_osk_resource_t resource_pp_mmu_bcast;
++              _mali_osk_resource_t resource_pp_bcast;
++              _mali_osk_resource_t resource_dlbu;
++              _mali_osk_resource_t resource_bcast;
++              _mali_osk_errcode_t resource_gp_found;
++              _mali_osk_errcode_t resource_gp_mmu_found;
++              _mali_osk_errcode_t resource_pp_found[8];
++              _mali_osk_errcode_t resource_pp_mmu_found[8];
++              _mali_osk_errcode_t resource_pp_mmu_bcast_found;
++              _mali_osk_errcode_t resource_pp_bcast_found;
++              _mali_osk_errcode_t resource_dlbu_found;
++              _mali_osk_errcode_t resource_bcast_found;
++
++              if (_MALI_PRODUCT_ID_MALI450 == global_product_id)
++              {
++                      /* Mali-450 have separate L2s for GP, and PP core group(s) */
++                      cluster_id_pp_grp0 = 1;
++                      cluster_id_pp_grp1 = 2;
++              }
++
++              resource_gp_found = _mali_osk_resource_find(global_gpu_base_address + 0x00000, &resource_gp);
++              resource_gp_mmu_found = _mali_osk_resource_find(global_gpu_base_address + 0x03000, &resource_gp_mmu);
++              resource_pp_found[0] = _mali_osk_resource_find(global_gpu_base_address + 0x08000, &(resource_pp[0]));
++              resource_pp_found[1] = _mali_osk_resource_find(global_gpu_base_address + 0x0A000, &(resource_pp[1]));
++              resource_pp_found[2] = _mali_osk_resource_find(global_gpu_base_address + 0x0C000, &(resource_pp[2]));
++              resource_pp_found[3] = _mali_osk_resource_find(global_gpu_base_address + 0x0E000, &(resource_pp[3]));
++              resource_pp_found[4] = _mali_osk_resource_find(global_gpu_base_address + 0x28000, &(resource_pp[4]));
++              resource_pp_found[5] = _mali_osk_resource_find(global_gpu_base_address + 0x2A000, &(resource_pp[5]));
++              resource_pp_found[6] = _mali_osk_resource_find(global_gpu_base_address + 0x2C000, &(resource_pp[6]));
++              resource_pp_found[7] = _mali_osk_resource_find(global_gpu_base_address + 0x2E000, &(resource_pp[7]));
++              resource_pp_mmu_found[0] = _mali_osk_resource_find(global_gpu_base_address + 0x04000, &(resource_pp_mmu[0]));
++              resource_pp_mmu_found[1] = _mali_osk_resource_find(global_gpu_base_address + 0x05000, &(resource_pp_mmu[1]));
++              resource_pp_mmu_found[2] = _mali_osk_resource_find(global_gpu_base_address + 0x06000, &(resource_pp_mmu[2]));
++              resource_pp_mmu_found[3] = _mali_osk_resource_find(global_gpu_base_address + 0x07000, &(resource_pp_mmu[3]));
++              resource_pp_mmu_found[4] = _mali_osk_resource_find(global_gpu_base_address + 0x1C000, &(resource_pp_mmu[4]));
++              resource_pp_mmu_found[5] = _mali_osk_resource_find(global_gpu_base_address + 0x1D000, &(resource_pp_mmu[5]));
++              resource_pp_mmu_found[6] = _mali_osk_resource_find(global_gpu_base_address + 0x1E000, &(resource_pp_mmu[6]));
++              resource_pp_mmu_found[7] = _mali_osk_resource_find(global_gpu_base_address + 0x1F000, &(resource_pp_mmu[7]));
++
++
++              if (_MALI_PRODUCT_ID_MALI450 == global_product_id)
++              {
++                      resource_bcast_found = _mali_osk_resource_find(global_gpu_base_address + 0x13000, &resource_bcast);
++                      resource_dlbu_found = _mali_osk_resource_find(global_gpu_base_address + 0x14000, &resource_dlbu);
++                      resource_pp_mmu_bcast_found = _mali_osk_resource_find(global_gpu_base_address + 0x15000, &resource_pp_mmu_bcast);
++                      resource_pp_bcast_found = _mali_osk_resource_find(global_gpu_base_address + 0x16000, &resource_pp_bcast);
++
++                      if (_MALI_OSK_ERR_OK != resource_bcast_found ||
++                          _MALI_OSK_ERR_OK != resource_dlbu_found ||
++                          _MALI_OSK_ERR_OK != resource_pp_mmu_bcast_found ||
++                          _MALI_OSK_ERR_OK != resource_pp_bcast_found)
++                      {
++                              /* Missing mandatory core(s) for Mali-450 */
++                              MALI_DEBUG_PRINT(2, ("Missing mandatory resources, Mali-450 needs DLBU, Broadcast unit, virtual PP core and virtual MMU\n"));
++                              return _MALI_OSK_ERR_FAULT;
++                      }
++              }
++
++              if (_MALI_OSK_ERR_OK != resource_gp_found ||
++                  _MALI_OSK_ERR_OK != resource_gp_mmu_found ||
++                  _MALI_OSK_ERR_OK != resource_pp_found[0] ||
++                  _MALI_OSK_ERR_OK != resource_pp_mmu_found[0])
++              {
++                      /* Missing mandatory core(s) */
++                      MALI_DEBUG_PRINT(2, ("Missing mandatory resource, need at least one GP and one PP, both with a separate MMU\n"));
++                      return _MALI_OSK_ERR_FAULT;
++              }
++
++              MALI_DEBUG_ASSERT(1 <= mali_l2_cache_core_get_glob_num_l2_cores());
++              err = mali_create_group(mali_l2_cache_core_get_glob_l2_core(cluster_id_gp), &resource_gp_mmu, &resource_gp, NULL);
++              if (err != _MALI_OSK_ERR_OK)
++              {
++                      return err;
++              }
++
++              /* Create group for first (and mandatory) PP core */
++              MALI_DEBUG_ASSERT(mali_l2_cache_core_get_glob_num_l2_cores() >= (cluster_id_pp_grp0 + 1)); /* >= 1 on Mali-300 and Mali-400, >= 2 on Mali-450 */
++              err = mali_create_group(mali_l2_cache_core_get_glob_l2_core(cluster_id_pp_grp0), &resource_pp_mmu[0], NULL, &resource_pp[0]);
++              if (err != _MALI_OSK_ERR_OK)
++              {
++                      return err;
++              }
++
++              mali_inited_pp_cores_group_1++;
++
++              /* Create groups for rest of the cores in the first PP core group */
++              for (i = 1; i < 4; i++) /* First half of the PP cores belong to first core group */
++              {
++                      if (mali_inited_pp_cores_group_1 < mali_max_pp_cores_group_1)
++                      {
++                              if (_MALI_OSK_ERR_OK == resource_pp_found[i] && _MALI_OSK_ERR_OK == resource_pp_mmu_found[i])
++                              {
++                                      err = mali_create_group(mali_l2_cache_core_get_glob_l2_core(cluster_id_pp_grp0), &resource_pp_mmu[i], NULL, &resource_pp[i]);
++                                      if (err != _MALI_OSK_ERR_OK)
++                                      {
++                                              return err;
++                                      }
++                                      mali_inited_pp_cores_group_1++;
++                              }
++                      }
++              }
++
++              /* Create groups for cores in the second PP core group */
++              for (i = 4; i < 8; i++) /* Second half of the PP cores belong to second core group */
++              {
++                      if (mali_inited_pp_cores_group_2 < mali_max_pp_cores_group_2)
++                      {
++                              if (_MALI_OSK_ERR_OK == resource_pp_found[i] && _MALI_OSK_ERR_OK == resource_pp_mmu_found[i])
++                              {
++                                      MALI_DEBUG_ASSERT(mali_l2_cache_core_get_glob_num_l2_cores() >= 2); /* Only Mali-450 have a second core group */
++                                      err = mali_create_group(mali_l2_cache_core_get_glob_l2_core(cluster_id_pp_grp1), &resource_pp_mmu[i], NULL, &resource_pp[i]);
++                                      if (err != _MALI_OSK_ERR_OK)
++                                      {
++                                              return err;
++                                      }
++                                      mali_inited_pp_cores_group_2++;
++                              }
++                      }
++              }
++
++              if(_MALI_PRODUCT_ID_MALI450 == global_product_id)
++              {
++                      err = mali_create_virtual_group(&resource_pp_mmu_bcast, &resource_pp_bcast, &resource_dlbu, &resource_bcast);
++                      if (_MALI_OSK_ERR_OK != err)
++                      {
++                              return err;
++                      }
++              }
++
++              mali_max_pp_cores_group_1 = mali_inited_pp_cores_group_1;
++              mali_max_pp_cores_group_2 = mali_inited_pp_cores_group_2;
++              MALI_DEBUG_PRINT(2, ("%d+%d PP cores initialized\n", mali_inited_pp_cores_group_1, mali_inited_pp_cores_group_2));
++
++              return _MALI_OSK_ERR_OK;
++      }
++
++      /* No known HW core */
++      return _MALI_OSK_ERR_FAULT;
++}
++
++static _mali_osk_errcode_t mali_parse_config_pmu(void)
++{
++      _mali_osk_resource_t resource_pmu;
++
++      if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x02000, &resource_pmu))
++      {
++              u32 number_of_pp_cores = 0;
++              u32 number_of_l2_caches = 0;
++
++              mali_resource_count(&number_of_pp_cores, &number_of_l2_caches);
++
++              if (NULL == mali_pmu_create(&resource_pmu, number_of_pp_cores, number_of_l2_caches))
++              {
++                      return _MALI_OSK_ERR_FAULT;
++              }
++      }
++
++      /* It's ok if the PMU doesn't exist */
++      return _MALI_OSK_ERR_OK;
++}
++
++static _mali_osk_errcode_t mali_parse_config_memory(void)
++{
++      _mali_osk_errcode_t ret;
++
++      if (0 == mali_dedicated_mem_start && 0 == mali_dedicated_mem_size && 0 == mali_shared_mem_size)
++      {
++              /* Memory settings are not overridden by module parameters, so use device settings */
++              struct _mali_osk_device_data data = { 0, };
++
++              if (_MALI_OSK_ERR_OK == _mali_osk_device_data_get(&data))
++              {
++                      /* Use device specific settings (if defined) */
++                      mali_dedicated_mem_start = data.dedicated_mem_start;
++                      mali_dedicated_mem_size = data.dedicated_mem_size;
++                      mali_shared_mem_size = data.shared_mem_size;
++              }
++
++              if (0 == mali_dedicated_mem_start && 0 == mali_dedicated_mem_size && 0 == mali_shared_mem_size)
++              {
++                      /* No GPU memory specified */
++                      return _MALI_OSK_ERR_INVALID_ARGS;
++              }
++
++              MALI_DEBUG_PRINT(2, ("Using device defined memory settings (dedicated: 0x%08X@0x%08X, shared: 0x%08X)\n",
++                                   mali_dedicated_mem_size, mali_dedicated_mem_start, mali_shared_mem_size));
++      }
++      else
++      {
++              MALI_DEBUG_PRINT(2, ("Using module defined memory settings (dedicated: 0x%08X@0x%08X, shared: 0x%08X)\n",
++                                   mali_dedicated_mem_size, mali_dedicated_mem_start, mali_shared_mem_size));
++      }
++
++      if (0 < mali_dedicated_mem_size && 0 != mali_dedicated_mem_start)
++      {
++              /* Dedicated memory */
++              ret = mali_memory_core_resource_dedicated_memory(mali_dedicated_mem_start, mali_dedicated_mem_size);
++              if (_MALI_OSK_ERR_OK != ret)
++              {
++                      MALI_PRINT_ERROR(("Failed to register dedicated memory\n"));
++                      mali_memory_terminate();
++                      return ret;
++              }
++      }
++
++      if (0 < mali_shared_mem_size)
++      {
++              /* Shared OS memory */
++              ret = mali_memory_core_resource_os_memory(mali_shared_mem_size);
++              if (_MALI_OSK_ERR_OK != ret)
++              {
++                      MALI_PRINT_ERROR(("Failed to register shared OS memory\n"));
++                      mali_memory_terminate();
++                      return ret;
++              }
++      }
++
++      if (0 == mali_fb_start && 0 == mali_fb_size)
++      {
++              /* Frame buffer settings are not overridden by module parameters, so use device settings */
++              struct _mali_osk_device_data data = { 0, };
++
++              if (_MALI_OSK_ERR_OK == _mali_osk_device_data_get(&data))
++              {
++                      /* Use device specific settings (if defined) */
++                      mali_fb_start = data.fb_start;
++                      mali_fb_size = data.fb_size;
++              }
++
++              MALI_DEBUG_PRINT(2, ("Using device defined frame buffer settings (0x%08X@0x%08X)\n",
++                                   mali_fb_size, mali_fb_start));
++      }
++      else
++      {
++              MALI_DEBUG_PRINT(2, ("Using module defined frame buffer settings (0x%08X@0x%08X)\n",
++                                   mali_fb_size, mali_fb_start));
++      }
++
++      if (0 != mali_fb_size)
++      {
++              /* Register frame buffer */
++              ret = mali_mem_validation_add_range(mali_fb_start, mali_fb_size);
++              if (_MALI_OSK_ERR_OK != ret)
++              {
++                      MALI_PRINT_ERROR(("Failed to register frame buffer memory region\n"));
++                      mali_memory_terminate();
++                      return ret;
++              }
++      }
++
++      return _MALI_OSK_ERR_OK;
++}
++
++_mali_osk_errcode_t mali_initialize_subsystems(void)
++{
++      _mali_osk_errcode_t err;
++
++      err = mali_session_initialize();
++      if (_MALI_OSK_ERR_OK != err) goto session_init_failed;
++
++#if defined(CONFIG_MALI400_PROFILING)
++      err = _mali_osk_profiling_init(mali_boot_profiling ? MALI_TRUE : MALI_FALSE);
++      if (_MALI_OSK_ERR_OK != err)
++      {
++              /* No biggie if we wheren't able to initialize the profiling */
++              MALI_PRINT_ERROR(("Failed to initialize profiling, feature will be unavailable\n"));
++      }
++#endif
++
++      err = mali_memory_initialize();
++      if (_MALI_OSK_ERR_OK != err) goto memory_init_failed;
++
++      /* Configure memory early. Memory allocation needed for mali_mmu_initialize. */
++      err = mali_parse_config_memory();
++      if (_MALI_OSK_ERR_OK != err) goto parse_memory_config_failed;
++
++      /* Initialize the MALI PMU */
++      err = mali_parse_config_pmu();
++      if (_MALI_OSK_ERR_OK != err) goto parse_pmu_config_failed;
++
++      /* Initialize the power management module */
++      err = mali_pm_initialize();
++      if (_MALI_OSK_ERR_OK != err) goto pm_init_failed;
++
++      /* Make sure the power stays on for the rest of this function */
++      err = _mali_osk_pm_dev_ref_add();
++      if (_MALI_OSK_ERR_OK != err) goto pm_always_on_failed;
++
++      /* Detect which Mali GPU we are dealing with */
++      err = mali_parse_product_info();
++      if (_MALI_OSK_ERR_OK != err) goto product_info_parsing_failed;
++
++      /* The global_product_id is now populated with the correct Mali GPU */
++
++      /* Initialize MMU module */
++      err = mali_mmu_initialize();
++      if (_MALI_OSK_ERR_OK != err) goto mmu_init_failed;
++
++      if (_MALI_PRODUCT_ID_MALI450 == global_product_id)
++      {
++              err = mali_dlbu_initialize();
++              if (_MALI_OSK_ERR_OK != err) goto dlbu_init_failed;
++      }
++
++      /* Start configuring the actual Mali hardware. */
++      err = mali_parse_config_l2_cache();
++      if (_MALI_OSK_ERR_OK != err) goto config_parsing_failed;
++      err = mali_parse_config_groups();
++      if (_MALI_OSK_ERR_OK != err) goto config_parsing_failed;
++
++      /* Initialize the schedulers */
++      err = mali_scheduler_initialize();
++      if (_MALI_OSK_ERR_OK != err) goto scheduler_init_failed;
++      err = mali_gp_scheduler_initialize();
++      if (_MALI_OSK_ERR_OK != err) goto gp_scheduler_init_failed;
++      err = mali_pp_scheduler_initialize();
++      if (_MALI_OSK_ERR_OK != err) goto pp_scheduler_init_failed;
++
++      /* Initialize the GPU utilization tracking */
++      err = mali_utilization_init();
++      if (_MALI_OSK_ERR_OK != err) goto utilization_init_failed;
++
++      /* Allowing the system to be turned off */
++      _mali_osk_pm_dev_ref_dec();
++
++      MALI_SUCCESS; /* all ok */
++
++      /* Error handling */
++
++utilization_init_failed:
++      mali_pp_scheduler_terminate();
++pp_scheduler_init_failed:
++      mali_gp_scheduler_terminate();
++gp_scheduler_init_failed:
++      mali_scheduler_terminate();
++scheduler_init_failed:
++config_parsing_failed:
++      mali_delete_l2_cache_cores(); /* Delete L2 cache cores even if config parsing failed. */
++dlbu_init_failed:
++      mali_dlbu_terminate();
++mmu_init_failed:
++      mali_mmu_terminate();
++      /* Nothing to roll back */
++product_info_parsing_failed:
++      /* Allowing the system to be turned off */
++      _mali_osk_pm_dev_ref_dec();
++pm_always_on_failed:
++      mali_pm_terminate();
++pm_init_failed:
++      {
++              struct mali_pmu_core *pmu = mali_pmu_get_global_pmu_core();
++              if (NULL != pmu)
++              {
++                      mali_pmu_delete(pmu);
++              }
++      }
++parse_pmu_config_failed:
++      /* undoing mali_parse_config_memory() is done by mali_memory_terminate() */
++parse_memory_config_failed:
++      mali_memory_terminate();
++memory_init_failed:
++#if defined(CONFIG_MALI400_PROFILING)
++      _mali_osk_profiling_term();
++#endif
++      mali_session_terminate();
++session_init_failed:
++      return err;
++}
++
++void mali_terminate_subsystems(void)
++{
++      struct mali_pmu_core *pmu = mali_pmu_get_global_pmu_core();
++
++      MALI_DEBUG_PRINT(2, ("terminate_subsystems() called\n"));
++
++      /* shut down subsystems in reverse order from startup */
++
++      /* We need the GPU to be powered up for the terminate sequence */
++      _mali_osk_pm_dev_ref_add();
++
++      mali_utilization_term();
++      mali_pp_scheduler_terminate();
++      mali_gp_scheduler_terminate();
++      mali_scheduler_terminate();
++      mali_delete_l2_cache_cores();
++      if (_MALI_PRODUCT_ID_MALI450 == global_product_id)
++      {
++              mali_dlbu_terminate();
++      }
++      mali_mmu_terminate();
++      if (NULL != pmu)
++      {
++              mali_pmu_delete(pmu);
++      }
++      mali_pm_terminate();
++      mali_memory_terminate();
++#if defined(CONFIG_MALI400_PROFILING)
++      _mali_osk_profiling_term();
++#endif
++
++      /* Allowing the system to be turned off */
++      _mali_osk_pm_dev_ref_dec();
++
++      mali_session_terminate();
++}
++
++_mali_product_id_t mali_kernel_core_get_product_id(void)
++{
++      return global_product_id;
++}
++
++_mali_osk_errcode_t _mali_ukk_get_api_version( _mali_uk_get_api_version_s *args )
++{
++      MALI_DEBUG_ASSERT_POINTER(args);
++      MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
++
++      /* check compatability */
++      if ( args->version == _MALI_UK_API_VERSION )
++      {
++              args->compatible = 1;
++      }
++      else
++      {
++              args->compatible = 0;
++      }
++
++      args->version = _MALI_UK_API_VERSION; /* report our version */
++
++      /* success regardless of being compatible or not */
++      MALI_SUCCESS;
++}
++
++_mali_osk_errcode_t _mali_ukk_wait_for_notification( _mali_uk_wait_for_notification_s *args )
++{
++      _mali_osk_errcode_t err;
++      _mali_osk_notification_t * notification;
++      _mali_osk_notification_queue_t *queue;
++
++      /* check input */
++      MALI_DEBUG_ASSERT_POINTER(args);
++      MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
++
++      queue = ((struct mali_session_data *)args->ctx)->ioctl_queue;
++
++      /* if the queue does not exist we're currently shutting down */
++      if (NULL == queue)
++      {
++              MALI_DEBUG_PRINT(1, ("No notification queue registered with the session. Asking userspace to stop querying\n"));
++              args->type = _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS;
++              MALI_SUCCESS;
++      }
++
++      /* receive a notification, might sleep */
++      err = _mali_osk_notification_queue_receive(queue, &notification);
++      if (_MALI_OSK_ERR_OK != err)
++      {
++              MALI_ERROR(err); /* errcode returned, pass on to caller */
++      }
++
++      /* copy the buffer to the user */
++      args->type = (_mali_uk_notification_type)notification->notification_type;
++      _mali_osk_memcpy(&args->data, notification->result_buffer, notification->result_buffer_size);
++
++      /* finished with the notification */
++      _mali_osk_notification_delete( notification );
++
++      MALI_SUCCESS; /* all ok */
++}
++
++_mali_osk_errcode_t _mali_ukk_post_notification( _mali_uk_post_notification_s *args )
++{
++      _mali_osk_notification_t * notification;
++      _mali_osk_notification_queue_t *queue;
++
++      /* check input */
++      MALI_DEBUG_ASSERT_POINTER(args);
++      MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
++
++      queue = ((struct mali_session_data *)args->ctx)->ioctl_queue;
++
++      /* if the queue does not exist we're currently shutting down */
++      if (NULL == queue)
++      {
++              MALI_DEBUG_PRINT(1, ("No notification queue registered with the session. Asking userspace to stop querying\n"));
++              MALI_SUCCESS;
++      }
++
++      notification = _mali_osk_notification_create(args->type, 0);
++      if (NULL == notification)
++      {
++              MALI_PRINT_ERROR( ("Failed to create notification object\n"));
++              return _MALI_OSK_ERR_NOMEM;
++      }
++
++      _mali_osk_notification_queue_send(queue, notification);
++
++      MALI_SUCCESS; /* all ok */
++}
++
++_mali_osk_errcode_t _mali_ukk_open(void **context)
++{
++      struct mali_session_data *session;
++
++      /* allocated struct to track this session */
++      session = (struct mali_session_data *)_mali_osk_calloc(1, sizeof(struct mali_session_data));
++      MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_NOMEM);
++
++      MALI_DEBUG_PRINT(3, ("Session starting\n"));
++
++      /* create a response queue for this session */
++      session->ioctl_queue = _mali_osk_notification_queue_init();
++      if (NULL == session->ioctl_queue)
++      {
++              _mali_osk_free(session);
++              MALI_ERROR(_MALI_OSK_ERR_NOMEM);
++      }
++
++      session->page_directory = mali_mmu_pagedir_alloc();
++      if (NULL == session->page_directory)
++      {
++              _mali_osk_notification_queue_term(session->ioctl_queue);
++              _mali_osk_free(session);
++              MALI_ERROR(_MALI_OSK_ERR_NOMEM);
++      }
++
++      if (_MALI_OSK_ERR_OK != mali_mmu_pagedir_map(session->page_directory, MALI_DLBU_VIRT_ADDR, _MALI_OSK_MALI_PAGE_SIZE))
++      {
++              MALI_PRINT_ERROR(("Failed to map DLBU page into session\n"));
++              _mali_osk_notification_queue_term(session->ioctl_queue);
++              _mali_osk_free(session);
++              MALI_ERROR(_MALI_OSK_ERR_NOMEM);
++      }
++
++      if (0 != mali_dlbu_phys_addr)
++      {
++              mali_mmu_pagedir_update(session->page_directory, MALI_DLBU_VIRT_ADDR, mali_dlbu_phys_addr,
++                                      _MALI_OSK_MALI_PAGE_SIZE, MALI_CACHE_STANDARD);
++      }
++
++      if (_MALI_OSK_ERR_OK != mali_memory_session_begin(session))
++      {
++              mali_mmu_pagedir_free(session->page_directory);
++              _mali_osk_notification_queue_term(session->ioctl_queue);
++              _mali_osk_free(session);
++              MALI_ERROR(_MALI_OSK_ERR_NOMEM);
++      }
++
++#ifdef CONFIG_SYNC
++/* MALI_SEC */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
++      _mali_osk_list_init(&session->pending_jobs);
++      session->pending_jobs_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK,
++                                                       0, _MALI_OSK_LOCK_ORDER_SESSION_PENDING_JOBS);
++      if (NULL == session->pending_jobs_lock)
++      {
++              MALI_PRINT_ERROR(("Failed to create pending jobs lock\n"));
++              mali_memory_session_end(session);
++              mali_mmu_pagedir_free(session->page_directory);
++              _mali_osk_notification_queue_term(session->ioctl_queue);
++              _mali_osk_free(session);
++              MALI_ERROR(_MALI_OSK_ERR_NOMEM);
++      }
++#endif
++#endif
++
++      *context = (void*)session;
++
++      /* Add session to the list of all sessions. */
++      mali_session_add(session);
++
++      /* Initialize list of jobs on this session */
++      _MALI_OSK_INIT_LIST_HEAD(&session->job_list);
++
++      MALI_DEBUG_PRINT(2, ("Session started\n"));
++      MALI_SUCCESS;
++}
++
++_mali_osk_errcode_t _mali_ukk_close(void **context)
++{
++      struct mali_session_data *session;
++      MALI_CHECK_NON_NULL(context, _MALI_OSK_ERR_INVALID_ARGS);
++      session = (struct mali_session_data *)*context;
++
++      MALI_DEBUG_PRINT(3, ("Session ending\n"));
++
++      /* Remove session from list of all sessions. */
++      mali_session_remove(session);
++
++      /* Abort pending jobs */
++#ifdef CONFIG_SYNC
++/* MALI_SEC */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
++      {
++              _mali_osk_list_t tmp_job_list;
++              struct mali_pp_job *job, *tmp;
++              _MALI_OSK_INIT_LIST_HEAD(&tmp_job_list);
++
++              _mali_osk_lock_wait(session->pending_jobs_lock, _MALI_OSK_LOCKMODE_RW);
++              /* Abort asynchronous wait on fence. */
++              _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &session->pending_jobs, struct mali_pp_job, list)
++              {
++                      MALI_DEBUG_PRINT(2, ("Sync: Aborting wait for session %x job %x\n", session, job));
++                      if (sync_fence_cancel_async(job->pre_fence, &job->sync_waiter))
++                      {
++                              MALI_DEBUG_PRINT(2, ("Sync: Failed to abort job %x\n", job));
++                      }
++                      _mali_osk_list_add(&job->list, &tmp_job_list);
++              }
++              _mali_osk_lock_signal(session->pending_jobs_lock, _MALI_OSK_LOCKMODE_RW);
++
++              _mali_osk_wq_flush();
++
++              _mali_osk_lock_term(session->pending_jobs_lock);
++
++              /* Delete jobs */
++              _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &tmp_job_list, struct mali_pp_job, list)
++              {
++                      mali_pp_job_delete(job);
++              }
++      }
++#endif
++#endif
++
++      /* Abort queued and running jobs */
++      mali_gp_scheduler_abort_session(session);
++      mali_pp_scheduler_abort_session(session);
++
++      /* Flush pending work.
++       * Needed to make sure all bottom half processing related to this
++       * session has been completed, before we free internal data structures.
++       */
++      _mali_osk_wq_flush();
++
++      /* Free remaining memory allocated to this session */
++      mali_memory_session_end(session);
++
++      /* Free session data structures */
++      mali_mmu_pagedir_free(session->page_directory);
++      _mali_osk_notification_queue_term(session->ioctl_queue);
++      _mali_osk_free(session);
++
++      *context = NULL;
++
++      MALI_DEBUG_PRINT(2, ("Session has ended\n"));
++
++      MALI_SUCCESS;
++}
++
++#if MALI_STATE_TRACKING
++u32 _mali_kernel_core_dump_state(char* buf, u32 size)
++{
++      int n = 0; /* Number of bytes written to buf */
++
++      n += mali_gp_scheduler_dump_state(buf + n, size - n);
++      n += mali_pp_scheduler_dump_state(buf + n, size - n);
++
++      return n;
++}
++#endif
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_kernel_core.h b/drivers/gpu/arm/mali400/mali/common/mali_kernel_core.h
+new file mode 100644
+index 0000000..83add03
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_kernel_core.h
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_KERNEL_CORE_H__
++#define __MALI_KERNEL_CORE_H__
++
++#include "mali_osk.h"
++/* MALI_SEC */
++extern int mali_hang_check_interval;
++extern int mali_max_job_runtime;
++
++typedef enum
++{
++      _MALI_PRODUCT_ID_UNKNOWN,
++      _MALI_PRODUCT_ID_MALI200,
++      _MALI_PRODUCT_ID_MALI300,
++      _MALI_PRODUCT_ID_MALI400,
++      _MALI_PRODUCT_ID_MALI450,
++} _mali_product_id_t;
++
++_mali_osk_errcode_t mali_initialize_subsystems(void);
++
++void mali_terminate_subsystems(void);
++
++_mali_product_id_t mali_kernel_core_get_product_id(void);
++
++u32 _mali_kernel_core_dump_state(char* buf, u32 size);
++
++#endif /* __MALI_KERNEL_CORE_H__ */
++
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_kernel_descriptor_mapping.c b/drivers/gpu/arm/mali400/mali/common/mali_kernel_descriptor_mapping.c
+new file mode 100644
+index 0000000..af6de5a
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_kernel_descriptor_mapping.c
+@@ -0,0 +1,184 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_kernel_common.h"
++#include "mali_kernel_descriptor_mapping.h"
++#include "mali_osk.h"
++#include "mali_osk_bitops.h"
++
++#define MALI_PAD_INT(x) (((x) + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1))
++
++/**
++ * Allocate a descriptor table capable of holding 'count' mappings
++ * @param count Number of mappings in the table
++ * @return Pointer to a new table, NULL on error
++ */
++static mali_descriptor_table * descriptor_table_alloc(int count);
++
++/**
++ * Free a descriptor table
++ * @param table The table to free
++ */
++static void descriptor_table_free(mali_descriptor_table * table);
++
++mali_descriptor_mapping * mali_descriptor_mapping_create(int init_entries, int max_entries)
++{
++      mali_descriptor_mapping * map = _mali_osk_calloc(1, sizeof(mali_descriptor_mapping));
++
++      init_entries = MALI_PAD_INT(init_entries);
++      max_entries = MALI_PAD_INT(max_entries);
++
++      if (NULL != map)
++      {
++              map->table = descriptor_table_alloc(init_entries);
++              if (NULL != map->table)
++              {
++            map->lock = _mali_osk_lock_init( (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, _MALI_OSK_LOCK_ORDER_DESCRIPTOR_MAP);
++            if (NULL != map->lock)
++            {
++                          _mali_osk_set_nonatomic_bit(0, map->table->usage); /* reserve bit 0 to prevent NULL/zero logic to kick in */
++                          map->max_nr_mappings_allowed = max_entries;
++                          map->current_nr_mappings = init_entries;
++                          return map;
++            }
++              descriptor_table_free(map->table);
++              }
++              _mali_osk_free(map);
++      }
++      return NULL;
++}
++
++void mali_descriptor_mapping_destroy(mali_descriptor_mapping * map)
++{
++      descriptor_table_free(map->table);
++    _mali_osk_lock_term(map->lock);
++      _mali_osk_free(map);
++}
++
++_mali_osk_errcode_t mali_descriptor_mapping_allocate_mapping(mali_descriptor_mapping * map, void * target, int *odescriptor)
++{
++      _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
++      int new_descriptor;
++
++    MALI_DEBUG_ASSERT_POINTER(map);
++    MALI_DEBUG_ASSERT_POINTER(odescriptor);
++
++    _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW);
++      new_descriptor = _mali_osk_find_first_zero_bit(map->table->usage, map->current_nr_mappings);
++      if (new_descriptor == map->current_nr_mappings)
++      {
++              /* no free descriptor, try to expand the table */
++              mali_descriptor_table * new_table, * old_table;
++              if (map->current_nr_mappings >= map->max_nr_mappings_allowed) goto unlock_and_exit;
++
++        map->current_nr_mappings += BITS_PER_LONG;
++              new_table = descriptor_table_alloc(map->current_nr_mappings);
++              if (NULL == new_table) goto unlock_and_exit;
++
++        old_table = map->table;
++              _mali_osk_memcpy(new_table->usage, old_table->usage, (sizeof(unsigned long)*map->current_nr_mappings) / BITS_PER_LONG);
++              _mali_osk_memcpy(new_table->mappings, old_table->mappings, map->current_nr_mappings * sizeof(void*));
++              map->table = new_table;
++              descriptor_table_free(old_table);
++      }
++
++      /* we have found a valid descriptor, set the value and usage bit */
++      _mali_osk_set_nonatomic_bit(new_descriptor, map->table->usage);
++      map->table->mappings[new_descriptor] = target;
++      *odescriptor = new_descriptor;
++    err = _MALI_OSK_ERR_OK;
++
++unlock_and_exit:
++    _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RW);
++    MALI_ERROR(err);
++}
++
++void mali_descriptor_mapping_call_for_each(mali_descriptor_mapping * map, void (*callback)(int, void*))
++{
++      int i;
++
++      MALI_DEBUG_ASSERT_POINTER(map);
++      MALI_DEBUG_ASSERT_POINTER(callback);
++
++    _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
++      /* id 0 is skipped as it's an reserved ID not mapping to anything */
++      for (i = 1; i < map->current_nr_mappings; ++i)
++      {
++              if (_mali_osk_test_bit(i, map->table->usage))
++              {
++                      callback(i, map->table->mappings[i]);
++              }
++      }
++    _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO);
++}
++
++_mali_osk_errcode_t mali_descriptor_mapping_get(mali_descriptor_mapping * map, int descriptor, void** target)
++{
++      _mali_osk_errcode_t result = _MALI_OSK_ERR_FAULT;
++      MALI_DEBUG_ASSERT_POINTER(map);
++    _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
++      if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
++      {
++              *target = map->table->mappings[descriptor];
++              result = _MALI_OSK_ERR_OK;
++      }
++      else *target = NULL;
++    _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO);
++      MALI_ERROR(result);
++}
++
++_mali_osk_errcode_t mali_descriptor_mapping_set(mali_descriptor_mapping * map, int descriptor, void * target)
++{
++      _mali_osk_errcode_t result = _MALI_OSK_ERR_FAULT;
++    _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
++      if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
++      {
++              map->table->mappings[descriptor] = target;
++              result = _MALI_OSK_ERR_OK;
++      }
++    _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO);
++      MALI_ERROR(result);
++}
++
++void *mali_descriptor_mapping_free(mali_descriptor_mapping * map, int descriptor)
++{
++      void *old_value = NULL;
++
++    _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW);
++      if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
++      {
++              old_value = map->table->mappings[descriptor];
++              map->table->mappings[descriptor] = NULL;
++              _mali_osk_clear_nonatomic_bit(descriptor, map->table->usage);
++      }
++    _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RW);
++
++      return old_value;
++}
++
++static mali_descriptor_table * descriptor_table_alloc(int count)
++{
++      mali_descriptor_table * table;
++
++      table = _mali_osk_calloc(1, sizeof(mali_descriptor_table) + ((sizeof(unsigned long) * count)/BITS_PER_LONG) + (sizeof(void*) * count));
++
++      if (NULL != table)
++      {
++              table->usage = (u32*)((u8*)table + sizeof(mali_descriptor_table));
++              table->mappings = (void**)((u8*)table + sizeof(mali_descriptor_table) + ((sizeof(unsigned long) * count)/BITS_PER_LONG));
++      }
++
++      return table;
++}
++
++static void descriptor_table_free(mali_descriptor_table * table)
++{
++      _mali_osk_free(table);
++}
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_kernel_descriptor_mapping.h b/drivers/gpu/arm/mali400/mali/common/mali_kernel_descriptor_mapping.h
+new file mode 100644
+index 0000000..2829173
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_kernel_descriptor_mapping.h
+@@ -0,0 +1,101 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_kernel_descriptor_mapping.h
++ */
++
++#ifndef __MALI_KERNEL_DESCRIPTOR_MAPPING_H__
++#define __MALI_KERNEL_DESCRIPTOR_MAPPING_H__
++
++#include "mali_osk.h"
++
++/**
++ * The actual descriptor mapping table, never directly accessed by clients
++ */
++typedef struct mali_descriptor_table
++{
++      u32 * usage; /**< Pointer to bitpattern indicating if a descriptor is valid/used or not */
++      void** mappings; /**< Array of the pointers the descriptors map to */
++} mali_descriptor_table;
++
++/**
++ * The descriptor mapping object
++ * Provides a separate namespace where we can map an integer to a pointer
++ */
++typedef struct mali_descriptor_mapping
++{
++    _mali_osk_lock_t *lock; /**< Lock protecting access to the mapping object */
++      int max_nr_mappings_allowed; /**< Max number of mappings to support in this namespace */
++      int current_nr_mappings; /**< Current number of possible mappings */
++      mali_descriptor_table * table; /**< Pointer to the current mapping table */
++} mali_descriptor_mapping;
++
++/**
++ * Create a descriptor mapping object
++ * Create a descriptor mapping capable of holding init_entries growable to max_entries
++ * @param init_entries Number of entries to preallocate memory for
++ * @param max_entries Number of entries to max support
++ * @return Pointer to a descriptor mapping object, NULL on failure
++ */
++mali_descriptor_mapping * mali_descriptor_mapping_create(int init_entries, int max_entries);
++
++/**
++ * Destroy a descriptor mapping object
++ * @param map The map to free
++ */
++void mali_descriptor_mapping_destroy(mali_descriptor_mapping * map);
++
++/**
++ * Allocate a new mapping entry (descriptor ID)
++ * Allocates a new entry in the map.
++ * @param map The map to allocate a new entry in
++ * @param target The value to map to
++ * @return The descriptor allocated, a negative value on error
++ */
++_mali_osk_errcode_t mali_descriptor_mapping_allocate_mapping(mali_descriptor_mapping * map, void * target, int *descriptor);
++
++/**
++ * Get the value mapped to by a descriptor ID
++ * @param map The map to lookup the descriptor id in
++ * @param descriptor The descriptor ID to lookup
++ * @param target Pointer to a pointer which will receive the stored value
++ * @return 0 on successful lookup, negative on error
++ */
++_mali_osk_errcode_t mali_descriptor_mapping_get(mali_descriptor_mapping * map, int descriptor, void** target);
++
++/**
++ * Set the value mapped to by a descriptor ID
++ * @param map The map to lookup the descriptor id in
++ * @param descriptor The descriptor ID to lookup
++ * @param target Pointer to replace the current value with
++ * @return 0 on successful lookup, negative on error
++ */
++_mali_osk_errcode_t mali_descriptor_mapping_set(mali_descriptor_mapping * map, int descriptor, void * target);
++
++/**
++ * Call the specified callback function for each descriptor in map.
++ * Entire function is mutex protected.
++ * @param map The map to do callbacks for
++ * @param callback A callback function which will be calle for each entry in map
++ */
++void mali_descriptor_mapping_call_for_each(mali_descriptor_mapping * map, void (*callback)(int, void*));
++
++/**
++ * Free the descriptor ID
++ * For the descriptor to be reused it has to be freed
++ * @param map The map to free the descriptor from
++ * @param descriptor The descriptor ID to free
++ *
++ * @return old value of descriptor mapping
++ */
++void *mali_descriptor_mapping_free(mali_descriptor_mapping * map, int descriptor);
++
++#endif /* __MALI_KERNEL_DESCRIPTOR_MAPPING_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_kernel_mem_os.c b/drivers/gpu/arm/mali400/mali/common/mali_kernel_mem_os.c
+new file mode 100644
+index 0000000..712970c
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_kernel_mem_os.c
+@@ -0,0 +1,353 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_kernel_common.h"
++#include "mali_kernel_memory_engine.h"
++#include "mali_osk.h"
++
++typedef struct os_allocation
++{
++      u32 num_pages;
++      u32 offset_start;
++      mali_allocation_engine * engine;
++      mali_memory_allocation * descriptor;
++} os_allocation;
++
++typedef struct os_allocator
++{
++      _mali_osk_lock_t *mutex;
++
++      /**
++       * Maximum number of pages to allocate from the OS
++       */
++      u32 num_pages_max;
++
++      /**
++       * Number of pages allocated from the OS
++       */
++      u32 num_pages_allocated;
++
++      /** CPU Usage adjustment (add to mali physical address to get cpu physical address) */
++      u32 cpu_usage_adjust;
++} os_allocator;
++
++static mali_physical_memory_allocation_result os_allocator_allocate(void* ctx, mali_allocation_engine * engine,  mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info);
++static mali_physical_memory_allocation_result os_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block);
++static void os_allocator_release(void * ctx, void * handle);
++static void os_allocator_page_table_block_release( mali_page_table_block *page_table_block );
++static void os_allocator_destroy(mali_physical_memory_allocator * allocator);
++static u32 os_allocator_stat(mali_physical_memory_allocator * allocator);
++
++mali_physical_memory_allocator * mali_os_allocator_create(u32 max_allocation, u32 cpu_usage_adjust, const char *name)
++{
++      mali_physical_memory_allocator * allocator;
++      os_allocator * info;
++
++      max_allocation = (max_allocation + _MALI_OSK_CPU_PAGE_SIZE-1) & ~(_MALI_OSK_CPU_PAGE_SIZE-1);
++
++      MALI_DEBUG_PRINT(2, ("Mali OS memory allocator created with max allocation size of 0x%X bytes, cpu_usage_adjust 0x%08X\n", max_allocation, cpu_usage_adjust));
++
++      allocator = _mali_osk_malloc(sizeof(mali_physical_memory_allocator));
++      if (NULL != allocator)
++      {
++              info = _mali_osk_malloc(sizeof(os_allocator));
++              if (NULL != info)
++              {
++                      info->num_pages_max = max_allocation / _MALI_OSK_CPU_PAGE_SIZE;
++                      info->num_pages_allocated = 0;
++                      info->cpu_usage_adjust = cpu_usage_adjust;
++
++                      info->mutex = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_ORDERED, 0, _MALI_OSK_LOCK_ORDER_MEM_INFO);
++            if (NULL != info->mutex)
++            {
++                          allocator->allocate = os_allocator_allocate;
++                          allocator->allocate_page_table_block = os_allocator_allocate_page_table_block;
++                          allocator->destroy = os_allocator_destroy;
++                              allocator->stat = os_allocator_stat;
++                          allocator->ctx = info;
++                              allocator->name = name;
++
++                          return allocator;
++            }
++            _mali_osk_free(info);
++              }
++              _mali_osk_free(allocator);
++      }
++
++      return NULL;
++}
++
++static u32 os_allocator_stat(mali_physical_memory_allocator * allocator)
++{
++      os_allocator * info;
++      info = (os_allocator*)allocator->ctx;
++      return info->num_pages_allocated * _MALI_OSK_MALI_PAGE_SIZE;
++}
++
++static void os_allocator_destroy(mali_physical_memory_allocator * allocator)
++{
++      os_allocator * info;
++        MALI_DEBUG_ASSERT_POINTER(allocator);
++      MALI_DEBUG_ASSERT_POINTER(allocator->ctx);
++      info = (os_allocator*)allocator->ctx;
++      _mali_osk_lock_term(info->mutex);
++      _mali_osk_free(info);
++      _mali_osk_free(allocator);
++}
++
++static mali_physical_memory_allocation_result os_allocator_allocate(void* ctx, mali_allocation_engine * engine,  mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info)
++{
++      mali_physical_memory_allocation_result result = MALI_MEM_ALLOC_NONE;
++      u32 left;
++      os_allocator * info;
++      os_allocation * allocation;
++      int pages_allocated = 0;
++      _mali_osk_errcode_t err = _MALI_OSK_ERR_OK;
++
++      MALI_DEBUG_ASSERT_POINTER(ctx);
++      MALI_DEBUG_ASSERT_POINTER(engine);
++      MALI_DEBUG_ASSERT_POINTER(descriptor);
++      MALI_DEBUG_ASSERT_POINTER(offset);
++      MALI_DEBUG_ASSERT_POINTER(alloc_info);
++
++      info = (os_allocator*)ctx;
++      left = descriptor->size - *offset;
++
++      if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) return MALI_MEM_ALLOC_INTERNAL_FAILURE;
++
++      /** @note this code may not work on Linux, or may require a more complex Linux implementation */
++      allocation = _mali_osk_malloc(sizeof(os_allocation));
++      if (NULL != allocation)
++      {
++              u32 os_mem_max_usage = info->num_pages_max * _MALI_OSK_CPU_PAGE_SIZE;
++              allocation->offset_start = *offset;
++              allocation->num_pages = ((left + _MALI_OSK_CPU_PAGE_SIZE - 1) & ~(_MALI_OSK_CPU_PAGE_SIZE - 1)) >> _MALI_OSK_CPU_PAGE_ORDER;
++              MALI_DEBUG_PRINT(6, ("Allocating page array of size %d bytes\n", allocation->num_pages * sizeof(struct page*)));
++/* MALI_SEC */
++/*
++while (left > 0 && ((info->num_pages_allocated + pages_allocated) < info->num_pages_max) && _mali_osk_mem_check_allocated(os_mem_max_usage))
++*/
++              while (left > 0)
++              {
++                      err = mali_allocation_engine_map_physical(engine, descriptor, *offset, MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC, info->cpu_usage_adjust, _MALI_OSK_CPU_PAGE_SIZE);
++                      if ( _MALI_OSK_ERR_OK != err)
++                      {
++                              if (  _MALI_OSK_ERR_NOMEM == err)
++                              {
++                                      /* 'Partial' allocation (or, out-of-memory on first page) */
++                                      break;
++                              }
++
++                              MALI_DEBUG_PRINT(1, ("Mapping of physical memory failed\n"));
++
++                              /* Fatal error, cleanup any previous pages allocated. */
++                              if ( pages_allocated > 0 )
++                              {
++                                      mali_allocation_engine_unmap_physical( engine, descriptor, allocation->offset_start, _MALI_OSK_CPU_PAGE_SIZE*pages_allocated, _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR );
++                                      /* (*offset) doesn't need to be restored; it will not be used by the caller on failure */
++                              }
++
++                              pages_allocated = 0;
++
++                              result = MALI_MEM_ALLOC_INTERNAL_FAILURE;
++                              break;
++                      }
++
++                      /* Loop iteration */
++                      if (left < _MALI_OSK_CPU_PAGE_SIZE) left = 0;
++                      else left -= _MALI_OSK_CPU_PAGE_SIZE;
++
++                      pages_allocated++;
++
++                      *offset += _MALI_OSK_CPU_PAGE_SIZE;
++              }
++
++              if (left) MALI_PRINT(("Out of memory. Mali memory allocated: %d kB  Configured maximum OS memory usage: %d kB\n",
++                               (info->num_pages_allocated * _MALI_OSK_CPU_PAGE_SIZE)/1024, (info->num_pages_max* _MALI_OSK_CPU_PAGE_SIZE)/1024));
++
++              /* Loop termination; decide on result */
++              if (pages_allocated)
++              {
++                      MALI_DEBUG_PRINT(6, ("Allocated %d pages\n", pages_allocated));
++                      if (left) result = MALI_MEM_ALLOC_PARTIAL;
++                      else result = MALI_MEM_ALLOC_FINISHED;
++
++            /* Some OS do not perform a full cache flush (including all outer caches) for uncached mapped memory.
++             * They zero the memory through a cached mapping, then flush the inner caches but not the outer caches.
++             * This is required for MALI to have the correct view of the memory.
++             */
++            _mali_osk_cache_ensure_uncached_range_flushed( (void *)descriptor, allocation->offset_start, pages_allocated *_MALI_OSK_CPU_PAGE_SIZE );
++                      allocation->num_pages = pages_allocated;
++                      allocation->engine = engine;         /* Necessary to make the engine's unmap call */
++                      allocation->descriptor = descriptor; /* Necessary to make the engine's unmap call */
++                      info->num_pages_allocated += pages_allocated;
++
++                      MALI_DEBUG_PRINT(6, ("%d out of %d pages now allocated\n", info->num_pages_allocated, info->num_pages_max));
++
++                      alloc_info->ctx = info;
++                      alloc_info->handle = allocation;
++                      alloc_info->release = os_allocator_release;
++              }
++              else
++              {
++                      MALI_DEBUG_PRINT(6, ("Releasing pages array due to no pages allocated\n"));
++                      _mali_osk_free( allocation );
++              }
++      }
++
++      _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
++
++      return result;
++}
++
++static void os_allocator_release(void * ctx, void * handle)
++{
++      os_allocator * info;
++      os_allocation * allocation;
++      mali_allocation_engine * engine;
++      mali_memory_allocation * descriptor;
++
++      MALI_DEBUG_ASSERT_POINTER(ctx);
++      MALI_DEBUG_ASSERT_POINTER(handle);
++
++      info = (os_allocator*)ctx;
++      allocation = (os_allocation*)handle;
++      engine = allocation->engine;
++      descriptor = allocation->descriptor;
++
++      MALI_DEBUG_ASSERT_POINTER( engine );
++      MALI_DEBUG_ASSERT_POINTER( descriptor );
++
++      if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW))
++      {
++              MALI_DEBUG_PRINT(1, ("allocator release: Failed to get mutex\n"));
++              return;
++      }
++
++      MALI_DEBUG_PRINT(6, ("Releasing %d os pages\n", allocation->num_pages));
++
++      MALI_DEBUG_ASSERT( allocation->num_pages <= info->num_pages_allocated);
++      info->num_pages_allocated -= allocation->num_pages;
++
++      mali_allocation_engine_unmap_physical( engine, descriptor, allocation->offset_start, _MALI_OSK_CPU_PAGE_SIZE*allocation->num_pages, _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR );
++
++      _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
++
++      _mali_osk_free(allocation);
++}
++
++static mali_physical_memory_allocation_result os_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block)
++{
++/* MALI_SEC  6->10 */
++#ifndef CONFIG_FORCE_MAX_ZONEORDER
++      int allocation_order = 10;
++#else
++      int allocation_order = CONFIG_FORCE_MAX_ZONEORDER - 1;
++#endif
++      void *virt = NULL;
++      u32 size = _MALI_OSK_CPU_PAGE_SIZE << allocation_order;
++      os_allocator * info;
++
++      u32 cpu_phys_base;
++
++      MALI_DEBUG_ASSERT_POINTER(ctx);
++      info = (os_allocator*)ctx;
++
++      /* Ensure we don't allocate more than we're supposed to from the ctx */
++      if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) return MALI_MEM_ALLOC_INTERNAL_FAILURE;
++
++      /* if the number of pages to be requested lead to exceeding the memory
++       * limit in info->num_pages_max, reduce the size that is to be requested. */
++      while ( (info->num_pages_allocated + (1 << allocation_order) > info->num_pages_max)
++              && _mali_osk_mem_check_allocated(info->num_pages_max * _MALI_OSK_CPU_PAGE_SIZE) )
++      {
++              if ( allocation_order > 0 ) {
++                      --allocation_order;
++              } else {
++                      /* return OOM */
++                      _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
++                      return MALI_MEM_ALLOC_NONE;
++              }
++      }
++
++      /* try to allocate 2^(allocation_order) pages, if that fails, try
++       * allocation_order-1 to allocation_order 0 (inclusive) */
++      while ( allocation_order >= 0 )
++      {
++              size = _MALI_OSK_CPU_PAGE_SIZE << allocation_order;
++              virt = _mali_osk_mem_allocioregion( &cpu_phys_base, size );
++
++              if (NULL != virt) break;
++
++              --allocation_order;
++      }
++
++      if ( NULL == virt )
++      {
++              MALI_DEBUG_PRINT(1, ("Failed to allocate consistent memory. Is CONSISTENT_DMA_SIZE set too low?\n"));
++              /* return OOM */
++              _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
++              return MALI_MEM_ALLOC_NONE;
++      }
++
++      MALI_DEBUG_PRINT(5, ("os_allocator_allocate_page_table_block: Allocation of order %i succeeded\n",
++                              allocation_order));
++
++      /* we now know the size of the allocation since we know for what
++       * allocation_order the allocation succeeded */
++      size = _MALI_OSK_CPU_PAGE_SIZE << allocation_order;
++
++
++      block->release = os_allocator_page_table_block_release;
++      block->ctx = ctx;
++      block->handle = (void*)allocation_order;
++      block->size = size;
++      block->phys_base = cpu_phys_base - info->cpu_usage_adjust;
++      block->mapping = virt;
++
++      info->num_pages_allocated += (1 << allocation_order);
++
++      _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
++
++      return MALI_MEM_ALLOC_FINISHED;
++}
++
++static void os_allocator_page_table_block_release( mali_page_table_block *page_table_block )
++{
++      os_allocator * info;
++      u32 allocation_order;
++      u32 pages_allocated;
++
++      MALI_DEBUG_ASSERT_POINTER( page_table_block );
++
++      info = (os_allocator*)page_table_block->ctx;
++
++      MALI_DEBUG_ASSERT_POINTER( info );
++
++      allocation_order = (u32)page_table_block->handle;
++
++      pages_allocated = 1 << allocation_order;
++
++      MALI_DEBUG_ASSERT( pages_allocated * _MALI_OSK_CPU_PAGE_SIZE == page_table_block->size );
++
++      if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW))
++      {
++              MALI_DEBUG_PRINT(1, ("allocator release: Failed to get mutex\n"));
++              return;
++      }
++
++      MALI_DEBUG_ASSERT( pages_allocated <= info->num_pages_allocated);
++      info->num_pages_allocated -= pages_allocated;
++
++      /* Adjust phys_base from mali physical address to CPU physical address */
++      _mali_osk_mem_freeioregion( page_table_block->phys_base + info->cpu_usage_adjust, page_table_block->size, page_table_block->mapping );
++
++      _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
++}
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_kernel_mem_os.h b/drivers/gpu/arm/mali400/mali/common/mali_kernel_mem_os.h
+new file mode 100644
+index 0000000..66c0a58
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_kernel_mem_os.h
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_KERNEL_MEM_OS_H__
++#define __MALI_KERNEL_MEM_OS_H__
++
++/**
++ * @brief Creates an object that manages allocating OS memory
++ *
++ * Creates an object that provides an interface to allocate OS memory and
++ * have it mapped into the Mali virtual memory space.
++ *
++ * The object exposes pointers to
++ * - allocate OS memory
++ * - allocate Mali page tables in OS memory
++ * - destroy the object
++ *
++ * Allocations from OS memory are of type mali_physical_memory_allocation
++ * which provides a function to release the allocation.
++ *
++ * @param max_allocation max. number of bytes that can be allocated from OS memory
++ * @param cpu_usage_adjust value to add to mali physical addresses to obtain CPU physical addresses
++ * @param name description of the allocator
++ * @return pointer to mali_physical_memory_allocator object. NULL on failure.
++ **/
++mali_physical_memory_allocator * mali_os_allocator_create(u32 max_allocation, u32 cpu_usage_adjust, const char *name);
++
++#endif /* __MALI_KERNEL_MEM_OS_H__ */
++
++
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_kernel_memory_engine.c b/drivers/gpu/arm/mali400/mali/common/mali_kernel_memory_engine.c
+new file mode 100644
+index 0000000..f0a0c97
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_kernel_memory_engine.c
+@@ -0,0 +1,375 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_kernel_common.h"
++#include "mali_kernel_memory_engine.h"
++#include "mali_osk.h"
++#include "mali_osk_list.h"
++
++typedef struct memory_engine
++{
++      mali_kernel_mem_address_manager * mali_address;
++      mali_kernel_mem_address_manager * process_address;
++} memory_engine;
++
++mali_allocation_engine mali_allocation_engine_create(mali_kernel_mem_address_manager * mali_address_manager, mali_kernel_mem_address_manager * process_address_manager)
++{
++      memory_engine * engine;
++
++      /* Mali Address Manager need not support unmap_physical */
++      MALI_DEBUG_ASSERT_POINTER(mali_address_manager);
++      MALI_DEBUG_ASSERT_POINTER(mali_address_manager->allocate);
++      MALI_DEBUG_ASSERT_POINTER(mali_address_manager->release);
++      MALI_DEBUG_ASSERT_POINTER(mali_address_manager->map_physical);
++
++      /* Process Address Manager must support unmap_physical for OS allocation
++       * error path handling */
++      MALI_DEBUG_ASSERT_POINTER(process_address_manager);
++      MALI_DEBUG_ASSERT_POINTER(process_address_manager->allocate);
++      MALI_DEBUG_ASSERT_POINTER(process_address_manager->release);
++      MALI_DEBUG_ASSERT_POINTER(process_address_manager->map_physical);
++      MALI_DEBUG_ASSERT_POINTER(process_address_manager->unmap_physical);
++
++
++      engine = (memory_engine*)_mali_osk_malloc(sizeof(memory_engine));
++      if (NULL == engine) return NULL;
++
++      engine->mali_address = mali_address_manager;
++      engine->process_address = process_address_manager;
++
++      return (mali_allocation_engine)engine;
++}
++
++void mali_allocation_engine_destroy(mali_allocation_engine engine)
++{
++      MALI_DEBUG_ASSERT_POINTER(engine);
++      _mali_osk_free(engine);
++}
++
++_mali_osk_errcode_t mali_allocation_engine_allocate_memory(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor, mali_physical_memory_allocator * physical_allocators, _mali_osk_list_t *tracking_list )
++{
++      memory_engine * engine = (memory_engine*)mem_engine;
++
++      MALI_DEBUG_ASSERT_POINTER(engine);
++      MALI_DEBUG_ASSERT_POINTER(descriptor);
++      MALI_DEBUG_ASSERT_POINTER(physical_allocators);
++      /* ASSERT that the list member has been initialized, even if it won't be
++       * used for tracking. We need it to be initialized to see if we need to
++       * delete it from a list in the release function. */
++      MALI_DEBUG_ASSERT( NULL != descriptor->list.next && NULL != descriptor->list.prev );
++
++      if (_MALI_OSK_ERR_OK == engine->mali_address->allocate(descriptor))
++      {
++              _mali_osk_errcode_t res = _MALI_OSK_ERR_OK;
++              if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE )
++              {
++                      res = engine->process_address->allocate(descriptor);
++              }
++              if ( _MALI_OSK_ERR_OK == res )
++              {
++                      /* address space setup OK, commit physical memory to the allocation */
++                      mali_physical_memory_allocator * active_allocator = physical_allocators;
++                      struct mali_physical_memory_allocation * active_allocation_tracker = &descriptor->physical_allocation;
++                      u32 offset = 0;
++
++                      while ( NULL != active_allocator )
++                      {
++                              switch (active_allocator->allocate(active_allocator->ctx, mem_engine, descriptor, &offset, active_allocation_tracker))
++                              {
++                                      case MALI_MEM_ALLOC_FINISHED:
++                                              if ( NULL != tracking_list )
++                                              {
++                                                      /* Insert into the memory session list */
++                                                      /* ASSERT that it is not already part of a list */
++                                                      MALI_DEBUG_ASSERT( _mali_osk_list_empty( &descriptor->list ) );
++                                                      _mali_osk_list_add( &descriptor->list, tracking_list );
++                                              }
++
++                                              MALI_SUCCESS; /* all done */
++                                      case MALI_MEM_ALLOC_NONE:
++                                              /* reuse current active_allocation_tracker */
++                                              MALI_DEBUG_PRINT( 4, ("Memory Engine Allocate: No allocation on %s, resorting to %s\n",
++                                                                                        ( active_allocator->name ) ? active_allocator->name : "UNNAMED",
++                                                                                        ( active_allocator->next ) ? (( active_allocator->next->name )? active_allocator->next->name : "UNNAMED") : "NONE") );
++                                              active_allocator = active_allocator->next;
++                                              break;
++                                      case MALI_MEM_ALLOC_PARTIAL:
++                                              if (NULL != active_allocator->next)
++                                              {
++                                                      /* need a new allocation tracker */
++                                                      active_allocation_tracker->next = _mali_osk_calloc(1, sizeof(mali_physical_memory_allocation));
++                                                      if (NULL != active_allocation_tracker->next)
++                                                      {
++                                                              active_allocation_tracker = active_allocation_tracker->next;
++                                                              MALI_DEBUG_PRINT( 2, ("Memory Engine Allocate: Partial allocation on %s, resorting to %s\n",
++                                                                                                        ( active_allocator->name ) ? active_allocator->name : "UNNAMED",
++                                                                                                        ( active_allocator->next ) ? (( active_allocator->next->name )? active_allocator->next->name : "UNNAMED") : "NONE") );
++                                                              active_allocator = active_allocator->next;
++                                                              break;
++                                                      }
++                                              }
++                                         /* FALL THROUGH */
++                                      case MALI_MEM_ALLOC_INTERNAL_FAILURE:
++                                         active_allocator = NULL; /* end the while loop */
++                                         break;
++                              }
++                      }
++
++                      MALI_PRINT(("Memory allocate failed, could not allocate size %d kB.\n", descriptor->size/1024));
++
++                      /* allocation failure, start cleanup */
++                      /* loop over any potential partial allocations */
++                      active_allocation_tracker = &descriptor->physical_allocation;
++                      while (NULL != active_allocation_tracker)
++                      {
++                              /* handle blank trackers which will show up during failure */
++                              if (NULL != active_allocation_tracker->release)
++                              {
++                                      active_allocation_tracker->release(active_allocation_tracker->ctx, active_allocation_tracker->handle);
++                              }
++                              active_allocation_tracker = active_allocation_tracker->next;
++                      }
++
++                      /* free the allocation tracker objects themselves, skipping the tracker stored inside the descriptor itself */
++                      for ( active_allocation_tracker = descriptor->physical_allocation.next; active_allocation_tracker != NULL; )
++                      {
++                              void * buf = active_allocation_tracker;
++                              active_allocation_tracker = active_allocation_tracker->next;
++                              _mali_osk_free(buf);
++                      }
++
++                      /* release the address spaces */
++
++                      if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE )
++                      {
++                              engine->process_address->release(descriptor);
++                      }
++              }
++              engine->mali_address->release(descriptor);
++      }
++
++      MALI_ERROR(_MALI_OSK_ERR_FAULT);
++}
++
++void mali_allocation_engine_release_memory(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor)
++{
++      mali_allocation_engine_release_pt1_mali_pagetables_unmap(mem_engine, descriptor);
++      mali_allocation_engine_release_pt2_physical_memory_free(mem_engine, descriptor);
++}
++
++void mali_allocation_engine_release_pt1_mali_pagetables_unmap(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor)
++{
++      memory_engine * engine = (memory_engine*)mem_engine;
++
++      MALI_DEBUG_ASSERT_POINTER(engine);
++      MALI_DEBUG_ASSERT_POINTER(descriptor);
++
++      /* Calling: mali_address_manager_release()  */
++      /* This function is allowed to be called several times, and it only does the release on the first call. */
++      engine->mali_address->release(descriptor);
++}
++
++void mali_allocation_engine_release_pt2_physical_memory_free(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor)
++{
++      memory_engine * engine = (memory_engine*)mem_engine;
++      mali_physical_memory_allocation * active_allocation_tracker;
++
++      /* Remove this from a tracking list in session_data->memory_head */
++      if ( ! _mali_osk_list_empty( &descriptor->list ) )
++      {
++              _mali_osk_list_del( &descriptor->list );
++              /* Clear the list for debug mode, catch use-after-free */
++              MALI_DEBUG_CODE( descriptor->list.next = descriptor->list.prev = NULL; )
++      }
++
++      active_allocation_tracker = &descriptor->physical_allocation;
++      while (NULL != active_allocation_tracker)
++      {
++              MALI_DEBUG_ASSERT_POINTER(active_allocation_tracker->release);
++              active_allocation_tracker->release(active_allocation_tracker->ctx, active_allocation_tracker->handle);
++              active_allocation_tracker = active_allocation_tracker->next;
++      }
++
++      /* free the allocation tracker objects themselves, skipping the tracker stored inside the descriptor itself */
++      for ( active_allocation_tracker = descriptor->physical_allocation.next; active_allocation_tracker != NULL; )
++      {
++              void * buf = active_allocation_tracker;
++              active_allocation_tracker = active_allocation_tracker->next;
++              _mali_osk_free(buf);
++      }
++
++      if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE )
++      {
++              engine->process_address->release(descriptor);
++      }
++}
++
++_mali_osk_errcode_t mali_allocation_engine_map_physical(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor, u32 offset, u32 phys, u32 cpu_usage_adjust, u32 size)
++{
++      _mali_osk_errcode_t err;
++      memory_engine * engine = (memory_engine*)mem_engine;
++      _mali_osk_mem_mapregion_flags_t unmap_flags = (_mali_osk_mem_mapregion_flags_t)0;
++
++      MALI_DEBUG_ASSERT_POINTER(engine);
++      MALI_DEBUG_ASSERT_POINTER(descriptor);
++
++      MALI_DEBUG_PRINT(7, ("Mapping phys 0x%08X length 0x%08X at offset 0x%08X\n", phys, size, offset));
++
++      MALI_DEBUG_ASSERT_POINTER(engine->mali_address);
++      MALI_DEBUG_ASSERT_POINTER(engine->mali_address->map_physical);
++
++      /* Handle process address manager first, because we may need them to
++       * allocate the physical page */
++      if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE )
++      {
++              /* Handle OS-allocated specially, since an adjustment may be required */
++              if ( MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC == phys )
++              {
++                      MALI_DEBUG_ASSERT( _MALI_OSK_CPU_PAGE_SIZE == size );
++
++                      /* Set flags to use on error path */
++                      unmap_flags |= _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR;
++
++                      err = engine->process_address->map_physical(descriptor, offset, &phys, size);
++                      /* Adjust for cpu physical address to mali physical address */
++                      phys -= cpu_usage_adjust;
++              }
++              else
++              {
++                      u32 cpu_phys;
++                      /* Adjust mali physical address to cpu physical address */
++                      cpu_phys = phys + cpu_usage_adjust;
++                      err = engine->process_address->map_physical(descriptor, offset, &cpu_phys, size);
++              }
++
++              if ( _MALI_OSK_ERR_OK != err )
++              {
++                      MALI_DEBUG_PRINT(2, ("Map failed: %s %d\n", __FUNCTION__, __LINE__));
++                      MALI_ERROR( err );
++              }
++      }
++
++      MALI_DEBUG_PRINT(7, ("Mapping phys 0x%08X length 0x%08X at offset 0x%08X to CPUVA 0x%08X\n", phys, size, offset, (u32)(descriptor->mapping) + offset));
++
++      /* Mali address manager must use the physical address - no point in asking
++       * it to allocate another one for us */
++      MALI_DEBUG_ASSERT( MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC != phys );
++
++      err = engine->mali_address->map_physical(descriptor, offset, &phys, size);
++
++      if ( _MALI_OSK_ERR_OK != err )
++      {
++              if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE )
++              {
++                      MALI_DEBUG_PRINT( 2, ("Process address manager succeeded, but Mali Address manager failed for phys=0x%08X size=0x%08X, offset=0x%08X. Will unmap.\n", phys, size, offset));
++                      engine->process_address->unmap_physical(descriptor, offset, size, unmap_flags);
++              }
++              MALI_DEBUG_PRINT(2, ("Map mali failed: %s %d\n", __FUNCTION__, __LINE__));
++              MALI_ERROR( err );
++      }
++
++      MALI_SUCCESS;
++}
++
++void mali_allocation_engine_unmap_physical(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t unmap_flags )
++{
++      memory_engine * engine = (memory_engine*)mem_engine;
++
++      MALI_DEBUG_ASSERT_POINTER(engine);
++      MALI_DEBUG_ASSERT_POINTER(descriptor);
++
++      MALI_DEBUG_PRINT(7, ("UnMapping length 0x%08X at offset 0x%08X\n", size, offset));
++
++      MALI_DEBUG_ASSERT_POINTER(engine->mali_address);
++      MALI_DEBUG_ASSERT_POINTER(engine->process_address);
++
++      if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE )
++      {
++              /* Mandetory for process_address manager to have an unmap function*/
++              engine->process_address->unmap_physical( descriptor, offset, size, unmap_flags );
++      }
++
++      /* Optional for mali_address manager to have an unmap function*/
++      if ( NULL != engine->mali_address->unmap_physical )
++      {
++              engine->mali_address->unmap_physical( descriptor, offset, size, unmap_flags );
++      }
++}
++
++
++_mali_osk_errcode_t mali_allocation_engine_allocate_page_tables(mali_allocation_engine engine, mali_page_table_block * descriptor, mali_physical_memory_allocator * physical_provider)
++{
++      mali_physical_memory_allocator * active_allocator = physical_provider;
++
++      MALI_DEBUG_ASSERT_POINTER(descriptor);
++      MALI_DEBUG_ASSERT_POINTER(physical_provider);
++
++      while ( NULL != active_allocator )
++      {
++              switch (active_allocator->allocate_page_table_block(active_allocator->ctx, descriptor))
++              {
++                      case MALI_MEM_ALLOC_FINISHED:
++                              MALI_SUCCESS; /* all done */
++                      case MALI_MEM_ALLOC_NONE:
++                              /* try next */
++                              MALI_DEBUG_PRINT( 2, ("Memory Engine Allocate PageTables: No allocation on %s, resorting to %s\n",
++                                                                        ( active_allocator->name ) ? active_allocator->name : "UNNAMED",
++                                                                        ( active_allocator->next ) ? (( active_allocator->next->name )? active_allocator->next->name : "UNNAMED") : "NONE") );
++                              active_allocator = active_allocator->next;
++                              break;
++                      case MALI_MEM_ALLOC_PARTIAL:
++                              MALI_DEBUG_PRINT(1, ("Invalid return value from allocate_page_table_block call: MALI_MEM_ALLOC_PARTIAL\n"));
++                              /* FALL THROUGH */
++                      case MALI_MEM_ALLOC_INTERNAL_FAILURE:
++                              MALI_DEBUG_PRINT(1, ("Aborting due to allocation failure\n"));
++                              active_allocator = NULL; /* end the while loop */
++                              break;
++              }
++      }
++
++      MALI_ERROR(_MALI_OSK_ERR_FAULT);
++}
++
++
++void mali_allocation_engine_report_allocators( mali_physical_memory_allocator * physical_provider )
++{
++      mali_physical_memory_allocator * active_allocator = physical_provider;
++      MALI_DEBUG_ASSERT_POINTER(physical_provider);
++
++      MALI_DEBUG_PRINT( 1, ("Mali memory allocators will be used in this order of preference (lowest numbered first) :\n"));
++      while ( NULL != active_allocator )
++      {
++              if ( NULL != active_allocator->name )
++              {
++                      MALI_DEBUG_PRINT( 1, ("\t%d: %s\n", active_allocator->alloc_order, active_allocator->name) );
++              }
++              else
++              {
++                      MALI_DEBUG_PRINT( 1, ("\t%d: (UNNAMED ALLOCATOR)\n", active_allocator->alloc_order) );
++              }
++              active_allocator = active_allocator->next;
++      }
++
++}
++
++u32 mali_allocation_engine_memory_usage(mali_physical_memory_allocator *allocator)
++{
++      u32 sum = 0;
++      while(NULL != allocator)
++      {
++              /* Only count allocators that have set up a stat function. */
++              if(allocator->stat)
++                      sum += allocator->stat(allocator);
++
++              allocator = allocator->next;
++      }
++
++      return sum;
++}
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_kernel_memory_engine.h b/drivers/gpu/arm/mali400/mali/common/mali_kernel_memory_engine.h
+new file mode 100644
+index 0000000..cf3dfac
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_kernel_memory_engine.h
+@@ -0,0 +1,152 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_KERNEL_MEMORY_ENGINE_H__
++#define  __MALI_KERNEL_MEMORY_ENGINE_H__
++
++typedef void * mali_allocation_engine;
++
++typedef enum { MALI_MEM_ALLOC_FINISHED, MALI_MEM_ALLOC_PARTIAL, MALI_MEM_ALLOC_NONE, MALI_MEM_ALLOC_INTERNAL_FAILURE } mali_physical_memory_allocation_result;
++
++typedef struct mali_physical_memory_allocation
++{
++      void (*release)(void * ctx, void * handle); /**< Function to call on to release the physical memory */
++      void * ctx;
++      void * handle;
++      struct mali_physical_memory_allocation * next;
++} mali_physical_memory_allocation;
++
++struct mali_page_table_block;
++
++typedef struct mali_page_table_block
++{
++      void (*release)(struct mali_page_table_block *page_table_block);
++      void * ctx;
++      void * handle;
++      u32 size; /**< In bytes, should be a multiple of MALI_MMU_PAGE_SIZE to avoid internal fragementation */
++      u32 phys_base; /**< Mali physical address */
++      mali_io_address mapping;
++} mali_page_table_block;
++
++
++/** @addtogroup _mali_osk_low_level_memory
++ * @{ */
++
++typedef enum
++{
++      MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE = 0x1,
++      MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE     = 0x2,
++} mali_memory_allocation_flag;
++
++/**
++ * Supplying this 'magic' physical address requests that the OS allocate the
++ * physical address at page commit time, rather than committing a specific page
++ */
++#define MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC ((u32)(-1))
++
++typedef struct mali_memory_allocation
++{
++      /* Information about the allocation */
++      void * mapping; /**< CPU virtual address where the memory is mapped at */
++      u32 mali_address; /**< The Mali seen address of the memory allocation */
++      u32 size; /**< Size of the allocation */
++      u32 permission; /**< Permission settings */
++      mali_memory_allocation_flag flags;
++      u32 cache_settings; /* type: mali_memory_cache_settings, found in <linux/mali/mali_utgard_uk_types.h> Ump DD breaks if we include it...*/
++
++      _mali_osk_lock_t * lock;
++
++      /* Manager specific information pointers */
++      void * mali_addr_mapping_info; /**< Mali address allocation specific info */
++      void * process_addr_mapping_info; /**< Mapping manager specific info */
++
++      mali_physical_memory_allocation physical_allocation;
++
++      _mali_osk_list_t list; /**< List for linking together memory allocations into the session's memory head */
++} mali_memory_allocation;
++/** @} */ /* end group _mali_osk_low_level_memory */
++
++
++typedef struct mali_physical_memory_allocator
++{
++      mali_physical_memory_allocation_result (*allocate)(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info);
++      mali_physical_memory_allocation_result (*allocate_page_table_block)(void * ctx, mali_page_table_block * block); /* MALI_MEM_ALLOC_PARTIAL not allowed */
++      void (*destroy)(struct mali_physical_memory_allocator * allocator);
++      u32 (*stat)(struct mali_physical_memory_allocator * allocator);
++      void * ctx;
++      const char * name; /**< Descriptive name for use in mali_allocation_engine_report_allocators, or NULL */
++      u32 alloc_order; /**< Order in which the allocations should happen */
++      struct mali_physical_memory_allocator * next;
++} mali_physical_memory_allocator;
++
++typedef struct mali_kernel_mem_address_manager
++{
++      _mali_osk_errcode_t (*allocate)(mali_memory_allocation *); /**< Function to call to reserve an address */
++      void (*release)(mali_memory_allocation *); /**< Function to call to free the address allocated */
++
++       /**
++        * Function called for each physical sub allocation.
++        * Called for each physical block allocated by the physical memory manager.
++        * @param[in] descriptor The memory descriptor in question
++        * @param[in] off Offset from the start of range
++        * @param[in,out] phys_addr A pointer to the physical address of the start of the
++        * physical block. When *phys_addr == MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC
++        * is used, this requests the function to allocate the physical page
++        * itself, and return it through the pointer provided.
++        * @param[in] size Length in bytes of the physical block
++        * @return _MALI_OSK_ERR_OK on success.
++        * A value of type _mali_osk_errcode_t other than _MALI_OSK_ERR_OK indicates failure.
++        * Specifically, _MALI_OSK_ERR_UNSUPPORTED indicates that the function
++        * does not support allocating physical pages itself.
++        */
++       _mali_osk_errcode_t (*map_physical)(mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size);
++
++       /**
++        * Function called to remove a physical sub allocation.
++        * Called on error paths where one of the address managers fails.
++        *
++        * @note this is optional. For address managers where this is not
++        * implemented, the value of this member is NULL. The memory engine
++        * currently does not require the mali address manager to be able to
++        * unmap individual pages, but the process address manager must have this
++        * capability.
++        *
++        * @param[in] descriptor The memory descriptor in question
++        * @param[in] off Offset from the start of range
++        * @param[in] size Length in bytes of the physical block
++        * @param[in] flags flags to use on a per-page basis. For OS-allocated
++        * physical pages, this must include _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR.
++        * @return _MALI_OSK_ERR_OK on success.
++        * A value of type _mali_osk_errcode_t other than _MALI_OSK_ERR_OK indicates failure.
++        */
++      void (*unmap_physical)(mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t flags);
++
++} mali_kernel_mem_address_manager;
++
++mali_allocation_engine mali_allocation_engine_create(mali_kernel_mem_address_manager * mali_address_manager, mali_kernel_mem_address_manager * process_address_manager);
++
++void mali_allocation_engine_destroy(mali_allocation_engine engine);
++
++int mali_allocation_engine_allocate_memory(mali_allocation_engine engine, mali_memory_allocation * descriptor, mali_physical_memory_allocator * physical_provider, _mali_osk_list_t *tracking_list );
++void mali_allocation_engine_release_memory(mali_allocation_engine engine, mali_memory_allocation * descriptor);
++
++void mali_allocation_engine_release_pt1_mali_pagetables_unmap(mali_allocation_engine engine, mali_memory_allocation * descriptor);
++void mali_allocation_engine_release_pt2_physical_memory_free(mali_allocation_engine engine, mali_memory_allocation * descriptor);
++
++int mali_allocation_engine_map_physical(mali_allocation_engine engine, mali_memory_allocation * descriptor, u32 offset, u32 phys, u32 cpu_usage_adjust, u32 size);
++void mali_allocation_engine_unmap_physical(mali_allocation_engine engine, mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t unmap_flags);
++
++int mali_allocation_engine_allocate_page_tables(mali_allocation_engine, mali_page_table_block * descriptor, mali_physical_memory_allocator * physical_provider);
++
++void mali_allocation_engine_report_allocators(mali_physical_memory_allocator * physical_provider);
++
++u32 mali_allocation_engine_memory_usage(mali_physical_memory_allocator *allocator);
++
++#endif /* __MALI_KERNEL_MEMORY_ENGINE_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_kernel_utilization.c b/drivers/gpu/arm/mali400/mali/common/mali_kernel_utilization.c
+new file mode 100644
+index 0000000..4d48e86
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_kernel_utilization.c
+@@ -0,0 +1,275 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_kernel_utilization.h"
++#include "mali_osk.h"
++#include "mali_osk_mali.h"
++#include "mali_kernel_common.h"
++
++/* Define how often to calculate and report GPU utilization, in milliseconds */
++static _mali_osk_lock_t *time_data_lock;
++
++static _mali_osk_atomic_t num_running_cores;
++
++static u64 period_start_time = 0;
++static u64 work_start_time = 0;
++static u64 accumulated_work_time = 0;
++
++static _mali_osk_timer_t *utilization_timer = NULL;
++static mali_bool timer_running = MALI_FALSE;
++
++static u32 last_utilization = 0 ;
++
++static u32 mali_utilization_timeout = 1000;
++static int gpu_entry_count = 0;
++void (*mali_utilization_callback)(unsigned int) = NULL;
++
++static void calculate_gpu_utilization(void* arg)
++{
++      u64 time_now;
++      u64 time_period;
++      u32 leading_zeroes;
++      u32 shift_val;
++      u32 work_normalized;
++      u32 period_normalized;
++      u32 utilization;
++
++      _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW);
++
++      if (accumulated_work_time == 0 && work_start_time == 0)
++      {
++              /* Don't reschedule timer, this will be started if new work arrives */
++              timer_running = MALI_FALSE;
++
++              _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
++
++              /* No work done for this period, report zero usage */
++              if (NULL != mali_utilization_callback)
++              {
++                      mali_utilization_callback(0);
++              }
++
++              return;
++      }
++
++      time_now = _mali_osk_time_get_ns();
++      time_period = time_now - period_start_time;
++
++      /* If we are currently busy, update working period up to now */
++      if (work_start_time != 0)
++      {
++              accumulated_work_time += (time_now - work_start_time);
++              work_start_time = time_now;
++      }
++
++      /*
++       * We have two 64-bit values, a dividend and a divisor.
++       * To avoid dependencies to a 64-bit divider, we shift down the two values
++       * equally first.
++       * We shift the dividend up and possibly the divisor down, making the result X in 256.
++       */
++
++      /* Shift the 64-bit values down so they fit inside a 32-bit integer */
++      leading_zeroes = _mali_osk_clz((u32)(time_period >> 32));
++      shift_val = 32 - leading_zeroes;
++      work_normalized = (u32)(accumulated_work_time >> shift_val);
++      period_normalized = (u32)(time_period >> shift_val);
++
++      /*
++       * Now, we should report the usage in parts of 256
++       * this means we must shift up the dividend or down the divisor by 8
++       * (we could do a combination, but we just use one for simplicity,
++       * but the end result should be good enough anyway)
++       */
++      if (period_normalized > 0x00FFFFFF)
++      {
++              /* The divisor is so big that it is safe to shift it down */
++              period_normalized >>= 8;
++      }
++      else
++      {
++              /*
++               * The divisor is so small that we can shift up the dividend, without loosing any data.
++               * (dividend is always smaller than the divisor)
++               */
++              work_normalized <<= 8;
++      }
++
++      utilization = work_normalized / period_normalized;
++
++      last_utilization = utilization;
++
++      accumulated_work_time = 0;
++      period_start_time = time_now; /* starting a new period */
++
++      _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
++
++      if (gpu_entry_count <= 3) {
++              gpu_entry_count++;
++              _mali_osk_timer_add(utilization_timer, _mali_osk_time_mstoticks((mali_utilization_timeout/2)));
++      } else {
++              _mali_osk_timer_add(utilization_timer, _mali_osk_time_mstoticks(mali_utilization_timeout));
++      }
++
++      if (NULL != mali_utilization_callback)
++      {
++              mali_utilization_callback(utilization);
++      }
++}
++
++_mali_osk_errcode_t mali_utilization_init(void)
++{
++#if USING_GPU_UTILIZATION
++      struct _mali_osk_device_data data;
++      if (_MALI_OSK_ERR_OK == _mali_osk_device_data_get(&data))
++      {
++              /* Use device specific settings (if defined) */
++              if (0 != data.utilization_interval)
++              {
++                      mali_utilization_timeout = data.utilization_interval;
++              }
++              if (NULL != data.utilization_handler)
++              {
++                      mali_utilization_callback = data.utilization_handler;
++              }
++      }
++#endif
++
++      if (NULL != mali_utilization_callback)
++      {
++              MALI_DEBUG_PRINT(2, ("Mali GPU Utilization: Utilization handler installed with interval %u\n", mali_utilization_timeout));
++      }
++      else
++      {
++              MALI_DEBUG_PRINT(2, ("Mali GPU Utilization: No utilization handler installed\n"));
++      }
++
++      time_data_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ |
++                                           _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_UTILIZATION);
++
++      if (NULL == time_data_lock)
++      {
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      _mali_osk_atomic_init(&num_running_cores, 0);
++
++      utilization_timer = _mali_osk_timer_init();
++      if (NULL == utilization_timer)
++      {
++              _mali_osk_lock_term(time_data_lock);
++              return _MALI_OSK_ERR_FAULT;
++      }
++      _mali_osk_timer_setcallback(utilization_timer, calculate_gpu_utilization, NULL);
++
++      return _MALI_OSK_ERR_OK;
++}
++
++void mali_utilization_suspend(void)
++{
++      if (NULL != utilization_timer)
++      {
++              _mali_osk_timer_del(utilization_timer);
++              timer_running = MALI_FALSE;
++      }
++}
++
++void mali_utilization_term(void)
++{
++      if (NULL != utilization_timer)
++      {
++              _mali_osk_timer_del(utilization_timer);
++              timer_running = MALI_FALSE;
++              _mali_osk_timer_term(utilization_timer);
++              utilization_timer = NULL;
++      }
++
++      _mali_osk_atomic_term(&num_running_cores);
++
++      _mali_osk_lock_term(time_data_lock);
++}
++
++void mali_utilization_core_start(u64 time_now)
++{
++      if (_mali_osk_atomic_inc_return(&num_running_cores) == 1)
++      {
++              /*
++               * We went from zero cores working, to one core working,
++               * we now consider the entire GPU for being busy
++               */
++
++              _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW);
++
++              if (time_now < period_start_time)
++              {
++                      /*
++                       * This might happen if the calculate_gpu_utilization() was able
++                       * to run between the sampling of time_now and us grabbing the lock above
++                       */
++                      time_now = period_start_time;
++              }
++
++              work_start_time = time_now;
++              if (timer_running != MALI_TRUE)
++              {
++                      timer_running = MALI_TRUE;
++                      period_start_time = work_start_time; /* starting a new period */
++
++                      _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
++
++                      gpu_entry_count = 0;
++                      _mali_osk_timer_add(utilization_timer, _mali_osk_time_mstoticks((mali_utilization_timeout/2)));
++              }
++              else
++              {
++                      _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
++              }
++      }
++}
++
++void mali_utilization_core_end(u64 time_now)
++{
++      if (_mali_osk_atomic_dec_return(&num_running_cores) == 0)
++      {
++              /*
++               * No more cores are working, so accumulate the time we was busy.
++               */
++              _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW);
++
++              if (time_now < work_start_time)
++              {
++                      /*
++                       * This might happen if the calculate_gpu_utilization() was able
++                       * to run between the sampling of time_now and us grabbing the lock above
++                       */
++                      time_now = work_start_time;
++              }
++
++              accumulated_work_time += (time_now - work_start_time);
++              work_start_time = 0;
++
++              _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
++      }
++}
++
++u32 _mali_ukk_utilization_gp_pp(void)
++{
++      return last_utilization;
++}
++
++u32 _mali_ukk_utilization_gp(void)
++{
++      return last_utilization;
++}
++
++u32 _mali_ukk_utilization_pp(void)
++{
++      return last_utilization;
++}
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_kernel_utilization.h b/drivers/gpu/arm/mali400/mali/common/mali_kernel_utilization.h
+new file mode 100644
+index 0000000..0769d08
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_kernel_utilization.h
+@@ -0,0 +1,53 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_KERNEL_UTILIZATION_H__
++#define __MALI_KERNEL_UTILIZATION_H__
++
++#include "mali_osk.h"
++
++extern void (*mali_utilization_callback)(unsigned int);
++
++/**
++ * Initialize/start the Mali GPU utilization metrics reporting.
++ *
++ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
++ */
++_mali_osk_errcode_t mali_utilization_init(void);
++
++/**
++ * Terminate the Mali GPU utilization metrics reporting
++ */
++void mali_utilization_term(void);
++
++/**
++ * Check if Mali utilization is enabled
++ */
++MALI_STATIC_INLINE mali_bool mali_utilization_enabled(void)
++{
++      return (NULL != mali_utilization_callback);
++}
++
++/**
++ * Should be called when a job is about to execute a job
++ */
++void mali_utilization_core_start(u64 time_now);
++
++/**
++ * Should be called to stop the utilization timer during system suspend
++ */
++void mali_utilization_suspend(void);
++
++/**
++ * Should be called when a job has completed executing a job
++ */
++void mali_utilization_core_end(u64 time_now);
++
++#endif /* __MALI_KERNEL_UTILIZATION_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_kernel_vsync.c b/drivers/gpu/arm/mali400/mali/common/mali_kernel_vsync.c
+new file mode 100644
+index 0000000..375f378
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_kernel_vsync.c
+@@ -0,0 +1,51 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_kernel_common.h"
++#include "mali_osk.h"
++#include "mali_ukk.h"
++
++#if defined(CONFIG_MALI400_PROFILING)
++#include "mali_osk_profiling.h"
++#endif
++
++_mali_osk_errcode_t _mali_ukk_vsync_event_report(_mali_uk_vsync_event_report_s *args)
++{
++      _mali_uk_vsync_event event = (_mali_uk_vsync_event)args->event;
++      MALI_IGNORE(event); /* event is not used for release code, and that is OK */
++
++#if defined(CONFIG_MALI400_PROFILING)
++      /*
++       * Manually generate user space events in kernel space.
++       * This saves user space from calling kernel space twice in this case.
++       * We just need to remember to add pid and tid manually.
++       */
++      if ( event==_MALI_UK_VSYNC_EVENT_BEGIN_WAIT)
++      {
++              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SUSPEND |
++                                            MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
++                                            MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VSYNC,
++                                            _mali_osk_get_pid(), _mali_osk_get_tid(), 0, 0, 0);
++      }
++
++      if (event==_MALI_UK_VSYNC_EVENT_END_WAIT)
++      {
++
++              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_RESUME |
++                                            MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
++                                            MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VSYNC,
++                                            _mali_osk_get_pid(), _mali_osk_get_tid(), 0, 0, 0);
++      }
++#endif
++
++      MALI_DEBUG_PRINT(4, ("Received VSYNC event: %d\n", event));
++      MALI_SUCCESS;
++}
++
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_l2_cache.c b/drivers/gpu/arm/mali400/mali/common/mali_l2_cache.c
+new file mode 100644
+index 0000000..de42aa8
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_l2_cache.c
+@@ -0,0 +1,474 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++#include "mali_kernel_common.h"
++#include "mali_osk.h"
++#include "mali_l2_cache.h"
++#include "mali_hw_core.h"
++#include "mali_scheduler.h"
++
++/**
++ * Size of the Mali L2 cache registers in bytes
++ */
++#define MALI400_L2_CACHE_REGISTERS_SIZE 0x30
++
++/**
++ * Mali L2 cache register numbers
++ * Used in the register read/write routines.
++ * See the hardware documentation for more information about each register
++ */
++typedef enum mali_l2_cache_register {
++      MALI400_L2_CACHE_REGISTER_STATUS       = 0x0008,
++      /*unused                               = 0x000C */
++      MALI400_L2_CACHE_REGISTER_COMMAND      = 0x0010, /**< Misc cache commands, e.g. clear */
++      MALI400_L2_CACHE_REGISTER_CLEAR_PAGE   = 0x0014,
++      MALI400_L2_CACHE_REGISTER_MAX_READS    = 0x0018, /**< Limit of outstanding read requests */
++      MALI400_L2_CACHE_REGISTER_ENABLE       = 0x001C, /**< Enable misc cache features */
++      MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0 = 0x0020,
++      MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0 = 0x0024,
++      MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1 = 0x0028,
++      MALI400_L2_CACHE_REGISTER_PERFCNT_VAL1 = 0x002C,
++} mali_l2_cache_register;
++
++/**
++ * Mali L2 cache commands
++ * These are the commands that can be sent to the Mali L2 cache unit
++ */
++typedef enum mali_l2_cache_command
++{
++      MALI400_L2_CACHE_COMMAND_CLEAR_ALL = 0x01, /**< Clear the entire cache */
++      /* Read HW TRM carefully before adding/using other commands than the clear above */
++} mali_l2_cache_command;
++
++/**
++ * Mali L2 cache commands
++ * These are the commands that can be sent to the Mali L2 cache unit
++ */
++typedef enum mali_l2_cache_enable
++{
++      MALI400_L2_CACHE_ENABLE_DEFAULT = 0x0, /**< Default state of enable register */
++      MALI400_L2_CACHE_ENABLE_ACCESS = 0x01, /**< Permit cacheable accesses */
++      MALI400_L2_CACHE_ENABLE_READ_ALLOCATE = 0x02, /**< Permit cache read allocate */
++} mali_l2_cache_enable;
++
++/**
++ * Mali L2 cache status bits
++ */
++typedef enum mali_l2_cache_status
++{
++      MALI400_L2_CACHE_STATUS_COMMAND_BUSY = 0x01, /**< Command handler of L2 cache is busy */
++      MALI400_L2_CACHE_STATUS_DATA_BUSY    = 0x02, /**< L2 cache is busy handling data requests */
++} mali_l2_cache_status;
++
++/**
++ * Definition of the L2 cache core struct
++ * Used to track a L2 cache unit in the system.
++ * Contains information about the mapping of the registers
++ */
++struct mali_l2_cache_core
++{
++      struct mali_hw_core  hw_core;      /**< Common for all HW cores */
++      u32                  core_id;      /**< Unique core ID */
++      _mali_osk_lock_t    *command_lock; /**< Serialize all L2 cache commands */
++      _mali_osk_lock_t    *counter_lock; /**< Synchronize L2 cache counter access */
++      u32                  counter_src0; /**< Performance counter 0, MALI_HW_CORE_NO_COUNTER for disabled */
++      u32                  counter_src1; /**< Performance counter 1, MALI_HW_CORE_NO_COUNTER for disabled */
++      u32                  last_invalidated_id;
++      mali_bool            power_is_enabled;
++};
++
++#define MALI400_L2_MAX_READS_DEFAULT 0x1C
++
++static struct mali_l2_cache_core *mali_global_l2_cache_cores[MALI_MAX_NUMBER_OF_L2_CACHE_CORES];
++static u32 mali_global_num_l2_cache_cores = 0;
++
++int mali_l2_max_reads = MALI400_L2_MAX_READS_DEFAULT;
++
++/* Local helper functions */
++static _mali_osk_errcode_t mali_l2_cache_send_command(struct mali_l2_cache_core *cache, u32 reg, u32 val);
++
++
++struct mali_l2_cache_core *mali_l2_cache_create(_mali_osk_resource_t *resource)
++{
++      struct mali_l2_cache_core *cache = NULL;
++      _mali_osk_lock_flags_t lock_flags;
++
++#if defined(MALI_UPPER_HALF_SCHEDULING)
++      lock_flags = _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE;
++#else
++      lock_flags = _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE;
++#endif
++
++      MALI_DEBUG_PRINT(2, ("Mali L2 cache: Creating Mali L2 cache: %s\n", resource->description));
++
++      if (mali_global_num_l2_cache_cores >= MALI_MAX_NUMBER_OF_L2_CACHE_CORES)
++      {
++              MALI_PRINT_ERROR(("Mali L2 cache: Too many L2 cache core objects created\n"));
++              return NULL;
++      }
++
++      cache = _mali_osk_malloc(sizeof(struct mali_l2_cache_core));
++      if (NULL != cache)
++      {
++              cache->core_id =  mali_global_num_l2_cache_cores;
++              cache->counter_src0 = MALI_HW_CORE_NO_COUNTER;
++              cache->counter_src1 = MALI_HW_CORE_NO_COUNTER;
++              if (_MALI_OSK_ERR_OK == mali_hw_core_create(&cache->hw_core, resource, MALI400_L2_CACHE_REGISTERS_SIZE))
++              {
++                      cache->command_lock = _mali_osk_lock_init(lock_flags, 0, _MALI_OSK_LOCK_ORDER_L2_COMMAND);
++                      if (NULL != cache->command_lock)
++                      {
++                              cache->counter_lock = _mali_osk_lock_init(lock_flags, 0, _MALI_OSK_LOCK_ORDER_L2_COUNTER);
++                              if (NULL != cache->counter_lock)
++                              {
++                                      mali_l2_cache_reset(cache);
++
++                                      cache->last_invalidated_id = 0;
++                                      cache->power_is_enabled = MALI_TRUE;
++
++                                      mali_global_l2_cache_cores[mali_global_num_l2_cache_cores] = cache;
++                                      mali_global_num_l2_cache_cores++;
++
++                                      return cache;
++                              }
++                              else
++                              {
++                                      MALI_PRINT_ERROR(("Mali L2 cache: Failed to create counter lock for L2 cache core %s\n", cache->hw_core.description));
++                              }
++
++                              _mali_osk_lock_term(cache->command_lock);
++                      }
++                      else
++                      {
++                              MALI_PRINT_ERROR(("Mali L2 cache: Failed to create command lock for L2 cache core %s\n", cache->hw_core.description));
++                      }
++
++                      mali_hw_core_delete(&cache->hw_core);
++              }
++
++              _mali_osk_free(cache);
++      }
++      else
++      {
++              MALI_PRINT_ERROR(("Mali L2 cache: Failed to allocate memory for L2 cache core\n"));
++      }
++
++      return NULL;
++}
++
++void mali_l2_cache_delete(struct mali_l2_cache_core *cache)
++{
++      u32 i;
++
++      /* reset to defaults */
++      mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_MAX_READS, (u32)MALI400_L2_MAX_READS_DEFAULT);
++      mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_ENABLE, (u32)MALI400_L2_CACHE_ENABLE_DEFAULT);
++
++      _mali_osk_lock_term(cache->counter_lock);
++      _mali_osk_lock_term(cache->command_lock);
++      mali_hw_core_delete(&cache->hw_core);
++
++      for (i = 0; i < MALI_MAX_NUMBER_OF_L2_CACHE_CORES; i++)
++      {
++              if (mali_global_l2_cache_cores[i] == cache)
++              {
++                      mali_global_l2_cache_cores[i] = NULL;
++                      mali_global_num_l2_cache_cores--;
++              }
++      }
++
++      _mali_osk_free(cache);
++}
++
++void mali_l2_cache_power_is_enabled_set(struct mali_l2_cache_core * core, mali_bool power_is_enabled)
++{
++       core->power_is_enabled = power_is_enabled;
++}
++
++mali_bool mali_l2_cache_power_is_enabled_get(struct mali_l2_cache_core * core)
++{
++       return core->power_is_enabled;
++}
++
++u32 mali_l2_cache_get_id(struct mali_l2_cache_core *cache)
++{
++      return cache->core_id;
++}
++
++mali_bool mali_l2_cache_core_set_counter_src0(struct mali_l2_cache_core *cache, u32 counter)
++{
++      u32 value = 0; /* disabled src */
++      mali_bool core_is_on;
++
++      MALI_DEBUG_ASSERT_POINTER(cache);
++
++      core_is_on = mali_l2_cache_lock_power_state(cache);
++
++      _mali_osk_lock_wait(cache->counter_lock, _MALI_OSK_LOCKMODE_RW);
++
++      cache->counter_src0 = counter;
++
++      if (MALI_HW_CORE_NO_COUNTER != counter)
++      {
++              value = counter;
++      }
++
++      if (MALI_TRUE == core_is_on)
++      {
++              mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0, value);
++      }
++
++      _mali_osk_lock_signal(cache->counter_lock, _MALI_OSK_LOCKMODE_RW);
++
++      mali_l2_cache_unlock_power_state(cache);
++
++      return MALI_TRUE;
++}
++
++mali_bool mali_l2_cache_core_set_counter_src1(struct mali_l2_cache_core *cache, u32 counter)
++{
++      u32 value = 0; /* disabled src */
++      mali_bool core_is_on;
++
++      MALI_DEBUG_ASSERT_POINTER(cache);
++
++      core_is_on = mali_l2_cache_lock_power_state(cache);
++
++      _mali_osk_lock_wait(cache->counter_lock, _MALI_OSK_LOCKMODE_RW);
++
++      cache->counter_src1 = counter;
++
++      if (MALI_HW_CORE_NO_COUNTER != counter)
++      {
++              value = counter;
++      }
++
++      if (MALI_TRUE == core_is_on)
++      {
++              mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1, value);
++      }
++
++      _mali_osk_lock_signal(cache->counter_lock, _MALI_OSK_LOCKMODE_RW);
++
++      mali_l2_cache_unlock_power_state(cache);
++
++      return MALI_TRUE;
++}
++
++u32 mali_l2_cache_core_get_counter_src0(struct mali_l2_cache_core *cache)
++{
++      return cache->counter_src0;
++}
++
++u32 mali_l2_cache_core_get_counter_src1(struct mali_l2_cache_core *cache)
++{
++      return cache->counter_src1;
++}
++
++void mali_l2_cache_core_get_counter_values(struct mali_l2_cache_core *cache, u32 *src0, u32 *value0, u32 *src1, u32 *value1)
++{
++      MALI_DEBUG_ASSERT(NULL != src0);
++      MALI_DEBUG_ASSERT(NULL != value0);
++      MALI_DEBUG_ASSERT(NULL != src1);
++      MALI_DEBUG_ASSERT(NULL != value1);
++
++      /* Caller must hold the PM lock and know that we are powered on */
++
++      _mali_osk_lock_wait(cache->counter_lock, _MALI_OSK_LOCKMODE_RW);
++
++      *src0 = cache->counter_src0;
++      *src1 = cache->counter_src1;
++
++      if (cache->counter_src0 != MALI_HW_CORE_NO_COUNTER)
++      {
++              *value0 = mali_hw_core_register_read(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0);
++      }
++
++      if (cache->counter_src1 != MALI_HW_CORE_NO_COUNTER)
++      {
++              *value1 = mali_hw_core_register_read(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_VAL1);
++      }
++
++      _mali_osk_lock_signal(cache->counter_lock, _MALI_OSK_LOCKMODE_RW);
++}
++
++struct mali_l2_cache_core *mali_l2_cache_core_get_glob_l2_core(u32 index)
++{
++      if (MALI_MAX_NUMBER_OF_L2_CACHE_CORES > index)
++      {
++              return mali_global_l2_cache_cores[index];
++      }
++
++      return NULL;
++}
++
++u32 mali_l2_cache_core_get_glob_num_l2_cores(void)
++{
++      return mali_global_num_l2_cache_cores;
++}
++
++void mali_l2_cache_reset(struct mali_l2_cache_core *cache)
++{
++      /* Invalidate cache (just to keep it in a known state at startup) */
++      mali_l2_cache_invalidate_all(cache);
++
++      /* Enable cache */
++      mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_ENABLE, (u32)MALI400_L2_CACHE_ENABLE_ACCESS | (u32)MALI400_L2_CACHE_ENABLE_READ_ALLOCATE);
++      mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_MAX_READS, (u32)mali_l2_max_reads);
++
++      /* Restart any performance counters (if enabled) */
++      _mali_osk_lock_wait(cache->counter_lock, _MALI_OSK_LOCKMODE_RW);
++
++      if (cache->counter_src0 != MALI_HW_CORE_NO_COUNTER)
++      {
++              mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0, cache->counter_src0);
++      }
++
++      if (cache->counter_src1 != MALI_HW_CORE_NO_COUNTER)
++      {
++              mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1, cache->counter_src1);
++      }
++
++      _mali_osk_lock_signal(cache->counter_lock, _MALI_OSK_LOCKMODE_RW);
++}
++
++void mali_l2_cache_reset_all(void)
++{
++      int i;
++      u32 num_cores = mali_l2_cache_core_get_glob_num_l2_cores();
++
++      for (i = 0; i < num_cores; i++)
++      {
++              mali_l2_cache_reset(mali_l2_cache_core_get_glob_l2_core(i));
++      }
++}
++
++_mali_osk_errcode_t mali_l2_cache_invalidate_all(struct mali_l2_cache_core *cache)
++{
++      return mali_l2_cache_send_command(cache, MALI400_L2_CACHE_REGISTER_COMMAND, MALI400_L2_CACHE_COMMAND_CLEAR_ALL);
++}
++
++mali_bool mali_l2_cache_invalidate_all_conditional(struct mali_l2_cache_core *cache, u32 id)
++{
++       MALI_DEBUG_ASSERT_POINTER(cache);
++
++       if (NULL != cache)
++       {
++               /* If the last cache invalidation was done by a job with a higher id we
++                * don't have to flush. Since user space will store jobs w/ their
++                * corresponding memory in sequence (first job #0, then job #1, ...),
++                * we don't have to flush for job n-1 if job n has already invalidated
++                * the cache since we know for sure that job n-1's memory was already
++                * written when job n was started. */
++               if (((s32)id) <= ((s32)cache->last_invalidated_id))
++               {
++                       return MALI_FALSE;
++               }
++               else
++               {
++                       cache->last_invalidated_id = mali_scheduler_get_new_id();
++               }
++
++               mali_l2_cache_invalidate_all(cache);
++       }
++       return MALI_TRUE;
++}
++
++void mali_l2_cache_invalidate_all_force(struct mali_l2_cache_core *cache)
++{
++       MALI_DEBUG_ASSERT_POINTER(cache);
++
++       if (NULL != cache)
++       {
++               cache->last_invalidated_id = mali_scheduler_get_new_id();
++               mali_l2_cache_invalidate_all(cache);
++       }
++}
++
++_mali_osk_errcode_t mali_l2_cache_invalidate_pages(struct mali_l2_cache_core *cache, u32 *pages, u32 num_pages)
++{
++      u32 i;
++      _mali_osk_errcode_t ret1, ret = _MALI_OSK_ERR_OK;
++
++      for (i = 0; i < num_pages; i++)
++      {
++              ret1 = mali_l2_cache_send_command(cache, MALI400_L2_CACHE_REGISTER_CLEAR_PAGE, pages[i]);
++              if (_MALI_OSK_ERR_OK != ret1)
++              {
++                      ret = ret1;
++              }
++      }
++
++      return ret;
++}
++
++void mali_l2_cache_invalidate_pages_conditional(u32 *pages, u32 num_pages)
++{
++       u32 i;
++
++       for (i = 0; i < mali_global_num_l2_cache_cores; i++)
++       {
++               /*additional check*/
++               if (MALI_TRUE == mali_l2_cache_lock_power_state(mali_global_l2_cache_cores[i]))
++               {
++                       mali_l2_cache_invalidate_pages(mali_global_l2_cache_cores[i], pages, num_pages);
++               }
++               mali_l2_cache_unlock_power_state(mali_global_l2_cache_cores[i]);
++               /*check for failed power locking???*/
++       }
++}
++
++mali_bool mali_l2_cache_lock_power_state(struct mali_l2_cache_core *cache)
++{
++      return _mali_osk_pm_dev_ref_add_no_power_on();
++}
++
++void mali_l2_cache_unlock_power_state(struct mali_l2_cache_core *cache)
++{
++      _mali_osk_pm_dev_ref_dec_no_power_on();
++}
++
++/* -------- local helper functions below -------- */
++
++
++static _mali_osk_errcode_t mali_l2_cache_send_command(struct mali_l2_cache_core *cache, u32 reg, u32 val)
++{
++      int i = 0;
++      const int loop_count = 100000;
++
++      /*
++       * Grab lock in order to send commands to the L2 cache in a serialized fashion.
++       * The L2 cache will ignore commands if it is busy.
++       */
++      _mali_osk_lock_wait(cache->command_lock, _MALI_OSK_LOCKMODE_RW);
++
++      /* First, wait for L2 cache command handler to go idle */
++
++      for (i = 0; i < loop_count; i++)
++      {
++              if (!(mali_hw_core_register_read(&cache->hw_core, MALI400_L2_CACHE_REGISTER_STATUS) & (u32)MALI400_L2_CACHE_STATUS_COMMAND_BUSY))
++              {
++                      break;
++              }
++      }
++
++      if (i == loop_count)
++      {
++              _mali_osk_lock_signal(cache->command_lock, _MALI_OSK_LOCKMODE_RW);
++              MALI_DEBUG_PRINT(1, ( "Mali L2 cache: aborting wait for command interface to go idle\n"));
++              MALI_ERROR( _MALI_OSK_ERR_FAULT );
++      }
++
++      /* then issue the command */
++      mali_hw_core_register_write(&cache->hw_core, reg, val);
++
++      _mali_osk_lock_signal(cache->command_lock, _MALI_OSK_LOCKMODE_RW);
++
++      MALI_SUCCESS;
++}
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_l2_cache.h b/drivers/gpu/arm/mali400/mali/common/mali_l2_cache.h
+new file mode 100644
+index 0000000..ce3f1e9
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_l2_cache.h
+@@ -0,0 +1,56 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_KERNEL_L2_CACHE_H__
++#define __MALI_KERNEL_L2_CACHE_H__
++
++#include "mali_osk.h"
++
++#define MALI_MAX_NUMBER_OF_L2_CACHE_CORES  3
++/* Maximum 1 GP and 4 PP for an L2 cache core (Mali-400 Quad-core) */
++#define MALI_MAX_NUMBER_OF_GROUPS_PER_L2_CACHE 5
++
++struct mali_l2_cache_core;
++struct mali_group;
++
++_mali_osk_errcode_t mali_l2_cache_initialize(void);
++void mali_l2_cache_terminate(void);
++
++struct mali_l2_cache_core *mali_l2_cache_create(_mali_osk_resource_t * resource);
++void mali_l2_cache_delete(struct mali_l2_cache_core *cache);
++
++void mali_l2_cache_power_is_enabled_set(struct mali_l2_cache_core *core, mali_bool power_is_enabled);
++mali_bool mali_l2_cache_power_is_enabled_get(struct mali_l2_cache_core * core);
++
++u32 mali_l2_cache_get_id(struct mali_l2_cache_core *cache);
++
++mali_bool mali_l2_cache_core_set_counter_src0(struct mali_l2_cache_core *cache, u32 counter);
++mali_bool mali_l2_cache_core_set_counter_src1(struct mali_l2_cache_core *cache, u32 counter);
++u32 mali_l2_cache_core_get_counter_src0(struct mali_l2_cache_core *cache);
++u32 mali_l2_cache_core_get_counter_src1(struct mali_l2_cache_core *cache);
++void mali_l2_cache_core_get_counter_values(struct mali_l2_cache_core *cache, u32 *src0, u32 *value0, u32 *src1, u32 *value1);
++struct mali_l2_cache_core *mali_l2_cache_core_get_glob_l2_core(u32 index);
++u32 mali_l2_cache_core_get_glob_num_l2_cores(void);
++
++void mali_l2_cache_reset(struct mali_l2_cache_core *cache);
++void mali_l2_cache_reset_all(void);
++
++struct mali_group *mali_l2_cache_get_group(struct mali_l2_cache_core *cache, u32 index);
++
++_mali_osk_errcode_t mali_l2_cache_invalidate_all(struct mali_l2_cache_core *cache);
++mali_bool mali_l2_cache_invalidate_all_conditional(struct mali_l2_cache_core *cache, u32 id);
++void mali_l2_cache_invalidate_all_force(struct mali_l2_cache_core *cache);
++_mali_osk_errcode_t mali_l2_cache_invalidate_pages(struct mali_l2_cache_core *cache, u32 *pages, u32 num_pages);
++void mali_l2_cache_invalidate_pages_conditional(u32 *pages, u32 num_pages);
++
++mali_bool mali_l2_cache_lock_power_state(struct mali_l2_cache_core *cache);
++void mali_l2_cache_unlock_power_state(struct mali_l2_cache_core *cache);
++
++#endif /* __MALI_KERNEL_L2_CACHE_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_mem_validation.c b/drivers/gpu/arm/mali400/mali/common/mali_mem_validation.c
+new file mode 100644
+index 0000000..7281a13
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_mem_validation.c
+@@ -0,0 +1,71 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_mem_validation.h"
++#include "mali_osk.h"
++#include "mali_kernel_common.h"
++
++#define MALI_INVALID_MEM_ADDR 0xFFFFFFFF
++
++typedef struct
++{
++      u32 phys_base;        /**< Mali physical base of the memory, page aligned */
++      u32 size;             /**< size in bytes of the memory, multiple of page size */
++} _mali_mem_validation_t;
++
++static _mali_mem_validation_t mali_mem_validator = { MALI_INVALID_MEM_ADDR, MALI_INVALID_MEM_ADDR };
++
++_mali_osk_errcode_t mali_mem_validation_add_range(u32 start, u32 size)
++{
++      /* Check that no other MEM_VALIDATION resources exist */
++      if (MALI_INVALID_MEM_ADDR != mali_mem_validator.phys_base)
++      {
++              MALI_PRINT_ERROR(("Failed to add frame buffer memory; another range is already specified\n"));
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      /* Check restrictions on page alignment */
++      if ((0 != (start & (~_MALI_OSK_CPU_PAGE_MASK))) ||
++          (0 != (size & (~_MALI_OSK_CPU_PAGE_MASK))))
++      {
++              MALI_PRINT_ERROR(("Failed to add frame buffer memory; incorrect alignment\n"));
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      mali_mem_validator.phys_base = start;
++      mali_mem_validator.size = size;
++      MALI_DEBUG_PRINT(2, ("Memory Validator installed for Mali physical address base=0x%08X, size=0x%08X\n",
++                       mali_mem_validator.phys_base, mali_mem_validator.size));
++
++      return _MALI_OSK_ERR_OK;
++}
++
++_mali_osk_errcode_t mali_mem_validation_check(u32 phys_addr, u32 size)
++{
++      if (phys_addr < (phys_addr + size)) /* Don't allow overflow (or zero size) */
++      {
++              if ((0 == ( phys_addr & (~_MALI_OSK_CPU_PAGE_MASK))) &&
++                      (0 == ( size & (~_MALI_OSK_CPU_PAGE_MASK))))
++              {
++                      if ((phys_addr          >= mali_mem_validator.phys_base) &&
++                              ((phys_addr + (size - 1)) >= mali_mem_validator.phys_base) &&
++                              (phys_addr          <= (mali_mem_validator.phys_base + (mali_mem_validator.size - 1))) &&
++                              ((phys_addr + (size - 1)) <= (mali_mem_validator.phys_base + (mali_mem_validator.size - 1))) )
++                      {
++                              MALI_DEBUG_PRINT(3, ("Accepted range 0x%08X + size 0x%08X (= 0x%08X)\n", phys_addr, size, (phys_addr + size - 1)));
++                              return _MALI_OSK_ERR_OK;
++                      }
++              }
++      }
++
++      MALI_PRINT_ERROR(("MALI PHYSICAL RANGE VALIDATION ERROR: The range supplied was: phys_base=0x%08X, size=0x%08X\n", phys_addr, size));
++
++      return _MALI_OSK_ERR_FAULT;
++}
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_mem_validation.h b/drivers/gpu/arm/mali400/mali/common/mali_mem_validation.h
+new file mode 100644
+index 0000000..e020429
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_mem_validation.h
+@@ -0,0 +1,19 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_MEM_VALIDATION_H__
++#define __MALI_MEM_VALIDATION_H__
++
++#include "mali_osk.h"
++
++_mali_osk_errcode_t mali_mem_validation_add_range(u32 start, u32 size);
++_mali_osk_errcode_t mali_mem_validation_check(u32 phys_addr, u32 size);
++
++#endif /* __MALI_MEM_VALIDATION_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_memory.c b/drivers/gpu/arm/mali400/mali/common/mali_memory.c
+new file mode 100644
+index 0000000..1fccb86
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_memory.c
+@@ -0,0 +1,1297 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_kernel_common.h"
++#include "mali_kernel_descriptor_mapping.h"
++#include "mali_mem_validation.h"
++#include "mali_memory.h"
++#include "mali_mmu_page_directory.h"
++#include "mali_kernel_memory_engine.h"
++#include "mali_block_allocator.h"
++#include "mali_kernel_mem_os.h"
++#include "mali_session.h"
++#include "mali_l2_cache.h"
++#include "mali_scheduler.h"
++#if defined(CONFIG_MALI400_UMP)
++#include "ump_kernel_interface.h"
++#endif
++
++/* kernel side OS functions and user-kernel interface */
++#include "mali_osk.h"
++#include "mali_osk_mali.h"
++#include "mali_ukk.h"
++#include "mali_osk_list.h"
++#include "mali_osk_bitops.h"
++
++/**
++ * Per-session memory descriptor mapping table sizes
++ */
++#define MALI_MEM_DESCRIPTORS_INIT 64
++#define MALI_MEM_DESCRIPTORS_MAX 65536
++
++typedef struct dedicated_memory_info
++{
++      u32 base;
++      u32 size;
++      struct dedicated_memory_info * next;
++} dedicated_memory_info;
++
++/* types used for external_memory and ump_memory physical memory allocators, which are using the mali_allocation_engine */
++#if defined(CONFIG_MALI400_UMP)
++typedef struct ump_mem_allocation
++{
++      mali_allocation_engine * engine;
++      mali_memory_allocation * descriptor;
++      u32 initial_offset;
++      u32 size_allocated;
++      ump_dd_handle ump_mem;
++} ump_mem_allocation ;
++#endif
++
++typedef struct external_mem_allocation
++{
++      mali_allocation_engine * engine;
++      mali_memory_allocation * descriptor;
++      u32 initial_offset;
++      u32 size;
++} external_mem_allocation;
++
++/**
++ * @brief Internal function for unmapping memory
++ *
++ * Worker function for unmapping memory from a user-process. We assume that the
++ * session/descriptor's lock was obtained before entry. For example, the
++ * wrapper _mali_ukk_mem_munmap() will lock the descriptor, then call this
++ * function to do the actual unmapping. mali_memory_core_session_end() could
++ * also call this directly (depending on compilation options), having locked
++ * the descriptor.
++ *
++ * This function will fail if it is unable to put the MMU in stall mode (which
++ * might be the case if a page fault is also being processed).
++ *
++ * @param args see _mali_uk_mem_munmap_s in "mali_utgard_uk_types.h"
++ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
++ */
++static _mali_osk_errcode_t _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args );
++
++#if defined(CONFIG_MALI400_UMP)
++static void ump_memory_release(void * ctx, void * handle);
++static mali_physical_memory_allocation_result ump_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info);
++#endif /* CONFIG_MALI400_UMP */
++
++
++static void external_memory_release(void * ctx, void * handle);
++static mali_physical_memory_allocation_result external_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info);
++
++
++/* nop functions */
++
++/* mali address manager needs to allocate page tables on allocate, write to page table(s) on map, write to page table(s) and release page tables on release */
++static _mali_osk_errcode_t  mali_address_manager_allocate(mali_memory_allocation * descriptor); /* validates the range, allocates memory for the page tables if needed */
++static _mali_osk_errcode_t  mali_address_manager_map(mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size);
++static void mali_address_manager_release(mali_memory_allocation * descriptor);
++
++/* MMU variables */
++
++typedef struct mali_mmu_page_table_allocation
++{
++      _mali_osk_list_t list;
++      u32 * usage_map;
++      u32 usage_count;
++      u32 num_pages;
++      mali_page_table_block pages;
++} mali_mmu_page_table_allocation;
++
++typedef struct mali_mmu_page_table_allocations
++{
++      _mali_osk_lock_t *lock;
++      _mali_osk_list_t partial;
++      _mali_osk_list_t full;
++      /* we never hold on to a empty allocation */
++} mali_mmu_page_table_allocations;
++
++static mali_kernel_mem_address_manager mali_address_manager =
++{
++      mali_address_manager_allocate, /* allocate */
++      mali_address_manager_release,  /* release */
++      mali_address_manager_map,      /* map_physical */
++      NULL                           /* unmap_physical not present*/
++};
++
++/* the mmu page table cache */
++static struct mali_mmu_page_table_allocations page_table_cache;
++
++
++static mali_kernel_mem_address_manager process_address_manager =
++{
++      _mali_osk_mem_mapregion_init,  /* allocate */
++      _mali_osk_mem_mapregion_term,  /* release */
++      _mali_osk_mem_mapregion_map,   /* map_physical */
++      _mali_osk_mem_mapregion_unmap  /* unmap_physical */
++};
++
++static _mali_osk_errcode_t mali_mmu_page_table_cache_create(void);
++static void mali_mmu_page_table_cache_destroy(void);
++
++static mali_allocation_engine memory_engine = NULL;
++static mali_physical_memory_allocator * physical_memory_allocators = NULL;
++
++static dedicated_memory_info * mem_region_registrations = NULL;
++
++mali_allocation_engine mali_mem_get_memory_engine(void)
++{
++      return memory_engine;
++}
++
++/* called during module init */
++_mali_osk_errcode_t mali_memory_initialize(void)
++{
++      _mali_osk_errcode_t err;
++
++      MALI_DEBUG_PRINT(2, ("Memory system initializing\n"));
++
++      err = mali_mmu_page_table_cache_create();
++      if(_MALI_OSK_ERR_OK != err)
++      {
++              MALI_ERROR(err);
++      }
++
++      memory_engine = mali_allocation_engine_create(&mali_address_manager, &process_address_manager);
++      MALI_CHECK_NON_NULL( memory_engine, _MALI_OSK_ERR_FAULT);
++
++      MALI_SUCCESS;
++}
++
++/* called if/when our module is unloaded */
++void mali_memory_terminate(void)
++{
++      MALI_DEBUG_PRINT(2, ("Memory system terminating\n"));
++
++      mali_mmu_page_table_cache_destroy();
++
++      while ( NULL != mem_region_registrations)
++      {
++              dedicated_memory_info * m;
++              m = mem_region_registrations;
++              mem_region_registrations = m->next;
++              _mali_osk_mem_unreqregion(m->base, m->size);
++              _mali_osk_free(m);
++      }
++
++      while ( NULL != physical_memory_allocators)
++      {
++              mali_physical_memory_allocator * m;
++              m = physical_memory_allocators;
++              physical_memory_allocators = m->next;
++              m->destroy(m);
++      }
++
++      if (NULL != memory_engine)
++      {
++              mali_allocation_engine_destroy(memory_engine);
++              memory_engine = NULL;
++      }
++}
++
++_mali_osk_errcode_t mali_memory_session_begin(struct mali_session_data * session_data)
++{
++      MALI_DEBUG_PRINT(5, ("Memory session begin\n"));
++
++      /* create descriptor mapping table */
++      session_data->descriptor_mapping = mali_descriptor_mapping_create(MALI_MEM_DESCRIPTORS_INIT, MALI_MEM_DESCRIPTORS_MAX);
++
++      if (NULL == session_data->descriptor_mapping)
++      {
++              MALI_ERROR(_MALI_OSK_ERR_NOMEM);
++      }
++
++      session_data->memory_lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_ONELOCK
++                                      | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_MEM_SESSION);
++      if (NULL == session_data->memory_lock)
++      {
++              mali_descriptor_mapping_destroy(session_data->descriptor_mapping);
++              _mali_osk_free(session_data);
++              MALI_ERROR(_MALI_OSK_ERR_FAULT);
++      }
++
++      /* Init the session's memory allocation list */
++      _MALI_OSK_INIT_LIST_HEAD( &session_data->memory_head );
++
++      MALI_DEBUG_PRINT(5, ("MMU session begin: success\n"));
++      MALI_SUCCESS;
++}
++
++static void descriptor_table_cleanup_callback(int descriptor_id, void* map_target)
++{
++      mali_memory_allocation * descriptor;
++
++      descriptor = (mali_memory_allocation*)map_target;
++
++      MALI_DEBUG_PRINT(3, ("Cleanup of descriptor %d mapping to 0x%x in descriptor table\n", descriptor_id, map_target));
++      MALI_DEBUG_ASSERT(descriptor);
++
++      mali_allocation_engine_release_memory(memory_engine, descriptor);
++      _mali_osk_free(descriptor);
++}
++
++void mali_memory_session_end(struct mali_session_data *session_data)
++{
++      _mali_osk_errcode_t err = _MALI_OSK_ERR_BUSY;
++
++      MALI_DEBUG_PRINT(3, ("MMU session end\n"));
++
++      if (NULL == session_data)
++      {
++              MALI_DEBUG_PRINT(1, ("No session data found during session end\n"));
++              return;
++      }
++
++      while (err == _MALI_OSK_ERR_BUSY)
++      {
++              /* Lock the session so we can modify the memory list */
++              _mali_osk_lock_wait( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW );
++              err = _MALI_OSK_ERR_OK;
++
++              /* Free all memory engine allocations */
++              if (!_mali_osk_list_empty(&session_data->memory_head))
++              {
++                      mali_memory_allocation *descriptor;
++                      mali_memory_allocation *temp;
++                      _mali_uk_mem_munmap_s unmap_args;
++
++                      MALI_DEBUG_PRINT(1, ("Memory found on session usage list during session termination\n"));
++
++                      unmap_args.ctx = session_data;
++
++                      /* use the 'safe' list iterator, since freeing removes the active block from the list we're iterating */
++                      _MALI_OSK_LIST_FOREACHENTRY(descriptor, temp, &session_data->memory_head, mali_memory_allocation, list)
++                      {
++                              MALI_DEBUG_PRINT(4, ("Freeing block with mali address 0x%x size %d mapped in user space at 0x%x\n",
++                                                      descriptor->mali_address, descriptor->size, descriptor->size, descriptor->mapping)
++                                              );
++                              /* ASSERT that the descriptor's lock references the correct thing */
++                              MALI_DEBUG_ASSERT(  descriptor->lock == session_data->memory_lock );
++                              /* Therefore, we have already locked the descriptor */
++
++                              unmap_args.size = descriptor->size;
++                              unmap_args.mapping = descriptor->mapping;
++                              unmap_args.cookie = (u32)descriptor;
++
++                              /*
++                                      * This removes the descriptor from the list, and frees the descriptor
++                                      *
++                                      * Does not handle the _MALI_OSK_SPECIFIC_INDIRECT_MMAP case, since
++                                      * the only OS we are aware of that requires indirect MMAP also has
++                                      * implicit mmap cleanup.
++                                      */
++                              err = _mali_ukk_mem_munmap_internal( &unmap_args );
++
++                              if (err == _MALI_OSK_ERR_BUSY)
++                              {
++                                      _mali_osk_lock_signal( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW );
++                                      /*
++                                              * Reason for this;
++                                              * We where unable to stall the MMU, probably because we are in page fault handling.
++                                              * Sleep for a while with the session lock released, then try again.
++                                              * Abnormal termination of programs with running Mali jobs is a normal reason for this.
++                                              */
++                                      _mali_osk_time_ubusydelay(10);
++                                      break; /* Will jump back into: "while (err == _MALI_OSK_ERR_BUSY)" */
++                              }
++                      }
++              }
++      }
++      /* Assert that we really did free everything */
++      MALI_DEBUG_ASSERT( _mali_osk_list_empty(&session_data->memory_head) );
++
++      if (NULL != session_data->descriptor_mapping)
++      {
++              mali_descriptor_mapping_call_for_each(session_data->descriptor_mapping, descriptor_table_cleanup_callback);
++              mali_descriptor_mapping_destroy(session_data->descriptor_mapping);
++              session_data->descriptor_mapping = NULL;
++      }
++
++      _mali_osk_lock_signal( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW );
++
++      /**
++       * @note Could the VMA close handler mean that we use the session data after it was freed?
++       * In which case, would need to refcount the session data, and free on VMA close
++       */
++
++      /* Free the lock */
++      _mali_osk_lock_term( session_data->memory_lock );
++
++      return;
++}
++
++_mali_osk_errcode_t mali_memory_core_resource_os_memory(u32 size)
++{
++      mali_physical_memory_allocator * allocator;
++      mali_physical_memory_allocator ** next_allocator_list;
++
++      u32 alloc_order = 1; /* OS memory has second priority */
++
++      allocator = mali_os_allocator_create(size, 0 /* cpu_usage_adjust */, "Shared Mali GPU memory");
++      if (NULL == allocator)
++      {
++              MALI_DEBUG_PRINT(1, ("Failed to create OS memory allocator\n"));
++              MALI_ERROR(_MALI_OSK_ERR_FAULT);
++      }
++
++      allocator->alloc_order = alloc_order;
++
++      /* link in the allocator: insertion into ordered list
++       * resources of the same alloc_order will be Last-in-first */
++      next_allocator_list = &physical_memory_allocators;
++
++      while (NULL != *next_allocator_list &&
++                      (*next_allocator_list)->alloc_order < alloc_order )
++      {
++              next_allocator_list = &((*next_allocator_list)->next);
++      }
++
++      allocator->next = (*next_allocator_list);
++      (*next_allocator_list) = allocator;
++
++      MALI_SUCCESS;
++}
++
++_mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(u32 start, u32 size)
++{
++      mali_physical_memory_allocator * allocator;
++      mali_physical_memory_allocator ** next_allocator_list;
++      dedicated_memory_info * cleanup_data;
++
++      u32 alloc_order = 0; /* Dedicated range has first priority */
++
++      /* do the low level linux operation first */
++
++      /* Request ownership of the memory */
++      if (_MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(start, size, "Dedicated Mali GPU memory"))
++      {
++              MALI_DEBUG_PRINT(1, ("Failed to request memory region for frame buffer (0x%08X - 0x%08X)\n", start, start + size - 1));
++              MALI_ERROR(_MALI_OSK_ERR_FAULT);
++      }
++
++      /* create generic block allocator object to handle it */
++      allocator = mali_block_allocator_create(start, 0 /* cpu_usage_adjust */, size, "Dedicated Mali GPU memory");
++
++      if (NULL == allocator)
++      {
++              MALI_DEBUG_PRINT(1, ("Memory bank registration failed\n"));
++              _mali_osk_mem_unreqregion(start, size);
++              MALI_ERROR(_MALI_OSK_ERR_FAULT);
++      }
++
++      /* save low level cleanup info */
++      allocator->alloc_order = alloc_order;
++
++      cleanup_data = _mali_osk_malloc(sizeof(dedicated_memory_info));
++
++      if (NULL == cleanup_data)
++      {
++              _mali_osk_mem_unreqregion(start, size);
++              allocator->destroy(allocator);
++              MALI_ERROR(_MALI_OSK_ERR_FAULT);
++      }
++
++      cleanup_data->base = start;
++      cleanup_data->size = size;
++
++      cleanup_data->next = mem_region_registrations;
++      mem_region_registrations = cleanup_data;
++
++      /* link in the allocator: insertion into ordered list
++       * resources of the same alloc_order will be Last-in-first */
++      next_allocator_list = &physical_memory_allocators;
++
++      while ( NULL != *next_allocator_list &&
++                      (*next_allocator_list)->alloc_order < alloc_order )
++      {
++              next_allocator_list = &((*next_allocator_list)->next);
++      }
++
++      allocator->next = (*next_allocator_list);
++      (*next_allocator_list) = allocator;
++
++      MALI_SUCCESS;
++}
++
++#if defined(CONFIG_MALI400_UMP)
++static mali_physical_memory_allocation_result ump_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info)
++{
++      ump_dd_handle ump_mem;
++      u32 nr_blocks;
++      u32 i;
++      ump_dd_physical_block * ump_blocks;
++      ump_mem_allocation *ret_allocation;
++
++      MALI_DEBUG_ASSERT_POINTER(ctx);
++      MALI_DEBUG_ASSERT_POINTER(engine);
++      MALI_DEBUG_ASSERT_POINTER(descriptor);
++      MALI_DEBUG_ASSERT_POINTER(alloc_info);
++
++      ret_allocation = _mali_osk_malloc( sizeof( ump_mem_allocation ) );
++      if ( NULL==ret_allocation ) return MALI_MEM_ALLOC_INTERNAL_FAILURE;
++
++      ump_mem = (ump_dd_handle)ctx;
++
++      MALI_DEBUG_PRINT(4, ("In ump_memory_commit\n"));
++
++      nr_blocks = ump_dd_phys_block_count_get(ump_mem);
++
++      MALI_DEBUG_PRINT(4, ("Have %d blocks\n", nr_blocks));
++
++      if (nr_blocks == 0)
++      {
++              MALI_DEBUG_PRINT(1, ("No block count\n"));
++              _mali_osk_free( ret_allocation );
++              return MALI_MEM_ALLOC_INTERNAL_FAILURE;
++      }
++
++      ump_blocks = _mali_osk_malloc(sizeof(*ump_blocks)*nr_blocks );
++      if ( NULL==ump_blocks )
++      {
++              _mali_osk_free( ret_allocation );
++              return MALI_MEM_ALLOC_INTERNAL_FAILURE;
++      }
++
++      if (UMP_DD_INVALID == ump_dd_phys_blocks_get(ump_mem, ump_blocks, nr_blocks))
++      {
++              _mali_osk_free(ump_blocks);
++              _mali_osk_free( ret_allocation );
++              return MALI_MEM_ALLOC_INTERNAL_FAILURE;
++      }
++
++      /* Store away the initial offset for unmapping purposes */
++      ret_allocation->initial_offset = *offset;
++
++      for(i=0; i<nr_blocks; ++i)
++      {
++              MALI_DEBUG_PRINT(4, ("Mapping in 0x%08x size %d\n", ump_blocks[i].addr , ump_blocks[i].size));
++              if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, ump_blocks[i].addr , 0, ump_blocks[i].size ))
++              {
++                      u32 size_allocated = *offset - ret_allocation->initial_offset;
++                      MALI_DEBUG_PRINT(1, ("Mapping of external memory failed\n"));
++
++                      /* unmap all previous blocks (if any) */
++                      mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->initial_offset, size_allocated, (_mali_osk_mem_mapregion_flags_t)0 );
++
++                      _mali_osk_free(ump_blocks);
++                      _mali_osk_free(ret_allocation);
++                      return MALI_MEM_ALLOC_INTERNAL_FAILURE;
++              }
++              *offset += ump_blocks[i].size;
++      }
++
++      if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE)
++      {
++              /* Map in an extra virtual guard page at the end of the VMA */
++              MALI_DEBUG_PRINT(4, ("Mapping in extra guard page\n"));
++              if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, ump_blocks[0].addr , 0, _MALI_OSK_MALI_PAGE_SIZE ))
++              {
++                      u32 size_allocated = *offset - ret_allocation->initial_offset;
++                      MALI_DEBUG_PRINT(1, ("Mapping of external memory (guard page) failed\n"));
++
++                      /* unmap all previous blocks (if any) */
++                      mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->initial_offset, size_allocated, (_mali_osk_mem_mapregion_flags_t)0 );
++
++                      _mali_osk_free(ump_blocks);
++                      _mali_osk_free(ret_allocation);
++                      return MALI_MEM_ALLOC_INTERNAL_FAILURE;
++              }
++              *offset += _MALI_OSK_MALI_PAGE_SIZE;
++      }
++
++      _mali_osk_free( ump_blocks );
++
++      ret_allocation->engine = engine;
++      ret_allocation->descriptor = descriptor;
++      ret_allocation->ump_mem = ump_mem;
++      ret_allocation->size_allocated = *offset - ret_allocation->initial_offset;
++
++      alloc_info->ctx = NULL;
++      alloc_info->handle = ret_allocation;
++      alloc_info->next = NULL;
++      alloc_info->release = ump_memory_release;
++
++      return MALI_MEM_ALLOC_FINISHED;
++}
++
++static void ump_memory_release(void * ctx, void * handle)
++{
++      ump_dd_handle ump_mem;
++      ump_mem_allocation *allocation;
++
++      allocation = (ump_mem_allocation *)handle;
++
++      MALI_DEBUG_ASSERT_POINTER( allocation );
++
++      ump_mem = allocation->ump_mem;
++
++      MALI_DEBUG_ASSERT(UMP_DD_HANDLE_INVALID!=ump_mem);
++
++      /* At present, this is a no-op. But, it allows the mali_address_manager to
++       * do unmapping of a subrange in future. */
++      mali_allocation_engine_unmap_physical( allocation->engine,
++                                                                                 allocation->descriptor,
++                                                                                 allocation->initial_offset,
++                                                                                 allocation->size_allocated,
++                                                                                 (_mali_osk_mem_mapregion_flags_t)0
++                                                                                 );
++      _mali_osk_free( allocation );
++
++
++      ump_dd_reference_release(ump_mem) ;
++      return;
++}
++
++_mali_osk_errcode_t _mali_ukk_attach_ump_mem( _mali_uk_attach_ump_mem_s *args )
++{
++      ump_dd_handle ump_mem;
++      mali_physical_memory_allocator external_memory_allocator;
++      struct mali_session_data *session_data;
++      mali_memory_allocation * descriptor;
++      int md;
++
++      MALI_DEBUG_ASSERT_POINTER(args);
++      MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
++
++      session_data = (struct mali_session_data *)args->ctx;
++      MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS);
++
++      /* check arguments */
++      /* NULL might be a valid Mali address */
++      if ( ! args->size) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
++
++      /* size must be a multiple of the system page size */
++      if ( args->size % _MALI_OSK_MALI_PAGE_SIZE ) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
++
++      MALI_DEBUG_PRINT(3,
++                       ("Requested to map ump memory with secure id %d into virtual memory 0x%08X, size 0x%08X\n",
++                        args->secure_id, args->mali_address, args->size));
++
++      ump_mem = ump_dd_handle_create_from_secure_id( (int)args->secure_id ) ;
++
++      if ( UMP_DD_HANDLE_INVALID==ump_mem ) MALI_ERROR(_MALI_OSK_ERR_FAULT);
++
++      descriptor = _mali_osk_calloc(1, sizeof(mali_memory_allocation));
++      if (NULL == descriptor)
++      {
++              ump_dd_reference_release(ump_mem);
++              MALI_ERROR(_MALI_OSK_ERR_NOMEM);
++      }
++
++      descriptor->size = args->size;
++      descriptor->mapping = NULL;
++      descriptor->mali_address = args->mali_address;
++      descriptor->mali_addr_mapping_info = (void*)session_data;
++      descriptor->process_addr_mapping_info = NULL; /* do not map to process address space */
++      descriptor->cache_settings = (u32) MALI_CACHE_STANDARD;
++      descriptor->lock = session_data->memory_lock;
++
++      if (args->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE)
++      {
++              descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE;
++      }
++      _mali_osk_list_init( &descriptor->list );
++
++      if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session_data->descriptor_mapping, descriptor, &md))
++      {
++              ump_dd_reference_release(ump_mem);
++              _mali_osk_free(descriptor);
++              MALI_ERROR(_MALI_OSK_ERR_FAULT);
++      }
++
++      external_memory_allocator.allocate = ump_memory_commit;
++      external_memory_allocator.allocate_page_table_block = NULL;
++      external_memory_allocator.ctx = ump_mem;
++      external_memory_allocator.name = "UMP Memory";
++      external_memory_allocator.next = NULL;
++
++      _mali_osk_lock_wait(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW);
++
++      if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_memory(memory_engine, descriptor, &external_memory_allocator, NULL))
++      {
++              _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW);
++              mali_descriptor_mapping_free(session_data->descriptor_mapping, md);
++              ump_dd_reference_release(ump_mem);
++              _mali_osk_free(descriptor);
++              MALI_ERROR(_MALI_OSK_ERR_NOMEM);
++      }
++
++      _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW);
++
++      args->cookie = md;
++
++      MALI_DEBUG_PRINT(5,("Returning from UMP attach\n"));
++
++      /* All OK */
++      MALI_SUCCESS;
++}
++
++
++_mali_osk_errcode_t _mali_ukk_release_ump_mem( _mali_uk_release_ump_mem_s *args )
++{
++      mali_memory_allocation * descriptor;
++      struct mali_session_data *session_data;
++
++      MALI_DEBUG_ASSERT_POINTER(args);
++      MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
++
++      session_data = (struct mali_session_data *)args->ctx;
++      MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS);
++
++      if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_get(session_data->descriptor_mapping, args->cookie, (void**)&descriptor))
++      {
++              MALI_DEBUG_PRINT(1, ("Invalid memory descriptor %d used to release ump memory\n", args->cookie));
++              MALI_ERROR(_MALI_OSK_ERR_FAULT);
++      }
++
++      descriptor = mali_descriptor_mapping_free(session_data->descriptor_mapping, args->cookie);
++
++      if (NULL != descriptor)
++      {
++              _mali_osk_lock_wait( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW );
++
++              mali_allocation_engine_release_memory(memory_engine, descriptor);
++
++              _mali_osk_lock_signal( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW );
++
++              _mali_osk_free(descriptor);
++      }
++
++      MALI_SUCCESS;
++
++}
++#endif /* CONFIG_MALI400_UMP */
++
++
++static mali_physical_memory_allocation_result external_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info)
++{
++      u32 * data;
++      external_mem_allocation * ret_allocation;
++
++      MALI_DEBUG_ASSERT_POINTER(ctx);
++      MALI_DEBUG_ASSERT_POINTER(engine);
++      MALI_DEBUG_ASSERT_POINTER(descriptor);
++      MALI_DEBUG_ASSERT_POINTER(alloc_info);
++
++      ret_allocation = _mali_osk_malloc( sizeof(external_mem_allocation) );
++
++      if ( NULL == ret_allocation )
++      {
++              return MALI_MEM_ALLOC_INTERNAL_FAILURE;
++      }
++
++      data = (u32*)ctx;
++
++      ret_allocation->engine = engine;
++      ret_allocation->descriptor = descriptor;
++      ret_allocation->initial_offset = *offset;
++
++      alloc_info->ctx = NULL;
++      alloc_info->handle = ret_allocation;
++      alloc_info->next = NULL;
++      alloc_info->release = external_memory_release;
++
++      MALI_DEBUG_PRINT(5, ("External map: mapping phys 0x%08X at mali virtual address 0x%08X staring at offset 0x%08X length 0x%08X\n", data[0], descriptor->mali_address, *offset, data[1]));
++
++      if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, data[0], 0, data[1]))
++      {
++              MALI_DEBUG_PRINT(1, ("Mapping of external memory failed\n"));
++              _mali_osk_free(ret_allocation);
++              return MALI_MEM_ALLOC_INTERNAL_FAILURE;
++      }
++      *offset += data[1];
++
++      if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE)
++      {
++              /* Map in an extra virtual guard page at the end of the VMA */
++              MALI_DEBUG_PRINT(4, ("Mapping in extra guard page\n"));
++              if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, data[0], 0, _MALI_OSK_MALI_PAGE_SIZE))
++              {
++                      u32 size_allocated = *offset - ret_allocation->initial_offset;
++                      MALI_DEBUG_PRINT(1, ("Mapping of external memory (guard page) failed\n"));
++
++                      /* unmap what we previously mapped */
++                      mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->initial_offset, size_allocated, (_mali_osk_mem_mapregion_flags_t)0 );
++                      _mali_osk_free(ret_allocation);
++                      return MALI_MEM_ALLOC_INTERNAL_FAILURE;
++              }
++              *offset += _MALI_OSK_MALI_PAGE_SIZE;
++      }
++
++      ret_allocation->size = *offset - ret_allocation->initial_offset;
++
++      return MALI_MEM_ALLOC_FINISHED;
++}
++
++static void external_memory_release(void * ctx, void * handle)
++{
++      external_mem_allocation * allocation;
++
++      allocation = (external_mem_allocation *) handle;
++      MALI_DEBUG_ASSERT_POINTER( allocation );
++
++      /* At present, this is a no-op. But, it allows the mali_address_manager to
++       * do unmapping of a subrange in future. */
++
++      mali_allocation_engine_unmap_physical( allocation->engine,
++                                                                                 allocation->descriptor,
++                                                                                 allocation->initial_offset,
++                                                                                 allocation->size,
++                                                                                 (_mali_osk_mem_mapregion_flags_t)0
++                                                                                 );
++
++      _mali_osk_free( allocation );
++
++      return;
++}
++
++_mali_osk_errcode_t _mali_ukk_map_external_mem( _mali_uk_map_external_mem_s *args )
++{
++      mali_physical_memory_allocator external_memory_allocator;
++      struct mali_session_data *session_data;
++      u32 info[2];
++      mali_memory_allocation * descriptor;
++      int md;
++
++      MALI_DEBUG_ASSERT_POINTER(args);
++      MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
++
++      session_data = (struct mali_session_data *)args->ctx;
++      MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS);
++
++      external_memory_allocator.allocate = external_memory_commit;
++      external_memory_allocator.allocate_page_table_block = NULL;
++      external_memory_allocator.ctx = &info[0];
++      external_memory_allocator.name = "External Memory";
++      external_memory_allocator.next = NULL;
++
++      /* check arguments */
++      /* NULL might be a valid Mali address */
++      if ( ! args->size) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
++
++      /* size must be a multiple of the system page size */
++      if ( args->size % _MALI_OSK_MALI_PAGE_SIZE ) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
++
++      MALI_DEBUG_PRINT(3,
++              ("Requested to map physical memory 0x%x-0x%x into virtual memory 0x%x\n",
++              (void*)args->phys_addr,
++              (void*)(args->phys_addr + args->size -1),
++              (void*)args->mali_address)
++      );
++
++      /* Validate the mali physical range */
++      if (_MALI_OSK_ERR_OK != mali_mem_validation_check(args->phys_addr, args->size))
++      {
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      info[0] = args->phys_addr;
++      info[1] = args->size;
++
++      descriptor = _mali_osk_calloc(1, sizeof(mali_memory_allocation));
++      if (NULL == descriptor) MALI_ERROR(_MALI_OSK_ERR_NOMEM);
++
++      descriptor->size = args->size;
++      descriptor->mapping = NULL;
++      descriptor->mali_address = args->mali_address;
++      descriptor->mali_addr_mapping_info = (void*)session_data;
++      descriptor->process_addr_mapping_info = NULL; /* do not map to process address space */
++      descriptor->cache_settings = (u32)MALI_CACHE_STANDARD;
++      descriptor->lock = session_data->memory_lock;
++      if (args->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE)
++      {
++              descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE;
++      }
++      _mali_osk_list_init( &descriptor->list );
++
++      _mali_osk_lock_wait(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW);
++
++      if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_memory(memory_engine, descriptor, &external_memory_allocator, NULL))
++      {
++              _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW);
++              _mali_osk_free(descriptor);
++              MALI_ERROR(_MALI_OSK_ERR_NOMEM);
++      }
++
++      _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW);
++
++      if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session_data->descriptor_mapping, descriptor, &md))
++      {
++              mali_allocation_engine_release_memory(memory_engine, descriptor);
++              _mali_osk_free(descriptor);
++              MALI_ERROR(_MALI_OSK_ERR_FAULT);
++      }
++
++      args->cookie = md;
++
++      MALI_DEBUG_PRINT(5,("Returning from range_map_external_memory\n"));
++
++      /* All OK */
++      MALI_SUCCESS;
++}
++
++
++_mali_osk_errcode_t _mali_ukk_unmap_external_mem( _mali_uk_unmap_external_mem_s *args )
++{
++      mali_memory_allocation * descriptor;
++      void* old_value;
++      struct mali_session_data *session_data;
++
++      MALI_DEBUG_ASSERT_POINTER(args);
++      MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
++
++      session_data = (struct mali_session_data *)args->ctx;
++      MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS);
++
++      if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_get(session_data->descriptor_mapping, args->cookie, (void**)&descriptor))
++      {
++              MALI_DEBUG_PRINT(1, ("Invalid memory descriptor %d used to unmap external memory\n", args->cookie));
++              MALI_ERROR(_MALI_OSK_ERR_FAULT);
++      }
++
++      old_value = mali_descriptor_mapping_free(session_data->descriptor_mapping, args->cookie);
++
++      if (NULL != old_value)
++      {
++              _mali_osk_lock_wait( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW );
++
++              mali_allocation_engine_release_memory(memory_engine, descriptor);
++
++              _mali_osk_lock_signal( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW );
++
++              _mali_osk_free(descriptor);
++      }
++
++      MALI_SUCCESS;
++}
++
++_mali_osk_errcode_t _mali_ukk_init_mem( _mali_uk_init_mem_s *args )
++{
++      MALI_DEBUG_ASSERT_POINTER(args);
++      MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
++
++      args->memory_size = 2 * 1024 * 1024 * 1024UL; /* 2GB address space */
++      args->mali_address_base = 1 * 1024 * 1024 * 1024UL; /* staring at 1GB, causing this layout: (0-1GB unused)(1GB-3G usage by Mali)(3G-4G unused) */
++      MALI_SUCCESS;
++}
++
++_mali_osk_errcode_t _mali_ukk_term_mem( _mali_uk_term_mem_s *args )
++{
++      MALI_DEBUG_ASSERT_POINTER(args);
++      MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
++      MALI_SUCCESS;
++}
++
++static _mali_osk_errcode_t mali_address_manager_allocate(mali_memory_allocation * descriptor)
++{
++      struct mali_session_data *session_data;
++      u32 actual_size;
++
++      MALI_DEBUG_ASSERT_POINTER(descriptor);
++
++      session_data = (struct mali_session_data *)descriptor->mali_addr_mapping_info;
++
++      actual_size = descriptor->size;
++
++      if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE)
++      {
++              actual_size += _MALI_OSK_MALI_PAGE_SIZE;
++      }
++
++      return mali_mmu_pagedir_map(session_data->page_directory, descriptor->mali_address, actual_size);
++}
++
++static void mali_address_manager_release(mali_memory_allocation * descriptor)
++{
++      const u32 illegal_mali_address = 0xffffffff;
++      struct mali_session_data *session_data;
++      MALI_DEBUG_ASSERT_POINTER(descriptor);
++
++      /* It is allowed to call this function several times on the same descriptor.
++         When memory is released we set the illegal_mali_address so we can early out here. */
++      if ( illegal_mali_address == descriptor->mali_address) return;
++
++      session_data = (struct mali_session_data *)descriptor->mali_addr_mapping_info;
++      mali_mmu_pagedir_unmap(session_data->page_directory, descriptor->mali_address, descriptor->size);
++
++      descriptor->mali_address = illegal_mali_address ;
++}
++
++static _mali_osk_errcode_t mali_address_manager_map(mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size)
++{
++      struct mali_session_data *session_data;
++      u32 mali_address;
++
++      MALI_DEBUG_ASSERT_POINTER(descriptor);
++      MALI_DEBUG_ASSERT_POINTER(phys_addr);
++
++      session_data = (struct mali_session_data *)descriptor->mali_addr_mapping_info;
++      MALI_DEBUG_ASSERT_POINTER(session_data);
++
++      mali_address = descriptor->mali_address + offset;
++
++      MALI_DEBUG_PRINT(7, ("Mali map: mapping 0x%08X to Mali address 0x%08X length 0x%08X\n", *phys_addr, mali_address, size));
++
++      mali_mmu_pagedir_update(session_data->page_directory, mali_address, *phys_addr, size, descriptor->cache_settings);
++
++      MALI_SUCCESS;
++}
++
++/* This handler registered to mali_mmap for MMU builds */
++_mali_osk_errcode_t _mali_ukk_mem_mmap( _mali_uk_mem_mmap_s *args )
++{
++      struct mali_session_data *session_data;
++      mali_memory_allocation * descriptor;
++
++      /* validate input */
++      if (NULL == args) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: args was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); }
++
++      /* Unpack arguments */
++      session_data = (struct mali_session_data *)args->ctx;
++
++      /* validate input */
++      if (NULL == session_data) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: session data was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_FAULT); }
++
++      descriptor = (mali_memory_allocation*) _mali_osk_calloc( 1, sizeof(mali_memory_allocation) );
++      if (NULL == descriptor) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: descriptor was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_NOMEM); }
++
++      descriptor->size = args->size;
++      descriptor->mali_address = args->phys_addr;
++      descriptor->mali_addr_mapping_info = (void*)session_data;
++
++      descriptor->process_addr_mapping_info = args->ukk_private; /* save to be used during physical manager callback */
++      descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE;
++      descriptor->cache_settings = (u32) args->cache_settings ;
++      descriptor->lock = session_data->memory_lock;
++      _mali_osk_list_init( &descriptor->list );
++
++      _mali_osk_lock_wait(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW);
++
++      if (0 == mali_allocation_engine_allocate_memory(memory_engine, descriptor, physical_memory_allocators, &session_data->memory_head))
++      {
++              /* We do not FLUSH nor TLB_ZAP on MMAP, since we do both of those on job start*/
++              _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW);
++
++              args->mapping = descriptor->mapping;
++              args->cookie = (u32)descriptor;
++
++              MALI_DEBUG_PRINT(7, ("MMAP OK\n"));
++              MALI_SUCCESS;
++      }
++      else
++      {
++              _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW);
++              /* OOM, but not a fatal error */
++              MALI_DEBUG_PRINT(4, ("Memory allocation failure, OOM\n"));
++              _mali_osk_free(descriptor);
++              /* Linux will free the CPU address allocation, userspace client the Mali address allocation */
++              MALI_ERROR(_MALI_OSK_ERR_FAULT);
++      }
++}
++
++static _mali_osk_errcode_t _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args )
++{
++      struct mali_session_data *session_data;
++      mali_memory_allocation * descriptor;
++
++      descriptor = (mali_memory_allocation *)args->cookie;
++      MALI_DEBUG_ASSERT_POINTER(descriptor);
++
++      /** @note args->context unused; we use the memory_session from the cookie */
++      /* args->mapping and args->size are also discarded. They are only necessary
++         for certain do_munmap implementations. However, they could be used to check the
++         descriptor at this point. */
++
++      session_data = (struct mali_session_data *)descriptor->mali_addr_mapping_info;
++      MALI_DEBUG_ASSERT_POINTER(session_data);
++
++      /* Unmapping the memory from the mali virtual address space.
++         It is allowed to call this function severeal times, which might happen if zapping below fails. */
++      mali_allocation_engine_release_pt1_mali_pagetables_unmap(memory_engine, descriptor);
++
++#ifdef MALI_UNMAP_FLUSH_ALL_MALI_L2
++      {
++              u32 i;
++              u32 number_of_l2_ccores = mali_l2_cache_core_get_glob_num_l2_cores();
++              for (i = 0; i < number_of_l2_ccores; i++)
++              {
++                      struct mali_l2_cache_core *core;
++                      core = mali_l2_cache_core_get_glob_l2_core(i);
++                      if (mali_l2_cache_power_is_enabled_get(core) )
++                      {
++                              mali_l2_cache_invalidate_all_force(core);
++                      }
++              }
++      }
++#endif
++
++      mali_scheduler_zap_all_active(session_data);
++
++      /* Removes the descriptor from the session's memory list, releases physical memory, releases descriptor */
++      mali_allocation_engine_release_pt2_physical_memory_free(memory_engine, descriptor);
++
++      _mali_osk_free(descriptor);
++
++      return _MALI_OSK_ERR_OK;
++}
++
++/* Handler for unmapping memory for MMU builds */
++_mali_osk_errcode_t _mali_ukk_mem_munmap( _mali_uk_mem_munmap_s *args )
++{
++      mali_memory_allocation * descriptor;
++      _mali_osk_lock_t *descriptor_lock;
++      _mali_osk_errcode_t err;
++
++      descriptor = (mali_memory_allocation *)args->cookie;
++      MALI_DEBUG_ASSERT_POINTER(descriptor);
++
++      /** @note args->context unused; we use the memory_session from the cookie */
++      /* args->mapping and args->size are also discarded. They are only necessary
++      for certain do_munmap implementations. However, they could be used to check the
++      descriptor at this point. */
++
++      MALI_DEBUG_ASSERT_POINTER((struct mali_session_data *)descriptor->mali_addr_mapping_info);
++
++      descriptor_lock = descriptor->lock; /* should point to the session data lock... */
++
++      err = _MALI_OSK_ERR_BUSY;
++      while (err == _MALI_OSK_ERR_BUSY)
++      {
++              if (descriptor_lock)
++              {
++                      _mali_osk_lock_wait( descriptor_lock, _MALI_OSK_LOCKMODE_RW );
++              }
++
++              err = _mali_ukk_mem_munmap_internal( args );
++
++              if (descriptor_lock)
++              {
++                      _mali_osk_lock_signal( descriptor_lock, _MALI_OSK_LOCKMODE_RW );
++              }
++
++              if (err == _MALI_OSK_ERR_BUSY)
++              {
++                      /*
++                       * Reason for this;
++                       * We where unable to stall the MMU, probably because we are in page fault handling.
++                       * Sleep for a while with the session lock released, then try again.
++                       * Abnormal termination of programs with running Mali jobs is a normal reason for this.
++                       */
++                      _mali_osk_time_ubusydelay(10);
++              }
++      }
++
++      return err;
++}
++
++u32 _mali_ukk_report_memory_usage(void)
++{
++      return mali_allocation_engine_memory_usage(physical_memory_allocators);
++}
++
++_mali_osk_errcode_t mali_mmu_get_table_page(u32 *table_page, mali_io_address *mapping)
++{
++      _mali_osk_lock_wait(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
++
++      if (!_mali_osk_list_empty(&page_table_cache.partial))
++      {
++              mali_mmu_page_table_allocation * alloc = _MALI_OSK_LIST_ENTRY(page_table_cache.partial.next, mali_mmu_page_table_allocation, list);
++              int page_number = _mali_osk_find_first_zero_bit(alloc->usage_map, alloc->num_pages);
++              MALI_DEBUG_PRINT(6, ("Partial page table allocation found, using page offset %d\n", page_number));
++              _mali_osk_set_nonatomic_bit(page_number, alloc->usage_map);
++              alloc->usage_count++;
++              if (alloc->num_pages == alloc->usage_count)
++              {
++                      /* full, move alloc to full list*/
++                      _mali_osk_list_move(&alloc->list, &page_table_cache.full);
++              }
++              _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
++
++              *table_page = (MALI_MMU_PAGE_SIZE * page_number) + alloc->pages.phys_base;
++              *mapping =  (mali_io_address)((MALI_MMU_PAGE_SIZE * page_number) + (u32)alloc->pages.mapping);
++              MALI_DEBUG_PRINT(4, ("Page table allocated for VA=0x%08X, MaliPA=0x%08X\n", *mapping, *table_page ));
++              MALI_SUCCESS;
++      }
++      else
++      {
++              mali_mmu_page_table_allocation * alloc;
++              /* no free pages, allocate a new one */
++
++              alloc = (mali_mmu_page_table_allocation *)_mali_osk_calloc(1, sizeof(mali_mmu_page_table_allocation));
++              if (NULL == alloc)
++              {
++                      _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
++                      *table_page = MALI_INVALID_PAGE;
++                      MALI_ERROR(_MALI_OSK_ERR_NOMEM);
++              }
++
++              _MALI_OSK_INIT_LIST_HEAD(&alloc->list);
++
++              if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_page_tables(memory_engine, &alloc->pages, physical_memory_allocators))
++              {
++                      MALI_DEBUG_PRINT(1, ("No more memory for page tables\n"));
++                      _mali_osk_free(alloc);
++                      _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
++                      *table_page = MALI_INVALID_PAGE;
++                      *mapping = NULL;
++                      MALI_ERROR(_MALI_OSK_ERR_NOMEM);
++              }
++
++              /* create the usage map */
++              alloc->num_pages = alloc->pages.size / MALI_MMU_PAGE_SIZE;
++              alloc->usage_count = 1;
++              MALI_DEBUG_PRINT(3, ("New page table cache expansion, %d pages in new cache allocation\n", alloc->num_pages));
++              alloc->usage_map = _mali_osk_calloc(1, ((alloc->num_pages + BITS_PER_LONG - 1) & ~(BITS_PER_LONG-1) / BITS_PER_LONG) * sizeof(unsigned long));
++              if (NULL == alloc->usage_map)
++              {
++                      MALI_DEBUG_PRINT(1, ("Failed to allocate memory to describe MMU page table cache usage\n"));
++                      alloc->pages.release(&alloc->pages);
++                      _mali_osk_free(alloc);
++                      _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
++                      *table_page = MALI_INVALID_PAGE;
++                      *mapping = NULL;
++                      MALI_ERROR(_MALI_OSK_ERR_NOMEM);
++              }
++
++              _mali_osk_set_nonatomic_bit(0, alloc->usage_map);
++
++              if (alloc->num_pages > 1)
++              {
++                      _mali_osk_list_add(&alloc->list, &page_table_cache.partial);
++              }
++              else
++              {
++                      _mali_osk_list_add(&alloc->list, &page_table_cache.full);
++              }
++
++              _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
++              *table_page = alloc->pages.phys_base; /* return the first page */
++              *mapping = alloc->pages.mapping; /* Mapping for first page */
++              MALI_DEBUG_PRINT(4, ("Page table allocated: VA=0x%08X, MaliPA=0x%08X\n", *mapping, *table_page ));
++              MALI_SUCCESS;
++      }
++}
++
++void mali_mmu_release_table_page(u32 pa)
++{
++      mali_mmu_page_table_allocation * alloc, * temp_alloc;
++
++      MALI_DEBUG_PRINT_IF(1, pa & 4095, ("Bad page address 0x%x given to mali_mmu_release_table_page\n", (void*)pa));
++
++      MALI_DEBUG_PRINT(4, ("Releasing table page 0x%08X to the cache\n", pa));
++
++      _mali_osk_lock_wait(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
++
++      /* find the entry this address belongs to */
++      /* first check the partial list */
++      _MALI_OSK_LIST_FOREACHENTRY(alloc, temp_alloc, &page_table_cache.partial, mali_mmu_page_table_allocation, list)
++      {
++              u32 start = alloc->pages.phys_base;
++              u32 last = start + (alloc->num_pages - 1) * MALI_MMU_PAGE_SIZE;
++              if (pa >= start && pa <= last)
++              {
++                      MALI_DEBUG_ASSERT(0 != _mali_osk_test_bit((pa - start)/MALI_MMU_PAGE_SIZE, alloc->usage_map));
++                      _mali_osk_clear_nonatomic_bit((pa - start)/MALI_MMU_PAGE_SIZE, alloc->usage_map);
++                      alloc->usage_count--;
++
++                      _mali_osk_memset((void*)( ((u32)alloc->pages.mapping) + (pa - start) ), 0, MALI_MMU_PAGE_SIZE);
++
++                      if (0 == alloc->usage_count)
++                      {
++                              /* empty, release whole page alloc */
++                              _mali_osk_list_del(&alloc->list);
++                              alloc->pages.release(&alloc->pages);
++                              _mali_osk_free(alloc->usage_map);
++                              _mali_osk_free(alloc);
++                      }
++                      _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
++                      MALI_DEBUG_PRINT(4, ("(partial list)Released table page 0x%08X to the cache\n", pa));
++                      return;
++              }
++      }
++
++      /* the check the full list */
++      _MALI_OSK_LIST_FOREACHENTRY(alloc, temp_alloc, &page_table_cache.full, mali_mmu_page_table_allocation, list)
++      {
++              u32 start = alloc->pages.phys_base;
++              u32 last = start + (alloc->num_pages - 1) * MALI_MMU_PAGE_SIZE;
++              if (pa >= start && pa <= last)
++              {
++                      _mali_osk_clear_nonatomic_bit((pa - start)/MALI_MMU_PAGE_SIZE, alloc->usage_map);
++                      alloc->usage_count--;
++
++                      _mali_osk_memset((void*)( ((u32)alloc->pages.mapping) + (pa - start) ), 0, MALI_MMU_PAGE_SIZE);
++
++
++                      if (0 == alloc->usage_count)
++                      {
++                              /* empty, release whole page alloc */
++                              _mali_osk_list_del(&alloc->list);
++                              alloc->pages.release(&alloc->pages);
++                              _mali_osk_free(alloc->usage_map);
++                              _mali_osk_free(alloc);
++                      }
++                      else
++                      {
++                              /* transfer to partial list */
++                              _mali_osk_list_move(&alloc->list, &page_table_cache.partial);
++                      }
++
++                      _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
++                      MALI_DEBUG_PRINT(4, ("(full list)Released table page 0x%08X to the cache\n", pa));
++                      return;
++              }
++      }
++
++      MALI_DEBUG_PRINT(1, ("pa 0x%x not found in the page table cache\n", (void*)pa));
++
++      _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
++}
++
++static _mali_osk_errcode_t mali_mmu_page_table_cache_create(void)
++{
++      page_table_cache.lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_ONELOCK
++                                  | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_MEM_PT_CACHE);
++      MALI_CHECK_NON_NULL( page_table_cache.lock, _MALI_OSK_ERR_FAULT );
++      _MALI_OSK_INIT_LIST_HEAD(&page_table_cache.partial);
++      _MALI_OSK_INIT_LIST_HEAD(&page_table_cache.full);
++      MALI_SUCCESS;
++}
++
++static void mali_mmu_page_table_cache_destroy(void)
++{
++      mali_mmu_page_table_allocation * alloc, *temp;
++
++      _MALI_OSK_LIST_FOREACHENTRY(alloc, temp, &page_table_cache.partial, mali_mmu_page_table_allocation, list)
++      {
++              MALI_DEBUG_PRINT_IF(1, 0 != alloc->usage_count, ("Destroying page table cache while pages are tagged as in use. %d allocations still marked as in use.\n", alloc->usage_count));
++              _mali_osk_list_del(&alloc->list);
++              alloc->pages.release(&alloc->pages);
++              _mali_osk_free(alloc->usage_map);
++              _mali_osk_free(alloc);
++      }
++
++      MALI_DEBUG_PRINT_IF(1, !_mali_osk_list_empty(&page_table_cache.full), ("Page table cache full list contains one or more elements \n"));
++
++      _MALI_OSK_LIST_FOREACHENTRY(alloc, temp, &page_table_cache.full, mali_mmu_page_table_allocation, list)
++      {
++              MALI_DEBUG_PRINT(1, ("Destroy alloc 0x%08X with usage count %d\n", (u32)alloc, alloc->usage_count));
++              _mali_osk_list_del(&alloc->list);
++              alloc->pages.release(&alloc->pages);
++              _mali_osk_free(alloc->usage_map);
++              _mali_osk_free(alloc);
++      }
++
++      _mali_osk_lock_term(page_table_cache.lock);
++}
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_memory.h b/drivers/gpu/arm/mali400/mali/common/mali_memory.h
+new file mode 100644
+index 0000000..d2cef59
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_memory.h
+@@ -0,0 +1,86 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_MEMORY_H__
++#define __MALI_MEMORY_H__
++
++#include "mali_osk.h"
++#include "mali_session.h"
++
++/** @brief Initialize Mali memory subsystem
++ *
++ * Allocate and initialize internal data structures. Must be called before
++ * allocating Mali memory.
++ *
++ * @return On success _MALI_OSK_ERR_OK, othervise some error code describing the error.
++ */
++_mali_osk_errcode_t mali_memory_initialize(void);
++
++/** @brief Terminate Mali memory system
++ *
++ * Clean up and release internal data structures.
++ */
++void mali_memory_terminate(void);
++
++/** @brief Start new Mali memory session
++ *
++ * Allocate and prepare session specific memory allocation data data. The
++ * session page directory, lock, and descriptor map is set up.
++ *
++ * @param mali_session_data pointer to the session data structure
++ */
++_mali_osk_errcode_t mali_memory_session_begin(struct mali_session_data *mali_session_data);
++
++/** @brief Close a Mali memory session
++ *
++ * Release session specific memory allocation related data.
++ *
++ * @param mali_session_data pointer to the session data structure
++ */
++void mali_memory_session_end(struct mali_session_data *mali_session_data);
++
++/** @brief Allocate a page table page
++ *
++ * Allocate a page for use as a page directory or page table. The page is
++ * mapped into kernel space.
++ *
++ * @return _MALI_OSK_ERR_OK on success, othervise an error code
++ * @param table_page GPU pointer to the allocated page
++ * @param mapping CPU pointer to the mapping of the allocated page
++ */
++_mali_osk_errcode_t mali_mmu_get_table_page(u32 *table_page, mali_io_address *mapping);
++
++/** @brief Release a page table page
++ *
++ * Release a page table page allocated through \a mali_mmu_get_table_page
++ *
++ * @param pa the GPU address of the page to release
++ */
++void mali_mmu_release_table_page(u32 pa);
++
++
++/** @brief Parse resource and prepare the OS memory allocator
++ *
++ * @param size Maximum size to allocate for Mali GPU.
++ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
++ */
++_mali_osk_errcode_t mali_memory_core_resource_os_memory(u32 size);
++
++/** @brief Parse resource and prepare the dedicated memory allocator
++ *
++ * @param start Physical start address of dedicated Mali GPU memory.
++ * @param size Size of dedicated Mali GPU memory.
++ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
++ */
++_mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(u32 start, u32 size);
++
++mali_allocation_engine mali_mem_get_memory_engine(void);
++
++#endif /* __MALI_MEMORY_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_mmu.c b/drivers/gpu/arm/mali400/mali/common/mali_mmu.c
+new file mode 100644
+index 0000000..382a17e
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_mmu.c
+@@ -0,0 +1,444 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_kernel_common.h"
++#include "mali_osk.h"
++#include "mali_osk_bitops.h"
++#include "mali_osk_list.h"
++#include "mali_ukk.h"
++
++#include "mali_mmu.h"
++#include "mali_hw_core.h"
++#include "mali_group.h"
++#include "mali_mmu_page_directory.h"
++
++/**
++ * Size of the MMU registers in bytes
++ */
++#define MALI_MMU_REGISTERS_SIZE 0x24
++
++/**
++ * MMU commands
++ * These are the commands that can be sent
++ * to the MMU unit.
++ */
++typedef enum mali_mmu_command
++{
++      MALI_MMU_COMMAND_ENABLE_PAGING = 0x00, /**< Enable paging (memory translation) */
++      MALI_MMU_COMMAND_DISABLE_PAGING = 0x01, /**< Disable paging (memory translation) */
++      MALI_MMU_COMMAND_ENABLE_STALL = 0x02, /**<  Enable stall on page fault */
++      MALI_MMU_COMMAND_DISABLE_STALL = 0x03, /**< Disable stall on page fault */
++      MALI_MMU_COMMAND_ZAP_CACHE = 0x04, /**< Zap the entire page table cache */
++      MALI_MMU_COMMAND_PAGE_FAULT_DONE = 0x05, /**< Page fault processed */
++      MALI_MMU_COMMAND_HARD_RESET = 0x06 /**< Reset the MMU back to power-on settings */
++} mali_mmu_command;
++
++static void mali_mmu_probe_trigger(void *data);
++static _mali_osk_errcode_t mali_mmu_probe_ack(void *data);
++
++MALI_STATIC_INLINE _mali_osk_errcode_t mali_mmu_raw_reset(struct mali_mmu_core *mmu);
++
++/* page fault queue flush helper pages
++ * note that the mapping pointers are currently unused outside of the initialization functions */
++static u32 mali_page_fault_flush_page_directory = MALI_INVALID_PAGE;
++static u32 mali_page_fault_flush_page_table = MALI_INVALID_PAGE;
++static u32 mali_page_fault_flush_data_page = MALI_INVALID_PAGE;
++
++/* an empty page directory (no address valid) which is active on any MMU not currently marked as in use */
++static u32 mali_empty_page_directory = MALI_INVALID_PAGE;
++
++_mali_osk_errcode_t mali_mmu_initialize(void)
++{
++      /* allocate the helper pages */
++      mali_empty_page_directory = mali_allocate_empty_page();
++      if(0 == mali_empty_page_directory)
++      {
++              mali_empty_page_directory = MALI_INVALID_PAGE;
++              return _MALI_OSK_ERR_NOMEM;
++      }
++
++      if (_MALI_OSK_ERR_OK != mali_create_fault_flush_pages(&mali_page_fault_flush_page_directory,
++                                      &mali_page_fault_flush_page_table, &mali_page_fault_flush_data_page))
++      {
++              mali_free_empty_page(mali_empty_page_directory);
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      return _MALI_OSK_ERR_OK;
++}
++
++void mali_mmu_terminate(void)
++{
++      MALI_DEBUG_PRINT(3, ("Mali MMU: terminating\n"));
++
++      /* Free global helper pages */
++      mali_free_empty_page(mali_empty_page_directory);
++
++      /* Free the page fault flush pages */
++      mali_destroy_fault_flush_pages(&mali_page_fault_flush_page_directory,
++                                  &mali_page_fault_flush_page_table, &mali_page_fault_flush_data_page);
++}
++
++struct mali_mmu_core *mali_mmu_create(_mali_osk_resource_t *resource, struct mali_group *group, mali_bool is_virtual)
++{
++      struct mali_mmu_core* mmu = NULL;
++
++      MALI_DEBUG_ASSERT_POINTER(resource);
++
++      MALI_DEBUG_PRINT(2, ("Mali MMU: Creating Mali MMU: %s\n", resource->description));
++
++      mmu = _mali_osk_calloc(1,sizeof(struct mali_mmu_core));
++      if (NULL != mmu)
++      {
++              if (_MALI_OSK_ERR_OK == mali_hw_core_create(&mmu->hw_core, resource, MALI_MMU_REGISTERS_SIZE))
++              {
++                      if (_MALI_OSK_ERR_OK == mali_group_add_mmu_core(group, mmu))
++                      {
++                              if (is_virtual)
++                              {
++                                      /* Skip reset and IRQ setup for virtual MMU */
++                                      return mmu;
++                              }
++
++                              if (_MALI_OSK_ERR_OK == mali_mmu_reset(mmu))
++                              {
++                                      /* Setup IRQ handlers (which will do IRQ probing if needed) */
++                                      mmu->irq = _mali_osk_irq_init(resource->irq,
++                                                                    mali_group_upper_half_mmu,
++                                                                    group,
++                                                                    mali_mmu_probe_trigger,
++                                                                    mali_mmu_probe_ack,
++                                                                    mmu,
++                                                                    "mali_mmu_irq_handlers");
++                                      if (NULL != mmu->irq)
++                                      {
++                                              return mmu;
++                                      }
++                                      else
++                                      {
++                                              MALI_PRINT_ERROR(("Mali MMU: Failed to setup interrupt handlers for MMU %s\n", mmu->hw_core.description));
++                                      }
++                              }
++                              mali_group_remove_mmu_core(group);
++                      }
++                      else
++                      {
++                              MALI_PRINT_ERROR(("Mali MMU: Failed to add core %s to group\n", mmu->hw_core.description));
++                      }
++                      mali_hw_core_delete(&mmu->hw_core);
++              }
++
++              _mali_osk_free(mmu);
++      }
++      else
++      {
++              MALI_PRINT_ERROR(("Failed to allocate memory for MMU\n"));
++      }
++
++      return NULL;
++}
++
++void mali_mmu_delete(struct mali_mmu_core *mmu)
++{
++      if (NULL != mmu->irq)
++      {
++              _mali_osk_irq_term(mmu->irq);
++      }
++
++      mali_hw_core_delete(&mmu->hw_core);
++      _mali_osk_free(mmu);
++}
++
++static void mali_mmu_enable_paging(struct mali_mmu_core *mmu)
++{
++      int i;
++
++      mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_PAGING);
++
++      for (i = 0; i < MALI_REG_POLL_COUNT_SLOW; ++i)
++      {
++              if (mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_PAGING_ENABLED)
++              {
++                      break;
++              }
++      }
++      if (MALI_REG_POLL_COUNT_SLOW == i)
++      {
++              MALI_PRINT_ERROR(("Enable paging request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS)));
++      }
++}
++
++mali_bool mali_mmu_enable_stall(struct mali_mmu_core *mmu)
++{
++      int i;
++      u32 mmu_status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS);
++
++      if ( 0 == (mmu_status & MALI_MMU_STATUS_BIT_PAGING_ENABLED) )
++      {
++              MALI_DEBUG_PRINT(4, ("MMU stall is implicit when Paging is not enebled.\n"));
++              return MALI_TRUE;
++      }
++
++      if ( mmu_status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE )
++      {
++              MALI_DEBUG_PRINT(3, ("Aborting MMU stall request since it is in pagefault state.\n"));
++              return MALI_FALSE;
++      }
++
++      mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_STALL);
++
++      for (i = 0; i < MALI_REG_POLL_COUNT_SLOW; ++i)
++      {
++              mmu_status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS);
++              if (mmu_status & (MALI_MMU_STATUS_BIT_STALL_ACTIVE|MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE) &&
++                  (0 == (mmu_status & MALI_MMU_STATUS_BIT_STALL_NOT_ACTIVE)))
++              {
++                      break;
++              }
++              if (0 == (mmu_status & ( MALI_MMU_STATUS_BIT_PAGING_ENABLED )))
++              {
++                      break;
++              }
++      }
++      if (MALI_REG_POLL_COUNT_SLOW == i)
++      {
++              MALI_PRINT_ERROR(("Enable stall request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS)));
++              return MALI_FALSE;
++      }
++
++      if ( mmu_status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE )
++      {
++              MALI_DEBUG_PRINT(3, ("Aborting MMU stall request since it has a pagefault.\n"));
++              return MALI_FALSE;
++      }
++
++      return MALI_TRUE;
++}
++
++void mali_mmu_disable_stall(struct mali_mmu_core *mmu)
++{
++      int i;
++      u32 mmu_status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS);
++
++      if ( 0 == (mmu_status & MALI_MMU_STATUS_BIT_PAGING_ENABLED ))
++      {
++              MALI_DEBUG_PRINT(3, ("MMU disable skipped since it was not enabled.\n"));
++              return;
++      }
++      if (mmu_status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE)
++      {
++              MALI_DEBUG_PRINT(2, ("Aborting MMU disable stall request since it is in pagefault state.\n"));
++              return;
++      }
++
++      mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_DISABLE_STALL);
++
++      for (i = 0; i < MALI_REG_POLL_COUNT_SLOW; ++i)
++      {
++              u32 status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS);
++              if ( 0 == (status & MALI_MMU_STATUS_BIT_STALL_ACTIVE) )
++              {
++                      break;
++              }
++              if ( status &  MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE )
++              {
++                      break;
++              }
++              if ( 0 == (mmu_status & MALI_MMU_STATUS_BIT_PAGING_ENABLED ))
++              {
++                      break;
++              }
++      }
++      if (MALI_REG_POLL_COUNT_SLOW == i) MALI_DEBUG_PRINT(1,("Disable stall request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS)));
++}
++
++void mali_mmu_page_fault_done(struct mali_mmu_core *mmu)
++{
++      MALI_DEBUG_PRINT(4, ("Mali MMU: %s: Leaving page fault mode\n", mmu->hw_core.description));
++      mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_PAGE_FAULT_DONE);
++}
++
++MALI_STATIC_INLINE _mali_osk_errcode_t mali_mmu_raw_reset(struct mali_mmu_core *mmu)
++{
++      int i;
++
++      mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR, 0xCAFEBABE);
++      mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_HARD_RESET);
++
++      for (i = 0; i < MALI_REG_POLL_COUNT_SLOW; ++i)
++      {
++              if (mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR) == 0)
++              {
++                      break;
++              }
++      }
++      if (MALI_REG_POLL_COUNT_SLOW == i)
++      {
++              MALI_PRINT_ERROR(("Reset request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS)));
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      return _MALI_OSK_ERR_OK;
++}
++
++_mali_osk_errcode_t mali_mmu_reset(struct mali_mmu_core *mmu)
++{
++      _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
++      mali_bool stall_success;
++      MALI_DEBUG_ASSERT_POINTER(mmu);
++
++      stall_success = mali_mmu_enable_stall(mmu);
++
++      /* The stall can not fail in current hw-state */
++      MALI_DEBUG_ASSERT(stall_success);
++
++      MALI_DEBUG_PRINT(3, ("Mali MMU: mali_kernel_mmu_reset: %s\n", mmu->hw_core.description));
++
++      if (_MALI_OSK_ERR_OK == mali_mmu_raw_reset(mmu))
++      {
++              mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK, MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR);
++              /* no session is active, so just activate the empty page directory */
++              mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR, mali_empty_page_directory);
++              mali_mmu_enable_paging(mmu);
++              err = _MALI_OSK_ERR_OK;
++      }
++      mali_mmu_disable_stall(mmu);
++
++      return err;
++}
++
++mali_bool mali_mmu_zap_tlb(struct mali_mmu_core *mmu)
++{
++      mali_bool stall_success = mali_mmu_enable_stall(mmu);
++
++      mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE);
++
++      if (MALI_FALSE == stall_success)
++      {
++              /* False means that it is in Pagefault state. Not possible to disable_stall then */
++              return MALI_FALSE;
++      }
++
++      mali_mmu_disable_stall(mmu);
++      return MALI_TRUE;
++}
++
++void mali_mmu_zap_tlb_without_stall(struct mali_mmu_core *mmu)
++{
++      mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE);
++}
++
++
++void mali_mmu_invalidate_page(struct mali_mmu_core *mmu, u32 mali_address)
++{
++      mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_ZAP_ONE_LINE, MALI_MMU_PDE_ENTRY(mali_address));
++}
++
++static void mali_mmu_activate_address_space(struct mali_mmu_core *mmu, u32 page_directory)
++{
++      /* The MMU must be in stalled or page fault mode, for this writing to work */
++      MALI_DEBUG_ASSERT( 0 != ( mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS)
++                        & (MALI_MMU_STATUS_BIT_STALL_ACTIVE|MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE) ) );
++      mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR, page_directory);
++      mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE);
++
++}
++
++mali_bool mali_mmu_activate_page_directory(struct mali_mmu_core *mmu, struct mali_page_directory *pagedir)
++{
++      mali_bool stall_success;
++      MALI_DEBUG_ASSERT_POINTER(mmu);
++
++      MALI_DEBUG_PRINT(5, ("Asked to activate page directory 0x%x on MMU %s\n", pagedir, mmu->hw_core.description));
++      stall_success = mali_mmu_enable_stall(mmu);
++
++      if ( MALI_FALSE==stall_success ) return MALI_FALSE;
++      mali_mmu_activate_address_space(mmu, pagedir->page_directory);
++      mali_mmu_disable_stall(mmu);
++      return MALI_TRUE;
++}
++
++void mali_mmu_activate_empty_page_directory(struct mali_mmu_core* mmu)
++{
++      mali_bool stall_success;
++
++      MALI_DEBUG_ASSERT_POINTER(mmu);
++      MALI_DEBUG_PRINT(3, ("Activating the empty page directory on MMU %s\n", mmu->hw_core.description));
++
++      stall_success = mali_mmu_enable_stall(mmu);
++      /* This function can only be called when the core is idle, so it could not fail. */
++      MALI_DEBUG_ASSERT( stall_success );
++      mali_mmu_activate_address_space(mmu, mali_empty_page_directory);
++      mali_mmu_disable_stall(mmu);
++}
++
++void mali_mmu_activate_fault_flush_page_directory(struct mali_mmu_core* mmu)
++{
++      mali_bool stall_success;
++      MALI_DEBUG_ASSERT_POINTER(mmu);
++
++      MALI_DEBUG_PRINT(3, ("Activating the page fault flush page directory on MMU %s\n", mmu->hw_core.description));
++      stall_success = mali_mmu_enable_stall(mmu);
++      /* This function is expect to fail the stalling, since it might be in PageFault mode when it is called */
++      mali_mmu_activate_address_space(mmu, mali_page_fault_flush_page_directory);
++      if ( MALI_TRUE==stall_success ) mali_mmu_disable_stall(mmu);
++}
++
++/* Is called when we want the mmu to give an interrupt */
++static void mali_mmu_probe_trigger(void *data)
++{
++      struct mali_mmu_core *mmu = (struct mali_mmu_core *)data;
++      mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_RAWSTAT, MALI_MMU_INTERRUPT_PAGE_FAULT|MALI_MMU_INTERRUPT_READ_BUS_ERROR);
++}
++
++/* Is called when the irq probe wants the mmu to acknowledge an interrupt from the hw */
++static _mali_osk_errcode_t mali_mmu_probe_ack(void *data)
++{
++      struct mali_mmu_core *mmu = (struct mali_mmu_core *)data;
++      u32 int_stat;
++
++      int_stat = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_STATUS);
++
++      MALI_DEBUG_PRINT(2, ("mali_mmu_probe_irq_acknowledge: intstat 0x%x\n", int_stat));
++      if (int_stat & MALI_MMU_INTERRUPT_PAGE_FAULT)
++      {
++              MALI_DEBUG_PRINT(2, ("Probe: Page fault detect: PASSED\n"));
++              mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_PAGE_FAULT);
++      }
++      else
++      {
++              MALI_DEBUG_PRINT(1, ("Probe: Page fault detect: FAILED\n"));
++      }
++
++      if (int_stat & MALI_MMU_INTERRUPT_READ_BUS_ERROR)
++      {
++              MALI_DEBUG_PRINT(2, ("Probe: Bus read error detect: PASSED\n"));
++              mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_READ_BUS_ERROR);
++      }
++      else
++      {
++              MALI_DEBUG_PRINT(1, ("Probe: Bus read error detect: FAILED\n"));
++      }
++
++      if ( (int_stat & (MALI_MMU_INTERRUPT_PAGE_FAULT|MALI_MMU_INTERRUPT_READ_BUS_ERROR)) ==
++                       (MALI_MMU_INTERRUPT_PAGE_FAULT|MALI_MMU_INTERRUPT_READ_BUS_ERROR))
++      {
++              return _MALI_OSK_ERR_OK;
++      }
++
++      return _MALI_OSK_ERR_FAULT;
++}
++
++#if 0
++void mali_mmu_print_state(struct mali_mmu_core *mmu)
++{
++      MALI_DEBUG_PRINT(2, ("MMU: State of %s is 0x%08x\n", mmu->hw_core.description, mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS)));
++}
++#endif
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_mmu.h b/drivers/gpu/arm/mali400/mali/common/mali_mmu.h
+new file mode 100644
+index 0000000..3410c0d
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_mmu.h
+@@ -0,0 +1,130 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_MMU_H__
++#define __MALI_MMU_H__
++
++#include "mali_osk.h"
++#include "mali_mmu_page_directory.h"
++#include "mali_hw_core.h"
++
++/* Forward declaration from mali_group.h */
++struct mali_group;
++
++/**
++ * MMU register numbers
++ * Used in the register read/write routines.
++ * See the hardware documentation for more information about each register
++ */
++typedef enum mali_mmu_register {
++      MALI_MMU_REGISTER_DTE_ADDR = 0x0000, /**< Current Page Directory Pointer */
++      MALI_MMU_REGISTER_STATUS = 0x0004, /**< Status of the MMU */
++      MALI_MMU_REGISTER_COMMAND = 0x0008, /**< Command register, used to control the MMU */
++      MALI_MMU_REGISTER_PAGE_FAULT_ADDR = 0x000C, /**< Logical address of the last page fault */
++      MALI_MMU_REGISTER_ZAP_ONE_LINE = 0x010, /**< Used to invalidate the mapping of a single page from the MMU */
++      MALI_MMU_REGISTER_INT_RAWSTAT = 0x0014, /**< Raw interrupt status, all interrupts visible */
++      MALI_MMU_REGISTER_INT_CLEAR = 0x0018, /**< Indicate to the MMU that the interrupt has been received */
++      MALI_MMU_REGISTER_INT_MASK = 0x001C, /**< Enable/disable types of interrupts */
++      MALI_MMU_REGISTER_INT_STATUS = 0x0020 /**< Interrupt status based on the mask */
++} mali_mmu_register;
++
++/**
++ * MMU interrupt register bits
++ * Each cause of the interrupt is reported
++ * through the (raw) interrupt status registers.
++ * Multiple interrupts can be pending, so multiple bits
++ * can be set at once.
++ */
++typedef enum mali_mmu_interrupt
++{
++      MALI_MMU_INTERRUPT_PAGE_FAULT = 0x01, /**< A page fault occured */
++      MALI_MMU_INTERRUPT_READ_BUS_ERROR = 0x02 /**< A bus read error occured */
++} mali_mmu_interrupt;
++
++typedef enum mali_mmu_status_bits
++{
++      MALI_MMU_STATUS_BIT_PAGING_ENABLED      = 1 << 0,
++      MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE   = 1 << 1,
++      MALI_MMU_STATUS_BIT_STALL_ACTIVE        = 1 << 2,
++      MALI_MMU_STATUS_BIT_IDLE                = 1 << 3,
++      MALI_MMU_STATUS_BIT_REPLAY_BUFFER_EMPTY = 1 << 4,
++      MALI_MMU_STATUS_BIT_PAGE_FAULT_IS_WRITE = 1 << 5,
++      MALI_MMU_STATUS_BIT_STALL_NOT_ACTIVE    = 1 << 31,
++} mali_mmu_status_bits;
++
++/**
++ * Definition of the MMU struct
++ * Used to track a MMU unit in the system.
++ * Contains information about the mapping of the registers
++ */
++struct mali_mmu_core
++{
++      struct mali_hw_core hw_core; /**< Common for all HW cores */
++      _mali_osk_irq_t *irq;        /**< IRQ handler */
++};
++
++_mali_osk_errcode_t mali_mmu_initialize(void);
++
++void mali_mmu_terminate(void);
++
++struct mali_mmu_core *mali_mmu_create(_mali_osk_resource_t *resource, struct mali_group *group, mali_bool is_virtual);
++void mali_mmu_delete(struct mali_mmu_core *mmu);
++
++_mali_osk_errcode_t mali_mmu_reset(struct mali_mmu_core *mmu);
++mali_bool mali_mmu_zap_tlb(struct mali_mmu_core *mmu);
++void mali_mmu_zap_tlb_without_stall(struct mali_mmu_core *mmu);
++void mali_mmu_invalidate_page(struct mali_mmu_core *mmu, u32 mali_address);
++
++mali_bool mali_mmu_activate_page_directory(struct mali_mmu_core* mmu, struct mali_page_directory *pagedir);
++void mali_mmu_activate_empty_page_directory(struct mali_mmu_core* mmu);
++void mali_mmu_activate_fault_flush_page_directory(struct mali_mmu_core* mmu);
++
++/**
++ * Issues the enable stall command to the MMU and waits for HW to complete the request
++ * @param mmu The MMU to enable paging for
++ * @return MALI_TRUE if HW stall was successfully engaged, otherwise MALI_FALSE (req timed out)
++ */
++mali_bool mali_mmu_enable_stall(struct mali_mmu_core *mmu);
++
++/**
++ * Issues the disable stall command to the MMU and waits for HW to complete the request
++ * @param mmu The MMU to enable paging for
++ */
++void mali_mmu_disable_stall(struct mali_mmu_core *mmu);
++
++void mali_mmu_page_fault_done(struct mali_mmu_core *mmu);
++
++/*** Register reading/writing functions ***/
++MALI_STATIC_INLINE u32 mali_mmu_get_int_status(struct mali_mmu_core *mmu)
++{
++      return mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_STATUS);
++}
++
++MALI_STATIC_INLINE u32 mali_mmu_get_rawstat(struct mali_mmu_core *mmu)
++{
++      return mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_RAWSTAT);
++}
++
++MALI_STATIC_INLINE void mali_mmu_mask_all_interrupts(struct mali_mmu_core *mmu)
++{
++      mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK, 0);
++}
++
++MALI_STATIC_INLINE u32 mali_mmu_get_status(struct mali_mmu_core *mmu)
++{
++      return mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS);
++}
++
++MALI_STATIC_INLINE u32 mali_mmu_get_page_fault_addr(struct mali_mmu_core *mmu)
++{
++      return mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_PAGE_FAULT_ADDR);
++}
++
++#endif /* __MALI_MMU_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_mmu_page_directory.c b/drivers/gpu/arm/mali400/mali/common/mali_mmu_page_directory.c
+new file mode 100644
+index 0000000..6a67fff
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_mmu_page_directory.c
+@@ -0,0 +1,522 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_kernel_common.h"
++#include "mali_kernel_core.h"
++#include "mali_osk.h"
++#include "mali_uk_types.h"
++#include "mali_mmu_page_directory.h"
++#include "mali_memory.h"
++#include "mali_l2_cache.h"
++#include "mali_group.h"
++
++static _mali_osk_errcode_t fill_page(mali_io_address mapping, u32 data);
++
++u32 mali_allocate_empty_page(void)
++{
++      _mali_osk_errcode_t err;
++      mali_io_address mapping;
++      u32 address;
++
++      if(_MALI_OSK_ERR_OK != mali_mmu_get_table_page(&address, &mapping))
++      {
++              /* Allocation failed */
++              return 0;
++      }
++
++      MALI_DEBUG_ASSERT_POINTER( mapping );
++
++      err = fill_page(mapping, 0);
++      if (_MALI_OSK_ERR_OK != err)
++      {
++              mali_mmu_release_table_page(address);
++      }
++      return address;
++}
++
++void mali_free_empty_page(u32 address)
++{
++      if (MALI_INVALID_PAGE != address)
++      {
++              mali_mmu_release_table_page(address);
++      }
++}
++
++_mali_osk_errcode_t mali_create_fault_flush_pages(u32 *page_directory, u32 *page_table, u32 *data_page)
++{
++      _mali_osk_errcode_t err;
++      mali_io_address page_directory_mapping;
++      mali_io_address page_table_mapping;
++      mali_io_address data_page_mapping;
++
++      err = mali_mmu_get_table_page(data_page, &data_page_mapping);
++      if (_MALI_OSK_ERR_OK == err)
++      {
++              err = mali_mmu_get_table_page(page_table, &page_table_mapping);
++              if (_MALI_OSK_ERR_OK == err)
++              {
++                      err = mali_mmu_get_table_page(page_directory, &page_directory_mapping);
++                      if (_MALI_OSK_ERR_OK == err)
++                      {
++                              fill_page(data_page_mapping, 0);
++                              fill_page(page_table_mapping, *data_page | MALI_MMU_FLAGS_WRITE_PERMISSION | MALI_MMU_FLAGS_READ_PERMISSION | MALI_MMU_FLAGS_PRESENT);
++                              fill_page(page_directory_mapping, *page_table | MALI_MMU_FLAGS_PRESENT);
++                              MALI_SUCCESS;
++                      }
++                      mali_mmu_release_table_page(*page_table);
++                      *page_table = MALI_INVALID_PAGE;
++              }
++              mali_mmu_release_table_page(*data_page);
++              *data_page = MALI_INVALID_PAGE;
++      }
++      return err;
++}
++
++void mali_destroy_fault_flush_pages(u32 *page_directory, u32 *page_table, u32 *data_page)
++{
++      if (MALI_INVALID_PAGE != *page_directory)
++      {
++              mali_mmu_release_table_page(*page_directory);
++              *page_directory = MALI_INVALID_PAGE;
++      }
++
++      if (MALI_INVALID_PAGE != *page_table)
++      {
++              mali_mmu_release_table_page(*page_table);
++              *page_table = MALI_INVALID_PAGE;
++      }
++
++      if (MALI_INVALID_PAGE != *data_page)
++      {
++              mali_mmu_release_table_page(*data_page);
++              *data_page = MALI_INVALID_PAGE;
++      }
++}
++
++static _mali_osk_errcode_t fill_page(mali_io_address mapping, u32 data)
++{
++      int i;
++      MALI_DEBUG_ASSERT_POINTER( mapping );
++
++      for(i = 0; i < MALI_MMU_PAGE_SIZE/4; i++)
++      {
++#ifdef CONFIG_SLP_MALI_DBG
++              _mali_osk_mem_iowrite32_relaxed_cpu( mapping, i * sizeof(u32), data);
++#else
++              _mali_osk_mem_iowrite32_relaxed( mapping, i * sizeof(u32), data);
++#endif
++      }
++      _mali_osk_mem_barrier();
++      MALI_SUCCESS;
++}
++
++_mali_osk_errcode_t mali_mmu_pagedir_map(struct mali_page_directory *pagedir, u32 mali_address, u32 size)
++{
++      const int first_pde = MALI_MMU_PDE_ENTRY(mali_address);
++      const int last_pde = MALI_MMU_PDE_ENTRY(mali_address + size - 1);
++      _mali_osk_errcode_t err;
++      mali_io_address pde_mapping;
++      u32 pde_phys;
++      int i;
++
++      for(i = first_pde; i <= last_pde; i++)
++      {
++#ifdef CONFIG_SLP_MALI_DBG
++              if(0 == (_mali_osk_mem_ioread32_cpu(pagedir->page_directory_mapped, i*sizeof(u32))&MALI_MMU_FLAGS_PRESENT))
++#else
++              if(0 == (_mali_osk_mem_ioread32(pagedir->page_directory_mapped, i*sizeof(u32)) & MALI_MMU_FLAGS_PRESENT))
++#endif
++              {
++                      /* Page table not present */
++                      MALI_DEBUG_ASSERT(0 == pagedir->page_entries_usage_count[i]);
++                      MALI_DEBUG_ASSERT(NULL == pagedir->page_entries_mapped[i]);
++
++                      err = mali_mmu_get_table_page(&pde_phys, &pde_mapping);
++                      if(_MALI_OSK_ERR_OK != err)
++                      {
++                              MALI_PRINT_ERROR(("Failed to allocate page table page.\n"));
++                              return err;
++                      }
++                      pagedir->page_entries_mapped[i] = pde_mapping;
++
++                      /* Update PDE, mark as present */
++#ifdef CONFIG_SLP_MALI_DBG
++                      _mali_osk_mem_iowrite32_relaxed_cpu(pagedir->page_directory_mapped, i*sizeof(u32),
++                                      pde_phys | MALI_MMU_FLAGS_PRESENT);
++#else
++                      _mali_osk_mem_iowrite32_relaxed(pagedir->page_directory_mapped, i*sizeof(u32),
++                                      pde_phys | MALI_MMU_FLAGS_PRESENT);
++#endif
++
++                      MALI_DEBUG_ASSERT(0 == pagedir->page_entries_usage_count[i]);
++                      pagedir->page_entries_usage_count[i] = 1;
++              }
++              else
++              {
++                      pagedir->page_entries_usage_count[i]++;
++              }
++      }
++      _mali_osk_write_mem_barrier();
++
++      MALI_SUCCESS;
++}
++
++MALI_STATIC_INLINE void mali_mmu_zero_pte(mali_io_address page_table, u32 mali_address, u32 size)
++{
++      int i;
++      const int first_pte = MALI_MMU_PTE_ENTRY(mali_address);
++      const int last_pte = MALI_MMU_PTE_ENTRY(mali_address + size - 1);
++
++      for (i = first_pte; i <= last_pte; i++)
++      {
++#ifdef CONFIG_SLP_MALI_DBG
++              _mali_osk_mem_iowrite32_relaxed_cpu(page_table, i * sizeof(u32), 0);
++#else
++              _mali_osk_mem_iowrite32_relaxed(page_table, i * sizeof(u32), 0);
++#endif
++      }
++}
++
++_mali_osk_errcode_t mali_mmu_pagedir_unmap(struct mali_page_directory *pagedir, u32 mali_address, u32 size)
++{
++      const int first_pde = MALI_MMU_PDE_ENTRY(mali_address);
++      const int last_pde = MALI_MMU_PDE_ENTRY(mali_address + size - 1);
++      u32 left = size;
++      int i;
++#ifndef MALI_UNMAP_FLUSH_ALL_MALI_L2
++      mali_bool pd_changed = MALI_FALSE;
++      u32 pages_to_invalidate[3]; /* hard-coded to 3: max two pages from the PT level plus max one page from PD level */
++      u32 num_pages_inv = 0;
++#endif
++
++      /* For all page directory entries in range. */
++      for (i = first_pde; i <= last_pde; i++)
++      {
++              u32 size_in_pde, offset;
++
++              MALI_DEBUG_ASSERT_POINTER(pagedir->page_entries_mapped[i]);
++              MALI_DEBUG_ASSERT(0 != pagedir->page_entries_usage_count[i]);
++
++              /* Offset into page table, 0 if mali_address is 4MiB aligned */
++              offset = (mali_address & (MALI_MMU_VIRTUAL_PAGE_SIZE - 1));
++              if (left < MALI_MMU_VIRTUAL_PAGE_SIZE - offset)
++              {
++                      size_in_pde = left;
++              }
++              else
++              {
++                      size_in_pde = MALI_MMU_VIRTUAL_PAGE_SIZE - offset;
++              }
++
++              pagedir->page_entries_usage_count[i]--;
++
++              /* If entire page table is unused, free it */
++              if (0 == pagedir->page_entries_usage_count[i])
++              {
++                      u32 page_address;
++                      MALI_DEBUG_PRINT(4, ("Releasing page table as this is the last reference\n"));
++                      /* last reference removed, no need to zero out each PTE  */
++
++#ifdef CONFIG_SLP_MALI_DBG
++                      page_address = MALI_MMU_ENTRY_ADDRESS(_mali_osk_mem_ioread32_cpu(pagedir->page_directory_mapped, i*sizeof(u32)));
++#else
++                      page_address = MALI_MMU_ENTRY_ADDRESS(_mali_osk_mem_ioread32(pagedir->page_directory_mapped, i*sizeof(u32)));
++#endif
++                      pagedir->page_entries_mapped[i] = NULL;
++#ifdef CONFIG_SLP_MALI_DBG
++                      _mali_osk_mem_iowrite32_relaxed_cpu(pagedir->page_directory_mapped, i*sizeof(u32), 0);
++#else
++                      _mali_osk_mem_iowrite32_relaxed(pagedir->page_directory_mapped, i*sizeof(u32), 0);
++#endif
++
++                      mali_mmu_release_table_page(page_address);
++#ifndef MALI_UNMAP_FLUSH_ALL_MALI_L2
++                      pd_changed = MALI_TRUE;
++#endif
++              }
++              else
++              {
++#ifndef MALI_UNMAP_FLUSH_ALL_MALI_L2
++                      pages_to_invalidate[num_pages_inv] = mali_page_directory_get_phys_address(pagedir, i);
++                      num_pages_inv++;
++                      MALI_DEBUG_ASSERT(num_pages_inv<3);
++#endif
++
++                      /* If part of the page table is still in use, zero the relevant PTEs */
++                      mali_mmu_zero_pte(pagedir->page_entries_mapped[i], mali_address, size_in_pde);
++              }
++
++              left -= size_in_pde;
++              mali_address += size_in_pde;
++      }
++      _mali_osk_write_mem_barrier();
++
++#ifndef MALI_UNMAP_FLUSH_ALL_MALI_L2
++      /* L2 pages invalidation */
++      if (MALI_TRUE == pd_changed)
++      {
++              pages_to_invalidate[num_pages_inv] = pagedir->page_directory;
++              num_pages_inv++;
++              MALI_DEBUG_ASSERT(num_pages_inv<3);
++      }
++
++      if (_MALI_PRODUCT_ID_MALI200 != mali_kernel_core_get_product_id())
++      {
++              mali_l2_cache_invalidate_pages_conditional(pages_to_invalidate, num_pages_inv);
++      }
++#endif
++
++      MALI_SUCCESS;
++}
++
++struct mali_page_directory *mali_mmu_pagedir_alloc(void)
++{
++      struct mali_page_directory *pagedir;
++
++      pagedir = _mali_osk_calloc(1, sizeof(struct mali_page_directory));
++      if(NULL == pagedir)
++      {
++              return NULL;
++      }
++
++      if(_MALI_OSK_ERR_OK != mali_mmu_get_table_page(&pagedir->page_directory, &pagedir->page_directory_mapped))
++      {
++              _mali_osk_free(pagedir);
++              return NULL;
++      }
++
++      /* Zero page directory */
++      fill_page(pagedir->page_directory_mapped, 0);
++
++      return pagedir;
++}
++
++void mali_mmu_pagedir_free(struct mali_page_directory *pagedir)
++{
++      const int num_page_table_entries = sizeof(pagedir->page_entries_mapped) / sizeof(pagedir->page_entries_mapped[0]);
++      int i;
++
++      /* Free referenced page tables and zero PDEs. */
++      for (i = 0; i < num_page_table_entries; i++)
++      {
++#ifdef CONFIG_SLP_MALI_DBG
++              if (pagedir->page_directory_mapped && (_mali_osk_mem_ioread32_cpu(pagedir->page_directory_mapped, sizeof(u32)*i)&MALI_MMU_FLAGS_PRESENT))
++              {
++                      mali_mmu_release_table_page( _mali_osk_mem_ioread32_cpu(pagedir->page_directory_mapped, i*sizeof(u32)) & ~MALI_MMU_FLAGS_MASK);
++                      _mali_osk_mem_iowrite32_relaxed_cpu(pagedir->page_directory_mapped, i * sizeof(u32), 0);
++              }
++#else
++              if (pagedir->page_directory_mapped && (_mali_osk_mem_ioread32(pagedir->page_directory_mapped, sizeof(u32)*i) & MALI_MMU_FLAGS_PRESENT))
++              {
++                      mali_mmu_release_table_page( _mali_osk_mem_ioread32(pagedir->page_directory_mapped, i*sizeof(u32)) & ~MALI_MMU_FLAGS_MASK);
++                      _mali_osk_mem_iowrite32_relaxed(pagedir->page_directory_mapped, i * sizeof(u32), 0);
++              }
++#endif
++      }
++      _mali_osk_write_mem_barrier();
++
++      /* Free the page directory page. */
++      mali_mmu_release_table_page(pagedir->page_directory);
++
++      _mali_osk_free(pagedir);
++}
++
++
++void mali_mmu_pagedir_update(struct mali_page_directory *pagedir, u32 mali_address, u32 phys_address, u32 size, mali_memory_cache_settings cache_settings)
++{
++      u32 end_address = mali_address + size;
++      u32 permission_bits;
++
++      switch ( cache_settings )
++      {
++              case MALI_CACHE_GP_READ_ALLOCATE:
++              MALI_DEBUG_PRINT(5, ("Map L2 GP_Read_allocate\n"));
++              permission_bits = MALI_MMU_FLAGS_FORCE_GP_READ_ALLOCATE;
++              break;
++
++              case MALI_CACHE_STANDARD:
++              MALI_DEBUG_PRINT(5, ("Map L2 Standard\n"));
++              /*falltrough */
++              default:
++              if ( MALI_CACHE_STANDARD != cache_settings) MALI_PRINT_ERROR(("Wrong cache settings\n"));
++              permission_bits = MALI_MMU_FLAGS_WRITE_PERMISSION | MALI_MMU_FLAGS_READ_PERMISSION | MALI_MMU_FLAGS_PRESENT;
++      }
++
++      /* Map physical pages into MMU page tables */
++      for ( ; mali_address < end_address; mali_address += MALI_MMU_PAGE_SIZE, phys_address += MALI_MMU_PAGE_SIZE)
++      {
++              MALI_DEBUG_ASSERT_POINTER(pagedir->page_entries_mapped[MALI_MMU_PDE_ENTRY(mali_address)]);
++#ifdef CONFIG_SLP_MALI_DBG
++              _mali_osk_mem_iowrite32_relaxed_cpu( pagedir->page_entries_mapped[MALI_MMU_PDE_ENTRY( mali_address)],
++                              MALI_MMU_PTE_ENTRY(mali_address) * sizeof(u32),
++                              phys_address | permission_bits);
++#else
++              _mali_osk_mem_iowrite32_relaxed(pagedir->page_entries_mapped[MALI_MMU_PDE_ENTRY(mali_address)],
++                              MALI_MMU_PTE_ENTRY(mali_address) * sizeof(u32),
++                              phys_address | permission_bits);
++#endif
++      }
++      _mali_osk_write_mem_barrier();
++}
++
++u32 mali_page_directory_get_phys_address(struct mali_page_directory *pagedir, u32 index)
++{
++#ifdef CONFIG_SLP_MALI_DBG
++      return (_mali_osk_mem_ioread32_cpu( pagedir->page_directory_mapped, index*sizeof(u32)) & ~MALI_MMU_FLAGS_MASK);
++#else
++      return (_mali_osk_mem_ioread32(pagedir->page_directory_mapped, index*sizeof(u32)) & ~MALI_MMU_FLAGS_MASK);
++#endif
++}
++
++/* For instrumented */
++struct dump_info
++{
++      u32 buffer_left;
++      u32 register_writes_size;
++      u32 page_table_dump_size;
++      u32 *buffer;
++};
++
++static _mali_osk_errcode_t writereg(u32 where, u32 what, const char *comment, struct dump_info *info)
++{
++      if (NULL != info)
++      {
++              info->register_writes_size += sizeof(u32)*2; /* two 32-bit words */
++
++              if (NULL != info->buffer)
++              {
++                      /* check that we have enough space */
++                      if (info->buffer_left < sizeof(u32)*2) MALI_ERROR(_MALI_OSK_ERR_NOMEM);
++
++                      *info->buffer = where;
++                      info->buffer++;
++
++                      *info->buffer = what;
++                      info->buffer++;
++
++                      info->buffer_left -= sizeof(u32)*2;
++              }
++      }
++
++      MALI_SUCCESS;
++}
++
++static _mali_osk_errcode_t dump_page(mali_io_address page, u32 phys_addr, struct dump_info * info)
++{
++      if (NULL != info)
++      {
++              /* 4096 for the page and 4 bytes for the address */
++              const u32 page_size_in_elements = MALI_MMU_PAGE_SIZE / 4;
++              const u32 page_size_in_bytes = MALI_MMU_PAGE_SIZE;
++              const u32 dump_size_in_bytes = MALI_MMU_PAGE_SIZE + 4;
++
++              info->page_table_dump_size += dump_size_in_bytes;
++
++              if (NULL != info->buffer)
++              {
++                      if (info->buffer_left < dump_size_in_bytes) MALI_ERROR(_MALI_OSK_ERR_NOMEM);
++
++                      *info->buffer = phys_addr;
++                      info->buffer++;
++
++                      _mali_osk_memcpy(info->buffer, page, page_size_in_bytes);
++                      info->buffer += page_size_in_elements;
++
++                      info->buffer_left -= dump_size_in_bytes;
++              }
++      }
++
++      MALI_SUCCESS;
++}
++
++static _mali_osk_errcode_t dump_mmu_page_table(struct mali_page_directory *pagedir, struct dump_info * info)
++{
++      MALI_DEBUG_ASSERT_POINTER(pagedir);
++      MALI_DEBUG_ASSERT_POINTER(info);
++
++      if (NULL != pagedir->page_directory_mapped)
++      {
++              int i;
++
++              MALI_CHECK_NO_ERROR(
++                      dump_page(pagedir->page_directory_mapped, pagedir->page_directory, info)
++                      );
++
++              for (i = 0; i < 1024; i++)
++              {
++                      if (NULL != pagedir->page_entries_mapped[i])
++                      {
++                              MALI_CHECK_NO_ERROR(
++                                  dump_page(pagedir->page_entries_mapped[i],
++#ifdef CONFIG_SLP_MALI_DBG
++                                      _mali_osk_mem_ioread32_cpu(pagedir->page_directory_mapped,
++                                      i * sizeof(u32)) & ~MALI_MMU_FLAGS_MASK, info)
++#else
++                                      _mali_osk_mem_ioread32(pagedir->page_directory_mapped,
++                                      i * sizeof(u32)) & ~MALI_MMU_FLAGS_MASK, info)
++#endif
++                              );
++                      }
++              }
++      }
++
++      MALI_SUCCESS;
++}
++
++static _mali_osk_errcode_t dump_mmu_registers(struct mali_page_directory *pagedir, struct dump_info * info)
++{
++      MALI_CHECK_NO_ERROR(writereg(0x00000000, pagedir->page_directory,
++                                   "set the page directory address", info));
++      MALI_CHECK_NO_ERROR(writereg(0x00000008, 4, "zap???", info));
++      MALI_CHECK_NO_ERROR(writereg(0x00000008, 0, "enable paging", info));
++      MALI_SUCCESS;
++}
++
++_mali_osk_errcode_t _mali_ukk_query_mmu_page_table_dump_size( _mali_uk_query_mmu_page_table_dump_size_s *args )
++{
++      struct dump_info info = { 0, 0, 0, NULL };
++      struct mali_session_data * session_data;
++
++      MALI_DEBUG_ASSERT_POINTER(args);
++      MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
++
++      session_data = (struct mali_session_data *)(args->ctx);
++
++      MALI_CHECK_NO_ERROR(dump_mmu_registers(session_data->page_directory, &info));
++      MALI_CHECK_NO_ERROR(dump_mmu_page_table(session_data->page_directory, &info));
++      args->size = info.register_writes_size + info.page_table_dump_size;
++      MALI_SUCCESS;
++}
++
++_mali_osk_errcode_t _mali_ukk_dump_mmu_page_table( _mali_uk_dump_mmu_page_table_s * args )
++{
++      struct dump_info info = { 0, 0, 0, NULL };
++      struct mali_session_data * session_data;
++
++      MALI_DEBUG_ASSERT_POINTER(args);
++      MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
++      MALI_CHECK_NON_NULL(args->buffer, _MALI_OSK_ERR_INVALID_ARGS);
++
++      session_data = (struct mali_session_data *)(args->ctx);
++
++      info.buffer_left = args->size;
++      info.buffer = args->buffer;
++
++      args->register_writes = info.buffer;
++      MALI_CHECK_NO_ERROR(dump_mmu_registers(session_data->page_directory, &info));
++
++      args->page_table_dump = info.buffer;
++      MALI_CHECK_NO_ERROR(dump_mmu_page_table(session_data->page_directory, &info));
++
++      args->register_writes_size = info.register_writes_size;
++      args->page_table_dump_size = info.page_table_dump_size;
++
++      MALI_SUCCESS;
++}
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_mmu_page_directory.h b/drivers/gpu/arm/mali400/mali/common/mali_mmu_page_directory.h
+new file mode 100644
+index 0000000..67225b1
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_mmu_page_directory.h
+@@ -0,0 +1,100 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_MMU_PAGE_DIRECTORY_H__
++#define __MALI_MMU_PAGE_DIRECTORY_H__
++
++#include "mali_osk.h"
++
++/**
++ * Size of an MMU page in bytes
++ */
++#define MALI_MMU_PAGE_SIZE 0x1000
++
++/*
++ * Size of the address space referenced by a page table page
++ */
++#define MALI_MMU_VIRTUAL_PAGE_SIZE 0x400000 /* 4 MiB */
++
++/**
++ * Page directory index from address
++ * Calculates the page directory index from the given address
++ */
++#define MALI_MMU_PDE_ENTRY(address) (((address)>>22) & 0x03FF)
++
++/**
++ * Page table index from address
++ * Calculates the page table index from the given address
++ */
++#define MALI_MMU_PTE_ENTRY(address) (((address)>>12) & 0x03FF)
++
++/**
++ * Extract the memory address from an PDE/PTE entry
++ */
++#define MALI_MMU_ENTRY_ADDRESS(value) ((value) & 0xFFFFFC00)
++
++#define MALI_INVALID_PAGE ((u32)(~0))
++
++/**
++ *
++ */
++typedef enum mali_mmu_entry_flags
++{
++      MALI_MMU_FLAGS_PRESENT = 0x01,
++      MALI_MMU_FLAGS_READ_PERMISSION = 0x02,
++      MALI_MMU_FLAGS_WRITE_PERMISSION = 0x04,
++      MALI_MMU_FLAGS_OVERRIDE_CACHE  = 0x8,
++      MALI_MMU_FLAGS_WRITE_CACHEABLE  = 0x10,
++      MALI_MMU_FLAGS_WRITE_ALLOCATE  = 0x20,
++      MALI_MMU_FLAGS_WRITE_BUFFERABLE  = 0x40,
++      MALI_MMU_FLAGS_READ_CACHEABLE  = 0x80,
++      MALI_MMU_FLAGS_READ_ALLOCATE  = 0x100,
++      MALI_MMU_FLAGS_MASK = 0x1FF,
++} mali_mmu_entry_flags;
++
++
++#define MALI_MMU_FLAGS_FORCE_GP_READ_ALLOCATE ( \
++MALI_MMU_FLAGS_PRESENT | \
++      MALI_MMU_FLAGS_READ_PERMISSION |  \
++      MALI_MMU_FLAGS_WRITE_PERMISSION | \
++      MALI_MMU_FLAGS_OVERRIDE_CACHE | \
++      MALI_MMU_FLAGS_WRITE_CACHEABLE | \
++      MALI_MMU_FLAGS_WRITE_BUFFERABLE | \
++      MALI_MMU_FLAGS_READ_CACHEABLE | \
++      MALI_MMU_FLAGS_READ_ALLOCATE )
++
++
++struct mali_page_directory
++{
++      u32 page_directory; /**< Physical address of the memory session's page directory */
++      mali_io_address page_directory_mapped; /**< Pointer to the mapped version of the page directory into the kernel's address space */
++
++      mali_io_address page_entries_mapped[1024]; /**< Pointers to the page tables which exists in the page directory mapped into the kernel's address space */
++      u32   page_entries_usage_count[1024]; /**< Tracks usage count of the page table pages, so they can be releases on the last reference */
++};
++
++/* Map Mali virtual address space (i.e. ensure page tables exist for the virtual range)  */
++_mali_osk_errcode_t mali_mmu_pagedir_map(struct mali_page_directory *pagedir, u32 mali_address, u32 size);
++_mali_osk_errcode_t mali_mmu_pagedir_unmap(struct mali_page_directory *pagedir, u32 mali_address, u32 size);
++
++/* Back virtual address space with actual pages. Assumes input is contiguous and 4k aligned. */
++void mali_mmu_pagedir_update(struct mali_page_directory *pagedir, u32 mali_address, u32 phys_address, u32 size, u32 cache_settings);
++
++u32 mali_page_directory_get_phys_address(struct mali_page_directory *pagedir, u32 index);
++
++u32 mali_allocate_empty_page(void);
++void mali_free_empty_page(u32 address);
++_mali_osk_errcode_t mali_create_fault_flush_pages(u32 *page_directory, u32 *page_table, u32 *data_page);
++void mali_destroy_fault_flush_pages(u32 *page_directory, u32 *page_table, u32 *data_page);
++
++struct mali_page_directory *mali_mmu_pagedir_alloc(void);
++void mali_mmu_pagedir_free(struct mali_page_directory *pagedir);
++
++#endif /* __MALI_MMU_PAGE_DIRECTORY_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_osk.h b/drivers/gpu/arm/mali400/mali/common/mali_osk.h
+new file mode 100644
+index 0000000..aa6d5fc
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_osk.h
+@@ -0,0 +1,1804 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_osk.h
++ * Defines the OS abstraction layer for the kernel device driver (OSK)
++ */
++
++#ifndef __MALI_OSK_H__
++#define __MALI_OSK_H__
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif
++
++/**
++ * @addtogroup uddapi Unified Device Driver (UDD) APIs
++ *
++ * @{
++ */
++
++/**
++ * @addtogroup oskapi UDD OS Abstraction for Kernel-side (OSK) APIs
++ *
++ * @{
++ */
++
++/** @defgroup _mali_osk_miscellaneous OSK Miscellaneous functions, constants and types
++ * @{ */
++
++/* Define integer types used by OSK. Note: these currently clash with Linux so we only define them if not defined already */
++#ifndef __KERNEL__
++      typedef unsigned char      u8;
++      typedef signed char        s8;
++      typedef unsigned short     u16;
++      typedef signed short       s16;
++      typedef unsigned int       u32;
++      typedef signed int         s32;
++      typedef unsigned long long u64;
++      #define BITS_PER_LONG (sizeof(long)*8)
++#else
++      /* Ensure Linux types u32, etc. are defined */
++      #include <linux/types.h>
++#endif
++
++/** @brief Mali Boolean type which uses MALI_TRUE and MALI_FALSE
++  */
++      typedef unsigned long mali_bool;
++
++#ifndef MALI_TRUE
++      #define MALI_TRUE ((mali_bool)1)
++#endif
++
++#ifndef MALI_FALSE
++      #define MALI_FALSE ((mali_bool)0)
++#endif
++
++#define MALI_HW_CORE_NO_COUNTER     ((u32)-1)
++
++/**
++ * @brief OSK Error codes
++ *
++ * Each OS may use its own set of error codes, and may require that the
++ * User/Kernel interface take certain error code. This means that the common
++ * error codes need to be sufficiently rich to pass the correct error code
++ * thorugh from the OSK to U/K layer, across all OSs.
++ *
++ * The result is that some error codes will appear redundant on some OSs.
++ * Under all OSs, the OSK layer must translate native OS error codes to
++ * _mali_osk_errcode_t codes. Similarly, the U/K layer must translate from
++ * _mali_osk_errcode_t codes to native OS error codes.
++ */
++typedef enum
++{
++    _MALI_OSK_ERR_OK = 0, /**< Success. */
++    _MALI_OSK_ERR_FAULT = -1, /**< General non-success */
++    _MALI_OSK_ERR_INVALID_FUNC = -2, /**< Invalid function requested through User/Kernel interface (e.g. bad IOCTL number) */
++    _MALI_OSK_ERR_INVALID_ARGS = -3, /**< Invalid arguments passed through User/Kernel interface */
++    _MALI_OSK_ERR_NOMEM = -4, /**< Insufficient memory */
++    _MALI_OSK_ERR_TIMEOUT = -5, /**< Timeout occurred */
++    _MALI_OSK_ERR_RESTARTSYSCALL = -6, /**< Special: On certain OSs, must report when an interruptable mutex is interrupted. Ignore otherwise. */
++    _MALI_OSK_ERR_ITEM_NOT_FOUND = -7, /**< Table Lookup failed */
++    _MALI_OSK_ERR_BUSY = -8, /**< Device/operation is busy. Try again later */
++      _MALI_OSK_ERR_UNSUPPORTED = -9, /**< Optional part of the interface used, and is unsupported */
++} _mali_osk_errcode_t;
++
++/** @} */ /* end group _mali_osk_miscellaneous */
++
++/** @defgroup _mali_osk_wq OSK work queues
++ * @{ */
++
++/** @brief Private type for work objects */
++typedef struct _mali_osk_wq_work_t_struct _mali_osk_wq_work_t;
++
++/** @brief Work queue handler function
++ *
++ * This function type is called when the work is scheduled by the work queue,
++ * e.g. as an IRQ bottom-half handler.
++ *
++ * Refer to \ref _mali_osk_wq_schedule_work() for more information on the
++ * work-queue and work handlers.
++ *
++ * @param arg resource-specific data
++ */
++typedef void (*_mali_osk_wq_work_handler_t)( void * arg );
++
++/* @} */ /* end group _mali_osk_wq */
++
++/** @defgroup _mali_osk_irq OSK IRQ handling
++ * @{ */
++
++/** @brief Private type for IRQ handling objects */
++typedef struct _mali_osk_irq_t_struct _mali_osk_irq_t;
++
++/** @brief Optional function to trigger an irq from a resource
++ *
++ * This function is implemented by the common layer to allow probing of a resource's IRQ.
++ * @param arg resource-specific data */
++typedef void  (*_mali_osk_irq_trigger_t)( void * arg );
++
++/** @brief Optional function to acknowledge an irq from a resource
++ *
++ * This function is implemented by the common layer to allow probing of a resource's IRQ.
++ * @param arg resource-specific data
++ * @return _MALI_OSK_ERR_OK if the IRQ was successful, or a suitable _mali_osk_errcode_t on failure. */
++typedef _mali_osk_errcode_t (*_mali_osk_irq_ack_t)( void * arg );
++
++/** @brief IRQ 'upper-half' handler callback.
++ *
++ * This function is implemented by the common layer to do the initial handling of a
++ * resource's IRQ. This maps on to the concept of an ISR that does the minimum
++ * work necessary before handing off to an IST.
++ *
++ * The communication of the resource-specific data from the ISR to the IST is
++ * handled by the OSK implementation.
++ *
++ * On most systems, the IRQ upper-half handler executes in IRQ context.
++ * Therefore, the system may have restrictions about what can be done in this
++ * context
++ *
++ * If an IRQ upper-half handler requires more work to be done than can be
++ * acheived in an IRQ context, then it may defer the work with
++ * _mali_osk_wq_schedule_work(). Refer to \ref _mali_osk_wq_create_work() for
++ * more information.
++ *
++ * @param arg resource-specific data
++ * @return _MALI_OSK_ERR_OK if the IRQ was correctly handled, or a suitable
++ * _mali_osk_errcode_t otherwise.
++ */
++typedef _mali_osk_errcode_t  (*_mali_osk_irq_uhandler_t)( void * arg );
++
++/** @} */ /* end group _mali_osk_irq */
++
++
++/** @defgroup _mali_osk_atomic OSK Atomic counters
++ * @{ */
++
++/** @brief Public type of atomic counters
++ *
++ * This is public for allocation on stack. On systems that support it, this is just a single 32-bit value.
++ * On others, it could be encapsulating an object stored elsewhere.
++ *
++ * Regardless of implementation, the \ref _mali_osk_atomic functions \b must be used
++ * for all accesses to the variable's value, even if atomicity is not required.
++ * Do not access u.val or u.obj directly.
++ */
++typedef struct
++{
++    union
++    {
++        u32 val;
++        void *obj;
++    } u;
++} _mali_osk_atomic_t;
++/** @} */ /* end group _mali_osk_atomic */
++
++
++/** @defgroup _mali_osk_lock OSK Mutual Exclusion Locks
++ * @{ */
++
++
++/** @brief OSK Mutual Exclusion Lock ordered list
++ *
++ * This lists the various types of locks in the system and is used to check
++ * that locks are taken in the correct order.
++ *
++ * Holding more than one lock of the same order at the same time is not
++ * allowed.
++ *
++ */
++typedef enum
++{
++      _MALI_OSK_LOCK_ORDER_LAST = 0,
++
++      _MALI_OSK_LOCK_ORDER_SESSION_PENDING_JOBS,
++      _MALI_OSK_LOCK_ORDER_PM_EXECUTE,
++      _MALI_OSK_LOCK_ORDER_UTILIZATION,
++      _MALI_OSK_LOCK_ORDER_L2_COUNTER,
++      _MALI_OSK_LOCK_ORDER_PROFILING,
++      _MALI_OSK_LOCK_ORDER_L2_COMMAND,
++      _MALI_OSK_LOCK_ORDER_PM_CORE_STATE,
++      _MALI_OSK_LOCK_ORDER_SCHEDULER_DEFERRED,
++      _MALI_OSK_LOCK_ORDER_SCHEDULER,
++      _MALI_OSK_LOCK_ORDER_GROUP,
++      _MALI_OSK_LOCK_ORDER_GROUP_VIRTUAL,
++      _MALI_OSK_LOCK_ORDER_DESCRIPTOR_MAP,
++      _MALI_OSK_LOCK_ORDER_MEM_PT_CACHE,
++      _MALI_OSK_LOCK_ORDER_MEM_INFO,
++      _MALI_OSK_LOCK_ORDER_MEM_SESSION,
++      _MALI_OSK_LOCK_ORDER_SESSIONS,
++
++      _MALI_OSK_LOCK_ORDER_FIRST
++} _mali_osk_lock_order_t;
++
++
++/** @brief OSK Mutual Exclusion Lock flags type
++ *
++ * Flags are supplied at the point where the Lock is initialized. Each flag can
++ * be combined with others using bitwise OR, '|'.
++ *
++ * The flags must be sufficiently rich to cope with all our OSs. This means
++ * that on some OSs, certain flags can be completely ignored. We define a
++ * number of terms that are significant across all OSs:
++ *
++ * - Sleeping/non-sleeping mutexs. Sleeping mutexs can block on waiting, and so
++ * schedule out the current thread. This is significant on OSs where there are
++ * situations in which the current thread must not be put to sleep. On OSs
++ * without this restriction, sleeping and non-sleeping mutexes can be treated
++ * as the same (if that is required).
++ * - Interruptable/non-interruptable mutexes. For sleeping mutexes, it may be
++ * possible for the sleep to be interrupted for a reason other than the thread
++ * being able to obtain the lock. OSs behaving in this way may provide a
++ * mechanism to control whether sleeping mutexes can be interrupted. On OSs
++ * that do not support the concept of interruption, \b or they do not support
++ * control of mutex interruption, then interruptable mutexes may be treated
++ * as non-interruptable.
++ *
++ * Some constrains apply to the lock type flags:
++ *
++ * - Spinlocks are by nature, non-interruptable. Hence, they must always be
++ * combined with the NONINTERRUPTABLE flag, because it is meaningless to ask
++ * for a spinlock that is interruptable (and this highlights its
++ * non-interruptable-ness). For example, on certain OSs they should be used when
++ * you must not sleep.
++ * - Reader/writer is an optimization hint, and any type of lock can be
++ * reader/writer. Since this is an optimization hint, the implementation need
++ * not respect this for any/all types of lock. For example, on certain OSs,
++ * there's no interruptable reader/writer mutex. If such a thing were requested
++ * on that OS, the fact that interruptable was requested takes priority over the
++ * reader/writer-ness, because reader/writer-ness is not necessary for correct
++ * operation.
++ * - Any lock can use the order parameter.
++ * - A onelock is an optimization hint specific to certain OSs. It can be
++ * specified when it is known that only one lock will be held by the thread,
++ * and so can provide faster mutual exclusion. This can be safely ignored if
++ * such optimization is not required/present.
++ *
++ * The absence of any flags (the value 0) results in a sleeping-mutex, which is interruptable.
++ */
++typedef enum
++{
++      _MALI_OSK_LOCKFLAG_SPINLOCK = 0x1,          /**< Specifically, don't sleep on those architectures that require it */
++      _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE = 0x2,  /**< The mutex cannot be interrupted, e.g. delivery of signals on those architectures where this is required */
++      _MALI_OSK_LOCKFLAG_READERWRITER = 0x4,      /**< Optimise for readers/writers */
++      _MALI_OSK_LOCKFLAG_ORDERED = 0x8,           /**< Use the order parameter; otherwise use automatic ordering */
++      _MALI_OSK_LOCKFLAG_ONELOCK = 0x10,          /**< Each thread can only hold one lock at a time */
++      _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ = 0x20,    /**<  IRQ version of spinlock */
++      /** @enum _mali_osk_lock_flags_t
++       *
++       * Flags from 0x10000--0x80000000 are RESERVED for User-mode */
++
++} _mali_osk_lock_flags_t;
++
++/** @brief Mutual Exclusion Lock Mode Optimization hint
++ *
++ * The lock mode is used to implement the read/write locking of locks specified
++ * as _MALI_OSK_LOCKFLAG_READERWRITER. In this case, the RO mode can be used
++ * to allow multiple concurrent readers, but no writers. The RW mode is used for
++ * writers, and so will wait for all readers to release the lock (if any present).
++ * Further readers and writers will wait until the writer releases the lock.
++ *
++ * The mode is purely an optimization hint: for example, it is permissible for
++ * all locks to behave in RW mode, regardless of that supplied.
++ *
++ * It is an error to attempt to use locks in anything other that RW mode when
++ * _MALI_OSK_LOCKFLAG_READERWRITER is not supplied.
++ *
++ */
++typedef enum
++{
++      _MALI_OSK_LOCKMODE_UNDEF = -1,  /**< Undefined lock mode. For internal use only */
++      _MALI_OSK_LOCKMODE_RW    = 0x0, /**< Read-write mode, default. All readers and writers are mutually-exclusive */
++      _MALI_OSK_LOCKMODE_RO,          /**< Read-only mode, to support multiple concurrent readers, but mutual exclusion in the presence of writers. */
++      /** @enum _mali_osk_lock_mode_t
++       *
++       * Lock modes 0x40--0x7F are RESERVED for User-mode */
++} _mali_osk_lock_mode_t;
++
++/** @brief Private type for Mutual Exclusion lock objects */
++typedef struct _mali_osk_lock_t_struct _mali_osk_lock_t;
++
++#ifdef DEBUG
++/** @brief Macro for asserting that the current thread holds a given lock
++ */
++#define MALI_DEBUG_ASSERT_LOCK_HELD(l) MALI_DEBUG_ASSERT(_mali_osk_lock_get_owner(l) == _mali_osk_get_tid());
++
++/** @brief returns a lock's owner (thread id) if debugging is enabled
++ */
++u32 _mali_osk_lock_get_owner( _mali_osk_lock_t *lock );
++#else
++#define MALI_DEBUG_ASSERT_LOCK_HELD(l) do {} while(0)
++#endif
++
++/** @} */ /* end group _mali_osk_lock */
++
++/** @defgroup _mali_osk_low_level_memory OSK Low-level Memory Operations
++ * @{ */
++
++/**
++ * @brief Private data type for use in IO accesses to/from devices.
++ *
++ * This represents some range that is accessible from the device. Examples
++ * include:
++ * - Device Registers, which could be readable and/or writeable.
++ * - Memory that the device has access to, for storing configuration structures.
++ *
++ * Access to this range must be made through the _mali_osk_mem_ioread32() and
++ * _mali_osk_mem_iowrite32() functions.
++ */
++typedef struct _mali_io_address * mali_io_address;
++
++/** @defgroup _MALI_OSK_CPU_PAGE CPU Physical page size macros.
++ *
++ * The order of the page size is supplied for
++ * ease of use by algorithms that might require it, since it is easier to know
++ * it ahead of time rather than calculating it.
++ *
++ * The Mali Page Mask macro masks off the lower bits of a physical address to
++ * give the start address of the page for that physical address.
++ *
++ * @note The Mali device driver code is designed for systems with 4KB page size.
++ * Changing these macros will not make the entire Mali device driver work with
++ * page sizes other than 4KB.
++ *
++ * @note The CPU Physical Page Size has been assumed to be the same as the Mali
++ * Physical Page Size.
++ *
++ * @{
++ */
++
++/** CPU Page Order, as log to base 2 of the Page size. @see _MALI_OSK_CPU_PAGE_SIZE */
++#define _MALI_OSK_CPU_PAGE_ORDER ((u32)12)
++/** CPU Page Size, in bytes.               */
++#define _MALI_OSK_CPU_PAGE_SIZE (((u32)1) << (_MALI_OSK_CPU_PAGE_ORDER))
++/** CPU Page Mask, which masks off the offset within a page */
++#define _MALI_OSK_CPU_PAGE_MASK (~((((u32)1) << (_MALI_OSK_CPU_PAGE_ORDER)) - ((u32)1)))
++/** @} */ /* end of group _MALI_OSK_CPU_PAGE */
++
++/** @defgroup _MALI_OSK_MALI_PAGE Mali Physical Page size macros
++ *
++ * Mali Physical page size macros. The order of the page size is supplied for
++ * ease of use by algorithms that might require it, since it is easier to know
++ * it ahead of time rather than calculating it.
++ *
++ * The Mali Page Mask macro masks off the lower bits of a physical address to
++ * give the start address of the page for that physical address.
++ *
++ * @note The Mali device driver code is designed for systems with 4KB page size.
++ * Changing these macros will not make the entire Mali device driver work with
++ * page sizes other than 4KB.
++ *
++ * @note The Mali Physical Page Size has been assumed to be the same as the CPU
++ * Physical Page Size.
++ *
++ * @{
++ */
++
++/** Mali Page Order, as log to base 2 of the Page size. @see _MALI_OSK_MALI_PAGE_SIZE */
++#define _MALI_OSK_MALI_PAGE_ORDER ((u32)12)
++/** Mali Page Size, in bytes.               */
++#define _MALI_OSK_MALI_PAGE_SIZE (((u32)1) << (_MALI_OSK_MALI_PAGE_ORDER))
++/** Mali Page Mask, which masks off the offset within a page */
++#define _MALI_OSK_MALI_PAGE_MASK (~((((u32)1) << (_MALI_OSK_MALI_PAGE_ORDER)) - ((u32)1)))
++/** @} */ /* end of group _MALI_OSK_MALI_PAGE*/
++
++/** @brief flags for mapping a user-accessible memory range
++ *
++ * Where a function with prefix '_mali_osk_mem_mapregion' accepts flags as one
++ * of the function parameters, it will use one of these. These allow per-page
++ * control over mappings. Compare with the mali_memory_allocation_flag type,
++ * which acts over an entire range
++ *
++ * These may be OR'd together with bitwise OR (|), but must be cast back into
++ * the type after OR'ing.
++ */
++typedef enum
++{
++      _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR = 0x1, /**< Physical address is OS Allocated */
++} _mali_osk_mem_mapregion_flags_t;
++/** @} */ /* end group _mali_osk_low_level_memory */
++
++/** @defgroup _mali_osk_notification OSK Notification Queues
++ * @{ */
++
++/** @brief Private type for notification queue objects */
++typedef struct _mali_osk_notification_queue_t_struct _mali_osk_notification_queue_t;
++
++/** @brief Public notification data object type */
++typedef struct _mali_osk_notification_t_struct
++{
++      u32 notification_type;   /**< The notification type */
++      u32 result_buffer_size; /**< Size of the result buffer to copy to user space */
++      void * result_buffer;   /**< Buffer containing any type specific data */
++} _mali_osk_notification_t;
++
++/** @} */ /* end group _mali_osk_notification */
++
++
++/** @defgroup _mali_osk_timer OSK Timer Callbacks
++ * @{ */
++
++/** @brief Function to call when a timer expires
++ *
++ * When a timer expires, this function is called. Note that on many systems,
++ * a timer callback will be executed in IRQ context. Therefore, restrictions
++ * may apply on what can be done inside the timer callback.
++ *
++ * If a timer requires more work to be done than can be acheived in an IRQ
++ * context, then it may defer the work with a work-queue. For example, it may
++ * use \ref _mali_osk_wq_schedule_work() to make use of a bottom-half handler
++ * to carry out the remaining work.
++ *
++ * Stopping the timer with \ref _mali_osk_timer_del() blocks on compeletion of
++ * the callback. Therefore, the callback may not obtain any mutexes also held
++ * by any callers of _mali_osk_timer_del(). Otherwise, a deadlock may occur.
++ *
++ * @param arg Function-specific data */
++typedef void (*_mali_osk_timer_callback_t)(void * arg );
++
++/** @brief Private type for Timer Callback Objects */
++typedef struct _mali_osk_timer_t_struct _mali_osk_timer_t;
++/** @} */ /* end group _mali_osk_timer */
++
++
++/** @addtogroup _mali_osk_list OSK Doubly-Linked Circular Lists
++ * @{ */
++
++/** @brief Public List objects.
++ *
++ * To use, add a _mali_osk_list_t member to the structure that may become part
++ * of a list. When traversing the _mali_osk_list_t objects, use the
++ * _MALI_OSK_CONTAINER_OF() macro to recover the structure from its
++ *_mali_osk_list_t member
++ *
++ * Each structure may have multiple _mali_osk_list_t members, so that the
++ * structure is part of multiple lists. When traversing lists, ensure that the
++ * correct _mali_osk_list_t member is used, because type-checking will be
++ * lost by the compiler.
++ */
++typedef struct _mali_osk_list_s
++{
++      struct _mali_osk_list_s *next;
++      struct _mali_osk_list_s *prev;
++} _mali_osk_list_t;
++
++/** @brief Initialize a list to be a head of an empty list
++ * @param exp the list to initialize. */
++#define _MALI_OSK_INIT_LIST_HEAD(exp) _mali_osk_list_init(exp)
++
++/** @brief Define a list variable, which is uninitialized.
++ * @param exp the name of the variable that the list will be defined as. */
++#define _MALI_OSK_LIST_HEAD(exp)      _mali_osk_list_t exp
++
++/** @brief Define a list variable, which is initialized.
++ * @param exp the name of the variable that the list will be defined as. */
++#define _MALI_OSK_LIST_HEAD_STATIC_INIT(exp) _mali_osk_list_t exp = { &exp, &exp }
++
++/** @brief Find the containing structure of another structure
++ *
++ * This is the reverse of the operation 'offsetof'. This means that the
++ * following condition is satisfied:
++ *
++ *   ptr == _MALI_OSK_CONTAINER_OF( &ptr->member, type, member )
++ *
++ * When ptr is of type 'type'.
++ *
++ * Its purpose it to recover a larger structure that has wrapped a smaller one.
++ *
++ * @note no type or memory checking occurs to ensure that a wrapper structure
++ * does in fact exist, and that it is being recovered with respect to the
++ * correct member.
++ *
++ * @param ptr the pointer to the member that is contained within the larger
++ * structure
++ * @param type the type of the structure that contains the member
++ * @param member the name of the member in the structure that ptr points to.
++ * @return a pointer to a \a type object which contains \a member, as pointed
++ * to by \a ptr.
++ */
++#define _MALI_OSK_CONTAINER_OF(ptr, type, member) \
++             ((type *)( ((char *)ptr) - offsetof(type,member) ))
++
++/** @brief Find the containing structure of a list
++ *
++ * When traversing a list, this is used to recover the containing structure,
++ * given that is contains a _mali_osk_list_t member.
++ *
++ * Each list must be of structures of one type, and must link the same members
++ * together, otherwise it will not be possible to correctly recover the
++ * sturctures that the lists link.
++ *
++ * @note no type or memory checking occurs to ensure that a structure does in
++ * fact exist for the list entry, and that it is being recovered with respect
++ * to the correct list member.
++ *
++ * @param ptr the pointer to the _mali_osk_list_t member in this structure
++ * @param type the type of the structure that contains the member
++ * @param member the member of the structure that ptr points to.
++ * @return a pointer to a \a type object which contains the _mali_osk_list_t
++ * \a member, as pointed to by the _mali_osk_list_t \a *ptr.
++ */
++#define _MALI_OSK_LIST_ENTRY(ptr, type, member) \
++            _MALI_OSK_CONTAINER_OF(ptr, type, member)
++
++/** @brief Enumerate a list safely
++ *
++ * With this macro, lists can be enumerated in a 'safe' manner. That is,
++ * entries can be deleted from the list without causing an error during
++ * enumeration. To achieve this, a 'temporary' pointer is required, which must
++ * be provided to the macro.
++ *
++ * Use it like a 'for()', 'while()' or 'do()' construct, and so it must be
++ * followed by a statement or compound-statement which will be executed for
++ * each list entry.
++ *
++ * Upon loop completion, providing that an early out was not taken in the
++ * loop body, then it is guaranteed that ptr->member == list, even if the loop
++ * body never executed.
++ *
++ * @param ptr a pointer to an object of type 'type', which points to the
++ * structure that contains the currently enumerated list entry.
++ * @param tmp a pointer to an object of type 'type', which must not be used
++ * inside the list-execution statement.
++ * @param list a pointer to a _mali_osk_list_t, from which enumeration will
++ * begin
++ * @param type the type of the structure that contains the _mali_osk_list_t
++ * member that is part of the list to be enumerated.
++ * @param member the _mali_osk_list_t member of the structure that is part of
++ * the list to be enumerated.
++ */
++#define _MALI_OSK_LIST_FOREACHENTRY(ptr, tmp, list, type, member)         \
++        for (ptr = _MALI_OSK_LIST_ENTRY((list)->next, type, member),      \
++             tmp = _MALI_OSK_LIST_ENTRY(ptr->member.next, type, member); \
++             &ptr->member != (list);                                    \
++             ptr = tmp, tmp = _MALI_OSK_LIST_ENTRY(tmp->member.next, type, member))
++/** @} */ /* end group _mali_osk_list */
++
++
++/** @addtogroup _mali_osk_miscellaneous
++ * @{ */
++
++/** @brief resource description struct
++ *
++ * Platform independent representation of a Mali HW resource
++ */
++typedef struct _mali_osk_resource
++{
++      const char * description;       /**< short description of the resource */
++      u32 base;                       /**< Physical base address of the resource, as seen by Mali resources. */
++      u32 irq;                        /**< IRQ number delivered to the CPU, or -1 to tell the driver to probe for it (if possible) */
++} _mali_osk_resource_t;
++/** @} */ /* end group _mali_osk_miscellaneous */
++
++
++#include "mali_kernel_memory_engine.h"   /* include for mali_memory_allocation and mali_physical_memory_allocation type */
++
++/** @addtogroup _mali_osk_wq
++ * @{ */
++
++/** @brief Initialize work queues (for deferred work)
++ *
++ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
++ */
++_mali_osk_errcode_t _mali_osk_wq_init(void);
++
++/** @brief Terminate work queues (for deferred work)
++ */
++void _mali_osk_wq_term(void);
++
++/** @brief Create work in the work queue
++ *
++ * Creates a work object which can be scheduled in the work queue. When
++ * scheduled, \a handler will be called with \a data as the argument.
++ *
++ * Refer to \ref _mali_osk_wq_schedule_work() for details on how work
++ * is scheduled in the queue.
++ *
++ * The returned pointer must be freed with \ref _mali_osk_wq_delete_work()
++ * when no longer needed.
++ */
++_mali_osk_wq_work_t *_mali_osk_wq_create_work( _mali_osk_wq_work_handler_t handler, void *data );
++
++/** @brief Delete a work object
++ *
++ * This will flush the work queue to ensure that the work handler will not
++ * be called after deletion.
++ */
++void _mali_osk_wq_delete_work( _mali_osk_wq_work_t *work );
++
++/** @brief Cause a queued, deferred call of the work handler
++ *
++ * _mali_osk_wq_schedule_work provides a mechanism for enqueuing deferred calls
++ * to the work handler. After calling \ref _mali_osk_wq_schedule_work(), the
++ * work handler will be scheduled to run at some point in the future.
++ *
++ * Typically this is called by the IRQ upper-half to defer further processing of
++ * IRQ-related work to the IRQ bottom-half handler. This is necessary for work
++ * that cannot be done in an IRQ context by the IRQ upper-half handler. Timer
++ * callbacks also use this mechanism, because they are treated as though they
++ * operate in an IRQ context. Refer to \ref _mali_osk_timer_t for more
++ * information.
++ *
++ * Code that operates in a kernel-process context (with no IRQ context
++ * restrictions) may also enqueue deferred calls to the IRQ bottom-half. The
++ * advantage over direct calling is that deferred calling allows the caller and
++ * IRQ bottom half to hold the same mutex, with a guarantee that they will not
++ * deadlock just by using this mechanism.
++ *
++ * _mali_osk_wq_schedule_work() places deferred call requests on a queue, to
++ * allow for more than one thread to make a deferred call. Therfore, if it is
++ * called 'K' times, then the IRQ bottom-half will be scheduled 'K' times too.
++ * 'K' is a number that is implementation-specific.
++ *
++ * _mali_osk_wq_schedule_work() is guaranteed to not block on:
++ * - enqueuing a deferred call request.
++ * - the completion of the work handler.
++ *
++ * This is to prevent deadlock. For example, if _mali_osk_wq_schedule_work()
++ * blocked, then it would cause a deadlock when the following two conditions
++ * hold:
++ * - The work handler callback (of type _mali_osk_wq_work_handler_t) locks
++ * a mutex
++ * - And, at the same time, the caller of _mali_osk_wq_schedule_work() also
++ * holds the same mutex
++ *
++ * @note care must be taken to not overflow the queue that
++ * _mali_osk_wq_schedule_work() operates on. Code must be structured to
++ * ensure that the number of requests made to the queue is bounded. Otherwise,
++ * work will be lost.
++ *
++ * The queue that _mali_osk_wq_schedule_work implements is a FIFO of N-writer,
++ * 1-reader type. The writers are the callers of _mali_osk_wq_schedule_work
++ * (all OSK-registered IRQ upper-half handlers in the system, watchdog timers,
++ * callers from a Kernel-process context). The reader is a single thread that
++ * handles all OSK-registered work.
++ *
++ * @param work a pointer to the _mali_osk_wq_work_t object corresponding to the
++ * work to begin processing.
++ */
++void _mali_osk_wq_schedule_work( _mali_osk_wq_work_t *work );
++
++/** @brief Flush the work queue
++ *
++ * This will flush the OSK work queue, ensuring all work in the queue has
++ * completed before returning.
++ *
++ * Since this blocks on the completion of work in the work-queue, the
++ * caller of this function \b must \b not hold any mutexes that are taken by
++ * any registered work handler. To do so may cause a deadlock.
++ *
++ */
++void _mali_osk_wq_flush(void);
++
++
++/** @} */ /* end group _mali_osk_wq */
++
++/** @addtogroup _mali_osk_irq
++ * @{ */
++
++/** @brief Initialize IRQ handling for a resource
++ *
++ * Registers an interrupt handler \a uhandler for the given IRQ number \a irqnum.
++ * \a data will be passed as argument to the handler when an interrupt occurs.
++ *
++ * If \a irqnum is -1, _mali_osk_irq_init will probe for the IRQ number using
++ * the supplied \a trigger_func and \a ack_func. These functions will also
++ * receive \a data as their argument.
++ *
++ * @param irqnum The IRQ number that the resource uses, as seen by the CPU.
++ * The value -1 has a special meaning which indicates the use of probing, and
++ * trigger_func and ack_func must be non-NULL.
++ * @param uhandler The interrupt handler, corresponding to a ISR handler for
++ * the resource
++ * @param int_data resource specific data, which will be passed to uhandler
++ * @param trigger_func Optional: a function to trigger the resource's irq, to
++ * probe for the interrupt. Use NULL if irqnum != -1.
++ * @param ack_func Optional: a function to acknowledge the resource's irq, to
++ * probe for the interrupt. Use NULL if irqnum != -1.
++ * @param probe_data resource-specific data, which will be passed to
++ * (if present) trigger_func and ack_func
++ * @param description textual description of the IRQ resource.
++ * @return on success, a pointer to a _mali_osk_irq_t object, which represents
++ * the IRQ handling on this resource. NULL on failure.
++ */
++_mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandler, void *int_data, _mali_osk_irq_trigger_t trigger_func, _mali_osk_irq_ack_t ack_func, void *probe_data, const char *description );
++
++/** @brief Terminate IRQ handling on a resource.
++ *
++ * This will disable the interrupt from the device, and then waits for any
++ * currently executing IRQ handlers to complete.
++ *
++ * @note If work is deferred to an IRQ bottom-half handler through
++ * \ref _mali_osk_wq_schedule_work(), be sure to flush any remaining work
++ * with \ref _mali_osk_wq_flush() or (implicitly) with \ref _mali_osk_wq_delete_work()
++ *
++ * @param irq a pointer to the _mali_osk_irq_t object corresponding to the
++ * resource whose IRQ handling is to be terminated.
++ */
++void _mali_osk_irq_term( _mali_osk_irq_t *irq );
++
++/** @} */ /* end group _mali_osk_irq */
++
++
++/** @addtogroup _mali_osk_atomic
++ * @{ */
++
++/** @brief Decrement an atomic counter
++ *
++ * @note It is an error to decrement the counter beyond -(1<<23)
++ *
++ * @param atom pointer to an atomic counter */
++void _mali_osk_atomic_dec( _mali_osk_atomic_t *atom );
++
++/** @brief Decrement an atomic counter, return new value
++ *
++ * @param atom pointer to an atomic counter
++ * @return The new value, after decrement */
++u32 _mali_osk_atomic_dec_return( _mali_osk_atomic_t *atom );
++
++/** @brief Increment an atomic counter
++ *
++ * @note It is an error to increment the counter beyond (1<<23)-1
++ *
++ * @param atom pointer to an atomic counter */
++void _mali_osk_atomic_inc( _mali_osk_atomic_t *atom );
++
++/** @brief Increment an atomic counter, return new value
++ *
++ * @param atom pointer to an atomic counter */
++u32 _mali_osk_atomic_inc_return( _mali_osk_atomic_t *atom );
++
++/** @brief Initialize an atomic counter
++ *
++ * @note the parameter required is a u32, and so signed integers should be
++ * cast to u32.
++ *
++ * @param atom pointer to an atomic counter
++ * @param val the value to initialize the atomic counter.
++ * @return _MALI_OSK_ERR_OK on success, otherwise, a suitable
++ * _mali_osk_errcode_t on failure.
++ */
++_mali_osk_errcode_t _mali_osk_atomic_init( _mali_osk_atomic_t *atom, u32 val );
++
++/** @brief Read a value from an atomic counter
++ *
++ * This can only be safely used to determine the value of the counter when it
++ * is guaranteed that other threads will not be modifying the counter. This
++ * makes its usefulness limited.
++ *
++ * @param atom pointer to an atomic counter
++ */
++u32 _mali_osk_atomic_read( _mali_osk_atomic_t *atom );
++
++/** @brief Terminate an atomic counter
++ *
++ * @param atom pointer to an atomic counter
++ */
++void _mali_osk_atomic_term( _mali_osk_atomic_t *atom );
++/** @} */  /* end group _mali_osk_atomic */
++
++
++/** @defgroup _mali_osk_memory OSK Memory Allocation
++ * @{ */
++
++/** @brief Allocate zero-initialized memory.
++ *
++ * Returns a buffer capable of containing at least \a n elements of \a size
++ * bytes each. The buffer is initialized to zero.
++ *
++ * If there is a need for a bigger block of memory (16KB or bigger), then
++ * consider to use _mali_osk_vmalloc() instead, as this function might
++ * map down to a OS function with size limitations.
++ *
++ * The buffer is suitably aligned for storage and subsequent access of every
++ * type that the compiler supports. Therefore, the pointer to the start of the
++ * buffer may be cast into any pointer type, and be subsequently accessed from
++ * such a pointer, without loss of information.
++ *
++ * When the buffer is no longer in use, it must be freed with _mali_osk_free().
++ * Failure to do so will cause a memory leak.
++ *
++ * @note Most toolchains supply memory allocation functions that meet the
++ * compiler's alignment requirements.
++ *
++ * @param n Number of elements to allocate
++ * @param size Size of each element
++ * @return On success, the zero-initialized buffer allocated. NULL on failure
++ */
++void *_mali_osk_calloc( u32 n, u32 size );
++
++/** @brief Allocate memory.
++ *
++ * Returns a buffer capable of containing at least \a size bytes. The
++ * contents of the buffer are undefined.
++ *
++ * If there is a need for a bigger block of memory (16KB or bigger), then
++ * consider to use _mali_osk_vmalloc() instead, as this function might
++ * map down to a OS function with size limitations.
++ *
++ * The buffer is suitably aligned for storage and subsequent access of every
++ * type that the compiler supports. Therefore, the pointer to the start of the
++ * buffer may be cast into any pointer type, and be subsequently accessed from
++ * such a pointer, without loss of information.
++ *
++ * When the buffer is no longer in use, it must be freed with _mali_osk_free().
++ * Failure to do so will cause a memory leak.
++ *
++ * @note Most toolchains supply memory allocation functions that meet the
++ * compiler's alignment requirements.
++ *
++ * Remember to free memory using _mali_osk_free().
++ * @param size Number of bytes to allocate
++ * @return On success, the buffer allocated. NULL on failure.
++ */
++void *_mali_osk_malloc( u32 size );
++
++/** @brief Free memory.
++ *
++ * Reclaims the buffer pointed to by the parameter \a ptr for the system.
++ * All memory returned from _mali_osk_malloc() and _mali_osk_calloc()
++ * must be freed before the application exits. Otherwise,
++ * a memory leak will occur.
++ *
++ * Memory must be freed once. It is an error to free the same non-NULL pointer
++ * more than once.
++ *
++ * It is legal to free the NULL pointer.
++ *
++ * @param ptr Pointer to buffer to free
++ */
++void _mali_osk_free( void *ptr );
++
++/** @brief Allocate memory.
++ *
++ * Returns a buffer capable of containing at least \a size bytes. The
++ * contents of the buffer are undefined.
++ *
++ * This function is potentially slower than _mali_osk_malloc() and _mali_osk_calloc(),
++ * but do support bigger sizes.
++ *
++ * The buffer is suitably aligned for storage and subsequent access of every
++ * type that the compiler supports. Therefore, the pointer to the start of the
++ * buffer may be cast into any pointer type, and be subsequently accessed from
++ * such a pointer, without loss of information.
++ *
++ * When the buffer is no longer in use, it must be freed with _mali_osk_free().
++ * Failure to do so will cause a memory leak.
++ *
++ * @note Most toolchains supply memory allocation functions that meet the
++ * compiler's alignment requirements.
++ *
++ * Remember to free memory using _mali_osk_free().
++ * @param size Number of bytes to allocate
++ * @return On success, the buffer allocated. NULL on failure.
++ */
++void *_mali_osk_valloc( u32 size );
++
++/** @brief Free memory.
++ *
++ * Reclaims the buffer pointed to by the parameter \a ptr for the system.
++ * All memory returned from _mali_osk_valloc() must be freed before the
++ * application exits. Otherwise a memory leak will occur.
++ *
++ * Memory must be freed once. It is an error to free the same non-NULL pointer
++ * more than once.
++ *
++ * It is legal to free the NULL pointer.
++ *
++ * @param ptr Pointer to buffer to free
++ */
++void _mali_osk_vfree( void *ptr );
++
++/** @brief Copies memory.
++ *
++ * Copies the \a len bytes from the buffer pointed by the parameter \a src
++ * directly to the buffer pointed by \a dst.
++ *
++ * It is an error for \a src to overlap \a dst anywhere in \a len bytes.
++ *
++ * @param dst Pointer to the destination array where the content is to be
++ * copied.
++ * @param src Pointer to the source of data to be copied.
++ * @param len Number of bytes to copy.
++ * @return \a dst is always passed through unmodified.
++ */
++void *_mali_osk_memcpy( void *dst, const void *src, u32 len );
++
++/** @brief Fills memory.
++ *
++ * Sets the first \a n bytes of the block of memory pointed to by \a s to
++ * the specified value
++ * @param s Pointer to the block of memory to fill.
++ * @param c Value to be set, passed as u32. Only the 8 Least Significant Bits (LSB)
++ * are used.
++ * @param n Number of bytes to be set to the value.
++ * @return \a s is always passed through unmodified
++ */
++void *_mali_osk_memset( void *s, u32 c, u32 n );
++/** @} */ /* end group _mali_osk_memory */
++
++
++/** @brief Checks the amount of memory allocated
++ *
++ * Checks that not more than \a max_allocated bytes are allocated.
++ *
++ * Some OS bring up an interactive out of memory dialogue when the
++ * system runs out of memory. This can stall non-interactive
++ * apps (e.g. automated test runs). This function can be used to
++ * not trigger the OOM dialogue by keeping allocations
++ * within a certain limit.
++ *
++ * @return MALI_TRUE when \a max_allocated bytes are not in use yet. MALI_FALSE
++ * when at least \a max_allocated bytes are in use.
++ */
++mali_bool _mali_osk_mem_check_allocated( u32 max_allocated );
++
++/** @addtogroup _mali_osk_lock
++ * @{ */
++
++/** @brief Initialize a Mutual Exclusion Lock
++ *
++ * Locks are created in the signalled (unlocked) state.
++ *
++ * initial must be zero, since there is currently no means of expressing
++ * whether a reader/writer lock should be initially locked as a reader or
++ * writer. This would require some encoding to be used.
++ *
++ * 'Automatic' ordering means that locks must be obtained in the order that
++ * they were created. For all locks that can be held at the same time, they must
++ * either all provide the order parameter, or they all must use 'automatic'
++ * ordering - because there is no way of mixing 'automatic' and 'manual'
++ * ordering.
++ *
++ * @param flags flags combined with bitwise OR ('|'), or zero. There are
++ * restrictions on which flags can be combined, @see _mali_osk_lock_flags_t.
++ * @param initial For future expansion into semaphores. SBZ.
++ * @param order The locking order of the mutex. That is, locks obtained by the
++ * same thread must have been created with an increasing order parameter, for
++ * deadlock prevention. Setting to zero causes 'automatic' ordering to be used.
++ * @return On success, a pointer to a _mali_osk_lock_t object. NULL on failure.
++ */
++_mali_osk_lock_t *_mali_osk_lock_init( _mali_osk_lock_flags_t flags, u32 initial, u32 order );
++
++/** @brief Wait for a lock to be signalled (obtained)
++
++ * After a thread has successfully waited on the lock, the lock is obtained by
++ * the thread, and is marked as unsignalled. The thread releases the lock by
++ * signalling it.
++ *
++ * In the case of Reader/Writer locks, multiple readers can obtain a lock in
++ * the absence of writers, which is a performance optimization (providing that
++ * the readers never write to the protected resource).
++ *
++ * To prevent deadlock, locks must always be obtained in the same order.
++ *
++ * For locks marked as _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, it is a
++ * programming error for the function to exit without obtaining the lock. This
++ * means that the error code must only be checked for interruptible locks.
++ *
++ * @param lock the lock to wait upon (obtain).
++ * @param mode the mode in which the lock should be obtained. Unless the lock
++ * was created with _MALI_OSK_LOCKFLAG_READERWRITER, this must be
++ * _MALI_OSK_LOCKMODE_RW.
++ * @return On success, _MALI_OSK_ERR_OK. For interruptible locks, a suitable
++ * _mali_osk_errcode_t will be returned on failure, and the lock will not be
++ * obtained. In this case, the error code must be propagated up to the U/K
++ * interface.
++ */
++_mali_osk_errcode_t _mali_osk_lock_wait( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode);
++
++
++/** @brief Signal (release) a lock
++ *
++ * Locks may only be signalled by the thread that originally waited upon the
++ * lock.
++ *
++ * @note In the OSU, a flag exists to allow any thread to signal a
++ * lock. Such functionality is not present in the OSK.
++ *
++ * @param lock the lock to signal (release).
++ * @param mode the mode in which the lock should be obtained. This must match
++ * the mode in which the lock was waited upon.
++ */
++void _mali_osk_lock_signal( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode );
++
++/** @brief Terminate a lock
++ *
++ * This terminates a lock and frees all associated resources.
++ *
++ * It is a programming error to terminate the lock when it is held (unsignalled)
++ * by a thread.
++ *
++ * @param lock the lock to terminate.
++ */
++void _mali_osk_lock_term( _mali_osk_lock_t *lock );
++/** @} */ /* end group _mali_osk_lock */
++
++
++/** @addtogroup _mali_osk_low_level_memory
++ * @{ */
++
++/** @brief Issue a memory barrier
++ *
++ * This defines an arbitrary memory barrier operation, which forces an ordering constraint
++ * on memory read and write operations.
++ */
++void _mali_osk_mem_barrier( void );
++
++/** @brief Issue a write memory barrier
++ *
++ * This defines an write memory barrier operation which forces an ordering constraint
++ * on memory write operations.
++ */
++void _mali_osk_write_mem_barrier( void );
++
++/** @brief Map a physically contiguous region into kernel space
++ *
++ * This is primarily used for mapping in registers from resources, and Mali-MMU
++ * page tables. The mapping is only visable from kernel-space.
++ *
++ * Access has to go through _mali_osk_mem_ioread32 and _mali_osk_mem_iowrite32
++ *
++ * @param phys CPU-physical base address of the memory to map in. This must
++ * be aligned to the system's page size, which is assumed to be 4K.
++ * @param size the number of bytes of physically contiguous address space to
++ * map in
++ * @param description A textual description of the memory being mapped in.
++ * @return On success, a Mali IO address through which the mapped-in
++ * memory/registers can be accessed. NULL on failure.
++ */
++mali_io_address _mali_osk_mem_mapioregion( u32 phys, u32 size, const char *description );
++
++/** @brief Unmap a physically contiguous address range from kernel space.
++ *
++ * The address range should be one previously mapped in through
++ * _mali_osk_mem_mapioregion.
++ *
++ * It is a programming error to do (but not limited to) the following:
++ * - attempt an unmap twice
++ * - unmap only part of a range obtained through _mali_osk_mem_mapioregion
++ * - unmap more than the range obtained through  _mali_osk_mem_mapioregion
++ * - unmap an address range that was not successfully mapped using
++ * _mali_osk_mem_mapioregion
++ * - provide a mapping that does not map to phys.
++ *
++ * @param phys CPU-physical base address of the memory that was originally
++ * mapped in. This must be aligned to the system's page size, which is assumed
++ * to be 4K
++ * @param size The number of bytes that were originally mapped in.
++ * @param mapping The Mali IO address through which the mapping is
++ * accessed.
++ */
++void _mali_osk_mem_unmapioregion( u32 phys, u32 size, mali_io_address mapping );
++
++/** @brief Allocate and Map a physically contiguous region into kernel space
++ *
++ * This is used for allocating physically contiguous regions (such as Mali-MMU
++ * page tables) and mapping them into kernel space. The mapping is only
++ * visible from kernel-space.
++ *
++ * The alignment of the returned memory is guaranteed to be at least
++ * _MALI_OSK_CPU_PAGE_SIZE.
++ *
++ * Access must go through _mali_osk_mem_ioread32 and _mali_osk_mem_iowrite32
++ *
++ * @note This function is primarily to provide support for OSs that are
++ * incapable of separating the tasks 'allocate physically contiguous memory'
++ * and 'map it into kernel space'
++ *
++ * @param[out] phys CPU-physical base address of memory that was allocated.
++ * (*phys) will be guaranteed to be aligned to at least
++ * _MALI_OSK_CPU_PAGE_SIZE on success.
++ *
++ * @param[in] size the number of bytes of physically contiguous memory to
++ * allocate. This must be a multiple of _MALI_OSK_CPU_PAGE_SIZE.
++ *
++ * @return On success, a Mali IO address through which the mapped-in
++ * memory/registers can be accessed. NULL on failure, and (*phys) is unmodified.
++ */
++mali_io_address _mali_osk_mem_allocioregion( u32 *phys, u32 size );
++
++/** @brief Free a physically contiguous address range from kernel space.
++ *
++ * The address range should be one previously mapped in through
++ * _mali_osk_mem_allocioregion.
++ *
++ * It is a programming error to do (but not limited to) the following:
++ * - attempt a free twice on the same ioregion
++ * - free only part of a range obtained through _mali_osk_mem_allocioregion
++ * - free more than the range obtained through  _mali_osk_mem_allocioregion
++ * - free an address range that was not successfully mapped using
++ * _mali_osk_mem_allocioregion
++ * - provide a mapping that does not map to phys.
++ *
++ * @param phys CPU-physical base address of the memory that was originally
++ * mapped in, which was aligned to _MALI_OSK_CPU_PAGE_SIZE.
++ * @param size The number of bytes that were originally mapped in, which was
++ * a multiple of _MALI_OSK_CPU_PAGE_SIZE.
++ * @param mapping The Mali IO address through which the mapping is
++ * accessed.
++ */
++void _mali_osk_mem_freeioregion( u32 phys, u32 size, mali_io_address mapping );
++
++/** @brief Request a region of physically contiguous memory
++ *
++ * This is used to ensure exclusive access to a region of physically contigous
++ * memory.
++ *
++ * It is acceptable to implement this as a stub. However, it is then the job
++ * of the System Integrator to ensure that no other device driver will be using
++ * the physical address ranges used by Mali, while the Mali device driver is
++ * loaded.
++ *
++ * @param phys CPU-physical base address of the memory to request. This must
++ * be aligned to the system's page size, which is assumed to be 4K.
++ * @param size the number of bytes of physically contiguous address space to
++ * request.
++ * @param description A textual description of the memory being requested.
++ * @return _MALI_OSK_ERR_OK on success. Otherwise, a suitable
++ * _mali_osk_errcode_t on failure.
++ */
++_mali_osk_errcode_t _mali_osk_mem_reqregion( u32 phys, u32 size, const char *description );
++
++/** @brief Un-request a region of physically contiguous memory
++ *
++ * This is used to release a regious of physically contiguous memory previously
++ * requested through _mali_osk_mem_reqregion, so that other device drivers may
++ * use it. This will be called at time of Mali device driver termination.
++ *
++ * It is a programming error to attempt to:
++ * - unrequest a region twice
++ * - unrequest only part of a range obtained through _mali_osk_mem_reqregion
++ * - unrequest more than the range obtained through  _mali_osk_mem_reqregion
++ * - unrequest an address range that was not successfully requested using
++ * _mali_osk_mem_reqregion
++ *
++ * @param phys CPU-physical base address of the memory to un-request. This must
++ * be aligned to the system's page size, which is assumed to be 4K
++ * @param size the number of bytes of physically contiguous address space to
++ * un-request.
++ */
++void _mali_osk_mem_unreqregion( u32 phys, u32 size );
++
++/** @brief Read from a location currently mapped in through
++ * _mali_osk_mem_mapioregion
++ *
++ * This reads a 32-bit word from a 32-bit aligned location. It is a programming
++ * error to provide unaligned locations, or to read from memory that is not
++ * mapped in, or not mapped through either _mali_osk_mem_mapioregion() or
++ * _mali_osk_mem_allocioregion().
++ *
++ * @param mapping Mali IO address to read from
++ * @param offset Byte offset from the given IO address to operate on, must be a multiple of 4
++ * @return the 32-bit word from the specified location.
++ */
++u32 _mali_osk_mem_ioread32( volatile mali_io_address mapping, u32 offset );
++#ifdef CONFIG_SLP_MALI_DBG
++u32 _mali_osk_mem_ioread32_cpu( volatile mali_io_address mapping, u32 offset );
++#endif
++
++/** @brief Write to a location currently mapped in through
++ * _mali_osk_mem_mapioregion without memory barriers
++ *
++ * This write a 32-bit word to a 32-bit aligned location without using memory barrier.
++ * It is a programming error to provide unaligned locations, or to write to memory that is not
++ * mapped in, or not mapped through either _mali_osk_mem_mapioregion() or
++ * _mali_osk_mem_allocioregion().
++ *
++ * @param mapping Mali IO address to write to
++ * @param offset Byte offset from the given IO address to operate on, must be a multiple of 4
++ * @param val the 32-bit word to write.
++ */
++void _mali_osk_mem_iowrite32_relaxed( volatile mali_io_address addr, u32 offset, u32 val );
++#ifdef CONFIG_SLP_MALI_DBG
++void _mali_osk_mem_iowrite32_relaxed_cpu( volatile mali_io_address addr, u32 offset, u32 val );
++#endif
++
++/** @brief Write to a location currently mapped in through
++ * _mali_osk_mem_mapioregion with write memory barrier
++ *
++ * This write a 32-bit word to a 32-bit aligned location. It is a programming
++ * error to provide unaligned locations, or to write to memory that is not
++ * mapped in, or not mapped through either _mali_osk_mem_mapioregion() or
++ * _mali_osk_mem_allocioregion().
++ *
++ * @param mapping Mali IO address to write to
++ * @param offset Byte offset from the given IO address to operate on, must be a multiple of 4
++ * @param val the 32-bit word to write.
++ */
++void _mali_osk_mem_iowrite32( volatile mali_io_address mapping, u32 offset, u32 val );
++
++/** @brief Flush all CPU caches
++ *
++ * This should only be implemented if flushing of the cache is required for
++ * memory mapped in through _mali_osk_mem_mapregion.
++ */
++void _mali_osk_cache_flushall( void );
++
++/** @brief Flush any caches necessary for the CPU and MALI to have the same view of a range of uncached mapped memory
++ *
++ * This should only be implemented if your OS doesn't do a full cache flush (inner & outer)
++ * after allocating uncached mapped memory.
++ *
++ * Some OS do not perform a full cache flush (including all outer caches) for uncached mapped memory.
++ * They zero the memory through a cached mapping, then flush the inner caches but not the outer caches.
++ * This is required for MALI to have the correct view of the memory.
++ */
++void _mali_osk_cache_ensure_uncached_range_flushed( void *uncached_mapping, u32 offset, u32 size );
++
++/** @} */ /* end group _mali_osk_low_level_memory */
++
++
++/** @addtogroup _mali_osk_notification
++ *
++ * User space notification framework
++ *
++ * Communication with user space of asynchronous events is performed through a
++ * synchronous call to the \ref u_k_api.
++ *
++ * Since the events are asynchronous, the events have to be queued until a
++ * synchronous U/K API call can be made by user-space. A U/K API call might also
++ * be received before any event has happened. Therefore the notifications the
++ * different subsystems wants to send to user space has to be queued for later
++ * reception, or a U/K API call has to be blocked until an event has occured.
++ *
++ * Typical uses of notifications are after running of jobs on the hardware or
++ * when changes to the system is detected that needs to be relayed to user
++ * space.
++ *
++ * After an event has occured user space has to be notified using some kind of
++ * message. The notification framework supports sending messages to waiting
++ * threads or queueing of messages until a U/K API call is made.
++ *
++ * The notification queue is a FIFO. There are no restrictions on the numbers
++ * of readers or writers in the queue.
++ *
++ * A message contains what user space needs to identifiy how to handle an
++ * event. This includes a type field and a possible type specific payload.
++ *
++ * A notification to user space is represented by a
++ * \ref _mali_osk_notification_t object. A sender gets hold of such an object
++ * using _mali_osk_notification_create(). The buffer given by the
++ * _mali_osk_notification_t::result_buffer field in the object is used to store
++ * any type specific data. The other fields are internal to the queue system
++ * and should not be touched.
++ *
++ * @{ */
++
++/** @brief Create a notification object
++ *
++ * Returns a notification object which can be added to the queue of
++ * notifications pending for user space transfer.
++ *
++ * The implementation will initialize all members of the
++ * \ref _mali_osk_notification_t object. In particular, the
++ * _mali_osk_notification_t::result_buffer member will be initialized to point
++ * to \a size bytes of storage, and that storage will be suitably aligned for
++ * storage of any structure. That is, the created buffer meets the same
++ * requirements as _mali_osk_malloc().
++ *
++ * The notification object must be deleted when not in use. Use
++ * _mali_osk_notification_delete() for deleting it.
++ *
++ * @note You \b must \b not call _mali_osk_free() on a \ref _mali_osk_notification_t,
++ * object, or on a _mali_osk_notification_t::result_buffer. You must only use
++ * _mali_osk_notification_delete() to free the resources assocaited with a
++ * \ref _mali_osk_notification_t object.
++ *
++ * @param type The notification type
++ * @param size The size of the type specific buffer to send
++ * @return Pointer to a notification object with a suitable buffer, or NULL on error.
++ */
++_mali_osk_notification_t *_mali_osk_notification_create( u32 type, u32 size );
++
++/** @brief Delete a notification object
++ *
++ * This must be called to reclaim the resources of a notification object. This
++ * includes:
++ * - The _mali_osk_notification_t::result_buffer
++ * - The \ref _mali_osk_notification_t itself.
++ *
++ * A notification object \b must \b not be used after it has been deleted by
++ * _mali_osk_notification_delete().
++ *
++ * In addition, the notification object may not be deleted while it is in a
++ * queue. That is, if it has been placed on a queue with
++ * _mali_osk_notification_queue_send(), then it must not be deleted until
++ * it has been received by a call to _mali_osk_notification_queue_receive().
++ * Otherwise, the queue may be corrupted.
++ *
++ * @param object the notification object to delete.
++ */
++void _mali_osk_notification_delete( _mali_osk_notification_t *object );
++
++/** @brief Create a notification queue
++ *
++ * Creates a notification queue which can be used to queue messages for user
++ * delivery and get queued messages from
++ *
++ * The queue is a FIFO, and has no restrictions on the numbers of readers or
++ * writers.
++ *
++ * When the queue is no longer in use, it must be terminated with
++ * \ref _mali_osk_notification_queue_term(). Failure to do so will result in a
++ * memory leak.
++ *
++ * @return Pointer to a new notification queue or NULL on error.
++ */
++_mali_osk_notification_queue_t *_mali_osk_notification_queue_init( void );
++
++/** @brief Destroy a notification queue
++ *
++ * Destroys a notification queue and frees associated resources from the queue.
++ *
++ * A notification queue \b must \b not be destroyed in the following cases:
++ * - while there are \ref _mali_osk_notification_t objects in the queue.
++ * - while there are writers currently acting upon the queue. That is, while
++ * a thread is currently calling \ref _mali_osk_notification_queue_send() on
++ * the queue, or while a thread may call
++ * \ref _mali_osk_notification_queue_send() on the queue in the future.
++ * - while there are readers currently waiting upon the queue. That is, while
++ * a thread is currently calling \ref _mali_osk_notification_queue_receive() on
++ * the queue, or while a thread may call
++ * \ref _mali_osk_notification_queue_receive() on the queue in the future.
++ *
++ * Therefore, all \ref _mali_osk_notification_t objects must be flushed and
++ * deleted by the code that makes use of the notification queues, since only
++ * they know the structure of the _mali_osk_notification_t::result_buffer
++ * (even if it may only be a flat sturcture).
++ *
++ * @note Since the queue is a FIFO, the code using notification queues may
++ * create its own 'flush' type of notification, to assist in flushing the
++ * queue.
++ *
++ * Once the queue has been destroyed, it must not be used again.
++ *
++ * @param queue The queue to destroy
++ */
++void _mali_osk_notification_queue_term( _mali_osk_notification_queue_t *queue );
++
++/** @brief Schedule notification for delivery
++ *
++ * When a \ref _mali_osk_notification_t object has been created successfully
++ * and set up, it may be added to the queue of objects waiting for user space
++ * transfer.
++ *
++ * The sending will not block if the queue is full.
++ *
++ * A \ref _mali_osk_notification_t object \b must \b not be put on two different
++ * queues at the same time, or enqueued twice onto a single queue before
++ * reception. However, it is acceptable for it to be requeued \em after reception
++ * from a call to _mali_osk_notification_queue_receive(), even onto the same queue.
++ *
++ * Again, requeuing must also not enqueue onto two different queues at the same
++ * time, or enqueue onto the same queue twice before reception.
++ *
++ * @param queue The notification queue to add this notification to
++ * @param object The entry to add
++ */
++void _mali_osk_notification_queue_send( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t *object );
++
++/** @brief Receive a notification from a queue
++ *
++ * Receives a single notification from the given queue.
++ *
++ * If no notifciations are ready the thread will sleep until one becomes ready.
++ * Therefore, notifications may not be received into an
++ * IRQ or 'atomic' context (that is, a context where sleeping is disallowed).
++ *
++ * @param queue The queue to receive from
++ * @param result Pointer to storage of a pointer of type
++ * \ref _mali_osk_notification_t*. \a result will be written to such that the
++ * expression \a (*result) will evaluate to a pointer to a valid
++ * \ref _mali_osk_notification_t object, or NULL if none were received.
++ * @return _MALI_OSK_ERR_OK on success. _MALI_OSK_ERR_RESTARTSYSCALL if the sleep was interrupted.
++ */
++_mali_osk_errcode_t _mali_osk_notification_queue_receive( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t **result );
++
++/** @brief Dequeues a notification from a queue
++ *
++ * Receives a single notification from the given queue.
++ *
++ * If no notifciations are ready the function call will return an error code.
++ *
++ * @param queue The queue to receive from
++ * @param result Pointer to storage of a pointer of type
++ * \ref _mali_osk_notification_t*. \a result will be written to such that the
++ * expression \a (*result) will evaluate to a pointer to a valid
++ * \ref _mali_osk_notification_t object, or NULL if none were received.
++ * @return _MALI_OSK_ERR_OK on success, _MALI_OSK_ERR_ITEM_NOT_FOUND if queue was empty.
++ */
++_mali_osk_errcode_t _mali_osk_notification_queue_dequeue( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t **result );
++
++/** @} */ /* end group _mali_osk_notification */
++
++
++/** @addtogroup _mali_osk_timer
++ *
++ * Timers use the OS's representation of time, which are 'ticks'. This is to
++ * prevent aliasing problems between the internal timer time, and the time
++ * asked for.
++ *
++ * @{ */
++
++/** @brief Initialize a timer
++ *
++ * Allocates resources for a new timer, and initializes them. This does not
++ * start the timer.
++ *
++ * @return a pointer to the allocated timer object, or NULL on failure.
++ */
++_mali_osk_timer_t *_mali_osk_timer_init(void);
++
++/** @brief Start a timer
++ *
++ * It is an error to start a timer without setting the callback via
++ * _mali_osk_timer_setcallback().
++ *
++ * It is an error to use this to start an already started timer.
++ *
++ * The timer will expire in \a ticks_to_expire ticks, at which point, the
++ * callback function will be invoked with the callback-specific data,
++ * as registered by _mali_osk_timer_setcallback().
++ *
++ * @param tim the timer to start
++ * @param ticks_to_expire the amount of time in ticks for the timer to run
++ * before triggering.
++ */
++void _mali_osk_timer_add( _mali_osk_timer_t *tim, u32 ticks_to_expire );
++
++/** @brief Modify a timer
++ *
++ * Set the relative time at which a timer will expire, and start it if it is
++ * stopped. If \a ticks_to_expire 0 the timer fires immediately.
++ *
++ * It is an error to modify a timer without setting the callback via
++ *  _mali_osk_timer_setcallback().
++ *
++ * The timer will expire at \a ticks_to_expire from the time of the call, at
++ * which point, the callback function will be invoked with the
++ * callback-specific data, as set by _mali_osk_timer_setcallback().
++ *
++ * @param tim the timer to modify, and start if necessary
++ * @param ticks_to_expire the \em absolute time in ticks at which this timer
++ * should trigger.
++ *
++ */
++void _mali_osk_timer_mod( _mali_osk_timer_t *tim, u32 ticks_to_expire);
++
++/** @brief Stop a timer, and block on its completion.
++ *
++ * Stop the timer. When the function returns, it is guaranteed that the timer's
++ * callback will not be running on any CPU core.
++ *
++ * Since stoping the timer blocks on compeletion of the callback, the callback
++ * may not obtain any mutexes that the caller holds. Otherwise, a deadlock will
++ * occur.
++ *
++ * @note While the callback itself is guaranteed to not be running, work
++ * enqueued on the work-queue by the timer (with
++ * \ref _mali_osk_wq_schedule_work()) may still run. The timer callback and
++ * work handler must take this into account.
++ *
++ * It is legal to stop an already stopped timer.
++ *
++ * @param tim the timer to stop.
++ *
++ */
++void _mali_osk_timer_del( _mali_osk_timer_t *tim );
++
++/** @brief Stop a timer.
++ *
++ * Stop the timer. When the function returns, the timer's callback may still be
++ * running on any CPU core.
++ *
++ * It is legal to stop an already stopped timer.
++ *
++ * @param tim the timer to stop.
++ */
++void _mali_osk_timer_del_async( _mali_osk_timer_t *tim );
++
++/** @brief Check if timer is pending.
++ *
++ * Check if timer is active.
++ *
++ * @param tim the timer to check
++ * @return MALI_TRUE if time is active, MALI_FALSE if it is not active
++ */
++mali_bool _mali_osk_timer_pending( _mali_osk_timer_t *tim);
++
++/** @brief Set a timer's callback parameters.
++ *
++ * This must be called at least once before a timer is started/modified.
++ *
++ * After a timer has been stopped or expires, the callback remains set. This
++ * means that restarting the timer will call the same function with the same
++ * parameters on expiry.
++ *
++ * @param tim the timer to set callback on.
++ * @param callback Function to call when timer expires
++ * @param data Function-specific data to supply to the function on expiry.
++ */
++void _mali_osk_timer_setcallback( _mali_osk_timer_t *tim, _mali_osk_timer_callback_t callback, void *data );
++
++/** @brief Terminate a timer, and deallocate resources.
++ *
++ * The timer must first be stopped by calling _mali_osk_timer_del().
++ *
++ * It is a programming error for _mali_osk_timer_term() to be called on:
++ * - timer that is currently running
++ * - a timer that is currently executing its callback.
++ *
++ * @param tim the timer to deallocate.
++ */
++void _mali_osk_timer_term( _mali_osk_timer_t *tim );
++/** @} */ /* end group _mali_osk_timer */
++
++
++/** @defgroup _mali_osk_time OSK Time functions
++ *
++ * \ref _mali_osk_time use the OS's representation of time, which are
++ * 'ticks'. This is to prevent aliasing problems between the internal timer
++ * time, and the time asked for.
++ *
++ * OS tick time is measured as a u32. The time stored in a u32 may either be
++ * an absolute time, or a time delta between two events. Whilst it is valid to
++ * use math opeartors to \em change the tick value represented as a u32, it
++ * is often only meaningful to do such operations on time deltas, rather than
++ * on absolute time. However, it is meaningful to add/subtract time deltas to
++ * absolute times.
++ *
++ * Conversion between tick time and milliseconds (ms) may not be loss-less,
++ * and are \em implementation \em depenedant.
++ *
++ * Code use OS time must take this into account, since:
++ * - a small OS time may (or may not) be rounded
++ * - a large time may (or may not) overflow
++ *
++ * @{ */
++
++/** @brief Return whether ticka occurs after tickb
++ *
++ * Some OSs handle tick 'rollover' specially, and so can be more robust against
++ * tick counters rolling-over. This function must therefore be called to
++ * determine if a time (in ticks) really occurs after another time (in ticks).
++ *
++ * @param ticka ticka
++ * @param tickb tickb
++ * @return non-zero if ticka represents a time that occurs after tickb.
++ * Zero otherwise.
++ */
++int   _mali_osk_time_after( u32 ticka, u32 tickb );
++
++/** @brief Convert milliseconds to OS 'ticks'
++ *
++ * @param ms time interval in milliseconds
++ * @return the corresponding time interval in OS ticks.
++ */
++u32   _mali_osk_time_mstoticks( u32 ms );
++
++/** @brief Convert OS 'ticks' to milliseconds
++ *
++ * @param ticks time interval in OS ticks.
++ * @return the corresponding time interval in milliseconds
++ */
++u32   _mali_osk_time_tickstoms( u32 ticks );
++
++
++/** @brief Get the current time in OS 'ticks'.
++ * @return the current time in OS 'ticks'.
++ */
++u32   _mali_osk_time_tickcount( void );
++
++/** @brief Cause a microsecond delay
++ *
++ * The delay will have microsecond resolution, and is necessary for correct
++ * operation of the driver. At worst, the delay will be \b at least \a usecs
++ * microseconds, and so may be (significantly) more.
++ *
++ * This function may be implemented as a busy-wait, which is the most sensible
++ * implementation. On OSs where there are situations in which a thread must not
++ * sleep, this is definitely implemented as a busy-wait.
++ *
++ * @param usecs the number of microseconds to wait for.
++ */
++void _mali_osk_time_ubusydelay( u32 usecs );
++
++/** @brief Return time in nano seconds, since any given reference.
++ *
++ * @return Time in nano seconds
++ */
++u64 _mali_osk_time_get_ns( void );
++
++
++/** @} */ /* end group _mali_osk_time */
++
++/** @defgroup _mali_osk_math OSK Math
++ * @{ */
++
++/** @brief Count Leading Zeros (Little-endian)
++ *
++ * @note This function must be implemented to support the reference
++ * implementation of _mali_osk_find_first_zero_bit, as defined in
++ * mali_osk_bitops.h.
++ *
++ * @param val 32-bit words to count leading zeros on
++ * @return the number of leading zeros.
++ */
++u32 _mali_osk_clz( u32 val );
++/** @} */ /* end group _mali_osk_math */
++
++/** @defgroup _mali_osk_wait_queue OSK Wait Queue functionality
++ * @{ */
++/** @brief Private type for wait queue objects */
++typedef struct _mali_osk_wait_queue_t_struct _mali_osk_wait_queue_t;
++
++/** @brief Initialize an empty Wait Queue */
++_mali_osk_wait_queue_t* _mali_osk_wait_queue_init( void );
++
++/** @brief Sleep  if condition is false
++ *
++ * @param queue the queue to use
++ * @param condition function pointer to a boolean function
++ *
++ * Put thread to sleep if the given \a codition function returns false. When
++ * being asked to wake up again, the condition will be re-checked and the
++ * thread only woken up if the condition is now true.
++ */
++void _mali_osk_wait_queue_wait_event( _mali_osk_wait_queue_t *queue, mali_bool (*condition)(void) );
++
++/** @brief Wake up all threads in wait queue if their respective conditions are
++ * true
++ *
++ * @param queue the queue whose threads should be woken up
++ *
++ * Wake up all threads in wait queue \a queue whose condition is now true.
++ */
++void _mali_osk_wait_queue_wake_up( _mali_osk_wait_queue_t *queue );
++
++/** @brief terminate a wait queue
++ *
++ * @param queue the queue to terminate.
++ */
++void _mali_osk_wait_queue_term( _mali_osk_wait_queue_t *queue );
++/** @} */ /* end group _mali_osk_wait_queue */
++
++
++/** @addtogroup _mali_osk_miscellaneous
++ * @{ */
++
++/** @brief Output a device driver debug message.
++ *
++ * The interpretation of \a fmt is the same as the \c format parameter in
++ * _mali_osu_vsnprintf().
++ *
++ * @param fmt a _mali_osu_vsnprintf() style format string
++ * @param ... a variable-number of parameters suitable for \a fmt
++ */
++void _mali_osk_dbgmsg( const char *fmt, ... );
++
++/** @brief Print fmt into buf.
++ *
++ * The interpretation of \a fmt is the same as the \c format parameter in
++ * _mali_osu_vsnprintf().
++ *
++ * @param buf a pointer to the result buffer
++ * @param size the total number of bytes allowed to write to \a buf
++ * @param fmt a _mali_osu_vsnprintf() style format string
++ * @param ... a variable-number of parameters suitable for \a fmt
++ * @return The number of bytes written to \a buf
++ */
++u32 _mali_osk_snprintf( char *buf, u32 size, const char *fmt, ... );
++
++/** @brief Abnormal process abort.
++ *
++ * Terminates the caller-process if this function is called.
++ *
++ * This function will be called from Debug assert-macros in mali_kernel_common.h.
++ *
++ * This function will never return - because to continue from a Debug assert
++ * could cause even more problems, and hinder debugging of the initial problem.
++ *
++ * This function is only used in Debug builds, and is not used in Release builds.
++ */
++void _mali_osk_abort(void);
++
++/** @brief Sets breakpoint at point where function is called.
++ *
++ * This function will be called from Debug assert-macros in mali_kernel_common.h,
++ * to assist in debugging. If debugging at this level is not required, then this
++ * function may be implemented as a stub.
++ *
++ * This function is only used in Debug builds, and is not used in Release builds.
++ */
++void _mali_osk_break(void);
++
++/** @brief Return an identificator for calling process.
++ *
++ * @return Identificator for calling process.
++ */
++u32 _mali_osk_get_pid(void);
++
++/** @brief Return an identificator for calling thread.
++ *
++ * @return Identificator for calling thread.
++ */
++u32 _mali_osk_get_tid(void);
++
++/** @brief Enable OS controlled runtime power management
++ */
++void _mali_osk_pm_dev_enable(void);
++
++/** @brief Disable OS controlled runtime power management
++ */
++void _mali_osk_pm_dev_disable(void);
++
++
++/** @brief Take a reference to the power manager system for the Mali device.
++ *
++ * When function returns successfully, Mali is ON.
++ *
++ * @note Call \a _mali_osk_pm_dev_ref_dec() to release this reference.
++ */
++_mali_osk_errcode_t _mali_osk_pm_dev_ref_add(void);
++
++
++/** @brief Release the reference to the power manger system for the Mali device.
++ *
++ * When reference count reach zero, the cores can be off.
++ *
++ * @note This must be used to release references taken with \a _mali_osk_pm_dev_ref_add().
++ */
++void _mali_osk_pm_dev_ref_dec(void);
++
++
++/** @brief Take a reference to the power manager system for the Mali device.
++ *
++ * Will leave the cores powered off if they are already powered off.
++ *
++ * @note Call \a _mali_osk_pm_dev_ref_dec() to release this reference.
++ *
++ * @return MALI_TRUE if the Mali GPU is powered on, otherwise MALI_FALSE.
++ */
++mali_bool _mali_osk_pm_dev_ref_add_no_power_on(void);
++
++
++/** @brief Releasing the reference to the power manger system for the Mali device.
++ *
++ * When reference count reach zero, the cores can be off.
++ *
++ * @note This must be used to release references taken with \a _mali_osk_pm_dev_ref_add_no_power_on().
++ */
++void _mali_osk_pm_dev_ref_dec_no_power_on(void);
++
++/** @} */ /* end group  _mali_osk_miscellaneous */
++
++/** @} */ /* end group osuapi */
++
++/** @} */ /* end group uddapi */
++
++#ifdef __cplusplus
++}
++#endif
++
++#include "mali_osk_specific.h"           /* include any per-os specifics */
++
++/* Check standard inlines */
++#ifndef MALI_STATIC_INLINE
++      #error MALI_STATIC_INLINE not defined on your OS
++#endif
++
++#ifndef MALI_NON_STATIC_INLINE
++      #error MALI_NON_STATIC_INLINE not defined on your OS
++#endif
++
++#endif /* __MALI_OSK_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_osk_bitops.h b/drivers/gpu/arm/mali400/mali/common/mali_osk_bitops.h
+new file mode 100644
+index 0000000..843ff20
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_osk_bitops.h
+@@ -0,0 +1,166 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_osk_bitops.h
++ * Implementation of the OS abstraction layer for the kernel device driver
++ */
++
++#ifndef __MALI_OSK_BITOPS_H__
++#define __MALI_OSK_BITOPS_H__
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif
++
++MALI_STATIC_INLINE void _mali_internal_clear_bit( u32 bit, u32 *addr )
++{
++      MALI_DEBUG_ASSERT( bit < 32 );
++      MALI_DEBUG_ASSERT( NULL != addr );
++
++      (*addr) &= ~(1 << bit);
++}
++
++MALI_STATIC_INLINE void _mali_internal_set_bit( u32 bit, u32 *addr )
++{
++      MALI_DEBUG_ASSERT( bit < 32 );
++      MALI_DEBUG_ASSERT( NULL != addr );
++
++      (*addr) |= (1 << bit);
++}
++
++MALI_STATIC_INLINE u32 _mali_internal_test_bit( u32 bit, u32 value )
++{
++      MALI_DEBUG_ASSERT( bit < 32 );
++      return value & (1 << bit);
++}
++
++MALI_STATIC_INLINE int _mali_internal_find_first_zero_bit( u32 value )
++{
++      u32 inverted;
++      u32 negated;
++      u32 isolated;
++      u32 leading_zeros;
++
++      /* Begin with xxx...x0yyy...y, where ys are 1, number of ys is in range  0..31 */
++      inverted = ~value; /* zzz...z1000...0 */
++      /* Using count_trailing_zeros on inverted value -
++       * See ARM System Developers Guide for details of count_trailing_zeros */
++
++      /* Isolate the zero: it is preceeded by a run of 1s, so add 1 to it */
++      negated = (u32)-inverted ; /* -a == ~a + 1 (mod 2^n) for n-bit numbers */
++    /* negated = xxx...x1000...0 */
++
++      isolated = negated & inverted ; /* xxx...x1000...0 & zzz...z1000...0, zs are ~xs */
++      /* And so the first zero bit is in the same position as the 1 == number of 1s that preceeded it
++       * Note that the output is zero if value was all 1s */
++
++      leading_zeros = _mali_osk_clz( isolated );
++
++      return 31 - leading_zeros;
++}
++
++
++/** @defgroup _mali_osk_bitops OSK Non-atomic Bit-operations
++ * @{ */
++
++/**
++ * These bit-operations do not work atomically, and so locks must be used if
++ * atomicity is required.
++ *
++ * Reference implementations for Little Endian are provided, and so it should
++ * not normally be necessary to re-implement these. Efficient bit-twiddling
++ * techniques are used where possible, implemented in portable C.
++ *
++ * Note that these reference implementations rely on _mali_osk_clz() being
++ * implemented.
++ */
++
++/** @brief Clear a bit in a sequence of 32-bit words
++ * @param nr bit number to clear, starting from the (Little-endian) least
++ * significant bit
++ * @param addr starting point for counting.
++ */
++MALI_STATIC_INLINE void _mali_osk_clear_nonatomic_bit( u32 nr, u32 *addr )
++{
++      addr += nr >> 5; /* find the correct word */
++      nr = nr & ((1 << 5)-1); /* The bit number within the word */
++
++      _mali_internal_clear_bit( nr, addr );
++}
++
++/** @brief Set a bit in a sequence of 32-bit words
++ * @param nr bit number to set, starting from the (Little-endian) least
++ * significant bit
++ * @param addr starting point for counting.
++ */
++MALI_STATIC_INLINE void _mali_osk_set_nonatomic_bit( u32 nr, u32 *addr )
++{
++      addr += nr >> 5; /* find the correct word */
++      nr = nr & ((1 << 5)-1); /* The bit number within the word */
++
++      _mali_internal_set_bit( nr, addr );
++}
++
++/** @brief Test a bit in a sequence of 32-bit words
++ * @param nr bit number to test, starting from the (Little-endian) least
++ * significant bit
++ * @param addr starting point for counting.
++ * @return zero if bit was clear, non-zero if set. Do not rely on the return
++ * value being related to the actual word under test.
++ */
++MALI_STATIC_INLINE u32 _mali_osk_test_bit( u32 nr, u32 *addr )
++{
++      addr += nr >> 5; /* find the correct word */
++      nr = nr & ((1 << 5)-1); /* The bit number within the word */
++
++      return _mali_internal_test_bit( nr, *addr );
++}
++
++/* Return maxbit if not found */
++/** @brief Find the first zero bit in a sequence of 32-bit words
++ * @param addr starting point for search.
++ * @param maxbit the maximum number of bits to search
++ * @return the number of the first zero bit found, or maxbit if none were found
++ * in the specified range.
++ */
++MALI_STATIC_INLINE u32 _mali_osk_find_first_zero_bit( const u32 *addr, u32 maxbit )
++{
++      u32 total;
++
++      for ( total = 0; total < maxbit; total += 32, ++addr )
++      {
++              int result;
++              result = _mali_internal_find_first_zero_bit( *addr );
++
++              /* non-negative signifies the bit was found */
++              if ( result >= 0 )
++              {
++                      total += (u32)result;
++                      break;
++              }
++      }
++
++      /* Now check if we reached maxbit or above */
++      if ( total >= maxbit )
++      {
++              total = maxbit;
++      }
++
++      return total; /* either the found bit nr, or maxbit if not found */
++}
++/** @} */ /* end group _mali_osk_bitops */
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* __MALI_OSK_BITOPS_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_osk_list.h b/drivers/gpu/arm/mali400/mali/common/mali_osk_list.h
+new file mode 100644
+index 0000000..67046b3
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_osk_list.h
+@@ -0,0 +1,183 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_osk_list.h
++ * Implementation of the OS abstraction layer for the kernel device driver
++ */
++
++#ifndef __MALI_OSK_LIST_H__
++#define __MALI_OSK_LIST_H__
++
++#include "mali_kernel_common.h"
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif
++
++MALI_STATIC_INLINE void __mali_osk_list_add(_mali_osk_list_t *new_entry, _mali_osk_list_t *prev, _mali_osk_list_t *next)
++{
++    next->prev = new_entry;
++    new_entry->next = next;
++    new_entry->prev = prev;
++    prev->next = new_entry;
++}
++
++MALI_STATIC_INLINE void __mali_osk_list_del(_mali_osk_list_t *prev, _mali_osk_list_t *next)
++{
++    next->prev = prev;
++    prev->next = next;
++}
++
++/** @addtogroup _mali_osk_list
++ * @{ */
++
++/** Reference implementations of Doubly-linked Circular Lists are provided.
++ * There is often no need to re-implement these.
++ *
++ * @note The implementation may differ subtly from any lists the OS provides.
++ * For this reason, these lists should not be mixed with OS-specific lists
++ * inside the OSK/UKK implementation. */
++
++/** @brief Initialize a list element.
++ *
++ * All list elements must be initialized before use.
++ *
++ * Do not use on any list element that is present in a list without using
++ * _mali_osk_list_del first, otherwise this will break the list.
++ *
++ * @param list the list element to initialize
++ */
++MALI_STATIC_INLINE void _mali_osk_list_init( _mali_osk_list_t *list )
++{
++    list->next = list;
++    list->prev = list;
++}
++
++/** @brief Insert a single list element after an entry in a list
++ *
++ * As an example, if this is inserted to the head of a list, then this becomes
++ * the first element of the list.
++ *
++ * Do not use to move list elements from one list to another, as it will break
++ * the originating list.
++ *
++ *
++ * @param newlist the list element to insert
++ * @param list the list in which to insert. The new element will be the next
++ * entry in this list
++ */
++MALI_STATIC_INLINE void _mali_osk_list_add( _mali_osk_list_t *new_entry, _mali_osk_list_t *list )
++{
++    __mali_osk_list_add(new_entry, list, list->next);
++}
++
++/** @brief Insert a single list element before an entry in a list
++ *
++ * As an example, if this is inserted to the head of a list, then this becomes
++ * the last element of the list.
++ *
++ * Do not use to move list elements from one list to another, as it will break
++ * the originating list.
++ *
++ * @param newlist the list element to insert
++ * @param list the list in which to insert. The new element will be the previous
++ * entry in this list
++ */
++MALI_STATIC_INLINE void _mali_osk_list_addtail( _mali_osk_list_t *new_entry, _mali_osk_list_t *list )
++{
++    __mali_osk_list_add(new_entry, list->prev, list);
++}
++
++/** @brief Remove a single element from a list
++ *
++ * The element will no longer be present in the list. The removed list element
++ * will be uninitialized, and so should not be traversed. It must be
++ * initialized before further use.
++ *
++ * @param list the list element to remove.
++ */
++MALI_STATIC_INLINE void _mali_osk_list_del( _mali_osk_list_t *list )
++{
++    __mali_osk_list_del(list->prev, list->next);
++}
++
++/** @brief Remove a single element from a list, and re-initialize it
++ *
++ * The element will no longer be present in the list. The removed list element
++ * will initialized, and so can be used as normal.
++ *
++ * @param list the list element to remove and initialize.
++ */
++MALI_STATIC_INLINE void _mali_osk_list_delinit( _mali_osk_list_t *list )
++{
++    __mali_osk_list_del(list->prev, list->next);
++    _mali_osk_list_init(list);
++}
++
++/** @brief Determine whether a list is empty.
++ *
++ * An empty list is one that contains a single element that points to itself.
++ *
++ * @param list the list to check.
++ * @return non-zero if the list is empty, and zero otherwise.
++ */
++MALI_STATIC_INLINE mali_bool _mali_osk_list_empty( _mali_osk_list_t *list )
++{
++    return list->next == list;
++}
++
++/** @brief Move a list element from one list to another.
++ *
++ * The list element must be initialized.
++ *
++ * As an example, moving a list item to the head of a new list causes this item
++ * to be the first element in the new list.
++ *
++ * @param move the list element to move
++ * @param list the new list into which the element will be inserted, as the next
++ * element in the list.
++ */
++MALI_STATIC_INLINE void _mali_osk_list_move( _mali_osk_list_t *move_entry, _mali_osk_list_t *list )
++{
++    __mali_osk_list_del(move_entry->prev, move_entry->next);
++    _mali_osk_list_add(move_entry, list);
++}
++
++/** @brief Move an entire list
++ *
++ * The list element must be initialized.
++ *
++ * Allows you to move a list from one list head to another list head
++ *
++ * @param old_list The existing list head
++ * @param new_list The new list head (must be an empty list)
++ */
++MALI_STATIC_INLINE void _mali_osk_list_move_list( _mali_osk_list_t *old_list, _mali_osk_list_t *new_list )
++{
++      MALI_DEBUG_ASSERT(_mali_osk_list_empty(new_list));
++      if (!_mali_osk_list_empty(old_list))
++      {
++              new_list->next = old_list->next;
++              new_list->prev = old_list->prev;
++              new_list->next->prev = new_list;
++              new_list->prev->next = new_list;
++              old_list->next = old_list;
++              old_list->prev = old_list;
++      }
++}
++/** @} */ /* end group _mali_osk_list */
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* __MALI_OSK_LIST_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_osk_mali.h b/drivers/gpu/arm/mali400/mali/common/mali_osk_mali.h
+new file mode 100644
+index 0000000..c8d5825
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_osk_mali.h
+@@ -0,0 +1,243 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_osk_mali.h
++ * Defines the OS abstraction layer which is specific for the Mali kernel device driver (OSK)
++ */
++
++#ifndef __MALI_OSK_MALI_H__
++#define __MALI_OSK_MALI_H__
++
++#include <mali_osk.h>
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif
++
++/** @addtogroup _mali_osk_miscellaneous
++ * @{ */
++
++/** @brief Struct with device specific configuration data
++ */
++struct _mali_osk_device_data
++{
++      /* Dedicated GPU memory range (physical). */
++      u32 dedicated_mem_start;
++      u32 dedicated_mem_size;
++
++      /* Shared GPU memory */
++      u32 shared_mem_size;
++
++      /* Frame buffer memory to be accessible by Mali GPU (physical) */
++      u32 fb_start;
++      u32 fb_size;
++
++      /* Report GPU utilization in this interval (specified in ms) */
++      u32 utilization_interval;
++
++      /* Function that will receive periodic GPU utilization numbers */
++      void (*utilization_handler)(unsigned int);
++};
++
++/** @brief Find Mali GPU HW resource
++ *
++ * @param addr Address of Mali GPU resource to find
++ * @param res Storage for resource information if resource is found.
++ * @return _MALI_OSK_ERR_OK on success, _MALI_OSK_ERR_ITEM_NOT_FOUND if resource is not found
++ */
++_mali_osk_errcode_t _mali_osk_resource_find(u32 addr, _mali_osk_resource_t *res);
++
++
++/** @brief Find Mali GPU HW base address
++ *
++ * @return 0 if resources are found, otherwise the Mali GPU component with lowest address.
++ */
++u32 _mali_osk_resource_base_address(void);
++
++/** @brief Retrieve the Mali GPU specific data
++ *
++ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
++ */
++_mali_osk_errcode_t _mali_osk_device_data_get(struct _mali_osk_device_data *data);
++
++/** @} */ /* end group _mali_osk_miscellaneous */
++
++
++
++
++/** @addtogroup _mali_osk_low_level_memory
++ * @{ */
++
++/** @brief Initialize a user-space accessible memory range
++ *
++ * This initializes a virtual address range such that it is reserved for the
++ * current process, but does not map any physical pages into this range.
++ *
++ * This function may initialize or adjust any members of the
++ * mali_memory_allocation \a descriptor supplied, before the physical pages are
++ * mapped in with _mali_osk_mem_mapregion_map().
++ *
++ * The function will always be called with MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE
++ * set in \a descriptor->flags. It is an error to call this function without
++ * setting this flag. Otherwise, \a descriptor->flags bits are reserved for
++ * future expansion
++ *
++ * The \a descriptor's process_addr_mapping_info member can be modified to
++ * allocate OS-specific information. Note that on input, this will be a
++ * ukk_private word from the U/K inteface, as inserted by _mali_ukk_mem_mmap().
++ * This is used to pass information from the U/K interface to the OSK interface,
++ * if necessary. The precise usage of the process_addr_mapping_info member
++ * depends on the U/K implementation of _mali_ukk_mem_mmap().
++ *
++ * Therefore, the U/K implementation of _mali_ukk_mem_mmap() and the OSK
++ * implementation of  _mali_osk_mem_mapregion_init() must agree on the meaning and
++ * usage of the ukk_private word and process_addr_mapping_info member.
++ *
++ * Refer to \ref u_k_api for more information on the U/K interface.
++ *
++ * On successful return, \a descriptor's mapping member will be correct for
++ * use with _mali_osk_mem_mapregion_term() and _mali_osk_mem_mapregion_map().
++ *
++ * @param descriptor the mali_memory_allocation to initialize.
++ */
++_mali_osk_errcode_t _mali_osk_mem_mapregion_init( mali_memory_allocation * descriptor );
++
++/** @brief Terminate a user-space accessible memory range
++ *
++ * This terminates a virtual address range reserved in the current user process,
++ * where none, some or all of the virtual address ranges have mappings to
++ * physical pages.
++ *
++ * It will unmap any physical pages that had been mapped into a reserved
++ * virtual address range for the current process, and then releases the virtual
++ * address range. Any extra book-keeping information or resources allocated
++ * during _mali_osk_mem_mapregion_init() will also be released.
++ *
++ * The \a descriptor itself is not freed - this must be handled by the caller of
++ * _mali_osk_mem_mapregion_term().
++ *
++ * The function will always be called with MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE
++ * set in descriptor->flags. It is an error to call this function without
++ * setting this flag. Otherwise, descriptor->flags bits are reserved for
++ * future expansion
++ *
++ * @param descriptor the mali_memory_allocation to terminate.
++ */
++void _mali_osk_mem_mapregion_term( mali_memory_allocation * descriptor );
++
++/** @brief Map physical pages into a user process's virtual address range
++ *
++ * This is used to map a number of physically contigous pages into a
++ * user-process's virtual address range, which was previously reserved by a
++ * call to _mali_osk_mem_mapregion_init().
++ *
++ * This need not provide a mapping for the entire virtual address range
++ * reserved for \a descriptor - it may be used to map single pages per call.
++ *
++ * The function will always be called with MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE
++ * set in \a descriptor->flags. It is an error to call this function without
++ * setting this flag. Otherwise, \a descriptor->flags bits are reserved for
++ * future expansion
++ *
++ * The function may supply \a *phys_addr == \ref MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC.
++ * In this case, \a size must be set to \ref _MALI_OSK_CPU_PAGE_SIZE, and the function
++ * will allocate the physical page itself. The physical address of the
++ * allocated page will be returned through \a phys_addr.
++ *
++ * It is an error to set \a size != \ref _MALI_OSK_CPU_PAGE_SIZE while
++ * \a *phys_addr == \ref MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC,
++ * since it is not always possible for OSs to support such a setting through this
++ * interface.
++ *
++ * @note \b IMPORTANT: This code must validate the input parameters. If the
++ * range defined by \a offset and \a size is outside the range allocated in
++ * \a descriptor, then this function \b MUST not attempt any mapping, and must
++ * instead return a suitable \ref _mali_osk_errcode_t \b failure code.
++ *
++ * @param[in,out] descriptor the mali_memory_allocation representing the
++ * user-process's virtual address range to map into.
++ *
++ * @param[in] offset the offset into the virtual address range. This is only added
++ * to the mapping member of the \a descriptor, and not the \a phys_addr parameter.
++ * It must be a multiple of \ref _MALI_OSK_CPU_PAGE_SIZE.
++ *
++ * @param[in,out] phys_addr a pointer to the physical base address to begin the
++ * mapping from. If \a size == \ref _MALI_OSK_CPU_PAGE_SIZE and
++ * \a *phys_addr == \ref MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC, then this
++ * function will allocate the physical page itself, and return the
++ * physical address of the page through \a phys_addr, which will be aligned to
++ * \ref _MALI_OSK_CPU_PAGE_SIZE. Otherwise, \a *phys_addr must be aligned to
++ * \ref _MALI_OSK_CPU_PAGE_SIZE, and is unmodified after the call.
++ * \a phys_addr is unaffected by the \a offset parameter.
++ *
++ * @param[in] size the number of bytes to map in. This must be a multiple of
++ * \ref _MALI_OSK_CPU_PAGE_SIZE.
++ *
++ * @return _MALI_OSK_ERR_OK on sucess, otherwise a _mali_osk_errcode_t value
++ * on failure
++ *
++ * @note could expand to use _mali_osk_mem_mapregion_flags_t instead of
++ * \ref MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC, but note that we must
++ * also modify the mali process address manager in the mmu/memory engine code.
++ */
++_mali_osk_errcode_t _mali_osk_mem_mapregion_map( mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size );
++
++
++/** @brief Unmap physical pages from a user process's virtual address range
++ *
++ * This is used to unmap a number of physically contigous pages from a
++ * user-process's virtual address range, which were previously mapped by a
++ * call to _mali_osk_mem_mapregion_map(). If the range specified was allocated
++ * from OS memory, then that memory will be returned to the OS. Whilst pages
++ * will be mapped out, the Virtual address range remains reserved, and at the
++ * same base address.
++ *
++ * When this function is used to unmap pages from OS memory
++ * (_mali_osk_mem_mapregion_map() was called with *phys_addr ==
++ * \ref MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC), then the \a flags must
++ * include \ref _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR. This is because
++ * it is not always easy for an OS implementation to discover whether the
++ * memory was OS allocated or not (and so, how it should release the memory).
++ *
++ * For this reason, only a range of pages of the same allocation type (all OS
++ * allocated, or none OS allocacted) may be unmapped in one call. Multiple
++ * calls must be made if allocations of these different types exist across the
++ * entire region described by the \a descriptor.
++ *
++ * The function will always be called with MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE
++ * set in \a descriptor->flags. It is an error to call this function without
++ * setting this flag. Otherwise, \a descriptor->flags bits are reserved for
++ * future expansion
++ *
++ * @param[in,out] descriptor the mali_memory_allocation representing the
++ * user-process's virtual address range to map into.
++ *
++ * @param[in] offset the offset into the virtual address range. This is only added
++ * to the mapping member of the \a descriptor. \a offset must be a multiple of
++ * \ref _MALI_OSK_CPU_PAGE_SIZE.
++ *
++ * @param[in] size the number of bytes to unmap. This must be a multiple of
++ * \ref _MALI_OSK_CPU_PAGE_SIZE.
++ *
++ * @param[in] flags specifies how the memory should be unmapped. For a range
++ * of pages that were originally OS allocated, this must have
++ * \ref _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR set.
++ */
++void _mali_osk_mem_mapregion_unmap( mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t flags );
++/** @} */ /* end group _mali_osk_low_level_memory */
++
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* __MALI_OSK_MALI_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_osk_profiling.h b/drivers/gpu/arm/mali400/mali/common/mali_osk_profiling.h
+new file mode 100644
+index 0000000..e2013b3
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_osk_profiling.h
+@@ -0,0 +1,140 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_OSK_PROFILING_H__
++#define __MALI_OSK_PROFILING_H__
++
++#if defined(CONFIG_MALI400_PROFILING) && defined (CONFIG_TRACEPOINTS)
++
++#include "mali_linux_trace.h"
++#include "mali_profiling_events.h"
++
++#define MALI_PROFILING_MAX_BUFFER_ENTRIES 1048576
++
++#define MALI_PROFILING_NO_HW_COUNTER = ((u32)-1)
++
++/** @defgroup _mali_osk_profiling External profiling connectivity
++ * @{ */
++
++/**
++ * Initialize the profiling module.
++ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
++ */
++_mali_osk_errcode_t _mali_osk_profiling_init(mali_bool auto_start);
++
++/*
++ * Terminate the profiling module.
++ */
++void _mali_osk_profiling_term(void);
++
++/**
++ * Start recording profiling data
++ *
++ * The specified limit will determine how large the capture buffer is.
++ * MALI_PROFILING_MAX_BUFFER_ENTRIES determines the maximum size allowed by the device driver.
++ *
++ * @param limit The desired maximum number of events to record on input, the actual maximum on output.
++ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
++ */
++_mali_osk_errcode_t _mali_osk_profiling_start(u32 * limit);
++
++/**
++ * Add an profiling event
++ *
++ * @param event_id The event identificator.
++ * @param data0 First data parameter, depending on event_id specified.
++ * @param data1 Second data parameter, depending on event_id specified.
++ * @param data2 Third data parameter, depending on event_id specified.
++ * @param data3 Fourth data parameter, depending on event_id specified.
++ * @param data4 Fifth data parameter, depending on event_id specified.
++ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
++ */
++/* Call Linux tracepoint directly */
++#define _mali_osk_profiling_add_event(event_id, data0, data1, data2, data3, data4) trace_mali_timeline_event((event_id), (data0), (data1), (data2), (data3), (data4))
++
++/**
++ * Report a hardware counter event.
++ *
++ * @param counter_id The ID of the counter.
++ * @param value The value of the counter.
++ */
++
++/* Call Linux tracepoint directly */
++#define _mali_osk_profiling_report_hw_counter(counter_id, value) trace_mali_hw_counter(counter_id, value)
++
++/**
++ * Report SW counters
++ *
++ * @param counters array of counter values
++ */
++void _mali_osk_profiling_report_sw_counters(u32 *counters);
++
++/**
++ * Stop recording profiling data
++ *
++ * @param count Returns the number of recorded events.
++ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
++ */
++_mali_osk_errcode_t _mali_osk_profiling_stop(u32 * count);
++
++/**
++ * Retrieves the number of events that can be retrieved
++ *
++ * @return The number of recorded events that can be retrieved.
++ */
++u32 _mali_osk_profiling_get_count(void);
++
++/**
++ * Retrieve an event
++ *
++ * @param index Event index (start with 0 and continue until this function fails to retrieve all events)
++ * @param timestamp The timestamp for the retrieved event will be stored here.
++ * @param event_id The event ID for the retrieved event will be stored here.
++ * @param data The 5 data values for the retrieved event will be stored here.
++ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
++ */
++_mali_osk_errcode_t _mali_osk_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5]);
++
++/**
++ * Clear the recorded buffer.
++ *
++ * This is needed in order to start another recording.
++ *
++ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
++ */
++_mali_osk_errcode_t _mali_osk_profiling_clear(void);
++
++/**
++ * Checks if a recording of profiling data is in progress
++ *
++ * @return MALI_TRUE if recording of profiling data is in progress, MALI_FALSE if not
++ */
++mali_bool _mali_osk_profiling_is_recording(void);
++
++/**
++ * Checks if profiling data is available for retrival
++ *
++ * @return MALI_TRUE if profiling data is avaiable, MALI_FALSE if not
++ */
++mali_bool _mali_osk_profiling_have_recording(void);
++
++/** @} */ /* end group _mali_osk_profiling */
++
++#else /* defined(CONFIG_MALI400_PROFILING)  && defined(CONFIG_TRACEPOINTS) */
++
++ /* Dummy add_event, for when profiling is disabled. */
++
++#define _mali_osk_profiling_add_event(event_id, data0, data1, data2, data3, data4)
++
++#endif /* defined(CONFIG_MALI400_PROFILING)  && defined(CONFIG_TRACEPOINTS) */
++
++#endif /* __MALI_OSK_PROFILING_H__ */
++
++
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_pm.c b/drivers/gpu/arm/mali400/mali/common/mali_pm.c
+new file mode 100644
+index 0000000..5d2b33f
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_pm.c
+@@ -0,0 +1,106 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_pm.h"
++#include "mali_kernel_common.h"
++#include "mali_osk.h"
++#include "mali_gp_scheduler.h"
++#include "mali_pp_scheduler.h"
++#include "mali_scheduler.h"
++#include "mali_kernel_utilization.h"
++#include "mali_group.h"
++
++static mali_bool mali_power_on = MALI_FALSE;
++
++_mali_osk_errcode_t mali_pm_initialize(void)
++{
++      _mali_osk_pm_dev_enable();
++      return _MALI_OSK_ERR_OK;
++}
++
++void mali_pm_terminate(void)
++{
++      _mali_osk_pm_dev_disable();
++}
++
++void mali_pm_core_event(enum mali_core_event core_event)
++{
++      MALI_DEBUG_ASSERT(MALI_CORE_EVENT_GP_START == core_event ||
++                        MALI_CORE_EVENT_PP_START == core_event ||
++                        MALI_CORE_EVENT_GP_STOP  == core_event ||
++                        MALI_CORE_EVENT_PP_STOP  == core_event);
++
++      if (MALI_CORE_EVENT_GP_START == core_event || MALI_CORE_EVENT_PP_START == core_event)
++      {
++              _mali_osk_pm_dev_ref_add();
++              if (mali_utilization_enabled())
++              {
++                      mali_utilization_core_start(_mali_osk_time_get_ns());
++              }
++      }
++      else
++      {
++              _mali_osk_pm_dev_ref_dec();
++              if (mali_utilization_enabled())
++              {
++                      mali_utilization_core_end(_mali_osk_time_get_ns());
++              }
++      }
++}
++
++/* Reset GPU after power up */
++static void mali_pm_reset_gpu(void)
++{
++      /* Reset all L2 caches */
++      mali_l2_cache_reset_all();
++
++      /* Reset all groups */
++      mali_scheduler_reset_all_groups();
++}
++
++void mali_pm_os_suspend(void)
++{
++      MALI_DEBUG_PRINT(3, ("Mali PM: OS suspend\n"));
++      mali_gp_scheduler_suspend();
++      mali_pp_scheduler_suspend();
++      mali_group_power_off();
++      mali_power_on = MALI_FALSE;
++}
++
++void mali_pm_os_resume(void)
++{
++      MALI_DEBUG_PRINT(3, ("Mali PM: OS resume\n"));
++      if (MALI_TRUE != mali_power_on)
++      {
++              mali_pm_reset_gpu();
++              mali_group_power_on();
++      }
++      mali_gp_scheduler_resume();
++      mali_pp_scheduler_resume();
++      mali_power_on = MALI_TRUE;
++}
++
++void mali_pm_runtime_suspend(void)
++{
++      MALI_DEBUG_PRINT(3, ("Mali PM: Runtime suspend\n"));
++      mali_group_power_off();
++      mali_power_on = MALI_FALSE;
++}
++
++void mali_pm_runtime_resume(void)
++{
++      MALI_DEBUG_PRINT(3, ("Mali PM: Runtime resume\n"));
++      if (MALI_TRUE != mali_power_on)
++      {
++              mali_pm_reset_gpu();
++              mali_group_power_on();
++      }
++      mali_power_on = MALI_TRUE;
++}
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_pm.h b/drivers/gpu/arm/mali400/mali/common/mali_pm.h
+new file mode 100644
+index 0000000..393582e
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_pm.h
+@@ -0,0 +1,36 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_PM_H__
++#define __MALI_PM_H__
++
++#include "mali_osk.h"
++
++enum mali_core_event
++{
++      MALI_CORE_EVENT_GP_START,
++      MALI_CORE_EVENT_GP_STOP,
++      MALI_CORE_EVENT_PP_START,
++      MALI_CORE_EVENT_PP_STOP
++};
++
++_mali_osk_errcode_t mali_pm_initialize(void);
++void mali_pm_terminate(void);
++
++void mali_pm_core_event(enum mali_core_event core_event);
++
++/* Callback functions registered for the runtime PMM system */
++void mali_pm_os_suspend(void);
++void mali_pm_os_resume(void);
++void mali_pm_runtime_suspend(void);
++void mali_pm_runtime_resume(void);
++
++
++#endif /* __MALI_PM_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_pmu.c b/drivers/gpu/arm/mali400/mali/common/mali_pmu.c
+new file mode 100644
+index 0000000..dc1ba34
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_pmu.c
+@@ -0,0 +1,197 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_pmu.c
++ * Mali driver functions for Mali 400 PMU hardware
++ */
++#include "mali_hw_core.h"
++#include "mali_pmu.h"
++#include "mali_pp.h"
++#include "mali_kernel_common.h"
++#include "mali_osk.h"
++
++static u32 mali_pmu_detect_mask(u32 number_of_pp_cores, u32 number_of_l2_caches);
++
++/** @brief MALI inbuilt PMU hardware info and PMU hardware has knowledge of cores power mask
++ */
++struct mali_pmu_core
++{
++      struct mali_hw_core hw_core;
++      u32 mali_registered_cores_power_mask;
++};
++
++static struct mali_pmu_core *mali_global_pmu_core = NULL;
++
++/** @brief Register layout for hardware PMU
++ */
++typedef enum {
++      PMU_REG_ADDR_MGMT_POWER_UP                  = 0x00,     /*< Power up register */
++      PMU_REG_ADDR_MGMT_POWER_DOWN                = 0x04,     /*< Power down register */
++      PMU_REG_ADDR_MGMT_STATUS                    = 0x08,     /*< Core sleep status register */
++      PMU_REG_ADDR_MGMT_INT_MASK                  = 0x0C,     /*< Interrupt mask register */
++      PMU_REGISTER_ADDRESS_SPACE_SIZE             = 0x10,     /*< Size of register space */
++} pmu_reg_addr_mgmt_addr;
++
++struct mali_pmu_core *mali_pmu_create(_mali_osk_resource_t *resource, u32 number_of_pp_cores, u32 number_of_l2_caches)
++{
++      struct mali_pmu_core* pmu;
++
++      MALI_DEBUG_ASSERT(NULL == mali_global_pmu_core);
++      MALI_DEBUG_PRINT(2, ("Mali PMU: Creating Mali PMU core\n"));
++
++      pmu = (struct mali_pmu_core *)_mali_osk_malloc(sizeof(struct mali_pmu_core));
++      if (NULL != pmu)
++      {
++              pmu->mali_registered_cores_power_mask = mali_pmu_detect_mask(number_of_pp_cores, number_of_l2_caches);
++              if (_MALI_OSK_ERR_OK == mali_hw_core_create(&pmu->hw_core, resource, PMU_REGISTER_ADDRESS_SPACE_SIZE))
++              {
++                      if (_MALI_OSK_ERR_OK == mali_pmu_reset(pmu))
++                      {
++                              mali_global_pmu_core = pmu;
++                              return pmu;
++                      }
++                      mali_hw_core_delete(&pmu->hw_core);
++              }
++              _mali_osk_free(pmu);
++      }
++
++      return NULL;
++}
++
++void mali_pmu_delete(struct mali_pmu_core *pmu)
++{
++      MALI_DEBUG_ASSERT_POINTER(pmu);
++
++      mali_hw_core_delete(&pmu->hw_core);
++      _mali_osk_free(pmu);
++      pmu = NULL;
++}
++
++_mali_osk_errcode_t mali_pmu_reset(struct mali_pmu_core *pmu)
++{
++      /* Don't use interrupts - just poll status */
++      mali_hw_core_register_write(&pmu->hw_core, PMU_REG_ADDR_MGMT_INT_MASK, 0);
++      return _MALI_OSK_ERR_OK;
++}
++
++_mali_osk_errcode_t mali_pmu_powerdown_all(struct mali_pmu_core *pmu)
++{
++      u32 stat;
++      u32 timeout;
++
++      MALI_DEBUG_ASSERT_POINTER(pmu);
++      MALI_DEBUG_ASSERT( pmu->mali_registered_cores_power_mask != 0 );
++      MALI_DEBUG_PRINT( 4, ("Mali PMU: power down (0x%08X)\n", pmu->mali_registered_cores_power_mask) );
++
++      mali_hw_core_register_write(&pmu->hw_core, PMU_REG_ADDR_MGMT_POWER_DOWN, pmu->mali_registered_cores_power_mask);
++
++      /* Wait for cores to be powered down (100 x 100us = 100ms) */
++      timeout = MALI_REG_POLL_COUNT_SLOW ;
++      do
++      {
++              /* Get status of sleeping cores */
++              stat = mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_STATUS);
++              stat &= pmu->mali_registered_cores_power_mask;
++              if( stat == pmu->mali_registered_cores_power_mask ) break; /* All cores we wanted are now asleep */
++              timeout--;
++      } while( timeout > 0 );
++
++      if( timeout == 0 )
++      {
++              return _MALI_OSK_ERR_TIMEOUT;
++      }
++
++      return _MALI_OSK_ERR_OK;
++}
++
++_mali_osk_errcode_t mali_pmu_powerup_all(struct mali_pmu_core *pmu)
++{
++      u32 stat;
++      u32 timeout;
++       
++      MALI_DEBUG_ASSERT_POINTER(pmu);
++      MALI_DEBUG_ASSERT( pmu->mali_registered_cores_power_mask != 0 ); /* Shouldn't be zero */
++      MALI_DEBUG_PRINT( 4, ("Mali PMU: power up (0x%08X)\n", pmu->mali_registered_cores_power_mask) );
++
++      mali_hw_core_register_write(&pmu->hw_core, PMU_REG_ADDR_MGMT_POWER_UP, pmu->mali_registered_cores_power_mask);
++
++      /* Wait for cores to be powered up (100 x 100us = 100ms) */
++      timeout = MALI_REG_POLL_COUNT_SLOW;
++      do
++      {
++              /* Get status of sleeping cores */
++              stat = mali_hw_core_register_read(&pmu->hw_core,PMU_REG_ADDR_MGMT_STATUS);
++              stat &= pmu->mali_registered_cores_power_mask;
++              if ( stat == 0 ) break; /* All cores we wanted are now awake */
++              timeout--;
++      } while ( timeout > 0 );
++
++      if ( timeout == 0 )
++      {
++              return _MALI_OSK_ERR_TIMEOUT;
++      }
++
++      return _MALI_OSK_ERR_OK;
++}
++
++struct mali_pmu_core *mali_pmu_get_global_pmu_core(void)
++{
++      return mali_global_pmu_core;
++}
++
++static u32 mali_pmu_detect_mask(u32 number_of_pp_cores, u32 number_of_l2_caches)
++{
++      u32 mask = 0;
++
++      if (number_of_l2_caches == 1)
++      {
++              /* Mali-300 or Mali-400 */
++              u32 i;
++
++              /* GP */
++              mask = 0x01;
++
++              /* L2 cache */
++              mask |= 0x01<<1;
++
++              /* Set bit for each PP core */
++              for (i = 0; i < number_of_pp_cores; i++)
++              {
++                      mask |= 0x01<<(i+2);
++              }
++      }
++      else if (number_of_l2_caches > 1)
++      {
++              /* Mali-450 */
++
++              /* GP (including its L2 cache) */
++              mask = 0x01;
++
++              /* There is always at least one PP (including its L2 cache) */
++              mask |= 0x01<<1;
++
++              /* Additional PP cores in same L2 cache */
++              if (number_of_pp_cores >= 2)
++              {
++                      mask |= 0x01<<2;
++              }
++
++              /* Additional PP cores in a third L2 cache */
++              if (number_of_pp_cores >= 5)
++              {
++                      mask |= 0x01<<3;
++              }
++      }
++
++      MALI_DEBUG_PRINT(4, ("Mali PMU: Power mask is 0x%08X (%u + %u)\n", mask, number_of_pp_cores, number_of_l2_caches));
++
++      return mask;
++}
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_pmu.h b/drivers/gpu/arm/mali400/mali/common/mali_pmu.h
+new file mode 100644
+index 0000000..399755d
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_pmu.h
+@@ -0,0 +1,70 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_platform.h
++ * Platform specific Mali driver functions
++ */
++
++#include "mali_osk.h"
++
++struct mali_pmu_core;
++
++/** @brief Initialisation of MALI PMU
++ * 
++ * This is called from entry point of the driver in order to create and intialize the PMU resource
++ *
++ * @param resource it will be a pointer to a PMU resource
++ * @param number_of_pp_cores Number of found PP resources in configuration
++ * @param number_of_l2_caches Number of found L2 cache resources in configuration
++ * @return The created PMU object, or NULL in case of failure.
++ */
++struct mali_pmu_core *mali_pmu_create(_mali_osk_resource_t *resource, u32 number_of_pp_cores, u32 number_of_l2_caches);
++
++/** @brief It deallocates the PMU resource
++ * 
++ * This is called on the exit of the driver to terminate the PMU resource
++ *
++ * @param pmu Pointer to PMU core object to delete
++ */
++void mali_pmu_delete(struct mali_pmu_core *pmu);
++
++/** @brief Reset PMU core
++ *
++ * @param pmu Pointer to PMU core object to reset
++ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
++ */
++_mali_osk_errcode_t mali_pmu_reset(struct mali_pmu_core *pmu);
++
++/** @brief MALI GPU power down using MALI in-built PMU
++ *
++ * called to power down all cores
++ *
++ * @param pmu Pointer to PMU core object to power down
++ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
++ */
++_mali_osk_errcode_t mali_pmu_powerdown_all(struct mali_pmu_core *pmu);
++
++
++/** @brief MALI GPU power up using MALI in-built PMU
++ * 
++ * called to power up all cores
++ *
++ * @param pmu Pointer to PMU core object to power up
++ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
++ */
++_mali_osk_errcode_t mali_pmu_powerup_all(struct mali_pmu_core *pmu);
++
++
++/** @brief Retrieves the Mali PMU core object (if any)
++ * 
++ * @return The Mali PMU object, or NULL if no PMU exists.
++ */
++struct mali_pmu_core *mali_pmu_get_global_pmu_core(void);
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_pp.c b/drivers/gpu/arm/mali400/mali/common/mali_pp.c
+new file mode 100644
+index 0000000..be0bb4b
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_pp.c
+@@ -0,0 +1,515 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_pp_job.h"
++#include "mali_pp.h"
++#include "mali_hw_core.h"
++#include "mali_group.h"
++#include "regs/mali_200_regs.h"
++#include "mali_kernel_common.h"
++#include "mali_kernel_core.h"
++#if defined(CONFIG_MALI400_PROFILING)
++#include "mali_osk_profiling.h"
++#endif
++
++/* Number of frame registers on Mali-200 */
++#define MALI_PP_MALI200_NUM_FRAME_REGISTERS ((0x04C/4)+1)
++/* Number of frame registers on Mali-300 and later */
++#define MALI_PP_MALI400_NUM_FRAME_REGISTERS ((0x058/4)+1)
++
++static struct mali_pp_core* mali_global_pp_cores[MALI_MAX_NUMBER_OF_PP_CORES];
++static u32 mali_global_num_pp_cores = 0;
++
++/* Interrupt handlers */
++static void mali_pp_irq_probe_trigger(void *data);
++static _mali_osk_errcode_t mali_pp_irq_probe_ack(void *data);
++
++struct mali_pp_core *mali_pp_create(const _mali_osk_resource_t *resource, struct mali_group *group, mali_bool is_virtual)
++{
++      struct mali_pp_core* core = NULL;
++
++      MALI_DEBUG_PRINT(2, ("Mali PP: Creating Mali PP core: %s\n", resource->description));
++      MALI_DEBUG_PRINT(2, ("Mali PP: Base address of PP core: 0x%x\n", resource->base));
++
++      if (mali_global_num_pp_cores >= MALI_MAX_NUMBER_OF_PP_CORES)
++      {
++              MALI_PRINT_ERROR(("Mali PP: Too many PP core objects created\n"));
++              return NULL;
++      }
++
++      core = _mali_osk_malloc(sizeof(struct mali_pp_core));
++      if (NULL != core)
++      {
++              core->core_id = mali_global_num_pp_cores;
++              core->counter_src0_used = MALI_HW_CORE_NO_COUNTER;
++              core->counter_src1_used = MALI_HW_CORE_NO_COUNTER;
++
++              if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALI200_REG_SIZEOF_REGISTER_BANK))
++              {
++                      _mali_osk_errcode_t ret;
++
++                      if (!is_virtual)
++                      {
++                              ret = mali_pp_reset(core);
++                      }
++                      else
++                      {
++                              ret = _MALI_OSK_ERR_OK;
++                      }
++
++                      if (_MALI_OSK_ERR_OK == ret)
++                      {
++                              ret = mali_group_add_pp_core(group, core);
++                              if (_MALI_OSK_ERR_OK == ret)
++                              {
++                                      /* Setup IRQ handlers (which will do IRQ probing if needed) */
++                                      MALI_DEBUG_ASSERT(!is_virtual || -1 != resource->irq);
++
++                                      core->irq = _mali_osk_irq_init(resource->irq,
++                                                                     mali_group_upper_half_pp,
++                                                                     group,
++                                                                     mali_pp_irq_probe_trigger,
++                                                                     mali_pp_irq_probe_ack,
++                                                                     core,
++                                                                     "mali_pp_irq_handlers");
++                                      if (NULL != core->irq)
++                                      {
++                                              mali_global_pp_cores[mali_global_num_pp_cores] = core;
++                                              mali_global_num_pp_cores++;
++
++                                              return core;
++                                      }
++                                      else
++                                      {
++                                              MALI_PRINT_ERROR(("Mali PP: Failed to setup interrupt handlers for PP core %s\n", core->hw_core.description));
++                                      }
++                                      mali_group_remove_pp_core(group);
++                              }
++                              else
++                              {
++                                      MALI_PRINT_ERROR(("Mali PP: Failed to add core %s to group\n", core->hw_core.description));
++                              }
++                      }
++                      mali_hw_core_delete(&core->hw_core);
++              }
++
++              _mali_osk_free(core);
++      }
++      else
++      {
++              MALI_PRINT_ERROR(("Mali PP: Failed to allocate memory for PP core\n"));
++      }
++
++      return NULL;
++}
++
++void mali_pp_delete(struct mali_pp_core *core)
++{
++      u32 i;
++
++      MALI_DEBUG_ASSERT_POINTER(core);
++
++      _mali_osk_irq_term(core->irq);
++      mali_hw_core_delete(&core->hw_core);
++
++      /* Remove core from global list */
++      for (i = 0; i < MALI_MAX_NUMBER_OF_PP_CORES; i++)
++      {
++              if (mali_global_pp_cores[i] == core)
++              {
++                      mali_global_pp_cores[i] = NULL;
++                      mali_global_num_pp_cores--;
++                      break;
++              }
++      }
++
++      _mali_osk_free(core);
++}
++
++void mali_pp_stop_bus(struct mali_pp_core *core)
++{
++      MALI_DEBUG_ASSERT_POINTER(core);
++      /* Will only send the stop bus command, and not wait for it to complete */
++      mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_STOP_BUS);
++}
++
++_mali_osk_errcode_t mali_pp_stop_bus_wait(struct mali_pp_core *core)
++{
++      int i;
++
++      MALI_DEBUG_ASSERT_POINTER(core);
++
++      /* Send the stop bus command. */
++      mali_pp_stop_bus(core);
++
++      /* Wait for bus to be stopped */
++      for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++)
++      {
++              if (mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS) & MALI200_REG_VAL_STATUS_BUS_STOPPED)
++                      break;
++      }
++
++      if (MALI_REG_POLL_COUNT_FAST == i)
++      {
++              MALI_PRINT_ERROR(("Mali PP: Failed to stop bus on %s. Status: 0x%08x\n", core->hw_core.description, mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS)));
++              return _MALI_OSK_ERR_FAULT;
++      }
++      return _MALI_OSK_ERR_OK;
++}
++
++/* Frame register reset values.
++ * Taken from the Mali400 TRM, 3.6. Pixel processor control register summary */
++static const u32 mali_frame_registers_reset_values[_MALI_PP_MAX_FRAME_REGISTERS] =
++{
++      0x0, /* Renderer List Address Register */
++      0x0, /* Renderer State Word Base Address Register */
++      0x0, /* Renderer Vertex Base Register */
++      0x2, /* Feature Enable Register */
++      0x0, /* Z Clear Value Register */
++      0x0, /* Stencil Clear Value Register */
++      0x0, /* ABGR Clear Value 0 Register */
++      0x0, /* ABGR Clear Value 1 Register */
++      0x0, /* ABGR Clear Value 2 Register */
++      0x0, /* ABGR Clear Value 3 Register */
++      0x0, /* Bounding Box Left Right Register */
++      0x0, /* Bounding Box Bottom Register */
++      0x0, /* FS Stack Address Register */
++      0x0, /* FS Stack Size and Initial Value Register */
++      0x0, /* Reserved */
++      0x0, /* Reserved */
++      0x0, /* Origin Offset X Register */
++      0x0, /* Origin Offset Y Register */
++      0x75, /* Subpixel Specifier Register */
++      0x0, /* Tiebreak mode Register */
++      0x0, /* Polygon List Format Register */
++      0x0, /* Scaling Register */
++      0x0 /* Tilebuffer configuration Register */
++};
++
++/* WBx register reset values */
++static const u32 mali_wb_registers_reset_values[_MALI_PP_MAX_WB_REGISTERS] =
++{
++      0x0, /* WBx Source Select Register */
++      0x0, /* WBx Target Address Register */
++      0x0, /* WBx Target Pixel Format Register */
++      0x0, /* WBx Target AA Format Register */
++      0x0, /* WBx Target Layout */
++      0x0, /* WBx Target Scanline Length */
++      0x0, /* WBx Target Flags Register */
++      0x0, /* WBx MRT Enable Register */
++      0x0, /* WBx MRT Offset Register */
++      0x0, /* WBx Global Test Enable Register */
++      0x0, /* WBx Global Test Reference Value Register */
++      0x0  /* WBx Global Test Compare Function Register */
++};
++
++/* Performance Counter 0 Enable Register reset value */
++static const u32 mali_perf_cnt_enable_reset_value = 0;
++
++_mali_osk_errcode_t mali_pp_hard_reset(struct mali_pp_core *core)
++{
++      /* Bus must be stopped before calling this function */
++      const u32 reset_invalid_value = 0xC0FFE000;
++      const u32 reset_check_value = 0xC01A0000;
++      int i;
++
++      MALI_DEBUG_ASSERT_POINTER(core);
++      MALI_DEBUG_PRINT(2, ("Mali PP: Hard reset of core %s\n", core->hw_core.description));
++
++      /* Set register to a bogus value. The register will be used to detect when reset is complete */
++      mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, reset_invalid_value);
++      mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_NONE);
++
++      /* Force core to reset */
++      mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_FORCE_RESET);
++
++      /* Wait for reset to be complete */
++      for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++)
++      {
++              mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, reset_check_value);
++              if (reset_check_value == mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW))
++              {
++                      break;
++              }
++      }
++
++      if (MALI_REG_POLL_COUNT_FAST == i)
++      {
++              MALI_PRINT_ERROR(("Mali PP: The hard reset loop didn't work, unable to recover\n"));
++      }
++
++      mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, 0x00000000); /* set it back to the default */
++      /* Re-enable interrupts */
++      mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL);
++      mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
++
++      return _MALI_OSK_ERR_OK;
++}
++
++void mali_pp_reset_async(struct mali_pp_core *core)
++{
++      MALI_DEBUG_ASSERT_POINTER(core);
++
++      MALI_DEBUG_PRINT(4, ("Mali PP: Reset of core %s\n", core->hw_core.description));
++
++      mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, 0); /* disable the IRQs */
++      mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT, MALI200_REG_VAL_IRQ_MASK_ALL);
++      mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI400PP_REG_VAL_CTRL_MGMT_SOFT_RESET);
++}
++
++_mali_osk_errcode_t mali_pp_reset_wait(struct mali_pp_core *core)
++{
++      int i;
++      u32 rawstat = 0;
++
++      /* TODO: For virtual Mali-450 core, check that PP active in STATUS is 0 (this must be initiated from group) */
++
++      for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++)
++      {
++              rawstat = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT);
++              if (rawstat & MALI400PP_REG_VAL_IRQ_RESET_COMPLETED)
++              {
++                      break;
++              }
++      }
++
++      if (i == MALI_REG_POLL_COUNT_FAST)
++      {
++              MALI_PRINT_ERROR(("Mali PP: Failed to reset core %s, rawstat: 0x%08x\n",
++                               core->hw_core.description, rawstat));
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      /* Re-enable interrupts */
++      mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL);
++      mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
++
++      return _MALI_OSK_ERR_OK;
++}
++
++_mali_osk_errcode_t mali_pp_reset(struct mali_pp_core *core)
++{
++      mali_pp_reset_async(core);
++      return mali_pp_reset_wait(core);
++}
++
++void mali_pp_job_start(struct mali_pp_core *core, struct mali_pp_job *job, u32 sub_job, mali_bool restart_virtual)
++{
++      u32 num_frame_registers;
++      u32 relative_address;
++      u32 start_index;
++      u32 nr_of_regs;
++      u32 *frame_registers = mali_pp_job_get_frame_registers(job);
++      u32 *wb0_registers = mali_pp_job_get_wb0_registers(job);
++      u32 *wb1_registers = mali_pp_job_get_wb1_registers(job);
++      u32 *wb2_registers = mali_pp_job_get_wb2_registers(job);
++      core->counter_src0_used = mali_pp_job_get_perf_counter_src0(job);
++      core->counter_src1_used = mali_pp_job_get_perf_counter_src1(job);
++
++      MALI_DEBUG_ASSERT_POINTER(core);
++
++      /* Write frame registers */
++      num_frame_registers = (_MALI_PRODUCT_ID_MALI200 == mali_kernel_core_get_product_id()) ? MALI_PP_MALI200_NUM_FRAME_REGISTERS : MALI_PP_MALI400_NUM_FRAME_REGISTERS;
++
++      /*
++       * There are two frame registers which are different for each sub job:
++       * 1. The Renderer List Address Register (MALI200_REG_ADDR_FRAME)
++       * 2. The FS Stack Address Register (MALI200_REG_ADDR_STACK)
++       */
++      mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_FRAME, mali_pp_job_get_addr_frame(job, sub_job), mali_frame_registers_reset_values[MALI200_REG_ADDR_FRAME / sizeof(u32)]);
++
++      /* For virtual jobs, the stack address shouldn't be broadcast but written individually */
++      if (!mali_pp_job_is_virtual(job) || restart_virtual)
++      {
++              mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_STACK, mali_pp_job_get_addr_stack(job, sub_job), mali_frame_registers_reset_values[MALI200_REG_ADDR_STACK / sizeof(u32)]);
++      }
++
++      /* Write registers between MALI200_REG_ADDR_FRAME and MALI200_REG_ADDR_STACK */
++      relative_address = MALI200_REG_ADDR_RSW;
++      start_index = MALI200_REG_ADDR_RSW / sizeof(u32);
++      nr_of_regs = (MALI200_REG_ADDR_STACK - MALI200_REG_ADDR_RSW) / sizeof(u32);
++
++      mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core,
++              relative_address, &frame_registers[start_index],
++              nr_of_regs, &mali_frame_registers_reset_values[start_index]);
++
++      /* MALI200_REG_ADDR_STACK_SIZE */
++      relative_address = MALI200_REG_ADDR_STACK_SIZE;
++      start_index = MALI200_REG_ADDR_STACK_SIZE / sizeof(u32);
++
++      mali_hw_core_register_write_relaxed_conditional(&core->hw_core,
++              relative_address, frame_registers[start_index],
++              mali_frame_registers_reset_values[start_index]);
++
++      /* Skip 2 reserved registers */
++
++      /* Write remaining registers */
++      relative_address = MALI200_REG_ADDR_ORIGIN_OFFSET_X;
++      start_index = MALI200_REG_ADDR_ORIGIN_OFFSET_X / sizeof(u32);
++      nr_of_regs = num_frame_registers - MALI200_REG_ADDR_ORIGIN_OFFSET_X / sizeof(u32);
++
++      mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core,
++              relative_address, &frame_registers[start_index],
++              nr_of_regs, &mali_frame_registers_reset_values[start_index]);
++
++      /* Write WBx registers */
++      if (wb0_registers[0]) /* M200_WB0_REG_SOURCE_SELECT register */
++      {
++              mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB0, wb0_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values);
++      }
++
++      if (wb1_registers[0]) /* M200_WB1_REG_SOURCE_SELECT register */
++      {
++              mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB1, wb1_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values);
++      }
++
++      if (wb2_registers[0]) /* M200_WB2_REG_SOURCE_SELECT register */
++      {
++              mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB2, wb2_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values);
++      }
++
++      if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used)
++      {
++              mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used);
++              mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE, mali_perf_cnt_enable_reset_value);
++      }
++      if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used)
++      {
++              mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used);
++              mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE, mali_perf_cnt_enable_reset_value);
++      }
++
++      MALI_DEBUG_PRINT(3, ("Mali PP: Starting job 0x%08X part %u/%u on PP core %s\n", job, sub_job + 1, mali_pp_job_get_sub_job_count(job), core->hw_core.description));
++
++      /* Adding barrier to make sure all rester writes are finished */
++      _mali_osk_write_mem_barrier();
++
++      /* This is the command that starts the core. */
++      mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_START_RENDERING);
++
++      /* Adding barrier to make sure previous rester writes is finished */
++      _mali_osk_write_mem_barrier();
++}
++
++u32 mali_pp_core_get_version(struct mali_pp_core *core)
++{
++      MALI_DEBUG_ASSERT_POINTER(core);
++      return mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_VERSION);
++}
++
++struct mali_pp_core* mali_pp_get_global_pp_core(u32 index)
++{
++      if (MALI_MAX_NUMBER_OF_PP_CORES > index)
++      {
++              return mali_global_pp_cores[index];
++      }
++
++      return NULL;
++}
++
++u32 mali_pp_get_glob_num_pp_cores(void)
++{
++      return mali_global_num_pp_cores;
++}
++
++/* ------------- interrupt handling below ------------------ */
++static void mali_pp_irq_probe_trigger(void *data)
++{
++      struct mali_pp_core *core = (struct mali_pp_core *)data;
++      mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
++      mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT, MALI200_REG_VAL_IRQ_FORCE_HANG);
++      _mali_osk_mem_barrier();
++}
++
++static _mali_osk_errcode_t mali_pp_irq_probe_ack(void *data)
++{
++      struct mali_pp_core *core = (struct mali_pp_core *)data;
++      u32 irq_readout;
++
++      irq_readout = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_STATUS);
++      if (MALI200_REG_VAL_IRQ_FORCE_HANG & irq_readout)
++      {
++              mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_FORCE_HANG);
++              _mali_osk_mem_barrier();
++              return _MALI_OSK_ERR_OK;
++      }
++
++      return _MALI_OSK_ERR_FAULT;
++}
++
++
++#if 0
++static void mali_pp_print_registers(struct mali_pp_core *core)
++{
++      MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_VERSION = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_VERSION)));
++      MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_CURRENT_REND_LIST_ADDR = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_CURRENT_REND_LIST_ADDR)));
++      MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS)));
++      MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_RAWSTAT = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT)));
++      MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_MASK = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK)));
++      MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_STATUS)));
++      MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_BUS_ERROR_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_BUS_ERROR_STATUS)));
++      MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE)));
++      MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC)));
++      MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE)));
++      MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE)));
++      MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC)));
++      MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE)));
++}
++#endif
++
++#if 0
++void mali_pp_print_state(struct mali_pp_core *core)
++{
++      MALI_DEBUG_PRINT(2, ("Mali PP: State: 0x%08x\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS) ));
++}
++#endif
++
++void mali_pp_update_performance_counters(struct mali_pp_core *core, struct mali_pp_job *job, u32 subjob)
++{
++      u32 val0 = 0;
++      u32 val1 = 0;
++#if defined(CONFIG_MALI400_PROFILING)
++      int counter_index = COUNTER_FP0_C0 + (2 * core->core_id);
++#endif
++
++      if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used)
++      {
++              val0 = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE);
++
++              mali_pp_job_set_perf_counter_value0(job, subjob, val0);
++
++#if defined(CONFIG_MALI400_PROFILING)
++              /*todo: check if the group is virtual - in such case, does it make sense to send a HW counter ?*/
++              _mali_osk_profiling_report_hw_counter(counter_index, val0);
++#endif
++      }
++
++      if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used)
++      {
++              val1 = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE);
++              mali_pp_job_set_perf_counter_value1(job, subjob, val1);
++
++#if defined(CONFIG_MALI400_PROFILING)
++              /*todo: check if the group is virtual - in such case, does it make sense to send a HW counter ?*/
++              _mali_osk_profiling_report_hw_counter(counter_index + 1, val1);
++#endif
++      }
++}
++
++#if MALI_STATE_TRACKING
++u32 mali_pp_dump_state(struct mali_pp_core *core, char *buf, u32 size)
++{
++      int n = 0;
++
++      n += _mali_osk_snprintf(buf + n, size - n, "\tPP #%d: %s\n", core->core_id, core->hw_core.description);
++
++      return n;
++}
++#endif
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_pp.h b/drivers/gpu/arm/mali400/mali/common/mali_pp.h
+new file mode 100644
+index 0000000..d654df2
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_pp.h
+@@ -0,0 +1,103 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_PP_H__
++#define __MALI_PP_H__
++
++#include "mali_osk.h"
++#include "mali_pp_job.h"
++#include "mali_hw_core.h"
++
++struct mali_group;
++
++#define MALI_MAX_NUMBER_OF_PP_CORES        9
++
++/**
++ * Definition of the PP core struct
++ * Used to track a PP core in the system.
++ */
++struct mali_pp_core
++{
++      struct mali_hw_core  hw_core;           /**< Common for all HW cores */
++      _mali_osk_irq_t     *irq;               /**< IRQ handler */
++      u32                  core_id;           /**< Unique core ID */
++      u32                  counter_src0_used; /**< The selected performance counter 0 when a job is running */
++      u32                  counter_src1_used; /**< The selected performance counter 1 when a job is running */
++};
++
++_mali_osk_errcode_t mali_pp_initialize(void);
++void mali_pp_terminate(void);
++
++struct mali_pp_core *mali_pp_create(const _mali_osk_resource_t * resource, struct mali_group *group, mali_bool is_virtual);
++void mali_pp_delete(struct mali_pp_core *core);
++
++void mali_pp_stop_bus(struct mali_pp_core *core);
++_mali_osk_errcode_t mali_pp_stop_bus_wait(struct mali_pp_core *core);
++void mali_pp_reset_async(struct mali_pp_core *core);
++_mali_osk_errcode_t mali_pp_reset_wait(struct mali_pp_core *core);
++_mali_osk_errcode_t mali_pp_reset(struct mali_pp_core *core);
++_mali_osk_errcode_t mali_pp_hard_reset(struct mali_pp_core *core);
++
++void mali_pp_job_start(struct mali_pp_core *core, struct mali_pp_job *job, u32 sub_job, mali_bool restart_virtual);
++
++u32 mali_pp_core_get_version(struct mali_pp_core *core);
++
++MALI_STATIC_INLINE u32 mali_pp_core_get_id(struct mali_pp_core *core)
++{
++      MALI_DEBUG_ASSERT_POINTER(core);
++      return core->core_id;
++}
++
++struct mali_pp_core* mali_pp_get_global_pp_core(u32 index);
++u32 mali_pp_get_glob_num_pp_cores(void);
++
++/* Debug */
++u32 mali_pp_dump_state(struct mali_pp_core *core, char *buf, u32 size);
++
++void mali_pp_update_performance_counters(struct mali_pp_core *core, struct mali_pp_job *job, u32 subjob);
++
++MALI_STATIC_INLINE const char *mali_pp_get_hw_core_desc(struct mali_pp_core *core)
++{
++      return core->hw_core.description;
++}
++
++/*** Register reading/writing functions ***/
++MALI_STATIC_INLINE u32 mali_pp_get_int_stat(struct mali_pp_core *core)
++{
++      return mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_STATUS);
++}
++
++MALI_STATIC_INLINE u32 mali_pp_read_rawstat(struct mali_pp_core *core)
++{
++      return mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT) & MALI200_REG_VAL_IRQ_MASK_USED;
++}
++
++MALI_STATIC_INLINE void mali_pp_mask_all_interrupts(struct mali_pp_core *core)
++{
++      mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_NONE);
++}
++
++MALI_STATIC_INLINE void mali_pp_clear_hang_interrupt(struct mali_pp_core *core)
++{
++      mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_HANG);
++}
++
++MALI_STATIC_INLINE void mali_pp_enable_interrupts(struct mali_pp_core *core)
++{
++      mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
++}
++
++MALI_STATIC_INLINE void mali_pp_write_addr_stack(struct mali_pp_core *core, struct mali_pp_job *job)
++{
++      u32 addr = mali_pp_job_get_addr_stack(job, core->core_id);
++      mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_STACK, addr);
++}
++
++#endif /* __MALI_PP_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_pp_job.c b/drivers/gpu/arm/mali400/mali/common/mali_pp_job.c
+new file mode 100644
+index 0000000..f863e9d
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_pp_job.c
+@@ -0,0 +1,137 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_pp_job.h"
++#include "mali_osk.h"
++#include "mali_osk_list.h"
++#include "mali_kernel_common.h"
++#include "mali_uk_types.h"
++
++static u32 pp_counter_src0 = MALI_HW_CORE_NO_COUNTER;      /**< Performance counter 0, MALI_HW_CORE_NO_COUNTER for disabled */
++static u32 pp_counter_src1 = MALI_HW_CORE_NO_COUNTER;      /**< Performance counter 1, MALI_HW_CORE_NO_COUNTER for disabled */
++
++struct mali_pp_job *mali_pp_job_create(struct mali_session_data *session, _mali_uk_pp_start_job_s *uargs, u32 id)
++{
++      struct mali_pp_job *job;
++      u32 perf_counter_flag;
++
++      job = _mali_osk_malloc(sizeof(struct mali_pp_job));
++      if (NULL != job)
++      {
++              u32 i;
++
++              if (0 != _mali_osk_copy_from_user(&job->uargs, uargs, sizeof(_mali_uk_pp_start_job_s)))
++              {
++                      _mali_osk_free(job);
++                      return NULL;
++              }
++
++              if (job->uargs.num_cores > _MALI_PP_MAX_SUB_JOBS)
++              {
++                      MALI_PRINT_ERROR(("Mali PP job: Too many sub jobs specified in job object\n"));
++                      _mali_osk_free(job);
++                      return NULL;
++              }
++
++              if (!mali_pp_job_use_no_notification(job))
++              {
++                      job->finished_notification = _mali_osk_notification_create(_MALI_NOTIFICATION_PP_FINISHED, sizeof(_mali_uk_pp_job_finished_s));
++                      if (NULL == job->finished_notification)
++                      {
++                              _mali_osk_free(job);
++                              return NULL;
++                      }
++              }
++              else
++              {
++                      job->finished_notification = NULL;
++              }
++
++              perf_counter_flag = mali_pp_job_get_perf_counter_flag(job);
++
++              /* case when no counters came from user space
++               * so pass the debugfs / DS-5 provided global ones to the job object */
++              if (!((perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE) ||
++                              (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE)))
++              {
++                      mali_pp_job_set_perf_counter_src0(job, mali_pp_job_get_pp_counter_src0());
++                      mali_pp_job_set_perf_counter_src1(job, mali_pp_job_get_pp_counter_src1());
++              }
++
++              _mali_osk_list_init(&job->list);
++              job->session = session;
++              _mali_osk_list_init(&job->session_list);
++              job->id = id;
++
++              for (i = 0; i < job->uargs.num_cores; i++)
++              {
++                      job->perf_counter_value0[i] = 0;
++                      job->perf_counter_value1[i] = 0;
++              }
++              job->sub_jobs_num = job->uargs.num_cores ? job->uargs.num_cores : 1;
++              job->sub_jobs_started = 0;
++              job->sub_jobs_completed = 0;
++              job->sub_job_errors = 0;
++              job->pid = _mali_osk_get_pid();
++              job->tid = _mali_osk_get_tid();
++#if defined(CONFIG_SYNC)
++/* MALI_SEC */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
++              job->sync_point = NULL;
++              job->pre_fence = NULL;
++              job->sync_work = NULL;
++#endif
++#endif
++
++              return job;
++      }
++
++      return NULL;
++}
++
++void mali_pp_job_delete(struct mali_pp_job *job)
++{
++#ifdef CONFIG_SYNC
++/* MALI_SEC */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
++      if (NULL != job->pre_fence) sync_fence_put(job->pre_fence);
++      if (NULL != job->sync_point) sync_fence_put(job->sync_point->fence);
++#endif
++#endif
++      if (NULL != job->finished_notification)
++      {
++              _mali_osk_notification_delete(job->finished_notification);
++      }
++      _mali_osk_free(job);
++}
++
++u32 mali_pp_job_get_pp_counter_src0(void)
++{
++      return pp_counter_src0;
++}
++
++mali_bool mali_pp_job_set_pp_counter_src0(u32 counter)
++{
++      pp_counter_src0 = counter;
++
++      return MALI_TRUE;
++}
++
++u32 mali_pp_job_get_pp_counter_src1(void)
++{
++      return pp_counter_src1;
++}
++
++mali_bool mali_pp_job_set_pp_counter_src1(u32 counter)
++{
++      pp_counter_src1 = counter;
++
++      return MALI_TRUE;
++}
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_pp_job.h b/drivers/gpu/arm/mali400/mali/common/mali_pp_job.h
+new file mode 100644
+index 0000000..f8a630e
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_pp_job.h
+@@ -0,0 +1,313 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_PP_JOB_H__
++#define __MALI_PP_JOB_H__
++
++#include "mali_osk.h"
++#include "mali_osk_list.h"
++#include "mali_uk_types.h"
++#include "mali_session.h"
++#include "mali_kernel_common.h"
++#include "regs/mali_200_regs.h"
++#include "mali_kernel_core.h"
++#ifdef CONFIG_SYNC
++/* MALI_SEC */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
++#include <linux/sync.h>
++#endif
++#endif
++#include "mali_dlbu.h"
++
++/**
++ * The structure represents a PP job, including all sub-jobs
++ * (This struct unfortunately needs to be public because of how the _mali_osk_list_*
++ * mechanism works)
++ */
++struct mali_pp_job
++{
++      _mali_osk_list_t list;                             /**< Used to link jobs together in the scheduler queue */
++      struct mali_session_data *session;                 /**< Session which submitted this job */
++      _mali_osk_list_t session_list;                     /**< Used to link jobs together in the session job list */
++      _mali_uk_pp_start_job_s uargs;                     /**< Arguments from user space */
++      u32 id;                                            /**< Identifier for this job in kernel space (sequential numbering) */
++      u32 perf_counter_value0[_MALI_PP_MAX_SUB_JOBS];    /**< Value of performance counter 0 (to be returned to user space), one for each sub job */
++      u32 perf_counter_value1[_MALI_PP_MAX_SUB_JOBS];    /**< Value of performance counter 1 (to be returned to user space), one for each sub job */
++      u32 sub_jobs_num;                                  /**< Number of subjobs; set to 1 for Mali-450 if DLBU is used, otherwise equals number of PP cores */
++      u32 sub_jobs_started;                              /**< Total number of sub-jobs started (always started in ascending order) */
++      u32 sub_jobs_completed;                            /**< Number of completed sub-jobs in this superjob */
++      u32 sub_job_errors;                                /**< Bitfield with errors (errors for each single sub-job is or'ed together) */
++      u32 pid;                                           /**< Process ID of submitting process */
++      u32 tid;                                           /**< Thread ID of submitting thread */
++      _mali_osk_notification_t *finished_notification;   /**< Notification sent back to userspace on job complete */
++#ifdef CONFIG_SYNC
++/* MALI_SEC */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
++      mali_sync_pt *sync_point;                          /**< Sync point to signal on completion */
++      struct sync_fence_waiter sync_waiter;              /**< Sync waiter for async wait */
++      _mali_osk_wq_work_t *sync_work;                    /**< Work to schedule in callback */
++      struct sync_fence *pre_fence;                      /**< Sync fence this job must wait for */
++#endif
++#endif
++};
++
++struct mali_pp_job *mali_pp_job_create(struct mali_session_data *session, _mali_uk_pp_start_job_s *uargs, u32 id);
++void mali_pp_job_delete(struct mali_pp_job *job);
++
++u32 mali_pp_job_get_pp_counter_src0(void);
++mali_bool mali_pp_job_set_pp_counter_src0(u32 counter);
++u32 mali_pp_job_get_pp_counter_src1(void);
++mali_bool mali_pp_job_set_pp_counter_src1(u32 counter);
++
++MALI_STATIC_INLINE u32 mali_pp_job_get_id(struct mali_pp_job *job)
++{
++      return (NULL == job) ? 0 : job->id;
++}
++
++MALI_STATIC_INLINE u32 mali_pp_job_get_user_id(struct mali_pp_job *job)
++{
++      return job->uargs.user_job_ptr;
++}
++
++MALI_STATIC_INLINE u32 mali_pp_job_get_frame_builder_id(struct mali_pp_job *job)
++{
++      return job->uargs.frame_builder_id;
++}
++
++MALI_STATIC_INLINE u32 mali_pp_job_get_flush_id(struct mali_pp_job *job)
++{
++      return job->uargs.flush_id;
++}
++
++MALI_STATIC_INLINE u32 mali_pp_job_get_pid(struct mali_pp_job *job)
++{
++      return job->pid;
++}
++
++MALI_STATIC_INLINE u32 mali_pp_job_get_tid(struct mali_pp_job *job)
++{
++      return job->tid;
++}
++
++MALI_STATIC_INLINE u32* mali_pp_job_get_frame_registers(struct mali_pp_job *job)
++{
++      return job->uargs.frame_registers;
++}
++
++MALI_STATIC_INLINE u32* mali_pp_job_get_dlbu_registers(struct mali_pp_job *job)
++{
++      return job->uargs.dlbu_registers;
++}
++
++MALI_STATIC_INLINE mali_bool mali_pp_job_is_virtual(struct mali_pp_job *job)
++{
++      return 0 == job->uargs.num_cores;
++}
++
++MALI_STATIC_INLINE u32 mali_pp_job_get_addr_frame(struct mali_pp_job *job, u32 sub_job)
++{
++      if (mali_pp_job_is_virtual(job))
++      {
++              return MALI_DLBU_VIRT_ADDR;
++      }
++      else if (0 == sub_job)
++      {
++              return job->uargs.frame_registers[MALI200_REG_ADDR_FRAME / sizeof(u32)];
++      }
++      else if (sub_job < _MALI_PP_MAX_SUB_JOBS)
++      {
++              return job->uargs.frame_registers_addr_frame[sub_job - 1];
++      }
++
++      return 0;
++}
++
++MALI_STATIC_INLINE u32 mali_pp_job_get_addr_stack(struct mali_pp_job *job, u32 sub_job)
++{
++      if (0 == sub_job)
++      {
++              return job->uargs.frame_registers[MALI200_REG_ADDR_STACK / sizeof(u32)];
++      }
++      else if (sub_job < _MALI_PP_MAX_SUB_JOBS)
++      {
++              return job->uargs.frame_registers_addr_stack[sub_job - 1];
++      }
++
++      return 0;
++}
++
++MALI_STATIC_INLINE u32* mali_pp_job_get_wb0_registers(struct mali_pp_job *job)
++{
++      return job->uargs.wb0_registers;
++}
++
++MALI_STATIC_INLINE u32* mali_pp_job_get_wb1_registers(struct mali_pp_job *job)
++{
++      return job->uargs.wb1_registers;
++}
++
++MALI_STATIC_INLINE u32* mali_pp_job_get_wb2_registers(struct mali_pp_job *job)
++{
++      return job->uargs.wb2_registers;
++}
++
++MALI_STATIC_INLINE void mali_pp_job_disable_wb0(struct mali_pp_job *job)
++{
++      job->uargs.wb0_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0;
++}
++
++MALI_STATIC_INLINE void mali_pp_job_disable_wb1(struct mali_pp_job *job)
++{
++      job->uargs.wb1_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0;
++}
++
++MALI_STATIC_INLINE void mali_pp_job_disable_wb2(struct mali_pp_job *job)
++{
++      job->uargs.wb2_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0;
++}
++
++MALI_STATIC_INLINE struct mali_session_data *mali_pp_job_get_session(struct mali_pp_job *job)
++{
++      return job->session;
++}
++
++MALI_STATIC_INLINE mali_bool mali_pp_job_has_unstarted_sub_jobs(struct mali_pp_job *job)
++{
++      return (job->sub_jobs_started < job->sub_jobs_num) ? MALI_TRUE : MALI_FALSE;
++}
++
++/* Function used when we are terminating a session with jobs. Return TRUE if it has a rendering job.
++   Makes sure that no new subjobs are started. */
++MALI_STATIC_INLINE void mali_pp_job_mark_unstarted_failed(struct mali_pp_job *job)
++{
++      u32 jobs_remaining = job->sub_jobs_num - job->sub_jobs_started;
++      job->sub_jobs_started   += jobs_remaining;
++      job->sub_jobs_completed += jobs_remaining;
++      job->sub_job_errors     += jobs_remaining;
++}
++
++MALI_STATIC_INLINE mali_bool mali_pp_job_is_complete(struct mali_pp_job *job)
++{
++      return (job->sub_jobs_num == job->sub_jobs_completed) ? MALI_TRUE : MALI_FALSE;
++}
++
++MALI_STATIC_INLINE u32 mali_pp_job_get_first_unstarted_sub_job(struct mali_pp_job *job)
++{
++      return job->sub_jobs_started;
++}
++
++MALI_STATIC_INLINE u32 mali_pp_job_get_sub_job_count(struct mali_pp_job *job)
++{
++      return job->sub_jobs_num;
++}
++
++MALI_STATIC_INLINE void mali_pp_job_mark_sub_job_started(struct mali_pp_job *job, u32 sub_job)
++{
++      /* Assert that we are marking the "first unstarted sub job" as started */
++      MALI_DEBUG_ASSERT(job->sub_jobs_started == sub_job);
++      job->sub_jobs_started++;
++}
++
++MALI_STATIC_INLINE void mali_pp_job_mark_sub_job_not_stated(struct mali_pp_job *job, u32 sub_job)
++{
++      /* This is only safe on Mali-200. */
++      MALI_DEBUG_ASSERT(_MALI_PRODUCT_ID_MALI200 == mali_kernel_core_get_product_id());
++
++      job->sub_jobs_started--;
++}
++
++MALI_STATIC_INLINE void mali_pp_job_mark_sub_job_completed(struct mali_pp_job *job, mali_bool success)
++{
++      job->sub_jobs_completed++;
++      if ( MALI_FALSE == success )
++      {
++              job->sub_job_errors++;
++      }
++}
++
++MALI_STATIC_INLINE mali_bool mali_pp_job_was_success(struct mali_pp_job *job)
++{
++      if ( 0 == job->sub_job_errors )
++      {
++              return MALI_TRUE;
++      }
++      return MALI_FALSE;
++}
++
++MALI_STATIC_INLINE mali_bool mali_pp_job_has_active_barrier(struct mali_pp_job *job)
++{
++      return job->uargs.flags & _MALI_PP_JOB_FLAG_BARRIER ? MALI_TRUE : MALI_FALSE;
++}
++
++MALI_STATIC_INLINE void mali_pp_job_barrier_enforced(struct mali_pp_job *job)
++{
++      job->uargs.flags &= ~_MALI_PP_JOB_FLAG_BARRIER;
++}
++
++MALI_STATIC_INLINE mali_bool mali_pp_job_use_no_notification(struct mali_pp_job *job)
++{
++      return job->uargs.flags & _MALI_PP_JOB_FLAG_NO_NOTIFICATION ? MALI_TRUE : MALI_FALSE;
++}
++
++MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_flag(struct mali_pp_job *job)
++{
++      return job->uargs.perf_counter_flag;
++}
++
++MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_src0(struct mali_pp_job *job)
++{
++      return job->uargs.perf_counter_src0;
++}
++
++MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_src1(struct mali_pp_job *job)
++{
++      return job->uargs.perf_counter_src1;
++}
++
++MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_value0(struct mali_pp_job *job, u32 sub_job)
++{
++      return job->perf_counter_value0[sub_job];
++}
++
++MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_value1(struct mali_pp_job *job, u32 sub_job)
++{
++      return job->perf_counter_value1[sub_job];
++}
++
++MALI_STATIC_INLINE void mali_pp_job_set_perf_counter_src0(struct mali_pp_job *job, u32 src)
++{
++      job->uargs.perf_counter_src0 = src;
++}
++
++MALI_STATIC_INLINE void mali_pp_job_set_perf_counter_src1(struct mali_pp_job *job, u32 src)
++{
++      job->uargs.perf_counter_src1 = src;
++}
++
++MALI_STATIC_INLINE void mali_pp_job_set_perf_counter_value0(struct mali_pp_job *job, u32 sub_job, u32 value)
++{
++      job->perf_counter_value0[sub_job] = value;
++}
++
++MALI_STATIC_INLINE void mali_pp_job_set_perf_counter_value1(struct mali_pp_job *job, u32 sub_job, u32 value)
++{
++      job->perf_counter_value1[sub_job] = value;
++}
++
++MALI_STATIC_INLINE _mali_osk_errcode_t mali_pp_job_check(struct mali_pp_job *job)
++{
++      if (mali_pp_job_is_virtual(job) && job->sub_jobs_num != 1)
++      {
++              return _MALI_OSK_ERR_FAULT;
++      }
++      return _MALI_OSK_ERR_OK;
++}
++
++#endif /* __MALI_PP_JOB_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_pp_scheduler.c b/drivers/gpu/arm/mali400/mali/common/mali_pp_scheduler.c
+new file mode 100644
+index 0000000..3ba1012
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_pp_scheduler.c
+@@ -0,0 +1,1335 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_pp_scheduler.h"
++#include "mali_kernel_common.h"
++#include "mali_kernel_core.h"
++#include "mali_osk.h"
++#include "mali_osk_list.h"
++#include "mali_scheduler.h"
++#include "mali_pp.h"
++#include "mali_pp_job.h"
++#include "mali_group.h"
++#include "mali_pm.h"
++
++#if defined(CONFIG_SYNC)
++#define MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE 1
++#endif
++
++/* Maximum of 8 PP cores (a group can only have maximum of 1 PP core) */
++#define MALI_MAX_NUMBER_OF_PP_GROUPS 9
++
++static mali_bool mali_pp_scheduler_is_suspended(void);
++static void mali_pp_scheduler_do_schedule(void *arg);
++#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
++static void mali_pp_scheduler_do_job_delete(void *arg);
++#endif
++
++static u32 pp_version = 0;
++
++/* Physical job queue */
++static _MALI_OSK_LIST_HEAD_STATIC_INIT(job_queue);              /* List of physical jobs with some unscheduled work */
++static u32 job_queue_depth = 0;
++
++/* Physical groups */
++static _MALI_OSK_LIST_HEAD_STATIC_INIT(group_list_working);     /* List of physical groups with working jobs on the pp core */
++static _MALI_OSK_LIST_HEAD_STATIC_INIT(group_list_idle);        /* List of physical groups with idle jobs on the pp core */
++
++/* Virtual job queue (Mali-450 only) */
++static _MALI_OSK_LIST_HEAD_STATIC_INIT(virtual_job_queue);      /* List of unstarted jobs for the virtual group */
++static u32 virtual_job_queue_depth = 0;
++
++/* Virtual group (Mali-450 only) */
++static struct mali_group *virtual_group = NULL;                 /* Virtual group (if any) */
++static mali_bool virtual_group_working = MALI_FALSE;            /* Flag which indicates whether the virtual group is working or idle */
++
++/* Number of physical cores */
++static u32 num_cores = 0;
++
++/* Variables to allow safe pausing of the scheduler */
++static _mali_osk_wait_queue_t *pp_scheduler_working_wait_queue = NULL;
++static u32 pause_count = 0;
++
++static _mali_osk_lock_t *pp_scheduler_lock = NULL;
++/* Contains tid of thread that locked the scheduler or 0, if not locked */
++MALI_DEBUG_CODE(static u32 pp_scheduler_lock_owner = 0);
++
++static _mali_osk_wq_work_t *pp_scheduler_wq_schedule = NULL;
++
++#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
++static _mali_osk_wq_work_t *pp_scheduler_wq_job_delete = NULL;
++static _mali_osk_lock_t *pp_scheduler_job_delete_lock = NULL;
++static _MALI_OSK_LIST_HEAD_STATIC_INIT(pp_scheduler_job_deletion_queue);
++#endif
++
++_mali_osk_errcode_t mali_pp_scheduler_initialize(void)
++{
++      struct mali_group *group;
++      struct mali_pp_core *pp_core;
++      _mali_osk_lock_flags_t lock_flags;
++      u32 num_groups;
++      u32 i;
++
++#if defined(MALI_UPPER_HALF_SCHEDULING)
++      lock_flags = _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE;
++#else
++      lock_flags = _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE;
++#endif
++
++      _MALI_OSK_INIT_LIST_HEAD(&job_queue);
++      _MALI_OSK_INIT_LIST_HEAD(&group_list_working);
++      _MALI_OSK_INIT_LIST_HEAD(&group_list_idle);
++
++      _MALI_OSK_INIT_LIST_HEAD(&virtual_job_queue);
++
++      pp_scheduler_lock = _mali_osk_lock_init(lock_flags, 0, _MALI_OSK_LOCK_ORDER_SCHEDULER);
++      if (NULL == pp_scheduler_lock)
++      {
++              return _MALI_OSK_ERR_NOMEM;
++      }
++
++      pp_scheduler_working_wait_queue = _mali_osk_wait_queue_init();
++      if (NULL == pp_scheduler_working_wait_queue)
++      {
++              _mali_osk_lock_term(pp_scheduler_lock);
++              return _MALI_OSK_ERR_NOMEM;
++      }
++
++      pp_scheduler_wq_schedule = _mali_osk_wq_create_work(mali_pp_scheduler_do_schedule, NULL);
++      if (NULL == pp_scheduler_wq_schedule)
++      {
++              _mali_osk_wait_queue_term(pp_scheduler_working_wait_queue);
++              _mali_osk_lock_term(pp_scheduler_lock);
++              return _MALI_OSK_ERR_NOMEM;
++      }
++
++#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
++      pp_scheduler_wq_job_delete = _mali_osk_wq_create_work(mali_pp_scheduler_do_job_delete, NULL);
++      if (NULL == pp_scheduler_wq_job_delete)
++      {
++              _mali_osk_wq_delete_work(pp_scheduler_wq_schedule);
++              _mali_osk_wait_queue_term(pp_scheduler_working_wait_queue);
++              _mali_osk_lock_term(pp_scheduler_lock);
++              return _MALI_OSK_ERR_NOMEM;
++      }
++
++      pp_scheduler_job_delete_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_SCHEDULER_DEFERRED);
++      if (NULL == pp_scheduler_job_delete_lock)
++      {
++              _mali_osk_wq_delete_work(pp_scheduler_wq_job_delete);
++              _mali_osk_wq_delete_work(pp_scheduler_wq_schedule);
++              _mali_osk_wait_queue_term(pp_scheduler_working_wait_queue);
++              _mali_osk_lock_term(pp_scheduler_lock);
++              return _MALI_OSK_ERR_NOMEM;
++      }
++#endif
++
++      num_groups = mali_group_get_glob_num_groups();
++
++      /* Do we have a virtual group? */
++      for (i = 0; i < num_groups; i++)
++      {
++              group = mali_group_get_glob_group(i);
++
++              if (mali_group_is_virtual(group))
++              {
++                      MALI_DEBUG_PRINT(3, ("Found virtual group %p\n", group));
++
++                      virtual_group = group;
++                      break;
++              }
++      }
++
++      /* Find all the available PP cores */
++      for (i = 0; i < num_groups; i++)
++      {
++              group = mali_group_get_glob_group(i);
++              pp_core = mali_group_get_pp_core(group);
++
++              if (NULL != pp_core && !mali_group_is_virtual(group))
++              {
++                      if (0 == pp_version)
++                      {
++                              /* Retrieve PP version from the first available PP core */
++                              pp_version = mali_pp_core_get_version(pp_core);
++                      }
++
++                      if (NULL != virtual_group)
++                      {
++                              /* Add all physical PP cores to the virtual group */
++                              mali_group_lock(virtual_group);
++                              group->state = MALI_GROUP_STATE_JOINING_VIRTUAL;
++                              mali_group_add_group(virtual_group, group);
++                              mali_group_unlock(virtual_group);
++                      }
++                      else
++                      {
++                              _mali_osk_list_add(&group->pp_scheduler_list, &group_list_idle);
++                      }
++
++                      num_cores++;
++              }
++      }
++
++      return _MALI_OSK_ERR_OK;
++}
++
++void mali_pp_scheduler_terminate(void)
++{
++      struct mali_group *group, *temp;
++
++      /* Delete all groups owned by scheduler */
++      if (NULL != virtual_group)
++      {
++              mali_group_delete(virtual_group);
++      }
++
++      MALI_DEBUG_ASSERT(_mali_osk_list_empty(&group_list_working));
++      _MALI_OSK_LIST_FOREACHENTRY(group, temp, &group_list_idle, struct mali_group, pp_scheduler_list)
++      {
++              mali_group_delete(group);
++      }
++
++#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
++      _mali_osk_lock_term(pp_scheduler_job_delete_lock);
++      _mali_osk_wq_delete_work(pp_scheduler_wq_job_delete);
++#endif
++
++      _mali_osk_wq_delete_work(pp_scheduler_wq_schedule);
++      _mali_osk_wait_queue_term(pp_scheduler_working_wait_queue);
++      _mali_osk_lock_term(pp_scheduler_lock);
++}
++
++MALI_STATIC_INLINE void mali_pp_scheduler_lock(void)
++{
++      if(_MALI_OSK_ERR_OK != _mali_osk_lock_wait(pp_scheduler_lock, _MALI_OSK_LOCKMODE_RW))
++      {
++              /* Non-interruptable lock failed: this should never happen. */
++              MALI_DEBUG_ASSERT(0);
++      }
++      MALI_DEBUG_PRINT(5, ("Mali PP scheduler: PP scheduler lock taken\n"));
++      MALI_DEBUG_ASSERT(0 == pp_scheduler_lock_owner);
++      MALI_DEBUG_CODE(pp_scheduler_lock_owner = _mali_osk_get_tid());
++}
++
++MALI_STATIC_INLINE void mali_pp_scheduler_unlock(void)
++{
++      MALI_DEBUG_PRINT(5, ("Mali PP scheduler: Releasing PP scheduler lock\n"));
++      MALI_DEBUG_ASSERT(_mali_osk_get_tid() == pp_scheduler_lock_owner);
++      MALI_DEBUG_CODE(pp_scheduler_lock_owner = 0);
++      _mali_osk_lock_signal(pp_scheduler_lock, _MALI_OSK_LOCKMODE_RW);
++}
++
++#ifdef DEBUG
++MALI_STATIC_INLINE void mali_pp_scheduler_assert_locked(void)
++{
++      MALI_DEBUG_ASSERT(_mali_osk_get_tid() == pp_scheduler_lock_owner);
++}
++#define MALI_ASSERT_PP_SCHEDULER_LOCKED() mali_pp_scheduler_assert_locked()
++#else
++#define MALI_ASSERT_PP_SCHEDULER_LOCKED()
++#endif
++
++/**
++ * Returns a physical job if a physical job is ready to run (no barrier present)
++ */
++MALI_STATIC_INLINE struct mali_pp_job *mali_pp_scheduler_get_physical_job(void)
++{
++      MALI_ASSERT_PP_SCHEDULER_LOCKED();
++
++      if (!_mali_osk_list_empty(&job_queue))
++      {
++              struct mali_pp_job *job;
++
++              MALI_DEBUG_ASSERT(job_queue_depth > 0);
++              job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_pp_job, list);
++
++              if (!mali_pp_job_has_active_barrier(job))
++              {
++                      return job;
++              }
++      }
++
++      return NULL;
++}
++
++MALI_STATIC_INLINE void mali_pp_scheduler_dequeue_physical_job(struct mali_pp_job *job)
++{
++      MALI_ASSERT_PP_SCHEDULER_LOCKED();
++      MALI_DEBUG_ASSERT(job_queue_depth > 0);
++
++      /* Remove job from queue */
++      if (!mali_pp_job_has_unstarted_sub_jobs(job))
++      {
++              /* All sub jobs have been started: remove job from queue */
++              _mali_osk_list_delinit(&job->list);
++      }
++
++      --job_queue_depth;
++}
++
++/**
++ * Returns a virtual job if a virtual job is ready to run (no barrier present)
++ */
++MALI_STATIC_INLINE struct mali_pp_job *mali_pp_scheduler_get_virtual_job(void)
++{
++      MALI_ASSERT_PP_SCHEDULER_LOCKED();
++      MALI_DEBUG_ASSERT_POINTER(virtual_group);
++
++      if (!_mali_osk_list_empty(&virtual_job_queue))
++      {
++              struct mali_pp_job *job;
++
++              MALI_DEBUG_ASSERT(virtual_job_queue_depth > 0);
++              job = _MALI_OSK_LIST_ENTRY(virtual_job_queue.next, struct mali_pp_job, list);
++
++              if (!mali_pp_job_has_active_barrier(job))
++              {
++                      return job;
++              }
++      }
++
++      return NULL;
++}
++
++MALI_STATIC_INLINE void mali_pp_scheduler_dequeue_virtual_job(struct mali_pp_job *job)
++{
++      MALI_ASSERT_PP_SCHEDULER_LOCKED();
++      MALI_DEBUG_ASSERT(virtual_job_queue_depth > 0);
++
++      /* Remove job from queue */
++      _mali_osk_list_delinit(&job->list);
++      --virtual_job_queue_depth;
++}
++
++/**
++ * Checks if the criteria is met for removing a physical core from virtual group
++ */
++MALI_STATIC_INLINE mali_bool mali_pp_scheduler_can_move_virtual_to_physical(void)
++{
++      MALI_ASSERT_PP_SCHEDULER_LOCKED();
++      MALI_DEBUG_ASSERT(NULL != virtual_group);
++      MALI_ASSERT_GROUP_LOCKED(virtual_group);
++      /*
++       * The criteria for taking out a physical group from a virtual group are the following:
++       * - There virtual group is idle
++       * - There are currently no physical groups (idle and working)
++       * - There are physical jobs to be scheduled (without a barrier)
++       */
++      return (!virtual_group_working) &&
++             _mali_osk_list_empty(&group_list_idle) &&
++             _mali_osk_list_empty(&group_list_working) &&
++             (NULL != mali_pp_scheduler_get_physical_job());
++}
++
++MALI_STATIC_INLINE struct mali_group *mali_pp_scheduler_acquire_physical_group(void)
++{
++      MALI_ASSERT_PP_SCHEDULER_LOCKED();
++
++      if (!_mali_osk_list_empty(&group_list_idle))
++      {
++              MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Acquiring physical group from idle list\n"));
++              return _MALI_OSK_LIST_ENTRY(group_list_idle.next, struct mali_group, pp_scheduler_list);
++      }
++      else if (NULL != virtual_group)
++      {
++              MALI_ASSERT_GROUP_LOCKED(virtual_group);
++              if (mali_pp_scheduler_can_move_virtual_to_physical())
++              {
++                      MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Acquiring physical group from virtual group\n"));
++                      return mali_group_acquire_group(virtual_group);
++              }
++      }
++
++      return NULL;
++}
++
++static void mali_pp_scheduler_schedule(void)
++{
++      struct mali_group* physical_groups_to_start[MALI_MAX_NUMBER_OF_PP_GROUPS-1];
++      struct mali_pp_job* physical_jobs_to_start[MALI_MAX_NUMBER_OF_PP_GROUPS-1];
++      u32 physical_subjobs_to_start[MALI_MAX_NUMBER_OF_PP_GROUPS-1];
++      int num_physical_jobs_to_start = 0;
++      int i;
++
++      if (NULL != virtual_group)
++      {
++              /* Need to lock the virtual group because we might need to grab a physical group from it */
++              mali_group_lock(virtual_group);
++      }
++
++      mali_pp_scheduler_lock();
++      if (pause_count > 0)
++      {
++              /* Scheduler is suspended, don't schedule any jobs */
++              mali_pp_scheduler_unlock();
++              if (NULL != virtual_group)
++              {
++                      mali_group_unlock(virtual_group);
++              }
++              return;
++      }
++
++      /* Find physical job(s) to schedule first */
++      while (1)
++      {
++              struct mali_group *group;
++              struct mali_pp_job *job;
++              u32 subjob;
++
++              job = mali_pp_scheduler_get_physical_job();
++              if (NULL == job)
++              {
++                      break; /* No job, early out */
++              }
++
++              MALI_DEBUG_ASSERT(!mali_pp_job_is_virtual(job));
++              MALI_DEBUG_ASSERT(mali_pp_job_has_unstarted_sub_jobs(job));
++              MALI_DEBUG_ASSERT(1 <= mali_pp_job_get_sub_job_count(job));
++
++              /* Acquire a physical group, either from the idle list or from the virtual group.
++               * In case the group was acquired from the virtual group, it's state will be
++               * LEAVING_VIRTUAL and must be set to IDLE before it can be used. */
++              group = mali_pp_scheduler_acquire_physical_group();
++              if (NULL == group)
++              {
++                      /* Could not get a group to run the job on, early out */
++                      MALI_DEBUG_PRINT(4, ("Mali PP scheduler: No more physical groups available.\n"));
++                      break;
++              }
++
++              MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Acquired physical group %p\n", group));
++
++              /* Mark subjob as started */
++              subjob = mali_pp_job_get_first_unstarted_sub_job(job);
++              mali_pp_job_mark_sub_job_started(job, subjob);
++
++              /* Remove job from queue (if we now got the last subjob) */
++              mali_pp_scheduler_dequeue_physical_job(job);
++
++              /* Move group to working list */
++              _mali_osk_list_move(&(group->pp_scheduler_list), &group_list_working);
++
++              /* Keep track of this group, so that we actually can start the job once we are done with the scheduler lock we are now holding */
++              physical_groups_to_start[num_physical_jobs_to_start] = group;
++              physical_jobs_to_start[num_physical_jobs_to_start] = job;
++              physical_subjobs_to_start[num_physical_jobs_to_start] = subjob;
++              ++num_physical_jobs_to_start;
++
++              MALI_DEBUG_ASSERT(num_physical_jobs_to_start < MALI_MAX_NUMBER_OF_PP_GROUPS);
++      }
++
++      /* See if we have a virtual job to schedule */
++      if (NULL != virtual_group)
++      {
++              if (!virtual_group_working)
++              {
++                      struct mali_pp_job *job = mali_pp_scheduler_get_virtual_job();
++                      if (NULL != job)
++                      {
++                              MALI_DEBUG_ASSERT(mali_pp_job_is_virtual(job));
++                              MALI_DEBUG_ASSERT(mali_pp_job_has_unstarted_sub_jobs(job));
++                              MALI_DEBUG_ASSERT(1 == mali_pp_job_get_sub_job_count(job));
++
++                              /* Mark the one and only subjob as started */
++                              mali_pp_job_mark_sub_job_started(job, 0);
++
++                              /* Remove job from queue */
++                              mali_pp_scheduler_dequeue_virtual_job(job);
++
++                              /* Virtual group is now working */
++                              virtual_group_working = MALI_TRUE;
++
++                              /*
++                               * We no longer need the scheduler lock,
++                               * but we still need the virtual lock in order to start the virtual job
++                               */
++                              mali_pp_scheduler_unlock();
++
++                              /* Start job */
++                              if (_MALI_OSK_ERR_OK == mali_group_start_pp_job(virtual_group, job, 0))
++                              {
++                                      MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Virtual job %u (0x%08X) part %u/%u started (from schedule)\n",
++                                                           mali_pp_job_get_id(job), job, 1,
++                                                           mali_pp_job_get_sub_job_count(job)));
++                              }
++                              else
++                              {
++                                      MALI_DEBUG_ASSERT(0);
++                              }
++
++                              /* And now we are all done with the virtual_group lock as well */
++                              mali_group_unlock(virtual_group);
++                      }
++                      else
++                      {
++                              /* No virtual job, release the two locks we are holding */
++                              mali_pp_scheduler_unlock();
++                              mali_group_unlock(virtual_group);
++                      }
++              }
++              else
++              {
++                      /* Virtual core busy, release the two locks we are holding */
++                      mali_pp_scheduler_unlock();
++                      mali_group_unlock(virtual_group);
++              }
++
++      }
++      else
++      {
++              /* There is no virtual group, release the only lock we are holding */
++              mali_pp_scheduler_unlock();
++      }
++
++      /*
++       * Now we have released the scheduler lock, and we are ready to kick of the actual starting of the
++       * physical jobs.
++       * The reason we want to wait until we have released the scheduler lock is that job start actually
++       * may take quite a bit of time (quite many registers needs to be written). This will allow new jobs
++       * from user space to come in, and post processing of other PP jobs to happen at the same time as we
++       * start jobs.
++       */
++      for (i = 0; i < num_physical_jobs_to_start; i++)
++      {
++              struct mali_group *group = physical_groups_to_start[i];
++              struct mali_pp_job *job  = physical_jobs_to_start[i];
++              u32 sub_job              = physical_subjobs_to_start[i];
++
++              MALI_DEBUG_ASSERT_POINTER(group);
++              MALI_DEBUG_ASSERT_POINTER(job);
++
++              mali_group_lock(group);
++
++              /* In case this group was acquired from a virtual core, update it's state to IDLE */
++              group->state = MALI_GROUP_STATE_IDLE;
++
++              if (_MALI_OSK_ERR_OK == mali_group_start_pp_job(group, job, sub_job))
++              {
++                      MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Physical job %u (0x%08X) part %u/%u started (from schedule)\n",
++                                           mali_pp_job_get_id(job), job, sub_job + 1,
++                                           mali_pp_job_get_sub_job_count(job)));
++              }
++              else
++              {
++                      MALI_DEBUG_ASSERT(0);
++              }
++
++              mali_group_unlock(group);
++
++              /* @@@@ todo: remove the return value from mali_group_start_xx_job, since we can't fail on Mali-300++ */
++      }
++}
++
++static void mali_pp_scheduler_return_job_to_user(struct mali_pp_job *job, mali_bool deferred)
++{
++      if (MALI_FALSE == mali_pp_job_use_no_notification(job))
++      {
++              u32 i;
++              u32 sub_jobs = mali_pp_job_get_sub_job_count(job);
++              mali_bool success = mali_pp_job_was_success(job);
++
++              _mali_uk_pp_job_finished_s *jobres = job->finished_notification->result_buffer;
++              _mali_osk_memset(jobres, 0, sizeof(_mali_uk_pp_job_finished_s)); /* @@@@ can be removed once we initialize all members in this struct */
++              jobres->user_job_ptr = mali_pp_job_get_user_id(job);
++              if (MALI_TRUE == success)
++              {
++                      jobres->status = _MALI_UK_JOB_STATUS_END_SUCCESS;
++              }
++              else
++              {
++                      jobres->status = _MALI_UK_JOB_STATUS_END_UNKNOWN_ERR;
++              }
++
++              for (i = 0; i < sub_jobs; i++)
++              {
++                      jobres->perf_counter0[i] = mali_pp_job_get_perf_counter_value0(job, i);
++                      jobres->perf_counter1[i] = mali_pp_job_get_perf_counter_value1(job, i);
++              }
++
++              mali_session_send_notification(mali_pp_job_get_session(job), job->finished_notification);
++              job->finished_notification = NULL;
++      }
++
++#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
++      if (MALI_TRUE == deferred)
++      {
++              /* The deletion of the job object (releasing sync refs etc) must be done in a different context */
++              _mali_osk_lock_wait(pp_scheduler_job_delete_lock, _MALI_OSK_LOCKMODE_RW);
++
++              MALI_DEBUG_ASSERT(_mali_osk_list_empty(&job->list)); /* This job object should not be on any list */
++              _mali_osk_list_addtail(&job->list, &pp_scheduler_job_deletion_queue);
++
++              _mali_osk_lock_signal(pp_scheduler_job_delete_lock, _MALI_OSK_LOCKMODE_RW);
++
++              _mali_osk_wq_schedule_work(pp_scheduler_wq_job_delete);
++      }
++      else
++      {
++              mali_pp_job_delete(job);
++      }
++#else
++      MALI_DEBUG_ASSERT(MALI_FALSE == deferred); /* no use cases need this in this configuration */
++      mali_pp_job_delete(job);
++#endif
++}
++
++static void mali_pp_scheduler_do_schedule(void *arg)
++{
++      MALI_IGNORE(arg);
++
++      mali_pp_scheduler_schedule();
++}
++
++#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
++static void mali_pp_scheduler_do_job_delete(void *arg)
++{
++      _MALI_OSK_LIST_HEAD_STATIC_INIT(list);
++      struct mali_pp_job *job;
++      struct mali_pp_job *tmp;
++
++      MALI_IGNORE(arg);
++
++      _mali_osk_lock_wait(pp_scheduler_job_delete_lock, _MALI_OSK_LOCKMODE_RW);
++
++      /*
++       * Quickly "unhook" the jobs pending to be deleted, so we can release the lock before
++       * we start deleting the job objects (without any locks held
++       */
++      _mali_osk_list_move_list(&pp_scheduler_job_deletion_queue, &list);
++
++      _mali_osk_lock_signal(pp_scheduler_job_delete_lock, _MALI_OSK_LOCKMODE_RW);
++
++      _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &list, struct mali_pp_job, list)
++      {
++              mali_pp_job_delete(job); /* delete the job object itself */
++      }
++}
++#endif
++
++void mali_pp_scheduler_job_done(struct mali_group *group, struct mali_pp_job *job, u32 sub_job, mali_bool success)
++{
++      mali_bool job_is_done;
++      mali_bool barrier_enforced = MALI_FALSE;
++
++      MALI_DEBUG_PRINT(3, ("Mali PP scheduler: %s job %u (0x%08X) part %u/%u completed (%s)\n",
++                           mali_pp_job_is_virtual(job) ? "Virtual" : "Physical",
++                           mali_pp_job_get_id(job),
++                           job, sub_job + 1,
++                           mali_pp_job_get_sub_job_count(job),
++                           success ? "success" : "failure"));
++      MALI_ASSERT_GROUP_LOCKED(group);
++      mali_pp_scheduler_lock();
++
++      mali_pp_job_mark_sub_job_completed(job, success);
++
++      MALI_DEBUG_ASSERT(mali_pp_job_is_virtual(job) == mali_group_is_virtual(group));
++
++      job_is_done = mali_pp_job_is_complete(job);
++
++      if (job_is_done)
++      {
++              struct mali_session_data *session = mali_pp_job_get_session(job);
++              struct mali_pp_job *job_head;
++
++              /* Remove job from session list */
++              _mali_osk_list_del(&job->session_list);
++
++              /* Send notification back to user space */
++              MALI_DEBUG_PRINT(4, ("Mali PP scheduler: All parts completed for %s job %u (0x%08X)\n",
++                                   mali_pp_job_is_virtual(job) ? "virtual" : "physical",
++                                   mali_pp_job_get_id(job), job));
++#if defined(CONFIG_SYNC)
++/* MALI_SEC */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
++              if (job->sync_point)
++              {
++                      int error;
++                      if (success) error = 0;
++                      else error = -EFAULT;
++                      MALI_DEBUG_PRINT(4, ("Sync: Signal %spoint for job %d\n",
++                                           success ? "" : "failed ",
++                                           mali_pp_job_get_id(job)));
++                      mali_sync_signal_pt(job->sync_point, error);
++              }
++#endif
++#endif
++
++#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
++              mali_pp_scheduler_return_job_to_user(job, MALI_TRUE);
++#else
++              mali_pp_scheduler_return_job_to_user(job, MALI_FALSE);
++#endif
++
++              mali_pm_core_event(MALI_CORE_EVENT_PP_STOP);
++
++              /* Resolve any barriers */
++              if (!_mali_osk_list_empty(&session->job_list))
++              {
++                      job_head = _MALI_OSK_LIST_ENTRY(session->job_list.next, struct mali_pp_job, session_list);
++                      if (mali_pp_job_has_active_barrier(job_head))
++                      {
++                              barrier_enforced = MALI_TRUE;
++                              mali_pp_job_barrier_enforced(job_head);
++                      }
++              }
++      }
++
++      /* If paused, then this was the last job, so wake up sleeping workers */
++      if (pause_count > 0)
++      {
++              /* Wake up sleeping workers. Their wake-up condition is that
++               * num_slots == num_slots_idle, so unless we are done working, no
++               * threads will actually be woken up.
++               */
++              _mali_osk_wait_queue_wake_up(pp_scheduler_working_wait_queue);
++              mali_pp_scheduler_unlock();
++              return;
++      }
++
++      if (barrier_enforced)
++      {
++              /* A barrier was resolved, so schedule previously blocked jobs */
++              _mali_osk_wq_schedule_work(pp_scheduler_wq_schedule);
++
++              /* TODO: Subjob optimisation */
++      }
++
++      /* Recycle variables */
++      job = NULL;
++      sub_job = 0;
++
++      if (mali_group_is_virtual(group))
++      {
++              /* Virtual group */
++
++              /* Now that the virtual group is idle, check if we should reconfigure */
++              struct mali_pp_job *physical_job = NULL;
++              struct mali_group *physical_group = NULL;
++
++              /* Obey the policy */
++              virtual_group_working = MALI_FALSE;
++
++              if (mali_pp_scheduler_can_move_virtual_to_physical())
++              {
++                      /* There is a runnable physical job and we can acquire a physical group */
++                      physical_job = mali_pp_scheduler_get_physical_job();
++                      MALI_DEBUG_ASSERT(mali_pp_job_has_unstarted_sub_jobs(physical_job));
++
++                      /* Mark subjob as started */
++                      sub_job = mali_pp_job_get_first_unstarted_sub_job(physical_job);
++                      mali_pp_job_mark_sub_job_started(physical_job, sub_job);
++
++                      /* Remove job from queue (if we now got the last subjob) */
++                      mali_pp_scheduler_dequeue_physical_job(physical_job);
++
++                      /* Acquire a physical group from the virtual group
++                       * It's state will be LEAVING_VIRTUAL and must be set to IDLE before it can be used */
++                      physical_group = mali_group_acquire_group(virtual_group);
++
++                      /* Move physical group to the working list, as we will soon start a job on it */
++                      _mali_osk_list_move(&(physical_group->pp_scheduler_list), &group_list_working);
++              }
++
++              /* Start the next virtual job */
++              job = mali_pp_scheduler_get_virtual_job();
++              if (NULL != job)
++              {
++                      /* There is a runnable virtual job */
++                      MALI_DEBUG_ASSERT(mali_pp_job_is_virtual(job));
++                      MALI_DEBUG_ASSERT(mali_pp_job_has_unstarted_sub_jobs(job));
++                      MALI_DEBUG_ASSERT(1 == mali_pp_job_get_sub_job_count(job));
++
++                      mali_pp_job_mark_sub_job_started(job, 0);
++
++                      /* Remove job from queue */
++                      mali_pp_scheduler_dequeue_virtual_job(job);
++
++                      /* Virtual group is now working */
++                      virtual_group_working = MALI_TRUE;
++
++                      mali_pp_scheduler_unlock();
++
++                      /* Start job */
++                      if (_MALI_OSK_ERR_OK == mali_group_start_pp_job(group, job, 0))
++                      {
++                              MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Virtual job %u (0x%08X) part %u/%u started (from job_done)\n",
++                                                   mali_pp_job_get_id(job), job, 1,
++                                                   mali_pp_job_get_sub_job_count(job)));
++                      }
++                      else
++                      {
++                              MALI_DEBUG_ASSERT(0);
++                      }
++              }
++              else
++              {
++                      mali_pp_scheduler_unlock();
++              }
++
++              /* Start a physical job (if we acquired a physical group earlier) */
++              if (NULL != physical_job && NULL != physical_group)
++              {
++                      mali_group_lock(physical_group);
++
++                      /* Set the group state from LEAVING_VIRTUAL to IDLE to complete the transition */
++                      physical_group->state = MALI_GROUP_STATE_IDLE;
++
++                      /* Start job on core */
++                      if (_MALI_OSK_ERR_OK == mali_group_start_pp_job(physical_group, physical_job, sub_job))
++                      {
++                              MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Physical job %u (0x%08X) part %u/%u started (from job_done)\n",
++                                                   mali_pp_job_get_id(physical_job), physical_job, sub_job + 1,
++                                                   mali_pp_job_get_sub_job_count(physical_job)));
++                      }
++                      else
++                      {
++                              /* @@@@ todo: this cant fail on Mali-300+, no need to implement put back of job */
++                              MALI_DEBUG_ASSERT(0);
++                      }
++
++                      mali_group_unlock(physical_group);
++              }
++      }
++      else
++      {
++              /* Physical group */
++              job = mali_pp_scheduler_get_physical_job();
++              if (NULL != job)
++              {
++                      /* There is a runnable physical job */
++                      MALI_DEBUG_ASSERT(mali_pp_job_has_unstarted_sub_jobs(job));
++
++                      /* Mark subjob as started */
++                      sub_job = mali_pp_job_get_first_unstarted_sub_job(job);
++                      mali_pp_job_mark_sub_job_started(job, sub_job);
++
++                      /* Remove job from queue (if we now got the last subjob) */
++                      mali_pp_scheduler_dequeue_physical_job(job);
++
++                      mali_pp_scheduler_unlock();
++
++                      /* Group is already on the working list, so start the job */
++                      if (_MALI_OSK_ERR_OK == mali_group_start_pp_job(group, job, sub_job))
++                      {
++                              MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Physical job %u (0x%08X) part %u/%u started (from job_done)\n",
++                                                   mali_pp_job_get_id(job), job, sub_job + 1,
++                                                   mali_pp_job_get_sub_job_count(job)));
++                      }
++                      else
++                      {
++                              MALI_DEBUG_ASSERT(0);
++                      }
++              }
++              else if (NULL != virtual_group)
++              {
++                      /* Rejoin virtual group */
++                      /* TODO: In the future, a policy check might be useful here */
++
++                      /* We're no longer needed on the scheduler list */
++                      _mali_osk_list_delinit(&(group->pp_scheduler_list));
++
++                      /* Make sure no interrupts are handled for this group during
++                       * the transition from physical to virtual */
++                      group->state = MALI_GROUP_STATE_JOINING_VIRTUAL;
++
++                      mali_pp_scheduler_unlock();
++                      mali_group_unlock(group);
++
++                      mali_group_lock(virtual_group);
++                      /* TODO: Take group lock also? */
++                      mali_group_add_group(virtual_group, group);
++                      mali_group_unlock(virtual_group);
++
++                      /* We need to return from this function with the group lock held */
++                      /* TODO: optimise! */
++                      mali_group_lock(group);
++              }
++              else
++              {
++                      _mali_osk_list_move(&(group->pp_scheduler_list), &group_list_idle);
++                      mali_pp_scheduler_unlock();
++              }
++      }
++}
++
++void mali_pp_scheduler_suspend(void)
++{
++      mali_pp_scheduler_lock();
++      pause_count++; /* Increment the pause_count so that no more jobs will be scheduled */
++      mali_pp_scheduler_unlock();
++
++      /* Go to sleep. When woken up again (in mali_pp_scheduler_job_done), the
++       * mali_pp_scheduler_suspended() function will be called. This will return true
++       * iff state is idle and pause_count > 0, so if the core is active this
++       * will not do anything.
++       */
++      _mali_osk_wait_queue_wait_event(pp_scheduler_working_wait_queue, mali_pp_scheduler_is_suspended);
++}
++
++void mali_pp_scheduler_resume(void)
++{
++      mali_pp_scheduler_lock();
++      pause_count--; /* Decrement pause_count to allow scheduling again (if it reaches 0) */
++      mali_pp_scheduler_unlock();
++      if (0 == pause_count)
++      {
++              mali_pp_scheduler_schedule();
++      }
++}
++
++MALI_STATIC_INLINE void mali_pp_scheduler_queue_job(struct mali_pp_job *job, struct mali_session_data *session)
++{
++      MALI_DEBUG_ASSERT_POINTER(job);
++
++      mali_pm_core_event(MALI_CORE_EVENT_PP_START);
++
++      mali_pp_scheduler_lock();
++
++      if (mali_pp_job_is_virtual(job))
++      {
++              /* Virtual job */
++              virtual_job_queue_depth += 1;
++              _mali_osk_list_addtail(&job->list, &virtual_job_queue);
++      }
++      else
++      {
++              job_queue_depth += mali_pp_job_get_sub_job_count(job);
++              _mali_osk_list_addtail(&job->list, &job_queue);
++      }
++
++      if (mali_pp_job_has_active_barrier(job) && _mali_osk_list_empty(&session->job_list))
++      {
++              /* No running jobs on this session, so barrier condition already met */
++              mali_pp_job_barrier_enforced(job);
++      }
++
++      /* Add job to session list */
++      _mali_osk_list_addtail(&job->session_list, &session->job_list);
++
++      MALI_DEBUG_PRINT(3, ("Mali PP scheduler: %s job %u (0x%08X) with %u parts queued\n",
++                           mali_pp_job_is_virtual(job) ? "Virtual" : "Physical",
++                           mali_pp_job_get_id(job), job, mali_pp_job_get_sub_job_count(job)));
++
++      mali_pp_scheduler_unlock();
++}
++
++#if defined(CONFIG_SYNC)
++/* MALI_SEC */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
++static void sync_callback(struct sync_fence *fence, struct sync_fence_waiter *waiter)
++{
++      struct mali_pp_job *job = _MALI_OSK_CONTAINER_OF(waiter, struct mali_pp_job, sync_waiter);
++
++      /* Schedule sync_callback_work */
++      _mali_osk_wq_schedule_work(job->sync_work);
++}
++
++static void sync_callback_work(void *arg)
++{
++      struct mali_pp_job *job = (struct mali_pp_job *)arg;
++      struct mali_session_data *session;
++      int err;
++
++      MALI_DEBUG_ASSERT_POINTER(job);
++
++      session = job->session;
++
++      /* Remove job from session pending job list */
++      _mali_osk_lock_wait(session->pending_jobs_lock, _MALI_OSK_LOCKMODE_RW);
++      _mali_osk_list_delinit(&job->list);
++      _mali_osk_lock_signal(session->pending_jobs_lock, _MALI_OSK_LOCKMODE_RW);
++
++      err = sync_fence_wait(job->pre_fence, 0);
++      if (likely(0 == err))
++      {
++              MALI_DEBUG_PRINT(3, ("Mali sync: Job %d ready to run\n", mali_pp_job_get_id(job)));
++
++              mali_pp_scheduler_queue_job(job, session);
++
++              mali_pp_scheduler_schedule();
++      }
++      else
++      {
++              /* Fence signaled error */
++              MALI_DEBUG_PRINT(3, ("Mali sync: Job %d abort due to sync error\n", mali_pp_job_get_id(job)));
++
++              if (job->sync_point) mali_sync_signal_pt(job->sync_point, err);
++
++              mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
++              mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
++      }
++}
++#endif
++#endif
++
++_mali_osk_errcode_t _mali_ukk_pp_start_job(void *ctx, _mali_uk_pp_start_job_s *uargs, int *fence)
++{
++      struct mali_session_data *session;
++      struct mali_pp_job *job;
++#if defined(CONFIG_SYNC)
++/* MALI_SEC */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
++      int post_fence = -1;
++#endif
++#endif
++
++      MALI_DEBUG_ASSERT_POINTER(uargs);
++      MALI_DEBUG_ASSERT_POINTER(ctx);
++
++      session = (struct mali_session_data*)ctx;
++
++      job = mali_pp_job_create(session, uargs, mali_scheduler_get_new_id());
++      if (NULL == job)
++      {
++              MALI_PRINT_ERROR(("Failed to create job!\n"));
++              return _MALI_OSK_ERR_NOMEM;
++      }
++
++      if (_MALI_OSK_ERR_OK != mali_pp_job_check(job))
++      {
++              /* Not a valid job, return to user immediately */
++              mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
++              mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
++              return _MALI_OSK_ERR_OK; /* User is notified via a notification, so this call is ok */
++      }
++
++#if PROFILING_SKIP_PP_JOBS || PROFILING_SKIP_PP_AND_GP_JOBS
++#warning PP jobs will not be executed
++      mali_pp_scheduler_return_job_to_user(job, MALI_FALSE);
++      return _MALI_OSK_ERR_OK;
++#endif
++
++#if defined(CONFIG_SYNC)
++/* MALI_SEC */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
++      if (_MALI_PP_JOB_FLAG_FENCE & job->uargs.flags)
++      {
++              job->sync_point = mali_stream_create_point(job->uargs.stream);
++
++              if (unlikely(NULL == job->sync_point))
++              {
++                      /* Fence creation failed. */
++                      MALI_DEBUG_PRINT(2, ("Failed to create sync point for job %d\n", mali_pp_job_get_id(job)));
++                      mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
++                      mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
++                      return _MALI_OSK_ERR_OK; /* User is notified via a notification, so this call is ok */
++              }
++
++              post_fence = mali_stream_create_fence(job->sync_point);
++
++              if (unlikely(0 > post_fence))
++              {
++                      /* Fence creation failed. */
++                      /* mali_stream_create_fence already freed the sync_point */
++                      MALI_DEBUG_PRINT(2, ("Failed to create fence for job %d\n", mali_pp_job_get_id(job)));
++                      mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
++                      mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
++                      return _MALI_OSK_ERR_OK; /* User is notified via a notification, so this call is ok */
++              }
++
++              /* Grab a reference to the fence. It must be around when the
++               * job is completed, so the point can be signalled. */
++              sync_fence_fdget(post_fence);
++
++              *fence = post_fence;
++
++              MALI_DEBUG_PRINT(3, ("Sync: Created fence %d for job %d\n", post_fence, mali_pp_job_get_id(job)));
++      }
++
++      if (0 < job->uargs.fence)
++      {
++              int pre_fence_fd = job->uargs.fence;
++              int err;
++
++              MALI_DEBUG_PRINT(2, ("Sync: Job %d waiting for fence %d\n", mali_pp_job_get_id(job), pre_fence_fd));
++
++              job->pre_fence = sync_fence_fdget(pre_fence_fd); /* Reference will be released when job is deleted. */
++              if (NULL == job->pre_fence)
++              {
++                      MALI_DEBUG_PRINT(2, ("Failed to import fence %d\n", pre_fence_fd));
++                      if (job->sync_point) mali_sync_signal_pt(job->sync_point, -EINVAL);
++                      mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
++                      mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
++                      return _MALI_OSK_ERR_OK; /* User is notified via a notification, so this call is ok */
++              }
++
++              job->sync_work = _mali_osk_wq_create_work(sync_callback_work, (void*)job);
++              if (NULL == job->sync_work)
++              {
++                      if (job->sync_point) mali_sync_signal_pt(job->sync_point, -ENOMEM);
++                      mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
++                      mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
++                      return _MALI_OSK_ERR_OK; /* User is notified via a notification, so this call is ok */
++              }
++
++              /* Add pending job to session pending job list */
++              _mali_osk_lock_wait(session->pending_jobs_lock, _MALI_OSK_LOCKMODE_RW);
++              _mali_osk_list_addtail(&job->list, &session->pending_jobs);
++              _mali_osk_lock_signal(session->pending_jobs_lock, _MALI_OSK_LOCKMODE_RW);
++
++              sync_fence_waiter_init(&job->sync_waiter, sync_callback);
++              err = sync_fence_wait_async(job->pre_fence, &job->sync_waiter);
++
++              if (0 != err)
++              {
++                      /* No async wait started, remove job from session pending job list */
++                      _mali_osk_lock_wait(session->pending_jobs_lock, _MALI_OSK_LOCKMODE_RW);
++                      _mali_osk_list_delinit(&job->list);
++                      _mali_osk_lock_signal(session->pending_jobs_lock, _MALI_OSK_LOCKMODE_RW);
++              }
++
++              if (1 == err)
++              {
++                      /* Fence has already signalled */
++                      mali_pp_scheduler_queue_job(job, session);
++                      if (0 == _mali_osk_list_empty(&group_list_idle)) mali_pp_scheduler_schedule();
++                      return _MALI_OSK_ERR_OK;
++              }
++              else if (0 > err)
++              {
++                      /* Sync fail */
++                      if (job->sync_point) mali_sync_signal_pt(job->sync_point, err);
++                      mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
++                      mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
++                      return _MALI_OSK_ERR_OK; /* User is notified via a notification, so this call is ok */
++              }
++
++      }
++      else
++#endif
++#endif /* CONFIG_SYNC */
++      {
++              mali_pp_scheduler_queue_job(job, session);
++
++              if (!_mali_osk_list_empty(&group_list_idle) || !virtual_group_working)
++              {
++                      mali_pp_scheduler_schedule();
++              }
++      }
++
++      return _MALI_OSK_ERR_OK;
++}
++
++_mali_osk_errcode_t _mali_ukk_get_pp_number_of_cores(_mali_uk_get_pp_number_of_cores_s *args)
++{
++      MALI_DEBUG_ASSERT_POINTER(args);
++      MALI_DEBUG_ASSERT_POINTER(args->ctx);
++      args->number_of_cores = num_cores;
++      return _MALI_OSK_ERR_OK;
++}
++
++_mali_osk_errcode_t _mali_ukk_get_pp_core_version(_mali_uk_get_pp_core_version_s *args)
++{
++      MALI_DEBUG_ASSERT_POINTER(args);
++      MALI_DEBUG_ASSERT_POINTER(args->ctx);
++      args->version = pp_version;
++      return _MALI_OSK_ERR_OK;
++}
++
++void _mali_ukk_pp_job_disable_wb(_mali_uk_pp_disable_wb_s *args)
++{
++      struct mali_session_data *session;
++      struct mali_pp_job *job;
++      struct mali_pp_job *tmp;
++
++      MALI_DEBUG_ASSERT_POINTER(args);
++      MALI_DEBUG_ASSERT_POINTER(args->ctx);
++
++      session = (struct mali_session_data*)args->ctx;
++
++      /* Check queue for jobs that match */
++      mali_pp_scheduler_lock();
++      _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &job_queue, struct mali_pp_job, list)
++      {
++              if (mali_pp_job_get_session(job) == session &&
++                  mali_pp_job_get_frame_builder_id(job) == (u32)args->fb_id &&
++                  mali_pp_job_get_flush_id(job) == (u32)args->flush_id)
++              {
++                      if (args->wbx & _MALI_UK_PP_JOB_WB0)
++                      {
++                              mali_pp_job_disable_wb0(job);
++                      }
++                      if (args->wbx & _MALI_UK_PP_JOB_WB1)
++                      {
++                              mali_pp_job_disable_wb1(job);
++                      }
++                      if (args->wbx & _MALI_UK_PP_JOB_WB2)
++                      {
++                              mali_pp_job_disable_wb2(job);
++                      }
++                      break;
++              }
++      }
++      mali_pp_scheduler_unlock();
++}
++
++void mali_pp_scheduler_abort_session(struct mali_session_data *session)
++{
++      struct mali_pp_job *job, *tmp_job;
++      struct mali_group *group, *tmp_group;
++      struct mali_group *groups[MALI_MAX_NUMBER_OF_GROUPS];
++      s32 i = 0;
++
++      mali_pp_scheduler_lock();
++      MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Aborting all jobs from session 0x%08x\n", session));
++
++      _MALI_OSK_LIST_FOREACHENTRY(job, tmp_job, &session->job_list, struct mali_pp_job, session_list)
++      {
++              /* Remove job from queue (if it's not queued, list_del has no effect) */
++              _mali_osk_list_delinit(&job->list);
++
++              if (mali_pp_job_is_virtual(job))
++              {
++                      MALI_DEBUG_ASSERT(1 == mali_pp_job_get_sub_job_count(job));
++                      if (0 == mali_pp_job_get_first_unstarted_sub_job(job))
++                      {
++                              --virtual_job_queue_depth;
++                      }
++              }
++              else
++              {
++                      job_queue_depth -= mali_pp_job_get_sub_job_count(job) - mali_pp_job_get_first_unstarted_sub_job(job);
++              }
++
++              /* Mark all unstarted jobs as failed */
++              mali_pp_job_mark_unstarted_failed(job);
++
++              if (mali_pp_job_is_complete(job))
++              {
++                      _mali_osk_list_del(&job->session_list);
++
++                      /* It is safe to delete the job, since it won't land in job_done() */
++                      MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Aborted PP job 0x%08x\n", job));
++                      mali_pp_job_delete(job);
++
++                      mali_pm_core_event(MALI_CORE_EVENT_PP_STOP);
++              }
++              else
++              {
++                      MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Keeping partially started PP job 0x%08x in session\n", job));
++              }
++      }
++
++      _MALI_OSK_LIST_FOREACHENTRY(group, tmp_group, &group_list_working, struct mali_group, pp_scheduler_list)
++      {
++              groups[i++] = group;
++      }
++
++      _MALI_OSK_LIST_FOREACHENTRY(group, tmp_group, &group_list_idle, struct mali_group, pp_scheduler_list)
++      {
++              groups[i++] = group;
++      }
++
++      mali_pp_scheduler_unlock();
++
++      /* Abort running jobs from this session */
++      while (i > 0)
++      {
++              mali_group_abort_session(groups[--i], session);
++      }
++
++      if (NULL != virtual_group)
++      {
++              mali_group_abort_session(virtual_group, session);
++      }
++}
++
++static mali_bool mali_pp_scheduler_is_suspended(void)
++{
++      mali_bool ret;
++
++      mali_pp_scheduler_lock();
++      ret = pause_count > 0 && _mali_osk_list_empty(&group_list_working) && !virtual_group_working;
++      mali_pp_scheduler_unlock();
++
++      return ret;
++}
++
++int mali_pp_scheduler_get_queue_depth(void)
++{
++      return job_queue_depth;
++}
++
++#if MALI_STATE_TRACKING
++u32 mali_pp_scheduler_dump_state(char *buf, u32 size)
++{
++      int n = 0;
++      struct mali_group *group;
++      struct mali_group *temp;
++
++      n += _mali_osk_snprintf(buf + n, size - n, "PP:\n");
++      n += _mali_osk_snprintf(buf + n, size - n, "\tQueue is %s\n", _mali_osk_list_empty(&job_queue) ? "empty" : "not empty");
++      n += _mali_osk_snprintf(buf + n, size - n, "\n");
++
++      _MALI_OSK_LIST_FOREACHENTRY(group, temp, &group_list_working, struct mali_group, pp_scheduler_list)
++      {
++              n += mali_group_dump_state(group, buf + n, size - n);
++      }
++
++      _MALI_OSK_LIST_FOREACHENTRY(group, temp, &group_list_idle, struct mali_group, pp_scheduler_list)
++      {
++              n += mali_group_dump_state(group, buf + n, size - n);
++      }
++
++      if (NULL != virtual_group)
++      {
++              n += mali_group_dump_state(virtual_group, buf + n, size -n);
++      }
++
++      n += _mali_osk_snprintf(buf + n, size - n, "\n");
++      return n;
++}
++#endif
++
++/* This function is intended for power on reset of all cores.
++ * No locking is done for the list iteration, which can only be safe if the
++ * scheduler is paused and all cores idle. That is always the case on init and
++ * power on. */
++void mali_pp_scheduler_reset_all_groups(void)
++{
++      struct mali_group *group, *temp;
++
++      if (NULL != virtual_group)
++      {
++              mali_group_reset(virtual_group);
++      }
++
++      MALI_DEBUG_ASSERT(_mali_osk_list_empty(&group_list_working));
++
++      _MALI_OSK_LIST_FOREACHENTRY(group, temp, &group_list_idle, struct mali_group, pp_scheduler_list)
++      {
++              mali_group_reset(group);
++      }
++}
++
++void mali_pp_scheduler_zap_all_active(struct mali_session_data *session)
++{
++      struct mali_group *group, *temp;
++      struct mali_group *groups[MALI_MAX_NUMBER_OF_GROUPS];
++      s32 i = 0;
++
++      if (NULL != virtual_group)
++      {
++              mali_group_zap_session(virtual_group, session);
++      }
++
++      mali_pp_scheduler_lock();
++      _MALI_OSK_LIST_FOREACHENTRY(group, temp, &group_list_working, struct mali_group, pp_scheduler_list)
++      {
++              groups[i++] = group;
++      }
++      mali_pp_scheduler_unlock();
++
++      while (i > 0)
++      {
++              mali_group_zap_session(groups[--i], session);
++      }
++}
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_pp_scheduler.h b/drivers/gpu/arm/mali400/mali/common/mali_pp_scheduler.h
+new file mode 100644
+index 0000000..4b2fec4
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_pp_scheduler.h
+@@ -0,0 +1,57 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_PP_SCHEDULER_H__
++#define __MALI_PP_SCHEDULER_H__
++
++#include "mali_osk.h"
++#include "mali_pp_job.h"
++#include "mali_group.h"
++
++_mali_osk_errcode_t mali_pp_scheduler_initialize(void);
++void mali_pp_scheduler_terminate(void);
++
++void mali_pp_scheduler_job_done(struct mali_group *group, struct mali_pp_job *job, u32 sub_job, mali_bool success);
++
++void mali_pp_scheduler_suspend(void);
++void mali_pp_scheduler_resume(void);
++
++/** @brief Abort all PP jobs from session running or queued
++ *
++ * This functions aborts all PP jobs from the specified session. Queued jobs are removed from the queue and jobs
++ * currently running on a core will be aborted.
++ *
++ * @param session Pointer to session whose jobs should be aborted
++ */
++void mali_pp_scheduler_abort_session(struct mali_session_data *session);
++
++/**
++ * @brief Reset all groups
++ *
++ * This function resets all groups known by the PP scheuduler. This must be
++ * called after the Mali HW has been powered on in order to reset the HW.
++ *
++ * This function is intended for power on reset of all cores.
++ * No locking is done, which can only be safe if the scheduler is paused and
++ * all cores idle. That is always the case on init and power on.
++ */
++void mali_pp_scheduler_reset_all_groups(void);
++
++/**
++ * @brief Zap TLB on all groups with \a session active
++ *
++ * The scheculer will zap the session on all groups it owns.
++ */
++void mali_pp_scheduler_zap_all_active(struct mali_session_data *session);
++
++int mali_pp_scheduler_get_queue_depth(void);
++u32 mali_pp_scheduler_dump_state(char *buf, u32 size);
++
++#endif /* __MALI_PP_SCHEDULER_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_scheduler.c b/drivers/gpu/arm/mali400/mali/common/mali_scheduler.c
+new file mode 100644
+index 0000000..e5d8186
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_scheduler.c
+@@ -0,0 +1,36 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_kernel_common.h"
++#include "mali_osk.h"
++
++static _mali_osk_atomic_t mali_job_autonumber;
++
++_mali_osk_errcode_t mali_scheduler_initialize(void)
++{
++      if ( _MALI_OSK_ERR_OK != _mali_osk_atomic_init(&mali_job_autonumber, 0))
++      {
++              MALI_DEBUG_PRINT(1,  ("Initialization of atomic job id counter failed.\n"));
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      return _MALI_OSK_ERR_OK;
++}
++
++void mali_scheduler_terminate(void)
++{
++      _mali_osk_atomic_term(&mali_job_autonumber);
++}
++
++u32 mali_scheduler_get_new_id(void)
++{
++      u32 job_id = _mali_osk_atomic_inc_return(&mali_job_autonumber);
++      return job_id;
++}
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_scheduler.h b/drivers/gpu/arm/mali400/mali/common/mali_scheduler.h
+new file mode 100644
+index 0000000..4fff577
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_scheduler.h
+@@ -0,0 +1,47 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_SCHEDULER_H__
++#define __MALI_SCHEDULER_H__
++
++#include "mali_osk.h"
++#include "mali_gp_scheduler.h"
++#include "mali_pp_scheduler.h"
++
++_mali_osk_errcode_t mali_scheduler_initialize(void);
++void mali_scheduler_terminate(void);
++
++u32 mali_scheduler_get_new_id(void);
++
++/**
++ * @brief Reset all groups
++ *
++ * This function resets all groups known by the both the PP and GP scheuduler.
++ * This must be called after the Mali HW has been powered on in order to reset
++ * the HW.
++ */
++MALI_STATIC_INLINE void mali_scheduler_reset_all_groups(void)
++{
++      mali_gp_scheduler_reset_all_groups();
++      mali_pp_scheduler_reset_all_groups();
++}
++
++/**
++ * @brief Zap TLB on all active groups running \a session
++ *
++ * @param session Pointer to the session to zap
++ */
++MALI_STATIC_INLINE void mali_scheduler_zap_all_active(struct mali_session_data *session)
++{
++      mali_gp_scheduler_zap_all_active(session);
++      mali_pp_scheduler_zap_all_active(session);
++}
++
++#endif /* __MALI_SCHEDULER_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_session.c b/drivers/gpu/arm/mali400/mali/common/mali_session.c
+new file mode 100644
+index 0000000..14729de
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_session.c
+@@ -0,0 +1,47 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_osk.h"
++#include "mali_osk_list.h"
++#include "mali_session.h"
++
++_MALI_OSK_LIST_HEAD(mali_sessions);
++
++_mali_osk_lock_t *mali_sessions_lock;
++
++_mali_osk_errcode_t mali_session_initialize(void)
++{
++      _MALI_OSK_INIT_LIST_HEAD(&mali_sessions);
++
++      mali_sessions_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_ORDERED, 0, _MALI_OSK_LOCK_ORDER_SESSIONS);
++
++      if (NULL == mali_sessions_lock) return _MALI_OSK_ERR_NOMEM;
++
++      return _MALI_OSK_ERR_OK;
++}
++
++void mali_session_terminate(void)
++{
++      _mali_osk_lock_term(mali_sessions_lock);
++}
++
++void mali_session_add(struct mali_session_data *session)
++{
++      mali_session_lock();
++      _mali_osk_list_add(&session->link, &mali_sessions);
++      mali_session_unlock();
++}
++
++void mali_session_remove(struct mali_session_data *session)
++{
++      mali_session_lock();
++      _mali_osk_list_delinit(&session->link);
++      mali_session_unlock();
++}
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_session.h b/drivers/gpu/arm/mali400/mali/common/mali_session.h
+new file mode 100644
+index 0000000..0d1b672
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_session.h
+@@ -0,0 +1,75 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_SESSION_H__
++#define __MALI_SESSION_H__
++
++#include "mali_mmu_page_directory.h"
++#include "mali_kernel_descriptor_mapping.h"
++#include "mali_osk.h"
++#include "mali_osk_list.h"
++
++struct mali_session_data
++{
++      _mali_osk_notification_queue_t * ioctl_queue;
++
++#ifdef CONFIG_SYNC
++/* MALI_SEC */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
++      _mali_osk_list_t pending_jobs;
++      _mali_osk_lock_t *pending_jobs_lock;
++#endif
++#endif
++
++      _mali_osk_lock_t *memory_lock; /**< Lock protecting the vm manipulation */
++      mali_descriptor_mapping * descriptor_mapping; /**< Mapping between userspace descriptors and our pointers */
++      _mali_osk_list_t memory_head; /**< Track all the memory allocated in this session, for freeing on abnormal termination */
++
++      struct mali_page_directory *page_directory; /**< MMU page directory for this session */
++
++      _MALI_OSK_LIST_HEAD(link); /**< Link for list of all sessions */
++
++      _MALI_OSK_LIST_HEAD(job_list); /**< List of all jobs on this session */
++};
++
++_mali_osk_errcode_t mali_session_initialize(void);
++void mali_session_terminate(void);
++
++/* List of all sessions. Actual list head in mali_kernel_core.c */
++extern _mali_osk_list_t mali_sessions;
++/* Lock to protect modification and access to the mali_sessions list */
++extern _mali_osk_lock_t *mali_sessions_lock;
++
++MALI_STATIC_INLINE void mali_session_lock(void)
++{
++      _mali_osk_lock_wait(mali_sessions_lock, _MALI_OSK_LOCKMODE_RW);
++}
++
++MALI_STATIC_INLINE void mali_session_unlock(void)
++{
++      _mali_osk_lock_signal(mali_sessions_lock, _MALI_OSK_LOCKMODE_RW);
++}
++
++void mali_session_add(struct mali_session_data *session);
++void mali_session_remove(struct mali_session_data *session);
++#define MALI_SESSION_FOREACH(session, tmp, link) \
++      _MALI_OSK_LIST_FOREACHENTRY(session, tmp, &mali_sessions, struct mali_session_data, link)
++
++MALI_STATIC_INLINE struct mali_page_directory *mali_session_get_page_directory(struct mali_session_data *session)
++{
++      return session->page_directory;
++}
++
++MALI_STATIC_INLINE void mali_session_send_notification(struct mali_session_data *session, _mali_osk_notification_t *object)
++{
++      _mali_osk_notification_queue_send(session->ioctl_queue, object);
++}
++
++#endif /* __MALI_SESSION_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_ukk.h b/drivers/gpu/arm/mali400/mali/common/mali_ukk.h
+new file mode 100644
+index 0000000..a3a7e7b
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_ukk.h
+@@ -0,0 +1,620 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_ukk.h
++ * Defines the kernel-side interface of the user-kernel interface
++ */
++
++#ifndef __MALI_UKK_H__
++#define __MALI_UKK_H__
++
++#include "mali_osk.h"
++#include "mali_uk_types.h"
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif
++
++/**
++ * @addtogroup uddapi Unified Device Driver (UDD) APIs
++ *
++ * @{
++ */
++
++/**
++ * @addtogroup u_k_api UDD User/Kernel Interface (U/K) APIs
++ *
++ * - The _mali_uk functions are an abstraction of the interface to the device
++ * driver. On certain OSs, this would be implemented via the IOCTL interface.
++ * On other OSs, it could be via extension of some Device Driver Class, or
++ * direct function call for Bare metal/RTOSs.
++ * - It is important to note that:
++ *   -  The Device Driver has implemented the _mali_ukk set of functions
++ *   -  The Base Driver calls the corresponding set of _mali_uku functions.
++ * - What requires porting is solely the calling mechanism from User-side to
++ * Kernel-side, and propagating back the results.
++ * - Each U/K function is associated with a (group, number) pair from
++ * \ref _mali_uk_functions to make it possible for a common function in the
++ * Base Driver and Device Driver to route User/Kernel calls from/to the
++ * correct _mali_uk function. For example, in an IOCTL system, the IOCTL number
++ * would be formed based on the group and number assigned to the _mali_uk
++ * function, as listed in \ref _mali_uk_functions. On the user-side, each
++ * _mali_uku function would just make an IOCTL with the IOCTL-code being an
++ * encoded form of the (group, number) pair. On the kernel-side, the Device
++ * Driver's IOCTL handler decodes the IOCTL-code back into a (group, number)
++ * pair, and uses this to determine which corresponding _mali_ukk should be
++ * called.
++ *   - Refer to \ref _mali_uk_functions for more information about this
++ * (group, number) pairing.
++ * - In a system where there is no distinction between user and kernel-side,
++ * the U/K interface may be implemented as:@code
++ * MALI_STATIC_INLINE _mali_osk_errcode_t _mali_uku_examplefunction( _mali_uk_examplefunction_s *args )
++ * {
++ *     return mali_ukk_examplefunction( args );
++ * }
++ * @endcode
++ * - Therefore, all U/K calls behave \em as \em though they were direct
++ * function calls (but the \b implementation \em need \em not be a direct
++ * function calls)
++ *
++ * @note Naming the _mali_uk functions the same on both User and Kernel sides
++ * on non-RTOS systems causes debugging issues when setting breakpoints. In
++ * this case, it is not clear which function the breakpoint is put on.
++ * Therefore the _mali_uk functions in user space are prefixed with \c _mali_uku
++ * and in kernel space with \c _mali_ukk. The naming for the argument
++ * structures is unaffected.
++ *
++ * - The _mali_uk functions are synchronous.
++ * - Arguments to the _mali_uk functions are passed in a structure. The only
++ * parameter passed to the _mali_uk functions is a pointer to this structure.
++ * This first member of this structure, ctx, is a pointer to a context returned
++ * by _mali_uku_open(). For example:@code
++ * typedef struct
++ * {
++ *     void *ctx;
++ *     u32 number_of_cores;
++ * } _mali_uk_get_gp_number_of_cores_s;
++ * @endcode
++ *
++ * - Each _mali_uk function has its own argument structure named after the
++ *  function. The argument is distinguished by the _s suffix.
++ * - The argument types are defined by the base driver and user-kernel
++ *  interface.
++ * - All _mali_uk functions return a standard \ref _mali_osk_errcode_t.
++ * - Only arguments of type input or input/output need be initialized before
++ * calling a _mali_uk function.
++ * - Arguments of type output and input/output are only valid when the
++ * _mali_uk function returns \ref _MALI_OSK_ERR_OK.
++ * - The \c ctx member is always invalid after it has been used by a
++ * _mali_uk function, except for the context management functions
++ *
++ *
++ * \b Interface \b restrictions
++ *
++ * The requirements of the interface mean that an implementation of the
++ * User-kernel interface may do no 'real' work. For example, the following are
++ * illegal in the User-kernel implementation:
++ * - Calling functions necessary for operation on all systems,  which would
++ * not otherwise get called on RTOS systems.
++ *     - For example, a  U/K interface that calls multiple _mali_ukk functions
++ * during one particular U/K call. This could not be achieved by the same code
++ * which uses direct function calls for the U/K interface.
++ * -  Writing in values to the args members, when otherwise these members would
++ * not hold a useful value for a direct function call U/K interface.
++ *     - For example, U/K interface implementation that take NULL members in
++ * their arguments structure from the user side, but those members are
++ * replaced with non-NULL values in the kernel-side of the U/K interface
++ * implementation. A scratch area for writing data is one such example. In this
++ * case, a direct function call U/K interface would segfault, because no code
++ * would be present to replace the NULL pointer with a meaningful pointer.
++ *     - Note that we discourage the case where the U/K implementation changes
++ * a NULL argument member to non-NULL, and then the Device Driver code (outside
++ * of the U/K layer) re-checks this member for NULL, and corrects it when
++ * necessary. Whilst such code works even on direct function call U/K
++ * intefaces, it reduces the testing coverage of the Device Driver code. This
++ * is because we have no way of testing the NULL == value path on an OS
++ * implementation.
++ *
++ * A number of allowable examples exist where U/K interfaces do 'real' work:
++ * - The 'pointer switching' technique for \ref _mali_ukk_get_system_info
++ *     - In this case, without the pointer switching on direct function call
++ * U/K interface, the Device Driver code still sees the same thing: a pointer
++ * to which it can write memory. This is because such a system has no
++ * distinction between a user and kernel pointer.
++ * - Writing an OS-specific value into the ukk_private member for
++ * _mali_ukk_mem_mmap().
++ *     - In this case, this value is passed around by Device Driver code, but
++ * its actual value is never checked. Device Driver code simply passes it from
++ * the U/K layer to the OSK layer, where it can be acted upon. In this case,
++ * \em some OS implementations of the U/K (_mali_ukk_mem_mmap()) and OSK
++ * (_mali_osk_mem_mapregion_init()) functions will collaborate on the
++ *  meaning of ukk_private member. On other OSs, it may be unused by both
++ * U/K and OSK layers
++ *     - Therefore, on error inside the U/K interface implementation itself,
++ * it will be as though the _mali_ukk function itself had failed, and cleaned
++ * up after itself.
++ *     - Compare this to a direct function call U/K implementation, where all
++ * error cleanup is handled by the _mali_ukk function itself. The direct
++ * function call U/K interface implementation is automatically atomic.
++ *
++ * The last example highlights a consequence of all U/K interface
++ * implementations: they must be atomic with respect to the Device Driver code.
++ * And therefore, should Device Driver code succeed but the U/K implementation
++ * fail afterwards (but before return to user-space), then the U/K
++ * implementation must cause appropriate cleanup actions to preserve the
++ * atomicity of the interface.
++ *
++ * @{
++ */
++
++
++/** @defgroup _mali_uk_context U/K Context management
++ *
++ * These functions allow for initialisation of the user-kernel interface once per process.
++ *
++ * Generally the context will store the OS specific object to communicate with the kernel device driver and further
++ * state information required by the specific implementation. The context is shareable among all threads in the caller process.
++ *
++ * On IOCTL systems, this is likely to be a file descriptor as a result of opening the kernel device driver.
++ *
++ * On a bare-metal/RTOS system with no distinction between kernel and
++ * user-space, the U/K interface simply calls the _mali_ukk variant of the
++ * function by direct function call. In this case, the context returned is the
++ * mali_session_data from _mali_ukk_open().
++ *
++ * The kernel side implementations of the U/K interface expect the first member of the argument structure to
++ * be the context created by _mali_uku_open(). On some OS implementations, the meaning of this context
++ * will be different between user-side and kernel-side. In which case, the kernel-side will need to replace this context
++ * with the kernel-side equivalent, because user-side will not have access to kernel-side data. The context parameter
++ * in the argument structure therefore has to be of type input/output.
++ *
++ * It should be noted that the caller cannot reuse the \c ctx member of U/K
++ * argument structure after a U/K call, because it may be overwritten. Instead,
++ * the context handle must always be stored  elsewhere, and copied into
++ * the appropriate U/K argument structure for each user-side call to
++ * the U/K interface. This is not usually a problem, since U/K argument
++ * structures are usually placed on the stack.
++ *
++ * @{ */
++
++/** @brief Begin a new Mali Device Driver session
++ *
++ * This is used to obtain a per-process context handle for all future U/K calls.
++ *
++ * @param context pointer to storage to return a (void*)context handle.
++ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
++ */
++_mali_osk_errcode_t _mali_ukk_open( void **context );
++
++/** @brief End a Mali Device Driver session
++ *
++ * This should be called when the process no longer requires use of the Mali Device Driver.
++ *
++ * The context handle must not be used after it has been closed.
++ *
++ * @param context pointer to a stored (void*)context handle.
++ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
++ */
++_mali_osk_errcode_t _mali_ukk_close( void **context );
++
++/** @} */ /* end group _mali_uk_context */
++
++
++/** @addtogroup _mali_uk_core U/K Core
++ *
++ * The core functions provide the following functionality:
++ * - verify that the user and kernel API are compatible
++ * - retrieve information about the cores and memory banks in the system
++ * - wait for the result of jobs started on a core
++ *
++ * @{ */
++
++/** @brief Waits for a job notification.
++ *
++ * Sleeps until notified or a timeout occurs. Returns information about the notification.
++ *
++ * @param args see _mali_uk_wait_for_notification_s in "mali_utgard_uk_types.h"
++ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
++ */
++_mali_osk_errcode_t _mali_ukk_wait_for_notification( _mali_uk_wait_for_notification_s *args );
++
++/** @brief Post a notification to the notification queue of this application.
++ *
++ * @param args see _mali_uk_post_notification_s in "mali_utgard_uk_types.h"
++ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
++ */
++_mali_osk_errcode_t _mali_ukk_post_notification( _mali_uk_post_notification_s *args );
++
++/** @brief Verifies if the user and kernel side of this API are compatible.
++ *
++ * @param args see _mali_uk_get_api_version_s in "mali_utgard_uk_types.h"
++ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
++ */
++_mali_osk_errcode_t _mali_ukk_get_api_version( _mali_uk_get_api_version_s *args );
++
++/** @brief Get the user space settings applicable for calling process.
++ *
++ * @param args see _mali_uk_get_user_settings_s in "mali_utgard_uk_types.h"
++ */
++_mali_osk_errcode_t _mali_ukk_get_user_settings(_mali_uk_get_user_settings_s *args);
++
++/** @brief Get a user space setting applicable for calling process.
++ *
++ * @param args see _mali_uk_get_user_setting_s in "mali_utgard_uk_types.h"
++ */
++_mali_osk_errcode_t _mali_ukk_get_user_setting(_mali_uk_get_user_setting_s *args);
++
++/** @} */ /* end group _mali_uk_core */
++
++
++/** @addtogroup _mali_uk_memory U/K Memory
++ *
++ * The memory functions provide functionality with and without a Mali-MMU present.
++ *
++ * For Mali-MMU based systems, the following functionality is provided:
++ * - Initialize and terminate MALI virtual address space
++ * - Allocate/deallocate physical memory to a MALI virtual address range and map into/unmap from the
++ * current process address space
++ * - Map/unmap external physical memory into the MALI virtual address range
++ *
++ * For Mali-nonMMU based systems:
++ * - Allocate/deallocate MALI memory
++ *
++ * @{ */
++
++/**
++ * @brief Initialize the Mali-MMU Memory system
++ *
++ * For Mali-MMU builds of the drivers, this function must be called before any
++ * other functions in the \ref _mali_uk_memory group are called.
++ *
++ * @note This function is for Mali-MMU builds \b only. It should not be called
++ * when the drivers are built without Mali-MMU support.
++ *
++ * @param args see \ref _mali_uk_init_mem_s in mali_utgard_uk_types.h
++ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable
++ * _mali_osk_errcode_t on failure.
++ */
++_mali_osk_errcode_t _mali_ukk_init_mem( _mali_uk_init_mem_s *args );
++
++/**
++ * @brief Terminate the MMU Memory system
++ *
++ * For Mali-MMU builds of the drivers, this function must be called when
++ * functions in the \ref _mali_uk_memory group will no longer be called. This
++ * function must be called before the application terminates.
++ *
++ * @note This function is for Mali-MMU builds \b only. It should not be called
++ * when the drivers are built without Mali-MMU support.
++ *
++ * @param args see \ref _mali_uk_term_mem_s in mali_utgard_uk_types.h
++ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable
++ * _mali_osk_errcode_t on failure.
++ */
++_mali_osk_errcode_t _mali_ukk_term_mem( _mali_uk_term_mem_s *args );
++
++/** @brief Map Mali Memory into the current user process
++ *
++ * Maps Mali memory into the current user process in a generic way.
++ *
++ * This function is to be used for Mali-MMU mode. The function is available in both Mali-MMU and Mali-nonMMU modes,
++ * but should not be called by a user process in Mali-nonMMU mode.
++ *
++ * The implementation and operation of _mali_ukk_mem_mmap() is dependant on whether the driver is built for Mali-MMU
++ * or Mali-nonMMU:
++ * - In the nonMMU case, _mali_ukk_mem_mmap() requires a physical address to be specified. For this reason, an OS U/K
++ * implementation should not allow this to be called from user-space. In any case, nonMMU implementations are
++ * inherently insecure, and so the overall impact is minimal. Mali-MMU mode should be used if security is desired.
++ * - In the MMU case, _mali_ukk_mem_mmap() the _mali_uk_mem_mmap_s::phys_addr
++ * member is used for the \em Mali-virtual address desired for the mapping. The
++ * implementation of _mali_ukk_mem_mmap() will allocate both the CPU-virtual
++ * and CPU-physical addresses, and can cope with mapping a contiguous virtual
++ * address range to a sequence of non-contiguous physical pages. In this case,
++ * the CPU-physical addresses are not communicated back to the user-side, as
++ * they are unnecsessary; the \em Mali-virtual address range must be used for
++ * programming Mali structures.
++ *
++ * In the second (MMU) case, _mali_ukk_mem_mmap() handles management of
++ * CPU-virtual and CPU-physical ranges, but the \em caller must manage the
++ * \em Mali-virtual address range from the user-side.
++ *
++ * @note Mali-virtual address ranges are entirely separate between processes.
++ * It is not possible for a process to accidentally corrupt another process'
++ * \em Mali-virtual address space.
++ *
++ * @param args see _mali_uk_mem_mmap_s in "mali_utgard_uk_types.h"
++ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
++ */
++_mali_osk_errcode_t _mali_ukk_mem_mmap( _mali_uk_mem_mmap_s *args );
++
++/** @brief Unmap Mali Memory from the current user process
++ *
++ * Unmaps Mali memory from the current user process in a generic way. This only operates on Mali memory supplied
++ * from _mali_ukk_mem_mmap().
++ *
++ * @param args see _mali_uk_mem_munmap_s in "mali_utgard_uk_types.h"
++ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
++ */
++_mali_osk_errcode_t _mali_ukk_mem_munmap( _mali_uk_mem_munmap_s *args );
++
++/** @brief Determine the buffer size necessary for an MMU page table dump.
++ * @param args see _mali_uk_query_mmu_page_table_dump_size_s in mali_utgard_uk_types.h
++ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
++ */
++_mali_osk_errcode_t _mali_ukk_query_mmu_page_table_dump_size( _mali_uk_query_mmu_page_table_dump_size_s *args );
++/** @brief Dump MMU Page tables.
++ * @param args see _mali_uk_dump_mmu_page_table_s in mali_utgard_uk_types.h
++ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
++ */
++_mali_osk_errcode_t _mali_ukk_dump_mmu_page_table( _mali_uk_dump_mmu_page_table_s * args );
++
++/** @brief Map a physically contiguous range of memory into Mali
++ * @param args see _mali_uk_map_external_mem_s in mali_utgard_uk_types.h
++ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
++ */
++_mali_osk_errcode_t _mali_ukk_map_external_mem( _mali_uk_map_external_mem_s *args );
++
++/** @brief Unmap a physically contiguous range of memory from Mali
++ * @param args see _mali_uk_unmap_external_mem_s in mali_utgard_uk_types.h
++ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
++ */
++_mali_osk_errcode_t _mali_ukk_unmap_external_mem( _mali_uk_unmap_external_mem_s *args );
++
++#if defined(CONFIG_MALI400_UMP)
++/** @brief Map UMP memory into Mali
++ * @param args see _mali_uk_attach_ump_mem_s in mali_utgard_uk_types.h
++ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
++ */
++_mali_osk_errcode_t _mali_ukk_attach_ump_mem( _mali_uk_attach_ump_mem_s *args );
++/** @brief Unmap UMP memory from Mali
++ * @param args see _mali_uk_release_ump_mem_s in mali_utgard_uk_types.h
++ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
++ */
++_mali_osk_errcode_t _mali_ukk_release_ump_mem( _mali_uk_release_ump_mem_s *args );
++#endif /* CONFIG_MALI400_UMP */
++
++/** @brief Determine virtual-to-physical mapping of a contiguous memory range
++ * (optional)
++ *
++ * This allows the user-side to do a virtual-to-physical address translation.
++ * In conjunction with _mali_uku_map_external_mem, this can be used to do
++ * direct rendering.
++ *
++ * This function will only succeed on a virtual range that is mapped into the
++ * current process, and that is contigious.
++ *
++ * If va is not page-aligned, then it is rounded down to the next page
++ * boundary. The remainer is added to size, such that ((u32)va)+size before
++ * rounding is equal to ((u32)va)+size after rounding. The rounded modified
++ * va and size will be written out into args on success.
++ *
++ * If the supplied size is zero, or not a multiple of the system's PAGE_SIZE,
++ * then size will be rounded up to the next multiple of PAGE_SIZE before
++ * translation occurs. The rounded up size will be written out into args on
++ * success.
++ *
++ * On most OSs, virtual-to-physical address translation is a priveledged
++ * function. Therefore, the implementer must validate the range supplied, to
++ * ensure they are not providing arbitrary virtual-to-physical address
++ * translations. While it is unlikely such a mechanism could be used to
++ * compromise the security of a system on its own, it is possible it could be
++ * combined with another small security risk to cause a much larger security
++ * risk.
++ *
++ * @note This is an optional part of the interface, and is only used by certain
++ * implementations of libEGL. If the platform layer in your libEGL
++ * implementation does not require Virtual-to-Physical address translation,
++ * then this function need not be implemented. A stub implementation should not
++ * be required either, as it would only be removed by the compiler's dead code
++ * elimination.
++ *
++ * @note if implemented, this function is entirely platform-dependant, and does
++ * not exist in common code.
++ *
++ * @param args see _mali_uk_va_to_mali_pa_s in "mali_utgard_uk_types.h"
++ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
++ */
++_mali_osk_errcode_t _mali_ukk_va_to_mali_pa( _mali_uk_va_to_mali_pa_s * args );
++
++/** @} */ /* end group _mali_uk_memory */
++
++
++/** @addtogroup _mali_uk_pp U/K Fragment Processor
++ *
++ * The Fragment Processor (aka PP (Pixel Processor)) functions provide the following functionality:
++ * - retrieving version of the fragment processors
++ * - determine number of fragment processors
++ * - starting a job on a fragment processor
++ *
++ * @{ */
++
++/** @brief Issue a request to start a new job on a Fragment Processor.
++ *
++ * If the request fails args->status is set to _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE and you can
++ * try to start the job again.
++ *
++ * An existing job could be returned for requeueing if the new job has a higher priority than a previously started job
++ * which the hardware hasn't actually started processing yet. In this case the new job will be started instead and the
++ * existing one returned, otherwise the new job is started and the status field args->status is set to
++ * _MALI_UK_START_JOB_STARTED.
++ *
++ * Job completion can be awaited with _mali_ukk_wait_for_notification().
++ *
++ * @oaram ctx user-kernel context (mali_session)
++ * @param uargs see _mali_uk_pp_start_job_s in "mali_utgard_uk_types.h". Use _mali_osk_copy_from_user to retrieve data!
++ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
++ */
++_mali_osk_errcode_t _mali_ukk_pp_start_job( void *ctx, _mali_uk_pp_start_job_s *uargs, int *fence );
++
++/** @brief Returns the number of Fragment Processors in the system
++ *
++ * @param args see _mali_uk_get_pp_number_of_cores_s in "mali_utgard_uk_types.h"
++ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
++ */
++_mali_osk_errcode_t _mali_ukk_get_pp_number_of_cores( _mali_uk_get_pp_number_of_cores_s *args );
++
++/** @brief Returns the version that all Fragment Processor cores are compatible with.
++ *
++ * This function may only be called when _mali_ukk_get_pp_number_of_cores() indicated at least one Fragment
++ * Processor core is available.
++ *
++ * @param args see _mali_uk_get_pp_core_version_s in "mali_utgard_uk_types.h"
++ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
++ */
++_mali_osk_errcode_t _mali_ukk_get_pp_core_version( _mali_uk_get_pp_core_version_s *args );
++
++/** @brief Disable Write-back unit(s) on specified job
++ *
++ * @param args see _mali_uk_get_pp_core_version_s in "mali_utgard_uk_types.h"
++ */
++void _mali_ukk_pp_job_disable_wb(_mali_uk_pp_disable_wb_s *args);
++
++
++/** @} */ /* end group _mali_uk_pp */
++
++
++/** @addtogroup _mali_uk_gp U/K Vertex Processor
++ *
++ * The Vertex Processor (aka GP (Geometry Processor)) functions provide the following functionality:
++ * - retrieving version of the Vertex Processors
++ * - determine number of Vertex Processors available
++ * - starting a job on a Vertex Processor
++ *
++ * @{ */
++
++/** @brief Issue a request to start a new job on a Vertex Processor.
++ *
++ * If the request fails args->status is set to _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE and you can
++ * try to start the job again.
++ *
++ * An existing job could be returned for requeueing if the new job has a higher priority than a previously started job
++ * which the hardware hasn't actually started processing yet. In this case the new job will be started and the
++ * existing one returned, otherwise the new job is started and the status field args->status is set to
++ * _MALI_UK_START_JOB_STARTED.
++ *
++ * Job completion can be awaited with _mali_ukk_wait_for_notification().
++ *
++ * @oaram ctx user-kernel context (mali_session)
++ * @param uargs see _mali_uk_gp_start_job_s in "mali_utgard_uk_types.h". Use _mali_osk_copy_from_user to retrieve data!
++ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
++ */
++_mali_osk_errcode_t _mali_ukk_gp_start_job( void *ctx, _mali_uk_gp_start_job_s *uargs );
++
++/** @brief Returns the number of Vertex Processors in the system.
++ *
++ * @param args see _mali_uk_get_gp_number_of_cores_s in "mali_utgard_uk_types.h"
++ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
++ */
++_mali_osk_errcode_t _mali_ukk_get_gp_number_of_cores( _mali_uk_get_gp_number_of_cores_s *args );
++
++/** @brief Returns the version that all Vertex Processor cores are compatible with.
++ *
++ * This function may only be called when _mali_uk_get_gp_number_of_cores() indicated at least one Vertex
++ * Processor core is available.
++ *
++ * @param args see _mali_uk_get_gp_core_version_s in "mali_utgard_uk_types.h"
++ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
++ */
++_mali_osk_errcode_t _mali_ukk_get_gp_core_version( _mali_uk_get_gp_core_version_s *args );
++
++/** @brief Resume or abort suspended Vertex Processor jobs.
++ *
++ * After receiving notification that a Vertex Processor job was suspended from
++ * _mali_ukk_wait_for_notification() you can use this function to resume or abort the job.
++ *
++ * @param args see _mali_uk_gp_suspend_response_s in "mali_utgard_uk_types.h"
++ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
++ */
++_mali_osk_errcode_t _mali_ukk_gp_suspend_response( _mali_uk_gp_suspend_response_s *args );
++
++/** @} */ /* end group _mali_uk_gp */
++
++#if defined(CONFIG_MALI400_PROFILING)
++/** @addtogroup _mali_uk_profiling U/K Timeline profiling module
++ * @{ */
++
++/** @brief Start recording profiling events.
++ *
++ * @param args see _mali_uk_profiling_start_s in "mali_utgard_uk_types.h"
++ */
++_mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args);
++
++/** @brief Add event to profiling buffer.
++ *
++ * @param args see _mali_uk_profiling_add_event_s in "mali_utgard_uk_types.h"
++ */
++_mali_osk_errcode_t _mali_ukk_profiling_add_event(_mali_uk_profiling_add_event_s *args);
++
++/** @brief Stop recording profiling events.
++ *
++ * @param args see _mali_uk_profiling_stop_s in "mali_utgard_uk_types.h"
++ */
++_mali_osk_errcode_t _mali_ukk_profiling_stop(_mali_uk_profiling_stop_s *args);
++
++/** @brief Retrieve a recorded profiling event.
++ *
++ * @param args see _mali_uk_profiling_get_event_s in "mali_utgard_uk_types.h"
++ */
++_mali_osk_errcode_t _mali_ukk_profiling_get_event(_mali_uk_profiling_get_event_s *args);
++
++/** @brief Clear recorded profiling events.
++ *
++ * @param args see _mali_uk_profiling_clear_s in "mali_utgard_uk_types.h"
++ */
++_mali_osk_errcode_t _mali_ukk_profiling_clear(_mali_uk_profiling_clear_s *args);
++
++/** @} */ /* end group _mali_uk_profiling */
++#endif
++
++/** @addtogroup _mali_uk_vsync U/K VSYNC reporting module
++ * @{ */
++
++/** @brief Report events related to vsync.
++ *
++ * @note Events should be reported when starting to wait for vsync and when the
++ * waiting is finished. This information can then be used in kernel space to
++ * complement the GPU utilization metric.
++ *
++ * @param args see _mali_uk_vsync_event_report_s in "mali_utgard_uk_types.h"
++ */
++_mali_osk_errcode_t _mali_ukk_vsync_event_report(_mali_uk_vsync_event_report_s *args);
++
++/** @} */ /* end group _mali_uk_vsync */
++
++/** @addtogroup _mali_sw_counters_report U/K Software counter reporting
++ * @{ */
++
++/** @brief Report software counters.
++ *
++ * @param args see _mali_uk_sw_counters_report_s in "mali_uk_types.h"
++ */
++_mali_osk_errcode_t _mali_ukk_sw_counters_report(_mali_uk_sw_counters_report_s *args);
++
++/** @} */ /* end group _mali_sw_counters_report */
++
++/** @} */ /* end group u_k_api */
++
++/** @} */ /* end group uddapi */
++
++u32 _mali_ukk_report_memory_usage(void);
++
++u32 _mali_ukk_utilization_gp_pp(void);
++
++u32 _mali_ukk_utilization_gp(void);
++
++u32 _mali_ukk_utilization_pp(void);
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* __MALI_UKK_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_user_settings_db.c b/drivers/gpu/arm/mali400/mali/common/mali_user_settings_db.c
+new file mode 100644
+index 0000000..389ab69
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_user_settings_db.c
+@@ -0,0 +1,88 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_osk.h"
++#include "mali_kernel_common.h"
++#include "mali_uk_types.h"
++#include "mali_user_settings_db.h"
++#include "mali_session.h"
++
++static u32 mali_user_settings[_MALI_UK_USER_SETTING_MAX];
++const char *_mali_uk_user_setting_descriptions[] = _MALI_UK_USER_SETTING_DESCRIPTIONS;
++
++static void mali_user_settings_notify(_mali_uk_user_setting_t setting, u32 value)
++{
++      struct mali_session_data *session, *tmp;
++
++      mali_session_lock();
++      MALI_SESSION_FOREACH(session, tmp, link)
++      {
++              _mali_osk_notification_t *notobj = _mali_osk_notification_create(_MALI_NOTIFICATION_SETTINGS_CHANGED, sizeof(_mali_uk_settings_changed_s));
++              _mali_uk_settings_changed_s *data = notobj->result_buffer;
++              data->setting = setting;
++              data->value = value;
++
++              mali_session_send_notification(session, notobj);
++      }
++      mali_session_unlock();
++}
++
++void mali_set_user_setting(_mali_uk_user_setting_t setting, u32 value)
++{
++      mali_bool notify = MALI_FALSE;
++
++      MALI_DEBUG_ASSERT(setting < _MALI_UK_USER_SETTING_MAX && setting >= 0);
++
++      if (mali_user_settings[setting] != value)
++      {
++              notify = MALI_TRUE;
++      }
++
++      mali_user_settings[setting] = value;
++
++      if (notify)
++      {
++              mali_user_settings_notify(setting, value);
++      }
++}
++
++u32 mali_get_user_setting(_mali_uk_user_setting_t setting)
++{
++      MALI_DEBUG_ASSERT(setting < _MALI_UK_USER_SETTING_MAX && setting >= 0);
++
++      return mali_user_settings[setting];
++}
++
++_mali_osk_errcode_t _mali_ukk_get_user_setting(_mali_uk_get_user_setting_s *args)
++{
++      _mali_uk_user_setting_t setting;
++      MALI_DEBUG_ASSERT_POINTER(args);
++
++      setting = args->setting;
++
++      if (0 <= setting && _MALI_UK_USER_SETTING_MAX > setting)
++      {
++              args->value = mali_user_settings[setting];
++              return _MALI_OSK_ERR_OK;
++      }
++      else
++      {
++              return _MALI_OSK_ERR_INVALID_ARGS;
++      }
++}
++
++_mali_osk_errcode_t _mali_ukk_get_user_settings(_mali_uk_get_user_settings_s *args)
++{
++      MALI_DEBUG_ASSERT_POINTER(args);
++
++      _mali_osk_memcpy(args->settings, mali_user_settings, sizeof(mali_user_settings));
++
++      return _MALI_OSK_ERR_OK;
++}
+diff --git a/drivers/gpu/arm/mali400/mali/common/mali_user_settings_db.h b/drivers/gpu/arm/mali400/mali/common/mali_user_settings_db.h
+new file mode 100644
+index 0000000..c93dfc7
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/common/mali_user_settings_db.h
+@@ -0,0 +1,40 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_USER_SETTINGS_DB_H__
++#define __MALI_USER_SETTINGS_DB_H__
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif
++
++#include "mali_uk_types.h"
++
++/** @brief Set Mali user setting in DB
++ *
++ * Update the DB with a new value for \a setting. If the value is different from theprevious set value running sessions will be notified of the change.
++ *
++ * @param setting the setting to be changed
++ * @param value the new value to set
++ */
++void mali_set_user_setting(_mali_uk_user_setting_t setting, u32 value);
++
++/** @brief Get current Mali user setting value from DB
++ *
++ * @param setting the setting to extract
++ * @return the value of the selected setting
++ */
++u32 mali_get_user_setting(_mali_uk_user_setting_t setting);
++
++#ifdef __cplusplus
++}
++#endif
++#endif  /* __MALI_KERNEL_USER_SETTING__ */
+diff --git a/drivers/gpu/arm/mali400/mali/include/linux/mali/mali_utgard.h b/drivers/gpu/arm/mali400/mali/include/linux/mali/mali_utgard.h
+new file mode 100644
+index 0000000..71ec677
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/include/linux/mali/mali_utgard.h
+@@ -0,0 +1,337 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_utgard.h
++ * Defines types and interface exposed by the Mali Utgard device driver
++ */
++
++#ifndef __MALI_UTGARD_H__
++#define __MALI_UTGARD_H__
++
++#define MALI_GPU_NAME_UTGARD "mali-utgard"
++
++/* Mali-200 */
++
++#define MALI_GPU_RESOURCES_MALI200(base_addr, gp_irq, pp_irq, mmu_irq) \
++      MALI_GPU_RESOURCE_PP(base_addr + 0x0000, pp_irq) \
++      MALI_GPU_RESOURCE_GP(base_addr + 0x2000, gp_irq) \
++      MALI_GPU_RESOURCE_MMU(base_addr + 0x3000, mmu_irq)
++
++/* Mali-300 */
++
++#define MALI_GPU_RESOURCES_MALI300(base_addr, gp_irq, gp_mmu_irq, pp_irq, pp_mmu_irq) \
++      MALI_GPU_RESOURCES_MALI400_MP1(base_addr, gp_irq, gp_mmu_irq, pp_irq, pp_mmu_irq)
++
++#define MALI_GPU_RESOURCES_MALI300_PMU(base_addr, gp_irq, gp_mmu_irq, pp_irq, pp_mmu_irq) \
++      MALI_GPU_RESOURCES_MALI400_MP1_PMU(base_addr, gp_irq, gp_mmu_irq, pp_irq, pp_mmu_irq)
++
++/* Mali-400 */
++
++#define MALI_GPU_RESOURCES_MALI400_MP1(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq) \
++      MALI_GPU_RESOURCE_L2(base_addr + 0x1000) \
++      MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x0000, gp_irq, base_addr + 0x3000, gp_mmu_irq) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x8000, pp0_irq, base_addr + 0x4000, pp0_mmu_irq)
++
++#define MALI_GPU_RESOURCES_MALI400_MP1_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq) \
++      MALI_GPU_RESOURCES_MALI400_MP1(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq) \
++      MALI_GPU_RESOURCE_PMU(base_addr + 0x2000)
++
++#define MALI_GPU_RESOURCES_MALI400_MP2(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq) \
++      MALI_GPU_RESOURCE_L2(base_addr + 0x1000) \
++      MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x0000, gp_irq, base_addr + 0x3000, gp_mmu_irq) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x8000, pp0_irq, base_addr + 0x4000, pp0_mmu_irq) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(1, base_addr + 0xA000, pp1_irq, base_addr + 0x5000, pp1_mmu_irq)
++
++#define MALI_GPU_RESOURCES_MALI400_MP2_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq) \
++      MALI_GPU_RESOURCES_MALI400_MP2(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq) \
++      MALI_GPU_RESOURCE_PMU(base_addr + 0x2000)
++
++#define MALI_GPU_RESOURCES_MALI400_MP3(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq) \
++      MALI_GPU_RESOURCE_L2(base_addr + 0x1000) \
++      MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x0000, gp_irq, base_addr + 0x3000, gp_mmu_irq) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x8000, pp0_irq, base_addr + 0x4000, pp0_mmu_irq) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(1, base_addr + 0xA000, pp1_irq, base_addr + 0x5000, pp1_mmu_irq) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(2, base_addr + 0xC000, pp2_irq, base_addr + 0x6000, pp2_mmu_irq)
++
++#define MALI_GPU_RESOURCES_MALI400_MP3_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq) \
++      MALI_GPU_RESOURCES_MALI400_MP3(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq) \
++      MALI_GPU_RESOURCE_PMU(base_addr + 0x2000)
++
++#define MALI_GPU_RESOURCES_MALI400_MP4(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq) \
++      MALI_GPU_RESOURCE_L2(base_addr + 0x1000) \
++      MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x0000, gp_irq, base_addr + 0x3000, gp_mmu_irq) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x8000, pp0_irq, base_addr + 0x4000, pp0_mmu_irq) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(1, base_addr + 0xA000, pp1_irq, base_addr + 0x5000, pp1_mmu_irq) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(2, base_addr + 0xC000, pp2_irq, base_addr + 0x6000, pp2_mmu_irq) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(3, base_addr + 0xE000, pp3_irq, base_addr + 0x7000, pp3_mmu_irq)
++
++#define MALI_GPU_RESOURCES_MALI400_MP4_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq) \
++      MALI_GPU_RESOURCES_MALI400_MP4(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq) \
++      MALI_GPU_RESOURCE_PMU(base_addr + 0x2000)
++
++/* Mali-450 */
++#define MALI_GPU_RESOURCES_MALI450_MP2(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp_bcast_irq) \
++      MALI_GPU_RESOURCE_L2(base_addr + 0x10000) \
++      MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x00000, gp_irq, base_addr + 0x03000, gp_mmu_irq) \
++      MALI_GPU_RESOURCE_L2(base_addr + 0x01000) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x08000, pp0_irq, base_addr + 0x04000, pp0_mmu_irq) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(1, base_addr + 0x0A000, pp1_irq, base_addr + 0x05000, pp1_mmu_irq) \
++      MALI_GPU_RESOURCE_BCAST(base_addr + 0x13000) \
++      MALI_GPU_RESOURCE_DLBU(base_addr + 0x14000) \
++      MALI_GPU_RESOURCE_PP_BCAST(base_addr + 0x16000, pp_bcast_irq) \
++      MALI_GPU_RESOURCE_PP_MMU_BCAST(base_addr + 0x15000)
++
++#define MALI_GPU_RESOURCES_MALI450_MP2_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp_bcast_irq) \
++      MALI_GPU_RESOURCES_MALI450_MP2(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp_bcast_irq) \
++      MALI_GPU_RESOURCE_PMU(base_addr + 0x2000) \
++
++#define MALI_GPU_RESOURCES_MALI450_MP4(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp_bcast_irq) \
++      MALI_GPU_RESOURCE_L2(base_addr + 0x10000) \
++      MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x00000, gp_irq, base_addr + 0x03000, gp_mmu_irq) \
++      MALI_GPU_RESOURCE_L2(base_addr + 0x01000) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x08000, pp0_irq, base_addr + 0x04000, pp0_mmu_irq) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(1, base_addr + 0x0A000, pp1_irq, base_addr + 0x05000, pp1_mmu_irq) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(2, base_addr + 0x0C000, pp2_irq, base_addr + 0x06000, pp2_mmu_irq) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(3, base_addr + 0x0E000, pp3_irq, base_addr + 0x07000, pp3_mmu_irq) \
++      MALI_GPU_RESOURCE_BCAST(base_addr + 0x13000) \
++      MALI_GPU_RESOURCE_DLBU(base_addr + 0x14000) \
++      MALI_GPU_RESOURCE_PP_BCAST(base_addr + 0x16000, pp_bcast_irq) \
++      MALI_GPU_RESOURCE_PP_MMU_BCAST(base_addr + 0x15000)
++
++#define MALI_GPU_RESOURCES_MALI450_MP4_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp_bcast_irq) \
++      MALI_GPU_RESOURCES_MALI450_MP4(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp_bcast_irq) \
++      MALI_GPU_RESOURCE_PMU(base_addr + 0x2000) \
++
++#define MALI_GPU_RESOURCES_MALI450_MP6(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp4_irq, pp4_mmu_irq, pp5_irq, pp5_mmu_irq, pp_bcast_irq) \
++      MALI_GPU_RESOURCE_L2(base_addr + 0x10000) \
++      MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x00000, gp_irq, base_addr + 0x03000, gp_mmu_irq) \
++      MALI_GPU_RESOURCE_L2(base_addr + 0x01000) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x08000, pp0_irq, base_addr + 0x04000, pp0_mmu_irq) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(1, base_addr + 0x0A000, pp1_irq, base_addr + 0x05000, pp1_mmu_irq) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(2, base_addr + 0x0C000, pp2_irq, base_addr + 0x06000, pp2_mmu_irq) \
++      MALI_GPU_RESOURCE_L2(base_addr + 0x11000) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(3, base_addr + 0x28000, pp3_irq, base_addr + 0x1C000, pp3_mmu_irq) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(4, base_addr + 0x2A000, pp4_irq, base_addr + 0x1D000, pp4_mmu_irq) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(5, base_addr + 0x2C000, pp5_irq, base_addr + 0x1E000, pp5_mmu_irq) \
++      MALI_GPU_RESOURCE_BCAST(base_addr + 0x13000) \
++      MALI_GPU_RESOURCE_DLBU(base_addr + 0x14000) \
++      MALI_GPU_RESOURCE_PP_BCAST(base_addr + 0x16000, pp_bcast_irq) \
++      MALI_GPU_RESOURCE_PP_MMU_BCAST(base_addr + 0x15000)
++
++#define MALI_GPU_RESOURCES_MALI450_MP6_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp4_irq, pp4_mmu_irq, pp5_irq, pp5_mmu_irq, pp_bcast_irq) \
++      MALI_GPU_RESOURCES_MALI450_MP6(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp4_irq, pp4_mmu_irq, pp5_irq, pp5_mmu_irq, pp_bcast_irq) \
++      MALI_GPU_RESOURCE_PMU(base_addr + 0x2000) \
++
++#define MALI_GPU_RESOURCES_MALI450_MP8(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp4_irq, pp4_mmu_irq, pp5_irq, pp5_mmu_irq, pp6_irq, pp6_mmu_irq, pp7_irq, pp7_mmu_irq, pp_bcast_irq) \
++      MALI_GPU_RESOURCE_L2(base_addr + 0x10000) \
++      MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x00000, gp_irq, base_addr + 0x03000, gp_mmu_irq) \
++      MALI_GPU_RESOURCE_L2(base_addr + 0x01000) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x08000, pp0_irq, base_addr + 0x04000, pp0_mmu_irq) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(1, base_addr + 0x0A000, pp1_irq, base_addr + 0x05000, pp1_mmu_irq) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(2, base_addr + 0x0C000, pp2_irq, base_addr + 0x06000, pp2_mmu_irq) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(3, base_addr + 0x0E000, pp3_irq, base_addr + 0x07000, pp3_mmu_irq) \
++      MALI_GPU_RESOURCE_L2(base_addr + 0x11000) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(4, base_addr + 0x28000, pp4_irq, base_addr + 0x1C000, pp4_mmu_irq) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(5, base_addr + 0x2A000, pp5_irq, base_addr + 0x1D000, pp5_mmu_irq) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(6, base_addr + 0x2C000, pp6_irq, base_addr + 0x1E000, pp6_mmu_irq) \
++      MALI_GPU_RESOURCE_PP_WITH_MMU(7, base_addr + 0x2E000, pp7_irq, base_addr + 0x1F000, pp7_mmu_irq) \
++      MALI_GPU_RESOURCE_BCAST(base_addr + 0x13000) \
++      MALI_GPU_RESOURCE_DLBU(base_addr + 0x14000) \
++      MALI_GPU_RESOURCE_PP_BCAST(base_addr + 0x16000, pp_bcast_irq) \
++      MALI_GPU_RESOURCE_PP_MMU_BCAST(base_addr + 0x15000)
++
++#define MALI_GPU_RESOURCES_MALI450_MP8_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp4_irq, pp4_mmu_irq, pp5_irq, pp5_mmu_irq, pp6_irq, pp6_mmu_irq, pp7_irq, pp7_mmu_irq, pp_bcast_irq) \
++      MALI_GPU_RESOURCES_MALI450_MP8(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp4_irq, pp4_mmu_irq, pp5_irq, pp5_mmu_irq, pp6_irq, pp6_mmu_irq, pp7_irq, pp7_mmu_irq, pp_bcast_irq) \
++      MALI_GPU_RESOURCE_PMU(base_addr + 0x2000) \
++
++#define MALI_GPU_RESOURCE_L2(addr) \
++      { \
++              .name = "Mali_L2", \
++              .flags = IORESOURCE_MEM, \
++              .start = addr, \
++              .end   = addr + 0x200, \
++      },
++
++#define MALI_GPU_RESOURCE_GP(gp_addr, gp_irq) \
++      { \
++              .name = "Mali_GP", \
++              .flags = IORESOURCE_MEM, \
++              .start = gp_addr, \
++              .end =   gp_addr + 0x100, \
++      }, \
++      { \
++              .name = "Mali_GP_IRQ", \
++              .flags = IORESOURCE_IRQ, \
++              .start = gp_irq, \
++              .end   = gp_irq, \
++      }, \
++
++#define MALI_GPU_RESOURCE_GP_WITH_MMU(gp_addr, gp_irq, gp_mmu_addr, gp_mmu_irq) \
++      { \
++              .name = "Mali_GP", \
++              .flags = IORESOURCE_MEM, \
++              .start = gp_addr, \
++              .end =   gp_addr + 0x100, \
++      }, \
++      { \
++              .name = "Mali_GP_IRQ", \
++              .flags = IORESOURCE_IRQ, \
++              .start = gp_irq, \
++              .end   = gp_irq, \
++      }, \
++      { \
++              .name = "Mali_GP_MMU", \
++              .flags = IORESOURCE_MEM, \
++              .start = gp_mmu_addr, \
++              .end =   gp_mmu_addr + 0x100, \
++      }, \
++      { \
++              .name = "Mali_GP_MMU_IRQ", \
++              .flags = IORESOURCE_IRQ, \
++              .start = gp_mmu_irq, \
++              .end =   gp_mmu_irq, \
++      },
++
++#define MALI_GPU_RESOURCE_PP(pp_addr, pp_irq) \
++      { \
++              .name = "Mali_PP", \
++              .flags = IORESOURCE_MEM, \
++              .start = pp_addr, \
++              .end =   pp_addr + 0x1100, \
++      }, \
++      { \
++              .name = "Mali_PP_IRQ", \
++              .flags = IORESOURCE_IRQ, \
++              .start = pp_irq, \
++              .end =   pp_irq, \
++      }, \
++
++#define MALI_GPU_RESOURCE_PP_WITH_MMU(id, pp_addr, pp_irq, pp_mmu_addr, pp_mmu_irq) \
++      { \
++              .name = "Mali_PP" #id, \
++              .flags = IORESOURCE_MEM, \
++              .start = pp_addr, \
++              .end =   pp_addr + 0x1100, \
++      }, \
++      { \
++              .name = "Mali_PP" #id "_IRQ", \
++              .flags = IORESOURCE_IRQ, \
++              .start = pp_irq, \
++              .end =   pp_irq, \
++      }, \
++      { \
++              .name = "Mali_PP" #id "_MMU", \
++              .flags = IORESOURCE_MEM, \
++              .start = pp_mmu_addr, \
++              .end =   pp_mmu_addr + 0x100, \
++      }, \
++      { \
++              .name = "Mali_PP" #id "_MMU_IRQ", \
++              .flags = IORESOURCE_IRQ, \
++              .start = pp_mmu_irq, \
++              .end =   pp_mmu_irq, \
++      },
++
++#define MALI_GPU_RESOURCE_MMU(mmu_addr, mmu_irq) \
++      { \
++              .name = "Mali_MMU", \
++              .flags = IORESOURCE_MEM, \
++              .start = mmu_addr, \
++              .end =   mmu_addr + 0x100, \
++      }, \
++      { \
++              .name = "Mali_MMU_IRQ", \
++              .flags = IORESOURCE_IRQ, \
++              .start = mmu_irq, \
++              .end =   mmu_irq, \
++      },
++
++#define MALI_GPU_RESOURCE_PMU(pmu_addr) \
++      { \
++              .name = "Mali_PMU", \
++              .flags = IORESOURCE_MEM, \
++              .start = pmu_addr, \
++              .end =   pmu_addr + 0x100, \
++      },
++
++#define MALI_GPU_RESOURCE_DLBU(dlbu_addr) \
++      { \
++              .name = "Mali_DLBU", \
++              .flags = IORESOURCE_MEM, \
++              .start = dlbu_addr, \
++              .end = dlbu_addr + 0x100, \
++      },
++
++#define MALI_GPU_RESOURCE_BCAST(bcast_addr) \
++      { \
++              .name = "Mali_Broadcast", \
++              .flags = IORESOURCE_MEM, \
++              .start = bcast_addr, \
++              .end = bcast_addr + 0x100, \
++      },
++
++#define MALI_GPU_RESOURCE_PP_BCAST(pp_addr, pp_irq) \
++      { \
++              .name = "Mali_PP_Broadcast", \
++              .flags = IORESOURCE_MEM, \
++              .start = pp_addr, \
++              .end =   pp_addr + 0x1100, \
++      }, \
++      { \
++              .name = "Mali_PP_Broadcast_IRQ", \
++              .flags = IORESOURCE_IRQ, \
++              .start = pp_irq, \
++              .end =   pp_irq, \
++      }, \
++
++#define MALI_GPU_RESOURCE_PP_MMU_BCAST(pp_mmu_bcast_addr) \
++      { \
++              .name = "Mali_PP_MMU_Broadcast", \
++              .flags = IORESOURCE_MEM, \
++              .start = pp_mmu_bcast_addr, \
++              .end = pp_mmu_bcast_addr + 0x100, \
++      },
++
++struct mali_gpu_device_data
++{
++      /* Dedicated GPU memory range (physical). */
++      unsigned long dedicated_mem_start;
++      unsigned long dedicated_mem_size;
++
++      /* Shared GPU memory */
++      unsigned long shared_mem_size;
++
++      /* Frame buffer memory to be accessible by Mali GPU (physical) */
++      unsigned long fb_start;
++      unsigned long fb_size;
++
++      /* Report GPU utilization in this interval (specified in ms) */
++      unsigned long utilization_interval;
++
++      /* Function that will receive periodic GPU utilization numbers */
++      void (*utilization_handler)(unsigned int);
++};
++
++/** @brief MALI GPU power down using MALI in-built PMU
++ * 
++ * called to power down all cores 
++ */
++int mali_pmu_powerdown(void);
++
++
++/** @brief MALI GPU power up using MALI in-built PMU
++ * 
++ * called to power up all cores 
++ */
++int mali_pmu_powerup(void);
++
++
++#endif
+diff --git a/drivers/gpu/arm/mali400/mali/include/linux/mali/mali_utgard_counters.h b/drivers/gpu/arm/mali400/mali/include/linux/mali/mali_utgard_counters.h
+new file mode 100644
+index 0000000..ca58bda
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/include/linux/mali/mali_utgard_counters.h
+@@ -0,0 +1,264 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef _MALI_UTGARD_COUNTERS_H_
++#define _MALI_UTGARD_COUNTERS_H_
++
++typedef struct
++{
++      void *unused;
++} mali_cinstr_counter_info;
++
++typedef enum
++{
++      MALI_CINSTR_COUNTER_SOURCE_EGL      =     0,
++      MALI_CINSTR_COUNTER_SOURCE_OPENGLES =  1000,
++      MALI_CINSTR_COUNTER_SOURCE_OPENVG   =  2000,
++      MALI_CINSTR_COUNTER_SOURCE_GP       =  3000,
++      MALI_CINSTR_COUNTER_SOURCE_PP       =  4000,
++} cinstr_counter_source;
++
++#define MALI_CINSTR_EGL_FIRST_COUNTER MALI_CINSTR_COUNTER_SOURCE_EGL
++#define MALI_CINSTR_EGL_LAST_COUNTER (MALI_CINSTR_COUNTER_SOURCE_EGL + 999)
++
++#define MALI_CINSTR_GLES_FIRST_COUNTER MALI_CINSTR_COUNTER_SOURCE_OPENGLES
++#define MALI_CINSTR_GLES_LAST_COUNTER (MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 999)
++
++#define MALI_CINSTR_VG_FIRST_COUNTER MALI_CINSTR_COUNTER_SOURCE_OPENVG
++#define MALI_CINSTR_VG_LAST_COUNTER (MALI_CINSTR_COUNTER_SOURCE_OPENVG + 999)
++
++#define MALI_CINSTR_GP_FIRST_COUNTER MALI_CINSTR_COUNTER_SOURCE_GP
++#define MALI_CINSTR_GP_LAST_COUNTER (MALI_CINSTR_COUNTER_SOURCE_GP + 999)
++
++#define MALI_CINSTR_PP_FIRST_COUNTER MALI_CINSTR_COUNTER_SOURCE_PP
++#define MALI_CINSTR_PP_LAST_COUNTER (MALI_CINSTR_COUNTER_SOURCE_PP + 999)
++
++
++typedef enum
++{
++      /* EGL counters */
++
++      MALI_CINSTR_EGL_BLIT_TIME                                            = MALI_CINSTR_COUNTER_SOURCE_EGL + 0,
++
++      /* Last counter in the EGL set */
++      MALI_CINSTR_EGL_MAX_COUNTER                                           = MALI_CINSTR_COUNTER_SOURCE_EGL + 1,
++
++      /* GLES counters */
++
++      MALI_CINSTR_GLES_DRAW_ELEMENTS_CALLS                                 = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 0,
++      MALI_CINSTR_GLES_DRAW_ELEMENTS_NUM_INDICES                           = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 1,
++      MALI_CINSTR_GLES_DRAW_ELEMENTS_NUM_TRANSFORMED                       = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 2,
++      MALI_CINSTR_GLES_DRAW_ARRAYS_CALLS                                   = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 3,
++      MALI_CINSTR_GLES_DRAW_ARRAYS_NUM_TRANSFORMED                         = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 4,
++      MALI_CINSTR_GLES_DRAW_POINTS                                         = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 5,
++      MALI_CINSTR_GLES_DRAW_LINES                                          = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 6,
++      MALI_CINSTR_GLES_DRAW_LINE_LOOP                                      = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 7,
++      MALI_CINSTR_GLES_DRAW_LINE_STRIP                                     = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 8,
++      MALI_CINSTR_GLES_DRAW_TRIANGLES                                      = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 9,
++      MALI_CINSTR_GLES_DRAW_TRIANGLE_STRIP                                 = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 10,
++      MALI_CINSTR_GLES_DRAW_TRIANGLE_FAN                                   = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 11,
++      MALI_CINSTR_GLES_NON_VBO_DATA_COPY_TIME                              = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 12,
++      MALI_CINSTR_GLES_UNIFORM_BYTES_COPIED_TO_MALI                        = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 13,
++      MALI_CINSTR_GLES_UPLOAD_TEXTURE_TIME                                 = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 14,
++      MALI_CINSTR_GLES_UPLOAD_VBO_TIME                                     = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 15,
++      MALI_CINSTR_GLES_NUM_FLUSHES                                         = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 16,
++      MALI_CINSTR_GLES_NUM_VSHADERS_GENERATED                              = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 17,
++      MALI_CINSTR_GLES_NUM_FSHADERS_GENERATED                              = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 18,
++      MALI_CINSTR_GLES_VSHADER_GEN_TIME                                    = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 19,
++      MALI_CINSTR_GLES_FSHADER_GEN_TIME                                    = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 20,
++      MALI_CINSTR_GLES_INPUT_TRIANGLES                                     = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 21,
++      MALI_CINSTR_GLES_VXCACHE_HIT                                         = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 22,
++      MALI_CINSTR_GLES_VXCACHE_MISS                                        = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 23,
++      MALI_CINSTR_GLES_VXCACHE_COLLISION                                   = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 24,
++      MALI_CINSTR_GLES_CULLED_TRIANGLES                                    = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 25,
++      MALI_CINSTR_GLES_CULLED_LINES                                        = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 26,
++      MALI_CINSTR_GLES_BACKFACE_TRIANGLES                                  = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 27,
++      MALI_CINSTR_GLES_GBCLIP_TRIANGLES                                    = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 28,
++      MALI_CINSTR_GLES_GBCLIP_LINES                                        = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 29,
++      MALI_CINSTR_GLES_TRIANGLES_DRAWN                                     = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 30,
++      MALI_CINSTR_GLES_DRAWCALL_TIME                                       = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 31,
++      MALI_CINSTR_GLES_TRIANGLES_COUNT                                     = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 32,
++      MALI_CINSTR_GLES_INDEPENDENT_TRIANGLES_COUNT                         = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 33,
++      MALI_CINSTR_GLES_STRIP_TRIANGLES_COUNT                               = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 34,
++      MALI_CINSTR_GLES_FAN_TRIANGLES_COUNT                                 = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 35,
++      MALI_CINSTR_GLES_LINES_COUNT                                         = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 36,
++      MALI_CINSTR_GLES_INDEPENDENT_LINES_COUNT                             = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 37,
++      MALI_CINSTR_GLES_STRIP_LINES_COUNT                                   = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 38,
++      MALI_CINSTR_GLES_LOOP_LINES_COUNT                                    = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 39,
++      MALI_CINSTR_GLES_POINTS_COUNT                                        = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 40,
++
++      /* Last counter in the GLES set */
++      MALI_CINSTR_GLES_MAX_COUNTER                                         = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 41,
++
++      /* OpenVG counters */
++
++      MALI_CINSTR_VG_MASK_COUNTER                                          = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 0,
++      MALI_CINSTR_VG_CLEAR_COUNTER                                         = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 1,
++      MALI_CINSTR_VG_APPEND_PATH_COUNTER                                   = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 2,
++      MALI_CINSTR_VG_APPEND_PATH_DATA_COUNTER                              = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 3,
++      MALI_CINSTR_VG_MODIFY_PATH_COORDS_COUNTER                            = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 4,
++      MALI_CINSTR_VG_TRANSFORM_PATH_COUNTER                                = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 5,
++      MALI_CINSTR_VG_INTERPOLATE_PATH_COUNTER                              = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 6,
++      MALI_CINSTR_VG_PATH_LENGTH_COUNTER                                   = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 7,
++      MALI_CINSTR_VG_POINT_ALONG_PATH_COUNTER                              = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 8,
++      MALI_CINSTR_VG_PATH_BOUNDS_COUNTER                                   = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 9,
++      MALI_CINSTR_VG_PATH_TRANSFORMED_BOUNDS_COUNTER                       = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 10,
++      MALI_CINSTR_VG_DRAW_PATH_COUNTER                                     = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 11,
++      MALI_CINSTR_VG_CLEAR_IMAGE_COUNTER                                   = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 12,
++      MALI_CINSTR_VG_IMAGE_SUB_DATA_COUNTER                                = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 13,
++      MALI_CINSTR_VG_GET_IMAGE_SUB_DATA_COUNTER                            = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 14,
++      MALI_CINSTR_VG_COPY_IMAGE_COUNTER                                    = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 15,
++      MALI_CINSTR_VG_DRAW_IMAGE_COUNTER                                    = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 16,
++      MALI_CINSTR_VG_SET_PIXELS_COUNTER                                    = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 17,
++      MALI_CINSTR_VG_WRITE_PIXELS_COUNTER                                  = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 18,
++      MALI_CINSTR_VG_GET_PIXELS_COUNTER                                    = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 19,
++      MALI_CINSTR_VG_READ_PIXELS_COUNTER                                   = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 20,
++      MALI_CINSTR_VG_COPY_PIXELS_COUNTER                                   = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 21,
++      MALI_CINSTR_VG_COLOR_MATRIX_COUNTER                                  = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 22,
++      MALI_CINSTR_VG_CONVOLVE_COUNTER                                      = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 23,
++      MALI_CINSTR_VG_SEPARABLE_CONVOLVE_COUNTER                            = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 24,
++      MALI_CINSTR_VG_GAUSSIAN_BLUR_COUNTER                                 = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 25,
++      MALI_CINSTR_VG_LOOKUP_COUNTER                                        = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 26,
++      MALI_CINSTR_VG_LOOKUP_SINGLE_COUNTER                                 = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 27,
++      MALI_CINSTR_VG_CONTEXT_CREATE_COUNTER                                = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 28,
++      MALI_CINSTR_VG_STROKED_CUBICS_COUNTER                                = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 29,
++      MALI_CINSTR_VG_STROKED_QUADS_COUNTER                                 = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 30,
++      MALI_CINSTR_VG_STROKED_ARCS_COUNTER                                  = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 31,
++      MALI_CINSTR_VG_STROKED_LINES_COUNTER                                 = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 32,
++      MALI_CINSTR_VG_FILLED_CUBICS_COUNTER                                 = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 33,
++      MALI_CINSTR_VG_FILLED_QUADS_COUNTER                                  = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 34,
++      MALI_CINSTR_VG_FILLED_ARCS_COUNTER                                   = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 35,
++      MALI_CINSTR_VG_FILLED_LINES_COUNTER                                  = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 36,
++      MALI_CINSTR_VG_DRAW_PATH_CALLS_COUNTER                               = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 37,
++      MALI_CINSTR_VG_TRIANGLES_COUNTER                                     = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 38,
++      MALI_CINSTR_VG_VERTICES_COUNTER                                      = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 39,
++      MALI_CINSTR_VG_INDICES_COUNTER                                       = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 40,
++      MALI_CINSTR_VG_FILLED_PATHS_COUNTER                                  = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 41,
++      MALI_CINSTR_VG_STROKED_PATHS_COUNTER                                 = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 42,
++      MALI_CINSTR_VG_FILL_EXTRACT_COUNTER                                  = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 43,
++      MALI_CINSTR_VG_DRAW_FILLED_PATH_COUNTER                              = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 44,
++      MALI_CINSTR_VG_STROKE_EXTRACT_COUNTER                                = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 45,
++      MALI_CINSTR_VG_DRAW_STROKED_PATH_COUNTER                             = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 46,
++      MALI_CINSTR_VG_DRAW_PAINT_COUNTER                                    = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 47,
++      MALI_CINSTR_VG_DATA_STRUCTURES_COUNTER                               = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 48,
++      MALI_CINSTR_VG_MEM_PATH_COUNTER                                      = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 49,
++      MALI_CINSTR_VG_RSW_COUNTER                                           = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 50,
++
++      /* Last counter in the VG set */
++      MALI_CINSTR_VG_MAX_COUNTER                                           = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 51,
++
++      /* Mali GP counters */
++
++      MALI_CINSTR_GP_DEPRECATED_0                                          = MALI_CINSTR_COUNTER_SOURCE_GP + 0,
++      MALI_CINSTR_GP_ACTIVE_CYCLES_GP                                      = MALI_CINSTR_COUNTER_SOURCE_GP + 1,
++      MALI_CINSTR_GP_ACTIVE_CYCLES_VERTEX_SHADER                           = MALI_CINSTR_COUNTER_SOURCE_GP + 2,
++      MALI_CINSTR_GP_ACTIVE_CYCLES_VERTEX_STORER                           = MALI_CINSTR_COUNTER_SOURCE_GP + 3,
++      MALI_CINSTR_GP_ACTIVE_CYCLES_VERTEX_LOADER                           = MALI_CINSTR_COUNTER_SOURCE_GP + 4,
++      MALI_CINSTR_GP_CYCLES_VERTEX_LOADER_WAITING_FOR_VERTEX_SHADER        = MALI_CINSTR_COUNTER_SOURCE_GP + 5,
++      MALI_CINSTR_GP_NUMBER_OF_WORDS_READ                                  = MALI_CINSTR_COUNTER_SOURCE_GP + 6,
++      MALI_CINSTR_GP_NUMBER_OF_WORDS_WRITTEN                               = MALI_CINSTR_COUNTER_SOURCE_GP + 7,
++      MALI_CINSTR_GP_NUMBER_OF_READ_BURSTS                                 = MALI_CINSTR_COUNTER_SOURCE_GP + 8,
++      MALI_CINSTR_GP_NUMBER_OF_WRITE_BURSTS                                = MALI_CINSTR_COUNTER_SOURCE_GP + 9,
++      MALI_CINSTR_GP_NUMBER_OF_VERTICES_PROCESSED                          = MALI_CINSTR_COUNTER_SOURCE_GP + 10,
++      MALI_CINSTR_GP_NUMBER_OF_VERTICES_FETCHED                            = MALI_CINSTR_COUNTER_SOURCE_GP + 11,
++      MALI_CINSTR_GP_NUMBER_OF_PRIMITIVES_FETCHED                          = MALI_CINSTR_COUNTER_SOURCE_GP + 12,
++      MALI_CINSTR_GP_RESERVED_13                                           = MALI_CINSTR_COUNTER_SOURCE_GP + 13,
++      MALI_CINSTR_GP_NUMBER_OF_BACKFACE_CULLINGS_DONE                      = MALI_CINSTR_COUNTER_SOURCE_GP + 14,
++      MALI_CINSTR_GP_NUMBER_OF_COMMANDS_WRITTEN_TO_TILES                   = MALI_CINSTR_COUNTER_SOURCE_GP + 15,
++      MALI_CINSTR_GP_NUMBER_OF_MEMORY_BLOCKS_ALLOCATED                     = MALI_CINSTR_COUNTER_SOURCE_GP + 16,
++      MALI_CINSTR_GP_RESERVED_17                                           = MALI_CINSTR_COUNTER_SOURCE_GP + 17,
++      MALI_CINSTR_GP_RESERVED_18                                           = MALI_CINSTR_COUNTER_SOURCE_GP + 18,
++      MALI_CINSTR_GP_NUMBER_OF_VERTEX_LOADER_CACHE_MISSES                  = MALI_CINSTR_COUNTER_SOURCE_GP + 19,
++      MALI_CINSTR_GP_RESERVED_20                                           = MALI_CINSTR_COUNTER_SOURCE_GP + 20,
++      MALI_CINSTR_GP_RESERVED_21                                           = MALI_CINSTR_COUNTER_SOURCE_GP + 21,
++      MALI_CINSTR_GP_ACTIVE_CYCLES_VERTEX_SHADER_COMMAND_PROCESSOR         = MALI_CINSTR_COUNTER_SOURCE_GP + 22,
++      MALI_CINSTR_GP_ACTIVE_CYCLES_PLBU_COMMAND_PROCESSOR                  = MALI_CINSTR_COUNTER_SOURCE_GP + 23,
++      MALI_CINSTR_GP_ACTIVE_CYCLES_PLBU_LIST_WRITER                        = MALI_CINSTR_COUNTER_SOURCE_GP + 24,
++      MALI_CINSTR_GP_ACTIVE_CYCLES_THROUGH_THE_PREPARE_LIST_COMMANDS       = MALI_CINSTR_COUNTER_SOURCE_GP + 25,
++      MALI_CINSTR_GP_RESERVED_26                                           = MALI_CINSTR_COUNTER_SOURCE_GP + 26,
++      MALI_CINSTR_GP_ACTIVE_CYCLES_PRIMITIVE_ASSEMBLY                      = MALI_CINSTR_COUNTER_SOURCE_GP + 27,
++      MALI_CINSTR_GP_ACTIVE_CYCLES_PLBU_VERTEX_FETCHER                     = MALI_CINSTR_COUNTER_SOURCE_GP + 28,
++      MALI_CINSTR_GP_RESERVED_29                                           = MALI_CINSTR_COUNTER_SOURCE_GP + 29,
++      MALI_CINSTR_GP_ACTIVE_CYCLES_BOUNDINGBOX_AND_COMMAND_GENERATOR       = MALI_CINSTR_COUNTER_SOURCE_GP + 30,
++      MALI_CINSTR_GP_RESERVED_31                                           = MALI_CINSTR_COUNTER_SOURCE_GP + 31,
++      MALI_CINSTR_GP_ACTIVE_CYCLES_SCISSOR_TILE_ITERATOR                   = MALI_CINSTR_COUNTER_SOURCE_GP + 32,
++      MALI_CINSTR_GP_ACTIVE_CYCLES_PLBU_TILE_ITERATOR                      = MALI_CINSTR_COUNTER_SOURCE_GP + 33,
++      MALI_CINSTR_GP_JOB_COUNT                                             = MALI_CINSTR_COUNTER_SOURCE_GP + 900,
++
++      /* Mali PP counters */
++
++      MALI_CINSTR_PP_ACTIVE_CLOCK_CYCLES_COUNT                             = MALI_CINSTR_COUNTER_SOURCE_PP + 0,
++      MALI_CINSTR_PP_TOTAL_CLOCK_CYCLES_COUNT_REMOVED                      = MALI_CINSTR_COUNTER_SOURCE_PP + 1,
++      MALI_CINSTR_PP_TOTAL_BUS_READS                                       = MALI_CINSTR_COUNTER_SOURCE_PP + 2,
++      MALI_CINSTR_PP_TOTAL_BUS_WRITES                                      = MALI_CINSTR_COUNTER_SOURCE_PP + 3,
++      MALI_CINSTR_PP_BUS_READ_REQUEST_CYCLES_COUNT                         = MALI_CINSTR_COUNTER_SOURCE_PP + 4,
++      MALI_CINSTR_PP_BUS_WRITE_REQUEST_CYCLES_COUNT                        = MALI_CINSTR_COUNTER_SOURCE_PP + 5,
++      MALI_CINSTR_PP_BUS_READ_TRANSACTIONS_COUNT                           = MALI_CINSTR_COUNTER_SOURCE_PP + 6,
++      MALI_CINSTR_PP_BUS_WRITE_TRANSACTIONS_COUNT                          = MALI_CINSTR_COUNTER_SOURCE_PP + 7,
++      MALI_CINSTR_PP_RESERVED_08                                           = MALI_CINSTR_COUNTER_SOURCE_PP + 8,
++      MALI_CINSTR_PP_TILE_WRITEBACK_WRITES                                 = MALI_CINSTR_COUNTER_SOURCE_PP + 9,
++      MALI_CINSTR_PP_STORE_UNIT_WRITES                                     = MALI_CINSTR_COUNTER_SOURCE_PP + 10,
++      MALI_CINSTR_PP_RESERVED_11                                           = MALI_CINSTR_COUNTER_SOURCE_PP + 11,
++      MALI_CINSTR_PP_PALETTE_CACHE_READS                                   = MALI_CINSTR_COUNTER_SOURCE_PP + 12,
++      MALI_CINSTR_PP_TEXTURE_CACHE_UNCOMPRESSED_READS                      = MALI_CINSTR_COUNTER_SOURCE_PP + 13,
++      MALI_CINSTR_PP_POLYGON_LIST_READS                                    = MALI_CINSTR_COUNTER_SOURCE_PP + 14,
++      MALI_CINSTR_PP_RSW_READS                                             = MALI_CINSTR_COUNTER_SOURCE_PP + 15,
++      MALI_CINSTR_PP_VERTEX_CACHE_READS                                    = MALI_CINSTR_COUNTER_SOURCE_PP + 16,
++      MALI_CINSTR_PP_UNIFORM_REMAPPING_READS                               = MALI_CINSTR_COUNTER_SOURCE_PP + 17,
++      MALI_CINSTR_PP_PROGRAM_CACHE_READS                                   = MALI_CINSTR_COUNTER_SOURCE_PP + 18,
++      MALI_CINSTR_PP_VARYING_READS                                         = MALI_CINSTR_COUNTER_SOURCE_PP + 19,
++      MALI_CINSTR_PP_TEXTURE_DESCRIPTORS_READS                             = MALI_CINSTR_COUNTER_SOURCE_PP + 20,
++      MALI_CINSTR_PP_TEXTURE_DESCRIPTORS_REMAPPING_READS                   = MALI_CINSTR_COUNTER_SOURCE_PP + 21,
++      MALI_CINSTR_PP_TEXTURE_CACHE_COMPRESSED_READS                        = MALI_CINSTR_COUNTER_SOURCE_PP + 22,
++      MALI_CINSTR_PP_LOAD_UNIT_READS                                       = MALI_CINSTR_COUNTER_SOURCE_PP + 23,
++      MALI_CINSTR_PP_POLYGON_COUNT                                         = MALI_CINSTR_COUNTER_SOURCE_PP + 24,
++      MALI_CINSTR_PP_PIXEL_RECTANGLE_COUNT                                 = MALI_CINSTR_COUNTER_SOURCE_PP + 25,
++      MALI_CINSTR_PP_LINES_COUNT                                           = MALI_CINSTR_COUNTER_SOURCE_PP + 26,
++      MALI_CINSTR_PP_POINTS_COUNT                                          = MALI_CINSTR_COUNTER_SOURCE_PP + 27,
++      MALI_CINSTR_PP_STALL_CYCLES_POLYGON_LIST_READER                      = MALI_CINSTR_COUNTER_SOURCE_PP + 28,
++      MALI_CINSTR_PP_STALL_CYCLES_TRIANGLE_SETUP                           = MALI_CINSTR_COUNTER_SOURCE_PP + 29,
++      MALI_CINSTR_PP_QUAD_RASTERIZED_COUNT                                 = MALI_CINSTR_COUNTER_SOURCE_PP + 30,
++      MALI_CINSTR_PP_FRAGMENT_RASTERIZED_COUNT                             = MALI_CINSTR_COUNTER_SOURCE_PP + 31,
++      MALI_CINSTR_PP_FRAGMENT_REJECTED_FRAGMENT_KILL_COUNT                 = MALI_CINSTR_COUNTER_SOURCE_PP + 32,
++      MALI_CINSTR_PP_FRAGMENT_REJECTED_FWD_FRAGMENT_KILL_COUNT             = MALI_CINSTR_COUNTER_SOURCE_PP + 33,
++      MALI_CINSTR_PP_FRAGMENT_PASSED_ZSTENCIL_COUNT                        = MALI_CINSTR_COUNTER_SOURCE_PP + 34,
++      MALI_CINSTR_PP_PATCHES_REJECTED_EARLY_Z_STENCIL_COUNT                = MALI_CINSTR_COUNTER_SOURCE_PP + 35,
++      MALI_CINSTR_PP_PATCHES_EVALUATED                                     = MALI_CINSTR_COUNTER_SOURCE_PP + 36,
++      MALI_CINSTR_PP_INSTRUCTION_COMPLETED_COUNT                           = MALI_CINSTR_COUNTER_SOURCE_PP + 37,
++      MALI_CINSTR_PP_INSTRUCTION_FAILED_RENDEZVOUS_COUNT                   = MALI_CINSTR_COUNTER_SOURCE_PP + 38,
++      MALI_CINSTR_PP_INSTRUCTION_FAILED_VARYING_MISS_COUNT                 = MALI_CINSTR_COUNTER_SOURCE_PP + 39,
++      MALI_CINSTR_PP_INSTRUCTION_FAILED_TEXTURE_MISS_COUNT                 = MALI_CINSTR_COUNTER_SOURCE_PP + 40,
++      MALI_CINSTR_PP_INSTRUCTION_FAILED_LOAD_MISS_COUNT                    = MALI_CINSTR_COUNTER_SOURCE_PP + 41,
++      MALI_CINSTR_PP_INSTRUCTION_FAILED_TILE_READ_MISS_COUNT               = MALI_CINSTR_COUNTER_SOURCE_PP + 42,
++      MALI_CINSTR_PP_INSTRUCTION_FAILED_STORE_MISS_COUNT                   = MALI_CINSTR_COUNTER_SOURCE_PP + 43,
++      MALI_CINSTR_PP_RENDEZVOUS_BREAKAGE_COUNT                             = MALI_CINSTR_COUNTER_SOURCE_PP + 44,
++      MALI_CINSTR_PP_PIPELINE_BUBBLES_CYCLE_COUNT                          = MALI_CINSTR_COUNTER_SOURCE_PP + 45,
++      MALI_CINSTR_PP_TEXTURE_MAPPER_MULTIPASS_COUNT                        = MALI_CINSTR_COUNTER_SOURCE_PP + 46,
++      MALI_CINSTR_PP_TEXTURE_MAPPER_CYCLE_COUNT                            = MALI_CINSTR_COUNTER_SOURCE_PP + 47,
++      MALI_CINSTR_PP_VERTEX_CACHE_HIT_COUNT                                = MALI_CINSTR_COUNTER_SOURCE_PP + 48,
++      MALI_CINSTR_PP_VERTEX_CACHE_MISS_COUNT                               = MALI_CINSTR_COUNTER_SOURCE_PP + 49,
++      MALI_CINSTR_PP_VARYING_CACHE_HIT_COUNT                               = MALI_CINSTR_COUNTER_SOURCE_PP + 50,
++      MALI_CINSTR_PP_VARYING_CACHE_MISS_COUNT                              = MALI_CINSTR_COUNTER_SOURCE_PP + 51,
++      MALI_CINSTR_PP_VARYING_CACHE_CONFLICT_MISS_COUNT                     = MALI_CINSTR_COUNTER_SOURCE_PP + 52,
++      MALI_CINSTR_PP_TEXTURE_CACHE_HIT_COUNT                               = MALI_CINSTR_COUNTER_SOURCE_PP + 53,
++      MALI_CINSTR_PP_TEXTURE_CACHE_MISS_COUNT                              = MALI_CINSTR_COUNTER_SOURCE_PP + 54,
++      MALI_CINSTR_PP_TEXTURE_CACHE_CONFLICT_MISS_COUNT                     = MALI_CINSTR_COUNTER_SOURCE_PP + 55,
++      MALI_CINSTR_PP_PALETTE_CACHE_HIT_COUNT                               = MALI_CINSTR_COUNTER_SOURCE_PP + 56, /* Mali 200 only */
++      MALI_CINSTR_PP_PALETTE_CACHE_MISS_COUNT                              = MALI_CINSTR_COUNTER_SOURCE_PP + 57, /* Mali 200 only */
++      MALI_CINSTR_PP_COMPRESSED_TEXTURE_CACHE_HIT_COUNT                    = MALI_CINSTR_COUNTER_SOURCE_PP + 56, /* Mali 400 class only */
++      MALI_CINSTR_PP_COMPRESSED_TEXTURE_CACHE_MISS_COUNT                   = MALI_CINSTR_COUNTER_SOURCE_PP + 57, /* Mali 400 class only */
++      MALI_CINSTR_PP_LOAD_STORE_CACHE_HIT_COUNT                            = MALI_CINSTR_COUNTER_SOURCE_PP + 58,
++      MALI_CINSTR_PP_LOAD_STORE_CACHE_MISS_COUNT                           = MALI_CINSTR_COUNTER_SOURCE_PP + 59,
++      MALI_CINSTR_PP_PROGRAM_CACHE_HIT_COUNT                               = MALI_CINSTR_COUNTER_SOURCE_PP + 60,
++      MALI_CINSTR_PP_PROGRAM_CACHE_MISS_COUNT                              = MALI_CINSTR_COUNTER_SOURCE_PP + 61,
++      MALI_CINSTR_PP_JOB_COUNT                                             = MALI_CINSTR_COUNTER_SOURCE_PP + 900,
++} cinstr_counters_m200_t;
++
++#endif /*_MALI_UTGARD_COUNTERS_H_*/
+diff --git a/drivers/gpu/arm/mali400/mali/include/linux/mali/mali_utgard_ioctl.h b/drivers/gpu/arm/mali400/mali/include/linux/mali/mali_utgard_ioctl.h
+new file mode 100644
+index 0000000..f9ff110
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/include/linux/mali/mali_utgard_ioctl.h
+@@ -0,0 +1,88 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_UTGARD_IOCTL_H__
++#define __MALI_UTGARD_IOCTL_H__
++
++#include <linux/types.h>
++#include <linux/ioctl.h>
++#include <linux/fs.h>       /* file system operations */
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif
++
++/**
++ * @file mali_kernel_ioctl.h
++ * Interface to the Linux device driver.
++ * This file describes the interface needed to use the Linux device driver.
++ * Its interface is designed to used by the HAL implementation through a thin arch layer.
++ */
++
++/**
++ * ioctl commands
++ */
++
++#define MALI_IOC_BASE           0x82
++#define MALI_IOC_CORE_BASE      (_MALI_UK_CORE_SUBSYSTEM      + MALI_IOC_BASE)
++#define MALI_IOC_MEMORY_BASE    (_MALI_UK_MEMORY_SUBSYSTEM    + MALI_IOC_BASE)
++#define MALI_IOC_PP_BASE        (_MALI_UK_PP_SUBSYSTEM        + MALI_IOC_BASE)
++#define MALI_IOC_GP_BASE        (_MALI_UK_GP_SUBSYSTEM        + MALI_IOC_BASE)
++#define MALI_IOC_PROFILING_BASE (_MALI_UK_PROFILING_SUBSYSTEM + MALI_IOC_BASE)
++#define MALI_IOC_VSYNC_BASE     (_MALI_UK_VSYNC_SUBSYSTEM + MALI_IOC_BASE)
++
++#define MALI_IOC_WAIT_FOR_NOTIFICATION      _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_WAIT_FOR_NOTIFICATION, _mali_uk_wait_for_notification_s *)
++#define MALI_IOC_GET_API_VERSION            _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_GET_API_VERSION, _mali_uk_get_api_version_s *)
++#define MALI_IOC_POST_NOTIFICATION          _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_POST_NOTIFICATION, _mali_uk_post_notification_s *)
++#define MALI_IOC_GET_USER_SETTING           _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_GET_USER_SETTING, _mali_uk_get_user_setting_s *)
++#define MALI_IOC_GET_USER_SETTINGS          _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_GET_USER_SETTINGS, _mali_uk_get_user_settings_s *)
++#define MALI_IOC_STREAM_CREATE              _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_STREAM_CREATE, _mali_uk_stream_create_s *)
++#define MALI_IOC_FENCE_VALIDATE             _IOR(MALI_IOC_CORE_BASE, _MALI_UK_FENCE_VALIDATE, _mali_uk_fence_validate_s *)
++
++#define MALI_IOC_MEM_GET_BIG_BLOCK          _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_GET_BIG_BLOCK, void *)
++#define MALI_IOC_MEM_FREE_BIG_BLOCK         _IOW (MALI_IOC_MEMORY_BASE, _MALI_UK_FREE_BIG_BLOCK, void *)
++#define MALI_IOC_MEM_INIT                   _IOR (MALI_IOC_MEMORY_BASE, _MALI_UK_INIT_MEM, _mali_uk_init_mem_s *)
++#define MALI_IOC_MEM_TERM                   _IOW (MALI_IOC_MEMORY_BASE, _MALI_UK_TERM_MEM, _mali_uk_term_mem_s *)
++#define MALI_IOC_MEM_MAP_EXT                _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_MAP_EXT_MEM, _mali_uk_map_external_mem_s *)
++#define MALI_IOC_MEM_UNMAP_EXT              _IOW (MALI_IOC_MEMORY_BASE, _MALI_UK_UNMAP_EXT_MEM, _mali_uk_unmap_external_mem_s *)
++#define MALI_IOC_MEM_ATTACH_DMA_BUF         _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_ATTACH_DMA_BUF, _mali_uk_attach_dma_buf_s *)
++#define MALI_IOC_MEM_RELEASE_DMA_BUF        _IOW(MALI_IOC_MEMORY_BASE, _MALI_UK_RELEASE_DMA_BUF, _mali_uk_release_dma_buf_s *)
++#define MALI_IOC_MEM_DMA_BUF_GET_SIZE       _IOR(MALI_IOC_MEMORY_BASE, _MALI_UK_DMA_BUF_GET_SIZE, _mali_uk_dma_buf_get_size_s *)
++#define MALI_IOC_MEM_ATTACH_UMP             _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_ATTACH_UMP_MEM, _mali_uk_attach_ump_mem_s *)
++#define MALI_IOC_MEM_RELEASE_UMP            _IOW(MALI_IOC_MEMORY_BASE, _MALI_UK_RELEASE_UMP_MEM, _mali_uk_release_ump_mem_s *)
++#define MALI_IOC_MEM_QUERY_MMU_PAGE_TABLE_DUMP_SIZE _IOR (MALI_IOC_MEMORY_BASE, _MALI_UK_QUERY_MMU_PAGE_TABLE_DUMP_SIZE, _mali_uk_query_mmu_page_table_dump_size_s *)
++#define MALI_IOC_MEM_DUMP_MMU_PAGE_TABLE    _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_DUMP_MMU_PAGE_TABLE, _mali_uk_dump_mmu_page_table_s *)
++
++#define MALI_IOC_PP_START_JOB               _IOWR(MALI_IOC_PP_BASE, _MALI_UK_PP_START_JOB, _mali_uk_pp_start_job_s *)
++#define MALI_IOC_PP_NUMBER_OF_CORES_GET           _IOR (MALI_IOC_PP_BASE, _MALI_UK_GET_PP_NUMBER_OF_CORES, _mali_uk_get_pp_number_of_cores_s *)
++#define MALI_IOC_PP_CORE_VERSION_GET      _IOR (MALI_IOC_PP_BASE, _MALI_UK_GET_PP_CORE_VERSION, _mali_uk_get_pp_core_version_s * )
++#define MALI_IOC_PP_DISABLE_WB              _IOW (MALI_IOC_PP_BASE, _MALI_UK_PP_DISABLE_WB, _mali_uk_pp_disable_wb_s * )
++
++#define MALI_IOC_GP2_START_JOB              _IOWR(MALI_IOC_GP_BASE, _MALI_UK_GP_START_JOB, _mali_uk_gp_start_job_s *)
++#define MALI_IOC_GP2_NUMBER_OF_CORES_GET    _IOR (MALI_IOC_GP_BASE, _MALI_UK_GET_GP_NUMBER_OF_CORES, _mali_uk_get_gp_number_of_cores_s *)
++#define MALI_IOC_GP2_CORE_VERSION_GET     _IOR (MALI_IOC_GP_BASE, _MALI_UK_GET_GP_CORE_VERSION, _mali_uk_get_gp_core_version_s *)
++#define MALI_IOC_GP2_SUSPEND_RESPONSE     _IOW (MALI_IOC_GP_BASE, _MALI_UK_GP_SUSPEND_RESPONSE,_mali_uk_gp_suspend_response_s *)
++
++#define MALI_IOC_PROFILING_START            _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_START, _mali_uk_profiling_start_s *)
++#define MALI_IOC_PROFILING_ADD_EVENT        _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_ADD_EVENT, _mali_uk_profiling_add_event_s*)
++#define MALI_IOC_PROFILING_STOP             _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_STOP, _mali_uk_profiling_stop_s *)
++#define MALI_IOC_PROFILING_GET_EVENT        _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_GET_EVENT, _mali_uk_profiling_get_event_s *)
++#define MALI_IOC_PROFILING_CLEAR            _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_CLEAR, _mali_uk_profiling_clear_s *)
++#define MALI_IOC_PROFILING_GET_CONFIG       _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_GET_CONFIG, _mali_uk_get_user_settings_s *)
++#define MALI_IOC_PROFILING_REPORT_SW_COUNTERS  _IOW (MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_REPORT_SW_COUNTERS, _mali_uk_sw_counters_report_s *)
++
++#define MALI_IOC_VSYNC_EVENT_REPORT         _IOW (MALI_IOC_VSYNC_BASE, _MALI_UK_VSYNC_EVENT_REPORT, _mali_uk_vsync_event_report_s *)
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* __MALI_UTGARD_IOCTL_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/include/linux/mali/mali_utgard_profiling_events.h b/drivers/gpu/arm/mali400/mali/include/linux/mali/mali_utgard_profiling_events.h
+new file mode 100644
+index 0000000..1642926
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/include/linux/mali/mali_utgard_profiling_events.h
+@@ -0,0 +1,167 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef _MALI_UTGARD_PROFILING_EVENTS_H_
++#define _MALI_UTGARD_PROFILING_EVENTS_H_
++
++/*
++ * The event ID is a 32 bit value consisting of different fields
++ * reserved, 4 bits, for future use
++ * event type, 4 bits, cinstr_profiling_event_type_t
++ * event channel, 8 bits, the source of the event.
++ * event data, 16 bit field, data depending on event type
++ */
++
++/**
++ * Specifies what kind of event this is
++ */
++typedef enum
++{
++      MALI_PROFILING_EVENT_TYPE_SINGLE  = 0 << 24,
++      MALI_PROFILING_EVENT_TYPE_START   = 1 << 24,
++      MALI_PROFILING_EVENT_TYPE_STOP    = 2 << 24,
++      MALI_PROFILING_EVENT_TYPE_SUSPEND = 3 << 24,
++      MALI_PROFILING_EVENT_TYPE_RESUME  = 4 << 24,
++} cinstr_profiling_event_type_t;
++
++
++/**
++ * Secifies the channel/source of the event
++ */
++typedef enum
++{
++      MALI_PROFILING_EVENT_CHANNEL_SOFTWARE =  0 << 16,
++      MALI_PROFILING_EVENT_CHANNEL_GP0      =  1 << 16,
++      MALI_PROFILING_EVENT_CHANNEL_PP0      =  5 << 16,
++      MALI_PROFILING_EVENT_CHANNEL_PP1      =  6 << 16,
++      MALI_PROFILING_EVENT_CHANNEL_PP2      =  7 << 16,
++      MALI_PROFILING_EVENT_CHANNEL_PP3      =  8 << 16,
++      MALI_PROFILING_EVENT_CHANNEL_PP4      =  9 << 16,
++      MALI_PROFILING_EVENT_CHANNEL_PP5      = 10 << 16,
++      MALI_PROFILING_EVENT_CHANNEL_PP6      = 11 << 16,
++      MALI_PROFILING_EVENT_CHANNEL_PP7      = 12 << 16,
++      MALI_PROFILING_EVENT_CHANNEL_GPU      = 21 << 16,
++} cinstr_profiling_event_channel_t;
++
++
++#define MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(num) (((MALI_PROFILING_EVENT_CHANNEL_GP0 >> 16) + (num)) << 16)
++#define MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(num) (((MALI_PROFILING_EVENT_CHANNEL_PP0 >> 16) + (num)) << 16)
++
++/**
++ * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SINGLE is used from software channel
++ */
++typedef enum
++{
++      MALI_PROFILING_EVENT_REASON_SINGLE_SW_NONE                  = 0,
++      MALI_PROFILING_EVENT_REASON_SINGLE_SW_EGL_NEW_FRAME         = 1,
++      MALI_PROFILING_EVENT_REASON_SINGLE_SW_FLUSH                 = 2,
++      MALI_PROFILING_EVENT_REASON_SINGLE_SW_EGL_SWAP_BUFFERS      = 3,
++      MALI_PROFILING_EVENT_REASON_SINGLE_SW_FB_EVENT              = 4,
++      MALI_PROFILING_EVENT_REASON_SINGLE_SW_GP_ENQUEUE            = 5,
++      MALI_PROFILING_EVENT_REASON_SINGLE_SW_PP_ENQUEUE            = 6,
++    MALI_PROFILING_EVENT_REASON_SINGLE_SW_ENTER_API_FUNC        = 10,
++    MALI_PROFILING_EVENT_REASON_SINGLE_SW_LEAVE_API_FUNC        = 11,
++    MALI_PROFILING_EVENT_REASON_SINGLE_SW_UMP_TRY_LOCK          = 53,
++      MALI_PROFILING_EVENT_REASON_SINGLE_SW_UMP_LOCK              = 54,
++      MALI_PROFILING_EVENT_REASON_SINGLE_SW_UMP_UNLOCK            = 55,
++      MALI_PROFILING_EVENT_REASON_SINGLE_LOCK_CONTENDED           = 56,
++} cinstr_profiling_event_reason_single_sw_t;
++
++/**
++ * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_START/STOP is used from software channel
++ * to inform whether the core is physical or virtual
++ */
++typedef enum
++{
++      MALI_PROFILING_EVENT_REASON_START_STOP_HW_PHYSICAL  = 0,
++      MALI_PROFILING_EVENT_REASON_START_STOP_HW_VIRTUAL   = 1,
++} cinstr_profiling_event_reason_start_stop_hw_t;
++
++/**
++ * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_START/STOP is used from software channel
++ */
++typedef enum
++{
++      /*MALI_PROFILING_EVENT_REASON_START_STOP_SW_NONE            = 0,*/
++      MALI_PROFILING_EVENT_REASON_START_STOP_SW_MALI            = 1,
++      MALI_PROFILING_EVENT_REASON_START_STOP_SW_CALLBACK_THREAD = 2,
++      MALI_PROFILING_EVENT_REASON_START_STOP_SW_WORKER_THREAD   = 3,
++      MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF     = 4,
++      MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF      = 5,
++} cinstr_profiling_event_reason_start_stop_sw_t;
++
++/**
++ * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SUSPEND/RESUME is used from software channel
++ */
++typedef enum
++{
++      MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_NONE                   =  0, /* used */
++      MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_PIPELINE_FULL          =  1, /* NOT used */
++      MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VSYNC                  = 26, /* used in some build configurations */
++      MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_FB_IFRAME_WAIT         = 27, /* USED */
++      MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_FB_IFRAME_SYNC         = 28, /* USED */
++      MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VG_WAIT_FILTER_CLEANUP = 29, /* used */
++      MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VG_WAIT_TEXTURE        = 30, /* used */
++      MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_GLES_WAIT_MIPLEVEL     = 31, /* used */
++      MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_GLES_WAIT_READPIXELS   = 32, /* used */
++      MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_EGL_WAIT_SWAP_IMMEDIATE= 33, /* NOT used */
++      MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_ICS_QUEUE_BUFFER       = 34, /* USED */
++      MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_ICS_DEQUEUE_BUFFER     = 35, /* USED */
++      MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_UMP_LOCK               = 36, /* Not currently used */
++      MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_X11_GLOBAL_LOCK        = 37, /* Not currently used */
++      MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_X11_SWAP               = 38, /* Not currently used */
++      MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_MALI_EGL_IMAGE_SYNC_WAIT = 39, /* USED */
++} cinstr_profiling_event_reason_suspend_resume_sw_t;
++
++/**
++ * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SINGLE is used from a HW channel (GPx+PPx)
++ */
++typedef enum
++{
++      MALI_PROFILING_EVENT_REASON_SINGLE_HW_NONE          = 0,
++      MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT     = 1,
++      MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH         = 2,
++} cinstr_profiling_event_reason_single_hw_t;
++
++/**
++ * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SINGLE is used from the GPU channel
++ */
++typedef enum
++{
++      MALI_PROFILING_EVENT_REASON_SINGLE_GPU_NONE              = 0,
++      MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE  = 1,
++      MALI_PROFILING_EVENT_REASON_SINGLE_GPU_L20_COUNTERS      = 2,
++      MALI_PROFILING_EVENT_REASON_SINGLE_GPU_L21_COUNTERS      = 3,
++      MALI_PROFILING_EVENT_REASON_SINGLE_GPU_L22_COUNTERS      = 4,
++} cinstr_profiling_event_reason_single_gpu_t;
++
++/**
++ * These values are applicable for the 3rd data parameter when
++ * the type MALI_PROFILING_EVENT_TYPE_START is used from the software channel
++ * with the MALI_PROFILING_EVENT_REASON_START_STOP_BOTTOM_HALF reason.
++ */
++typedef enum
++{
++      MALI_PROFILING_EVENT_DATA_CORE_GP0             =  1,
++      MALI_PROFILING_EVENT_DATA_CORE_PP0             =  5,
++      MALI_PROFILING_EVENT_DATA_CORE_PP1             =  6,
++      MALI_PROFILING_EVENT_DATA_CORE_PP2             =  7,
++      MALI_PROFILING_EVENT_DATA_CORE_PP3             =  8,
++      MALI_PROFILING_EVENT_DATA_CORE_PP4             =  9,
++      MALI_PROFILING_EVENT_DATA_CORE_PP5             = 10,
++      MALI_PROFILING_EVENT_DATA_CORE_PP6             = 11,
++      MALI_PROFILING_EVENT_DATA_CORE_PP7             = 12,
++} cinstr_profiling_event_data_core_t;
++
++#define MALI_PROFILING_MAKE_EVENT_DATA_CORE_GP(num) (MALI_PROFILING_EVENT_DATA_CORE_GP0 + (num))
++#define MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(num) (MALI_PROFILING_EVENT_DATA_CORE_PP0 + (num))
++
++
++#endif /*_MALI_UTGARD_PROFILING_EVENTS_H_*/
+diff --git a/drivers/gpu/arm/mali400/mali/include/linux/mali/mali_utgard_uk_types.h b/drivers/gpu/arm/mali400/mali/include/linux/mali/mali_utgard_uk_types.h
+new file mode 100644
+index 0000000..9ce6d23
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/include/linux/mali/mali_utgard_uk_types.h
+@@ -0,0 +1,1132 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_uk_types.h
++ * Defines the types and constants used in the user-kernel interface
++ */
++
++#ifndef __MALI_UTGARD_UK_TYPES_H__
++#define __MALI_UTGARD_UK_TYPES_H__
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif
++
++/**
++ * @addtogroup uddapi Unified Device Driver (UDD) APIs
++ *
++ * @{
++ */
++
++/**
++ * @addtogroup u_k_api UDD User/Kernel Interface (U/K) APIs
++ *
++ * @{
++ */
++
++/** @defgroup _mali_uk_core U/K Core
++ * @{ */
++
++/** Definition of subsystem numbers, to assist in creating a unique identifier
++ * for each U/K call.
++ *
++ * @see _mali_uk_functions */
++typedef enum
++{
++    _MALI_UK_CORE_SUBSYSTEM,      /**< Core Group of U/K calls */
++    _MALI_UK_MEMORY_SUBSYSTEM,    /**< Memory Group of U/K calls */
++    _MALI_UK_PP_SUBSYSTEM,        /**< Fragment Processor Group of U/K calls */
++    _MALI_UK_GP_SUBSYSTEM,        /**< Vertex Processor Group of U/K calls */
++      _MALI_UK_PROFILING_SUBSYSTEM, /**< Profiling Group of U/K calls */
++    _MALI_UK_PMM_SUBSYSTEM,       /**< Power Management Module Group of U/K calls */
++      _MALI_UK_VSYNC_SUBSYSTEM,     /**< VSYNC Group of U/K calls */
++} _mali_uk_subsystem_t;
++
++/** Within a function group each function has its unique sequence number
++ * to assist in creating a unique identifier for each U/K call.
++ *
++ * An ordered pair of numbers selected from
++ * ( \ref _mali_uk_subsystem_t,\ref  _mali_uk_functions) will uniquely identify the
++ * U/K call across all groups of functions, and all functions. */
++typedef enum
++{
++      /** Core functions */
++
++    _MALI_UK_OPEN                    = 0, /**< _mali_ukk_open() */
++    _MALI_UK_CLOSE,                       /**< _mali_ukk_close() */
++    _MALI_UK_WAIT_FOR_NOTIFICATION,       /**< _mali_ukk_wait_for_notification() */
++    _MALI_UK_GET_API_VERSION,             /**< _mali_ukk_get_api_version() */
++    _MALI_UK_POST_NOTIFICATION,           /**< _mali_ukk_post_notification() */
++      _MALI_UK_GET_USER_SETTING,       /**< _mali_ukk_get_user_setting() *//**< [out] */
++      _MALI_UK_GET_USER_SETTINGS,       /**< _mali_ukk_get_user_settings() *//**< [out] */
++      _MALI_UK_STREAM_CREATE,           /**< _mali_ukk_stream_create() */
++      _MALI_UK_FENCE_VALIDATE,          /**< _mali_ukk_fence_validate() */
++
++      /** Memory functions */
++
++    _MALI_UK_INIT_MEM                = 0,    /**< _mali_ukk_init_mem() */
++    _MALI_UK_TERM_MEM,                       /**< _mali_ukk_term_mem() */
++    _MALI_UK_GET_BIG_BLOCK,                  /**< _mali_ukk_get_big_block() */
++    _MALI_UK_FREE_BIG_BLOCK,                 /**< _mali_ukk_free_big_block() */
++    _MALI_UK_MAP_MEM,                        /**< _mali_ukk_mem_mmap() */
++    _MALI_UK_UNMAP_MEM,                      /**< _mali_ukk_mem_munmap() */
++    _MALI_UK_QUERY_MMU_PAGE_TABLE_DUMP_SIZE, /**< _mali_ukk_mem_get_mmu_page_table_dump_size() */
++    _MALI_UK_DUMP_MMU_PAGE_TABLE,            /**< _mali_ukk_mem_dump_mmu_page_table() */
++    _MALI_UK_ATTACH_DMA_BUF,                 /**< _mali_ukk_attach_dma_buf() */
++    _MALI_UK_RELEASE_DMA_BUF,                /**< _mali_ukk_release_dma_buf() */
++    _MALI_UK_DMA_BUF_GET_SIZE,               /**< _mali_ukk_dma_buf_get_size() */
++    _MALI_UK_ATTACH_UMP_MEM,                 /**< _mali_ukk_attach_ump_mem() */
++    _MALI_UK_RELEASE_UMP_MEM,                /**< _mali_ukk_release_ump_mem() */
++    _MALI_UK_MAP_EXT_MEM,                    /**< _mali_uku_map_external_mem() */
++    _MALI_UK_UNMAP_EXT_MEM,                  /**< _mali_uku_unmap_external_mem() */
++    _MALI_UK_VA_TO_MALI_PA,                  /**< _mali_uku_va_to_mali_pa() */
++
++    /** Common functions for each core */
++
++    _MALI_UK_START_JOB           = 0,     /**< Start a Fragment/Vertex Processor Job on a core */
++    _MALI_UK_GET_NUMBER_OF_CORES,         /**< Get the number of Fragment/Vertex Processor cores */
++    _MALI_UK_GET_CORE_VERSION,            /**< Get the Fragment/Vertex Processor version compatible with all cores */
++
++    /** Fragment Processor Functions  */
++
++    _MALI_UK_PP_START_JOB            = _MALI_UK_START_JOB,            /**< _mali_ukk_pp_start_job() */
++    _MALI_UK_GET_PP_NUMBER_OF_CORES  = _MALI_UK_GET_NUMBER_OF_CORES,  /**< _mali_ukk_get_pp_number_of_cores() */
++    _MALI_UK_GET_PP_CORE_VERSION     = _MALI_UK_GET_CORE_VERSION,     /**< _mali_ukk_get_pp_core_version() */
++    _MALI_UK_PP_DISABLE_WB,                                           /**< _mali_ukk_pp_job_disable_wb() */
++
++    /** Vertex Processor Functions  */
++
++    _MALI_UK_GP_START_JOB            = _MALI_UK_START_JOB,            /**< _mali_ukk_gp_start_job() */
++    _MALI_UK_GET_GP_NUMBER_OF_CORES  = _MALI_UK_GET_NUMBER_OF_CORES,  /**< _mali_ukk_get_gp_number_of_cores() */
++    _MALI_UK_GET_GP_CORE_VERSION     = _MALI_UK_GET_CORE_VERSION,     /**< _mali_ukk_get_gp_core_version() */
++    _MALI_UK_GP_SUSPEND_RESPONSE,                                     /**< _mali_ukk_gp_suspend_response() */
++
++      /** Profiling functions */
++
++      _MALI_UK_PROFILING_START         = 0, /**< __mali_uku_profiling_start() */
++      _MALI_UK_PROFILING_ADD_EVENT,         /**< __mali_uku_profiling_add_event() */
++      _MALI_UK_PROFILING_STOP,              /**< __mali_uku_profiling_stop() */
++      _MALI_UK_PROFILING_GET_EVENT,         /**< __mali_uku_profiling_get_event() */
++      _MALI_UK_PROFILING_CLEAR,             /**< __mali_uku_profiling_clear() */
++      _MALI_UK_PROFILING_GET_CONFIG,        /**< __mali_uku_profiling_get_config() */
++      _MALI_UK_PROFILING_REPORT_SW_COUNTERS,/**< __mali_uku_profiling_report_sw_counters() */
++
++      /** VSYNC reporting fuctions */
++      _MALI_UK_VSYNC_EVENT_REPORT      = 0, /**< _mali_ukk_vsync_event_report() */
++
++} _mali_uk_functions;
++
++/** @brief Get the size necessary for system info
++ *
++ * @see _mali_ukk_get_system_info_size()
++ */
++typedef struct
++{
++    void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      u32 size;                       /**< [out] size of buffer necessary to hold system information data, in bytes */
++} _mali_uk_get_system_info_size_s;
++
++
++/** @defgroup _mali_uk_getsysteminfo U/K Get System Info
++ * @{ */
++
++/**
++ * Type definition for the core version number.
++ * Used when returning the version number read from a core
++ *
++ * Its format is that of the 32-bit Version register for a particular core.
++ * Refer to the "Mali200 and MaliGP2 3D Graphics Processor Technical Reference
++ * Manual", ARM DDI 0415C, for more information.
++ */
++typedef u32 _mali_core_version;
++
++/**
++ * Enum values for the different modes the driver can be put in.
++ * Normal is the default mode. The driver then uses a job queue and takes job objects from the clients.
++ * Job completion is reported using the _mali_ukk_wait_for_notification call.
++ * The driver blocks this io command until a job has completed or failed or a timeout occurs.
++ *
++ * The 'raw' mode is reserved for future expansion.
++ */
++typedef enum _mali_driver_mode
++{
++      _MALI_DRIVER_MODE_RAW = 1,    /**< Reserved for future expansion */
++      _MALI_DRIVER_MODE_NORMAL = 2  /**< Normal mode of operation */
++} _mali_driver_mode;
++
++/** @brief List of possible cores
++ *
++ * add new entries to the end of this enum */
++typedef enum _mali_core_type
++{
++      _MALI_GP2 = 2,                /**< MaliGP2 Programmable Vertex Processor */
++      _MALI_200 = 5,                /**< Mali200 Programmable Fragment Processor */
++      _MALI_400_GP = 6,             /**< Mali400 Programmable Vertex Processor */
++      _MALI_400_PP = 7,             /**< Mali400 Programmable Fragment Processor */
++      /* insert new core here, do NOT alter the existing values */
++} _mali_core_type;
++
++
++/** @brief Capabilities of Memory Banks
++ *
++ * These may be used to restrict memory banks for certain uses. They may be
++ * used when access is not possible (e.g. Bus does not support access to it)
++ * or when access is possible but not desired (e.g. Access is slow).
++ *
++ * In the case of 'possible but not desired', there is no way of specifying
++ * the flags as an optimization hint, so that the memory could be used as a
++ * last resort.
++ *
++ * @see _mali_mem_info
++ */
++typedef enum _mali_bus_usage
++{
++
++      _MALI_PP_READABLE   = (1<<0),  /** Readable by the Fragment Processor */
++      _MALI_PP_WRITEABLE  = (1<<1),  /** Writeable by the Fragment Processor */
++      _MALI_GP_READABLE   = (1<<2),  /** Readable by the Vertex Processor */
++      _MALI_GP_WRITEABLE  = (1<<3),  /** Writeable by the Vertex Processor */
++      _MALI_CPU_READABLE  = (1<<4),  /** Readable by the CPU */
++      _MALI_CPU_WRITEABLE = (1<<5),  /** Writeable by the CPU */
++      _MALI_GP_L2_ALLOC   = (1<<6),  /** GP allocate mali L2 cache lines*/
++      _MALI_MMU_READABLE  = _MALI_PP_READABLE | _MALI_GP_READABLE,   /** Readable by the MMU (including all cores behind it) */
++      _MALI_MMU_WRITEABLE = _MALI_PP_WRITEABLE | _MALI_GP_WRITEABLE, /** Writeable by the MMU (including all cores behind it) */
++} _mali_bus_usage;
++
++typedef enum mali_memory_cache_settings
++{
++      MALI_CACHE_STANDARD                     = 0,
++      MALI_CACHE_GP_READ_ALLOCATE     = 1,
++} mali_memory_cache_settings ;
++
++
++/** @brief Information about the Mali Memory system
++ *
++ * Information is stored in a linked list, which is stored entirely in the
++ * buffer pointed to by the system_info member of the
++ * _mali_uk_get_system_info_s arguments provided to _mali_ukk_get_system_info()
++ *
++ * Each element of the linked list describes a single Mali Memory bank.
++ * Each allocation can only come from one bank, and will not cross multiple
++ * banks.
++ *
++ * On Mali-MMU systems, there is only one bank, which describes the maximum
++ * possible address range that could be allocated (which may be much less than
++ * the available physical memory)
++ *
++ * The flags member describes the capabilities of the memory. It is an error
++ * to attempt to build a job for a particular core (PP or GP) when the memory
++ * regions used do not have the capabilities for supporting that core. This
++ * would result in a job abort from the Device Driver.
++ *
++ * For example, it is correct to build a PP job where read-only data structures
++ * are taken from a memory with _MALI_PP_READABLE set and
++ * _MALI_PP_WRITEABLE clear, and a framebuffer with  _MALI_PP_WRITEABLE set and
++ * _MALI_PP_READABLE clear. However, it would be incorrect to use a framebuffer
++ * where _MALI_PP_WRITEABLE is clear.
++ */
++typedef struct _mali_mem_info
++{
++      u32 size;                     /**< Size of the memory bank in bytes */
++      _mali_bus_usage flags;        /**< Capabilitiy flags of the memory */
++      u32 maximum_order_supported;  /**< log2 supported size */
++      u32 identifier;               /* mali_memory_cache_settings cache_settings; */
++      struct _mali_mem_info * next; /**< Next List Link */
++} _mali_mem_info;
++
++
++
++/** @} */ /* end group _mali_uk_core */
++
++
++/** @defgroup _mali_uk_gp U/K Vertex Processor
++ * @{ */
++
++/** @defgroup _mali_uk_gp_suspend_response_s Vertex Processor Suspend Response
++ * @{ */
++
++/** @brief Arguments for _mali_ukk_gp_suspend_response()
++ *
++ * When _mali_wait_for_notification() receives notification that a
++ * Vertex Processor job was suspended, you need to send a response to indicate
++ * what needs to happen with this job. You can either abort or resume the job.
++ *
++ * - set @c code to indicate response code. This is either @c _MALIGP_JOB_ABORT or
++ * @c _MALIGP_JOB_RESUME_WITH_NEW_HEAP to indicate you will provide a new heap
++ * for the job that will resolve the out of memory condition for the job.
++ * - copy the @c cookie value from the @c _mali_uk_gp_job_suspended_s notification;
++ * this is an identifier for the suspended job
++ * - set @c arguments[0] and @c arguments[1] to zero if you abort the job. If
++ * you resume it, @c argument[0] should specify the Mali start address for the new
++ * heap and @c argument[1] the Mali end address of the heap.
++ * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open()
++ *
++ */
++typedef enum _maligp_job_suspended_response_code
++{
++      _MALIGP_JOB_ABORT,                  /**< Abort the Vertex Processor job */
++      _MALIGP_JOB_RESUME_WITH_NEW_HEAP    /**< Resume the Vertex Processor job with a new heap */
++} _maligp_job_suspended_response_code;
++
++typedef struct
++{
++    void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      u32 cookie;                     /**< [in] cookie from the _mali_uk_gp_job_suspended_s notification */
++      _maligp_job_suspended_response_code code; /**< [in] abort or resume response code, see \ref _maligp_job_suspended_response_code */
++      u32 arguments[2];               /**< [in] 0 when aborting a job. When resuming a job, the Mali start and end address for a new heap to resume the job with */
++} _mali_uk_gp_suspend_response_s;
++
++/** @} */ /* end group _mali_uk_gp_suspend_response_s */
++
++/** @defgroup _mali_uk_gpstartjob_s Vertex Processor Start Job
++ * @{ */
++
++/** @brief Status indicating the result of starting a Vertex or Fragment processor job */
++typedef enum
++{
++    _MALI_UK_START_JOB_STARTED,                         /**< Job started */
++    _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE           /**< Job could not be started at this time. Try starting the job again */
++} _mali_uk_start_job_status;
++
++/** @brief Status indicating the result of the execution of a Vertex or Fragment processor job  */
++
++typedef enum
++{
++      _MALI_UK_JOB_STATUS_END_SUCCESS         = 1<<(16+0),
++      _MALI_UK_JOB_STATUS_END_OOM             = 1<<(16+1),
++      _MALI_UK_JOB_STATUS_END_ABORT           = 1<<(16+2),
++      _MALI_UK_JOB_STATUS_END_TIMEOUT_SW      = 1<<(16+3),
++      _MALI_UK_JOB_STATUS_END_HANG            = 1<<(16+4),
++      _MALI_UK_JOB_STATUS_END_SEG_FAULT       = 1<<(16+5),
++      _MALI_UK_JOB_STATUS_END_ILLEGAL_JOB     = 1<<(16+6),
++      _MALI_UK_JOB_STATUS_END_UNKNOWN_ERR     = 1<<(16+7),
++      _MALI_UK_JOB_STATUS_END_SHUTDOWN        = 1<<(16+8),
++      _MALI_UK_JOB_STATUS_END_SYSTEM_UNUSABLE = 1<<(16+9)
++} _mali_uk_job_status;
++
++#define MALIGP2_NUM_REGS_FRAME (6)
++
++/** @brief Arguments for _mali_ukk_gp_start_job()
++ *
++ * To start a Vertex Processor job
++ * - associate the request with a reference to a @c mali_gp_job_info by setting
++ * user_job_ptr to the address of the @c mali_gp_job_info of the job.
++ * - set @c priority to the priority of the @c mali_gp_job_info
++ * - specify a timeout for the job by setting @c watchdog_msecs to the number of
++ * milliseconds the job is allowed to run. Specifying a value of 0 selects the
++ * default timeout in use by the device driver.
++ * - copy the frame registers from the @c mali_gp_job_info into @c frame_registers.
++ * - set the @c perf_counter_flag, @c perf_counter_src0 and @c perf_counter_src1 to zero
++ * for a non-instrumented build. For an instrumented build you can use up
++ * to two performance counters. Set the corresponding bit in @c perf_counter_flag
++ * to enable them. @c perf_counter_src0 and @c perf_counter_src1 specify
++ * the source of what needs to get counted (e.g. number of vertex loader
++ * cache hits). For source id values, see ARM DDI0415A, Table 3-60.
++ * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open()
++ *
++ * When @c _mali_ukk_gp_start_job() returns @c _MALI_OSK_ERR_OK, status contains the
++ * result of the request (see \ref _mali_uk_start_job_status). If the job could
++ * not get started (@c _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE) it should be
++ * tried again.
++ *
++ * After the job has started, @c _mali_wait_for_notification() will be notified
++ * that the job finished or got suspended. It may get suspended due to
++ * resource shortage. If it finished (see _mali_ukk_wait_for_notification())
++ * the notification will contain a @c _mali_uk_gp_job_finished_s result. If
++ * it got suspended the notification will contain a @c _mali_uk_gp_job_suspended_s
++ * result.
++ *
++ * The @c _mali_uk_gp_job_finished_s contains the job status (see \ref _mali_uk_job_status),
++ * the number of milliseconds the job took to render, and values of core registers
++ * when the job finished (irq status, performance counters, renderer list
++ * address). A job has finished succesfully when its status is
++ * @c _MALI_UK_JOB_STATUS_FINISHED. If the hardware detected a timeout while rendering
++ * the job, or software detected the job is taking more than watchdog_msecs to
++ * complete, the status will indicate @c _MALI_UK_JOB_STATUS_HANG.
++ * If the hardware detected a bus error while accessing memory associated with the
++ * job, status will indicate @c _MALI_UK_JOB_STATUS_SEG_FAULT.
++ * status will indicate @c _MALI_UK_JOB_STATUS_NOT_STARTED if the driver had to
++ * stop the job but the job didn't start on the hardware yet, e.g. when the
++ * driver shutdown.
++ *
++ * In case the job got suspended, @c _mali_uk_gp_job_suspended_s contains
++ * the @c user_job_ptr identifier used to start the job with, the @c reason
++ * why the job stalled (see \ref _maligp_job_suspended_reason) and a @c cookie
++ * to identify the core on which the job stalled.  This @c cookie will be needed
++ * when responding to this nofication by means of _mali_ukk_gp_suspend_response().
++ * (see _mali_ukk_gp_suspend_response()). The response is either to abort or
++ * resume the job. If the job got suspended due to an out of memory condition
++ * you may be able to resolve this by providing more memory and resuming the job.
++ *
++ */
++typedef struct
++{
++    void *ctx;                          /**< [in,out] user-kernel context (trashed on output) */
++    u32 user_job_ptr;                   /**< [in] identifier for the job in user space, a @c mali_gp_job_info* */
++    u32 priority;                       /**< [in] job priority. A lower number means higher priority */
++    u32 frame_registers[MALIGP2_NUM_REGS_FRAME]; /**< [in] core specific registers associated with this job */
++    u32 perf_counter_flag;              /**< [in] bitmask indicating which performance counters to enable, see \ref _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE and related macro definitions */
++    u32 perf_counter_src0;              /**< [in] source id for performance counter 0 (see ARM DDI0415A, Table 3-60) */
++    u32 perf_counter_src1;              /**< [in] source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */
++      u32 frame_builder_id;               /**< [in] id of the originating frame builder */
++      u32 flush_id;                       /**< [in] flush id within the originating frame builder */
++} _mali_uk_gp_start_job_s;
++
++#define _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE (1<<0) /**< Enable performance counter SRC0 for a job */
++#define _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE (1<<1) /**< Enable performance counter SRC1 for a job */
++
++/** @} */ /* end group _mali_uk_gpstartjob_s */
++
++typedef struct
++{
++    u32 user_job_ptr;               /**< [out] identifier for the job in user space */
++    _mali_uk_job_status status;     /**< [out] status of finished job */
++    u32 heap_current_addr;          /**< [out] value of the GP PLB PL heap start address register */
++    u32 perf_counter0;              /**< [out] value of perfomance counter 0 (see ARM DDI0415A) */
++    u32 perf_counter1;              /**< [out] value of perfomance counter 1 (see ARM DDI0415A) */
++} _mali_uk_gp_job_finished_s;
++
++typedef enum _maligp_job_suspended_reason
++{
++      _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY  /**< Polygon list builder unit (PLBU) has run out of memory */
++} _maligp_job_suspended_reason;
++
++typedef struct
++{
++      u32 user_job_ptr;                    /**< [out] identifier for the job in user space */
++      _maligp_job_suspended_reason reason; /**< [out] reason why the job stalled */
++      u32 cookie;                          /**< [out] identifier for the core in kernel space on which the job stalled */
++} _mali_uk_gp_job_suspended_s;
++
++/** @} */ /* end group _mali_uk_gp */
++
++
++/** @defgroup _mali_uk_pp U/K Fragment Processor
++ * @{ */
++
++#define _MALI_PP_MAX_SUB_JOBS 8
++
++#define _MALI_PP_MAX_FRAME_REGISTERS ((0x058/4)+1)
++
++#define _MALI_PP_MAX_WB_REGISTERS ((0x02C/4)+1)
++
++#define _MALI_DLBU_MAX_REGISTERS 4
++
++/** Flag for _mali_uk_pp_start_job_s */
++#define _MALI_PP_JOB_FLAG_NO_NOTIFICATION (1<<0)
++#define _MALI_PP_JOB_FLAG_BARRIER         (1<<1)
++#define _MALI_PP_JOB_FLAG_FENCE           (1<<2)
++
++/** @defgroup _mali_uk_ppstartjob_s Fragment Processor Start Job
++ * @{ */
++
++/** @brief Arguments for _mali_ukk_pp_start_job()
++ *
++ * To start a Fragment Processor job
++ * - associate the request with a reference to a mali_pp_job by setting
++ * @c user_job_ptr to the address of the @c mali_pp_job of the job.
++ * - set @c priority to the priority of the mali_pp_job
++ * - specify a timeout for the job by setting @c watchdog_msecs to the number of
++ * milliseconds the job is allowed to run. Specifying a value of 0 selects the
++ * default timeout in use by the device driver.
++ * - copy the frame registers from the @c mali_pp_job into @c frame_registers.
++ * For MALI200 you also need to copy the write back 0,1 and 2 registers.
++ * - set the @c perf_counter_flag, @c perf_counter_src0 and @c perf_counter_src1 to zero
++ * for a non-instrumented build. For an instrumented build you can use up
++ * to two performance counters. Set the corresponding bit in @c perf_counter_flag
++ * to enable them. @c perf_counter_src0 and @c perf_counter_src1 specify
++ * the source of what needs to get counted (e.g. number of vertex loader
++ * cache hits). For source id values, see ARM DDI0415A, Table 3-60.
++ * - pass in the user-kernel context in @c ctx that was returned from _mali_ukk_open()
++ *
++ * When _mali_ukk_pp_start_job() returns @c _MALI_OSK_ERR_OK, @c status contains the
++ * result of the request (see \ref _mali_uk_start_job_status). If the job could
++ * not get started (@c _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE) it should be
++ * tried again.
++ *
++ * After the job has started, _mali_wait_for_notification() will be notified
++ * when the job finished. The notification will contain a
++ * @c _mali_uk_pp_job_finished_s result. It contains the @c user_job_ptr
++ * identifier used to start the job with, the job @c status (see \ref _mali_uk_job_status),
++ * the number of milliseconds the job took to render, and values of core registers
++ * when the job finished (irq status, performance counters, renderer list
++ * address). A job has finished succesfully when its status is
++ * @c _MALI_UK_JOB_STATUS_FINISHED. If the hardware detected a timeout while rendering
++ * the job, or software detected the job is taking more than @c watchdog_msecs to
++ * complete, the status will indicate @c _MALI_UK_JOB_STATUS_HANG.
++ * If the hardware detected a bus error while accessing memory associated with the
++ * job, status will indicate @c _MALI_UK_JOB_STATUS_SEG_FAULT.
++ * status will indicate @c _MALI_UK_JOB_STATUS_NOT_STARTED if the driver had to
++ * stop the job but the job didn't start on the hardware yet, e.g. when the
++ * driver shutdown.
++ *
++ */
++typedef struct
++{
++    void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++    u32 user_job_ptr;               /**< [in] identifier for the job in user space */
++    u32 priority;                   /**< [in] job priority. A lower number means higher priority */
++    u32 frame_registers[_MALI_PP_MAX_FRAME_REGISTERS];         /**< [in] core specific registers associated with first sub job, see ARM DDI0415A */
++    u32 frame_registers_addr_frame[_MALI_PP_MAX_SUB_JOBS - 1]; /**< [in] ADDR_FRAME registers for sub job 1-7 */
++    u32 frame_registers_addr_stack[_MALI_PP_MAX_SUB_JOBS - 1]; /**< [in] ADDR_STACK registers for sub job 1-7 */
++    u32 wb0_registers[_MALI_PP_MAX_WB_REGISTERS];
++    u32 wb1_registers[_MALI_PP_MAX_WB_REGISTERS];
++    u32 wb2_registers[_MALI_PP_MAX_WB_REGISTERS];
++      u32 dlbu_registers[_MALI_DLBU_MAX_REGISTERS]; /**< [in] Dynamic load balancing unit registers */
++      u32 num_cores;                      /**< [in] Number of cores to set up (valid range: 1-4) */
++    u32 perf_counter_flag;              /**< [in] bitmask indicating which performance counters to enable, see \ref _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE and related macro definitions */
++    u32 perf_counter_src0;              /**< [in] source id for performance counter 0 (see ARM DDI0415A, Table 3-60) */
++    u32 perf_counter_src1;              /**< [in] source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */
++      u32 frame_builder_id;               /**< [in] id of the originating frame builder */
++      u32 flush_id;                       /**< [in] flush id within the originating frame builder */
++      u32 flags;                          /**< [in] See _MALI_PP_JOB_FLAG_* for a list of avaiable flags */
++      s32 fence;                          /**< [in,out] Fence to wait on / fence that will be signalled on job completion, if _MALI_PP_JOB_FLAG_FENCE is set */
++      s32 stream;                         /**< [in] Steam identifier */
++} _mali_uk_pp_start_job_s;
++/** @} */ /* end group _mali_uk_ppstartjob_s */
++
++typedef struct
++{
++    u32 user_job_ptr;                          /**< [out] identifier for the job in user space */
++    _mali_uk_job_status status;                /**< [out] status of finished job */
++    u32 perf_counter0[_MALI_PP_MAX_SUB_JOBS];  /**< [out] value of perfomance counter 0 (see ARM DDI0415A), one for each sub job */
++    u32 perf_counter1[_MALI_PP_MAX_SUB_JOBS];  /**< [out] value of perfomance counter 1 (see ARM DDI0415A), one for each sub job */
++} _mali_uk_pp_job_finished_s;
++
++/**
++ * Flags to indicate write-back units
++ */
++typedef enum
++{
++      _MALI_UK_PP_JOB_WB0 = 1,
++      _MALI_UK_PP_JOB_WB1 = 2,
++      _MALI_UK_PP_JOB_WB2 = 4,
++} _mali_uk_pp_job_wbx_flag;
++
++typedef struct
++{
++    void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++    u32 fb_id;                      /**< [in] Frame builder ID of job to disable WB units for */
++    u32 flush_id;                   /**< [in] Flush ID of job to disable WB units for */
++    _mali_uk_pp_job_wbx_flag wbx;   /**< [in] write-back units to disable */
++} _mali_uk_pp_disable_wb_s;
++
++
++/** @} */ /* end group _mali_uk_pp */
++
++
++/** @addtogroup _mali_uk_core U/K Core
++ * @{ */
++
++/** @defgroup _mali_uk_waitfornotification_s Wait For Notification
++ * @{ */
++
++/** @brief Notification type encodings
++ *
++ * Each Notification type is an ordered pair of (subsystem,id), and is unique.
++ *
++ * The encoding of subsystem,id into a 32-bit word is:
++ * encoding = (( subsystem << _MALI_NOTIFICATION_SUBSYSTEM_SHIFT ) & _MALI_NOTIFICATION_SUBSYSTEM_MASK)
++ *            | (( id <<  _MALI_NOTIFICATION_ID_SHIFT ) & _MALI_NOTIFICATION_ID_MASK)
++ *
++ * @see _mali_uk_wait_for_notification_s
++ */
++typedef enum
++{
++      /** core notifications */
++
++      _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS =  (_MALI_UK_CORE_SUBSYSTEM << 16) | 0x20,
++      _MALI_NOTIFICATION_APPLICATION_QUIT =           (_MALI_UK_CORE_SUBSYSTEM << 16) | 0x40,
++      _MALI_NOTIFICATION_SETTINGS_CHANGED =           (_MALI_UK_CORE_SUBSYSTEM << 16) | 0x80,
++
++      /** Fragment Processor notifications */
++
++      _MALI_NOTIFICATION_PP_FINISHED =                (_MALI_UK_PP_SUBSYSTEM << 16) | 0x10,
++
++      /** Vertex Processor notifications */
++
++      _MALI_NOTIFICATION_GP_FINISHED =                (_MALI_UK_GP_SUBSYSTEM << 16) | 0x10,
++      _MALI_NOTIFICATION_GP_STALLED =                 (_MALI_UK_GP_SUBSYSTEM << 16) | 0x20,
++
++} _mali_uk_notification_type;
++
++/** to assist in splitting up 32-bit notification value in subsystem and id value */
++#define _MALI_NOTIFICATION_SUBSYSTEM_MASK 0xFFFF0000
++#define _MALI_NOTIFICATION_SUBSYSTEM_SHIFT 16
++#define _MALI_NOTIFICATION_ID_MASK 0x0000FFFF
++#define _MALI_NOTIFICATION_ID_SHIFT 0
++
++
++/** @brief Enumeration of possible settings which match mali_setting_t in user space
++ *
++ *
++ */
++typedef enum
++{
++      _MALI_UK_USER_SETTING_SW_EVENTS_ENABLE = 0,
++      _MALI_UK_USER_SETTING_COLORBUFFER_CAPTURE_ENABLED,
++      _MALI_UK_USER_SETTING_DEPTHBUFFER_CAPTURE_ENABLED,
++      _MALI_UK_USER_SETTING_STENCILBUFFER_CAPTURE_ENABLED,
++      _MALI_UK_USER_SETTING_PER_TILE_COUNTERS_CAPTURE_ENABLED,
++      _MALI_UK_USER_SETTING_BUFFER_CAPTURE_COMPOSITOR,
++      _MALI_UK_USER_SETTING_BUFFER_CAPTURE_WINDOW,
++      _MALI_UK_USER_SETTING_BUFFER_CAPTURE_OTHER,
++      _MALI_UK_USER_SETTING_BUFFER_CAPTURE_N_FRAMES,
++      _MALI_UK_USER_SETTING_BUFFER_CAPTURE_RESIZE_FACTOR,
++      _MALI_UK_USER_SETTING_SW_COUNTER_ENABLED,
++      _MALI_UK_USER_SETTING_MAX,
++} _mali_uk_user_setting_t;
++
++/* See mali_user_settings_db.c */
++extern const char *_mali_uk_user_setting_descriptions[];
++#define _MALI_UK_USER_SETTING_DESCRIPTIONS \
++{                                           \
++      "sw_events_enable",                 \
++      "colorbuffer_capture_enable",       \
++      "depthbuffer_capture_enable",       \
++      "stencilbuffer_capture_enable",     \
++      "per_tile_counters_enable",         \
++      "buffer_capture_compositor",        \
++      "buffer_capture_window",            \
++      "buffer_capture_other",             \
++      "buffer_capture_n_frames",          \
++      "buffer_capture_resize_factor",     \
++      "sw_counters_enable",               \
++};
++
++/** @brief struct to hold the value to a particular setting as seen in the kernel space
++ */
++typedef struct
++{
++      _mali_uk_user_setting_t setting;
++      u32 value;
++} _mali_uk_settings_changed_s;
++
++/** @brief Arguments for _mali_ukk_wait_for_notification()
++ *
++ * On successful return from _mali_ukk_wait_for_notification(), the members of
++ * this structure will indicate the reason for notification.
++ *
++ * Specifically, the source of the notification can be identified by the
++ * subsystem and id fields of the mali_uk_notification_type in the code.type
++ * member. The type member is encoded in a way to divide up the types into a
++ * subsystem field, and a per-subsystem ID field. See
++ * _mali_uk_notification_type for more information.
++ *
++ * Interpreting the data union member depends on the notification type:
++ *
++ * - type == _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS
++ *     - The kernel side is shutting down. No further
++ * _mali_uk_wait_for_notification() calls should be made.
++ *     - In this case, the value of the data union member is undefined.
++ *     - This is used to indicate to the user space client that it should close
++ * the connection to the Mali Device Driver.
++ * - type == _MALI_NOTIFICATION_PP_FINISHED
++ *    - The notification data is of type _mali_uk_pp_job_finished_s. It contains the user_job_ptr
++ * identifier used to start the job with, the job status, the number of milliseconds the job took to render,
++ * and values of core registers when the job finished (irq status, performance counters, renderer list
++ * address).
++ *    - A job has finished succesfully when its status member is _MALI_UK_JOB_STATUS_FINISHED.
++ *    - If the hardware detected a timeout while rendering the job, or software detected the job is
++ * taking more than watchdog_msecs (see _mali_ukk_pp_start_job()) to complete, the status member will
++ * indicate _MALI_UK_JOB_STATUS_HANG.
++ *    - If the hardware detected a bus error while accessing memory associated with the job, status will
++ * indicate _MALI_UK_JOB_STATUS_SEG_FAULT.
++ *    - Status will indicate MALI_UK_JOB_STATUS_NOT_STARTED if the driver had to stop the job but the job
++ * didn't start the hardware yet, e.g. when the driver closes.
++ * - type == _MALI_NOTIFICATION_GP_FINISHED
++ *     - The notification data is of type _mali_uk_gp_job_finished_s. The notification is similar to that of
++ * type == _MALI_NOTIFICATION_PP_FINISHED, except that several other GP core register values are returned.
++ * The status values have the same meaning for type == _MALI_NOTIFICATION_PP_FINISHED.
++ * - type == _MALI_NOTIFICATION_GP_STALLED
++ *     - The nofication data is of type _mali_uk_gp_job_suspended_s. It contains the user_job_ptr
++ * identifier used to start the job with, the reason why the job stalled and a cookie to identify the core on
++ * which the job stalled.
++ *     - The reason member of gp_job_suspended is set to _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY
++ * when the polygon list builder unit has run out of memory.
++ */
++typedef struct
++{
++      void *ctx;                       /**< [in,out] user-kernel context (trashed on output) */
++      _mali_uk_notification_type type; /**< [out] Type of notification available */
++      union
++      {
++              _mali_uk_gp_job_suspended_s gp_job_suspended;/**< [out] Notification data for _MALI_NOTIFICATION_GP_STALLED notification type */
++              _mali_uk_gp_job_finished_s  gp_job_finished; /**< [out] Notification data for _MALI_NOTIFICATION_GP_FINISHED notification type */
++              _mali_uk_pp_job_finished_s  pp_job_finished; /**< [out] Notification data for _MALI_NOTIFICATION_PP_FINISHED notification type */
++              _mali_uk_settings_changed_s setting_changed;/**< [out] Notification data for _MALI_NOTIFICAATION_SETTINGS_CHANGED notification type */
++      } data;
++} _mali_uk_wait_for_notification_s;
++
++/** @brief Arguments for _mali_ukk_post_notification()
++ *
++ * Posts the specified notification to the notification queue for this application.
++ * This is used to send a quit message to the callback thread.
++ */
++typedef struct
++{
++    void *ctx;                       /**< [in,out] user-kernel context (trashed on output) */
++      _mali_uk_notification_type type; /**< [in] Type of notification to post */
++} _mali_uk_post_notification_s;
++
++/** @} */ /* end group _mali_uk_waitfornotification_s */
++
++/** @defgroup _mali_uk_getapiversion_s Get API Version
++ * @{ */
++
++/** helpers for Device Driver API version handling */
++
++/** @brief Encode a version ID from a 16-bit input
++ *
++ * @note the input is assumed to be 16 bits. It must not exceed 16 bits. */
++#define _MAKE_VERSION_ID(x) (((x) << 16UL) | (x))
++
++/** @brief Check whether a 32-bit value is likely to be Device Driver API
++ * version ID. */
++#define _IS_VERSION_ID(x) (((x) & 0xFFFF) == (((x) >> 16UL) & 0xFFFF))
++
++/** @brief Decode a 16-bit version number from a 32-bit Device Driver API version
++ * ID */
++#define _GET_VERSION(x) (((x) >> 16UL) & 0xFFFF)
++
++/** @brief Determine whether two 32-bit encoded version IDs match */
++#define _IS_API_MATCH(x, y) (IS_VERSION_ID((x)) && IS_VERSION_ID((y)) && (GET_VERSION((x)) == GET_VERSION((y))))
++
++/**
++ * API version define.
++ * Indicates the version of the kernel API
++ * The version is a 16bit integer incremented on each API change.
++ * The 16bit integer is stored twice in a 32bit integer
++ * For example, for version 1 the value would be 0x00010001
++ */
++#define _MALI_API_VERSION 19
++#define _MALI_UK_API_VERSION _MAKE_VERSION_ID(_MALI_API_VERSION)
++
++/**
++ * The API version is a 16-bit integer stored in both the lower and upper 16-bits
++ * of a 32-bit value. The 16-bit API version value is incremented on each API
++ * change. Version 1 would be 0x00010001. Used in _mali_uk_get_api_version_s.
++ */
++typedef u32 _mali_uk_api_version;
++
++/** @brief Arguments for _mali_uk_get_api_version()
++ *
++ * The user-side interface version must be written into the version member,
++ * encoded using _MAKE_VERSION_ID(). It will be compared to the API version of
++ * the kernel-side interface.
++ *
++ * On successful return, the version member will be the API version of the
++ * kernel-side interface. _MALI_UK_API_VERSION macro defines the current version
++ * of the API.
++ *
++ * The compatible member must be checked to see if the version of the user-side
++ * interface is compatible with the kernel-side interface, since future versions
++ * of the interface may be backwards compatible.
++ */
++typedef struct
++{
++    void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      _mali_uk_api_version version;   /**< [in,out] API version of user-side interface. */
++      int compatible;                 /**< [out] @c 1 when @version is compatible, @c 0 otherwise */
++} _mali_uk_get_api_version_s;
++/** @} */ /* end group _mali_uk_getapiversion_s */
++
++/** @defgroup _mali_uk_get_user_settings_s Get user space settings */
++
++/** @brief struct to keep the matching values of the user space settings within certain context
++ *
++ * Each member of the settings array corresponds to a matching setting in the user space and its value is the value
++ * of that particular setting.
++ *
++ * All settings are given reference to the context pointed to by the ctx pointer.
++ *
++ */
++typedef struct
++{
++      void *ctx;                       /**< [in,out] user-kernel context (trashed on output) */
++      u32 settings[_MALI_UK_USER_SETTING_MAX]; /**< [out] The values for all settings */
++} _mali_uk_get_user_settings_s;
++
++/** @brief struct to hold the value of a particular setting from the user space within a given context
++ */
++typedef struct
++{
++      void *ctx;                       /**< [in,out] user-kernel context (trashed on output) */
++      _mali_uk_user_setting_t setting; /**< [in] setting to get */
++      u32 value;                       /**< [out] value of setting */
++} _mali_uk_get_user_setting_s;
++
++/** @} */ /* end group _mali_uk_core */
++
++
++/** @defgroup _mali_uk_memory U/K Memory
++ * @{ */
++
++/** @brief Arguments for _mali_ukk_init_mem(). */
++typedef struct
++{
++    void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      u32 mali_address_base;          /**< [out] start of MALI address space */
++      u32 memory_size;                /**< [out] total MALI address space available */
++} _mali_uk_init_mem_s;
++
++/** @brief Arguments for _mali_ukk_term_mem(). */
++typedef struct
++{
++    void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++} _mali_uk_term_mem_s;
++
++/** Flag for _mali_uk_map_external_mem_s, _mali_uk_attach_ump_mem_s and _mali_uk_attach_dma_buf_s */
++#define _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE (1<<0)
++
++typedef struct
++{
++    void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      u32 phys_addr;                  /**< [in] physical address */
++      u32 size;                       /**< [in] size */
++      u32 mali_address;               /**< [in] mali address to map the physical memory to */
++      u32 rights;                     /**< [in] rights necessary for accessing memory */
++      u32 flags;                      /**< [in] flags, see \ref _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE */
++      u32 cookie;                     /**< [out] identifier for mapped memory object in kernel space  */
++} _mali_uk_map_external_mem_s;
++
++typedef struct
++{
++    void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      u32 cookie;                     /**< [out] identifier for mapped memory object in kernel space  */
++} _mali_uk_unmap_external_mem_s;
++
++/** @note This is identical to _mali_uk_map_external_mem_s above, however phys_addr is replaced by memory descriptor */
++typedef struct
++{
++    void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      u32 mem_fd;                     /**< [in] Memory descriptor */
++      u32 size;                       /**< [in] size */
++      u32 mali_address;               /**< [in] mali address to map the physical memory to */
++      u32 rights;                     /**< [in] rights necessary for accessing memory */
++      u32 flags;                      /**< [in] flags, see \ref _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE */
++      u32 cookie;                     /**< [out] identifier for mapped memory object in kernel space  */
++} _mali_uk_attach_dma_buf_s;
++
++typedef struct
++{
++      void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      u32 mem_fd;                     /**< [in] Memory descriptor */
++      u32 size;                       /**< [out] size */
++} _mali_uk_dma_buf_get_size_s;
++
++typedef struct
++{
++    void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      u32 cookie;                     /**< [in] identifier for mapped memory object in kernel space  */
++} _mali_uk_release_dma_buf_s;
++
++/** @note This is identical to _mali_uk_map_external_mem_s above, however phys_addr is replaced by secure_id */
++typedef struct
++{
++    void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      u32 secure_id;                  /**< [in] secure id */
++      u32 size;                       /**< [in] size */
++      u32 mali_address;               /**< [in] mali address to map the physical memory to */
++      u32 rights;                     /**< [in] rights necessary for accessing memory */
++      u32 flags;                      /**< [in] flags, see \ref _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE */
++      u32 cookie;                     /**< [out] identifier for mapped memory object in kernel space  */
++} _mali_uk_attach_ump_mem_s;
++
++typedef struct
++{
++    void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      u32 cookie;                     /**< [in] identifier for mapped memory object in kernel space  */
++} _mali_uk_release_ump_mem_s;
++
++/** @brief Arguments for _mali_ukk_va_to_mali_pa()
++ *
++ * if size is zero or not a multiple of the system's page size, it will be
++ * rounded up to the next multiple of the page size. This will occur before
++ * any other use of the size parameter.
++ *
++ * if va is not PAGE_SIZE aligned, it will be rounded down to the next page
++ * boundary.
++ *
++ * The range (va) to ((u32)va)+(size-1) inclusive will be checked for physical
++ * contiguity.
++ *
++ * The implementor will check that the entire physical range is allowed to be mapped
++ * into user-space.
++ *
++ * Failure will occur if either of the above are not satisfied.
++ *
++ * Otherwise, the physical base address of the range is returned through pa,
++ * va is updated to be page aligned, and size is updated to be a non-zero
++ * multiple of the system's pagesize.
++ */
++typedef struct
++{
++      void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      void *va;                       /**< [in,out] Virtual address of the start of the range */
++      u32 pa;                         /**< [out] Physical base address of the range */
++      u32 size;                       /**< [in,out] Size of the range, in bytes. */
++} _mali_uk_va_to_mali_pa_s;
++
++
++typedef struct
++{
++    void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      u32 size;                       /**< [out] size of MMU page table information (registers + page tables) */
++} _mali_uk_query_mmu_page_table_dump_size_s;
++
++typedef struct
++{
++    void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      u32 size;                       /**< [in] size of buffer to receive mmu page table information */
++    void *buffer;                   /**< [in,out] buffer to receive mmu page table information */
++    u32 register_writes_size;       /**< [out] size of MMU register dump */
++      u32 *register_writes;           /**< [out] pointer within buffer where MMU register dump is stored */
++      u32 page_table_dump_size;       /**< [out] size of MMU page table dump */
++      u32 *page_table_dump;           /**< [out] pointer within buffer where MMU page table dump is stored */
++} _mali_uk_dump_mmu_page_table_s;
++
++/** @} */ /* end group _mali_uk_memory */
++
++
++/** @addtogroup _mali_uk_pp U/K Fragment Processor
++ * @{ */
++
++/** @brief Arguments for _mali_ukk_get_pp_number_of_cores()
++ *
++ * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open()
++ * - Upon successful return from _mali_ukk_get_pp_number_of_cores(), @c number_of_cores
++ * will contain the number of Fragment Processor cores in the system.
++ */
++typedef struct
++{
++    void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++    u32 number_of_cores;            /**< [out] number of Fragment Processor cores in the system */
++} _mali_uk_get_pp_number_of_cores_s;
++
++/** @brief Arguments for _mali_ukk_get_pp_core_version()
++ *
++ * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open()
++ * - Upon successful return from _mali_ukk_get_pp_core_version(), @c version contains
++ * the version that all Fragment Processor cores are compatible with.
++ */
++typedef struct
++{
++    void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++    _mali_core_version version;     /**< [out] version returned from core, see \ref _mali_core_version  */
++} _mali_uk_get_pp_core_version_s;
++
++/** @} */ /* end group _mali_uk_pp */
++
++
++/** @addtogroup _mali_uk_gp U/K Vertex Processor
++ * @{ */
++
++/** @brief Arguments for _mali_ukk_get_gp_number_of_cores()
++ *
++ * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open()
++ * - Upon successful return from _mali_ukk_get_gp_number_of_cores(), @c number_of_cores
++ * will contain the number of Vertex Processor cores in the system.
++ */
++typedef struct
++{
++    void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++    u32 number_of_cores;            /**< [out] number of Vertex Processor cores in the system */
++} _mali_uk_get_gp_number_of_cores_s;
++
++/** @brief Arguments for _mali_ukk_get_gp_core_version()
++ *
++ * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open()
++ * - Upon successful return from _mali_ukk_get_gp_core_version(), @c version contains
++ * the version that all Vertex Processor cores are compatible with.
++ */
++typedef struct
++{
++    void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++    _mali_core_version version;     /**< [out] version returned from core, see \ref _mali_core_version */
++} _mali_uk_get_gp_core_version_s;
++
++typedef struct
++{
++      void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      u32 limit;                      /**< [in,out] The desired limit for number of events to record on input, actual limit on output */
++} _mali_uk_profiling_start_s;
++
++typedef struct
++{
++      void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      u32 event_id;                   /**< [in] event id to register (see  enum mali_profiling_events for values) */
++      u32 data[5];                    /**< [in] event specific data */
++} _mali_uk_profiling_add_event_s;
++
++typedef struct
++{
++      void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      u32 count;                      /**< [out] The number of events sampled */
++} _mali_uk_profiling_stop_s;
++
++typedef struct
++{
++      void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      u32 index;                      /**< [in] which index to get (starting at zero) */
++      u64 timestamp;                  /**< [out] timestamp of event */
++      u32 event_id;                   /**< [out] event id of event (see  enum mali_profiling_events for values) */
++      u32 data[5];                    /**< [out] event specific data */
++} _mali_uk_profiling_get_event_s;
++
++typedef struct
++{
++      void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++} _mali_uk_profiling_clear_s;
++
++/** @} */ /* end group _mali_uk_gp */
++
++
++/** @addtogroup _mali_uk_memory U/K Memory
++ * @{ */
++
++/** @brief Arguments to _mali_ukk_mem_mmap()
++ *
++ * Use of the phys_addr member depends on whether the driver is compiled for
++ * Mali-MMU or nonMMU:
++ * - in the nonMMU case, this is the physical address of the memory as seen by
++ * the CPU (which may be a constant offset from that used by Mali)
++ * - in the MMU case, this is the Mali Virtual base address of the memory to
++ * allocate, and the particular physical pages used to back the memory are
++ * entirely determined by _mali_ukk_mem_mmap(). The details of the physical pages
++ * are not reported to user-space for security reasons.
++ *
++ * The cookie member must be stored for use later when freeing the memory by
++ * calling _mali_ukk_mem_munmap(). In the Mali-MMU case, the cookie is secure.
++ *
++ * The ukk_private word must be set to zero when calling from user-space. On
++ * Kernel-side, the  OS implementation of the U/K interface can use it to
++ * communicate data to the OS implementation of the OSK layer. In particular,
++ * _mali_ukk_get_big_block() directly calls _mali_ukk_mem_mmap directly, and
++ * will communicate its own ukk_private word through the ukk_private member
++ * here. The common code itself will not inspect or modify the ukk_private
++ * word, and so it may be safely used for whatever purposes necessary to
++ * integrate Mali Memory handling into the OS.
++ *
++ * The uku_private member is currently reserved for use by the user-side
++ * implementation of the U/K interface. Its value must be zero.
++ */
++typedef struct
++{
++      void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      void *mapping;                  /**< [out] Returns user-space virtual address for the mapping */
++      u32 size;                       /**< [in] Size of the requested mapping */
++      u32 phys_addr;                  /**< [in] Physical address - could be offset, depending on caller+callee convention */
++      u32 cookie;                     /**< [out] Returns a cookie for use in munmap calls */
++      void *uku_private;              /**< [in] User-side Private word used by U/K interface */
++      void *ukk_private;              /**< [in] Kernel-side Private word used by U/K interface */
++      mali_memory_cache_settings cache_settings; /**< [in] Option to set special cache flags, tuning L2 efficency */
++} _mali_uk_mem_mmap_s;
++
++/** @brief Arguments to _mali_ukk_mem_munmap()
++ *
++ * The cookie and mapping members must be that returned from the same previous
++ * call to _mali_ukk_mem_mmap(). The size member must correspond to cookie
++ * and mapping - that is, it must be the value originally supplied to a call to
++ * _mali_ukk_mem_mmap that returned the values of mapping and cookie.
++ *
++ * An error will be returned if an attempt is made to unmap only part of the
++ * originally obtained range, or to unmap more than was originally obtained.
++ */
++typedef struct
++{
++      void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      void *mapping;                  /**< [in] The mapping returned from mmap call */
++      u32 size;                       /**< [in] The size passed to mmap call */
++      u32 cookie;                     /**< [in] Cookie from mmap call */
++} _mali_uk_mem_munmap_s;
++/** @} */ /* end group _mali_uk_memory */
++
++/** @defgroup _mali_uk_vsync U/K VSYNC Wait Reporting Module
++ * @{ */
++
++/** @brief VSYNC events
++ *
++ * These events are reported when DDK starts to wait for vsync and when the
++ * vsync has occured and the DDK can continue on the next frame.
++ */
++typedef enum _mali_uk_vsync_event
++{
++      _MALI_UK_VSYNC_EVENT_BEGIN_WAIT = 0,
++      _MALI_UK_VSYNC_EVENT_END_WAIT
++} _mali_uk_vsync_event;
++
++/** @brief Arguments to _mali_ukk_vsync_event()
++ *
++ */
++typedef struct
++{
++      void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      _mali_uk_vsync_event event;     /**< [in] VSYNCH event type */
++} _mali_uk_vsync_event_report_s;
++
++/** @} */ /* end group _mali_uk_vsync */
++
++/** @defgroup _mali_uk_sw_counters_report U/K Software Counter Reporting
++ * @{ */
++
++/** @brief Software counter values
++ *
++ * Values recorded for each of the software counters during a single renderpass.
++ */
++typedef struct
++{
++      void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      u32* counters;                  /**< [in] The array of counter values */
++      u32  num_counters;              /**< [in] The number of elements in counters array */
++} _mali_uk_sw_counters_report_s;
++
++/** @} */ /* end group _mali_uk_sw_counters_report */
++
++/** @defgroup _mali_uk_stream U/K Mali stream module
++ * @{ */
++
++/** @brief Create stream
++ */
++typedef struct
++{
++      void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      int fd;                         /**< [out] file descriptor describing stream */
++} _mali_uk_stream_create_s;
++
++/** @brief Destroy stream
++*/
++typedef struct
++{
++      void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      int fd;                         /**< [in] file descriptor describing stream */
++} _mali_uk_stream_destroy_s;
++
++/** @brief Check fence validity
++ */
++typedef struct
++{
++      void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      int fd;                         /**< [in] file descriptor describing fence */
++} _mali_uk_fence_validate_s;
++
++/** @} */ /* end group _mali_uk_stream */
++
++/** @} */ /* end group u_k_api */
++
++/** @} */ /* end group uddapi */
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* __MALI_UTGARD_UK_TYPES_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/linux/license/gpl/mali_kernel_license.h b/drivers/gpu/arm/mali400/mali/linux/license/gpl/mali_kernel_license.h
+new file mode 100644
+index 0000000..bd4f9aa
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/license/gpl/mali_kernel_license.h
+@@ -0,0 +1,31 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_kernel_license.h
++ * Defines for the macro MODULE_LICENSE.
++ */
++
++#ifndef __MALI_KERNEL_LICENSE_H__
++#define __MALI_KERNEL_LICENSE_H__
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif
++
++#define MALI_KERNEL_LINUX_LICENSE     "GPL"
++#define MALI_LICENSE_IS_GPL 1
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* __MALI_KERNEL_LICENSE_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_dma_buf.c b/drivers/gpu/arm/mali400/mali/linux/mali_dma_buf.c
+new file mode 100644
+index 0000000..900c969
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_dma_buf.c
+@@ -0,0 +1,389 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include <linux/fs.h>    /* file system operations */
++#include <asm/uaccess.h>      /* user space access */
++#include <linux/dma-buf.h>
++#include <linux/scatterlist.h>
++#include <linux/rbtree.h>
++#include <linux/platform_device.h>
++
++#include "mali_ukk.h"
++#include "mali_osk.h"
++#include "mali_kernel_common.h"
++#include "mali_session.h"
++#include "mali_kernel_linux.h"
++
++#include "mali_kernel_memory_engine.h"
++#include "mali_memory.h"
++
++
++struct mali_dma_buf_attachment {
++      struct dma_buf *buf;
++      struct dma_buf_attachment *attachment;
++      struct sg_table *sgt;
++      _mali_osk_atomic_t ref;
++      struct rb_node rb_node;
++};
++
++static struct rb_root mali_dma_bufs = RB_ROOT;
++static DEFINE_SPINLOCK(mali_dma_bufs_lock);
++
++static inline struct mali_dma_buf_attachment *mali_dma_buf_lookup(struct rb_root *root, struct dma_buf *target)
++{
++      struct rb_node *node = root->rb_node;
++      struct mali_dma_buf_attachment *res;
++
++      spin_lock(&mali_dma_bufs_lock);
++      while (node)
++      {
++              res = rb_entry(node, struct mali_dma_buf_attachment, rb_node);
++
++              if (target < res->buf) node = node->rb_left;
++              else if (target > res->buf) node = node->rb_right;
++              else
++              {
++                      _mali_osk_atomic_inc(&res->ref);
++                      spin_unlock(&mali_dma_bufs_lock);
++                      return res;
++              }
++      }
++      spin_unlock(&mali_dma_bufs_lock);
++
++      return NULL;
++}
++
++static void mali_dma_buf_add(struct rb_root *root, struct mali_dma_buf_attachment *new)
++{
++      struct rb_node **node = &root->rb_node;
++      struct rb_node *parent = NULL;
++      struct mali_dma_buf_attachment *res;
++
++      spin_lock(&mali_dma_bufs_lock);
++      while (*node)
++      {
++              parent = *node;
++              res = rb_entry(*node, struct mali_dma_buf_attachment, rb_node);
++
++              if (new->buf < res->buf) node = &(*node)->rb_left;
++              else node = &(*node)->rb_right;
++      }
++
++      rb_link_node(&new->rb_node, parent, node);
++      rb_insert_color(&new->rb_node, &mali_dma_bufs);
++
++      spin_unlock(&mali_dma_bufs_lock);
++
++      return;
++}
++
++
++static void mali_dma_buf_release(void *ctx, void *handle)
++{
++      struct mali_dma_buf_attachment *mem;
++      u32 ref;
++
++      mem = (struct mali_dma_buf_attachment *)handle;
++
++      MALI_DEBUG_ASSERT_POINTER(mem);
++      MALI_DEBUG_ASSERT_POINTER(mem->attachment);
++      MALI_DEBUG_ASSERT_POINTER(mem->buf);
++
++      spin_lock(&mali_dma_bufs_lock);
++      ref = _mali_osk_atomic_dec_return(&mem->ref);
++
++      if (0 == ref)
++      {
++              rb_erase(&mem->rb_node, &mali_dma_bufs);
++              spin_unlock(&mali_dma_bufs_lock);
++
++              MALI_DEBUG_ASSERT(0 == _mali_osk_atomic_read(&mem->ref));
++
++              dma_buf_unmap_attachment(mem->attachment, mem->sgt, DMA_BIDIRECTIONAL);
++
++              dma_buf_detach(mem->buf, mem->attachment);
++              dma_buf_put(mem->buf);
++
++              _mali_osk_free(mem);
++      }
++      else
++      {
++              spin_unlock(&mali_dma_bufs_lock);
++      }
++}
++
++/* Callback from memory engine which will map into Mali virtual address space */
++static mali_physical_memory_allocation_result mali_dma_buf_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info)
++{
++      struct mali_session_data *session;
++      struct mali_page_directory *pagedir;
++      struct mali_dma_buf_attachment *mem;
++      struct scatterlist *sg;
++      int i;
++      u32 virt;
++
++      MALI_DEBUG_ASSERT_POINTER(ctx);
++      MALI_DEBUG_ASSERT_POINTER(engine);
++      MALI_DEBUG_ASSERT_POINTER(descriptor);
++      MALI_DEBUG_ASSERT_POINTER(offset);
++      MALI_DEBUG_ASSERT_POINTER(alloc_info);
++
++      /* Mapping dma-buf with an offset is not supported. */
++      MALI_DEBUG_ASSERT(0 == *offset);
++
++      virt = descriptor->mali_address;
++      session = (struct mali_session_data *)descriptor->mali_addr_mapping_info;
++      pagedir = mali_session_get_page_directory(session);
++
++      MALI_DEBUG_ASSERT_POINTER(session);
++
++      mem = (struct mali_dma_buf_attachment *)ctx;
++
++      MALI_DEBUG_ASSERT_POINTER(mem);
++
++      mem->sgt = dma_buf_map_attachment(mem->attachment, DMA_BIDIRECTIONAL);
++      if (IS_ERR_OR_NULL(mem->sgt))
++      {
++              MALI_PRINT_ERROR(("Failed to map dma-buf attachment\n"));
++              return MALI_MEM_ALLOC_INTERNAL_FAILURE;
++      }
++
++      for_each_sg(mem->sgt->sgl, sg, mem->sgt->nents, i)
++      {
++              u32 size = sg_dma_len(sg);
++              dma_addr_t phys = sg_dma_address(sg);
++
++              /* sg must be page aligned. */
++              MALI_DEBUG_ASSERT(0 == size % MALI_MMU_PAGE_SIZE);
++
++              mali_mmu_pagedir_update(pagedir, virt, phys, size, MALI_CACHE_STANDARD);
++
++              virt += size;
++              *offset += size;
++      }
++
++      if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE)
++      {
++              u32 guard_phys;
++              MALI_DEBUG_PRINT(7, ("Mapping in extra guard page\n"));
++
++              guard_phys = sg_dma_address(mem->sgt->sgl);
++              mali_mmu_pagedir_update(mali_session_get_page_directory(session), virt, guard_phys, MALI_MMU_PAGE_SIZE, MALI_CACHE_STANDARD);
++      }
++
++      MALI_DEBUG_ASSERT(*offset == descriptor->size);
++
++      alloc_info->ctx = NULL;
++      alloc_info->handle = mem;
++      alloc_info->next = NULL;
++      alloc_info->release = mali_dma_buf_release;
++
++      return MALI_MEM_ALLOC_FINISHED;
++}
++
++int mali_attach_dma_buf(struct mali_session_data *session, _mali_uk_attach_dma_buf_s __user *user_arg)
++{
++      mali_physical_memory_allocator external_memory_allocator;
++      struct dma_buf *buf;
++      struct mali_dma_buf_attachment *mem;
++      _mali_uk_attach_dma_buf_s args;
++      mali_memory_allocation *descriptor;
++      int md;
++      int fd;
++
++      /* Get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
++      if (0 != copy_from_user(&args, (void __user *)user_arg, sizeof(_mali_uk_attach_dma_buf_s)))
++      {
++              return -EFAULT;
++      }
++
++
++      fd = args.mem_fd;
++
++      buf = dma_buf_get(fd);
++      if (IS_ERR_OR_NULL(buf))
++      {
++              MALI_DEBUG_PRINT(2, ("Failed to get dma-buf from fd: %d\n", fd));
++              return PTR_RET(buf);
++      }
++
++      /* Currently, mapping of the full buffer are supported. */
++      if (args.size != buf->size)
++      {
++              MALI_DEBUG_PRINT(2, ("dma-buf size doesn't match mapping size.\n"));
++              dma_buf_put(buf);
++              return -EINVAL;
++      }
++
++
++      mem = mali_dma_buf_lookup(&mali_dma_bufs, buf);
++      if (NULL == mem)
++      {
++              /* dma-buf is not already attached to Mali */
++              mem = _mali_osk_calloc(1, sizeof(struct mali_dma_buf_attachment));
++              if (NULL == mem)
++              {
++                      MALI_PRINT_ERROR(("Failed to allocate dma-buf tracing struct\n"));
++                      dma_buf_put(buf);
++                      return -ENOMEM;
++              }
++              _mali_osk_atomic_init(&mem->ref, 1);
++              mem->buf = buf;
++
++              mem->attachment = dma_buf_attach(mem->buf, &mali_platform_device->dev);
++              if (NULL == mem->attachment)
++              {
++                      MALI_DEBUG_PRINT(2, ("Failed to attach to dma-buf %d\n", fd));
++                      dma_buf_put(mem->buf);
++                      _mali_osk_free(mem);
++                      return -EFAULT;
++              }
++
++              mali_dma_buf_add(&mali_dma_bufs, mem);
++      }
++      else
++      {
++              /* dma-buf is already attached to Mali */
++              /* Give back the reference we just took, mali_dma_buf_lookup grabbed a new reference for us. */
++              dma_buf_put(buf);
++      }
++
++      /* Map dma-buf into this session's page tables */
++
++      /* Set up Mali memory descriptor */
++      descriptor = _mali_osk_calloc(1, sizeof(mali_memory_allocation));
++      if (NULL == descriptor)
++      {
++              MALI_PRINT_ERROR(("Failed to allocate descriptor dma-buf %d\n", fd));
++              mali_dma_buf_release(NULL, mem);
++              return -ENOMEM;
++      }
++
++      descriptor->size = args.size;
++      descriptor->mapping = NULL;
++      descriptor->mali_address = args.mali_address;
++      descriptor->mali_addr_mapping_info = (void*)session;
++      descriptor->process_addr_mapping_info = NULL; /* do not map to process address space */
++      descriptor->lock = session->memory_lock;
++
++      if (args.flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE)
++      {
++              descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE;
++      }
++      _mali_osk_list_init( &descriptor->list );
++
++      /* Get descriptor mapping for memory. */
++      if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session->descriptor_mapping, descriptor, &md))
++      {
++              MALI_PRINT_ERROR(("Failed to create descriptor mapping for dma-buf %d\n", fd));
++              _mali_osk_free(descriptor);
++              mali_dma_buf_release(NULL, mem);
++              return -EFAULT;
++      }
++
++      external_memory_allocator.allocate = mali_dma_buf_commit;
++      external_memory_allocator.allocate_page_table_block = NULL;
++      external_memory_allocator.ctx = mem;
++      external_memory_allocator.name = "DMA-BUF Memory";
++      external_memory_allocator.next = NULL;
++
++      /* Map memory into session's Mali virtual address space. */
++      _mali_osk_lock_wait(session->memory_lock, _MALI_OSK_LOCKMODE_RW);
++      if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_memory(mali_mem_get_memory_engine(), descriptor, &external_memory_allocator, NULL))
++      {
++              _mali_osk_lock_signal(session->memory_lock, _MALI_OSK_LOCKMODE_RW);
++
++              MALI_PRINT_ERROR(("Failed to map dma-buf %d into Mali address space\n", fd));
++              mali_descriptor_mapping_free(session->descriptor_mapping, md);
++              mali_dma_buf_release(NULL, mem);
++              return -ENOMEM;
++      }
++      _mali_osk_lock_signal(session->memory_lock, _MALI_OSK_LOCKMODE_RW);
++
++      /* Return stuff to user space */
++      if (0 != put_user(md, &user_arg->cookie))
++      {
++              /* Roll back */
++              MALI_PRINT_ERROR(("Failed to return descriptor to user space for dma-buf %d\n", fd));
++              mali_descriptor_mapping_free(session->descriptor_mapping, md);
++              mali_dma_buf_release(NULL, mem);
++              return -EFAULT;
++      }
++
++      return 0;
++}
++
++int mali_release_dma_buf(struct mali_session_data *session, _mali_uk_release_dma_buf_s __user *user_arg)
++{
++      _mali_uk_release_dma_buf_s args;
++      mali_memory_allocation *descriptor;
++
++      /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
++      if ( 0 != copy_from_user(&args, (void __user *)user_arg, sizeof(_mali_uk_release_dma_buf_s)) )
++      {
++              return -EFAULT;
++      }
++
++      if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_get(session->descriptor_mapping, args.cookie, (void**)&descriptor))
++      {
++              MALI_DEBUG_PRINT(1, ("Invalid memory descriptor %d used to release dma-buf\n", args.cookie));
++              return -EINVAL;
++      }
++
++      descriptor = mali_descriptor_mapping_free(session->descriptor_mapping, args.cookie);
++
++      if (NULL != descriptor)
++      {
++              _mali_osk_lock_wait( session->memory_lock, _MALI_OSK_LOCKMODE_RW );
++
++              /* Will call back to mali_dma_buf_release() which will release the dma-buf attachment. */
++              mali_allocation_engine_release_memory(mali_mem_get_memory_engine(), descriptor);
++
++              _mali_osk_lock_signal( session->memory_lock, _MALI_OSK_LOCKMODE_RW );
++
++              _mali_osk_free(descriptor);
++      }
++
++      /* Return the error that _mali_ukk_map_external_ump_mem produced */
++      return 0;
++}
++
++int mali_dma_buf_get_size(struct mali_session_data *session, _mali_uk_dma_buf_get_size_s __user *user_arg)
++{
++      _mali_uk_dma_buf_get_size_s args;
++      int fd;
++      struct dma_buf *buf;
++
++      /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
++      if ( 0 != copy_from_user(&args, (void __user *)user_arg, sizeof(_mali_uk_dma_buf_get_size_s)) )
++      {
++              return -EFAULT;
++      }
++
++      /* Do DMA-BUF stuff */
++      fd = args.mem_fd;
++
++      buf = dma_buf_get(fd);
++      if (IS_ERR_OR_NULL(buf))
++      {
++              MALI_DEBUG_PRINT(2, ("Failed to get dma-buf from fd: %d\n", fd));
++              return PTR_RET(buf);
++      }
++
++      if (0 != put_user(buf->size, &user_arg->size))
++      {
++              dma_buf_put(buf);
++              return -EFAULT;
++      }
++
++      dma_buf_put(buf);
++
++      return 0;
++}
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_dma_buf.h b/drivers/gpu/arm/mali400/mali/linux/mali_dma_buf.h
+new file mode 100644
+index 0000000..9d19773
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_dma_buf.h
+@@ -0,0 +1,29 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_DMA_BUF_H__
++#define __MALI_DMA_BUF_H__
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif
++
++#include "mali_osk.h"
++
++int mali_attach_dma_buf(struct mali_session_data *session, _mali_uk_attach_dma_buf_s __user *arg);
++int mali_release_dma_buf(struct mali_session_data *session, _mali_uk_release_dma_buf_s __user *arg);
++int mali_dma_buf_get_size(struct mali_session_data *session, _mali_uk_dma_buf_get_size_s __user *arg);
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* __MALI_KERNEL_LINUX_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_kernel_linux.c b/drivers/gpu/arm/mali400/mali/linux/mali_kernel_linux.c
+new file mode 100644
+index 0000000..adaaf9a
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_kernel_linux.c
+@@ -0,0 +1,755 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_kernel_linux.c
++ * Implementation of the Linux device driver entrypoints
++ */
++#include <linux/module.h>   /* kernel module definitions */
++#include <linux/fs.h>       /* file system operations */
++#include <linux/cdev.h>     /* character device definitions */
++#include <linux/mm.h>       /* memory manager definitions */
++#include <linux/mali/mali_utgard_ioctl.h>
++#include <linux/version.h>
++#include <linux/device.h>
++#include "mali_kernel_license.h"
++#include <linux/platform_device.h>
++#if MALI_LICENSE_IS_GPL
++#include <linux/miscdevice.h>
++#endif
++#include <linux/mali/mali_utgard.h>
++#include "mali_kernel_common.h"
++#include "mali_session.h"
++#include "mali_kernel_core.h"
++#include "mali_osk.h"
++#include "mali_kernel_linux.h"
++#include "mali_ukk.h"
++#include "mali_ukk_wrappers.h"
++#include "mali_kernel_sysfs.h"
++#include "mali_pm.h"
++#include "mali_kernel_license.h"
++#include "mali_dma_buf.h"
++#if defined(CONFIG_MALI400_INTERNAL_PROFILING)
++#include "mali_profiling_internal.h"
++#endif
++/* MALI_SEC */
++#include "../platform/pegasus-m400/exynos4_pmm.h"
++
++/* Streamline support for the Mali driver */
++#if defined(CONFIG_TRACEPOINTS) && defined(CONFIG_MALI400_PROFILING)
++/* Ask Linux to create the tracepoints */
++#define CREATE_TRACE_POINTS
++#include "mali_linux_trace.h"
++#endif /* CONFIG_TRACEPOINTS */
++
++/* from the __malidrv_build_info.c file that is generated during build */
++extern const char *__malidrv_build_info(void);
++
++/* Module parameter to control log level */
++int mali_debug_level = 2;
++module_param(mali_debug_level, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); /* rw-rw-r-- */
++MODULE_PARM_DESC(mali_debug_level, "Higher number, more dmesg output");
++
++module_param(mali_max_job_runtime, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH);
++MODULE_PARM_DESC(mali_max_job_runtime, "Maximum allowed job runtime in msecs.\nJobs will be killed after this no matter what");
++
++extern int mali_l2_max_reads;
++module_param(mali_l2_max_reads, int, S_IRUSR | S_IRGRP | S_IROTH);
++MODULE_PARM_DESC(mali_l2_max_reads, "Maximum reads for Mali L2 cache");
++
++extern int mali_dedicated_mem_start;
++module_param(mali_dedicated_mem_start, int, S_IRUSR | S_IRGRP | S_IROTH);
++MODULE_PARM_DESC(mali_dedicated_mem_start, "Physical start address of dedicated Mali GPU memory.");
++
++extern int mali_dedicated_mem_size;
++module_param(mali_dedicated_mem_size, int, S_IRUSR | S_IRGRP | S_IROTH);
++MODULE_PARM_DESC(mali_dedicated_mem_size, "Size of dedicated Mali GPU memory.");
++
++extern int mali_shared_mem_size;
++module_param(mali_shared_mem_size, int, S_IRUSR | S_IRGRP | S_IROTH);
++MODULE_PARM_DESC(mali_shared_mem_size, "Size of shared Mali GPU memory.");
++
++#if defined(CONFIG_MALI400_PROFILING)
++extern int mali_boot_profiling;
++module_param(mali_boot_profiling, int, S_IRUSR | S_IRGRP | S_IROTH);
++MODULE_PARM_DESC(mali_boot_profiling, "Start profiling as a part of Mali driver initialization");
++#endif
++
++extern int mali_max_pp_cores_group_1;
++module_param(mali_max_pp_cores_group_1, int, S_IRUSR | S_IRGRP | S_IROTH);
++MODULE_PARM_DESC(mali_max_pp_cores_group_1, "Limit the number of PP cores to use from first PP group.");
++
++extern int mali_max_pp_cores_group_2;
++module_param(mali_max_pp_cores_group_2, int, S_IRUSR | S_IRGRP | S_IROTH);
++MODULE_PARM_DESC(mali_max_pp_cores_group_2, "Limit the number of PP cores to use from second PP group (Mali-450 only).");
++
++/* Export symbols from common code: mali_user_settings.c */
++#include "mali_user_settings_db.h"
++EXPORT_SYMBOL(mali_set_user_setting);
++EXPORT_SYMBOL(mali_get_user_setting);
++#if CONFIG_MALI_DVFS
++/* MALI_SEC */
++extern int mali_dvfs_control;
++module_param(mali_dvfs_control, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
++MODULE_PARM_DESC(mali_dvfs_control, "Mali Current DVFS");
++
++#if 0
++extern int mali_gpu_clk;
++module_param(mali_gpu_clk, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */
++MODULE_PARM_DESC(mali_gpu_clk, "Mali Current Clock");
++
++extern int mali_gpu_vol;
++module_param(mali_gpu_vol, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */
++MODULE_PARM_DESC(mali_gpu_vol, "Mali Current Voltage");
++
++extern int gpu_power_state;
++module_param(gpu_power_state, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */
++MODULE_PARM_DESC(gpu_power_state, "Mali Power State");
++#endif
++#endif
++
++static char mali_dev_name[] = "mali"; /* should be const, but the functions we call requires non-cost */
++
++/* This driver only supports one Mali device, and this variable stores this single platform device */
++struct platform_device *mali_platform_device = NULL;
++
++/* This driver only supports one Mali device, and this variable stores the exposed misc device (/dev/mali) */
++static struct miscdevice mali_miscdevice = { 0, };
++
++static int mali_miscdevice_register(struct platform_device *pdev);
++static void mali_miscdevice_unregister(void);
++
++static int mali_open(struct inode *inode, struct file *filp);
++static int mali_release(struct inode *inode, struct file *filp);
++#ifdef HAVE_UNLOCKED_IOCTL
++static long mali_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
++#else
++static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
++#endif
++static int mali_mmap(struct file * filp, struct vm_area_struct * vma);
++
++static int mali_probe(struct platform_device *pdev);
++static int mali_remove(struct platform_device *pdev);
++
++static int mali_driver_suspend_scheduler(struct device *dev);
++static int mali_driver_resume_scheduler(struct device *dev);
++
++#ifdef CONFIG_PM_RUNTIME
++static int mali_driver_runtime_suspend(struct device *dev);
++static int mali_driver_runtime_resume(struct device *dev);
++static int mali_driver_runtime_idle(struct device *dev);
++#endif
++
++#if defined(MALI_FAKE_PLATFORM_DEVICE)
++extern int mali_platform_device_register(void);
++extern int mali_platform_device_unregister(void);
++#endif
++
++/* Linux power management operations provided by the Mali device driver */
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
++struct pm_ext_ops mali_dev_ext_pm_ops =
++{
++      .base =
++      {
++              .suspend = mali_driver_suspend_scheduler,
++              .resume = mali_driver_resume_scheduler,
++              .freeze = mali_driver_suspend_scheduler,
++              .thaw =   mali_driver_resume_scheduler,
++      },
++};
++#else
++static const struct dev_pm_ops mali_dev_pm_ops =
++{
++#ifdef CONFIG_PM_RUNTIME
++      .runtime_suspend = mali_driver_runtime_suspend,
++      .runtime_resume = mali_driver_runtime_resume,
++      .runtime_idle = mali_driver_runtime_idle,
++#endif
++      .suspend = mali_driver_suspend_scheduler,
++      .resume = mali_driver_resume_scheduler,
++      .freeze = mali_driver_suspend_scheduler,
++      .thaw = mali_driver_resume_scheduler,
++};
++#endif
++
++/* The Mali device driver struct */
++static struct platform_driver mali_platform_driver =
++{
++      .probe  = mali_probe,
++      .remove = mali_remove,
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
++      .pm = &mali_dev_ext_pm_ops,
++#endif
++      .driver =
++      {
++              .name   = "mali_dev", /* MALI_SEC MALI_GPU_NAME_UTGARD, */
++              .owner  = THIS_MODULE,
++              .bus = &platform_bus_type,
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
++              .pm = &mali_dev_pm_ops,
++#endif
++      },
++};
++
++/* Linux misc device operations (/dev/mali) */
++struct file_operations mali_fops =
++{
++      .owner = THIS_MODULE,
++      .open = mali_open,
++      .release = mali_release,
++#ifdef HAVE_UNLOCKED_IOCTL
++      .unlocked_ioctl = mali_ioctl,
++#else
++      .ioctl = mali_ioctl,
++#endif
++      .mmap = mali_mmap
++};
++
++
++
++
++
++
++int mali_module_init(void)
++{
++      int err = 0;
++
++      MALI_DEBUG_PRINT(2, ("Inserting Mali v%d device driver. \n",_MALI_API_VERSION));
++      MALI_DEBUG_PRINT(2, ("Compiled: %s, time: %s.\n", __DATE__, __TIME__));
++      MALI_DEBUG_PRINT(2, ("Driver revision: %s\n", SVN_REV_STRING));
++
++      /* Initialize module wide settings */
++      mali_osk_low_level_mem_init();
++
++#if defined(MALI_FAKE_PLATFORM_DEVICE)
++      MALI_DEBUG_PRINT(2, ("mali_module_init() registering device\n"));
++      err = mali_platform_device_register();
++      if (0 != err)
++      {
++              return err;
++      }
++#endif
++
++      MALI_DEBUG_PRINT(2, ("mali_module_init() registering driver\n"));
++
++      err = platform_driver_register(&mali_platform_driver);
++
++      if (0 != err)
++      {
++              MALI_DEBUG_PRINT(2, ("mali_module_init() Failed to register driver (%d)\n", err));
++#if defined(MALI_FAKE_PLATFORM_DEVICE)
++              mali_platform_device_unregister();
++#endif
++              mali_platform_device = NULL;
++              return err;
++      }
++
++#if defined(CONFIG_MALI400_INTERNAL_PROFILING)
++        err = _mali_internal_profiling_init(mali_boot_profiling ? MALI_TRUE : MALI_FALSE);
++        if (0 != err)
++        {
++                /* No biggie if we wheren't able to initialize the profiling */
++                MALI_PRINT_ERROR(("Failed to initialize profiling, feature will be unavailable\n"));
++        }
++#endif
++
++      MALI_PRINT(("Mali device driver loaded\n"));
++
++      return 0; /* Success */
++}
++
++void mali_module_exit(void)
++{
++      MALI_DEBUG_PRINT(2, ("Unloading Mali v%d device driver.\n",_MALI_API_VERSION));
++
++      MALI_DEBUG_PRINT(2, ("mali_module_exit() unregistering driver\n"));
++
++#if defined(CONFIG_MALI400_INTERNAL_PROFILING)
++        _mali_internal_profiling_term();
++#endif
++
++      platform_driver_unregister(&mali_platform_driver);
++
++#if defined(MALI_FAKE_PLATFORM_DEVICE)
++      MALI_DEBUG_PRINT(2, ("mali_module_exit() unregistering device\n"));
++      mali_platform_device_unregister();
++#endif
++
++      mali_osk_low_level_mem_term();
++
++      MALI_PRINT(("Mali device driver unloaded\n"));
++}
++
++static int mali_probe(struct platform_device *pdev)
++{
++      int err;
++
++      MALI_DEBUG_PRINT(2, ("mali_probe(): Called for platform device %s\n", pdev->name));
++
++      if (NULL != mali_platform_device)
++      {
++              /* Already connected to a device, return error */
++              MALI_PRINT_ERROR(("mali_probe(): The Mali driver is already connected with a Mali device."));
++              return -EEXIST;
++      }
++
++      mali_platform_device = pdev;
++
++      if (_MALI_OSK_ERR_OK == _mali_osk_wq_init())
++      {
++              /* Initialize the Mali GPU HW specified by pdev */
++              if (_MALI_OSK_ERR_OK == mali_initialize_subsystems())
++              {
++                      /* Register a misc device (so we are accessible from user space) */
++                      err = mali_miscdevice_register(pdev);
++                      if (0 == err)
++                      {
++                              /* Setup sysfs entries */
++                              err = mali_sysfs_register(mali_dev_name);
++                              if (0 == err)
++                              {
++                                      MALI_DEBUG_PRINT(2, ("mali_probe(): Successfully initialized driver for platform device %s\n", pdev->name));
++                                      return 0;
++                              }
++                              else
++                              {
++                                      MALI_PRINT_ERROR(("mali_probe(): failed to register sysfs entries"));
++                              }
++                              mali_miscdevice_unregister();
++                      }
++                      else
++                      {
++                              MALI_PRINT_ERROR(("mali_probe(): failed to register Mali misc device."));
++                      }
++                      mali_terminate_subsystems();
++              }
++              else
++              {
++                      MALI_PRINT_ERROR(("mali_probe(): Failed to initialize Mali device driver."));
++              }
++              _mali_osk_wq_term();
++      }
++
++      mali_platform_device = NULL;
++      return -EFAULT;
++}
++
++static int mali_remove(struct platform_device *pdev)
++{
++      MALI_DEBUG_PRINT(2, ("mali_remove() called for platform device %s\n", pdev->name));
++      mali_sysfs_unregister();
++      mali_miscdevice_unregister();
++      mali_terminate_subsystems();
++      _mali_osk_wq_term();
++      mali_platform_device = NULL;
++      return 0;
++}
++
++static int mali_miscdevice_register(struct platform_device *pdev)
++{
++      int err;
++
++      mali_miscdevice.minor = MISC_DYNAMIC_MINOR;
++      mali_miscdevice.name = mali_dev_name;
++      mali_miscdevice.fops = &mali_fops;
++      mali_miscdevice.parent = get_device(&pdev->dev);
++
++      err = misc_register(&mali_miscdevice);
++      if (0 != err)
++      {
++              MALI_PRINT_ERROR(("Failed to register misc device, misc_register() returned %d\n", err));
++      }
++
++      return err;
++}
++
++static void mali_miscdevice_unregister(void)
++{
++      misc_deregister(&mali_miscdevice);
++}
++
++static int mali_driver_suspend_scheduler(struct device *dev)
++{
++      mali_pm_os_suspend();
++      /* MALI_SEC */
++      mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP);
++      return 0;
++}
++
++static int mali_driver_resume_scheduler(struct device *dev)
++{
++      /* MALI_SEC */
++      mali_platform_power_mode_change(MALI_POWER_MODE_ON);
++      mali_pm_os_resume();
++      return 0;
++}
++
++#ifdef CONFIG_PM_RUNTIME
++static int mali_driver_runtime_suspend(struct device *dev)
++{
++      mali_pm_runtime_suspend();
++      /* MALI_SEC */
++      mali_platform_power_mode_change(MALI_POWER_MODE_LIGHT_SLEEP);
++      return 0;
++}
++
++static int mali_driver_runtime_resume(struct device *dev)
++{
++      /* MALI_SEC */
++      mali_platform_power_mode_change(MALI_POWER_MODE_ON);
++      mali_pm_runtime_resume();
++      return 0;
++}
++
++static int mali_driver_runtime_idle(struct device *dev)
++{
++      /* Nothing to do */
++      return 0;
++}
++#endif
++
++/** @note munmap handler is done by vma close handler */
++static int mali_mmap(struct file * filp, struct vm_area_struct * vma)
++{
++      struct mali_session_data * session_data;
++      _mali_uk_mem_mmap_s args = {0, };
++
++    session_data = (struct mali_session_data *)filp->private_data;
++      if (NULL == session_data)
++      {
++              MALI_PRINT_ERROR(("mmap called without any session data available\n"));
++              return -EFAULT;
++      }
++
++      MALI_DEBUG_PRINT(4, ("MMap() handler: start=0x%08X, phys=0x%08X, size=0x%08X vma->flags 0x%08x\n", (unsigned int)vma->vm_start, (unsigned int)(vma->vm_pgoff << PAGE_SHIFT), (unsigned int)(vma->vm_end - vma->vm_start), vma->vm_flags));
++
++      /* Re-pack the arguments that mmap() packed for us */
++      args.ctx = session_data;
++      args.phys_addr = vma->vm_pgoff << PAGE_SHIFT;
++      args.size = vma->vm_end - vma->vm_start;
++      args.ukk_private = vma;
++
++      if ( VM_SHARED== (VM_SHARED  & vma->vm_flags))
++      {
++              args.cache_settings = MALI_CACHE_STANDARD ;
++              MALI_DEBUG_PRINT(3,("Allocate - Standard - Size: %d kb\n", args.size/1024));
++      }
++      else
++      {
++              args.cache_settings = MALI_CACHE_GP_READ_ALLOCATE;
++              MALI_DEBUG_PRINT(3,("Allocate - GP Cached - Size: %d kb\n", args.size/1024));
++      }
++      /* Setting it equal to VM_SHARED and not Private, which would have made the later io_remap fail for MALI_CACHE_GP_READ_ALLOCATE */
++      vma->vm_flags = 0x000000fb;
++
++      /* Call the common mmap handler */
++      MALI_CHECK(_MALI_OSK_ERR_OK ==_mali_ukk_mem_mmap( &args ), -EFAULT);
++
++    return 0;
++}
++
++static int mali_open(struct inode *inode, struct file *filp)
++{
++      struct mali_session_data * session_data;
++    _mali_osk_errcode_t err;
++
++      /* input validation */
++      if (mali_miscdevice.minor != iminor(inode))
++      {
++              MALI_PRINT_ERROR(("mali_open() Minor does not match\n"));
++              return -ENODEV;
++      }
++
++      /* allocated struct to track this session */
++    err = _mali_ukk_open((void **)&session_data);
++    if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
++
++      /* initialize file pointer */
++      filp->f_pos = 0;
++
++      /* link in our session data */
++      filp->private_data = (void*)session_data;
++
++      return 0;
++}
++
++static int mali_release(struct inode *inode, struct file *filp)
++{
++    _mali_osk_errcode_t err;
++
++      /* input validation */
++      if (mali_miscdevice.minor != iminor(inode))
++      {
++              MALI_PRINT_ERROR(("mali_release() Minor does not match\n"));
++              return -ENODEV;
++      }
++
++    err = _mali_ukk_close((void **)&filp->private_data);
++    if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
++
++      return 0;
++}
++
++int map_errcode( _mali_osk_errcode_t err )
++{
++    switch(err)
++    {
++        case _MALI_OSK_ERR_OK : return 0;
++        case _MALI_OSK_ERR_FAULT: return -EFAULT;
++        case _MALI_OSK_ERR_INVALID_FUNC: return -ENOTTY;
++        case _MALI_OSK_ERR_INVALID_ARGS: return -EINVAL;
++        case _MALI_OSK_ERR_NOMEM: return -ENOMEM;
++        case _MALI_OSK_ERR_TIMEOUT: return -ETIMEDOUT;
++        case _MALI_OSK_ERR_RESTARTSYSCALL: return -ERESTARTSYS;
++        case _MALI_OSK_ERR_ITEM_NOT_FOUND: return -ENOENT;
++        default: return -EFAULT;
++    }
++}
++
++#ifdef HAVE_UNLOCKED_IOCTL
++static long mali_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
++#else
++static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
++#endif
++{
++      int err;
++      struct mali_session_data *session_data;
++
++#ifndef HAVE_UNLOCKED_IOCTL
++      /* inode not used */
++      (void)inode;
++#endif
++
++      MALI_DEBUG_PRINT(7, ("Ioctl received 0x%08X 0x%08lX\n", cmd, arg));
++
++      session_data = (struct mali_session_data *)filp->private_data;
++      if (NULL == session_data)
++      {
++              MALI_DEBUG_PRINT(7, ("filp->private_data was NULL\n"));
++              return -ENOTTY;
++      }
++
++      if (NULL == (void *)arg)
++      {
++              MALI_DEBUG_PRINT(7, ("arg was NULL\n"));
++              return -ENOTTY;
++      }
++
++      switch(cmd)
++      {
++              case MALI_IOC_WAIT_FOR_NOTIFICATION:
++                      err = wait_for_notification_wrapper(session_data, (_mali_uk_wait_for_notification_s __user *)arg);
++                      break;
++
++              case MALI_IOC_GET_API_VERSION:
++                      err = get_api_version_wrapper(session_data, (_mali_uk_get_api_version_s __user *)arg);
++                      break;
++
++              case MALI_IOC_POST_NOTIFICATION:
++                      err = post_notification_wrapper(session_data, (_mali_uk_post_notification_s __user *)arg);
++                      break;
++
++              case MALI_IOC_GET_USER_SETTINGS:
++                      err = get_user_settings_wrapper(session_data, (_mali_uk_get_user_settings_s __user *)arg);
++                      break;
++
++#if defined(CONFIG_MALI400_PROFILING)
++              case MALI_IOC_PROFILING_START:
++                      err = profiling_start_wrapper(session_data, (_mali_uk_profiling_start_s __user *)arg);
++                      break;
++
++              case MALI_IOC_PROFILING_ADD_EVENT:
++                      err = profiling_add_event_wrapper(session_data, (_mali_uk_profiling_add_event_s __user *)arg);
++                      break;
++
++              case MALI_IOC_PROFILING_STOP:
++                      err = profiling_stop_wrapper(session_data, (_mali_uk_profiling_stop_s __user *)arg);
++                      break;
++
++              case MALI_IOC_PROFILING_GET_EVENT:
++                      err = profiling_get_event_wrapper(session_data, (_mali_uk_profiling_get_event_s __user *)arg);
++                      break;
++
++              case MALI_IOC_PROFILING_CLEAR:
++                      err = profiling_clear_wrapper(session_data, (_mali_uk_profiling_clear_s __user *)arg);
++                      break;
++
++              case MALI_IOC_PROFILING_GET_CONFIG:
++                      /* Deprecated: still compatible with get_user_settings */
++                      err = get_user_settings_wrapper(session_data, (_mali_uk_get_user_settings_s __user *)arg);
++                      break;
++
++              case MALI_IOC_PROFILING_REPORT_SW_COUNTERS:
++                      err = profiling_report_sw_counters_wrapper(session_data, (_mali_uk_sw_counters_report_s __user *)arg);
++                      break;
++
++#else
++
++              case MALI_IOC_PROFILING_START:              /* FALL-THROUGH */
++              case MALI_IOC_PROFILING_ADD_EVENT:          /* FALL-THROUGH */
++              case MALI_IOC_PROFILING_STOP:               /* FALL-THROUGH */
++              case MALI_IOC_PROFILING_GET_EVENT:          /* FALL-THROUGH */
++              case MALI_IOC_PROFILING_CLEAR:              /* FALL-THROUGH */
++              case MALI_IOC_PROFILING_GET_CONFIG:         /* FALL-THROUGH */
++              case MALI_IOC_PROFILING_REPORT_SW_COUNTERS: /* FALL-THROUGH */
++                      MALI_DEBUG_PRINT(2, ("Profiling not supported\n"));
++                      err = -ENOTTY;
++                      break;
++
++#endif
++
++              case MALI_IOC_MEM_INIT:
++                      err = mem_init_wrapper(session_data, (_mali_uk_init_mem_s __user *)arg);
++                      break;
++
++              case MALI_IOC_MEM_TERM:
++                      err = mem_term_wrapper(session_data, (_mali_uk_term_mem_s __user *)arg);
++                      break;
++
++              case MALI_IOC_MEM_MAP_EXT:
++                      err = mem_map_ext_wrapper(session_data, (_mali_uk_map_external_mem_s __user *)arg);
++                      break;
++
++              case MALI_IOC_MEM_UNMAP_EXT:
++                      err = mem_unmap_ext_wrapper(session_data, (_mali_uk_unmap_external_mem_s __user *)arg);
++                      break;
++
++              case MALI_IOC_MEM_QUERY_MMU_PAGE_TABLE_DUMP_SIZE:
++                      err = mem_query_mmu_page_table_dump_size_wrapper(session_data, (_mali_uk_query_mmu_page_table_dump_size_s __user *)arg);
++                      break;
++
++              case MALI_IOC_MEM_DUMP_MMU_PAGE_TABLE:
++                      err = mem_dump_mmu_page_table_wrapper(session_data, (_mali_uk_dump_mmu_page_table_s __user *)arg);
++                      break;
++
++#if defined(CONFIG_MALI400_UMP)
++
++              case MALI_IOC_MEM_ATTACH_UMP:
++                      err = mem_attach_ump_wrapper(session_data, (_mali_uk_attach_ump_mem_s __user *)arg);
++                      break;
++
++              case MALI_IOC_MEM_RELEASE_UMP:
++                      err = mem_release_ump_wrapper(session_data, (_mali_uk_release_ump_mem_s __user *)arg);
++                      break;
++
++#else
++
++              case MALI_IOC_MEM_ATTACH_UMP:
++              case MALI_IOC_MEM_RELEASE_UMP: /* FALL-THROUGH */
++                      MALI_DEBUG_PRINT(2, ("UMP not supported\n"));
++                      err = -ENOTTY;
++                      break;
++#endif
++
++#ifdef CONFIG_DMA_SHARED_BUFFER
++              case MALI_IOC_MEM_ATTACH_DMA_BUF:
++                      err = mali_attach_dma_buf(session_data, (_mali_uk_attach_dma_buf_s __user *)arg);
++                      break;
++
++              case MALI_IOC_MEM_RELEASE_DMA_BUF:
++                      err = mali_release_dma_buf(session_data, (_mali_uk_release_dma_buf_s __user *)arg);
++                      break;
++
++              case MALI_IOC_MEM_DMA_BUF_GET_SIZE:
++                      err = mali_dma_buf_get_size(session_data, (_mali_uk_dma_buf_get_size_s __user *)arg);
++                      break;
++#else
++
++              case MALI_IOC_MEM_ATTACH_DMA_BUF:   /* FALL-THROUGH */
++              case MALI_IOC_MEM_RELEASE_DMA_BUF:  /* FALL-THROUGH */
++              case MALI_IOC_MEM_DMA_BUF_GET_SIZE: /* FALL-THROUGH */
++                      MALI_DEBUG_PRINT(2, ("DMA-BUF not supported\n"));
++                      err = -ENOTTY;
++                      break;
++#endif
++
++              case MALI_IOC_PP_START_JOB:
++                      err = pp_start_job_wrapper(session_data, (_mali_uk_pp_start_job_s __user *)arg);
++                      break;
++
++              case MALI_IOC_PP_NUMBER_OF_CORES_GET:
++                      err = pp_get_number_of_cores_wrapper(session_data, (_mali_uk_get_pp_number_of_cores_s __user *)arg);
++                      break;
++
++              case MALI_IOC_PP_CORE_VERSION_GET:
++                      err = pp_get_core_version_wrapper(session_data, (_mali_uk_get_pp_core_version_s __user *)arg);
++                      break;
++
++              case MALI_IOC_PP_DISABLE_WB:
++                      err = pp_disable_wb_wrapper(session_data, (_mali_uk_pp_disable_wb_s __user *)arg);
++                      break;
++
++              case MALI_IOC_GP2_START_JOB:
++                      err = gp_start_job_wrapper(session_data, (_mali_uk_gp_start_job_s __user *)arg);
++                      break;
++
++              case MALI_IOC_GP2_NUMBER_OF_CORES_GET:
++                      err = gp_get_number_of_cores_wrapper(session_data, (_mali_uk_get_gp_number_of_cores_s __user *)arg);
++                      break;
++
++              case MALI_IOC_GP2_CORE_VERSION_GET:
++                      err = gp_get_core_version_wrapper(session_data, (_mali_uk_get_gp_core_version_s __user *)arg);
++                      break;
++
++              case MALI_IOC_GP2_SUSPEND_RESPONSE:
++                      err = gp_suspend_response_wrapper(session_data, (_mali_uk_gp_suspend_response_s __user *)arg);
++                      break;
++
++              case MALI_IOC_VSYNC_EVENT_REPORT:
++                      err = vsync_event_report_wrapper(session_data, (_mali_uk_vsync_event_report_s __user *)arg);
++                      break;
++
++              case MALI_IOC_STREAM_CREATE:
++#if defined(CONFIG_SYNC)
++/* MALI_SEC */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
++                      err = stream_create_wrapper(session_data, (_mali_uk_stream_create_s __user *)arg);
++#else
++                      err = -ENOTTY;
++#endif
++                      break;
++#endif
++              case MALI_IOC_FENCE_VALIDATE:
++#if defined(CONFIG_SYNC)
++/* MALI_SEC */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
++                      err = sync_fence_validate_wrapper(session_data, (_mali_uk_fence_validate_s __user *)arg);
++#else
++                      MALI_DEBUG_PRINT(2, ("Sync objects not supported\n"));
++                      err = -ENOTTY;
++#endif
++                      break;
++#else
++                      MALI_DEBUG_PRINT(2, ("Sync objects not supported\n"));
++                      err = -ENOTTY;
++                      break;
++#endif
++
++              case MALI_IOC_MEM_GET_BIG_BLOCK: /* Fallthrough */
++              case MALI_IOC_MEM_FREE_BIG_BLOCK:
++                      MALI_PRINT_ERROR(("Non-MMU mode is no longer supported.\n"));
++                      err = -ENOTTY;
++                      break;
++
++              default:
++                      MALI_DEBUG_PRINT(2, ("No handler for ioctl 0x%08X 0x%08lX\n", cmd, arg));
++                      err = -ENOTTY;
++      };
++
++      return err;
++}
++
++
++module_init(mali_module_init);
++module_exit(mali_module_exit);
++
++MODULE_LICENSE(MALI_KERNEL_LINUX_LICENSE);
++MODULE_AUTHOR("ARM Ltd.");
++MODULE_VERSION(SVN_REV_STRING);
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_kernel_linux.h b/drivers/gpu/arm/mali400/mali/linux/mali_kernel_linux.h
+new file mode 100644
+index 0000000..2d551af
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_kernel_linux.h
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_KERNEL_LINUX_H__
++#define __MALI_KERNEL_LINUX_H__
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif
++
++#include <linux/cdev.h>     /* character device definitions */
++#include "mali_kernel_license.h"
++#include "mali_osk.h"
++
++extern struct platform_device *mali_platform_device;
++
++#if MALI_LICENSE_IS_GPL
++/* Defined in mali_osk_irq.h */
++extern struct workqueue_struct * mali_wq;
++#endif
++
++void mali_osk_low_level_mem_init(void);
++void mali_osk_low_level_mem_term(void);
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* __MALI_KERNEL_LINUX_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_kernel_sysfs.c b/drivers/gpu/arm/mali400/mali/linux/mali_kernel_sysfs.c
+new file mode 100644
+index 0000000..49779d1
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_kernel_sysfs.c
+@@ -0,0 +1,1442 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_kernel_sysfs.c
++ * Implementation of some sysfs data exports
++ */
++
++#include <linux/kernel.h>
++#include <linux/fs.h>
++#include <linux/device.h>
++#include <linux/module.h>
++#include "mali_kernel_license.h"
++#include "mali_kernel_common.h"
++#include "mali_ukk.h"
++
++#if MALI_LICENSE_IS_GPL
++
++#include <linux/seq_file.h>
++#include <linux/debugfs.h>
++#include <asm/uaccess.h>
++#include <linux/module.h>
++#include "mali_kernel_sysfs.h"
++#if defined(CONFIG_MALI400_INTERNAL_PROFILING)
++#include <linux/slab.h>
++#include "mali_osk_profiling.h"
++#endif
++#include "mali_pm.h"
++#include "mali_group.h"
++#include "mali_gp.h"
++#include "mali_pp.h"
++#include "mali_l2_cache.h"
++#include "mali_hw_core.h"
++#include "mali_kernel_core.h"
++#include "mali_user_settings_db.h"
++#include "mali_device_pause_resume.h"
++#include "mali_profiling_internal.h"
++#include "mali_gp_job.h"
++#include "mali_pp_job.h"
++
++#define POWER_BUFFER_SIZE 3
++
++static struct dentry *mali_debugfs_dir = NULL;
++
++typedef enum
++{
++        _MALI_DEVICE_SUSPEND,
++        _MALI_DEVICE_RESUME,
++        _MALI_DEVICE_DVFS_PAUSE,
++        _MALI_DEVICE_DVFS_RESUME,
++        _MALI_MAX_EVENTS
++} _mali_device_debug_power_events;
++
++static const char* const mali_power_events[_MALI_MAX_EVENTS] = {
++        [_MALI_DEVICE_SUSPEND] = "suspend",
++        [_MALI_DEVICE_RESUME] = "resume",
++        [_MALI_DEVICE_DVFS_PAUSE] = "dvfs_pause",
++        [_MALI_DEVICE_DVFS_RESUME] = "dvfs_resume",
++};
++
++static u32 virtual_power_status_register = 0;
++static char pwr_buf[POWER_BUFFER_SIZE];
++
++static mali_bool power_always_on_enabled = MALI_FALSE;
++
++static int open_copy_private_data(struct inode *inode, struct file *filp)
++{
++      filp->private_data = inode->i_private;
++      return 0;
++}
++
++static ssize_t gp_gpx_counter_srcx_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *gpos, u32 src_id)
++{
++      char buf[64];
++      int r;
++      u32 val;
++
++      if (0 == src_id)
++      {
++              val = mali_gp_job_get_gp_counter_src0();
++      }
++      else
++      {
++              val = mali_gp_job_get_gp_counter_src1();
++      }
++
++      if (MALI_HW_CORE_NO_COUNTER == val)
++      {
++              r = sprintf(buf, "-1\n");
++      }
++      else
++      {
++              r = sprintf(buf, "%u\n", val);
++      }
++      return simple_read_from_buffer(ubuf, cnt, gpos, buf, r);
++}
++
++static ssize_t gp_gpx_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos, u32 src_id)
++{
++      char buf[64];
++      long val;
++      int ret;
++
++      if (cnt >= sizeof(buf))
++      {
++              return -EINVAL;
++      }
++
++      if (copy_from_user(&buf, ubuf, cnt))
++      {
++              return -EFAULT;
++      }
++
++      buf[cnt] = 0;
++
++      ret = strict_strtol(buf, 10, &val);
++      if (ret < 0)
++      {
++              return ret;
++      }
++
++      if (val < 0)
++      {
++              /* any negative input will disable counter */
++              val = MALI_HW_CORE_NO_COUNTER;
++      }
++
++      if (0 == src_id)
++      {
++              if (MALI_TRUE != mali_gp_job_set_gp_counter_src0((u32)val))
++              {
++                      return 0;
++              }
++      }
++      else
++      {
++              if (MALI_TRUE != mali_gp_job_set_gp_counter_src1((u32)val))
++              {
++                      return 0;
++              }
++      }
++
++      *gpos += cnt;
++      return cnt;
++}
++
++static ssize_t gp_all_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos, u32 src_id)
++{
++      char buf[64];
++      long val;
++      int ret;
++      u32 num_groups;
++      int i;
++
++      if (cnt >= sizeof(buf))
++      {
++              return -EINVAL;
++      }
++
++      if (copy_from_user(&buf, ubuf, cnt))
++      {
++              return -EFAULT;
++      }
++
++      buf[cnt] = 0;
++
++      ret = strict_strtol(buf, 10, &val);
++      if (ret < 0)
++      {
++              return ret;
++      }
++
++      if (val < 0)
++      {
++              /* any negative input will disable counter */
++              val = MALI_HW_CORE_NO_COUNTER;
++      }
++
++      num_groups = mali_group_get_glob_num_groups();
++      for (i = 0; i < num_groups; i++)
++      {
++              struct mali_group *group = mali_group_get_glob_group(i);
++
++              struct mali_gp_core *gp_core = mali_group_get_gp_core(group);
++              if (NULL != gp_core)
++              {
++                      if (0 == src_id)
++                      {
++                              if (MALI_TRUE != mali_gp_job_set_gp_counter_src0((u32)val))
++                              {
++                                      return 0;
++                              }
++                      }
++                      else
++                      {
++                              if (MALI_TRUE != mali_gp_job_set_gp_counter_src1((u32)val))
++                              {
++                                      return 0;
++                              }
++                      }
++              }
++      }
++
++      *gpos += cnt;
++      return cnt;
++}
++
++static ssize_t gp_gpx_counter_src0_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *gpos)
++{
++      return gp_gpx_counter_srcx_read(filp, ubuf, cnt, gpos, 0);
++}
++
++static ssize_t gp_gpx_counter_src1_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *gpos)
++{
++      return gp_gpx_counter_srcx_read(filp, ubuf, cnt, gpos, 1);
++}
++
++static ssize_t gp_gpx_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos)
++{
++      return gp_gpx_counter_srcx_write(filp, ubuf, cnt, gpos, 0);
++}
++
++static ssize_t gp_gpx_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos)
++{
++      return gp_gpx_counter_srcx_write(filp, ubuf, cnt, gpos, 1);
++}
++
++static ssize_t gp_all_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos)
++{
++      return gp_all_counter_srcx_write(filp, ubuf, cnt, gpos, 0);
++}
++
++static ssize_t gp_all_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos)
++{
++      return gp_all_counter_srcx_write(filp, ubuf, cnt, gpos, 1);
++}
++
++static const struct file_operations gp_gpx_counter_src0_fops = {
++      .owner = THIS_MODULE,
++      .open  = open_copy_private_data,
++      .read  = gp_gpx_counter_src0_read,
++      .write = gp_gpx_counter_src0_write,
++};
++
++static const struct file_operations gp_gpx_counter_src1_fops = {
++      .owner = THIS_MODULE,
++      .open  = open_copy_private_data,
++      .read  = gp_gpx_counter_src1_read,
++      .write = gp_gpx_counter_src1_write,
++};
++
++static const struct file_operations gp_all_counter_src0_fops = {
++      .owner = THIS_MODULE,
++      .write = gp_all_counter_src0_write,
++};
++
++static const struct file_operations gp_all_counter_src1_fops = {
++      .owner = THIS_MODULE,
++      .write = gp_all_counter_src1_write,
++};
++
++static ssize_t pp_ppx_counter_srcx_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id)
++{
++      char buf[64];
++      int r;
++      u32 val;
++
++      if (0 == src_id)
++      {
++              val = mali_pp_job_get_pp_counter_src0();
++      }
++      else
++      {
++              val = mali_pp_job_get_pp_counter_src1();
++      }
++
++      if (MALI_HW_CORE_NO_COUNTER == val)
++      {
++              r = sprintf(buf, "-1\n");
++      }
++      else
++      {
++              r = sprintf(buf, "%u\n", val);
++      }
++      return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
++}
++
++static ssize_t pp_ppx_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id)
++{
++      char buf[64];
++      long val;
++      int ret;
++
++      if (cnt >= sizeof(buf))
++      {
++              return -EINVAL;
++      }
++
++      if (copy_from_user(&buf, ubuf, cnt))
++      {
++              return -EFAULT;
++      }
++
++      buf[cnt] = 0;
++
++      ret = strict_strtol(buf, 10, &val);
++      if (ret < 0)
++      {
++              return ret;
++      }
++
++      if (val < 0)
++      {
++              /* any negative input will disable counter */
++              val = MALI_HW_CORE_NO_COUNTER;
++      }
++
++      if (0 == src_id)
++      {
++              if (MALI_TRUE != mali_pp_job_set_pp_counter_src0((u32)val))
++              {
++                      return 0;
++              }
++      }
++      else
++      {
++              if (MALI_TRUE != mali_pp_job_set_pp_counter_src1((u32)val))
++              {
++                      return 0;
++              }
++      }
++
++      *ppos += cnt;
++      return cnt;
++}
++
++static ssize_t pp_all_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id)
++{
++      char buf[64];
++      long val;
++      int ret;
++      u32 num_groups;
++      int i;
++
++      if (cnt >= sizeof(buf))
++      {
++              return -EINVAL;
++      }
++
++      if (copy_from_user(&buf, ubuf, cnt))
++      {
++              return -EFAULT;
++      }
++
++      buf[cnt] = 0;
++
++      ret = strict_strtol(buf, 10, &val);
++      if (ret < 0)
++      {
++              return ret;
++      }
++
++      if (val < 0)
++      {
++              /* any negative input will disable counter */
++              val = MALI_HW_CORE_NO_COUNTER;
++      }
++
++      num_groups = mali_group_get_glob_num_groups();
++      for (i = 0; i < num_groups; i++)
++      {
++              struct mali_group *group = mali_group_get_glob_group(i);
++
++              struct mali_pp_core *pp_core = mali_group_get_pp_core(group);
++              if (NULL != pp_core)
++              {
++                      if (0 == src_id)
++                      {
++                              if (MALI_TRUE != mali_pp_job_set_pp_counter_src0((u32)val))
++                              {
++                                      return 0;
++                              }
++                      }
++                      else
++                      {
++                              if (MALI_TRUE != mali_pp_job_set_pp_counter_src1((u32)val))
++                              {
++                                      return 0;
++                              }
++                      }
++              }
++      }
++
++      *ppos += cnt;
++      return cnt;
++}
++
++static ssize_t pp_ppx_counter_src0_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++      return pp_ppx_counter_srcx_read(filp, ubuf, cnt, ppos, 0);
++}
++
++static ssize_t pp_ppx_counter_src1_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++      return pp_ppx_counter_srcx_read(filp, ubuf, cnt, ppos, 1);
++}
++
++static ssize_t pp_ppx_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++      return pp_ppx_counter_srcx_write(filp, ubuf, cnt, ppos, 0);
++}
++
++static ssize_t pp_ppx_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++      return pp_ppx_counter_srcx_write(filp, ubuf, cnt, ppos, 1);
++}
++
++static ssize_t pp_all_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++      return pp_all_counter_srcx_write(filp, ubuf, cnt, ppos, 0);
++}
++
++static ssize_t pp_all_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++      return pp_all_counter_srcx_write(filp, ubuf, cnt, ppos, 1);
++}
++
++static const struct file_operations pp_ppx_counter_src0_fops = {
++      .owner = THIS_MODULE,
++      .open  = open_copy_private_data,
++      .read  = pp_ppx_counter_src0_read,
++      .write = pp_ppx_counter_src0_write,
++};
++
++static const struct file_operations pp_ppx_counter_src1_fops = {
++      .owner = THIS_MODULE,
++      .open  = open_copy_private_data,
++      .read  = pp_ppx_counter_src1_read,
++      .write = pp_ppx_counter_src1_write,
++};
++
++static const struct file_operations pp_all_counter_src0_fops = {
++      .owner = THIS_MODULE,
++      .write = pp_all_counter_src0_write,
++};
++
++static const struct file_operations pp_all_counter_src1_fops = {
++      .owner = THIS_MODULE,
++      .write = pp_all_counter_src1_write,
++};
++
++static ssize_t l2_l2x_counter_srcx_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id)
++{
++      char buf[64];
++      int r;
++      u32 val;
++      struct mali_l2_cache_core *l2_core = (struct mali_l2_cache_core *)filp->private_data;
++
++      if (0 == src_id)
++      {
++              val = mali_l2_cache_core_get_counter_src0(l2_core);
++      }
++      else
++      {
++              val = mali_l2_cache_core_get_counter_src1(l2_core);
++      }
++
++      if (MALI_HW_CORE_NO_COUNTER == val)
++      {
++              r = sprintf(buf, "-1\n");
++      }
++      else
++      {
++              r = sprintf(buf, "%u\n", val);
++      }
++      return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
++}
++
++static ssize_t l2_l2x_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id)
++{
++      struct mali_l2_cache_core *l2_core = (struct mali_l2_cache_core *)filp->private_data;
++      char buf[64];
++      long val;
++      int ret;
++
++      if (cnt >= sizeof(buf))
++      {
++              return -EINVAL;
++      }
++
++      if (copy_from_user(&buf, ubuf, cnt))
++      {
++              return -EFAULT;
++      }
++
++      buf[cnt] = 0;
++
++      ret = strict_strtol(buf, 10, &val);
++      if (ret < 0)
++      {
++              return ret;
++      }
++
++      if (val < 0)
++      {
++              /* any negative input will disable counter */
++              val = MALI_HW_CORE_NO_COUNTER;
++      }
++
++      if (0 == src_id)
++      {
++              if (MALI_TRUE != mali_l2_cache_core_set_counter_src0(l2_core, (u32)val))
++              {
++                      return 0;
++              }
++      }
++      else
++      {
++              if (MALI_TRUE != mali_l2_cache_core_set_counter_src1(l2_core, (u32)val))
++              {
++                      return 0;
++              }
++      }
++
++      *ppos += cnt;
++      return cnt;
++}
++
++static ssize_t l2_all_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id)
++{
++      char buf[64];
++      long val;
++      int ret;
++      u32 l2_id;
++      struct mali_l2_cache_core *l2_cache;
++
++      if (cnt >= sizeof(buf))
++      {
++              return -EINVAL;
++      }
++
++      if (copy_from_user(&buf, ubuf, cnt))
++      {
++              return -EFAULT;
++      }
++
++      buf[cnt] = 0;
++
++      ret = strict_strtol(buf, 10, &val);
++      if (ret < 0)
++      {
++              return ret;
++      }
++
++      if (val < 0)
++      {
++              /* any negative input will disable counter */
++              val = MALI_HW_CORE_NO_COUNTER;
++      }
++
++      l2_id = 0;
++      l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id);
++      while (NULL != l2_cache)
++      {
++              if (0 == src_id)
++              {
++                      if (MALI_TRUE != mali_l2_cache_core_set_counter_src0(l2_cache, (u32)val))
++                      {
++                              return 0;
++                      }
++              }
++              else
++              {
++                      if (MALI_TRUE != mali_l2_cache_core_set_counter_src1(l2_cache, (u32)val))
++                      {
++                              return 0;
++                      }
++              }
++
++              /* try next L2 */
++              l2_id++;
++              l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id);
++      }
++
++      *ppos += cnt;
++      return cnt;
++}
++
++static ssize_t l2_l2x_counter_src0_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++      return l2_l2x_counter_srcx_read(filp, ubuf, cnt, ppos, 0);
++}
++
++static ssize_t l2_l2x_counter_src1_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++      return l2_l2x_counter_srcx_read(filp, ubuf, cnt, ppos, 1);
++}
++
++static ssize_t l2_l2x_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++      return l2_l2x_counter_srcx_write(filp, ubuf, cnt, ppos, 0);
++}
++
++static ssize_t l2_l2x_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++      return l2_l2x_counter_srcx_write(filp, ubuf, cnt, ppos, 1);
++}
++
++static ssize_t l2_all_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++      return l2_all_counter_srcx_write(filp, ubuf, cnt, ppos, 0);
++}
++
++static ssize_t l2_all_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++      return l2_all_counter_srcx_write(filp, ubuf, cnt, ppos, 1);
++}
++
++static const struct file_operations l2_l2x_counter_src0_fops = {
++      .owner = THIS_MODULE,
++      .open  = open_copy_private_data,
++      .read  = l2_l2x_counter_src0_read,
++      .write = l2_l2x_counter_src0_write,
++};
++
++static const struct file_operations l2_l2x_counter_src1_fops = {
++      .owner = THIS_MODULE,
++      .open  = open_copy_private_data,
++      .read  = l2_l2x_counter_src1_read,
++      .write = l2_l2x_counter_src1_write,
++};
++
++static const struct file_operations l2_all_counter_src0_fops = {
++      .owner = THIS_MODULE,
++      .write = l2_all_counter_src0_write,
++};
++
++static const struct file_operations l2_all_counter_src1_fops = {
++      .owner = THIS_MODULE,
++      .write = l2_all_counter_src1_write,
++};
++
++static ssize_t power_always_on_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++      unsigned long val;
++      int ret;
++      char buf[32];
++
++      cnt = min(cnt, sizeof(buf) - 1);
++      if (copy_from_user(buf, ubuf, cnt))
++      {
++              return -EFAULT;
++      }
++      buf[cnt] = '\0';
++
++      ret = strict_strtoul(buf, 10, &val);
++      if (0 != ret)
++      {
++              return ret;
++      }
++
++      /* Update setting (not exactly thread safe) */
++      if (1 == val && MALI_FALSE == power_always_on_enabled)
++      {
++              power_always_on_enabled = MALI_TRUE;
++              _mali_osk_pm_dev_ref_add();
++      }
++      else if (0 == val && MALI_TRUE == power_always_on_enabled)
++      {
++              power_always_on_enabled = MALI_FALSE;
++              _mali_osk_pm_dev_ref_dec();
++      }
++
++      *ppos += cnt;
++      return cnt;
++}
++
++static ssize_t power_always_on_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++      if (MALI_TRUE == power_always_on_enabled)
++      {
++              return simple_read_from_buffer(ubuf, cnt, ppos, "1\n", 2);
++      }
++      else
++      {
++              return simple_read_from_buffer(ubuf, cnt, ppos, "0\n", 2);
++      }
++}
++
++static const struct file_operations power_always_on_fops = {
++      .owner = THIS_MODULE,
++      .read  = power_always_on_read,
++      .write = power_always_on_write,
++};
++
++static ssize_t power_power_events_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++
++      if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_SUSPEND],strlen(mali_power_events[_MALI_DEVICE_SUSPEND])))
++      {
++              mali_pm_os_suspend();
++              /* @@@@ assuming currently suspend is successful later on to tune as per previous*/
++              virtual_power_status_register =1;
++
++      }
++      else if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_RESUME],strlen(mali_power_events[_MALI_DEVICE_RESUME])))
++      {
++              mali_pm_os_resume();
++
++              /* @@@@ assuming currently resume is successful later on to tune as per previous */
++              virtual_power_status_register = 1;
++      }
++      else if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_DVFS_PAUSE],strlen(mali_power_events[_MALI_DEVICE_DVFS_PAUSE])))
++      {
++              mali_bool power_on;
++              mali_dev_pause(&power_on);
++              if (!power_on)
++              {
++                      virtual_power_status_register = 2;
++                      mali_dev_resume();
++              }
++              else
++              {
++                      /*  @@@@ assuming currently resume is successful later on to tune as per previous */
++                      virtual_power_status_register =1;
++              }
++      }
++      else if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_DVFS_RESUME],strlen(mali_power_events[_MALI_DEVICE_DVFS_RESUME])))
++      {
++              mali_dev_resume();
++              /*  @@@@ assuming currently resume is successful later on to tune as per previous */
++              virtual_power_status_register = 1;
++      }
++      *ppos += cnt;
++      sprintf(pwr_buf, "%d",virtual_power_status_register);
++      return cnt;
++}
++
++static ssize_t power_power_events_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++      return simple_read_from_buffer(ubuf, cnt, ppos, pwr_buf, POWER_BUFFER_SIZE);
++}
++
++static loff_t power_power_events_seek(struct file *file, loff_t offset, int orig)
++{
++      file->f_pos = offset;
++        return 0;
++}
++
++static const struct file_operations power_power_events_fops = {
++      .owner = THIS_MODULE,
++      .read  = power_power_events_read,
++      .write = power_power_events_write,
++      .llseek = power_power_events_seek,
++};
++
++#if MALI_STATE_TRACKING
++static int mali_seq_internal_state_show(struct seq_file *seq_file, void *v)
++{
++      u32 len = 0;
++      u32 size;
++      char *buf;
++
++      size = seq_get_buf(seq_file, &buf);
++
++      if(!size)
++      {
++                      return -ENOMEM;
++      }
++
++      /* Create the internal state dump. */
++      len  = snprintf(buf+len, size-len, "Mali device driver %s\n", SVN_REV_STRING);
++      len += snprintf(buf+len, size-len, "License: %s\n\n", MALI_KERNEL_LINUX_LICENSE);
++
++      len += _mali_kernel_core_dump_state(buf + len, size - len);
++
++      seq_commit(seq_file, len);
++
++      return 0;
++}
++
++static int mali_seq_internal_state_open(struct inode *inode, struct file *file)
++{
++      return single_open(file, mali_seq_internal_state_show, NULL);
++}
++
++static const struct file_operations mali_seq_internal_state_fops = {
++      .owner = THIS_MODULE,
++      .open = mali_seq_internal_state_open,
++      .read = seq_read,
++      .llseek = seq_lseek,
++      .release = single_release,
++};
++#endif /* MALI_STATE_TRACKING */
++
++#if defined(CONFIG_MALI400_INTERNAL_PROFILING)
++static ssize_t profiling_record_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++      char buf[64];
++      int r;
++
++      r = sprintf(buf, "%u\n", _mali_internal_profiling_is_recording() ? 1 : 0);
++      return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
++}
++
++static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++      char buf[64];
++      unsigned long val;
++      int ret;
++
++      if (cnt >= sizeof(buf))
++      {
++              return -EINVAL;
++      }
++
++      if (copy_from_user(&buf, ubuf, cnt))
++      {
++              return -EFAULT;
++      }
++
++      buf[cnt] = 0;
++
++      ret = strict_strtoul(buf, 10, &val);
++      if (ret < 0)
++      {
++              return ret;
++      }
++
++      if (val != 0)
++      {
++              u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* This can be made configurable at a later stage if we need to */
++
++              /* check if we are already recording */
++              if (MALI_TRUE == _mali_internal_profiling_is_recording())
++              {
++                      MALI_DEBUG_PRINT(3, ("Recording of profiling events already in progress\n"));
++                      return -EFAULT;
++              }
++
++              /* check if we need to clear out an old recording first */
++              if (MALI_TRUE == _mali_internal_profiling_have_recording())
++              {
++                      if (_MALI_OSK_ERR_OK != _mali_internal_profiling_clear())
++                      {
++                              MALI_DEBUG_PRINT(3, ("Failed to clear existing recording of profiling events\n"));
++                              return -EFAULT;
++                      }
++              }
++
++              /* start recording profiling data */
++              if (_MALI_OSK_ERR_OK != _mali_internal_profiling_start(&limit))
++              {
++                      MALI_DEBUG_PRINT(3, ("Failed to start recording of profiling events\n"));
++                      return -EFAULT;
++              }
++
++              MALI_DEBUG_PRINT(3, ("Profiling recording started (max %u events)\n", limit));
++      }
++      else
++      {
++              /* stop recording profiling data */
++              u32 count = 0;
++              if (_MALI_OSK_ERR_OK != _mali_internal_profiling_stop(&count))
++              {
++                      MALI_DEBUG_PRINT(2, ("Failed to stop recording of profiling events\n"));
++                      return -EFAULT;
++              }
++              
++              MALI_DEBUG_PRINT(2, ("Profiling recording stopped (recorded %u events)\n", count));
++      }
++
++      *ppos += cnt;
++      return cnt;
++}
++
++static const struct file_operations profiling_record_fops = {
++      .owner = THIS_MODULE,
++      .read  = profiling_record_read,
++      .write = profiling_record_write,
++};
++
++static void *profiling_events_start(struct seq_file *s, loff_t *pos)
++{
++      loff_t *spos;
++
++      /* check if we have data avaiable */
++      if (MALI_TRUE != _mali_internal_profiling_have_recording())
++      {
++              return NULL;
++      }
++
++      spos = kmalloc(sizeof(loff_t), GFP_KERNEL);
++      if (NULL == spos)
++      {
++              return NULL;
++      }
++
++      *spos = *pos;
++      return spos;
++}
++
++static void *profiling_events_next(struct seq_file *s, void *v, loff_t *pos)
++{
++      loff_t *spos = v;
++
++      /* check if we have data avaiable */
++      if (MALI_TRUE != _mali_internal_profiling_have_recording())
++      {
++              return NULL;
++      }
++
++      /* check if the next entry actually is avaiable */
++      if (_mali_internal_profiling_get_count() <= (u32)(*spos + 1))
++      {
++              return NULL;
++      }
++
++      *pos = ++*spos;
++      return spos;
++}
++
++static void profiling_events_stop(struct seq_file *s, void *v)
++{
++      kfree(v);
++}
++
++static int profiling_events_show(struct seq_file *seq_file, void *v)
++{
++      loff_t *spos = v;
++      u32 index;
++      u64 timestamp;
++      u32 event_id;
++      u32 data[5];
++
++      index = (u32)*spos;
++
++      /* Retrieve all events */
++      if (_MALI_OSK_ERR_OK == _mali_internal_profiling_get_event(index, &timestamp, &event_id, data))
++      {
++              seq_printf(seq_file, "%llu %u %u %u %u %u %u\n", timestamp, event_id, data[0], data[1], data[2], data[3], data[4]);
++              return 0;
++      }
++
++      return 0;
++}
++
++static int profiling_events_show_human_readable(struct seq_file *seq_file, void *v)
++{
++      #define MALI_EVENT_ID_IS_HW(event_id) (((event_id & 0x00FF0000) >= MALI_PROFILING_EVENT_CHANNEL_GP0) && ((event_id & 0x00FF0000) <= MALI_PROFILING_EVENT_CHANNEL_PP7))
++
++      static u64 start_time = 0;
++      loff_t *spos = v;
++      u32 index;
++      u64 timestamp;
++      u32 event_id;
++      u32 data[5];
++
++      index = (u32)*spos;
++
++      /* Retrieve all events */
++      if (_MALI_OSK_ERR_OK == _mali_internal_profiling_get_event(index, &timestamp, &event_id, data))
++      {
++              seq_printf(seq_file, "%llu %u %u %u %u %u %u # ", timestamp, event_id, data[0], data[1], data[2], data[3], data[4]);
++
++              if (0 == index)
++              {
++                      start_time = timestamp;
++              }
++
++              seq_printf(seq_file, "[%06u] ", index);
++
++              switch(event_id & 0x0F000000)
++              {
++              case MALI_PROFILING_EVENT_TYPE_SINGLE:
++                      seq_printf(seq_file, "SINGLE | ");
++                      break;
++              case MALI_PROFILING_EVENT_TYPE_START:
++                      seq_printf(seq_file, "START | ");
++                      break;
++              case MALI_PROFILING_EVENT_TYPE_STOP:
++                      seq_printf(seq_file, "STOP | ");
++                      break;
++              case MALI_PROFILING_EVENT_TYPE_SUSPEND:
++                      seq_printf(seq_file, "SUSPEND | ");
++                      break;
++              case MALI_PROFILING_EVENT_TYPE_RESUME:
++                      seq_printf(seq_file, "RESUME | ");
++                      break;
++              default:
++                      seq_printf(seq_file, "0x%01X | ", (event_id & 0x0F000000) >> 24);
++                      break;
++              }
++
++              switch(event_id & 0x00FF0000)
++              {
++              case MALI_PROFILING_EVENT_CHANNEL_SOFTWARE:
++                      seq_printf(seq_file, "SW | ");
++                      break;
++              case MALI_PROFILING_EVENT_CHANNEL_GP0:
++                      seq_printf(seq_file, "GP0 | ");
++                      break;
++              case MALI_PROFILING_EVENT_CHANNEL_PP0:
++                      seq_printf(seq_file, "PP0 | ");
++                      break;
++              case MALI_PROFILING_EVENT_CHANNEL_PP1:
++                      seq_printf(seq_file, "PP1 | ");
++                      break;
++              case MALI_PROFILING_EVENT_CHANNEL_PP2:
++                      seq_printf(seq_file, "PP2 | ");
++                      break;
++              case MALI_PROFILING_EVENT_CHANNEL_PP3:
++                      seq_printf(seq_file, "PP3 | ");
++                      break;
++              case MALI_PROFILING_EVENT_CHANNEL_PP4:
++                      seq_printf(seq_file, "PP4 | ");
++                      break;
++              case MALI_PROFILING_EVENT_CHANNEL_PP5:
++                      seq_printf(seq_file, "PP5 | ");
++                      break;
++              case MALI_PROFILING_EVENT_CHANNEL_PP6:
++                      seq_printf(seq_file, "PP6 | ");
++                      break;
++              case MALI_PROFILING_EVENT_CHANNEL_PP7:
++                      seq_printf(seq_file, "PP7 | ");
++                      break;
++              case MALI_PROFILING_EVENT_CHANNEL_GPU:
++                      seq_printf(seq_file, "GPU | ");
++                      break;
++              default:
++                      seq_printf(seq_file, "0x%02X | ", (event_id & 0x00FF0000) >> 16);
++                      break;
++              }
++
++              if (MALI_EVENT_ID_IS_HW(event_id))
++              {
++                      if (((event_id & 0x0F000000) == MALI_PROFILING_EVENT_TYPE_START) || ((event_id & 0x0F000000) == MALI_PROFILING_EVENT_TYPE_STOP))
++                      {
++                              switch(event_id & 0x0000FFFF)
++                              {
++                              case MALI_PROFILING_EVENT_REASON_START_STOP_HW_PHYSICAL:
++                                      seq_printf(seq_file, "PHYSICAL | ");
++                                      break;
++                              case MALI_PROFILING_EVENT_REASON_START_STOP_HW_VIRTUAL:
++                                      seq_printf(seq_file, "VIRTUAL | ");
++                                      break;
++                              default:
++                                      seq_printf(seq_file, "0x%04X | ", event_id & 0x0000FFFF);
++                                      break;
++                              }
++                      }
++                      else
++                      {
++                              seq_printf(seq_file, "0x%04X | ", event_id & 0x0000FFFF);
++                      }
++              }
++              else
++              {
++                      seq_printf(seq_file, "0x%04X | ", event_id & 0x0000FFFF);
++              }
++
++              seq_printf(seq_file, "T0 + 0x%016llX\n", timestamp - start_time);
++
++              return 0;
++      }
++
++      return 0;
++}
++
++static const struct seq_operations profiling_events_seq_ops = {
++      .start = profiling_events_start,
++      .next  = profiling_events_next,
++      .stop  = profiling_events_stop,
++      .show  = profiling_events_show
++};
++
++static int profiling_events_open(struct inode *inode, struct file *file)
++{
++      return seq_open(file, &profiling_events_seq_ops);
++}
++
++static const struct file_operations profiling_events_fops = {
++      .owner = THIS_MODULE,
++      .open = profiling_events_open,
++      .read = seq_read,
++      .llseek = seq_lseek,
++      .release = seq_release,
++};
++
++static const struct seq_operations profiling_events_human_readable_seq_ops = {
++      .start = profiling_events_start,
++      .next  = profiling_events_next,
++      .stop  = profiling_events_stop,
++      .show  = profiling_events_show_human_readable
++};
++
++static int profiling_events_human_readable_open(struct inode *inode, struct file *file)
++{
++      return seq_open(file, &profiling_events_human_readable_seq_ops);
++}
++
++static const struct file_operations profiling_events_human_readable_fops = {
++      .owner = THIS_MODULE,
++      .open = profiling_events_human_readable_open,
++      .read = seq_read,
++      .llseek = seq_lseek,
++      .release = seq_release,
++};
++
++#endif
++
++static ssize_t memory_used_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++      char buf[64];
++      size_t r;
++      u32 mem = _mali_ukk_report_memory_usage();
++
++      r = snprintf(buf, 64, "%u\n", mem);
++      return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
++}
++
++static const struct file_operations memory_usage_fops = {
++      .owner = THIS_MODULE,
++      .read = memory_used_read,
++};
++
++static ssize_t utilization_gp_pp_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++      char buf[64];
++      size_t r;
++      u32 uval= _mali_ukk_utilization_gp_pp();
++
++      r = snprintf(buf, 64, "%u\n", uval);
++      return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
++}
++
++static ssize_t utilization_gp_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++      char buf[64];
++      size_t r;
++      u32 uval= _mali_ukk_utilization_gp();
++
++      r = snprintf(buf, 64, "%u\n", uval);
++      return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
++}
++
++static ssize_t utilization_pp_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++      char buf[64];
++      size_t r;
++      u32 uval= _mali_ukk_utilization_pp();
++
++      r = snprintf(buf, 64, "%u\n", uval);
++      return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
++}
++
++
++static const struct file_operations utilization_gp_pp_fops = {
++      .owner = THIS_MODULE,
++      .read = utilization_gp_pp_read,
++};
++
++static const struct file_operations utilization_gp_fops = {
++      .owner = THIS_MODULE,
++      .read = utilization_gp_read,
++};
++
++static const struct file_operations utilization_pp_fops = {
++      .owner = THIS_MODULE,
++      .read = utilization_pp_read,
++};
++
++static ssize_t user_settings_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++      unsigned long val;
++      int ret;
++      _mali_uk_user_setting_t setting;
++      char buf[32];
++
++      cnt = min(cnt, sizeof(buf) - 1);
++      if (copy_from_user(buf, ubuf, cnt))
++      {
++              return -EFAULT;
++      }
++      buf[cnt] = '\0';
++
++      ret = strict_strtoul(buf, 10, &val);
++      if (0 != ret)
++      {
++              return ret;
++      }
++
++      /* Update setting */
++      setting = (_mali_uk_user_setting_t)(filp->private_data);
++      mali_set_user_setting(setting, val);
++
++      *ppos += cnt;
++      return cnt;
++}
++
++static ssize_t user_settings_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++      char buf[64];
++      size_t r;
++      u32 value;
++      _mali_uk_user_setting_t setting;
++
++      setting = (_mali_uk_user_setting_t)(filp->private_data);
++      value = mali_get_user_setting(setting);
++
++      r = snprintf(buf, 64, "%u\n", value);
++      return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
++}
++
++static const struct file_operations user_settings_fops = {
++      .owner = THIS_MODULE,
++      .open = open_copy_private_data,
++      .read = user_settings_read,
++      .write = user_settings_write,
++};
++
++static int mali_sysfs_user_settings_register(void)
++{
++      struct dentry *mali_user_settings_dir = debugfs_create_dir("userspace_settings", mali_debugfs_dir);
++
++      if (mali_user_settings_dir != NULL)
++      {
++              int i;
++              for (i = 0; i < _MALI_UK_USER_SETTING_MAX; i++)
++              {
++                      debugfs_create_file(_mali_uk_user_setting_descriptions[i], 0600, mali_user_settings_dir, (void*)i, &user_settings_fops);
++              }
++      }
++
++      return 0;
++}
++
++int mali_sysfs_register(const char *mali_dev_name)
++{
++      mali_debugfs_dir = debugfs_create_dir(mali_dev_name, NULL);
++      if(ERR_PTR(-ENODEV) == mali_debugfs_dir)
++      {
++              /* Debugfs not supported. */
++              mali_debugfs_dir = NULL;
++      }
++      else
++      {
++              if(NULL != mali_debugfs_dir)
++              {
++                      /* Debugfs directory created successfully; create files now */
++                      struct dentry *mali_power_dir;
++                      struct dentry *mali_gp_dir;
++                      struct dentry *mali_pp_dir;
++                      struct dentry *mali_l2_dir;
++#if defined(CONFIG_MALI400_INTERNAL_PROFILING)
++                      struct dentry *mali_profiling_dir;
++#endif
++
++                      mali_power_dir = debugfs_create_dir("power", mali_debugfs_dir);
++                      if (mali_power_dir != NULL)
++                      {
++                              debugfs_create_file("always_on", 0400, mali_power_dir, NULL, &power_always_on_fops);
++                              debugfs_create_file("power_events", 0400, mali_power_dir, NULL, &power_power_events_fops);
++                      }
++
++                      mali_gp_dir = debugfs_create_dir("gp", mali_debugfs_dir);
++                      if (mali_gp_dir != NULL)
++                      {
++                              struct dentry *mali_gp_all_dir;
++                              u32 num_groups;
++                              int i;
++
++                              mali_gp_all_dir = debugfs_create_dir("all", mali_gp_dir);
++                              if (mali_gp_all_dir != NULL)
++                              {
++                                      debugfs_create_file("counter_src0", 0400, mali_gp_all_dir, NULL, &gp_all_counter_src0_fops);
++                                      debugfs_create_file("counter_src1", 0400, mali_gp_all_dir, NULL, &gp_all_counter_src1_fops);
++                              }
++
++                              num_groups = mali_group_get_glob_num_groups();
++                              for (i = 0; i < num_groups; i++)
++                              {
++                                      struct mali_group *group = mali_group_get_glob_group(i);
++
++                                      struct mali_gp_core *gp_core = mali_group_get_gp_core(group);
++                                      if (NULL != gp_core)
++                                      {
++                                              struct dentry *mali_gp_gpx_dir;
++                                              mali_gp_gpx_dir = debugfs_create_dir("gp0", mali_gp_dir);
++                                              if (NULL != mali_gp_gpx_dir)
++                                              {
++                                                      debugfs_create_file("counter_src0", 0600, mali_gp_gpx_dir, gp_core, &gp_gpx_counter_src0_fops);
++                                                      debugfs_create_file("counter_src1", 0600, mali_gp_gpx_dir, gp_core, &gp_gpx_counter_src1_fops);
++                                              }
++                                              break; /* no need to look for any other GP cores */
++                                      }
++
++                              }
++                      }
++
++                      mali_pp_dir = debugfs_create_dir("pp", mali_debugfs_dir);
++                      if (mali_pp_dir != NULL)
++                      {
++                              struct dentry *mali_pp_all_dir;
++                              u32 num_groups;
++                              int i;
++
++                              mali_pp_all_dir = debugfs_create_dir("all", mali_pp_dir);
++                              if (mali_pp_all_dir != NULL)
++                              {
++                                      debugfs_create_file("counter_src0", 0400, mali_pp_all_dir, NULL, &pp_all_counter_src0_fops);
++                                      debugfs_create_file("counter_src1", 0400, mali_pp_all_dir, NULL, &pp_all_counter_src1_fops);
++                              }
++
++                              num_groups = mali_group_get_glob_num_groups();
++                              for (i = 0; i < num_groups; i++)
++                              {
++                                      struct mali_group *group = mali_group_get_glob_group(i);
++
++                                      struct mali_pp_core *pp_core = mali_group_get_pp_core(group);
++                                      if (NULL != pp_core)
++                                      {
++                                              char buf[16];
++                                              struct dentry *mali_pp_ppx_dir;
++                                              _mali_osk_snprintf(buf, sizeof(buf), "pp%u", mali_pp_core_get_id(pp_core));
++                                              mali_pp_ppx_dir = debugfs_create_dir(buf, mali_pp_dir);
++                                              if (NULL != mali_pp_ppx_dir)
++                                              {
++                                                      debugfs_create_file("counter_src0", 0600, mali_pp_ppx_dir, pp_core, &pp_ppx_counter_src0_fops);
++                                                      debugfs_create_file("counter_src1", 0600, mali_pp_ppx_dir, pp_core, &pp_ppx_counter_src1_fops);
++                                              }
++                                      }
++                              }
++                      }
++
++                      mali_l2_dir = debugfs_create_dir("l2", mali_debugfs_dir);
++                      if (mali_l2_dir != NULL)
++                      {
++                              struct dentry *mali_l2_all_dir;
++                              u32 l2_id;
++                              struct mali_l2_cache_core *l2_cache;
++
++                              mali_l2_all_dir = debugfs_create_dir("all", mali_l2_dir);
++                              if (mali_l2_all_dir != NULL)
++                              {
++                                      debugfs_create_file("counter_src0", 0400, mali_l2_all_dir, NULL, &l2_all_counter_src0_fops);
++                                      debugfs_create_file("counter_src1", 0400, mali_l2_all_dir, NULL, &l2_all_counter_src1_fops);
++                              }
++
++                              l2_id = 0;
++                              l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id);
++                              while (NULL != l2_cache)
++                              {
++                                      char buf[16];
++                                      struct dentry *mali_l2_l2x_dir;
++                                      _mali_osk_snprintf(buf, sizeof(buf), "l2%u", l2_id);
++                                      mali_l2_l2x_dir = debugfs_create_dir(buf, mali_l2_dir);
++                                      if (NULL != mali_l2_l2x_dir)
++                                      {
++                                              debugfs_create_file("counter_src0", 0600, mali_l2_l2x_dir, l2_cache, &l2_l2x_counter_src0_fops);
++                                              debugfs_create_file("counter_src1", 0600, mali_l2_l2x_dir, l2_cache, &l2_l2x_counter_src1_fops);
++                                      }
++
++                                      /* try next L2 */
++                                      l2_id++;
++                                      l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id);
++                              }
++                      }
++
++                      debugfs_create_file("memory_usage", 0400, mali_debugfs_dir, NULL, &memory_usage_fops);
++
++                      debugfs_create_file("utilization_gp_pp", 0400, mali_debugfs_dir, NULL, &utilization_gp_pp_fops);
++                      debugfs_create_file("utilization_gp", 0400, mali_debugfs_dir, NULL, &utilization_gp_fops);
++                      debugfs_create_file("utilization_pp", 0400, mali_debugfs_dir, NULL, &utilization_pp_fops);
++
++#if defined(CONFIG_MALI400_INTERNAL_PROFILING)
++                      mali_profiling_dir = debugfs_create_dir("profiling", mali_debugfs_dir);
++                      if (mali_profiling_dir != NULL)
++                      {
++                              struct dentry *mali_profiling_proc_dir = debugfs_create_dir("proc", mali_profiling_dir);
++                              if (mali_profiling_proc_dir != NULL)
++                              {
++                                      struct dentry *mali_profiling_proc_default_dir = debugfs_create_dir("default", mali_profiling_proc_dir);
++                                      if (mali_profiling_proc_default_dir != NULL)
++                                      {
++                                              debugfs_create_file("enable", 0600, mali_profiling_proc_default_dir, (void*)_MALI_UK_USER_SETTING_SW_EVENTS_ENABLE, &user_settings_fops);
++                                      }
++                              }
++                              debugfs_create_file("record", 0600, mali_profiling_dir, NULL, &profiling_record_fops);
++                              debugfs_create_file("events", 0400, mali_profiling_dir, NULL, &profiling_events_fops);
++                              debugfs_create_file("events_human_readable", 0400, mali_profiling_dir, NULL, &profiling_events_human_readable_fops);
++                      }
++#endif
++
++#if MALI_STATE_TRACKING
++                      debugfs_create_file("state_dump", 0400, mali_debugfs_dir, NULL, &mali_seq_internal_state_fops);
++#endif
++
++                      if (mali_sysfs_user_settings_register())
++                      {
++                              /* Failed to create the debugfs entries for the user settings DB. */
++                              MALI_DEBUG_PRINT(2, ("Failed to create user setting debugfs files. Ignoring...\n"));
++                      }
++              }
++      }
++
++      /* Success! */
++      return 0;
++}
++
++int mali_sysfs_unregister(void)
++{
++      if(NULL != mali_debugfs_dir)
++      {
++              debugfs_remove_recursive(mali_debugfs_dir);
++      }
++      return 0;
++}
++
++#else
++
++/* Dummy implementations for non-GPL */
++
++int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev_name)
++{
++      return 0;
++}
++
++int mali_sysfs_unregister(void)
++{
++      return 0;
++}
++
++
++#endif
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_kernel_sysfs.h b/drivers/gpu/arm/mali400/mali/linux/mali_kernel_sysfs.h
+new file mode 100644
+index 0000000..31e7bc6
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_kernel_sysfs.h
+@@ -0,0 +1,30 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_KERNEL_SYSFS_H__
++#define __MALI_KERNEL_SYSFS_H__
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif
++
++#include <linux/device.h>
++
++#define MALI_PROC_DIR "driver/mali"
++
++int mali_sysfs_register(const char *mali_dev_name);
++int mali_sysfs_unregister(void);
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* __MALI_KERNEL_LINUX_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_linux_pm_testsuite.h b/drivers/gpu/arm/mali400/mali/linux/mali_linux_pm_testsuite.h
+new file mode 100644
+index 0000000..db57d21
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_linux_pm_testsuite.h
+@@ -0,0 +1,32 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++#ifndef __MALI_LINUX_PM_TESTSUITE_H__
++#define __MALI_LINUX_PM_TESTSUITE_H__
++
++#if MALI_POWER_MGMT_TEST_SUITE && defined(CONFIG_PM)
++
++typedef enum
++{
++        _MALI_DEVICE_PMM_TIMEOUT_EVENT,
++        _MALI_DEVICE_PMM_JOB_SCHEDULING_EVENTS,
++      _MALI_DEVICE_PMM_REGISTERED_CORES,
++        _MALI_DEVICE_MAX_PMM_EVENTS
++
++} _mali_device_pmm_recording_events;
++
++extern unsigned int mali_timeout_event_recording_on;
++extern unsigned int mali_job_scheduling_events_recording_on;
++extern unsigned int pwr_mgmt_status_reg;
++extern unsigned int is_mali_pmm_testsuite_enabled;
++extern unsigned int is_mali_pmu_present;
++
++#endif /* MALI_POWER_MGMT_TEST_SUITE && defined(CONFIG_PM) */
++
++#endif /* __MALI_LINUX_PM_TESTSUITE_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_linux_trace.h b/drivers/gpu/arm/mali400/mali/linux/mali_linux_trace.h
+new file mode 100644
+index 0000000..915240a
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_linux_trace.h
+@@ -0,0 +1,126 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#if !defined (MALI_LINUX_TRACE_H) || defined (TRACE_HEADER_MULTI_READ)
++#define MALI_LINUX_TRACE_H
++
++#include <linux/types.h>
++
++#include <linux/stringify.h>
++#include <linux/tracepoint.h>
++
++#undef  TRACE_SYSTEM
++#define TRACE_SYSTEM mali
++#define TRACE_SYSTEM_STRING __stringfy(TRACE_SYSTEM)
++
++#define TRACE_INCLUDE_PATH .
++#define TRACE_INCLUDE_FILE mali_linux_trace
++
++/**
++ * Define the tracepoint used to communicate the status of a GPU. Called 
++ * when a GPU turns on or turns off.
++ *
++ * @param event_id The type of the event. This parameter is a bitfield 
++ *  encoding the type of the event.
++ *
++ * @param d0 First data parameter.
++ * @param d1 Second data parameter.
++ * @param d2 Third data parameter.
++ * @param d3 Fourth data parameter.
++ * @param d4 Fifth data parameter.
++ */
++TRACE_EVENT(mali_timeline_event,
++
++    TP_PROTO(unsigned int event_id, unsigned int d0, unsigned int d1, 
++        unsigned int d2, unsigned int d3, unsigned int d4),
++
++    TP_ARGS(event_id, d0, d1, d2, d3, d4),
++
++    TP_STRUCT__entry(
++        __field(unsigned int, event_id)
++        __field(unsigned int, d0)
++        __field(unsigned int, d1)
++        __field(unsigned int, d2)
++        __field(unsigned int, d3)
++        __field(unsigned int, d4)
++    ),
++
++    TP_fast_assign(
++        __entry->event_id = event_id;
++        __entry->d0 = d0;
++        __entry->d1 = d1;
++        __entry->d2 = d2;
++        __entry->d3 = d3;
++        __entry->d4 = d4;
++    ),
++
++    TP_printk("event=%d", __entry->event_id)
++);
++
++/**
++ * Define a tracepoint used to regsiter the value of a hardware counter.
++ * Hardware counters belonging to the vertex or fragment processor are
++ * reported via this tracepoint each frame, whilst L2 cache hardware
++ * counters are reported continuously.
++ *
++ * @param counter_id The counter ID.
++ * @param value The value of the counter.
++ */
++TRACE_EVENT(mali_hw_counter,
++
++    TP_PROTO(unsigned int counter_id, unsigned int value),
++
++    TP_ARGS(counter_id, value),
++
++    TP_STRUCT__entry(
++        __field(unsigned int, counter_id)
++        __field(unsigned int, value)
++    ),
++
++    TP_fast_assign(
++        __entry->counter_id = counter_id;
++    ),
++
++    TP_printk("event %d = %d", __entry->counter_id, __entry->value)
++);
++
++/**
++ * Define a tracepoint used to send a bundle of software counters.
++ *
++ * @param counters The bundle of counters.
++ */
++TRACE_EVENT(mali_sw_counters,
++
++    TP_PROTO(pid_t pid, pid_t tid, void * surface_id, unsigned int * counters),
++
++    TP_ARGS(pid, tid, surface_id, counters),
++
++    TP_STRUCT__entry(
++            __field(pid_t, pid)
++            __field(pid_t, tid)
++            __field(void *, surface_id)
++            __field(unsigned int *, counters)
++    ),
++
++    TP_fast_assign(
++            __entry->pid = pid;
++                      __entry->tid = tid;
++                      __entry->surface_id = surface_id;
++                      __entry->counters = counters;
++    ),
++
++    TP_printk("counters were %s", __entry->counters == NULL? "NULL" : "not NULL")
++);
++
++#endif /* MALI_LINUX_TRACE_H */
++
++/* This part must exist outside the header guard. */
++#include <trace/define_trace.h>
++
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_osk_atomics.c b/drivers/gpu/arm/mali400/mali/linux/mali_osk_atomics.c
+new file mode 100644
+index 0000000..6c135c3
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_osk_atomics.c
+@@ -0,0 +1,55 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_osk_atomics.c
++ * Implementation of the OS abstraction layer for the kernel device driver
++ */
++
++#include "mali_osk.h"
++#include <asm/atomic.h>
++#include "mali_kernel_common.h"
++
++void _mali_osk_atomic_dec( _mali_osk_atomic_t *atom )
++{
++    atomic_dec((atomic_t *)&atom->u.val);
++}
++
++u32 _mali_osk_atomic_dec_return( _mali_osk_atomic_t *atom )
++{
++    return atomic_dec_return((atomic_t *)&atom->u.val);
++}
++
++void _mali_osk_atomic_inc( _mali_osk_atomic_t *atom )
++{
++    atomic_inc((atomic_t *)&atom->u.val);
++}
++
++u32 _mali_osk_atomic_inc_return( _mali_osk_atomic_t *atom )
++{
++    return atomic_inc_return((atomic_t *)&atom->u.val);
++}
++
++_mali_osk_errcode_t _mali_osk_atomic_init( _mali_osk_atomic_t *atom, u32 val )
++{
++    MALI_CHECK_NON_NULL(atom, _MALI_OSK_ERR_INVALID_ARGS);
++    atomic_set((atomic_t *)&atom->u.val, val);
++    return _MALI_OSK_ERR_OK;
++}
++
++u32 _mali_osk_atomic_read( _mali_osk_atomic_t *atom )
++{
++    return atomic_read((atomic_t *)&atom->u.val);
++}
++
++void _mali_osk_atomic_term( _mali_osk_atomic_t *atom )
++{
++    MALI_IGNORE(atom);
++}
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_osk_irq.c b/drivers/gpu/arm/mali400/mali/linux/mali_osk_irq.c
+new file mode 100644
+index 0000000..fbfe830
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_osk_irq.c
+@@ -0,0 +1,133 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_osk_irq.c
++ * Implementation of the OS abstraction layer for the kernel device driver
++ */
++
++#include <linux/slab.h>       /* For memory allocation */
++
++#include "mali_osk.h"
++#include "mali_kernel_common.h"
++#include "linux/interrupt.h"
++
++typedef struct _mali_osk_irq_t_struct
++{
++      u32 irqnum;
++      void *data;
++      _mali_osk_irq_uhandler_t uhandler;
++} mali_osk_irq_object_t;
++
++typedef irqreturn_t (*irq_handler_func_t)(int, void *, struct pt_regs *);
++static irqreturn_t irq_handler_upper_half (int port_name, void* dev_id ); /* , struct pt_regs *regs*/
++
++_mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandler, void *int_data, _mali_osk_irq_trigger_t trigger_func, _mali_osk_irq_ack_t ack_func, void *probe_data, const char *description )
++{
++      mali_osk_irq_object_t *irq_object;
++
++      irq_object = kmalloc(sizeof(mali_osk_irq_object_t), GFP_KERNEL);
++      if (NULL == irq_object)
++      {
++              return NULL;
++      }
++
++      if (-1 == irqnum)
++      {
++              /* Probe for IRQ */
++              if ( (NULL != trigger_func) && (NULL != ack_func) )
++              {
++                      unsigned long probe_count = 3;
++                      _mali_osk_errcode_t err;
++                      int irq;
++
++                      MALI_DEBUG_PRINT(2, ("Probing for irq\n"));
++
++                      do
++                      {
++                              unsigned long mask;
++
++                              mask = probe_irq_on();
++                              trigger_func(probe_data);
++
++                              _mali_osk_time_ubusydelay(5);
++
++                              irq = probe_irq_off(mask);
++                              err = ack_func(probe_data);
++                      }
++                      while (irq < 0 && (err == _MALI_OSK_ERR_OK) && probe_count--);
++
++                      if (irq < 0 || (_MALI_OSK_ERR_OK != err)) irqnum = -1;
++                      else irqnum = irq;
++              }
++              else irqnum = -1; /* no probe functions, fault */
++
++              if (-1 != irqnum)
++              {
++                      /* found an irq */
++                      MALI_DEBUG_PRINT(2, ("Found irq %d\n", irqnum));
++              }
++              else
++              {
++                      MALI_DEBUG_PRINT(2, ("Probe for irq failed\n"));
++              }
++      }
++
++      irq_object->irqnum = irqnum;
++      irq_object->uhandler = uhandler;
++      irq_object->data = int_data;
++
++      if (-1 == irqnum)
++      {
++              MALI_DEBUG_PRINT(2, ("No IRQ for core '%s' found during probe\n", description));
++              kfree(irq_object);
++              return NULL;
++      }
++
++      if (0 != request_irq(irqnum, irq_handler_upper_half, IRQF_SHARED, description, irq_object))
++      {
++              MALI_DEBUG_PRINT(2, ("Unable to install IRQ handler for core '%s'\n", description));
++              kfree(irq_object);
++              return NULL;
++      }
++
++      return irq_object;
++}
++
++void _mali_osk_irq_term( _mali_osk_irq_t *irq )
++{
++      mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq;
++      free_irq(irq_object->irqnum, irq_object);
++      kfree(irq_object);
++}
++
++
++/** This function is called directly in interrupt context from the OS just after
++ * the CPU get the hw-irq from mali, or other devices on the same IRQ-channel.
++ * It is registered one of these function for each mali core. When an interrupt
++ * arrives this function will be called equal times as registered mali cores.
++ * That means that we only check one mali core in one function call, and the
++ * core we check for each turn is given by the \a dev_id variable.
++ * If we detect an pending interrupt on the given core, we mask the interrupt
++ * out by settging the core's IRQ_MASK register to zero.
++ * Then we schedule the mali_core_irq_handler_bottom_half to run as high priority
++ * work queue job.
++ */
++static irqreturn_t irq_handler_upper_half (int port_name, void* dev_id ) /* , struct pt_regs *regs*/
++{
++      mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)dev_id;
++
++      if (irq_object->uhandler(irq_object->data) == _MALI_OSK_ERR_OK)
++      {
++              return IRQ_HANDLED;
++      }
++      return IRQ_NONE;
++}
++
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_osk_locks.c b/drivers/gpu/arm/mali400/mali/linux/mali_osk_locks.c
+new file mode 100644
+index 0000000..2ba952e
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_osk_locks.c
+@@ -0,0 +1,333 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_osk_locks.c
++ * Implemenation of the OS abstraction layer for the kernel device driver
++ */
++
++#include <linux/spinlock.h>
++#include <linux/rwsem.h>
++#include <linux/mutex.h>
++
++#include <linux/slab.h>
++
++#include "mali_osk.h"
++#include "mali_kernel_common.h"
++
++/* These are all the locks we implement: */
++typedef enum
++{
++      _MALI_OSK_INTERNAL_LOCKTYPE_SPIN,            /* Mutex, implicitly non-interruptable, use spin_lock/spin_unlock */
++      _MALI_OSK_INTERNAL_LOCKTYPE_SPIN_IRQ,        /* Mutex, IRQ version of spinlock, use spin_lock_irqsave/spin_unlock_irqrestore */
++      _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX,           /* Interruptable, use mutex_unlock()/down_interruptable() */
++      _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT,    /* Non-Interruptable, use mutex_unlock()/down() */
++      _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW, /* Non-interruptable, Reader/Writer, use {mutex_unlock,down}{read,write}() */
++
++      /* Linux supports, but we do not support:
++       * Non-Interruptable Reader/Writer spinlock mutexes - RW optimization will be switched off
++       */
++
++      /* Linux does not support:
++       * One-locks, of any sort - no optimization for this fact will be made.
++       */
++
++} _mali_osk_internal_locktype;
++
++struct _mali_osk_lock_t_struct
++{
++    _mali_osk_internal_locktype type;
++      unsigned long flags;
++    union
++    {
++        spinlock_t spinlock;
++      struct mutex mutex;
++        struct rw_semaphore rw_sema;
++    } obj;
++      MALI_DEBUG_CODE(
++                                /** original flags for debug checking */
++                                _mali_osk_lock_flags_t orig_flags;
++
++                                /* id of the thread currently holding this lock, 0 if no
++                                 * threads hold it. */
++                                u32 owner;
++                                /* number of owners this lock currently has (can be > 1 if
++                                 * taken in R/O mode. */
++                                u32 nOwners;
++                                /* what mode the lock was taken in */
++                                _mali_osk_lock_mode_t mode;
++      ); /* MALI_DEBUG_CODE */
++};
++
++_mali_osk_lock_t *_mali_osk_lock_init( _mali_osk_lock_flags_t flags, u32 initial, u32 order )
++{
++    _mali_osk_lock_t *lock = NULL;
++
++      /* Validate parameters: */
++      /* Flags acceptable */
++      MALI_DEBUG_ASSERT( 0 == ( flags & ~(_MALI_OSK_LOCKFLAG_SPINLOCK
++                                      | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ
++                                      | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE
++                                      | _MALI_OSK_LOCKFLAG_READERWRITER
++                                      | _MALI_OSK_LOCKFLAG_ORDERED
++                                      | _MALI_OSK_LOCKFLAG_ONELOCK )) );
++      /* Spinlocks are always non-interruptable */
++      MALI_DEBUG_ASSERT( (((flags & _MALI_OSK_LOCKFLAG_SPINLOCK) || (flags & _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ)) && (flags & _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE))
++                                       || !(flags & _MALI_OSK_LOCKFLAG_SPINLOCK));
++      /* Parameter initial SBZ - for future expansion */
++      MALI_DEBUG_ASSERT( 0 == initial );
++
++      lock = kmalloc(sizeof(_mali_osk_lock_t), GFP_KERNEL);
++
++      if ( NULL == lock )
++      {
++              return lock;
++      }
++
++      /* Determine type of mutex: */
++    /* defaults to interruptable mutex if no flags are specified */
++
++      if ( (flags & _MALI_OSK_LOCKFLAG_SPINLOCK) )
++      {
++              /* Non-interruptable Spinlocks override all others */
++              lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_SPIN;
++              spin_lock_init( &lock->obj.spinlock );
++      }
++      else if ( (flags & _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ ) )
++      {
++              lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_SPIN_IRQ;
++              lock->flags = 0;
++              spin_lock_init( &lock->obj.spinlock );
++      }
++      else if ( (flags & _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE)
++                        && (flags & _MALI_OSK_LOCKFLAG_READERWRITER) )
++      {
++              lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW;
++              init_rwsem( &lock->obj.rw_sema );
++      }
++      else
++      {
++              /* Usual mutex types */
++              if ( (flags & _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE) )
++              {
++                      lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT;
++              }
++              else
++              {
++                      lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX;
++              }
++
++              /* Initially unlocked */
++              mutex_init(&lock->obj.mutex);
++      }
++
++#ifdef DEBUG
++      /* Debug tracking of flags */
++      lock->orig_flags = flags;
++
++      /* Debug tracking of lock owner */
++      lock->owner = 0;
++      lock->nOwners = 0;
++#endif /* DEBUG */
++
++    return lock;
++}
++
++#ifdef DEBUG
++u32 _mali_osk_lock_get_owner( _mali_osk_lock_t *lock )
++{
++      return lock->owner;
++}
++
++u32 _mali_osk_lock_get_number_owners( _mali_osk_lock_t *lock )
++{
++      return lock->nOwners;
++}
++
++u32 _mali_osk_lock_get_mode( _mali_osk_lock_t *lock )
++{
++      return lock->mode;
++}
++#endif /* DEBUG */
++
++_mali_osk_errcode_t _mali_osk_lock_wait( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode)
++{
++    _mali_osk_errcode_t err = _MALI_OSK_ERR_OK;
++
++      /* Parameter validation */
++      MALI_DEBUG_ASSERT_POINTER( lock );
++
++      MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_RW == mode
++                                       || _MALI_OSK_LOCKMODE_RO == mode );
++
++      /* Only allow RO locks when the initial object was a Reader/Writer lock
++       * Since information is lost on the internal locktype, we use the original
++       * information, which is only stored when built for DEBUG */
++      MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_RW == mode
++                                       || (_MALI_OSK_LOCKMODE_RO == mode && (_MALI_OSK_LOCKFLAG_READERWRITER & lock->orig_flags)) );
++
++      switch ( lock->type )
++      {
++      case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN:
++              spin_lock(&lock->obj.spinlock);
++              break;
++      case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN_IRQ:
++              {
++                      unsigned long tmp_flags;
++                      spin_lock_irqsave(&lock->obj.spinlock, tmp_flags);
++                      lock->flags = tmp_flags;
++              }
++              break;
++
++      case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX:
++              if (mutex_lock_interruptible(&lock->obj.mutex))
++              {
++                      MALI_PRINT_ERROR(("Can not lock mutex\n"));
++                      err = _MALI_OSK_ERR_RESTARTSYSCALL;
++              }
++              break;
++
++      case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT:
++              mutex_lock(&lock->obj.mutex);
++              break;
++
++      case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW:
++              if (mode == _MALI_OSK_LOCKMODE_RO)
++        {
++            down_read(&lock->obj.rw_sema);
++        }
++        else
++        {
++            down_write(&lock->obj.rw_sema);
++        }
++              break;
++
++      default:
++              /* Reaching here indicates a programming error, so you will not get here
++               * on non-DEBUG builds */
++              MALI_DEBUG_PRINT_ERROR( ("Invalid internal lock type: %.8X", lock->type ) );
++              break;
++      }
++
++#ifdef DEBUG
++      /* This thread is now the owner of this lock */
++      if (_MALI_OSK_ERR_OK == err)
++      {
++              if (mode == _MALI_OSK_LOCKMODE_RW)
++              {
++                      /*MALI_DEBUG_ASSERT(0 == lock->owner);*/
++                      if (0 != lock->owner)
++                      {
++                              printk(KERN_ERR "%d: ERROR: Lock %p already has owner %d\n", _mali_osk_get_tid(), lock, lock->owner);
++                              dump_stack();
++                      }
++                      lock->owner = _mali_osk_get_tid();
++                      lock->mode = mode;
++                      ++lock->nOwners;
++              }
++              else /* mode == _MALI_OSK_LOCKMODE_RO */
++              {
++                      lock->owner |= _mali_osk_get_tid();
++                      lock->mode = mode;
++                      ++lock->nOwners;
++              }
++      }
++#endif
++
++    return err;
++}
++
++void _mali_osk_lock_signal( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode )
++{
++      /* Parameter validation */
++      MALI_DEBUG_ASSERT_POINTER( lock );
++
++      MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_RW == mode
++                                       || _MALI_OSK_LOCKMODE_RO == mode );
++
++      /* Only allow RO locks when the initial object was a Reader/Writer lock
++       * Since information is lost on the internal locktype, we use the original
++       * information, which is only stored when built for DEBUG */
++      MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_RW == mode
++                                       || (_MALI_OSK_LOCKMODE_RO == mode && (_MALI_OSK_LOCKFLAG_READERWRITER & lock->orig_flags)) );
++
++#ifdef DEBUG
++      /* make sure the thread releasing the lock actually was the owner */
++      if (mode == _MALI_OSK_LOCKMODE_RW)
++      {
++              /*MALI_DEBUG_ASSERT(_mali_osk_get_tid() == lock->owner);*/
++              if (_mali_osk_get_tid() != lock->owner)
++              {
++                      printk(KERN_ERR "%d: ERROR: Lock %p owner was %d\n", _mali_osk_get_tid(), lock, lock->owner);
++                      dump_stack();
++              }
++              /* This lock now has no owner */
++              lock->owner = 0;
++              --lock->nOwners;
++      }
++      else /* mode == _MALI_OSK_LOCKMODE_RO */
++      {
++              if ((_mali_osk_get_tid() & lock->owner) != _mali_osk_get_tid())
++              {
++                      printk(KERN_ERR "%d: ERROR: Not an owner of %p lock.\n", _mali_osk_get_tid(), lock);
++                      dump_stack();
++              }
++
++              /* if this is the last thread holding this lock in R/O mode, set owner
++               * back to 0 */
++              if (0 == --lock->nOwners)
++              {
++                      lock->owner = 0;
++              }
++      }
++#endif /* DEBUG */
++
++      switch ( lock->type )
++      {
++      case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN:
++              spin_unlock(&lock->obj.spinlock);
++              break;
++      case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN_IRQ:
++              spin_unlock_irqrestore(&lock->obj.spinlock, lock->flags);
++              break;
++
++      case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX:
++              /* FALLTHROUGH */
++      case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT:
++              mutex_unlock(&lock->obj.mutex);
++              break;
++
++      case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW:
++              if (mode == _MALI_OSK_LOCKMODE_RO)
++        {
++            up_read(&lock->obj.rw_sema);
++        }
++        else
++        {
++            up_write(&lock->obj.rw_sema);
++        }
++              break;
++
++      default:
++              /* Reaching here indicates a programming error, so you will not get here
++               * on non-DEBUG builds */
++              MALI_DEBUG_PRINT_ERROR( ("Invalid internal lock type: %.8X", lock->type ) );
++              break;
++      }
++}
++
++void _mali_osk_lock_term( _mali_osk_lock_t *lock )
++{
++      /* Parameter validation  */
++      MALI_DEBUG_ASSERT_POINTER( lock );
++
++      /* Linux requires no explicit termination of spinlocks, semaphores, or rw_semaphores */
++    kfree(lock);
++}
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_osk_low_level_mem.c b/drivers/gpu/arm/mali400/mali/linux/mali_osk_low_level_mem.c
+new file mode 100644
+index 0000000..21f7762
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_osk_low_level_mem.c
+@@ -0,0 +1,719 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_osk_low_level_mem.c
++ * Implementation of the OS abstraction layer for the kernel device driver
++ */
++
++/* needed to detect kernel version specific code */
++#include <linux/version.h>
++
++#include <asm/io.h>
++#include <linux/ioport.h>
++#include <linux/slab.h>
++#include <linux/mm.h>
++#include <linux/dma-mapping.h>
++#include <linux/spinlock.h>
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)
++#include <linux/shrinker.h>
++#endif
++/* MALI_SEC */
++#ifdef CONFIG_SLP
++#include <linux/memcontrol.h>
++#endif
++
++#include "mali_osk.h"
++#include "mali_ukk.h" /* required to hook in _mali_ukk_mem_mmap handling */
++#include "mali_kernel_common.h"
++#include "mali_kernel_linux.h"
++
++#ifdef CONFIG_SLP_MALI_DBG
++#include <mach/regs-pmu.h>
++#endif
++
++static void mali_kernel_memory_vma_open(struct vm_area_struct * vma);
++static void mali_kernel_memory_vma_close(struct vm_area_struct * vma);
++
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
++static int mali_kernel_memory_cpu_page_fault_handler(struct vm_area_struct *vma, struct vm_fault *vmf);
++#else
++static unsigned long mali_kernel_memory_cpu_page_fault_handler(struct vm_area_struct * vma, unsigned long address);
++#endif
++
++
++typedef struct mali_vma_usage_tracker
++{
++      int references;
++      u32 cookie;
++} mali_vma_usage_tracker;
++
++#define INVALID_PAGE 0xffffffff
++
++/* Linked list structure to hold details of all OS allocations in a particular
++ * mapping
++ */
++struct AllocationList
++{
++      struct AllocationList *next;
++      u32 offset;
++      u32 physaddr;
++};
++
++typedef struct AllocationList AllocationList;
++
++/* Private structure to store details of a mapping region returned
++ * from _mali_osk_mem_mapregion_init
++ */
++struct MappingInfo
++{
++      struct vm_area_struct *vma;
++      struct AllocationList *list;
++      struct AllocationList *tail;
++};
++
++typedef struct MappingInfo MappingInfo;
++
++static u32 _kernel_page_allocate(void);
++static void _kernel_page_release(u32 physical_address);
++static AllocationList * _allocation_list_item_get(void);
++static void _allocation_list_item_release(AllocationList * item);
++
++
++/* Variable declarations */
++static DEFINE_SPINLOCK(allocation_list_spinlock);
++static AllocationList * pre_allocated_memory = (AllocationList*) NULL ;
++static int pre_allocated_memory_size_current  = 0;
++#ifdef MALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB
++      static int pre_allocated_memory_size_max      = MALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB * 1024 * 1024;
++#else
++      static int pre_allocated_memory_size_max      = 16 * 1024 * 1024; /* 6 MiB */
++#endif
++
++static struct vm_operations_struct mali_kernel_vm_ops =
++{
++      .open = mali_kernel_memory_vma_open,
++      .close = mali_kernel_memory_vma_close,
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
++      .fault = mali_kernel_memory_cpu_page_fault_handler
++#else
++      .nopfn = mali_kernel_memory_cpu_page_fault_handler
++#endif
++};
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
++      #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)
++static int mali_mem_shrink(int nr_to_scan, gfp_t gfp_mask)
++      #else
++static int mali_mem_shrink(struct shrinker *shrinker, int nr_to_scan, gfp_t gfp_mask)
++      #endif
++#else
++static int mali_mem_shrink(struct shrinker *shrinker, struct shrink_control *sc)
++#endif
++{
++      unsigned long flags;
++      AllocationList *item;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
++      int nr = nr_to_scan;
++#else
++      int nr = sc->nr_to_scan;
++#endif
++
++      if (0 == nr)
++      {
++              return pre_allocated_memory_size_current / PAGE_SIZE;
++      }
++
++      if (0 == pre_allocated_memory_size_current)
++      {
++              /* No pages availble */
++              return 0;
++      }
++
++      if (0 == spin_trylock_irqsave(&allocation_list_spinlock, flags))
++      {
++              /* Not able to lock. */
++              return -1;
++      }
++
++      while (pre_allocated_memory && nr > 0)
++      {
++              item = pre_allocated_memory;
++              pre_allocated_memory = item->next;
++
++              _kernel_page_release(item->physaddr);
++              _mali_osk_free(item);
++
++              pre_allocated_memory_size_current -= PAGE_SIZE;
++              --nr;
++      }
++      spin_unlock_irqrestore(&allocation_list_spinlock,flags);
++
++      return pre_allocated_memory_size_current / PAGE_SIZE;
++}
++
++struct shrinker mali_mem_shrinker = {
++      .shrink = mali_mem_shrink,
++      .seeks = DEFAULT_SEEKS,
++};
++
++void mali_osk_low_level_mem_init(void)
++{
++      pre_allocated_memory = (AllocationList*) NULL ;
++
++      register_shrinker(&mali_mem_shrinker);
++}
++
++void mali_osk_low_level_mem_term(void)
++{
++      unregister_shrinker(&mali_mem_shrinker);
++
++      while ( NULL != pre_allocated_memory )
++      {
++              AllocationList *item;
++              item = pre_allocated_memory;
++              pre_allocated_memory = item->next;
++              _kernel_page_release(item->physaddr);
++              _mali_osk_free( item );
++      }
++      pre_allocated_memory_size_current  = 0;
++}
++
++static u32 _kernel_page_allocate(void)
++{
++      struct page *new_page;
++      u32 linux_phys_addr;
++
++      new_page = alloc_page(GFP_HIGHUSER | __GFP_ZERO | __GFP_REPEAT | __GFP_NOWARN | __GFP_COLD);
++
++      if ( NULL == new_page )
++      {
++              return INVALID_PAGE;
++      }
++
++/* MALI_SEC */
++#ifdef CONFIG_SLP
++      /* SLP: charging 3D allocated page */
++      mem_cgroup_newpage_charge(new_page, current->mm, GFP_HIGHUSER |
++      __GFP_ZERO | __GFP_REPEAT | __GFP_NOWARN | __GFP_COLD);
++
++#ifdef CONFIG_SLP_LOWMEM_NOTIFY
++      inc_mm_counter(current->mm, MM_ANONPAGES);
++#endif
++#endif
++      /* Ensure page is flushed from CPU caches. */
++      linux_phys_addr = dma_map_page(NULL, new_page, 0, PAGE_SIZE, DMA_BIDIRECTIONAL);
++
++      return linux_phys_addr;
++}
++
++static void _kernel_page_release(u32 physical_address)
++{
++      struct page *unmap_page;
++
++      #if 1
++      dma_unmap_page(NULL, physical_address, PAGE_SIZE, DMA_BIDIRECTIONAL);
++      #endif
++
++      unmap_page = pfn_to_page( physical_address >> PAGE_SHIFT );
++      MALI_DEBUG_ASSERT_POINTER( unmap_page );
++/* MALI_SEC */
++#ifdef CONFIG_SLP
++      /* SLP: uncharging 3D allocated page */
++      mem_cgroup_uncharge_page(unmap_page);
++
++#ifdef CONFIG_SLP_LOWMEM_NOTIFY
++      if (current && current->mm)
++              dec_mm_counter(current->mm, MM_ANONPAGES);
++#endif
++#endif
++      __free_page( unmap_page );
++}
++
++static AllocationList * _allocation_list_item_get(void)
++{
++      AllocationList *item = NULL;
++      unsigned long flags;
++
++      spin_lock_irqsave(&allocation_list_spinlock,flags);
++      if ( pre_allocated_memory )
++      {
++              item = pre_allocated_memory;
++              pre_allocated_memory = pre_allocated_memory->next;
++              pre_allocated_memory_size_current -= PAGE_SIZE;
++
++              spin_unlock_irqrestore(&allocation_list_spinlock,flags);
++              return item;
++      }
++      spin_unlock_irqrestore(&allocation_list_spinlock,flags);
++
++      item = _mali_osk_malloc( sizeof(AllocationList) );
++      if ( NULL == item)
++      {
++              return NULL;
++      }
++
++      item->physaddr = _kernel_page_allocate();
++      if ( INVALID_PAGE == item->physaddr )
++      {
++              /* Non-fatal error condition, out of memory. Upper levels will handle this. */
++              _mali_osk_free( item );
++              return NULL;
++      }
++      return item;
++}
++
++static void _allocation_list_item_release(AllocationList * item)
++{
++      unsigned long flags;
++      spin_lock_irqsave(&allocation_list_spinlock,flags);
++      if ( pre_allocated_memory_size_current < pre_allocated_memory_size_max)
++      {
++              item->next = pre_allocated_memory;
++              pre_allocated_memory = item;
++              pre_allocated_memory_size_current += PAGE_SIZE;
++              spin_unlock_irqrestore(&allocation_list_spinlock,flags);
++              return;
++      }
++      spin_unlock_irqrestore(&allocation_list_spinlock,flags);
++
++      _kernel_page_release(item->physaddr);
++      _mali_osk_free( item );
++}
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
++static int mali_kernel_memory_cpu_page_fault_handler(struct vm_area_struct *vma, struct vm_fault *vmf)
++#else
++static unsigned long mali_kernel_memory_cpu_page_fault_handler(struct vm_area_struct * vma, unsigned long address)
++#endif
++{
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
++      void __user * address;
++      address = vmf->virtual_address;
++#endif
++      /*
++       * We always fail the call since all memory is pre-faulted when assigned to the process.
++       * Only the Mali cores can use page faults to extend buffers.
++      */
++
++      MALI_DEBUG_PRINT(1, ("Page-fault in Mali memory region caused by the CPU.\n"));
++      MALI_DEBUG_PRINT(1, ("Tried to access %p (process local virtual address) which is not currently mapped to any Mali memory.\n", (void*)address));
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
++      return VM_FAULT_SIGBUS;
++#else
++      return NOPFN_SIGBUS;
++#endif
++}
++
++static void mali_kernel_memory_vma_open(struct vm_area_struct * vma)
++{
++      mali_vma_usage_tracker * vma_usage_tracker;
++      MALI_DEBUG_PRINT(4, ("Open called on vma %p\n", vma));
++
++      vma_usage_tracker = (mali_vma_usage_tracker*)vma->vm_private_data;
++      vma_usage_tracker->references++;
++
++      return;
++}
++
++static void mali_kernel_memory_vma_close(struct vm_area_struct * vma)
++{
++      _mali_uk_mem_munmap_s args = {0, };
++      mali_memory_allocation * descriptor;
++      mali_vma_usage_tracker * vma_usage_tracker;
++      MALI_DEBUG_PRINT(3, ("Close called on vma %p\n", vma));
++
++      vma_usage_tracker = (mali_vma_usage_tracker*)vma->vm_private_data;
++
++      BUG_ON(!vma_usage_tracker);
++      BUG_ON(0 == vma_usage_tracker->references);
++
++      vma_usage_tracker->references--;
++
++      if (0 != vma_usage_tracker->references)
++      {
++              MALI_DEBUG_PRINT(3, ("Ignoring this close, %d references still exists\n", vma_usage_tracker->references));
++              return;
++      }
++
++      /** @note args->context unused, initialized to 0.
++       * Instead, we use the memory_session from the cookie */
++
++      descriptor = (mali_memory_allocation *)vma_usage_tracker->cookie;
++
++      args.cookie = (u32)descriptor;
++      args.mapping = descriptor->mapping;
++      args.size = descriptor->size;
++
++      _mali_ukk_mem_munmap( &args );
++
++      /* vma_usage_tracker is free()d by _mali_osk_mem_mapregion_term().
++       * In the case of the memory engine, it is called as the release function that has been registered with the engine*/
++}
++
++void _mali_osk_mem_barrier( void )
++{
++      mb();
++}
++
++void _mali_osk_write_mem_barrier( void )
++{
++      wmb();
++}
++
++mali_io_address _mali_osk_mem_mapioregion( u32 phys, u32 size, const char *description )
++{
++      return (mali_io_address)ioremap_nocache(phys, size);
++}
++
++void _mali_osk_mem_unmapioregion( u32 phys, u32 size, mali_io_address virt )
++{
++      iounmap((void*)virt);
++}
++
++mali_io_address _mali_osk_mem_allocioregion( u32 *phys, u32 size )
++{
++      void * virt;
++      MALI_DEBUG_ASSERT_POINTER( phys );
++      MALI_DEBUG_ASSERT( 0 == (size & ~_MALI_OSK_CPU_PAGE_MASK) );
++      MALI_DEBUG_ASSERT( 0 != size );
++
++      /* dma_alloc_* uses a limited region of address space. On most arch/marchs
++       * 2 to 14 MiB is available. This should be enough for the page tables, which
++       * currently is the only user of this function. */
++      virt = dma_alloc_coherent(NULL, size, phys, GFP_KERNEL | GFP_DMA );
++
++      MALI_DEBUG_PRINT(3, ("Page table virt: 0x%x = dma_alloc_coherent(size:%d, phys:0x%x, )\n", virt, size, phys));
++
++      if ( NULL == virt )
++      {
++              MALI_DEBUG_PRINT(5, ("allocioregion: Failed to allocate Pagetable memory, size=0x%.8X\n", size ));
++              return 0;
++      }
++
++      MALI_DEBUG_ASSERT( 0 == (*phys & ~_MALI_OSK_CPU_PAGE_MASK) );
++
++      return (mali_io_address)virt;
++}
++
++void _mali_osk_mem_freeioregion( u32 phys, u32 size, mali_io_address virt )
++{
++      MALI_DEBUG_ASSERT_POINTER( (void*)virt );
++      MALI_DEBUG_ASSERT( 0 != size );
++      MALI_DEBUG_ASSERT( 0 == (phys & ( (1 << PAGE_SHIFT) - 1 )) );
++
++      dma_free_coherent(NULL, size, virt, phys);
++}
++
++_mali_osk_errcode_t inline _mali_osk_mem_reqregion( u32 phys, u32 size, const char *description )
++{
++#if MALI_LICENSE_IS_GPL
++      return _MALI_OSK_ERR_OK; /* GPL driver gets the mem region for the resources registered automatically */
++#else
++      return ((NULL == request_mem_region(phys, size, description)) ? _MALI_OSK_ERR_NOMEM : _MALI_OSK_ERR_OK);
++#endif
++}
++
++void inline _mali_osk_mem_unreqregion( u32 phys, u32 size )
++{
++#if !MALI_LICENSE_IS_GPL
++      release_mem_region(phys, size);
++#endif
++}
++
++void inline _mali_osk_mem_iowrite32_relaxed( volatile mali_io_address addr, u32 offset, u32 val )
++{
++#ifdef CONFIG_SLP_MALI_DBG
++      if (!(__raw_readl(EXYNOS4_G3D_CONFIGURATION) & 0x7))
++              panic("%s:addr[0x%x]\n", __func__, (u32)addr + offset);
++#endif
++      __raw_writel(cpu_to_le32(val),((u8*)addr) + offset);
++}
++
++#ifdef CONFIG_SLP_MALI_DBG
++void inline _mali_osk_mem_iowrite32_relaxed_cpu( volatile mali_io_address addr,
++                                                      u32 offset, u32 val )
++{
++      __raw_writel(cpu_to_le32(val),((u8*)addr) + offset);
++}
++#endif
++
++u32 inline _mali_osk_mem_ioread32( volatile mali_io_address addr, u32 offset )
++{
++#ifdef CONFIG_SLP_MALI_DBG
++      if (!(__raw_readl(EXYNOS4_G3D_CONFIGURATION) & 0x7))
++              panic("%s:addr[0x%x]\n", __func__, (u32)addr + offset);
++#endif
++      return ioread32(((u8*)addr) + offset);
++}
++
++#ifdef CONFIG_SLP_MALI_DBG
++u32 inline _mali_osk_mem_ioread32_cpu(volatile mali_io_address addr, u32 offset)
++{
++      return ioread32(((u8*)addr) + offset);
++}
++#endif
++
++void inline _mali_osk_mem_iowrite32( volatile mali_io_address addr, u32 offset, u32 val )
++{
++#ifdef CONFIG_SLP_MALI_DBG
++      if (!(__raw_readl(EXYNOS4_G3D_CONFIGURATION) & 0x7))
++              panic("%s:addr[0x%x]\n", __func__, (u32)addr + offset);
++#endif
++      iowrite32(val, ((u8*)addr) + offset);
++}
++
++void _mali_osk_cache_flushall( void )
++{
++      /** @note Cached memory is not currently supported in this implementation */
++}
++
++void _mali_osk_cache_ensure_uncached_range_flushed( void *uncached_mapping, u32 offset, u32 size )
++{
++      _mali_osk_write_mem_barrier();
++}
++
++_mali_osk_errcode_t _mali_osk_mem_mapregion_init( mali_memory_allocation * descriptor )
++{
++      struct vm_area_struct *vma;
++      mali_vma_usage_tracker * vma_usage_tracker;
++      MappingInfo *mappingInfo;
++
++      if (NULL == descriptor) return _MALI_OSK_ERR_FAULT;
++
++      MALI_DEBUG_ASSERT( 0 != (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE) );
++
++      vma = (struct vm_area_struct*)descriptor->process_addr_mapping_info;
++
++      if (NULL == vma ) return _MALI_OSK_ERR_FAULT;
++
++      /* Re-write the process_addr_mapping_info */
++      mappingInfo = _mali_osk_calloc( 1, sizeof(MappingInfo) );
++
++      if ( NULL == mappingInfo ) return _MALI_OSK_ERR_FAULT;
++
++      vma_usage_tracker = _mali_osk_calloc( 1, sizeof(mali_vma_usage_tracker) );
++
++      if (NULL == vma_usage_tracker)
++      {
++              MALI_DEBUG_PRINT(2, ("Failed to allocate memory to track memory usage\n"));
++              _mali_osk_free( mappingInfo );
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      mappingInfo->vma = vma;
++      descriptor->process_addr_mapping_info = mappingInfo;
++
++      /* Do the va range allocation - in this case, it was done earlier, so we copy in that information */
++      descriptor->mapping = (void __user*)vma->vm_start;
++      /* list member is already NULL */
++
++      /*
++        set some bits which indicate that:
++        The memory is IO memory, meaning that no paging is to be performed and the memory should not be included in crash dumps
++        The memory is reserved, meaning that it's present and can never be paged out (see also previous entry)
++      */
++      vma->vm_flags |= VM_IO;
++      vma->vm_flags |= VM_RESERVED;
++      vma->vm_flags |= VM_DONTCOPY;
++
++      vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
++      vma->vm_ops = &mali_kernel_vm_ops; /* Operations used on any memory system */
++
++      vma_usage_tracker->references = 1; /* set initial reference count to be 1 as vma_open won't be called for the first mmap call */
++      vma_usage_tracker->cookie = (u32)descriptor; /* cookie for munmap */
++
++      vma->vm_private_data = vma_usage_tracker;
++
++      return _MALI_OSK_ERR_OK;
++}
++
++void _mali_osk_mem_mapregion_term( mali_memory_allocation * descriptor )
++{
++      struct vm_area_struct* vma;
++      mali_vma_usage_tracker * vma_usage_tracker;
++      MappingInfo *mappingInfo;
++
++      if (NULL == descriptor) return;
++
++      MALI_DEBUG_ASSERT( 0 != (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE) );
++
++      mappingInfo = (MappingInfo *)descriptor->process_addr_mapping_info;
++
++      MALI_DEBUG_ASSERT_POINTER( mappingInfo );
++
++      /* Linux does the right thing as part of munmap to remove the mapping
++       * All that remains is that we remove the vma_usage_tracker setup in init() */
++      vma = mappingInfo->vma;
++
++      MALI_DEBUG_ASSERT_POINTER( vma );
++
++      /* ASSERT that there are no allocations on the list. Unmap should've been
++       * called on all OS allocations. */
++      MALI_DEBUG_ASSERT( NULL == mappingInfo->list );
++
++      vma_usage_tracker = vma->vm_private_data;
++
++      /* We only get called if mem_mapregion_init succeeded */
++      _mali_osk_free(vma_usage_tracker);
++
++      _mali_osk_free( mappingInfo );
++      return;
++}
++
++_mali_osk_errcode_t _mali_osk_mem_mapregion_map( mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size )
++{
++      struct vm_area_struct *vma;
++      MappingInfo *mappingInfo;
++
++      if (NULL == descriptor) return _MALI_OSK_ERR_FAULT;
++
++      MALI_DEBUG_ASSERT_POINTER( phys_addr );
++
++      MALI_DEBUG_ASSERT( 0 != (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE) );
++
++      MALI_DEBUG_ASSERT( 0 == (size & ~_MALI_OSK_CPU_PAGE_MASK) );
++
++      MALI_DEBUG_ASSERT( 0 == (offset & ~_MALI_OSK_CPU_PAGE_MASK));
++
++      if (NULL == descriptor->mapping) return _MALI_OSK_ERR_INVALID_ARGS;
++
++      if (size > (descriptor->size - offset))
++      {
++              MALI_DEBUG_PRINT(1,("_mali_osk_mem_mapregion_map: virtual memory area not large enough to map physical 0x%x size %x into area 0x%x at offset 0x%xr\n",
++                                  *phys_addr, size, descriptor->mapping, offset));
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      mappingInfo = (MappingInfo *)descriptor->process_addr_mapping_info;
++
++      MALI_DEBUG_ASSERT_POINTER( mappingInfo );
++
++      vma = mappingInfo->vma;
++
++      if (NULL == vma ) return _MALI_OSK_ERR_FAULT;
++
++      MALI_DEBUG_PRINT(7, ("Process map: mapping 0x%08X to process address 0x%08lX length 0x%08X\n", *phys_addr, (long unsigned int)(descriptor->mapping + offset), size));
++
++      if ( MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC == *phys_addr )
++      {
++              _mali_osk_errcode_t ret;
++              AllocationList *alloc_item;
++              u32 linux_phys_frame_num;
++
++              alloc_item = _allocation_list_item_get();
++              if (NULL == alloc_item)
++              {
++                      MALI_DEBUG_PRINT(1, ("Failed to allocate list item\n"));
++                      return _MALI_OSK_ERR_NOMEM;
++              }
++
++              linux_phys_frame_num = alloc_item->physaddr >> PAGE_SHIFT;
++
++              ret = ( remap_pfn_range( vma, ((u32)descriptor->mapping) + offset, linux_phys_frame_num, size, vma->vm_page_prot) ) ? _MALI_OSK_ERR_FAULT : _MALI_OSK_ERR_OK;
++
++              if ( ret != _MALI_OSK_ERR_OK)
++              {
++                      MALI_PRINT_ERROR(("%s %d could not remap_pfn_range()\n", __FUNCTION__, __LINE__));
++                      _allocation_list_item_release(alloc_item);
++                      return ret;
++              }
++
++              /* Put our alloc_item into the list of allocations on success */
++              if (NULL == mappingInfo->list)
++              {
++                      mappingInfo->list = alloc_item;
++              }
++              else
++              {
++                      mappingInfo->tail->next = alloc_item;
++              }
++
++              mappingInfo->tail = alloc_item;
++              alloc_item->next = NULL;
++              alloc_item->offset = offset;
++
++              /* Write out new physical address on success */
++              *phys_addr = alloc_item->physaddr;
++
++              return ret;
++      }
++
++      /* Otherwise, Use the supplied physical address */
++
++      /* ASSERT that supplied phys_addr is page aligned */
++      MALI_DEBUG_ASSERT( 0 == ((*phys_addr) & ~_MALI_OSK_CPU_PAGE_MASK) );
++
++      return ( remap_pfn_range( vma, ((u32)descriptor->mapping) + offset, *phys_addr >> PAGE_SHIFT, size, vma->vm_page_prot) ) ? _MALI_OSK_ERR_FAULT : _MALI_OSK_ERR_OK;
++
++}
++
++void _mali_osk_mem_mapregion_unmap( mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t flags )
++{
++      MappingInfo *mappingInfo;
++
++   if (NULL == descriptor) return;
++
++      MALI_DEBUG_ASSERT( 0 != (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE) );
++
++      MALI_DEBUG_ASSERT( 0 == (size & ~_MALI_OSK_CPU_PAGE_MASK) );
++
++      MALI_DEBUG_ASSERT( 0 == (offset & ~_MALI_OSK_CPU_PAGE_MASK) );
++
++      if (NULL == descriptor->mapping) return;
++
++      if (size > (descriptor->size - offset))
++      {
++              MALI_DEBUG_PRINT(1,("_mali_osk_mem_mapregion_unmap: virtual memory area not large enough to unmap size %x from area 0x%x at offset 0x%x\n",
++                                                      size, descriptor->mapping, offset));
++              return;
++      }
++      mappingInfo = (MappingInfo *)descriptor->process_addr_mapping_info;
++
++      MALI_DEBUG_ASSERT_POINTER( mappingInfo );
++
++      if ( 0 != (flags & _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR) )
++      {
++              /* This physical RAM was allocated in _mali_osk_mem_mapregion_map and
++               * so needs to be unmapped
++               */
++              while (size)
++              {
++                      /* First find the allocation in the list of allocations */
++                      AllocationList *alloc = mappingInfo->list;
++                      AllocationList **prev = &(mappingInfo->list);
++
++                      while (NULL != alloc && alloc->offset != offset)
++                      {
++                              prev = &(alloc->next);
++                              alloc = alloc->next;
++                      }
++                      if (alloc == NULL) {
++                              MALI_DEBUG_PRINT(1, ("Unmapping memory that isn't mapped\n"));
++                              size -= _MALI_OSK_CPU_PAGE_SIZE;
++                              offset += _MALI_OSK_CPU_PAGE_SIZE;
++                              continue;
++                      }
++
++                      *prev = alloc->next;
++                      _allocation_list_item_release(alloc);
++
++                      /* Move onto the next allocation */
++                      size -= _MALI_OSK_CPU_PAGE_SIZE;
++                      offset += _MALI_OSK_CPU_PAGE_SIZE;
++              }
++      }
++
++      /* Linux does the right thing as part of munmap to remove the mapping */
++
++      return;
++}
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_osk_mali.c b/drivers/gpu/arm/mali400/mali/linux/mali_osk_mali.c
+new file mode 100644
+index 0000000..aef3212
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_osk_mali.c
+@@ -0,0 +1,110 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_osk_mali.c
++ * Implementation of the OS abstraction layer which is specific for the Mali kernel device driver
++ */
++#include <linux/kernel.h>
++#include <asm/uaccess.h>
++#include <linux/platform_device.h>
++#include <linux/mali/mali_utgard.h>
++
++#include "mali_osk_mali.h"
++#include "mali_kernel_common.h" /* MALI_xxx macros */
++#include "mali_osk.h"           /* kernel side OS functions */
++#include "mali_uk_types.h"
++#include "mali_kernel_linux.h"
++
++_mali_osk_errcode_t _mali_osk_resource_find(u32 addr, _mali_osk_resource_t *res)
++{
++      int i;
++
++      if (NULL == mali_platform_device)
++      {
++              /* Not connected to a device */
++              return _MALI_OSK_ERR_ITEM_NOT_FOUND;
++      }
++
++      for (i = 0; i < mali_platform_device->num_resources; i++)
++      {
++              if (IORESOURCE_MEM == resource_type(&(mali_platform_device->resource[i])) &&
++                  mali_platform_device->resource[i].start == addr)
++              {
++                      if (NULL != res)
++                      {
++                              res->base = addr;
++                              res->description = mali_platform_device->resource[i].name;
++
++                              /* Any (optional) IRQ resource belonging to this resource will follow */
++                              if ((i + 1) < mali_platform_device->num_resources &&
++                                  IORESOURCE_IRQ == resource_type(&(mali_platform_device->resource[i+1])))
++                              {
++                                      res->irq = mali_platform_device->resource[i+1].start;
++                              }
++                              else
++                              {
++                                      res->irq = -1;
++                              }
++                      }
++                      return _MALI_OSK_ERR_OK;
++              }
++      }
++
++      return _MALI_OSK_ERR_ITEM_NOT_FOUND;
++}
++
++u32 _mali_osk_resource_base_address(void)
++{
++      u32 lowest_addr = 0xFFFFFFFF;
++      u32 ret = 0;
++
++      if (NULL != mali_platform_device)
++      {
++              int i;
++              for (i = 0; i < mali_platform_device->num_resources; i++)
++              {
++                      if (mali_platform_device->resource[i].flags & IORESOURCE_MEM &&
++                          mali_platform_device->resource[i].start < lowest_addr)
++                      {
++                              lowest_addr = mali_platform_device->resource[i].start;
++                              ret = lowest_addr;
++                      }
++              }
++      }
++
++      return ret;
++}
++
++_mali_osk_errcode_t _mali_osk_device_data_get(struct _mali_osk_device_data *data)
++{
++      MALI_DEBUG_ASSERT_POINTER(data);
++
++      if (NULL != mali_platform_device)
++      {
++              struct mali_gpu_device_data* os_data = NULL;
++
++              os_data = (struct mali_gpu_device_data*)mali_platform_device->dev.platform_data;
++              if (NULL != os_data)
++              {
++                      /* Copy data from OS dependant struct to Mali neutral struct (identical!) */
++                      data->dedicated_mem_start = os_data->dedicated_mem_start;
++                      data->dedicated_mem_size = os_data->dedicated_mem_size;
++                      data->shared_mem_size = os_data->shared_mem_size;
++                      data->fb_start = os_data->fb_start;
++                      data->fb_size = os_data->fb_size;
++                      data->utilization_interval = os_data->utilization_interval;
++                      data->utilization_handler = os_data->utilization_handler;
++                      return _MALI_OSK_ERR_OK;
++              }
++      }
++
++      return _MALI_OSK_ERR_ITEM_NOT_FOUND;
++}
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_osk_math.c b/drivers/gpu/arm/mali400/mali/linux/mali_osk_math.c
+new file mode 100644
+index 0000000..d6e3786
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_osk_math.c
+@@ -0,0 +1,22 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_osk_math.c
++ * Implementation of the OS abstraction layer for the kernel device driver
++ */
++
++#include "mali_osk.h"
++#include <linux/bitops.h>
++
++u32 inline _mali_osk_clz( u32 input )
++{
++      return 32-fls(input);
++}
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_osk_memory.c b/drivers/gpu/arm/mali400/mali/linux/mali_osk_memory.c
+new file mode 100644
+index 0000000..5d18d39
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_osk_memory.c
+@@ -0,0 +1,61 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_osk_memory.c
++ * Implementation of the OS abstraction layer for the kernel device driver
++ */
++
++#include "mali_osk.h"
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++
++void inline *_mali_osk_calloc( u32 n, u32 size )
++{
++    return kcalloc(n, size, GFP_KERNEL);
++}
++
++void inline *_mali_osk_malloc( u32 size )
++{
++    return kmalloc(size, GFP_KERNEL);
++}
++
++void inline _mali_osk_free( void *ptr )
++{
++    kfree(ptr);
++}
++
++void inline *_mali_osk_valloc( u32 size )
++{
++    return vmalloc(size);
++}
++
++void inline _mali_osk_vfree( void *ptr )
++{
++    vfree(ptr);
++}
++
++void inline *_mali_osk_memcpy( void *dst, const void *src, u32        len )
++{
++    return memcpy(dst, src, len);
++}
++
++void inline *_mali_osk_memset( void *s, u32 c, u32 n )
++{
++    return memset(s, c, n);
++}
++
++mali_bool _mali_osk_mem_check_allocated( u32 max_allocated )
++{
++      /* No need to prevent an out-of-memory dialogue appearing on Linux,
++       * so we always return MALI_TRUE.
++       */
++      return MALI_TRUE;
++}
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_osk_misc.c b/drivers/gpu/arm/mali400/mali/linux/mali_osk_misc.c
+new file mode 100644
+index 0000000..942e062
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_osk_misc.c
+@@ -0,0 +1,64 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_osk_misc.c
++ * Implementation of the OS abstraction layer for the kernel device driver
++ */
++#include <linux/kernel.h>
++#include <asm/uaccess.h>
++#include <asm/cacheflush.h>
++#include <linux/sched.h>
++#include <linux/module.h>
++#include "mali_osk.h"
++
++void _mali_osk_dbgmsg( const char *fmt, ... )
++{
++    va_list args;
++    va_start(args, fmt);
++    vprintk(fmt, args);
++      va_end(args);
++}
++
++u32 _mali_osk_snprintf( char *buf, u32 size, const char *fmt, ... )
++{
++      int res;
++      va_list args;
++      va_start(args, fmt);
++
++      res = vscnprintf(buf, (size_t)size, fmt, args);
++
++      va_end(args);
++      return res;
++}
++
++void _mali_osk_abort(void)
++{
++      /* make a simple fault by dereferencing a NULL pointer */
++      dump_stack();
++      *(int *)0 = 0;
++}
++
++void _mali_osk_break(void)
++{
++      _mali_osk_abort();
++}
++
++u32 _mali_osk_get_pid(void)
++{
++      /* Thread group ID is the process ID on Linux */
++      return (u32)current->tgid;
++}
++
++u32 _mali_osk_get_tid(void)
++{
++      /* pid is actually identifying the thread on Linux */
++      return (u32)current->pid;
++}
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_osk_notification.c b/drivers/gpu/arm/mali400/mali/linux/mali_osk_notification.c
+new file mode 100644
+index 0000000..d631427
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_osk_notification.c
+@@ -0,0 +1,186 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_osk_notification.c
++ * Implementation of the OS abstraction layer for the kernel device driver
++ */
++
++#include "mali_osk.h"
++#include "mali_kernel_common.h"
++
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/spinlock.h>
++
++/**
++ * Declaration of the notification queue object type
++ * Contains a linked list of notification pending delivery to user space.
++ * It also contains a wait queue of exclusive waiters blocked in the ioctl
++ * When a new notification is posted a single thread is resumed.
++ */
++struct _mali_osk_notification_queue_t_struct
++{
++      spinlock_t mutex; /**< Mutex protecting the list */
++      wait_queue_head_t receive_queue; /**< Threads waiting for new entries to the queue */
++      struct list_head head; /**< List of notifications waiting to be picked up */
++};
++
++typedef struct _mali_osk_notification_wrapper_t_struct
++{
++      struct list_head list;           /**< Internal linked list variable */
++      _mali_osk_notification_t data;   /**< Notification data */
++} _mali_osk_notification_wrapper_t;
++
++_mali_osk_notification_queue_t *_mali_osk_notification_queue_init( void )
++{
++      _mali_osk_notification_queue_t *        result;
++
++      result = (_mali_osk_notification_queue_t *)kmalloc(sizeof(_mali_osk_notification_queue_t), GFP_KERNEL);
++      if (NULL == result) return NULL;
++
++      spin_lock_init(&result->mutex);
++      init_waitqueue_head(&result->receive_queue);
++      INIT_LIST_HEAD(&result->head);
++
++      return result;
++}
++
++_mali_osk_notification_t *_mali_osk_notification_create( u32 type, u32 size )
++{
++      /* OPT Recycling of notification objects */
++      _mali_osk_notification_wrapper_t *notification;
++
++      notification = (_mali_osk_notification_wrapper_t *)kmalloc( sizeof(_mali_osk_notification_wrapper_t) + size,
++                                                                  GFP_KERNEL | __GFP_HIGH | __GFP_REPEAT);
++      if (NULL == notification)
++      {
++              MALI_DEBUG_PRINT(1, ("Failed to create a notification object\n"));
++              return NULL;
++      }
++
++      /* Init the list */
++      INIT_LIST_HEAD(&notification->list);
++
++      if (0 != size)
++      {
++              notification->data.result_buffer = ((u8*)notification) + sizeof(_mali_osk_notification_wrapper_t);
++      }
++      else
++      {
++              notification->data.result_buffer = NULL;
++      }
++
++      /* set up the non-allocating fields */
++      notification->data.notification_type = type;
++      notification->data.result_buffer_size = size;
++
++      /* all ok */
++      return &(notification->data);
++}
++
++void _mali_osk_notification_delete( _mali_osk_notification_t *object )
++{
++      _mali_osk_notification_wrapper_t *notification;
++      MALI_DEBUG_ASSERT_POINTER( object );
++
++      notification = container_of( object, _mali_osk_notification_wrapper_t, data );
++
++      /* Free the container */
++      kfree(notification);
++}
++
++void _mali_osk_notification_queue_term( _mali_osk_notification_queue_t *queue )
++{
++      MALI_DEBUG_ASSERT_POINTER( queue );
++
++      /* not much to do, just free the memory */
++      kfree(queue);
++}
++
++void _mali_osk_notification_queue_send( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t *object )
++{
++#if defined(MALI_UPPER_HALF_SCHEDULING)
++      unsigned long irq_flags;
++#endif
++
++      _mali_osk_notification_wrapper_t *notification;
++      MALI_DEBUG_ASSERT_POINTER( queue );
++      MALI_DEBUG_ASSERT_POINTER( object );
++
++      notification = container_of( object, _mali_osk_notification_wrapper_t, data );
++
++#if defined(MALI_UPPER_HALF_SCHEDULING)
++      spin_lock_irqsave(&queue->mutex, irq_flags);
++#else
++      spin_lock(&queue->mutex);
++#endif
++
++      list_add_tail(&notification->list, &queue->head);
++
++#if defined(MALI_UPPER_HALF_SCHEDULING)
++      spin_unlock_irqrestore(&queue->mutex, irq_flags);
++#else
++      spin_unlock(&queue->mutex);
++#endif
++
++      /* and wake up one possible exclusive waiter */
++      wake_up(&queue->receive_queue);
++}
++
++_mali_osk_errcode_t _mali_osk_notification_queue_dequeue( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t **result )
++{
++#if defined(MALI_UPPER_HALF_SCHEDULING)
++      unsigned long irq_flags;
++#endif
++
++      _mali_osk_errcode_t ret = _MALI_OSK_ERR_ITEM_NOT_FOUND;
++      _mali_osk_notification_wrapper_t *wrapper_object;
++
++#if defined(MALI_UPPER_HALF_SCHEDULING)
++      spin_lock_irqsave(&queue->mutex, irq_flags);
++#else
++      spin_lock(&queue->mutex);
++#endif
++
++      if (!list_empty(&queue->head))
++      {
++              wrapper_object = list_entry(queue->head.next, _mali_osk_notification_wrapper_t, list);
++              *result = &(wrapper_object->data);
++              list_del_init(&wrapper_object->list);
++              ret = _MALI_OSK_ERR_OK;
++      }
++
++#if defined(MALI_UPPER_HALF_SCHEDULING)
++      spin_unlock_irqrestore(&queue->mutex, irq_flags);
++#else
++      spin_unlock(&queue->mutex);
++#endif
++
++      return ret;
++}
++
++_mali_osk_errcode_t _mali_osk_notification_queue_receive( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t **result )
++{
++    /* check input */
++      MALI_DEBUG_ASSERT_POINTER( queue );
++      MALI_DEBUG_ASSERT_POINTER( result );
++
++      /* default result */
++      *result = NULL;
++
++      if (wait_event_interruptible(queue->receive_queue,
++                                   _MALI_OSK_ERR_OK == _mali_osk_notification_queue_dequeue(queue, result)))
++      {
++              return _MALI_OSK_ERR_RESTARTSYSCALL;
++      }
++
++      return _MALI_OSK_ERR_OK; /* all ok */
++}
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_osk_pm.c b/drivers/gpu/arm/mali400/mali/linux/mali_osk_pm.c
+new file mode 100644
+index 0000000..f2351bd
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_osk_pm.c
+@@ -0,0 +1,103 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_osk_pm.c
++ * Implementation of the callback functions from common power management
++ */
++
++#include <linux/sched.h>
++
++#ifdef CONFIG_PM_RUNTIME
++#include <linux/pm_runtime.h>
++#endif /* CONFIG_PM_RUNTIME */
++#include <linux/platform_device.h>
++#include <linux/version.h>
++#include "mali_osk.h"
++#include "mali_kernel_common.h"
++#include "mali_kernel_linux.h"
++
++static _mali_osk_atomic_t mali_pm_ref_count;
++
++void _mali_osk_pm_dev_enable(void) /* @@@@ todo: change to init of some kind.. or change the way or where atomics are initialized? */
++{
++      _mali_osk_atomic_init(&mali_pm_ref_count, 0);
++}
++
++void _mali_osk_pm_dev_disable(void) /* @@@@ todo: change to term of some kind */
++{
++      _mali_osk_atomic_term(&mali_pm_ref_count);
++}
++
++/* Can NOT run in atomic context */
++_mali_osk_errcode_t _mali_osk_pm_dev_ref_add(void)
++{
++#ifdef CONFIG_PM_RUNTIME
++      int err;
++      MALI_DEBUG_ASSERT_POINTER(mali_platform_device);
++      err = pm_runtime_get_sync(&(mali_platform_device->dev));
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
++      pm_runtime_mark_last_busy(&(mali_platform_device->dev));
++#endif
++      if (0 > err)
++      {
++              MALI_PRINT_ERROR(("Mali OSK PM: pm_runtime_get_sync() returned error code %d\n", err));
++              return _MALI_OSK_ERR_FAULT;
++      }
++      _mali_osk_atomic_inc(&mali_pm_ref_count);
++      MALI_DEBUG_PRINT(4, ("Mali OSK PM: Power ref taken (%u)\n", _mali_osk_atomic_read(&mali_pm_ref_count)));
++#endif
++      return _MALI_OSK_ERR_OK;
++}
++
++/* Can run in atomic context */
++void _mali_osk_pm_dev_ref_dec(void)
++{
++#ifdef CONFIG_PM_RUNTIME
++      MALI_DEBUG_ASSERT_POINTER(mali_platform_device);
++      _mali_osk_atomic_dec(&mali_pm_ref_count);
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
++      pm_runtime_mark_last_busy(&(mali_platform_device->dev));
++      pm_runtime_put_autosuspend(&(mali_platform_device->dev));
++#else
++      pm_runtime_put(&(mali_platform_device->dev));
++#endif
++      MALI_DEBUG_PRINT(4, ("Mali OSK PM: Power ref released (%u)\n", _mali_osk_atomic_read(&mali_pm_ref_count)));
++#endif
++}
++
++/* Can run in atomic context */
++mali_bool _mali_osk_pm_dev_ref_add_no_power_on(void)
++{
++#ifdef CONFIG_PM_RUNTIME
++      u32 ref;
++      MALI_DEBUG_ASSERT_POINTER(mali_platform_device);
++      pm_runtime_get_noresume(&(mali_platform_device->dev));
++      ref = _mali_osk_atomic_read(&mali_pm_ref_count);
++      MALI_DEBUG_PRINT(4, ("Mali OSK PM: No-power ref taken (%u)\n", _mali_osk_atomic_read(&mali_pm_ref_count)));
++      return ref > 0 ? MALI_TRUE : MALI_FALSE;
++#else
++      return MALI_TRUE;
++#endif
++}
++
++/* Can run in atomic context */
++void _mali_osk_pm_dev_ref_dec_no_power_on(void)
++{
++#ifdef CONFIG_PM_RUNTIME
++      MALI_DEBUG_ASSERT_POINTER(mali_platform_device);
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
++      pm_runtime_put_autosuspend(&(mali_platform_device->dev));
++#else
++      pm_runtime_put(&(mali_platform_device->dev));
++#endif
++      MALI_DEBUG_PRINT(4, ("Mali OSK PM: No-power ref released (%u)\n", _mali_osk_atomic_read(&mali_pm_ref_count)));
++#endif
++}
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_osk_profiling.c b/drivers/gpu/arm/mali400/mali/linux/mali_osk_profiling.c
+new file mode 100644
+index 0000000..9deb433
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_osk_profiling.c
+@@ -0,0 +1,260 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include <linux/module.h>
++
++#include "mali_kernel_common.h"
++#include "mali_osk.h"
++#include "mali_ukk.h"
++#include "mali_uk_types.h"
++#include "mali_osk_profiling.h"
++#include "mali_linux_trace.h"
++#include "mali_gp.h"
++#include "mali_pp.h"
++#include "mali_l2_cache.h"
++#include "mali_user_settings_db.h"
++
++_mali_osk_errcode_t _mali_osk_profiling_init(mali_bool auto_start)
++{
++      if (MALI_TRUE == auto_start)
++      {
++              mali_set_user_setting(_MALI_UK_USER_SETTING_SW_EVENTS_ENABLE, MALI_TRUE);
++      }
++
++      return _MALI_OSK_ERR_OK;
++}
++
++void _mali_osk_profiling_term(void)
++{
++      /* Nothing to do */
++}
++
++_mali_osk_errcode_t _mali_osk_profiling_start(u32 * limit)
++{
++      /* Nothing to do */
++      return _MALI_OSK_ERR_OK;
++}
++
++_mali_osk_errcode_t _mali_osk_profiling_stop(u32 *count)
++{
++      /* Nothing to do */
++      return _MALI_OSK_ERR_OK;
++}
++
++u32 _mali_osk_profiling_get_count(void)
++{
++      return 0;
++}
++
++_mali_osk_errcode_t _mali_osk_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5])
++{
++      /* Nothing to do */
++      return _MALI_OSK_ERR_OK;
++}
++
++_mali_osk_errcode_t _mali_osk_profiling_clear(void)
++{
++      /* Nothing to do */
++      return _MALI_OSK_ERR_OK;
++}
++
++mali_bool _mali_osk_profiling_is_recording(void)
++{
++      return MALI_FALSE;
++}
++
++mali_bool _mali_osk_profiling_have_recording(void)
++{
++      return MALI_FALSE;
++}
++
++void _mali_osk_profiling_report_sw_counters(u32 *counters)
++{
++      trace_mali_sw_counters(_mali_osk_get_pid(), _mali_osk_get_tid(), NULL, counters);
++}
++
++
++_mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args)
++{
++      return _mali_osk_profiling_start(&args->limit);
++}
++
++_mali_osk_errcode_t _mali_ukk_profiling_add_event(_mali_uk_profiling_add_event_s *args)
++{
++      /* Always add process and thread identificator in the first two data elements for events from user space */
++      _mali_osk_profiling_add_event(args->event_id, _mali_osk_get_pid(), _mali_osk_get_tid(), args->data[2], args->data[3], args->data[4]);
++
++      return _MALI_OSK_ERR_OK;
++}
++
++_mali_osk_errcode_t _mali_ukk_profiling_stop(_mali_uk_profiling_stop_s *args)
++{
++      return _mali_osk_profiling_stop(&args->count);
++}
++
++_mali_osk_errcode_t _mali_ukk_profiling_get_event(_mali_uk_profiling_get_event_s *args)
++{
++      return _mali_osk_profiling_get_event(args->index, &args->timestamp, &args->event_id, args->data);
++}
++
++_mali_osk_errcode_t _mali_ukk_profiling_clear(_mali_uk_profiling_clear_s *args)
++{
++      return _mali_osk_profiling_clear();
++}
++
++_mali_osk_errcode_t _mali_ukk_sw_counters_report(_mali_uk_sw_counters_report_s *args)
++{
++      _mali_osk_profiling_report_sw_counters(args->counters);
++      return _MALI_OSK_ERR_OK;
++}
++
++/**
++ * Called by gator.ko to set HW counters
++ *
++ * @param counter_id The counter ID.
++ * @param event_id Event ID that the counter should count (HW counter value from TRM).
++ * 
++ * @return 1 on success, 0 on failure.
++ */
++int _mali_profiling_set_event(u32 counter_id, s32 event_id)
++{
++      if (COUNTER_VP_C0 == counter_id)
++      {
++              if (MALI_TRUE == mali_gp_job_set_gp_counter_src0(event_id))
++              {
++                      return 1;
++              }
++      }
++      if (COUNTER_VP_C1 == counter_id)
++      {
++              if (MALI_TRUE == mali_gp_job_set_gp_counter_src1(event_id))
++              {
++                      return 1;
++              }
++      }
++      if (COUNTER_FP0_C0 <= counter_id && COUNTER_FP3_C1 >= counter_id)
++      {
++              u32 core_id = (counter_id - COUNTER_FP0_C0) >> 1;
++              struct mali_pp_core* pp_core = mali_pp_get_global_pp_core(core_id);
++
++              if (NULL != pp_core)
++              {
++                      if ((COUNTER_FP0_C0 == counter_id) || (COUNTER_FP0_C1 == counter_id))
++                      {
++                              u32 counter_src = (counter_id - COUNTER_FP0_C0) & 1;
++                              if (0 == counter_src)
++                              {
++                                      if (MALI_TRUE == mali_pp_job_set_pp_counter_src0(event_id))
++                                      {
++                                              return 1;
++                                      }
++                              }
++                              else
++                              {
++                                      if (MALI_TRUE == mali_pp_job_set_pp_counter_src1(event_id))
++                                      {
++                                      MALI_DEBUG_PRINT(5, ("MALI PROFILING SET EVENT core 0 counter_id = %d\n",counter_id));
++                                      return 1;
++                                      }
++                              }
++                      }
++              }
++      }
++      if (COUNTER_L2_C0 <= counter_id && COUNTER_L2_C1 >= counter_id)
++      {
++              u32 core_id = (counter_id - COUNTER_L2_C0) >> 1;
++              struct mali_l2_cache_core* l2_cache_core = mali_l2_cache_core_get_glob_l2_core(core_id);
++
++              if (NULL != l2_cache_core)
++              {
++                      u32 counter_src = (counter_id - COUNTER_L2_C0) & 1;
++                      if (0 == counter_src)
++                      {
++                              MALI_DEBUG_PRINT(5, ("SET EVENT L2 0 COUNTER\n"));
++                              if (MALI_TRUE == mali_l2_cache_core_set_counter_src0(l2_cache_core, event_id))
++                              {
++                                      return 1;
++                              }
++                      }
++                      else
++                      {
++                              MALI_DEBUG_PRINT(5, ("SET EVENT L2 1 COUNTER\n"));
++                              if (MALI_TRUE == mali_l2_cache_core_set_counter_src1(l2_cache_core, event_id))
++                              {
++                                      return 1;
++                              }
++                      }
++              }
++      }
++
++      return 0;
++}
++
++/**
++ * Called by gator.ko to retrieve the L2 cache counter values for the first L2 cache. 
++ * The L2 cache counters are unique in that they are polled by gator, rather than being
++ * transmitted via the tracepoint mechanism. 
++ *
++ * @param src0 First L2 cache counter ID.
++ * @param val0 First L2 cache counter value.
++ * @param src1 Second L2 cache counter ID.
++ * @param val1 Second L2 cache counter value.
++ */
++void _mali_profiling_get_counters(u32 *src0, u32 *val0, u32 *src1, u32 *val1)
++{
++       struct mali_l2_cache_core *l2_cache = mali_l2_cache_core_get_glob_l2_core(0);
++       if (NULL != l2_cache)
++       {
++              if (MALI_TRUE == mali_l2_cache_lock_power_state(l2_cache))
++              {
++                      /* It is now safe to access the L2 cache core in order to retrieve the counters */
++                      mali_l2_cache_core_get_counter_values(l2_cache, src0, val0, src1, val1);
++              }
++              mali_l2_cache_unlock_power_state(l2_cache);
++       }
++}
++
++/*
++ * List of possible actions to be controlled by Streamline.
++ * The following numbers are used by gator to control the frame buffer dumping and s/w counter reporting.
++ * We cannot use the enums in mali_uk_types.h because they are unknown inside gator.
++ */
++#define FBDUMP_CONTROL_ENABLE (1)
++#define FBDUMP_CONTROL_RATE (2)
++#define SW_COUNTER_ENABLE (3)
++#define FBDUMP_CONTROL_RESIZE_FACTOR (4)
++
++/**
++ * Called by gator to control the production of profiling information at runtime.
++ */
++void _mali_profiling_control(u32 action, u32 value)
++{
++      switch(action)
++      {
++      case FBDUMP_CONTROL_ENABLE:
++              mali_set_user_setting(_MALI_UK_USER_SETTING_COLORBUFFER_CAPTURE_ENABLED, (value == 0 ? MALI_FALSE : MALI_TRUE));
++              break;
++      case FBDUMP_CONTROL_RATE:
++              mali_set_user_setting(_MALI_UK_USER_SETTING_BUFFER_CAPTURE_N_FRAMES, value);
++              break;
++      case SW_COUNTER_ENABLE:
++              mali_set_user_setting(_MALI_UK_USER_SETTING_SW_COUNTER_ENABLED, value);
++              break;
++      case FBDUMP_CONTROL_RESIZE_FACTOR:
++              mali_set_user_setting(_MALI_UK_USER_SETTING_BUFFER_CAPTURE_RESIZE_FACTOR, value);
++              break;
++      default:
++              break;  /* Ignore unimplemented actions */
++      }
++}
++
++EXPORT_SYMBOL(_mali_profiling_set_event);
++EXPORT_SYMBOL(_mali_profiling_get_counters);
++EXPORT_SYMBOL(_mali_profiling_control);
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_osk_specific.h b/drivers/gpu/arm/mali400/mali/linux/mali_osk_specific.h
+new file mode 100644
+index 0000000..87c7a3c
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_osk_specific.h
+@@ -0,0 +1,148 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_osk_specific.h
++ * Defines per-OS Kernel level specifics, such as unusual workarounds for
++ * certain OSs.
++ */
++
++#ifndef __MALI_OSK_SPECIFIC_H__
++#define __MALI_OSK_SPECIFIC_H__
++
++#include <asm/uaccess.h>
++
++#include "mali_sync.h"
++
++#define MALI_STATIC_INLINE static inline
++#define MALI_NON_STATIC_INLINE inline
++
++#ifdef CONFIG_SYNC
++/* MALI_SEC */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
++typedef struct sync_timeline mali_sync_tl;
++typedef struct sync_pt mali_sync_pt;
++
++MALI_STATIC_INLINE mali_sync_pt *_mali_osk_sync_pt_create(mali_sync_tl *parent)
++{
++      return (mali_sync_pt*)mali_sync_pt_alloc(parent);
++}
++
++MALI_STATIC_INLINE void _mali_osk_sync_pt_signal(mali_sync_pt *pt)
++{
++      mali_sync_signal_pt(pt, 0);
++}
++#endif
++#endif /* CONFIG_SYNC */
++
++MALI_STATIC_INLINE u32 _mali_osk_copy_from_user(void *to, void *from, u32 n)
++{
++      return (u32)copy_from_user(to, from, (unsigned long)n);
++}
++
++/** The list of events supported by the Mali DDK. */
++typedef enum
++{
++    /* Vertex processor activity */
++    ACTIVITY_VP = 0,
++
++    /* Fragment processor activity */
++    ACTIVITY_FP0,
++    ACTIVITY_FP1,
++    ACTIVITY_FP2,
++    ACTIVITY_FP3,
++
++    /* L2 cache counters */
++    COUNTER_L2_C0,
++    COUNTER_L2_C1,
++
++    /* Vertex processor counters */
++    COUNTER_VP_C0,
++    COUNTER_VP_C1,
++
++    /* Fragment processor counters */
++    COUNTER_FP0_C0,
++    COUNTER_FP0_C1,
++    COUNTER_FP1_C0,
++    COUNTER_FP1_C1,
++    COUNTER_FP2_C0,
++    COUNTER_FP2_C1,
++    COUNTER_FP3_C0,
++    COUNTER_FP3_C1,
++
++    /*
++     * If more hardware counters are added, the _mali_osk_hw_counter_table
++     * below should also be updated.
++     */
++
++    /* EGL software counters */
++    COUNTER_EGL_BLIT_TIME,
++
++    /* GLES software counters */
++    COUNTER_GLES_DRAW_ELEMENTS_CALLS,
++    COUNTER_GLES_DRAW_ELEMENTS_NUM_INDICES,
++    COUNTER_GLES_DRAW_ELEMENTS_NUM_TRANSFORMED,
++    COUNTER_GLES_DRAW_ARRAYS_CALLS,
++    COUNTER_GLES_DRAW_ARRAYS_NUM_TRANSFORMED,
++    COUNTER_GLES_DRAW_POINTS,
++    COUNTER_GLES_DRAW_LINES,
++    COUNTER_GLES_DRAW_LINE_LOOP,
++    COUNTER_GLES_DRAW_LINE_STRIP,
++    COUNTER_GLES_DRAW_TRIANGLES,
++    COUNTER_GLES_DRAW_TRIANGLE_STRIP,
++    COUNTER_GLES_DRAW_TRIANGLE_FAN,
++    COUNTER_GLES_NON_VBO_DATA_COPY_TIME,
++    COUNTER_GLES_UNIFORM_BYTES_COPIED_TO_MALI,
++    COUNTER_GLES_UPLOAD_TEXTURE_TIME,
++    COUNTER_GLES_UPLOAD_VBO_TIME,
++    COUNTER_GLES_NUM_FLUSHES,
++    COUNTER_GLES_NUM_VSHADERS_GENERATED,
++    COUNTER_GLES_NUM_FSHADERS_GENERATED,
++    COUNTER_GLES_VSHADER_GEN_TIME,
++    COUNTER_GLES_FSHADER_GEN_TIME,
++    COUNTER_GLES_INPUT_TRIANGLES,
++    COUNTER_GLES_VXCACHE_HIT,
++    COUNTER_GLES_VXCACHE_MISS,
++    COUNTER_GLES_VXCACHE_COLLISION,
++    COUNTER_GLES_CULLED_TRIANGLES,
++    COUNTER_GLES_CULLED_LINES,
++    COUNTER_GLES_BACKFACE_TRIANGLES,
++    COUNTER_GLES_GBCLIP_TRIANGLES,
++    COUNTER_GLES_GBCLIP_LINES,
++    COUNTER_GLES_TRIANGLES_DRAWN,
++    COUNTER_GLES_DRAWCALL_TIME,
++    COUNTER_GLES_TRIANGLES_COUNT,
++    COUNTER_GLES_INDEPENDENT_TRIANGLES_COUNT,
++    COUNTER_GLES_STRIP_TRIANGLES_COUNT,
++    COUNTER_GLES_FAN_TRIANGLES_COUNT,
++    COUNTER_GLES_LINES_COUNT,
++    COUNTER_GLES_INDEPENDENT_LINES_COUNT,
++    COUNTER_GLES_STRIP_LINES_COUNT,
++    COUNTER_GLES_LOOP_LINES_COUNT,
++
++    /* Framebuffer capture pseudo-counter */
++    COUNTER_FILMSTRIP,
++
++    NUMBER_OF_EVENTS
++} _mali_osk_counter_id;
++
++#define FIRST_ACTIVITY_EVENT    ACTIVITY_VP
++#define LAST_ACTIVITY_EVENT     ACTIVITY_FP3
++
++#define FIRST_HW_COUNTER        COUNTER_L2_C0
++#define LAST_HW_COUNTER         COUNTER_FP3_C1
++
++#define FIRST_SW_COUNTER        COUNTER_EGL_BLIT_TIME
++#define LAST_SW_COUNTER         COUNTER_GLES_LOOP_LINES_COUNT
++
++#define FIRST_SPECIAL_COUNTER   COUNTER_FILMSTRIP
++#define LAST_SPECIAL_COUNTER    COUNTER_FILMSTRIP
++
++#endif /* __MALI_OSK_SPECIFIC_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_osk_time.c b/drivers/gpu/arm/mali400/mali/linux/mali_osk_time.c
+new file mode 100644
+index 0000000..2aa6588
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_osk_time.c
+@@ -0,0 +1,51 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_osk_time.c
++ * Implementation of the OS abstraction layer for the kernel device driver
++ */
++
++#include "mali_osk.h"
++#include <linux/jiffies.h>
++#include <linux/time.h>
++#include <asm/delay.h>
++
++int   _mali_osk_time_after( u32 ticka, u32 tickb )
++{
++    return time_after((unsigned long)ticka, (unsigned long)tickb);
++}
++
++u32   _mali_osk_time_mstoticks( u32 ms )
++{
++    return msecs_to_jiffies(ms);
++}
++
++u32   _mali_osk_time_tickstoms( u32 ticks )
++{
++    return jiffies_to_msecs(ticks);
++}
++
++u32   _mali_osk_time_tickcount( void )
++{
++    return jiffies;
++}
++
++void _mali_osk_time_ubusydelay( u32 usecs )
++{
++    udelay(usecs);
++}
++
++u64 _mali_osk_time_get_ns( void )
++{
++      struct timespec tsval;
++      getnstimeofday(&tsval);
++      return (u64)timespec_to_ns(&tsval);
++}
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_osk_timers.c b/drivers/gpu/arm/mali400/mali/linux/mali_osk_timers.c
+new file mode 100644
+index 0000000..f235c7e1
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_osk_timers.c
+@@ -0,0 +1,77 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_osk_timers.c
++ * Implementation of the OS abstraction layer for the kernel device driver
++ */
++
++#include <linux/timer.h>
++#include <linux/slab.h>
++#include "mali_osk.h"
++#include "mali_kernel_common.h"
++
++struct _mali_osk_timer_t_struct
++{
++    struct timer_list timer;
++};
++
++typedef void (*timer_timeout_function_t)(unsigned long);
++
++_mali_osk_timer_t *_mali_osk_timer_init(void)
++{
++    _mali_osk_timer_t *t = (_mali_osk_timer_t*)kmalloc(sizeof(_mali_osk_timer_t), GFP_KERNEL);
++    if (NULL != t) init_timer(&t->timer);
++    return t;
++}
++
++void _mali_osk_timer_add( _mali_osk_timer_t *tim, u32 ticks_to_expire )
++{
++      MALI_DEBUG_ASSERT_POINTER(tim);
++    tim->timer.expires = jiffies + ticks_to_expire;
++    add_timer(&(tim->timer));
++}
++
++void _mali_osk_timer_mod( _mali_osk_timer_t *tim, u32 ticks_to_expire)
++{
++    MALI_DEBUG_ASSERT_POINTER(tim);
++    mod_timer(&(tim->timer), jiffies + ticks_to_expire);
++}
++
++void _mali_osk_timer_del( _mali_osk_timer_t *tim )
++{
++    MALI_DEBUG_ASSERT_POINTER(tim);
++    del_timer_sync(&(tim->timer));
++}
++
++void _mali_osk_timer_del_async( _mali_osk_timer_t *tim )
++{
++      MALI_DEBUG_ASSERT_POINTER(tim);
++      del_timer(&(tim->timer));
++}
++
++mali_bool _mali_osk_timer_pending( _mali_osk_timer_t *tim )
++{
++      MALI_DEBUG_ASSERT_POINTER(tim);
++      return 1 == timer_pending(&(tim->timer));
++}
++
++void _mali_osk_timer_setcallback( _mali_osk_timer_t *tim, _mali_osk_timer_callback_t callback, void *data )
++{
++    MALI_DEBUG_ASSERT_POINTER(tim);
++    tim->timer.data = (unsigned long)data;
++    tim->timer.function = (timer_timeout_function_t)callback;
++}
++
++void _mali_osk_timer_term( _mali_osk_timer_t *tim )
++{
++    MALI_DEBUG_ASSERT_POINTER(tim);
++    kfree(tim);
++}
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_osk_wait_queue.c b/drivers/gpu/arm/mali400/mali/linux/mali_osk_wait_queue.c
+new file mode 100644
+index 0000000..a42fa03
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_osk_wait_queue.c
+@@ -0,0 +1,73 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_osk_wait_queue.c
++ * Implemenation of the OS abstraction layer for the kernel device driver
++ */
++
++#include <linux/wait.h>
++#include <linux/slab.h>
++#include <linux/sched.h>
++
++#include "mali_osk.h"
++#include "mali_kernel_common.h"
++
++struct _mali_osk_wait_queue_t_struct
++{
++    wait_queue_head_t wait_queue;
++};
++
++_mali_osk_wait_queue_t* _mali_osk_wait_queue_init( void )
++{
++    _mali_osk_wait_queue_t* ret = NULL;
++
++    ret = kmalloc(sizeof(_mali_osk_wait_queue_t), GFP_KERNEL);
++
++    if (NULL == ret)
++    {
++        return ret;
++    }
++
++    init_waitqueue_head(&ret->wait_queue);
++    MALI_DEBUG_ASSERT(!waitqueue_active(&ret->wait_queue));
++
++    return ret;
++}
++
++void _mali_osk_wait_queue_wait_event( _mali_osk_wait_queue_t *queue, mali_bool (*condition)(void) )
++{
++    MALI_DEBUG_ASSERT_POINTER( queue );
++    MALI_DEBUG_PRINT(6, ("Adding to wait queue %p\n", queue));
++    wait_event(queue->wait_queue, condition());
++}
++
++void _mali_osk_wait_queue_wake_up( _mali_osk_wait_queue_t *queue )
++{
++    MALI_DEBUG_ASSERT_POINTER( queue );
++
++    /* if queue is empty, don't attempt to wake up its elements */
++    if (!waitqueue_active(&queue->wait_queue)) return;
++
++    MALI_DEBUG_PRINT(6, ("Waking up elements in wait queue %p ....\n", queue));
++
++    wake_up_all(&queue->wait_queue);
++
++    MALI_DEBUG_PRINT(6, ("... elements in wait queue %p woken up\n", queue));
++}
++
++void _mali_osk_wait_queue_term( _mali_osk_wait_queue_t *queue )
++{
++      /* Parameter validation  */
++      MALI_DEBUG_ASSERT_POINTER( queue );
++
++      /* Linux requires no explicit termination of wait queues */
++    kfree(queue);
++}
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_osk_wq.c b/drivers/gpu/arm/mali400/mali/linux/mali_osk_wq.c
+new file mode 100644
+index 0000000..02685fa
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_osk_wq.c
+@@ -0,0 +1,118 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_osk_wq.c
++ * Implementation of the OS abstraction layer for the kernel device driver
++ */
++
++#include <linux/slab.h>       /* For memory allocation */
++#include <linux/workqueue.h>
++#include <linux/version.h>
++
++#include "mali_osk.h"
++#include "mali_kernel_common.h"
++#include "mali_kernel_license.h"
++#include "mali_kernel_linux.h"
++
++typedef struct _mali_osk_wq_work_t_struct
++{
++      _mali_osk_wq_work_handler_t handler;
++      void *data;
++      struct work_struct work_handle;
++} mali_osk_wq_work_object_t;
++
++#if MALI_LICENSE_IS_GPL
++struct workqueue_struct *mali_wq = NULL;
++#endif
++
++static void _mali_osk_wq_work_func ( struct work_struct *work );
++
++_mali_osk_errcode_t _mali_osk_wq_init(void)
++{
++#if MALI_LICENSE_IS_GPL
++      MALI_DEBUG_ASSERT(NULL == mali_wq);
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
++      mali_wq = alloc_workqueue("mali", WQ_UNBOUND, 0);
++#else
++      mali_wq = create_workqueue("mali");
++#endif
++      if(NULL == mali_wq)
++      {
++              MALI_PRINT_ERROR(("Unable to create Mali workqueue\n"));
++              return _MALI_OSK_ERR_FAULT;
++      }
++#endif
++
++      return _MALI_OSK_ERR_OK;
++}
++
++void _mali_osk_wq_flush(void)
++{
++#if MALI_LICENSE_IS_GPL
++       flush_workqueue(mali_wq);
++#else
++       flush_scheduled_work();
++#endif
++}
++
++void _mali_osk_wq_term(void)
++{
++#if MALI_LICENSE_IS_GPL
++      MALI_DEBUG_ASSERT(NULL != mali_wq);
++
++      flush_workqueue(mali_wq);
++      destroy_workqueue(mali_wq);
++      mali_wq = NULL;
++#else
++      flush_scheduled_work();
++#endif
++}
++
++_mali_osk_wq_work_t *_mali_osk_wq_create_work( _mali_osk_wq_work_handler_t handler, void *data )
++{
++      mali_osk_wq_work_object_t *work = kmalloc(sizeof(mali_osk_wq_work_object_t), GFP_KERNEL);
++
++      if (NULL == work) return NULL;
++
++      work->handler = handler;
++      work->data = data;
++
++      INIT_WORK( &work->work_handle, _mali_osk_wq_work_func );
++
++      return work;
++}
++
++void _mali_osk_wq_delete_work( _mali_osk_wq_work_t *work )
++{
++      mali_osk_wq_work_object_t *work_object = (mali_osk_wq_work_object_t *)work;
++      _mali_osk_wq_flush();
++      kfree(work_object);
++}
++
++void _mali_osk_wq_schedule_work( _mali_osk_wq_work_t *work )
++{
++      mali_osk_wq_work_object_t *work_object = (mali_osk_wq_work_object_t *)work;
++#if MALI_LICENSE_IS_GPL
++      queue_work(mali_wq, &work_object->work_handle);
++#else
++      schedule_work(&work_object->work_handle);
++#endif
++}
++
++static void _mali_osk_wq_work_func ( struct work_struct *work )
++{
++      mali_osk_wq_work_object_t *work_object;
++
++      work_object = _MALI_OSK_CONTAINER_OF(work, mali_osk_wq_work_object_t, work_handle);
++      work_object->handler(work_object->data);
++}
++
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_pmu_power_up_down.c b/drivers/gpu/arm/mali400/mali/linux/mali_pmu_power_up_down.c
+new file mode 100644
+index 0000000..ee6aa2f
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_pmu_power_up_down.c
+@@ -0,0 +1,65 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_pmu_power_up_down.c
++ */
++
++#include <linux/version.h>
++#include <linux/sched.h>
++#include <linux/module.h>
++#include "mali_osk.h"
++#include "mali_kernel_common.h"
++#include "mali_pmu.h"
++#include "linux/mali/mali_utgard.h"
++
++/* Mali PMU power up/down APIs */
++
++int mali_pmu_powerup(void)
++{
++      struct mali_pmu_core *pmu = mali_pmu_get_global_pmu_core();
++
++      MALI_DEBUG_PRINT(5, ("Mali PMU: Power up\n"));
++
++      if (NULL == pmu)
++      {
++              return -ENXIO;
++      }
++
++      if (_MALI_OSK_ERR_OK != mali_pmu_powerup_all(pmu))
++      {
++              return -EFAULT;
++      }
++
++      return 0;
++}
++
++EXPORT_SYMBOL(mali_pmu_powerup);
++
++int mali_pmu_powerdown(void)
++{
++      struct mali_pmu_core *pmu = mali_pmu_get_global_pmu_core();
++
++      MALI_DEBUG_PRINT(5, ("Mali PMU: Power down\n"));
++
++      if (NULL == pmu)
++      {
++              return -ENXIO;
++      }
++
++      if (_MALI_OSK_ERR_OK != mali_pmu_powerdown_all(pmu))
++      {
++              return -EFAULT;
++      }
++
++      return 0;
++}
++
++EXPORT_SYMBOL(mali_pmu_powerdown);
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_profiling_events.h b/drivers/gpu/arm/mali400/mali/linux/mali_profiling_events.h
+new file mode 100644
+index 0000000..e1e7afa
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_profiling_events.h
+@@ -0,0 +1,17 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_PROFILING_EVENTS_H__
++#define __MALI_PROFILING_EVENTS_H__
++
++/* Simple wrapper in order to find the OS specific location of this file */
++#include <linux/mali/mali_utgard_profiling_events.h>
++
++#endif /* __MALI_PROFILING_EVENTS_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_profiling_internal.c b/drivers/gpu/arm/mali400/mali/linux/mali_profiling_internal.c
+new file mode 100644
+index 0000000..2928ce4
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_profiling_internal.c
+@@ -0,0 +1,300 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_kernel_common.h"
++#include "mali_osk.h"
++#include "mali_osk_mali.h"
++#include "mali_ukk.h"
++#include "mali_timestamp.h"
++#include "mali_osk_profiling.h"
++#include "mali_user_settings_db.h"
++#include "mali_profiling_internal.h"
++
++typedef struct mali_profiling_entry
++{
++      u64 timestamp;
++      u32 event_id;
++      u32 data[5];
++} mali_profiling_entry;
++
++
++typedef enum mali_profiling_state
++{
++      MALI_PROFILING_STATE_UNINITIALIZED,
++      MALI_PROFILING_STATE_IDLE,
++      MALI_PROFILING_STATE_RUNNING,
++      MALI_PROFILING_STATE_RETURN,
++} mali_profiling_state;
++
++static _mali_osk_lock_t *lock = NULL;
++static mali_profiling_state prof_state = MALI_PROFILING_STATE_UNINITIALIZED;
++static mali_profiling_entry* profile_entries = NULL;
++static _mali_osk_atomic_t profile_insert_index;
++static u32 profile_mask = 0;
++static inline void add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4);
++
++void probe_mali_timeline_event(void *data, TP_PROTO(unsigned int event_id, unsigned int d0, unsigned int d1, unsigned
++                      int d2, unsigned int d3, unsigned int d4))
++{
++      add_event(event_id, d0, d1, d2, d3, d4);
++}
++
++_mali_osk_errcode_t _mali_internal_profiling_init(mali_bool auto_start)
++{
++      profile_entries = NULL;
++      profile_mask = 0;
++      _mali_osk_atomic_init(&profile_insert_index, 0);
++
++      lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_PROFILING);
++      if (NULL == lock)
++      {
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      prof_state = MALI_PROFILING_STATE_IDLE;
++
++      if (MALI_TRUE == auto_start)
++      {
++              u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* Use maximum buffer size */
++
++              mali_set_user_setting(_MALI_UK_USER_SETTING_SW_EVENTS_ENABLE, MALI_TRUE);
++              if (_MALI_OSK_ERR_OK != _mali_internal_profiling_start(&limit))
++              {
++                      return _MALI_OSK_ERR_FAULT;
++              }
++      }
++
++      return _MALI_OSK_ERR_OK;
++}
++
++void _mali_internal_profiling_term(void)
++{
++      u32 count;
++
++      /* Ensure profiling is stopped */
++      _mali_internal_profiling_stop(&count);
++
++      prof_state = MALI_PROFILING_STATE_UNINITIALIZED;
++
++      if (NULL != profile_entries)
++      {
++              _mali_osk_vfree(profile_entries);
++              profile_entries = NULL;
++      }
++
++      if (NULL != lock)
++      {
++              _mali_osk_lock_term(lock);
++              lock = NULL;
++      }
++}
++
++_mali_osk_errcode_t _mali_internal_profiling_start(u32 * limit)
++{
++      _mali_osk_errcode_t ret;
++      mali_profiling_entry *new_profile_entries;
++
++      _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
++
++      if (MALI_PROFILING_STATE_RUNNING == prof_state)
++      {
++              _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
++              return _MALI_OSK_ERR_BUSY;
++      }
++
++      new_profile_entries = _mali_osk_valloc(*limit * sizeof(mali_profiling_entry));
++
++      if (NULL == new_profile_entries)
++      {
++              _mali_osk_vfree(new_profile_entries);
++              return _MALI_OSK_ERR_NOMEM;
++      }
++
++      if (MALI_PROFILING_MAX_BUFFER_ENTRIES < *limit)
++      {
++              *limit = MALI_PROFILING_MAX_BUFFER_ENTRIES;
++      }
++
++      profile_mask = 1;
++      while (profile_mask <= *limit)
++      {
++              profile_mask <<= 1;
++      }
++      profile_mask >>= 1;
++
++      *limit = profile_mask;
++
++      profile_mask--; /* turns the power of two into a mask of one less */
++
++      if (MALI_PROFILING_STATE_IDLE != prof_state)
++      {
++              _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
++              _mali_osk_vfree(new_profile_entries);
++              return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */
++      }
++
++      profile_entries = new_profile_entries;
++
++      ret = _mali_timestamp_reset();
++
++      if (_MALI_OSK_ERR_OK == ret)
++      {
++              prof_state = MALI_PROFILING_STATE_RUNNING;
++      }
++      else
++      {
++              _mali_osk_vfree(profile_entries);
++              profile_entries = NULL;
++      }
++
++      register_trace_mali_timeline_event(probe_mali_timeline_event, NULL);
++
++      _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
++      return ret;
++}
++
++static inline void add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4)
++{
++      u32 cur_index = (_mali_osk_atomic_inc_return(&profile_insert_index) - 1) & profile_mask;
++
++      profile_entries[cur_index].timestamp = _mali_timestamp_get();
++      profile_entries[cur_index].event_id = event_id;
++      profile_entries[cur_index].data[0] = data0;
++      profile_entries[cur_index].data[1] = data1;
++      profile_entries[cur_index].data[2] = data2;
++      profile_entries[cur_index].data[3] = data3;
++      profile_entries[cur_index].data[4] = data4;
++
++      /* If event is "leave API function", add current memory usage to the event
++       * as data point 4.  This is used in timeline profiling to indicate how
++       * much memory was used when leaving a function. */
++      if (event_id == (MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_SINGLE_SW_LEAVE_API_FUNC))
++      {
++              profile_entries[cur_index].data[4] = _mali_ukk_report_memory_usage();
++      }
++}
++
++_mali_osk_errcode_t _mali_internal_profiling_stop(u32 * count)
++{
++      _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
++
++      if (MALI_PROFILING_STATE_RUNNING != prof_state)
++      {
++              _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
++              return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */
++      }
++
++      /* go into return state (user to retreive events), no more events will be added after this */
++      prof_state = MALI_PROFILING_STATE_RETURN;
++
++      unregister_trace_mali_timeline_event(probe_mali_timeline_event, NULL);
++
++      _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
++
++      tracepoint_synchronize_unregister();
++
++      *count = _mali_osk_atomic_read(&profile_insert_index);
++      if (*count > profile_mask) *count = profile_mask;
++
++      return _MALI_OSK_ERR_OK;
++}
++
++u32 _mali_internal_profiling_get_count(void)
++{
++      u32 retval = 0;
++
++      _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
++      if (MALI_PROFILING_STATE_RETURN == prof_state)
++      {
++              retval = _mali_osk_atomic_read(&profile_insert_index);
++              if (retval > profile_mask) retval = profile_mask;
++      }
++      _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
++
++      return retval;
++}
++
++_mali_osk_errcode_t _mali_internal_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5])
++{
++      u32 raw_index = _mali_osk_atomic_read(&profile_insert_index);
++
++      _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
++
++      if (index < profile_mask)
++      {
++              if ((raw_index & ~profile_mask) != 0)
++              {
++                      index += raw_index;
++                      index &= profile_mask;
++              }
++
++              if (prof_state != MALI_PROFILING_STATE_RETURN)
++              {
++                      _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
++                      return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */
++              }
++
++              if(index >= raw_index)
++              {
++                      _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
++                      return _MALI_OSK_ERR_FAULT;
++              }
++
++              *timestamp = profile_entries[index].timestamp;
++              *event_id = profile_entries[index].event_id;
++              data[0] = profile_entries[index].data[0];
++              data[1] = profile_entries[index].data[1];
++              data[2] = profile_entries[index].data[2];
++              data[3] = profile_entries[index].data[3];
++              data[4] = profile_entries[index].data[4];
++      }
++      else
++      {
++              _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
++      return _MALI_OSK_ERR_OK;
++}
++
++_mali_osk_errcode_t _mali_internal_profiling_clear(void)
++{
++      _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
++
++      if (MALI_PROFILING_STATE_RETURN != prof_state)
++      {
++              _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
++              return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */
++      }
++
++      prof_state = MALI_PROFILING_STATE_IDLE;
++      profile_mask = 0;
++      _mali_osk_atomic_init(&profile_insert_index, 0);
++
++      if (NULL != profile_entries)
++      {
++              _mali_osk_vfree(profile_entries);
++              profile_entries = NULL;
++      }
++
++      _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
++      return _MALI_OSK_ERR_OK;
++}
++
++mali_bool _mali_internal_profiling_is_recording(void)
++{
++      return prof_state == MALI_PROFILING_STATE_RUNNING ? MALI_TRUE : MALI_FALSE;
++}
++
++mali_bool _mali_internal_profiling_have_recording(void)
++{
++      return prof_state == MALI_PROFILING_STATE_RETURN ? MALI_TRUE : MALI_FALSE;
++}
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_profiling_internal.h b/drivers/gpu/arm/mali400/mali/linux/mali_profiling_internal.h
+new file mode 100644
+index 0000000..4646d25
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_profiling_internal.h
+@@ -0,0 +1,36 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_PROFILING_INTERNAL_H__
++#define __MALI_PROFILING_INTERNAL_H__
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif
++
++#include "mali_osk.h"
++
++int _mali_internal_profiling_init(mali_bool auto_start);
++void _mali_internal_profiling_term(void);
++
++mali_bool _mali_internal_profiling_is_recording(void);
++mali_bool _mali_internal_profiling_have_recording(void);
++_mali_osk_errcode_t _mali_internal_profiling_clear(void);
++_mali_osk_errcode_t _mali_internal_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5]);
++u32 _mali_internal_profiling_get_count(void);
++int _mali_internal_profiling_stop(u32 * count);
++int _mali_internal_profiling_start(u32 * limit);
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* __MALI_PROFILING_INTERNAL_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_sync.c b/drivers/gpu/arm/mali400/mali/linux/mali_sync.c
+new file mode 100644
+index 0000000..9b84896
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_sync.c
+@@ -0,0 +1,199 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_sync.c
++ *
++ */
++
++#include <linux/seq_file.h>
++#include <linux/sync.h>
++
++#include "mali_osk.h"
++#include "mali_kernel_common.h"
++
++struct mali_sync_timeline
++{
++      struct sync_timeline timeline;
++      atomic_t counter;
++      atomic_t signalled;
++};
++
++struct mali_sync_pt
++{
++      struct sync_pt pt;
++      u32 order;
++      s32 error;
++};
++
++static inline struct mali_sync_timeline *to_mali_sync_timeline(struct sync_timeline *timeline)
++{
++      return container_of(timeline, struct mali_sync_timeline, timeline);
++}
++
++static inline struct mali_sync_pt *to_mali_sync_pt(struct sync_pt *pt)
++{
++      return container_of(pt, struct mali_sync_pt, pt);
++}
++
++static struct sync_pt *timeline_dup(struct sync_pt *pt)
++{
++      struct mali_sync_pt *mpt = to_mali_sync_pt(pt);
++      struct mali_sync_pt *new_mpt;
++      struct sync_pt *new_pt = sync_pt_create(pt->parent, sizeof(struct mali_sync_pt));
++
++      if (!new_pt)
++      {
++              return NULL;
++      }
++
++      new_mpt = to_mali_sync_pt(new_pt);
++      new_mpt->order = mpt->order;
++
++      return new_pt;
++
++}
++
++static int timeline_has_signaled(struct sync_pt *pt)
++{
++      struct mali_sync_pt *mpt = to_mali_sync_pt(pt);
++      struct mali_sync_timeline *mtl = to_mali_sync_timeline(pt->parent);
++      long diff;
++
++      if (0 != mpt->error)
++      {
++              return mpt->error;
++      }
++
++      diff = atomic_read(&mtl->signalled) - mpt->order;
++
++      return diff >= 0;
++}
++
++static int timeline_compare(struct sync_pt *a, struct sync_pt *b)
++{
++      struct mali_sync_pt *ma = container_of(a, struct mali_sync_pt, pt);
++      struct mali_sync_pt *mb = container_of(b, struct mali_sync_pt, pt);
++
++      long diff = ma->order - mb->order;
++
++      if (diff < 0)
++      {
++              return -1;
++      }
++      else if (diff == 0)
++      {
++              return 0;
++      }
++      else
++      {
++              return 1;
++      }
++}
++
++static void timeline_print_tl(struct seq_file *s, struct sync_timeline *sync_timeline)
++{
++      struct mali_sync_timeline *mtl = to_mali_sync_timeline(sync_timeline);
++
++      seq_printf(s, "%u, %u", atomic_read(&mtl->signalled), atomic_read(&mtl->counter));
++}
++
++static void timeline_print_pt(struct seq_file *s, struct sync_pt *sync_pt)
++{
++      struct mali_sync_pt *mpt = to_mali_sync_pt(sync_pt);
++
++      seq_printf(s, "%u", mpt->order);
++
++}
++
++static struct sync_timeline_ops mali_timeline_ops = {
++      .driver_name    = "Mali",
++      .dup            = timeline_dup,
++      .has_signaled   = timeline_has_signaled,
++      .compare        = timeline_compare,
++      .print_obj      = timeline_print_tl,
++      .print_pt       = timeline_print_pt
++};
++
++int mali_sync_timeline_is_ours(struct sync_timeline *timeline)
++{
++      return (timeline->ops == &mali_timeline_ops);
++}
++
++struct sync_timeline *mali_sync_timeline_alloc(const char * name)
++{
++      struct sync_timeline *tl;
++      struct mali_sync_timeline *mtl;
++
++      tl = sync_timeline_create(&mali_timeline_ops,
++                                sizeof(struct mali_sync_timeline), name);
++      if (!tl)
++      {
++              return NULL;
++      }
++
++      /* Set the counter in our private struct */
++      mtl = to_mali_sync_timeline(tl);
++      atomic_set(&mtl->counter, 0);
++      atomic_set(&mtl->signalled, 0);
++
++      return tl;
++}
++
++struct sync_pt *mali_sync_pt_alloc(struct sync_timeline *parent)
++{
++      struct sync_pt *pt = sync_pt_create(parent, sizeof(struct mali_sync_pt));
++      struct mali_sync_timeline *mtl = to_mali_sync_timeline(parent);
++      struct mali_sync_pt *mpt;
++
++      if (!pt)
++      {
++              return NULL;
++      }
++
++      mpt = to_mali_sync_pt(pt);
++      mpt->order = atomic_inc_return(&mtl->counter);
++      mpt->error = 0;
++
++      return pt;
++}
++
++void mali_sync_signal_pt(struct sync_pt *pt, int error)
++{
++      struct mali_sync_pt *mpt = to_mali_sync_pt(pt);
++      struct mali_sync_timeline *mtl = to_mali_sync_timeline(pt->parent);
++      int signalled;
++      long diff;
++
++      if (0 != error)
++      {
++              MALI_DEBUG_ASSERT(0 > error);
++              mpt->error = error;
++      }
++
++      do {
++
++              signalled = atomic_read(&mtl->signalled);
++
++              diff = signalled - mpt->order;
++
++              if (diff > 0)
++              {
++                      /* The timeline is already at or ahead of this point. This should not happen unless userspace
++                       * has been signalling fences out of order, so warn but don't violate the sync_pt API.
++                       * The warning is only in debug builds to prevent a malicious user being able to spam dmesg.
++                       */
++                      MALI_DEBUG_PRINT_ERROR(("Sync points were triggerd in a different order to allocation!\n"));
++                      return;
++              }
++      } while (atomic_cmpxchg(&mtl->signalled, signalled, mpt->order) != signalled);
++
++      sync_timeline_signal(pt->parent);
++}
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_sync.h b/drivers/gpu/arm/mali400/mali/linux/mali_sync.h
+new file mode 100644
+index 0000000..efd8179
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_sync.h
+@@ -0,0 +1,81 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_sync.h
++ *
++ */
++
++#ifndef _MALI_SYNC_H_
++#define _MALI_SYNC_H_
++
++#include <linux/version.h>
++#ifdef CONFIG_SYNC
++/* MALI_SEC */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
++
++#include <linux/seq_file.h>
++#include <linux/sync.h>
++
++/*
++ * Create a stream object.
++ * Built on top of timeline object.
++ * Exposed as a file descriptor.
++ * Life-time controlled via the file descriptor:
++ * - dup to add a ref
++ * - close to remove a ref
++ */
++_mali_osk_errcode_t mali_stream_create(const char * name, int * out_fd);
++
++/*
++ * Create a fence in a stream object
++ */
++struct sync_pt *mali_stream_create_point(int tl_fd);
++int mali_stream_create_fence(struct sync_pt *pt);
++
++/*
++ * Validate a fd to be a valid fence
++ * No reference is taken.
++ *
++ * This function is only usable to catch unintentional user errors early,
++ * it does not stop malicious code changing the fd after this function returns.
++ */
++_mali_osk_errcode_t mali_fence_validate(int fd);
++
++
++/* Returns true if the specified timeline is allocated by Mali */
++int mali_sync_timeline_is_ours(struct sync_timeline *timeline);
++
++/* Allocates a timeline for Mali
++ *
++ * One timeline should be allocated per API context.
++ */
++struct sync_timeline *mali_sync_timeline_alloc(const char *name);
++
++/* Allocates a sync point within the timeline.
++ *
++ * The timeline must be the one allocated by mali_sync_timeline_alloc
++ *
++ * Sync points must be triggered in *exactly* the same order as they are allocated.
++ */
++struct sync_pt *mali_sync_pt_alloc(struct sync_timeline *parent);
++
++/* Signals a particular sync point
++ *
++ * Sync points must be triggered in *exactly* the same order as they are allocated.
++ *
++ * If they are signalled in the wrong order then a message will be printed in debug
++ * builds and otherwise attempts to signal order sync_pts will be ignored.
++ */
++void mali_sync_signal_pt(struct sync_pt *pt, int error);
++
++#endif
++#endif /* CONFIG_SYNC */
++#endif /* _MALI_SYNC_H_ */
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_sync_user.c b/drivers/gpu/arm/mali400/mali/linux/mali_sync_user.c
+new file mode 100644
+index 0000000..c346668
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_sync_user.c
+@@ -0,0 +1,159 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_sync_user.c
++ *
++ */
++
++#ifdef CONFIG_SYNC
++
++#include <linux/sched.h>
++#include <linux/fdtable.h>
++#include <linux/file.h>
++#include <linux/fs.h>
++#include <linux/module.h>
++#include <linux/anon_inodes.h>
++#include <linux/version.h>
++#include <asm/uaccess.h>
++
++/* MALI_SEC */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
++#include "mali_osk.h"
++#include "mali_kernel_common.h"
++#include "mali_sync.h"
++
++static int mali_stream_close(struct inode * inode, struct file * file)
++{
++      struct sync_timeline * tl;
++      tl = (struct sync_timeline*)file->private_data;
++      BUG_ON(!tl);
++      sync_timeline_destroy(tl);
++      return 0;
++}
++
++static struct file_operations stream_fops =
++{
++      .owner = THIS_MODULE,
++      .release = mali_stream_close,
++};
++
++_mali_osk_errcode_t mali_stream_create(const char * name, int *out_fd)
++{
++      struct sync_timeline * tl;
++      BUG_ON(!out_fd);
++
++      tl = mali_sync_timeline_alloc(name);
++      if (!tl)
++      {
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      *out_fd = anon_inode_getfd(name, &stream_fops, tl, O_RDONLY | O_CLOEXEC);
++
++      if (*out_fd < 0)
++      {
++              sync_timeline_destroy(tl);
++              return _MALI_OSK_ERR_FAULT;
++      }
++      else
++      {
++              return _MALI_OSK_ERR_OK;
++      }
++}
++
++mali_sync_pt *mali_stream_create_point(int tl_fd)
++{
++      struct sync_timeline *tl;
++      struct sync_pt * pt;
++      struct file *tl_file;
++
++      tl_file = fget(tl_fd);
++      if (tl_file == NULL)
++              return NULL;
++
++      if (tl_file->f_op != &stream_fops)
++      {
++              pt = NULL;
++              goto out;
++      }
++
++      tl = tl_file->private_data;
++
++      pt = mali_sync_pt_alloc(tl);
++      if (!pt)
++      {
++              pt = NULL;
++              goto out;
++      }
++
++out:
++      fput(tl_file);
++
++      return pt;
++}
++
++int mali_stream_create_fence(mali_sync_pt *pt)
++{
++      struct sync_fence *fence;
++      struct fdtable * fdt;
++      struct files_struct * files;
++      int fd = -1;
++
++      fence = sync_fence_create("mali_fence", pt);
++      if (!fence)
++      {
++              sync_pt_free(pt);
++              fd = -EFAULT;
++              goto out;
++      }
++
++      /* create a fd representing the fence */
++      fd = get_unused_fd();
++      if (fd < 0)
++      {
++              sync_fence_put(fence);
++              goto out;
++      }
++
++      files = current->files;
++      spin_lock(&files->file_lock);
++      fdt = files_fdtable(files);
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
++      __set_close_on_exec(fd, fdt);
++#else
++      FD_SET(fd, fdt->close_on_exec);
++#endif
++      spin_unlock(&files->file_lock);
++
++      /* bind fence to the new fd */
++      sync_fence_install(fence, fd);
++
++out:
++      return fd;
++}
++
++_mali_osk_errcode_t mali_fence_validate(int fd)
++{
++      struct sync_fence * fence;
++      fence = sync_fence_fdget(fd);
++      if (NULL != fence)
++      {
++              sync_fence_put(fence);
++              return _MALI_OSK_ERR_OK;
++      }
++      else
++      {
++              return _MALI_OSK_ERR_FAULT;
++      }
++}
++
++#endif
++#endif /* CONFIG_SYNC */
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_uk_types.h b/drivers/gpu/arm/mali400/mali/linux/mali_uk_types.h
+new file mode 100644
+index 0000000..d6efb8e
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_uk_types.h
+@@ -0,0 +1,17 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_UK_TYPES_H__
++#define __MALI_UK_TYPES_H__
++
++/* Simple wrapper in order to find the OS specific location of this file */
++#include <linux/mali/mali_utgard_uk_types.h>
++
++#endif /* __MALI_UK_TYPES_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_ukk_core.c b/drivers/gpu/arm/mali400/mali/linux/mali_ukk_core.c
+new file mode 100644
+index 0000000..ccf3692
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_ukk_core.c
+@@ -0,0 +1,153 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++#include <linux/fs.h>       /* file system operations */
++#include <linux/slab.h>     /* memort allocation functions */
++#include <asm/uaccess.h>    /* user space access */
++
++#include "mali_ukk.h"
++#include "mali_osk.h"
++#include "mali_kernel_common.h"
++#include "mali_session.h"
++#include "mali_ukk_wrappers.h"
++#include "mali_sync.h"
++
++int get_api_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_api_version_s __user *uargs)
++{
++      _mali_uk_get_api_version_s kargs;
++    _mali_osk_errcode_t err;
++
++    MALI_CHECK_NON_NULL(uargs, -EINVAL);
++
++    if (0 != get_user(kargs.version, &uargs->version)) return -EFAULT;
++
++    kargs.ctx = session_data;
++    err = _mali_ukk_get_api_version(&kargs);
++    if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
++
++    if (0 != put_user(kargs.version, &uargs->version)) return -EFAULT;
++    if (0 != put_user(kargs.compatible, &uargs->compatible)) return -EFAULT;
++
++    return 0;
++}
++
++int wait_for_notification_wrapper(struct mali_session_data *session_data, _mali_uk_wait_for_notification_s __user *uargs)
++{
++    _mali_uk_wait_for_notification_s kargs;
++    _mali_osk_errcode_t err;
++
++    MALI_CHECK_NON_NULL(uargs, -EINVAL);
++
++    kargs.ctx = session_data;
++    err = _mali_ukk_wait_for_notification(&kargs);
++    if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
++
++      if(_MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS != kargs.type)
++      {
++              kargs.ctx = NULL; /* prevent kernel address to be returned to user space */
++              if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_wait_for_notification_s))) return -EFAULT;
++      }
++      else
++      {
++              if (0 != put_user(kargs.type, &uargs->type)) return -EFAULT;
++      }
++
++    return 0;
++}
++
++int post_notification_wrapper(struct mali_session_data *session_data, _mali_uk_post_notification_s __user *uargs)
++{
++      _mali_uk_post_notification_s kargs;
++      _mali_osk_errcode_t err;
++
++      MALI_CHECK_NON_NULL(uargs, -EINVAL);
++
++      kargs.ctx = session_data;
++
++      if (0 != get_user(kargs.type, &uargs->type))
++      {
++              return -EFAULT;
++      }
++
++      err = _mali_ukk_post_notification(&kargs);
++      if (_MALI_OSK_ERR_OK != err)
++      {
++              return map_errcode(err);
++      }
++
++      return 0;
++}
++
++int get_user_settings_wrapper(struct mali_session_data *session_data, _mali_uk_get_user_settings_s __user *uargs)
++{
++      _mali_uk_get_user_settings_s kargs;
++      _mali_osk_errcode_t err;
++
++      MALI_CHECK_NON_NULL(uargs, -EINVAL);
++
++      kargs.ctx = session_data;
++      err = _mali_ukk_get_user_settings(&kargs);
++      if (_MALI_OSK_ERR_OK != err)
++      {
++              return map_errcode(err);
++      }
++
++      kargs.ctx = NULL; /* prevent kernel address to be returned to user space */
++      if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_get_user_settings_s))) return -EFAULT;
++
++      return 0;
++}
++
++#ifdef CONFIG_SYNC
++/* MALI_SEC */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
++int stream_create_wrapper(struct mali_session_data *session_data, _mali_uk_stream_create_s __user *uargs)
++{
++      _mali_uk_stream_create_s kargs;
++      _mali_osk_errcode_t err;
++      char name[32];
++
++      MALI_CHECK_NON_NULL(uargs, -EINVAL);
++
++      snprintf(name, 32, "mali-%u", _mali_osk_get_pid());
++
++      kargs.ctx = session_data;
++      err = mali_stream_create(name, &kargs.fd);
++      if (_MALI_OSK_ERR_OK != err)
++      {
++              return map_errcode(err);
++      }
++
++      kargs.ctx = NULL; /* prevent kernel address to be returned to user space */
++      if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_stream_create_s))) return -EFAULT;
++
++      return 0;
++}
++
++int sync_fence_validate_wrapper(struct mali_session_data *session, _mali_uk_fence_validate_s __user *uargs)
++{
++      int fd;
++      _mali_osk_errcode_t err;
++
++      if (0 != get_user(fd, &uargs->fd))
++      {
++              return -EFAULT;
++      }
++
++      err = mali_fence_validate(fd);
++
++      if (_MALI_OSK_ERR_OK == err)
++      {
++              return 0;
++      }
++
++      return -EINVAL;
++}
++#endif
++#endif
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_ukk_gp.c b/drivers/gpu/arm/mali400/mali/linux/mali_ukk_gp.c
+new file mode 100644
+index 0000000..598e299
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_ukk_gp.c
+@@ -0,0 +1,88 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++#include <linux/fs.h>       /* file system operations */
++#include <asm/uaccess.h>    /* user space access */
++
++#include "mali_ukk.h"
++#include "mali_osk.h"
++#include "mali_kernel_common.h"
++#include "mali_session.h"
++#include "mali_ukk_wrappers.h"
++
++int gp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_gp_start_job_s __user *uargs)
++{
++      _mali_osk_errcode_t err;
++
++      MALI_CHECK_NON_NULL(uargs, -EINVAL);
++      MALI_CHECK_NON_NULL(session_data, -EINVAL);
++
++      err = _mali_ukk_gp_start_job(session_data, uargs);
++      if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
++
++      return 0;
++}
++
++int gp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_gp_core_version_s __user *uargs)
++{
++    _mali_uk_get_gp_core_version_s kargs;
++    _mali_osk_errcode_t err;
++
++    MALI_CHECK_NON_NULL(uargs, -EINVAL);
++    MALI_CHECK_NON_NULL(session_data, -EINVAL);
++
++    kargs.ctx = session_data;
++    err =  _mali_ukk_get_gp_core_version(&kargs);
++    if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
++
++      /* no known transactions to roll-back */
++
++    if (0 != put_user(kargs.version, &uargs->version)) return -EFAULT;
++
++    return 0;
++}
++
++int gp_suspend_response_wrapper(struct mali_session_data *session_data, _mali_uk_gp_suspend_response_s __user *uargs)
++{
++    _mali_uk_gp_suspend_response_s kargs;
++    _mali_osk_errcode_t err;
++
++    MALI_CHECK_NON_NULL(uargs, -EINVAL);
++    MALI_CHECK_NON_NULL(session_data, -EINVAL);
++
++    if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_gp_suspend_response_s))) return -EFAULT;
++
++    kargs.ctx = session_data;
++    err = _mali_ukk_gp_suspend_response(&kargs);
++    if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
++
++    if (0 != put_user(kargs.cookie, &uargs->cookie)) return -EFAULT;
++
++    /* no known transactions to roll-back */
++    return 0;
++}
++
++int gp_get_number_of_cores_wrapper(struct mali_session_data *session_data, _mali_uk_get_gp_number_of_cores_s __user *uargs)
++{
++    _mali_uk_get_gp_number_of_cores_s kargs;
++    _mali_osk_errcode_t err;
++
++    MALI_CHECK_NON_NULL(uargs, -EINVAL);
++    MALI_CHECK_NON_NULL(session_data, -EINVAL);
++
++    kargs.ctx = session_data;
++    err = _mali_ukk_get_gp_number_of_cores(&kargs);
++    if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
++
++      /* no known transactions to roll-back */
++
++    if (0 != put_user(kargs.number_of_cores, &uargs->number_of_cores)) return -EFAULT;
++
++    return 0;
++}
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_ukk_mem.c b/drivers/gpu/arm/mali400/mali/linux/mali_ukk_mem.c
+new file mode 100644
+index 0000000..6ce45c1
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_ukk_mem.c
+@@ -0,0 +1,259 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++#include <linux/fs.h>       /* file system operations */
++#include <asm/uaccess.h>    /* user space access */
++
++#include "mali_ukk.h"
++#include "mali_osk.h"
++#include "mali_kernel_common.h"
++#include "mali_session.h"
++#include "mali_ukk_wrappers.h"
++
++int mem_init_wrapper(struct mali_session_data *session_data, _mali_uk_init_mem_s __user *uargs)
++{
++    _mali_uk_init_mem_s kargs;
++    _mali_osk_errcode_t err;
++
++    MALI_CHECK_NON_NULL(uargs, -EINVAL);
++
++    kargs.ctx = session_data;
++    err = _mali_ukk_init_mem(&kargs);
++    if (_MALI_OSK_ERR_OK != err)
++    {
++        return map_errcode(err);
++    }
++
++    if (0 != put_user(kargs.mali_address_base, &uargs->mali_address_base)) goto mem_init_rollback;
++    if (0 != put_user(kargs.memory_size, &uargs->memory_size)) goto mem_init_rollback;
++
++    return 0;
++
++mem_init_rollback:
++      {
++              _mali_uk_term_mem_s kargs;
++              kargs.ctx = session_data;
++              err = _mali_ukk_term_mem(&kargs);
++              if (_MALI_OSK_ERR_OK != err)
++              {
++                      MALI_DEBUG_PRINT(4, ("reverting _mali_ukk_init_mem, as a result of failing put_user(), failed\n"));
++              }
++      }
++    return -EFAULT;
++}
++
++int mem_term_wrapper(struct mali_session_data *session_data, _mali_uk_term_mem_s __user *uargs)
++{
++    _mali_uk_term_mem_s kargs;
++    _mali_osk_errcode_t err;
++
++    MALI_CHECK_NON_NULL(uargs, -EINVAL);
++
++    kargs.ctx = session_data;
++    err = _mali_ukk_term_mem(&kargs);
++    if (_MALI_OSK_ERR_OK != err)
++    {
++        return map_errcode(err);
++    }
++
++    return 0;
++}
++
++int mem_map_ext_wrapper(struct mali_session_data *session_data, _mali_uk_map_external_mem_s __user * argument)
++{
++      _mali_uk_map_external_mem_s uk_args;
++      _mali_osk_errcode_t err_code;
++
++      /* validate input */
++      /* the session_data pointer was validated by caller */
++    MALI_CHECK_NON_NULL( argument, -EINVAL);
++
++      /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
++      if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_map_external_mem_s)) )
++      {
++              return -EFAULT;
++      }
++
++    uk_args.ctx = session_data;
++      err_code = _mali_ukk_map_external_mem( &uk_args );
++
++    if (0 != put_user(uk_args.cookie, &argument->cookie))
++    {
++        if (_MALI_OSK_ERR_OK == err_code)
++        {
++            /* Rollback */
++              _mali_uk_unmap_external_mem_s uk_args_unmap;
++
++            uk_args_unmap.ctx = session_data;
++            uk_args_unmap.cookie = uk_args.cookie;
++            err_code = _mali_ukk_unmap_external_mem( &uk_args_unmap );
++            if (_MALI_OSK_ERR_OK != err_code)
++            {
++                MALI_DEBUG_PRINT(4, ("reverting _mali_ukk_unmap_external_mem, as a result of failing put_user(), failed\n"));
++            }
++        }
++        return -EFAULT;
++    }
++
++    /* Return the error that _mali_ukk_free_big_block produced */
++      return map_errcode(err_code);
++}
++
++int mem_unmap_ext_wrapper(struct mali_session_data *session_data, _mali_uk_unmap_external_mem_s __user * argument)
++{
++      _mali_uk_unmap_external_mem_s uk_args;
++      _mali_osk_errcode_t err_code;
++
++      /* validate input */
++      /* the session_data pointer was validated by caller */
++    MALI_CHECK_NON_NULL( argument, -EINVAL);
++
++      /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
++      if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_unmap_external_mem_s)) )
++      {
++              return -EFAULT;
++      }
++
++    uk_args.ctx = session_data;
++      err_code = _mali_ukk_unmap_external_mem( &uk_args );
++
++      /* Return the error that _mali_ukk_free_big_block produced */
++      return map_errcode(err_code);
++}
++
++#if defined(CONFIG_MALI400_UMP)
++int mem_release_ump_wrapper(struct mali_session_data *session_data, _mali_uk_release_ump_mem_s __user * argument)
++{
++      _mali_uk_release_ump_mem_s uk_args;
++      _mali_osk_errcode_t err_code;
++
++      /* validate input */
++      /* the session_data pointer was validated by caller */
++    MALI_CHECK_NON_NULL( argument, -EINVAL);
++
++      /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
++      if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_release_ump_mem_s)) )
++      {
++              return -EFAULT;
++      }
++
++    uk_args.ctx = session_data;
++      err_code = _mali_ukk_release_ump_mem( &uk_args );
++
++      /* Return the error that _mali_ukk_free_big_block produced */
++      return map_errcode(err_code);
++}
++
++int mem_attach_ump_wrapper(struct mali_session_data *session_data, _mali_uk_attach_ump_mem_s __user * argument)
++{
++      _mali_uk_attach_ump_mem_s uk_args;
++      _mali_osk_errcode_t err_code;
++
++      /* validate input */
++      /* the session_data pointer was validated by caller */
++    MALI_CHECK_NON_NULL( argument, -EINVAL);
++
++      /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
++      if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_attach_ump_mem_s)) )
++      {
++              return -EFAULT;
++      }
++
++    uk_args.ctx = session_data;
++      err_code = _mali_ukk_attach_ump_mem( &uk_args );
++
++    if (0 != put_user(uk_args.cookie, &argument->cookie))
++    {
++        if (_MALI_OSK_ERR_OK == err_code)
++        {
++            /* Rollback */
++              _mali_uk_release_ump_mem_s uk_args_unmap;
++
++            uk_args_unmap.ctx = session_data;
++            uk_args_unmap.cookie = uk_args.cookie;
++            err_code = _mali_ukk_release_ump_mem( &uk_args_unmap );
++            if (_MALI_OSK_ERR_OK != err_code)
++            {
++                MALI_DEBUG_PRINT(4, ("reverting _mali_ukk_attach_mem, as a result of failing put_user(), failed\n"));
++            }
++        }
++        return -EFAULT;
++    }
++
++    /* Return the error that _mali_ukk_map_external_ump_mem produced */
++      return map_errcode(err_code);
++}
++#endif /* CONFIG_MALI400_UMP */
++
++int mem_query_mmu_page_table_dump_size_wrapper(struct mali_session_data *session_data, _mali_uk_query_mmu_page_table_dump_size_s __user * uargs)
++{
++    _mali_uk_query_mmu_page_table_dump_size_s kargs;
++    _mali_osk_errcode_t err;
++
++    MALI_CHECK_NON_NULL(uargs, -EINVAL);
++    MALI_CHECK_NON_NULL(session_data, -EINVAL);
++
++    kargs.ctx = session_data;
++
++    err = _mali_ukk_query_mmu_page_table_dump_size(&kargs);
++    if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
++
++    if (0 != put_user(kargs.size, &uargs->size)) return -EFAULT;
++
++    return 0;
++}
++
++int mem_dump_mmu_page_table_wrapper(struct mali_session_data *session_data, _mali_uk_dump_mmu_page_table_s __user * uargs)
++{
++    _mali_uk_dump_mmu_page_table_s kargs;
++    _mali_osk_errcode_t err;
++    void *buffer;
++    int rc = -EFAULT;
++
++      /* validate input */
++    MALI_CHECK_NON_NULL(uargs, -EINVAL);
++      /* the session_data pointer was validated by caller */
++
++    kargs.buffer = NULL;
++
++    /* get location of user buffer */
++      if (0 != get_user(buffer, &uargs->buffer)) goto err_exit;
++      /* get size of mmu page table info buffer from user space */
++      if ( 0 != get_user(kargs.size, &uargs->size) ) goto err_exit;
++    /* verify we can access the whole of the user buffer */
++    if (!access_ok(VERIFY_WRITE, buffer, kargs.size)) goto err_exit;
++
++    /* allocate temporary buffer (kernel side) to store mmu page table info */
++    kargs.buffer = _mali_osk_valloc(kargs.size);
++    if (NULL == kargs.buffer)
++    {
++        rc = -ENOMEM;
++        goto err_exit;
++    }
++
++    kargs.ctx = session_data;
++    err = _mali_ukk_dump_mmu_page_table(&kargs);
++    if (_MALI_OSK_ERR_OK != err)
++    {
++        rc = map_errcode(err);
++        goto err_exit;
++    }
++
++    /* copy mmu page table info back to user space and update pointers */
++      if (0 != copy_to_user(uargs->buffer, kargs.buffer, kargs.size) ) goto err_exit;
++    if (0 != put_user((kargs.register_writes - (u32 *)kargs.buffer) + (u32 *)uargs->buffer, &uargs->register_writes)) goto err_exit;
++    if (0 != put_user((kargs.page_table_dump - (u32 *)kargs.buffer) + (u32 *)uargs->buffer, &uargs->page_table_dump)) goto err_exit;
++    if (0 != put_user(kargs.register_writes_size, &uargs->register_writes_size)) goto err_exit;
++    if (0 != put_user(kargs.page_table_dump_size, &uargs->page_table_dump_size)) goto err_exit;
++    rc = 0;
++
++err_exit:
++    if (kargs.buffer) _mali_osk_vfree(kargs.buffer);
++    return rc;
++}
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_ukk_pp.c b/drivers/gpu/arm/mali400/mali/linux/mali_ukk_pp.c
+new file mode 100644
+index 0000000..0bbd5a5
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_ukk_pp.c
+@@ -0,0 +1,85 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++#include <linux/fs.h>       /* file system operations */
++#include <asm/uaccess.h>    /* user space access */
++
++#include "mali_ukk.h"
++#include "mali_osk.h"
++#include "mali_kernel_common.h"
++#include "mali_session.h"
++#include "mali_ukk_wrappers.h"
++
++int pp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_start_job_s __user *uargs)
++{
++      _mali_osk_errcode_t err;
++      int fence = -1;
++
++      MALI_CHECK_NON_NULL(uargs, -EINVAL);
++      MALI_CHECK_NON_NULL(session_data, -EINVAL);
++
++      err = _mali_ukk_pp_start_job(session_data, uargs, &fence);
++      if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
++
++      if (-1 != fence)
++      {
++              if (0 != put_user(fence, &uargs->fence)) return -EFAULT;
++      }
++
++      return 0;
++}
++
++int pp_get_number_of_cores_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_number_of_cores_s __user *uargs)
++{
++    _mali_uk_get_pp_number_of_cores_s kargs;
++    _mali_osk_errcode_t err;
++
++    MALI_CHECK_NON_NULL(uargs, -EINVAL);
++    MALI_CHECK_NON_NULL(session_data, -EINVAL);
++
++    kargs.ctx = session_data;
++    err = _mali_ukk_get_pp_number_of_cores(&kargs);
++    if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
++
++    if (0 != put_user(kargs.number_of_cores, &uargs->number_of_cores)) return -EFAULT;
++
++    return 0;
++}
++
++int pp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_core_version_s __user *uargs)
++{
++    _mali_uk_get_pp_core_version_s kargs;
++    _mali_osk_errcode_t err;
++
++    MALI_CHECK_NON_NULL(uargs, -EINVAL);
++    MALI_CHECK_NON_NULL(session_data, -EINVAL);
++
++    kargs.ctx = session_data;
++    err = _mali_ukk_get_pp_core_version(&kargs);
++    if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
++
++    if (0 != put_user(kargs.version, &uargs->version)) return -EFAULT;
++
++    return 0;
++}
++
++int pp_disable_wb_wrapper(struct mali_session_data *session_data, _mali_uk_pp_disable_wb_s __user *uargs)
++{
++      _mali_uk_pp_disable_wb_s kargs;
++
++    MALI_CHECK_NON_NULL(uargs, -EINVAL);
++    MALI_CHECK_NON_NULL(session_data, -EINVAL);
++
++    if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_pp_disable_wb_s))) return -EFAULT;
++
++    kargs.ctx = session_data;
++    _mali_ukk_pp_job_disable_wb(&kargs);
++
++    return 0;
++}
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_ukk_profiling.c b/drivers/gpu/arm/mali400/mali/linux/mali_ukk_profiling.c
+new file mode 100644
+index 0000000..236f8e5
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_ukk_profiling.c
+@@ -0,0 +1,181 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++#include <linux/fs.h>       /* file system operations */
++#include <asm/uaccess.h>    /* user space access */
++#include <linux/slab.h>
++
++#include "mali_ukk.h"
++#include "mali_osk.h"
++#include "mali_kernel_common.h"
++#include "mali_session.h"
++#include "mali_ukk_wrappers.h"
++
++int profiling_start_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_start_s __user *uargs)
++{
++      _mali_uk_profiling_start_s kargs;
++      _mali_osk_errcode_t err;
++
++      MALI_CHECK_NON_NULL(uargs, -EINVAL);
++
++      if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_profiling_start_s)))
++      {
++              return -EFAULT;
++      }
++
++      kargs.ctx = session_data;
++      err = _mali_ukk_profiling_start(&kargs);
++      if (_MALI_OSK_ERR_OK != err)
++      {
++              return map_errcode(err);
++      }
++
++      if (0 != put_user(kargs.limit, &uargs->limit))
++      {
++              return -EFAULT;
++      }
++
++      return 0;
++}
++
++int profiling_add_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_add_event_s __user *uargs)
++{
++      _mali_uk_profiling_add_event_s kargs;
++      _mali_osk_errcode_t err;
++
++      MALI_CHECK_NON_NULL(uargs, -EINVAL);
++
++      if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_profiling_add_event_s)))
++      {
++              return -EFAULT;
++      }
++
++      kargs.ctx = session_data;
++      err = _mali_ukk_profiling_add_event(&kargs);
++      if (_MALI_OSK_ERR_OK != err)
++      {
++              return map_errcode(err);
++      }
++
++      return 0;
++}
++
++int profiling_stop_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_stop_s __user *uargs)
++{
++      _mali_uk_profiling_stop_s kargs;
++      _mali_osk_errcode_t err;
++
++      MALI_CHECK_NON_NULL(uargs, -EINVAL);
++
++      kargs.ctx = session_data;
++      err = _mali_ukk_profiling_stop(&kargs);
++      if (_MALI_OSK_ERR_OK != err)
++      {
++              return map_errcode(err);
++      }
++
++      if (0 != put_user(kargs.count, &uargs->count))
++      {
++              return -EFAULT;
++      }
++
++      return 0;
++}
++
++int profiling_get_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_get_event_s __user *uargs)
++{
++      _mali_uk_profiling_get_event_s kargs;
++      _mali_osk_errcode_t err;
++
++      MALI_CHECK_NON_NULL(uargs, -EINVAL);
++
++      if (0 != get_user(kargs.index, &uargs->index))
++      {
++              return -EFAULT;
++      }
++
++      kargs.ctx = session_data;
++
++      err = _mali_ukk_profiling_get_event(&kargs);
++      if (_MALI_OSK_ERR_OK != err)
++      {
++              return map_errcode(err);
++      }
++
++      kargs.ctx = NULL; /* prevent kernel address to be returned to user space */
++      if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_profiling_get_event_s)))
++      {
++              return -EFAULT;
++      }
++
++      return 0;
++}
++
++int profiling_clear_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_clear_s __user *uargs)
++{
++      _mali_uk_profiling_clear_s kargs;
++      _mali_osk_errcode_t err;
++
++      MALI_CHECK_NON_NULL(uargs, -EINVAL);
++
++      kargs.ctx = session_data;
++      err = _mali_ukk_profiling_clear(&kargs);
++      if (_MALI_OSK_ERR_OK != err)
++      {
++              return map_errcode(err);
++      }
++
++      return 0;
++}
++
++int profiling_report_sw_counters_wrapper(struct mali_session_data *session_data, _mali_uk_sw_counters_report_s __user *uargs)
++{
++      _mali_uk_sw_counters_report_s kargs;
++      _mali_osk_errcode_t err;
++      u32 *counter_buffer;
++
++      MALI_CHECK_NON_NULL(uargs, -EINVAL);
++
++      if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_sw_counters_report_s)))
++      {
++              return -EFAULT;
++      }
++
++      /* make sure that kargs.num_counters is [at least somewhat] sane */
++      if (kargs.num_counters > 10000) {
++              MALI_DEBUG_PRINT(1, ("User space attempted to allocate too many counters.\n"));
++              return -EINVAL;
++      }
++
++      counter_buffer = (u32*)kmalloc(sizeof(u32) * kargs.num_counters, GFP_KERNEL);
++      if (NULL == counter_buffer)
++      {
++              return -ENOMEM;
++      }
++
++      if (0 != copy_from_user(counter_buffer, kargs.counters, sizeof(u32) * kargs.num_counters))
++      {
++              kfree(counter_buffer);
++              return -EFAULT;
++      }
++
++      kargs.ctx = session_data;
++      kargs.counters = counter_buffer;
++
++      err = _mali_ukk_sw_counters_report(&kargs);
++
++      kfree(counter_buffer);
++
++      if (_MALI_OSK_ERR_OK != err)
++      {
++              return map_errcode(err);
++      }
++
++      return 0;
++}
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_ukk_vsync.c b/drivers/gpu/arm/mali400/mali/linux/mali_ukk_vsync.c
+new file mode 100644
+index 0000000..184aa08
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_ukk_vsync.c
+@@ -0,0 +1,41 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++#include <linux/fs.h>       /* file system operations */
++#include <asm/uaccess.h>    /* user space access */
++
++#include "mali_ukk.h"
++#include "mali_osk.h"
++#include "mali_kernel_common.h"
++#include "mali_session.h"
++#include "mali_ukk_wrappers.h"
++
++
++int vsync_event_report_wrapper(struct mali_session_data *session_data, _mali_uk_vsync_event_report_s __user *uargs)
++{
++      _mali_uk_vsync_event_report_s kargs;
++      _mali_osk_errcode_t err;
++
++      MALI_CHECK_NON_NULL(uargs, -EINVAL);
++
++      if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_vsync_event_report_s)))
++      {
++              return -EFAULT;
++      }
++
++      kargs.ctx = session_data;
++      err = _mali_ukk_vsync_event_report(&kargs);
++      if (_MALI_OSK_ERR_OK != err)
++      {
++              return map_errcode(err);
++      }
++
++      return 0;
++}
++
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_ukk_wrappers.h b/drivers/gpu/arm/mali400/mali/linux/mali_ukk_wrappers.h
+new file mode 100644
+index 0000000..0ad27fa
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_ukk_wrappers.h
+@@ -0,0 +1,75 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_ukk_wrappers.h
++ * Defines the wrapper functions for each user-kernel function
++ */
++
++#ifndef __MALI_UKK_WRAPPERS_H__
++#define __MALI_UKK_WRAPPERS_H__
++
++#include "mali_uk_types.h"
++#include "mali_osk.h"
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif
++
++int wait_for_notification_wrapper(struct mali_session_data *session_data, _mali_uk_wait_for_notification_s __user *uargs);
++int get_api_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_api_version_s __user *uargs);
++int get_user_settings_wrapper(struct mali_session_data *session_data, _mali_uk_get_user_settings_s __user *uargs);
++#if defined(CONFIG_SYNC)
++/* MALI_SEC */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
++int stream_create_wrapper(struct mali_session_data *session_data, _mali_uk_stream_create_s __user *uargs);
++int sync_fence_validate_wrapper(struct mali_session_data *session, _mali_uk_fence_validate_s __user *uargs);
++#endif
++#endif
++int post_notification_wrapper(struct mali_session_data *session_data, _mali_uk_post_notification_s __user *uargs);
++int mem_init_wrapper(struct mali_session_data *session_data, _mali_uk_init_mem_s __user *uargs);
++int mem_term_wrapper(struct mali_session_data *session_data, _mali_uk_term_mem_s __user *uargs);
++int mem_map_ext_wrapper(struct mali_session_data *session_data, _mali_uk_map_external_mem_s __user * argument);
++int mem_unmap_ext_wrapper(struct mali_session_data *session_data, _mali_uk_unmap_external_mem_s __user * argument);
++int mem_query_mmu_page_table_dump_size_wrapper(struct mali_session_data *session_data, _mali_uk_query_mmu_page_table_dump_size_s __user * uargs);
++int mem_dump_mmu_page_table_wrapper(struct mali_session_data *session_data, _mali_uk_dump_mmu_page_table_s __user * uargs);
++
++#if defined(CONFIG_MALI400_UMP)
++int mem_attach_ump_wrapper(struct mali_session_data *session_data, _mali_uk_attach_ump_mem_s __user * argument);
++int mem_release_ump_wrapper(struct mali_session_data *session_data, _mali_uk_release_ump_mem_s __user * argument);
++#endif
++
++int pp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_start_job_s __user *uargs);
++int pp_get_number_of_cores_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_number_of_cores_s __user *uargs);
++int pp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_core_version_s __user *uargs);
++int pp_disable_wb_wrapper(struct mali_session_data *session_data, _mali_uk_pp_disable_wb_s __user *uargs);
++int gp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_gp_start_job_s __user *uargs);
++int gp_get_number_of_cores_wrapper(struct mali_session_data *session_data, _mali_uk_get_gp_number_of_cores_s __user *uargs);
++int gp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_gp_core_version_s __user *uargs);
++int gp_suspend_response_wrapper(struct mali_session_data *session_data, _mali_uk_gp_suspend_response_s __user *uargs);
++
++int profiling_start_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_start_s __user *uargs);
++int profiling_add_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_add_event_s __user *uargs);
++int profiling_stop_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_stop_s __user *uargs);
++int profiling_get_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_get_event_s __user *uargs);
++int profiling_clear_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_clear_s __user *uargs);
++int profiling_report_sw_counters_wrapper(struct mali_session_data *session_data, _mali_uk_sw_counters_report_s __user *uargs);
++
++int vsync_event_report_wrapper(struct mali_session_data *session_data, _mali_uk_vsync_event_report_s __user *uargs);
++
++
++int map_errcode( _mali_osk_errcode_t err );
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* __MALI_UKK_WRAPPERS_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/platform/arm/arm.c b/drivers/gpu/arm/mali400/mali/platform/arm/arm.c
+new file mode 100644
+index 0000000..fd6769e
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/platform/arm/arm.c
+@@ -0,0 +1,209 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_platform.c
++ * Platform specific Mali driver functions for:
++ * - Realview Versatile platforms with ARM11 Mpcore and virtex 5.
++ * - Versatile Express platforms with ARM Cortex-A9 and virtex 6.
++ */
++#include <linux/platform_device.h>
++#include <linux/version.h>
++#include <linux/pm.h>
++#ifdef CONFIG_PM_RUNTIME
++#include <linux/pm_runtime.h>
++#endif
++#include <asm/io.h>
++#include <linux/mali/mali_utgard.h>
++#include "mali_kernel_common.h"
++
++static void mali_platform_device_release(struct device *device);
++static u32 mali_read_phys(u32 phys_addr);
++#if defined(CONFIG_ARCH_REALVIEW)
++static void mali_write_phys(u32 phys_addr, u32 value);
++#endif
++
++#if defined(CONFIG_ARCH_VEXPRESS)
++
++static struct resource mali_gpu_resources_m450_mp8[] =
++{
++      MALI_GPU_RESOURCES_MALI450_MP8_PMU(0xFC040000, -1, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 68)
++};
++
++#elif defined(CONFIG_ARCH_REALVIEW)
++
++static struct resource mali_gpu_resources_m200[] =
++{
++      MALI_GPU_RESOURCES_MALI200(0xC0000000, -1, -1, -1)
++};
++
++static struct resource mali_gpu_resources_m300[] =
++{
++      MALI_GPU_RESOURCES_MALI300_PMU(0xC0000000, -1, -1, -1, -1)
++};
++
++static struct resource mali_gpu_resources_m400_mp1[] =
++{
++      MALI_GPU_RESOURCES_MALI400_MP1_PMU(0xC0000000, -1, -1, -1, -1)
++};
++
++static struct resource mali_gpu_resources_m400_mp2[] =
++{
++      MALI_GPU_RESOURCES_MALI400_MP2_PMU(0xC0000000, -1, -1, -1, -1, -1, -1)
++};
++
++#endif
++
++static struct platform_device mali_gpu_device =
++{
++      .name = MALI_GPU_NAME_UTGARD,
++      .id = 0,
++      .dev.release = mali_platform_device_release,
++};
++
++static struct mali_gpu_device_data mali_gpu_data =
++{
++#if defined(CONFIG_ARCH_VEXPRESS)
++      .shared_mem_size =256 * 1024 * 1024, /* 256MB */
++#elif defined(CONFIG_ARCH_REALVIEW)
++      .dedicated_mem_start = 0x80000000, /* Physical start address (use 0xD0000000 for old indirect setup) */
++      .dedicated_mem_size = 0x10000000, /* 256MB */
++#endif
++      .fb_start = 0xe0000000,
++      .fb_size = 0x01000000,
++};
++
++int mali_platform_device_register(void)
++{
++      int err = -1;
++#if defined(CONFIG_ARCH_REALVIEW)
++      u32 m400_gp_version;
++#endif
++
++      MALI_DEBUG_PRINT(4, ("mali_platform_device_register() called\n"));
++
++      /* Detect present Mali GPU and connect the correct resources to the device */
++#if defined(CONFIG_ARCH_VEXPRESS)
++
++      if (mali_read_phys(0xFC020000) == 0x00010100)
++      {
++              MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP8 device\n"));
++              err = platform_device_add_resources(&mali_gpu_device, mali_gpu_resources_m450_mp8, sizeof(mali_gpu_resources_m450_mp8) / sizeof(mali_gpu_resources_m450_mp8[0]));
++      }
++
++#elif defined(CONFIG_ARCH_REALVIEW)
++
++      m400_gp_version = mali_read_phys(0xC000006C);
++      if (m400_gp_version == 0x00000000 && (mali_read_phys(0xC000206c) & 0xFFFF0000) == 0x0A070000)
++      {
++              MALI_DEBUG_PRINT(4, ("Registering Mali-200 device\n"));
++              err = platform_device_add_resources(&mali_gpu_device, mali_gpu_resources_m200, sizeof(mali_gpu_resources_m200) / sizeof(mali_gpu_resources_m200[0]));
++              mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */
++      }
++      else if ((m400_gp_version & 0xFFFF0000) == 0x0C070000)
++      {
++              MALI_DEBUG_PRINT(4, ("Registering Mali-300 device\n"));
++              err = platform_device_add_resources(&mali_gpu_device, mali_gpu_resources_m300, sizeof(mali_gpu_resources_m300) / sizeof(mali_gpu_resources_m300[0]));
++              mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */
++      }
++      else if ((m400_gp_version & 0xFFFF0000) == 0x0B070000)
++      {
++              u32 fpga_fw_version = mali_read_phys(0xC0010000);
++              if (fpga_fw_version == 0x130C008F || fpga_fw_version == 0x110C008F)
++              {
++                      /* Mali-400 MP1 r1p0 or r1p1 */
++                      MALI_DEBUG_PRINT(4, ("Registering Mali-400 MP1 device\n"));
++                      err = platform_device_add_resources(&mali_gpu_device, mali_gpu_resources_m400_mp1, sizeof(mali_gpu_resources_m400_mp1) / sizeof(mali_gpu_resources_m400_mp1[0]));
++                      mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */
++              }
++              else if (fpga_fw_version == 0x130C000F)
++              {
++                      /* Mali-400 MP2 r1p1 */
++                      MALI_DEBUG_PRINT(4, ("Registering Mali-400 MP2 device\n"));
++                      err = platform_device_add_resources(&mali_gpu_device, mali_gpu_resources_m400_mp2, sizeof(mali_gpu_resources_m400_mp2) / sizeof(mali_gpu_resources_m400_mp2[0]));
++                      mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */
++              }
++      }
++
++#endif
++
++      if (0 == err)
++      {
++              err = platform_device_add_data(&mali_gpu_device, &mali_gpu_data, sizeof(mali_gpu_data));
++              if (0 == err)
++              {
++                      /* Register the platform device */
++                      err = platform_device_register(&mali_gpu_device);
++                      if (0 == err)
++                      {
++#ifdef CONFIG_PM_RUNTIME
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
++                              pm_runtime_set_autosuspend_delay(&(mali_gpu_device.dev), 1000);
++                              pm_runtime_use_autosuspend(&(mali_gpu_device.dev));
++#endif
++                              pm_runtime_enable(&(mali_gpu_device.dev));
++#endif
++
++                              return 0;
++                      }
++              }
++
++              platform_device_unregister(&mali_gpu_device);
++      }
++
++      return err;
++}
++
++void mali_platform_device_unregister(void)
++{
++      MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n"));
++
++      platform_device_unregister(&mali_gpu_device);
++
++#if defined(CONFIG_ARCH_REALVIEW)
++      mali_write_phys(0xC0010020, 0x9); /* Restore default (legacy) memory mapping */
++#endif
++}
++
++static void mali_platform_device_release(struct device *device)
++{
++      MALI_DEBUG_PRINT(4, ("mali_platform_device_release() called\n"));
++}
++
++static u32 mali_read_phys(u32 phys_addr)
++{
++      u32 phys_addr_page = phys_addr & 0xFFFFE000;
++      u32 phys_offset    = phys_addr & 0x00001FFF;
++      u32 map_size       = phys_offset + sizeof(u32);
++      u32 ret = 0xDEADBEEF;
++      void *mem_mapped = ioremap_nocache(phys_addr_page, map_size);
++      if (NULL != mem_mapped)
++      {
++              ret = (u32)ioread32(((u8*)mem_mapped) + phys_offset);
++              iounmap(mem_mapped);
++      }
++
++      return ret;
++}
++
++#if defined(CONFIG_ARCH_REALVIEW)
++static void mali_write_phys(u32 phys_addr, u32 value)
++{
++      u32 phys_addr_page = phys_addr & 0xFFFFE000;
++      u32 phys_offset    = phys_addr & 0x00001FFF;
++      u32 map_size       = phys_offset + sizeof(u32);
++      void *mem_mapped = ioremap_nocache(phys_addr_page, map_size);
++      if (NULL != mem_mapped)
++      {
++              iowrite32(value, ((u8*)mem_mapped) + phys_offset);
++              iounmap(mem_mapped);
++      }
++}
++#endif
+diff --git a/drivers/gpu/arm/mali400/mali/platform/default/mali_platform.c b/drivers/gpu/arm/mali400/mali/platform/default/mali_platform.c
+new file mode 100644
+index 0000000..8f1b781
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/platform/default/mali_platform.c
+@@ -0,0 +1,41 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_platform.c
++ * Platform specific Mali driver functions for a default platform
++ */
++#include "mali_kernel_common.h"
++#include "mali_osk.h"
++#include "mali_platform.h"
++
++
++_mali_osk_errcode_t mali_platform_init(void)
++{
++    MALI_SUCCESS;
++}
++
++_mali_osk_errcode_t mali_platform_deinit(void)
++{
++    MALI_SUCCESS;
++}
++
++_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode)
++{
++    MALI_SUCCESS;
++}
++
++void mali_gpu_utilization_handler(u32 utilization)
++{
++}
++
++void set_mali_parent_power_domain(void* dev)
++{
++}
+diff --git a/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4.c b/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4.c
+new file mode 100644
+index 0000000..bc77dbf
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4.c
+@@ -0,0 +1,320 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_platform.c
++ * Platform specific Mali driver functions for the exynos 4XXX based platforms
++ */
++#include <linux/platform_device.h>
++#include <linux/version.h>
++#include <linux/pm.h>
++#ifdef CONFIG_PM_RUNTIME
++#include <linux/pm_runtime.h>
++#endif
++#include <linux/mali/mali_utgard.h>
++#include "mali_kernel_common.h"
++
++#include <plat/pd.h>
++
++#include "exynos4_pmm.h"
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
++struct exynos_pm_domain;
++extern struct exynos_pm_domain exynos4_pd_g3d;
++void exynos_pm_add_dev_to_genpd(struct platform_device *pdev, struct exynos_pm_domain *pd);
++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
++extern struct platform_device exynos4_device_pd[];
++#else
++extern struct platform_device s5pv310_device_pd[];
++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) */
++
++static void mali_platform_device_release(struct device *device);
++static int mali_os_suspend(struct device *device);
++static int mali_os_resume(struct device *device);
++static int mali_os_freeze(struct device *device);
++static int mali_os_thaw(struct device *device);
++#ifdef CONFIG_PM_RUNTIME
++static int mali_runtime_suspend(struct device *device);
++static int mali_runtime_resume(struct device *device);
++static int mali_runtime_idle(struct device *device);
++#endif
++
++#if defined(CONFIG_ARCH_S5PV310) && !defined(CONFIG_BOARD_HKDKC210)
++
++/* This is for other SMDK boards */
++#define MALI_BASE_IRQ 232
++
++#else
++
++/* This is for the Odroid boards */
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
++#define MALI_BASE_IRQ 182
++#else
++#define MALI_BASE_IRQ 150
++#endif
++
++#endif
++
++#define MALI_GP_IRQ       MALI_BASE_IRQ + 9
++#define MALI_PP0_IRQ      MALI_BASE_IRQ + 5
++#define MALI_PP1_IRQ      MALI_BASE_IRQ + 6
++#define MALI_PP2_IRQ      MALI_BASE_IRQ + 7
++#define MALI_PP3_IRQ      MALI_BASE_IRQ + 8
++#define MALI_GP_MMU_IRQ   MALI_BASE_IRQ + 4
++#define MALI_PP0_MMU_IRQ  MALI_BASE_IRQ + 0
++#define MALI_PP1_MMU_IRQ  MALI_BASE_IRQ + 1
++#define MALI_PP2_MMU_IRQ  MALI_BASE_IRQ + 2
++#define MALI_PP3_MMU_IRQ  MALI_BASE_IRQ + 3
++
++static struct resource mali_gpu_resources[] =
++{
++      MALI_GPU_RESOURCES_MALI400_MP4(0x13000000,
++                                     MALI_GP_IRQ, MALI_GP_MMU_IRQ,
++                                     MALI_PP0_IRQ, MALI_PP0_MMU_IRQ,
++                                     MALI_PP1_IRQ, MALI_PP1_MMU_IRQ,
++                                     MALI_PP2_IRQ, MALI_PP2_MMU_IRQ,
++                                     MALI_PP3_IRQ, MALI_PP3_MMU_IRQ)
++};
++
++static struct dev_pm_ops mali_gpu_device_type_pm_ops =
++{
++      .suspend = mali_os_suspend,
++      .resume = mali_os_resume,
++      .freeze = mali_os_freeze,
++      .thaw = mali_os_thaw,
++#ifdef CONFIG_PM_RUNTIME
++      .runtime_suspend = mali_runtime_suspend,
++      .runtime_resume = mali_runtime_resume,
++      .runtime_idle = mali_runtime_idle,
++#endif
++};
++
++static struct device_type mali_gpu_device_device_type =
++{
++      .pm = &mali_gpu_device_type_pm_ops,
++};
++
++static struct platform_device mali_gpu_device =
++{
++      .name = MALI_GPU_NAME_UTGARD,
++      .id = 0,
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
++      /* Set in mali_platform_device_register() for these kernels */
++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
++      .dev.parent = &exynos4_device_pd[PD_G3D].dev,
++#else
++      .dev.parent = &s5pv310_device_pd[PD_G3D].dev,
++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) */
++      .dev.release = mali_platform_device_release,
++      /*
++       * We temporarily make use of a device type so that we can control the Mali power
++       * from within the mali.ko (since the default platform bus implementation will not do that).
++       * Ideally .dev.pm_domain should be used instead, as this is the new framework designed
++       * to control the power of devices.
++       */
++      .dev.type = &mali_gpu_device_device_type, /* We should probably use the pm_domain instead of type on newer kernels */
++};
++
++static struct mali_gpu_device_data mali_gpu_data =
++{
++      .shared_mem_size = 256 * 1024 * 1024, /* 256MB */
++      .fb_start = 0x40000000,
++      .fb_size = 0xb1000000,
++      .utilization_interval = 1000, /* 1000ms */
++      .utilization_handler = mali_gpu_utilization_handler,
++};
++
++int mali_platform_device_register(void)
++{
++      int err;
++
++      MALI_DEBUG_PRINT(4, ("mali_platform_device_register() called\n"));
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
++      exynos_pm_add_dev_to_genpd(&mali_gpu_device, &exynos4_pd_g3d);
++#endif
++
++      /* Connect resources to the device */
++      err = platform_device_add_resources(&mali_gpu_device, mali_gpu_resources, sizeof(mali_gpu_resources) / sizeof(mali_gpu_resources[0]));
++      if (0 == err)
++      {
++              err = platform_device_add_data(&mali_gpu_device, &mali_gpu_data, sizeof(mali_gpu_data));
++              if (0 == err)
++              {
++                      /* Register the platform device */
++                      err = platform_device_register(&mali_gpu_device);
++                      if (0 == err)
++                      {
++                              mali_platform_init();
++
++#ifdef CONFIG_PM_RUNTIME
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
++                              pm_runtime_set_autosuspend_delay(&(mali_gpu_device.dev), 1000);
++                              pm_runtime_use_autosuspend(&(mali_gpu_device.dev));
++#endif
++                              pm_runtime_enable(&(mali_gpu_device.dev));
++#endif
++
++                              return 0;
++                      }
++              }
++
++              platform_device_unregister(&mali_gpu_device);
++      }
++
++      return err;
++}
++
++void mali_platform_device_unregister(void)
++{
++      MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n"));
++
++      mali_platform_deinit();
++
++      platform_device_unregister(&mali_gpu_device);
++}
++
++static void mali_platform_device_release(struct device *device)
++{
++      MALI_DEBUG_PRINT(4, ("mali_platform_device_release() called\n"));
++}
++
++static int mali_os_suspend(struct device *device)
++{
++      int ret = 0;
++
++      MALI_DEBUG_PRINT(4, ("mali_os_suspend() called\n"));
++
++      if (NULL != device->driver &&
++          NULL != device->driver->pm &&
++          NULL != device->driver->pm->suspend)
++      {
++              /* Need to notify Mali driver about this event */
++              ret = device->driver->pm->suspend(device);
++      }
++
++      mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP);
++
++      return ret;
++}
++
++static int mali_os_resume(struct device *device)
++{
++      int ret = 0;
++
++      MALI_DEBUG_PRINT(4, ("mali_os_resume() called\n"));
++
++      mali_platform_power_mode_change(MALI_POWER_MODE_ON);
++
++      if (NULL != device->driver &&
++          NULL != device->driver->pm &&
++          NULL != device->driver->pm->resume)
++      {
++              /* Need to notify Mali driver about this event */
++              ret = device->driver->pm->resume(device);
++      }
++
++      return ret;
++}
++
++static int mali_os_freeze(struct device *device)
++{
++      int ret = 0;
++
++      MALI_DEBUG_PRINT(4, ("mali_os_freeze() called\n"));
++
++      if (NULL != device->driver &&
++          NULL != device->driver->pm &&
++          NULL != device->driver->pm->freeze)
++      {
++              /* Need to notify Mali driver about this event */
++              ret = device->driver->pm->freeze(device);
++      }
++
++      return ret;
++}
++
++static int mali_os_thaw(struct device *device)
++{
++      int ret = 0;
++
++      MALI_DEBUG_PRINT(4, ("mali_os_thaw() called\n"));
++
++      if (NULL != device->driver &&
++          NULL != device->driver->pm &&
++          NULL != device->driver->pm->thaw)
++      {
++              /* Need to notify Mali driver about this event */
++              ret = device->driver->pm->thaw(device);
++      }
++
++      return ret;
++}
++
++#ifdef CONFIG_PM_RUNTIME
++static int mali_runtime_suspend(struct device *device)
++{
++      int ret = 0;
++
++      MALI_DEBUG_PRINT(4, ("mali_runtime_suspend() called\n"));
++
++      if (NULL != device->driver &&
++          NULL != device->driver->pm &&
++          NULL != device->driver->pm->runtime_suspend)
++      {
++              /* Need to notify Mali driver about this event */
++              ret = device->driver->pm->runtime_suspend(device);
++      }
++
++      mali_platform_power_mode_change(MALI_POWER_MODE_LIGHT_SLEEP);
++
++      return ret;
++}
++
++static int mali_runtime_resume(struct device *device)
++{
++      int ret = 0;
++
++      MALI_DEBUG_PRINT(4, ("mali_runtime_resume() called\n"));
++
++      mali_platform_power_mode_change(MALI_POWER_MODE_ON);
++
++      if (NULL != device->driver &&
++          NULL != device->driver->pm &&
++          NULL != device->driver->pm->runtime_resume)
++      {
++              /* Need to notify Mali driver about this event */
++              ret = device->driver->pm->runtime_resume(device);
++      }
++
++      return ret;
++}
++
++static int mali_runtime_idle(struct device *device)
++{
++      MALI_DEBUG_PRINT(4, ("mali_runtime_idle() called\n"));
++
++      if (NULL != device->driver &&
++          NULL != device->driver->pm &&
++          NULL != device->driver->pm->runtime_idle)
++      {
++              /* Need to notify Mali driver about this event */
++              int ret = device->driver->pm->runtime_idle(device);
++              if (0 != ret)
++              {
++                      return ret;
++              }
++      }
++
++      pm_runtime_suspend(device);
++
++      return 0;
++}
++#endif
+diff --git a/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4_pmm.c b/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4_pmm.c
+new file mode 100644
+index 0000000..6e99950
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4_pmm.c
+@@ -0,0 +1,849 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_platform.c
++ * Platform specific Mali driver functions for a default platform
++ */
++#include "mali_kernel_common.h"
++#include "mali_osk.h"
++#include "exynos4_pmm.h"
++#include <linux/clk.h>
++#include <linux/err.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/regulator/consumer.h>
++
++#if defined(CONFIG_MALI400_PROFILING)
++#include "mali_osk_profiling.h"
++#endif
++
++#if defined(CONFIG_PM_RUNTIME)
++#include <plat/pd.h>
++#endif
++
++#include <asm/io.h>
++#include <mach/regs-pmu.h>
++
++#include <linux/workqueue.h>
++
++#define MALI_DVFS_STEPS 5
++#define MALI_DVFS_WATING 10 // msec
++#define MALI_DVFS_DEFAULT_STEP 3
++
++#define MALI_DVFS_CLK_DEBUG 0
++#define SEC_THRESHOLD 1
++#define LWJ 1
++
++#define CPUFREQ_LOCK_DURING_440 0
++
++static int bMaliDvfsRun = 0;
++
++typedef struct mali_dvfs_tableTag{
++      unsigned int clock;
++      unsigned int freq;
++      unsigned int vol;
++#if SEC_THRESHOLD
++      unsigned int downthreshold;
++    unsigned int upthreshold;
++#endif
++}mali_dvfs_table;
++
++typedef struct mali_dvfs_statusTag{
++      unsigned int currentStep;
++      mali_dvfs_table * pCurrentDvfs;
++
++} mali_dvfs_status_t;
++
++/*dvfs status*/
++mali_dvfs_status_t maliDvfsStatus;
++
++/*dvfs table*/
++
++mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={
++#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
++                      /*step 0*/{160  ,1000000    ,875000    , 0   , 70},
++                      /*step 1*/{266  ,1000000    ,900000    ,62   , 90},
++                      /*step 2*/{350  ,1000000    ,950000    ,85   , 90},
++                      /*step 3*/{440  ,1000000    ,1025000   ,85   , 90},
++                      /*step 4*/{533  ,1000000    ,1075000   ,85   ,100} };
++#else
++                      /*step 0*/{134  ,1000000    , 950000   ,85   , 90},
++                      /*step 1*/{267  ,1000000    ,1050000   ,85   ,100} };
++#endif
++
++
++#define EXTXTALCLK_NAME  "ext_xtal"
++#define VPLLSRCCLK_NAME  "vpll_src"
++#define FOUTVPLLCLK_NAME "fout_vpll"
++#define SCLVPLLCLK_NAME  "sclk_vpll"
++#define GPUMOUT1CLK_NAME "mout_g3d1"
++
++#define MPLLCLK_NAME     "mout_mpll"
++#define GPUMOUT0CLK_NAME "mout_g3d0"
++#define GPUCLK_NAME      "sclk_g3d"
++#define CLK_DIV_STAT_G3D 0x1003C62C
++#define CLK_DESC         "clk-divider-status"
++
++static struct clk *ext_xtal_clock = NULL;
++static struct clk *vpll_src_clock = NULL;
++static struct clk *fout_vpll_clock = NULL;
++static struct clk *sclk_vpll_clock = NULL;
++
++static struct clk *mpll_clock = NULL;
++static struct clk *mali_parent_clock = NULL;
++static struct clk *mali_clock = NULL;
++
++#if defined(CONFIG_CPU_EXYNOS4412) || defined(CONFIG_CPU_EXYNOS4212)
++/* Pegasus */
++static const mali_bool bis_vpll  = MALI_TRUE;
++unsigned int mali_gpu_clk = 440;
++unsigned int mali_gpu_vol = 1025000;
++#else
++/* Orion */
++static const mali_bool bis_vpll  = MALI_FALSE;
++int mali_gpu_clk                 = 267;
++static unsigned int mali_gpu_vol = 1050000; /* 1.05V */
++#endif
++
++static unsigned int GPU_MHZ   =               1000000;
++
++int  gpu_power_state;
++static int bPoweroff;
++
++#ifdef CONFIG_REGULATOR
++struct regulator *g3d_regulator = NULL;
++#endif
++
++mali_io_address clk_register_map = 0;
++
++/* DVFS */
++static unsigned int mali_dvfs_utilization = 255;
++
++static void mali_dvfs_work_handler(struct work_struct *w);
++
++static struct workqueue_struct *mali_dvfs_wq = 0;
++
++extern mali_io_address clk_register_map;
++
++_mali_osk_lock_t *mali_dvfs_lock = 0; 
++
++static DECLARE_WORK(mali_dvfs_work, mali_dvfs_work_handler);
++
++
++/* export GPU frequency as a read-only parameter so that it can be read in /sys */
++module_param(mali_gpu_clk, int, S_IRUSR | S_IRGRP | S_IROTH);
++MODULE_PARM_DESC(mali_gpu_clk, "GPU frequency in MHz");
++
++#ifdef CONFIG_REGULATOR
++void mali_regulator_disable(void)
++{
++      if(IS_ERR_OR_NULL(g3d_regulator))
++      {
++              MALI_DEBUG_PRINT(1, ("error on mali_regulator_disable : g3d_regulator is null\n"));
++              return;
++      }
++      regulator_disable(g3d_regulator);
++}
++
++void mali_regulator_enable(void)
++{
++      if(IS_ERR_OR_NULL(g3d_regulator))
++      {
++              MALI_DEBUG_PRINT(1, ("error on mali_regulator_enable : g3d_regulator is null\n"));
++              return;
++      }
++      regulator_enable(g3d_regulator);
++}
++
++void mali_regulator_set_voltage(int min_uV, int max_uV)
++{
++      _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
++      if(IS_ERR_OR_NULL(g3d_regulator))
++      {
++              MALI_DEBUG_PRINT(1, ("error on mali_regulator_set_voltage : g3d_regulator is null\n"));
++              return;
++      }
++      MALI_PRINT(("= regulator_set_voltage: %d, %d \n",min_uV, max_uV));
++      regulator_set_voltage(g3d_regulator, min_uV, max_uV);
++      mali_gpu_vol = regulator_get_voltage(g3d_regulator);
++      MALI_DEBUG_PRINT(1, ("Mali voltage: %d\n", mali_gpu_vol));
++      _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
++}
++#endif
++
++unsigned long mali_clk_get_rate(void)
++{
++//    return clk_get_rate(mali_clock);
++#if LWJ
++      return maliDvfsStatus.currentStep;
++#endif
++}
++
++
++static unsigned int get_mali_dvfs_status(void)
++{
++      return maliDvfsStatus.currentStep;
++}
++
++mali_bool mali_clk_get(void)
++{
++      if (bis_vpll)
++      {
++              if (ext_xtal_clock == NULL)
++              {
++                      ext_xtal_clock = clk_get(NULL,EXTXTALCLK_NAME);
++                      if (IS_ERR(ext_xtal_clock)) {
++                              MALI_PRINT( ("MALI Error : failed to get source ext_xtal_clock\n"));
++                              return MALI_FALSE;
++                      }
++              }
++
++              if (vpll_src_clock == NULL)
++              {
++                      vpll_src_clock = clk_get(NULL,VPLLSRCCLK_NAME);
++                      if (IS_ERR(vpll_src_clock)) {
++                              MALI_PRINT( ("MALI Error : failed to get source vpll_src_clock\n"));
++                              return MALI_FALSE;
++                      }
++              }
++
++              if (fout_vpll_clock == NULL)
++              {
++                      fout_vpll_clock = clk_get(NULL,FOUTVPLLCLK_NAME);
++                      if (IS_ERR(fout_vpll_clock)) {
++                              MALI_PRINT( ("MALI Error : failed to get source fout_vpll_clock\n"));
++                              return MALI_FALSE;
++                      }
++              }
++
++              if (sclk_vpll_clock == NULL)
++              {
++                      sclk_vpll_clock = clk_get(NULL,SCLVPLLCLK_NAME);
++                      if (IS_ERR(sclk_vpll_clock)) {
++                              MALI_PRINT( ("MALI Error : failed to get source sclk_vpll_clock\n"));
++                              return MALI_FALSE;
++                      }
++              }
++
++              if (mali_parent_clock == NULL)
++              {
++                      mali_parent_clock = clk_get(NULL, GPUMOUT1CLK_NAME);
++
++                      if (IS_ERR(mali_parent_clock)) {
++                              MALI_PRINT( ( "MALI Error : failed to get source mali parent clock\n"));
++                              return MALI_FALSE;
++                      }
++              }
++      }
++      else // mpll
++      {
++              if (mpll_clock == NULL)
++              {
++                      mpll_clock = clk_get(NULL,MPLLCLK_NAME);
++
++                      if (IS_ERR(mpll_clock)) {
++                              MALI_PRINT( ("MALI Error : failed to get source mpll clock\n"));
++                              return MALI_FALSE;
++                      }
++              }
++
++              if (mali_parent_clock == NULL)
++              {
++                      mali_parent_clock = clk_get(NULL, GPUMOUT0CLK_NAME);
++
++                      if (IS_ERR(mali_parent_clock)) {
++                              MALI_PRINT( ( "MALI Error : failed to get source mali parent clock\n"));
++                              return MALI_FALSE;
++                      }
++              }
++      }
++
++      // mali clock get always.
++      if (mali_clock == NULL)
++      {
++              mali_clock = clk_get(NULL, GPUCLK_NAME);
++
++              if (IS_ERR(mali_clock)) {
++                      MALI_PRINT( ("MALI Error : failed to get source mali clock\n"));
++                      return MALI_FALSE;
++              }
++      }
++
++      return MALI_TRUE;
++}
++
++void mali_clk_put(mali_bool binc_mali_clock)
++{
++      if (mali_parent_clock)
++      {
++              clk_put(mali_parent_clock);
++              mali_parent_clock = NULL;
++      }
++
++      if (mpll_clock)
++      {
++              clk_put(mpll_clock);
++              mpll_clock = NULL;
++      }
++
++      if (sclk_vpll_clock)
++      {
++              clk_put(sclk_vpll_clock);
++              sclk_vpll_clock = NULL;
++      }
++
++      if (binc_mali_clock && fout_vpll_clock)
++      {
++              clk_put(fout_vpll_clock);
++              fout_vpll_clock = NULL;
++      }
++
++      if (vpll_src_clock)
++      {
++              clk_put(vpll_src_clock);
++              vpll_src_clock = NULL;
++      }
++
++      if (ext_xtal_clock)
++      {
++              clk_put(ext_xtal_clock);
++              ext_xtal_clock = NULL;
++      }
++
++      if (binc_mali_clock && mali_clock)
++      {
++              clk_put(mali_clock);
++              mali_clock = NULL;
++      }
++}
++
++void mali_clk_set_rate(unsigned int clk, unsigned int mhz)
++{
++      int err;
++      unsigned long rate = (unsigned long)clk * (unsigned long)mhz;
++
++      _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
++      MALI_DEBUG_PRINT(3, ("Mali platform: Setting frequency to %d mhz\n", clk));
++      if (bis_vpll && fout_vpll_clock)
++      {
++              err = clk_set_rate(fout_vpll_clock, (unsigned int)mali_gpu_clk * GPU_MHZ);
++              if (err) MALI_PRINT_ERROR(("Failed to set vpll: %d\n", err));
++      }
++      err = clk_set_rate(mali_clock, rate);
++      if (err) MALI_PRINT_ERROR(("Failed to set Mali clock: %d\n", err));
++
++      rate = mali_clk_get_rate();
++
++      MALI_PRINT(("Mali frequency %d\n", rate / mhz));
++      GPU_MHZ = mhz;
++      _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
++}
++
++mali_bool set_mali_dvfs_current_step(unsigned int step)
++{
++      _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
++      maliDvfsStatus.currentStep = step % MALI_DVFS_STEPS;
++//    if (step >= MAX_MALI_DVFS_STEPS) //LWJ
++//            mali_runtime_resumed = maliDvfsStatus.currentStep;
++      _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
++      return MALI_TRUE;
++}
++
++
++static mali_bool set_mali_dvfs_status(u32 step,mali_bool boostup)
++{
++      u32 validatedStep=step;
++#if MALI_DVFS_CLK_DEBUG
++      unsigned int *pRegMaliClkDiv;
++      unsigned int *pRegMaliMpll;
++#endif
++
++      if(boostup)
++      {
++#ifdef CONFIG_REGULATOR
++              /*change the voltage*/
++              mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol);
++#endif
++              /*change the clock*/
++              mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq);
++      }
++      else
++      {
++              /*change the clock*/
++              mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq);
++#ifdef CONFIG_REGULATOR
++              /*change the voltage*/
++              mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol);
++#endif
++      }
++
++#if defined(CONFIG_MALI400_PROFILING)
++      _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE| MALI_PROFILING_EVENT_CHANNEL_GPU|MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0);
++#endif
++      mali_clk_put(MALI_FALSE);
++
++#if MALI_DVFS_CLK_DEBUG
++      pRegMaliClkDiv = ioremap(0x1003c52c,32);
++      pRegMaliMpll = ioremap(0x1003c22c,32);
++      MALI_PRINT( ("Mali MPLL reg:%d, CLK DIV: %d \n",*pRegMaliMpll, *pRegMaliClkDiv));
++#endif
++
++#ifdef EXYNOS4_ASV_ENABLED
++      if (samsung_rev() < EXYNOS4412_REV_2_0) {
++              if (mali_dvfs[step].clock == 160)
++                      exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_100V);
++              else
++                      exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_130V);
++      }
++#endif
++
++
++//    maliDvfsStatus.currentStep = validatedStep;
++      set_mali_dvfs_current_step(validatedStep);
++      /*for future use*/
++      maliDvfsStatus.pCurrentDvfs = &mali_dvfs[validatedStep];
++
++#if CPUFREQ_LOCK_DURING_440
++      /* lock/unlock CPU freq by Mali */
++      if (mali_dvfs[step].clock == 440)
++              err = cpufreq_lock_by_mali(1200);
++      else
++              cpufreq_unlock_by_mali();
++#endif
++
++
++      return MALI_TRUE;
++}
++
++static void mali_platform_wating(u32 msec)
++{
++      /*sample wating
++      change this in the future with proper check routine.
++      */
++      unsigned int read_val;
++      while(1)
++      {
++              read_val = _mali_osk_mem_ioread32(clk_register_map, 0x00);
++              if ((read_val & 0x8000)==0x0000) break;
++
++              _mali_osk_time_ubusydelay(100); /* 1000 -> 100 : 20101218 */
++      }
++      /* _mali_osk_time_ubusydelay(msec*1000);*/
++}
++
++static mali_bool change_mali_dvfs_status(u32 step, mali_bool boostup )
++{
++      MALI_DEBUG_PRINT(4, ("> change_mali_dvfs_status: %d, %d \n",step, boostup));
++
++      if(!set_mali_dvfs_status(step, boostup))
++      {
++              MALI_DEBUG_PRINT(1, ("error on set_mali_dvfs_status: %d, %d \n",step, boostup));
++              return MALI_FALSE;
++      }
++
++      /*wait until clock and voltage is stablized*/
++      mali_platform_wating(MALI_DVFS_WATING); /*msec*/
++
++      return MALI_TRUE;
++}
++
++static unsigned int decideNextStatus(unsigned int utilization)
++{
++      unsigned int level=0; /* 0:stay, 1:up */
++#if 0
++      if( utilization>127 && maliDvfsStatus.currentStep==0 ) /* over 60% -> 50% (up fast) */
++              level=1;
++      else if( utilization<51 && maliDvfsStatus.currentStep==1 ) /* under 30% -> 20% (down slow) */
++              level=0;
++      else
++              level = maliDvfsStatus.currentStep;
++#else
++
++      level = maliDvfsStatus.currentStep;
++//    if (maliDvfsStatus.currentStep) {
++              if (utilization > (int)(255 * mali_dvfs[maliDvfsStatus.currentStep].upthreshold / 100) &&
++                              level < MALI_DVFS_STEPS - 1) {
++                      level++;
++//                    if ((samsung_rev() < EXYNOS4412_REV_2_0) && (maliDvfsStatus.currentStep == 3)) {
++//                            level=get_mali_dvfs_status();
++//                    }
++              }
++              if (utilization < (int)(255 * mali_dvfs[maliDvfsStatus.currentStep].downthreshold / 100) &&
++                              level > 0) {
++                      level--;
++              }
++//    } 
++#endif
++      printk("LWJ %s Level %d\n", __func__, level);
++      return level;
++}
++
++static mali_bool mali_dvfs_status(unsigned int utilization)
++{
++      unsigned int nextStatus=0;
++      unsigned int curStatus=0;
++      mali_bool boostup=0;
++
++      MALI_DEBUG_PRINT(4, ("> mali_dvfs_status: %d \n",utilization));
++
++      /*decide next step*/
++      curStatus = get_mali_dvfs_status();
++      printk("LWJ curStatus %d\n",curStatus);
++      nextStatus = decideNextStatus(utilization);
++
++      MALI_DEBUG_PRINT(4, ("= curStatus %d, nextStatus %d, maliDvfsStatus.currentStep %d \n", curStatus, nextStatus, maliDvfsStatus.currentStep));
++      /*if next status is same with current status, don't change anything*/
++      if(curStatus!=nextStatus)
++      {
++              /*check if boost up or not*/
++              if(nextStatus > maliDvfsStatus.currentStep) boostup = 1;
++
++              /*change mali dvfs status*/
++              if(!change_mali_dvfs_status(nextStatus,boostup))
++              {
++                      MALI_DEBUG_PRINT(1, ("error on change_mali_dvfs_status \n"));
++                      return MALI_FALSE;
++              }
++      }
++      return MALI_TRUE;
++}
++
++
++int mali_dvfs_is_running(void)
++{
++      return bMaliDvfsRun;
++}
++
++
++static void mali_dvfs_work_handler(struct work_struct *w)
++{
++      bMaliDvfsRun=1;
++
++      MALI_DEBUG_PRINT(3, ("=== mali_dvfs_work_handler\n"));
++
++      if(!mali_dvfs_status(mali_dvfs_utilization))
++      MALI_DEBUG_PRINT(1,( "error on mali dvfs status in mali_dvfs_work_handler"));
++
++      bMaliDvfsRun=0;
++}
++
++
++mali_bool init_mali_dvfs_status(void)
++{
++      /*default status
++      add here with the right function to get initilization value.
++      */
++
++      if (!mali_dvfs_wq)
++      {
++              mali_dvfs_wq = create_singlethread_workqueue("mali_dvfs");
++      }
++
++      /*add a error handling here*/
++      maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP;
++
++      return MALI_TRUE;
++}
++
++void deinit_mali_dvfs_status(void)
++{
++      if (mali_dvfs_wq)
++      {
++              destroy_workqueue(mali_dvfs_wq);
++              mali_dvfs_wq = NULL;
++      }
++}
++
++mali_bool mali_dvfs_handler(unsigned int utilization)
++{
++      mali_dvfs_utilization = utilization;
++      queue_work(mali_dvfs_wq,&mali_dvfs_work);
++
++      /*add error handle here*/
++
++      return MALI_TRUE;
++}
++
++static mali_bool init_mali_clock(void)
++{
++      mali_bool ret = MALI_TRUE;
++      gpu_power_state = 0;
++      bPoweroff = 1;
++
++      if (mali_clock != 0)
++              return ret; /* already initialized */
++
++      mali_dvfs_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE
++                      | _MALI_OSK_LOCKFLAG_ONELOCK, 0, 0);
++      if (mali_dvfs_lock == NULL)
++              return _MALI_OSK_ERR_FAULT;
++
++
++
++      if (!mali_clk_get())
++      {
++              MALI_PRINT(("Error: Failed to get Mali clock\n"));
++              goto err_clk;
++      }
++
++      if (bis_vpll)
++      {
++              clk_set_parent(vpll_src_clock, ext_xtal_clock);
++              clk_set_parent(sclk_vpll_clock, fout_vpll_clock);
++
++              clk_set_parent(mali_parent_clock, sclk_vpll_clock);
++              clk_set_parent(mali_clock, mali_parent_clock);
++      }
++      else
++      {
++              clk_set_parent(mali_parent_clock, mpll_clock);
++              clk_set_parent(mali_clock, mali_parent_clock);
++      }
++
++      if (clk_enable(mali_clock) < 0)
++      {
++              MALI_PRINT(("Error: Failed to enable clock\n"));
++              goto err_clk;
++      }
++
++      mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ);
++
++      MALI_PRINT(("init_mali_clock mali_clock %x\n", mali_clock));
++
++#ifdef CONFIG_REGULATOR
++      g3d_regulator = regulator_get(NULL, "vdd_g3d");
++
++      if (IS_ERR(g3d_regulator))
++      {
++              MALI_PRINT( ("MALI Error : failed to get vdd_g3d\n"));
++              ret = MALI_FALSE;
++              goto err_regulator;
++      }
++
++      regulator_enable(g3d_regulator);
++      mali_regulator_set_voltage(mali_gpu_vol, mali_gpu_vol);
++#endif
++
++#if defined(CONFIG_MALI400_PROFILING)
++      _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|
++                      MALI_PROFILING_EVENT_CHANNEL_GPU|MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
++                      mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0);
++#endif
++
++      mali_clk_put(MALI_FALSE);
++
++      return MALI_TRUE;
++
++#ifdef CONFIG_REGULATOR
++err_regulator:
++      regulator_put(g3d_regulator);
++#endif
++err_clk:
++      mali_clk_put(MALI_TRUE);
++
++      return ret;
++}
++
++static mali_bool deinit_mali_clock(void)
++{
++      if (mali_clock == 0)
++              return MALI_TRUE;
++
++#ifdef CONFIG_REGULATOR
++      if (g3d_regulator)
++      {
++              regulator_put(g3d_regulator);
++              g3d_regulator = NULL;
++      }
++#endif
++
++      mali_clk_put(MALI_TRUE);
++
++      return MALI_TRUE;
++}
++
++
++static _mali_osk_errcode_t enable_mali_clocks(void)
++{
++      int err;
++      err = clk_enable(mali_clock);
++      MALI_DEBUG_PRINT(3,("enable_mali_clocks mali_clock %p error %d \n", mali_clock, err));
++
++      /* set clock rate */
++      mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ);
++
++      maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP;
++
++      MALI_SUCCESS;
++}
++
++static _mali_osk_errcode_t disable_mali_clocks(void)
++{
++      clk_disable(mali_clock);
++      MALI_DEBUG_PRINT(3,("disable_mali_clocks mali_clock %p \n", mali_clock));
++
++      MALI_SUCCESS;
++}
++
++/* Some defines changed names in later Odroid-A kernels. Make sure it works for both. */
++#ifndef S5P_G3D_CONFIGURATION
++#define S5P_G3D_CONFIGURATION S5P_PMU_G3D_CONF
++#endif
++#ifndef S5P_G3D_STATUS
++#define S5P_G3D_STATUS S5P_PMU_G3D_CONF + 0x4
++#endif
++
++_mali_osk_errcode_t g3d_power_domain_control(int bpower_on)
++{
++      if (bpower_on)
++      {
++              void __iomem *status;
++              u32 timeout;
++              __raw_writel(EXYNOS_INT_LOCAL_PWR_EN, S5P_G3D_CONFIGURATION);
++              status = S5P_G3D_STATUS;
++
++              timeout = 10;
++              while ((__raw_readl(status) & EXYNOS_INT_LOCAL_PWR_EN)
++                      != EXYNOS_INT_LOCAL_PWR_EN) {
++                      if (timeout == 0) {
++                              MALI_PRINTF(("Power domain  enable failed.\n"));
++                              return -ETIMEDOUT;
++                      }
++                      timeout--;
++                      _mali_osk_time_ubusydelay(100);
++              }
++      }
++      else
++      {
++              void __iomem *status;
++              u32 timeout;
++              __raw_writel(0, S5P_G3D_CONFIGURATION);
++
++              status = S5P_G3D_STATUS;
++              /* Wait max 1ms */
++              timeout = 10;
++              while (__raw_readl(status) & EXYNOS_INT_LOCAL_PWR_EN)
++              {
++                      if (timeout == 0) {
++                              MALI_PRINTF(("Power domain  disable failed.\n" ));
++                              return -ETIMEDOUT;
++                      }
++                      timeout--;
++                      _mali_osk_time_ubusydelay( 100);
++              }
++      }
++
++      MALI_SUCCESS;
++}
++
++_mali_osk_errcode_t mali_platform_init(void)
++{
++      MALI_CHECK(init_mali_clock(), _MALI_OSK_ERR_FAULT);
++#ifdef CONFIG_MALI_DVFS
++      if (!clk_register_map) clk_register_map = _mali_osk_mem_mapioregion( CLK_DIV_STAT_G3D, 0x20, CLK_DESC );
++      if(!init_mali_dvfs_status())
++              MALI_DEBUG_PRINT(1, ("mali_platform_init failed\n"));
++#endif
++      mali_platform_power_mode_change(MALI_POWER_MODE_ON);
++
++      MALI_SUCCESS;
++}
++
++_mali_osk_errcode_t mali_platform_deinit(void)
++{
++
++      mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP);
++      deinit_mali_clock();
++
++#ifdef CONFIG_MALI_DVFS
++      deinit_mali_dvfs_status();
++      if (clk_register_map )
++      {
++              _mali_osk_mem_unmapioregion(CLK_DIV_STAT_G3D, 0x20, clk_register_map);
++              clk_register_map = NULL;
++      }
++#endif
++
++      MALI_SUCCESS;
++}
++
++_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode)
++{
++      switch (power_mode)
++      {
++              case MALI_POWER_MODE_ON:
++                      MALI_DEBUG_PRINT(3, ("Mali platform: Got MALI_POWER_MODE_ON event, %s\n",
++                                           bPoweroff ? "powering on" : "already on"));
++                      if (bPoweroff == 1)
++                      {
++#if !defined(CONFIG_PM_RUNTIME)
++                              g3d_power_domain_control(1);
++#endif
++                              MALI_DEBUG_PRINT(4,("enable clock \n"));
++                              enable_mali_clocks();
++#if defined(CONFIG_MALI400_PROFILING)
++                              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
++                                              MALI_PROFILING_EVENT_CHANNEL_GPU |
++                                              MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, mali_gpu_clk,
++                                              mali_gpu_vol/1000, 0, 0, 0);
++
++#endif
++                              bPoweroff=0;
++                      }
++                      break;
++              case MALI_POWER_MODE_LIGHT_SLEEP:
++              case MALI_POWER_MODE_DEEP_SLEEP:
++                      MALI_DEBUG_PRINT(3, ("Mali platform: Got %s event, %s\n", power_mode ==
++                                              MALI_POWER_MODE_LIGHT_SLEEP ?  "MALI_POWER_MODE_LIGHT_SLEEP" :
++                                              "MALI_POWER_MODE_DEEP_SLEEP", bPoweroff ? "already off" : "powering off"));
++                      if (bPoweroff == 0)
++                      {
++                              disable_mali_clocks();
++#if defined(CONFIG_MALI400_PROFILING)
++                              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
++                                              MALI_PROFILING_EVENT_CHANNEL_GPU |
++                                              MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, 0, 0, 0, 0, 0);
++#endif
++
++#if !defined(CONFIG_PM_RUNTIME)
++                              g3d_power_domain_control(0);
++#endif
++                              bPoweroff=1;
++                      }
++
++                      break;
++      }
++      MALI_SUCCESS;
++}
++
++void mali_gpu_utilization_handler(unsigned int utilization)
++{
++      printk("LWJ utilization %d\n",utilization);
++      if (bPoweroff==0)
++      {
++#ifdef CONFIG_MALI_DVFS
++              if(!mali_dvfs_handler(utilization))
++                      MALI_DEBUG_PRINT(1,( "error on mali dvfs status in utilization\n"));
++#endif
++      }
++}
++
++
++/*REGISTER
++ Enable Power
++ pPowerPTR = ioremap(0x10023C60,32);
++ *pPowerPTR |= 0x7;
++
++ Enable Clock
++ pPTR = ioremap(0x1003C92C,32);
++ *pPTR |= 0x1;
++*/
++
+diff --git a/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4_pmm.h b/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4_pmm.h
+new file mode 100644
+index 0000000..46a269e
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4_pmm.h
+@@ -0,0 +1,86 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_platform.h
++ * Platform specific Mali driver functions
++ */
++
++#ifndef __EXYNOS4_PMM_H__
++#define __EXYNOS4_PMM_H__
++
++#include "mali_osk.h"
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++/** @brief description of power change reasons
++ */
++typedef enum mali_power_mode_tag
++{
++      MALI_POWER_MODE_ON,
++      MALI_POWER_MODE_LIGHT_SLEEP,
++      MALI_POWER_MODE_DEEP_SLEEP,
++} mali_power_mode;
++
++/** @brief Platform specific setup and initialisation of MALI
++ *
++ * This is called from the entrypoint of the driver to initialize the platform
++ *
++ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
++ */
++_mali_osk_errcode_t mali_platform_init(void);
++
++/** @brief Platform specific deinitialisation of MALI
++ *
++ * This is called on the exit of the driver to terminate the platform
++ *
++ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
++ */
++_mali_osk_errcode_t mali_platform_deinit(void);
++
++/** @brief Platform specific powerdown sequence of MALI
++ *
++ * Call as part of platform init if there is no PMM support, else the
++ * PMM will call it. 
++ * There are three power modes defined:
++ *  1) MALI_POWER_MODE_ON
++ *  2) MALI_POWER_MODE_LIGHT_SLEEP
++ *  3) MALI_POWER_MODE_DEEP_SLEEP
++ * MALI power management module transitions to MALI_POWER_MODE_LIGHT_SLEEP mode when MALI is idle
++ * for idle timer (software timer defined in mali_pmm_policy_jobcontrol.h) duration, MALI transitions
++ * to MALI_POWER_MODE_LIGHT_SLEEP mode during timeout if there are no more jobs queued.
++ * MALI power management module transitions to MALI_POWER_MODE_DEEP_SLEEP mode when OS does system power
++ * off. 
++ * Customer has to add power down code when MALI transitions to MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP
++ * mode.
++ * MALI_POWER_MODE_ON mode is entered when the MALI is to powered up. Some customers want to control voltage regulators during
++ * the whole system powers on/off. Customer can track in this function whether the MALI is powered up from
++ * MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP mode and manage the voltage regulators as well.
++ * @param power_mode defines the power modes
++ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
++ */
++_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode);
++
++
++/** @brief Platform specific handling of GPU utilization data
++ *
++ * When GPU utilization data is enabled, this function will be
++ * periodically called.
++ *
++ * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization.
++ */
++void mali_gpu_utilization_handler(unsigned int utilization);
++
++#ifdef __cplusplus
++}
++#endif
++#endif
+diff --git a/drivers/gpu/arm/mali400/mali/platform/mali_platform.h b/drivers/gpu/arm/mali400/mali/platform/mali_platform.h
+new file mode 100644
+index 0000000..9ce814f
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/platform/mali_platform.h
+@@ -0,0 +1,153 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_platform.h
++ * Platform specific Mali driver functions
++ */
++
++#ifndef __MALI_PLATFORM_H__
++#define __MALI_PLATFORM_H__
++
++#include "mali_osk.h"
++
++#ifdef CONFIG_CPU_EXYNOS4210
++#define MALI_DVFS_STEPS 2
++#else
++#define MALI_DVFS_STEPS 5
++#endif
++
++/* @Enable or Disable Mali GPU Bottom Lock feature */
++#define MALI_GPU_BOTTOM_LOCK 1
++
++#define MALI_VOLTAGE_LOCK 1
++
++/* @Enable or Disable the CPU frequency lock when the GPU clock is 440 Mhz */
++#define CPUFREQ_LOCK_DURING_440 0
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++/** @brief description of power change reasons
++ */
++typedef enum mali_power_mode_tag
++{
++      MALI_POWER_MODE_ON,           /**< Power Mali on */
++      MALI_POWER_MODE_LIGHT_SLEEP,  /**< Mali has been idle for a short time, or runtime PM suspend */
++      MALI_POWER_MODE_DEEP_SLEEP,   /**< Mali has been idle for a long time, or OS suspend */
++} mali_power_mode;
++
++/** @brief Platform specific setup and initialisation of MALI
++ *
++ * This is called from the entrypoint of the driver to initialize the platform
++ *
++ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
++ */
++_mali_osk_errcode_t mali_platform_init(void);
++
++/** @brief Platform specific deinitialisation of MALI
++ *
++ * This is called on the exit of the driver to terminate the platform
++ *
++ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
++ */
++_mali_osk_errcode_t mali_platform_deinit(void);
++
++/** @brief Platform specific powerdown sequence of MALI
++ *
++ * Notification from the Mali device driver stating the new desired power mode.
++ * MALI_POWER_MODE_ON must be obeyed, while the other modes are optional.
++ * @param power_mode defines the power modes
++ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
++ */
++_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode);
++
++
++/** @brief Platform specific handling of GPU utilization data
++ *
++ * When GPU utilization data is enabled, this function will be
++ * periodically called.
++ *
++ * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization.
++ */
++void mali_gpu_utilization_handler(u32 utilization);
++
++/** @brief Setting the power domain of MALI
++ *
++ * This function sets the power domain of MALI if Linux run time power management is enabled
++ *
++ * @param dev Reference to struct platform_device (defined in linux) used by MALI GPU
++ */
++//void set_mali_parent_power_domain(void* dev);
++void mali_utilization_suspend(void);
++
++#ifdef CONFIG_REGULATOR
++int mali_regulator_get_usecount(void);
++void mali_regulator_disable(void);
++void mali_regulator_enable(void);
++void mali_regulator_set_voltage(int min_uV, int max_uV);
++#endif
++mali_bool mali_clk_set_rate(unsigned int clk, unsigned int mhz);
++unsigned long mali_clk_get_rate(void);
++void mali_clk_put(mali_bool binc_mali_clk);
++
++#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
++_mali_osk_errcode_t mali_platform_powerdown(u32 cores);
++_mali_osk_errcode_t mali_platform_powerup(u32 cores);
++#endif
++
++
++#if USING_MALI_PMM
++#if MALI_POWER_MGMT_TEST_SUITE
++/** @brief function to get status of individual cores
++ *
++ * This function is used by power management test suite to get the status of powered up/down the number
++ * of cores
++ * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization.
++ */
++u32 pmu_get_power_up_down_info(void);
++#endif
++#endif
++
++#if MALI_DVFS_ENABLED
++mali_bool init_mali_dvfs_status(int step);
++void deinit_mali_dvfs_status(void);
++mali_bool mali_dvfs_handler(u32 utilization);
++int mali_dvfs_is_running(void);
++void mali_dvfs_late_resume(void);
++int get_mali_dvfs_control_status(void);
++mali_bool set_mali_dvfs_current_step(unsigned int step);
++void mali_default_step_set(int step, mali_bool boostup);
++int change_dvfs_tableset(int change_clk, int change_step);
++#ifdef CONFIG_CPU_EXYNOS4210
++#if MALI_GPU_BOTTOM_LOCK
++int mali_dvfs_bottom_lock_push(void);
++int mali_dvfs_bottom_lock_pop(void);
++#endif
++#else
++int mali_dvfs_bottom_lock_push(int lock_step);
++int mali_dvfs_bottom_lock_pop(void);
++#endif
++#endif
++
++int mali_dvfs_get_vol(int step);
++
++#if MALI_VOLTAGE_LOCK
++int mali_voltage_lock_push(int lock_vol);
++int mali_voltage_lock_pop(void);
++int mali_voltage_lock_init(void);
++int mali_vol_get_from_table(int vol);
++#endif
++
++#ifdef __cplusplus
++}
++#endif
++#endif
+diff --git a/drivers/gpu/arm/mali400/mali/platform/pegasus-m400/exynos4.c b/drivers/gpu/arm/mali400/mali/platform/pegasus-m400/exynos4.c
+new file mode 100644
+index 0000000..493bd7b
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/platform/pegasus-m400/exynos4.c
+@@ -0,0 +1,273 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_platform.c
++ * Platform specific Mali driver functions for the exynos 4XXX based platforms
++ */
++#include <linux/platform_device.h>
++#include <linux/version.h>
++#include <linux/pm.h>
++#ifdef CONFIG_PM_RUNTIME
++#include <linux/pm_runtime.h>
++#endif
++#include <linux/mali/mali_utgard.h>
++#include "mali_kernel_common.h"
++
++#include <linux/irq.h>
++#include <plat/devs.h>
++
++#include "exynos4_pmm.h"
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
++struct exynos_pm_domain;
++//extern struct exynos_pm_domain exynos4_pd_g3d;
++void exynos_pm_add_dev_to_genpd(struct platform_device *pdev, struct exynos_pm_domain *pd);
++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
++extern struct platform_device exynos4_device_pd[];
++#else
++extern struct platform_device s5pv310_device_pd[];
++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) */
++
++static void mali_platform_device_release(struct device *device);
++static int mali_os_suspend(struct device *device);
++static int mali_os_resume(struct device *device);
++static int mali_os_freeze(struct device *device);
++static int mali_os_thaw(struct device *device);
++#ifdef CONFIG_PM_RUNTIME
++static int mali_runtime_suspend(struct device *device);
++static int mali_runtime_resume(struct device *device);
++static int mali_runtime_idle(struct device *device);
++#endif
++
++#define MALI_GP_IRQ       EXYNOS4_IRQ_GP_3D
++#define MALI_PP0_IRQ      EXYNOS4_IRQ_PP0_3D
++#define MALI_PP1_IRQ      EXYNOS4_IRQ_PP1_3D
++#define MALI_PP2_IRQ      EXYNOS4_IRQ_PP2_3D
++#define MALI_PP3_IRQ      EXYNOS4_IRQ_PP3_3D
++#define MALI_GP_MMU_IRQ   EXYNOS4_IRQ_GPMMU_3D
++#define MALI_PP0_MMU_IRQ  EXYNOS4_IRQ_PPMMU0_3D
++#define MALI_PP1_MMU_IRQ  EXYNOS4_IRQ_PPMMU1_3D
++#define MALI_PP2_MMU_IRQ  EXYNOS4_IRQ_PPMMU2_3D
++#define MALI_PP3_MMU_IRQ  EXYNOS4_IRQ_PPMMU3_3D
++
++static struct resource mali_gpu_resources[] =
++{
++      MALI_GPU_RESOURCES_MALI400_MP4(0x13000000,
++                                     MALI_GP_IRQ, MALI_GP_MMU_IRQ,
++                                     MALI_PP0_IRQ, MALI_PP0_MMU_IRQ,
++                                     MALI_PP1_IRQ, MALI_PP1_MMU_IRQ,
++                                     MALI_PP2_IRQ, MALI_PP2_MMU_IRQ,
++                                     MALI_PP3_IRQ, MALI_PP3_MMU_IRQ)
++};
++
++static struct dev_pm_ops mali_gpu_device_type_pm_ops =
++{
++      .suspend = mali_os_suspend,
++      .resume = mali_os_resume,
++      .freeze = mali_os_freeze,
++      .thaw = mali_os_thaw,
++#ifdef CONFIG_PM_RUNTIME
++      .runtime_suspend = mali_runtime_suspend,
++      .runtime_resume = mali_runtime_resume,
++      .runtime_idle = mali_runtime_idle,
++#endif
++};
++
++static struct device_type mali_gpu_device_device_type =
++{
++      .pm = &mali_gpu_device_type_pm_ops,
++};
++
++
++static struct platform_device *mali_gpu_device;
++
++static struct mali_gpu_device_data mali_gpu_data =
++{
++      .shared_mem_size = 256 * 1024 * 1024, /* 256MB */
++      .fb_start = 0x40000000,
++      .fb_size = 0xb1000000,
++      .utilization_interval = 1000, /* 1000ms */
++      .utilization_handler = mali_gpu_utilization_handler,
++};
++
++int mali_platform_device_register(void)
++{
++      int err;
++
++      MALI_DEBUG_PRINT(4, ("mali_platform_device_register() called\n"));
++
++      /* Connect resources to the device */
++      err = platform_device_add_resources(&exynos4_device_g3d, mali_gpu_resources, sizeof(mali_gpu_resources) / sizeof(mali_gpu_resources[0]));
++      if (0 == err)
++      {
++              err = platform_device_add_data(&exynos4_device_g3d, &mali_gpu_data, sizeof(mali_gpu_data));
++              if (0 == err)
++              {
++                      mali_platform_init();
++
++#ifdef CONFIG_PM_RUNTIME
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
++                      pm_runtime_set_autosuspend_delay(&(exynos4_device_g3d.dev), 1000);
++                      pm_runtime_use_autosuspend(&(exynos4_device_g3d.dev));
++#endif
++                      pm_runtime_enable(&(exynos4_device_g3d.dev));
++#endif
++                      return 0;
++              }
++
++      }
++      return err;
++}
++
++void mali_platform_device_unregister(void)
++{
++      MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n"));
++
++      mali_platform_deinit();
++}
++
++static void mali_platform_device_release(struct device *device)
++{
++      MALI_DEBUG_PRINT(4, ("mali_platform_device_release() called\n"));
++}
++
++static int mali_os_suspend(struct device *device)
++{
++      int ret = 0;
++
++      MALI_DEBUG_PRINT(4, ("mali_os_suspend() called\n"));
++
++      if (NULL != device->driver &&
++          NULL != device->driver->pm &&
++          NULL != device->driver->pm->suspend)
++      {
++              /* Need to notify Mali driver about this event */
++              ret = device->driver->pm->suspend(device);
++      }
++
++      mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP);
++
++      return ret;
++}
++
++static int mali_os_resume(struct device *device)
++{
++      int ret = 0;
++
++      MALI_DEBUG_PRINT(4, ("mali_os_resume() called\n"));
++
++      mali_platform_power_mode_change(MALI_POWER_MODE_ON);
++
++      if (NULL != device->driver &&
++          NULL != device->driver->pm &&
++          NULL != device->driver->pm->resume)
++      {
++              /* Need to notify Mali driver about this event */
++              ret = device->driver->pm->resume(device);
++      }
++
++      return ret;
++}
++
++static int mali_os_freeze(struct device *device)
++{
++      int ret = 0;
++
++      MALI_DEBUG_PRINT(4, ("mali_os_freeze() called\n"));
++
++      if (NULL != device->driver &&
++          NULL != device->driver->pm &&
++          NULL != device->driver->pm->freeze)
++      {
++              /* Need to notify Mali driver about this event */
++              ret = device->driver->pm->freeze(device);
++      }
++
++      return ret;
++}
++
++static int mali_os_thaw(struct device *device)
++{
++      int ret = 0;
++
++      MALI_DEBUG_PRINT(4, ("mali_os_thaw() called\n"));
++
++      if (NULL != device->driver &&
++          NULL != device->driver->pm &&
++          NULL != device->driver->pm->thaw)
++      {
++              /* Need to notify Mali driver about this event */
++              ret = device->driver->pm->thaw(device);
++      }
++
++      return ret;
++}
++
++#ifdef CONFIG_PM_RUNTIME
++static int mali_runtime_suspend(struct device *device)
++{
++      int ret = 0;
++
++      MALI_DEBUG_PRINT(4, ("mali_runtime_suspend() called\n"));
++
++      if (NULL != device->driver &&
++          NULL != device->driver->pm &&
++          NULL != device->driver->pm->runtime_suspend)
++      {
++              /* Need to notify Mali driver about this event */
++              ret = device->driver->pm->runtime_suspend(device);
++      }
++
++      mali_platform_power_mode_change(MALI_POWER_MODE_LIGHT_SLEEP);
++
++      return ret;
++}
++
++static int mali_runtime_resume(struct device *device)
++{
++      int ret = 0;
++
++      MALI_DEBUG_PRINT(4, ("mali_runtime_resume() called\n"));
++
++      mali_platform_power_mode_change(MALI_POWER_MODE_ON);
++
++      if (NULL != device->driver &&
++          NULL != device->driver->pm &&
++          NULL != device->driver->pm->runtime_resume)
++      {
++              /* Need to notify Mali driver about this event */
++              ret = device->driver->pm->runtime_resume(device);
++      }
++
++      return ret;
++}
++
++static int mali_runtime_idle(struct device *device)
++{
++      MALI_DEBUG_PRINT(4, ("mali_runtime_idle() called\n"));
++
++      if (NULL != device->driver &&
++          NULL != device->driver->pm &&
++          NULL != device->driver->pm->runtime_idle)
++      {
++              /* Need to notify Mali driver about this event */
++              int ret = device->driver->pm->runtime_idle(device);
++              if (0 != ret)
++              {
++                      return ret;
++              }
++      }
++
++      pm_runtime_suspend(device);
++
++      return 0;
++}
++#endif
+diff --git a/drivers/gpu/arm/mali400/mali/platform/pegasus-m400/exynos4_pmm.c b/drivers/gpu/arm/mali400/mali/platform/pegasus-m400/exynos4_pmm.c
+new file mode 100644
+index 0000000..e8ab610
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/platform/pegasus-m400/exynos4_pmm.c
+@@ -0,0 +1,842 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_platform.c
++ * Platform specific Mali driver functions for a default platform
++ */
++#include "mali_kernel_common.h"
++#include "mali_osk.h"
++#include "exynos4_pmm.h"
++#include <linux/clk.h>
++#include <linux/err.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/regulator/consumer.h>
++
++#if defined(CONFIG_MALI400_PROFILING)
++#include "mali_osk_profiling.h"
++#endif
++
++#if defined(CONFIG_PM_RUNTIME)
++//#include <plat/pd.h>
++#endif
++
++#include <asm/io.h>
++#include <mach/regs-pmu.h>
++
++#include <linux/workqueue.h>
++
++#define MALI_DVFS_STEPS 5
++#define MALI_DVFS_WATING 10 // msec
++#define MALI_DVFS_DEFAULT_STEP 3
++
++#define MALI_DVFS_CLK_DEBUG 0
++#define SEC_THRESHOLD 1
++
++#define CPUFREQ_LOCK_DURING_440 0
++
++static int bMaliDvfsRun = 0;
++
++typedef struct mali_dvfs_tableTag{
++      unsigned int clock;
++      unsigned int freq;
++      unsigned int vol;
++#if SEC_THRESHOLD
++      unsigned int downthreshold;
++    unsigned int upthreshold;
++#endif
++}mali_dvfs_table;
++
++typedef struct mali_dvfs_statusTag{
++      unsigned int currentStep;
++      mali_dvfs_table * pCurrentDvfs;
++
++} mali_dvfs_status_t;
++
++/*dvfs status*/
++mali_dvfs_status_t maliDvfsStatus;
++int mali_dvfs_control;
++/*dvfs table*/
++
++mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={
++#if 1//defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
++                      /*step 0*/{160  ,1000000    ,875000    , 0   , 70},
++                      /*step 1*/{266  ,1000000    ,900000    ,62   , 90},
++                      /*step 2*/{350  ,1000000    ,950000    ,85   , 90},
++                      /*step 3*/{440  ,1000000    ,1025000   ,85   , 90},
++                      /*step 4*/{533  ,1000000    ,1075000   ,85   ,100} };
++#else
++                      /*step 0*/{134  ,1000000    , 950000   ,85   , 90},
++                      /*step 1*/{267  ,1000000    ,1050000   ,85   ,100} };
++#endif
++
++
++#define EXTXTALCLK_NAME  "ext_xtal"
++#define VPLLSRCCLK_NAME  "vpll_src"
++#define FOUTVPLLCLK_NAME "fout_vpll"
++#define SCLVPLLCLK_NAME  "sclk_vpll"
++#define GPUMOUT1CLK_NAME "mout_g3d1"
++
++#define MPLLCLK_NAME     "mout_mpll"
++#define GPUMOUT0CLK_NAME "mout_g3d0"
++#define GPUCLK_NAME      "sclk_g3d"
++#define CLK_DIV_STAT_G3D 0x1003C62C
++#define CLK_DESC         "clk-divider-status"
++
++static struct clk *ext_xtal_clock = NULL;
++static struct clk *vpll_src_clock = NULL;
++static struct clk *fout_vpll_clock = NULL;
++static struct clk *sclk_vpll_clock = NULL;
++
++static struct clk *mpll_clock = NULL;
++static struct clk *mali_parent_clock = NULL;
++static struct clk *mali_clock = NULL;
++
++#if defined(CONFIG_CPU_EXYNOS4412) || defined(CONFIG_CPU_EXYNOS4212)
++/* Pegasus */
++static const mali_bool bis_vpll  = MALI_TRUE;
++int mali_gpu_clk                 = 440;
++static unsigned int mali_gpu_vol = 1025000;
++#else
++/* Orion */
++static const mali_bool bis_vpll  = MALI_FALSE;
++int mali_gpu_clk                 = 267;
++static unsigned int mali_gpu_vol = 1050000; /* 1.05V */
++#endif
++
++static unsigned int GPU_MHZ   =               1000000;
++
++int  gpu_power_state;
++static int bPoweroff;
++
++#ifdef CONFIG_REGULATOR
++struct regulator *g3d_regulator = NULL;
++#endif
++
++mali_io_address clk_register_map = 0;
++
++/* DVFS */
++static unsigned int mali_dvfs_utilization = 255;
++
++static void mali_dvfs_work_handler(struct work_struct *w);
++
++static struct workqueue_struct *mali_dvfs_wq = 0;
++
++extern mali_io_address clk_register_map;
++
++_mali_osk_lock_t *mali_dvfs_lock = 0;
++
++static DECLARE_WORK(mali_dvfs_work, mali_dvfs_work_handler);
++
++
++/* export GPU frequency as a read-only parameter so that it can be read in /sys */
++module_param(mali_gpu_clk, int, S_IRUSR | S_IRGRP | S_IROTH);
++MODULE_PARM_DESC(mali_gpu_clk, "GPU frequency in MHz");
++
++#ifdef CONFIG_REGULATOR
++void mali_regulator_disable(void)
++{
++      if(IS_ERR_OR_NULL(g3d_regulator))
++      {
++              MALI_DEBUG_PRINT(1, ("error on mali_regulator_disable : g3d_regulator is null\n"));
++              return;
++      }
++      regulator_disable(g3d_regulator);
++}
++
++void mali_regulator_enable(void)
++{
++      if(IS_ERR_OR_NULL(g3d_regulator))
++      {
++              MALI_DEBUG_PRINT(1, ("error on mali_regulator_enable : g3d_regulator is null\n"));
++              return;
++      }
++      regulator_enable(g3d_regulator);
++}
++
++void mali_regulator_set_voltage(int min_uV, int max_uV)
++{
++      _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
++      if(IS_ERR_OR_NULL(g3d_regulator))
++      {
++              MALI_DEBUG_PRINT(1, ("error on mali_regulator_set_voltage : g3d_regulator is null\n"));
++              return;
++      }
++      MALI_PRINT(("= regulator_set_voltage: %d, %d \n",min_uV, max_uV));
++      regulator_set_voltage(g3d_regulator, min_uV, max_uV);
++      mali_gpu_vol = regulator_get_voltage(g3d_regulator);
++      MALI_DEBUG_PRINT(1, ("Mali voltage: %d\n", mali_gpu_vol));
++      _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
++}
++#endif
++
++unsigned long mali_clk_get_rate(void)
++{
++      return clk_get_rate(mali_clock);
++}
++
++
++static unsigned int get_mali_dvfs_status(void)
++{
++      return maliDvfsStatus.currentStep;
++}
++
++mali_bool mali_clk_get(void)
++{
++      if (bis_vpll)
++      {
++              if (ext_xtal_clock == NULL)
++              {
++                      ext_xtal_clock = clk_get(NULL,EXTXTALCLK_NAME);
++                      if (IS_ERR(ext_xtal_clock)) {
++                              MALI_PRINT( ("MALI Error : failed to get source ext_xtal_clock\n"));
++                              return MALI_FALSE;
++                      }
++              }
++
++              if (vpll_src_clock == NULL)
++              {
++                      vpll_src_clock = clk_get(NULL,VPLLSRCCLK_NAME);
++                      if (IS_ERR(vpll_src_clock)) {
++                              MALI_PRINT( ("MALI Error : failed to get source vpll_src_clock\n"));
++                              return MALI_FALSE;
++                      }
++              }
++
++              if (fout_vpll_clock == NULL)
++              {
++                      fout_vpll_clock = clk_get(NULL,FOUTVPLLCLK_NAME);
++                      if (IS_ERR(fout_vpll_clock)) {
++                              MALI_PRINT( ("MALI Error : failed to get source fout_vpll_clock\n"));
++                              return MALI_FALSE;
++                      }
++              }
++
++              if (sclk_vpll_clock == NULL)
++              {
++                      sclk_vpll_clock = clk_get(NULL,SCLVPLLCLK_NAME);
++                      if (IS_ERR(sclk_vpll_clock)) {
++                              MALI_PRINT( ("MALI Error : failed to get source sclk_vpll_clock\n"));
++                              return MALI_FALSE;
++                      }
++              }
++
++              if (mali_parent_clock == NULL)
++              {
++                      mali_parent_clock = clk_get(NULL, GPUMOUT1CLK_NAME);
++
++                      if (IS_ERR(mali_parent_clock)) {
++                              MALI_PRINT( ( "MALI Error : failed to get source mali parent clock\n"));
++                              return MALI_FALSE;
++                      }
++              }
++      }
++      else // mpll
++      {
++              if (mpll_clock == NULL)
++              {
++                      mpll_clock = clk_get(NULL,MPLLCLK_NAME);
++
++                      if (IS_ERR(mpll_clock)) {
++                              MALI_PRINT( ("MALI Error : failed to get source mpll clock\n"));
++                              return MALI_FALSE;
++                      }
++              }
++
++              if (mali_parent_clock == NULL)
++              {
++                      mali_parent_clock = clk_get(NULL, GPUMOUT0CLK_NAME);
++
++                      if (IS_ERR(mali_parent_clock)) {
++                              MALI_PRINT( ( "MALI Error : failed to get source mali parent clock\n"));
++                              return MALI_FALSE;
++                      }
++              }
++      }
++
++      // mali clock get always.
++      if (mali_clock == NULL)
++      {
++              mali_clock = clk_get(NULL, GPUCLK_NAME);
++
++              if (IS_ERR(mali_clock)) {
++                      MALI_PRINT( ("MALI Error : failed to get source mali clock\n"));
++                      return MALI_FALSE;
++              }
++      }
++
++      return MALI_TRUE;
++}
++
++void mali_clk_put(mali_bool binc_mali_clock)
++{
++      if (mali_parent_clock)
++      {
++              clk_put(mali_parent_clock);
++              mali_parent_clock = NULL;
++      }
++
++      if (mpll_clock)
++      {
++              clk_put(mpll_clock);
++              mpll_clock = NULL;
++      }
++
++      if (sclk_vpll_clock)
++      {
++              clk_put(sclk_vpll_clock);
++              sclk_vpll_clock = NULL;
++      }
++
++      if (binc_mali_clock && fout_vpll_clock)
++      {
++              clk_put(fout_vpll_clock);
++              fout_vpll_clock = NULL;
++      }
++
++      if (vpll_src_clock)
++      {
++              clk_put(vpll_src_clock);
++              vpll_src_clock = NULL;
++      }
++
++      if (ext_xtal_clock)
++      {
++              clk_put(ext_xtal_clock);
++              ext_xtal_clock = NULL;
++      }
++
++      if (binc_mali_clock && mali_clock)
++      {
++              clk_put(mali_clock);
++              mali_clock = NULL;
++      }
++}
++
++void mali_clk_set_rate(unsigned int clk, unsigned int mhz)
++{
++      int err;
++      unsigned long rate = (unsigned long)clk * (unsigned long)mhz;
++
++      _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
++      MALI_DEBUG_PRINT(3, ("Mali platform: Setting frequency to %d mhz\n", clk));
++      if (bis_vpll && fout_vpll_clock)
++      {
++              err = clk_set_rate(fout_vpll_clock, (unsigned int)mali_gpu_clk * GPU_MHZ);
++              if (err) MALI_PRINT_ERROR(("Failed to set vpll: %d\n", err));
++      }
++      err = clk_set_rate(mali_clock, rate);
++      if (err) MALI_PRINT_ERROR(("Failed to set Mali clock: %d\n", err));
++
++      rate = mali_clk_get_rate();
++
++      MALI_PRINT(("Mali frequency %d\n", rate / mhz));
++      GPU_MHZ = mhz;
++      mali_gpu_clk = (int)(rate / mhz);
++      _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
++}
++
++int get_mali_dvfs_control_status(void)
++{
++      return mali_dvfs_control;
++}
++
++mali_bool set_mali_dvfs_current_step(unsigned int step)
++{
++      _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
++      maliDvfsStatus.currentStep = step % MALI_DVFS_STEPS;
++      _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
++      return MALI_TRUE;
++}
++
++
++static mali_bool set_mali_dvfs_status(u32 step,mali_bool boostup)
++{
++      u32 validatedStep=step;
++#if MALI_DVFS_CLK_DEBUG
++      unsigned int *pRegMaliClkDiv;
++      unsigned int *pRegMaliMpll;
++#endif
++
++      if(boostup)     {
++#ifdef CONFIG_REGULATOR
++              /*change the voltage*/
++              mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol);
++#endif
++              /*change the clock*/
++              mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq);
++      } else {
++              /*change the clock*/
++              mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq);
++#ifdef CONFIG_REGULATOR
++              /*change the voltage*/
++              mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol);
++#endif
++      }
++
++#if defined(CONFIG_MALI400_PROFILING)
++      _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE| MALI_PROFILING_EVENT_CHANNEL_GPU|MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0);
++#endif
++      mali_clk_put(MALI_FALSE);
++
++#if MALI_DVFS_CLK_DEBUG
++      pRegMaliClkDiv = ioremap(0x1003c52c,32);
++      pRegMaliMpll = ioremap(0x1003c22c,32);
++      MALI_PRINT( ("Mali MPLL reg:%d, CLK DIV: %d \n",*pRegMaliMpll, *pRegMaliClkDiv));
++#endif
++
++#ifdef EXYNOS4_ASV_ENABLED
++      if (samsung_rev() < EXYNOS4412_REV_2_0) {
++              if (mali_dvfs[step].clock == 160)
++                      exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_100V);
++              else
++                      exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_130V);
++      }
++#endif
++
++
++//    maliDvfsStatus.currentStep = validatedStep;
++      set_mali_dvfs_current_step(validatedStep);
++      /*for future use*/
++      maliDvfsStatus.pCurrentDvfs = &mali_dvfs[validatedStep];
++
++#if CPUFREQ_LOCK_DURING_440
++      /* lock/unlock CPU freq by Mali */
++      if (mali_dvfs[step].clock == 440)
++              err = cpufreq_lock_by_mali(1200);
++      else
++              cpufreq_unlock_by_mali();
++#endif
++
++
++      return MALI_TRUE;
++}
++
++static void mali_platform_wating(u32 msec)
++{
++      /*sample wating
++      change this in the future with proper check routine.
++      */
++      unsigned int read_val;
++      while(1)
++      {
++              read_val = _mali_osk_mem_ioread32(clk_register_map, 0x00);
++              if ((read_val & 0x8000)==0x0000) break;
++
++              _mali_osk_time_ubusydelay(100); /* 1000 -> 100 : 20101218 */
++      }
++      /* _mali_osk_time_ubusydelay(msec*1000);*/
++}
++
++static mali_bool change_mali_dvfs_status(u32 step, mali_bool boostup )
++{
++      MALI_DEBUG_PRINT(4, ("> change_mali_dvfs_status: %d, %d \n",step, boostup));
++
++      if(!set_mali_dvfs_status(step, boostup))
++      {
++              MALI_DEBUG_PRINT(1, ("error on set_mali_dvfs_status: %d, %d \n",step, boostup));
++              return MALI_FALSE;
++      }
++
++      /*wait until clock and voltage is stablized*/
++      mali_platform_wating(MALI_DVFS_WATING); /*msec*/
++
++      return MALI_TRUE;
++}
++
++static unsigned int decideNextStatus(unsigned int utilization)
++{
++      unsigned int level= maliDvfsStatus.currentStep;
++      unsigned int uiStepCount = 0;
++
++      if (mali_dvfs_control == 0) {
++              // && maliDvfsStatus.currentStep) {
++              if (utilization > (int)(255 * mali_dvfs[maliDvfsStatus.currentStep].upthreshold / 100) &&
++                              level < MALI_DVFS_STEPS - 1) {
++                      level++;
++//                    if ((samsung_rev() < EXYNOS4412_REV_2_0) && (maliDvfsStatus.currentStep == 3)) {
++//                            level=get_mali_dvfs_status();
++//                    }
++              }
++              if (utilization < (int)(255 * mali_dvfs[maliDvfsStatus.currentStep].downthreshold / 100) &&
++                              level > 0) {
++                      level--;
++              }
++      } else {
++              for(uiStepCount = MALI_DVFS_STEPS-1; uiStepCount >= 0; uiStepCount--) {
++                      if ( mali_dvfs_control >= mali_dvfs[uiStepCount].clock ) {
++                              maliDvfsStatus.currentStep = uiStepCount;
++                              level = maliDvfsStatus.currentStep;
++                              break;
++                      }
++              }
++      }
++
++      return level;
++}
++
++static mali_bool mali_dvfs_status(unsigned int utilization)
++{
++      unsigned int nextStatus=0;
++      unsigned int curStatus=0;
++      mali_bool boostup=0;
++
++      MALI_DEBUG_PRINT(4, ("> mali_dvfs_status: %d \n",utilization));
++
++      /*decide next step*/
++      curStatus = get_mali_dvfs_status();
++      nextStatus = decideNextStatus(utilization);
++
++      MALI_DEBUG_PRINT(4, ("= curStatus %d, nextStatus %d, maliDvfsStatus.currentStep %d \n", curStatus, nextStatus, maliDvfsStatus.currentStep));
++      /*if next status is same with current status, don't change anything*/
++      if(curStatus!=nextStatus)
++      {
++              /*check if boost up or not*/
++              if(nextStatus > maliDvfsStatus.currentStep) boostup = 1;
++
++              /*change mali dvfs status*/
++              if(!change_mali_dvfs_status(nextStatus,boostup))
++              {
++                      MALI_DEBUG_PRINT(1, ("error on change_mali_dvfs_status \n"));
++                      return MALI_FALSE;
++              }
++      }
++      return MALI_TRUE;
++}
++
++
++int mali_dvfs_is_running(void)
++{
++      return bMaliDvfsRun;
++}
++
++
++static void mali_dvfs_work_handler(struct work_struct *w)
++{
++      bMaliDvfsRun=1;
++
++      MALI_DEBUG_PRINT(3, ("=== mali_dvfs_work_handler\n"));
++
++      if(!mali_dvfs_status(mali_dvfs_utilization))
++      MALI_DEBUG_PRINT(1,( "error on mali dvfs status in mali_dvfs_work_handler"));
++
++      bMaliDvfsRun=0;
++}
++
++
++mali_bool init_mali_dvfs_status(void)
++{
++      /*default status
++      add here with the right function to get initilization value.
++      */
++
++      if (!mali_dvfs_wq)
++      {
++              mali_dvfs_wq = create_singlethread_workqueue("mali_dvfs");
++      }
++
++      /*add a error handling here*/
++      maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP;
++
++      return MALI_TRUE;
++}
++
++void deinit_mali_dvfs_status(void)
++{
++      if (mali_dvfs_wq)
++      {
++              destroy_workqueue(mali_dvfs_wq);
++              mali_dvfs_wq = NULL;
++      }
++}
++
++mali_bool mali_dvfs_handler(unsigned int utilization)
++{
++      mali_dvfs_utilization = utilization;
++      queue_work_on(0, mali_dvfs_wq, &mali_dvfs_work);
++
++      return MALI_TRUE;
++}
++
++static mali_bool init_mali_clock(void)
++{
++      mali_bool ret = MALI_TRUE;
++      gpu_power_state = 0;
++      bPoweroff = 1;
++
++      if (mali_clock != 0)
++              return ret; /* already initialized */
++
++      mali_dvfs_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE
++                      | _MALI_OSK_LOCKFLAG_ONELOCK, 0, 0);
++      if (mali_dvfs_lock == NULL)
++              return _MALI_OSK_ERR_FAULT;
++
++
++
++      if (!mali_clk_get())
++      {
++              MALI_PRINT(("Error: Failed to get Mali clock\n"));
++              goto err_clk;
++      }
++
++      if (bis_vpll)
++      {
++              clk_set_parent(vpll_src_clock, ext_xtal_clock);
++              clk_set_parent(sclk_vpll_clock, fout_vpll_clock);
++
++              clk_set_parent(mali_parent_clock, sclk_vpll_clock);
++              clk_set_parent(mali_clock, mali_parent_clock);
++      }
++      else
++      {
++              clk_set_parent(mali_parent_clock, mpll_clock);
++              clk_set_parent(mali_clock, mali_parent_clock);
++      }
++
++      if (clk_enable(mali_clock) < 0)
++      {
++              MALI_PRINT(("Error: Failed to enable clock\n"));
++              goto err_clk;
++      }
++
++      mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ);
++
++      MALI_PRINT(("init_mali_clock mali_clock %x\n", mali_clock));
++
++#ifdef CONFIG_REGULATOR
++      g3d_regulator = regulator_get(NULL, "vdd_g3d");
++
++      if (IS_ERR(g3d_regulator))
++      {
++              MALI_PRINT( ("MALI Error : failed to get vdd_g3d\n"));
++              ret = MALI_FALSE;
++              goto err_regulator;
++      }
++
++      regulator_enable(g3d_regulator);
++      mali_regulator_set_voltage(mali_gpu_vol, mali_gpu_vol);
++#endif
++
++#if defined(CONFIG_MALI400_PROFILING)
++      _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|
++                      MALI_PROFILING_EVENT_CHANNEL_GPU|MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
++                      mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0);
++#endif
++
++      mali_clk_put(MALI_FALSE);
++
++      return MALI_TRUE;
++
++#ifdef CONFIG_REGULATOR
++err_regulator:
++      regulator_put(g3d_regulator);
++#endif
++err_clk:
++      mali_clk_put(MALI_TRUE);
++
++      return ret;
++}
++
++static mali_bool deinit_mali_clock(void)
++{
++      if (mali_clock == 0)
++              return MALI_TRUE;
++
++#ifdef CONFIG_REGULATOR
++      if (g3d_regulator)
++      {
++              regulator_put(g3d_regulator);
++              g3d_regulator = NULL;
++      }
++#endif
++
++      mali_clk_put(MALI_TRUE);
++
++      return MALI_TRUE;
++}
++
++
++static _mali_osk_errcode_t enable_mali_clocks(void)
++{
++      int err;
++      err = clk_enable(mali_clock);
++      MALI_DEBUG_PRINT(3,("enable_mali_clocks mali_clock %p error %d \n", mali_clock, err));
++
++      /* set clock rate */
++      mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ);
++
++      maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP;
++
++      MALI_SUCCESS;
++}
++
++static _mali_osk_errcode_t disable_mali_clocks(void)
++{
++      clk_disable(mali_clock);
++      MALI_DEBUG_PRINT(3,("disable_mali_clocks mali_clock %p \n", mali_clock));
++
++      MALI_SUCCESS;
++}
++
++/* Some defines changed names in later Odroid-A kernels. Make sure it works for both. */
++#ifndef S5P_G3D_CONFIGURATION
++#define S5P_G3D_CONFIGURATION EXYNOS4_G3D_CONFIGURATION
++#endif
++#ifndef S5P_G3D_STATUS
++#define S5P_G3D_STATUS EXYNOS4_G3D_CONFIGURATION + 0x4
++#endif
++
++_mali_osk_errcode_t g3d_power_domain_control(int bpower_on)
++{
++      if (bpower_on)
++      {
++              void __iomem *status;
++              u32 timeout;
++              __raw_writel(EXYNOS_INT_LOCAL_PWR_EN, S5P_G3D_CONFIGURATION);
++              status = S5P_G3D_STATUS;
++
++              timeout = 10;
++              while ((__raw_readl(status) & EXYNOS_INT_LOCAL_PWR_EN)
++                      != EXYNOS_INT_LOCAL_PWR_EN) {
++                      if (timeout == 0) {
++                              MALI_PRINTF(("Power domain  enable failed.\n"));
++                              return -ETIMEDOUT;
++                      }
++                      timeout--;
++                      _mali_osk_time_ubusydelay(100);
++              }
++      }
++      else
++      {
++              void __iomem *status;
++              u32 timeout;
++              __raw_writel(0, S5P_G3D_CONFIGURATION);
++
++              status = S5P_G3D_STATUS;
++              /* Wait max 1ms */
++              timeout = 10;
++              while (__raw_readl(status) & EXYNOS_INT_LOCAL_PWR_EN)
++              {
++                      if (timeout == 0) {
++                              MALI_PRINTF(("Power domain  disable failed.\n" ));
++                              return -ETIMEDOUT;
++                      }
++                      timeout--;
++                      _mali_osk_time_ubusydelay( 100);
++              }
++      }
++
++      MALI_SUCCESS;
++}
++
++_mali_osk_errcode_t mali_platform_init(void)
++{
++      MALI_CHECK(init_mali_clock(), _MALI_OSK_ERR_FAULT);
++#ifdef CONFIG_MALI_DVFS
++      if (!clk_register_map) clk_register_map = _mali_osk_mem_mapioregion( CLK_DIV_STAT_G3D, 0x20, CLK_DESC );
++      if(!init_mali_dvfs_status())
++              MALI_DEBUG_PRINT(1, ("mali_platform_init failed\n"));
++#endif
++      mali_platform_power_mode_change(MALI_POWER_MODE_ON);
++
++      MALI_SUCCESS;
++}
++
++_mali_osk_errcode_t mali_platform_deinit(void)
++{
++
++      mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP);
++      deinit_mali_clock();
++
++#ifdef CONFIG_MALI_DVFS
++      deinit_mali_dvfs_status();
++      if (clk_register_map )
++      {
++              _mali_osk_mem_unmapioregion(CLK_DIV_STAT_G3D, 0x20, clk_register_map);
++              clk_register_map = NULL;
++      }
++#endif
++
++      MALI_SUCCESS;
++}
++
++_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode)
++{
++      switch (power_mode)
++      {
++              case MALI_POWER_MODE_ON:
++                      MALI_DEBUG_PRINT(3, ("Mali platform: Got MALI_POWER_MODE_ON event, %s\n",
++                                           bPoweroff ? "powering on" : "already on"));
++                      if (bPoweroff == 1)
++                      {
++#if !defined(CONFIG_PM_RUNTIME)
++                              g3d_power_domain_control(1);
++#endif
++                              MALI_DEBUG_PRINT(4,("enable clock \n"));
++                              enable_mali_clocks();
++#if defined(CONFIG_MALI400_PROFILING)
++                              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
++                                              MALI_PROFILING_EVENT_CHANNEL_GPU |
++                                              MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, mali_gpu_clk,
++                                              mali_gpu_vol/1000, 0, 0, 0);
++
++#endif
++                              bPoweroff=0;
++                      }
++                      break;
++              case MALI_POWER_MODE_LIGHT_SLEEP:
++              case MALI_POWER_MODE_DEEP_SLEEP:
++                      MALI_DEBUG_PRINT(3, ("Mali platform: Got %s event, %s\n", power_mode ==
++                                              MALI_POWER_MODE_LIGHT_SLEEP ?  "MALI_POWER_MODE_LIGHT_SLEEP" :
++                                              "MALI_POWER_MODE_DEEP_SLEEP", bPoweroff ? "already off" : "powering off"));
++                      if (bPoweroff == 0)
++                      {
++                              disable_mali_clocks();
++#if defined(CONFIG_MALI400_PROFILING)
++                              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
++                                              MALI_PROFILING_EVENT_CHANNEL_GPU |
++                                              MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, 0, 0, 0, 0, 0);
++#endif
++
++#if !defined(CONFIG_PM_RUNTIME)
++                              g3d_power_domain_control(0);
++#endif
++                              bPoweroff=1;
++                      }
++
++                      break;
++      }
++      MALI_SUCCESS;
++}
++
++void mali_gpu_utilization_handler(unsigned int utilization)
++{
++      if (bPoweroff==0)
++      {
++#ifdef CONFIG_MALI_DVFS
++              if(!mali_dvfs_handler(utilization))
++                      MALI_DEBUG_PRINT(1,( "error on mali dvfs status in utilization\n"));
++#endif
++      }
++}
++
++
++/*REGISTER
++ Enable Power
++ pPowerPTR = ioremap(0x10023C60,32);
++ *pPowerPTR |= 0x7;
++
++ Enable Clock
++ pPTR = ioremap(0x1003C92C,32);
++ *pPTR |= 0x1;
++*/
++
+diff --git a/drivers/gpu/arm/mali400/mali/platform/pegasus-m400/exynos4_pmm.h b/drivers/gpu/arm/mali400/mali/platform/pegasus-m400/exynos4_pmm.h
+new file mode 100644
+index 0000000..1b69b16
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/platform/pegasus-m400/exynos4_pmm.h
+@@ -0,0 +1,86 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file mali_platform.h
++ * Platform specific Mali driver functions
++ */
++
++#ifndef __EXYNOS4_PMM_H__
++#define __EXYNOS4_PMM_H__
++
++#include "mali_osk.h"
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++/** @brief description of power change reasons
++ */
++typedef enum mali_power_mode_tag
++{
++      MALI_POWER_MODE_ON,
++      MALI_POWER_MODE_LIGHT_SLEEP,
++      MALI_POWER_MODE_DEEP_SLEEP,
++} mali_power_mode;
++
++/** @brief Platform specific setup and initialisation of MALI
++ *
++ * This is called from the entrypoint of the driver to initialize the platform
++ *
++ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
++ */
++_mali_osk_errcode_t mali_platform_init(void);
++
++/** @brief Platform specific deinitialisation of MALI
++ *
++ * This is called on the exit of the driver to terminate the platform
++ *
++ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
++ */
++_mali_osk_errcode_t mali_platform_deinit(void);
++
++/** @brief Platform specific powerdown sequence of MALI
++ *
++ * Call as part of platform init if there is no PMM support, else the
++ * PMM will call it.
++ * There are three power modes defined:
++ *  1) MALI_POWER_MODE_ON
++ *  2) MALI_POWER_MODE_LIGHT_SLEEP
++ *  3) MALI_POWER_MODE_DEEP_SLEEP
++ * MALI power management module transitions to MALI_POWER_MODE_LIGHT_SLEEP mode when MALI is idle
++ * for idle timer (software timer defined in mali_pmm_policy_jobcontrol.h) duration, MALI transitions
++ * to MALI_POWER_MODE_LIGHT_SLEEP mode during timeout if there are no more jobs queued.
++ * MALI power management module transitions to MALI_POWER_MODE_DEEP_SLEEP mode when OS does system power
++ * off.
++ * Customer has to add power down code when MALI transitions to MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP
++ * mode.
++ * MALI_POWER_MODE_ON mode is entered when the MALI is to powered up. Some customers want to control voltage regulators during
++ * the whole system powers on/off. Customer can track in this function whether the MALI is powered up from
++ * MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP mode and manage the voltage regulators as well.
++ * @param power_mode defines the power modes
++ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
++ */
++_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode);
++
++
++/** @brief Platform specific handling of GPU utilization data
++ *
++ * When GPU utilization data is enabled, this function will be
++ * periodically called.
++ *
++ * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization.
++ */
++void mali_gpu_utilization_handler(unsigned int utilization);
++
++#ifdef __cplusplus
++}
++#endif
++#endif
+diff --git a/drivers/gpu/arm/mali400/mali/platform/redwood/exynos4.c b/drivers/gpu/arm/mali400/mali/platform/redwood/exynos4.c
+new file mode 100644
+index 0000000..348bc7e
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/platform/redwood/exynos4.c
+@@ -0,0 +1,272 @@
++/* drivers/gpu/mali400/mali/platform/pegasus-m400/exynos4.c
++ *
++ * Copyright 2011 by S.LSI. Samsung Electronics Inc.
++ * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea
++ *
++ * Samsung SoC Mali400 DVFS driver
++ *
++ * 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.
++ */
++
++/**
++ * @file exynos4.c
++ * Platform specific Mali driver functions for the exynos 4XXX based platforms
++ */
++#include <linux/platform_device.h>
++#include <linux/version.h>
++#include <linux/pm.h>
++#ifdef CONFIG_PM_RUNTIME
++#include <linux/pm_runtime.h>
++#endif
++#include <linux/mali/mali_utgard.h>
++#include "mali_kernel_common.h"
++
++#include <linux/irq.h>
++#include <plat/devs.h>
++
++#include "exynos4_pmm.h"
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) && LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)
++extern struct platform_device exynos4_device_pd[];
++#else
++extern struct platform_device s5pv310_device_pd[];
++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) */
++
++static void mali_platform_device_release(struct device *device);
++static int mali_os_suspend(struct device *device);
++static int mali_os_resume(struct device *device);
++static int mali_os_freeze(struct device *device);
++static int mali_os_thaw(struct device *device);
++#ifdef CONFIG_PM_RUNTIME
++static int mali_runtime_suspend(struct device *device);
++static int mali_runtime_resume(struct device *device);
++static int mali_runtime_idle(struct device *device);
++#endif
++
++#define MALI_GP_IRQ       EXYNOS4_IRQ_GP_3D
++#define MALI_PP0_IRQ      EXYNOS4_IRQ_PP0_3D
++#define MALI_PP1_IRQ      EXYNOS4_IRQ_PP1_3D
++#define MALI_PP2_IRQ      EXYNOS4_IRQ_PP2_3D
++#define MALI_PP3_IRQ      EXYNOS4_IRQ_PP3_3D
++#define MALI_GP_MMU_IRQ   EXYNOS4_IRQ_GPMMU_3D
++#define MALI_PP0_MMU_IRQ  EXYNOS4_IRQ_PPMMU0_3D
++#define MALI_PP1_MMU_IRQ  EXYNOS4_IRQ_PPMMU1_3D
++#define MALI_PP2_MMU_IRQ  EXYNOS4_IRQ_PPMMU2_3D
++#define MALI_PP3_MMU_IRQ  EXYNOS4_IRQ_PPMMU3_3D
++
++static struct resource mali_gpu_resources[] =
++{
++      MALI_GPU_RESOURCES_MALI400_MP4(0x13000000,
++                                     MALI_GP_IRQ, MALI_GP_MMU_IRQ,
++                                     MALI_PP0_IRQ, MALI_PP0_MMU_IRQ,
++                                     MALI_PP1_IRQ, MALI_PP1_MMU_IRQ,
++                                     MALI_PP2_IRQ, MALI_PP2_MMU_IRQ,
++                                     MALI_PP3_IRQ, MALI_PP3_MMU_IRQ)
++};
++
++static struct dev_pm_ops mali_gpu_device_type_pm_ops =
++{
++      .suspend = mali_os_suspend,
++      .resume = mali_os_resume,
++      .freeze = mali_os_freeze,
++      .thaw = mali_os_thaw,
++#ifdef CONFIG_PM_RUNTIME
++      .runtime_suspend = mali_runtime_suspend,
++      .runtime_resume = mali_runtime_resume,
++      .runtime_idle = mali_runtime_idle,
++#endif
++};
++
++static struct device_type mali_gpu_device_device_type =
++{
++      .pm = &mali_gpu_device_type_pm_ops,
++};
++
++
++static struct platform_device *mali_gpu_device;
++
++static struct mali_gpu_device_data mali_gpu_data =
++{
++      .shared_mem_size = 256 * 1024 * 1024, /* 256MB */
++      .fb_start = 0x40000000,
++      .fb_size = 0xb1000000,
++/*    .utilization_interval = 1000, *//* 1000ms */
++      .utilization_interval = 100, /* 100ms in Tizen */
++      .utilization_handler = mali_gpu_utilization_handler,
++};
++
++int mali_platform_device_register(void)
++{
++      int err;
++
++      MALI_DEBUG_PRINT(4, ("mali_platform_device_register() called\n"));
++
++      /* Connect resources to the device */
++      err = platform_device_add_resources(&exynos4_device_g3d, mali_gpu_resources, sizeof(mali_gpu_resources) / sizeof(mali_gpu_resources[0]));
++      if (0 == err)
++      {
++              err = platform_device_add_data(&exynos4_device_g3d, &mali_gpu_data, sizeof(mali_gpu_data));
++              if (0 == err)
++              {
++                      mali_platform_init();
++
++#ifdef CONFIG_PM_RUNTIME
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
++                      pm_runtime_set_autosuspend_delay(&(exynos4_device_g3d.dev), 300);
++                      pm_runtime_use_autosuspend(&(exynos4_device_g3d.dev));
++#endif
++                      pm_runtime_enable(&(exynos4_device_g3d.dev));
++#endif
++                      return 0;
++              }
++
++      }
++      return err;
++}
++
++void mali_platform_device_unregister(void)
++{
++      MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n"));
++
++      mali_platform_deinit();
++}
++
++static void mali_platform_device_release(struct device *device)
++{
++      MALI_DEBUG_PRINT(4, ("mali_platform_device_release() called\n"));
++}
++
++static int mali_os_suspend(struct device *device)
++{
++      int ret = 0;
++
++      MALI_DEBUG_PRINT(4, ("mali_os_suspend() called\n"));
++
++      if (NULL != device->driver &&
++          NULL != device->driver->pm &&
++          NULL != device->driver->pm->suspend)
++      {
++              /* Need to notify Mali driver about this event */
++              ret = device->driver->pm->suspend(device);
++      }
++
++      mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP);
++
++      return ret;
++}
++
++static int mali_os_resume(struct device *device)
++{
++      int ret = 0;
++
++      MALI_DEBUG_PRINT(4, ("mali_os_resume() called\n"));
++
++      mali_platform_power_mode_change(MALI_POWER_MODE_ON);
++
++      if (NULL != device->driver &&
++          NULL != device->driver->pm &&
++          NULL != device->driver->pm->resume)
++      {
++              /* Need to notify Mali driver about this event */
++              ret = device->driver->pm->resume(device);
++      }
++
++      return ret;
++}
++
++static int mali_os_freeze(struct device *device)
++{
++      int ret = 0;
++
++      MALI_DEBUG_PRINT(4, ("mali_os_freeze() called\n"));
++
++      if (NULL != device->driver &&
++          NULL != device->driver->pm &&
++          NULL != device->driver->pm->freeze)
++      {
++              /* Need to notify Mali driver about this event */
++              ret = device->driver->pm->freeze(device);
++      }
++
++      return ret;
++}
++
++static int mali_os_thaw(struct device *device)
++{
++      int ret = 0;
++
++      MALI_DEBUG_PRINT(4, ("mali_os_thaw() called\n"));
++
++      if (NULL != device->driver &&
++          NULL != device->driver->pm &&
++          NULL != device->driver->pm->thaw)
++      {
++              /* Need to notify Mali driver about this event */
++              ret = device->driver->pm->thaw(device);
++      }
++
++      return ret;
++}
++
++#ifdef CONFIG_PM_RUNTIME
++static int mali_runtime_suspend(struct device *device)
++{
++      int ret = 0;
++
++      MALI_DEBUG_PRINT(4, ("mali_runtime_suspend() called\n"));
++
++      if (NULL != device->driver &&
++          NULL != device->driver->pm &&
++          NULL != device->driver->pm->runtime_suspend)
++      {
++              /* Need to notify Mali driver about this event */
++              ret = device->driver->pm->runtime_suspend(device);
++      }
++
++      mali_platform_power_mode_change(MALI_POWER_MODE_LIGHT_SLEEP);
++
++      return ret;
++}
++
++static int mali_runtime_resume(struct device *device)
++{
++      int ret = 0;
++
++      MALI_DEBUG_PRINT(4, ("mali_runtime_resume() called\n"));
++
++      mali_platform_power_mode_change(MALI_POWER_MODE_ON);
++
++      if (NULL != device->driver &&
++          NULL != device->driver->pm &&
++          NULL != device->driver->pm->runtime_resume)
++      {
++              /* Need to notify Mali driver about this event */
++              ret = device->driver->pm->runtime_resume(device);
++      }
++
++      return ret;
++}
++
++static int mali_runtime_idle(struct device *device)
++{
++      MALI_DEBUG_PRINT(4, ("mali_runtime_idle() called\n"));
++
++      if (NULL != device->driver &&
++          NULL != device->driver->pm &&
++          NULL != device->driver->pm->runtime_idle)
++      {
++              /* Need to notify Mali driver about this event */
++              int ret = device->driver->pm->runtime_idle(device);
++              if (0 != ret)
++              {
++                      return ret;
++              }
++      }
++
++      pm_runtime_suspend(device);
++
++      return 0;
++}
++#endif
+diff --git a/drivers/gpu/arm/mali400/mali/platform/redwood/exynos4_pmm.c b/drivers/gpu/arm/mali400/mali/platform/redwood/exynos4_pmm.c
+new file mode 100644
+index 0000000..09d0f98
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/platform/redwood/exynos4_pmm.c
+@@ -0,0 +1,1010 @@
++/* drivers/gpu/mali400/mali/platform/pegasus-m400/exynos4_pmm.c
++ *
++ * Copyright 2011 by S.LSI. Samsung Electronics Inc.
++ * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea
++ *
++ * Samsung SoC Mali400 DVFS driver
++ *
++ * 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.
++ */
++
++/**
++ * @file exynos4_pmm.c
++ * Platform specific Mali driver functions for the exynos 4XXX based platforms
++ */
++#include "mali_kernel_common.h"
++#include "mali_osk.h"
++#include "exynos4_pmm.h"
++#include <linux/clk.h>
++#include <linux/err.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/regulator/consumer.h>
++
++#if defined(CONFIG_MALI400_PROFILING)
++#include "mali_osk_profiling.h"
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)
++/* Some defines changed names in later Odroid-A kernels. Make sure it works for both. */
++#ifndef S5P_G3D_CONFIGURATION
++#define S5P_G3D_CONFIGURATION S5P_PMU_G3D_CONF
++#endif
++#ifndef S5P_G3D_STATUS
++#define S5P_G3D_STATUS S5P_PMU_G3D_CONF + 0x4
++#endif
++#if defined(CONFIG_PM_RUNTIME)
++#include <plat/pd.h>
++#endif
++#else
++/* Some defines changed names in later Odroid-A kernels. Make sure it works for both. */
++#ifndef S5P_G3D_CONFIGURATION
++#define S5P_G3D_CONFIGURATION EXYNOS4_G3D_CONFIGURATION
++#endif
++#ifndef S5P_G3D_STATUS
++#define S5P_G3D_STATUS (EXYNOS4_G3D_CONFIGURATION + 0x4)
++#endif
++#ifndef S5P_INT_LOCAL_PWR_EN
++#define S5P_INT_LOCAL_PWR_EN EXYNOS_INT_LOCAL_PWR_EN
++#endif
++#endif
++
++#include <asm/io.h>
++#include <mach/regs-pmu.h>
++#include <linux/pm_qos.h>
++#ifdef CONFIG_EXYNOS_BUSFREQ_OPP
++#include <mach/busfreq_exynos4.h>
++#endif
++
++#include <linux/workqueue.h>
++
++#define MALI_DVFS_STEPS 5
++#define MALI_DVFS_WATING 10 /* msec */
++#define MALI_DVFS_DEFAULT_STEP 1
++
++#ifdef CONFIG_CPU_FREQ
++#include <mach/asv.h>
++#define EXYNOS4_ASV_ENABLED
++#endif
++
++#define MALI_DVFS_CLK_DEBUG 0
++#define SEC_THRESHOLD 1
++
++static int bMaliDvfsRun = 0;
++
++typedef struct mali_dvfs_tableTag{
++      unsigned int clock;
++      unsigned int freq;
++      unsigned int vol;
++#if SEC_THRESHOLD
++      unsigned int downthreshold;
++      unsigned int upthreshold;
++#endif
++}mali_dvfs_table;
++
++typedef struct mali_dvfs_statusTag{
++      unsigned int currentStep;
++      mali_dvfs_table * pCurrentDvfs;
++
++} mali_dvfs_status_t;
++
++/* dvfs status */
++mali_dvfs_status_t maliDvfsStatus;
++int mali_dvfs_control;
++
++typedef struct mali_runtime_resumeTag{
++      int clk;
++      int vol;
++      unsigned int step;
++}mali_runtime_resume_table;
++
++/*mali_runtime_resume_table mali_runtime_resume = {266, 900000, 1};*/
++mali_runtime_resume_table mali_runtime_resume = {160, 875000, 1};
++
++/* dvfs table */
++mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={
++                      /*step 0*/{160  ,1000000    ,875000    , 0   , 70},
++                      /*step 1*/{266  ,1000000    ,900000    ,62   , 90},
++                      /*step 2*/{350  ,1000000    ,950000    ,85   , 90},
++                      /*step 3*/{440  ,1000000    ,1025000   ,85   , 90},
++                      /*step 4*/{533  ,1000000    ,1075000   ,85   ,100} };
++
++#ifdef EXYNOS4_ASV_ENABLED
++#define ASV_LEVEL      12     /* ASV0, 1, 11 is reserved */
++#define ASV_LEVEL_PRIME        13  /* ASV0, 1, 12 is reserved */
++
++static unsigned int asv_3d_volt_9_table_for_prime[MALI_DVFS_STEPS][ASV_LEVEL_PRIME] = {
++      {  962500,  937500,  925000,  912500,  900000,  887500,  875000,  862500,  875000,  862500,  850000,  850000,  850000},  /* L4(160Mhz) */
++#if (MALI_DVFS_STEPS > 1)
++      {  987500,  962500,  950000,  937500,  925000,  912500,  900000,  887500,  900000,  887500,  875000,  875000,  875000}, /* L3(266Mhz) */
++#if (MALI_DVFS_STEPS > 2)
++      { 1037500, 1012500, 1000000,  987500,  975000,  962500,  950000,  937500,  950000,  937500,  912500,  900000,  887500}, /* L2(350Mhz) */
++#if (MALI_DVFS_STEPS > 3)
++      { 1100000, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 1012500, 1000000,  975000,  962500,  950000}, /* L1(440Mhz) */
++#if (MALI_DVFS_STEPS > 4)
++      { 1162500, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1075000, 1062500, 1037500, 1025000, 1012500}, /* L0(533Mhz) */
++#endif
++#endif
++#endif
++#endif
++};
++#endif /* ASV_LEVEL */
++
++#define EXTXTALCLK_NAME  "ext_xtal"
++#define VPLLSRCCLK_NAME  "vpll_src"
++#define FOUTVPLLCLK_NAME "fout_vpll"
++#define SCLVPLLCLK_NAME  "sclk_vpll"
++#define GPUMOUT1CLK_NAME "mout_g3d1"
++
++#define MPLLCLK_NAME     "mout_mpll"
++#define GPUMOUT0CLK_NAME "mout_g3d0"
++#define GPUCLK_NAME      "sclk_g3d"
++#define CLK_DIV_STAT_G3D 0x1003C62C
++#define CLK_DESC         "clk-divider-status"
++
++static struct clk *ext_xtal_clock = NULL;
++static struct clk *vpll_src_clock = NULL;
++static struct clk *fout_vpll_clock = NULL;
++static struct clk *sclk_vpll_clock = NULL;
++
++static struct clk *mpll_clock = NULL;
++static struct clk *mali_parent_clock = NULL;
++static struct clk *mali_clock = NULL;
++
++/* Pegasus */
++static const mali_bool bis_vpll = MALI_TRUE;
++int mali_gpu_clk = 440;
++int mali_gpu_vol = 1025000;
++
++static unsigned int GPU_MHZ   =               1000000;
++
++int  gpu_power_state;
++static int bPoweroff;
++static atomic_t clk_active;
++
++#ifdef CONFIG_EXYNOS_BUSFREQ_OPP
++static struct pm_qos_request mali_pm_qos_busfreq;
++#endif
++
++#ifdef CONFIG_ARM_EXYNOS_CPUFREQ
++static struct pm_qos_request mali_pm_qos_cpufreq;
++static atomic_t mali_cur_cpufreq = ATOMIC_INIT(0);
++#endif
++
++#ifdef CONFIG_REGULATOR
++struct regulator *g3d_regulator = NULL;
++#endif
++
++mali_io_address clk_register_map = 0;
++
++/* DVFS */
++unsigned int mali_dvfs_utilization = 255;
++static int mali_gpu_clk_on;
++
++static void mali_dvfs_work_handler(struct work_struct *w);
++
++static struct workqueue_struct *mali_dvfs_wq = 0;
++
++extern mali_io_address clk_register_map;
++
++_mali_osk_lock_t *mali_dvfs_lock = 0;
++
++int mali_runtime_resumed = -1;
++
++static DECLARE_WORK(mali_dvfs_work, mali_dvfs_work_handler);
++
++
++/* export GPU frequency as a read-only parameter so that it can be read in /sys */
++module_param(mali_gpu_clk, int, S_IRUSR | S_IRGRP | S_IROTH);
++MODULE_PARM_DESC(mali_gpu_clk, "GPU frequency in MHz");
++
++/*
++ * The CPU frequency lock is used to guarantee CPU minimum QoS at maximum GPU
++ * clocks. So when GPU clock is 440MHz, CPU QoS is set to minimum 1.2GHz,
++ * and when GPU clock is 533MHz, CPU QoS is set to minimum 1.4GHz.
++ * The other cases, CPU QoS is set to 0.
++ */
++#ifdef CONFIG_ARM_EXYNOS_CPUFREQ
++int cpufreq_lock_by_mali(int freq)
++{
++      if (freq < 0)
++              return _MALI_OSK_ERR_INVALID_ARGS;
++
++      if (atomic_read(&mali_cur_cpufreq) != freq) {
++              pm_qos_update_request(&mali_pm_qos_cpufreq, freq * 1000);
++              atomic_set(&mali_cur_cpufreq, freq);
++      }
++
++      return _MALI_OSK_ERR_OK;
++}
++
++void cpufreq_unlock_by_mali(void)
++{
++      if (atomic_read(&mali_cur_cpufreq) > 0) {
++              pm_qos_update_request(&mali_pm_qos_cpufreq, 0);
++              atomic_set(&mali_cur_cpufreq, 0);
++      }
++}
++#endif
++
++#ifdef CONFIG_REGULATOR
++void mali_regulator_disable(void)
++{
++      if(IS_ERR_OR_NULL(g3d_regulator))
++      {
++              MALI_DEBUG_PRINT(1, ("error on mali_regulator_disable : g3d_regulator is null\n"));
++              return;
++      }
++      regulator_disable(g3d_regulator);
++}
++
++void mali_regulator_enable(void)
++{
++      if(IS_ERR_OR_NULL(g3d_regulator))
++      {
++              MALI_DEBUG_PRINT(1, ("error on mali_regulator_enable : g3d_regulator is null\n"));
++              return;
++      }
++      regulator_enable(g3d_regulator);
++}
++
++void mali_regulator_set_voltage(int min_uV, int max_uV)
++{
++      _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
++      if(IS_ERR_OR_NULL(g3d_regulator))
++      {
++              MALI_DEBUG_PRINT(1, ("error on mali_regulator_set_voltage : g3d_regulator is null\n"));
++              return;
++      }
++      MALI_DEBUG_PRINT(3, ("= regulator_set_voltage: %d, %d \n",min_uV, max_uV));
++      regulator_set_voltage(g3d_regulator, min_uV, max_uV);
++      mali_gpu_vol = regulator_get_voltage(g3d_regulator);
++      MALI_DEBUG_PRINT(1, ("Mali voltage: %d\n", mali_gpu_vol));
++      _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
++}
++#endif
++
++unsigned long mali_clk_get_rate(void)
++{
++      return clk_get_rate(mali_clock);
++}
++
++
++static unsigned int get_mali_dvfs_status(void)
++{
++      return maliDvfsStatus.currentStep;
++}
++
++mali_bool mali_clk_get(void)
++{
++      if (bis_vpll)
++      {
++              if (ext_xtal_clock == NULL)
++              {
++                      ext_xtal_clock = clk_get(NULL,EXTXTALCLK_NAME);
++                      if (IS_ERR(ext_xtal_clock)) {
++                              MALI_PRINT( ("MALI Error : failed to get source ext_xtal_clock\n"));
++                              return MALI_FALSE;
++                      }
++              }
++
++              if (vpll_src_clock == NULL)
++              {
++                      vpll_src_clock = clk_get(NULL,VPLLSRCCLK_NAME);
++                      if (IS_ERR(vpll_src_clock)) {
++                              MALI_PRINT( ("MALI Error : failed to get source vpll_src_clock\n"));
++                              return MALI_FALSE;
++                      }
++              }
++
++              if (fout_vpll_clock == NULL)
++              {
++                      fout_vpll_clock = clk_get(NULL,FOUTVPLLCLK_NAME);
++                      if (IS_ERR(fout_vpll_clock)) {
++                              MALI_PRINT( ("MALI Error : failed to get source fout_vpll_clock\n"));
++                              return MALI_FALSE;
++                      }
++              }
++
++              if (sclk_vpll_clock == NULL)
++              {
++                      sclk_vpll_clock = clk_get(NULL,SCLVPLLCLK_NAME);
++                      if (IS_ERR(sclk_vpll_clock)) {
++                              MALI_PRINT( ("MALI Error : failed to get source sclk_vpll_clock\n"));
++                              return MALI_FALSE;
++                      }
++              }
++
++              if (mali_parent_clock == NULL)
++              {
++                      mali_parent_clock = clk_get(NULL, GPUMOUT1CLK_NAME);
++
++                      if (IS_ERR(mali_parent_clock)) {
++                              MALI_PRINT( ( "MALI Error : failed to get source mali parent clock\n"));
++                              return MALI_FALSE;
++                      }
++              }
++      }
++      else /* mpll */
++      {
++              if (mpll_clock == NULL)
++              {
++                      mpll_clock = clk_get(NULL,MPLLCLK_NAME);
++
++                      if (IS_ERR(mpll_clock)) {
++                              MALI_PRINT( ("MALI Error : failed to get source mpll clock\n"));
++                              return MALI_FALSE;
++                      }
++              }
++
++              if (mali_parent_clock == NULL)
++              {
++                      mali_parent_clock = clk_get(NULL, GPUMOUT0CLK_NAME);
++
++                      if (IS_ERR(mali_parent_clock)) {
++                              MALI_PRINT( ( "MALI Error : failed to get source mali parent clock\n"));
++                              return MALI_FALSE;
++                      }
++              }
++      }
++
++      // mali clock get always.
++      if (mali_clock == NULL)
++      {
++              mali_clock = clk_get(NULL, GPUCLK_NAME);
++
++              if (IS_ERR(mali_clock)) {
++                      MALI_PRINT( ("MALI Error : failed to get source mali clock\n"));
++                      return MALI_FALSE;
++              }
++      }
++
++      return MALI_TRUE;
++}
++
++void mali_clk_put(mali_bool binc_mali_clock)
++{
++      if (mali_parent_clock)
++      {
++              clk_put(mali_parent_clock);
++              mali_parent_clock = NULL;
++      }
++
++      if (mpll_clock)
++      {
++              clk_put(mpll_clock);
++              mpll_clock = NULL;
++      }
++
++      if (sclk_vpll_clock)
++      {
++              clk_put(sclk_vpll_clock);
++              sclk_vpll_clock = NULL;
++      }
++
++      if (binc_mali_clock && fout_vpll_clock)
++      {
++              clk_put(fout_vpll_clock);
++              fout_vpll_clock = NULL;
++      }
++
++      if (vpll_src_clock)
++      {
++              clk_put(vpll_src_clock);
++              vpll_src_clock = NULL;
++      }
++
++      if (ext_xtal_clock)
++      {
++              clk_put(ext_xtal_clock);
++              ext_xtal_clock = NULL;
++      }
++
++      if (binc_mali_clock && mali_clock)
++      {
++              clk_put(mali_clock);
++              mali_clock = NULL;
++      }
++}
++
++void mali_clk_set_rate(unsigned int clk, unsigned int mhz)
++{
++      int err;
++      unsigned long rate = (unsigned long)clk * (unsigned long)mhz;
++
++      _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
++      MALI_DEBUG_PRINT(3, ("Mali platform: Setting frequency to %d mhz\n", clk));
++
++      if (mali_clk_get() == MALI_FALSE)
++              return;
++
++      if (bis_vpll)
++      {
++              clk_set_rate(fout_vpll_clock, (unsigned int)clk * GPU_MHZ);
++              clk_set_parent(vpll_src_clock, ext_xtal_clock);
++              clk_set_parent(sclk_vpll_clock, fout_vpll_clock);
++
++              clk_set_parent(mali_parent_clock, sclk_vpll_clock);
++              clk_set_parent(mali_clock, mali_parent_clock);
++      }
++      else
++      {
++              clk_set_parent(mali_parent_clock, mpll_clock);
++              clk_set_parent(mali_clock, mali_parent_clock);
++      }
++
++      if (!atomic_read(&clk_active)) {
++              if (clk_enable(mali_clock) < 0)
++                      return;
++              atomic_set(&clk_active, 1);
++      }
++
++      err = clk_set_rate(mali_clock, rate);
++      if (err) MALI_PRINT_ERROR(("Failed to set Mali clock: %d\n", err));
++
++      rate = mali_clk_get_rate();
++
++      MALI_DEBUG_PRINT(3, ("Mali frequency %d\n", rate / mhz));
++      GPU_MHZ = mhz;
++      mali_gpu_clk = (int)(rate / mhz);
++
++      mali_clk_put(MALI_FALSE);
++
++      _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
++}
++
++int get_mali_dvfs_control_status(void)
++{
++      return mali_dvfs_control;
++}
++
++mali_bool set_mali_dvfs_current_step(unsigned int step)
++{
++      _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
++      maliDvfsStatus.currentStep = step % MALI_DVFS_STEPS;
++      if (step >= MALI_DVFS_STEPS)
++              mali_runtime_resumed = maliDvfsStatus.currentStep;
++
++      _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
++      return MALI_TRUE;
++}
++
++
++static mali_bool set_mali_dvfs_status(u32 step,mali_bool boostup)
++{
++      u32 validatedStep=step;
++#if MALI_DVFS_CLK_DEBUG
++      unsigned int *pRegMaliClkDiv;
++      unsigned int *pRegMaliMpll;
++#endif
++      int err;
++
++      if(boostup)     {
++#ifdef CONFIG_REGULATOR
++              /*change the voltage*/
++              mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol);
++#endif
++              /*change the clock*/
++              mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq);
++      } else {
++              /*change the clock*/
++              mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq);
++#ifdef CONFIG_REGULATOR
++              /*change the voltage*/
++              mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol);
++#endif
++      }
++
++#if defined(CONFIG_MALI400_PROFILING)
++      _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|
++                      MALI_PROFILING_EVENT_CHANNEL_GPU|
++                      MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
++                      mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0);
++#endif
++      mali_clk_put(MALI_FALSE);
++
++#if MALI_DVFS_CLK_DEBUG
++      pRegMaliClkDiv = ioremap(0x1003c52c,32);
++      pRegMaliMpll = ioremap(0x1003c22c,32);
++      MALI_PRINT( ("Mali MPLL reg:%d, CLK DIV: %d \n",*pRegMaliMpll, *pRegMaliClkDiv));
++#endif
++
++      set_mali_dvfs_current_step(validatedStep);
++      /*for future use*/
++      maliDvfsStatus.pCurrentDvfs = &mali_dvfs[validatedStep];
++
++#ifdef CONFIG_ARM_EXYNOS_CPUFREQ
++      /* lock/unlock CPU freq by Mali */
++      if (mali_dvfs[step].clock >= 530)
++              err = cpufreq_lock_by_mali(1400);
++      else if (mali_dvfs[step].clock >= 440)
++              err = cpufreq_lock_by_mali(1200);
++      else
++              cpufreq_unlock_by_mali();
++#endif
++
++
++      return MALI_TRUE;
++}
++
++static void mali_platform_wating(u32 msec)
++{
++      /*
++      * sample wating
++      * change this in the future with proper check routine.
++      */
++      unsigned int read_val;
++      while(1)
++      {
++#ifdef CONFIG_SLP_MALI_DBG
++              read_val = _mali_osk_mem_ioread32_cpu(clk_register_map, 0x00);
++#else
++              read_val = _mali_osk_mem_ioread32(clk_register_map, 0x00);
++#endif
++              if ((read_val & 0x8000)==0x0000) break;
++
++              _mali_osk_time_ubusydelay(100); /* 1000 -> 100 : 20101218 */
++      }
++      /* _mali_osk_time_ubusydelay(msec*1000);*/
++}
++
++static mali_bool change_mali_dvfs_status(u32 step, mali_bool boostup )
++{
++      MALI_DEBUG_PRINT(4, ("> change_mali_dvfs_status: %d, %d \n",step, boostup));
++
++      if(!set_mali_dvfs_status(step, boostup))
++      {
++              MALI_DEBUG_PRINT(1, ("error on set_mali_dvfs_status: %d, %d \n",step, boostup));
++              return MALI_FALSE;
++      }
++
++      /*wait until clock and voltage is stablized*/
++      mali_platform_wating(MALI_DVFS_WATING); /*msec*/
++
++      return MALI_TRUE;
++}
++
++#ifdef EXYNOS4_ASV_ENABLED
++extern unsigned int exynos_result_of_asv;
++
++static mali_bool mali_dvfs_table_update(void)
++{
++      unsigned int i;
++      unsigned int step_num = MALI_DVFS_STEPS;
++
++      MALI_PRINT(("::P::exynos_result_of_asv : %d\n", exynos_result_of_asv));
++      for (i = 0; i < step_num; i++) {
++              mali_dvfs[i].vol = asv_3d_volt_9_table_for_prime[i][exynos_result_of_asv];
++              MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol));
++      }
++      return MALI_TRUE;
++}
++#endif
++
++
++static unsigned int decideNextStatus(unsigned int utilization)
++{
++      static unsigned int level = 0;
++      int iStepCount = 0;
++      if (mali_runtime_resumed >= 0) {
++              level = mali_runtime_resumed;
++              mali_runtime_resumed = -1;
++      }
++
++      if (mali_dvfs_control == 0 && level == get_mali_dvfs_status()) {
++              if (utilization > (int)(255 * mali_dvfs[maliDvfsStatus.currentStep].upthreshold / 100) &&
++                              level < MALI_DVFS_STEPS - 1) {
++                      level++;
++              }
++              else if (utilization < (int)(255 * mali_dvfs[maliDvfsStatus.currentStep].downthreshold / 100) &&
++                              level > 0) {
++                      level--;
++              }
++      } else {
++              for (iStepCount = MALI_DVFS_STEPS-1; iStepCount >= 0; iStepCount--) {
++                      if ( mali_dvfs_control >= mali_dvfs[iStepCount].clock ) {
++                              maliDvfsStatus.currentStep = iStepCount;
++                              level = iStepCount;
++                              break;
++                      }
++              }
++      }
++
++      return level;
++}
++
++static mali_bool mali_dvfs_status(unsigned int utilization)
++{
++      unsigned int nextStatus = 0;
++      unsigned int curStatus = 0;
++      mali_bool boostup = MALI_FALSE;
++#ifdef EXYNOS4_ASV_ENABLED
++      static mali_bool asv_applied = MALI_FALSE;
++#endif
++
++#ifdef EXYNOS4_ASV_ENABLED
++      if (asv_applied == MALI_FALSE) {
++              mali_dvfs_table_update();
++              change_mali_dvfs_status(1, 0);
++              asv_applied = MALI_TRUE;
++
++              return MALI_TRUE;
++      }
++#endif
++
++      MALI_DEBUG_PRINT(4, ("> mali_dvfs_status: %d \n",utilization));
++
++      /*decide next step*/
++      curStatus = get_mali_dvfs_status();
++      nextStatus = decideNextStatus(utilization);
++
++      MALI_DEBUG_PRINT(4, ("= curStatus %d, nextStatus %d, maliDvfsStatus.currentStep %d \n", curStatus, nextStatus, maliDvfsStatus.currentStep));
++      /*if next status is same with current status, don't change anything*/
++      if(curStatus!=nextStatus)
++      {
++              /*check if boost up or not*/
++              if(nextStatus > maliDvfsStatus.currentStep) boostup = 1;
++
++              /*change mali dvfs status*/
++              if(!change_mali_dvfs_status(nextStatus,boostup))
++              {
++                      MALI_DEBUG_PRINT(1, ("error on change_mali_dvfs_status \n"));
++                      return MALI_FALSE;
++              }
++      }
++      return MALI_TRUE;
++}
++
++
++int mali_dvfs_is_running(void)
++{
++      return bMaliDvfsRun;
++}
++
++
++static void mali_dvfs_work_handler(struct work_struct *w)
++{
++      bMaliDvfsRun=1;
++
++      MALI_DEBUG_PRINT(3, ("=== mali_dvfs_work_handler\n"));
++
++      if(!mali_dvfs_status(mali_dvfs_utilization))
++      MALI_DEBUG_PRINT(1,( "error on mali dvfs status in mali_dvfs_work_handler"));
++
++      bMaliDvfsRun=0;
++}
++
++
++mali_bool init_mali_dvfs_status(void)
++{
++      /*
++      * default status
++      * add here with the right function to get initilization value.
++      */
++
++      if (!mali_dvfs_wq)
++      {
++              mali_dvfs_wq = create_singlethread_workqueue("mali_dvfs");
++      }
++
++      /*add a error handling here*/
++      maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP;
++
++#ifdef CONFIG_ARM_EXYNOS_CPUFREQ
++      pm_qos_add_request(&mali_pm_qos_cpufreq, PM_QOS_CPU_FREQ_MIN, 0);
++#endif
++
++      return MALI_TRUE;
++}
++
++void deinit_mali_dvfs_status(void)
++{
++      if (mali_dvfs_wq)
++      {
++              destroy_workqueue(mali_dvfs_wq);
++              mali_dvfs_wq = NULL;
++      }
++
++#ifdef CONFIG_ARM_EXYNOS_CPUFREQ
++      pm_qos_remove_request(&mali_pm_qos_cpufreq);
++#endif
++}
++
++mali_bool mali_dvfs_handler(unsigned int utilization)
++{
++      mali_dvfs_utilization = utilization;
++      queue_work_on(0, mali_dvfs_wq, &mali_dvfs_work);
++
++      return MALI_TRUE;
++}
++
++static mali_bool init_mali_clock(void)
++{
++      mali_bool ret = MALI_TRUE;
++      gpu_power_state = 0;
++      bPoweroff = 1;
++
++      if (mali_clock != 0)
++              return ret; /* already initialized */
++
++      mali_dvfs_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE
++                      | _MALI_OSK_LOCKFLAG_ONELOCK, 0, 0);
++      if (mali_dvfs_lock == NULL)
++              return _MALI_OSK_ERR_FAULT;
++
++
++
++      if (!mali_clk_get())
++      {
++              MALI_PRINT(("Error: Failed to get Mali clock\n"));
++              goto err_clk;
++      }
++
++      mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ);
++
++      MALI_PRINT(("init_mali_clock mali_clock %x\n", mali_clock));
++
++#ifdef CONFIG_REGULATOR
++      g3d_regulator = regulator_get(NULL, "vdd_g3d");
++
++      if (IS_ERR(g3d_regulator))
++      {
++              MALI_PRINT( ("MALI Error : failed to get vdd_g3d\n"));
++              ret = MALI_FALSE;
++              goto err_regulator;
++      }
++
++      regulator_enable(g3d_regulator);
++      mali_regulator_set_voltage(mali_gpu_vol, mali_gpu_vol);
++#endif
++
++#if defined(CONFIG_MALI400_PROFILING)
++      _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|
++                      MALI_PROFILING_EVENT_CHANNEL_GPU|
++                      MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
++                      mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0);
++#endif
++
++      mali_clk_put(MALI_FALSE);
++
++      mali_gpu_clk_on = mali_gpu_clk;
++
++      return MALI_TRUE;
++
++#ifdef CONFIG_REGULATOR
++err_regulator:
++      regulator_put(g3d_regulator);
++#endif
++err_clk:
++      mali_clk_put(MALI_TRUE);
++
++      return ret;
++}
++
++static mali_bool deinit_mali_clock(void)
++{
++      if (mali_clock == 0)
++              return MALI_TRUE;
++
++#ifdef CONFIG_REGULATOR
++      if (g3d_regulator)
++      {
++              regulator_put(g3d_regulator);
++              g3d_regulator = NULL;
++      }
++#endif
++
++      mali_clk_put(MALI_TRUE);
++
++      return MALI_TRUE;
++}
++
++
++static _mali_osk_errcode_t enable_mali_clocks(void)
++{
++      int err;
++
++      if (!atomic_read(&clk_active)) {
++              err = clk_enable(mali_clock);
++              MALI_DEBUG_PRINT(3,("enable_mali_clocks mali_clock %p error %d \n", mali_clock, err));
++              atomic_set(&clk_active, 1);
++      }
++
++      mali_gpu_clk = mali_gpu_clk_on;
++
++      /* set clock rate */
++#ifdef CONFIG_MALI_DVFS
++      if (get_mali_dvfs_control_status() != 0 || mali_gpu_clk >= mali_runtime_resume.clk) {
++              mali_clk_set_rate(mali_gpu_clk, GPU_MHZ);
++      } else {
++#ifdef CONFIG_REGULATOR
++              mali_regulator_set_voltage(mali_runtime_resume.vol, mali_runtime_resume.vol);
++#endif
++              mali_clk_set_rate(mali_runtime_resume.clk, GPU_MHZ);
++              set_mali_dvfs_current_step(mali_runtime_resume.step);
++      }
++#else
++      mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ);
++
++      maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP;
++#endif
++
++#ifdef CONFIG_ARM_EXYNOS_CPUFREQ
++      /* lock/unlock CPU freq by Mali */
++      if (mali_gpu_clk >= 530)
++              err = cpufreq_lock_by_mali(1400);
++      else if (mali_gpu_clk >= 440)
++              err = cpufreq_lock_by_mali(1200);
++      else
++              cpufreq_unlock_by_mali();
++#endif
++
++      MALI_SUCCESS;
++}
++
++static _mali_osk_errcode_t disable_mali_clocks(void)
++{
++      if (atomic_read(&clk_active)) {
++              clk_disable(mali_clock);
++              atomic_set(&clk_active, 0);
++      }
++
++      MALI_DEBUG_PRINT(3,("disable_mali_clocks mali_clock %p \n", mali_clock));
++
++#ifdef CONFIG_ARM_EXYNOS_CPUFREQ
++      cpufreq_unlock_by_mali();
++#endif
++
++      /* to reflect the gpu clock off state */
++      mali_gpu_clk_on = mali_gpu_clk;
++      mali_gpu_clk = 0;
++
++      MALI_SUCCESS;
++}
++
++
++_mali_osk_errcode_t g3d_power_domain_control(int bpower_on)
++{
++      if (bpower_on)
++      {
++              void __iomem *status;
++              u32 timeout;
++              __raw_writel(EXYNOS_INT_LOCAL_PWR_EN, S5P_G3D_CONFIGURATION);
++              status = S5P_G3D_STATUS;
++
++              timeout = 10;
++              while ((__raw_readl(status) & EXYNOS_INT_LOCAL_PWR_EN)
++                      != EXYNOS_INT_LOCAL_PWR_EN) {
++                      if (timeout == 0) {
++                              MALI_PRINTF(("Power domain  enable failed.\n"));
++                              return -ETIMEDOUT;
++                      }
++                      timeout--;
++                      _mali_osk_time_ubusydelay(100);
++              }
++      }
++      else
++      {
++              void __iomem *status;
++              u32 timeout;
++              __raw_writel(0, S5P_G3D_CONFIGURATION);
++
++              status = S5P_G3D_STATUS;
++              /* Wait max 1ms */
++              timeout = 10;
++              while (__raw_readl(status) & EXYNOS_INT_LOCAL_PWR_EN)
++              {
++                      if (timeout == 0) {
++                              MALI_PRINTF(("Power domain  disable failed.\n" ));
++                              return -ETIMEDOUT;
++                      }
++                      timeout--;
++                      _mali_osk_time_ubusydelay( 100);
++              }
++      }
++
++      MALI_SUCCESS;
++}
++
++_mali_osk_errcode_t mali_platform_init(void)
++{
++      MALI_CHECK(init_mali_clock(), _MALI_OSK_ERR_FAULT);
++#ifdef CONFIG_MALI_DVFS
++      if (!clk_register_map) clk_register_map = _mali_osk_mem_mapioregion( CLK_DIV_STAT_G3D, 0x20, CLK_DESC );
++      if(!init_mali_dvfs_status())
++              MALI_DEBUG_PRINT(1, ("mali_platform_init failed\n"));
++#endif
++
++#ifdef CONFIG_EXYNOS_BUSFREQ_OPP
++      pm_qos_add_request(&mali_pm_qos_busfreq, PM_QOS_BUS_THROUGHPUT, 0);
++#endif
++
++      mali_platform_power_mode_change(MALI_POWER_MODE_ON);
++
++      MALI_SUCCESS;
++}
++
++_mali_osk_errcode_t mali_platform_deinit(void)
++{
++
++      mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP);
++      deinit_mali_clock();
++
++#ifdef CONFIG_MALI_DVFS
++      deinit_mali_dvfs_status();
++      if (clk_register_map )
++      {
++              _mali_osk_mem_unmapioregion(CLK_DIV_STAT_G3D, 0x20, clk_register_map);
++              clk_register_map = NULL;
++      }
++#endif
++
++#ifdef CONFIG_EXYNOS_BUSFREQ_OPP
++      pm_qos_remove_request(&mali_pm_qos_busfreq);
++#endif
++
++      MALI_SUCCESS;
++}
++
++_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode)
++{
++      switch (power_mode)
++      {
++              case MALI_POWER_MODE_ON:
++                      MALI_DEBUG_PRINT(3, ("Mali platform: Got MALI_POWER_MODE_ON event, %s\n",
++                                           bPoweroff ? "powering on" : "already on"));
++                      if (bPoweroff == 1)
++                      {
++#if !defined(CONFIG_PM_RUNTIME)
++                              g3d_power_domain_control(1);
++#endif
++                              MALI_DEBUG_PRINT(4,("enable clock \n"));
++                              enable_mali_clocks();
++#if defined(CONFIG_MALI400_PROFILING)
++                              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
++                                              MALI_PROFILING_EVENT_CHANNEL_GPU |
++                                              MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
++                                              mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0);
++
++#endif
++                              bPoweroff=0;
++                      }
++                      break;
++              case MALI_POWER_MODE_LIGHT_SLEEP:
++              case MALI_POWER_MODE_DEEP_SLEEP:
++                      MALI_DEBUG_PRINT(3, ("Mali platform: Got %s event, %s\n", power_mode ==
++                                              MALI_POWER_MODE_LIGHT_SLEEP ?  "MALI_POWER_MODE_LIGHT_SLEEP" :
++                                              "MALI_POWER_MODE_DEEP_SLEEP", bPoweroff ? "already off" : "powering off"));
++                      if (bPoweroff == 0)
++                      {
++                              disable_mali_clocks();
++#if defined(CONFIG_MALI400_PROFILING)
++                              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
++                                              MALI_PROFILING_EVENT_CHANNEL_GPU |
++                                              MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
++                                              0, 0, 0, 0, 0);
++#endif
++
++#if !defined(CONFIG_PM_RUNTIME)
++                              g3d_power_domain_control(0);
++#endif
++                              bPoweroff=1;
++                      }
++
++                      break;
++      }
++      MALI_SUCCESS;
++}
++
++void mali_gpu_utilization_handler(unsigned int utilization)
++{
++      if (bPoweroff==0)
++      {
++#ifdef CONFIG_MALI_DVFS
++              if(!mali_dvfs_handler(utilization))
++                      MALI_DEBUG_PRINT(1,( "error on mali dvfs status in utilization\n"));
++#endif
++      }
++}
+diff --git a/drivers/gpu/arm/mali400/mali/platform/redwood/exynos4_pmm.h b/drivers/gpu/arm/mali400/mali/platform/redwood/exynos4_pmm.h
+new file mode 100644
+index 0000000..ef98c9c
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/platform/redwood/exynos4_pmm.h
+@@ -0,0 +1,96 @@
++/* drivers/gpu/mali400/mali/platform/pegasus-m400/exynos4_pmm.h
++ *
++ * Copyright 2011 by S.LSI. Samsung Electronics Inc.
++ * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea
++ *
++ * Samsung SoC Mali400 DVFS driver
++ *
++ * 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.
++ */
++
++/**
++ * @file exynos4_pmm.h
++ * Platform specific Mali driver functions for the exynos 4XXX based platforms
++ */
++
++#ifndef __EXYNOS4_PMM_H__
++#define __EXYNOS4_PMM_H__
++
++#include "mali_osk.h"
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++/** @brief description of power change reasons
++ */
++typedef enum mali_power_mode_tag
++{
++      MALI_POWER_MODE_ON,
++      MALI_POWER_MODE_LIGHT_SLEEP,
++      MALI_POWER_MODE_DEEP_SLEEP,
++} mali_power_mode;
++
++/** @brief Platform specific setup and initialisation of MALI
++ *
++ * This is called from the entrypoint of the driver to initialize the platform
++ *
++ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
++ */
++_mali_osk_errcode_t mali_platform_init(void);
++
++/** @brief Platform specific deinitialisation of MALI
++ *
++ * This is called on the exit of the driver to terminate the platform
++ *
++ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
++ */
++_mali_osk_errcode_t mali_platform_deinit(void);
++
++/** @brief Platform specific powerdown sequence of MALI
++ *
++ * Call as part of platform init if there is no PMM support, else the
++ * PMM will call it.
++ * There are three power modes defined:
++ *  1) MALI_POWER_MODE_ON
++ *  2) MALI_POWER_MODE_LIGHT_SLEEP
++ *  3) MALI_POWER_MODE_DEEP_SLEEP
++ * MALI power management module transitions to MALI_POWER_MODE_LIGHT_SLEEP mode when MALI is idle
++ * for idle timer (software timer defined in mali_pmm_policy_jobcontrol.h) duration, MALI transitions
++ * to MALI_POWER_MODE_LIGHT_SLEEP mode during timeout if there are no more jobs queued.
++ * MALI power management module transitions to MALI_POWER_MODE_DEEP_SLEEP mode when OS does system power
++ * off.
++ * Customer has to add power down code when MALI transitions to MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP
++ * mode.
++ * MALI_POWER_MODE_ON mode is entered when the MALI is to powered up. Some customers want to control voltage regulators during
++ * the whole system powers on/off. Customer can track in this function whether the MALI is powered up from
++ * MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP mode and manage the voltage regulators as well.
++ * @param power_mode defines the power modes
++ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
++ */
++_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode);
++
++
++/** @brief Platform specific handling of GPU utilization data
++ *
++ * When GPU utilization data is enabled, this function will be
++ * periodically called.
++ *
++ * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization.
++ */
++void mali_gpu_utilization_handler(unsigned int utilization);
++
++_mali_osk_errcode_t g3d_power_domain_control(int bpower_on);
++
++#ifdef CONFIG_REGULATOR
++void mali_regulator_disable(void);
++void mali_regulator_enable(void);
++void mali_regulator_set_voltage(int min_uV, int max_uV);
++#endif
++
++#ifdef __cplusplus
++}
++#endif
++#endif
+diff --git a/drivers/gpu/arm/mali400/mali/regs/mali_200_regs.h b/drivers/gpu/arm/mali400/mali/regs/mali_200_regs.h
+new file mode 100644
+index 0000000..1a4d8b8
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/regs/mali_200_regs.h
+@@ -0,0 +1,128 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef _MALI200_REGS_H_
++#define _MALI200_REGS_H_
++
++/**
++ *  Enum for management register addresses.
++ */
++enum mali200_mgmt_reg
++{
++      MALI200_REG_ADDR_MGMT_VERSION                              = 0x1000,
++      MALI200_REG_ADDR_MGMT_CURRENT_REND_LIST_ADDR               = 0x1004,
++      MALI200_REG_ADDR_MGMT_STATUS                               = 0x1008,
++      MALI200_REG_ADDR_MGMT_CTRL_MGMT                            = 0x100c,
++
++      MALI200_REG_ADDR_MGMT_INT_RAWSTAT                          = 0x1020,
++      MALI200_REG_ADDR_MGMT_INT_CLEAR                            = 0x1024,
++      MALI200_REG_ADDR_MGMT_INT_MASK                             = 0x1028,
++      MALI200_REG_ADDR_MGMT_INT_STATUS                           = 0x102c,
++
++      MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW                   = 0x1044,
++
++      MALI200_REG_ADDR_MGMT_BUS_ERROR_STATUS                     = 0x1050,
++
++      MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE                    = 0x1080,
++      MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC                       = 0x1084,
++      MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE                     = 0x108c,
++
++      MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE                    = 0x10a0,
++      MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC                       = 0x10a4,
++      MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE                     = 0x10ac,
++
++      MALI200_REG_SIZEOF_REGISTER_BANK                           = 0x10f0
++
++};
++
++#define MALI200_REG_VAL_PERF_CNT_ENABLE 1
++
++enum mali200_mgmt_ctrl_mgmt {
++      MALI200_REG_VAL_CTRL_MGMT_STOP_BUS         = (1<<0),
++      MALI200_REG_VAL_CTRL_MGMT_FLUSH_CACHES     = (1<<3),
++      MALI200_REG_VAL_CTRL_MGMT_FORCE_RESET      = (1<<5),
++      MALI200_REG_VAL_CTRL_MGMT_START_RENDERING  = (1<<6),
++      MALI400PP_REG_VAL_CTRL_MGMT_SOFT_RESET     = (1<<7), /* Only valid for Mali-300 and later */
++};
++
++enum mali200_mgmt_irq {
++      MALI200_REG_VAL_IRQ_END_OF_FRAME          = (1<<0),
++      MALI200_REG_VAL_IRQ_END_OF_TILE           = (1<<1),
++      MALI200_REG_VAL_IRQ_HANG                  = (1<<2),
++      MALI200_REG_VAL_IRQ_FORCE_HANG            = (1<<3),
++      MALI200_REG_VAL_IRQ_BUS_ERROR             = (1<<4),
++      MALI200_REG_VAL_IRQ_BUS_STOP              = (1<<5),
++      MALI200_REG_VAL_IRQ_CNT_0_LIMIT           = (1<<6),
++      MALI200_REG_VAL_IRQ_CNT_1_LIMIT           = (1<<7),
++      MALI200_REG_VAL_IRQ_WRITE_BOUNDARY_ERROR  = (1<<8),
++      MALI400PP_REG_VAL_IRQ_INVALID_PLIST_COMMAND = (1<<9),
++      MALI400PP_REG_VAL_IRQ_CALL_STACK_UNDERFLOW  = (1<<10),
++      MALI400PP_REG_VAL_IRQ_CALL_STACK_OVERFLOW   = (1<<11),
++      MALI400PP_REG_VAL_IRQ_RESET_COMPLETED       = (1<<12),
++};
++
++#define MALI200_REG_VAL_IRQ_MASK_ALL  ((enum mali200_mgmt_irq) (\
++    MALI200_REG_VAL_IRQ_END_OF_FRAME                           |\
++    MALI200_REG_VAL_IRQ_END_OF_TILE                            |\
++    MALI200_REG_VAL_IRQ_HANG                                   |\
++    MALI200_REG_VAL_IRQ_FORCE_HANG                             |\
++    MALI200_REG_VAL_IRQ_BUS_ERROR                              |\
++    MALI200_REG_VAL_IRQ_BUS_STOP                               |\
++    MALI200_REG_VAL_IRQ_CNT_0_LIMIT                            |\
++    MALI200_REG_VAL_IRQ_CNT_1_LIMIT                            |\
++    MALI200_REG_VAL_IRQ_WRITE_BOUNDARY_ERROR                   |\
++    MALI400PP_REG_VAL_IRQ_INVALID_PLIST_COMMAND                  |\
++    MALI400PP_REG_VAL_IRQ_CALL_STACK_UNDERFLOW                   |\
++    MALI400PP_REG_VAL_IRQ_CALL_STACK_OVERFLOW                    |\
++    MALI400PP_REG_VAL_IRQ_RESET_COMPLETED))
++
++#define MALI200_REG_VAL_IRQ_MASK_USED ((enum mali200_mgmt_irq) (\
++    MALI200_REG_VAL_IRQ_END_OF_FRAME                           |\
++    MALI200_REG_VAL_IRQ_FORCE_HANG                             |\
++    MALI200_REG_VAL_IRQ_BUS_ERROR                              |\
++    MALI200_REG_VAL_IRQ_WRITE_BOUNDARY_ERROR                   |\
++    MALI400PP_REG_VAL_IRQ_INVALID_PLIST_COMMAND                  |\
++    MALI400PP_REG_VAL_IRQ_CALL_STACK_UNDERFLOW                   |\
++    MALI400PP_REG_VAL_IRQ_CALL_STACK_OVERFLOW))
++
++#define MALI200_REG_VAL_IRQ_MASK_NONE ((enum mali200_mgmt_irq)(0))
++
++enum mali200_mgmt_status {
++      MALI200_REG_VAL_STATUS_RENDERING_ACTIVE     = (1<<0),
++      MALI200_REG_VAL_STATUS_BUS_STOPPED          = (1<<4),
++};
++
++enum mali200_render_unit
++{
++      MALI200_REG_ADDR_FRAME = 0x0000,
++      MALI200_REG_ADDR_RSW   = 0x0004,
++      MALI200_REG_ADDR_STACK = 0x0030,
++      MALI200_REG_ADDR_STACK_SIZE = 0x0034,
++      MALI200_REG_ADDR_ORIGIN_OFFSET_X  = 0x0040
++};
++
++enum mali200_wb_unit {
++    MALI200_REG_ADDR_WB0 = 0x0100,
++    MALI200_REG_ADDR_WB1 = 0x0200,
++    MALI200_REG_ADDR_WB2 = 0x0300
++};
++
++enum mali200_wb_unit_regs {
++      MALI200_REG_ADDR_WB_SOURCE_SELECT = 0x0000,
++};
++
++/* This should be in the top 16 bit of the version register of Mali PP */
++#define MALI200_PP_PRODUCT_ID 0xC807
++#define MALI300_PP_PRODUCT_ID 0xCE07
++#define MALI400_PP_PRODUCT_ID 0xCD07
++#define MALI450_PP_PRODUCT_ID 0xCF07
++
++
++#endif /* _MALI200_REGS_H_ */
+diff --git a/drivers/gpu/arm/mali400/mali/regs/mali_gp_regs.h b/drivers/gpu/arm/mali400/mali/regs/mali_gp_regs.h
+new file mode 100644
+index 0000000..eedb228
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/regs/mali_gp_regs.h
+@@ -0,0 +1,173 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef _MALIGP2_CONROL_REGS_H_
++#define _MALIGP2_CONROL_REGS_H_
++
++/**
++ * These are the different geometry processor control registers.
++ * Their usage is to control and monitor the operation of the
++ * Vertex Shader and the Polygon List Builder in the geometry processor.
++ * Addresses are in 32-bit word relative sizes.
++ * @see [P0081] "Geometry Processor Data Structures" for details
++ */
++
++typedef enum {
++      MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR           = 0x00,
++      MALIGP2_REG_ADDR_MGMT_VSCL_END_ADDR             = 0x04,
++      MALIGP2_REG_ADDR_MGMT_PLBUCL_START_ADDR         = 0x08,
++      MALIGP2_REG_ADDR_MGMT_PLBUCL_END_ADDR           = 0x0c,
++      MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR     = 0x10,
++      MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR       = 0x14,
++      MALIGP2_REG_ADDR_MGMT_CMD                       = 0x20,
++      MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT               = 0x24,
++      MALIGP2_REG_ADDR_MGMT_INT_CLEAR                 = 0x28,
++      MALIGP2_REG_ADDR_MGMT_INT_MASK                  = 0x2C,
++      MALIGP2_REG_ADDR_MGMT_INT_STAT                  = 0x30,
++      MALIGP2_REG_ADDR_MGMT_WRITE_BOUND_LOW           = 0x34,
++      MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE         = 0x3C,
++      MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE         = 0x40,
++      MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC            = 0x44,
++      MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC            = 0x48,
++      MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE          = 0x4C,
++      MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE          = 0x50,
++      MALIGP2_REG_ADDR_MGMT_STATUS                    = 0x68,
++      MALIGP2_REG_ADDR_MGMT_VERSION                   = 0x6C,
++      MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR_READ      = 0x80,
++      MALIGP2_REG_ADDR_MGMT_PLBCL_START_ADDR_READ     = 0x84,
++      MALIGP2_CONTR_AXI_BUS_ERROR_STAT                = 0x94,
++      MALIGP2_REGISTER_ADDRESS_SPACE_SIZE             = 0x98,
++} maligp_reg_addr_mgmt_addr;
++
++#define MALIGP2_REG_VAL_PERF_CNT_ENABLE 1
++
++/**
++ * Commands to geometry processor.
++ *  @see MALIGP2_CTRL_REG_CMD
++ */
++typedef enum
++{
++      MALIGP2_REG_VAL_CMD_START_VS                    = (1<< 0),
++      MALIGP2_REG_VAL_CMD_START_PLBU                  = (1<< 1),
++      MALIGP2_REG_VAL_CMD_UPDATE_PLBU_ALLOC   = (1<< 4),
++      MALIGP2_REG_VAL_CMD_RESET                               = (1<< 5),
++      MALIGP2_REG_VAL_CMD_FORCE_HANG                  = (1<< 6),
++      MALIGP2_REG_VAL_CMD_STOP_BUS                    = (1<< 9),
++      MALI400GP_REG_VAL_CMD_SOFT_RESET                = (1<<10), /* only valid for Mali-300 and later */
++} mgp_contr_reg_val_cmd;
++
++
++/**  @defgroup MALIGP2_IRQ
++ * Interrupt status of geometry processor.
++ *  @see MALIGP2_CTRL_REG_INT_RAWSTAT, MALIGP2_REG_ADDR_MGMT_INT_CLEAR,
++ *       MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_ADDR_MGMT_INT_STAT
++ * @{
++ */
++#define MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST      (1 << 0)
++#define MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST    (1 << 1)
++#define MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM     (1 << 2)
++#define MALIGP2_REG_VAL_IRQ_VS_SEM_IRQ          (1 << 3)
++#define MALIGP2_REG_VAL_IRQ_PLBU_SEM_IRQ        (1 << 4)
++#define MALIGP2_REG_VAL_IRQ_HANG                (1 << 5)
++#define MALIGP2_REG_VAL_IRQ_FORCE_HANG          (1 << 6)
++#define MALIGP2_REG_VAL_IRQ_PERF_CNT_0_LIMIT    (1 << 7)
++#define MALIGP2_REG_VAL_IRQ_PERF_CNT_1_LIMIT    (1 << 8)
++#define MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR     (1 << 9)
++#define MALIGP2_REG_VAL_IRQ_SYNC_ERROR          (1 << 10)
++#define MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR       (1 << 11)
++#define MALI400GP_REG_VAL_IRQ_AXI_BUS_STOPPED     (1 << 12)
++#define MALI400GP_REG_VAL_IRQ_VS_INVALID_CMD      (1 << 13)
++#define MALI400GP_REG_VAL_IRQ_PLB_INVALID_CMD     (1 << 14)
++#define MALI400GP_REG_VAL_IRQ_RESET_COMPLETED     (1 << 19)
++#define MALI400GP_REG_VAL_IRQ_SEMAPHORE_UNDERFLOW (1 << 20)
++#define MALI400GP_REG_VAL_IRQ_SEMAPHORE_OVERFLOW  (1 << 21)
++#define MALI400GP_REG_VAL_IRQ_PTR_ARRAY_OUT_OF_BOUNDS  (1 << 22)
++
++/* Mask defining all IRQs in Mali GP */
++#define MALIGP2_REG_VAL_IRQ_MASK_ALL \
++      (\
++              MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST      | \
++              MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST    | \
++              MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM     | \
++              MALIGP2_REG_VAL_IRQ_VS_SEM_IRQ          | \
++              MALIGP2_REG_VAL_IRQ_PLBU_SEM_IRQ        | \
++              MALIGP2_REG_VAL_IRQ_HANG                | \
++              MALIGP2_REG_VAL_IRQ_FORCE_HANG          | \
++              MALIGP2_REG_VAL_IRQ_PERF_CNT_0_LIMIT    | \
++              MALIGP2_REG_VAL_IRQ_PERF_CNT_1_LIMIT    | \
++              MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR     | \
++              MALIGP2_REG_VAL_IRQ_SYNC_ERROR          | \
++              MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR       | \
++              MALI400GP_REG_VAL_IRQ_AXI_BUS_STOPPED     | \
++              MALI400GP_REG_VAL_IRQ_VS_INVALID_CMD      | \
++              MALI400GP_REG_VAL_IRQ_PLB_INVALID_CMD     | \
++              MALI400GP_REG_VAL_IRQ_RESET_COMPLETED     | \
++              MALI400GP_REG_VAL_IRQ_SEMAPHORE_UNDERFLOW | \
++              MALI400GP_REG_VAL_IRQ_SEMAPHORE_OVERFLOW  | \
++              MALI400GP_REG_VAL_IRQ_PTR_ARRAY_OUT_OF_BOUNDS)
++
++/* Mask defining the IRQs in Mali GP which we use */
++#define MALIGP2_REG_VAL_IRQ_MASK_USED \
++      (\
++              MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST      | \
++              MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST    | \
++              MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM     | \
++              MALIGP2_REG_VAL_IRQ_FORCE_HANG          | \
++              MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR     | \
++              MALIGP2_REG_VAL_IRQ_SYNC_ERROR          | \
++              MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR       | \
++              MALI400GP_REG_VAL_IRQ_VS_INVALID_CMD      | \
++              MALI400GP_REG_VAL_IRQ_PLB_INVALID_CMD     | \
++              MALI400GP_REG_VAL_IRQ_SEMAPHORE_UNDERFLOW | \
++              MALI400GP_REG_VAL_IRQ_SEMAPHORE_OVERFLOW  | \
++              MALI400GP_REG_VAL_IRQ_PTR_ARRAY_OUT_OF_BOUNDS)
++
++/* Mask defining non IRQs on MaliGP2*/
++#define MALIGP2_REG_VAL_IRQ_MASK_NONE 0
++
++/** }@ defgroup MALIGP2_IRQ*/
++
++/** @defgroup MALIGP2_STATUS
++ * The different Status values to the geometry processor.
++ *  @see MALIGP2_CTRL_REG_STATUS
++ * @{
++ */
++#define MALIGP2_REG_VAL_STATUS_VS_ACTIVE         0x0002
++#define MALIGP2_REG_VAL_STATUS_BUS_STOPPED       0x0004
++#define MALIGP2_REG_VAL_STATUS_PLBU_ACTIVE       0x0008
++#define MALIGP2_REG_VAL_STATUS_BUS_ERROR         0x0040
++#define MALIGP2_REG_VAL_STATUS_WRITE_BOUND_ERR   0x0100
++/** }@ defgroup MALIGP2_STATUS*/
++
++#define MALIGP2_REG_VAL_STATUS_MASK_ACTIVE (\
++      MALIGP2_REG_VAL_STATUS_VS_ACTIVE|\
++      MALIGP2_REG_VAL_STATUS_PLBU_ACTIVE)
++
++
++#define MALIGP2_REG_VAL_STATUS_MASK_ERROR (\
++      MALIGP2_REG_VAL_STATUS_BUS_ERROR |\
++      MALIGP2_REG_VAL_STATUS_WRITE_BOUND_ERR )
++
++/* This should be in the top 16 bit of the version register of gp.*/
++#define MALI200_GP_PRODUCT_ID 0xA07
++#define MALI300_GP_PRODUCT_ID 0xC07
++#define MALI400_GP_PRODUCT_ID 0xB07
++#define MALI450_GP_PRODUCT_ID 0xD07
++
++/**
++ * The different sources for instrumented on the geometry processor.
++ *  @see MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC
++ */
++
++enum MALIGP2_cont_reg_perf_cnt_src {
++      MALIGP2_REG_VAL_PERF_CNT1_SRC_NUMBER_OF_VERTICES_PROCESSED = 0x0a,
++};
++
++#endif
+diff --git a/drivers/gpu/arm/mali400/mali/timestamp-arm11-cc/mali_timestamp.c b/drivers/gpu/arm/mali400/mali/timestamp-arm11-cc/mali_timestamp.c
+new file mode 100644
+index 0000000..213596a
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/timestamp-arm11-cc/mali_timestamp.c
+@@ -0,0 +1,13 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_timestamp.h"
++
++/* This file is intentionally left empty, as all functions are inlined in mali_profiling_sampler.h */
+diff --git a/drivers/gpu/arm/mali400/mali/timestamp-arm11-cc/mali_timestamp.h b/drivers/gpu/arm/mali400/mali/timestamp-arm11-cc/mali_timestamp.h
+new file mode 100644
+index 0000000..248548b
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/timestamp-arm11-cc/mali_timestamp.h
+@@ -0,0 +1,48 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_TIMESTAMP_H__
++#define __MALI_TIMESTAMP_H__
++
++#include "mali_osk.h"
++
++MALI_STATIC_INLINE _mali_osk_errcode_t _mali_timestamp_reset(void)
++{
++      /*
++       * reset counters and overflow flags
++       */
++
++    u32 mask = (1 << 0) | /* enable all three counters */
++                 (0 << 1) | /* reset both Count Registers to 0x0 */
++                 (1 << 2) | /* reset the Cycle Counter Register to 0x0 */
++                 (0 << 3) | /* 1 = Cycle Counter Register counts every 64th processor clock cycle */
++                 (0 << 4) | /* Count Register 0 interrupt enable */
++                 (0 << 5) | /* Count Register 1 interrupt enable */
++                 (0 << 6) | /* Cycle Counter interrupt enable */
++                 (0 << 8) | /* Count Register 0 overflow flag (clear or write, flag on read) */
++                 (0 << 9) | /* Count Register 1 overflow flag (clear or write, flag on read) */
++                 (1 << 10); /* Cycle Counter Register overflow flag (clear or write, flag on read) */
++
++      __asm__ __volatile__ ("MCR    p15, 0, %0, c15, c12, 0" : : "r" (mask) );
++
++      return _MALI_OSK_ERR_OK;
++}
++
++MALI_STATIC_INLINE u64 _mali_timestamp_get(void)
++{
++      u32 result;
++
++      /* this is for the clock cycles */
++      __asm__ __volatile__ ("MRC    p15, 0, %0, c15, c12, 1" : "=r" (result));
++
++      return (u64)result;
++}
++
++#endif /* __MALI_TIMESTAMP_H__ */
+diff --git a/drivers/gpu/arm/mali400/mali/timestamp-default/mali_timestamp.c b/drivers/gpu/arm/mali400/mali/timestamp-default/mali_timestamp.c
+new file mode 100644
+index 0000000..213596a
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/timestamp-default/mali_timestamp.c
+@@ -0,0 +1,13 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_timestamp.h"
++
++/* This file is intentionally left empty, as all functions are inlined in mali_profiling_sampler.h */
+diff --git a/drivers/gpu/arm/mali400/mali/timestamp-default/mali_timestamp.h b/drivers/gpu/arm/mali400/mali/timestamp-default/mali_timestamp.h
+new file mode 100644
+index 0000000..867253f
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/timestamp-default/mali_timestamp.h
+@@ -0,0 +1,26 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __MALI_TIMESTAMP_H__
++#define __MALI_TIMESTAMP_H__
++
++#include "mali_osk.h"
++
++MALI_STATIC_INLINE _mali_osk_errcode_t _mali_timestamp_reset(void)
++{
++      return _MALI_OSK_ERR_OK;
++}
++
++MALI_STATIC_INLINE u64 _mali_timestamp_get(void)
++{
++      return _mali_osk_time_get_ns();
++}
++
++#endif /* __MALI_TIMESTAMP_H__ */
+diff --git a/drivers/gpu/arm/mali400/ump/Kbuild b/drivers/gpu/arm/mali400/ump/Kbuild
+new file mode 100644
+index 0000000..2c4d72c
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/Kbuild
+@@ -0,0 +1,76 @@
++#
++# Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++#
++# This program is free software and is provided to you under the terms of the GNU General Public License version 2
++# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++#
++# A copy of the licence is included with the program, and can also be obtained from Free Software
++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++#
++
++# Set default configuration to use, if Makefile didn't provide one.
++# Change this to use a different config.h
++# MALI_SEC
++# CONFIG ?= os_memory_64m
++CONFIG ?= release
++
++# Validate selected config
++ifneq ($(shell [ -d $(src)/arch-$(CONFIG) ] && [ -f  $(src)/arch-$(CONFIG)/config.h ] && echo "OK"), OK)
++$(warning Current directory is $(src))
++$(error No configuration found for config $(CONFIG). Check that arch-$(CONFIG)/config.h exists)
++else
++# Link arch to the selected arch-config directory
++$(shell [ -L $(src)/arch ] && rm $(src)/arch)
++$(shell ln -sf arch-$(CONFIG) $(src)/arch)
++$(shell touch $(src)/arch/config.h)
++endif
++
++UDD_FILE_PREFIX = ../mali/
++
++# Get subversion revision number, fall back to 0000 if no svn info is available
++SVN_REV := $(shell ((svnversion | grep -qv exported && echo -n 'Revision: ' && svnversion) || git svn info | sed -e 's/$$$$/M/' | grep '^Revision: ' || echo ${MALI_RELEASE_NAME}) 2>/dev/null | sed -e 's/^Revision: //')
++
++ccflags-y += -DSVN_REV=$(SVN_REV)
++ccflags-y += -DSVN_REV_STRING=\"$(SVN_REV)\"
++
++ccflags-y += -I$(src) -I$(src)/common -I$(src)/linux -I$(src)/../mali/common -I$(src)/../mali/linux -I$(src)/../../ump/include/ump
++# MALI_SEC
++ccflags-y += -I$(src)/include
++ccflags-y += -DUSING_MEMORY=1 -DUMP_MEM_SIZE=512
++
++ccflags-y += -DMALI_STATE_TRACKING=0
++ccflags-$(CONFIG_UMP_DEBUG) += -DDEBUG
++
++# For customer releases the Linux Device Drivers will be provided as ARM proprietary and GPL releases:
++# The ARM proprietary product will only include the license/proprietary directory
++# The GPL product will only include the license/gpl directory
++
++ifeq ($(wildcard $(src)/linux/license/gpl/*),)
++ccflags-y += -I$(src)/linux/license/proprietary
++else
++ccflags-y += -I$(src)/linux/license/gpl
++endif
++
++ump-y = common/ump_kernel_common.o \
++      common/ump_kernel_descriptor_mapping.o \
++      common/ump_kernel_api.o \
++      common/ump_kernel_ref_drv.o \
++      linux/ump_kernel_linux.o \
++      linux/ump_kernel_memory_backend_os.o \
++      linux/ump_kernel_memory_backend_dedicated.o \
++      linux/ump_memory_backend.o \
++      linux/ump_ukk_wrappers.o \
++      linux/ump_ukk_ref_wrappers.o \
++      linux/ump_osk_atomics.o \
++      linux/ump_osk_low_level_mem.o \
++      linux/ump_osk_misc.o
++
++# MALI_SEC
++#     $(UDD_FILE_PREFIX)linux/mali_osk_atomics.o \
++#     $(UDD_FILE_PREFIX)linux/mali_osk_locks.o \
++#     $(UDD_FILE_PREFIX)linux/mali_osk_memory.o \
++#     $(UDD_FILE_PREFIX)linux/mali_osk_math.o \
++#     $(UDD_FILE_PREFIX)linux/mali_osk_misc.o
++
++obj-$(CONFIG_MALI400_UMP) := ump.o
++
+diff --git a/drivers/gpu/arm/mali400/ump/Kconfig b/drivers/gpu/arm/mali400/ump/Kconfig
+new file mode 100644
+index 0000000..13785e2
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/Kconfig
+@@ -0,0 +1,7 @@
++config UMP_DEBUG
++      bool "Enable extra debug in UMP"
++      depends on MALI400_UMP
++      default n
++      ---help---
++        This enabled extra debug checks and messages in UMP.
++
+diff --git a/drivers/gpu/arm/mali400/ump/Makefile b/drivers/gpu/arm/mali400/ump/Makefile
+new file mode 100644
+index 0000000..912cf47
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/Makefile
+@@ -0,0 +1,67 @@
++#
++# Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++#
++# This program is free software and is provided to you under the terms of the GNU General Public License version 2
++# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++#
++# A copy of the licence is included with the program, and can also be obtained from Free Software
++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++#
++
++# For each arch check: CROSS_COMPILE , KDIR , CFLAGS += -DARCH
++
++export ARCH ?= arm
++BUILD ?= debug
++
++check_cc2 = \
++      $(shell if $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; \
++      then \
++              echo "$(2)"; \
++      else \
++              echo "$(3)"; \
++      fi ;)
++
++# Check that required parameters are supplied.
++ifeq ($(CONFIG),)
++$(error "CONFIG must be specified.")
++endif
++ifeq ($(CPU)$(KDIR),)
++$(error "KDIR or CPU must be specified.")
++endif
++
++# Get any user defined KDIR-<names> or maybe even a hardcoded KDIR
++-include KDIR_CONFIGURATION
++
++# Define host system directory
++KDIR-$(shell uname -m):=/lib/modules/$(shell uname -r)/build
++
++ifeq ($(ARCH), arm)
++# when compiling for ARM we're cross compiling
++export CROSS_COMPILE ?= $(call check_cc2, arm-linux-gnueabi-gcc, arm-linux-gnueabi-, arm-none-linux-gnueabi-)
++endif
++
++# look up KDIR based om CPU selection
++KDIR ?= $(KDIR-$(CPU))
++
++export CONFIG
++
++export CONFIG_MALI400_UMP := m
++ifeq ($(BUILD),debug)
++export CONFIG_UMP_DEBUG := y
++else
++export CONFIG_UMP_DEBUG := n
++endif
++
++ifeq ($(KDIR),)
++$(error No KDIR found for platform $(CPU))
++endif
++
++all:
++      $(MAKE) -C $(KDIR) M=$(CURDIR) modules
++
++kernelrelease:
++      $(MAKE) -C $(KDIR) kernelrelease
++
++clean:
++      $(MAKE) -C $(KDIR) M=$(CURDIR) clean
++      $(MAKE) -C $(KDIR) M=$(CURDIR)/../mali clean
+diff --git a/drivers/gpu/arm/mali400/ump/Makefile.common b/drivers/gpu/arm/mali400/ump/Makefile.common
+new file mode 100644
+index 0000000..0eb2558
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/Makefile.common
+@@ -0,0 +1,20 @@
++#
++# Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++#
++# This program is free software and is provided to you under the terms of the GNU General Public License version 2
++# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++#
++# A copy of the licence is included with the program, and can also be obtained from Free Software
++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++#
++
++SRC = $(UMP_FILE_PREFIX)common/ump_kernel_common.c \
++      $(UMP_FILE_PREFIX)common/ump_kernel_descriptor_mapping.c \
++      $(UMP_FILE_PREFIX)common/ump_kernel_api.c \
++      $(UMP_FILE_PREFIX)common/ump_kernel_ref_drv.c
++
++# Get subversion revision number, fall back to 0000 if no svn info is available
++SVN_REV:=$(shell ((svnversion | grep -qv exported && echo -n 'Revision: ' && svnversion) || git svn info | sed -e 's/$$$$/M/' | grep '^Revision: ' || echo ${MALI_RELEASE_NAME}) 2>/dev/null | sed -e 's/^Revision: //')
++
++EXTRA_CFLAGS += -DSVN_REV=$(SVN_REV)
++EXTRA_CFLAGS += -DSVN_REV_STRING=\"$(SVN_REV)\"
+diff --git a/drivers/gpu/arm/mali400/ump/arch-pb-virtex5/config.h b/drivers/gpu/arm/mali400/ump/arch-pb-virtex5/config.h
+new file mode 100644
+index 0000000..a61ca2b
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/arch-pb-virtex5/config.h
+@@ -0,0 +1,18 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __ARCH_CONFIG_H__
++#define __ARCH_CONFIG_H__
++
++#define ARCH_UMP_BACKEND_DEFAULT          0
++#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT   0xE1000000
++#define ARCH_UMP_MEMORY_SIZE_DEFAULT 16UL * 1024UL * 1024UL
++
++#endif /* __ARCH_CONFIG_H__ */
+diff --git a/drivers/gpu/arm/mali400/ump/arch-pegasus-m400/config.h b/drivers/gpu/arm/mali400/ump/arch-pegasus-m400/config.h
+new file mode 100644
+index 0000000..0b8dd5a
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/arch-pegasus-m400/config.h
+@@ -0,0 +1,22 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __ARCH_CONFIG_UMP_H__
++#define __ARCH_CONFIG_UMP_H__
++
++#define ARCH_UMP_BACKEND_DEFAULT              USING_MEMORY
++#if (USING_MEMORY == 0) /* Dedicated Memory */
++#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT       0x2C000000
++#else
++#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT       0
++#endif
++
++#define ARCH_UMP_MEMORY_SIZE_DEFAULT          UMP_MEM_SIZE*1024*1024
++#endif /* __ARCH_CONFIG_UMP_H__ */
+diff --git a/drivers/gpu/arm/mali400/ump/arch-release/config.h b/drivers/gpu/arm/mali400/ump/arch-release/config.h
+new file mode 100644
+index 0000000..0b8dd5a
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/arch-release/config.h
+@@ -0,0 +1,22 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __ARCH_CONFIG_UMP_H__
++#define __ARCH_CONFIG_UMP_H__
++
++#define ARCH_UMP_BACKEND_DEFAULT              USING_MEMORY
++#if (USING_MEMORY == 0) /* Dedicated Memory */
++#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT       0x2C000000
++#else
++#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT       0
++#endif
++
++#define ARCH_UMP_MEMORY_SIZE_DEFAULT          UMP_MEM_SIZE*1024*1024
++#endif /* __ARCH_CONFIG_UMP_H__ */
+diff --git a/drivers/gpu/arm/mali400/ump/arch/arch-release b/drivers/gpu/arm/mali400/ump/arch/arch-release
+new file mode 120000
+index 0000000..58ffbe7
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/arch/arch-release
+@@ -0,0 +1 @@
++arch-release
+\ No newline at end of file
+diff --git a/drivers/gpu/arm/mali400/ump/arch/config.h b/drivers/gpu/arm/mali400/ump/arch/config.h
+new file mode 100644
+index 0000000..0b8dd5a
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/arch/config.h
+@@ -0,0 +1,22 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __ARCH_CONFIG_UMP_H__
++#define __ARCH_CONFIG_UMP_H__
++
++#define ARCH_UMP_BACKEND_DEFAULT              USING_MEMORY
++#if (USING_MEMORY == 0) /* Dedicated Memory */
++#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT       0x2C000000
++#else
++#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT       0
++#endif
++
++#define ARCH_UMP_MEMORY_SIZE_DEFAULT          UMP_MEM_SIZE*1024*1024
++#endif /* __ARCH_CONFIG_UMP_H__ */
+diff --git a/drivers/gpu/arm/mali400/ump/common/ump_kernel_api.c b/drivers/gpu/arm/mali400/ump/common/ump_kernel_api.c
+new file mode 100644
+index 0000000..f45fc3a
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/common/ump_kernel_api.c
+@@ -0,0 +1,580 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_osk.h"
++#include "mali_osk_list.h"
++#include "ump_osk.h"
++#include "ump_uk_types.h"
++#include "ump_kernel_interface.h"
++#include "ump_kernel_common.h"
++
++/* MALI_SEC */
++#ifdef CONFIG_DMA_SHARED_BUFFER
++#include <linux/dma-buf.h>
++#endif
++
++/* ---------------- UMP kernel space API functions follows ---------------- */
++
++
++
++UMP_KERNEL_API_EXPORT ump_secure_id ump_dd_secure_id_get(ump_dd_handle memh)
++{
++      ump_dd_mem * mem = (ump_dd_mem *)memh;
++
++      DEBUG_ASSERT_POINTER(mem);
++
++      DBG_MSG(5, ("Returning secure ID. ID: %u\n", mem->secure_id));
++
++      return mem->secure_id;
++}
++
++
++
++UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_secure_id(ump_secure_id secure_id)
++{
++      ump_dd_mem * mem;
++
++      _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++
++      DBG_MSG(5, ("Getting handle from secure ID. ID: %u\n", secure_id));
++      if (0 != ump_descriptor_mapping_get(device.secure_id_map, (int)secure_id, (void**)&mem))
++      {
++              _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++              DBG_MSG(1, ("Secure ID not found. ID: %u\n", secure_id));
++              return UMP_DD_HANDLE_INVALID;
++      }
++
++      ump_dd_reference_add(mem);
++
++      _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++
++      return (ump_dd_handle)mem;
++}
++/* MALI_SEC */
++UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_get(ump_secure_id secure_id)
++{
++      ump_dd_mem * mem;
++
++      _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++
++      DBG_MSG(5, ("Getting handle from secure ID. ID: %u\n", secure_id));
++      if (0 != ump_descriptor_mapping_get(device.secure_id_map, (int)secure_id, (void**)&mem))
++      {
++              _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++              DBG_MSG(1, ("Secure ID not found. ID: %u\n", secure_id));
++              return UMP_DD_HANDLE_INVALID;
++      }
++
++      _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++
++      return (ump_dd_handle)mem;
++}
++
++UMP_KERNEL_API_EXPORT unsigned long ump_dd_phys_block_count_get(ump_dd_handle memh)
++{
++      ump_dd_mem * mem = (ump_dd_mem*) memh;
++
++      DEBUG_ASSERT_POINTER(mem);
++
++      return mem->nr_blocks;
++}
++
++
++
++UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_phys_blocks_get(ump_dd_handle memh, ump_dd_physical_block * blocks, unsigned long num_blocks)
++{
++      ump_dd_mem * mem = (ump_dd_mem *)memh;
++
++      DEBUG_ASSERT_POINTER(mem);
++
++      if (blocks == NULL)
++      {
++              DBG_MSG(1, ("NULL parameter in ump_dd_phys_blocks_get()\n"));
++              return UMP_DD_INVALID;
++      }
++
++      if (mem->nr_blocks != num_blocks)
++      {
++              DBG_MSG(1, ("Specified number of blocks do not match actual number of blocks\n"));
++              return UMP_DD_INVALID;
++      }
++
++      DBG_MSG(5, ("Returning physical block information. ID: %u\n", mem->secure_id));
++
++      _mali_osk_memcpy(blocks, mem->block_array, sizeof(ump_dd_physical_block) * mem->nr_blocks);
++
++      return UMP_DD_SUCCESS;
++}
++
++
++
++UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_phys_block_get(ump_dd_handle memh, unsigned long index, ump_dd_physical_block * block)
++{
++      ump_dd_mem * mem = (ump_dd_mem *)memh;
++
++      DEBUG_ASSERT_POINTER(mem);
++
++      if (block == NULL)
++      {
++              DBG_MSG(1, ("NULL parameter in ump_dd_phys_block_get()\n"));
++              return UMP_DD_INVALID;
++      }
++
++      if (index >= mem->nr_blocks)
++      {
++              DBG_MSG(5, ("Invalid index specified in ump_dd_phys_block_get()\n"));
++              return UMP_DD_INVALID;
++      }
++
++      DBG_MSG(5, ("Returning physical block information. ID: %u, index: %lu\n", mem->secure_id, index));
++
++      *block = mem->block_array[index];
++
++      return UMP_DD_SUCCESS;
++}
++
++
++
++UMP_KERNEL_API_EXPORT unsigned long ump_dd_size_get(ump_dd_handle memh)
++{
++      ump_dd_mem * mem = (ump_dd_mem*)memh;
++
++      DEBUG_ASSERT_POINTER(mem);
++
++      DBG_MSG(5, ("Returning size. ID: %u, size: %lu\n", mem->secure_id, mem->size_bytes));
++
++      return mem->size_bytes;
++}
++
++
++
++UMP_KERNEL_API_EXPORT void ump_dd_reference_add(ump_dd_handle memh)
++{
++      ump_dd_mem * mem = (ump_dd_mem*)memh;
++      int new_ref;
++
++      DEBUG_ASSERT_POINTER(mem);
++
++      new_ref = _ump_osk_atomic_inc_and_read(&mem->ref_count);
++
++      DBG_MSG(5, ("Memory reference incremented. ID: %u, new value: %d\n", mem->secure_id, new_ref));
++}
++
++
++
++UMP_KERNEL_API_EXPORT void ump_dd_reference_release(ump_dd_handle memh)
++{
++      int new_ref;
++      ump_dd_mem * mem = (ump_dd_mem*)memh;
++
++      DEBUG_ASSERT_POINTER(mem);
++
++      /* We must hold this mutex while doing the atomic_dec_and_read, to protect
++      that elements in the ump_descriptor_mapping table is always valid.  If they
++      are not, userspace may accidently map in this secure_ids right before its freed
++      giving a mapped backdoor into unallocated memory.*/
++      _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++
++      new_ref = _ump_osk_atomic_dec_and_read(&mem->ref_count);
++
++      DBG_MSG(5, ("Memory reference decremented. ID: %u, new value: %d\n", mem->secure_id, new_ref));
++
++      if (0 == new_ref)
++      {
++              DBG_MSG(3, ("Final release of memory. ID: %u\n", mem->secure_id));
++
++              ump_descriptor_mapping_free(device.secure_id_map, (int)mem->secure_id);
++
++              _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++
++/* MALI_SEC */
++#ifdef CONFIG_DMA_SHARED_BUFFER
++      /*
++       * when ump descriptor imported to dmabuf is released,
++       * physical memory region to the ump descriptor should be
++       * released only through dma_buf_put().
++       * if dma_buf_put() is called then file's refcount to
++       * the dmabuf becomes 0 and release func of exporter will be
++       * called by file->f_op->release to release the physical
++       * memory region finally.
++       */
++      if (mem->import_attach) {
++              struct dma_buf_attachment *attach = mem->import_attach;
++              struct dma_buf *dmabuf = attach->dmabuf;
++
++              if (mem->sgt)
++                      dma_buf_unmap_attachment(attach, mem->sgt,
++                                              DMA_NONE);
++
++              dma_buf_detach(dmabuf, attach);
++              mem->import_attach = NULL;
++              dma_buf_put(dmabuf);
++      }
++#endif
++
++              mem->release_func(mem->ctx, mem);
++              _mali_osk_free(mem);
++      }
++      else
++      {
++              _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++      }
++}
++
++
++
++/* --------------- Handling of user space requests follows --------------- */
++
++
++_mali_osk_errcode_t _ump_uku_get_api_version( _ump_uk_api_version_s *args )
++{
++      ump_session_data * session_data;
++
++      DEBUG_ASSERT_POINTER( args );
++      DEBUG_ASSERT_POINTER( args->ctx );
++
++      session_data = (ump_session_data *)args->ctx;
++
++      /* check compatability */
++      if (args->version == UMP_IOCTL_API_VERSION)
++      {
++              DBG_MSG(3, ("API version set to newest %d (compatible)\n", GET_VERSION(args->version)));
++              args->compatible = 1;
++              session_data->api_version = args->version;
++      }
++      else if (args->version == MAKE_VERSION_ID(1))
++      {
++              DBG_MSG(2, ("API version set to depricated: %d (compatible)\n", GET_VERSION(args->version)));
++              args->compatible = 1;
++              session_data->api_version = args->version;
++      }
++      else
++      {
++              DBG_MSG(2, ("API version set to %d (incompatible with client version %d)\n", GET_VERSION(UMP_IOCTL_API_VERSION), GET_VERSION(args->version)));
++              args->compatible = 0;
++              args->version = UMP_IOCTL_API_VERSION; /* report our version */
++      }
++
++      return _MALI_OSK_ERR_OK;
++}
++
++
++_mali_osk_errcode_t _ump_ukk_release( _ump_uk_release_s *release_info )
++{
++      ump_session_memory_list_element * session_memory_element;
++      ump_session_memory_list_element * tmp;
++      ump_session_data * session_data;
++      _mali_osk_errcode_t ret = _MALI_OSK_ERR_INVALID_FUNC;
++      int secure_id;
++
++      DEBUG_ASSERT_POINTER( release_info );
++      DEBUG_ASSERT_POINTER( release_info->ctx );
++
++      /* Retreive the session data */
++      session_data = (ump_session_data*)release_info->ctx;
++
++      /* If there are many items in the memory session list we
++       * could be de-referencing this pointer a lot so keep a local copy
++       */
++      secure_id = release_info->secure_id;
++
++      DBG_MSG(4, ("Releasing memory with IOCTL, ID: %u\n", secure_id));
++
++      /* Iterate through the memory list looking for the requested secure ID */
++      _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
++      _MALI_OSK_LIST_FOREACHENTRY(session_memory_element, tmp, &session_data->list_head_session_memory_list, ump_session_memory_list_element, list)
++      {
++              if ( session_memory_element->mem->secure_id == secure_id)
++              {
++                      ump_dd_mem *release_mem;
++
++                      release_mem = session_memory_element->mem;
++                      _mali_osk_list_del(&session_memory_element->list);
++                      ump_dd_reference_release(release_mem);
++                      _mali_osk_free(session_memory_element);
++
++                      ret = _MALI_OSK_ERR_OK;
++                      break;
++              }
++      }
++
++      _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
++      DBG_MSG_IF(1, _MALI_OSK_ERR_OK != ret, ("UMP memory with ID %u does not belong to this session.\n", secure_id));
++
++      DBG_MSG(4, ("_ump_ukk_release() returning 0x%x\n", ret));
++      return ret;
++}
++
++_mali_osk_errcode_t _ump_ukk_size_get( _ump_uk_size_get_s *user_interaction )
++{
++      ump_dd_mem * mem;
++      _mali_osk_errcode_t ret = _MALI_OSK_ERR_FAULT;
++
++      DEBUG_ASSERT_POINTER( user_interaction );
++
++      /* We lock the mappings so things don't get removed while we are looking for the memory */
++      _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++      if (0 == ump_descriptor_mapping_get(device.secure_id_map, (int)user_interaction->secure_id, (void**)&mem))
++      {
++              user_interaction->size = mem->size_bytes;
++              DBG_MSG(4, ("Returning size. ID: %u, size: %lu ", (ump_secure_id)user_interaction->secure_id, (unsigned long)user_interaction->size));
++              ret = _MALI_OSK_ERR_OK;
++      }
++      else
++      {
++               user_interaction->size = 0;
++              DBG_MSG(1, ("Failed to look up mapping in ump_ioctl_size_get(). ID: %u\n", (ump_secure_id)user_interaction->secure_id));
++      }
++
++      _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++      return ret;
++}
++
++
++
++void _ump_ukk_msync( _ump_uk_msync_s *args )
++{
++      ump_dd_mem * mem = NULL;
++      void *virtual = NULL;
++      u32 size = 0;
++      u32 offset = 0;
++
++      _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++      ump_descriptor_mapping_get(device.secure_id_map, (int)args->secure_id, (void**)&mem);
++
++      if (NULL == mem)
++      {
++              _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++              DBG_MSG(1, ("Failed to look up mapping in _ump_ukk_msync(). ID: %u\n", (ump_secure_id)args->secure_id));
++              return;
++      }
++      /* Ensure the memory doesn't dissapear when we are flushing it. */
++      ump_dd_reference_add(mem);
++      _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++
++      /* Returns the cache settings back to Userspace */
++      args->is_cached=mem->is_cached;
++
++      /* If this flag is the only one set, we should not do the actual flush, only the readout */
++      if ( _UMP_UK_MSYNC_READOUT_CACHE_ENABLED==args->op )
++      {
++              DBG_MSG(3, ("_ump_ukk_msync READOUT  ID: %u Enabled: %d\n", (ump_secure_id)args->secure_id, mem->is_cached));
++              goto msync_release_and_return;
++      }
++
++      /* Nothing to do if the memory is not caches */
++      if ( 0==mem->is_cached )
++      {
++              DBG_MSG(3, ("_ump_ukk_msync IGNORING ID: %u Enabled: %d  OP: %d\n", (ump_secure_id)args->secure_id, mem->is_cached, args->op));
++              goto msync_release_and_return;
++      }
++      DBG_MSG(3, ("UMP[%02u] _ump_ukk_msync  Flush  OP: %d Address: 0x%08x Mapping: 0x%08x\n",
++                  (ump_secure_id)args->secure_id, args->op, args->address, args->mapping));
++
++      if ( args->address )
++      {
++              virtual = (void *)((u32)args->address);
++              offset = (u32)((args->address) - (args->mapping));
++      } else {
++              /* Flush entire mapping when no address is specified. */
++              virtual = args->mapping;
++      }
++      if ( args->size )
++      {
++              size = args->size;
++      } else {
++              /* Flush entire mapping when no size is specified. */
++              size = mem->size_bytes - offset;
++      }
++
++      if ( (offset + size) > mem->size_bytes )
++      {
++              DBG_MSG(1, ("Trying to flush more than the entire UMP allocation: offset: %u + size: %u > %u\n", offset, size, mem->size_bytes));
++              goto msync_release_and_return;
++      }
++
++      /* The actual cache flush - Implemented for each OS*/
++      _ump_osk_msync( mem, virtual, offset, size, args->op, NULL);
++
++msync_release_and_return:
++      ump_dd_reference_release(mem);
++      return;
++}
++
++void _ump_ukk_cache_operations_control(_ump_uk_cache_operations_control_s* args)
++{
++      ump_session_data * session_data;
++      ump_uk_cache_op_control op;
++
++      DEBUG_ASSERT_POINTER( args );
++      DEBUG_ASSERT_POINTER( args->ctx );
++
++      op = args->op;
++      session_data = (ump_session_data *)args->ctx;
++
++      _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
++      if ( op== _UMP_UK_CACHE_OP_START )
++      {
++              session_data->cache_operations_ongoing++;
++              DBG_MSG(4, ("Cache ops start\n" ));
++              if ( session_data->cache_operations_ongoing != 1 )
++              {
++                      DBG_MSG(2, ("UMP: Number of simultanious cache control ops: %d\n", session_data->cache_operations_ongoing) );
++              }
++      }
++      else if ( op== _UMP_UK_CACHE_OP_FINISH )
++      {
++              DBG_MSG(4, ("Cache ops finish\n"));
++              session_data->cache_operations_ongoing--;
++              #if 0
++              if ( session_data->has_pending_level1_cache_flush)
++              {
++                      /* This function will set has_pending_level1_cache_flush=0 */
++                      _ump_osk_msync( NULL, NULL, 0, 0, _UMP_UK_MSYNC_FLUSH_L1, session_data);
++              }
++              #endif
++
++              /* to be on the safe side: always flush l1 cache when cache operations are done */
++              _ump_osk_msync( NULL, NULL, 0, 0, _UMP_UK_MSYNC_FLUSH_L1, session_data);
++              DBG_MSG(4, ("Cache ops finish end\n" ));
++      }
++      else
++      {
++              DBG_MSG(1, ("Illegal call to %s at line %d\n", __FUNCTION__, __LINE__));
++      }
++      _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
++
++}
++
++void _ump_ukk_switch_hw_usage(_ump_uk_switch_hw_usage_s *args )
++{
++      ump_dd_mem * mem = NULL;
++      ump_uk_user old_user;
++      ump_uk_msync_op cache_op = _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE;
++      ump_session_data *session_data;
++
++      DEBUG_ASSERT_POINTER( args );
++      DEBUG_ASSERT_POINTER( args->ctx );
++
++      session_data = (ump_session_data *)args->ctx;
++
++      _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++      ump_descriptor_mapping_get(device.secure_id_map, (int)args->secure_id, (void**)&mem);
++
++      if (NULL == mem)
++      {
++              _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++              DBG_MSG(1, ("Failed to look up mapping in _ump_ukk_switch_hw_usage(). ID: %u\n", (ump_secure_id)args->secure_id));
++              return;
++      }
++
++      old_user = mem->hw_device;
++      mem->hw_device = args->new_user;
++
++      DBG_MSG(3, ("UMP[%02u] Switch usage  Start  New: %s  Prev: %s.\n", (ump_secure_id)args->secure_id, args->new_user?"MALI":"CPU",old_user?"MALI":"CPU"));
++
++      if ( ! mem->is_cached )
++      {
++              _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++              DBG_MSG(3, ("UMP[%02u] Changing owner of uncached memory. Cache flushing not needed.\n", (ump_secure_id)args->secure_id));
++              return;
++      }
++
++      if ( old_user == args->new_user)
++      {
++              _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++              DBG_MSG(4, ("UMP[%02u] Setting the new_user equal to previous for. Cache flushing not needed.\n", (ump_secure_id)args->secure_id));
++              return;
++      }
++      if (
++               /* Previous AND new is both different from CPU */
++               (old_user != _UMP_UK_USED_BY_CPU) && (args->new_user != _UMP_UK_USED_BY_CPU  )
++         )
++      {
++              _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++              DBG_MSG(4, ("UMP[%02u] Previous and new user is not CPU. Cache flushing not needed.\n", (ump_secure_id)args->secure_id));
++              return;
++      }
++
++      if ( (old_user != _UMP_UK_USED_BY_CPU ) && (args->new_user==_UMP_UK_USED_BY_CPU) )
++      {
++              cache_op =_UMP_UK_MSYNC_INVALIDATE;
++              DBG_MSG(4, ("UMP[%02u] Cache invalidation needed\n", (ump_secure_id)args->secure_id));
++#ifdef UMP_SKIP_INVALIDATION
++#error
++              _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++              DBG_MSG(4, ("UMP[%02u] Performing Cache invalidation SKIPPED\n", (ump_secure_id)args->secure_id));
++              return;
++#endif
++      }
++      /* Ensure the memory doesn't dissapear when we are flushing it. */
++      ump_dd_reference_add(mem);
++      _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++
++      /* Take lock to protect: session->cache_operations_ongoing and session->has_pending_level1_cache_flush */
++      _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
++      /* Actual cache flush */
++      _ump_osk_msync( mem, NULL, 0, mem->size_bytes, cache_op, session_data);
++      _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
++
++      ump_dd_reference_release(mem);
++      DBG_MSG(4, ("UMP[%02u] Switch usage  Finish\n", (ump_secure_id)args->secure_id));
++      return;
++}
++
++void _ump_ukk_lock(_ump_uk_lock_s *args )
++{
++      ump_dd_mem * mem = NULL;
++
++      _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++      ump_descriptor_mapping_get(device.secure_id_map, (int)args->secure_id, (void**)&mem);
++
++      if (NULL == mem)
++      {
++              _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++              DBG_MSG(1, ("UMP[%02u] Failed to look up mapping in _ump_ukk_lock(). ID: %u\n", (ump_secure_id)args->secure_id));
++              return;
++      }
++      ump_dd_reference_add(mem);
++      _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++
++      DBG_MSG(1, ("UMP[%02u] Lock. New lock flag: %d. Old Lock flag:\n", (u32)args->secure_id, (u32)args->lock_usage, (u32) mem->lock_usage ));
++
++      mem->lock_usage = (ump_lock_usage) args->lock_usage;
++
++      /** TODO: TAKE LOCK HERE */
++
++      ump_dd_reference_release(mem);
++}
++
++void _ump_ukk_unlock(_ump_uk_unlock_s *args )
++{
++      ump_dd_mem * mem = NULL;
++
++      _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++      ump_descriptor_mapping_get(device.secure_id_map, (int)args->secure_id, (void**)&mem);
++
++      if (NULL == mem)
++      {
++              _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++              DBG_MSG(1, ("Failed to look up mapping in _ump_ukk_unlock(). ID: %u\n", (ump_secure_id)args->secure_id));
++              return;
++      }
++      ump_dd_reference_add(mem);
++      _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++
++      DBG_MSG(1, ("UMP[%02u] Unlocking. Old Lock flag:\n", (u32)args->secure_id, (u32) mem->lock_usage ));
++
++      mem->lock_usage = (ump_lock_usage) UMP_NOT_LOCKED;
++
++      /** TODO: RELEASE LOCK HERE */
++
++      ump_dd_reference_release(mem);
++}
+diff --git a/drivers/gpu/arm/mali400/ump/common/ump_kernel_common.c b/drivers/gpu/arm/mali400/ump/common/ump_kernel_common.c
+new file mode 100644
+index 0000000..27b816e
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/common/ump_kernel_common.c
+@@ -0,0 +1,416 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_kernel_common.h"
++#include "mali_osk.h"
++#include "mali_osk_bitops.h"
++#include "mali_osk_list.h"
++#include "ump_osk.h"
++#include "ump_uk_types.h"
++#include "ump_ukk.h"
++#include "ump_kernel_common.h"
++#include "ump_kernel_descriptor_mapping.h"
++#include "ump_kernel_memory_backend.h"
++
++
++
++/**
++ * Define the initial and maximum size of number of secure_ids on the system
++ */
++#define UMP_SECURE_ID_TABLE_ENTRIES_INITIAL (128  )
++#define UMP_SECURE_ID_TABLE_ENTRIES_MAXIMUM (4096 )
++
++
++/**
++ * Define the initial and maximum size of the ump_session_data::cookies_map,
++ * which is a \ref ump_descriptor_mapping. This limits how many secure_ids
++ * may be mapped into a particular process using _ump_ukk_map_mem().
++ */
++
++#define UMP_COOKIES_PER_SESSION_INITIAL (UMP_SECURE_ID_TABLE_ENTRIES_INITIAL )
++#define UMP_COOKIES_PER_SESSION_MAXIMUM (UMP_SECURE_ID_TABLE_ENTRIES_MAXIMUM)
++
++struct ump_dev device;
++
++_mali_osk_errcode_t ump_kernel_constructor(void)
++{
++      _mali_osk_errcode_t err;
++
++      /* Perform OS Specific initialization */
++      err = _ump_osk_init();
++      if( _MALI_OSK_ERR_OK != err )
++      {
++              MSG_ERR(("Failed to initiaze the UMP Device Driver"));
++              return err;
++      }
++
++      /* Init the global device */
++      _mali_osk_memset(&device, 0, sizeof(device) );
++
++      /* Create the descriptor map, which will be used for mapping secure ID to ump_dd_mem structs */
++      device.secure_id_map_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0 , 0);
++      if (NULL == device.secure_id_map_lock)
++      {
++              MSG_ERR(("Failed to create OSK lock for secure id lookup table\n"));
++              return _MALI_OSK_ERR_NOMEM;
++      }
++
++      device.secure_id_map = ump_descriptor_mapping_create(UMP_SECURE_ID_TABLE_ENTRIES_INITIAL, UMP_SECURE_ID_TABLE_ENTRIES_MAXIMUM);
++      if (NULL == device.secure_id_map)
++      {
++              _mali_osk_lock_term(device.secure_id_map_lock);
++              MSG_ERR(("Failed to create secure id lookup table\n"));
++              return _MALI_OSK_ERR_NOMEM;
++      }
++
++      /* Init memory backend */
++      device.backend = ump_memory_backend_create();
++      if (NULL == device.backend)
++      {
++              MSG_ERR(("Failed to create memory backend\n"));
++              _mali_osk_lock_term(device.secure_id_map_lock);
++              ump_descriptor_mapping_destroy(device.secure_id_map);
++              return _MALI_OSK_ERR_NOMEM;
++      }
++
++      return _MALI_OSK_ERR_OK;
++}
++
++void ump_kernel_destructor(void)
++{
++      DEBUG_ASSERT_POINTER(device.secure_id_map);
++      DEBUG_ASSERT_POINTER(device.secure_id_map_lock);
++
++      _mali_osk_lock_term(device.secure_id_map_lock);
++      device.secure_id_map_lock = NULL;
++
++      ump_descriptor_mapping_destroy(device.secure_id_map);
++      device.secure_id_map = NULL;
++
++      device.backend->shutdown(device.backend);
++      device.backend = NULL;
++
++      ump_memory_backend_destroy();
++
++      _ump_osk_term();
++}
++
++/** Creates a new UMP session
++ */
++_mali_osk_errcode_t _ump_ukk_open( void** context )
++{
++      struct ump_session_data * session_data;
++
++      /* allocated struct to track this session */
++      session_data = (struct ump_session_data *)_mali_osk_malloc(sizeof(struct ump_session_data));
++      if (NULL == session_data)
++      {
++              MSG_ERR(("Failed to allocate ump_session_data in ump_file_open()\n"));
++              return _MALI_OSK_ERR_NOMEM;
++      }
++
++      session_data->lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, 0);
++      if( NULL == session_data->lock )
++      {
++              MSG_ERR(("Failed to initialize lock for ump_session_data in ump_file_open()\n"));
++              _mali_osk_free(session_data);
++              return _MALI_OSK_ERR_NOMEM;
++      }
++
++      session_data->cookies_map = ump_descriptor_mapping_create( UMP_COOKIES_PER_SESSION_INITIAL, UMP_COOKIES_PER_SESSION_MAXIMUM );
++
++      if ( NULL == session_data->cookies_map )
++      {
++              MSG_ERR(("Failed to create descriptor mapping for _ump_ukk_map_mem cookies\n"));
++
++              _mali_osk_lock_term( session_data->lock );
++              _mali_osk_free( session_data );
++              return _MALI_OSK_ERR_NOMEM;
++      }
++
++      _MALI_OSK_INIT_LIST_HEAD(&session_data->list_head_session_memory_list);
++
++      _MALI_OSK_INIT_LIST_HEAD(&session_data->list_head_session_memory_mappings_list);
++
++      /* Since initial version of the UMP interface did not use the API_VERSION ioctl we have to assume
++         that it is this version, and not the "latest" one: UMP_IOCTL_API_VERSION
++         Current and later API versions would do an additional call to this IOCTL and update this variable
++         to the correct one.*/
++      session_data->api_version = MAKE_VERSION_ID(1);
++
++      *context = (void*)session_data;
++
++      session_data->cache_operations_ongoing = 0 ;
++      session_data->has_pending_level1_cache_flush = 0;
++
++      DBG_MSG(2, ("New session opened\n"));
++
++      return _MALI_OSK_ERR_OK;
++}
++
++_mali_osk_errcode_t _ump_ukk_close( void** context )
++{
++      struct ump_session_data * session_data;
++      ump_session_memory_list_element * item;
++      ump_session_memory_list_element * tmp;
++
++      session_data = (struct ump_session_data *)*context;
++      if (NULL == session_data)
++      {
++              MSG_ERR(("Session data is NULL in _ump_ukk_close()\n"));
++              return _MALI_OSK_ERR_INVALID_ARGS;
++      }
++
++      /* Unmap any descriptors mapped in. */
++      if (0 == _mali_osk_list_empty(&session_data->list_head_session_memory_mappings_list))
++      {
++              ump_memory_allocation *descriptor;
++              ump_memory_allocation *temp;
++
++              DBG_MSG(1, ("Memory mappings found on session usage list during session termination\n"));
++
++              /* use the 'safe' list iterator, since freeing removes the active block from the list we're iterating */
++              _MALI_OSK_LIST_FOREACHENTRY(descriptor, temp, &session_data->list_head_session_memory_mappings_list, ump_memory_allocation, list)
++              {
++                      _ump_uk_unmap_mem_s unmap_args;
++                      DBG_MSG(4, ("Freeing block with phys address 0x%x size 0x%x mapped in user space at 0x%x\n",
++                                  descriptor->phys_addr, descriptor->size, descriptor->mapping));
++                      unmap_args.ctx = (void*)session_data;
++                      unmap_args.mapping = descriptor->mapping;
++                      unmap_args.size = descriptor->size;
++                      unmap_args._ukk_private = NULL; /* NOTE: unused */
++                      unmap_args.cookie = descriptor->cookie;
++
++                      /* NOTE: This modifies the list_head_session_memory_mappings_list */
++                      _ump_ukk_unmap_mem( &unmap_args );
++              }
++      }
++
++      /* ASSERT that we really did free everything, because _ump_ukk_unmap_mem()
++       * can fail silently. */
++      DEBUG_ASSERT( _mali_osk_list_empty(&session_data->list_head_session_memory_mappings_list) );
++
++      _MALI_OSK_LIST_FOREACHENTRY(item, tmp, &session_data->list_head_session_memory_list, ump_session_memory_list_element, list)
++      {
++              _mali_osk_list_del(&item->list);
++              DBG_MSG(2, ("Releasing UMP memory %u as part of file close\n", item->mem->secure_id));
++              ump_dd_reference_release(item->mem);
++              _mali_osk_free(item);
++      }
++
++      ump_descriptor_mapping_destroy( session_data->cookies_map );
++
++      _mali_osk_lock_term(session_data->lock);
++      _mali_osk_free(session_data);
++
++      DBG_MSG(2, ("Session closed\n"));
++
++      return _MALI_OSK_ERR_OK;
++}
++
++_mali_osk_errcode_t _ump_ukk_map_mem( _ump_uk_map_mem_s *args )
++{
++      struct ump_session_data * session_data;
++      ump_memory_allocation * descriptor;  /* Describes current mapping of memory */
++      _mali_osk_errcode_t err;
++      unsigned long offset = 0;
++      unsigned long left;
++      ump_dd_handle handle;  /* The real UMP handle for this memory. Its real datatype is ump_dd_mem*  */
++      ump_dd_mem * mem;      /* The real UMP memory. It is equal to the handle, but with exposed struct */
++      u32 block;
++      int map_id;
++
++      session_data = (ump_session_data *)args->ctx;
++      if( NULL == session_data )
++      {
++              MSG_ERR(("Session data is NULL in _ump_ukk_map_mem()\n"));
++              return _MALI_OSK_ERR_INVALID_ARGS;
++      }
++      /* MALI_SEC */
++      /* SEC kernel stability 2012-02-17 */
++      if (NULL == session_data->cookies_map)
++      {
++              MSG_ERR(("session_data->cookies_map is NULL in _ump_ukk_map_mem()\n"));
++              return _MALI_OSK_ERR_INVALID_ARGS;
++      }
++      descriptor = (ump_memory_allocation*) _mali_osk_calloc( 1, sizeof(ump_memory_allocation));
++      if (NULL == descriptor)
++      {
++              MSG_ERR(("ump_ukk_map_mem: descriptor allocation failed\n"));
++              return _MALI_OSK_ERR_NOMEM;
++      }
++
++      handle = ump_dd_handle_create_from_secure_id(args->secure_id);
++      if ( UMP_DD_HANDLE_INVALID == handle)
++      {
++              _mali_osk_free(descriptor);
++              DBG_MSG(1, ("Trying to map unknown secure ID %u\n", args->secure_id));
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      mem = (ump_dd_mem*)handle;
++      DEBUG_ASSERT(mem);
++      if (mem->size_bytes != args->size)
++      {
++              _mali_osk_free(descriptor);
++              ump_dd_reference_release(handle);
++              DBG_MSG(1, ("Trying to map too much or little. ID: %u, virtual size=%lu, UMP size: %lu\n", args->secure_id, args->size, mem->size_bytes));
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      map_id = ump_descriptor_mapping_allocate_mapping( session_data->cookies_map, (void*) descriptor );
++
++      if (map_id < 0)
++      {
++              _mali_osk_free(descriptor);
++              ump_dd_reference_release(handle);
++              DBG_MSG(1, ("ump_ukk_map_mem: unable to allocate a descriptor_mapping for return cookie\n"));
++
++              return _MALI_OSK_ERR_NOMEM;
++      }
++
++      descriptor->size = args->size;
++      descriptor->handle = handle;
++      descriptor->phys_addr = args->phys_addr;
++      descriptor->process_mapping_info = args->_ukk_private;
++      descriptor->ump_session = session_data;
++      descriptor->cookie = (u32)map_id;
++
++      if ( mem->is_cached )
++      {
++              descriptor->is_cached = 1;
++              args->is_cached       = 1;
++              DBG_MSG(3, ("Mapping UMP secure_id: %d as cached.\n", args->secure_id));
++      }
++      else if ( args->is_cached) /* MALI_SEC */
++      {
++              mem->is_cached = 1;
++              descriptor->is_cached = 1;
++              DBG_MSG(3, ("Warning mapping UMP secure_id: %d. As cached, while it was allocated uncached.\n", args->secure_id));
++      }
++      else
++      {
++              descriptor->is_cached = 0;
++              args->is_cached       = 0;
++              DBG_MSG(3, ("Mapping UMP secure_id: %d  as Uncached.\n", args->secure_id));
++      }
++
++      _mali_osk_list_init( &descriptor->list );
++
++      err = _ump_osk_mem_mapregion_init( descriptor );
++      if( _MALI_OSK_ERR_OK != err )
++      {
++              DBG_MSG(1, ("Failed to initialize memory mapping in _ump_ukk_map_mem(). ID: %u\n", args->secure_id));
++              ump_descriptor_mapping_free( session_data->cookies_map, map_id );
++              _mali_osk_free(descriptor);
++              ump_dd_reference_release(mem);
++              return err;
++      }
++
++      DBG_MSG(4, ("Mapping virtual to physical memory: ID: %u, size:%lu, first physical addr: 0x%08lx, number of regions: %lu\n",
++              mem->secure_id,
++              mem->size_bytes,
++              ((NULL != mem->block_array) ? mem->block_array->addr : 0),
++              mem->nr_blocks));
++
++      left = descriptor->size;
++      /* loop over all blocks and map them in */
++      for (block = 0; block < mem->nr_blocks; block++)
++      {
++              unsigned long size_to_map;
++
++              if (left >  mem->block_array[block].size)
++              {
++                      size_to_map = mem->block_array[block].size;
++              }
++              else
++              {
++                      size_to_map = left;
++              }
++
++              if (_MALI_OSK_ERR_OK != _ump_osk_mem_mapregion_map(descriptor, offset, (u32 *)&(mem->block_array[block].addr), size_to_map ) )
++              {
++                      DBG_MSG(1, ("WARNING: _ump_ukk_map_mem failed to map memory into userspace\n"));
++                      ump_descriptor_mapping_free( session_data->cookies_map, map_id );
++                      ump_dd_reference_release(mem);
++                      _ump_osk_mem_mapregion_term( descriptor );
++                      _mali_osk_free(descriptor);
++                      return _MALI_OSK_ERR_FAULT;
++              }
++              left -= size_to_map;
++              offset += size_to_map;
++      }
++
++      /* Add to the ump_memory_allocation tracking list */
++      _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
++      _mali_osk_list_add( &descriptor->list, &session_data->list_head_session_memory_mappings_list );
++      _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
++
++      args->mapping = descriptor->mapping;
++      args->cookie = descriptor->cookie;
++
++      return _MALI_OSK_ERR_OK;
++}
++
++void _ump_ukk_unmap_mem( _ump_uk_unmap_mem_s *args )
++{
++      struct ump_session_data * session_data;
++      ump_memory_allocation * descriptor;
++      ump_dd_handle handle;
++
++      session_data = (ump_session_data *)args->ctx;
++
++      if( NULL == session_data )
++      {
++              MSG_ERR(("Session data is NULL in _ump_ukk_map_mem()\n"));
++              return;
++      }
++      /* MALI_SEC */
++      /* SEC kernel stability 2012-02-17 */
++      if (NULL == session_data->cookies_map)
++      {
++              MSG_ERR(("session_data->cookies_map is NULL in _ump_ukk_map_mem()\n"));
++              return;
++      }
++      if (0 != ump_descriptor_mapping_get( session_data->cookies_map, (int)args->cookie, (void**)&descriptor) )
++      {
++              MSG_ERR(("_ump_ukk_map_mem: cookie 0x%X not found for this session\n", args->cookie ));
++              return;
++      }
++
++      DEBUG_ASSERT_POINTER(descriptor);
++
++      handle = descriptor->handle;
++      if ( UMP_DD_HANDLE_INVALID == handle)
++      {
++              DBG_MSG(1, ("WARNING: Trying to unmap unknown handle: UNKNOWN\n"));
++              return;
++      }
++
++      /* Remove the ump_memory_allocation from the list of tracked mappings */
++      _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
++      _mali_osk_list_del( &descriptor->list );
++      _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
++
++      ump_descriptor_mapping_free( session_data->cookies_map, (int)args->cookie );
++
++      ump_dd_reference_release(handle);
++
++      _ump_osk_mem_mapregion_term( descriptor );
++      _mali_osk_free(descriptor);
++}
++
++u32 _ump_ukk_report_memory_usage( void )
++{
++      if(device.backend->stat)
++              return device.backend->stat(device.backend);
++      else
++              return 0;
++}
+diff --git a/drivers/gpu/arm/mali400/ump/common/ump_kernel_common.h b/drivers/gpu/arm/mali400/ump/common/ump_kernel_common.h
+new file mode 100644
+index 0000000..75afa0d
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/common/ump_kernel_common.h
+@@ -0,0 +1,128 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __UMP_KERNEL_COMMON_H__
++#define __UMP_KERNEL_COMMON_H__
++
++#include "ump_kernel_types.h"
++#include "ump_kernel_interface.h"
++#include "ump_kernel_descriptor_mapping.h"
++#include "ump_kernel_memory_backend.h"
++
++
++#ifdef DEBUG
++      extern int ump_debug_level;
++      #define UMP_DEBUG_PRINT(args) _mali_osk_dbgmsg args
++      #define UMP_DEBUG_CODE(args) args
++      #define DBG_MSG(level,args)  do { /* args should be in brackets */ \
++              ((level) <=  ump_debug_level)?\
++              UMP_DEBUG_PRINT(("UMP<" #level ">: ")), \
++              UMP_DEBUG_PRINT(args):0; \
++              } while (0)
++
++      #define DBG_MSG_IF(level,condition,args) /* args should be in brackets */ \
++              if((condition)&&((level) <=  ump_debug_level)) {\
++              UMP_DEBUG_PRINT(("UMP<" #level ">: ")); \
++              UMP_DEBUG_PRINT(args); \
++              }
++
++      #define DBG_MSG_ELSE(level,args) /* args should be in brackets */ \
++              else if((level) <=  ump_debug_level) { \
++              UMP_DEBUG_PRINT(("UMP<" #level ">: ")); \
++              UMP_DEBUG_PRINT(args); \
++              }
++
++      #define DEBUG_ASSERT_POINTER(pointer) do  {if( (pointer)== NULL) MSG_ERR(("NULL pointer " #pointer)); } while(0)
++      #define DEBUG_ASSERT(condition) do  {if(!(condition)) MSG_ERR(("ASSERT failed: " #condition)); } while(0)
++#else /* DEBUG */
++      #define UMP_DEBUG_PRINT(args) do {} while(0)
++      #define UMP_DEBUG_CODE(args)
++      #define DBG_MSG(level,args) do {} while(0)
++      #define DBG_MSG_IF(level,condition,args) do {} while(0)
++      #define DBG_MSG_ELSE(level,args) do {} while(0)
++      #define DEBUG_ASSERT(condition) do {} while(0)
++      #define DEBUG_ASSERT_POINTER(pointer) do  {} while(0)
++#endif /* DEBUG */
++
++#define MSG_ERR(args) do{ /* args should be in brackets */ \
++       _mali_osk_dbgmsg("UMP: ERR: %s\n" ,__FILE__); \
++       _mali_osk_dbgmsg( "           %s()%4d\n", __FUNCTION__, __LINE__) ; \
++       _mali_osk_dbgmsg args ; \
++       _mali_osk_dbgmsg("\n"); \
++      } while(0)
++
++#define MSG(args) do{ /* args should be in brackets */ \
++               _mali_osk_dbgmsg("UMP: "); \
++               _mali_osk_dbgmsg args; \
++              } while (0)
++
++
++
++/*
++ * This struct is used to store per session data.
++ * A session is created when someone open() the device, and
++ * closed when someone close() it or the user space application terminates.
++ */
++typedef struct ump_session_data
++{
++      _mali_osk_list_t list_head_session_memory_list;  /**< List of ump allocations made by the process (elements are ump_session_memory_list_element) */
++      _mali_osk_list_t list_head_session_memory_mappings_list; /**< List of ump_memory_allocations mapped in */
++      int api_version;
++      _mali_osk_lock_t * lock;
++      ump_descriptor_mapping * cookies_map; /**< Secure mapping of cookies from _ump_ukk_map_mem() */
++      int cache_operations_ongoing;
++      int has_pending_level1_cache_flush;
++} ump_session_data;
++
++
++
++/*
++ * This struct is used to track the UMP memory references a session has.
++ * We need to track this in order to be able to clean up after user space processes
++ * which don't do it themself (e.g. due to a crash or premature termination).
++ */
++typedef struct ump_session_memory_list_element
++{
++      struct ump_dd_mem * mem;
++      _mali_osk_list_t list;
++} ump_session_memory_list_element;
++
++
++
++/*
++ * Device specific data, created when device driver is loaded, and then kept as the global variable device.
++ */
++typedef struct ump_dev
++{
++      _mali_osk_lock_t * secure_id_map_lock;
++      ump_descriptor_mapping * secure_id_map;
++      ump_memory_backend * backend;
++} ump_dev;
++
++
++
++extern int ump_debug_level;
++extern struct ump_dev device;
++
++_mali_osk_errcode_t ump_kernel_constructor(void);
++void ump_kernel_destructor(void);
++int map_errcode( _mali_osk_errcode_t err );
++
++/**
++ * variables from user space cannot be dereferenced from kernel space; tagging them
++ * with __user allows the GCC compiler to generate a warning. Other compilers may
++ * not support this so we define it here as an empty macro if the compiler doesn't
++ * define it.
++ */
++#ifndef __user
++#define __user
++#endif
++
++#endif /* __UMP_KERNEL_COMMON_H__ */
+diff --git a/drivers/gpu/arm/mali400/ump/common/ump_kernel_descriptor_mapping.c b/drivers/gpu/arm/mali400/ump/common/ump_kernel_descriptor_mapping.c
+new file mode 100644
+index 0000000..c0cdff6
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/common/ump_kernel_descriptor_mapping.c
+@@ -0,0 +1,166 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_kernel_common.h"
++#include "mali_osk.h"
++#include "mali_osk_bitops.h"
++#include "ump_kernel_common.h"
++#include "ump_kernel_descriptor_mapping.h"
++
++#define MALI_PAD_INT(x) (((x) + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1))
++
++/**
++ * Allocate a descriptor table capable of holding 'count' mappings
++ * @param count Number of mappings in the table
++ * @return Pointer to a new table, NULL on error
++ */
++static ump_descriptor_table * descriptor_table_alloc(int count);
++
++/**
++ * Free a descriptor table
++ * @param table The table to free
++ */
++static void descriptor_table_free(ump_descriptor_table * table);
++
++ump_descriptor_mapping * ump_descriptor_mapping_create(int init_entries, int max_entries)
++{
++      ump_descriptor_mapping * map = _mali_osk_calloc(1, sizeof(ump_descriptor_mapping) );
++
++      init_entries = MALI_PAD_INT(init_entries);
++      max_entries = MALI_PAD_INT(max_entries);
++
++      if (NULL != map)
++      {
++              map->table = descriptor_table_alloc(init_entries);
++              if (NULL != map->table)
++              {
++                      map->lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_READERWRITER, 0 , 0);
++                      if ( NULL != map->lock )
++                      {
++                              _mali_osk_set_nonatomic_bit(0, map->table->usage); /* reserve bit 0 to prevent NULL/zero logic to kick in */
++                              map->max_nr_mappings_allowed = max_entries;
++                              map->current_nr_mappings = init_entries;
++                              return map;
++                      }
++                      descriptor_table_free(map->table);
++              }
++              _mali_osk_free(map);
++      }
++      return NULL;
++}
++
++void ump_descriptor_mapping_destroy(ump_descriptor_mapping * map)
++{
++      descriptor_table_free(map->table);
++      _mali_osk_lock_term( map->lock );
++      _mali_osk_free(map);
++}
++
++int ump_descriptor_mapping_allocate_mapping(ump_descriptor_mapping * map, void * target)
++{
++      int descriptor = -1;/*-EFAULT;*/
++      _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW);
++      descriptor = _mali_osk_find_first_zero_bit(map->table->usage, map->current_nr_mappings);
++      if (descriptor == map->current_nr_mappings)
++      {
++              int nr_mappings_new;
++              /* no free descriptor, try to expand the table */
++              ump_descriptor_table * new_table;
++              ump_descriptor_table * old_table = map->table;
++              nr_mappings_new= map->current_nr_mappings *2;
++
++              if (map->current_nr_mappings >= map->max_nr_mappings_allowed)
++              {
++                      descriptor = -1;
++                      goto unlock_and_exit;
++              }
++
++              new_table = descriptor_table_alloc(nr_mappings_new);
++              if (NULL == new_table)
++              {
++                      descriptor = -1;
++                      goto unlock_and_exit;
++              }
++
++              _mali_osk_memcpy(new_table->usage, old_table->usage, (sizeof(unsigned long)*map->current_nr_mappings) / BITS_PER_LONG);
++              _mali_osk_memcpy(new_table->mappings, old_table->mappings, map->current_nr_mappings * sizeof(void*));
++              map->table = new_table;
++              map->current_nr_mappings = nr_mappings_new;
++              descriptor_table_free(old_table);
++      }
++
++      /* we have found a valid descriptor, set the value and usage bit */
++      _mali_osk_set_nonatomic_bit(descriptor, map->table->usage);
++      map->table->mappings[descriptor] = target;
++
++unlock_and_exit:
++      _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RW);
++      return descriptor;
++}
++
++int ump_descriptor_mapping_get(ump_descriptor_mapping * map, int descriptor, void** target)
++{
++      int result = -1;/*-EFAULT;*/
++      DEBUG_ASSERT(map);
++      _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
++      if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
++      {
++              *target = map->table->mappings[descriptor];
++              result = 0;
++      }
++      else *target = NULL;
++      _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO);
++      return result;
++}
++
++int ump_descriptor_mapping_set(ump_descriptor_mapping * map, int descriptor, void * target)
++{
++      int result = -1;/*-EFAULT;*/
++      _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
++      if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
++      {
++              map->table->mappings[descriptor] = target;
++              result = 0;
++      }
++      _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO);
++      return result;
++}
++
++void ump_descriptor_mapping_free(ump_descriptor_mapping * map, int descriptor)
++{
++      _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW);
++      if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
++      {
++              map->table->mappings[descriptor] = NULL;
++              _mali_osk_clear_nonatomic_bit(descriptor, map->table->usage);
++      }
++      _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RW);
++}
++
++static ump_descriptor_table * descriptor_table_alloc(int count)
++{
++      ump_descriptor_table * table;
++
++      table = _mali_osk_calloc(1, sizeof(ump_descriptor_table) + ((sizeof(unsigned long) * count)/BITS_PER_LONG) + (sizeof(void*) * count) );
++
++      if (NULL != table)
++      {
++              table->usage = (u32*)((u8*)table + sizeof(ump_descriptor_table));
++              table->mappings = (void**)((u8*)table + sizeof(ump_descriptor_table) + ((sizeof(unsigned long) * count)/BITS_PER_LONG));
++      }
++
++      return table;
++}
++
++static void descriptor_table_free(ump_descriptor_table * table)
++{
++      _mali_osk_free(table);
++}
++
+diff --git a/drivers/gpu/arm/mali400/ump/common/ump_kernel_descriptor_mapping.h b/drivers/gpu/arm/mali400/ump/common/ump_kernel_descriptor_mapping.h
+new file mode 100644
+index 0000000..fed5336
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/common/ump_kernel_descriptor_mapping.h
+@@ -0,0 +1,91 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file ump_kernel_descriptor_mapping.h
++ */
++
++#ifndef __UMP_KERNEL_DESCRIPTOR_MAPPING_H__
++#define __UMP_KERNEL_DESCRIPTOR_MAPPING_H__
++
++#include "mali_osk.h"
++
++/**
++ * The actual descriptor mapping table, never directly accessed by clients
++ */
++typedef struct ump_descriptor_table
++{
++      u32 * usage; /**< Pointer to bitpattern indicating if a descriptor is valid/used or not */
++      void** mappings; /**< Array of the pointers the descriptors map to */
++} ump_descriptor_table;
++
++/**
++ * The descriptor mapping object
++ * Provides a separate namespace where we can map an integer to a pointer
++ */
++typedef struct ump_descriptor_mapping
++{
++      _mali_osk_lock_t *lock; /**< Lock protecting access to the mapping object */
++      int max_nr_mappings_allowed; /**< Max number of mappings to support in this namespace */
++      int current_nr_mappings; /**< Current number of possible mappings */
++      ump_descriptor_table * table; /**< Pointer to the current mapping table */
++} ump_descriptor_mapping;
++
++/**
++ * Create a descriptor mapping object
++ * Create a descriptor mapping capable of holding init_entries growable to max_entries
++ * @param init_entries Number of entries to preallocate memory for
++ * @param max_entries Number of entries to max support
++ * @return Pointer to a descriptor mapping object, NULL on failure
++ */
++ump_descriptor_mapping * ump_descriptor_mapping_create(int init_entries, int max_entries);
++
++/**
++ * Destroy a descriptor mapping object
++ * @param map The map to free
++ */
++void ump_descriptor_mapping_destroy(ump_descriptor_mapping * map);
++
++/**
++ * Allocate a new mapping entry (descriptor ID)
++ * Allocates a new entry in the map.
++ * @param map The map to allocate a new entry in
++ * @param target The value to map to
++ * @return The descriptor allocated, a negative value on error
++ */
++int ump_descriptor_mapping_allocate_mapping(ump_descriptor_mapping * map, void * target);
++
++/**
++ * Get the value mapped to by a descriptor ID
++ * @param map The map to lookup the descriptor id in
++ * @param descriptor The descriptor ID to lookup
++ * @param target Pointer to a pointer which will receive the stored value
++ * @return 0 on successful lookup, negative on error
++ */
++int ump_descriptor_mapping_get(ump_descriptor_mapping * map, int descriptor, void** target);
++
++/**
++ * Set the value mapped to by a descriptor ID
++ * @param map The map to lookup the descriptor id in
++ * @param descriptor The descriptor ID to lookup
++ * @param target Pointer to replace the current value with
++ * @return 0 on successful lookup, negative on error
++ */
++int ump_descriptor_mapping_set(ump_descriptor_mapping * map, int descriptor, void * target);
++
++/**
++ * Free the descriptor ID
++ * For the descriptor to be reused it has to be freed
++ * @param map The map to free the descriptor from
++ * @param descriptor The descriptor ID to free
++ */
++void ump_descriptor_mapping_free(ump_descriptor_mapping * map, int descriptor);
++
++#endif /* __UMP_KERNEL_DESCRIPTOR_MAPPING_H__ */
+diff --git a/drivers/gpu/arm/mali400/ump/common/ump_kernel_memory_backend.h b/drivers/gpu/arm/mali400/ump/common/ump_kernel_memory_backend.h
+new file mode 100644
+index 0000000..c3cc078
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/common/ump_kernel_memory_backend.h
+@@ -0,0 +1,52 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file ump_kernel_memory_mapping.h
++ */
++
++#ifndef __UMP_KERNEL_MEMORY_BACKEND_H__
++#define __UMP_KERNEL_MEMORY_BACKEND_H__
++
++#include "ump_kernel_interface.h"
++#include "ump_kernel_types.h"
++
++
++typedef struct ump_memory_allocation
++{
++      void                    * phys_addr;
++      void                    * mapping;
++      unsigned long             size;
++      ump_dd_handle             handle;
++      void                    * process_mapping_info;
++      u32                       cookie;               /**< necessary on some U/K interface implementations */
++      struct ump_session_data * ump_session;          /**< Session that this allocation belongs to */
++      _mali_osk_list_t          list;                 /**< List for linking together memory allocations into the session's memory head */
++      u32 is_cached;
++} ump_memory_allocation;
++
++typedef struct ump_memory_backend
++{
++      int  (*allocate)(void* ctx, ump_dd_mem * descriptor);
++      void (*release)(void* ctx, ump_dd_mem * descriptor);
++      void (*shutdown)(struct ump_memory_backend * backend);
++      u32  (*stat)(struct ump_memory_backend *backend);
++      int  (*pre_allocate_physical_check)(void *ctx, u32 size);
++      u32  (*adjust_to_mali_phys)(void *ctx, u32 cpu_phys);
++      void *(*get)(ump_dd_mem *mem, void *args); /* MALI_SEC */
++      void (*set)(ump_dd_mem *mem, void *args);
++      void * ctx;
++} ump_memory_backend;
++
++ump_memory_backend * ump_memory_backend_create ( void );
++void ump_memory_backend_destroy( void );
++
++#endif /*__UMP_KERNEL_MEMORY_BACKEND_H__ */
++
+diff --git a/drivers/gpu/arm/mali400/ump/common/ump_kernel_ref_drv.c b/drivers/gpu/arm/mali400/ump/common/ump_kernel_ref_drv.c
+new file mode 100644
+index 0000000..ae278ca
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/common/ump_kernel_ref_drv.c
+@@ -0,0 +1,197 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include "mali_osk.h"
++#include "mali_osk_list.h"
++#include "ump_osk.h"
++#include "ump_uk_types.h"
++
++#include "ump_kernel_interface_ref_drv.h"
++#include "ump_kernel_common.h"
++#include "ump_kernel_descriptor_mapping.h"
++
++#define UMP_MINIMUM_SIZE         4096
++#define UMP_MINIMUM_SIZE_MASK    (~(UMP_MINIMUM_SIZE-1))
++#define UMP_SIZE_ALIGN(x)        (((x)+UMP_MINIMUM_SIZE-1)&UMP_MINIMUM_SIZE_MASK)
++#define UMP_ADDR_ALIGN_OFFSET(x) ((x)&(UMP_MINIMUM_SIZE-1))
++static void phys_blocks_release(void * ctx, struct ump_dd_mem * descriptor);
++
++UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_phys_blocks(ump_dd_physical_block * blocks, unsigned long num_blocks)
++{
++      ump_dd_mem * mem;
++      unsigned long size_total = 0;
++      int map_id;
++      u32 i;
++
++      /* Go through the input blocks and verify that they are sane */
++      for (i=0; i < num_blocks; i++)
++      {
++              unsigned long addr = blocks[i].addr;
++              unsigned long size = blocks[i].size;
++
++              DBG_MSG(5, ("Adding physical memory to new handle. Address: 0x%08lx, size: %lu\n", addr, size));
++              size_total += blocks[i].size;
++
++              if (0 != UMP_ADDR_ALIGN_OFFSET(addr))
++              {
++                      MSG_ERR(("Trying to create UMP memory from unaligned physical address. Address: 0x%08lx\n", addr));
++                      return UMP_DD_HANDLE_INVALID;
++              }
++
++              if (0 != UMP_ADDR_ALIGN_OFFSET(size))
++              {
++                      MSG_ERR(("Trying to create UMP memory with unaligned size. Size: %lu\n", size));
++                      return UMP_DD_HANDLE_INVALID;
++              }
++      }
++
++      /* Allocate the ump_dd_mem struct for this allocation */
++      mem = _mali_osk_malloc(sizeof(*mem));
++      if (NULL == mem)
++      {
++              DBG_MSG(1, ("Could not allocate ump_dd_mem in ump_dd_handle_create_from_phys_blocks()\n"));
++              return UMP_DD_HANDLE_INVALID;
++      }
++
++      /* Find a secure ID for this allocation */
++      _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++      map_id = ump_descriptor_mapping_allocate_mapping(device.secure_id_map, (void*) mem);
++
++      if (map_id < 0)
++      {
++              _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++              _mali_osk_free(mem);
++              DBG_MSG(1, ("Failed to allocate secure ID in ump_dd_handle_create_from_phys_blocks()\n"));
++              return UMP_DD_HANDLE_INVALID;
++      }
++
++      /* Now, make a copy of the block information supplied by the user */
++      mem->block_array = _mali_osk_malloc(sizeof(ump_dd_physical_block)* num_blocks);
++      if (NULL == mem->block_array)
++      {
++              ump_descriptor_mapping_free(device.secure_id_map, map_id);
++              _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++              _mali_osk_free(mem);
++              DBG_MSG(1, ("Could not allocate a mem handle for function ump_dd_handle_create_from_phys_blocks().\n"));
++              return UMP_DD_HANDLE_INVALID;
++      }
++
++      _mali_osk_memcpy(mem->block_array, blocks, sizeof(ump_dd_physical_block) * num_blocks);
++
++      /* And setup the rest of the ump_dd_mem struct */
++      _mali_osk_atomic_init(&mem->ref_count, 1);
++      mem->secure_id = (ump_secure_id)map_id;
++      mem->size_bytes = size_total;
++      mem->nr_blocks = num_blocks;
++      mem->backend_info = NULL;
++      mem->ctx = NULL;
++      mem->release_func = phys_blocks_release;
++      /* For now UMP handles created by ump_dd_handle_create_from_phys_blocks() is forced to be Uncached */
++      mem->is_cached = 0;
++      mem->hw_device = _UMP_UK_USED_BY_CPU;
++      mem->lock_usage = UMP_NOT_LOCKED;
++
++      _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++      DBG_MSG(3, ("UMP memory created. ID: %u, size: %lu\n", mem->secure_id, mem->size_bytes));
++
++      return (ump_dd_handle)mem;
++}
++
++static void phys_blocks_release(void * ctx, struct ump_dd_mem * descriptor)
++{
++      _mali_osk_free(descriptor->block_array);
++      descriptor->block_array = NULL;
++}
++
++_mali_osk_errcode_t _ump_ukk_allocate( _ump_uk_allocate_s *user_interaction )
++{
++      ump_session_data * session_data = NULL;
++      ump_dd_mem *new_allocation = NULL;
++      ump_session_memory_list_element * session_memory_element = NULL;
++      int map_id;
++
++      DEBUG_ASSERT_POINTER( user_interaction );
++      DEBUG_ASSERT_POINTER( user_interaction->ctx );
++
++      session_data = (ump_session_data *) user_interaction->ctx;
++
++      session_memory_element = _mali_osk_calloc( 1, sizeof(ump_session_memory_list_element));
++      if (NULL == session_memory_element)
++      {
++              DBG_MSG(1, ("Failed to allocate ump_session_memory_list_element in ump_ioctl_allocate()\n"));
++              return _MALI_OSK_ERR_NOMEM;
++      }
++
++
++      new_allocation = _mali_osk_calloc( 1, sizeof(ump_dd_mem));
++      if (NULL==new_allocation)
++      {
++              _mali_osk_free(session_memory_element);
++              DBG_MSG(1, ("Failed to allocate ump_dd_mem in _ump_ukk_allocate()\n"));
++              return _MALI_OSK_ERR_NOMEM;
++      }
++
++      /* Create a secure ID for this allocation */
++      _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++      map_id = ump_descriptor_mapping_allocate_mapping(device.secure_id_map, (void*)new_allocation);
++
++      if (map_id < 0)
++      {
++              _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++              _mali_osk_free(session_memory_element);
++              _mali_osk_free(new_allocation);
++              DBG_MSG(1, ("Failed to allocate secure ID in ump_ioctl_allocate()\n"));
++              return - _MALI_OSK_ERR_INVALID_FUNC;
++      }
++
++      /* Initialize the part of the new_allocation that we know so for */
++      new_allocation->secure_id = (ump_secure_id)map_id;
++      _mali_osk_atomic_init(&new_allocation->ref_count,1);
++      if ( 0==(UMP_REF_DRV_UK_CONSTRAINT_USE_CACHE & user_interaction->constraints) )
++               new_allocation->is_cached = 0;
++      else new_allocation->is_cached = 1;
++
++      /* special case a size of 0, we should try to emulate what malloc does in this case, which is to return a valid pointer that must be freed, but can't be dereferences */
++      if (0 == user_interaction->size)
++      {
++              user_interaction->size = 1; /* emulate by actually allocating the minimum block size */
++      }
++
++      new_allocation->size_bytes = UMP_SIZE_ALIGN(user_interaction->size); /* Page align the size */
++      new_allocation->lock_usage = UMP_NOT_LOCKED;
++
++      /* Now, ask the active memory backend to do the actual memory allocation */
++      if (!device.backend->allocate( device.backend->ctx, new_allocation ) )
++      {
++              DBG_MSG(3, ("OOM: No more UMP memory left. Failed to allocate memory in ump_ioctl_allocate(). Size: %lu, requested size: %lu\n", new_allocation->size_bytes, (unsigned long)user_interaction->size));
++              ump_descriptor_mapping_free(device.secure_id_map, map_id);
++              _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++              _mali_osk_free(new_allocation);
++              _mali_osk_free(session_memory_element);
++              return _MALI_OSK_ERR_INVALID_FUNC;
++      }
++      new_allocation->hw_device = _UMP_UK_USED_BY_CPU;
++      new_allocation->ctx = device.backend->ctx;
++      new_allocation->release_func = device.backend->release;
++
++      _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
++
++      /* Initialize the session_memory_element, and add it to the session object */
++      session_memory_element->mem = new_allocation;
++      _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
++      _mali_osk_list_add(&(session_memory_element->list), &(session_data->list_head_session_memory_list));
++      _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
++
++      user_interaction->secure_id = new_allocation->secure_id;
++      user_interaction->size = new_allocation->size_bytes;
++      DBG_MSG(3, ("UMP memory allocated. ID: %u, size: %lu\n", new_allocation->secure_id, new_allocation->size_bytes));
++
++      return _MALI_OSK_ERR_OK;
++}
+diff --git a/drivers/gpu/arm/mali400/ump/common/ump_kernel_types.h b/drivers/gpu/arm/mali400/ump/common/ump_kernel_types.h
+new file mode 100644
+index 0000000..10b70f9
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/common/ump_kernel_types.h
+@@ -0,0 +1,58 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __UMP_KERNEL_TYPES_H__
++#define __UMP_KERNEL_TYPES_H__
++
++#include "ump_kernel_interface.h"
++#include "mali_osk.h"
++
++
++typedef enum
++{
++      UMP_USED_BY_CPU = 0,
++      UMP_USED_BY_MALI = 1,
++      UMP_USED_BY_UNKNOWN_DEVICE= 100,
++} ump_hw_usage;
++
++typedef enum
++{
++      UMP_NOT_LOCKED = 0,
++      UMP_READ = 1,
++      UMP_READ_WRITE = 3,
++} ump_lock_usage;
++
++
++/*
++ * This struct is what is "behind" a ump_dd_handle
++ */
++typedef struct ump_dd_mem
++{
++      ump_secure_id secure_id;
++      _mali_osk_atomic_t ref_count;
++      unsigned long size_bytes;
++      unsigned long nr_blocks;
++      ump_dd_physical_block * block_array;
++      void (*release_func)(void * ctx, struct ump_dd_mem * descriptor);
++      void * ctx;
++      void * backend_info;
++      int is_cached;
++      ump_hw_usage hw_device;
++      ump_lock_usage lock_usage;
++/* MALI_SEC */
++#ifdef CONFIG_DMA_SHARED_BUFFER
++      struct dma_buf_attachment *import_attach;
++      struct sg_table *sgt;
++#endif
++} ump_dd_mem;
++
++
++
++#endif /* __UMP_KERNEL_TYPES_H__ */
+diff --git a/drivers/gpu/arm/mali400/ump/common/ump_osk.h b/drivers/gpu/arm/mali400/ump/common/ump_osk.h
+new file mode 100644
+index 0000000..3da77d9
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/common/ump_osk.h
+@@ -0,0 +1,51 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file ump_osk.h
++ * Defines the OS abstraction layer for the UMP kernel device driver (OSK)
++ */
++
++#ifndef __UMP_OSK_H__
++#define __UMP_OSK_H__
++
++#include <mali_osk.h>
++#include <ump_kernel_memory_backend.h>
++#include "ump_uk_types.h"
++#include "ump_kernel_common.h"
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif
++
++_mali_osk_errcode_t _ump_osk_init( void );
++
++_mali_osk_errcode_t _ump_osk_term( void );
++
++int _ump_osk_atomic_inc_and_read( _mali_osk_atomic_t *atom );
++
++int _ump_osk_atomic_dec_and_read( _mali_osk_atomic_t *atom );
++
++_mali_osk_errcode_t _ump_osk_mem_mapregion_init( ump_memory_allocation *descriptor );
++
++_mali_osk_errcode_t _ump_osk_mem_mapregion_map( ump_memory_allocation * descriptor, u32 offset, u32 * phys_addr, unsigned long size );
++
++void _ump_osk_mem_mapregion_term( ump_memory_allocation * descriptor );
++
++void _ump_osk_msync( ump_dd_mem * mem, void * virt, u32 offset, u32 size, ump_uk_msync_op op, ump_session_data * session_data );
++/* MALI_SEC */
++void _ump_osk_mem_mapregion_get( ump_dd_mem ** mem, unsigned long vaddr);
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif
+diff --git a/drivers/gpu/arm/mali400/ump/common/ump_ukk.h b/drivers/gpu/arm/mali400/ump/common/ump_ukk.h
+new file mode 100644
+index 0000000..3cd4dec
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/common/ump_ukk.h
+@@ -0,0 +1,61 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file ump_ukk.h
++ * Defines the kernel-side interface of the user-kernel interface
++ */
++
++#ifndef __UMP_UKK_H__
++#define __UMP_UKK_H__
++
++#include "mali_osk.h"
++#include "ump_uk_types.h"
++
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif
++
++
++_mali_osk_errcode_t _ump_ukk_open( void** context );
++
++_mali_osk_errcode_t _ump_ukk_close( void** context );
++
++_mali_osk_errcode_t _ump_ukk_allocate( _ump_uk_allocate_s *user_interaction );
++
++_mali_osk_errcode_t _ump_ukk_release( _ump_uk_release_s *release_info );
++
++_mali_osk_errcode_t _ump_ukk_size_get( _ump_uk_size_get_s *user_interaction );
++
++_mali_osk_errcode_t _ump_ukk_map_mem( _ump_uk_map_mem_s *args );
++
++_mali_osk_errcode_t _ump_uku_get_api_version( _ump_uk_api_version_s *args );
++
++void _ump_ukk_unmap_mem( _ump_uk_unmap_mem_s *args );
++
++void _ump_ukk_msync( _ump_uk_msync_s *args );
++
++void _ump_ukk_cache_operations_control(_ump_uk_cache_operations_control_s* args);
++
++void _ump_ukk_switch_hw_usage(_ump_uk_switch_hw_usage_s *args );
++
++void _ump_ukk_lock(_ump_uk_lock_s *args );
++
++void _ump_ukk_unlock(_ump_uk_unlock_s *args );
++
++u32 _ump_ukk_report_memory_usage( void );
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* __UMP_UKK_H__ */
+diff --git a/drivers/gpu/arm/mali400/ump/include/ump_kernel_interface.h b/drivers/gpu/arm/mali400/ump/include/ump_kernel_interface.h
+new file mode 100644
+index 0000000..c14922d
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/include/ump_kernel_interface.h
+@@ -0,0 +1,236 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file ump_kernel_interface.h
++ *
++ * This file contains the kernel space part of the UMP API.
++ */
++
++#ifndef __UMP_KERNEL_INTERFACE_H__
++#define __UMP_KERNEL_INTERFACE_H__
++
++
++/** @defgroup ump_kernel_space_api UMP Kernel Space API
++ * @{ */
++
++
++#include "ump_kernel_platform.h"
++
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif
++
++
++/**
++ * External representation of a UMP handle in kernel space.
++ */
++typedef void * ump_dd_handle;
++
++/**
++ * Typedef for a secure ID, a system wide identificator for UMP memory buffers.
++ */
++typedef unsigned int ump_secure_id;
++
++
++/**
++ * Value to indicate an invalid UMP memory handle.
++ */
++#define UMP_DD_HANDLE_INVALID ((ump_dd_handle)0)
++
++
++/**
++ * Value to indicate an invalid secure Id.
++ */
++#define UMP_INVALID_SECURE_ID ((ump_secure_id)-1)
++
++
++/**
++ * UMP error codes for kernel space.
++ */
++typedef enum
++{
++      UMP_DD_SUCCESS, /**< indicates success */
++      UMP_DD_INVALID, /**< indicates failure */
++} ump_dd_status_code;
++
++
++/**
++ * Struct used to describe a physical block used by UMP memory
++ */
++typedef struct ump_dd_physical_block
++{
++      unsigned long addr; /**< The physical address of the block */
++      unsigned long size; /**< The length of the block, typically page aligned */
++} ump_dd_physical_block;
++
++
++/**
++ * Retrieves the secure ID for the specified UMP memory.
++ *
++ * This identificator is unique across the entire system, and uniquely identifies
++ * the specified UMP memory. This identificator can later be used through the
++ * @ref ump_dd_handle_create_from_secure_id "ump_dd_handle_create_from_secure_id" or
++ * @ref ump_handle_create_from_secure_id "ump_handle_create_from_secure_id"
++ * functions in order to access this UMP memory, for instance from another process.
++ *
++ * @note There is a user space equivalent function called @ref ump_secure_id_get "ump_secure_id_get"
++ *
++ * @see ump_dd_handle_create_from_secure_id
++ * @see ump_handle_create_from_secure_id
++ * @see ump_secure_id_get
++ *
++ * @param mem Handle to UMP memory.
++ *
++ * @return Returns the secure ID for the specified UMP memory.
++ */
++UMP_KERNEL_API_EXPORT ump_secure_id ump_dd_secure_id_get(ump_dd_handle mem);
++
++
++/**
++ * Retrieves a handle to allocated UMP memory.
++ *
++ * The usage of UMP memory is reference counted, so this will increment the reference
++ * count by one for the specified UMP memory.
++ * Use @ref ump_dd_reference_release "ump_dd_reference_release" when there is no longer any
++ * use for the retrieved handle.
++ *
++ * @note There is a user space equivalent function called @ref ump_handle_create_from_secure_id "ump_handle_create_from_secure_id"
++ *
++ * @see ump_dd_reference_release
++ * @see ump_handle_create_from_secure_id
++ *
++ * @param secure_id The secure ID of the UMP memory to open, that can be retrieved using the @ref ump_secure_id_get "ump_secure_id_get " function.
++ *
++ * @return UMP_INVALID_MEMORY_HANDLE indicates failure, otherwise a valid handle is returned.
++ */
++UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_secure_id(ump_secure_id secure_id);
++
++
++/**
++ * Retrieves the number of physical blocks used by the specified UMP memory.
++ *
++ * This function retrieves the number of @ref ump_dd_physical_block "ump_dd_physical_block" structs needed
++ * to describe the physical memory layout of the given UMP memory. This can later be used when calling
++ * the functions @ref ump_dd_phys_blocks_get "ump_dd_phys_blocks_get" and
++ * @ref ump_dd_phys_block_get "ump_dd_phys_block_get".
++ *
++ * @see ump_dd_phys_blocks_get
++ * @see ump_dd_phys_block_get
++ *
++ * @param mem Handle to UMP memory.
++ *
++ * @return The number of ump_dd_physical_block structs required to describe the physical memory layout of the specified UMP memory.
++ */
++UMP_KERNEL_API_EXPORT unsigned long ump_dd_phys_block_count_get(ump_dd_handle mem);
++
++
++/**
++ * Retrieves all physical memory block information for specified UMP memory.
++ *
++ * This function can be used by other device drivers in order to create MMU tables.
++ *
++ * @note This function will fail if the num_blocks parameter is either to large or to small.
++ *
++ * @see ump_dd_phys_block_get
++ *
++ * @param mem Handle to UMP memory.
++ * @param blocks An array of @ref ump_dd_physical_block "ump_dd_physical_block" structs that will receive the physical description.
++ * @param num_blocks The number of blocks to return in the blocks array. Use the function
++ *                   @ref ump_dd_phys_block_count_get "ump_dd_phys_block_count_get" first to determine the number of blocks required.
++ *
++ * @return UMP_DD_SUCCESS indicates success, UMP_DD_INVALID indicates failure.
++ */
++UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_phys_blocks_get(ump_dd_handle mem, ump_dd_physical_block * blocks, unsigned long num_blocks);
++
++
++/**
++ * Retrieves the physical memory block information for specified block for the specified UMP memory.
++ *
++ * This function can be used by other device drivers in order to create MMU tables.
++ *
++ * @note This function will return UMP_DD_INVALID if the specified index is out of range.
++ *
++ * @see ump_dd_phys_blocks_get
++ *
++ * @param mem Handle to UMP memory.
++ * @param index Which physical info block to retrieve.
++ * @param block Pointer to a @ref ump_dd_physical_block "ump_dd_physical_block" struct which will receive the requested information.
++ *
++ * @return UMP_DD_SUCCESS indicates success, UMP_DD_INVALID indicates failure.
++ */
++UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_phys_block_get(ump_dd_handle mem, unsigned long index, ump_dd_physical_block * block);
++
++
++/**
++ * Retrieves the actual size of the specified UMP memory.
++ *
++ * The size is reported in bytes, and is typically page aligned.
++ *
++ * @note There is a user space equivalent function called @ref ump_size_get "ump_size_get"
++ *
++ * @see ump_size_get
++ *
++ * @param mem Handle to UMP memory.
++ *
++ * @return Returns the allocated size of the specified UMP memory, in bytes.
++ */
++UMP_KERNEL_API_EXPORT unsigned long ump_dd_size_get(ump_dd_handle mem);
++
++
++/**
++ * Adds an extra reference to the specified UMP memory.
++ *
++ * This function adds an extra reference to the specified UMP memory. This function should
++ * be used every time a UMP memory handle is duplicated, that is, assigned to another ump_dd_handle
++ * variable. The function @ref ump_dd_reference_release "ump_dd_reference_release" must then be used
++ * to release each copy of the UMP memory handle.
++ *
++ * @note You are not required to call @ref ump_dd_reference_add "ump_dd_reference_add"
++ * for UMP handles returned from
++ * @ref ump_dd_handle_create_from_secure_id "ump_dd_handle_create_from_secure_id",
++ * because these handles are already reference counted by this function.
++ *
++ * @note There is a user space equivalent function called @ref ump_reference_add "ump_reference_add"
++ *
++ * @see ump_reference_add
++ *
++ * @param mem Handle to UMP memory.
++ */
++UMP_KERNEL_API_EXPORT void ump_dd_reference_add(ump_dd_handle mem);
++
++
++/**
++ * Releases a reference from the specified UMP memory.
++ *
++ * This function should be called once for every reference to the UMP memory handle.
++ * When the last reference is released, all resources associated with this UMP memory
++ * handle are freed.
++ *
++ * @note There is a user space equivalent function called @ref ump_reference_release "ump_reference_release"
++ *
++ * @see ump_reference_release
++ *
++ * @param mem Handle to UMP memory.
++ */
++UMP_KERNEL_API_EXPORT void ump_dd_reference_release(ump_dd_handle mem);
++
++
++#ifdef __cplusplus
++}
++#endif
++
++
++/** @} */ /* end group ump_kernel_space_api */
++
++
++#endif  /* __UMP_KERNEL_INTERFACE_H__ */
+diff --git a/drivers/gpu/arm/mali400/ump/include/ump_kernel_interface_ref_drv.h b/drivers/gpu/arm/mali400/ump/include/ump_kernel_interface_ref_drv.h
+new file mode 100644
+index 0000000..0247e76
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/include/ump_kernel_interface_ref_drv.h
+@@ -0,0 +1,35 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file ump_kernel_interface.h
++ */
++
++#ifndef __UMP_KERNEL_INTERFACE_REF_DRV_H__
++#define __UMP_KERNEL_INTERFACE_REF_DRV_H__
++
++#include "ump_kernel_interface.h"
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++/** Turn specified physical memory into UMP memory. */
++UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_phys_blocks(ump_dd_physical_block * blocks, unsigned long num_blocks);
++UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_get(ump_secure_id secure_id);
++UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_meminfo_set(ump_dd_handle memh, void* args);
++UMP_KERNEL_API_EXPORT void *ump_dd_meminfo_get(ump_secure_id secure_id, void* args);
++UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_get_from_vaddr(unsigned long vaddr);
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif  /* __UMP_KERNEL_INTERFACE_REF_DRV_H__ */
+diff --git a/drivers/gpu/arm/mali400/ump/include/ump_kernel_platform.h b/drivers/gpu/arm/mali400/ump/include/ump_kernel_platform.h
+new file mode 100644
+index 0000000..dfefa2a
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/include/ump_kernel_platform.h
+@@ -0,0 +1,48 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file ump_kernel_platform.h
++ *
++ * This file should define UMP_KERNEL_API_EXPORT,
++ * which dictates how the UMP kernel API should be exported/imported.
++ * Modify this file, if needed, to match your platform setup.
++ */
++
++#ifndef __UMP_KERNEL_PLATFORM_H__
++#define __UMP_KERNEL_PLATFORM_H__
++
++/** @addtogroup ump_kernel_space_api
++ * @{ */
++
++/**
++ * A define which controls how UMP kernel space API functions are imported and exported.
++ * This define should be set by the implementor of the UMP API.
++ */
++
++#if defined(_WIN32)
++
++#if defined(UMP_BUILDING_UMP_LIBRARY)
++#define UMP_KERNEL_API_EXPORT __declspec(dllexport)
++#else
++#define UMP_KERNEL_API_EXPORT __declspec(dllimport)
++#endif
++
++#else
++
++#define UMP_KERNEL_API_EXPORT
++
++#endif
++
++
++/** @} */ /* end group ump_kernel_space_api */
++
++
++#endif /* __UMP_KERNEL_PLATFORM_H__ */
+diff --git a/drivers/gpu/arm/mali400/ump/include/ump_uk_types.h b/drivers/gpu/arm/mali400/ump/include/ump_uk_types.h
+new file mode 100644
+index 0000000..c587d83
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/include/ump_uk_types.h
+@@ -0,0 +1,218 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file ump_uk_types.h
++ * Defines the types and constants used in the user-kernel interface
++ */
++
++#ifndef __UMP_UK_TYPES_H__
++#define __UMP_UK_TYPES_H__
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif
++
++/* Helpers for API version handling */
++#define MAKE_VERSION_ID(x) (((x) << 16UL) | (x))
++#define IS_VERSION_ID(x) (((x) & 0xFFFF) == (((x) >> 16UL) & 0xFFFF))
++#define GET_VERSION(x) (((x) >> 16UL) & 0xFFFF)
++#define IS_API_MATCH(x, y) (IS_VERSION_ID((x)) && IS_VERSION_ID((y)) && (GET_VERSION((x)) == GET_VERSION((y))))
++
++/**
++ * API version define.
++ * Indicates the version of the kernel API
++ * The version is a 16bit integer incremented on each API change.
++ * The 16bit integer is stored twice in a 32bit integer
++ * So for version 1 the value would be 0x00010001
++ */
++#define UMP_IOCTL_API_VERSION MAKE_VERSION_ID(2)
++
++typedef enum
++{
++      _UMP_IOC_QUERY_API_VERSION = 1,
++      _UMP_IOC_ALLOCATE,
++      _UMP_IOC_RELEASE,
++      _UMP_IOC_SIZE_GET,
++      _UMP_IOC_MAP_MEM,    /* not used in Linux */
++      _UMP_IOC_UNMAP_MEM,  /* not used in Linux */
++      _UMP_IOC_MSYNC,
++/* MALI_SEC */
++#ifdef CONFIG_DMA_SHARED_BUFFER
++      _UMP_IOC_DMABUF_IMPORT,
++#endif
++      _UMP_IOC_CACHE_OPERATIONS_CONTROL,
++      _UMP_IOC_SWITCH_HW_USAGE,
++      _UMP_IOC_LOCK,
++      _UMP_IOC_UNLOCK,
++      _UMP_IOC_ION_IMPORT,
++}_ump_uk_functions;
++
++typedef enum
++{
++      UMP_REF_DRV_UK_CONSTRAINT_NONE = 0,
++      UMP_REF_DRV_UK_CONSTRAINT_PHYSICALLY_LINEAR = 1,
++      UMP_REF_DRV_UK_CONSTRAINT_USE_CACHE = 128,
++} ump_uk_alloc_constraints;
++
++typedef enum
++{
++      _UMP_UK_MSYNC_CLEAN = 0,
++      _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE = 1,
++      _UMP_UK_MSYNC_INVALIDATE = 2,
++      _UMP_UK_MSYNC_FLUSH_L1   = 3,
++      _UMP_UK_MSYNC_READOUT_CACHE_ENABLED = 128,
++} ump_uk_msync_op;
++
++typedef enum
++{
++      _UMP_UK_CACHE_OP_START = 0,
++      _UMP_UK_CACHE_OP_FINISH  = 1,
++} ump_uk_cache_op_control;
++
++typedef enum
++{
++      _UMP_UK_READ = 1,
++      _UMP_UK_READ_WRITE = 3,
++} ump_uk_lock_usage;
++
++typedef enum
++{
++      _UMP_UK_USED_BY_CPU = 0,
++      _UMP_UK_USED_BY_MALI = 1,
++      _UMP_UK_USED_BY_UNKNOWN_DEVICE= 100,
++} ump_uk_user;
++
++/**
++ * Get API version ([in,out] u32 api_version, [out] u32 compatible)
++ */
++typedef struct _ump_uk_api_version_s
++{
++      void *ctx;      /**< [in,out] user-kernel context (trashed on output) */
++      u32 version;    /**< Set to the user space version on entry, stores the device driver version on exit */
++      u32 compatible; /**< Non-null if the device is compatible with the client */
++} _ump_uk_api_version_s;
++
++/**
++ * ALLOCATE ([out] u32 secure_id, [in,out] u32 size,  [in] contraints)
++ */
++typedef struct _ump_uk_allocate_s
++{
++      void *ctx;                              /**< [in,out] user-kernel context (trashed on output) */
++      u32 secure_id;                          /**< Return value from DD to Userdriver */
++      u32 size;                               /**< Input and output. Requested size; input. Returned size; output */
++      ump_uk_alloc_constraints constraints;   /**< Only input to Devicedriver */
++} _ump_uk_allocate_s;
++
++typedef struct _ump_uk_ion_import_s
++{
++      void *ctx;                              /**< [in,out] user-kernel context (trashed on output) */
++      int ion_fd;                             /**< ion_fd */
++      u32 secure_id;                          /**< Return value from DD to Userdriver */
++      u32 size;                               /**< Input and output. Requested size; input. Returned size; output */
++      ump_uk_alloc_constraints constraints;   /**< Only input to Devicedriver */
++} _ump_uk_ion_import_s;
++
++/* MALI_SEC */
++#ifdef CONFIG_DMA_SHARED_BUFFER
++struct ump_uk_dmabuf {
++      void* ctx;
++      int fd;
++      size_t size;
++      uint32_t secure_id;
++};
++#endif
++
++/**
++ * SIZE_GET ([in] u32 secure_id, [out]size )
++ */
++typedef struct _ump_uk_size_get_s
++{
++      void *ctx;                              /**< [in,out] user-kernel context (trashed on output) */
++      u32 secure_id;                          /**< Input to DD */
++      u32 size;                               /**< Returned size; output */
++} _ump_uk_size_get_s;
++
++/**
++ * Release ([in] u32 secure_id)
++ */
++typedef struct _ump_uk_release_s
++{
++      void *ctx;                              /**< [in,out] user-kernel context (trashed on output) */
++      u32 secure_id;                          /**< Input to DD */
++} _ump_uk_release_s;
++
++typedef struct _ump_uk_map_mem_s
++{
++      void *ctx;                      /**< [in,out] user-kernel context (trashed on output) */
++      void *mapping;                  /**< [out] Returns user-space virtual address for the mapping */
++      void *phys_addr;                /**< [in] physical address */
++      unsigned long size;             /**< [in] size */
++      u32 secure_id;                  /**< [in] secure_id to assign to mapping */
++      void * _ukk_private;            /**< Only used inside linux port between kernel frontend and common part to store vma */
++      u32 cookie;
++      u32 is_cached;            /**< [in,out] caching of CPU mappings */
++} _ump_uk_map_mem_s;
++
++typedef struct _ump_uk_unmap_mem_s
++{
++      void *ctx;            /**< [in,out] user-kernel context (trashed on output) */
++      void *mapping;
++      u32 size;
++      void * _ukk_private;
++      u32 cookie;
++} _ump_uk_unmap_mem_s;
++
++typedef struct _ump_uk_msync_s
++{
++      void *ctx;            /**< [in,out] user-kernel context (trashed on output) */
++      void *mapping;        /**< [in] mapping addr */
++      void *address;        /**< [in] flush start addr */
++      u32 size;             /**< [in] size to flush */
++      ump_uk_msync_op op;   /**< [in] flush operation */
++      u32 cookie;           /**< [in] cookie stored with reference to the kernel mapping internals */
++      u32 secure_id;        /**< [in] secure_id that identifies the ump buffer */
++      u32 is_cached;        /**< [out] caching of CPU mappings */
++} _ump_uk_msync_s;
++
++typedef struct _ump_uk_cache_operations_control_s
++{
++      void *ctx;                   /**< [in,out] user-kernel context (trashed on output) */
++      ump_uk_cache_op_control op;  /**< [in] cache operations start/stop */
++} _ump_uk_cache_operations_control_s;
++
++
++typedef struct _ump_uk_switch_hw_usage_s
++{
++      void *ctx;            /**< [in,out] user-kernel context (trashed on output) */
++      u32 secure_id;        /**< [in] secure_id that identifies the ump buffer */
++      ump_uk_user new_user;         /**< [in] cookie stored with reference to the kernel mapping internals */
++
++} _ump_uk_switch_hw_usage_s;
++
++typedef struct _ump_uk_lock_s
++{
++      void *ctx;            /**< [in,out] user-kernel context (trashed on output) */
++      u32 secure_id;        /**< [in] secure_id that identifies the ump buffer */
++      ump_uk_lock_usage lock_usage;
++} _ump_uk_lock_s;
++
++typedef struct _ump_uk_unlock_s
++{
++      void *ctx;            /**< [in,out] user-kernel context (trashed on output) */
++      u32 secure_id;        /**< [in] secure_id that identifies the ump buffer */
++} _ump_uk_unlock_s;
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* __UMP_UK_TYPES_H__ */
+diff --git a/drivers/gpu/arm/mali400/ump/linux/license/gpl/ump_kernel_license.h b/drivers/gpu/arm/mali400/ump/linux/license/gpl/ump_kernel_license.h
+new file mode 100644
+index 0000000..698e206
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/linux/license/gpl/ump_kernel_license.h
+@@ -0,0 +1,31 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file ump_kernel_license.h
++ * Defines for the macro MODULE_LICENSE.
++ */
++
++#ifndef __UMP_KERNEL_LICENSE_H__
++#define __UMP_KERNEL_LICENSE_H__
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif
++
++#define UMP_KERNEL_LINUX_LICENSE     "GPL"
++#define UMP_LICENSE_IS_GPL 1
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* __UMP_KERNEL_LICENSE_H__ */
+diff --git a/drivers/gpu/arm/mali400/ump/linux/ump_ioctl.h b/drivers/gpu/arm/mali400/ump/linux/ump_ioctl.h
+new file mode 100644
+index 0000000..300f303
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/linux/ump_ioctl.h
+@@ -0,0 +1,62 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __UMP_IOCTL_H__
++#define __UMP_IOCTL_H__
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif
++
++#include <linux/types.h>
++#include <linux/ioctl.h>
++
++#include <ump_uk_types.h>
++
++#ifndef __user
++#define __user
++#endif
++
++
++/**
++ * @file UMP_ioctl.h
++ * This file describes the interface needed to use the Linux device driver.
++ * The interface is used by the userpace UMP driver.
++ */
++
++#define UMP_IOCTL_NR 0x90
++
++
++#define UMP_IOC_QUERY_API_VERSION _IOR(UMP_IOCTL_NR, _UMP_IOC_QUERY_API_VERSION, _ump_uk_api_version_s)
++#define UMP_IOC_ALLOCATE  _IOWR(UMP_IOCTL_NR,  _UMP_IOC_ALLOCATE,  _ump_uk_allocate_s)
++#define UMP_IOC_RELEASE  _IOR(UMP_IOCTL_NR,  _UMP_IOC_RELEASE,  _ump_uk_release_s)
++#define UMP_IOC_SIZE_GET  _IOWR(UMP_IOCTL_NR,  _UMP_IOC_SIZE_GET, _ump_uk_size_get_s)
++#define UMP_IOC_MSYNC     _IOW(UMP_IOCTL_NR,  _UMP_IOC_MSYNC, _ump_uk_msync_s)
++/* MALI_SEC */
++#ifdef CONFIG_ION_EXYNOS
++#define UMP_IOC_ION_IMPORT  _IOW(UMP_IOCTL_NR,  _UMP_IOC_ION_IMPORT, _ump_uk_ion_import_s)
++#endif
++#ifdef CONFIG_DMA_SHARED_BUFFER
++#define UMP_IOC_DMABUF_IMPORT  _IOW(UMP_IOCTL_NR,  _UMP_IOC_DMABUF_IMPORT,\
++                                      struct ump_uk_dmabuf)
++#endif
++
++#define UMP_IOC_CACHE_OPERATIONS_CONTROL _IOW(UMP_IOCTL_NR,  _UMP_IOC_CACHE_OPERATIONS_CONTROL, _ump_uk_cache_operations_control_s)
++#define UMP_IOC_SWITCH_HW_USAGE   _IOW(UMP_IOCTL_NR,  _UMP_IOC_SWITCH_HW_USAGE, _ump_uk_switch_hw_usage_s)
++#define UMP_IOC_LOCK          _IOW(UMP_IOCTL_NR,  _UMP_IOC_LOCK, _ump_uk_lock_s)
++#define UMP_IOC_UNLOCK        _IOW(UMP_IOCTL_NR,  _UMP_IOC_UNLOCK, _ump_uk_unlock_s)
++
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* __UMP_IOCTL_H__ */
+diff --git a/drivers/gpu/arm/mali400/ump/linux/ump_kernel_linux.c b/drivers/gpu/arm/mali400/ump/linux/ump_kernel_linux.c
+new file mode 100644
+index 0000000..9c903cf
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/linux/ump_kernel_linux.c
+@@ -0,0 +1,454 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include <linux/module.h>            /* kernel module definitions */
++#include <linux/fs.h>                /* file system operations */
++#include <linux/cdev.h>              /* character device definitions */
++#include <linux/ioport.h>            /* request_mem_region */
++#include <linux/mm.h>                /* memory management functions and types */
++#include <asm/uaccess.h>             /* user space access */
++#include <asm/atomic.h>
++#include <linux/device.h>
++#include <linux/debugfs.h>
++
++#include "arch/config.h"             /* Configuration for current platform. The symlinc for arch is set by Makefile */
++#include "ump_ioctl.h"
++#include "ump_kernel_common.h"
++#include "ump_kernel_interface.h"
++#include "ump_kernel_interface_ref_drv.h"
++#include "ump_kernel_descriptor_mapping.h"
++#include "ump_kernel_memory_backend.h"
++#include "ump_kernel_memory_backend_os.h"
++#include "ump_kernel_memory_backend_dedicated.h"
++#include "ump_kernel_license.h"
++
++#include "ump_osk.h"
++#include "ump_ukk.h"
++#include "ump_uk_types.h"
++#include "ump_ukk_wrappers.h"
++#include "ump_ukk_ref_wrappers.h"
++
++
++/* Module parameter to control log level */
++int ump_debug_level = 2;
++module_param(ump_debug_level, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); /* rw-rw-r-- */
++MODULE_PARM_DESC(ump_debug_level, "Higher number, more dmesg output");
++
++/* By default the module uses any available major, but it's possible to set it at load time to a specific number */
++int ump_major = 0;
++module_param(ump_major, int, S_IRUGO); /* r--r--r-- */
++MODULE_PARM_DESC(ump_major, "Device major number");
++
++/* Name of the UMP device driver */
++static char ump_dev_name[] = "ump"; /* should be const, but the functions we call requires non-cost */
++
++
++#if UMP_LICENSE_IS_GPL
++static struct dentry *ump_debugfs_dir = NULL;
++#endif
++
++/*
++ * The data which we attached to each virtual memory mapping request we get.
++ * Each memory mapping has a reference to the UMP memory it maps.
++ * We release this reference when the last memory mapping is unmapped.
++ */
++typedef struct ump_vma_usage_tracker
++{
++      int references;
++      ump_dd_handle handle;
++} ump_vma_usage_tracker;
++
++struct ump_device
++{
++      struct cdev cdev;
++#if UMP_LICENSE_IS_GPL
++      struct class * ump_class;
++#endif
++};
++
++/* The global variable containing the global device data */
++static struct ump_device ump_device;
++
++
++/* Forward declare static functions */
++static int ump_file_open(struct inode *inode, struct file *filp);
++static int ump_file_release(struct inode *inode, struct file *filp);
++#ifdef HAVE_UNLOCKED_IOCTL
++static long ump_file_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
++#else
++static int ump_file_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
++#endif
++static int ump_file_mmap(struct file * filp, struct vm_area_struct * vma);
++
++
++/* This variable defines the file operations this UMP device driver offer */
++static struct file_operations ump_fops =
++{
++      .owner   = THIS_MODULE,
++      .open    = ump_file_open,
++      .release = ump_file_release,
++#ifdef HAVE_UNLOCKED_IOCTL
++      .unlocked_ioctl   = ump_file_ioctl,
++#else
++      .ioctl   = ump_file_ioctl,
++#endif
++      .mmap    = ump_file_mmap
++};
++
++
++/* This function is called by Linux to initialize this module.
++ * All we do is initialize the UMP device driver.
++ */
++static int ump_initialize_module(void)
++{
++      _mali_osk_errcode_t err;
++
++      DBG_MSG(2, ("Inserting UMP device driver. Compiled: %s, time: %s\n", __DATE__, __TIME__));
++
++      err = ump_kernel_constructor();
++      if (_MALI_OSK_ERR_OK != err)
++      {
++              MSG_ERR(("UMP device driver init failed\n"));
++              return map_errcode(err);
++      }
++
++      MSG(("UMP device driver %s loaded\n", SVN_REV_STRING));
++      return 0;
++}
++
++
++
++/*
++ * This function is called by Linux to unload/terminate/exit/cleanup this module.
++ * All we do is terminate the UMP device driver.
++ */
++static void ump_cleanup_module(void)
++{
++      DBG_MSG(2, ("Unloading UMP device driver\n"));
++      ump_kernel_destructor();
++      DBG_MSG(2, ("Module unloaded\n"));
++}
++
++
++
++static ssize_t ump_memory_used_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
++{
++        char buf[64];
++        size_t r;
++        u32 mem = _ump_ukk_report_memory_usage();
++
++        r = snprintf(buf, 64, "%u\n", mem);
++        return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
++}
++
++static const struct file_operations ump_memory_usage_fops = {
++        .owner = THIS_MODULE,
++        .read = ump_memory_used_read,
++};
++
++/*
++ * Initialize the UMP device driver.
++ */
++int ump_kernel_device_initialize(void)
++{
++      int err;
++      dev_t dev = 0;
++#if UMP_LICENSE_IS_GPL
++      ump_debugfs_dir = debugfs_create_dir(ump_dev_name, NULL);
++      if (ERR_PTR(-ENODEV) == ump_debugfs_dir)
++      {
++                      ump_debugfs_dir = NULL;
++      }
++      else
++      {
++              debugfs_create_file("memory_usage", 0400, ump_debugfs_dir, NULL, &ump_memory_usage_fops);
++      }
++#endif
++
++      if (0 == ump_major)
++      {
++              /* auto select a major */
++              err = alloc_chrdev_region(&dev, 0, 1, ump_dev_name);
++              ump_major = MAJOR(dev);
++      }
++      else
++      {
++              /* use load time defined major number */
++              dev = MKDEV(ump_major, 0);
++              err = register_chrdev_region(dev, 1, ump_dev_name);
++      }
++
++      if (0 == err)
++      {
++              memset(&ump_device, 0, sizeof(ump_device));
++
++              /* initialize our char dev data */
++              cdev_init(&ump_device.cdev, &ump_fops);
++              ump_device.cdev.owner = THIS_MODULE;
++              ump_device.cdev.ops = &ump_fops;
++
++              /* register char dev with the kernel */
++              err = cdev_add(&ump_device.cdev, dev, 1/*count*/);
++              if (0 == err)
++              {
++
++#if UMP_LICENSE_IS_GPL
++                      ump_device.ump_class = class_create(THIS_MODULE, ump_dev_name);
++                      if (IS_ERR(ump_device.ump_class))
++                      {
++                              err = PTR_ERR(ump_device.ump_class);
++                      }
++                      else
++                      {
++                              struct device * mdev;
++                              mdev = device_create(ump_device.ump_class, NULL, dev, NULL, ump_dev_name);
++                              if (!IS_ERR(mdev))
++                              {
++                                      return 0;
++                              }
++
++                              err = PTR_ERR(mdev);
++                      }
++                      cdev_del(&ump_device.cdev);
++#else
++                      return 0;
++#endif
++              }
++
++              unregister_chrdev_region(dev, 1);
++      }
++
++      return err;
++}
++
++
++
++/*
++ * Terminate the UMP device driver
++ */
++void ump_kernel_device_terminate(void)
++{
++      dev_t dev = MKDEV(ump_major, 0);
++
++#if UMP_LICENSE_IS_GPL
++      device_destroy(ump_device.ump_class, dev);
++      class_destroy(ump_device.ump_class);
++#endif
++
++      /* unregister char device */
++      cdev_del(&ump_device.cdev);
++
++      /* free major */
++      unregister_chrdev_region(dev, 1);
++
++#if UMP_LICENSE_IS_GPL
++      if(ump_debugfs_dir)
++              debugfs_remove_recursive(ump_debugfs_dir);
++#endif
++}
++
++/*
++ * Open a new session. User space has called open() on us.
++ */
++static int ump_file_open(struct inode *inode, struct file *filp)
++{
++      struct ump_session_data * session_data;
++      _mali_osk_errcode_t err;
++
++      /* input validation */
++      if (0 != MINOR(inode->i_rdev))
++      {
++              MSG_ERR(("Minor not zero in ump_file_open()\n"));
++              return -ENODEV;
++      }
++
++      /* Call the OS-Independent UMP Open function */
++      err = _ump_ukk_open((void**) &session_data );
++      if( _MALI_OSK_ERR_OK != err )
++      {
++              MSG_ERR(("Ump failed to open a new session\n"));
++              return map_errcode( err );
++      }
++
++      filp->private_data = (void*)session_data;
++      filp->f_pos = 0;
++
++      return 0; /* success */
++}
++
++
++
++/*
++ * Close a session. User space has called close() or crashed/terminated.
++ */
++static int ump_file_release(struct inode *inode, struct file *filp)
++{
++      _mali_osk_errcode_t err;
++
++      err = _ump_ukk_close((void**) &filp->private_data );
++      if( _MALI_OSK_ERR_OK != err )
++      {
++              return map_errcode( err );
++      }
++
++      return 0;  /* success */
++}
++
++
++
++/*
++ * Handle IOCTL requests.
++ */
++#ifdef HAVE_UNLOCKED_IOCTL
++static long ump_file_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
++#else
++static int ump_file_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
++#endif
++{
++      int err = -ENOTTY;
++      void __user * argument;
++      struct ump_session_data * session_data;
++
++#ifndef HAVE_UNLOCKED_IOCTL
++      (void)inode; /* inode not used */
++#endif
++
++      session_data = (struct ump_session_data *)filp->private_data;
++      if (NULL == session_data)
++      {
++              MSG_ERR(("No session data attached to file object\n"));
++              return -ENOTTY;
++      }
++
++      /* interpret the argument as a user pointer to something */
++      argument = (void __user *)arg;
++
++      switch (cmd)
++      {
++              case UMP_IOC_QUERY_API_VERSION:
++                      err = ump_get_api_version_wrapper((u32 __user *)argument, session_data);
++                      break;
++
++              case UMP_IOC_ALLOCATE :
++                      err = ump_allocate_wrapper((u32 __user *)argument, session_data);
++                      break;
++/* MALI_SEC */
++#ifdef CONFIG_DMA_SHARED_BUFFER
++              case UMP_IOC_DMABUF_IMPORT:
++                      err = ump_dmabuf_import_wrapper((u32 __user *)argument,
++                                                      session_data);
++                      break;
++#endif
++
++              case UMP_IOC_RELEASE:
++                      err = ump_release_wrapper((u32 __user *)argument, session_data);
++                      break;
++
++              case UMP_IOC_SIZE_GET:
++                      err = ump_size_get_wrapper((u32 __user *)argument, session_data);
++                      break;
++
++              case UMP_IOC_MSYNC:
++                      err = ump_msync_wrapper((u32 __user *)argument, session_data);
++                      break;
++
++              case UMP_IOC_CACHE_OPERATIONS_CONTROL:
++                      err = ump_cache_operations_control_wrapper((u32 __user *)argument, session_data);
++                      break;
++
++              case UMP_IOC_SWITCH_HW_USAGE:
++                      err = ump_switch_hw_usage_wrapper((u32 __user *)argument, session_data);
++                      break;
++
++              case UMP_IOC_LOCK:
++                      err = ump_lock_wrapper((u32 __user *)argument, session_data);
++                      break;
++
++              case UMP_IOC_UNLOCK:
++                      err = ump_unlock_wrapper((u32 __user *)argument, session_data);
++                      break;
++
++              default:
++                      DBG_MSG(1, ("No handler for IOCTL. cmd: 0x%08x, arg: 0x%08lx\n", cmd, arg));
++                      err = -EFAULT;
++                      break;
++      }
++
++      return err;
++}
++
++/*
++ * Handle from OS to map specified virtual memory to specified UMP memory.
++ */
++static int ump_file_mmap(struct file * filp, struct vm_area_struct * vma)
++{
++      _ump_uk_map_mem_s args;
++      _mali_osk_errcode_t err;
++      struct ump_session_data * session_data;
++
++      /* Validate the session data */
++      session_data = (struct ump_session_data *)filp->private_data;
++      if (NULL == session_data || NULL == session_data->cookies_map->table->mappings) /* MALI_SEC */
++      {
++              MSG_ERR(("mmap() called without any session data available\n"));
++              return -EFAULT;
++      }
++
++      /* Re-pack the arguments that mmap() packed for us */
++      args.ctx = session_data;
++      args.phys_addr = 0;
++      args.size = vma->vm_end - vma->vm_start;
++      args._ukk_private = vma;
++      args.secure_id = vma->vm_pgoff;
++      args.is_cached = 0;
++
++      if (!(vma->vm_flags & VM_SHARED))
++      {
++              args.is_cached = 1;
++              vma->vm_flags = vma->vm_flags | VM_SHARED | VM_MAYSHARE  ;
++              DBG_MSG(3, ("UMP Map function: Forcing the CPU to use cache\n"));
++      }
++      /* By setting this flag, during a process fork; the child process will not have the parent UMP mappings */
++      vma->vm_flags |= VM_DONTCOPY;
++
++      DBG_MSG(4, ("UMP vma->flags: %x\n", vma->vm_flags ));
++
++      /* Call the common mmap handler */
++      err = _ump_ukk_map_mem( &args );
++      if ( _MALI_OSK_ERR_OK != err)
++      {
++              MSG_ERR(("_ump_ukk_map_mem() failed in function ump_file_mmap()"));
++              return map_errcode( err );
++      }
++
++      return 0; /* success */
++}
++
++/* Export UMP kernel space API functions */
++EXPORT_SYMBOL(ump_dd_secure_id_get);
++EXPORT_SYMBOL(ump_dd_handle_create_from_secure_id);
++EXPORT_SYMBOL(ump_dd_phys_block_count_get);
++EXPORT_SYMBOL(ump_dd_phys_block_get);
++EXPORT_SYMBOL(ump_dd_phys_blocks_get);
++EXPORT_SYMBOL(ump_dd_size_get);
++EXPORT_SYMBOL(ump_dd_reference_add);
++EXPORT_SYMBOL(ump_dd_reference_release);
++
++/* Export our own extended kernel space allocator */
++EXPORT_SYMBOL(ump_dd_handle_create_from_phys_blocks);
++
++/* Setup init and exit functions for this module */
++module_init(ump_initialize_module);
++module_exit(ump_cleanup_module);
++
++/* And some module informatio */
++MODULE_LICENSE(UMP_KERNEL_LINUX_LICENSE);
++MODULE_AUTHOR("ARM Ltd.");
++MODULE_VERSION(SVN_REV_STRING);
+diff --git a/drivers/gpu/arm/mali400/ump/linux/ump_kernel_linux.h b/drivers/gpu/arm/mali400/ump/linux/ump_kernel_linux.h
+new file mode 100644
+index 0000000..a23a705
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/linux/ump_kernel_linux.h
+@@ -0,0 +1,18 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef __UMP_KERNEL_LINUX_H__
++#define __UMP_KERNEL_LINUX_H__
++
++int ump_kernel_device_initialize(void);
++void ump_kernel_device_terminate(void);
++
++
++#endif /* __UMP_KERNEL_H__ */
+diff --git a/drivers/gpu/arm/mali400/ump/linux/ump_kernel_memory_backend_dedicated.c b/drivers/gpu/arm/mali400/ump/linux/ump_kernel_memory_backend_dedicated.c
+new file mode 100644
+index 0000000..c309d63
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/linux/ump_kernel_memory_backend_dedicated.c
+@@ -0,0 +1,288 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/* needed to detect kernel version specific code */
++#include <linux/version.h>
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
++#include <linux/semaphore.h>
++#else /* pre 2.6.26 the file was in the arch specific location */
++#include <asm/semaphore.h>
++#endif
++
++#include <linux/mm.h>
++#include <linux/slab.h>
++#include <asm/atomic.h>
++#include <linux/vmalloc.h>
++#include "ump_kernel_common.h"
++#include "ump_kernel_memory_backend.h"
++
++
++
++#define UMP_BLOCK_SIZE (256UL * 1024UL)  /* 256kB, remember to keep the ()s */
++
++
++
++typedef struct block_info
++{
++      struct block_info * next;
++} block_info;
++
++
++
++typedef struct block_allocator
++{
++      struct semaphore mutex;
++      block_info * all_blocks;
++      block_info * first_free;
++      u32 base;
++      u32 num_blocks;
++      u32 num_free;
++} block_allocator;
++
++
++static void block_allocator_shutdown(ump_memory_backend * backend);
++static int block_allocator_allocate(void* ctx, ump_dd_mem * mem);
++static void block_allocator_release(void * ctx, ump_dd_mem * handle);
++static inline u32 get_phys(block_allocator * allocator, block_info * block);
++static u32 block_allocator_stat(struct ump_memory_backend *backend);
++
++
++
++/*
++ * Create dedicated memory backend
++ */
++ump_memory_backend * ump_block_allocator_create(u32 base_address, u32 size)
++{
++      ump_memory_backend * backend;
++      block_allocator * allocator;
++      u32 usable_size;
++      u32 num_blocks;
++
++      usable_size = (size + UMP_BLOCK_SIZE - 1) & ~(UMP_BLOCK_SIZE - 1);
++      num_blocks = usable_size / UMP_BLOCK_SIZE;
++
++      if (0 == usable_size)
++      {
++              DBG_MSG(1, ("Memory block of size %u is unusable\n", size));
++              return NULL;
++      }
++
++      DBG_MSG(5, ("Creating dedicated UMP memory backend. Base address: 0x%08x, size: 0x%08x\n", base_address, size));
++      DBG_MSG(6, ("%u usable bytes which becomes %u blocks\n", usable_size, num_blocks));
++
++      backend = kzalloc(sizeof(ump_memory_backend), GFP_KERNEL);
++      if (NULL != backend)
++      {
++              allocator = kmalloc(sizeof(block_allocator), GFP_KERNEL);
++              if (NULL != allocator)
++              {
++                      allocator->all_blocks = kmalloc(sizeof(block_allocator) * num_blocks, GFP_KERNEL);
++                      if (NULL != allocator->all_blocks)
++                      {
++                              int i;
++
++                              allocator->first_free = NULL;
++                              allocator->num_blocks = num_blocks;
++                              allocator->num_free = num_blocks;
++                              allocator->base = base_address;
++                              sema_init(&allocator->mutex, 1);
++
++                              for (i = 0; i < num_blocks; i++)
++                              {
++                                      allocator->all_blocks[i].next = allocator->first_free;
++                                      allocator->first_free = &allocator->all_blocks[i];
++                              }
++
++                              backend->ctx = allocator;
++                              backend->allocate = block_allocator_allocate;
++                              backend->release = block_allocator_release;
++                              backend->shutdown = block_allocator_shutdown;
++                              backend->stat = block_allocator_stat;
++                              backend->pre_allocate_physical_check = NULL;
++                              backend->adjust_to_mali_phys = NULL;
++                              /* MALI_SEC */
++                              backend->get = NULL;
++                              backend->set = NULL;
++
++                              return backend;
++                      }
++                      kfree(allocator);
++              }
++              kfree(backend);
++      }
++
++      return NULL;
++}
++
++
++
++/*
++ * Destroy specified dedicated memory backend
++ */
++static void block_allocator_shutdown(ump_memory_backend * backend)
++{
++      block_allocator * allocator;
++
++      BUG_ON(!backend);
++      BUG_ON(!backend->ctx);
++
++      allocator = (block_allocator*)backend->ctx;
++
++      DBG_MSG_IF(1, allocator->num_free != allocator->num_blocks, ("%u blocks still in use during shutdown\n", allocator->num_blocks - allocator->num_free));
++
++      kfree(allocator->all_blocks);
++      kfree(allocator);
++      kfree(backend);
++}
++
++
++
++static int block_allocator_allocate(void* ctx, ump_dd_mem * mem)
++{
++      block_allocator * allocator;
++      u32 left;
++      block_info * last_allocated = NULL;
++      int i = 0;
++
++      BUG_ON(!ctx);
++      BUG_ON(!mem);
++
++      allocator = (block_allocator*)ctx;
++      left = mem->size_bytes;
++
++      BUG_ON(!left);
++      BUG_ON(!&allocator->mutex);
++
++      mem->nr_blocks = ((left + UMP_BLOCK_SIZE - 1) & ~(UMP_BLOCK_SIZE - 1)) / UMP_BLOCK_SIZE;
++      mem->block_array = (ump_dd_physical_block*)vmalloc(sizeof(ump_dd_physical_block) * mem->nr_blocks);
++      if (NULL == mem->block_array)
++      {
++              MSG_ERR(("Failed to allocate block array\n"));
++              return 0;
++      }
++
++      if (down_interruptible(&allocator->mutex))
++      {
++              MSG_ERR(("Could not get mutex to do block_allocate\n"));
++              return 0;
++      }
++
++      mem->size_bytes = 0;
++
++      while ((left > 0) && (allocator->first_free))
++      {
++              block_info * block;
++
++              block = allocator->first_free;
++              allocator->first_free = allocator->first_free->next;
++              block->next = last_allocated;
++              last_allocated = block;
++              allocator->num_free--;
++
++              mem->block_array[i].addr = get_phys(allocator, block);
++              mem->block_array[i].size = UMP_BLOCK_SIZE;
++              mem->size_bytes += UMP_BLOCK_SIZE;
++
++              i++;
++
++              if (left < UMP_BLOCK_SIZE) left = 0;
++              else left -= UMP_BLOCK_SIZE;
++      }
++
++      if (left)
++      {
++              block_info * block;
++              /* release all memory back to the pool */
++              while (last_allocated)
++              {
++                      block = last_allocated->next;
++                      last_allocated->next = allocator->first_free;
++                      allocator->first_free = last_allocated;
++                      last_allocated = block;
++                      allocator->num_free++;
++              }
++
++              vfree(mem->block_array);
++              mem->backend_info = NULL;
++              mem->block_array = NULL;
++
++              DBG_MSG(4, ("Could not find a mem-block for the allocation.\n"));
++              up(&allocator->mutex);
++
++              return 0;
++      }
++
++      mem->backend_info = last_allocated;
++
++      up(&allocator->mutex);
++      mem->is_cached=0;
++
++      return 1;
++}
++
++
++
++static void block_allocator_release(void * ctx, ump_dd_mem * handle)
++{
++      block_allocator * allocator;
++      block_info * block, * next;
++
++      BUG_ON(!ctx);
++      BUG_ON(!handle);
++
++      allocator = (block_allocator*)ctx;
++      block = (block_info*)handle->backend_info;
++      BUG_ON(!block);
++
++      if (down_interruptible(&allocator->mutex))
++      {
++              MSG_ERR(("Allocator release: Failed to get mutex - memory leak\n"));
++              return;
++      }
++
++      while (block)
++      {
++              next = block->next;
++
++              BUG_ON( (block < allocator->all_blocks) || (block > (allocator->all_blocks + allocator->num_blocks)));
++
++              block->next = allocator->first_free;
++              allocator->first_free = block;
++              allocator->num_free++;
++
++              block = next;
++      }
++      DBG_MSG(3, ("%d blocks free after release call\n", allocator->num_free));
++      up(&allocator->mutex);
++
++      vfree(handle->block_array);
++      handle->block_array = NULL;
++}
++
++
++
++/*
++ * Helper function for calculating the physical base adderss of a memory block
++ */
++static inline u32 get_phys(block_allocator * allocator, block_info * block)
++{
++      return allocator->base + ((block - allocator->all_blocks) * UMP_BLOCK_SIZE);
++}
++
++static u32 block_allocator_stat(struct ump_memory_backend *backend)
++{
++      block_allocator *allocator;
++      BUG_ON(!backend);
++      allocator = (block_allocator*)backend->ctx;
++      BUG_ON(!allocator);
++
++      return (allocator->num_blocks - allocator->num_free)* UMP_BLOCK_SIZE;
++}
+diff --git a/drivers/gpu/arm/mali400/ump/linux/ump_kernel_memory_backend_dedicated.h b/drivers/gpu/arm/mali400/ump/linux/ump_kernel_memory_backend_dedicated.h
+new file mode 100644
+index 0000000..85432a4
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/linux/ump_kernel_memory_backend_dedicated.h
+@@ -0,0 +1,23 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file ump_kernel_memory_backend_dedicated.h
++ */
++
++#ifndef __UMP_KERNEL_MEMORY_BACKEND_DEDICATED_H__
++#define __UMP_KERNEL_MEMORY_BACKEND_DEDICATED_H__
++
++#include "ump_kernel_memory_backend.h"
++
++ump_memory_backend * ump_block_allocator_create(u32 base_address, u32 size);
++
++#endif /* __UMP_KERNEL_MEMORY_BACKEND_DEDICATED_H__ */
++
+diff --git a/drivers/gpu/arm/mali400/ump/linux/ump_kernel_memory_backend_os.c b/drivers/gpu/arm/mali400/ump/linux/ump_kernel_memory_backend_os.c
+new file mode 100644
+index 0000000..4e635ea
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/linux/ump_kernel_memory_backend_os.c
+@@ -0,0 +1,261 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/* needed to detect kernel version specific code */
++#include <linux/version.h>
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
++#include <linux/semaphore.h>
++#else /* pre 2.6.26 the file was in the arch specific location */
++#include <asm/semaphore.h>
++#endif
++
++#include <linux/dma-mapping.h>
++#include <linux/mm.h>
++#include <linux/slab.h>
++#include <asm/atomic.h>
++#include <linux/vmalloc.h>
++#include <asm/cacheflush.h>
++#include "ump_kernel_common.h"
++#include "ump_kernel_memory_backend.h"
++
++
++
++typedef struct os_allocator
++{
++      struct semaphore mutex;
++      u32 num_pages_max;       /**< Maximum number of pages to allocate from the OS */
++      u32 num_pages_allocated; /**< Number of pages allocated from the OS */
++} os_allocator;
++
++
++
++static void os_free(void* ctx, ump_dd_mem * descriptor);
++static int os_allocate(void* ctx, ump_dd_mem * descriptor);
++static void os_memory_backend_destroy(ump_memory_backend * backend);
++static u32 os_stat(struct ump_memory_backend *backend);
++
++
++
++/*
++ * Create OS memory backend
++ */
++ump_memory_backend * ump_os_memory_backend_create(const int max_allocation)
++{
++      ump_memory_backend * backend;
++      os_allocator * info;
++
++      info = kmalloc(sizeof(os_allocator), GFP_KERNEL);
++      if (NULL == info)
++      {
++              return NULL;
++      }
++
++      info->num_pages_max = max_allocation >> PAGE_SHIFT;
++      info->num_pages_allocated = 0;
++
++      sema_init(&info->mutex, 1);
++
++      backend = kmalloc(sizeof(ump_memory_backend), GFP_KERNEL);
++      if (NULL == backend)
++      {
++              kfree(info);
++              return NULL;
++      }
++
++      backend->ctx = info;
++      backend->allocate = os_allocate;
++      backend->release = os_free;
++      backend->shutdown = os_memory_backend_destroy;
++      backend->stat = os_stat;
++      backend->pre_allocate_physical_check = NULL;
++      backend->adjust_to_mali_phys = NULL;
++      /* MALI_SEC */
++      backend->get = NULL;
++      backend->set = NULL;
++
++      return backend;
++}
++
++
++
++/*
++ * Destroy specified OS memory backend
++ */
++static void os_memory_backend_destroy(ump_memory_backend * backend)
++{
++      os_allocator * info = (os_allocator*)backend->ctx;
++
++      DBG_MSG_IF(1, 0 != info->num_pages_allocated, ("%d pages still in use during shutdown\n", info->num_pages_allocated));
++
++      kfree(info);
++      kfree(backend);
++}
++
++
++
++/*
++ * Allocate UMP memory
++ */
++static int os_allocate(void* ctx, ump_dd_mem * descriptor)
++{
++      u32 left;
++      os_allocator * info;
++      int pages_allocated = 0;
++      int is_cached;
++
++      BUG_ON(!descriptor);
++      BUG_ON(!ctx);
++
++      info = (os_allocator*)ctx;
++      left = descriptor->size_bytes;
++      is_cached = descriptor->is_cached;
++
++      if (down_interruptible(&info->mutex))
++      {
++              DBG_MSG(1, ("Failed to get mutex in os_free\n"));
++              return 0; /* failure */
++      }
++
++      descriptor->backend_info = NULL;
++      descriptor->nr_blocks = ((left + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) >> PAGE_SHIFT;
++
++      DBG_MSG(5, ("Allocating page array. Size: %lu\n", descriptor->nr_blocks * sizeof(ump_dd_physical_block)));
++
++      descriptor->block_array = (ump_dd_physical_block *)vmalloc(sizeof(ump_dd_physical_block) * descriptor->nr_blocks);
++      if (NULL == descriptor->block_array)
++      {
++              up(&info->mutex);
++              DBG_MSG(1, ("Block array could not be allocated\n"));
++              return 0; /* failure */
++      }
++
++      while (left > 0 && ((info->num_pages_allocated + pages_allocated) < info->num_pages_max))
++      {
++              struct page * new_page;
++
++              if (is_cached)
++              {
++                      new_page = alloc_page(GFP_HIGHUSER | __GFP_ZERO | __GFP_REPEAT | __GFP_NOWARN);
++              } else
++              {
++                      new_page = alloc_page(GFP_HIGHUSER | __GFP_ZERO | __GFP_REPEAT | __GFP_NOWARN | __GFP_COLD);
++              }
++              if (NULL == new_page)
++              {
++                      MSG_ERR(("UMP memory allocated: Out of Memory !!\n"));
++                      break;
++              }
++
++              /* Ensure page caches are flushed. */
++              if ( is_cached )
++              {
++                      descriptor->block_array[pages_allocated].addr = page_to_phys(new_page);
++                      descriptor->block_array[pages_allocated].size = PAGE_SIZE;
++              } else
++              {
++                      descriptor->block_array[pages_allocated].addr = dma_map_page(NULL, new_page, 0, PAGE_SIZE, DMA_BIDIRECTIONAL );
++                      descriptor->block_array[pages_allocated].size = PAGE_SIZE;
++              }
++
++              DBG_MSG(5, ("Allocated page 0x%08lx cached: %d\n", descriptor->block_array[pages_allocated].addr, is_cached));
++
++              if (left < PAGE_SIZE)
++              {
++                      left = 0;
++              }
++              else
++              {
++                      left -= PAGE_SIZE;
++              }
++
++              pages_allocated++;
++      }
++
++      DBG_MSG(5, ("Alloce for ID:%2d got %d pages, cached: %d\n", descriptor->secure_id,  pages_allocated));
++
++      if (left)
++      {
++              DBG_MSG(1, ("Failed to allocate needed pages\n"));
++              DBG_MSG(1, ("UMP memory allocated: %d kB  Configured maximum OS memory usage: %d kB\n",
++                               (pages_allocated * _MALI_OSK_CPU_PAGE_SIZE)/1024, (info->num_pages_max* _MALI_OSK_CPU_PAGE_SIZE)/1024));
++
++              while(pages_allocated)
++              {
++                      pages_allocated--;
++                      if ( !is_cached )
++                      {
++                              dma_unmap_page(NULL, descriptor->block_array[pages_allocated].addr, PAGE_SIZE, DMA_BIDIRECTIONAL);
++                      }
++                      __free_page(pfn_to_page(descriptor->block_array[pages_allocated].addr >> PAGE_SHIFT) );
++              }
++
++              up(&info->mutex);
++
++              return 0; /* failure */
++      }
++
++      info->num_pages_allocated += pages_allocated;
++
++      DBG_MSG(6, ("%d out of %d pages now allocated\n", info->num_pages_allocated, info->num_pages_max));
++
++      up(&info->mutex);
++
++      return 1; /* success*/
++}
++
++
++/*
++ * Free specified UMP memory
++ */
++static void os_free(void* ctx, ump_dd_mem * descriptor)
++{
++      os_allocator * info;
++      int i;
++
++      BUG_ON(!ctx);
++      BUG_ON(!descriptor);
++
++      info = (os_allocator*)ctx;
++
++      BUG_ON(descriptor->nr_blocks > info->num_pages_allocated);
++
++      if (down_interruptible(&info->mutex))
++      {
++              DBG_MSG(1, ("Failed to get mutex in os_free\n"));
++              return;
++      }
++
++      DBG_MSG(5, ("Releasing %lu OS pages\n", descriptor->nr_blocks));
++
++      info->num_pages_allocated -= descriptor->nr_blocks;
++
++      up(&info->mutex);
++
++      for ( i = 0; i < descriptor->nr_blocks; i++)
++      {
++              DBG_MSG(6, ("Freeing physical page. Address: 0x%08lx\n", descriptor->block_array[i].addr));
++              if ( ! descriptor->is_cached)
++              {
++                      dma_unmap_page(NULL, descriptor->block_array[i].addr, PAGE_SIZE, DMA_BIDIRECTIONAL);
++              }
++              __free_page(pfn_to_page(descriptor->block_array[i].addr>>PAGE_SHIFT) );
++      }
++
++      vfree(descriptor->block_array);
++}
++
++
++static u32 os_stat(struct ump_memory_backend *backend)
++{
++      os_allocator *info;
++      info = (os_allocator*)backend->ctx;
++      return info->num_pages_allocated * _MALI_OSK_MALI_PAGE_SIZE;
++}
+diff --git a/drivers/gpu/arm/mali400/ump/linux/ump_kernel_memory_backend_os.h b/drivers/gpu/arm/mali400/ump/linux/ump_kernel_memory_backend_os.h
+new file mode 100644
+index 0000000..82e708f
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/linux/ump_kernel_memory_backend_os.h
+@@ -0,0 +1,23 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file ump_kernel_memory_backend_os.h
++ */
++
++#ifndef __UMP_KERNEL_MEMORY_BACKEND_OS_H__
++#define __UMP_KERNEL_MEMORY_BACKEND_OS_H__
++
++#include "ump_kernel_memory_backend.h"
++
++ump_memory_backend * ump_os_memory_backend_create(const int max_allocation);
++
++#endif /* __UMP_KERNEL_MEMORY_BACKEND_OS_H__ */
++
+diff --git a/drivers/gpu/arm/mali400/ump/linux/ump_memory_backend.c b/drivers/gpu/arm/mali400/ump/linux/ump_memory_backend.c
+new file mode 100644
+index 0000000..a05c416
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/linux/ump_memory_backend.c
+@@ -0,0 +1,78 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#include <linux/module.h>            /* kernel module definitions */
++#include <linux/ioport.h>            /* request_mem_region */
++
++#include "arch/config.h"             /* Configuration for current platform. The symlink for arch is set by Makefile */
++
++#include "ump_osk.h"
++#include "ump_kernel_common.h"
++#include "ump_kernel_memory_backend_os.h"
++#include "ump_kernel_memory_backend_dedicated.h"
++
++/* Configure which dynamic memory allocator to use */
++int ump_backend = ARCH_UMP_BACKEND_DEFAULT;
++module_param(ump_backend, int, S_IRUGO); /* r--r--r-- */
++MODULE_PARM_DESC(ump_backend, "0 = dedicated memory backend (default), 1 = OS memory backend");
++
++/* The base address of the memory block for the dedicated memory backend */
++unsigned int ump_memory_address = ARCH_UMP_MEMORY_ADDRESS_DEFAULT;
++module_param(ump_memory_address, uint, S_IRUGO); /* r--r--r-- */
++MODULE_PARM_DESC(ump_memory_address, "The physical address to map for the dedicated memory backend");
++
++/* The size of the memory block for the dedicated memory backend */
++unsigned int ump_memory_size = ARCH_UMP_MEMORY_SIZE_DEFAULT;
++module_param(ump_memory_size, uint, S_IRUGO); /* r--r--r-- */
++MODULE_PARM_DESC(ump_memory_size, "The size of fixed memory to map in the dedicated memory backend");
++
++ump_memory_backend* ump_memory_backend_create ( void )
++{
++      ump_memory_backend * backend = NULL;
++
++      /* Create the dynamic memory allocator backend */
++      if (0 == ump_backend)
++      {
++              DBG_MSG(2, ("Using dedicated memory backend\n"));
++
++              DBG_MSG(2, ("Requesting dedicated memory: 0x%08x, size: %u\n", ump_memory_address, ump_memory_size));
++              /* Ask the OS if we can use the specified physical memory */
++              if (NULL == request_mem_region(ump_memory_address, ump_memory_size, "UMP Memory"))
++              {
++                      MSG_ERR(("Failed to request memory region (0x%08X - 0x%08X). Is Mali DD already loaded?\n", ump_memory_address, ump_memory_address + ump_memory_size - 1));
++                      return NULL;
++              }
++              backend = ump_block_allocator_create(ump_memory_address, ump_memory_size);
++      }
++      else if (1 == ump_backend)
++      {
++              DBG_MSG(2, ("Using OS memory backend, allocation limit: %d\n", ump_memory_size));
++              backend = ump_os_memory_backend_create(ump_memory_size);
++      }
++/* MALI_SEC */
++#ifdef CONFIG_UMP_VCM_ALLOC
++      else if (2 == ump_backend)
++      {
++              DBG_MSG(2, ("Using VCM memory backend, allocation limit: %d\n", ump_memory_size));
++              backend = ump_vcm_memory_backend_create(ump_memory_size);
++      }
++#endif
++
++      return backend;
++}
++
++void ump_memory_backend_destroy( void )
++{
++      if (0 == ump_backend)
++      {
++              DBG_MSG(2, ("Releasing dedicated memory: 0x%08x\n", ump_memory_address));
++              release_mem_region(ump_memory_address, ump_memory_size);
++      }
++}
+diff --git a/drivers/gpu/arm/mali400/ump/linux/ump_osk_atomics.c b/drivers/gpu/arm/mali400/ump/linux/ump_osk_atomics.c
+new file mode 100644
+index 0000000..6ebaa0a
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/linux/ump_osk_atomics.c
+@@ -0,0 +1,27 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file ump_osk_atomics.c
++ * Implementation of the OS abstraction layer for the UMP kernel device driver
++ */
++
++#include "ump_osk.h"
++#include <asm/atomic.h>
++
++int _ump_osk_atomic_dec_and_read( _mali_osk_atomic_t *atom )
++{
++      return atomic_dec_return((atomic_t *)&atom->u.val);
++}
++
++int _ump_osk_atomic_inc_and_read( _mali_osk_atomic_t *atom )
++{
++      return atomic_inc_return((atomic_t *)&atom->u.val);
++}
+diff --git a/drivers/gpu/arm/mali400/ump/linux/ump_osk_low_level_mem.c b/drivers/gpu/arm/mali400/ump/linux/ump_osk_low_level_mem.c
+new file mode 100644
+index 0000000..6f1b6ff
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/linux/ump_osk_low_level_mem.c
+@@ -0,0 +1,352 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file ump_osk_memory.c
++ * Implementation of the OS abstraction layer for the kernel device driver
++ */
++
++/* needed to detect kernel version specific code */
++#include <linux/version.h>
++
++#include "ump_osk.h"
++#include "ump_uk_types.h"
++#include "ump_ukk.h"
++#include "ump_kernel_common.h"
++#include <linux/module.h>            /* kernel module definitions */
++#include <linux/kernel.h>
++#include <linux/mm.h>
++#include <linux/sched.h> /* MALI_SEC */
++#include <linux/slab.h>
++
++#include <asm/memory.h>
++#include <asm/uaccess.h>                      /* to verify pointers from user space */
++#include <asm/cacheflush.h>
++#include <linux/dma-mapping.h>
++
++typedef struct ump_vma_usage_tracker
++{
++      atomic_t references;
++      ump_memory_allocation *descriptor;
++} ump_vma_usage_tracker;
++
++static void ump_vma_open(struct vm_area_struct * vma);
++static void ump_vma_close(struct vm_area_struct * vma);
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
++static int ump_cpu_page_fault_handler(struct vm_area_struct *vma, struct vm_fault *vmf);
++#else
++static unsigned long ump_cpu_page_fault_handler(struct vm_area_struct * vma, unsigned long address);
++#endif
++
++static struct vm_operations_struct ump_vm_ops =
++{
++      .open = ump_vma_open,
++      .close = ump_vma_close,
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
++      .fault = ump_cpu_page_fault_handler
++#else
++      .nopfn = ump_cpu_page_fault_handler
++#endif
++};
++
++/*
++ * Page fault for VMA region
++ * This should never happen since we always map in the entire virtual memory range.
++ */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
++static int ump_cpu_page_fault_handler(struct vm_area_struct *vma, struct vm_fault *vmf)
++#else
++static unsigned long ump_cpu_page_fault_handler(struct vm_area_struct * vma, unsigned long address)
++#endif
++{
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
++      void __user * address;
++      address = vmf->virtual_address;
++#endif
++      MSG_ERR(("Page-fault in UMP memory region caused by the CPU\n"));
++      MSG_ERR(("VMA: 0x%08lx, virtual address: 0x%08lx\n", (unsigned long)vma, address));
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
++      return VM_FAULT_SIGBUS;
++#else
++      return NOPFN_SIGBUS;
++#endif
++}
++
++static void ump_vma_open(struct vm_area_struct * vma)
++{
++      ump_vma_usage_tracker * vma_usage_tracker;
++      int new_val;
++
++      vma_usage_tracker = (ump_vma_usage_tracker*)vma->vm_private_data;
++      BUG_ON(NULL == vma_usage_tracker);
++
++      new_val = atomic_inc_return(&vma_usage_tracker->references);
++
++      DBG_MSG(4, ("VMA open, VMA reference count incremented. VMA: 0x%08lx, reference count: %d\n", (unsigned long)vma, new_val));
++}
++
++static void ump_vma_close(struct vm_area_struct * vma)
++{
++      ump_vma_usage_tracker * vma_usage_tracker;
++      _ump_uk_unmap_mem_s args;
++      int new_val;
++
++      vma_usage_tracker = (ump_vma_usage_tracker*)vma->vm_private_data;
++      BUG_ON(NULL == vma_usage_tracker);
++
++      new_val = atomic_dec_return(&vma_usage_tracker->references);
++
++      DBG_MSG(4, ("VMA close, VMA reference count decremented. VMA: 0x%08lx, reference count: %d\n", (unsigned long)vma, new_val));
++
++      if (0 == new_val)
++      {
++              ump_memory_allocation * descriptor;
++
++              descriptor = vma_usage_tracker->descriptor;
++
++              args.ctx = descriptor->ump_session;
++              args.cookie = descriptor->cookie;
++              args.mapping = descriptor->mapping;
++              args.size = descriptor->size;
++
++              args._ukk_private = NULL; /** @note unused */
++
++              DBG_MSG(4, ("No more VMA references left, releasing UMP memory\n"));
++              _ump_ukk_unmap_mem( & args );
++
++              /* vma_usage_tracker is free()d by _ump_osk_mem_mapregion_term() */
++      }
++}
++
++_mali_osk_errcode_t _ump_osk_mem_mapregion_init( ump_memory_allocation * descriptor )
++{
++      ump_vma_usage_tracker * vma_usage_tracker;
++      struct vm_area_struct *vma;
++
++      if (NULL == descriptor) return _MALI_OSK_ERR_FAULT;
++
++      vma_usage_tracker = kmalloc(sizeof(ump_vma_usage_tracker), GFP_KERNEL);
++      if (NULL == vma_usage_tracker)
++      {
++              DBG_MSG(1, ("Failed to allocate memory for ump_vma_usage_tracker in _mali_osk_mem_mapregion_init\n"));
++              return -_MALI_OSK_ERR_FAULT;
++      }
++
++      vma = (struct vm_area_struct*)descriptor->process_mapping_info;
++      if (NULL == vma )
++      {
++              kfree(vma_usage_tracker);
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      vma->vm_private_data = vma_usage_tracker;
++      vma->vm_flags |= VM_IO;
++      vma->vm_flags |= VM_RESERVED;
++
++      if (0==descriptor->is_cached)
++      {
++              vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
++      }
++      DBG_MSG(3, ("Mapping with page_prot: 0x%x\n", vma->vm_page_prot ));
++
++      /* Setup the functions which handle further VMA handling */
++      vma->vm_ops = &ump_vm_ops;
++
++      /* Do the va range allocation - in this case, it was done earlier, so we copy in that information */
++      descriptor->mapping = (void __user*)vma->vm_start;
++
++      atomic_set(&vma_usage_tracker->references, 1); /*this can later be increased if process is forked, see ump_vma_open() */
++      vma_usage_tracker->descriptor = descriptor;
++
++      return _MALI_OSK_ERR_OK;
++}
++
++void _ump_osk_mem_mapregion_term( ump_memory_allocation * descriptor )
++{
++      struct vm_area_struct* vma;
++      ump_vma_usage_tracker * vma_usage_tracker;
++
++      if (NULL == descriptor) return;
++
++      /* Linux does the right thing as part of munmap to remove the mapping
++       * All that remains is that we remove the vma_usage_tracker setup in init() */
++      vma = (struct vm_area_struct*)descriptor->process_mapping_info;
++
++      vma_usage_tracker = vma->vm_private_data;
++
++      /* We only get called if mem_mapregion_init succeeded */
++      kfree(vma_usage_tracker);
++      return;
++}
++
++_mali_osk_errcode_t _ump_osk_mem_mapregion_map( ump_memory_allocation * descriptor, u32 offset, u32 * phys_addr, unsigned long size )
++{
++      struct vm_area_struct *vma;
++      _mali_osk_errcode_t retval;
++
++      if (NULL == descriptor) return _MALI_OSK_ERR_FAULT;
++
++      vma = (struct vm_area_struct*)descriptor->process_mapping_info;
++
++      if (NULL == vma ) return _MALI_OSK_ERR_FAULT;
++
++      retval = remap_pfn_range( vma, ((u32)descriptor->mapping) + offset, (*phys_addr) >> PAGE_SHIFT, size, vma->vm_page_prot) ? _MALI_OSK_ERR_FAULT : _MALI_OSK_ERR_OK;;
++
++              DBG_MSG(4, ("Mapping virtual to physical memory. ID: %u, vma: 0x%08lx, virtual addr:0x%08lx, physical addr: 0x%08lx, size:%lu, prot:0x%x, vm_flags:0x%x RETVAL: 0x%x\n",
++                      ump_dd_secure_id_get(descriptor->handle),
++                      (unsigned long)vma,
++                      (unsigned long)(vma->vm_start + offset),
++                      (unsigned long)*phys_addr,
++                      size,
++                      (unsigned int)vma->vm_page_prot, vma->vm_flags, retval));
++
++      return retval;
++}
++
++static void level1_cache_flush_all(void)
++{
++      DBG_MSG(4, ("UMP[xx] Flushing complete L1 cache\n"));
++      __cpuc_flush_kern_all();
++}
++
++void _ump_osk_msync( ump_dd_mem * mem, void * virt, u32 offset, u32 size, ump_uk_msync_op op, ump_session_data * session_data )
++{
++      int i;
++      const void *start_v, *end_v;
++
++      /* Flush L1 using virtual address, the entire range in one go.
++       * Only flush if user space process has a valid write mapping on given address. */
++      if( (mem) && (virt!=NULL) && (access_ok(VERIFY_WRITE, virt, size)) )
++      {
++              start_v = (void *)virt;
++              end_v   = (void *)(start_v + size - 1);
++              /*  There is no dmac_clean_range, so the L1 is always flushed,
++               *  also for UMP_MSYNC_CLEAN. */
++              /* MALI_SEC */
++              if (size >= SZ_64K)
++                      flush_all_cpu_caches();
++              else
++                      dmac_flush_range(start_v, end_v);
++
++              DBG_MSG(3, ("UMP[%02u] Flushing CPU L1 Cache. Cpu address: %x-%x\n", mem->secure_id, start_v,end_v));
++      }
++      else
++      {
++              if (session_data)
++              {
++                      if (op == _UMP_UK_MSYNC_FLUSH_L1  )
++                      {
++                              DBG_MSG(4, ("UMP Pending L1 cache flushes: %d\n", session_data->has_pending_level1_cache_flush));
++                              session_data->has_pending_level1_cache_flush = 0;
++                              level1_cache_flush_all();
++                              return;
++                      }
++                      else
++                      {
++                              if (session_data->cache_operations_ongoing)
++                              {
++                                      session_data->has_pending_level1_cache_flush++;
++                                      DBG_MSG(4, ("UMP[%02u] Defering the L1 flush. Nr pending:%d\n", mem->secure_id, session_data->has_pending_level1_cache_flush) );
++                              }
++                              else
++                              {
++                                      /* Flushing the L1 cache for each switch_user() if ump_cache_operations_control(START) is not called */
++                                      level1_cache_flush_all();
++                              }
++                      }
++              }
++              else
++              {
++                      DBG_MSG(4, ("Unkown state %s %d\n", __FUNCTION__, __LINE__));
++                      level1_cache_flush_all();
++              }
++      }
++
++      if ( NULL == mem ) return;
++
++      if ( mem->size_bytes==size)
++      {
++              DBG_MSG(3, ("UMP[%02u] Flushing CPU L2 Cache\n",mem->secure_id));
++      }
++      else
++      {
++              DBG_MSG(3, ("UMP[%02u] Flushing CPU L2 Cache. Blocks:%u, TotalSize:%u. FlushSize:%u Offset:0x%x FirstPaddr:0x%08x\n",
++                  mem->secure_id, mem->nr_blocks, mem->size_bytes, size, offset, mem->block_array[0].addr));
++      }
++
++
++      /* Flush L2 using physical addresses, block for block. */
++      for (i=0 ; i < mem->nr_blocks; i++)
++      {
++              u32 start_p, end_p;
++              ump_dd_physical_block *block;
++              block = &mem->block_array[i];
++
++              if(offset >= block->size)
++              {
++                      offset -= block->size;
++                      continue;
++              }
++
++              if(offset)
++              {
++                      start_p = (u32)block->addr + offset;
++                      /* We'll zero the offset later, after using it to calculate end_p. */
++              }
++              else
++              {
++                      start_p = (u32)block->addr;
++              }
++
++              if(size < block->size - offset)
++              {
++                      end_p = start_p + size - 1;
++                      size = 0;
++              }
++              else
++              {
++                      if(offset)
++                      {
++                              end_p = start_p + (block->size - offset - 1);
++                              size -= block->size - offset;
++                              offset = 0;
++                      }
++                      else
++                      {
++                              end_p = start_p + block->size - 1;
++                              size -= block->size;
++                      }
++              }
++
++              switch(op)
++              {
++                              case _UMP_UK_MSYNC_CLEAN:
++                                              outer_clean_range(start_p, end_p);
++                                              break;
++                              case _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE:
++                                              outer_flush_range(start_p, end_p);
++                                              break;
++                              case _UMP_UK_MSYNC_INVALIDATE:
++                                              outer_inv_range(start_p, end_p);
++                                              break;
++                              default:
++                                              break;
++              }
++
++              if(0 == size)
++              {
++                      /* Nothing left to flush. */
++                      break;
++              }
++      }
++
++      return;
++}
+diff --git a/drivers/gpu/arm/mali400/ump/linux/ump_osk_misc.c b/drivers/gpu/arm/mali400/ump/linux/ump_osk_misc.c
+new file mode 100644
+index 0000000..dcfee7d
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/linux/ump_osk_misc.c
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file ump_osk_misc.c
++ * Implementation of the OS abstraction layer for the UMP kernel device driver
++ */
++
++
++#include "ump_osk.h"
++
++#include <linux/kernel.h>
++#include "ump_kernel_linux.h"
++
++/* is called from ump_kernel_constructor in common code */
++_mali_osk_errcode_t _ump_osk_init( void )
++{
++      if (0 != ump_kernel_device_initialize())
++      {
++              return _MALI_OSK_ERR_FAULT;
++      }
++
++      return _MALI_OSK_ERR_OK;
++}
++
++_mali_osk_errcode_t _ump_osk_term( void )
++{
++      ump_kernel_device_terminate();
++      return _MALI_OSK_ERR_OK;
++}
+diff --git a/drivers/gpu/arm/mali400/ump/linux/ump_ukk_ref_wrappers.c b/drivers/gpu/arm/mali400/ump/linux/ump_ukk_ref_wrappers.c
+new file mode 100644
+index 0000000..e252a9b
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/linux/ump_ukk_ref_wrappers.c
+@@ -0,0 +1,254 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file ump_ukk_wrappers.c
++ * Defines the wrapper functions which turn Linux IOCTL calls into _ukk_ calls for the reference implementation
++ */
++
++
++#include <asm/uaccess.h>             /* user space access */
++
++#include "ump_osk.h"
++#include "ump_uk_types.h"
++#include "ump_ukk.h"
++#include "ump_kernel_common.h"
++/* MALI_SEC */
++#ifdef CONFIG_DMA_SHARED_BUFFER
++#include <linux/scatterlist.h>
++#include "ump_kernel_interface_ref_drv.h"
++#include "mali_osk_list.h"
++#include <linux/dma-buf.h>
++#endif
++
++/* FIXME */
++struct device tmp_dev;
++
++/*
++ * IOCTL operation; Allocate UMP memory
++ */
++int ump_allocate_wrapper(u32 __user * argument, struct ump_session_data  * session_data)
++{
++      _ump_uk_allocate_s user_interaction;
++      _mali_osk_errcode_t err;
++
++      /* Sanity check input parameters */
++      if (NULL == argument || NULL == session_data)
++      {
++              MSG_ERR(("NULL parameter in ump_ioctl_allocate()\n"));
++              return -ENOTTY;
++      }
++
++      /* Copy the user space memory to kernel space (so we safely can read it) */
++      if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction)))
++      {
++              MSG_ERR(("copy_from_user() in ump_ioctl_allocate()\n"));
++              return -EFAULT;
++      }
++
++      user_interaction.ctx = (void *) session_data;
++
++      err = _ump_ukk_allocate( &user_interaction );
++      if( _MALI_OSK_ERR_OK != err )
++      {
++              DBG_MSG(1, ("_ump_ukk_allocate() failed in ump_ioctl_allocate()\n"));
++              return map_errcode(err);
++      }
++      user_interaction.ctx = NULL;
++
++      if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction)))
++      {
++              /* If the copy fails then we should release the memory. We can use the IOCTL release to accomplish this */
++              _ump_uk_release_s release_args;
++
++              MSG_ERR(("copy_to_user() failed in ump_ioctl_allocate()\n"));
++
++              release_args.ctx = (void *) session_data;
++              release_args.secure_id = user_interaction.secure_id;
++
++              err = _ump_ukk_release( &release_args );
++              if(_MALI_OSK_ERR_OK != err)
++              {
++                      MSG_ERR(("_ump_ukk_release() also failed when trying to release newly allocated memory in ump_ioctl_allocate()\n"));
++              }
++
++              return -EFAULT;
++      }
++
++      return 0; /* success */
++}
++
++/* MALI_SEC */
++#ifdef CONFIG_DMA_SHARED_BUFFER
++static ump_dd_handle
++      get_ump_handle_from_dmabuf(struct ump_session_data *session_data,
++                                      struct dma_buf *dmabuf)
++{
++      ump_session_memory_list_element *session_mem, *tmp;
++      struct dma_buf_attachment *attach;
++      ump_dd_handle ump_handle;
++
++      _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
++
++      _MALI_OSK_LIST_FOREACHENTRY(session_mem, tmp,
++                              &session_data->list_head_session_memory_list,
++                              ump_session_memory_list_element, list) {
++              if (session_mem->mem->import_attach) {
++                      attach = session_mem->mem->import_attach;
++                      if (attach->dmabuf == dmabuf) {
++                              _mali_osk_lock_signal(session_data->lock,
++                                                      _MALI_OSK_LOCKMODE_RW);
++                              ump_handle = (ump_dd_handle)session_mem->mem;
++                              return ump_handle;
++                      }
++              }
++      }
++
++      _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
++
++      return NULL;
++}
++
++int ump_dmabuf_import_wrapper(u32 __user *argument,
++                              struct ump_session_data  *session_data)
++{
++      ump_session_memory_list_element *session = NULL;
++      struct ump_uk_dmabuf ump_dmabuf;
++      ump_dd_handle ump_handle;
++      ump_dd_physical_block *blocks = NULL;
++      struct dma_buf_attachment *attach = NULL;
++      struct dma_buf *dma_buf;
++      struct sg_table *sgt = NULL;
++      struct scatterlist *sgl;
++      unsigned long block_size;
++      unsigned int i = 0, npages;
++      int ret;
++
++      /* FIXME */
++      memset(&tmp_dev, 0x0, sizeof(struct device));
++
++      /* Sanity check input parameters */
++      if (!argument || !session_data) {
++              MSG_ERR(("NULL parameter.\n"));
++              return -EINVAL;
++      }
++
++      if (copy_from_user(&ump_dmabuf, argument,
++                              sizeof(struct ump_uk_dmabuf))) {
++              MSG_ERR(("copy_from_user() failed.\n"));
++              return -EFAULT;
++      }
++
++      dma_buf = dma_buf_get(ump_dmabuf.fd);
++      if (IS_ERR(dma_buf))
++              return PTR_ERR(dma_buf);
++
++      /*
++       * if already imported then increase a refcount to the ump descriptor
++       * and call dma_buf_put() and then go to found to return previous
++       * ump secure id.
++       */
++      ump_handle = get_ump_handle_from_dmabuf(session_data, dma_buf);
++      if (ump_handle) {
++              dma_buf_put(dma_buf);
++              goto found;
++      }
++
++      attach = dma_buf_attach(dma_buf, &tmp_dev);
++      if (IS_ERR(attach)) {
++              ret = PTR_ERR(attach);
++              goto err_dma_buf_put;
++      }
++
++      sgt = dma_buf_map_attachment(attach, DMA_NONE);
++      if (IS_ERR(sgt)) {
++              ret = PTR_ERR(sgt);
++              goto err_dma_buf_detach;
++      }
++
++      npages = sgt->nents;
++
++      /* really need? */
++      ump_dmabuf.ctx = (void *)session_data;
++
++      block_size = sizeof(ump_dd_physical_block) * npages;
++
++      blocks = (ump_dd_physical_block *)_mali_osk_malloc(block_size);
++      sgl = sgt->sgl;
++
++      while (i < npages) {
++              blocks[i].addr = sg_phys(sgl);
++              blocks[i].size = sgl->length;
++              sgl = sg_next(sgl);
++              i++;
++      }
++
++      /*
++       * Initialize the session memory list element, and add it
++       * to the session object
++       */
++      session = _mali_osk_calloc(1, sizeof(*session));
++      if (!session) {
++              DBG_MSG(1, ("Failed to allocate session.\n"));
++              ret = -EFAULT;
++              goto err_free_block;
++      }
++
++      ump_handle = ump_dd_handle_create_from_phys_blocks(blocks, i);
++      if (UMP_DD_HANDLE_INVALID == ump_handle) {
++              DBG_MSG(1, ("Failed to create ump handle.\n"));
++              ret = -EFAULT;
++              goto err_free_session;
++      }
++
++      session->mem = (ump_dd_mem *)ump_handle;
++      session->mem->import_attach = attach;
++      session->mem->sgt = sgt;
++
++      _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
++      _mali_osk_list_add(&(session->list),
++                      &(session_data->list_head_session_memory_list));
++      _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
++
++      _mali_osk_free(blocks);
++
++found:
++      ump_dmabuf.secure_id = ump_dd_secure_id_get(ump_handle);
++      ump_dmabuf.size = ump_dd_size_get(ump_handle);
++
++      if (copy_to_user(argument, &ump_dmabuf,
++                              sizeof(struct ump_uk_dmabuf))) {
++              MSG_ERR(("copy_to_user() failed.\n"));
++              if (session) {
++                      _mali_osk_lock_wait(session_data->lock,
++                                                      _MALI_OSK_LOCKMODE_RW);
++                      _mali_osk_list_del(&session->list);
++                      _mali_osk_lock_signal(session_data->lock,
++                                                      _MALI_OSK_LOCKMODE_RW);
++                      ump_dd_reference_release(ump_handle);
++                      _mali_osk_free(session);
++              }
++              return -EFAULT;
++      }
++
++      return 0;
++
++err_free_session:
++      _mali_osk_free(session);
++err_free_block:
++      _mali_osk_free(blocks);
++      dma_buf_unmap_attachment(attach, sgt, DMA_NONE);
++err_dma_buf_detach:
++      dma_buf_detach(dma_buf, attach);
++err_dma_buf_put:
++      dma_buf_put(dma_buf);
++      return ret;
++}
++#endif
+diff --git a/drivers/gpu/arm/mali400/ump/linux/ump_ukk_ref_wrappers.h b/drivers/gpu/arm/mali400/ump/linux/ump_ukk_ref_wrappers.h
+new file mode 100644
+index 0000000..d9d444b
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/linux/ump_ukk_ref_wrappers.h
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file ump_ukk_wrappers.h
++ * Defines the wrapper functions which turn Linux IOCTL calls into _ukk_ calls for the reference implementation
++ */
++
++#ifndef __UMP_UKK_REF_WRAPPERS_H__
++#define __UMP_UKK_REF_WRAPPERS_H__
++
++#include <linux/kernel.h>
++#include "ump_kernel_common.h"
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif
++
++
++int ump_allocate_wrapper(u32 __user * argument, struct ump_session_data  * session_data);
++/* MALI_SEC */
++#ifdef CONFIG_ION_EXYNOS
++int ump_ion_import_wrapper(u32 __user * argument, struct ump_session_data  * session_data);
++#endif
++
++#ifdef CONFIG_DMA_SHARED_BUFFER
++int ump_dmabuf_import_wrapper(u32 __user *argument,
++                              struct ump_session_data  *session_data);
++#endif
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* __UMP_UKK_REF_WRAPPERS_H__ */
+diff --git a/drivers/gpu/arm/mali400/ump/linux/ump_ukk_wrappers.c b/drivers/gpu/arm/mali400/ump/linux/ump_ukk_wrappers.c
+new file mode 100644
+index 0000000..9cfa5e9
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/linux/ump_ukk_wrappers.c
+@@ -0,0 +1,306 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file ump_ukk_wrappers.c
++ * Defines the wrapper functions which turn Linux IOCTL calls into _ukk_ calls
++ */
++
++#include <asm/uaccess.h>             /* user space access */
++
++#include "ump_osk.h"
++#include "ump_uk_types.h"
++#include "ump_ukk.h"
++#include "ump_kernel_common.h"
++
++/*
++ * IOCTL operation; Negotiate version of IOCTL API
++ */
++int ump_get_api_version_wrapper(u32 __user * argument, struct ump_session_data * session_data)
++{
++      _ump_uk_api_version_s version_info;
++      _mali_osk_errcode_t err;
++
++      /* Sanity check input parameters */
++      if (NULL == argument || NULL == session_data)
++      {
++              MSG_ERR(("NULL parameter in ump_ioctl_get_api_version()\n"));
++              return -ENOTTY;
++      }
++
++      /* Copy the user space memory to kernel space (so we safely can read it) */
++      if (0 != copy_from_user(&version_info, argument, sizeof(version_info)))
++      {
++              MSG_ERR(("copy_from_user() in ump_ioctl_get_api_version()\n"));
++              return -EFAULT;
++      }
++
++      version_info.ctx = (void*) session_data;
++      err = _ump_uku_get_api_version( &version_info );
++      if( _MALI_OSK_ERR_OK != err )
++      {
++              MSG_ERR(("_ump_uku_get_api_version() failed in ump_ioctl_get_api_version()\n"));
++              return map_errcode(err);
++      }
++
++      version_info.ctx = NULL;
++
++      /* Copy ouput data back to user space */
++      if (0 != copy_to_user(argument, &version_info, sizeof(version_info)))
++      {
++              MSG_ERR(("copy_to_user() failed in ump_ioctl_get_api_version()\n"));
++              return -EFAULT;
++      }
++
++      return 0; /* success */
++}
++
++
++/*
++ * IOCTL operation; Release reference to specified UMP memory.
++ */
++int ump_release_wrapper(u32 __user * argument, struct ump_session_data  * session_data)
++{
++      _ump_uk_release_s release_args;
++      _mali_osk_errcode_t err;
++
++      /* Sanity check input parameters */
++      if (NULL == session_data)
++      {
++              MSG_ERR(("NULL parameter in ump_ioctl_release()\n"));
++              return -ENOTTY;
++      }
++
++      /* Copy the user space memory to kernel space (so we safely can read it) */
++      if (0 != copy_from_user(&release_args, argument, sizeof(release_args)))
++      {
++              MSG_ERR(("copy_from_user() in ump_ioctl_get_api_version()\n"));
++              return -EFAULT;
++      }
++
++      release_args.ctx = (void*) session_data;
++      err = _ump_ukk_release( &release_args );
++      if( _MALI_OSK_ERR_OK != err )
++      {
++              MSG_ERR(("_ump_ukk_release() failed in ump_ioctl_release()\n"));
++              return map_errcode(err);
++      }
++
++
++      return 0; /* success */
++}
++
++/*
++ * IOCTL operation; Return size for specified UMP memory.
++ */
++int ump_size_get_wrapper(u32 __user * argument, struct ump_session_data  * session_data)
++{
++      _ump_uk_size_get_s user_interaction;
++      _mali_osk_errcode_t err;
++
++      /* Sanity check input parameters */
++      if (NULL == argument || NULL == session_data)
++      {
++              MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n"));
++              return -ENOTTY;
++      }
++
++      if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction)))
++      {
++              MSG_ERR(("copy_from_user() in ump_ioctl_size_get()\n"));
++              return -EFAULT;
++      }
++
++      user_interaction.ctx = (void *) session_data;
++      err = _ump_ukk_size_get( &user_interaction );
++      if( _MALI_OSK_ERR_OK != err )
++      {
++              MSG_ERR(("_ump_ukk_size_get() failed in ump_ioctl_size_get()\n"));
++              return map_errcode(err);
++      }
++
++      user_interaction.ctx = NULL;
++
++      if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction)))
++      {
++              MSG_ERR(("copy_to_user() failed in ump_ioctl_size_get()\n"));
++              return -EFAULT;
++      }
++
++      return 0; /* success */
++}
++
++/*
++ * IOCTL operation; Do cache maintenance on specified UMP memory.
++ */
++int ump_msync_wrapper(u32 __user * argument, struct ump_session_data  * session_data)
++{
++      _ump_uk_msync_s user_interaction;
++
++      /* Sanity check input parameters */
++      if (NULL == argument || NULL == session_data)
++      {
++              MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n"));
++              return -ENOTTY;
++      }
++
++      if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction)))
++      {
++              MSG_ERR(("copy_from_user() in ump_ioctl_msync()\n"));
++              return -EFAULT;
++      }
++
++      user_interaction.ctx = (void *) session_data;
++
++      _ump_ukk_msync( &user_interaction );
++
++      user_interaction.ctx = NULL;
++
++      if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction)))
++      {
++              MSG_ERR(("copy_to_user() failed in ump_ioctl_msync()\n"));
++              return -EFAULT;
++      }
++
++      return 0; /* success */
++}
++int ump_cache_operations_control_wrapper(u32 __user * argument, struct ump_session_data  * session_data)
++{
++      _ump_uk_cache_operations_control_s user_interaction;
++
++      /* Sanity check input parameters */
++      if (NULL == argument || NULL == session_data)
++      {
++              MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n"));
++              return -ENOTTY;
++      }
++
++      if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction)))
++      {
++              MSG_ERR(("copy_from_user() in ump_ioctl_cache_operations_control()\n"));
++              return -EFAULT;
++      }
++
++      user_interaction.ctx = (void *) session_data;
++
++      _ump_ukk_cache_operations_control((_ump_uk_cache_operations_control_s*) &user_interaction );
++
++      user_interaction.ctx = NULL;
++
++#if 0  /* No data to copy back */
++      if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction)))
++      {
++              MSG_ERR(("copy_to_user() failed in ump_ioctl_cache_operations_control()\n"));
++              return -EFAULT;
++      }
++#endif
++      return 0; /* success */
++}
++
++int ump_switch_hw_usage_wrapper(u32 __user * argument, struct ump_session_data  * session_data)
++{
++      _ump_uk_switch_hw_usage_s user_interaction;
++
++      /* Sanity check input parameters */
++      if (NULL == argument || NULL == session_data)
++      {
++              MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n"));
++              return -ENOTTY;
++      }
++
++      if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction)))
++      {
++              MSG_ERR(("copy_from_user() in ump_ioctl_switch_hw_usage()\n"));
++              return -EFAULT;
++      }
++
++      user_interaction.ctx = (void *) session_data;
++
++      _ump_ukk_switch_hw_usage( &user_interaction );
++
++      user_interaction.ctx = NULL;
++
++#if 0  /* No data to copy back */
++      if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction)))
++      {
++              MSG_ERR(("copy_to_user() failed in ump_ioctl_switch_hw_usage()\n"));
++              return -EFAULT;
++      }
++#endif
++      return 0; /* success */
++}
++
++int ump_lock_wrapper(u32 __user * argument, struct ump_session_data  * session_data)
++{
++      _ump_uk_lock_s user_interaction;
++
++      /* Sanity check input parameters */
++      if (NULL == argument || NULL == session_data)
++      {
++              MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n"));
++              return -ENOTTY;
++      }
++
++      if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction)))
++      {
++              MSG_ERR(("copy_from_user() in ump_ioctl_switch_hw_usage()\n"));
++              return -EFAULT;
++      }
++
++      user_interaction.ctx = (void *) session_data;
++
++      _ump_ukk_lock( &user_interaction );
++
++      user_interaction.ctx = NULL;
++
++#if 0  /* No data to copy back */
++      if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction)))
++      {
++              MSG_ERR(("copy_to_user() failed in ump_ioctl_switch_hw_usage()\n"));
++              return -EFAULT;
++      }
++#endif
++
++      return 0; /* success */
++}
++
++int ump_unlock_wrapper(u32 __user * argument, struct ump_session_data  * session_data)
++{
++      _ump_uk_unlock_s user_interaction;
++
++      /* Sanity check input parameters */
++      if (NULL == argument || NULL == session_data)
++      {
++              MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n"));
++              return -ENOTTY;
++      }
++
++      if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction)))
++      {
++              MSG_ERR(("copy_from_user() in ump_ioctl_switch_hw_usage()\n"));
++              return -EFAULT;
++      }
++
++      user_interaction.ctx = (void *) session_data;
++
++      _ump_ukk_unlock( &user_interaction );
++
++      user_interaction.ctx = NULL;
++
++#if 0  /* No data to copy back */
++      if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction)))
++      {
++              MSG_ERR(("copy_to_user() failed in ump_ioctl_switch_hw_usage()\n"));
++              return -EFAULT;
++      }
++#endif
++
++      return 0; /* success */
++}
+diff --git a/drivers/gpu/arm/mali400/ump/linux/ump_ukk_wrappers.h b/drivers/gpu/arm/mali400/ump/linux/ump_ukk_wrappers.h
+new file mode 100644
+index 0000000..0d7abb1
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/linux/ump_ukk_wrappers.h
+@@ -0,0 +1,47 @@
++/*
++ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
++ *
++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
++ *
++ * A copy of the licence is included with the program, and can also be obtained from Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++/**
++ * @file ump_ukk_wrappers.h
++ * Defines the wrapper functions which turn Linux IOCTL calls into _ukk_ calls
++ */
++
++#ifndef __UMP_UKK_WRAPPERS_H__
++#define __UMP_UKK_WRAPPERS_H__
++
++#include <linux/kernel.h>
++#include "ump_kernel_common.h"
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif
++
++
++
++int ump_get_api_version_wrapper(u32 __user * argument, struct ump_session_data * session_data);
++int ump_release_wrapper(u32 __user * argument, struct ump_session_data  * session_data);
++int ump_size_get_wrapper(u32 __user * argument, struct ump_session_data  * session_data);
++int ump_msync_wrapper(u32 __user * argument, struct ump_session_data  * session_data);
++int ump_cache_operations_control_wrapper(u32 __user * argument, struct ump_session_data  * session_data);
++int ump_switch_hw_usage_wrapper(u32 __user * argument, struct ump_session_data  * session_data);
++int ump_lock_wrapper(u32 __user * argument, struct ump_session_data  * session_data);
++int ump_unlock_wrapper(u32 __user * argument, struct ump_session_data  * session_data);
++
++
++
++
++#ifdef __cplusplus
++}
++#endif
++
++
++
++#endif /* __UMP_UKK_WRAPPERS_H__ */
+diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
+index 6d9788d..a7672c6 100644
+--- a/drivers/video/Kconfig
++++ b/drivers/video/Kconfig
+@@ -19,6 +19,8 @@ source "drivers/char/agp/Kconfig"
+ source "drivers/gpu/vga/Kconfig"
++source "drivers/gpu/arm/Kconfig"
++
+ source "drivers/gpu/drm/Kconfig"
+ source "drivers/gpu/host1x/Kconfig"
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0116-gpu-arm-mali400-mali-Do-not-use-non-existent-VM_RESE.patch b/patches.tizen/0116-gpu-arm-mali400-mali-Do-not-use-non-existent-VM_RESE.patch
new file mode 100644 (file)
index 0000000..55f96eb
--- /dev/null
@@ -0,0 +1,28 @@
+From 17fb6c07dc10e0baa5f6de46b836c1b760080a4d Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 9 May 2013 17:21:28 +0200
+Subject: [PATCH 0116/1302] gpu: arm: mali400: mali: Do not use non-existent
+ VM_RESERVED flag
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/arm/mali400/mali/linux/mali_osk_low_level_mem.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_osk_low_level_mem.c b/drivers/gpu/arm/mali400/mali/linux/mali_osk_low_level_mem.c
+index 21f7762..258f8b6 100644
+--- a/drivers/gpu/arm/mali400/mali/linux/mali_osk_low_level_mem.c
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_osk_low_level_mem.c
+@@ -523,7 +523,7 @@ _mali_osk_errcode_t _mali_osk_mem_mapregion_init( mali_memory_allocation * descr
+         The memory is reserved, meaning that it's present and can never be paged out (see also previous entry)
+       */
+       vma->vm_flags |= VM_IO;
+-      vma->vm_flags |= VM_RESERVED;
++      vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
+       vma->vm_flags |= VM_DONTCOPY;
+       vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0117-gpu-arm-mali400-ump-Do-not-use-non-existent-VM_RESER.patch b/patches.tizen/0117-gpu-arm-mali400-ump-Do-not-use-non-existent-VM_RESER.patch
new file mode 100644 (file)
index 0000000..c8c686d
--- /dev/null
@@ -0,0 +1,28 @@
+From 434c634b344657bcc5b50793080d18b3987436e2 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 9 May 2013 17:21:56 +0200
+Subject: [PATCH 0117/1302] gpu: arm: mali400: ump: Do not use non-existent
+ VM_RESERVED flag
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/arm/mali400/ump/linux/ump_osk_low_level_mem.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/arm/mali400/ump/linux/ump_osk_low_level_mem.c b/drivers/gpu/arm/mali400/ump/linux/ump_osk_low_level_mem.c
+index 6f1b6ff..c47be67 100644
+--- a/drivers/gpu/arm/mali400/ump/linux/ump_osk_low_level_mem.c
++++ b/drivers/gpu/arm/mali400/ump/linux/ump_osk_low_level_mem.c
+@@ -149,7 +149,7 @@ _mali_osk_errcode_t _ump_osk_mem_mapregion_init( ump_memory_allocation * descrip
+       vma->vm_private_data = vma_usage_tracker;
+       vma->vm_flags |= VM_IO;
+-      vma->vm_flags |= VM_RESERVED;
++      vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
+       if (0==descriptor->is_cached)
+       {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0118-gpu-arm-mali400-mali-Remove-useless-platforms.patch b/patches.tizen/0118-gpu-arm-mali400-mali-Remove-useless-platforms.patch
new file mode 100644 (file)
index 0000000..a4ea3c6
--- /dev/null
@@ -0,0 +1,2783 @@
+From b7116388b42acc1a3028b69ef57de9a551bdd048 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 10 May 2013 14:53:03 +0200
+Subject: [PATCH 0118/1302] gpu: arm: mali400: mali: Remove useless platforms
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/arm/mali400/mali/platform/arm/arm.c    | 209 -----
+ .../mali400/mali/platform/default/mali_platform.c  |  41 -
+ .../arm/mali400/mali/platform/exynos4/exynos4.c    | 320 --------
+ .../mali400/mali/platform/exynos4/exynos4_pmm.c    | 849 ---------------------
+ .../mali400/mali/platform/exynos4/exynos4_pmm.h    |  86 ---
+ .../mali400/mali/platform/pegasus-m400/exynos4.c   | 273 -------
+ .../mali/platform/pegasus-m400/exynos4_pmm.c       | 842 --------------------
+ .../mali/platform/pegasus-m400/exynos4_pmm.h       |  86 ---
+ 8 files changed, 2706 deletions(-)
+ delete mode 100644 drivers/gpu/arm/mali400/mali/platform/arm/arm.c
+ delete mode 100644 drivers/gpu/arm/mali400/mali/platform/default/mali_platform.c
+ delete mode 100644 drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4.c
+ delete mode 100644 drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4_pmm.c
+ delete mode 100644 drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4_pmm.h
+ delete mode 100644 drivers/gpu/arm/mali400/mali/platform/pegasus-m400/exynos4.c
+ delete mode 100644 drivers/gpu/arm/mali400/mali/platform/pegasus-m400/exynos4_pmm.c
+ delete mode 100644 drivers/gpu/arm/mali400/mali/platform/pegasus-m400/exynos4_pmm.h
+
+diff --git a/drivers/gpu/arm/mali400/mali/platform/arm/arm.c b/drivers/gpu/arm/mali400/mali/platform/arm/arm.c
+deleted file mode 100644
+index fd6769e..0000000
+--- a/drivers/gpu/arm/mali400/mali/platform/arm/arm.c
++++ /dev/null
+@@ -1,209 +0,0 @@
+-/*
+- * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+- *
+- * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+- * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+- *
+- * A copy of the licence is included with the program, and can also be obtained from Free Software
+- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+- */
+-
+-/**
+- * @file mali_platform.c
+- * Platform specific Mali driver functions for:
+- * - Realview Versatile platforms with ARM11 Mpcore and virtex 5.
+- * - Versatile Express platforms with ARM Cortex-A9 and virtex 6.
+- */
+-#include <linux/platform_device.h>
+-#include <linux/version.h>
+-#include <linux/pm.h>
+-#ifdef CONFIG_PM_RUNTIME
+-#include <linux/pm_runtime.h>
+-#endif
+-#include <asm/io.h>
+-#include <linux/mali/mali_utgard.h>
+-#include "mali_kernel_common.h"
+-
+-static void mali_platform_device_release(struct device *device);
+-static u32 mali_read_phys(u32 phys_addr);
+-#if defined(CONFIG_ARCH_REALVIEW)
+-static void mali_write_phys(u32 phys_addr, u32 value);
+-#endif
+-
+-#if defined(CONFIG_ARCH_VEXPRESS)
+-
+-static struct resource mali_gpu_resources_m450_mp8[] =
+-{
+-      MALI_GPU_RESOURCES_MALI450_MP8_PMU(0xFC040000, -1, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 68)
+-};
+-
+-#elif defined(CONFIG_ARCH_REALVIEW)
+-
+-static struct resource mali_gpu_resources_m200[] =
+-{
+-      MALI_GPU_RESOURCES_MALI200(0xC0000000, -1, -1, -1)
+-};
+-
+-static struct resource mali_gpu_resources_m300[] =
+-{
+-      MALI_GPU_RESOURCES_MALI300_PMU(0xC0000000, -1, -1, -1, -1)
+-};
+-
+-static struct resource mali_gpu_resources_m400_mp1[] =
+-{
+-      MALI_GPU_RESOURCES_MALI400_MP1_PMU(0xC0000000, -1, -1, -1, -1)
+-};
+-
+-static struct resource mali_gpu_resources_m400_mp2[] =
+-{
+-      MALI_GPU_RESOURCES_MALI400_MP2_PMU(0xC0000000, -1, -1, -1, -1, -1, -1)
+-};
+-
+-#endif
+-
+-static struct platform_device mali_gpu_device =
+-{
+-      .name = MALI_GPU_NAME_UTGARD,
+-      .id = 0,
+-      .dev.release = mali_platform_device_release,
+-};
+-
+-static struct mali_gpu_device_data mali_gpu_data =
+-{
+-#if defined(CONFIG_ARCH_VEXPRESS)
+-      .shared_mem_size =256 * 1024 * 1024, /* 256MB */
+-#elif defined(CONFIG_ARCH_REALVIEW)
+-      .dedicated_mem_start = 0x80000000, /* Physical start address (use 0xD0000000 for old indirect setup) */
+-      .dedicated_mem_size = 0x10000000, /* 256MB */
+-#endif
+-      .fb_start = 0xe0000000,
+-      .fb_size = 0x01000000,
+-};
+-
+-int mali_platform_device_register(void)
+-{
+-      int err = -1;
+-#if defined(CONFIG_ARCH_REALVIEW)
+-      u32 m400_gp_version;
+-#endif
+-
+-      MALI_DEBUG_PRINT(4, ("mali_platform_device_register() called\n"));
+-
+-      /* Detect present Mali GPU and connect the correct resources to the device */
+-#if defined(CONFIG_ARCH_VEXPRESS)
+-
+-      if (mali_read_phys(0xFC020000) == 0x00010100)
+-      {
+-              MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP8 device\n"));
+-              err = platform_device_add_resources(&mali_gpu_device, mali_gpu_resources_m450_mp8, sizeof(mali_gpu_resources_m450_mp8) / sizeof(mali_gpu_resources_m450_mp8[0]));
+-      }
+-
+-#elif defined(CONFIG_ARCH_REALVIEW)
+-
+-      m400_gp_version = mali_read_phys(0xC000006C);
+-      if (m400_gp_version == 0x00000000 && (mali_read_phys(0xC000206c) & 0xFFFF0000) == 0x0A070000)
+-      {
+-              MALI_DEBUG_PRINT(4, ("Registering Mali-200 device\n"));
+-              err = platform_device_add_resources(&mali_gpu_device, mali_gpu_resources_m200, sizeof(mali_gpu_resources_m200) / sizeof(mali_gpu_resources_m200[0]));
+-              mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */
+-      }
+-      else if ((m400_gp_version & 0xFFFF0000) == 0x0C070000)
+-      {
+-              MALI_DEBUG_PRINT(4, ("Registering Mali-300 device\n"));
+-              err = platform_device_add_resources(&mali_gpu_device, mali_gpu_resources_m300, sizeof(mali_gpu_resources_m300) / sizeof(mali_gpu_resources_m300[0]));
+-              mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */
+-      }
+-      else if ((m400_gp_version & 0xFFFF0000) == 0x0B070000)
+-      {
+-              u32 fpga_fw_version = mali_read_phys(0xC0010000);
+-              if (fpga_fw_version == 0x130C008F || fpga_fw_version == 0x110C008F)
+-              {
+-                      /* Mali-400 MP1 r1p0 or r1p1 */
+-                      MALI_DEBUG_PRINT(4, ("Registering Mali-400 MP1 device\n"));
+-                      err = platform_device_add_resources(&mali_gpu_device, mali_gpu_resources_m400_mp1, sizeof(mali_gpu_resources_m400_mp1) / sizeof(mali_gpu_resources_m400_mp1[0]));
+-                      mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */
+-              }
+-              else if (fpga_fw_version == 0x130C000F)
+-              {
+-                      /* Mali-400 MP2 r1p1 */
+-                      MALI_DEBUG_PRINT(4, ("Registering Mali-400 MP2 device\n"));
+-                      err = platform_device_add_resources(&mali_gpu_device, mali_gpu_resources_m400_mp2, sizeof(mali_gpu_resources_m400_mp2) / sizeof(mali_gpu_resources_m400_mp2[0]));
+-                      mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */
+-              }
+-      }
+-
+-#endif
+-
+-      if (0 == err)
+-      {
+-              err = platform_device_add_data(&mali_gpu_device, &mali_gpu_data, sizeof(mali_gpu_data));
+-              if (0 == err)
+-              {
+-                      /* Register the platform device */
+-                      err = platform_device_register(&mali_gpu_device);
+-                      if (0 == err)
+-                      {
+-#ifdef CONFIG_PM_RUNTIME
+-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+-                              pm_runtime_set_autosuspend_delay(&(mali_gpu_device.dev), 1000);
+-                              pm_runtime_use_autosuspend(&(mali_gpu_device.dev));
+-#endif
+-                              pm_runtime_enable(&(mali_gpu_device.dev));
+-#endif
+-
+-                              return 0;
+-                      }
+-              }
+-
+-              platform_device_unregister(&mali_gpu_device);
+-      }
+-
+-      return err;
+-}
+-
+-void mali_platform_device_unregister(void)
+-{
+-      MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n"));
+-
+-      platform_device_unregister(&mali_gpu_device);
+-
+-#if defined(CONFIG_ARCH_REALVIEW)
+-      mali_write_phys(0xC0010020, 0x9); /* Restore default (legacy) memory mapping */
+-#endif
+-}
+-
+-static void mali_platform_device_release(struct device *device)
+-{
+-      MALI_DEBUG_PRINT(4, ("mali_platform_device_release() called\n"));
+-}
+-
+-static u32 mali_read_phys(u32 phys_addr)
+-{
+-      u32 phys_addr_page = phys_addr & 0xFFFFE000;
+-      u32 phys_offset    = phys_addr & 0x00001FFF;
+-      u32 map_size       = phys_offset + sizeof(u32);
+-      u32 ret = 0xDEADBEEF;
+-      void *mem_mapped = ioremap_nocache(phys_addr_page, map_size);
+-      if (NULL != mem_mapped)
+-      {
+-              ret = (u32)ioread32(((u8*)mem_mapped) + phys_offset);
+-              iounmap(mem_mapped);
+-      }
+-
+-      return ret;
+-}
+-
+-#if defined(CONFIG_ARCH_REALVIEW)
+-static void mali_write_phys(u32 phys_addr, u32 value)
+-{
+-      u32 phys_addr_page = phys_addr & 0xFFFFE000;
+-      u32 phys_offset    = phys_addr & 0x00001FFF;
+-      u32 map_size       = phys_offset + sizeof(u32);
+-      void *mem_mapped = ioremap_nocache(phys_addr_page, map_size);
+-      if (NULL != mem_mapped)
+-      {
+-              iowrite32(value, ((u8*)mem_mapped) + phys_offset);
+-              iounmap(mem_mapped);
+-      }
+-}
+-#endif
+diff --git a/drivers/gpu/arm/mali400/mali/platform/default/mali_platform.c b/drivers/gpu/arm/mali400/mali/platform/default/mali_platform.c
+deleted file mode 100644
+index 8f1b781..0000000
+--- a/drivers/gpu/arm/mali400/mali/platform/default/mali_platform.c
++++ /dev/null
+@@ -1,41 +0,0 @@
+-/*
+- * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+- *
+- * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+- * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+- *
+- * A copy of the licence is included with the program, and can also be obtained from Free Software
+- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+- */
+-
+-/**
+- * @file mali_platform.c
+- * Platform specific Mali driver functions for a default platform
+- */
+-#include "mali_kernel_common.h"
+-#include "mali_osk.h"
+-#include "mali_platform.h"
+-
+-
+-_mali_osk_errcode_t mali_platform_init(void)
+-{
+-    MALI_SUCCESS;
+-}
+-
+-_mali_osk_errcode_t mali_platform_deinit(void)
+-{
+-    MALI_SUCCESS;
+-}
+-
+-_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode)
+-{
+-    MALI_SUCCESS;
+-}
+-
+-void mali_gpu_utilization_handler(u32 utilization)
+-{
+-}
+-
+-void set_mali_parent_power_domain(void* dev)
+-{
+-}
+diff --git a/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4.c b/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4.c
+deleted file mode 100644
+index bc77dbf..0000000
+--- a/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4.c
++++ /dev/null
+@@ -1,320 +0,0 @@
+-/*
+- * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+- *
+- * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+- * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+- *
+- * A copy of the licence is included with the program, and can also be obtained from Free Software
+- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+- */
+-
+-/**
+- * @file mali_platform.c
+- * Platform specific Mali driver functions for the exynos 4XXX based platforms
+- */
+-#include <linux/platform_device.h>
+-#include <linux/version.h>
+-#include <linux/pm.h>
+-#ifdef CONFIG_PM_RUNTIME
+-#include <linux/pm_runtime.h>
+-#endif
+-#include <linux/mali/mali_utgard.h>
+-#include "mali_kernel_common.h"
+-
+-#include <plat/pd.h>
+-
+-#include "exynos4_pmm.h"
+-
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
+-struct exynos_pm_domain;
+-extern struct exynos_pm_domain exynos4_pd_g3d;
+-void exynos_pm_add_dev_to_genpd(struct platform_device *pdev, struct exynos_pm_domain *pd);
+-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
+-extern struct platform_device exynos4_device_pd[];
+-#else
+-extern struct platform_device s5pv310_device_pd[];
+-#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) */
+-
+-static void mali_platform_device_release(struct device *device);
+-static int mali_os_suspend(struct device *device);
+-static int mali_os_resume(struct device *device);
+-static int mali_os_freeze(struct device *device);
+-static int mali_os_thaw(struct device *device);
+-#ifdef CONFIG_PM_RUNTIME
+-static int mali_runtime_suspend(struct device *device);
+-static int mali_runtime_resume(struct device *device);
+-static int mali_runtime_idle(struct device *device);
+-#endif
+-
+-#if defined(CONFIG_ARCH_S5PV310) && !defined(CONFIG_BOARD_HKDKC210)
+-
+-/* This is for other SMDK boards */
+-#define MALI_BASE_IRQ 232
+-
+-#else
+-
+-/* This is for the Odroid boards */
+-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
+-#define MALI_BASE_IRQ 182
+-#else
+-#define MALI_BASE_IRQ 150
+-#endif
+-
+-#endif
+-
+-#define MALI_GP_IRQ       MALI_BASE_IRQ + 9
+-#define MALI_PP0_IRQ      MALI_BASE_IRQ + 5
+-#define MALI_PP1_IRQ      MALI_BASE_IRQ + 6
+-#define MALI_PP2_IRQ      MALI_BASE_IRQ + 7
+-#define MALI_PP3_IRQ      MALI_BASE_IRQ + 8
+-#define MALI_GP_MMU_IRQ   MALI_BASE_IRQ + 4
+-#define MALI_PP0_MMU_IRQ  MALI_BASE_IRQ + 0
+-#define MALI_PP1_MMU_IRQ  MALI_BASE_IRQ + 1
+-#define MALI_PP2_MMU_IRQ  MALI_BASE_IRQ + 2
+-#define MALI_PP3_MMU_IRQ  MALI_BASE_IRQ + 3
+-
+-static struct resource mali_gpu_resources[] =
+-{
+-      MALI_GPU_RESOURCES_MALI400_MP4(0x13000000,
+-                                     MALI_GP_IRQ, MALI_GP_MMU_IRQ,
+-                                     MALI_PP0_IRQ, MALI_PP0_MMU_IRQ,
+-                                     MALI_PP1_IRQ, MALI_PP1_MMU_IRQ,
+-                                     MALI_PP2_IRQ, MALI_PP2_MMU_IRQ,
+-                                     MALI_PP3_IRQ, MALI_PP3_MMU_IRQ)
+-};
+-
+-static struct dev_pm_ops mali_gpu_device_type_pm_ops =
+-{
+-      .suspend = mali_os_suspend,
+-      .resume = mali_os_resume,
+-      .freeze = mali_os_freeze,
+-      .thaw = mali_os_thaw,
+-#ifdef CONFIG_PM_RUNTIME
+-      .runtime_suspend = mali_runtime_suspend,
+-      .runtime_resume = mali_runtime_resume,
+-      .runtime_idle = mali_runtime_idle,
+-#endif
+-};
+-
+-static struct device_type mali_gpu_device_device_type =
+-{
+-      .pm = &mali_gpu_device_type_pm_ops,
+-};
+-
+-static struct platform_device mali_gpu_device =
+-{
+-      .name = MALI_GPU_NAME_UTGARD,
+-      .id = 0,
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
+-      /* Set in mali_platform_device_register() for these kernels */
+-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
+-      .dev.parent = &exynos4_device_pd[PD_G3D].dev,
+-#else
+-      .dev.parent = &s5pv310_device_pd[PD_G3D].dev,
+-#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) */
+-      .dev.release = mali_platform_device_release,
+-      /*
+-       * We temporarily make use of a device type so that we can control the Mali power
+-       * from within the mali.ko (since the default platform bus implementation will not do that).
+-       * Ideally .dev.pm_domain should be used instead, as this is the new framework designed
+-       * to control the power of devices.
+-       */
+-      .dev.type = &mali_gpu_device_device_type, /* We should probably use the pm_domain instead of type on newer kernels */
+-};
+-
+-static struct mali_gpu_device_data mali_gpu_data =
+-{
+-      .shared_mem_size = 256 * 1024 * 1024, /* 256MB */
+-      .fb_start = 0x40000000,
+-      .fb_size = 0xb1000000,
+-      .utilization_interval = 1000, /* 1000ms */
+-      .utilization_handler = mali_gpu_utilization_handler,
+-};
+-
+-int mali_platform_device_register(void)
+-{
+-      int err;
+-
+-      MALI_DEBUG_PRINT(4, ("mali_platform_device_register() called\n"));
+-
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
+-      exynos_pm_add_dev_to_genpd(&mali_gpu_device, &exynos4_pd_g3d);
+-#endif
+-
+-      /* Connect resources to the device */
+-      err = platform_device_add_resources(&mali_gpu_device, mali_gpu_resources, sizeof(mali_gpu_resources) / sizeof(mali_gpu_resources[0]));
+-      if (0 == err)
+-      {
+-              err = platform_device_add_data(&mali_gpu_device, &mali_gpu_data, sizeof(mali_gpu_data));
+-              if (0 == err)
+-              {
+-                      /* Register the platform device */
+-                      err = platform_device_register(&mali_gpu_device);
+-                      if (0 == err)
+-                      {
+-                              mali_platform_init();
+-
+-#ifdef CONFIG_PM_RUNTIME
+-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+-                              pm_runtime_set_autosuspend_delay(&(mali_gpu_device.dev), 1000);
+-                              pm_runtime_use_autosuspend(&(mali_gpu_device.dev));
+-#endif
+-                              pm_runtime_enable(&(mali_gpu_device.dev));
+-#endif
+-
+-                              return 0;
+-                      }
+-              }
+-
+-              platform_device_unregister(&mali_gpu_device);
+-      }
+-
+-      return err;
+-}
+-
+-void mali_platform_device_unregister(void)
+-{
+-      MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n"));
+-
+-      mali_platform_deinit();
+-
+-      platform_device_unregister(&mali_gpu_device);
+-}
+-
+-static void mali_platform_device_release(struct device *device)
+-{
+-      MALI_DEBUG_PRINT(4, ("mali_platform_device_release() called\n"));
+-}
+-
+-static int mali_os_suspend(struct device *device)
+-{
+-      int ret = 0;
+-
+-      MALI_DEBUG_PRINT(4, ("mali_os_suspend() called\n"));
+-
+-      if (NULL != device->driver &&
+-          NULL != device->driver->pm &&
+-          NULL != device->driver->pm->suspend)
+-      {
+-              /* Need to notify Mali driver about this event */
+-              ret = device->driver->pm->suspend(device);
+-      }
+-
+-      mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP);
+-
+-      return ret;
+-}
+-
+-static int mali_os_resume(struct device *device)
+-{
+-      int ret = 0;
+-
+-      MALI_DEBUG_PRINT(4, ("mali_os_resume() called\n"));
+-
+-      mali_platform_power_mode_change(MALI_POWER_MODE_ON);
+-
+-      if (NULL != device->driver &&
+-          NULL != device->driver->pm &&
+-          NULL != device->driver->pm->resume)
+-      {
+-              /* Need to notify Mali driver about this event */
+-              ret = device->driver->pm->resume(device);
+-      }
+-
+-      return ret;
+-}
+-
+-static int mali_os_freeze(struct device *device)
+-{
+-      int ret = 0;
+-
+-      MALI_DEBUG_PRINT(4, ("mali_os_freeze() called\n"));
+-
+-      if (NULL != device->driver &&
+-          NULL != device->driver->pm &&
+-          NULL != device->driver->pm->freeze)
+-      {
+-              /* Need to notify Mali driver about this event */
+-              ret = device->driver->pm->freeze(device);
+-      }
+-
+-      return ret;
+-}
+-
+-static int mali_os_thaw(struct device *device)
+-{
+-      int ret = 0;
+-
+-      MALI_DEBUG_PRINT(4, ("mali_os_thaw() called\n"));
+-
+-      if (NULL != device->driver &&
+-          NULL != device->driver->pm &&
+-          NULL != device->driver->pm->thaw)
+-      {
+-              /* Need to notify Mali driver about this event */
+-              ret = device->driver->pm->thaw(device);
+-      }
+-
+-      return ret;
+-}
+-
+-#ifdef CONFIG_PM_RUNTIME
+-static int mali_runtime_suspend(struct device *device)
+-{
+-      int ret = 0;
+-
+-      MALI_DEBUG_PRINT(4, ("mali_runtime_suspend() called\n"));
+-
+-      if (NULL != device->driver &&
+-          NULL != device->driver->pm &&
+-          NULL != device->driver->pm->runtime_suspend)
+-      {
+-              /* Need to notify Mali driver about this event */
+-              ret = device->driver->pm->runtime_suspend(device);
+-      }
+-
+-      mali_platform_power_mode_change(MALI_POWER_MODE_LIGHT_SLEEP);
+-
+-      return ret;
+-}
+-
+-static int mali_runtime_resume(struct device *device)
+-{
+-      int ret = 0;
+-
+-      MALI_DEBUG_PRINT(4, ("mali_runtime_resume() called\n"));
+-
+-      mali_platform_power_mode_change(MALI_POWER_MODE_ON);
+-
+-      if (NULL != device->driver &&
+-          NULL != device->driver->pm &&
+-          NULL != device->driver->pm->runtime_resume)
+-      {
+-              /* Need to notify Mali driver about this event */
+-              ret = device->driver->pm->runtime_resume(device);
+-      }
+-
+-      return ret;
+-}
+-
+-static int mali_runtime_idle(struct device *device)
+-{
+-      MALI_DEBUG_PRINT(4, ("mali_runtime_idle() called\n"));
+-
+-      if (NULL != device->driver &&
+-          NULL != device->driver->pm &&
+-          NULL != device->driver->pm->runtime_idle)
+-      {
+-              /* Need to notify Mali driver about this event */
+-              int ret = device->driver->pm->runtime_idle(device);
+-              if (0 != ret)
+-              {
+-                      return ret;
+-              }
+-      }
+-
+-      pm_runtime_suspend(device);
+-
+-      return 0;
+-}
+-#endif
+diff --git a/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4_pmm.c b/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4_pmm.c
+deleted file mode 100644
+index 6e99950..0000000
+--- a/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4_pmm.c
++++ /dev/null
+@@ -1,849 +0,0 @@
+-/*
+- * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+- *
+- * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+- * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+- *
+- * A copy of the licence is included with the program, and can also be obtained from Free Software
+- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+- */
+-
+-/**
+- * @file mali_platform.c
+- * Platform specific Mali driver functions for a default platform
+- */
+-#include "mali_kernel_common.h"
+-#include "mali_osk.h"
+-#include "exynos4_pmm.h"
+-#include <linux/clk.h>
+-#include <linux/err.h>
+-#include <linux/module.h>
+-#include <linux/platform_device.h>
+-#include <linux/regulator/consumer.h>
+-
+-#if defined(CONFIG_MALI400_PROFILING)
+-#include "mali_osk_profiling.h"
+-#endif
+-
+-#if defined(CONFIG_PM_RUNTIME)
+-#include <plat/pd.h>
+-#endif
+-
+-#include <asm/io.h>
+-#include <mach/regs-pmu.h>
+-
+-#include <linux/workqueue.h>
+-
+-#define MALI_DVFS_STEPS 5
+-#define MALI_DVFS_WATING 10 // msec
+-#define MALI_DVFS_DEFAULT_STEP 3
+-
+-#define MALI_DVFS_CLK_DEBUG 0
+-#define SEC_THRESHOLD 1
+-#define LWJ 1
+-
+-#define CPUFREQ_LOCK_DURING_440 0
+-
+-static int bMaliDvfsRun = 0;
+-
+-typedef struct mali_dvfs_tableTag{
+-      unsigned int clock;
+-      unsigned int freq;
+-      unsigned int vol;
+-#if SEC_THRESHOLD
+-      unsigned int downthreshold;
+-    unsigned int upthreshold;
+-#endif
+-}mali_dvfs_table;
+-
+-typedef struct mali_dvfs_statusTag{
+-      unsigned int currentStep;
+-      mali_dvfs_table * pCurrentDvfs;
+-
+-} mali_dvfs_status_t;
+-
+-/*dvfs status*/
+-mali_dvfs_status_t maliDvfsStatus;
+-
+-/*dvfs table*/
+-
+-mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={
+-#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+-                      /*step 0*/{160  ,1000000    ,875000    , 0   , 70},
+-                      /*step 1*/{266  ,1000000    ,900000    ,62   , 90},
+-                      /*step 2*/{350  ,1000000    ,950000    ,85   , 90},
+-                      /*step 3*/{440  ,1000000    ,1025000   ,85   , 90},
+-                      /*step 4*/{533  ,1000000    ,1075000   ,85   ,100} };
+-#else
+-                      /*step 0*/{134  ,1000000    , 950000   ,85   , 90},
+-                      /*step 1*/{267  ,1000000    ,1050000   ,85   ,100} };
+-#endif
+-
+-
+-#define EXTXTALCLK_NAME  "ext_xtal"
+-#define VPLLSRCCLK_NAME  "vpll_src"
+-#define FOUTVPLLCLK_NAME "fout_vpll"
+-#define SCLVPLLCLK_NAME  "sclk_vpll"
+-#define GPUMOUT1CLK_NAME "mout_g3d1"
+-
+-#define MPLLCLK_NAME     "mout_mpll"
+-#define GPUMOUT0CLK_NAME "mout_g3d0"
+-#define GPUCLK_NAME      "sclk_g3d"
+-#define CLK_DIV_STAT_G3D 0x1003C62C
+-#define CLK_DESC         "clk-divider-status"
+-
+-static struct clk *ext_xtal_clock = NULL;
+-static struct clk *vpll_src_clock = NULL;
+-static struct clk *fout_vpll_clock = NULL;
+-static struct clk *sclk_vpll_clock = NULL;
+-
+-static struct clk *mpll_clock = NULL;
+-static struct clk *mali_parent_clock = NULL;
+-static struct clk *mali_clock = NULL;
+-
+-#if defined(CONFIG_CPU_EXYNOS4412) || defined(CONFIG_CPU_EXYNOS4212)
+-/* Pegasus */
+-static const mali_bool bis_vpll  = MALI_TRUE;
+-unsigned int mali_gpu_clk = 440;
+-unsigned int mali_gpu_vol = 1025000;
+-#else
+-/* Orion */
+-static const mali_bool bis_vpll  = MALI_FALSE;
+-int mali_gpu_clk                 = 267;
+-static unsigned int mali_gpu_vol = 1050000; /* 1.05V */
+-#endif
+-
+-static unsigned int GPU_MHZ   =               1000000;
+-
+-int  gpu_power_state;
+-static int bPoweroff;
+-
+-#ifdef CONFIG_REGULATOR
+-struct regulator *g3d_regulator = NULL;
+-#endif
+-
+-mali_io_address clk_register_map = 0;
+-
+-/* DVFS */
+-static unsigned int mali_dvfs_utilization = 255;
+-
+-static void mali_dvfs_work_handler(struct work_struct *w);
+-
+-static struct workqueue_struct *mali_dvfs_wq = 0;
+-
+-extern mali_io_address clk_register_map;
+-
+-_mali_osk_lock_t *mali_dvfs_lock = 0; 
+-
+-static DECLARE_WORK(mali_dvfs_work, mali_dvfs_work_handler);
+-
+-
+-/* export GPU frequency as a read-only parameter so that it can be read in /sys */
+-module_param(mali_gpu_clk, int, S_IRUSR | S_IRGRP | S_IROTH);
+-MODULE_PARM_DESC(mali_gpu_clk, "GPU frequency in MHz");
+-
+-#ifdef CONFIG_REGULATOR
+-void mali_regulator_disable(void)
+-{
+-      if(IS_ERR_OR_NULL(g3d_regulator))
+-      {
+-              MALI_DEBUG_PRINT(1, ("error on mali_regulator_disable : g3d_regulator is null\n"));
+-              return;
+-      }
+-      regulator_disable(g3d_regulator);
+-}
+-
+-void mali_regulator_enable(void)
+-{
+-      if(IS_ERR_OR_NULL(g3d_regulator))
+-      {
+-              MALI_DEBUG_PRINT(1, ("error on mali_regulator_enable : g3d_regulator is null\n"));
+-              return;
+-      }
+-      regulator_enable(g3d_regulator);
+-}
+-
+-void mali_regulator_set_voltage(int min_uV, int max_uV)
+-{
+-      _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+-      if(IS_ERR_OR_NULL(g3d_regulator))
+-      {
+-              MALI_DEBUG_PRINT(1, ("error on mali_regulator_set_voltage : g3d_regulator is null\n"));
+-              return;
+-      }
+-      MALI_PRINT(("= regulator_set_voltage: %d, %d \n",min_uV, max_uV));
+-      regulator_set_voltage(g3d_regulator, min_uV, max_uV);
+-      mali_gpu_vol = regulator_get_voltage(g3d_regulator);
+-      MALI_DEBUG_PRINT(1, ("Mali voltage: %d\n", mali_gpu_vol));
+-      _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+-}
+-#endif
+-
+-unsigned long mali_clk_get_rate(void)
+-{
+-//    return clk_get_rate(mali_clock);
+-#if LWJ
+-      return maliDvfsStatus.currentStep;
+-#endif
+-}
+-
+-
+-static unsigned int get_mali_dvfs_status(void)
+-{
+-      return maliDvfsStatus.currentStep;
+-}
+-
+-mali_bool mali_clk_get(void)
+-{
+-      if (bis_vpll)
+-      {
+-              if (ext_xtal_clock == NULL)
+-              {
+-                      ext_xtal_clock = clk_get(NULL,EXTXTALCLK_NAME);
+-                      if (IS_ERR(ext_xtal_clock)) {
+-                              MALI_PRINT( ("MALI Error : failed to get source ext_xtal_clock\n"));
+-                              return MALI_FALSE;
+-                      }
+-              }
+-
+-              if (vpll_src_clock == NULL)
+-              {
+-                      vpll_src_clock = clk_get(NULL,VPLLSRCCLK_NAME);
+-                      if (IS_ERR(vpll_src_clock)) {
+-                              MALI_PRINT( ("MALI Error : failed to get source vpll_src_clock\n"));
+-                              return MALI_FALSE;
+-                      }
+-              }
+-
+-              if (fout_vpll_clock == NULL)
+-              {
+-                      fout_vpll_clock = clk_get(NULL,FOUTVPLLCLK_NAME);
+-                      if (IS_ERR(fout_vpll_clock)) {
+-                              MALI_PRINT( ("MALI Error : failed to get source fout_vpll_clock\n"));
+-                              return MALI_FALSE;
+-                      }
+-              }
+-
+-              if (sclk_vpll_clock == NULL)
+-              {
+-                      sclk_vpll_clock = clk_get(NULL,SCLVPLLCLK_NAME);
+-                      if (IS_ERR(sclk_vpll_clock)) {
+-                              MALI_PRINT( ("MALI Error : failed to get source sclk_vpll_clock\n"));
+-                              return MALI_FALSE;
+-                      }
+-              }
+-
+-              if (mali_parent_clock == NULL)
+-              {
+-                      mali_parent_clock = clk_get(NULL, GPUMOUT1CLK_NAME);
+-
+-                      if (IS_ERR(mali_parent_clock)) {
+-                              MALI_PRINT( ( "MALI Error : failed to get source mali parent clock\n"));
+-                              return MALI_FALSE;
+-                      }
+-              }
+-      }
+-      else // mpll
+-      {
+-              if (mpll_clock == NULL)
+-              {
+-                      mpll_clock = clk_get(NULL,MPLLCLK_NAME);
+-
+-                      if (IS_ERR(mpll_clock)) {
+-                              MALI_PRINT( ("MALI Error : failed to get source mpll clock\n"));
+-                              return MALI_FALSE;
+-                      }
+-              }
+-
+-              if (mali_parent_clock == NULL)
+-              {
+-                      mali_parent_clock = clk_get(NULL, GPUMOUT0CLK_NAME);
+-
+-                      if (IS_ERR(mali_parent_clock)) {
+-                              MALI_PRINT( ( "MALI Error : failed to get source mali parent clock\n"));
+-                              return MALI_FALSE;
+-                      }
+-              }
+-      }
+-
+-      // mali clock get always.
+-      if (mali_clock == NULL)
+-      {
+-              mali_clock = clk_get(NULL, GPUCLK_NAME);
+-
+-              if (IS_ERR(mali_clock)) {
+-                      MALI_PRINT( ("MALI Error : failed to get source mali clock\n"));
+-                      return MALI_FALSE;
+-              }
+-      }
+-
+-      return MALI_TRUE;
+-}
+-
+-void mali_clk_put(mali_bool binc_mali_clock)
+-{
+-      if (mali_parent_clock)
+-      {
+-              clk_put(mali_parent_clock);
+-              mali_parent_clock = NULL;
+-      }
+-
+-      if (mpll_clock)
+-      {
+-              clk_put(mpll_clock);
+-              mpll_clock = NULL;
+-      }
+-
+-      if (sclk_vpll_clock)
+-      {
+-              clk_put(sclk_vpll_clock);
+-              sclk_vpll_clock = NULL;
+-      }
+-
+-      if (binc_mali_clock && fout_vpll_clock)
+-      {
+-              clk_put(fout_vpll_clock);
+-              fout_vpll_clock = NULL;
+-      }
+-
+-      if (vpll_src_clock)
+-      {
+-              clk_put(vpll_src_clock);
+-              vpll_src_clock = NULL;
+-      }
+-
+-      if (ext_xtal_clock)
+-      {
+-              clk_put(ext_xtal_clock);
+-              ext_xtal_clock = NULL;
+-      }
+-
+-      if (binc_mali_clock && mali_clock)
+-      {
+-              clk_put(mali_clock);
+-              mali_clock = NULL;
+-      }
+-}
+-
+-void mali_clk_set_rate(unsigned int clk, unsigned int mhz)
+-{
+-      int err;
+-      unsigned long rate = (unsigned long)clk * (unsigned long)mhz;
+-
+-      _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+-      MALI_DEBUG_PRINT(3, ("Mali platform: Setting frequency to %d mhz\n", clk));
+-      if (bis_vpll && fout_vpll_clock)
+-      {
+-              err = clk_set_rate(fout_vpll_clock, (unsigned int)mali_gpu_clk * GPU_MHZ);
+-              if (err) MALI_PRINT_ERROR(("Failed to set vpll: %d\n", err));
+-      }
+-      err = clk_set_rate(mali_clock, rate);
+-      if (err) MALI_PRINT_ERROR(("Failed to set Mali clock: %d\n", err));
+-
+-      rate = mali_clk_get_rate();
+-
+-      MALI_PRINT(("Mali frequency %d\n", rate / mhz));
+-      GPU_MHZ = mhz;
+-      _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+-}
+-
+-mali_bool set_mali_dvfs_current_step(unsigned int step)
+-{
+-      _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+-      maliDvfsStatus.currentStep = step % MALI_DVFS_STEPS;
+-//    if (step >= MAX_MALI_DVFS_STEPS) //LWJ
+-//            mali_runtime_resumed = maliDvfsStatus.currentStep;
+-      _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+-      return MALI_TRUE;
+-}
+-
+-
+-static mali_bool set_mali_dvfs_status(u32 step,mali_bool boostup)
+-{
+-      u32 validatedStep=step;
+-#if MALI_DVFS_CLK_DEBUG
+-      unsigned int *pRegMaliClkDiv;
+-      unsigned int *pRegMaliMpll;
+-#endif
+-
+-      if(boostup)
+-      {
+-#ifdef CONFIG_REGULATOR
+-              /*change the voltage*/
+-              mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol);
+-#endif
+-              /*change the clock*/
+-              mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq);
+-      }
+-      else
+-      {
+-              /*change the clock*/
+-              mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq);
+-#ifdef CONFIG_REGULATOR
+-              /*change the voltage*/
+-              mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol);
+-#endif
+-      }
+-
+-#if defined(CONFIG_MALI400_PROFILING)
+-      _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE| MALI_PROFILING_EVENT_CHANNEL_GPU|MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0);
+-#endif
+-      mali_clk_put(MALI_FALSE);
+-
+-#if MALI_DVFS_CLK_DEBUG
+-      pRegMaliClkDiv = ioremap(0x1003c52c,32);
+-      pRegMaliMpll = ioremap(0x1003c22c,32);
+-      MALI_PRINT( ("Mali MPLL reg:%d, CLK DIV: %d \n",*pRegMaliMpll, *pRegMaliClkDiv));
+-#endif
+-
+-#ifdef EXYNOS4_ASV_ENABLED
+-      if (samsung_rev() < EXYNOS4412_REV_2_0) {
+-              if (mali_dvfs[step].clock == 160)
+-                      exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_100V);
+-              else
+-                      exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_130V);
+-      }
+-#endif
+-
+-
+-//    maliDvfsStatus.currentStep = validatedStep;
+-      set_mali_dvfs_current_step(validatedStep);
+-      /*for future use*/
+-      maliDvfsStatus.pCurrentDvfs = &mali_dvfs[validatedStep];
+-
+-#if CPUFREQ_LOCK_DURING_440
+-      /* lock/unlock CPU freq by Mali */
+-      if (mali_dvfs[step].clock == 440)
+-              err = cpufreq_lock_by_mali(1200);
+-      else
+-              cpufreq_unlock_by_mali();
+-#endif
+-
+-
+-      return MALI_TRUE;
+-}
+-
+-static void mali_platform_wating(u32 msec)
+-{
+-      /*sample wating
+-      change this in the future with proper check routine.
+-      */
+-      unsigned int read_val;
+-      while(1)
+-      {
+-              read_val = _mali_osk_mem_ioread32(clk_register_map, 0x00);
+-              if ((read_val & 0x8000)==0x0000) break;
+-
+-              _mali_osk_time_ubusydelay(100); /* 1000 -> 100 : 20101218 */
+-      }
+-      /* _mali_osk_time_ubusydelay(msec*1000);*/
+-}
+-
+-static mali_bool change_mali_dvfs_status(u32 step, mali_bool boostup )
+-{
+-      MALI_DEBUG_PRINT(4, ("> change_mali_dvfs_status: %d, %d \n",step, boostup));
+-
+-      if(!set_mali_dvfs_status(step, boostup))
+-      {
+-              MALI_DEBUG_PRINT(1, ("error on set_mali_dvfs_status: %d, %d \n",step, boostup));
+-              return MALI_FALSE;
+-      }
+-
+-      /*wait until clock and voltage is stablized*/
+-      mali_platform_wating(MALI_DVFS_WATING); /*msec*/
+-
+-      return MALI_TRUE;
+-}
+-
+-static unsigned int decideNextStatus(unsigned int utilization)
+-{
+-      unsigned int level=0; /* 0:stay, 1:up */
+-#if 0
+-      if( utilization>127 && maliDvfsStatus.currentStep==0 ) /* over 60% -> 50% (up fast) */
+-              level=1;
+-      else if( utilization<51 && maliDvfsStatus.currentStep==1 ) /* under 30% -> 20% (down slow) */
+-              level=0;
+-      else
+-              level = maliDvfsStatus.currentStep;
+-#else
+-
+-      level = maliDvfsStatus.currentStep;
+-//    if (maliDvfsStatus.currentStep) {
+-              if (utilization > (int)(255 * mali_dvfs[maliDvfsStatus.currentStep].upthreshold / 100) &&
+-                              level < MALI_DVFS_STEPS - 1) {
+-                      level++;
+-//                    if ((samsung_rev() < EXYNOS4412_REV_2_0) && (maliDvfsStatus.currentStep == 3)) {
+-//                            level=get_mali_dvfs_status();
+-//                    }
+-              }
+-              if (utilization < (int)(255 * mali_dvfs[maliDvfsStatus.currentStep].downthreshold / 100) &&
+-                              level > 0) {
+-                      level--;
+-              }
+-//    } 
+-#endif
+-      printk("LWJ %s Level %d\n", __func__, level);
+-      return level;
+-}
+-
+-static mali_bool mali_dvfs_status(unsigned int utilization)
+-{
+-      unsigned int nextStatus=0;
+-      unsigned int curStatus=0;
+-      mali_bool boostup=0;
+-
+-      MALI_DEBUG_PRINT(4, ("> mali_dvfs_status: %d \n",utilization));
+-
+-      /*decide next step*/
+-      curStatus = get_mali_dvfs_status();
+-      printk("LWJ curStatus %d\n",curStatus);
+-      nextStatus = decideNextStatus(utilization);
+-
+-      MALI_DEBUG_PRINT(4, ("= curStatus %d, nextStatus %d, maliDvfsStatus.currentStep %d \n", curStatus, nextStatus, maliDvfsStatus.currentStep));
+-      /*if next status is same with current status, don't change anything*/
+-      if(curStatus!=nextStatus)
+-      {
+-              /*check if boost up or not*/
+-              if(nextStatus > maliDvfsStatus.currentStep) boostup = 1;
+-
+-              /*change mali dvfs status*/
+-              if(!change_mali_dvfs_status(nextStatus,boostup))
+-              {
+-                      MALI_DEBUG_PRINT(1, ("error on change_mali_dvfs_status \n"));
+-                      return MALI_FALSE;
+-              }
+-      }
+-      return MALI_TRUE;
+-}
+-
+-
+-int mali_dvfs_is_running(void)
+-{
+-      return bMaliDvfsRun;
+-}
+-
+-
+-static void mali_dvfs_work_handler(struct work_struct *w)
+-{
+-      bMaliDvfsRun=1;
+-
+-      MALI_DEBUG_PRINT(3, ("=== mali_dvfs_work_handler\n"));
+-
+-      if(!mali_dvfs_status(mali_dvfs_utilization))
+-      MALI_DEBUG_PRINT(1,( "error on mali dvfs status in mali_dvfs_work_handler"));
+-
+-      bMaliDvfsRun=0;
+-}
+-
+-
+-mali_bool init_mali_dvfs_status(void)
+-{
+-      /*default status
+-      add here with the right function to get initilization value.
+-      */
+-
+-      if (!mali_dvfs_wq)
+-      {
+-              mali_dvfs_wq = create_singlethread_workqueue("mali_dvfs");
+-      }
+-
+-      /*add a error handling here*/
+-      maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP;
+-
+-      return MALI_TRUE;
+-}
+-
+-void deinit_mali_dvfs_status(void)
+-{
+-      if (mali_dvfs_wq)
+-      {
+-              destroy_workqueue(mali_dvfs_wq);
+-              mali_dvfs_wq = NULL;
+-      }
+-}
+-
+-mali_bool mali_dvfs_handler(unsigned int utilization)
+-{
+-      mali_dvfs_utilization = utilization;
+-      queue_work(mali_dvfs_wq,&mali_dvfs_work);
+-
+-      /*add error handle here*/
+-
+-      return MALI_TRUE;
+-}
+-
+-static mali_bool init_mali_clock(void)
+-{
+-      mali_bool ret = MALI_TRUE;
+-      gpu_power_state = 0;
+-      bPoweroff = 1;
+-
+-      if (mali_clock != 0)
+-              return ret; /* already initialized */
+-
+-      mali_dvfs_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE
+-                      | _MALI_OSK_LOCKFLAG_ONELOCK, 0, 0);
+-      if (mali_dvfs_lock == NULL)
+-              return _MALI_OSK_ERR_FAULT;
+-
+-
+-
+-      if (!mali_clk_get())
+-      {
+-              MALI_PRINT(("Error: Failed to get Mali clock\n"));
+-              goto err_clk;
+-      }
+-
+-      if (bis_vpll)
+-      {
+-              clk_set_parent(vpll_src_clock, ext_xtal_clock);
+-              clk_set_parent(sclk_vpll_clock, fout_vpll_clock);
+-
+-              clk_set_parent(mali_parent_clock, sclk_vpll_clock);
+-              clk_set_parent(mali_clock, mali_parent_clock);
+-      }
+-      else
+-      {
+-              clk_set_parent(mali_parent_clock, mpll_clock);
+-              clk_set_parent(mali_clock, mali_parent_clock);
+-      }
+-
+-      if (clk_enable(mali_clock) < 0)
+-      {
+-              MALI_PRINT(("Error: Failed to enable clock\n"));
+-              goto err_clk;
+-      }
+-
+-      mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ);
+-
+-      MALI_PRINT(("init_mali_clock mali_clock %x\n", mali_clock));
+-
+-#ifdef CONFIG_REGULATOR
+-      g3d_regulator = regulator_get(NULL, "vdd_g3d");
+-
+-      if (IS_ERR(g3d_regulator))
+-      {
+-              MALI_PRINT( ("MALI Error : failed to get vdd_g3d\n"));
+-              ret = MALI_FALSE;
+-              goto err_regulator;
+-      }
+-
+-      regulator_enable(g3d_regulator);
+-      mali_regulator_set_voltage(mali_gpu_vol, mali_gpu_vol);
+-#endif
+-
+-#if defined(CONFIG_MALI400_PROFILING)
+-      _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|
+-                      MALI_PROFILING_EVENT_CHANNEL_GPU|MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
+-                      mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0);
+-#endif
+-
+-      mali_clk_put(MALI_FALSE);
+-
+-      return MALI_TRUE;
+-
+-#ifdef CONFIG_REGULATOR
+-err_regulator:
+-      regulator_put(g3d_regulator);
+-#endif
+-err_clk:
+-      mali_clk_put(MALI_TRUE);
+-
+-      return ret;
+-}
+-
+-static mali_bool deinit_mali_clock(void)
+-{
+-      if (mali_clock == 0)
+-              return MALI_TRUE;
+-
+-#ifdef CONFIG_REGULATOR
+-      if (g3d_regulator)
+-      {
+-              regulator_put(g3d_regulator);
+-              g3d_regulator = NULL;
+-      }
+-#endif
+-
+-      mali_clk_put(MALI_TRUE);
+-
+-      return MALI_TRUE;
+-}
+-
+-
+-static _mali_osk_errcode_t enable_mali_clocks(void)
+-{
+-      int err;
+-      err = clk_enable(mali_clock);
+-      MALI_DEBUG_PRINT(3,("enable_mali_clocks mali_clock %p error %d \n", mali_clock, err));
+-
+-      /* set clock rate */
+-      mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ);
+-
+-      maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP;
+-
+-      MALI_SUCCESS;
+-}
+-
+-static _mali_osk_errcode_t disable_mali_clocks(void)
+-{
+-      clk_disable(mali_clock);
+-      MALI_DEBUG_PRINT(3,("disable_mali_clocks mali_clock %p \n", mali_clock));
+-
+-      MALI_SUCCESS;
+-}
+-
+-/* Some defines changed names in later Odroid-A kernels. Make sure it works for both. */
+-#ifndef S5P_G3D_CONFIGURATION
+-#define S5P_G3D_CONFIGURATION S5P_PMU_G3D_CONF
+-#endif
+-#ifndef S5P_G3D_STATUS
+-#define S5P_G3D_STATUS S5P_PMU_G3D_CONF + 0x4
+-#endif
+-
+-_mali_osk_errcode_t g3d_power_domain_control(int bpower_on)
+-{
+-      if (bpower_on)
+-      {
+-              void __iomem *status;
+-              u32 timeout;
+-              __raw_writel(EXYNOS_INT_LOCAL_PWR_EN, S5P_G3D_CONFIGURATION);
+-              status = S5P_G3D_STATUS;
+-
+-              timeout = 10;
+-              while ((__raw_readl(status) & EXYNOS_INT_LOCAL_PWR_EN)
+-                      != EXYNOS_INT_LOCAL_PWR_EN) {
+-                      if (timeout == 0) {
+-                              MALI_PRINTF(("Power domain  enable failed.\n"));
+-                              return -ETIMEDOUT;
+-                      }
+-                      timeout--;
+-                      _mali_osk_time_ubusydelay(100);
+-              }
+-      }
+-      else
+-      {
+-              void __iomem *status;
+-              u32 timeout;
+-              __raw_writel(0, S5P_G3D_CONFIGURATION);
+-
+-              status = S5P_G3D_STATUS;
+-              /* Wait max 1ms */
+-              timeout = 10;
+-              while (__raw_readl(status) & EXYNOS_INT_LOCAL_PWR_EN)
+-              {
+-                      if (timeout == 0) {
+-                              MALI_PRINTF(("Power domain  disable failed.\n" ));
+-                              return -ETIMEDOUT;
+-                      }
+-                      timeout--;
+-                      _mali_osk_time_ubusydelay( 100);
+-              }
+-      }
+-
+-      MALI_SUCCESS;
+-}
+-
+-_mali_osk_errcode_t mali_platform_init(void)
+-{
+-      MALI_CHECK(init_mali_clock(), _MALI_OSK_ERR_FAULT);
+-#ifdef CONFIG_MALI_DVFS
+-      if (!clk_register_map) clk_register_map = _mali_osk_mem_mapioregion( CLK_DIV_STAT_G3D, 0x20, CLK_DESC );
+-      if(!init_mali_dvfs_status())
+-              MALI_DEBUG_PRINT(1, ("mali_platform_init failed\n"));
+-#endif
+-      mali_platform_power_mode_change(MALI_POWER_MODE_ON);
+-
+-      MALI_SUCCESS;
+-}
+-
+-_mali_osk_errcode_t mali_platform_deinit(void)
+-{
+-
+-      mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP);
+-      deinit_mali_clock();
+-
+-#ifdef CONFIG_MALI_DVFS
+-      deinit_mali_dvfs_status();
+-      if (clk_register_map )
+-      {
+-              _mali_osk_mem_unmapioregion(CLK_DIV_STAT_G3D, 0x20, clk_register_map);
+-              clk_register_map = NULL;
+-      }
+-#endif
+-
+-      MALI_SUCCESS;
+-}
+-
+-_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode)
+-{
+-      switch (power_mode)
+-      {
+-              case MALI_POWER_MODE_ON:
+-                      MALI_DEBUG_PRINT(3, ("Mali platform: Got MALI_POWER_MODE_ON event, %s\n",
+-                                           bPoweroff ? "powering on" : "already on"));
+-                      if (bPoweroff == 1)
+-                      {
+-#if !defined(CONFIG_PM_RUNTIME)
+-                              g3d_power_domain_control(1);
+-#endif
+-                              MALI_DEBUG_PRINT(4,("enable clock \n"));
+-                              enable_mali_clocks();
+-#if defined(CONFIG_MALI400_PROFILING)
+-                              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
+-                                              MALI_PROFILING_EVENT_CHANNEL_GPU |
+-                                              MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, mali_gpu_clk,
+-                                              mali_gpu_vol/1000, 0, 0, 0);
+-
+-#endif
+-                              bPoweroff=0;
+-                      }
+-                      break;
+-              case MALI_POWER_MODE_LIGHT_SLEEP:
+-              case MALI_POWER_MODE_DEEP_SLEEP:
+-                      MALI_DEBUG_PRINT(3, ("Mali platform: Got %s event, %s\n", power_mode ==
+-                                              MALI_POWER_MODE_LIGHT_SLEEP ?  "MALI_POWER_MODE_LIGHT_SLEEP" :
+-                                              "MALI_POWER_MODE_DEEP_SLEEP", bPoweroff ? "already off" : "powering off"));
+-                      if (bPoweroff == 0)
+-                      {
+-                              disable_mali_clocks();
+-#if defined(CONFIG_MALI400_PROFILING)
+-                              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
+-                                              MALI_PROFILING_EVENT_CHANNEL_GPU |
+-                                              MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, 0, 0, 0, 0, 0);
+-#endif
+-
+-#if !defined(CONFIG_PM_RUNTIME)
+-                              g3d_power_domain_control(0);
+-#endif
+-                              bPoweroff=1;
+-                      }
+-
+-                      break;
+-      }
+-      MALI_SUCCESS;
+-}
+-
+-void mali_gpu_utilization_handler(unsigned int utilization)
+-{
+-      printk("LWJ utilization %d\n",utilization);
+-      if (bPoweroff==0)
+-      {
+-#ifdef CONFIG_MALI_DVFS
+-              if(!mali_dvfs_handler(utilization))
+-                      MALI_DEBUG_PRINT(1,( "error on mali dvfs status in utilization\n"));
+-#endif
+-      }
+-}
+-
+-
+-/*REGISTER
+- Enable Power
+- pPowerPTR = ioremap(0x10023C60,32);
+- *pPowerPTR |= 0x7;
+-
+- Enable Clock
+- pPTR = ioremap(0x1003C92C,32);
+- *pPTR |= 0x1;
+-*/
+-
+diff --git a/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4_pmm.h b/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4_pmm.h
+deleted file mode 100644
+index 46a269e..0000000
+--- a/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4_pmm.h
++++ /dev/null
+@@ -1,86 +0,0 @@
+-/*
+- * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+- *
+- * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+- * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+- *
+- * A copy of the licence is included with the program, and can also be obtained from Free Software
+- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+- */
+-
+-/**
+- * @file mali_platform.h
+- * Platform specific Mali driver functions
+- */
+-
+-#ifndef __EXYNOS4_PMM_H__
+-#define __EXYNOS4_PMM_H__
+-
+-#include "mali_osk.h"
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-/** @brief description of power change reasons
+- */
+-typedef enum mali_power_mode_tag
+-{
+-      MALI_POWER_MODE_ON,
+-      MALI_POWER_MODE_LIGHT_SLEEP,
+-      MALI_POWER_MODE_DEEP_SLEEP,
+-} mali_power_mode;
+-
+-/** @brief Platform specific setup and initialisation of MALI
+- *
+- * This is called from the entrypoint of the driver to initialize the platform
+- *
+- * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
+- */
+-_mali_osk_errcode_t mali_platform_init(void);
+-
+-/** @brief Platform specific deinitialisation of MALI
+- *
+- * This is called on the exit of the driver to terminate the platform
+- *
+- * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
+- */
+-_mali_osk_errcode_t mali_platform_deinit(void);
+-
+-/** @brief Platform specific powerdown sequence of MALI
+- *
+- * Call as part of platform init if there is no PMM support, else the
+- * PMM will call it. 
+- * There are three power modes defined:
+- *  1) MALI_POWER_MODE_ON
+- *  2) MALI_POWER_MODE_LIGHT_SLEEP
+- *  3) MALI_POWER_MODE_DEEP_SLEEP
+- * MALI power management module transitions to MALI_POWER_MODE_LIGHT_SLEEP mode when MALI is idle
+- * for idle timer (software timer defined in mali_pmm_policy_jobcontrol.h) duration, MALI transitions
+- * to MALI_POWER_MODE_LIGHT_SLEEP mode during timeout if there are no more jobs queued.
+- * MALI power management module transitions to MALI_POWER_MODE_DEEP_SLEEP mode when OS does system power
+- * off. 
+- * Customer has to add power down code when MALI transitions to MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP
+- * mode.
+- * MALI_POWER_MODE_ON mode is entered when the MALI is to powered up. Some customers want to control voltage regulators during
+- * the whole system powers on/off. Customer can track in this function whether the MALI is powered up from
+- * MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP mode and manage the voltage regulators as well.
+- * @param power_mode defines the power modes
+- * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
+- */
+-_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode);
+-
+-
+-/** @brief Platform specific handling of GPU utilization data
+- *
+- * When GPU utilization data is enabled, this function will be
+- * periodically called.
+- *
+- * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization.
+- */
+-void mali_gpu_utilization_handler(unsigned int utilization);
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-#endif
+diff --git a/drivers/gpu/arm/mali400/mali/platform/pegasus-m400/exynos4.c b/drivers/gpu/arm/mali400/mali/platform/pegasus-m400/exynos4.c
+deleted file mode 100644
+index 493bd7b..0000000
+--- a/drivers/gpu/arm/mali400/mali/platform/pegasus-m400/exynos4.c
++++ /dev/null
+@@ -1,273 +0,0 @@
+-/*
+- * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+- *
+- * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+- * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+- *
+- * A copy of the licence is included with the program, and can also be obtained from Free Software
+- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+- */
+-
+-/**
+- * @file mali_platform.c
+- * Platform specific Mali driver functions for the exynos 4XXX based platforms
+- */
+-#include <linux/platform_device.h>
+-#include <linux/version.h>
+-#include <linux/pm.h>
+-#ifdef CONFIG_PM_RUNTIME
+-#include <linux/pm_runtime.h>
+-#endif
+-#include <linux/mali/mali_utgard.h>
+-#include "mali_kernel_common.h"
+-
+-#include <linux/irq.h>
+-#include <plat/devs.h>
+-
+-#include "exynos4_pmm.h"
+-
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
+-struct exynos_pm_domain;
+-//extern struct exynos_pm_domain exynos4_pd_g3d;
+-void exynos_pm_add_dev_to_genpd(struct platform_device *pdev, struct exynos_pm_domain *pd);
+-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
+-extern struct platform_device exynos4_device_pd[];
+-#else
+-extern struct platform_device s5pv310_device_pd[];
+-#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) */
+-
+-static void mali_platform_device_release(struct device *device);
+-static int mali_os_suspend(struct device *device);
+-static int mali_os_resume(struct device *device);
+-static int mali_os_freeze(struct device *device);
+-static int mali_os_thaw(struct device *device);
+-#ifdef CONFIG_PM_RUNTIME
+-static int mali_runtime_suspend(struct device *device);
+-static int mali_runtime_resume(struct device *device);
+-static int mali_runtime_idle(struct device *device);
+-#endif
+-
+-#define MALI_GP_IRQ       EXYNOS4_IRQ_GP_3D
+-#define MALI_PP0_IRQ      EXYNOS4_IRQ_PP0_3D
+-#define MALI_PP1_IRQ      EXYNOS4_IRQ_PP1_3D
+-#define MALI_PP2_IRQ      EXYNOS4_IRQ_PP2_3D
+-#define MALI_PP3_IRQ      EXYNOS4_IRQ_PP3_3D
+-#define MALI_GP_MMU_IRQ   EXYNOS4_IRQ_GPMMU_3D
+-#define MALI_PP0_MMU_IRQ  EXYNOS4_IRQ_PPMMU0_3D
+-#define MALI_PP1_MMU_IRQ  EXYNOS4_IRQ_PPMMU1_3D
+-#define MALI_PP2_MMU_IRQ  EXYNOS4_IRQ_PPMMU2_3D
+-#define MALI_PP3_MMU_IRQ  EXYNOS4_IRQ_PPMMU3_3D
+-
+-static struct resource mali_gpu_resources[] =
+-{
+-      MALI_GPU_RESOURCES_MALI400_MP4(0x13000000,
+-                                     MALI_GP_IRQ, MALI_GP_MMU_IRQ,
+-                                     MALI_PP0_IRQ, MALI_PP0_MMU_IRQ,
+-                                     MALI_PP1_IRQ, MALI_PP1_MMU_IRQ,
+-                                     MALI_PP2_IRQ, MALI_PP2_MMU_IRQ,
+-                                     MALI_PP3_IRQ, MALI_PP3_MMU_IRQ)
+-};
+-
+-static struct dev_pm_ops mali_gpu_device_type_pm_ops =
+-{
+-      .suspend = mali_os_suspend,
+-      .resume = mali_os_resume,
+-      .freeze = mali_os_freeze,
+-      .thaw = mali_os_thaw,
+-#ifdef CONFIG_PM_RUNTIME
+-      .runtime_suspend = mali_runtime_suspend,
+-      .runtime_resume = mali_runtime_resume,
+-      .runtime_idle = mali_runtime_idle,
+-#endif
+-};
+-
+-static struct device_type mali_gpu_device_device_type =
+-{
+-      .pm = &mali_gpu_device_type_pm_ops,
+-};
+-
+-
+-static struct platform_device *mali_gpu_device;
+-
+-static struct mali_gpu_device_data mali_gpu_data =
+-{
+-      .shared_mem_size = 256 * 1024 * 1024, /* 256MB */
+-      .fb_start = 0x40000000,
+-      .fb_size = 0xb1000000,
+-      .utilization_interval = 1000, /* 1000ms */
+-      .utilization_handler = mali_gpu_utilization_handler,
+-};
+-
+-int mali_platform_device_register(void)
+-{
+-      int err;
+-
+-      MALI_DEBUG_PRINT(4, ("mali_platform_device_register() called\n"));
+-
+-      /* Connect resources to the device */
+-      err = platform_device_add_resources(&exynos4_device_g3d, mali_gpu_resources, sizeof(mali_gpu_resources) / sizeof(mali_gpu_resources[0]));
+-      if (0 == err)
+-      {
+-              err = platform_device_add_data(&exynos4_device_g3d, &mali_gpu_data, sizeof(mali_gpu_data));
+-              if (0 == err)
+-              {
+-                      mali_platform_init();
+-
+-#ifdef CONFIG_PM_RUNTIME
+-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+-                      pm_runtime_set_autosuspend_delay(&(exynos4_device_g3d.dev), 1000);
+-                      pm_runtime_use_autosuspend(&(exynos4_device_g3d.dev));
+-#endif
+-                      pm_runtime_enable(&(exynos4_device_g3d.dev));
+-#endif
+-                      return 0;
+-              }
+-
+-      }
+-      return err;
+-}
+-
+-void mali_platform_device_unregister(void)
+-{
+-      MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n"));
+-
+-      mali_platform_deinit();
+-}
+-
+-static void mali_platform_device_release(struct device *device)
+-{
+-      MALI_DEBUG_PRINT(4, ("mali_platform_device_release() called\n"));
+-}
+-
+-static int mali_os_suspend(struct device *device)
+-{
+-      int ret = 0;
+-
+-      MALI_DEBUG_PRINT(4, ("mali_os_suspend() called\n"));
+-
+-      if (NULL != device->driver &&
+-          NULL != device->driver->pm &&
+-          NULL != device->driver->pm->suspend)
+-      {
+-              /* Need to notify Mali driver about this event */
+-              ret = device->driver->pm->suspend(device);
+-      }
+-
+-      mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP);
+-
+-      return ret;
+-}
+-
+-static int mali_os_resume(struct device *device)
+-{
+-      int ret = 0;
+-
+-      MALI_DEBUG_PRINT(4, ("mali_os_resume() called\n"));
+-
+-      mali_platform_power_mode_change(MALI_POWER_MODE_ON);
+-
+-      if (NULL != device->driver &&
+-          NULL != device->driver->pm &&
+-          NULL != device->driver->pm->resume)
+-      {
+-              /* Need to notify Mali driver about this event */
+-              ret = device->driver->pm->resume(device);
+-      }
+-
+-      return ret;
+-}
+-
+-static int mali_os_freeze(struct device *device)
+-{
+-      int ret = 0;
+-
+-      MALI_DEBUG_PRINT(4, ("mali_os_freeze() called\n"));
+-
+-      if (NULL != device->driver &&
+-          NULL != device->driver->pm &&
+-          NULL != device->driver->pm->freeze)
+-      {
+-              /* Need to notify Mali driver about this event */
+-              ret = device->driver->pm->freeze(device);
+-      }
+-
+-      return ret;
+-}
+-
+-static int mali_os_thaw(struct device *device)
+-{
+-      int ret = 0;
+-
+-      MALI_DEBUG_PRINT(4, ("mali_os_thaw() called\n"));
+-
+-      if (NULL != device->driver &&
+-          NULL != device->driver->pm &&
+-          NULL != device->driver->pm->thaw)
+-      {
+-              /* Need to notify Mali driver about this event */
+-              ret = device->driver->pm->thaw(device);
+-      }
+-
+-      return ret;
+-}
+-
+-#ifdef CONFIG_PM_RUNTIME
+-static int mali_runtime_suspend(struct device *device)
+-{
+-      int ret = 0;
+-
+-      MALI_DEBUG_PRINT(4, ("mali_runtime_suspend() called\n"));
+-
+-      if (NULL != device->driver &&
+-          NULL != device->driver->pm &&
+-          NULL != device->driver->pm->runtime_suspend)
+-      {
+-              /* Need to notify Mali driver about this event */
+-              ret = device->driver->pm->runtime_suspend(device);
+-      }
+-
+-      mali_platform_power_mode_change(MALI_POWER_MODE_LIGHT_SLEEP);
+-
+-      return ret;
+-}
+-
+-static int mali_runtime_resume(struct device *device)
+-{
+-      int ret = 0;
+-
+-      MALI_DEBUG_PRINT(4, ("mali_runtime_resume() called\n"));
+-
+-      mali_platform_power_mode_change(MALI_POWER_MODE_ON);
+-
+-      if (NULL != device->driver &&
+-          NULL != device->driver->pm &&
+-          NULL != device->driver->pm->runtime_resume)
+-      {
+-              /* Need to notify Mali driver about this event */
+-              ret = device->driver->pm->runtime_resume(device);
+-      }
+-
+-      return ret;
+-}
+-
+-static int mali_runtime_idle(struct device *device)
+-{
+-      MALI_DEBUG_PRINT(4, ("mali_runtime_idle() called\n"));
+-
+-      if (NULL != device->driver &&
+-          NULL != device->driver->pm &&
+-          NULL != device->driver->pm->runtime_idle)
+-      {
+-              /* Need to notify Mali driver about this event */
+-              int ret = device->driver->pm->runtime_idle(device);
+-              if (0 != ret)
+-              {
+-                      return ret;
+-              }
+-      }
+-
+-      pm_runtime_suspend(device);
+-
+-      return 0;
+-}
+-#endif
+diff --git a/drivers/gpu/arm/mali400/mali/platform/pegasus-m400/exynos4_pmm.c b/drivers/gpu/arm/mali400/mali/platform/pegasus-m400/exynos4_pmm.c
+deleted file mode 100644
+index e8ab610..0000000
+--- a/drivers/gpu/arm/mali400/mali/platform/pegasus-m400/exynos4_pmm.c
++++ /dev/null
+@@ -1,842 +0,0 @@
+-/*
+- * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+- *
+- * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+- * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+- *
+- * A copy of the licence is included with the program, and can also be obtained from Free Software
+- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+- */
+-
+-/**
+- * @file mali_platform.c
+- * Platform specific Mali driver functions for a default platform
+- */
+-#include "mali_kernel_common.h"
+-#include "mali_osk.h"
+-#include "exynos4_pmm.h"
+-#include <linux/clk.h>
+-#include <linux/err.h>
+-#include <linux/module.h>
+-#include <linux/platform_device.h>
+-#include <linux/regulator/consumer.h>
+-
+-#if defined(CONFIG_MALI400_PROFILING)
+-#include "mali_osk_profiling.h"
+-#endif
+-
+-#if defined(CONFIG_PM_RUNTIME)
+-//#include <plat/pd.h>
+-#endif
+-
+-#include <asm/io.h>
+-#include <mach/regs-pmu.h>
+-
+-#include <linux/workqueue.h>
+-
+-#define MALI_DVFS_STEPS 5
+-#define MALI_DVFS_WATING 10 // msec
+-#define MALI_DVFS_DEFAULT_STEP 3
+-
+-#define MALI_DVFS_CLK_DEBUG 0
+-#define SEC_THRESHOLD 1
+-
+-#define CPUFREQ_LOCK_DURING_440 0
+-
+-static int bMaliDvfsRun = 0;
+-
+-typedef struct mali_dvfs_tableTag{
+-      unsigned int clock;
+-      unsigned int freq;
+-      unsigned int vol;
+-#if SEC_THRESHOLD
+-      unsigned int downthreshold;
+-    unsigned int upthreshold;
+-#endif
+-}mali_dvfs_table;
+-
+-typedef struct mali_dvfs_statusTag{
+-      unsigned int currentStep;
+-      mali_dvfs_table * pCurrentDvfs;
+-
+-} mali_dvfs_status_t;
+-
+-/*dvfs status*/
+-mali_dvfs_status_t maliDvfsStatus;
+-int mali_dvfs_control;
+-/*dvfs table*/
+-
+-mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={
+-#if 1//defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+-                      /*step 0*/{160  ,1000000    ,875000    , 0   , 70},
+-                      /*step 1*/{266  ,1000000    ,900000    ,62   , 90},
+-                      /*step 2*/{350  ,1000000    ,950000    ,85   , 90},
+-                      /*step 3*/{440  ,1000000    ,1025000   ,85   , 90},
+-                      /*step 4*/{533  ,1000000    ,1075000   ,85   ,100} };
+-#else
+-                      /*step 0*/{134  ,1000000    , 950000   ,85   , 90},
+-                      /*step 1*/{267  ,1000000    ,1050000   ,85   ,100} };
+-#endif
+-
+-
+-#define EXTXTALCLK_NAME  "ext_xtal"
+-#define VPLLSRCCLK_NAME  "vpll_src"
+-#define FOUTVPLLCLK_NAME "fout_vpll"
+-#define SCLVPLLCLK_NAME  "sclk_vpll"
+-#define GPUMOUT1CLK_NAME "mout_g3d1"
+-
+-#define MPLLCLK_NAME     "mout_mpll"
+-#define GPUMOUT0CLK_NAME "mout_g3d0"
+-#define GPUCLK_NAME      "sclk_g3d"
+-#define CLK_DIV_STAT_G3D 0x1003C62C
+-#define CLK_DESC         "clk-divider-status"
+-
+-static struct clk *ext_xtal_clock = NULL;
+-static struct clk *vpll_src_clock = NULL;
+-static struct clk *fout_vpll_clock = NULL;
+-static struct clk *sclk_vpll_clock = NULL;
+-
+-static struct clk *mpll_clock = NULL;
+-static struct clk *mali_parent_clock = NULL;
+-static struct clk *mali_clock = NULL;
+-
+-#if defined(CONFIG_CPU_EXYNOS4412) || defined(CONFIG_CPU_EXYNOS4212)
+-/* Pegasus */
+-static const mali_bool bis_vpll  = MALI_TRUE;
+-int mali_gpu_clk                 = 440;
+-static unsigned int mali_gpu_vol = 1025000;
+-#else
+-/* Orion */
+-static const mali_bool bis_vpll  = MALI_FALSE;
+-int mali_gpu_clk                 = 267;
+-static unsigned int mali_gpu_vol = 1050000; /* 1.05V */
+-#endif
+-
+-static unsigned int GPU_MHZ   =               1000000;
+-
+-int  gpu_power_state;
+-static int bPoweroff;
+-
+-#ifdef CONFIG_REGULATOR
+-struct regulator *g3d_regulator = NULL;
+-#endif
+-
+-mali_io_address clk_register_map = 0;
+-
+-/* DVFS */
+-static unsigned int mali_dvfs_utilization = 255;
+-
+-static void mali_dvfs_work_handler(struct work_struct *w);
+-
+-static struct workqueue_struct *mali_dvfs_wq = 0;
+-
+-extern mali_io_address clk_register_map;
+-
+-_mali_osk_lock_t *mali_dvfs_lock = 0;
+-
+-static DECLARE_WORK(mali_dvfs_work, mali_dvfs_work_handler);
+-
+-
+-/* export GPU frequency as a read-only parameter so that it can be read in /sys */
+-module_param(mali_gpu_clk, int, S_IRUSR | S_IRGRP | S_IROTH);
+-MODULE_PARM_DESC(mali_gpu_clk, "GPU frequency in MHz");
+-
+-#ifdef CONFIG_REGULATOR
+-void mali_regulator_disable(void)
+-{
+-      if(IS_ERR_OR_NULL(g3d_regulator))
+-      {
+-              MALI_DEBUG_PRINT(1, ("error on mali_regulator_disable : g3d_regulator is null\n"));
+-              return;
+-      }
+-      regulator_disable(g3d_regulator);
+-}
+-
+-void mali_regulator_enable(void)
+-{
+-      if(IS_ERR_OR_NULL(g3d_regulator))
+-      {
+-              MALI_DEBUG_PRINT(1, ("error on mali_regulator_enable : g3d_regulator is null\n"));
+-              return;
+-      }
+-      regulator_enable(g3d_regulator);
+-}
+-
+-void mali_regulator_set_voltage(int min_uV, int max_uV)
+-{
+-      _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+-      if(IS_ERR_OR_NULL(g3d_regulator))
+-      {
+-              MALI_DEBUG_PRINT(1, ("error on mali_regulator_set_voltage : g3d_regulator is null\n"));
+-              return;
+-      }
+-      MALI_PRINT(("= regulator_set_voltage: %d, %d \n",min_uV, max_uV));
+-      regulator_set_voltage(g3d_regulator, min_uV, max_uV);
+-      mali_gpu_vol = regulator_get_voltage(g3d_regulator);
+-      MALI_DEBUG_PRINT(1, ("Mali voltage: %d\n", mali_gpu_vol));
+-      _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+-}
+-#endif
+-
+-unsigned long mali_clk_get_rate(void)
+-{
+-      return clk_get_rate(mali_clock);
+-}
+-
+-
+-static unsigned int get_mali_dvfs_status(void)
+-{
+-      return maliDvfsStatus.currentStep;
+-}
+-
+-mali_bool mali_clk_get(void)
+-{
+-      if (bis_vpll)
+-      {
+-              if (ext_xtal_clock == NULL)
+-              {
+-                      ext_xtal_clock = clk_get(NULL,EXTXTALCLK_NAME);
+-                      if (IS_ERR(ext_xtal_clock)) {
+-                              MALI_PRINT( ("MALI Error : failed to get source ext_xtal_clock\n"));
+-                              return MALI_FALSE;
+-                      }
+-              }
+-
+-              if (vpll_src_clock == NULL)
+-              {
+-                      vpll_src_clock = clk_get(NULL,VPLLSRCCLK_NAME);
+-                      if (IS_ERR(vpll_src_clock)) {
+-                              MALI_PRINT( ("MALI Error : failed to get source vpll_src_clock\n"));
+-                              return MALI_FALSE;
+-                      }
+-              }
+-
+-              if (fout_vpll_clock == NULL)
+-              {
+-                      fout_vpll_clock = clk_get(NULL,FOUTVPLLCLK_NAME);
+-                      if (IS_ERR(fout_vpll_clock)) {
+-                              MALI_PRINT( ("MALI Error : failed to get source fout_vpll_clock\n"));
+-                              return MALI_FALSE;
+-                      }
+-              }
+-
+-              if (sclk_vpll_clock == NULL)
+-              {
+-                      sclk_vpll_clock = clk_get(NULL,SCLVPLLCLK_NAME);
+-                      if (IS_ERR(sclk_vpll_clock)) {
+-                              MALI_PRINT( ("MALI Error : failed to get source sclk_vpll_clock\n"));
+-                              return MALI_FALSE;
+-                      }
+-              }
+-
+-              if (mali_parent_clock == NULL)
+-              {
+-                      mali_parent_clock = clk_get(NULL, GPUMOUT1CLK_NAME);
+-
+-                      if (IS_ERR(mali_parent_clock)) {
+-                              MALI_PRINT( ( "MALI Error : failed to get source mali parent clock\n"));
+-                              return MALI_FALSE;
+-                      }
+-              }
+-      }
+-      else // mpll
+-      {
+-              if (mpll_clock == NULL)
+-              {
+-                      mpll_clock = clk_get(NULL,MPLLCLK_NAME);
+-
+-                      if (IS_ERR(mpll_clock)) {
+-                              MALI_PRINT( ("MALI Error : failed to get source mpll clock\n"));
+-                              return MALI_FALSE;
+-                      }
+-              }
+-
+-              if (mali_parent_clock == NULL)
+-              {
+-                      mali_parent_clock = clk_get(NULL, GPUMOUT0CLK_NAME);
+-
+-                      if (IS_ERR(mali_parent_clock)) {
+-                              MALI_PRINT( ( "MALI Error : failed to get source mali parent clock\n"));
+-                              return MALI_FALSE;
+-                      }
+-              }
+-      }
+-
+-      // mali clock get always.
+-      if (mali_clock == NULL)
+-      {
+-              mali_clock = clk_get(NULL, GPUCLK_NAME);
+-
+-              if (IS_ERR(mali_clock)) {
+-                      MALI_PRINT( ("MALI Error : failed to get source mali clock\n"));
+-                      return MALI_FALSE;
+-              }
+-      }
+-
+-      return MALI_TRUE;
+-}
+-
+-void mali_clk_put(mali_bool binc_mali_clock)
+-{
+-      if (mali_parent_clock)
+-      {
+-              clk_put(mali_parent_clock);
+-              mali_parent_clock = NULL;
+-      }
+-
+-      if (mpll_clock)
+-      {
+-              clk_put(mpll_clock);
+-              mpll_clock = NULL;
+-      }
+-
+-      if (sclk_vpll_clock)
+-      {
+-              clk_put(sclk_vpll_clock);
+-              sclk_vpll_clock = NULL;
+-      }
+-
+-      if (binc_mali_clock && fout_vpll_clock)
+-      {
+-              clk_put(fout_vpll_clock);
+-              fout_vpll_clock = NULL;
+-      }
+-
+-      if (vpll_src_clock)
+-      {
+-              clk_put(vpll_src_clock);
+-              vpll_src_clock = NULL;
+-      }
+-
+-      if (ext_xtal_clock)
+-      {
+-              clk_put(ext_xtal_clock);
+-              ext_xtal_clock = NULL;
+-      }
+-
+-      if (binc_mali_clock && mali_clock)
+-      {
+-              clk_put(mali_clock);
+-              mali_clock = NULL;
+-      }
+-}
+-
+-void mali_clk_set_rate(unsigned int clk, unsigned int mhz)
+-{
+-      int err;
+-      unsigned long rate = (unsigned long)clk * (unsigned long)mhz;
+-
+-      _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+-      MALI_DEBUG_PRINT(3, ("Mali platform: Setting frequency to %d mhz\n", clk));
+-      if (bis_vpll && fout_vpll_clock)
+-      {
+-              err = clk_set_rate(fout_vpll_clock, (unsigned int)mali_gpu_clk * GPU_MHZ);
+-              if (err) MALI_PRINT_ERROR(("Failed to set vpll: %d\n", err));
+-      }
+-      err = clk_set_rate(mali_clock, rate);
+-      if (err) MALI_PRINT_ERROR(("Failed to set Mali clock: %d\n", err));
+-
+-      rate = mali_clk_get_rate();
+-
+-      MALI_PRINT(("Mali frequency %d\n", rate / mhz));
+-      GPU_MHZ = mhz;
+-      mali_gpu_clk = (int)(rate / mhz);
+-      _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+-}
+-
+-int get_mali_dvfs_control_status(void)
+-{
+-      return mali_dvfs_control;
+-}
+-
+-mali_bool set_mali_dvfs_current_step(unsigned int step)
+-{
+-      _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+-      maliDvfsStatus.currentStep = step % MALI_DVFS_STEPS;
+-      _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+-      return MALI_TRUE;
+-}
+-
+-
+-static mali_bool set_mali_dvfs_status(u32 step,mali_bool boostup)
+-{
+-      u32 validatedStep=step;
+-#if MALI_DVFS_CLK_DEBUG
+-      unsigned int *pRegMaliClkDiv;
+-      unsigned int *pRegMaliMpll;
+-#endif
+-
+-      if(boostup)     {
+-#ifdef CONFIG_REGULATOR
+-              /*change the voltage*/
+-              mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol);
+-#endif
+-              /*change the clock*/
+-              mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq);
+-      } else {
+-              /*change the clock*/
+-              mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq);
+-#ifdef CONFIG_REGULATOR
+-              /*change the voltage*/
+-              mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol);
+-#endif
+-      }
+-
+-#if defined(CONFIG_MALI400_PROFILING)
+-      _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE| MALI_PROFILING_EVENT_CHANNEL_GPU|MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0);
+-#endif
+-      mali_clk_put(MALI_FALSE);
+-
+-#if MALI_DVFS_CLK_DEBUG
+-      pRegMaliClkDiv = ioremap(0x1003c52c,32);
+-      pRegMaliMpll = ioremap(0x1003c22c,32);
+-      MALI_PRINT( ("Mali MPLL reg:%d, CLK DIV: %d \n",*pRegMaliMpll, *pRegMaliClkDiv));
+-#endif
+-
+-#ifdef EXYNOS4_ASV_ENABLED
+-      if (samsung_rev() < EXYNOS4412_REV_2_0) {
+-              if (mali_dvfs[step].clock == 160)
+-                      exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_100V);
+-              else
+-                      exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_130V);
+-      }
+-#endif
+-
+-
+-//    maliDvfsStatus.currentStep = validatedStep;
+-      set_mali_dvfs_current_step(validatedStep);
+-      /*for future use*/
+-      maliDvfsStatus.pCurrentDvfs = &mali_dvfs[validatedStep];
+-
+-#if CPUFREQ_LOCK_DURING_440
+-      /* lock/unlock CPU freq by Mali */
+-      if (mali_dvfs[step].clock == 440)
+-              err = cpufreq_lock_by_mali(1200);
+-      else
+-              cpufreq_unlock_by_mali();
+-#endif
+-
+-
+-      return MALI_TRUE;
+-}
+-
+-static void mali_platform_wating(u32 msec)
+-{
+-      /*sample wating
+-      change this in the future with proper check routine.
+-      */
+-      unsigned int read_val;
+-      while(1)
+-      {
+-              read_val = _mali_osk_mem_ioread32(clk_register_map, 0x00);
+-              if ((read_val & 0x8000)==0x0000) break;
+-
+-              _mali_osk_time_ubusydelay(100); /* 1000 -> 100 : 20101218 */
+-      }
+-      /* _mali_osk_time_ubusydelay(msec*1000);*/
+-}
+-
+-static mali_bool change_mali_dvfs_status(u32 step, mali_bool boostup )
+-{
+-      MALI_DEBUG_PRINT(4, ("> change_mali_dvfs_status: %d, %d \n",step, boostup));
+-
+-      if(!set_mali_dvfs_status(step, boostup))
+-      {
+-              MALI_DEBUG_PRINT(1, ("error on set_mali_dvfs_status: %d, %d \n",step, boostup));
+-              return MALI_FALSE;
+-      }
+-
+-      /*wait until clock and voltage is stablized*/
+-      mali_platform_wating(MALI_DVFS_WATING); /*msec*/
+-
+-      return MALI_TRUE;
+-}
+-
+-static unsigned int decideNextStatus(unsigned int utilization)
+-{
+-      unsigned int level= maliDvfsStatus.currentStep;
+-      unsigned int uiStepCount = 0;
+-
+-      if (mali_dvfs_control == 0) {
+-              // && maliDvfsStatus.currentStep) {
+-              if (utilization > (int)(255 * mali_dvfs[maliDvfsStatus.currentStep].upthreshold / 100) &&
+-                              level < MALI_DVFS_STEPS - 1) {
+-                      level++;
+-//                    if ((samsung_rev() < EXYNOS4412_REV_2_0) && (maliDvfsStatus.currentStep == 3)) {
+-//                            level=get_mali_dvfs_status();
+-//                    }
+-              }
+-              if (utilization < (int)(255 * mali_dvfs[maliDvfsStatus.currentStep].downthreshold / 100) &&
+-                              level > 0) {
+-                      level--;
+-              }
+-      } else {
+-              for(uiStepCount = MALI_DVFS_STEPS-1; uiStepCount >= 0; uiStepCount--) {
+-                      if ( mali_dvfs_control >= mali_dvfs[uiStepCount].clock ) {
+-                              maliDvfsStatus.currentStep = uiStepCount;
+-                              level = maliDvfsStatus.currentStep;
+-                              break;
+-                      }
+-              }
+-      }
+-
+-      return level;
+-}
+-
+-static mali_bool mali_dvfs_status(unsigned int utilization)
+-{
+-      unsigned int nextStatus=0;
+-      unsigned int curStatus=0;
+-      mali_bool boostup=0;
+-
+-      MALI_DEBUG_PRINT(4, ("> mali_dvfs_status: %d \n",utilization));
+-
+-      /*decide next step*/
+-      curStatus = get_mali_dvfs_status();
+-      nextStatus = decideNextStatus(utilization);
+-
+-      MALI_DEBUG_PRINT(4, ("= curStatus %d, nextStatus %d, maliDvfsStatus.currentStep %d \n", curStatus, nextStatus, maliDvfsStatus.currentStep));
+-      /*if next status is same with current status, don't change anything*/
+-      if(curStatus!=nextStatus)
+-      {
+-              /*check if boost up or not*/
+-              if(nextStatus > maliDvfsStatus.currentStep) boostup = 1;
+-
+-              /*change mali dvfs status*/
+-              if(!change_mali_dvfs_status(nextStatus,boostup))
+-              {
+-                      MALI_DEBUG_PRINT(1, ("error on change_mali_dvfs_status \n"));
+-                      return MALI_FALSE;
+-              }
+-      }
+-      return MALI_TRUE;
+-}
+-
+-
+-int mali_dvfs_is_running(void)
+-{
+-      return bMaliDvfsRun;
+-}
+-
+-
+-static void mali_dvfs_work_handler(struct work_struct *w)
+-{
+-      bMaliDvfsRun=1;
+-
+-      MALI_DEBUG_PRINT(3, ("=== mali_dvfs_work_handler\n"));
+-
+-      if(!mali_dvfs_status(mali_dvfs_utilization))
+-      MALI_DEBUG_PRINT(1,( "error on mali dvfs status in mali_dvfs_work_handler"));
+-
+-      bMaliDvfsRun=0;
+-}
+-
+-
+-mali_bool init_mali_dvfs_status(void)
+-{
+-      /*default status
+-      add here with the right function to get initilization value.
+-      */
+-
+-      if (!mali_dvfs_wq)
+-      {
+-              mali_dvfs_wq = create_singlethread_workqueue("mali_dvfs");
+-      }
+-
+-      /*add a error handling here*/
+-      maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP;
+-
+-      return MALI_TRUE;
+-}
+-
+-void deinit_mali_dvfs_status(void)
+-{
+-      if (mali_dvfs_wq)
+-      {
+-              destroy_workqueue(mali_dvfs_wq);
+-              mali_dvfs_wq = NULL;
+-      }
+-}
+-
+-mali_bool mali_dvfs_handler(unsigned int utilization)
+-{
+-      mali_dvfs_utilization = utilization;
+-      queue_work_on(0, mali_dvfs_wq, &mali_dvfs_work);
+-
+-      return MALI_TRUE;
+-}
+-
+-static mali_bool init_mali_clock(void)
+-{
+-      mali_bool ret = MALI_TRUE;
+-      gpu_power_state = 0;
+-      bPoweroff = 1;
+-
+-      if (mali_clock != 0)
+-              return ret; /* already initialized */
+-
+-      mali_dvfs_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE
+-                      | _MALI_OSK_LOCKFLAG_ONELOCK, 0, 0);
+-      if (mali_dvfs_lock == NULL)
+-              return _MALI_OSK_ERR_FAULT;
+-
+-
+-
+-      if (!mali_clk_get())
+-      {
+-              MALI_PRINT(("Error: Failed to get Mali clock\n"));
+-              goto err_clk;
+-      }
+-
+-      if (bis_vpll)
+-      {
+-              clk_set_parent(vpll_src_clock, ext_xtal_clock);
+-              clk_set_parent(sclk_vpll_clock, fout_vpll_clock);
+-
+-              clk_set_parent(mali_parent_clock, sclk_vpll_clock);
+-              clk_set_parent(mali_clock, mali_parent_clock);
+-      }
+-      else
+-      {
+-              clk_set_parent(mali_parent_clock, mpll_clock);
+-              clk_set_parent(mali_clock, mali_parent_clock);
+-      }
+-
+-      if (clk_enable(mali_clock) < 0)
+-      {
+-              MALI_PRINT(("Error: Failed to enable clock\n"));
+-              goto err_clk;
+-      }
+-
+-      mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ);
+-
+-      MALI_PRINT(("init_mali_clock mali_clock %x\n", mali_clock));
+-
+-#ifdef CONFIG_REGULATOR
+-      g3d_regulator = regulator_get(NULL, "vdd_g3d");
+-
+-      if (IS_ERR(g3d_regulator))
+-      {
+-              MALI_PRINT( ("MALI Error : failed to get vdd_g3d\n"));
+-              ret = MALI_FALSE;
+-              goto err_regulator;
+-      }
+-
+-      regulator_enable(g3d_regulator);
+-      mali_regulator_set_voltage(mali_gpu_vol, mali_gpu_vol);
+-#endif
+-
+-#if defined(CONFIG_MALI400_PROFILING)
+-      _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|
+-                      MALI_PROFILING_EVENT_CHANNEL_GPU|MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
+-                      mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0);
+-#endif
+-
+-      mali_clk_put(MALI_FALSE);
+-
+-      return MALI_TRUE;
+-
+-#ifdef CONFIG_REGULATOR
+-err_regulator:
+-      regulator_put(g3d_regulator);
+-#endif
+-err_clk:
+-      mali_clk_put(MALI_TRUE);
+-
+-      return ret;
+-}
+-
+-static mali_bool deinit_mali_clock(void)
+-{
+-      if (mali_clock == 0)
+-              return MALI_TRUE;
+-
+-#ifdef CONFIG_REGULATOR
+-      if (g3d_regulator)
+-      {
+-              regulator_put(g3d_regulator);
+-              g3d_regulator = NULL;
+-      }
+-#endif
+-
+-      mali_clk_put(MALI_TRUE);
+-
+-      return MALI_TRUE;
+-}
+-
+-
+-static _mali_osk_errcode_t enable_mali_clocks(void)
+-{
+-      int err;
+-      err = clk_enable(mali_clock);
+-      MALI_DEBUG_PRINT(3,("enable_mali_clocks mali_clock %p error %d \n", mali_clock, err));
+-
+-      /* set clock rate */
+-      mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ);
+-
+-      maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP;
+-
+-      MALI_SUCCESS;
+-}
+-
+-static _mali_osk_errcode_t disable_mali_clocks(void)
+-{
+-      clk_disable(mali_clock);
+-      MALI_DEBUG_PRINT(3,("disable_mali_clocks mali_clock %p \n", mali_clock));
+-
+-      MALI_SUCCESS;
+-}
+-
+-/* Some defines changed names in later Odroid-A kernels. Make sure it works for both. */
+-#ifndef S5P_G3D_CONFIGURATION
+-#define S5P_G3D_CONFIGURATION EXYNOS4_G3D_CONFIGURATION
+-#endif
+-#ifndef S5P_G3D_STATUS
+-#define S5P_G3D_STATUS EXYNOS4_G3D_CONFIGURATION + 0x4
+-#endif
+-
+-_mali_osk_errcode_t g3d_power_domain_control(int bpower_on)
+-{
+-      if (bpower_on)
+-      {
+-              void __iomem *status;
+-              u32 timeout;
+-              __raw_writel(EXYNOS_INT_LOCAL_PWR_EN, S5P_G3D_CONFIGURATION);
+-              status = S5P_G3D_STATUS;
+-
+-              timeout = 10;
+-              while ((__raw_readl(status) & EXYNOS_INT_LOCAL_PWR_EN)
+-                      != EXYNOS_INT_LOCAL_PWR_EN) {
+-                      if (timeout == 0) {
+-                              MALI_PRINTF(("Power domain  enable failed.\n"));
+-                              return -ETIMEDOUT;
+-                      }
+-                      timeout--;
+-                      _mali_osk_time_ubusydelay(100);
+-              }
+-      }
+-      else
+-      {
+-              void __iomem *status;
+-              u32 timeout;
+-              __raw_writel(0, S5P_G3D_CONFIGURATION);
+-
+-              status = S5P_G3D_STATUS;
+-              /* Wait max 1ms */
+-              timeout = 10;
+-              while (__raw_readl(status) & EXYNOS_INT_LOCAL_PWR_EN)
+-              {
+-                      if (timeout == 0) {
+-                              MALI_PRINTF(("Power domain  disable failed.\n" ));
+-                              return -ETIMEDOUT;
+-                      }
+-                      timeout--;
+-                      _mali_osk_time_ubusydelay( 100);
+-              }
+-      }
+-
+-      MALI_SUCCESS;
+-}
+-
+-_mali_osk_errcode_t mali_platform_init(void)
+-{
+-      MALI_CHECK(init_mali_clock(), _MALI_OSK_ERR_FAULT);
+-#ifdef CONFIG_MALI_DVFS
+-      if (!clk_register_map) clk_register_map = _mali_osk_mem_mapioregion( CLK_DIV_STAT_G3D, 0x20, CLK_DESC );
+-      if(!init_mali_dvfs_status())
+-              MALI_DEBUG_PRINT(1, ("mali_platform_init failed\n"));
+-#endif
+-      mali_platform_power_mode_change(MALI_POWER_MODE_ON);
+-
+-      MALI_SUCCESS;
+-}
+-
+-_mali_osk_errcode_t mali_platform_deinit(void)
+-{
+-
+-      mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP);
+-      deinit_mali_clock();
+-
+-#ifdef CONFIG_MALI_DVFS
+-      deinit_mali_dvfs_status();
+-      if (clk_register_map )
+-      {
+-              _mali_osk_mem_unmapioregion(CLK_DIV_STAT_G3D, 0x20, clk_register_map);
+-              clk_register_map = NULL;
+-      }
+-#endif
+-
+-      MALI_SUCCESS;
+-}
+-
+-_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode)
+-{
+-      switch (power_mode)
+-      {
+-              case MALI_POWER_MODE_ON:
+-                      MALI_DEBUG_PRINT(3, ("Mali platform: Got MALI_POWER_MODE_ON event, %s\n",
+-                                           bPoweroff ? "powering on" : "already on"));
+-                      if (bPoweroff == 1)
+-                      {
+-#if !defined(CONFIG_PM_RUNTIME)
+-                              g3d_power_domain_control(1);
+-#endif
+-                              MALI_DEBUG_PRINT(4,("enable clock \n"));
+-                              enable_mali_clocks();
+-#if defined(CONFIG_MALI400_PROFILING)
+-                              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
+-                                              MALI_PROFILING_EVENT_CHANNEL_GPU |
+-                                              MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, mali_gpu_clk,
+-                                              mali_gpu_vol/1000, 0, 0, 0);
+-
+-#endif
+-                              bPoweroff=0;
+-                      }
+-                      break;
+-              case MALI_POWER_MODE_LIGHT_SLEEP:
+-              case MALI_POWER_MODE_DEEP_SLEEP:
+-                      MALI_DEBUG_PRINT(3, ("Mali platform: Got %s event, %s\n", power_mode ==
+-                                              MALI_POWER_MODE_LIGHT_SLEEP ?  "MALI_POWER_MODE_LIGHT_SLEEP" :
+-                                              "MALI_POWER_MODE_DEEP_SLEEP", bPoweroff ? "already off" : "powering off"));
+-                      if (bPoweroff == 0)
+-                      {
+-                              disable_mali_clocks();
+-#if defined(CONFIG_MALI400_PROFILING)
+-                              _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
+-                                              MALI_PROFILING_EVENT_CHANNEL_GPU |
+-                                              MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, 0, 0, 0, 0, 0);
+-#endif
+-
+-#if !defined(CONFIG_PM_RUNTIME)
+-                              g3d_power_domain_control(0);
+-#endif
+-                              bPoweroff=1;
+-                      }
+-
+-                      break;
+-      }
+-      MALI_SUCCESS;
+-}
+-
+-void mali_gpu_utilization_handler(unsigned int utilization)
+-{
+-      if (bPoweroff==0)
+-      {
+-#ifdef CONFIG_MALI_DVFS
+-              if(!mali_dvfs_handler(utilization))
+-                      MALI_DEBUG_PRINT(1,( "error on mali dvfs status in utilization\n"));
+-#endif
+-      }
+-}
+-
+-
+-/*REGISTER
+- Enable Power
+- pPowerPTR = ioremap(0x10023C60,32);
+- *pPowerPTR |= 0x7;
+-
+- Enable Clock
+- pPTR = ioremap(0x1003C92C,32);
+- *pPTR |= 0x1;
+-*/
+-
+diff --git a/drivers/gpu/arm/mali400/mali/platform/pegasus-m400/exynos4_pmm.h b/drivers/gpu/arm/mali400/mali/platform/pegasus-m400/exynos4_pmm.h
+deleted file mode 100644
+index 1b69b16..0000000
+--- a/drivers/gpu/arm/mali400/mali/platform/pegasus-m400/exynos4_pmm.h
++++ /dev/null
+@@ -1,86 +0,0 @@
+-/*
+- * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+- *
+- * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+- * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+- *
+- * A copy of the licence is included with the program, and can also be obtained from Free Software
+- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+- */
+-
+-/**
+- * @file mali_platform.h
+- * Platform specific Mali driver functions
+- */
+-
+-#ifndef __EXYNOS4_PMM_H__
+-#define __EXYNOS4_PMM_H__
+-
+-#include "mali_osk.h"
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-/** @brief description of power change reasons
+- */
+-typedef enum mali_power_mode_tag
+-{
+-      MALI_POWER_MODE_ON,
+-      MALI_POWER_MODE_LIGHT_SLEEP,
+-      MALI_POWER_MODE_DEEP_SLEEP,
+-} mali_power_mode;
+-
+-/** @brief Platform specific setup and initialisation of MALI
+- *
+- * This is called from the entrypoint of the driver to initialize the platform
+- *
+- * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
+- */
+-_mali_osk_errcode_t mali_platform_init(void);
+-
+-/** @brief Platform specific deinitialisation of MALI
+- *
+- * This is called on the exit of the driver to terminate the platform
+- *
+- * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
+- */
+-_mali_osk_errcode_t mali_platform_deinit(void);
+-
+-/** @brief Platform specific powerdown sequence of MALI
+- *
+- * Call as part of platform init if there is no PMM support, else the
+- * PMM will call it.
+- * There are three power modes defined:
+- *  1) MALI_POWER_MODE_ON
+- *  2) MALI_POWER_MODE_LIGHT_SLEEP
+- *  3) MALI_POWER_MODE_DEEP_SLEEP
+- * MALI power management module transitions to MALI_POWER_MODE_LIGHT_SLEEP mode when MALI is idle
+- * for idle timer (software timer defined in mali_pmm_policy_jobcontrol.h) duration, MALI transitions
+- * to MALI_POWER_MODE_LIGHT_SLEEP mode during timeout if there are no more jobs queued.
+- * MALI power management module transitions to MALI_POWER_MODE_DEEP_SLEEP mode when OS does system power
+- * off.
+- * Customer has to add power down code when MALI transitions to MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP
+- * mode.
+- * MALI_POWER_MODE_ON mode is entered when the MALI is to powered up. Some customers want to control voltage regulators during
+- * the whole system powers on/off. Customer can track in this function whether the MALI is powered up from
+- * MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP mode and manage the voltage regulators as well.
+- * @param power_mode defines the power modes
+- * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
+- */
+-_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode);
+-
+-
+-/** @brief Platform specific handling of GPU utilization data
+- *
+- * When GPU utilization data is enabled, this function will be
+- * periodically called.
+- *
+- * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization.
+- */
+-void mali_gpu_utilization_handler(unsigned int utilization);
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-#endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0119-gpu-arm-mali400-ump-Remove-call-to-flush_all_cpu_cac.patch b/patches.tizen/0119-gpu-arm-mali400-ump-Remove-call-to-flush_all_cpu_cac.patch
new file mode 100644 (file)
index 0000000..ee8ba77
--- /dev/null
@@ -0,0 +1,33 @@
+From 635d09bc272f044badeb14c0edcf29f9472c3590 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 10 May 2013 19:06:39 +0200
+Subject: [PATCH 0119/1302] gpu: arm: mali400: ump: Remove call to
+ flush_all_cpu_caches()
+
+This function is not available anymore in Linux 3.8.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/arm/mali400/ump/linux/ump_osk_low_level_mem.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/arm/mali400/ump/linux/ump_osk_low_level_mem.c b/drivers/gpu/arm/mali400/ump/linux/ump_osk_low_level_mem.c
+index c47be67..3a01220 100644
+--- a/drivers/gpu/arm/mali400/ump/linux/ump_osk_low_level_mem.c
++++ b/drivers/gpu/arm/mali400/ump/linux/ump_osk_low_level_mem.c
+@@ -231,10 +231,7 @@ void _ump_osk_msync( ump_dd_mem * mem, void * virt, u32 offset, u32 size, ump_uk
+               /*  There is no dmac_clean_range, so the L1 is always flushed,
+                *  also for UMP_MSYNC_CLEAN. */
+               /* MALI_SEC */
+-              if (size >= SZ_64K)
+-                      flush_all_cpu_caches();
+-              else
+-                      dmac_flush_range(start_v, end_v);
++              dmac_flush_range(start_v, end_v);
+               DBG_MSG(3, ("UMP[%02u] Flushing CPU L1 Cache. Cpu address: %x-%x\n", mem->secure_id, start_v,end_v));
+       }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0120-gpu-arm-mali400-Add-support-for-Device-Tree.patch b/patches.tizen/0120-gpu-arm-mali400-Add-support-for-Device-Tree.patch
new file mode 100644 (file)
index 0000000..b7939dd
--- /dev/null
@@ -0,0 +1,94 @@
+From 0df75c6aa113af5ccef7f0fd2d6e9074739da3ab Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 10 May 2013 19:10:17 +0200
+Subject: [PATCH 0120/1302] gpu: arm: mali400: Add support for Device Tree
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/arm/mali400/mali/Kbuild                    |  1 -
+ drivers/gpu/arm/mali400/mali/Makefile                  |  1 -
+ drivers/gpu/arm/mali400/mali/linux/mali_kernel_linux.c | 15 ++++++++++-----
+ 3 files changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/arm/mali400/mali/Kbuild b/drivers/gpu/arm/mali400/mali/Kbuild
+index 8c6e1f0..b7ff03c 100644
+--- a/drivers/gpu/arm/mali400/mali/Kbuild
++++ b/drivers/gpu/arm/mali400/mali/Kbuild
+@@ -25,7 +25,6 @@ MALI_UPPER_HALF_SCHEDULING ?= 1
+ TARGET_PLATFORM=redwood
+ include $(src)/MALI_CONFIGURATION
+ MALI_PLATFORM = $(MALI_PLATFORM-$(TARGET_PLATFORM))
+-EXTRA_DEFINES += -DMALI_FAKE_PLATFORM_DEVICE=1
+ MALI_PLATFORM_FILES = $(subst $(src)/,,$(wildcard $(src)/platform/$(MALI_PLATFORM)/*.c))
+ # For customer releases the Linux Device Drivers will be provided as ARM proprietary and GPL releases:
+diff --git a/drivers/gpu/arm/mali400/mali/Makefile b/drivers/gpu/arm/mali400/mali/Makefile
+index 9cdfd44..0a47c9f 100644
+--- a/drivers/gpu/arm/mali400/mali/Makefile
++++ b/drivers/gpu/arm/mali400/mali/Makefile
+@@ -93,7 +93,6 @@ endif
+ export CONFIG_MALI400=m
+ ifneq ($(MALI_PLATFORM),)
+-export EXTRA_DEFINES += -DMALI_FAKE_PLATFORM_DEVICE=1
+ export MALI_PLATFORM_FILES = $(wildcard platform/$(MALI_PLATFORM)/*.c)
+ endif
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_kernel_linux.c b/drivers/gpu/arm/mali400/mali/linux/mali_kernel_linux.c
+index adaaf9a..8bd4ca8 100644
+--- a/drivers/gpu/arm/mali400/mali/linux/mali_kernel_linux.c
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_kernel_linux.c
+@@ -17,6 +17,7 @@
+ #include <linux/cdev.h>     /* character device definitions */
+ #include <linux/mm.h>       /* memory manager definitions */
+ #include <linux/mali/mali_utgard_ioctl.h>
++#include <linux/of.h>
+ #include <linux/version.h>
+ #include <linux/device.h>
+ #include "mali_kernel_license.h"
+@@ -95,11 +96,6 @@ MODULE_PARM_DESC(mali_max_pp_cores_group_2, "Limit the number of PP cores to use
+ EXPORT_SYMBOL(mali_set_user_setting);
+ EXPORT_SYMBOL(mali_get_user_setting);
+ #if CONFIG_MALI_DVFS
+-/* MALI_SEC */
+-extern int mali_dvfs_control;
+-module_param(mali_dvfs_control, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
+-MODULE_PARM_DESC(mali_dvfs_control, "Mali Current DVFS");
+-
+ #if 0
+ extern int mali_gpu_clk;
+ module_param(mali_gpu_clk, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */
+@@ -195,6 +191,7 @@ static struct platform_driver mali_platform_driver =
+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
+               .pm = &mali_dev_pm_ops,
+ #endif
++              .of_match_table = of_match_ptr(mali_of_matches),
+       },
+ };
+@@ -302,6 +299,13 @@ static int mali_probe(struct platform_device *pdev)
+       mali_platform_device = pdev;
++      if (mali_platform_init() != _MALI_OSK_ERR_OK)
++      {
++              /* Platform-specific initialization failed, return error */
++              MALI_PRINT_ERROR(("mali_probe(): mali_platform_init() failed."));
++              return -EFAULT;
++      }
++
+       if (_MALI_OSK_ERR_OK == _mali_osk_wq_init())
+       {
+               /* Initialize the Mali GPU HW specified by pdev */
+@@ -348,6 +352,7 @@ static int mali_remove(struct platform_device *pdev)
+       mali_miscdevice_unregister();
+       mali_terminate_subsystems();
+       _mali_osk_wq_term();
++      mali_platform_deinit();
+       mali_platform_device = NULL;
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0121-gpu-arm-mali400-mali-Add-exynos4-platform-code.patch b/patches.tizen/0121-gpu-arm-mali400-mali-Add-exynos4-platform-code.patch
new file mode 100644 (file)
index 0000000..2cfe9c3
--- /dev/null
@@ -0,0 +1,471 @@
+From cf2bacebc7e89ba4fc23d07e72f389e48a57283e Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 10 May 2013 19:11:22 +0200
+Subject: [PATCH 0121/1302] gpu: arm: mali400: mali: Add exynos4 platform code
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/arm/mali400/mali/Kbuild                |   2 +-
+ drivers/gpu/arm/mali400/mali/MALI_CONFIGURATION    |   1 +
+ .../gpu/arm/mali400/mali/linux/mali_kernel_linux.c |   2 +-
+ .../arm/mali400/mali/platform/exynos4/exynos4.c    | 316 +++++++++++++++++++++
+ .../arm/mali400/mali/platform/exynos4/exynos4.h    |  88 ++++++
+ 5 files changed, 407 insertions(+), 2 deletions(-)
+ create mode 100644 drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4.c
+ create mode 100644 drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4.h
+
+diff --git a/drivers/gpu/arm/mali400/mali/Kbuild b/drivers/gpu/arm/mali400/mali/Kbuild
+index b7ff03c..58c8d05 100644
+--- a/drivers/gpu/arm/mali400/mali/Kbuild
++++ b/drivers/gpu/arm/mali400/mali/Kbuild
+@@ -22,7 +22,7 @@ MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS ?= 0
+ MALI_UPPER_HALF_SCHEDULING ?= 1
+ # MALI_SEC 
+ # Include the mapping between TARGET_PLATFORM and KDIR + MALI_PLATFORM
+-TARGET_PLATFORM=redwood
++TARGET_PLATFORM=exynos4
+ include $(src)/MALI_CONFIGURATION
+ MALI_PLATFORM = $(MALI_PLATFORM-$(TARGET_PLATFORM))
+ MALI_PLATFORM_FILES = $(subst $(src)/,,$(wildcard $(src)/platform/$(MALI_PLATFORM)/*.c))
+diff --git a/drivers/gpu/arm/mali400/mali/MALI_CONFIGURATION b/drivers/gpu/arm/mali400/mali/MALI_CONFIGURATION
+index 9926768..b0c2ebd 100644
+--- a/drivers/gpu/arm/mali400/mali/MALI_CONFIGURATION
++++ b/drivers/gpu/arm/mali400/mali/MALI_CONFIGURATION
+@@ -22,3 +22,4 @@ MALI_PLATFORM-tcc8900=tcc8900
+ MALI_PLATFORM-pb11mp=arm
+ MALI_PLATFORM-vea9=arm
+ MALI_PLATFORM-snowball=ux500
++MALI_PLATFORM-exynos4=exynos4
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_kernel_linux.c b/drivers/gpu/arm/mali400/mali/linux/mali_kernel_linux.c
+index 8bd4ca8..b1f2862 100644
+--- a/drivers/gpu/arm/mali400/mali/linux/mali_kernel_linux.c
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_kernel_linux.c
+@@ -41,7 +41,7 @@
+ #include "mali_profiling_internal.h"
+ #endif
+ /* MALI_SEC */
+-#include "../platform/pegasus-m400/exynos4_pmm.h"
++#include "../platform/exynos4/exynos4.h"
+ /* Streamline support for the Mali driver */
+ #if defined(CONFIG_TRACEPOINTS) && defined(CONFIG_MALI400_PROFILING)
+diff --git a/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4.c b/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4.c
+new file mode 100644
+index 0000000..64fd5de
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4.c
+@@ -0,0 +1,316 @@
++/*
++ * Mali400 platform glue for Samsung Exynos 4 SoCs
++ *
++ * Copyright 2013 by Samsung Electronics Co., Ltd.
++ * Author: Tomasz Figa <t.figa@samsung.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/clk.h>
++#include <linux/of.h>
++#include <linux/mali/mali_utgard.h>
++#include <linux/platform_device.h>
++#include <linux/pm.h>
++#include <linux/pm_runtime.h>
++#include <linux/regulator/consumer.h>
++#include <linux/slab.h>
++#include <linux/workqueue.h>
++
++#include "mali_kernel_common.h"
++#include "mali_osk.h"
++
++#include "exynos4.h"
++
++struct mali_exynos_variant {
++      const struct mali_exynos_dvfs_step *steps;
++      unsigned int nr_steps;
++};
++
++struct mali_exynos_dvfs_step {
++      unsigned int rate;
++      unsigned int min_uv;
++      unsigned int max_uv;
++      unsigned int downthreshold;
++      unsigned int upthreshold;
++};
++
++struct mali_exynos_drvdata {
++      struct device *dev;
++
++      const struct mali_exynos_dvfs_step *steps;
++      unsigned int nr_steps;
++
++      struct clk *sclk_vpll;
++      struct clk *mout_g3d1;
++      struct clk *mout_g3d;
++      struct clk *sclk_g3d;
++
++      struct regulator *vdd_g3d;
++
++      mali_power_mode power_mode;
++      unsigned int dvfs_step;
++      unsigned int load;
++
++      struct workqueue_struct *dvfs_workqueue;
++      struct work_struct dvfs_work;
++};
++
++extern struct platform_device *mali_platform_device;
++
++static struct mali_exynos_drvdata *mali;
++
++/*
++ * DVFS tables
++ */
++
++#define MALI_DVFS_STEP(freq, min_uv, max_uv, down, up) \
++      {freq * 1000000, min_uv, max_uv, (255 * down) / 100, (255 * up) / 100}
++
++static const struct mali_exynos_dvfs_step mali_exynos_dvfs_step_4210[] = {
++      MALI_DVFS_STEP(160,  950000,  975000,  0,  85),
++      MALI_DVFS_STEP(266, 1000000, 1025000, 75, 100),
++};
++
++static const struct mali_exynos_dvfs_step mali_exynos_dvfs_step_4x12[] = {
++      MALI_DVFS_STEP(160,  875000,  900000,  0,  70),
++      MALI_DVFS_STEP(266,  900000,  925000, 62,  90),
++      MALI_DVFS_STEP(350,  950000,  975000, 85,  90),
++      MALI_DVFS_STEP(440, 1025000, 1050000, 85, 100),
++};
++
++static const struct mali_exynos_dvfs_step mali_exynos_dvfs_step_4x12_prime[] = {
++      MALI_DVFS_STEP(160,  875000,  900000,  0,  70),
++      MALI_DVFS_STEP(266,  900000,  925000, 62,  90),
++      MALI_DVFS_STEP(350,  950000,  975000, 85,  90),
++      MALI_DVFS_STEP(440, 1025000, 1050000, 85,  90),
++      MALI_DVFS_STEP(533, 1075000, 1100000, 85, 100),
++};
++
++/*
++ * Variants
++ */
++
++static const struct mali_exynos_variant mali_variant_4210 = {
++      .steps = mali_exynos_dvfs_step_4210,
++      .nr_steps = ARRAY_SIZE(mali_exynos_dvfs_step_4210),
++};
++
++static const struct mali_exynos_variant mali_variant_4x12 = {
++      .steps = mali_exynos_dvfs_step_4x12,
++      .nr_steps = ARRAY_SIZE(mali_exynos_dvfs_step_4x12),
++};
++
++static const struct mali_exynos_variant mali_variant_4x12_prime = {
++      .steps = mali_exynos_dvfs_step_4x12_prime,
++      .nr_steps = ARRAY_SIZE(mali_exynos_dvfs_step_4x12_prime),
++};
++
++const struct of_device_id mali_of_matches[] = {
++      { .compatible = "samsung,exynos4210-g3d",
++                                      .data = &mali_variant_4210, },
++      { .compatible = "samsung,exynos4x12-g3d",
++                                      .data = &mali_variant_4x12, },
++      { .compatible = "samsung,exynos4x12-prime-g3d",
++                                      .data = &mali_variant_4x12_prime, },
++      { /* Sentinel */ }
++};
++
++/*
++ * DVFS control
++ */
++
++static void mali_exynos_set_dvfs_step(struct mali_exynos_drvdata *mali,
++                                                      unsigned int step)
++{
++      const struct mali_exynos_dvfs_step *next = &mali->steps[step];
++
++      if (step <= mali->dvfs_step)
++              clk_set_rate(mali->sclk_g3d, next->rate);
++
++      regulator_set_voltage(mali->vdd_g3d,
++                                      next->min_uv, next->max_uv);
++
++      if (step > mali->dvfs_step)
++              clk_set_rate(mali->sclk_g3d, next->rate);
++
++      mali->dvfs_step = step;
++}
++
++static void exynos_dvfs_work(struct work_struct *work)
++{
++      struct mali_exynos_drvdata *mali = container_of(work,
++                                      struct mali_exynos_drvdata, dvfs_work);
++      unsigned int step = mali->dvfs_step;
++      const struct mali_exynos_dvfs_step *cur = &mali->steps[step];
++
++      if (mali->load > cur->upthreshold)
++              ++step;
++      else if (mali->load < cur->downthreshold)
++              --step;
++
++      BUG_ON(step >= mali->nr_steps);
++
++      if (step != mali->dvfs_step)
++              mali_exynos_set_dvfs_step(mali, step);
++}
++
++static void exynos_update_dvfs(unsigned int load)
++{
++      if (load > 255)
++              load = 255;
++
++      mali->load = load;
++
++      queue_work(mali->dvfs_workqueue, &mali->dvfs_work);
++}
++
++/*
++ * Power management
++ */
++
++_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode)
++{
++      if (WARN_ON(mali->power_mode == power_mode))
++              MALI_SUCCESS;
++
++      switch (power_mode) {
++      case MALI_POWER_MODE_ON:
++              mali_exynos_set_dvfs_step(mali, 0);
++              clk_prepare_enable(mali->sclk_g3d);
++              break;
++
++      case MALI_POWER_MODE_LIGHT_SLEEP:
++      case MALI_POWER_MODE_DEEP_SLEEP:
++              clk_disable_unprepare(mali->sclk_g3d);
++              break;
++      }
++
++      mali->power_mode = power_mode;
++
++      MALI_SUCCESS;
++}
++
++/*
++ * Platform-specific initialization/cleanup
++ */
++
++static struct mali_gpu_device_data mali_exynos_gpu_data = {
++      .shared_mem_size = SZ_256M,
++      .fb_start = 0x40000000,
++      .fb_size = 0xb1000000,
++      .utilization_interval = 100, /* 100ms in Tizen */
++      .utilization_handler = exynos_update_dvfs,
++};
++
++_mali_osk_errcode_t mali_platform_init(void)
++{
++      struct platform_device *pdev = mali_platform_device;
++      const struct mali_exynos_variant *variant;
++      const struct of_device_id *match;
++      struct resource *old_res, *new_res;
++      unsigned int i, irq_res, mem_res;
++      struct device_node *np;
++
++      if (WARN_ON(!pdev))
++              return -ENODEV;
++
++      MALI_DEBUG_PRINT(4, ("mali_platform_device_register() called\n"));
++
++      pdev->dev.platform_data = &mali_exynos_gpu_data;
++
++      np = pdev->dev.of_node;
++      if (WARN_ON(!np))
++              return -ENODEV;
++
++      match = of_match_node(mali_of_matches, np);
++      if (WARN_ON(!match))
++              return -ENODEV;
++
++      variant = match->data;
++
++      old_res = pdev->resource;
++      new_res = kzalloc(sizeof(*new_res) * pdev->num_resources, GFP_KERNEL);
++      if (WARN_ON(!new_res))
++              return -ENOMEM;
++
++      /* Copy first resource */
++      memcpy(new_res, old_res++, sizeof(*new_res));
++
++      /* Rearrange next resources */
++      irq_res = 0;
++      mem_res = 0;
++      for (i = 1; i < pdev->num_resources; ++i, ++old_res) {
++              if (resource_type(old_res) == IORESOURCE_MEM)
++                      memcpy(&new_res[1 + 2 * mem_res++],
++                                              old_res, sizeof(*old_res));
++              else if (resource_type(old_res) == IORESOURCE_IRQ)
++                      memcpy(&new_res[2 + 2 * irq_res++],
++                                              old_res, sizeof(*old_res));
++      }
++
++      kfree(pdev->resource);
++      pdev->resource = new_res;
++
++      mali = devm_kzalloc(&pdev->dev, sizeof(*mali), GFP_KERNEL);
++      if (WARN_ON(!mali))
++              return -ENOMEM;
++
++      mali->dev = &pdev->dev;
++      mali->steps = variant->steps;
++      mali->nr_steps = variant->nr_steps;
++
++      mali->sclk_vpll = devm_clk_get(mali->dev, "sclk_vpll");
++      if (WARN_ON(IS_ERR(mali->sclk_vpll)))
++              return PTR_ERR(mali->sclk_vpll);
++
++      mali->mout_g3d1 = devm_clk_get(mali->dev, "mout_g3d1");
++      if (WARN_ON(IS_ERR(mali->mout_g3d1)))
++              return PTR_ERR(mali->mout_g3d1);
++
++      mali->mout_g3d = devm_clk_get(mali->dev, "mout_g3d");
++      if (WARN_ON(IS_ERR(mali->mout_g3d)))
++              return PTR_ERR(mali->mout_g3d);
++
++      mali->sclk_g3d = devm_clk_get(mali->dev, "sclk_g3d");
++      if (WARN_ON(IS_ERR(mali->sclk_g3d)))
++              return PTR_ERR(mali->sclk_g3d);
++
++      mali->vdd_g3d = devm_regulator_get(mali->dev, "vdd_g3d");
++      if (WARN_ON(IS_ERR(mali->vdd_g3d)))
++              return PTR_ERR(mali->vdd_g3d);
++
++      mali->dvfs_workqueue = create_singlethread_workqueue("mali_dvfs");
++      if (WARN_ON(!mali->dvfs_workqueue))
++              return -EFAULT;
++
++      mali->power_mode = MALI_POWER_MODE_LIGHT_SLEEP;
++
++      INIT_WORK(&mali->dvfs_work, exynos_dvfs_work);
++
++      regulator_enable(mali->vdd_g3d);
++
++      clk_set_parent(mali->mout_g3d1, mali->sclk_vpll);
++      clk_set_parent(mali->mout_g3d, mali->mout_g3d1);
++      mali_exynos_set_dvfs_step(mali, 0);
++
++      pm_runtime_set_autosuspend_delay(&pdev->dev, 300);
++      pm_runtime_use_autosuspend(&pdev->dev);
++
++      pm_runtime_enable(&pdev->dev);
++
++      MALI_SUCCESS;
++}
++
++_mali_osk_errcode_t mali_platform_deinit(void)
++{
++      struct platform_device *pdev = mali_platform_device;
++
++      pm_runtime_disable(&pdev->dev);
++
++      regulator_disable(mali->vdd_g3d);
++
++      MALI_SUCCESS;
++}
+diff --git a/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4.h b/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4.h
+new file mode 100644
+index 0000000..d4f5640
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4.h
+@@ -0,0 +1,88 @@
++/*
++ * Mali400 platform glue for Samsung Exynos 4 SoCs
++ *
++ * Copyright 2013 by Samsung Electronics Co., Ltd.
++ * Author: Tomasz Figa <t.figa@samsung.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 __EXYNOS4_H__
++#define __EXYNOS4_H__
++
++#include "mali_osk.h"
++
++/** @brief description of power change reasons
++ */
++typedef enum mali_power_mode_tag
++{
++      MALI_POWER_MODE_ON,
++      MALI_POWER_MODE_LIGHT_SLEEP,
++      MALI_POWER_MODE_DEEP_SLEEP,
++} mali_power_mode;
++
++/** @brief Platform specific setup and initialisation of MALI
++ *
++ * This is called from the entrypoint of the driver to initialize the platform
++ *
++ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
++ */
++_mali_osk_errcode_t mali_platform_init(void);
++
++/** @brief Platform specific deinitialisation of MALI
++ *
++ * This is called on the exit of the driver to terminate the platform
++ *
++ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
++ */
++_mali_osk_errcode_t mali_platform_deinit(void);
++
++/** @brief Platform specific powerdown sequence of MALI
++ *
++ * Call as part of platform init if there is no PMM support, else the
++ * PMM will call it.
++ * There are three power modes defined:
++ *  1) MALI_POWER_MODE_ON
++ *  2) MALI_POWER_MODE_LIGHT_SLEEP
++ *  3) MALI_POWER_MODE_DEEP_SLEEP
++ * MALI power management module transitions to MALI_POWER_MODE_LIGHT_SLEEP mode when MALI is idle
++ * for idle timer (software timer defined in mali_pmm_policy_jobcontrol.h) duration, MALI transitions
++ * to MALI_POWER_MODE_LIGHT_SLEEP mode during timeout if there are no more jobs queued.
++ * MALI power management module transitions to MALI_POWER_MODE_DEEP_SLEEP mode when OS does system power
++ * off.
++ * Customer has to add power down code when MALI transitions to MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP
++ * mode.
++ * MALI_POWER_MODE_ON mode is entered when the MALI is to powered up. Some customers want to control voltage regulators during
++ * the whole system powers on/off. Customer can track in this function whether the MALI is powered up from
++ * MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP mode and manage the voltage regulators as well.
++ * @param power_mode defines the power modes
++ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
++ */
++_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode);
++
++/** @brief Platform specific handling of GPU utilization data
++ *
++ * When GPU utilization data is enabled, this function will be
++ * periodically called.
++ *
++ * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization.
++ */
++void mali_gpu_utilization_handler(unsigned int utilization);
++
++/** @brief Platform specific power management initialization
++ *
++ * Initializes platform-specific part of power management.
++ */
++_mali_osk_errcode_t exynos_pmm_init(void);
++
++/** @brief Platform specific power management deinitialization
++ *
++ * Deinitializes platform-specific part of power management.
++ */
++_mali_osk_errcode_t exynos_pmm_deinit(void);
++
++extern const struct of_device_id mali_of_matches[];
++
++#endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0122-gpu-arm-mali400-ump-Fix-forced-recompilation-of-some.patch b/patches.tizen/0122-gpu-arm-mali400-ump-Fix-forced-recompilation-of-some.patch
new file mode 100644 (file)
index 0000000..bd9d02e
--- /dev/null
@@ -0,0 +1,77 @@
+From 310a12119656eb493f96db308ecbd8043d32b81c Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Mon, 13 May 2013 18:09:13 +0200
+Subject: [PATCH 0122/1302] gpu: arm: mali400: ump: Fix forced recompilation of
+ some files
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/arm/mali400/ump/Kbuild            |  1 -
+ drivers/gpu/arm/mali400/ump/arch              |  1 +
+ drivers/gpu/arm/mali400/ump/arch/arch-release |  1 -
+ drivers/gpu/arm/mali400/ump/arch/config.h     | 22 ----------------------
+ 4 files changed, 1 insertion(+), 24 deletions(-)
+ create mode 120000 drivers/gpu/arm/mali400/ump/arch
+ delete mode 120000 drivers/gpu/arm/mali400/ump/arch/arch-release
+ delete mode 100644 drivers/gpu/arm/mali400/ump/arch/config.h
+
+diff --git a/drivers/gpu/arm/mali400/ump/Kbuild b/drivers/gpu/arm/mali400/ump/Kbuild
+index 2c4d72c..55aa2d9 100644
+--- a/drivers/gpu/arm/mali400/ump/Kbuild
++++ b/drivers/gpu/arm/mali400/ump/Kbuild
+@@ -22,7 +22,6 @@ else
+ # Link arch to the selected arch-config directory
+ $(shell [ -L $(src)/arch ] && rm $(src)/arch)
+ $(shell ln -sf arch-$(CONFIG) $(src)/arch)
+-$(shell touch $(src)/arch/config.h)
+ endif
+ UDD_FILE_PREFIX = ../mali/
+diff --git a/drivers/gpu/arm/mali400/ump/arch b/drivers/gpu/arm/mali400/ump/arch
+new file mode 120000
+index 0000000..58ffbe7
+--- /dev/null
++++ b/drivers/gpu/arm/mali400/ump/arch
+@@ -0,0 +1 @@
++arch-release
+\ No newline at end of file
+diff --git a/drivers/gpu/arm/mali400/ump/arch/arch-release b/drivers/gpu/arm/mali400/ump/arch/arch-release
+deleted file mode 120000
+index 58ffbe7..0000000
+--- a/drivers/gpu/arm/mali400/ump/arch/arch-release
++++ /dev/null
+@@ -1 +0,0 @@
+-arch-release
+\ No newline at end of file
+diff --git a/drivers/gpu/arm/mali400/ump/arch/config.h b/drivers/gpu/arm/mali400/ump/arch/config.h
+deleted file mode 100644
+index 0b8dd5a..0000000
+--- a/drivers/gpu/arm/mali400/ump/arch/config.h
++++ /dev/null
+@@ -1,22 +0,0 @@
+-/*
+- * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+- *
+- * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+- * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+- *
+- * A copy of the licence is included with the program, and can also be obtained from Free Software
+- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+- */
+-
+-#ifndef __ARCH_CONFIG_UMP_H__
+-#define __ARCH_CONFIG_UMP_H__
+-
+-#define ARCH_UMP_BACKEND_DEFAULT              USING_MEMORY
+-#if (USING_MEMORY == 0) /* Dedicated Memory */
+-#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT       0x2C000000
+-#else
+-#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT       0
+-#endif
+-
+-#define ARCH_UMP_MEMORY_SIZE_DEFAULT          UMP_MEM_SIZE*1024*1024
+-#endif /* __ARCH_CONFIG_UMP_H__ */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0123-ARM-dts-exynos4-Add-gpu-node-for-ARM-Mali-400.patch b/patches.tizen/0123-ARM-dts-exynos4-Add-gpu-node-for-ARM-Mali-400.patch
new file mode 100644 (file)
index 0000000..a5eda2a
--- /dev/null
@@ -0,0 +1,74 @@
+From 1a4303e7c0c703e67bd43aa05b3d1e38dbe9d2f6 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 14 Feb 2013 12:24:07 +0100
+Subject: [PATCH 0123/1302] ARM: dts: exynos4: Add gpu node for ARM Mali 400
+
+This patch adds gpu node to exynos4 dtsi with properties common for all
+Exynos4 SoCs.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210.dtsi | 17 +++++++++++++++++
+ arch/arm/boot/dts/exynos4x12.dtsi | 17 +++++++++++++++++
+ 2 files changed, 34 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
+index 750b320..fe5aa7a 100644
+--- a/arch/arm/boot/dts/exynos4210.dtsi
++++ b/arch/arm/boot/dts/exynos4210.dtsi
+@@ -202,6 +202,23 @@
+               };
+       };
++      gpu@13000000 {
++              compatible = "samsung,exynos4210-g3d";
++              reg = <0x13001000 0x200>,
++                      <0x13000000 0x100>, <0x13003000 0x100>,
++                      <0x13008000 0x1100>, <0x13004000 0x100>,
++                      <0x1300a000 0x1100>, <0x13005000 0x100>,
++                      <0x1300c000 0x1100>, <0x13006000 0x100>,
++                      <0x1300e000 0x1100>, <0x13007000 0x100>;
++              interrupts = <0 127 0>, <0 122 0>, <0 123 0>, <0 118 0>,
++                              <0 124 0>, <0 119 0>, <0 125 0>, <0 120 0>,
++                              <0 126 0>, <0 121 0>;
++              clock-names = "sclk_vpll", "mout_g3d1", "mout_g3d", "sclk_g3d";
++              clocks = <&clock 11>, <&clock 393>, <&clock 394>, <&clock 172>;
++              samsung,power-domain = <&pd_g3d>;
++              status = "disabled";
++      };
++
+       cpufreq {
+               compatible = "samsung,exynos-cpufreq";
+               clocks = <&clock 12>, <&clock 19>, <&clock 9>, <&clock 20>;
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index c0edb05..3872297 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -262,6 +262,23 @@
+               };
+       };
++      gpu@13000000 {
++              compatible = "samsung,exynos4x12-g3d";
++              reg = <0x13001000 0x200>,
++                      <0x13000000 0x100>, <0x13003000 0x100>,
++                      <0x13008000 0x1100>, <0x13004000 0x100>,
++                      <0x1300a000 0x1100>, <0x13005000 0x100>,
++                      <0x1300c000 0x1100>, <0x13006000 0x100>,
++                      <0x1300e000 0x1100>, <0x13007000 0x100>;
++              interrupts = <0 127 0>, <0 122 0>, <0 123 0>, <0 118 0>,
++                              <0 124 0>, <0 119 0>, <0 125 0>, <0 120 0>,
++                              <0 126 0>, <0 121 0>;
++              clock-names = "sclk_vpll", "mout_g3d1", "mout_g3d", "sclk_g3d";
++              clocks = <&clock 11>, <&clock 393>, <&clock 394>, <&clock 172>;
++              samsung,power-domain = <&pd_g3d>;
++              status = "disabled";
++      };
++
+       cpufreq {
+               compatible = "samsung,exynos-cpufreq";
+               clocks = <&clock 12>, <&clock 19>, <&clock 9>, <&clock 20>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0124-ARM-dts-exynos4412-slp_pq-Add-gpu-node-for-ARM-Mali-.patch b/patches.tizen/0124-ARM-dts-exynos4412-slp_pq-Add-gpu-node-for-ARM-Mali-.patch
new file mode 100644 (file)
index 0000000..e236224
--- /dev/null
@@ -0,0 +1,34 @@
+From dee5a784844f9343cb41bb7864b64058f97c2cba Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 14 Feb 2013 12:25:47 +0100
+Subject: [PATCH 0124/1302] ARM: dts: exynos4412-slp_pq: Add gpu node for ARM
+ Mali 400
+
+This patch adds gpu node with board-specific properties and status
+override to enable G3D on SLP_PQ board.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 653ef3b..77ee50e 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -705,6 +705,11 @@
+               };
+       };
++      gpu@13000000 {
++              status = "okay";
++              vdd_g3d-supply = <&buck4_reg>;
++      };
++
+       cpufreq {
+               freq_table = <0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 1100000 1000000
+                            900000 800000 700000 600000 500000 400000 300000
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0125-ARM-dts-exynos4210-trats-Add-G3D-voltage-regulator.patch b/patches.tizen/0125-ARM-dts-exynos4210-trats-Add-G3D-voltage-regulator.patch
new file mode 100644 (file)
index 0000000..b75b4a8
--- /dev/null
@@ -0,0 +1,35 @@
+From d21cbc163ffbc772510ff231421c962d28acfe9c Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 20 Feb 2013 10:57:42 +0100
+Subject: [PATCH 0125/1302] ARM: dts: exynos4210-trats: Add G3D voltage
+ regulator
+
+This patch adds G3D voltage regulator, which is needed for voltage
+scaling in Mali driver, to PMIC node.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index 4b90ae3..fca0c16 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -292,6 +292,12 @@
+                                    regulator-always-on;
+                               };
++                              vg3d_breg: BUCK3 {
++                                      regulator-name = "VG3D_1.1V_C210";
++                                      regulator-min-microvolt = <850000>;
++                                      regulator-max-microvolt = <1100000>;
++                              };
++
+                               camisp_breg: BUCK4 {
+                                    regulator-name = "CAM_ISP_CORE_1.2V";
+                                    regulator-min-microvolt = <1200000>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0126-ARM-dts-exynos4210-trats-Add-gpu-node-for-ARM-Mali-4.patch b/patches.tizen/0126-ARM-dts-exynos4210-trats-Add-gpu-node-for-ARM-Mali-4.patch
new file mode 100644 (file)
index 0000000..be5a608
--- /dev/null
@@ -0,0 +1,32 @@
+From e2d1801d620b232b038ac4221a02cca11b58af0b Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 20 Feb 2013 10:59:43 +0100
+Subject: [PATCH 0126/1302] ARM: dts: exynos4210-trats: Add gpu node for ARM
+ Mali 400
+
+This patch adds gpu node with board-specific properties and status
+override to enable G3D on Trats board.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index fca0c16..eca8054 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -444,4 +444,9 @@
+               vdd_arm-supply = <&varm_breg>;
+               status = "okay";
+       };
++
++      gpu@13000000 {
++              status = "okay";
++              vdd_g3d-supply = <&vg3d_breg>;
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0127-ARM-dts-exynos4412-redwood-Add-gpu-node-for-ARM-Mali.patch b/patches.tizen/0127-ARM-dts-exynos4412-redwood-Add-gpu-node-for-ARM-Mali.patch
new file mode 100644 (file)
index 0000000..1e2d6ec
--- /dev/null
@@ -0,0 +1,32 @@
+From 31dc6d7bf6ecdb998e1abdadee9eca37015f57c6 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 21 Feb 2013 16:23:39 +0100
+Subject: [PATCH 0127/1302] ARM: dts: exynos4412-redwood: Add gpu node for ARM
+ Mali 400
+
+This patch adds gpu node with board-specific properties and status
+override to enable G3D on Redwood board.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-redwood.dts | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-redwood.dts b/arch/arm/boot/dts/exynos4412-redwood.dts
+index ac6ef14..5df54e8 100644
+--- a/arch/arm/boot/dts/exynos4412-redwood.dts
++++ b/arch/arm/boot/dts/exynos4412-redwood.dts
+@@ -525,4 +525,9 @@
+                       memory-region = <&mfc_r_mem>;
+               };
+       };
++
++      gpu@13000000 {
++              status = "okay";
++              vdd_g3d-supply = <&buck4_reg>;
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0128-ARM-dts-add-mshc-controller-node-for-Exynos4x12-SoCs.patch b/patches.tizen/0128-ARM-dts-add-mshc-controller-node-for-Exynos4x12-SoCs.patch
new file mode 100644 (file)
index 0000000..d4f56f1
--- /dev/null
@@ -0,0 +1,51 @@
+From 57acac5957558f2d61c76e5af672a1911bd8bd31 Mon Sep 17 00:00:00 2001
+From: Thomas Abraham <thomas.abraham@linaro.org>
+Date: Wed, 27 Feb 2013 10:13:06 +0100
+Subject: [PATCH 0128/1302] ARM: dts: add mshc controller node for Exynos4x12
+ SoCs
+
+Commit cea0f256 ("ARM: dts: Add board dts file for ODROID-X") includes a node
+to describe the board level properties for mshc controller. But the mshc
+controller node was not added in the Exynos4x12 dtsi file which resulted
+in the following warning when compiling the dtb files.
+
+Warning (reg_format): "reg" property in /mshc@12550000/slot@0 has invalid length (4 bytes) (#address-cells == 2, #size-cells == 1)
+Warning (avoid_default_addr_size): Relying on default #address-cells value for /mshc@12550000/slot@0
+Warning (avoid_default_addr_size): Relying on default #size-cells value for /mshc@12550000/slot@0
+
+Fix this by adding the mshc controller node for Exynos4x12 SoCs.
+
+Cc: Dongjin Kim <tobetter@gmail.com>
+Cc: Kukjin Kim <kgene.kim@samsung.com>
+[s.nawrocki: resolved merge conflict]
+Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
+Tested-by: Dongjin Kim <tobetter@gmail.com>
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12.dtsi | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index 3872297..1e7784e 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -75,6 +75,14 @@
+               };
+       };
++      mshc@12550000 {
++              compatible = "samsung,exynos4412-dw-mshc";
++              reg = <0x12550000 0x1000>;
++              interrupts = <0 77 0>;
++              #address-cells = <1>;
++              #size-cells = <0>;
++      };
++
+       pinctrl_2: pinctrl@03860000 {
+               compatible = "samsung,exynos4x12-pinctrl";
+               reg = <0x03860000 0x1000>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0129-ARM-dts-added-cam_port_a-to-exynos4210-pinctrl.patch b/patches.tizen/0129-ARM-dts-added-cam_port_a-to-exynos4210-pinctrl.patch
new file mode 100644 (file)
index 0000000..9961f78
--- /dev/null
@@ -0,0 +1,50 @@
+From 123af196bbcd3f3b21442b0f44c8d8529bad2451 Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Wed, 27 Feb 2013 10:36:38 +0100
+Subject: [PATCH 0129/1302] ARM: dts: added cam_port_a to exynos4210 pinctrl
+
+Patch adds cam_port a to exynos4210.
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-pinctrl.dtsi | 23 +++++++++++++++++++++++
+ 1 file changed, 23 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
+index 55a2efb..00a1221 100644
+--- a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
++++ b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
+@@ -708,6 +708,29 @@
+                       samsung,pin-pud = <0>;
+                       samsung,pin-drv = <0>;
+               };
++
++              cam_port_a_io: cam-port-a-io {
++                      samsung,pins = "gpj0-0", "gpj0-1", "gpj0-2", "gpj0-3",
++                                      "gpj0-4", "gpj0-5", "gpj0-6", "gpj0-7",
++                                      "gpj1-0", "gpj1-1", "gpj1-2", "gpj1-4";
++                      samsung,pin-function = <2>;
++                      samsung,pin-pud = <0>;
++                      samsung,pin-drv = <0>;
++              };
++
++              cam_port_a_clk: cam-port-a-clk {
++                      samsung,pins = "gpj1-3";
++                      samsung,pin-function = <2>;
++                      samsung,pin-pud = <0>;
++                      samsung,pin-drv = <3>;
++              };
++
++              cam_port_a_clk_off: cam-port-a-clk-off {
++                      samsung,pins = "gpj1-3";
++                      samsung,pin-function = <0>;
++                      samsung,pin-pud = <0>;
++                      samsung,pin-drv = <0>;
++              };
+       };
+       pinctrl@03860000 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0130-ARM-dts-added-trats-m5mols-camera-support.patch b/patches.tizen/0130-ARM-dts-added-trats-m5mols-camera-support.patch
new file mode 100644 (file)
index 0000000..0a70ec8
--- /dev/null
@@ -0,0 +1,172 @@
+From 6c46f5bb6fb5f80bd3c98a38611774b710c2421e Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Wed, 13 Feb 2013 15:33:06 +0100
+Subject: [PATCH 0130/1302] ARM: dts: added trats m5mols camera support
+
+The patch adds:
+- m5mols camera node,
+- csis0 node,
+- m5mols camera fixed regulators.
+Additionally all fixed regulators are moved to regulators node.
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 117 ++++++++++++++++++++++++++++-----
+ 1 file changed, 102 insertions(+), 15 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index eca8054..5c68f44 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -63,13 +63,60 @@
+               };
+       };
+-      vemmc_reg: voltage-regulator@0 {
+-              compatible = "regulator-fixed";
+-              regulator-name = "VMEM_VDD_2.8V";
+-              regulator-min-microvolt = <2800000>;
+-              regulator-max-microvolt = <2800000>;
+-              gpio = <&gpk0 2 0>;
+-              enable-active-high;
++      regulators {
++              compatible = "simple-bus";
++              #address-cells = <1>;
++              #size-cells = <0>;
++
++              vemmc_reg: regulator@0 {
++                      compatible = "regulator-fixed";
++                      reg = <0>;
++                      regulator-name = "VMEM_VDD_2.8V";
++                      regulator-min-microvolt = <2800000>;
++                      regulator-max-microvolt = <2800000>;
++                      gpio = <&gpk0 2 0>;
++                      enable-active-high;
++              };
++
++              tsp_reg: regulator@1 {
++                      compatible = "regulator-fixed";
++                      reg = <1>;
++                      regulator-name = "TSP_FIXED_VOLTAGES";
++                      regulator-min-microvolt = <2800000>;
++                      regulator-max-microvolt = <2800000>;
++                      gpio = <&gpl0 3 0>;
++                      enable-active-high;
++              };
++
++              cam_af_28v_reg: regulator@2 {
++                      compatible = "regulator-fixed";
++                      reg = <2>;
++                      regulator-name = "8M_AF_2.8V_EN";
++                      regulator-min-microvolt = <2800000>;
++                      regulator-max-microvolt = <2800000>;
++                      gpio = <&gpk1 1 0>;
++                      enable-active-high;
++              };
++
++              cam_io_en_reg: regulator@3 {
++                      compatible = "regulator-fixed";
++                      reg = <3>;
++                      regulator-name = "CAM_IO_EN";
++                      regulator-min-microvolt = <2800000>;
++                      regulator-max-microvolt = <2800000>;
++                      gpio = <&gpe2 1 0>;
++                      enable-active-high;
++              };
++
++              cam_io_12v_reg: regulator@4 {
++                      compatible = "regulator-fixed";
++                      reg = <4>;
++                      regulator-name = "8M_1.2V_EN";
++                      regulator-min-microvolt = <1200000>;
++                      regulator-max-microvolt = <1200000>;
++                      gpio = <&gpe2 5 0>;
++                      enable-active-high;
++              };
+       };
+       sdhci_emmc: sdhci@12510000 {
+@@ -130,15 +177,36 @@
+               };
+       };
+-      tsp_reg: voltage-regulator {
+-              compatible = "regulator-fixed";
+-              regulator-name = "TSP_FIXED_VOLTAGES";
+-              regulator-min-microvolt = <2800000>;
+-              regulator-max-microvolt = <2800000>;
+-              gpio = <&gpl0 3 0>;
+-              enable-active-high;
++      i2c@13860000 {
++              samsung,i2c-sda-delay = <100>;
++              samsung,i2c-max-bus-freq = <400000>;
++              pinctrl-0 = <&i2c0_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              m5mols@1f {
++                      compatible = "samsung,m5mols";
++                      reg = <0x1f>;
++                      interrupt-parent = <&gpx1>;
++                      interrupts = <5 1>;
++                      core-supply = <&camisp_breg>;
++                      dig_18-supply = <&vcam_reg>;
++                      d_sensor-supply = <&camsensor_reg>;
++                      dig_28-supply = <&cam_af_28v_reg>;
++                      a_sensor-supply = <&cam_io_en_reg>;
++                      dig_12-supply = <&cam_io_12v_reg>;
++                      gpios = <&gpy3 7 1>;
++                      clock-frequency = <24000000>;
++
++                      port {
++                              m5mols_ep: endpoint {
++                                      remote-endpoint = <&m5mols_ep>;
++                              };
++                      };
++              };
+       };
++
+       i2c@13890000 {
+               samsung,i2c-sda-delay = <100>;
+               samsung,i2c-slave-addr = <0x10>;
+@@ -408,7 +476,7 @@
+               status = "okay";
+               pinctrl-names = "default";
+-              pinctrl-0 = <>; /* TODO */
++              pinctrl-0 = <&cam_port_a_clk>;
+               fimc_0: fimc@11800000 {
+                       status = "okay";
+@@ -425,6 +493,25 @@
+               fimc_3: fimc@11830000 {
+                       status = "okay";
+               };
++
++              csis_0: csis@11880000 {
++                      status = "okay";
++                      vddcore-supply = <&vusb_reg>;
++                      vddio-supply = <&vmipi_reg>;
++                      clock-frequency = <160000000>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++
++                      /* Camera C (3) MIPI CSI-2 (CSIS0) */
++                      port@3 {
++                              reg = <3>;
++                              csis0_ep: endpoint {
++                                      remote-endpoint = <&m5mols_ep>;
++                                      data-lanes = <1 2>;
++                                      samsung,csis-hs-settle = <12>;
++                              };
++                      };
++              };
+       };
+       mfc: codec@13400000 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0131-m5mols-improved-power-on-routine.patch b/patches.tizen/0131-m5mols-improved-power-on-routine.patch
new file mode 100644 (file)
index 0000000..c094934
--- /dev/null
@@ -0,0 +1,69 @@
+From 55c0af6a56a3e489e7c408e7327ec95f3fe36491 Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Wed, 27 Feb 2013 12:32:39 +0100
+Subject: [PATCH 0131/1302] m5mols: improved power on routine
+
+1. Regulators are enabled sequentially.
+2. Added 1ms delay after GPIO reset.
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/m5mols/m5mols_core.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c
+index 0b899cb..656e107 100644
+--- a/drivers/media/i2c/m5mols/m5mols_core.c
++++ b/drivers/media/i2c/m5mols/m5mols_core.c
+@@ -740,6 +740,22 @@ static const struct v4l2_subdev_video_ops m5mols_video_ops = {
+       .s_stream       = m5mols_s_stream,
+ };
++static int regulator_bulk_enable_sync(int num_consumers,
++                                    struct regulator_bulk_data *consumers)
++{
++      int ret = 0;
++      int i;
++
++      for (i = 0; i < ARRAY_SIZE(supplies); ++i) {
++              ret = regulator_enable(supplies[i].consumer);
++      }
++      if (ret < 0)
++              for (; i >= 0; --i)
++                      regulator_disable(supplies[i].consumer);
++
++      return ret;
++}
++
+ static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
+ {
+       struct v4l2_subdev *sd = &info->sd;
+@@ -757,13 +773,15 @@ static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
+                               return ret;
+               }
+-              ret = regulator_bulk_enable(ARRAY_SIZE(supplies), supplies);
++              ret = regulator_bulk_enable_sync(ARRAY_SIZE(supplies),
++                                                supplies);
+               if (ret) {
+                       info->set_power(&client->dev, 0);
+                       return ret;
+               }
+               gpio_set_value(pdata->gpio_reset, !pdata->reset_polarity);
++              usleep_range(1000, 1000);
+               info->power = 1;
+               return ret;
+@@ -777,6 +795,7 @@ static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
+               info->set_power(&client->dev, 0);
+       gpio_set_value(pdata->gpio_reset, pdata->reset_polarity);
++      usleep_range(1000, 1000);
+       info->isp_ready = 0;
+       info->power = 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0132-m5mols-device-initialization-moved-to-V4L2-registere.patch b/patches.tizen/0132-m5mols-device-initialization-moved-to-V4L2-registere.patch
new file mode 100644 (file)
index 0000000..231c3b9
--- /dev/null
@@ -0,0 +1,75 @@
+From 2de48b138ec30e3dbabb3e3f361e84a27553151f Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Wed, 27 Feb 2013 13:26:29 +0100
+Subject: [PATCH 0132/1302] m5mols: device initialization moved to V4L2
+ registered callback
+
+Since parent media device controls camera clock
+device initialization must be performed in registered callback.
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/m5mols/m5mols_core.c | 37 +++++++++++++++++++++++-----------
+ 1 file changed, 25 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c
+index 656e107..9504d88 100644
+--- a/drivers/media/i2c/m5mols/m5mols_core.c
++++ b/drivers/media/i2c/m5mols/m5mols_core.c
+@@ -925,7 +925,31 @@ static int m5mols_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+       return 0;
+ }
++static int m5mols_registered(struct v4l2_subdev *sd)
++{
++      struct m5mols_info *info = to_m5mols(sd);
++      int ret;
++
++      mutex_lock(&info->lock);
++
++      ret = m5mols_sensor_power(info, true);
++      if (!ret)
++              ret = m5mols_fw_start(sd);
++      if (!ret)
++              ret = m5mols_init_controls(sd);
++
++      m5mols_sensor_power(info, false);
++
++      mutex_unlock(&info->lock);
++
++      v4l2_dbg(1, m5mols_debug, sd, "%s: Booting %s (%d)\n",
++               __func__, ret ? "failed" : "succeded", ret);
++
++      return ret;
++}
++
+ static const struct v4l2_subdev_internal_ops m5mols_subdev_internal_ops = {
++      .registered     = m5mols_registered,
+       .open           = m5mols_open,
+ };
+@@ -1013,19 +1037,8 @@ static int m5mols_probe(struct i2c_client *client,
+       info->ffmt[0] = m5mols_default_ffmt[0];
+       info->ffmt[1] = m5mols_default_ffmt[1];
+-      ret = m5mols_sensor_power(info, true);
+-      if (ret)
+-              goto out_irq;
+-
+-      ret = m5mols_fw_start(sd);
+-      if (!ret)
+-              ret = m5mols_init_controls(sd);
++      return 0;
+-      ret = m5mols_sensor_power(info, false);
+-      if (!ret)
+-              return 0;
+-out_irq:
+-      free_irq(client->irq, sd);
+ out_me:
+       media_entity_cleanup(&sd->entity);
+ out_reg:
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0133-m5mols-added-device-tree-support.patch b/patches.tizen/0133-m5mols-added-device-tree-support.patch
new file mode 100644 (file)
index 0000000..78de2db
--- /dev/null
@@ -0,0 +1,210 @@
+From 3cf961c859baef7440ecb81d6daa361e4f52ab8e Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Wed, 27 Feb 2013 14:34:40 +0100
+Subject: [PATCH 0133/1302] m5mols: added device tree support
+
+The only property required by m5mols is "gpios",
+which should contain specification of reset GPIO.
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/m5mols/m5mols.h      |  8 ++--
+ drivers/media/i2c/m5mols/m5mols_core.c | 71 ++++++++++++++++++++++++----------
+ 2 files changed, 54 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/media/i2c/m5mols/m5mols.h b/drivers/media/i2c/m5mols/m5mols.h
+index 90a6c52..0599b8a 100644
+--- a/drivers/media/i2c/m5mols/m5mols.h
++++ b/drivers/media/i2c/m5mols/m5mols.h
+@@ -18,6 +18,8 @@
+ #include <linux/sizes.h>
+ #include <media/v4l2-subdev.h>
++#include <media/m5mols.h>
++
+ #include "m5mols_reg.h"
+@@ -182,7 +184,6 @@ struct m5mols_version {
+  * @wdr: wide dynamic range control
+  * @stabilization: image stabilization control
+  * @jpeg_quality: JPEG compression quality control
+- * @set_power: optional power callback to the board code
+  * @lock: mutex protecting the structure fields below
+  * @ffmt: current fmt according to resolution type
+  * @res_type: current resolution type
+@@ -195,7 +196,8 @@ struct m5mols_version {
+  * @mode: register value for current operation mode
+  */
+ struct m5mols_info {
+-      const struct m5mols_platform_data *pdata;
++      struct m5mols_platform_data pdata;
++
+       struct v4l2_subdev sd;
+       struct media_pad pad;
+@@ -225,8 +227,6 @@ struct m5mols_info {
+       struct v4l2_ctrl *stabilization;
+       struct v4l2_ctrl *jpeg_quality;
+-      int (*set_power)(struct device *dev, int on);
+-
+       struct mutex lock;
+       struct v4l2_mbus_framefmt ffmt[M5MOLS_RESTYPE_MAX];
+diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c
+index 9504d88..a8ae5d8 100644
+--- a/drivers/media/i2c/m5mols/m5mols_core.c
++++ b/drivers/media/i2c/m5mols/m5mols_core.c
+@@ -19,13 +19,13 @@
+ #include <linux/interrupt.h>
+ #include <linux/delay.h>
+ #include <linux/gpio.h>
++#include <linux/of_gpio.h>
+ #include <linux/regulator/consumer.h>
+ #include <linux/videodev2.h>
+ #include <linux/module.h>
+ #include <media/v4l2-ctrls.h>
+ #include <media/v4l2-device.h>
+ #include <media/v4l2-subdev.h>
+-#include <media/m5mols.h>
+ #include "m5mols.h"
+ #include "m5mols_reg.h"
+@@ -760,15 +760,15 @@ static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
+ {
+       struct v4l2_subdev *sd = &info->sd;
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+-      const struct m5mols_platform_data *pdata = info->pdata;
++      struct m5mols_platform_data *pdata = &info->pdata;
+       int ret;
+       if (info->power == enable)
+               return 0;
+       if (enable) {
+-              if (info->set_power) {
+-                      ret = info->set_power(&client->dev, 1);
++              if (pdata->set_power) {
++                      ret = pdata->set_power(&client->dev, 1);
+                       if (ret)
+                               return ret;
+               }
+@@ -776,7 +776,7 @@ static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
+               ret = regulator_bulk_enable_sync(ARRAY_SIZE(supplies),
+                                                 supplies);
+               if (ret) {
+-                      info->set_power(&client->dev, 0);
++                      pdata->set_power(&client->dev, 0);
+                       return ret;
+               }
+@@ -791,8 +791,8 @@ static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
+       if (ret)
+               return ret;
+-      if (info->set_power)
+-              info->set_power(&client->dev, 0);
++      if (pdata->set_power)
++              pdata->set_power(&client->dev, 0);
+       gpio_set_value(pdata->gpio_reset, pdata->reset_polarity);
+       usleep_range(1000, 1000);
+@@ -969,24 +969,38 @@ static irqreturn_t m5mols_irq_handler(int irq, void *data)
+       return IRQ_HANDLED;
+ }
++static int m5mols_get_platform_data(struct m5mols_info *info,
++                                  struct device *dev)
++{
++      struct m5mols_platform_data *pdata = dev->platform_data;
++      struct device_node *node = dev->of_node;
++      enum of_gpio_flags of_flags;
++
++      if (!node) {
++              if (!pdata) {
++                      dev_err(dev, "No platform data\n");
++                      return -EINVAL;
++              }
++              info->pdata = *pdata;
++              return 0;
++      }
++
++      pdata = &info->pdata;
++
++      pdata->gpio_reset = of_get_gpio_flags(node, 0, &of_flags);
++      pdata->reset_polarity = !(of_flags & OF_GPIO_ACTIVE_LOW);
++
++      return 0;
++}
++
+ static int m5mols_probe(struct i2c_client *client,
+                       const struct i2c_device_id *id)
+ {
+-      const struct m5mols_platform_data *pdata = client->dev.platform_data;
++      struct m5mols_platform_data *pdata;
+       struct m5mols_info *info;
+       struct v4l2_subdev *sd;
+       int ret;
+-      if (pdata == NULL) {
+-              dev_err(&client->dev, "No platform data\n");
+-              return -EINVAL;
+-      }
+-
+-      if (!gpio_is_valid(pdata->gpio_reset)) {
+-              dev_err(&client->dev, "No valid RESET GPIO specified\n");
+-              return -EINVAL;
+-      }
+-
+       if (!client->irq) {
+               dev_err(&client->dev, "Interrupt not assigned\n");
+               return -EINVAL;
+@@ -996,8 +1010,16 @@ static int m5mols_probe(struct i2c_client *client,
+       if (!info)
+               return -ENOMEM;
+-      info->pdata = pdata;
+-      info->set_power = pdata->set_power;
++      ret = m5mols_get_platform_data(info, &client->dev);
++      if (ret < 0)
++              return ret;
++
++      pdata = &info->pdata;
++
++      if (!gpio_is_valid(pdata->gpio_reset)) {
++              dev_err(&client->dev, "No valid RESET GPIO specified\n");
++              return -EINVAL;
++      }
+       ret = gpio_request(pdata->gpio_reset, "M5MOLS_NRST");
+       if (ret) {
+@@ -1060,7 +1082,7 @@ static int m5mols_remove(struct i2c_client *client)
+       free_irq(client->irq, sd);
+       regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
+-      gpio_free(info->pdata->gpio_reset);
++      gpio_free(info->pdata.gpio_reset);
+       media_entity_cleanup(&sd->entity);
+       kfree(info);
+       return 0;
+@@ -1072,8 +1094,15 @@ static const struct i2c_device_id m5mols_id[] = {
+ };
+ MODULE_DEVICE_TABLE(i2c, m5mols_id);
++static const struct of_device_id m5mols_of_match[] = {
++      { .compatible = "samsung,m5mols" },
++      { }
++};
++MODULE_DEVICE_TABLE(of, m5mols_of_match);
++
+ static struct i2c_driver m5mols_i2c_driver = {
+       .driver = {
++              .of_match_table = m5mols_of_match,
+               .name   = MODULE_NAME,
+       },
+       .probe          = m5mols_probe,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0134-ARM-dts-exynos4210-trats-add-s5k5baf-sensor-support.patch b/patches.tizen/0134-ARM-dts-exynos4210-trats-add-s5k5baf-sensor-support.patch
new file mode 100644 (file)
index 0000000..b45653a
--- /dev/null
@@ -0,0 +1,114 @@
+From 8021cf7d5e7f901009e9ef198486abf298aeffff Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 10 May 2013 15:16:07 +0200
+Subject: [PATCH 0134/1302] ARM: dts: exynos4210-trats: add s5k5baf sensor
+ support
+
+Added:
+- i2c-gpio bus for the sensor,
+- required regulators,
+- MIPI-CSIS1 node,
+- sensor node.
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 61 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 61 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index 5c68f44..a399016 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -117,6 +117,16 @@
+                       gpio = <&gpe2 5 0>;
+                       enable-active-high;
+               };
++
++              vt_core_15v_reg: regulator@5 {
++                      compatible = "regulator-fixed";
++                      reg = <5>;
++                      regulator-name = "VT_CORE_1.5V";
++                      regulator-min-microvolt = <1500000>;
++                      regulator-max-microvolt = <1500000>;
++                      gpio = <&gpe2 2 0>;
++                      enable-active-high;
++              };
+       };
+       sdhci_emmc: sdhci@12510000 {
+@@ -177,6 +187,32 @@
+               };
+       };
++      i2c-gpio {
++              compatible = "i2c-gpio";
++              gpios = <&gpc1 0 0>, <&gpc1 2 0>;
++              i2c-gpio,delay-us = <2>;
++              #address-cells = <1>;
++              #size-cells = <0>;
++              status = "okay";
++
++              s5k5bafx@2d {
++                      compatible = "samsung,s5k5baf";
++                      reg = <0x2d>;
++                      vdda-supply = <&cam_io_en_reg>;
++                      vdd_reg-supply = <&vt_core_15v_reg>;
++                      vddio-supply = <&vtcam_reg>;
++                      gpios = <&gpl2 1 1>,
++                              <&gpl2 0 1>;
++                      clock-frequency = <24000000>;
++
++                      port {
++                              s5k5bafx_ep: endpoint {
++                                      remote-endpoint = <&csis1_ep>;
++                              };
++                      };
++              };
++      };
++
+       i2c@13860000 {
+               samsung,i2c-sda-delay = <100>;
+               samsung,i2c-max-bus-freq = <400000>;
+@@ -321,6 +357,12 @@
+                                    regulator-always-on;
+                               };
++                              vtcam_reg: LDO12 {
++                                   regulator-name = "VT_CAM_1.8V";
++                                   regulator-min-microvolt = <1800000>;
++                                   regulator-max-microvolt = <1800000>;
++                              };
++
+                               vcclcd_reg: LDO13 {
+                                    regulator-name = "VCC_3.3V_LCD";
+                                    regulator-min-microvolt = <3300000>;
+@@ -512,6 +554,25 @@
+                               };
+                       };
+               };
++
++              csis_1: csis@11890000 {
++                      status = "okay";
++                      vddcore-supply = <&vusb_reg>;
++                      vddio-supply = <&vmipi_reg>;
++                      clock-frequency = <160000000>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++
++                      /* MIPI-CSIS1 */
++                      port@4 {
++                              reg = <4>;
++                              csis1_ep: endpoint {
++                                      remote-endpoint = <&s5k5bafx_ep>;
++                                      data-lanes = <1>;
++                                      samsung,csis-hs-settle = <6>;
++                              };
++                      };
++              };
+       };
+       mfc: codec@13400000 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0135-ASoC-samsung-Add-pinctrl-support-to-I2S-driver.patch b/patches.tizen/0135-ASoC-samsung-Add-pinctrl-support-to-I2S-driver.patch
new file mode 100644 (file)
index 0000000..4e63e4d
--- /dev/null
@@ -0,0 +1,38 @@
+From 3fc77d8e44e5dc89782dde282f8375fb7b39ba21 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 14 Feb 2013 18:33:26 +0100
+Subject: [PATCH 0135/1302] ASoC: samsung: Add pinctrl support to I2S driver
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ sound/soc/samsung/i2s.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
+index 82ebb1a..78472d2 100644
+--- a/sound/soc/samsung/i2s.c
++++ b/sound/soc/samsung/i2s.c
+@@ -17,6 +17,7 @@
+ #include <linux/module.h>
+ #include <linux/of.h>
+ #include <linux/of_gpio.h>
++#include <linux/pinctrl/consumer.h>
+ #include <linux/pm_runtime.h>
+ #include <sound/soc.h>
+@@ -1236,7 +1237,10 @@ static int samsung_i2s_probe(struct platform_device *pdev)
+       }
+       if (np) {
+-              if (samsung_i2s_parse_dt_gpio(pri_dai)) {
++              struct pinctrl *pctrl;
++              pctrl = devm_pinctrl_get_select_default(&pdev->dev);
++
++              if (IS_ERR(pctrl) && samsung_i2s_parse_dt_gpio(pri_dai)) {
+                       dev_err(&pdev->dev, "Unable to configure gpio\n");
+                       ret = -EINVAL;
+                       goto err;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0136-ARM-dts-Use-generic-DMA-bindings-for-Exynos4-SPI-dev.patch b/patches.tizen/0136-ARM-dts-Use-generic-DMA-bindings-for-Exynos4-SPI-dev.patch
new file mode 100644 (file)
index 0000000..3b3be87
--- /dev/null
@@ -0,0 +1,52 @@
+From a66299a97599f083e5b867294c124af979b6c8db Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 15 Feb 2013 18:55:41 +0100
+Subject: [PATCH 0136/1302] ARM: dts: Use generic DMA bindings for Exynos4 SPI
+ devices
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index 5a6bf05..d4c419a 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -392,8 +392,8 @@
+               compatible = "samsung,exynos4210-spi";
+               reg = <0x13920000 0x100>;
+               interrupts = <0 66 0>;
+-              tx-dma-channel = <&pdma0 7>; /* preliminary */
+-              rx-dma-channel = <&pdma0 6>; /* preliminary */
++              dmas = <&pdma0 7>, <&pdma0 6>;
++              dma-names = "tx", "rx";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&clock 327>, <&clock 159>;
+@@ -407,8 +407,8 @@
+               compatible = "samsung,exynos4210-spi";
+               reg = <0x13930000 0x100>;
+               interrupts = <0 67 0>;
+-              tx-dma-channel = <&pdma1 7>; /* preliminary */
+-              rx-dma-channel = <&pdma1 6>; /* preliminary */
++              dmas = <&pdma1 7>, <&pdma1 6>;
++              dma-names = "tx", "rx";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&clock 328>, <&clock 160>;
+@@ -422,8 +422,8 @@
+               compatible = "samsung,exynos4210-spi";
+               reg = <0x13940000 0x100>;
+               interrupts = <0 68 0>;
+-              tx-dma-channel = <&pdma0 9>; /* preliminary */
+-              rx-dma-channel = <&pdma0 8>; /* preliminary */
++              dmas = <&pdma0 9>, <&pdma0 8>;
++              dma-names = "tx", "rx";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&clock 329>, <&clock 161>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0137-ARM-dts-Add-I2S-device-nodes-for-Exynos4-SoCs.patch b/patches.tizen/0137-ARM-dts-Add-I2S-device-nodes-for-Exynos4-SoCs.patch
new file mode 100644 (file)
index 0000000..2967a3b
--- /dev/null
@@ -0,0 +1,62 @@
+From 1b575f6ba25e947217fd1187738fc5f8ce1136be Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 21 Feb 2013 15:23:39 +0100
+Subject: [PATCH 0137/1302] ARM: dts: Add I2S device nodes for Exynos4 SoCs
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi | 36 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 36 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index d4c419a..e22a075 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -450,6 +450,42 @@
+               status = "disabled";
+       };
++      i2s0: i2s@03830000 {
++              compatible = "samsung,i2s-v5";
++              reg = <0x03830000 0x100>;
++              clocks = <&clock_audss 0>, <&clock_audss 3>, <&clock_audss 1>,
++                      <&clock_audss 2>, <&clock_audss 4>, <&clock_audss 2>;
++              clock-names = "mout_audss", "mout_i2s", "dout_srp",
++                      "dout_bus", "dout_i2s", "i2s_opclk0";
++              dmas = <&pdma0 12>, <&pdma0 11>, <&pdma0 10>;
++              dma-names = "tx", "rx", "tx-sec";
++              samsung,supports-6ch;
++              samsung,supports-rstclr;
++              samsung,supports-secdai;
++              samsung,idma-addr = <0x03000000>;
++              status = "disabled";
++      };
++
++      i2s1: i2s@12D60000 {
++              compatible = "samsung,i2s-v5";
++              reg = <0x12D60000 0x100>;
++              clocks = <&clock 330>;
++              clock-names = "iis";
++              dmas = <&pdma1 12>, <&pdma1 11>;
++              dma-names = "tx", "rx";
++              status = "disabled";
++      };
++
++      i2s2: i2s@12D70000 {
++              compatible = "samsung,i2s-v5";
++              reg = <0x12D70000 0x100>;
++              clocks = <&clock 331>;
++              clock-names = "iis";
++              dmas = <&pdma0 14>, <&pdma0 13>;
++              dma-names = "tx", "rx";
++              status = "disabled";
++      };
++
+       amba {
+               #address-cells = <1>;
+               #size-cells = <1>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0138-clk-Add-Exynos-Audio-Subsystem-clocks-driver.patch b/patches.tizen/0138-clk-Add-Exynos-Audio-Subsystem-clocks-driver.patch
new file mode 100644 (file)
index 0000000..d07b783
--- /dev/null
@@ -0,0 +1,233 @@
+From c6cf52e8b00fa5205677342e1d9dc6d3c688c2ef Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 21 Feb 2013 21:23:42 +0100
+Subject: [PATCH 0138/1302] clk: Add Exynos Audio Subsystem clocks driver
+
+TODO: gate clocks.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../bindings/clock/exynos4-audss-clock.txt         |  57 ++++++++++
+ drivers/clk/samsung/Makefile                       |   1 +
+ drivers/clk/samsung/clk-exynos4-audss.c            | 118 +++++++++++++++++++++
+ drivers/clk/samsung/clk-exynos4.c                  |   4 -
+ 4 files changed, 176 insertions(+), 4 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/clock/exynos4-audss-clock.txt
+ create mode 100644 drivers/clk/samsung/clk-exynos4-audss.c
+
+diff --git a/Documentation/devicetree/bindings/clock/exynos4-audss-clock.txt b/Documentation/devicetree/bindings/clock/exynos4-audss-clock.txt
+new file mode 100644
+index 0000000..4126fab
+--- /dev/null
++++ b/Documentation/devicetree/bindings/clock/exynos4-audss-clock.txt
+@@ -0,0 +1,57 @@
++* Samsung Exynos4 Audio Subsystem Clock Controller
++
++The Exynos4 Audio Subsystem clock controller generates and supplies clocks
++to Audio Subsystem block available in the Exynos4 SoCs. The clock binding
++described here is applicable to all SoC's in the Exynos4 family.
++
++
++Required Properties:
++
++- comptible: should be one of the following.
++  - "samsung,exynos4-audss-clock" - controller compatible with all Exynos4 SoCs.
++
++- reg: physical base address of the controller and length of memory mapped
++  region.
++
++- #clock-cells: should be 1.
++
++The following is the list of clocks generated by the controller. Each clock is
++assigned an identifier and client nodes use this identifier to specify the
++clock which they consume. Some of the clocks are available only on a particular
++Exynos4 SoC and this is specified where applicable.
++
++
++Provided clocks:
++
++      Clock           ID      SoC (if specific)
++      -----------------------------------------------
++
++      mout_audss      0
++      dout_rp         1
++      dout_aud_bus    2
++      mout_i2s        3
++      dout_i2sclk0    4
++      clk_i2s0        5
++      clk_pcm0        6
++
++
++Example 1: An example of a clock controller node is listed below.
++
++      clock_audss: clock-controller@03810000 {
++              compatible = "samsung,exynos4-audss-clock";
++              reg = <0x03810000 0x0C>;
++              #clock-cells = <1>;
++      };
++
++Example 2: I2S controller node that consumes the clock generated by the clock
++         controller. Refer to the standard clock bindings for information
++         about 'clocks' and 'clock-names' property.
++
++      i2s0: i2s@03830000 {
++              compatible = "samsung,i2s-v5";
++              reg = <0x03830000 0x100>;
++              clocks = <&clock_audss 0>, <&clock_audss 3>, <&clock_audss 1>,
++                      <&clock_audss 2>, <&clock_audss 4>, <&clock_audss 2>;
++              clock-names = "mout_audss", "mout_i2s", "dout_srp",
++                      "dout_bus", "dout_i2s", "i2s_opclk0";
++      };
+diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
+index b7c232e..ec86c33 100644
+--- a/drivers/clk/samsung/Makefile
++++ b/drivers/clk/samsung/Makefile
+@@ -6,3 +6,4 @@ obj-$(CONFIG_COMMON_CLK)       += clk.o clk-pll.o
+ obj-$(CONFIG_ARCH_EXYNOS4)    += clk-exynos4.o
+ obj-$(CONFIG_SOC_EXYNOS5250)  += clk-exynos5250.o
+ obj-$(CONFIG_SOC_EXYNOS5440)  += clk-exynos5440.o
++obj-$(CONFIG_PLAT_SAMSUNG)    += clk-exynos4-audss.o
+diff --git a/drivers/clk/samsung/clk-exynos4-audss.c b/drivers/clk/samsung/clk-exynos4-audss.c
+new file mode 100644
+index 0000000..978c5de
+--- /dev/null
++++ b/drivers/clk/samsung/clk-exynos4-audss.c
+@@ -0,0 +1,118 @@
++/*
++ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
++ *
++ * 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.
++ *
++ * Driver for Exynos4 SoC Audio Subsystem clocks.
++*/
++#include <linux/kernel.h>
++#include <linux/clk.h>
++#include <linux/clkdev.h>
++#include <linux/clk-provider.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/syscore_ops.h>
++
++#include "clk.h"
++
++#define AUDSS_CLKSRC                  0x00
++#define AUDSS_CLKDIV                  0x04
++#define AUDSS_CLKGATE                 0x08
++
++/* IP Clock Gate 0 Registers */
++#define EXYNOS_AUDSS_CLKGATE_RP               (1 << 0)
++#define EXYNOS_AUDSS_CLKGATE_I2SBUS   (1 << 2)
++#define EXYNOS_AUDSS_CLKGATE_I2S_SPEC (1 << 3)
++#define EXYNOS_AUDSS_CLKGATE_PCMBUS   (1 << 4)
++#define EXYNOS_AUDSS_CLKGATE_PCM_SPEC (1 << 5)
++#define EXYNOS_AUDSS_CLKGATE_GPIO     (1 << 6)
++#define EXYNOS_AUDSS_CLKGATE_UART     (1 << 7)
++#define EXYNOS_AUDSS_CLKGATE_TIMER    (1 << 8)
++
++#define CLK_MOUT_AUDSS                        0
++#define CLK_DOUT_RP                   1
++#define CLK_DOUT_AUD_BUS              2
++#define CLK_MOUT_I2S                  3
++#define CLK_DOUT_I2SCLK0              4
++#define CLK_I2S0                      5
++#define CLK_PCM0                      6
++#define AUDSS_CLK_MAX                 7
++
++static const char *mux_audss_p[] __initconst = {
++      "xxti", "fout_epll"
++};
++static const char *mux_i2s_p[] __initconst = {
++      "mout_audss", "iiscdclk0", "sclk_audio0"
++};
++
++static struct clk_onecell_data clk_data;
++static void __iomem *io_base;
++static struct clk *clks[AUDSS_CLK_MAX];
++
++static int samsung_audss_clk_suspend(void)
++{
++      /* TODO: */
++      return 0;
++}
++
++static void samsung_audss_clk_resume(void)
++{
++      /* TODO: */
++}
++
++static struct syscore_ops samsung_audss_clk_syscore_ops = {
++      .suspend = samsung_audss_clk_suspend,
++      .resume  = samsung_audss_clk_resume,
++};
++
++
++#ifdef CONFIG_OF
++static struct of_device_id audss_of_match[] __initdata = {
++      { .compatible = "samsung,exynos4-audss-clock" },
++      { },
++};
++#endif
++
++static DEFINE_SPINLOCK(audss_clk_lock);
++
++static int samsung_audss_clk_init(void)
++{
++      struct device_node *node;
++
++      node = of_find_matching_node(NULL, audss_of_match);
++      if (!node)
++              return -ENODEV;
++
++      io_base = of_iomap(node, 0);
++      if (WARN_ON(!io_base))
++              return -ENOMEM;
++
++      clks[CLK_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss",
++              mux_audss_p, ARRAY_SIZE(mux_audss_p), CLK_SET_RATE_PARENT,
++              io_base + AUDSS_CLKSRC, 0, 1, 0, &audss_clk_lock);
++      clks[CLK_MOUT_I2S] = clk_register_mux(NULL, "mout_i2s0",
++              mux_i2s_p, ARRAY_SIZE(mux_i2s_p), CLK_SET_RATE_PARENT,
++              io_base + AUDSS_CLKSRC, 2, 2, 0, &audss_clk_lock);
++
++      clks[CLK_DOUT_RP] = clk_register_divider(NULL, "dout_rp",
++              "mout_audss", CLK_SET_RATE_PARENT, io_base + AUDSS_CLKDIV,
++              0, 4, 0, &audss_clk_lock);
++      clks[CLK_DOUT_AUD_BUS] = clk_register_divider(NULL, "dout_aud_bus",
++              "dout_rp", CLK_SET_RATE_PARENT, io_base + AUDSS_CLKDIV,
++              4, 4, 0, &audss_clk_lock);
++      clks[CLK_DOUT_I2SCLK0] = clk_register_divider(NULL, "dout_i2s0",
++              "mout_i2s0", CLK_SET_RATE_PARENT, io_base + AUDSS_CLKDIV,
++              8, 4, 0, &audss_clk_lock);
++
++      /* TODO: Add gate clocks */
++
++      clk_data.clks = clks;
++      clk_data.clk_num = ARRAY_SIZE(clks);
++      of_clk_add_provider(node, of_clk_src_onecell_get, &clk_data);
++
++      register_syscore_ops(&samsung_audss_clk_syscore_ops);
++      return 0;
++}
++postcore_initcall(samsung_audss_clk_init);
+diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
+index f2a338f..c68b207 100644
+--- a/drivers/clk/samsung/clk-exynos4.c
++++ b/drivers/clk/samsung/clk-exynos4.c
+@@ -856,10 +856,6 @@ struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = {
+                       E4X12_GATE_IP_ISP, 3, 0, 0),
+       GATE_A(wdt, "watchdog", "aclk100",
+                       E4X12_GATE_IP_PERIR, 14, 0, 0, "watchdog"),
+-      GATE_DA(pcm0, "samsung-pcm.0", "pcm0", "aclk100",
+-                      E4X12_GATE_IP_MAUDIO, 2, 0, 0, "pcm"),
+-      GATE_DA(i2s0, "samsung-i2s.0", "i2s0", "aclk100",
+-                      E4X12_GATE_IP_MAUDIO, 3, 0, 0, "iis"),
+       GATE(fimc_isp, "isp", "aclk200", E4X12_GATE_ISP0, 0,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(fimc_drc, "drc", "aclk200", E4X12_GATE_ISP0, 1,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0139-regulator-wm8994-Enable-device-tree-based-driver-mat.patch b/patches.tizen/0139-regulator-wm8994-Enable-device-tree-based-driver-mat.patch
new file mode 100644 (file)
index 0000000..6f1ad90
--- /dev/null
@@ -0,0 +1,37 @@
+From 5c32e280518b5364cf35824a8f7352ebaeb5c505 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 21 Feb 2013 15:54:19 +0100
+Subject: [PATCH 0139/1302] regulator: wm8994: Enable device tree based driver
+ matching
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/regulator/wm8994-regulator.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c
+index a612c35..dab41ae 100644
+--- a/drivers/regulator/wm8994-regulator.c
++++ b/drivers/regulator/wm8994-regulator.c
+@@ -192,10 +192,17 @@ static int wm8994_ldo_remove(struct platform_device *pdev)
+       return 0;
+ }
++static const struct of_device_id wm8994_ldo_of_match[] = {
++      { .compatible = "wlf,wm8994-ldo" },
++      { },
++};
++MODULE_DEVICE_TABLE(of, wm8994_ldo_of_match);
++
+ static struct platform_driver wm8994_ldo_driver = {
+       .probe = wm8994_ldo_probe,
+       .remove = wm8994_ldo_remove,
+       .driver         = {
++              .of_match_table = wm8994_ldo_of_match,
+               .name   = "wm8994-ldo",
+               .owner  = THIS_MODULE,
+       },
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0140-ARM-dts-Add-Exynos-Audio-Subsystem-clock-controller-.patch b/patches.tizen/0140-ARM-dts-Add-Exynos-Audio-Subsystem-clock-controller-.patch
new file mode 100644 (file)
index 0000000..730a6ba
--- /dev/null
@@ -0,0 +1,33 @@
+From c6f6ebe3f8d5700b03b474a8885ba4bff8ec6de7 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 21 Feb 2013 15:58:27 +0100
+Subject: [PATCH 0140/1302] ARM: dts: Add Exynos Audio Subsystem clock
+ controller node
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index e22a075..f32e414 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -49,6 +49,12 @@
+               reg = <0x10000000 0x100>;
+       };
++      clock_audss: clock-controller@03810000 {
++              compatible = "samsung,exynos4-audss-clock";
++              reg = <0x03810000 0x0C>;
++              #clock-cells = <1>;
++      };
++
+       pd_mfc: mfc-power-domain@10023C40 {
+               compatible = "samsung,exynos4210-pd";
+               reg = <0x10023C40 0x20>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0141-sound-samsung-i2s-Correct-I2S-clock-handling.patch b/patches.tizen/0141-sound-samsung-i2s-Correct-I2S-clock-handling.patch
new file mode 100644 (file)
index 0000000..5c0fb54
--- /dev/null
@@ -0,0 +1,249 @@
+From 8d6dbc6ec4ba17aa381fd1ece575dba7f0667de1 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 28 Feb 2013 18:48:54 +0100
+Subject: [PATCH 0141/1302] sound: samsung: i2s: Correct I2S clock handling
+
+Moving to Common Clock Framework introduced the need to configure clock
+hierarchy and rates in driver.
+
+This patch reworks clock handling in samsung-i2s driver to meet this
+requirement.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ sound/soc/samsung/i2s.c | 123 +++++++++++++++++++++++++++++++++++++++++-------
+ sound/soc/samsung/i2s.h |   1 +
+ 2 files changed, 107 insertions(+), 17 deletions(-)
+
+diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
+index 78472d2..e1d976e 100644
+--- a/sound/soc/samsung/i2s.c
++++ b/sound/soc/samsung/i2s.c
+@@ -34,6 +34,13 @@
+ #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
++#ifndef MHZ
++#define MHZ (1000*1000)
++#endif
++
++#define TARGET_SRPCLK_RATE    (200 * MHZ)
++#define TARGET_BUSCLK_RATE    (100 * MHZ)
++
+ enum samsung_dai_type {
+       TYPE_PRI,
+       TYPE_SEC,
+@@ -59,8 +66,16 @@ struct i2s_dai {
+        * 0 indicates CPU driver is free to choose any value.
+        */
+       unsigned rfs, bfs;
+-      /* I2S Controller's core clock */
+-      struct clk *clk;
++      /* Audss's source clock */
++      struct clk *mout_audss;
++      /* Audss's i2s source clock */
++      struct clk *mout_i2s;
++      /* SRP clock's divider */
++      struct clk *dout_srp;
++      /* Bus clock's divider */
++      struct clk *dout_bus;
++      /* i2s clock's divider */
++      struct clk *dout_i2s;
+       /* Clock for generating I2S signals */
+       struct clk *op_clk;
+       /* Pointer to the Primary_Fifo if this is Sec_Fifo, NULL otherwise */
+@@ -400,6 +415,10 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai,
+       u32 mod = readl(i2s->addr + I2SMOD);
+       switch (clk_id) {
++      case SAMSUNG_I2S_OPCLK:
++              mod &= ~MOD_OPCLK_MASK;
++              mod |= dir;
++              break;
+       case SAMSUNG_I2S_CDCLK:
+               /* Shouldn't matter in GATING(CLOCK_IN) mode */
+               if (dir == SND_SOC_CLOCK_IN)
+@@ -433,7 +452,7 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai,
+                       clk_id = 1;
+               if (!any_active(i2s)) {
+-                      if (i2s->op_clk) {
++                      if (!IS_ERR(i2s->op_clk)) {
+                               if ((clk_id && !(mod & MOD_IMS_SYSMUX)) ||
+                                       (!clk_id && (mod & MOD_IMS_SYSMUX))) {
+                                       clk_disable_unprepare(i2s->op_clk);
+@@ -451,6 +470,10 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai,
+                       else
+                               i2s->op_clk = clk_get(&i2s->pdev->dev,
+                                               "i2s_opclk0");
++
++                      if (!WARN_ON(IS_ERR(i2s->op_clk)))
++                              return -EINVAL;
++
+                       clk_prepare_enable(i2s->op_clk);
+                       i2s->rclk_srcrate = clk_get_rate(i2s->op_clk);
+@@ -849,6 +872,70 @@ i2s_delay(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
+       return delay;
+ }
++static int clk_set_hierarchy(struct i2s_dai *i2s)
++{
++      struct device *dev = &i2s->pdev->dev;
++      struct clk *fout_epll;
++      unsigned int ret;
++
++      fout_epll = devm_clk_get(dev, "fout_epll");
++      if (IS_ERR(fout_epll)) {
++              dev_err(dev, "failed to get fout_epll clock\n");
++              return PTR_ERR(fout_epll);
++      }
++
++      i2s->mout_audss = devm_clk_get(dev, "mout_audss");
++      if (IS_ERR(i2s->mout_audss)) {
++              dev_err(dev, "failed to get mout_audss clock\n");
++              return PTR_ERR(i2s->mout_audss);
++      }
++
++      i2s->mout_i2s = devm_clk_get(dev, "mout_i2s");
++      if (IS_ERR(i2s->mout_i2s)) {
++              dev_err(dev, "failed to get mout_i2s clock\n");
++              return PTR_ERR(i2s->mout_i2s);
++      }
++
++      i2s->dout_srp = devm_clk_get(dev, "dout_srp");
++      if (IS_ERR(i2s->dout_srp)) {
++              dev_err(dev, "failed to get dout_srp div\n");
++              return PTR_ERR(i2s->dout_srp);
++      }
++
++      i2s->dout_bus = devm_clk_get(dev, "dout_bus");
++      if (IS_ERR(i2s->dout_bus)) {
++              dev_err(dev, "failed to get dout_bus div\n");
++              return PTR_ERR(i2s->dout_bus);
++      }
++
++      i2s->dout_i2s = devm_clk_get(dev, "dout_i2s");
++      if (IS_ERR(i2s->dout_i2s)) {
++              dev_err(dev, "failed to get dout_i2s div\n");
++              return PTR_ERR(i2s->dout_i2s);
++      }
++
++      ret = clk_set_parent(i2s->mout_audss, fout_epll);
++      if (ret) {
++              dev_err(dev, "failed to set parent clock of mout_audss\n");
++              return ret;
++      }
++
++      ret = clk_set_parent(i2s->mout_i2s, i2s->mout_audss);
++      if (ret) {
++              dev_err(dev, "failed to set parent clock of mout_i2s\n");
++              return ret;
++      }
++
++      clk_set_rate(i2s->dout_srp, TARGET_SRPCLK_RATE);
++      clk_set_rate(i2s->dout_bus, TARGET_BUSCLK_RATE);
++
++      dev_dbg(dev, "EPLL rate = %ld\n", clk_get_rate(fout_epll));
++      dev_dbg(dev, "SRP rate = %ld\n", clk_get_rate(i2s->dout_srp));
++      dev_dbg(dev, "BUS rate = %ld\n", clk_get_rate(i2s->dout_bus));
++
++      return 0;
++}
++
+ #ifdef CONFIG_PM
+ static int i2s_suspend(struct snd_soc_dai *dai)
+ {
+@@ -884,8 +971,9 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
+ {
+       struct i2s_dai *i2s = to_info(dai);
+       struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
++      int ret;
+-      if (other && other->clk) /* If this is probe on secondary */
++      if (other && other->op_clk) /* If this is probe on secondary */
+               goto probe_exit;
+       i2s->addr = ioremap(i2s->base, 0x100);
+@@ -894,17 +982,16 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
+               return -ENXIO;
+       }
+-      i2s->clk = clk_get(&i2s->pdev->dev, "iis");
+-      if (IS_ERR(i2s->clk)) {
+-              dev_err(&i2s->pdev->dev, "failed to get i2s_clock\n");
+-              iounmap(i2s->addr);
+-              return -ENOENT;
++      /* Set clock hierarchy for audio subsystem */
++      ret = clk_set_hierarchy(i2s);
++      if (ret) {
++              dev_err(&i2s->pdev->dev, "failed to set clock hierachy.\n");
++              return ret;
+       }
+-      clk_prepare_enable(i2s->clk);
+       if (other) {
+               other->addr = i2s->addr;
+-              other->clk = i2s->clk;
++              other->op_clk = i2s->op_clk;
+       }
+       if (i2s->quirks & QUIRK_NEED_RSTCLR)
+@@ -937,18 +1024,20 @@ static int samsung_i2s_dai_remove(struct snd_soc_dai *dai)
+       struct i2s_dai *i2s = snd_soc_dai_get_drvdata(dai);
+       struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
+-      if (!other || !other->clk) {
++      if (!other || !other->op_clk) {
+               if (i2s->quirks & QUIRK_NEED_RSTCLR)
+                       writel(0, i2s->addr + I2SCON);
+-              clk_disable_unprepare(i2s->clk);
+-              clk_put(i2s->clk);
++              if (i2s->op_clk) {
++                      clk_disable_unprepare(i2s->op_clk);
++                      clk_put(i2s->op_clk);
++              }
+               iounmap(i2s->addr);
+       }
+-      i2s->clk = NULL;
++      i2s->op_clk = ERR_PTR(-EINVAL);
+       return 0;
+ }
+@@ -1084,7 +1173,7 @@ static int i2s_runtime_suspend(struct device *dev)
+ {
+       struct i2s_dai *i2s = dev_get_drvdata(dev);
+-      clk_disable_unprepare(i2s->clk);
++      clk_disable_unprepare(i2s->op_clk);
+       return 0;
+ }
+@@ -1093,7 +1182,7 @@ static int i2s_runtime_resume(struct device *dev)
+ {
+       struct i2s_dai *i2s = dev_get_drvdata(dev);
+-      clk_prepare_enable(i2s->clk);
++      clk_prepare_enable(i2s->op_clk);
+       return 0;
+ }
+diff --git a/sound/soc/samsung/i2s.h b/sound/soc/samsung/i2s.h
+index 7966afc..21ff24e 100644
+--- a/sound/soc/samsung/i2s.h
++++ b/sound/soc/samsung/i2s.h
+@@ -18,5 +18,6 @@
+ #define SAMSUNG_I2S_RCLKSRC_0 0
+ #define SAMSUNG_I2S_RCLKSRC_1 1
+ #define SAMSUNG_I2S_CDCLK             2
++#define SAMSUNG_I2S_OPCLK             3
+ #endif /* __SND_SOC_SAMSUNG_I2S_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0142-clk-samsung-exynos4-Add-support-for-CLKOUT.patch b/patches.tizen/0142-clk-samsung-exynos4-Add-support-for-CLKOUT.patch
new file mode 100644 (file)
index 0000000..cac48d8
--- /dev/null
@@ -0,0 +1,133 @@
+From 41dd64ba3e25b2f7b2be1a7dcac5d6a8a068c6c8 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 28 Feb 2013 18:53:27 +0100
+Subject: [PATCH 0142/1302] clk: samsung: exynos4: Add support for CLKOUT
+
+This patch adds the ability to control gating and muxing of CLKOUT
+signal through common clock routines.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/clock/exynos4-clock.txt    |  2 +
+ drivers/clk/samsung/clk-exynos4.c                  | 49 +++++++++++++++++++++-
+ 2 files changed, 49 insertions(+), 2 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/clock/exynos4-clock.txt b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
+index da82f71..9017baa 100644
+--- a/Documentation/devicetree/bindings/clock/exynos4-clock.txt
++++ b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
+@@ -46,6 +46,7 @@ Exynos4 SoC and this is specified where applicable.
+   mout_mpll_user_c    18      Exynos4x12
+   mout_core           19
+   mout_apll           20
++  clkout              21
+             [Clock Gate for Special Clocks]
+@@ -253,6 +254,7 @@ Exynos4 SoC and this is specified where applicable.
+   mout_g3d1           393
+   mout_g3d            394
+   aclk400_mcuisp      395     Exynos4x12
++  mout_clkout         396
+               [Div Clocks]
+diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
+index c68b207..c84247a 100644
+--- a/drivers/clk/samsung/clk-exynos4.c
++++ b/drivers/clk/samsung/clk-exynos4.c
+@@ -143,7 +143,7 @@ enum exynos4_clks {
+       xxti, xusbxti, fin_pll, fout_apll, fout_mpll, fout_epll, fout_vpll,
+       sclk_apll, sclk_mpll, sclk_epll, sclk_vpll, arm_clk, aclk200, aclk100,
+       aclk160, aclk133, mout_mpll_user_t, mout_mpll_user_c, mout_core,
+-      mout_apll, /* 20 */
++      mout_apll, clkout, /* 21 */
+       /* gate for special clocks (sclk) */
+       sclk_fimc0 = 128, sclk_fimc1, sclk_fimc2, sclk_fimc3, sclk_cam0,
+@@ -177,7 +177,7 @@ enum exynos4_clks {
+       /* mux clocks */
+       mout_fimc0 = 384, mout_fimc1, mout_fimc2, mout_fimc3, mout_cam0,
+       mout_cam1, mout_csis0, mout_csis1, mout_g3d0, mout_g3d1, mout_g3d,
+-      aclk400_mcuisp,
++      aclk400_mcuisp, mout_clkout,
+       /* div clocks */
+       div_isp0 = 450, div_isp1, div_mcuisp0, div_mcuisp1, div_aclk200,
+@@ -299,6 +299,8 @@ PNAME(mout_spdif_p)        = { "sclk_audio0", "sclk_audio1", "sclk_audio2",
+                               "spdif_extclk", };
+ PNAME(mout_onenand_p)  = {"aclk133", "aclk160", };
+ PNAME(mout_onenand1_p) = {"mout_onenand", "sclk_vpll", };
++PNAME(clkout_p)               = { "none", "none", "none", "none", "none", "none",
++                              "none", "none", "xxti", "xusbxti", };
+ /* Exynos 4210-specific parent groups */
+ PNAME(sclk_vpll_p4210)        = { "mout_vpllsrc", "fout_vpll", };
+@@ -910,6 +912,11 @@ struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = {
+                       CLK_IGNORE_UNUSED, 0),
+ };
++static struct of_device_id exynos4_clkout_ids[] __initdata = {
++      { .compatible = "samsung,exynos4210-clkout", },
++      { },
++};
++
+ /*
+  * The parent of the fin_pll clock is selected by the XOM[0] bit. This bit
+  * resides in chipid register space, outside of the clock controller memory
+@@ -982,6 +989,8 @@ static __initdata struct of_device_id ext_clk_match[] = {
+       {},
+ };
++static DEFINE_SPINLOCK(clkout_lock);
++
+ /* PLLs PMS values */
+ struct pll_pms pll35xx_exynos4412_pms[] = {
+       {.p = 4, .m = 250, .s = 0},
+@@ -1118,6 +1127,42 @@ void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc exynos4_so
+                       ARRAY_SIZE(exynos4x12_gate_clks));
+       }
++      np = of_find_matching_node(NULL, exynos4_clkout_ids);
++      if (np) {
++              void __iomem *clkout_base;
++              struct clk *clk;
++
++              clkout_base = of_iomap(np, 0);
++              if (!clkout_base) {
++                      pr_err("%s: failed to map clkout control register\n",
++                                                              __func__);
++                      goto clkout_fail;
++              }
++
++              clk = clk_register_mux(NULL, "mout_clkout", clkout_p,
++                                      ARRAY_SIZE(clkout_p), 0, clkout_base,
++                                      8, 4, 0, &clkout_lock);
++              if (IS_ERR(clk)) {
++                      pr_err("%s: failed to register clkout mux clock\n",
++                                                              __func__);
++                      goto clkout_fail;
++              }
++
++              samsung_clk_add_lookup(clk, mout_clkout);
++
++              clk = clk_register_gate(NULL, "clkout", "mout_clkout",
++                              0, clkout_base, 0, CLK_GATE_SET_TO_DISABLE,
++                              &clkout_lock);
++              if (IS_ERR(clk)) {
++                      pr_err("%s: failed to register clkout gate clock\n",
++                                                              __func__);
++                      goto clkout_fail;
++              }
++
++              samsung_clk_add_lookup(clk, clkout);
++      }
++
++clkout_fail:
+       pr_info("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n"
+               "\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk = %ld\n",
+               exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12",
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0143-ARM-dts-exynos4-Add-clkout-Device-Tree-node.patch b/patches.tizen/0143-ARM-dts-exynos4-Add-clkout-Device-Tree-node.patch
new file mode 100644 (file)
index 0000000..297bd6a
--- /dev/null
@@ -0,0 +1,33 @@
+From c35dc5424c5b25cf8b3d60ce2dcd86eca44959c9 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 28 Feb 2013 18:57:07 +0100
+Subject: [PATCH 0143/1302] ARM: dts: exynos4: Add clkout Device Tree node
+
+This patch adds device tree node for CLKOUT clock controller (part of
+Exynos 4 PMU block).
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index f32e414..2d2df61 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -49,6 +49,11 @@
+               reg = <0x10000000 0x100>;
+       };
++      clkout: clock-controller@10020A00 {
++              compatible = "samsung,exynos4210-clkout";
++              reg = <0x10020A00 0x4>;
++      };
++
+       clock_audss: clock-controller@03810000 {
+               compatible = "samsung,exynos4-audss-clock";
+               reg = <0x03810000 0x0C>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0144-sound-soc-codecs-Import-Yamaha-YMU823-MC1N2-codec-dr.patch b/patches.tizen/0144-sound-soc-codecs-Import-Yamaha-YMU823-MC1N2-codec-dr.patch
new file mode 100644 (file)
index 0000000..0e919c4
--- /dev/null
@@ -0,0 +1,53913 @@
+From 54a34eca28757e9d0de09cbbf574cbdc4bb747a1 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 28 Feb 2013 19:38:05 +0100
+Subject: [PATCH 0144/1302] sound: soc: codecs: Import Yamaha YMU823 (MC1N2)
+ codec driver
+
+This patch adds initial version of Yamaha YMU823 (MC1N2) codec driver
+ported for Linux 3.8 and Device Tree.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/mfd/mc1n2_pdata.h        |    29 +
+ include/uapi/sound/asound.h            |     1 +
+ sound/soc/codecs/Kconfig               |     2 +
+ sound/soc/codecs/Makefile              |     2 +
+ sound/soc/codecs/mc1n2/Kconfig         |    12 +
+ sound/soc/codecs/mc1n2/Makefile        |     4 +
+ sound/soc/codecs/mc1n2/mc1n2.c         |  4774 ++++++++
+ sound/soc/codecs/mc1n2/mc1n2.h         |   126 +
+ sound/soc/codecs/mc1n2/mc1n2_cfg.h     |  1199 ++
+ sound/soc/codecs/mc1n2/mc1n2_cfg_gsm.h |  1159 ++
+ sound/soc/codecs/mc1n2/mc1n2_cfg_lgt.h |  1199 ++
+ sound/soc/codecs/mc1n2/mc1n2_cfg_px.h  |  1199 ++
+ sound/soc/codecs/mc1n2/mc1n2_cfg_q1.h  |  1199 ++
+ sound/soc/codecs/mc1n2/mc1n2_dbg.c     |   439 +
+ sound/soc/codecs/mc1n2/mc1n2_priv.h    |   196 +
+ sound/soc/codecs/mc1n2/mcdebuglog.c    |  1771 +++
+ sound/soc/codecs/mc1n2/mcdebuglog.h    |    31 +
+ sound/soc/codecs/mc1n2/mcdefs.h        |  1160 ++
+ sound/soc/codecs/mc1n2/mcdevif.c       |   317 +
+ sound/soc/codecs/mc1n2/mcdevif.h       |    81 +
+ sound/soc/codecs/mc1n2/mcdevprof.c     |   131 +
+ sound/soc/codecs/mc1n2/mcdevprof.h     |    53 +
+ sound/soc/codecs/mc1n2/mcdriver.c      |  4047 +++++++
+ sound/soc/codecs/mc1n2/mcdriver.h      |   906 ++
+ sound/soc/codecs/mc1n2/mcdriver_AA.c   | 18276 +++++++++++++++++++++++++++++++
+ sound/soc/codecs/mc1n2/mcdriver_AA.h   |    25 +
+ sound/soc/codecs/mc1n2/mcmachdep.c     |   318 +
+ sound/soc/codecs/mc1n2/mcmachdep.h     |    34 +
+ sound/soc/codecs/mc1n2/mcpacking.c     |  4710 ++++++++
+ sound/soc/codecs/mc1n2/mcpacking.h     |    91 +
+ sound/soc/codecs/mc1n2/mcresctrl.c     |  9419 ++++++++++++++++
+ sound/soc/codecs/mc1n2/mcresctrl.h     |   263 +
+ sound/soc/codecs/mc1n2/mcservice.c     |   365 +
+ sound/soc/codecs/mc1n2/mcservice.h     |    34 +
+ sound/soc/codecs/mc1n2/mctypedef.h     |    38 +
+ 35 files changed, 53610 insertions(+)
+ create mode 100644 include/linux/mfd/mc1n2_pdata.h
+ create mode 100644 sound/soc/codecs/mc1n2/Kconfig
+ create mode 100644 sound/soc/codecs/mc1n2/Makefile
+ create mode 100644 sound/soc/codecs/mc1n2/mc1n2.c
+ create mode 100644 sound/soc/codecs/mc1n2/mc1n2.h
+ create mode 100644 sound/soc/codecs/mc1n2/mc1n2_cfg.h
+ create mode 100755 sound/soc/codecs/mc1n2/mc1n2_cfg_gsm.h
+ create mode 100644 sound/soc/codecs/mc1n2/mc1n2_cfg_lgt.h
+ create mode 100644 sound/soc/codecs/mc1n2/mc1n2_cfg_px.h
+ create mode 100644 sound/soc/codecs/mc1n2/mc1n2_cfg_q1.h
+ create mode 100644 sound/soc/codecs/mc1n2/mc1n2_dbg.c
+ create mode 100644 sound/soc/codecs/mc1n2/mc1n2_priv.h
+ create mode 100644 sound/soc/codecs/mc1n2/mcdebuglog.c
+ create mode 100644 sound/soc/codecs/mc1n2/mcdebuglog.h
+ create mode 100644 sound/soc/codecs/mc1n2/mcdefs.h
+ create mode 100644 sound/soc/codecs/mc1n2/mcdevif.c
+ create mode 100644 sound/soc/codecs/mc1n2/mcdevif.h
+ create mode 100644 sound/soc/codecs/mc1n2/mcdevprof.c
+ create mode 100644 sound/soc/codecs/mc1n2/mcdevprof.h
+ create mode 100644 sound/soc/codecs/mc1n2/mcdriver.c
+ create mode 100644 sound/soc/codecs/mc1n2/mcdriver.h
+ create mode 100644 sound/soc/codecs/mc1n2/mcdriver_AA.c
+ create mode 100644 sound/soc/codecs/mc1n2/mcdriver_AA.h
+ create mode 100644 sound/soc/codecs/mc1n2/mcmachdep.c
+ create mode 100644 sound/soc/codecs/mc1n2/mcmachdep.h
+ create mode 100644 sound/soc/codecs/mc1n2/mcpacking.c
+ create mode 100644 sound/soc/codecs/mc1n2/mcpacking.h
+ create mode 100644 sound/soc/codecs/mc1n2/mcresctrl.c
+ create mode 100644 sound/soc/codecs/mc1n2/mcresctrl.h
+ create mode 100644 sound/soc/codecs/mc1n2/mcservice.c
+ create mode 100644 sound/soc/codecs/mc1n2/mcservice.h
+ create mode 100644 sound/soc/codecs/mc1n2/mctypedef.h
+
+diff --git a/include/linux/mfd/mc1n2_pdata.h b/include/linux/mfd/mc1n2_pdata.h
+new file mode 100644
+index 0000000..474f6e1
+--- /dev/null
++++ b/include/linux/mfd/mc1n2_pdata.h
+@@ -0,0 +1,29 @@
++ /*
++  * Copyright (C) 2008 Samsung Electronics, Inc.
++  *
++  * This software is licensed under the terms of the GNU General Public
++  * License version 2, as published by the Free Software Foundation, and
++  * may be copied, distributed, and modified under those terms.
++  *
++  * This program is distributed in the hope that it will be useful,
++  * but WITHOUT ANY WARRANTY; without even the implied warranty of
++  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++  * GNU General Public License for more details.
++  *
++  */
++
++#ifndef __S5PC210_MC1N2_H
++#define __S5PC210_MC1N2_H
++
++enum mic_type {
++      MAIN_MIC = 0x1,
++      SUB_MIC  = 0x2,
++};
++
++struct mc1n2_platform_data {
++      void (*set_main_mic_bias)(struct device *dev, bool on);
++      void (*set_sub_mic_bias)(struct device *dev, bool on);
++      int (*set_adc_power_constraints)(struct device *dev, int disabled);
++};
++
++#endif
+diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h
+index e3983d5..d2fc951 100644
+--- a/include/uapi/sound/asound.h
++++ b/include/uapi/sound/asound.h
+@@ -93,6 +93,7 @@ enum {
+       SNDRV_HWDEP_IFACE_SB_RC,        /* SB Extigy/Audigy2NX remote control */
+       SNDRV_HWDEP_IFACE_HDA,          /* HD-audio */
+       SNDRV_HWDEP_IFACE_USB_STREAM,   /* direct access to usb stream */
++      SNDRV_HWDEP_IFACE_MC1N2,        /* FIXME */
+       /* Don't forget to change the following: */
+       SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_USB_STREAM
+diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
+index 2f45f00..576065f 100644
+--- a/sound/soc/codecs/Kconfig
++++ b/sound/soc/codecs/Kconfig
+@@ -525,3 +525,5 @@ config SND_SOC_ML26124
+ config SND_SOC_TPA6130A2
+       tristate
++
++source "sound/soc/codecs/mc1n2/Kconfig"
+diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
+index b9e41c9..bcbd4a5 100644
+--- a/sound/soc/codecs/Makefile
++++ b/sound/soc/codecs/Makefile
+@@ -246,3 +246,5 @@ obj-$(CONFIG_SND_SOC_WM_HUBS)      += snd-soc-wm-hubs.o
+ # Amp
+ obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
+ obj-$(CONFIG_SND_SOC_TPA6130A2)       += snd-soc-tpa6130a2.o
++
++obj-$(CONFIG_SND_SOC)         += mc1n2/
+diff --git a/sound/soc/codecs/mc1n2/Kconfig b/sound/soc/codecs/mc1n2/Kconfig
+new file mode 100644
+index 0000000..2b521c1
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/Kconfig
+@@ -0,0 +1,12 @@
++config SND_SOC_MC1N2
++      tristate
++      depends on SND_SOC && I2C
++      select SND_HWDEP
++
++config SND_SOC_USE_EXTERNAL_MIC_BIAS
++      bool "Use External Mic Bias"
++
++config SND_SOC_MC1N2_DEBUG
++      bool "MC-1N2 verbose debug messages while core driver call"
++      select SND_DEBUG
++      depends on SND_SOC_MC1N2
+diff --git a/sound/soc/codecs/mc1n2/Makefile b/sound/soc/codecs/mc1n2/Makefile
+new file mode 100644
+index 0000000..9c6b1c0
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/Makefile
+@@ -0,0 +1,4 @@
++snd-soc-mc1n2-objs := mc1n2.o mc1n2_dbg.o \
++      mcdevif.o mcdevprof.o mcdriver.o mcmachdep.o mcpacking.o mcresctrl.o mcservice.o mcdebuglog.o mcdriver_AA.o
++
++obj-$(CONFIG_SND_SOC_MC1N2) += snd-soc-mc1n2.o
+diff --git a/sound/soc/codecs/mc1n2/mc1n2.c b/sound/soc/codecs/mc1n2/mc1n2.c
+new file mode 100644
+index 0000000..9f56575
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mc1n2.c
+@@ -0,0 +1,4774 @@
++/*
++ * MC-1N2 ASoC codec driver
++ *
++ * Copyright (c) 2010-2011 Yamaha Corporation
++ *
++ * This software is provided 'as-is', without any express or implied
++ * warranty.  In no event will the authors be held liable for any damages
++ * arising from the use of this software.
++ *
++ * Permission is granted to anyone to use this software for any purpose,
++ * including commercial applications, and to alter it and redistribute it
++ * freely, subject to the following restrictions:
++ *
++ * 1. The origin of this software must not be misrepresented; you must not
++ *    claim that you wrote the original software. If you use this software
++ *    in a product, an acknowledgment in the product documentation would be
++ *    appreciated but is not required.
++ * 2. Altered source versions must be plainly marked as such, and must not be
++ *    misrepresented as being the original software.
++ * 3. This notice may not be removed or altered from any source distribution.
++ */
++
++#include <linux/delay.h>
++#include <linux/errno.h>
++#include <linux/slab.h>
++#include <linux/gpio.h>
++#include <linux/regulator/consumer.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/mutex.h>
++#include <linux/of.h>
++#include <linux/of_gpio.h>
++#include <linux/types.h>
++#ifdef CONFIG_SND_SOC_PM_RUNTIME
++#include <linux/pm_runtime.h>
++#endif
++#include <sound/hwdep.h>
++#include <sound/initval.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++#include <sound/tlv.h>
++#include "mc1n2.h"
++#include "mc1n2_priv.h"
++
++#include <plat/gpio-cfg.h>
++#include <mach/gpio.h>
++
++#ifdef CONFIG_TARGET_LOCALE_NAATT_TEMP
++/* CONFIG_TARGET_LOCALE_NAATT_TEMP is intentionally introduced temporarily*/
++
++#include "mc1n2_cfg_gsm.h"
++#elif defined(CONFIG_MACH_Q1_BD)
++#include "mc1n2_cfg_q1.h"
++#elif defined(CONFIG_MACH_U1_KOR_LGT)
++#include "mc1n2_cfg_lgt.h"
++#elif defined(CONFIG_MACH_PX)
++#include "mc1n2_cfg_px.h"
++#else
++#include "mc1n2_cfg.h"
++#endif
++
++extern int mc1n2_set_mclk_source(bool on);
++static int audio_ctrl_mic_bias_gpio(struct mc1n2_platform_data *pdata, int mic, bool on);
++
++#define MC1N2_DRIVER_VERSION "1.0.4"
++
++#define MC1N2_NAME "mc1n2"
++
++#define MC1N2_I2S_RATE (SNDRV_PCM_RATE_8000_48000)
++#define MC1N2_I2S_FORMATS \
++      (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
++       SNDRV_PCM_FMTBIT_S24_3LE)
++
++#define MC1N2_PCM_RATE (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000)
++#define MC1N2_PCM_FORMATS \
++      (SNDRV_PCM_FMTBIT_S8 | \
++       SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
++       SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_MU_LAW)
++
++#define MC1N2_HWDEP_ID "mc1n2"
++
++#define MC1N2_HW_ID_AA 0x78
++#define MC1N2_HW_ID_AB 0x79
++
++#define MC1N2_WAITTIME_MICIN  100
++
++#ifdef ALSA_VER_ANDROID_3_0
++static struct i2c_client *mc1n2_i2c;
++#endif
++
++/*
++ * Driver private data structure
++ */
++static UINT8 mc1n2_hwid;
++
++static size_t mc1n2_path_channel_tbl[] = {
++      offsetof(MCDRV_PATH_INFO, asDit0[0]),
++      offsetof(MCDRV_PATH_INFO, asDit1[0]),
++      offsetof(MCDRV_PATH_INFO, asDit2[0]),
++      offsetof(MCDRV_PATH_INFO, asHpOut[0]),
++      offsetof(MCDRV_PATH_INFO, asHpOut[1]),
++      offsetof(MCDRV_PATH_INFO, asSpOut[0]),
++      offsetof(MCDRV_PATH_INFO, asSpOut[1]),
++      offsetof(MCDRV_PATH_INFO, asRcOut[0]),
++      offsetof(MCDRV_PATH_INFO, asLout1[0]),
++      offsetof(MCDRV_PATH_INFO, asLout1[1]),
++      offsetof(MCDRV_PATH_INFO, asLout2[0]),
++      offsetof(MCDRV_PATH_INFO, asLout2[1]),
++      offsetof(MCDRV_PATH_INFO, asDac[0]),
++      offsetof(MCDRV_PATH_INFO, asDac[1]),
++      offsetof(MCDRV_PATH_INFO, asAe[0]),
++      offsetof(MCDRV_PATH_INFO, asAdc0[0]),
++      offsetof(MCDRV_PATH_INFO, asAdc0[1]),
++      offsetof(MCDRV_PATH_INFO, asMix[0]),
++      offsetof(MCDRV_PATH_INFO, asBias[0]),
++};
++#define MC1N2_N_PATH_CHANNELS (sizeof(mc1n2_path_channel_tbl) / sizeof(size_t))
++
++struct mc1n2_port_params {
++      UINT8 rate;
++      UINT8 bits[SNDRV_PCM_STREAM_LAST+1];
++      UINT8 pcm_mono[SNDRV_PCM_STREAM_LAST+1];
++      UINT8 pcm_order[SNDRV_PCM_STREAM_LAST+1];
++      UINT8 pcm_law[SNDRV_PCM_STREAM_LAST+1];
++      UINT8 master;
++      UINT8 inv;
++      UINT8 format;
++      UINT8 bckfs;
++      UINT8 pcm_clkdown;
++      UINT8 channels;
++      UINT8 stream;                     /* bit0: Playback, bit1: Capture */
++      UINT8 dir[MC1N2_N_PATH_CHANNELS]; /* path settings for DIR */
++      MCDRV_CHANNEL dit;                /* path settings for DIT */
++};
++
++struct mc1n2_data {
++      struct mutex mutex;
++      struct mc1n2_setup setup;
++      struct mc1n2_port_params port[IOPORT_NUM];
++      struct snd_hwdep *hwdep;
++      struct mc1n2_platform_data *pdata;
++      int clk_update;
++      MCDRV_PATH_INFO path_store;
++      MCDRV_VOL_INFO vol_store;
++      MCDRV_DIO_INFO dio_store;
++      MCDRV_DAC_INFO dac_store;
++      MCDRV_ADC_INFO adc_store;
++      MCDRV_SP_INFO sp_store;
++      MCDRV_DNG_INFO dng_store;
++      MCDRV_SYSEQ_INFO syseq_store;
++      MCDRV_AE_INFO ae_store;
++      MCDRV_PDM_INFO pdm_store;
++      UINT32 hdmicount;
++      UINT32 delay_mic1in;
++      UINT32 lineoutenable;
++#ifdef CONFIG_SND_SOC_PM_RUNTIME
++      int suspended;
++#endif
++      struct regulator *regulator;
++      int gpio_main_mic_bias;
++      int gpio_sub_mic_bias;
++};
++
++struct mc1n2_info_store {
++      UINT32 get;
++      UINT32 set;
++      size_t offset;
++      UINT32 flags;
++};
++
++struct mc1n2_info_store mc1n2_info_store_tbl[] = {
++      {MCDRV_GET_DIGITALIO, MCDRV_SET_DIGITALIO,
++       offsetof(struct mc1n2_data, dio_store), 0x1ff},
++      {MCDRV_GET_DAC, MCDRV_SET_DAC,
++       offsetof(struct mc1n2_data, dac_store), 0x7},
++      {MCDRV_GET_ADC, MCDRV_SET_ADC,
++       offsetof(struct mc1n2_data, adc_store), 0x7},
++      {MCDRV_GET_SP, MCDRV_SET_SP,
++       offsetof(struct mc1n2_data, sp_store), 0},
++      {MCDRV_GET_DNG, MCDRV_SET_DNG,
++       offsetof(struct mc1n2_data, dng_store), 0x3f3f3f},
++      {MCDRV_GET_SYSEQ, MCDRV_SET_SYSEQ,
++       offsetof(struct mc1n2_data, syseq_store), 0x3},
++      {0, MCDRV_SET_AUDIOENGINE,
++       offsetof(struct mc1n2_data, ae_store), 0x1ff},
++      {MCDRV_GET_PDM, MCDRV_SET_PDM,
++       offsetof(struct mc1n2_data, pdm_store), 0x7f},
++      {MCDRV_GET_PATH, MCDRV_SET_PATH,
++       offsetof(struct mc1n2_data, path_store), 0},
++      {MCDRV_GET_VOLUME, MCDRV_SET_VOLUME,
++       offsetof(struct mc1n2_data, vol_store), 0},
++};
++#define MC1N2_N_INFO_STORE (sizeof(mc1n2_info_store_tbl) / sizeof(struct mc1n2_info_store))
++
++#define mc1n2_is_in_playback(p) ((p)->stream & (1 << SNDRV_PCM_STREAM_PLAYBACK))
++#define mc1n2_is_in_capture(p)  ((p)->stream & (1 << SNDRV_PCM_STREAM_CAPTURE))
++#define get_port_id(id) (id-1)
++
++static int mc1n2_current_mode;
++
++#ifdef CONFIG_SND_SOC_PM_RUNTIME
++#define MC1N2_PM_RUNTIME_DELAY_MS 500
++#endif
++#if !defined(ALSA_VER_ANDROID_3_0) || defined(CONFIG_SND_SOC_PM_RUNTIME)
++static struct snd_soc_codec *mc1n2_codec;
++#endif
++
++#if !defined(ALSA_VER_ANDROID_3_0) || defined(CONFIG_SND_SOC_PM_RUNTIME)
++static struct snd_soc_codec *mc1n2_get_codec_data(void)
++{
++      return mc1n2_codec;
++}
++
++static void mc1n2_set_codec_data(struct snd_soc_codec *codec)
++{
++      mc1n2_codec = codec;
++}
++#endif
++
++/* deliver i2c access to machdep */
++struct i2c_client *mc1n2_get_i2c_client(void)
++{
++#ifdef ALSA_VER_ANDROID_3_0
++      return mc1n2_i2c;
++#else
++      return mc1n2_codec->control_data;
++#endif
++}
++
++static int audio_ctrl_mic_bias_gpio(struct mc1n2_platform_data *pdata, int mic, bool on)
++{
++      if (!pdata) {
++              pr_err("failed to control mic bias\n");
++              return -EINVAL;
++      }
++
++      if ((mic & MAIN_MIC) && (pdata->set_main_mic_bias != NULL))
++              pdata->set_main_mic_bias(&mc1n2_i2c->dev, on);
++
++      if ((mic & SUB_MIC) && (pdata->set_sub_mic_bias != NULL))
++              pdata->set_sub_mic_bias(&mc1n2_i2c->dev, on);
++
++      return 0;
++}
++
++/*
++ * DAI (PCM interface)
++ */
++/* SRC_RATE settings @ 73728000Hz (ideal PLL output) */
++static int mc1n2_src_rate[][SNDRV_PCM_STREAM_LAST+1] = {
++      /* DIR, DIT */
++      {32768, 4096},                  /* MCDRV_FS_48000 */
++      {30106, 4458},                  /* MCDRV_FS_44100 */
++      {21845, 6144},                  /* MCDRV_FS_32000 */
++      {0, 0},                         /* N/A */
++      {0, 0},                         /* N/A */
++      {15053, 8916},                  /* MCDRV_FS_22050 */
++      {10923, 12288},                 /* MCDRV_FS_16000 */
++      {0, 0},                         /* N/A */
++      {0, 0},                         /* N/A */
++      {7526, 17833},                  /* MCDRV_FS_11025 */
++      {5461, 24576},                  /* MCDRV_FS_8000 */
++};
++
++#define mc1n2_fs_to_srcrate(rate,dir) mc1n2_src_rate[(rate)][(dir)];
++
++static int mc1n2_setup_dai(struct mc1n2_data *mc1n2, int id, int mode, int dir)
++{
++      MCDRV_DIO_INFO dio;
++      MCDRV_DIO_PORT *port = &dio.asPortInfo[id];
++      struct mc1n2_setup *setup = &mc1n2->setup;
++      struct mc1n2_port_params *par = &mc1n2->port[id];
++      UINT32 update = 0;
++      int i;
++
++      memset(&dio, 0, sizeof(MCDRV_DIO_INFO));
++
++      if (par->stream == 0) {
++              port->sDioCommon.bMasterSlave = par->master;
++              port->sDioCommon.bAutoFs = MCDRV_AUTOFS_OFF;
++              port->sDioCommon.bFs = par->rate;
++              port->sDioCommon.bBckFs = par->bckfs;
++              port->sDioCommon.bInterface = mode;
++              port->sDioCommon.bBckInvert = par->inv;
++              if (mode == MCDRV_DIO_PCM) {
++                      port->sDioCommon.bPcmHizTim = setup->pcm_hiz_redge[id];
++                      port->sDioCommon.bPcmClkDown = par->pcm_clkdown;
++                      port->sDioCommon.bPcmFrame = par->format;
++                      port->sDioCommon.bPcmHighPeriod = setup->pcm_hperiod[id];
++              }
++              update |= MCDRV_DIO0_COM_UPDATE_FLAG;
++      }
++
++      if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
++              port->sDir.wSrcRate = mc1n2_fs_to_srcrate(par->rate, dir);
++              if (mode == MCDRV_DIO_DA) {
++                      port->sDir.sDaFormat.bBitSel = par->bits[dir];
++                      port->sDir.sDaFormat.bMode = par->format;
++              } else {
++                      port->sDir.sPcmFormat.bMono = par->pcm_mono[dir];
++                      port->sDir.sPcmFormat.bOrder = par->pcm_order[dir];
++                      if (setup->pcm_extend[id]) {
++                              port->sDir.sPcmFormat.bOrder |=
++                                      (1 << setup->pcm_extend[id]);
++                      }
++                      port->sDir.sPcmFormat.bLaw = par->pcm_law[dir];
++                      port->sDir.sPcmFormat.bBitSel = par->bits[dir];
++              }
++              for (i = 0; i < DIO_CHANNELS; i++) {
++                      if (i && par->channels == 1) {
++                              port->sDir.abSlot[i] = port->sDir.abSlot[i-1];
++                      } else {
++                              port->sDir.abSlot[i] = setup->slot[id][dir][i];
++                      }
++
++              }
++              update |= MCDRV_DIO0_DIR_UPDATE_FLAG;
++      }
++
++      if (dir == SNDRV_PCM_STREAM_CAPTURE) {
++              port->sDit.wSrcRate = mc1n2_fs_to_srcrate(par->rate, dir);
++              if (mode == MCDRV_DIO_DA) {
++                      port->sDit.sDaFormat.bBitSel = par->bits[dir];
++                      port->sDit.sDaFormat.bMode = par->format;
++              } else {
++                      port->sDit.sPcmFormat.bMono = par->pcm_mono[dir];
++                      port->sDit.sPcmFormat.bOrder = par->pcm_order[dir];
++                      if (setup->pcm_extend[id]) {
++                              port->sDit.sPcmFormat.bOrder |=
++                                      (1 << setup->pcm_extend[id]);
++                      }
++                      port->sDit.sPcmFormat.bLaw = par->pcm_law[dir];
++                      port->sDit.sPcmFormat.bBitSel = par->bits[dir];
++              }
++              for (i = 0; i < DIO_CHANNELS; i++) {
++                      port->sDit.abSlot[i] = setup->slot[id][dir][i];
++              }
++              update |= MCDRV_DIO0_DIT_UPDATE_FLAG;
++      }
++
++      return _McDrv_Ctrl(MCDRV_SET_DIGITALIO, &dio, update << (id*3));
++}
++
++static int mc1n2_control_dir(struct mc1n2_data *mc1n2, int id, int enable)
++{
++      MCDRV_PATH_INFO info;
++      MCDRV_CHANNEL *ch;
++      int activate;
++      int i;
++
++      memset(&info, 0, sizeof(MCDRV_PATH_INFO));
++
++      for (i = 0; i < MC1N2_N_PATH_CHANNELS; i++) {
++              ch = (MCDRV_CHANNEL *)((void *)&info + mc1n2_path_channel_tbl[i]);
++
++              switch (i) {
++              case 0:
++#ifdef DIO0_DAI_ENABLE
++                      activate = enable && mc1n2_is_in_capture(&mc1n2->port[0]);
++#else
++                      activate = enable;
++#endif
++                      break;
++
++              case 1:
++#ifdef DIO1_DAI_ENABLE
++                      activate = enable && mc1n2_is_in_capture(&mc1n2->port[1]);
++#else
++                      activate = enable;
++#endif
++                      break;
++              case 2:
++#ifdef DIO2_DAI_ENABLE
++                      activate = enable && mc1n2_is_in_capture(&mc1n2->port[2]);
++#else
++                      activate = enable;
++#endif
++                      break;
++              default:
++                      activate = enable;
++                      break;
++              }
++
++              if (mc1n2->port[id].dir[i]) {
++                      ch->abSrcOnOff[3] = 0x1 << (id * 2 + !activate);
++              }
++      }
++
++      return _McDrv_Ctrl(MCDRV_SET_PATH, &info, 0);
++}
++
++static int mc1n2_control_dit(struct mc1n2_data *mc1n2, int id, int enable)
++{
++      MCDRV_PATH_INFO info;
++      MCDRV_CHANNEL *ch = info.asDit0 + id;
++      int stream;
++      int i;
++
++      memset(&info, 0, sizeof(MCDRV_PATH_INFO));
++
++      for (i = 0; i < SOURCE_BLOCK_NUM; i++) {
++              if (i == 3) {
++                      stream = 0;
++
++#ifdef DIO0_DAI_ENABLE
++                      stream |= mc1n2_is_in_playback(&mc1n2->port[0]);
++#endif
++#ifdef DIO1_DAI_ENABLE
++                      stream |= mc1n2_is_in_playback(&mc1n2->port[1]) << 2;
++#endif
++#ifdef DIO2_DAI_ENABLE
++                      stream |= mc1n2_is_in_playback(&mc1n2->port[2]) << 4;
++#endif
++
++                      ch->abSrcOnOff[3] = (stream & mc1n2->port[id].dit.abSrcOnOff[3]) << !enable;
++              } else {
++                      ch->abSrcOnOff[i] = mc1n2->port[id].dit.abSrcOnOff[i] << !enable;
++              }
++      }
++
++      return _McDrv_Ctrl(MCDRV_SET_PATH, &info, 0);
++}
++
++static int mc1n2_update_clock(struct mc1n2_data *mc1n2)
++{
++      MCDRV_CLOCK_INFO info;
++
++      memset(&info, 0, sizeof(MCDRV_CLOCK_INFO));
++      info.bCkSel = mc1n2->setup.init.bCkSel;
++      info.bDivR0 = mc1n2->setup.init.bDivR0;
++      info.bDivF0 = mc1n2->setup.init.bDivF0;
++      info.bDivR1 = mc1n2->setup.init.bDivR1;
++      info.bDivF1 = mc1n2->setup.init.bDivF1;
++
++      return _McDrv_Ctrl(MCDRV_UPDATE_CLOCK, &info, 0);
++}
++
++static int mc1n2_set_clkdiv_common(struct mc1n2_data *mc1n2, int div_id, int div)
++{
++      struct mc1n2_setup *setup = &mc1n2->setup;
++
++      switch (div_id) {
++      case MC1N2_CKSEL:
++              switch (div) {
++              case 0:
++                      setup->init.bCkSel = MCDRV_CKSEL_CMOS;
++                      break;
++              case 1:
++                      setup->init.bCkSel = MCDRV_CKSEL_TCXO;
++                      break;
++              case 2:
++                      setup->init.bCkSel = MCDRV_CKSEL_CMOS_TCXO;
++                      break;
++              case 3:
++                      setup->init.bCkSel = MCDRV_CKSEL_TCXO_CMOS;
++                      break;
++              default:
++                      return -EINVAL;
++              }
++              break;
++      case MC1N2_DIVR0:
++              if ((div < 1) || (div > 127)) {
++                      return -EINVAL;
++              }
++              setup->init.bDivR0 = div;
++              break;
++      case MC1N2_DIVF0:
++              if ((div < 1) || (div > 255)) {
++                      return -EINVAL;
++              }
++              setup->init.bDivF0 = div;
++              break;
++      case MC1N2_DIVR1:
++              if ((div < 1) || (div > 127)) {
++                      return -EINVAL;
++              }
++              setup->init.bDivR1 = div;
++              break;
++      case MC1N2_DIVF1:
++              if ((div < 1) || (div > 255)) {
++                      return -EINVAL;
++              }
++              setup->init.bDivF1 = div;
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      mc1n2->clk_update = 1;
++
++      return 0;
++}
++
++static int mc1n2_set_fmt_common(struct mc1n2_port_params *port, unsigned int fmt)
++{
++      /* master */
++      switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++      case SND_SOC_DAIFMT_CBM_CFM:
++              port->master = MCDRV_DIO_MASTER;
++              break;
++      case SND_SOC_DAIFMT_CBS_CFS:
++              port->master = MCDRV_DIO_SLAVE;
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      /* inv */
++      switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
++      case SND_SOC_DAIFMT_NB_NF:
++              port->inv = MCDRV_BCLK_NORMAL;
++              break;
++      case SND_SOC_DAIFMT_IB_NF:
++              port->inv = MCDRV_BCLK_INVERT;
++              break;
++      default:
++              return -EINVAL;
++      }
++
++#ifdef ALSA_VER_1_0_19
++      /* clock */
++      switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) {
++      case SND_SOC_DAIFMT_SYNC:
++              /* just validating */
++              break;
++      default:
++              return -EINVAL;
++      }
++#endif
++
++      return 0;
++}
++
++static int mc1n2_i2s_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div)
++{
++      struct snd_soc_codec *codec = dai->codec;
++#if (defined ALSA_VER_ANDROID_2_6_35) || (defined ALSA_VER_ANDROID_3_0)
++      struct mc1n2_data *mc1n2 = snd_soc_codec_get_drvdata(codec);
++#else
++      struct mc1n2_data *mc1n2 = codec->private_data;
++#endif
++      struct mc1n2_port_params *port = &mc1n2->port[get_port_id(dai->id)];
++
++      switch (div_id) {
++      case MC1N2_BCLK_MULT:
++              switch (div) {
++              case MC1N2_LRCK_X32:
++                      port->bckfs = MCDRV_BCKFS_32;
++                      break;
++              case MC1N2_LRCK_X48:
++                      port->bckfs = MCDRV_BCKFS_48;
++                      break;
++              case MC1N2_LRCK_X64:
++                      port->bckfs = MCDRV_BCKFS_64;
++                      break;
++              default:
++                      return -EINVAL;
++              }
++              break;
++      default:
++              return mc1n2_set_clkdiv_common(mc1n2, div_id, div);
++      }
++
++      return 0;
++}
++
++static int mc1n2_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
++{
++      struct snd_soc_codec *codec = dai->codec;
++#if (defined ALSA_VER_ANDROID_2_6_35) || (defined ALSA_VER_ANDROID_3_0)
++      struct mc1n2_data *mc1n2 = snd_soc_codec_get_drvdata(codec);
++#else
++      struct mc1n2_data *mc1n2 = codec->private_data;
++#endif
++      struct mc1n2_port_params *port = &mc1n2->port[get_port_id(dai->id)];
++
++      /* format */
++      switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++      case SND_SOC_DAIFMT_I2S:
++              port->format = MCDRV_DAMODE_I2S;
++              break;
++      case SND_SOC_DAIFMT_RIGHT_J:
++              port->format = MCDRV_DAMODE_TAILALIGN;
++              break;
++      case SND_SOC_DAIFMT_LEFT_J:
++              port->format = MCDRV_DAMODE_HEADALIGN;
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      return mc1n2_set_fmt_common(port, fmt);
++}
++
++static int mc1n2_i2s_hw_params(struct snd_pcm_substream *substream,
++                             struct snd_pcm_hw_params *params,
++                             struct snd_soc_dai *dai)
++{
++#ifdef ALSA_VER_ANDROID_3_0
++      struct snd_soc_codec *codec = dai->codec;
++#else
++      struct snd_soc_pcm_runtime *runtime = snd_pcm_substream_chip(substream);
++#ifdef ALSA_VER_1_0_19
++      struct snd_soc_codec *codec = runtime->socdev->codec;
++#else
++      struct snd_soc_codec *codec = runtime->socdev->card->codec;
++#endif
++#endif
++#if (defined ALSA_VER_ANDROID_2_6_35) || (defined ALSA_VER_ANDROID_3_0)
++      struct mc1n2_data *mc1n2 = snd_soc_codec_get_drvdata(codec);
++#else
++      struct mc1n2_data *mc1n2 = codec->private_data;
++#endif
++      struct mc1n2_port_params *port = &mc1n2->port[get_port_id(dai->id)];
++      int dir = substream->stream;
++      int rate;
++      int err = 0;
++
++      dbg_info("hw_params: [%d] name=%s, dir=%d, rate=%d, bits=%d, ch=%d\n",
++               get_port_id(dai->id), substream->name, dir,
++               params_rate(params), params_format(params), params_channels(params));
++
++      /* format (bits) */
++      switch (params_format(params)) {
++      case SNDRV_PCM_FORMAT_S16_LE:
++              port->bits[dir] = MCDRV_BITSEL_16;
++              break;
++      case SNDRV_PCM_FORMAT_S20_3LE:
++              port->bits[dir] = MCDRV_BITSEL_20;
++              break;
++      case SNDRV_PCM_FORMAT_S24_3LE:
++              port->bits[dir] = MCDRV_BITSEL_24;
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      /* rate */
++      switch (params_rate(params)) {
++      case 8000:
++              rate = MCDRV_FS_8000;
++              break;
++      case 11025:
++              rate = MCDRV_FS_11025;
++              break;
++      case 16000:
++              rate = MCDRV_FS_16000;
++              break;
++      case 22050:
++              rate = MCDRV_FS_22050;
++              break;
++      case 32000:
++              rate = MCDRV_FS_32000;
++              break;
++      case 44100:
++              rate = MCDRV_FS_44100;
++              break;
++      case 48000:
++              rate = MCDRV_FS_48000;
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      mutex_lock(&mc1n2->mutex);
++
++      if ((port->stream & ~(1 << dir)) && (rate != port->rate)) {
++              err = -EBUSY;
++              goto error;
++      }
++
++#ifdef CONFIG_SND_SAMSUNG_RP
++      if ((dir == SNDRV_PCM_STREAM_PLAYBACK) && (get_port_id(dai->id) == 0)
++              && (port->stream & (1 << dir)) && (rate == port->rate)) {
++              /* During ULP Audio, DAI should not be touched
++                 if i2s port already opened. */
++              err = 0;
++              goto error;
++      }
++#endif
++
++/* Because of line out pop up noise issue, i2s port already opend */
++      if ((mc1n2->lineoutenable == 1) && (port->stream & (1 << dir))) {
++              err = 0;
++              goto error;
++      }
++
++      port->rate = rate;
++      port->channels = params_channels(params);
++
++      err = mc1n2_update_clock(mc1n2);
++      if (err != MCDRV_SUCCESS) {
++              dev_err(codec->dev, "%d: Error in mc1n2_update_clock\n", err);
++              err = -EIO;
++              goto error;
++      }
++
++      err = mc1n2_setup_dai(mc1n2, get_port_id(dai->id), MCDRV_DIO_DA, dir);
++      if (err != MCDRV_SUCCESS) {
++              dev_err(codec->dev, "%d: Error in mc1n2_setup_dai\n", err);
++              err = -EIO;
++              goto error;
++      }
++
++      if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
++              err = mc1n2_control_dir(mc1n2, get_port_id(dai->id), 1);
++      } else {
++              err = mc1n2_control_dit(mc1n2, get_port_id(dai->id), 1);
++      }
++      if (err != MCDRV_SUCCESS) {
++              dev_err(codec->dev, "%d: Error in mc1n2_control_dir/dit\n", err);
++              err = -EIO;
++              goto error;
++      }
++
++      port->stream |= (1 << dir);
++
++error:
++      mutex_unlock(&mc1n2->mutex);
++
++      return err;
++}
++
++static int mc1n2_hw_free(struct snd_pcm_substream *substream,
++                       struct snd_soc_dai *dai)
++{
++#ifdef ALSA_VER_ANDROID_3_0
++      struct snd_soc_codec *codec = dai->codec;
++#else
++      struct snd_soc_pcm_runtime *runtime = snd_pcm_substream_chip(substream);
++#ifdef ALSA_VER_1_0_19
++      struct snd_soc_codec *codec = runtime->socdev->codec;
++#else
++      struct snd_soc_codec *codec = runtime->socdev->card->codec;
++#endif
++#endif
++#if (defined ALSA_VER_ANDROID_2_6_35) || (defined ALSA_VER_ANDROID_3_0)
++      struct mc1n2_data *mc1n2 = snd_soc_codec_get_drvdata(codec);
++#else
++      struct mc1n2_data *mc1n2 = codec->private_data;
++#endif
++      struct mc1n2_port_params *port = &mc1n2->port[get_port_id(dai->id)];
++      int dir = substream->stream;
++      int err;
++
++      mutex_lock(&mc1n2->mutex);
++
++      if (!(port->stream & (1 << dir))) {
++              err = 0;
++              goto error;
++      }
++
++#ifdef CONFIG_SND_SAMSUNG_RP
++      if ((dir == SNDRV_PCM_STREAM_PLAYBACK) && (get_port_id(dai->id) == 0)) {
++              /* Leave codec opened during ULP Audio */
++              err = 0;
++              goto error;
++      }
++#endif
++
++/* Because of line out pop up noise, leave codec opened */
++      if (mc1n2->lineoutenable == 1) {
++              err = 0;
++              goto error;
++      }
++
++      if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
++              err = mc1n2_control_dir(mc1n2, get_port_id(dai->id), 0);
++      } else {
++              err = mc1n2_control_dit(mc1n2, get_port_id(dai->id), 0);
++      }
++      if (err != MCDRV_SUCCESS) {
++              dev_err(codec->dev, "%d: Error in mc1n2_control_dir/dit\n", err);
++              err = -EIO;
++              goto error;
++      }
++
++      port->stream &= ~(1 << dir);
++
++error:
++      mutex_unlock(&mc1n2->mutex);
++
++      return err;
++}
++
++static int mc1n2_pcm_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div)
++{
++      struct snd_soc_codec *codec = dai->codec;
++#if (defined ALSA_VER_ANDROID_2_6_35) || (defined ALSA_VER_ANDROID_3_0)
++      struct mc1n2_data *mc1n2 = snd_soc_codec_get_drvdata(codec);
++#else
++      struct mc1n2_data *mc1n2 = codec->private_data;
++#endif
++      struct mc1n2_port_params *port = &mc1n2->port[get_port_id(dai->id)];
++
++      switch (div_id) {
++      case MC1N2_BCLK_MULT:
++              switch (div) {
++              case MC1N2_LRCK_X8:
++                      port->bckfs = MCDRV_BCKFS_16;
++                      port->pcm_clkdown = MCDRV_PCM_CLKDOWN_HALF;
++                      break;
++              case MC1N2_LRCK_X16:
++                      port->bckfs = MCDRV_BCKFS_16;
++                      port->pcm_clkdown = MCDRV_PCM_CLKDOWN_OFF;
++                      break;
++              case MC1N2_LRCK_X24:
++                      port->bckfs = MCDRV_BCKFS_48;
++                      port->pcm_clkdown = MCDRV_PCM_CLKDOWN_HALF;
++                      break;
++              case MC1N2_LRCK_X32:
++                      port->bckfs = MCDRV_BCKFS_32;
++                      port->pcm_clkdown = MCDRV_PCM_CLKDOWN_OFF;
++                      break;
++              case MC1N2_LRCK_X48:
++                      port->bckfs = MCDRV_BCKFS_48;
++                      port->pcm_clkdown = MCDRV_PCM_CLKDOWN_OFF;
++                      break;
++              case MC1N2_LRCK_X64:
++                      port->bckfs = MCDRV_BCKFS_64;
++                      port->pcm_clkdown = MCDRV_PCM_CLKDOWN_OFF;
++                      break;
++              case MC1N2_LRCK_X128:
++                      port->bckfs = MCDRV_BCKFS_128;
++                      port->pcm_clkdown = MCDRV_PCM_CLKDOWN_OFF;
++                      break;
++              case MC1N2_LRCK_X256:
++                      port->bckfs = MCDRV_BCKFS_256;
++                      port->pcm_clkdown = MCDRV_PCM_CLKDOWN_OFF;
++                      break;
++              case MC1N2_LRCK_X512:
++                      port->bckfs = MCDRV_BCKFS_512;
++                      port->pcm_clkdown = MCDRV_PCM_CLKDOWN_OFF;
++                      break;
++              }
++              break;
++      default:
++              return mc1n2_set_clkdiv_common(mc1n2, div_id, div);
++      }
++
++      return 0;
++}
++
++static int mc1n2_pcm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
++{
++      struct snd_soc_codec *codec = dai->codec;
++#if (defined ALSA_VER_ANDROID_2_6_35) || (defined ALSA_VER_ANDROID_3_0)
++      struct mc1n2_data *mc1n2 = snd_soc_codec_get_drvdata(codec);
++#else
++      struct mc1n2_data *mc1n2 = codec->private_data;
++#endif
++      struct mc1n2_port_params *port = &mc1n2->port[get_port_id(dai->id)];
++
++      /* format */
++      switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++      case SND_SOC_DAIFMT_DSP_A:
++              port->format = MCDRV_PCM_SHORTFRAME;
++              break;
++      case SND_SOC_DAIFMT_DSP_B:
++              port->format = MCDRV_PCM_LONGFRAME;
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      return mc1n2_set_fmt_common(port, fmt);
++}
++
++static int mc1n2_pcm_hw_params(struct snd_pcm_substream *substream,
++                             struct snd_pcm_hw_params *params,
++                             struct snd_soc_dai *dai)
++{
++#ifdef ALSA_VER_ANDROID_3_0
++      struct snd_soc_codec *codec = dai->codec;
++#else
++      struct snd_soc_pcm_runtime *runtime = snd_pcm_substream_chip(substream);
++#ifdef ALSA_VER_1_0_19
++      struct snd_soc_codec *codec = runtime->socdev->codec;
++#else
++      struct snd_soc_codec *codec = runtime->socdev->card->codec;
++#endif
++#endif
++#if (defined ALSA_VER_ANDROID_2_6_35) || (defined ALSA_VER_ANDROID_3_0)
++      struct mc1n2_data *mc1n2 = snd_soc_codec_get_drvdata(codec);
++#else
++      struct mc1n2_data *mc1n2 = codec->private_data;
++#endif
++      struct mc1n2_port_params *port = &mc1n2->port[get_port_id(dai->id)];
++      int dir = substream->stream;
++      int rate;
++      int err;
++
++      dbg_info("hw_params: [%d] name=%s, dir=%d, rate=%d, bits=%d, ch=%d\n",
++               get_port_id(dai->id), substream->name, dir,
++               params_rate(params), params_format(params), params_channels(params));
++
++      /* channels */
++      switch (params_channels(params)) {
++      case 1:
++              port->pcm_mono[dir] = MCDRV_PCM_MONO;
++              break;
++      case 2:
++              port->pcm_mono[dir] = MCDRV_PCM_STEREO;
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      /* format (bits) */
++      switch (params_format(params)) {
++      case SNDRV_PCM_FORMAT_S8:
++              port->bits[dir] = MCDRV_PCM_BITSEL_8;
++              port->pcm_order[dir] = MCDRV_PCM_MSB_FIRST;
++              port->pcm_law[dir] = MCDRV_PCM_LINEAR;
++              break;
++      case SNDRV_PCM_FORMAT_S16_LE:
++              port->bits[dir] = MCDRV_PCM_BITSEL_16;
++              port->pcm_order[dir] = MCDRV_PCM_LSB_FIRST;
++              port->pcm_law[dir] = MCDRV_PCM_LINEAR;
++              break;
++      case SNDRV_PCM_FORMAT_S16_BE:
++              port->bits[dir] = MCDRV_PCM_BITSEL_16;
++              port->pcm_order[dir] = MCDRV_PCM_MSB_FIRST;
++              port->pcm_law[dir] = MCDRV_PCM_LINEAR;
++              break;
++      case SNDRV_PCM_FORMAT_A_LAW:
++              port->bits[dir] = MCDRV_PCM_BITSEL_8;
++              port->pcm_order[dir] = MCDRV_PCM_MSB_FIRST;
++              port->pcm_law[dir] = MCDRV_PCM_ALAW;
++              break;
++      case SNDRV_PCM_FORMAT_MU_LAW:
++              port->bits[dir] = MCDRV_PCM_BITSEL_8;
++              port->pcm_order[dir] = MCDRV_PCM_MSB_FIRST;
++              port->pcm_law[dir] = MCDRV_PCM_MULAW;
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      /* rate */
++      switch (params_rate(params)) {
++      case 8000:
++              rate = MCDRV_FS_8000;
++              break;
++      case 16000:
++              rate = MCDRV_FS_16000;
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      mutex_lock(&mc1n2->mutex);
++
++      if ((port->stream & ~(1 << dir)) && (rate != port->rate)) {
++              err = -EBUSY;
++              goto error;
++      }
++
++      port->rate = rate;
++      port->channels = params_channels(params);
++
++      err = mc1n2_update_clock(mc1n2);
++      if (err != MCDRV_SUCCESS) {
++              dev_err(codec->dev, "%d: Error in mc1n2_update_clock\n", err);
++              err = -EIO;
++              goto error;
++      }
++
++      err = mc1n2_setup_dai(mc1n2, get_port_id(dai->id), MCDRV_DIO_PCM, dir);
++      if (err != MCDRV_SUCCESS) {
++              dev_err(codec->dev, "%d: Error in mc1n2_setup_dai\n", err);
++              err = -EIO;
++              goto error;
++      }
++
++      if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
++              err = mc1n2_control_dir(mc1n2, get_port_id(dai->id), 1);
++      } else {
++              err = mc1n2_control_dit(mc1n2, get_port_id(dai->id), 1);
++      }
++      if (err != MCDRV_SUCCESS) {
++              dev_err(codec->dev, "%d: Error in mc1n2_control_dir/dit\n", err);
++              err = -EIO;
++              goto error;
++      }
++
++      port->stream |= (1 << dir);
++
++error:
++      mutex_unlock(&mc1n2->mutex);
++
++      return err;
++}
++
++#ifndef ALSA_VER_1_0_19
++static struct snd_soc_dai_ops mc1n2_dai_ops[] = {
++      {
++              .set_clkdiv = mc1n2_i2s_set_clkdiv,
++              .set_fmt = mc1n2_i2s_set_fmt,
++              .hw_params = mc1n2_i2s_hw_params,
++              .hw_free = mc1n2_hw_free,
++      },
++      {
++              .set_clkdiv = mc1n2_pcm_set_clkdiv,
++              .set_fmt = mc1n2_pcm_set_fmt,
++              .hw_params = mc1n2_pcm_hw_params,
++              .hw_free = mc1n2_hw_free,
++      },
++      {
++              .set_clkdiv = mc1n2_i2s_set_clkdiv,
++              .set_fmt = mc1n2_i2s_set_fmt,
++              .hw_params = mc1n2_i2s_hw_params,
++              .hw_free = mc1n2_hw_free,
++      },
++      {
++              .set_clkdiv = mc1n2_pcm_set_clkdiv,
++              .set_fmt = mc1n2_pcm_set_fmt,
++              .hw_params = mc1n2_pcm_hw_params,
++              .hw_free = mc1n2_hw_free,
++      },
++      {
++              .set_clkdiv = mc1n2_i2s_set_clkdiv,
++              .set_fmt = mc1n2_i2s_set_fmt,
++              .hw_params = mc1n2_i2s_hw_params,
++              .hw_free = mc1n2_hw_free,
++      },
++      {
++              .set_clkdiv = mc1n2_pcm_set_clkdiv,
++              .set_fmt = mc1n2_pcm_set_fmt,
++              .hw_params = mc1n2_pcm_hw_params,
++              .hw_free = mc1n2_hw_free,
++      }
++};
++#endif
++
++
++#ifdef ALSA_VER_ANDROID_3_0
++struct snd_soc_dai_driver mc1n2_dai[] = {
++#else
++struct snd_soc_dai mc1n2_dai[] = {
++#endif
++      {
++              .name = MC1N2_NAME "-da0i",
++              .id = 1,
++              .playback = {
++                      .stream_name = "Playback",
++                      .channels_min = 1,
++                      .channels_max = 2,
++                      .rates = MC1N2_I2S_RATE,
++                      .formats = MC1N2_I2S_FORMATS,
++              },
++              .capture = {
++                      .stream_name = "Capture",
++                      .channels_min = 1,
++                      .channels_max = 2,
++                      .rates = MC1N2_I2S_RATE,
++                      .formats = MC1N2_I2S_FORMATS,
++              },
++#ifdef ALSA_VER_1_0_19
++              .ops = {
++                      .set_clkdiv = mc1n2_i2s_set_clkdiv,
++                      .set_fmt = mc1n2_i2s_set_fmt,
++                      .hw_params = mc1n2_i2s_hw_params,
++                      .hw_free = mc1n2_hw_free,
++              }
++#else
++              .ops = &mc1n2_dai_ops[0]
++#endif
++      },
++      {
++              .name = MC1N2_NAME "-da0p",
++              .id = 1,
++              .playback = {
++                      .stream_name = "Playback",
++                      .channels_min = 1,
++                      .channels_max = 2,
++                      .rates = MC1N2_PCM_RATE,
++                      .formats = MC1N2_PCM_FORMATS,
++              },
++              .capture = {
++                      .stream_name = "Capture",
++                      .channels_min = 1,
++                      .channels_max = 2,
++                      .rates = MC1N2_PCM_RATE,
++                      .formats = MC1N2_PCM_FORMATS,
++              },
++#ifdef ALSA_VER_1_0_19
++              .ops = {
++                      .set_clkdiv = mc1n2_pcm_set_clkdiv,
++                      .set_fmt = mc1n2_pcm_set_fmt,
++                      .hw_params = mc1n2_pcm_hw_params,
++                      .hw_free = mc1n2_hw_free,
++              }
++#else
++              .ops = &mc1n2_dai_ops[1]
++#endif
++      },
++      {
++              .name = MC1N2_NAME "-da1i",
++              .id = 2,
++              .playback = {
++                      .stream_name = "Playback",
++                      .channels_min = 1,
++                      .channels_max = 2,
++                      .rates = MC1N2_I2S_RATE,
++                      .formats = MC1N2_I2S_FORMATS,
++              },
++              .capture = {
++                      .stream_name = "Capture",
++                      .channels_min = 1,
++                      .channels_max = 2,
++                      .rates = MC1N2_I2S_RATE,
++                      .formats = MC1N2_I2S_FORMATS,
++              },
++#ifdef ALSA_VER_1_0_19
++              .ops = {
++                      .set_clkdiv = mc1n2_i2s_set_clkdiv,
++                      .set_fmt = mc1n2_i2s_set_fmt,
++                      .hw_params = mc1n2_i2s_hw_params,
++                      .hw_free = mc1n2_hw_free,
++              }
++#else
++              .ops = &mc1n2_dai_ops[2]
++#endif
++      },
++      {
++              .name = MC1N2_NAME "-da1p",
++              .id = 2,
++              .playback = {
++                      .stream_name = "Playback",
++                      .channels_min = 1,
++                      .channels_max = 2,
++                      .rates = MC1N2_PCM_RATE,
++                      .formats = MC1N2_PCM_FORMATS,
++              },
++              .capture = {
++                      .stream_name = "Capture",
++                      .channels_min = 1,
++                      .channels_max = 2,
++                      .rates = MC1N2_PCM_RATE,
++                      .formats = MC1N2_PCM_FORMATS,
++              },
++#ifdef ALSA_VER_1_0_19
++              .ops = {
++                      .set_clkdiv = mc1n2_pcm_set_clkdiv,
++                      .set_fmt = mc1n2_pcm_set_fmt,
++                      .hw_params = mc1n2_pcm_hw_params,
++                      .hw_free = mc1n2_hw_free,
++              }
++#else
++              .ops = &mc1n2_dai_ops[3]
++#endif
++      },
++      {
++              .name = MC1N2_NAME "-da2i",
++              .id = 3,
++              .playback = {
++                      .stream_name = "Playback",
++                      .channels_min = 1,
++                      .channels_max = 2,
++                      .rates = MC1N2_I2S_RATE,
++                      .formats = MC1N2_I2S_FORMATS,
++              },
++              .capture = {
++                      .stream_name = "Capture",
++                      .channels_min = 1,
++                      .channels_max = 2,
++                      .rates = MC1N2_I2S_RATE,
++                      .formats = MC1N2_I2S_FORMATS,
++              },
++#ifdef ALSA_VER_1_0_19
++              .ops = {
++                      .set_clkdiv = mc1n2_i2s_set_clkdiv,
++                      .set_fmt = mc1n2_i2s_set_fmt,
++                      .hw_params = mc1n2_i2s_hw_params,
++                      .hw_free = mc1n2_hw_free,
++              }
++#else
++              .ops = &mc1n2_dai_ops[4]
++#endif
++      },
++      {
++              .name = MC1N2_NAME "-da2p",
++              .id = 3,
++              .playback = {
++                      .stream_name = "Playback",
++                      .channels_min = 1,
++                      .channels_max = 2,
++                      .rates = MC1N2_PCM_RATE,
++                      .formats = MC1N2_PCM_FORMATS,
++              },
++              .capture = {
++                      .stream_name = "Capture",
++                      .channels_min = 1,
++                      .channels_max = 2,
++                      .rates = MC1N2_PCM_RATE,
++                      .formats = MC1N2_PCM_FORMATS,
++              },
++#ifdef ALSA_VER_1_0_19
++              .ops = {
++                      .set_clkdiv = mc1n2_pcm_set_clkdiv,
++                      .set_fmt = mc1n2_pcm_set_fmt,
++                      .hw_params = mc1n2_pcm_hw_params,
++                      .hw_free = mc1n2_hw_free,
++              }
++#else
++              .ops = &mc1n2_dai_ops[5]
++#endif
++      },
++};
++#ifndef ALSA_VER_ANDROID_3_0
++EXPORT_SYMBOL_GPL(mc1n2_dai);
++#endif
++
++/*
++ * Control interface
++ */
++/*
++ * Virtual register
++ *
++ * 16bit software registers are implemented for volumes and mute
++ * switches (as an exception, no mute switches for MIC and HP gain).
++ * Register contents are stored in codec's register cache.
++ *
++ *   15  14                       8   7   6                       0
++ *  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
++ *  |swR|          volume-R         |swL|          volume-L         |
++ *  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
++ */
++struct mc1n2_vreg_info {
++      size_t offset;
++      SINT16 *volmap;
++};
++
++/* volmap for Digital Volumes */
++static SINT16 mc1n2_vol_digital[] = {
++      0xa000, 0xb600, 0xb700, 0xb800, 0xb900, 0xba00, 0xbb00, 0xbc00,
++      0xbd00, 0xbe00, 0xbf00, 0xc000, 0xc100, 0xc200, 0xc300, 0xc400,
++      0xc500, 0xc600, 0xc700, 0xc800, 0xc900, 0xca00, 0xcb00, 0xcc00,
++      0xcd00, 0xce00, 0xcf00, 0xd000, 0xd100, 0xd200, 0xd300, 0xd400,
++      0xd500, 0xd600, 0xd700, 0xd800, 0xd900, 0xda00, 0xdb00, 0xdc00,
++      0xdd00, 0xde00, 0xdf00, 0xe000, 0xe100, 0xe200, 0xe300, 0xe400,
++      0xe500, 0xe600, 0xe700, 0xe800, 0xe900, 0xea00, 0xeb00, 0xec00,
++      0xed00, 0xee00, 0xef00, 0xf000, 0xf100, 0xf200, 0xf300, 0xf400,
++      0xf500, 0xf600, 0xf700, 0xf800, 0xf900, 0xfa00, 0xfb00, 0xfc00,
++      0xfd00, 0xfe00, 0xff00, 0x0000, 0x0100, 0x0200, 0x0300, 0x0400,
++      0x0500, 0x0600, 0x0700, 0x0800, 0x0900, 0x0a00, 0x0b00, 0x0c00,
++      0x0d00, 0x0e00, 0x0f00, 0x1000, 0x1100, 0x1200,
++};
++
++/* volmap for ADC Analog Volume */
++static SINT16 mc1n2_vol_adc[] = {
++      0xa000, 0xe500, 0xe680, 0xe800, 0xe980, 0xeb00, 0xec80, 0xee00,
++      0xef80, 0xf100, 0xf280, 0xf400, 0xf580, 0xf700, 0xf880, 0xfa00,
++      0xfb80, 0xfd00, 0xfe80, 0x0000, 0x0180, 0x0300, 0x0480, 0x0600,
++      0x0780, 0x0900, 0x0a80, 0x0c00, 0x0d80, 0x0f00, 0x1080, 0x1200,
++};
++
++/* volmap for LINE/MIC Input Volumes */
++static SINT16 mc1n2_vol_ain[] = {
++      0xa000, 0xe200, 0xe380, 0xe500, 0xe680, 0xe800, 0xe980, 0xeb00,
++      0xec80, 0xee00, 0xef80, 0xf100, 0xf280, 0xf400, 0xf580, 0xf700,
++      0xf880, 0xfa00, 0xfb80, 0xfd00, 0xfe80, 0x0000, 0x0180, 0x0300,
++      0x0480, 0x0600, 0x0780, 0x0900, 0x0a80, 0x0c00, 0x0d80, 0x0f00,
++};
++
++/* volmap for HP/SP Output Volumes */
++static SINT16 mc1n2_vol_hpsp[] = {
++      0xa000, 0xdc00, 0xe400, 0xe800, 0xea00, 0xec00, 0xee00, 0xf000,
++      0xf100, 0xf200, 0xf300, 0xf400, 0xf500, 0xf600, 0xf700, 0xf800,
++      0xf880, 0xf900, 0xf980, 0xfa00, 0xfa80, 0xfb00, 0xfb80, 0xfc00,
++      0xfc80, 0xfd00, 0xfd80, 0xfe00, 0xfe80, 0xff00, 0xff80, 0x0000,
++};
++
++/* volmap for RC/LINE Output Volumes */
++static SINT16 mc1n2_vol_aout[] = {
++      0xa000, 0xe200, 0xe300, 0xe400, 0xe500, 0xe600, 0xe700, 0xe800,
++      0xe900, 0xea00, 0xeb00, 0xec00, 0xed00, 0xee00, 0xef00, 0xf000,
++      0xf100, 0xf200, 0xf300, 0xf400, 0xf500, 0xf600, 0xf700, 0xf800,
++      0xf900, 0xfa00, 0xfb00, 0xfc00, 0xfd00, 0xfe00, 0xff00, 0x0000,
++};
++
++/* volmap for MIC Gain Volumes */
++static SINT16 mc1n2_vol_micgain[] = {
++      0x0f00, 0x1400, 0x1900, 0x1e00,
++};
++
++/* volmap for HP Gain Volume */
++static SINT16 mc1n2_vol_hpgain[] = {
++      0x0000, 0x0180, 0x0300, 0x0600,
++};
++
++struct mc1n2_vreg_info mc1n2_vreg_map[MC1N2_N_VOL_REG] = {
++      {offsetof(MCDRV_VOL_INFO, aswD_Ad0),       mc1n2_vol_digital},
++      {offsetof(MCDRV_VOL_INFO, aswD_Aeng6),     mc1n2_vol_digital},
++      {offsetof(MCDRV_VOL_INFO, aswD_Pdm),       mc1n2_vol_digital},
++      {offsetof(MCDRV_VOL_INFO, aswD_Dir0),      mc1n2_vol_digital},
++      {offsetof(MCDRV_VOL_INFO, aswD_Dir1),      mc1n2_vol_digital},
++      {offsetof(MCDRV_VOL_INFO, aswD_Dir2),      mc1n2_vol_digital},
++      {offsetof(MCDRV_VOL_INFO, aswD_Ad0Att),    mc1n2_vol_digital},
++      {offsetof(MCDRV_VOL_INFO, aswD_Dir0Att),   mc1n2_vol_digital},
++      {offsetof(MCDRV_VOL_INFO, aswD_Dir1Att),   mc1n2_vol_digital},
++      {offsetof(MCDRV_VOL_INFO, aswD_Dir2Att),   mc1n2_vol_digital},
++      {offsetof(MCDRV_VOL_INFO, aswD_SideTone),  mc1n2_vol_digital},
++      {offsetof(MCDRV_VOL_INFO, aswD_DacMaster), mc1n2_vol_digital},
++      {offsetof(MCDRV_VOL_INFO, aswD_DacVoice),  mc1n2_vol_digital},
++      {offsetof(MCDRV_VOL_INFO, aswD_DacAtt),    mc1n2_vol_digital},
++      {offsetof(MCDRV_VOL_INFO, aswD_Dit0),      mc1n2_vol_digital},
++      {offsetof(MCDRV_VOL_INFO, aswD_Dit1),      mc1n2_vol_digital},
++      {offsetof(MCDRV_VOL_INFO, aswD_Dit2),      mc1n2_vol_digital},
++      {offsetof(MCDRV_VOL_INFO, aswA_Ad0),       mc1n2_vol_adc},
++      {offsetof(MCDRV_VOL_INFO, aswA_Lin1),      mc1n2_vol_ain},
++      {offsetof(MCDRV_VOL_INFO, aswA_Mic1),      mc1n2_vol_ain},
++      {offsetof(MCDRV_VOL_INFO, aswA_Mic2),      mc1n2_vol_ain},
++      {offsetof(MCDRV_VOL_INFO, aswA_Mic3),      mc1n2_vol_ain},
++      {offsetof(MCDRV_VOL_INFO, aswA_Hp),        mc1n2_vol_hpsp},
++      {offsetof(MCDRV_VOL_INFO, aswA_Sp),        mc1n2_vol_hpsp},
++      {offsetof(MCDRV_VOL_INFO, aswA_Rc),        mc1n2_vol_hpsp},
++      {offsetof(MCDRV_VOL_INFO, aswA_Lout1),     mc1n2_vol_aout},
++      {offsetof(MCDRV_VOL_INFO, aswA_Lout2),     mc1n2_vol_aout},
++      {offsetof(MCDRV_VOL_INFO, aswA_Mic1Gain),  mc1n2_vol_micgain},
++      {offsetof(MCDRV_VOL_INFO, aswA_Mic2Gain),  mc1n2_vol_micgain},
++      {offsetof(MCDRV_VOL_INFO, aswA_Mic3Gain),  mc1n2_vol_micgain},
++      {offsetof(MCDRV_VOL_INFO, aswA_HpGain),    mc1n2_vol_hpgain},
++};
++
++#ifdef ALSA_VER_ANDROID_3_0
++static int cache_read(struct snd_soc_codec *codec, unsigned int reg)
++{
++      int ret;
++      unsigned int val;
++
++      ret = snd_soc_cache_read(codec, reg, &val);
++      if (ret != 0) {
++              dev_err(codec->dev, "Cache read to %x failed: %d\n", reg, ret);
++              return -EIO;
++      }
++      return val;
++}
++static int cache_write(struct snd_soc_codec *codec,
++                                         unsigned int reg, unsigned int value)
++{
++      return ((int)snd_soc_cache_write(codec, reg, value));
++}
++#else
++static int cache_read(struct snd_soc_codec *codec, unsigned int reg)
++{
++      return ((u16 *)codec->reg_cache)[reg];
++}
++static int cache_write(struct snd_soc_codec *codec,
++                                         unsigned int reg, unsigned int value)
++{
++      u16 *cp = (u16 *)codec->reg_cache + reg;
++      *cp = value;
++      return 0;
++}
++#endif
++
++static unsigned int mc1n2_read_reg(struct snd_soc_codec *codec, unsigned int reg)
++{
++      int ret;
++
++      ret = cache_read(codec, reg);
++      if (ret < 0) {
++              return -EIO;
++      }
++      return (unsigned int)ret;
++}
++
++#ifdef ALSA_VER_ANDROID_3_0
++#define REG_CACHE_READ(reg)   (mc1n2_read_reg(codec, reg))
++#else
++#define REG_CACHE_READ(reg)   ((u16 *)codec->reg_cache)[reg]
++#endif
++
++static int write_reg_vol(struct snd_soc_codec *codec,
++                         unsigned int reg, unsigned int value)
++{
++      MCDRV_VOL_INFO update;
++      SINT16 *vp;
++      int ret;
++      int err, i;
++
++      memset(&update, 0, sizeof(MCDRV_VOL_INFO));
++      vp = (SINT16 *)((void *)&update + mc1n2_vreg_map[reg].offset);
++
++      for (i = 0; i < 2; i++, vp++) {
++              unsigned int v = (value >> (i*8)) & 0xff;
++              unsigned int c = (mc1n2_read_reg(codec, reg) >> (i*8)) & 0xff;
++              if (v != c) {
++                      int sw, vol;
++                      SINT16 db;
++                      sw = (reg < MC1N2_AVOL_MIC1_GAIN) ? (v & 0x80) : 1;
++                      vol = sw ? (v & 0x7f) : 0;
++                      db = mc1n2_vreg_map[reg].volmap[vol];
++                      *vp = db | MCDRV_VOL_UPDATE;
++              }
++      }
++
++      err = _McDrv_Ctrl(MCDRV_SET_VOLUME, &update, 0);
++      if (err != MCDRV_SUCCESS) {
++              dev_err(codec->dev, "%d: Error in MCDRV_SET_VOLUME\n", err);
++              return -EIO;
++      }
++      ret = cache_write(codec, reg, value);
++      if (ret != 0) {
++              dev_err(codec->dev, "Cache write to %x failed: %d\n", reg, ret);
++      }
++
++      return 0;
++}
++
++static int mc1n2_hwdep_ioctl_set_path(struct snd_soc_codec *codec,
++                                    void *info, unsigned int update);
++
++static int write_reg_path(struct snd_soc_codec *codec,
++                         unsigned int reg, unsigned int value)
++{
++      MCDRV_PATH_INFO update;
++      MCDRV_CHANNEL *pch;
++      MCDRV_AE_INFO *pae;
++      int ret = 0;
++      int err;
++
++      memset(&update, 0, sizeof(MCDRV_PATH_INFO));
++
++      ret = cache_write(codec, reg, value);
++      if (ret != 0) {
++              dev_err(codec->dev, "Cache write to %x failed: %d\n",reg, ret);
++      }
++
++      switch (reg) {
++      case MC1N2_ADCL_MIC1_SW:
++              if (value) {
++                      update.asAdc0[0].abSrcOnOff[0] = MCDRV_SRC0_MIC1_ON;
++              }
++              else {
++                      update.asAdc0[0].abSrcOnOff[0] = MCDRV_SRC0_MIC1_OFF;
++              }
++              break;
++      case MC1N2_ADCL_MIC2_SW:
++              if (value) {
++                      update.asAdc0[0].abSrcOnOff[0] = MCDRV_SRC0_MIC2_ON;
++              }
++              else {
++                      update.asAdc0[0].abSrcOnOff[0] = MCDRV_SRC0_MIC2_OFF;
++              }
++              break;
++      case MC1N2_ADCL_MIC3_SW:
++              if (value) {
++                      update.asAdc0[0].abSrcOnOff[0] = MCDRV_SRC0_MIC3_ON;
++              }
++              else {
++                      update.asAdc0[0].abSrcOnOff[0] = MCDRV_SRC0_MIC3_OFF;
++              }
++              break;
++      case MC1N2_ADCL_LINE_SW:
++      case MC1N2_ADCL_LINE_SRC:
++              if (REG_CACHE_READ(MC1N2_ADCL_LINE_SRC) == 0) {
++                      if (REG_CACHE_READ(MC1N2_ADCL_LINE_SW)) {
++                              update.asAdc0[0].abSrcOnOff[1] = MCDRV_SRC1_LINE1_L_ON;
++                      }
++                      else {
++                              update.asAdc0[0].abSrcOnOff[1] = MCDRV_SRC1_LINE1_L_OFF;
++                      }
++              }
++              else {
++                      if (REG_CACHE_READ(MC1N2_ADCL_LINE_SW)) {
++                              update.asAdc0[0].abSrcOnOff[1] = MCDRV_SRC1_LINE1_M_ON;
++                      }
++                      else {
++                              update.asAdc0[0].abSrcOnOff[1] = MCDRV_SRC1_LINE1_M_OFF;
++                      }
++              }
++              break;
++      case MC1N2_ADCR_MIC1_SW:
++              if (value) {
++                      update.asAdc0[1].abSrcOnOff[0] = MCDRV_SRC0_MIC1_ON;
++              }
++              else {
++                      update.asAdc0[1].abSrcOnOff[0] = MCDRV_SRC0_MIC1_OFF;
++              }
++              break;
++      case MC1N2_ADCR_MIC2_SW:
++              if (value) {
++                      update.asAdc0[1].abSrcOnOff[0] = MCDRV_SRC0_MIC2_ON;
++              }
++              else {
++                      update.asAdc0[1].abSrcOnOff[0] = MCDRV_SRC0_MIC2_OFF;
++              }
++              break;
++      case MC1N2_ADCR_MIC3_SW:
++              if (value) {
++                      update.asAdc0[1].abSrcOnOff[0] = MCDRV_SRC0_MIC3_ON;
++              }
++              else {
++                      update.asAdc0[1].abSrcOnOff[0] = MCDRV_SRC0_MIC3_OFF;
++              }
++              break;
++      case MC1N2_ADCR_LINE_SW:
++      case MC1N2_ADCR_LINE_SRC:
++              if (REG_CACHE_READ(MC1N2_ADCR_LINE_SRC) == 0) {
++                      if (REG_CACHE_READ(MC1N2_ADCR_LINE_SW)) {
++                              update.asAdc0[1].abSrcOnOff[1] = MCDRV_SRC1_LINE1_R_ON;
++                      }
++                      else {
++                              update.asAdc0[1].abSrcOnOff[1] = MCDRV_SRC1_LINE1_R_OFF;
++                      }
++              }
++              else {
++                      if (REG_CACHE_READ(MC1N2_ADCR_LINE_SW)) {
++                              update.asAdc0[1].abSrcOnOff[1] = MCDRV_SRC1_LINE1_M_ON;
++                      }
++                      else {
++                              update.asAdc0[1].abSrcOnOff[1] = MCDRV_SRC1_LINE1_M_OFF;
++                      }
++              }
++              break;
++      case MC1N2_HPL_MIC1_SW:
++              if (value) {
++                      update.asHpOut[0].abSrcOnOff[0] = MCDRV_SRC0_MIC1_ON;
++              }
++              else {
++                      update.asHpOut[0].abSrcOnOff[0] = MCDRV_SRC0_MIC1_OFF;
++              }
++              break;
++      case MC1N2_HPL_MIC2_SW:
++              if (value) {
++                      update.asHpOut[0].abSrcOnOff[0] = MCDRV_SRC0_MIC2_ON;
++              }
++              else {
++                      update.asHpOut[0].abSrcOnOff[0] = MCDRV_SRC0_MIC2_OFF;
++              }
++              break;
++      case MC1N2_HPL_MIC3_SW:
++              if (value) {
++                      update.asHpOut[0].abSrcOnOff[0] = MCDRV_SRC0_MIC3_ON;
++              }
++              else {
++                      update.asHpOut[0].abSrcOnOff[0] = MCDRV_SRC0_MIC3_OFF;
++              }
++              break;
++      case MC1N2_HPL_LINE_SW:
++      case MC1N2_HPL_LINE_SRC:
++              if (REG_CACHE_READ(MC1N2_HPL_LINE_SRC) == 0) {
++                      if (REG_CACHE_READ(MC1N2_HPL_LINE_SW)) {
++                              update.asHpOut[0].abSrcOnOff[1] = MCDRV_SRC1_LINE1_L_ON;
++                      }
++                      else {
++                              update.asHpOut[0].abSrcOnOff[1] = MCDRV_SRC1_LINE1_L_OFF;
++                      }
++              }
++              else {
++                      if (REG_CACHE_READ(MC1N2_HPL_LINE_SW)) {
++                              update.asHpOut[0].abSrcOnOff[1] = MCDRV_SRC1_LINE1_M_ON;
++                      }
++                      else {
++                              update.asHpOut[0].abSrcOnOff[1] = MCDRV_SRC1_LINE1_M_OFF;
++                      }
++              }
++              break;
++      case MC1N2_HPL_DAC_SW:
++      case MC1N2_HPL_DAC_SRC:
++              if (REG_CACHE_READ(MC1N2_HPL_DAC_SRC) == 0) {
++                      if (REG_CACHE_READ(MC1N2_HPL_DAC_SW)) {
++                              update.asHpOut[0].abSrcOnOff[5] = MCDRV_SRC5_DAC_L_ON;
++                      }
++                      else {
++                              update.asHpOut[0].abSrcOnOff[5] = MCDRV_SRC5_DAC_L_OFF;
++                      }
++              }
++              else {
++                      if (REG_CACHE_READ(MC1N2_HPL_DAC_SW)) {
++                              update.asHpOut[0].abSrcOnOff[5] = MCDRV_SRC5_DAC_M_ON;
++                      }
++                      else {
++                              update.asHpOut[0].abSrcOnOff[5] = MCDRV_SRC5_DAC_M_OFF;
++                      }
++              }
++              break;
++      case MC1N2_HPR_MIC1_SW:
++              if (value) {
++                      update.asHpOut[1].abSrcOnOff[0] = MCDRV_SRC0_MIC1_ON;
++              }
++              else {
++                      update.asHpOut[1].abSrcOnOff[0] = MCDRV_SRC0_MIC1_OFF;
++              }
++              break;
++      case MC1N2_HPR_MIC2_SW:
++              if (value) {
++                      update.asHpOut[1].abSrcOnOff[0] = MCDRV_SRC0_MIC2_ON;
++              }
++              else {
++                      update.asHpOut[1].abSrcOnOff[0] = MCDRV_SRC0_MIC2_OFF;
++              }
++              break;
++      case MC1N2_HPR_MIC3_SW:
++              if (value) {
++                      update.asHpOut[1].abSrcOnOff[0] = MCDRV_SRC0_MIC3_ON;
++              }
++              else {
++                      update.asHpOut[1].abSrcOnOff[0] = MCDRV_SRC0_MIC3_OFF;
++              }
++              break;
++      case MC1N2_HPR_LINER_SW:
++              if (value) {
++                      update.asHpOut[1].abSrcOnOff[1] = MCDRV_SRC1_LINE1_R_ON;
++              }
++              else {
++                      update.asHpOut[1].abSrcOnOff[1] = MCDRV_SRC1_LINE1_R_OFF;
++              }
++              break;
++      case MC1N2_HPR_DACR_SW:
++              if (value) {
++                      update.asHpOut[1].abSrcOnOff[5] = MCDRV_SRC5_DAC_R_ON;
++              }
++              else {
++                      update.asHpOut[1].abSrcOnOff[5] = MCDRV_SRC5_DAC_R_OFF;
++              }
++              break;
++      case MC1N2_SPL_LINE_SW:
++      case MC1N2_SPL_LINE_SRC:
++              if (REG_CACHE_READ(MC1N2_SPL_LINE_SRC) == 0) {
++                      if (REG_CACHE_READ(MC1N2_SPL_LINE_SW)) {
++                              update.asSpOut[0].abSrcOnOff[1] = MCDRV_SRC1_LINE1_L_ON;
++                      }
++                      else {
++                              update.asSpOut[0].abSrcOnOff[1] = MCDRV_SRC1_LINE1_L_OFF;
++                      }
++              }
++              else {
++                      if (REG_CACHE_READ(MC1N2_SPL_LINE_SW)) {
++                              update.asSpOut[0].abSrcOnOff[1] = MCDRV_SRC1_LINE1_M_ON;
++                      }
++                      else {
++                              update.asSpOut[0].abSrcOnOff[1] = MCDRV_SRC1_LINE1_M_OFF;
++                      }
++              }
++              break;
++      case MC1N2_SPL_DAC_SW:
++      case MC1N2_SPL_DAC_SRC:
++              if (REG_CACHE_READ(MC1N2_SPL_DAC_SRC) == 0) {
++                      if (REG_CACHE_READ(MC1N2_SPL_DAC_SW)) {
++                              update.asSpOut[0].abSrcOnOff[5] = MCDRV_SRC5_DAC_L_ON;
++                      }
++                      else {
++                              update.asSpOut[0].abSrcOnOff[5] = MCDRV_SRC5_DAC_L_OFF;
++                      }
++              }
++              else {
++                      if (REG_CACHE_READ(MC1N2_SPL_DAC_SW)) {
++                              update.asSpOut[0].abSrcOnOff[5] = MCDRV_SRC5_DAC_M_ON;
++                      }
++                      else {
++                              update.asSpOut[0].abSrcOnOff[5] = MCDRV_SRC5_DAC_M_OFF;
++                      }
++              }
++              break;
++      case MC1N2_SPR_LINE_SW:
++      case MC1N2_SPR_LINE_SRC:
++              if (REG_CACHE_READ(MC1N2_SPR_LINE_SRC) == 0) {
++                      if (REG_CACHE_READ(MC1N2_SPR_LINE_SW)) {
++                              update.asSpOut[1].abSrcOnOff[1] = MCDRV_SRC1_LINE1_R_ON;
++                      }
++                      else {
++                              update.asSpOut[1].abSrcOnOff[1] = MCDRV_SRC1_LINE1_R_OFF;
++                      }
++              }
++              else {
++                      if (REG_CACHE_READ(MC1N2_SPR_LINE_SW)) {
++                              update.asSpOut[1].abSrcOnOff[1] = MCDRV_SRC1_LINE1_M_ON;
++                      }
++                      else {
++                              update.asSpOut[1].abSrcOnOff[1] = MCDRV_SRC1_LINE1_M_OFF;
++                      }
++              }
++              break;
++      case MC1N2_SPR_DAC_SW:
++      case MC1N2_SPR_DAC_SRC:
++              if (REG_CACHE_READ(MC1N2_SPR_DAC_SRC) == 0) {
++                      if (REG_CACHE_READ(MC1N2_SPR_DAC_SW)) {
++                              update.asSpOut[1].abSrcOnOff[5] = MCDRV_SRC5_DAC_R_ON;
++                      }
++                      else {
++                              update.asSpOut[1].abSrcOnOff[5] = MCDRV_SRC5_DAC_R_OFF;
++                      }
++              }
++              else {
++                      if (REG_CACHE_READ(MC1N2_SPR_DAC_SW)) {
++                              update.asSpOut[1].abSrcOnOff[5] = MCDRV_SRC5_DAC_M_ON;
++                      }
++                      else {
++                              update.asSpOut[1].abSrcOnOff[5] = MCDRV_SRC5_DAC_M_OFF;
++                      }
++              }
++              break;
++      case MC1N2_RC_MIC1_SW:
++              if (value) {
++                      update.asRcOut[0].abSrcOnOff[0] = MCDRV_SRC0_MIC1_ON;
++              }
++              else {
++                      update.asRcOut[0].abSrcOnOff[0] = MCDRV_SRC0_MIC1_OFF;
++              }
++              break;
++      case MC1N2_RC_MIC2_SW:
++              if (value) {
++                      update.asRcOut[0].abSrcOnOff[0] = MCDRV_SRC0_MIC2_ON;
++              }
++              else {
++                      update.asRcOut[0].abSrcOnOff[0] = MCDRV_SRC0_MIC2_OFF;
++              }
++              break;
++      case MC1N2_RC_MIC3_SW:
++              if (value) {
++                      update.asRcOut[0].abSrcOnOff[0] = MCDRV_SRC0_MIC3_ON;
++              }
++              else {
++                      update.asRcOut[0].abSrcOnOff[0] = MCDRV_SRC0_MIC3_OFF;
++              }
++              break;
++      case MC1N2_RC_LINEMONO_SW:
++              if (value) {
++                      update.asRcOut[0].abSrcOnOff[1] = MCDRV_SRC1_LINE1_M_ON;
++              }
++              else {
++                      update.asRcOut[0].abSrcOnOff[1] = MCDRV_SRC1_LINE1_M_OFF;
++              }
++              break;
++      case MC1N2_RC_DACL_SW:
++              if (value) {
++                      update.asRcOut[0].abSrcOnOff[5] = MCDRV_SRC5_DAC_L_ON;
++              }
++              else {
++                      update.asRcOut[0].abSrcOnOff[5] = MCDRV_SRC5_DAC_L_OFF;
++              }
++              break;
++      case MC1N2_RC_DACR_SW:
++              if (value) {
++                      update.asRcOut[0].abSrcOnOff[5] = MCDRV_SRC5_DAC_R_ON;
++              }
++              else {
++                      update.asRcOut[0].abSrcOnOff[5] = MCDRV_SRC5_DAC_R_OFF;
++              }
++              break;
++      case MC1N2_LOUT1L_MIC1_SW:
++              if (value) {
++                      update.asLout1[0].abSrcOnOff[0] = MCDRV_SRC0_MIC1_ON;
++              }
++              else {
++                      update.asLout1[0].abSrcOnOff[0] = MCDRV_SRC0_MIC1_OFF;
++              }
++              break;
++      case MC1N2_LOUT1L_MIC2_SW:
++              if (value) {
++                      update.asLout1[0].abSrcOnOff[0] = MCDRV_SRC0_MIC2_ON;
++              }
++              else {
++                      update.asLout1[0].abSrcOnOff[0] = MCDRV_SRC0_MIC2_OFF;
++              }
++              break;
++      case MC1N2_LOUT1L_MIC3_SW:
++              if (value) {
++                      update.asLout1[0].abSrcOnOff[0] = MCDRV_SRC0_MIC3_ON;
++              }
++              else {
++                      update.asLout1[0].abSrcOnOff[0] = MCDRV_SRC0_MIC3_OFF;
++              }
++              break;
++      case MC1N2_LOUT1L_LINE_SW:
++      case MC1N2_LOUT1L_LINE_SRC:
++              if (REG_CACHE_READ(MC1N2_LOUT1L_LINE_SRC) == 0) {
++                      if (REG_CACHE_READ(MC1N2_LOUT1L_LINE_SW)) {
++                              update.asLout1[0].abSrcOnOff[1] = MCDRV_SRC1_LINE1_L_ON;
++                      }
++                      else {
++                              update.asLout1[0].abSrcOnOff[1] = MCDRV_SRC1_LINE1_L_OFF;
++                      }
++              }
++              else {
++                      if (REG_CACHE_READ(MC1N2_LOUT1L_LINE_SW)) {
++                              update.asLout1[0].abSrcOnOff[1] = MCDRV_SRC1_LINE1_M_ON;
++                      }
++                      else {
++                              update.asLout1[0].abSrcOnOff[1] = MCDRV_SRC1_LINE1_M_OFF;
++                      }
++              }
++              break;
++      case MC1N2_LOUT1L_DAC_SW:
++      case MC1N2_LOUT1L_DAC_SRC:
++              if (REG_CACHE_READ(MC1N2_LOUT1L_DAC_SRC) == 0) {
++                      if (REG_CACHE_READ(MC1N2_LOUT1L_DAC_SW)) {
++                              update.asLout1[0].abSrcOnOff[5] = MCDRV_SRC5_DAC_L_ON;
++                      }
++                      else {
++                              update.asLout1[0].abSrcOnOff[5] = MCDRV_SRC5_DAC_L_OFF;
++                      }
++              }
++              else {
++                      if (value) {
++                              update.asLout1[0].abSrcOnOff[5] = MCDRV_SRC5_DAC_M_ON;
++                      }
++                      else {
++                              update.asLout1[0].abSrcOnOff[5] = MCDRV_SRC5_DAC_M_OFF;
++                      }
++              }
++              break;
++      case MC1N2_LOUT1R_MIC1_SW:
++              if (value) {
++                      update.asLout1[1].abSrcOnOff[0] = MCDRV_SRC0_MIC1_ON;
++              }
++              else {
++                      update.asLout1[1].abSrcOnOff[0] = MCDRV_SRC0_MIC1_OFF;
++              }
++              break;
++      case MC1N2_LOUT1R_MIC2_SW:
++              if (value) {
++                      update.asLout1[1].abSrcOnOff[0] = MCDRV_SRC0_MIC2_ON;
++              }
++              else {
++                      update.asLout1[1].abSrcOnOff[0] = MCDRV_SRC0_MIC2_OFF;
++              }
++              break;
++      case MC1N2_LOUT1R_MIC3_SW:
++              if (value) {
++                      update.asLout1[1].abSrcOnOff[0] = MCDRV_SRC0_MIC3_ON;
++              }
++              else {
++                      update.asLout1[1].abSrcOnOff[0] = MCDRV_SRC0_MIC3_OFF;
++              }
++              break;
++      case MC1N2_LOUT1R_LINER_SW:
++              if (value) {
++                      update.asLout1[1].abSrcOnOff[1] = MCDRV_SRC1_LINE1_R_ON;
++              }
++              else {
++                      update.asLout1[1].abSrcOnOff[1] = MCDRV_SRC1_LINE1_R_OFF;
++              }
++              break;
++      case MC1N2_LOUT1R_DACR_SW:
++              if (value) {
++                      update.asLout1[1].abSrcOnOff[5] = MCDRV_SRC5_DAC_R_ON;
++              }
++              else {
++                      update.asLout1[1].abSrcOnOff[5] = MCDRV_SRC5_DAC_R_OFF;
++              }
++              break;
++      case MC1N2_LOUT2L_MIC1_SW:
++              if (value) {
++                      update.asLout2[0].abSrcOnOff[0] = MCDRV_SRC0_MIC1_ON;
++              }
++              else {
++                      update.asLout2[0].abSrcOnOff[0] = MCDRV_SRC0_MIC1_OFF;
++              }
++              break;
++      case MC1N2_LOUT2L_MIC2_SW:
++              if (value) {
++                      update.asLout2[0].abSrcOnOff[0] = MCDRV_SRC0_MIC2_ON;
++              }
++              else {
++                      update.asLout2[0].abSrcOnOff[0] = MCDRV_SRC0_MIC2_OFF;
++              }
++              break;
++      case MC1N2_LOUT2L_MIC3_SW:
++              if (value) {
++                      update.asLout2[0].abSrcOnOff[0] = MCDRV_SRC0_MIC3_ON;
++              }
++              else {
++                      update.asLout2[0].abSrcOnOff[0] = MCDRV_SRC0_MIC3_OFF;
++              }
++              break;
++      case MC1N2_LOUT2L_LINE_SW:
++      case MC1N2_LOUT2L_LINE_SRC:
++              if (REG_CACHE_READ(MC1N2_LOUT2L_LINE_SRC) == 0) {
++                      if (REG_CACHE_READ(MC1N2_LOUT2L_LINE_SW)) {
++                              update.asLout2[0].abSrcOnOff[1] = MCDRV_SRC1_LINE1_L_ON;
++                      }
++                      else {
++                              update.asLout2[0].abSrcOnOff[1] = MCDRV_SRC1_LINE1_L_OFF;
++                      }
++              }
++              else {
++                      if (REG_CACHE_READ(MC1N2_LOUT2L_LINE_SW)) {
++                              update.asLout2[0].abSrcOnOff[1] = MCDRV_SRC1_LINE1_M_ON;
++                      }
++                      else {
++                              update.asLout2[0].abSrcOnOff[1] = MCDRV_SRC1_LINE1_M_OFF;
++                      }
++              }
++              break;
++      case MC1N2_LOUT2L_DAC_SW:
++      case MC1N2_LOUT2L_DAC_SRC:
++              if (REG_CACHE_READ(MC1N2_LOUT2L_DAC_SRC) == 0) {
++                      if (REG_CACHE_READ(MC1N2_LOUT2L_DAC_SW)) {
++                              update.asLout2[0].abSrcOnOff[5] = MCDRV_SRC5_DAC_L_ON;
++                      }
++                      else {
++                              update.asLout2[0].abSrcOnOff[5] = MCDRV_SRC5_DAC_L_OFF;
++                      }
++              }
++              else {
++                      if (REG_CACHE_READ(MC1N2_LOUT2L_DAC_SW)) {
++                              update.asLout2[0].abSrcOnOff[5] = MCDRV_SRC5_DAC_M_ON;
++                      }
++                      else {
++                              update.asLout2[0].abSrcOnOff[5] = MCDRV_SRC5_DAC_M_OFF;
++                      }
++              }
++              break;
++      case MC1N2_LOUT2R_MIC1_SW:
++              if (value) {
++                      update.asLout2[1].abSrcOnOff[0] = MCDRV_SRC0_MIC1_ON;
++              }
++              else {
++                      update.asLout2[1].abSrcOnOff[0] = MCDRV_SRC0_MIC1_OFF;
++              }
++              break;
++      case MC1N2_LOUT2R_MIC2_SW:
++              if (value) {
++                      update.asLout2[1].abSrcOnOff[0] = MCDRV_SRC0_MIC2_ON;
++              }
++              else {
++                      update.asLout2[1].abSrcOnOff[0] = MCDRV_SRC0_MIC2_OFF;
++              }
++              break;
++      case MC1N2_LOUT2R_MIC3_SW:
++              if (value) {
++                      update.asLout2[1].abSrcOnOff[0] = MCDRV_SRC0_MIC3_ON;
++              }
++              else {
++                      update.asLout2[1].abSrcOnOff[0] = MCDRV_SRC0_MIC3_OFF;
++              }
++              break;
++      case MC1N2_LOUT2R_LINER_SW:
++              if (value) {
++                      update.asLout2[1].abSrcOnOff[1] = MCDRV_SRC1_LINE1_R_ON;
++              }
++              else {
++                      update.asLout2[1].abSrcOnOff[1] = MCDRV_SRC1_LINE1_R_OFF;
++              }
++              break;
++      case MC1N2_LOUT2R_DACR_SW:
++              if (value) {
++                      update.asLout2[1].abSrcOnOff[5] = MCDRV_SRC5_DAC_R_ON;
++              }
++              else {
++                      update.asLout2[1].abSrcOnOff[5] = MCDRV_SRC5_DAC_R_OFF;
++              }
++              break;
++      case MC1N2_DACMAIN_SRC:
++      case MC1N2_DACVOICE_SRC:
++      case MC1N2_DIT0_SRC:
++      case MC1N2_DIT1_SRC:
++      case MC1N2_DIT2_SRC:
++              if (reg == MC1N2_DACMAIN_SRC) {
++                      pch = &update.asDac[0];
++              }
++              else if (reg == MC1N2_DACVOICE_SRC) {
++                      pch = &update.asDac[1];
++              }
++              else if (reg == MC1N2_DIT0_SRC) {
++                      pch = &update.asDit0[0];
++              }
++              else if (reg == MC1N2_DIT1_SRC) {
++                      pch = &update.asDit1[0];
++              }
++              else if (reg == MC1N2_DIT2_SRC) {
++                      pch = &update.asDit2[0];
++              }
++
++              switch (value) {
++              case MC1N2_DSOURCE_OFF:
++                      pch->abSrcOnOff[3] =
++                              MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                      pch->abSrcOnOff[4] = MCDRV_SRC4_ADC0_OFF | MCDRV_SRC4_PDM_OFF;
++                      pch->abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_OFF;
++                      break;
++              case MC1N2_DSOURCE_ADC: /* ADC */
++                      pch->abSrcOnOff[3] =
++                              MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_ADC) {
++                              pch->abSrcOnOff[4] = MCDRV_SRC4_ADC0_OFF | MCDRV_SRC4_PDM_OFF;
++                              pch->abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              if (REG_CACHE_READ(MC1N2_ADC_PDM_SEL)) {
++                                      pch->abSrcOnOff[4] = MCDRV_SRC4_ADC0_OFF | MCDRV_SRC4_PDM_ON;
++                              }
++                              else {
++                                      pch->abSrcOnOff[4] = MCDRV_SRC4_ADC0_ON | MCDRV_SRC4_PDM_OFF;
++                              }
++                              pch->abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              case MC1N2_DSOURCE_DIR0: /* DIR0 */
++                      pch->abSrcOnOff[4] = MCDRV_SRC4_ADC0_OFF | MCDRV_SRC4_PDM_OFF;
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_DIR0) {
++                              pch->abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                              pch->abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              pch->abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_ON | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                              pch->abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              case MC1N2_DSOURCE_DIR1: /* DIR1 */
++                      pch->abSrcOnOff[4] = MCDRV_SRC4_ADC0_OFF | MCDRV_SRC4_PDM_OFF;
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_DIR1) {
++                              pch->abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                              pch->abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              pch->abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_ON | MCDRV_SRC3_DIR2_OFF;
++                              pch->abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              case MC1N2_DSOURCE_DIR2: /* DIR2 */
++                      pch->abSrcOnOff[4] = MCDRV_SRC4_ADC0_OFF | MCDRV_SRC4_PDM_OFF;
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_DIR2) {
++                              pch->abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                              pch->abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              pch->abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_ON;
++                              pch->abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              case MC1N2_DSOURCE_MIX: /* MIX */
++                      pch->abSrcOnOff[4] = MCDRV_SRC4_ADC0_OFF | MCDRV_SRC4_PDM_OFF;
++                      pch->abSrcOnOff[3] =
++                              MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_MIX) {
++                              pch->abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              pch->abSrcOnOff[6] = MCDRV_SRC6_MIX_ON | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              }
++              break;
++      case MC1N2_AE_SRC:
++      case MC1N2_ADC_PDM_SEL:
++              switch (REG_CACHE_READ(MC1N2_AE_SRC)) {
++              case MC1N2_DSOURCE_OFF:
++                      update.asAe[0].abSrcOnOff[4] = MCDRV_SRC4_ADC0_OFF | MCDRV_SRC4_PDM_OFF;
++                      update.asAe[0].abSrcOnOff[3] =
++                              MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                      update.asAe[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF;
++                      break;
++              case MC1N2_DSOURCE_ADC: /* ADC */
++                      if (REG_CACHE_READ(MC1N2_ADC_PDM_SEL)) {
++                              update.asAe[0].abSrcOnOff[4] = MCDRV_SRC4_ADC0_OFF | MCDRV_SRC4_PDM_ON;
++                      }
++                      else {
++                              update.asAe[0].abSrcOnOff[4] = MCDRV_SRC4_ADC0_ON | MCDRV_SRC4_PDM_OFF;
++                      }
++                      update.asAe[0].abSrcOnOff[3] =
++                              MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                      update.asAe[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF;
++                      break;
++              case MC1N2_DSOURCE_DIR0: /* DIR0 */
++                      update.asAe[0].abSrcOnOff[4] = MCDRV_SRC4_ADC0_OFF | MCDRV_SRC4_PDM_OFF;
++                      update.asAe[0].abSrcOnOff[3] =
++                              MCDRV_SRC3_DIR0_ON | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                      update.asAe[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF;
++                      break;
++              case MC1N2_DSOURCE_DIR1:/* DIR1 */
++                      update.asAe[0].abSrcOnOff[4] = MCDRV_SRC4_ADC0_OFF | MCDRV_SRC4_PDM_OFF;
++                      update.asAe[0].abSrcOnOff[3] =
++                              MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_ON | MCDRV_SRC3_DIR2_OFF;
++                      update.asAe[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF;
++                      break;
++              case MC1N2_DSOURCE_DIR2:/* DIR2 */
++                      update.asAe[0].abSrcOnOff[4] = MCDRV_SRC4_ADC0_OFF | MCDRV_SRC4_PDM_OFF;
++                      update.asAe[0].abSrcOnOff[3] =
++                              MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_ON;
++                      update.asAe[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF;
++                      break;
++              case MC1N2_DSOURCE_MIX: /* MIX */
++                      update.asAe[0].abSrcOnOff[4] = MCDRV_SRC4_ADC0_OFF | MCDRV_SRC4_PDM_OFF;
++                      update.asAe[0].abSrcOnOff[3] =
++                              MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                      update.asAe[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_ON;
++                      break;
++              }
++
++              switch (REG_CACHE_READ(MC1N2_DACMAIN_SRC)) {
++              case MC1N2_DSOURCE_ADC: /* ADC */
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_ADC) {
++                              update.asDac[0].abSrcOnOff[4] = MCDRV_SRC4_ADC0_OFF | MCDRV_SRC4_PDM_OFF;
++                              update.asDac[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              if (REG_CACHE_READ(MC1N2_ADC_PDM_SEL)) {
++                                      update.asDac[0].abSrcOnOff[4] = MCDRV_SRC4_ADC0_OFF | MCDRV_SRC4_PDM_ON;
++                              }
++                              else {
++                                      update.asDac[0].abSrcOnOff[4] = MCDRV_SRC4_ADC0_ON | MCDRV_SRC4_PDM_OFF;
++                              }
++                              update.asDac[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              case MC1N2_DSOURCE_DIR0: /* DIR0 */
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_DIR0) {
++                              update.asDac[0].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                              update.asDac[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              update.asDac[0].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_ON | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                              update.asDac[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              case MC1N2_DSOURCE_DIR1: /* DIR1 */
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_DIR1) {
++                              update.asDac[0].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                              update.asDac[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              update.asDac[0].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_ON | MCDRV_SRC3_DIR2_OFF;
++                              update.asDac[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              case MC1N2_DSOURCE_DIR2: /* DIR2 */
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_DIR2) {
++                              update.asDac[0].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                              update.asDac[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              update.asDac[0].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_ON;
++                              update.asDac[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              case MC1N2_DSOURCE_MIX: /* MIX */
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_MIX) {
++                              update.asDac[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              update.asDac[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_ON | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              }
++
++              switch (REG_CACHE_READ(MC1N2_DACVOICE_SRC)) {
++              case MC1N2_DSOURCE_ADC: /* ADC */
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_ADC) {
++                              update.asDac[1].abSrcOnOff[4] = MCDRV_SRC4_ADC0_OFF | MCDRV_SRC4_PDM_OFF;
++                              update.asDac[1].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              if (REG_CACHE_READ(MC1N2_ADC_PDM_SEL)) {
++                                      update.asDac[1].abSrcOnOff[4] = MCDRV_SRC4_ADC0_OFF | MCDRV_SRC4_PDM_ON;
++                              }
++                              else {
++                                      update.asDac[1].abSrcOnOff[4] = MCDRV_SRC4_ADC0_ON | MCDRV_SRC4_PDM_OFF;
++                              }
++                              update.asDac[1].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              case MC1N2_DSOURCE_DIR0: /* DIR0 */
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_DIR0) {
++                              update.asDac[1].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                              update.asDac[1].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              update.asDac[1].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_ON | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                              update.asDac[1].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              case MC1N2_DSOURCE_DIR1: /* DIR1 */
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_DIR1) {
++                              update.asDac[1].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                              update.asDac[1].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              update.asDac[1].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_ON | MCDRV_SRC3_DIR2_OFF;
++                              update.asDac[1].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              case MC1N2_DSOURCE_DIR2: /* DIR2 */
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_DIR2) {
++                              update.asDac[1].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                              update.asDac[1].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              update.asDac[1].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_ON;
++                              update.asDac[1].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              case MC1N2_DSOURCE_MIX: /* MIX */
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_MIX) {
++                              update.asDac[1].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              update.asDac[1].abSrcOnOff[6] = MCDRV_SRC6_MIX_ON | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              }
++
++              switch (REG_CACHE_READ(MC1N2_DIT0_SRC)) {
++              case MC1N2_DSOURCE_ADC: /* ADC */
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_ADC) {
++                              update.asDit0[0].abSrcOnOff[4] = MCDRV_SRC4_ADC0_OFF | MCDRV_SRC4_PDM_OFF;
++                              update.asDit0[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              if (REG_CACHE_READ(MC1N2_ADC_PDM_SEL)) {
++                                      update.asDit0[0].abSrcOnOff[4] = MCDRV_SRC4_ADC0_OFF | MCDRV_SRC4_PDM_ON;
++                              }
++                              else {
++                                      update.asDit0[0].abSrcOnOff[4] = MCDRV_SRC4_ADC0_ON | MCDRV_SRC4_PDM_OFF;
++                              }
++                              update.asDit0[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              case MC1N2_DSOURCE_DIR0: /* DIR0 */
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_DIR0) {
++                              update.asDit0[0].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                              update.asDit0[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              update.asDit0[0].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_ON | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                              update.asDit0[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              case MC1N2_DSOURCE_DIR1: /* DIR1 */
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_DIR1) {
++                              update.asDit0[0].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                              update.asDit0[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              update.asDit0[0].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_ON | MCDRV_SRC3_DIR2_OFF;
++                              update.asDit0[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              case MC1N2_DSOURCE_DIR2: /* DIR2 */
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_DIR2) {
++                              update.asDit0[0].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                              update.asDit0[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              update.asDit0[0].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_ON;
++                              update.asDit0[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              case MC1N2_DSOURCE_MIX: /* MIX */
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_MIX) {
++                              update.asDit0[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              update.asDit0[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_ON | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              }
++
++              switch (REG_CACHE_READ(MC1N2_DIT1_SRC)) {
++              case MC1N2_DSOURCE_ADC: /* ADC */
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_ADC) {
++                              update.asDit1[0].abSrcOnOff[4] = MCDRV_SRC4_ADC0_OFF | MCDRV_SRC4_PDM_OFF;
++                              update.asDit1[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              if (REG_CACHE_READ(MC1N2_ADC_PDM_SEL)) {
++                                      update.asDit1[0].abSrcOnOff[4] = MCDRV_SRC4_ADC0_OFF | MCDRV_SRC4_PDM_ON;
++                              }
++                              else {
++                                      update.asDit1[0].abSrcOnOff[4] = MCDRV_SRC4_ADC0_ON | MCDRV_SRC4_PDM_OFF;
++                              }
++                              update.asDit1[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              case MC1N2_DSOURCE_DIR0: /* DIR0 */
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_DIR0) {
++                              update.asDit1[0].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                              update.asDit1[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              update.asDit1[0].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_ON | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                              update.asDit1[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              case MC1N2_DSOURCE_DIR1: /* DIR1 */
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_DIR1) {
++                              update.asDit1[0].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                              update.asDit1[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              update.asDit1[0].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_ON | MCDRV_SRC3_DIR2_OFF;
++                              update.asDit1[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              case MC1N2_DSOURCE_DIR2: /* DIR2 */
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_DIR2) {
++                              update.asDit1[0].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                              update.asDit1[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              update.asDit1[0].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_ON;
++                              update.asDit1[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              case MC1N2_DSOURCE_MIX: /* MIX */
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_MIX) {
++                              update.asDit1[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              update.asDit1[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_ON | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              }
++
++              switch (REG_CACHE_READ(MC1N2_DIT2_SRC)) {
++              case MC1N2_DSOURCE_ADC: /* ADC */
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_ADC) {
++                              update.asDit2[0].abSrcOnOff[4] = MCDRV_SRC4_ADC0_OFF | MCDRV_SRC4_PDM_OFF;
++                              update.asDit2[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              if (REG_CACHE_READ(MC1N2_ADC_PDM_SEL)) {
++                                      update.asDit2[0].abSrcOnOff[4] = MCDRV_SRC4_ADC0_OFF | MCDRV_SRC4_PDM_ON;
++                              }
++                              else {
++                                      update.asDit2[0].abSrcOnOff[4] = MCDRV_SRC4_ADC0_ON | MCDRV_SRC4_PDM_OFF;
++                              }
++                              update.asDit2[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              case MC1N2_DSOURCE_DIR0: /* DIR0 */
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_DIR0) {
++                              update.asDit2[0].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                              update.asDit2[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              update.asDit2[0].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_ON | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                              update.asDit2[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              case MC1N2_DSOURCE_DIR1: /* DIR1 */
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_DIR1) {
++                              update.asDit2[0].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                              update.asDit2[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              update.asDit2[0].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_ON | MCDRV_SRC3_DIR2_OFF;
++                              update.asDit2[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              case MC1N2_DSOURCE_DIR2: /* DIR2 */
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_DIR2) {
++                              update.asDit2[0].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_OFF;
++                              update.asDit2[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              update.asDit2[0].abSrcOnOff[3] =
++                                      MCDRV_SRC3_DIR0_OFF | MCDRV_SRC3_DIR1_OFF | MCDRV_SRC3_DIR2_ON;
++                              update.asDit2[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              case MC1N2_DSOURCE_MIX: /* MIX */
++                      if (REG_CACHE_READ(MC1N2_AE_SRC) == MC1N2_DSOURCE_MIX) {
++                              update.asDit2[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_OFF | MCDRV_SRC6_AE_ON;
++                      }
++                      else {
++                              update.asDit2[0].abSrcOnOff[6] = MCDRV_SRC6_MIX_ON | MCDRV_SRC6_AE_OFF;
++                      }
++                      break;
++              }
++
++              break;
++      case MC1N2_DMIX_ADC_SW:
++              if (value) {
++                      if (REG_CACHE_READ(MC1N2_ADC_PDM_SEL)) {
++                              update.asMix[0].abSrcOnOff[4] = MCDRV_SRC4_ADC0_OFF | MCDRV_SRC4_PDM_ON;
++                      }
++                      else {
++                              update.asMix[0].abSrcOnOff[4] = MCDRV_SRC4_ADC0_ON | MCDRV_SRC4_PDM_OFF;
++                      }
++              }
++              else {
++                      update.asMix[0].abSrcOnOff[4] = MCDRV_SRC4_ADC0_OFF | MCDRV_SRC4_PDM_OFF;
++              }
++              break;
++      case MC1N2_DMIX_DIR0_SW:
++              if (value) {
++                      update.asMix[0].abSrcOnOff[3] = MCDRV_SRC3_DIR0_ON;
++              }
++              else {
++                      update.asMix[0].abSrcOnOff[3] = MCDRV_SRC3_DIR0_OFF;
++              }
++              break;
++      case MC1N2_DMIX_DIR1_SW:
++              if (value) {
++                      update.asMix[0].abSrcOnOff[3] = MCDRV_SRC3_DIR1_ON;
++              }
++              else {
++                      update.asMix[0].abSrcOnOff[3] = MCDRV_SRC3_DIR1_OFF;
++              }
++              break;
++      case MC1N2_DMIX_DIR2_SW:
++              if (value) {
++                      update.asMix[0].abSrcOnOff[3] = MCDRV_SRC3_DIR2_ON;
++              }
++              else {
++                      update.asMix[0].abSrcOnOff[3] = MCDRV_SRC3_DIR2_OFF;
++              }
++              break;
++      case MC1N2_AE_PARAM_SEL:
++              switch (value) {
++              case MC1N2_AE_PARAM_1:
++                      pae = &sAeInfo_1;
++                      break;
++              case MC1N2_AE_PARAM_2:
++                      pae = &sAeInfo_2;
++                      break;
++              case MC1N2_AE_PARAM_3:
++                      pae = &sAeInfo_3;
++                      break;
++              case MC1N2_AE_PARAM_4:
++                      pae = &sAeInfo_4;
++                      break;
++              case MC1N2_AE_PARAM_5:
++                      pae = &sAeInfo_5;
++                      break;
++              default:
++                      pae = NULL;
++                      break;
++              }
++              err = _McDrv_Ctrl(MCDRV_SET_AUDIOENGINE, pae, 0x1FF);
++              return err;
++              break;
++      case MC1N2_MICBIAS1:
++              if (value) {
++                      update.asBias[0].abSrcOnOff[0] = MCDRV_SRC0_MIC1_ON;
++              }
++              else {
++                      update.asBias[0].abSrcOnOff[0] = MCDRV_SRC0_MIC1_OFF;
++              }
++              break;
++      case MC1N2_MICBIAS2:
++              if (value) {
++                      update.asBias[0].abSrcOnOff[0] = MCDRV_SRC0_MIC2_ON;
++              }
++              else {
++                      update.asBias[0].abSrcOnOff[0] = MCDRV_SRC0_MIC2_OFF;
++              }
++              break;
++      case MC1N2_MICBIAS3:
++              if (value) {
++                      update.asBias[0].abSrcOnOff[0] = MCDRV_SRC0_MIC3_ON;
++              }
++              else {
++                      update.asBias[0].abSrcOnOff[0] = MCDRV_SRC0_MIC3_OFF;
++              }
++              break;
++      }
++
++      mc1n2_hwdep_ioctl_set_path(codec, &update, 0);
++      err = _McDrv_Ctrl(MCDRV_SET_PATH, &update, 0);
++
++      return err;
++}
++
++static int mc1n2_write_reg(struct snd_soc_codec *codec,
++                         unsigned int reg, unsigned int value)
++{
++      int err;
++
++#ifdef CONFIG_SND_SOC_PM_RUNTIME
++      pm_runtime_get_sync(codec->dev);
++#endif
++
++      if (reg < MC1N2_N_VOL_REG) {
++              err = write_reg_vol(codec, reg, value);
++      }
++      else {
++              err = write_reg_path(codec, reg, value);
++      }
++#ifdef CONFIG_SND_SOC_PM_RUNTIME
++      pm_runtime_mark_last_busy(codec->dev);
++      pm_runtime_put_autosuspend(codec->dev);
++#endif
++
++      return err;
++}
++
++static int mc1n2_get_codec_status(struct snd_kcontrol *kcontrol,
++      struct snd_ctl_elem_value *ucontrol)
++{
++
++      return 0;
++}
++
++static int mc1n2_set_codec_status(struct snd_kcontrol *kcontrol,
++      struct snd_ctl_elem_value *ucontrol)
++{
++      struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++      struct mc1n2_data *mc1n2 = snd_soc_codec_get_drvdata(codec);
++      SINT16 *vol = (SINT16 *)&mc1n2->vol_store;
++
++      int control_data = ucontrol->value.integer.value[0];
++      int err, i;
++
++      dev_info(codec->dev, "%s: Recovery [%d]\n", __func__, control_data);
++
++      switch(control_data)
++      {
++      case CMD_CODEC_EMERGENCY_RECOVERY:
++              mutex_lock(&mc1n2->mutex);
++
++              mc1n2_set_mclk_source(1);
++
++              /* store parameters */
++              for (i = 0; i < MC1N2_N_INFO_STORE; i++) {
++                      struct mc1n2_info_store *store
++                                              = &mc1n2_info_store_tbl[i];
++                      if (store->get) {
++                              err = _McDrv_Ctrl(store->get,
++                                      (void *)mc1n2 + store->offset, 0);
++                              if (err != MCDRV_SUCCESS) {
++                                      dev_err(codec->dev,
++                                              "%d: Error in MCDRV_GET\n",
++                                              err);
++                              }
++                      }
++              }
++
++              err = _McDrv_Ctrl(MCDRV_TERM, NULL, 0);
++              if (err != MCDRV_SUCCESS)
++                      dev_err(codec->dev, "%d: Error in MCDRV_TERM\n", err);
++
++              err = _McDrv_Ctrl(MCDRV_INIT, &mc1n2->setup.init, 0);
++              if (err != MCDRV_SUCCESS)
++                      dev_err(codec->dev, "%d: Error in MCDRV_INIT\n", err);
++
++              /* restore parameters */
++              for (i = 0; i < sizeof(MCDRV_VOL_INFO)/sizeof(SINT16);
++                                                              i++, vol++) {
++                      *vol |= 0x0001;
++              }
++
++              for (i = 0; i < MC1N2_N_INFO_STORE; i++) {
++                      struct mc1n2_info_store *store =
++                                              &mc1n2_info_store_tbl[i];
++                      if (store->set) {
++                              err = _McDrv_Ctrl(store->set,
++                                      (void *) mc1n2 + store->offset,
++                                       store->flags);
++
++                              if (err != MCDRV_SUCCESS) {
++                                      dev_err(codec->dev,
++                                              "%d: Error in MCDRV_Set\n",
++                                              err);
++                              }
++                      }
++              }
++
++              err = mc1n2_update_clock(mc1n2);
++              if (err != MCDRV_SUCCESS) {
++                      dev_err(codec->dev,
++                              "%d: Error in mc1n2_update_clock\n", err);
++              }
++
++              mutex_unlock(&mc1n2->mutex);
++
++              dev_info(codec->dev, "%s: Recovery Done\n", __func__);
++              break;
++
++      default:
++              break;
++      }
++
++      return 0;
++}
++
++static const DECLARE_TLV_DB_SCALE(mc1n2_tlv_digital, -7500, 100, 1);
++static const DECLARE_TLV_DB_SCALE(mc1n2_tlv_adc, -2850, 150, 1);
++static const DECLARE_TLV_DB_SCALE(mc1n2_tlv_ain, -3150, 150, 1);
++static const DECLARE_TLV_DB_SCALE(mc1n2_tlv_aout, -3100, 100, 1);
++static const DECLARE_TLV_DB_SCALE(mc1n2_tlv_micgain, 1500, 500, 0);
++
++static unsigned int mc1n2_tlv_hpsp[] = {
++      TLV_DB_RANGE_HEAD(5),
++      0, 2, TLV_DB_SCALE_ITEM(-4400, 800, 1),
++      2, 3, TLV_DB_SCALE_ITEM(-2800, 400, 0),
++      3, 7, TLV_DB_SCALE_ITEM(-2400, 200, 0),
++      7, 15, TLV_DB_SCALE_ITEM(-1600, 100, 0),
++      15, 31, TLV_DB_SCALE_ITEM(-800, 50, 0),
++};
++
++static unsigned int mc1n2_tlv_hpgain[] = {
++      TLV_DB_RANGE_HEAD(2),
++      0, 2, TLV_DB_SCALE_ITEM(0, 150, 0),
++      2, 3, TLV_DB_SCALE_ITEM(300, 300, 0),
++};
++
++static const char *codec_status_control[] = {
++        "REC_OFF", "REC_ON", "RESET_ON", "RESET_OFF"
++};
++
++static const struct soc_enum path_control_enum[] = {
++        SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(codec_status_control), codec_status_control),
++};
++
++static const struct snd_kcontrol_new mc1n2_snd_controls[] = {
++      /*
++       * digital volumes and mute switches
++       */
++      SOC_DOUBLE_TLV("AD Digital Volume",
++                     MC1N2_DVOL_AD0, 0, 8, 93, 0, mc1n2_tlv_digital),
++      SOC_DOUBLE("AD Digital Switch",
++                 MC1N2_DVOL_AD0, 7, 15, 1, 0),
++
++      SOC_DOUBLE_TLV("AENG6 Volume",
++                     MC1N2_DVOL_AENG6, 0, 8, 93, 0, mc1n2_tlv_digital),
++      SOC_DOUBLE("AENG6 Switch",
++                 MC1N2_DVOL_AENG6, 7, 15, 1, 0),
++
++      SOC_DOUBLE_TLV("PDM Volume",
++                     MC1N2_DVOL_PDM, 0, 8, 93, 0, mc1n2_tlv_digital),
++      SOC_DOUBLE("PDM Switch",
++                 MC1N2_DVOL_PDM, 7, 15, 1, 0),
++
++      SOC_DOUBLE_TLV("DIR#0 Volume",
++                     MC1N2_DVOL_DIR0, 0, 8, 93, 0, mc1n2_tlv_digital),
++      SOC_DOUBLE("DIR#0 Switch",
++                 MC1N2_DVOL_DIR0, 7, 15, 1, 0),
++
++      SOC_DOUBLE_TLV("DIR#1 Volume",
++                     MC1N2_DVOL_DIR1, 0, 8, 93, 0, mc1n2_tlv_digital),
++      SOC_DOUBLE("DIR#1 Switch",
++                 MC1N2_DVOL_DIR1, 7, 15, 1, 0),
++
++      SOC_DOUBLE_TLV("DIR#2 Volume",
++                     MC1N2_DVOL_DIR2, 0, 8, 93, 0, mc1n2_tlv_digital),
++      SOC_DOUBLE("DIR#2 Switch",
++                 MC1N2_DVOL_DIR2, 7, 15, 1, 0),
++
++      SOC_DOUBLE_TLV("AD ATT Volume",
++                     MC1N2_DVOL_AD0_ATT, 0, 8, 93, 0, mc1n2_tlv_digital),
++      SOC_DOUBLE("AD ATT Switch",
++                 MC1N2_DVOL_AD0_ATT, 7, 15, 1, 0),
++
++      SOC_DOUBLE_TLV("DIR#0 ATT Volume",
++                     MC1N2_DVOL_DIR0_ATT, 0, 8, 93, 0, mc1n2_tlv_digital),
++      SOC_DOUBLE("DIR#0 ATT Switch",
++                 MC1N2_DVOL_DIR0_ATT, 7, 15, 1, 0),
++
++      SOC_DOUBLE_TLV("DIR#1 ATT Volume",
++                     MC1N2_DVOL_DIR1_ATT, 0, 8, 93, 0, mc1n2_tlv_digital),
++      SOC_DOUBLE("DIR#1 ATT Switch",
++                 MC1N2_DVOL_DIR1_ATT, 7, 15, 1, 0),
++
++      SOC_DOUBLE_TLV("DIR#2 ATT Volume",
++                     MC1N2_DVOL_DIR2_ATT, 0, 8, 93, 0, mc1n2_tlv_digital),
++      SOC_DOUBLE("DIR#2 ATT Switch",
++                 MC1N2_DVOL_DIR2_ATT, 7, 15, 1, 0),
++
++      SOC_DOUBLE_TLV("Side Tone Playback Volume",
++                     MC1N2_DVOL_SIDETONE, 0, 8, 93, 0, mc1n2_tlv_digital),
++      SOC_DOUBLE("Side Tone Playback Switch",
++                 MC1N2_DVOL_SIDETONE, 7, 15, 1, 0),
++
++      SOC_DOUBLE_TLV("Master Playback Volume",
++                     MC1N2_DVOL_DAC_MASTER, 0, 8, 93, 0, mc1n2_tlv_digital),
++      SOC_DOUBLE("Master Playback Switch",
++                 MC1N2_DVOL_DAC_MASTER, 7, 15, 1, 0),
++
++      SOC_DOUBLE_TLV("Voice Playback Volume",
++                     MC1N2_DVOL_DAC_VOICE, 0, 8, 93, 0, mc1n2_tlv_digital),
++      SOC_DOUBLE("Voice Playback Switch",
++                 MC1N2_DVOL_DAC_VOICE, 7, 15, 1, 0),
++
++      SOC_DOUBLE_TLV("DAC Playback Volume",
++                     MC1N2_DVOL_DAC_ATT, 0, 8, 93, 0, mc1n2_tlv_digital),
++      SOC_DOUBLE("DAC Playback Switch",
++                 MC1N2_DVOL_DAC_ATT, 7, 15, 1, 0),
++
++      SOC_DOUBLE_TLV("DIT#0 Capture Volume",
++                     MC1N2_DVOL_DIT0, 0, 8, 93, 0, mc1n2_tlv_digital),
++      SOC_DOUBLE("DIT#0 Capture Switch",
++                 MC1N2_DVOL_DIT0, 7, 15, 1, 0),
++
++      SOC_DOUBLE_TLV("DIT#1 Capture Volume",
++                     MC1N2_DVOL_DIT1, 0, 8, 93, 0, mc1n2_tlv_digital),
++      SOC_DOUBLE("DIT#1 Capture Switch",
++                 MC1N2_DVOL_DIT1, 7, 15, 1, 0),
++
++      SOC_DOUBLE_TLV("DIT#2 Capture Volume",
++                     MC1N2_DVOL_DIT2, 0, 8, 93, 0, mc1n2_tlv_digital),
++      SOC_DOUBLE("DIT#2 Capture Switch",
++                 MC1N2_DVOL_DIT2, 7, 15, 1, 0),
++
++      /*
++       * analog volumes and mute switches
++       */
++      SOC_DOUBLE_TLV("AD Analog Volume",
++                     MC1N2_AVOL_AD0, 0, 8, 31, 0, mc1n2_tlv_adc),
++      SOC_DOUBLE("AD Analog Switch",
++                 MC1N2_AVOL_AD0, 7, 15, 1, 0),
++
++      SOC_DOUBLE_TLV("Line Bypass Playback Volume",
++                     MC1N2_AVOL_LIN1, 0, 8, 31, 0, mc1n2_tlv_ain),
++      SOC_DOUBLE("Line Bypass Playback Switch",
++                 MC1N2_AVOL_LIN1, 7, 15, 1, 0),
++
++      SOC_SINGLE_TLV("Mic 1 Bypass Playback Volume",
++                     MC1N2_AVOL_MIC1, 0, 31, 0, mc1n2_tlv_ain),
++      SOC_SINGLE("Mic 1 Bypass Playback Switch",
++                 MC1N2_AVOL_MIC1, 7, 1, 0),
++
++      SOC_SINGLE_TLV("Mic 2 Bypass Playback Volume",
++                     MC1N2_AVOL_MIC2, 0, 31, 0, mc1n2_tlv_ain),
++      SOC_SINGLE("Mic 2 Bypass Playback Switch",
++                 MC1N2_AVOL_MIC2, 7, 1, 0),
++
++      SOC_SINGLE_TLV("Mic 3 Bypass Playback Volume",
++                     MC1N2_AVOL_MIC3, 0, 31, 0, mc1n2_tlv_ain),
++      SOC_SINGLE("Mic 3 Bypass Playback Switch",
++                 MC1N2_AVOL_MIC3, 7, 1, 0),
++
++      SOC_DOUBLE_TLV("Headphone Playback Volume",
++                     MC1N2_AVOL_HP, 0, 8, 31, 0, mc1n2_tlv_hpsp),
++      SOC_DOUBLE("Headphone Playback Switch",
++                 MC1N2_AVOL_HP, 7, 15, 1, 0),
++
++      SOC_DOUBLE_TLV("Speaker Playback Volume",
++                     MC1N2_AVOL_SP, 0, 8, 31, 0, mc1n2_tlv_hpsp),
++      SOC_DOUBLE("Speaker Playback Switch",
++                 MC1N2_AVOL_SP, 7, 15, 1, 0),
++
++      SOC_SINGLE_TLV("Receiver Playback Volume",
++                     MC1N2_AVOL_RC, 0, 31, 0, mc1n2_tlv_hpsp),
++      SOC_SINGLE("Receiver Playback Switch",
++                 MC1N2_AVOL_RC, 7, 1, 0),
++
++      SOC_DOUBLE_TLV("Line 1 Playback Volume",
++                     MC1N2_AVOL_LOUT1, 0, 8, 31, 0, mc1n2_tlv_aout),
++      SOC_DOUBLE("Line 1 Playback Switch",
++                 MC1N2_AVOL_LOUT1, 7, 15, 1, 0),
++
++      SOC_DOUBLE_TLV("Line 2 Playback Volume",
++                     MC1N2_AVOL_LOUT2, 0, 8, 31, 0, mc1n2_tlv_aout),
++      SOC_DOUBLE("Line 2 Playback Switch",
++                 MC1N2_AVOL_LOUT2, 7, 15, 1, 0),
++
++      SOC_SINGLE_TLV("Mic 1 Gain Volume",
++                     MC1N2_AVOL_MIC1_GAIN, 0, 3, 0, mc1n2_tlv_micgain),
++
++      SOC_SINGLE_TLV("Mic 2 Gain Volume",
++                     MC1N2_AVOL_MIC2_GAIN, 0, 3, 0, mc1n2_tlv_micgain),
++
++      SOC_SINGLE_TLV("Mic 3 Gain Volume",
++                     MC1N2_AVOL_MIC3_GAIN, 0, 3, 0, mc1n2_tlv_micgain),
++
++      SOC_SINGLE_TLV("HP Gain Playback Volume",
++                     MC1N2_AVOL_HP_GAIN, 0, 3, 0, mc1n2_tlv_hpgain),
++
++      SOC_ENUM_EXT("Codec Status", path_control_enum[0],
++                              mc1n2_get_codec_status, mc1n2_set_codec_status),
++};
++
++/*
++ * Same as snd_soc_add_controls supported in alsa-driver 1.0.19 or later.
++ * This function is implimented for compatibility with linux 2.6.29.
++ */
++static int mc1n2_add_controls(struct snd_soc_codec *codec,
++                            const struct snd_kcontrol_new *controls, int n)
++{
++      int err, i;
++
++      for (i = 0; i < n; i++, controls++) {
++#ifdef ALSA_VER_ANDROID_3_0
++              if ((err = snd_ctl_add((struct snd_card *)codec->card->snd_card,
++                                      snd_soc_cnew(controls, codec, NULL, NULL))) < 0) {
++                      return err;
++              }
++#else
++              if ((err = snd_ctl_add(codec->card,
++                                     snd_soc_cnew(controls, codec, NULL))) < 0) {
++                      return err;
++              }
++#endif
++      }
++
++      return 0;
++}
++
++static const struct snd_kcontrol_new adcl_mix[] = {
++      SOC_DAPM_SINGLE("Mic1 Switch", MC1N2_ADCL_MIC1_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Mic2 Switch", MC1N2_ADCL_MIC2_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Mic3 Switch", MC1N2_ADCL_MIC3_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Line Switch", MC1N2_ADCL_LINE_SW, 0, 1, 0),
++};
++
++static const struct snd_kcontrol_new adcr_mix[] = {
++      SOC_DAPM_SINGLE("Mic1 Switch", MC1N2_ADCR_MIC1_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Mic2 Switch", MC1N2_ADCR_MIC2_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Mic3 Switch", MC1N2_ADCR_MIC3_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Line Switch", MC1N2_ADCR_LINE_SW, 0, 1, 0),
++};
++
++static const struct snd_kcontrol_new hpl_mix[] = {
++      SOC_DAPM_SINGLE("Mic1 Switch", MC1N2_HPL_MIC1_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Mic2 Switch", MC1N2_HPL_MIC2_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Mic3 Switch", MC1N2_HPL_MIC3_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Line Switch", MC1N2_HPL_LINE_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Dac Switch", MC1N2_HPL_DAC_SW, 0, 1, 0),
++};
++
++static const struct snd_kcontrol_new hpr_mix[] = {
++      SOC_DAPM_SINGLE("Mic1 Switch", MC1N2_HPR_MIC1_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Mic2 Switch", MC1N2_HPR_MIC2_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Mic3 Switch", MC1N2_HPR_MIC3_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("LineR Switch", MC1N2_HPR_LINER_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("DacR Switch", MC1N2_HPR_DACR_SW, 0, 1, 0),
++};
++
++static const struct snd_kcontrol_new spl_mix[] = {
++      SOC_DAPM_SINGLE("Line Switch", MC1N2_SPL_LINE_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Dac Switch", MC1N2_SPL_DAC_SW, 0, 1, 0),
++};
++
++static const struct snd_kcontrol_new spr_mix[] = {
++      SOC_DAPM_SINGLE("Line Switch", MC1N2_SPR_LINE_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Dac Switch", MC1N2_SPR_DAC_SW, 0, 1, 0),
++};
++
++static const struct snd_kcontrol_new rc_mix[] = {
++      SOC_DAPM_SINGLE("Mic1 Switch", MC1N2_RC_MIC1_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Mic2 Switch", MC1N2_RC_MIC2_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Mic3 Switch", MC1N2_RC_MIC3_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("LineMono Switch", MC1N2_RC_LINEMONO_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("DacL Switch", MC1N2_RC_DACL_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("DacR Switch", MC1N2_RC_DACR_SW, 0, 1, 0),
++};
++
++static const struct snd_kcontrol_new lout1l_mix[] = {
++      SOC_DAPM_SINGLE("Mic1 Switch", MC1N2_LOUT1L_MIC1_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Mic2 Switch", MC1N2_LOUT1L_MIC2_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Mic3 Switch", MC1N2_LOUT1L_MIC3_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Line Switch", MC1N2_LOUT1L_LINE_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Dac Switch", MC1N2_LOUT1L_DAC_SW, 0, 1, 0),
++};
++
++static const struct snd_kcontrol_new lout1r_mix[] = {
++      SOC_DAPM_SINGLE("Mic1 Switch", MC1N2_LOUT1R_MIC1_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Mic2 Switch", MC1N2_LOUT1R_MIC2_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Mic3 Switch", MC1N2_LOUT1R_MIC3_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("LineR Switch", MC1N2_LOUT1R_LINER_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("DacR Switch", MC1N2_LOUT1R_DACR_SW, 0, 1, 0),
++};
++
++static const struct snd_kcontrol_new lout2l_mix[] = {
++      SOC_DAPM_SINGLE("Mic1 Switch", MC1N2_LOUT2L_MIC1_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Mic2 Switch", MC1N2_LOUT2L_MIC2_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Mic3 Switch", MC1N2_LOUT2L_MIC3_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Line Switch", MC1N2_LOUT2L_LINE_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Dac Switch", MC1N2_LOUT2L_DAC_SW, 0, 1, 0),
++};
++
++static const struct snd_kcontrol_new lout2r_mix[] = {
++      SOC_DAPM_SINGLE("Mic1 Switch", MC1N2_LOUT2R_MIC1_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Mic2 Switch", MC1N2_LOUT2R_MIC2_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Mic3 Switch", MC1N2_LOUT2R_MIC3_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("LineR Switch", MC1N2_LOUT2R_LINER_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("DacR Switch", MC1N2_LOUT2R_DACR_SW, 0, 1, 0),
++};
++
++static const struct snd_kcontrol_new digital_mix[] = {
++      SOC_DAPM_SINGLE("Adc Switch", MC1N2_DMIX_ADC_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Dir0 Switch", MC1N2_DMIX_DIR0_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Dir1 Switch", MC1N2_DMIX_DIR1_SW, 0, 1, 0),
++      SOC_DAPM_SINGLE("Dir2 Switch", MC1N2_DMIX_DIR2_SW, 0, 1, 0),
++};
++
++static const char *dsource_text[] = {
++      "OFF", "ADC", "DIR0", "DIR1", "DIR2", "MIX",
++};
++
++static const char *linel_mode_text[] = {
++      "LINEL", "LINEMONO",
++};
++
++static const char *liner_mode_text[] = {
++      "LINER", "LINEMONO",
++};
++
++static const char *dacl_mode_text[] = {
++      "DACL", "DACMONO",
++};
++
++static const char *dacr_mode_text[] = {
++      "DACR", "DACMONO",
++};
++
++static const char *ae_param_text[] = {
++      "PARAM1", "PARAM2", "PARAM3", "PARAM4", "PARAM5",
++};
++
++static const char *adc_pdm_text[] = {
++      "ADC", "PDM",
++};
++
++static const struct soc_enum dacmain_source_enum =
++      SOC_ENUM_SINGLE(MC1N2_DACMAIN_SRC, 0, 6, dsource_text);
++
++static const struct soc_enum dacvoice_source_enum =
++      SOC_ENUM_SINGLE(MC1N2_DACVOICE_SRC, 0, 6, dsource_text);
++
++static const struct soc_enum dit0_source_enum =
++      SOC_ENUM_SINGLE(MC1N2_DIT0_SRC, 0, 6, dsource_text);
++
++static const struct soc_enum dit1_source_enum =
++      SOC_ENUM_SINGLE(MC1N2_DIT1_SRC, 0, 6, dsource_text);
++
++static const struct soc_enum dit2_source_enum =
++      SOC_ENUM_SINGLE(MC1N2_DIT2_SRC, 0, 6, dsource_text);
++
++static const struct soc_enum ae_source_enum =
++      SOC_ENUM_SINGLE(MC1N2_AE_SRC, 0, 6, dsource_text);
++
++static const struct soc_enum adcl_line_enum =
++      SOC_ENUM_SINGLE(MC1N2_ADCL_LINE_SRC, 0, 2, linel_mode_text);
++
++static const struct soc_enum adcr_line_enum =
++      SOC_ENUM_SINGLE(MC1N2_ADCR_LINE_SRC, 0, 2, liner_mode_text);
++
++static const struct soc_enum hpl_line_enum =
++      SOC_ENUM_SINGLE(MC1N2_HPL_LINE_SRC, 0, 2, linel_mode_text);
++
++static const struct soc_enum hpl_dac_enum =
++      SOC_ENUM_SINGLE(MC1N2_HPL_DAC_SRC, 0, 2, dacl_mode_text);
++
++static const struct soc_enum spl_line_enum =
++      SOC_ENUM_SINGLE(MC1N2_SPL_LINE_SRC, 0, 2, linel_mode_text);
++
++static const struct soc_enum spl_dac_enum =
++      SOC_ENUM_SINGLE(MC1N2_SPL_DAC_SRC, 0, 2, dacl_mode_text);
++
++static const struct soc_enum spr_line_enum =
++      SOC_ENUM_SINGLE(MC1N2_SPR_LINE_SRC, 0, 2, liner_mode_text);
++
++static const struct soc_enum spr_dac_enum =
++      SOC_ENUM_SINGLE(MC1N2_SPR_DAC_SRC, 0, 2, dacr_mode_text);
++
++static const struct soc_enum lout1l_line_enum =
++      SOC_ENUM_SINGLE(MC1N2_LOUT1L_LINE_SRC, 0, 2, linel_mode_text);
++
++static const struct soc_enum lout1l_dac_enum =
++      SOC_ENUM_SINGLE(MC1N2_LOUT1L_DAC_SRC, 0, 2, dacl_mode_text);
++
++static const struct soc_enum lout2l_line_enum =
++      SOC_ENUM_SINGLE(MC1N2_LOUT2L_LINE_SRC, 0, 2, linel_mode_text);
++
++static const struct soc_enum lout2l_dac_enum =
++      SOC_ENUM_SINGLE(MC1N2_LOUT2L_DAC_SRC, 0, 2, dacl_mode_text);
++
++static const struct soc_enum ae_param_enum =
++      SOC_ENUM_SINGLE(MC1N2_AE_PARAM_SEL, 0, 5, ae_param_text);
++
++static const struct soc_enum adc_pdm_enum =
++      SOC_ENUM_SINGLE(MC1N2_ADC_PDM_SEL, 0, 2, adc_pdm_text);
++
++static const struct snd_kcontrol_new dacmain_mux =
++      SOC_DAPM_ENUM("DACMAIN SRC MUX", dacmain_source_enum);
++
++static const struct snd_kcontrol_new dacvoice_mux =
++      SOC_DAPM_ENUM("DACVOICE SRC MUX", dacvoice_source_enum);
++
++static const struct snd_kcontrol_new dit0_mux =
++      SOC_DAPM_ENUM("DIT0 SRC MUX", dit0_source_enum);
++
++static const struct snd_kcontrol_new dit1_mux =
++      SOC_DAPM_ENUM("DIT1 SRC MUX", dit1_source_enum);
++
++static const struct snd_kcontrol_new dit2_mux =
++      SOC_DAPM_ENUM("DIT2 SRC MUX", dit2_source_enum);
++
++static const struct snd_kcontrol_new ae_mux =
++      SOC_DAPM_ENUM("AE SRC MUX", ae_source_enum);
++
++static const struct snd_kcontrol_new adcl_line_mux =
++      SOC_DAPM_ENUM("ADCL LINE MUX", adcl_line_enum);
++
++static const struct snd_kcontrol_new adcr_line_mux =
++      SOC_DAPM_ENUM("ADCR LINE MUX", adcr_line_enum);
++
++static const struct snd_kcontrol_new hpl_line_mux =
++      SOC_DAPM_ENUM("HPL LINE MUX", hpl_line_enum);
++
++static const struct snd_kcontrol_new hpl_dac_mux =
++      SOC_DAPM_ENUM("HPL DAC MUX", hpl_dac_enum);
++
++static const struct snd_kcontrol_new spl_line_mux =
++      SOC_DAPM_ENUM("SPL LINE MUX", spl_line_enum);
++
++static const struct snd_kcontrol_new spl_dac_mux =
++      SOC_DAPM_ENUM("SPL DAC MUX", spl_dac_enum);
++
++static const struct snd_kcontrol_new spr_line_mux =
++      SOC_DAPM_ENUM("SPR LINE MUX", spr_line_enum);
++
++static const struct snd_kcontrol_new spr_dac_mux =
++      SOC_DAPM_ENUM("SPR DAC MUX", spr_dac_enum);
++
++static const struct snd_kcontrol_new lout1l_line_mux =
++      SOC_DAPM_ENUM("LOUT1L LINE MUX", lout1l_line_enum);
++
++static const struct snd_kcontrol_new lout1l_dac_mux =
++      SOC_DAPM_ENUM("LOUT1L DAC MUX", lout1l_dac_enum);
++
++static const struct snd_kcontrol_new lout2l_line_mux =
++      SOC_DAPM_ENUM("LOUT2L LINE MUX", lout2l_line_enum);
++
++static const struct snd_kcontrol_new lout2l_dac_mux =
++      SOC_DAPM_ENUM("LOUT2L DAC MUX", lout2l_dac_enum);
++
++static const struct snd_kcontrol_new ae_param_mux =
++      SOC_DAPM_ENUM("AE PARAMETER", ae_param_enum);
++
++static const struct snd_kcontrol_new adc_pdm_mux =
++      SOC_DAPM_ENUM("ADC PDM MUX", adc_pdm_enum);
++
++static const struct snd_kcontrol_new bias1_sw =
++      SOC_DAPM_SINGLE("Switch", MC1N2_MICBIAS1, 0, 1, 0);
++
++static const struct snd_kcontrol_new bias2_sw =
++      SOC_DAPM_SINGLE("Switch", MC1N2_MICBIAS2, 0, 1, 0);
++
++static const struct snd_kcontrol_new bias3_sw =
++      SOC_DAPM_SINGLE("Switch", MC1N2_MICBIAS3, 0, 1, 0);
++
++static const struct snd_soc_dapm_widget mc1n2_widgets[] = {
++SND_SOC_DAPM_INPUT("MIC1"),
++SND_SOC_DAPM_INPUT("MIC2"),
++SND_SOC_DAPM_INPUT("MIC3"),
++SND_SOC_DAPM_INPUT("LINEIN"),
++
++SND_SOC_DAPM_INPUT("DIR0"),
++SND_SOC_DAPM_INPUT("DIR1"),
++SND_SOC_DAPM_INPUT("DIR2"),
++
++SND_SOC_DAPM_INPUT("PDM"),
++
++SND_SOC_DAPM_INPUT("AE1"),
++SND_SOC_DAPM_INPUT("AE2"),
++SND_SOC_DAPM_INPUT("AE3"),
++SND_SOC_DAPM_INPUT("AE4"),
++SND_SOC_DAPM_INPUT("AE5"),
++
++SND_SOC_DAPM_INPUT("BIAS1"),
++SND_SOC_DAPM_INPUT("BIAS2"),
++SND_SOC_DAPM_INPUT("BIAS3"),
++
++SND_SOC_DAPM_OUTPUT("DIT0"),
++SND_SOC_DAPM_OUTPUT("DIT1"),
++SND_SOC_DAPM_OUTPUT("DIT2"),
++
++SND_SOC_DAPM_ADC("ADC", NULL, SND_SOC_NOPM, 0, 0),
++SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0),
++
++SND_SOC_DAPM_MIXER("ADCL MIXER", SND_SOC_NOPM, 0, 0, adcl_mix, ARRAY_SIZE(adcl_mix)),
++SND_SOC_DAPM_MIXER("ADCR MIXER", SND_SOC_NOPM, 0, 0, adcr_mix, ARRAY_SIZE(adcr_mix)),
++SND_SOC_DAPM_MIXER("HPL MIXER", SND_SOC_NOPM, 0, 0, hpl_mix, ARRAY_SIZE(hpl_mix)),
++SND_SOC_DAPM_MIXER("HPR MIXER", SND_SOC_NOPM, 0, 0, hpr_mix, ARRAY_SIZE(hpr_mix)),
++SND_SOC_DAPM_MIXER("SPL MIXER", SND_SOC_NOPM, 0, 0, spl_mix, ARRAY_SIZE(spl_mix)),
++SND_SOC_DAPM_MIXER("SPR MIXER", SND_SOC_NOPM, 0, 0, spr_mix, ARRAY_SIZE(spr_mix)),
++SND_SOC_DAPM_MIXER("RC MIXER", SND_SOC_NOPM, 0, 0, rc_mix, ARRAY_SIZE(rc_mix)),
++SND_SOC_DAPM_MIXER("LINEOUT1L MIXER", SND_SOC_NOPM, 0, 0, lout1l_mix, ARRAY_SIZE(lout1l_mix)),
++SND_SOC_DAPM_MIXER("LINEOUT1R MIXER", SND_SOC_NOPM, 0, 0, lout1r_mix, ARRAY_SIZE(lout1r_mix)),
++SND_SOC_DAPM_MIXER("LINEOUT2L MIXER", SND_SOC_NOPM, 0, 0, lout2l_mix, ARRAY_SIZE(lout2l_mix)),
++SND_SOC_DAPM_MIXER("LINEOUT2R MIXER", SND_SOC_NOPM, 0, 0, lout2r_mix, ARRAY_SIZE(lout2r_mix)),
++
++SND_SOC_DAPM_MIXER("DIGITAL MIXER", SND_SOC_NOPM, 0, 0, digital_mix, ARRAY_SIZE(digital_mix)),
++
++SND_SOC_DAPM_MUX("DACMAIN SRC", SND_SOC_NOPM, 0, 0, &dacmain_mux),
++SND_SOC_DAPM_MUX("DACVOICE SRC", SND_SOC_NOPM, 0, 0, &dacvoice_mux),
++SND_SOC_DAPM_MUX("DIT0 SRC", SND_SOC_NOPM, 0, 0, &dit0_mux),
++SND_SOC_DAPM_MUX("DIT1 SRC", SND_SOC_NOPM, 0, 0, &dit1_mux),
++SND_SOC_DAPM_MUX("DIT2 SRC", SND_SOC_NOPM, 0, 0, &dit2_mux),
++
++SND_SOC_DAPM_MUX("AE SRC", SND_SOC_NOPM, 0, 0, &ae_mux),
++
++SND_SOC_DAPM_MUX("ADCL LINE MIXMODE", SND_SOC_NOPM, 0, 0, &adcl_line_mux),
++SND_SOC_DAPM_MUX("ADCR LINE MIXMODE", SND_SOC_NOPM, 0, 0, &adcr_line_mux),
++
++SND_SOC_DAPM_MUX("HPL LINE MIXMODE", SND_SOC_NOPM, 0, 0, &hpl_line_mux),
++SND_SOC_DAPM_MUX("HPL DAC MIXMODE", SND_SOC_NOPM, 0, 0, &hpl_dac_mux),
++
++SND_SOC_DAPM_MUX("SPL LINE MIXMODE", SND_SOC_NOPM, 0, 0, &spl_line_mux),
++SND_SOC_DAPM_MUX("SPL DAC MIXMODE", SND_SOC_NOPM, 0, 0, &spl_dac_mux),
++SND_SOC_DAPM_MUX("SPR LINE MIXMODE", SND_SOC_NOPM, 0, 0, &spr_line_mux),
++SND_SOC_DAPM_MUX("SPR DAC MIXMODE", SND_SOC_NOPM, 0, 0, &spr_dac_mux),
++
++SND_SOC_DAPM_MUX("LINEOUT1L LINE MIXMODE", SND_SOC_NOPM, 0, 0, &lout1l_line_mux),
++SND_SOC_DAPM_MUX("LINEOUT1L DAC MIXMODE", SND_SOC_NOPM, 0, 0, &lout1l_dac_mux),
++
++SND_SOC_DAPM_MUX("LINEOUT2L LINE MIXMODE", SND_SOC_NOPM, 0, 0, &lout2l_line_mux),
++SND_SOC_DAPM_MUX("LINEOUT2L DAC MIXMODE", SND_SOC_NOPM, 0, 0, &lout2l_dac_mux),
++
++SND_SOC_DAPM_MUX("AE PARAMETER SEL", SND_SOC_NOPM, 0, 0, &ae_param_mux),
++
++SND_SOC_DAPM_MUX("ADC PDM SEL", SND_SOC_NOPM, 0, 0, &adc_pdm_mux),
++
++SND_SOC_DAPM_SWITCH("MB1", SND_SOC_NOPM, 0, 0, &bias1_sw),
++SND_SOC_DAPM_SWITCH("MB2", SND_SOC_NOPM, 0, 0, &bias2_sw),
++SND_SOC_DAPM_SWITCH("MB3", SND_SOC_NOPM, 0, 0, &bias3_sw),
++};
++
++static const struct snd_soc_dapm_route intercon[] = {
++      {"ADCL LINE MIXMODE", "LINEL", "LINEIN"},
++      {"ADCL LINE MIXMODE", "LINEMONO", "LINEIN"},
++      {"ADCR LINE MIXMODE", "LINER", "LINEIN"},
++      {"ADCR LINE MIXMODE", "LINEMONO", "LINEIN"},
++
++      {"HPL LINE MIXMODE", "LINEL", "LINEIN"},
++      {"HPL LINE MIXMODE", "LINEMONO", "LINEIN"},
++      {"HPL DAC MIXMODE", "DACL", "DAC"},
++      {"HPL DAC MIXMODE", "DACMONO", "DAC"},
++
++      {"SPL LINE MIXMODE", "LINEL", "LINEIN"},
++      {"SPL LINE MIXMODE", "LINEMONO", "LINEIN"},
++      {"SPL DAC MIXMODE", "DACL", "DAC"},
++      {"SPL DAC MIXMODE", "DACMONO", "DAC"},
++
++      {"SPR LINE MIXMODE", "LINER", "LINEIN"},
++      {"SPR LINE MIXMODE", "LINEMONO", "LINEIN"},
++      {"SPR DAC MIXMODE", "DACR", "DAC"},
++      {"SPR DAC MIXMODE", "DACMONO", "DAC"},
++
++      {"LINEOUT1L LINE MIXMODE", "LINEL", "LINEIN"},
++      {"LINEOUT1L LINE MIXMODE", "LINEMONO", "LINEIN"},
++      {"LINEOUT1L DAC MIXMODE", "DACL", "DAC"},
++      {"LINEOUT1L DAC MIXMODE", "DACMONO", "DAC"},
++
++      {"LINEOUT2L LINE MIXMODE", "LINEL", "LINEIN"},
++      {"LINEOUT2L LINE MIXMODE", "LINEMONO", "LINEIN"},
++      {"LINEOUT2L DAC MIXMODE", "DACL", "DAC"},
++      {"LINEOUT2L DAC MIXMODE", "DACMONO", "DAC"},
++
++      {"ADCL MIXER", "Mic1 Switch", "MIC1"},
++      {"ADCL MIXER", "Mic2 Switch", "MIC2"},
++      {"ADCL MIXER", "Mic3 Switch", "MIC3"},
++      {"ADCL MIXER", "Line Switch", "ADCL LINE MIXMODE"},
++
++      {"ADCR MIXER", "Mic1 Switch", "MIC1"},
++      {"ADCR MIXER", "Mic2 Switch", "MIC2"},
++      {"ADCR MIXER", "Mic3 Switch", "MIC3"},
++      {"ADCR MIXER", "Line Switch", "ADCR LINE MIXMODE"},
++
++      {"HPL MIXER", "Mic1 Switch", "MIC1"},
++      {"HPL MIXER", "Mic2 Switch", "MIC2"},
++      {"HPL MIXER", "Mic3 Switch", "MIC3"},
++      {"HPL MIXER", "Line Switch", "HPL LINE MIXMODE"},
++      {"HPL MIXER", "Dac Switch", "HPL DAC MIXMODE"},
++
++      {"HPR MIXER", "Mic1 Switch", "MIC1"},
++      {"HPR MIXER", "Mic2 Switch", "MIC2"},
++      {"HPR MIXER", "Mic3 Switch", "MIC3"},
++      {"HPR MIXER", "LineR Switch", "LINEIN"},
++      {"HPR MIXER", "DacR Switch", "DAC"},
++
++      {"SPL MIXER", "Line Switch", "SPL LINE MIXMODE"},
++      {"SPL MIXER", "Dac Switch", "SPL DAC MIXMODE"},
++
++      {"SPR MIXER", "Line Switch", "SPR LINE MIXMODE"},
++      {"SPR MIXER", "Dac Switch", "SPR DAC MIXMODE"},
++
++      {"RC MIXER", "Mic1 Switch", "MIC1"},
++      {"RC MIXER", "Mic2 Switch", "MIC2"},
++      {"RC MIXER", "Mic3 Switch", "MIC3"},
++      {"RC MIXER", "LineMono Switch", "LINEIN"},
++      {"RC MIXER", "DacL Switch", "DAC"},
++      {"RC MIXER", "DacR Switch", "DAC"},
++
++      {"LINEOUT1L MIXER", "Mic1 Switch", "MIC1"},
++      {"LINEOUT1L MIXER", "Mic2 Switch", "MIC2"},
++      {"LINEOUT1L MIXER", "Mic3 Switch", "MIC3"},
++      {"LINEOUT1L MIXER", "Line Switch", "LINEOUT1L LINE MIXMODE"},
++      {"LINEOUT1L MIXER", "Dac Switch", "LINEOUT1L DAC MIXMODE"},
++
++      {"LINEOUT1R MIXER", "Mic1 Switch", "MIC1"},
++      {"LINEOUT1R MIXER", "Mic2 Switch", "MIC2"},
++      {"LINEOUT1R MIXER", "Mic3 Switch", "MIC3"},
++      {"LINEOUT1R MIXER", "LineR Switch", "LINEIN"},
++      {"LINEOUT1R MIXER", "DacR Switch", "DAC"},
++
++      {"LINEOUT2L MIXER", "Mic1 Switch", "MIC1"},
++      {"LINEOUT2L MIXER", "Mic2 Switch", "MIC2"},
++      {"LINEOUT2L MIXER", "Mic3 Switch", "MIC3"},
++
++      {"LINEOUT2L MIXER", "Line Switch", "LINEOUT2L LINE MIXMODE"},
++      {"LINEOUT2L MIXER", "Dac Switch", "LINEOUT2L DAC MIXMODE"},
++
++      {"LINEOUT2R MIXER", "Mic1 Switch", "MIC1"},
++      {"LINEOUT2R MIXER", "Mic2 Switch", "MIC2"},
++      {"LINEOUT2R MIXER", "Mic3 Switch", "MIC3"},
++      {"LINEOUT2R MIXER", "LineR Switch", "LINEIN"},
++      {"LINEOUT2R MIXER", "DacR Switch", "DAC"},
++
++      {"ADC", NULL, "ADCL MIXER"},
++      {"ADC", NULL, "ADCR MIXER"},
++
++      {"DIGITAL MIXER", "Adc Switch", "ADC PDM SEL"},
++      {"DIGITAL MIXER", "Dir0 Switch", "DIR0"},
++      {"DIGITAL MIXER", "Dir1 Switch", "DIR1"},
++      {"DIGITAL MIXER", "Dir2 Switch", "DIR2"},
++
++      {"AE SRC", "ADC", "ADCL MIXER"},
++      {"AE SRC", "ADC", "ADCR MIXER"},
++      {"AE SRC", "DIR0", "DIR0"},
++      {"AE SRC", "DIR1", "DIR1"},
++      {"AE SRC", "DIR2", "DIR2"},
++      {"AE SRC", "MIX", "DIGITAL MIXER"},
++
++      {"DACMAIN SRC", "ADC", "ADC PDM SEL"},
++      {"DACMAIN SRC", "DIR0", "DIR0"},
++      {"DACMAIN SRC", "DIR1", "DIR1"},
++      {"DACMAIN SRC", "DIR2", "DIR2"},
++      {"DACMAIN SRC", "MIX", "DIGITAL MIXER"},
++
++      {"DACVOICE SRC", "ADC", "ADC PDM SEL"},
++      {"DACVOICE SRC", "DIR0", "DIR0"},
++      {"DACVOICE SRC", "DIR1", "DIR1"},
++      {"DACVOICE SRC", "DIR2", "DIR2"},
++      {"DACVOICE SRC", "MIX", "DIGITAL MIXER"},
++
++      {"DIT0 SRC", "ADC", "ADC PDM SEL"},
++      {"DIT0 SRC", "DIR0", "DIR0"},
++      {"DIT0 SRC", "DIR1", "DIR1"},
++      {"DIT0 SRC", "DIR2", "DIR2"},
++      {"DIT0 SRC", "MIX", "DIGITAL MIXER"},
++
++      {"DIT1 SRC", "ADC", "ADC PDM SEL"},
++      {"DIT1 SRC", "DIR0", "DIR0"},
++      {"DIT1 SRC", "DIR1", "DIR1"},
++      {"DIT1 SRC", "DIR2", "DIR2"},
++      {"DIT1 SRC", "MIX", "DIGITAL MIXER"},
++
++      {"DIT2 SRC", "ADC", "ADC PDM SEL"},
++      {"DIT2 SRC", "DIR0", "DIR0"},
++      {"DIT2 SRC", "DIR1", "DIR1"},
++      {"DIT2 SRC", "DIR2", "DIR2"},
++      {"DIT2 SRC", "MIX", "DIGITAL MIXER"},
++
++      {"AE PARAMETER SEL", "PARAM1", "AE1"},
++      {"AE PARAMETER SEL", "PARAM2", "AE2"},
++      {"AE PARAMETER SEL", "PARAM3", "AE3"},
++      {"AE PARAMETER SEL", "PARAM4", "AE4"},
++      {"AE PARAMETER SEL", "PARAM5", "AE5"},
++
++      {"ADC PDM SEL", "ADC", "ADC"},
++      {"ADC PDM SEL", "PDM", "PDM"},
++
++      {"MB1", "Switch", "BIAS1"},
++      {"MB2", "Switch", "BIAS2"},
++      {"MB3", "Switch", "BIAS3"},
++
++      {"MIC1", NULL, "MB1"},
++      {"MIC2", NULL, "MB2"},
++      {"MIC3", NULL, "MB3"},
++};
++
++#ifdef ALSA_VER_ANDROID_3_0
++static int mc1n2_add_widgets(struct snd_soc_codec *codec)
++{
++      int err;
++
++      err = snd_soc_dapm_new_controls(&codec->dapm, mc1n2_widgets,
++                                ARRAY_SIZE(mc1n2_widgets));
++      if(err < 0) {
++              return err;
++      }
++
++      err = snd_soc_dapm_add_routes(&codec->dapm, intercon, ARRAY_SIZE(intercon));
++      if(err < 0) {
++              return err;
++      }
++
++      err = snd_soc_dapm_new_widgets(&codec->dapm);
++      if(err < 0) {
++              return err;
++      }
++
++      return 0;
++}
++#else
++static int mc1n2_add_widgets(struct snd_soc_codec *codec)
++{
++      int err;
++
++      err = snd_soc_dapm_new_controls(codec, mc1n2_widgets,
++                                ARRAY_SIZE(mc1n2_widgets));
++      if(err < 0) {
++              return err;
++      }
++
++      err = snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
++      if(err < 0) {
++              return err;
++      }
++
++      err = snd_soc_dapm_new_widgets(codec);
++      if(err < 0) {
++              return err;
++      }
++
++      return 0;
++}
++#endif
++
++/*
++ * Hwdep interface
++ */
++static int mc1n2_hwdep_open(struct snd_hwdep * hw, struct file *file)
++{
++      /* Nothing to do */
++      return 0;
++}
++
++static int mc1n2_hwdep_release(struct snd_hwdep *hw, struct file *file)
++{
++      /* Nothing to do */
++      return 0;
++}
++
++static int mc1n2_hwdep_map_error(int err)
++{
++      switch (err) {
++      case MCDRV_SUCCESS:
++              return 0;
++      case MCDRV_ERROR_ARGUMENT:
++              return -EINVAL;
++      case MCDRV_ERROR_STATE:
++              return -EBUSY;
++      case MCDRV_ERROR_TIMEOUT:
++              return -EIO;
++      default:
++              /* internal error */
++              return -EIO;
++      }
++}
++
++static int mc1n2_hwdep_ioctl_set_path(struct snd_soc_codec *codec,
++                                    void *info, unsigned int update)
++{
++#if (defined ALSA_VER_ANDROID_2_6_35) || (defined ALSA_VER_ANDROID_3_0)
++      struct mc1n2_data *mc1n2 = snd_soc_codec_get_drvdata(codec);
++#else
++      struct mc1n2_data *mc1n2 = codec->private_data;
++#endif
++      MCDRV_CHANNEL *ch;
++      int i, j;
++      MCDRV_PATH_INFO *path = (MCDRV_PATH_INFO *) info;
++
++      mutex_lock(&mc1n2->mutex);
++
++      /* preserve DIR settings */
++      for (i = 0; i < MC1N2_N_PATH_CHANNELS; i++) {
++              ch = (MCDRV_CHANNEL *)(info + mc1n2_path_channel_tbl[i]);
++#ifdef DIO0_DAI_ENABLE
++              switch ((ch->abSrcOnOff[3]) & 0x3) {
++              case 1:
++                      mc1n2->port[0].dir[i] = 1;
++                      break;
++              case 2:
++                      mc1n2->port[0].dir[i] = 0;
++                      break;
++              }
++#endif
++#ifdef DIO1_DAI_ENABLE
++              switch ((ch->abSrcOnOff[3] >> 2) & 0x3) {
++              case 1:
++                      mc1n2->port[1].dir[i] = 1;
++                      break;
++              case 2:
++                      mc1n2->port[1].dir[i] = 0;
++                      break;
++              }
++#endif
++#ifdef DIO2_DAI_ENABLE
++              switch ((ch->abSrcOnOff[3] >> 4) & 0x3) {
++              case 1:
++                      mc1n2->port[2].dir[i] = 1;
++                      break;
++              case 2:
++                      mc1n2->port[2].dir[i] = 0;
++                      break;
++              }
++#endif
++      }
++
++      /* preserve DIT settings */
++#ifdef DIO0_DAI_ENABLE
++      ch = (MCDRV_CHANNEL *)(info + mc1n2_path_channel_tbl[0]);
++      for (j = 0; j < SOURCE_BLOCK_NUM; j++) {
++              mc1n2->port[0].dit.abSrcOnOff[j] |=
++                      ch->abSrcOnOff[j] & 0x55;
++              mc1n2->port[0].dit.abSrcOnOff[j] &=
++                      ~((ch->abSrcOnOff[j] & 0xaa) >> 1);
++      }
++#endif
++#ifdef DIO1_DAI_ENABLE
++      ch = (MCDRV_CHANNEL *)(info + mc1n2_path_channel_tbl[1]);
++      for (j = 0; j < SOURCE_BLOCK_NUM; j++) {
++              mc1n2->port[1].dit.abSrcOnOff[j] |=
++                      ch->abSrcOnOff[j] & 0x55;
++              mc1n2->port[1].dit.abSrcOnOff[j] &=
++                      ~((ch->abSrcOnOff[j] & 0xaa) >> 1);
++      }
++#endif
++#ifdef DIO2_DAI_ENABLE
++      ch = (MCDRV_CHANNEL *)(info + mc1n2_path_channel_tbl[2]);
++      for (j = 0; j < SOURCE_BLOCK_NUM; j++) {
++              mc1n2->port[2].dit.abSrcOnOff[j] |=
++                      ch->abSrcOnOff[j] & 0x55;
++              mc1n2->port[2].dit.abSrcOnOff[j] &=
++                      ~((ch->abSrcOnOff[j] & 0xaa) >> 1);
++      }
++#endif
++
++      /* modify path */
++      for (i = 0; i < MC1N2_N_PATH_CHANNELS; i++) {
++              ch = (MCDRV_CHANNEL *)(info + mc1n2_path_channel_tbl[i]);
++
++#ifdef DIO0_DAI_ENABLE
++              if (!mc1n2_is_in_playback(&mc1n2->port[0])) {
++                      ch->abSrcOnOff[3] &= ~(0x3);
++              }
++#endif
++#ifdef DIO1_DAI_ENABLE
++              if (!mc1n2_is_in_playback(&mc1n2->port[1])) {
++                      ch->abSrcOnOff[3] &= ~(0x3 << 2);
++              }
++#endif
++#ifdef DIO2_DAI_ENABLE
++              if (!mc1n2_is_in_playback(&mc1n2->port[2])) {
++                      ch->abSrcOnOff[3] &= ~(0x3 << 4);
++              }
++#endif
++      }
++
++#ifdef DIO0_DAI_ENABLE
++      ch = (MCDRV_CHANNEL *)(info + mc1n2_path_channel_tbl[0]);
++      for (j = 0; j < SOURCE_BLOCK_NUM; j++) {
++              if (!mc1n2_is_in_capture(&mc1n2->port[0])) {
++                      ch->abSrcOnOff[j] = 0;
++              }
++      }
++#endif
++#ifdef DIO1_DAI_ENABLE
++      ch = (MCDRV_CHANNEL *)(info + mc1n2_path_channel_tbl[1]);
++      for (j = 0; j < SOURCE_BLOCK_NUM; j++) {
++              if (!mc1n2_is_in_capture(&mc1n2->port[1])) {
++                      ch->abSrcOnOff[j] = 0;
++              }
++      }
++#endif
++#ifdef DIO2_DAI_ENABLE
++      ch = (MCDRV_CHANNEL *)(info + mc1n2_path_channel_tbl[2]);
++      for (j = 0; j < SOURCE_BLOCK_NUM; j++) {
++              if (!mc1n2_is_in_capture(&mc1n2->port[2])) {
++                      ch->abSrcOnOff[j] = 0;
++              }
++      }
++#endif
++
++      /* select mic path */
++      if ((path->asAdc0[0].abSrcOnOff[0] & MCDRV_SRC0_MIC1_OFF) && (path->asAdc0[1].abSrcOnOff[0] & MCDRV_SRC0_MIC1_OFF)) {
++              audio_ctrl_mic_bias_gpio(mc1n2->pdata, MAIN_MIC, 0);
++      } else {
++              audio_ctrl_mic_bias_gpio(mc1n2->pdata, MAIN_MIC, 1);
++              mdelay(mc1n2->delay_mic1in);
++      }
++
++      if ((path->asAdc0[0].abSrcOnOff[0] & MCDRV_SRC0_MIC3_OFF) && (path->asAdc0[1].abSrcOnOff[0] & MCDRV_SRC0_MIC3_OFF)) {
++              audio_ctrl_mic_bias_gpio(mc1n2->pdata, SUB_MIC, 0);
++      } else
++              audio_ctrl_mic_bias_gpio(mc1n2->pdata, SUB_MIC, 1);
++
++      mutex_unlock(&mc1n2->mutex);
++
++      return 0;
++}
++
++static int mc1n2_hwdep_ioctl_set_ae(struct snd_soc_codec *codec,
++                                  void *info, unsigned int update)
++{
++#if (defined ALSA_VER_ANDROID_2_6_35) || (defined ALSA_VER_ANDROID_3_0)
++      struct mc1n2_data *mc1n2 = snd_soc_codec_get_drvdata(codec);
++#else
++      struct mc1n2_data *mc1n2 = codec->private_data;
++#endif
++      UINT8 onoff = ((MCDRV_AE_INFO *)info)->bOnOff;
++      unsigned int mask = update & 0x0f;      /* bit mask for bOnOff */
++      int i;
++
++      struct mc1n2_ae_copy {
++              UINT32 flag;
++              size_t offset;
++              size_t size;
++      };
++
++      struct mc1n2_ae_copy tbl[] = {
++              {MCDRV_AEUPDATE_FLAG_BEX,
++               offsetof(MCDRV_AE_INFO, abBex), BEX_PARAM_SIZE},
++              {MCDRV_AEUPDATE_FLAG_WIDE,
++               offsetof(MCDRV_AE_INFO, abWide), WIDE_PARAM_SIZE},
++              {MCDRV_AEUPDATE_FLAG_DRC,
++               offsetof(MCDRV_AE_INFO, abDrc), DRC_PARAM_SIZE},
++              {MCDRV_AEUPDATE_FLAG_EQ5,
++               offsetof(MCDRV_AE_INFO, abEq5), EQ5_PARAM_SIZE},
++              {MCDRV_AEUPDATE_FLAG_EQ3,
++               offsetof(MCDRV_AE_INFO, abEq3), EQ3_PARAM_SIZE},
++      };
++
++      mutex_lock(&mc1n2->mutex);
++
++      mc1n2->ae_store.bOnOff = (mc1n2->ae_store.bOnOff & ~mask) | onoff;
++
++      for (i = 0; i < sizeof(tbl)/sizeof(struct mc1n2_ae_copy); i++) {
++              if (update & tbl[i].flag) {
++                      memcpy((void *)&mc1n2->ae_store + tbl[i].offset,
++                             info + tbl[i].offset, tbl[i].size);
++              }
++      }
++
++      mutex_unlock(&mc1n2->mutex);
++
++      return 0;
++}
++
++struct mc1n2_hwdep_func {
++      int cmd;
++      size_t size;
++      int (*callback)(struct snd_soc_codec *, void *, unsigned int);
++};
++
++struct mc1n2_hwdep_func mc1n2_hwdep_func_map[] = {
++      {0, 0, NULL},                                         /* INIT */
++      {0, 0, NULL},                                         /* TERM */
++      {MC1N2_IOCTL_NR_BOTH, sizeof(MCDRV_REG_INFO), NULL},  /* READ_REG */
++      {0, 0, NULL},                                         /* WRITE_REG */
++      {MC1N2_IOCTL_NR_GET, sizeof(MCDRV_PATH_INFO), NULL},  /* GET_PATH */
++      {MC1N2_IOCTL_NR_SET, sizeof(MCDRV_PATH_INFO),
++       mc1n2_hwdep_ioctl_set_path},                         /* SET_PATH */
++      {0, 0, NULL},                                         /* GET_VOLUME */
++      {0, 0, NULL},                                         /* SET_VOLUME */
++      {MC1N2_IOCTL_NR_GET, sizeof(MCDRV_DIO_INFO), NULL},   /* GET_DIGITALIO */
++      {MC1N2_IOCTL_NR_SET, sizeof(MCDRV_DIO_INFO), NULL},   /* SET_DIGITALIO */
++      {MC1N2_IOCTL_NR_GET, sizeof(MCDRV_DAC_INFO), NULL},   /* GET_DAC */
++      {MC1N2_IOCTL_NR_SET, sizeof(MCDRV_DAC_INFO), NULL},   /* SET_DAC */
++      {MC1N2_IOCTL_NR_GET, sizeof(MCDRV_ADC_INFO), NULL},   /* GET_ADC */
++      {MC1N2_IOCTL_NR_SET, sizeof(MCDRV_ADC_INFO), NULL},   /* SET_ADC */
++      {MC1N2_IOCTL_NR_GET, sizeof(MCDRV_SP_INFO), NULL},    /* GET_SP */
++      {MC1N2_IOCTL_NR_SET, sizeof(MCDRV_SP_INFO), NULL},    /* SET_SP */
++      {MC1N2_IOCTL_NR_GET, sizeof(MCDRV_DNG_INFO), NULL},   /* GET_DNG */
++      {MC1N2_IOCTL_NR_SET, sizeof(MCDRV_DNG_INFO), NULL},   /* SET_DNG */
++      {MC1N2_IOCTL_NR_SET, sizeof(MCDRV_AE_INFO),
++       mc1n2_hwdep_ioctl_set_ae},                           /* SET_AE */
++      {0, 0, NULL},                                         /* SET_AE_EX */
++      {0, 0, NULL},                                         /* SET_CDSP */
++      {0, 0, NULL},                                         /* GET_CDSP_PARAM */
++      {0, 0, NULL},                                         /* SET_CDSP_PARAM */
++      {0, 0, NULL},                                         /* REG_CDSP_CB */
++      {MC1N2_IOCTL_NR_GET, sizeof(MCDRV_PDM_INFO), NULL},   /* GET PDM */
++      {MC1N2_IOCTL_NR_SET, sizeof(MCDRV_PDM_INFO), NULL},   /* SET_PDM */
++      {0, 0, NULL},                                         /* SET_DTMF */
++      {0, 0, NULL},                                         /* CONFIG_GP */
++      {0, 0, NULL},                                         /* MASK_GP */
++      {0, 0, NULL},                                         /* GETSET_GP */
++      {0, 0, NULL},                                         /* GET_PEAK */
++      {0, 0, NULL},                                         /* IRQ */
++      {0, 0, NULL},                                         /* UPDATE_CLOCK */
++      {MC1N2_IOCTL_NR_SET, sizeof(MCDRV_CLKSW_INFO), NULL}, /* SWITCH_CLOCK */
++      {MC1N2_IOCTL_NR_GET, sizeof(MCDRV_SYSEQ_INFO), NULL}, /* GET SYSEQ */
++      {MC1N2_IOCTL_NR_SET, sizeof(MCDRV_SYSEQ_INFO), NULL}, /* SET_SYSEQ */
++};
++#define MC1N2_HWDEP_N_FUNC_MAP \
++      (sizeof(mc1n2_hwdep_func_map)/sizeof(struct mc1n2_hwdep_func))
++
++static int mc1n2_hwdep_ioctl_get_ctrl(struct snd_soc_codec *codec,
++                                    struct mc1n2_ctrl_args *args)
++{
++      struct mc1n2_hwdep_func *func = &mc1n2_hwdep_func_map[args->dCmd];
++      void *info;
++      int err;
++
++      if (func->cmd != MC1N2_IOCTL_NR_GET) {
++              return -EINVAL;
++      }
++
++      if (!access_ok(VERIFY_WRITE, args->pvPrm, func->size)) {
++              return -EFAULT;
++      }
++
++      if (!(info = kzalloc(func->size, GFP_KERNEL))) {
++              return -ENOMEM;
++      }
++
++      err = _McDrv_Ctrl(args->dCmd, info, args->dPrm);
++      err = mc1n2_hwdep_map_error(err);
++      if (err < 0) {
++              goto error;
++      }
++
++      if (func->callback) {                   /* call post-process */
++              func->callback(codec, info, args->dPrm);
++      }
++
++      if (copy_to_user(args->pvPrm, info, func->size) != 0) {
++              err = -EFAULT;
++              goto error;
++      }
++
++error:
++      kfree(info);
++      return err;
++}
++
++static int mc1n2_hwdep_ioctl_set_ctrl(struct snd_soc_codec *codec,
++                                    struct mc1n2_ctrl_args *args)
++{
++      struct mc1n2_hwdep_func *func = &mc1n2_hwdep_func_map[args->dCmd];
++      void *info;
++      int err;
++
++      if (func->cmd != MC1N2_IOCTL_NR_SET) {
++              return -EINVAL;
++      }
++
++      if (!access_ok(VERIFY_READ, args->pvPrm, func->size)) {
++              return -EFAULT;
++      }
++
++      if (!(info = kzalloc(func->size, GFP_KERNEL))) {
++              return -ENOMEM;
++      }
++
++      if (copy_from_user(info, args->pvPrm, func->size) != 0) {
++              kfree(info);
++              return -EFAULT;
++      }
++
++      if (func->callback) {                   /* call pre-process */
++              func->callback(codec, info, args->dPrm);
++      }
++
++      if (args->dCmd == MCDRV_SET_DIGITALIO) {
++#ifdef DIO0_DAI_ENABLE
++              args->dPrm &= ~(MCDRV_DIO0_COM_UPDATE_FLAG | MCDRV_DIO0_DIR_UPDATE_FLAG | MCDRV_DIO0_DIT_UPDATE_FLAG);
++#endif
++#ifdef DIO1_DAI_ENABLE
++              args->dPrm &= ~(MCDRV_DIO1_COM_UPDATE_FLAG | MCDRV_DIO1_DIR_UPDATE_FLAG | MCDRV_DIO1_DIT_UPDATE_FLAG);
++#endif
++#ifdef DIO2_DAI_ENABLE
++              args->dPrm &= ~(MCDRV_DIO2_COM_UPDATE_FLAG | MCDRV_DIO2_DIR_UPDATE_FLAG | MCDRV_DIO2_DIT_UPDATE_FLAG);
++#endif
++      }
++
++      err = _McDrv_Ctrl(args->dCmd, info, args->dPrm);
++
++      kfree(info);
++
++      return mc1n2_hwdep_map_error(err);
++}
++
++static int mc1n2_hwdep_ioctl_read_reg(struct mc1n2_ctrl_args *args)
++{
++      struct mc1n2_hwdep_func *func = &mc1n2_hwdep_func_map[args->dCmd];
++      MCDRV_REG_INFO info;
++      int err;
++
++      if (func->cmd != MC1N2_IOCTL_NR_BOTH) {
++              return -EINVAL;
++      }
++
++      if (!access_ok(VERIFY_WRITE, args->pvPrm, sizeof(MCDRV_REG_INFO))) {
++              return -EFAULT;
++      }
++
++      if (copy_from_user(&info, args->pvPrm, sizeof(MCDRV_REG_INFO)) != 0) {
++              return -EFAULT;
++      }
++
++      err = _McDrv_Ctrl(args->dCmd, &info, args->dPrm);
++      if (err != MCDRV_SUCCESS) {
++              return mc1n2_hwdep_map_error(err);
++      }
++
++      if (copy_to_user(args->pvPrm, &info, sizeof(MCDRV_REG_INFO)) != 0) {
++              return -EFAULT;
++      }
++
++      return 0;
++}
++
++static int mc1n2_hwdep_ioctl_notify(struct snd_soc_codec *codec,
++                                    struct mc1n2_ctrl_args *args)
++{
++      MCDRV_PATH_INFO path;
++      int err;
++
++#if (defined ALSA_VER_ANDROID_2_6_35) || (defined ALSA_VER_ANDROID_3_0)
++      struct mc1n2_data *mc1n2 = snd_soc_codec_get_drvdata(codec);
++#else
++      struct mc1n2_data *mc1n2 = codec->private_data;
++#endif
++
++      switch (args->dCmd) {
++      case MCDRV_NOTIFY_CALL_START:
++      case MCDRV_NOTIFY_2MIC_CALL_START:
++              mc1n2_current_mode |= MC1N2_MODE_CALL_ON;
++              err = mc1n2->pdata->set_adc_power_constraints(&mc1n2_i2c->dev, 0);
++              if (err < 0) {
++                      dev_err(codec->dev,
++                              "%s:%d:Error VADC_3.3V[On]\n", __func__, err);
++              }
++              break;
++      case MCDRV_NOTIFY_CALL_STOP:
++              mc1n2_current_mode &= ~MC1N2_MODE_CALL_ON;
++              err = mc1n2->pdata->set_adc_power_constraints(&mc1n2_i2c->dev, 1);
++              if (err < 0) {
++                      dev_err(codec->dev,
++                              "%s:%d:Error VADC_3.3V[Off]\n", __func__, err);
++              }
++              break;
++      case MCDRV_NOTIFY_MEDIA_PLAY_START:
++              break;
++      case MCDRV_NOTIFY_MEDIA_PLAY_STOP:
++              break;
++      case MCDRV_NOTIFY_FM_PLAY_START:
++              mc1n2_current_mode |= MC1N2_MODE_FM_ON;
++              break;
++      case MCDRV_NOTIFY_FM_PLAY_STOP:
++              mc1n2_current_mode &= ~MC1N2_MODE_FM_ON;
++              break;
++      case MCDRV_NOTIFY_BT_SCO_ENABLE:
++              break;
++      case MCDRV_NOTIFY_BT_SCO_DISABLE:
++              break;
++      case MCDRV_NOTIFY_VOICE_REC_START:
++              mc1n2->delay_mic1in = MC1N2_WAITTIME_MICIN;
++              break;
++      case MCDRV_NOTIFY_VOICE_REC_STOP:
++              mc1n2->delay_mic1in = 0;
++              break;
++      case MCDRV_NOTIFY_HDMI_START:
++              if (mc1n2->hdmicount == 0) {
++                      memset(&path, 0, sizeof(path));
++                      path.asDit0[0].abSrcOnOff[3] = MCDRV_SRC3_DIR0_OFF;
++                      path.asDit1[0].abSrcOnOff[3] = MCDRV_SRC3_DIR0_OFF;
++                      path.asDit2[0].abSrcOnOff[3] = MCDRV_SRC3_DIR0_OFF;
++                      path.asDac[0].abSrcOnOff[3] = MCDRV_SRC3_DIR0_OFF;
++                      path.asDac[1].abSrcOnOff[3] = MCDRV_SRC3_DIR0_OFF;
++                      path.asAe[0].abSrcOnOff[3] = MCDRV_SRC3_DIR0_OFF;
++                      path.asMix[0].abSrcOnOff[3] = MCDRV_SRC3_DIR0_OFF;
++                      _McDrv_Ctrl(MCDRV_SET_PATH, &path, 0);
++              }
++
++              (mc1n2->hdmicount)++;
++              break;
++      case MCDRV_NOTIFY_HDMI_STOP:
++              if (mc1n2->hdmicount != 0) {
++                      if (mc1n2->hdmicount == 1) {
++                              memset(&path, 0, sizeof(path));
++                              path.asDit0[0].abSrcOnOff[3] = MCDRV_SRC3_DIR0_OFF;
++                              path.asDit1[0].abSrcOnOff[3] = MCDRV_SRC3_DIR0_OFF;
++                              path.asDit2[0].abSrcOnOff[3] = MCDRV_SRC3_DIR0_OFF;
++                              path.asDac[0].abSrcOnOff[3] = MCDRV_SRC3_DIR0_OFF;
++                              path.asDac[1].abSrcOnOff[3] = MCDRV_SRC3_DIR0_OFF;
++                              path.asAe[0].abSrcOnOff[3] = MCDRV_SRC3_DIR0_OFF;
++                              path.asMix[0].abSrcOnOff[3] = MCDRV_SRC3_DIR0_OFF;
++                              _McDrv_Ctrl(MCDRV_SET_PATH, &path, 0);
++                      }
++
++                      (mc1n2->hdmicount)--;
++              }
++              break;
++      case MCDRV_NOTIFY_LINEOUT_START:
++              mc1n2->lineoutenable = 1;
++              break;
++      case MCDRV_NOTIFY_LINEOUT_STOP:
++              mc1n2->lineoutenable = 0;
++              break;
++      case MCDRV_NOTIFY_RECOVER:
++              {
++                      int err, i;
++                      SINT16 *vol = (SINT16 *)&mc1n2->vol_store;
++
++                      mutex_lock(&mc1n2->mutex);
++
++                      /* store parameters */
++                      for (i = 0; i < MC1N2_N_INFO_STORE; i++) {
++                              struct mc1n2_info_store *store = &mc1n2_info_store_tbl[i];
++                              if (store->get) {
++                                      err = _McDrv_Ctrl(store->get, (void *)mc1n2 + store->offset, 0);
++                                      if (err != MCDRV_SUCCESS) {
++                                              dev_err(codec->dev,
++                                                      "%d: Error in MCDRV_GET_xxx\n", err);
++                                              err = -EIO;
++                                              goto error_recover;
++                                      } else {
++                                              err = 0;
++                                      }
++                              }
++                      }
++
++                      err = _McDrv_Ctrl(MCDRV_TERM, NULL, 0);
++                      if (err != MCDRV_SUCCESS) {
++                              dev_err(codec->dev, "%d: Error in MCDRV_TERM\n", err);
++                              err = -EIO;
++                      } else {
++                              err = 0;
++                      }
++
++                      err = _McDrv_Ctrl(MCDRV_INIT, &mc1n2->setup.init, 0);
++                      if (err != MCDRV_SUCCESS) {
++                              dev_err(codec->dev, "%d: Error in MCDRV_INIT\n", err);
++                              err = -EIO;
++                              goto error_recover;
++                      } else {
++                              err = 0;
++                      }
++
++                      /* restore parameters */
++                      for (i = 0; i < sizeof(MCDRV_VOL_INFO)/sizeof(SINT16); i++, vol++) {
++                              *vol |= 0x0001;
++                      }
++
++                      for (i = 0; i < MC1N2_N_INFO_STORE; i++) {
++                              struct mc1n2_info_store *store = &mc1n2_info_store_tbl[i];
++                              if (store->set) {
++                                      err = _McDrv_Ctrl(store->set, (void *)mc1n2 + store->offset,
++                                                        store->flags);
++                                      if (err != MCDRV_SUCCESS) {
++                                              dev_err(codec->dev,
++                                                      "%d: Error in MCDRV_SET_xxx\n", err);
++                                              err = -EIO;
++                                              goto error_recover;
++                                      } else {
++                                              err = 0;
++                                      }
++                              }
++                      }
++
++error_recover:
++                      mutex_unlock(&mc1n2->mutex);
++                      return err;
++                      break;
++              }
++      }
++
++      return 0;
++}
++
++static int mc1n2_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
++                           unsigned int cmd, unsigned long arg)
++{
++      struct mc1n2_ctrl_args ctrl_args;
++      struct snd_soc_codec *codec = hw->private_data;
++      int err;
++
++      if (!access_ok(VERIFY_READ, (struct mc1n2_ctrl_args *)arg,
++                     sizeof(struct mc1n2_ctrl_args))) {
++              return -EFAULT;
++      }
++
++      if (copy_from_user(&ctrl_args, (struct mc1n2_ctrl_args *)arg,
++                         sizeof(struct mc1n2_ctrl_args)) != 0) {
++              return -EFAULT;
++      }
++
++      if (cmd == MC1N2_IOCTL_NOTIFY) {
++              return mc1n2_hwdep_ioctl_notify(codec, &ctrl_args);
++      }
++
++      if (ctrl_args.dCmd >= MC1N2_HWDEP_N_FUNC_MAP) {
++              return -EINVAL;
++      }
++
++      switch (cmd) {
++      case MC1N2_IOCTL_GET_CTRL:
++              err = mc1n2_hwdep_ioctl_get_ctrl(codec, &ctrl_args);
++              break;
++      case MC1N2_IOCTL_SET_CTRL:
++              err = mc1n2_hwdep_ioctl_set_ctrl(codec, &ctrl_args);
++              break;
++      case MC1N2_IOCTL_READ_REG:
++              err = mc1n2_hwdep_ioctl_read_reg(&ctrl_args);
++              break;
++      default:
++              err = -EINVAL;
++      }
++
++      return err;
++}
++
++static int mc1n2_add_hwdep(struct snd_soc_codec *codec)
++{
++      struct snd_hwdep *hw;
++#if (defined ALSA_VER_ANDROID_2_6_35) || (defined ALSA_VER_ANDROID_3_0)
++      struct mc1n2_data *mc1n2 = snd_soc_codec_get_drvdata(codec);
++#else
++      struct mc1n2_data *mc1n2 = codec->private_data;
++#endif
++      int err;
++
++#ifdef ALSA_VER_ANDROID_3_0
++      err = snd_hwdep_new((struct snd_card *)codec->card->snd_card,
++                                              MC1N2_HWDEP_ID, 0, &hw);
++#else
++      err = snd_hwdep_new(codec->card, MC1N2_HWDEP_ID, 0, &hw);
++#endif
++      if (err < 0) {
++              return err;
++      }
++
++      hw->iface = SNDRV_HWDEP_IFACE_MC1N2;
++      hw->private_data = codec;
++      hw->ops.open = mc1n2_hwdep_open;
++      hw->ops.release = mc1n2_hwdep_release;
++      hw->ops.ioctl = mc1n2_hwdep_ioctl;
++      hw->exclusive = 1;
++      strcpy(hw->name, MC1N2_HWDEP_ID);
++      mc1n2->hwdep = hw;
++
++      return 0;
++}
++
++/*
++ * Codec device
++ */
++#ifdef ALSA_VER_ANDROID_3_0
++static int mc1n2_probe(struct snd_soc_codec *codec)
++#else
++static int mc1n2_probe(struct platform_device *pdev)
++#endif
++{
++#ifdef ALSA_VER_ANDROID_3_0
++      struct mc1n2_data *mc1n2 = snd_soc_codec_get_drvdata(codec);
++      struct device *dev = codec->dev;
++      struct mc1n2_setup *setup = &mc1n2_cfg_setup;
++#else
++      struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++      struct snd_soc_codec *codec = mc1n2_get_codec_data();
++#ifdef ALSA_VER_ANDROID_2_6_35
++      struct mc1n2_data *mc1n2 = snd_soc_codec_get_drvdata(codec);
++#else
++      struct mc1n2_data *mc1n2 = codec->private_data;
++#endif
++      struct mc1n2_setup *setup = socdev->codec_data;
++      struct device *dev = socdev->dev;
++#endif
++      int err;
++      UINT32 update = 0;
++
++      TRACE_FUNC();
++
++      if (!codec) {
++              dev_err(dev, "I2C bus is not probed successfully\n");
++              err = -ENODEV;
++              goto error_codec_data;
++      }
++#ifndef ALSA_VER_ANDROID_3_0
++#ifdef ALSA_VER_1_0_19
++      socdev->codec = codec;
++#else
++      socdev->card->codec = codec;
++#endif
++#endif
++
++      /* init hardware */
++      if (!setup) {
++              dev_err(dev, "No initialization parameters given\n");
++              err = -EINVAL;
++              goto error_init_hw;
++      }
++      memcpy(&mc1n2->setup, setup, sizeof(struct mc1n2_setup));
++      err = _McDrv_Ctrl(MCDRV_INIT, &mc1n2->setup.init, 0);
++      if (err != MCDRV_SUCCESS) {
++              dev_err(dev, "%d: Error in MCDRV_INIT\n", err);
++              err = -EIO;
++              goto error_init_hw;
++      }
++
++      /* pcm */
++#ifndef ALSA_VER_ANDROID_3_0
++      err = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
++      if (err < 0) {
++              dev_err(dev, "%d: Error in snd_soc_new_pcms\n", err);
++              goto error_new_pcm;
++      }
++#endif
++
++      /* controls */
++      err = mc1n2_add_controls(codec, mc1n2_snd_controls,
++                               ARRAY_SIZE(mc1n2_snd_controls));
++      if (err < 0) {
++              dev_err(dev, "%d: Error in mc1n2_add_controls\n", err);
++              goto error_add_ctl;
++      }
++
++      err = mc1n2_add_widgets(codec);
++      if (err < 0) {
++              dev_err(dev, "%d: Error in mc1n2_add_widgets\n", err);
++              goto error_add_ctl;
++      }
++
++      /* hwdep */
++      err = mc1n2_add_hwdep(codec);
++      if (err < 0) {
++              dev_err(dev, "%d: Error in mc1n2_add_hwdep\n", err);
++              goto error_add_hwdep;
++      }
++
++#if (defined ALSA_VER_1_0_19) || (defined ALSA_VER_1_0_21)
++      err = snd_soc_init_card(socdev);
++      if (err < 0) {
++              dev_err(dev, "%d: Error in snd_soc_init_card\n", err);
++              goto error_init_card;
++      }
++#endif
++
++#ifndef DIO0_DAI_ENABLE
++      update |= (MCDRV_DIO0_COM_UPDATE_FLAG | MCDRV_DIO0_DIR_UPDATE_FLAG | MCDRV_DIO0_DIT_UPDATE_FLAG);
++#endif
++
++#ifndef DIO1_DAI_ENABLE
++      update |= (MCDRV_DIO1_COM_UPDATE_FLAG | MCDRV_DIO1_DIR_UPDATE_FLAG | MCDRV_DIO1_DIT_UPDATE_FLAG);
++#endif
++
++#ifndef DIO2_DAI_ENABLE
++      update |= (MCDRV_DIO2_COM_UPDATE_FLAG | MCDRV_DIO2_DIR_UPDATE_FLAG | MCDRV_DIO2_DIT_UPDATE_FLAG);
++#endif
++
++      err = _McDrv_Ctrl(MCDRV_SET_DIGITALIO, (void *)&stDioInfo_Default, update);
++      if (err < 0) {
++              dev_err(dev, "%d: Error in MCDRV_SET_DIGITALIO\n", err);
++              goto error_set_mode;
++      }
++
++      err = _McDrv_Ctrl(MCDRV_SET_DAC, (void *)&stDacInfo_Default, 0x7);
++      if (err < 0) {
++              dev_err(dev, "%d: Error in MCDRV_SET_DAC\n", err);
++              goto error_set_mode;
++      }
++
++      err = _McDrv_Ctrl(MCDRV_SET_ADC, (void *)&stAdcInfo_Default, 0x7);
++      if (err < 0) {
++              dev_err(dev, "%d: Error in MCDRV_SET_ADC\n", err);
++              goto error_set_mode;
++      }
++
++      err = _McDrv_Ctrl(MCDRV_SET_SP, (void *)&stSpInfo_Default, 0);
++      if (err < 0) {
++              dev_err(dev, "%d: Error in MCDRV_SET_SP\n", err);
++              goto error_set_mode;
++      }
++
++      err = _McDrv_Ctrl(MCDRV_SET_DNG, (void *)&stDngInfo_Default, 0x3F3F3F);
++      if (err < 0) {
++              dev_err(dev, "%d: Error in MCDRV_SET_DNG\n", err);
++              goto error_set_mode;
++      }
++
++      if (mc1n2_hwid == MC1N2_HW_ID_AB) {
++              err = _McDrv_Ctrl(MCDRV_SET_SYSEQ, (void *)&stSyseqInfo_Default, 0x3);
++
++              if (err < 0) {
++                      dev_err(dev, "%d: Error in MCDRV_SET_SYSEQ\n", err);
++                      goto error_set_mode;
++              }
++      }
++#ifdef CONFIG_SND_SOC_PM_RUNTIME
++      pm_runtime_set_active(codec->dev);
++      pm_runtime_get_noresume(codec->dev);
++      pm_runtime_use_autosuspend(codec->dev);
++      pm_runtime_set_autosuspend_delay(codec->dev, MC1N2_PM_RUNTIME_DELAY_MS);
++      pm_runtime_enable(codec->dev);
++      pm_runtime_mark_last_busy(codec->dev);
++      pm_runtime_put_sync_autosuspend(codec->dev);
++#endif
++
++      return 0;
++
++error_set_mode:
++#if (defined ALSA_VER_1_0_19) || (defined ALSA_VER_1_0_21)
++error_init_card:
++#endif
++error_add_hwdep:
++error_add_ctl:
++#ifndef ALSA_VER_ANDROID_3_0
++      snd_soc_free_pcms(socdev);
++error_new_pcm:
++#endif
++      _McDrv_Ctrl(MCDRV_TERM, NULL, 0);
++error_init_hw:
++#ifndef ALSA_VER_ANDROID_3_0
++#ifdef ALSA_VER_1_0_19
++      socdev->codec = NULL;
++#else
++      socdev->card->codec = NULL;
++#endif
++#endif
++error_codec_data:
++      return err;
++}
++
++#ifdef ALSA_VER_ANDROID_3_0
++static int mc1n2_remove(struct snd_soc_codec *codec)
++{
++      int err;
++
++      TRACE_FUNC();
++
++      if (codec) {
++              err = _McDrv_Ctrl(MCDRV_TERM, NULL, 0);
++              if (err != MCDRV_SUCCESS) {
++                      dev_err(codec->dev, "%d: Error in MCDRV_TERM\n", err);
++                      return -EIO;
++              }
++      }
++      return 0;
++}
++#else
++static int mc1n2_remove(struct platform_device *pdev)
++{
++      struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++      int err;
++
++      TRACE_FUNC();
++
++#ifdef ALSA_VER_1_0_19
++      if (socdev->codec) {
++#else
++      if (socdev->card->codec) {
++#endif
++              snd_soc_free_pcms(socdev);
++
++              err = _McDrv_Ctrl(MCDRV_TERM, NULL, 0);
++              if (err != MCDRV_SUCCESS) {
++                      dev_err(socdev->dev, "%d: Error in MCDRV_TERM\n", err);
++                      return -EIO;
++              }
++      }
++
++      return 0;
++}
++#endif
++
++#ifdef ALSA_VER_ANDROID_3_0
++static int mc1n2_suspend(struct snd_soc_codec *codec, pm_message_t state)
++#else
++static int mc1n2_suspend(struct platform_device *pdev, pm_message_t state)
++#endif
++{
++#ifdef ALSA_VER_ANDROID_3_0
++      struct mc1n2_data *mc1n2 = snd_soc_codec_get_drvdata(codec);
++#else
++      struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++#ifdef ALSA_VER_1_0_19
++      struct snd_soc_codec *codec = socdev->codec;
++#else
++      struct snd_soc_codec *codec = socdev->card->codec;
++#endif
++#ifdef ALSA_VER_ANDROID_2_6_35
++      struct mc1n2_data *mc1n2 = snd_soc_codec_get_drvdata(codec);
++#else
++      struct mc1n2_data *mc1n2 = codec->private_data;
++#endif
++#endif
++      int err, i;
++
++      TRACE_FUNC();
++
++#ifdef CONFIG_SND_SOC_PM_RUNTIME
++      if (state.event == PM_EVENT_SUSPEND)
++              dev_dbg(codec->dev, "Suspend From ASoC suspend\n");
++      else if (state.event == PM_EVENT_AUTO_SUSPEND)
++              dev_dbg(codec->dev, "Suspend From Runtime suspend\n");
++#endif
++
++      mutex_lock(&mc1n2->mutex);
++#ifdef CONFIG_SND_SOC_PM_RUNTIME
++      if (mc1n2->suspended) {
++              dev_info(codec->dev, "Already suspended\n");
++              err = 0;
++              goto suspend_done;
++      } else
++              dev_info(codec->dev, "Suspending...\n");
++#endif
++
++      /* store parameters */
++      for (i = 0; i < MC1N2_N_INFO_STORE; i++) {
++              struct mc1n2_info_store *store = &mc1n2_info_store_tbl[i];
++              if (store->get) {
++                      err = _McDrv_Ctrl(store->get, (void *)mc1n2 + store->offset, 0);
++                      if (err != MCDRV_SUCCESS) {
++                              dev_err(codec->dev,
++                                      "%d: Error in mc1n2_suspend\n", err);
++                              err = -EIO;
++                              goto error;
++                      } else {
++                              err = 0;
++                      }
++              }
++      }
++
++      /* Do not enter suspend mode for voice call */
++      if(mc1n2_current_mode != MC1N2_MODE_IDLE) {
++              err = 0;
++              goto error;
++      }
++
++      err = _McDrv_Ctrl(MCDRV_TERM, NULL, 0);
++      if (err != MCDRV_SUCCESS) {
++              dev_err(codec->dev, "%d: Error in MCDRV_TERM\n", err);
++              err = -EIO;
++      } else {
++              err = 0;
++      }
++
++      /* Suepend MCLK */
++      mc1n2_set_mclk_source(0);
++#ifdef CONFIG_SND_SOC_PM_RUNTIME
++      mc1n2->suspended = 1;
++suspend_done:
++#endif
++error:
++      mutex_unlock(&mc1n2->mutex);
++
++      return err;
++}
++
++
++#ifdef ALSA_VER_ANDROID_3_0
++static int mc1n2_resume(struct snd_soc_codec *codec)
++#else
++static int mc1n2_resume(struct platform_device *pdev)
++#endif
++{
++#ifdef ALSA_VER_ANDROID_3_0
++      struct mc1n2_data *mc1n2 = snd_soc_codec_get_drvdata(codec);
++#else
++      struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++#ifdef ALSA_VER_1_0_19
++      struct snd_soc_codec *codec = socdev->codec;
++#else
++      struct snd_soc_codec *codec = socdev->card->codec;
++#endif
++#ifdef ALSA_VER_ANDROID_2_6_35
++      struct mc1n2_data *mc1n2 = snd_soc_codec_get_drvdata(codec);
++#else
++      struct mc1n2_data *mc1n2 = codec->private_data;
++#endif
++#endif
++      SINT16 *vol = (SINT16 *)&mc1n2->vol_store;
++      int err, i;
++
++      TRACE_FUNC();
++
++      mutex_lock(&mc1n2->mutex);
++#ifdef CONFIG_SND_SOC_PM_RUNTIME
++      if (!mc1n2->suspended) {
++              dev_info(codec->dev, "Already resumed\n");
++              err = 0;
++              goto resume_done;
++      } else
++              dev_info(codec->dev, "Resuming...\n");
++#endif
++
++      /* Resume MCLK */
++      mc1n2_set_mclk_source(1);
++
++      err = _McDrv_Ctrl(MCDRV_INIT, &mc1n2->setup.init, 0);
++      if (err != MCDRV_SUCCESS) {
++              dev_err(codec->dev, "%d: Error in MCDRV_INIT\n", err);
++              err = -EIO;
++              goto error;
++      } else {
++              err = 0;
++      }
++
++      /* restore parameters */
++      for (i = 0; i < sizeof(MCDRV_VOL_INFO)/sizeof(SINT16); i++, vol++) {
++              *vol |= 0x0001;
++      }
++
++      for (i = 0; i < MC1N2_N_INFO_STORE; i++) {
++              struct mc1n2_info_store *store = &mc1n2_info_store_tbl[i];
++              if (store->set) {
++                      err = _McDrv_Ctrl(store->set, (void *)mc1n2 + store->offset,
++                                        store->flags);
++                      if (err != MCDRV_SUCCESS) {
++                              dev_err(codec->dev,
++                                      "%d: Error in mc1n2_resume\n", err);
++                              err = -EIO;
++                              goto error;
++                      } else {
++                              err = 0;
++                      }
++              }
++      }
++#ifdef CONFIG_SND_SOC_PM_RUNTIME
++      mc1n2->suspended = 0;
++resume_done:
++#endif
++error:
++      mutex_unlock(&mc1n2->mutex);
++
++      return err;
++}
++
++#ifdef CONFIG_SND_SOC_PM_RUNTIME
++static int mc1n2_runtime_suspend(struct device *dev)
++{
++      struct snd_soc_codec *codec = mc1n2_get_codec_data();
++      int err = 0;
++
++      err = mc1n2_suspend(codec, PMSG_AUTO_SUSPEND);
++      if (err)
++              dev_err(dev, "%s failed\n", __func__);
++
++      return err;
++}
++
++static int mc1n2_runtime_resume(struct device *dev)
++{
++      struct snd_soc_codec *codec = mc1n2_get_codec_data();
++      int err = 0;
++
++      err = mc1n2_resume(codec);
++      if (err)
++              dev_err(dev, "%s failed\n", __func__);
++
++      return err;
++}
++
++static int mc1n2_set_bias_level(struct snd_soc_codec *codec,
++                              enum snd_soc_bias_level level)
++{
++      /* just update bias level flag */
++      pr_info("MC1N2: bias_level: %d\n", level);
++      codec->dapm.bias_level = level;
++      return 0;
++}
++#endif
++
++#ifdef ALSA_VER_ANDROID_3_0
++struct snd_soc_codec_driver soc_codec_dev_mc1n2 = {
++      .probe = mc1n2_probe,
++      .remove = mc1n2_remove,
++      .suspend = mc1n2_suspend,
++      .resume = mc1n2_resume,
++      .read = mc1n2_read_reg,
++      .write = mc1n2_write_reg,
++      .reg_cache_size = MC1N2_N_REG,
++      .reg_word_size = sizeof(u16),
++      .reg_cache_step = 1,
++#ifdef CONFIG_SND_SOC_PM_RUNTIME
++      .set_bias_level = mc1n2_set_bias_level,
++#endif
++};
++#else
++struct snd_soc_codec_device soc_codec_dev_mc1n2 = {
++      .probe = mc1n2_probe,
++      .remove = mc1n2_remove,
++      .suspend = mc1n2_suspend,
++      .resume = mc1n2_resume
++};
++EXPORT_SYMBOL_GPL(soc_codec_dev_mc1n2);
++#endif
++
++/*
++ * I2C client
++ */
++static int mc1n2_i2c_detect(struct i2c_client *client, struct i2c_board_info *info)
++{
++      UINT8   bHwid = mc1n2_i2c_read_byte(client, 8);
++
++      if (bHwid != MC1N2_HW_ID_AB && bHwid != MC1N2_HW_ID_AA) {
++              return -ENODEV;
++      }
++      mc1n2_hwid = bHwid;
++
++      return 0;
++}
++
++static void mc1n2_dt_set_sub_mic_bias(struct device *dev, bool on)
++{
++      struct mc1n2_data *data = dev_get_drvdata(dev);
++
++      gpio_set_value(data->gpio_sub_mic_bias, on);
++}
++
++static void mc1n2_dt_set_main_mic_bias(struct device *dev, bool on)
++{
++      struct mc1n2_data *data = dev_get_drvdata(dev);
++
++      gpio_set_value(data->gpio_main_mic_bias, on);
++}
++
++static int mc1n2_dt_set_adc_power_constraints(struct device *dev, int disabled)
++{
++      struct mc1n2_data *data = dev_get_drvdata(dev);
++
++      if (!disabled)
++              regulator_enable(data->regulator);
++      else if (regulator_is_enabled(data->regulator))
++              regulator_force_disable(data->regulator);
++
++      return 0;
++}
++
++static struct mc1n2_platform_data *mc1n2_parse_dt(struct mc1n2_data *data,
++                                                      struct device *dev)
++{
++      struct device_node *np = dev->of_node;
++      struct mc1n2_platform_data *pdata;
++
++      pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
++      if (!pdata) {
++              dev_err(dev, "failed to allocate platform data\n");
++              return ERR_PTR(-ENOMEM);
++      }
++
++      data->regulator = devm_regulator_get(dev, "vadc");
++      if (IS_ERR(data->regulator)) {
++              dev_err(dev, "failed to get regulator\n");
++              return ERR_PTR(PTR_ERR(data->regulator));
++      }
++
++      data->gpio_main_mic_bias = of_get_gpio(np, 0);
++      if (!gpio_is_valid(data->gpio_main_mic_bias)) {
++              dev_err(dev, "failed to get main mic bias GPIO\n");
++              return ERR_PTR(data->gpio_main_mic_bias);
++      }
++
++      data->gpio_sub_mic_bias = of_get_gpio(np, 1);
++      if (!gpio_is_valid(data->gpio_sub_mic_bias)) {
++              dev_err(dev, "failed to get sub mic bias GPIO\n");
++              return ERR_PTR(data->gpio_sub_mic_bias);
++      }
++
++      pdata->set_main_mic_bias = mc1n2_dt_set_main_mic_bias;
++      pdata->set_sub_mic_bias = mc1n2_dt_set_sub_mic_bias;
++      pdata->set_adc_power_constraints = mc1n2_dt_set_adc_power_constraints;
++
++      return pdata;
++}
++
++static int mc1n2_i2c_probe(struct i2c_client *client,
++                         const struct i2c_device_id *id)
++{
++      struct snd_soc_codec *codec;
++      struct mc1n2_data *mc1n2;
++      int err;
++
++      TRACE_FUNC();
++
++      /* setup codec data */
++      if (!(codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL))) {
++              err = -ENOMEM;
++              goto err_alloc_codec;
++      }
++      codec->name = MC1N2_NAME;
++//    codec->owner = THIS_MODULE;
++      mutex_init(&codec->mutex);
++      codec->dev = &client->dev;
++
++      if (!(mc1n2 = kzalloc(sizeof(struct mc1n2_data), GFP_KERNEL))) {
++              err = -ENOMEM;
++              goto err_alloc_data;
++      }
++      mutex_init(&mc1n2->mutex);
++#if (defined ALSA_VER_ANDROID_2_6_35) || (defined ALSA_VER_ANDROID_3_0)
++      snd_soc_codec_set_drvdata(codec, mc1n2);
++#else
++      codec->private_data = mc1n2;
++#endif
++
++      mc1n2->hdmicount = 0;
++      mc1n2->lineoutenable = 0;
++      mc1n2->pdata = client->dev.platform_data;
++
++      if (client->dev.of_node) {
++              mc1n2->pdata = mc1n2_parse_dt(mc1n2, &client->dev);
++              if (IS_ERR(mc1n2->pdata)) {
++                      dev_err(&client->dev, "failed to parse DT data\n");
++                      return PTR_ERR(mc1n2->pdata);
++              }
++      }
++
++      /* setup i2c client data */
++      if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
++              err = -ENODEV;
++              goto err_i2c;
++      }
++
++      if ((err = mc1n2_i2c_detect(client, NULL)) < 0) {
++              goto err_i2c;
++      }
++
++
++#ifdef ALSA_VER_ANDROID_3_0
++      i2c_set_clientdata(client, mc1n2);
++#ifdef CONFIG_SND_SOC_PM_RUNTIME
++      mc1n2_set_codec_data(codec);
++#endif
++#else
++      i2c_set_clientdata(client, codec);
++
++      codec->control_data = client;
++      codec->read = mc1n2_read_reg;
++      codec->write = mc1n2_write_reg;
++      codec->hw_write = NULL;
++      codec->hw_read = NULL;
++      codec->reg_cache = kzalloc(sizeof(u16) * MC1N2_N_REG, GFP_KERNEL);
++      if (codec->reg_cache == NULL) {
++              err = -ENOMEM;
++              goto err_alloc_cache;
++      }
++      codec->reg_cache_size = MC1N2_N_REG;
++      codec->reg_cache_step = 1;
++      INIT_LIST_HEAD(&codec->dapm_widgets);
++      INIT_LIST_HEAD(&codec->dapm_paths);
++      codec->dai = mc1n2_dai;
++      codec->num_dai = ARRAY_SIZE(mc1n2_dai);
++      mc1n2_set_codec_data(codec);
++#endif
++
++#ifdef ALSA_VER_ANDROID_3_0
++      if ((err = snd_soc_register_codec(&client->dev, &soc_codec_dev_mc1n2,
++                                                                        mc1n2_dai, ARRAY_SIZE(mc1n2_dai))) < 0) {
++              goto err_reg_codec;
++      }
++
++      mc1n2_i2c = client;
++#else
++      if ((err = snd_soc_register_codec(codec)) < 0) {
++              goto err_reg_codec;
++      }
++
++      /* setup DAI data */
++      for (i = 0; i < ARRAY_SIZE(mc1n2_dai); i++) {
++              mc1n2_dai[i].dev = &client->dev;
++      }
++        if ((err = snd_soc_register_dais(mc1n2_dai, ARRAY_SIZE(mc1n2_dai))) < 0) {
++              goto err_reg_dai;
++      }
++#endif
++
++      return 0;
++
++#ifndef ALSA_VER_ANDROID_3_0
++err_reg_dai:
++      snd_soc_unregister_codec(codec);
++#endif
++err_reg_codec:
++#ifndef ALSA_VER_ANDROID_3_0
++      kfree(codec->reg_cache);
++err_alloc_cache:
++#endif
++      i2c_set_clientdata(client, NULL);
++err_i2c:
++      kfree(mc1n2);
++err_alloc_data:
++      kfree(codec);
++err_alloc_codec:
++      dev_err(&client->dev, "err=%d: failed to probe MC-1N2\n", err);
++      return err;
++}
++
++static int mc1n2_i2c_remove(struct i2c_client *client)
++{
++#ifndef ALSA_VER_ANDROID_3_0
++      struct snd_soc_codec *codec = i2c_get_clientdata(client);
++#endif
++      struct mc1n2_data *mc1n2;
++
++      TRACE_FUNC();
++
++#ifdef ALSA_VER_ANDROID_3_0
++      mc1n2 = (struct mc1n2_data*)(i2c_get_clientdata(client));
++      mutex_destroy(&mc1n2->mutex);
++      snd_soc_unregister_codec(&client->dev);
++#else
++      if (codec) {
++#ifdef ALSA_VER_ANDROID_2_6_35
++              mc1n2 = snd_soc_codec_get_drvdata(codec);
++#else
++              mc1n2 = codec->private_data;
++#endif
++              snd_soc_unregister_dais(mc1n2_dai, ARRAY_SIZE(mc1n2_dai));
++              snd_soc_unregister_codec(codec);
++
++              mutex_destroy(&mc1n2->mutex);
++              kfree(mc1n2);
++
++              mutex_destroy(&codec->mutex);
++              kfree(codec);
++      }
++#endif
++
++      return 0;
++}
++
++/*
++ * Function to prevent tick-noise when reboot menu selected.
++ * if you have Power-Off sound and same problem, use this function
++ */
++static void mc1n2_i2c_shutdown(struct i2c_client *client)
++{
++#ifndef ALSA_VER_ANDROID_3_0
++      struct snd_soc_codec *codec = i2c_get_clientdata(client);
++#endif
++      struct mc1n2_data *mc1n2;
++      int err, i;
++
++      pr_info("%s\n", __func__);
++
++      TRACE_FUNC();
++
++#ifdef ALSA_VER_ANDROID_3_0
++      mc1n2 = (struct mc1n2_data *)(i2c_get_clientdata(client));
++#else
++#ifdef ALSA_VER_ANDROID_2_6_35
++      mc1n2 = snd_soc_codec_get_drvdata(codec);
++#else
++      mc1n2 = codec->private_data;
++#endif
++#endif
++
++      mutex_lock(&mc1n2->mutex);
++#ifdef CONFIG_SND_SOC_PM_RUNTIME
++      if (mc1n2->suspended) {
++              err = 0;
++              goto error;
++      }
++#endif
++
++      /* store parameters */
++      for (i = 0; i < MC1N2_N_INFO_STORE; i++) {
++              struct mc1n2_info_store *store = &mc1n2_info_store_tbl[i];
++              if (store->get) {
++                      err = _McDrv_Ctrl(store->get,
++                              (void *)mc1n2 + store->offset, 0);
++                      if (err != MCDRV_SUCCESS) {
++                              pr_err("%d: Error in mc1n2_suspend\n", err);
++                              err = -EIO;
++                              goto error;
++                      } else {
++                              err = 0;
++                      }
++              }
++      }
++
++      /* Do not enter suspend mode for voice call */
++      if (mc1n2_current_mode != MC1N2_MODE_IDLE) {
++              err = 0;
++              goto error;
++      }
++
++      err = _McDrv_Ctrl(MCDRV_TERM, NULL, 0);
++      if (err != MCDRV_SUCCESS) {
++              pr_err("%d: Error in MCDRV_TERM\n", err);
++              err = -EIO;
++      } else {
++              err = 0;
++      }
++
++      /* Suepend MCLK */
++      mc1n2_set_mclk_source(0);
++
++      pr_info("%s done\n", __func__);
++
++error:
++      mutex_unlock(&mc1n2->mutex);
++
++      if (err != 0)
++              pr_err("%s: err = %d\n", __func__, err);
++
++      return;
++}
++
++static const struct i2c_device_id mc1n2_i2c_id[] = {
++      {MC1N2_NAME, 0},
++      {},
++};
++MODULE_DEVICE_TABLE(i2c, mc1n2_i2c_id);
++
++static struct of_device_id mc1n2_of_matches[] = {
++      { .compatible = "yamaha,mc1n2", },
++      {},
++};
++
++#ifdef CONFIG_SND_SOC_PM_RUNTIME
++static const struct dev_pm_ops mc1n2_i2c_pm_ops = {
++      .runtime_suspend = mc1n2_runtime_suspend,
++      .runtime_resume = mc1n2_runtime_resume,
++};
++#endif
++static struct i2c_driver mc1n2_i2c_driver = {
++      .driver = {
++              .name = MC1N2_NAME,
++              .owner = THIS_MODULE,
++              .of_match_table = mc1n2_of_matches,
++#ifdef CONFIG_SND_SOC_PM_RUNTIME
++              .pm = &mc1n2_i2c_pm_ops,
++#endif
++      },
++      .probe = mc1n2_i2c_probe,
++      .remove = mc1n2_i2c_remove,
++      .shutdown = mc1n2_i2c_shutdown,
++      .id_table = mc1n2_i2c_id,
++};
++
++/*
++ * Module init and exit
++ */
++static int __init mc1n2_init(void)
++{
++      return i2c_add_driver(&mc1n2_i2c_driver);
++}
++module_init(mc1n2_init);
++
++static void __exit mc1n2_exit(void)
++{
++      i2c_del_driver(&mc1n2_i2c_driver);
++}
++module_exit(mc1n2_exit);
++
++MODULE_AUTHOR("Yamaha Corporation");
++MODULE_DESCRIPTION("Yamaha MC-1N2 ALSA SoC codec driver");
++MODULE_LICENSE("GPL");
++MODULE_VERSION(MC1N2_DRIVER_VERSION);
+diff --git a/sound/soc/codecs/mc1n2/mc1n2.h b/sound/soc/codecs/mc1n2/mc1n2.h
+new file mode 100644
+index 0000000..8167f7c
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mc1n2.h
+@@ -0,0 +1,126 @@
++/*
++ * MC-1N2 ASoC codec driver
++ *
++ * Copyright (c) 2010-2011 Yamaha Corporation
++ *
++ * This software is provided 'as-is', without any express or implied
++ * warranty.  In no event will the authors be held liable for any damages
++ * arising from the use of this software.
++ *
++ * Permission is granted to anyone to use this software for any purpose,
++ * including commercial applications, and to alter it and redistribute it
++ * freely, subject to the following restrictions:
++ *
++ * 1. The origin of this software must not be misrepresented; you must not
++ *    claim that you wrote the original software. If you use this software
++ *    in a product, an acknowledgment in the product documentation would be
++ *    appreciated but is not required.
++ * 2. Altered source versions must be plainly marked as such, and must not be
++ *    misrepresented as being the original software.
++ * 3. This notice may not be removed or altered from any source distribution.
++ */
++
++#ifndef MC1N2_H
++#define MC1N2_H
++
++#include "mcdriver.h"
++#include <linux/mfd/mc1n2_pdata.h>
++
++/*
++ * dai: set_sysclk
++ */
++/* clk_id */
++#define MC1N2_CLKI              0
++
++/* default freq for MC1N2_CLKI */
++#define MC1N2_DEFAULT_CLKI      19200000
++
++/*
++ * dai: set_clkdiv
++ */
++/* div_id */
++#define MC1N2_CKSEL             0
++#define MC1N2_DIVR0             1
++#define MC1N2_DIVF0             2
++#define MC1N2_DIVR1             3
++#define MC1N2_DIVF1             4
++#define MC1N2_BCLK_MULT         5
++
++/* div for MC1N2_BCLK_MULT */
++#define MC1N2_LRCK_X8           0
++#define MC1N2_LRCK_X16          1
++#define MC1N2_LRCK_X24          2
++#define MC1N2_LRCK_X32          3
++#define MC1N2_LRCK_X48          4
++#define MC1N2_LRCK_X64          5
++#define MC1N2_LRCK_X128         6
++#define MC1N2_LRCK_X256         7
++#define MC1N2_LRCK_X512         8
++
++/*
++ * hwdep: ioctl
++ */
++#define MC1N2_MAGIC             'N'
++#define MC1N2_IOCTL_NR_GET      1
++#define MC1N2_IOCTL_NR_SET      2
++#define MC1N2_IOCTL_NR_BOTH     3
++#define MC1N2_IOCTL_NR_NOTIFY   4
++
++#define MC1N2_IOCTL_GET_CTRL \
++      _IOR(MC1N2_MAGIC, MC1N2_IOCTL_NR_GET, struct mc1n2_ctrl_args)
++#define MC1N2_IOCTL_SET_CTRL \
++      _IOW(MC1N2_MAGIC, MC1N2_IOCTL_NR_SET, struct mc1n2_ctrl_args)
++
++#define MC1N2_IOCTL_READ_REG \
++      _IOWR(MC1N2_MAGIC, MC1N2_IOCTL_NR_BOTH, struct mc1n2_ctrl_args)
++
++#define MC1N2_IOCTL_NOTIFY \
++      _IOW(MC1N2_MAGIC, MC1N2_IOCTL_NR_NOTIFY, struct mc1n2_ctrl_args)
++
++struct mc1n2_ctrl_args {
++      unsigned long dCmd;
++      void *pvPrm;
++      unsigned long dPrm;
++};
++
++/*
++ * MC1N2_IOCTL_NOTIFY dCmd definitions
++ */
++#define MCDRV_NOTIFY_CALL_START               0x00000000
++#define MCDRV_NOTIFY_CALL_STOP                0x00000001
++#define MCDRV_NOTIFY_MEDIA_PLAY_START 0x00000002
++#define MCDRV_NOTIFY_MEDIA_PLAY_STOP  0x00000003
++#define MCDRV_NOTIFY_FM_PLAY_START    0x00000004
++#define MCDRV_NOTIFY_FM_PLAY_STOP     0x00000005
++#define MCDRV_NOTIFY_BT_SCO_ENABLE    0x00000006
++#define MCDRV_NOTIFY_BT_SCO_DISABLE   0x00000007
++#define MCDRV_NOTIFY_VOICE_REC_START  0x00000008
++#define MCDRV_NOTIFY_VOICE_REC_STOP   0x00000009
++#define MCDRV_NOTIFY_HDMI_START               0x0000000A
++#define MCDRV_NOTIFY_HDMI_STOP                0x0000000B
++#define       MCDRV_NOTIFY_RECOVER            0x0000000C
++#define MCDRV_NOTIFY_2MIC_CALL_START  0x0000000D
++#define MCDRV_NOTIFY_LINEOUT_START    0x00000010
++#define MCDRV_NOTIFY_LINEOUT_STOP     0x00000011
++
++#define MC1N2_MODE_IDLE                       (0x00)
++#define MC1N2_MODE_CALL_ON            (0x1<<0)
++#define MC1N2_MODE_FM_ON              (0x1<<1)
++
++/*
++ * Setup parameters
++ */
++struct mc1n2_setup {
++      MCDRV_INIT_INFO init;
++      unsigned char pcm_extend[IOPORT_NUM];
++      unsigned char pcm_hiz_redge[IOPORT_NUM];
++      unsigned char pcm_hperiod[IOPORT_NUM];
++      unsigned char slot[IOPORT_NUM][SNDRV_PCM_STREAM_LAST+1][DIO_CHANNELS];
++};
++
++/*
++ * Codec Status definitions (for backward compatibility)
++ */
++#define CMD_CODEC_EMERGENCY_RECOVERY 9 // Emergency recovery for Error like -EIO, -ESTRPIPE, and etc.
++
++#endif
+diff --git a/sound/soc/codecs/mc1n2/mc1n2_cfg.h b/sound/soc/codecs/mc1n2/mc1n2_cfg.h
+new file mode 100644
+index 0000000..dc7ce48
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mc1n2_cfg.h
+@@ -0,0 +1,1199 @@
++/*
++ * MC-1N2 ASoC codec driver
++ *
++ * Copyright (c) 2010-2011 Yamaha Corporation
++ *
++ * This software is provided 'as-is', without any express or implied
++ * warranty.  In no event will the authors be held liable for any damages
++ * arising from the use of this software.
++ *
++ * Permission is granted to anyone to use this software for any purpose,
++ * including commercial applications, and to alter it and redistribute it
++ * freely, subject to the following restrictions:
++ *
++ * 1. The origin of this software must not be misrepresented; you must not
++ *    claim that you wrote the original software. If you use this software
++ *    in a product, an acknowledgment in the product documentation would be
++ *    appreciated but is not required.
++ * 2. Altered source versions must be plainly marked as such, and must not be
++ *    misrepresented as being the original software.
++ * 3. This notice may not be removed or altered from any source distribution.
++ */
++
++#ifndef MC1N2_CFG_H
++#define MC1N2_CFG_H
++
++#include "mcdriver.h"
++
++/*
++ * ALSA Version
++ */
++/* #define ALSA_VER_1_0_19 */
++/* #define ALSA_VER_1_0_21 */
++/* #define ALSA_VER_1_0_23 */
++/* #define ALSA_VER_ANDROID_2_6_35 */
++#define ALSA_VER_ANDROID_3_0
++
++#define DIO0_DAI_ENABLE
++/* #define DIO1_DAI_ENABLE */
++/* #define DIO2_DAI_ENABLE */
++
++#ifdef ALSA_VER_ANDROID_3_0
++static struct mc1n2_setup mc1n2_cfg_setup = {
++      {  /* MCDRV_INIT_INFO */
++              MCDRV_CKSEL_CMOS, /* bCkSel */
++              41,               /* bDivR0 */
++              126,              /* bDivF0 */
++              41,               /* bDivR1 */
++              126,              /* bDivF1 */
++              0,                /* bRange0*/
++              0,                /* bRange1*/
++              0,                /* bBypass*/
++              MCDRV_DAHIZ_LOW,  /* bDioSdo0Hiz */
++              MCDRV_DAHIZ_LOW,  /* bDioSdo1Hiz */
++              MCDRV_DAHIZ_LOW,  /* bDioSdo2Hiz */
++              MCDRV_DAHIZ_HIZ,  /* bDioClk0Hiz */
++              MCDRV_DAHIZ_HIZ,  /* bDioClk1Hiz */
++              MCDRV_DAHIZ_HIZ,  /* bDioClk2Hiz */
++              MCDRV_PCMHIZ_HIZ, /* bPcmHiz */
++              MCDRV_LINE_STEREO,/* bLineIn1Dif */
++              0,                /* bLineIn2Dif */
++              MCDRV_LINE_STEREO,/* bLineOut1Dif */
++              MCDRV_LINE_STEREO,/* bLineOUt2Dif */
++              MCDRV_SPMN_ON,    /* bSpmn */
++              MCDRV_MIC_DIF,    /* bMic1Sng */
++              MCDRV_MIC_DIF,    /* bMic2Sng */
++              MCDRV_MIC_DIF,    /* bMic3Sng */
++              MCDRV_POWMODE_NORMAL, /* bPowerMode */
++              MCDRV_SPHIZ_PULLDOWN, /* bSpHiz */
++              MCDRV_LDO_ON,     /* bLdo */
++              MCDRV_PAD_GPIO,   /* bPad0Func */
++              MCDRV_PAD_GPIO,   /* bPad1Func */
++              MCDRV_PAD_GPIO,   /* bPad2Func */
++              MCDRV_OUTLEV_4,   /* bAvddLev */
++              0,                /* bVrefLev */
++              MCDRV_DCLGAIN_12, /* bDclGain */
++              MCDRV_DCLLIMIT_0, /* bDclLimit */
++              1,                   /* set Hi-power mode 0: HP mode 1: normal */
++              0,                /* bReserved1 */
++              0,                /* bReserved2 */
++              0,                /* bReserved3 */
++              0,                /* bReserved4 */
++              0,                /* bReserved5 */
++              {                 /* sWaitTime */
++                      130000,         /* dAdHpf */
++                      25000,          /* dMic1Cin */
++                      25000,          /* dMic2Cin */
++                      25000,          /* dMic3Cin */
++                      25000,          /* dLine1Cin */
++                      25000,          /* dLine2Cin */
++                      5000,           /* dVrefRdy1 */
++                      15000,          /* dVrefRdy2 */
++                      9000,           /* dHpRdy */
++                      13000,          /* dSpRdy */
++                      0,              /* dPdm */
++                      1000,           /* dAnaRdyInterval */
++                      1000,           /* dSvolInterval */
++                      1000,           /* dAnaRdyTimeOut */
++                      1000            /* dSvolTimeOut */
++              }
++      }, /* MCDRV_INIT_INFO end */
++      {  /* pcm_extend */
++              0, 0, 0
++      }, /* pcm_extend end */
++      {  /* pcm_hiz_redge */
++              MCDRV_PCMHIZTIM_FALLING, MCDRV_PCMHIZTIM_FALLING, MCDRV_PCMHIZTIM_FALLING
++      }, /* pcm_hiz_redge end */
++      {  /* pcm_hperiod */
++              1, 1, 1
++      }, /* pcm_hperiod end */
++      {  /* slot */
++              { {0, 1}, {0, 1} },
++              { {0, 1}, {0, 1} },
++              { {0, 1}, {0, 1} }
++      }  /* slot end */
++};
++#endif
++
++static const MCDRV_DIO_INFO stDioInfo_Default = {
++      {
++              /* DIO port 0 */
++              {
++                      /* sDioCommon */
++                      {
++                              /* bMasterSlave : Master / Slave Setting */
++                              /*     MCDRV_DIO_SLAVE (0)  : Slave      */
++                              /*     MCDRV_DIO_MASTER(1)  : Master     */
++                              MCDRV_DIO_MASTER,
++                              /* bAutoFs : Sampling frequency automatic measurement ON/OFF Setting in slave mode */
++                              /*     MCDRV_AUTOFS_OFF(0)  : OFF */
++                              /*     MCDRV_AUTOFS_ON (1)  : ON  */
++                              MCDRV_AUTOFS_ON ,
++                              /* bFs : Sampling Rate Setting        */
++                              /*     MCDRV_FS_48000(0)  : 48kHz     */
++                              /*     MCDRV_FS_44100(1)  : 44.1kHz   */
++                              /*     MCDRV_FS_32000(2)  : 32kHz     */
++                              /*     MCDRV_FS_24000(4)  : 24kHz     */
++                              /*     MCDRV_FS_22050(5)  : 22.05kHz  */
++                              /*     MCDRV_FS_16000(6)  : 16kHz     */
++                              /*     MCDRV_FS_12000(8)  : 12kHz     */
++                              /*     MCDRV_FS_11025(9)  : 11.025kHz */
++                              /*     MCDRV_FS_8000 (10) : 8kHz      */
++                              MCDRV_FS_44100,
++                              /* bBckFs : Bit Clock Frequency Setting */
++                              /*     MCDRV_BCKFS_64 (0)  : LRCK x  64 */
++                              /*     MCDRV_BCKFS_48 (1)  : LRCK x  48 */
++                              /*     MCDRV_BCKFS_32 (2)  : LRCK x  32 */
++                              /*     MCDRV_BCKFS_512(4)  : LRCK x 512 */
++                              /*     MCDRV_BCKFS_256(5)  : LRCK x 256 */
++                              /*     MCDRV_BCKFS_128(6)  : LRCK x 128 */
++                              /*     MCDRV_BCKFS_16 (7)  : LRCK x  16 */
++                              MCDRV_BCKFS_32,
++                              /* bInterface : Interface Selection      */
++                              /*     MCDRV_DIO_DA (0)  : Digital Audio */
++                              /*     MCDRV_DIO_PCM(1)  : PCM           */
++                              MCDRV_DIO_DA,
++                              /* bBckInvert : Bit Clock Inversion Setting     */
++                              /*     MCDRV_BCLK_NORMAL(0)  : Normal Operation */
++                              /*     MCDRV_BCLK_INVERT(1)  : Clock Inverted   */
++                              MCDRV_BCLK_NORMAL,
++                              /* bPcmHizTim : High Impedance transition timing after transmitting the last PCM I/F data */
++                              /*     MCDRV_PCMHIZTIM_FALLING(0)  : BCLK#* Falling Edge */
++                              /*     MCDRV_PCMHIZTIM_RISING (1)  : BCLK#* Rising Edge  */
++                              MCDRV_PCMHIZTIM_FALLING,
++                              /* bPcmClkDown : Bit Clock Setting with PCM selected and Master selected                */
++                              /*     MCDRV_PCM_CLKDOWN_OFF (0)  : A bit clock value specified with bBckFs             */
++                              /*     MCDRV_PCM_CLKDOWN_HALF(1)  : A half of the bit clock value specified with bBckFs */
++                              MCDRV_PCM_CLKDOWN_OFF,
++                              /* bPcmFrame : Frame Mode Setting with PCM interface */
++                              /*     MCDRV_PCM_SHORTFRAME(0)  : Short Frame        */
++                              /*     MCDRV_PCM_LONGFRAME (1)  : Long Frame         */
++                              MCDRV_PCM_SHORTFRAME,
++                              /* bPcmHighPeriod : LR clock High time setting with PCM selected and Master selected */
++                              /*     0 to 31  : High level keeps during the period of time of         */
++                              /*                (setting value + 1) of the bit clock.                 */
++                              0,
++                      },
++                      /* sDir       */
++                      {
++                              /* wSrcRate : Sampling Rate Converter Setting */
++                              0,
++                              /* sDaFormat : Digital Audio Format Information */
++                              {
++                                      /* bBitSel : Bit Width Setting     */
++                                      /*     MCDRV_BITSEL_16(0)  : 16bit */
++                                      /*     MCDRV_BITSEL_20(1)  : 20bit */
++                                      /*     MCDRV_BITSEL_24(2)  : 24bit */
++                                      MCDRV_BITSEL_16,
++                                      /* bMode : Data Format Setting                             */
++                                      /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++                                      /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++                                      /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++                                      MCDRV_DAMODE_I2S
++                              },
++                              /* sPcmFormat : PCM Format Information */
++                              {
++                                      /* bMono : Mono / Stereo Setting  */
++                                      /*     MCDRV_PCM_STEREO(0) Stereo */
++                                      /*     MCDRV_PCM_MONO  (1) Mono   */
++                                      MCDRV_PCM_MONO ,
++                                      /* bOrder : Bit Order Setting                                     */
++                                      /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++                                      /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++                                      /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++                                      /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++                                      MCDRV_PCM_MSB_FIRST,
++                                      /* bLaw : Data Format Setting        */
++                                      /*     MCDRV_PCM_LINEAR(0)  : Linear */
++                                      /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++                                      /*     MCDRV_PCM_MULAW (2)  : u-Law */
++                                      MCDRV_PCM_LINEAR,
++                                      /* bBitSel : Bit Width Setting        */
++                                      /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++                                      /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++                                      /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++                                      /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++                                      MCDRV_PCM_BITSEL_8
++                              },
++                              /* asSlot : Setting of a slot number of data to be fed to each channel */
++                              {0, 1}
++                      },
++                      /* sDit       */
++                      {
++                              /* wSrcRate : Sampling Rate Converter Setting */
++                              0,
++                              /* sDaFormat : Digital Audio Format Information */
++                              {
++                                      /* bBitSel : Bit Width Setting     */
++                                      /*     MCDRV_BITSEL_16(0)  : 16bit */
++                                      /*     MCDRV_BITSEL_20(1)  : 20bit */
++                                      /*     MCDRV_BITSEL_24(2)  : 24bit */
++                                      MCDRV_BITSEL_16,
++                                      /* bMode : Data Format Setting                             */
++                                      /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++                                      /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++                                      /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++                                      MCDRV_DAMODE_I2S
++                              },
++                              /* sPcmFormat : PCM Format Information */
++                              {
++                                      /* bMono : Mono / Stereo Setting  */
++                                      /*     MCDRV_PCM_STEREO(0) Stereo */
++                                      /*     MCDRV_PCM_MONO  (1) Mono   */
++                                      MCDRV_PCM_MONO ,
++                                      /* bOrder : Bit Order Setting                                     */
++                                      /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++                                      /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++                                      /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++                                      /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++                                      MCDRV_PCM_MSB_FIRST,
++                                      /* bLaw : Data Format Setting        */
++                                      /*     MCDRV_PCM_LINEAR(0)  : Linear */
++                                      /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++                                      /*     MCDRV_PCM_MULAW (2)  : u-Law */
++                                      MCDRV_PCM_LINEAR,
++                                      /* bBitSel : Bit Width Setting        */
++                                      /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++                                      /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++                                      /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++                                      /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++                                      MCDRV_PCM_BITSEL_8
++                              },
++                              /* asSlot Setting of a slot number of data to be transmitted from each channel */
++                              {0, 1}
++                      }
++              },
++              /* DIO port 1 */
++              {
++                      /* sDioCommon */
++                      {
++                              /* bMasterSlave : Master / Slave Setting */
++                              /*     MCDRV_DIO_SLAVE (0)  : Slave      */
++                              /*     MCDRV_DIO_MASTER(1)  : Master     */
++                              MCDRV_DIO_SLAVE,
++                              /* bAutoFs : Sampling frequency automatic measurement ON/OFF Setting in slave mode */
++                              /*     MCDRV_AUTOFS_OFF(0)  : OFF */
++                              /*     MCDRV_AUTOFS_ON (1)  : ON  */
++                              MCDRV_AUTOFS_ON ,
++                              /* bFs : Sampling Rate Setting        */
++                              /*     MCDRV_FS_48000(0)  : 48kHz     */
++                              /*     MCDRV_FS_44100(1)  : 44.1kHz   */
++                              /*     MCDRV_FS_32000(2)  : 32kHz     */
++                              /*     MCDRV_FS_24000(4)  : 24kHz     */
++                              /*     MCDRV_FS_22050(5)  : 22.05kHz  */
++                              /*     MCDRV_FS_16000(6)  : 16kHz     */
++                              /*     MCDRV_FS_12000(8)  : 12kHz     */
++                              /*     MCDRV_FS_11025(9)  : 11.025kHz */
++                              /*     MCDRV_FS_8000 (10) : 8kHz      */
++                              MCDRV_FS_8000,
++                              /* bBckFs : Bit Clock Frequency Setting */
++                              /*     MCDRV_BCKFS_64 (0)  : LRCK x  64 */
++                              /*     MCDRV_BCKFS_48 (1)  : LRCK x  48 */
++                              /*     MCDRV_BCKFS_32 (2)  : LRCK x  32 */
++                              /*     MCDRV_BCKFS_512(4)  : LRCK x 512 */
++                              /*     MCDRV_BCKFS_256(5)  : LRCK x 256 */
++                              /*     MCDRV_BCKFS_128(6)  : LRCK x 128 */
++                              /*     MCDRV_BCKFS_16 (7)  : LRCK x  16 */
++                              MCDRV_BCKFS_32,
++                              /* bInterface : Interface Selection      */
++                              /*     MCDRV_DIO_DA (0)  : Digital Audio */
++                              /*     MCDRV_DIO_PCM(1)  : PCM           */
++                              MCDRV_DIO_DA,
++                              /* bBckInvert : Bit Clock Inversion Setting     */
++                              /*     MCDRV_BCLK_NORMAL(0)  : Normal Operation */
++                              /*     MCDRV_BCLK_INVERT(1)  : Clock Inverted   */
++                              MCDRV_BCLK_INVERT,
++                              /* bPcmHizTim : High Impedance transition timing after transmitting the last PCM I/F data */
++                              /*     MCDRV_PCMHIZTIM_FALLING(0)  : BCLK#* Falling Edge */
++                              /*     MCDRV_PCMHIZTIM_RISING (1)  : BCLK#* Rising Edge  */
++                              MCDRV_PCMHIZTIM_FALLING,
++                              /* bPcmClkDown : Bit Clock Setting with PCM selected and Master selected                */
++                              /*     MCDRV_PCM_CLKDOWN_OFF (0)  : A bit clock value specified with bBckFs             */
++                              /*     MCDRV_PCM_CLKDOWN_HALF(1)  : A half of the bit clock value specified with bBckFs */
++                              MCDRV_PCM_CLKDOWN_OFF,
++                              /* bPcmFrame : Frame Mode Setting with PCM interface */
++                              /*     MCDRV_PCM_SHORTFRAME(0)  : Short Frame        */
++                              /*     MCDRV_PCM_LONGFRAME (1)  : Long Frame         */
++                              MCDRV_PCM_SHORTFRAME,
++                              /* bPcmHighPeriod : LR clock High time setting with PCM selected and Master selected */
++                              /*     0 to 31  : High level keeps during the period of time of         */
++                              /*                (setting value + 1) of the bit clock.                 */
++                              0,
++                      },
++                      /* sDir       */
++                      {
++                              /* wSrcRate : Sampling Rate Converter Setting */
++                              0,
++                              /* sDaFormat : Digital Audio Format Information */
++                              {
++                                      /* bBitSel : Bit Width Setting     */
++                                      /*     MCDRV_BITSEL_16(0)  : 16bit */
++                                      /*     MCDRV_BITSEL_20(1)  : 20bit */
++                                      /*     MCDRV_BITSEL_24(2)  : 24bit */
++                                      MCDRV_BITSEL_16,
++                                      /* bMode : Data Format Setting                             */
++                                      /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++                                      /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++                                      /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++                                      MCDRV_DAMODE_I2S
++                              },
++                              /* sPcmFormat : PCM Format Information */
++                              {
++                                      /* bMono : Mono / Stereo Setting  */
++                                      /*     MCDRV_PCM_STEREO(0) Stereo */
++                                      /*     MCDRV_PCM_MONO  (1) Mono   */
++                                      MCDRV_PCM_STEREO ,
++                                      /* bOrder : Bit Order Setting                                     */
++                                      /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++                                      /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++                                      /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++                                      /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++                                      MCDRV_PCM_MSB_FIRST,
++                                      /* bLaw : Data Format Setting        */
++                                      /*     MCDRV_PCM_LINEAR(0)  : Linear */
++                                      /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++                                      /*     MCDRV_PCM_MULAW (2)  : u-Law */
++                                      MCDRV_PCM_LINEAR,
++                                      /* bBitSel : Bit Width Setting        */
++                                      /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++                                      /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++                                      /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++                                      /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++                                      MCDRV_PCM_BITSEL_16
++                              },
++                              /* asSlot : Setting of a slot number of data to be fed to each channel */
++                              {1, 1}
++                      },
++                      /* sDit       */
++                      {
++                              /* wSrcRate : Sampling Rate Converter Setting */
++                              0,
++                              /* sDaFormat : Digital Audio Format Information */
++                              {
++                                      /* bBitSel : Bit Width Setting     */
++                                      /*     MCDRV_BITSEL_16(0)  : 16bit */
++                                      /*     MCDRV_BITSEL_20(1)  : 20bit */
++                                      /*     MCDRV_BITSEL_24(2)  : 24bit */
++                                      MCDRV_BITSEL_16,
++                                      /* bMode : Data Format Setting                             */
++                                      /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++                                      /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++                                      /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++                                      MCDRV_DAMODE_I2S
++                              },
++                              /* sPcmFormat : PCM Format Information */
++                              {
++                                      /* bMono : Mono / Stereo Setting  */
++                                      /*     MCDRV_PCM_STEREO(0) Stereo */
++                                      /*     MCDRV_PCM_MONO  (1) Mono   */
++                                      MCDRV_PCM_STEREO ,
++                                      /* bOrder : Bit Order Setting                                     */
++                                      /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++                                      /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++                                      /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++                                      /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++                                      MCDRV_PCM_MSB_FIRST,
++                                      /* bLaw : Data Format Setting        */
++                                      /*     MCDRV_PCM_LINEAR(0)  : Linear */
++                                      /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++                                      /*     MCDRV_PCM_MULAW (2)  : u-Law */
++                                      MCDRV_PCM_LINEAR,
++                                      /* bBitSel : Bit Width Setting        */
++                                      /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++                                      /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++                                      /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++                                      /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++                                      MCDRV_PCM_BITSEL_16
++                              },
++                              /* asSlot Setting of a slot number of data to be transmitted from each channel */
++                              {1, 0}
++                      }
++              },
++              /* DIO port 2 */
++              {
++                      /* sDioCommon */
++                      {
++                              /* bMasterSlave : Master / Slave Setting */
++                              /*     MCDRV_DIO_SLAVE (0)  : Slave      */
++                              /*     MCDRV_DIO_MASTER(1)  : Master     */
++                              MCDRV_DIO_MASTER,
++                              /* bAutoFs : Sampling frequency automatic measurement ON/OFF Setting in slave mode */
++                              /*     MCDRV_AUTOFS_OFF(0)  : OFF */
++                              /*     MCDRV_AUTOFS_ON (1)  : ON  */
++                              MCDRV_AUTOFS_ON ,
++                              /* bFs : Sampling Rate Setting        */
++                              /*     MCDRV_FS_48000(0)  : 48kHz     */
++                              /*     MCDRV_FS_44100(1)  : 44.1kHz   */
++                              /*     MCDRV_FS_32000(2)  : 32kHz     */
++                              /*     MCDRV_FS_24000(4)  : 24kHz     */
++                              /*     MCDRV_FS_22050(5)  : 22.05kHz  */
++                              /*     MCDRV_FS_16000(6)  : 16kHz     */
++                              /*     MCDRV_FS_12000(8)  : 12kHz     */
++                              /*     MCDRV_FS_11025(9)  : 11.025kHz */
++                              /*     MCDRV_FS_8000 (10) : 8kHz      */
++                              MCDRV_FS_8000,
++                              /* bBckFs : Bit Clock Frequency Setting */
++                              /*     MCDRV_BCKFS_64 (0)  : LRCK x  64 */
++                              /*     MCDRV_BCKFS_48 (1)  : LRCK x  48 */
++                              /*     MCDRV_BCKFS_32 (2)  : LRCK x  32 */
++                              /*     MCDRV_BCKFS_512(4)  : LRCK x 512 */
++                              /*     MCDRV_BCKFS_256(5)  : LRCK x 256 */
++                              /*     MCDRV_BCKFS_128(6)  : LRCK x 128 */
++                              /*     MCDRV_BCKFS_16 (7)  : LRCK x  16 */
++                              MCDRV_BCKFS_32,
++                              /* bInterface : Interface Selection      */
++                              /*     MCDRV_DIO_DA (0)  : Digital Audio */
++                              /*     MCDRV_DIO_PCM(1)  : PCM           */
++                              MCDRV_DIO_PCM,
++                              /* bBckInvert : Bit Clock Inversion Setting     */
++                              /*     MCDRV_BCLK_NORMAL(0)  : Normal Operation */
++                              /*     MCDRV_BCLK_INVERT(1)  : Clock Inverted   */
++                              MCDRV_BCLK_NORMAL,
++                              /* bPcmHizTim : High Impedance transition timing after transmitting the last PCM I/F data */
++                              /*     MCDRV_PCMHIZTIM_FALLING(0)  : BCLK#* Falling Edge */
++                              /*     MCDRV_PCMHIZTIM_RISING (1)  : BCLK#* Rising Edge  */
++                              MCDRV_PCMHIZTIM_FALLING,
++                              /* bPcmClkDown : Bit Clock Setting with PCM selected and Master selected                */
++                              /*     MCDRV_PCM_CLKDOWN_OFF (0)  : A bit clock value specified with bBckFs             */
++                              /*     MCDRV_PCM_CLKDOWN_HALF(1)  : A half of the bit clock value specified with bBckFs */
++                              MCDRV_PCM_CLKDOWN_OFF,
++                              /* bPcmFrame : Frame Mode Setting with PCM interface */
++                              /*     MCDRV_PCM_SHORTFRAME(0)  : Short Frame        */
++                              /*     MCDRV_PCM_LONGFRAME (1)  : Long Frame         */
++                              MCDRV_PCM_SHORTFRAME,
++                              /* bPcmHighPeriod : LR clock High time setting with PCM selected and Master selected */
++                              /*     0 to 31  : High level keeps during the period of time of         */
++                              /*                (setting value + 1) of the bit clock.                 */
++                              0,
++                      },
++                      /* sDir       */
++                      {
++                              /* wSrcRate : Sampling Rate Converter Setting */
++                              0,
++                              /* sDaFormat : Digital Audio Format Information */
++                              {
++                                      /* bBitSel : Bit Width Setting     */
++                                      /*     MCDRV_BITSEL_16(0)  : 16bit */
++                                      /*     MCDRV_BITSEL_20(1)  : 20bit */
++                                      /*     MCDRV_BITSEL_24(2)  : 24bit */
++                                      MCDRV_BITSEL_16,
++                                      /* bMode : Data Format Setting                             */
++                                      /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++                                      /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++                                      /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++                                      MCDRV_DAMODE_HEADALIGN
++                              },
++                              /* sPcmFormat : PCM Format Information */
++                              {
++                                      /* bMono : Mono / Stereo Setting  */
++                                      /*     MCDRV_PCM_STEREO(0) Stereo */
++                                      /*     MCDRV_PCM_MONO  (1) Mono   */
++                                      MCDRV_PCM_STEREO ,
++                                      /* bOrder : Bit Order Setting                                     */
++                                      /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++                                      /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++                                      /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++                                      /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++                                      MCDRV_PCM_MSB_FIRST,
++                                      /* bLaw : Data Format Setting        */
++                                      /*     MCDRV_PCM_LINEAR(0)  : Linear */
++                                      /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++                                      /*     MCDRV_PCM_MULAW (2)  : u-Law */
++                                      MCDRV_PCM_LINEAR,
++                                      /* bBitSel : Bit Width Setting        */
++                                      /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++                                      /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++                                      /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++                                      /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++                                      MCDRV_PCM_BITSEL_16
++                              },
++                              /* asSlot : Setting of a slot number of data to be fed to each channel */
++                              {0, 0}
++                      },
++                      /* sDit       */
++                      {
++                              /* wSrcRate : Sampling Rate Converter Setting */
++                              0,
++                              /* sDaFormat : Digital Audio Format Information */
++                              {
++                                      /* bBitSel : Bit Width Setting     */
++                                      /*     MCDRV_BITSEL_16(0)  : 16bit */
++                                      /*     MCDRV_BITSEL_20(1)  : 20bit */
++                                      /*     MCDRV_BITSEL_24(2)  : 24bit */
++                                      MCDRV_BITSEL_16,
++                                      /* bMode : Data Format Setting                             */
++                                      /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++                                      /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++                                      /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++                                      MCDRV_DAMODE_HEADALIGN
++                              },
++                              /* sPcmFormat : PCM Format Information */
++                              {
++                                      /* bMono : Mono / Stereo Setting  */
++                                      /*     MCDRV_PCM_STEREO(0) Stereo */
++                                      /*     MCDRV_PCM_MONO  (1) Mono   */
++                                      MCDRV_PCM_MONO ,
++                                      /* bOrder : Bit Order Setting                                     */
++                                      /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++                                      /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++                                      /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++                                      /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++                                      MCDRV_PCM_MSB_FIRST,
++                                      /* bLaw : Data Format Setting        */
++                                      /*     MCDRV_PCM_LINEAR(0)  : Linear */
++                                      /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++                                      /*     MCDRV_PCM_MULAW (2)  : u-Law */
++                                      MCDRV_PCM_LINEAR,
++                                      /* bBitSel : Bit Width Setting        */
++                                      /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++                                      /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++                                      /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++                                      /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++                                      MCDRV_PCM_BITSEL_16
++                              },
++                              /* asSlot Setting of a slot number of data to be transmitted from each channel */
++                              {0, 1}
++                      }
++              }
++      }
++};
++
++/* ========================================
++   DAC settings
++   ========================================*/
++static const MCDRV_DAC_INFO stDacInfo_Default = {
++      /* bMasterSwap : DAC Master Path SWAP Setting                          */
++      /*     MCDRV_DSWAP_OFF      (0)  : No SWAP                             */
++      /*     MCDRV_DSWAP_SWAP     (1)  : SWAP                                */
++      /*     MCDRV_DSWAP_MUTE     (2)  : MUTE                                */
++      /*     MCDRV_DSWAP_RMVCENTER(3)  : Center Removed                      */
++      /*     MCDRV_DSWAP_MONO     (4)  : Mono                                */
++      /*     MCDRV_DSWAP_MONOHALF (5)  : Reserved (do not use this setting)  */
++      /*     MCDRV_DSWAP_BOTHL    (6)  : Lch data output in both Lch and Rch */
++      /*     MCDRV_DSWAP_BOTHR    (7)  : Rch data output in both Lch and Rch */
++      MCDRV_DSWAP_OFF,
++      /* bVoiceSwap : DAC Voice Path SWAP Setting                            */
++      /*     MCDRV_DSWAP_OFF      (0)  : No SWAP                             */
++      /*     MCDRV_DSWAP_SWAP     (1)  : SWAP                                */
++      /*     MCDRV_DSWAP_MUTE     (2)  : MUTE                                */
++      /*     MCDRV_DSWAP_RMVCENTER(3)  : Center Removed                      */
++      /*     MCDRV_DSWAP_MONO     (4)  : Mono (-6dB)                         */
++      /*     MCDRV_DSWAP_MONOHALF (5)  : Reserved (do not use this setting)  */
++      /*     MCDRV_DSWAP_BOTHL    (6)  : Lch data output in both Lch and Rch */
++      /*     MCDRV_DSWAP_BOTHR    (7)  : Rch data output in both Lch and Rch */
++      MCDRV_DSWAP_OFF,
++      /* bDcCut : HP, SP Protection DC-ct Filter Setting  */
++      /*     MCDRV_DCCUT_ON (0)  : DC-cut Filter ON       */
++      /*     MCDRV_DCCUT_OFF(1)  : DC-cut Filter OFF      */
++      MCDRV_DCCUT_ON
++};
++
++/* ========================================
++   ADC settings
++   ========================================*/
++
++static const MCDRV_ADC_INFO stAdcInfo_Default = {
++      /* bAgcAdjust : AGC Gain Control Range     */
++      /*     MCDRV_AGCADJ_24(0)  : -3dB to +24dB */
++      /*     MCDRV_AGCADJ_18(1)  : -3dB to +18dB */
++      /*     MCDRV_AGCADJ_12(2)  : -3dB to +12dB */
++      /*     MCDRV_AGCADJ_0 (3)  : -3dB to  +0dB */
++      MCDRV_AGCADJ_0,
++      /* bAgcOn : AGC ON/OFF Setting */
++      /*     MCDRV_AGC_OFF(0)  : OFF */
++      /*     MCDRV_AGC_ON (1)  : ON  */
++      MCDRV_AGC_OFF,
++      /* bMonot : Mono / Stereo Setting    */
++      /*     MCDRV_ADC_STEREO(0)  : Stereo */
++      /*     MCDRV_ADC_MONO  (1)  : Mono   */
++      MCDRV_ADC_STEREO
++};
++
++/* ========================================
++   SP settings
++   ========================================*/
++static const MCDRV_SP_INFO stSpInfo_Default = {
++      /* bSwap : Swap setting                */
++      /*     MCDRV_SPSWAP_OFF (0)  : No SWAP */
++      /*     MCDRV_SPSWAP_SWAP(1)  : SWAP    */
++      MCDRV_SPSWAP_OFF
++};
++
++/* ========================================
++   DNG settings
++   ========================================*/
++static const MCDRV_DNG_INFO stDngInfo_Default = {
++      /* bOnOff[] : Digital Noise Gate On/Off Setting */
++      /*     MCDRV_DNG_OFF(0)  : OFF                */
++      /*     MCDRV_DNG_ON (1)  : ON                 */
++      {MCDRV_DNG_OFF, MCDRV_DNG_OFF, MCDRV_DNG_OFF},
++
++      /* bThreshold[] : Threshold Setting    */
++      /*     MCDRV_DNG_THRES_30    (0) */
++      /*     MCDRV_DNG_THRES_36    (1) */
++      /*     MCDRV_DNG_THRES_42    (2) */
++      /*     MCDRV_DNG_THRES_48    (3) */
++      /*     MCDRV_DNG_THRES_54    (4) */
++      /*     MCDRV_DNG_THRES_60    (5) */
++      /*     MCDRV_DNG_THRES_66    (6) */
++      /*     MCDRV_DNG_THRES_72    (7) */
++      /*     MCDRV_DNG_THRES_78    (8) */
++      /*     MCDRV_DNG_THRES_84    (9) */
++      {MCDRV_DNG_THRES_60, MCDRV_DNG_THRES_60, MCDRV_DNG_THRES_60},
++
++      /* bHold[] : Hold Time Setting         */
++      /*     MCDRV_DNG_HOLD_30 (0)  :  30ms */
++      /*     MCDRV_DNG_HOLD_120(1)  : 120ms */
++      /*     MCDRV_DNG_HOLD_500(2)  : 500ms */
++      {MCDRV_DNG_HOLD_500, MCDRV_DNG_HOLD_500, MCDRV_DNG_HOLD_500},
++
++      /* bAttack[] : Attack Time Setting        */
++      /*     MCDRV_DNG_ATTACK_25   (0)  :   25ms */
++      /*     MCDRV_DNG_ATTACK_100  (1)  :  100ms */
++      /*     MCDRV_DNG_ATTACK_400  (2)  :  400ms */
++      /*     MCDRV_DNG_ATTACK_800  (3)  :  800ms */
++      {MCDRV_DNG_ATTACK_100, MCDRV_DNG_ATTACK_100, MCDRV_DNG_ATTACK_100},
++
++      /* bRelease[] : Release Time Setting        */
++      /*     MCDRV_DNG_RELEASE_7950(0)  : 7.95ms */
++      /*     MCDRV_DNG_RELEASE_470 (1)  : 0.47ms */
++      /*     MCDRV_DNG_RELEASE_940 (2)  : 0.94ms */
++      {MCDRV_DNG_RELEASE_940, MCDRV_DNG_RELEASE_940, MCDRV_DNG_RELEASE_940},
++
++      /* bTarget[] : Target Volume Setting        */
++      /*     MCDRV_DNG_TARGET_6    (0)  : -6dB  */
++      /*     MCDRV_DNG_TARGET_9    (1)  : -9dB  */
++      /*     MCDRV_DNG_TARGET_12   (2)  : -12dB */
++      /*     MCDRV_DNG_TARGET_15   (3)  : -15dB */
++      /*     MCDRV_DNG_TARGET_18   (4)  : -18dB */
++      /*     MCDRV_DNG_TARGET_MUTE (5)  : Mute  */
++      {MCDRV_DNG_TARGET_MUTE, MCDRV_DNG_TARGET_MUTE, MCDRV_DNG_TARGET_MUTE},
++};
++#if 0
++static const MCDRV_DNG_INFO stDngInfo_Default = {
++      /* bOnOff : Digital Noise Gate On/Off Setting */
++      /*     MCDRV_DNG_OFF(0)  : OFF                */
++      /*     MCDRV_DNG_ON (1)  : ON                 */
++      MCDRV_DNG_OFF,
++
++      /* bThreshold : Threshold Setting    */
++      /*     MCDRV_DNG_THRES_5BIT  (0) */
++      /*     MCDRV_DNG_THRES_7BIT  (1) */
++      /*     MCDRV_DNG_THRES_9BIT  (2) */
++      /*     MCDRV_DNG_THRES_11BIT (3) */
++      /*     MCDRV_DNG_THRES_13BIT (4) */
++      /*     MCDRV_DNG_THRES_15BIT (5) */
++      /*     MCDRV_DNG_THRES_17BIT (6) */
++      /*     MCDRV_DNG_THRES_21BIT (7) */
++      MCDRV_DNG_THRES_11BIT,
++
++      /* bHold : Hold Time Setting         */
++      /*     MCDRV_DNG_HOLD_30 (0)  :  30ms */
++      /*     MCDRV_DNG_HOLD_120(1)  : 120ms */
++      /*     MCDRV_DNG_HOLD_500(2)  : 500ms */
++      MCDRV_DNG_HOLD_500,
++
++      /* bAttack : Attack Time Setting        */
++      /*     MCDRV_DNG_ATTACK_25   (0)  :   25ms */
++      /*     MCDRV_DNG_ATTACK_800  (1)  :  800ms */
++      /*     MCDRV_DNG_ATTACK_1100 (2)  : 1100ms */
++      MCDRV_DNG_ATTACK_1100,
++
++      /* bRelease : Release Time Setting        */
++      /*     MCDRV_DNG_RELEASE_7950(0)  : 7.95ms */
++      /*     MCDRV_DNG_RELEASE_470 (1)  : 0.47ms */
++      /*     MCDRV_DNG_RELEASE_940 (2)  : 0.94ms */
++      MCDRV_DNG_RELEASE_940,
++
++};
++#endif
++
++/* ========================================
++   AudioEngine settings
++   ========================================*/
++static MCDRV_AE_INFO sAeInfo_1 = {
++      /* On/Off */
++      0x00,
++      /* BEX */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* WIDE */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00
++      },
++      /* DRC */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* EQ5 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00
++      },
++      /* EQ3 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00
++      }
++};
++
++static MCDRV_AE_INFO sAeInfo_2 = {
++      /* On/Off */
++      0x00,
++      /* BEX */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* WIDE */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00
++      },
++      /* DRC */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* EQ5 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00
++      },
++      /* EQ3 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00
++      }
++};
++
++static MCDRV_AE_INFO sAeInfo_3 = {
++      /* On/Off */
++      0x00,
++      /* BEX */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* WIDE */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00
++      },
++      /* DRC */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* EQ5 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00
++      },
++      /* EQ3 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00
++      }
++};
++
++static MCDRV_AE_INFO sAeInfo_4 = {
++      /* On/Off */
++      0x00,
++      /* BEX */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* WIDE */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00
++      },
++      /* DRC */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* EQ5 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00
++      },
++      /* EQ3 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00
++      }
++};
++
++static MCDRV_AE_INFO sAeInfo_5 = {
++      /* On/Off */
++      0x00,
++      /* BEX */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* WIDE */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00
++      },
++      /* DRC */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* EQ5 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00
++      },
++      /* EQ3 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00
++      }
++};
++
++/* ========================================
++   System EQ settings
++   ========================================*/
++static MCDRV_SYSEQ_INFO stSyseqInfo_Default = {
++      /* On/Off */
++      0x00,
++      /* EQ */
++      {
++              0x10,0xc4,0x50,0x12,0xc4,0x40,0x02,0xa9,
++              0x60,0xed,0x3b,0xc0,0xfc,0x92,0x40,
++      },
++};
++
++#endif
+diff --git a/sound/soc/codecs/mc1n2/mc1n2_cfg_gsm.h b/sound/soc/codecs/mc1n2/mc1n2_cfg_gsm.h
+new file mode 100755
+index 0000000..7ec50a7
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mc1n2_cfg_gsm.h
+@@ -0,0 +1,1159 @@
++/*
++ * MC-1N2 ASoC codec driver
++ *
++ * Copyright (c) 2010 Yamaha Corporation
++ *
++ * This software is provided 'as-is', without any express or implied
++ * warranty.  In no event will the authors be held liable for any damages
++ * arising from the use of this software.
++ *
++ * Permission is granted to anyone to use this software for any purpose,
++ * including commercial applications, and to alter it and redistribute it
++ * freely, subject to the following restrictions:
++ *
++ * 1. The origin of this software must not be misrepresented; you must not
++ *    claim that you wrote the original software. If you use this software
++ *    in a product, an acknowledgment in the product documentation would be
++ *    appreciated but is not required.
++ * 2. Altered source versions must be plainly marked as such, and must not be
++ *    misrepresented as being the original software.
++ * 3. This notice may not be removed or altered from any source distribution.
++ */
++
++#ifndef MC1N2_CFG_H
++#define MC1N2_CFG_H
++
++#include "mcdriver.h"
++
++/*
++ * ALSA Version
++ */
++/* #define ALSA_VER_1_0_19 */
++/* #define ALSA_VER_1_0_21 */
++/* #define ALSA_VER_1_0_23 */
++#define ALSA_VER_ANDROID_3_0
++
++#define DIO0_DAI_ENABLE
++/* #define DIO1_DAI_ENABLE */
++/* #define DIO2_DAI_ENABLE */
++
++#ifdef ALSA_VER_ANDROID_3_0
++static struct mc1n2_setup mc1n2_cfg_setup = {
++      {                                                       /* MCDRV_INIT_INFO */
++       MCDRV_CKSEL_CMOS,                      /* bCkSel */
++       28,                                            /* bDivR0 20MHz *//* 28 for 24, 19 for 20 */
++       86,                                            /* bDivF0 20MHz *//* 86 for 24, 70 for 20 */
++       28,                                            /* bDivR1 */
++       86,                                            /* bDivF1 */
++       0,                                                     /* bRange0 */
++       0,                                                     /* bRange1 */
++       0,                                                     /* bBypass */
++       MCDRV_DAHIZ_LOW,                       /* bDioSdo0Hiz */
++       MCDRV_DAHIZ_LOW,                       /* bDioSdo1Hiz */
++       MCDRV_DAHIZ_LOW,                       /* bDioSdo2Hiz */
++       MCDRV_DAHIZ_HIZ,                       /* bDioClk0Hiz */
++       MCDRV_DAHIZ_HIZ,                       /* bDioClk1Hiz */
++       MCDRV_DAHIZ_HIZ,                       /* bDioClk2Hiz */
++       MCDRV_PCMHIZ_HIZ,                      /* bPcmHiz */
++       MCDRV_LINE_STEREO,                     /* bLineIn1Dif */
++       0,                                                     /* bLineIn2Dif */
++       MCDRV_LINE_STEREO,                     /* bLineOut1Dif */
++       MCDRV_LINE_STEREO,                     /* bLineOUt2Dif */
++       MCDRV_SPMN_ON,                         /* bSpmn */
++       MCDRV_MIC_DIF,                         /* bMic1Sng */
++       MCDRV_MIC_DIF,                         /* bMic2Sng */
++       MCDRV_MIC_DIF,                         /* bMic3Sng */
++       MCDRV_POWMODE_NORMAL,          /* bPowerMode */
++       MCDRV_SPHIZ_PULLDOWN,          /* bSpHiz */
++       MCDRV_LDO_ON,                          /* bLdo */
++       MCDRV_PAD_GPIO,                        /* bPad0Func */
++       MCDRV_PAD_GPIO,                        /* bPad1Func */
++       MCDRV_PAD_GPIO,                        /* bPad2Func */
++       MCDRV_OUTLEV_4,                        /* bAvddLev */
++       0,                                                     /* bVrefLev */
++       MCDRV_DCLGAIN_12,                      /* bDclGain */
++       MCDRV_DCLLIMIT_0,                      /* bDclLimit */
++       1,                                                     /* set Hi-power mode 0: HP mode 1: normal */
++       0,                                                     /* bReserved1 */
++       0,                                                     /* bReserved2 */
++       0,                                                     /* bReserved3 */
++       0,                                                     /* bReserved4 */
++       0,                                                     /* bReserved5 */
++       {                                                      /* sWaitTime */
++        130000,                                       /* dAdHpf */
++        25000,                                        /* dMic1Cin */
++        25000,                                        /* dMic2Cin */
++        25000,                                        /* dMic3Cin */
++        25000,                                        /* dLine1Cin */
++        25000,                                        /* dLine2Cin */
++        5000,                                         /* dVrefRdy1 */
++        15000,                                        /* dVrefRdy2 */
++        9000,                                         /* dHpRdy */
++        13000,                                        /* dSpRdy */
++        0,                                            /* dPdm */
++        1000,                                         /* dAnaRdyInterval */
++        1000,                                         /* dSvolInterval */
++        1000,                                         /* dAnaRdyTimeOut */
++        1000                                          /* dSvolTimeOut */
++        }
++       },                                                     /* MCDRV_INIT_INFO end */
++      {                                                       /* pcm_extend */
++       0, 0, 0},                                      /* pcm_extend end */
++      {                                                       /* pcm_hiz_redge */
++       MCDRV_PCMHIZTIM_FALLING, MCDRV_PCMHIZTIM_FALLING, MCDRV_PCMHIZTIM_FALLING},    /* pcm_hiz_redge end */
++      {                                                       /* pcm_hperiod */
++       1, 1, 1},                                      /* pcm_hperiod end */
++      {                                                       /* slot */
++       {{0, 1}, {0, 1} },
++       {{0, 1}, {0, 1} },
++       {{0, 1}, {0, 1} }
++       },
++};
++#endif
++
++static const MCDRV_DIO_INFO stDioInfo_Default = {
++      {
++       /* DIO port 0 */
++       {
++        /* sDioCommon */
++        {
++         /* bMasterSlave : Master / Slave Setting */
++         /*     MCDRV_DIO_SLAVE (0)  : Slave      */
++         /*     MCDRV_DIO_MASTER(1)  : Master     */
++         MCDRV_DIO_MASTER,
++         /* bAutoFs : Sampling frequency automatic measurement ON/OFF Setting in slave mode */
++         /*     MCDRV_AUTOFS_OFF(0)  : OFF */
++         /*     MCDRV_AUTOFS_ON (1)  : ON  */
++         MCDRV_AUTOFS_ON,
++         /* bFs : Sampling Rate Setting        */
++         /*     MCDRV_FS_48000(0)  : 48kHz     */
++         /*     MCDRV_FS_44100(1)  : 44.1kHz   */
++         /*     MCDRV_FS_32000(2)  : 32kHz     */
++         /*     MCDRV_FS_24000(4)  : 24kHz     */
++         /*     MCDRV_FS_22050(5)  : 22.05kHz  */
++         /*     MCDRV_FS_16000(6)  : 16kHz     */
++         /*     MCDRV_FS_12000(8)  : 12kHz     */
++         /*     MCDRV_FS_11025(9)  : 11.025kHz */
++         /*     MCDRV_FS_8000 (10) : 8kHz      */
++         MCDRV_FS_44100,
++         /* bBckFs : Bit Clock Frequency Setting */
++         /*     MCDRV_BCKFS_64 (0)  : LRCK x  64 */
++         /*     MCDRV_BCKFS_48 (1)  : LRCK x  48 */
++         /*     MCDRV_BCKFS_32 (2)  : LRCK x  32 */
++         /*     MCDRV_BCKFS_512(4)  : LRCK x 512 */
++         /*     MCDRV_BCKFS_256(5)  : LRCK x 256 */
++         /*     MCDRV_BCKFS_128(6)  : LRCK x 128 */
++         /*     MCDRV_BCKFS_16 (7)  : LRCK x  16 */
++         MCDRV_BCKFS_32,
++         /* bInterface : Interface Selection      */
++         /*     MCDRV_DIO_DA (0)  : Digital Audio */
++         /*     MCDRV_DIO_PCM(1)  : PCM           */
++         MCDRV_DIO_DA,
++         /* bBckInvert : Bit Clock Inversion Setting     */
++         /*     MCDRV_BCLK_NORMAL(0)  : Normal Operation */
++         /*     MCDRV_BCLK_INVERT(1)  : Clock Inverted   */
++         MCDRV_BCLK_NORMAL,
++         /* bPcmHizTim : High Impedance transition timing after transmitting the last PCM I/F data */
++         /*     MCDRV_PCMHIZTIM_FALLING(0)  : BCLK#* Falling Edge */
++         /*     MCDRV_PCMHIZTIM_RISING (1)  : BCLK#* Rising Edge  */
++         MCDRV_PCMHIZTIM_FALLING,
++         /* bPcmClkDown : Bit Clock Setting with PCM selected and Master selected                */
++         /*     MCDRV_PCM_CLKDOWN_OFF (0)  : A bit clock value specified with bBckFs             */
++         /*     MCDRV_PCM_CLKDOWN_HALF(1)  : A half of the bit clock value specified with bBckFs */
++         MCDRV_PCM_CLKDOWN_OFF,
++         /* bPcmFrame : Frame Mode Setting with PCM interface */
++         /*     MCDRV_PCM_SHORTFRAME(0)  : Short Frame        */
++         /*     MCDRV_PCM_LONGFRAME (1)  : Long Frame         */
++         MCDRV_PCM_SHORTFRAME,
++         /* bPcmHighPeriod : LR clock High time setting with PCM selected and Master selected */
++         /*     0 to 31  : High level keeps during the period of time of         */
++         /*                (setting value + 1) of the bit clock.                 */
++         0,
++         },
++        /* sDir       */
++        {
++         /* wSrcRate : Sampling Rate Converter Setting */
++         0,
++         /* sDaFormat : Digital Audio Format Information */
++         {
++              /* bBitSel : Bit Width Setting     */
++              /*     MCDRV_BITSEL_16(0)  : 16bit */
++              /*     MCDRV_BITSEL_20(1)  : 20bit */
++              /*     MCDRV_BITSEL_24(2)  : 24bit */
++              MCDRV_BITSEL_16,
++              /* bMode : Data Format Setting                             */
++              /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++              /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++              /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++              MCDRV_DAMODE_I2S},
++         /* sPcmFormat : PCM Format Information */
++         {
++              /* bMono : Mono / Stereo Setting  */
++              /*     MCDRV_PCM_STEREO(0) Stereo */
++              /*     MCDRV_PCM_MONO  (1) Mono   */
++              MCDRV_PCM_MONO,
++              /* bOrder : Bit Order Setting                                     */
++              /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++              /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++              /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++              /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++              /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++              /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++              MCDRV_PCM_MSB_FIRST,
++              /* bLaw : Data Format Setting        */
++              /*     MCDRV_PCM_LINEAR(0)  : Linear */
++              /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++              /*     MCDRV_PCM_MULAW (2)  : u-Law */
++              MCDRV_PCM_LINEAR,
++              /* bBitSel : Bit Width Setting        */
++              /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++              /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++              /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++              /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++              MCDRV_PCM_BITSEL_8},
++         /* asSlot : Setting of a slot number of data to be fed to each channel */
++         {0, 1}
++         },
++        /* sDit       */
++        {
++         /* wSrcRate : Sampling Rate Converter Setting */
++         0,
++         /* sDaFormat : Digital Audio Format Information */
++         {
++              /* bBitSel : Bit Width Setting     */
++              /*     MCDRV_BITSEL_16(0)  : 16bit */
++              /*     MCDRV_BITSEL_20(1)  : 20bit */
++              /*     MCDRV_BITSEL_24(2)  : 24bit */
++              MCDRV_BITSEL_16,
++              /* bMode : Data Format Setting                             */
++              /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++              /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++              /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++              MCDRV_DAMODE_I2S},
++         /* sPcmFormat : PCM Format Information */
++         {
++              /* bMono : Mono / Stereo Setting  */
++              /*     MCDRV_PCM_STEREO(0) Stereo */
++              /*     MCDRV_PCM_MONO  (1) Mono   */
++              MCDRV_PCM_MONO,
++              /* bOrder : Bit Order Setting                                     */
++              /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++              /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++              /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++              /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++              /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++              /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++              MCDRV_PCM_MSB_FIRST,
++              /* bLaw : Data Format Setting        */
++              /*     MCDRV_PCM_LINEAR(0)  : Linear */
++              /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++              /*     MCDRV_PCM_MULAW (2)  : u-Law */
++              MCDRV_PCM_LINEAR,
++              /* bBitSel : Bit Width Setting        */
++              /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++              /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++              /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++              /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++              MCDRV_PCM_BITSEL_8},
++         /* asSlot Setting of a slot number of data to be transmitted from each channel */
++         {0, 1}
++         }
++        },
++       /* DIO port 1 */
++       {
++        /* sDioCommon */
++        {
++         /* bMasterSlave : Master / Slave Setting */
++         /*     MCDRV_DIO_SLAVE (0)  : Slave      */
++         /*     MCDRV_DIO_MASTER(1)  : Master     */
++         MCDRV_DIO_MASTER,
++         /* bAutoFs : Sampling frequency automatic measurement ON/OFF Setting in slave mode */
++         /*     MCDRV_AUTOFS_OFF(0)  : OFF */
++         /*     MCDRV_AUTOFS_ON (1)  : ON  */
++         MCDRV_AUTOFS_ON,
++         /* bFs : Sampling Rate Setting        */
++         /*     MCDRV_FS_48000(0)  : 48kHz     */
++         /*     MCDRV_FS_44100(1)  : 44.1kHz   */
++         /*     MCDRV_FS_32000(2)  : 32kHz     */
++         /*     MCDRV_FS_24000(4)  : 24kHz     */
++         /*     MCDRV_FS_22050(5)  : 22.05kHz  */
++         /*     MCDRV_FS_16000(6)  : 16kHz     */
++         /*     MCDRV_FS_12000(8)  : 12kHz     */
++         /*     MCDRV_FS_11025(9)  : 11.025kHz */
++         /*     MCDRV_FS_8000 (10) : 8kHz      */
++         MCDRV_FS_16000,
++         /* bBckFs : Bit Clock Frequency Setting */
++         /*     MCDRV_BCKFS_64 (0)  : LRCK x  64 */
++         /*     MCDRV_BCKFS_48 (1)  : LRCK x  48 */
++         /*     MCDRV_BCKFS_32 (2)  : LRCK x  32 */
++         /*     MCDRV_BCKFS_512(4)  : LRCK x 512 */
++         /*     MCDRV_BCKFS_256(5)  : LRCK x 256 */
++         /*     MCDRV_BCKFS_128(6)  : LRCK x 128 */
++         /*     MCDRV_BCKFS_16 (7)  : LRCK x  16 */
++         MCDRV_BCKFS_32,
++         /* bInterface : Interface Selection      */
++         /*     MCDRV_DIO_DA (0)  : Digital Audio */
++         /*     MCDRV_DIO_PCM(1)  : PCM           */
++         MCDRV_DIO_DA,
++         /* bBckInvert : Bit Clock Inversion Setting     */
++         /*     MCDRV_BCLK_NORMAL(0)  : Normal Operation */
++         /*     MCDRV_BCLK_INVERT(1)  : Clock Inverted   */
++         MCDRV_BCLK_NORMAL,
++         /* bPcmHizTim : High Impedance transition timing after transmitting the last PCM I/F data */
++         /*     MCDRV_PCMHIZTIM_FALLING(0)  : BCLK#* Falling Edge */
++         /*     MCDRV_PCMHIZTIM_RISING (1)  : BCLK#* Rising Edge  */
++         MCDRV_PCMHIZTIM_FALLING,
++         /* bPcmClkDown : Bit Clock Setting with PCM selected and Master selected                */
++         /*     MCDRV_PCM_CLKDOWN_OFF (0)  : A bit clock value specified with bBckFs             */
++         /*     MCDRV_PCM_CLKDOWN_HALF(1)  : A half of the bit clock value specified with bBckFs */
++         MCDRV_PCM_CLKDOWN_OFF,
++         /* bPcmFrame : Frame Mode Setting with PCM interface */
++         /*     MCDRV_PCM_SHORTFRAME(0)  : Short Frame        */
++         /*     MCDRV_PCM_LONGFRAME (1)  : Long Frame         */
++         MCDRV_PCM_SHORTFRAME,
++         /* bPcmHighPeriod : LR clock High time setting with PCM selected and Master selected */
++         /*     0 to 31  : High level keeps during the period of time of         */
++         /*                (setting value + 1) of the bit clock.                 */
++         0,
++         },
++        /* sDir       */
++        {
++         /* wSrcRate : Sampling Rate Converter Setting */
++         0,
++         /* sDaFormat : Digital Audio Format Information */
++         {
++              /* bBitSel : Bit Width Setting     */
++              /*     MCDRV_BITSEL_16(0)  : 16bit */
++              /*     MCDRV_BITSEL_20(1)  : 20bit */
++              /*     MCDRV_BITSEL_24(2)  : 24bit */
++              MCDRV_BITSEL_16,
++              /* bMode : Data Format Setting                             */
++              /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++              /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++              /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++              MCDRV_DAMODE_I2S},
++         /* sPcmFormat : PCM Format Information */
++         {
++              /* bMono : Mono / Stereo Setting  */
++              /*     MCDRV_PCM_STEREO(0) Stereo */
++              /*     MCDRV_PCM_MONO  (1) Mono   */
++              MCDRV_PCM_STEREO,
++              /* bOrder : Bit Order Setting                                     */
++              /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++              /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++              /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++              /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++              /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++              /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++              MCDRV_PCM_MSB_FIRST,
++              /* bLaw : Data Format Setting        */
++              /*     MCDRV_PCM_LINEAR(0)  : Linear */
++              /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++              /*     MCDRV_PCM_MULAW (2)  : u-Law */
++              MCDRV_PCM_LINEAR,
++              /* bBitSel : Bit Width Setting        */
++              /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++              /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++              /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++              /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++              MCDRV_PCM_BITSEL_16},
++         /* asSlot : Setting of a slot number of data to be fed to each channel */
++         {0, 0}
++         },
++        /* sDit       */
++        {
++         /* wSrcRate : Sampling Rate Converter Setting */
++         0,
++         /* sDaFormat : Digital Audio Format Information */
++         {
++              /* bBitSel : Bit Width Setting     */
++              /*     MCDRV_BITSEL_16(0)  : 16bit */
++              /*     MCDRV_BITSEL_20(1)  : 20bit */
++              /*     MCDRV_BITSEL_24(2)  : 24bit */
++              MCDRV_BITSEL_16,
++              /* bMode : Data Format Setting                             */
++              /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++              /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++              /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++              MCDRV_DAMODE_I2S},
++         /* sPcmFormat : PCM Format Information */
++         {
++              /* bMono : Mono / Stereo Setting  */
++              /*     MCDRV_PCM_STEREO(0) Stereo */
++              /*     MCDRV_PCM_MONO  (1) Mono   */
++              MCDRV_PCM_STEREO,
++              /* bOrder : Bit Order Setting                                     */
++              /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++              /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++              /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++              /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++              /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++              /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++              MCDRV_PCM_MSB_FIRST,
++              /* bLaw : Data Format Setting        */
++              /*     MCDRV_PCM_LINEAR(0)  : Linear */
++              /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++              /*     MCDRV_PCM_MULAW (2)  : u-Law */
++              MCDRV_PCM_LINEAR,
++              /* bBitSel : Bit Width Setting        */
++              /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++              /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++              /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++              /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++              MCDRV_PCM_BITSEL_16},
++         /* asSlot Setting of a slot number of data to be transmitted from each channel */
++         {1, 0}
++         }
++        },
++       /* DIO port 2 */
++       {
++        /* sDioCommon */
++        {
++         /* bMasterSlave : Master / Slave Setting */
++         /*     MCDRV_DIO_SLAVE (0)  : Slave      */
++         /*     MCDRV_DIO_MASTER(1)  : Master     */
++         MCDRV_DIO_MASTER,
++         /* bAutoFs : Sampling frequency automatic measurement ON/OFF Setting in slave mode */
++         /*     MCDRV_AUTOFS_OFF(0)  : OFF */
++         /*     MCDRV_AUTOFS_ON (1)  : ON  */
++         MCDRV_AUTOFS_ON,
++         /* bFs : Sampling Rate Setting        */
++         /*     MCDRV_FS_48000(0)  : 48kHz     */
++         /*     MCDRV_FS_44100(1)  : 44.1kHz   */
++         /*     MCDRV_FS_32000(2)  : 32kHz     */
++         /*     MCDRV_FS_24000(4)  : 24kHz     */
++         /*     MCDRV_FS_22050(5)  : 22.05kHz  */
++         /*     MCDRV_FS_16000(6)  : 16kHz     */
++         /*     MCDRV_FS_12000(8)  : 12kHz     */
++         /*     MCDRV_FS_11025(9)  : 11.025kHz */
++         /*     MCDRV_FS_8000 (10) : 8kHz      */
++         MCDRV_FS_8000,
++         /* bBckFs : Bit Clock Frequency Setting */
++         /*     MCDRV_BCKFS_64 (0)  : LRCK x  64 */
++         /*     MCDRV_BCKFS_48 (1)  : LRCK x  48 */
++         /*     MCDRV_BCKFS_32 (2)  : LRCK x  32 */
++         /*     MCDRV_BCKFS_512(4)  : LRCK x 512 */
++         /*     MCDRV_BCKFS_256(5)  : LRCK x 256 */
++         /*     MCDRV_BCKFS_128(6)  : LRCK x 128 */
++         /*     MCDRV_BCKFS_16 (7)  : LRCK x  16 */
++         MCDRV_BCKFS_32,
++         /* bInterface : Interface Selection      */
++         /*     MCDRV_DIO_DA (0)  : Digital Audio */
++         /*     MCDRV_DIO_PCM(1)  : PCM           */
++         MCDRV_DIO_PCM,
++         /* bBckInvert : Bit Clock Inversion Setting     */
++         /*     MCDRV_BCLK_NORMAL(0)  : Normal Operation */
++         /*     MCDRV_BCLK_INVERT(1)  : Clock Inverted   */
++         MCDRV_BCLK_NORMAL,
++         /* bPcmHizTim : High Impedance transition timing after transmitting the last PCM I/F data */
++         /*     MCDRV_PCMHIZTIM_FALLING(0)  : BCLK#* Falling Edge */
++         /*     MCDRV_PCMHIZTIM_RISING (1)  : BCLK#* Rising Edge  */
++         MCDRV_PCMHIZTIM_FALLING,
++         /* bPcmClkDown : Bit Clock Setting with PCM selected and Master selected                */
++         /*     MCDRV_PCM_CLKDOWN_OFF (0)  : A bit clock value specified with bBckFs             */
++         /*     MCDRV_PCM_CLKDOWN_HALF(1)  : A half of the bit clock value specified with bBckFs */
++         MCDRV_PCM_CLKDOWN_OFF,
++         /* bPcmFrame : Frame Mode Setting with PCM interface */
++         /*     MCDRV_PCM_SHORTFRAME(0)  : Short Frame        */
++         /*     MCDRV_PCM_LONGFRAME (1)  : Long Frame         */
++         MCDRV_PCM_SHORTFRAME,
++         /* bPcmHighPeriod : LR clock High time setting with PCM selected and Master selected */
++         /*     0 to 31  : High level keeps during the period of time of         */
++         /*                (setting value + 1) of the bit clock.                 */
++         0,
++         },
++        /* sDir       */
++        {
++         /* wSrcRate : Sampling Rate Converter Setting */
++         0,
++         /* sDaFormat : Digital Audio Format Information */
++         {
++              /* bBitSel : Bit Width Setting     */
++              /*     MCDRV_BITSEL_16(0)  : 16bit */
++              /*     MCDRV_BITSEL_20(1)  : 20bit */
++              /*     MCDRV_BITSEL_24(2)  : 24bit */
++              MCDRV_BITSEL_16,
++              /* bMode : Data Format Setting                             */
++              /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++              /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++              /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++              MCDRV_DAMODE_HEADALIGN},
++         /* sPcmFormat : PCM Format Information */
++         {
++              /* bMono : Mono / Stereo Setting  */
++              /*     MCDRV_PCM_STEREO(0) Stereo */
++              /*     MCDRV_PCM_MONO  (1) Mono   */
++              MCDRV_PCM_STEREO,
++              /* bOrder : Bit Order Setting                                     */
++              /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++              /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++              /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++              /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++              /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++              /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++              MCDRV_PCM_MSB_FIRST,
++              /* bLaw : Data Format Setting        */
++              /*     MCDRV_PCM_LINEAR(0)  : Linear */
++              /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++              /*     MCDRV_PCM_MULAW (2)  : u-Law */
++              MCDRV_PCM_LINEAR,
++              /* bBitSel : Bit Width Setting        */
++              /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++              /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++              /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++              /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++              MCDRV_PCM_BITSEL_16},
++         /* asSlot : Setting of a slot number of data to be fed to each channel */
++         {0, 0}
++         },
++        /* sDit       */
++        {
++         /* wSrcRate : Sampling Rate Converter Setting */
++         0,
++         /* sDaFormat : Digital Audio Format Information */
++         {
++              /* bBitSel : Bit Width Setting     */
++              /*     MCDRV_BITSEL_16(0)  : 16bit */
++              /*     MCDRV_BITSEL_20(1)  : 20bit */
++              /*     MCDRV_BITSEL_24(2)  : 24bit */
++              MCDRV_BITSEL_16,
++              /* bMode : Data Format Setting                             */
++              /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++              /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++              /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++              MCDRV_DAMODE_HEADALIGN},
++         /* sPcmFormat : PCM Format Information */
++         {
++              /* bMono : Mono / Stereo Setting  */
++              /*     MCDRV_PCM_STEREO(0) Stereo */
++              /*     MCDRV_PCM_MONO  (1) Mono   */
++              MCDRV_PCM_MONO,
++              /* bOrder : Bit Order Setting                                     */
++              /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++              /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++              /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++              /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++              /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++              /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++              MCDRV_PCM_MSB_FIRST,
++              /* bLaw : Data Format Setting        */
++              /*     MCDRV_PCM_LINEAR(0)  : Linear */
++              /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++              /*     MCDRV_PCM_MULAW (2)  : u-Law */
++              MCDRV_PCM_LINEAR,
++              /* bBitSel : Bit Width Setting        */
++              /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++              /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++              /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++              /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++              MCDRV_PCM_BITSEL_16},
++         /* asSlot Setting of a slot number of data to be transmitted from each channel */
++         {0, 1}
++         }
++        }
++       }
++};
++
++/* ========================================
++   DAC settings
++   ========================================*/
++static const MCDRV_DAC_INFO stDacInfo_Default = {
++      /* bMasterSwap : DAC Master Path SWAP Setting                          */
++      /*     MCDRV_DSWAP_OFF      (0)  : No SWAP                             */
++      /*     MCDRV_DSWAP_SWAP     (1)  : SWAP                                */
++      /*     MCDRV_DSWAP_MUTE     (2)  : MUTE                                */
++      /*     MCDRV_DSWAP_RMVCENTER(3)  : Center Removed                      */
++      /*     MCDRV_DSWAP_MONO     (4)  : Mono                                */
++      /*     MCDRV_DSWAP_MONOHALF (5)  : Reserved (do not use this setting)  */
++      /*     MCDRV_DSWAP_BOTHL    (6)  : Lch data output in both Lch and Rch */
++      /*     MCDRV_DSWAP_BOTHR    (7)  : Rch data output in both Lch and Rch */
++      MCDRV_DSWAP_OFF,
++      /* bVoiceSwap : DAC Voice Path SWAP Setting                            */
++      /*     MCDRV_DSWAP_OFF      (0)  : No SWAP                             */
++      /*     MCDRV_DSWAP_SWAP     (1)  : SWAP                                */
++      /*     MCDRV_DSWAP_MUTE     (2)  : MUTE                                */
++      /*     MCDRV_DSWAP_RMVCENTER(3)  : Center Removed                      */
++      /*     MCDRV_DSWAP_MONO     (4)  : Mono (-6dB)                         */
++      /*     MCDRV_DSWAP_MONOHALF (5)  : Reserved (do not use this setting)  */
++      /*     MCDRV_DSWAP_BOTHL    (6)  : Lch data output in both Lch and Rch */
++      /*     MCDRV_DSWAP_BOTHR    (7)  : Rch data output in both Lch and Rch */
++      MCDRV_DSWAP_OFF,
++      /* bDcCut : HP, SP Protection DC-ct Filter Setting  */
++      /*     MCDRV_DCCUT_ON (0)  : DC-cut Filter ON       */
++      /*     MCDRV_DCCUT_OFF(1)  : DC-cut Filter OFF      */
++      MCDRV_DCCUT_ON
++};
++
++/* ========================================
++   ADC settings
++   ========================================*/
++
++static const MCDRV_ADC_INFO stAdcInfo_Default = {
++      /* bAgcAdjust : AGC Gain Control Range     */
++      /*     MCDRV_AGCADJ_24(0)  : -3dB to +24dB */
++      /*     MCDRV_AGCADJ_18(1)  : -3dB to +18dB */
++      /*     MCDRV_AGCADJ_12(2)  : -3dB to +12dB */
++      /*     MCDRV_AGCADJ_0 (3)  : -3dB to  +0dB */
++      MCDRV_AGCADJ_0,
++      /* bAgcOn : AGC ON/OFF Setting */
++      /*     MCDRV_AGC_OFF(0)  : OFF */
++      /*     MCDRV_AGC_ON (1)  : ON  */
++      MCDRV_AGC_OFF,
++      /* bMonot : Mono / Stereo Setting    */
++      /*     MCDRV_ADC_STEREO(0)  : Stereo */
++      /*     MCDRV_ADC_MONO  (1)  : Mono   */
++      MCDRV_ADC_STEREO
++};
++
++/* ========================================
++   SP settings
++   ========================================*/
++static const MCDRV_SP_INFO stSpInfo_Default = {
++      /* bSwap : Swap setting                */
++      /*     MCDRV_SPSWAP_OFF (0)  : No SWAP */
++      /*     MCDRV_SPSWAP_SWAP(1)  : SWAP    */
++      MCDRV_SPSWAP_OFF
++};
++
++/* ========================================
++   DNG settings
++   ========================================*/
++static const MCDRV_DNG_INFO stDngInfo_Default = {
++      /* bOnOff[] : Digital Noise Gate On/Off Setting */
++      /*     MCDRV_DNG_OFF(0)  : OFF                */
++      /*     MCDRV_DNG_ON (1)  : ON                 */
++      {MCDRV_DNG_OFF, MCDRV_DNG_OFF, MCDRV_DNG_OFF},
++
++      /* bThreshold[] : Threshold Setting    */
++      /*     MCDRV_DNG_THRES_30    (0) */
++      /*     MCDRV_DNG_THRES_36    (1) */
++      /*     MCDRV_DNG_THRES_42    (2) */
++      /*     MCDRV_DNG_THRES_48    (3) */
++      /*     MCDRV_DNG_THRES_54    (4) */
++      /*     MCDRV_DNG_THRES_60    (5) */
++      /*     MCDRV_DNG_THRES_66    (6) */
++      /*     MCDRV_DNG_THRES_72    (7) */
++      /*     MCDRV_DNG_THRES_78    (8) */
++      /*     MCDRV_DNG_THRES_84    (9) */
++      {MCDRV_DNG_THRES_60, MCDRV_DNG_THRES_60, MCDRV_DNG_THRES_60},
++
++      /* bHold[] : Hold Time Setting         */
++      /*     MCDRV_DNG_HOLD_30 (0)  :  30ms */
++      /*     MCDRV_DNG_HOLD_120(1)  : 120ms */
++      /*     MCDRV_DNG_HOLD_500(2)  : 500ms */
++      {MCDRV_DNG_HOLD_500, MCDRV_DNG_HOLD_500, MCDRV_DNG_HOLD_500},
++
++      /* bAttack[] : Attack Time Setting        */
++      /*     MCDRV_DNG_ATTACK_25   (0)  :   25ms */
++      /*     MCDRV_DNG_ATTACK_100  (1)  :  100ms */
++      /*     MCDRV_DNG_ATTACK_400  (2)  :  400ms */
++      /*     MCDRV_DNG_ATTACK_800  (3)  :  800ms */
++      {MCDRV_DNG_ATTACK_100, MCDRV_DNG_ATTACK_100, MCDRV_DNG_ATTACK_100},
++
++      /* bRelease[] : Release Time Setting        */
++      /*     MCDRV_DNG_RELEASE_7950(0)  : 7.95ms */
++      /*     MCDRV_DNG_RELEASE_470 (1)  : 0.47ms */
++      /*     MCDRV_DNG_RELEASE_940 (2)  : 0.94ms */
++      {MCDRV_DNG_RELEASE_940, MCDRV_DNG_RELEASE_940, MCDRV_DNG_RELEASE_940},
++
++      /* bTarget[] : Target Volume Setting        */
++      /*     MCDRV_DNG_TARGET_6    (0)  : -6dB  */
++      /*     MCDRV_DNG_TARGET_9    (1)  : -9dB  */
++      /*     MCDRV_DNG_TARGET_12   (2)  : -12dB */
++      /*     MCDRV_DNG_TARGET_15   (3)  : -15dB */
++      /*     MCDRV_DNG_TARGET_18   (4)  : -18dB */
++      /*     MCDRV_DNG_TARGET_MUTE (5)  : Mute  */
++      {MCDRV_DNG_TARGET_MUTE, MCDRV_DNG_TARGET_MUTE, MCDRV_DNG_TARGET_MUTE},
++};
++
++#if 0
++static const MCDRV_DNG_INFO stDngInfo_Default = {
++      /* bOnOff : Digital Noise Gate On/Off Setting */
++      /*     MCDRV_DNG_OFF(0)  : OFF                */
++      /*     MCDRV_DNG_ON (1)  : ON                 */
++      MCDRV_DNG_OFF,
++
++      /* bThreshold : Threshold Setting    */
++      /*     MCDRV_DNG_THRES_5BIT  (0) */
++      /*     MCDRV_DNG_THRES_7BIT  (1) */
++      /*     MCDRV_DNG_THRES_9BIT  (2) */
++      /*     MCDRV_DNG_THRES_11BIT (3) */
++      /*     MCDRV_DNG_THRES_13BIT (4) */
++      /*     MCDRV_DNG_THRES_15BIT (5) */
++      /*     MCDRV_DNG_THRES_17BIT (6) */
++      /*     MCDRV_DNG_THRES_21BIT (7) */
++      MCDRV_DNG_THRES_11BIT,
++
++      /* bHold : Hold Time Setting         */
++      /*     MCDRV_DNG_HOLD_30 (0)  :  30ms */
++      /*     MCDRV_DNG_HOLD_120(1)  : 120ms */
++      /*     MCDRV_DNG_HOLD_500(2)  : 500ms */
++      MCDRV_DNG_HOLD_500,
++
++      /* bAttack : Attack Time Setting        */
++      /*     MCDRV_DNG_ATTACK_25   (0)  :   25ms */
++      /*     MCDRV_DNG_ATTACK_800  (1)  :  800ms */
++      /*     MCDRV_DNG_ATTACK_1100 (2)  : 1100ms */
++      MCDRV_DNG_ATTACK_1100,
++
++      /* bRelease : Release Time Setting        */
++      /*     MCDRV_DNG_RELEASE_7950(0)  : 7.95ms */
++      /*     MCDRV_DNG_RELEASE_470 (1)  : 0.47ms */
++      /*     MCDRV_DNG_RELEASE_940 (2)  : 0.94ms */
++      MCDRV_DNG_RELEASE_940,
++
++};
++#endif
++
++/* ========================================
++   AudioEngine settings
++   ========================================*/
++static MCDRV_AE_INFO sAeInfo_1 = {
++      /* On/Off */
++      0x00,
++      /* BEX */
++      {
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
++      /* WIDE */
++      {
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00},
++      /* DRC */
++      {
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
++      /* EQ5 */
++      {
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00},
++      /* EQ3 */
++      {
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00}
++};
++
++static MCDRV_AE_INFO sAeInfo_2 = {
++      /* On/Off */
++      0x00,
++      /* BEX */
++      {
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
++      /* WIDE */
++      {
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00},
++      /* DRC */
++      {
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
++      /* EQ5 */
++      {
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00},
++      /* EQ3 */
++      {
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00}
++};
++
++static MCDRV_AE_INFO sAeInfo_3 = {
++      /* On/Off */
++      0x00,
++      /* BEX */
++      {
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
++      /* WIDE */
++      {
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00},
++      /* DRC */
++      {
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
++      /* EQ5 */
++      {
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00},
++      /* EQ3 */
++      {
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00}
++};
++
++static MCDRV_AE_INFO sAeInfo_4 = {
++      /* On/Off */
++      0x00,
++      /* BEX */
++      {
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
++      /* WIDE */
++      {
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00},
++      /* DRC */
++      {
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
++      /* EQ5 */
++      {
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00},
++      /* EQ3 */
++      {
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00}
++};
++
++static MCDRV_AE_INFO sAeInfo_5 = {
++      /* On/Off */
++      0x00,
++      /* BEX */
++      {
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
++      /* WIDE */
++      {
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00},
++      /* DRC */
++      {
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
++      /* EQ5 */
++      {
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00},
++      /* EQ3 */
++      {
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++       0x00, 0x00, 0x00}
++};
++
++/* ========================================
++   System EQ settings
++   ========================================*/
++static MCDRV_SYSEQ_INFO stSyseqInfo_Default = {
++      /* On/Off */
++      0x00,
++      /* EQ */
++      {
++       0x10, 0xc4, 0x50, 0x12, 0xc4, 0x40, 0x02, 0xa9,
++       0x60, 0xed, 0x3b, 0xc0, 0xfc, 0x92, 0x40,
++       },
++};
++
++#endif
+diff --git a/sound/soc/codecs/mc1n2/mc1n2_cfg_lgt.h b/sound/soc/codecs/mc1n2/mc1n2_cfg_lgt.h
+new file mode 100644
+index 0000000..b806d94
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mc1n2_cfg_lgt.h
+@@ -0,0 +1,1199 @@
++/*
++ * MC-1N2 ASoC codec driver
++ *
++ * Copyright (c) 2010-2011 Yamaha Corporation
++ *
++ * This software is provided 'as-is', without any express or implied
++ * warranty.  In no event will the authors be held liable for any damages
++ * arising from the use of this software.
++ *
++ * Permission is granted to anyone to use this software for any purpose,
++ * including commercial applications, and to alter it and redistribute it
++ * freely, subject to the following restrictions:
++ *
++ * 1. The origin of this software must not be misrepresented; you must not
++ *    claim that you wrote the original software. If you use this software
++ *    in a product, an acknowledgment in the product documentation would be
++ *    appreciated but is not required.
++ * 2. Altered source versions must be plainly marked as such, and must not be
++ *    misrepresented as being the original software.
++ * 3. This notice may not be removed or altered from any source distribution.
++ */
++
++#ifndef MC1N2_CFG_H
++#define MC1N2_CFG_H
++
++#include "mcdriver.h"
++
++/*
++ * ALSA Version
++ */
++/* #define ALSA_VER_1_0_19 */
++/* #define ALSA_VER_1_0_21 */
++/* #define ALSA_VER_1_0_23 */
++/* #define ALSA_VER_ANDROID_2_6_35 */
++#define ALSA_VER_ANDROID_3_0
++
++#define DIO0_DAI_ENABLE
++/* #define DIO1_DAI_ENABLE */
++/* #define DIO2_DAI_ENABLE */
++
++#ifdef ALSA_VER_ANDROID_3_0
++static struct mc1n2_setup mc1n2_cfg_setup = {
++      {  /* MCDRV_INIT_INFO */
++              MCDRV_CKSEL_CMOS, /* bCkSel */
++              28,               /* bDivR0 20MHz*/ /* 28 for 24, 19 for 20 */
++              86,               /* bDivF0 20MHz*/ /* 86 for 24, 70 for 20 */
++              28,               /* bDivR1*/
++              86,               /* bDivF1*/
++              0,                /* bRange0*/
++              0,                /* bRange1*/
++              0,                /* bBypass*/
++              MCDRV_DAHIZ_LOW,  /* bDioSdo0Hiz */
++              MCDRV_DAHIZ_LOW,  /* bDioSdo1Hiz */
++              MCDRV_DAHIZ_LOW,  /* bDioSdo2Hiz */
++              MCDRV_DAHIZ_HIZ,  /* bDioClk0Hiz */
++              MCDRV_DAHIZ_HIZ,  /* bDioClk1Hiz */
++              MCDRV_DAHIZ_HIZ,  /* bDioClk2Hiz */
++              MCDRV_PCMHIZ_HIZ, /* bPcmHiz */
++              MCDRV_LINE_STEREO,/* bLineIn1Dif */
++              0,                /* bLineIn2Dif */
++              MCDRV_LINE_STEREO,/* bLineOut1Dif */
++              MCDRV_LINE_STEREO,/* bLineOUt2Dif */
++              MCDRV_SPMN_ON,    /* bSpmn */
++              MCDRV_MIC_DIF,    /* bMic1Sng */
++              MCDRV_MIC_DIF,    /* bMic2Sng */
++              MCDRV_MIC_DIF,    /* bMic3Sng */
++              MCDRV_POWMODE_NORMAL, /* bPowerMode */
++              MCDRV_SPHIZ_PULLDOWN, /* bSpHiz */
++              MCDRV_LDO_ON,     /* bLdo */
++              MCDRV_PAD_GPIO,   /* bPad0Func */
++              MCDRV_PAD_GPIO,   /* bPad1Func */
++              MCDRV_PAD_GPIO,   /* bPad2Func */
++              MCDRV_OUTLEV_4,   /* bAvddLev */
++              0,                /* bVrefLev */
++              MCDRV_DCLGAIN_12, /* bDclGain */
++              MCDRV_DCLLIMIT_0, /* bDclLimit */
++              1,                   /* set Hi-power mode 0: HP mode 1: normal */
++              0,                /* bReserved1 */
++              0,                /* bReserved2 */
++              0,                /* bReserved3 */
++              0,                /* bReserved4 */
++              0,                /* bReserved5 */
++              {                 /* sWaitTime */
++                      130000,         /* dAdHpf */
++                      25000,          /* dMic1Cin */
++                      25000,          /* dMic2Cin */
++                      25000,          /* dMic3Cin */
++                      25000,          /* dLine1Cin */
++                      25000,          /* dLine2Cin */
++                      5000,           /* dVrefRdy1 */
++                      15000,          /* dVrefRdy2 */
++                      9000,           /* dHpRdy */
++                      13000,          /* dSpRdy */
++                      0,              /* dPdm */
++                      1000,           /* dAnaRdyInterval */
++                      1000,           /* dSvolInterval */
++                      1000,           /* dAnaRdyTimeOut */
++                      1000            /* dSvolTimeOut */
++              }
++      }, /* MCDRV_INIT_INFO end */
++      {  /* pcm_extend */
++              0, 0, 0
++      }, /* pcm_extend end */
++      {  /* pcm_hiz_redge */
++              MCDRV_PCMHIZTIM_FALLING, MCDRV_PCMHIZTIM_FALLING, MCDRV_PCMHIZTIM_FALLING
++      }, /* pcm_hiz_redge end */
++      {  /* pcm_hperiod */
++              1, 1, 1
++      }, /* pcm_hperiod end */
++      {  /* slot */
++              { {0, 1}, {0, 1} },
++              { {0, 1}, {0, 1} },
++              { {0, 1}, {0, 1} }
++      },
++};
++#endif
++
++static const MCDRV_DIO_INFO stDioInfo_Default = {
++      {
++              /* DIO port 0 */
++              {
++                      /* sDioCommon */
++                      {
++                              /* bMasterSlave : Master / Slave Setting */
++                              /*     MCDRV_DIO_SLAVE (0)  : Slave      */
++                              /*     MCDRV_DIO_MASTER(1)  : Master     */
++                              MCDRV_DIO_MASTER,
++                              /* bAutoFs : Sampling frequency automatic measurement ON/OFF Setting in slave mode */
++                              /*     MCDRV_AUTOFS_OFF(0)  : OFF */
++                              /*     MCDRV_AUTOFS_ON (1)  : ON  */
++                              MCDRV_AUTOFS_ON ,
++                              /* bFs : Sampling Rate Setting        */
++                              /*     MCDRV_FS_48000(0)  : 48kHz     */
++                              /*     MCDRV_FS_44100(1)  : 44.1kHz   */
++                              /*     MCDRV_FS_32000(2)  : 32kHz     */
++                              /*     MCDRV_FS_24000(4)  : 24kHz     */
++                              /*     MCDRV_FS_22050(5)  : 22.05kHz  */
++                              /*     MCDRV_FS_16000(6)  : 16kHz     */
++                              /*     MCDRV_FS_12000(8)  : 12kHz     */
++                              /*     MCDRV_FS_11025(9)  : 11.025kHz */
++                              /*     MCDRV_FS_8000 (10) : 8kHz      */
++                              MCDRV_FS_44100,
++                              /* bBckFs : Bit Clock Frequency Setting */
++                              /*     MCDRV_BCKFS_64 (0)  : LRCK x  64 */
++                              /*     MCDRV_BCKFS_48 (1)  : LRCK x  48 */
++                              /*     MCDRV_BCKFS_32 (2)  : LRCK x  32 */
++                              /*     MCDRV_BCKFS_512(4)  : LRCK x 512 */
++                              /*     MCDRV_BCKFS_256(5)  : LRCK x 256 */
++                              /*     MCDRV_BCKFS_128(6)  : LRCK x 128 */
++                              /*     MCDRV_BCKFS_16 (7)  : LRCK x  16 */
++                              MCDRV_BCKFS_32,
++                              /* bInterface : Interface Selection      */
++                              /*     MCDRV_DIO_DA (0)  : Digital Audio */
++                              /*     MCDRV_DIO_PCM(1)  : PCM           */
++                              MCDRV_DIO_DA,
++                              /* bBckInvert : Bit Clock Inversion Setting     */
++                              /*     MCDRV_BCLK_NORMAL(0)  : Normal Operation */
++                              /*     MCDRV_BCLK_INVERT(1)  : Clock Inverted   */
++                              MCDRV_BCLK_NORMAL,
++                              /* bPcmHizTim : High Impedance transition timing after transmitting the last PCM I/F data */
++                              /*     MCDRV_PCMHIZTIM_FALLING(0)  : BCLK#* Falling Edge */
++                              /*     MCDRV_PCMHIZTIM_RISING (1)  : BCLK#* Rising Edge  */
++                              MCDRV_PCMHIZTIM_FALLING,
++                              /* bPcmClkDown : Bit Clock Setting with PCM selected and Master selected                */
++                              /*     MCDRV_PCM_CLKDOWN_OFF (0)  : A bit clock value specified with bBckFs             */
++                              /*     MCDRV_PCM_CLKDOWN_HALF(1)  : A half of the bit clock value specified with bBckFs */
++                              MCDRV_PCM_CLKDOWN_OFF,
++                              /* bPcmFrame : Frame Mode Setting with PCM interface */
++                              /*     MCDRV_PCM_SHORTFRAME(0)  : Short Frame        */
++                              /*     MCDRV_PCM_LONGFRAME (1)  : Long Frame         */
++                              MCDRV_PCM_SHORTFRAME,
++                              /* bPcmHighPeriod : LR clock High time setting with PCM selected and Master selected */
++                              /*     0 to 31  : High level keeps during the period of time of         */
++                              /*                (setting value + 1) of the bit clock.                 */
++                              0,
++                      },
++                      /* sDir       */
++                      {
++                              /* wSrcRate : Sampling Rate Converter Setting */
++                              0,
++                              /* sDaFormat : Digital Audio Format Information */
++                              {
++                                      /* bBitSel : Bit Width Setting     */
++                                      /*     MCDRV_BITSEL_16(0)  : 16bit */
++                                      /*     MCDRV_BITSEL_20(1)  : 20bit */
++                                      /*     MCDRV_BITSEL_24(2)  : 24bit */
++                                      MCDRV_BITSEL_16,
++                                      /* bMode : Data Format Setting                             */
++                                      /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++                                      /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++                                      /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++                                      MCDRV_DAMODE_I2S
++                              },
++                              /* sPcmFormat : PCM Format Information */
++                              {
++                                      /* bMono : Mono / Stereo Setting  */
++                                      /*     MCDRV_PCM_STEREO(0) Stereo */
++                                      /*     MCDRV_PCM_MONO  (1) Mono   */
++                                      MCDRV_PCM_MONO ,
++                                      /* bOrder : Bit Order Setting                                     */
++                                      /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++                                      /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++                                      /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++                                      /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++                                      MCDRV_PCM_MSB_FIRST,
++                                      /* bLaw : Data Format Setting        */
++                                      /*     MCDRV_PCM_LINEAR(0)  : Linear */
++                                      /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++                                      /*     MCDRV_PCM_MULAW (2)  : u-Law */
++                                      MCDRV_PCM_LINEAR,
++                                      /* bBitSel : Bit Width Setting        */
++                                      /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++                                      /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++                                      /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++                                      /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++                                      MCDRV_PCM_BITSEL_8
++                              },
++                              /* asSlot : Setting of a slot number of data to be fed to each channel */
++                              {0, 1}
++                      },
++                      /* sDit       */
++                      {
++                              /* wSrcRate : Sampling Rate Converter Setting */
++                              0,
++                              /* sDaFormat : Digital Audio Format Information */
++                              {
++                                      /* bBitSel : Bit Width Setting     */
++                                      /*     MCDRV_BITSEL_16(0)  : 16bit */
++                                      /*     MCDRV_BITSEL_20(1)  : 20bit */
++                                      /*     MCDRV_BITSEL_24(2)  : 24bit */
++                                      MCDRV_BITSEL_16,
++                                      /* bMode : Data Format Setting                             */
++                                      /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++                                      /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++                                      /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++                                      MCDRV_DAMODE_I2S
++                              },
++                              /* sPcmFormat : PCM Format Information */
++                              {
++                                      /* bMono : Mono / Stereo Setting  */
++                                      /*     MCDRV_PCM_STEREO(0) Stereo */
++                                      /*     MCDRV_PCM_MONO  (1) Mono   */
++                                      MCDRV_PCM_MONO ,
++                                      /* bOrder : Bit Order Setting                                     */
++                                      /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++                                      /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++                                      /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++                                      /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++                                      MCDRV_PCM_MSB_FIRST,
++                                      /* bLaw : Data Format Setting        */
++                                      /*     MCDRV_PCM_LINEAR(0)  : Linear */
++                                      /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++                                      /*     MCDRV_PCM_MULAW (2)  : u-Law */
++                                      MCDRV_PCM_LINEAR,
++                                      /* bBitSel : Bit Width Setting        */
++                                      /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++                                      /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++                                      /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++                                      /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++                                      MCDRV_PCM_BITSEL_8
++                              },
++                              /* asSlot Setting of a slot number of data to be transmitted from each channel */
++                              {0, 1}
++                      }
++              },
++              /* DIO port 1 */
++              {
++                      /* sDioCommon */
++                      {
++                              /* bMasterSlave : Master / Slave Setting */
++                              /*     MCDRV_DIO_SLAVE (0)  : Slave      */
++                              /*     MCDRV_DIO_MASTER(1)  : Master     */
++                              MCDRV_DIO_SLAVE,
++                              /* bAutoFs : Sampling frequency automatic measurement ON/OFF Setting in slave mode */
++                              /*     MCDRV_AUTOFS_OFF(0)  : OFF */
++                              /*     MCDRV_AUTOFS_ON (1)  : ON  */
++                              MCDRV_AUTOFS_ON ,
++                              /* bFs : Sampling Rate Setting        */
++                              /*     MCDRV_FS_48000(0)  : 48kHz     */
++                              /*     MCDRV_FS_44100(1)  : 44.1kHz   */
++                              /*     MCDRV_FS_32000(2)  : 32kHz     */
++                              /*     MCDRV_FS_24000(4)  : 24kHz     */
++                              /*     MCDRV_FS_22050(5)  : 22.05kHz  */
++                              /*     MCDRV_FS_16000(6)  : 16kHz     */
++                              /*     MCDRV_FS_12000(8)  : 12kHz     */
++                              /*     MCDRV_FS_11025(9)  : 11.025kHz */
++                              /*     MCDRV_FS_8000 (10) : 8kHz      */
++                              MCDRV_FS_8000,
++                              /* bBckFs : Bit Clock Frequency Setting */
++                              /*     MCDRV_BCKFS_64 (0)  : LRCK x  64 */
++                              /*     MCDRV_BCKFS_48 (1)  : LRCK x  48 */
++                              /*     MCDRV_BCKFS_32 (2)  : LRCK x  32 */
++                              /*     MCDRV_BCKFS_512(4)  : LRCK x 512 */
++                              /*     MCDRV_BCKFS_256(5)  : LRCK x 256 */
++                              /*     MCDRV_BCKFS_128(6)  : LRCK x 128 */
++                              /*     MCDRV_BCKFS_16 (7)  : LRCK x  16 */
++                              MCDRV_BCKFS_32,
++                              /* bInterface : Interface Selection      */
++                              /*     MCDRV_DIO_DA (0)  : Digital Audio */
++                              /*     MCDRV_DIO_PCM(1)  : PCM           */
++                              MCDRV_DIO_PCM,
++                              /* bBckInvert : Bit Clock Inversion Setting     */
++                              /*     MCDRV_BCLK_NORMAL(0)  : Normal Operation */
++                              /*     MCDRV_BCLK_INVERT(1)  : Clock Inverted   */
++                              MCDRV_BCLK_NORMAL,
++                              /* bPcmHizTim : High Impedance transition timing after transmitting the last PCM I/F data */
++                              /*     MCDRV_PCMHIZTIM_FALLING(0)  : BCLK#* Falling Edge */
++                              /*     MCDRV_PCMHIZTIM_RISING (1)  : BCLK#* Rising Edge  */
++                              MCDRV_PCMHIZTIM_FALLING,
++                              /* bPcmClkDown : Bit Clock Setting with PCM selected and Master selected                */
++                              /*     MCDRV_PCM_CLKDOWN_OFF (0)  : A bit clock value specified with bBckFs             */
++                              /*     MCDRV_PCM_CLKDOWN_HALF(1)  : A half of the bit clock value specified with bBckFs */
++                              MCDRV_PCM_CLKDOWN_OFF,
++                              /* bPcmFrame : Frame Mode Setting with PCM interface */
++                              /*     MCDRV_PCM_SHORTFRAME(0)  : Short Frame        */
++                              /*     MCDRV_PCM_LONGFRAME (1)  : Long Frame         */
++                              MCDRV_PCM_SHORTFRAME,
++                              /* bPcmHighPeriod : LR clock High time setting with PCM selected and Master selected */
++                              /*     0 to 31  : High level keeps during the period of time of         */
++                              /*                (setting value + 1) of the bit clock.                 */
++                              0,
++                      },
++                      /* sDir       */
++                      {
++                              /* wSrcRate : Sampling Rate Converter Setting */
++                              0,
++                              /* sDaFormat : Digital Audio Format Information */
++                              {
++                                      /* bBitSel : Bit Width Setting     */
++                                      /*     MCDRV_BITSEL_16(0)  : 16bit */
++                                      /*     MCDRV_BITSEL_20(1)  : 20bit */
++                                      /*     MCDRV_BITSEL_24(2)  : 24bit */
++                                      MCDRV_BITSEL_16,
++                                      /* bMode : Data Format Setting                             */
++                                      /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++                                      /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++                                      /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++                                      MCDRV_DAMODE_HEADALIGN
++                              },
++                              /* sPcmFormat : PCM Format Information */
++                              {
++                                      /* bMono : Mono / Stereo Setting  */
++                                      /*     MCDRV_PCM_STEREO(0) Stereo */
++                                      /*     MCDRV_PCM_MONO  (1) Mono   */
++                                      MCDRV_PCM_STEREO ,
++                                      /* bOrder : Bit Order Setting                                     */
++                                      /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++                                      /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++                                      /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++                                      /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++                                      MCDRV_PCM_MSB_FIRST,
++                                      /* bLaw : Data Format Setting        */
++                                      /*     MCDRV_PCM_LINEAR(0)  : Linear */
++                                      /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++                                      /*     MCDRV_PCM_MULAW (2)  : u-Law */
++                                      MCDRV_PCM_LINEAR,
++                                      /* bBitSel : Bit Width Setting        */
++                                      /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++                                      /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++                                      /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++                                      /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++                                      MCDRV_PCM_BITSEL_16
++                              },
++                              /* asSlot : Setting of a slot number of data to be fed to each channel */
++                              {0, 0}
++                      },
++                      /* sDit       */
++                      {
++                              /* wSrcRate : Sampling Rate Converter Setting */
++                              0,
++                              /* sDaFormat : Digital Audio Format Information */
++                              {
++                                      /* bBitSel : Bit Width Setting     */
++                                      /*     MCDRV_BITSEL_16(0)  : 16bit */
++                                      /*     MCDRV_BITSEL_20(1)  : 20bit */
++                                      /*     MCDRV_BITSEL_24(2)  : 24bit */
++                                      MCDRV_BITSEL_16,
++                                      /* bMode : Data Format Setting                             */
++                                      /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++                                      /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++                                      /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++                                      MCDRV_DAMODE_HEADALIGN
++                              },
++                              /* sPcmFormat : PCM Format Information */
++                              {
++                                      /* bMono : Mono / Stereo Setting  */
++                                      /*     MCDRV_PCM_STEREO(0) Stereo */
++                                      /*     MCDRV_PCM_MONO  (1) Mono   */
++                                      MCDRV_PCM_STEREO ,
++                                      /* bOrder : Bit Order Setting                                     */
++                                      /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++                                      /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++                                      /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++                                      /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++                                      MCDRV_PCM_MSB_FIRST,
++                                      /* bLaw : Data Format Setting        */
++                                      /*     MCDRV_PCM_LINEAR(0)  : Linear */
++                                      /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++                                      /*     MCDRV_PCM_MULAW (2)  : u-Law */
++                                      MCDRV_PCM_LINEAR,
++                                      /* bBitSel : Bit Width Setting        */
++                                      /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++                                      /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++                                      /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++                                      /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++                                      MCDRV_PCM_BITSEL_16
++                              },
++                              /* asSlot Setting of a slot number of data to be transmitted from each channel */
++                              {0, 1}
++                      }
++              },
++              /* DIO port 2 */
++              {
++                      /* sDioCommon */
++                      {
++                              /* bMasterSlave : Master / Slave Setting */
++                              /*     MCDRV_DIO_SLAVE (0)  : Slave      */
++                              /*     MCDRV_DIO_MASTER(1)  : Master     */
++                              MCDRV_DIO_MASTER,
++                              /* bAutoFs : Sampling frequency automatic measurement ON/OFF Setting in slave mode */
++                              /*     MCDRV_AUTOFS_OFF(0)  : OFF */
++                              /*     MCDRV_AUTOFS_ON (1)  : ON  */
++                              MCDRV_AUTOFS_ON ,
++                              /* bFs : Sampling Rate Setting        */
++                              /*     MCDRV_FS_48000(0)  : 48kHz     */
++                              /*     MCDRV_FS_44100(1)  : 44.1kHz   */
++                              /*     MCDRV_FS_32000(2)  : 32kHz     */
++                              /*     MCDRV_FS_24000(4)  : 24kHz     */
++                              /*     MCDRV_FS_22050(5)  : 22.05kHz  */
++                              /*     MCDRV_FS_16000(6)  : 16kHz     */
++                              /*     MCDRV_FS_12000(8)  : 12kHz     */
++                              /*     MCDRV_FS_11025(9)  : 11.025kHz */
++                              /*     MCDRV_FS_8000 (10) : 8kHz      */
++                              MCDRV_FS_8000,
++                              /* bBckFs : Bit Clock Frequency Setting */
++                              /*     MCDRV_BCKFS_64 (0)  : LRCK x  64 */
++                              /*     MCDRV_BCKFS_48 (1)  : LRCK x  48 */
++                              /*     MCDRV_BCKFS_32 (2)  : LRCK x  32 */
++                              /*     MCDRV_BCKFS_512(4)  : LRCK x 512 */
++                              /*     MCDRV_BCKFS_256(5)  : LRCK x 256 */
++                              /*     MCDRV_BCKFS_128(6)  : LRCK x 128 */
++                              /*     MCDRV_BCKFS_16 (7)  : LRCK x  16 */
++                              MCDRV_BCKFS_32,
++                              /* bInterface : Interface Selection      */
++                              /*     MCDRV_DIO_DA (0)  : Digital Audio */
++                              /*     MCDRV_DIO_PCM(1)  : PCM           */
++                              MCDRV_DIO_PCM,
++                              /* bBckInvert : Bit Clock Inversion Setting     */
++                              /*     MCDRV_BCLK_NORMAL(0)  : Normal Operation */
++                              /*     MCDRV_BCLK_INVERT(1)  : Clock Inverted   */
++                              MCDRV_BCLK_NORMAL,
++                              /* bPcmHizTim : High Impedance transition timing after transmitting the last PCM I/F data */
++                              /*     MCDRV_PCMHIZTIM_FALLING(0)  : BCLK#* Falling Edge */
++                              /*     MCDRV_PCMHIZTIM_RISING (1)  : BCLK#* Rising Edge  */
++                              MCDRV_PCMHIZTIM_FALLING,
++                              /* bPcmClkDown : Bit Clock Setting with PCM selected and Master selected                */
++                              /*     MCDRV_PCM_CLKDOWN_OFF (0)  : A bit clock value specified with bBckFs             */
++                              /*     MCDRV_PCM_CLKDOWN_HALF(1)  : A half of the bit clock value specified with bBckFs */
++                              MCDRV_PCM_CLKDOWN_OFF,
++                              /* bPcmFrame : Frame Mode Setting with PCM interface */
++                              /*     MCDRV_PCM_SHORTFRAME(0)  : Short Frame        */
++                              /*     MCDRV_PCM_LONGFRAME (1)  : Long Frame         */
++                              MCDRV_PCM_SHORTFRAME,
++                              /* bPcmHighPeriod : LR clock High time setting with PCM selected and Master selected */
++                              /*     0 to 31  : High level keeps during the period of time of         */
++                              /*                (setting value + 1) of the bit clock.                 */
++                              0,
++                      },
++                      /* sDir       */
++                      {
++                              /* wSrcRate : Sampling Rate Converter Setting */
++                              0,
++                              /* sDaFormat : Digital Audio Format Information */
++                              {
++                                      /* bBitSel : Bit Width Setting     */
++                                      /*     MCDRV_BITSEL_16(0)  : 16bit */
++                                      /*     MCDRV_BITSEL_20(1)  : 20bit */
++                                      /*     MCDRV_BITSEL_24(2)  : 24bit */
++                                      MCDRV_BITSEL_16,
++                                      /* bMode : Data Format Setting                             */
++                                      /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++                                      /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++                                      /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++                                      MCDRV_DAMODE_HEADALIGN
++                              },
++                              /* sPcmFormat : PCM Format Information */
++                              {
++                                      /* bMono : Mono / Stereo Setting  */
++                                      /*     MCDRV_PCM_STEREO(0) Stereo */
++                                      /*     MCDRV_PCM_MONO  (1) Mono   */
++                                      MCDRV_PCM_STEREO ,
++                                      /* bOrder : Bit Order Setting                                     */
++                                      /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++                                      /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++                                      /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++                                      /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++                                      MCDRV_PCM_MSB_FIRST,
++                                      /* bLaw : Data Format Setting        */
++                                      /*     MCDRV_PCM_LINEAR(0)  : Linear */
++                                      /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++                                      /*     MCDRV_PCM_MULAW (2)  : u-Law */
++                                      MCDRV_PCM_LINEAR,
++                                      /* bBitSel : Bit Width Setting        */
++                                      /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++                                      /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++                                      /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++                                      /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++                                      MCDRV_PCM_BITSEL_16
++                              },
++                              /* asSlot : Setting of a slot number of data to be fed to each channel */
++                              {0, 0}
++                      },
++                      /* sDit       */
++                      {
++                              /* wSrcRate : Sampling Rate Converter Setting */
++                              0,
++                              /* sDaFormat : Digital Audio Format Information */
++                              {
++                                      /* bBitSel : Bit Width Setting     */
++                                      /*     MCDRV_BITSEL_16(0)  : 16bit */
++                                      /*     MCDRV_BITSEL_20(1)  : 20bit */
++                                      /*     MCDRV_BITSEL_24(2)  : 24bit */
++                                      MCDRV_BITSEL_16,
++                                      /* bMode : Data Format Setting                             */
++                                      /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++                                      /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++                                      /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++                                      MCDRV_DAMODE_HEADALIGN
++                              },
++                              /* sPcmFormat : PCM Format Information */
++                              {
++                                      /* bMono : Mono / Stereo Setting  */
++                                      /*     MCDRV_PCM_STEREO(0) Stereo */
++                                      /*     MCDRV_PCM_MONO  (1) Mono   */
++                                      MCDRV_PCM_MONO ,
++                                      /* bOrder : Bit Order Setting                                     */
++                                      /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++                                      /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++                                      /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++                                      /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++                                      MCDRV_PCM_MSB_FIRST,
++                                      /* bLaw : Data Format Setting        */
++                                      /*     MCDRV_PCM_LINEAR(0)  : Linear */
++                                      /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++                                      /*     MCDRV_PCM_MULAW (2)  : u-Law */
++                                      MCDRV_PCM_LINEAR,
++                                      /* bBitSel : Bit Width Setting        */
++                                      /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++                                      /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++                                      /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++                                      /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++                                      MCDRV_PCM_BITSEL_16
++                              },
++                              /* asSlot Setting of a slot number of data to be transmitted from each channel */
++                              {0, 1}
++                      }
++              }
++      }
++};
++
++/* ========================================
++   DAC settings
++   ========================================*/
++static const MCDRV_DAC_INFO stDacInfo_Default = {
++      /* bMasterSwap : DAC Master Path SWAP Setting                          */
++      /*     MCDRV_DSWAP_OFF      (0)  : No SWAP                             */
++      /*     MCDRV_DSWAP_SWAP     (1)  : SWAP                                */
++      /*     MCDRV_DSWAP_MUTE     (2)  : MUTE                                */
++      /*     MCDRV_DSWAP_RMVCENTER(3)  : Center Removed                      */
++      /*     MCDRV_DSWAP_MONO     (4)  : Mono                                */
++      /*     MCDRV_DSWAP_MONOHALF (5)  : Reserved (do not use this setting)  */
++      /*     MCDRV_DSWAP_BOTHL    (6)  : Lch data output in both Lch and Rch */
++      /*     MCDRV_DSWAP_BOTHR    (7)  : Rch data output in both Lch and Rch */
++      MCDRV_DSWAP_OFF,
++      /* bVoiceSwap : DAC Voice Path SWAP Setting                            */
++      /*     MCDRV_DSWAP_OFF      (0)  : No SWAP                             */
++      /*     MCDRV_DSWAP_SWAP     (1)  : SWAP                                */
++      /*     MCDRV_DSWAP_MUTE     (2)  : MUTE                                */
++      /*     MCDRV_DSWAP_RMVCENTER(3)  : Center Removed                      */
++      /*     MCDRV_DSWAP_MONO     (4)  : Mono (-6dB)                         */
++      /*     MCDRV_DSWAP_MONOHALF (5)  : Reserved (do not use this setting)  */
++      /*     MCDRV_DSWAP_BOTHL    (6)  : Lch data output in both Lch and Rch */
++      /*     MCDRV_DSWAP_BOTHR    (7)  : Rch data output in both Lch and Rch */
++      MCDRV_DSWAP_OFF,
++      /* bDcCut : HP, SP Protection DC-ct Filter Setting  */
++      /*     MCDRV_DCCUT_ON (0)  : DC-cut Filter ON       */
++      /*     MCDRV_DCCUT_OFF(1)  : DC-cut Filter OFF      */
++      MCDRV_DCCUT_ON
++};
++
++/* ========================================
++   ADC settings
++   ========================================*/
++
++static const MCDRV_ADC_INFO stAdcInfo_Default = {
++      /* bAgcAdjust : AGC Gain Control Range     */
++      /*     MCDRV_AGCADJ_24(0)  : -3dB to +24dB */
++      /*     MCDRV_AGCADJ_18(1)  : -3dB to +18dB */
++      /*     MCDRV_AGCADJ_12(2)  : -3dB to +12dB */
++      /*     MCDRV_AGCADJ_0 (3)  : -3dB to  +0dB */
++      MCDRV_AGCADJ_0,
++      /* bAgcOn : AGC ON/OFF Setting */
++      /*     MCDRV_AGC_OFF(0)  : OFF */
++      /*     MCDRV_AGC_ON (1)  : ON  */
++      MCDRV_AGC_OFF,
++      /* bMonot : Mono / Stereo Setting    */
++      /*     MCDRV_ADC_STEREO(0)  : Stereo */
++      /*     MCDRV_ADC_MONO  (1)  : Mono   */
++      MCDRV_ADC_STEREO
++};
++
++/* ========================================
++   SP settings
++   ========================================*/
++static const MCDRV_SP_INFO stSpInfo_Default = {
++      /* bSwap : Swap setting                */
++      /*     MCDRV_SPSWAP_OFF (0)  : No SWAP */
++      /*     MCDRV_SPSWAP_SWAP(1)  : SWAP    */
++      MCDRV_SPSWAP_OFF
++};
++
++/* ========================================
++   DNG settings
++   ========================================*/
++static const MCDRV_DNG_INFO stDngInfo_Default = {
++      /* bOnOff[] : Digital Noise Gate On/Off Setting */
++      /*     MCDRV_DNG_OFF(0)  : OFF                */
++      /*     MCDRV_DNG_ON (1)  : ON                 */
++      {MCDRV_DNG_OFF, MCDRV_DNG_OFF, MCDRV_DNG_OFF},
++
++      /* bThreshold[] : Threshold Setting    */
++      /*     MCDRV_DNG_THRES_30    (0) */
++      /*     MCDRV_DNG_THRES_36    (1) */
++      /*     MCDRV_DNG_THRES_42    (2) */
++      /*     MCDRV_DNG_THRES_48    (3) */
++      /*     MCDRV_DNG_THRES_54    (4) */
++      /*     MCDRV_DNG_THRES_60    (5) */
++      /*     MCDRV_DNG_THRES_66    (6) */
++      /*     MCDRV_DNG_THRES_72    (7) */
++      /*     MCDRV_DNG_THRES_78    (8) */
++      /*     MCDRV_DNG_THRES_84    (9) */
++      {MCDRV_DNG_THRES_60, MCDRV_DNG_THRES_60, MCDRV_DNG_THRES_60},
++
++      /* bHold[] : Hold Time Setting         */
++      /*     MCDRV_DNG_HOLD_30 (0)  :  30ms */
++      /*     MCDRV_DNG_HOLD_120(1)  : 120ms */
++      /*     MCDRV_DNG_HOLD_500(2)  : 500ms */
++      {MCDRV_DNG_HOLD_500, MCDRV_DNG_HOLD_500, MCDRV_DNG_HOLD_500},
++
++      /* bAttack[] : Attack Time Setting        */
++      /*     MCDRV_DNG_ATTACK_25   (0)  :   25ms */
++      /*     MCDRV_DNG_ATTACK_100  (1)  :  100ms */
++      /*     MCDRV_DNG_ATTACK_400  (2)  :  400ms */
++      /*     MCDRV_DNG_ATTACK_800  (3)  :  800ms */
++      {MCDRV_DNG_ATTACK_100, MCDRV_DNG_ATTACK_100, MCDRV_DNG_ATTACK_100},
++
++      /* bRelease[] : Release Time Setting        */
++      /*     MCDRV_DNG_RELEASE_7950(0)  : 7.95ms */
++      /*     MCDRV_DNG_RELEASE_470 (1)  : 0.47ms */
++      /*     MCDRV_DNG_RELEASE_940 (2)  : 0.94ms */
++      {MCDRV_DNG_RELEASE_940, MCDRV_DNG_RELEASE_940, MCDRV_DNG_RELEASE_940},
++
++      /* bTarget[] : Target Volume Setting        */
++      /*     MCDRV_DNG_TARGET_6    (0)  : -6dB  */
++      /*     MCDRV_DNG_TARGET_9    (1)  : -9dB  */
++      /*     MCDRV_DNG_TARGET_12   (2)  : -12dB */
++      /*     MCDRV_DNG_TARGET_15   (3)  : -15dB */
++      /*     MCDRV_DNG_TARGET_18   (4)  : -18dB */
++      /*     MCDRV_DNG_TARGET_MUTE (5)  : Mute  */
++      {MCDRV_DNG_TARGET_MUTE, MCDRV_DNG_TARGET_MUTE, MCDRV_DNG_TARGET_MUTE},
++};
++#if 0
++static const MCDRV_DNG_INFO stDngInfo_Default = {
++      /* bOnOff : Digital Noise Gate On/Off Setting */
++      /*     MCDRV_DNG_OFF(0)  : OFF                */
++      /*     MCDRV_DNG_ON (1)  : ON                 */
++      MCDRV_DNG_OFF,
++
++      /* bThreshold : Threshold Setting    */
++      /*     MCDRV_DNG_THRES_5BIT  (0) */
++      /*     MCDRV_DNG_THRES_7BIT  (1) */
++      /*     MCDRV_DNG_THRES_9BIT  (2) */
++      /*     MCDRV_DNG_THRES_11BIT (3) */
++      /*     MCDRV_DNG_THRES_13BIT (4) */
++      /*     MCDRV_DNG_THRES_15BIT (5) */
++      /*     MCDRV_DNG_THRES_17BIT (6) */
++      /*     MCDRV_DNG_THRES_21BIT (7) */
++      MCDRV_DNG_THRES_11BIT,
++
++      /* bHold : Hold Time Setting         */
++      /*     MCDRV_DNG_HOLD_30 (0)  :  30ms */
++      /*     MCDRV_DNG_HOLD_120(1)  : 120ms */
++      /*     MCDRV_DNG_HOLD_500(2)  : 500ms */
++      MCDRV_DNG_HOLD_500,
++
++      /* bAttack : Attack Time Setting        */
++      /*     MCDRV_DNG_ATTACK_25   (0)  :   25ms */
++      /*     MCDRV_DNG_ATTACK_800  (1)  :  800ms */
++      /*     MCDRV_DNG_ATTACK_1100 (2)  : 1100ms */
++      MCDRV_DNG_ATTACK_1100,
++
++      /* bRelease : Release Time Setting        */
++      /*     MCDRV_DNG_RELEASE_7950(0)  : 7.95ms */
++      /*     MCDRV_DNG_RELEASE_470 (1)  : 0.47ms */
++      /*     MCDRV_DNG_RELEASE_940 (2)  : 0.94ms */
++      MCDRV_DNG_RELEASE_940,
++
++};
++#endif
++
++/* ========================================
++   AudioEngine settings
++   ========================================*/
++static MCDRV_AE_INFO sAeInfo_1 = {
++      /* On/Off */
++      0x00,
++      /* BEX */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* WIDE */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00
++      },
++      /* DRC */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* EQ5 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00
++      },
++      /* EQ3 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00
++      }
++};
++
++static MCDRV_AE_INFO sAeInfo_2 = {
++      /* On/Off */
++      0x00,
++      /* BEX */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* WIDE */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00
++      },
++      /* DRC */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* EQ5 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00
++      },
++      /* EQ3 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00
++      }
++};
++
++static MCDRV_AE_INFO sAeInfo_3 = {
++      /* On/Off */
++      0x00,
++      /* BEX */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* WIDE */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00
++      },
++      /* DRC */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* EQ5 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00
++      },
++      /* EQ3 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00
++      }
++};
++
++static MCDRV_AE_INFO sAeInfo_4 = {
++      /* On/Off */
++      0x00,
++      /* BEX */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* WIDE */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00
++      },
++      /* DRC */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* EQ5 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00
++      },
++      /* EQ3 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00
++      }
++};
++
++static MCDRV_AE_INFO sAeInfo_5 = {
++      /* On/Off */
++      0x00,
++      /* BEX */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* WIDE */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00
++      },
++      /* DRC */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* EQ5 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00
++      },
++      /* EQ3 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00
++      }
++};
++
++/* ========================================
++   System EQ settings
++   ========================================*/
++static MCDRV_SYSEQ_INFO stSyseqInfo_Default = {
++      /* On/Off */
++      0x00,
++      /* EQ */
++      {
++              0x10,0xc4,0x50,0x12,0xc4,0x40,0x02,0xa9,
++              0x60,0xed,0x3b,0xc0,0xfc,0x92,0x40,
++      },
++};
++
++#endif
+diff --git a/sound/soc/codecs/mc1n2/mc1n2_cfg_px.h b/sound/soc/codecs/mc1n2/mc1n2_cfg_px.h
+new file mode 100644
+index 0000000..2d159af
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mc1n2_cfg_px.h
+@@ -0,0 +1,1199 @@
++/*
++ * MC-1N2 ASoC codec driver
++ *
++ * Copyright (c) 2010-2011 Yamaha Corporation
++ *
++ * This software is provided 'as-is', without any express or implied
++ * warranty.  In no event will the authors be held liable for any damages
++ * arising from the use of this software.
++ *
++ * Permission is granted to anyone to use this software for any purpose,
++ * including commercial applications, and to alter it and redistribute it
++ * freely, subject to the following restrictions:
++ *
++ * 1. The origin of this software must not be misrepresented; you must not
++ *    claim that you wrote the original software. If you use this software
++ *    in a product, an acknowledgment in the product documentation would be
++ *    appreciated but is not required.
++ * 2. Altered source versions must be plainly marked as such, and must not be
++ *    misrepresented as being the original software.
++ * 3. This notice may not be removed or altered from any source distribution.
++ */
++
++#ifndef MC1N2_CFG_H
++#define MC1N2_CFG_H
++
++#include "mcdriver.h"
++
++/*
++ * ALSA Version
++ */
++/* #define ALSA_VER_1_0_19 */
++/* #define ALSA_VER_1_0_21 */
++/* #define ALSA_VER_1_0_23 */
++/* #define ALSA_VER_ANDROID_2_6_35 */
++#define ALSA_VER_ANDROID_3_0
++
++#define DIO0_DAI_ENABLE
++/* #define DIO1_DAI_ENABLE */
++/* #define DIO2_DAI_ENABLE */
++
++#ifdef ALSA_VER_ANDROID_3_0
++static struct mc1n2_setup mc1n2_cfg_setup = {
++      {  /* MCDRV_INIT_INFO */
++              MCDRV_CKSEL_CMOS, /* bCkSel */
++              41,               /* bDivR0 */
++              126,              /* bDivF0 */
++              41,               /* bDivR1 */
++              126,              /* bDivF1 */
++              0,                /* bRange0*/
++              0,                /* bRange1*/
++              0,                /* bBypass*/
++              MCDRV_DAHIZ_LOW,  /* bDioSdo0Hiz */
++              MCDRV_DAHIZ_LOW,  /* bDioSdo1Hiz */
++              MCDRV_DAHIZ_LOW,  /* bDioSdo2Hiz */
++              MCDRV_DAHIZ_HIZ,  /* bDioClk0Hiz */
++              MCDRV_DAHIZ_HIZ,  /* bDioClk1Hiz */
++              MCDRV_DAHIZ_HIZ,  /* bDioClk2Hiz */
++              MCDRV_PCMHIZ_HIZ, /* bPcmHiz */
++              MCDRV_LINE_STEREO,/* bLineIn1Dif */
++              0,                /* bLineIn2Dif */
++              MCDRV_LINE_STEREO,/* bLineOut1Dif */
++              MCDRV_LINE_STEREO,/* bLineOUt2Dif */
++              MCDRV_SPMN_ON,    /* bSpmn */
++              MCDRV_MIC_DIF,    /* bMic1Sng */
++              MCDRV_MIC_DIF,    /* bMic2Sng */
++              MCDRV_MIC_DIF,    /* bMic3Sng */
++              MCDRV_POWMODE_NORMAL, /* bPowerMode */
++              MCDRV_SPHIZ_PULLDOWN, /* bSpHiz */
++              MCDRV_LDO_ON,     /* bLdo */
++              MCDRV_PAD_GPIO,   /* bPad0Func */
++              MCDRV_PAD_GPIO,   /* bPad1Func */
++              MCDRV_PAD_GPIO,   /* bPad2Func */
++              MCDRV_OUTLEV_4,   /* bAvddLev */
++              0,                /* bVrefLev */
++              MCDRV_DCLGAIN_12, /* bDclGain */
++              MCDRV_DCLLIMIT_0, /* bDclLimit */
++              1,                   /* set Hi-power mode 0: HP mode 1: normal */
++              0,                /* bReserved1 */
++              0,                /* bReserved2 */
++              0,                /* bReserved3 */
++              0,                /* bReserved4 */
++              0,                /* bReserved5 */
++              {                 /* sWaitTime */
++                      130000,         /* dAdHpf */
++                      25000,          /* dMic1Cin */
++                      25000,          /* dMic2Cin */
++                      25000,          /* dMic3Cin */
++                      25000,          /* dLine1Cin */
++                      25000,          /* dLine2Cin */
++                      5000,           /* dVrefRdy1 */
++                      15000,          /* dVrefRdy2 */
++                      9000,           /* dHpRdy */
++                      13000,          /* dSpRdy */
++                      0,              /* dPdm */
++                      1000,           /* dAnaRdyInterval */
++                      1000,           /* dSvolInterval */
++                      1000,           /* dAnaRdyTimeOut */
++                      1000            /* dSvolTimeOut */
++              }
++      }, /* MCDRV_INIT_INFO end */
++      {  /* pcm_extend */
++              0, 0, 0
++      }, /* pcm_extend end */
++      {  /* pcm_hiz_redge */
++              MCDRV_PCMHIZTIM_FALLING, MCDRV_PCMHIZTIM_FALLING, MCDRV_PCMHIZTIM_FALLING
++      }, /* pcm_hiz_redge end */
++      {  /* pcm_hperiod */
++              1, 1, 1
++      }, /* pcm_hperiod end */
++      {  /* slot */
++              { {0, 1}, {0, 1} },
++              { {0, 1}, {0, 1} },
++              { {0, 1}, {0, 1} }
++      }  /* slot end */
++};
++#endif
++
++static const MCDRV_DIO_INFO stDioInfo_Default = {
++      {
++              /* DIO port 0 */
++              {
++                      /* sDioCommon */
++                      {
++                              /* bMasterSlave : Master / Slave Setting */
++                              /*     MCDRV_DIO_SLAVE (0)  : Slave      */
++                              /*     MCDRV_DIO_MASTER(1)  : Master     */
++                              MCDRV_DIO_MASTER,
++                              /* bAutoFs : Sampling frequency automatic measurement ON/OFF Setting in slave mode */
++                              /*     MCDRV_AUTOFS_OFF(0)  : OFF */
++                              /*     MCDRV_AUTOFS_ON (1)  : ON  */
++                              MCDRV_AUTOFS_ON ,
++                              /* bFs : Sampling Rate Setting        */
++                              /*     MCDRV_FS_48000(0)  : 48kHz     */
++                              /*     MCDRV_FS_44100(1)  : 44.1kHz   */
++                              /*     MCDRV_FS_32000(2)  : 32kHz     */
++                              /*     MCDRV_FS_24000(4)  : 24kHz     */
++                              /*     MCDRV_FS_22050(5)  : 22.05kHz  */
++                              /*     MCDRV_FS_16000(6)  : 16kHz     */
++                              /*     MCDRV_FS_12000(8)  : 12kHz     */
++                              /*     MCDRV_FS_11025(9)  : 11.025kHz */
++                              /*     MCDRV_FS_8000 (10) : 8kHz      */
++                              MCDRV_FS_44100,
++                              /* bBckFs : Bit Clock Frequency Setting */
++                              /*     MCDRV_BCKFS_64 (0)  : LRCK x  64 */
++                              /*     MCDRV_BCKFS_48 (1)  : LRCK x  48 */
++                              /*     MCDRV_BCKFS_32 (2)  : LRCK x  32 */
++                              /*     MCDRV_BCKFS_512(4)  : LRCK x 512 */
++                              /*     MCDRV_BCKFS_256(5)  : LRCK x 256 */
++                              /*     MCDRV_BCKFS_128(6)  : LRCK x 128 */
++                              /*     MCDRV_BCKFS_16 (7)  : LRCK x  16 */
++                              MCDRV_BCKFS_32,
++                              /* bInterface : Interface Selection      */
++                              /*     MCDRV_DIO_DA (0)  : Digital Audio */
++                              /*     MCDRV_DIO_PCM(1)  : PCM           */
++                              MCDRV_DIO_DA,
++                              /* bBckInvert : Bit Clock Inversion Setting     */
++                              /*     MCDRV_BCLK_NORMAL(0)  : Normal Operation */
++                              /*     MCDRV_BCLK_INVERT(1)  : Clock Inverted   */
++                              MCDRV_BCLK_NORMAL,
++                              /* bPcmHizTim : High Impedance transition timing after transmitting the last PCM I/F data */
++                              /*     MCDRV_PCMHIZTIM_FALLING(0)  : BCLK#* Falling Edge */
++                              /*     MCDRV_PCMHIZTIM_RISING (1)  : BCLK#* Rising Edge  */
++                              MCDRV_PCMHIZTIM_FALLING,
++                              /* bPcmClkDown : Bit Clock Setting with PCM selected and Master selected                */
++                              /*     MCDRV_PCM_CLKDOWN_OFF (0)  : A bit clock value specified with bBckFs             */
++                              /*     MCDRV_PCM_CLKDOWN_HALF(1)  : A half of the bit clock value specified with bBckFs */
++                              MCDRV_PCM_CLKDOWN_OFF,
++                              /* bPcmFrame : Frame Mode Setting with PCM interface */
++                              /*     MCDRV_PCM_SHORTFRAME(0)  : Short Frame        */
++                              /*     MCDRV_PCM_LONGFRAME (1)  : Long Frame         */
++                              MCDRV_PCM_SHORTFRAME,
++                              /* bPcmHighPeriod : LR clock High time setting with PCM selected and Master selected */
++                              /*     0 to 31  : High level keeps during the period of time of         */
++                              /*                (setting value + 1) of the bit clock.                 */
++                              0,
++                      },
++                      /* sDir       */
++                      {
++                              /* wSrcRate : Sampling Rate Converter Setting */
++                              0,
++                              /* sDaFormat : Digital Audio Format Information */
++                              {
++                                      /* bBitSel : Bit Width Setting     */
++                                      /*     MCDRV_BITSEL_16(0)  : 16bit */
++                                      /*     MCDRV_BITSEL_20(1)  : 20bit */
++                                      /*     MCDRV_BITSEL_24(2)  : 24bit */
++                                      MCDRV_BITSEL_16,
++                                      /* bMode : Data Format Setting                             */
++                                      /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++                                      /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++                                      /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++                                      MCDRV_DAMODE_I2S
++                              },
++                              /* sPcmFormat : PCM Format Information */
++                              {
++                                      /* bMono : Mono / Stereo Setting  */
++                                      /*     MCDRV_PCM_STEREO(0) Stereo */
++                                      /*     MCDRV_PCM_MONO  (1) Mono   */
++                                      MCDRV_PCM_MONO ,
++                                      /* bOrder : Bit Order Setting                                     */
++                                      /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++                                      /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++                                      /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++                                      /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++                                      MCDRV_PCM_MSB_FIRST,
++                                      /* bLaw : Data Format Setting        */
++                                      /*     MCDRV_PCM_LINEAR(0)  : Linear */
++                                      /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++                                      /*     MCDRV_PCM_MULAW (2)  : u-Law */
++                                      MCDRV_PCM_LINEAR,
++                                      /* bBitSel : Bit Width Setting        */
++                                      /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++                                      /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++                                      /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++                                      /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++                                      MCDRV_PCM_BITSEL_8
++                              },
++                              /* asSlot : Setting of a slot number of data to be fed to each channel */
++                              {0, 1}
++                      },
++                      /* sDit       */
++                      {
++                              /* wSrcRate : Sampling Rate Converter Setting */
++                              0,
++                              /* sDaFormat : Digital Audio Format Information */
++                              {
++                                      /* bBitSel : Bit Width Setting     */
++                                      /*     MCDRV_BITSEL_16(0)  : 16bit */
++                                      /*     MCDRV_BITSEL_20(1)  : 20bit */
++                                      /*     MCDRV_BITSEL_24(2)  : 24bit */
++                                      MCDRV_BITSEL_16,
++                                      /* bMode : Data Format Setting                             */
++                                      /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++                                      /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++                                      /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++                                      MCDRV_DAMODE_I2S
++                              },
++                              /* sPcmFormat : PCM Format Information */
++                              {
++                                      /* bMono : Mono / Stereo Setting  */
++                                      /*     MCDRV_PCM_STEREO(0) Stereo */
++                                      /*     MCDRV_PCM_MONO  (1) Mono   */
++                                      MCDRV_PCM_MONO ,
++                                      /* bOrder : Bit Order Setting                                     */
++                                      /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++                                      /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++                                      /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++                                      /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++                                      MCDRV_PCM_MSB_FIRST,
++                                      /* bLaw : Data Format Setting        */
++                                      /*     MCDRV_PCM_LINEAR(0)  : Linear */
++                                      /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++                                      /*     MCDRV_PCM_MULAW (2)  : u-Law */
++                                      MCDRV_PCM_LINEAR,
++                                      /* bBitSel : Bit Width Setting        */
++                                      /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++                                      /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++                                      /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++                                      /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++                                      MCDRV_PCM_BITSEL_8
++                              },
++                              /* asSlot Setting of a slot number of data to be transmitted from each channel */
++                              {0, 1}
++                      }
++              },
++              /* DIO port 1 */
++              {
++                      /* sDioCommon */
++                      {
++                              /* bMasterSlave : Master / Slave Setting */
++                              /*     MCDRV_DIO_SLAVE (0)  : Slave      */
++                              /*     MCDRV_DIO_MASTER(1)  : Master     */
++                              MCDRV_DIO_SLAVE,
++                              /* bAutoFs : Sampling frequency automatic measurement ON/OFF Setting in slave mode */
++                              /*     MCDRV_AUTOFS_OFF(0)  : OFF */
++                              /*     MCDRV_AUTOFS_ON (1)  : ON  */
++                              MCDRV_AUTOFS_ON ,
++                              /* bFs : Sampling Rate Setting        */
++                              /*     MCDRV_FS_48000(0)  : 48kHz     */
++                              /*     MCDRV_FS_44100(1)  : 44.1kHz   */
++                              /*     MCDRV_FS_32000(2)  : 32kHz     */
++                              /*     MCDRV_FS_24000(4)  : 24kHz     */
++                              /*     MCDRV_FS_22050(5)  : 22.05kHz  */
++                              /*     MCDRV_FS_16000(6)  : 16kHz     */
++                              /*     MCDRV_FS_12000(8)  : 12kHz     */
++                              /*     MCDRV_FS_11025(9)  : 11.025kHz */
++                              /*     MCDRV_FS_8000 (10) : 8kHz      */
++                              MCDRV_FS_8000,
++                              /* bBckFs : Bit Clock Frequency Setting */
++                              /*     MCDRV_BCKFS_64 (0)  : LRCK x  64 */
++                              /*     MCDRV_BCKFS_48 (1)  : LRCK x  48 */
++                              /*     MCDRV_BCKFS_32 (2)  : LRCK x  32 */
++                              /*     MCDRV_BCKFS_512(4)  : LRCK x 512 */
++                              /*     MCDRV_BCKFS_256(5)  : LRCK x 256 */
++                              /*     MCDRV_BCKFS_128(6)  : LRCK x 128 */
++                              /*     MCDRV_BCKFS_16 (7)  : LRCK x  16 */
++                              MCDRV_BCKFS_32,
++                              /* bInterface : Interface Selection      */
++                              /*     MCDRV_DIO_DA (0)  : Digital Audio */
++                              /*     MCDRV_DIO_PCM(1)  : PCM           */
++                              MCDRV_DIO_DA,
++                              /* bBckInvert : Bit Clock Inversion Setting     */
++                              /*     MCDRV_BCLK_NORMAL(0)  : Normal Operation */
++                              /*     MCDRV_BCLK_INVERT(1)  : Clock Inverted   */
++                              MCDRV_BCLK_NORMAL,
++                              /* bPcmHizTim : High Impedance transition timing after transmitting the last PCM I/F data */
++                              /*     MCDRV_PCMHIZTIM_FALLING(0)  : BCLK#* Falling Edge */
++                              /*     MCDRV_PCMHIZTIM_RISING (1)  : BCLK#* Rising Edge  */
++                              MCDRV_PCMHIZTIM_FALLING,
++                              /* bPcmClkDown : Bit Clock Setting with PCM selected and Master selected                */
++                              /*     MCDRV_PCM_CLKDOWN_OFF (0)  : A bit clock value specified with bBckFs             */
++                              /*     MCDRV_PCM_CLKDOWN_HALF(1)  : A half of the bit clock value specified with bBckFs */
++                              MCDRV_PCM_CLKDOWN_OFF,
++                              /* bPcmFrame : Frame Mode Setting with PCM interface */
++                              /*     MCDRV_PCM_SHORTFRAME(0)  : Short Frame        */
++                              /*     MCDRV_PCM_LONGFRAME (1)  : Long Frame         */
++                              MCDRV_PCM_SHORTFRAME,
++                              /* bPcmHighPeriod : LR clock High time setting with PCM selected and Master selected */
++                              /*     0 to 31  : High level keeps during the period of time of         */
++                              /*                (setting value + 1) of the bit clock.                 */
++                              0,
++                      },
++                      /* sDir       */
++                      {
++                              /* wSrcRate : Sampling Rate Converter Setting */
++                              0,
++                              /* sDaFormat : Digital Audio Format Information */
++                              {
++                                      /* bBitSel : Bit Width Setting     */
++                                      /*     MCDRV_BITSEL_16(0)  : 16bit */
++                                      /*     MCDRV_BITSEL_20(1)  : 20bit */
++                                      /*     MCDRV_BITSEL_24(2)  : 24bit */
++                                      MCDRV_BITSEL_16,
++                                      /* bMode : Data Format Setting                             */
++                                      /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++                                      /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++                                      /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++                                      MCDRV_DAMODE_I2S
++                              },
++                              /* sPcmFormat : PCM Format Information */
++                              {
++                                      /* bMono : Mono / Stereo Setting  */
++                                      /*     MCDRV_PCM_STEREO(0) Stereo */
++                                      /*     MCDRV_PCM_MONO  (1) Mono   */
++                                      MCDRV_PCM_STEREO ,
++                                      /* bOrder : Bit Order Setting                                     */
++                                      /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++                                      /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++                                      /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++                                      /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++                                      MCDRV_PCM_MSB_FIRST,
++                                      /* bLaw : Data Format Setting        */
++                                      /*     MCDRV_PCM_LINEAR(0)  : Linear */
++                                      /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++                                      /*     MCDRV_PCM_MULAW (2)  : u-Law */
++                                      MCDRV_PCM_LINEAR,
++                                      /* bBitSel : Bit Width Setting        */
++                                      /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++                                      /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++                                      /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++                                      /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++                                      MCDRV_PCM_BITSEL_16
++                              },
++                              /* asSlot : Setting of a slot number of data to be fed to each channel */
++                              {1, 1}
++                      },
++                      /* sDit       */
++                      {
++                              /* wSrcRate : Sampling Rate Converter Setting */
++                              0,
++                              /* sDaFormat : Digital Audio Format Information */
++                              {
++                                      /* bBitSel : Bit Width Setting     */
++                                      /*     MCDRV_BITSEL_16(0)  : 16bit */
++                                      /*     MCDRV_BITSEL_20(1)  : 20bit */
++                                      /*     MCDRV_BITSEL_24(2)  : 24bit */
++                                      MCDRV_BITSEL_16,
++                                      /* bMode : Data Format Setting                             */
++                                      /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++                                      /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++                                      /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++                                      MCDRV_DAMODE_I2S
++                              },
++                              /* sPcmFormat : PCM Format Information */
++                              {
++                                      /* bMono : Mono / Stereo Setting  */
++                                      /*     MCDRV_PCM_STEREO(0) Stereo */
++                                      /*     MCDRV_PCM_MONO  (1) Mono   */
++                                      MCDRV_PCM_STEREO ,
++                                      /* bOrder : Bit Order Setting                                     */
++                                      /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++                                      /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++                                      /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++                                      /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++                                      MCDRV_PCM_MSB_FIRST,
++                                      /* bLaw : Data Format Setting        */
++                                      /*     MCDRV_PCM_LINEAR(0)  : Linear */
++                                      /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++                                      /*     MCDRV_PCM_MULAW (2)  : u-Law */
++                                      MCDRV_PCM_LINEAR,
++                                      /* bBitSel : Bit Width Setting        */
++                                      /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++                                      /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++                                      /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++                                      /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++                                      MCDRV_PCM_BITSEL_16
++                              },
++                              /* asSlot Setting of a slot number of data to be transmitted from each channel */
++                              {1, 0}
++                      }
++              },
++              /* DIO port 2 */
++              {
++                      /* sDioCommon */
++                      {
++                              /* bMasterSlave : Master / Slave Setting */
++                              /*     MCDRV_DIO_SLAVE (0)  : Slave      */
++                              /*     MCDRV_DIO_MASTER(1)  : Master     */
++                              MCDRV_DIO_MASTER,
++                              /* bAutoFs : Sampling frequency automatic measurement ON/OFF Setting in slave mode */
++                              /*     MCDRV_AUTOFS_OFF(0)  : OFF */
++                              /*     MCDRV_AUTOFS_ON (1)  : ON  */
++                              MCDRV_AUTOFS_ON ,
++                              /* bFs : Sampling Rate Setting        */
++                              /*     MCDRV_FS_48000(0)  : 48kHz     */
++                              /*     MCDRV_FS_44100(1)  : 44.1kHz   */
++                              /*     MCDRV_FS_32000(2)  : 32kHz     */
++                              /*     MCDRV_FS_24000(4)  : 24kHz     */
++                              /*     MCDRV_FS_22050(5)  : 22.05kHz  */
++                              /*     MCDRV_FS_16000(6)  : 16kHz     */
++                              /*     MCDRV_FS_12000(8)  : 12kHz     */
++                              /*     MCDRV_FS_11025(9)  : 11.025kHz */
++                              /*     MCDRV_FS_8000 (10) : 8kHz      */
++                              MCDRV_FS_8000,
++                              /* bBckFs : Bit Clock Frequency Setting */
++                              /*     MCDRV_BCKFS_64 (0)  : LRCK x  64 */
++                              /*     MCDRV_BCKFS_48 (1)  : LRCK x  48 */
++                              /*     MCDRV_BCKFS_32 (2)  : LRCK x  32 */
++                              /*     MCDRV_BCKFS_512(4)  : LRCK x 512 */
++                              /*     MCDRV_BCKFS_256(5)  : LRCK x 256 */
++                              /*     MCDRV_BCKFS_128(6)  : LRCK x 128 */
++                              /*     MCDRV_BCKFS_16 (7)  : LRCK x  16 */
++                              MCDRV_BCKFS_32,
++                              /* bInterface : Interface Selection      */
++                              /*     MCDRV_DIO_DA (0)  : Digital Audio */
++                              /*     MCDRV_DIO_PCM(1)  : PCM           */
++                              MCDRV_DIO_PCM,
++                              /* bBckInvert : Bit Clock Inversion Setting     */
++                              /*     MCDRV_BCLK_NORMAL(0)  : Normal Operation */
++                              /*     MCDRV_BCLK_INVERT(1)  : Clock Inverted   */
++                              MCDRV_BCLK_NORMAL,
++                              /* bPcmHizTim : High Impedance transition timing after transmitting the last PCM I/F data */
++                              /*     MCDRV_PCMHIZTIM_FALLING(0)  : BCLK#* Falling Edge */
++                              /*     MCDRV_PCMHIZTIM_RISING (1)  : BCLK#* Rising Edge  */
++                              MCDRV_PCMHIZTIM_FALLING,
++                              /* bPcmClkDown : Bit Clock Setting with PCM selected and Master selected                */
++                              /*     MCDRV_PCM_CLKDOWN_OFF (0)  : A bit clock value specified with bBckFs             */
++                              /*     MCDRV_PCM_CLKDOWN_HALF(1)  : A half of the bit clock value specified with bBckFs */
++                              MCDRV_PCM_CLKDOWN_OFF,
++                              /* bPcmFrame : Frame Mode Setting with PCM interface */
++                              /*     MCDRV_PCM_SHORTFRAME(0)  : Short Frame        */
++                              /*     MCDRV_PCM_LONGFRAME (1)  : Long Frame         */
++                              MCDRV_PCM_SHORTFRAME,
++                              /* bPcmHighPeriod : LR clock High time setting with PCM selected and Master selected */
++                              /*     0 to 31  : High level keeps during the period of time of         */
++                              /*                (setting value + 1) of the bit clock.                 */
++                              0,
++                      },
++                      /* sDir       */
++                      {
++                              /* wSrcRate : Sampling Rate Converter Setting */
++                              0,
++                              /* sDaFormat : Digital Audio Format Information */
++                              {
++                                      /* bBitSel : Bit Width Setting     */
++                                      /*     MCDRV_BITSEL_16(0)  : 16bit */
++                                      /*     MCDRV_BITSEL_20(1)  : 20bit */
++                                      /*     MCDRV_BITSEL_24(2)  : 24bit */
++                                      MCDRV_BITSEL_16,
++                                      /* bMode : Data Format Setting                             */
++                                      /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++                                      /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++                                      /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++                                      MCDRV_DAMODE_HEADALIGN
++                              },
++                              /* sPcmFormat : PCM Format Information */
++                              {
++                                      /* bMono : Mono / Stereo Setting  */
++                                      /*     MCDRV_PCM_STEREO(0) Stereo */
++                                      /*     MCDRV_PCM_MONO  (1) Mono   */
++                                      MCDRV_PCM_STEREO ,
++                                      /* bOrder : Bit Order Setting                                     */
++                                      /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++                                      /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++                                      /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++                                      /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++                                      MCDRV_PCM_MSB_FIRST,
++                                      /* bLaw : Data Format Setting        */
++                                      /*     MCDRV_PCM_LINEAR(0)  : Linear */
++                                      /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++                                      /*     MCDRV_PCM_MULAW (2)  : u-Law */
++                                      MCDRV_PCM_LINEAR,
++                                      /* bBitSel : Bit Width Setting        */
++                                      /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++                                      /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++                                      /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++                                      /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++                                      MCDRV_PCM_BITSEL_16
++                              },
++                              /* asSlot : Setting of a slot number of data to be fed to each channel */
++                              {0, 0}
++                      },
++                      /* sDit       */
++                      {
++                              /* wSrcRate : Sampling Rate Converter Setting */
++                              0,
++                              /* sDaFormat : Digital Audio Format Information */
++                              {
++                                      /* bBitSel : Bit Width Setting     */
++                                      /*     MCDRV_BITSEL_16(0)  : 16bit */
++                                      /*     MCDRV_BITSEL_20(1)  : 20bit */
++                                      /*     MCDRV_BITSEL_24(2)  : 24bit */
++                                      MCDRV_BITSEL_16,
++                                      /* bMode : Data Format Setting                             */
++                                      /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++                                      /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++                                      /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++                                      MCDRV_DAMODE_HEADALIGN
++                              },
++                              /* sPcmFormat : PCM Format Information */
++                              {
++                                      /* bMono : Mono / Stereo Setting  */
++                                      /*     MCDRV_PCM_STEREO(0) Stereo */
++                                      /*     MCDRV_PCM_MONO  (1) Mono   */
++                                      MCDRV_PCM_MONO ,
++                                      /* bOrder : Bit Order Setting                                     */
++                                      /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++                                      /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++                                      /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++                                      /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++                                      MCDRV_PCM_MSB_FIRST,
++                                      /* bLaw : Data Format Setting        */
++                                      /*     MCDRV_PCM_LINEAR(0)  : Linear */
++                                      /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++                                      /*     MCDRV_PCM_MULAW (2)  : u-Law */
++                                      MCDRV_PCM_LINEAR,
++                                      /* bBitSel : Bit Width Setting        */
++                                      /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++                                      /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++                                      /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++                                      /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++                                      MCDRV_PCM_BITSEL_16
++                              },
++                              /* asSlot Setting of a slot number of data to be transmitted from each channel */
++                              {0, 1}
++                      }
++              }
++      }
++};
++
++/* ========================================
++   DAC settings
++   ========================================*/
++static const MCDRV_DAC_INFO stDacInfo_Default = {
++      /* bMasterSwap : DAC Master Path SWAP Setting                          */
++      /*     MCDRV_DSWAP_OFF      (0)  : No SWAP                             */
++      /*     MCDRV_DSWAP_SWAP     (1)  : SWAP                                */
++      /*     MCDRV_DSWAP_MUTE     (2)  : MUTE                                */
++      /*     MCDRV_DSWAP_RMVCENTER(3)  : Center Removed                      */
++      /*     MCDRV_DSWAP_MONO     (4)  : Mono                                */
++      /*     MCDRV_DSWAP_MONOHALF (5)  : Reserved (do not use this setting)  */
++      /*     MCDRV_DSWAP_BOTHL    (6)  : Lch data output in both Lch and Rch */
++      /*     MCDRV_DSWAP_BOTHR    (7)  : Rch data output in both Lch and Rch */
++      MCDRV_DSWAP_OFF,
++      /* bVoiceSwap : DAC Voice Path SWAP Setting                            */
++      /*     MCDRV_DSWAP_OFF      (0)  : No SWAP                             */
++      /*     MCDRV_DSWAP_SWAP     (1)  : SWAP                                */
++      /*     MCDRV_DSWAP_MUTE     (2)  : MUTE                                */
++      /*     MCDRV_DSWAP_RMVCENTER(3)  : Center Removed                      */
++      /*     MCDRV_DSWAP_MONO     (4)  : Mono (-6dB)                         */
++      /*     MCDRV_DSWAP_MONOHALF (5)  : Reserved (do not use this setting)  */
++      /*     MCDRV_DSWAP_BOTHL    (6)  : Lch data output in both Lch and Rch */
++      /*     MCDRV_DSWAP_BOTHR    (7)  : Rch data output in both Lch and Rch */
++      MCDRV_DSWAP_OFF,
++      /* bDcCut : HP, SP Protection DC-ct Filter Setting  */
++      /*     MCDRV_DCCUT_ON (0)  : DC-cut Filter ON       */
++      /*     MCDRV_DCCUT_OFF(1)  : DC-cut Filter OFF      */
++      MCDRV_DCCUT_ON
++};
++
++/* ========================================
++   ADC settings
++   ========================================*/
++
++static const MCDRV_ADC_INFO stAdcInfo_Default = {
++      /* bAgcAdjust : AGC Gain Control Range     */
++      /*     MCDRV_AGCADJ_24(0)  : -3dB to +24dB */
++      /*     MCDRV_AGCADJ_18(1)  : -3dB to +18dB */
++      /*     MCDRV_AGCADJ_12(2)  : -3dB to +12dB */
++      /*     MCDRV_AGCADJ_0 (3)  : -3dB to  +0dB */
++      MCDRV_AGCADJ_0,
++      /* bAgcOn : AGC ON/OFF Setting */
++      /*     MCDRV_AGC_OFF(0)  : OFF */
++      /*     MCDRV_AGC_ON (1)  : ON  */
++      MCDRV_AGC_OFF,
++      /* bMonot : Mono / Stereo Setting    */
++      /*     MCDRV_ADC_STEREO(0)  : Stereo */
++      /*     MCDRV_ADC_MONO  (1)  : Mono   */
++      MCDRV_ADC_STEREO
++};
++
++/* ========================================
++   SP settings
++   ========================================*/
++static const MCDRV_SP_INFO stSpInfo_Default = {
++      /* bSwap : Swap setting                */
++      /*     MCDRV_SPSWAP_OFF (0)  : No SWAP */
++      /*     MCDRV_SPSWAP_SWAP(1)  : SWAP    */
++      MCDRV_SPSWAP_OFF
++};
++
++/* ========================================
++   DNG settings
++   ========================================*/
++static const MCDRV_DNG_INFO stDngInfo_Default = {
++      /* bOnOff[] : Digital Noise Gate On/Off Setting */
++      /*     MCDRV_DNG_OFF(0)  : OFF                */
++      /*     MCDRV_DNG_ON (1)  : ON                 */
++      {MCDRV_DNG_OFF, MCDRV_DNG_OFF, MCDRV_DNG_OFF},
++
++      /* bThreshold[] : Threshold Setting    */
++      /*     MCDRV_DNG_THRES_30    (0) */
++      /*     MCDRV_DNG_THRES_36    (1) */
++      /*     MCDRV_DNG_THRES_42    (2) */
++      /*     MCDRV_DNG_THRES_48    (3) */
++      /*     MCDRV_DNG_THRES_54    (4) */
++      /*     MCDRV_DNG_THRES_60    (5) */
++      /*     MCDRV_DNG_THRES_66    (6) */
++      /*     MCDRV_DNG_THRES_72    (7) */
++      /*     MCDRV_DNG_THRES_78    (8) */
++      /*     MCDRV_DNG_THRES_84    (9) */
++      {MCDRV_DNG_THRES_60, MCDRV_DNG_THRES_60, MCDRV_DNG_THRES_60},
++
++      /* bHold[] : Hold Time Setting         */
++      /*     MCDRV_DNG_HOLD_30 (0)  :  30ms */
++      /*     MCDRV_DNG_HOLD_120(1)  : 120ms */
++      /*     MCDRV_DNG_HOLD_500(2)  : 500ms */
++      {MCDRV_DNG_HOLD_500, MCDRV_DNG_HOLD_500, MCDRV_DNG_HOLD_500},
++
++      /* bAttack[] : Attack Time Setting        */
++      /*     MCDRV_DNG_ATTACK_25   (0)  :   25ms */
++      /*     MCDRV_DNG_ATTACK_100  (1)  :  100ms */
++      /*     MCDRV_DNG_ATTACK_400  (2)  :  400ms */
++      /*     MCDRV_DNG_ATTACK_800  (3)  :  800ms */
++      {MCDRV_DNG_ATTACK_100, MCDRV_DNG_ATTACK_100, MCDRV_DNG_ATTACK_100},
++
++      /* bRelease[] : Release Time Setting        */
++      /*     MCDRV_DNG_RELEASE_7950(0)  : 7.95ms */
++      /*     MCDRV_DNG_RELEASE_470 (1)  : 0.47ms */
++      /*     MCDRV_DNG_RELEASE_940 (2)  : 0.94ms */
++      {MCDRV_DNG_RELEASE_940, MCDRV_DNG_RELEASE_940, MCDRV_DNG_RELEASE_940},
++
++      /* bTarget[] : Target Volume Setting        */
++      /*     MCDRV_DNG_TARGET_6    (0)  : -6dB  */
++      /*     MCDRV_DNG_TARGET_9    (1)  : -9dB  */
++      /*     MCDRV_DNG_TARGET_12   (2)  : -12dB */
++      /*     MCDRV_DNG_TARGET_15   (3)  : -15dB */
++      /*     MCDRV_DNG_TARGET_18   (4)  : -18dB */
++      /*     MCDRV_DNG_TARGET_MUTE (5)  : Mute  */
++      {MCDRV_DNG_TARGET_MUTE, MCDRV_DNG_TARGET_MUTE, MCDRV_DNG_TARGET_MUTE},
++};
++#if 0
++static const MCDRV_DNG_INFO stDngInfo_Default = {
++      /* bOnOff : Digital Noise Gate On/Off Setting */
++      /*     MCDRV_DNG_OFF(0)  : OFF                */
++      /*     MCDRV_DNG_ON (1)  : ON                 */
++      MCDRV_DNG_OFF,
++
++      /* bThreshold : Threshold Setting    */
++      /*     MCDRV_DNG_THRES_5BIT  (0) */
++      /*     MCDRV_DNG_THRES_7BIT  (1) */
++      /*     MCDRV_DNG_THRES_9BIT  (2) */
++      /*     MCDRV_DNG_THRES_11BIT (3) */
++      /*     MCDRV_DNG_THRES_13BIT (4) */
++      /*     MCDRV_DNG_THRES_15BIT (5) */
++      /*     MCDRV_DNG_THRES_17BIT (6) */
++      /*     MCDRV_DNG_THRES_21BIT (7) */
++      MCDRV_DNG_THRES_11BIT,
++
++      /* bHold : Hold Time Setting         */
++      /*     MCDRV_DNG_HOLD_30 (0)  :  30ms */
++      /*     MCDRV_DNG_HOLD_120(1)  : 120ms */
++      /*     MCDRV_DNG_HOLD_500(2)  : 500ms */
++      MCDRV_DNG_HOLD_500,
++
++      /* bAttack : Attack Time Setting        */
++      /*     MCDRV_DNG_ATTACK_25   (0)  :   25ms */
++      /*     MCDRV_DNG_ATTACK_800  (1)  :  800ms */
++      /*     MCDRV_DNG_ATTACK_1100 (2)  : 1100ms */
++      MCDRV_DNG_ATTACK_1100,
++
++      /* bRelease : Release Time Setting        */
++      /*     MCDRV_DNG_RELEASE_7950(0)  : 7.95ms */
++      /*     MCDRV_DNG_RELEASE_470 (1)  : 0.47ms */
++      /*     MCDRV_DNG_RELEASE_940 (2)  : 0.94ms */
++      MCDRV_DNG_RELEASE_940,
++
++};
++#endif
++
++/* ========================================
++   AudioEngine settings
++   ========================================*/
++static MCDRV_AE_INFO sAeInfo_1 = {
++      /* On/Off */
++      0x00,
++      /* BEX */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* WIDE */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00
++      },
++      /* DRC */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* EQ5 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00
++      },
++      /* EQ3 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00
++      }
++};
++
++static MCDRV_AE_INFO sAeInfo_2 = {
++      /* On/Off */
++      0x00,
++      /* BEX */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* WIDE */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00
++      },
++      /* DRC */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* EQ5 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00
++      },
++      /* EQ3 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00
++      }
++};
++
++static MCDRV_AE_INFO sAeInfo_3 = {
++      /* On/Off */
++      0x00,
++      /* BEX */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* WIDE */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00
++      },
++      /* DRC */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* EQ5 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00
++      },
++      /* EQ3 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00
++      }
++};
++
++static MCDRV_AE_INFO sAeInfo_4 = {
++      /* On/Off */
++      0x00,
++      /* BEX */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* WIDE */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00
++      },
++      /* DRC */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* EQ5 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00
++      },
++      /* EQ3 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00
++      }
++};
++
++static MCDRV_AE_INFO sAeInfo_5 = {
++      /* On/Off */
++      0x00,
++      /* BEX */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* WIDE */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00
++      },
++      /* DRC */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* EQ5 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00
++      },
++      /* EQ3 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00
++      }
++};
++
++/* ========================================
++   System EQ settings
++   ========================================*/
++static MCDRV_SYSEQ_INFO stSyseqInfo_Default = {
++      /* On/Off */
++      0x00,
++      /* EQ */
++      {
++              0x10,0xc4,0x50,0x12,0xc4,0x40,0x02,0xa9,
++              0x60,0xed,0x3b,0xc0,0xfc,0x92,0x40,
++      },
++};
++
++#endif
+diff --git a/sound/soc/codecs/mc1n2/mc1n2_cfg_q1.h b/sound/soc/codecs/mc1n2/mc1n2_cfg_q1.h
+new file mode 100644
+index 0000000..c90e9b5
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mc1n2_cfg_q1.h
+@@ -0,0 +1,1199 @@
++/*
++ * MC-1N2 ASoC codec driver
++ *
++ * Copyright (c) 2010-2011 Yamaha Corporation
++ *
++ * This software is provided 'as-is', without any express or implied
++ * warranty.  In no event will the authors be held liable for any damages
++ * arising from the use of this software.
++ *
++ * Permission is granted to anyone to use this software for any purpose,
++ * including commercial applications, and to alter it and redistribute it
++ * freely, subject to the following restrictions:
++ *
++ * 1. The origin of this software must not be misrepresented; you must not
++ *    claim that you wrote the original software. If you use this software
++ *    in a product, an acknowledgment in the product documentation would be
++ *    appreciated but is not required.
++ * 2. Altered source versions must be plainly marked as such, and must not be
++ *    misrepresented as being the original software.
++ * 3. This notice may not be removed or altered from any source distribution.
++ */
++
++#ifndef MC1N2_CFG_H
++#define MC1N2_CFG_H
++
++#include "mcdriver.h"
++
++/*
++ * ALSA Version
++ */
++/* #define ALSA_VER_1_0_19 */
++/* #define ALSA_VER_1_0_21 */
++/* #define ALSA_VER_1_0_23 */
++/* #define ALSA_VER_ANDROID_2_6_35 */
++#define ALSA_VER_ANDROID_3_0
++
++#define DIO0_DAI_ENABLE
++/* #define DIO1_DAI_ENABLE */
++/* #define DIO2_DAI_ENABLE */
++
++#ifdef ALSA_VER_ANDROID_3_0
++static struct mc1n2_setup mc1n2_cfg_setup = {
++      {  /* MCDRV_INIT_INFO */
++              MCDRV_CKSEL_CMOS, /* bCkSel */
++              41,               /* bDivR0 */
++              126,              /* bDivF0 */
++              41,               /* bDivR1 */
++              126,              /* bDivF1 */
++              0,                /* bRange0*/
++              0,                /* bRange1*/
++              0,                /* bBypass*/
++              MCDRV_DAHIZ_LOW,  /* bDioSdo0Hiz */
++              MCDRV_DAHIZ_LOW,  /* bDioSdo1Hiz */
++              MCDRV_DAHIZ_LOW,  /* bDioSdo2Hiz */
++              MCDRV_DAHIZ_HIZ,  /* bDioClk0Hiz */
++              MCDRV_DAHIZ_HIZ,  /* bDioClk1Hiz */
++              MCDRV_DAHIZ_HIZ,  /* bDioClk2Hiz */
++              MCDRV_PCMHIZ_HIZ, /* bPcmHiz */
++              MCDRV_LINE_STEREO,/* bLineIn1Dif */
++              0,                /* bLineIn2Dif */
++              MCDRV_LINE_STEREO,/* bLineOut1Dif */
++              MCDRV_LINE_STEREO,/* bLineOUt2Dif */
++              MCDRV_SPMN_ON,    /* bSpmn */
++              MCDRV_MIC_DIF,    /* bMic1Sng */
++              MCDRV_MIC_DIF,    /* bMic2Sng */
++              MCDRV_MIC_DIF,    /* bMic3Sng */
++              MCDRV_POWMODE_NORMAL, /* bPowerMode */
++              MCDRV_SPHIZ_PULLDOWN, /* bSpHiz */
++              MCDRV_LDO_ON,     /* bLdo */
++              MCDRV_PAD_GPIO,   /* bPad0Func */
++              MCDRV_PAD_GPIO,   /* bPad1Func */
++              MCDRV_PAD_GPIO,   /* bPad2Func */
++              MCDRV_OUTLEV_4,   /* bAvddLev */
++              0,                /* bVrefLev */
++              MCDRV_DCLGAIN_12, /* bDclGain */
++              MCDRV_DCLLIMIT_0, /* bDclLimit */
++              1,                   /* set Hi-power mode 0: HP mode 1: normal */
++              0,                /* bReserved1 */
++              0,                /* bReserved2 */
++              0,                /* bReserved3 */
++              0,                /* bReserved4 */
++              0,                /* bReserved5 */
++              {                 /* sWaitTime */
++                      130000,         /* dAdHpf */
++                      25000,          /* dMic1Cin */
++                      25000,          /* dMic2Cin */
++                      25000,          /* dMic3Cin */
++                      25000,          /* dLine1Cin */
++                      25000,          /* dLine2Cin */
++                      5000,           /* dVrefRdy1 */
++                      15000,          /* dVrefRdy2 */
++                      9000,           /* dHpRdy */
++                      13000,          /* dSpRdy */
++                      0,              /* dPdm */
++                      1000,           /* dAnaRdyInterval */
++                      1000,           /* dSvolInterval */
++                      1000,           /* dAnaRdyTimeOut */
++                      1000            /* dSvolTimeOut */
++              }
++      }, /* MCDRV_INIT_INFO end */
++      {  /* pcm_extend */
++              0, 0, 0
++      }, /* pcm_extend end */
++      {  /* pcm_hiz_redge */
++              MCDRV_PCMHIZTIM_FALLING, MCDRV_PCMHIZTIM_FALLING, MCDRV_PCMHIZTIM_FALLING
++      }, /* pcm_hiz_redge end */
++      {  /* pcm_hperiod */
++              1, 1, 1
++      }, /* pcm_hperiod end */
++      {  /* slot */
++              { {0, 1}, {0, 1} },
++              { {0, 1}, {0, 1} },
++              { {0, 1}, {0, 1} }
++      }  /* slot end */
++};
++#endif
++
++static const MCDRV_DIO_INFO stDioInfo_Default = {
++      {
++              /* DIO port 0 */
++              {
++                      /* sDioCommon */
++                      {
++                              /* bMasterSlave : Master / Slave Setting */
++                              /*     MCDRV_DIO_SLAVE (0)  : Slave      */
++                              /*     MCDRV_DIO_MASTER(1)  : Master     */
++                              MCDRV_DIO_MASTER,
++                              /* bAutoFs : Sampling frequency automatic measurement ON/OFF Setting in slave mode */
++                              /*     MCDRV_AUTOFS_OFF(0)  : OFF */
++                              /*     MCDRV_AUTOFS_ON (1)  : ON  */
++                              MCDRV_AUTOFS_ON ,
++                              /* bFs : Sampling Rate Setting        */
++                              /*     MCDRV_FS_48000(0)  : 48kHz     */
++                              /*     MCDRV_FS_44100(1)  : 44.1kHz   */
++                              /*     MCDRV_FS_32000(2)  : 32kHz     */
++                              /*     MCDRV_FS_24000(4)  : 24kHz     */
++                              /*     MCDRV_FS_22050(5)  : 22.05kHz  */
++                              /*     MCDRV_FS_16000(6)  : 16kHz     */
++                              /*     MCDRV_FS_12000(8)  : 12kHz     */
++                              /*     MCDRV_FS_11025(9)  : 11.025kHz */
++                              /*     MCDRV_FS_8000 (10) : 8kHz      */
++                              MCDRV_FS_44100,
++                              /* bBckFs : Bit Clock Frequency Setting */
++                              /*     MCDRV_BCKFS_64 (0)  : LRCK x  64 */
++                              /*     MCDRV_BCKFS_48 (1)  : LRCK x  48 */
++                              /*     MCDRV_BCKFS_32 (2)  : LRCK x  32 */
++                              /*     MCDRV_BCKFS_512(4)  : LRCK x 512 */
++                              /*     MCDRV_BCKFS_256(5)  : LRCK x 256 */
++                              /*     MCDRV_BCKFS_128(6)  : LRCK x 128 */
++                              /*     MCDRV_BCKFS_16 (7)  : LRCK x  16 */
++                              MCDRV_BCKFS_32,
++                              /* bInterface : Interface Selection      */
++                              /*     MCDRV_DIO_DA (0)  : Digital Audio */
++                              /*     MCDRV_DIO_PCM(1)  : PCM           */
++                              MCDRV_DIO_DA,
++                              /* bBckInvert : Bit Clock Inversion Setting     */
++                              /*     MCDRV_BCLK_NORMAL(0)  : Normal Operation */
++                              /*     MCDRV_BCLK_INVERT(1)  : Clock Inverted   */
++                              MCDRV_BCLK_NORMAL,
++                              /* bPcmHizTim : High Impedance transition timing after transmitting the last PCM I/F data */
++                              /*     MCDRV_PCMHIZTIM_FALLING(0)  : BCLK#* Falling Edge */
++                              /*     MCDRV_PCMHIZTIM_RISING (1)  : BCLK#* Rising Edge  */
++                              MCDRV_PCMHIZTIM_FALLING,
++                              /* bPcmClkDown : Bit Clock Setting with PCM selected and Master selected                */
++                              /*     MCDRV_PCM_CLKDOWN_OFF (0)  : A bit clock value specified with bBckFs             */
++                              /*     MCDRV_PCM_CLKDOWN_HALF(1)  : A half of the bit clock value specified with bBckFs */
++                              MCDRV_PCM_CLKDOWN_OFF,
++                              /* bPcmFrame : Frame Mode Setting with PCM interface */
++                              /*     MCDRV_PCM_SHORTFRAME(0)  : Short Frame        */
++                              /*     MCDRV_PCM_LONGFRAME (1)  : Long Frame         */
++                              MCDRV_PCM_SHORTFRAME,
++                              /* bPcmHighPeriod : LR clock High time setting with PCM selected and Master selected */
++                              /*     0 to 31  : High level keeps during the period of time of         */
++                              /*                (setting value + 1) of the bit clock.                 */
++                              0,
++                      },
++                      /* sDir       */
++                      {
++                              /* wSrcRate : Sampling Rate Converter Setting */
++                              0,
++                              /* sDaFormat : Digital Audio Format Information */
++                              {
++                                      /* bBitSel : Bit Width Setting     */
++                                      /*     MCDRV_BITSEL_16(0)  : 16bit */
++                                      /*     MCDRV_BITSEL_20(1)  : 20bit */
++                                      /*     MCDRV_BITSEL_24(2)  : 24bit */
++                                      MCDRV_BITSEL_16,
++                                      /* bMode : Data Format Setting                             */
++                                      /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++                                      /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++                                      /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++                                      MCDRV_DAMODE_I2S
++                              },
++                              /* sPcmFormat : PCM Format Information */
++                              {
++                                      /* bMono : Mono / Stereo Setting  */
++                                      /*     MCDRV_PCM_STEREO(0) Stereo */
++                                      /*     MCDRV_PCM_MONO  (1) Mono   */
++                                      MCDRV_PCM_MONO ,
++                                      /* bOrder : Bit Order Setting                                     */
++                                      /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++                                      /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++                                      /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++                                      /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++                                      MCDRV_PCM_MSB_FIRST,
++                                      /* bLaw : Data Format Setting        */
++                                      /*     MCDRV_PCM_LINEAR(0)  : Linear */
++                                      /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++                                      /*     MCDRV_PCM_MULAW (2)  : u-Law */
++                                      MCDRV_PCM_LINEAR,
++                                      /* bBitSel : Bit Width Setting        */
++                                      /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++                                      /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++                                      /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++                                      /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++                                      MCDRV_PCM_BITSEL_8
++                              },
++                              /* asSlot : Setting of a slot number of data to be fed to each channel */
++                              {0, 1}
++                      },
++                      /* sDit       */
++                      {
++                              /* wSrcRate : Sampling Rate Converter Setting */
++                              0,
++                              /* sDaFormat : Digital Audio Format Information */
++                              {
++                                      /* bBitSel : Bit Width Setting     */
++                                      /*     MCDRV_BITSEL_16(0)  : 16bit */
++                                      /*     MCDRV_BITSEL_20(1)  : 20bit */
++                                      /*     MCDRV_BITSEL_24(2)  : 24bit */
++                                      MCDRV_BITSEL_16,
++                                      /* bMode : Data Format Setting                             */
++                                      /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++                                      /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++                                      /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++                                      MCDRV_DAMODE_I2S
++                              },
++                              /* sPcmFormat : PCM Format Information */
++                              {
++                                      /* bMono : Mono / Stereo Setting  */
++                                      /*     MCDRV_PCM_STEREO(0) Stereo */
++                                      /*     MCDRV_PCM_MONO  (1) Mono   */
++                                      MCDRV_PCM_MONO ,
++                                      /* bOrder : Bit Order Setting                                     */
++                                      /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++                                      /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++                                      /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++                                      /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++                                      MCDRV_PCM_MSB_FIRST,
++                                      /* bLaw : Data Format Setting        */
++                                      /*     MCDRV_PCM_LINEAR(0)  : Linear */
++                                      /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++                                      /*     MCDRV_PCM_MULAW (2)  : u-Law */
++                                      MCDRV_PCM_LINEAR,
++                                      /* bBitSel : Bit Width Setting        */
++                                      /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++                                      /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++                                      /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++                                      /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++                                      MCDRV_PCM_BITSEL_8
++                              },
++                              /* asSlot Setting of a slot number of data to be transmitted from each channel */
++                              {0, 1}
++                      }
++              },
++              /* DIO port 1 */
++              {
++                      /* sDioCommon */
++                      {
++                              /* bMasterSlave : Master / Slave Setting */
++                              /*     MCDRV_DIO_SLAVE (0)  : Slave      */
++                              /*     MCDRV_DIO_MASTER(1)  : Master     */
++                              MCDRV_DIO_SLAVE,
++                              /* bAutoFs : Sampling frequency automatic measurement ON/OFF Setting in slave mode */
++                              /*     MCDRV_AUTOFS_OFF(0)  : OFF */
++                              /*     MCDRV_AUTOFS_ON (1)  : ON  */
++                              MCDRV_AUTOFS_ON ,
++                              /* bFs : Sampling Rate Setting        */
++                              /*     MCDRV_FS_48000(0)  : 48kHz     */
++                              /*     MCDRV_FS_44100(1)  : 44.1kHz   */
++                              /*     MCDRV_FS_32000(2)  : 32kHz     */
++                              /*     MCDRV_FS_24000(4)  : 24kHz     */
++                              /*     MCDRV_FS_22050(5)  : 22.05kHz  */
++                              /*     MCDRV_FS_16000(6)  : 16kHz     */
++                              /*     MCDRV_FS_12000(8)  : 12kHz     */
++                              /*     MCDRV_FS_11025(9)  : 11.025kHz */
++                              /*     MCDRV_FS_8000 (10) : 8kHz      */
++                              MCDRV_FS_8000,
++                              /* bBckFs : Bit Clock Frequency Setting */
++                              /*     MCDRV_BCKFS_64 (0)  : LRCK x  64 */
++                              /*     MCDRV_BCKFS_48 (1)  : LRCK x  48 */
++                              /*     MCDRV_BCKFS_32 (2)  : LRCK x  32 */
++                              /*     MCDRV_BCKFS_512(4)  : LRCK x 512 */
++                              /*     MCDRV_BCKFS_256(5)  : LRCK x 256 */
++                              /*     MCDRV_BCKFS_128(6)  : LRCK x 128 */
++                              /*     MCDRV_BCKFS_16 (7)  : LRCK x  16 */
++                              MCDRV_BCKFS_32,
++                              /* bInterface : Interface Selection      */
++                              /*     MCDRV_DIO_DA (0)  : Digital Audio */
++                              /*     MCDRV_DIO_PCM(1)  : PCM           */
++                              MCDRV_DIO_DA,
++                              /* bBckInvert : Bit Clock Inversion Setting     */
++                              /*     MCDRV_BCLK_NORMAL(0)  : Normal Operation */
++                              /*     MCDRV_BCLK_INVERT(1)  : Clock Inverted   */
++                              MCDRV_BCLK_NORMAL,
++                              /* bPcmHizTim : High Impedance transition timing after transmitting the last PCM I/F data */
++                              /*     MCDRV_PCMHIZTIM_FALLING(0)  : BCLK#* Falling Edge */
++                              /*     MCDRV_PCMHIZTIM_RISING (1)  : BCLK#* Rising Edge  */
++                              MCDRV_PCMHIZTIM_FALLING,
++                              /* bPcmClkDown : Bit Clock Setting with PCM selected and Master selected                */
++                              /*     MCDRV_PCM_CLKDOWN_OFF (0)  : A bit clock value specified with bBckFs             */
++                              /*     MCDRV_PCM_CLKDOWN_HALF(1)  : A half of the bit clock value specified with bBckFs */
++                              MCDRV_PCM_CLKDOWN_OFF,
++                              /* bPcmFrame : Frame Mode Setting with PCM interface */
++                              /*     MCDRV_PCM_SHORTFRAME(0)  : Short Frame        */
++                              /*     MCDRV_PCM_LONGFRAME (1)  : Long Frame         */
++                              MCDRV_PCM_SHORTFRAME,
++                              /* bPcmHighPeriod : LR clock High time setting with PCM selected and Master selected */
++                              /*     0 to 31  : High level keeps during the period of time of         */
++                              /*                (setting value + 1) of the bit clock.                 */
++                              0,
++                      },
++                      /* sDir       */
++                      {
++                              /* wSrcRate : Sampling Rate Converter Setting */
++                              0,
++                              /* sDaFormat : Digital Audio Format Information */
++                              {
++                                      /* bBitSel : Bit Width Setting     */
++                                      /*     MCDRV_BITSEL_16(0)  : 16bit */
++                                      /*     MCDRV_BITSEL_20(1)  : 20bit */
++                                      /*     MCDRV_BITSEL_24(2)  : 24bit */
++                                      MCDRV_BITSEL_16,
++                                      /* bMode : Data Format Setting                             */
++                                      /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++                                      /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++                                      /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++                                      MCDRV_DAMODE_I2S
++                              },
++                              /* sPcmFormat : PCM Format Information */
++                              {
++                                      /* bMono : Mono / Stereo Setting  */
++                                      /*     MCDRV_PCM_STEREO(0) Stereo */
++                                      /*     MCDRV_PCM_MONO  (1) Mono   */
++                                      MCDRV_PCM_STEREO ,
++                                      /* bOrder : Bit Order Setting                                     */
++                                      /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++                                      /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++                                      /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++                                      /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++                                      MCDRV_PCM_MSB_FIRST,
++                                      /* bLaw : Data Format Setting        */
++                                      /*     MCDRV_PCM_LINEAR(0)  : Linear */
++                                      /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++                                      /*     MCDRV_PCM_MULAW (2)  : u-Law */
++                                      MCDRV_PCM_LINEAR,
++                                      /* bBitSel : Bit Width Setting        */
++                                      /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++                                      /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++                                      /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++                                      /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++                                      MCDRV_PCM_BITSEL_16
++                              },
++                              /* asSlot : Setting of a slot number of data to be fed to each channel */
++                              {0, 0}
++                      },
++                      /* sDit       */
++                      {
++                              /* wSrcRate : Sampling Rate Converter Setting */
++                              0,
++                              /* sDaFormat : Digital Audio Format Information */
++                              {
++                                      /* bBitSel : Bit Width Setting     */
++                                      /*     MCDRV_BITSEL_16(0)  : 16bit */
++                                      /*     MCDRV_BITSEL_20(1)  : 20bit */
++                                      /*     MCDRV_BITSEL_24(2)  : 24bit */
++                                      MCDRV_BITSEL_16,
++                                      /* bMode : Data Format Setting                             */
++                                      /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++                                      /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++                                      /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++                                      MCDRV_DAMODE_I2S
++                              },
++                              /* sPcmFormat : PCM Format Information */
++                              {
++                                      /* bMono : Mono / Stereo Setting  */
++                                      /*     MCDRV_PCM_STEREO(0) Stereo */
++                                      /*     MCDRV_PCM_MONO  (1) Mono   */
++                                      MCDRV_PCM_STEREO ,
++                                      /* bOrder : Bit Order Setting                                     */
++                                      /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++                                      /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++                                      /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++                                      /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++                                      MCDRV_PCM_MSB_FIRST,
++                                      /* bLaw : Data Format Setting        */
++                                      /*     MCDRV_PCM_LINEAR(0)  : Linear */
++                                      /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++                                      /*     MCDRV_PCM_MULAW (2)  : u-Law */
++                                      MCDRV_PCM_LINEAR,
++                                      /* bBitSel : Bit Width Setting        */
++                                      /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++                                      /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++                                      /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++                                      /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++                                      MCDRV_PCM_BITSEL_16
++                              },
++                              /* asSlot Setting of a slot number of data to be transmitted from each channel */
++                              {0, 1}
++                      }
++              },
++              /* DIO port 2 */
++              {
++                      /* sDioCommon */
++                      {
++                              /* bMasterSlave : Master / Slave Setting */
++                              /*     MCDRV_DIO_SLAVE (0)  : Slave      */
++                              /*     MCDRV_DIO_MASTER(1)  : Master     */
++                              MCDRV_DIO_MASTER,
++                              /* bAutoFs : Sampling frequency automatic measurement ON/OFF Setting in slave mode */
++                              /*     MCDRV_AUTOFS_OFF(0)  : OFF */
++                              /*     MCDRV_AUTOFS_ON (1)  : ON  */
++                              MCDRV_AUTOFS_ON ,
++                              /* bFs : Sampling Rate Setting        */
++                              /*     MCDRV_FS_48000(0)  : 48kHz     */
++                              /*     MCDRV_FS_44100(1)  : 44.1kHz   */
++                              /*     MCDRV_FS_32000(2)  : 32kHz     */
++                              /*     MCDRV_FS_24000(4)  : 24kHz     */
++                              /*     MCDRV_FS_22050(5)  : 22.05kHz  */
++                              /*     MCDRV_FS_16000(6)  : 16kHz     */
++                              /*     MCDRV_FS_12000(8)  : 12kHz     */
++                              /*     MCDRV_FS_11025(9)  : 11.025kHz */
++                              /*     MCDRV_FS_8000 (10) : 8kHz      */
++                              MCDRV_FS_8000,
++                              /* bBckFs : Bit Clock Frequency Setting */
++                              /*     MCDRV_BCKFS_64 (0)  : LRCK x  64 */
++                              /*     MCDRV_BCKFS_48 (1)  : LRCK x  48 */
++                              /*     MCDRV_BCKFS_32 (2)  : LRCK x  32 */
++                              /*     MCDRV_BCKFS_512(4)  : LRCK x 512 */
++                              /*     MCDRV_BCKFS_256(5)  : LRCK x 256 */
++                              /*     MCDRV_BCKFS_128(6)  : LRCK x 128 */
++                              /*     MCDRV_BCKFS_16 (7)  : LRCK x  16 */
++                              MCDRV_BCKFS_32,
++                              /* bInterface : Interface Selection      */
++                              /*     MCDRV_DIO_DA (0)  : Digital Audio */
++                              /*     MCDRV_DIO_PCM(1)  : PCM           */
++                              MCDRV_DIO_PCM,
++                              /* bBckInvert : Bit Clock Inversion Setting     */
++                              /*     MCDRV_BCLK_NORMAL(0)  : Normal Operation */
++                              /*     MCDRV_BCLK_INVERT(1)  : Clock Inverted   */
++                              MCDRV_BCLK_NORMAL,
++                              /* bPcmHizTim : High Impedance transition timing after transmitting the last PCM I/F data */
++                              /*     MCDRV_PCMHIZTIM_FALLING(0)  : BCLK#* Falling Edge */
++                              /*     MCDRV_PCMHIZTIM_RISING (1)  : BCLK#* Rising Edge  */
++                              MCDRV_PCMHIZTIM_FALLING,
++                              /* bPcmClkDown : Bit Clock Setting with PCM selected and Master selected                */
++                              /*     MCDRV_PCM_CLKDOWN_OFF (0)  : A bit clock value specified with bBckFs             */
++                              /*     MCDRV_PCM_CLKDOWN_HALF(1)  : A half of the bit clock value specified with bBckFs */
++                              MCDRV_PCM_CLKDOWN_OFF,
++                              /* bPcmFrame : Frame Mode Setting with PCM interface */
++                              /*     MCDRV_PCM_SHORTFRAME(0)  : Short Frame        */
++                              /*     MCDRV_PCM_LONGFRAME (1)  : Long Frame         */
++                              MCDRV_PCM_SHORTFRAME,
++                              /* bPcmHighPeriod : LR clock High time setting with PCM selected and Master selected */
++                              /*     0 to 31  : High level keeps during the period of time of         */
++                              /*                (setting value + 1) of the bit clock.                 */
++                              0,
++                      },
++                      /* sDir       */
++                      {
++                              /* wSrcRate : Sampling Rate Converter Setting */
++                              0,
++                              /* sDaFormat : Digital Audio Format Information */
++                              {
++                                      /* bBitSel : Bit Width Setting     */
++                                      /*     MCDRV_BITSEL_16(0)  : 16bit */
++                                      /*     MCDRV_BITSEL_20(1)  : 20bit */
++                                      /*     MCDRV_BITSEL_24(2)  : 24bit */
++                                      MCDRV_BITSEL_16,
++                                      /* bMode : Data Format Setting                             */
++                                      /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++                                      /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++                                      /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++                                      MCDRV_DAMODE_HEADALIGN
++                              },
++                              /* sPcmFormat : PCM Format Information */
++                              {
++                                      /* bMono : Mono / Stereo Setting  */
++                                      /*     MCDRV_PCM_STEREO(0) Stereo */
++                                      /*     MCDRV_PCM_MONO  (1) Mono   */
++                                      MCDRV_PCM_STEREO ,
++                                      /* bOrder : Bit Order Setting                                     */
++                                      /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++                                      /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++                                      /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++                                      /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++                                      MCDRV_PCM_MSB_FIRST,
++                                      /* bLaw : Data Format Setting        */
++                                      /*     MCDRV_PCM_LINEAR(0)  : Linear */
++                                      /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++                                      /*     MCDRV_PCM_MULAW (2)  : u-Law */
++                                      MCDRV_PCM_LINEAR,
++                                      /* bBitSel : Bit Width Setting        */
++                                      /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++                                      /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++                                      /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++                                      /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++                                      MCDRV_PCM_BITSEL_16
++                              },
++                              /* asSlot : Setting of a slot number of data to be fed to each channel */
++                              {0, 0}
++                      },
++                      /* sDit       */
++                      {
++                              /* wSrcRate : Sampling Rate Converter Setting */
++                              0,
++                              /* sDaFormat : Digital Audio Format Information */
++                              {
++                                      /* bBitSel : Bit Width Setting     */
++                                      /*     MCDRV_BITSEL_16(0)  : 16bit */
++                                      /*     MCDRV_BITSEL_20(1)  : 20bit */
++                                      /*     MCDRV_BITSEL_24(2)  : 24bit */
++                                      MCDRV_BITSEL_16,
++                                      /* bMode : Data Format Setting                             */
++                                      /*     MCDRV_DAMODE_HEADALIGN(0)  : Left-justified Format  */
++                                      /*     MCDRV_DAMODE_I2S      (1)  : I2S                    */
++                                      /*     MCDRV_DAMODE_TAILALIGN(2)  : Right-justified Format */
++                                      MCDRV_DAMODE_HEADALIGN
++                              },
++                              /* sPcmFormat : PCM Format Information */
++                              {
++                                      /* bMono : Mono / Stereo Setting  */
++                                      /*     MCDRV_PCM_STEREO(0) Stereo */
++                                      /*     MCDRV_PCM_MONO  (1) Mono   */
++                                      MCDRV_PCM_MONO ,
++                                      /* bOrder : Bit Order Setting                                     */
++                                      /*     MCDRV_PCM_MSB_FIRST      (0)  : MSB First                  */
++                                      /*     MCDRV_PCM_LSB_FIRST      (1)  : LSB First                  */
++                                      /*     MCDRV_PCM_MSB_FIRST_SIGN (2)  : MSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_LSB_FIRST_SIGN (3)  : LSB First (Sign Extension) */
++                                      /*     MCDRV_PCM_MSB_FIRST_ZERO (4)  : MSB First (Zeros Padding)  */
++                                      /*     MCDRV_PCM_LSB_FIRST_ZERO (5)  : LSB First (Zeros Padding)  */
++                                      MCDRV_PCM_MSB_FIRST,
++                                      /* bLaw : Data Format Setting        */
++                                      /*     MCDRV_PCM_LINEAR(0)  : Linear */
++                                      /*     MCDRV_PCM_ALAW  (1)  : A-Law  */
++                                      /*     MCDRV_PCM_MULAW (2)  : u-Law */
++                                      MCDRV_PCM_LINEAR,
++                                      /* bBitSel : Bit Width Setting        */
++                                      /*     MCDRV_PCM_BITSEL_8 (0)  8 bits */
++                                      /*     MCDRV_PCM_BITSEL_13(1) 13 bits */
++                                      /*     MCDRV_PCM_BITSEL_14(2) 14 bits */
++                                      /*     MCDRV_PCM_BITSEL_16(3) 16 bits */
++                                      MCDRV_PCM_BITSEL_16
++                              },
++                              /* asSlot Setting of a slot number of data to be transmitted from each channel */
++                              {0, 1}
++                      }
++              }
++      }
++};
++
++/* ========================================
++   DAC settings
++   ========================================*/
++static const MCDRV_DAC_INFO stDacInfo_Default = {
++      /* bMasterSwap : DAC Master Path SWAP Setting                          */
++      /*     MCDRV_DSWAP_OFF      (0)  : No SWAP                             */
++      /*     MCDRV_DSWAP_SWAP     (1)  : SWAP                                */
++      /*     MCDRV_DSWAP_MUTE     (2)  : MUTE                                */
++      /*     MCDRV_DSWAP_RMVCENTER(3)  : Center Removed                      */
++      /*     MCDRV_DSWAP_MONO     (4)  : Mono                                */
++      /*     MCDRV_DSWAP_MONOHALF (5)  : Reserved (do not use this setting)  */
++      /*     MCDRV_DSWAP_BOTHL    (6)  : Lch data output in both Lch and Rch */
++      /*     MCDRV_DSWAP_BOTHR    (7)  : Rch data output in both Lch and Rch */
++      MCDRV_DSWAP_OFF,
++      /* bVoiceSwap : DAC Voice Path SWAP Setting                            */
++      /*     MCDRV_DSWAP_OFF      (0)  : No SWAP                             */
++      /*     MCDRV_DSWAP_SWAP     (1)  : SWAP                                */
++      /*     MCDRV_DSWAP_MUTE     (2)  : MUTE                                */
++      /*     MCDRV_DSWAP_RMVCENTER(3)  : Center Removed                      */
++      /*     MCDRV_DSWAP_MONO     (4)  : Mono (-6dB)                         */
++      /*     MCDRV_DSWAP_MONOHALF (5)  : Reserved (do not use this setting)  */
++      /*     MCDRV_DSWAP_BOTHL    (6)  : Lch data output in both Lch and Rch */
++      /*     MCDRV_DSWAP_BOTHR    (7)  : Rch data output in both Lch and Rch */
++      MCDRV_DSWAP_OFF,
++      /* bDcCut : HP, SP Protection DC-ct Filter Setting  */
++      /*     MCDRV_DCCUT_ON (0)  : DC-cut Filter ON       */
++      /*     MCDRV_DCCUT_OFF(1)  : DC-cut Filter OFF      */
++      MCDRV_DCCUT_ON
++};
++
++/* ========================================
++   ADC settings
++   ========================================*/
++
++static const MCDRV_ADC_INFO stAdcInfo_Default = {
++      /* bAgcAdjust : AGC Gain Control Range     */
++      /*     MCDRV_AGCADJ_24(0)  : -3dB to +24dB */
++      /*     MCDRV_AGCADJ_18(1)  : -3dB to +18dB */
++      /*     MCDRV_AGCADJ_12(2)  : -3dB to +12dB */
++      /*     MCDRV_AGCADJ_0 (3)  : -3dB to  +0dB */
++      MCDRV_AGCADJ_0,
++      /* bAgcOn : AGC ON/OFF Setting */
++      /*     MCDRV_AGC_OFF(0)  : OFF */
++      /*     MCDRV_AGC_ON (1)  : ON  */
++      MCDRV_AGC_OFF,
++      /* bMonot : Mono / Stereo Setting    */
++      /*     MCDRV_ADC_STEREO(0)  : Stereo */
++      /*     MCDRV_ADC_MONO  (1)  : Mono   */
++      MCDRV_ADC_STEREO
++};
++
++/* ========================================
++   SP settings
++   ========================================*/
++static const MCDRV_SP_INFO stSpInfo_Default = {
++      /* bSwap : Swap setting                */
++      /*     MCDRV_SPSWAP_OFF (0)  : No SWAP */
++      /*     MCDRV_SPSWAP_SWAP(1)  : SWAP    */
++      MCDRV_SPSWAP_OFF
++};
++
++/* ========================================
++   DNG settings
++   ========================================*/
++static const MCDRV_DNG_INFO stDngInfo_Default = {
++      /* bOnOff[] : Digital Noise Gate On/Off Setting */
++      /*     MCDRV_DNG_OFF(0)  : OFF                */
++      /*     MCDRV_DNG_ON (1)  : ON                 */
++      {MCDRV_DNG_OFF, MCDRV_DNG_OFF, MCDRV_DNG_OFF},
++
++      /* bThreshold[] : Threshold Setting    */
++      /*     MCDRV_DNG_THRES_30    (0) */
++      /*     MCDRV_DNG_THRES_36    (1) */
++      /*     MCDRV_DNG_THRES_42    (2) */
++      /*     MCDRV_DNG_THRES_48    (3) */
++      /*     MCDRV_DNG_THRES_54    (4) */
++      /*     MCDRV_DNG_THRES_60    (5) */
++      /*     MCDRV_DNG_THRES_66    (6) */
++      /*     MCDRV_DNG_THRES_72    (7) */
++      /*     MCDRV_DNG_THRES_78    (8) */
++      /*     MCDRV_DNG_THRES_84    (9) */
++      {MCDRV_DNG_THRES_60, MCDRV_DNG_THRES_60, MCDRV_DNG_THRES_60},
++
++      /* bHold[] : Hold Time Setting         */
++      /*     MCDRV_DNG_HOLD_30 (0)  :  30ms */
++      /*     MCDRV_DNG_HOLD_120(1)  : 120ms */
++      /*     MCDRV_DNG_HOLD_500(2)  : 500ms */
++      {MCDRV_DNG_HOLD_500, MCDRV_DNG_HOLD_500, MCDRV_DNG_HOLD_500},
++
++      /* bAttack[] : Attack Time Setting        */
++      /*     MCDRV_DNG_ATTACK_25   (0)  :   25ms */
++      /*     MCDRV_DNG_ATTACK_100  (1)  :  100ms */
++      /*     MCDRV_DNG_ATTACK_400  (2)  :  400ms */
++      /*     MCDRV_DNG_ATTACK_800  (3)  :  800ms */
++      {MCDRV_DNG_ATTACK_100, MCDRV_DNG_ATTACK_100, MCDRV_DNG_ATTACK_100},
++
++      /* bRelease[] : Release Time Setting        */
++      /*     MCDRV_DNG_RELEASE_7950(0)  : 7.95ms */
++      /*     MCDRV_DNG_RELEASE_470 (1)  : 0.47ms */
++      /*     MCDRV_DNG_RELEASE_940 (2)  : 0.94ms */
++      {MCDRV_DNG_RELEASE_940, MCDRV_DNG_RELEASE_940, MCDRV_DNG_RELEASE_940},
++
++      /* bTarget[] : Target Volume Setting        */
++      /*     MCDRV_DNG_TARGET_6    (0)  : -6dB  */
++      /*     MCDRV_DNG_TARGET_9    (1)  : -9dB  */
++      /*     MCDRV_DNG_TARGET_12   (2)  : -12dB */
++      /*     MCDRV_DNG_TARGET_15   (3)  : -15dB */
++      /*     MCDRV_DNG_TARGET_18   (4)  : -18dB */
++      /*     MCDRV_DNG_TARGET_MUTE (5)  : Mute  */
++      {MCDRV_DNG_TARGET_MUTE, MCDRV_DNG_TARGET_MUTE, MCDRV_DNG_TARGET_MUTE},
++};
++#if 0
++static const MCDRV_DNG_INFO stDngInfo_Default = {
++      /* bOnOff : Digital Noise Gate On/Off Setting */
++      /*     MCDRV_DNG_OFF(0)  : OFF                */
++      /*     MCDRV_DNG_ON (1)  : ON                 */
++      MCDRV_DNG_OFF,
++
++      /* bThreshold : Threshold Setting    */
++      /*     MCDRV_DNG_THRES_5BIT  (0) */
++      /*     MCDRV_DNG_THRES_7BIT  (1) */
++      /*     MCDRV_DNG_THRES_9BIT  (2) */
++      /*     MCDRV_DNG_THRES_11BIT (3) */
++      /*     MCDRV_DNG_THRES_13BIT (4) */
++      /*     MCDRV_DNG_THRES_15BIT (5) */
++      /*     MCDRV_DNG_THRES_17BIT (6) */
++      /*     MCDRV_DNG_THRES_21BIT (7) */
++      MCDRV_DNG_THRES_11BIT,
++
++      /* bHold : Hold Time Setting         */
++      /*     MCDRV_DNG_HOLD_30 (0)  :  30ms */
++      /*     MCDRV_DNG_HOLD_120(1)  : 120ms */
++      /*     MCDRV_DNG_HOLD_500(2)  : 500ms */
++      MCDRV_DNG_HOLD_500,
++
++      /* bAttack : Attack Time Setting        */
++      /*     MCDRV_DNG_ATTACK_25   (0)  :   25ms */
++      /*     MCDRV_DNG_ATTACK_800  (1)  :  800ms */
++      /*     MCDRV_DNG_ATTACK_1100 (2)  : 1100ms */
++      MCDRV_DNG_ATTACK_1100,
++
++      /* bRelease : Release Time Setting        */
++      /*     MCDRV_DNG_RELEASE_7950(0)  : 7.95ms */
++      /*     MCDRV_DNG_RELEASE_470 (1)  : 0.47ms */
++      /*     MCDRV_DNG_RELEASE_940 (2)  : 0.94ms */
++      MCDRV_DNG_RELEASE_940,
++
++};
++#endif
++
++/* ========================================
++   AudioEngine settings
++   ========================================*/
++static MCDRV_AE_INFO sAeInfo_1 = {
++      /* On/Off */
++      0x00,
++      /* BEX */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* WIDE */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00
++      },
++      /* DRC */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* EQ5 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00
++      },
++      /* EQ3 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00
++      }
++};
++
++static MCDRV_AE_INFO sAeInfo_2 = {
++      /* On/Off */
++      0x00,
++      /* BEX */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* WIDE */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00
++      },
++      /* DRC */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* EQ5 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00
++      },
++      /* EQ3 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00
++      }
++};
++
++static MCDRV_AE_INFO sAeInfo_3 = {
++      /* On/Off */
++      0x00,
++      /* BEX */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* WIDE */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00
++      },
++      /* DRC */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* EQ5 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00
++      },
++      /* EQ3 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00
++      }
++};
++
++static MCDRV_AE_INFO sAeInfo_4 = {
++      /* On/Off */
++      0x00,
++      /* BEX */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* WIDE */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00
++      },
++      /* DRC */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* EQ5 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00
++      },
++      /* EQ3 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00
++      }
++};
++
++static MCDRV_AE_INFO sAeInfo_5 = {
++      /* On/Off */
++      0x00,
++      /* BEX */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* WIDE */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00
++      },
++      /* DRC */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++      },
++      /* EQ5 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00
++      },
++      /* EQ3 */
++      {
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              0x00,0x00,0x00
++      }
++};
++
++/* ========================================
++   System EQ settings
++   ========================================*/
++static MCDRV_SYSEQ_INFO stSyseqInfo_Default = {
++      /* On/Off */
++      0x00,
++      /* EQ */
++      {
++              0x10,0xc4,0x50,0x12,0xc4,0x40,0x02,0xa9,
++              0x60,0xed,0x3b,0xc0,0xfc,0x92,0x40,
++      },
++};
++
++#endif
+diff --git a/sound/soc/codecs/mc1n2/mc1n2_dbg.c b/sound/soc/codecs/mc1n2/mc1n2_dbg.c
+new file mode 100644
+index 0000000..d454969
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mc1n2_dbg.c
+@@ -0,0 +1,439 @@
++#include <sound/soc.h>
++#include "mc1n2_priv.h"
++
++#ifdef CONFIG_SND_SOC_MC1N2_DEBUG
++
++static void mc1n2_dump_reg_info(const void *pvPrm, UINT32 dPrm)
++{
++      MCDRV_REG_INFO *info = (MCDRV_REG_INFO *)pvPrm;
++
++      dbg_info("bRegType = 0x%02x\n", info->bRegType);
++      dbg_info("bAddress = 0x%02x\n", info->bAddress);
++}
++
++static void mc1n2_dump_array(const char *name,
++                           const unsigned char *data, size_t len)
++{
++      char str[2048], *p;
++      int n = (len <= 256) ? len : 256;
++      int i;
++
++      p = str;
++      for (i = 0; i < n; i++) {
++              p += sprintf(p, "0x%02x ", data[i]);
++      }
++
++      dbg_info("%s[] = {%s}\n", name, str);
++}
++
++#define DEF_PATH(p) {offsetof(MCDRV_PATH_INFO, p), #p}
++
++static void mc1n2_dump_path_info(const void *pvPrm, UINT32 dPrm)
++{
++      MCDRV_PATH_INFO *info = (MCDRV_PATH_INFO *)pvPrm;
++      int i;
++
++      struct path_table {
++              size_t offset;
++              char *name;
++      };
++
++      struct path_table table[] = {
++              DEF_PATH(asHpOut[0]), DEF_PATH(asHpOut[1]),
++              DEF_PATH(asSpOut[0]), DEF_PATH(asSpOut[1]),
++              DEF_PATH(asRcOut[0]),
++              DEF_PATH(asLout1[0]), DEF_PATH(asLout1[1]),
++              DEF_PATH(asLout2[0]), DEF_PATH(asLout2[1]),
++              DEF_PATH(asPeak[0]),
++              DEF_PATH(asDit0[0]),
++              DEF_PATH(asDit1[0]),
++              DEF_PATH(asDit2[0]),
++              DEF_PATH(asDac[0]), DEF_PATH(asDac[1]),
++              DEF_PATH(asAe[0]),
++              DEF_PATH(asCdsp[0]), DEF_PATH(asCdsp[1]),
++              DEF_PATH(asCdsp[2]), DEF_PATH(asCdsp[3]),
++              DEF_PATH(asAdc0[0]), DEF_PATH(asAdc0[1]),
++              DEF_PATH(asAdc1[0]),
++              DEF_PATH(asMix[0]),
++              DEF_PATH(asBias[0]),
++      };
++
++#define N_PATH_TABLE (sizeof(table) / sizeof(struct path_table))
++
++      for (i = 0; i < N_PATH_TABLE; i++) {
++              MCDRV_CHANNEL *ch = (MCDRV_CHANNEL *)((void *)info + table[i].offset);
++              int j;
++              for (j = 0; j < SOURCE_BLOCK_NUM; j++) {
++                      if (ch->abSrcOnOff[j] != 0) {
++                              dbg_info("%s.abSrcOnOff[%d] = 0x%02x\n",
++                                       table[i].name, j, ch->abSrcOnOff[j]);
++                      }
++              }
++      }
++}
++
++#define DEF_VOL(v) {offsetof(MCDRV_VOL_INFO, v), #v}
++
++static void mc1n2_dump_vol_info(const void *pvPrm, UINT32 dPrm)
++{
++      MCDRV_VOL_INFO *info = (MCDRV_VOL_INFO *)pvPrm;
++      int i;
++
++      struct vol_table {
++              size_t offset;
++              char *name;
++      };
++
++      struct vol_table table[] = {
++              DEF_VOL(aswD_Ad0[0]), DEF_VOL(aswD_Ad0[1]),
++              DEF_VOL(aswD_Ad1[0]),
++              DEF_VOL(aswD_Aeng6[0]), DEF_VOL(aswD_Aeng6[1]),
++              DEF_VOL(aswD_Pdm[0]), DEF_VOL(aswD_Pdm[1]),
++              DEF_VOL(aswD_Dtmfb[0]), DEF_VOL(aswD_Dtmfb[1]),
++              DEF_VOL(aswD_Dir0[0]), DEF_VOL(aswD_Dir0[1]),
++              DEF_VOL(aswD_Dir1[0]), DEF_VOL(aswD_Dir1[1]),
++              DEF_VOL(aswD_Dir2[0]), DEF_VOL(aswD_Dir2[1]),
++              DEF_VOL(aswD_Ad0Att[0]), DEF_VOL(aswD_Ad0Att[1]),
++              DEF_VOL(aswD_Ad1Att[0]),
++              DEF_VOL(aswD_Dir0Att[0]), DEF_VOL(aswD_Dir0Att[1]),
++              DEF_VOL(aswD_Dir1Att[0]), DEF_VOL(aswD_Dir1Att[1]),
++              DEF_VOL(aswD_Dir2Att[0]), DEF_VOL(aswD_Dir2Att[1]),
++              DEF_VOL(aswD_SideTone[0]), DEF_VOL(aswD_SideTone[1]),
++              DEF_VOL(aswD_DtmfAtt[0]), DEF_VOL(aswD_DtmfAtt[1]),
++              DEF_VOL(aswD_DacMaster[0]), DEF_VOL(aswD_DacMaster[1]),
++              DEF_VOL(aswD_DacVoice[0]), DEF_VOL(aswD_DacVoice[1]),
++              DEF_VOL(aswD_DacAtt[0]), DEF_VOL(aswD_DacAtt[1]),
++              DEF_VOL(aswD_Dit0[0]), DEF_VOL(aswD_Dit0[1]),
++              DEF_VOL(aswD_Dit1[0]), DEF_VOL(aswD_Dit1[1]),
++              DEF_VOL(aswD_Dit2[0]), DEF_VOL(aswD_Dit2[1]),
++              DEF_VOL(aswA_Ad0[0]), DEF_VOL(aswA_Ad0[1]),
++              DEF_VOL(aswA_Ad1[0]),
++              DEF_VOL(aswA_Lin1[0]), DEF_VOL(aswA_Lin1[1]),
++              DEF_VOL(aswA_Lin2[0]), DEF_VOL(aswA_Lin2[1]),
++              DEF_VOL(aswA_Mic1[0]),
++              DEF_VOL(aswA_Mic2[0]),
++              DEF_VOL(aswA_Mic3[0]),
++              DEF_VOL(aswA_Hp[0]), DEF_VOL(aswA_Hp[1]),
++              DEF_VOL(aswA_Sp[0]), DEF_VOL(aswA_Sp[1]),
++              DEF_VOL(aswA_Rc[0]),
++              DEF_VOL(aswA_Lout1[0]), DEF_VOL(aswA_Lout1[1]),
++              DEF_VOL(aswA_Lout2[0]), DEF_VOL(aswA_Lout2[1]),
++              DEF_VOL(aswA_Mic1Gain[0]),
++              DEF_VOL(aswA_Mic2Gain[0]),
++              DEF_VOL(aswA_Mic3Gain[0]),
++              DEF_VOL(aswA_HpGain[0]),
++      };
++
++#define N_VOL_TABLE (sizeof(table) / sizeof(struct vol_table))
++
++      for (i = 0; i < N_VOL_TABLE; i++) {
++              SINT16 vol = *(SINT16 *)((void *)info + table[i].offset);
++              if (vol & 0x0001) {
++                      dbg_info("%s = 0x%04x\n", table[i].name, (vol & 0xfffe));
++              }
++      }
++}
++
++static void mc1n2_dump_dio_info(const void *pvPrm, UINT32 dPrm)
++{
++      MCDRV_DIO_INFO *info = (MCDRV_DIO_INFO *)pvPrm;
++      MCDRV_DIO_PORT *port;
++      UINT32 update;
++      int i;
++
++      for (i = 0; i < IOPORT_NUM; i++) {
++              dbg_info("asPortInfo[%d]:\n", i);
++              port = &info->asPortInfo[i];
++              update = dPrm >> (i*3);
++              if (update & MCDRV_DIO0_COM_UPDATE_FLAG) {
++                      dbg_info("sDioCommon.bMasterSlave = 0x%02x\n",
++                               port->sDioCommon.bMasterSlave);
++                      dbg_info("           bAutoFs = 0x%02x\n",
++                               port->sDioCommon.bAutoFs);
++                      dbg_info("           bFs = 0x%02x\n",
++                               port->sDioCommon.bFs);
++                      dbg_info("           bBckFs = 0x%02x\n",
++                               port->sDioCommon.bBckFs);
++                      dbg_info("           bInterface = 0x%02x\n",
++                               port->sDioCommon.bInterface);
++                      dbg_info("           bBckInvert = 0x%02x\n",
++                               port->sDioCommon.bBckInvert);
++                      dbg_info("           bPcmHizTim = 0x%02x\n",
++                               port->sDioCommon.bPcmHizTim);
++                      dbg_info("           bPcmClkDown = 0x%02x\n",
++                               port->sDioCommon.bPcmClkDown);
++                      dbg_info("           bPcmFrame = 0x%02x\n",
++                               port->sDioCommon.bPcmFrame);
++                      dbg_info("           bPcmHighPeriod = 0x%02x\n",
++                               port->sDioCommon.bPcmHighPeriod);
++              }
++              if (update & MCDRV_DIO0_DIR_UPDATE_FLAG) {
++                      dbg_info("sDir.wSrcRate = 0x%04x\n",
++                               port->sDir.wSrcRate);
++                      dbg_info("     sDaFormat.bBitSel = 0x%02x\n",
++                               port->sDir.sDaFormat.bBitSel);
++                      dbg_info("               bMode = 0x%02x\n",
++                               port->sDir.sDaFormat.bMode);
++                      dbg_info("     sPcmFormat.bMono = 0x%02x\n",
++                               port->sDir.sPcmFormat.bMono);
++                      dbg_info("                bOrder = 0x%02x\n",
++                               port->sDir.sPcmFormat.bOrder);
++                      dbg_info("                bLaw = 0x%02x\n",
++                               port->sDir.sPcmFormat.bLaw);
++                      dbg_info("                bBitSel = 0x%02x\n",
++                               port->sDir.sPcmFormat.bBitSel);
++                      dbg_info("     abSlot[] = {0x%02x, 0x%02x}\n",
++                               port->sDir.abSlot[0], port->sDir.abSlot[1]);
++              }
++              if (update & MCDRV_DIO0_DIT_UPDATE_FLAG) {
++                      dbg_info("sDit.wSrcRate = 0x%04x\n",
++                               port->sDit.wSrcRate);
++                      dbg_info("     sDaFormat.bBitSel = 0x%02x\n",
++                               port->sDit.sDaFormat.bBitSel);
++                      dbg_info("               bMode = 0x%02x\n",
++                               port->sDit.sDaFormat.bMode);
++                      dbg_info("     sPcmFormat.bMono = 0x%02x\n",
++                               port->sDit.sPcmFormat.bMono);
++                      dbg_info("                bOrder = 0x%02x\n",
++                               port->sDit.sPcmFormat.bOrder);
++                      dbg_info("                bLaw = 0x%02x\n",
++                               port->sDit.sPcmFormat.bLaw);
++                      dbg_info("                bBitSel = 0x%02x\n",
++                               port->sDit.sPcmFormat.bBitSel);
++                      dbg_info("     abSlot[] = {0x%02x, 0x%02x}\n",
++                               port->sDit.abSlot[0], port->sDit.abSlot[1]);
++              }
++      }
++}
++
++static void mc1n2_dump_dac_info(const void *pvPrm, UINT32 dPrm)
++{
++      MCDRV_DAC_INFO *info = (MCDRV_DAC_INFO *)pvPrm;
++
++      if (dPrm & MCDRV_DAC_MSWP_UPDATE_FLAG) {
++              dbg_info("bMasterSwap = 0x%02x\n", info->bMasterSwap);
++      }
++      if (dPrm & MCDRV_DAC_VSWP_UPDATE_FLAG) {
++              dbg_info("bVoiceSwap = 0x%02x\n", info->bVoiceSwap);
++      }
++      if (dPrm & MCDRV_DAC_HPF_UPDATE_FLAG) {
++              dbg_info("bDcCut = 0x%02x\n", info->bDcCut);
++      }
++}
++
++static void mc1n2_dump_adc_info(const void *pvPrm, UINT32 dPrm)
++{
++      MCDRV_ADC_INFO *info = (MCDRV_ADC_INFO *)pvPrm;
++
++      if (dPrm & MCDRV_ADCADJ_UPDATE_FLAG) {
++              dbg_info("bAgcAdjust = 0x%02x\n", info->bAgcAdjust);
++      }
++      if (dPrm & MCDRV_ADCAGC_UPDATE_FLAG) {
++              dbg_info("bAgcOn = 0x%02x\n", info->bAgcOn);
++      }
++      if (dPrm & MCDRV_ADCMONO_UPDATE_FLAG) {
++              dbg_info("bMono = 0x%02x\n", info->bMono);
++      }
++}
++
++static void mc1n2_dump_sp_info(const void *pvPrm, UINT32 dPrm)
++{
++      MCDRV_SP_INFO *info = (MCDRV_SP_INFO *)pvPrm;
++
++      dbg_info("bSwap = 0x%02x\n", info->bSwap);
++}
++
++static void mc1n2_dump_dng_info(const void *pvPrm, UINT32 dPrm)
++{
++      MCDRV_DNG_INFO *info = (MCDRV_DNG_INFO *)pvPrm;
++
++      if (dPrm & MCDRV_DNGSW_HP_UPDATE_FLAG) {
++              dbg_info("HP:abOnOff = 0x%02x\n", info->abOnOff[0]);
++      }
++      if (dPrm & MCDRV_DNGTHRES_HP_UPDATE_FLAG) {
++              dbg_info("HP:abThreshold = 0x%02x\n", info->abThreshold[0]);
++      }
++      if (dPrm & MCDRV_DNGHOLD_HP_UPDATE_FLAG) {
++              dbg_info("HP:abHold = 0x%02x\n", info->abHold[0]);
++      }
++      if (dPrm & MCDRV_DNGATK_HP_UPDATE_FLAG) {
++              dbg_info("HP:abAttack = 0x%02x\n", info->abAttack[0]);
++      }
++      if (dPrm & MCDRV_DNGREL_HP_UPDATE_FLAG) {
++              dbg_info("HP:abRelease = 0x%02x\n", info->abRelease[0]);
++      }
++      if (dPrm & MCDRV_DNGTARGET_HP_UPDATE_FLAG) {
++              dbg_info("HP:abTarget = 0x%02x\n", info->abTarget[0]);
++      }
++
++      if (dPrm & MCDRV_DNGSW_SP_UPDATE_FLAG) {
++              dbg_info("SP:abOnOff = 0x%02x\n", info->abOnOff[1]);
++      }
++      if (dPrm & MCDRV_DNGTHRES_SP_UPDATE_FLAG) {
++              dbg_info("SP:abThreshold = 0x%02x\n", info->abThreshold[1]);
++      }
++      if (dPrm & MCDRV_DNGHOLD_SP_UPDATE_FLAG) {
++              dbg_info("SP:abHold = 0x%02x\n", info->abHold[1]);
++      }
++      if (dPrm & MCDRV_DNGATK_SP_UPDATE_FLAG) {
++              dbg_info("SP:abAttack = 0x%02x\n", info->abAttack[1]);
++      }
++      if (dPrm & MCDRV_DNGREL_SP_UPDATE_FLAG) {
++              dbg_info("SP:abRelease = 0x%02x\n", info->abRelease[1]);
++      }
++      if (dPrm & MCDRV_DNGTARGET_SP_UPDATE_FLAG) {
++              dbg_info("SP:abTarget = 0x%02x\n", info->abTarget[1]);
++      }
++
++      if (dPrm & MCDRV_DNGSW_RC_UPDATE_FLAG) {
++              dbg_info("RC:abOnOff = 0x%02x\n", info->abOnOff[2]);
++      }
++      if (dPrm & MCDRV_DNGTHRES_RC_UPDATE_FLAG) {
++              dbg_info("RC:abThreshold = 0x%02x\n", info->abThreshold[2]);
++      }
++      if (dPrm & MCDRV_DNGHOLD_RC_UPDATE_FLAG) {
++              dbg_info("RC:abHold = 0x%02x\n", info->abHold[2]);
++      }
++      if (dPrm & MCDRV_DNGATK_RC_UPDATE_FLAG) {
++              dbg_info("RC:abAttack = 0x%02x\n", info->abAttack[2]);
++      }
++      if (dPrm & MCDRV_DNGREL_RC_UPDATE_FLAG) {
++              dbg_info("RC:abRelease = 0x%02x\n", info->abRelease[2]);
++      }
++      if (dPrm & MCDRV_DNGTARGET_RC_UPDATE_FLAG) {
++              dbg_info("RC:abTarget = 0x%02x\n", info->abTarget[2]);
++      }
++}
++
++static void mc1n2_dump_ae_info(const void *pvPrm, UINT32 dPrm)
++{
++      MCDRV_AE_INFO *info = (MCDRV_AE_INFO *)pvPrm;
++
++      dbg_info("bOnOff = 0x%02x\n", info->bOnOff);
++      if (dPrm & MCDRV_AEUPDATE_FLAG_BEX) {
++              mc1n2_dump_array("abBex", info->abBex, BEX_PARAM_SIZE);
++      }
++      if (dPrm & MCDRV_AEUPDATE_FLAG_WIDE) {
++              mc1n2_dump_array("abWide", info->abWide, WIDE_PARAM_SIZE);
++      }
++      if (dPrm & MCDRV_AEUPDATE_FLAG_DRC) {
++              mc1n2_dump_array("abDrc", info->abDrc, DRC_PARAM_SIZE);
++      }
++      if (dPrm & MCDRV_AEUPDATE_FLAG_EQ5) {
++              mc1n2_dump_array("abEq5", info->abEq5, EQ5_PARAM_SIZE);
++      }
++      if (dPrm & MCDRV_AEUPDATE_FLAG_EQ3) {
++              mc1n2_dump_array("abEq3", info->abEq3, EQ5_PARAM_SIZE);
++      }
++}
++
++static void mc1n2_dump_pdm_info(const void *pvPrm, UINT32 dPrm)
++{
++      MCDRV_PDM_INFO *info = (MCDRV_PDM_INFO *)pvPrm;
++
++      if (dPrm & MCDRV_PDMCLK_UPDATE_FLAG) {
++              dbg_info("bClk = 0x%02x\n", info->bClk);
++      }
++      if (dPrm & MCDRV_PDMADJ_UPDATE_FLAG) {
++              dbg_info("bAgcAdjust = 0x%02x\n", info->bAgcAdjust);
++      }
++      if (dPrm & MCDRV_PDMAGC_UPDATE_FLAG) {
++              dbg_info("bAgcOn = 0x%02x\n", info->bAgcOn);
++      }
++      if (dPrm & MCDRV_PDMEDGE_UPDATE_FLAG) {
++              dbg_info("bPdmEdge = 0x%02x\n", info->bPdmEdge);
++      }
++      if (dPrm & MCDRV_PDMWAIT_UPDATE_FLAG) {
++              dbg_info("bPdmWait = 0x%02x\n", info->bPdmWait);
++      }
++      if (dPrm & MCDRV_PDMSEL_UPDATE_FLAG) {
++              dbg_info("bPdmSel = 0x%02x\n", info->bPdmSel);
++      }
++      if (dPrm & MCDRV_PDMMONO_UPDATE_FLAG) {
++              dbg_info("bMono = 0x%02x\n", info->bMono);
++      }
++}
++
++static void mc1n2_dump_clksw_info(const void *pvPrm, UINT32 dPrm)
++{
++      MCDRV_CLKSW_INFO *info = (MCDRV_CLKSW_INFO *)pvPrm;
++
++      dbg_info("bClkSrc = 0x%02x\n", info->bClkSrc);
++}
++
++static void mc1n2_dump_syseq_info(const void *pvPrm, UINT32 dPrm)
++{
++      MCDRV_SYSEQ_INFO *info = (MCDRV_SYSEQ_INFO *)pvPrm;
++      int i;
++
++      if (dPrm & MCDRV_SYSEQ_ONOFF_UPDATE_FLAG) {
++              dbg_info("bOnOff = 0x%02x\n", info->bOnOff);
++      }
++      if (dPrm & MCDRV_SYSEQ_PARAM_UPDATE_FLAG) {
++              for (i = 0; i < 15; i++){
++                      dbg_info("abParam[%d] = 0x%02x\n", i, info->abParam[i]);
++              }
++      }
++}
++
++struct mc1n2_dump_func {
++      char *name;
++      void (*func)(const void *, UINT32);
++};
++
++struct mc1n2_dump_func mc1n2_dump_func_map[] = {
++      {"MCDRV_INIT", NULL},
++      {"MCDRV_TERM", NULL},
++      {"MCDRV_READ_REG", mc1n2_dump_reg_info},
++      {"MCDRV_WRITE_REG", NULL},
++      {"MCDRV_GET_PATH", NULL},
++      {"MCDRV_SET_PATH", mc1n2_dump_path_info},
++      {"MCDRV_GET_VOLUME", NULL},
++      {"MCDRV_SET_VOLUME", mc1n2_dump_vol_info},
++      {"MCDRV_GET_DIGITALIO", NULL},
++      {"MCDRV_SET_DIGITALIO", mc1n2_dump_dio_info},
++      {"MCDRV_GET_DAC", NULL},
++      {"MCDRV_SET_DAC", mc1n2_dump_dac_info},
++      {"MCDRV_GET_ADC", NULL},
++      {"MCDRV_SET_ADC", mc1n2_dump_adc_info},
++      {"MCDRV_GET_SP", NULL},
++      {"MCDRV_SET_SP", mc1n2_dump_sp_info},
++      {"MCDRV_GET_DNG", NULL},
++      {"MCDRV_SET_DNG", mc1n2_dump_dng_info},
++      {"MCDRV_SET_AUDIOENGINE", mc1n2_dump_ae_info},
++      {"MCDRV_SET_AUDIOENGINE_EX", NULL},
++      {"MCDRV_SET_CDSP", NULL},
++      {"MCDRV_GET_CDSP_PARAM", NULL},
++      {"MCDRV_SET_CDSP_PARAM", NULL},
++      {"MCDRV_REGISTER_CDSP_CB", NULL},
++      {"MCDRV_GET_PDM", NULL},
++      {"MCDRV_SET_PDM", mc1n2_dump_pdm_info},
++      {"MCDRV_SET_DTMF", NULL},
++      {"MCDRV_CONFIG_GP", NULL},
++      {"MCDRV_MASK_GP", NULL},
++      {"MCDRV_GETSET_GP", NULL},
++      {"MCDRV_GET_PEAK", NULL},
++      {"MCDRV_IRQ", NULL},
++      {"MCDRV_UPDATE_CLOCK", NULL},
++      {"MCDRV_SWITCH_CLOCK", mc1n2_dump_clksw_info},
++      {"MCDRV_GET_SYSEQ", NULL},
++      {"MCDRV_SET_SYSEQ", mc1n2_dump_syseq_info},
++};
++
++SINT32 McDrv_Ctrl_dbg(UINT32 dCmd, void *pvPrm, UINT32 dPrm)
++{
++      SINT32 err;
++
++      dbg_info("calling %s:\n", mc1n2_dump_func_map[dCmd].name);
++
++      if (mc1n2_dump_func_map[dCmd].func) {
++              mc1n2_dump_func_map[dCmd].func(pvPrm, dPrm);
++      }
++
++      err = McDrv_Ctrl(dCmd, pvPrm, dPrm);
++      dbg_info("err = %ld\n", err);
++
++      return err;
++}
++
++#endif /* CONFIG_SND_SOC_MC1N2_DEBUG */
+diff --git a/sound/soc/codecs/mc1n2/mc1n2_priv.h b/sound/soc/codecs/mc1n2/mc1n2_priv.h
+new file mode 100644
+index 0000000..47dee1a
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mc1n2_priv.h
+@@ -0,0 +1,196 @@
++/*
++ * MC-1N2 ASoC codec driver - private header
++ *
++ * Copyright (c) 2010 Yamaha Corporation
++ *
++ * This software is provided 'as-is', without any express or implied
++ * warranty.  In no event will the authors be held liable for any damages
++ * arising from the use of this software.
++ *
++ * Permission is granted to anyone to use this software for any purpose,
++ * including commercial applications, and to alter it and redistribute it
++ * freely, subject to the following restrictions:
++ *
++ * 1. The origin of this software must not be misrepresented; you must not
++ *    claim that you wrote the original software. If you use this software
++ *    in a product, an acknowledgment in the product documentation would be
++ *    appreciated but is not required.
++ * 2. Altered source versions must be plainly marked as such, and must not be
++ *    misrepresented as being the original software.
++ * 3. This notice may not be removed or altered from any source distribution.
++ */
++
++#ifndef MC1N2_PRIV_H
++#define MC1N2_PRIV_H
++
++#include "mcdriver.h"
++
++/*
++ * Virtual registers
++ */
++enum {
++      MC1N2_DVOL_AD0,
++      MC1N2_DVOL_AENG6,
++      MC1N2_DVOL_PDM,
++      MC1N2_DVOL_DIR0,
++      MC1N2_DVOL_DIR1,
++      MC1N2_DVOL_DIR2,
++      MC1N2_DVOL_AD0_ATT,
++      MC1N2_DVOL_DIR0_ATT,
++      MC1N2_DVOL_DIR1_ATT,
++      MC1N2_DVOL_DIR2_ATT,
++      MC1N2_DVOL_SIDETONE,
++      MC1N2_DVOL_DAC_MASTER,
++      MC1N2_DVOL_DAC_VOICE,
++      MC1N2_DVOL_DAC_ATT,
++      MC1N2_DVOL_DIT0,
++      MC1N2_DVOL_DIT1,
++      MC1N2_DVOL_DIT2,
++      MC1N2_AVOL_AD0,
++      MC1N2_AVOL_LIN1,
++      MC1N2_AVOL_MIC1,
++      MC1N2_AVOL_MIC2,
++      MC1N2_AVOL_MIC3,
++      MC1N2_AVOL_HP,
++      MC1N2_AVOL_SP,
++      MC1N2_AVOL_RC,
++      MC1N2_AVOL_LOUT1,
++      MC1N2_AVOL_LOUT2,
++      MC1N2_AVOL_MIC1_GAIN,
++      MC1N2_AVOL_MIC2_GAIN,
++      MC1N2_AVOL_MIC3_GAIN,
++      MC1N2_AVOL_HP_GAIN,
++
++      MC1N2_ADCL_MIC1_SW,
++      MC1N2_ADCL_MIC2_SW,
++      MC1N2_ADCL_MIC3_SW,
++      MC1N2_ADCL_LINE_SW,
++      MC1N2_ADCR_MIC1_SW,
++      MC1N2_ADCR_MIC2_SW,
++      MC1N2_ADCR_MIC3_SW,
++      MC1N2_ADCR_LINE_SW,
++
++      MC1N2_HPL_MIC1_SW,
++      MC1N2_HPL_MIC2_SW,
++      MC1N2_HPL_MIC3_SW,
++      MC1N2_HPL_LINE_SW,
++      MC1N2_HPL_DAC_SW,
++
++      MC1N2_HPR_MIC1_SW,
++      MC1N2_HPR_MIC2_SW,
++      MC1N2_HPR_MIC3_SW,
++      MC1N2_HPR_LINER_SW,
++      MC1N2_HPR_DACR_SW,
++
++      MC1N2_SPL_LINE_SW,
++      MC1N2_SPL_DAC_SW,
++      MC1N2_SPR_LINE_SW,
++      MC1N2_SPR_DAC_SW,
++
++      MC1N2_RC_MIC1_SW,
++      MC1N2_RC_MIC2_SW,
++      MC1N2_RC_MIC3_SW,
++      MC1N2_RC_LINEMONO_SW,
++      MC1N2_RC_DACL_SW,
++      MC1N2_RC_DACR_SW,
++
++      MC1N2_LOUT1L_MIC1_SW,
++      MC1N2_LOUT1L_MIC2_SW,
++      MC1N2_LOUT1L_MIC3_SW,
++      MC1N2_LOUT1L_LINE_SW,
++      MC1N2_LOUT1L_DAC_SW,
++
++      MC1N2_LOUT1R_MIC1_SW,
++      MC1N2_LOUT1R_MIC2_SW,
++      MC1N2_LOUT1R_MIC3_SW,
++      MC1N2_LOUT1R_LINER_SW,
++      MC1N2_LOUT1R_DACR_SW,
++
++      MC1N2_LOUT2L_MIC1_SW,
++      MC1N2_LOUT2L_MIC2_SW,
++      MC1N2_LOUT2L_MIC3_SW,
++      MC1N2_LOUT2L_LINE_SW,
++      MC1N2_LOUT2L_DAC_SW,
++
++      MC1N2_LOUT2R_MIC1_SW,
++      MC1N2_LOUT2R_MIC2_SW,
++      MC1N2_LOUT2R_MIC3_SW,
++      MC1N2_LOUT2R_LINER_SW,
++      MC1N2_LOUT2R_DACR_SW,
++
++      MC1N2_DMIX_ADC_SW,
++      MC1N2_DMIX_DIR0_SW,
++      MC1N2_DMIX_DIR1_SW,
++      MC1N2_DMIX_DIR2_SW,
++
++      MC1N2_DACMAIN_SRC,
++      MC1N2_DACVOICE_SRC,
++      MC1N2_DIT0_SRC,
++      MC1N2_DIT1_SRC,
++      MC1N2_DIT2_SRC,
++      MC1N2_AE_SRC,
++
++      MC1N2_ADCL_LINE_SRC,
++      MC1N2_ADCR_LINE_SRC,
++      MC1N2_HPL_LINE_SRC,
++      MC1N2_HPL_DAC_SRC,
++      MC1N2_SPL_LINE_SRC,
++      MC1N2_SPL_DAC_SRC,
++      MC1N2_SPR_LINE_SRC,
++      MC1N2_SPR_DAC_SRC,
++      MC1N2_LOUT1L_LINE_SRC,
++      MC1N2_LOUT1L_DAC_SRC,
++      MC1N2_LOUT2L_LINE_SRC,
++      MC1N2_LOUT2L_DAC_SRC,
++
++      MC1N2_AE_PARAM_SEL,
++      MC1N2_ADC_PDM_SEL,
++
++      MC1N2_MICBIAS1,
++      MC1N2_MICBIAS2,
++      MC1N2_MICBIAS3,
++
++      MC1N2_N_REG
++};
++
++#define MC1N2_N_VOL_REG MC1N2_ADCL_MIC1_SW     
++
++#define MC1N2_DSOURCE_OFF             0
++#define MC1N2_DSOURCE_ADC             1
++#define MC1N2_DSOURCE_DIR0            2
++#define MC1N2_DSOURCE_DIR1            3
++#define MC1N2_DSOURCE_DIR2            4
++#define MC1N2_DSOURCE_MIX             5
++
++#define MC1N2_AE_PARAM_1              0
++#define MC1N2_AE_PARAM_2              1
++#define MC1N2_AE_PARAM_3              2
++#define MC1N2_AE_PARAM_4              3
++#define MC1N2_AE_PARAM_5              4
++
++#define mc1n2_i2c_read_byte(c,r) i2c_smbus_read_byte_data((c), (r)<<1)
++
++extern struct i2c_client *mc1n2_get_i2c_client(void);
++
++/*
++ * For debugging
++ */
++#ifdef CONFIG_SND_SOC_MC1N2_DEBUG
++
++#define dbg_info(format, arg...) snd_printd(KERN_INFO format, ## arg)
++#define TRACE_FUNC() snd_printd(KERN_INFO "<trace> %s()\n", __FUNCTION__)
++
++
++#define _McDrv_Ctrl McDrv_Ctrl_dbg
++extern SINT32 McDrv_Ctrl_dbg(UINT32 dCmd, void *pvPrm, UINT32 dPrm);
++
++#else
++
++#define dbg_info(format, arg...)
++#define TRACE_FUNC()
++
++#define _McDrv_Ctrl McDrv_Ctrl
++
++#endif /* CONFIG_SND_SOC_MC1N2_DEBUG */
++
++#endif /* MC1N2_PRIV_H */
+diff --git a/sound/soc/codecs/mc1n2/mcdebuglog.c b/sound/soc/codecs/mc1n2/mcdebuglog.c
+new file mode 100644
+index 0000000..5f1e61c0
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mcdebuglog.c
+@@ -0,0 +1,1771 @@
++/****************************************************************************
++ *
++ *            Copyright(c) 2010 Yamaha Corporation. All rights reserved.
++ *
++ *            Module          : mcdebuglog.c
++ *
++ *            Description     : MC Driver debug log
++ *
++ *            Version         : 1.0.0         2010.09.10
++ *
++ ****************************************************************************/
++
++
++#include "mcdebuglog.h"
++#include "mcresctrl.h"
++
++#if MCDRV_DEBUG_LEVEL
++
++#include "mcdefs.h"
++#include "mcdevprof.h"
++#include "mcservice.h"
++#include "mcmachdep.h"
++
++
++
++typedef char  CHAR;
++
++static CHAR   gsbLogString[8192];
++static CHAR   gsbLFCode[]     = "\n";
++
++static const CHAR     gsbCmdName[][20]        =
++{
++      "init",
++      "term",
++      "read_reg",
++      "write_reg",
++      "get_path",
++      "set_path",
++      "get_volume",
++      "set_volume",
++      "get_digitalio",
++      "set_digitalio",
++      "get_dac",
++      "set_dac",
++      "get_adc",
++      "set_adc",
++      "get_sp",
++      "set_sp",
++      "get_dng",
++      "set_dng",
++      "set_ae",
++      "set_aeex",
++      "set_cdsp",
++      "get_cdspparam",
++      "set_cdspparam",
++      "reg_cdsp_cb",
++      "get_pdm",
++      "set_pdm",
++      "set_dtmf",
++      "config_gp",
++      "mask_gp",
++      "getset_gp",
++      "get_peak",
++      "irq",
++      "update_clock",
++      "switch_clock",
++      "get_syseq",
++      "set_syseq"
++};
++
++
++static void   OutputRegDump(void);
++static void   GetRegDump_B(CHAR* psbLogString, UINT8 bSlaveAddr, UINT8 bADRAddr, UINT8 bWINDOWAddr, UINT8 bRegType);
++
++static void   MakeInitInfoLog(const MCDRV_INIT_INFO* pParam);
++static void   MakeRegInfoLog(const MCDRV_REG_INFO* pParam);
++static void   MakeClockInfoLog(const MCDRV_CLOCK_INFO* pParam);
++static void   MakeClockSwInfoLog(const MCDRV_CLKSW_INFO* pParam);
++static void   MakePathInfoLog(const MCDRV_PATH_INFO* pParam);
++static void   MakeVolInfoLog(const MCDRV_VOL_INFO* pParam);
++static void   MakeDIOInfoLog(const MCDRV_DIO_INFO* pParam);
++static void   MakeDACInfoLog(const MCDRV_DAC_INFO* pParam);
++static void   MakeADCInfoLog(const MCDRV_ADC_INFO* pParam);
++static void   MakeSpInfoLog(const MCDRV_SP_INFO* pParam);
++static void   MakeDNGInfoLog(const MCDRV_DNG_INFO* pParam);
++static void   MakeAEInfoLog(const MCDRV_AE_INFO* pParam);
++static void   MakeAEExInfoLog(const UINT16* pParam);
++static void   MakeSetCDSPLog(const UINT16* pParam);
++static void   MakeCDSPParamLog(const MCDRV_CDSPPARAM* pParam);
++static void   MakeCDSPCBLog(const void* pParam);
++static void   MakePDMInfoLog(const MCDRV_PDM_INFO* pParam);
++static void   MakeDTMFInfoLog(const MCDRV_DTMF_INFO* pParam);
++static void   MakeGPModeLog(const MCDRV_GP_MODE* pParam);
++static void   MakeGPMaskLog(const UINT8* pParam);
++static void   MakeGetSetGPLog(const UINT8* pParam);
++static void   MakePeakLog(const MCDRV_PEAK* pParam);
++static void   MakeSysEQInfoLog(const MCDRV_SYSEQ_INFO* pParam);
++
++/****************************************************************************
++ *    McDebugLog_CmdIn
++ *
++ *    Description:
++ *                    Output Function entrance log.
++ *    Arguments:
++ *                    dCmd            Command ID
++ *                    pvParam         pointer to parameter
++ *                    dUpdateInfo     Update info
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McDebugLog_CmdIn
++(
++      UINT32          dCmd,
++      const void*     pvParam,
++      UINT32          dUpdateInfo
++)
++{
++      CHAR    sbStr[80];
++      UINT8   bLevel  = MCDRV_DEBUG_LEVEL;
++
++      if(dCmd >= sizeof(gsbCmdName)/sizeof(gsbCmdName[0]))
++      {
++              return;
++      }
++
++      strcpy(gsbLogString, gsbCmdName[dCmd]);
++      strcat(gsbLogString, " In");
++
++      if(bLevel < 2)
++      {
++              strcat(gsbLogString, gsbLFCode);
++              machdep_DebugPrint((UINT8*)(void*)gsbLogString);
++              return;
++      }
++
++      switch(dCmd)
++      {
++      case    MCDRV_INIT:
++              MakeInitInfoLog((MCDRV_INIT_INFO*)pvParam);
++              break;
++      case    MCDRV_READ_REG:
++      case    MCDRV_WRITE_REG:
++              MakeRegInfoLog((MCDRV_REG_INFO*)pvParam);
++              break;
++      case    MCDRV_UPDATE_CLOCK:
++              MakeClockInfoLog((MCDRV_CLOCK_INFO*)pvParam);
++              break;
++      case    MCDRV_SWITCH_CLOCK:
++              MakeClockSwInfoLog((MCDRV_CLKSW_INFO*)pvParam);
++              break;
++      case    MCDRV_SET_PATH:
++              MakePathInfoLog((MCDRV_PATH_INFO*)pvParam);
++              break;
++      case    MCDRV_SET_VOLUME:
++              MakeVolInfoLog((MCDRV_VOL_INFO*)pvParam);
++              break;
++      case    MCDRV_SET_DIGITALIO:
++              MakeDIOInfoLog((MCDRV_DIO_INFO*)pvParam);
++              sprintf(sbStr, " dPrm=%08lX", dUpdateInfo);
++              strcat(gsbLogString, sbStr);
++              break;
++      case    MCDRV_SET_DAC:
++              MakeDACInfoLog((MCDRV_DAC_INFO*)pvParam);
++              sprintf(sbStr, " dPrm=%08lX", dUpdateInfo);
++              strcat(gsbLogString, sbStr);
++              break;
++      case    MCDRV_SET_ADC:
++              MakeADCInfoLog((MCDRV_ADC_INFO*)pvParam);
++              sprintf(sbStr, " dPrm=%08lX", dUpdateInfo);
++              strcat(gsbLogString, sbStr);
++              break;
++      case    MCDRV_SET_SP:
++              MakeSpInfoLog((MCDRV_SP_INFO*)pvParam);
++              break;
++      case    MCDRV_SET_DNG:
++              MakeDNGInfoLog((MCDRV_DNG_INFO*)pvParam);
++              sprintf(sbStr, " dPrm=%08lX", dUpdateInfo);
++              strcat(gsbLogString, sbStr);
++              break;
++      case    MCDRV_SET_AUDIOENGINE:
++              MakeAEInfoLog((MCDRV_AE_INFO*)pvParam);
++              sprintf(sbStr, " dPrm=%08lX", dUpdateInfo);
++              strcat(gsbLogString, sbStr);
++              break;
++      case    MCDRV_SET_AUDIOENGINE_EX:
++              MakeAEExInfoLog((UINT16*)pvParam);
++              sprintf(sbStr, " dPrm=%08lX", dUpdateInfo);
++              strcat(gsbLogString, sbStr);
++              break;
++      case    MCDRV_SET_CDSP:
++              MakeSetCDSPLog((UINT16*)pvParam);
++              sprintf(sbStr, " dPrm=%08lX", dUpdateInfo);
++              strcat(gsbLogString, sbStr);
++              break;
++      case    MCDRV_SET_CDSP_PARAM:
++              MakeCDSPParamLog((MCDRV_CDSPPARAM*)pvParam);
++              break;
++      case    MCDRV_REGISTER_CDSP_CB:
++              MakeCDSPCBLog(pvParam);
++              break;
++      case    MCDRV_SET_PDM:
++              MakePDMInfoLog((MCDRV_PDM_INFO*)pvParam);
++              sprintf(sbStr, " dPrm=%08lX", dUpdateInfo);
++              strcat(gsbLogString, sbStr);
++              break;
++      case    MCDRV_SET_DTMF:
++              MakeDTMFInfoLog((MCDRV_DTMF_INFO*)pvParam);
++              break;
++      case    MCDRV_CONFIG_GP:
++              MakeGPModeLog((MCDRV_GP_MODE*)pvParam);
++              break;
++      case    MCDRV_MASK_GP:
++              MakeGPMaskLog((UINT8*)pvParam);
++              sprintf(sbStr, " dPrm=%08lX", dUpdateInfo);
++              strcat(gsbLogString, sbStr);
++              break;
++      case    MCDRV_GETSET_GP:
++              MakeGetSetGPLog((UINT8*)pvParam);
++              sprintf(sbStr, " dPrm=%08lX", dUpdateInfo);
++              strcat(gsbLogString, sbStr);
++              break;
++      case    MCDRV_SET_SYSEQ:
++              MakeSysEQInfoLog((MCDRV_SYSEQ_INFO*)pvParam);
++              sprintf(sbStr, " dPrm=%08lX", dUpdateInfo);
++              strcat(gsbLogString, sbStr);
++              break;
++
++      default:
++              break;
++      }
++
++      strcat(gsbLogString, gsbLFCode);
++      machdep_DebugPrint((UINT8*)(void*)gsbLogString);
++}
++
++/****************************************************************************
++ *    McDebugLog_CmdOut
++ *
++ *    Description:
++ *                    Output Function exit log.
++ *    Arguments:
++ *                    dCmd            Command ID
++ *                    psdRet          retrun value
++ *                    pvParam         pointer to parameter
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McDebugLog_CmdOut
++(
++      UINT32                  dCmd,
++      const SINT32*   psdRet,
++      const void*             pvParam
++)
++{
++      CHAR    sbStr[80];
++      UINT8   bLevel  = MCDRV_DEBUG_LEVEL;
++
++      if(dCmd >= sizeof(gsbCmdName)/sizeof(gsbCmdName[0]))
++      {
++              return;
++      }
++
++      strcpy(gsbLogString, gsbCmdName[dCmd]);
++      strcat(gsbLogString, " Out");
++      if(psdRet != NULL)
++      {
++              sprintf(sbStr, " ret=%ld", *psdRet);
++              strcat(gsbLogString, sbStr);
++      }
++
++      if(bLevel < 2)
++      {
++              strcat(gsbLogString, gsbLFCode);
++              machdep_DebugPrint((UINT8*)(void*)gsbLogString);
++              return;
++      }
++
++      switch(dCmd)
++      {
++      case    MCDRV_READ_REG:
++              MakeRegInfoLog((MCDRV_REG_INFO*)pvParam);
++              break;
++      case    MCDRV_GET_PATH:
++              MakePathInfoLog((MCDRV_PATH_INFO*)pvParam);
++              break;
++      case    MCDRV_GET_VOLUME:
++              MakeVolInfoLog((MCDRV_VOL_INFO*)pvParam);
++              break;
++      case    MCDRV_GET_DIGITALIO:
++              MakeDIOInfoLog((MCDRV_DIO_INFO*)pvParam);
++              break;
++      case    MCDRV_GET_DAC:
++              MakeDACInfoLog((MCDRV_DAC_INFO*)pvParam);
++              break;
++      case    MCDRV_GET_ADC:
++              MakeADCInfoLog((MCDRV_ADC_INFO*)pvParam);
++              break;
++      case    MCDRV_GET_SP:
++              MakeSpInfoLog((MCDRV_SP_INFO*)pvParam);
++              break;
++      case    MCDRV_GET_DNG:
++              MakeDNGInfoLog((MCDRV_DNG_INFO*)pvParam);
++              break;
++      case    MCDRV_GET_CDSP_PARAM:
++              MakeCDSPParamLog((MCDRV_CDSPPARAM*)pvParam);
++              break;
++      case    MCDRV_GET_PDM:
++              MakePDMInfoLog((MCDRV_PDM_INFO*)pvParam);
++              break;
++      case    MCDRV_GETSET_GP:
++              MakeGetSetGPLog((UINT8*)pvParam);
++              break;
++      case    MCDRV_GET_PEAK:
++              MakePeakLog((MCDRV_PEAK*)pvParam);
++              break;
++      case    MCDRV_GET_SYSEQ:
++              MakeSysEQInfoLog((MCDRV_SYSEQ_INFO*)pvParam);
++              break;
++
++      default:
++              break;
++      }
++      strcat(gsbLogString, gsbLFCode);
++      machdep_DebugPrint((UINT8*)(void*)gsbLogString);
++
++      if(bLevel < 3)
++      {
++              return;
++      }
++
++      OutputRegDump();
++}
++
++/****************************************************************************
++ *    McDebugLog_FuncIn
++ *
++ *    Description:
++ *                    Output Function entrance log.
++ *    Arguments:
++ *                    pbFuncName      function name
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McDebugLog_FuncIn
++(
++      void*   pvFuncName
++)
++{
++      strcpy(gsbLogString, (CHAR*)pvFuncName);
++      strcat(gsbLogString, " In");
++
++      strcat(gsbLogString, gsbLFCode);
++      machdep_DebugPrint((UINT8*)(void*)gsbLogString);
++}
++
++/****************************************************************************
++ *    McDebugLog_FuncOut
++ *
++ *    Description:
++ *                    Output Function exit log.
++ *    Arguments:
++ *                    pbFuncName      function name
++ *                    psdRet          retrun value
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McDebugLog_FuncOut
++(
++      void*                   pvFuncName,
++      const SINT32*   psdRet
++)
++{
++      CHAR    sbStr[80];
++
++      strcpy(gsbLogString, (CHAR*)pvFuncName);
++      strcat(gsbLogString, " Out");
++      if(psdRet != NULL)
++      {
++              sprintf(sbStr, " ret=%ld", *psdRet);
++              strcat(gsbLogString, sbStr);
++      }
++
++      strcat(gsbLogString, gsbLFCode);
++      machdep_DebugPrint((UINT8*)(void*)gsbLogString);
++}
++
++
++/****************************************************************************
++ *    OutputRegDump
++ *
++ *    Description:
++ *                    Output Register dump.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   OutputRegDump
++(
++      void
++)
++{
++      UINT16  i;
++      CHAR    sbStr[10];
++      CHAR    sbLogString[2500]="";
++      UINT8   bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++      MCDRV_REG_INFO  sRegInfo;
++
++      /*      A_ADR   */
++      sRegInfo.bRegType       = MCDRV_REGTYPE_A;
++      strcpy(sbLogString, "A_ADR:");
++      for(i = 0; i < 256UL; i++)
++      {
++              sRegInfo.bAddress       = (UINT8)i;
++              if((McResCtrl_GetRegAccess(&sRegInfo) & eMCDRV_READ_ONLY) != 0)
++              {
++                      sprintf(sbStr, "[%d]=%02X", i, McSrv_ReadI2C(bSlaveAddr, i));
++                      strcat(sbLogString, sbStr);
++                      if(i < 255UL)
++                      {
++                              strcat(sbLogString, " ");
++                      }
++              }
++      }
++      strcat(sbLogString, gsbLFCode);
++      machdep_DebugPrint((UINT8*)(void*)sbLogString);
++
++      /*      BASE_ADR        */
++      strcpy(sbLogString, "BASE_ADR:");
++      GetRegDump_B(sbLogString, bSlaveAddr, MCI_BASE_ADR, MCI_BASE_WINDOW, MCDRV_REGTYPE_B_BASE);
++      strcat(sbLogString, gsbLFCode);
++      machdep_DebugPrint((UINT8*)(void*)sbLogString);
++
++      /*      ANA_ADR */
++      strcpy(sbLogString, "ANA_ADR:");
++      GetRegDump_B(sbLogString, McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_ANA), MCI_ANA_ADR, MCI_ANA_WINDOW, MCDRV_REGTYPE_B_ANALOG);
++      strcat(sbLogString, gsbLFCode);
++      machdep_DebugPrint((UINT8*)(void*)sbLogString);
++
++      /*      CD_ADR  */
++      strcpy(sbLogString, "CD_ADR:");
++      GetRegDump_B(sbLogString, bSlaveAddr, MCI_CD_ADR, MCI_CD_WINDOW, MCDRV_REGTYPE_B_CODEC);
++      strcat(sbLogString, gsbLFCode);
++      machdep_DebugPrint((UINT8*)(void*)sbLogString);
++
++      /*      MIX_ADR */
++      strcpy(sbLogString, "MIX_ADR:");
++      GetRegDump_B(sbLogString, bSlaveAddr, MCI_MIX_ADR, MCI_MIX_WINDOW, MCDRV_REGTYPE_B_MIXER);
++      strcat(sbLogString, gsbLFCode);
++      machdep_DebugPrint((UINT8*)(void*)sbLogString);
++
++#if 0
++      /*      AE_ADR  */
++      strcpy(sbLogString, "AE_ADR:");
++      GetRegDump_B(sbLogString, bSlaveAddr, MCI_AE_ADR, MCI_AE_WINDOW, MCDRV_REGTYPE_B_AE);
++      strcat(sbLogString, gsbLFCode);
++      machdep_DebugPrint((UINT8*)(void*)sbLogString);
++#endif
++}
++
++/****************************************************************************
++ *    GetRegDump_B
++ *
++ *    Description:
++ *                    Get B-ADR Register dump string.
++ *    Arguments:
++ *                    psbLogString    string buffer
++ *                    bSlaveAddr              Slave address
++ *                    bADRAddr                ADR address
++ *                    bWINDOWAddr             WINDOW address
++ *                    bRegType                register type
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   GetRegDump_B
++(
++      CHAR*   psbLogString,
++      UINT8   bSlaveAddr,
++      UINT8   bADRAddr,
++      UINT8   bWINDOWAddr,
++      UINT8   bRegType
++)
++{
++      UINT16  i;
++      CHAR    sbStr[10];
++      UINT8   abData[2];
++      MCDRV_REG_INFO  sRegInfo;
++
++      abData[0]       = bADRAddr<<1;
++      sRegInfo.bRegType       = bRegType;
++
++      for(i = 0; i < 256UL; i++)
++      {
++              sRegInfo.bAddress       = (UINT8)i;
++              if((McResCtrl_GetRegAccess(&sRegInfo) & eMCDRV_READ_ONLY) != 0)
++              {
++                      abData[1]       = (UINT8)i;
++                      McSrv_WriteI2C(bSlaveAddr, abData, 2);
++                      sprintf(sbStr, "[%d]=%02X", i, McSrv_ReadI2C(bSlaveAddr, bWINDOWAddr));
++                      strcat(psbLogString, sbStr);
++                      if(i < 255UL)
++                      {
++                              strcat(psbLogString, " ");
++                      }
++              }
++      }
++}
++
++/****************************************************************************
++ *    MakeInitInfoLog
++ *
++ *    Description:
++ *                    Make Init Parameter log.
++ *    Arguments:
++ *                    pParam  pointer to parameter
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   MakeInitInfoLog
++(
++      const MCDRV_INIT_INFO*  pParam
++)
++{
++      CHAR    sbStr[80];
++
++      if(pParam == NULL)
++      {
++              strcat(gsbLogString, " param=NULL");
++              return;
++      }
++
++      sprintf(sbStr, " bCkSel=%02X", pParam->bCkSel);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bDivR0=%02X", pParam->bDivR0);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bDivF0=%02X", pParam->bDivF0);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bDivR1=%02X", pParam->bDivR1);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bDivF1=%02X", pParam->bDivF1);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bRange0=%02X", pParam->bRange0);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bRange1=%02X", pParam->bRange1);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bBypass=%02X", pParam->bBypass);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bDioSdo0Hiz=%02X", pParam->bDioSdo0Hiz);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bDioSdo1Hiz=%02X", pParam->bDioSdo1Hiz);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bDioSdo2Hiz=%02X", pParam->bDioSdo2Hiz);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bDioClk0Hiz=%02X", pParam->bDioClk0Hiz);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bDioClk1Hiz=%02X", pParam->bDioClk1Hiz);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bDioClk2Hiz=%02X", pParam->bDioClk2Hiz);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bPcmHiz=%02X", pParam->bPcmHiz);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bLineIn1Dif=%02X", pParam->bLineIn1Dif);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bLineIn2Dif=%02X", pParam->bLineIn2Dif);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bLineOut1Dif=%02X", pParam->bLineOut1Dif);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bLineOut2Dif=%02X", pParam->bLineOut2Dif);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bSpmn=%02X", pParam->bSpmn);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bMic1Sng=%02X", pParam->bMic1Sng);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bMic2Sng=%02X", pParam->bMic2Sng);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bMic3Sng=%02X", pParam->bMic3Sng);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bPowerMode=%02X", pParam->bPowerMode);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bSpHiz=%02X", pParam->bSpHiz);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bLdo=%02X", pParam->bLdo);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bPad0Func=%02X", pParam->bPad0Func);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bPad1Func=%02X", pParam->bPad1Func);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bPad2Func=%02X", pParam->bPad2Func);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bAvddLev=%02X", pParam->bAvddLev);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bVrefLev=%02X", pParam->bVrefLev);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bDclGain=%02X", pParam->bDclGain);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bDclLimit=%02X", pParam->bDclLimit);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bCpMod=%02X", pParam->bCpMod);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bReserved1=%02X", pParam->bReserved1);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bReserved2=%02X", pParam->bReserved2);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bReserved3=%02X", pParam->bReserved3);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bReserved4=%02X", pParam->bReserved4);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bReserved5=%02X", pParam->bReserved5);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " sWaitTime.dAdHpf=%08lX", pParam->sWaitTime.dAdHpf);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " sWaitTime.dMic1Cin=%08lX", pParam->sWaitTime.dMic1Cin);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " sWaitTime.dMic2Cin=%08lX", pParam->sWaitTime.dMic2Cin);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " sWaitTime.dMic3Cin=%08lX", pParam->sWaitTime.dMic3Cin);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " sWaitTime.dLine1Cin=%08lX", pParam->sWaitTime.dLine1Cin);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " sWaitTime.dLine2Cin=%08lX", pParam->sWaitTime.dLine2Cin);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " sWaitTime.dVrefRdy1=%08lX", pParam->sWaitTime.dVrefRdy1);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " sWaitTime.dVrefRdy2=%08lX", pParam->sWaitTime.dVrefRdy2);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " sWaitTime.dHpRdy=%08lX", pParam->sWaitTime.dHpRdy);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " sWaitTime.dSpRdy=%08lX", pParam->sWaitTime.dSpRdy);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " sWaitTime.dPdm=%08lX", pParam->sWaitTime.dPdm);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " sWaitTime.dAnaRdyInterval=%08lX", pParam->sWaitTime.dAnaRdyInterval);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " sWaitTime.dSvolInterval=%08lX", pParam->sWaitTime.dSvolInterval);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " sWaitTime.dAnaRdyTimeOut=%08lX", pParam->sWaitTime.dAnaRdyTimeOut);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " sWaitTime.dSvolTimeOut=%08lX", pParam->sWaitTime.dSvolTimeOut);
++      strcat(gsbLogString, sbStr);
++}
++
++/****************************************************************************
++ *    MakeRegInfoLog
++ *
++ *    Description:
++ *                    Make Reg Info Parameter log.
++ *    Arguments:
++ *                    pParam  pointer to parameter
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   MakeRegInfoLog
++(
++      const MCDRV_REG_INFO* pParam
++)
++{
++      CHAR    sbStr[80];
++
++      if(pParam == NULL)
++      {
++              strcat(gsbLogString, " param=NULL");
++              return;
++      }
++
++      sprintf(sbStr, " bRegType=%02X", pParam->bRegType);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bAddress=%02X", pParam->bAddress);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bData=%02X", pParam->bData);
++      strcat(gsbLogString, sbStr);
++}
++
++/****************************************************************************
++ *    MakeClockInfoLog
++ *
++ *    Description:
++ *                    Make Clock Info Parameter log.
++ *    Arguments:
++ *                    pParam  pointer to parameter
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   MakeClockInfoLog
++(
++      const MCDRV_CLOCK_INFO* pParam
++)
++{
++      CHAR    sbStr[80];
++
++      if(pParam == NULL)
++      {
++              strcat(gsbLogString, " param=NULL");
++              return;
++      }
++
++      sprintf(sbStr, " bCkSel=%02X", pParam->bCkSel);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bDivR0=%02X", pParam->bDivR0);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bDivF0=%02X", pParam->bDivF0);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bDivR1=%02X", pParam->bDivR1);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bDivF1=%02X", pParam->bDivF1);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bRange0=%02X", pParam->bRange0);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bRange1=%02X", pParam->bRange1);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bBypass=%02X", pParam->bBypass);
++      strcat(gsbLogString, sbStr);
++}
++
++/****************************************************************************
++ *    MakeClockSwInfoLog
++ *
++ *    Description:
++ *                    Make Clock Switch Info Parameter log.
++ *    Arguments:
++ *                    pParam  pointer to parameter
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   MakeClockSwInfoLog
++(
++      const MCDRV_CLKSW_INFO* pParam
++)
++{
++      CHAR    sbStr[80];
++
++      if(pParam == NULL)
++      {
++              strcat(gsbLogString, " param=NULL");
++              return;
++      }
++
++      sprintf(sbStr, " bClkSrc=%02X", pParam->bClkSrc);
++      strcat(gsbLogString, sbStr);
++}
++
++/****************************************************************************
++ *    MakePathInfoLog
++ *
++ *    Description:
++ *                    Make Path Info Parameter log.
++ *    Arguments:
++ *                    pParam  pointer to parameter
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   MakePathInfoLog
++(
++      const MCDRV_PATH_INFO* pParam
++)
++{
++      UINT8   bBlock, bCh;
++      CHAR    sbStr[80];
++
++      if(pParam == NULL)
++      {
++              strcat(gsbLogString, " param=NULL");
++              return;
++      }
++
++      for(bCh = 0; bCh < HP_PATH_CHANNELS; bCh++)
++      {
++              for(bBlock = 0; bBlock < SOURCE_BLOCK_NUM; bBlock++)
++              {
++                      sprintf(sbStr, " asHpOut[%d].abSrcOnOff[%d]=%02X", bCh, bBlock, pParam->asHpOut[bCh].abSrcOnOff[bBlock]);
++                      strcat(gsbLogString, sbStr);
++              }
++      }
++      for(bCh = 0; bCh < SP_PATH_CHANNELS; bCh++)
++      {
++              for(bBlock = 0; bBlock < SOURCE_BLOCK_NUM; bBlock++)
++              {
++                      sprintf(sbStr, " asSpOut[%d].abSrcOnOff[%d]=%02X", bCh, bBlock, pParam->asSpOut[bCh].abSrcOnOff[bBlock]);
++                      strcat(gsbLogString, sbStr);
++              }
++      }
++      for(bCh = 0; bCh < RC_PATH_CHANNELS; bCh++)
++      {
++              for(bBlock = 0; bBlock < SOURCE_BLOCK_NUM; bBlock++)
++              {
++                      sprintf(sbStr, " asRcOut[%d].abSrcOnOff[%d]=%02X", bCh, bBlock, pParam->asRcOut[bCh].abSrcOnOff[bBlock]);
++                      strcat(gsbLogString, sbStr);
++              }
++      }
++      for(bCh = 0; bCh < LOUT1_PATH_CHANNELS; bCh++)
++      {
++              for(bBlock = 0; bBlock < SOURCE_BLOCK_NUM; bBlock++)
++              {
++                      sprintf(sbStr, " asLout1[%d].abSrcOnOff[%d]=%02X", bCh, bBlock, pParam->asLout1[bCh].abSrcOnOff[bBlock]);
++                      strcat(gsbLogString, sbStr);
++              }
++      }
++      for(bCh = 0; bCh < LOUT2_PATH_CHANNELS; bCh++)
++      {
++              for(bBlock = 0; bBlock < SOURCE_BLOCK_NUM; bBlock++)
++              {
++                      sprintf(sbStr, " asLout2[%d].abSrcOnOff[%d]=%02X", bCh, bBlock, pParam->asLout2[bCh].abSrcOnOff[bBlock]);
++                      strcat(gsbLogString, sbStr);
++              }
++      }
++      for(bCh = 0; bCh < PEAK_PATH_CHANNELS; bCh++)
++      {
++              for(bBlock = 0; bBlock < SOURCE_BLOCK_NUM; bBlock++)
++              {
++                      sprintf(sbStr, " asPeak[%d].abSrcOnOff[%d]=%02X", bCh, bBlock, pParam->asPeak[bCh].abSrcOnOff[bBlock]);
++                      strcat(gsbLogString, sbStr);
++              }
++      }
++      for(bCh = 0; bCh < DIT0_PATH_CHANNELS; bCh++)
++      {
++              for(bBlock = 0; bBlock < SOURCE_BLOCK_NUM; bBlock++)
++              {
++                      sprintf(sbStr, " asDit0[%d].abSrcOnOff[%d]=%02X", bCh, bBlock, pParam->asDit0[bCh].abSrcOnOff[bBlock]);
++                      strcat(gsbLogString, sbStr);
++              }
++      }
++      for(bCh = 0; bCh < DIT1_PATH_CHANNELS; bCh++)
++      {
++              for(bBlock = 0; bBlock < SOURCE_BLOCK_NUM; bBlock++)
++              {
++                      sprintf(sbStr, " asDit1[%d].abSrcOnOff[%d]=%02X", bCh, bBlock, pParam->asDit1[bCh].abSrcOnOff[bBlock]);
++                      strcat(gsbLogString, sbStr);
++              }
++      }
++      for(bCh = 0; bCh < DIT2_PATH_CHANNELS; bCh++)
++      {
++              for(bBlock = 0; bBlock < SOURCE_BLOCK_NUM; bBlock++)
++              {
++                      sprintf(sbStr, " asDit2[%d].abSrcOnOff[%d]=%02X", bCh, bBlock, pParam->asDit2[bCh].abSrcOnOff[bBlock]);
++                      strcat(gsbLogString, sbStr);
++              }
++      }
++      for(bCh = 0; bCh < DAC_PATH_CHANNELS; bCh++)
++      {
++              for(bBlock = 0; bBlock < SOURCE_BLOCK_NUM; bBlock++)
++              {
++                      sprintf(sbStr, " asDac[%d].abSrcOnOff[%d]=%02X", bCh, bBlock, pParam->asDac[bCh].abSrcOnOff[bBlock]);
++                      strcat(gsbLogString, sbStr);
++              }
++      }
++      for(bCh = 0; bCh < AE_PATH_CHANNELS; bCh++)
++      {
++              for(bBlock = 0; bBlock < SOURCE_BLOCK_NUM; bBlock++)
++              {
++                      sprintf(sbStr, " asAe[%d].abSrcOnOff[%d]=%02X", bCh, bBlock, pParam->asAe[bCh].abSrcOnOff[bBlock]);
++                      strcat(gsbLogString, sbStr);
++              }
++      }
++      for(bCh = 0; bCh < CDSP_PATH_CHANNELS; bCh++)
++      {
++              for(bBlock = 0; bBlock < SOURCE_BLOCK_NUM; bBlock++)
++              {
++                      sprintf(sbStr, " asCdsp[%d].abSrcOnOff[%d]=%02X", bCh, bBlock, pParam->asCdsp[bCh].abSrcOnOff[bBlock]);
++                      strcat(gsbLogString, sbStr);
++              }
++      }
++      for(bCh = 0; bCh < ADC0_PATH_CHANNELS; bCh++)
++      {
++              for(bBlock = 0; bBlock < SOURCE_BLOCK_NUM; bBlock++)
++              {
++                      sprintf(sbStr, " asAdc0[%d].abSrcOnOff[%d]=%02X", bCh, bBlock, pParam->asAdc0[bCh].abSrcOnOff[bBlock]);
++                      strcat(gsbLogString, sbStr);
++              }
++      }
++      for(bCh = 0; bCh < ADC1_PATH_CHANNELS; bCh++)
++      {
++              for(bBlock = 0; bBlock < SOURCE_BLOCK_NUM; bBlock++)
++              {
++                      sprintf(sbStr, " asAdc1[%d].abSrcOnOff[%d]=%02X", bCh, bBlock, pParam->asAdc1[bCh].abSrcOnOff[bBlock]);
++                      strcat(gsbLogString, sbStr);
++              }
++      }
++      for(bCh = 0; bCh < MIX_PATH_CHANNELS; bCh++)
++      {
++              for(bBlock = 0; bBlock < SOURCE_BLOCK_NUM; bBlock++)
++              {
++                      sprintf(sbStr, " asMix[%d].abSrcOnOff[%d]=%02X", bCh, bBlock, pParam->asMix[bCh].abSrcOnOff[bBlock]);
++                      strcat(gsbLogString, sbStr);
++              }
++      }
++      for(bCh = 0; bCh < BIAS_PATH_CHANNELS; bCh++)
++      {
++              for(bBlock = 0; bBlock < SOURCE_BLOCK_NUM; bBlock++)
++              {
++                      sprintf(sbStr, " asBias[%d].abSrcOnOff[%d]=%02X", bCh, bBlock, pParam->asBias[bCh].abSrcOnOff[bBlock]);
++                      strcat(gsbLogString, sbStr);
++              }
++      }
++}
++
++/****************************************************************************
++ *    MakeVolInfoLog
++ *
++ *    Description:
++ *                    Make Volume Info Parameter log.
++ *    Arguments:
++ *                    pParam  pointer to parameter
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   MakeVolInfoLog
++(
++      const MCDRV_VOL_INFO* pParam
++)
++{
++      UINT8   bCh;
++      CHAR    sbStr[80];
++
++      if(pParam == NULL)
++      {
++              strcat(gsbLogString, " param=NULL");
++              return;
++      }
++
++      for(bCh = 0; bCh < AD0_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswD_Ad0[%d]=%04X", bCh, (UINT16)pParam->aswD_Ad0[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < AD1_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswD_Ad1[%d]=%04X", bCh, (UINT16)pParam->aswD_Ad1[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < AENG6_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswD_Aeng6[%d]=%04X", bCh, (UINT16)pParam->aswD_Aeng6[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < PDM_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswD_Pdm[%d]=%04X", bCh, (UINT16)pParam->aswD_Pdm[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < DTMF_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswD_Dtmfb[%d]=%04X", bCh, (UINT16)pParam->aswD_Dtmfb[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < DIO0_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswD_Dir0[%d]=%04X", bCh, (UINT16)pParam->aswD_Dir0[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < DIO1_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswD_Dir1[%d]=%04X", bCh, (UINT16)pParam->aswD_Dir1[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < DIO2_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswD_Dir2[%d]=%04X", bCh, (UINT16)pParam->aswD_Dir2[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < AD0_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswD_Ad0Att[%d]=%04X", bCh, (UINT16)pParam->aswD_Ad0Att[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < AD1_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswD_Ad1Att[%d]=%04X", bCh, (UINT16)pParam->aswD_Ad1Att[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < DIO0_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswD_Dir0Att[%d]=%04X", bCh, (UINT16)pParam->aswD_Dir0Att[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < DIO1_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswD_Dir1Att[%d]=%04X", bCh, (UINT16)pParam->aswD_Dir1Att[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < DIO2_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswD_Dir2Att[%d]=%04X", bCh, (UINT16)pParam->aswD_Dir2Att[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < PDM_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswD_SideTone[%d]=%04X", bCh, (UINT16)pParam->aswD_SideTone[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < DTFM_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswD_DtmfAtt[%d]=%04X", bCh, (UINT16)pParam->aswD_DtmfAtt[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < DAC_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswD_DacMaster[%d]=%04X", bCh, (UINT16)pParam->aswD_DacMaster[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < DAC_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswD_DacVoice[%d]=%04X", bCh, (UINT16)pParam->aswD_DacVoice[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < DAC_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswD_DacAtt[%d]=%04X", bCh, (UINT16)pParam->aswD_DacAtt[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < DIO0_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswD_Dit0[%d]=%04X",bCh, (UINT16)pParam->aswD_Dit0[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < DIO1_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswD_Dit1[%d]=%04X", bCh, (UINT16)pParam->aswD_Dit1[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < DIO2_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswD_Dit2[%d]=%04X", bCh, (UINT16)pParam->aswD_Dit2[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < AD0_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswA_Ad0[%d]=%04X", bCh, (UINT16)pParam->aswA_Ad0[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < AD1_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswA_Ad1[%d]=%04X", bCh, (UINT16)pParam->aswA_Ad1[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh <LIN1_VOL_CHANNELS ; bCh++)
++      {
++              sprintf(sbStr, " aswA_Lin1[%d]=%04X", bCh, (UINT16)pParam->aswA_Lin1[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < LIN2_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswA_Lin2[%d]=%04X", bCh, (UINT16)pParam->aswA_Lin2[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < MIC1_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswA_Mic1[%d]=%04X", bCh, (UINT16)pParam->aswA_Mic1[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < MIC2_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswA_Mic2[%d]=%04X", bCh, (UINT16)pParam->aswA_Mic2[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < MIC3_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswA_Mic3[%d]=%04X", bCh, (UINT16)pParam->aswA_Mic3[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < HP_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswA_Hp[%d]=%04X", bCh, (UINT16)pParam->aswA_Hp[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < SP_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswA_Sp[%d]=%04X", bCh, (UINT16)pParam->aswA_Sp[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < RC_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswA_Rc[%d]=%04X", bCh, (UINT16)pParam->aswA_Rc[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < LOUT1_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswA_Lout1[%d]=%04X", bCh, (UINT16)pParam->aswA_Lout1[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < LOUT2_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswA_Lout2[%d]=%04X", bCh, (UINT16)pParam->aswA_Lout2[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < MIC1_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswA_Mic1Gain[%d]=%04X", bCh, (UINT16)pParam->aswA_Mic1Gain[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < MIC2_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswA_Mic2Gain[%d]=%04X", bCh, (UINT16)pParam->aswA_Mic2Gain[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < MIC3_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswA_Mic3Gain[%d]=%04X", bCh, (UINT16)pParam->aswA_Mic3Gain[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bCh = 0; bCh < HPGAIN_VOL_CHANNELS; bCh++)
++      {
++              sprintf(sbStr, " aswA_HpGain[%d]=%04X", bCh, (UINT16)pParam->aswA_HpGain[bCh]);
++              strcat(gsbLogString, sbStr);
++      }
++}
++
++/****************************************************************************
++ *    MakeDIOInfoLog
++ *
++ *    Description:
++ *                    Make Digital I/O Info Parameter log.
++ *    Arguments:
++ *                    pParam  pointer to parameter
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   MakeDIOInfoLog
++(
++      const MCDRV_DIO_INFO* pParam
++)
++{
++      CHAR    sbStr[80];
++      UINT8   bPort, bCh;
++
++      if(pParam == NULL)
++      {
++              strcat(gsbLogString, " param=NULL");
++              return;
++      }
++
++      for(bPort = 0; bPort < IOPORT_NUM; bPort++)
++      {
++              sprintf(sbStr, " asPortInfo[%d].sDioCommon.bMasterSlave=%02X", bPort, pParam->asPortInfo[bPort].sDioCommon.bMasterSlave);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " asPortInfo[%d].sDioCommon.bAutoFs=%02X", bPort, pParam->asPortInfo[bPort].sDioCommon.bAutoFs);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " asPortInfo[%d].sDioCommon.bFs=%02X", bPort, pParam->asPortInfo[bPort].sDioCommon.bFs);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " asPortInfo[%d].sDioCommon.bBckFs=%02X", bPort, pParam->asPortInfo[bPort].sDioCommon.bBckFs);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " asPortInfo[%d].sDioCommon.bInterface=%02X", bPort, pParam->asPortInfo[bPort].sDioCommon.bInterface);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " asPortInfo[%d].sDioCommon.bBckInvert=%02X", bPort, pParam->asPortInfo[bPort].sDioCommon.bBckInvert);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " asPortInfo[%d].sDioCommon.bPcmHizTim=%02X", bPort, pParam->asPortInfo[bPort].sDioCommon.bPcmHizTim);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " asPortInfo[%d].sDioCommon.bPcmClkDown=%02X", bPort, pParam->asPortInfo[bPort].sDioCommon.bPcmClkDown);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " asPortInfo[%d].sDioCommon.bPcmFrame=%02X", bPort, pParam->asPortInfo[bPort].sDioCommon.bPcmFrame);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " asPortInfo[%d].sDioCommon.bPcmHighPeriod=%02X", bPort, pParam->asPortInfo[bPort].sDioCommon.bPcmHighPeriod);
++              strcat(gsbLogString, sbStr);
++
++              sprintf(sbStr, " asPortInfo[%d].sDir.wSrcRate=%04X", bPort, pParam->asPortInfo[bPort].sDir.wSrcRate);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " asPortInfo[%d].sDir.sDaFormat.bBitSel=%02X", bPort, pParam->asPortInfo[bPort].sDir.sDaFormat.bBitSel);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " asPortInfo[%d].sDir.sDaFormat.bMode=%02X", bPort, pParam->asPortInfo[bPort].sDir.sDaFormat.bMode);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " asPortInfo[%d].sDir.sPcmFormat.bMono=%02X", bPort, pParam->asPortInfo[bPort].sDir.sPcmFormat.bMono);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " asPortInfo[%d].sDir.sPcmFormat.bOrder=%02X", bPort, pParam->asPortInfo[bPort].sDir.sPcmFormat.bOrder);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " asPortInfo[%d].sDir.sPcmFormat.bLaw=%02X", bPort, pParam->asPortInfo[bPort].sDir.sPcmFormat.bLaw);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " asPortInfo[%d].sDir.sPcmFormat.bBitSel=%02X", bPort, pParam->asPortInfo[bPort].sDir.sPcmFormat.bBitSel);
++              strcat(gsbLogString, sbStr);
++              for(bCh = 0; bCh < DIO_CHANNELS; bCh++)
++              {
++                      sprintf(sbStr, " asPortInfo[%d].sDir.abSlot[%d]=%02X", bPort, bCh, pParam->asPortInfo[bPort].sDir.abSlot[bCh]);
++                      strcat(gsbLogString, sbStr);
++              }
++
++              sprintf(sbStr, " asPortInfo[%d].sDit.wSrcRate=%04X", bPort, pParam->asPortInfo[bPort].sDit.wSrcRate);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " asPortInfo[%d].sDit.sDaFormat.bBitSel=%02X", bPort, pParam->asPortInfo[bPort].sDit.sDaFormat.bBitSel);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " asPortInfo[%d].sDit.sDaFormat.bMode=%02X", bPort, pParam->asPortInfo[bPort].sDit.sDaFormat.bMode);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " asPortInfo[%d].sDit.sPcmFormat.bMono=%02X", bPort, pParam->asPortInfo[bPort].sDit.sPcmFormat.bMono);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " asPortInfo[%d].sDit.sPcmFormat.bOrder=%02X", bPort, pParam->asPortInfo[bPort].sDit.sPcmFormat.bOrder);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " asPortInfo[%d].sDit.sPcmFormat.bLaw=%02X", bPort, pParam->asPortInfo[bPort].sDit.sPcmFormat.bLaw);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " asPortInfo[%d].sDit.sPcmFormat.bBitSel=%02X", bPort, pParam->asPortInfo[bPort].sDit.sPcmFormat.bBitSel);
++              strcat(gsbLogString, sbStr);
++              for(bCh = 0; bCh < DIO_CHANNELS; bCh++)
++              {
++                      sprintf(sbStr, " asPortInfo[%d].sDit.abSlot[%d]=%02X", bPort, bCh, pParam->asPortInfo[bPort].sDit.abSlot[bCh]);
++                      strcat(gsbLogString, sbStr);
++              }
++      }
++}
++
++/****************************************************************************
++ *    MakeDACInfoLog
++ *
++ *    Description:
++ *                    Make DAC Info Parameter log.
++ *    Arguments:
++ *                    pParam  pointer to parameter
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   MakeDACInfoLog
++(
++      const MCDRV_DAC_INFO* pParam
++)
++{
++      CHAR    sbStr[80];
++
++      if(pParam == NULL)
++      {
++              strcat(gsbLogString, " param=NULL");
++              return;
++      }
++
++      sprintf(sbStr, " bMasterSwap=%02X", pParam->bMasterSwap);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bVoiceSwap=%02X", pParam->bVoiceSwap);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bDcCut=%02X", pParam->bDcCut);
++      strcat(gsbLogString, sbStr);
++}
++
++/****************************************************************************
++ *    MakeADCInfoLog
++ *
++ *    Description:
++ *                    Make ADC Info Parameter log.
++ *    Arguments:
++ *                    pParam  pointer to parameter
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   MakeADCInfoLog
++(
++      const MCDRV_ADC_INFO* pParam
++)
++{
++      CHAR    sbStr[80];
++
++      if(pParam == NULL)
++      {
++              strcat(gsbLogString, " param=NULL");
++              return;
++      }
++
++      sprintf(sbStr, " bAgcAdjust=%02X", pParam->bAgcAdjust);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bAgcOn=%02X", pParam->bAgcOn);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bMono=%02X", pParam->bMono);
++      strcat(gsbLogString, sbStr);
++}
++
++/****************************************************************************
++ *    MakeSpInfoLog
++ *
++ *    Description:
++ *                    Make Sp Info Parameter log.
++ *    Arguments:
++ *                    pParam  pointer to parameter
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   MakeSpInfoLog
++(
++      const MCDRV_SP_INFO* pParam
++)
++{
++      CHAR    sbStr[80];
++
++      if(pParam == NULL)
++      {
++              strcat(gsbLogString, " param=NULL");
++              return;
++      }
++
++      sprintf(sbStr, " bSwap=%02X", pParam->bSwap);
++      strcat(gsbLogString, sbStr);
++}
++
++/****************************************************************************
++ *    MakeDNGInfoLog
++ *
++ *    Description:
++ *                    Make DNG Info Parameter log.
++ *    Arguments:
++ *                    pParam  pointer to parameter
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   MakeDNGInfoLog
++(
++      const MCDRV_DNG_INFO* pParam
++)
++{
++      CHAR    sbStr[80];
++      UINT8   bItem;
++
++      if(pParam == NULL)
++      {
++              strcat(gsbLogString, " param=NULL");
++              return;
++      }
++
++      for(bItem = 0; bItem < DNG_ITEM_NUM; bItem++)
++      {
++              sprintf(sbStr, " abOnOff[%d]=%02X", bItem, pParam->abOnOff[bItem]);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " abThreshold[%d]=%02X", bItem, pParam->abThreshold[bItem]);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " abHold[%d]=%02X", bItem, pParam->abHold[bItem]);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " abAttack[%d]=%02X", bItem, pParam->abAttack[bItem]);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " abRelease[%d]=%02X", bItem, pParam->abRelease[bItem]);
++              strcat(gsbLogString, sbStr);
++              sprintf(sbStr, " abTarget[%d]=%02X", bItem, pParam->abTarget[bItem]);
++              strcat(gsbLogString, sbStr);
++      }
++}
++
++/****************************************************************************
++ *    MakeAEInfoLog
++ *
++ *    Description:
++ *                    Make AudioEngine Info Parameter log.
++ *    Arguments:
++ *                    pParam  pointer to parameter
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   MakeAEInfoLog
++(
++      const MCDRV_AE_INFO* pParam
++)
++{
++      CHAR    sbStr[80];
++      UINT16  wIdx;
++
++      if(pParam == NULL)
++      {
++              strcat(gsbLogString, " param=NULL");
++              return;
++      }
++
++      sprintf(sbStr, " bOnOff=%02X", pParam->bOnOff);
++      strcat(gsbLogString, sbStr);
++
++      for(wIdx = 0; wIdx < BEX_PARAM_SIZE; wIdx++)
++      {
++              sprintf(sbStr, " abBex[%d]=%02X", wIdx, pParam->abBex[wIdx]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(wIdx = 0; wIdx < WIDE_PARAM_SIZE; wIdx++)
++      {
++              sprintf(sbStr, " abWide[%d]=%02X", wIdx, pParam->abWide[wIdx]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(wIdx = 0; wIdx < DRC_PARAM_SIZE; wIdx++)
++      {
++              sprintf(sbStr, " abDrc[%d]=%02X", wIdx, pParam->abDrc[wIdx]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(wIdx = 0; wIdx < EQ5_PARAM_SIZE; wIdx++)
++      {
++              sprintf(sbStr, " abEq5[%d]=%02X", wIdx, pParam->abEq5[wIdx]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(wIdx = 0; wIdx < EQ3_PARAM_SIZE; wIdx++)
++      {
++              sprintf(sbStr, " abEq3[%d]=%02X", wIdx, pParam->abEq3[wIdx]);
++              strcat(gsbLogString, sbStr);
++      }
++}
++
++/****************************************************************************
++ *    MakeAEExInfoLog
++ *
++ *    Description:
++ *                    Make AudioEngineEx Info Parameter log.
++ *    Arguments:
++ *                    pParam  pointer to parameter
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   MakeAEExInfoLog
++(
++      const UINT16* pParam
++)
++{
++      CHAR    sbStr[80];
++
++      if(pParam == NULL)
++      {
++              strcat(gsbLogString, " param=NULL");
++              return;
++      }
++
++      sprintf(sbStr, " param=%04X", *pParam);
++      strcat(gsbLogString, sbStr);
++}
++
++/****************************************************************************
++ *    MakeSetCDSPLog
++ *
++ *    Description:
++ *                    Make CDSP Parameter log.
++ *    Arguments:
++ *                    pParam  pointer to parameter
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   MakeSetCDSPLog
++(
++      const UINT16* pParam
++)
++{
++      CHAR    sbStr[80];
++
++      if(pParam == NULL)
++      {
++              strcat(gsbLogString, " param=NULL");
++              return;
++      }
++
++      sprintf(sbStr, " param=%04X", *pParam);
++      strcat(gsbLogString, sbStr);
++}
++
++/****************************************************************************
++ *    MakeCDSPParamLog
++ *
++ *    Description:
++ *                    Make CDSP Parameter log.
++ *    Arguments:
++ *                    pParam  pointer to parameter
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   MakeCDSPParamLog
++(
++      const MCDRV_CDSPPARAM* pParam
++)
++{
++      CHAR    sbStr[80];
++      UINT8   bIdx;
++
++      if(pParam == NULL)
++      {
++              strcat(gsbLogString, " param=NULL");
++              return;
++      }
++
++      sprintf(sbStr, " bId=%02X", pParam->bId);
++      strcat(gsbLogString, sbStr);
++      for(bIdx = 0; bIdx < 16; bIdx++)
++      {
++              sprintf(sbStr, " abParam[%d]=%02X", bIdx, pParam->abParam[bIdx]);
++              strcat(gsbLogString, sbStr);
++      }
++}
++
++/****************************************************************************
++ *    MakeCDSPCBLog
++ *
++ *    Description:
++ *                    Make CDSP Callback Parameter log.
++ *    Arguments:
++ *                    pParam  pointer to parameter
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   MakeCDSPCBLog
++(
++      const void* pParam
++)
++{
++      CHAR    sbStr[80];
++
++      if(pParam == NULL)
++      {
++              strcat(gsbLogString, " param=NULL");
++              return;
++      }
++
++      sprintf(sbStr, " param=%08lX", *(UINT32*)pParam);
++      strcat(gsbLogString, sbStr);
++}
++
++/****************************************************************************
++ *    MakePDMInfoLog
++ *
++ *    Description:
++ *                    Make PDM Info Parameter log.
++ *    Arguments:
++ *                    pParam  pointer to parameter
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   MakePDMInfoLog
++(
++      const MCDRV_PDM_INFO* pParam
++)
++{
++      CHAR    sbStr[80];
++
++      if(pParam == NULL)
++      {
++              strcat(gsbLogString, " param=NULL");
++              return;
++      }
++
++      sprintf(sbStr, " bClk=%02X", pParam->bClk);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bAgcAdjust=%02X", pParam->bAgcAdjust);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bAgcOn=%02X", pParam->bAgcOn);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bPdmEdge=%02X", pParam->bPdmEdge);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bPdmWait=%02X", pParam->bPdmWait);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bPdmSel=%02X", pParam->bPdmSel);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " bMono=%02X", pParam->bMono);
++      strcat(gsbLogString, sbStr);
++}
++
++/****************************************************************************
++ *    MakeDTMFInfoLog
++ *
++ *    Description:
++ *                    Make DTMF Info Parameter log.
++ *    Arguments:
++ *                    pParam  pointer to parameter
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   MakeDTMFInfoLog
++(
++      const MCDRV_DTMF_INFO* pParam
++)
++{
++      CHAR    sbStr[80];
++
++      if(pParam == NULL)
++      {
++              strcat(gsbLogString, " param=NULL");
++              return;
++      }
++
++      sprintf(sbStr, " bOnOff=%02X", pParam->bOnOff);
++      strcat(gsbLogString, sbStr);
++
++      sprintf(sbStr, " sParam.bSinGen0Vol=%02X", pParam->sParam.bSinGen0Vol);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " sParam.bSinGen1Vol=%02X", pParam->sParam.bSinGen1Vol);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " sParam.wSinGen0Freq=%04X", pParam->sParam.wSinGen0Freq);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " sParam.wSinGen1Freq=%04X", pParam->sParam.wSinGen1Freq);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " sParam.bSinGenGate=%02X", pParam->sParam.bSinGenGate);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " sParam.=bSinGenMode%02X", pParam->sParam.bSinGenMode);
++      strcat(gsbLogString, sbStr);
++      sprintf(sbStr, " sParam.bSinGenLoop=%02X", pParam->sParam.bSinGenLoop);
++      strcat(gsbLogString, sbStr);
++}
++
++/****************************************************************************
++ *    MakeGPModeLog
++ *
++ *    Description:
++ *                    Make GPIO mode Info Parameter log.
++ *    Arguments:
++ *                    pParam  pointer to parameter
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   MakeGPModeLog
++(
++      const MCDRV_GP_MODE* pParam
++)
++{
++      CHAR    sbStr[80];
++      UINT8   bPadNo;
++
++      if(pParam == NULL)
++      {
++              strcat(gsbLogString, " param=NULL");
++              return;
++      }
++
++      for(bPadNo = 0; bPadNo < GPIO_PAD_NUM; bPadNo++)
++      {
++              sprintf(sbStr, " abGpDdr[%d]=%02X", bPadNo, pParam->abGpDdr[bPadNo]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bPadNo = 0; bPadNo < GPIO_PAD_NUM; bPadNo++)
++      {
++              sprintf(sbStr, " abGpMode[%d]=%02X", bPadNo, pParam->abGpMode[bPadNo]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bPadNo = 0; bPadNo < GPIO_PAD_NUM; bPadNo++)
++      {
++              sprintf(sbStr, " abGpHost[%d]=%02X", bPadNo, pParam->abGpHost[bPadNo]);
++              strcat(gsbLogString, sbStr);
++      }
++      for(bPadNo = 0; bPadNo < GPIO_PAD_NUM; bPadNo++)
++      {
++              sprintf(sbStr, " abGpInvert[%d]=%02X", bPadNo, pParam->abGpInvert[bPadNo]);
++              strcat(gsbLogString, sbStr);
++      }
++}
++
++/****************************************************************************
++ *    MakeGPMaskLog
++ *
++ *    Description:
++ *                    Make GPIO Mask Info Parameter log.
++ *    Arguments:
++ *                    pParam  pointer to parameter
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   MakeGPMaskLog
++(
++      const UINT8* pParam
++)
++{
++      CHAR    sbStr[80];
++
++      if(pParam == NULL)
++      {
++              strcat(gsbLogString, " param=NULL");
++              return;
++      }
++
++      sprintf(sbStr, " mask=%02X", *pParam);
++      strcat(gsbLogString, sbStr);
++}
++
++/****************************************************************************
++ *    MakeGetSetGPLog
++ *
++ *    Description:
++ *                    Make Get/Set GPIO Info Parameter log.
++ *    Arguments:
++ *                    pParam  pointer to parameter
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   MakeGetSetGPLog
++(
++      const UINT8* pParam
++)
++{
++      CHAR    sbStr[80];
++
++      if(pParam == NULL)
++      {
++              strcat(gsbLogString, " param=NULL");
++              return;
++      }
++
++      sprintf(sbStr, " HiLow=%02X", *pParam);
++      strcat(gsbLogString, sbStr);
++}
++
++/****************************************************************************
++ *    MakePeakLog
++ *
++ *    Description:
++ *                    Make Peak Parameter log.
++ *    Arguments:
++ *                    pParam  pointer to parameter
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   MakePeakLog
++(
++      const MCDRV_PEAK* pParam
++)
++{
++      CHAR    sbStr[80];
++      UINT8   bIdx;
++
++      if(pParam == NULL)
++      {
++              strcat(gsbLogString, " param=NULL");
++              return;
++      }
++
++      for(bIdx = 0; bIdx < PEAK_CHANNELS; bIdx++)
++      {
++              sprintf(sbStr, " aswPeak[%d]=%02X", bIdx, pParam->aswPeak[bIdx]);
++              strcat(gsbLogString, sbStr);
++      }
++}
++
++/****************************************************************************
++ *    MakeSysEQInfoLog
++ *
++ *    Description:
++ *                    Make System EQ Info Parameter log.
++ *    Arguments:
++ *                    pParam  pointer to parameter
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   MakeSysEQInfoLog
++(
++      const MCDRV_SYSEQ_INFO* pParam
++)
++{
++      CHAR    sbStr[80];
++      UINT8   bIdx;
++
++      if(pParam == NULL)
++      {
++              strcat(gsbLogString, " param=NULL");
++              return;
++      }
++
++      sprintf(sbStr, " bOnOff=%02X", pParam->bOnOff);
++      strcat(gsbLogString, sbStr);
++
++      for(bIdx = 0; bIdx < 15; bIdx++)
++      {
++              sprintf(sbStr, " abParam[%d]=%02X", bIdx, pParam->abParam[bIdx]);
++              strcat(gsbLogString, sbStr);
++      }
++}
++
++
++
++
++#endif        /*      MCDRV_DEBUG_LEVEL       */
+diff --git a/sound/soc/codecs/mc1n2/mcdebuglog.h b/sound/soc/codecs/mc1n2/mcdebuglog.h
+new file mode 100644
+index 0000000..f7b9e86
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mcdebuglog.h
+@@ -0,0 +1,31 @@
++/****************************************************************************
++ *
++ *            Copyright(c) 2010 Yamaha Corporation. All rights reserved.
++ *
++ *            Module          : mcdebuglog.h
++ *
++ *            Description     : MC Driver debug log header
++ *
++ *            Version         : 1.0.0         2010.08.16
++ *
++ ****************************************************************************/
++
++#ifndef _MCDEBUGLOB_H_
++#define _MCDEBUGLOG_H_
++
++#include "mcdriver.h"
++#include "mcmachdep.h"
++
++#if MCDRV_DEBUG_LEVEL
++
++
++void          McDebugLog_CmdIn        (UINT32 dCmd, const void* pvParam, UINT32 dUpdateInfo);
++void          McDebugLog_CmdOut       (UINT32 dCmd, const SINT32* psdRet, const void* pvParam);
++
++void          McDebugLog_FuncIn       (void* pvFuncName);
++void          McDebugLog_FuncOut      (void* pvFuncName, const SINT32* psdRet);
++
++
++#endif        /*      MCDRV_DEBUG_LEVEL       */
++
++#endif /* _MCDEBUGLOG_H_ */
+diff --git a/sound/soc/codecs/mc1n2/mcdefs.h b/sound/soc/codecs/mc1n2/mcdefs.h
+new file mode 100644
+index 0000000..fd05382
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mcdefs.h
+@@ -0,0 +1,1160 @@
++/****************************************************************************
++ *
++ *            Copyright(c) 2010 Yamaha Corporation. All rights reserved.
++ *
++ *            Module          : mcdefs.h
++ *
++ *            Description     : MC Device Definitions
++ *
++ *            Version         : 1.0.0         2010.07.05
++ *
++ ****************************************************************************/
++
++#ifndef _MCDEFS_H_
++#define       _MCDEFS_H_
++
++/*    Register Definition
++
++      [Naming Rules]
++
++        MCI_xxx               : Registers
++        MCI_xxx_DEF   : Default setting of registers
++        MCB_xxx               : Miscelleneous bit definition
++*/
++
++/*    Registers       */
++/*    A_ADR   */
++#define       MCI_RST                                         (0)
++#define       MCB_RST                                         (0x01)
++#define       MCI_RST_DEF                                     (MCB_RST)
++
++#define       MCI_BASE_ADR                            (1)
++#define       MCI_BASE_WINDOW                         (2)
++
++#define       MCI_HW_ID                                       (8)
++#define       MCI_HW_ID_DEF                           (0x79)
++
++#define       MCI_ANA_ADR                                     (12)
++#define       MCI_ANA_WINDOW                          (13)
++
++#define       MCI_CD_ADR                                      (14)
++#define       MCI_CD_WINDOW                           (15)
++
++#define       MCI_MIX_ADR                                     (16)
++#define       MCI_MIX_WINDOW                          (17)
++
++#define       MCI_AE_ADR                                      (18)
++#define       MCI_AE_WINDOW                           (19)
++
++#define       MCI_BDSP_ST                                     (20)
++#define       MCB_EQ5ON                                       (0x80)
++#define       MCB_DRCON                                       (0x40)
++#define       MCB_EQ3ON                                       (0x20)
++#define       MCB_DBEXON                                      (0x08)
++#define       MCB_BDSP_ST                                     (0x01)
++
++#define       MCI_BDSP_RST                            (21)
++#define       MCB_TRAM_RST                            (0x02)
++#define       MCB_BDSP_RST                            (0x01)
++
++#define       MCI_BDSP_ADR                            (22)
++#define       MCI_BDSP_WINDOW                         (23)
++
++#define       MCI_CDSP_ADR                            (24)
++#define       MCI_CDSP_WINDOW                         (25)
++
++/*    B_ADR(BASE)     */
++#define       MCI_RSTB                                        (0)
++#define       MCB_RSTB                                        (0x10)
++#define       MCI_RSTB_DEF                            (MCB_RSTB)
++
++#define       MCI_PWM_DIGITAL                         (1)
++#define       MCB_PWM_DP2                                     (0x04)
++#define       MCB_PWM_DP1                                     (0x02)
++#define       MCI_PWM_DIGITAL_DEF                     (MCB_PWM_DP2 | MCB_PWM_DP1)
++
++#define       MCI_PWM_DIGITAL_1                       (3)
++#define       MCB_PWM_DPPDM                           (0x10)
++#define       MCB_PWM_DPDI2                           (0x08)
++#define       MCB_PWM_DPDI1                           (0x04)
++#define       MCB_PWM_DPDI0                           (0x02)
++#define       MCB_PWM_DPB                                     (0x01)
++#define       MCI_PWM_DIGITAL_1_DEF           (MCB_PWM_DPPDM | MCB_PWM_DPDI2 | MCB_PWM_DPDI1 | MCB_PWM_DPDI0 | MCB_PWM_DPB)
++
++#define       MCI_PWM_DIGITAL_CDSP            (4)
++#define       MCB_PWM_DPCDSP                          (0x00)
++#define       MCI_PWM_DIGITAL_CDSP_DEF        (MCB_PWM_DPCDSP)
++
++#define       MCI_PWM_DIGITAL_BDSP            (6)
++#define       MCI_PWM_DIGITAL_BDSP_DEF        (MCB_PWM_DPBDSP)
++#define       MCB_PWM_DPBDSP                          (0x01)
++
++#define       MCI_SD_MSK                                      (9)
++#define       MCB_SDIN_MSK2                           (0x80)
++#define       MCB_SDO_DDR2                            (0x10)
++#define       MCB_SDIN_MSK1                           (0x08)
++#define       MCB_SDO_DDR1                            (0x01)
++#define       MCI_SD_MSK_DEF                          (MCB_SDIN_MSK2 | MCB_SDIN_MSK1)
++
++#define       MCI_SD_MSK_1                            (10)
++#define       MCB_SDIN_MSK0                           (0x80)
++#define       MCB_SDO_DDR0                            (0x10)
++#define       MCI_SD_MSK_1_DEF                        (MCB_SDIN_MSK0)
++
++#define       MCI_BCLK_MSK                            (11)
++#define       MCB_BCLK_MSK2                           (0x80)
++#define       MCB_BCLK_DDR2                           (0x40)
++#define       MCB_LRCK_MSK2                           (0x20)
++#define       MCB_LRCK_DDR2                           (0x10)
++#define       MCB_BCLK_MSK1                           (0x08)
++#define       MCB_BCLK_DDR1                           (0x04)
++#define       MCB_LRCK_MSK1                           (0x02)
++#define       MCB_LRCK_DDR1                           (0x01)
++#define       MCI_BCLK_MSK_DEF                        (MCB_BCLK_MSK2 | MCB_LRCK_MSK2 | MCB_BCLK_MSK1 | MCB_LRCK_MSK1)
++
++#define       MCI_BCLK_MSK_1                          (12)
++#define       MCB_BCLK_MSK0                           (0x80)
++#define       MCB_BCLK_DDR0                           (0x40)
++#define       MCB_LRCK_MSK0                           (0x20)
++#define       MCB_LRCK_DDR0                           (0x10)
++#define       MCB_PCMOUT_HIZ2                         (0x08)
++#define       MCB_PCMOUT_HIZ1                         (0x04)
++#define       MCB_PCMOUT_HIZ0                         (0x02)
++#define       MCB_ROUTER_MS                           (0x01)
++#define       MCI_BCLK_MSK_1_DEF                      (MCB_BCLK_MSK0 | MCB_LRCK_MSK0)
++
++#define       MCI_BCKP                                        (13)
++#define       MCB_DI2_BCKP                            (0x04)
++#define       MCB_DI1_BCKP                            (0x02)
++#define       MCB_DI0_BCKP                            (0x01)
++#define       MCI_BCKP_DEF                            (0)
++
++#define       MCI_BYPASS                                      (21)
++#define       MCB_LOCK1                                       (0x80)
++#define       MCB_LOCK0                                       (0x40)
++#define       MCB_BYPASS1                                     (0x02)
++#define       MCB_BYPASS0                                     (0x01)
++
++#define       MCI_EPA_IRQ                                     (22)
++#define       MCB_EPA2_IRQ                            (0x04)
++#define       MCB_EPA1_IRQ                            (0x02)
++#define       MCB_EPA0_IRQ                            (0x01)
++
++#define       MCI_PA_FLG                                      (23)
++#define       MCB_PA2_FLAG                            (0x04)
++#define       MCB_PA1_FLAG                            (0x02)
++#define       MCB_PA0_FLAG                            (0x01)
++
++#define       MCI_PA_MSK                                      (26)
++#define       MCB_PA1_MSK                                     (0x80)
++#define       MCB_PA1_DDR                                     (0x40)
++#define       MCB_PA0_MSK                                     (0x08)
++#define       MCB_PA0_DDR                                     (0x04)
++#define       MCI_PA_MSK_DEF                          (MCB_PA1_MSK | MCB_PA0_MSK)
++
++#define       MCI_PA_HOST                                     (28)
++#define       MCI_PA_HOST_1                           (29)
++
++#define       MCI_PA_OUT                                      (30)
++#define       MCB_PA_OUT                                      (0x01)
++
++#define       MCI_PA_SCU_PA                           (31)
++#define       MCB_PA_SCU_PA0                          (0x01)
++#define       MCB_PA_SCU_PA1                          (0x02)
++
++/*    B_ADR(MIX)      */
++#define       MCI_DIT_INVFLAGL                        (0)
++#define       MCB_DIT0_INVFLAGL                       (0x20)
++#define       MCB_DIT1_INVFLAGL                       (0x10)
++#define       MCB_DIT2_INVFLAGL                       (0x08)
++
++#define       MCI_DIT_INVFLAGR                        (1)
++#define       MCB_DIT0_INVFLAGR                       (0x20)
++#define       MCB_DIT1_INVFLAGR                       (0x10)
++#define       MCB_DIT2_INVFLAGR                       (0x08)
++
++#define       MCI_DIR_VFLAGL                          (2)
++#define       MCB_PDM0_VFLAGL                         (0x80)
++#define       MCB_DIR0_VFLAGL                         (0x20)
++#define       MCB_DIR1_VFLAGL                         (0x10)
++#define       MCB_DIR2_VFLAGL                         (0x08)
++
++#define       MCI_DIR_VFLAGR                          (3)
++#define       MCB_PDM0_VFLAGR                         (0x80)
++#define       MCB_DIR0_VFLAGR                         (0x20)
++#define       MCB_DIR1_VFLAGR                         (0x10)
++#define       MCB_DIR2_VFLAGR                         (0x08)
++
++#define       MCI_AD_VFLAGL                           (4)
++#define       MCB_ADC_VFLAGL                          (0x80)
++#define       MCB_AENG6_VFLAGL                        (0x20)
++
++#define       MCI_AD_VFLAGR                           (5)
++#define       MCB_ADC_VFLAGR                          (0x80)
++#define       MCB_AENG6_VFLAGR                        (0x20)
++
++#define       MCI_AFLAGL                                      (6)
++#define       MCB_ADC_AFLAGL                          (0x40)
++#define       MCB_DIR0_AFLAGL                         (0x20)
++#define       MCB_DIR1_AFLAGL                         (0x10)
++#define       MCB_DIR2_AFLAGL                         (0x04)
++
++#define       MCI_AFLAGR                                      (7)
++#define       MCB_ADC_AFLAGR                          (0x40)
++#define       MCB_DIR0_AFLAGR                         (0x20)
++#define       MCB_DIR1_AFLAGR                         (0x10)
++#define       MCB_DIR2_AFLAGR                         (0x04)
++
++#define       MCI_DAC_INS_FLAG                        (8)
++#define       MCB_DAC_INS_FLAG                        (0x80)
++
++#define       MCI_INS_FLAG                            (9)
++#define       MCB_ADC_INS_FLAG                        (0x40)
++#define       MCB_DIR0_INS_FLAG                       (0x20)
++#define       MCB_DIR1_INS_FLAG                       (0x10)
++#define       MCB_DIR2_INS_FLAG                       (0x04)
++
++#define       MCI_DAC_FLAGL                           (10)
++#define       MCB_ST_FLAGL                            (0x80)
++#define       MCB_MASTER_OFLAGL                       (0x40)
++#define       MCB_VOICE_FLAGL                         (0x10)
++#define       MCB_DAC_FLAGL                           (0x02)
++
++#define       MCI_DAC_FLAGR                           (11)
++#define       MCB_ST_FLAGR                            (0x80)
++#define       MCB_MASTER_OFLAGR                       (0x40)
++#define       MCB_VOICE_FLAGR                         (0x10)
++#define       MCB_DAC_FLAGR                           (0x02)
++
++#define       MCI_DIT0_INVOLL                         (12)
++#define       MCB_DIT0_INLAT                          (0x80)
++#define       MCB_DIT0_INVOLL                         (0x7F)
++
++#define       MCI_DIT0_INVOLR                         (13)
++#define       MCB_DIT0_INVOLR                         (0x7F)
++
++#define       MCI_DIT1_INVOLL                         (14)
++#define       MCB_DIT1_INLAT                          (0x80)
++#define       MCB_DIT1_INVOLL                         (0x7F)
++
++#define       MCI_DIT1_INVOLR                         (15)
++#define       MCB_DIT1_INVOLR                         (0x7F)
++
++#define       MCI_DIT2_INVOLL                         (16)
++#define       MCB_DIT2_INLAT                          (0x80)
++#define       MCB_DIT2_INVOLL                         (0x7F)
++
++#define       MCI_DIT2_INVOLR                         (17)
++#define       MCB_DIT2_INVOLR                         (0x7F)
++
++#define       MCI_ESRC0_INVOLL                        (16)
++#define       MCI_ESRC0_INVOLR                        (17)
++
++#define       MCI_PDM0_VOLL                           (24)
++#define       MCB_PDM0_LAT                            (0x80)
++#define       MCB_PDM0_VOLL                           (0x7F)
++
++#define       MCI_PDM0_VOLR                           (25)
++#define       MCB_PDM0_VOLR                           (0x7F)
++
++#define       MCI_DIR0_VOLL                           (28)
++#define       MCB_DIR0_LAT                            (0x80)
++#define       MCB_DIR0_VOLL                           (0x7F)
++
++#define       MCI_DIR0_VOLR                           (29)
++#define       MCB_DIR0_VOLR                           (0x7F)
++
++#define       MCI_DIR1_VOLL                           (30)
++#define       MCB_DIR1_LAT                            (0x80)
++#define       MCB_DIR1_VOLL                           (0x7F)
++
++#define       MCI_DIR1_VOLR                           (31)
++#define       MCB_DIR1_VOLR                           (0x7F)
++
++#define       MCI_DIR2_VOLL                           (32)
++#define       MCB_DIR2_LAT                            (0x80)
++#define       MCB_DIR2_VOLL                           (0x7F)
++
++#define       MCI_DIR2_VOLR                           (33)
++#define       MCB_DIR2_VOLR                           (0x7F)
++/*
++#define       MCI_ADC1_VOLL                           (38?)
++#define       MCB_ADC1_LAT                            (0x80)
++#define       MCB_ADC1_VOLL                           (0x7F)
++
++#define       MCI_ADC1_VOLR                           (39?)
++#define       MCB_ADC1_VOLR                           (0x7F)
++*/
++#define       MCI_ADC_VOLL                            (40)
++#define       MCB_ADC_LAT                                     (0x80)
++#define       MCB_ADC_VOLL                            (0x7F)
++
++#define       MCI_ADC_VOLR                            (41)
++#define       MCB_ADC_VOLR                            (0x7F)
++/*
++#define       MCI_DTMFB_VOLL                          (42)
++#define       MCI_DTMFB_VOLR                          (43)
++*/
++#define       MCI_AENG6_VOLL                          (44)
++#define       MCB_AENG6_LAT                           (0x80)
++#define       MCB_AENG6_VOLL                          (0x7F)
++
++#define       MCI_AENG6_VOLR                          (45)
++#define       MCB_AENG6_VOLR                          (0x7F)
++
++#define       MCI_DIT_ININTP                          (50)
++#define       MCB_DIT0_ININTP                         (0x20)
++#define       MCB_DIT1_ININTP                         (0x10)
++#define       MCB_DIT2_ININTP                         (0x08)
++#define       MCI_DIT_ININTP_DEF                      (MCB_DIT0_ININTP | MCB_DIT1_ININTP | MCB_DIT2_ININTP)
++
++#define       MCI_DIR_INTP                            (51)
++#define       MCB_PDM0_INTP                           (0x80)
++#define       MCB_DIR0_INTP                           (0x20)
++#define       MCB_DIR1_INTP                           (0x10)
++#define       MCB_DIR2_INTP                           (0x08)
++#define       MCB_ADC2_INTP                           (0x01)
++#define       MCI_DIR_INTP_DEF                        (MCB_PDM0_INTP | MCB_DIR0_INTP | MCB_DIR1_INTP | MCB_DIR2_INTP)
++
++#define       MCI_ADC_INTP                            (52)
++#define       MCB_ADC_INTP                            (0x80)
++#define       MCB_AENG6_INTP                          (0x20)
++#define       MCI_ADC_INTP_DEF                        (MCB_ADC_INTP | MCB_AENG6_INTP)
++
++#define       MCI_ADC_ATTL                            (54)
++#define       MCB_ADC_ALAT                            (0x80)
++#define       MCB_ADC_ATTL                            (0x7F)
++
++#define       MCI_ADC_ATTR                            (55)
++#define       MCB_ADC_ATTR                            (0x7F)
++
++#define       MCI_DIR0_ATTL                           (56)
++#define       MCB_DIR0_ALAT                           (0x80)
++#define       MCB_DIR0_ATTL                           (0x7F)
++
++#define       MCI_DIR0_ATTR                           (57)
++#define       MCB_DIR0_ATTR                           (0x7F)
++
++#define       MCI_DIR1_ATTL                           (58)
++#define       MCB_DIR1_ALAT                           (0x80)
++#define       MCB_DIR1_ATTL                           (0x7F)
++
++#define       MCI_DIR1_ATTR                           (59)
++#define       MCB_DIR1_ATTR                           (0x7F)
++/*
++#define       MCI_ADC2_ATTL                           (60)
++#define       MCI_ADC2_ATTR                           (61)
++*/
++#define       MCI_DIR2_ATTL                           (62)
++#define       MCB_DIR2_ALAT                           (0x80)
++#define       MCB_DIR2_ATTL                           (0x7F)
++
++#define       MCI_DIR2_ATTR                           (63)
++#define       MCB_DIR2_ATTR                           (0x7F)
++
++#define       MCI_AINTP                                       (72)
++#define       MCB_ADC_AINTP                           (0x40)
++#define       MCB_DIR0_AINTP                          (0x20)
++#define       MCB_DIR1_AINTP                          (0x10)
++#define       MCB_DIR2_AINTP                          (0x04)
++#define       MCI_AINTP_DEF                           (MCB_ADC_AINTP | MCB_DIR0_AINTP | MCB_DIR1_AINTP | MCB_DIR2_AINTP)
++
++#define       MCI_DAC_INS                                     (74)
++#define       MCB_DAC_INS                                     (0x80)
++
++#define       MCI_INS                                         (75)
++#define       MCB_ADC_INS                                     (0x40)
++#define       MCB_DIR0_INS                            (0x20)
++#define       MCB_DIR1_INS                            (0x10)
++#define       MCB_DIR2_INS                            (0x04)
++
++#define       MCI_IINTP                                       (76)
++#define       MCB_DAC_IINTP                           (0x80)
++#define       MCB_ADC_IINTP                           (0x40)
++#define       MCB_DIR0_IINTP                          (0x20)
++#define       MCB_DIR1_IINTP                          (0x10)
++#define       MCB_DIR2_IINTP                          (0x04)
++#define       MCI_IINTP_DEF                           (MCB_DAC_IINTP | MCB_ADC_IINTP | MCB_DIR0_IINTP | MCB_DIR1_IINTP | MCB_DIR2_IINTP)
++
++#define       MCI_ST_VOLL                                     (77)
++#define       MCB_ST_LAT                                      (0x80)
++#define       MCB_ST_VOLL                                     (0x7F)
++
++#define       MCI_ST_VOLR                                     (78)
++#define       MCB_ST_VOLR                                     (0x7F)
++
++#define       MCI_MASTER_OUTL                         (79)
++#define       MCB_MASTER_OLAT                         (0x80)
++#define       MCB_MASTER_OUTL                         (0x7F)
++
++#define       MCI_MASTER_OUTR                         (80)
++#define       MCB_MASTER_OUTR                         (0x7F)
++
++#define       MCI_VOICE_ATTL                          (83)
++#define       MCB_VOICE_LAT                           (0x80)
++#define       MCB_VOICE_ATTL                          (0x7F)
++
++#define       MCI_VOICE_ATTR                          (84)
++#define       MCB_VOICE_ATTR                          (0x7F)
++/*
++#define       MCI_DTMF_ATTL                           (85)
++#define       MCI_DTMF_ATTR                           (86)
++*/
++#define       MCI_DAC_ATTL                            (89)
++#define       MCB_DAC_LAT                                     (0x80)
++#define       MCB_DAC_ATTL                            (0x7F)
++
++#define       MCI_DAC_ATTR                            (90)
++#define       MCB_DAC_ATTR                            (0x7F)
++
++#define       MCI_DAC_INTP                            (93)
++#define       MCB_ST_INTP                                     (0x80)
++#define       MCB_MASTER_OINTP                        (0x40)
++#define       MCB_VOICE_INTP                          (0x10)
++/*#define     MCB_DTMF_INTP                           (0x08)*/
++#define       MCB_DAC_INTP                            (0x02)
++#define       MCI_DAC_INTP_DEF                        (MCB_ST_INTP | MCB_MASTER_OINTP | MCB_VOICE_INTP | MCB_DAC_INTP)
++
++#define       MCI_SOURCE                                      (110)
++#define       MCB_DAC_SOURCE_AD                       (0x10)
++#define       MCB_DAC_SOURCE_DIR2                     (0x20)
++#define       MCB_DAC_SOURCE_DIR0                     (0x30)
++#define       MCB_DAC_SOURCE_DIR1                     (0x40)
++#define       MCB_DAC_SOURCE_MIX                      (0x70)
++#define       MCB_VOICE_SOURCE_AD                     (0x01)
++#define       MCB_VOICE_SOURCE_DIR2           (0x02)
++#define       MCB_VOICE_SOURCE_DIR0           (0x03)
++#define       MCB_VOICE_SOURCE_DIR1           (0x04)
++#define       MCB_VOICE_SOURCE_MIX            (0x07)
++
++#define       MCI_SWP                                         (111)
++
++#define       MCI_SRC_SOURCE                          (112)
++#define       MCB_DIT0_SOURCE_AD                      (0x10)
++#define       MCB_DIT0_SOURCE_DIR2            (0x20)
++#define       MCB_DIT0_SOURCE_DIR0            (0x30)
++#define       MCB_DIT0_SOURCE_DIR1            (0x40)
++#define       MCB_DIT0_SOURCE_MIX                     (0x70)
++#define       MCB_DIT1_SOURCE_AD                      (0x01)
++#define       MCB_DIT1_SOURCE_DIR2            (0x02)
++#define       MCB_DIT1_SOURCE_DIR0            (0x03)
++#define       MCB_DIT1_SOURCE_DIR1            (0x04)
++#define       MCB_DIT1_SOURCE_MIX                     (0x07)
++
++#define       MCI_SRC_SOURCE_1                        (113)
++#define       MCB_AE_SOURCE_AD                        (0x10)
++#define       MCB_AE_SOURCE_DIR2                      (0x20)
++#define       MCB_AE_SOURCE_DIR0                      (0x30)
++#define       MCB_AE_SOURCE_DIR1                      (0x40)
++#define       MCB_AE_SOURCE_MIX                       (0x70)
++#define       MCB_DIT2_SOURCE_AD                      (0x01)
++#define       MCB_DIT2_SOURCE_DIR2            (0x02)
++#define       MCB_DIT2_SOURCE_DIR0            (0x03)
++#define       MCB_DIT2_SOURCE_DIR1            (0x04)
++#define       MCB_DIT2_SOURCE_MIX                     (0x07)
++
++#define       MCI_ESRC_SOURCE                         (114)
++
++#define       MCI_AENG6_SOURCE                        (115)
++#define       MCB_AENG6_ADC0                          (0x00)
++#define       MCB_AENG6_PDM                           (0x01)
++
++#define       MCI_EFIFO_SOURCE                        (116)
++
++#define       MCI_SRC_SOURCE_2                        (117)
++
++#define       MCI_PEAK_METER                          (121)
++
++#define       MCI_OVFL                                        (122)
++#define       MCI_OVFR                                        (123)
++
++#define       MCI_DIMODE0                                     (130)
++
++#define       MCI_DIRSRC_RATE0_MSB            (131)
++
++#define       MCI_DIRSRC_RATE0_LSB            (132)
++
++#define       MCI_DITSRC_RATE0_MSB            (133)
++
++#define       MCI_DITSRC_RATE0_LSB            (134)
++
++#define       MCI_DI_FS0                                      (135)
++
++/*    DI Common Parameter     */
++#define       MCB_DICOMMON_SRC_RATE_SET       (0x01)
++
++#define       MCI_DI0_SRC                                     (136)
++
++#define       MCI_DIX0_START                          (137)
++#define       MCB_DITIM0_START                        (0x40)
++#define       MCB_DIR0_SRC_START                      (0x08)
++#define       MCB_DIR0_START                          (0x04)
++#define       MCB_DIT0_SRC_START                      (0x02)
++#define       MCB_DIT0_START                          (0x01)
++
++#define       MCI_DIX0_FMT                            (142)
++
++#define       MCI_DIR0_CH                                     (143)
++#define       MCI_DIR0_CH_DEF                         (0x10)
++
++#define       MCI_DIT0_SLOT                           (144)
++#define       MCI_DIT0_SLOT_DEF                       (0x10)
++
++#define       MCI_HIZ_REDGE0                          (145)
++
++#define       MCI_PCM_RX0                                     (146)
++#define       MCB_PCM_MONO_RX0                        (0x80)
++#define       MCI_PCM_RX0_DEF                         (MCB_PCM_MONO_RX0)
++
++#define       MCI_PCM_SLOT_RX0                        (147)
++
++#define       MCI_PCM_TX0                                     (148)
++#define       MCB_PCM_MONO_TX0                        (0x80)
++#define       MCI_PCM_TX0_DEF                         (MCB_PCM_MONO_TX0)
++
++#define       MCI_PCM_SLOT_TX0                        (149)
++#define       MCI_PCM_SLOT_TX0_DEF            (0x10)
++
++#define       MCI_DIMODE1                                     (150)
++
++#define       MCI_DIRSRC_RATE1_MSB            (151)
++#define       MCI_DIRSRC_RATE1_LSB            (152)
++
++#define       MCI_DITSRC_RATE1_MSB            (153)
++#define       MCI_DITSRC_RATE1_LSB            (154)
++
++#define       MCI_DI_FS1                                      (155)
++
++#define       MCI_DI1_SRC                                     (156)
++
++#define       MCI_DIX1_START                          (157)
++#define       MCB_DITIM1_START                        (0x40)
++#define       MCB_DIR1_SRC_START                      (0x08)
++#define       MCB_DIR1_START                          (0x04)
++#define       MCB_DIT1_SRC_START                      (0x02)
++#define       MCB_DIT1_START                          (0x01)
++
++#define       MCI_DIX1_FMT                            (162)
++
++#define       MCI_DIR1_CH                                     (163)
++#define       MCB_DIR1_CH1                            (0x10)
++#define       MCI_DIR1_CH_DEF                         (MCB_DIR1_CH1)
++
++#define       MCI_DIT1_SLOT                           (164)
++#define       MCB_DIT1_SLOT1                          (0x10)
++#define       MCI_DIT1_SLOT_DEF                       (MCB_DIT1_SLOT1)
++
++#define       MCI_HIZ_REDGE1                          (165)
++
++#define       MCI_PCM_RX1                                     (166)
++#define       MCB_PCM_MONO_RX1                        (0x80)
++#define       MCI_PCM_RX1_DEF                         (MCB_PCM_MONO_RX1)
++
++#define       MCI_PCM_SLOT_RX1                        (167)
++
++#define       MCI_PCM_TX1                                     (168)
++#define       MCB_PCM_MONO_TX1                        (0x80)
++#define       MCI_PCM_TX1_DEF                         (MCB_PCM_MONO_TX1)
++
++#define       MCI_PCM_SLOT_TX1                        (169)
++#define       MCI_PCM_SLOT_TX1_DEF            (0x10)
++
++#define       MCI_DIMODE2                                     (170)
++
++#define       MCI_DIRSRC_RATE2_MSB            (171)
++#define       MCI_DIRSRC_RATE2_LSB            (172)
++
++#define       MCI_DITSRC_RATE2_MSB            (173)
++#define       MCI_DITSRC_RATE2_LSB            (174)
++
++#define       MCI_DI_FS2                                      (175)
++
++#define       MCI_DI2_SRC                                     (176)
++
++#define       MCI_DIX2_START                          (177)
++#define       MCB_DITIM2_START                        (0x40)
++#define       MCB_DIR2_SRC_START                      (0x08)
++#define       MCB_DIR2_START                          (0x04)
++#define       MCB_DIT2_SRC_START                      (0x02)
++#define       MCB_DIT2_START                          (0x01)
++
++#define       MCI_DIX2_FMT                            (182)
++
++#define       MCI_DIR2_CH                                     (183)
++#define       MCB_DIR2_CH1                            (0x10)
++#define       MCB_DIR2_CH0                            (0x01)
++#define       MCI_DIR2_CH_DEF                         (MCB_DIR2_CH1)
++
++#define       MCI_DIT2_SLOT                           (184)
++#define       MCB_DIT2_SLOT1                          (0x10)
++#define       MCB_DIT2_SLOT0                          (0x01)
++#define       MCI_DIT2_SLOT_DEF                       (MCB_DIT2_SLOT1)
++
++#define       MCI_HIZ_REDGE2                          (185)
++
++#define       MCI_PCM_RX2                                     (186)
++#define       MCB_PCM_MONO_RX2                        (0x80)
++#define       MCI_PCM_RX2_DEF                         (MCB_PCM_MONO_RX2)
++
++#define       MCI_PCM_SLOT_RX2                        (187)
++
++#define       MCI_PCM_TX2                                     (188)
++#define       MCB_PCM_MONO_TX2                        (0x80)
++#define       MCI_PCM_TX2_DEF                         (MCB_PCM_MONO_TX2)
++
++#define       MCI_PCM_SLOT_TX2                        (189)
++#define       MCI_PCM_SLOT_TX2_DEF            (0x10)
++
++#define       MCI_CD_START                            (192)
++
++#define       MCI_CDI_CH                                      (193)
++#define       MCI_CDI_CH_DEF                          (0xE4)
++
++#define       MCI_CDO_SLOT                            (194)
++#define       MCI_CDO_SLOT_DEF                        (0xE4)
++
++#define       MCI_PDM_AGC                                     (200)
++#define       MCI_PDM_AGC_DEF                         (0x03)
++
++#define       MCI_PDM_START                           (202)
++#define       MCB_PDM_MN                                      (0x02)
++#define       MCB_PDM_START                           (0x01)
++
++#define       MCI_PDM_STWAIT                          (205)
++#define       MCI_PDM_STWAIT_DEF                      (0x40)
++
++#define       MCI_HP_ID                                       (206)
++
++#define       MCI_CHP_H                                       (207)
++#define       MCI_CHP_H_DEF                           (0x3F)
++
++#define       MCI_CHP_M                                       (208)
++#define       MCI_CHP_M_DEF                           (0xEA)
++
++#define       MCI_CHP_L                                       (209)
++#define       MCI_CHP_L_DEF                           (0x94)
++
++#define       MCI_SINGEN0_VOL                         (210)
++#define       MCI_SINGEN1_VOL                         (211)
++
++#define       MCI_SINGEN_FREQ0_MSB            (212)
++#define       MCI_SINGEN_FREQ0_LSB            (213)
++
++#define       MCI_SINGEN_FREQ1_MSB            (214)
++#define       MCI_SINGEN_FREQ1_LSB            (215)
++
++#define       MCI_SINGEN_GATETIME                     (216)
++
++#define       MCI_SINGEN_FLAG                         (217)
++
++/*    BADR(AE)        */
++#define       MCI_BAND0_CEQ0                          (0)
++#define       MCI_BAND0_CEQ0_H_DEF            (0x10)
++
++#define       MCI_BAND1_CEQ0                          (15)
++#define       MCI_BAND1_CEQ0_H_DEF            (0x10)
++
++#define       MCI_BAND2_CEQ0                          (30)
++#define       MCI_BAND2_CEQ0_H_DEF            (0x10)
++
++#define       MCI_BAND3H_CEQ0                         (45)
++#define       MCI_BAND3H_CEQ0_H_DEF           (0x10)
++
++#define       MCI_BAND4H_CEQ0                         (75)
++#define       MCI_BAND4H_CEQ0_H_DEF           (0x10)
++
++#define       MCI_BAND5_CEQ0                          (105)
++#define       MCI_BAND5_CEQ0_H_DEF            (0x10)
++
++#define       MCI_BAND6H_CEQ0                         (120)
++#define       MCI_BAND6H_CEQ0_H_DEF           (0x10)
++
++#define       MCI_BAND7H_CEQ0                         (150)
++#define       MCI_BAND7H_CEQ0_H_DEF           (0x10)
++
++#define       MCI_PDM_CHP0_H                          (240)
++#define       MCI_PDM_CHP0_H_DEF                      (0x3F)
++#define       MCI_PDM_CHP0_M                          (241)
++#define       MCI_PDM_CHP0_M_DEF                      (0xEA)
++#define       MCI_PDM_CHP0_L                          (242)
++#define       MCI_PDM_CHP0_L_DEF                      (0x94)
++
++#define       MCI_PDM_CHP1_H                          (243)
++#define       MCI_PDM_CHP1_H_DEF                      (0xC0)
++#define       MCI_PDM_CHP1_M                          (244)
++#define       MCI_PDM_CHP1_M_DEF                      (0x15)
++#define       MCI_PDM_CHP1_L                          (245)
++#define       MCI_PDM_CHP1_L_DEF                      (0x6C)
++
++#define       MCI_PDM_CHP2_H                          (246)
++#define       MCI_PDM_CHP2_H_DEF                      (0x00)
++#define       MCI_PDM_CHP2_M                          (247)
++#define       MCI_PDM_CHP2_M_DEF                      (0x00)
++#define       MCI_PDM_CHP2_L                          (248)
++#define       MCI_PDM_CHP2_L_DEF                      (0x00)
++
++#define       MCI_PDM_CHP3_H                          (249)
++#define       MCI_PDM_CHP3_H_DEF                      (0x3F)
++#define       MCI_PDM_CHP3_M                          (250)
++#define       MCI_PDM_CHP3_M_DEF                      (0xD5)
++#define       MCI_PDM_CHP3_L                          (251)
++#define       MCI_PDM_CHP3_L_DEF                      (0x29)
++
++#define       MCI_PDM_CHP4_H                          (252)
++#define       MCI_PDM_CHP4_H_DEF                      (0x00)
++#define       MCI_PDM_CHP4_M                          (253)
++#define       MCI_PDM_CHP4_M_DEF                      (0x00)
++#define       MCI_PDM_CHP4_L                          (254)
++#define       MCI_PDM_CHP4_L_DEF                      (0x00)
++
++/*    B_ADR(CDSP)     */
++#define       MCI_CDSP_SAVEOFF                        (0)
++
++#define       MCI_OFIFO_LVL                           (1)
++
++#define       MCI_EFIFO_LVL                           (2)
++
++#define       MCI_DEC_POS_24                          (4)
++#define       MCI_DEC_POS_16                          (5)
++#define       MCI_DEC_POS_8                           (6)
++#define       MCI_DEC_POS_0                           (7)
++
++#define       MCI_ENC_POS_24                          (8)
++#define       MCI_ENC_POS_16                          (9)
++#define       MCI_ENC_POS_8                           (10)
++#define       MCI_ENC_POS_0                           (11)
++
++#define       MCI_DEC_ERR                                     (12)
++#define       MCI_ENC_ERR                                     (13)
++
++#define       MCI_FIFO_RST                            (14)
++
++#define       MCI_DEC_ENC_START                       (15)
++
++#define       MCI_FIFO4CH                                     (16)
++
++#define       MCI_DEC_CTL15                           (19)
++
++#define       MCI_DEC_GPR15                           (35)
++
++#define       MCI_DEC_SFR1                            (51)
++#define       MCI_DEC_SFR0                            (52)
++
++#define       MCI_ENC_CTL15                           (53)
++
++#define       MCI_ENC_GPR15                           (69)
++
++#define       MCI_ENC_SFR1                            (85)
++#define       MCI_ENC_SFR0                            (86)
++
++#define       MCI_JOEMP                                       (92)
++#define       MCB_JOEMP                                       (0x80)
++#define       MCB_JOPNT                                       (0x40)
++#define       MCB_OOVF_FLG                            (0x08)
++#define       MCB_OUDF_FLG                            (0x04)
++#define       MCB_OEMP_FLG                            (0x02)
++#define       MCB_OPNT_FLG                            (0x01)
++#define       MCI_JOEMP_DEF                           (MCB_JOEMP | MCB_OEMP_FLG)
++
++#define       MCI_JEEMP                                       (93)
++#define       MCB_JEEMP                                       (0x80)
++#define       MCB_JEPNT                                       (0x40)
++#define       MCB_EOVF_FLG                            (0x08)
++#define       MCB_EUDF_FLG                            (0x04)
++#define       MCB_EEMP_FLG                            (0x02)
++#define       MCB_EPNT_FLG                            (0x01)
++#define       MCI_JEEMP_DEF                           (MCB_JEEMP | MCB_EEMP_FLG)
++
++#define       MCI_DEC_FLG                                     (96)
++#define       MCI_ENC_FLG                                     (97)
++
++#define       MCI_DEC_GPR_FLG                         (98)
++#define       MCI_ENC_GPR_FLG                         (99)
++
++#define       MCI_EOPNT                                       (101)
++
++#define       MCI_EDEC                                        (105)
++#define       MCI_EENC                                        (106)
++
++#define       MCI_EDEC_GPR                            (107)
++#define       MCI_EENC_GPR                            (108)
++
++#define       MCI_CDSP_SRST                           (110)
++#define       MCB_CDSP_FMODE                          (0x10)
++#define       MCB_CDSP_MSAVE                          (0x08)
++#define       MCB_CDSP_SRST                           (0x01)
++#define       MCI_CDSP_SRST_DEF                       (MCB_CDSP_SRST)
++
++#define       MCI_CDSP_SLEEP                          (112)
++
++#define       MCI_CDSP_ERR                            (113)
++
++#define       MCI_CDSP_MAR_MSB                        (114)
++#define       MCI_CDSP_MAR_LSB                        (115)
++
++#define       MCI_OFIFO_IRQ_PNT                       (116)
++
++#define       MCI_EFIFO_IRQ_PNT                       (122)
++
++#define       MCI_CDSP_FLG                            (128)
++
++#define       MCI_ECDSP_ERR                           (129)
++
++/*    B_ADR(CD)       */
++#define       MCI_DPADIF                                      (1)
++#define       MCB_CLKSRC                                      (0x80)
++#define       MCB_CLKBUSY                                     (0x40)
++#define       MCB_CLKINPUT                            (0x20)
++#define       MCB_DPADIF                                      (0x10)
++#define       MCB_DP0_CLKI1                           (0x08)
++#define       MCB_DP0_CLKI0                           (0x01)
++#define       MCI_DPADIF_DEF                          (MCB_DPADIF|MCB_DP0_CLKI1|MCB_DP0_CLKI0)
++
++#define       MCI_CKSEL                                       (4)
++#define       MCB_CK1SEL                                      (0x80)
++#define       MCB_CK0SEL                                      (0x40)
++
++#define       MCI_CD_HW_ID                            (8)
++#define       MCI_CD_HW_ID_DEF                        (0x79)
++
++#define       MCI_PLL_RST                                     (15)
++#define       MCB_PLLRST0                                     (0x01)
++#define       MCI_PLL_RST_DEF                         (MCB_PLLRST0)
++
++#define       MCI_DIVR0                                       (16)
++#define       MCI_DIVR0_DEF                           (0x0D)
++
++#define       MCI_DIVF0                                       (17)
++#define       MCI_DIVF0_DEF                           (0x55)
++
++#define       MCI_DIVR1                                       (18)
++#define       MCI_DIVR1_DEF                           (0x02)
++
++#define       MCI_DIVF1                                       (19)
++#define       MCI_DIVF1_DEF                           (0x48)
++
++#define       MCI_AD_AGC                                      (70)
++#define       MCI_AD_AGC_DEF                          (0x03)
++
++#define       MCI_AD_START                            (72)
++#define       MCI_AD_START_DEF                        (0x00)
++#define       MCB_AD_START                            (0x01)
++
++#define       MCI_DCCUTOFF                            (77)
++#define       MCI_DCCUTOFF_DEF                        (0x00)
++
++#define       MCI_DAC_CONFIG                          (78)
++#define       MCI_DAC_CONFIG_DEF                      (0x02)
++#define       MCB_NSMUTE                                      (0x02)
++#define       MCB_DACON                                       (0x01)
++
++#define       MCI_DCL                                         (79)
++#define       MCI_DCL_DEF                                     (0x00)
++
++#define       MCI_SYS_CEQ0_19_12                      (80)
++#define       MCI_SYS_CEQ0_19_12_DEF          (0x10)
++
++#define       MCI_SYS_CEQ0_11_4                       (81)
++#define       MCI_SYS_CEQ0_11_4_DEF           (0xC4)
++
++#define       MCI_SYS_CEQ0_3_0                        (82)
++#define       MCI_SYS_CEQ0_3_0_DEF            (0x50)
++
++#define       MCI_SYS_CEQ1_19_12                      (83)
++#define       MCI_SYS_CEQ1_19_12_DEF          (0x12)
++
++#define       MCI_SYS_CEQ1_11_4                       (84)
++#define       MCI_SYS_CEQ1_11_4_DEF           (0xC4)
++
++#define       MCI_SYS_CEQ1_3_0                        (85)
++#define       MCI_SYS_CEQ1_3_0_DEF            (0x40)
++
++#define       MCI_SYS_CEQ2_19_12                      (86)
++#define       MCI_SYS_CEQ2_19_12_DEF          (0x02)
++
++#define       MCI_SYS_CEQ2_11_4                       (87)
++#define       MCI_SYS_CEQ2_11_4_DEF           (0xA9)
++
++#define       MCI_SYS_CEQ2_3_0                        (88)
++#define       MCI_SYS_CEQ2_3_0_DEF            (0x60)
++
++#define       MCI_SYS_CEQ3_19_12                      (89)
++#define       MCI_SYS_CEQ3_19_12_DEF          (0xED)
++
++#define       MCI_SYS_CEQ3_11_4                       (90)
++#define       MCI_SYS_CEQ3_11_4_DEF           (0x3B)
++
++#define       MCI_SYS_CEQ3_3_0                        (91)
++#define       MCI_SYS_CEQ3_3_0_DEF            (0xC0)
++
++#define       MCI_SYS_CEQ4_19_12                      (92)
++#define       MCI_SYS_CEQ4_19_12_DEF          (0xFC)
++
++#define       MCI_SYS_CEQ4_11_4                       (93)
++#define       MCI_SYS_CEQ4_11_4_DEF           (0x92)
++
++#define       MCI_SYS_CEQ4_3_0                        (94)
++#define       MCI_SYS_CEQ4_3_0_DEF            (0x40)
++
++#define       MCI_SYSTEM_EQON                         (95)
++#define       MCB_SYSEQ_INTP                          (0x20)
++#define       MCB_SYSEQ_FLAG                          (0x10)
++#define       MCB_SYSTEM_EQON                         (0x01)
++#define       MCI_SYSTEM_EQON_DEF                     (MCB_SYSEQ_INTP|MCB_SYSTEM_EQON)
++
++/*    B_ADR(ANA)      */
++#define       MCI_ANA_RST                                     (0)
++#define       MCI_ANA_RST_DEF                         (0x01)
++
++#define       MCI_PWM_ANALOG_0                        (2)
++#define       MCB_PWM_VR                                      (0x01)
++#define       MCB_PWM_CP                                      (0x02)
++#define       MCB_PWM_REFA                            (0x04)
++#define       MCB_PWM_LDOA                            (0x08)
++#define       MCI_PWM_ANALOG_0_DEF            (MCB_PWM_VR|MCB_PWM_CP|MCB_PWM_REFA|MCB_PWM_LDOA)
++
++#define       MCI_PWM_ANALOG_1                        (3)
++#define       MCB_PWM_SPL1                            (0x01)
++#define       MCB_PWM_SPL2                            (0x02)
++#define       MCB_PWM_SPR1                            (0x04)
++#define       MCB_PWM_SPR2                            (0x08)
++#define       MCB_PWM_HPL                                     (0x10)
++#define       MCB_PWM_HPR                                     (0x20)
++#define       MCB_PWM_ADL                                     (0x40)
++#define       MCB_PWM_ADR                                     (0x80)
++#define       MCI_PWM_ANALOG_1_DEF            (MCB_PWM_SPL1|MCB_PWM_SPL2|MCB_PWM_SPR1|MCB_PWM_SPR2|MCB_PWM_HPL|MCB_PWM_HPR|MCB_PWM_ADL|MCB_PWM_ADR)
++
++#define       MCI_PWM_ANALOG_2                        (4)
++#define       MCB_PWM_LO1L                            (0x01)
++#define       MCB_PWM_LO1R                            (0x02)
++#define       MCB_PWM_LO2L                            (0x04)
++#define       MCB_PWM_LO2R                            (0x08)
++#define       MCB_PWM_RC1                                     (0x10)
++#define       MCB_PWM_RC2                                     (0x20)
++#define       MCI_PWM_ANALOG_2_DEF            (MCB_PWM_LO1L|MCB_PWM_LO1R|MCB_PWM_LO2L|MCB_PWM_LO2R|MCB_PWM_RC1|MCB_PWM_RC2)
++
++#define       MCI_PWM_ANALOG_3                        (5)
++#define       MCB_PWM_MB1                                     (0x01)
++#define       MCB_PWM_MB2                                     (0x02)
++#define       MCB_PWM_MB3                                     (0x04)
++#define       MCB_PWM_DAL                                     (0x08)
++#define       MCB_PWM_DAR                                     (0x10)
++#define       MCI_PWM_ANALOG_3_DEF            (MCB_PWM_MB1|MCB_PWM_MB2|MCB_PWM_MB3|MCB_PWM_DAL|MCB_PWM_DAR)
++
++#define       MCI_PWM_ANALOG_4                        (6)
++#define       MCB_PWM_MC1                                     (0x10)
++#define       MCB_PWM_MC2                                     (0x20)
++#define       MCB_PWM_MC3                                     (0x40)
++#define       MCB_PWM_LI                                      (0x80)
++#define       MCI_PWM_ANALOG_4_DEF            (MCB_PWM_MC1|MCB_PWM_MC2|MCB_PWM_MC3|MCB_PWM_LI)
++
++#define       MCI_BUSY1                                       (12)
++#define       MCB_RC_BUSY                                     (0x20)
++#define       MCB_HPL_BUSY                            (0x10)
++#define       MCB_SPL_BUSY                            (0x08)
++
++#define       MCI_BUSY2                                       (13)
++#define       MCB_HPR_BUSY                            (0x10)
++#define       MCB_SPR_BUSY                            (0x08)
++
++#define       MCI_APMOFF                                      (16)
++#define       MCB_APMOFF_SP                           (0x01)
++#define       MCB_APMOFF_HP                           (0x02)
++#define       MCB_APMOFF_RC                           (0x04)
++
++#define       MCI_DIF_LINE                            (24)
++#define       MCI_DIF_LINE_DEF                        (0x00)
++
++#define       MCI_LI1VOL_L                            (25)
++#define       MCI_LI1VOL_L_DEF                        (0x00)
++#define       MCB_ALAT_LI1                            (0x40)
++#define       MCB_LI1VOL_L                            (0x1F)
++
++#define       MCI_LI1VOL_R                            (26)
++#define       MCI_LI1VOL_R_DEF                        (0x00)
++#define       MCB_LI1VOL_R                            (0x1F)
++
++#define       MCI_LI2VOL_L                            (27)
++#define       MCI_LI2VOL_L_DEF                        (0x00)
++#define       MCB_ALAT_LI2                            (0x40)
++#define       MCB_LI2VOL_L                            (0x1F)
++
++#define       MCI_LI2VOL_R                            (28)
++#define       MCI_LI2VOL_R_DEF                        (0x00)
++#define       MCB_LI2VOL_R                            (0x1F)
++
++#define       MCI_MC1VOL                                      (29)
++#define       MCI_MC1VOL_DEF                          (0x00)
++#define       MCB_MC1VOL                                      (0x1F)
++
++#define       MCI_MC2VOL                                      (30)
++#define       MCI_MC2VOL_DEF                          (0x00)
++#define       MCB_MC2VOL                                      (0x1F)
++
++#define       MCI_MC3VOL                                      (31)
++#define       MCI_MC3VOL_DEF                          (0x00)
++#define       MCB_MC3VOL                                      (0x1F)
++
++#define       MCI_ADVOL_L                                     (32)
++#define       MCI_ADVOL_L_DEF                         (0x00)
++#define       MCB_ALAT_AD                                     (0x40)
++#define       MCB_ADVOL_L                                     (0x1F)
++
++#define       MCI_ADVOL_R                                     (33)
++#define       MCB_ADVOL_R                                     (0x1F)
++
++#define       MCI_HPVOL_L                                     (35)
++#define       MCB_ALAT_HP                                     (0x40)
++#define       MCB_SVOL_HP                                     (0x20)
++#define       MCB_HPVOL_L                                     (0x1F)
++#define       MCI_HPVOL_L_DEF                         (MCB_SVOL_HP)
++
++#define       MCI_HPVOL_R                                     (36)
++#define       MCI_HPVOL_R_DEF                         (0x00)
++#define       MCB_HPVOL_R                                     (0x1F)
++
++#define       MCI_SPVOL_L                                     (37)
++#define       MCB_ALAT_SP                                     (0x40)
++#define       MCB_SVOL_SP                                     (0x20)
++#define       MCB_SPVOL_L                                     (0x1F)
++#define       MCI_SPVOL_L_DEF                         (MCB_SVOL_SP)
++
++#define       MCI_SPVOL_R                                     (38)
++#define       MCI_SPVOL_R_DEF                         (0x00)
++#define       MCB_SPVOL_R                                     (0x1F)
++
++#define       MCI_RCVOL                                       (39)
++#define       MCB_SVOL_RC                                     (0x20)
++#define       MCB_RCVOL                                       (0x1F)
++#define       MCI_RCVOL_DEF                           (MCB_SVOL_RC)
++
++#define       MCI_LO1VOL_L                            (40)
++#define       MCI_LO1VOL_L_DEF                        (0x20)
++#define       MCB_ALAT_LO1                            (0x40)
++#define       MCB_LO1VOL_L                            (0x1F)
++
++#define       MCI_LO1VOL_R                            (41)
++#define       MCI_LO1VOL_R_DEF                        (0x00)
++#define       MCB_LO1VOL_R                            (0x1F)
++
++#define       MCI_LO2VOL_L                            (42)
++#define       MCI_LO2VOL_L_DEF                        (0x20)
++#define       MCB_ALAT_LO2                            (0x40)
++#define       MCB_LO2VOL_L                            (0x1F)
++
++#define       MCI_LO2VOL_R                            (43)
++#define       MCI_LO2VOL_R_DEF                        (0x00)
++#define       MCB_LO2VOL_R                            (0x1F)
++
++#define       MCI_SP_MODE                                     (44)
++#define       MCB_SPR_HIZ                                     (0x20)
++#define       MCB_SPL_HIZ                                     (0x10)
++#define       MCB_SPMN                                        (0x02)
++#define       MCB_SP_SWAP                                     (0x01)
++
++#define       MCI_MC_GAIN                                     (45)
++#define       MCI_MC_GAIN_DEF                         (0x00)
++#define       MCB_MC2SNG                                      (0x40)
++#define       MCB_MC2GAIN                                     (0x30)
++#define       MCB_MC1SNG                                      (0x04)
++#define       MCB_MC1GAIN                                     (0x03)
++
++#define       MCI_MC3_GAIN                            (46)
++#define       MCI_MC3_GAIN_DEF                        (0x00)
++#define       MCB_MC3SNG                                      (0x04)
++#define       MCB_MC3GAIN                                     (0x03)
++
++#define       MCI_RDY_FLAG                            (47)
++#define       MCB_LDO_RDY                                     (0x80)
++#define       MCB_VREF_RDY                            (0x40)
++#define       MCB_SPRDY_R                                     (0x20)
++#define       MCB_SPRDY_L                                     (0x10)
++#define       MCB_HPRDY_R                                     (0x08)
++#define       MCB_HPRDY_L                                     (0x04)
++#define       MCB_CPPDRDY                                     (0x02)
++
++/*    analog mixer common */
++#define       MCB_LI1MIX                                      (0x01)
++#define       MCB_M1MIX                                       (0x08)
++#define       MCB_M2MIX                                       (0x10)
++#define       MCB_M3MIX                                       (0x20)
++#define       MCB_DAMIX                                       (0x40)
++#define       MCB_DARMIX                                      (0x40)
++#define       MCB_DALMIX                                      (0x80)
++
++#define       MCB_MONO_DA                                     (0x40)
++#define       MCB_MONO_LI1                            (0x01)
++
++#define       MCI_ADL_MIX                                     (50)
++#define       MCI_ADL_MONO                            (51)
++#define       MCI_ADR_MIX                                     (52)
++#define       MCI_ADR_MONO                            (53)
++
++#define       MCI_LO1L_MIX                            (55)
++#define       MCI_LO1L_MONO                           (56)
++#define       MCI_LO1R_MIX                            (57)
++
++#define       MCI_LO2L_MIX                            (58)
++#define       MCI_LO2L_MONO                           (59)
++#define       MCI_LO2R_MIX                            (60)
++
++#define       MCI_HPL_MIX                                     (61)
++#define       MCI_HPL_MONO                            (62)
++#define       MCI_HPR_MIX                                     (63)
++
++#define       MCI_SPL_MIX                                     (64)
++#define       MCI_SPL_MONO                            (65)
++#define       MCI_SPR_MIX                                     (66)
++#define       MCI_SPR_MONO                            (67)
++
++#define       MCI_RC_MIX                                      (69)
++
++#define       MCI_CPMOD                                       (72)
++
++#define       MCI_HP_GAIN                                     (77)
++
++#define       MCI_LEV                                         (79)
++#define       MCB_AVDDLEV                                     (0x07)
++#define       MCI_LEV_DEF                                     (0x24)
++
++#define       MCI_DNGATRT_HP                          (82)
++#define       MCI_DNGATRT_HP_DEF                      (0x23)
++
++#define       MCI_DNGTARGET_HP                        (83)
++#define       MCI_DNGTARGET_HP_DEF            (0x50)
++
++#define       MCI_DNGON_HP                            (84)
++#define       MCI_DNGON_HP_DEF                        (0x54)
++
++#define       MCI_DNGATRT_SP                          (85)
++#define       MCI_DNGATRT_SP_DEF                      (0x23)
++
++#define       MCI_DNGTARGET_SP                        (86)
++#define       MCI_DNGTARGET_SP_DEF            (0x50)
++
++#define       MCI_DNGON_SP                            (87)
++#define       MCI_DNGON_SP_DEF                        (0x54)
++
++#define       MCI_DNGATRT_RC                          (88)
++#define       MCI_DNGATRT_RC_DEF                      (0x23)
++
++#define       MCI_DNGTARGET_RC                        (89)
++#define       MCI_DNGTARGET_RC_DEF            (0x50)
++
++#define       MCI_DNGON_RC                            (90)
++#define       MCI_DNGON_RC_DEF                        (0x54)
++
++#define       MCI_AP_A1                                       (123)
++#define       MCB_AP_CP_A                                     (0x10)
++#define       MCB_AP_HPL_A                            (0x02)
++#define       MCB_AP_HPR_A                            (0x01)
++
++#define       MCI_AP_A2                                       (124)
++#define       MCB_AP_RC1_A                            (0x20)
++#define       MCB_AP_RC2_A                            (0x10)
++#define       MCB_AP_SPL1_A                           (0x08)
++#define       MCB_AP_SPR1_A                           (0x04)
++#define       MCB_AP_SPL2_A                           (0x02)
++#define       MCB_AP_SPR2_A                           (0x01)
++
++#endif /* __MCDEFS_H__ */
+diff --git a/sound/soc/codecs/mc1n2/mcdevif.c b/sound/soc/codecs/mc1n2/mcdevif.c
+new file mode 100644
+index 0000000..00a2224
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mcdevif.c
+@@ -0,0 +1,317 @@
++/****************************************************************************
++ *
++ *            Copyright(c) 2010 Yamaha Corporation. All rights reserved.
++ *
++ *            Module          : mcdevif.c
++ *
++ *            Description     : MC Driver device interface
++ *
++ *            Version         : 1.0.0         2010.09.10
++ *
++ ****************************************************************************/
++
++
++#include "mcdevif.h"
++#include "mcservice.h"
++#include "mcresctrl.h"
++#include "mcmachdep.h"
++#if MCDRV_DEBUG_LEVEL
++#include "mcdebuglog.h"
++#endif
++
++
++
++static MCDRV_PACKET*  gpsPacket       = NULL;
++
++/****************************************************************************
++ *    McDevIf_AllocPacketBuf
++ *
++ *    Description:
++ *                    allocate the buffer for register setting packets.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR
++ *
++ ****************************************************************************/
++SINT32        McDevIf_AllocPacketBuf
++(
++      void
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McDevIf_AllocPacketBuf");
++#endif
++
++      gpsPacket       = McResCtrl_AllocPacketBuf();
++      if(gpsPacket == NULL)
++      {
++              sdRet   = MCDRV_ERROR;
++      }
++      else
++      {
++              McDevIf_ClearPacket();
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McDevIf_AllocPacketBuf", &sdRet);
++#endif
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    McDevIf_ReleasePacketBuf
++ *
++ *    Description:
++ *                    Release the buffer for register setting packets.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McDevIf_ReleasePacketBuf
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McDevIf_ReleasePacketBuf");
++#endif
++
++      McResCtrl_ReleasePacketBuf();
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McDevIf_ReleasePacketBuf", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McDevIf_ClearPacket
++ *
++ *    Description:
++ *                    Clear packets.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McDevIf_ClearPacket
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("McDevIf_ClearPacket");
++#endif
++
++      if(gpsPacket == NULL)
++      {
++              #if (MCDRV_DEBUG_LEVEL>=4)
++                      sdRet   = MCDRV_ERROR;
++                      McDebugLog_FuncOut("McDevIf_ClearPacket", &sdRet);
++              #endif
++              return;
++      }
++
++      gpsPacket[0].dDesc = MCDRV_PACKET_TYPE_TERMINATE;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McDevIf_ClearPacket", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McDevIf_AddPacket
++ *
++ *    Description:
++ *                    Add a packet.
++ *    Arguments:
++ *                    dDesc           packet info
++ *                    bData           packet data
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McDevIf_AddPacket
++(
++      UINT32                  dDesc,
++      UINT8                   bData
++)
++{
++      UINT32  i;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McDevIf_AddPacket");
++#endif
++
++      if(gpsPacket == NULL)
++      {
++      }
++      else
++      {
++              for(i = 0; i < MCDRV_MAX_PACKETS; i++)
++              {
++                      if(gpsPacket[i].dDesc == MCDRV_PACKET_TYPE_TERMINATE)
++                      {
++                              break;
++                      }
++              }
++              if(i >= MCDRV_MAX_PACKETS)
++              {
++                      McDevIf_ExecutePacket();
++                      i       = 0;
++              }
++
++              gpsPacket[i].dDesc              = dDesc;
++              gpsPacket[i].bData              = bData;
++              gpsPacket[i+1UL].dDesc  = MCDRV_PACKET_TYPE_TERMINATE;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McDevIf_AddPacket", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McDevIf_AddPacketRepeat
++ *
++ *    Description:
++ *                    Add packets to set data at same register over agian.
++ *    Arguments:
++ *                    dDesc                   packet info
++ *                    pbData                  poointer to packet data
++ *                    wDataCount              packet data count
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McDevIf_AddPacketRepeat
++(
++      UINT32                  dDesc,
++      const UINT8*    pbData,
++      UINT16                  wDataCount
++)
++{
++      UINT16  wCount;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McDevIf_AddPacketRepeat");
++#endif
++
++      for(wCount = 0; wCount < wDataCount; wCount++)
++      {
++              McDevIf_AddPacket(dDesc, pbData[wCount]);
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McDevIf_AddPacketRepeat", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McDevIf_ExecutePacket
++ *
++ *    Description:
++ *                    Execute sequence for register setting.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++SINT32        McDevIf_ExecutePacket
++(
++      void
++)
++{
++      SINT32  sdRet;
++      SINT16  swPacketIndex;
++      UINT32  dPacketType;
++      UINT32  dParam1;
++      UINT32  dParam2;
++      UINT16  wAddress;
++      UINT16  wRegType;
++      MCDRV_UPDATE_MODE       eUpdateMode;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McDevIf_ExecutePacket");
++#endif
++
++      if(gpsPacket == NULL)
++      {
++              sdRet   = MCDRV_ERROR_RESOURCEOVER;
++      }
++      else
++      {
++              sdRet   = MCDRV_SUCCESS;
++
++              McResCtrl_InitRegUpdate();
++              swPacketIndex = 0;
++              while ((MCDRV_PACKET_TYPE_TERMINATE != (gpsPacket[swPacketIndex].dDesc & MCDRV_PACKET_TYPE_MASK)) && (sdRet == MCDRV_SUCCESS))
++              {
++                      dPacketType = gpsPacket[swPacketIndex].dDesc & MCDRV_PACKET_TYPE_MASK;
++                      switch (dPacketType)
++                      {
++                      case MCDRV_PACKET_TYPE_WRITE:
++                      case MCDRV_PACKET_TYPE_FORCE_WRITE:
++                              wRegType = (UINT16)(gpsPacket[swPacketIndex].dDesc & MCDRV_PACKET_REGTYPE_MASK);
++                              wAddress = (UINT16)(gpsPacket[swPacketIndex].dDesc & MCDRV_PACKET_ADR_MASK);
++                              if (MCDRV_PACKET_TYPE_WRITE == dPacketType)
++                              {
++                                      eUpdateMode = eMCDRV_UPDATE_NORMAL;
++                              }
++                              else if (MCDRV_PACKET_TYPE_FORCE_WRITE == dPacketType)
++                              {
++                                      eUpdateMode = eMCDRV_UPDATE_FORCE;
++                              }
++                              else
++                              {
++                                      eUpdateMode = eMCDRV_UPDATE_DUMMY;
++                              }
++                              McResCtrl_AddRegUpdate(wRegType, wAddress, gpsPacket[swPacketIndex].bData, eUpdateMode);
++                              break;
++
++                      case MCDRV_PACKET_TYPE_TIMWAIT:
++                              McResCtrl_ExecuteRegUpdate();
++                              McResCtrl_InitRegUpdate();
++                              dParam1 = gpsPacket[swPacketIndex].dDesc & MCDRV_PACKET_TIME_MASK;
++                              McSrv_Sleep(dParam1);
++                              break;
++
++                      case MCDRV_PACKET_TYPE_EVTWAIT:
++                              McResCtrl_ExecuteRegUpdate();
++                              McResCtrl_InitRegUpdate();
++                              dParam1 = gpsPacket[swPacketIndex].dDesc & MCDRV_PACKET_EVT_MASK;
++                              dParam2 = gpsPacket[swPacketIndex].dDesc & MCDRV_PACKET_EVTPRM_MASK;
++                              sdRet = McResCtrl_WaitEvent(dParam1, dParam2);
++                              break;
++
++                      default:
++                              sdRet   = MCDRV_ERROR;
++                              break;
++                      }
++
++                      swPacketIndex++;
++              }
++              if(sdRet == MCDRV_SUCCESS)
++              {
++                      McResCtrl_ExecuteRegUpdate();
++              }
++              McDevIf_ClearPacket();
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McDevIf_ExecutePacket", &sdRet);
++#endif
++
++      return sdRet;
++}
++
+diff --git a/sound/soc/codecs/mc1n2/mcdevif.h b/sound/soc/codecs/mc1n2/mcdevif.h
+new file mode 100644
+index 0000000..b51383a
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mcdevif.h
+@@ -0,0 +1,81 @@
++/****************************************************************************
++ *
++ *            Copyright(c) 2010 Yamaha Corporation. All rights reserved.
++ *
++ *            Module          : mcdevif.h
++ *
++ *            Description     : MC Driver device interface header
++ *
++ *            Version         : 1.0.0         2010.07.05
++ *
++ ****************************************************************************/
++
++#ifndef _MCDEVIF_H_
++#define _MCDEVIF_H_
++
++#include "mctypedef.h"
++#include "mcdriver.h"
++
++/* packet */
++typedef struct
++{
++      UINT32  dDesc;
++      UINT8   bData;
++} MCDRV_PACKET;
++
++#define       MCDRV_MAX_PACKETS                                       (256UL)
++
++/*    packet dDesc    */
++/*    packet type     */
++#define       MCDRV_PACKET_TYPE_WRITE                         (0x10000000UL)
++#define       MCDRV_PACKET_TYPE_FORCE_WRITE           (0x20000000UL)
++#define       MCDRV_PACKET_TYPE_TIMWAIT                       (0x30000000UL)
++#define       MCDRV_PACKET_TYPE_EVTWAIT                       (0x40000000UL)
++#define       MCDRV_PACKET_TYPE_TERMINATE                     (0xF0000000UL)
++
++#define       MCDRV_PACKET_TYPE_MASK                          (0xF0000000UL)
++
++/*    reg type        */
++#define       MCDRV_PACKET_REGTYPE_A                          (0x00000000UL)
++#define       MCDRV_PACKET_REGTYPE_B_BASE                     (0x00001000UL)
++#define       MCDRV_PACKET_REGTYPE_B_MIXER            (0x00002000UL)
++#define       MCDRV_PACKET_REGTYPE_B_AE                       (0x00003000UL)
++#define       MCDRV_PACKET_REGTYPE_B_CDSP                     (0x00004000UL)
++#define       MCDRV_PACKET_REGTYPE_B_CODEC            (0x00005000UL)
++#define       MCDRV_PACKET_REGTYPE_B_ANA                      (0x00006000UL)
++
++#define       MCDRV_PACKET_REGTYPE_MASK                       (0x0000F000UL)
++#define       MCDRV_PACKET_ADR_MASK                           (0x00000FFFUL)
++
++/*    event   */
++#define       MCDRV_EVT_INSFLG                                        (0x00010000UL)
++#define       MCDRV_EVT_ALLMUTE                                       (0x00020000UL)
++#define       MCDRV_EVT_DACMUTE                                       (0x00030000UL)
++#define       MCDRV_EVT_DITMUTE                                       (0x00040000UL)
++#define       MCDRV_EVT_SVOL_DONE                                     (0x00050000UL)
++#define       MCDRV_EVT_APM_DONE                                      (0x00060000UL)
++#define       MCDRV_EVT_ANA_RDY                                       (0x00070000UL)
++#define       MCDRV_EVT_SYSEQ_FLAG_RESET                      (0x00080000UL)
++#define       MCDRV_EVT_CLKBUSY_RESET                         (0x00090000UL)
++#define       MCDRV_EVT_CLKSRC_SET                            (0x000A0000UL)
++#define       MCDRV_EVT_CLKSRC_RESET                          (0x000B0000UL)
++#define MCDRV_EVT_ADCMUTE                                     (0x000C0000UL)
++
++
++#define       MCDRV_PACKET_EVT_MASK                           (0x0FFF0000UL)
++#define       MCDRV_PACKET_EVTPRM_MASK                        (0x0000FFFFUL)
++
++/*    timer   */
++#define       MCDRV_PACKET_TIME_MASK                          (0x0FFFFFFFUL)
++
++
++
++SINT32                McDevIf_AllocPacketBuf          (void);
++void          McDevIf_ReleasePacketBuf        (void);
++void          McDevIf_ClearPacket                     (void);
++void          McDevIf_AddPacket                       (UINT32 dDesc, UINT8 bData);
++void          McDevIf_AddPacketRepeat         (UINT32 dDesc, const UINT8* pbData, UINT16 wDataCount);
++SINT32                McDevIf_ExecutePacket           (void);
++
++
++#endif /* _MCDEVIF_H_ */
+diff --git a/sound/soc/codecs/mc1n2/mcdevprof.c b/sound/soc/codecs/mc1n2/mcdevprof.c
+new file mode 100644
+index 0000000..ece8349
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mcdevprof.c
+@@ -0,0 +1,131 @@
++/****************************************************************************
++ *
++ *            Copyright(c) 2010 Yamaha Corporation. All rights reserved.
++ *
++ *            Module          : mcdevprof.c
++ *
++ *            Description     : MC Driver device profile
++ *
++ *            Version         : 1.0.0         2010.09.10
++ *
++ ****************************************************************************/
++
++
++#include "mcdevprof.h"
++#include "mcmachdep.h"
++#if MCDRV_DEBUG_LEVEL
++#include "mcdebuglog.h"
++#endif
++
++
++static        MCDRV_DEV_ID    geDevID = eMCDRV_DEV_ID_1N2;
++
++static        UINT8   gabValid[][3]   =
++{
++/*    MC-1N2  MC-2N   MC-3N   */
++      {0,             0,              1},             /*      DI2             */
++      {0,             0,              1},             /*      RANGE   */
++      {0,             0,              1},             /*      BYPASS  */
++      {0,             0,              1},             /*      ADC1    */
++      {0,             0,              0},             /*      PAD2    */
++      {0,             1,              1},             /*      DBEX    */
++      {0,             0,              1},             /*      GPMODE  */
++      {0,             0,              1},             /*      DTMF    */
++      {0,             0,              1},             /*      IRQ             */
++};
++
++static UINT8  gabSlaveAddr[3][2]      =
++{
++/*    Digital Analog  */
++      {0x3A,  0x3A},  /*      MC1N2   */
++      {0x00,  0x00},  /*      MC2N    */
++      {0x00,  0x00}   /*      MC3N    */
++};
++
++/****************************************************************************
++ *    McDevProf_SetDevId
++ *
++ *    Description:
++ *                    Set device ID.
++ *    Arguments:
++ *                    eDevId  device ID
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McDevProf_SetDevId(MCDRV_DEV_ID eDevId)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McDevProf_SetDevId");
++#endif
++
++      geDevID = eDevId;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McDevProf_SetDevId", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McDevProf_IsValid
++ *
++ *    Description:
++ *                    Validity function.
++ *    Arguments:
++ *                    function kind
++ *    Return:
++ *                    0:Invalid/1:Valid
++ *
++ ****************************************************************************/
++UINT8 McDevProf_IsValid
++(
++      MCDRV_FUNC_KIND eFuncKind
++)
++{
++      UINT8   bData;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("McDevProf_IsValid");
++#endif
++
++      bData   = gabValid[eFuncKind][geDevID];
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = (SINT32)bData;
++      McDebugLog_FuncOut("McDevProf_IsValid", &sdRet);
++#endif
++      return bData;
++}
++
++/****************************************************************************
++ *    McDevProf_GetSlaveAddr
++ *
++ *    Description:
++ *                    get slave address.
++ *    Arguments:
++ *                    eSlaveAddrKind  slave address kind
++ *    Return:
++ *                    slave address
++ *
++ ****************************************************************************/
++UINT8 McDevProf_GetSlaveAddr
++(
++      MCDRV_SLAVE_ADDR_KIND eSlaveAddrKind
++)
++{
++      UINT8   bData   = gabSlaveAddr[geDevID][eSlaveAddrKind];
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("McDevProf_GetSlaveAddr");
++#endif
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = (SINT32)bData;
++      McDebugLog_FuncOut("McDevProf_GetSlaveAddr", &sdRet);
++#endif
++
++      return bData;
++}
++
+diff --git a/sound/soc/codecs/mc1n2/mcdevprof.h b/sound/soc/codecs/mc1n2/mcdevprof.h
+new file mode 100644
+index 0000000..6c1c166
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mcdevprof.h
+@@ -0,0 +1,53 @@
++/****************************************************************************
++ *
++ *            Copyright(c) 2010 Yamaha Corporation. All rights reserved.
++ *
++ *            Module          : mcdevprof.h
++ *
++ *            Description     : MC Driver device profile header
++ *
++ *            Version         : 1.0.0         2010.07.05
++ *
++ ****************************************************************************/
++
++#ifndef _MCDEVPROF_H_
++#define _MCDEVPROF_H_
++
++#include "mctypedef.h"
++
++typedef enum
++{
++      eMCDRV_DEV_ID_1N2       = 0,
++      eMCDRV_DEV_ID_2N,
++      eMCDRV_DEV_ID_3N
++} MCDRV_DEV_ID;
++
++typedef enum
++{
++      eMCDRV_FUNC_LI2 = 0,
++      eMCDRV_FUNC_RANGE,
++      eMCDRV_FUNC_BYPASS,
++      eMCDRV_FUNC_ADC1,
++      eMCDRV_FUNC_PAD2,
++      eMCDRV_FUNC_DBEX,
++      eMCDRV_FUNC_GPMODE,
++      eMCDRV_FUNC_DTMF,
++      eMCDRV_FUNC_IRQ
++} MCDRV_FUNC_KIND;
++
++typedef enum
++{
++      eMCDRV_SLAVE_ADDR_DIG   = 0,
++      eMCDRV_SLAVE_ADDR_ANA
++} MCDRV_SLAVE_ADDR_KIND;
++
++
++
++void  McDevProf_SetDevId(MCDRV_DEV_ID eDevId);
++
++UINT8 McDevProf_IsValid(MCDRV_FUNC_KIND eFuncKind);
++UINT8 McDevProf_GetSlaveAddr(MCDRV_SLAVE_ADDR_KIND eSlaveAddrKind);
++
++
++
++#endif        /*      _MCDEVPROF_H_   */
+diff --git a/sound/soc/codecs/mc1n2/mcdriver.c b/sound/soc/codecs/mc1n2/mcdriver.c
+new file mode 100644
+index 0000000..af3cdc3
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mcdriver.c
+@@ -0,0 +1,4047 @@
++/****************************************************************************
++ *
++ *            Copyright(c) 2010-2011 Yamaha Corporation. All rights reserved.
++ *
++ *            Module          : mcdriver.c
++ *
++ *            Description     : MC Driver
++ *
++ *            Version         : 1.0.2         2011.04.18
++ *
++ ****************************************************************************/
++
++
++#include "mcdriver_AA.h"
++#include "mcdriver.h"
++#include "mcservice.h"
++#include "mcdevif.h"
++#include "mcresctrl.h"
++#include "mcdefs.h"
++#include "mcdevprof.h"
++#include "mcmachdep.h"
++#if MCDRV_DEBUG_LEVEL
++#include "mcdebuglog.h"
++#endif
++
++
++
++#define       MCDRV_MAX_WAIT_TIME     ((UINT32)0x0FFFFFFF)
++
++static SINT32 init                                    (const MCDRV_INIT_INFO* psInitInfo);
++static SINT32 term                                    (void);
++
++static SINT32 read_reg                                (MCDRV_REG_INFO* psRegInfo);
++static SINT32 write_reg                               (const MCDRV_REG_INFO* psRegInfo);
++
++static SINT32 update_clock                    (const MCDRV_CLOCK_INFO* psClockInfo);
++static SINT32 switch_clock                    (const MCDRV_CLKSW_INFO* psClockInfo);
++
++static SINT32 get_path                                (MCDRV_PATH_INFO* psPathInfo);
++static SINT32 set_path                                (const MCDRV_PATH_INFO* psPathInfo);
++
++static SINT32 get_volume                              (MCDRV_VOL_INFO* psVolInfo);
++static SINT32 set_volume                              (const MCDRV_VOL_INFO *psVolInfo);
++
++static SINT32 get_digitalio                   (MCDRV_DIO_INFO* psDioInfo);
++static SINT32 set_digitalio                   (const MCDRV_DIO_INFO* psDioInfo, UINT32 dUpdateInfo);
++
++static SINT32 get_dac                                 (MCDRV_DAC_INFO* psDacInfo);
++static SINT32 set_dac                                 (const MCDRV_DAC_INFO* psDacInfo, UINT32 dUpdateInfo);
++
++static SINT32 get_adc                                 (MCDRV_ADC_INFO* psAdcInfo);
++static SINT32 set_adc                                 (const MCDRV_ADC_INFO* psAdcInfo, UINT32 dUpdateInfo);
++
++static SINT32 get_sp                                  (MCDRV_SP_INFO* psSpInfo);
++static SINT32 set_sp                                  (const MCDRV_SP_INFO* psSpInfo);
++
++static SINT32 get_dng                                 (MCDRV_DNG_INFO* psDngInfo);
++static SINT32 set_dng                                 (const MCDRV_DNG_INFO* psDngInfo, UINT32 dUpdateInfo);
++
++static SINT32 set_ae                                  (const MCDRV_AE_INFO* psAeInfo, UINT32 dUpdateInfo);
++
++static SINT32 get_pdm                                 (MCDRV_PDM_INFO* psPdmInfo);
++static SINT32 set_pdm                                 (const MCDRV_PDM_INFO* psPdmInfo, UINT32 dUpdateInfo);
++
++static SINT32 config_gp                               (const MCDRV_GP_MODE* psGpMode);
++static SINT32 mask_gp                                 (UINT8* pbMask, UINT32 dPadNo);
++static SINT32 getset_gp                               (UINT8* pbGpio, UINT32 dPadNo);
++
++static SINT32 get_syseq                               (MCDRV_SYSEQ_INFO* psSysEq);
++static SINT32 set_syseq                               (const MCDRV_SYSEQ_INFO* psSysEq, UINT32 dUpdateInfo);
++
++static SINT32 ValidateInitParam               (const MCDRV_INIT_INFO* psInitInfo);
++static SINT32 ValidateClockParam              (const MCDRV_CLOCK_INFO* psClockInfo);
++static SINT32 ValidateReadRegParam    (const MCDRV_REG_INFO* psRegInfo);
++static SINT32 ValidateWriteRegParam   (const MCDRV_REG_INFO* psRegInfo);
++static SINT32 ValidatePathParam               (const MCDRV_PATH_INFO* psPathInfo);
++static SINT32 ValidateDioParam                (const MCDRV_DIO_INFO* psDioInfo, UINT32 dUpdateInfo);
++static SINT32 CheckDIOCommon                  (const MCDRV_DIO_INFO*  psDioInfo, UINT8 bPort);
++static SINT32 CheckDIODIR                             (const MCDRV_DIO_INFO*  psDioInfo, UINT8 bPort, UINT8 bInterface);
++static SINT32 CheckDIODIT                             (const MCDRV_DIO_INFO*  psDioInfo, UINT8 bPort, UINT8 bInterface);
++
++static SINT32 SetVol                                  (UINT32 dUpdate, MCDRV_VOLUPDATE_MODE eMode, UINT32* pdSVolDoneParam);
++static        SINT32  PreUpdatePath                   (UINT16* pwDACMuteParam, UINT16* pwDITMuteParam);
++
++
++/****************************************************************************
++ *    init
++ *
++ *    Description:
++ *                    Initialize.
++ *    Arguments:
++ *                    psInitInfo      initialize information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  init
++(
++      const MCDRV_INIT_INFO   *psInitInfo
++)
++{
++      SINT32  sdRet;
++      UINT8   bHWID;
++
++      if(NULL == psInitInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT != McResCtrl_GetState())
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McSrv_SystemInit();
++      McSrv_Lock();
++
++      bHWID   = McSrv_ReadI2C(McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG), (UINT32)MCI_HW_ID);
++      sdRet   = McResCtrl_SetHwId(bHWID);
++      if(sdRet != MCDRV_SUCCESS)
++      {
++              McSrv_Unlock();
++              McSrv_SystemTerm();
++              return sdRet;
++      }
++
++      if(bHWID == MCDRV_HWID_AA)
++      {
++              McSrv_Unlock();
++              McSrv_SystemTerm();
++              return McDrv_Ctrl_AA(MCDRV_INIT, (MCDRV_INIT_INFO*)psInitInfo, 0);
++      }
++      else
++      {
++              sdRet   = ValidateInitParam(psInitInfo);
++
++              if(sdRet == MCDRV_SUCCESS)
++              {
++                      McResCtrl_Init(psInitInfo);
++                      sdRet   = McDevIf_AllocPacketBuf();
++              }
++
++              if(sdRet == MCDRV_SUCCESS)
++              {
++                      sdRet   = McPacket_AddInit(psInitInfo);
++              }
++
++              if(sdRet == MCDRV_SUCCESS)
++              {
++                      sdRet   = McDevIf_ExecutePacket();
++              }
++
++              if(sdRet == MCDRV_SUCCESS)
++              {
++                      McResCtrl_UpdateState(eMCDRV_STATE_READY);
++              }
++              else
++              {
++                      McDevIf_ReleasePacketBuf();
++              }
++
++              McSrv_Unlock();
++
++              if(sdRet != MCDRV_SUCCESS)
++              {
++                      McSrv_SystemTerm();
++              }
++      }
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    term
++ *
++ *    Description:
++ *                    Terminate.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  term
++(
++      void
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bCh, bSrcIdx;
++      UINT8   abOnOff[SOURCE_BLOCK_NUM];
++      MCDRV_PATH_INFO         sPathInfo;
++      MCDRV_POWER_INFO        sPowerInfo;
++      MCDRV_POWER_UPDATE      sPowerUpdate;
++
++      if(eMCDRV_STATE_READY != McResCtrl_GetState())
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McSrv_Lock();
++
++      abOnOff[0]      = (MCDRV_SRC0_MIC1_OFF|MCDRV_SRC0_MIC2_OFF|MCDRV_SRC0_MIC3_OFF);
++      abOnOff[1]      = (MCDRV_SRC1_LINE1_L_OFF|MCDRV_SRC1_LINE1_R_OFF|MCDRV_SRC1_LINE1_M_OFF);
++      abOnOff[2]      = (MCDRV_SRC2_LINE2_L_OFF|MCDRV_SRC2_LINE2_R_OFF|MCDRV_SRC2_LINE2_M_OFF);
++      abOnOff[3]      = (MCDRV_SRC3_DIR0_OFF|MCDRV_SRC3_DIR1_OFF|MCDRV_SRC3_DIR2_OFF|MCDRV_SRC3_DIR2_DIRECT_OFF);
++      abOnOff[4]      = (MCDRV_SRC4_DTMF_OFF|MCDRV_SRC4_PDM_OFF|MCDRV_SRC4_ADC0_OFF|MCDRV_SRC4_ADC1_OFF);
++      abOnOff[5]      = (MCDRV_SRC5_DAC_L_OFF|MCDRV_SRC5_DAC_R_OFF|MCDRV_SRC5_DAC_M_OFF);
++      abOnOff[6]      = (MCDRV_SRC6_MIX_OFF|MCDRV_SRC6_AE_OFF|MCDRV_SRC6_CDSP_OFF|MCDRV_SRC6_CDSP_DIRECT_OFF);
++
++      for(bSrcIdx = 0; bSrcIdx < SOURCE_BLOCK_NUM; bSrcIdx++)
++      {
++              for(bCh = 0; bCh < HP_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asHpOut[bCh].abSrcOnOff[bSrcIdx]      = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < SP_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asSpOut[bCh].abSrcOnOff[bSrcIdx]      = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < RC_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asRcOut[bCh].abSrcOnOff[bSrcIdx]      = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < LOUT1_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asLout1[bCh].abSrcOnOff[bSrcIdx]      = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < LOUT2_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asLout2[bCh].abSrcOnOff[bSrcIdx]      = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < PEAK_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asPeak[bCh].abSrcOnOff[bSrcIdx]       = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < DIT0_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asDit0[bCh].abSrcOnOff[bSrcIdx]       = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < DIT1_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asDit1[bCh].abSrcOnOff[bSrcIdx]       = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < DIT2_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asDit2[bCh].abSrcOnOff[bSrcIdx]       = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < DAC_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asDac[bCh].abSrcOnOff[bSrcIdx]        = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < AE_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asAe[bCh].abSrcOnOff[bSrcIdx]         = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < CDSP_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asCdsp[bCh].abSrcOnOff[bSrcIdx]       = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < ADC0_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asAdc0[bCh].abSrcOnOff[bSrcIdx]       = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < ADC1_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asAdc1[bCh].abSrcOnOff[bSrcIdx]       = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < MIX_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asMix[bCh].abSrcOnOff[bSrcIdx]        = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < BIAS_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asBias[bCh].abSrcOnOff[bSrcIdx]       = abOnOff[bSrcIdx];
++              }
++      }
++      sdRet   = set_path(&sPathInfo);
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              sPowerInfo.dDigital                     = (MCDRV_POWINFO_DIGITAL_DP0
++                                                                        |MCDRV_POWINFO_DIGITAL_DP1
++                                                                        |MCDRV_POWINFO_DIGITAL_DP2
++                                                                        |MCDRV_POWINFO_DIGITAL_DPB
++                                                                        |MCDRV_POWINFO_DIGITAL_DPDI0
++                                                                        |MCDRV_POWINFO_DIGITAL_DPDI1
++                                                                        |MCDRV_POWINFO_DIGITAL_DPDI2
++                                                                        |MCDRV_POWINFO_DIGITAL_DPPDM
++                                                                        |MCDRV_POWINFO_DIGITAL_DPBDSP
++                                                                        |MCDRV_POWINFO_DIGITAL_DPADIF
++                                                                        |MCDRV_POWINFO_DIGITAL_PLLRST0);
++              sPowerInfo.abAnalog[0]          =
++              sPowerInfo.abAnalog[1]          =
++              sPowerInfo.abAnalog[2]          =
++              sPowerInfo.abAnalog[3]          =
++              sPowerInfo.abAnalog[4]          = (UINT8)0xFF;
++              sPowerUpdate.dDigital           = MCDRV_POWUPDATE_DIGITAL_ALL;
++              sPowerUpdate.abAnalog[0]        = (UINT8)MCDRV_POWUPDATE_ANALOG0_ALL;
++              sPowerUpdate.abAnalog[1]        = (UINT8)MCDRV_POWUPDATE_ANALOG1_ALL;
++              sPowerUpdate.abAnalog[2]        = (UINT8)MCDRV_POWUPDATE_ANALOG2_ALL;
++              sPowerUpdate.abAnalog[3]        = (UINT8)MCDRV_POWUPDATE_ANALOG3_ALL;
++              sPowerUpdate.abAnalog[4]        = (UINT8)MCDRV_POWUPDATE_ANALOG4_ALL;
++              sdRet   = McPacket_AddPowerDown(&sPowerInfo, &sPowerUpdate);
++      }
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              sdRet   = McDevIf_ExecutePacket();
++      }
++
++      McDevIf_ReleasePacketBuf();
++
++      McResCtrl_UpdateState(eMCDRV_STATE_NOTINIT);
++
++      McSrv_Unlock();
++
++      McSrv_SystemTerm();
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    read_reg
++ *
++ *    Description:
++ *                    read register.
++ *    Arguments:
++ *                    psRegInfo       register information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_STATE
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++static        SINT32  read_reg
++(
++      MCDRV_REG_INFO* psRegInfo
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bSlaveAddr;
++      UINT8   bAddr;
++      UINT8   abData[2];
++      MCDRV_POWER_INFO        sPowerInfo;
++      MCDRV_POWER_INFO        sCurPowerInfo;
++      MCDRV_POWER_UPDATE      sPowerUpdate;
++
++      if(NULL == psRegInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT == McResCtrl_GetState())
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      sdRet   = ValidateReadRegParam(psRegInfo);
++      if(sdRet != MCDRV_SUCCESS)
++      {
++              return sdRet;
++      }
++
++      /*      get current power info  */
++      McResCtrl_GetCurPowerInfo(&sCurPowerInfo);
++
++      /*      power up        */
++      McResCtrl_GetPowerInfoRegAccess(psRegInfo, &sPowerInfo);
++      sPowerUpdate.dDigital           = MCDRV_POWUPDATE_DIGITAL_ALL;
++      sPowerUpdate.abAnalog[0]        = (UINT8)MCDRV_POWUPDATE_ANALOG0_ALL;
++      sPowerUpdate.abAnalog[1]        = (UINT8)MCDRV_POWUPDATE_ANALOG1_ALL;
++      sPowerUpdate.abAnalog[2]        = (UINT8)MCDRV_POWUPDATE_ANALOG2_ALL;
++      sPowerUpdate.abAnalog[3]        = (UINT8)MCDRV_POWUPDATE_ANALOG3_ALL;
++      sPowerUpdate.abAnalog[4]        = (UINT8)MCDRV_POWUPDATE_ANALOG4_ALL;
++      sdRet   = McPacket_AddPowerUp(&sPowerInfo, &sPowerUpdate);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      sdRet   = McDevIf_ExecutePacket();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      bAddr   = psRegInfo->bAddress;
++
++      if(psRegInfo->bRegType == MCDRV_REGTYPE_A)
++      {
++              bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++      }
++      else
++      {
++              switch(psRegInfo->bRegType)
++              {
++              case    MCDRV_REGTYPE_B_BASE:
++                      bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++                      abData[0]       = MCI_BASE_ADR<<1;
++                      abData[1]       = bAddr;
++                      McSrv_WriteI2C(bSlaveAddr, abData, 2);
++                      bAddr   = MCI_BASE_WINDOW;
++                      break;
++
++              case    MCDRV_REGTYPE_B_MIXER:
++                      bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++                      abData[0]       = MCI_MIX_ADR<<1;
++                      abData[1]       = bAddr;
++                      McSrv_WriteI2C(bSlaveAddr, abData, 2);
++                      bAddr   = MCI_MIX_WINDOW;
++                      break;
++
++              case    MCDRV_REGTYPE_B_AE:
++                      bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++                      abData[0]       = MCI_AE_ADR<<1;
++                      abData[1]       = bAddr;
++                      McSrv_WriteI2C(bSlaveAddr, abData, 2);
++                      bAddr   = MCI_AE_WINDOW;
++                      break;
++
++              case    MCDRV_REGTYPE_B_CDSP:
++                      bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++                      abData[0]       = MCI_CDSP_ADR<<1;
++                      abData[1]       = bAddr;
++                      McSrv_WriteI2C(bSlaveAddr, abData, 2);
++                      bAddr   = MCI_CDSP_WINDOW;
++                      break;
++
++              case    MCDRV_REGTYPE_B_CODEC:
++                      bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++                      abData[0]       = MCI_CD_ADR<<1;
++                      abData[1]       = bAddr;
++                      McSrv_WriteI2C(bSlaveAddr, abData, 2);
++                      bAddr   = MCI_CD_WINDOW;
++                      break;
++
++              case    MCDRV_REGTYPE_B_ANALOG:
++                      bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_ANA);
++                      abData[0]       = MCI_ANA_ADR<<1;
++                      abData[1]       = bAddr;
++                      McSrv_WriteI2C(bSlaveAddr, abData, 2);
++                      bAddr   = MCI_ANA_WINDOW;
++                      break;
++
++              default:
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++
++      /*      read register   */
++      psRegInfo->bData        = McSrv_ReadI2C(bSlaveAddr, bAddr);
++
++      /*      restore power   */
++      sdRet   = McPacket_AddPowerDown(&sCurPowerInfo, &sPowerUpdate);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      return McDevIf_ExecutePacket();
++}
++
++/****************************************************************************
++ *    write_reg
++ *
++ *    Description:
++ *                    Write register.
++ *    Arguments:
++ *                    psWR    register information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_STATE
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *
++ ****************************************************************************/
++static        SINT32  write_reg
++(
++      const MCDRV_REG_INFO*   psRegInfo
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      MCDRV_POWER_INFO        sPowerInfo;
++      MCDRV_POWER_INFO        sCurPowerInfo;
++      MCDRV_POWER_UPDATE      sPowerUpdate;
++
++      if(NULL == psRegInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT == McResCtrl_GetState())
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      sdRet   = ValidateWriteRegParam(psRegInfo);
++      if(sdRet != MCDRV_SUCCESS)
++      {
++              return sdRet;
++      }
++
++      /*      get current power info  */
++      McResCtrl_GetCurPowerInfo(&sCurPowerInfo);
++
++      /*      power up        */
++      McResCtrl_GetPowerInfoRegAccess(psRegInfo, &sPowerInfo);
++      sPowerUpdate.dDigital           = MCDRV_POWUPDATE_DIGITAL_ALL;
++      sPowerUpdate.abAnalog[0]        = (UINT8)MCDRV_POWUPDATE_ANALOG0_ALL;
++      sPowerUpdate.abAnalog[1]        = (UINT8)MCDRV_POWUPDATE_ANALOG1_ALL;
++      sPowerUpdate.abAnalog[2]        = (UINT8)MCDRV_POWUPDATE_ANALOG2_ALL;
++      sPowerUpdate.abAnalog[3]        = (UINT8)MCDRV_POWUPDATE_ANALOG3_ALL;
++      sPowerUpdate.abAnalog[4]        = (UINT8)MCDRV_POWUPDATE_ANALOG4_ALL;
++      sdRet   = McPacket_AddPowerUp(&sPowerInfo, &sPowerUpdate);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      switch(psRegInfo->bRegType)
++      {
++      case    MCDRV_REGTYPE_A:
++              McDevIf_AddPacket((MCDRV_PACKET_TYPE_FORCE_WRITE | MCDRV_PACKET_REGTYPE_A | psRegInfo->bAddress), psRegInfo->bData);
++              break;
++
++      case    MCDRV_REGTYPE_B_BASE:
++              McDevIf_AddPacket((MCDRV_PACKET_TYPE_FORCE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | psRegInfo->bAddress), psRegInfo->bData);
++              break;
++
++      case    MCDRV_REGTYPE_B_MIXER:
++              McDevIf_AddPacket((MCDRV_PACKET_TYPE_FORCE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | psRegInfo->bAddress), psRegInfo->bData);
++              break;
++
++      case    MCDRV_REGTYPE_B_AE:
++              McDevIf_AddPacket((MCDRV_PACKET_TYPE_FORCE_WRITE | MCDRV_PACKET_REGTYPE_B_AE | psRegInfo->bAddress), psRegInfo->bData);
++              break;
++
++      case    MCDRV_REGTYPE_B_CDSP:
++              McDevIf_AddPacket((MCDRV_PACKET_TYPE_FORCE_WRITE | MCDRV_PACKET_REGTYPE_B_CDSP | psRegInfo->bAddress), psRegInfo->bData);
++              break;
++
++      case    MCDRV_REGTYPE_B_CODEC:
++              McDevIf_AddPacket((MCDRV_PACKET_TYPE_FORCE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | psRegInfo->bAddress), psRegInfo->bData);
++              break;
++
++      case    MCDRV_REGTYPE_B_ANALOG:
++              McDevIf_AddPacket((MCDRV_PACKET_TYPE_FORCE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | psRegInfo->bAddress), psRegInfo->bData);
++              break;
++
++      default:
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      sdRet   = McDevIf_ExecutePacket();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      /*      restore power   */
++      if(psRegInfo->bRegType == MCDRV_REGTYPE_B_BASE)
++      {
++              if(psRegInfo->bAddress == MCI_PWM_DIGITAL)
++              {
++                      if((psRegInfo->bData & MCB_PWM_DP1) == 0)
++                      {
++                              sCurPowerInfo.dDigital &= ~MCDRV_POWINFO_DIGITAL_DP1;
++                      }
++                      if((psRegInfo->bData & MCB_PWM_DP2) == 0)
++                      {
++                              sCurPowerInfo.dDigital &= ~MCDRV_POWINFO_DIGITAL_DP2;
++                      }
++              }
++              else if(psRegInfo->bAddress == MCI_PWM_DIGITAL_1)
++              {
++                      if((psRegInfo->bData & MCB_PWM_DPB) == 0)
++                      {
++                              sCurPowerInfo.dDigital &= ~MCDRV_POWINFO_DIGITAL_DPB;
++                      }
++                      if((psRegInfo->bData & MCB_PWM_DPDI0) == 0)
++                      {
++                              sCurPowerInfo.dDigital &= ~MCDRV_POWINFO_DIGITAL_DPDI0;
++                      }
++                      if((psRegInfo->bData & MCB_PWM_DPDI1) == 0)
++                      {
++                              sCurPowerInfo.dDigital &= ~MCDRV_POWINFO_DIGITAL_DPDI1;
++                      }
++                      if((psRegInfo->bData & MCB_PWM_DPDI2) == 0)
++                      {
++                              sCurPowerInfo.dDigital &= ~MCDRV_POWINFO_DIGITAL_DPDI2;
++                      }
++                      if((psRegInfo->bData & MCB_PWM_DPPDM) == 0)
++                      {
++                              sCurPowerInfo.dDigital &= ~MCDRV_POWINFO_DIGITAL_DPPDM;
++                      }
++              }
++              else if(psRegInfo->bAddress == MCI_PWM_DIGITAL_BDSP)
++              {
++                      if((psRegInfo->bData & MCB_PWM_DPBDSP) == 0)
++                      {
++                              sCurPowerInfo.dDigital &= ~MCDRV_POWINFO_DIGITAL_DPBDSP;
++                      }
++              }
++              else
++              {
++              }
++      }
++      else if(psRegInfo->bRegType == MCDRV_REGTYPE_B_CODEC)
++      {
++              if(psRegInfo->bAddress == MCI_DPADIF)
++              {
++                      if((psRegInfo->bData & MCB_DPADIF) == 0)
++                      {
++                              sCurPowerInfo.dDigital &= ~MCDRV_POWINFO_DIGITAL_DPADIF;
++                      }
++                      if((psRegInfo->bData & MCB_DP0_CLKI0) == 0)
++                      {
++                              sCurPowerInfo.dDigital &= ~MCDRV_POWINFO_DIGITAL_DP0;
++                      }
++                      if((psRegInfo->bData & MCB_DP0_CLKI1) == 0)
++                      {
++                              sCurPowerInfo.dDigital &= ~MCDRV_POWINFO_DIGITAL_DP0;
++                      }
++              }
++              if(psRegInfo->bAddress == MCI_PLL_RST)
++              {
++                      if((psRegInfo->bData & MCB_PLLRST0) == 0)
++                      {
++                              sCurPowerInfo.dDigital &= ~MCDRV_POWINFO_DIGITAL_PLLRST0;
++                      }
++              }
++      }
++      else if(psRegInfo->bRegType == MCDRV_REGTYPE_B_ANALOG)
++      {
++              if(psRegInfo->bAddress == MCI_PWM_ANALOG_0)
++              {
++                      sCurPowerInfo.abAnalog[0]       = psRegInfo->bData;
++              }
++              else if(psRegInfo->bAddress == MCI_PWM_ANALOG_1)
++              {
++                      sCurPowerInfo.abAnalog[1]       = psRegInfo->bData;
++              }
++              else if(psRegInfo->bAddress == MCI_PWM_ANALOG_2)
++              {
++                      sCurPowerInfo.abAnalog[2]       = psRegInfo->bData;
++              }
++              else if(psRegInfo->bAddress == MCI_PWM_ANALOG_3)
++              {
++                      sCurPowerInfo.abAnalog[3]       = psRegInfo->bData;
++              }
++              else if(psRegInfo->bAddress == MCI_PWM_ANALOG_4)
++              {
++                      sCurPowerInfo.abAnalog[4]       = psRegInfo->bData;
++              }
++              else
++              {
++              }
++      }
++      else
++      {
++      }
++
++      sdRet   = McPacket_AddPowerDown(&sCurPowerInfo, &sPowerUpdate);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      return McDevIf_ExecutePacket();
++}
++
++/****************************************************************************
++ *    update_clock
++ *
++ *    Description:
++ *                    Update clock info.
++ *    Arguments:
++ *                    psClockInfo     clock info
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  update_clock
++(
++      const MCDRV_CLOCK_INFO* psClockInfo
++)
++{
++      SINT32                  sdRet   = MCDRV_SUCCESS;
++      MCDRV_STATE             eState  = McResCtrl_GetState();
++      MCDRV_INIT_INFO sInitInfo;
++
++      if(NULL == psClockInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_GetInitInfo(&sInitInfo);
++      if((sInitInfo.bPowerMode & MCDRV_POWMODE_CLKON) != 0)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      sdRet   = ValidateClockParam(psClockInfo);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      McResCtrl_SetClockInfo(psClockInfo);
++      return sdRet;
++}
++
++/****************************************************************************
++ *    switch_clock
++ *
++ *    Description:
++ *                    Switch clock.
++ *    Arguments:
++ *                    psClockInfo     clock info
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  switch_clock
++(
++      const MCDRV_CLKSW_INFO* psClockInfo
++)
++{
++      SINT32          sdRet   = MCDRV_SUCCESS;
++      MCDRV_STATE     eState  = McResCtrl_GetState();
++
++      if(eMCDRV_STATE_NOTINIT == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      if(NULL == psClockInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if((psClockInfo->bClkSrc != MCDRV_CLKSW_CLKI0) && (psClockInfo->bClkSrc != MCDRV_CLKSW_CLKI1))
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      McResCtrl_SetClockSwitch(psClockInfo);
++
++      sdRet   = McPacket_AddClockSwitch();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      return McDevIf_ExecutePacket();
++}
++
++/****************************************************************************
++ *    get_path
++ *
++ *    Description:
++ *                    Get current path setting.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  get_path
++(
++      MCDRV_PATH_INFO*        psPathInfo
++)
++{
++      if(NULL == psPathInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT == McResCtrl_GetState())
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_GetPathInfoVirtual(psPathInfo);
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    set_path
++ *
++ *    Description:
++ *                    Set path.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  set_path
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++      SINT32                  sdRet   = MCDRV_SUCCESS;
++      UINT32                  dSVolDoneParam  = 0;
++      UINT16                  wDACMuteParam   = 0;
++      UINT16                  wDITMuteParam   = 0;
++      MCDRV_STATE             eState  = McResCtrl_GetState();
++      MCDRV_POWER_INFO        sPowerInfo;
++      MCDRV_POWER_UPDATE      sPowerUpdate;
++
++      if(NULL == psPathInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      sdRet   = ValidatePathParam(psPathInfo);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      McResCtrl_SetPathInfo(psPathInfo);
++
++      /*      unused analog out volume mute   */
++      sdRet   = SetVol(MCDRV_VOLUPDATE_ANAOUT_ALL, eMCDRV_VOLUPDATE_MUTE, &dSVolDoneParam);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      /*      DAC/DIT* mute   */
++      sdRet   = PreUpdatePath(&wDACMuteParam, &wDITMuteParam);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      /*      unused volume mute      */
++      sdRet   = SetVol(MCDRV_VOLUPDATE_ALL&~MCDRV_VOLUPDATE_ANAOUT_ALL, eMCDRV_VOLUPDATE_MUTE, NULL);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      /*      wait XX_BUSY    */
++      if(dSVolDoneParam != (UINT32)0)
++      {
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_EVTWAIT | MCDRV_EVT_SVOL_DONE | dSVolDoneParam, 0);
++      }
++      if(wDACMuteParam != 0)
++      {
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_EVTWAIT | MCDRV_EVT_DACMUTE | wDACMuteParam, 0);
++      }
++      if(wDITMuteParam != 0)
++      {
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_EVTWAIT | MCDRV_EVT_DITMUTE | wDITMuteParam, 0);
++      }
++
++      /*      stop unused path        */
++      sdRet   = McPacket_AddStop();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      sdRet   = McDevIf_ExecutePacket();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      McResCtrl_GetPowerInfo(&sPowerInfo);
++
++      /*      used path power up      */
++      sPowerUpdate.dDigital           = MCDRV_POWUPDATE_DIGITAL_ALL;
++      sPowerUpdate.abAnalog[0]        = (UINT8)MCDRV_POWUPDATE_ANALOG0_ALL;
++      sPowerUpdate.abAnalog[1]        = (UINT8)MCDRV_POWUPDATE_ANALOG1_ALL;
++      sPowerUpdate.abAnalog[2]        = (UINT8)MCDRV_POWUPDATE_ANALOG2_ALL;
++      sPowerUpdate.abAnalog[3]        = (UINT8)MCDRV_POWUPDATE_ANALOG3_ALL;
++      sPowerUpdate.abAnalog[4]        = (UINT8)MCDRV_POWUPDATE_ANALOG4_ALL;
++      sdRet   = McPacket_AddPowerUp(&sPowerInfo, &sPowerUpdate);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      sdRet   = McDevIf_ExecutePacket();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      /*      set digital mixer       */
++      sdRet   = McPacket_AddPathSet();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      sdRet   = McDevIf_ExecutePacket();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      /*      set analog mixer        */
++      sdRet   = McPacket_AddMixSet();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      sdRet   = McDevIf_ExecutePacket();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      /*      unused path power down  */
++      sPowerUpdate.dDigital           = MCDRV_POWUPDATE_DIGITAL_ALL;
++      sPowerUpdate.abAnalog[0]        = (UINT8)MCDRV_POWUPDATE_ANALOG0_ALL;
++      sPowerUpdate.abAnalog[1]        = (UINT8)MCDRV_POWUPDATE_ANALOG1_ALL;
++      sPowerUpdate.abAnalog[2]        = (UINT8)MCDRV_POWUPDATE_ANALOG2_ALL;
++      sPowerUpdate.abAnalog[3]        = (UINT8)MCDRV_POWUPDATE_ANALOG3_ALL;
++      sPowerUpdate.abAnalog[4]        = (UINT8)MCDRV_POWUPDATE_ANALOG4_ALL;
++      sdRet   = McPacket_AddPowerDown(&sPowerInfo, &sPowerUpdate);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      sdRet   = McDevIf_ExecutePacket();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      /*      start   */
++      sdRet   = McPacket_AddStart();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      sdRet   = McDevIf_ExecutePacket();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      /*      set volume      */
++      sdRet   = SetVol(MCDRV_VOLUPDATE_ALL&~MCDRV_VOLUPDATE_ANAOUT_ALL, eMCDRV_VOLUPDATE_ALL, NULL);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      return SetVol(MCDRV_VOLUPDATE_ANAOUT_ALL, eMCDRV_VOLUPDATE_ALL, &dSVolDoneParam);
++}
++
++/****************************************************************************
++ *    get_volume
++ *
++ *    Description:
++ *                    Get current volume setting.
++ *    Arguments:
++ *                    psVolInfo       volume information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++static        SINT32  get_volume
++(
++      MCDRV_VOL_INFO* psVolInfo
++)
++{
++      if(NULL == psVolInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT == McResCtrl_GetState())
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_GetVolInfo(psVolInfo);
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    set_volume
++ *
++ *    Description:
++ *                    Set volume.
++ *    Arguments:
++ *                    psVolInfo       volume update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++static        SINT32  set_volume
++(
++      const MCDRV_VOL_INFO*   psVolInfo
++)
++{
++      MCDRV_STATE     eState  = McResCtrl_GetState();
++      MCDRV_PATH_INFO sPathInfo;
++
++      if(NULL == psVolInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_SetVolInfo(psVolInfo);
++
++      McResCtrl_GetPathInfoVirtual(&sPathInfo);
++      return  set_path(&sPathInfo);
++}
++
++/****************************************************************************
++ *    get_digitalio
++ *
++ *    Description:
++ *                    Get current digital IO setting.
++ *    Arguments:
++ *                    psDioInfo       digital IO information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  get_digitalio
++(
++      MCDRV_DIO_INFO* psDioInfo
++)
++{
++      if(NULL == psDioInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT == McResCtrl_GetState())
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_GetDioInfo(psDioInfo);
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    set_digitalio
++ *
++ *    Description:
++ *                    Update digital IO configuration.
++ *    Arguments:
++ *                    psDioInfo       digital IO configuration
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  set_digitalio
++(
++      const MCDRV_DIO_INFO*   psDioInfo,
++      UINT32                                  dUpdateInfo
++)
++{
++      SINT32          sdRet   = MCDRV_SUCCESS;
++      MCDRV_STATE     eState  = McResCtrl_GetState();
++
++      if(NULL == psDioInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      sdRet   = ValidateDioParam(psDioInfo, dUpdateInfo);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      McResCtrl_SetDioInfo(psDioInfo, dUpdateInfo);
++
++      sdRet   = McPacket_AddDigitalIO(dUpdateInfo);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      return McDevIf_ExecutePacket();
++}
++
++/****************************************************************************
++ *    get_dac
++ *
++ *    Description:
++ *                    Get current DAC setting.
++ *    Arguments:
++ *                    psDacInfo       DAC information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  get_dac
++(
++      MCDRV_DAC_INFO* psDacInfo
++)
++{
++      if(NULL == psDacInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT == McResCtrl_GetState())
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_GetDacInfo(psDacInfo);
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    set_dac
++ *
++ *    Description:
++ *                    Update DAC configuration.
++ *    Arguments:
++ *                    psDacInfo       DAC configuration
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  set_dac
++(
++      const MCDRV_DAC_INFO*   psDacInfo,
++      UINT32                                  dUpdateInfo
++)
++{
++      SINT32          sdRet   = MCDRV_SUCCESS;
++      MCDRV_STATE     eState  = McResCtrl_GetState();
++
++      if(NULL == psDacInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_SetDacInfo(psDacInfo, dUpdateInfo);
++
++      sdRet   = McPacket_AddDAC(dUpdateInfo);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      return McDevIf_ExecutePacket();
++}
++
++/****************************************************************************
++ *    get_adc
++ *
++ *    Description:
++ *                    Get current ADC setting.
++ *    Arguments:
++ *                    psAdcInfo       ADC information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  get_adc
++(
++      MCDRV_ADC_INFO* psAdcInfo
++)
++{
++      if(NULL == psAdcInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT == McResCtrl_GetState())
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_GetAdcInfo(psAdcInfo);
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    set_adc
++ *
++ *    Description:
++ *                    Update ADC configuration.
++ *    Arguments:
++ *                    psAdcInfo       ADC configuration
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  set_adc
++(
++      const MCDRV_ADC_INFO*   psAdcInfo,
++      UINT32                                  dUpdateInfo
++)
++{
++      SINT32          sdRet   = MCDRV_SUCCESS;
++      MCDRV_STATE     eState  = McResCtrl_GetState();
++
++      if(NULL == psAdcInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_SetAdcInfo(psAdcInfo, dUpdateInfo);
++
++      sdRet   = McPacket_AddADC(dUpdateInfo);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      return McDevIf_ExecutePacket();
++}
++
++/****************************************************************************
++ *    get_sp
++ *
++ *    Description:
++ *                    Get current SP setting.
++ *    Arguments:
++ *                    psSpInfo        SP information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  get_sp
++(
++      MCDRV_SP_INFO*  psSpInfo
++)
++{
++      if(NULL == psSpInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT == McResCtrl_GetState())
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_GetSpInfo(psSpInfo);
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    set_sp
++ *
++ *    Description:
++ *                    Update SP configuration.
++ *    Arguments:
++ *                    psSpInfo        SP configuration
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  set_sp
++(
++      const MCDRV_SP_INFO*    psSpInfo
++)
++{
++      SINT32          sdRet   = MCDRV_SUCCESS;
++      MCDRV_STATE     eState  = McResCtrl_GetState();
++
++      if(NULL == psSpInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_SetSpInfo(psSpInfo);
++
++      sdRet   = McPacket_AddSP();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      return McDevIf_ExecutePacket();
++}
++
++/****************************************************************************
++ *    get_dng
++ *
++ *    Description:
++ *                    Get current Digital Noise Gate setting.
++ *    Arguments:
++ *                    psDngInfo       DNG information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  get_dng
++(
++      MCDRV_DNG_INFO* psDngInfo
++)
++{
++      if(NULL == psDngInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT == McResCtrl_GetState())
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_GetDngInfo(psDngInfo);
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    set_dng
++ *
++ *    Description:
++ *                    Update Digital Noise Gate configuration.
++ *    Arguments:
++ *                    psDngInfo       DNG configuration
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  set_dng
++(
++      const MCDRV_DNG_INFO*   psDngInfo,
++      UINT32                                  dUpdateInfo
++)
++{
++      SINT32          sdRet   = MCDRV_SUCCESS;
++      MCDRV_STATE     eState  = McResCtrl_GetState();
++
++      if(NULL == psDngInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_SetDngInfo(psDngInfo, dUpdateInfo);
++
++      sdRet   = McPacket_AddDNG(dUpdateInfo);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      return McDevIf_ExecutePacket();
++}
++
++/****************************************************************************
++ *    set_ae
++ *
++ *    Description:
++ *                    Update Audio Engine configuration.
++ *    Arguments:
++ *                    psAeInfo        AE configuration
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  set_ae
++(
++      const MCDRV_AE_INFO*    psAeInfo,
++      UINT32                                  dUpdateInfo
++)
++{
++      SINT32          sdRet   = MCDRV_SUCCESS;
++      MCDRV_STATE     eState  = McResCtrl_GetState();
++      MCDRV_PATH_INFO sPathInfo;
++
++      if(NULL == psAeInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_SetAeInfo(psAeInfo, dUpdateInfo);
++
++      sdRet   = McPacket_AddAE(dUpdateInfo);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      sdRet   = McDevIf_ExecutePacket();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      McResCtrl_GetPathInfoVirtual(&sPathInfo);
++      return  set_path(&sPathInfo);
++}
++
++/****************************************************************************
++ *    get_pdm
++ *
++ *    Description:
++ *                    Get current PDM setting.
++ *    Arguments:
++ *                    psPdmInfo       PDM information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  get_pdm
++(
++      MCDRV_PDM_INFO* psPdmInfo
++)
++{
++      if(NULL == psPdmInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT == McResCtrl_GetState())
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_GetPdmInfo(psPdmInfo);
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    set_pdm
++ *
++ *    Description:
++ *                    Update PDM configuration.
++ *    Arguments:
++ *                    psPdmInfo       PDM configuration
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  set_pdm
++(
++      const MCDRV_PDM_INFO*   psPdmInfo,
++      UINT32                                  dUpdateInfo
++)
++{
++      SINT32          sdRet   = MCDRV_SUCCESS;
++      MCDRV_STATE     eState  = McResCtrl_GetState();
++
++      if(NULL == psPdmInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_SetPdmInfo(psPdmInfo, dUpdateInfo);
++
++      sdRet   = McPacket_AddPDM(dUpdateInfo);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      return McDevIf_ExecutePacket();
++}
++
++/****************************************************************************
++ *    config_gp
++ *
++ *    Description:
++ *                    Set GPIO mode.
++ *    Arguments:
++ *                    psGpMode        GPIO mode information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_STATE
++*
++ ****************************************************************************/
++static        SINT32  config_gp
++(
++      const MCDRV_GP_MODE*    psGpMode
++)
++{
++      SINT32          sdRet   = MCDRV_SUCCESS;
++      MCDRV_STATE     eState  = McResCtrl_GetState();
++
++      if(NULL == psGpMode)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_SetGPMode(psGpMode);
++
++      sdRet   = McPacket_AddGPMode();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      return McDevIf_ExecutePacket();
++}
++
++/****************************************************************************
++ *    mask_gp
++ *
++ *    Description:
++ *                    Set GPIO input mask.
++ *    Arguments:
++ *                    pbMask  mask setting
++ *                    dPadNo  PAD number
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_STATE
++ *                    MCDRV_ERROR
++*
++ ****************************************************************************/
++static        SINT32  mask_gp
++(
++      UINT8*  pbMask,
++      UINT32  dPadNo
++)
++{
++      SINT32          sdRet   = MCDRV_SUCCESS;
++      MCDRV_STATE     eState  = McResCtrl_GetState();
++      MCDRV_INIT_INFO sInitInfo;
++      MCDRV_GP_MODE   sGPMode;
++
++      if(NULL == pbMask)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_GetInitInfo(&sInitInfo);
++      McResCtrl_GetGPMode(&sGPMode);
++
++      if(dPadNo == MCDRV_GP_PAD0)
++      {
++              if((sInitInfo.bPad0Func == MCDRV_PAD_GPIO) && (sGPMode.abGpDdr[dPadNo] == MCDRV_GPDDR_OUT))
++              {
++                      return MCDRV_ERROR;
++              }
++      }
++      else if(dPadNo == MCDRV_GP_PAD1)
++      {
++              if((sInitInfo.bPad1Func == MCDRV_PAD_GPIO) && (sGPMode.abGpDdr[dPadNo] == MCDRV_GPDDR_OUT))
++              {
++                      return MCDRV_ERROR;
++              }
++      }
++      else
++      {
++              return MCDRV_ERROR;
++      }
++
++      McResCtrl_SetGPMask(*pbMask, dPadNo);
++
++      sdRet   = McPacket_AddGPMask(dPadNo);
++      if(sdRet != MCDRV_SUCCESS)
++      {
++              return sdRet;
++      }
++      return McDevIf_ExecutePacket();
++}
++
++/****************************************************************************
++ *    getset_gp
++ *
++ *    Description:
++ *                    Set or get state of GPIO pin.
++ *    Arguments:
++ *                    pbGpio  pin state
++ *                    dPadNo  PAD number
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++*
++ ****************************************************************************/
++static        SINT32  getset_gp
++(
++      UINT8*  pbGpio,
++      UINT32  dPadNo
++)
++{
++      SINT32                  sdRet   = MCDRV_SUCCESS;
++      UINT8                   bSlaveAddr;
++      UINT8                   abData[2];
++      UINT8                   bRegData;
++      MCDRV_STATE             eState  = McResCtrl_GetState();
++      MCDRV_INIT_INFO sInitInfo;
++      MCDRV_GP_MODE   sGPMode;
++
++      if(NULL == pbGpio)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_GetInitInfo(&sInitInfo);
++      McResCtrl_GetGPMode(&sGPMode);
++
++      if(((dPadNo == MCDRV_GP_PAD0) && (sInitInfo.bPad0Func != MCDRV_PAD_GPIO))
++      || ((dPadNo == MCDRV_GP_PAD1) && (sInitInfo.bPad1Func != MCDRV_PAD_GPIO)))
++      {
++              return MCDRV_ERROR;
++      }
++
++      if(sGPMode.abGpDdr[dPadNo] == MCDRV_GPDDR_IN)
++      {
++              bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              abData[0]       = MCI_BASE_ADR<<1;
++              abData[1]       = MCI_PA_SCU_PA;
++              McSrv_WriteI2C(bSlaveAddr, abData, 2);
++              bRegData        = McSrv_ReadI2C(bSlaveAddr, MCI_BASE_WINDOW);
++              if(dPadNo == MCDRV_GP_PAD0)
++              {
++                      *pbGpio = bRegData & MCB_PA_SCU_PA0;
++              }
++              else if(dPadNo == MCDRV_GP_PAD1)
++              {
++                      *pbGpio = (bRegData & MCB_PA_SCU_PA1) >> 1;
++              }
++              else
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      else
++      {
++              sdRet   = McPacket_AddGPSet(*pbGpio, dPadNo);
++              if(sdRet != MCDRV_SUCCESS)
++              {
++                      return sdRet;
++              }
++              return McDevIf_ExecutePacket();
++      }
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    get_syseq
++ *
++ *    Description:
++ *                    Get System Eq.
++ *    Arguments:
++ *                    psSysEq pointer to MCDRV_SYSEQ_INFO struct
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_STATE
++ *                    MCDRV_ERROR_ARGUMENT
++*
++ ****************************************************************************/
++static        SINT32  get_syseq
++(
++      MCDRV_SYSEQ_INFO*       psSysEq
++)
++{
++      MCDRV_STATE     eState  = McResCtrl_GetState();
++
++      if(eMCDRV_STATE_NOTINIT == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      if(NULL == psSysEq)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      McResCtrl_GetSysEq(psSysEq);
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    set_syseq
++ *
++ *    Description:
++ *                    Set System Eq.
++ *    Arguments:
++ *                    psSysEq         pointer to MCDRV_SYSEQ_INFO struct
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_STATE
++ *                    MCDRV_ERROR_ARGUMENT
++*
++ ****************************************************************************/
++static        SINT32  set_syseq
++(
++      const MCDRV_SYSEQ_INFO* psSysEq,
++      UINT32                                  dUpdateInfo
++)
++{
++      SINT32          sdRet   = MCDRV_SUCCESS;
++      MCDRV_STATE     eState  = McResCtrl_GetState();
++
++      if(eMCDRV_STATE_NOTINIT == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      if(NULL == psSysEq)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      McResCtrl_SetSysEq(psSysEq, dUpdateInfo);
++      sdRet   = McPacket_AddSysEq(dUpdateInfo);
++      if(sdRet != MCDRV_SUCCESS)
++      {
++              return sdRet;
++      }
++      return McDevIf_ExecutePacket();
++}
++
++
++/****************************************************************************
++ *    ValidateInitParam
++ *
++ *    Description:
++ *                    validate init parameters.
++ *    Arguments:
++ *                    psInitInfo      initialize information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++static        SINT32  ValidateInitParam
++(
++      const MCDRV_INIT_INFO*  psInitInfo
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("ValidateInitParam");
++#endif
++
++
++      if((MCDRV_CKSEL_CMOS != psInitInfo->bCkSel)
++      && (MCDRV_CKSEL_TCXO != psInitInfo->bCkSel)
++      && (MCDRV_CKSEL_CMOS_TCXO != psInitInfo->bCkSel)
++      && (MCDRV_CKSEL_TCXO_CMOS != psInitInfo->bCkSel))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if(((psInitInfo->bDivR0 == 0x00) || (psInitInfo->bDivR0 > 0x3F))
++      || ((psInitInfo->bDivR1 == 0x00) || (psInitInfo->bDivR1 > 0x3F))
++      || ((psInitInfo->bDivF0 == 0x00) || (psInitInfo->bDivF0 > 0x7F))
++      || ((psInitInfo->bDivF1 == 0x00) || (psInitInfo->bDivF1 > 0x7F)))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if((McDevProf_IsValid(eMCDRV_FUNC_RANGE) == 1) && (((psInitInfo->bRange0 > 0x07) || (psInitInfo->bRange1 > 0x07))))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if((McDevProf_IsValid(eMCDRV_FUNC_BYPASS) == 1) && (psInitInfo->bBypass > 0x03))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if(((MCDRV_DAHIZ_LOW != psInitInfo->bDioSdo0Hiz) && (MCDRV_DAHIZ_HIZ != psInitInfo->bDioSdo0Hiz))
++      || ((MCDRV_DAHIZ_LOW != psInitInfo->bDioSdo1Hiz) && (MCDRV_DAHIZ_HIZ != psInitInfo->bDioSdo1Hiz))
++      || ((MCDRV_DAHIZ_LOW != psInitInfo->bDioSdo2Hiz) && (MCDRV_DAHIZ_HIZ != psInitInfo->bDioSdo2Hiz)))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if((MCDRV_PCMHIZ_HIZ != psInitInfo->bPcmHiz) && (MCDRV_PCMHIZ_LOW != psInitInfo->bPcmHiz))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if(((MCDRV_DAHIZ_LOW != psInitInfo->bDioClk0Hiz) && (MCDRV_DAHIZ_HIZ != psInitInfo->bDioClk0Hiz))
++      || ((MCDRV_DAHIZ_LOW != psInitInfo->bDioClk1Hiz) && (MCDRV_DAHIZ_HIZ != psInitInfo->bDioClk1Hiz))
++      || ((MCDRV_DAHIZ_LOW != psInitInfo->bDioClk2Hiz) && (MCDRV_DAHIZ_HIZ != psInitInfo->bDioClk2Hiz)))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if((MCDRV_PCMHIZ_HIZ != psInitInfo->bPcmHiz) && (MCDRV_PCMHIZ_LOW != psInitInfo->bPcmHiz))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if((MCDRV_LINE_STEREO != psInitInfo->bLineIn1Dif) && (MCDRV_LINE_DIF != psInitInfo->bLineIn1Dif))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if((McDevProf_IsValid(eMCDRV_FUNC_LI2) == 1) && (MCDRV_LINE_STEREO != psInitInfo->bLineIn2Dif) && (MCDRV_LINE_DIF != psInitInfo->bLineIn2Dif))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if(((MCDRV_LINE_STEREO != psInitInfo->bLineOut1Dif) && (MCDRV_LINE_DIF != psInitInfo->bLineOut1Dif))
++      || ((MCDRV_LINE_STEREO != psInitInfo->bLineOut2Dif) && (MCDRV_LINE_DIF != psInitInfo->bLineOut2Dif)))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if((MCDRV_SPMN_ON != psInitInfo->bSpmn) && (MCDRV_SPMN_OFF != psInitInfo->bSpmn))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if(((MCDRV_MIC_DIF != psInitInfo->bMic1Sng) && (MCDRV_MIC_SINGLE != psInitInfo->bMic1Sng))
++      || ((MCDRV_MIC_DIF != psInitInfo->bMic2Sng) && (MCDRV_MIC_SINGLE != psInitInfo->bMic2Sng))
++      || ((MCDRV_MIC_DIF != psInitInfo->bMic3Sng) && (MCDRV_MIC_SINGLE != psInitInfo->bMic3Sng)))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if((MCDRV_POWMODE_NORMAL != psInitInfo->bPowerMode)
++      && (MCDRV_POWMODE_CLKON != psInitInfo->bPowerMode)
++      && (MCDRV_POWMODE_VREFON != psInitInfo->bPowerMode)
++      && (MCDRV_POWMODE_CLKVREFON != psInitInfo->bPowerMode)
++      && (MCDRV_POWMODE_FULL != psInitInfo->bPowerMode))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if((MCDRV_SPHIZ_PULLDOWN != psInitInfo->bSpHiz) && (MCDRV_SPHIZ_HIZ != psInitInfo->bSpHiz))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if((MCDRV_LDO_OFF != psInitInfo->bLdo) && (MCDRV_LDO_ON != psInitInfo->bLdo))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if((MCDRV_PAD_GPIO != psInitInfo->bPad0Func) && (MCDRV_PAD_PDMCK != psInitInfo->bPad0Func) && (MCDRV_PAD_IRQ != psInitInfo->bPad0Func))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if((McDevProf_IsValid(eMCDRV_FUNC_IRQ) != 1) && (MCDRV_PAD_IRQ == psInitInfo->bPad0Func))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if((MCDRV_PAD_GPIO != psInitInfo->bPad1Func) && (MCDRV_PAD_PDMDI != psInitInfo->bPad1Func) && (MCDRV_PAD_IRQ != psInitInfo->bPad1Func))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if((McDevProf_IsValid(eMCDRV_FUNC_IRQ) != 1) && (MCDRV_PAD_IRQ == psInitInfo->bPad1Func))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if((McDevProf_IsValid(eMCDRV_FUNC_PAD2) == 1)
++      && (MCDRV_PAD_GPIO != psInitInfo->bPad2Func)
++      && (MCDRV_PAD_PDMDI != psInitInfo->bPad2Func)
++      && (MCDRV_PAD_IRQ != psInitInfo->bPad2Func))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if((MCDRV_OUTLEV_0 != psInitInfo->bAvddLev) && (MCDRV_OUTLEV_1 != psInitInfo->bAvddLev)
++      && (MCDRV_OUTLEV_2 != psInitInfo->bAvddLev) && (MCDRV_OUTLEV_3 != psInitInfo->bAvddLev)
++      && (MCDRV_OUTLEV_4 != psInitInfo->bAvddLev) && (MCDRV_OUTLEV_5 != psInitInfo->bAvddLev)
++      && (MCDRV_OUTLEV_6 != psInitInfo->bAvddLev) && (MCDRV_OUTLEV_7 != psInitInfo->bAvddLev))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if((MCDRV_OUTLEV_0 != psInitInfo->bVrefLev) && (MCDRV_OUTLEV_1 != psInitInfo->bVrefLev)
++      && (MCDRV_OUTLEV_2 != psInitInfo->bVrefLev) && (MCDRV_OUTLEV_3 != psInitInfo->bVrefLev)
++      && (MCDRV_OUTLEV_4 != psInitInfo->bVrefLev) && (MCDRV_OUTLEV_5 != psInitInfo->bVrefLev)
++      && (MCDRV_OUTLEV_6 != psInitInfo->bVrefLev) && (MCDRV_OUTLEV_7 != psInitInfo->bVrefLev))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if((MCDRV_DCLGAIN_0 != psInitInfo->bDclGain) && (MCDRV_DCLGAIN_6 != psInitInfo->bDclGain)
++      && (MCDRV_DCLGAIN_12!= psInitInfo->bDclGain) && (MCDRV_DCLGAIN_18!= psInitInfo->bDclGain))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if((MCDRV_DCLLIMIT_0 != psInitInfo->bDclLimit) && (MCDRV_DCLLIMIT_116 != psInitInfo->bDclLimit)
++      && (MCDRV_DCLLIMIT_250 != psInitInfo->bDclLimit) && (MCDRV_DCLLIMIT_602 != psInitInfo->bDclLimit))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if((MCDRV_CPMOD_ON != psInitInfo->bCpMod) && (MCDRV_CPMOD_OFF != psInitInfo->bCpMod))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if((MCDRV_MAX_WAIT_TIME < psInitInfo->sWaitTime.dAdHpf)
++      || (MCDRV_MAX_WAIT_TIME < psInitInfo->sWaitTime.dMic1Cin)
++      || (MCDRV_MAX_WAIT_TIME < psInitInfo->sWaitTime.dMic2Cin)
++      || (MCDRV_MAX_WAIT_TIME < psInitInfo->sWaitTime.dMic3Cin)
++      || (MCDRV_MAX_WAIT_TIME < psInitInfo->sWaitTime.dLine1Cin)
++      || (MCDRV_MAX_WAIT_TIME < psInitInfo->sWaitTime.dLine2Cin)
++      || (MCDRV_MAX_WAIT_TIME < psInitInfo->sWaitTime.dVrefRdy1)
++      || (MCDRV_MAX_WAIT_TIME < psInitInfo->sWaitTime.dVrefRdy2)
++      || (MCDRV_MAX_WAIT_TIME < psInitInfo->sWaitTime.dHpRdy)
++      || (MCDRV_MAX_WAIT_TIME < psInitInfo->sWaitTime.dSpRdy)
++      || (MCDRV_MAX_WAIT_TIME < psInitInfo->sWaitTime.dPdm))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("ValidateInitParam", &sdRet);
++#endif
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    ValidateClockParam
++ *
++ *    Description:
++ *                    validate clock parameters.
++ *    Arguments:
++ *                    psClockInfo     clock information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++static        SINT32  ValidateClockParam
++(
++      const MCDRV_CLOCK_INFO* psClockInfo
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("ValidateClockParam");
++#endif
++
++
++      if((MCDRV_CKSEL_CMOS != psClockInfo->bCkSel)
++      && (MCDRV_CKSEL_TCXO != psClockInfo->bCkSel)
++      && (MCDRV_CKSEL_CMOS_TCXO != psClockInfo->bCkSel)
++      && (MCDRV_CKSEL_TCXO_CMOS != psClockInfo->bCkSel))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      else if((psClockInfo->bDivR0 == 0x00) || (psClockInfo->bDivR0 > 0x3F))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      else if((psClockInfo->bDivR1 == 0x00) || (psClockInfo->bDivR1 > 0x3F))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      else if((psClockInfo->bDivF0 == 0x00) || (psClockInfo->bDivF0 > 0x7F))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      else if((psClockInfo->bDivF1 == 0x00) || (psClockInfo->bDivF1 > 0x7F))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      else if((McDevProf_IsValid(eMCDRV_FUNC_RANGE) == 1)
++      && ((psClockInfo->bRange0 > 0x07) || (psClockInfo->bRange1 > 0x07)))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      else if((McDevProf_IsValid(eMCDRV_FUNC_BYPASS) == 1) && (psClockInfo->bBypass > 0x03))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      else
++      {
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("ValidateClockParam", &sdRet);
++#endif
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    ValidateReadRegParam
++ *
++ *    Description:
++ *                    validate read reg parameter.
++ *    Arguments:
++ *                    psRegInfo       register information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++static        SINT32  ValidateReadRegParam
++(
++      const MCDRV_REG_INFO*   psRegInfo
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("ValidateReadRegParam");
++#endif
++
++
++      if((McResCtrl_GetRegAccess(psRegInfo) & eMCDRV_READ_ONLY) == 0)
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("ValidateReadRegParam", &sdRet);
++#endif
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    ValidateWriteRegParam
++ *
++ *    Description:
++ *                    validate write reg parameter.
++ *    Arguments:
++ *                    psRegInfo       register information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++static        SINT32  ValidateWriteRegParam
++(
++      const MCDRV_REG_INFO*   psRegInfo
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("ValidateWriteRegParam");
++#endif
++
++
++      if((McResCtrl_GetRegAccess(psRegInfo) & eMCDRV_WRITE_ONLY) == 0)
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("ValidateWriteRegParam", &sdRet);
++#endif
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    ValidatePathParam
++ *
++ *    Description:
++ *                    validate path parameters.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++SINT32        ValidatePathParam
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bBlock;
++      UINT8   bCh;
++      UINT8   bPDMIsSrc       = 0;
++      UINT8   bADC0IsSrc      = 0;
++      MCDRV_PATH_INFO         sCurPathInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("ValidatePathParam");
++#endif
++
++
++      McResCtrl_GetPathInfoVirtual(&sCurPathInfo);
++      /*      set off to current path info    */
++      for(bBlock = 0; bBlock < SOURCE_BLOCK_NUM; bBlock++)
++      {
++              for(bCh = 0; bCh < HP_PATH_CHANNELS; bCh++)
++              {
++                      if((psPathInfo->asHpOut[bCh].abSrcOnOff[bBlock] & (0x03)) == 0x02)
++                      {
++                              sCurPathInfo.asHpOut[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x01;
++                              sCurPathInfo.asHpOut[bCh].abSrcOnOff[bBlock]    |= 0x02;
++                      }
++                      if((psPathInfo->asHpOut[bCh].abSrcOnOff[bBlock] & (0x0C)) == 0x08)
++                      {
++                              sCurPathInfo.asHpOut[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x04;
++                              sCurPathInfo.asHpOut[bCh].abSrcOnOff[bBlock]    |= 0x08;
++                      }
++                      if((psPathInfo->asHpOut[bCh].abSrcOnOff[bBlock] & (0x30)) == 0x20)
++                      {
++                              sCurPathInfo.asHpOut[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x10;
++                              sCurPathInfo.asHpOut[bCh].abSrcOnOff[bBlock]    |= 0x20;
++                      }
++                      if((psPathInfo->asHpOut[bCh].abSrcOnOff[bBlock] & (0xC0)) == 0x80)
++                      {
++                              sCurPathInfo.asHpOut[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x40;
++                              sCurPathInfo.asHpOut[bCh].abSrcOnOff[bBlock]    |= 0x80;
++                      }
++              }
++              for(bCh = 0; bCh < SP_PATH_CHANNELS; bCh++)
++              {
++                      if((psPathInfo->asSpOut[bCh].abSrcOnOff[bBlock] & (0x03)) == 0x02)
++                      {
++                              sCurPathInfo.asSpOut[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x01;
++                              sCurPathInfo.asSpOut[bCh].abSrcOnOff[bBlock]    |= (UINT8)0x02;
++                      }
++                      if((psPathInfo->asSpOut[bCh].abSrcOnOff[bBlock] & (0x0C)) == 0x08)
++                      {
++                              sCurPathInfo.asSpOut[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x04;
++                              sCurPathInfo.asSpOut[bCh].abSrcOnOff[bBlock]    |= (UINT8)0x08;
++                      }
++                      if((psPathInfo->asSpOut[bCh].abSrcOnOff[bBlock] & (0x30)) == 0x20)
++                      {
++                              sCurPathInfo.asSpOut[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x10;
++                              sCurPathInfo.asSpOut[bCh].abSrcOnOff[bBlock]    |= (UINT8)0x20;
++                      }
++                      if((psPathInfo->asSpOut[bCh].abSrcOnOff[bBlock] & (0xC0)) == 0x80)
++                      {
++                              sCurPathInfo.asSpOut[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x40;
++                              sCurPathInfo.asSpOut[bCh].abSrcOnOff[bBlock]    |= (UINT8)0x80;
++                      }
++              }
++              for(bCh = 0; bCh < RC_PATH_CHANNELS; bCh++)
++              {
++                      if((psPathInfo->asRcOut[bCh].abSrcOnOff[bBlock] & (0x03)) == 0x02)
++                      {
++                              sCurPathInfo.asRcOut[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x01;
++                              sCurPathInfo.asRcOut[bCh].abSrcOnOff[bBlock]    |= (UINT8)0x02;
++                      }
++                      if((psPathInfo->asRcOut[bCh].abSrcOnOff[bBlock] & (0x0C)) == 0x08)
++                      {
++                              sCurPathInfo.asRcOut[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x04;
++                              sCurPathInfo.asRcOut[bCh].abSrcOnOff[bBlock]    |= (UINT8)0x08;
++                      }
++                      if((psPathInfo->asRcOut[bCh].abSrcOnOff[bBlock] & (0x30)) == 0x20)
++                      {
++                              sCurPathInfo.asRcOut[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x10;
++                              sCurPathInfo.asRcOut[bCh].abSrcOnOff[bBlock]    |= (UINT8)0x20;
++                      }
++                      if((psPathInfo->asRcOut[bCh].abSrcOnOff[bBlock] & (0xC0)) == 0x80)
++                      {
++                              sCurPathInfo.asRcOut[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x40;
++                              sCurPathInfo.asRcOut[bCh].abSrcOnOff[bBlock]    |= (UINT8)0x80;
++                      }
++              }
++              for(bCh = 0; bCh < LOUT1_PATH_CHANNELS; bCh++)
++              {
++                      if((psPathInfo->asLout1[bCh].abSrcOnOff[bBlock] & (0x03)) == 0x02)
++                      {
++                              sCurPathInfo.asLout1[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x01;
++                              sCurPathInfo.asLout1[bCh].abSrcOnOff[bBlock]    |= (UINT8)0x02;
++                      }
++                      if((psPathInfo->asLout1[bCh].abSrcOnOff[bBlock] & (0x0C)) == 0x08)
++                      {
++                              sCurPathInfo.asLout1[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x04;
++                              sCurPathInfo.asLout1[bCh].abSrcOnOff[bBlock]    |= (UINT8)0x08;
++                      }
++                      if((psPathInfo->asLout1[bCh].abSrcOnOff[bBlock] & (0x30)) == 0x20)
++                      {
++                              sCurPathInfo.asLout1[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x10;
++                              sCurPathInfo.asLout1[bCh].abSrcOnOff[bBlock]    |= (UINT8)0x20;
++                      }
++                      if((psPathInfo->asLout1[bCh].abSrcOnOff[bBlock] & (0xC0)) == 0x80)
++                      {
++                              sCurPathInfo.asLout1[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x40;
++                              sCurPathInfo.asLout1[bCh].abSrcOnOff[bBlock]    |= (UINT8)0x80;
++                      }
++              }
++              for(bCh = 0; bCh < LOUT2_PATH_CHANNELS; bCh++)
++              {
++                      if((psPathInfo->asLout2[bCh].abSrcOnOff[bBlock] & (0x03)) == 0x02)
++                      {
++                              sCurPathInfo.asLout2[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x01;
++                              sCurPathInfo.asLout2[bCh].abSrcOnOff[bBlock]    |= 0x02;
++                      }
++                      if((psPathInfo->asLout2[bCh].abSrcOnOff[bBlock] & (0x0C)) == 0x08)
++                      {
++                              sCurPathInfo.asLout2[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x04;
++                              sCurPathInfo.asLout2[bCh].abSrcOnOff[bBlock]    |= 0x08;
++                      }
++                      if((psPathInfo->asLout2[bCh].abSrcOnOff[bBlock] & (0x30)) == 0x20)
++                      {
++                              sCurPathInfo.asLout2[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x10;
++                              sCurPathInfo.asLout2[bCh].abSrcOnOff[bBlock]    |= 0x20;
++                      }
++                      if((psPathInfo->asLout2[bCh].abSrcOnOff[bBlock] & (0xC0)) == 0x80)
++                      {
++                              sCurPathInfo.asLout2[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x40;
++                              sCurPathInfo.asLout2[bCh].abSrcOnOff[bBlock]    |= 0x80;
++                      }
++              }
++              for(bCh = 0; bCh < DIT0_PATH_CHANNELS; bCh++)
++              {
++                      if((psPathInfo->asDit0[bCh].abSrcOnOff[bBlock] & (0x03)) == 0x02)
++                      {
++                              sCurPathInfo.asDit0[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x01;
++                              sCurPathInfo.asDit0[bCh].abSrcOnOff[bBlock]     |= 0x02;
++                      }
++                      if((psPathInfo->asDit0[bCh].abSrcOnOff[bBlock] & (0x0C)) == 0x08)
++                      {
++                              sCurPathInfo.asDit0[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x04;
++                              sCurPathInfo.asDit0[bCh].abSrcOnOff[bBlock]     |= 0x08;
++                      }
++                      if((psPathInfo->asDit0[bCh].abSrcOnOff[bBlock] & (0x30)) == 0x20)
++                      {
++                              sCurPathInfo.asDit0[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x10;
++                              sCurPathInfo.asDit0[bCh].abSrcOnOff[bBlock]     |= 0x20;
++                      }
++                      if((psPathInfo->asDit0[bCh].abSrcOnOff[bBlock] & (0xC0)) == 0x80)
++                      {
++                              sCurPathInfo.asDit0[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x40;
++                              sCurPathInfo.asDit0[bCh].abSrcOnOff[bBlock]     |= 0x80;
++                      }
++              }
++              for(bCh = 0; bCh < DIT1_PATH_CHANNELS; bCh++)
++              {
++                      if((psPathInfo->asDit1[bCh].abSrcOnOff[bBlock] & (0x03)) == 0x02)
++                      {
++                              sCurPathInfo.asDit1[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x01;
++                              sCurPathInfo.asDit1[bCh].abSrcOnOff[bBlock]     |= 0x02;
++                      }
++                      if((psPathInfo->asDit1[bCh].abSrcOnOff[bBlock] & (0x0C)) == 0x08)
++                      {
++                              sCurPathInfo.asDit1[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x04;
++                              sCurPathInfo.asDit1[bCh].abSrcOnOff[bBlock]     |= 0x08;
++                      }
++                      if((psPathInfo->asDit1[bCh].abSrcOnOff[bBlock] & (0x30)) == 0x20)
++                      {
++                              sCurPathInfo.asDit1[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x10;
++                              sCurPathInfo.asDit1[bCh].abSrcOnOff[bBlock]     |= 0x20;
++                      }
++                      if((psPathInfo->asDit1[bCh].abSrcOnOff[bBlock] & (0xC0)) == 0x80)
++                      {
++                              sCurPathInfo.asDit1[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x40;
++                              sCurPathInfo.asDit1[bCh].abSrcOnOff[bBlock]     |= 0x80;
++                      }
++              }
++              for(bCh = 0; bCh < DIT2_PATH_CHANNELS; bCh++)
++              {
++                      if((psPathInfo->asDit2[bCh].abSrcOnOff[bBlock] & (0x03)) == 0x02)
++                      {
++                              sCurPathInfo.asDit2[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x01;
++                              sCurPathInfo.asDit2[bCh].abSrcOnOff[bBlock]     |= 0x02;
++                      }
++                      if((psPathInfo->asDit2[bCh].abSrcOnOff[bBlock] & (0x0C)) == 0x08)
++                      {
++                              sCurPathInfo.asDit2[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x04;
++                              sCurPathInfo.asDit2[bCh].abSrcOnOff[bBlock]     |= 0x08;
++                      }
++                      if((psPathInfo->asDit2[bCh].abSrcOnOff[bBlock] & (0x30)) == 0x20)
++                      {
++                              sCurPathInfo.asDit2[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x10;
++                              sCurPathInfo.asDit2[bCh].abSrcOnOff[bBlock]     |= 0x20;
++                      }
++                      if((psPathInfo->asDit2[bCh].abSrcOnOff[bBlock] & (0xC0)) == 0x80)
++                      {
++                              sCurPathInfo.asDit2[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x40;
++                              sCurPathInfo.asDit2[bCh].abSrcOnOff[bBlock]     |= 0x80;
++                      }
++              }
++              for(bCh = 0; bCh < DAC_PATH_CHANNELS; bCh++)
++              {
++                      if((psPathInfo->asDac[bCh].abSrcOnOff[bBlock] & (0x03)) == 0x02)
++                      {
++                              sCurPathInfo.asDac[bCh].abSrcOnOff[bBlock]      &= (UINT8)~0x01;
++                              sCurPathInfo.asDac[bCh].abSrcOnOff[bBlock]      |= 0x02;
++                      }
++                      if((psPathInfo->asDac[bCh].abSrcOnOff[bBlock] & (0x0C)) == 0x08)
++                      {
++                              sCurPathInfo.asDac[bCh].abSrcOnOff[bBlock]      &= (UINT8)~0x04;
++                              sCurPathInfo.asDac[bCh].abSrcOnOff[bBlock]      |= 0x08;
++                      }
++                      if((psPathInfo->asDac[bCh].abSrcOnOff[bBlock] & (0x30)) == 0x20)
++                      {
++                              sCurPathInfo.asDac[bCh].abSrcOnOff[bBlock]      &= (UINT8)~0x10;
++                              sCurPathInfo.asDac[bCh].abSrcOnOff[bBlock]      |= 0x20;
++                      }
++                      if((psPathInfo->asDac[bCh].abSrcOnOff[bBlock] & (0xC0)) == 0x80)
++                      {
++                              sCurPathInfo.asDac[bCh].abSrcOnOff[bBlock]      &= (UINT8)~0x40;
++                              sCurPathInfo.asDac[bCh].abSrcOnOff[bBlock]      |= 0x80;
++                      }
++              }
++              for(bCh = 0; bCh < AE_PATH_CHANNELS; bCh++)
++              {
++                      if((psPathInfo->asAe[bCh].abSrcOnOff[bBlock] & (0x03)) == 0x02)
++                      {
++                              sCurPathInfo.asAe[bCh].abSrcOnOff[bBlock]       &= (UINT8)~0x01;
++                              sCurPathInfo.asAe[bCh].abSrcOnOff[bBlock]       |= 0x02;
++                      }
++                      if((psPathInfo->asAe[bCh].abSrcOnOff[bBlock] & (0x0C)) == 0x08)
++                      {
++                              sCurPathInfo.asAe[bCh].abSrcOnOff[bBlock]       &= (UINT8)~0x04;
++                              sCurPathInfo.asAe[bCh].abSrcOnOff[bBlock]       |= 0x08;
++                      }
++                      if((psPathInfo->asAe[bCh].abSrcOnOff[bBlock] & (0x30)) == 0x20)
++                      {
++                              sCurPathInfo.asAe[bCh].abSrcOnOff[bBlock]       &= (UINT8)~0x10;
++                              sCurPathInfo.asAe[bCh].abSrcOnOff[bBlock]       |= 0x20;
++                      }
++                      if((psPathInfo->asAe[bCh].abSrcOnOff[bBlock] & (0xC0)) == 0x80)
++                      {
++                              sCurPathInfo.asAe[bCh].abSrcOnOff[bBlock]       &= (UINT8)~0x40;
++                              sCurPathInfo.asAe[bCh].abSrcOnOff[bBlock]       |= 0x80;
++                      }
++              }
++              for(bCh = 0; bCh < ADC0_PATH_CHANNELS; bCh++)
++              {
++                      if((psPathInfo->asAdc0[bCh].abSrcOnOff[bBlock] & (0x03)) == 0x02)
++                      {
++                              sCurPathInfo.asAdc0[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x01;
++                              sCurPathInfo.asAdc0[bCh].abSrcOnOff[bBlock]     |= (UINT8)0x02;
++                      }
++                      if((psPathInfo->asAdc0[bCh].abSrcOnOff[bBlock] & (0x0C)) == 0x08)
++                      {
++                              sCurPathInfo.asAdc0[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x04;
++                              sCurPathInfo.asAdc0[bCh].abSrcOnOff[bBlock]     |= (UINT8)0x08;
++                      }
++                      if((psPathInfo->asAdc0[bCh].abSrcOnOff[bBlock] & (0x30)) == 0x20)
++                      {
++                              sCurPathInfo.asAdc0[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x10;
++                              sCurPathInfo.asAdc0[bCh].abSrcOnOff[bBlock]     |= (UINT8)0x20;
++                      }
++                      if((psPathInfo->asAdc0[bCh].abSrcOnOff[bBlock] & (0xC0)) == 0x80)
++                      {
++                              sCurPathInfo.asAdc0[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x40;
++                              sCurPathInfo.asAdc0[bCh].abSrcOnOff[bBlock]     |= (UINT8)0x80;
++                      }
++              }
++              for(bCh = 0; bCh < MIX_PATH_CHANNELS; bCh++)
++              {
++                      if((psPathInfo->asMix[bCh].abSrcOnOff[bBlock] & (0x03)) == 0x02)
++                      {
++                              sCurPathInfo.asMix[bCh].abSrcOnOff[bBlock]      &= (UINT8)~0x01;
++                              sCurPathInfo.asMix[bCh].abSrcOnOff[bBlock]      |= 0x02;
++                      }
++                      if((psPathInfo->asMix[bCh].abSrcOnOff[bBlock] & (0x0C)) == 0x08)
++                      {
++                              sCurPathInfo.asMix[bCh].abSrcOnOff[bBlock]      &= (UINT8)~0x04;
++                              sCurPathInfo.asMix[bCh].abSrcOnOff[bBlock]      |= 0x08;
++                      }
++                      if((psPathInfo->asMix[bCh].abSrcOnOff[bBlock] & (0x30)) == 0x20)
++                      {
++                              sCurPathInfo.asMix[bCh].abSrcOnOff[bBlock]      &= (UINT8)~0x10;
++                              sCurPathInfo.asMix[bCh].abSrcOnOff[bBlock]      |= 0x20;
++                      }
++                      if((psPathInfo->asMix[bCh].abSrcOnOff[bBlock] & (0xC0)) == 0x80)
++                      {
++                              sCurPathInfo.asMix[bCh].abSrcOnOff[bBlock]      &= (UINT8)~0x40;
++                              sCurPathInfo.asMix[bCh].abSrcOnOff[bBlock]      |= 0x80;
++                      }
++              }
++      }
++
++      if(((sCurPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON)
++      || ((sCurPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON)
++      || ((sCurPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON)
++      || ((sCurPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON)
++      || ((sCurPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON)
++      || ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON)
++      || ((sCurPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON))
++      {
++              bPDMIsSrc       = 1;
++      }
++      if(((sCurPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON)
++      || ((sCurPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON)
++      || ((sCurPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON)
++      || ((sCurPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON)
++      || ((sCurPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON)
++      || ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON)
++      || ((sCurPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON))
++      {
++              bADC0IsSrc      = 1;
++      }
++
++      /*      HP      */
++      if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++      {
++              if(((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++              || ((sCurPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              if((sCurPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++      {
++              if(((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++              || ((sCurPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++      {
++              if((sCurPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++
++      /*      SP      */
++      if((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++      {
++              if(((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++              || ((sCurPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              if((sCurPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++      {
++              if(((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++              || ((sCurPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++      {
++              if((sCurPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_ON)
++      {
++              if(((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++              || ((sCurPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              if((sCurPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_ON)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & (MCDRV_SRC5_DAC_R_ON|MCDRV_SRC5_DAC_R_OFF)) == MCDRV_SRC5_DAC_R_ON)
++      {
++              if(((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++              || ((sCurPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++      {
++              if((sCurPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & (MCDRV_SRC5_DAC_R_ON|MCDRV_SRC5_DAC_R_OFF)) == MCDRV_SRC5_DAC_R_ON)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++
++      /*      RCV     */
++
++      /*      LOUT1   */
++      if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++      {
++              if(((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++              || ((sCurPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              if((sCurPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++      {
++              if(((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++              || ((sCurPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++      {
++              if((sCurPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++
++      /*      LOUT2   */
++      if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++      {
++              if(((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++              || ((sCurPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              if((sCurPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++      {
++              if(((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++              || ((sCurPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++      {
++              if((sCurPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++
++      /*      PeakMeter       */
++
++      /*      DIT0    */
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++      {
++              if(((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++              || ((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++              || ((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++              || ((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++              || ((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++              || ((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              || ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++      {
++              if(((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++              || ((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++              || ((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++              || ((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++              || ((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              || ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++      {
++              if(((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++              || ((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++              || ((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++              || ((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              || ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      {
++              if(((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++              || ((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++              || ((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              || ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              if(((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++              || ((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              || ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++      {
++              if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++      {
++              if((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      {
++              if(bADC0IsSrc == 1)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++              else
++              {
++                      bPDMIsSrc       = 1;
++              }
++      }
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              if(bPDMIsSrc == 1)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++              else
++              {
++                      bADC0IsSrc      = 1;
++              }
++      }
++
++      /*      DIT1    */
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++      {
++              if(((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++              || ((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++              || ((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++              || ((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++              || ((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++              || ((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              || ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++      {
++              if(((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++              || ((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++              || ((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++              || ((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++              || ((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              || ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++      {
++              if(((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++              || ((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++              || ((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++              || ((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              || ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      {
++              if(((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++              || ((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++              || ((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              || ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              if(((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++              || ((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              || ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++      {
++              if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++      {
++              if((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      {
++              if(bADC0IsSrc == 1)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++              else
++              {
++                      bPDMIsSrc       = 1;
++              }
++      }
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              if(bPDMIsSrc == 1)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++              else
++              {
++                      bADC0IsSrc      = 1;
++              }
++      }
++
++      /*      DIT2    */
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++      {
++              if(((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++              || ((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++              || ((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++              || ((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++              || ((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++              || ((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              || ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++      {
++              if(((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++              || ((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++              || ((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++              || ((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++              || ((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              || ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++      {
++              if(((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++              || ((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++              || ((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++              || ((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              || ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      {
++              if(((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++              || ((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++              || ((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              || ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              if(((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++              || ((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              || ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++      {
++              if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++      {
++              if((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      {
++              if(bADC0IsSrc == 1)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++              else
++              {
++                      bPDMIsSrc       = 1;
++              }
++      }
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              if(bPDMIsSrc == 1)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++              else
++              {
++                      bADC0IsSrc      = 1;
++              }
++      }
++
++      /*      DAC     */
++      for(bCh = 0; bCh < DAC_PATH_CHANNELS; bCh++)
++      {
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++              {
++                      if(((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++                      || ((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++                      || ((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++                      || ((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++                      || ((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++                      || ((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++                      || ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON))
++                      {
++                              sdRet   = MCDRV_ERROR_ARGUMENT;
++                      }
++              }
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++              {
++                      if(((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++                      || ((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++                      || ((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++                      || ((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++                      || ((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++                      || ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON))
++                      {
++                              sdRet   = MCDRV_ERROR_ARGUMENT;
++                      }
++              }
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++              {
++                      if(((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++                      || ((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++                      || ((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++                      || ((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++                      || ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON))
++                      {
++                              sdRet   = MCDRV_ERROR_ARGUMENT;
++                      }
++              }
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++              {
++                      if(((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++                      || ((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++                      || ((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++                      || ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON))
++                      {
++                              sdRet   = MCDRV_ERROR_ARGUMENT;
++                      }
++              }
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++              {
++                      if(((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++                      || ((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++                      || ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON))
++                      {
++                              sdRet   = MCDRV_ERROR_ARGUMENT;
++                      }
++              }
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++              {
++                      if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++                      {
++                              sdRet   = MCDRV_ERROR_ARGUMENT;
++                      }
++              }
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              {
++                      if((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++                      {
++                              sdRet   = MCDRV_ERROR_ARGUMENT;
++                      }
++              }
++
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++              {
++                      if(bADC0IsSrc == 1)
++                      {
++                              sdRet   = MCDRV_ERROR_ARGUMENT;
++                      }
++                      else
++                      {
++                              bPDMIsSrc       = 1;
++                      }
++              }
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++              {
++                      if(bPDMIsSrc == 1)
++                      {
++                              sdRet   = MCDRV_ERROR_ARGUMENT;
++                      }
++                      else
++                      {
++                              bADC0IsSrc      = 1;
++                      }
++              }
++      }
++
++      /*      AE      */
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++      {
++              if(((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++              || ((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++              || ((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++              || ((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++              || ((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++      {
++              if(((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++              || ((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++              || ((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++              || ((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++      {
++              if(((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++              || ((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++              || ((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      {
++              if(((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++              || ((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      {
++              if(bADC0IsSrc == 1)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++              else
++              {
++                      bPDMIsSrc       = 1;
++              }
++      }
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              if(bPDMIsSrc == 1)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++              else
++              {
++                      bADC0IsSrc      = 1;
++              }
++      }
++      if(((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++      && (((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++              || ((sCurPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON)))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++
++      /*      CDSP    */
++      for(bCh = 0; bCh < 4; bCh++)
++      {
++      }
++
++      /*      ADC0    */
++      if((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++      {
++              if(((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++              || ((sCurPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              if((sCurPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_ON)
++      {
++              if(((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++              || ((sCurPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              if((sCurPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_ON)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++
++      /*      ADC1    */
++
++      /*      MIX     */
++      if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      {
++              if(bADC0IsSrc == 1)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++              else
++              {
++                      bPDMIsSrc       = 1;
++              }
++      }
++      if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              if(bPDMIsSrc == 1)
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++              else
++              {
++                      bADC0IsSrc      = 1;
++              }
++      }
++      if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++      {
++              if(((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              || ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & MCDRV_SRC6_MIX_ON) == MCDRV_SRC6_MIX_ON))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if(((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++      && ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if(((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++      && ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if(((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++      && ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if(((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      && ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if(((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      && ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++      && (((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++       || ((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++       || ((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++       || ((psPathInfo->asDac[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++       || ((psPathInfo->asDac[1].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++       || ((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++       || ((sCurPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++       || ((sCurPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++       || ((sCurPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++       || ((sCurPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++       || ((sCurPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++       || ((sCurPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++       ))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if(((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++      && (((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++       || ((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++       || ((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++       || ((psPathInfo->asDac[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++       || ((psPathInfo->asDac[1].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++       || ((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++       || ((sCurPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++       || ((sCurPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++       || ((sCurPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++       || ((sCurPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++       || ((sCurPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++       || ((sCurPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++       ))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if(((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++      && (((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++       || ((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++       || ((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++       || ((psPathInfo->asDac[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++       || ((psPathInfo->asDac[1].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++       || ((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++       || ((sCurPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++       || ((sCurPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++       || ((sCurPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++       || ((sCurPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++       || ((sCurPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++       || ((sCurPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++       ))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if(((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      && (((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++       || ((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++       || ((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++       || ((psPathInfo->asDac[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++       || ((psPathInfo->asDac[1].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++       || ((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++       || ((sCurPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++       || ((sCurPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++       || ((sCurPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++       || ((sCurPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++       || ((sCurPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++       || ((sCurPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if(((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      && (((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++       || ((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++       || ((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++       || ((psPathInfo->asDac[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++       || ((psPathInfo->asDac[1].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++       || ((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++       || ((sCurPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++       || ((sCurPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++       || ((sCurPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++       || ((sCurPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++       || ((sCurPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++       || ((sCurPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if(((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++      && (((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++       || ((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++       || ((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++       || ((psPathInfo->asDac[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++       || ((psPathInfo->asDac[1].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++       || ((sCurPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++       || ((sCurPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++       || ((sCurPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++       || ((sCurPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++       || ((sCurPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++       ))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("ValidatePathParam", &sdRet);
++#endif
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    ValidateDioParam
++ *
++ *    Description:
++ *                    validate digital IO parameters.
++ *    Arguments:
++ *                    psDioInfo       digital IO information
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++static SINT32 ValidateDioParam
++(
++      const MCDRV_DIO_INFO*   psDioInfo,
++      UINT32                                  dUpdateInfo
++)
++{
++      SINT32                          sdRet   = MCDRV_SUCCESS;
++      UINT8                           bPort;
++      MCDRV_SRC_TYPE          aeDITSource[IOPORT_NUM];
++      MCDRV_SRC_TYPE          eAESource;
++      MCDRV_SRC_TYPE          eDAC0Source;
++      MCDRV_SRC_TYPE          eDAC1Source;
++      UINT8                           bDIRUsed[IOPORT_NUM];
++      MCDRV_DIO_INFO          sDioInfo;
++      MCDRV_DIO_PORT_NO       aePort[IOPORT_NUM]      = {eMCDRV_DIO_0, eMCDRV_DIO_1, eMCDRV_DIO_2};
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("ValidateDioParam");
++#endif
++
++      eAESource       = McResCtrl_GetAESource();
++      eDAC0Source     = McResCtrl_GetDACSource(eMCDRV_DAC_MASTER);
++      eDAC1Source     = McResCtrl_GetDACSource(eMCDRV_DAC_VOICE);
++
++
++      McResCtrl_GetDioInfo(&sDioInfo);
++
++      for(bPort = 0; bPort < IOPORT_NUM; bPort++)
++      {
++              aeDITSource[bPort]      = McResCtrl_GetDITSource(aePort[bPort]);
++              bDIRUsed[bPort]         = 0;
++      }
++
++      if(((eAESource == eMCDRV_SRC_DIR0) || (eDAC0Source == eMCDRV_SRC_DIR0) || (eDAC1Source == eMCDRV_SRC_DIR0))
++      || ((aeDITSource[0] == eMCDRV_SRC_DIR0) || (aeDITSource[1] == eMCDRV_SRC_DIR0) || (aeDITSource[2] == eMCDRV_SRC_DIR0)))
++      {
++              bDIRUsed[0]     = 1;
++      }
++      if(((eAESource == eMCDRV_SRC_DIR1) || (eDAC0Source == eMCDRV_SRC_DIR1) || (eDAC1Source == eMCDRV_SRC_DIR1))
++      || ((aeDITSource[0] == eMCDRV_SRC_DIR1) || (aeDITSource[1] == eMCDRV_SRC_DIR1) || (aeDITSource[2] == eMCDRV_SRC_DIR1)))
++      {
++              bDIRUsed[1]     = 1;
++      }
++      if(((eAESource == eMCDRV_SRC_DIR2) || (eDAC0Source == eMCDRV_SRC_DIR2) || (eDAC1Source == eMCDRV_SRC_DIR2))
++      || ((aeDITSource[0] == eMCDRV_SRC_DIR2) || (aeDITSource[1] == eMCDRV_SRC_DIR2) || (aeDITSource[2] == eMCDRV_SRC_DIR2)))
++      {
++              bDIRUsed[2]     = 1;
++      }
++
++      if(((bDIRUsed[0] == 1) && (((dUpdateInfo & MCDRV_DIO0_COM_UPDATE_FLAG) != 0UL) || ((dUpdateInfo & MCDRV_DIO0_DIR_UPDATE_FLAG) != 0UL)))
++      || ((aeDITSource[0] != eMCDRV_SRC_NONE) && (((dUpdateInfo & MCDRV_DIO0_COM_UPDATE_FLAG) != 0UL) || ((dUpdateInfo & MCDRV_DIO0_DIT_UPDATE_FLAG) != 0UL))))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if(((bDIRUsed[1] == 1) && (((dUpdateInfo & MCDRV_DIO1_COM_UPDATE_FLAG) != 0UL) || ((dUpdateInfo & MCDRV_DIO1_DIR_UPDATE_FLAG) != 0UL)))
++      || ((aeDITSource[1] != eMCDRV_SRC_NONE) && (((dUpdateInfo & MCDRV_DIO1_COM_UPDATE_FLAG) != 0UL) || ((dUpdateInfo & MCDRV_DIO1_DIT_UPDATE_FLAG) != 0UL))))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++      if(((bDIRUsed[2] == 1) && (((dUpdateInfo & MCDRV_DIO2_COM_UPDATE_FLAG) != 0UL) || ((dUpdateInfo & MCDRV_DIO2_DIR_UPDATE_FLAG) != 0UL)))
++      || ((aeDITSource[2] != eMCDRV_SRC_NONE) && (((dUpdateInfo & MCDRV_DIO2_COM_UPDATE_FLAG) != 0UL) || ((dUpdateInfo & MCDRV_DIO2_DIT_UPDATE_FLAG) != 0UL))))
++      {
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              if((dUpdateInfo & MCDRV_DIO0_COM_UPDATE_FLAG) != 0UL)
++              {
++                      sdRet   = CheckDIOCommon(psDioInfo, 0);
++                      if(sdRet == MCDRV_SUCCESS)
++                      {
++                              sDioInfo.asPortInfo[0].sDioCommon.bInterface    = psDioInfo->asPortInfo[0].sDioCommon.bInterface;
++                      }
++              }
++      }
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              if((dUpdateInfo & MCDRV_DIO1_COM_UPDATE_FLAG) != 0UL)
++              {
++                      sdRet   = CheckDIOCommon(psDioInfo, 1);
++                      if(sdRet == MCDRV_SUCCESS)
++                      {
++                              sDioInfo.asPortInfo[1].sDioCommon.bInterface    = psDioInfo->asPortInfo[1].sDioCommon.bInterface;
++                      }
++              }
++      }
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              if((dUpdateInfo & MCDRV_DIO2_COM_UPDATE_FLAG) != 0UL)
++              {
++                      sdRet   = CheckDIOCommon(psDioInfo, 2);
++                      if(sdRet == MCDRV_SUCCESS)
++                      {
++                              sDioInfo.asPortInfo[2].sDioCommon.bInterface    = psDioInfo->asPortInfo[2].sDioCommon.bInterface;
++                      }
++              }
++      }
++
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              if((dUpdateInfo & MCDRV_DIO0_DIR_UPDATE_FLAG) != 0UL)
++              {
++                      sdRet   = CheckDIODIR(psDioInfo, 0, sDioInfo.asPortInfo[0].sDioCommon.bInterface);
++              }
++      }
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              if((dUpdateInfo & MCDRV_DIO1_DIR_UPDATE_FLAG) != 0UL)
++              {
++                      sdRet   = CheckDIODIR(psDioInfo, 1, sDioInfo.asPortInfo[1].sDioCommon.bInterface);
++              }
++      }
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              if((dUpdateInfo & MCDRV_DIO2_DIR_UPDATE_FLAG) != 0UL)
++              {
++                      sdRet   = CheckDIODIR(psDioInfo, 2, sDioInfo.asPortInfo[2].sDioCommon.bInterface);
++              }
++      }
++
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              if((dUpdateInfo & MCDRV_DIO0_DIT_UPDATE_FLAG) != 0UL)
++              {
++                      sdRet   = CheckDIODIT(psDioInfo, 0, sDioInfo.asPortInfo[0].sDioCommon.bInterface);
++              }
++      }
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              if((dUpdateInfo & MCDRV_DIO1_DIT_UPDATE_FLAG) != 0UL)
++              {
++                      sdRet   = CheckDIODIT(psDioInfo, 1, sDioInfo.asPortInfo[1].sDioCommon.bInterface);
++              }
++      }
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              if((dUpdateInfo & MCDRV_DIO2_DIT_UPDATE_FLAG) != 0UL)
++              {
++                      sdRet   = CheckDIODIT(psDioInfo, 2, sDioInfo.asPortInfo[2].sDioCommon.bInterface);
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("ValidateDioParam", &sdRet);
++#endif
++
++      return sdRet;
++}
++
++
++/****************************************************************************
++ *    CheckDIOCommon
++ *
++ *    Description:
++ *                    validate Digital IO Common parameters.
++ *    Arguments:
++ *                    psDioInfo       digital IO information
++ *                    bPort           port number
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++static SINT32 CheckDIOCommon
++(
++      const MCDRV_DIO_INFO*   psDioInfo,
++      UINT8   bPort
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("CheckDIOCommon");
++#endif
++
++
++      if(psDioInfo->asPortInfo[bPort].sDioCommon.bInterface == MCDRV_DIO_PCM)
++      {
++              if((psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_48000)
++              || (psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_44100)
++              || (psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_32000)
++              || (psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_24000)
++              || (psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_22050)
++              || (psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_12000)
++              || (psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_11025))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++
++              if((psDioInfo->asPortInfo[bPort].sDioCommon.bMasterSlave == MCDRV_DIO_MASTER)
++              && (psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_16000))
++              {
++                      if(psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs == MCDRV_BCKFS_512)
++                      {
++                              sdRet   = MCDRV_ERROR_ARGUMENT;
++                      }
++              }
++      }
++      else
++      {
++              if((psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs == MCDRV_BCKFS_512)
++              || (psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs == MCDRV_BCKFS_256)
++              || (psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs == MCDRV_BCKFS_128)
++              || (psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs == MCDRV_BCKFS_16))
++              {
++                      sdRet   = MCDRV_ERROR_ARGUMENT;
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("CheckDIOCommon", &sdRet);
++#endif
++      return sdRet;
++}
++
++/****************************************************************************
++ *    CheckDIODIR
++ *
++ *    Description:
++ *                    validate Digital IO DIR parameters.
++ *    Arguments:
++ *                    psDioInfo       digital IO information
++ *                    bPort           port number
++ *                    bInterface      Interface(DA/PCM)
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++static SINT32 CheckDIODIR
++(
++      const MCDRV_DIO_INFO*   psDioInfo,
++      UINT8   bPort,
++      UINT8   bInterface
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("CheckDIODIR");
++#endif
++
++
++      if(bInterface == MCDRV_DIO_PCM)
++      {
++              if((psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bLaw == MCDRV_PCM_ALAW)
++              || (psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bLaw == MCDRV_PCM_MULAW))
++              {
++                      if((psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_13)
++                      || (psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_14)
++                      || (psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_16))
++                      {
++                              sdRet   = MCDRV_ERROR_ARGUMENT;
++                      }
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("CheckDIODIR", &sdRet);
++#endif
++      return sdRet;
++}
++
++/****************************************************************************
++ *    CheckDIDIT
++ *
++ *    Description:
++ *                    validate Digital IO DIT parameters.
++ *    Arguments:
++ *                    psDioInfo       digital IO information
++ *                    bPort           port number
++ *                    bInterface      Interface(DA/PCM)
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++static SINT32 CheckDIODIT
++(
++      const MCDRV_DIO_INFO*   psDioInfo,
++      UINT8   bPort,
++      UINT8   bInterface
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("CheckDIODIT");
++#endif
++
++
++      if(bInterface == MCDRV_DIO_PCM)
++      {
++              if((psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bLaw == MCDRV_PCM_ALAW)
++              || (psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bLaw == MCDRV_PCM_MULAW))
++              {
++                      if((psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_13)
++                      || (psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_14)
++                      || (psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_16))
++                      {
++                              sdRet   = MCDRV_ERROR_ARGUMENT;
++                      }
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("CheckDIODIT", &sdRet);
++#endif
++      return sdRet;
++}
++
++/****************************************************************************
++ *    SetVol
++ *
++ *    Description:
++ *                    set volume.
++ *    Arguments:
++ *                    dUpdate                 target volume items
++ *                    eMode                   update mode
++ *                    pdSVolDoneParam wait soft volume complete flag
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *
++ ****************************************************************************/
++static SINT32 SetVol
++(
++      UINT32                                  dUpdate,
++      MCDRV_VOLUPDATE_MODE    eMode,
++      UINT32*                                 pdSVolDoneParam
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("SetVol");
++#endif
++
++      sdRet   = McPacket_AddVol(dUpdate, eMode, pdSVolDoneParam);
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              sdRet   = McDevIf_ExecutePacket();
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("SetVol", &sdRet);
++#endif
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    PreUpdatePath
++ *
++ *    Description:
++ *                    Preprocess update path.
++ *    Arguments:
++ *                    pwDACMuteParam  wait DAC mute complete flag
++ *                    pwDITMuteParam  wait DIT mute complete flag
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *
++ ****************************************************************************/
++static        SINT32  PreUpdatePath
++(
++      UINT16* pwDACMuteParam,
++      UINT16* pwDITMuteParam
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bReg    = 0;
++      UINT8   bReadReg= 0;
++      UINT8   bLAT    = 0;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("PreUpdatePath");
++#endif
++
++      *pwDACMuteParam = 0;
++      *pwDITMuteParam = 0;
++
++      switch(McResCtrl_GetDACSource(eMCDRV_DAC_MASTER))
++      {
++      case    eMCDRV_SRC_PDM:
++              bReg    = MCB_DAC_SOURCE_AD;
++              break;
++      case    eMCDRV_SRC_ADC0:
++              bReg    = MCB_DAC_SOURCE_AD;
++              break;
++      case    eMCDRV_SRC_DIR0:
++              bReg    = MCB_DAC_SOURCE_DIR0;
++              break;
++      case    eMCDRV_SRC_DIR1:
++              bReg    = MCB_DAC_SOURCE_DIR1;
++              break;
++      case    eMCDRV_SRC_DIR2:
++              bReg    = MCB_DAC_SOURCE_DIR2;
++              break;
++      case    eMCDRV_SRC_MIX:
++              bReg    = MCB_DAC_SOURCE_MIX;
++              break;
++      default:
++              bReg    = 0;
++      }
++      bReadReg        = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_SOURCE);
++      if(((bReadReg & 0xF0) != 0) && (bReg != (bReadReg & 0xF0)))
++      {/*     DAC source changed      */
++              if((McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_MASTER_OUTL)&MCB_MASTER_OUTL) != 0)
++              {
++                      if(McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_MASTER_OUTR) != 0)
++                      {
++                              bLAT    = MCB_MASTER_OLAT;
++                      }
++                      else
++                      {
++                              bLAT    = 0;
++                      }
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_MASTER_OUTL, bLAT);
++              }
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_MASTER_OUTR, 0);
++              *pwDACMuteParam |= (UINT16)(MCB_MASTER_OFLAGL<<8);
++              *pwDACMuteParam |= MCB_MASTER_OFLAGR;
++      }
++
++      switch(McResCtrl_GetDACSource(eMCDRV_DAC_VOICE))
++      {
++      case    eMCDRV_SRC_PDM:
++              bReg    = MCB_VOICE_SOURCE_AD;
++              break;
++      case    eMCDRV_SRC_ADC0:
++              bReg    = MCB_VOICE_SOURCE_AD;
++              break;
++      case    eMCDRV_SRC_DIR0:
++              bReg    = MCB_VOICE_SOURCE_DIR0;
++              break;
++      case    eMCDRV_SRC_DIR1:
++              bReg    = MCB_VOICE_SOURCE_DIR1;
++              break;
++      case    eMCDRV_SRC_DIR2:
++              bReg    = MCB_VOICE_SOURCE_DIR2;
++              break;
++      case    eMCDRV_SRC_MIX:
++              bReg    = MCB_VOICE_SOURCE_MIX;
++              break;
++      default:
++              bReg    = 0;
++      }
++      if(((bReadReg & 0x0F) != 0) && (bReg != (bReadReg & 0x0F)))
++      {/*     VOICE source changed    */
++              if((McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_VOICE_ATTL)&MCB_VOICE_ATTL) != 0)
++              {
++                      if(McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_VOICE_ATTR) != 0)
++                      {
++                              bLAT    = MCB_VOICE_LAT;
++                      }
++                      else
++                      {
++                              bLAT    = 0;
++                      }
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_VOICE_ATTL, bLAT);
++              }
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_VOICE_ATTR, 0);
++              *pwDACMuteParam |= (UINT16)(MCB_VOICE_FLAGL<<8);
++              *pwDACMuteParam |= MCB_VOICE_FLAGR;
++      }
++
++      switch(McResCtrl_GetDITSource(eMCDRV_DIO_0))
++      {
++      case    eMCDRV_SRC_PDM:
++              bReg    = MCB_DIT0_SOURCE_AD;
++              break;
++      case    eMCDRV_SRC_ADC0:
++              bReg    = MCB_DIT0_SOURCE_AD;
++              break;
++      case    eMCDRV_SRC_DIR0:
++              bReg    = MCB_DIT0_SOURCE_DIR0;
++              break;
++      case    eMCDRV_SRC_DIR1:
++              bReg    = MCB_DIT0_SOURCE_DIR1;
++              break;
++      case    eMCDRV_SRC_DIR2:
++              bReg    = MCB_DIT0_SOURCE_DIR2;
++              break;
++      case    eMCDRV_SRC_MIX:
++              bReg    = MCB_DIT0_SOURCE_MIX;
++              break;
++      default:
++              bReg    = 0;
++      }
++      bReadReg        = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_SRC_SOURCE);
++      if(((bReadReg & 0xF0) != 0) && (bReg != (bReadReg & 0xF0)))
++      {/*     DIT source changed      */
++              if((McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DIT0_INVOLL)&MCB_DIT0_INVOLL) != 0)
++              {
++                      if(McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DIT0_INVOLR) != 0)
++                      {
++                              bLAT    = MCB_DIT0_INLAT;
++                      }
++                      else
++                      {
++                              bLAT    = 0;
++                      }
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_DIT0_INVOLL, bLAT);
++              }
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_DIT0_INVOLR, 0);
++              *pwDITMuteParam |= (UINT16)(MCB_DIT0_INVFLAGL<<8);
++              *pwDITMuteParam |= MCB_DIT0_INVFLAGR;
++      }
++
++      switch(McResCtrl_GetDITSource(eMCDRV_DIO_1))
++      {
++      case    eMCDRV_SRC_PDM:
++              bReg    = MCB_DIT1_SOURCE_AD;
++              break;
++      case    eMCDRV_SRC_ADC0:
++              bReg    = MCB_DIT1_SOURCE_AD;
++              break;
++      case    eMCDRV_SRC_DIR0:
++              bReg    = MCB_DIT1_SOURCE_DIR0;
++              break;
++      case    eMCDRV_SRC_DIR1:
++              bReg    = MCB_DIT1_SOURCE_DIR1;
++              break;
++      case    eMCDRV_SRC_DIR2:
++              bReg    = MCB_DIT1_SOURCE_DIR2;
++              break;
++      case    eMCDRV_SRC_MIX:
++              bReg    = MCB_DIT1_SOURCE_MIX;
++              break;
++      default:
++              bReg    = 0;
++      }
++      if(((bReadReg & 0x0F) != 0) && (bReg != (bReadReg & 0x0F)))
++      {/*     DIT source changed      */
++              if((McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DIT1_INVOLL)&MCB_DIT1_INVOLL) != 0)
++              {
++                      if(McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DIT1_INVOLR) != 0)
++                      {
++                              bLAT    = MCB_DIT1_INLAT;
++                      }
++                      else
++                      {
++                              bLAT    = 0;
++                      }
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_DIT1_INVOLL, bLAT);
++              }
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_DIT1_INVOLR, 0);
++              *pwDITMuteParam |= (UINT16)(MCB_DIT1_INVFLAGL<<8);
++              *pwDITMuteParam |= MCB_DIT1_INVFLAGR;
++      }
++
++      switch(McResCtrl_GetDITSource(eMCDRV_DIO_2))
++      {
++      case    eMCDRV_SRC_PDM:
++              bReg    = MCB_DIT2_SOURCE_AD;
++              break;
++      case    eMCDRV_SRC_ADC0:
++              bReg    = MCB_DIT2_SOURCE_AD;
++              break;
++      case    eMCDRV_SRC_DIR0:
++              bReg    = MCB_DIT2_SOURCE_DIR0;
++              break;
++      case    eMCDRV_SRC_DIR1:
++              bReg    = MCB_DIT2_SOURCE_DIR1;
++              break;
++      case    eMCDRV_SRC_DIR2:
++              bReg    = MCB_DIT2_SOURCE_DIR2;
++              break;
++      case    eMCDRV_SRC_MIX:
++              bReg    = MCB_DIT2_SOURCE_MIX;
++              break;
++      default:
++              bReg    = 0;
++      }
++      bReadReg        = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_SRC_SOURCE_1);
++      if(((bReadReg & 0x0F) != 0) && (bReg != (bReadReg & 0x0F)))
++      {/*     DIT source changed      */
++              if((McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DIT2_INVOLL)&MCB_DIT2_INVOLL) != 0)
++              {
++                      if(McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DIT2_INVOLR) != 0)
++                      {
++                              bLAT    = MCB_DIT2_INLAT;
++                      }
++                      else
++                      {
++                              bLAT    = 0;
++                      }
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_DIT2_INVOLL, bLAT);
++              }
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_DIT2_INVOLR, 0);
++              *pwDITMuteParam |= (UINT16)(MCB_DIT2_INVFLAGL<<8);
++              *pwDITMuteParam |= MCB_DIT2_INVFLAGR;
++      }
++
++      sdRet   = McDevIf_ExecutePacket();
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("PreUpdatePath", &sdRet);
++#endif
++      /*      do not Execute & Clear  */
++      return sdRet;
++}
++
++/****************************************************************************
++ *    McDrv_Ctrl
++ *
++ *    Description:
++ *                    MC Driver I/F function.
++ *    Arguments:
++ *                    dCmd            command #
++ *                    pvPrm           parameter
++ *                    dPrm            update info
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++SINT32        McDrv_Ctrl
++(
++      UINT32  dCmd,
++      void*   pvPrm,
++      UINT32  dPrm
++)
++{
++      SINT32  sdRet   = MCDRV_ERROR;
++
++#if MCDRV_DEBUG_LEVEL
++      McDebugLog_CmdIn(dCmd, pvPrm, dPrm);
++#endif
++
++      if((UINT32)MCDRV_INIT == dCmd)
++      {
++              sdRet   = init((MCDRV_INIT_INFO*)pvPrm);
++      }
++      else if((UINT32)MCDRV_TERM == dCmd)
++      {
++              if(McResCtrl_GetHwId() == MCDRV_HWID_AA)
++              {
++                      sdRet   = McDrv_Ctrl_AA(dCmd, pvPrm, dPrm);
++              }
++              else
++              {
++                      sdRet   = term();
++              }
++      }
++      else
++      {
++              if(McResCtrl_GetHwId() == MCDRV_HWID_AA)
++              {
++                      sdRet   = McDrv_Ctrl_AA(dCmd, pvPrm, dPrm);
++              }
++              else
++              {
++                      McSrv_Lock();
++
++                      switch (dCmd)
++                      {
++                      case    MCDRV_UPDATE_CLOCK:
++                              sdRet   = update_clock((MCDRV_CLOCK_INFO*)pvPrm);
++                              break;
++                      case    MCDRV_SWITCH_CLOCK:
++                              sdRet   = switch_clock((MCDRV_CLKSW_INFO*)pvPrm);
++                              break;
++                      case    MCDRV_GET_PATH:
++                              sdRet   = get_path((MCDRV_PATH_INFO*)pvPrm);
++                              break;
++                      case    MCDRV_SET_PATH:
++                              sdRet   = set_path((MCDRV_PATH_INFO*)pvPrm);
++                              break;
++                      case    MCDRV_GET_VOLUME:
++                              sdRet   = get_volume((MCDRV_VOL_INFO*)pvPrm);
++                              break;
++                      case    MCDRV_SET_VOLUME:
++                              sdRet   = set_volume((MCDRV_VOL_INFO*)pvPrm);
++                              break;
++                      case    MCDRV_GET_DIGITALIO:
++                              sdRet   = get_digitalio((MCDRV_DIO_INFO*)pvPrm);
++                              break;
++                      case    MCDRV_SET_DIGITALIO:
++                              sdRet   = set_digitalio((MCDRV_DIO_INFO*)pvPrm, dPrm);
++                              break;
++                      case    MCDRV_GET_DAC:
++                              sdRet   = get_dac((MCDRV_DAC_INFO*)pvPrm);
++                              break;
++                      case    MCDRV_SET_DAC:
++                              sdRet   = set_dac((MCDRV_DAC_INFO*)pvPrm, dPrm);
++                              break;
++                      case    MCDRV_GET_ADC:
++                              sdRet   = get_adc((MCDRV_ADC_INFO*)pvPrm);
++                              break;
++                      case    MCDRV_SET_ADC:
++                              sdRet   = set_adc((MCDRV_ADC_INFO*)pvPrm, dPrm);
++                              break;
++                      case    MCDRV_GET_SP:
++                              sdRet   = get_sp((MCDRV_SP_INFO*)pvPrm);
++                              break;
++                      case    MCDRV_SET_SP:
++                              sdRet   = set_sp((MCDRV_SP_INFO*)pvPrm);
++                              break;
++                      case    MCDRV_GET_DNG:
++                              sdRet   = get_dng((MCDRV_DNG_INFO*)pvPrm);
++                              break;
++                      case    MCDRV_SET_DNG:
++                              sdRet   = set_dng((MCDRV_DNG_INFO*)pvPrm, dPrm);
++                              break;
++                      case    MCDRV_SET_AUDIOENGINE:
++                              sdRet   = set_ae((MCDRV_AE_INFO*)pvPrm, dPrm);
++                              break;
++                      case    MCDRV_GET_PDM:
++                              sdRet   = get_pdm((MCDRV_PDM_INFO*)pvPrm);
++                              break;
++                      case    MCDRV_SET_PDM:
++                              sdRet   = set_pdm((MCDRV_PDM_INFO*)pvPrm, dPrm);
++                              break;
++                      case    MCDRV_CONFIG_GP:
++                              sdRet   = config_gp((MCDRV_GP_MODE*)pvPrm);
++                              break;
++                      case    MCDRV_MASK_GP:
++                              sdRet   = mask_gp((UINT8*)pvPrm, dPrm);
++                              break;
++                      case    MCDRV_GETSET_GP:
++                              sdRet   = getset_gp((UINT8*)pvPrm, dPrm);
++                              break;
++                      case    MCDRV_GET_SYSEQ:
++                              sdRet   = get_syseq((MCDRV_SYSEQ_INFO*)pvPrm);
++                              break;
++                      case    MCDRV_SET_SYSEQ:
++                              sdRet   = set_syseq((MCDRV_SYSEQ_INFO*)pvPrm, dPrm);
++                              break;
++                      case    MCDRV_READ_REG :
++                              sdRet   = read_reg((MCDRV_REG_INFO*)pvPrm);
++                              break;
++                      case    MCDRV_WRITE_REG :
++                              sdRet   = write_reg((MCDRV_REG_INFO*)pvPrm);
++                              break;
++
++                      case    MCDRV_IRQ:
++                              break;
++
++                      default:
++                              break;
++                      }
++
++                      McSrv_Unlock();
++              }
++      }
++
++#if MCDRV_DEBUG_LEVEL
++      McDebugLog_CmdOut(dCmd, &sdRet, pvPrm);
++#endif
++
++      return sdRet;
++}
+diff --git a/sound/soc/codecs/mc1n2/mcdriver.h b/sound/soc/codecs/mc1n2/mcdriver.h
+new file mode 100644
+index 0000000..a8051d3
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mcdriver.h
+@@ -0,0 +1,906 @@
++/****************************************************************************
++ *
++ *            Copyright(c) 2010 Yamaha Corporation. All rights reserved.
++ *
++ *            Module          : mcdriver.h
++ *
++ *            Description     : MC Driver header
++ *
++ *            Version         : 1.0.0         2010.07.05
++ *
++ ****************************************************************************/
++
++#ifndef _MCDRIVER_H_
++#define _MCDRIVER_H_
++
++#include "mctypedef.h"
++
++
++
++signed long   McDrv_Ctrl( UINT32 dCmd, void* pvPrm, UINT32 dPrm );
++
++
++
++
++/*    return value    */
++#define       MCDRV_SUCCESS                           ((SINT32)0)
++#define       MCDRV_ERROR_ARGUMENT            (-1)
++#define       MCDRV_ERROR_TIMEOUT                     (-2)
++#define       MCDRV_ERROR_INIT                        (-3)
++#define       MCDRV_ERROR_RESOURCEOVER        (-4)
++#define       MCDRV_ERROR_STATE                       (-5)
++
++#define       MCDRV_ERROR                                     (-10)
++
++
++/*    dCmd    */
++#define       MCDRV_INIT                                      (0)
++#define       MCDRV_TERM                                      (1)
++#define       MCDRV_READ_REG                          (2)
++#define       MCDRV_WRITE_REG                         (3)
++#define       MCDRV_GET_PATH                          (4)
++#define       MCDRV_SET_PATH                          (5)
++#define       MCDRV_GET_VOLUME                        (6)
++#define       MCDRV_SET_VOLUME                        (7)
++#define       MCDRV_GET_DIGITALIO                     (8)
++#define       MCDRV_SET_DIGITALIO                     (9)
++#define       MCDRV_GET_DAC                           (10)
++#define       MCDRV_SET_DAC                           (11)
++#define       MCDRV_GET_ADC                           (12)
++#define       MCDRV_SET_ADC                           (13)
++#define       MCDRV_GET_SP                            (14)
++#define       MCDRV_SET_SP                            (15)
++#define       MCDRV_GET_DNG                           (16)
++#define       MCDRV_SET_DNG                           (17)
++#define       MCDRV_SET_AUDIOENGINE           (18)
++#define       MCDRV_SET_AUDIOENGINE_EX        (19)
++#define       MCDRV_SET_CDSP                          (20)
++#define       MCDRV_GET_CDSP_PARAM            (21)
++#define       MCDRV_SET_CDSP_PARAM            (22)
++#define       MCDRV_REGISTER_CDSP_CB          (23)
++#define       MCDRV_GET_PDM                           (24)
++#define       MCDRV_SET_PDM                           (25)
++#define       MCDRV_SET_DTMF                          (26)
++#define       MCDRV_CONFIG_GP                         (27)
++#define       MCDRV_MASK_GP                           (28)
++#define       MCDRV_GETSET_GP                         (29)
++#define       MCDRV_GET_PEAK                          (30)
++#define       MCDRV_IRQ                                       (31)
++#define       MCDRV_UPDATE_CLOCK                      (32)
++#define       MCDRV_SWITCH_CLOCK                      (33)
++#define       MCDRV_GET_SYSEQ                         (34)
++#define       MCDRV_SET_SYSEQ                         (35)
++
++/*    pvPrm   */
++/*    init    */
++/*    MCDRV_INIT_INFO bCkSel setting  */
++#define       MCDRV_CKSEL_CMOS                        (0x00)
++#define       MCDRV_CKSEL_TCXO                        (0xC0)
++#define       MCDRV_CKSEL_CMOS_TCXO           (0x80)
++#define       MCDRV_CKSEL_TCXO_CMOS           (0x40)
++
++/*    MCDRV_INIT_INFO bXXXHiz setting */
++#define       MCDRV_DAHIZ_LOW                         (0)
++#define       MCDRV_DAHIZ_HIZ                         (1)
++
++/*    CDRV_INIT_INFO bPcmHiz setting  */
++#define       MCDRV_PCMHIZ_LOW                        (0)
++#define       MCDRV_PCMHIZ_HIZ                        (1)
++
++/*    MCDRV_INIT_INFO bSvolStep setting       */
++#define       MCDRV_SVOLSTEP_0137                     (0)
++#define       MCDRV_SVOLSTEP_0274                     (1)
++#define       MCDRV_SVOLSTEP_0548                     (2)
++#define       MCDRV_SVOLSTEP_1096                     (3)
++
++/*    MCDRV_INIT_INFO bLinexxDif setting      */
++#define       MCDRV_LINE_STEREO                       (0)
++#define       MCDRV_LINE_DIF                          (1)
++
++/*    MCDRV_INIT_INFO bSpmn setting   */
++#define       MCDRV_SPMN_ON                           (0)
++#define       MCDRV_SPMN_OFF                          (1)
++
++/*    MCDRV_INIT_INFO bMicxSng setting        */
++#define       MCDRV_MIC_DIF                           (0)
++#define       MCDRV_MIC_SINGLE                        (1)
++
++/*    MCDRV_INIT_INFO bPowerMode setting      */
++#define       MCDRV_POWMODE_NORMAL            (0)
++#define       MCDRV_POWMODE_CLKON                     (1)
++#define       MCDRV_POWMODE_VREFON            (2)
++#define       MCDRV_POWMODE_CLKVREFON         (3)
++#define       MCDRV_POWMODE_FULL                      (4)
++
++/* bSpHiz setting */
++#define       MCDRV_SPHIZ_PULLDOWN            (0)
++#define       MCDRV_SPHIZ_HIZ                         (1)
++
++/*    MCDRV_INIT_INFO bLdo setting    */
++#define       MCDRV_LDO_OFF                           (0)
++#define       MCDRV_LDO_ON                            (1)
++
++/*    MCDRV_INIT_INFO bPadxFunc setting       */
++#define       MCDRV_PAD_GPIO                          (0)
++#define       MCDRV_PAD_PDMCK                         (1)
++#define       MCDRV_PAD_PDMDI                         (2)
++#define       MCDRV_PAD_IRQ                           (3)
++
++/*    MCDRV_INIT_INFO bAvddLev/bVrefLev setting       */
++#define       MCDRV_OUTLEV_0                          (0)
++#define       MCDRV_OUTLEV_1                          (1)
++#define       MCDRV_OUTLEV_2                          (2)
++#define       MCDRV_OUTLEV_3                          (3)
++#define       MCDRV_OUTLEV_4                          (4)
++#define       MCDRV_OUTLEV_5                          (5)
++#define       MCDRV_OUTLEV_6                          (6)
++#define       MCDRV_OUTLEV_7                          (7)
++
++/*    MCDRV_INIT_INFO bDclGain setting        */
++#define       MCDRV_DCLGAIN_0                         (0)
++#define       MCDRV_DCLGAIN_6                         (1)
++#define       MCDRV_DCLGAIN_12                        (2)
++#define       MCDRV_DCLGAIN_18                        (3)
++
++/*    MCDRV_INIT_INFO bDclLimit setting       */
++#define       MCDRV_DCLLIMIT_0                        (0)
++#define       MCDRV_DCLLIMIT_116                      (1)
++#define       MCDRV_DCLLIMIT_250                      (2)
++#define       MCDRV_DCLLIMIT_602                      (3)
++
++/*    MCDRV_INIT_INFO bCpMod setting  */
++#define       MCDRV_CPMOD_ON                          (0)
++#define       MCDRV_CPMOD_OFF                         (1)
++
++typedef struct
++{
++      UINT32  dAdHpf;
++      UINT32  dMic1Cin;
++      UINT32  dMic2Cin;
++      UINT32  dMic3Cin;
++      UINT32  dLine1Cin;
++      UINT32  dLine2Cin;
++      UINT32  dVrefRdy1;
++      UINT32  dVrefRdy2;
++      UINT32  dHpRdy;
++      UINT32  dSpRdy;
++      UINT32  dPdm;
++      UINT32  dAnaRdyInterval;
++      UINT32  dSvolInterval;
++      UINT32  dAnaRdyTimeOut;
++      UINT32  dSvolTimeOut;
++} MCDRV_WAIT_TIME;
++
++typedef struct
++{
++      UINT8                   bCkSel;
++      UINT8                   bDivR0;
++      UINT8                   bDivF0;
++      UINT8                   bDivR1;
++      UINT8                   bDivF1;
++      UINT8                   bRange0;
++      UINT8                   bRange1;
++      UINT8                   bBypass;
++      UINT8                   bDioSdo0Hiz;
++      UINT8                   bDioSdo1Hiz;
++      UINT8                   bDioSdo2Hiz;
++      UINT8                   bDioClk0Hiz;
++      UINT8                   bDioClk1Hiz;
++      UINT8                   bDioClk2Hiz;
++      UINT8                   bPcmHiz;
++      UINT8                   bLineIn1Dif;
++      UINT8                   bLineIn2Dif;
++      UINT8                   bLineOut1Dif;
++      UINT8                   bLineOut2Dif;
++      UINT8                   bSpmn;
++      UINT8                   bMic1Sng;
++      UINT8                   bMic2Sng;
++      UINT8                   bMic3Sng;
++      UINT8                   bPowerMode;
++      UINT8                   bSpHiz;
++      UINT8                   bLdo;
++      UINT8                   bPad0Func;
++      UINT8                   bPad1Func;
++      UINT8                   bPad2Func;
++      UINT8                   bAvddLev;
++      UINT8                   bVrefLev;
++      UINT8                   bDclGain;
++      UINT8                   bDclLimit;
++      UINT8                   bCpMod;
++      UINT8                   bReserved1;
++      UINT8                   bReserved2;
++      UINT8                   bReserved3;
++      UINT8                   bReserved4;
++      UINT8                   bReserved5;
++      MCDRV_WAIT_TIME sWaitTime;
++} MCDRV_INIT_INFO;
++
++/*    update clock    */
++typedef struct
++{
++      UINT8   bCkSel;
++      UINT8   bDivR0;
++      UINT8   bDivF0;
++      UINT8   bDivR1;
++      UINT8   bDivF1;
++      UINT8   bRange0;
++      UINT8   bRange1;
++      UINT8   bBypass;
++} MCDRV_CLOCK_INFO;
++
++/*    switch clock    */
++/*    MCDRV_CLKSW_INFO bClkSrc setting        */
++#define       MCDRV_CLKSW_CLKI0       (0x00)
++#define       MCDRV_CLKSW_CLKI1       (0x01)
++
++typedef struct
++{
++      UINT8   bClkSrc;
++} MCDRV_CLKSW_INFO;
++
++/*    set/get path    */
++#define       SOURCE_BLOCK_NUM                        (7)
++#define       MCDRV_SRC_MIC1_BLOCK            (0)
++#define       MCDRV_SRC_MIC2_BLOCK            (0)
++#define       MCDRV_SRC_MIC3_BLOCK            (0)
++#define       MCDRV_SRC_LINE1_L_BLOCK         (1)
++#define       MCDRV_SRC_LINE1_R_BLOCK         (1)
++#define       MCDRV_SRC_LINE1_M_BLOCK         (1)
++#define       MCDRV_SRC_LINE2_L_BLOCK         (2)
++#define       MCDRV_SRC_LINE2_R_BLOCK         (2)
++#define       MCDRV_SRC_LINE2_M_BLOCK         (2)
++#define       MCDRV_SRC_DIR0_BLOCK            (3)
++#define       MCDRV_SRC_DIR1_BLOCK            (3)
++#define       MCDRV_SRC_DIR2_BLOCK            (3)
++#define       MCDRV_SRC_DIR2_DIRECT_BLOCK     (3)
++#define       MCDRV_SRC_DTMF_BLOCK            (4)
++#define       MCDRV_SRC_PDM_BLOCK                     (4)
++#define       MCDRV_SRC_ADC0_BLOCK            (4)
++#define       MCDRV_SRC_ADC1_BLOCK            (4)
++#define       MCDRV_SRC_DAC_L_BLOCK           (5)
++#define       MCDRV_SRC_DAC_R_BLOCK           (5)
++#define       MCDRV_SRC_DAC_M_BLOCK           (5)
++#define       MCDRV_SRC_MIX_BLOCK                     (6)
++#define       MCDRV_SRC_AE_BLOCK                      (6)
++#define       MCDRV_SRC_CDSP_BLOCK            (6)
++#define       MCDRV_SRC_CDSP_DIRECT_BLOCK     (6)
++
++#define       MCDRV_SRC0_MIC1_ON                      (0x01)
++#define       MCDRV_SRC0_MIC1_OFF                     (0x02)
++#define       MCDRV_SRC0_MIC2_ON                      (0x04)
++#define       MCDRV_SRC0_MIC2_OFF                     (0x08)
++#define       MCDRV_SRC0_MIC3_ON                      (0x10)
++#define       MCDRV_SRC0_MIC3_OFF                     (0x20)
++#define       MCDRV_SRC1_LINE1_L_ON           (0x01)
++#define       MCDRV_SRC1_LINE1_L_OFF          (0x02)
++#define       MCDRV_SRC1_LINE1_R_ON           (0x04)
++#define       MCDRV_SRC1_LINE1_R_OFF          (0x08)
++#define       MCDRV_SRC1_LINE1_M_ON           (0x10)
++#define       MCDRV_SRC1_LINE1_M_OFF          (0x20)
++#define       MCDRV_SRC2_LINE2_L_ON           (0x01)
++#define       MCDRV_SRC2_LINE2_L_OFF          (0x02)
++#define       MCDRV_SRC2_LINE2_R_ON           (0x04)
++#define       MCDRV_SRC2_LINE2_R_OFF          (0x08)
++#define       MCDRV_SRC2_LINE2_M_ON           (0x10)
++#define       MCDRV_SRC2_LINE2_M_OFF          (0x20)
++#define       MCDRV_SRC3_DIR0_ON                      (0x01)
++#define       MCDRV_SRC3_DIR0_OFF                     (0x02)
++#define       MCDRV_SRC3_DIR1_ON                      (0x04)
++#define       MCDRV_SRC3_DIR1_OFF                     (0x08)
++#define       MCDRV_SRC3_DIR2_ON                      (0x10)
++#define       MCDRV_SRC3_DIR2_OFF                     (0x20)
++#define       MCDRV_SRC3_DIR2_DIRECT_ON       (0x40)
++#define       MCDRV_SRC3_DIR2_DIRECT_OFF      (0x80)
++#define       MCDRV_SRC4_DTMF_ON                      (0x01)
++#define       MCDRV_SRC4_DTMF_OFF                     (0x02)
++#define       MCDRV_SRC4_PDM_ON                       (0x04)
++#define       MCDRV_SRC4_PDM_OFF                      (0x08)
++#define       MCDRV_SRC4_ADC0_ON                      (0x10)
++#define       MCDRV_SRC4_ADC0_OFF                     (0x20)
++#define       MCDRV_SRC4_ADC1_ON                      (0x40)
++#define       MCDRV_SRC4_ADC1_OFF                     (0x80)
++#define       MCDRV_SRC5_DAC_L_ON                     (0x01)
++#define       MCDRV_SRC5_DAC_L_OFF            (0x02)
++#define       MCDRV_SRC5_DAC_R_ON                     (0x04)
++#define       MCDRV_SRC5_DAC_R_OFF            (0x08)
++#define       MCDRV_SRC5_DAC_M_ON                     (0x10)
++#define       MCDRV_SRC5_DAC_M_OFF            (0x20)
++#define       MCDRV_SRC6_MIX_ON                       (0x01)
++#define       MCDRV_SRC6_MIX_OFF                      (0x02)
++#define       MCDRV_SRC6_AE_ON                        (0x04)
++#define       MCDRV_SRC6_AE_OFF                       (0x08)
++#define       MCDRV_SRC6_CDSP_ON                      (0x10)
++#define       MCDRV_SRC6_CDSP_OFF                     (0x20)
++#define       MCDRV_SRC6_CDSP_DIRECT_ON       (0x40)
++#define       MCDRV_SRC6_CDSP_DIRECT_OFF      (0x80)
++
++typedef struct
++{
++      UINT8   abSrcOnOff[SOURCE_BLOCK_NUM];
++} MCDRV_CHANNEL;
++
++#define       HP_PATH_CHANNELS                (2)
++#define       SP_PATH_CHANNELS                (2)
++#define       RC_PATH_CHANNELS                (1)
++#define       LOUT1_PATH_CHANNELS             (2)
++#define       LOUT2_PATH_CHANNELS             (2)
++#define       PEAK_PATH_CHANNELS              (1)
++#define       DIT0_PATH_CHANNELS              (1)
++#define       DIT1_PATH_CHANNELS              (1)
++#define       DIT2_PATH_CHANNELS              (1)
++#define       DAC_PATH_CHANNELS               (2)
++#define       AE_PATH_CHANNELS                (1)
++#define       CDSP_PATH_CHANNELS              (4)
++#define       ADC0_PATH_CHANNELS              (2)
++#define       ADC1_PATH_CHANNELS              (1)
++#define       MIX_PATH_CHANNELS               (1)
++#define       BIAS_PATH_CHANNELS              (1)
++
++typedef struct
++{
++      MCDRV_CHANNEL   asHpOut[HP_PATH_CHANNELS];
++      MCDRV_CHANNEL   asSpOut[SP_PATH_CHANNELS];
++      MCDRV_CHANNEL   asRcOut[RC_PATH_CHANNELS];
++      MCDRV_CHANNEL   asLout1[LOUT1_PATH_CHANNELS];
++      MCDRV_CHANNEL   asLout2[LOUT2_PATH_CHANNELS];
++      MCDRV_CHANNEL   asPeak[PEAK_PATH_CHANNELS];
++      MCDRV_CHANNEL   asDit0[DIT0_PATH_CHANNELS];
++      MCDRV_CHANNEL   asDit1[DIT1_PATH_CHANNELS];
++      MCDRV_CHANNEL   asDit2[DIT2_PATH_CHANNELS];
++      MCDRV_CHANNEL   asDac[DAC_PATH_CHANNELS];
++      MCDRV_CHANNEL   asAe[AE_PATH_CHANNELS];
++      MCDRV_CHANNEL   asCdsp[CDSP_PATH_CHANNELS];
++      MCDRV_CHANNEL   asAdc0[ADC0_PATH_CHANNELS];
++      MCDRV_CHANNEL   asAdc1[ADC1_PATH_CHANNELS];
++      MCDRV_CHANNEL   asMix[MIX_PATH_CHANNELS];
++      MCDRV_CHANNEL   asBias[BIAS_PATH_CHANNELS];
++} MCDRV_PATH_INFO;
++
++/*    set/get vol     */
++#define       MCDRV_VOL_UPDATE                (0x0001)
++
++#define       AD0_VOL_CHANNELS                (2)
++#define       AD1_VOL_CHANNELS                (1)
++#define       AENG6_VOL_CHANNELS              (2)
++#define       PDM_VOL_CHANNELS                (2)
++#define       DTMF_VOL_CHANNELS               (2)
++#define       DIO0_VOL_CHANNELS               (2)
++#define       DIO1_VOL_CHANNELS               (2)
++#define       DIO2_VOL_CHANNELS               (2)
++#define       DTFM_VOL_CHANNELS               (2)
++#define       DAC_VOL_CHANNELS                (2)
++
++#define       LIN1_VOL_CHANNELS               (2)
++#define       LIN2_VOL_CHANNELS               (2)
++#define       MIC1_VOL_CHANNELS               (1)
++#define       MIC2_VOL_CHANNELS               (1)
++#define       MIC3_VOL_CHANNELS               (1)
++#define       HP_VOL_CHANNELS                 (2)
++#define       SP_VOL_CHANNELS                 (2)
++#define       RC_VOL_CHANNELS                 (1)
++#define       LOUT1_VOL_CHANNELS              (2)
++#define       LOUT2_VOL_CHANNELS              (2)
++#define       HPGAIN_VOL_CHANNELS             (1)
++
++typedef struct
++{
++      SINT16  aswD_Ad0[AD0_VOL_CHANNELS];
++      SINT16  aswD_Ad1[AD1_VOL_CHANNELS];
++      SINT16  aswD_Aeng6[AENG6_VOL_CHANNELS];
++      SINT16  aswD_Pdm[PDM_VOL_CHANNELS];
++      SINT16  aswD_Dtmfb[DTMF_VOL_CHANNELS];
++      SINT16  aswD_Dir0[DIO0_VOL_CHANNELS];
++      SINT16  aswD_Dir1[DIO1_VOL_CHANNELS];
++      SINT16  aswD_Dir2[DIO2_VOL_CHANNELS];
++      SINT16  aswD_Ad0Att[AD0_VOL_CHANNELS];
++      SINT16  aswD_Ad1Att[AD1_VOL_CHANNELS];
++      SINT16  aswD_Dir0Att[DIO0_VOL_CHANNELS];
++      SINT16  aswD_Dir1Att[DIO1_VOL_CHANNELS];
++      SINT16  aswD_Dir2Att[DIO2_VOL_CHANNELS];
++      SINT16  aswD_SideTone[PDM_VOL_CHANNELS];
++      SINT16  aswD_DtmfAtt[DTFM_VOL_CHANNELS];
++      SINT16  aswD_DacMaster[DAC_VOL_CHANNELS];
++      SINT16  aswD_DacVoice[DAC_VOL_CHANNELS];
++      SINT16  aswD_DacAtt[DAC_VOL_CHANNELS];
++      SINT16  aswD_Dit0[DIO0_VOL_CHANNELS];
++      SINT16  aswD_Dit1[DIO1_VOL_CHANNELS];
++      SINT16  aswD_Dit2[DIO2_VOL_CHANNELS];
++      SINT16  aswA_Ad0[AD0_VOL_CHANNELS];
++      SINT16  aswA_Ad1[AD1_VOL_CHANNELS];
++      SINT16  aswA_Lin1[LIN1_VOL_CHANNELS];
++      SINT16  aswA_Lin2[LIN2_VOL_CHANNELS];
++      SINT16  aswA_Mic1[MIC1_VOL_CHANNELS];
++      SINT16  aswA_Mic2[MIC2_VOL_CHANNELS];
++      SINT16  aswA_Mic3[MIC3_VOL_CHANNELS];
++      SINT16  aswA_Hp[HP_VOL_CHANNELS];
++      SINT16  aswA_Sp[SP_VOL_CHANNELS];
++      SINT16  aswA_Rc[RC_VOL_CHANNELS];
++      SINT16  aswA_Lout1[LOUT1_VOL_CHANNELS];
++      SINT16  aswA_Lout2[LOUT2_VOL_CHANNELS];
++      SINT16  aswA_Mic1Gain[MIC1_VOL_CHANNELS];
++      SINT16  aswA_Mic2Gain[MIC2_VOL_CHANNELS];
++      SINT16  aswA_Mic3Gain[MIC3_VOL_CHANNELS];
++      SINT16  aswA_HpGain[HPGAIN_VOL_CHANNELS];
++} MCDRV_VOL_INFO;
++
++/*    set/get digitalio       */
++#define       MCDRV_DIO0_COM_UPDATE_FLAG      ((UINT32)0x00000001)
++#define       MCDRV_DIO0_DIR_UPDATE_FLAG      ((UINT32)0x00000002)
++#define       MCDRV_DIO0_DIT_UPDATE_FLAG      ((UINT32)0x00000004)
++#define       MCDRV_DIO1_COM_UPDATE_FLAG      ((UINT32)0x00000008)
++#define       MCDRV_DIO1_DIR_UPDATE_FLAG      ((UINT32)0x00000010)
++#define       MCDRV_DIO1_DIT_UPDATE_FLAG      ((UINT32)0x00000020)
++#define       MCDRV_DIO2_COM_UPDATE_FLAG      ((UINT32)0x00000040)
++#define       MCDRV_DIO2_DIR_UPDATE_FLAG      ((UINT32)0x00000080)
++#define       MCDRV_DIO2_DIT_UPDATE_FLAG      ((UINT32)0x00000100)
++
++/*    MCDRV_DIO_COMMON bMasterSlave setting   */
++#define       MCDRV_DIO_SLAVE                         (0)
++#define       MCDRV_DIO_MASTER                        (1)
++
++/*    MCDRV_DIO_COMMON bDigitalAutoFs setting */
++#define       MCDRV_AUTOFS_OFF                        (0)
++#define       MCDRV_AUTOFS_ON                         (1)
++
++/*    MCDRV_DIO_COMMON bFs setting    */
++#define       MCDRV_FS_48000                          (0)
++#define       MCDRV_FS_44100                          (1)
++#define       MCDRV_FS_32000                          (2)
++#define       MCDRV_FS_24000                          (4)
++#define       MCDRV_FS_22050                          (5)
++#define       MCDRV_FS_16000                          (6)
++#define       MCDRV_FS_12000                          (8)
++#define       MCDRV_FS_11025                          (9)
++#define       MCDRV_FS_8000                           (10)
++
++/*    MCDRV_DIO_COMMON bBckFs setting */
++#define       MCDRV_BCKFS_64                          (0)
++#define       MCDRV_BCKFS_48                          (1)
++#define       MCDRV_BCKFS_32                          (2)
++#define       MCDRV_BCKFS_512                         (4)
++#define       MCDRV_BCKFS_256                         (5)
++#define       MCDRV_BCKFS_128                         (6)
++#define       MCDRV_BCKFS_16                          (7)
++
++/*    MCDRV_DIO_COMMON bInterface setting     */
++#define       MCDRV_DIO_DA                            (0)
++#define       MCDRV_DIO_PCM                           (1)
++
++/*    MCDRV_DIO_COMMON bBckInvert setting     */
++#define       MCDRV_BCLK_NORMAL                       (0)
++#define       MCDRV_BCLK_INVERT                       (1)
++
++/*    MCDRV_DIO_COMMON bPcmHizTim setting     */
++#define       MCDRV_PCMHIZTIM_FALLING         (0)
++#define       MCDRV_PCMHIZTIM_RISING          (1)
++
++/*    MCDRV_DIO_COMMON bPcmClkDown setting    */
++#define       MCDRV_PCM_CLKDOWN_OFF           (0)
++#define       MCDRV_PCM_CLKDOWN_HALF          (1)
++
++/*    MCDRV_DIO_COMMON bPcmFrame setting      */
++#define       MCDRV_PCM_SHORTFRAME            (0)
++#define       MCDRV_PCM_LONGFRAME                     (1)
++
++typedef struct
++{
++      UINT8   bMasterSlave;
++      UINT8   bAutoFs;
++      UINT8   bFs;
++      UINT8   bBckFs;
++      UINT8   bInterface;
++      UINT8   bBckInvert;
++      UINT8   bPcmHizTim;
++      UINT8   bPcmClkDown;
++      UINT8   bPcmFrame;
++      UINT8   bPcmHighPeriod;
++} MCDRV_DIO_COMMON;
++
++/*    MCDRV_DA_FORMAT bBitSel setting */
++#define       MCDRV_BITSEL_16                         (0)
++#define       MCDRV_BITSEL_20                         (1)
++#define       MCDRV_BITSEL_24                         (2)
++
++/*    MCDRV_DA_FORMAT bMode setting   */
++#define       MCDRV_DAMODE_HEADALIGN          (0)
++#define       MCDRV_DAMODE_I2S                        (1)
++#define       MCDRV_DAMODE_TAILALIGN          (2)
++
++typedef struct
++{
++      UINT8   bBitSel;
++      UINT8   bMode;
++} MCDRV_DA_FORMAT;
++
++/*    MCDRV_PCM_FORMAT bMono setting  */
++#define       MCDRV_PCM_STEREO                        (0)
++#define       MCDRV_PCM_MONO                          (1)
++
++/*    MCDRV_PCM_FORMAT bOrder setting */
++#define       MCDRV_PCM_MSB_FIRST                     (0)
++#define       MCDRV_PCM_LSB_FIRST                     (1)
++#define       MCDRV_PCM_MSB_FIRST_SIGN        (2)
++#define       MCDRV_PCM_LSB_FIRST_SIGN        (3)
++#define       MCDRV_PCM_MSB_FIRST_ZERO        (4)
++#define       MCDRV_PCM_LSB_FIRST_ZERO        (5)
++
++/*    MCDRV_PCM_FORMAT bLaw setting   */
++#define       MCDRV_PCM_LINEAR                        (0)
++#define       MCDRV_PCM_ALAW                          (1)
++#define       MCDRV_PCM_MULAW                         (2)
++
++/*    MCDRV_PCM_FORMAT bBitSel setting        */
++#define       MCDRV_PCM_BITSEL_8                      (0)
++#define       MCDRV_PCM_BITSEL_13                     (1)
++#define       MCDRV_PCM_BITSEL_14                     (2)
++#define       MCDRV_PCM_BITSEL_16                     (3)
++
++typedef struct
++{
++      UINT8   bMono;
++      UINT8   bOrder;
++      UINT8   bLaw;
++      UINT8   bBitSel;
++} MCDRV_PCM_FORMAT;
++
++#define       DIO_CHANNELS            (2)
++typedef struct
++{
++      UINT16                          wSrcRate;
++      MCDRV_DA_FORMAT         sDaFormat;
++      MCDRV_PCM_FORMAT        sPcmFormat;
++      UINT8                           abSlot[DIO_CHANNELS];
++} MCDRV_DIO_DIR;
++
++typedef struct
++{
++      UINT16                          wSrcRate;
++      MCDRV_DA_FORMAT         sDaFormat;
++      MCDRV_PCM_FORMAT        sPcmFormat;
++      UINT8                           abSlot[DIO_CHANNELS];
++} MCDRV_DIO_DIT;
++
++typedef struct
++{
++      MCDRV_DIO_COMMON        sDioCommon;
++      MCDRV_DIO_DIR           sDir;
++      MCDRV_DIO_DIT           sDit;
++} MCDRV_DIO_PORT;
++
++#define       IOPORT_NUM                      (3)
++typedef struct
++{
++      MCDRV_DIO_PORT  asPortInfo[IOPORT_NUM];
++} MCDRV_DIO_INFO;
++
++/*    set dac */
++#define       MCDRV_DAC_MSWP_UPDATE_FLAG      ((UINT32)0x01)
++#define       MCDRV_DAC_VSWP_UPDATE_FLAG      ((UINT32)0x02)
++#define       MCDRV_DAC_HPF_UPDATE_FLAG       ((UINT32)0x04)
++
++/*    MCDRV_DAC_INFO bMasterSwap/bVoiceSwap setting   */
++#define       MCDRV_DSWAP_OFF                 (0)
++#define       MCDRV_DSWAP_SWAP                (1)
++#define       MCDRV_DSWAP_MUTE                (2)
++#define       MCDRV_DSWAP_RMVCENTER   (3)
++#define       MCDRV_DSWAP_MONO                (4)
++#define       MCDRV_DSWAP_MONOHALF    (5)
++#define       MCDRV_DSWAP_BOTHL               (6)
++#define       MCDRV_DSWAP_BOTHR               (7)
++
++/*    MCDRV_DAC_INFO bDcCut setting   */
++#define       MCDRV_DCCUT_ON                  (0)
++#define       MCDRV_DCCUT_OFF                 (1)
++
++typedef struct
++{
++      UINT8   bMasterSwap;
++      UINT8   bVoiceSwap;
++      UINT8   bDcCut;
++} MCDRV_DAC_INFO;
++
++/*    set adc */
++#define       MCDRV_ADCADJ_UPDATE_FLAG        ((UINT32)0x00000001)
++#define       MCDRV_ADCAGC_UPDATE_FLAG        ((UINT32)0x00000002)
++#define       MCDRV_ADCMONO_UPDATE_FLAG       ((UINT32)0x00000004)
++
++/*    MCDRV_ADC_INFO bAgcAdjust setting       */
++#define       MCDRV_AGCADJ_24                 (0)
++#define       MCDRV_AGCADJ_18                 (1)
++#define       MCDRV_AGCADJ_12                 (2)
++#define       MCDRV_AGCADJ_0                  (3)
++
++/*    MCDRV_ADC_INFO bAgcOn setting   */
++#define       MCDRV_AGC_OFF                   (0)
++#define       MCDRV_AGC_ON                    (1)
++
++/*    MCDRV_ADC_INFO bMono setting    */
++#define       MCDRV_ADC_STEREO                (0)
++#define       MCDRV_ADC_MONO                  (1)
++
++typedef struct
++{
++      UINT8   bAgcAdjust;
++      UINT8   bAgcOn;
++      UINT8   bMono;
++} MCDRV_ADC_INFO;
++
++/*    set sp  */
++/*    MCDRV_SP_INFO bSwap setting     */
++#define       MCDRV_SPSWAP_OFF                (0)
++#define       MCDRV_SPSWAP_SWAP               (1)
++
++typedef struct
++{
++      UINT8   bSwap;
++} MCDRV_SP_INFO;
++
++/*    set dng */
++#define       DNG_ITEM_NUM                            (3)
++#define       MCDRV_DNG_ITEM_HP                       (0)
++#define       MCDRV_DNG_ITEM_SP                       (1)
++#define       MCDRV_DNG_ITEM_RC                       (2)
++
++#define       MCDRV_DNGSW_HP_UPDATE_FLAG              ((UINT32)0x00000001)
++#define       MCDRV_DNGTHRES_HP_UPDATE_FLAG   ((UINT32)0x00000002)
++#define       MCDRV_DNGHOLD_HP_UPDATE_FLAG    ((UINT32)0x00000004)
++#define       MCDRV_DNGATK_HP_UPDATE_FLAG             ((UINT32)0x00000008)
++#define       MCDRV_DNGREL_HP_UPDATE_FLAG             ((UINT32)0x00000010)
++#define       MCDRV_DNGTARGET_HP_UPDATE_FLAG  ((UINT32)0x00000020)
++#define       MCDRV_DNGSW_SP_UPDATE_FLAG              ((UINT32)0x00000100)
++#define       MCDRV_DNGTHRES_SP_UPDATE_FLAG   ((UINT32)0x00000200)
++#define       MCDRV_DNGHOLD_SP_UPDATE_FLAG    ((UINT32)0x00000400)
++#define       MCDRV_DNGATK_SP_UPDATE_FLAG             ((UINT32)0x00000800)
++#define       MCDRV_DNGREL_SP_UPDATE_FLAG             ((UINT32)0x00001000)
++#define       MCDRV_DNGTARGET_SP_UPDATE_FLAG  ((UINT32)0x00002000)
++#define       MCDRV_DNGSW_RC_UPDATE_FLAG              ((UINT32)0x00010000)
++#define       MCDRV_DNGTHRES_RC_UPDATE_FLAG   ((UINT32)0x00020000)
++#define       MCDRV_DNGHOLD_RC_UPDATE_FLAG    ((UINT32)0x00040000)
++#define       MCDRV_DNGATK_RC_UPDATE_FLAG             ((UINT32)0x00080000)
++#define       MCDRV_DNGREL_RC_UPDATE_FLAG             ((UINT32)0x00100000)
++#define       MCDRV_DNGTARGET_RC_UPDATE_FLAG  ((UINT32)0x00200000)
++
++/*    MCDRV_DNG_INFO bOnOff setting   */
++#define       MCDRV_DNG_OFF                           (0)
++#define       MCDRV_DNG_ON                            (1)
++
++/*    MCDRV_DNG_INFO bThreshold setting       */
++#define       MCDRV_DNG_THRES_30                      (0)
++#define       MCDRV_DNG_THRES_36                      (1)
++#define       MCDRV_DNG_THRES_42                      (2)
++#define       MCDRV_DNG_THRES_48                      (3)
++#define       MCDRV_DNG_THRES_54                      (4)
++#define       MCDRV_DNG_THRES_60                      (5)
++#define       MCDRV_DNG_THRES_66                      (6)
++#define       MCDRV_DNG_THRES_72                      (7)
++#define       MCDRV_DNG_THRES_78                      (8)
++#define       MCDRV_DNG_THRES_84                      (9)
++
++/*    MCDRV_DNG_INFO bHold setting    */
++#define       MCDRV_DNG_HOLD_30                       (0)
++#define       MCDRV_DNG_HOLD_120                      (1)
++#define       MCDRV_DNG_HOLD_500                      (2)
++
++/*    MCDRV_DNG_INFO bAttack setting  */
++#define       MCDRV_DNG_ATTACK_25                     (0)
++#define       MCDRV_DNG_ATTACK_100            (1)
++#define       MCDRV_DNG_ATTACK_400            (2)
++#define       MCDRV_DNG_ATTACK_800            (3)
++
++/*    MCDRV_DNG_INFO bRelease setting */
++#define       MCDRV_DNG_RELEASE_7950          (0)
++#define       MCDRV_DNG_RELEASE_470           (1)
++#define       MCDRV_DNG_RELEASE_940           (2)
++
++/*    MCDRV_DNG_INFO bTarget setting  */
++#define       MCDRV_DNG_TARGET_6                      (0)
++#define       MCDRV_DNG_TARGET_9                      (1)
++#define       MCDRV_DNG_TARGET_12                     (2)
++#define       MCDRV_DNG_TARGET_15                     (3)
++#define       MCDRV_DNG_TARGET_18                     (4)
++#define       MCDRV_DNG_TARGET_MUTE           (5)
++
++typedef struct
++{
++      UINT8   abOnOff[DNG_ITEM_NUM];
++      UINT8   abThreshold[DNG_ITEM_NUM];
++      UINT8   abHold[DNG_ITEM_NUM];
++      UINT8   abAttack[DNG_ITEM_NUM];
++      UINT8   abRelease[DNG_ITEM_NUM];
++      UINT8   abTarget[DNG_ITEM_NUM];
++}     MCDRV_DNG_INFO;
++
++/*    set audio engine        */
++#define       MCDRV_AEUPDATE_FLAG_BEXWIDE_ONOFF       ((UINT32)0x00000001)
++#define       MCDRV_AEUPDATE_FLAG_DRC_ONOFF           ((UINT32)0x00000002)
++#define       MCDRV_AEUPDATE_FLAG_EQ5_ONOFF           ((UINT32)0x00000004)
++#define       MCDRV_AEUPDATE_FLAG_EQ3_ONOFF           ((UINT32)0x00000008)
++#define       MCDRV_AEUPDATE_FLAG_BEX                         ((UINT32)0x00000010)
++#define       MCDRV_AEUPDATE_FLAG_WIDE                        ((UINT32)0x00000020)
++#define       MCDRV_AEUPDATE_FLAG_DRC                         ((UINT32)0x00000040)
++#define       MCDRV_AEUPDATE_FLAG_EQ5                         ((UINT32)0x00000080)
++#define       MCDRV_AEUPDATE_FLAG_EQ3                         ((UINT32)0x00000100)
++
++/*    MCDRV_AE_INFO bOnOff setting    */
++#define       MCDRV_BEXWIDE_ON                        (0x01)
++#define       MCDRV_DRC_ON                            (0x02)
++#define       MCDRV_EQ5_ON                            (0x04)
++#define       MCDRV_EQ3_ON                            (0x08)
++
++#define       BEX_PARAM_SIZE                          (104)
++#define       WIDE_PARAM_SIZE                         (20)
++#define       DRC_PARAM_SIZE                          (256)
++#define       EQ5_PARAM_SIZE                          (105)
++#define       EQ3_PARAM_SIZE                          (75)
++
++typedef struct
++{
++      UINT8   bOnOff;
++      UINT8   abBex[BEX_PARAM_SIZE];
++      UINT8   abWide[WIDE_PARAM_SIZE];
++      UINT8   abDrc[DRC_PARAM_SIZE];
++      UINT8   abEq5[EQ5_PARAM_SIZE];
++      UINT8   abEq3[EQ3_PARAM_SIZE];
++}     MCDRV_AE_INFO;
++
++/*    set cdsp param  */
++typedef struct
++{
++      UINT8   bId;
++      UINT8   abParam[16];
++} MCDRV_CDSPPARAM;
++
++/*    register cdsp cb        */
++/*    dEvtType        */
++#define       MCDRV_CDSP_EVT_ERROR            (0)
++#define       MCDRV_CDSP_EVT_PARAM            (1)
++
++/*    dEvtPrm */
++#define       MCDRV_CDSP_PRG_ERROR            (0)
++#define       MCDRV_CDSP_PRG_ERROR_FATAL      (1)
++#define       MCDRV_CDSP_SYS_ERROR            (2)
++
++/*    set pdm */
++#define       MCDRV_PDMCLK_UPDATE_FLAG        ((UINT32)0x00000001)
++#define       MCDRV_PDMADJ_UPDATE_FLAG        ((UINT32)0x00000002)
++#define       MCDRV_PDMAGC_UPDATE_FLAG        ((UINT32)0x00000004)
++#define       MCDRV_PDMEDGE_UPDATE_FLAG       ((UINT32)0x00000008)
++#define       MCDRV_PDMWAIT_UPDATE_FLAG       ((UINT32)0x00000010)
++#define       MCDRV_PDMSEL_UPDATE_FLAG        ((UINT32)0x00000020)
++#define       MCDRV_PDMMONO_UPDATE_FLAG       ((UINT32)0x00000040)
++
++/*    MCDRV_PDM_INFO bClk setting     */
++#define       MCDRV_PDM_CLK_128                       (1)
++#define       MCDRV_PDM_CLK_64                        (2)
++#define       MCDRV_PDM_CLK_32                        (3)
++
++/*    MCDRV_PDM_INFO bPdmEdge setting */
++#define       MCDRV_PDMEDGE_LH                        (0)
++#define       MCDRV_PDMEDGE_HL                        (1)
++
++/*    MCDRV_PDM_INFO bPdmWait setting */
++#define       MCDRV_PDMWAIT_0                         (0)
++#define       MCDRV_PDMWAIT_1                         (1)
++#define       MCDRV_PDMWAIT_10                        (2)
++#define       MCDRV_PDMWAIT_20                        (3)
++
++/*    MCDRV_PDM_INFO bPdmSel setting  */
++#define       MCDRV_PDMSEL_L1R2                       (0)
++#define       MCDRV_PDMSEL_L2R1                       (1)
++#define       MCDRV_PDMSEL_L1R1                       (2)
++#define       MCDRV_PDMSEL_L2R2                       (3)
++
++/*    MCDRV_PDM_INFO bMono setting    */
++#define       MCDRV_PDM_STEREO                        (0)
++#define       MCDRV_PDM_MONO                          (1)
++
++typedef struct
++{
++      UINT8   bClk;
++      UINT8   bAgcAdjust;
++      UINT8   bAgcOn;
++      UINT8   bPdmEdge;
++      UINT8   bPdmWait;
++      UINT8   bPdmSel;
++      UINT8   bMono;
++} MCDRV_PDM_INFO;
++
++/*    set dtmf        */
++typedef struct
++{
++      UINT8   bSinGen0Vol;
++      UINT8   bSinGen1Vol;
++      UINT16  wSinGen0Freq;
++      UINT16  wSinGen1Freq;
++      UINT8   bSinGenGate;
++      UINT8   bSinGenMode;
++      UINT8   bSinGenLoop;
++} MCDRV_DTMF_PARAM;
++
++/*    MCDRV_DTMF_INFO bOnOff setting  */
++#define       MCDRV_DTMF_ON                           (0)
++#define       MCDRV_DTMF_OFF                          (1)
++
++typedef struct
++{
++      UINT8                           bOnOff;
++      MCDRV_DTMF_PARAM        sParam;
++} MCDRV_DTMF_INFO;
++
++/*    config gp       */
++#define       GPIO_PAD_NUM                            (2)
++
++/*    MCDRV_GP_MODE abGpDdr setting   */
++#define       MCDRV_GPDDR_IN                          (0)
++#define       MCDRV_GPDDR_OUT                         (1)
++
++/*    MCDRV_GP_MODE abGpMode setting  */
++#define       MCDRV_GPMODE_RISING                     (0)
++#define       MCDRV_GPMODE_FALLING            (1)
++#define       MCDRV_GPMODE_BOTH                       (2)
++
++/*    MCDRV_GP_MODE abGpHost setting  */
++#define       MCDRV_GPHOST_SCU                        (0)
++#define       MCDRV_GPHOST_CDSP                       (1)
++
++/*    MCDRV_GP_MODE abGpInvert setting        */
++#define       MCDRV_GPINV_NORMAL                      (0)
++#define       MCDRV_GPINV_INVERT                      (1)
++
++typedef struct
++{
++      UINT8   abGpDdr[GPIO_PAD_NUM];
++      UINT8   abGpMode[GPIO_PAD_NUM];
++      UINT8   abGpHost[GPIO_PAD_NUM];
++      UINT8   abGpInvert[GPIO_PAD_NUM];
++} MCDRV_GP_MODE;
++
++/*    mask gp */
++#define       MCDRV_GPMASK_OFF                        (0)
++#define       MCDRV_GPMASK_ON                         (1)
++
++#define       MCDRV_GP_PAD0                           ((UINT32)0)
++#define       MCDRV_GP_PAD1                           ((UINT32)1)
++
++/*    getset gp       */
++#define       MCDRV_GP_LOW                            (0)
++#define       MCDRV_GP_HIGH                           (1)
++
++/*    get peak        */
++#define       PEAK_CHANNELS                           (2)
++typedef struct
++{
++      SINT16  aswPeak[PEAK_CHANNELS];
++} MCDRV_PEAK;
++
++/*    set/get syseq   */
++#define       MCDRV_SYSEQ_ONOFF_UPDATE_FLAG   ((UINT32)0x00000001)
++#define       MCDRV_SYSEQ_PARAM_UPDATE_FLAG   ((UINT32)0x00000002)
++
++/*    MCDRV_SYSEQ_INFO bOnOff setting */
++#define       MCDRV_SYSEQ_OFF                         (0)
++#define       MCDRV_SYSEQ_ON                          (1)
++
++typedef struct
++{
++      UINT8   bOnOff;
++      UINT8   abParam[15];
++} MCDRV_SYSEQ_INFO;
++
++/*    read_reg, write_reg     */
++#define       MCDRV_REGTYPE_A                         (0)
++#define       MCDRV_REGTYPE_B_BASE            (1)
++#define       MCDRV_REGTYPE_B_MIXER           (2)
++#define       MCDRV_REGTYPE_B_AE                      (3)
++#define       MCDRV_REGTYPE_B_CDSP            (4)
++#define       MCDRV_REGTYPE_B_CODEC           (5)
++#define       MCDRV_REGTYPE_B_ANALOG          (6)
++typedef struct
++{
++      UINT8   bRegType;
++      UINT8   bAddress;
++      UINT8   bData;
++} MCDRV_REG_INFO;
++
++
++#endif /* _MCDRIVER_H_ */
+diff --git a/sound/soc/codecs/mc1n2/mcdriver_AA.c b/sound/soc/codecs/mc1n2/mcdriver_AA.c
+new file mode 100644
+index 0000000..ac61eaf
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mcdriver_AA.c
+@@ -0,0 +1,18276 @@
++/****************************************************************************
++ *
++ *            Copyright(c) 2010-2011 Yamaha Corporation. All rights reserved.
++ *
++ *            Module          : mcdriver.c
++ *
++ *            Description     : MC Driver
++ *
++ *            Version         : 1.0.2         2011.04.18
++ *
++ ****************************************************************************/
++
++
++#include "mcdriver.h"
++#include "mcdriver_AA.h"
++#include "mcservice.h"
++
++
++
++/*******************************************/
++
++/*    Register Definition
++
++      [Naming Rules]
++
++        MCI_AA_xxx            : Registers
++        MCI_AA_xxx_DEF        : Default setting of registers
++        MCB_AA_xxx            : Miscelleneous bit definition
++*/
++
++/*    Registers       */
++/*    A_ADR   */
++#define       MCI_AA_RST                                              (0)
++#define       MCB_AA_RST                                              (0x01)
++#define       MCI_AA_RST_DEF                                  (MCB_AA_RST)
++
++#define       MCI_AA_BASE_ADR                         (1)
++#define       MCI_AA_BASE_WINDOW                              (2)
++
++#define       MCI_AA_HW_ID                                    (8)
++#define       MCI_AA_HW_ID_DEF                                (0x44)
++
++#define       MCI_AA_ANA_ADR                                  (12)
++#define       MCI_AA_ANA_WINDOW                               (13)
++
++#define       MCI_AA_CD_ADR                                   (14)
++#define       MCI_AA_CD_WINDOW                                (15)
++
++#define       MCI_AA_MIX_ADR                                  (16)
++#define       MCI_AA_MIX_WINDOW                               (17)
++
++#define       MCI_AA_AE_ADR                                   (18)
++#define       MCI_AA_AE_WINDOW                                (19)
++
++#define       MCI_AA_BDSP_ST                                  (20)
++#define       MCB_AA_EQ5ON                                    (0x80)
++#define       MCB_AA_DRCON                                    (0x40)
++#define       MCB_AA_EQ3ON                                    (0x20)
++#define       MCB_AA_DBEXON                                   (0x08)
++#define       MCB_AA_BDSP_ST                                  (0x01)
++
++#define       MCI_AA_BDSP_RST                         (21)
++#define       MCB_AA_TRAM_RST                         (0x02)
++#define       MCB_AA_BDSP_RST                         (0x01)
++
++#define       MCI_AA_BDSP_ADR                         (22)
++#define       MCI_AA_BDSP_WINDOW                              (23)
++
++#define       MCI_AA_CDSP_ADR                         (24)
++#define       MCI_AA_CDSP_WINDOW                              (25)
++
++/*    B_ADR(BASE)     */
++#define       MCI_AA_RSTB                                     (0)
++#define       MCB_AA_RSTB                                     (0x10)
++#define       MCI_AA_RSTB_DEF                         (MCB_AA_RSTB)
++
++#define       MCI_AA_PWM_DIGITAL                              (1)
++#define       MCB_AA_PWM_DP2                                  (0x04)
++#define       MCB_AA_PWM_DP1                                  (0x02)
++#define       MCB_AA_PWM_DP0                                  (0x01)
++#define       MCI_AA_PWM_DIGITAL_DEF                  (MCB_AA_PWM_DP2 | MCB_AA_PWM_DP1 | MCB_AA_PWM_DP0)
++
++#define       MCI_AA_PWM_DIGITAL_1                    (3)
++#define       MCB_AA_PWM_DPPDM                                (0x10)
++#define       MCB_AA_PWM_DPDI2                                (0x08)
++#define       MCB_AA_PWM_DPDI1                                (0x04)
++#define       MCB_AA_PWM_DPDI0                                (0x02)
++#define       MCB_AA_PWM_DPB                                  (0x01)
++#define       MCI_AA_PWM_DIGITAL_1_DEF                (MCB_AA_PWM_DPPDM | MCB_AA_PWM_DPDI2 | MCB_AA_PWM_DPDI1 | MCB_AA_PWM_DPDI0 | MCB_AA_PWM_DPB)
++
++#define       MCI_AA_PWM_DIGITAL_CDSP         (4)
++#define       MCB_AA_PWM_DPCDSP                               (0x00)
++#define       MCI_AA_PWM_DIGITAL_CDSP_DEF     (MCB_AA_PWM_DPCDSP)
++
++#define       MCI_AA_PWM_DIGITAL_BDSP         (6)
++#define       MCI_AA_PWM_DIGITAL_BDSP_DEF     (MCB_AA_PWM_DPBDSP)
++#define       MCB_AA_PWM_DPBDSP                               (0x01)
++
++#define       MCI_AA_SD_MSK                                   (9)
++#define       MCB_AA_SDIN_MSK2                                (0x80)
++#define       MCB_AA_SDO_DDR2                         (0x10)
++#define       MCB_AA_SDIN_MSK1                                (0x08)
++#define       MCB_AA_SDO_DDR1                         (0x01)
++#define       MCI_AA_SD_MSK_DEF                               (MCB_AA_SDIN_MSK2 | MCB_AA_SDIN_MSK1)
++
++#define       MCI_AA_SD_MSK_1                         (10)
++#define       MCB_AA_SDIN_MSK0                                (0x80)
++#define       MCB_AA_SDO_DDR0                         (0x10)
++#define       MCI_AA_SD_MSK_1_DEF                     (MCB_AA_SDIN_MSK0)
++
++#define       MCI_AA_BCLK_MSK                         (11)
++#define       MCB_AA_BCLK_MSK2                                (0x80)
++#define       MCB_AA_BCLK_DDR2                                (0x40)
++#define       MCB_AA_LRCK_MSK2                                (0x20)
++#define       MCB_AA_LRCK_DDR2                                (0x10)
++#define       MCB_AA_BCLK_MSK1                                (0x08)
++#define       MCB_AA_BCLK_DDR1                                (0x04)
++#define       MCB_AA_LRCK_MSK1                                (0x02)
++#define       MCB_AA_LRCK_DDR1                                (0x01)
++#define       MCI_AA_BCLK_MSK_DEF                     (MCB_AA_BCLK_MSK2 | MCB_AA_LRCK_MSK2 | MCB_AA_BCLK_MSK1 | MCB_AA_LRCK_MSK1)
++
++#define       MCI_AA_BCLK_MSK_1                               (12)
++#define       MCB_AA_BCLK_MSK0                                (0x80)
++#define       MCB_AA_BCLK_DDR0                                (0x40)
++#define       MCB_AA_LRCK_MSK0                                (0x20)
++#define       MCB_AA_LRCK_DDR0                                (0x10)
++#define       MCB_AA_PCMOUT_HIZ2                              (0x08)
++#define       MCB_AA_PCMOUT_HIZ1                              (0x04)
++#define       MCB_AA_PCMOUT_HIZ0                              (0x02)
++#define       MCB_AA_ROUTER_MS                                (0x01)
++#define       MCI_AA_BCLK_MSK_1_DEF                   (MCB_AA_BCLK_MSK0 | MCB_AA_LRCK_MSK0)
++
++#define       MCI_AA_BCKP                                     (13)
++#define       MCB_AA_DI2_BCKP                         (0x04)
++#define       MCB_AA_DI1_BCKP                         (0x02)
++#define       MCB_AA_DI0_BCKP                         (0x01)
++#define       MCI_AA_BCKP_DEF                         (0)
++
++#define       MCI_AA_PLL_RST                                  (14)
++#define       MCB_AA_PLLRST1                                  (0x00)
++#define       MCB_AA_PLLRST0                                  (0x01)
++#define       MCI_AA_PLL_RST_DEF                              (MCB_AA_PLLRST1 | MCB_AA_PLLRST0)
++
++#define       MCI_AA_DIVR0                                    (15)
++#define       MCI_AA_DIVR0_DEF                                (0x0A)
++
++#define       MCI_AA_DIVF0                                    (16)
++#define       MCI_AA_DIVF0_DEF                                (0x48)
++
++#define       MCI_AA_DIVR1                                    (17)
++#define       MCI_AA_DIVF1                                    (18)
++
++#define       MCI_AA_CKSEL                                    (20)
++#define       MCB_AA_CKSEL                                    (0x80)
++
++#define       MCI_AA_BYPASS                                   (21)
++#define       MCB_AA_LOCK1                                    (0x80)
++#define       MCB_AA_LOCK0                                    (0x40)
++#define       MCB_AA_BYPASS1                                  (0x02)
++#define       MCB_AA_BYPASS0                                  (0x01)
++
++#define       MCI_AA_EPA_IRQ                                  (22)
++#define       MCB_AA_EPA2_IRQ                         (0x04)
++#define       MCB_AA_EPA1_IRQ                         (0x02)
++#define       MCB_AA_EPA0_IRQ                         (0x01)
++
++#define       MCI_AA_PA_FLG                                   (23)
++#define       MCB_AA_PA2_FLAG                         (0x04)
++#define       MCB_AA_PA1_FLAG                         (0x02)
++#define       MCB_AA_PA0_FLAG                         (0x01)
++
++#define       MCI_AA_PA_MSK                                   (25)
++#define       MCB_AA_PA2_MSK                                  (0x08)
++#define       MCB_AA_PA2_DDR                                  (0x04)
++#define       MCI_AA_PA_MSK_DEF                               (MCB_AA_PA2_MSK)
++
++#define       MCI_AA_PA_MSK_1                         (26)
++#define       MCB_AA_PA1_MSK                                  (0x80)
++#define       MCB_AA_PA1_DDR                                  (0x40)
++#define       MCB_AA_PA0_MSK                                  (0x08)
++#define       MCB_AA_PA0_DDR                                  (0x04)
++#define       MCI_AA_PA_MSK_1_DEF                     (MCB_AA_PA1_MSK | MCB_AA_PA0_MSK)
++
++#define       MCI_AA_PA_HOST                                  (28)
++#define       MCI_AA_PA_HOST_1                                (29)
++
++#define       MCI_AA_PA_OUT                                   (30)
++#define       MCB_AA_PA_OUT                                   (0x01)
++
++#define       MCI_AA_PA_SCU_PA                                (31)
++#define       MCB_AA_PA_SCU_PA0                               (0x01)
++#define       MCB_AA_PA_SCU_PA1                               (0x02)
++#define       MCB_AA_PA_SCU_PA2                               (0x04)
++
++/*    B_ADR(MIX)      */
++#define       MCI_AA_DIT_INVFLAGL                     (0)
++#define       MCB_AA_DIT0_INVFLAGL                    (0x20)
++#define       MCB_AA_DIT1_INVFLAGL                    (0x10)
++#define       MCB_AA_DIT2_INVFLAGL                    (0x08)
++
++#define       MCI_AA_DIT_INVFLAGR                     (1)
++#define       MCB_AA_DIT0_INVFLAGR                    (0x20)
++#define       MCB_AA_DIT1_INVFLAGR                    (0x10)
++#define       MCB_AA_DIT2_INVFLAGR                    (0x08)
++
++#define       MCI_AA_DIR_VFLAGL                               (2)
++#define       MCB_AA_PDM0_VFLAGL                              (0x80)
++#define       MCB_AA_DIR0_VFLAGL                              (0x20)
++#define       MCB_AA_DIR1_VFLAGL                              (0x10)
++#define       MCB_AA_DIR2_VFLAGL                              (0x08)
++
++#define       MCI_AA_DIR_VFLAGR                               (3)
++#define       MCB_AA_PDM0_VFLAGR                              (0x80)
++#define       MCB_AA_DIR0_VFLAGR                              (0x20)
++#define       MCB_AA_DIR1_VFLAGR                              (0x10)
++#define       MCB_AA_DIR2_VFLAGR                              (0x08)
++
++#define       MCI_AA_AD_VFLAGL                                (4)
++#define       MCB_AA_ADC_VFLAGL                               (0x80)
++#define       MCB_AA_AENG6_VFLAGL                     (0x20)
++
++#define       MCI_AA_AD_VFLAGR                                (5)
++#define       MCB_AA_ADC_VFLAGR                               (0x80)
++#define       MCB_AA_AENG6_VFLAGR                     (0x20)
++
++#define       MCI_AA_AFLAGL                                   (6)
++#define       MCB_AA_ADC_AFLAGL                               (0x40)
++#define       MCB_AA_DIR0_AFLAGL                              (0x20)
++#define       MCB_AA_DIR1_AFLAGL                              (0x10)
++#define       MCB_AA_DIR2_AFLAGL                              (0x04)
++
++#define       MCI_AA_AFLAGR                                   (7)
++#define       MCB_AA_ADC_AFLAGR                               (0x40)
++#define       MCB_AA_DIR0_AFLAGR                              (0x20)
++#define       MCB_AA_DIR1_AFLAGR                              (0x10)
++#define       MCB_AA_DIR2_AFLAGR                              (0x04)
++
++#define       MCI_AA_DAC_INS_FLAG                     (8)
++#define       MCB_AA_DAC_INS_FLAG                     (0x80)
++
++#define       MCI_AA_INS_FLAG                         (9)
++#define       MCB_AA_ADC_INS_FLAG                     (0x40)
++#define       MCB_AA_DIR0_INS_FLAG                    (0x20)
++#define       MCB_AA_DIR1_INS_FLAG                    (0x10)
++#define       MCB_AA_DIR2_INS_FLAG                    (0x04)
++
++#define       MCI_AA_DAC_FLAGL                                (10)
++#define       MCB_AA_ST_FLAGL                         (0x80)
++#define       MCB_AA_MASTER_OFLAGL                    (0x40)
++#define       MCB_AA_VOICE_FLAGL                              (0x10)
++#define       MCB_AA_DAC_FLAGL                                (0x02)
++
++#define       MCI_AA_DAC_FLAGR                                (11)
++#define       MCB_AA_ST_FLAGR                         (0x80)
++#define       MCB_AA_MASTER_OFLAGR                    (0x40)
++#define       MCB_AA_VOICE_FLAGR                              (0x10)
++#define       MCB_AA_DAC_FLAGR                                (0x02)
++
++#define       MCI_AA_DIT0_INVOLL                              (12)
++#define       MCB_AA_DIT0_INLAT                               (0x80)
++#define       MCB_AA_DIT0_INVOLL                              (0x7F)
++
++#define       MCI_AA_DIT0_INVOLR                              (13)
++#define       MCB_AA_DIT0_INVOLR                              (0x7F)
++
++#define       MCI_AA_DIT1_INVOLL                              (14)
++#define       MCB_AA_DIT1_INLAT                               (0x80)
++#define       MCB_AA_DIT1_INVOLL                              (0x7F)
++
++#define       MCI_AA_DIT1_INVOLR                              (15)
++#define       MCB_AA_DIT1_INVOLR                              (0x7F)
++
++#define       MCI_AA_DIT2_INVOLL                              (16)
++#define       MCB_AA_DIT2_INLAT                               (0x80)
++#define       MCB_AA_DIT2_INVOLL                              (0x7F)
++
++#define       MCI_AA_DIT2_INVOLR                              (17)
++#define       MCB_AA_DIT2_INVOLR                              (0x7F)
++
++#define       MCI_AA_ESRC0_INVOLL                     (16)
++#define       MCI_AA_ESRC0_INVOLR                     (17)
++
++#define       MCI_AA_PDM0_VOLL                                (24)
++#define       MCB_AA_PDM0_INLAT                               (0x80)
++#define       MCB_AA_PDM0_VOLL                                (0x7F)
++
++#define       MCI_AA_PDM0_VOLR                                (25)
++#define       MCB_AA_PDM0_VOLR                                (0x7F)
++
++#define       MCI_AA_DIR0_VOLL                                (28)
++#define       MCB_AA_DIR0_LAT                         (0x80)
++#define       MCB_AA_DIR0_VOLL                                (0x7F)
++
++#define       MCI_AA_DIR0_VOLR                                (29)
++#define       MCB_AA_DIR0_VOLR                                (0x7F)
++
++#define       MCI_AA_DIR1_VOLL                                (30)
++#define       MCB_AA_DIR1_LAT                         (0x80)
++#define       MCB_AA_DIR1_VOLL                                (0x7F)
++
++#define       MCI_AA_DIR1_VOLR                                (31)
++#define       MCB_AA_DIR1_VOLR                                (0x7F)
++
++#define       MCI_AA_DIR2_VOLL                                (32)
++#define       MCB_AA_DIR2_LAT                         (0x80)
++#define       MCB_AA_DIR2_VOLL                                (0x7F)
++
++#define       MCI_AA_DIR2_VOLR                                (33)
++#define       MCB_AA_DIR2_VOLR                                (0x7F)
++/*
++#define       MCI_AA_ADC1_VOLL                                (38?)
++#define       MCB_AA_ADC1_LAT                         (0x80)
++#define       MCB_AA_ADC1_VOLL                                (0x7F)
++
++#define       MCI_AA_ADC1_VOLR                                (39?)
++#define       MCB_AA_ADC1_VOLR                                (0x7F)
++*/
++#define       MCI_AA_ADC_VOLL                         (40)
++#define       MCB_AA_ADC_LAT                                  (0x80)
++#define       MCB_AA_ADC_VOLL                         (0x7F)
++
++#define       MCI_AA_ADC_VOLR                         (41)
++#define       MCB_AA_ADC_VOLR                         (0x7F)
++/*
++#define       MCI_AA_DTMFB_VOLL                               (42)
++#define       MCI_AA_DTMFB_VOLR                               (43)
++*/
++#define       MCI_AA_AENG6_VOLL                               (44)
++#define       MCB_AA_AENG6_LAT                                (0x80)
++#define       MCB_AA_AENG6_VOLL                               (0x7F)
++
++#define       MCI_AA_AENG6_VOLR                               (45)
++#define       MCB_AA_AENG6_VOLR                               (0x7F)
++
++#define       MCI_AA_DIT_ININTP                               (50)
++#define       MCB_AA_DIT0_ININTP                              (0x20)
++#define       MCB_AA_DIT1_ININTP                              (0x10)
++#define       MCB_AA_DIT2_ININTP                              (0x08)
++#define       MCI_AA_DIT_ININTP_DEF                   (MCB_AA_DIT0_ININTP | MCB_AA_DIT1_ININTP | MCB_AA_DIT2_ININTP)
++
++#define       MCI_AA_DIR_INTP                         (51)
++#define       MCB_AA_PDM0_INTP                                (0x80)
++#define       MCB_AA_DIR0_INTP                                (0x20)
++#define       MCB_AA_DIR1_INTP                                (0x10)
++#define       MCB_AA_DIR2_INTP                                (0x08)
++#define       MCB_AA_ADC2_INTP                                (0x01)
++#define       MCI_AA_DIR_INTP_DEF                     (MCB_AA_PDM0_INTP | MCB_AA_DIR0_INTP | MCB_AA_DIR1_INTP | MCB_AA_DIR2_INTP)
++
++#define       MCI_AA_ADC_INTP                         (52)
++#define       MCB_AA_ADC_INTP                         (0x80)
++#define       MCB_AA_AENG6_INTP                               (0x20)
++#define       MCI_AA_ADC_INTP_DEF                     (MCB_AA_ADC_INTP | MCB_AA_AENG6_INTP)
++
++#define       MCI_AA_ADC_ATTL                         (54)
++#define       MCB_AA_ADC_ALAT                         (0x80)
++#define       MCB_AA_ADC_ATTL                         (0x7F)
++
++#define       MCI_AA_ADC_ATTR                         (55)
++#define       MCB_AA_ADC_ATTR                         (0x7F)
++
++#define       MCI_AA_DIR0_ATTL                                (56)
++#define       MCB_AA_DIR0_ALAT                                (0x80)
++#define       MCB_AA_DIR0_ATTL                                (0x7F)
++
++#define       MCI_AA_DIR0_ATTR                                (57)
++#define       MCB_AA_DIR0_ATTR                                (0x7F)
++
++#define       MCI_AA_DIR1_ATTL                                (58)
++#define       MCB_AA_DIR1_ALAT                                (0x80)
++#define       MCB_AA_DIR1_ATTL                                (0x7F)
++
++#define       MCI_AA_DIR1_ATTR                                (59)
++#define       MCB_AA_DIR1_ATTR                                (0x7F)
++/*
++#define       MCI_AA_ADC2_ATTL                                (60)
++#define       MCI_AA_ADC2_ATTR                                (61)
++*/
++#define       MCI_AA_DIR2_ATTL                                (62)
++#define       MCB_AA_DIR2_ALAT                                (0x80)
++#define       MCB_AA_DIR2_ATTL                                (0x7F)
++
++#define       MCI_AA_DIR2_ATTR                                (63)
++#define       MCB_AA_DIR2_ATTR                                (0x7F)
++
++#define       MCI_AA_AINTP                                    (72)
++#define       MCB_AA_ADC_AINTP                                (0x40)
++#define       MCB_AA_DIR0_AINTP                               (0x20)
++#define       MCB_AA_DIR1_AINTP                               (0x10)
++#define       MCB_AA_DIR2_AINTP                               (0x04)
++#define       MCI_AA_AINTP_DEF                                (MCB_AA_ADC_AINTP | MCB_AA_DIR0_AINTP | MCB_AA_DIR1_AINTP | MCB_AA_DIR2_AINTP)
++
++#define       MCI_AA_DAC_INS                                  (74)
++#define       MCB_AA_DAC_INS                                  (0x80)
++
++#define       MCI_AA_INS                                              (75)
++#define       MCB_AA_ADC_INS                                  (0x40)
++#define       MCB_AA_DIR0_INS                         (0x20)
++#define       MCB_AA_DIR1_INS                         (0x10)
++#define       MCB_AA_DIR2_INS                         (0x04)
++
++#define       MCI_AA_IINTP                                    (76)
++#define       MCB_AA_DAC_IINTP                                (0x80)
++#define       MCB_AA_ADC_IINTP                                (0x40)
++#define       MCB_AA_DIR0_IINTP                               (0x20)
++#define       MCB_AA_DIR1_IINTP                               (0x10)
++#define       MCB_AA_DIR2_IINTP                               (0x04)
++#define       MCI_AA_IINTP_DEF                                (MCB_AA_DAC_IINTP | MCB_AA_ADC_IINTP | MCB_AA_DIR0_IINTP | MCB_AA_DIR1_IINTP | MCB_AA_DIR2_IINTP)
++
++#define       MCI_AA_ST_VOLL                                  (77)
++#define       MCB_AA_ST_LAT                                   (0x80)
++#define       MCB_AA_ST_VOLL                                  (0x7F)
++
++#define       MCI_AA_ST_VOLR                                  (78)
++#define       MCB_AA_ST_VOLR                                  (0x7F)
++
++#define       MCI_AA_MASTER_OUTL                              (79)
++#define       MCB_AA_MASTER_OLAT                              (0x80)
++#define       MCB_AA_MASTER_OUTL                              (0x7F)
++
++#define       MCI_AA_MASTER_OUTR                              (80)
++#define       MCB_AA_MASTER_OUTR                              (0x7F)
++
++#define       MCI_AA_VOICE_ATTL                               (83)
++#define       MCB_AA_VOICE_LAT                                (0x80)
++#define       MCB_AA_VOICE_ATTL                               (0x7F)
++
++#define       MCI_AA_VOICE_ATTR                               (84)
++#define       MCB_AA_VOICE_ATTR                               (0x7F)
++/*
++#define       MCI_AA_DTMF_ATTL                                (85)
++#define       MCI_AA_DTMF_ATTR                                (86)
++*/
++#define       MCI_AA_DAC_ATTL                         (89)
++#define       MCB_AA_DAC_LAT                                  (0x80)
++#define       MCB_AA_DAC_ATTL                         (0x7F)
++
++#define       MCI_AA_DAC_ATTR                         (90)
++#define       MCB_AA_DAC_ATTR                         (0x7F)
++
++#define       MCI_AA_DAC_INTP                         (93)
++#define       MCB_AA_ST_INTP                                  (0x80)
++#define       MCB_AA_MASTER_OINTP                     (0x40)
++#define       MCB_AA_VOICE_INTP                               (0x10)
++/*#define     MCB_AA_DTMF_INTP                                (0x08)*/
++#define       MCB_AA_DAC_INTP                         (0x02)
++#define       MCI_AA_DAC_INTP_DEF                     (MCB_AA_ST_INTP | MCB_AA_MASTER_OINTP | MCB_AA_VOICE_INTP | MCB_AA_DAC_INTP)
++
++#define       MCI_AA_SOURCE                                   (110)
++#define       MCB_AA_DAC_SOURCE_AD                    (0x10)
++#define       MCB_AA_DAC_SOURCE_DIR2                  (0x20)
++#define       MCB_AA_DAC_SOURCE_DIR0                  (0x30)
++#define       MCB_AA_DAC_SOURCE_DIR1                  (0x40)
++#define       MCB_AA_DAC_SOURCE_MIX                   (0x70)
++#define       MCB_AA_VOICE_SOURCE_AD                  (0x01)
++#define       MCB_AA_VOICE_SOURCE_DIR2                (0x02)
++#define       MCB_AA_VOICE_SOURCE_DIR0                (0x03)
++#define       MCB_AA_VOICE_SOURCE_DIR1                (0x04)
++#define       MCB_AA_VOICE_SOURCE_MIX         (0x07)
++
++#define       MCI_AA_SWP                                              (111)
++
++#define       MCI_AA_SRC_SOURCE                               (112)
++#define       MCB_AA_DIT0_SOURCE_AD                   (0x10)
++#define       MCB_AA_DIT0_SOURCE_DIR2         (0x20)
++#define       MCB_AA_DIT0_SOURCE_DIR0         (0x30)
++#define       MCB_AA_DIT0_SOURCE_DIR1         (0x40)
++#define       MCB_AA_DIT0_SOURCE_MIX                  (0x70)
++#define       MCB_AA_DIT1_SOURCE_AD                   (0x01)
++#define       MCB_AA_DIT1_SOURCE_DIR2         (0x02)
++#define       MCB_AA_DIT1_SOURCE_DIR0         (0x03)
++#define       MCB_AA_DIT1_SOURCE_DIR1         (0x04)
++#define       MCB_AA_DIT1_SOURCE_MIX                  (0x07)
++
++#define       MCI_AA_SRC_SOURCE_1                     (113)
++#define       MCB_AA_AE_SOURCE_AD                     (0x10)
++#define       MCB_AA_AE_SOURCE_DIR2                   (0x20)
++#define       MCB_AA_AE_SOURCE_DIR0                   (0x30)
++#define       MCB_AA_AE_SOURCE_DIR1                   (0x40)
++#define       MCB_AA_AE_SOURCE_MIX                    (0x70)
++#define       MCB_AA_DIT2_SOURCE_AD                   (0x01)
++#define       MCB_AA_DIT2_SOURCE_DIR2         (0x02)
++#define       MCB_AA_DIT2_SOURCE_DIR0         (0x03)
++#define       MCB_AA_DIT2_SOURCE_DIR1         (0x04)
++#define       MCB_AA_DIT2_SOURCE_MIX                  (0x07)
++
++#define       MCI_AA_ESRC_SOURCE                              (114)
++
++#define       MCI_AA_AENG6_SOURCE                     (115)
++#define       MCB_AA_AENG6_ADC0                               (0x00)
++#define       MCB_AA_AENG6_PDM                                (0x01)
++
++#define       MCI_AA_EFIFO_SOURCE                     (116)
++
++#define       MCI_AA_SRC_SOURCE_2                     (117)
++
++#define       MCI_AA_PEAK_METER                               (121)
++
++#define       MCI_AA_OVFL                                     (122)
++#define       MCI_AA_OVFR                                     (123)
++
++#define       MCI_AA_DIMODE0                                  (130)
++
++#define       MCI_AA_DIRSRC_RATE0_MSB         (131)
++
++#define       MCI_AA_DIRSRC_RATE0_LSB         (132)
++
++#define       MCI_AA_DITSRC_RATE0_MSB         (133)
++
++#define       MCI_AA_DITSRC_RATE0_LSB         (134)
++
++#define       MCI_AA_DI_FS0                                   (135)
++
++/*    DI Common Parameter     */
++#define       MCB_AA_DICOMMON_SRC_RATE_SET    (0x01)
++
++#define       MCI_AA_DI0_SRC                                  (136)
++
++#define       MCI_AA_DIX0_START                               (137)
++#define       MCB_AA_DITIM0_START                     (0x40)
++#define       MCB_AA_DIR0_SRC_START                   (0x08)
++#define       MCB_AA_DIR0_START                               (0x04)
++#define       MCB_AA_DIT0_SRC_START                   (0x02)
++#define       MCB_AA_DIT0_START                               (0x01)
++
++#define       MCI_AA_DIX0_FMT                         (142)
++
++#define       MCI_AA_DIR0_CH                                  (143)
++#define       MCI_AA_DIR0_CH_DEF                              (0x10)
++
++#define       MCI_AA_DIT0_SLOT                                (144)
++#define       MCI_AA_DIT0_SLOT_DEF                    (0x10)
++
++#define       MCI_AA_HIZ_REDGE0                               (145)
++
++#define       MCI_AA_PCM_RX0                                  (146)
++#define       MCB_AA_PCM_MONO_RX0                     (0x80)
++#define       MCI_AA_PCM_RX0_DEF                              (MCB_AA_PCM_MONO_RX0)
++
++#define       MCI_AA_PCM_SLOT_RX0                     (147)
++
++#define       MCI_AA_PCM_TX0                                  (148)
++#define       MCB_AA_PCM_MONO_TX0                     (0x80)
++#define       MCI_AA_PCM_TX0_DEF                              (MCB_AA_PCM_MONO_TX0)
++
++#define       MCI_AA_PCM_SLOT_TX0                     (149)
++#define       MCI_AA_PCM_SLOT_TX0_DEF         (0x10)
++
++#define       MCI_AA_DIMODE1                                  (150)
++
++#define       MCI_AA_DIRSRC_RATE1_MSB         (151)
++#define       MCI_AA_DIRSRC_RATE1_LSB         (152)
++
++#define       MCI_AA_DITSRC_RATE1_MSB         (153)
++#define       MCI_AA_DITSRC_RATE1_LSB         (154)
++
++#define       MCI_AA_DI_FS1                                   (155)
++
++#define       MCI_AA_DI1_SRC                                  (156)
++
++#define       MCI_AA_DIX1_START                               (157)
++#define       MCB_AA_DITIM1_START                     (0x40)
++#define       MCB_AA_DIR1_SRC_START                   (0x08)
++#define       MCB_AA_DIR1_START                               (0x04)
++#define       MCB_AA_DIT1_SRC_START                   (0x02)
++#define       MCB_AA_DIT1_START                               (0x01)
++
++#define       MCI_AA_DIX1_FMT                         (162)
++
++#define       MCI_AA_DIR1_CH                                  (163)
++#define       MCB_AA_DIR1_CH1                         (0x10)
++#define       MCI_AA_DIR1_CH_DEF                              (MCB_AA_DIR1_CH1)
++
++#define       MCI_AA_DIT1_SLOT                                (164)
++#define       MCB_AA_DIT1_SLOT1                               (0x10)
++#define       MCI_AA_DIT1_SLOT_DEF                    (MCB_AA_DIT1_SLOT1)
++
++#define       MCI_AA_HIZ_REDGE1                               (165)
++
++#define       MCI_AA_PCM_RX1                                  (166)
++#define       MCB_AA_PCM_MONO_RX1                     (0x80)
++#define       MCI_AA_PCM_RX1_DEF                              (MCB_AA_PCM_MONO_RX1)
++
++#define       MCI_AA_PCM_SLOT_RX1                     (167)
++
++#define       MCI_AA_PCM_TX1                                  (168)
++#define       MCB_AA_PCM_MONO_TX1                     (0x80)
++#define       MCI_AA_PCM_TX1_DEF                              (MCB_AA_PCM_MONO_TX1)
++
++#define       MCI_AA_PCM_SLOT_TX1                     (169)
++#define       MCI_AA_PCM_SLOT_TX1_DEF         (0x10)
++
++#define       MCI_AA_DIMODE2                                  (170)
++
++#define       MCI_AA_DIRSRC_RATE2_MSB         (171)
++#define       MCI_AA_DIRSRC_RATE2_LSB         (172)
++
++#define       MCI_AA_DITSRC_RATE2_MSB         (173)
++#define       MCI_AA_DITSRC_RATE2_LSB         (174)
++
++#define       MCI_AA_DI_FS2                                   (175)
++
++#define       MCI_AA_DI2_SRC                                  (176)
++
++#define       MCI_AA_DIX2_START                               (177)
++#define       MCB_AA_DITIM2_START                     (0x40)
++#define       MCB_AA_DIR2_SRC_START                   (0x08)
++#define       MCB_AA_DIR2_START                               (0x04)
++#define       MCB_AA_DIT2_SRC_START                   (0x02)
++#define       MCB_AA_DIT2_START                               (0x01)
++
++#define       MCI_AA_DIX2_FMT                         (182)
++
++#define       MCI_AA_DIR2_CH                                  (183)
++#define       MCB_AA_DIR2_CH1                         (0x10)
++#define       MCB_AA_DIR2_CH0                         (0x01)
++#define       MCI_AA_DIR2_CH_DEF                              (MCB_AA_DIR2_CH1)
++
++#define       MCI_AA_DIT2_SLOT                                (184)
++#define       MCB_AA_DIT2_SLOT1                               (0x10)
++#define       MCB_AA_DIT2_SLOT0                               (0x01)
++#define       MCI_AA_DIT2_SLOT_DEF                    (MCB_AA_DIT2_SLOT1)
++
++#define       MCI_AA_HIZ_REDGE2                               (185)
++
++#define       MCI_AA_PCM_RX2                                  (186)
++#define       MCB_AA_PCM_MONO_RX2                     (0x80)
++#define       MCI_AA_PCM_RX2_DEF                              (MCB_AA_PCM_MONO_RX2)
++
++#define       MCI_AA_PCM_SLOT_RX2                     (187)
++
++#define       MCI_AA_PCM_TX2                                  (188)
++#define       MCB_AA_PCM_MONO_TX2                     (0x80)
++#define       MCI_AA_PCM_TX2_DEF                              (MCB_AA_PCM_MONO_TX2)
++
++#define       MCI_AA_PCM_SLOT_TX2                     (189)
++#define       MCI_AA_PCM_SLOT_TX2_DEF         (0x10)
++
++#define       MCI_AA_CD_START                         (192)
++
++#define       MCI_AA_CDI_CH                                   (193)
++#define       MCI_AA_CDI_CH_DEF                               (0xE4)
++
++#define       MCI_AA_CDO_SLOT                         (194)
++#define       MCI_AA_CDO_SLOT_DEF                     (0xE4)
++
++#define       MCI_AA_PDM_AGC                                  (200)
++#define       MCI_AA_PDM_AGC_DEF                              (0x03)
++
++#define       MCI_AA_PDM_MUTE                         (201)
++#define       MCI_AA_PDM_MUTE_DEF                     (0x00)
++#define       MCB_AA_PDM_MUTE                         (0x01)
++
++#define       MCI_AA_PDM_START                                (202)
++#define       MCB_AA_PDM_MN                                   (0x02)
++#define       MCB_AA_PDM_START                                (0x01)
++
++#define       MCI_AA_PDM_STWAIT                               (205)
++#define       MCI_AA_PDM_STWAIT_DEF                   (0x40)
++
++#define       MCI_AA_HP_ID                                    (206)
++
++#define       MCI_AA_CHP_H                                    (207)
++#define       MCI_AA_CHP_H_DEF                                (0x3F)
++
++#define       MCI_AA_CHP_M                                    (208)
++#define       MCI_AA_CHP_M_DEF                                (0xEA)
++
++#define       MCI_AA_CHP_L                                    (209)
++#define       MCI_AA_CHP_L_DEF                                (0x94)
++
++#define       MCI_AA_SINGEN0_VOL                              (210)
++#define       MCI_AA_SINGEN1_VOL                              (211)
++
++#define       MCI_AA_SINGEN_FREQ0_MSB         (212)
++#define       MCI_AA_SINGEN_FREQ0_LSB         (213)
++
++#define       MCI_AA_SINGEN_FREQ1_MSB         (214)
++#define       MCI_AA_SINGEN_FREQ1_LSB         (215)
++
++#define       MCI_AA_SINGEN_GATETIME                  (216)
++
++#define       MCI_AA_SINGEN_FLAG                              (217)
++
++/*    BADR(AE)        */
++#define       MCI_AA_BAND0_CEQ0                               (0)
++#define       MCI_AA_BAND0_CEQ0_H_DEF         (0x10)
++
++#define       MCI_AA_BAND1_CEQ0                               (15)
++#define       MCI_AA_BAND1_CEQ0_H_DEF         (0x10)
++
++#define       MCI_AA_BAND2_CEQ0                               (30)
++#define       MCI_AA_BAND2_CEQ0_H_DEF         (0x10)
++
++#define       MCI_AA_BAND3H_CEQ0                              (45)
++#define       MCI_AA_BAND3H_CEQ0_H_DEF                (0x10)
++
++#define       MCI_AA_BAND4H_CEQ0                              (75)
++#define       MCI_AA_BAND4H_CEQ0_H_DEF                (0x10)
++
++#define       MCI_AA_BAND5_CEQ0                               (105)
++#define       MCI_AA_BAND5_CEQ0_H_DEF         (0x10)
++
++#define       MCI_AA_BAND6H_CEQ0                              (120)
++#define       MCI_AA_BAND6H_CEQ0_H_DEF                (0x10)
++
++#define       MCI_AA_BAND7H_CEQ0                              (150)
++#define       MCI_AA_BAND7H_CEQ0_H_DEF                (0x10)
++
++#define       MCI_AA_PDM_CHP0_H                               (240)
++#define       MCI_AA_PDM_CHP0_H_DEF                   (0x3F)
++#define       MCI_AA_PDM_CHP0_M                               (241)
++#define       MCI_AA_PDM_CHP0_M_DEF                   (0xEA)
++#define       MCI_AA_PDM_CHP0_L                               (242)
++#define       MCI_AA_PDM_CHP0_L_DEF                   (0x94)
++
++#define       MCI_AA_PDM_CHP1_H                               (243)
++#define       MCI_AA_PDM_CHP1_H_DEF                   (0xC0)
++#define       MCI_AA_PDM_CHP1_M                               (244)
++#define       MCI_AA_PDM_CHP1_M_DEF                   (0x15)
++#define       MCI_AA_PDM_CHP1_L                               (245)
++#define       MCI_AA_PDM_CHP1_L_DEF                   (0x6C)
++
++#define       MCI_AA_PDM_CHP2_H                               (246)
++#define       MCI_AA_PDM_CHP2_H_DEF                   (0x00)
++#define       MCI_AA_PDM_CHP2_M                               (247)
++#define       MCI_AA_PDM_CHP2_M_DEF                   (0x00)
++#define       MCI_AA_PDM_CHP2_L                               (248)
++#define       MCI_AA_PDM_CHP2_L_DEF                   (0x00)
++
++#define       MCI_AA_PDM_CHP3_H                               (249)
++#define       MCI_AA_PDM_CHP3_H_DEF                   (0x3F)
++#define       MCI_AA_PDM_CHP3_M                               (250)
++#define       MCI_AA_PDM_CHP3_M_DEF                   (0xD5)
++#define       MCI_AA_PDM_CHP3_L                               (251)
++#define       MCI_AA_PDM_CHP3_L_DEF                   (0x29)
++
++#define       MCI_AA_PDM_CHP4_H                               (252)
++#define       MCI_AA_PDM_CHP4_H_DEF                   (0x00)
++#define       MCI_AA_PDM_CHP4_M                               (253)
++#define       MCI_AA_PDM_CHP4_M_DEF                   (0x00)
++#define       MCI_AA_PDM_CHP4_L                               (254)
++#define       MCI_AA_PDM_CHP4_L_DEF                   (0x00)
++
++/*    B_ADR(CDSP)     */
++#define       MCI_AA_CDSP_SAVEOFF                     (0)
++
++#define       MCI_AA_OFIFO_LVL                                (1)
++
++#define       MCI_AA_EFIFO_LVL                                (2)
++
++#define       MCI_AA_DEC_POS_24                               (4)
++#define       MCI_AA_DEC_POS_16                               (5)
++#define       MCI_AA_DEC_POS_8                                (6)
++#define       MCI_AA_DEC_POS_0                                (7)
++
++#define       MCI_AA_ENC_POS_24                               (8)
++#define       MCI_AA_ENC_POS_16                               (9)
++#define       MCI_AA_ENC_POS_8                                (10)
++#define       MCI_AA_ENC_POS_0                                (11)
++
++#define       MCI_AA_DEC_ERR                                  (12)
++#define       MCI_AA_ENC_ERR                                  (13)
++
++#define       MCI_AA_FIFO_RST                         (14)
++
++#define       MCI_AA_DEC_ENC_START                    (15)
++
++#define       MCI_AA_FIFO4CH                                  (16)
++
++#define       MCI_AA_DEC_CTL15                                (19)
++
++#define       MCI_AA_DEC_GPR15                                (35)
++
++#define       MCI_AA_DEC_SFR1                         (51)
++#define       MCI_AA_DEC_SFR0                         (52)
++
++#define       MCI_AA_ENC_CTL15                                (53)
++
++#define       MCI_AA_ENC_GPR15                                (69)
++
++#define       MCI_AA_ENC_SFR1                         (85)
++#define       MCI_AA_ENC_SFR0                         (86)
++
++#define       MCI_AA_JOEMP                                    (92)
++#define       MCB_AA_JOEMP                                    (0x80)
++#define       MCB_AA_JOPNT                                    (0x40)
++#define       MCB_AA_OOVF_FLG                         (0x08)
++#define       MCB_AA_OUDF_FLG                         (0x04)
++#define       MCB_AA_OEMP_FLG                         (0x02)
++#define       MCB_AA_OPNT_FLG                         (0x01)
++#define       MCI_AA_JOEMP_DEF                                (MCB_AA_JOEMP | MCB_AA_OEMP_FLG)
++
++#define       MCI_AA_JEEMP                                    (93)
++#define       MCB_AA_JEEMP                                    (0x80)
++#define       MCB_AA_JEPNT                                    (0x40)
++#define       MCB_AA_EOVF_FLG                         (0x08)
++#define       MCB_AA_EUDF_FLG                         (0x04)
++#define       MCB_AA_EEMP_FLG                         (0x02)
++#define       MCB_AA_EPNT_FLG                         (0x01)
++#define       MCI_AA_JEEMP_DEF                                (MCB_AA_JEEMP | MCB_AA_EEMP_FLG)
++
++#define       MCI_AA_DEC_FLG                                  (96)
++#define       MCI_AA_ENC_FLG                                  (97)
++
++#define       MCI_AA_DEC_GPR_FLG                              (98)
++#define       MCI_AA_ENC_GPR_FLG                              (99)
++
++#define       MCI_AA_EOPNT                                    (101)
++
++#define       MCI_AA_EDEC                                     (105)
++#define       MCI_AA_EENC                                     (106)
++
++#define       MCI_AA_EDEC_GPR                         (107)
++#define       MCI_AA_EENC_GPR                         (108)
++
++#define       MCI_AA_CDSP_SRST                                (110)
++#define       MCB_AA_CDSP_FMODE                               (0x10)
++#define       MCB_AA_CDSP_MSAVE                               (0x08)
++#define       MCB_AA_CDSP_SRST                                (0x01)
++#define       MCI_AA_CDSP_SRST_DEF                    (MCB_AA_CDSP_SRST)
++
++#define       MCI_AA_CDSP_SLEEP                               (112)
++
++#define       MCI_AA_CDSP_ERR                         (113)
++
++#define       MCI_AA_CDSP_MAR_MSB                     (114)
++#define       MCI_AA_CDSP_MAR_LSB                     (115)
++
++#define       MCI_AA_OFIFO_IRQ_PNT                    (116)
++
++#define       MCI_AA_EFIFO_IRQ_PNT                    (122)
++
++#define       MCI_AA_CDSP_FLG                         (128)
++
++#define       MCI_AA_ECDSP_ERR                                (129)
++
++/*    B_ADR(CD)       */
++#define       MCI_AA_DPADIF                                   (1)
++#define       MCB_AA_DPADIF                                   (0x10)
++#define       MCI_AA_DPADIF_DEF                               (MCB_AA_DPADIF)
++
++#define       MCI_AA_CD_HW_ID                         (8)
++#define       MCI_AA_CD_HW_ID_DEF                     (0x78)
++
++#define       MCI_AA_AD_AGC                                   (70)
++#define       MCI_AA_AD_AGC_DEF                               (0x03)
++
++#define       MCI_AA_AD_MUTE                                  (71)
++#define       MCI_AA_AD_MUTE_DEF                              (0x00)
++#define       MCB_AA_AD_MUTE                                  (0x01)
++
++#define       MCI_AA_AD_START                         (72)
++#define       MCI_AA_AD_START_DEF                     (0x00)
++#define       MCB_AA_AD_START                         (0x01)
++
++#define       MCI_AA_DCCUTOFF                         (77)
++#define       MCI_AA_DCCUTOFF_DEF                     (0x00)
++
++#define       MCI_AA_DAC_CONFIG                               (78)
++#define       MCI_AA_DAC_CONFIG_DEF                   (0x02)
++#define       MCB_AA_NSMUTE                                   (0x02)
++#define       MCB_AA_DACON                                    (0x01)
++
++#define       MCI_AA_DCL                                              (79)
++#define       MCI_AA_DCL_DEF                                  (0x00)
++
++
++/*    B_ADR(ANA)      */
++#define       MCI_AA_ANA_RST                                  (0)
++#define       MCI_AA_ANA_RST_DEF                              (0x01)
++
++#define       MCI_AA_PWM_ANALOG_0                     (2)
++#define       MCB_AA_PWM_VR                                   (0x01)
++#define       MCB_AA_PWM_CP                                   (0x02)
++#define       MCB_AA_PWM_REFA                         (0x04)
++#define       MCB_AA_PWM_LDOA                         (0x08)
++#define       MCI_AA_PWM_ANALOG_0_DEF         (MCB_AA_PWM_VR|MCB_AA_PWM_CP|MCB_AA_PWM_REFA|MCB_AA_PWM_LDOA)
++
++#define       MCI_AA_PWM_ANALOG_1                     (3)
++#define       MCB_AA_PWM_SPL1                         (0x01)
++#define       MCB_AA_PWM_SPL2                         (0x02)
++#define       MCB_AA_PWM_SPR1                         (0x04)
++#define       MCB_AA_PWM_SPR2                         (0x08)
++#define       MCB_AA_PWM_HPL                                  (0x10)
++#define       MCB_AA_PWM_HPR                                  (0x20)
++#define       MCB_AA_PWM_ADL                                  (0x40)
++#define       MCB_AA_PWM_ADR                                  (0x80)
++#define       MCI_AA_PWM_ANALOG_1_DEF         (MCB_AA_PWM_SPL1|MCB_AA_PWM_SPL2|MCB_AA_PWM_SPR1|MCB_AA_PWM_SPR2|MCB_AA_PWM_HPL|MCB_AA_PWM_HPR|MCB_AA_PWM_ADL|MCB_AA_PWM_ADR)
++
++#define       MCI_AA_PWM_ANALOG_2                     (4)
++#define       MCB_AA_PWM_LO1L                         (0x01)
++#define       MCB_AA_PWM_LO1R                         (0x02)
++#define       MCB_AA_PWM_LO2L                         (0x04)
++#define       MCB_AA_PWM_LO2R                         (0x08)
++#define       MCB_AA_PWM_RC1                                  (0x10)
++#define       MCB_AA_PWM_RC2                                  (0x20)
++#define       MCI_AA_PWM_ANALOG_2_DEF         (MCB_AA_PWM_LO1L|MCB_AA_PWM_LO1R|MCB_AA_PWM_LO2L|MCB_AA_PWM_LO2R|MCB_AA_PWM_RC1|MCB_AA_PWM_RC2)
++
++#define       MCI_AA_PWM_ANALOG_3                     (5)
++#define       MCB_AA_PWM_MB1                                  (0x01)
++#define       MCB_AA_PWM_MB2                                  (0x02)
++#define       MCB_AA_PWM_MB3                                  (0x04)
++#define       MCB_AA_PWM_DA                                   (0x08)
++#define       MCI_AA_PWM_ANALOG_3_DEF         (MCB_AA_PWM_MB1|MCB_AA_PWM_MB2|MCB_AA_PWM_MB3|MCB_AA_PWM_DA)
++
++#define       MCI_AA_PWM_ANALOG_4                     (6)
++#define       MCB_AA_PWM_MC1                                  (0x10)
++#define       MCB_AA_PWM_MC2                                  (0x20)
++#define       MCB_AA_PWM_MC3                                  (0x40)
++#define       MCB_AA_PWM_LI                                   (0x80)
++#define       MCI_AA_PWM_ANALOG_4_DEF         (MCB_AA_PWM_MC1|MCB_AA_PWM_MC2|MCB_AA_PWM_MC3|MCB_AA_PWM_LI)
++
++#define       MCI_AA_BUSY1                                    (12)
++#define       MCB_AA_RC_BUSY                                  (0x20)
++#define       MCB_AA_HPL_BUSY                         (0x10)
++#define       MCB_AA_SPL_BUSY                         (0x08)
++
++#define       MCI_AA_BUSY2                                    (13)
++#define       MCB_AA_HPR_BUSY                         (0x10)
++#define       MCB_AA_SPR_BUSY                         (0x08)
++
++#define       MCI_AA_AMP                                              (16)
++#define       MCB_AA_AMPOFF_SP                                (0x01)
++#define       MCB_AA_AMPOFF_HP                                (0x02)
++#define       MCB_AA_AMPOFF_RC                                (0x04)
++
++#define       MCI_AA_DNGATRT                                  (20)
++#define       MCI_AA_DNGATRT_DEF                              (0x22)
++
++#define       MCI_AA_DNGON                                    (21)
++#define       MCI_AA_DNGON_DEF                                (0x34)
++
++#define       MCI_AA_DIF_LINE                         (24)
++#define       MCI_AA_DIF_LINE_DEF                     (0x00)
++
++#define       MCI_AA_LI1VOL_L                         (25)
++#define       MCI_AA_LI1VOL_L_DEF                     (0x00)
++#define       MCB_AA_ALAT_LI1                         (0x40)
++#define       MCB_AA_LI1VOL_L                         (0x1F)
++
++#define       MCI_AA_LI1VOL_R                         (26)
++#define       MCI_AA_LI1VOL_R_DEF                     (0x00)
++#define       MCB_AA_LI1VOL_R                         (0x1F)
++
++#define       MCI_AA_LI2VOL_L                         (27)
++#define       MCI_AA_LI2VOL_L_DEF                     (0x00)
++#define       MCB_AA_ALAT_LI2                         (0x40)
++#define       MCB_AA_LI2VOL_L                         (0x1F)
++
++#define       MCI_AA_LI2VOL_R                         (28)
++#define       MCI_AA_LI2VOL_R_DEF                     (0x00)
++#define       MCB_AA_LI2VOL_R                         (0x1F)
++
++#define       MCI_AA_MC1VOL                                   (29)
++#define       MCI_AA_MC1VOL_DEF                               (0x00)
++#define       MCB_AA_MC1VOL                                   (0x1F)
++
++#define       MCI_AA_MC2VOL                                   (30)
++#define       MCI_AA_MC2VOL_DEF                               (0x00)
++#define       MCB_AA_MC2VOL                                   (0x1F)
++
++#define       MCI_AA_MC3VOL                                   (31)
++#define       MCI_AA_MC3VOL_DEF                               (0x00)
++#define       MCB_AA_MC3VOL                                   (0x1F)
++
++#define       MCI_AA_ADVOL_L                                  (32)
++#define       MCI_AA_ADVOL_L_DEF                              (0x00)
++#define       MCB_AA_ALAT_AD                                  (0x40)
++#define       MCB_AA_ADVOL_L                                  (0x1F)
++
++#define       MCI_AA_ADVOL_R                                  (33)
++#define       MCB_AA_ADVOL_R                                  (0x1F)
++
++#define       MCI_AA_HPVOL_L                                  (35)
++#define       MCB_AA_ALAT_HP                                  (0x40)
++#define       MCB_AA_SVOL_HP                                  (0x20)
++#define       MCB_AA_HPVOL_L                                  (0x1F)
++#define       MCI_AA_HPVOL_L_DEF                              (MCB_AA_SVOL_HP)
++
++#define       MCI_AA_HPVOL_R                                  (36)
++#define       MCI_AA_HPVOL_R_DEF                              (0x00)
++#define       MCB_AA_HPVOL_R                                  (0x1F)
++
++#define       MCI_AA_SPVOL_L                                  (37)
++#define       MCB_AA_ALAT_SP                                  (0x40)
++#define       MCB_AA_SVOL_SP                                  (0x20)
++#define       MCB_AA_SPVOL_L                                  (0x1F)
++#define       MCI_AA_SPVOL_L_DEF                              (MCB_AA_SVOL_SP)
++
++#define       MCI_AA_SPVOL_R                                  (38)
++#define       MCI_AA_SPVOL_R_DEF                              (0x00)
++#define       MCB_AA_SPVOL_R                                  (0x1F)
++
++#define       MCI_AA_RCVOL                                    (39)
++#define       MCB_AA_SVOL_RC                                  (0x20)
++#define       MCB_AA_RCVOL                                    (0x1F)
++#define       MCI_AA_RCVOL_DEF                                (MCB_AA_SVOL_RC)
++
++#define       MCI_AA_LO1VOL_L                         (40)
++#define       MCI_AA_LO1VOL_L_DEF                     (0x20)
++#define       MCB_AA_ALAT_LO1                         (0x40)
++#define       MCB_AA_LO1VOL_L                         (0x1F)
++
++#define       MCI_AA_LO1VOL_R                         (41)
++#define       MCI_AA_LO1VOL_R_DEF                     (0x00)
++#define       MCB_AA_LO1VOL_R                         (0x1F)
++
++#define       MCI_AA_LO2VOL_L                         (42)
++#define       MCI_AA_LO2VOL_L_DEF                     (0x20)
++#define       MCB_AA_ALAT_LO2                         (0x40)
++#define       MCB_AA_LO2VOL_L                         (0x1F)
++
++#define       MCI_AA_LO2VOL_R                         (43)
++#define       MCI_AA_LO2VOL_R_DEF                     (0x00)
++#define       MCB_AA_LO2VOL_R                         (0x1F)
++
++#define       MCI_AA_SP_MODE                                  (44)
++#define       MCB_AA_SPR_HIZ                                  (0x20)
++#define       MCB_AA_SPL_HIZ                                  (0x10)
++#define       MCB_AA_SPMN                                     (0x02)
++#define       MCB_AA_SP_SWAP                                  (0x01)
++
++#define       MCI_AA_MC_GAIN                                  (45)
++#define       MCI_AA_MC_GAIN_DEF                              (0x00)
++#define       MCB_AA_MC2SNG                                   (0x40)
++#define       MCB_AA_MC2GAIN                                  (0x30)
++#define       MCB_AA_MC1SNG                                   (0x04)
++#define       MCB_AA_MC1GAIN                                  (0x03)
++
++#define       MCI_AA_MC3_GAIN                         (46)
++#define       MCI_AA_MC3_GAIN_DEF                     (0x00)
++#define       MCB_AA_MC3SNG                                   (0x04)
++#define       MCB_AA_MC3GAIN                                  (0x03)
++
++#define       MCI_AA_RDY_FLAG                         (47)
++#define       MCB_AA_LDO_RDY                                  (0x80)
++#define       MCB_AA_VREF_RDY                         (0x40)
++#define       MCB_AA_SPRDY_R                                  (0x20)
++#define       MCB_AA_SPRDY_L                                  (0x10)
++#define       MCB_AA_HPRDY_R                                  (0x08)
++#define       MCB_AA_HPRDY_L                                  (0x04)
++#define       MCB_AA_CPPDRDY                                  (0x02)
++
++/*    analog mixer common */
++#define       MCB_AA_LI1MIX                                   (0x01)
++#define       MCB_AA_M1MIX                                    (0x08)
++#define       MCB_AA_M2MIX                                    (0x10)
++#define       MCB_AA_M3MIX                                    (0x20)
++#define       MCB_AA_DAMIX                                    (0x40)
++#define       MCB_AA_DARMIX                                   (0x40)
++#define       MCB_AA_DALMIX                                   (0x80)
++
++#define       MCB_AA_MONO_DA                                  (0x40)
++#define       MCB_AA_MONO_LI1                         (0x01)
++
++#define       MCI_AA_ADL_MIX                                  (50)
++#define       MCI_AA_ADL_MONO                         (51)
++#define       MCI_AA_ADR_MIX                                  (52)
++#define       MCI_AA_ADR_MONO                         (53)
++
++#define       MCI_AA_LO1L_MIX                         (55)
++#define       MCI_AA_LO1L_MONO                                (56)
++#define       MCI_AA_LO1R_MIX                         (57)
++
++#define       MCI_AA_LO2L_MIX                         (58)
++#define       MCI_AA_LO2L_MONO                                (59)
++#define       MCI_AA_LO2R_MIX                         (60)
++
++#define       MCI_AA_HPL_MIX                                  (61)
++#define       MCI_AA_HPL_MONO                         (62)
++#define       MCI_AA_HPR_MIX                                  (63)
++
++#define       MCI_AA_SPL_MIX                                  (64)
++#define       MCI_AA_SPL_MONO                         (65)
++#define       MCI_AA_SPR_MIX                                  (66)
++#define       MCI_AA_SPR_MONO                         (67)
++
++#define       MCI_AA_RC_MIX                                   (69)
++
++#define       MCI_AA_HP_GAIN                                  (77)
++
++#define       MCI_AA_LEV                                              (79)
++#define       MCB_AA_AVDDLEV                                  (0x07)
++#define       MCI_AA_LEV_DEF                                  (0x24)
++
++#define       MCI_AA_AP_A1                                    (123)
++#define       MCB_AA_AP_CP_A                                  (0x10)
++#define       MCB_AA_AP_HPL_A                         (0x02)
++#define       MCB_AA_AP_HPR_A                         (0x01)
++
++#define       MCI_AA_AP_A2                                    (124)
++#define       MCB_AA_AP_RC1_A                         (0x20)
++#define       MCB_AA_AP_RC2_A                         (0x10)
++#define       MCB_AA_AP_SPL1_A                                (0x08)
++#define       MCB_AA_AP_SPR1_A                                (0x04)
++#define       MCB_AA_AP_SPL2_A                                (0x02)
++#define       MCB_AA_AP_SPR2_A                                (0x01)
++
++/************************************/
++
++typedef enum
++{
++      eMCDRV_DEV_ID_1N2       = 0,
++      eMCDRV_DEV_ID_1N2B,
++      eMCDRV_DEV_ID_2N,
++      eMCDRV_DEV_ID_3N
++} MCDRV_DEV_ID;
++
++typedef enum
++{
++      eMCDRV_FUNC_LI2 = 0,
++      eMCDRV_FUNC_DIVR1,
++      eMCDRV_FUNC_DIVF1,
++      eMCDRV_FUNC_RANGE,
++      eMCDRV_FUNC_BYPASS,
++      eMCDRV_FUNC_ADC1,
++      eMCDRV_FUNC_PAD2,
++      eMCDRV_FUNC_DBEX,
++      eMCDRV_FUNC_GPMODE,
++      eMCDRV_FUNC_DTMF,
++      eMCDRV_FUNC_IRQ,
++      eMCDRV_FUNC_HWADJ
++} MCDRV_FUNC_KIND;
++
++typedef enum
++{
++      eMCDRV_SLAVE_ADDR_DIG   = 0,
++      eMCDRV_SLAVE_ADDR_ANA
++} MCDRV_SLAVE_ADDR_KIND;
++
++static        MCDRV_DEV_ID    geDevID = eMCDRV_DEV_ID_1N2;
++
++static        UINT8   gabValid[][4]   =
++{
++/*    MC-1N2  MC-1N2B MC-2N   MC-3N   */
++      {0,             0,              0,              1},             /*      DI2             */
++      {0,             0,              0,              1},             /*      DIVR1   */
++      {0,             0,              0,              1},             /*      DIVF1   */
++      {0,             0,              0,              1},             /*      RANGE   */
++      {0,             0,              0,              1},             /*      BYPASS  */
++      {0,             0,              0,              1},             /*      ADC1    */
++      {0,             0,              0,              1},             /*      PAD2    */
++      {0,             0,              1,              1},             /*      DBEX    */
++      {0,             0,              0,              1},             /*      GPMODE  */
++      {0,             0,              0,              1},             /*      DTMF    */
++      {0,             0,              0,              1},             /*      IRQ             */
++      {0,             0,              0,              0},             /*      HWADJ   */
++};
++
++static UINT8  gabSlaveAddr[3][2]      =
++{
++/*    Digital Analog  */
++      {0x3A,  0x3A},  /*      MC1N2   */
++      {0x00,  0x00},  /*      MC2N    */
++      {0x00,  0x00}   /*      MC3N    */
++};
++
++/****************************************************************************
++ *    McDevProf_SetDevId
++ *
++ *    Description:
++ *                    Set device ID.
++ *    Arguments:
++ *                    eDevId  device ID
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   McDevProf_SetDevId(MCDRV_DEV_ID eDevId)
++{
++      geDevID = eDevId;
++}
++
++/****************************************************************************
++ *    McDevProf_IsValid
++ *
++ *    Description:
++ *                    Validity function.
++ *    Arguments:
++ *                    function kind
++ *    Return:
++ *                    0:Invalid/1:Valid
++ *
++ ****************************************************************************/
++static UINT8  McDevProf_IsValid
++(
++      MCDRV_FUNC_KIND eFuncKind
++)
++{
++      return gabValid[eFuncKind][geDevID];
++}
++
++/****************************************************************************
++ *    McDevProf_GetSlaveAddr
++ *
++ *    Description:
++ *                    get slave address.
++ *    Arguments:
++ *                    eSlaveAddrKind  slave address kind
++ *    Return:
++ *                    slave address
++ *
++ ****************************************************************************/
++static UINT8  McDevProf_GetSlaveAddr
++(
++      MCDRV_SLAVE_ADDR_KIND eSlaveAddrKind
++)
++{
++      return gabSlaveAddr[geDevID][eSlaveAddrKind];
++}
++
++/**************************************/
++
++/*    UpdateReg parameter     */
++typedef enum
++{
++      eMCDRV_UPDATE_NORMAL_AA,
++      eMCDRV_UPDATE_FORCE_AA,
++      eMCDRV_UPDATE_DUMMY_AA
++} MCDRV_UPDATE_MODE_AA;
++
++/*    ePacketBufAlloc setting */
++typedef enum
++{
++      eMCDRV_PACKETBUF_FREE_AA,
++      eMCDRV_PACKETBUF_ALLOCATED_AA
++} MCDRV_PACKETBUF_ALLOC_AA;
++
++/* packet */
++typedef struct
++{
++      UINT32  dDesc;
++      UINT8   bData;
++} MCDRV_PACKET_AA;
++
++#define       MCDRV_MAX_PACKETS_AA                                    (256UL)
++
++/*    packet dDesc    */
++/*    packet type     */
++#define       MCDRV_PACKET_TYPE_WRITE_AA                              (0x10000000UL)
++#define       MCDRV_PACKET_TYPE_FORCE_WRITE_AA                (0x20000000UL)
++#define       MCDRV_PACKET_TYPE_TIMWAIT_AA                    (0x30000000UL)
++#define       MCDRV_PACKET_TYPE_EVTWAIT_AA                    (0x40000000UL)
++#define       MCDRV_PACKET_TYPE_TERMINATE_AA                  (0xF0000000UL)
++
++#define       MCDRV_PACKET_TYPE_MASK_AA                               (0xF0000000UL)
++
++/*    reg type        */
++#define       MCDRV_PACKET_REGTYPE_A_AA                               (0x00000000UL)
++#define       MCDRV_PACKET_REGTYPE_B_BASE_AA                  (0x00001000UL)
++#define       MCDRV_PACKET_REGTYPE_B_MIXER_AA         (0x00002000UL)
++#define       MCDRV_PACKET_REGTYPE_B_AE_AA                    (0x00003000UL)
++#define       MCDRV_PACKET_REGTYPE_B_CDSP_AA                  (0x00004000UL)
++#define       MCDRV_PACKET_REGTYPE_B_CODEC_AA         (0x00005000UL)
++#define       MCDRV_PACKET_REGTYPE_B_ANA_AA                   (0x00006000UL)
++
++#define       MCDRV_PACKET_REGTYPE_MASK_AA                    (0x0000F000UL)
++#define       MCDRV_PACKET_ADR_MASK_AA                                (0x00000FFFUL)
++
++/*    event   */
++#define       MCDRV_EVT_INSFLG_AA                                     (0x00010000UL)
++#define       MCDRV_EVT_ALLMUTE_AA                                    (0x00020000UL)
++#define       MCDRV_EVT_DACMUTE_AA                                    (0x00030000UL)
++#define       MCDRV_EVT_DITMUTE_AA                                    (0x00040000UL)
++#define       MCDRV_EVT_SVOL_DONE_AA                                  (0x00050000UL)
++#define       MCDRV_EVT_APM_DONE_AA                                   (0x00060000UL)
++#define       MCDRV_EVT_ANA_RDY_AA                                    (0x00070000UL)
++#define       MCDRV_EVT_SYSEQ_FLAG_RESET_AA                   (0x00080000UL)
++#define       MCDRV_EVT_CLKBUSY_RESET_AA                              (0x00090000UL)
++#define       MCDRV_EVT_CLKSRC_SET_AA                         (0x000A0000UL)
++#define       MCDRV_EVT_CLKSRC_RESET_AA                               (0x000B0000UL)
++
++#define       MCDRV_PACKET_EVT_MASK_AA                                (0x0FFF0000UL)
++#define       MCDRV_PACKET_EVTPRM_MASK_AA                     (0x0000FFFFUL)
++
++/*    timer   */
++#define       MCDRV_PACKET_TIME_MASK_AA                               (0x0FFFFFFFUL)
++
++static SINT32 McDevIf_AllocPacketBuf_AA       (void);
++static void           McDevIf_ReleasePacketBuf_AA     (void);
++static void           McDevIf_ClearPacket_AA          (void);
++static void           McDevIf_AddPacket_AA            (UINT32 dDesc, UINT8 bData);
++static void           McDevIf_AddPacketRepeat_AA      (UINT32 dDesc, const UINT8* pbData, UINT16 wDataCount);
++static SINT32 McDevIf_ExecutePacket_AA        (void);
++
++static MCDRV_PACKET_AA*       gpsPacket       = NULL;
++
++
++static MCDRV_PACKET_AA*       McResCtrl_AllocPacketBuf_AA                     (void);
++static void                           McResCtrl_ReleasePacketBuf_AA           (void);
++static void                           McResCtrl_InitRegUpdate_AA                      (void);
++static void                           McResCtrl_AddRegUpdate_AA                       (UINT16 wRegType, UINT16 wAddress, UINT8 bData, MCDRV_UPDATE_MODE_AA eUpdateMode);
++static void                           McResCtrl_ExecuteRegUpdate_AA           (void);
++static SINT32                 McResCtrl_WaitEvent_AA                          (UINT32 dEvent, UINT32 dParam);
++
++
++/****************************************************************************
++ *    McDevIf_AllocPacketBuf_AA
++ *
++ *    \8b@\94\:
++ *                    \83\8c\83W\83X\83^\90Ý\92è\83p\83P\83b\83g\97p\83o\83b\83t\83@\82Ì\8am\95Û.
++ *    \88ø\90\94:
++ *                    \82È\82µ
++ *    \96ß\82è\92l:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR
++ *
++ ****************************************************************************/
++SINT32        McDevIf_AllocPacketBuf_AA
++(
++      void
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++
++      gpsPacket       = McResCtrl_AllocPacketBuf_AA();
++      if(gpsPacket == NULL)
++      {
++              sdRet   = MCDRV_ERROR;
++      }
++      else
++      {
++              McDevIf_ClearPacket_AA();
++      }
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    McDevIf_ReleasePacketBuf_AA
++ *
++ *    \8b@\94\:
++ *                    \83\8c\83W\83X\83^\90Ý\92è\83p\83P\83b\83g\97p\83o\83b\83t\83@\82Ì\8aJ\95ú.
++ *    \88ø\90\94:
++ *                    \82È\82µ
++ *    \96ß\82è\92l:
++ *                    \82È\82µ
++ *
++ ****************************************************************************/
++void  McDevIf_ReleasePacketBuf_AA
++(
++      void
++)
++{
++      McResCtrl_ReleasePacketBuf_AA();
++}
++
++/****************************************************************************
++ *    McDevIf_ClearPacket_AA
++ *
++ *    \8b@\94\:
++ *                    \83p\83P\83b\83g\82Ì\83N\83\8a\83A.
++ *    \88ø\90\94:
++ *                    \82È\82µ
++ *    \96ß\82è\92l:
++ *                    \82È\82µ
++ *
++ ****************************************************************************/
++void  McDevIf_ClearPacket_AA
++(
++      void
++)
++{
++      if(gpsPacket == NULL)
++      {
++              return;
++      }
++
++      gpsPacket[0].dDesc = MCDRV_PACKET_TYPE_TERMINATE_AA;
++}
++
++/****************************************************************************
++ *    McDevIf_AddPacket_AA
++ *
++ *    \8b@\94\:
++ *                    \83p\83P\83b\83g\92Ç\89Á
++ *    \88ø\90\94:
++ *                    dDesc                   \83p\83P\83b\83g\8fî\95ñ
++ *                    bData                   \83p\83P\83b\83g\83f\81[\83^
++ *    \96ß\82è\92l:
++ *                    \82È\82µ
++ *
++ ****************************************************************************/
++void  McDevIf_AddPacket_AA
++(
++      UINT32                  dDesc,
++      UINT8                   bData
++)
++{
++      UINT32  i;
++
++      if(gpsPacket == NULL)
++      {
++      }
++      else
++      {
++              for(i = 0; i < MCDRV_MAX_PACKETS_AA; i++)
++              {
++                      if(gpsPacket[i].dDesc == MCDRV_PACKET_TYPE_TERMINATE_AA)
++                      {
++                              break;
++                      }
++              }
++              if(i >= MCDRV_MAX_PACKETS_AA)
++              {
++                      McDevIf_ExecutePacket_AA();
++                      i       = 0;
++              }
++
++              gpsPacket[i].dDesc              = dDesc;
++              gpsPacket[i].bData              = bData;
++              gpsPacket[i+1UL].dDesc  = MCDRV_PACKET_TYPE_TERMINATE_AA;
++      }
++}
++
++/****************************************************************************
++ *    McDevIf_AddPacketRepeat_AA
++ *
++ *    \8b@\94\:
++ *                    \93¯\88ê\83\8c\83W\83X\83^\82É\8cJ\82è\95Ô\82µ\83f\81[\83^\83Z\83b\83g\82·\82é\83p\83P\83b\83g\82ð\92Ç\89Á
++ *    \88ø\90\94:
++ *                    dDesc                   \83p\83P\83b\83g\8fî\95ñ
++ *                    pbData                  \83p\83P\83b\83g\83f\81[\83^\83o\83b\83t\83@\82Ì\83|\83C\83\93\83^
++ *                    wDataCount              \83p\83P\83b\83g\83f\81[\83^\90\94
++ *    \96ß\82è\92l:
++ *                    \82È\82µ
++ *
++ ****************************************************************************/
++void  McDevIf_AddPacketRepeat_AA
++(
++      UINT32                  dDesc,
++      const UINT8*    pbData,
++      UINT16                  wDataCount
++)
++{
++      UINT16  wCount;
++
++      for(wCount = 0; wCount < wDataCount; wCount++)
++      {
++              McDevIf_AddPacket_AA(dDesc, pbData[wCount]);
++      }
++}
++
++/****************************************************************************
++ *    McDevIf_ExecutePacket_AA
++ *
++ *    \8b@\94\:
++ *                    \83\8c\83W\83X\83^\90Ý\92è\83V\81[\83P\83\93\83X\82Ì\8eÀ\8ds.
++ *    \88ø\90\94:
++ *                    \82È\82µ
++ *    \96ß\82è\92l:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++SINT32        McDevIf_ExecutePacket_AA
++(
++      void
++)
++{
++      SINT32  sdRet;
++      SINT16  swPacketIndex;
++      UINT32  dPacketType;
++      UINT32  dParam1;
++      UINT32  dParam2;
++      UINT16  wAddress;
++      UINT16  wRegType;
++      MCDRV_UPDATE_MODE_AA    eUpdateMode;
++
++      if(gpsPacket == NULL)
++      {
++              sdRet   = MCDRV_ERROR_RESOURCEOVER;
++      }
++      else
++      {
++              sdRet   = MCDRV_SUCCESS;
++
++              McResCtrl_InitRegUpdate_AA();
++              swPacketIndex = 0;
++              while ((MCDRV_PACKET_TYPE_TERMINATE_AA != (gpsPacket[swPacketIndex].dDesc & MCDRV_PACKET_TYPE_MASK_AA)) && (sdRet == MCDRV_SUCCESS))
++              {
++                      dPacketType = gpsPacket[swPacketIndex].dDesc & MCDRV_PACKET_TYPE_MASK_AA;
++                      switch (dPacketType)
++                      {
++                      case MCDRV_PACKET_TYPE_WRITE_AA:
++                      case MCDRV_PACKET_TYPE_FORCE_WRITE_AA:
++                              wRegType = (UINT16)(gpsPacket[swPacketIndex].dDesc & MCDRV_PACKET_REGTYPE_MASK_AA);
++                              wAddress = (UINT16)(gpsPacket[swPacketIndex].dDesc & MCDRV_PACKET_ADR_MASK_AA);
++                              if (MCDRV_PACKET_TYPE_WRITE_AA == dPacketType)
++                              {
++                                      eUpdateMode = eMCDRV_UPDATE_NORMAL_AA;
++                              }
++                              else if (MCDRV_PACKET_TYPE_FORCE_WRITE_AA == dPacketType)
++                              {
++                                      eUpdateMode = eMCDRV_UPDATE_FORCE_AA;
++                              }
++                              else
++                              {
++                                      eUpdateMode = eMCDRV_UPDATE_DUMMY_AA;
++                              }
++                              McResCtrl_AddRegUpdate_AA(wRegType, wAddress, gpsPacket[swPacketIndex].bData, eUpdateMode);
++                              break;
++
++                      case MCDRV_PACKET_TYPE_TIMWAIT_AA:
++                              McResCtrl_ExecuteRegUpdate_AA();
++                              McResCtrl_InitRegUpdate_AA();
++                              dParam1 = gpsPacket[swPacketIndex].dDesc & MCDRV_PACKET_TIME_MASK_AA;
++                              McSrv_Sleep(dParam1);
++                              break;
++
++                      case MCDRV_PACKET_TYPE_EVTWAIT_AA:
++                              McResCtrl_ExecuteRegUpdate_AA();
++                              McResCtrl_InitRegUpdate_AA();
++                              dParam1 = gpsPacket[swPacketIndex].dDesc & MCDRV_PACKET_EVT_MASK_AA;
++                              dParam2 = gpsPacket[swPacketIndex].dDesc & MCDRV_PACKET_EVTPRM_MASK_AA;
++                              sdRet = McResCtrl_WaitEvent_AA(dParam1, dParam2);
++                              break;
++
++                      default:
++                              sdRet   = MCDRV_ERROR;
++                              break;
++                      }
++
++                      swPacketIndex++;
++              }
++              if(sdRet == MCDRV_SUCCESS)
++              {
++                      McResCtrl_ExecuteRegUpdate_AA();
++              }
++              McDevIf_ClearPacket_AA();
++      }
++
++      return sdRet;
++}
++
++/*****************************************/
++
++/*    power setting   */
++#define       MCDRV_POWINFO_DIGITAL_DP0_AA            ((UINT32)0x0001)
++#define       MCDRV_POWINFO_DIGITAL_DP1_AA            ((UINT32)0x0002)
++#define       MCDRV_POWINFO_DIGITAL_DP2_AA            ((UINT32)0x0004)
++#define       MCDRV_POWINFO_DIGITAL_DPB_AA            ((UINT32)0x0008)
++#define       MCDRV_POWINFO_DIGITAL_DPDI0_AA          ((UINT32)0x0010)
++#define       MCDRV_POWINFO_DIGITAL_DPDI1_AA          ((UINT32)0x0020)
++#define       MCDRV_POWINFO_DIGITAL_DPDI2_AA          ((UINT32)0x0040)
++#define       MCDRV_POWINFO_DIGITAL_DPPDM_AA          ((UINT32)0x0080)
++#define       MCDRV_POWINFO_DIGITAL_DPBDSP_AA         ((UINT32)0x0100)
++#define       MCDRV_POWINFO_DIGITAL_DPADIF_AA         ((UINT32)0x0200)
++#define       MCDRV_POWINFO_DIGITAL_PLLRST0_AA        ((UINT32)0x0400)
++typedef struct
++{
++      UINT32  dDigital;
++      UINT8   abAnalog[5];
++} MCDRV_POWER_INFO_AA;
++
++
++#define       MCDRV_BURST_WRITE_ENABLE        (0x01)
++
++/*    eState setting  */
++typedef enum
++{
++      eMCDRV_STATE_NOTINIT_AA,
++      eMCDRV_STATE_READY_AA
++} MCDRV_STATE_AA;
++
++/*    volume setting  */
++#define       MCDRV_LOGICAL_VOL_MUTE          (-24576)        /*      -96dB   */
++#define       MCDRV_LOGICAL_MICGAIN_DEF       (3840)          /*      15dB    */
++#define       MCDRV_LOGICAL_HPGAIN_DEF        (0)                     /*      0dB             */
++
++#define       MCDRV_VOLUPDATE_ALL_AA                  (0xFFFFFFFFUL)
++#define       MCDRV_VOLUPDATE_ANAOUT_ALL_AA   (0x00000001UL)
++
++#define       MCDRV_REG_MUTE  (0x00)
++
++/*    DAC source setting      */
++typedef enum
++{
++      eMCDRV_DAC_MASTER_AA    = 0,
++      eMCDRV_DAC_VOICE_AA
++} MCDRV_DAC_CH_AA;
++
++/*    DIO port setting        */
++typedef enum
++{
++      eMCDRV_DIO_0_AA = 0,
++      eMCDRV_DIO_1_AA,
++      eMCDRV_DIO_2_AA
++} MCDRV_DIO_PORT_NO_AA;
++
++/*    Path source setting     */
++typedef enum
++{
++      eMCDRV_SRC_NONE_AA                      = (0),
++      eMCDRV_SRC_MIC1_AA                      = (1<<0),
++      eMCDRV_SRC_MIC2_AA                      = (1<<1),
++      eMCDRV_SRC_MIC3_AA                      = (1<<2),
++      eMCDRV_SRC_LINE1_L_AA           = (1<<3),
++      eMCDRV_SRC_LINE1_R_AA           = (1<<4),
++      eMCDRV_SRC_LINE1_M_AA           = (1<<5),
++      eMCDRV_SRC_LINE2_L_AA           = (1<<6),
++      eMCDRV_SRC_LINE2_R_AA           = (1<<7),
++      eMCDRV_SRC_LINE2_M_AA           = (1<<8),
++      eMCDRV_SRC_DIR0_AA                      = (1<<9),
++      eMCDRV_SRC_DIR1_AA                      = (1<<10),
++      eMCDRV_SRC_DIR2_AA                      = (1<<11),
++      eMCDRV_SRC_DTMF_AA                      = (1<<12),
++      eMCDRV_SRC_PDM_AA                       = (1<<13),
++      eMCDRV_SRC_ADC0_AA                      = (1<<14),
++      eMCDRV_SRC_ADC1_AA                      = (1<<15),
++      eMCDRV_SRC_DAC_L_AA                     = (1<<16),
++      eMCDRV_SRC_DAC_R_AA                     = (1<<17),
++      eMCDRV_SRC_DAC_M_AA                     = (1<<18),
++      eMCDRV_SRC_AE_AA                        = (1<<19),
++      eMCDRV_SRC_CDSP_AA                      = (1<<20),
++      eMCDRV_SRC_MIX_AA                       = (1<<21),
++      eMCDRV_SRC_DIR2_DIRECT_AA       = (1<<22),
++      eMCDRV_SRC_CDSP_DIRECT_AA       = (1<<23)
++} MCDRV_SRC_TYPE_AA;
++
++/*    Path destination setting        */
++typedef enum
++{
++      eMCDRV_DST_CH0_AA       = 0,
++      eMCDRV_DST_CH1_AA
++} MCDRV_DST_CH;
++typedef enum
++{
++      eMCDRV_DST_HP_AA        = 0,
++      eMCDRV_DST_SP_AA,
++      eMCDRV_DST_RCV_AA,
++      eMCDRV_DST_LOUT1_AA,
++      eMCDRV_DST_LOUT2_AA,
++      eMCDRV_DST_PEAK_AA,
++      eMCDRV_DST_DIT0_AA,
++      eMCDRV_DST_DIT1_AA,
++      eMCDRV_DST_DIT2_AA,
++      eMCDRV_DST_DAC_AA,
++      eMCDRV_DST_AE_AA,
++      eMCDRV_DST_CDSP_AA,
++      eMCDRV_DST_ADC0_AA,
++      eMCDRV_DST_ADC1_AA,
++      eMCDRV_DST_MIX_AA,
++      eMCDRV_DST_BIAS_AA
++} MCDRV_DST_TYPE_AA;
++
++/*    Register accsess availability   */
++typedef enum
++{
++      eMCDRV_ACCESS_DENY_AA   = 0,
++      eMCDRV_READ_ONLY_AA     = 0x01,
++      eMCDRV_WRITE_ONLY_AA    = 0x02,
++      eMCDRV_READ_WRITE_AA    = eMCDRV_READ_ONLY_AA | eMCDRV_WRITE_ONLY_AA
++} MCDRV_REG_ACCSESS_AA;
++
++
++/* power management sequence mode */
++typedef enum
++{
++      eMCDRV_APM_ON_AA,
++      eMCDRV_APM_OFF_AA
++} MCDRV_PMODE_AA;
++
++#define       MCDRV_A_REG_NUM_AA                      (64)
++#define       MCDRV_B_BASE_REG_NUM_AA         (32)
++#define       MCDRV_B_MIXER_REG_NUM_AA        (218)
++#define       MCDRV_B_AE_REG_NUM_AA           (255)
++#define       MCDRV_B_CDSP_REG_NUM_AA         (130)
++#define       MCDRV_B_CODEC_REG_NUM_AA        (128)
++#define       MCDRV_B_ANA_REG_NUM_AA          (128)
++
++/* control packet for serial host interface */
++#define       MCDRV_MAX_CTRL_DATA_NUM (1024)
++typedef struct
++{
++      UINT8   abData[MCDRV_MAX_CTRL_DATA_NUM];
++      UINT16  wDataNum;
++} MCDRV_SERIAL_CTRL_PACKET_AA;
++
++/*    HWADJ setting   */
++typedef enum _MCDRV_HWADJ
++{
++      eMCDRV_HWADJ_NOCHANGE   = 0,
++      eMCDRV_HWADJ_THRU,
++      eMCDRV_HWADJ_REC8,
++      eMCDRV_HWADJ_REC44,
++      eMCDRV_HWADJ_REC48,
++      eMCDRV_HWADJ_PLAY8,
++      eMCDRV_HWADJ_PLAY44,
++      eMCDRV_HWADJ_PLAY48
++} MCDRV_HWADJ;
++
++/*    global information      */
++typedef struct
++{
++      UINT8                                           bHwId;
++      MCDRV_PACKETBUF_ALLOC_AA                ePacketBufAlloc;
++      UINT8                                           abRegValA[MCDRV_A_REG_NUM_AA];
++      UINT8                                           abRegValB_BASE[MCDRV_B_BASE_REG_NUM_AA];
++      UINT8                                           abRegValB_MIXER[MCDRV_B_MIXER_REG_NUM_AA];
++      UINT8                                           abRegValB_AE[MCDRV_B_AE_REG_NUM_AA];
++      UINT8                                           abRegValB_CDSP[MCDRV_B_CDSP_REG_NUM_AA];
++      UINT8                                           abRegValB_CODEC[MCDRV_B_CODEC_REG_NUM_AA];
++      UINT8                                           abRegValB_ANA[MCDRV_B_ANA_REG_NUM_AA];
++
++      MCDRV_INIT_INFO                         sInitInfo;
++      MCDRV_PATH_INFO                         sPathInfo;
++      MCDRV_PATH_INFO                         sPathInfoVirtual;
++      MCDRV_VOL_INFO                          sVolInfo;
++      MCDRV_DIO_INFO                          sDioInfo;
++      MCDRV_DAC_INFO                          sDacInfo;
++      MCDRV_ADC_INFO                          sAdcInfo;
++      MCDRV_SP_INFO                           sSpInfo;
++      MCDRV_DNG_INFO                          sDngInfo;
++      MCDRV_AE_INFO                           sAeInfo;
++      MCDRV_PDM_INFO                          sPdmInfo;
++      MCDRV_GP_MODE                           sGpMode;
++      UINT8                                           abGpMask[GPIO_PAD_NUM];
++
++      MCDRV_SERIAL_CTRL_PACKET_AA     sCtrlPacket;
++      UINT16                                          wCurSlaveAddress;
++      UINT16                                          wCurRegType;
++      UINT16                                          wCurRegAddress;
++      UINT16                                          wDataContinueCount;
++      UINT16                                          wPrevAddressIndex;
++
++      MCDRV_PMODE_AA                                  eAPMode;
++
++      MCDRV_HWADJ                                     eHwAdj;
++} MCDRV_GLOBAL_INFO_AA;
++
++static SINT32                 McResCtrl_SetHwId_AA                            (UINT8 bHwId);
++static void                           McResCtrl_Init_AA                                       (const MCDRV_INIT_INFO* psInitInfo);
++static void                           McResCtrl_UpdateState_AA                        (MCDRV_STATE_AA eState);
++static MCDRV_STATE_AA McResCtrl_GetState_AA                           (void);
++static UINT8                  McResCtrl_GetRegVal_AA                          (UINT16 wRegType, UINT16 wRegAddr);
++static void                           McResCtrl_SetRegVal_AA                          (UINT16 wRegType, UINT16 wRegAddr, UINT8 bRegVal);
++
++static void                           McResCtrl_GetInitInfo_AA                        (MCDRV_INIT_INFO* psInitInfo);
++static void                           McResCtrl_SetClockInfo_AA                       (const MCDRV_CLOCK_INFO* psClockInfo);
++static void                           McResCtrl_SetPathInfo_AA                        (const MCDRV_PATH_INFO* psPathInfo);
++static void                           McResCtrl_GetPathInfo_AA                        (MCDRV_PATH_INFO* psPathInfo);
++static void                           McResCtrl_GetPathInfoVirtual_AA         (MCDRV_PATH_INFO* psPathInfo);
++static void                           McResCtrl_SetDioInfo_AA                         (const MCDRV_DIO_INFO* psDioInfo, UINT32 dUpdateInfo);
++static void                           McResCtrl_GetDioInfo_AA                         (MCDRV_DIO_INFO* psDioInfo);
++static void                           McResCtrl_SetVolInfo_AA                         (const MCDRV_VOL_INFO* psVolInfo);
++static void                           McResCtrl_GetVolInfo_AA                         (MCDRV_VOL_INFO* psVolInfo);
++static void                           McResCtrl_SetDacInfo_AA                         (const MCDRV_DAC_INFO* psDacInfo, UINT32 dUpdateInfo);
++static void                           McResCtrl_GetDacInfo_AA                         (MCDRV_DAC_INFO* psDacInfo);
++static void                           McResCtrl_SetAdcInfo_AA                         (const MCDRV_ADC_INFO* psAdcInfo, UINT32 dUpdateInfo);
++static void                           McResCtrl_GetAdcInfo_AA                         (MCDRV_ADC_INFO* psAdcInfo);
++static void                           McResCtrl_SetSpInfo_AA                          (const MCDRV_SP_INFO* psSpInfo);
++static void                           McResCtrl_GetSpInfo_AA                          (MCDRV_SP_INFO* psSpInfo);
++static void                           McResCtrl_SetDngInfo_AA                         (const MCDRV_DNG_INFO* psDngInfo, UINT32 dUpdateInfo);
++static void                           McResCtrl_GetDngInfo_AA                         (MCDRV_DNG_INFO* psDngInfo);
++static void                           McResCtrl_SetAeInfo_AA                          (const MCDRV_AE_INFO* psAeInfo, UINT32 dUpdateInfo);
++static void                           McResCtrl_GetAeInfo_AA                          (MCDRV_AE_INFO* psAeInfo);
++static void                           McResCtrl_SetPdmInfo_AA                         (const MCDRV_PDM_INFO* psPdmInfo, UINT32 dUpdateInfo);
++static void                           McResCtrl_GetPdmInfo_AA                         (MCDRV_PDM_INFO* psPdmInfo);
++static void                           McResCtrl_SetGPMode_AA                          (const MCDRV_GP_MODE* psGpMode);
++static void                           McResCtrl_GetGPMode_AA                          (MCDRV_GP_MODE* psGpMode);
++static void                           McResCtrl_SetGPMask_AA                          (UINT8 bMask, UINT32 dPadNo);
++static void                           McResCtrl_GetGPMask_AA                          (UINT8* pabMask);
++
++static void                           McResCtrl_GetVolReg_AA                          (MCDRV_VOL_INFO* psVolInfo);
++static void                           McResCtrl_GetPowerInfo_AA                       (MCDRV_POWER_INFO_AA* psPowerInfo);
++static void                           McResCtrl_GetPowerInfoRegAccess_AA      (const MCDRV_REG_INFO* psRegInfo, MCDRV_POWER_INFO_AA* psPowerInfo);
++static void                           McResCtrl_GetCurPowerInfo_AA            (MCDRV_POWER_INFO_AA* psPowerInfo);
++
++static MCDRV_SRC_TYPE_AA      McResCtrl_GetDACSource_AA               (MCDRV_DAC_CH_AA eCh);
++static MCDRV_SRC_TYPE_AA      McResCtrl_GetDITSource_AA               (MCDRV_DIO_PORT_NO_AA ePort);
++static MCDRV_SRC_TYPE_AA      McResCtrl_GetAESource_AA                (void);
++static UINT8                          McResCtrl_IsSrcUsed_AA                  (MCDRV_SRC_TYPE_AA ePathSrc);
++static UINT8                          McResCtrl_IsDstUsed_AA                  (MCDRV_DST_TYPE_AA eType, MCDRV_DST_CH eCh);
++static MCDRV_REG_ACCSESS_AA   McResCtrl_GetRegAccess_AA               (const MCDRV_REG_INFO* psRegInfo);
++
++static MCDRV_PMODE_AA         McResCtrl_GetAPMode_AA                  (void);
++
++
++
++static MCDRV_HWADJ            McResCtrl_ConfigHwAdj_AA                        (void);
++
++/*************************************/
++
++/* HW_ID */
++#define       MCDRV_HWID_YMU821_AA    (0x78)
++
++/* wait time */
++#define       MCDRV_INTERVAL_MUTE_AA  (1000)
++#define       MCDRV_TIME_OUT_MUTE_AA  (1000)
++
++
++static MCDRV_STATE_AA geState = eMCDRV_STATE_NOTINIT_AA;
++
++static MCDRV_GLOBAL_INFO_AA   gsGlobalInfo_AA;
++static MCDRV_PACKET_AA                gasPacket[MCDRV_MAX_PACKETS_AA+1];
++
++/* register next address */
++static const UINT16   gawNextAddressA[MCDRV_A_REG_NUM_AA] =
++{
++      0,              1,              2,              0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 8,              0xFFFF, 0xFFFF, 0xFFFF, 12,             13,             14,             15,
++      16,             17,             18,             19,             20,             21,             22,             23,             0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
++      0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
++      0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF
++};
++
++static const UINT16   gawNextAddressB_BASE[MCDRV_B_BASE_REG_NUM_AA] =
++{
++      1,              2,              3,              4,              5,              6,              7,              0xFFFF, 9,              10,             11,             12,             13,             14,             15,             16,
++      17,             18,             19,             20,             0xFFFF, 22,             23,             24,             25,             26,             27,             28,             29,             30,             31,             0xFFFF
++};
++
++static const UINT16   gawNextAddressB_MIXER[MCDRV_B_MIXER_REG_NUM_AA] =
++{
++      1,              2,              3,              4,              5,              6,              7,              8,              9,              10,             11,             12,             13,             14,             15,             16,
++      17,             18,             19,             20,             21,             22,             23,             24,             25,             26,             27,             28,             29,             30,             31,             32,
++      33,             34,             35,             36,             37,             38,             39,             40,             41,             42,             43,             44,             45,             46,             47,             48,
++      49,             50,             51,             52,             53,             54,             55,             56,             57,             58,             59,             60,             61,             62,             63,             64,
++      65,             66,             67,             68,             69,             70,             71,             72,             73,             74,             75,             76,             77,             78,             79,             80,
++      81,             82,             83,             84,             85,             86,             87,             88,             89,             90,             91,             92,             93,             94,             95,             96,
++      97,             98,             99,             100,    101,    102,    103,    104,    105,    106,    107,    108,    109,    110,    111,    112,
++      113,    114,    115,    116,    117,    118,    119,    120,    121,    122,    123,    124,    125,    126,    127,    128,
++      129,    130,    131,    132,    133,    134,    135,    136,    137,    138,    139,    140,    141,    142,    143,    144,
++      145,    146,    147,    148,    149,    150,    151,    152,    153,    154,    155,    156,    157,    158,    159,    160,
++      161,    162,    163,    164,    165,    166,    167,    168,    169,    170,    171,    172,    173,    174,    175,    176,
++      177,    178,    179,    180,    181,    182,    183,    184,    185,    186,    187,    188,    189,    190,    191,    192,
++      193,    194,    195,    196,    197,    198,    199,    200,    201,    202,    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
++      0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF
++};
++
++static const UINT16   gawNextAddressB_AE[MCDRV_B_AE_REG_NUM_AA] =
++{
++      1,              2,              3,              4,              5,              6,              7,              8,              9,              10,             11,             12,             13,             14,             15,             16,
++      17,             18,             19,             20,             21,             22,             23,             24,             25,             26,             27,             28,             29,             30,             31,             32,
++      33,             34,             35,             36,             37,             38,             39,             40,             41,             42,             43,             44,             45,             46,             47,             48,
++      49,             50,             51,             52,             53,             54,             55,             56,             57,             58,             59,             60,             61,             62,             63,             64,
++      65,             66,             67,             68,             69,             70,             71,             72,             73,             74,             75,             76,             77,             78,             79,             80,
++      81,             82,             83,             84,             85,             86,             87,             88,             89,             90,             91,             92,             93,             94,             95,             96,
++      97,             98,             99,             100,    101,    102,    103,    104,    105,    106,    107,    108,    109,    110,    111,    112,
++      113,    114,    115,    116,    117,    118,    119,    120,    121,    122,    123,    124,    125,    126,    127,    128,
++      129,    130,    131,    132,    133,    134,    135,    136,    137,    138,    139,    140,    141,    142,    143,    144,
++      145,    146,    147,    148,    149,    150,    151,    152,    153,    154,    155,    156,    157,    158,    159,    160,
++      161,    162,    163,    164,    165,    166,    167,    168,    169,    170,    171,    172,    173,    174,    175,    176,
++      177,    178,    179,    180,    181,    182,    183,    184,    185,    186,    187,    188,    189,    190,    191,    192,
++      193,    194,    195,    196,    197,    198,    199,    200,    201,    202,    203,    204,    205,    206,    207,    208,
++      209,    210,    211,    212,    213,    214,    215,    216,    217,    218,    219,    220,    221,    222,    223,    224,
++      225,    226,    227,    228,    229,    230,    231,    232,    233,    234,    235,    236,    237,    238,    239,    240,
++      241,    242,    243,    244,    245,    246,    247,    248,    249,    250,    251,    252,    253,    254,    0xFFFF
++};
++
++static const UINT16   gawNextAddressB_CDSP[MCDRV_B_CDSP_REG_NUM_AA] =
++{
++      1,              2,              3,              4,              5,              6,              7,              8,              9,              10,             11,             12,             13,             14,             15,             16,
++      17,             18,             19,             20,             21,             22,             23,             24,             25,             26,             27,             28,             29,             30,             31,             32,
++      33,             34,             35,             36,             37,             38,             39,             40,             41,             42,             43,             44,             45,             46,             47,             48,
++      49,             50,             51,             52,             53,             54,             55,             56,             57,             58,             59,             60,             61,             62,             63,             64,
++      65,             66,             67,             68,             69,             70,             71,             72,             73,             74,             75,             76,             77,             78,             79,             80,
++      81,             82,             83,             84,             85,             86,             87,             88,             89,             90,             91,             92,             93,             94,             95,             96,
++      97,             98,             99,             100,    101,    102,    103,    104,    105,    106,    107,    108,    109,    110,    111,    112,
++      113,    114,    115,    116,    117,    118,    119,    120,    121,    122,    123,    124,    125,    126,    127,    128,
++      129,    0xFFFF
++};
++
++static const UINT16   gawNextAddressB_CODEC[MCDRV_B_CODEC_REG_NUM_AA] =
++{
++      1,              2,              3,              4,              5,              6,              7,              8,              9,              10,             11,             12,             13,             14,             15,             16,
++      17,             18,             19,             20,             21,             22,             23,             24,             25,             26,             27,             28,             29,             30,             31,             32,
++      33,             34,             35,             36,             37,             38,             39,             40,             41,             42,             43,             44,             45,             46,             47,             48,
++      49,             50,             51,             52,             53,             54,             55,             56,             57,             58,             59,             60,             61,             62,             63,             64,
++      65,             66,             67,             68,             69,             70,             71,             72,             73,             74,             75,             76,             77,             78,             79,             80,
++      81,             82,             83,             84,             85,             86,             87,             88,             89,             90,             91,             92,             93,             94,             95,             96,
++      97,             98,             99,             100,    101,    102,    103,    104,    105,    106,    107,    108,    109,    110,    111,    112,
++      113,    114,    115,    116,    117,    118,    119,    120,    121,    122,    123,    124,    125,    126,    127,    0xFFFF
++};
++
++static const UINT16   gawNextAddressB_Ana[MCDRV_B_ANA_REG_NUM_AA] =
++{
++      1,              2,              3,              4,              5,              6,              7,              8,              9,              10,             11,             12,             13,             14,             15,             16,
++      17,             18,             19,             20,             21,             22,             23,             24,             25,             26,             27,             28,             29,             30,             31,             32,
++      33,             34,             35,             36,             37,             38,             39,             40,             41,             42,             43,             44,             45,             46,             47,             48,
++      49,             50,             51,             52,             53,             54,             55,             56,             57,             58,             59,             60,             61,             62,             63,             64,
++      65,             66,             67,             68,             69,             70,             71,             72,             73,             74,             75,             76,             77,             0xFFFF, 79,             80,
++      81,             82,             83,             84,             85,             86,             87,             88,             89,             90,             91,             92,             93,             94,             95,             96,
++      97,             98,             99,             100,    101,    102,    103,    104,    105,    106,    107,    108,    109,    110,    111,    112,
++      113,    114,    115,    116,    117,    118,    119,    120,    121,    122,    123,    124,    125,    126,    127,    0xFFFF
++};
++
++/*    register access available       */
++static const MCDRV_REG_ACCSESS_AA     gawRegAccessAvailableA[256] =
++{
++      eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_READ_ONLY_AA,    eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,
++      eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++};
++static const MCDRV_REG_ACCSESS_AA     gawRegAccessAvailableB_BASE[256] =
++{
++      eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,
++      eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++};
++static const MCDRV_REG_ACCSESS_AA     gawRegAccessAvailableB_ANA[256] =
++{
++      eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_ONLY_AA,    eMCDRV_READ_ONLY_AA,    eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,
++      eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,
++      eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_ONLY_AA,
++      eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,
++      eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,
++      eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_ONLY_AA,    eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_ONLY_AA,    eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++};
++static const MCDRV_REG_ACCSESS_AA     gawRegAccessAvailableB_CODEC[256] =
++{
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_READ_ONLY_AA,    eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,
++      eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++};
++static const MCDRV_REG_ACCSESS_AA     gawRegAccessAvailableB_MIX[256] =
++{
++      eMCDRV_READ_ONLY_AA,    eMCDRV_READ_ONLY_AA,    eMCDRV_READ_ONLY_AA,    eMCDRV_READ_ONLY_AA,    eMCDRV_READ_ONLY_AA,    eMCDRV_READ_ONLY_AA,    eMCDRV_READ_ONLY_AA,    eMCDRV_READ_ONLY_AA,
++      eMCDRV_READ_ONLY_AA,    eMCDRV_READ_ONLY_AA,    eMCDRV_READ_ONLY_AA,    eMCDRV_READ_ONLY_AA,    eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,
++      eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,
++      eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,
++      eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,
++      eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,
++      eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,
++      eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,
++      eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,
++      eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,
++      eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,
++      eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,
++      eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,
++      eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_READ_WRITE_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++};
++static const MCDRV_REG_ACCSESS_AA     gawRegAccessAvailableB_AE[256] =
++{
++      eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,
++      eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,
++      eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,
++      eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,
++      eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,
++      eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,
++      eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,
++      eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,
++      eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,
++      eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,
++      eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,
++      eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,
++      eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,
++      eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,
++      eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,
++      eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,
++      eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,
++      eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,
++      eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,
++      eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,
++      eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,
++      eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,
++      eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_WRITE_ONLY_AA,   eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++      eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,  eMCDRV_ACCESS_DENY_AA,
++};
++
++
++static void           SetRegDefault(void);
++static void           InitPathInfo(void);
++static void           InitVolInfo(void);
++static void           InitDioInfo(void);
++static void           InitDacInfo(void);
++static void           InitAdcInfo(void);
++static void           InitSpInfo(void);
++static void           InitDngInfo(void);
++static void           InitAeInfo(void);
++static void           InitPdmInfo(void);
++static void           InitGpMode(void);
++static void           InitGpMask(void);
++
++static void           SetHPSourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetSPSourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetRCVSourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetLO1SourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetLO2SourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetPMSourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetDIT0SourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetDIT1SourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetDIT2SourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetDACSourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetAESourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetCDSPSourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetADC0SourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetADC1SourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetMixSourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetBiasSourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++
++static void           SetDIOCommon(const MCDRV_DIO_INFO* psDioInfo, UINT8 bPort);
++static void           SetDIODIR(const MCDRV_DIO_INFO* psDioInfo, UINT8 bPort);
++static void           SetDIODIT(const MCDRV_DIO_INFO* psDioInfo, UINT8 bPort);
++
++static SINT16 GetDigitalVolReg(SINT16 swVol);
++static SINT16 GetADVolReg(SINT16 swVol);
++static SINT16 GetLIVolReg(SINT16 swVol);
++static SINT16 GetMcVolReg(SINT16 swVol);
++static SINT16 GetMcGainReg(SINT16 swVol);
++static SINT16 GetHpVolReg(SINT16 swVol);
++static SINT16 GetHpGainReg(SINT16 swVol);
++static SINT16 GetSpVolReg(SINT16 swVol);
++static SINT16 GetRcVolReg(SINT16 swVol);
++static SINT16 GetLoVolReg(SINT16 swVol);
++
++static SINT32 WaitBitSet(UINT8 bSlaveAddr, UINT16 wRegAddr, UINT8 bBit, UINT32 dCycleTime, UINT32 dTimeOut);
++static SINT32 WaitBitRelease(UINT8 bSlaveAddr, UINT16 wRegAddr, UINT8 bBit, UINT32 dCycleTime, UINT32 dTimeOut);
++
++/****************************************************************************
++ *    McResCtrl_SetHwId_AA
++ *
++ *    Description:
++ *                    Set hardware ID.
++ *    Arguments:
++ *                    bHwId   hardware ID
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_INIT
++ *
++ ****************************************************************************/
++SINT32        McResCtrl_SetHwId_AA
++(
++      UINT8   bHwId
++)
++{
++      gsGlobalInfo_AA.bHwId   = bHwId;
++
++      switch (bHwId)
++      {
++      case MCDRV_HWID_YMU821_AA:
++              McDevProf_SetDevId(eMCDRV_DEV_ID_1N2);
++              break;
++      default:
++              return MCDRV_ERROR_INIT;
++      }
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    McResCtrl_Init_AA
++ *
++ *    Description:
++ *                    initialize the resource controller.
++ *    Arguments:
++ *                    psInitInfo      pointer to the initialize information struct
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_Init_AA
++(
++      const MCDRV_INIT_INFO*  psInitInfo
++)
++{
++      gsGlobalInfo_AA.ePacketBufAlloc = eMCDRV_PACKETBUF_FREE_AA;
++      SetRegDefault();
++
++      gsGlobalInfo_AA.sInitInfo.bCkSel        = psInitInfo->bCkSel;
++      gsGlobalInfo_AA.sInitInfo.bDivR0        = psInitInfo->bDivR0;
++      gsGlobalInfo_AA.sInitInfo.bDivF0        = psInitInfo->bDivF0;
++      if(McDevProf_IsValid(eMCDRV_FUNC_DIVR1) == 1)
++      {
++              gsGlobalInfo_AA.sInitInfo.bDivR1        = psInitInfo->bDivR1;
++      }
++      else
++      {
++              gsGlobalInfo_AA.sInitInfo.bDivR1        = 0;
++      }
++      if(McDevProf_IsValid(eMCDRV_FUNC_DIVF1) == 1)
++      {
++              gsGlobalInfo_AA.sInitInfo.bDivF1        = psInitInfo->bDivF1;
++      }
++      else
++      {
++              gsGlobalInfo_AA.sInitInfo.bDivF1        = 0;
++      }
++      if(McDevProf_IsValid(eMCDRV_FUNC_RANGE) == 1)
++      {
++              gsGlobalInfo_AA.sInitInfo.bRange0       = psInitInfo->bRange0;
++              gsGlobalInfo_AA.sInitInfo.bRange1       = psInitInfo->bRange1;
++      }
++      else
++      {
++              gsGlobalInfo_AA.sInitInfo.bRange0       = 0;
++              gsGlobalInfo_AA.sInitInfo.bRange1       = 0;
++      }
++      if(McDevProf_IsValid(eMCDRV_FUNC_BYPASS) == 1)
++      {
++              gsGlobalInfo_AA.sInitInfo.bBypass       = psInitInfo->bBypass;
++      }
++      else
++      {
++              gsGlobalInfo_AA.sInitInfo.bBypass       = 0;
++      }
++      gsGlobalInfo_AA.sInitInfo.bDioSdo0Hiz   = psInitInfo->bDioSdo0Hiz;
++      gsGlobalInfo_AA.sInitInfo.bDioSdo1Hiz   = psInitInfo->bDioSdo1Hiz;
++      gsGlobalInfo_AA.sInitInfo.bDioSdo2Hiz   = psInitInfo->bDioSdo2Hiz;
++      gsGlobalInfo_AA.sInitInfo.bDioClk0Hiz   = psInitInfo->bDioClk0Hiz;
++      gsGlobalInfo_AA.sInitInfo.bDioClk1Hiz   = psInitInfo->bDioClk1Hiz;
++      gsGlobalInfo_AA.sInitInfo.bDioClk2Hiz   = psInitInfo->bDioClk2Hiz;
++      gsGlobalInfo_AA.sInitInfo.bPcmHiz               = psInitInfo->bPcmHiz;
++      gsGlobalInfo_AA.sInitInfo.bLineIn1Dif   = psInitInfo->bLineIn1Dif;
++      if(McDevProf_IsValid(eMCDRV_FUNC_LI2) == 1)
++      {
++              gsGlobalInfo_AA.sInitInfo.bLineIn2Dif   = psInitInfo->bLineIn2Dif;
++      }
++      else
++      {
++              gsGlobalInfo_AA.sInitInfo.bLineIn2Dif   = MCDRV_LINE_STEREO;
++      }
++      gsGlobalInfo_AA.sInitInfo.bLineOut1Dif  = psInitInfo->bLineOut1Dif;
++      gsGlobalInfo_AA.sInitInfo.bLineOut2Dif  = psInitInfo->bLineOut2Dif;
++      gsGlobalInfo_AA.sInitInfo.bSpmn         = psInitInfo->bSpmn;
++      gsGlobalInfo_AA.sInitInfo.bMic1Sng              = psInitInfo->bMic1Sng;
++      gsGlobalInfo_AA.sInitInfo.bMic2Sng              = psInitInfo->bMic2Sng;
++      gsGlobalInfo_AA.sInitInfo.bMic3Sng              = psInitInfo->bMic3Sng;
++      gsGlobalInfo_AA.sInitInfo.bPowerMode    = psInitInfo->bPowerMode;
++      gsGlobalInfo_AA.sInitInfo.bSpHiz                = psInitInfo->bSpHiz;
++      gsGlobalInfo_AA.sInitInfo.bLdo                  = psInitInfo->bLdo;
++      gsGlobalInfo_AA.sInitInfo.bPad0Func     = psInitInfo->bPad0Func;
++      gsGlobalInfo_AA.sInitInfo.bPad1Func     = psInitInfo->bPad1Func;
++      if(McDevProf_IsValid(eMCDRV_FUNC_PAD2) == 1)
++      {
++              gsGlobalInfo_AA.sInitInfo.bPad2Func     = psInitInfo->bPad2Func;
++      }
++      else
++      {
++              gsGlobalInfo_AA.sInitInfo.bPad2Func     = MCDRV_PAD_GPIO;
++      }
++      gsGlobalInfo_AA.sInitInfo.bAvddLev              = psInitInfo->bAvddLev;
++      gsGlobalInfo_AA.sInitInfo.bVrefLev              = psInitInfo->bVrefLev;
++      gsGlobalInfo_AA.sInitInfo.bDclGain              = psInitInfo->bDclGain;
++      gsGlobalInfo_AA.sInitInfo.bDclLimit     = psInitInfo->bDclLimit;
++      gsGlobalInfo_AA.sInitInfo.bReserved1    = psInitInfo->bReserved1;
++      gsGlobalInfo_AA.sInitInfo.bReserved2    = psInitInfo->bReserved2;
++      gsGlobalInfo_AA.sInitInfo.bReserved3    = psInitInfo->bReserved3;
++      gsGlobalInfo_AA.sInitInfo.bReserved4    = psInitInfo->bReserved4;
++      gsGlobalInfo_AA.sInitInfo.bReserved5    = psInitInfo->bReserved5;
++      gsGlobalInfo_AA.sInitInfo.sWaitTime     = psInitInfo->sWaitTime;
++
++      InitPathInfo();
++      InitVolInfo();
++      InitDioInfo();
++      InitDacInfo();
++      InitAdcInfo();
++      InitSpInfo();
++      InitDngInfo();
++      InitAeInfo();
++      InitPdmInfo();
++      InitGpMode();
++      InitGpMask();
++
++      McResCtrl_InitRegUpdate_AA();
++
++      gsGlobalInfo_AA.eAPMode = eMCDRV_APM_OFF_AA;
++
++      gsGlobalInfo_AA.eHwAdj = eMCDRV_HWADJ_THRU;
++}
++
++/****************************************************************************
++ *    SetRegDefault
++ *
++ *    Description:
++ *                    Initialize the virtual registers.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetRegDefault
++(
++      void
++)
++{
++      UINT16  i;
++      for(i = 0; i < MCDRV_A_REG_NUM_AA; i++)
++      {
++              gsGlobalInfo_AA.abRegValA[i]    = 0;
++      }
++      gsGlobalInfo_AA.abRegValA[MCI_AA_RST]           = MCI_AA_RST_DEF;
++      gsGlobalInfo_AA.abRegValA[MCI_AA_HW_ID] = MCI_AA_HW_ID_DEF;
++
++      for(i = 0; i < MCDRV_B_BASE_REG_NUM_AA; i++)
++      {
++              gsGlobalInfo_AA.abRegValB_BASE[i]       = 0;
++      }
++      gsGlobalInfo_AA.abRegValB_BASE[MCI_AA_RSTB]                             = MCI_AA_RSTB_DEF;
++      gsGlobalInfo_AA.abRegValB_BASE[MCI_AA_PWM_DIGITAL]              = MCI_AA_PWM_DIGITAL_DEF;
++      gsGlobalInfo_AA.abRegValB_BASE[MCI_AA_PWM_DIGITAL_1]            = MCI_AA_PWM_DIGITAL_1_DEF;
++      gsGlobalInfo_AA.abRegValB_BASE[MCI_AA_PWM_DIGITAL_CDSP] = MCI_AA_PWM_DIGITAL_CDSP_DEF;
++      gsGlobalInfo_AA.abRegValB_BASE[MCI_AA_PWM_DIGITAL_BDSP] = MCI_AA_PWM_DIGITAL_BDSP_DEF;
++      gsGlobalInfo_AA.abRegValB_BASE[MCI_AA_SD_MSK]                           = MCI_AA_SD_MSK_DEF;
++      gsGlobalInfo_AA.abRegValB_BASE[MCI_AA_SD_MSK_1]                 = MCI_AA_SD_MSK_1_DEF;
++      gsGlobalInfo_AA.abRegValB_BASE[MCI_AA_BCLK_MSK]                 = MCI_AA_BCLK_MSK_DEF;
++      gsGlobalInfo_AA.abRegValB_BASE[MCI_AA_BCLK_MSK_1]                       = MCI_AA_BCLK_MSK_1_DEF;
++      gsGlobalInfo_AA.abRegValB_BASE[MCI_AA_BCKP]                             = MCI_AA_BCKP_DEF;
++      gsGlobalInfo_AA.abRegValB_BASE[MCI_AA_PLL_RST]                          = MCI_AA_PLL_RST_DEF;
++      gsGlobalInfo_AA.abRegValB_BASE[MCI_AA_DIVR0]                            = MCI_AA_DIVR0_DEF;
++      gsGlobalInfo_AA.abRegValB_BASE[MCI_AA_DIVF0]                            = MCI_AA_DIVF0_DEF;
++      gsGlobalInfo_AA.abRegValB_BASE[MCI_AA_PA_MSK]                           = MCI_AA_PA_MSK_DEF;
++      gsGlobalInfo_AA.abRegValB_BASE[MCI_AA_PA_MSK_1]                 = MCI_AA_PA_MSK_1_DEF;
++
++      for(i = 0; i < MCDRV_B_MIXER_REG_NUM_AA; i++)
++      {
++              gsGlobalInfo_AA.abRegValB_MIXER[i]      = 0;
++      }
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_DIT_ININTP]      = MCI_AA_DIT_ININTP_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_DIR_INTP]                = MCI_AA_DIR_INTP_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_ADC_INTP]                = MCI_AA_ADC_INTP_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_AINTP]                   = MCI_AA_AINTP_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_IINTP]                   = MCI_AA_IINTP_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_DAC_INTP]                = MCI_AA_DAC_INTP_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_DIR0_CH]         = MCI_AA_DIR0_CH_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_DIT0_SLOT]               = MCI_AA_DIT0_SLOT_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_PCM_RX0]         = MCI_AA_PCM_RX0_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_PCM_TX0]         = MCI_AA_PCM_TX0_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_PCM_SLOT_TX0]    = MCI_AA_PCM_SLOT_TX0_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_DIR1_CH]         = MCI_AA_DIR1_CH_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_DIT1_SLOT]               = MCI_AA_DIT1_SLOT_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_PCM_RX1]         = MCI_AA_PCM_RX1_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_PCM_TX1]         = MCI_AA_PCM_TX1_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_PCM_SLOT_TX1]    = MCI_AA_PCM_SLOT_TX1_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_DIR2_CH]         = MCI_AA_DIR2_CH_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_DIT2_SLOT]               = MCI_AA_DIT2_SLOT_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_PCM_RX2]         = MCI_AA_PCM_RX2_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_PCM_TX2]         = MCI_AA_PCM_TX2_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_PCM_SLOT_TX2]    = MCI_AA_PCM_SLOT_TX2_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_CDI_CH]          = MCI_AA_CDI_CH_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_CDO_SLOT]                = MCI_AA_CDO_SLOT_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_PDM_AGC]         = MCI_AA_PDM_AGC_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_PDM_MUTE]                = MCI_AA_PDM_MUTE_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_PDM_STWAIT]      = MCI_AA_PDM_STWAIT_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_CHP_H]                   = MCI_AA_CHP_H_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_CHP_M]                   = MCI_AA_CHP_M_DEF;
++      gsGlobalInfo_AA.abRegValB_MIXER[MCI_AA_CHP_L]                   = MCI_AA_CHP_L_DEF;
++
++      for(i = 0; i < MCDRV_B_AE_REG_NUM_AA; i++)
++      {
++              gsGlobalInfo_AA.abRegValB_AE[i] = 0;
++      }
++      gsGlobalInfo_AA.abRegValB_AE[MCI_AA_BAND0_CEQ0] = MCI_AA_BAND0_CEQ0_H_DEF;
++      gsGlobalInfo_AA.abRegValB_AE[MCI_AA_BAND1_CEQ0] = MCI_AA_BAND1_CEQ0_H_DEF;
++      gsGlobalInfo_AA.abRegValB_AE[MCI_AA_BAND2_CEQ0] = MCI_AA_BAND2_CEQ0_H_DEF;
++      gsGlobalInfo_AA.abRegValB_AE[MCI_AA_BAND3H_CEQ0]        = MCI_AA_BAND3H_CEQ0_H_DEF;
++      gsGlobalInfo_AA.abRegValB_AE[MCI_AA_BAND4H_CEQ0]        = MCI_AA_BAND4H_CEQ0_H_DEF;
++      gsGlobalInfo_AA.abRegValB_AE[MCI_AA_BAND5_CEQ0] = MCI_AA_BAND5_CEQ0_H_DEF;
++      gsGlobalInfo_AA.abRegValB_AE[MCI_AA_BAND6H_CEQ0]        = MCI_AA_BAND6H_CEQ0_H_DEF;
++      gsGlobalInfo_AA.abRegValB_AE[MCI_AA_BAND7H_CEQ0]        = MCI_AA_BAND7H_CEQ0_H_DEF;
++      gsGlobalInfo_AA.abRegValB_AE[MCI_AA_PDM_CHP0_H] = MCI_AA_PDM_CHP0_H_DEF;
++      gsGlobalInfo_AA.abRegValB_AE[MCI_AA_PDM_CHP0_M] = MCI_AA_PDM_CHP0_M_DEF;
++      gsGlobalInfo_AA.abRegValB_AE[MCI_AA_PDM_CHP0_L] = MCI_AA_PDM_CHP0_L_DEF;
++      gsGlobalInfo_AA.abRegValB_AE[MCI_AA_PDM_CHP1_H] = MCI_AA_PDM_CHP1_H_DEF;
++      gsGlobalInfo_AA.abRegValB_AE[MCI_AA_PDM_CHP1_M] = MCI_AA_PDM_CHP1_M_DEF;
++      gsGlobalInfo_AA.abRegValB_AE[MCI_AA_PDM_CHP1_L] = MCI_AA_PDM_CHP1_L_DEF;
++      gsGlobalInfo_AA.abRegValB_AE[MCI_AA_PDM_CHP3_H] = MCI_AA_PDM_CHP3_H_DEF;
++      gsGlobalInfo_AA.abRegValB_AE[MCI_AA_PDM_CHP3_M] = MCI_AA_PDM_CHP3_M_DEF;
++      gsGlobalInfo_AA.abRegValB_AE[MCI_AA_PDM_CHP3_L] = MCI_AA_PDM_CHP3_L_DEF;
++
++      for(i = 0; i < MCDRV_B_CDSP_REG_NUM_AA; i++)
++      {
++              gsGlobalInfo_AA.abRegValB_CDSP[i]       = 0;
++      }
++      gsGlobalInfo_AA.abRegValB_CDSP[MCI_AA_JOEMP]            = MCI_AA_JOEMP_DEF;
++      gsGlobalInfo_AA.abRegValB_CDSP[MCI_AA_JEEMP]            = MCI_AA_JEEMP_DEF;
++      gsGlobalInfo_AA.abRegValB_CDSP[MCI_AA_CDSP_SRST]        = MCI_AA_CDSP_SRST_DEF;
++
++      for(i = 0; i < MCDRV_B_ANA_REG_NUM_AA; i++)
++      {
++              gsGlobalInfo_AA.abRegValB_ANA[i]        = 0;
++      }
++      gsGlobalInfo_AA.abRegValB_ANA[MCI_AA_ANA_RST]                   = MCI_AA_ANA_RST_DEF;
++      gsGlobalInfo_AA.abRegValB_ANA[MCI_AA_PWM_ANALOG_0]      = MCI_AA_PWM_ANALOG_0_DEF;
++      gsGlobalInfo_AA.abRegValB_ANA[MCI_AA_PWM_ANALOG_1]      = MCI_AA_PWM_ANALOG_1_DEF;
++      gsGlobalInfo_AA.abRegValB_ANA[MCI_AA_PWM_ANALOG_2]      = MCI_AA_PWM_ANALOG_2_DEF;
++      gsGlobalInfo_AA.abRegValB_ANA[MCI_AA_PWM_ANALOG_3]      = MCI_AA_PWM_ANALOG_3_DEF;
++      gsGlobalInfo_AA.abRegValB_ANA[MCI_AA_PWM_ANALOG_4]      = MCI_AA_PWM_ANALOG_4_DEF;
++      gsGlobalInfo_AA.abRegValB_ANA[MCI_AA_DNGATRT]                   = MCI_AA_DNGATRT_DEF;
++      gsGlobalInfo_AA.abRegValB_ANA[MCI_AA_DNGON]                     = MCI_AA_DNGON_DEF;
++      gsGlobalInfo_AA.abRegValB_ANA[MCI_AA_HPVOL_L]                   = MCI_AA_HPVOL_L_DEF;
++      gsGlobalInfo_AA.abRegValB_ANA[MCI_AA_SPVOL_L]                   = MCI_AA_SPVOL_L_DEF;
++      gsGlobalInfo_AA.abRegValB_ANA[MCI_AA_RCVOL]                     = MCI_AA_RCVOL_DEF;
++      gsGlobalInfo_AA.abRegValB_ANA[MCI_AA_LEV]                               = MCI_AA_LEV_DEF;
++
++      for(i = 0; i < MCDRV_B_CODEC_REG_NUM_AA; i++)
++      {
++              gsGlobalInfo_AA.abRegValB_CODEC[i]      = 0;
++      }
++      gsGlobalInfo_AA.abRegValB_CODEC[MCI_AA_DPADIF]          = MCI_AA_DPADIF_DEF;
++      gsGlobalInfo_AA.abRegValB_CODEC[MCI_AA_AD_AGC]          = MCI_AA_AD_AGC_DEF;
++      gsGlobalInfo_AA.abRegValB_CODEC[MCI_AA_DAC_CONFIG]      = MCI_AA_DAC_CONFIG_DEF;
++}
++
++/****************************************************************************
++ *    InitPathInfo
++ *
++ *    Description:
++ *                    Initialize path info.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   InitPathInfo
++(
++      void
++)
++{
++      UINT8   bCh, bBlockIdx;
++      UINT8   abOnOff[SOURCE_BLOCK_NUM];
++
++      abOnOff[0]      = (MCDRV_SRC0_MIC1_OFF|MCDRV_SRC0_MIC2_OFF|MCDRV_SRC0_MIC3_OFF);
++      abOnOff[1]      = (MCDRV_SRC1_LINE1_L_OFF|MCDRV_SRC1_LINE1_R_OFF|MCDRV_SRC1_LINE1_M_OFF);
++      abOnOff[2]      = (MCDRV_SRC2_LINE2_L_OFF|MCDRV_SRC2_LINE2_R_OFF|MCDRV_SRC2_LINE2_M_OFF);
++      abOnOff[3]      = (MCDRV_SRC3_DIR0_OFF|MCDRV_SRC3_DIR1_OFF|MCDRV_SRC3_DIR2_OFF|MCDRV_SRC3_DIR2_DIRECT_OFF);
++      abOnOff[4]      = (MCDRV_SRC4_DTMF_OFF|MCDRV_SRC4_PDM_OFF|MCDRV_SRC4_ADC0_OFF|MCDRV_SRC4_ADC1_OFF);
++      abOnOff[5]      = (MCDRV_SRC5_DAC_L_OFF|MCDRV_SRC5_DAC_R_OFF|MCDRV_SRC5_DAC_M_OFF);
++      abOnOff[6]      = (MCDRV_SRC6_MIX_OFF|MCDRV_SRC6_AE_OFF|MCDRV_SRC6_CDSP_OFF|MCDRV_SRC6_CDSP_DIRECT_OFF);
++
++      for(bCh = 0; bCh < HP_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asHpOut[bCh].abSrcOnOff[bBlockIdx]    = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < SP_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asSpOut[bCh].abSrcOnOff[bBlockIdx]    = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < RC_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asRcOut[bCh].abSrcOnOff[bBlockIdx]    = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < LOUT1_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asLout1[bCh].abSrcOnOff[bBlockIdx]    = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < LOUT2_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asLout2[bCh].abSrcOnOff[bBlockIdx]    = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < PEAK_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asPeak[bCh].abSrcOnOff[bBlockIdx]     = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < DIT0_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asDit0[bCh].abSrcOnOff[bBlockIdx]     = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < DIT1_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asDit1[bCh].abSrcOnOff[bBlockIdx]     = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < DIT2_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asDit2[bCh].abSrcOnOff[bBlockIdx]     = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < DAC_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[bBlockIdx]      = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < AE_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asAe[bCh].abSrcOnOff[bBlockIdx]       = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < CDSP_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asCdsp[bCh].abSrcOnOff[bBlockIdx]     = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < ADC0_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asAdc0[bCh].abSrcOnOff[bBlockIdx]     = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < ADC1_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asAdc1[bCh].abSrcOnOff[bBlockIdx]     = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < MIX_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asMix[bCh].abSrcOnOff[bBlockIdx]      = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < BIAS_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asBias[bCh].abSrcOnOff[bBlockIdx]     = abOnOff[bBlockIdx];
++              }
++      }
++      gsGlobalInfo_AA.sPathInfoVirtual        = gsGlobalInfo_AA.sPathInfo;
++}
++
++/****************************************************************************
++ *    InitVolInfo
++ *
++ *    Description:
++ *                    Initialize volume info.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   InitVolInfo
++(
++      void
++)
++{
++      UINT8   bCh;
++      for(bCh = 0; bCh < AD0_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswD_Ad0[bCh]                  = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < AD1_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswD_Ad1[bCh]                  = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < AENG6_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswD_Aeng6[bCh]                = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < PDM_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswD_Pdm[bCh]                  = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DTMF_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswD_Dtmfb[bCh]                = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DIO0_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswD_Dir0[bCh]         = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DIO1_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswD_Dir1[bCh]         = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DIO2_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswD_Dir2[bCh]         = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < AD0_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswD_Ad0Att[bCh]               = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < AD1_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswD_Ad1Att[bCh]               = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DIO0_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswD_Dir0Att[bCh]              = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DIO1_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswD_Dir1Att[bCh]              = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DIO2_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswD_Dir2Att[bCh]              = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < PDM_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswD_SideTone[bCh]     = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DTFM_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswD_DtmfAtt[bCh]              = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DAC_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswD_DacMaster[bCh]    = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DAC_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswD_DacVoice[bCh]     = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DAC_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswD_DacAtt[bCh]               = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DIO0_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswD_Dit0[bCh]         = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DIO1_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswD_Dit1[bCh]         = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DIO2_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswD_Dit2[bCh]         = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < AD0_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswA_Ad0[bCh]                  = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < AD1_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswA_Ad1[bCh]                  = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < LIN1_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswA_Lin1[bCh]         = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < LIN2_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswA_Lin2[bCh]         = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < MIC1_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswA_Mic1[bCh]         = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < MIC2_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswA_Mic2[bCh]         = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < MIC3_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswA_Mic3[bCh]         = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < HP_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswA_Hp[bCh]                   = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < SP_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswA_Sp[bCh]                   = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < RC_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswA_Rc[bCh]                   = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < LOUT1_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswA_Lout1[bCh]                = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < LOUT2_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswA_Lout2[bCh]                = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < MIC1_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswA_Mic1Gain[bCh]     = MCDRV_LOGICAL_MICGAIN_DEF;
++      }
++      for(bCh = 0; bCh < MIC2_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswA_Mic2Gain[bCh]     = MCDRV_LOGICAL_MICGAIN_DEF;
++      }
++      for(bCh = 0; bCh < MIC3_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswA_Mic3Gain[bCh]     = MCDRV_LOGICAL_MICGAIN_DEF;
++      }
++      for(bCh = 0; bCh < HPGAIN_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo_AA.sVolInfo.aswA_HpGain[bCh]               = MCDRV_LOGICAL_HPGAIN_DEF;
++      }
++}
++
++/****************************************************************************
++ *    InitDioInfo
++ *
++ *    Description:
++ *                    Initialize Digital I/O info.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   InitDioInfo
++(
++      void
++)
++{
++      UINT8   bDioIdx, bDioCh;
++      for(bDioIdx = 0; bDioIdx < 3; bDioIdx++)
++      {
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDioCommon.bMasterSlave    = MCDRV_DIO_SLAVE;
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDioCommon.bAutoFs         = MCDRV_AUTOFS_ON;
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDioCommon.bFs                     = MCDRV_FS_48000;
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDioCommon.bBckFs                  = MCDRV_BCKFS_64;
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDioCommon.bInterface              = MCDRV_DIO_DA;
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDioCommon.bBckInvert              = MCDRV_BCLK_NORMAL;
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDioCommon.bPcmHizTim              = MCDRV_PCMHIZTIM_FALLING;
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDioCommon.bPcmClkDown     = MCDRV_PCM_CLKDOWN_OFF;
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDioCommon.bPcmFrame               = MCDRV_PCM_SHORTFRAME;
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDioCommon.bPcmHighPeriod  = 0;
++
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDir.wSrcRate                              = 0x0000;
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDir.sDaFormat.bBitSel     = MCDRV_BITSEL_16;
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDir.sDaFormat.bMode               = MCDRV_DAMODE_HEADALIGN;
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDir.sPcmFormat.bMono              = MCDRV_PCM_MONO;
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDir.sPcmFormat.bOrder     = MCDRV_PCM_MSB_FIRST;
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDir.sPcmFormat.bLaw               = MCDRV_PCM_LINEAR;
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDir.sPcmFormat.bBitSel    = MCDRV_PCM_BITSEL_8;
++              for(bDioCh = 0; bDioCh < DIO_CHANNELS; bDioCh++)
++              {
++                      gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDir.abSlot[bDioCh]        = bDioCh;
++              }
++
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDit.wSrcRate                              = 0x0000;
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDit.sDaFormat.bBitSel     = MCDRV_BITSEL_16;
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDit.sDaFormat.bMode               = MCDRV_DAMODE_HEADALIGN;
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDit.sPcmFormat.bMono              = MCDRV_PCM_MONO;
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDit.sPcmFormat.bOrder     = MCDRV_PCM_MSB_FIRST;
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDit.sPcmFormat.bLaw               = MCDRV_PCM_LINEAR;
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDit.sPcmFormat.bBitSel    = MCDRV_PCM_BITSEL_8;
++              for(bDioCh = 0; bDioCh < DIO_CHANNELS; bDioCh++)
++              {
++                      gsGlobalInfo_AA.sDioInfo.asPortInfo[bDioIdx].sDit.abSlot[bDioCh]        = bDioCh;
++              }
++      }
++}
++
++/****************************************************************************
++ *    InitDacInfo
++ *
++ *    Description:
++ *                    Initialize Dac info.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   InitDacInfo
++(
++      void
++)
++{
++      gsGlobalInfo_AA.sDacInfo.bMasterSwap    = MCDRV_DSWAP_OFF;
++      gsGlobalInfo_AA.sDacInfo.bVoiceSwap     = MCDRV_DSWAP_OFF;
++      gsGlobalInfo_AA.sDacInfo.bDcCut         = MCDRV_DCCUT_ON;
++}
++
++/****************************************************************************
++ *    InitAdcInfo
++ *
++ *    Description:
++ *                    Initialize Adc info.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   InitAdcInfo
++(
++      void
++)
++{
++      gsGlobalInfo_AA.sAdcInfo.bAgcAdjust     = MCDRV_AGCADJ_0;
++      gsGlobalInfo_AA.sAdcInfo.bAgcOn         = MCDRV_AGC_OFF;
++      gsGlobalInfo_AA.sAdcInfo.bMono                  = MCDRV_ADC_STEREO;
++}
++
++/****************************************************************************
++ *    InitSpInfo
++ *
++ *    Description:
++ *                    Initialize SP info.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   InitSpInfo
++(
++      void
++)
++{
++      gsGlobalInfo_AA.sSpInfo.bSwap   = MCDRV_SPSWAP_OFF;
++}
++
++/****************************************************************************
++ *    InitDngInfo
++ *
++ *    Description:
++ *                    Initialize DNG info.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   InitDngInfo
++(
++      void
++)
++{
++      gsGlobalInfo_AA.sDngInfo.abOnOff[0]             = MCDRV_DNG_OFF;
++      gsGlobalInfo_AA.sDngInfo.abThreshold[0] = MCDRV_DNG_THRES_48;
++      gsGlobalInfo_AA.sDngInfo.abHold[0]                      = MCDRV_DNG_HOLD_500;
++      gsGlobalInfo_AA.sDngInfo.abAttack[0]            = 2/*MCDRV_DNG_ATTACK_1100*/;
++      gsGlobalInfo_AA.sDngInfo.abRelease[0]           = MCDRV_DNG_RELEASE_940;
++}
++
++/****************************************************************************
++ *    InitAeInfo
++ *
++ *    Description:
++ *                    Initialize Audio Engine info.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   InitAeInfo
++(
++      void
++)
++{
++      if(McDevProf_IsValid(eMCDRV_FUNC_HWADJ) == 1)
++      {
++              gsGlobalInfo_AA.sAeInfo.bOnOff          = MCDRV_EQ3_ON;
++      }
++      else
++      {
++              gsGlobalInfo_AA.sAeInfo.bOnOff          = 0;
++      }
++}
++
++/****************************************************************************
++ *    InitPdmInfo
++ *
++ *    Description:
++ *                    Initialize Pdm info.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   InitPdmInfo
++(
++      void
++)
++{
++      gsGlobalInfo_AA.sPdmInfo.bClk                   = MCDRV_PDM_CLK_64;
++      gsGlobalInfo_AA.sPdmInfo.bAgcAdjust     = MCDRV_AGCADJ_0;
++      gsGlobalInfo_AA.sPdmInfo.bAgcOn         = MCDRV_AGC_OFF;
++      gsGlobalInfo_AA.sPdmInfo.bPdmEdge               = MCDRV_PDMEDGE_LH;
++      gsGlobalInfo_AA.sPdmInfo.bPdmWait               = MCDRV_PDMWAIT_10;
++      gsGlobalInfo_AA.sPdmInfo.bPdmSel                = MCDRV_PDMSEL_L1R2;
++      gsGlobalInfo_AA.sPdmInfo.bMono                  = MCDRV_PDM_STEREO;
++}
++
++/****************************************************************************
++ *    InitGpMode
++ *
++ *    Description:
++ *                    Initialize Gp mode.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   InitGpMode
++(
++      void
++)
++{
++      UINT8   bGpioIdx;
++      for(bGpioIdx = 0; bGpioIdx < GPIO_PAD_NUM; bGpioIdx++)
++      {
++              gsGlobalInfo_AA.sGpMode.abGpDdr[bGpioIdx]               = MCDRV_GPDDR_IN;
++              gsGlobalInfo_AA.sGpMode.abGpMode[bGpioIdx]              = MCDRV_GPMODE_RISING;
++              gsGlobalInfo_AA.sGpMode.abGpHost[bGpioIdx]              = MCDRV_GPHOST_SCU;
++              gsGlobalInfo_AA.sGpMode.abGpInvert[bGpioIdx]    = MCDRV_GPINV_NORMAL;
++      }
++}
++
++/****************************************************************************
++ *    InitGpMask
++ *
++ *    Description:
++ *                    Initialize Gp mask.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   InitGpMask
++(
++      void
++)
++{
++      UINT8   bGpioIdx;
++      for(bGpioIdx = 0; bGpioIdx < GPIO_PAD_NUM; bGpioIdx++)
++      {
++              gsGlobalInfo_AA.abGpMask[bGpioIdx]              = MCDRV_GPMASK_ON;
++      }
++}
++
++/****************************************************************************
++ *    McResCtrl_UpdateState_AA
++ *
++ *    Description:
++ *                    update state.
++ *    Arguments:
++ *                    eState  state
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_UpdateState_AA
++(
++      MCDRV_STATE_AA  eState
++)
++{
++      geState = eState;
++}
++
++/****************************************************************************
++ *    McResCtrl_GetState_AA
++ *
++ *    Description:
++ *                    Get state.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    current state
++ *
++ ****************************************************************************/
++MCDRV_STATE_AA        McResCtrl_GetState_AA
++(
++      void
++)
++{
++      return geState;
++}
++
++/****************************************************************************
++ *    McResCtrl_GetRegVal_AA
++ *
++ *    Description:
++ *                    Get register value.
++ *    Arguments:
++ *                    wRegType        register type
++ *                    wRegAddr        address
++ *    Return:
++ *                    register value
++ *
++ ****************************************************************************/
++UINT8 McResCtrl_GetRegVal_AA
++(
++      UINT16  wRegType,
++      UINT16  wRegAddr
++)
++{
++      switch(wRegType)
++      {
++      case    MCDRV_PACKET_REGTYPE_A_AA:
++              return gsGlobalInfo_AA.abRegValA[wRegAddr];
++      case    MCDRV_PACKET_REGTYPE_B_BASE_AA:
++              return gsGlobalInfo_AA.abRegValB_BASE[wRegAddr];
++      case    MCDRV_PACKET_REGTYPE_B_MIXER_AA:
++              return gsGlobalInfo_AA.abRegValB_MIXER[wRegAddr];
++      case    MCDRV_PACKET_REGTYPE_B_AE_AA:
++              return gsGlobalInfo_AA.abRegValB_AE[wRegAddr];
++      case    MCDRV_PACKET_REGTYPE_B_CDSP_AA:
++              return gsGlobalInfo_AA.abRegValB_CDSP[wRegAddr];
++      case    MCDRV_PACKET_REGTYPE_B_CODEC_AA:
++              return gsGlobalInfo_AA.abRegValB_CODEC[wRegAddr];
++      case    MCDRV_PACKET_REGTYPE_B_ANA_AA:
++              return gsGlobalInfo_AA.abRegValB_ANA[wRegAddr];
++      default:
++              break;
++      }
++
++      return 0;
++}
++
++/****************************************************************************
++ *    McResCtrl_SetRegVal_AA
++ *
++ *    Description:
++ *                    Set register value.
++ *    Arguments:
++ *                    wRegType        register type
++ *                    wRegAddr        address
++ *                    bRegVal         register value
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetRegVal_AA
++(
++      UINT16  wRegType,
++      UINT16  wRegAddr,
++      UINT8   bRegVal
++)
++{
++      switch(wRegType)
++      {
++      case    MCDRV_PACKET_REGTYPE_A_AA:
++              gsGlobalInfo_AA.abRegValA[wRegAddr]             = bRegVal;
++              break;
++      case    MCDRV_PACKET_REGTYPE_B_BASE_AA:
++              gsGlobalInfo_AA.abRegValB_BASE[wRegAddr]        = bRegVal;
++              break;
++      case    MCDRV_PACKET_REGTYPE_B_MIXER_AA:
++              gsGlobalInfo_AA.abRegValB_MIXER[wRegAddr]       = bRegVal;
++              break;
++      case    MCDRV_PACKET_REGTYPE_B_AE_AA:
++              gsGlobalInfo_AA.abRegValB_AE[wRegAddr]          = bRegVal;
++              break;
++      case    MCDRV_PACKET_REGTYPE_B_CDSP_AA:
++              gsGlobalInfo_AA.abRegValB_CDSP[wRegAddr]        = bRegVal;
++              break;
++      case    MCDRV_PACKET_REGTYPE_B_CODEC_AA:
++              gsGlobalInfo_AA.abRegValB_CODEC[wRegAddr]       = bRegVal;
++              break;
++      case    MCDRV_PACKET_REGTYPE_B_ANA_AA:
++              gsGlobalInfo_AA.abRegValB_ANA[wRegAddr] = bRegVal;
++              break;
++      default:
++              break;
++      }
++}
++
++/****************************************************************************
++ *    McResCtrl_GetInitInfo_AA
++ *
++ *    Description:
++ *                    Get Initialize information.
++ *    Arguments:
++ *                    psInitInfo      Initialize information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetInitInfo_AA
++(
++      MCDRV_INIT_INFO*        psInitInfo
++)
++{
++      *psInitInfo     = gsGlobalInfo_AA.sInitInfo;
++}
++
++/****************************************************************************
++ *    McResCtrl_SetClockInfo_AA
++ *
++ *    Description:
++ *                    Set clock information.
++ *    Arguments:
++ *                    psClockInfo     clock information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetClockInfo_AA
++(
++      const MCDRV_CLOCK_INFO* psClockInfo
++)
++{
++
++      gsGlobalInfo_AA.sInitInfo.bCkSel        = psClockInfo->bCkSel;
++      gsGlobalInfo_AA.sInitInfo.bDivR0        = psClockInfo->bDivR0;
++      gsGlobalInfo_AA.sInitInfo.bDivF0        = psClockInfo->bDivF0;
++      if(McDevProf_IsValid(eMCDRV_FUNC_DIVR1) == 1)
++      {
++              gsGlobalInfo_AA.sInitInfo.bDivR1        = psClockInfo->bDivR1;
++      }
++      if(McDevProf_IsValid(eMCDRV_FUNC_DIVF1) == 1)
++      {
++              gsGlobalInfo_AA.sInitInfo.bDivF1        = psClockInfo->bDivF1;
++      }
++      if(McDevProf_IsValid(eMCDRV_FUNC_RANGE) == 1)
++      {
++              gsGlobalInfo_AA.sInitInfo.bRange0       = psClockInfo->bRange0;
++              gsGlobalInfo_AA.sInitInfo.bRange1       = psClockInfo->bRange1;
++      }
++      if(McDevProf_IsValid(eMCDRV_FUNC_BYPASS) == 1)
++      {
++              gsGlobalInfo_AA.sInitInfo.bBypass       = psClockInfo->bBypass;
++      }
++}
++
++/****************************************************************************
++ *    McResCtrl_SetPathInfo_AA
++ *
++ *    Description:
++ *                    Set path information.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetPathInfo_AA
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++
++      gsGlobalInfo_AA.sPathInfo       = gsGlobalInfo_AA.sPathInfoVirtual;
++
++      /*      HP source on/off        */
++      SetHPSourceOnOff(psPathInfo);
++
++      /*      SP source on/off        */
++      SetSPSourceOnOff(psPathInfo);
++
++      /*      RCV source on/off       */
++      SetRCVSourceOnOff(psPathInfo);
++
++      /*      LOut1 source on/off     */
++      SetLO1SourceOnOff(psPathInfo);
++
++      /*      LOut2 source on/off     */
++      SetLO2SourceOnOff(psPathInfo);
++
++      /*      Peak source on/off      */
++      SetPMSourceOnOff(psPathInfo);
++
++      /*      DIT0 source on/off      */
++      SetDIT0SourceOnOff(psPathInfo);
++
++      /*      DIT1 source on/off      */
++      SetDIT1SourceOnOff(psPathInfo);
++
++      /*      DIT2 source on/off      */
++      SetDIT2SourceOnOff(psPathInfo);
++
++      /*      DAC source on/off       */
++      SetDACSourceOnOff(psPathInfo);
++
++      /*      AE source on/off        */
++      SetAESourceOnOff(psPathInfo);
++
++      /*      CDSP source on/off      */
++      SetCDSPSourceOnOff(psPathInfo);
++
++      /*      ADC0 source on/off      */
++      SetADC0SourceOnOff(psPathInfo);
++
++      /*      ADC1 source on/off      */
++      SetADC1SourceOnOff(psPathInfo);
++
++      /*      Mix source on/off       */
++      SetMixSourceOnOff(psPathInfo);
++
++      /*      Bias source on/off      */
++      SetBiasSourceOnOff(psPathInfo);
++
++      gsGlobalInfo_AA.sPathInfoVirtual        = gsGlobalInfo_AA.sPathInfo;
++
++      if((McResCtrl_IsDstUsed_AA(eMCDRV_DST_ADC0_AA, eMCDRV_DST_CH0_AA) == 0)
++      && (McResCtrl_IsDstUsed_AA(eMCDRV_DST_ADC0_AA, eMCDRV_DST_CH1_AA) == 0))
++      {/*     ADC0 source all off     */
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]     &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]     &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]              &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]     &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]     |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]     |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]              |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]     |= MCDRV_SRC4_ADC0_OFF;
++      }
++
++      if((McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_DAC_L_AA) == 0)
++      && (McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_DAC_M_AA) == 0)
++      && (McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_DAC_R_AA) == 0))
++      {/*     DAC is unused   */
++              gsGlobalInfo_AA.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]              &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]     &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]     &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]     &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]     &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]              &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]              &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]     &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]     &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]     &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]     &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]              &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]              |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]     |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]     |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]     |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]     |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]              |= MCDRV_SRC6_MIX_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]              |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]     |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]     |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]     |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]     |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]              |= MCDRV_SRC6_MIX_OFF;
++      }
++
++      if(McResCtrl_GetAESource_AA() == eMCDRV_SRC_NONE_AA)
++      {/*     AE source all off       */
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]      &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]      &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]      &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]       &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_AE_BLOCK]       &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]       &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]      |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]      |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]      |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]       |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_AE_BLOCK]       |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]       |= MCDRV_SRC6_AE_OFF;
++      }
++      else if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_AE_AA) == 0)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       |= MCDRV_SRC6_MIX_OFF;
++      }
++
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_MIX_AA, eMCDRV_DST_CH0_AA) == 0)
++      {/*     MIX source all off      */
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]              &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]              &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]               &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]              |= MCDRV_SRC6_MIX_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]              |= MCDRV_SRC6_MIX_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]               |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_MIX_AA) == 0)
++      {
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]              &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]     &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]     &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]     &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]     &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]               &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]              |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]     |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]     |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]     |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]     |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]               |= MCDRV_SRC6_AE_OFF;
++      }
++
++      if((McResCtrl_GetDACSource_AA(eMCDRV_DAC_MASTER_AA) == eMCDRV_SRC_NONE_AA)
++      && (McResCtrl_GetDACSource_AA(eMCDRV_DAC_VOICE_AA) == eMCDRV_SRC_NONE_AA))
++      {/*     DAC source all off      */
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_L_ON;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_M_ON;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_R_ON;
++              gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_L_ON;
++              gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_M_ON;
++              gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_R_ON;
++              gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_M_ON;
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_L_ON;
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_R_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_L_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_M_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_R_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_L_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_M_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_R_ON;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  |= MCDRV_SRC5_DAC_L_OFF;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  |= MCDRV_SRC5_DAC_M_OFF;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  |= MCDRV_SRC5_DAC_R_OFF;
++              gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  |= MCDRV_SRC5_DAC_L_OFF;
++              gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  |= MCDRV_SRC5_DAC_M_OFF;
++              gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  |= MCDRV_SRC5_DAC_R_OFF;
++              gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  |= MCDRV_SRC5_DAC_M_OFF;
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  |= MCDRV_SRC5_DAC_L_OFF;
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  |= MCDRV_SRC5_DAC_R_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  |= MCDRV_SRC5_DAC_L_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  |= MCDRV_SRC5_DAC_M_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  |= MCDRV_SRC5_DAC_R_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  |= MCDRV_SRC5_DAC_L_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  |= MCDRV_SRC5_DAC_M_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  |= MCDRV_SRC5_DAC_R_OFF;
++      }
++
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_ADC0_AA) == 0)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]            &= (UINT8)~MCDRV_SRC0_MIC1_ON;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]            &= (UINT8)~MCDRV_SRC0_MIC2_ON;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]            &= (UINT8)~MCDRV_SRC0_MIC3_ON;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] &= (UINT8)~MCDRV_SRC1_LINE1_L_ON;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] &= (UINT8)~MCDRV_SRC1_LINE1_M_ON;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]            &= (UINT8)~MCDRV_SRC0_MIC1_ON;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]            &= (UINT8)~MCDRV_SRC0_MIC2_ON;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]            &= (UINT8)~MCDRV_SRC0_MIC3_ON;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] &= (UINT8)~MCDRV_SRC1_LINE1_R_ON;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] &= (UINT8)~MCDRV_SRC1_LINE1_M_ON;
++
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]            |= MCDRV_SRC0_MIC1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]            |= MCDRV_SRC0_MIC2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]            |= MCDRV_SRC0_MIC3_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] |= MCDRV_SRC1_LINE1_L_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] |= MCDRV_SRC1_LINE1_M_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]            |= MCDRV_SRC0_MIC1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]            |= MCDRV_SRC0_MIC2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]            |= MCDRV_SRC0_MIC3_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] |= MCDRV_SRC1_LINE1_R_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] |= MCDRV_SRC1_LINE1_M_OFF;
++      }
++}
++
++/****************************************************************************
++ *    SetHPSourceOnOff
++ *
++ *    Description:
++ *                    Set HP source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetHPSourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++      if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   |= MCDRV_SRC0_MIC1_ON;
++      }
++      else if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC1_ON;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   |= MCDRV_SRC0_MIC1_OFF;
++      }
++      if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   |= MCDRV_SRC0_MIC2_ON;
++      }
++      else if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC2_ON;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   |= MCDRV_SRC0_MIC2_OFF;
++      }
++      if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC3_OFF;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   |= MCDRV_SRC0_MIC3_ON;
++      }
++      else if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC3_ON;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   |= MCDRV_SRC0_MIC3_OFF;
++      }
++
++      if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_L_OFF;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]        |= MCDRV_SRC1_LINE1_L_ON;
++      }
++      else if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_L_ON;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]        |= MCDRV_SRC1_LINE1_L_OFF;
++      }
++      if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_M_OFF;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]        |= MCDRV_SRC1_LINE1_M_ON;
++      }
++      else if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_M_ON;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]        |= MCDRV_SRC1_LINE1_M_OFF;
++      }
++
++      if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_L_OFF;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  |= MCDRV_SRC5_DAC_L_ON;
++      }
++      else if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_L_ON;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  |= MCDRV_SRC5_DAC_L_OFF;
++      }
++      if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_M_OFF;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  |= MCDRV_SRC5_DAC_M_ON;
++      }
++      else if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_M_ON;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  |= MCDRV_SRC5_DAC_M_OFF;
++      }
++
++      if((psPathInfo->asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   |= MCDRV_SRC0_MIC1_ON;
++      }
++      else if((psPathInfo->asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC1_ON;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   |= MCDRV_SRC0_MIC1_OFF;
++      }
++      if((psPathInfo->asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   |= MCDRV_SRC0_MIC2_ON;
++      }
++      else if((psPathInfo->asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC2_ON;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   |= MCDRV_SRC0_MIC2_OFF;
++      }
++      if((psPathInfo->asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC3_OFF;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   |= MCDRV_SRC0_MIC3_ON;
++      }
++      else if((psPathInfo->asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC3_ON;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   |= MCDRV_SRC0_MIC3_OFF;
++      }
++
++      if((psPathInfo->asHpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_R_OFF;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]        |= MCDRV_SRC1_LINE1_R_ON;
++      }
++      else if((psPathInfo->asHpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_R_ON;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]        |= MCDRV_SRC1_LINE1_R_OFF;
++      }
++
++      if((psPathInfo->asHpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & (MCDRV_SRC5_DAC_R_ON|MCDRV_SRC5_DAC_R_OFF)) == MCDRV_SRC5_DAC_R_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_R_OFF;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  |= MCDRV_SRC5_DAC_R_ON;
++      }
++      else if((psPathInfo->asHpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & (MCDRV_SRC5_DAC_R_ON|MCDRV_SRC5_DAC_R_OFF)) == MCDRV_SRC5_DAC_R_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_R_ON;
++              gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  |= MCDRV_SRC5_DAC_R_OFF;
++      }
++}
++
++/****************************************************************************
++ *    SetSPSourceOnOff
++ *
++ *    Description:
++ *                    Set SP source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetSPSourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++      if((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_L_OFF;
++              gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]        |= MCDRV_SRC1_LINE1_L_ON;
++      }
++      else if((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_L_ON;
++              gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]        |= MCDRV_SRC1_LINE1_L_OFF;
++      }
++      if((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_M_OFF;
++              gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]        |= MCDRV_SRC1_LINE1_M_ON;
++      }
++      else if((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_M_ON;
++              gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]        |= MCDRV_SRC1_LINE1_M_OFF;
++      }
++
++      if((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_L_OFF;
++              gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  |= MCDRV_SRC5_DAC_L_ON;
++      }
++      else if((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_L_ON;
++              gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  |= MCDRV_SRC5_DAC_L_OFF;
++      }
++      if((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_M_OFF;
++              gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  |= MCDRV_SRC5_DAC_M_ON;
++      }
++      else if((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_M_ON;
++              gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  |= MCDRV_SRC5_DAC_M_OFF;
++      }
++
++      if((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_R_OFF;
++              gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]        |= MCDRV_SRC1_LINE1_R_ON;
++      }
++      else if((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_R_ON;
++              gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]        |= MCDRV_SRC1_LINE1_R_OFF;
++      }
++      if((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_M_OFF;
++              gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]        |= MCDRV_SRC1_LINE1_M_ON;
++      }
++      else if((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_M_ON;
++              gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]        |= MCDRV_SRC1_LINE1_M_OFF;
++      }
++
++      if((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & (MCDRV_SRC5_DAC_R_ON|MCDRV_SRC5_DAC_R_OFF)) == MCDRV_SRC5_DAC_R_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_R_OFF;
++              gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  |= MCDRV_SRC5_DAC_R_ON;
++      }
++      else if((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & (MCDRV_SRC5_DAC_R_ON|MCDRV_SRC5_DAC_R_OFF)) == MCDRV_SRC5_DAC_R_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_R_ON;
++              gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  |= MCDRV_SRC5_DAC_R_OFF;
++      }
++      if((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_M_OFF;
++              gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  |= MCDRV_SRC5_DAC_M_ON;
++      }
++      else if((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_M_ON;
++              gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  |= MCDRV_SRC5_DAC_M_OFF;
++      }
++}
++
++/****************************************************************************
++ *    SetRCVSourceOnOff
++ *
++ *    Description:
++ *                    Set RCV source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetRCVSourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++      if((psPathInfo->asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   |= MCDRV_SRC0_MIC1_ON;
++      }
++      else if((psPathInfo->asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC1_ON;
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   |= MCDRV_SRC0_MIC1_OFF;
++      }
++      if((psPathInfo->asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   |= MCDRV_SRC0_MIC2_ON;
++      }
++      else if((psPathInfo->asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC2_ON;
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   |= MCDRV_SRC0_MIC2_OFF;
++      }
++      if((psPathInfo->asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC3_OFF;
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   |= MCDRV_SRC0_MIC3_ON;
++      }
++      else if((psPathInfo->asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC3_ON;
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   |= MCDRV_SRC0_MIC3_OFF;
++      }
++
++      if((psPathInfo->asRcOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_M_OFF;
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]        |= MCDRV_SRC1_LINE1_M_ON;
++      }
++      else if((psPathInfo->asRcOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_M_ON;
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]        |= MCDRV_SRC1_LINE1_M_OFF;
++      }
++
++      if((psPathInfo->asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_L_OFF;
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  |= MCDRV_SRC5_DAC_L_ON;
++      }
++      else if((psPathInfo->asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_L_ON;
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  |= MCDRV_SRC5_DAC_L_OFF;
++      }
++
++      if((psPathInfo->asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & (MCDRV_SRC5_DAC_R_ON|MCDRV_SRC5_DAC_R_OFF)) == MCDRV_SRC5_DAC_R_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_R_OFF;
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  |= MCDRV_SRC5_DAC_R_ON;
++      }
++      else if((psPathInfo->asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & (MCDRV_SRC5_DAC_R_ON|MCDRV_SRC5_DAC_R_OFF)) == MCDRV_SRC5_DAC_R_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_R_ON;
++              gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  |= MCDRV_SRC5_DAC_R_OFF;
++      }
++}
++
++/****************************************************************************
++ *    SetLO1SourceOnOff
++ *
++ *    Description:
++ *                    Set LOut1 source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetLO1SourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++      if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   |= MCDRV_SRC0_MIC1_ON;
++      }
++      else if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC1_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   |= MCDRV_SRC0_MIC1_OFF;
++      }
++      if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   |= MCDRV_SRC0_MIC2_ON;
++      }
++      else if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC2_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   |= MCDRV_SRC0_MIC2_OFF;
++      }
++      if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC3_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   |= MCDRV_SRC0_MIC3_ON;
++      }
++      else if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC3_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   |= MCDRV_SRC0_MIC3_OFF;
++      }
++
++      if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_L_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]        |= MCDRV_SRC1_LINE1_L_ON;
++      }
++      else if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_L_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]        |= MCDRV_SRC1_LINE1_L_OFF;
++      }
++      if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_M_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]        |= MCDRV_SRC1_LINE1_M_ON;
++      }
++      else if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_M_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]        |= MCDRV_SRC1_LINE1_M_OFF;
++      }
++
++      if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_L_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  |= MCDRV_SRC5_DAC_L_ON;
++      }
++      else if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_L_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  |= MCDRV_SRC5_DAC_L_OFF;
++      }
++      if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_M_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  |= MCDRV_SRC5_DAC_M_ON;
++      }
++      else if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_M_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  |= MCDRV_SRC5_DAC_M_OFF;
++      }
++
++      if((psPathInfo->asLout1[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   |= MCDRV_SRC0_MIC1_ON;
++      }
++      else if((psPathInfo->asLout1[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC1_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   |= MCDRV_SRC0_MIC1_OFF;
++      }
++      if((psPathInfo->asLout1[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   |= MCDRV_SRC0_MIC2_ON;
++      }
++      else if((psPathInfo->asLout1[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC2_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   |= MCDRV_SRC0_MIC2_OFF;
++      }
++      if((psPathInfo->asLout1[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC3_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   |= MCDRV_SRC0_MIC3_ON;
++      }
++      else if((psPathInfo->asLout1[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC3_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   |= MCDRV_SRC0_MIC3_OFF;
++      }
++
++      if((psPathInfo->asLout1[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_R_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]        |= MCDRV_SRC1_LINE1_R_ON;
++      }
++      else if((psPathInfo->asLout1[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_R_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]        |= MCDRV_SRC1_LINE1_R_OFF;
++      }
++
++      if((psPathInfo->asLout1[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & (MCDRV_SRC5_DAC_R_ON|MCDRV_SRC5_DAC_R_OFF)) == MCDRV_SRC5_DAC_R_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_R_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  |= MCDRV_SRC5_DAC_R_ON;
++      }
++      else if((psPathInfo->asLout1[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & (MCDRV_SRC5_DAC_R_ON|MCDRV_SRC5_DAC_R_OFF)) == MCDRV_SRC5_DAC_R_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_R_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  |= MCDRV_SRC5_DAC_R_OFF;
++      }
++}
++
++/****************************************************************************
++ *    SetLO2SourceOnOff
++ *
++ *    Description:
++ *                    Set LOut2 source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetLO2SourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++      if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   |= MCDRV_SRC0_MIC1_ON;
++      }
++      else if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC1_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   |= MCDRV_SRC0_MIC1_OFF;
++      }
++      if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   |= MCDRV_SRC0_MIC2_ON;
++      }
++      else if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC2_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   |= MCDRV_SRC0_MIC2_OFF;
++      }
++      if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC3_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   |= MCDRV_SRC0_MIC3_ON;
++      }
++      else if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC3_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   |= MCDRV_SRC0_MIC3_OFF;
++      }
++
++      if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_L_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]        |= MCDRV_SRC1_LINE1_L_ON;
++      }
++      else if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_L_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]        |= MCDRV_SRC1_LINE1_L_OFF;
++      }
++      if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_M_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]        |= MCDRV_SRC1_LINE1_M_ON;
++      }
++      else if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_M_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]        |= MCDRV_SRC1_LINE1_M_OFF;
++      }
++
++      if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_L_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  |= MCDRV_SRC5_DAC_L_ON;
++      }
++      else if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_L_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]  |= MCDRV_SRC5_DAC_L_OFF;
++      }
++      if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_M_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  |= MCDRV_SRC5_DAC_M_ON;
++      }
++      else if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_M_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]  |= MCDRV_SRC5_DAC_M_OFF;
++      }
++
++      if((psPathInfo->asLout2[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   |= MCDRV_SRC0_MIC1_ON;
++      }
++      else if((psPathInfo->asLout2[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC1_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]   |= MCDRV_SRC0_MIC1_OFF;
++      }
++      if((psPathInfo->asLout2[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   |= MCDRV_SRC0_MIC2_ON;
++      }
++      else if((psPathInfo->asLout2[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC2_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]   |= MCDRV_SRC0_MIC2_OFF;
++      }
++      if((psPathInfo->asLout2[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC3_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   |= MCDRV_SRC0_MIC3_ON;
++      }
++      else if((psPathInfo->asLout2[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   &= (UINT8)~MCDRV_SRC0_MIC3_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]   |= MCDRV_SRC0_MIC3_OFF;
++      }
++
++      if((psPathInfo->asLout2[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_R_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]        |= MCDRV_SRC1_LINE1_R_ON;
++      }
++      else if((psPathInfo->asLout2[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]        &= (UINT8)~MCDRV_SRC1_LINE1_R_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]        |= MCDRV_SRC1_LINE1_R_OFF;
++      }
++
++      if((psPathInfo->asLout2[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & (MCDRV_SRC5_DAC_R_ON|MCDRV_SRC5_DAC_R_OFF)) == MCDRV_SRC5_DAC_R_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_R_OFF;
++              gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  |= MCDRV_SRC5_DAC_R_ON;
++      }
++      else if((psPathInfo->asLout2[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & (MCDRV_SRC5_DAC_R_ON|MCDRV_SRC5_DAC_R_OFF)) == MCDRV_SRC5_DAC_R_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  &= (UINT8)~MCDRV_SRC5_DAC_R_ON;
++              gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]  |= MCDRV_SRC5_DAC_R_OFF;
++      }
++}
++
++/****************************************************************************
++ *    SetPMSourceOnOff
++ *
++ *    Description:
++ *                    Set PeakMeter source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetPMSourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++      (void)psPathInfo;
++}
++
++/****************************************************************************
++ *    SetDIT0SourceOnOff
++ *
++ *    Description:
++ *                    Set DIT0 source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetDIT0SourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++      && gsGlobalInfo_AA.sInitInfo.bPad0Func == MCDRV_PAD_PDMCK)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_OFF;
++      }
++
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++      }
++
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_OFF;
++      }
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_OFF;
++      }
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_OFF;
++      }
++
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_OFF;
++      }
++
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_ON;
++      }
++      else if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++      }
++}
++
++/****************************************************************************
++ *    SetDIT1SourceOnOff
++ *
++ *    Description:
++ *                    Set DIT1 source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetDIT1SourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++      && gsGlobalInfo_AA.sInitInfo.bPad0Func == MCDRV_PAD_PDMCK)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_OFF;
++      }
++
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++      }
++
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_OFF;
++      }
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_OFF;
++      }
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_OFF;
++      }
++
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_OFF;
++      }
++
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_ON;
++      }
++      else if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++      }
++}
++
++/****************************************************************************
++ *    SetDIT2SourceOnOff
++ *
++ *    Description:
++ *                    Set DIT2 source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetDIT2SourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++      && gsGlobalInfo_AA.sInitInfo.bPad0Func == MCDRV_PAD_PDMCK)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_OFF;
++      }
++
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++      }
++
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_OFF;
++      }
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_OFF;
++      }
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_OFF;
++      }
++
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_OFF;
++      }
++
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_OFF;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_ON;
++      }
++      else if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++      }
++}
++
++/****************************************************************************
++ *    SetDACSourceOnOff
++ *
++ *    Description:
++ *                    Set DAC source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetDACSourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++      UINT8   bCh;
++      for(bCh = 0; bCh < DAC_PATH_CHANNELS; bCh++)
++      {
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++              && gsGlobalInfo_AA.sInitInfo.bPad0Func == MCDRV_PAD_PDMCK)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]    &= (UINT8)~MCDRV_SRC4_PDM_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]    |= MCDRV_SRC4_PDM_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]   &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]   |= MCDRV_SRC4_ADC0_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]   &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]   |= MCDRV_SRC3_DIR0_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]   &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]   |= MCDRV_SRC3_DIR1_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]   &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]   |= MCDRV_SRC3_DIR2_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]     &= (UINT8)~MCDRV_SRC6_AE_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]     |= MCDRV_SRC6_AE_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]    &= (UINT8)~MCDRV_SRC6_MIX_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]    |= MCDRV_SRC6_MIX_OFF;
++              }
++              else if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_OFF)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]    &= (UINT8)~MCDRV_SRC4_PDM_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]    |= MCDRV_SRC4_PDM_OFF;
++              }
++
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]    &= (UINT8)~MCDRV_SRC4_PDM_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]    |= MCDRV_SRC4_PDM_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]   &= (UINT8)~MCDRV_SRC4_ADC0_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]   |= MCDRV_SRC4_ADC0_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]   &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]   |= MCDRV_SRC3_DIR0_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]   &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]   |= MCDRV_SRC3_DIR1_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]   &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]   |= MCDRV_SRC3_DIR2_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]     &= (UINT8)~MCDRV_SRC6_AE_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]     |= MCDRV_SRC6_AE_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]    &= (UINT8)~MCDRV_SRC6_MIX_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]    |= MCDRV_SRC6_MIX_OFF;
++              }
++              else if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_OFF)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]   &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]   |= MCDRV_SRC4_ADC0_OFF;
++              }
++
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]    &= (UINT8)~MCDRV_SRC4_PDM_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]    |= MCDRV_SRC4_PDM_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]   &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]   |= MCDRV_SRC4_ADC0_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]   &= (UINT8)~MCDRV_SRC3_DIR0_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]   |= MCDRV_SRC3_DIR0_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]   &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]   |= MCDRV_SRC3_DIR1_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]   &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]   |= MCDRV_SRC3_DIR2_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]     &= (UINT8)~MCDRV_SRC6_AE_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]     |= MCDRV_SRC6_AE_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]    &= (UINT8)~MCDRV_SRC6_MIX_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]    |= MCDRV_SRC6_MIX_OFF;
++              }
++              else if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_OFF)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]   &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]   |= MCDRV_SRC3_DIR0_OFF;
++              }
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]    &= (UINT8)~MCDRV_SRC4_PDM_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]    |= MCDRV_SRC4_PDM_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]   &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]   |= MCDRV_SRC4_ADC0_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]   &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]   |= MCDRV_SRC3_DIR0_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]   &= (UINT8)~MCDRV_SRC3_DIR1_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]   |= MCDRV_SRC3_DIR1_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]   &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]   |= MCDRV_SRC3_DIR2_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]     &= (UINT8)~MCDRV_SRC6_AE_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]     |= MCDRV_SRC6_AE_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]    &= (UINT8)~MCDRV_SRC6_MIX_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]    |= MCDRV_SRC6_MIX_OFF;
++              }
++              else if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_OFF)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]   &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]   |= MCDRV_SRC3_DIR1_OFF;
++              }
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]    &= (UINT8)~MCDRV_SRC4_PDM_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]    |= MCDRV_SRC4_PDM_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]   &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]   |= MCDRV_SRC4_ADC0_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]   &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]   |= MCDRV_SRC3_DIR0_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]   &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]   |= MCDRV_SRC3_DIR1_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]   &= (UINT8)~MCDRV_SRC3_DIR2_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]   |= MCDRV_SRC3_DIR2_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]     &= (UINT8)~MCDRV_SRC6_AE_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]     |= MCDRV_SRC6_AE_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]    &= (UINT8)~MCDRV_SRC6_MIX_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]    |= MCDRV_SRC6_MIX_OFF;
++              }
++              else if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_OFF)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]   &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]   |= MCDRV_SRC3_DIR2_OFF;
++              }
++
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]    &= (UINT8)~MCDRV_SRC4_PDM_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]    |= MCDRV_SRC4_PDM_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]   &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]   |= MCDRV_SRC4_ADC0_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]   &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]   |= MCDRV_SRC3_DIR0_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]   &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]   |= MCDRV_SRC3_DIR1_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]   &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]   |= MCDRV_SRC3_DIR2_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]     &= (UINT8)~MCDRV_SRC6_AE_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]     |= MCDRV_SRC6_AE_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]    &= (UINT8)~MCDRV_SRC6_MIX_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]    |= MCDRV_SRC6_MIX_OFF;
++              }
++              else if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_OFF)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]     &= (UINT8)~MCDRV_SRC6_AE_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]     |= MCDRV_SRC6_AE_OFF;
++              }
++
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]    &= (UINT8)~MCDRV_SRC4_PDM_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]    |= MCDRV_SRC4_PDM_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]   &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]   |= MCDRV_SRC4_ADC0_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]   &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]   |= MCDRV_SRC3_DIR0_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]   &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]   |= MCDRV_SRC3_DIR1_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]   &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]   |= MCDRV_SRC3_DIR2_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]     &= (UINT8)~MCDRV_SRC6_AE_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]     |= MCDRV_SRC6_AE_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]    &= (UINT8)~MCDRV_SRC6_MIX_OFF;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]    |= MCDRV_SRC6_MIX_ON;
++              }
++              else if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_OFF)
++              {
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]    &= (UINT8)~MCDRV_SRC6_MIX_ON;
++                      gsGlobalInfo_AA.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]    |= MCDRV_SRC6_MIX_OFF;
++              }
++      }
++}
++
++/****************************************************************************
++ *    SetAESourceOnOff
++ *
++ *    Description:
++ *                    Set AE source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetAESourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++      && gsGlobalInfo_AA.sInitInfo.bPad0Func == MCDRV_PAD_PDMCK)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       &= (UINT8)~MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       |= MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       |= MCDRV_SRC4_PDM_OFF;
++      }
++
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      &= (UINT8)~MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      |= MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      |= MCDRV_SRC4_ADC0_OFF;
++      }
++
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      |= MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      |= MCDRV_SRC3_DIR0_OFF;
++      }
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      |= MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      |= MCDRV_SRC3_DIR1_OFF;
++      }
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      |= MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      |= MCDRV_SRC3_DIR2_OFF;
++      }
++
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       &= (UINT8)~MCDRV_SRC6_MIX_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       |= MCDRV_SRC6_MIX_ON;
++      }
++      else if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       |= MCDRV_SRC6_MIX_OFF;
++      }
++}
++
++/****************************************************************************
++ *    SetCDSPSourceOnOff
++ *
++ *    Description:
++ *                    Set CDSP source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetCDSPSourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++      (void)psPathInfo;
++}
++
++/****************************************************************************
++ *    SetADC0SourceOnOff
++ *
++ *    Description:
++ *                    Set ADC0 source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetADC0SourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++      if((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]    &= (UINT8)~MCDRV_SRC0_MIC1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]    |= MCDRV_SRC0_MIC1_ON;
++      }
++      else if((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]    &= (UINT8)~MCDRV_SRC0_MIC1_ON;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]    |= MCDRV_SRC0_MIC1_OFF;
++      }
++      if((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]    &= (UINT8)~MCDRV_SRC0_MIC2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]    |= MCDRV_SRC0_MIC2_ON;
++      }
++      else if((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]    &= (UINT8)~MCDRV_SRC0_MIC2_ON;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]    |= MCDRV_SRC0_MIC2_OFF;
++      }
++      if((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]    &= (UINT8)~MCDRV_SRC0_MIC3_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]    |= MCDRV_SRC0_MIC3_ON;
++      }
++      else if((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]    &= (UINT8)~MCDRV_SRC0_MIC3_ON;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]    |= MCDRV_SRC0_MIC3_OFF;
++      }
++
++      if((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] &= (UINT8)~MCDRV_SRC1_LINE1_L_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] |= MCDRV_SRC1_LINE1_L_ON;
++      }
++      else if((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] &= (UINT8)~MCDRV_SRC1_LINE1_L_ON;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] |= MCDRV_SRC1_LINE1_L_OFF;
++      }
++      if((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] &= (UINT8)~MCDRV_SRC1_LINE1_M_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] |= MCDRV_SRC1_LINE1_M_ON;
++      }
++      else if((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] &= (UINT8)~MCDRV_SRC1_LINE1_M_ON;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] |= MCDRV_SRC1_LINE1_M_OFF;
++      }
++
++      if((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]    &= (UINT8)~MCDRV_SRC0_MIC1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]    |= MCDRV_SRC0_MIC1_ON;
++      }
++      else if((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]    &= (UINT8)~MCDRV_SRC0_MIC1_ON;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]    |= MCDRV_SRC0_MIC1_OFF;
++      }
++      if((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]    &= (UINT8)~MCDRV_SRC0_MIC2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]    |= MCDRV_SRC0_MIC2_ON;
++      }
++      else if((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]    &= (UINT8)~MCDRV_SRC0_MIC2_ON;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]    |= MCDRV_SRC0_MIC2_OFF;
++      }
++      if((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]    &= (UINT8)~MCDRV_SRC0_MIC3_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]    |= MCDRV_SRC0_MIC3_ON;
++      }
++      else if((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]    &= (UINT8)~MCDRV_SRC0_MIC3_ON;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]    |= MCDRV_SRC0_MIC3_OFF;
++      }
++
++      if((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] &= (UINT8)~MCDRV_SRC1_LINE1_R_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] |= MCDRV_SRC1_LINE1_R_ON;
++      }
++      else if((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] &= (UINT8)~MCDRV_SRC1_LINE1_R_ON;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] |= MCDRV_SRC1_LINE1_R_OFF;
++      }
++      if((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] &= (UINT8)~MCDRV_SRC1_LINE1_M_OFF;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] |= MCDRV_SRC1_LINE1_M_ON;
++      }
++      else if((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] &= (UINT8)~MCDRV_SRC1_LINE1_M_ON;
++              gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] |= MCDRV_SRC1_LINE1_M_OFF;
++      }
++}
++
++/****************************************************************************
++ *    SetADC1SourceOnOff
++ *
++ *    Description:
++ *                    Set ADC1 source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetADC1SourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++      (void)psPathInfo;
++}
++
++/****************************************************************************
++ *    SetMixSourceOnOff
++ *
++ *    Description:
++ *                    Set Mix source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetMixSourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++      if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++      && gsGlobalInfo_AA.sInitInfo.bPad0Func == MCDRV_PAD_PDMCK)
++      {
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]      &= (UINT8)~MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]      |= MCDRV_SRC4_PDM_ON;
++      }
++      else if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]      &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]      |= MCDRV_SRC4_PDM_OFF;
++      }
++
++      if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]     &= (UINT8)~MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]     |= MCDRV_SRC4_ADC0_ON;
++      }
++      else if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]     &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]     |= MCDRV_SRC4_ADC0_OFF;
++      }
++
++      if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]     &= (UINT8)~MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]     |= MCDRV_SRC3_DIR0_ON;
++      }
++      else if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]     &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]     |= MCDRV_SRC3_DIR0_OFF;
++      }
++      if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]     &= (UINT8)~MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]     |= MCDRV_SRC3_DIR1_ON;
++      }
++      else if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]     &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]     |= MCDRV_SRC3_DIR1_OFF;
++      }
++      if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]     &= (UINT8)~MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]     |= MCDRV_SRC3_DIR2_ON;
++      }
++      else if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]     &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]     |= MCDRV_SRC3_DIR2_OFF;
++      }
++
++      if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]       &= (UINT8)~MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]       |= MCDRV_SRC6_AE_ON;
++      }
++      else if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]       &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]       |= MCDRV_SRC6_AE_OFF;
++      }
++}
++
++/****************************************************************************
++ *    SetExtBiasOnOff
++ *
++ *    Description:
++ *                    Set Bias source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetBiasSourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++      if((psPathInfo->asBias[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]    &= (UINT8)~MCDRV_SRC0_MIC1_OFF;
++              gsGlobalInfo_AA.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]    |= MCDRV_SRC0_MIC1_ON;
++      }
++      else if((psPathInfo->asBias[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]    &= (UINT8)~MCDRV_SRC0_MIC1_ON;
++              gsGlobalInfo_AA.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]    |= MCDRV_SRC0_MIC1_OFF;
++      }
++      if((psPathInfo->asBias[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]    &= (UINT8)~MCDRV_SRC0_MIC2_OFF;
++              gsGlobalInfo_AA.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]    |= MCDRV_SRC0_MIC2_ON;
++      }
++      else if((psPathInfo->asBias[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]    &= (UINT8)~MCDRV_SRC0_MIC2_ON;
++              gsGlobalInfo_AA.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]    |= MCDRV_SRC0_MIC2_OFF;
++      }
++      if((psPathInfo->asBias[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_ON)
++      {
++              gsGlobalInfo_AA.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]    &= (UINT8)~MCDRV_SRC0_MIC3_OFF;
++              gsGlobalInfo_AA.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]    |= MCDRV_SRC0_MIC3_ON;
++      }
++      else if((psPathInfo->asBias[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_OFF)
++      {
++              gsGlobalInfo_AA.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]    &= (UINT8)~MCDRV_SRC0_MIC3_ON;
++              gsGlobalInfo_AA.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]    |= MCDRV_SRC0_MIC3_OFF;
++      }
++}
++
++/****************************************************************************
++ *    McResCtrl_GetPathInfo_AA
++ *
++ *    Description:
++ *                    Get path information.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetPathInfo_AA
++(
++      MCDRV_PATH_INFO*        psPathInfo
++)
++{
++      *psPathInfo     = gsGlobalInfo_AA.sPathInfo;
++}
++
++/****************************************************************************
++ *    McResCtrl_GetPathInfoVirtual_AA
++ *
++ *    Description:
++ *                    Get virtaul path information.
++ *    Arguments:
++ *                    psPathInfo      virtaul path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetPathInfoVirtual_AA
++(
++      MCDRV_PATH_INFO*        psPathInfo
++)
++{
++      *psPathInfo     = gsGlobalInfo_AA.sPathInfoVirtual;
++}
++
++/****************************************************************************
++ *    McResCtrl_SetDioInfo_AA
++ *
++ *    Description:
++ *                    Set digital io information.
++ *    Arguments:
++ *                    psDioInfo       digital io information
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetDioInfo_AA
++(
++      const MCDRV_DIO_INFO*   psDioInfo,
++      UINT32  dUpdateInfo
++)
++{
++
++      if((dUpdateInfo & MCDRV_DIO0_COM_UPDATE_FLAG) != 0)
++      {
++              SetDIOCommon(psDioInfo, 0);
++      }
++      if((dUpdateInfo & MCDRV_DIO1_COM_UPDATE_FLAG) != 0)
++      {
++              SetDIOCommon(psDioInfo, 1);
++      }
++      if((dUpdateInfo & MCDRV_DIO2_COM_UPDATE_FLAG) != 0)
++      {
++              SetDIOCommon(psDioInfo, 2);
++      }
++
++      if((dUpdateInfo & MCDRV_DIO0_DIR_UPDATE_FLAG) != 0)
++      {
++              SetDIODIR(psDioInfo, 0);
++      }
++      if((dUpdateInfo & MCDRV_DIO1_DIR_UPDATE_FLAG) != 0)
++      {
++              SetDIODIR(psDioInfo, 1);
++      }
++      if((dUpdateInfo & MCDRV_DIO2_DIR_UPDATE_FLAG) != 0)
++      {
++              SetDIODIR(psDioInfo, 2);
++      }
++
++      if((dUpdateInfo & MCDRV_DIO0_DIT_UPDATE_FLAG) != 0)
++      {
++              SetDIODIT(psDioInfo, 0);
++      }
++      if((dUpdateInfo & MCDRV_DIO1_DIT_UPDATE_FLAG) != 0)
++      {
++              SetDIODIT(psDioInfo, 1);
++      }
++      if((dUpdateInfo & MCDRV_DIO2_DIT_UPDATE_FLAG) != 0)
++      {
++              SetDIODIT(psDioInfo, 2);
++      }
++}
++
++/****************************************************************************
++ *    SetDIOCommon
++ *
++ *    Description:
++ *                    Set digital io common information.
++ *    Arguments:
++ *                    psDioInfo       digital io information
++ *                    bPort           port number
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetDIOCommon
++(
++      const MCDRV_DIO_INFO*   psDioInfo,
++      UINT8   bPort
++)
++{
++      if(psDioInfo->asPortInfo[bPort].sDioCommon.bMasterSlave == MCDRV_DIO_SLAVE
++      || psDioInfo->asPortInfo[bPort].sDioCommon.bMasterSlave == MCDRV_DIO_MASTER)
++      {
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDioCommon.bMasterSlave      = psDioInfo->asPortInfo[bPort].sDioCommon.bMasterSlave;
++      }
++      if(psDioInfo->asPortInfo[bPort].sDioCommon.bAutoFs == MCDRV_AUTOFS_OFF
++      || psDioInfo->asPortInfo[bPort].sDioCommon.bAutoFs == MCDRV_AUTOFS_ON)
++      {
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDioCommon.bAutoFs   = psDioInfo->asPortInfo[bPort].sDioCommon.bAutoFs;
++      }
++      if(psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_48000
++      || psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_44100
++      || psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_32000
++      || psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_24000
++      || psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_22050
++      || psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_16000
++      || psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_12000
++      || psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_11025
++      || psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_8000)
++      {
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDioCommon.bFs       = psDioInfo->asPortInfo[bPort].sDioCommon.bFs;
++      }
++      if(psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs == MCDRV_BCKFS_64
++      || psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs == MCDRV_BCKFS_48
++      || psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs == MCDRV_BCKFS_32
++      || psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs == MCDRV_BCKFS_512
++      || psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs == MCDRV_BCKFS_256
++      || psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs == MCDRV_BCKFS_128
++      || psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs == MCDRV_BCKFS_16)
++      {
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDioCommon.bBckFs    = psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs;
++      }
++      if(psDioInfo->asPortInfo[bPort].sDioCommon.bInterface == MCDRV_DIO_DA
++      || psDioInfo->asPortInfo[bPort].sDioCommon.bInterface == MCDRV_DIO_PCM)
++      {
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDioCommon.bInterface        = psDioInfo->asPortInfo[bPort].sDioCommon.bInterface;
++      }
++      if(psDioInfo->asPortInfo[bPort].sDioCommon.bBckInvert == MCDRV_BCLK_NORMAL
++      || psDioInfo->asPortInfo[bPort].sDioCommon.bBckInvert == MCDRV_BCLK_INVERT)
++      {
++              gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDioCommon.bBckInvert        = psDioInfo->asPortInfo[bPort].sDioCommon.bBckInvert;
++      }
++      if(psDioInfo->asPortInfo[bPort].sDioCommon.bInterface == MCDRV_DIO_PCM)
++      {
++              if(psDioInfo->asPortInfo[bPort].sDioCommon.bPcmHizTim == MCDRV_PCMHIZTIM_FALLING
++              || psDioInfo->asPortInfo[bPort].sDioCommon.bPcmHizTim == MCDRV_PCMHIZTIM_RISING)
++              {
++                      gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDioCommon.bPcmHizTim        = psDioInfo->asPortInfo[bPort].sDioCommon.bPcmHizTim;
++              }
++              if(psDioInfo->asPortInfo[bPort].sDioCommon.bPcmClkDown == MCDRV_PCM_CLKDOWN_OFF
++              || psDioInfo->asPortInfo[bPort].sDioCommon.bPcmClkDown == MCDRV_PCM_CLKDOWN_HALF)
++              {
++                      gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDioCommon.bPcmClkDown       = psDioInfo->asPortInfo[bPort].sDioCommon.bPcmClkDown;
++              }
++              if(psDioInfo->asPortInfo[bPort].sDioCommon.bPcmFrame == MCDRV_PCM_SHORTFRAME
++              || psDioInfo->asPortInfo[bPort].sDioCommon.bPcmFrame == MCDRV_PCM_LONGFRAME)
++              {
++                      gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDioCommon.bPcmFrame = psDioInfo->asPortInfo[bPort].sDioCommon.bPcmFrame;
++              }
++              if(psDioInfo->asPortInfo[bPort].sDioCommon.bPcmHighPeriod <= 31)
++              {
++                      gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDioCommon.bPcmHighPeriod    = psDioInfo->asPortInfo[bPort].sDioCommon.bPcmHighPeriod;
++              }
++      }
++}
++
++/****************************************************************************
++ *    SetDIODIR
++ *
++ *    Description:
++ *                    Set digital io dir information.
++ *    Arguments:
++ *                    psDioInfo       digital io information
++ *                    bPort           port number
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetDIODIR
++(
++      const MCDRV_DIO_INFO*   psDioInfo,
++      UINT8   bPort
++)
++{
++      UINT8   bDIOCh;
++
++      gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDir.wSrcRate        = psDioInfo->asPortInfo[bPort].sDir.wSrcRate;
++      if(gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDioCommon.bInterface == MCDRV_DIO_DA)
++      {
++              if(psDioInfo->asPortInfo[bPort].sDir.sDaFormat.bBitSel == MCDRV_BITSEL_16
++              || psDioInfo->asPortInfo[bPort].sDir.sDaFormat.bBitSel == MCDRV_BITSEL_20
++              || psDioInfo->asPortInfo[bPort].sDir.sDaFormat.bBitSel == MCDRV_BITSEL_24)
++              {
++                      gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDir.sDaFormat.bBitSel       = psDioInfo->asPortInfo[bPort].sDir.sDaFormat.bBitSel;
++              }
++              if(psDioInfo->asPortInfo[bPort].sDir.sDaFormat.bMode == MCDRV_DAMODE_HEADALIGN
++              || psDioInfo->asPortInfo[bPort].sDir.sDaFormat.bMode == MCDRV_DAMODE_I2S
++              || psDioInfo->asPortInfo[bPort].sDir.sDaFormat.bMode == MCDRV_DAMODE_TAILALIGN)
++              {
++                      gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDir.sDaFormat.bMode = psDioInfo->asPortInfo[bPort].sDir.sDaFormat.bMode;
++              }
++      }
++      else if(gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDioCommon.bInterface == MCDRV_DIO_PCM)
++      {
++              if(psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bMono == MCDRV_PCM_STEREO
++              || psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bMono == MCDRV_PCM_MONO)
++              {
++                      gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDir.sPcmFormat.bMono        = psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bMono;
++              }
++              if(psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bOrder == MCDRV_PCM_MSB_FIRST
++              || psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bOrder == MCDRV_PCM_LSB_FIRST
++              || psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bOrder == MCDRV_PCM_MSB_FIRST_SIGN
++              || psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bOrder == MCDRV_PCM_LSB_FIRST_SIGN
++              || psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bOrder == MCDRV_PCM_MSB_FIRST_ZERO
++              || psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bOrder == MCDRV_PCM_LSB_FIRST_ZERO)
++              {
++                      gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDir.sPcmFormat.bOrder       = psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bOrder;
++              }
++              if(psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bLaw == MCDRV_PCM_LINEAR
++              || psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bLaw == MCDRV_PCM_ALAW
++              || psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bLaw == MCDRV_PCM_MULAW)
++              {
++                      gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDir.sPcmFormat.bLaw = psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bLaw;
++              }
++              if(psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_8
++              || psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_13
++              || psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_14
++              || psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_16)
++              {
++                      gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDir.sPcmFormat.bBitSel      = psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bBitSel;
++              }
++      }
++      for(bDIOCh = 0; bDIOCh < DIO_CHANNELS; bDIOCh++)
++      {
++              if(psDioInfo->asPortInfo[bPort].sDir.abSlot[bDIOCh] < 2)
++              {
++                      gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDir.abSlot[bDIOCh]  = psDioInfo->asPortInfo[bPort].sDir.abSlot[bDIOCh];
++              }
++      }
++}
++
++/****************************************************************************
++ *    SetDIODIT
++ *
++ *    Description:
++ *                    Set digital io dit information.
++ *    Arguments:
++ *                    psDioInfo       digital io information
++ *                    bPort           port number
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetDIODIT
++(
++      const MCDRV_DIO_INFO*   psDioInfo,
++      UINT8   bPort
++)
++{
++      UINT8   bDIOCh;
++
++      gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDit.wSrcRate        = psDioInfo->asPortInfo[bPort].sDit.wSrcRate;
++      if(gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDioCommon.bInterface == MCDRV_DIO_DA)
++      {
++              if(psDioInfo->asPortInfo[bPort].sDit.sDaFormat.bBitSel == MCDRV_BITSEL_16
++              || psDioInfo->asPortInfo[bPort].sDit.sDaFormat.bBitSel == MCDRV_BITSEL_20
++              || psDioInfo->asPortInfo[bPort].sDit.sDaFormat.bBitSel == MCDRV_BITSEL_24)
++              {
++                      gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDit.sDaFormat.bBitSel       = psDioInfo->asPortInfo[bPort].sDit.sDaFormat.bBitSel;
++              }
++              if(psDioInfo->asPortInfo[bPort].sDit.sDaFormat.bMode == MCDRV_DAMODE_HEADALIGN
++              || psDioInfo->asPortInfo[bPort].sDit.sDaFormat.bMode == MCDRV_DAMODE_I2S
++              || psDioInfo->asPortInfo[bPort].sDit.sDaFormat.bMode == MCDRV_DAMODE_TAILALIGN)
++              {
++                      gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDit.sDaFormat.bMode = psDioInfo->asPortInfo[bPort].sDit.sDaFormat.bMode;
++              }
++      }
++      else if(gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDioCommon.bInterface == MCDRV_DIO_PCM)
++      {
++              if(psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bMono == MCDRV_PCM_STEREO
++              || psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bMono == MCDRV_PCM_MONO)
++              {
++                      gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDit.sPcmFormat.bMono        = psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bMono;
++              }
++              if(psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bOrder == MCDRV_PCM_MSB_FIRST
++              || psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bOrder == MCDRV_PCM_LSB_FIRST
++              || psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bOrder == MCDRV_PCM_MSB_FIRST_SIGN
++              || psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bOrder == MCDRV_PCM_LSB_FIRST_SIGN
++              || psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bOrder == MCDRV_PCM_MSB_FIRST_ZERO
++              || psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bOrder == MCDRV_PCM_LSB_FIRST_ZERO)
++              {
++                      gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDit.sPcmFormat.bOrder       = psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bOrder;
++              }
++              if(psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bLaw == MCDRV_PCM_LINEAR
++              || psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bLaw == MCDRV_PCM_ALAW
++              || psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bLaw == MCDRV_PCM_MULAW)
++              {
++                      gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDit.sPcmFormat.bLaw = psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bLaw;
++              }
++              if(psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_8
++              || psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_13
++              || psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_14
++              || psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_16)
++              {
++                      gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDit.sPcmFormat.bBitSel      = psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bBitSel;
++              }
++      }
++      for(bDIOCh = 0; bDIOCh < DIO_CHANNELS; bDIOCh++)
++      {
++              if(psDioInfo->asPortInfo[bPort].sDit.abSlot[bDIOCh] < 2)
++              {
++                      gsGlobalInfo_AA.sDioInfo.asPortInfo[bPort].sDit.abSlot[bDIOCh]  = psDioInfo->asPortInfo[bPort].sDit.abSlot[bDIOCh];
++              }
++      }
++}
++
++/****************************************************************************
++ *    McResCtrl_GetDioInfo_AA
++ *
++ *    Description:
++ *                    Get digital io information.
++ *    Arguments:
++ *                    psDioInfo       digital io information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetDioInfo_AA
++(
++      MCDRV_DIO_INFO* psDioInfo
++)
++{
++      *psDioInfo      = gsGlobalInfo_AA.sDioInfo;
++}
++
++/****************************************************************************
++ *    McResCtrl_SetVolInfo_AA
++ *
++ *    Description:
++ *                    Update volume.
++ *    Arguments:
++ *                    psVolInfo               volume setting
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetVolInfo_AA
++(
++      const MCDRV_VOL_INFO*   psVolInfo
++)
++{
++      UINT8   bCh;
++
++
++      for(bCh = 0; bCh < AD0_VOL_CHANNELS; bCh++)
++      {
++              if((psVolInfo->aswD_Ad0[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswD_Ad0[bCh]  = (psVolInfo->aswD_Ad0[bCh] & 0xFFFE);
++              }
++              if((psVolInfo->aswD_Ad0Att[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswD_Ad0Att[bCh]       = (psVolInfo->aswD_Ad0Att[bCh] & 0xFFFE);
++              }
++              if((psVolInfo->aswA_Ad0[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswA_Ad0[bCh]  = (psVolInfo->aswA_Ad0[bCh] & 0xFFFE);
++              }
++      }
++      for(bCh = 0; bCh < AD1_VOL_CHANNELS; bCh++)
++      {
++              if((psVolInfo->aswD_Ad1[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswD_Ad1[bCh]  = (psVolInfo->aswD_Ad1[bCh] & 0xFFFE);
++              }
++              if((psVolInfo->aswD_Ad1Att[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswD_Ad1Att[bCh]       = (psVolInfo->aswD_Ad1Att[bCh] & 0xFFFE);
++              }
++              if((psVolInfo->aswA_Ad1[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswA_Ad1[bCh]  = (psVolInfo->aswA_Ad1[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < AENG6_VOL_CHANNELS; bCh++)
++      {
++              if((psVolInfo->aswD_Aeng6[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswD_Aeng6[bCh]        = (psVolInfo->aswD_Aeng6[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < PDM_VOL_CHANNELS; bCh++)
++      {
++              if((psVolInfo->aswD_Pdm[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswD_Pdm[bCh]  = (psVolInfo->aswD_Pdm[bCh] & 0xFFFE);
++              }
++              if((psVolInfo->aswD_SideTone[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswD_SideTone[bCh]     = (psVolInfo->aswD_SideTone[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < DTMF_VOL_CHANNELS; bCh++)
++      {
++              if((psVolInfo->aswD_Dtmfb[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswD_Dtmfb[bCh]        = (psVolInfo->aswD_Dtmfb[bCh] & 0xFFFE);
++              }
++              if((psVolInfo->aswD_DtmfAtt[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswD_DtmfAtt[bCh]      = (psVolInfo->aswD_DtmfAtt[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < DIO0_VOL_CHANNELS; bCh++)
++      {
++              if((psVolInfo->aswD_Dir0[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswD_Dir0[bCh] = (psVolInfo->aswD_Dir0[bCh] & 0xFFFE);
++              }
++              if((psVolInfo->aswD_Dir0Att[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswD_Dir0Att[bCh]      = (psVolInfo->aswD_Dir0Att[bCh] & 0xFFFE);
++              }
++              if((psVolInfo->aswD_Dit0[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswD_Dit0[bCh] = (psVolInfo->aswD_Dit0[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < DIO1_VOL_CHANNELS; bCh++)
++      {
++              if((psVolInfo->aswD_Dir1[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswD_Dir1[bCh] = (psVolInfo->aswD_Dir1[bCh] & 0xFFFE);
++              }
++              if((psVolInfo->aswD_Dir1Att[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswD_Dir1Att[bCh]      = (psVolInfo->aswD_Dir1Att[bCh] & 0xFFFE);
++              }
++              if((psVolInfo->aswD_Dit1[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswD_Dit1[bCh] = (psVolInfo->aswD_Dit1[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < DIO2_VOL_CHANNELS; bCh++)
++      {
++              if((psVolInfo->aswD_Dir2[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswD_Dir2[bCh] = (psVolInfo->aswD_Dir2[bCh] & 0xFFFE);
++              }
++              if((psVolInfo->aswD_Dir2Att[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswD_Dir2Att[bCh]      = (psVolInfo->aswD_Dir2Att[bCh] & 0xFFFE);
++              }
++              if((psVolInfo->aswD_Dit2[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswD_Dit2[bCh] = (psVolInfo->aswD_Dit2[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < DAC_VOL_CHANNELS; bCh++)
++      {
++              if((psVolInfo->aswD_DacMaster[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswD_DacMaster[bCh]    = (psVolInfo->aswD_DacMaster[bCh] & 0xFFFE);
++              }
++              if((psVolInfo->aswD_DacVoice[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswD_DacVoice[bCh]     = (psVolInfo->aswD_DacVoice[bCh] & 0xFFFE);
++              }
++              if((psVolInfo->aswD_DacAtt[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswD_DacAtt[bCh]       = (psVolInfo->aswD_DacAtt[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < LIN1_VOL_CHANNELS; bCh++)
++      {
++              if((psVolInfo->aswA_Lin1[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswA_Lin1[bCh] = (psVolInfo->aswA_Lin1[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < LIN2_VOL_CHANNELS; bCh++)
++      {
++              if((psVolInfo->aswA_Lin2[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswA_Lin2[bCh] = (psVolInfo->aswA_Lin2[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < MIC1_VOL_CHANNELS; bCh++)
++      {
++              if((psVolInfo->aswA_Mic1[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswA_Mic1[bCh] = (psVolInfo->aswA_Mic1[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < MIC2_VOL_CHANNELS; bCh++)
++      {
++              if((psVolInfo->aswA_Mic2[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswA_Mic2[bCh] = (psVolInfo->aswA_Mic2[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < MIC3_VOL_CHANNELS; bCh++)
++      {
++              if((psVolInfo->aswA_Mic3[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswA_Mic3[bCh] = (psVolInfo->aswA_Mic3[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < HP_VOL_CHANNELS; bCh++)
++      {
++              if((psVolInfo->aswA_Hp[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswA_Hp[bCh]   = (psVolInfo->aswA_Hp[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < SP_VOL_CHANNELS; bCh++)
++      {
++              if((psVolInfo->aswA_Sp[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswA_Sp[bCh]   = (psVolInfo->aswA_Sp[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < RC_VOL_CHANNELS; bCh++)
++      {
++              if((psVolInfo->aswA_Rc[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswA_Rc[bCh]   = (psVolInfo->aswA_Rc[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < LOUT1_VOL_CHANNELS; bCh++)
++      {
++              if((psVolInfo->aswA_Lout1[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswA_Lout1[bCh]        = (psVolInfo->aswA_Lout1[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < LOUT2_VOL_CHANNELS; bCh++)
++      {
++              if((psVolInfo->aswA_Lout2[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswA_Lout2[bCh]        = (psVolInfo->aswA_Lout2[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < MIC1_VOL_CHANNELS; bCh++)
++      {
++              if((psVolInfo->aswA_Mic1Gain[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswA_Mic1Gain[bCh]     = (psVolInfo->aswA_Mic1Gain[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < MIC2_VOL_CHANNELS; bCh++)
++      {
++              if((psVolInfo->aswA_Mic2Gain[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswA_Mic2Gain[bCh]     = (psVolInfo->aswA_Mic2Gain[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < MIC3_VOL_CHANNELS; bCh++)
++      {
++              if((psVolInfo->aswA_Mic3Gain[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswA_Mic3Gain[bCh]     = (psVolInfo->aswA_Mic3Gain[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < HPGAIN_VOL_CHANNELS; bCh++)
++      {
++              if((psVolInfo->aswA_HpGain[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo_AA.sVolInfo.aswA_HpGain[bCh]       = (psVolInfo->aswA_HpGain[bCh] & 0xFFFE);
++              }
++      }
++}
++
++/****************************************************************************
++ *    McResCtrl_GetVolInfo_AA
++ *
++ *    Description:
++ *                    Get volume setting.
++ *    Arguments:
++ *                    psVolInfo               volume setting
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetVolInfo_AA
++(
++      MCDRV_VOL_INFO* psVolInfo
++)
++{
++      *psVolInfo      = gsGlobalInfo_AA.sVolInfo;
++}
++
++/****************************************************************************
++ *    McResCtrl_SetDacInfo_AA
++ *
++ *    Description:
++ *                    Set DAC information.
++ *    Arguments:
++ *                    psDacInfo       DAC information
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetDacInfo_AA
++(
++      const MCDRV_DAC_INFO*   psDacInfo,
++      UINT32  dUpdateInfo
++)
++{
++
++      if((dUpdateInfo & MCDRV_DAC_MSWP_UPDATE_FLAG) != 0)
++      {
++              switch(psDacInfo->bMasterSwap)
++              {
++              case    MCDRV_DSWAP_OFF:
++              case    MCDRV_DSWAP_SWAP:
++              case    MCDRV_DSWAP_MUTE:
++              case    MCDRV_DSWAP_RMVCENTER:
++              case    MCDRV_DSWAP_MONO:
++              case    MCDRV_DSWAP_MONOHALF:
++              case    MCDRV_DSWAP_BOTHL:
++              case    MCDRV_DSWAP_BOTHR:
++                      gsGlobalInfo_AA.sDacInfo.bMasterSwap    = psDacInfo->bMasterSwap;
++                      break;
++              default:
++                      break;
++              }
++      }
++      if((dUpdateInfo & MCDRV_DAC_VSWP_UPDATE_FLAG) != 0)
++      {
++              switch(psDacInfo->bVoiceSwap)
++              {
++              case    MCDRV_DSWAP_OFF:
++              case    MCDRV_DSWAP_SWAP:
++              case    MCDRV_DSWAP_MUTE:
++              case    MCDRV_DSWAP_RMVCENTER:
++              case    MCDRV_DSWAP_MONO:
++              case    MCDRV_DSWAP_MONOHALF:
++              case    MCDRV_DSWAP_BOTHL:
++              case    MCDRV_DSWAP_BOTHR:
++                      gsGlobalInfo_AA.sDacInfo.bVoiceSwap     = psDacInfo->bVoiceSwap;
++                      break;
++              default:
++                      break;
++              }
++      }
++      if((dUpdateInfo & MCDRV_DAC_HPF_UPDATE_FLAG) != 0)
++      {
++              if(psDacInfo->bDcCut == MCDRV_DCCUT_ON || psDacInfo->bDcCut == MCDRV_DCCUT_OFF)
++              {
++                      gsGlobalInfo_AA.sDacInfo.bDcCut = psDacInfo->bDcCut;
++              }
++      }
++}
++
++/****************************************************************************
++ *    McResCtrl_GetDacInfo_AA
++ *
++ *    Description:
++ *                    Get DAC information.
++ *    Arguments:
++ *                    psDacInfo       DAC information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetDacInfo_AA
++(
++      MCDRV_DAC_INFO* psDacInfo
++)
++{
++      *psDacInfo      = gsGlobalInfo_AA.sDacInfo;
++}
++
++/****************************************************************************
++ *    McResCtrl_SetAdcInfo_AA
++ *
++ *    Description:
++ *                    Set ADC information.
++ *    Arguments:
++ *                    psAdcInfo       ADC information
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetAdcInfo_AA
++(
++      const MCDRV_ADC_INFO*   psAdcInfo,
++      UINT32  dUpdateInfo
++)
++{
++
++      if((dUpdateInfo & MCDRV_ADCADJ_UPDATE_FLAG) != 0)
++      {
++              switch(psAdcInfo->bAgcAdjust)
++              {
++              case    MCDRV_AGCADJ_24:
++              case    MCDRV_AGCADJ_18:
++              case    MCDRV_AGCADJ_12:
++              case    MCDRV_AGCADJ_0:
++                      gsGlobalInfo_AA.sAdcInfo.bAgcAdjust     = psAdcInfo->bAgcAdjust;
++                      break;
++              default:
++                      break;
++              }
++      }
++      if((dUpdateInfo & MCDRV_ADCAGC_UPDATE_FLAG) != 0)
++      {
++              if(psAdcInfo->bAgcOn == MCDRV_AGC_OFF || psAdcInfo->bAgcOn == MCDRV_AGC_ON)
++              {
++                      gsGlobalInfo_AA.sAdcInfo.bAgcOn = psAdcInfo->bAgcOn;
++              }
++      }
++      if((dUpdateInfo & MCDRV_ADCMONO_UPDATE_FLAG) != 0)
++      {
++              if(psAdcInfo->bMono == MCDRV_ADC_STEREO || psAdcInfo->bMono == MCDRV_ADC_MONO)
++              {
++                      gsGlobalInfo_AA.sAdcInfo.bMono  = psAdcInfo->bMono;
++              }
++      }
++}
++
++/****************************************************************************
++ *    McResCtrl_GetAdcInfo_AA
++ *
++ *    Description:
++ *                    Get ADC information.
++ *    Arguments:
++ *                    psAdcInfo       ADC information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetAdcInfo_AA
++(
++      MCDRV_ADC_INFO* psAdcInfo
++)
++{
++      *psAdcInfo      = gsGlobalInfo_AA.sAdcInfo;
++}
++
++/****************************************************************************
++ *    McResCtrl_SetSpInfo_AA
++ *
++ *    Description:
++ *                    Set SP information.
++ *    Arguments:
++ *                    psSpInfo        SP information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetSpInfo_AA
++(
++      const MCDRV_SP_INFO*    psSpInfo
++)
++{
++
++      if(psSpInfo->bSwap == MCDRV_SPSWAP_OFF || psSpInfo->bSwap == MCDRV_SPSWAP_SWAP)
++      {
++              gsGlobalInfo_AA.sSpInfo.bSwap   = psSpInfo->bSwap;
++      }
++}
++
++/****************************************************************************
++ *    McResCtrl_GetSpInfo_AA
++ *
++ *    Description:
++ *                    Get SP information.
++ *    Arguments:
++ *                    psSpInfo        SP information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetSpInfo_AA
++(
++      MCDRV_SP_INFO*  psSpInfo
++)
++{
++      *psSpInfo       = gsGlobalInfo_AA.sSpInfo;
++}
++
++/****************************************************************************
++ *    McResCtrl_SetDngInfo_AA
++ *
++ *    Description:
++ *                    Set Digital Noise Gate information.
++ *    Arguments:
++ *                    psDngInfo       DNG information
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetDngInfo_AA
++(
++      const MCDRV_DNG_INFO*   psDngInfo,
++      UINT32  dUpdateInfo
++)
++{
++
++      if((dUpdateInfo & MCDRV_DNGSW_HP_UPDATE_FLAG) != 0)
++      {
++              if(psDngInfo->abOnOff[0] == MCDRV_DNG_OFF || psDngInfo->abOnOff[0] == MCDRV_DNG_ON)
++              {
++                      gsGlobalInfo_AA.sDngInfo.abOnOff[0]     = psDngInfo->abOnOff[0];
++              }
++      }
++      if((dUpdateInfo & MCDRV_DNGTHRES_HP_UPDATE_FLAG) != 0)
++      {
++              if(psDngInfo->abThreshold[0] <= MCDRV_DNG_THRES_72)
++              {
++                      gsGlobalInfo_AA.sDngInfo.abThreshold[0] = psDngInfo->abThreshold[0];
++              }
++      }
++      if((dUpdateInfo & MCDRV_DNGHOLD_HP_UPDATE_FLAG) != 0)
++      {
++              switch(psDngInfo->abHold[0])
++              {
++              case    MCDRV_DNG_HOLD_30:
++              case    MCDRV_DNG_HOLD_120:
++              case    MCDRV_DNG_HOLD_500:
++                      gsGlobalInfo_AA.sDngInfo.abHold[0]      = psDngInfo->abHold[0];
++                      break;
++              default:
++                      break;
++              }
++      }
++      if((dUpdateInfo & MCDRV_DNGATK_HP_UPDATE_FLAG) != 0)
++      {
++              if(psDngInfo->abAttack[0] == MCDRV_DNG_ATTACK_25)
++              {
++                      gsGlobalInfo_AA.sDngInfo.abAttack[0]    = psDngInfo->abAttack[0];
++              }
++              else if(psDngInfo->abAttack[0] == MCDRV_DNG_ATTACK_800)
++              {
++                      gsGlobalInfo_AA.sDngInfo.abAttack[0]    = 1/*MCDRV_DNG_ATTACK_800*/;
++              }
++      }
++      if((dUpdateInfo & MCDRV_DNGREL_HP_UPDATE_FLAG) != 0)
++      {
++              switch(psDngInfo->abRelease[0])
++              {
++              case    MCDRV_DNG_RELEASE_7950:
++              case    MCDRV_DNG_RELEASE_470:
++              case    MCDRV_DNG_RELEASE_940:
++                      gsGlobalInfo_AA.sDngInfo.abRelease[0]   = psDngInfo->abRelease[0];
++                      break;
++              default:
++                      break;
++              }
++      }
++}
++
++/****************************************************************************
++ *    McResCtrl_GetDngInfo_AA
++ *
++ *    Description:
++ *                    Get Digital Noise Gate information.
++ *    Arguments:
++ *                    psDngInfo       DNG information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetDngInfo_AA
++(
++      MCDRV_DNG_INFO* psDngInfo
++)
++{
++      *psDngInfo      = gsGlobalInfo_AA.sDngInfo;
++}
++
++/****************************************************************************
++ *    McResCtrl_SetAeInfo_AA
++ *
++ *    Description:
++ *                    Set Audio Engine information.
++ *    Arguments:
++ *                    psAeInfo        AE information
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetAeInfo_AA
++(
++      const MCDRV_AE_INFO*    psAeInfo,
++      UINT32  dUpdateInfo
++)
++{
++
++      if(McDevProf_IsValid(eMCDRV_FUNC_DBEX) == 1
++      && (dUpdateInfo & MCDRV_AEUPDATE_FLAG_BEXWIDE_ONOFF) != 0)
++      {
++              if((psAeInfo->bOnOff & MCDRV_BEXWIDE_ON) != 0)
++              {
++                      gsGlobalInfo_AA.sAeInfo.bOnOff  |= MCDRV_BEXWIDE_ON;
++              }
++              else
++              {
++                      gsGlobalInfo_AA.sAeInfo.bOnOff &= (UINT8)~MCDRV_BEXWIDE_ON;
++              }
++      }
++      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_DRC_ONOFF) != 0)
++      {
++              if((psAeInfo->bOnOff & MCDRV_DRC_ON) != 0)
++              {
++                      gsGlobalInfo_AA.sAeInfo.bOnOff  |= MCDRV_DRC_ON;
++              }
++              else
++              {
++                      gsGlobalInfo_AA.sAeInfo.bOnOff &= (UINT8)~MCDRV_DRC_ON;
++              }
++      }
++      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ5_ONOFF) != 0)
++      {
++              if((psAeInfo->bOnOff & MCDRV_EQ5_ON) != 0)
++              {
++                      gsGlobalInfo_AA.sAeInfo.bOnOff  |= MCDRV_EQ5_ON;
++              }
++              else
++              {
++                      gsGlobalInfo_AA.sAeInfo.bOnOff &= (UINT8)~MCDRV_EQ5_ON;
++              }
++      }
++      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ3_ONOFF) != 0)
++      {
++              if((psAeInfo->bOnOff & MCDRV_EQ3_ON) != 0)
++              {
++                      gsGlobalInfo_AA.sAeInfo.bOnOff  |= MCDRV_EQ3_ON;
++              }
++              else
++              {
++                      gsGlobalInfo_AA.sAeInfo.bOnOff &= (UINT8)~MCDRV_EQ3_ON;
++              }
++      }
++
++      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_BEX) != 0)
++      {
++              McSrv_MemCopy(psAeInfo->abBex, gsGlobalInfo_AA.sAeInfo.abBex, BEX_PARAM_SIZE);
++      }
++
++      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_WIDE) != 0)
++      {
++              McSrv_MemCopy(psAeInfo->abWide, gsGlobalInfo_AA.sAeInfo.abWide, WIDE_PARAM_SIZE);
++      }
++
++      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_DRC) != 0)
++      {
++              McSrv_MemCopy(psAeInfo->abDrc, gsGlobalInfo_AA.sAeInfo.abDrc, DRC_PARAM_SIZE);
++      }
++
++      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ5) != 0)
++      {
++              McSrv_MemCopy(psAeInfo->abEq5, gsGlobalInfo_AA.sAeInfo.abEq5, EQ5_PARAM_SIZE);
++      }
++
++      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ3) != 0)
++      {
++              McSrv_MemCopy(psAeInfo->abEq3, gsGlobalInfo_AA.sAeInfo.abEq3, EQ3_PARAM_SIZE);
++      }
++
++      if(McDevProf_IsValid(eMCDRV_FUNC_HWADJ) == 1)
++      {
++              gsGlobalInfo_AA.sAeInfo.bOnOff |= MCDRV_EQ3_ON;
++      }
++}
++
++/****************************************************************************
++ *    McResCtrl_GetAeInfo_AA
++ *
++ *    Description:
++ *                    Get Audio Engine information.
++ *    Arguments:
++ *                    psAeInfo        AE information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetAeInfo_AA
++(
++      MCDRV_AE_INFO*  psAeInfo
++)
++{
++      *psAeInfo       = gsGlobalInfo_AA.sAeInfo;
++}
++
++/****************************************************************************
++ *    McResCtrl_SetPdmInfo_AA
++ *
++ *    Description:
++ *                    Set PDM information.
++ *    Arguments:
++ *                    psPdmInfo       PDM information
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetPdmInfo_AA
++(
++      const MCDRV_PDM_INFO*   psPdmInfo,
++      UINT32  dUpdateInfo
++)
++{
++
++      if((dUpdateInfo & MCDRV_PDMCLK_UPDATE_FLAG) != 0)
++      {
++              switch(psPdmInfo->bClk)
++              {
++              case    MCDRV_PDM_CLK_128:
++              case    MCDRV_PDM_CLK_64:
++              case    MCDRV_PDM_CLK_32:
++                      gsGlobalInfo_AA.sPdmInfo.bClk   = psPdmInfo->bClk;
++                      break;
++              default:
++                      break;
++              }
++      }
++      if((dUpdateInfo & MCDRV_PDMADJ_UPDATE_FLAG) != 0)
++      {
++              switch(psPdmInfo->bAgcAdjust)
++              {
++              case    MCDRV_AGCADJ_24:
++              case    MCDRV_AGCADJ_18:
++              case    MCDRV_AGCADJ_12:
++              case    MCDRV_AGCADJ_0:
++                      gsGlobalInfo_AA.sPdmInfo.bAgcAdjust     = psPdmInfo->bAgcAdjust;
++                      break;
++              default:
++                      break;
++              }
++      }
++      if((dUpdateInfo & MCDRV_PDMAGC_UPDATE_FLAG) != 0)
++      {
++              switch(psPdmInfo->bAgcOn)
++              {
++              case    MCDRV_AGC_OFF:
++              case    MCDRV_AGC_ON:
++                      gsGlobalInfo_AA.sPdmInfo.bAgcOn = psPdmInfo->bAgcOn;
++                      break;
++              default:
++                      break;
++              }
++      }
++      if((dUpdateInfo & MCDRV_PDMEDGE_UPDATE_FLAG) != 0)
++      {
++              switch(psPdmInfo->bPdmEdge)
++              {
++              case    MCDRV_PDMEDGE_LH:
++              case    MCDRV_PDMEDGE_HL:
++                      gsGlobalInfo_AA.sPdmInfo.bPdmEdge       = psPdmInfo->bPdmEdge;
++                      break;
++              default:
++                      break;
++              }
++      }
++      if((dUpdateInfo & MCDRV_PDMWAIT_UPDATE_FLAG) != 0)
++      {
++              switch(psPdmInfo->bPdmWait)
++              {
++              case    MCDRV_PDMWAIT_0:
++              case    MCDRV_PDMWAIT_1:
++              case    MCDRV_PDMWAIT_10:
++              case    MCDRV_PDMWAIT_20:
++                      gsGlobalInfo_AA.sPdmInfo.bPdmWait       = psPdmInfo->bPdmWait;
++                      break;
++              default:
++                      break;
++              }
++      }
++      if((dUpdateInfo & MCDRV_PDMSEL_UPDATE_FLAG) != 0)
++      {
++              switch(psPdmInfo->bPdmSel)
++              {
++              case    MCDRV_PDMSEL_L1R2:
++              case    MCDRV_PDMSEL_L2R1:
++              case    MCDRV_PDMSEL_L1R1:
++              case    MCDRV_PDMSEL_L2R2:
++                      gsGlobalInfo_AA.sPdmInfo.bPdmSel        = psPdmInfo->bPdmSel;
++                      break;
++              default:
++                      break;
++              }
++      }
++      if((dUpdateInfo & MCDRV_PDMMONO_UPDATE_FLAG) != 0)
++      {
++              switch(psPdmInfo->bMono)
++              {
++              case    MCDRV_PDM_STEREO:
++              case    MCDRV_PDM_MONO:
++                      gsGlobalInfo_AA.sPdmInfo.bMono  = psPdmInfo->bMono;
++                      break;
++              default:
++                      break;
++              }
++      }
++}
++
++/****************************************************************************
++ *    McResCtrl_GetPdmInfo_AA
++ *
++ *    Description:
++ *                    Get PDM information.
++ *    Arguments:
++ *                    psPdmInfo       PDM information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetPdmInfo_AA
++(
++      MCDRV_PDM_INFO* psPdmInfo
++)
++{
++      *psPdmInfo      = gsGlobalInfo_AA.sPdmInfo;
++}
++
++/****************************************************************************
++ *    McResCtrl_SetGPMode_AA
++ *
++ *    Description:
++ *                    Set GP mode.
++ *    Arguments:
++ *                    psGpMode        GP mode
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetGPMode_AA
++(
++      const MCDRV_GP_MODE*    psGpMode
++)
++{
++      UINT8   bPad;
++
++
++      for(bPad = 0; bPad < GPIO_PAD_NUM; bPad++)
++      {
++              if(psGpMode->abGpDdr[bPad] == MCDRV_GPDDR_IN
++              || psGpMode->abGpDdr[bPad] == MCDRV_GPDDR_OUT)
++              {
++                      gsGlobalInfo_AA.sGpMode.abGpDdr[bPad]   = psGpMode->abGpDdr[bPad];
++              }
++              if(McDevProf_IsValid(eMCDRV_FUNC_GPMODE) == 1)
++              {
++                      if(psGpMode->abGpMode[bPad] == MCDRV_GPMODE_RISING
++                      || psGpMode->abGpMode[bPad] == MCDRV_GPMODE_FALLING
++                      || psGpMode->abGpMode[bPad] == MCDRV_GPMODE_BOTH)
++                      {
++                              gsGlobalInfo_AA.sGpMode.abGpMode[bPad]  = psGpMode->abGpMode[bPad];
++                      }
++                      if(psGpMode->abGpHost[bPad] == MCDRV_GPHOST_SCU
++                      || psGpMode->abGpHost[bPad] == MCDRV_GPHOST_CDSP)
++                      {
++                              gsGlobalInfo_AA.sGpMode.abGpHost[bPad]  = psGpMode->abGpHost[bPad];
++                      }
++                      if(psGpMode->abGpInvert[bPad] == MCDRV_GPINV_NORMAL
++                      || psGpMode->abGpInvert[bPad] == MCDRV_GPINV_INVERT)
++                      {
++                              gsGlobalInfo_AA.sGpMode.abGpInvert[bPad]        = psGpMode->abGpInvert[bPad];
++                      }
++              }
++      }
++}
++
++/****************************************************************************
++ *    McResCtrl_GetGPMode_AA
++ *
++ *    Description:
++ *                    Get GP mode.
++ *    Arguments:
++ *                    psGpMode        GP mode
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetGPMode_AA
++(
++      MCDRV_GP_MODE*  psGpMode
++)
++{
++      *psGpMode       = gsGlobalInfo_AA.sGpMode;
++}
++
++/****************************************************************************
++ *    McResCtrl_SetGPMask_AA
++ *
++ *    Description:
++ *                    Set GP mask.
++ *    Arguments:
++ *                    bMask   GP mask
++ *                    dPadNo  PAD Number
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetGPMask_AA
++(
++      UINT8   bMask,
++      UINT32  dPadNo
++)
++{
++      if(dPadNo == MCDRV_GP_PAD0)
++      {
++              if(gsGlobalInfo_AA.sInitInfo.bPad0Func == MCDRV_PAD_GPIO
++              && gsGlobalInfo_AA.sGpMode.abGpDdr[dPadNo] == MCDRV_GPDDR_IN)
++              {
++                      if(bMask == MCDRV_GPMASK_ON || bMask == MCDRV_GPMASK_OFF)
++                      {
++                              gsGlobalInfo_AA.abGpMask[dPadNo]        = bMask;
++                      }
++              }
++      }
++      else if(dPadNo == MCDRV_GP_PAD1)
++      {
++              if(gsGlobalInfo_AA.sInitInfo.bPad1Func == MCDRV_PAD_GPIO
++              && gsGlobalInfo_AA.sGpMode.abGpDdr[dPadNo] == MCDRV_GPDDR_IN)
++              {
++                      if(bMask == MCDRV_GPMASK_ON || bMask == MCDRV_GPMASK_OFF)
++                      {
++                              gsGlobalInfo_AA.abGpMask[dPadNo]        = bMask;
++                      }
++              }
++      }
++/*
++      else if(dPadNo == MCDRV_GP_PAD2)
++      {
++              if(gsGlobalInfo_AA.sInitInfo.bPad2Func == MCDRV_PAD_GPIO
++              && gsGlobalInfo_AA.sGpMode.abGpDdr[dPadNo] == MCDRV_GPDDR_IN)
++              {
++                      if(bMask == MCDRV_GPMASK_ON || bMask == MCDRV_GPMASK_OFF)
++                      {
++                              gsGlobalInfo_AA.abGpMask[dPadNo]        = bMask;
++                      }
++              }
++      }
++*/
++}
++
++/****************************************************************************
++ *    McResCtrl_GetGPMask_AA
++ *
++ *    Description:
++ *                    Get GP mask.
++ *    Arguments:
++ *                    pabMask GP mask
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetGPMask_AA
++(
++      UINT8*  pabMask
++)
++{
++      UINT8   bPadNo;
++      for(bPadNo = 0; bPadNo < GPIO_PAD_NUM; bPadNo++)
++      {
++              pabMask[bPadNo] = gsGlobalInfo_AA.abGpMask[bPadNo];
++      }
++}
++
++
++/****************************************************************************
++ *    McResCtrl_GetVolReg_AA
++ *
++ *    Description:
++ *                    Get value of volume registers.
++ *    Arguments:
++ *                    psVolInfo       volume information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetVolReg_AA
++(
++      MCDRV_VOL_INFO* psVolInfo
++)
++{
++      UINT8   bCh;
++      MCDRV_DST_CH    abDSTCh[]       = {eMCDRV_DST_CH0_AA, eMCDRV_DST_CH1_AA};
++      SINT16  swGainUp;
++
++
++      *psVolInfo      = gsGlobalInfo_AA.sVolInfo;
++
++      if(gsGlobalInfo_AA.sInitInfo.bDclGain == MCDRV_DCLGAIN_6)
++      {
++              swGainUp        = 6 * 256;
++      }
++      else if(gsGlobalInfo_AA.sInitInfo.bDclGain == MCDRV_DCLGAIN_12)
++      {
++              swGainUp        = 12 * 256;
++      }
++      else if(gsGlobalInfo_AA.sInitInfo.bDclGain == MCDRV_DCLGAIN_18)
++      {
++              swGainUp        = 18 * 256;
++      }
++      else
++      {
++              swGainUp        = 0;
++      }
++
++      psVolInfo->aswA_HpGain[0]       = MCDRV_REG_MUTE;
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_HP_AA, eMCDRV_DST_CH0_AA) == 0)
++      {
++              psVolInfo->aswA_Hp[0]   = MCDRV_REG_MUTE;
++      }
++      else
++      {
++              psVolInfo->aswA_Hp[0]           = GetHpVolReg(gsGlobalInfo_AA.sVolInfo.aswA_Hp[0]);
++              psVolInfo->aswA_HpGain[0]       = GetHpGainReg(gsGlobalInfo_AA.sVolInfo.aswA_HpGain[0]);
++      }
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_HP_AA, eMCDRV_DST_CH1_AA) == 0)
++      {
++              psVolInfo->aswA_Hp[1]   = MCDRV_REG_MUTE;
++      }
++      else
++      {
++              psVolInfo->aswA_Hp[1]   = GetHpVolReg(gsGlobalInfo_AA.sVolInfo.aswA_Hp[1]);
++              psVolInfo->aswA_HpGain[0]       = GetHpGainReg(gsGlobalInfo_AA.sVolInfo.aswA_HpGain[0]);
++      }
++
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_SP_AA, eMCDRV_DST_CH0_AA) == 0)
++      {
++              psVolInfo->aswA_Sp[0]   = MCDRV_REG_MUTE;
++      }
++      else
++      {
++              psVolInfo->aswA_Sp[0]   = GetSpVolReg(gsGlobalInfo_AA.sVolInfo.aswA_Sp[0]);
++      }
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_SP_AA, eMCDRV_DST_CH1_AA) == 0)
++      {
++              psVolInfo->aswA_Sp[1]   = MCDRV_REG_MUTE;
++      }
++      else
++      {
++              psVolInfo->aswA_Sp[1]   = GetSpVolReg(gsGlobalInfo_AA.sVolInfo.aswA_Sp[1]);
++      }
++
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_RCV_AA, eMCDRV_DST_CH0_AA) == 0)
++      {
++              psVolInfo->aswA_Rc[0]   = MCDRV_REG_MUTE;
++      }
++      else
++      {
++              psVolInfo->aswA_Rc[0]   = GetRcVolReg(gsGlobalInfo_AA.sVolInfo.aswA_Rc[0]);
++      }
++
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_LOUT1_AA, eMCDRV_DST_CH0_AA) == 0)
++      {
++              psVolInfo->aswA_Lout1[0]        = MCDRV_REG_MUTE;
++      }
++      else
++      {
++              psVolInfo->aswA_Lout1[0]        = GetLoVolReg(gsGlobalInfo_AA.sVolInfo.aswA_Lout1[0]);
++      }
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_LOUT1_AA, eMCDRV_DST_CH1_AA) == 0)
++      {
++              psVolInfo->aswA_Lout1[1]        = MCDRV_REG_MUTE;
++      }
++      else
++      {
++              psVolInfo->aswA_Lout1[1]        = GetLoVolReg(gsGlobalInfo_AA.sVolInfo.aswA_Lout1[1]);
++      }
++
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_LOUT2_AA, eMCDRV_DST_CH0_AA) == 0)
++      {
++              psVolInfo->aswA_Lout2[0]        = MCDRV_REG_MUTE;
++      }
++      else
++      {
++              psVolInfo->aswA_Lout2[0]        = GetLoVolReg(gsGlobalInfo_AA.sVolInfo.aswA_Lout2[0]);
++      }
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_LOUT2_AA, eMCDRV_DST_CH1_AA) == 0)
++      {
++              psVolInfo->aswA_Lout2[1]        = MCDRV_REG_MUTE;
++      }
++      else
++      {
++              psVolInfo->aswA_Lout2[1]        = GetLoVolReg(gsGlobalInfo_AA.sVolInfo.aswA_Lout2[1]);
++      }
++
++      for(bCh = 0; bCh < AD0_VOL_CHANNELS; bCh++)
++      {
++              if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_ADC0_AA, abDSTCh[bCh]) == 0)
++              {/*     ADC0 source all off     */
++                      psVolInfo->aswA_Ad0[bCh]        = MCDRV_REG_MUTE;
++                      psVolInfo->aswD_Ad0[bCh]        = MCDRV_REG_MUTE;
++              }
++              else
++              {
++                      psVolInfo->aswA_Ad0[bCh]        = GetADVolReg(gsGlobalInfo_AA.sVolInfo.aswA_Ad0[bCh]);
++                      psVolInfo->aswD_Ad0[bCh]        = GetDigitalVolReg(gsGlobalInfo_AA.sVolInfo.aswD_Ad0[bCh] - swGainUp);
++              }
++      }
++      if((gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON
++      || (gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON
++      || ((gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON
++              && (McResCtrl_GetAESource_AA() == eMCDRV_SRC_PDM_AA || McResCtrl_GetAESource_AA() == eMCDRV_SRC_ADC0_AA)))
++      {
++              for(bCh = 0; bCh < AD0_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Ad0Att[bCh]     = GetDigitalVolReg(gsGlobalInfo_AA.sVolInfo.aswD_Ad0Att[bCh]);
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < AD0_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Ad0Att[bCh]     = MCDRV_REG_MUTE;
++              }
++      }
++
++      if(McDevProf_IsValid(eMCDRV_FUNC_ADC1) == 1)
++      {
++              if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_ADC1_AA, eMCDRV_DST_CH0_AA) == 0)
++              {/*     ADC1 source all off     */
++                      for(bCh = 0; bCh < AD1_VOL_CHANNELS; bCh++)
++                      {
++                              psVolInfo->aswA_Ad1[bCh]        = MCDRV_REG_MUTE;
++                              psVolInfo->aswD_Ad1[bCh]        = MCDRV_REG_MUTE;
++                      }
++              }
++              else
++              {
++                      for(bCh = 0; bCh < AD1_VOL_CHANNELS; bCh++)
++                      {
++                              psVolInfo->aswA_Ad1[bCh]        = GetADVolReg(gsGlobalInfo_AA.sVolInfo.aswA_Ad1[bCh]);
++                              psVolInfo->aswD_Ad1[bCh]        = GetDigitalVolReg(gsGlobalInfo_AA.sVolInfo.aswD_Ad1[bCh] - swGainUp);
++                      }
++              }
++              if((gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC1_BLOCK] & MCDRV_SRC4_ADC1_ON) == MCDRV_SRC4_ADC1_ON)
++              {
++                      for(bCh = 0; bCh < AD1_VOL_CHANNELS; bCh++)
++                      {
++                              psVolInfo->aswD_Ad1Att[bCh]     = GetDigitalVolReg(gsGlobalInfo_AA.sVolInfo.aswD_Ad1Att[bCh]);
++                      }
++              }
++              else
++              {
++                      for(bCh = 0; bCh < AD1_VOL_CHANNELS; bCh++)
++                      {
++                              psVolInfo->aswD_Ad1Att[bCh]     = MCDRV_REG_MUTE;
++                      }
++              }
++      }
++
++      if(((gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++      || ((gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++      || ((gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++      || ((gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++      || ((gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++      || ((gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      || ((gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      || ((gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      || ((gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      || ((gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      || ((gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      || ((gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON))
++      {
++              psVolInfo->aswA_Lin1[0] = GetLIVolReg(gsGlobalInfo_AA.sVolInfo.aswA_Lin1[0]);
++      }
++      else
++      {
++              psVolInfo->aswA_Lin1[0] = MCDRV_REG_MUTE;
++      }
++
++      if(((gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON)
++      || ((gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON)
++      || ((gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON)
++      || ((gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON))
++      {
++              psVolInfo->aswA_Lin1[1] = GetLIVolReg(gsGlobalInfo_AA.sVolInfo.aswA_Lin1[1]);
++      }
++      else
++      {
++              psVolInfo->aswA_Lin1[1] = MCDRV_REG_MUTE;
++      }
++
++      if(McDevProf_IsValid(eMCDRV_FUNC_LI2) == 1)
++      {
++              psVolInfo->aswA_Lin2[0] = MCDRV_REG_MUTE;
++              psVolInfo->aswA_Lin2[1] = MCDRV_REG_MUTE;
++      }
++
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_MIC1_AA) == 0)
++      {/*     MIC1 is unused  */
++              for(bCh = 0; bCh < MIC1_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswA_Mic1[bCh]               = MCDRV_REG_MUTE;
++                      psVolInfo->aswA_Mic1Gain[bCh]   = (SINT16)(McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_MC_GAIN) & MCB_AA_MC1GAIN);
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < MIC1_VOL_CHANNELS; bCh++)
++              {
++                      if(((gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) != MCDRV_SRC0_MIC1_ON)
++                      && ((gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) != MCDRV_SRC0_MIC1_ON)
++                      && ((gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) != MCDRV_SRC0_MIC1_ON)
++                      && ((gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) != MCDRV_SRC0_MIC1_ON)
++                      && ((gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) != MCDRV_SRC0_MIC1_ON)
++                      && ((gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) != MCDRV_SRC0_MIC1_ON)
++                      && ((gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) != MCDRV_SRC0_MIC1_ON))
++                      {
++                              psVolInfo->aswA_Mic1[bCh]       = MCDRV_REG_MUTE;
++                      }
++                      else
++                      {
++                              psVolInfo->aswA_Mic1[bCh]       = GetMcVolReg(gsGlobalInfo_AA.sVolInfo.aswA_Mic1[bCh]);
++                      }
++                      psVolInfo->aswA_Mic1Gain[bCh]   = GetMcGainReg(gsGlobalInfo_AA.sVolInfo.aswA_Mic1Gain[bCh]);
++              }
++      }
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_MIC2_AA) == 0)
++      {/*     MIC2 is unused  */
++              for(bCh = 0; bCh < MIC2_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswA_Mic2[bCh]               = MCDRV_REG_MUTE;
++                      psVolInfo->aswA_Mic2Gain[bCh]   = (SINT16)((McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_MC_GAIN) & MCB_AA_MC2GAIN) >> 4);
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < MIC2_VOL_CHANNELS; bCh++)
++              {
++                      if(((gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) != MCDRV_SRC0_MIC2_ON)
++                      && ((gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) != MCDRV_SRC0_MIC2_ON)
++                      && ((gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) != MCDRV_SRC0_MIC2_ON)
++                      && ((gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) != MCDRV_SRC0_MIC2_ON)
++                      && ((gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) != MCDRV_SRC0_MIC2_ON)
++                      && ((gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) != MCDRV_SRC0_MIC2_ON)
++                      && ((gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) != MCDRV_SRC0_MIC2_ON))
++                      {
++                              psVolInfo->aswA_Mic2[bCh]       = MCDRV_REG_MUTE;
++                      }
++                      else
++                      {
++                              psVolInfo->aswA_Mic2[bCh]       = GetMcVolReg(gsGlobalInfo_AA.sVolInfo.aswA_Mic2[bCh]);
++                      }
++                      psVolInfo->aswA_Mic2Gain[bCh]   = GetMcGainReg(gsGlobalInfo_AA.sVolInfo.aswA_Mic2Gain[bCh]);
++              }
++      }
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_MIC3_AA) == 0)
++      {/*     MIC3 is unused  */
++              for(bCh = 0; bCh < MIC3_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswA_Mic3[bCh]               = MCDRV_REG_MUTE;
++                      psVolInfo->aswA_Mic3Gain[bCh]   = (SINT16)(McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_MC3_GAIN) & MCB_AA_MC3GAIN);
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < MIC3_VOL_CHANNELS; bCh++)
++              {
++                      if(((gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) != MCDRV_SRC0_MIC3_ON)
++                      && ((gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) != MCDRV_SRC0_MIC3_ON)
++                      && ((gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) != MCDRV_SRC0_MIC3_ON)
++                      && ((gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) != MCDRV_SRC0_MIC3_ON)
++                      && ((gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) != MCDRV_SRC0_MIC3_ON)
++                      && ((gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) != MCDRV_SRC0_MIC3_ON)
++                      && ((gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) != MCDRV_SRC0_MIC3_ON))
++                      {
++                              psVolInfo->aswA_Mic3[bCh]       = MCDRV_REG_MUTE;
++                      }
++                      else
++                      {
++                              psVolInfo->aswA_Mic3[bCh]       = GetMcVolReg(gsGlobalInfo_AA.sVolInfo.aswA_Mic3[bCh]);
++                      }
++                      psVolInfo->aswA_Mic3Gain[bCh]   = GetMcGainReg(gsGlobalInfo_AA.sVolInfo.aswA_Mic3Gain[bCh]);
++              }
++      }
++
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_DIR0_AA) == 0)
++      {/*     DIR0 is unused  */
++              for(bCh = 0; bCh < DIO0_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dir0[bCh]               = MCDRV_REG_MUTE;
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < DIO0_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dir0[bCh]               = GetDigitalVolReg(gsGlobalInfo_AA.sVolInfo.aswD_Dir0[bCh] - swGainUp);
++              }
++      }
++      if((gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) == MCDRV_SRC3_DIR0_ON
++      || ((gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON
++              && McResCtrl_GetAESource_AA() == eMCDRV_SRC_DIR0_AA))
++      {
++              for(bCh = 0; bCh < DIO0_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dir0Att[bCh]    = GetDigitalVolReg(gsGlobalInfo_AA.sVolInfo.aswD_Dir0Att[bCh]);
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < DIO0_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dir0Att[bCh]    = MCDRV_REG_MUTE;
++              }
++      }
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_DIR1_AA) == 0)
++      {/*     DIR1 is unused  */
++              for(bCh = 0; bCh < DIO1_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dir1[bCh]               = MCDRV_REG_MUTE;
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < DIO1_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dir1[bCh]               = GetDigitalVolReg(gsGlobalInfo_AA.sVolInfo.aswD_Dir1[bCh] - swGainUp);
++              }
++      }
++      if((gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) == MCDRV_SRC3_DIR1_ON
++      || ((gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON
++              && McResCtrl_GetAESource_AA() == eMCDRV_SRC_DIR1_AA))
++      {
++              for(bCh = 0; bCh < DIO1_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dir1Att[bCh]    = GetDigitalVolReg(gsGlobalInfo_AA.sVolInfo.aswD_Dir1Att[bCh]);
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < DIO1_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dir1Att[bCh]    = MCDRV_REG_MUTE;
++              }
++      }
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_DIR2_AA) == 0)
++      {/*     DIR2 is unused  */
++              for(bCh = 0; bCh < DIO2_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dir2[bCh]               = MCDRV_REG_MUTE;
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < DIO2_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dir2[bCh]               = GetDigitalVolReg(gsGlobalInfo_AA.sVolInfo.aswD_Dir2[bCh] - swGainUp);
++              }
++      }
++      if((gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) == MCDRV_SRC3_DIR2_ON
++      || ((gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON
++              && McResCtrl_GetAESource_AA() == eMCDRV_SRC_DIR2_AA))
++      {
++              for(bCh = 0; bCh < DIO2_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dir2Att[bCh]    = GetDigitalVolReg(gsGlobalInfo_AA.sVolInfo.aswD_Dir2Att[bCh]);
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < DIO2_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dir2Att[bCh]    = MCDRV_REG_MUTE;
++              }
++      }
++
++      if(McResCtrl_GetDITSource_AA(eMCDRV_DIO_0_AA) == eMCDRV_SRC_NONE_AA)
++      {/*     DIT0 source all off     */
++              for(bCh = 0; bCh < DIO0_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dit0[bCh]       = MCDRV_REG_MUTE;
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < DIO0_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dit0[bCh]       = GetDigitalVolReg(gsGlobalInfo_AA.sVolInfo.aswD_Dit0[bCh] + swGainUp);
++              }
++      }
++      if(McResCtrl_GetDITSource_AA(eMCDRV_DIO_1_AA) == eMCDRV_SRC_NONE_AA)
++      {/*     DIT1 source all off     */
++              for(bCh = 0; bCh < DIO1_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dit1[bCh]       = MCDRV_REG_MUTE;
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < DIO1_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dit1[bCh]       = GetDigitalVolReg(gsGlobalInfo_AA.sVolInfo.aswD_Dit1[bCh] + swGainUp);
++              }
++      }
++      if(McResCtrl_GetDITSource_AA(eMCDRV_DIO_2_AA) == eMCDRV_SRC_NONE_AA)
++      {/*     DIT2 source all off     */
++              for(bCh = 0; bCh < DIO2_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dit2[bCh]       = MCDRV_REG_MUTE;
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < DIO2_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dit2[bCh]       = GetDigitalVolReg(gsGlobalInfo_AA.sVolInfo.aswD_Dit2[bCh] + swGainUp);
++              }
++      }
++
++      if(McResCtrl_GetDACSource_AA(eMCDRV_DAC_MASTER_AA) == eMCDRV_SRC_NONE_AA
++      && McResCtrl_GetDACSource_AA(eMCDRV_DAC_VOICE_AA) == eMCDRV_SRC_NONE_AA)
++      {
++              for(bCh = 0; bCh < DAC_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_DacAtt[bCh]             = MCDRV_REG_MUTE;
++                      psVolInfo->aswD_DacMaster[bCh]  = MCDRV_REG_MUTE;
++                      psVolInfo->aswD_DacVoice[bCh]   = MCDRV_REG_MUTE;
++              }
++      }
++      else
++      {
++              if(McResCtrl_GetDACSource_AA(eMCDRV_DAC_MASTER_AA) == eMCDRV_SRC_NONE_AA)
++              {
++                      for(bCh = 0; bCh < DAC_VOL_CHANNELS; bCh++)
++                      {
++                              psVolInfo->aswD_DacMaster[bCh]  = MCDRV_REG_MUTE;
++                      }
++              }
++              else
++              {
++                      for(bCh = 0; bCh < DAC_VOL_CHANNELS; bCh++)
++                      {
++                              psVolInfo->aswD_DacMaster[bCh]  = GetDigitalVolReg(gsGlobalInfo_AA.sVolInfo.aswD_DacMaster[bCh]);
++                      }
++              }
++              if(McResCtrl_GetDACSource_AA(eMCDRV_DAC_VOICE_AA) == eMCDRV_SRC_NONE_AA)
++              {
++                      for(bCh = 0; bCh < DAC_VOL_CHANNELS; bCh++)
++                      {
++                              psVolInfo->aswD_DacVoice[bCh]   = MCDRV_REG_MUTE;
++                      }
++              }
++              else
++              {
++                      for(bCh = 0; bCh < DAC_VOL_CHANNELS; bCh++)
++                      {
++                              psVolInfo->aswD_DacVoice[bCh]   = GetDigitalVolReg(gsGlobalInfo_AA.sVolInfo.aswD_DacVoice[bCh]);
++                      }
++              }
++              for(bCh = 0; bCh < DAC_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_DacAtt[bCh]     = GetDigitalVolReg(gsGlobalInfo_AA.sVolInfo.aswD_DacAtt[bCh]);
++              }
++      }
++
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_PDM_AA) == 0
++      && McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_ADC0_AA) == 0)
++      {/*     PDM&ADC0 is unused      */
++              for(bCh = 0; bCh < AENG6_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Aeng6[bCh]      = MCDRV_REG_MUTE;
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < AENG6_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Aeng6[bCh]      = GetDigitalVolReg(gsGlobalInfo_AA.sVolInfo.aswD_Aeng6[bCh]);
++              }
++      }
++
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_PDM_AA) == 0)
++      {/*     PDM is unused   */
++              for(bCh = 0; bCh < PDM_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Pdm[bCh]                = MCDRV_REG_MUTE;
++                      psVolInfo->aswD_SideTone[bCh]   = MCDRV_REG_MUTE;
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < PDM_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Pdm[bCh]                = GetDigitalVolReg(gsGlobalInfo_AA.sVolInfo.aswD_Pdm[bCh] - swGainUp);
++                      psVolInfo->aswD_SideTone[bCh]   = GetDigitalVolReg(gsGlobalInfo_AA.sVolInfo.aswD_SideTone[bCh] - swGainUp);
++              }
++      }
++
++      if(McDevProf_IsValid(eMCDRV_FUNC_DTMF) == 1)
++      {
++              /*      DTMF    */
++              for(bCh = 0; bCh < DTMF_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dtmfb[bCh]              = GetDigitalVolReg(gsGlobalInfo_AA.sVolInfo.aswD_Dtmfb[bCh] - swGainUp);
++                      psVolInfo->aswD_DtmfAtt[bCh]    = GetDigitalVolReg(gsGlobalInfo_AA.sVolInfo.aswD_DtmfAtt[bCh] - swGainUp);
++              }
++      }
++}
++
++/****************************************************************************
++ *    GetDigitalVolReg
++ *
++ *    Description:
++ *                    Get value of digital volume registers.
++ *    Arguments:
++ *                    swVol   volume(dB value*256)
++ *    Return:
++ *                    value of registers
++ *
++ ****************************************************************************/
++static SINT16 GetDigitalVolReg
++(
++      SINT16  swVol
++)
++{
++      SINT16  swRet;
++
++      if(swVol < (-74*256))
++      {
++              swRet   = 0;
++      }
++      else if(swVol < 0)
++      {
++              swRet   = 96 + (swVol-128)/256;
++      }
++      else
++      {
++              swRet   = 96 + (swVol+128)/256;
++      }
++
++      if(swRet < 22)
++      {
++              swRet   = 0;
++      }
++
++      if(swRet > 114)
++      {
++              swRet   = 114;
++      }
++
++      return swRet;
++}
++
++/****************************************************************************
++ *    GetADVolReg
++ *
++ *    Description:
++ *                    Get update value of analog AD volume registers.
++ *    Arguments:
++ *                    swVol   volume(dB value*256)
++ *    Return:
++ *                    value of registers
++ *
++ ****************************************************************************/
++static SINT16 GetADVolReg
++(
++      SINT16  swVol
++)
++{
++      SINT16  swRet;
++
++      if(swVol < (-27*256))
++      {
++              swRet   = 0;
++      }
++      else if(swVol < 0)
++      {
++              swRet   = 19 + (swVol-192) * 2 / (256*3);
++      }
++      else
++      {
++              swRet   = 19 + (swVol+192) * 2 / (256*3);
++      }
++
++      if(swRet < 0)
++      {
++              swRet   = 0;
++      }
++
++      if(swRet > 31)
++      {
++              swRet   = 31;
++      }
++
++      return swRet;
++}
++
++/****************************************************************************
++ *    GetLIVolReg
++ *
++ *    Description:
++ *                    Get update value of analog LIN volume registers.
++ *    Arguments:
++ *                    swVol   volume(dB value*256)
++ *    Return:
++ *                    value of registers
++ *
++ ****************************************************************************/
++static SINT16 GetLIVolReg
++(
++      SINT16  swVol
++)
++{
++      SINT16  swRet;
++
++      if(swVol < (-30*256))
++      {
++              swRet   = 0;
++      }
++      else if(swVol < 0)
++      {
++              swRet   = 21 + (swVol-192) * 2 / (256*3);
++      }
++      else
++      {
++              swRet   = 21 + (swVol+192) * 2 / (256*3);
++      }
++
++      if(swRet < 0)
++      {
++              swRet   = 0;
++      }
++      if(swRet > 31)
++      {
++              swRet   = 31;
++      }
++      return swRet;
++}
++
++/****************************************************************************
++ *    GetMcVolReg
++ *
++ *    Description:
++ *                    Get update value of analog Mic volume registers.
++ *    Arguments:
++ *                    swVol   volume(dB value*256)
++ *    Return:
++ *                    value of registers
++ *
++ ****************************************************************************/
++static SINT16 GetMcVolReg
++(
++      SINT16  swVol
++)
++{
++      SINT16  swRet;
++
++      if(swVol < (-30*256))
++      {
++              swRet   = 0;
++      }
++      else if(swVol < 0)
++      {
++              swRet   = 21 + (swVol-192) * 2 / (256*3);
++      }
++      else
++      {
++              swRet   = 21 + (swVol+192) * 2 / (256*3);
++      }
++
++      if(swRet < 0)
++      {
++              swRet   = 0;
++      }
++      if(swRet > 31)
++      {
++              swRet   = 31;
++      }
++      return swRet;
++}
++
++/****************************************************************************
++ *    GetMcGainReg
++ *
++ *    Description:
++ *                    Get update value of analog Mic gain registers.
++ *    Arguments:
++ *                    swVol   volume(dB value*256)
++ *    Return:
++ *                    value of registers
++ *
++ ****************************************************************************/
++static SINT16 GetMcGainReg
++(
++      SINT16  swVol
++)
++{
++      SINT16  swGain  = (swVol+128)/256;
++
++      if(swGain < 18)
++      {
++              return 0;
++      }
++      if(swGain < 23)
++      {
++              return 1;
++      }
++      if(swGain < 28)
++      {
++              return 2;
++      }
++
++      return 3;
++}
++
++/****************************************************************************
++ *    GetHpVolReg
++ *
++ *    Description:
++ *                    Get update value of analog Hp volume registers.
++ *    Arguments:
++ *                    swVol   volume(dB value*256)
++ *    Return:
++ *                    value of registers
++ *
++ ****************************************************************************/
++static SINT16 GetHpVolReg
++(
++      SINT16  swVol
++)
++{
++      SINT16  swDB    = swVol/256;
++
++      if(swVol >= 0)
++      {
++              return 31;
++      }
++
++      if(swDB <= -8)
++      {
++              if(swVol < (-36*256))
++              {
++                      return 0;
++              }
++              if(swDB <= -32)
++              {
++                      return 1;
++              }
++              if(swDB <= -26)
++              {
++                      return 2;
++              }
++              if(swDB <= -23)
++              {
++                      return 3;
++              }
++              if(swDB <= -21)
++              {
++                      return 4;
++              }
++              if(swDB <= -19)
++              {
++                      return 5;
++              }
++              if(swDB <= -17)
++              {
++                      return 6;
++              }
++              return 23+(swVol-128)/256;
++      }
++
++      return 31 + (swVol-64)*2/256;
++}
++
++/****************************************************************************
++ *    GetHpGainReg
++ *
++ *    Description:
++ *                    Get update value of analog Hp gain registers.
++ *    Arguments:
++ *                    swVol   volume(dB value*256)
++ *    Return:
++ *                    value of registers
++ *
++ ****************************************************************************/
++static SINT16 GetHpGainReg
++(
++      SINT16  swVol
++)
++{
++      SINT16  swDB    = swVol/(256/4);
++
++      if(swDB < 3)
++      {
++              return 0;
++      }
++      if(swDB < 9)
++      {
++              return 1;
++      }
++      if(swDB < 18)
++      {
++              return 2;
++      }
++
++      return 3;
++}
++
++/****************************************************************************
++ *    GetSpVolReg
++ *
++ *    Description:
++ *                    Get update value of analog Sp volume registers.
++ *    Arguments:
++ *                    swVol   volume(dB value*256)
++ *    Return:
++ *                    value of registers
++ *
++ ****************************************************************************/
++static SINT16 GetSpVolReg
++(
++      SINT16  swVol
++)
++{
++      SINT16  swDB    = swVol/256;
++
++      if(swVol >= 0)
++      {
++              return 31;
++      }
++
++      if(swDB <= -8)
++      {
++              if(swVol < (-36*256))
++              {
++                      return 0;
++              }
++              if(swDB <= -32)
++              {
++                      return 1;
++              }
++              if(swDB <= -26)
++              {
++                      return 2;
++              }
++              if(swDB <= -23)
++              {
++                      return 3;
++              }
++              if(swDB <= -21)
++              {
++                      return 4;
++              }
++              if(swDB <= -19)
++              {
++                      return 5;
++              }
++              if(swDB <= -17)
++              {
++                      return 6;
++              }
++              return 23+(swVol-128)/256;
++      }
++
++      return 31 + (swVol-64)*2/256;
++}
++
++/****************************************************************************
++ *    GetRcVolReg
++ *
++ *    Description:
++ *                    Get update value of analog Rcv volume registers.
++ *    Arguments:
++ *                    swVol   volume(dB value*256)
++ *    Return:
++ *                    value of registers
++ *
++ ****************************************************************************/
++static SINT16 GetRcVolReg
++(
++      SINT16  swVol
++)
++{
++      SINT16  swRet   = 31 + (swVol-128)/256;
++      if(swVol < (-30*256))
++      {
++              swRet   = 0;
++      }
++      if(swRet < 0)
++      {
++              swRet   = 0;
++      }
++      if(swRet > 31)
++      {
++              swRet   = 31;
++      }
++      return swRet;
++}
++
++/****************************************************************************
++ *    GetLoVolReg
++ *
++ *    Description:
++ *                    Get update value of analog Lout volume registers.
++ *    Arguments:
++ *                    swVol   volume(dB value*256)
++ *    Return:
++ *                    value of registers
++ *
++ ****************************************************************************/
++static SINT16 GetLoVolReg
++(
++      SINT16  swVol
++)
++{
++      SINT16  swRet   = 31 + (swVol-128)/256;
++      if(swVol < (-30*256))
++      {
++              swRet   = 0;
++      }
++      if(swRet < 0)
++      {
++              swRet   = 0;
++      }
++      if(swRet > 31)
++      {
++              swRet   = 31;
++      }
++      return swRet;
++}
++
++/****************************************************************************
++ *    McResCtrl_GetPowerInfo_AA
++ *
++ *    Description:
++ *                    Get power information.
++ *    Arguments:
++ *                    psPowerInfo     power information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetPowerInfo_AA
++(
++      MCDRV_POWER_INFO_AA*    psPowerInfo
++)
++{
++      UINT8   i;
++      UINT8   bAnalogOn       = 0;
++      UINT8   bPowerMode      = gsGlobalInfo_AA.sInitInfo.bPowerMode;
++
++      /*      Digital power   */
++      psPowerInfo->dDigital   = 0;
++      if((bPowerMode & MCDRV_POWMODE_CLKON) == 0)
++      {
++              psPowerInfo->dDigital |= (MCDRV_POWINFO_DIGITAL_DP0_AA | MCDRV_POWINFO_DIGITAL_DP1_AA | MCDRV_POWINFO_DIGITAL_DP2_AA | MCDRV_POWINFO_DIGITAL_PLLRST0_AA);
++      }
++      if(McResCtrl_GetDITSource_AA(eMCDRV_DIO_0_AA)           != eMCDRV_SRC_NONE_AA
++      || McResCtrl_GetDITSource_AA(eMCDRV_DIO_1_AA)           != eMCDRV_SRC_NONE_AA
++      || McResCtrl_GetDITSource_AA(eMCDRV_DIO_2_AA)           != eMCDRV_SRC_NONE_AA
++      || McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_DAC_L_AA)  != 0
++      || McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_DAC_M_AA)  != 0
++      || McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_DAC_R_AA)  != 0
++      || McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_ADC0_AA)           != 0
++      || McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_AE_AA)             != 0
++      || McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_MIX_AA)            != 0)
++      {
++              /*      DP0-2, PLLRST0 on       */
++              psPowerInfo->dDigital &= ~(MCDRV_POWINFO_DIGITAL_DP0_AA | MCDRV_POWINFO_DIGITAL_DP1_AA | MCDRV_POWINFO_DIGITAL_DP2_AA | MCDRV_POWINFO_DIGITAL_PLLRST0_AA);
++      }
++      else
++      {
++              psPowerInfo->dDigital |= MCDRV_POWINFO_DIGITAL_DPB_AA;
++      }
++
++      /*      DPBDSP  */
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_AE_AA) == 0
++      || (gsGlobalInfo_AA.sAeInfo.bOnOff&(MCDRV_BEXWIDE_ON|MCDRV_DRC_ON)) == 0)
++      {
++              psPowerInfo->dDigital |= MCDRV_POWINFO_DIGITAL_DPBDSP_AA;
++      }
++
++      /*      DPADIF  */
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_ADC0_AA) == 0)
++      {
++              psPowerInfo->dDigital |= MCDRV_POWINFO_DIGITAL_DPADIF_AA;
++      }
++
++      /*      DPPDM   */
++      if(gsGlobalInfo_AA.sInitInfo.bPad0Func != MCDRV_PAD_PDMCK || McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_PDM_AA) == 0)
++      {
++              psPowerInfo->dDigital |= MCDRV_POWINFO_DIGITAL_DPPDM_AA;
++      }
++
++      /*      DPDI*   */
++      if(gsGlobalInfo_AA.sDioInfo.asPortInfo[0].sDioCommon.bMasterSlave == MCDRV_DIO_SLAVE
++      || (McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_DIR0_AA) == 0 && McResCtrl_GetDITSource_AA(eMCDRV_DIO_0_AA) == eMCDRV_SRC_NONE_AA))
++      {
++              psPowerInfo->dDigital |= MCDRV_POWINFO_DIGITAL_DPDI0_AA;
++      }
++      if(gsGlobalInfo_AA.sDioInfo.asPortInfo[1].sDioCommon.bMasterSlave == MCDRV_DIO_SLAVE
++      || (McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_DIR1_AA) == 0 && McResCtrl_GetDITSource_AA(eMCDRV_DIO_1_AA) == eMCDRV_SRC_NONE_AA))
++      {
++              psPowerInfo->dDigital |= MCDRV_POWINFO_DIGITAL_DPDI1_AA;
++      }
++      if(gsGlobalInfo_AA.sDioInfo.asPortInfo[2].sDioCommon.bMasterSlave == MCDRV_DIO_SLAVE
++      || (McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_DIR2_AA) == 0 && McResCtrl_GetDITSource_AA(eMCDRV_DIO_2_AA) == eMCDRV_SRC_NONE_AA))
++      {
++              psPowerInfo->dDigital |= MCDRV_POWINFO_DIGITAL_DPDI2_AA;
++      }
++
++      /*      Analog power    */
++      for(i = 0; i < 5; i++)
++      {
++              psPowerInfo->abAnalog[i]        = 0;
++      }
++
++      /*      SPL*    */
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_SP_AA, eMCDRV_DST_CH0_AA) == 0)
++      {
++              psPowerInfo->abAnalog[1] |= MCB_AA_PWM_SPL1;
++              psPowerInfo->abAnalog[1] |= MCB_AA_PWM_SPL2;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      /*      SPR*    */
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_SP_AA, eMCDRV_DST_CH1_AA) == 0)
++      {
++              psPowerInfo->abAnalog[1] |= MCB_AA_PWM_SPR1;
++              psPowerInfo->abAnalog[1] |= MCB_AA_PWM_SPR2;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++
++      /*      HPL     */
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_HP_AA, eMCDRV_DST_CH0_AA) == 0)
++      {
++              psPowerInfo->abAnalog[1] |= MCB_AA_PWM_HPL;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      /*      HPR     */
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_HP_AA, eMCDRV_DST_CH1_AA) == 0)
++      {
++              psPowerInfo->abAnalog[1] |= MCB_AA_PWM_HPR;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      /*      CP      */
++      if((psPowerInfo->abAnalog[1] & MCB_AA_PWM_HPL) != 0 && (psPowerInfo->abAnalog[1] & MCB_AA_PWM_HPR) != 0)
++      {
++              psPowerInfo->abAnalog[0] |= MCB_AA_PWM_CP;
++      }
++
++      /*      LOUT1L  */
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_LOUT1_AA, eMCDRV_DST_CH0_AA) == 0)
++      {
++              psPowerInfo->abAnalog[2] |= MCB_AA_PWM_LO1L;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      /*      LOUT1R  */
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_LOUT1_AA, eMCDRV_DST_CH1_AA) == 0)
++      {
++              psPowerInfo->abAnalog[2] |= MCB_AA_PWM_LO1R;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      /*      LOUT2L  */
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_LOUT2_AA, eMCDRV_DST_CH0_AA) == 0)
++      {
++              psPowerInfo->abAnalog[2] |= MCB_AA_PWM_LO2L;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      /*      LOUT2R  */
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_LOUT2_AA, eMCDRV_DST_CH1_AA) == 0)
++      {
++              psPowerInfo->abAnalog[2] |= MCB_AA_PWM_LO2R;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      /*      RCV     */
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_RCV_AA, eMCDRV_DST_CH0_AA) == 0)
++      {
++              psPowerInfo->abAnalog[2] |= MCB_AA_PWM_RC1;
++              psPowerInfo->abAnalog[2] |= MCB_AA_PWM_RC2;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      /*      DA      */
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_DAC_AA, eMCDRV_DST_CH0_AA) == 0
++      && McResCtrl_IsDstUsed_AA(eMCDRV_DST_DAC_AA, eMCDRV_DST_CH1_AA) == 0)
++      {
++              psPowerInfo->abAnalog[3] |= MCB_AA_PWM_DA;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      /*      ADC0L   */
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_ADC0_AA, eMCDRV_DST_CH0_AA) == 1)
++      {
++              bAnalogOn       = 1;
++      }
++      else
++      {
++              if(McDevProf_IsValid(eMCDRV_FUNC_LI2) == 1
++              && ((gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE2_L_BLOCK] & MCDRV_SRC2_LINE2_L_ON) == MCDRV_SRC2_LINE2_L_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE2_M_BLOCK] & MCDRV_SRC2_LINE2_M_ON) == MCDRV_SRC2_LINE2_M_ON))
++              {
++                      bAnalogOn       = 1;
++              }
++              else
++              {
++                      psPowerInfo->abAnalog[1] |= MCB_AA_PWM_ADL;
++              }
++      }
++      /*      ADC0R   */
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_ADC0_AA, eMCDRV_DST_CH1_AA) == 1)
++      {
++              bAnalogOn       = 1;
++      }
++      else
++      {
++              if(McDevProf_IsValid(eMCDRV_FUNC_LI2) == 1
++              && ((gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE2_R_BLOCK] & MCDRV_SRC2_LINE2_R_ON) == MCDRV_SRC2_LINE2_R_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE2_M_BLOCK] & MCDRV_SRC2_LINE2_M_ON) == MCDRV_SRC2_LINE2_M_ON))
++              {
++                      bAnalogOn       = 1;
++              }
++              else
++              {
++                      psPowerInfo->abAnalog[1] |= MCB_AA_PWM_ADR;
++              }
++      }
++      if(McDevProf_IsValid(eMCDRV_FUNC_ADC1) == 1)
++      {
++      }
++      /*      LI      */
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_LINE1_L_AA) == 0
++      && McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_LINE1_M_AA) == 0
++      && McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_LINE1_R_AA) == 0)
++      {
++              psPowerInfo->abAnalog[4] |= MCB_AA_PWM_LI;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      if(McDevProf_IsValid(eMCDRV_FUNC_LI2) == 1)
++      {
++              if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_LINE2_L_AA) == 0
++              && McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_LINE2_M_AA) == 0
++              && McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_LINE2_R_AA) == 0)
++              {
++                      /*psPowerInfo->abAnalog[4] |= MCB_AA_PWM_LI2;*/
++              }
++              else
++              {
++                      bAnalogOn       = 1;
++              }
++      }
++      /*      MC1     */
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_MIC1_AA) == 0)
++      {
++              psPowerInfo->abAnalog[4] |= MCB_AA_PWM_MC1;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      /*      MC2     */
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_MIC2_AA) == 0)
++      {
++              psPowerInfo->abAnalog[4] |= MCB_AA_PWM_MC2;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      /*      MC3     */
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_MIC3_AA) == 0)
++      {
++              psPowerInfo->abAnalog[4] |= MCB_AA_PWM_MC3;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      if((gsGlobalInfo_AA.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) != MCDRV_SRC0_MIC1_ON)
++      {
++              psPowerInfo->abAnalog[3] |= MCB_AA_PWM_MB1;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      if((gsGlobalInfo_AA.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) != MCDRV_SRC0_MIC2_ON)
++      {
++              psPowerInfo->abAnalog[3] |= MCB_AA_PWM_MB2;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      if((gsGlobalInfo_AA.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) != MCDRV_SRC0_MIC3_ON)
++      {
++              psPowerInfo->abAnalog[3] |= MCB_AA_PWM_MB3;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++
++      /*      VR/LDOA/REFA    */
++      if ((0 == bAnalogOn) && ((bPowerMode & MCDRV_POWMODE_VREFON) == 0))
++      {
++              psPowerInfo->abAnalog[0] |= MCB_AA_PWM_VR;
++              psPowerInfo->abAnalog[0] |= MCB_AA_PWM_REFA;
++              psPowerInfo->abAnalog[0] |= MCB_AA_PWM_LDOA;
++      }
++      else
++      {
++              if (MCDRV_LDO_OFF == gsGlobalInfo_AA.sInitInfo.bLdo)
++              {
++                      psPowerInfo->abAnalog[0] |= MCB_AA_PWM_LDOA;
++              }
++              else
++              {
++                      psPowerInfo->abAnalog[0] |= MCB_AA_PWM_REFA;
++              }
++      }
++}
++
++/****************************************************************************
++ *    McResCtrl_GetPowerInfoRegAccess_AA
++ *
++ *    Description:
++ *                    Get power information to access register.
++ *    Arguments:
++ *                    psRegInfo       register information
++ *                    psPowerInfo     power information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetPowerInfoRegAccess_AA
++(
++      const MCDRV_REG_INFO*   psRegInfo,
++      MCDRV_POWER_INFO_AA*            psPowerInfo
++)
++{
++
++      McResCtrl_GetPowerInfo_AA(psPowerInfo);
++
++      switch(psRegInfo->bRegType)
++      {
++      default:
++      case    MCDRV_REGTYPE_A:
++      case    MCDRV_REGTYPE_B_BASE:
++      case    MCDRV_REGTYPE_B_AE:
++              break;
++      case    MCDRV_REGTYPE_B_ANALOG:
++              switch(psRegInfo->bAddress)
++              {
++              case    MCI_AA_AMP:
++              case    MCI_AA_DNGATRT:
++              case    MCI_AA_HPVOL_L:
++              case    MCI_AA_HPVOL_R:
++              case    MCI_AA_SPVOL_L:
++              case    MCI_AA_SPVOL_R:
++              case    MCI_AA_RCVOL:
++              case    MCI_AA_ADL_MIX:
++              case    MCI_AA_ADL_MONO:
++              case    MCI_AA_ADR_MIX:
++              case    MCI_AA_ADR_MONO:
++              case    MCI_AA_LO1L_MIX:
++              case    MCI_AA_LO1L_MONO:
++              case    MCI_AA_LO1R_MIX:
++              case    MCI_AA_LO2L_MIX:
++              case    MCI_AA_LO2L_MONO:
++              case    MCI_AA_LO2R_MIX:
++              case    MCI_AA_HPL_MIX:
++              case    MCI_AA_HPL_MONO:
++              case    MCI_AA_HPR_MIX:
++              case    MCI_AA_SPL_MIX:
++              case    MCI_AA_SPL_MONO:
++              case    MCI_AA_SPR_MIX:
++              case    MCI_AA_SPR_MONO:
++              case    MCI_AA_RC_MIX:
++                      psPowerInfo->abAnalog[0]        &= (UINT8)~MCB_AA_PWM_VR;
++                      break;
++              case    MCI_AA_DNGON:
++                      psPowerInfo->dDigital   &= ~(MCDRV_POWINFO_DIGITAL_DP0_AA | MCDRV_POWINFO_DIGITAL_DP1_AA
++                                                                                              | MCDRV_POWINFO_DIGITAL_DP2_AA | MCDRV_POWINFO_DIGITAL_PLLRST0_AA);
++                      break;
++              default:
++                      break;
++              }
++              break;
++
++      case    MCDRV_REGTYPE_B_CODEC:
++              if(psRegInfo->bAddress == MCI_AA_DPADIF || psRegInfo->bAddress == MCI_AA_CD_HW_ID)
++              {
++                      break;
++              }
++              psPowerInfo->dDigital   &= ~(MCDRV_POWINFO_DIGITAL_DP0_AA | MCDRV_POWINFO_DIGITAL_DP1_AA
++                                                                                      | MCDRV_POWINFO_DIGITAL_DP2_AA | MCDRV_POWINFO_DIGITAL_PLLRST0_AA | MCDRV_POWINFO_DIGITAL_DPB_AA);
++              break;
++
++      case    MCDRV_REGTYPE_B_MIXER:
++              psPowerInfo->dDigital   &= ~(MCDRV_POWINFO_DIGITAL_DP0_AA | MCDRV_POWINFO_DIGITAL_DP1_AA
++                                                                                      | MCDRV_POWINFO_DIGITAL_DP2_AA | MCDRV_POWINFO_DIGITAL_PLLRST0_AA | MCDRV_POWINFO_DIGITAL_DPB_AA);
++              break;
++
++      case    MCDRV_REGTYPE_B_CDSP:
++              break;
++      }
++}
++
++/****************************************************************************
++ *    McResCtrl_GetCurPowerInfo_AA
++ *
++ *    Description:
++ *                    Get current power setting.
++ *    Arguments:
++ *                    psPowerInfo     power information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetCurPowerInfo_AA
++(
++      MCDRV_POWER_INFO_AA*    psPowerInfo
++)
++{
++      UINT8   bReg;
++
++
++      psPowerInfo->abAnalog[0]        = gsGlobalInfo_AA.abRegValB_ANA[MCI_AA_PWM_ANALOG_0];
++      psPowerInfo->abAnalog[1]        = gsGlobalInfo_AA.abRegValB_ANA[MCI_AA_PWM_ANALOG_1];
++      psPowerInfo->abAnalog[2]        = gsGlobalInfo_AA.abRegValB_ANA[MCI_AA_PWM_ANALOG_2];
++      psPowerInfo->abAnalog[3]        = gsGlobalInfo_AA.abRegValB_ANA[MCI_AA_PWM_ANALOG_3];
++      psPowerInfo->abAnalog[4]        = gsGlobalInfo_AA.abRegValB_ANA[MCI_AA_PWM_ANALOG_4];
++
++      psPowerInfo->dDigital   = 0;
++      bReg    = gsGlobalInfo_AA.abRegValB_BASE[MCI_AA_PWM_DIGITAL];
++      if((bReg & MCB_AA_PWM_DP0) == MCB_AA_PWM_DP0)
++      {
++              psPowerInfo->dDigital   |= MCDRV_POWINFO_DIGITAL_DP0_AA;
++      }
++      if((bReg & MCB_AA_PWM_DP1) == MCB_AA_PWM_DP1)
++      {
++              psPowerInfo->dDigital   |= MCDRV_POWINFO_DIGITAL_DP1_AA;
++      }
++      if((bReg & MCB_AA_PWM_DP2) == MCB_AA_PWM_DP2)
++      {
++              psPowerInfo->dDigital   |= MCDRV_POWINFO_DIGITAL_DP2_AA;
++      }
++
++      bReg    = gsGlobalInfo_AA.abRegValB_BASE[MCI_AA_PWM_DIGITAL_1];
++      if((bReg & MCB_AA_PWM_DPB) == MCB_AA_PWM_DPB)
++      {
++              psPowerInfo->dDigital   |= MCDRV_POWINFO_DIGITAL_DPB_AA;
++      }
++      if((bReg & MCB_AA_PWM_DPDI0) == MCB_AA_PWM_DPDI0)
++      {
++              psPowerInfo->dDigital   |= MCDRV_POWINFO_DIGITAL_DPDI0_AA;
++      }
++      if((bReg & MCB_AA_PWM_DPDI1) == MCB_AA_PWM_DPDI1)
++      {
++              psPowerInfo->dDigital   |= MCDRV_POWINFO_DIGITAL_DPDI1_AA;
++      }
++      if((bReg & MCB_AA_PWM_DPDI2) == MCB_AA_PWM_DPDI2)
++      {
++              psPowerInfo->dDigital   |= MCDRV_POWINFO_DIGITAL_DPDI2_AA;
++      }
++      if((bReg & MCB_AA_PWM_DPPDM) == MCB_AA_PWM_DPPDM)
++      {
++              psPowerInfo->dDigital   |= MCDRV_POWINFO_DIGITAL_DPPDM_AA;
++      }
++
++      bReg    = gsGlobalInfo_AA.abRegValB_BASE[MCI_AA_PWM_DIGITAL_BDSP];
++      if((bReg & MCB_AA_PWM_DPBDSP) == MCB_AA_PWM_DPBDSP)
++      {
++              psPowerInfo->dDigital   |= MCDRV_POWINFO_DIGITAL_DPBDSP_AA;
++      }
++
++      bReg    = gsGlobalInfo_AA.abRegValB_BASE[MCI_AA_PLL_RST];
++      if((bReg & MCB_AA_PLLRST0) == MCB_AA_PLLRST0)
++      {
++              psPowerInfo->dDigital   |= MCDRV_POWINFO_DIGITAL_PLLRST0_AA;
++      }
++
++      bReg    = gsGlobalInfo_AA.abRegValB_CODEC[MCI_AA_DPADIF];
++      if((bReg & MCB_AA_DPADIF) == MCB_AA_DPADIF)
++      {
++              psPowerInfo->dDigital   |= MCDRV_POWINFO_DIGITAL_DPADIF_AA;
++      }
++}
++
++/****************************************************************************
++ *    McResCtrl_GetDACSource_AA
++ *
++ *    Description:
++ *                    Get DAC source information.
++ *    Arguments:
++ *                    eCh     0:Master/1:Voice
++ *    Return:
++ *                    path source(MCDRV_SRC_TYPE_AA)
++ *
++ ****************************************************************************/
++MCDRV_SRC_TYPE_AA     McResCtrl_GetDACSource_AA
++(
++      MCDRV_DAC_CH_AA eCh
++)
++{
++
++      if((gsGlobalInfo_AA.sPathInfo.asDac[eCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON)
++      {
++              return eMCDRV_SRC_PDM_AA;
++      }
++      else if((gsGlobalInfo_AA.sPathInfo.asDac[eCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON)
++      {
++              return eMCDRV_SRC_ADC0_AA;
++      }
++      else if((gsGlobalInfo_AA.sPathInfo.asDac[eCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) == MCDRV_SRC3_DIR0_ON)
++      {
++              return eMCDRV_SRC_DIR0_AA;
++      }
++      else if((gsGlobalInfo_AA.sPathInfo.asDac[eCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) == MCDRV_SRC3_DIR1_ON)
++      {
++              return eMCDRV_SRC_DIR1_AA;
++      }
++      else if((gsGlobalInfo_AA.sPathInfo.asDac[eCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) == MCDRV_SRC3_DIR2_ON)
++      {
++              return eMCDRV_SRC_DIR2_AA;
++      }
++      else if((gsGlobalInfo_AA.sPathInfo.asDac[eCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & MCDRV_SRC6_MIX_ON) == MCDRV_SRC6_MIX_ON)
++      {
++              return eMCDRV_SRC_MIX_AA;
++      }
++      else if((gsGlobalInfo_AA.sPathInfo.asDac[eCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON)
++      {
++              return McResCtrl_GetAESource_AA();
++      }
++      return eMCDRV_SRC_NONE_AA;
++}
++
++/****************************************************************************
++ *    McResCtrl_GetDITSource_AA
++ *
++ *    Description:
++ *                    Get DIT source information.
++ *    Arguments:
++ *                    ePort   port number
++ *    Return:
++ *                    path source(MCDRV_SRC_TYPE_AA)
++ *
++ ****************************************************************************/
++MCDRV_SRC_TYPE_AA     McResCtrl_GetDITSource_AA
++(
++      MCDRV_DIO_PORT_NO_AA    ePort
++)
++{
++      MCDRV_CHANNEL*  pasDit;
++
++      if(ePort == 0)
++      {
++              pasDit  = &gsGlobalInfo_AA.sPathInfo.asDit0[0];
++      }
++      else if(ePort == 1)
++      {
++              pasDit  = &gsGlobalInfo_AA.sPathInfo.asDit1[0];
++      }
++      else if(ePort == 2)
++      {
++              pasDit  = &gsGlobalInfo_AA.sPathInfo.asDit2[0];
++      }
++      else
++      {
++              return eMCDRV_SRC_NONE_AA;
++      }
++
++      if((pasDit->abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON)
++      {
++              return eMCDRV_SRC_PDM_AA;
++      }
++      else if((pasDit->abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON)
++      {
++              return eMCDRV_SRC_ADC0_AA;
++      }
++      else if((pasDit->abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) == MCDRV_SRC3_DIR0_ON)
++      {
++              return eMCDRV_SRC_DIR0_AA;
++      }
++      else if((pasDit->abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) == MCDRV_SRC3_DIR1_ON)
++      {
++              return eMCDRV_SRC_DIR1_AA;
++      }
++      else if((pasDit->abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) == MCDRV_SRC3_DIR2_ON)
++      {
++              return eMCDRV_SRC_DIR2_AA;
++      }
++      else if((pasDit->abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & MCDRV_SRC6_MIX_ON) == MCDRV_SRC6_MIX_ON)
++      {
++              return eMCDRV_SRC_MIX_AA;
++      }
++      else if((pasDit->abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON)
++      {
++              return McResCtrl_GetAESource_AA();
++      }
++      return eMCDRV_SRC_NONE_AA;
++}
++
++/****************************************************************************
++ *    McResCtrl_GetAESource_AA
++ *
++ *    Description:
++ *                    Get AE source information.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    path source(MCDRV_SRC_TYPE_AA)
++ *
++ ****************************************************************************/
++MCDRV_SRC_TYPE_AA     McResCtrl_GetAESource_AA
++(
++void
++)
++{
++      if((gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON)
++      {
++              return eMCDRV_SRC_PDM_AA;
++      }
++      else if((gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON)
++      {
++              return eMCDRV_SRC_ADC0_AA;
++      }
++      else if((gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) == MCDRV_SRC3_DIR0_ON)
++      {
++              return eMCDRV_SRC_DIR0_AA;
++      }
++      else if((gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) == MCDRV_SRC3_DIR1_ON)
++      {
++              return eMCDRV_SRC_DIR1_AA;
++      }
++      else if((gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) == MCDRV_SRC3_DIR2_ON)
++      {
++              return eMCDRV_SRC_DIR2_AA;
++      }
++      else if((gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & MCDRV_SRC6_MIX_ON) == MCDRV_SRC6_MIX_ON)
++      {
++              return eMCDRV_SRC_MIX_AA;
++      }
++      return eMCDRV_SRC_NONE_AA;
++}
++
++/****************************************************************************
++ *    McResCtrl_IsSrcUsed_AA
++ *
++ *    Description:
++ *                    Is Src used
++ *    Arguments:
++ *                    ePathSrc        path src type
++ *    Return:
++ *                    0:unused/1:used
++ *
++ ****************************************************************************/
++UINT8 McResCtrl_IsSrcUsed_AA
++(
++      MCDRV_SRC_TYPE_AA       ePathSrc
++)
++{
++      UINT8   bUsed   = 0;
++
++      switch(ePathSrc)
++      {
++      case    eMCDRV_SRC_MIC1_AA:
++              if((gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON
++              || (gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON
++              || (gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON
++              || (gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON
++              || (gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON)
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_MIC2_AA:
++              if((gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON
++              || (gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON
++              || (gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON
++              || (gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON
++              || (gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON)
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_MIC3_AA:
++              if((gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON
++              || (gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON
++              || (gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON
++              || (gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON
++              || (gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON)
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_LINE1_L_AA:
++              if((gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON
++              || (gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON
++              || (gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_LINE1_R_AA:
++              if((gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON
++              || (gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON
++              || (gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON)
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_LINE1_M_AA:
++              if((gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON
++              || (gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON
++              || (gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON
++              || (gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON
++              || (gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON
++              || (gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_LINE2_L_AA:
++              if((gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE2_L_BLOCK] & MCDRV_SRC2_LINE2_L_ON) == MCDRV_SRC2_LINE2_L_ON
++              || (gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE2_L_BLOCK] & MCDRV_SRC2_LINE2_L_ON) == MCDRV_SRC2_LINE2_L_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE2_L_BLOCK] & MCDRV_SRC2_LINE2_L_ON) == MCDRV_SRC2_LINE2_L_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE2_L_BLOCK] & MCDRV_SRC2_LINE2_L_ON) == MCDRV_SRC2_LINE2_L_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE2_L_BLOCK] & MCDRV_SRC2_LINE2_L_ON) == MCDRV_SRC2_LINE2_L_ON
++              || (gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE2_L_BLOCK] & MCDRV_SRC2_LINE2_L_ON) == MCDRV_SRC2_LINE2_L_ON)
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_LINE2_R_AA:
++              if((gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_LINE2_R_BLOCK] & MCDRV_SRC2_LINE2_R_ON) == MCDRV_SRC2_LINE2_R_ON
++              || (gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE2_R_BLOCK] & MCDRV_SRC2_LINE2_R_ON) == MCDRV_SRC2_LINE2_R_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_LINE2_R_BLOCK] & MCDRV_SRC2_LINE2_R_ON) == MCDRV_SRC2_LINE2_R_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_LINE2_R_BLOCK] & MCDRV_SRC2_LINE2_R_ON) == MCDRV_SRC2_LINE2_R_ON
++              || (gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE2_R_BLOCK] & MCDRV_SRC2_LINE2_R_ON) == MCDRV_SRC2_LINE2_R_ON)
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_LINE2_M_AA:
++              if((gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE2_M_BLOCK] & MCDRV_SRC2_LINE2_M_ON) == MCDRV_SRC2_LINE2_M_ON
++              || (gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE2_M_BLOCK] & MCDRV_SRC2_LINE2_M_ON) == MCDRV_SRC2_LINE2_M_ON
++              || (gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE2_M_BLOCK] & MCDRV_SRC2_LINE2_M_ON) == MCDRV_SRC2_LINE2_M_ON
++              || (gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_LINE2_M_BLOCK] & MCDRV_SRC2_LINE2_M_ON) == MCDRV_SRC2_LINE2_M_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE2_M_BLOCK] & MCDRV_SRC2_LINE2_M_ON) == MCDRV_SRC2_LINE2_M_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE2_M_BLOCK] & MCDRV_SRC2_LINE2_M_ON) == MCDRV_SRC2_LINE2_M_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE2_M_BLOCK] & MCDRV_SRC2_LINE2_M_ON) == MCDRV_SRC2_LINE2_M_ON
++              || (gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE2_M_BLOCK] & MCDRV_SRC2_LINE2_M_ON) == MCDRV_SRC2_LINE2_M_ON
++              || (gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE2_M_BLOCK] & MCDRV_SRC2_LINE2_M_ON) == MCDRV_SRC2_LINE2_M_ON)
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_DIR0_AA:
++              if((gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) == MCDRV_SRC3_DIR0_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) == MCDRV_SRC3_DIR0_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) == MCDRV_SRC3_DIR0_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) == MCDRV_SRC3_DIR0_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) == MCDRV_SRC3_DIR0_ON
++              || (gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) == MCDRV_SRC3_DIR0_ON
++              || (gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) == MCDRV_SRC3_DIR0_ON)
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_DIR1_AA:
++              if((gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) == MCDRV_SRC3_DIR1_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) == MCDRV_SRC3_DIR1_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) == MCDRV_SRC3_DIR1_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) == MCDRV_SRC3_DIR1_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) == MCDRV_SRC3_DIR1_ON
++              || (gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) == MCDRV_SRC3_DIR1_ON
++              || (gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) == MCDRV_SRC3_DIR1_ON)
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_DIR2_AA:
++              if((gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) == MCDRV_SRC3_DIR2_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) == MCDRV_SRC3_DIR2_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) == MCDRV_SRC3_DIR2_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) == MCDRV_SRC3_DIR2_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) == MCDRV_SRC3_DIR2_ON
++              || (gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) == MCDRV_SRC3_DIR2_ON
++              || (gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) == MCDRV_SRC3_DIR2_ON)
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_DTMF_AA:
++              break;
++
++      case    eMCDRV_SRC_PDM_AA:
++              if((gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON
++              || (gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON
++              || (gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON)
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_ADC0_AA:
++              if((gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON
++              || (gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON
++              || (gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON)
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_ADC1_AA:
++              break;
++
++      case    eMCDRV_SRC_DAC_L_AA:
++              if((gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON
++              || (gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON
++              || (gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON)
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_DAC_R_AA:
++              if((gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON
++              || (gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON
++              || (gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON)
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_DAC_M_AA:
++              if((gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON
++              || (gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON
++              || (gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON
++              || (gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON)
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_AE_AA:
++              if((gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON
++              || (gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON)
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_CDSP_AA:
++              break;
++
++      case    eMCDRV_SRC_MIX_AA:
++              if((gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & MCDRV_SRC6_MIX_ON) == MCDRV_SRC6_MIX_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & MCDRV_SRC6_MIX_ON) == MCDRV_SRC6_MIX_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & MCDRV_SRC6_MIX_ON) == MCDRV_SRC6_MIX_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & MCDRV_SRC6_MIX_ON) == MCDRV_SRC6_MIX_ON
++              || (gsGlobalInfo_AA.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & MCDRV_SRC6_MIX_ON) == MCDRV_SRC6_MIX_ON
++              || (gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & MCDRV_SRC6_MIX_ON) == MCDRV_SRC6_MIX_ON)
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_DIR2_DIRECT_AA:
++              break;
++
++      case    eMCDRV_SRC_CDSP_DIRECT_AA:
++              break;
++
++      default:
++              break;
++      }
++
++      return bUsed;
++}
++
++/****************************************************************************
++ *    McResCtrl_IsDstUsed_AA
++ *
++ *    Description:
++ *                    Is Destination used
++ *    Arguments:
++ *                    eType   path destination
++ *                    eCh             channel
++ *    Return:
++ *                    0:unused/1:used
++ *
++ ****************************************************************************/
++UINT8 McResCtrl_IsDstUsed_AA
++(
++      MCDRV_DST_TYPE_AA       eType,
++      MCDRV_DST_CH    eCh
++)
++{
++      UINT8   bUsed   = 0;
++
++      switch(eType)
++      {
++      case    eMCDRV_DST_HP_AA:
++              if(eCh == eMCDRV_DST_CH0_AA)
++              {
++                      if((gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON)
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else if(eCh == eMCDRV_DST_CH1_AA)
++              {
++                      if((gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON)
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else
++              {
++              }
++              break;
++
++      case    eMCDRV_DST_SP_AA:
++              if(eCh == eMCDRV_DST_CH0_AA)
++              {
++                      if((gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON)
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else if(eCh == eMCDRV_DST_CH1_AA)
++              {
++                      if((gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON)
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else
++              {
++              }
++              break;
++
++      case    eMCDRV_DST_RCV_AA:
++              if(eCh == eMCDRV_DST_CH0_AA)
++              {
++                      if((gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) ==MCDRV_SRC5_DAC_R_ON)
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else
++              {
++              }
++              break;
++
++      case    eMCDRV_DST_LOUT1_AA:
++              if(eCh == eMCDRV_DST_CH0_AA)
++              {
++                      if((gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON)
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else if(eCh == eMCDRV_DST_CH1_AA)
++              {
++                      if((gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON)
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else
++              {
++              }
++              break;
++
++      case    eMCDRV_DST_LOUT2_AA:
++              if(eCh == eMCDRV_DST_CH0_AA)
++              {
++                      if((gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON)
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else if(eCh == eMCDRV_DST_CH1_AA)
++              {
++                      if((gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON)
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else
++              {
++              }
++              break;
++
++      case    eMCDRV_DST_PEAK_AA:
++              break;
++
++      case    eMCDRV_DST_DIT0_AA:
++              if(eCh == eMCDRV_DST_CH0_AA)
++              {
++                      if(McResCtrl_GetDITSource_AA(eMCDRV_DIO_0_AA) != eMCDRV_SRC_NONE_AA)
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else
++              {
++              }
++              break;
++
++      case    eMCDRV_DST_DIT1_AA:
++              if(eCh == eMCDRV_DST_CH0_AA)
++              {
++                      if(McResCtrl_GetDITSource_AA(eMCDRV_DIO_1_AA) != eMCDRV_SRC_NONE_AA)
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else
++              {
++              }
++              break;
++
++      case    eMCDRV_DST_DIT2_AA:
++              if(eCh == eMCDRV_DST_CH0_AA)
++              {
++                      if(McResCtrl_GetDITSource_AA(eMCDRV_DIO_2_AA) != eMCDRV_SRC_NONE_AA)
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else
++              {
++              }
++              break;
++
++      case    eMCDRV_DST_DAC_AA:
++              if(eCh == eMCDRV_DST_CH0_AA)
++              {
++                      if(McResCtrl_GetDACSource_AA(eMCDRV_DAC_MASTER_AA) != eMCDRV_SRC_NONE_AA)
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else if(eCh == eMCDRV_DST_CH1_AA)
++              {
++                      if(McResCtrl_GetDACSource_AA(eMCDRV_DAC_VOICE_AA) != eMCDRV_SRC_NONE_AA)
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else
++              {
++              }
++              break;
++
++      case    eMCDRV_DST_AE_AA:
++              if(eCh == eMCDRV_DST_CH0_AA)
++              {
++                      if(McResCtrl_GetAESource_AA() != eMCDRV_SRC_NONE_AA)
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else
++              {
++              }
++              break;
++
++      case    eMCDRV_DST_CDSP_AA:
++              break;
++
++      case    eMCDRV_DST_ADC0_AA:
++              if(eCh == eMCDRV_DST_CH0_AA)
++              {
++                      if((gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else if(eCh == eMCDRV_DST_CH1_AA)
++              {
++                      if((gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else
++              {
++              }
++              break;
++
++      case    eMCDRV_DST_ADC1_AA:
++              if(McDevProf_IsValid(eMCDRV_FUNC_ADC1) == 1)
++              {
++                      if(eCh == eMCDRV_DST_CH0_AA)
++                      {
++                              if((gsGlobalInfo_AA.sPathInfo.asAdc1[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON
++                              || (gsGlobalInfo_AA.sPathInfo.asAdc1[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON
++                              || (gsGlobalInfo_AA.sPathInfo.asAdc1[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON
++                              || (gsGlobalInfo_AA.sPathInfo.asAdc1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON
++                              || (gsGlobalInfo_AA.sPathInfo.asAdc1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++                              {
++                                      bUsed   = 1;
++                              }
++                      }
++                      else
++                      {
++                      }
++              }
++              break;
++
++      case    eMCDRV_DST_MIX_AA:
++              if(eCh != 0)
++              {
++                      break;
++              }
++              if((gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON
++              || (gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON
++              || (gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) == MCDRV_SRC3_DIR0_ON
++              || (gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) == MCDRV_SRC3_DIR1_ON
++              || (gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) == MCDRV_SRC3_DIR2_ON
++              || (gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON)
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_DST_BIAS_AA:
++              if(eCh == eMCDRV_DST_CH0_AA)
++              {
++                      if((gsGlobalInfo_AA.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON
++                      || (gsGlobalInfo_AA.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON)
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else
++              {
++              }
++              break;
++
++      default:
++              break;
++      }
++
++      return bUsed;
++}
++
++/****************************************************************************
++ *    McResCtrl_GetRegAccess_AA
++ *
++ *    Description:
++ *                    Get register access availability
++ *    Arguments:
++ *                    psRegInfo       register information
++ *    Return:
++ *                    MCDRV_REG_ACCSESS_AA
++ *
++ ****************************************************************************/
++MCDRV_REG_ACCSESS_AA  McResCtrl_GetRegAccess_AA
++(
++      const MCDRV_REG_INFO*   psRegInfo
++)
++{
++      switch(psRegInfo->bRegType)
++      {
++      case    MCDRV_REGTYPE_A:
++              return gawRegAccessAvailableA[psRegInfo->bAddress];
++
++      case    MCDRV_REGTYPE_B_BASE:
++              return gawRegAccessAvailableB_BASE[psRegInfo->bAddress];
++
++      case    MCDRV_REGTYPE_B_ANALOG:
++              return gawRegAccessAvailableB_ANA[psRegInfo->bAddress];
++
++      case    MCDRV_REGTYPE_B_CODEC:
++              return gawRegAccessAvailableB_CODEC[psRegInfo->bAddress];
++
++      case    MCDRV_REGTYPE_B_MIXER:
++              return gawRegAccessAvailableB_MIX[psRegInfo->bAddress];
++
++      case    MCDRV_REGTYPE_B_AE:
++              return gawRegAccessAvailableB_AE[psRegInfo->bAddress];
++
++      default:
++              break;
++      }
++      return eMCDRV_ACCESS_DENY_AA;
++}
++
++/****************************************************************************
++ *    McResCtrl_GetAPMode_AA
++ *
++ *    Description:
++ *                    get auto power management mode.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    eMCDRV_APM_ON_AA
++ *                    eMCDRV_APM_OFF
++ *
++ ****************************************************************************/
++MCDRV_PMODE_AA        McResCtrl_GetAPMode_AA
++(
++      void
++)
++{
++      return gsGlobalInfo_AA.eAPMode;
++}
++
++
++/****************************************************************************
++ *    McResCtrl_AllocPacketBuf_AA
++ *
++ *    Description:
++ *                    allocate the buffer for register setting packets.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    pointer to the area to store packets
++ *
++ ****************************************************************************/
++MCDRV_PACKET_AA*      McResCtrl_AllocPacketBuf_AA
++(
++      void
++)
++{
++      if(eMCDRV_PACKETBUF_ALLOCATED_AA == gsGlobalInfo_AA.ePacketBufAlloc)
++      {
++              return NULL;
++      }
++
++      gsGlobalInfo_AA.ePacketBufAlloc = eMCDRV_PACKETBUF_ALLOCATED_AA;
++      return gasPacket;
++}
++
++/****************************************************************************
++ *    McResCtrl_ReleasePacketBuf_AA
++ *
++ *    Description:
++ *                    Release the buffer for register setting packets.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_ReleasePacketBuf_AA
++(
++      void
++)
++{
++      gsGlobalInfo_AA.ePacketBufAlloc = eMCDRV_PACKETBUF_FREE_AA;
++}
++
++/****************************************************************************
++ *    McResCtrl_InitRegUpdate_AA
++ *
++ *    Description:
++ *                    Initialize the process of register update.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_InitRegUpdate_AA
++(
++      void
++)
++{
++      gsGlobalInfo_AA.sCtrlPacket.wDataNum    = 0;
++      gsGlobalInfo_AA.wCurSlaveAddress                = 0xFFFF;
++      gsGlobalInfo_AA.wCurRegType                     = 0xFFFF;
++      gsGlobalInfo_AA.wCurRegAddress                  = 0xFFFF;
++      gsGlobalInfo_AA.wDataContinueCount              = 0;
++      gsGlobalInfo_AA.wPrevAddressIndex               = 0;
++}
++
++/****************************************************************************
++ *    McResCtrl_AddRegUpdate_AA
++ *
++ *    Description:
++ *                    Add register update packet and save register value.
++ *    Arguments:
++ *                    wRegType        register type
++ *                    wAddress        address
++ *                    bData           write data
++ *                    eUpdateMode     updete mode
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_AddRegUpdate_AA
++(
++      UINT16  wRegType,
++      UINT16  wAddress,
++      UINT8   bData,
++      MCDRV_UPDATE_MODE_AA    eUpdateMode
++)
++{
++      UINT8                   *pbRegVal;
++      UINT8                   bAddressADR;
++      UINT8                   bAddressWINDOW;
++      UINT8                   *pbCtrlData;
++      UINT16                  *pwCtrlDataNum;
++      const UINT16    *pwNextAddress;
++      UINT16                  wNextAddress;
++      UINT16                  wSlaveAddress;
++
++      switch (wRegType)
++      {
++      case MCDRV_PACKET_REGTYPE_A_AA:
++              wSlaveAddress   = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              pbRegVal                = gsGlobalInfo_AA.abRegValA;
++              pwNextAddress   = gawNextAddressA;
++              bAddressADR             = (UINT8)wAddress;
++              bAddressWINDOW  = bAddressADR;
++              if(MCDRV_A_REG_NUM_AA <= wAddress)
++              {
++                      return;
++              }
++              break;
++
++      case MCDRV_PACKET_REGTYPE_B_BASE_AA:
++              wSlaveAddress   = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              pbRegVal                = gsGlobalInfo_AA.abRegValB_BASE;
++              pwNextAddress   = gawNextAddressB_BASE;
++              bAddressADR             = MCI_AA_BASE_ADR;
++              bAddressWINDOW  = MCI_AA_BASE_WINDOW;
++              if(MCDRV_B_BASE_REG_NUM_AA <= wAddress)
++              {
++                      return;
++              }
++              break;
++
++      case MCDRV_PACKET_REGTYPE_B_CODEC_AA:
++              wSlaveAddress   = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              pbRegVal                = gsGlobalInfo_AA.abRegValB_CODEC;
++              pwNextAddress   = gawNextAddressB_CODEC;
++              bAddressADR             = MCI_AA_CD_ADR;
++              bAddressWINDOW  = MCI_AA_CD_WINDOW;
++              if(MCDRV_B_CODEC_REG_NUM_AA <= wAddress)
++              {
++                      return;
++              }
++              break;
++
++      case MCDRV_PACKET_REGTYPE_B_ANA_AA:
++              wSlaveAddress   = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_ANA);
++              pbRegVal                = gsGlobalInfo_AA.abRegValB_ANA;
++              pwNextAddress   = gawNextAddressB_Ana;
++              bAddressADR             = MCI_AA_ANA_ADR;
++              bAddressWINDOW  = MCI_AA_ANA_WINDOW;
++              if(MCDRV_B_ANA_REG_NUM_AA <= wAddress)
++              {
++                      return;
++              }
++              break;
++
++      case MCDRV_PACKET_REGTYPE_B_MIXER_AA:
++              wSlaveAddress   = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              pbRegVal                = gsGlobalInfo_AA.abRegValB_MIXER;
++              pwNextAddress   = gawNextAddressB_MIXER;
++              bAddressADR             = MCI_AA_MIX_ADR;
++              bAddressWINDOW  = MCI_AA_MIX_WINDOW;
++              if(MCDRV_B_MIXER_REG_NUM_AA <= wAddress)
++              {
++                      return;
++              }
++              break;
++
++      case MCDRV_PACKET_REGTYPE_B_AE_AA:
++              wSlaveAddress   = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              pbRegVal                = gsGlobalInfo_AA.abRegValB_AE;
++              pwNextAddress   = gawNextAddressB_AE;
++              bAddressADR             = MCI_AA_AE_ADR;
++              bAddressWINDOW  = MCI_AA_AE_WINDOW;
++              if(MCDRV_B_AE_REG_NUM_AA <= wAddress)
++              {
++                      return;
++              }
++              break;
++
++      case MCDRV_PACKET_REGTYPE_B_CDSP_AA:
++              wSlaveAddress   = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              pbRegVal                = gsGlobalInfo_AA.abRegValB_CDSP;
++              pwNextAddress   = gawNextAddressB_CDSP;
++              bAddressADR             = MCI_AA_CDSP_ADR;
++              bAddressWINDOW  = MCI_AA_CDSP_WINDOW;
++              if(MCDRV_B_CDSP_REG_NUM_AA <= wAddress)
++              {
++                      return;
++              }
++              break;
++
++      default:
++              return;
++      }
++
++      if(gsGlobalInfo_AA.wCurSlaveAddress != 0xFFFF && gsGlobalInfo_AA.wCurSlaveAddress != wSlaveAddress)
++      {
++              McResCtrl_ExecuteRegUpdate_AA();
++              McResCtrl_InitRegUpdate_AA();
++      }
++
++      if(gsGlobalInfo_AA.wCurRegType != 0xFFFF && gsGlobalInfo_AA.wCurRegType != wRegType)
++      {
++              McResCtrl_ExecuteRegUpdate_AA();
++              McResCtrl_InitRegUpdate_AA();
++      }
++
++      if ((eMCDRV_UPDATE_FORCE_AA != eUpdateMode) && (bData == pbRegVal[wAddress]))
++      {
++              return;
++      }
++
++      if(gsGlobalInfo_AA.wCurRegAddress == 0xFFFF)
++      {
++              gsGlobalInfo_AA.wCurRegAddress  = wAddress;
++      }
++
++      if (eMCDRV_UPDATE_DUMMY_AA != eUpdateMode)
++      {
++              pbCtrlData              = gsGlobalInfo_AA.sCtrlPacket.abData;
++              pwCtrlDataNum   = &(gsGlobalInfo_AA.sCtrlPacket.wDataNum);
++              wNextAddress    = pwNextAddress[gsGlobalInfo_AA.wCurRegAddress];
++
++              if ((wSlaveAddress == gsGlobalInfo_AA.wCurSlaveAddress)
++              && (wRegType == gsGlobalInfo_AA.wCurRegType)
++              && (0xFFFF != wNextAddress)
++              && (wAddress != wNextAddress))
++              {
++                      if (pwNextAddress[wNextAddress] == wAddress)
++                      {
++                              if (0 == gsGlobalInfo_AA.wDataContinueCount)
++                              {
++                                      pbCtrlData[gsGlobalInfo_AA.wPrevAddressIndex] |= MCDRV_BURST_WRITE_ENABLE;
++                              }
++                              pbCtrlData[*pwCtrlDataNum]      = pbRegVal[wNextAddress];
++                              (*pwCtrlDataNum)++;
++                              gsGlobalInfo_AA.wDataContinueCount++;
++                              wNextAddress                            = pwNextAddress[wNextAddress];
++                      }
++                      else if ((0xFFFF != pwNextAddress[wNextAddress])
++                                      && pwNextAddress[pwNextAddress[wNextAddress]] == wAddress)
++                      {
++                              if (0 == gsGlobalInfo_AA.wDataContinueCount)
++                              {
++                                      pbCtrlData[gsGlobalInfo_AA.wPrevAddressIndex] |= MCDRV_BURST_WRITE_ENABLE;
++                              }
++                              pbCtrlData[*pwCtrlDataNum]      = pbRegVal[wNextAddress];
++                              (*pwCtrlDataNum)++;
++                              pbCtrlData[*pwCtrlDataNum]      = pbRegVal[pwNextAddress[wNextAddress]];
++                              (*pwCtrlDataNum)++;
++                              gsGlobalInfo_AA.wDataContinueCount += 2;
++                              wNextAddress                            = pwNextAddress[pwNextAddress[wNextAddress]];
++                      }
++              }
++
++              if ((0 == *pwCtrlDataNum) || (wAddress != wNextAddress))
++              {
++                      if (0 != gsGlobalInfo_AA.wDataContinueCount)
++                      {
++                              McResCtrl_ExecuteRegUpdate_AA();
++                              McResCtrl_InitRegUpdate_AA();
++                      }
++
++                      if (MCDRV_PACKET_REGTYPE_A_AA == wRegType)
++                      {
++                              pbCtrlData[*pwCtrlDataNum]              = (bAddressADR << 1);
++                              gsGlobalInfo_AA.wPrevAddressIndex       = *pwCtrlDataNum;
++                              (*pwCtrlDataNum)++;
++                      }
++                      else
++                      {
++                              pbCtrlData[(*pwCtrlDataNum)++]  = (bAddressADR << 1);
++                              pbCtrlData[(*pwCtrlDataNum)++]  = (UINT8)wAddress;
++                              pbCtrlData[*pwCtrlDataNum]              = (bAddressWINDOW << 1);
++                              gsGlobalInfo_AA.wPrevAddressIndex       = (*pwCtrlDataNum)++;
++                      }
++              }
++              else
++              {
++                      if (0 == gsGlobalInfo_AA.wDataContinueCount)
++                      {
++                              pbCtrlData[gsGlobalInfo_AA.wPrevAddressIndex] |= MCDRV_BURST_WRITE_ENABLE;
++                      }
++                      gsGlobalInfo_AA.wDataContinueCount++;
++              }
++
++              pbCtrlData[(*pwCtrlDataNum)++]  = bData;
++      }
++
++      gsGlobalInfo_AA.wCurSlaveAddress        = wSlaveAddress;
++      gsGlobalInfo_AA.wCurRegType             = wRegType;
++      gsGlobalInfo_AA.wCurRegAddress          = wAddress;
++
++      /* save register value */
++      pbRegVal[wAddress] = bData;
++}
++
++/****************************************************************************
++ *    McResCtrl_ExecuteRegUpdate_AA
++ *
++ *    Description:
++ *                    Add register update packet and save register value.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_ExecuteRegUpdate_AA
++(
++      void
++)
++{
++      if (0 != gsGlobalInfo_AA.sCtrlPacket.wDataNum)
++      {
++              McSrv_WriteI2C((UINT8)gsGlobalInfo_AA.wCurSlaveAddress, gsGlobalInfo_AA.sCtrlPacket.abData, gsGlobalInfo_AA.sCtrlPacket.wDataNum);
++      }
++}
++
++/****************************************************************************
++ *    McResCtrl_WaitEvent_AA
++ *
++ *    Description:
++ *                    Wait event.
++ *    Arguments:
++ *                    dEvent  event to wait
++ *                    dParam  event parameter
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++SINT32        McResCtrl_WaitEvent_AA
++(
++      UINT32  dEvent,
++      UINT32  dParam
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT32  dInterval;
++      UINT32  dTimeOut;
++      UINT8   bSlaveAddr;
++      UINT8   abWriteData[2];
++
++
++      switch(dEvent)
++      {
++      case    MCDRV_EVT_INSFLG_AA:
++              dInterval       = gsGlobalInfo_AA.sInitInfo.sWaitTime.dSvolInterval;
++              dTimeOut        = gsGlobalInfo_AA.sInitInfo.sWaitTime.dSvolTimeOut;
++              bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              if((dParam>>8) != (UINT32)0)
++              {
++                      abWriteData[0]  = MCI_AA_MIX_ADR<<1;
++                      abWriteData[1]  = MCI_AA_DAC_INS_FLAG;
++                      McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++                      sdRet   = WaitBitRelease(bSlaveAddr, MCI_AA_MIX_WINDOW, (UINT8)(dParam>>8), dInterval, dTimeOut);
++                      if(MCDRV_SUCCESS != sdRet)
++                      {
++                              break;
++                      }
++              }
++              else if((dParam&(UINT32)0xFF) != (UINT32)0)
++              {
++                      abWriteData[0]  = MCI_AA_MIX_ADR<<1;
++                      abWriteData[1]  = MCI_AA_INS_FLAG;
++                      McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++                      sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_AA_MIX_WINDOW, (UINT8)(dParam&(UINT32)0xFF), dInterval, dTimeOut);
++              }
++              break;
++
++      case    MCDRV_EVT_ALLMUTE_AA:
++              dInterval       = gsGlobalInfo_AA.sInitInfo.sWaitTime.dSvolInterval;
++              dTimeOut        = gsGlobalInfo_AA.sInitInfo.sWaitTime.dSvolTimeOut;
++              bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              abWriteData[0]  = MCI_AA_MIX_ADR<<1;
++              abWriteData[1]  = MCI_AA_DIT_INVFLAGL;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_AA_MIX_WINDOW, (MCB_AA_DIT0_INVFLAGL|MCB_AA_DIT1_INVFLAGL|MCB_AA_DIT2_INVFLAGL), dInterval, dTimeOut);
++              if(MCDRV_SUCCESS != sdRet)
++              {
++                      break;
++              }
++              abWriteData[0]  = MCI_AA_MIX_ADR<<1;
++              abWriteData[1]  = MCI_AA_DIT_INVFLAGR;
++              McSrv_WriteI2C(McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG), abWriteData, 2);
++              sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_AA_MIX_WINDOW, (MCB_AA_DIT0_INVFLAGR|MCB_AA_DIT1_INVFLAGR|MCB_AA_DIT2_INVFLAGR), dInterval, dTimeOut);
++              if(MCDRV_SUCCESS != sdRet)
++              {
++                      break;
++              }
++              abWriteData[0]  = MCI_AA_MIX_ADR<<1;
++              abWriteData[1]  = MCI_AA_DIR_VFLAGL;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_AA_MIX_WINDOW, (MCB_AA_PDM0_VFLAGL|MCB_AA_DIR0_VFLAGL|MCB_AA_DIR1_VFLAGL|MCB_AA_DIR2_VFLAGL), dInterval, dTimeOut);
++              if(MCDRV_SUCCESS != sdRet)
++              {
++                      break;
++              }
++              abWriteData[0]  = MCI_AA_MIX_ADR<<1;
++              abWriteData[1]  = MCI_AA_DIR_VFLAGR;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_AA_MIX_WINDOW, (MCB_AA_PDM0_VFLAGR|MCB_AA_DIR0_VFLAGR|MCB_AA_DIR1_VFLAGR|MCB_AA_DIR2_VFLAGR), dInterval, dTimeOut);
++              if(MCDRV_SUCCESS != sdRet)
++              {
++                      break;
++              }
++              abWriteData[0]  = MCI_AA_MIX_ADR<<1;
++              abWriteData[1]  = MCI_AA_AD_VFLAGL;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_AA_MIX_WINDOW, (MCB_AA_ADC_VFLAGL|MCB_AA_AENG6_VFLAGL), dInterval, dTimeOut);
++              if(MCDRV_SUCCESS != sdRet)
++              {
++                      break;
++              }
++              abWriteData[0]  = MCI_AA_MIX_ADR<<1;
++              abWriteData[1]  = MCI_AA_AD_VFLAGR;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_AA_MIX_WINDOW, (MCB_AA_ADC_VFLAGR|MCB_AA_AENG6_VFLAGR), dInterval, dTimeOut);
++              if(MCDRV_SUCCESS != sdRet)
++              {
++                      break;
++              }
++              abWriteData[0]  = MCI_AA_MIX_ADR<<1;
++              abWriteData[1]  = MCI_AA_AFLAGL;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_AA_MIX_WINDOW, (MCB_AA_ADC_AFLAGL|MCB_AA_DIR0_AFLAGL|MCB_AA_DIR1_AFLAGL|MCB_AA_DIR2_AFLAGL), dInterval, dTimeOut);
++              if(MCDRV_SUCCESS != sdRet)
++              {
++                      break;
++              }
++              abWriteData[0]  = MCI_AA_MIX_ADR<<1;
++              abWriteData[1]  = MCI_AA_AFLAGR;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_AA_MIX_WINDOW, (MCB_AA_ADC_AFLAGR|MCB_AA_DIR0_AFLAGR|MCB_AA_DIR1_AFLAGR|MCB_AA_DIR2_AFLAGR), dInterval, dTimeOut);
++              if(MCDRV_SUCCESS != sdRet)
++              {
++                      break;
++              }
++              abWriteData[0]  = MCI_AA_MIX_ADR<<1;
++              abWriteData[1]  = MCI_AA_DAC_FLAGL;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_AA_MIX_WINDOW, (MCB_AA_ST_FLAGL|MCB_AA_MASTER_OFLAGL|MCB_AA_VOICE_FLAGL|MCB_AA_DAC_FLAGL), dInterval, dTimeOut);
++              if(MCDRV_SUCCESS != sdRet)
++              {
++                      break;
++              }
++              abWriteData[0]  = MCI_AA_MIX_ADR<<1;
++              abWriteData[1]  = MCI_AA_DAC_FLAGR;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_AA_MIX_WINDOW, (MCB_AA_ST_FLAGR|MCB_AA_MASTER_OFLAGR|MCB_AA_VOICE_FLAGR|MCB_AA_DAC_FLAGR), dInterval, dTimeOut);
++              break;
++
++      case    MCDRV_EVT_DITMUTE_AA:
++              dInterval       = gsGlobalInfo_AA.sInitInfo.sWaitTime.dSvolInterval;
++              dTimeOut        = gsGlobalInfo_AA.sInitInfo.sWaitTime.dSvolTimeOut;
++              bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              if((dParam>>8) != (UINT32)0)
++              {
++                      abWriteData[0]  = MCI_AA_MIX_ADR<<1;
++                      abWriteData[1]  = MCI_AA_DIT_INVFLAGL;
++                      McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++                      sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_AA_MIX_WINDOW, (UINT8)(dParam>>8), dInterval, dTimeOut);
++                      if(MCDRV_SUCCESS != sdRet)
++                      {
++                              break;
++                      }
++              }
++              if((dParam&(UINT32)0xFF) != (UINT32)0)
++              {
++                      abWriteData[0]  = MCI_AA_MIX_ADR<<1;
++                      abWriteData[1]  = MCI_AA_DIT_INVFLAGR;
++                      McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++                      sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_AA_MIX_WINDOW, (UINT8)(dParam&(UINT32)0xFF), dInterval, dTimeOut);
++              }
++              break;
++
++      case    MCDRV_EVT_DACMUTE_AA:
++              dInterval       = gsGlobalInfo_AA.sInitInfo.sWaitTime.dSvolInterval;
++              dTimeOut        = gsGlobalInfo_AA.sInitInfo.sWaitTime.dSvolTimeOut;
++              bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              if((dParam>>8) != (UINT32)0)
++              {
++                      abWriteData[0]  = MCI_AA_MIX_ADR<<1;
++                      abWriteData[1]  = MCI_AA_DAC_FLAGL;
++                      McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++                      sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_AA_MIX_WINDOW, (UINT8)(dParam>>8), dInterval, dTimeOut);
++                      if(MCDRV_SUCCESS != sdRet)
++                      {
++                              break;
++                      }
++              }
++              if((dParam&(UINT32)0xFF) != (UINT32)0)
++              {
++                      abWriteData[0]  = MCI_AA_MIX_ADR<<1;
++                      abWriteData[1]  = MCI_AA_DAC_FLAGR;
++                      McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++                      sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_AA_MIX_WINDOW, (UINT8)(dParam&(UINT32)0xFF), dInterval, dTimeOut);
++              }
++              break;
++
++      case    MCDRV_EVT_SVOL_DONE_AA:
++              dInterval       = gsGlobalInfo_AA.sInitInfo.sWaitTime.dSvolInterval;
++              dTimeOut        = gsGlobalInfo_AA.sInitInfo.sWaitTime.dSvolTimeOut;
++              bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_ANA);
++              if((dParam>>8) != (UINT32)0)
++              {
++                      abWriteData[0]  = MCI_AA_ANA_ADR<<1;
++                      abWriteData[1]  = MCI_AA_BUSY1;
++                      McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++                      sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_AA_ANA_WINDOW, (UINT8)(dParam>>8), dInterval, dTimeOut);
++                      if(MCDRV_SUCCESS != sdRet)
++                      {
++                              break;
++                      }
++              }
++              if((dParam&(UINT32)0xFF) != (UINT32)0)
++              {
++                      abWriteData[0]  = MCI_AA_ANA_ADR<<1;
++                      abWriteData[1]  = MCI_AA_BUSY2;
++                      McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++                      return WaitBitRelease(bSlaveAddr, (UINT16)MCI_AA_ANA_WINDOW, (UINT8)(dParam&(UINT8)0xFF), dInterval, dTimeOut);
++              }
++              break;
++
++      case    MCDRV_EVT_APM_DONE_AA:
++              dInterval       = gsGlobalInfo_AA.sInitInfo.sWaitTime.dSvolInterval;
++              dTimeOut        = gsGlobalInfo_AA.sInitInfo.sWaitTime.dSvolTimeOut;
++              bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_ANA);
++              abWriteData[0]  = MCI_AA_ANA_ADR<<1;
++              abWriteData[1]  = MCI_AA_AP_A1;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitSet(bSlaveAddr, (UINT16)MCI_AA_ANA_WINDOW, (UINT8)(dParam>>8), dInterval, dTimeOut);
++              if(MCDRV_SUCCESS != sdRet)
++              {
++                      break;
++              }
++              abWriteData[0]  = MCI_AA_ANA_ADR<<1;
++              abWriteData[1]  = MCI_AA_AP_A2;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitSet(bSlaveAddr, (UINT16)MCI_AA_ANA_WINDOW, (UINT8)(dParam&(UINT8)0xFF), dInterval, dTimeOut);
++              break;
++
++      case    MCDRV_EVT_ANA_RDY_AA:
++              dInterval       = gsGlobalInfo_AA.sInitInfo.sWaitTime.dAnaRdyInterval;
++              dTimeOut        = gsGlobalInfo_AA.sInitInfo.sWaitTime.dAnaRdyTimeOut;
++              bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_ANA);
++              abWriteData[0]  = MCI_AA_ANA_ADR<<1;
++              abWriteData[1]  = MCI_AA_RDY_FLAG;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitSet(bSlaveAddr, (UINT16)MCI_AA_ANA_WINDOW, (UINT8)dParam, dInterval, dTimeOut);
++              break;
++
++      default:
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    WaitBitSet
++ *
++ *    Description:
++ *                    Wait register bit to set.
++ *    Arguments:
++ *                    bSlaveAddr      slave address
++ *                    wRegAddr        register address
++ *                    bBit            bit
++ *                    dCycleTime      cycle time to poll [us]
++ *                    dTimeOut        number of read cycles for time out
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++static SINT32 WaitBitSet
++(
++      UINT8   bSlaveAddr,
++      UINT16  wRegAddr,
++      UINT8   bBit,
++      UINT32  dCycleTime,
++      UINT32  dTimeOut
++)
++{
++      UINT8   bData;
++      UINT32  dCycles;
++      SINT32  sdRet;
++
++
++      dCycles = 0;
++      sdRet   = MCDRV_ERROR_TIMEOUT;
++
++      while(dCycles < dTimeOut)
++      {
++              bData   = McSrv_ReadI2C(bSlaveAddr, wRegAddr);
++              if((bData & bBit) == bBit)
++              {
++                      sdRet   = MCDRV_SUCCESS;
++                      break;
++              }
++
++              McSrv_Sleep(dCycleTime);
++              dCycles++;
++      }
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    WaitBitRelease
++ *
++ *    Description:
++ *                    Wait register bit to release.
++ *    Arguments:
++ *                    bSlaveAddr      slave address
++ *                    wRegAddr        register address
++ *                    bBit            bit
++ *                    dCycleTime      cycle time to poll [us]
++ *                    dTimeOut        number of read cycles for time out
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++static SINT32 WaitBitRelease
++(
++      UINT8   bSlaveAddr,
++      UINT16  wRegAddr,
++      UINT8   bBit,
++      UINT32  dCycleTime,
++      UINT32  dTimeOut
++)
++{
++      UINT8   bData;
++      UINT32  dCycles;
++      SINT32  sdRet;
++
++
++      dCycles = 0;
++      sdRet   = MCDRV_ERROR_TIMEOUT;
++
++      while(dCycles < dTimeOut)
++      {
++              bData   = McSrv_ReadI2C(bSlaveAddr, wRegAddr);
++              if(0 == (bData & bBit))
++              {
++                      sdRet   = MCDRV_SUCCESS;
++                      break;
++              }
++
++              McSrv_Sleep(dCycleTime);
++              dCycles++;
++      }
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    McResCtrl_ConfigHwAdj_AA
++ *
++ *    Description:
++ *                    HWADJ configuration.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    MCDRV_HWADJ
++ *
++ ****************************************************************************/
++MCDRV_HWADJ   McResCtrl_ConfigHwAdj_AA
++(
++      void
++)
++{
++      UINT8                   bFs;
++      UINT8                   bSrc1;
++      UINT8                   bSrc2;
++      UINT8                   bSrc3;
++      MCDRV_DST_TYPE_AA       eDstType;
++      MCDRV_SRC_TYPE_AA       eSrcType;
++      MCDRV_HWADJ             eHwAdj;
++
++      eDstType = eMCDRV_DST_DIT0_AA;
++      eSrcType = eMCDRV_SRC_DIR0_AA;
++      eHwAdj = eMCDRV_HWADJ_THRU;
++      bFs = 0xFF;
++
++      /* DIR0->AE or DIR0->MIX */
++      bSrc1 = gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON;
++      bSrc2 = gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON;
++      if((bSrc1 != 0) || (bSrc2 != 0))
++      {
++              bFs = gsGlobalInfo_AA.sDioInfo.asPortInfo[0].sDioCommon.bFs;
++              eSrcType = eMCDRV_SRC_DIR0_AA;
++      }
++
++      /* DIR1->AE or DIR1->MIX */
++      bSrc1 = gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON;
++      bSrc2 = gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON;
++      if((bSrc1 != 0) || (bSrc2 != 0))
++      {
++              if(bFs > gsGlobalInfo_AA.sDioInfo.asPortInfo[1].sDioCommon.bFs)
++              {
++                      bFs = gsGlobalInfo_AA.sDioInfo.asPortInfo[1].sDioCommon.bFs;
++                      eSrcType = eMCDRV_SRC_DIR1_AA;
++              }
++      }
++
++      /* DIR2->AE or DIR2->MIX */
++      bSrc1 = gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON;
++      bSrc2 = gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON;
++      if((bSrc1 != 0) || (bSrc2 != 0))
++      {
++              if(bFs > gsGlobalInfo_AA.sDioInfo.asPortInfo[2].sDioCommon.bFs)
++              {
++                      bFs = gsGlobalInfo_AA.sDioInfo.asPortInfo[2].sDioCommon.bFs;
++                      eSrcType = eMCDRV_SRC_DIR2_AA;
++              }
++      }
++
++      if(bFs != 0xFF)
++      {
++              if((bFs != MCDRV_FS_48000) && (bFs != MCDRV_FS_44100) && (bFs != MCDRV_FS_8000))
++              {
++                      bFs = 0xFF;
++              }
++
++              if(bFs != 0xFF)
++              {
++                      switch(eSrcType)
++                      {
++                      case    eMCDRV_SRC_DIR0_AA:
++                              if((gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) != 0)
++                              {
++                                      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_AE_AA, eMCDRV_DST_CH0_AA) == 1)
++                                      {
++                                              if(((gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & MCDRV_SRC6_MIX_ON) == 0) &&
++                                                 ((gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) == 0))
++                                              {
++                                                      bFs = 0xFF;
++                                              }
++                                      }
++                                      else
++                                      {
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       &= (UINT8)~MCDRV_SRC4_PDM_ON;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       |= MCDRV_SRC4_PDM_OFF;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      |= MCDRV_SRC4_ADC0_OFF;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR0_OFF;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      |= MCDRV_SRC3_DIR0_ON;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      |= MCDRV_SRC3_DIR1_OFF;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      |= MCDRV_SRC3_DIR2_OFF;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       &= (UINT8)~MCDRV_SRC6_MIX_ON;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       |= MCDRV_SRC6_MIX_OFF;
++
++                                              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]     &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++                                              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]     |= MCDRV_SRC3_DIR0_OFF;
++                                              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]       &= (UINT8)~MCDRV_SRC6_AE_OFF;
++                                              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]       |= MCDRV_SRC6_AE_ON;
++                                      }
++                              }
++                              break;
++                      case    eMCDRV_SRC_DIR1_AA:
++                              if((gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) != 0)
++                              {
++                                      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_AE_AA, eMCDRV_DST_CH0_AA) == 1)
++                                      {
++                                              if(((gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & MCDRV_SRC6_MIX_ON) == 0) &&
++                                                 ((gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) == 0))
++                                              {
++                                                      bFs = 0xFF;
++                                              }
++                                      }
++                                      else
++                                      {
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       &= (UINT8)~MCDRV_SRC4_PDM_ON;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       |= MCDRV_SRC4_PDM_OFF;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      |= MCDRV_SRC4_ADC0_OFF;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      |= MCDRV_SRC3_DIR0_OFF;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR1_OFF;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      |= MCDRV_SRC3_DIR1_ON;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      |= MCDRV_SRC3_DIR2_OFF;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       &= (UINT8)~MCDRV_SRC6_MIX_ON;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       |= MCDRV_SRC6_MIX_OFF;
++
++                                              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]     &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++                                              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]     |= MCDRV_SRC3_DIR1_OFF;
++                                              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]       &= (UINT8)~MCDRV_SRC6_AE_OFF;
++                                              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]       |= MCDRV_SRC6_AE_ON;
++                                      }
++                              }
++                              break;
++                      case    eMCDRV_SRC_DIR2_AA:
++                              if((gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) != 0)
++                              {
++                                      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_AE_AA, eMCDRV_DST_CH0_AA) == 1)
++                                      {
++                                              if(((gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & MCDRV_SRC6_MIX_ON) == 0) &&
++                                                 ((gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) == 0))
++                                              {
++                                                      bFs = 0xFF;
++                                              }
++                                      }
++                                      else
++                                      {
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       &= (UINT8)~MCDRV_SRC4_PDM_ON;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       |= MCDRV_SRC4_PDM_OFF;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      |= MCDRV_SRC4_ADC0_OFF;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      |= MCDRV_SRC3_DIR0_OFF;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      |= MCDRV_SRC3_DIR1_OFF;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR2_OFF;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      |= MCDRV_SRC3_DIR2_ON;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       &= (UINT8)~MCDRV_SRC6_MIX_ON;
++                                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       |= MCDRV_SRC6_MIX_OFF;
++
++                                              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]     &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++                                              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]     |= MCDRV_SRC3_DIR2_OFF;
++                                              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]       &= (UINT8)~MCDRV_SRC6_AE_OFF;
++                                              gsGlobalInfo_AA.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]       |= MCDRV_SRC6_AE_ON;
++                                      }
++                              }
++                              break;
++                      default:
++                              bFs = 0xFF;
++                              break;
++                      }
++
++                      switch(bFs)
++                      {
++                      case    MCDRV_FS_48000:
++                              eHwAdj = eMCDRV_HWADJ_PLAY48;
++                              break;
++                      case    MCDRV_FS_44100:
++                              eHwAdj = eMCDRV_HWADJ_PLAY44;
++                              break;
++                      case    MCDRV_FS_8000:
++                              eHwAdj = eMCDRV_HWADJ_PLAY8;
++                              break;
++                      default:
++                              break;
++                      }
++              }
++      }
++      else
++      {
++              /* AD->DIT0 or AD->AE->DIT0 */
++              bSrc1 = gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON;
++              bSrc2 = gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON;
++              bSrc3 = gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON;
++              if((bSrc1 != 0) || ((bSrc2 != 0) && (bSrc3 != 0)))
++              {
++                      bFs = gsGlobalInfo_AA.sDioInfo.asPortInfo[0].sDioCommon.bFs;
++                      eDstType = eMCDRV_DST_DIT0_AA;
++              }
++
++              /* AD->DIT1 or AD->AE->DIT1 */
++              bSrc1 = gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON;
++              bSrc2 = gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON;
++              bSrc3 = gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON;
++              if((bSrc1 != 0) || ((bSrc2 != 0) && (bSrc3 != 0)))
++              {
++                      if(bFs > gsGlobalInfo_AA.sDioInfo.asPortInfo[1].sDioCommon.bFs)
++                      {
++                              bFs = gsGlobalInfo_AA.sDioInfo.asPortInfo[1].sDioCommon.bFs;
++                              eDstType = eMCDRV_DST_DIT1_AA;
++                      }
++              }
++
++              /* AD->DIT2 or AD->AE->DIT2 */
++              bSrc1 = gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON;
++              bSrc2 = gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON;
++              bSrc3 = gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON;
++              if((bSrc1 != 0) || ((bSrc2 != 0) && (bSrc3 != 0)))
++              {
++                      if(bFs > gsGlobalInfo_AA.sDioInfo.asPortInfo[2].sDioCommon.bFs)
++                      {
++                              bFs = gsGlobalInfo_AA.sDioInfo.asPortInfo[2].sDioCommon.bFs;
++                              eDstType = eMCDRV_DST_DIT2_AA;
++                      }
++              }
++
++              if((bFs != MCDRV_FS_48000) && (bFs != MCDRV_FS_44100) && (bFs != MCDRV_FS_8000))
++              {
++                      bFs = 0xFF;
++              }
++
++              if(bFs != 0xFF)
++              {
++                      switch(eDstType)
++                      {
++                      case    eMCDRV_DST_DIT0_AA:
++                              if(((gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) != 0) ||
++                                 ((gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) != 0))
++                              {
++                                      bFs = 0xFF;
++                              }
++                              else
++                              {
++                                      if((gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) != 0)
++                                      {
++                                              if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_AE_AA, eMCDRV_DST_CH0_AA) == 1)
++                                              {
++                                                      bFs = 0xFF;
++                                              }
++                                              else
++                                              {
++                                                      gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_ON;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_OFF;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_OFF;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_OFF;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_OFF;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_OFF;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_ON;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++                                              }
++                                      }
++                              }
++                              break;
++                      case    eMCDRV_DST_DIT1_AA:
++                              if(((gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) != 0) ||
++                                 ((gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) != 0))
++                              {
++                                      bFs = 0xFF;
++                              }
++                              else
++                              {
++                                      if((gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) != 0)
++                                      {
++                                              if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_AE_AA, eMCDRV_DST_CH0_AA) == 1)
++                                              {
++                                                      bFs = 0xFF;
++                                              }
++                                              else
++                                              {
++                                                      gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_ON;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_OFF;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_OFF;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_OFF;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_OFF;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_OFF;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_ON;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++                                              }
++                                      }
++                              }
++                              break;
++                      case    eMCDRV_DST_DIT2_AA:
++                              if(((gsGlobalInfo_AA.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) != 0) ||
++                                 ((gsGlobalInfo_AA.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) != 0))
++                              {
++                                      bFs = 0xFF;
++                              }
++                              else
++                              {
++                                      if((gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) != 0)
++                                      {
++                                              if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_AE_AA, eMCDRV_DST_CH0_AA) == 1)
++                                              {
++                                                      bFs = 0xFF;
++                                              }
++                                              else
++                                              {
++                                                      gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     &= (UINT8)~MCDRV_SRC4_PDM_ON;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]     |= MCDRV_SRC4_PDM_OFF;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]    |= MCDRV_SRC4_ADC0_OFF;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]    |= MCDRV_SRC3_DIR0_OFF;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]    |= MCDRV_SRC3_DIR1_OFF;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]    |= MCDRV_SRC3_DIR2_OFF;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              &= (UINT8)~MCDRV_SRC6_AE_OFF;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]              |= MCDRV_SRC6_AE_ON;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     &= (UINT8)~MCDRV_SRC6_MIX_ON;
++                                                      gsGlobalInfo_AA.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]     |= MCDRV_SRC6_MIX_OFF;
++                                              }
++                                      }
++                              }
++                              break;
++                      default:
++                              bFs = 0xFF;
++                              break;
++                      }
++
++
++                      if((bFs != 0xFF) && (McResCtrl_IsDstUsed_AA(eMCDRV_DST_AE_AA, eMCDRV_DST_CH0_AA) == 0))
++                      {
++                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       &= (UINT8)~MCDRV_SRC4_PDM_ON;
++                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       |= MCDRV_SRC4_PDM_OFF;
++                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      &= (UINT8)~MCDRV_SRC4_ADC0_OFF;
++                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      |= MCDRV_SRC4_ADC0_ON;
++                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      |= MCDRV_SRC3_DIR0_OFF;
++                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      |= MCDRV_SRC3_DIR1_OFF;
++                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      |= MCDRV_SRC3_DIR2_OFF;
++                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       &= (UINT8)~MCDRV_SRC6_MIX_ON;
++                              gsGlobalInfo_AA.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       |= MCDRV_SRC6_MIX_OFF;
++                      }
++
++                      switch(bFs)
++                      {
++                      case    MCDRV_FS_48000:
++                              eHwAdj = eMCDRV_HWADJ_REC48;
++                              break;
++                      case    MCDRV_FS_44100:
++                              eHwAdj = eMCDRV_HWADJ_REC44;
++                              break;
++                      case    MCDRV_FS_8000:
++                              eHwAdj = eMCDRV_HWADJ_REC8;
++                              break;
++                      default:
++                              break;
++                      }
++              }
++      }
++
++      if(gsGlobalInfo_AA.eHwAdj == eHwAdj)
++      {
++              eHwAdj = eMCDRV_HWADJ_NOCHANGE;
++      }
++      else
++      {
++              gsGlobalInfo_AA.eHwAdj = eHwAdj;
++      }
++
++      return eHwAdj;
++}
++
++/**************************************/
++
++/* volume update */
++typedef enum
++{
++      eMCDRV_VOLUPDATE_MUTE_AA,
++      eMCDRV_VOLUPDATE_ALL_AA
++} MCDRV_VOLUPDATE_MODE_AA;
++
++/* power update */
++typedef struct
++{
++      UINT32  dDigital;
++      UINT8   abAnalog[5];
++} MCDRV_POWER_UPDATE_AA;
++
++#define       MCDRV_POWUPDATE_DIGITAL_ALL_AA          (0xFFFFFFFFUL)
++#define       MCDRV_POWUPDATE_ANALOG0_ALL_AA          (0x0F)
++#define       MCDRV_POWUPDATE_ANALOG1_ALL_AA          (0xFF)
++#define       MCDRV_POWUPDATE_ANALOG2_ALL_AA          (0x3F)
++#define       MCDRV_POWUPDATE_ANALOG3_ALL_AA          (0x0F)
++#define       MCDRV_POWUPDATE_ANALOG4_ALL_AA          (0xF0)
++#define       MCDRV_POWUPDATE_ANALOG0_IN_AA           (0x0D)
++#define       MCDRV_POWUPDATE_ANALOG1_IN_AA           (0xC0)
++#define       MCDRV_POWUPDATE_ANALOG2_IN_AA           (0x00)
++#define       MCDRV_POWUPDATE_ANALOG3_IN_AA           (0x0F)
++#define       MCDRV_POWUPDATE_ANALOG4_IN_AA           (0xF0)
++#define       MCDRV_POWUPDATE_ANALOG0_OUT_AA          (0x02)
++#define       MCDRV_POWUPDATE_ANALOG1_OUT_AA          (0x3F)
++#define       MCDRV_POWUPDATE_ANALOG2_OUT_AA          (0x3F)
++#define       MCDRV_POWUPDATE_ANALOG3_OUT_AA          (0x00)
++#define       MCDRV_POWUPDATE_ANALOG4_OUT_AA          (0x00)
++
++
++#define       MCDRV_TCXO_WAIT_TIME_AA         ((UINT32)2000)
++#define       MCDRV_PLRST_WAIT_TIME_AA        ((UINT32)2000)
++#define       MCDRV_LDOA_WAIT_TIME_AA         ((UINT32)1000)
++#define       MCDRV_SP_WAIT_TIME_AA           ((UINT32)150)
++#define       MCDRV_HP_WAIT_TIME_AA           ((UINT32)300)
++#define       MCDRV_RC_WAIT_TIME_AA           ((UINT32)150)
++
++/* SrcRate default */
++#define       MCDRV_DIR_SRCRATE_48000_AA      (32768)
++#define       MCDRV_DIR_SRCRATE_44100_AA      (30106)
++#define       MCDRV_DIR_SRCRATE_32000_AA      (21845)
++#define       MCDRV_DIR_SRCRATE_24000_AA      (16384)
++#define       MCDRV_DIR_SRCRATE_22050_AA      (15053)
++#define       MCDRV_DIR_SRCRATE_16000_AA      (10923)
++#define       MCDRV_DIR_SRCRATE_12000_AA      (8192)
++#define       MCDRV_DIR_SRCRATE_11025_AA      (7526)
++#define       MCDRV_DIR_SRCRATE_8000_AA       (5461)
++
++#define       MCDRV_DIT_SRCRATE_48000_AA      (4096)
++#define       MCDRV_DIT_SRCRATE_44100_AA      (4458)
++#define       MCDRV_DIT_SRCRATE_32000_AA      (6144)
++#define       MCDRV_DIT_SRCRATE_24000_AA      (8192)
++#define       MCDRV_DIT_SRCRATE_22050_AA      (8916)
++#define       MCDRV_DIT_SRCRATE_16000_AA      (12288)
++#define       MCDRV_DIT_SRCRATE_12000_AA      (16384)
++#define       MCDRV_DIT_SRCRATE_11025_AA      (17833)
++#define       MCDRV_DIT_SRCRATE_8000_AA       (24576)
++
++static SINT32 AddAnalogPowerUpAuto(const MCDRV_POWER_INFO_AA* psPowerInfo, const MCDRV_POWER_UPDATE_AA* psPowerUpdate);
++
++static void           AddDIPad(void);
++static void           AddPAD(void);
++static SINT32 AddSource(void);
++static void           AddDIStart(void);
++static UINT8  GetMicMixBit(const MCDRV_CHANNEL* psChannel);
++static void           AddStopADC(void);
++static void           AddStopPDM(void);
++static UINT8  IsModifiedDIO(UINT32 dUpdateInfo);
++static UINT8  IsModifiedDIOCommon(MCDRV_DIO_PORT_NO_AA ePort);
++static UINT8  IsModifiedDIODIR(MCDRV_DIO_PORT_NO_AA ePort);
++static UINT8  IsModifiedDIODIT(MCDRV_DIO_PORT_NO_AA ePort);
++static void           AddDIOCommon(MCDRV_DIO_PORT_NO_AA ePort);
++static void           AddDIODIR(MCDRV_DIO_PORT_NO_AA ePort);
++static void           AddDIODIT(MCDRV_DIO_PORT_NO_AA ePort);
++
++#define       MCDRV_DPB_KEEP_AA       0
++#define       MCDRV_DPB_UP_AA 1
++static SINT32 PowerUpDig(UINT8 bDPBUp);
++
++static UINT32 GetMaxWait(UINT8 bRegChange);
++
++static SINT32         McPacket_AddInit_AA                     (const MCDRV_INIT_INFO* psInitInfo);
++static SINT32         McPacket_AddVol_AA                      (UINT32 dUpdate, MCDRV_VOLUPDATE_MODE_AA eMode);
++static SINT32         McPacket_AddPowerUp_AA          (const MCDRV_POWER_INFO_AA* psPowerInfo, const MCDRV_POWER_UPDATE_AA* psPowerUpdate);
++static SINT32         McPacket_AddPowerDown_AA        (const MCDRV_POWER_INFO_AA* psPowerInfo, const MCDRV_POWER_UPDATE_AA* psPowerUpdate);
++static SINT32         McPacket_AddPathSet_AA          (void);
++static SINT32         McPacket_AddMixSet_AA           (void);
++static SINT32         McPacket_AddStart_AA            (void);
++static SINT32         McPacket_AddStop_AA                     (void);
++static SINT32         McPacket_AddDigitalIO_AA        (UINT32 dUpdateInfo);
++static SINT32         McPacket_AddDAC_AA                      (UINT32 dUpdateInfo);
++static SINT32         McPacket_AddADC_AA                      (UINT32 dUpdateInfo);
++static SINT32         McPacket_AddSP_AA                       (void);
++static SINT32         McPacket_AddDNG_AA                      (UINT32 dUpdateInfo);
++static SINT32         McPacket_AddAE_AA                       (UINT32 dUpdateInfo);
++static SINT32         McPacket_AddPDM_AA                      (UINT32 dUpdateInfo);
++static SINT32         McPacket_AddGPMode_AA           (void);
++static SINT32         McPacket_AddGPMask_AA           (UINT32 dPadNo);
++static SINT32         McPacket_AddGPSet_AA            (UINT8 bGpio, UINT32 dPadNo);
++
++/****************************************************************************
++ *    McPacket_AddInit_AA
++ *
++ *    Description:
++ *                    Add initialize packet.
++ *    Arguments:
++ *                    psInitInfo              information for initialization
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddInit_AA
++(
++      const MCDRV_INIT_INFO*  psInitInfo
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bReg;
++      MCDRV_POWER_INFO_AA     sPowerInfo;
++      MCDRV_POWER_UPDATE_AA   sPowerUpdate;
++
++
++      /*      RSTA    */
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_FORCE_WRITE_AA | MCDRV_PACKET_REGTYPE_A_AA | MCI_AA_RST, MCB_AA_RST);
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_FORCE_WRITE_AA | MCDRV_PACKET_REGTYPE_A_AA | MCI_AA_RST, 0);
++
++      /*      ANA_RST */
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_FORCE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | (UINT32)MCI_AA_ANA_RST, MCI_AA_ANA_RST_DEF);
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_FORCE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | (UINT32)MCI_AA_ANA_RST, 0);
++
++      /*      SDIN_MSK*, SDO_DDR*     */
++      bReg    = MCB_AA_SDIN_MSK2;
++      if(psInitInfo->bDioSdo2Hiz == MCDRV_DAHIZ_LOW)
++      {
++              bReg |= MCB_AA_SDO_DDR2;
++      }
++      bReg |= MCB_AA_SDIN_MSK1;
++      if(psInitInfo->bDioSdo1Hiz == MCDRV_DAHIZ_LOW)
++      {
++              bReg |= MCB_AA_SDO_DDR1;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_SD_MSK, bReg);
++
++      bReg    = MCB_AA_SDIN_MSK0;
++      if(psInitInfo->bDioSdo0Hiz == MCDRV_DAHIZ_LOW)
++      {
++              bReg |= MCB_AA_SDO_DDR0;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_SD_MSK_1, bReg);
++
++      /*      BCLK_MSK*, BCLD_DDR*, LRCK_MSK*, LRCK_DDR*, PCM_HIZ*    */
++      bReg    = 0;
++      bReg |= MCB_AA_BCLK_MSK2;
++      bReg |= MCB_AA_LRCK_MSK2;
++      if(psInitInfo->bDioClk2Hiz == MCDRV_DAHIZ_LOW)
++      {
++              bReg |= MCB_AA_BCLK_DDR2;
++              bReg |= MCB_AA_LRCK_DDR2;
++      }
++      bReg |= MCB_AA_BCLK_MSK1;
++      bReg |= MCB_AA_LRCK_MSK1;
++      if(psInitInfo->bDioClk1Hiz == MCDRV_DAHIZ_LOW)
++      {
++              bReg |= MCB_AA_BCLK_DDR1;
++              bReg |= MCB_AA_LRCK_DDR1;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_BCLK_MSK, bReg);
++
++      bReg    = 0;
++      bReg |= MCB_AA_BCLK_MSK0;
++      bReg |= MCB_AA_LRCK_MSK0;
++      if(psInitInfo->bDioClk0Hiz == MCDRV_DAHIZ_LOW)
++      {
++              bReg |= MCB_AA_BCLK_DDR0;
++              bReg |= MCB_AA_LRCK_DDR0;
++      }
++      if(psInitInfo->bPcmHiz == MCDRV_PCMHIZ_HIZ)
++      {
++              bReg |= (MCB_AA_PCMOUT_HIZ2 | MCB_AA_PCMOUT_HIZ1 | MCB_AA_PCMOUT_HIZ0);
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_BCLK_MSK_1, bReg);
++
++      /*      DI*_BCKP        */
++
++      /*      PA*_MSK, PA*_DDR        */
++      bReg    = MCI_AA_PA_MSK_1_DEF;
++      if(psInitInfo->bPad0Func == MCDRV_PAD_PDMCK)
++      {
++              bReg    |= MCB_AA_PA0_DDR;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PA_MSK_1, bReg);
++
++      /*      PA0_OUT */
++      if(psInitInfo->bPad0Func == MCDRV_PAD_PDMCK)
++      {
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PA_OUT, MCB_AA_PA_OUT);
++      }
++
++      /*      SCU_PA* */
++
++      /*      CKSEL   */
++      if(psInitInfo->bCkSel != MCDRV_CKSEL_CMOS)
++      {
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_CKSEL, MCB_AA_CKSEL);
++      }
++
++      /*      DIVR0, DIVF0    */
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_DIVR0, psInitInfo->bDivR0);
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_DIVF0, psInitInfo->bDivF0);
++
++      /*      Clock Start     */
++      sdRet   = McDevIf_ExecutePacket_AA();
++      if(sdRet != MCDRV_SUCCESS)
++      {
++              return sdRet;
++      }
++      McSrv_ClockStart();
++
++      /*      DP0     */
++      bReg    = MCB_AA_PWM_DP2|MCB_AA_PWM_DP1;
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PWM_DIGITAL, bReg);
++      if(psInitInfo->bCkSel != MCDRV_CKSEL_CMOS)
++      {
++              /*      2ms wait        */
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_TIMWAIT_AA | MCDRV_TCXO_WAIT_TIME_AA, 0);
++      }
++
++      /*      PLLRST0 */
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PLL_RST, 0);
++      /*      2ms wait        */
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_TIMWAIT_AA | MCDRV_PLRST_WAIT_TIME_AA, 0);
++      /*      DP1/DP2 up      */
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PWM_DIGITAL, 0);
++      /*      RSTB    */
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_RSTB, 0);
++      /*      DPB     */
++      bReg    = MCB_AA_PWM_DPPDM|MCB_AA_PWM_DPDI2|MCB_AA_PWM_DPDI1|MCB_AA_PWM_DPDI0;
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PWM_DIGITAL_1, bReg);
++
++      /*      DCL_GAIN, DCL_LMT       */
++      bReg    = (psInitInfo->bDclGain<<4) | psInitInfo->bDclLimit;
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_CODEC_AA | MCI_AA_DCL, bReg);
++
++      /*      DIF_LI, DIF_LO* */
++      bReg    = (psInitInfo->bLineOut2Dif<<5) | (psInitInfo->bLineOut1Dif<<4) | psInitInfo->bLineIn1Dif;
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_DIF_LINE, bReg);
++
++      /*      SP*_HIZ, SPMN   */
++      bReg    = (psInitInfo->bSpmn << 1);
++      if(MCDRV_SPHIZ_HIZ == psInitInfo->bSpHiz)
++      {
++              bReg    |= (MCB_AA_SPL_HIZ|MCB_AA_SPR_HIZ);
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_SP_MODE, bReg);
++
++      /*      MC*SNG  */
++      bReg    = (psInitInfo->bMic2Sng<<6) | (psInitInfo->bMic1Sng<<2);
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_MC_GAIN, bReg);
++      bReg    = (psInitInfo->bMic3Sng<<2);
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_MC3_GAIN, bReg);
++
++      /*      AVDDLEV, VREFLEV        */
++      bReg    = 0x20 | psInitInfo->bAvddLev;
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_LEV, bReg);
++
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_A_AA | (UINT32)MCI_AA_ANA_ADR, MCI_AA_PWM_ANALOG_0);
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_A_AA | (UINT32)60, 0xD9);
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_A_AA | (UINT32)MCI_AA_ANA_WINDOW, MCI_AA_PWM_ANALOG_0_DEF);
++
++      if((psInitInfo->bPowerMode & MCDRV_POWMODE_VREFON) != 0 || McResCtrl_GetAPMode_AA() == eMCDRV_APM_OFF_AA)
++      {
++              bReg    = MCI_AA_PWM_ANALOG_0_DEF;
++              if(psInitInfo->bLdo == MCDRV_LDO_ON)
++              {
++                      /*      AP_LDOA */
++                      bReg    &= (UINT8)~MCB_AA_PWM_LDOA;
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_PWM_ANALOG_0, bReg);
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_TIMWAIT_AA | MCDRV_LDOA_WAIT_TIME_AA, 0);
++              }
++              else
++              {
++                      bReg    &= (UINT8)~MCB_AA_PWM_REFA;
++              }
++              /*      AP_VR up        */
++              bReg    &= (UINT8)~MCB_AA_PWM_VR;
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_PWM_ANALOG_0, bReg);
++              sdRet   = McDevIf_ExecutePacket_AA();
++              if(sdRet != MCDRV_SUCCESS)
++              {
++                      return sdRet;
++              }
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_TIMWAIT_AA | psInitInfo->sWaitTime.dVrefRdy2, 0);
++      }
++
++      if(McResCtrl_GetAPMode_AA() == eMCDRV_APM_OFF_AA)
++      {
++              bReg    = MCB_AA_AMPOFF_SP|MCB_AA_AMPOFF_HP|MCB_AA_AMPOFF_RC;
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_AMP, bReg);
++      }
++
++      sdRet   = McDevIf_ExecutePacket_AA();
++      if (MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      /*      unused path power down  */
++      McResCtrl_GetPowerInfo_AA(&sPowerInfo);
++      sPowerUpdate.dDigital           = MCDRV_POWUPDATE_DIGITAL_ALL_AA;
++      sPowerUpdate.abAnalog[0]        = (UINT8)MCDRV_POWUPDATE_ANALOG0_ALL_AA;
++      sPowerUpdate.abAnalog[1]        = (UINT8)MCDRV_POWUPDATE_ANALOG1_ALL_AA;
++      sPowerUpdate.abAnalog[2]        = (UINT8)MCDRV_POWUPDATE_ANALOG2_ALL_AA;
++      sPowerUpdate.abAnalog[3]        = (UINT8)MCDRV_POWUPDATE_ANALOG3_ALL_AA;
++      sPowerUpdate.abAnalog[4]        = (UINT8)MCDRV_POWUPDATE_ANALOG4_ALL_AA;
++      return McPacket_AddPowerDown_AA(&sPowerInfo, &sPowerUpdate);
++}
++
++/****************************************************************************
++ *    McPacket_AddPowerUp_AA
++ *
++ *    Description:
++ *                    Add powerup packet.
++ *    Arguments:
++ *                    psPowerInfo             power information
++ *                    psPowerUpdate   power update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddPowerUp_AA
++(
++      const MCDRV_POWER_INFO_AA*              psPowerInfo,
++      const MCDRV_POWER_UPDATE_AA*    psPowerUpdate
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bReg;
++      UINT8   bRegCur;
++      UINT8   bRegAna1;
++      UINT8   bRegAna2;
++      UINT32  dUpdate;
++      UINT8   bRegChange;
++      UINT8   bSpHizReg;
++      UINT32  dWaitTime;
++      UINT32  dWaitTimeDone   = 0;
++      UINT8   bWaitVREFRDY    = 0;
++      UINT8   bWaitHPVolUp    = 0;
++      UINT8   bWaitSPVolUp    = 0;
++      MCDRV_INIT_INFO sInitInfo;
++
++
++      McResCtrl_GetInitInfo_AA(&sInitInfo);
++
++      /*      Digital Power   */
++      dUpdate = ~psPowerInfo->dDigital & psPowerUpdate->dDigital;
++      if((dUpdate & MCDRV_POWINFO_DIGITAL_DP0_AA) != 0)
++      {
++              if((McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_BASE_AA, MCI_AA_PWM_DIGITAL) & MCB_AA_PWM_DP0) != 0)
++              {/*     DP0 changed     */
++                      /*      CKSEL   */
++                      if(sInitInfo.bCkSel != MCDRV_CKSEL_CMOS)
++                      {
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | (UINT32)MCI_AA_CKSEL, MCB_AA_CKSEL);
++                      }
++                      else
++                      {
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | (UINT32)MCI_AA_CKSEL, 0);
++                      }
++                      /*      DIVR0, DIVF0    */
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | (UINT32)MCI_AA_DIVR0, sInitInfo.bDivR0);
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | (UINT32)MCI_AA_DIVF0, sInitInfo.bDivF0);
++                      sdRet   = McDevIf_ExecutePacket_AA();
++                      if(sdRet != MCDRV_SUCCESS)
++                      {
++                              return sdRet;
++                      }
++                      /*      Clock Start     */
++                      McSrv_ClockStart();
++                      /*      DP0 up  */
++                      bReg    = MCB_AA_PWM_DP2|MCB_AA_PWM_DP1;
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PWM_DIGITAL, bReg);
++                      if(sInitInfo.bCkSel != MCDRV_CKSEL_CMOS)
++                      {
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_TIMWAIT_AA | MCDRV_TCXO_WAIT_TIME_AA, 0);
++                      }
++                      /*      PLLRST0 up      */
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PLL_RST, 0);
++                      /*      2ms wait        */
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_TIMWAIT_AA | MCDRV_PLRST_WAIT_TIME_AA, 0);
++                      /*      DP1/DP2 up      */
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PWM_DIGITAL, 0);
++                      /*      DPB/DPDI* up    */
++                      bReg    = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_BASE_AA, MCI_AA_PWM_DIGITAL_1);
++                      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPDI0_AA) != 0)
++                      {
++                              bReg    &= (UINT8)~MCB_AA_PWM_DPDI0;
++                      }
++                      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPDI1_AA) != 0)
++                      {
++                              bReg    &= (UINT8)~MCB_AA_PWM_DPDI1;
++                      }
++                      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPDI2_AA) != 0)
++                      {
++                              bReg    &= (UINT8)~MCB_AA_PWM_DPDI2;
++                      }
++                      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPPDM_AA) != 0)
++                      {
++                              bReg    &= (UINT8)~MCB_AA_PWM_DPPDM;
++                      }
++                      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPB_AA) != 0)
++                      {
++                              bReg    &= (UINT8)~MCB_AA_PWM_DPB;
++                      }
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PWM_DIGITAL_1, bReg);
++              }
++              else if((dUpdate & MCDRV_POWINFO_DIGITAL_DP2_AA) != 0)
++              {
++                      /*      DP1/DP2 up      */
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PWM_DIGITAL, 0);
++                      /*      DPB/DPDI* up    */
++                      bReg    = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_BASE_AA, MCI_AA_PWM_DIGITAL_1);
++                      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPDI0_AA) != 0)
++                      {
++                              bReg    &= (UINT8)~MCB_AA_PWM_DPDI0;
++                      }
++                      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPDI1_AA) != 0)
++                      {
++                              bReg    &= (UINT8)~MCB_AA_PWM_DPDI1;
++                      }
++                      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPDI2_AA) != 0)
++                      {
++                              bReg    &= (UINT8)~MCB_AA_PWM_DPDI2;
++                      }
++                      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPPDM_AA) != 0)
++                      {
++                              bReg    &= (UINT8)~MCB_AA_PWM_DPPDM;
++                      }
++                      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPB_AA) != 0)
++                      {
++                              bReg    &= (UINT8)~MCB_AA_PWM_DPB;
++                      }
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PWM_DIGITAL_1, bReg);
++              }
++
++              /*      DPBDSP  */
++              if((dUpdate & MCDRV_POWINFO_DIGITAL_DPBDSP_AA) != 0)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PWM_DIGITAL_BDSP, 0);
++              }
++              /*      DPADIF  */
++              if((dUpdate & MCDRV_POWINFO_DIGITAL_DPADIF_AA) != 0)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_CODEC_AA | MCI_AA_DPADIF, 0);
++              }
++      }
++
++      if(McResCtrl_GetAPMode_AA() == eMCDRV_APM_ON_AA)
++      {
++              return AddAnalogPowerUpAuto(psPowerInfo, psPowerUpdate);
++      }
++
++      /*      Analog Power    */
++      dUpdate = ~psPowerInfo->abAnalog[0] & psPowerUpdate->abAnalog[0];
++      if((dUpdate & MCB_AA_PWM_VR) != 0)
++      {
++              if((McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_PWM_ANALOG_0) & MCB_AA_PWM_VR) != 0)
++              {/*     AP_VR changed   */
++                      bReg    = MCI_AA_PWM_ANALOG_0_DEF;
++                      if(sInitInfo.bLdo == MCDRV_LDO_ON)
++                      {
++                              /*      AP_LDOA */
++                              bReg    &= (UINT8)~MCB_AA_PWM_LDOA;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | (UINT32)MCI_AA_PWM_ANALOG_0, bReg);
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_TIMWAIT_AA | MCDRV_LDOA_WAIT_TIME_AA, 0);
++                      }
++                      else
++                      {
++                              bReg    &= (UINT8)~MCB_AA_PWM_REFA;
++                      }
++                      /*      AP_VR up        */
++                      bReg    &= (UINT8)~MCB_AA_PWM_VR;
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | (UINT32)MCI_AA_PWM_ANALOG_0, bReg);
++                      dWaitTimeDone   = sInitInfo.sWaitTime.dVrefRdy1;
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_TIMWAIT_AA | dWaitTimeDone, 0);
++                      bWaitVREFRDY    = 1;
++              }
++
++              bReg    = (UINT8)~((UINT8)~psPowerInfo->abAnalog[1] & psPowerUpdate->abAnalog[1]) & McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_PWM_ANALOG_1);
++              /*      SP_HIZ control  */
++              if(MCDRV_SPHIZ_HIZ == sInitInfo.bSpHiz)
++              {
++                      bSpHizReg       = 0;
++                      if((bReg & (MCB_AA_PWM_SPL1 | MCB_AA_PWM_SPL2)) != 0)
++                      {
++                              bSpHizReg |= MCB_AA_SPL_HIZ;
++                      }
++
++                      if((bReg & (MCB_AA_PWM_SPR1 | MCB_AA_PWM_SPR2)) != 0)
++                      {
++                              bSpHizReg |= MCB_AA_SPR_HIZ;
++                      }
++
++                      bSpHizReg |= (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_SP_MODE) & (MCB_AA_SPMN | MCB_AA_SP_SWAP));
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_SP_MODE, bSpHizReg);
++              }
++
++              bRegCur = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_PWM_ANALOG_3);
++              bReg    = (UINT8)~((UINT8)~psPowerInfo->abAnalog[3] & psPowerUpdate->abAnalog[3]) & bRegCur;
++              bRegChange      = bReg ^ bRegCur;
++              /*      set DACON and NSMUTE before setting 0 to AP_DA  */
++              if((bRegChange & MCB_AA_PWM_DA) != 0 && (psPowerInfo->abAnalog[3] & psPowerUpdate->abAnalog[3] & MCB_AA_PWM_DA) == 0)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_CODEC_AA | (UINT32)MCI_AA_DAC_CONFIG, MCB_AA_NSMUTE);
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_CODEC_AA | (UINT32)MCI_AA_DAC_CONFIG, (MCB_AA_DACON | MCB_AA_NSMUTE));
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_CODEC_AA | (UINT32)MCI_AA_DAC_CONFIG, MCB_AA_DACON);
++              }
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_PWM_ANALOG_3, bReg);
++
++              bRegCur = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_PWM_ANALOG_4);
++              bReg    = (UINT8)~((UINT8)~psPowerInfo->abAnalog[4] & psPowerUpdate->abAnalog[4]) & bRegCur;
++              bRegChange      |= (bReg ^ bRegCur);
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_PWM_ANALOG_4, bReg);
++
++              if(bWaitVREFRDY != 0)
++              {
++                      /*      wait VREF_RDY   */
++                      dWaitTimeDone   = sInitInfo.sWaitTime.dVrefRdy2 - dWaitTimeDone;
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_TIMWAIT_AA | dWaitTimeDone, 0);
++              }
++
++              sdRet   = McDevIf_ExecutePacket_AA();
++              if(sdRet != MCDRV_SUCCESS)
++              {
++                      return sdRet;
++              }
++              bRegCur = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_PWM_ANALOG_0);
++              bReg    = (UINT8)~dUpdate & bRegCur;
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_PWM_ANALOG_0, bReg);
++              if((bRegCur & MCB_AA_PWM_CP) != 0 && (bReg & MCB_AA_PWM_CP) == 0)
++              {/*     AP_CP up        */
++                      dWaitTime               = MCDRV_HP_WAIT_TIME_AA;
++              }
++              else
++              {
++                      dWaitTime       = 0;
++              }
++
++              bRegCur = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_PWM_ANALOG_1);
++              bRegAna1        = (UINT8)~(~psPowerInfo->abAnalog[1] & psPowerUpdate->abAnalog[1]) & bRegCur;
++              if(((bRegCur & MCB_AA_PWM_SPL1) != 0 && (bRegAna1 & MCB_AA_PWM_SPL1) == 0)
++              || ((bRegCur & MCB_AA_PWM_SPR1) != 0 && (bRegAna1 & MCB_AA_PWM_SPR1) == 0))
++              {/*     AP_SP* up       */
++                      bReg    = bRegAna1|(bRegCur&(UINT8)~(MCB_AA_PWM_SPL1|MCB_AA_PWM_SPR1));
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_PWM_ANALOG_1, bReg);
++                      if(dWaitTime == (UINT32)0)
++                      {
++                              dWaitTime               = MCDRV_SP_WAIT_TIME_AA;
++                              bWaitSPVolUp    = 1;
++                      }
++              }
++              if(((bRegCur & MCB_AA_PWM_HPL) != 0 && (bRegAna1 & MCB_AA_PWM_HPL) == 0)
++              || ((bRegCur & MCB_AA_PWM_HPR) != 0 && (bRegAna1 & MCB_AA_PWM_HPR) == 0))
++              {
++                      bWaitHPVolUp    = 1;
++              }
++
++              bRegCur = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_PWM_ANALOG_2);
++              bRegAna2        = (UINT8)~(~psPowerInfo->abAnalog[2] & psPowerUpdate->abAnalog[2]) & bRegCur;
++              if((bRegCur & MCB_AA_PWM_RC1) != 0 && (bRegAna2 & MCB_AA_PWM_RC1) == 0)
++              {/*     AP_RC up        */
++                      bReg    = bRegAna2|(bRegCur&~MCB_AA_PWM_RC1);
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_PWM_ANALOG_2, bReg);
++                      if(dWaitTime == (UINT32)0)
++                      {
++                              dWaitTime       = MCDRV_RC_WAIT_TIME_AA;
++                      }
++              }
++              if(dWaitTime > (UINT32)0)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_TIMWAIT_AA | dWaitTime, 0);
++                      dWaitTimeDone   += dWaitTime;
++              }
++
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_PWM_ANALOG_1, bRegAna1);
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_PWM_ANALOG_2, bRegAna2);
++
++              /*      time wait       */
++              dWaitTime       = GetMaxWait(bRegChange);
++              if(dWaitTime > dWaitTimeDone)
++              {
++                      dWaitTime       = dWaitTime - dWaitTimeDone;
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_TIMWAIT_AA | dWaitTime, 0);
++                      dWaitTimeDone   += dWaitTime;
++              }
++
++              if(bWaitSPVolUp != 0 && sInitInfo.sWaitTime.dSpRdy > dWaitTimeDone)
++              {
++                      dWaitTime       = sInitInfo.sWaitTime.dSpRdy - dWaitTimeDone;
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_TIMWAIT_AA | dWaitTime, 0);
++                      dWaitTimeDone   += dWaitTime;
++              }
++              if(bWaitHPVolUp != 0 && sInitInfo.sWaitTime.dHpRdy > dWaitTimeDone)
++              {
++                      dWaitTime       = sInitInfo.sWaitTime.dHpRdy - dWaitTimeDone;
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_TIMWAIT_AA | dWaitTime, 0);
++                      dWaitTimeDone   += dWaitTime;
++              }
++      }
++      return sdRet;
++}
++
++/****************************************************************************
++ *    AddAnalogPowerUpAuto
++ *
++ *    Description:
++ *                    Add analog auto powerup packet.
++ *    Arguments:
++ *                    psPowerInfo             power information
++ *                    psPowerUpdate   power update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++static SINT32 AddAnalogPowerUpAuto
++(
++      const MCDRV_POWER_INFO_AA*              psPowerInfo,
++      const MCDRV_POWER_UPDATE_AA*    psPowerUpdate
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bReg;
++      UINT8   bRegCur;
++      UINT32  dUpdate;
++      UINT8   bRegChange;
++      UINT8   bSpHizReg;
++      MCDRV_INIT_INFO sInitInfo;
++      UINT32  dWaitTime       = 0;
++
++
++      McResCtrl_GetInitInfo_AA(&sInitInfo);
++
++      /*      Analog Power    */
++      dUpdate = (UINT32)~psPowerInfo->abAnalog[0] & psPowerUpdate->abAnalog[0];
++      if((dUpdate & MCB_AA_PWM_VR) != 0)
++      {
++              if((McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_PWM_ANALOG_0) & MCB_AA_PWM_VR) != 0)
++              {/*     AP_VR changed   */
++                      /*      AP_VR up        */
++                      bReg    = MCI_AA_PWM_ANALOG_0_DEF;
++                      if(sInitInfo.bLdo == MCDRV_LDO_ON)
++                      {
++                              /*      AP_LDOA */
++                              bReg    &= (UINT8)~MCB_AA_PWM_LDOA;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | (UINT32)MCI_AA_PWM_ANALOG_0, bReg);
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_TIMWAIT_AA | MCDRV_LDOA_WAIT_TIME_AA, 0);
++                      }
++                      else
++                      {
++                              bReg    &= (UINT8)~MCB_AA_PWM_REFA;
++                      }
++                      bReg    &= (UINT8)~MCB_AA_PWM_VR;
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | (UINT32)MCI_AA_PWM_ANALOG_0, bReg);
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_TIMWAIT_AA | sInitInfo.sWaitTime.dVrefRdy1, 0);
++                      if(sInitInfo.sWaitTime.dVrefRdy2 > sInitInfo.sWaitTime.dVrefRdy1)
++                      {
++                              dWaitTime       = sInitInfo.sWaitTime.dVrefRdy2 - sInitInfo.sWaitTime.dVrefRdy1;
++                      }
++              }
++
++              bReg    = (UINT8)~((UINT8)~psPowerInfo->abAnalog[1] & psPowerUpdate->abAnalog[1]) & McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_PWM_ANALOG_1);
++              /*      SP_HIZ control  */
++              if(MCDRV_SPHIZ_HIZ == sInitInfo.bSpHiz)
++              {
++                      bSpHizReg       = 0;
++                      if((bReg & (MCB_AA_PWM_SPL1 | MCB_AA_PWM_SPL2)) != 0)
++                      {
++                              bSpHizReg |= MCB_AA_SPL_HIZ;
++                      }
++
++                      if((bReg & (MCB_AA_PWM_SPR1 | MCB_AA_PWM_SPR2)) != 0)
++                      {
++                              bSpHizReg |= MCB_AA_SPR_HIZ;
++                      }
++
++                      bSpHizReg |= (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_SP_MODE) & (MCB_AA_SPMN | MCB_AA_SP_SWAP));
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_SP_MODE, bSpHizReg);
++              }
++
++              bRegCur = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_PWM_ANALOG_3);
++              bReg    = (UINT8)~((UINT8)~psPowerInfo->abAnalog[3] & psPowerUpdate->abAnalog[3]) & bRegCur;
++              bRegChange      = bReg ^ bRegCur;
++              /*      set DACON and NSMUTE before setting 0 to AP_DA  */
++              if((bRegChange & MCB_AA_PWM_DA) != 0 && (psPowerInfo->abAnalog[3] & psPowerUpdate->abAnalog[3] & MCB_AA_PWM_DA) == 0)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_CODEC_AA | (UINT32)MCI_AA_DAC_CONFIG, MCB_AA_NSMUTE);
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_CODEC_AA | (UINT32)MCI_AA_DAC_CONFIG, (MCB_AA_DACON | MCB_AA_NSMUTE));
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_CODEC_AA | (UINT32)MCI_AA_DAC_CONFIG, MCB_AA_DACON);
++              }
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_PWM_ANALOG_3, bReg);
++
++              bRegCur = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_PWM_ANALOG_4);
++              bReg    = (UINT8)~((UINT8)~psPowerInfo->abAnalog[4] & psPowerUpdate->abAnalog[4]) & bRegCur;
++              bRegChange      |= (bReg ^ bRegCur);
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_PWM_ANALOG_4, bReg);
++
++              if(dWaitTime > (UINT32)0)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_TIMWAIT_AA | dWaitTime, 0);
++              }
++
++              sdRet   = McDevIf_ExecutePacket_AA();
++              if(sdRet != MCDRV_SUCCESS)
++              {
++                      return sdRet;
++              }
++              bRegCur = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_PWM_ANALOG_0);
++              bReg    = (UINT8)~dUpdate & bRegCur;
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_PWM_ANALOG_0, bReg);
++
++              bRegCur = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_PWM_ANALOG_1);
++              bReg    = (UINT8)~((UINT8)~psPowerInfo->abAnalog[1] & psPowerUpdate->abAnalog[1]) & bRegCur;
++              if((bRegCur & (MCB_AA_PWM_ADL|MCB_AA_PWM_ADR)) != (bReg & (MCB_AA_PWM_ADL|MCB_AA_PWM_ADR)))
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_PWM_ANALOG_1, bReg);
++              }
++              else
++              {
++                      sdRet   = McDevIf_ExecutePacket_AA();
++                      if(sdRet != MCDRV_SUCCESS)
++                      {
++                              return sdRet;
++                      }
++                      McResCtrl_SetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_PWM_ANALOG_1, bReg);
++              }
++
++              bRegCur = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_PWM_ANALOG_2);
++              bReg    = (UINT8)~((UINT8)~psPowerInfo->abAnalog[2] & psPowerUpdate->abAnalog[2]) & bRegCur;
++              if((bRegCur & (MCB_AA_PWM_LO1L|MCB_AA_PWM_LO1R|MCB_AA_PWM_LO2L|MCB_AA_PWM_LO2R)) != (bReg & (MCB_AA_PWM_LO1L|MCB_AA_PWM_LO1R|MCB_AA_PWM_LO2L|MCB_AA_PWM_LO2R)))
++              {
++                      bReg    = bReg|(bRegCur&(MCB_AA_PWM_RC1|MCB_AA_PWM_RC2));
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_PWM_ANALOG_2, bReg);
++              }
++              else
++              {
++                      sdRet   = McDevIf_ExecutePacket_AA();
++                      if(sdRet != MCDRV_SUCCESS)
++                      {
++                              return sdRet;
++                      }
++                      McResCtrl_SetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_PWM_ANALOG_2, bReg);
++              }
++
++              /*      time wait       */
++              if(dWaitTime < GetMaxWait(bRegChange))
++              {
++                      dWaitTime       = GetMaxWait(bRegChange) - dWaitTime;
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_TIMWAIT_AA | dWaitTime, 0);
++              }
++      }
++      return sdRet;
++}
++
++/****************************************************************************
++ *    McPacket_AddPowerDown_AA
++ *
++ *    Description:
++ *                    Add powerdown packet.
++ *    Arguments:
++ *                    psPowerInfo             power information
++ *                    psPowerUpdate   power update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddPowerDown_AA
++(
++      const MCDRV_POWER_INFO_AA*              psPowerInfo,
++      const MCDRV_POWER_UPDATE_AA*    psPowerUpdate
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bReg;
++      UINT8   bRegCur;
++      UINT32  dUpdate = psPowerInfo->dDigital & psPowerUpdate->dDigital;
++      UINT32  dAPMDoneParam;
++      UINT32  dAnaRdyParam;
++      UINT8   bSpHizReg;
++      MCDRV_INIT_INFO sInitInfo;
++
++
++      McResCtrl_GetInitInfo_AA(&sInitInfo);
++
++      if(McResCtrl_GetAPMode_AA() == eMCDRV_APM_ON_AA)
++      {
++              if(((psPowerInfo->abAnalog[0] & psPowerUpdate->abAnalog[0] & MCB_AA_PWM_VR) != 0
++                      && (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_PWM_ANALOG_0) & MCB_AA_PWM_VR) == 0))
++              {
++                      /*      wait AP_XX_A    */
++                      dAPMDoneParam   = ((MCB_AA_AP_CP_A|MCB_AA_AP_HPL_A|MCB_AA_AP_HPR_A)<<8)
++                                                      | (MCB_AA_AP_RC1_A|MCB_AA_AP_RC2_A|MCB_AA_AP_SPL1_A|MCB_AA_AP_SPR1_A|MCB_AA_AP_SPL2_A|MCB_AA_AP_SPR2_A);
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_EVTWAIT_AA | MCDRV_EVT_APM_DONE_AA | dAPMDoneParam, 0);
++              }
++      }
++
++      if((dUpdate & MCDRV_POWINFO_DIGITAL_DP0_AA) != 0
++      && (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_BASE_AA, MCI_AA_PWM_DIGITAL) & MCB_AA_PWM_DP0) == 0)
++      {
++              /*      wait mute complete      */
++              sdRet   = McDevIf_ExecutePacket_AA();
++              if(sdRet != MCDRV_SUCCESS)
++              {
++                      return sdRet;
++              }
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_EVTWAIT_AA | MCDRV_EVT_ALLMUTE_AA, 0);
++      }
++
++      /*      Analog Power    */
++      bRegCur = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_PWM_ANALOG_1);
++      bReg    = (psPowerInfo->abAnalog[1] & psPowerUpdate->abAnalog[1]) | bRegCur;
++      if((psPowerUpdate->abAnalog[1] & MCDRV_POWUPDATE_ANALOG1_OUT_AA) != 0 && (MCDRV_SPHIZ_HIZ == sInitInfo.bSpHiz))
++      {
++              /*      SP_HIZ control  */
++              bSpHizReg       = 0;
++              if((bReg & (MCB_AA_PWM_SPL1 | MCB_AA_PWM_SPL2)) != 0)
++              {
++                      bSpHizReg |= MCB_AA_SPL_HIZ;
++              }
++
++              if((bReg & (MCB_AA_PWM_SPR1 | MCB_AA_PWM_SPR2)) != 0)
++              {
++                      bSpHizReg |= MCB_AA_SPR_HIZ;
++              }
++
++              bSpHizReg |= (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_SP_MODE) & (MCB_AA_SPMN | MCB_AA_SP_SWAP));
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_SP_MODE, bSpHizReg);
++      }
++
++      if(McResCtrl_GetAPMode_AA() == eMCDRV_APM_ON_AA)
++      {
++              if((bRegCur & (MCB_AA_PWM_ADL|MCB_AA_PWM_ADR)) != (bReg & (MCB_AA_PWM_ADL|MCB_AA_PWM_ADR)))
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_PWM_ANALOG_1, bReg);
++              }
++              else
++              {
++                      sdRet   = McDevIf_ExecutePacket_AA();
++                      if(sdRet != MCDRV_SUCCESS)
++                      {
++                              return sdRet;
++                      }
++                      McResCtrl_SetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_PWM_ANALOG_1, bReg);
++              }
++      }
++      else
++      {
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | (UINT32)MCI_AA_PWM_ANALOG_1, bReg);
++      }
++
++      bRegCur = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_PWM_ANALOG_2);
++      bReg    = (psPowerInfo->abAnalog[2] & psPowerUpdate->abAnalog[2]) | bRegCur;
++      if(McResCtrl_GetAPMode_AA() == eMCDRV_APM_ON_AA)
++      {
++              if((bRegCur & (MCB_AA_PWM_LO1L|MCB_AA_PWM_LO1R|MCB_AA_PWM_LO2L|MCB_AA_PWM_LO2R)) != (bReg & (MCB_AA_PWM_LO1L|MCB_AA_PWM_LO1R|MCB_AA_PWM_LO2L|MCB_AA_PWM_LO2R)))
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_PWM_ANALOG_2, bReg);
++              }
++              else
++              {
++                      sdRet   = McDevIf_ExecutePacket_AA();
++                      if(sdRet != MCDRV_SUCCESS)
++                      {
++                              return sdRet;
++                      }
++                      McResCtrl_SetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_PWM_ANALOG_2, bReg);
++              }
++      }
++      else
++      {
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | (UINT32)MCI_AA_PWM_ANALOG_2, bReg);
++      }
++
++      bReg    = (UINT8)(psPowerInfo->abAnalog[3] & psPowerUpdate->abAnalog[3]) | McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_PWM_ANALOG_3);
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_PWM_ANALOG_3, bReg);
++      bReg    = (UINT8)(psPowerInfo->abAnalog[4] & psPowerUpdate->abAnalog[4]) | McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_PWM_ANALOG_4);
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_PWM_ANALOG_4, bReg);
++
++      /*      set DACON and NSMUTE after setting 1 to AP_DA   */
++      if((psPowerInfo->abAnalog[3] & psPowerUpdate->abAnalog[3] & MCB_AA_PWM_DA) != 0)
++      {
++              if((McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_CODEC_AA, MCI_AA_DAC_CONFIG) & MCB_AA_DACON) == MCB_AA_DACON)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_EVTWAIT_AA | MCDRV_EVT_DACMUTE_AA | (UINT32)((MCB_AA_DAC_FLAGL<<8)|MCB_AA_DAC_FLAGR), 0);
++              }
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_CODEC_AA | (UINT32)MCI_AA_DAC_CONFIG, MCB_AA_NSMUTE);
++      }
++
++      bRegCur = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_PWM_ANALOG_0);
++      bReg    = psPowerInfo->abAnalog[0] & psPowerUpdate->abAnalog[0];
++      if(McResCtrl_GetAPMode_AA() == eMCDRV_APM_OFF_AA)
++      {
++              /*      wait CPPDRDY    */
++              dAnaRdyParam    = 0;
++              if((bRegCur & MCB_AA_PWM_CP) == 0 && (bReg & MCB_AA_PWM_CP) == MCB_AA_PWM_CP)
++              {
++                      dAnaRdyParam    = MCB_AA_CPPDRDY;
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_EVTWAIT_AA | MCDRV_EVT_ANA_RDY_AA | dAnaRdyParam, 0);
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | (UINT32)MCI_AA_PWM_ANALOG_0, (bRegCur|MCB_AA_PWM_CP));
++              }
++      }
++
++      if((bReg & MCB_AA_PWM_VR) != 0 && (bRegCur & MCB_AA_PWM_VR) == 0)
++      {/*     AP_VR changed   */
++              /*      AP_xx down      */
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | (UINT32)MCI_AA_PWM_ANALOG_0, MCI_AA_PWM_ANALOG_0_DEF);
++      }
++      else
++      {
++              bReg    |= bRegCur;
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | (UINT32)MCI_AA_PWM_ANALOG_0, bReg);
++      }
++
++
++      /*      Digital Power   */
++      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPADIF_AA) != 0
++      && McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_CODEC_AA, MCI_AA_DPADIF) != MCB_AA_DPADIF)
++      {
++              /*      AD_MUTE */
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_CODEC_AA | MCI_AA_AD_MUTE, MCB_AA_AD_MUTE);
++              /*      DPADIF  */
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_CODEC_AA | MCI_AA_DPADIF, MCB_AA_DPADIF);
++      }
++
++      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPPDM_AA) != 0
++      && (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_BASE_AA, MCI_AA_PWM_DIGITAL_1) & MCB_AA_PWM_DPPDM) == 0)
++      {
++              /*      PDM_MUTE        */
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_PDM_MUTE, MCB_AA_PDM_MUTE);
++      }
++
++      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPBDSP_AA) != 0)
++      {
++              /*      DPBDSP  */
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PWM_DIGITAL_BDSP, MCB_AA_PWM_DPBDSP);
++      }
++
++      /*      DPDI*, DPPDM    */
++      bReg    = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_BASE_AA, MCI_AA_PWM_DIGITAL_1);
++      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPDI0_AA) != 0 || (dUpdate & MCDRV_POWINFO_DIGITAL_DP2_AA) != 0)
++      {
++              bReg |= MCB_AA_PWM_DPDI0;
++      }
++      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPDI1_AA) != 0 || (dUpdate & MCDRV_POWINFO_DIGITAL_DP2_AA) != 0)
++      {
++              bReg |= MCB_AA_PWM_DPDI1;
++      }
++      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPDI2_AA) != 0 || (dUpdate & MCDRV_POWINFO_DIGITAL_DP2_AA) != 0)
++      {
++              bReg |= MCB_AA_PWM_DPDI2;
++      }
++      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPPDM_AA) != 0)
++      {
++              bReg |= MCB_AA_PWM_DPPDM;
++      }
++      if(bReg != 0)
++      {
++              /*      cannot set DP* & DPB at the same time   */
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PWM_DIGITAL_1, bReg);
++      }
++      /*      DPB     */
++      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPB_AA) != 0)
++      {
++              bReg |= MCB_AA_PWM_DPB;
++      }
++      if(bReg != 0)
++      {
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PWM_DIGITAL_1, bReg);
++      }
++
++      if((dUpdate & MCDRV_POWINFO_DIGITAL_DP2_AA) != 0
++      && (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_BASE_AA, MCI_AA_PWM_DIGITAL) & MCB_AA_PWM_DP2) == 0)
++      {
++              if((dUpdate & MCDRV_POWINFO_DIGITAL_DP0_AA) != 0)
++              {
++                      /*      DP2, DP1        */
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PWM_DIGITAL, (MCB_AA_PWM_DP2 | MCB_AA_PWM_DP1));
++                      if((dUpdate & MCDRV_POWINFO_DIGITAL_PLLRST0_AA) != 0)
++                      {
++                              /*      PLLRST0 */
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PLL_RST, MCB_AA_PLLRST0);
++                      }
++                      /*      DP0     */
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PWM_DIGITAL, (MCB_AA_PWM_DP2 | MCB_AA_PWM_DP1 | MCB_AA_PWM_DP0));
++                      sdRet   = McDevIf_ExecutePacket_AA();
++                      if(sdRet != MCDRV_SUCCESS)
++                      {
++                              return sdRet;
++                      }
++                      McSrv_ClockStop();
++              }
++              else
++              {
++                      /*      DP2     */
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PWM_DIGITAL, MCB_AA_PWM_DP2);
++              }
++      }
++      return sdRet;
++}
++
++/****************************************************************************
++ *    McPacket_AddPathSet_AA
++ *
++ *    Description:
++ *                    Add path update packet.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddPathSet_AA
++(
++      void
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++
++      /*      DI Pad  */
++      AddDIPad();
++
++      /*      PAD(PDM)        */
++      AddPAD();
++
++      /*      Digital Mixer Source    */
++      sdRet   = AddSource();
++      if(sdRet != MCDRV_SUCCESS)
++      {
++              return sdRet;
++      }
++
++      /*      DIR*_START, DIT*_START  */
++      AddDIStart();
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    AddDIPad
++ *
++ *    Description:
++ *                    Add DI Pad setup packet.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   AddDIPad
++(
++      void
++)
++{
++      UINT8   bReg;
++      UINT8   bIsUsedDIR[3];
++      MCDRV_INIT_INFO sInitInfo;
++      MCDRV_PATH_INFO sPathInfo;
++      MCDRV_DIO_INFO  sDioInfo;
++
++      McResCtrl_GetInitInfo_AA(&sInitInfo);
++      McResCtrl_GetPathInfo_AA(&sPathInfo);
++      McResCtrl_GetDioInfo_AA(&sDioInfo);
++
++      /*      SDIN_MSK2/1     */
++      bReg    = 0;
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_DIR2_AA) == 0)
++      {
++              bReg |= MCB_AA_SDIN_MSK2;
++              bIsUsedDIR[2]   = 0;
++      }
++      else
++      {
++              bIsUsedDIR[2]   = 1;
++      }
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_DIR1_AA) == 0)
++      {
++              bReg |= MCB_AA_SDIN_MSK1;
++              bIsUsedDIR[1]   = 0;
++      }
++      else
++      {
++              bIsUsedDIR[1]   = 1;
++      }
++      /*      SDO_DDR2/1      */
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_DIT2_AA, eMCDRV_DST_CH0_AA) == 0)
++      {
++              if(sInitInfo.bDioSdo2Hiz == MCDRV_DAHIZ_LOW)
++              {
++                      bReg |= MCB_AA_SDO_DDR2;
++              }
++      }
++      else
++      {
++              bReg |= MCB_AA_SDO_DDR2;
++      }
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_DIT1_AA, eMCDRV_DST_CH0_AA) == 0)
++      {
++              if(sInitInfo.bDioSdo1Hiz == MCDRV_DAHIZ_LOW)
++              {
++                      bReg |= MCB_AA_SDO_DDR1;
++              }
++      }
++      else
++      {
++              bReg |= MCB_AA_SDO_DDR1;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | (UINT32)MCI_AA_SD_MSK, bReg);
++
++      /*      SDIN_MSK0       */
++      bReg    = 0;
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_DIR0_AA) == 0)
++      {
++              bReg |= MCB_AA_SDIN_MSK0;
++              bIsUsedDIR[0]   = 0;
++      }
++      else
++      {
++              bIsUsedDIR[0]   = 1;
++      }
++      /*      SDO_DDR0        */
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_DIT0_AA, eMCDRV_DST_CH0_AA) == 0)
++      {
++              if(sInitInfo.bDioSdo0Hiz == MCDRV_DAHIZ_LOW)
++              {
++                      bReg |= MCB_AA_SDO_DDR0;
++              }
++      }
++      else
++      {
++              bReg |= MCB_AA_SDO_DDR0;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | (UINT32)MCI_AA_SD_MSK_1, bReg);
++
++      /*      BCLK_MSK*, BCLD_DDR*, LRCK_MSK*, LRCK_DDR*      */
++      bReg    = 0;
++      if(bIsUsedDIR[2] == 0 && McResCtrl_GetDITSource_AA(eMCDRV_DIO_2_AA) == eMCDRV_SRC_NONE_AA)
++      {
++              bReg |= MCB_AA_BCLK_MSK2;
++              bReg |= MCB_AA_LRCK_MSK2;
++              if(sInitInfo.bDioClk2Hiz == MCDRV_DAHIZ_LOW)
++              {
++                      bReg |= MCB_AA_BCLK_DDR2;
++                      bReg |= MCB_AA_LRCK_DDR2;
++              }
++      }
++      else
++      {
++              if(sDioInfo.asPortInfo[2].sDioCommon.bMasterSlave == MCDRV_DIO_MASTER)
++              {
++                      bReg |= MCB_AA_BCLK_DDR2;
++                      bReg |= MCB_AA_LRCK_DDR2;
++              }
++      }
++      if(bIsUsedDIR[1] == 0 && McResCtrl_GetDITSource_AA(eMCDRV_DIO_1_AA) == eMCDRV_SRC_NONE_AA)
++      {
++              bReg |= MCB_AA_BCLK_MSK1;
++              bReg |= MCB_AA_LRCK_MSK1;
++              if(sInitInfo.bDioClk1Hiz == MCDRV_DAHIZ_LOW)
++              {
++                      bReg |= MCB_AA_BCLK_DDR1;
++                      bReg |= MCB_AA_LRCK_DDR1;
++              }
++      }
++      else
++      {
++              if(sDioInfo.asPortInfo[1].sDioCommon.bMasterSlave == MCDRV_DIO_MASTER)
++              {
++                      bReg |= MCB_AA_BCLK_DDR1;
++                      bReg |= MCB_AA_LRCK_DDR1;
++              }
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_BCLK_MSK, bReg);
++
++      /*      BCLK_MSK*, BCLD_DDR*, LRCK_MSK*, LRCK_DDR*, PCM_HIZ*    */
++      bReg    = 0;
++      if(bIsUsedDIR[0] == 0 && McResCtrl_GetDITSource_AA(eMCDRV_DIO_0_AA) == eMCDRV_SRC_NONE_AA)
++      {
++              bReg |= MCB_AA_BCLK_MSK0;
++              bReg |= MCB_AA_LRCK_MSK0;
++              if(sInitInfo.bDioClk0Hiz == MCDRV_DAHIZ_LOW)
++              {
++                      bReg |= MCB_AA_BCLK_DDR0;
++                      bReg |= MCB_AA_LRCK_DDR0;
++              }
++      }
++      else
++      {
++              if(sDioInfo.asPortInfo[0].sDioCommon.bMasterSlave == MCDRV_DIO_MASTER)
++              {
++                      bReg |= MCB_AA_BCLK_DDR0;
++                      bReg |= MCB_AA_LRCK_DDR0;
++              }
++      }
++      if(sInitInfo.bPcmHiz == MCDRV_PCMHIZ_HIZ)
++      {
++              bReg |= (MCB_AA_PCMOUT_HIZ2 | MCB_AA_PCMOUT_HIZ1 | MCB_AA_PCMOUT_HIZ0);
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_BCLK_MSK_1, bReg);
++}
++
++/****************************************************************************
++ *    AddPAD
++ *
++ *    Description:
++ *                    Add PAD setup packet.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   AddPAD
++(
++      void
++)
++{
++      UINT8   bReg;
++      MCDRV_INIT_INFO sInitInfo;
++
++      McResCtrl_GetInitInfo_AA(&sInitInfo);
++
++      /*      PA*_MSK */
++      bReg    = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_BASE_AA, MCI_AA_PA_MSK_1);
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_PDM_AA) == 0)
++      {
++              bReg    |= MCB_AA_PA0_MSK;
++              if(sInitInfo.bPad1Func == MCDRV_PAD_PDMDI)
++              {
++                      bReg    |= MCB_AA_PA1_MSK;
++              }
++      }
++      else
++      {
++              bReg    &= (UINT8)~MCB_AA_PA0_MSK;
++              if(sInitInfo.bPad1Func == MCDRV_PAD_PDMDI)
++              {
++                      bReg    &= (UINT8)~MCB_AA_PA1_MSK;
++              }
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PA_MSK_1, bReg);
++}
++
++/****************************************************************************
++ *    AddSource
++ *
++ *    Description:
++ *                    Add source setup packet.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++static SINT32 AddSource
++(
++      void
++)
++{
++      SINT32  sdRet                   = MCDRV_SUCCESS;
++      UINT8   bReg;
++      UINT8   bAEng6                  = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_AENG6_SOURCE);
++      UINT8   bRegAESource    = 0;
++      UINT8   bAESourceChange = 0;
++      UINT32  dXFadeParam             = 0;
++      MCDRV_SRC_TYPE_AA       eAESource       = McResCtrl_GetAESource_AA();
++      MCDRV_PATH_INFO sPathInfo;
++      MCDRV_DAC_INFO  sDacInfo;
++      MCDRV_AE_INFO   sAeInfo;
++
++      McResCtrl_GetPathInfo_AA(&sPathInfo);
++      McResCtrl_GetAeInfo_AA(&sAeInfo);
++
++      switch(eAESource)
++      {
++      case    eMCDRV_SRC_PDM_AA:              bRegAESource    = MCB_AA_AE_SOURCE_AD;          bAEng6  = MCB_AA_AENG6_PDM;     break;
++      case    eMCDRV_SRC_ADC0_AA:     bRegAESource    = MCB_AA_AE_SOURCE_AD;          bAEng6  = MCB_AA_AENG6_ADC0;    break;
++      case    eMCDRV_SRC_DIR0_AA:     bRegAESource    = MCB_AA_AE_SOURCE_DIR0;        break;
++      case    eMCDRV_SRC_DIR1_AA:     bRegAESource    = MCB_AA_AE_SOURCE_DIR1;        break;
++      case    eMCDRV_SRC_DIR2_AA:     bRegAESource    = MCB_AA_AE_SOURCE_DIR2;        break;
++      case    eMCDRV_SRC_MIX_AA:              bRegAESource    = MCB_AA_AE_SOURCE_MIX; break;
++      default:                                        bRegAESource    = 0;
++      }
++      if(bRegAESource != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_SRC_SOURCE_1)&0xF0))
++      {
++              /*      xxx_INS */
++              dXFadeParam     = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DAC_INS);
++              dXFadeParam <<= 8;
++              dXFadeParam     |= McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_INS);
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)MCI_AA_DAC_INS, 0);
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)MCI_AA_INS, 0);
++              bAESourceChange = 1;
++              sdRet   = McDevIf_ExecutePacket_AA();
++              if(sdRet != MCDRV_SUCCESS)
++              {
++                      return sdRet;
++              }
++      }
++
++      McResCtrl_GetDacInfo_AA(&sDacInfo);
++
++      /*      DAC_SOURCE/VOICE_SOURCE */
++      bReg    = 0;
++      switch(McResCtrl_GetDACSource_AA(eMCDRV_DAC_MASTER_AA))
++      {
++      case    eMCDRV_SRC_PDM_AA:
++              bReg |= MCB_AA_DAC_SOURCE_AD;
++              bAEng6  = MCB_AA_AENG6_PDM;
++              break;
++      case    eMCDRV_SRC_ADC0_AA:
++              bReg |= MCB_AA_DAC_SOURCE_AD;
++              bAEng6  = MCB_AA_AENG6_ADC0;
++              break;
++      case    eMCDRV_SRC_DIR0_AA:
++              bReg |= MCB_AA_DAC_SOURCE_DIR0;
++              break;
++      case    eMCDRV_SRC_DIR1_AA:
++              bReg |= MCB_AA_DAC_SOURCE_DIR1;
++              break;
++      case    eMCDRV_SRC_DIR2_AA:
++              bReg |= MCB_AA_DAC_SOURCE_DIR2;
++              break;
++      case    eMCDRV_SRC_MIX_AA:
++              bReg |= MCB_AA_DAC_SOURCE_MIX;
++              break;
++      default:
++              break;
++      }
++      switch(McResCtrl_GetDACSource_AA(eMCDRV_DAC_VOICE_AA))
++      {
++      case    eMCDRV_SRC_PDM_AA:
++              bReg |= MCB_AA_VOICE_SOURCE_AD;
++              bAEng6  = MCB_AA_AENG6_PDM;
++              break;
++      case    eMCDRV_SRC_ADC0_AA:
++              bReg |= MCB_AA_VOICE_SOURCE_AD;
++              bAEng6  = MCB_AA_AENG6_ADC0;
++              break;
++      case    eMCDRV_SRC_DIR0_AA:
++              bReg |= MCB_AA_VOICE_SOURCE_DIR0;
++              break;
++      case    eMCDRV_SRC_DIR1_AA:
++              bReg |= MCB_AA_VOICE_SOURCE_DIR1;
++              break;
++      case    eMCDRV_SRC_DIR2_AA:
++              bReg |= MCB_AA_VOICE_SOURCE_DIR2;
++              break;
++      case    eMCDRV_SRC_MIX_AA:
++              bReg |= MCB_AA_VOICE_SOURCE_MIX;
++              break;
++      default:
++              break;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_SOURCE, bReg);
++
++      /*      SWP/VOICE_SWP   */
++      bReg    = (sDacInfo.bMasterSwap << 4) | sDacInfo.bVoiceSwap;
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_SWP, bReg);
++
++      /*      DIT0SRC_SOURCE/DIT1SRC_SOURCE   */
++      bReg    = 0;
++      switch(McResCtrl_GetDITSource_AA(eMCDRV_DIO_0_AA))
++      {
++      case    eMCDRV_SRC_PDM_AA:
++              bReg |= MCB_AA_DIT0_SOURCE_AD;
++                      bAEng6  = MCB_AA_AENG6_PDM;
++              break;
++      case    eMCDRV_SRC_ADC0_AA:
++              bReg |= MCB_AA_DIT0_SOURCE_AD;
++                      bAEng6  = MCB_AA_AENG6_ADC0;
++              break;
++      case    eMCDRV_SRC_DIR0_AA:
++              bReg |= MCB_AA_DIT0_SOURCE_DIR0;
++              break;
++      case    eMCDRV_SRC_DIR1_AA:
++              bReg |= MCB_AA_DIT0_SOURCE_DIR1;
++              break;
++      case    eMCDRV_SRC_DIR2_AA:
++              bReg |= MCB_AA_DIT0_SOURCE_DIR2;
++              break;
++      case    eMCDRV_SRC_MIX_AA:
++              bReg |= MCB_AA_DIT0_SOURCE_MIX;
++              break;
++      default:
++              break;
++      }
++      switch(McResCtrl_GetDITSource_AA(eMCDRV_DIO_1_AA))
++      {
++      case    eMCDRV_SRC_PDM_AA:
++              bReg |= MCB_AA_DIT1_SOURCE_AD;
++                      bAEng6  = MCB_AA_AENG6_PDM;
++              break;
++      case    eMCDRV_SRC_ADC0_AA:
++              bReg |= MCB_AA_DIT1_SOURCE_AD;
++                      bAEng6  = MCB_AA_AENG6_ADC0;
++              break;
++      case    eMCDRV_SRC_DIR0_AA:
++              bReg |= MCB_AA_DIT1_SOURCE_DIR0;
++              break;
++      case    eMCDRV_SRC_DIR1_AA:
++              bReg |= MCB_AA_DIT1_SOURCE_DIR1;
++              break;
++      case    eMCDRV_SRC_DIR2_AA:
++              bReg |= MCB_AA_DIT1_SOURCE_DIR2;
++              break;
++      case    eMCDRV_SRC_MIX_AA:
++              bReg |= MCB_AA_DIT1_SOURCE_MIX;
++              break;
++      default:
++              break;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_SRC_SOURCE, bReg);
++
++      /*      AE_SOURCE/DIT2SRC_SOURCE        */
++      bReg    = bRegAESource;
++      switch(McResCtrl_GetDITSource_AA(eMCDRV_DIO_2_AA))
++      {
++      case    eMCDRV_SRC_PDM_AA:
++              bReg |= MCB_AA_DIT2_SOURCE_AD;
++                      bAEng6  = MCB_AA_AENG6_PDM;
++              break;
++      case    eMCDRV_SRC_ADC0_AA:
++              bReg |= MCB_AA_DIT2_SOURCE_AD;
++                      bAEng6  = MCB_AA_AENG6_ADC0;
++              break;
++      case    eMCDRV_SRC_DIR0_AA:
++              bReg |= MCB_AA_DIT2_SOURCE_DIR0;
++              break;
++      case    eMCDRV_SRC_DIR1_AA:
++              bReg |= MCB_AA_DIT2_SOURCE_DIR1;
++              break;
++      case    eMCDRV_SRC_DIR2_AA:
++              bReg |= MCB_AA_DIT2_SOURCE_DIR2;
++              break;
++      case    eMCDRV_SRC_MIX_AA:
++              bReg |= MCB_AA_DIT2_SOURCE_MIX;
++              break;
++      default:
++              break;
++      }
++      if(bAESourceChange != 0)
++      {
++              /*      wait xfade complete     */
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_EVTWAIT_AA | MCDRV_EVT_INSFLG_AA | dXFadeParam, 0);
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_SRC_SOURCE_1, bReg);
++
++      /*      BDSP_ST */
++      if(McResCtrl_GetAESource_AA() == eMCDRV_SRC_NONE_AA)
++      {/*     AE is unused    */
++              /*      BDSP stop & reset       */
++              if((McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_A_AA, MCI_AA_BDSP_ST)&MCB_AA_BDSP_ST) != 0)
++              {
++                      bReg    = 0;
++                      if((sAeInfo.bOnOff & MCDRV_EQ5_ON) != 0)
++                      {
++                              bReg |= MCB_AA_EQ5ON;
++                      }
++                      if((sAeInfo.bOnOff & MCDRV_DRC_ON) != 0)
++                      {
++                              bReg |= MCB_AA_DRCON;
++                      }
++                      if((sAeInfo.bOnOff & MCDRV_EQ3_ON) != 0)
++                      {
++                              bReg |= MCB_AA_EQ3ON;
++                      }
++                      if(McDevProf_IsValid(eMCDRV_FUNC_DBEX) == 1)
++                      {
++                              if((sAeInfo.bOnOff & MCDRV_BEXWIDE_ON) != 0)
++                              {
++                                      bReg |= MCB_AA_DBEXON;
++                              }
++                      }
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_A_AA | MCI_AA_BDSP_ST, bReg);
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_A_AA | MCI_AA_BDSP_RST, MCB_AA_TRAM_RST);
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_A_AA | MCI_AA_BDSP_RST, 0);
++              }
++      }
++      else
++      {/*     AE is used      */
++              bReg    = 0;
++              if((sAeInfo.bOnOff & MCDRV_EQ5_ON) != 0)
++              {
++                      bReg |= MCB_AA_EQ5ON;
++              }
++              if((sAeInfo.bOnOff & MCDRV_DRC_ON) != 0)
++              {
++                      bReg |= MCB_AA_DRCON;
++                      bReg |= MCB_AA_BDSP_ST;
++              }
++              if((sAeInfo.bOnOff & MCDRV_EQ3_ON) != 0)
++              {
++                      bReg |= MCB_AA_EQ3ON;
++              }
++              if(McDevProf_IsValid(eMCDRV_FUNC_DBEX) == 1)
++              {
++                      if((sAeInfo.bOnOff & MCDRV_BEXWIDE_ON) != 0)
++                      {
++                              bReg |= MCB_AA_DBEXON;
++                              bReg |= MCB_AA_BDSP_ST;
++                      }
++              }
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_A_AA | MCI_AA_BDSP_ST, bReg);
++      }
++
++      /*      check MIX SOURCE for AENG6_SOURCE       */
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_PDM_AA) != 0)
++      {
++              bAEng6  = MCB_AA_AENG6_PDM;
++      }
++      else if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_ADC0_AA) != 0)
++      {
++              bAEng6  = MCB_AA_AENG6_ADC0;
++      }
++
++      /*      AENG6_SOURCE    */
++      if(bAEng6 != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_AENG6_SOURCE))
++      {
++              bReg    = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_CODEC_AA, MCI_AA_AD_START);
++              if((bReg & MCB_AA_AD_START) != 0)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_CODEC_AA | MCI_AA_AD_MUTE, MCB_AA_AD_MUTE);
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_CODEC_AA | MCI_AA_AD_START, bReg&(UINT8)~MCB_AA_AD_START);
++              }
++              bReg    = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_PDM_START);
++              if((bReg & MCB_AA_PDM_START) != 0)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_PDM_MUTE, MCB_AA_PDM_MUTE);
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_PDM_START, bReg&(UINT8)~MCB_AA_PDM_START);
++              }
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_AENG6_SOURCE, bAEng6);
++
++      /*      xxx_INS */
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_AE_AA) != 0)
++      {
++              switch(eAESource)
++              {
++              case    eMCDRV_SRC_PDM_AA:
++              case    eMCDRV_SRC_ADC0_AA:
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)MCI_AA_INS, MCB_AA_ADC_INS);
++                      break;
++              case    eMCDRV_SRC_DIR0_AA:
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)MCI_AA_INS, MCB_AA_DIR0_INS);
++                      break;
++              case    eMCDRV_SRC_DIR1_AA:
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)MCI_AA_INS, MCB_AA_DIR1_INS);
++                      break;
++              case    eMCDRV_SRC_DIR2_AA:
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)MCI_AA_INS, MCB_AA_DIR2_INS);
++                      break;
++              case    eMCDRV_SRC_MIX_AA:
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)MCI_AA_DAC_INS, MCB_AA_DAC_INS);
++                      break;
++              default:
++                      break;
++              }
++      }
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    AddDIStart
++ *
++ *    Description:
++ *                    Add DIStart setup packet.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   AddDIStart
++(
++      void
++)
++{
++      UINT8   bReg;
++      MCDRV_PATH_INFO sPathInfo;
++      MCDRV_DIO_INFO  sDioInfo;
++
++      McResCtrl_GetPathInfo_AA(&sPathInfo);
++      McResCtrl_GetDioInfo_AA(&sDioInfo);
++
++      /*      DIR*_START, DIT*_START  */
++      bReg    = 0;
++      if(McResCtrl_GetDITSource_AA(eMCDRV_DIO_0_AA) != eMCDRV_SRC_NONE_AA)
++      {
++              if(sDioInfo.asPortInfo[0].sDioCommon.bMasterSlave == MCDRV_DIO_MASTER)
++              {
++                      bReg |= MCB_AA_DITIM0_START;
++              }
++              bReg |= MCB_AA_DIT0_SRC_START;
++              bReg |= MCB_AA_DIT0_START;
++      }
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_DIR0_AA) != 0)
++      {
++              if(sDioInfo.asPortInfo[0].sDioCommon.bMasterSlave == MCDRV_DIO_MASTER)
++              {
++                      bReg |= MCB_AA_DITIM0_START;
++              }
++              bReg |= MCB_AA_DIR0_SRC_START;
++              bReg |= MCB_AA_DIR0_START;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIX0_START, bReg);
++
++      bReg    = 0;
++      if(McResCtrl_GetDITSource_AA(eMCDRV_DIO_1_AA) != eMCDRV_SRC_NONE_AA)
++      {
++              if(sDioInfo.asPortInfo[1].sDioCommon.bMasterSlave == MCDRV_DIO_MASTER)
++              {
++                      bReg |= MCB_AA_DITIM1_START;
++              }
++              bReg |= MCB_AA_DIT1_SRC_START;
++              bReg |= MCB_AA_DIT1_START;
++      }
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_DIR1_AA) != 0)
++      {
++              if(sDioInfo.asPortInfo[1].sDioCommon.bMasterSlave == MCDRV_DIO_MASTER)
++              {
++                      bReg |= MCB_AA_DITIM1_START;
++              }
++              bReg |= MCB_AA_DIR1_SRC_START;
++              bReg |= MCB_AA_DIR1_START;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIX1_START, bReg);
++
++      bReg    = 0;
++      if(McResCtrl_GetDITSource_AA(eMCDRV_DIO_2_AA) != eMCDRV_SRC_NONE_AA)
++      {
++              if(sDioInfo.asPortInfo[2].sDioCommon.bMasterSlave == MCDRV_DIO_MASTER)
++              {
++                      bReg |= MCB_AA_DITIM2_START;
++              }
++              bReg |= MCB_AA_DIT2_SRC_START;
++              bReg |= MCB_AA_DIT2_START;
++      }
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_DIR2_AA) != 0)
++      {
++              if(sDioInfo.asPortInfo[2].sDioCommon.bMasterSlave == MCDRV_DIO_MASTER)
++              {
++                      bReg |= MCB_AA_DITIM2_START;
++              }
++              bReg |= MCB_AA_DIR2_SRC_START;
++              bReg |= MCB_AA_DIR2_START;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIX2_START, bReg);
++}
++
++/****************************************************************************
++ *    McPacket_AddMixSet_AA
++ *
++ *    Description:
++ *                    Add analog mixer set packet.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddMixSet_AA
++(
++      void
++)
++{
++      UINT8   bReg;
++      MCDRV_INIT_INFO sInitInfo;
++      MCDRV_PATH_INFO sPathInfo;
++
++      McResCtrl_GetInitInfo_AA(&sInitInfo);
++      McResCtrl_GetPathInfo_AA(&sPathInfo);
++
++      /*      ADL_MIX */
++      bReg    = GetMicMixBit(&sPathInfo.asAdc0[0]);
++      if((sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON
++      || (sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              bReg |= MCB_AA_LI1MIX;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_ADL_MIX, bReg);
++      /*      ADL_MONO        */
++      bReg    = 0;
++      if((sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              bReg |= MCB_AA_MONO_LI1;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_ADL_MONO, bReg);
++
++      /*      ADR_MIX */
++      bReg    = GetMicMixBit(&sPathInfo.asAdc0[1]);
++      if((sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON
++      || (sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              bReg |= MCB_AA_LI1MIX;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_ADR_MIX, bReg);
++      /*      ADR_MONO        */
++      bReg    = 0;
++      if((sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              bReg |= MCB_AA_MONO_LI1;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_ADR_MONO, bReg);
++
++      /*      L1L_MIX */
++      bReg    = GetMicMixBit(&sPathInfo.asLout1[0]);
++      if((sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON
++      || (sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              bReg |= MCB_AA_LI1MIX;
++      }
++      if((sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON
++      || (sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON)
++      {
++              bReg |= MCB_AA_DAMIX;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_LO1L_MIX, bReg);
++      /*      L1L_MONO        */
++      bReg    = 0;
++      if((sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              bReg |= MCB_AA_MONO_LI1;
++      }
++      if((sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON)
++      {
++              bReg |= MCB_AA_MONO_DA;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_LO1L_MONO, bReg);
++
++      /*      L1R_MIX */
++      if(sInitInfo.bLineOut1Dif != MCDRV_LINE_DIF)
++      {
++              bReg    = GetMicMixBit(&sPathInfo.asLout1[1]);
++              if((sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON)
++              {
++                      bReg |= MCB_AA_LI1MIX;
++              }
++              if((sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON)
++              {
++                      bReg |= MCB_AA_DAMIX;
++              }
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | (UINT32)MCI_AA_LO1R_MIX, bReg);
++      }
++
++      /*      L2L_MIX */
++      bReg    = GetMicMixBit(&sPathInfo.asLout2[0]);
++      if((sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON
++      || (sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              bReg |= MCB_AA_LI1MIX;
++      }
++      if((sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON
++      || (sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON)
++      {
++              bReg |= MCB_AA_DAMIX;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_LO2L_MIX, bReg);
++      /*      L2L_MONO        */
++      bReg    = 0;
++      if((sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              bReg |= MCB_AA_MONO_LI1;
++      }
++      if((sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON)
++      {
++              bReg |= MCB_AA_MONO_DA;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_LO2L_MONO, bReg);
++
++      /*      L2R_MIX */
++      if(sInitInfo.bLineOut2Dif != MCDRV_LINE_DIF)
++      {
++              bReg    = GetMicMixBit(&sPathInfo.asLout2[1]);
++              if((sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON)
++              {
++                      bReg |= MCB_AA_LI1MIX;
++              }
++              if((sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON)
++              {
++                      bReg |= MCB_AA_DAMIX;
++              }
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | (UINT32)MCI_AA_LO2R_MIX, bReg);
++      }
++
++      /*      HPL_MIX */
++      bReg    = GetMicMixBit(&sPathInfo.asHpOut[0]);
++      if((sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON
++      || (sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              bReg |= MCB_AA_LI1MIX;
++      }
++      if((sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON
++      || (sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON)
++      {
++              bReg |= MCB_AA_DAMIX;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_HPL_MIX, bReg);
++      /*      HPL_MONO        */
++      bReg    = 0;
++      if((sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              bReg |= MCB_AA_MONO_LI1;
++      }
++      if((sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON)
++      {
++              bReg |= MCB_AA_MONO_DA;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_HPL_MONO, bReg);
++
++      /*      HPR_MIX */
++      bReg    = GetMicMixBit(&sPathInfo.asHpOut[1]);
++      if((sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON)
++      {
++              bReg |= MCB_AA_LI1MIX;
++      }
++      if((sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON)
++      {
++              bReg |= MCB_AA_DAMIX;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_HPR_MIX, bReg);
++
++      /*      SPL_MIX */
++      bReg    = 0;
++      if((sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON
++      || (sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              bReg |= MCB_AA_LI1MIX;
++      }
++      if((sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON
++      || (sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON)
++      {
++              bReg |= MCB_AA_DAMIX;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_SPL_MIX, bReg);
++      /*      SPL_MONO        */
++      bReg    = 0;
++      if((sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              bReg |= MCB_AA_MONO_LI1;
++      }
++      if((sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON)
++      {
++              bReg |= MCB_AA_MONO_DA;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_SPL_MONO, bReg);
++
++      /*      SPR_MIX */
++      bReg    = 0;
++      if((sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON
++      || (sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              bReg |= MCB_AA_LI1MIX;
++      }
++      if((sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON
++      || (sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON)
++      {
++              bReg |= MCB_AA_DAMIX;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_SPR_MIX, bReg);
++      /*      SPR_MONO        */
++      bReg    = 0;
++      if((sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              bReg |= MCB_AA_MONO_LI1;
++      }
++      if((sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON)
++      {
++              bReg |= MCB_AA_MONO_DA;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_SPR_MONO, bReg);
++
++      /*      RCV_MIX */
++      bReg    = GetMicMixBit(&sPathInfo.asRcOut[0]);
++      if((sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              bReg |= MCB_AA_LI1MIX;
++      }
++      if((sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON)
++      {
++              bReg |= MCB_AA_DALMIX;
++      }
++      if((sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON)
++      {
++              bReg |= MCB_AA_DARMIX;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_RC_MIX, bReg);
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    GetMicMixBit
++ *
++ *    Description:
++ *                    Get mic mixer bit.
++ *    Arguments:
++ *                    source info
++ *    Return:
++ *                    mic mixer bit
++ *
++ ****************************************************************************/
++static UINT8  GetMicMixBit
++(
++      const MCDRV_CHANNEL* psChannel
++)
++{
++      UINT8   bMicMix = 0;
++
++      if((psChannel->abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON)
++      {
++              bMicMix |= MCB_AA_M1MIX;
++      }
++      if((psChannel->abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON)
++      {
++              bMicMix |= MCB_AA_M2MIX;
++      }
++      if((psChannel->abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON)
++      {
++              bMicMix |= MCB_AA_M3MIX;
++      }
++      return bMicMix;
++}
++
++/****************************************************************************
++ *    McPacket_AddStart_AA
++ *
++ *    Description:
++ *                    Add start packet.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddStart_AA
++(
++      void
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bReg;
++      UINT8   bADStart        = 0;
++      UINT8   bPDMStart       = 0;
++      MCDRV_INIT_INFO sInitInfo;
++      MCDRV_PATH_INFO sPathInfo;
++      MCDRV_ADC_INFO  sAdcInfo;
++      MCDRV_PDM_INFO  sPdmInfo;
++
++      McResCtrl_GetInitInfo_AA(&sInitInfo);
++      McResCtrl_GetPathInfo_AA(&sPathInfo);
++      McResCtrl_GetAdcInfo_AA(&sAdcInfo);
++      McResCtrl_GetPdmInfo_AA(&sPdmInfo);
++
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_ADC0_AA, eMCDRV_DST_CH0_AA) == 1
++      || McResCtrl_IsDstUsed_AA(eMCDRV_DST_ADC0_AA, eMCDRV_DST_CH1_AA) == 1)
++      {/*     ADC0 source is used     */
++              if((McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_CODEC_AA, MCI_AA_AD_START) & MCB_AA_AD_START) == 0)
++              {
++                      bReg    = (sAdcInfo.bAgcOn << 2) | sAdcInfo.bAgcAdjust;
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_CODEC_AA | MCI_AA_AD_AGC, bReg);
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_CODEC_AA | MCI_AA_AD_MUTE, MCB_AA_AD_MUTE);
++                      bReg    = (sAdcInfo.bMono << 1) | MCB_AA_AD_START;
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_CODEC_AA | MCI_AA_AD_START, bReg);
++                      bADStart        = 1;
++              }
++      }
++      else if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_PDM_AA) != 0)
++      {/*     PDM is used     */
++              if((McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_PDM_START) & MCB_AA_PDM_START) == 0)
++              {
++                      bReg    = (sPdmInfo.bAgcOn << 2) | sPdmInfo.bAgcAdjust;
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_PDM_AGC, bReg);
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_PDM_MUTE, MCB_AA_PDM_MUTE);
++                      bReg    = (sPdmInfo.bMono << 1) | MCB_AA_PDM_START;
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_PDM_START, bReg);
++                      bPDMStart       = 1;
++              }
++      }
++
++      if(bADStart == 1 || bPDMStart == 1)
++      {
++              sdRet   = McDevIf_ExecutePacket_AA();
++              if(sdRet != MCDRV_SUCCESS)
++              {
++                      return sdRet;
++              }
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_TIMWAIT_AA | sInitInfo.sWaitTime.dAdHpf, 0);
++              if(bADStart == 1)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_CODEC_AA | MCI_AA_AD_MUTE, 0);
++              }
++              else
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_PDM_MUTE, 0);
++              }
++      }
++      return sdRet;
++}
++
++/****************************************************************************
++ *    McPacket_AddStop_AA
++ *
++ *    Description:
++ *                    Add stop packet.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddStop_AA
++(
++      void
++)
++{
++      UINT8   bReg;
++
++      bReg    = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIX0_START);
++      if(McResCtrl_GetDITSource_AA(eMCDRV_DIO_0_AA) == eMCDRV_SRC_NONE_AA)
++      {/*     DIT is unused   */
++              bReg &= (UINT8)~MCB_AA_DIT0_SRC_START;
++              bReg &= (UINT8)~MCB_AA_DIT0_START;
++      }
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_DIR0_AA) == 0)
++      {/*     DIR is unused   */
++              bReg &= (UINT8)~MCB_AA_DIR0_SRC_START;
++              bReg &= (UINT8)~MCB_AA_DIR0_START;
++      }
++      if((bReg & 0x0F) == 0)
++      {
++              bReg &= (UINT8)~MCB_AA_DITIM0_START;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIX0_START, bReg);
++
++      bReg    = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIX1_START);
++      if(McResCtrl_GetDITSource_AA(eMCDRV_DIO_1_AA) == eMCDRV_SRC_NONE_AA)
++      {/*     DIT is unused   */
++              bReg &= (UINT8)~MCB_AA_DIT1_SRC_START;
++              bReg &= (UINT8)~MCB_AA_DIT1_START;
++      }
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_DIR1_AA) == 0)
++      {/*     DIR is unused   */
++              bReg &= (UINT8)~MCB_AA_DIR1_SRC_START;
++              bReg &= (UINT8)~MCB_AA_DIR1_START;
++      }
++      if((bReg & 0x0F) == 0)
++      {
++              bReg &= (UINT8)~MCB_AA_DITIM1_START;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIX1_START, bReg);
++
++      bReg    = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIX2_START);
++      if(McResCtrl_GetDITSource_AA(eMCDRV_DIO_2_AA) == eMCDRV_SRC_NONE_AA)
++      {/*     DIT is unused   */
++              bReg &= (UINT8)~MCB_AA_DIT2_SRC_START;
++              bReg &= (UINT8)~MCB_AA_DIT2_START;
++      }
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_DIR2_AA) == 0)
++      {/*     DIR is unused   */
++              bReg &= (UINT8)~MCB_AA_DIR2_SRC_START;
++              bReg &= (UINT8)~MCB_AA_DIR2_START;
++      }
++      if((bReg & 0x0F) == 0)
++      {
++              bReg &= (UINT8)~MCB_AA_DITIM2_START;
++      }
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIX2_START, bReg);
++
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_ADC0_AA, eMCDRV_DST_CH0_AA) == 0
++      && McResCtrl_IsDstUsed_AA(eMCDRV_DST_ADC0_AA, eMCDRV_DST_CH1_AA) == 0)
++      {/*     ADC0 source is unused   */
++              AddStopADC();
++      }
++      if(McResCtrl_IsSrcUsed_AA(eMCDRV_SRC_PDM_AA) == 0)
++      {/*     PDM is unused   */
++              AddStopPDM();
++      }
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    McPacket_AddVol_AA
++ *
++ *    Description:
++ *                    Add volume mute packet.
++ *    Arguments:
++ *                    dUpdate         target volume items
++ *                    eMode           update mode
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddVol_AA
++(
++      UINT32                                  dUpdate,
++      MCDRV_VOLUPDATE_MODE_AA eMode
++)
++{
++      UINT8                   bVolL;
++      UINT8                   bVolR;
++      UINT8                   bLAT;
++      UINT8                   bReg;
++      UINT32                  dSVolDoneParam  = 0;
++      MCDRV_INIT_INFO sInitInfo;
++      MCDRV_VOL_INFO  sVolInfo;
++
++      McResCtrl_GetInitInfo_AA(&sInitInfo);
++      McResCtrl_GetVolReg_AA(&sVolInfo);
++
++      if((dUpdate & MCDRV_VOLUPDATE_ANAOUT_ALL_AA) != (UINT32)0)
++      {
++              bVolL   = (UINT8)sVolInfo.aswA_Hp[0]&MCB_AA_HPVOL_L;
++              bVolR   = (UINT8)sVolInfo.aswA_Hp[1]&MCB_AA_HPVOL_R;
++              if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_HPVOL_L) & MCB_AA_HPVOL_L))
++              {
++                      if((eMode != eMCDRV_VOLUPDATE_MUTE_AA) || (bVolL == MCDRV_REG_MUTE))
++                      {
++                              if(((eMode != eMCDRV_VOLUPDATE_MUTE_AA) || (bVolR == MCDRV_REG_MUTE))
++                              && (bVolR != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_HPVOL_R)))
++                              {
++                                      bLAT    = MCB_AA_ALAT_HP;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|MCB_AA_SVOL_HP|bVolL;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | (UINT32)MCI_AA_HPVOL_L, bReg);
++                              if(bVolL == MCDRV_REG_MUTE)
++                              {
++                                      dSVolDoneParam  |= (MCB_AA_HPL_BUSY<<8);
++                              }
++                      }
++              }
++              if((eMode != eMCDRV_VOLUPDATE_MUTE_AA) || (bVolR == MCDRV_REG_MUTE))
++              {
++                      if((bVolR == MCDRV_REG_MUTE) && (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_HPVOL_R) != 0))
++                      {
++                              dSVolDoneParam  |= (UINT8)MCB_AA_HPR_BUSY;
++                      }
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | (UINT32)MCI_AA_HPVOL_R, bVolR);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswA_Sp[0]&MCB_AA_SPVOL_L;
++              bVolR   = (UINT8)sVolInfo.aswA_Sp[1]&MCB_AA_SPVOL_R;
++              if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_SPVOL_L) & MCB_AA_SPVOL_L))
++              {
++                      if((eMode != eMCDRV_VOLUPDATE_MUTE_AA) || (bVolL == MCDRV_REG_MUTE))
++                      {
++                              if(((eMode != eMCDRV_VOLUPDATE_MUTE_AA) || (bVolR == MCDRV_REG_MUTE))
++                              && (bVolR != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_SPVOL_R)))
++                              {
++                                      bLAT    = MCB_AA_ALAT_SP;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|MCB_AA_SVOL_SP|bVolL;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | (UINT32)MCI_AA_SPVOL_L, bReg);
++                              if(bVolL == MCDRV_REG_MUTE)
++                              {
++                                      dSVolDoneParam  |= (MCB_AA_SPL_BUSY<<8);
++                              }
++                      }
++              }
++              if((eMode != eMCDRV_VOLUPDATE_MUTE_AA) || (bVolR == MCDRV_REG_MUTE))
++              {
++                      if((bVolR == MCDRV_REG_MUTE) && (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_SPVOL_R) != 0))
++                      {
++                              dSVolDoneParam  |= (UINT8)MCB_AA_SPR_BUSY;
++                      }
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | (UINT32)MCI_AA_SPVOL_R, bVolR);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswA_Rc[0]&MCB_AA_RCVOL;
++              if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_RCVOL) & MCB_AA_RCVOL))
++              {
++                      if((eMode != eMCDRV_VOLUPDATE_MUTE_AA) || (bVolL == MCDRV_REG_MUTE))
++                      {
++                              bReg    = MCB_AA_SVOL_RC|bVolL;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | (UINT32)MCI_AA_RCVOL, bReg);
++                              if(bVolL == MCDRV_REG_MUTE)
++                              {
++                                      dSVolDoneParam  |= (MCB_AA_RC_BUSY<<8);
++                              }
++                      }
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswA_Lout1[0]&MCB_AA_LO1VOL_L;
++              bVolR   = (UINT8)sVolInfo.aswA_Lout1[1]&MCB_AA_LO1VOL_R;
++              if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_LO1VOL_L) & MCB_AA_LO1VOL_L))
++              {
++                      if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++                      {
++                              if((eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                              && bVolR != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_LO1VOL_R))
++                              {
++                                      bLAT    = MCB_AA_ALAT_LO1;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|bVolL;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_LO1VOL_L, bReg);
++                      }
++              }
++              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_LO1VOL_R, bVolR);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswA_Lout2[0]&MCB_AA_LO2VOL_L;
++              bVolR   = (UINT8)sVolInfo.aswA_Lout2[1]&MCB_AA_LO2VOL_R;
++              if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_LO2VOL_L) & MCB_AA_LO2VOL_L))
++              {
++                      if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++                      {
++                              if((eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                              && bVolR != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_LO2VOL_R))
++                              {
++                                      bLAT    = MCB_AA_ALAT_LO2;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|bVolL;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_LO2VOL_L, bReg);
++                      }
++              }
++              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_LO2VOL_R, bVolR);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswA_HpGain[0];
++              if(bVolL != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_HP_GAIN))
++              {
++                      if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++                      {
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_HP_GAIN, bVolL);
++                      }
++              }
++              /*      wait XX_BUSY    */
++              if(dSVolDoneParam != (UINT32)0)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_EVTWAIT_AA | MCDRV_EVT_SVOL_DONE_AA | dSVolDoneParam, 0);
++              }
++      }
++      if((dUpdate & (UINT32)~MCDRV_VOLUPDATE_ANAOUT_ALL_AA) != (UINT32)0)
++      {
++              bVolL   = (UINT8)sVolInfo.aswA_Lin1[0]&MCB_AA_LI1VOL_L;
++              bVolR   = (UINT8)sVolInfo.aswA_Lin1[1]&MCB_AA_LI1VOL_R;
++              if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_LI1VOL_L) & MCB_AA_LI1VOL_L))
++              {
++                      if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++                      {
++                              if((eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                              && bVolR != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_LI1VOL_R))
++                              {
++                                      bLAT    = MCB_AA_ALAT_LI1;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|bVolL;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_LI1VOL_L, bReg);
++                      }
++              }
++              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_LI1VOL_R, bVolR);
++              }
++
++              if(McDevProf_IsValid(eMCDRV_FUNC_LI2) == 1)
++              {
++                      bVolL   = (UINT8)sVolInfo.aswA_Lin2[0]&MCB_AA_LI2VOL_L;
++                      bVolR   = (UINT8)sVolInfo.aswA_Lin2[1]&MCB_AA_LI2VOL_R;
++                      if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_LI2VOL_L) & MCB_AA_LI2VOL_L))
++                      {
++                              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++                              {
++                                      if((eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                                      && bVolR != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_LI2VOL_R))
++                                      {
++                                              bLAT    = MCB_AA_ALAT_LI2;
++                                      }
++                                      else
++                                      {
++                                              bLAT    = 0;
++                                      }
++                                      bReg    = bLAT|bVolL;
++                                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_LI2VOL_L, bReg);
++                              }
++                      }
++                      if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                      {
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_LI2VOL_R, bVolR);
++                      }
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswA_Mic1[0]&MCB_AA_MC1VOL;
++              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_MC1VOL, bVolL);
++              }
++              bVolL   = (UINT8)sVolInfo.aswA_Mic2[0]&MCB_AA_MC2VOL;
++              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_MC2VOL, bVolL);
++              }
++              bVolL   = (UINT8)sVolInfo.aswA_Mic3[0]&MCB_AA_MC3VOL;
++              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_MC3VOL, bVolL);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswA_Ad0[0]&MCB_AA_ADVOL_L;
++              bVolR   = (UINT8)sVolInfo.aswA_Ad0[1]&MCB_AA_ADVOL_R;
++              if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_ADVOL_L) & MCB_AA_ADVOL_L))
++              {
++                      if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++                      {
++                              if((eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                              && bVolR != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_ADVOL_R))
++                              {
++                                      bLAT    = MCB_AA_ALAT_AD;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|bVolL;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_ADVOL_L, bReg);
++                      }
++              }
++              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_ADVOL_R, bVolR);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswA_Mic2Gain[0]&0x03;
++              bVolL   = (UINT8)((bVolL << 4) & MCB_AA_MC2GAIN) | (UINT8)(sVolInfo.aswA_Mic1Gain[0]&MCB_AA_MC1GAIN);
++              bVolL |= ((sInitInfo.bMic2Sng << 6) & MCB_AA_MC2SNG);
++              bVolL |= ((sInitInfo.bMic1Sng << 2) & MCB_AA_MC1SNG);
++              if(eMode == eMCDRV_VOLUPDATE_MUTE_AA)
++              {
++                      bReg    = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_MC_GAIN);
++                      if(((bReg & MCB_AA_MC2GAIN) == 0) && ((bReg & MCB_AA_MC1GAIN) == 0))
++                      {
++                              ;
++                      }
++                      else
++                      {
++                              if((bReg & MCB_AA_MC2GAIN) == 0)
++                              {
++                                      bVolL &= (UINT8)~MCB_AA_MC2GAIN;
++                              }
++                              else if((bReg & MCB_AA_MC1GAIN) == 0)
++                              {
++                                      bVolL &= (UINT8)~MCB_AA_MC1GAIN;
++                              }
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_MC_GAIN, bVolL);
++                      }
++              }
++              else
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_MC_GAIN, bVolL);
++              }
++
++              bVolL   = (UINT8)(sVolInfo.aswA_Mic3Gain[0]&MCB_AA_MC3GAIN) | ((sInitInfo.bMic3Sng << 2) & MCB_AA_MC3SNG);
++              if(eMode == eMCDRV_VOLUPDATE_MUTE_AA)
++              {
++                      bReg    = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_MC3_GAIN);
++                      if((bReg & MCB_AA_MC3GAIN) == 0)
++                      {
++                              ;
++                      }
++                      else
++                      {
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_MC3_GAIN, bVolL);
++                      }
++              }
++              else
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_MC3_GAIN, bVolL);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswD_Dit0[0]&MCB_AA_DIT0_INVOLL;
++              bVolR   = (UINT8)sVolInfo.aswD_Dit0[1]&MCB_AA_DIT0_INVOLR;
++              if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIT0_INVOLL) & MCB_AA_DIT0_INVOLL))
++              {
++                      if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++                      {
++                              if((eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                              && bVolR != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIT0_INVOLR))
++                              {
++                                      bLAT    = MCB_AA_DIT0_INLAT;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|bVolL;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIT0_INVOLL, bReg);
++                      }
++              }
++              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIT0_INVOLR, bVolR);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswD_Dit1[0]&MCB_AA_DIT1_INVOLL;
++              bVolR   = (UINT8)sVolInfo.aswD_Dit1[1]&MCB_AA_DIT1_INVOLR;
++              if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIT1_INVOLL) & MCB_AA_DIT1_INVOLL))
++              {
++                      if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++                      {
++                              if((eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                              && bVolR != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIT1_INVOLR))
++                              {
++                                      bLAT    = MCB_AA_DIT1_INLAT;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|bVolL;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIT1_INVOLL, bReg);
++                      }
++              }
++              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIT1_INVOLR, bVolR);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswD_Dit2[0]&MCB_AA_DIT2_INVOLL;
++              bVolR   = (UINT8)sVolInfo.aswD_Dit2[1]&MCB_AA_DIT2_INVOLR;
++              if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIT2_INVOLL) & MCB_AA_DIT2_INVOLL))
++              {
++                      if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++                      {
++                              if((eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                              && bVolR != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIT2_INVOLR))
++                              {
++                                      bLAT    = MCB_AA_DIT2_INLAT;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|bVolL;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIT2_INVOLL, bReg);
++                      }
++              }
++              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIT2_INVOLR, bVolR);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswD_Pdm[0]&MCB_AA_PDM0_VOLL;
++              bVolR   = (UINT8)sVolInfo.aswD_Pdm[1]&MCB_AA_PDM0_VOLR;
++              if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_PDM0_VOLL) & MCB_AA_PDM0_VOLL))
++              {
++                      if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++                      {
++                              if((eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                              && bVolR != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_PDM0_VOLR))
++                              {
++                                      bLAT    = MCB_AA_PDM0_INLAT;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|bVolL;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_PDM0_VOLL, bReg);
++                      }
++              }
++              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_PDM0_VOLR, bVolR);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswD_Dir0[0]&MCB_AA_DIR0_VOLL;
++              bVolR   = (UINT8)sVolInfo.aswD_Dir0[1]&MCB_AA_DIR0_VOLR;
++              if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIR0_VOLL) & MCB_AA_DIR0_VOLL))
++              {
++                      if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++                      {
++                              if((eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                              && bVolR != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIR0_VOLR))
++                              {
++                                      bLAT    = MCB_AA_DIR0_LAT;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|bVolL;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIR0_VOLL, bReg);
++                      }
++              }
++              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIR0_VOLR, bVolR);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswD_Dir1[0]&MCB_AA_DIR1_VOLL;
++              bVolR   = (UINT8)sVolInfo.aswD_Dir1[1]&MCB_AA_DIR1_VOLR;
++              if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIR1_VOLL) & MCB_AA_DIR1_VOLL))
++              {
++                      if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++                      {
++                              if((eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                              && bVolR != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIR1_VOLR))
++                              {
++                                      bLAT    = MCB_AA_DIR1_LAT;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|bVolL;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIR1_VOLL, bReg);
++                      }
++              }
++              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIR1_VOLR, bVolR);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswD_Dir2[0]&MCB_AA_DIR2_VOLL;
++              bVolR   = (UINT8)sVolInfo.aswD_Dir2[1]&MCB_AA_DIR2_VOLR;
++              if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIR2_VOLL) & MCB_AA_DIR2_VOLL))
++              {
++                      if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++                      {
++                              if((eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                              && bVolR != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIR2_VOLR))
++                              {
++                                      bLAT    = MCB_AA_DIR2_LAT;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|bVolL;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIR2_VOLL, bReg);
++                      }
++              }
++              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIR2_VOLR, bVolR);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswD_Ad0[0]&MCB_AA_ADC_VOLL;
++              bVolR   = (UINT8)sVolInfo.aswD_Ad0[1]&MCB_AA_ADC_VOLR;
++              if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_ADC_VOLL) & MCB_AA_ADC_VOLL))
++              {
++                      if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++                      {
++                              if((eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                              && bVolR != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_ADC_VOLR))
++                              {
++                                      bLAT    = MCB_AA_ADC_LAT;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|bVolL;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_ADC_VOLL, bReg);
++                      }
++              }
++              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_ADC_VOLR, bVolR);
++              }
++
++              if(McDevProf_IsValid(eMCDRV_FUNC_ADC1) == 1)
++              {
++#if 0
++                      bVolL   = (UINT8)sVolInfo.aswD_Ad1[0]&MCB_AA_ADC1_VOLL;
++                      bVolR   = (UINT8)sVolInfo.aswD_Ad1[1]&MCB_AA_ADC1_VOLR;
++                      if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_ADC1_VOLL) & MCB_AA_ADC1_VOLL))
++                      {
++                              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++                              {
++                                      if((eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                                      && bVolR != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_ADC1_VOLR))
++                                      {
++                                              bLAT    = MCB_AA_ADC_LAT;
++                                      }
++                                      else
++                                      {
++                                              bLAT    = 0;
++                                      }
++                                      bReg    = bLAT|bVolL;
++                                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_ADC1_VOLL, bReg);
++                              }
++                      }
++                      if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                      {
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_ADC1_VOLR, bVolR);
++                      }
++#endif
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswD_Aeng6[0]&MCB_AA_AENG6_VOLL;
++              bVolR   = (UINT8)sVolInfo.aswD_Aeng6[1]&MCB_AA_AENG6_VOLR;
++              if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_AENG6_VOLL) & MCB_AA_AENG6_VOLL))
++              {
++                      if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++                      {
++                              if((eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                              && bVolR != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_AENG6_VOLR))
++                              {
++                                      bLAT    = MCB_AA_AENG6_LAT;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|bVolL;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_AENG6_VOLL, bReg);
++                      }
++              }
++              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_AENG6_VOLR, bVolR);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswD_Ad0Att[0]&MCB_AA_ADC_ATTL;
++              bVolR   = (UINT8)sVolInfo.aswD_Ad0Att[1]&MCB_AA_ADC_ATTR;
++              if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_ADC_ATTL) & MCB_AA_ADC_ATTL))
++              {
++                      if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++                      {
++                              if((eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                              && bVolR != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_ADC_ATTR))
++                              {
++                                      bLAT    = MCB_AA_ADC_ALAT;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|bVolL;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_ADC_ATTL, bReg);
++                      }
++              }
++              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_ADC_ATTR, bVolR);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswD_Dir0Att[0]&MCB_AA_DIR0_ATTL;
++              bVolR   = (UINT8)sVolInfo.aswD_Dir0Att[1]&MCB_AA_DIR0_ATTR;
++              if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIR0_ATTL) & MCB_AA_DIR0_ATTL))
++              {
++                      if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++                      {
++                              if((eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                              && bVolR != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIR0_ATTR))
++                              {
++                                      bLAT    = MCB_AA_DIR0_ALAT;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|bVolL;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIR0_ATTL, bReg);
++                      }
++              }
++              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIR0_ATTR, bVolR);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswD_Dir1Att[0]&MCB_AA_DIR1_ATTL;
++              bVolR   = (UINT8)sVolInfo.aswD_Dir1Att[1]&MCB_AA_DIR1_ATTR;
++              if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIR1_ATTL) & MCB_AA_DIR1_ATTL))
++              {
++                      if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++                      {
++                              if((eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                              && bVolR != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIR1_ATTR))
++                              {
++                                      bLAT    = MCB_AA_DIR1_ALAT;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|bVolL;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIR1_ATTL, bReg);
++                      }
++              }
++              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIR1_ATTR, bVolR);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswD_Dir2Att[0]&MCB_AA_DIR2_ATTL;
++              bVolR   = (UINT8)sVolInfo.aswD_Dir2Att[1]&MCB_AA_DIR2_ATTR;
++              if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIR2_ATTL) & MCB_AA_DIR2_ATTL))
++              {
++                      if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++                      {
++                              if((eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                              && bVolR != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIR2_ATTR))
++                              {
++                                      bLAT    = MCB_AA_DIR2_ALAT;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|bVolL;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIR2_ATTL, bReg);
++                      }
++              }
++              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIR2_ATTR, bVolR);
++              }
++
++              if(McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_AENG6_SOURCE) == MCB_AA_AENG6_PDM)
++              {
++                      bVolL   = (UINT8)sVolInfo.aswD_SideTone[0]&MCB_AA_ST_VOLL;
++                      bVolR   = (UINT8)sVolInfo.aswD_SideTone[1]&MCB_AA_ST_VOLR;
++                      if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_ST_VOLL) & MCB_AA_ST_VOLL))
++                      {
++                              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++                              {
++                                      if((eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                                      && bVolR != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_ST_VOLR))
++                                      {
++                                              bLAT    = MCB_AA_ST_LAT;
++                                      }
++                                      else
++                                      {
++                                              bLAT    = 0;
++                                      }
++                                      bReg    = bLAT|bVolL;
++                                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_ST_VOLL, bReg);
++                              }
++                      }
++                      if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                      {
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_ST_VOLR, bVolR);
++                      }
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswD_DacMaster[0]&MCB_AA_MASTER_OUTL;
++              bVolR   = (UINT8)sVolInfo.aswD_DacMaster[1]&MCB_AA_MASTER_OUTR;
++              if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_MASTER_OUTL) & MCB_AA_MASTER_OUTL))
++              {
++                      if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++                      {
++                              if((eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                              && bVolR != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_MASTER_OUTR))
++                              {
++                                      bLAT    = MCB_AA_MASTER_OLAT;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|bVolL;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_MASTER_OUTL, bReg);
++                      }
++              }
++              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_MASTER_OUTR, bVolR);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswD_DacVoice[0]&MCB_AA_VOICE_ATTL;
++              bVolR   = (UINT8)sVolInfo.aswD_DacVoice[1]&MCB_AA_VOICE_ATTR;
++              if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_VOICE_ATTL) & MCB_AA_VOICE_ATTL))
++              {
++                      if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++                      {
++                              if((eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                              && bVolR != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_VOICE_ATTR))
++                              {
++                                      bLAT    = MCB_AA_VOICE_LAT;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|bVolL;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_VOICE_ATTL, bReg);
++                      }
++              }
++              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_VOICE_ATTR, bVolR);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswD_DacAtt[0]&MCB_AA_DAC_ATTL;
++              bVolR   = (UINT8)sVolInfo.aswD_DacAtt[1]&MCB_AA_DAC_ATTR;
++              if(bVolL != (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DAC_ATTL) & MCB_AA_DAC_ATTL))
++              {
++                      if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolL == MCDRV_REG_MUTE)
++                      {
++                              if((eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++                              && bVolR != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DAC_ATTR))
++                              {
++                                      bLAT    = MCB_AA_DAC_LAT;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|bVolL;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DAC_ATTL, bReg);
++                      }
++              }
++              if(eMode != eMCDRV_VOLUPDATE_MUTE_AA || bVolR == MCDRV_REG_MUTE)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DAC_ATTR, bVolR);
++              }
++      }
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    AddStopADC
++ *
++ *    Description:
++ *                    Add stop ADC packet.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   AddStopADC
++(
++      void
++)
++{
++      UINT8   bReg    = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_CODEC_AA, MCI_AA_AD_START);
++      if((bReg & MCB_AA_AD_START) != 0)
++      {
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_CODEC_AA | MCI_AA_AD_MUTE, MCB_AA_AD_MUTE);
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_CODEC_AA | MCI_AA_AD_START, bReg&(UINT8)~MCB_AA_AD_START);
++      }
++}
++
++/****************************************************************************
++ *    AddStopPDM
++ *
++ *    Description:
++ *                    Add stop PDM packet.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   AddStopPDM
++(
++      void
++)
++{
++      UINT8   bReg    = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_PDM_START);
++      if((bReg & MCB_AA_PDM_START) != 0)
++      {
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_PDM_MUTE, MCB_AA_PDM_MUTE);
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_PDM_START, bReg&(UINT8)~MCB_AA_PDM_START);
++      }
++}
++
++/****************************************************************************
++ *    McPacket_AddDigitalIO_AA
++ *
++ *    Description:
++ *                    Add DigitalI0 setup packet.
++ *    Arguments:
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddDigitalIO_AA
++(
++      UINT32  dUpdateInfo
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bReg;
++      MCDRV_POWER_INFO_AA     sPowerInfo;
++      MCDRV_POWER_UPDATE_AA   sPowerUpdate;
++      MCDRV_DIO_INFO          sDioInfo;
++
++      if(IsModifiedDIO(dUpdateInfo) == 0)
++      {
++              return sdRet;
++      }
++
++      McResCtrl_GetCurPowerInfo_AA(&sPowerInfo);
++      sdRet   = PowerUpDig(MCDRV_DPB_UP_AA);
++      if(sdRet != MCDRV_SUCCESS)
++      {
++              return sdRet;
++      }
++
++      if((dUpdateInfo & MCDRV_DIO0_COM_UPDATE_FLAG) != (UINT32)0)
++      {
++              AddDIOCommon(eMCDRV_DIO_0_AA);
++      }
++      if((dUpdateInfo & MCDRV_DIO1_COM_UPDATE_FLAG) != (UINT32)0)
++      {
++              AddDIOCommon(eMCDRV_DIO_1_AA);
++      }
++      if((dUpdateInfo & MCDRV_DIO2_COM_UPDATE_FLAG) != (UINT32)0)
++      {
++              AddDIOCommon(eMCDRV_DIO_2_AA);
++      }
++
++      /*      DI*_BCKP        */
++      if((dUpdateInfo & MCDRV_DIO0_COM_UPDATE_FLAG) != (UINT32)0
++      || (dUpdateInfo & MCDRV_DIO1_COM_UPDATE_FLAG) != (UINT32)0
++      || (dUpdateInfo & MCDRV_DIO2_COM_UPDATE_FLAG) != (UINT32)0)
++      {
++              McResCtrl_GetDioInfo_AA(&sDioInfo);
++              bReg    = 0;
++              if(sDioInfo.asPortInfo[0].sDioCommon.bBckInvert == MCDRV_BCLK_INVERT)
++              {
++                      bReg |= MCB_AA_DI0_BCKP;
++              }
++              if(sDioInfo.asPortInfo[1].sDioCommon.bBckInvert == MCDRV_BCLK_INVERT)
++              {
++                      bReg |= MCB_AA_DI1_BCKP;
++              }
++              if(sDioInfo.asPortInfo[2].sDioCommon.bBckInvert == MCDRV_BCLK_INVERT)
++              {
++                      bReg |= MCB_AA_DI2_BCKP;
++              }
++              if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_BASE_AA, MCI_AA_BCKP))
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | (UINT32)MCI_AA_BCKP, bReg);
++              }
++      }
++
++      if((dUpdateInfo & MCDRV_DIO0_DIR_UPDATE_FLAG) != (UINT32)0)
++      {
++              AddDIODIR(eMCDRV_DIO_0_AA);
++      }
++      if((dUpdateInfo & MCDRV_DIO1_DIR_UPDATE_FLAG) != (UINT32)0)
++      {
++              AddDIODIR(eMCDRV_DIO_1_AA);
++      }
++      if((dUpdateInfo & MCDRV_DIO2_DIR_UPDATE_FLAG) != (UINT32)0)
++      {
++              AddDIODIR(eMCDRV_DIO_2_AA);
++      }
++
++      if((dUpdateInfo & MCDRV_DIO0_DIT_UPDATE_FLAG) != (UINT32)0)
++      {
++              AddDIODIT(eMCDRV_DIO_0_AA);
++      }
++      if((dUpdateInfo & MCDRV_DIO1_DIT_UPDATE_FLAG) != (UINT32)0)
++      {
++              AddDIODIT(eMCDRV_DIO_1_AA);
++      }
++      if((dUpdateInfo & MCDRV_DIO2_DIT_UPDATE_FLAG) != (UINT32)0)
++      {
++              AddDIODIT(eMCDRV_DIO_2_AA);
++      }
++
++      /*      unused path power down  */
++      sPowerUpdate.dDigital           = MCDRV_POWUPDATE_DIGITAL_ALL_AA;
++      sPowerUpdate.abAnalog[0]        =
++      sPowerUpdate.abAnalog[1]        =
++      sPowerUpdate.abAnalog[2]        =
++      sPowerUpdate.abAnalog[3]        =
++      sPowerUpdate.abAnalog[4]        = 0;
++      return McPacket_AddPowerDown_AA(&sPowerInfo, &sPowerUpdate);
++}
++
++/****************************************************************************
++ *    IsModifiedDIO
++ *
++ *    Description:
++ *                    Is modified DigitalIO.
++ *    Arguments:
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    0:not modified/1:modified
++ *
++ ****************************************************************************/
++static UINT8  IsModifiedDIO
++(
++      UINT32          dUpdateInfo
++)
++{
++      if((dUpdateInfo & MCDRV_DIO0_COM_UPDATE_FLAG) != (UINT32)0 && IsModifiedDIOCommon(eMCDRV_DIO_0_AA) == 1)
++      {
++              return 1;
++      }
++      if((dUpdateInfo & MCDRV_DIO1_COM_UPDATE_FLAG) != (UINT32)0 && IsModifiedDIOCommon(eMCDRV_DIO_1_AA) == 1)
++      {
++              return 1;
++      }
++      if((dUpdateInfo & MCDRV_DIO2_COM_UPDATE_FLAG) != (UINT32)0 && IsModifiedDIOCommon(eMCDRV_DIO_2_AA) == 1)
++      {
++              return 1;
++      }
++
++      if((dUpdateInfo & MCDRV_DIO0_DIR_UPDATE_FLAG) != (UINT32)0 && IsModifiedDIODIR(eMCDRV_DIO_0_AA) == 1)
++      {
++              return 1;
++      }
++      if((dUpdateInfo & MCDRV_DIO1_DIR_UPDATE_FLAG) != (UINT32)0 && IsModifiedDIODIR(eMCDRV_DIO_1_AA) == 1)
++      {
++              return 1;
++      }
++      if((dUpdateInfo & MCDRV_DIO2_DIR_UPDATE_FLAG) != (UINT32)0 && IsModifiedDIODIR(eMCDRV_DIO_2_AA) == 1)
++      {
++              return 1;
++      }
++
++      if((dUpdateInfo & MCDRV_DIO0_DIT_UPDATE_FLAG) != (UINT32)0 && IsModifiedDIODIT(eMCDRV_DIO_0_AA) == 1)
++      {
++              return 1;
++      }
++      if((dUpdateInfo & MCDRV_DIO1_DIT_UPDATE_FLAG) != (UINT32)0 && IsModifiedDIODIT(eMCDRV_DIO_1_AA) == 1)
++      {
++              return 1;
++      }
++      if((dUpdateInfo & MCDRV_DIO2_DIT_UPDATE_FLAG) != (UINT32)0 && IsModifiedDIODIT(eMCDRV_DIO_2_AA) == 1)
++      {
++              return 1;
++      }
++      return 0;
++}
++
++/****************************************************************************
++ *    IsModifiedDIOCommon
++ *
++ *    Description:
++ *                    Is modified DigitalIO Common.
++ *    Arguments:
++ *                    ePort           port number
++ *    Return:
++ *                    0:not modified/1:modified
++ *
++ ****************************************************************************/
++static UINT8  IsModifiedDIOCommon
++(
++      MCDRV_DIO_PORT_NO_AA    ePort
++)
++{
++      UINT8   bReg;
++      UINT8   bRegOffset;
++      MCDRV_DIO_INFO  sDioInfo;
++
++      if(ePort == eMCDRV_DIO_0_AA)
++      {
++              bRegOffset      = 0;
++      }
++      else if(ePort == eMCDRV_DIO_1_AA)
++      {
++              bRegOffset      = MCI_AA_DIMODE1 - MCI_AA_DIMODE0;
++      }
++      else if(ePort == eMCDRV_DIO_2_AA)
++      {
++              bRegOffset      = MCI_AA_DIMODE2 - MCI_AA_DIMODE0;
++      }
++      else
++      {
++              return 0;
++      }
++
++      McResCtrl_GetDioInfo_AA(&sDioInfo);
++
++      if(sDioInfo.asPortInfo[ePort].sDioCommon.bInterface != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIMODE0+bRegOffset))
++      {
++              return 1;
++      }
++
++      bReg    = (sDioInfo.asPortInfo[ePort].sDioCommon.bAutoFs << 7)
++                      | (sDioInfo.asPortInfo[ePort].sDioCommon.bBckFs << 4)
++                      | sDioInfo.asPortInfo[ePort].sDioCommon.bFs;
++      if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DI_FS0+bRegOffset))
++      {
++              return 1;
++      }
++
++      bReg    = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DI0_SRC+bRegOffset);
++      if(sDioInfo.asPortInfo[ePort].sDioCommon.bAutoFs == 0
++      && sDioInfo.asPortInfo[ePort].sDioCommon.bMasterSlave == MCDRV_DIO_SLAVE)
++      {
++              bReg |= MCB_AA_DICOMMON_SRC_RATE_SET;
++      }
++      if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DI0_SRC+bRegOffset))
++      {
++              return 1;
++      }
++
++      if(sDioInfo.asPortInfo[ePort].sDioCommon.bInterface == MCDRV_DIO_PCM)
++      {
++              bReg    = (sDioInfo.asPortInfo[ePort].sDioCommon.bPcmHizTim << 7)
++                              | (sDioInfo.asPortInfo[ePort].sDioCommon.bPcmClkDown << 6)
++                              | (sDioInfo.asPortInfo[ePort].sDioCommon.bPcmFrame << 5)
++                              | (sDioInfo.asPortInfo[ePort].sDioCommon.bPcmHighPeriod);
++              if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_HIZ_REDGE0+bRegOffset))
++              {
++                      return 1;
++              }
++      }
++      return 0;
++}
++
++/****************************************************************************
++ *    IsModifiedDIODIR
++ *
++ *    Description:
++ *                    Is modified DigitalIO DIR.
++ *    Arguments:
++ *                    ePort           port number
++ *    Return:
++ *                    0:not modified/1:modified
++ *
++ ****************************************************************************/
++static UINT8  IsModifiedDIODIR
++(
++      MCDRV_DIO_PORT_NO_AA    ePort
++)
++{
++      UINT8   bReg;
++      UINT8   bRegOffset;
++      MCDRV_DIO_INFO  sDioInfo;
++
++      if(ePort == eMCDRV_DIO_0_AA)
++      {
++              bRegOffset      = 0;
++      }
++      else if(ePort == eMCDRV_DIO_1_AA)
++      {
++              bRegOffset      = MCI_AA_DIMODE1 - MCI_AA_DIMODE0;
++      }
++      else if(ePort == eMCDRV_DIO_2_AA)
++      {
++              bRegOffset      = MCI_AA_DIMODE2 - MCI_AA_DIMODE0;
++      }
++      else
++      {
++              return 0;
++      }
++
++      McResCtrl_GetDioInfo_AA(&sDioInfo);
++
++      bReg    = (UINT8)(sDioInfo.asPortInfo[ePort].sDir.wSrcRate>>8);
++      if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIRSRC_RATE0_MSB+bRegOffset))
++      {
++              return 1;
++      }
++
++      bReg    = (UINT8)sDioInfo.asPortInfo[ePort].sDir.wSrcRate;
++      if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIRSRC_RATE0_LSB+bRegOffset))
++      {
++              return 1;
++      }
++
++      if(sDioInfo.asPortInfo[ePort].sDioCommon.bInterface == MCDRV_DIO_DA)
++      {
++              bReg    = (sDioInfo.asPortInfo[ePort].sDit.sDaFormat.bMode << 6)
++                              | (sDioInfo.asPortInfo[ePort].sDit.sDaFormat.bBitSel << 4)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sDaFormat.bMode << 2)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sDaFormat.bBitSel);
++              if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIX0_FMT+bRegOffset))
++              {
++                      return 1;
++              }
++              /*      DIR*_CH */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDir.abSlot[1] << 4) | (sDioInfo.asPortInfo[ePort].sDir.abSlot[0]);
++              if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIR0_CH+bRegOffset))
++              {
++                      return 1;
++              }
++      }
++      else
++      {
++              /*      PCM_MONO_RX*, PCM_EXTEND_RX*, PCM_LSBON_RX*, PCM_LAW_RX*, PCM_BIT_RX*   */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDir.sPcmFormat.bMono << 7)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sPcmFormat.bOrder << 4)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sPcmFormat.bLaw << 2)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sPcmFormat.bBitSel);
++              if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_PCM_RX0+bRegOffset))
++              {
++                      return 1;
++              }
++              /*      PCM_CH1_RX*, PCM_CH0_RX*        */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDir.abSlot[1] << 4) | (sDioInfo.asPortInfo[ePort].sDir.abSlot[0]);
++              if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_PCM_SLOT_RX0+bRegOffset))
++              {
++                      return 1;
++              }
++      }
++      return 0;
++}
++
++/****************************************************************************
++ *    IsModifiedDIODIT
++ *
++ *    Description:
++ *                    Is modified DigitalIO DIT.
++ *    Arguments:
++ *                    ePort           port number
++ *    Return:
++ *                    0:not modified/1:modified
++ *
++ ****************************************************************************/
++static UINT8  IsModifiedDIODIT
++(
++      MCDRV_DIO_PORT_NO_AA    ePort
++)
++{
++      UINT8   bReg;
++      UINT8   bRegOffset;
++      MCDRV_DIO_INFO  sDioInfo;
++
++      if(ePort == eMCDRV_DIO_0_AA)
++      {
++              bRegOffset      = 0;
++      }
++      else if(ePort == eMCDRV_DIO_1_AA)
++      {
++              bRegOffset      = MCI_AA_DIMODE1 - MCI_AA_DIMODE0;
++      }
++      else if(ePort == eMCDRV_DIO_2_AA)
++      {
++              bRegOffset      = MCI_AA_DIMODE2 - MCI_AA_DIMODE0;
++      }
++      else
++      {
++              return 0;
++      }
++
++      McResCtrl_GetDioInfo_AA(&sDioInfo);
++
++      bReg    = (UINT8)(sDioInfo.asPortInfo[ePort].sDit.wSrcRate>>8);
++      if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DITSRC_RATE0_MSB+bRegOffset))
++      {
++              return 1;
++      }
++      bReg    = (UINT8)sDioInfo.asPortInfo[ePort].sDit.wSrcRate;
++      if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DITSRC_RATE0_LSB+bRegOffset))
++      {
++              return 1;
++      }
++
++      if(sDioInfo.asPortInfo[ePort].sDioCommon.bInterface == MCDRV_DIO_DA)
++      {
++              /*      DIT*_FMT, DIT*_BIT, DIR*_FMT, DIR*_BIT  */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDit.sDaFormat.bMode << 6)
++                              | (sDioInfo.asPortInfo[ePort].sDit.sDaFormat.bBitSel << 4)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sDaFormat.bMode << 2)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sDaFormat.bBitSel);
++              if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIX0_FMT+bRegOffset))
++              {
++                      return 1;
++              }
++
++              /*      DIT*_SLOT       */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDit.abSlot[1] << 4) | (sDioInfo.asPortInfo[ePort].sDit.abSlot[0]);
++              if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIT0_SLOT+bRegOffset))
++              {
++                      return 1;
++              }
++      }
++      else
++      {
++              /*      PCM_MONO_TX*, PCM_EXTEND_TX*, PCM_LSBON_TX*, PCM_LAW_TX*, PCM_BIT_TX*   */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDit.sPcmFormat.bMono << 7)
++                              | (sDioInfo.asPortInfo[ePort].sDit.sPcmFormat.bOrder << 4)
++                              | (sDioInfo.asPortInfo[ePort].sDit.sPcmFormat.bLaw << 2)
++                              | (sDioInfo.asPortInfo[ePort].sDit.sPcmFormat.bBitSel);
++              if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_PCM_TX0+bRegOffset))
++              {
++                      return 1;
++              }
++
++              /*      PCM_CH1_TX*, PCM_CH0_TX*        */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDit.abSlot[1] << 4) | (sDioInfo.asPortInfo[ePort].sDit.abSlot[0]);
++              if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_PCM_SLOT_TX0+bRegOffset))
++              {
++                      return 1;
++              }
++      }
++      return 0;
++}
++
++/****************************************************************************
++ *    AddDIOCommon
++ *
++ *    Description:
++ *                    Add DigitalI0 Common setup packet.
++ *    Arguments:
++ *                    ePort           port number
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   AddDIOCommon
++(
++      MCDRV_DIO_PORT_NO_AA    ePort
++)
++{
++      UINT8   bReg;
++      UINT8   bRegOffset;
++      MCDRV_DIO_INFO  sDioInfo;
++
++      if(ePort == eMCDRV_DIO_0_AA)
++      {
++              bRegOffset      = 0;
++      }
++      else if(ePort == eMCDRV_DIO_1_AA)
++      {
++              bRegOffset      = MCI_AA_DIMODE1 - MCI_AA_DIMODE0;
++      }
++      else if(ePort == eMCDRV_DIO_2_AA)
++      {
++              bRegOffset      = MCI_AA_DIMODE2 - MCI_AA_DIMODE0;
++      }
++      else
++      {
++              return;
++      }
++
++      McResCtrl_GetDioInfo_AA(&sDioInfo);
++
++      /*      DIMODE* */
++      if(sDioInfo.asPortInfo[ePort].sDioCommon.bInterface != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIMODE0+bRegOffset))
++      {
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)(MCI_AA_DIMODE0+bRegOffset),
++                                                      sDioInfo.asPortInfo[ePort].sDioCommon.bInterface);
++      }
++
++      /*      DIAUTO_FS*, DIBCK*, DIFS*       */
++      bReg    = (sDioInfo.asPortInfo[ePort].sDioCommon.bAutoFs << 7)
++                      | (sDioInfo.asPortInfo[ePort].sDioCommon.bBckFs << 4)
++                      | sDioInfo.asPortInfo[ePort].sDioCommon.bFs;
++      if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DI_FS0+bRegOffset))
++      {
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)(MCI_AA_DI_FS0+bRegOffset), bReg);
++      }
++
++      /*      DI*_SRCRATE_SET */
++      bReg    = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DI0_SRC+bRegOffset);
++      if(sDioInfo.asPortInfo[ePort].sDioCommon.bAutoFs == 0
++      && sDioInfo.asPortInfo[ePort].sDioCommon.bMasterSlave == MCDRV_DIO_SLAVE)
++      {
++              bReg |= MCB_AA_DICOMMON_SRC_RATE_SET;
++      }
++      else
++      {
++              bReg &= (UINT8)~MCB_AA_DICOMMON_SRC_RATE_SET;
++      }
++      if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DI0_SRC+bRegOffset))
++      {
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)(MCI_AA_DI0_SRC+bRegOffset), bReg);
++      }
++
++      /*      HIZ_REDGE*, PCM_CLKDOWN*, PCM_FRAME*, PCM_HPERIOD*      */
++      if(sDioInfo.asPortInfo[ePort].sDioCommon.bInterface == MCDRV_DIO_PCM)
++      {
++              bReg    = (sDioInfo.asPortInfo[ePort].sDioCommon.bPcmHizTim << 7)
++                              | (sDioInfo.asPortInfo[ePort].sDioCommon.bPcmClkDown << 6)
++                              | (sDioInfo.asPortInfo[ePort].sDioCommon.bPcmFrame << 5)
++                              | (sDioInfo.asPortInfo[ePort].sDioCommon.bPcmHighPeriod);
++              if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_HIZ_REDGE0+bRegOffset))
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)(MCI_AA_HIZ_REDGE0+bRegOffset), bReg);
++              }
++      }
++}
++
++/****************************************************************************
++ *    AddDIODIR
++ *
++ *    Description:
++ *                    Add DigitalI0 DIR setup packet.
++ *    Arguments:
++ *                    ePort           port number
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   AddDIODIR
++(
++      MCDRV_DIO_PORT_NO_AA    ePort
++)
++{
++      UINT8   bReg;
++      UINT8   bRegOffset;
++      UINT16  wSrcRate;
++      MCDRV_DIO_INFO  sDioInfo;
++
++      if(ePort == eMCDRV_DIO_0_AA)
++      {
++              bRegOffset      = 0;
++      }
++      else if(ePort == eMCDRV_DIO_1_AA)
++      {
++              bRegOffset      = MCI_AA_DIMODE1 - MCI_AA_DIMODE0;
++      }
++      else if(ePort == eMCDRV_DIO_2_AA)
++      {
++              bRegOffset      = MCI_AA_DIMODE2 - MCI_AA_DIMODE0;
++      }
++      else
++      {
++              return;
++      }
++
++      McResCtrl_GetDioInfo_AA(&sDioInfo);
++
++      /*      DIRSRC_RATE*    */
++      wSrcRate        = sDioInfo.asPortInfo[ePort].sDir.wSrcRate;
++      if(wSrcRate == 0)
++      {
++              switch(sDioInfo.asPortInfo[ePort].sDioCommon.bFs)
++              {
++              case MCDRV_FS_48000:
++                      wSrcRate        = MCDRV_DIR_SRCRATE_48000_AA;
++                      break;
++              case MCDRV_FS_44100:
++                      wSrcRate        = MCDRV_DIR_SRCRATE_44100_AA;
++                      break;
++              case MCDRV_FS_32000:
++                      wSrcRate        = MCDRV_DIR_SRCRATE_32000_AA;
++                      break;
++              case MCDRV_FS_24000:
++                      wSrcRate        = MCDRV_DIR_SRCRATE_24000_AA;
++                      break;
++              case MCDRV_FS_22050:
++                      wSrcRate        = MCDRV_DIR_SRCRATE_22050_AA;
++                      break;
++              case MCDRV_FS_16000:
++                      wSrcRate        = MCDRV_DIR_SRCRATE_16000_AA;
++                      break;
++              case MCDRV_FS_12000:
++                      wSrcRate        = MCDRV_DIR_SRCRATE_12000_AA;
++                      break;
++              case MCDRV_FS_11025:
++                      wSrcRate        = MCDRV_DIR_SRCRATE_11025_AA;
++                      break;
++              case MCDRV_FS_8000:
++                      wSrcRate        = MCDRV_DIR_SRCRATE_8000_AA;
++                      break;
++              default:
++                      /* unreachable */
++                      wSrcRate = 0;
++                      break;
++              }
++      }
++      bReg    = (UINT8)(wSrcRate>>8);
++      if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIRSRC_RATE0_MSB+bRegOffset))
++      {
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)(MCI_AA_DIRSRC_RATE0_MSB+bRegOffset), bReg);
++      }
++      bReg    = (UINT8)wSrcRate;
++      if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIRSRC_RATE0_LSB+bRegOffset))
++      {
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)(MCI_AA_DIRSRC_RATE0_LSB+bRegOffset), bReg);
++      }
++
++      /*      DIT*_FMT, DIT*_BIT, DIR*_FMT, DIR*_BIT  */
++      if(sDioInfo.asPortInfo[ePort].sDioCommon.bInterface == MCDRV_DIO_DA)
++      {
++              bReg    = (sDioInfo.asPortInfo[ePort].sDit.sDaFormat.bMode << 6)
++                              | (sDioInfo.asPortInfo[ePort].sDit.sDaFormat.bBitSel << 4)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sDaFormat.bMode << 2)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sDaFormat.bBitSel);
++              if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIX0_FMT+bRegOffset))
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)(MCI_AA_DIX0_FMT+bRegOffset), bReg);
++              }
++              /*      DIR*_CH */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDir.abSlot[1] << 4) | (sDioInfo.asPortInfo[ePort].sDir.abSlot[0]);
++              if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIR0_CH+bRegOffset))
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)(MCI_AA_DIR0_CH+bRegOffset), bReg);
++              }
++      }
++      else
++      {
++              /*      PCM_MONO_RX*, PCM_EXTEND_RX*, PCM_LSBON_RX*, PCM_LAW_RX*, PCM_BIT_RX*   */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDir.sPcmFormat.bMono << 7)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sPcmFormat.bOrder << 4)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sPcmFormat.bLaw << 2)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sPcmFormat.bBitSel);
++              if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_PCM_RX0+bRegOffset))
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)(MCI_AA_PCM_RX0+bRegOffset), bReg);
++              }
++              /*      PCM_CH1_RX*, PCM_CH0_RX*        */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDir.abSlot[1] << 4) | (sDioInfo.asPortInfo[ePort].sDir.abSlot[0]);
++              if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_PCM_SLOT_RX0+bRegOffset))
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)(MCI_AA_PCM_SLOT_RX0+bRegOffset), bReg);
++              }
++      }
++}
++
++/****************************************************************************
++ *    AddDIODIT
++ *
++ *    Description:
++ *                    Add DigitalI0 DIT setup packet.
++ *    Arguments:
++ *                    ePort           port number
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   AddDIODIT
++(
++      MCDRV_DIO_PORT_NO_AA    ePort
++)
++{
++      UINT8   bReg;
++      UINT8   bRegOffset;
++      UINT16  wSrcRate;
++      MCDRV_DIO_INFO  sDioInfo;
++
++      if(ePort == eMCDRV_DIO_0_AA)
++      {
++              bRegOffset      = 0;
++      }
++      else if(ePort == eMCDRV_DIO_1_AA)
++      {
++              bRegOffset      = MCI_AA_DIMODE1 - MCI_AA_DIMODE0;
++      }
++      else if(ePort == eMCDRV_DIO_2_AA)
++      {
++              bRegOffset      = MCI_AA_DIMODE2 - MCI_AA_DIMODE0;
++      }
++      else
++      {
++              return;
++      }
++
++      McResCtrl_GetDioInfo_AA(&sDioInfo);
++
++      wSrcRate        = sDioInfo.asPortInfo[ePort].sDit.wSrcRate;
++      if(wSrcRate == 0)
++      {
++              switch(sDioInfo.asPortInfo[ePort].sDioCommon.bFs)
++              {
++              case MCDRV_FS_48000:
++                      wSrcRate        = MCDRV_DIT_SRCRATE_48000_AA;
++                      break;
++              case MCDRV_FS_44100:
++                      wSrcRate        = MCDRV_DIT_SRCRATE_44100_AA;
++                      break;
++              case MCDRV_FS_32000:
++                      wSrcRate        = MCDRV_DIT_SRCRATE_32000_AA;
++                      break;
++              case MCDRV_FS_24000:
++                      wSrcRate        = MCDRV_DIT_SRCRATE_24000_AA;
++                      break;
++              case MCDRV_FS_22050:
++                      wSrcRate        = MCDRV_DIT_SRCRATE_22050_AA;
++                      break;
++              case MCDRV_FS_16000:
++                      wSrcRate        = MCDRV_DIT_SRCRATE_16000_AA;
++                      break;
++              case MCDRV_FS_12000:
++                      wSrcRate        = MCDRV_DIT_SRCRATE_12000_AA;
++                      break;
++              case MCDRV_FS_11025:
++                      wSrcRate        = MCDRV_DIT_SRCRATE_11025_AA;
++                      break;
++              case MCDRV_FS_8000:
++                      wSrcRate        = MCDRV_DIT_SRCRATE_8000_AA;
++                      break;
++              default:
++                      /* unreachable */
++                      wSrcRate = 0;
++                      break;
++              }
++      }
++      /*      DITSRC_RATE*    */
++      bReg    = (UINT8)(wSrcRate>>8);
++      if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DITSRC_RATE0_MSB+bRegOffset))
++      {
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)(MCI_AA_DITSRC_RATE0_MSB+bRegOffset), bReg);
++      }
++      bReg    = (UINT8)wSrcRate;
++      if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DITSRC_RATE0_LSB+bRegOffset))
++      {
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)(MCI_AA_DITSRC_RATE0_LSB+bRegOffset), bReg);
++      }
++
++      if(sDioInfo.asPortInfo[ePort].sDioCommon.bInterface == MCDRV_DIO_DA)
++      {
++              /*      DIT*_FMT, DIT*_BIT, DIR*_FMT, DIR*_BIT  */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDit.sDaFormat.bMode << 6)
++                              | (sDioInfo.asPortInfo[ePort].sDit.sDaFormat.bBitSel << 4)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sDaFormat.bMode << 2)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sDaFormat.bBitSel);
++              if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIX0_FMT+bRegOffset))
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)(MCI_AA_DIX0_FMT+bRegOffset), bReg);
++              }
++
++              /*      DIT*_SLOT       */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDit.abSlot[1] << 4) | (sDioInfo.asPortInfo[ePort].sDit.abSlot[0]);
++              if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIT0_SLOT+bRegOffset))
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)(MCI_AA_DIT0_SLOT+bRegOffset), bReg);
++              }
++      }
++      else
++      {
++              /*      PCM_MONO_TX*, PCM_EXTEND_TX*, PCM_LSBON_TX*, PCM_LAW_TX*, PCM_BIT_TX*   */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDit.sPcmFormat.bMono << 7)
++                              | (sDioInfo.asPortInfo[ePort].sDit.sPcmFormat.bOrder << 4)
++                              | (sDioInfo.asPortInfo[ePort].sDit.sPcmFormat.bLaw << 2)
++                              | (sDioInfo.asPortInfo[ePort].sDit.sPcmFormat.bBitSel);
++              if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_PCM_TX0+bRegOffset))
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)(MCI_AA_PCM_TX0+bRegOffset), bReg);
++              }
++
++              /*      PCM_CH1_TX*, PCM_CH0_TX*        */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDit.abSlot[1] << 4) | (sDioInfo.asPortInfo[ePort].sDit.abSlot[0]);
++              if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_PCM_SLOT_TX0+bRegOffset))
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)(MCI_AA_PCM_SLOT_TX0+bRegOffset), bReg);
++              }
++      }
++}
++
++/****************************************************************************
++ *    McPacket_AddDAC_AA
++ *
++ *    Description:
++ *                    Add DAC setup packet.
++ *    Arguments:
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddDAC_AA
++(
++      UINT32                  dUpdateInfo
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      MCDRV_POWER_INFO_AA     sPowerInfo;
++      MCDRV_POWER_UPDATE_AA   sPowerUpdate;
++      MCDRV_DAC_INFO          sDacInfo;
++      UINT8   bReg;
++
++      McResCtrl_GetDacInfo_AA(&sDacInfo);
++
++      if((dUpdateInfo & MCDRV_DAC_MSWP_UPDATE_FLAG) != (UINT32)0 || (dUpdateInfo & MCDRV_DAC_VSWP_UPDATE_FLAG) != (UINT32)0)
++      {
++              bReg    = (sDacInfo.bMasterSwap<<4)|sDacInfo.bVoiceSwap;
++              if(bReg == McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_SWP))
++              {
++                      dUpdateInfo     &= ~(MCDRV_DAC_MSWP_UPDATE_FLAG|MCDRV_DAC_VSWP_UPDATE_FLAG);
++              }
++      }
++      if((dUpdateInfo & MCDRV_DAC_HPF_UPDATE_FLAG) != (UINT32)0)
++      {
++              if(sDacInfo.bDcCut == McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_CODEC_AA, MCI_AA_DCCUTOFF))
++              {
++                      dUpdateInfo     &= ~(MCDRV_DAC_HPF_UPDATE_FLAG);
++              }
++      }
++      if(dUpdateInfo == (UINT32)0)
++      {
++              return sdRet;
++      }
++
++      McResCtrl_GetCurPowerInfo_AA(&sPowerInfo);
++      sdRet   = PowerUpDig(MCDRV_DPB_UP_AA);
++      if(sdRet != MCDRV_SUCCESS)
++      {
++              return sdRet;
++      }
++
++      if((dUpdateInfo & MCDRV_DAC_MSWP_UPDATE_FLAG) != (UINT32)0 || (dUpdateInfo & MCDRV_DAC_VSWP_UPDATE_FLAG) != (UINT32)0)
++      {
++              bReg    = (sDacInfo.bMasterSwap<<4)|sDacInfo.bVoiceSwap;
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_SWP, bReg);
++      }
++      if((dUpdateInfo & MCDRV_DAC_HPF_UPDATE_FLAG) != (UINT32)0)
++      {
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_CODEC_AA | MCI_AA_DCCUTOFF, sDacInfo.bDcCut);
++      }
++
++      /*      unused path power down  */
++      sPowerUpdate.dDigital           = MCDRV_POWUPDATE_DIGITAL_ALL_AA;
++      sPowerUpdate.abAnalog[0]        =
++      sPowerUpdate.abAnalog[1]        =
++      sPowerUpdate.abAnalog[2]        =
++      sPowerUpdate.abAnalog[3]        =
++      sPowerUpdate.abAnalog[4]        = 0;
++      return McPacket_AddPowerDown_AA(&sPowerInfo, &sPowerUpdate);
++}
++
++/****************************************************************************
++ *    McPacket_AddADC_AA
++ *
++ *    Description:
++ *                    Add ADC setup packet.
++ *    Arguments:
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddADC_AA
++(
++      UINT32                  dUpdateInfo
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bReg;
++      MCDRV_POWER_INFO_AA     sPowerInfo;
++      MCDRV_POWER_UPDATE_AA   sPowerUpdate;
++      MCDRV_ADC_INFO          sAdcInfo;
++
++      McResCtrl_GetAdcInfo_AA(&sAdcInfo);
++
++      if((dUpdateInfo & MCDRV_ADCADJ_UPDATE_FLAG) != (UINT32)0 || (dUpdateInfo & MCDRV_ADCAGC_UPDATE_FLAG) != (UINT32)0)
++      {
++              bReg    = (sAdcInfo.bAgcOn<<2)|sAdcInfo.bAgcAdjust;
++              if(bReg == McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_CODEC_AA, MCI_AA_AD_AGC))
++              {
++                      dUpdateInfo     &= ~(MCDRV_ADCADJ_UPDATE_FLAG|MCDRV_ADCAGC_UPDATE_FLAG);
++              }
++      }
++      if((dUpdateInfo & MCDRV_ADCMONO_UPDATE_FLAG) != (UINT32)0)
++      {
++              bReg    = (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_CODEC_AA, MCI_AA_AD_START) & MCB_AA_AD_START) | (sAdcInfo.bMono << 1);
++              if(bReg == McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_CODEC_AA, MCI_AA_AD_START))
++              {
++                      dUpdateInfo     &= ~(MCDRV_ADCMONO_UPDATE_FLAG);
++              }
++      }
++
++      if(dUpdateInfo == (UINT32)0)
++      {
++              return sdRet;
++      }
++
++      McResCtrl_GetCurPowerInfo_AA(&sPowerInfo);
++      sdRet   = PowerUpDig(MCDRV_DPB_UP_AA);
++      if(sdRet != MCDRV_SUCCESS)
++      {
++              return sdRet;
++      }
++
++      if((dUpdateInfo & MCDRV_ADCADJ_UPDATE_FLAG) != (UINT32)0 || (dUpdateInfo & MCDRV_ADCAGC_UPDATE_FLAG) != (UINT32)0)
++      {
++              bReg    = (sAdcInfo.bAgcOn<<2)|sAdcInfo.bAgcAdjust;
++              if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_CODEC_AA, MCI_AA_AD_AGC))
++              {
++                      AddStopADC();
++                      sdRet   = McDevIf_ExecutePacket_AA();
++                      if(MCDRV_SUCCESS != sdRet)
++                      {
++                              return sdRet;
++                      }
++              }
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_CODEC_AA | MCI_AA_AD_AGC, bReg);
++      }
++      if((dUpdateInfo & MCDRV_ADCMONO_UPDATE_FLAG) != (UINT32)0)
++      {
++              bReg    = (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_CODEC_AA, MCI_AA_AD_START) & MCB_AA_AD_START) | (sAdcInfo.bMono << 1);
++              if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_CODEC_AA, MCI_AA_AD_START))
++              {
++                      AddStopADC();
++                      sdRet   = McDevIf_ExecutePacket_AA();
++                      if(MCDRV_SUCCESS != sdRet)
++                      {
++                              return sdRet;
++                      }
++              }
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_CODEC_AA | MCI_AA_AD_START, (sAdcInfo.bMono << 1));
++      }
++
++      /*      unused path power down  */
++      sPowerUpdate.dDigital           = MCDRV_POWUPDATE_DIGITAL_ALL_AA;
++      sPowerUpdate.abAnalog[0]        =
++      sPowerUpdate.abAnalog[1]        =
++      sPowerUpdate.abAnalog[2]        =
++      sPowerUpdate.abAnalog[3]        =
++      sPowerUpdate.abAnalog[4]        = 0;
++      sdRet   = McPacket_AddPowerDown_AA(&sPowerInfo, &sPowerUpdate);
++      if(sdRet != MCDRV_SUCCESS)
++      {
++              return sdRet;
++      }
++      return McPacket_AddStart_AA();
++}
++
++/****************************************************************************
++ *    McPacket_AddSP_AA
++ *
++ *    Description:
++ *                    Add SP setup packet.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddSP_AA
++(
++      void
++)
++{
++      MCDRV_SP_INFO   sSpInfo;
++      UINT8   bReg    = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_SP_MODE) & (UINT8)~MCB_AA_SP_SWAP;
++
++      McResCtrl_GetSpInfo_AA(&sSpInfo);
++
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_SP_MODE, bReg|sSpInfo.bSwap);
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    McPacket_AddDNG_AA
++ *
++ *    Description:
++ *                    Add Digital Noise Gate setup packet.
++ *    Arguments:
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddDNG_AA
++(
++      UINT32                  dUpdateInfo
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      MCDRV_POWER_INFO_AA     sCurPowerInfo;
++      MCDRV_POWER_INFO_AA     sPowerInfo;
++      MCDRV_POWER_UPDATE_AA   sPowerUpdate;
++      MCDRV_DNG_INFO          sDngInfo;
++      UINT8   bReg;
++
++      McResCtrl_GetDngInfo_AA(&sDngInfo);
++
++      if((dUpdateInfo & MCDRV_DNGREL_HP_UPDATE_FLAG) != (UINT32)0 || (dUpdateInfo & MCDRV_DNGATK_HP_UPDATE_FLAG) != (UINT32)0)
++      {
++              bReg    = (sDngInfo.abRelease[0]<<4)|sDngInfo.abAttack[0];
++              if(bReg == McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_DNGATRT))
++              {
++                      dUpdateInfo     &= ~(MCDRV_DNGREL_HP_UPDATE_FLAG|MCDRV_DNGATK_HP_UPDATE_FLAG);
++              }
++      }
++      if((dUpdateInfo & MCDRV_DNGSW_HP_UPDATE_FLAG) != (UINT32)0
++      || (dUpdateInfo & MCDRV_DNGTHRES_HP_UPDATE_FLAG) != (UINT32)0
++      || (dUpdateInfo & MCDRV_DNGHOLD_HP_UPDATE_FLAG) != (UINT32)0)
++      {
++              bReg    = (sDngInfo.abThreshold[0]<<4)|(sDngInfo.abHold[0]<<1)|sDngInfo.abOnOff[0];
++              if(bReg == McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_ANA_AA, MCI_AA_DNGON))
++              {
++                      dUpdateInfo     &= ~(MCDRV_DNGSW_HP_UPDATE_FLAG|MCDRV_DNGTHRES_HP_UPDATE_FLAG|MCDRV_DNGHOLD_HP_UPDATE_FLAG);
++              }
++      }
++      if(dUpdateInfo == (UINT32)0)
++      {
++              return sdRet;
++      }
++
++      McResCtrl_GetCurPowerInfo_AA(&sCurPowerInfo);
++      sPowerInfo      = sCurPowerInfo;
++      sPowerInfo.dDigital     &= ~MCDRV_POWINFO_DIGITAL_DP0_AA;
++      sPowerInfo.dDigital     &= ~MCDRV_POWINFO_DIGITAL_DP1_AA;
++      sPowerInfo.dDigital     &= ~MCDRV_POWINFO_DIGITAL_DP2_AA;
++      sPowerInfo.dDigital     &= ~MCDRV_POWINFO_DIGITAL_PLLRST0_AA;
++      sPowerUpdate.dDigital   = MCDRV_POWUPDATE_DIGITAL_ALL_AA;
++      if((dUpdateInfo & MCDRV_DNGREL_HP_UPDATE_FLAG) != (UINT32)0 || (dUpdateInfo & MCDRV_DNGATK_HP_UPDATE_FLAG) != (UINT32)0)
++      {
++              sPowerInfo.abAnalog[0]  &= (UINT8)~MCB_AA_PWM_VR;
++              sPowerUpdate.abAnalog[0]        = (UINT8)MCDRV_POWUPDATE_ANALOG0_ALL_AA;
++              sPowerUpdate.abAnalog[1]        =
++              sPowerUpdate.abAnalog[2]        =
++              sPowerUpdate.abAnalog[3]        =
++              sPowerUpdate.abAnalog[4]        = 0;
++      }
++      sdRet   = McPacket_AddPowerUp_AA(&sPowerInfo, &sPowerUpdate);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      sdRet   = McDevIf_ExecutePacket_AA();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      sdRet   = McDevIf_ExecutePacket_AA();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      if((dUpdateInfo & MCDRV_DNGREL_HP_UPDATE_FLAG) != (UINT32)0 || (dUpdateInfo & MCDRV_DNGATK_HP_UPDATE_FLAG) != (UINT32)0)
++      {
++              bReg    = (sDngInfo.abRelease[0]<<4)|sDngInfo.abAttack[0];
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_DNGATRT, bReg);
++      }
++      if((dUpdateInfo & MCDRV_DNGSW_HP_UPDATE_FLAG) != (UINT32)0
++      || (dUpdateInfo & MCDRV_DNGTHRES_HP_UPDATE_FLAG) != (UINT32)0
++      || (dUpdateInfo & MCDRV_DNGHOLD_HP_UPDATE_FLAG) != (UINT32)0)
++      {
++              bReg    = (sDngInfo.abThreshold[0]<<4)|(sDngInfo.abHold[0]<<1)|sDngInfo.abOnOff[0];
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | MCI_AA_DNGON, bReg);
++      }
++
++      /*      restore power   */
++      return McPacket_AddPowerDown_AA(&sCurPowerInfo, &sPowerUpdate);
++}
++
++/****************************************************************************
++ *    McPacket_AddAE_AA
++ *
++ *    Description:
++ *                    Add Audio Engine setup packet.
++ *    Arguments:
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddAE_AA
++(
++      UINT32  dUpdateInfo
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bReg;
++      UINT8   i;
++      UINT32  dXFadeParam     = 0;
++      MCDRV_AE_INFO   sAeInfo;
++      MCDRV_PATH_INFO sPathInfo;
++      MCDRV_POWER_INFO_AA     sPowerInfo;
++      MCDRV_POWER_UPDATE_AA   sPowerUpdate;
++
++      McResCtrl_GetPathInfo_AA(&sPathInfo);
++      McResCtrl_GetAeInfo_AA(&sAeInfo);
++
++      if(McResCtrl_IsDstUsed_AA(eMCDRV_DST_AE_AA, eMCDRV_DST_CH0_AA) == 1)
++      {/*     AE is used      */
++              bReg    = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_A_AA, MCI_AA_BDSP_ST);
++              if(McDevProf_IsValid(eMCDRV_FUNC_DBEX) == 1)
++              {
++                      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_BEXWIDE_ONOFF) != (UINT32)0)
++                      {
++                              if(((sAeInfo.bOnOff & MCDRV_BEXWIDE_ON) != 0 && (bReg & MCB_AA_DBEXON) != 0)
++                              || ((sAeInfo.bOnOff & MCDRV_BEXWIDE_ON) == 0 && (bReg & MCB_AA_DBEXON) == 0))
++                              {
++                                      dUpdateInfo     &= ~MCDRV_AEUPDATE_FLAG_BEXWIDE_ONOFF;
++                              }
++                      }
++              }
++              if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_DRC_ONOFF) != (UINT32)0)
++              {
++                      if(((sAeInfo.bOnOff & MCDRV_DRC_ON) != 0 && (bReg & MCB_AA_DRCON) != 0)
++                      || ((sAeInfo.bOnOff & MCDRV_DRC_ON) == 0 && (bReg & MCB_AA_DRCON) == 0))
++                      {
++                              dUpdateInfo     &= ~MCDRV_AEUPDATE_FLAG_DRC_ONOFF;
++                      }
++              }
++              if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ5_ONOFF) != (UINT32)0)
++              {
++                      if(((sAeInfo.bOnOff & MCDRV_EQ5_ON) != 0 && (bReg & MCB_AA_EQ5ON) != 0)
++                      || ((sAeInfo.bOnOff & MCDRV_EQ5_ON) == 0 && (bReg & MCB_AA_EQ5ON) == 0))
++                      {
++                              dUpdateInfo     &= ~MCDRV_AEUPDATE_FLAG_EQ5_ONOFF;
++                      }
++              }
++              if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ3_ONOFF) != (UINT32)0)
++              {
++                      if(((sAeInfo.bOnOff & MCDRV_EQ3_ON) != 0 && (bReg & MCB_AA_EQ3ON) != 0)
++                      || ((sAeInfo.bOnOff & MCDRV_EQ3_ON) == 0 && (bReg & MCB_AA_EQ3ON) == 0))
++                      {
++                              dUpdateInfo     &= ~MCDRV_AEUPDATE_FLAG_EQ3_ONOFF;
++                      }
++              }
++              if(dUpdateInfo == (UINT32)0)
++              {
++                      return sdRet;
++              }
++
++              /*      on/off setting or param changed */
++              if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ5) != (UINT32)0
++              || (dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ3) != (UINT32)0
++              || (dUpdateInfo & MCDRV_AEUPDATE_FLAG_BEX) != (UINT32)0
++              || (dUpdateInfo & MCDRV_AEUPDATE_FLAG_WIDE) != (UINT32)0
++              || (dUpdateInfo & MCDRV_AEUPDATE_FLAG_DRC) != (UINT32)0
++              || (dUpdateInfo & MCDRV_AEUPDATE_FLAG_BEXWIDE_ONOFF) != (UINT32)0
++              || (dUpdateInfo & MCDRV_AEUPDATE_FLAG_DRC_ONOFF) != (UINT32)0
++              || (dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ5_ONOFF) != (UINT32)0
++              || (dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ3_ONOFF) != (UINT32)0)
++              {
++                      dXFadeParam     = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DAC_INS);
++                      dXFadeParam     <<= 8;
++                      dXFadeParam     |= McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_INS);
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)MCI_AA_DAC_INS, 0);
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)MCI_AA_INS, 0);
++              }
++              sdRet   = McDevIf_ExecutePacket_AA();
++              if(sdRet != MCDRV_SUCCESS)
++              {
++                      return sdRet;
++              }
++
++              /*      wait xfade complete     */
++              if(dXFadeParam != (UINT32)0)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_EVTWAIT_AA | MCDRV_EVT_INSFLG_AA | dXFadeParam, 0);
++                      bReg    = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_A_AA, MCI_AA_BDSP_ST);
++                      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ5) != (UINT32)0)
++                      {
++                              bReg    &= (UINT8)~MCB_AA_EQ5ON;
++                      }
++                      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ3) != (UINT32)0)
++                      {
++                              bReg    &= (UINT8)~MCB_AA_EQ3ON;
++                      }
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_A_AA | (UINT32)MCI_AA_BDSP_ST, bReg);
++              }
++
++              bReg    = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_A_AA, MCI_AA_BDSP_ST);
++              if((bReg & MCB_AA_BDSP_ST) == MCB_AA_BDSP_ST)
++              {
++                      /*      Stop BDSP       */
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_A_AA | (UINT32)MCI_AA_BDSP_ST, 0);
++                      /*      Reset TRAM      */
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_A_AA | (UINT32)MCI_AA_BDSP_RST, MCB_AA_TRAM_RST);
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_A_AA | (UINT32)MCI_AA_BDSP_RST, 0);
++              }
++      }
++
++      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_DRC) != (UINT32)0)
++      {
++              McResCtrl_GetPowerInfo_AA(&sPowerInfo);
++              sPowerInfo.dDigital     &= ~MCDRV_POWINFO_DIGITAL_DP0_AA;
++              sPowerInfo.dDigital     &= ~MCDRV_POWINFO_DIGITAL_DP1_AA;
++              sPowerInfo.dDigital     &= ~MCDRV_POWINFO_DIGITAL_DP2_AA;
++              sPowerInfo.dDigital     &= ~MCDRV_POWINFO_DIGITAL_DPBDSP_AA;
++              sPowerInfo.dDigital     &= ~MCDRV_POWINFO_DIGITAL_PLLRST0_AA;
++              sPowerUpdate.dDigital   = MCDRV_POWUPDATE_DIGITAL_ALL_AA;
++              sPowerUpdate.abAnalog[0]        =
++              sPowerUpdate.abAnalog[1]        =
++              sPowerUpdate.abAnalog[2]        =
++              sPowerUpdate.abAnalog[3]        =
++              sPowerUpdate.abAnalog[4]        = 0;
++              sdRet   = McPacket_AddPowerUp_AA(&sPowerInfo, &sPowerUpdate);
++              if(MCDRV_SUCCESS != sdRet)
++              {
++                      return sdRet;
++              }
++              sdRet   = McDevIf_ExecutePacket_AA();
++              if(MCDRV_SUCCESS != sdRet)
++              {
++                      return sdRet;
++              }
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_FORCE_WRITE_AA | MCDRV_PACKET_REGTYPE_A_AA | (UINT32)MCI_AA_BDSP_ADR, 0);
++              sdRet   = McDevIf_ExecutePacket_AA();
++              if(MCDRV_SUCCESS != sdRet)
++              {
++                      return sdRet;
++              }
++              McDevIf_AddPacketRepeat_AA(MCDRV_PACKET_TYPE_FORCE_WRITE_AA | MCDRV_PACKET_REGTYPE_A_AA | (UINT32)MCI_AA_BDSP_WINDOW, sAeInfo.abDrc, DRC_PARAM_SIZE);
++      }
++
++      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ5) != (UINT32)0)
++      {
++              for(i = 0; i < EQ5_PARAM_SIZE; i++)
++              {
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_FORCE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_AE_AA | (UINT32)(MCI_AA_BAND0_CEQ0+i), sAeInfo.abEq5[i]);
++              }
++      }
++      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ3) != (UINT32)0)
++      {
++              if(McDevProf_IsValid(eMCDRV_FUNC_HWADJ) == 1)
++              {
++                      for(i = 0; i < 15; i++)
++                      {
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_FORCE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_AE_AA | (UINT32)(MCI_AA_BAND5_CEQ0+i), sAeInfo.abEq3[i]);
++                      }
++              }
++              else
++              {
++                      for(i = 0; i < EQ3_PARAM_SIZE; i++)
++                      {
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_FORCE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_AE_AA | (UINT32)(MCI_AA_BAND5_CEQ0+i), sAeInfo.abEq3[i]);
++                      }
++              }
++      }
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    McPacket_AddPDM_AA
++ *
++ *    Description:
++ *                    Add PDM setup packet.
++ *    Arguments:
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddPDM_AA
++(
++      UINT32                  dUpdateInfo
++)
++{
++      SINT32                          sdRet           = MCDRV_SUCCESS;
++      UINT8                           bReg;
++      MCDRV_POWER_INFO_AA     sPowerInfo;
++      MCDRV_POWER_UPDATE_AA   sPowerUpdate;
++      MCDRV_PDM_INFO          sPdmInfo;
++
++      McResCtrl_GetPdmInfo_AA(&sPdmInfo);
++      if((dUpdateInfo & MCDRV_PDMADJ_UPDATE_FLAG) != (UINT32)0 || (dUpdateInfo & MCDRV_PDMAGC_UPDATE_FLAG) != (UINT32)0)
++      {
++              bReg    = (sPdmInfo.bAgcOn<<2)|sPdmInfo.bAgcAdjust;
++              if(bReg == McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_PDM_AGC))
++              {
++                      dUpdateInfo &= ~(MCDRV_PDMADJ_UPDATE_FLAG|MCDRV_PDMAGC_UPDATE_FLAG);
++              }
++      }
++      if((dUpdateInfo & MCDRV_PDMMONO_UPDATE_FLAG) != (UINT32)0)
++      {
++              bReg    = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_PDM_START) & (UINT8)MCB_AA_PDM_MN;
++              if((sPdmInfo.bMono<<1) == bReg)
++              {
++                      dUpdateInfo &= ~(MCDRV_PDMMONO_UPDATE_FLAG);
++              }
++      }
++      if((dUpdateInfo & MCDRV_PDMCLK_UPDATE_FLAG) != (UINT32)0
++      || (dUpdateInfo & MCDRV_PDMEDGE_UPDATE_FLAG) != (UINT32)0
++      || (dUpdateInfo & MCDRV_PDMWAIT_UPDATE_FLAG) != (UINT32)0
++      || (dUpdateInfo & MCDRV_PDMSEL_UPDATE_FLAG) != (UINT32)0)
++      {
++              bReg    = (sPdmInfo.bPdmWait<<5) | (sPdmInfo.bPdmEdge<<4) | (sPdmInfo.bPdmSel<<2) | sPdmInfo.bClk;
++              if(bReg == McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_PDM_STWAIT))
++              {
++                      dUpdateInfo &= ~(MCDRV_PDMCLK_UPDATE_FLAG|MCDRV_PDMEDGE_UPDATE_FLAG|MCDRV_PDMWAIT_UPDATE_FLAG|MCDRV_PDMSEL_UPDATE_FLAG);
++              }
++      }
++      if(dUpdateInfo == (UINT32)0)
++      {
++              return MCDRV_SUCCESS;
++      }
++
++      McResCtrl_GetCurPowerInfo_AA(&sPowerInfo);
++      sdRet   = PowerUpDig(MCDRV_DPB_UP_AA);
++      if(sdRet != MCDRV_SUCCESS)
++      {
++              return sdRet;
++      }
++
++      if((dUpdateInfo & MCDRV_PDMADJ_UPDATE_FLAG) != (UINT32)0 || (dUpdateInfo & MCDRV_PDMAGC_UPDATE_FLAG) != (UINT32)0)
++      {
++              bReg    = (sPdmInfo.bAgcOn<<2)|sPdmInfo.bAgcAdjust;
++              if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_PDM_AGC))
++              {
++                      AddStopPDM();
++                      sdRet   = McDevIf_ExecutePacket_AA();
++                      if(MCDRV_SUCCESS != sdRet)
++                      {
++                              return sdRet;
++                      }
++              }
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_PDM_AGC, bReg);
++      }
++      if((dUpdateInfo & MCDRV_PDMMONO_UPDATE_FLAG) != (UINT32)0)
++      {
++              bReg    = (McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_PDM_START) & (UINT8)~MCB_AA_PDM_MN) | (sPdmInfo.bMono<<1);
++              if(bReg != McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_PDM_START))
++              {
++                      AddStopPDM();
++                      sdRet   = McDevIf_ExecutePacket_AA();
++                      if(MCDRV_SUCCESS != sdRet)
++                      {
++                              return sdRet;
++                      }
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_PDM_START, (sPdmInfo.bMono<<1));
++              }
++      }
++      if((dUpdateInfo & MCDRV_PDMCLK_UPDATE_FLAG) != (UINT32)0
++      || (dUpdateInfo & MCDRV_PDMEDGE_UPDATE_FLAG) != (UINT32)0
++      || (dUpdateInfo & MCDRV_PDMWAIT_UPDATE_FLAG) != (UINT32)0
++      || (dUpdateInfo & MCDRV_PDMSEL_UPDATE_FLAG) != (UINT32)0)
++      {
++              bReg    = (sPdmInfo.bPdmWait<<5) | (sPdmInfo.bPdmEdge<<4) | (sPdmInfo.bPdmSel<<2) | sPdmInfo.bClk;
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_PDM_STWAIT, bReg);
++      }
++
++      /*      unused path power down  */
++      sPowerUpdate.dDigital           = MCDRV_POWUPDATE_DIGITAL_ALL_AA;
++      sPowerUpdate.abAnalog[0]        =
++      sPowerUpdate.abAnalog[1]        =
++      sPowerUpdate.abAnalog[2]        =
++      sPowerUpdate.abAnalog[3]        =
++      sPowerUpdate.abAnalog[4]        = 0;
++      sdRet   = McPacket_AddPowerDown_AA(&sPowerInfo, &sPowerUpdate);
++      if(sdRet != MCDRV_SUCCESS)
++      {
++              return sdRet;
++      }
++      return McPacket_AddStart_AA();
++}
++
++/****************************************************************************
++ *    McPacket_AddGPMode_AA
++ *
++ *    Description:
++ *                    Add GP mode setup packet.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddGPMode_AA
++(
++      void
++)
++{
++      UINT8   abReg[2];
++      MCDRV_INIT_INFO sInitInfo;
++      MCDRV_GP_MODE   sGPMode;
++
++      McResCtrl_GetInitInfo_AA(&sInitInfo);
++      McResCtrl_GetGPMode_AA(&sGPMode);
++
++      abReg[0]        = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_BASE_AA, MCI_AA_PA_MSK);
++      abReg[1]        = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_BASE_AA, MCI_AA_PA_MSK_1);
++
++      if(sInitInfo.bPad0Func == MCDRV_PAD_GPIO)
++      {
++              if(sGPMode.abGpDdr[0] == MCDRV_GPDDR_IN)
++              {
++                      abReg[1]        &= (UINT8)~MCB_AA_PA0_DDR;
++              }
++              else
++              {
++                      abReg[1]        |= MCB_AA_PA0_DDR;
++              }
++      }
++      if(sInitInfo.bPad1Func == MCDRV_PAD_GPIO)
++      {
++              if(sGPMode.abGpDdr[1] == MCDRV_GPDDR_IN)
++              {
++                      abReg[1]        &= (UINT8)~MCB_AA_PA1_DDR;
++              }
++              else
++              {
++                      abReg[1]        |= MCB_AA_PA1_DDR;
++              }
++      }
++/*
++      if(sInitInfo.bPad2Func == MCDRV_PAD_GPIO)
++      {
++              if(sGPMode.abGpDdr[2] == MCDRV_GPDDR_IN)
++              {
++                      abReg[0]        &= (UINT8)~MCB_AA_PA2_DDR;
++              }
++              else
++              {
++                      abReg[0]        |= MCB_AA_PA2_DDR;
++              }
++      }
++*/
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PA_MSK, abReg[0]);
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PA_MSK_1, abReg[1]);
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    McPacket_AddGPMask_AA
++ *
++ *    Description:
++ *                    Add GP mask setup packet.
++ *    Arguments:
++ *                    dPadNo          PAD number
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddGPMask_AA
++(
++      UINT32  dPadNo
++)
++{
++      UINT8   bReg;
++      MCDRV_INIT_INFO sInitInfo;
++      MCDRV_GP_MODE   sGPMode;
++      UINT8   abMask[GPIO_PAD_NUM];
++
++      McResCtrl_GetInitInfo_AA(&sInitInfo);
++      McResCtrl_GetGPMode_AA(&sGPMode);
++      McResCtrl_GetGPMask_AA(abMask);
++
++      if(dPadNo == MCDRV_GP_PAD0)
++      {
++              if(sInitInfo.bPad0Func == MCDRV_PAD_GPIO && sGPMode.abGpDdr[0] == MCDRV_GPDDR_IN)
++              {
++                      bReg    = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_BASE_AA, MCI_AA_PA_MSK_1);
++                      if(abMask[0] == MCDRV_GPMASK_OFF)
++                      {
++                              bReg    &= (UINT8)~MCB_AA_PA0_MSK;
++                      }
++                      else
++                      {
++                              bReg    |= MCB_AA_PA0_MSK;
++                      }
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PA_MSK_1, bReg);
++              }
++      }
++      else if(dPadNo == MCDRV_GP_PAD1)
++      {
++              if(sInitInfo.bPad1Func == MCDRV_PAD_GPIO && sGPMode.abGpDdr[1] == MCDRV_GPDDR_IN)
++              {
++                      bReg    = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_BASE_AA, MCI_AA_PA_MSK_1);
++                      if(abMask[1] == MCDRV_GPMASK_OFF)
++                      {
++                              bReg    &= (UINT8)~MCB_AA_PA1_MSK;
++                      }
++                      else
++                      {
++                              bReg    |= MCB_AA_PA1_MSK;
++                      }
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PA_MSK_1, bReg);
++              }
++      }
++/*
++      else if(dPadNo == MCDRV_GP_PAD2)
++      {
++              if(sInitInfo.bPad2Func == MCDRV_PAD_GPIO && sGPMode.abGpDdr[2] == MCDRV_GPDDR_IN)
++              {
++                      bReg    = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_BASE_AA, MCI_AA_PA_MSK);
++                      if(abMask[2] == MCDRV_GPMASK_OFF)
++                      {
++                              bReg    &= (UINT8)~MCB_AA_PA2_MSK;
++                      }
++                      else
++                      {
++                              bReg    |= MCB_AA_PA2_MSK;
++                      }
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PA_MSK, bReg);
++              }
++      }
++*/
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    McPacket_AddGPSet_AA
++ *
++ *    Description:
++ *                    Add GPIO output packet.
++ *    Arguments:
++ *                    bGpio           pin state setting
++ *                    dPadNo          PAD number
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddGPSet_AA
++(
++      UINT8   bGpio,
++      UINT32  dPadNo
++)
++{
++      UINT8   bReg    = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_BASE_AA, MCI_AA_PA_SCU_PA);
++
++      if(dPadNo == MCDRV_GP_PAD0)
++      {
++              if(bGpio == MCDRV_GP_LOW)
++              {
++                      bReg    &= (UINT8)~MCB_AA_PA_SCU_PA0;
++              }
++              else if(bGpio == MCDRV_GP_HIGH)
++              {
++                      bReg    |= MCB_AA_PA_SCU_PA0;
++              }
++      }
++      else if(dPadNo == MCDRV_GP_PAD1)
++      {
++              if(bGpio == MCDRV_GP_LOW)
++              {
++                      bReg    &= (UINT8)~MCB_AA_PA_SCU_PA1;
++              }
++              else if(bGpio == MCDRV_GP_HIGH)
++              {
++                      bReg    |= MCB_AA_PA_SCU_PA1;
++              }
++      }
++/*
++      else if(dPadNo == MCDRV_GP_PAD2)
++      {
++              if(bGpio == MCDRV_GP_LOW)
++              {
++                      bReg    &= (UINT8)~MCB_AA_PA_SCU_PA2;
++              }
++              else if(bGpio == MCDRV_GP_HIGH)
++              {
++                      bReg    |= MCB_AA_PA_SCU_PA2;
++              }
++      }
++*/
++      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | MCI_AA_PA_SCU_PA, bReg);
++
++      return MCDRV_SUCCESS;
++}
++
++
++/****************************************************************************
++ *    PowerUpDig
++ *
++ *    Description:
++ *                    Digital power up.
++ *    Arguments:
++ *                    bDPBUp          1:DPB power up
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++static SINT32 PowerUpDig
++(
++      UINT8   bDPBUp
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      MCDRV_POWER_INFO_AA     sPowerInfo;
++      MCDRV_POWER_UPDATE_AA   sPowerUpdate;
++
++      McResCtrl_GetCurPowerInfo_AA(&sPowerInfo);
++      sPowerInfo.dDigital     &= ~MCDRV_POWINFO_DIGITAL_DP0_AA;
++      sPowerInfo.dDigital     &= ~MCDRV_POWINFO_DIGITAL_DP1_AA;
++      sPowerInfo.dDigital     &= ~MCDRV_POWINFO_DIGITAL_DP2_AA;
++      sPowerInfo.dDigital     &= ~MCDRV_POWINFO_DIGITAL_PLLRST0_AA;
++      if(bDPBUp == MCDRV_DPB_UP_AA)
++      {
++              sPowerInfo.dDigital     &= ~MCDRV_POWINFO_DIGITAL_DPB_AA;
++      }
++      sPowerUpdate.dDigital   = MCDRV_POWUPDATE_DIGITAL_ALL_AA;
++      sdRet   = McPacket_AddPowerUp_AA(&sPowerInfo, &sPowerUpdate);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      return McDevIf_ExecutePacket_AA();
++}
++
++/****************************************************************************
++ *    GetMaxWait
++ *
++ *    Description:
++ *                    Get maximum wait time.
++ *    Arguments:
++ *                    bRegChange      analog power management register update information
++ *    Return:
++ *                    wait time
++ *
++ ****************************************************************************/
++static UINT32 GetMaxWait
++(
++      UINT8   bRegChange
++)
++{
++      UINT32  dWaitTimeMax    = 0;
++      MCDRV_INIT_INFO sInitInfo;
++
++      McResCtrl_GetInitInfo_AA(&sInitInfo);
++
++      if((bRegChange & MCB_AA_PWM_LI) != 0)
++      {
++              if(sInitInfo.sWaitTime.dLine1Cin > dWaitTimeMax)
++              {
++                      dWaitTimeMax    = sInitInfo.sWaitTime.dLine1Cin;
++              }
++      }
++      if((bRegChange & MCB_AA_PWM_MB1) != 0 || (bRegChange & MCB_AA_PWM_MC1) != 0)
++      {
++              if(sInitInfo.sWaitTime.dMic1Cin > dWaitTimeMax)
++              {
++                      dWaitTimeMax    = sInitInfo.sWaitTime.dMic1Cin;
++              }
++      }
++      if((bRegChange & MCB_AA_PWM_MB2) != 0 || (bRegChange & MCB_AA_PWM_MC2) != 0)
++      {
++              if(sInitInfo.sWaitTime.dMic2Cin > dWaitTimeMax)
++              {
++                      dWaitTimeMax    = sInitInfo.sWaitTime.dMic2Cin;
++              }
++      }
++      if((bRegChange & MCB_AA_PWM_MB3) != 0 || (bRegChange & MCB_AA_PWM_MC3) != 0)
++      {
++              if(sInitInfo.sWaitTime.dMic3Cin > dWaitTimeMax)
++              {
++                      dWaitTimeMax    = sInitInfo.sWaitTime.dMic3Cin;
++              }
++      }
++
++      return dWaitTimeMax;
++}
++
++/*******************************/
++
++#define       MCDRV_MAX_WAIT_TIME_AA  (0x0FFFFFFFUL)
++
++static SINT32 init                                    (const MCDRV_INIT_INFO* psInitInfo);
++static SINT32 term                                    (void);
++
++static SINT32 read_reg                                (MCDRV_REG_INFO* psRegInfo);
++static SINT32 write_reg                               (const MCDRV_REG_INFO* psRegInfo);
++
++static SINT32 update_clock                    (const MCDRV_CLOCK_INFO* psClockInfo);
++
++static SINT32 get_path                                (MCDRV_PATH_INFO* psPathInfo);
++static SINT32 set_path                                (const MCDRV_PATH_INFO* psPathInfo);
++
++static SINT32 get_volume                              (MCDRV_VOL_INFO* psVolInfo);
++static SINT32 set_volume                              (const MCDRV_VOL_INFO *psVolInfo);
++
++static SINT32 get_digitalio                   (MCDRV_DIO_INFO* psDioInfo);
++static SINT32 set_digitalio                   (const MCDRV_DIO_INFO* psDioInfo, UINT32 dUpdateInfo);
++
++static SINT32 get_dac                                 (MCDRV_DAC_INFO* psDacInfo);
++static SINT32 set_dac                                 (const MCDRV_DAC_INFO* psDacInfo, UINT32 dUpdateInfo);
++
++static SINT32 get_adc                                 (MCDRV_ADC_INFO* psAdcInfo);
++static SINT32 set_adc                                 (const MCDRV_ADC_INFO* psAdcInfo, UINT32 dUpdateInfo);
++
++static SINT32 get_sp                                  (MCDRV_SP_INFO* psSpInfo);
++static SINT32 set_sp                                  (const MCDRV_SP_INFO* psSpInfo);
++
++static SINT32 get_dng                                 (MCDRV_DNG_INFO* psDngInfo);
++static SINT32 set_dng                                 (const MCDRV_DNG_INFO* psDngInfo, UINT32 dUpdateInfo);
++
++static SINT32 set_ae                                  (const MCDRV_AE_INFO* psAeInfo, UINT32 dUpdateInfo);
++
++static SINT32 get_pdm                                 (MCDRV_PDM_INFO* psPdmInfo);
++static SINT32 set_pdm                                 (const MCDRV_PDM_INFO* psPdmInfo, UINT32 dUpdateInfo);
++
++static SINT32 config_gp                               (const MCDRV_GP_MODE* psGpMode);
++static SINT32 mask_gp                                 (UINT8* pbMask, UINT32 dPadNo);
++static SINT32 getset_gp                               (UINT8* pbGpio, UINT32 dPadNo);
++
++static SINT32 ValidateInitParam               (const MCDRV_INIT_INFO* psInitInfo);
++static SINT32 ValidateClockParam              (const MCDRV_CLOCK_INFO* psClockInfo);
++static SINT32 ValidateReadRegParam    (const MCDRV_REG_INFO* psRegInfo);
++static SINT32 ValidateWriteRegParam   (const MCDRV_REG_INFO* psRegInfo);
++static SINT32 ValidatePathParam               (const MCDRV_PATH_INFO* psPathInfo);
++static SINT32 ValidateDioParam                (const MCDRV_DIO_INFO* psDioInfo, UINT32 dUpdateInfo);
++static SINT32 CheckDIOCommon                  (const MCDRV_DIO_INFO*  psDioInfo, UINT8 bPort);
++static SINT32 CheckDIODIR                             (const MCDRV_DIO_INFO*  psDioInfo, UINT8 bPort, UINT8 bInterface);
++static SINT32 CheckDIODIT                             (const MCDRV_DIO_INFO*  psDioInfo, UINT8 bPort, UINT8 bInterface);
++
++static SINT32 SetVol                                  (UINT32 dUpdate, MCDRV_VOLUPDATE_MODE_AA eMode);
++static        SINT32  PreUpdatePath                   (void);
++
++static UINT8  abHwAdjParam_Thru[60] =
++{
++      0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++      0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
++};
++static UINT8  abHwAdjParam_Rec8[60] =
++{
++      0x10,0x07,0x79,0xEA,0xEB,0xAA,0xE3,0xBE,0xD3,0x9D,
++      0x80,0xF4,0x0F,0x46,0x5C,0xEE,0x26,0x04,0x1C,0x41,
++      0x2C,0x62,0x7F,0x0E,0xF0,0xB2,0x29,0x26,0xEE,0x56,
++      0x10,0x00,0xCD,0x1A,0xC6,0x9C,0xE2,0x35,0xC9,0x28,
++      0x8C,0x62,0x0F,0x74,0xD1,0x4A,0x2F,0x16,0x1D,0xCA,
++      0x36,0xD7,0x73,0xA0,0xF0,0x8A,0x61,0x9B,0x0A,0x50
++};
++static UINT8  abHwAdjParam_Rec44[60] =
++{
++      0x10,0x83,0x6A,0x3F,0x68,0x46,0x19,0x89,0xC7,0xB0,
++      0x55,0x42,0x0C,0xFF,0x7A,0xAB,0x42,0x3A,0xE6,0x76,
++      0x38,0x4F,0xAA,0xC0,0xF2,0x7D,0x1B,0x15,0x55,0x82,
++      0x10,0x69,0xF3,0x99,0x9D,0x9E,0x08,0x63,0x05,0xAA,
++      0x11,0xB8,0xFB,0x72,0x65,0x70,0x71,0x56,0xF7,0x7F,
++      0x4C,0x6D,0x22,0xCA,0x04,0x41,0x54,0xDE,0xBC,0x90
++};
++static UINT8  abHwAdjParam_Rec48[60] =
++{
++      0x10,0x58,0xEB,0x76,0xA5,0x22,0x19,0x40,0x9A,0xF9,
++      0x6A,0x26,0x0C,0xCF,0xC3,0x76,0x0C,0x38,0xE6,0xBF,
++      0x65,0x06,0x95,0xDC,0xF2,0xD7,0x51,0x13,0x4E,0xA6,
++      0x10,0x46,0x7F,0x35,0x83,0x86,0x08,0x50,0xE8,0x01,
++      0xBD,0x14,0xFB,0x7C,0x3B,0x31,0x2A,0xD4,0xF7,0x9B,
++      0x3F,0xDC,0xC7,0xC8,0x04,0x51,0x1D,0xBA,0xCC,0xCC
++};
++static UINT8  abHwAdjParam_Play8[60] =
++{
++      0x10,0x17,0xAE,0x9C,0x5E,0x76,0xE4,0x96,0x5C,0x5C,
++      0xE7,0x7E,0x0F,0x53,0x7E,0x85,0xBC,0xD0,0x1B,0x69,
++      0xA3,0xA3,0x18,0x84,0xF0,0x94,0xD2,0xDD,0xE4,0xBC,
++      0x10,0x11,0x1E,0x9A,0xB6,0xCE,0xE4,0x2A,0x1A,0xE5,
++      0x81,0x80,0x0F,0x62,0xDA,0x03,0x5A,0xB4,0x1B,0xD5,
++      0xE5,0x1A,0x7E,0x82,0xF0,0x8C,0x07,0x61,0xEE,0x80
++};
++static UINT8  abHwAdjParam_Play44[60] =
++{
++      0x10,0x6D,0x19,0x4D,0xE6,0xFA,0x19,0x7A,0xF7,0x6F,
++      0x4E,0x18,0x0D,0x04,0xAD,0x61,0x04,0xD2,0xE6,0x85,
++      0x08,0x90,0xB1,0xEA,0xF2,0x8E,0x39,0x51,0x14,0x36,
++      0x10,0xA7,0x40,0x2A,0x76,0x8E,0x0B,0xEA,0x7D,0x17,
++      0x6A,0x44,0xFE,0x5D,0xCE,0x5E,0x8C,0x5A,0xF3,0xE6,
++      0x41,0x04,0x5A,0x44,0x01,0x2A,0x33,0x5B,0x38,0x94
++};
++static UINT8  abHwAdjParam_Play48[60] =
++{
++      0x0F,0x90,0xBD,0x36,0x47,0x08,0x15,0x62,0x68,0x36,
++      0xFC,0x2A,0x09,0x20,0x8F,0xCB,0xCD,0x52,0xEA,0x9D,
++      0x97,0xC9,0x03,0xD8,0xF7,0x4E,0xB2,0xFD,0xEB,0xA8,
++      0x11,0xB9,0x89,0xB8,0x89,0x34,0x10,0x0F,0xDD,0x08,
++      0xCB,0x38,0x03,0xA3,0x87,0xD1,0x51,0x14,0xEF,0x0F,
++      0x12,0xEC,0x91,0xA2,0xFB,0x83,0xFE,0x80,0xC8,0xE2
++};
++
++/****************************************************************************
++ *    init
++ *
++ *    Description:
++ *                    Initialize.
++ *    Arguments:
++ *                    psInitInfo      initialize information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  init
++(
++      const MCDRV_INIT_INFO   *psInitInfo
++)
++{
++      SINT32  sdRet;
++      UINT8   bReg;
++
++      if(NULL == psInitInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT_AA != McResCtrl_GetState_AA())
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McSrv_SystemInit();
++      McSrv_Lock();
++
++      bReg    = McSrv_ReadI2C(McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG), (UINT32)MCI_AA_HW_ID);
++      sdRet   = McResCtrl_SetHwId_AA(bReg);
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              sdRet   = ValidateInitParam(psInitInfo);
++      }
++
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              McResCtrl_Init_AA(psInitInfo);
++              sdRet   = McDevIf_AllocPacketBuf_AA();
++      }
++
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              sdRet   = McPacket_AddInit_AA(psInitInfo);
++      }
++
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              sdRet   = McDevIf_ExecutePacket_AA();
++      }
++
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              McResCtrl_UpdateState_AA(eMCDRV_STATE_READY_AA);
++      }
++      else
++      {
++              McDevIf_ReleasePacketBuf_AA();
++      }
++
++      McSrv_Unlock();
++
++      if(sdRet != MCDRV_SUCCESS)
++      {
++              McSrv_SystemTerm();
++      }
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    term
++ *
++ *    Description:
++ *                    Terminate.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  term
++(
++      void
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bCh, bSrcIdx;
++      UINT8   abOnOff[SOURCE_BLOCK_NUM];
++      MCDRV_PATH_INFO         sPathInfo;
++      MCDRV_POWER_INFO_AA     sPowerInfo;
++      MCDRV_POWER_UPDATE_AA   sPowerUpdate;
++
++      if(eMCDRV_STATE_READY_AA != McResCtrl_GetState_AA())
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McSrv_Lock();
++
++      abOnOff[0]      = (MCDRV_SRC0_MIC1_OFF|MCDRV_SRC0_MIC2_OFF|MCDRV_SRC0_MIC3_OFF);
++      abOnOff[1]      = (MCDRV_SRC1_LINE1_L_OFF|MCDRV_SRC1_LINE1_R_OFF|MCDRV_SRC1_LINE1_M_OFF);
++      abOnOff[2]      = (MCDRV_SRC2_LINE2_L_OFF|MCDRV_SRC2_LINE2_R_OFF|MCDRV_SRC2_LINE2_M_OFF);
++      abOnOff[3]      = (MCDRV_SRC3_DIR0_OFF|MCDRV_SRC3_DIR1_OFF|MCDRV_SRC3_DIR2_OFF|MCDRV_SRC3_DIR2_DIRECT_OFF);
++      abOnOff[4]      = (MCDRV_SRC4_DTMF_OFF|MCDRV_SRC4_PDM_OFF|MCDRV_SRC4_ADC0_OFF|MCDRV_SRC4_ADC1_OFF);
++      abOnOff[5]      = (MCDRV_SRC5_DAC_L_OFF|MCDRV_SRC5_DAC_R_OFF|MCDRV_SRC5_DAC_M_OFF);
++      abOnOff[6]      = (MCDRV_SRC6_MIX_OFF|MCDRV_SRC6_AE_OFF|MCDRV_SRC6_CDSP_OFF|MCDRV_SRC6_CDSP_DIRECT_OFF);
++
++      for(bSrcIdx = 0; bSrcIdx < SOURCE_BLOCK_NUM; bSrcIdx++)
++      {
++              for(bCh = 0; bCh < HP_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asHpOut[bCh].abSrcOnOff[bSrcIdx]      = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < SP_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asSpOut[bCh].abSrcOnOff[bSrcIdx]      = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < RC_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asRcOut[bCh].abSrcOnOff[bSrcIdx]      = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < LOUT1_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asLout1[bCh].abSrcOnOff[bSrcIdx]      = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < LOUT2_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asLout2[bCh].abSrcOnOff[bSrcIdx]      = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < PEAK_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asPeak[bCh].abSrcOnOff[bSrcIdx]       = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < DIT0_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asDit0[bCh].abSrcOnOff[bSrcIdx]       = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < DIT1_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asDit1[bCh].abSrcOnOff[bSrcIdx]       = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < DIT2_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asDit2[bCh].abSrcOnOff[bSrcIdx]       = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < DAC_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asDac[bCh].abSrcOnOff[bSrcIdx]        = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < AE_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asAe[bCh].abSrcOnOff[bSrcIdx]         = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < CDSP_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asCdsp[bCh].abSrcOnOff[bSrcIdx]       = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < ADC0_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asAdc0[bCh].abSrcOnOff[bSrcIdx]       = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < ADC1_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asAdc1[bCh].abSrcOnOff[bSrcIdx]       = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < MIX_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asMix[bCh].abSrcOnOff[bSrcIdx]        = abOnOff[bSrcIdx];
++              }
++              for(bCh = 0; bCh < BIAS_PATH_CHANNELS; bCh++)
++              {
++                      sPathInfo.asBias[bCh].abSrcOnOff[bSrcIdx]       = abOnOff[bSrcIdx];
++              }
++      }
++      sdRet   = set_path(&sPathInfo);
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              sPowerInfo.dDigital                     = (MCDRV_POWINFO_DIGITAL_DP0_AA
++                                                                        |MCDRV_POWINFO_DIGITAL_DP1_AA
++                                                                        |MCDRV_POWINFO_DIGITAL_DP2_AA
++                                                                        |MCDRV_POWINFO_DIGITAL_DPB_AA
++                                                                        |MCDRV_POWINFO_DIGITAL_DPDI0_AA
++                                                                        |MCDRV_POWINFO_DIGITAL_DPDI1_AA
++                                                                        |MCDRV_POWINFO_DIGITAL_DPDI2_AA
++                                                                        |MCDRV_POWINFO_DIGITAL_DPPDM_AA
++                                                                        |MCDRV_POWINFO_DIGITAL_DPBDSP_AA
++                                                                        |MCDRV_POWINFO_DIGITAL_DPADIF_AA
++                                                                        |MCDRV_POWINFO_DIGITAL_PLLRST0_AA);
++              sPowerInfo.abAnalog[0]          =
++              sPowerInfo.abAnalog[1]          =
++              sPowerInfo.abAnalog[2]          =
++              sPowerInfo.abAnalog[3]          =
++              sPowerInfo.abAnalog[4]          = (UINT8)0xFF;
++              sPowerUpdate.dDigital           = MCDRV_POWUPDATE_DIGITAL_ALL_AA;
++              sPowerUpdate.abAnalog[0]        = (UINT8)MCDRV_POWUPDATE_ANALOG0_ALL_AA;
++              sPowerUpdate.abAnalog[1]        = (UINT8)MCDRV_POWUPDATE_ANALOG1_ALL_AA;
++              sPowerUpdate.abAnalog[2]        = (UINT8)MCDRV_POWUPDATE_ANALOG2_ALL_AA;
++              sPowerUpdate.abAnalog[3]        = (UINT8)MCDRV_POWUPDATE_ANALOG3_ALL_AA;
++              sPowerUpdate.abAnalog[4]        = (UINT8)MCDRV_POWUPDATE_ANALOG4_ALL_AA;
++              sdRet   = McPacket_AddPowerDown_AA(&sPowerInfo, &sPowerUpdate);
++      }
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              sdRet   = McDevIf_ExecutePacket_AA();
++      }
++
++      McDevIf_ReleasePacketBuf_AA();
++
++      McResCtrl_UpdateState_AA(eMCDRV_STATE_NOTINIT_AA);
++
++      McSrv_Unlock();
++
++      McSrv_SystemTerm();
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    read_reg
++ *
++ *    Description:
++ *                    read register.
++ *    Arguments:
++ *                    psRegInfo       register information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_STATE
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++static        SINT32  read_reg
++(
++      MCDRV_REG_INFO* psRegInfo
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bSlaveAddr;
++      UINT8   bAddr;
++      UINT8   abData[2];
++      MCDRV_POWER_INFO_AA     sPowerInfo;
++      MCDRV_POWER_INFO_AA     sCurPowerInfo;
++      MCDRV_POWER_UPDATE_AA   sPowerUpdate;
++
++      if(NULL == psRegInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT_AA == McResCtrl_GetState_AA())
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      sdRet   = ValidateReadRegParam(psRegInfo);
++      if(sdRet != MCDRV_SUCCESS)
++      {
++              return sdRet;
++      }
++
++      /*      get current power info  */
++      McResCtrl_GetCurPowerInfo_AA(&sCurPowerInfo);
++
++      /*      power up        */
++      McResCtrl_GetPowerInfoRegAccess_AA(psRegInfo, &sPowerInfo);
++      sPowerUpdate.dDigital           = MCDRV_POWUPDATE_DIGITAL_ALL_AA;
++      sPowerUpdate.abAnalog[0]        = (UINT8)MCDRV_POWUPDATE_ANALOG0_ALL_AA;
++      sPowerUpdate.abAnalog[1]        = (UINT8)MCDRV_POWUPDATE_ANALOG1_ALL_AA;
++      sPowerUpdate.abAnalog[2]        = (UINT8)MCDRV_POWUPDATE_ANALOG2_ALL_AA;
++      sPowerUpdate.abAnalog[3]        = (UINT8)MCDRV_POWUPDATE_ANALOG3_ALL_AA;
++      sPowerUpdate.abAnalog[4]        = (UINT8)MCDRV_POWUPDATE_ANALOG4_ALL_AA;
++      sdRet   = McPacket_AddPowerUp_AA(&sPowerInfo, &sPowerUpdate);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      sdRet   = McDevIf_ExecutePacket_AA();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      bAddr   = psRegInfo->bAddress;
++
++      if(psRegInfo->bRegType == MCDRV_REGTYPE_A)
++      {
++              bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++      }
++      else
++      {
++              switch(psRegInfo->bRegType)
++              {
++              case    MCDRV_REGTYPE_B_BASE:
++                      bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++                      abData[0]       = MCI_AA_BASE_ADR<<1;
++                      abData[1]       = bAddr;
++                      McSrv_WriteI2C(bSlaveAddr, abData, 2);
++                      bAddr   = MCI_AA_BASE_WINDOW;
++                      break;
++
++              case    MCDRV_REGTYPE_B_MIXER:
++                      bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++                      abData[0]       = MCI_AA_MIX_ADR<<1;
++                      abData[1]       = bAddr;
++                      McSrv_WriteI2C(bSlaveAddr, abData, 2);
++                      bAddr   = MCI_AA_MIX_WINDOW;
++                      break;
++
++              case    MCDRV_REGTYPE_B_AE:
++                      bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++                      abData[0]       = MCI_AA_AE_ADR<<1;
++                      abData[1]       = bAddr;
++                      McSrv_WriteI2C(bSlaveAddr, abData, 2);
++                      bAddr   = MCI_AA_AE_WINDOW;
++                      break;
++
++              case    MCDRV_REGTYPE_B_CDSP:
++                      bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++                      abData[0]       = MCI_AA_CDSP_ADR<<1;
++                      abData[1]       = bAddr;
++                      McSrv_WriteI2C(bSlaveAddr, abData, 2);
++                      bAddr   = MCI_AA_CDSP_WINDOW;
++                      break;
++
++              case    MCDRV_REGTYPE_B_CODEC:
++                      bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++                      abData[0]       = MCI_AA_CD_ADR<<1;
++                      abData[1]       = bAddr;
++                      McSrv_WriteI2C(bSlaveAddr, abData, 2);
++                      bAddr   = MCI_AA_CD_WINDOW;
++                      break;
++
++              case    MCDRV_REGTYPE_B_ANALOG:
++                      bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_ANA);
++                      abData[0]       = MCI_AA_ANA_ADR<<1;
++                      abData[1]       = bAddr;
++                      McSrv_WriteI2C(bSlaveAddr, abData, 2);
++                      bAddr   = MCI_AA_ANA_WINDOW;
++                      break;
++
++              default:
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++
++      /*      read register   */
++      psRegInfo->bData        = McSrv_ReadI2C(bSlaveAddr, bAddr);
++
++      /*      restore power   */
++      sdRet   = McPacket_AddPowerDown_AA(&sCurPowerInfo, &sPowerUpdate);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      return McDevIf_ExecutePacket_AA();
++}
++
++/****************************************************************************
++ *    write_reg
++ *
++ *    Description:
++ *                    Write register.
++ *    Arguments:
++ *                    psWR    register information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_STATE
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *
++ ****************************************************************************/
++static        SINT32  write_reg
++(
++      const MCDRV_REG_INFO*   psRegInfo
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      MCDRV_POWER_INFO_AA     sPowerInfo;
++      MCDRV_POWER_INFO_AA     sCurPowerInfo;
++      MCDRV_POWER_UPDATE_AA   sPowerUpdate;
++
++      if(NULL == psRegInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT_AA == McResCtrl_GetState_AA())
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      sdRet   = ValidateWriteRegParam(psRegInfo);
++      if(sdRet != MCDRV_SUCCESS)
++      {
++              return sdRet;
++      }
++
++      /*      get current power info  */
++      McResCtrl_GetCurPowerInfo_AA(&sCurPowerInfo);
++
++      /*      power up        */
++      McResCtrl_GetPowerInfoRegAccess_AA(psRegInfo, &sPowerInfo);
++      sPowerUpdate.dDigital           = MCDRV_POWUPDATE_DIGITAL_ALL_AA;
++      sPowerUpdate.abAnalog[0]        = (UINT8)MCDRV_POWUPDATE_ANALOG0_ALL_AA;
++      sPowerUpdate.abAnalog[1]        = (UINT8)MCDRV_POWUPDATE_ANALOG1_ALL_AA;
++      sPowerUpdate.abAnalog[2]        = (UINT8)MCDRV_POWUPDATE_ANALOG2_ALL_AA;
++      sPowerUpdate.abAnalog[3]        = (UINT8)MCDRV_POWUPDATE_ANALOG3_ALL_AA;
++      sPowerUpdate.abAnalog[4]        = (UINT8)MCDRV_POWUPDATE_ANALOG4_ALL_AA;
++      sdRet   = McPacket_AddPowerUp_AA(&sPowerInfo, &sPowerUpdate);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      switch(psRegInfo->bRegType)
++      {
++      case    MCDRV_REGTYPE_A:
++              McDevIf_AddPacket_AA((MCDRV_PACKET_TYPE_FORCE_WRITE_AA | MCDRV_PACKET_REGTYPE_A_AA | psRegInfo->bAddress), psRegInfo->bData);
++              break;
++
++      case    MCDRV_REGTYPE_B_BASE:
++              McDevIf_AddPacket_AA((MCDRV_PACKET_TYPE_FORCE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_BASE_AA | psRegInfo->bAddress), psRegInfo->bData);
++              break;
++
++      case    MCDRV_REGTYPE_B_MIXER:
++              McDevIf_AddPacket_AA((MCDRV_PACKET_TYPE_FORCE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | psRegInfo->bAddress), psRegInfo->bData);
++              break;
++
++      case    MCDRV_REGTYPE_B_AE:
++              McDevIf_AddPacket_AA((MCDRV_PACKET_TYPE_FORCE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_AE_AA | psRegInfo->bAddress), psRegInfo->bData);
++              break;
++
++      case    MCDRV_REGTYPE_B_CDSP:
++              McDevIf_AddPacket_AA((MCDRV_PACKET_TYPE_FORCE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_CDSP_AA | psRegInfo->bAddress), psRegInfo->bData);
++              break;
++
++      case    MCDRV_REGTYPE_B_CODEC:
++              McDevIf_AddPacket_AA((MCDRV_PACKET_TYPE_FORCE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_CODEC_AA | psRegInfo->bAddress), psRegInfo->bData);
++              break;
++
++      case    MCDRV_REGTYPE_B_ANALOG:
++              McDevIf_AddPacket_AA((MCDRV_PACKET_TYPE_FORCE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_ANA_AA | psRegInfo->bAddress), psRegInfo->bData);
++              break;
++
++      default:
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      sdRet   = McDevIf_ExecutePacket_AA();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      /*      restore power   */
++      if(psRegInfo->bRegType == MCDRV_REGTYPE_B_BASE)
++      {
++              if(psRegInfo->bAddress == MCI_AA_PWM_DIGITAL)
++              {
++                      if((psRegInfo->bData & MCB_AA_PWM_DP0) == 0)
++                      {
++                              sCurPowerInfo.dDigital &= ~MCDRV_POWINFO_DIGITAL_DP0_AA;
++                      }
++                      if((psRegInfo->bData & MCB_AA_PWM_DP1) == 0)
++                      {
++                              sCurPowerInfo.dDigital &= ~MCDRV_POWINFO_DIGITAL_DP1_AA;
++                      }
++                      if((psRegInfo->bData & MCB_AA_PWM_DP2) == 0)
++                      {
++                              sCurPowerInfo.dDigital &= ~MCDRV_POWINFO_DIGITAL_DP2_AA;
++                      }
++              }
++              else if(psRegInfo->bAddress == MCI_AA_PWM_DIGITAL_1)
++              {
++                      if((psRegInfo->bData & MCB_AA_PWM_DPB) == 0)
++                      {
++                              sCurPowerInfo.dDigital &= ~MCDRV_POWINFO_DIGITAL_DPB_AA;
++                      }
++                      if((psRegInfo->bData & MCB_AA_PWM_DPDI0) == 0)
++                      {
++                              sCurPowerInfo.dDigital &= ~MCDRV_POWINFO_DIGITAL_DPDI0_AA;
++                      }
++                      if((psRegInfo->bData & MCB_AA_PWM_DPDI1) == 0)
++                      {
++                              sCurPowerInfo.dDigital &= ~MCDRV_POWINFO_DIGITAL_DPDI1_AA;
++                      }
++                      if((psRegInfo->bData & MCB_AA_PWM_DPDI2) == 0)
++                      {
++                              sCurPowerInfo.dDigital &= ~MCDRV_POWINFO_DIGITAL_DPDI2_AA;
++                      }
++                      if((psRegInfo->bData & MCB_AA_PWM_DPPDM) == 0)
++                      {
++                              sCurPowerInfo.dDigital &= ~MCDRV_POWINFO_DIGITAL_DPPDM_AA;
++                      }
++              }
++              else if(psRegInfo->bAddress == MCI_AA_PWM_DIGITAL_BDSP)
++              {
++                      if((psRegInfo->bData & MCB_AA_PWM_DPBDSP) == 0)
++                      {
++                              sCurPowerInfo.dDigital &= ~MCDRV_POWINFO_DIGITAL_DPBDSP_AA;
++                      }
++              }
++              else if(psRegInfo->bAddress == MCI_AA_PLL_RST)
++              {
++                      if((psRegInfo->bData & MCB_AA_PLLRST0) == 0)
++                      {
++                              sCurPowerInfo.dDigital &= ~MCDRV_POWINFO_DIGITAL_PLLRST0_AA;
++                      }
++              }
++      }
++      else if(psRegInfo->bRegType == MCDRV_REGTYPE_B_CODEC)
++      {
++              if(psRegInfo->bAddress == MCI_AA_DPADIF)
++              {
++                      if((psRegInfo->bData & MCB_AA_DPADIF) == 0)
++                      {
++                              sCurPowerInfo.dDigital &= ~MCDRV_POWINFO_DIGITAL_DPADIF_AA;
++                      }
++              }
++      }
++      else if(psRegInfo->bRegType == MCDRV_REGTYPE_B_ANALOG)
++      {
++              if(psRegInfo->bAddress == MCI_AA_PWM_ANALOG_0)
++              {
++                      sCurPowerInfo.abAnalog[0]       = psRegInfo->bData;
++              }
++              else if(psRegInfo->bAddress == MCI_AA_PWM_ANALOG_1)
++              {
++                      sCurPowerInfo.abAnalog[1]       = psRegInfo->bData;
++              }
++              else if(psRegInfo->bAddress == MCI_AA_PWM_ANALOG_2)
++              {
++                      sCurPowerInfo.abAnalog[2]       = psRegInfo->bData;
++              }
++              else if(psRegInfo->bAddress == MCI_AA_PWM_ANALOG_3)
++              {
++                      sCurPowerInfo.abAnalog[3]       = psRegInfo->bData;
++              }
++              else if(psRegInfo->bAddress == MCI_AA_PWM_ANALOG_4)
++              {
++                      sCurPowerInfo.abAnalog[4]       = psRegInfo->bData;
++              }
++      }
++
++      sdRet   = McPacket_AddPowerDown_AA(&sCurPowerInfo, &sPowerUpdate);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      return McDevIf_ExecutePacket_AA();
++}
++
++/****************************************************************************
++ *    update_clock
++ *
++ *    Description:
++ *                    Update clock info.
++ *    Arguments:
++ *                    psClockInfo     clock info
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  update_clock
++(
++      const MCDRV_CLOCK_INFO* psClockInfo
++)
++{
++      SINT32                  sdRet   = MCDRV_SUCCESS;
++      MCDRV_STATE_AA          eState  = McResCtrl_GetState_AA();
++      MCDRV_INIT_INFO sInitInfo;
++
++      if(NULL == psClockInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT_AA == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_GetInitInfo_AA(&sInitInfo);
++      if((sInitInfo.bPowerMode & MCDRV_POWMODE_CLKON) != 0)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      sdRet   = ValidateClockParam(psClockInfo);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      McResCtrl_SetClockInfo_AA(psClockInfo);
++      return sdRet;
++}
++
++/****************************************************************************
++ *    get_path
++ *
++ *    Description:
++ *                    Get current path setting.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  get_path
++(
++      MCDRV_PATH_INFO*        psPathInfo
++)
++{
++      if(NULL == psPathInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT_AA == McResCtrl_GetState_AA())
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_GetPathInfoVirtual_AA(psPathInfo);
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    set_path
++ *
++ *    Description:
++ *                    Set path.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  set_path
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++      SINT32                  sdRet   = MCDRV_SUCCESS;
++      UINT32                  dXFadeParam     = 0;
++      MCDRV_STATE_AA          eState  = McResCtrl_GetState_AA();
++      MCDRV_POWER_INFO_AA     sPowerInfo;
++      MCDRV_POWER_UPDATE_AA   sPowerUpdate;
++      MCDRV_HWADJ                     eHwAdj;
++      UINT8                           *pbHwAdjParam;
++      UINT8                           bReg;
++      UINT8                           i;
++
++      if(NULL == psPathInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT_AA == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      sdRet   = ValidatePathParam(psPathInfo);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      McResCtrl_SetPathInfo_AA(psPathInfo);
++
++      /*      unused analog out volume mute   */
++      sdRet   = SetVol(MCDRV_VOLUPDATE_ANAOUT_ALL_AA, eMCDRV_VOLUPDATE_MUTE_AA);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      /*      DAC/DIT* mute   */
++      sdRet   = PreUpdatePath();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      /*      unused volume mute      */
++      sdRet   = SetVol(MCDRV_VOLUPDATE_ALL_AA&~MCDRV_VOLUPDATE_ANAOUT_ALL_AA, eMCDRV_VOLUPDATE_MUTE_AA);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      /*      stop unused path        */
++      sdRet   = McPacket_AddStop_AA();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      sdRet   = McDevIf_ExecutePacket_AA();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      if(McDevProf_IsValid(eMCDRV_FUNC_HWADJ) == 1)
++      {
++              eHwAdj = McResCtrl_ConfigHwAdj_AA();
++
++              if(eHwAdj != eMCDRV_HWADJ_NOCHANGE)
++              {
++                      switch(eHwAdj)
++                      {
++                      case    eMCDRV_HWADJ_REC8:
++                              pbHwAdjParam = abHwAdjParam_Rec8;
++                              break;
++                      case    eMCDRV_HWADJ_REC44:
++                              pbHwAdjParam = abHwAdjParam_Rec44;
++                              break;
++                      case    eMCDRV_HWADJ_REC48:
++                              pbHwAdjParam = abHwAdjParam_Rec48;
++                              break;
++                      case    eMCDRV_HWADJ_PLAY8:
++                              pbHwAdjParam = abHwAdjParam_Play8;
++                              break;
++                      case    eMCDRV_HWADJ_PLAY44:
++                              pbHwAdjParam = abHwAdjParam_Play44;
++                              break;
++                      case    eMCDRV_HWADJ_PLAY48:
++                              pbHwAdjParam = abHwAdjParam_Play48;
++                              break;
++                      default:
++                              pbHwAdjParam = abHwAdjParam_Thru;
++                              break;
++                      }
++
++                      dXFadeParam     = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DAC_INS);
++                      dXFadeParam     <<= 8;
++                      dXFadeParam     |= McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_INS);
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)MCI_AA_DAC_INS, 0);
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | (UINT32)MCI_AA_INS, 0);
++                      sdRet   = McDevIf_ExecutePacket_AA();
++                      if(sdRet != MCDRV_SUCCESS)
++                      {
++                              return sdRet;
++                      }
++
++                      /*      wait xfade complete     */
++                      if(dXFadeParam != (UINT32)0)
++                      {
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_EVTWAIT_AA | MCDRV_EVT_INSFLG_AA | dXFadeParam, 0);
++                              bReg    = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_A_AA, MCI_AA_BDSP_ST);
++                              bReg    &= (UINT8)~MCB_AA_EQ3ON;
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_A_AA | (UINT32)MCI_AA_BDSP_ST, bReg);
++                      }
++
++                      for(i = 0; i < 60; i++)
++                      {
++                              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_FORCE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_AE_AA | (UINT32)(MCI_AA_BAND6H_CEQ0+i), pbHwAdjParam[i]);
++                      }
++
++                      sdRet   = McDevIf_ExecutePacket_AA();
++                      if(MCDRV_SUCCESS != sdRet)
++                      {
++                              return sdRet;
++                      }
++              }
++      }
++
++      McResCtrl_GetPowerInfo_AA(&sPowerInfo);
++
++      /*      used path power up      */
++      sPowerUpdate.dDigital           = MCDRV_POWUPDATE_DIGITAL_ALL_AA;
++      sPowerUpdate.abAnalog[0]        = (UINT8)MCDRV_POWUPDATE_ANALOG0_ALL_AA;
++      sPowerUpdate.abAnalog[1]        = (UINT8)MCDRV_POWUPDATE_ANALOG1_ALL_AA;
++      sPowerUpdate.abAnalog[2]        = (UINT8)MCDRV_POWUPDATE_ANALOG2_ALL_AA;
++      sPowerUpdate.abAnalog[3]        = (UINT8)MCDRV_POWUPDATE_ANALOG3_ALL_AA;
++      sPowerUpdate.abAnalog[4]        = (UINT8)MCDRV_POWUPDATE_ANALOG4_ALL_AA;
++      sdRet   = McPacket_AddPowerUp_AA(&sPowerInfo, &sPowerUpdate);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      sdRet   = McDevIf_ExecutePacket_AA();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      /*      set digital mixer       */
++      sdRet   = McPacket_AddPathSet_AA();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      sdRet   = McDevIf_ExecutePacket_AA();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      /*      set analog mixer        */
++      sdRet   = McPacket_AddMixSet_AA();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      sdRet   = McDevIf_ExecutePacket_AA();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      /*      unused path power down  */
++      sPowerUpdate.dDigital           = MCDRV_POWUPDATE_DIGITAL_ALL_AA;
++      if(McDevProf_IsValid(eMCDRV_FUNC_HWADJ) == 1)
++      {
++              sPowerUpdate.abAnalog[0]        = 0;
++              sPowerUpdate.abAnalog[1]        = 0xCF;
++      }
++      else
++      {
++              sPowerUpdate.abAnalog[0]        = (UINT8)MCDRV_POWUPDATE_ANALOG0_ALL_AA;
++              sPowerUpdate.abAnalog[1]        = (UINT8)MCDRV_POWUPDATE_ANALOG1_ALL_AA;
++      }
++      sPowerUpdate.abAnalog[2]        = (UINT8)MCDRV_POWUPDATE_ANALOG2_ALL_AA;
++      sPowerUpdate.abAnalog[3]        = (UINT8)MCDRV_POWUPDATE_ANALOG3_ALL_AA;
++      sPowerUpdate.abAnalog[4]        = (UINT8)MCDRV_POWUPDATE_ANALOG4_ALL_AA;
++      sdRet   = McPacket_AddPowerDown_AA(&sPowerInfo, &sPowerUpdate);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      sdRet   = McDevIf_ExecutePacket_AA();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      /*      start   */
++      sdRet   = McPacket_AddStart_AA();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      sdRet   = McDevIf_ExecutePacket_AA();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      /*      set volume      */
++      sdRet   = SetVol(MCDRV_VOLUPDATE_ALL_AA&~MCDRV_VOLUPDATE_ANAOUT_ALL_AA, eMCDRV_VOLUPDATE_ALL_AA);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      return SetVol(MCDRV_VOLUPDATE_ANAOUT_ALL_AA, eMCDRV_VOLUPDATE_ALL_AA);
++}
++
++/****************************************************************************
++ *    get_volume
++ *
++ *    Description:
++ *                    Get current volume setting.
++ *    Arguments:
++ *                    psVolInfo       volume information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++static        SINT32  get_volume
++(
++      MCDRV_VOL_INFO* psVolInfo
++)
++{
++      if(NULL == psVolInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT_AA == McResCtrl_GetState_AA())
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_GetVolInfo_AA(psVolInfo);
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    set_volume
++ *
++ *    Description:
++ *                    Set volume.
++ *    Arguments:
++ *                    psVolInfo       volume update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++static        SINT32  set_volume
++(
++      const MCDRV_VOL_INFO*   psVolInfo
++)
++{
++      MCDRV_STATE_AA  eState  = McResCtrl_GetState_AA();
++
++      if(NULL == psVolInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT_AA == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_SetVolInfo_AA(psVolInfo);
++
++      return SetVol(MCDRV_VOLUPDATE_ALL_AA, eMCDRV_VOLUPDATE_ALL_AA);
++}
++
++/****************************************************************************
++ *    get_digitalio
++ *
++ *    Description:
++ *                    Get current digital IO setting.
++ *    Arguments:
++ *                    psDioInfo       digital IO information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  get_digitalio
++(
++      MCDRV_DIO_INFO* psDioInfo
++)
++{
++      if(NULL == psDioInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT_AA == McResCtrl_GetState_AA())
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_GetDioInfo_AA(psDioInfo);
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    set_digitalio
++ *
++ *    Description:
++ *                    Update digital IO configuration.
++ *    Arguments:
++ *                    psDioInfo       digital IO configuration
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  set_digitalio
++(
++      const MCDRV_DIO_INFO*   psDioInfo,
++      UINT32                                  dUpdateInfo
++)
++{
++      SINT32          sdRet   = MCDRV_SUCCESS;
++      MCDRV_STATE_AA  eState  = McResCtrl_GetState_AA();
++
++      if(NULL == psDioInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT_AA == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      sdRet   = ValidateDioParam(psDioInfo, dUpdateInfo);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      McResCtrl_SetDioInfo_AA(psDioInfo, dUpdateInfo);
++
++      sdRet   = McPacket_AddDigitalIO_AA(dUpdateInfo);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      return McDevIf_ExecutePacket_AA();
++}
++
++/****************************************************************************
++ *    get_dac
++ *
++ *    Description:
++ *                    Get current DAC setting.
++ *    Arguments:
++ *                    psDacInfo       DAC information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  get_dac
++(
++      MCDRV_DAC_INFO* psDacInfo
++)
++{
++      if(NULL == psDacInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT_AA == McResCtrl_GetState_AA())
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_GetDacInfo_AA(psDacInfo);
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    set_dac
++ *
++ *    Description:
++ *                    Update DAC configuration.
++ *    Arguments:
++ *                    psDacInfo       DAC configuration
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  set_dac
++(
++      const MCDRV_DAC_INFO*   psDacInfo,
++      UINT32                                  dUpdateInfo
++)
++{
++      SINT32          sdRet   = MCDRV_SUCCESS;
++      MCDRV_STATE_AA  eState  = McResCtrl_GetState_AA();
++
++      if(NULL == psDacInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT_AA == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_SetDacInfo_AA(psDacInfo, dUpdateInfo);
++
++      sdRet   = McPacket_AddDAC_AA(dUpdateInfo);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      return McDevIf_ExecutePacket_AA();
++}
++
++/****************************************************************************
++ *    get_adc
++ *
++ *    Description:
++ *                    Get current ADC setting.
++ *    Arguments:
++ *                    psAdcInfo       ADC information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  get_adc
++(
++      MCDRV_ADC_INFO* psAdcInfo
++)
++{
++      if(NULL == psAdcInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT_AA == McResCtrl_GetState_AA())
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_GetAdcInfo_AA(psAdcInfo);
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    set_adc
++ *
++ *    Description:
++ *                    Update ADC configuration.
++ *    Arguments:
++ *                    psAdcInfo       ADC configuration
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  set_adc
++(
++      const MCDRV_ADC_INFO*   psAdcInfo,
++      UINT32                                  dUpdateInfo
++)
++{
++      SINT32          sdRet   = MCDRV_SUCCESS;
++      MCDRV_STATE_AA  eState  = McResCtrl_GetState_AA();
++
++      if(NULL == psAdcInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT_AA == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_SetAdcInfo_AA(psAdcInfo, dUpdateInfo);
++
++      sdRet   = McPacket_AddADC_AA(dUpdateInfo);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      return McDevIf_ExecutePacket_AA();
++}
++
++/****************************************************************************
++ *    get_sp
++ *
++ *    Description:
++ *                    Get current SP setting.
++ *    Arguments:
++ *                    psSpInfo        SP information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  get_sp
++(
++      MCDRV_SP_INFO*  psSpInfo
++)
++{
++      if(NULL == psSpInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT_AA == McResCtrl_GetState_AA())
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_GetSpInfo_AA(psSpInfo);
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    set_sp
++ *
++ *    Description:
++ *                    Update SP configuration.
++ *    Arguments:
++ *                    psSpInfo        SP configuration
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  set_sp
++(
++      const MCDRV_SP_INFO*    psSpInfo
++)
++{
++      SINT32          sdRet   = MCDRV_SUCCESS;
++      MCDRV_STATE_AA  eState  = McResCtrl_GetState_AA();
++
++      if(NULL == psSpInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT_AA == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_SetSpInfo_AA(psSpInfo);
++
++      sdRet   = McPacket_AddSP_AA();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      return McDevIf_ExecutePacket_AA();
++}
++
++/****************************************************************************
++ *    get_dng
++ *
++ *    Description:
++ *                    Get current Digital Noise Gate setting.
++ *    Arguments:
++ *                    psDngInfo       DNG information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  get_dng
++(
++      MCDRV_DNG_INFO* psDngInfo
++)
++{
++      if(NULL == psDngInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT_AA == McResCtrl_GetState_AA())
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_GetDngInfo_AA(psDngInfo);
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    set_dng
++ *
++ *    Description:
++ *                    Update Digital Noise Gate configuration.
++ *    Arguments:
++ *                    psDngInfo       DNG configuration
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  set_dng
++(
++      const MCDRV_DNG_INFO*   psDngInfo,
++      UINT32                                  dUpdateInfo
++)
++{
++      SINT32          sdRet   = MCDRV_SUCCESS;
++      MCDRV_STATE_AA  eState  = McResCtrl_GetState_AA();
++
++      if(NULL == psDngInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT_AA == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_SetDngInfo_AA(psDngInfo, dUpdateInfo);
++
++      sdRet   = McPacket_AddDNG_AA(dUpdateInfo);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      return McDevIf_ExecutePacket_AA();
++}
++
++/****************************************************************************
++ *    set_ae
++ *
++ *    Description:
++ *                    Update Audio Engine configuration.
++ *    Arguments:
++ *                    psAeInfo        AE configuration
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  set_ae
++(
++      const MCDRV_AE_INFO*    psAeInfo,
++      UINT32                                  dUpdateInfo
++)
++{
++      SINT32          sdRet   = MCDRV_SUCCESS;
++      MCDRV_STATE_AA  eState  = McResCtrl_GetState_AA();
++      MCDRV_PATH_INFO sPathInfo;
++
++      if(NULL == psAeInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT_AA == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_SetAeInfo_AA(psAeInfo, dUpdateInfo);
++
++      sdRet   = McPacket_AddAE_AA(dUpdateInfo);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      sdRet   = McDevIf_ExecutePacket_AA();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++
++      McResCtrl_GetPathInfoVirtual_AA(&sPathInfo);
++      return  set_path(&sPathInfo);
++}
++
++/****************************************************************************
++ *    get_pdm
++ *
++ *    Description:
++ *                    Get current PDM setting.
++ *    Arguments:
++ *                    psPdmInfo       PDM information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  get_pdm
++(
++      MCDRV_PDM_INFO* psPdmInfo
++)
++{
++      if(NULL == psPdmInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT_AA == McResCtrl_GetState_AA())
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_GetPdmInfo_AA(psPdmInfo);
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    set_pdm
++ *
++ *    Description:
++ *                    Update PDM configuration.
++ *    Arguments:
++ *                    psPdmInfo       PDM configuration
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++static        SINT32  set_pdm
++(
++      const MCDRV_PDM_INFO*   psPdmInfo,
++      UINT32                                  dUpdateInfo
++)
++{
++      SINT32          sdRet   = MCDRV_SUCCESS;
++      MCDRV_STATE_AA  eState  = McResCtrl_GetState_AA();
++
++      if(NULL == psPdmInfo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT_AA == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_SetPdmInfo_AA(psPdmInfo, dUpdateInfo);
++
++      sdRet   = McPacket_AddPDM_AA(dUpdateInfo);
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      return McDevIf_ExecutePacket_AA();
++}
++
++/****************************************************************************
++ *    config_gp
++ *
++ *    Description:
++ *                    Set GPIO mode.
++ *    Arguments:
++ *                    psGpMode        GPIO mode information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_STATE
++*
++ ****************************************************************************/
++static        SINT32  config_gp
++(
++      const MCDRV_GP_MODE*    psGpMode
++)
++{
++      SINT32          sdRet   = MCDRV_SUCCESS;
++      MCDRV_STATE_AA  eState  = McResCtrl_GetState_AA();
++
++      if(NULL == psGpMode)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT_AA == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_SetGPMode_AA(psGpMode);
++
++      sdRet   = McPacket_AddGPMode_AA();
++      if(MCDRV_SUCCESS != sdRet)
++      {
++              return sdRet;
++      }
++      return McDevIf_ExecutePacket_AA();
++}
++
++/****************************************************************************
++ *    mask_gp
++ *
++ *    Description:
++ *                    Set GPIO input mask.
++ *    Arguments:
++ *                    pbMask  mask setting
++ *                    dPadNo  PAD number
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_STATE
++ *                    MCDRV_ERROR
++*
++ ****************************************************************************/
++static        SINT32  mask_gp
++(
++      UINT8*  pbMask,
++      UINT32  dPadNo
++)
++{
++      SINT32          sdRet   = MCDRV_SUCCESS;
++      MCDRV_STATE_AA  eState  = McResCtrl_GetState_AA();
++      MCDRV_INIT_INFO sInitInfo;
++      MCDRV_GP_MODE   sGPMode;
++
++      if(NULL == pbMask)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT_AA == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_GetInitInfo_AA(&sInitInfo);
++      McResCtrl_GetGPMode_AA(&sGPMode);
++
++      if(dPadNo == MCDRV_GP_PAD0)
++      {
++              if(sInitInfo.bPad0Func == MCDRV_PAD_GPIO && sGPMode.abGpDdr[dPadNo] == MCDRV_GPDDR_OUT)
++              {
++                      return MCDRV_ERROR;
++              }
++      }
++      else if(dPadNo == MCDRV_GP_PAD1)
++      {
++              if(sInitInfo.bPad1Func == MCDRV_PAD_GPIO && sGPMode.abGpDdr[dPadNo] == MCDRV_GPDDR_OUT)
++              {
++                      return MCDRV_ERROR;
++              }
++      }
++/*
++      else if(dPadNo == MCDRV_GP_PAD2)
++      {
++              if(sInitInfo.bPad2Func == MCDRV_PAD_GPIO && sGPMode.abGpDdr[dPadNo] == MCDRV_GPDDR_OUT)
++              {
++                      return MCDRV_ERROR;
++              }
++      }
++*/
++      McResCtrl_SetGPMask_AA(*pbMask, dPadNo);
++
++      sdRet   = McPacket_AddGPMask_AA(dPadNo);
++      if(sdRet != MCDRV_SUCCESS)
++      {
++              return sdRet;
++      }
++      return McDevIf_ExecutePacket_AA();
++}
++
++/****************************************************************************
++ *    getset_gp
++ *
++ *    Description:
++ *                    Set or get state of GPIO pin.
++ *    Arguments:
++ *                    pbGpio  pin state
++ *                    dPadNo  PAD number
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++*
++ ****************************************************************************/
++static        SINT32  getset_gp
++(
++      UINT8*  pbGpio,
++      UINT32  dPadNo
++)
++{
++      SINT32                  sdRet   = MCDRV_SUCCESS;
++      UINT8                   bSlaveAddr;
++      UINT8                   abData[2];
++      UINT8                   bRegData;
++      MCDRV_STATE_AA          eState  = McResCtrl_GetState_AA();
++      MCDRV_INIT_INFO sInitInfo;
++      MCDRV_GP_MODE   sGPMode;
++
++      if(NULL == pbGpio)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(eMCDRV_STATE_NOTINIT_AA == eState)
++      {
++              return MCDRV_ERROR_STATE;
++      }
++
++      McResCtrl_GetInitInfo_AA(&sInitInfo);
++      McResCtrl_GetGPMode_AA(&sGPMode);
++
++      if((dPadNo == MCDRV_GP_PAD0 && sInitInfo.bPad0Func != MCDRV_PAD_GPIO)
++      || (dPadNo == MCDRV_GP_PAD1 && sInitInfo.bPad1Func != MCDRV_PAD_GPIO)
++      /*|| (dPadNo == MCDRV_GP_PAD2 && sInitInfo.bPad2Func != MCDRV_PAD_GPIO)*/)
++      {
++              return MCDRV_ERROR;
++      }
++
++      if(dPadNo < GPIO_PAD_NUM)
++      {
++              if(sGPMode.abGpDdr[dPadNo] == MCDRV_GPDDR_IN)
++              {
++                      bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++                      abData[0]       = MCI_AA_BASE_ADR<<1;
++                      abData[1]       = MCI_AA_PA_SCU_PA;
++                      McSrv_WriteI2C(bSlaveAddr, abData, 2);
++                      bRegData        = McSrv_ReadI2C(bSlaveAddr, MCI_AA_BASE_WINDOW);
++                      if(dPadNo == MCDRV_GP_PAD0)
++                      {
++                              *pbGpio = bRegData & MCB_AA_PA_SCU_PA0;
++                      }
++                      else if(dPadNo == MCDRV_GP_PAD1)
++                      {
++                              *pbGpio = (bRegData & MCB_AA_PA_SCU_PA1) >> 1;
++                      }
++      /*
++                      else if(dPadNo == MCDRV_GP_PAD2)
++                      {
++                              *pbGpio = (bRegData & MCB_AA_PA_SCU_PA2) >> 2;
++                      }
++      */
++              }
++              else
++              {
++                      sdRet   = McPacket_AddGPSet_AA(*pbGpio, dPadNo);
++                      if(sdRet != MCDRV_SUCCESS)
++                      {
++                              return sdRet;
++                      }
++                      return McDevIf_ExecutePacket_AA();
++              }
++      }
++
++      return MCDRV_SUCCESS;
++}
++
++
++/****************************************************************************
++ *    ValidateInitParam
++ *
++ *    Description:
++ *                    validate init parameters.
++ *    Arguments:
++ *                    psInitInfo      initialize information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++static        SINT32  ValidateInitParam
++(
++      const MCDRV_INIT_INFO*  psInitInfo
++)
++{
++
++      if(MCDRV_CKSEL_CMOS != psInitInfo->bCkSel && 1/*MCDRV_CKSEL_TCXO*/ != psInitInfo->bCkSel)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(psInitInfo->bDivR0 == 0x00 || psInitInfo->bDivR0 > 0x7F)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(McDevProf_IsValid(eMCDRV_FUNC_DIVR1) == 1
++      && (psInitInfo->bDivR1 == 0x00 || psInitInfo->bDivR1 > 0x7F))
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(psInitInfo->bDivF0 == 0x00)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(McDevProf_IsValid(eMCDRV_FUNC_DIVF1) == 1 && psInitInfo->bDivF1 == 0x00)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(McDevProf_IsValid(eMCDRV_FUNC_RANGE) == 1
++      && (psInitInfo->bRange0 > 0x07 || psInitInfo->bRange1 > 0x07))
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(McDevProf_IsValid(eMCDRV_FUNC_BYPASS) == 1 && psInitInfo->bBypass > 0x03)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(MCDRV_DAHIZ_LOW != psInitInfo->bDioSdo0Hiz && MCDRV_DAHIZ_HIZ != psInitInfo->bDioSdo0Hiz)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(MCDRV_DAHIZ_LOW != psInitInfo->bDioSdo1Hiz && MCDRV_DAHIZ_HIZ != psInitInfo->bDioSdo1Hiz)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(MCDRV_DAHIZ_LOW != psInitInfo->bDioSdo2Hiz && MCDRV_DAHIZ_HIZ != psInitInfo->bDioSdo2Hiz)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(MCDRV_PCMHIZ_HIZ != psInitInfo->bPcmHiz && MCDRV_PCMHIZ_LOW != psInitInfo->bPcmHiz)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(MCDRV_DAHIZ_LOW != psInitInfo->bDioClk0Hiz && MCDRV_DAHIZ_HIZ != psInitInfo->bDioClk0Hiz)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(MCDRV_DAHIZ_LOW != psInitInfo->bDioClk1Hiz && MCDRV_DAHIZ_HIZ != psInitInfo->bDioClk1Hiz)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(MCDRV_DAHIZ_LOW != psInitInfo->bDioClk2Hiz && MCDRV_DAHIZ_HIZ != psInitInfo->bDioClk2Hiz)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(MCDRV_PCMHIZ_HIZ != psInitInfo->bPcmHiz && MCDRV_PCMHIZ_LOW != psInitInfo->bPcmHiz)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(MCDRV_LINE_STEREO != psInitInfo->bLineIn1Dif && MCDRV_LINE_DIF != psInitInfo->bLineIn1Dif)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(McDevProf_IsValid(eMCDRV_FUNC_LI2) == 1
++      && MCDRV_LINE_STEREO != psInitInfo->bLineIn2Dif && MCDRV_LINE_DIF != psInitInfo->bLineIn2Dif)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(MCDRV_LINE_STEREO != psInitInfo->bLineOut1Dif && MCDRV_LINE_DIF != psInitInfo->bLineOut1Dif)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(MCDRV_LINE_STEREO != psInitInfo->bLineOut2Dif && MCDRV_LINE_DIF != psInitInfo->bLineOut2Dif)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(MCDRV_SPMN_ON != psInitInfo->bSpmn && MCDRV_SPMN_OFF != psInitInfo->bSpmn)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(MCDRV_MIC_DIF != psInitInfo->bMic1Sng && MCDRV_MIC_SINGLE != psInitInfo->bMic1Sng)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(MCDRV_MIC_DIF != psInitInfo->bMic2Sng && MCDRV_MIC_SINGLE != psInitInfo->bMic2Sng)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(MCDRV_MIC_DIF != psInitInfo->bMic3Sng && MCDRV_MIC_SINGLE != psInitInfo->bMic3Sng)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(MCDRV_POWMODE_NORMAL != psInitInfo->bPowerMode
++      && MCDRV_POWMODE_CLKON != psInitInfo->bPowerMode
++      && MCDRV_POWMODE_VREFON != psInitInfo->bPowerMode
++      && MCDRV_POWMODE_CLKVREFON != psInitInfo->bPowerMode
++      && MCDRV_POWMODE_FULL != psInitInfo->bPowerMode)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(MCDRV_SPHIZ_PULLDOWN != psInitInfo->bSpHiz && MCDRV_SPHIZ_HIZ != psInitInfo->bSpHiz)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(MCDRV_LDO_OFF != psInitInfo->bLdo && MCDRV_LDO_ON != psInitInfo->bLdo)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(MCDRV_PAD_GPIO != psInitInfo->bPad0Func
++      && MCDRV_PAD_PDMCK != psInitInfo->bPad0Func && MCDRV_PAD_IRQ != psInitInfo->bPad0Func)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(McDevProf_IsValid(eMCDRV_FUNC_IRQ) != 1 && MCDRV_PAD_IRQ == psInitInfo->bPad0Func)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(MCDRV_PAD_GPIO != psInitInfo->bPad1Func
++      && MCDRV_PAD_PDMDI != psInitInfo->bPad1Func && MCDRV_PAD_IRQ != psInitInfo->bPad1Func)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(McDevProf_IsValid(eMCDRV_FUNC_IRQ) != 1 && MCDRV_PAD_IRQ == psInitInfo->bPad1Func)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(McDevProf_IsValid(eMCDRV_FUNC_PAD2) == 1
++      && MCDRV_PAD_GPIO != psInitInfo->bPad2Func
++      && MCDRV_PAD_PDMDI != psInitInfo->bPad2Func
++      && MCDRV_PAD_IRQ != psInitInfo->bPad2Func)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(MCDRV_OUTLEV_0 != psInitInfo->bAvddLev && MCDRV_OUTLEV_1 != psInitInfo->bAvddLev
++      && MCDRV_OUTLEV_2 != psInitInfo->bAvddLev && MCDRV_OUTLEV_3 != psInitInfo->bAvddLev
++      && MCDRV_OUTLEV_4 != psInitInfo->bAvddLev && MCDRV_OUTLEV_5 != psInitInfo->bAvddLev
++      && MCDRV_OUTLEV_6 != psInitInfo->bAvddLev && MCDRV_OUTLEV_7 != psInitInfo->bAvddLev)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(MCDRV_OUTLEV_0 != psInitInfo->bVrefLev && MCDRV_OUTLEV_1 != psInitInfo->bVrefLev
++      && MCDRV_OUTLEV_2 != psInitInfo->bVrefLev && MCDRV_OUTLEV_3 != psInitInfo->bVrefLev
++      && MCDRV_OUTLEV_4 != psInitInfo->bVrefLev && MCDRV_OUTLEV_5 != psInitInfo->bVrefLev
++      && MCDRV_OUTLEV_6 != psInitInfo->bVrefLev && MCDRV_OUTLEV_7 != psInitInfo->bVrefLev)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(MCDRV_DCLGAIN_0 != psInitInfo->bDclGain && MCDRV_DCLGAIN_6 != psInitInfo->bDclGain
++      && MCDRV_DCLGAIN_12!= psInitInfo->bDclGain && MCDRV_DCLGAIN_18!= psInitInfo->bDclGain)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if(MCDRV_DCLLIMIT_0 != psInitInfo->bDclLimit && MCDRV_DCLLIMIT_116 != psInitInfo->bDclLimit
++      && MCDRV_DCLLIMIT_250 != psInitInfo->bDclLimit && MCDRV_DCLLIMIT_602 != psInitInfo->bDclLimit)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if((MCDRV_MAX_WAIT_TIME_AA < psInitInfo->sWaitTime.dAdHpf)
++      || (MCDRV_MAX_WAIT_TIME_AA < psInitInfo->sWaitTime.dMic1Cin)
++      || (MCDRV_MAX_WAIT_TIME_AA < psInitInfo->sWaitTime.dMic2Cin)
++      || (MCDRV_MAX_WAIT_TIME_AA < psInitInfo->sWaitTime.dMic3Cin)
++      || (MCDRV_MAX_WAIT_TIME_AA < psInitInfo->sWaitTime.dLine1Cin)
++      || (MCDRV_MAX_WAIT_TIME_AA < psInitInfo->sWaitTime.dLine2Cin)
++      || (MCDRV_MAX_WAIT_TIME_AA < psInitInfo->sWaitTime.dVrefRdy1)
++      || (MCDRV_MAX_WAIT_TIME_AA < psInitInfo->sWaitTime.dVrefRdy2)
++      || (MCDRV_MAX_WAIT_TIME_AA < psInitInfo->sWaitTime.dHpRdy)
++      || (MCDRV_MAX_WAIT_TIME_AA < psInitInfo->sWaitTime.dSpRdy)
++      || (MCDRV_MAX_WAIT_TIME_AA < psInitInfo->sWaitTime.dPdm))
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    ValidateClockParam
++ *
++ *    Description:
++ *                    validate clock parameters.
++ *    Arguments:
++ *                    psClockInfo     clock information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++static        SINT32  ValidateClockParam
++(
++      const MCDRV_CLOCK_INFO* psClockInfo
++)
++{
++
++      if((MCDRV_CKSEL_CMOS != psClockInfo->bCkSel) && (1/*MCDRV_CKSEL_TCXO*/ != psClockInfo->bCkSel))
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if((psClockInfo->bDivR0 == 0x00) || (psClockInfo->bDivR0 > 0x7F))
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if((McDevProf_IsValid(eMCDRV_FUNC_DIVR1) == 1)
++      && ((psClockInfo->bDivR1 == 0x00) || (psClockInfo->bDivR1 > 0x7F)))
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(psClockInfo->bDivF0 == 0x00)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if((McDevProf_IsValid(eMCDRV_FUNC_DIVF1) == 1) && (psClockInfo->bDivF1 == 0x00))
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if((McDevProf_IsValid(eMCDRV_FUNC_RANGE) == 1)
++      && ((psClockInfo->bRange0 > 0x07) || (psClockInfo->bRange1 > 0x07)))
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if((McDevProf_IsValid(eMCDRV_FUNC_BYPASS) == 1) && (psClockInfo->bBypass > 0x03))
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    ValidateReadRegParam
++ *
++ *    Description:
++ *                    validate read reg parameter.
++ *    Arguments:
++ *                    psRegInfo       register information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++static        SINT32  ValidateReadRegParam
++(
++      const MCDRV_REG_INFO*   psRegInfo
++)
++{
++
++      if((McResCtrl_GetRegAccess_AA(psRegInfo) & eMCDRV_READ_ONLY_AA) == 0)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    ValidateWriteRegParam
++ *
++ *    Description:
++ *                    validate write reg parameter.
++ *    Arguments:
++ *                    psRegInfo       register information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++static        SINT32  ValidateWriteRegParam
++(
++      const MCDRV_REG_INFO*   psRegInfo
++)
++{
++
++      if((McResCtrl_GetRegAccess_AA(psRegInfo) & eMCDRV_WRITE_ONLY_AA) == 0)
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    ValidatePathParam
++ *
++ *    Description:
++ *                    validate path parameters.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++static SINT32 ValidatePathParam(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++      UINT8   bBlock;
++      UINT8   bCh;
++      UINT8   bPDMIsSrc       = 0;
++      UINT8   bADC0IsSrc      = 0;
++      MCDRV_PATH_INFO         sCurPathInfo;
++
++
++      McResCtrl_GetPathInfoVirtual_AA(&sCurPathInfo);
++      /*      set off to current path info    */
++      for(bBlock = 0; bBlock < SOURCE_BLOCK_NUM; bBlock++)
++      {
++              for(bCh = 0; bCh < HP_PATH_CHANNELS; bCh++)
++              {
++                      if((psPathInfo->asHpOut[bCh].abSrcOnOff[bBlock] & (0x03)) == 0x02)
++                      {
++                              sCurPathInfo.asHpOut[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x01;
++                              sCurPathInfo.asHpOut[bCh].abSrcOnOff[bBlock]    |= 0x02;
++                      }
++                      if((psPathInfo->asHpOut[bCh].abSrcOnOff[bBlock] & (0x0C)) == 0x08)
++                      {
++                              sCurPathInfo.asHpOut[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x04;
++                              sCurPathInfo.asHpOut[bCh].abSrcOnOff[bBlock]    |= 0x08;
++                      }
++                      if((psPathInfo->asHpOut[bCh].abSrcOnOff[bBlock] & (0x30)) == 0x20)
++                      {
++                              sCurPathInfo.asHpOut[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x10;
++                              sCurPathInfo.asHpOut[bCh].abSrcOnOff[bBlock]    |= 0x20;
++                      }
++                      if((psPathInfo->asHpOut[bCh].abSrcOnOff[bBlock] & (0xC0)) == 0x80)
++                      {
++                              sCurPathInfo.asHpOut[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x40;
++                              sCurPathInfo.asHpOut[bCh].abSrcOnOff[bBlock]    |= 0x80;
++                      }
++              }
++              for(bCh = 0; bCh < SP_PATH_CHANNELS; bCh++)
++              {
++                      if((psPathInfo->asSpOut[bCh].abSrcOnOff[bBlock] & (0x03)) == 0x02)
++                      {
++                              sCurPathInfo.asSpOut[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x01;
++                              sCurPathInfo.asSpOut[bCh].abSrcOnOff[bBlock]    |= (UINT8)0x02;
++                      }
++                      if((psPathInfo->asSpOut[bCh].abSrcOnOff[bBlock] & (0x0C)) == 0x08)
++                      {
++                              sCurPathInfo.asSpOut[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x04;
++                              sCurPathInfo.asSpOut[bCh].abSrcOnOff[bBlock]    |= (UINT8)0x08;
++                      }
++                      if((psPathInfo->asSpOut[bCh].abSrcOnOff[bBlock] & (0x30)) == 0x20)
++                      {
++                              sCurPathInfo.asSpOut[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x10;
++                              sCurPathInfo.asSpOut[bCh].abSrcOnOff[bBlock]    |= (UINT8)0x20;
++                      }
++                      if((psPathInfo->asSpOut[bCh].abSrcOnOff[bBlock] & (0xC0)) == 0x80)
++                      {
++                              sCurPathInfo.asSpOut[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x40;
++                              sCurPathInfo.asSpOut[bCh].abSrcOnOff[bBlock]    |= (UINT8)0x80;
++                      }
++              }
++              for(bCh = 0; bCh < RC_PATH_CHANNELS; bCh++)
++              {
++                      if((psPathInfo->asRcOut[bCh].abSrcOnOff[bBlock] & (0x03)) == 0x02)
++                      {
++                              sCurPathInfo.asRcOut[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x01;
++                              sCurPathInfo.asRcOut[bCh].abSrcOnOff[bBlock]    |= (UINT8)0x02;
++                      }
++                      if((psPathInfo->asRcOut[bCh].abSrcOnOff[bBlock] & (0x0C)) == 0x08)
++                      {
++                              sCurPathInfo.asRcOut[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x04;
++                              sCurPathInfo.asRcOut[bCh].abSrcOnOff[bBlock]    |= (UINT8)0x08;
++                      }
++                      if((psPathInfo->asRcOut[bCh].abSrcOnOff[bBlock] & (0x30)) == 0x20)
++                      {
++                              sCurPathInfo.asRcOut[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x10;
++                              sCurPathInfo.asRcOut[bCh].abSrcOnOff[bBlock]    |= (UINT8)0x20;
++                      }
++                      if((psPathInfo->asRcOut[bCh].abSrcOnOff[bBlock] & (0xC0)) == 0x80)
++                      {
++                              sCurPathInfo.asRcOut[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x40;
++                              sCurPathInfo.asRcOut[bCh].abSrcOnOff[bBlock]    |= (UINT8)0x80;
++                      }
++              }
++              for(bCh = 0; bCh < LOUT1_PATH_CHANNELS; bCh++)
++              {
++                      if((psPathInfo->asLout1[bCh].abSrcOnOff[bBlock] & (0x03)) == 0x02)
++                      {
++                              sCurPathInfo.asLout1[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x01;
++                              sCurPathInfo.asLout1[bCh].abSrcOnOff[bBlock]    |= (UINT8)0x02;
++                      }
++                      if((psPathInfo->asLout1[bCh].abSrcOnOff[bBlock] & (0x0C)) == 0x08)
++                      {
++                              sCurPathInfo.asLout1[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x04;
++                              sCurPathInfo.asLout1[bCh].abSrcOnOff[bBlock]    |= (UINT8)0x08;
++                      }
++                      if((psPathInfo->asLout1[bCh].abSrcOnOff[bBlock] & (0x30)) == 0x20)
++                      {
++                              sCurPathInfo.asLout1[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x10;
++                              sCurPathInfo.asLout1[bCh].abSrcOnOff[bBlock]    |= (UINT8)0x20;
++                      }
++                      if((psPathInfo->asLout1[bCh].abSrcOnOff[bBlock] & (0xC0)) == 0x80)
++                      {
++                              sCurPathInfo.asLout1[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x40;
++                              sCurPathInfo.asLout1[bCh].abSrcOnOff[bBlock]    |= (UINT8)0x80;
++                      }
++              }
++              for(bCh = 0; bCh < LOUT2_PATH_CHANNELS; bCh++)
++              {
++                      if((psPathInfo->asLout2[bCh].abSrcOnOff[bBlock] & (0x03)) == 0x02)
++                      {
++                              sCurPathInfo.asLout2[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x01;
++                              sCurPathInfo.asLout2[bCh].abSrcOnOff[bBlock]    |= 0x02;
++                      }
++                      if((psPathInfo->asLout2[bCh].abSrcOnOff[bBlock] & (0x0C)) == 0x08)
++                      {
++                              sCurPathInfo.asLout2[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x04;
++                              sCurPathInfo.asLout2[bCh].abSrcOnOff[bBlock]    |= 0x08;
++                      }
++                      if((psPathInfo->asLout2[bCh].abSrcOnOff[bBlock] & (0x30)) == 0x20)
++                      {
++                              sCurPathInfo.asLout2[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x10;
++                              sCurPathInfo.asLout2[bCh].abSrcOnOff[bBlock]    |= 0x20;
++                      }
++                      if((psPathInfo->asLout2[bCh].abSrcOnOff[bBlock] & (0xC0)) == 0x80)
++                      {
++                              sCurPathInfo.asLout2[bCh].abSrcOnOff[bBlock]    &= (UINT8)~0x40;
++                              sCurPathInfo.asLout2[bCh].abSrcOnOff[bBlock]    |= 0x80;
++                      }
++              }
++              for(bCh = 0; bCh < DIT0_PATH_CHANNELS; bCh++)
++              {
++                      if((psPathInfo->asDit0[bCh].abSrcOnOff[bBlock] & (0x03)) == 0x02)
++                      {
++                              sCurPathInfo.asDit0[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x01;
++                              sCurPathInfo.asDit0[bCh].abSrcOnOff[bBlock]     |= 0x02;
++                      }
++                      if((psPathInfo->asDit0[bCh].abSrcOnOff[bBlock] & (0x0C)) == 0x08)
++                      {
++                              sCurPathInfo.asDit0[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x04;
++                              sCurPathInfo.asDit0[bCh].abSrcOnOff[bBlock]     |= 0x08;
++                      }
++                      if((psPathInfo->asDit0[bCh].abSrcOnOff[bBlock] & (0x30)) == 0x20)
++                      {
++                              sCurPathInfo.asDit0[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x10;
++                              sCurPathInfo.asDit0[bCh].abSrcOnOff[bBlock]     |= 0x20;
++                      }
++                      if((psPathInfo->asDit0[bCh].abSrcOnOff[bBlock] & (0xC0)) == 0x80)
++                      {
++                              sCurPathInfo.asDit0[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x40;
++                              sCurPathInfo.asDit0[bCh].abSrcOnOff[bBlock]     |= 0x80;
++                      }
++              }
++              for(bCh = 0; bCh < DIT1_PATH_CHANNELS; bCh++)
++              {
++                      if((psPathInfo->asDit1[bCh].abSrcOnOff[bBlock] & (0x03)) == 0x02)
++                      {
++                              sCurPathInfo.asDit1[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x01;
++                              sCurPathInfo.asDit1[bCh].abSrcOnOff[bBlock]     |= 0x02;
++                      }
++                      if((psPathInfo->asDit1[bCh].abSrcOnOff[bBlock] & (0x0C)) == 0x08)
++                      {
++                              sCurPathInfo.asDit1[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x04;
++                              sCurPathInfo.asDit1[bCh].abSrcOnOff[bBlock]     |= 0x08;
++                      }
++                      if((psPathInfo->asDit1[bCh].abSrcOnOff[bBlock] & (0x30)) == 0x20)
++                      {
++                              sCurPathInfo.asDit1[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x10;
++                              sCurPathInfo.asDit1[bCh].abSrcOnOff[bBlock]     |= 0x20;
++                      }
++                      if((psPathInfo->asDit1[bCh].abSrcOnOff[bBlock] & (0xC0)) == 0x80)
++                      {
++                              sCurPathInfo.asDit1[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x40;
++                              sCurPathInfo.asDit1[bCh].abSrcOnOff[bBlock]     |= 0x80;
++                      }
++              }
++              for(bCh = 0; bCh < DIT2_PATH_CHANNELS; bCh++)
++              {
++                      if((psPathInfo->asDit2[bCh].abSrcOnOff[bBlock] & (0x03)) == 0x02)
++                      {
++                              sCurPathInfo.asDit2[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x01;
++                              sCurPathInfo.asDit2[bCh].abSrcOnOff[bBlock]     |= 0x02;
++                      }
++                      if((psPathInfo->asDit2[bCh].abSrcOnOff[bBlock] & (0x0C)) == 0x08)
++                      {
++                              sCurPathInfo.asDit2[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x04;
++                              sCurPathInfo.asDit2[bCh].abSrcOnOff[bBlock]     |= 0x08;
++                      }
++                      if((psPathInfo->asDit2[bCh].abSrcOnOff[bBlock] & (0x30)) == 0x20)
++                      {
++                              sCurPathInfo.asDit2[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x10;
++                              sCurPathInfo.asDit2[bCh].abSrcOnOff[bBlock]     |= 0x20;
++                      }
++                      if((psPathInfo->asDit2[bCh].abSrcOnOff[bBlock] & (0xC0)) == 0x80)
++                      {
++                              sCurPathInfo.asDit2[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x40;
++                              sCurPathInfo.asDit2[bCh].abSrcOnOff[bBlock]     |= 0x80;
++                      }
++              }
++              for(bCh = 0; bCh < DAC_PATH_CHANNELS; bCh++)
++              {
++                      if((psPathInfo->asDac[bCh].abSrcOnOff[bBlock] & (0x03)) == 0x02)
++                      {
++                              sCurPathInfo.asDac[bCh].abSrcOnOff[bBlock]      &= (UINT8)~0x01;
++                              sCurPathInfo.asDac[bCh].abSrcOnOff[bBlock]      |= 0x02;
++                      }
++                      if((psPathInfo->asDac[bCh].abSrcOnOff[bBlock] & (0x0C)) == 0x08)
++                      {
++                              sCurPathInfo.asDac[bCh].abSrcOnOff[bBlock]      &= (UINT8)~0x04;
++                              sCurPathInfo.asDac[bCh].abSrcOnOff[bBlock]      |= 0x08;
++                      }
++                      if((psPathInfo->asDac[bCh].abSrcOnOff[bBlock] & (0x30)) == 0x20)
++                      {
++                              sCurPathInfo.asDac[bCh].abSrcOnOff[bBlock]      &= (UINT8)~0x10;
++                              sCurPathInfo.asDac[bCh].abSrcOnOff[bBlock]      |= 0x20;
++                      }
++                      if((psPathInfo->asDac[bCh].abSrcOnOff[bBlock] & (0xC0)) == 0x80)
++                      {
++                              sCurPathInfo.asDac[bCh].abSrcOnOff[bBlock]      &= (UINT8)~0x40;
++                              sCurPathInfo.asDac[bCh].abSrcOnOff[bBlock]      |= 0x80;
++                      }
++              }
++              for(bCh = 0; bCh < AE_PATH_CHANNELS; bCh++)
++              {
++                      if((psPathInfo->asAe[bCh].abSrcOnOff[bBlock] & (0x03)) == 0x02)
++                      {
++                              sCurPathInfo.asAe[bCh].abSrcOnOff[bBlock]       &= (UINT8)~0x01;
++                              sCurPathInfo.asAe[bCh].abSrcOnOff[bBlock]       |= 0x02;
++                      }
++                      if((psPathInfo->asAe[bCh].abSrcOnOff[bBlock] & (0x0C)) == 0x08)
++                      {
++                              sCurPathInfo.asAe[bCh].abSrcOnOff[bBlock]       &= (UINT8)~0x04;
++                              sCurPathInfo.asAe[bCh].abSrcOnOff[bBlock]       |= 0x08;
++                      }
++                      if((psPathInfo->asAe[bCh].abSrcOnOff[bBlock] & (0x30)) == 0x20)
++                      {
++                              sCurPathInfo.asAe[bCh].abSrcOnOff[bBlock]       &= (UINT8)~0x10;
++                              sCurPathInfo.asAe[bCh].abSrcOnOff[bBlock]       |= 0x20;
++                      }
++                      if((psPathInfo->asAe[bCh].abSrcOnOff[bBlock] & (0xC0)) == 0x80)
++                      {
++                              sCurPathInfo.asAe[bCh].abSrcOnOff[bBlock]       &= (UINT8)~0x40;
++                              sCurPathInfo.asAe[bCh].abSrcOnOff[bBlock]       |= 0x80;
++                      }
++              }
++              for(bCh = 0; bCh < ADC0_PATH_CHANNELS; bCh++)
++              {
++                      if((psPathInfo->asAdc0[bCh].abSrcOnOff[bBlock] & (0x03)) == 0x02)
++                      {
++                              sCurPathInfo.asAdc0[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x01;
++                              sCurPathInfo.asAdc0[bCh].abSrcOnOff[bBlock]     |= (UINT8)0x02;
++                      }
++                      if((psPathInfo->asAdc0[bCh].abSrcOnOff[bBlock] & (0x0C)) == 0x08)
++                      {
++                              sCurPathInfo.asAdc0[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x04;
++                              sCurPathInfo.asAdc0[bCh].abSrcOnOff[bBlock]     |= (UINT8)0x08;
++                      }
++                      if((psPathInfo->asAdc0[bCh].abSrcOnOff[bBlock] & (0x30)) == 0x20)
++                      {
++                              sCurPathInfo.asAdc0[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x10;
++                              sCurPathInfo.asAdc0[bCh].abSrcOnOff[bBlock]     |= (UINT8)0x20;
++                      }
++                      if((psPathInfo->asAdc0[bCh].abSrcOnOff[bBlock] & (0xC0)) == 0x80)
++                      {
++                              sCurPathInfo.asAdc0[bCh].abSrcOnOff[bBlock]     &= (UINT8)~0x40;
++                              sCurPathInfo.asAdc0[bCh].abSrcOnOff[bBlock]     |= (UINT8)0x80;
++                      }
++              }
++              for(bCh = 0; bCh < MIX_PATH_CHANNELS; bCh++)
++              {
++                      if((psPathInfo->asMix[bCh].abSrcOnOff[bBlock] & (0x03)) == 0x02)
++                      {
++                              sCurPathInfo.asMix[bCh].abSrcOnOff[bBlock]      &= (UINT8)~0x01;
++                              sCurPathInfo.asMix[bCh].abSrcOnOff[bBlock]      |= 0x02;
++                      }
++                      if((psPathInfo->asMix[bCh].abSrcOnOff[bBlock] & (0x0C)) == 0x08)
++                      {
++                              sCurPathInfo.asMix[bCh].abSrcOnOff[bBlock]      &= (UINT8)~0x04;
++                              sCurPathInfo.asMix[bCh].abSrcOnOff[bBlock]      |= 0x08;
++                      }
++                      if((psPathInfo->asMix[bCh].abSrcOnOff[bBlock] & (0x30)) == 0x20)
++                      {
++                              sCurPathInfo.asMix[bCh].abSrcOnOff[bBlock]      &= (UINT8)~0x10;
++                              sCurPathInfo.asMix[bCh].abSrcOnOff[bBlock]      |= 0x20;
++                      }
++                      if((psPathInfo->asMix[bCh].abSrcOnOff[bBlock] & (0xC0)) == 0x80)
++                      {
++                              sCurPathInfo.asMix[bCh].abSrcOnOff[bBlock]      &= (UINT8)~0x40;
++                              sCurPathInfo.asMix[bCh].abSrcOnOff[bBlock]      |= 0x80;
++                      }
++              }
++      }
++
++      if((sCurPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON
++      || (sCurPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON
++      || (sCurPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON
++      || (sCurPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON
++      || (sCurPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON
++      || (sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON
++      || (sCurPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON)
++      {
++              bPDMIsSrc       = 1;
++      }
++      if((sCurPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON
++      || (sCurPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON
++      || (sCurPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON
++      || (sCurPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON
++      || (sCurPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON
++      || (sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON
++      || (sCurPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON)
++      {
++              bADC0IsSrc      = 1;
++      }
++
++      /*      HP      */
++      if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++      {
++              if(((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++              || ((sCurPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON))
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              if((sCurPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++      {
++              if(((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++              || ((sCurPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON))
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++      {
++              if((sCurPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++
++      /*      SP      */
++      if((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++      {
++              if(((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++              || ((sCurPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON))
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              if((sCurPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++      {
++              if(((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++              || ((sCurPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON))
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++      {
++              if((sCurPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_ON)
++      {
++              if(((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++              || ((sCurPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON))
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              if((sCurPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & (MCDRV_SRC5_DAC_R_ON|MCDRV_SRC5_DAC_R_OFF)) == MCDRV_SRC5_DAC_R_ON)
++      {
++              if(((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++              || ((sCurPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON))
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++      {
++              if((sCurPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & (MCDRV_SRC5_DAC_R_ON|MCDRV_SRC5_DAC_R_OFF)) == MCDRV_SRC5_DAC_R_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++
++      /*      RCV     */
++
++      /*      LOUT1   */
++      if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++      {
++              if(((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++              || ((sCurPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON))
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              if((sCurPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++      {
++              if(((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++              || ((sCurPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON))
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++      {
++              if((sCurPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++
++      /*      LOUT2   */
++      if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++      {
++              if(((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++              || ((sCurPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON))
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              if((sCurPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++      {
++              if(((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++              || ((sCurPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON))
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++      {
++              if((sCurPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++
++      /*      PeakMeter       */
++
++      /*      DIT0    */
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++      {
++              if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON
++              || (psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON
++              || (psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++              || (psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++              || (psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON
++              || (psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++              || (sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++      {
++              if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON
++              || (psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++              || (psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++              || (psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON
++              || (psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++              || (sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++      {
++              if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++              || (psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++              || (psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON
++              || (psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++              || (sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      {
++              if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++              || (psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON
++              || (psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++              || (sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON
++              || (psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++              || (sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++      {
++              if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++      {
++              if((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      {
++              if(bADC0IsSrc == 1)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++              else
++              {
++                      bPDMIsSrc       = 1;
++              }
++      }
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              if(bPDMIsSrc == 1)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++              else
++              {
++                      bADC0IsSrc      = 1;
++              }
++      }
++
++      /*      DIT1    */
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++      {
++              if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON
++              || (psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON
++              || (psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++              || (psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++              || (psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON
++              || (psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++              || (sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++      {
++              if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON
++              || (psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++              || (psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++              || (psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON
++              || (psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++              || (sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++      {
++              if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++              || (psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++              || (psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON
++              || (psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++              || (sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      {
++              if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++              || (psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON
++              || (psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++              || (sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON
++              || (psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++              || (sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++      {
++              if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++      {
++              if((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      {
++              if(bADC0IsSrc == 1)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++              else
++              {
++                      bPDMIsSrc       = 1;
++              }
++      }
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              if(bPDMIsSrc == 1)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++              else
++              {
++                      bADC0IsSrc      = 1;
++              }
++      }
++
++      /*      DIT2    */
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++      {
++              if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON
++              || (psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON
++              || (psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++              || (psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++              || (psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON
++              || (psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++              || (sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++      {
++              if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON
++              || (psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++              || (psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++              || (psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON
++              || (psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++              || (sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++      {
++              if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++              || (psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++              || (psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON
++              || (psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++              || (sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      {
++              if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++              || (psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON
++              || (psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++              || (sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON
++              || (psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++              || (sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++      {
++              if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++      {
++              if((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      {
++              if(bADC0IsSrc == 1)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++              else
++              {
++                      bPDMIsSrc       = 1;
++              }
++      }
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              if(bPDMIsSrc == 1)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++              else
++              {
++                      bADC0IsSrc      = 1;
++              }
++      }
++
++      /*      DAC     */
++      for(bCh = 0; bCh < DAC_PATH_CHANNELS; bCh++)
++      {
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++              {
++                      if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON
++                      || (psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON
++                      || (psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++                      || (psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++                      || (psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON
++                      || (psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++                      || (sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++                      {
++                              return MCDRV_ERROR_ARGUMENT;
++                      }
++              }
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++              {
++                      if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON
++                      || (psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++                      || (psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++                      || (psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON
++                      || (psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++                      || (sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++                      {
++                              return MCDRV_ERROR_ARGUMENT;
++                      }
++              }
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++              {
++                      if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++                      || (psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++                      || (psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON
++                      || (psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++                      || (sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++                      {
++                              return MCDRV_ERROR_ARGUMENT;
++                      }
++              }
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++              {
++                      if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++                      || (psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON
++                      || (psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++                      || (sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++                      {
++                              return MCDRV_ERROR_ARGUMENT;
++                      }
++              }
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++              {
++                      if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON
++                      || (psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++                      || (sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++                      {
++                              return MCDRV_ERROR_ARGUMENT;
++                      }
++              }
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++              {
++                      if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++                      {
++                              return MCDRV_ERROR_ARGUMENT;
++                      }
++              }
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              {
++                      if((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++                      {
++                              return MCDRV_ERROR_ARGUMENT;
++                      }
++              }
++
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++              {
++                      if(bADC0IsSrc == 1)
++                      {
++                              return MCDRV_ERROR_ARGUMENT;
++                      }
++                      else
++                      {
++                              bPDMIsSrc       = 1;
++                      }
++              }
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++              {
++                      if(bPDMIsSrc == 1)
++                      {
++                              return MCDRV_ERROR_ARGUMENT;
++                      }
++                      else
++                      {
++                              bADC0IsSrc      = 1;
++                      }
++              }
++      }
++
++      /*      AE      */
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++      {
++              if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON
++              || (psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON
++              || (psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++              || (psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++              || (psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++      {
++              if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON
++              || (psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++              || (psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++              || (psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++      {
++              if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++              || (psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++              || (psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      {
++              if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++              || (psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      {
++              if(bADC0IsSrc == 1)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++              else
++              {
++                      bPDMIsSrc       = 1;
++              }
++      }
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              if(bPDMIsSrc == 1)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++              else
++              {
++                      bADC0IsSrc      = 1;
++              }
++      }
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++      && ((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON
++              || (sCurPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON))
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      /*      CDSP    */
++      for(bCh = 0; bCh < 4; bCh++)
++      {
++      }
++
++      /*      ADC0    */
++      if((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++      {
++              if(((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++              || ((sCurPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON))
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              if((sCurPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_ON)
++      {
++              if(((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++              || ((sCurPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON))
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              if((sCurPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++
++      /*      ADC1    */
++
++      /*      MIX     */
++      if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      {
++              if(bADC0IsSrc == 1)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++              else
++              {
++                      bPDMIsSrc       = 1;
++              }
++      }
++      if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              if(bPDMIsSrc == 1)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++              else
++              {
++                      bADC0IsSrc      = 1;
++              }
++      }
++      if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++      {
++              if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++              || (sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & MCDRV_SRC6_MIX_ON) == MCDRV_SRC6_MIX_ON)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      if(((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++      && ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON))
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++      && ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON))
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++      && ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON))
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      && ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON))
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if(((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      && ((sCurPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON))
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON
++      && ((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON
++       || (psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON
++       || (psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON
++       || (psPathInfo->asDac[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON
++       || (psPathInfo->asDac[1].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON
++       || (psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON
++       || (sCurPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON
++       || (sCurPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON
++       || (sCurPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON
++       || (sCurPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON
++       || (sCurPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON
++       || (sCurPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON
++       ))
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON
++      && ((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON
++       || (psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON
++       || (psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON
++       || (psPathInfo->asDac[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON
++       || (psPathInfo->asDac[1].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON
++       || (psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON
++       || (sCurPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON
++       || (sCurPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON
++       || (sCurPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON
++       || (sCurPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON
++       || (sCurPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON
++       || (sCurPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON
++       ))
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON
++      && ((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON
++       || (psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON
++       || (psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON
++       || (psPathInfo->asDac[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON
++       || (psPathInfo->asDac[1].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON
++       || (psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON
++       || (sCurPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON
++       || (sCurPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON
++       || (sCurPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON
++       || (sCurPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON
++       || (sCurPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON
++       || (sCurPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON
++       ))
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++      && ((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++       || (psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++       || (psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++       || (psPathInfo->asDac[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++       || (psPathInfo->asDac[1].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++       || (psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++       || (sCurPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++       || (sCurPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++       || (sCurPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++       || (sCurPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++       || (sCurPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON
++       || (sCurPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON))
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++      && ((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++       || (psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++       || (psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++       || (psPathInfo->asDac[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++       || (psPathInfo->asDac[1].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++       || (psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++       || (sCurPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++       || (sCurPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++       || (sCurPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++       || (sCurPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++       || (sCurPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON
++       || (sCurPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON))
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++      && ((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++       || (psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++       || (psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++       || (psPathInfo->asDac[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++       || (psPathInfo->asDac[1].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++       || (sCurPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++       || (sCurPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++       || (sCurPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++       || (sCurPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++       || (sCurPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON
++       ))
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    ValidateDioParam
++ *
++ *    Description:
++ *                    validate digital IO parameters.
++ *    Arguments:
++ *                    psDioInfo       digital IO information
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++static SINT32 ValidateDioParam
++(
++      const MCDRV_DIO_INFO*   psDioInfo,
++      UINT32                                  dUpdateInfo
++)
++{
++      SINT32                          sdRet   = MCDRV_SUCCESS;
++      UINT8                           bPort;
++      MCDRV_SRC_TYPE_AA               aeDITSource[IOPORT_NUM];
++      MCDRV_SRC_TYPE_AA               eAESource       = McResCtrl_GetAESource_AA();
++      MCDRV_SRC_TYPE_AA               eDAC0Source     = McResCtrl_GetDACSource_AA(eMCDRV_DAC_MASTER_AA);
++      MCDRV_SRC_TYPE_AA               eDAC1Source     = McResCtrl_GetDACSource_AA(eMCDRV_DAC_VOICE_AA);
++      UINT8                           bDIRUsed[IOPORT_NUM];
++      MCDRV_DIO_INFO          sDioInfo;
++      MCDRV_DIO_PORT_NO_AA    aePort[IOPORT_NUM]      = {eMCDRV_DIO_0_AA, eMCDRV_DIO_1_AA, eMCDRV_DIO_2_AA};
++
++
++      McResCtrl_GetDioInfo_AA(&sDioInfo);
++
++      for(bPort = 0; bPort < IOPORT_NUM; bPort++)
++      {
++              aeDITSource[bPort]      = McResCtrl_GetDITSource_AA(aePort[bPort]);
++              bDIRUsed[bPort]         = 0;
++      }
++
++      if(eAESource == eMCDRV_SRC_DIR0_AA || eDAC0Source == eMCDRV_SRC_DIR0_AA || eDAC1Source == eMCDRV_SRC_DIR0_AA
++      || aeDITSource[0] == eMCDRV_SRC_DIR0_AA || aeDITSource[1] == eMCDRV_SRC_DIR0_AA || aeDITSource[2] == eMCDRV_SRC_DIR0_AA)
++      {
++              bDIRUsed[0]     = 1;
++      }
++      if(eAESource == eMCDRV_SRC_DIR1_AA || eDAC0Source == eMCDRV_SRC_DIR1_AA || eDAC1Source == eMCDRV_SRC_DIR1_AA
++      || aeDITSource[0] == eMCDRV_SRC_DIR1_AA || aeDITSource[1] == eMCDRV_SRC_DIR1_AA || aeDITSource[2] == eMCDRV_SRC_DIR1_AA)
++      {
++              bDIRUsed[1]     = 1;
++      }
++      if(eAESource == eMCDRV_SRC_DIR2_AA || eDAC0Source == eMCDRV_SRC_DIR2_AA || eDAC1Source == eMCDRV_SRC_DIR2_AA
++      || aeDITSource[0] == eMCDRV_SRC_DIR2_AA || aeDITSource[1] == eMCDRV_SRC_DIR2_AA || aeDITSource[2] == eMCDRV_SRC_DIR2_AA)
++      {
++              bDIRUsed[2]     = 1;
++      }
++
++      if((bDIRUsed[0] == 1 && ((dUpdateInfo & MCDRV_DIO0_COM_UPDATE_FLAG) != 0 || (dUpdateInfo & MCDRV_DIO0_DIR_UPDATE_FLAG) != 0))
++      || (aeDITSource[0] != eMCDRV_SRC_NONE_AA && ((dUpdateInfo & MCDRV_DIO0_COM_UPDATE_FLAG) != 0 || (dUpdateInfo & MCDRV_DIO0_DIT_UPDATE_FLAG) != 0)))
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if((bDIRUsed[1] == 1 && ((dUpdateInfo & MCDRV_DIO1_COM_UPDATE_FLAG) != 0 || (dUpdateInfo & MCDRV_DIO1_DIR_UPDATE_FLAG) != 0))
++      || (aeDITSource[1] != eMCDRV_SRC_NONE_AA && ((dUpdateInfo & MCDRV_DIO1_COM_UPDATE_FLAG) != 0 || (dUpdateInfo & MCDRV_DIO1_DIT_UPDATE_FLAG) != 0)))
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++      if((bDIRUsed[2] == 1 && ((dUpdateInfo & MCDRV_DIO2_COM_UPDATE_FLAG) != 0 || (dUpdateInfo & MCDRV_DIO2_DIR_UPDATE_FLAG) != 0))
++      || (aeDITSource[2] != eMCDRV_SRC_NONE_AA && ((dUpdateInfo & MCDRV_DIO2_COM_UPDATE_FLAG) != 0 || (dUpdateInfo & MCDRV_DIO2_DIT_UPDATE_FLAG) != 0)))
++      {
++              return MCDRV_ERROR_ARGUMENT;
++      }
++
++      if((dUpdateInfo & MCDRV_DIO0_COM_UPDATE_FLAG) != 0)
++      {
++              sdRet   = CheckDIOCommon(psDioInfo, 0);
++              if(sdRet != MCDRV_SUCCESS)
++              {
++                      return sdRet;
++              }
++              sDioInfo.asPortInfo[0].sDioCommon.bInterface    = psDioInfo->asPortInfo[0].sDioCommon.bInterface;
++      }
++      if((dUpdateInfo & MCDRV_DIO1_COM_UPDATE_FLAG) != 0)
++      {
++              sdRet   = CheckDIOCommon(psDioInfo, 1);
++              if(sdRet != MCDRV_SUCCESS)
++              {
++                      return sdRet;
++              }
++              sDioInfo.asPortInfo[1].sDioCommon.bInterface    = psDioInfo->asPortInfo[1].sDioCommon.bInterface;
++      }
++      if((dUpdateInfo & MCDRV_DIO2_COM_UPDATE_FLAG) != 0)
++      {
++              sdRet   = CheckDIOCommon(psDioInfo, 2);
++              if(sdRet != MCDRV_SUCCESS)
++              {
++                      return sdRet;
++              }
++              sDioInfo.asPortInfo[2].sDioCommon.bInterface    = psDioInfo->asPortInfo[2].sDioCommon.bInterface;
++      }
++
++      if((dUpdateInfo & MCDRV_DIO0_DIR_UPDATE_FLAG) != 0)
++      {
++              sdRet   = CheckDIODIR(psDioInfo, 0, sDioInfo.asPortInfo[0].sDioCommon.bInterface);
++              if(sdRet != MCDRV_SUCCESS)
++              {
++                      return sdRet;
++              }
++      }
++      if((dUpdateInfo & MCDRV_DIO1_DIR_UPDATE_FLAG) != 0)
++      {
++              sdRet   = CheckDIODIR(psDioInfo, 1, sDioInfo.asPortInfo[1].sDioCommon.bInterface);
++              if(sdRet != MCDRV_SUCCESS)
++              {
++                      return sdRet;
++              }
++      }
++      if((dUpdateInfo & MCDRV_DIO2_DIR_UPDATE_FLAG) != 0)
++      {
++              sdRet   = CheckDIODIR(psDioInfo, 2, sDioInfo.asPortInfo[2].sDioCommon.bInterface);
++              if(sdRet != MCDRV_SUCCESS)
++              {
++                      return sdRet;
++              }
++      }
++
++      if((dUpdateInfo & MCDRV_DIO0_DIT_UPDATE_FLAG) != 0)
++      {
++              sdRet   = CheckDIODIT(psDioInfo, 0, sDioInfo.asPortInfo[0].sDioCommon.bInterface);
++              if(sdRet != MCDRV_SUCCESS)
++              {
++                      return sdRet;
++              }
++      }
++      if((dUpdateInfo & MCDRV_DIO1_DIT_UPDATE_FLAG) != 0)
++      {
++              sdRet   = CheckDIODIT(psDioInfo, 1, sDioInfo.asPortInfo[1].sDioCommon.bInterface);
++              if(sdRet != MCDRV_SUCCESS)
++              {
++                      return sdRet;
++              }
++      }
++      if((dUpdateInfo & MCDRV_DIO2_DIT_UPDATE_FLAG) != 0)
++      {
++              sdRet   = CheckDIODIT(psDioInfo, 2, sDioInfo.asPortInfo[2].sDioCommon.bInterface);
++              if(sdRet != MCDRV_SUCCESS)
++              {
++                      return sdRet;
++              }
++      }
++
++      return sdRet;
++}
++
++
++/****************************************************************************
++ *    CheckDIOCommon
++ *
++ *    Description:
++ *                    validate Digital IO Common parameters.
++ *    Arguments:
++ *                    psDioInfo       digital IO information
++ *                    bPort           port number
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++static SINT32 CheckDIOCommon
++(
++      const MCDRV_DIO_INFO*   psDioInfo,
++      UINT8   bPort
++)
++{
++
++      if(psDioInfo->asPortInfo[bPort].sDioCommon.bInterface == MCDRV_DIO_PCM)
++      {
++              if(psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_48000
++              || psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_44100
++              || psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_32000
++              || psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_24000
++              || psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_22050
++              || psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_12000
++              || psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_11025)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++
++              if(psDioInfo->asPortInfo[bPort].sDioCommon.bMasterSlave == MCDRV_DIO_MASTER
++              && psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_16000)
++              {
++                      if(psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs == MCDRV_BCKFS_512)
++                      {
++                              return MCDRV_ERROR_ARGUMENT;
++                      }
++              }
++      }
++      else
++      {
++              if(psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs == MCDRV_BCKFS_512
++              || psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs == MCDRV_BCKFS_256
++              || psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs == MCDRV_BCKFS_128
++              || psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs == MCDRV_BCKFS_16)
++              {
++                      return MCDRV_ERROR_ARGUMENT;
++              }
++      }
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    CheckDIODIR
++ *
++ *    Description:
++ *                    validate Digital IO DIR parameters.
++ *    Arguments:
++ *                    psDioInfo       digital IO information
++ *                    bPort           port number
++ *                    bInterface      Interface(DA/PCM)
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++static SINT32 CheckDIODIR
++(
++      const MCDRV_DIO_INFO*   psDioInfo,
++      UINT8   bPort,
++      UINT8   bInterface
++)
++{
++
++      if(bInterface == MCDRV_DIO_PCM)
++      {
++              if(psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bLaw == MCDRV_PCM_ALAW
++              || psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bLaw == MCDRV_PCM_MULAW)
++              {
++                      if(psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_13
++                      || psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_14
++                      || psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_16)
++                      {
++                              return MCDRV_ERROR_ARGUMENT;
++                      }
++              }
++      }
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    CheckDIDIT
++ *
++ *    Description:
++ *                    validate Digital IO DIT parameters.
++ *    Arguments:
++ *                    psDioInfo       digital IO information
++ *                    bPort           port number
++ *                    bInterface      Interface(DA/PCM)
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *
++ ****************************************************************************/
++static SINT32 CheckDIODIT
++(
++      const MCDRV_DIO_INFO*   psDioInfo,
++      UINT8   bPort,
++      UINT8   bInterface
++)
++{
++
++      if(bInterface == MCDRV_DIO_PCM)
++      {
++              if(psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bLaw == MCDRV_PCM_ALAW
++              || psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bLaw == MCDRV_PCM_MULAW)
++              {
++                      if(psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_13
++                      || psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_14
++                      || psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_16)
++                      {
++                              return MCDRV_ERROR_ARGUMENT;
++                      }
++              }
++      }
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    SetVol
++ *
++ *    Description:
++ *                    set volume.
++ *    Arguments:
++ *                    dUpdate         target volume items
++ *                    eMode           update mode
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *
++ ****************************************************************************/
++static SINT32 SetVol
++(
++      UINT32                                  dUpdate,
++      MCDRV_VOLUPDATE_MODE_AA eMode
++)
++{
++      SINT32  sdRet   = McPacket_AddVol_AA(dUpdate, eMode);
++      if(sdRet != MCDRV_SUCCESS)
++      {
++              return sdRet;
++      }
++      return McDevIf_ExecutePacket_AA();
++}
++
++/****************************************************************************
++ *    PreUpdatePath
++ *
++ *    Description:
++ *                    Preprocess update path.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *
++ ****************************************************************************/
++static        SINT32  PreUpdatePath
++(
++void
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bReg    = 0;
++      UINT8   bReadReg= 0;
++      UINT16  wDACMuteParam   = 0;
++      UINT16  wDITMuteParam   = 0;
++      UINT8   bLAT    = 0;
++
++      switch(McResCtrl_GetDACSource_AA(eMCDRV_DAC_MASTER_AA))
++      {
++      case    eMCDRV_SRC_PDM_AA:
++              bReg    = MCB_AA_DAC_SOURCE_AD;
++              break;
++      case    eMCDRV_SRC_ADC0_AA:
++              bReg    = MCB_AA_DAC_SOURCE_AD;
++              break;
++      case    eMCDRV_SRC_DIR0_AA:
++              bReg    = MCB_AA_DAC_SOURCE_DIR0;
++              break;
++      case    eMCDRV_SRC_DIR1_AA:
++              bReg    = MCB_AA_DAC_SOURCE_DIR1;
++              break;
++      case    eMCDRV_SRC_DIR2_AA:
++              bReg    = MCB_AA_DAC_SOURCE_DIR2;
++              break;
++      case    eMCDRV_SRC_MIX_AA:
++              bReg    = MCB_AA_DAC_SOURCE_MIX;
++              break;
++      default:
++              bReg    = 0;
++      }
++      bReadReg        = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_SOURCE);
++      if((bReadReg & 0xF0) != 0 && bReg != (bReadReg & 0xF0))
++      {/*     DAC source changed      */
++              if((McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_MASTER_OUTL)&MCB_AA_MASTER_OUTL) != 0)
++              {
++                      if(McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_MASTER_OUTR) != 0)
++                      {
++                              bLAT    = MCB_AA_MASTER_OLAT;
++                      }
++                      else
++                      {
++                              bLAT    = 0;
++                      }
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_MASTER_OUTL, bLAT);
++              }
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_MASTER_OUTR, 0);
++              wDACMuteParam   |= (UINT16)(MCB_AA_MASTER_OFLAGL<<8);
++              wDACMuteParam   |= MCB_AA_MASTER_OFLAGR;
++      }
++
++      switch(McResCtrl_GetDACSource_AA(eMCDRV_DAC_VOICE_AA))
++      {
++      case    eMCDRV_SRC_PDM_AA:
++              bReg    = MCB_AA_VOICE_SOURCE_AD;
++              break;
++      case    eMCDRV_SRC_ADC0_AA:
++              bReg    = MCB_AA_VOICE_SOURCE_AD;
++              break;
++      case    eMCDRV_SRC_DIR0_AA:
++              bReg    = MCB_AA_VOICE_SOURCE_DIR0;
++              break;
++      case    eMCDRV_SRC_DIR1_AA:
++              bReg    = MCB_AA_VOICE_SOURCE_DIR1;
++              break;
++      case    eMCDRV_SRC_DIR2_AA:
++              bReg    = MCB_AA_VOICE_SOURCE_DIR2;
++              break;
++      case    eMCDRV_SRC_MIX_AA:
++              bReg    = MCB_AA_VOICE_SOURCE_MIX;
++              break;
++      default:
++              bReg    = 0;
++      }
++      if((bReadReg & 0x0F) != 0 && bReg != (bReadReg & 0x0F))
++      {/*     VOICE source changed    */
++              if((McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_VOICE_ATTL)&MCB_AA_VOICE_ATTL) != 0)
++              {
++                      if(McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_VOICE_ATTR) != 0)
++                      {
++                              bLAT    = MCB_AA_VOICE_LAT;
++                      }
++                      else
++                      {
++                              bLAT    = 0;
++                      }
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_VOICE_ATTL, bLAT);
++              }
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_VOICE_ATTR, 0);
++              wDACMuteParam   |= (UINT16)(MCB_AA_VOICE_FLAGL<<8);
++              wDACMuteParam   |= MCB_AA_VOICE_FLAGR;
++      }
++
++      switch(McResCtrl_GetDITSource_AA(eMCDRV_DIO_0_AA))
++      {
++      case    eMCDRV_SRC_PDM_AA:
++              bReg    = MCB_AA_DIT0_SOURCE_AD;
++              break;
++      case    eMCDRV_SRC_ADC0_AA:
++              bReg    = MCB_AA_DIT0_SOURCE_AD;
++              break;
++      case    eMCDRV_SRC_DIR0_AA:
++              bReg    = MCB_AA_DIT0_SOURCE_DIR0;
++              break;
++      case    eMCDRV_SRC_DIR1_AA:
++              bReg    = MCB_AA_DIT0_SOURCE_DIR1;
++              break;
++      case    eMCDRV_SRC_DIR2_AA:
++              bReg    = MCB_AA_DIT0_SOURCE_DIR2;
++              break;
++      case    eMCDRV_SRC_MIX_AA:
++              bReg    = MCB_AA_DIT0_SOURCE_MIX;
++              break;
++      default:
++              bReg    = 0;
++      }
++      bReadReg        = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_SRC_SOURCE);
++      if((bReadReg & 0xF0) != 0 && bReg != (bReadReg & 0xF0))
++      {/*     DIT source changed      */
++              if((McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIT0_INVOLL)&MCB_AA_DIT0_INVOLL) != 0)
++              {
++                      if(McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIT0_INVOLR) != 0)
++                      {
++                              bLAT    = MCB_AA_DIT0_INLAT;
++                      }
++                      else
++                      {
++                              bLAT    = 0;
++                      }
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIT0_INVOLL, bLAT);
++              }
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIT0_INVOLR, 0);
++              wDITMuteParam   |= (UINT16)(MCB_AA_DIT0_INVFLAGL<<8);
++              wDITMuteParam   |= MCB_AA_DIT0_INVFLAGR;
++      }
++
++      switch(McResCtrl_GetDITSource_AA(eMCDRV_DIO_1_AA))
++      {
++      case    eMCDRV_SRC_PDM_AA:
++              bReg    = MCB_AA_DIT1_SOURCE_AD;
++              break;
++      case    eMCDRV_SRC_ADC0_AA:
++              bReg    = MCB_AA_DIT1_SOURCE_AD;
++              break;
++      case    eMCDRV_SRC_DIR0_AA:
++              bReg    = MCB_AA_DIT1_SOURCE_DIR0;
++              break;
++      case    eMCDRV_SRC_DIR1_AA:
++              bReg    = MCB_AA_DIT1_SOURCE_DIR1;
++              break;
++      case    eMCDRV_SRC_DIR2_AA:
++              bReg    = MCB_AA_DIT1_SOURCE_DIR2;
++              break;
++      case    eMCDRV_SRC_MIX_AA:
++              bReg    = MCB_AA_DIT1_SOURCE_MIX;
++              break;
++      default:
++              bReg    = 0;
++      }
++      if((bReadReg & 0x0F) != 0 && bReg != (bReadReg & 0x0F))
++      {/*     DIT source changed      */
++              if((McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIT1_INVOLL)&MCB_AA_DIT1_INVOLL) != 0)
++              {
++                      if(McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIT1_INVOLR) != 0)
++                      {
++                              bLAT    = MCB_AA_DIT1_INLAT;
++                      }
++                      else
++                      {
++                              bLAT    = 0;
++                      }
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIT1_INVOLL, bLAT);
++              }
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIT1_INVOLR, 0);
++              wDITMuteParam   |= (UINT16)(MCB_AA_DIT1_INVFLAGL<<8);
++              wDITMuteParam   |= MCB_AA_DIT1_INVFLAGR;
++      }
++
++      switch(McResCtrl_GetDITSource_AA(eMCDRV_DIO_2_AA))
++      {
++      case    eMCDRV_SRC_PDM_AA:
++              bReg    = MCB_AA_DIT2_SOURCE_AD;
++              break;
++      case    eMCDRV_SRC_ADC0_AA:
++              bReg    = MCB_AA_DIT2_SOURCE_AD;
++              break;
++      case    eMCDRV_SRC_DIR0_AA:
++              bReg    = MCB_AA_DIT2_SOURCE_DIR0;
++              break;
++      case    eMCDRV_SRC_DIR1_AA:
++              bReg    = MCB_AA_DIT2_SOURCE_DIR1;
++              break;
++      case    eMCDRV_SRC_DIR2_AA:
++              bReg    = MCB_AA_DIT2_SOURCE_DIR2;
++              break;
++      case    eMCDRV_SRC_MIX_AA:
++              bReg    = MCB_AA_DIT2_SOURCE_MIX;
++              break;
++      default:
++              bReg    = 0;
++      }
++      bReadReg        = McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_SRC_SOURCE_1);
++      if((bReadReg & 0x0F) != 0 && bReg != (bReadReg & 0x0F))
++      {/*     DIT source changed      */
++              if((McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIT2_INVOLL)&MCB_AA_DIT2_INVOLL) != 0)
++              {
++                      if(McResCtrl_GetRegVal_AA(MCDRV_PACKET_REGTYPE_B_MIXER_AA, MCI_AA_DIT2_INVOLR) != 0)
++                      {
++                              bLAT    = MCB_AA_DIT2_INLAT;
++                      }
++                      else
++                      {
++                              bLAT    = 0;
++                      }
++                      McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIT2_INVOLL, bLAT);
++              }
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_WRITE_AA | MCDRV_PACKET_REGTYPE_B_MIXER_AA | MCI_AA_DIT2_INVOLR, 0);
++              wDITMuteParam   |= (UINT16)(MCB_AA_DIT2_INVFLAGL<<8);
++              wDITMuteParam   |= MCB_AA_DIT2_INVFLAGR;
++      }
++
++      sdRet   = McDevIf_ExecutePacket_AA();
++      if(sdRet != MCDRV_SUCCESS)
++      {
++              return sdRet;
++      }
++
++      if(wDACMuteParam != 0)
++      {
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_EVTWAIT_AA | MCDRV_EVT_DACMUTE_AA | wDACMuteParam, 0);
++      }
++      if(wDITMuteParam != 0)
++      {
++              McDevIf_AddPacket_AA(MCDRV_PACKET_TYPE_EVTWAIT_AA | MCDRV_EVT_DITMUTE_AA | wDITMuteParam, 0);
++      }
++      /*      do not Execute & Clear  */
++      return MCDRV_SUCCESS;
++}
++
++/****************************************************************************
++ *    McDrv_Ctrl
++ *
++ *    Description:
++ *                    MC Driver I/F function.
++ *    Arguments:
++ *                    dCmd            command #
++ *                    pvPrm           parameter
++ *                    dPrm            update info
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_ARGUMENT
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *                    MCDRV_ERROR_STATE
++ *
++ ****************************************************************************/
++SINT32        McDrv_Ctrl_AA
++(
++      UINT32  dCmd,
++      void*   pvPrm,
++      UINT32  dPrm
++)
++{
++      SINT32  sdRet   = MCDRV_ERROR;
++
++      switch(dCmd)
++      {
++      case    MCDRV_INIT:     return init((MCDRV_INIT_INFO*)pvPrm);
++      case    MCDRV_TERM:     return term();
++      default:                        break;
++      }
++
++      McSrv_Lock();
++
++      switch (dCmd)
++      {
++      case    MCDRV_UPDATE_CLOCK:
++              sdRet   = update_clock((MCDRV_CLOCK_INFO*)pvPrm);
++              break;
++      case    MCDRV_GET_PATH:
++              sdRet   = get_path((MCDRV_PATH_INFO*)pvPrm);
++              break;
++      case    MCDRV_SET_PATH:
++              sdRet   = set_path((MCDRV_PATH_INFO*)pvPrm);
++              break;
++      case    MCDRV_GET_VOLUME:
++              sdRet   = get_volume((MCDRV_VOL_INFO*)pvPrm);
++              break;
++      case    MCDRV_SET_VOLUME:
++              sdRet   = set_volume((MCDRV_VOL_INFO*)pvPrm);
++              break;
++      case    MCDRV_GET_DIGITALIO:
++              sdRet   = get_digitalio((MCDRV_DIO_INFO*)pvPrm);
++              break;
++      case    MCDRV_SET_DIGITALIO:
++              sdRet   = set_digitalio((MCDRV_DIO_INFO*)pvPrm, dPrm);
++              break;
++      case    MCDRV_GET_DAC:
++              sdRet   = get_dac((MCDRV_DAC_INFO*)pvPrm);
++              break;
++      case    MCDRV_SET_DAC:
++              sdRet   = set_dac((MCDRV_DAC_INFO*)pvPrm, dPrm);
++              break;
++      case    MCDRV_GET_ADC:
++              sdRet   = get_adc((MCDRV_ADC_INFO*)pvPrm);
++              break;
++      case    MCDRV_SET_ADC:
++              sdRet   = set_adc((MCDRV_ADC_INFO*)pvPrm, dPrm);
++              break;
++      case    MCDRV_GET_SP:
++              sdRet   = get_sp((MCDRV_SP_INFO*)pvPrm);
++              break;
++      case    MCDRV_SET_SP:
++              sdRet   = set_sp((MCDRV_SP_INFO*)pvPrm);
++              break;
++      case    MCDRV_GET_DNG:
++              sdRet   = get_dng((MCDRV_DNG_INFO*)pvPrm);
++              break;
++      case    MCDRV_SET_DNG:
++              sdRet   = set_dng((MCDRV_DNG_INFO*)pvPrm, dPrm);
++              break;
++      case    MCDRV_SET_AUDIOENGINE:
++              sdRet   = set_ae((MCDRV_AE_INFO*)pvPrm, dPrm);
++              break;
++      case    MCDRV_GET_PDM:
++              sdRet   = get_pdm((MCDRV_PDM_INFO*)pvPrm);
++              break;
++      case    MCDRV_SET_PDM:
++              sdRet   = set_pdm((MCDRV_PDM_INFO*)pvPrm, dPrm);
++              break;
++      case MCDRV_CONFIG_GP:
++              sdRet   = config_gp((MCDRV_GP_MODE*)pvPrm);
++              break;
++      case MCDRV_MASK_GP:
++              sdRet   = mask_gp((UINT8*)pvPrm, dPrm);
++              break;
++      case MCDRV_GETSET_GP:
++              sdRet   = getset_gp((UINT8*)pvPrm, dPrm);
++              break;
++      case MCDRV_READ_REG :
++              sdRet   = read_reg((MCDRV_REG_INFO*)pvPrm);
++              break;
++      case MCDRV_WRITE_REG :
++              sdRet   = write_reg((MCDRV_REG_INFO*)pvPrm);
++              break;
++      case MCDRV_GET_SYSEQ :
++      case MCDRV_SET_SYSEQ :
++              sdRet   = MCDRV_SUCCESS;
++              break;
++
++      case MCDRV_IRQ:
++              break;
++
++      default:
++              break;
++      }
++
++      McSrv_Unlock();
++
++      return sdRet;
++}
+diff --git a/sound/soc/codecs/mc1n2/mcdriver_AA.h b/sound/soc/codecs/mc1n2/mcdriver_AA.h
+new file mode 100644
+index 0000000..f8531d8
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mcdriver_AA.h
+@@ -0,0 +1,25 @@
++/****************************************************************************
++ *
++ *            Copyright(c) 2010 Yamaha Corporation. All rights reserved.
++ *
++ *            Module          : mcdriver_AA.h
++ *
++ *            Description     : MC Driver header
++ *
++ *            Version         : 1.0.0         2010.09.01
++ *
++ ****************************************************************************/
++
++#ifndef _MCDRIVER_AA_H_
++#define _MCDRIVER_AA_H_
++
++#include "mctypedef.h"
++
++
++
++signed long   McDrv_Ctrl_AA( UINT32 dCmd, void* pvPrm, UINT32 dPrm );
++
++
++
++
++#endif /* _MCDRIVER_H_ */
+diff --git a/sound/soc/codecs/mc1n2/mcmachdep.c b/sound/soc/codecs/mc1n2/mcmachdep.c
+new file mode 100644
+index 0000000..eaebc5b
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mcmachdep.c
+@@ -0,0 +1,318 @@
++/****************************************************************************
++ *
++ *            Copyright(c) 2010 Yamaha Corporation. All rights reserved.
++ *
++ *            Module          : mcmachdep.c
++ *
++ *            Description     : machine dependent part for MC Driver
++ *
++ *            Version         : 1.0.0         2010.09.10
++ *
++ ****************************************************************************/
++
++#include <linux/delay.h>
++#include <linux/i2c.h>
++#include <linux/mutex.h>
++#include "mcmachdep.h"
++#include "mc1n2_priv.h"
++#if (MCDRV_DEBUG_LEVEL>=4)
++#include "mcdebuglog.h"
++#endif
++
++static struct mutex McDrv_Mutex;
++static struct i2c_client *McDrv_I2C_Client;
++
++/****************************************************************************
++ *    machdep_SystemInit
++ *
++ *    Description:
++ *                    Initialize the system.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  machdep_SystemInit
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("machdep_SystemInit");
++#endif
++
++      /* Please implement system initialization procedure if need */
++      mutex_init(&McDrv_Mutex);
++      McDrv_I2C_Client = mc1n2_get_i2c_client();
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("machdep_SystemInit", 0);
++#endif
++}
++
++/****************************************************************************
++ *    machdep_SystemTerm
++ *
++ *    Description:
++ *                    Terminate the system.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  machdep_SystemTerm
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("machdep_SystemTerm");
++#endif
++
++      /* Please implement system termination procedure if need */
++      mutex_destroy(&McDrv_Mutex);
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("machdep_SystemTerm", 0);
++#endif
++}
++
++/****************************************************************************
++ *    machdep_ClockStart
++ *
++ *    Description:
++ *                    Start clock.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  machdep_ClockStart
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("machdep_ClockStart");
++#endif
++
++      /* Please implement clock start procedure if need */
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("machdep_ClockStart", 0);
++#endif
++}
++
++/****************************************************************************
++ *    machdep_ClockStop
++ *
++ *    Description:
++ *                    Stop clock.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  machdep_ClockStop
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("machdep_ClockStop");
++#endif
++
++      /* Please implement clock stop procedure if need */
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("machdep_ClockStop", 0);
++#endif
++}
++
++/***************************************************************************
++ *    machdep_WriteI2C
++ *
++ *    Function:
++ *                    Write a byte data to the register.
++ *    Arguments:
++ *                    bSlaveAdr       slave address
++ *                    pbData          byte data for write
++ *                    dSize           byte data length
++ *    Return:
++ *                    None
++ *
++ ****************************************************************************/
++void  machdep_WriteI2C
++(
++      UINT8   bSlaveAdr,
++      const UINT8*    pbData,
++      UINT32  dSize
++)
++{
++      int count;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("machdep_WriteI2C");
++#endif
++
++      /* Please implement register write procedure */
++      count = i2c_master_send(McDrv_I2C_Client, pbData, dSize);
++      if (count != dSize) {
++              dev_err(&McDrv_I2C_Client->dev, "I2C write error\n");
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("machdep_WriteI2C", 0);
++#endif
++}
++
++/***************************************************************************
++ *    machdep_ReadI2C
++ *
++ *    Function:
++ *                    Read a byte data from the register.
++ *    Arguments:
++ *                    bSlaveAdr       slave address
++ *                    dAddress        address of register
++ *    Return:
++ *                    read data
++ *
++ ****************************************************************************/
++UINT8 machdep_ReadI2C
++(
++      UINT8   bSlaveAdr,
++      UINT32  dAddress
++)
++{
++      UINT8   bData;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("machdep_ReadI2C");
++#endif
++
++      /* Please implement register read procedure */
++      bData = mc1n2_i2c_read_byte(McDrv_I2C_Client, dAddress);
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = (SINT32)bData;
++      McDebugLog_FuncOut("machdep_ReadI2C", &sdRet);
++#endif
++
++      return bData;
++}
++
++/****************************************************************************
++ *    machdep_Sleep
++ *
++ *    Function:
++ *                    Sleep for a specified interval.
++ *    Arguments:
++ *                    dSleepTime      sleep time [us]
++ *    Return:
++ *                    None
++ *
++ ****************************************************************************/
++void  machdep_Sleep
++(
++      UINT32  dSleepTime
++)
++{
++      unsigned long ms = dSleepTime / 1000;
++      unsigned long us = dSleepTime % 1000;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("machdep_Sleep");
++#endif
++
++      /* Please implement sleep procedure */
++      if (us)
++              udelay(us);
++      if (ms)
++              msleep(ms);
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("machdep_Sleep", 0);
++#endif
++}
++
++/***************************************************************************
++ *    machdep_Lock
++ *
++ *    Function:
++ *                    Lock a call of the driver.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  machdep_Lock
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("machdep_Lock");
++#endif
++
++      /* Please implement lock procedure */
++      mutex_lock(&McDrv_Mutex);
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("machdep_Lock", 0);
++#endif
++}
++
++/***************************************************************************
++ *    machdep_Unlock
++ *
++ *    Function:
++ *                    Unlock a call of the driver.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  machdep_Unlock
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("machdep_Unlock");
++#endif
++
++      /* Please implement unlock procedure */
++      mutex_unlock(&McDrv_Mutex);
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("machdep_Unlock", 0);
++#endif
++}
++
++/***************************************************************************
++ *    machdep_DebugPrint
++ *
++ *    Function:
++ *                    Output debug log.
++ *    Arguments:
++ *                    pbLogString     log string buffer pointer
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  machdep_DebugPrint
++(
++      UINT8*  pbLogString
++)
++{
++      /* Please implement debug output procedure */
++      pr_debug("MCDRV: %s\n", pbLogString);
++}
++
+diff --git a/sound/soc/codecs/mc1n2/mcmachdep.h b/sound/soc/codecs/mc1n2/mcmachdep.h
+new file mode 100644
+index 0000000..ea62018
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mcmachdep.h
+@@ -0,0 +1,34 @@
++/****************************************************************************
++ *
++ *            Copyright(c) 2010 Yamaha Corporation. All rights reserved.
++ *
++ *            Module          : mcmachdep.h
++ *
++ *            Description     : MC Driver machine dependent part header
++ *
++ *            Version         : 1.0.0         2010.09.10
++ *
++ ****************************************************************************/
++
++#ifndef _MCMACHDEP_H_
++#define _MCMACHDEP_H_
++
++#include "mctypedef.h"
++
++
++#define       MCDRV_DEBUG_LEVEL       (0)
++
++
++void  machdep_SystemInit      ( void );
++void  machdep_SystemTerm      ( void );
++void  machdep_ClockStart      ( void );
++void  machdep_ClockStop       ( void );
++void  machdep_WriteI2C        ( UINT8 bSlaveAdr, const UINT8 *pbData, UINT32 dSize );
++UINT8 machdep_ReadI2C         ( UINT8 bSlaveAdr, UINT32 dAddress );
++void  machdep_Sleep           ( UINT32 dSleepTime );
++void  machdep_Lock            ( void );
++void  machdep_Unlock          ( void );
++void  machdep_DebugPrint      ( UINT8 *pbLogString );
++
++
++#endif /* _MCMACHDEP_H_ */
+diff --git a/sound/soc/codecs/mc1n2/mcpacking.c b/sound/soc/codecs/mc1n2/mcpacking.c
+new file mode 100644
+index 0000000..89651c5
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mcpacking.c
+@@ -0,0 +1,4710 @@
++/****************************************************************************
++ *
++ *            Copyright(c) 2010 Yamaha Corporation. All rights reserved.
++ *
++ *            Module          : mcpacking.c
++ *
++ *            Description     : MC Driver packet packing control
++ *
++ *            Version         : 1.0.0         2010.09.10
++ *
++ ****************************************************************************/
++
++
++#include "mcpacking.h"
++#include "mcdevif.h"
++#include "mcresctrl.h"
++#include "mcdefs.h"
++#include "mcdevprof.h"
++#include "mcservice.h"
++#include "mcmachdep.h"
++#if MCDRV_DEBUG_LEVEL
++#include "mcdebuglog.h"
++#endif
++
++
++
++#define       MCDRV_TCXO_WAIT_TIME    ((UINT32)2000)
++#define       MCDRV_PLRST_WAIT_TIME   ((UINT32)2000)
++#define       MCDRV_LDOA_WAIT_TIME    ((UINT32)1000)
++#define       MCDRV_SP_WAIT_TIME              ((UINT32)150)
++#define       MCDRV_HP_WAIT_TIME              ((UINT32)300)
++#define       MCDRV_RC_WAIT_TIME              ((UINT32)150)
++
++/* SrcRate default */
++#define       MCDRV_DIR_SRCRATE_48000 (32768)
++#define       MCDRV_DIR_SRCRATE_44100 (30106)
++#define       MCDRV_DIR_SRCRATE_32000 (21845)
++#define       MCDRV_DIR_SRCRATE_24000 (16384)
++#define       MCDRV_DIR_SRCRATE_22050 (15053)
++#define       MCDRV_DIR_SRCRATE_16000 (10923)
++#define       MCDRV_DIR_SRCRATE_12000 (8192)
++#define       MCDRV_DIR_SRCRATE_11025 (7526)
++#define       MCDRV_DIR_SRCRATE_8000  (5461)
++
++#define       MCDRV_DIT_SRCRATE_48000 (4096)
++#define       MCDRV_DIT_SRCRATE_44100 (4458)
++#define       MCDRV_DIT_SRCRATE_32000 (6144)
++#define       MCDRV_DIT_SRCRATE_24000 (8192)
++#define       MCDRV_DIT_SRCRATE_22050 (8916)
++#define       MCDRV_DIT_SRCRATE_16000 (12288)
++#define       MCDRV_DIT_SRCRATE_12000 (16384)
++#define       MCDRV_DIT_SRCRATE_11025 (17833)
++#define       MCDRV_DIT_SRCRATE_8000  (24576)
++
++static SINT32 AddAnalogPowerUpAuto(const MCDRV_POWER_INFO* psPowerInfo, const MCDRV_POWER_UPDATE* psPowerUpdate);
++
++static void           AddDIPad(void);
++static void           AddPAD(void);
++static SINT32 AddSource(void);
++static void           AddDIStart(void);
++static UINT8  GetMicMixBit(const MCDRV_CHANNEL* psChannel);
++static void           AddDigVolPacket(UINT8 bVolL, UINT8 bVolR, UINT8 bVolLAddr, UINT8 bLAT, UINT8 bVolRAddr, MCDRV_VOLUPDATE_MODE eMode);
++static void           AddStopADC(void);
++static void           AddStopPDM(void);
++static UINT8  IsModifiedDIO(UINT32 dUpdateInfo);
++static UINT8  IsModifiedDIOCommon(MCDRV_DIO_PORT_NO ePort);
++static UINT8  IsModifiedDIODIR(MCDRV_DIO_PORT_NO ePort);
++static UINT8  IsModifiedDIODIT(MCDRV_DIO_PORT_NO ePort);
++static void           AddDIOCommon(MCDRV_DIO_PORT_NO ePort);
++static void           AddDIODIR(MCDRV_DIO_PORT_NO ePort);
++static void           AddDIODIT(MCDRV_DIO_PORT_NO ePort);
++
++#define       MCDRV_DPB_KEEP  0
++#define       MCDRV_DPB_UP    1
++static SINT32 PowerUpDig(UINT8 bDPBUp);
++
++static UINT32 GetMaxWait(UINT8 bRegChange);
++
++/****************************************************************************
++ *    McPacket_AddInit
++ *
++ *    Description:
++ *                    Add initialize packet.
++ *    Arguments:
++ *                    psInitInfo              information for initialization
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddInit
++(
++      const MCDRV_INIT_INFO*  psInitInfo
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bReg;
++      MCDRV_POWER_INFO        sPowerInfo;
++      MCDRV_POWER_UPDATE      sPowerUpdate;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McPacket_AddInit");
++#endif
++
++
++      /*      RSTA    */
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_FORCE_WRITE | MCDRV_PACKET_REGTYPE_A | (UINT32)MCI_RST, MCB_RST);
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_FORCE_WRITE | MCDRV_PACKET_REGTYPE_A | (UINT32)MCI_RST, 0);
++
++      /*      ANA_RST */
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_FORCE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_ANA_RST, MCI_ANA_RST_DEF);
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_FORCE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_ANA_RST, 0);
++
++      /*      SDIN_MSK*, SDO_DDR*     */
++      bReg    = MCB_SDIN_MSK2;
++      if(psInitInfo->bDioSdo2Hiz == MCDRV_DAHIZ_LOW)
++      {
++              bReg |= MCB_SDO_DDR2;
++      }
++      bReg |= MCB_SDIN_MSK1;
++      if(psInitInfo->bDioSdo1Hiz == MCDRV_DAHIZ_LOW)
++      {
++              bReg |= MCB_SDO_DDR1;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_SD_MSK, bReg);
++
++      bReg    = MCB_SDIN_MSK0;
++      if(psInitInfo->bDioSdo0Hiz == MCDRV_DAHIZ_LOW)
++      {
++              bReg |= MCB_SDO_DDR0;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_SD_MSK_1, bReg);
++
++      /*      BCLK_MSK*, BCLD_DDR*, LRCK_MSK*, LRCK_DDR*, PCM_HIZ*    */
++      bReg    = 0;
++      bReg |= MCB_BCLK_MSK2;
++      bReg |= MCB_LRCK_MSK2;
++      if(psInitInfo->bDioClk2Hiz == MCDRV_DAHIZ_LOW)
++      {
++              bReg |= MCB_BCLK_DDR2;
++              bReg |= MCB_LRCK_DDR2;
++      }
++      bReg |= MCB_BCLK_MSK1;
++      bReg |= MCB_LRCK_MSK1;
++      if(psInitInfo->bDioClk1Hiz == MCDRV_DAHIZ_LOW)
++      {
++              bReg |= MCB_BCLK_DDR1;
++              bReg |= MCB_LRCK_DDR1;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_BCLK_MSK, bReg);
++
++      bReg    = 0;
++      bReg |= MCB_BCLK_MSK0;
++      bReg |= MCB_LRCK_MSK0;
++      if(psInitInfo->bDioClk0Hiz == MCDRV_DAHIZ_LOW)
++      {
++              bReg |= MCB_BCLK_DDR0;
++              bReg |= MCB_LRCK_DDR0;
++      }
++      if(psInitInfo->bPcmHiz == MCDRV_PCMHIZ_HIZ)
++      {
++              bReg |= (MCB_PCMOUT_HIZ2 | MCB_PCMOUT_HIZ1 | MCB_PCMOUT_HIZ0);
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_BCLK_MSK_1, bReg);
++
++      /*      DI*_BCKP        */
++
++      /*      PA*_MSK, PA*_DDR        */
++      bReg    = MCI_PA_MSK_DEF;
++      if(psInitInfo->bPad0Func == MCDRV_PAD_PDMCK)
++      {
++              bReg    |= MCB_PA0_DDR;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_PA_MSK, bReg);
++
++      /*      PA0_OUT */
++      if(psInitInfo->bPad0Func == MCDRV_PAD_PDMCK)
++      {
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_PA_OUT, MCB_PA_OUT);
++      }
++
++      /*      SCU_PA* */
++
++      /*      CKSEL   */
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_CKSEL, psInitInfo->bCkSel);
++
++      /*      DIVR0, DIVF0    */
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DIVR0, psInitInfo->bDivR0);
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DIVF0, psInitInfo->bDivF0);
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DIVR1, psInitInfo->bDivR1);
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DIVF1, psInitInfo->bDivF1);
++
++      /*      Clock Start     */
++      sdRet   = McDevIf_ExecutePacket();
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              McSrv_ClockStart();
++
++              /*      DP0     */
++              bReg    = MCI_DPADIF_DEF & (UINT8)~MCB_DP0_CLKI0;
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DPADIF, bReg);
++              if(psInitInfo->bCkSel != MCDRV_CKSEL_CMOS)
++              {
++                      /*      2ms wait        */
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_TIMWAIT | MCDRV_TCXO_WAIT_TIME, 0);
++              }
++
++              /*      PLLRST0 */
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_PLL_RST, 0);
++              /*      2ms wait        */
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_TIMWAIT | MCDRV_PLRST_WAIT_TIME, 0);
++              /*      DP1/DP2 up      */
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_PWM_DIGITAL, 0);
++              /*      RSTB    */
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_RSTB, 0);
++              /*      DPB     */
++              bReg    = MCB_PWM_DPPDM|MCB_PWM_DPDI2|MCB_PWM_DPDI1|MCB_PWM_DPDI0;
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_PWM_DIGITAL_1, bReg);
++
++              /*      DCL_GAIN, DCL_LMT       */
++              bReg    = (psInitInfo->bDclGain<<4) | psInitInfo->bDclLimit;
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DCL, bReg);
++
++              /*      DIF_LI, DIF_LO* */
++              bReg    = (psInitInfo->bLineOut2Dif<<5) | (psInitInfo->bLineOut1Dif<<4) | psInitInfo->bLineIn1Dif;
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_DIF_LINE, bReg);
++
++              /*      SP*_HIZ, SPMN   */
++              bReg    = (psInitInfo->bSpmn << 1);
++              if(MCDRV_SPHIZ_HIZ == psInitInfo->bSpHiz)
++              {
++                      bReg    |= (MCB_SPL_HIZ|MCB_SPR_HIZ);
++              }
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_SP_MODE, bReg);
++
++              /*      MC*SNG  */
++              bReg    = (psInitInfo->bMic2Sng<<6) | (psInitInfo->bMic1Sng<<2);
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_MC_GAIN, bReg);
++              bReg    = (psInitInfo->bMic3Sng<<2);
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_MC3_GAIN, bReg);
++
++              /*      CPMOD   */
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_CPMOD, psInitInfo->bCpMod);
++
++              /*      AVDDLEV, VREFLEV        */
++              bReg    = 0x20 | psInitInfo->bAvddLev;
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_LEV, bReg);
++
++              if(((psInitInfo->bPowerMode & MCDRV_POWMODE_VREFON) != 0) || (McResCtrl_GetAPMode() == eMCDRV_APM_OFF))
++              {
++                      bReg    = MCI_PWM_ANALOG_0_DEF;
++                      if(psInitInfo->bLdo == MCDRV_LDO_ON)
++                      {
++                              /*      AP_LDOA */
++                              bReg    &= (UINT8)~MCB_PWM_LDOA;
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_0, bReg);
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_TIMWAIT | MCDRV_LDOA_WAIT_TIME, 0);
++                      }
++                      else
++                      {
++                              bReg    &= (UINT8)~MCB_PWM_REFA;
++                      }
++                      /*      AP_VR up        */
++                      bReg    &= (UINT8)~MCB_PWM_VR;
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_0, bReg);
++                      sdRet   = McDevIf_ExecutePacket();
++                      if(sdRet == MCDRV_SUCCESS)
++                      {
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_TIMWAIT | psInitInfo->sWaitTime.dVrefRdy2, 0);
++                      }
++              }
++      }
++
++      if(MCDRV_SUCCESS == sdRet)
++      {
++              if(McResCtrl_GetAPMode() == eMCDRV_APM_OFF)
++              {
++                      bReg    = MCB_APMOFF_SP|MCB_APMOFF_HP|MCB_APMOFF_RC;
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_APMOFF, bReg);
++              }
++              sdRet   = McDevIf_ExecutePacket();
++      }
++      if(MCDRV_SUCCESS == sdRet)
++      {
++              /*      unused path power down  */
++              McResCtrl_GetPowerInfo(&sPowerInfo);
++              sPowerUpdate.dDigital           = MCDRV_POWUPDATE_DIGITAL_ALL;
++              sPowerUpdate.abAnalog[0]        = (UINT8)MCDRV_POWUPDATE_ANALOG0_ALL;
++              sPowerUpdate.abAnalog[1]        = (UINT8)MCDRV_POWUPDATE_ANALOG1_ALL;
++              sPowerUpdate.abAnalog[2]        = (UINT8)MCDRV_POWUPDATE_ANALOG2_ALL;
++              sPowerUpdate.abAnalog[3]        = (UINT8)MCDRV_POWUPDATE_ANALOG3_ALL;
++              sPowerUpdate.abAnalog[4]        = (UINT8)MCDRV_POWUPDATE_ANALOG4_ALL;
++              sdRet   = McPacket_AddPowerDown(&sPowerInfo, &sPowerUpdate);
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McPacket_AddInit", &sdRet);
++#endif
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    McPacket_AddPowerUp
++ *
++ *    Description:
++ *                    Add powerup packet.
++ *    Arguments:
++ *                    psPowerInfo             power information
++ *                    psPowerUpdate   power update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddPowerUp
++(
++      const MCDRV_POWER_INFO*         psPowerInfo,
++      const MCDRV_POWER_UPDATE*       psPowerUpdate
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bReg;
++      UINT8   bRegDPADIF;
++      UINT8   bRegCur;
++      UINT8   bRegAna1;
++      UINT8   bRegAna2;
++      UINT32  dUpdate;
++      UINT8   bRegChange;
++      UINT8   bSpHizReg;
++      UINT32  dWaitTime;
++      UINT32  dWaitTimeDone   = 0;
++      UINT8   bWaitVREFRDY    = 0;
++      UINT8   bWaitHPVolUp    = 0;
++      UINT8   bWaitSPVolUp    = 0;
++      MCDRV_INIT_INFO         sInitInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McPacket_AddPowerUp");
++#endif
++
++      bRegDPADIF      = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_CODEC, MCI_DPADIF);
++
++
++      McResCtrl_GetInitInfo(&sInitInfo);
++
++      /*      Digital Power   */
++      dUpdate = ~psPowerInfo->dDigital & psPowerUpdate->dDigital;
++      if((dUpdate & MCDRV_POWINFO_DIGITAL_DP0) != 0UL)
++      {
++              if((bRegDPADIF & (MCB_DP0_CLKI1|MCB_DP0_CLKI0)) == (MCB_DP0_CLKI1|MCB_DP0_CLKI0))
++              {/*     DP0 changed     */
++                      /*      CKSEL   */
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_CKSEL, sInitInfo.bCkSel);
++                      /*      DIVR0, DIVF0    */
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DIVR0, sInitInfo.bDivR0);
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DIVF0, sInitInfo.bDivF0);
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DIVR1, sInitInfo.bDivR1);
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DIVF1, sInitInfo.bDivF1);
++                      sdRet   = McDevIf_ExecutePacket();
++                      if(sdRet == MCDRV_SUCCESS)
++                      {
++                              /*      Clock Start     */
++                              McSrv_ClockStart();
++                              /*      DP0 up  */
++                              if((((bRegDPADIF & MCB_CLKSRC) == 0) && ((bRegDPADIF & MCB_CLKINPUT) == 0))
++                              || (((bRegDPADIF & MCB_CLKSRC) != 0) && ((bRegDPADIF & MCB_CLKINPUT) != 0)))
++                              {
++                                      bRegDPADIF      &= (UINT8)~MCB_DP0_CLKI0;
++                              }
++                              else
++                              {
++                                      bRegDPADIF      &= (UINT8)~MCB_DP0_CLKI1;
++                              }
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DPADIF, bRegDPADIF);
++                              if(sInitInfo.bCkSel != MCDRV_CKSEL_CMOS)
++                              {
++                                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_TIMWAIT | MCDRV_TCXO_WAIT_TIME, 0);
++                              }
++                              /*      PLLRST0 up      */
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_PLL_RST, 0);
++                              /*      2ms wait        */
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_TIMWAIT | MCDRV_PLRST_WAIT_TIME, 0);
++                              sdRet   = McDevIf_ExecutePacket();
++                              if(sdRet == MCDRV_SUCCESS)
++                              {
++                                      /*      DP1/DP2 up      */
++                                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_PWM_DIGITAL, 0);
++                                      /*      DPB/DPDI* up    */
++                                      bReg    = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_BASE, MCI_PWM_DIGITAL_1);
++                                      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPDI0) != 0UL)
++                                      {
++                                              bReg    &= (UINT8)~MCB_PWM_DPDI0;
++                                      }
++                                      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPDI1) != 0UL)
++                                      {
++                                              bReg    &= (UINT8)~MCB_PWM_DPDI1;
++                                      }
++                                      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPDI2) != 0UL)
++                                      {
++                                              bReg    &= (UINT8)~MCB_PWM_DPDI2;
++                                      }
++                                      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPPDM) != 0UL)
++                                      {
++                                              bReg    &= (UINT8)~MCB_PWM_DPPDM;
++                                      }
++                                      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPB) != 0UL)
++                                      {
++                                              bReg    &= (UINT8)~MCB_PWM_DPB;
++                                      }
++                                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_PWM_DIGITAL_1, bReg);
++                              }
++                      }
++              }
++              else if((dUpdate & MCDRV_POWINFO_DIGITAL_DP2) != 0UL)
++              {
++                      /*      DP1/DP2 up      */
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_PWM_DIGITAL, 0);
++                      /*      DPB/DPDI* up    */
++                      bReg    = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_BASE, MCI_PWM_DIGITAL_1);
++                      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPDI0) != 0UL)
++                      {
++                              bReg    &= (UINT8)~MCB_PWM_DPDI0;
++                      }
++                      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPDI1) != 0UL)
++                      {
++                              bReg    &= (UINT8)~MCB_PWM_DPDI1;
++                      }
++                      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPDI2) != 0UL)
++                      {
++                              bReg    &= (UINT8)~MCB_PWM_DPDI2;
++                      }
++                      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPPDM) != 0UL)
++                      {
++                              bReg    &= (UINT8)~MCB_PWM_DPPDM;
++                      }
++                      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPB) != 0UL)
++                      {
++                              bReg    &= (UINT8)~MCB_PWM_DPB;
++                      }
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_PWM_DIGITAL_1, bReg);
++              }
++              else
++              {
++              }
++
++              if(sdRet == MCDRV_SUCCESS)
++              {
++                      /*      DPBDSP  */
++                      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPBDSP) != 0UL)
++                      {
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_PWM_DIGITAL_BDSP, 0);
++                      }
++                      /*      DPADIF  */
++                      if((dUpdate & MCDRV_POWINFO_DIGITAL_DPADIF) != 0UL)
++                      {
++                              bRegDPADIF      = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_CODEC, MCI_DPADIF);
++                              bRegDPADIF      &= (UINT8)~MCB_DPADIF;
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DPADIF, bRegDPADIF);
++                      }
++              }
++      }
++
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              if(McResCtrl_GetAPMode() == eMCDRV_APM_ON)
++              {
++                      sdRet   = AddAnalogPowerUpAuto(psPowerInfo, psPowerUpdate);
++              }
++              else
++              {
++                      /*      Analog Power    */
++                      dUpdate = (UINT32)~psPowerInfo->abAnalog[0] & (UINT32)psPowerUpdate->abAnalog[0];
++                      if((dUpdate & (UINT32)MCB_PWM_VR) != 0UL)
++                      {
++                              if((McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_PWM_ANALOG_0) & MCB_PWM_VR) != 0)
++                              {/*     AP_VR changed   */
++                                      bReg    = MCI_PWM_ANALOG_0_DEF;
++                                      if(sInitInfo.bLdo == MCDRV_LDO_ON)
++                                      {
++                                              /*      AP_LDOA */
++                                              bReg    &= (UINT8)~MCB_PWM_LDOA;
++                                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_0, bReg);
++                                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_TIMWAIT | MCDRV_LDOA_WAIT_TIME, 0);
++                                      }
++                                      else
++                                      {
++                                              bReg    &= (UINT8)~MCB_PWM_REFA;
++                                      }
++                                      /*      AP_VR up        */
++                                      bReg    &= (UINT8)~MCB_PWM_VR;
++                                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_0, bReg);
++                                      dWaitTimeDone   = sInitInfo.sWaitTime.dVrefRdy1;
++                                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_TIMWAIT | dWaitTimeDone, 0);
++                                      bWaitVREFRDY    = 1;
++                              }
++
++                              bReg    = (UINT8)((UINT8)~((UINT8)~psPowerInfo->abAnalog[1] & psPowerUpdate->abAnalog[1]) & McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_PWM_ANALOG_1));
++                              /*      SP_HIZ control  */
++                              if(MCDRV_SPHIZ_HIZ == sInitInfo.bSpHiz)
++                              {
++                                      bSpHizReg       = 0;
++                                      if((bReg & (MCB_PWM_SPL1 | MCB_PWM_SPL2)) != 0)
++                                      {
++                                              bSpHizReg |= MCB_SPL_HIZ;
++                                      }
++
++                                      if((bReg & (MCB_PWM_SPR1 | MCB_PWM_SPR2)) != 0)
++                                      {
++                                              bSpHizReg |= MCB_SPR_HIZ;
++                                      }
++
++                                      bSpHizReg |= (McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_SP_MODE) & (MCB_SPMN | MCB_SP_SWAP));
++                                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_SP_MODE, bSpHizReg);
++                              }
++
++                              bRegCur = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_PWM_ANALOG_3);
++                              bReg    = (UINT8)((UINT8)~((UINT8)~psPowerInfo->abAnalog[3] & psPowerUpdate->abAnalog[3]) & bRegCur);
++                              bRegChange      = bReg ^ bRegCur;
++                              /*      set DACON and NSMUTE before setting 0 to AP_DA  */
++                              if(((bRegChange & (MCB_PWM_DAR|MCB_PWM_DAL)) != 0) && ((psPowerInfo->abAnalog[3] & psPowerUpdate->abAnalog[3] & (MCB_PWM_DAR|MCB_PWM_DAL)) != (MCB_PWM_DAR|MCB_PWM_DAL)))
++                              {
++                                      if((McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_CODEC, MCI_DAC_CONFIG) & MCB_DACON) == 0)
++                                      {
++                                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DAC_CONFIG, MCB_NSMUTE);
++                                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DAC_CONFIG, (MCB_DACON | MCB_NSMUTE));
++                                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DAC_CONFIG, MCB_DACON);
++                                      }
++                              }
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_3, bReg);
++                              bRegChange      &= (MCB_PWM_MB1|MCB_PWM_MB2|MCB_PWM_MB3);
++
++                              bRegCur = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_PWM_ANALOG_4);
++                              bReg    = (UINT8)((UINT8)~((UINT8)~psPowerInfo->abAnalog[4] & psPowerUpdate->abAnalog[4]) & bRegCur);
++                              bRegChange      |= (bReg ^ bRegCur);
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_4, bReg);
++
++                              if(bWaitVREFRDY != 0)
++                              {
++                                      /*      wait VREF_RDY   */
++                                      dWaitTimeDone   = sInitInfo.sWaitTime.dVrefRdy2 - dWaitTimeDone;
++                                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_TIMWAIT | dWaitTimeDone, 0);
++                              }
++
++                              sdRet   = McDevIf_ExecutePacket();
++                              if(sdRet == MCDRV_SUCCESS)
++                              {
++                                      bRegCur = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_PWM_ANALOG_0);
++                                      bReg    = (UINT8)(~dUpdate & bRegCur);
++                                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_0, bReg);
++                                      if(((bRegCur & MCB_PWM_CP) != 0) && ((bReg & MCB_PWM_CP) == 0))
++                                      {/*     AP_CP up        */
++                                              dWaitTime               = MCDRV_HP_WAIT_TIME;
++                                      }
++                                      else
++                                      {
++                                              dWaitTime       = 0;
++                                      }
++
++                                      bRegCur = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_PWM_ANALOG_1);
++                                      bRegAna1        = (UINT8)((UINT8)~((UINT8)~psPowerInfo->abAnalog[1] & psPowerUpdate->abAnalog[1]) & bRegCur);
++                                      if((((bRegCur & MCB_PWM_SPL1) != 0) && ((bRegAna1 & MCB_PWM_SPL1) == 0))
++                                      || (((bRegCur & MCB_PWM_SPR1) != 0) && ((bRegAna1 & MCB_PWM_SPR1) == 0)))
++                                      {/*     AP_SP* up       */
++                                              bReg    = bRegAna1|(bRegCur&(UINT8)~(MCB_PWM_SPL1|MCB_PWM_SPR1));
++                                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_1, bReg);
++                                              if(dWaitTime == (UINT32)0)
++                                              {
++                                                      dWaitTime               = MCDRV_SP_WAIT_TIME;
++                                                      bWaitSPVolUp    = 1;
++                                              }
++                                      }
++                                      if((((bRegCur & MCB_PWM_HPL) != 0) && ((bRegAna1 & MCB_PWM_HPL) == 0))
++                                      || (((bRegCur & MCB_PWM_HPR) != 0) && ((bRegAna1 & MCB_PWM_HPR) == 0)))
++                                      {
++                                              bWaitHPVolUp    = 1;
++                                      }
++
++                                      bRegCur = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_PWM_ANALOG_2);
++                                      bRegAna2        = (UINT8)((UINT8)~((UINT8)~psPowerInfo->abAnalog[2] & psPowerUpdate->abAnalog[2]) & bRegCur);
++                                      if(((bRegCur & MCB_PWM_RC1) != 0) && ((bRegAna2 & MCB_PWM_RC1) == 0))
++                                      {/*     AP_RC up        */
++                                              bReg    = bRegAna2|(bRegCur&(UINT8)~MCB_PWM_RC1);
++                                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_2, bReg);
++                                              if(dWaitTime == (UINT32)0)
++                                              {
++                                                      dWaitTime       = MCDRV_RC_WAIT_TIME;
++                                              }
++                                      }
++                                      if(dWaitTime > (UINT32)0)
++                                      {
++                                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_TIMWAIT | dWaitTime, 0);
++                                              dWaitTimeDone   += dWaitTime;
++                                      }
++
++                                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_1, bRegAna1);
++                                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_2, bRegAna2);
++
++                                      /*      time wait       */
++                                      dWaitTime       = GetMaxWait(bRegChange);
++                                      if(dWaitTime > dWaitTimeDone)
++                                      {
++                                              dWaitTime       = dWaitTime - dWaitTimeDone;
++                                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_TIMWAIT | dWaitTime, 0);
++                                              dWaitTimeDone   += dWaitTime;
++                                      }
++
++                                      if((bWaitSPVolUp != 0) && (sInitInfo.sWaitTime.dSpRdy > dWaitTimeDone))
++                                      {
++                                              dWaitTime       = sInitInfo.sWaitTime.dSpRdy - dWaitTimeDone;
++                                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_TIMWAIT | dWaitTime, 0);
++                                              dWaitTimeDone   += dWaitTime;
++                                      }
++                                      if((bWaitHPVolUp != 0) && (sInitInfo.sWaitTime.dHpRdy > dWaitTimeDone))
++                                      {
++                                              dWaitTime       = sInitInfo.sWaitTime.dHpRdy - dWaitTimeDone;
++                                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_TIMWAIT | dWaitTime, 0);
++                                              dWaitTimeDone   += dWaitTime;
++                                      }
++                              }
++                      }
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McPacket_AddPowerUp", &sdRet);
++#endif
++      return sdRet;
++}
++
++/****************************************************************************
++ *    AddAnalogPowerUpAuto
++ *
++ *    Description:
++ *                    Add analog auto powerup packet.
++ *    Arguments:
++ *                    psPowerInfo             power information
++ *                    psPowerUpdate   power update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++static SINT32 AddAnalogPowerUpAuto
++(
++      const MCDRV_POWER_INFO*         psPowerInfo,
++      const MCDRV_POWER_UPDATE*       psPowerUpdate
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bReg;
++      UINT8   bRegCur;
++      UINT32  dUpdate;
++      UINT8   bRegChange;
++      UINT8   bSpHizReg;
++      MCDRV_INIT_INFO sInitInfo;
++      UINT32  dWaitTime       = 0;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("AddAnalogPowerUpAuto");
++#endif
++
++
++      McResCtrl_GetInitInfo(&sInitInfo);
++
++      /*      Analog Power    */
++      dUpdate = (UINT32)~psPowerInfo->abAnalog[0] & psPowerUpdate->abAnalog[0];
++      if((dUpdate & (UINT32)MCB_PWM_VR) != 0UL)
++      {
++              if((McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_PWM_ANALOG_0) & MCB_PWM_VR) != 0)
++              {/*     AP_VR changed   */
++                      /*      AP_VR up        */
++                      bReg    = MCI_PWM_ANALOG_0_DEF;
++                      if(sInitInfo.bLdo == MCDRV_LDO_ON)
++                      {
++                              /*      AP_LDOA */
++                              bReg    &= (UINT8)~MCB_PWM_LDOA;
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_0, bReg);
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_TIMWAIT | MCDRV_LDOA_WAIT_TIME, 0);
++                      }
++                      else
++                      {
++                              bReg    &= (UINT8)~MCB_PWM_REFA;
++                      }
++                      bReg    &= (UINT8)~MCB_PWM_VR;
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_0, bReg);
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_TIMWAIT | sInitInfo.sWaitTime.dVrefRdy1, 0);
++                      if(sInitInfo.sWaitTime.dVrefRdy2 > sInitInfo.sWaitTime.dVrefRdy1)
++                      {
++                              dWaitTime       = sInitInfo.sWaitTime.dVrefRdy2 - sInitInfo.sWaitTime.dVrefRdy1;
++                      }
++              }
++
++              bReg    = (UINT8)((UINT8)~((UINT8)~psPowerInfo->abAnalog[1] & psPowerUpdate->abAnalog[1]) & McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_PWM_ANALOG_1));
++              /*      SP_HIZ control  */
++              if(MCDRV_SPHIZ_HIZ == sInitInfo.bSpHiz)
++              {
++                      bSpHizReg       = 0;
++                      if((bReg & (MCB_PWM_SPL1 | MCB_PWM_SPL2)) != 0)
++                      {
++                              bSpHizReg |= MCB_SPL_HIZ;
++                      }
++
++                      if((bReg & (MCB_PWM_SPR1 | MCB_PWM_SPR2)) != 0)
++                      {
++                              bSpHizReg |= MCB_SPR_HIZ;
++                      }
++
++                      bSpHizReg |= (McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_SP_MODE) & (MCB_SPMN | MCB_SP_SWAP));
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_SP_MODE, bSpHizReg);
++              }
++
++              bRegCur = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_PWM_ANALOG_3);
++              bReg    = (UINT8)~((UINT8)~psPowerInfo->abAnalog[3] & psPowerUpdate->abAnalog[3]) & bRegCur;
++              bRegChange      = bReg ^ bRegCur;
++              /*      set DACON and NSMUTE before setting 0 to AP_DA  */
++              if(((bRegChange & (MCB_PWM_DAR|MCB_PWM_DAL)) != 0) && ((psPowerInfo->abAnalog[3] & psPowerUpdate->abAnalog[3] & (MCB_PWM_DAR|MCB_PWM_DAL)) != (MCB_PWM_DAR|MCB_PWM_DAL)))
++              {
++                      if((McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_CODEC, MCI_DAC_CONFIG) & MCB_DACON) == 0)
++                      {
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DAC_CONFIG, MCB_NSMUTE);
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DAC_CONFIG, (MCB_DACON | MCB_NSMUTE));
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DAC_CONFIG, MCB_DACON);
++                      }
++              }
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_3, bReg);
++              bRegChange      &= (MCB_PWM_MB1|MCB_PWM_MB2|MCB_PWM_MB3);
++
++              bRegCur = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_PWM_ANALOG_4);
++              bReg    = (UINT8)~((UINT8)~psPowerInfo->abAnalog[4] & psPowerUpdate->abAnalog[4]) & bRegCur;
++              bRegChange      |= (bReg ^ bRegCur);
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_4, bReg);
++
++              if(dWaitTime > (UINT32)0)
++              {
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_TIMWAIT | dWaitTime, 0);
++              }
++
++              sdRet   = McDevIf_ExecutePacket();
++              if(sdRet == MCDRV_SUCCESS)
++              {
++                      bRegCur = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_PWM_ANALOG_0);
++                      bReg    = (UINT8)~dUpdate & bRegCur;
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_0, bReg);
++
++                      bRegCur = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_PWM_ANALOG_1);
++                      bReg    = (UINT8)~((UINT8)~psPowerInfo->abAnalog[1] & psPowerUpdate->abAnalog[1]) & bRegCur;
++                      if((bRegCur & (MCB_PWM_ADL|MCB_PWM_ADR)) != (bReg & (MCB_PWM_ADL|MCB_PWM_ADR)))
++                      {
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_1, bReg);
++                      }
++                      else
++                      {
++                              sdRet   = McDevIf_ExecutePacket();
++                              if(sdRet == MCDRV_SUCCESS)
++                              {
++                                      McResCtrl_SetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_PWM_ANALOG_1, bReg);
++                              }
++                      }
++              }
++
++              if(sdRet == MCDRV_SUCCESS)
++              {
++                      bRegCur = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_PWM_ANALOG_2);
++                      bReg    = (UINT8)~((UINT8)~psPowerInfo->abAnalog[2] & psPowerUpdate->abAnalog[2]) & bRegCur;
++                      if((bRegCur & (MCB_PWM_LO1L|MCB_PWM_LO1R|MCB_PWM_LO2L|MCB_PWM_LO2R)) != (bReg & (MCB_PWM_LO1L|MCB_PWM_LO1R|MCB_PWM_LO2L|MCB_PWM_LO2R)))
++                      {
++                              bReg    = bReg|(bRegCur&(MCB_PWM_RC1|MCB_PWM_RC2));
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_2, bReg);
++                      }
++                      else
++                      {
++                              sdRet   = McDevIf_ExecutePacket();
++                              if(sdRet == MCDRV_SUCCESS)
++                              {
++                                      McResCtrl_SetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_PWM_ANALOG_2, bReg);
++                              }
++                      }
++              }
++
++              if(sdRet == MCDRV_SUCCESS)
++              {
++                      /*      time wait       */
++                      if(dWaitTime < GetMaxWait(bRegChange))
++                      {
++                              dWaitTime       = GetMaxWait(bRegChange) - dWaitTime;
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_TIMWAIT | dWaitTime, 0);
++                      }
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("AddAnalogPowerUpAuto", &sdRet);
++#endif
++      return sdRet;
++}
++
++/****************************************************************************
++ *    McPacket_AddPowerDown
++ *
++ *    Description:
++ *                    Add powerdown packet.
++ *    Arguments:
++ *                    psPowerInfo             power information
++ *                    psPowerUpdate   power update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddPowerDown
++(
++      const MCDRV_POWER_INFO*         psPowerInfo,
++      const MCDRV_POWER_UPDATE*       psPowerUpdate
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bReg;
++      UINT8   bRegDPADIF;
++      UINT8   bRegCur;
++      UINT32  dUpdate = psPowerInfo->dDigital & psPowerUpdate->dDigital;
++      UINT32  dAPMDoneParam;
++      UINT32  dAnaRdyParam;
++      UINT8   bSpHizReg;
++      MCDRV_INIT_INFO sInitInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McPacket_AddPowerDown");
++#endif
++
++      bRegDPADIF      = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_CODEC, MCI_DPADIF);
++
++
++      McResCtrl_GetInitInfo(&sInitInfo);
++
++      if(McResCtrl_GetAPMode() == eMCDRV_APM_ON)
++      {
++              if((((psPowerInfo->abAnalog[0] & psPowerUpdate->abAnalog[0] & MCB_PWM_VR) != 0)
++                      && (McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_PWM_ANALOG_0) & MCB_PWM_VR) == 0))
++              {
++                      /*      wait AP_XX_A    */
++                      dAPMDoneParam   = ((MCB_AP_CP_A|MCB_AP_HPL_A|MCB_AP_HPR_A)<<8)
++                                                      | (MCB_AP_RC1_A|MCB_AP_RC2_A|MCB_AP_SPL1_A|MCB_AP_SPR1_A|MCB_AP_SPL2_A|MCB_AP_SPR2_A);
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_EVTWAIT | MCDRV_EVT_APM_DONE | dAPMDoneParam, 0);
++              }
++      }
++
++      if(((dUpdate & MCDRV_POWINFO_DIGITAL_DP0) != 0UL)
++      && ((bRegDPADIF & (MCB_DP0_CLKI1|MCB_DP0_CLKI0)) != (MCB_DP0_CLKI1|MCB_DP0_CLKI0)))
++      {
++              /*      wait mute complete      */
++              sdRet   = McDevIf_ExecutePacket();
++              if(sdRet == MCDRV_SUCCESS)
++              {
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_EVTWAIT | MCDRV_EVT_ALLMUTE, 0);
++              }
++      }
++
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              /*      Analog Power    */
++              bRegCur = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_PWM_ANALOG_1);
++              bReg    = (psPowerInfo->abAnalog[1] & psPowerUpdate->abAnalog[1]) | bRegCur;
++              if(((psPowerUpdate->abAnalog[1] & MCDRV_POWUPDATE_ANALOG1_OUT) != 0) && (MCDRV_SPHIZ_HIZ == sInitInfo.bSpHiz))
++              {
++                      /*      SP_HIZ control  */
++                      bSpHizReg       = 0;
++                      if((bReg & (MCB_PWM_SPL1 | MCB_PWM_SPL2)) != 0)
++                      {
++                              bSpHizReg |= MCB_SPL_HIZ;
++                      }
++
++                      if((bReg & (MCB_PWM_SPR1 | MCB_PWM_SPR2)) != 0)
++                      {
++                              bSpHizReg |= MCB_SPR_HIZ;
++                      }
++
++                      bSpHizReg |= (McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_SP_MODE) & (MCB_SPMN | MCB_SP_SWAP));
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_SP_MODE, bSpHizReg);
++              }
++
++              if(McResCtrl_GetAPMode() == eMCDRV_APM_ON)
++              {
++                      if((bRegCur & (MCB_PWM_ADL|MCB_PWM_ADR)) != (bReg & (MCB_PWM_ADL|MCB_PWM_ADR)))
++                      {
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_1, bReg);
++                      }
++                      else
++                      {
++                              sdRet   = McDevIf_ExecutePacket();
++                              if(sdRet == MCDRV_SUCCESS)
++                              {
++                                      McResCtrl_SetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_PWM_ANALOG_1, bReg);
++                              }
++                      }
++              }
++              else
++              {
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_1, bReg);
++              }
++      }
++
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              bRegCur = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_PWM_ANALOG_2);
++              bReg    = (psPowerInfo->abAnalog[2] & psPowerUpdate->abAnalog[2]) | bRegCur;
++              if(McResCtrl_GetAPMode() == eMCDRV_APM_ON)
++              {
++                      if((bRegCur & (MCB_PWM_LO1L|MCB_PWM_LO1R|MCB_PWM_LO2L|MCB_PWM_LO2R)) != (bReg & (MCB_PWM_LO1L|MCB_PWM_LO1R|MCB_PWM_LO2L|MCB_PWM_LO2R)))
++                      {
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_2, bReg);
++                      }
++                      else
++                      {
++                              sdRet   = McDevIf_ExecutePacket();
++                              if(sdRet == MCDRV_SUCCESS)
++                              {
++                                      McResCtrl_SetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_PWM_ANALOG_2, bReg);
++                              }
++                      }
++              }
++              else
++              {
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_2, bReg);
++              }
++      }
++
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              bReg    = (UINT8)((psPowerInfo->abAnalog[3] & psPowerUpdate->abAnalog[3]) | McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_PWM_ANALOG_3));
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_3, bReg);
++              bReg    = (UINT8)((psPowerInfo->abAnalog[4] & psPowerUpdate->abAnalog[4]) | McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_PWM_ANALOG_4));
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_4, bReg);
++
++              /*      set DACON and NSMUTE after setting 1 to AP_DA   */
++              if((psPowerInfo->abAnalog[3] & psPowerUpdate->abAnalog[3] & (MCB_PWM_DAR|MCB_PWM_DAL)) == (MCB_PWM_DAR|MCB_PWM_DAL))
++              {
++                      if((McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_CODEC, MCI_DAC_CONFIG) & MCB_DACON) == MCB_DACON)
++                      {
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_EVTWAIT | MCDRV_EVT_DACMUTE | (UINT32)((MCB_DAC_FLAGL<<8)|MCB_DAC_FLAGR), 0);
++                      }
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DAC_CONFIG, MCB_NSMUTE);
++              }
++
++              bRegCur = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_PWM_ANALOG_0);
++              bReg    = psPowerInfo->abAnalog[0] & psPowerUpdate->abAnalog[0];
++              if(McResCtrl_GetAPMode() == eMCDRV_APM_OFF)
++              {
++                      /*      wait CPPDRDY    */
++                      dAnaRdyParam    = 0;
++                      if(((bRegCur & MCB_PWM_CP) == 0) && ((bReg & MCB_PWM_CP) == MCB_PWM_CP))
++                      {
++                              dAnaRdyParam    = MCB_CPPDRDY;
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_EVTWAIT | MCDRV_EVT_ANA_RDY | dAnaRdyParam, 0);
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_0, (bRegCur|MCB_PWM_CP));
++                      }
++              }
++
++              if(((bReg & MCB_PWM_VR) != 0) && ((bRegCur & MCB_PWM_VR) == 0))
++              {/*     AP_VR changed   */
++                      /*      AP_xx down      */
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_0, MCI_PWM_ANALOG_0_DEF);
++              }
++              else
++              {
++                      bReg    |= bRegCur;
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_PWM_ANALOG_0, bReg);
++              }
++
++
++              /*      Digital Power   */
++              if(((dUpdate & MCDRV_POWINFO_DIGITAL_DPADIF) != 0UL)
++              && (bRegDPADIF != MCB_DPADIF))
++              {
++                      /*      DPADIF  */
++                      bRegDPADIF      |= MCB_DPADIF;
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DPADIF, bRegDPADIF);
++              }
++
++              if((dUpdate & MCDRV_POWINFO_DIGITAL_DPBDSP) != 0UL)
++              {
++                      /*      DPBDSP  */
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_PWM_DIGITAL_BDSP, MCB_PWM_DPBDSP);
++              }
++
++              /*      DPDI*, DPPDM    */
++              bReg    = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_BASE, MCI_PWM_DIGITAL_1);
++              if(((dUpdate & MCDRV_POWINFO_DIGITAL_DPDI0) != 0UL) || ((dUpdate & MCDRV_POWINFO_DIGITAL_DP2) != 0UL))
++              {
++                      bReg |= MCB_PWM_DPDI0;
++              }
++              if(((dUpdate & MCDRV_POWINFO_DIGITAL_DPDI1) != 0UL) || ((dUpdate & MCDRV_POWINFO_DIGITAL_DP2) != 0UL))
++              {
++                      bReg |= MCB_PWM_DPDI1;
++              }
++              if(((dUpdate & MCDRV_POWINFO_DIGITAL_DPDI2) != 0UL) || ((dUpdate & MCDRV_POWINFO_DIGITAL_DP2) != 0UL))
++              {
++                      bReg |= MCB_PWM_DPDI2;
++              }
++              if((dUpdate & MCDRV_POWINFO_DIGITAL_DPPDM) != 0UL)
++              {
++                      bReg |= MCB_PWM_DPPDM;
++              }
++              if(bReg != 0)
++              {
++                      /*      cannot set DP* & DPB at the same time   */
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_PWM_DIGITAL_1, bReg);
++              }
++              /*      DPB     */
++              if((dUpdate & MCDRV_POWINFO_DIGITAL_DPB) != 0UL)
++              {
++                      bReg |= MCB_PWM_DPB;
++              }
++              if(bReg != 0)
++              {
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_PWM_DIGITAL_1, bReg);
++              }
++
++              if(((dUpdate & MCDRV_POWINFO_DIGITAL_DP2) != 0UL)
++              && ((McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_BASE, MCI_PWM_DIGITAL) & MCB_PWM_DP2) == 0))
++              {
++                      if((dUpdate & MCDRV_POWINFO_DIGITAL_DP0) != 0UL)
++                      {
++                              /*      DP2, DP1        */
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_PWM_DIGITAL, (MCB_PWM_DP2 | MCB_PWM_DP1));
++                              if((dUpdate & MCDRV_POWINFO_DIGITAL_PLLRST0) != 0UL)
++                              {
++                                      /*      PLLRST0 */
++                                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_PLL_RST, MCB_PLLRST0);
++                              }
++                              /*      DP0     */
++                              bRegDPADIF      |= (MCB_DP0_CLKI1 | MCB_DP0_CLKI0);
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DPADIF, bRegDPADIF);
++                              sdRet   = McDevIf_ExecutePacket();
++                              if(sdRet == MCDRV_SUCCESS)
++                              {
++                                      McSrv_ClockStop();
++                              }
++                      }
++                      else
++                      {
++                              /*      DP2     */
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_PWM_DIGITAL, MCB_PWM_DP2);
++                      }
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McPacket_AddPowerDown", &sdRet);
++#endif
++      return sdRet;
++}
++
++/****************************************************************************
++ *    McPacket_AddPathSet
++ *
++ *    Description:
++ *                    Add path update packet.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddPathSet
++(
++      void
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McPacket_AddPathSet");
++#endif
++
++      /*      DI Pad  */
++      AddDIPad();
++
++      /*      PAD(PDM)        */
++      AddPAD();
++
++      /*      Digital Mixer Source    */
++      sdRet   = AddSource();
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              /*      DIR*_START, DIT*_START  */
++              AddDIStart();
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McPacket_AddPathSet", &sdRet);
++#endif
++      return sdRet;
++}
++
++/****************************************************************************
++ *    AddDIPad
++ *
++ *    Description:
++ *                    Add DI Pad setup packet.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   AddDIPad
++(
++      void
++)
++{
++      UINT8   bReg;
++      UINT8   bIsUsedDIR[3];
++      MCDRV_INIT_INFO sInitInfo;
++      MCDRV_PATH_INFO sPathInfo;
++      MCDRV_DIO_INFO  sDioInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("AddDIPad");
++#endif
++
++      McResCtrl_GetInitInfo(&sInitInfo);
++      McResCtrl_GetPathInfo(&sPathInfo);
++      McResCtrl_GetDioInfo(&sDioInfo);
++
++      /*      SDIN_MSK2/1     */
++      bReg    = 0;
++      if(McResCtrl_IsSrcUsed(eMCDRV_SRC_DIR2) == 0)
++      {
++              bReg |= MCB_SDIN_MSK2;
++              bIsUsedDIR[2]   = 0;
++      }
++      else
++      {
++              bIsUsedDIR[2]   = 1;
++      }
++      if(McResCtrl_IsSrcUsed(eMCDRV_SRC_DIR1) == 0)
++      {
++              bReg |= MCB_SDIN_MSK1;
++              bIsUsedDIR[1]   = 0;
++      }
++      else
++      {
++              bIsUsedDIR[1]   = 1;
++      }
++      /*      SDO_DDR2/1      */
++      if(McResCtrl_IsDstUsed(eMCDRV_DST_DIT2, eMCDRV_DST_CH0) == 0)
++      {
++              if(sInitInfo.bDioSdo2Hiz == MCDRV_DAHIZ_LOW)
++              {
++                      bReg |= MCB_SDO_DDR2;
++              }
++      }
++      else
++      {
++              bReg |= MCB_SDO_DDR2;
++      }
++      if(McResCtrl_IsDstUsed(eMCDRV_DST_DIT1, eMCDRV_DST_CH0) == 0)
++      {
++              if(sInitInfo.bDioSdo1Hiz == MCDRV_DAHIZ_LOW)
++              {
++                      bReg |= MCB_SDO_DDR1;
++              }
++      }
++      else
++      {
++              bReg |= MCB_SDO_DDR1;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_SD_MSK, bReg);
++
++      /*      SDIN_MSK0       */
++      bReg    = 0;
++      if(McResCtrl_IsSrcUsed(eMCDRV_SRC_DIR0) == 0)
++      {
++              bReg |= MCB_SDIN_MSK0;
++              bIsUsedDIR[0]   = 0;
++      }
++      else
++      {
++              bIsUsedDIR[0]   = 1;
++      }
++      /*      SDO_DDR0        */
++      if(McResCtrl_IsDstUsed(eMCDRV_DST_DIT0, eMCDRV_DST_CH0) == 0)
++      {
++              if(sInitInfo.bDioSdo0Hiz == MCDRV_DAHIZ_LOW)
++              {
++                      bReg |= MCB_SDO_DDR0;
++              }
++      }
++      else
++      {
++              bReg |= MCB_SDO_DDR0;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_SD_MSK_1, bReg);
++
++      /*      BCLK_MSK*, BCLD_DDR*, LRCK_MSK*, LRCK_DDR*      */
++      bReg    = 0;
++      if((bIsUsedDIR[2] == 0) && (McResCtrl_GetDITSource(eMCDRV_DIO_2) == eMCDRV_SRC_NONE))
++      {
++              bReg |= MCB_BCLK_MSK2;
++              bReg |= MCB_LRCK_MSK2;
++              if(sInitInfo.bDioClk2Hiz == MCDRV_DAHIZ_LOW)
++              {
++                      bReg |= MCB_BCLK_DDR2;
++                      bReg |= MCB_LRCK_DDR2;
++              }
++      }
++      else
++      {
++              if(sDioInfo.asPortInfo[2].sDioCommon.bMasterSlave == MCDRV_DIO_MASTER)
++              {
++                      bReg |= MCB_BCLK_DDR2;
++                      bReg |= MCB_LRCK_DDR2;
++              }
++      }
++      if((bIsUsedDIR[1] == 0) && (McResCtrl_GetDITSource(eMCDRV_DIO_1) == eMCDRV_SRC_NONE))
++      {
++              bReg |= MCB_BCLK_MSK1;
++              bReg |= MCB_LRCK_MSK1;
++              if(sInitInfo.bDioClk1Hiz == MCDRV_DAHIZ_LOW)
++              {
++                      bReg |= MCB_BCLK_DDR1;
++                      bReg |= MCB_LRCK_DDR1;
++              }
++      }
++      else
++      {
++              if(sDioInfo.asPortInfo[1].sDioCommon.bMasterSlave == MCDRV_DIO_MASTER)
++              {
++                      bReg |= MCB_BCLK_DDR1;
++                      bReg |= MCB_LRCK_DDR1;
++              }
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_BCLK_MSK, bReg);
++
++      /*      BCLK_MSK*, BCLD_DDR*, LRCK_MSK*, LRCK_DDR*, PCM_HIZ*    */
++      bReg    = 0;
++      if((bIsUsedDIR[0] == 0) && (McResCtrl_GetDITSource(eMCDRV_DIO_0) == eMCDRV_SRC_NONE))
++      {
++              bReg |= MCB_BCLK_MSK0;
++              bReg |= MCB_LRCK_MSK0;
++              if(sInitInfo.bDioClk0Hiz == MCDRV_DAHIZ_LOW)
++              {
++                      bReg |= MCB_BCLK_DDR0;
++                      bReg |= MCB_LRCK_DDR0;
++              }
++      }
++      else
++      {
++              if(sDioInfo.asPortInfo[0].sDioCommon.bMasterSlave == MCDRV_DIO_MASTER)
++              {
++                      bReg |= MCB_BCLK_DDR0;
++                      bReg |= MCB_LRCK_DDR0;
++              }
++      }
++      if(sInitInfo.bPcmHiz == MCDRV_PCMHIZ_HIZ)
++      {
++              bReg |= (MCB_PCMOUT_HIZ2 | MCB_PCMOUT_HIZ1 | MCB_PCMOUT_HIZ0);
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_BCLK_MSK_1, bReg);
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("AddDIPad", 0);
++#endif
++}
++
++/****************************************************************************
++ *    AddPAD
++ *
++ *    Description:
++ *                    Add PAD setup packet.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   AddPAD
++(
++      void
++)
++{
++      UINT8   bReg;
++      MCDRV_INIT_INFO sInitInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("AddPAD");
++#endif
++
++      McResCtrl_GetInitInfo(&sInitInfo);
++
++      /*      PA*_MSK */
++      bReg    = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_BASE, MCI_PA_MSK);
++      if(McResCtrl_IsSrcUsed(eMCDRV_SRC_PDM) == 0)
++      {
++              bReg    |= MCB_PA0_MSK;
++              if(sInitInfo.bPad1Func == MCDRV_PAD_PDMDI)
++              {
++                      bReg    |= MCB_PA1_MSK;
++              }
++      }
++      else
++      {
++              bReg    &= (UINT8)~MCB_PA0_MSK;
++              if(sInitInfo.bPad1Func == MCDRV_PAD_PDMDI)
++              {
++                      bReg    &= (UINT8)~MCB_PA1_MSK;
++              }
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_PA_MSK, bReg);
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("AddPAD", 0);
++#endif
++}
++
++/****************************************************************************
++ *    AddSource
++ *
++ *    Description:
++ *                    Add source setup packet.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++static SINT32 AddSource
++(
++      void
++)
++{
++      SINT32  sdRet                   = MCDRV_SUCCESS;
++      UINT8   bReg;
++      UINT8   bAEng6;
++      UINT8   bRegAESource    = 0;
++      UINT8   bAESourceChange = 0;
++      UINT32  dXFadeParam             = 0;
++      MCDRV_SRC_TYPE  eAESource;
++      MCDRV_PATH_INFO sPathInfo;
++      MCDRV_DAC_INFO  sDacInfo;
++      MCDRV_AE_INFO   sAeInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("AddSource");
++#endif
++
++      bAEng6          = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_AENG6_SOURCE);
++      eAESource       = McResCtrl_GetAESource();
++
++      McResCtrl_GetPathInfo(&sPathInfo);
++      McResCtrl_GetAeInfo(&sAeInfo);
++
++      switch(eAESource)
++      {
++      case    eMCDRV_SRC_PDM:         bRegAESource    = MCB_AE_SOURCE_AD;             bAEng6  = MCB_AENG6_PDM;        break;
++      case    eMCDRV_SRC_ADC0:        bRegAESource    = MCB_AE_SOURCE_AD;             bAEng6  = MCB_AENG6_ADC0;       break;
++      case    eMCDRV_SRC_DIR0:        bRegAESource    = MCB_AE_SOURCE_DIR0;   break;
++      case    eMCDRV_SRC_DIR1:        bRegAESource    = MCB_AE_SOURCE_DIR1;   break;
++      case    eMCDRV_SRC_DIR2:        bRegAESource    = MCB_AE_SOURCE_DIR2;   break;
++      case    eMCDRV_SRC_MIX:         bRegAESource    = MCB_AE_SOURCE_MIX;    break;
++      default:                                        bRegAESource    = 0;
++      }
++      if(bRegAESource != (McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_SRC_SOURCE_1)&0xF0))
++      {
++              /*      xxx_INS */
++              dXFadeParam     = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DAC_INS);
++              dXFadeParam <<= 8;
++              dXFadeParam     |= McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_INS);
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_DAC_INS, 0);
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_INS, 0);
++              bAESourceChange = 1;
++              sdRet   = McDevIf_ExecutePacket();
++      }
++
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              McResCtrl_GetDacInfo(&sDacInfo);
++
++              /*      DAC_SOURCE/VOICE_SOURCE */
++              bReg    = 0;
++              switch(McResCtrl_GetDACSource(eMCDRV_DAC_MASTER))
++              {
++              case    eMCDRV_SRC_PDM:
++                      bReg |= MCB_DAC_SOURCE_AD;
++                      bAEng6  = MCB_AENG6_PDM;
++                      break;
++              case    eMCDRV_SRC_ADC0:
++                      bReg |= MCB_DAC_SOURCE_AD;
++                      bAEng6  = MCB_AENG6_ADC0;
++                      break;
++              case    eMCDRV_SRC_DIR0:
++                      bReg |= MCB_DAC_SOURCE_DIR0;
++                      break;
++              case    eMCDRV_SRC_DIR1:
++                      bReg |= MCB_DAC_SOURCE_DIR1;
++                      break;
++              case    eMCDRV_SRC_DIR2:
++                      bReg |= MCB_DAC_SOURCE_DIR2;
++                      break;
++              case    eMCDRV_SRC_MIX:
++                      bReg |= MCB_DAC_SOURCE_MIX;
++                      break;
++              default:
++                      break;
++              }
++              switch(McResCtrl_GetDACSource(eMCDRV_DAC_VOICE))
++              {
++              case    eMCDRV_SRC_PDM:
++                      bReg |= MCB_VOICE_SOURCE_AD;
++                      bAEng6  = MCB_AENG6_PDM;
++                      break;
++              case    eMCDRV_SRC_ADC0:
++                      bReg |= MCB_VOICE_SOURCE_AD;
++                      bAEng6  = MCB_AENG6_ADC0;
++                      break;
++              case    eMCDRV_SRC_DIR0:
++                      bReg |= MCB_VOICE_SOURCE_DIR0;
++                      break;
++              case    eMCDRV_SRC_DIR1:
++                      bReg |= MCB_VOICE_SOURCE_DIR1;
++                      break;
++              case    eMCDRV_SRC_DIR2:
++                      bReg |= MCB_VOICE_SOURCE_DIR2;
++                      break;
++              case    eMCDRV_SRC_MIX:
++                      bReg |= MCB_VOICE_SOURCE_MIX;
++                      break;
++              default:
++                      break;
++              }
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_SOURCE, bReg);
++
++              /*      SWP/VOICE_SWP   */
++              bReg    = (sDacInfo.bMasterSwap << 4) | sDacInfo.bVoiceSwap;
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_SWP, bReg);
++
++              /*      DIT0SRC_SOURCE/DIT1SRC_SOURCE   */
++              bReg    = 0;
++              switch(McResCtrl_GetDITSource(eMCDRV_DIO_0))
++              {
++              case    eMCDRV_SRC_PDM:
++                      bReg |= MCB_DIT0_SOURCE_AD;
++                              bAEng6  = MCB_AENG6_PDM;
++                      break;
++              case    eMCDRV_SRC_ADC0:
++                      bReg |= MCB_DIT0_SOURCE_AD;
++                              bAEng6  = MCB_AENG6_ADC0;
++                      break;
++              case    eMCDRV_SRC_DIR0:
++                      bReg |= MCB_DIT0_SOURCE_DIR0;
++                      break;
++              case    eMCDRV_SRC_DIR1:
++                      bReg |= MCB_DIT0_SOURCE_DIR1;
++                      break;
++              case    eMCDRV_SRC_DIR2:
++                      bReg |= MCB_DIT0_SOURCE_DIR2;
++                      break;
++              case    eMCDRV_SRC_MIX:
++                      bReg |= MCB_DIT0_SOURCE_MIX;
++                      break;
++              default:
++                      break;
++              }
++              switch(McResCtrl_GetDITSource(eMCDRV_DIO_1))
++              {
++              case    eMCDRV_SRC_PDM:
++                      bReg |= MCB_DIT1_SOURCE_AD;
++                              bAEng6  = MCB_AENG6_PDM;
++                      break;
++              case    eMCDRV_SRC_ADC0:
++                      bReg |= MCB_DIT1_SOURCE_AD;
++                              bAEng6  = MCB_AENG6_ADC0;
++                      break;
++              case    eMCDRV_SRC_DIR0:
++                      bReg |= MCB_DIT1_SOURCE_DIR0;
++                      break;
++              case    eMCDRV_SRC_DIR1:
++                      bReg |= MCB_DIT1_SOURCE_DIR1;
++                      break;
++              case    eMCDRV_SRC_DIR2:
++                      bReg |= MCB_DIT1_SOURCE_DIR2;
++                      break;
++              case    eMCDRV_SRC_MIX:
++                      bReg |= MCB_DIT1_SOURCE_MIX;
++                      break;
++              default:
++                      break;
++              }
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_SRC_SOURCE, bReg);
++
++              /*      AE_SOURCE/DIT2SRC_SOURCE        */
++              bReg    = bRegAESource;
++              switch(McResCtrl_GetDITSource(eMCDRV_DIO_2))
++              {
++              case    eMCDRV_SRC_PDM:
++                      bReg |= MCB_DIT2_SOURCE_AD;
++                              bAEng6  = MCB_AENG6_PDM;
++                      break;
++              case    eMCDRV_SRC_ADC0:
++                      bReg |= MCB_DIT2_SOURCE_AD;
++                              bAEng6  = MCB_AENG6_ADC0;
++                      break;
++              case    eMCDRV_SRC_DIR0:
++                      bReg |= MCB_DIT2_SOURCE_DIR0;
++                      break;
++              case    eMCDRV_SRC_DIR1:
++                      bReg |= MCB_DIT2_SOURCE_DIR1;
++                      break;
++              case    eMCDRV_SRC_DIR2:
++                      bReg |= MCB_DIT2_SOURCE_DIR2;
++                      break;
++              case    eMCDRV_SRC_MIX:
++                      bReg |= MCB_DIT2_SOURCE_MIX;
++                      break;
++              default:
++                      break;
++              }
++              if(bAESourceChange != 0)
++              {
++                      /*      wait xfade complete     */
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_EVTWAIT | MCDRV_EVT_INSFLG | dXFadeParam, 0);
++              }
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_SRC_SOURCE_1, bReg);
++
++              /*      BDSP_ST */
++              if(McResCtrl_GetAESource() == eMCDRV_SRC_NONE)
++              {/*     AE is unused    */
++                      /*      BDSP stop & reset       */
++                      if((McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_A, MCI_BDSP_ST)&MCB_BDSP_ST) != 0)
++                      {
++                              bReg    = 0;
++                              if((sAeInfo.bOnOff & MCDRV_EQ5_ON) != 0)
++                              {
++                                      bReg |= MCB_EQ5ON;
++                              }
++                              if((sAeInfo.bOnOff & MCDRV_DRC_ON) != 0)
++                              {
++                                      bReg |= MCB_DRCON;
++                              }
++                              if((sAeInfo.bOnOff & MCDRV_EQ3_ON) != 0)
++                              {
++                                      bReg |= MCB_EQ3ON;
++                              }
++                              if(McDevProf_IsValid(eMCDRV_FUNC_DBEX) == 1)
++                              {
++                                      if((sAeInfo.bOnOff & MCDRV_BEXWIDE_ON) != 0)
++                                      {
++                                              bReg |= MCB_DBEXON;
++                                      }
++                              }
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_A | (UINT32)MCI_BDSP_ST, bReg);
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_A | (UINT32)MCI_BDSP_RST, MCB_TRAM_RST);
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_A | (UINT32)MCI_BDSP_RST, 0);
++                      }
++              }
++              else
++              {/*     AE is used      */
++                      bReg    = 0;
++                      if((sAeInfo.bOnOff & MCDRV_EQ5_ON) != 0)
++                      {
++                              bReg |= MCB_EQ5ON;
++                      }
++                      if((sAeInfo.bOnOff & MCDRV_DRC_ON) != 0)
++                      {
++                              bReg |= MCB_DRCON;
++                              bReg |= MCB_BDSP_ST;
++                      }
++                      if((sAeInfo.bOnOff & MCDRV_EQ3_ON) != 0)
++                      {
++                              bReg |= MCB_EQ3ON;
++                      }
++                      if(McDevProf_IsValid(eMCDRV_FUNC_DBEX) == 1)
++                      {
++                              if((sAeInfo.bOnOff & MCDRV_BEXWIDE_ON) != 0)
++                              {
++                                      bReg |= MCB_DBEXON;
++                                      bReg |= MCB_BDSP_ST;
++                              }
++                      }
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_A | (UINT32)MCI_BDSP_ST, bReg);
++              }
++
++              /*      check MIX SOURCE for AENG6_SOURCE       */
++              if(McResCtrl_IsSrcUsed(eMCDRV_SRC_PDM) != 0)
++              {
++                      bAEng6  = MCB_AENG6_PDM;
++              }
++              else if(McResCtrl_IsSrcUsed(eMCDRV_SRC_ADC0) != 0)
++              {
++                      bAEng6  = MCB_AENG6_ADC0;
++              }
++              else
++              {
++              }
++
++              /*      AENG6_SOURCE    */
++              if(bAEng6 != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_AENG6_SOURCE))
++              {
++                      bReg    = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_CODEC, MCI_AD_START);
++                      if((bReg & MCB_AD_START) != 0)
++                      {
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_AD_START, bReg&(UINT8)~MCB_AD_START);
++                      }
++                      bReg    = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_PDM_START);
++                      if((bReg & MCB_PDM_START) != 0)
++                      {
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_PDM_START, bReg&(UINT8)~MCB_PDM_START);
++                      }
++              }
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_AENG6_SOURCE, bAEng6);
++
++              /*      xxx_INS */
++              if(McResCtrl_IsSrcUsed(eMCDRV_SRC_AE) != 0)
++              {
++                      switch(eAESource)
++                      {
++                      case    eMCDRV_SRC_PDM:
++                      case    eMCDRV_SRC_ADC0:
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_INS, MCB_ADC_INS);
++                              break;
++                      case    eMCDRV_SRC_DIR0:
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_INS, MCB_DIR0_INS);
++                              break;
++                      case    eMCDRV_SRC_DIR1:
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_INS, MCB_DIR1_INS);
++                              break;
++                      case    eMCDRV_SRC_DIR2:
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_INS, MCB_DIR2_INS);
++                              break;
++                      case    eMCDRV_SRC_MIX:
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_DAC_INS, MCB_DAC_INS);
++                              break;
++                      default:
++                              break;
++                      }
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("AddSource", &sdRet);
++#endif
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    AddDIStart
++ *
++ *    Description:
++ *                    Add DIStart setup packet.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   AddDIStart
++(
++      void
++)
++{
++      UINT8   bReg;
++      MCDRV_PATH_INFO sPathInfo;
++      MCDRV_DIO_INFO  sDioInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("AddDIStart");
++#endif
++
++      McResCtrl_GetPathInfo(&sPathInfo);
++      McResCtrl_GetDioInfo(&sDioInfo);
++
++      /*      DIR*_START, DIT*_START  */
++      bReg    = 0;
++      if(McResCtrl_GetDITSource(eMCDRV_DIO_0) != eMCDRV_SRC_NONE)
++      {
++              if(sDioInfo.asPortInfo[0].sDioCommon.bMasterSlave == MCDRV_DIO_MASTER)
++              {
++                      bReg |= MCB_DITIM0_START;
++              }
++              bReg |= MCB_DIT0_SRC_START;
++              bReg |= MCB_DIT0_START;
++      }
++      if(McResCtrl_IsSrcUsed(eMCDRV_SRC_DIR0) != 0)
++      {
++              if(sDioInfo.asPortInfo[0].sDioCommon.bMasterSlave == MCDRV_DIO_MASTER)
++              {
++                      bReg |= MCB_DITIM0_START;
++              }
++              bReg |= MCB_DIR0_SRC_START;
++              bReg |= MCB_DIR0_START;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_DIX0_START, bReg);
++
++      bReg    = 0;
++      if(McResCtrl_GetDITSource(eMCDRV_DIO_1) != eMCDRV_SRC_NONE)
++      {
++              if(sDioInfo.asPortInfo[1].sDioCommon.bMasterSlave == MCDRV_DIO_MASTER)
++              {
++                      bReg |= MCB_DITIM1_START;
++              }
++              bReg |= MCB_DIT1_SRC_START;
++              bReg |= MCB_DIT1_START;
++      }
++      if(McResCtrl_IsSrcUsed(eMCDRV_SRC_DIR1) != 0)
++      {
++              if(sDioInfo.asPortInfo[1].sDioCommon.bMasterSlave == MCDRV_DIO_MASTER)
++              {
++                      bReg |= MCB_DITIM1_START;
++              }
++              bReg |= MCB_DIR1_SRC_START;
++              bReg |= MCB_DIR1_START;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_DIX1_START, bReg);
++
++      bReg    = 0;
++      if(McResCtrl_GetDITSource(eMCDRV_DIO_2) != eMCDRV_SRC_NONE)
++      {
++              if(sDioInfo.asPortInfo[2].sDioCommon.bMasterSlave == MCDRV_DIO_MASTER)
++              {
++                      bReg |= MCB_DITIM2_START;
++              }
++              bReg |= MCB_DIT2_SRC_START;
++              bReg |= MCB_DIT2_START;
++      }
++      if(McResCtrl_IsSrcUsed(eMCDRV_SRC_DIR2) != 0)
++      {
++              if(sDioInfo.asPortInfo[2].sDioCommon.bMasterSlave == MCDRV_DIO_MASTER)
++              {
++                      bReg |= MCB_DITIM2_START;
++              }
++              bReg |= MCB_DIR2_SRC_START;
++              bReg |= MCB_DIR2_START;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_DIX2_START, bReg);
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("AddDIStart", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McPacket_AddMixSet
++ *
++ *    Description:
++ *                    Add analog mixer set packet.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddMixSet
++(
++      void
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bReg;
++      MCDRV_INIT_INFO sInitInfo;
++      MCDRV_PATH_INFO sPathInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McPacket_AddMixSet");
++#endif
++
++      McResCtrl_GetInitInfo(&sInitInfo);
++      McResCtrl_GetPathInfo(&sPathInfo);
++
++      /*      ADL_MIX */
++      bReg    = GetMicMixBit(&sPathInfo.asAdc0[0]);
++      if(((sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++      || ((sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON))
++      {
++              bReg |= MCB_LI1MIX;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_ADL_MIX, bReg);
++      /*      ADL_MONO        */
++      bReg    = 0;
++      if((sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              bReg |= MCB_MONO_LI1;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_ADL_MONO, bReg);
++
++      /*      ADR_MIX */
++      bReg    = GetMicMixBit(&sPathInfo.asAdc0[1]);
++      if(((sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON)
++      || ((sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON))
++      {
++              bReg |= MCB_LI1MIX;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_ADR_MIX, bReg);
++      /*      ADR_MONO        */
++      bReg    = 0;
++      if((sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              bReg |= MCB_MONO_LI1;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_ADR_MONO, bReg);
++
++      /*      L1L_MIX */
++      bReg    = GetMicMixBit(&sPathInfo.asLout1[0]);
++      if(((sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++      || ((sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON))
++      {
++              bReg |= MCB_LI1MIX;
++      }
++      if(((sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON)
++      || ((sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON))
++      {
++              bReg |= MCB_DAMIX;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_LO1L_MIX, bReg);
++      /*      L1L_MONO        */
++      bReg    = 0;
++      if((sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              bReg |= MCB_MONO_LI1;
++      }
++      if((sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON)
++      {
++              bReg |= MCB_MONO_DA;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_LO1L_MONO, bReg);
++
++      /*      L1R_MIX */
++      if(sInitInfo.bLineOut1Dif != MCDRV_LINE_DIF)
++      {
++              bReg    = GetMicMixBit(&sPathInfo.asLout1[1]);
++              if((sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON)
++              {
++                      bReg |= MCB_LI1MIX;
++              }
++              if((sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON)
++              {
++                      bReg |= MCB_DAMIX;
++              }
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_LO1R_MIX, bReg);
++      }
++
++      /*      L2L_MIX */
++      bReg    = GetMicMixBit(&sPathInfo.asLout2[0]);
++      if(((sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++      || ((sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON))
++      {
++              bReg |= MCB_LI1MIX;
++      }
++      if(((sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON)
++      || ((sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON))
++      {
++              bReg |= MCB_DAMIX;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_LO2L_MIX, bReg);
++      /*      L2L_MONO        */
++      bReg    = 0;
++      if((sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              bReg |= MCB_MONO_LI1;
++      }
++      if((sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON)
++      {
++              bReg |= MCB_MONO_DA;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_LO2L_MONO, bReg);
++
++      /*      L2R_MIX */
++      if(sInitInfo.bLineOut2Dif != MCDRV_LINE_DIF)
++      {
++              bReg    = GetMicMixBit(&sPathInfo.asLout2[1]);
++              if((sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON)
++              {
++                      bReg |= MCB_LI1MIX;
++              }
++              if((sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON)
++              {
++                      bReg |= MCB_DAMIX;
++              }
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_LO2R_MIX, bReg);
++      }
++
++      /*      HPL_MIX */
++      bReg    = GetMicMixBit(&sPathInfo.asHpOut[0]);
++      if(((sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++      || ((sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON))
++      {
++              bReg |= MCB_LI1MIX;
++      }
++      if(((sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON)
++      || ((sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON))
++      {
++              bReg |= MCB_DAMIX;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_HPL_MIX, bReg);
++      /*      HPL_MONO        */
++      bReg    = 0;
++      if((sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              bReg |= MCB_MONO_LI1;
++      }
++      if((sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON)
++      {
++              bReg |= MCB_MONO_DA;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_HPL_MONO, bReg);
++
++      /*      HPR_MIX */
++      bReg    = GetMicMixBit(&sPathInfo.asHpOut[1]);
++      if((sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON)
++      {
++              bReg |= MCB_LI1MIX;
++      }
++      if((sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON)
++      {
++              bReg |= MCB_DAMIX;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_HPR_MIX, bReg);
++
++      /*      SPL_MIX */
++      bReg    = 0;
++      if(((sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++      || ((sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON))
++      {
++              bReg |= MCB_LI1MIX;
++      }
++      if(((sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON)
++      || ((sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON))
++      {
++              bReg |= MCB_DAMIX;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_SPL_MIX, bReg);
++      /*      SPL_MONO        */
++      bReg    = 0;
++      if((sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              bReg |= MCB_MONO_LI1;
++      }
++      if((sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON)
++      {
++              bReg |= MCB_MONO_DA;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_SPL_MONO, bReg);
++
++      /*      SPR_MIX */
++      bReg    = 0;
++      if(((sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON)
++      || ((sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON))
++      {
++              bReg |= MCB_LI1MIX;
++      }
++      if(((sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON)
++      || ((sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON))
++      {
++              bReg |= MCB_DAMIX;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_SPR_MIX, bReg);
++      /*      SPR_MONO        */
++      bReg    = 0;
++      if((sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              bReg |= MCB_MONO_LI1;
++      }
++      if((sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON)
++      {
++              bReg |= MCB_MONO_DA;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_SPR_MONO, bReg);
++
++      /*      RCV_MIX */
++      bReg    = GetMicMixBit(&sPathInfo.asRcOut[0]);
++      if((sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              bReg |= MCB_LI1MIX;
++      }
++      if((sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON)
++      {
++              bReg |= MCB_DALMIX;
++      }
++      if((sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON)
++      {
++              bReg |= MCB_DARMIX;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_RC_MIX, bReg);
++
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McPacket_AddMixSet", &sdRet);
++#endif
++      return sdRet;
++}
++
++/****************************************************************************
++ *    GetMicMixBit
++ *
++ *    Description:
++ *                    Get mic mixer bit.
++ *    Arguments:
++ *                    source info
++ *    Return:
++ *                    mic mixer bit
++ *
++ ****************************************************************************/
++static UINT8  GetMicMixBit
++(
++      const MCDRV_CHANNEL* psChannel
++)
++{
++      UINT8   bMicMix = 0;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("GetMicMixBit");
++#endif
++
++      if((psChannel->abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON)
++      {
++              bMicMix |= MCB_M1MIX;
++      }
++      if((psChannel->abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON)
++      {
++              bMicMix |= MCB_M2MIX;
++      }
++      if((psChannel->abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON)
++      {
++              bMicMix |= MCB_M3MIX;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = (SINT32)bMicMix;
++      McDebugLog_FuncOut("GetMicMixBit", &sdRet);
++#endif
++      return bMicMix;
++}
++
++/****************************************************************************
++ *    McPacket_AddStart
++ *
++ *    Description:
++ *                    Add start packet.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddStart
++(
++      void
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bReg;
++      MCDRV_INIT_INFO sInitInfo;
++      MCDRV_PATH_INFO sPathInfo;
++      MCDRV_ADC_INFO  sAdcInfo;
++      MCDRV_PDM_INFO  sPdmInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McPacket_AddStart");
++#endif
++
++      McResCtrl_GetInitInfo(&sInitInfo);
++      McResCtrl_GetPathInfo(&sPathInfo);
++      McResCtrl_GetAdcInfo(&sAdcInfo);
++      McResCtrl_GetPdmInfo(&sPdmInfo);
++
++      if((McResCtrl_IsDstUsed(eMCDRV_DST_ADC0, eMCDRV_DST_CH0) == 1)
++      || (McResCtrl_IsDstUsed(eMCDRV_DST_ADC0, eMCDRV_DST_CH1) == 1))
++      {/*     ADC0 source is used     */
++              if((McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_CODEC, MCI_AD_START) & MCB_AD_START) == 0)
++              {
++                      bReg    = (sAdcInfo.bAgcOn << 2) | sAdcInfo.bAgcAdjust;
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_AD_AGC, bReg);
++                      bReg    = (sAdcInfo.bMono << 1) | MCB_AD_START;
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_AD_START, bReg);
++              }
++      }
++      else if(McResCtrl_IsSrcUsed(eMCDRV_SRC_PDM) != 0)
++      {/*     PDM is used     */
++              if((McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_PDM_START) & MCB_PDM_START) == 0)
++              {
++                      bReg    = (sPdmInfo.bAgcOn << 2) | sPdmInfo.bAgcAdjust;
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_PDM_AGC, bReg);
++                      bReg    = (sPdmInfo.bMono << 1) | MCB_PDM_START;
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_PDM_START, bReg);
++              }
++      }
++      else
++      {
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McPacket_AddStart", &sdRet);
++#endif
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    McPacket_AddStop
++ *
++ *    Description:
++ *                    Add stop packet.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddStop
++(
++      void
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bReg;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McPacket_AddStop");
++#endif
++
++      bReg    = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DIX0_START);
++      if(McResCtrl_GetDITSource(eMCDRV_DIO_0) == eMCDRV_SRC_NONE)
++      {/*     DIT is unused   */
++              bReg &= (UINT8)~MCB_DIT0_SRC_START;
++              bReg &= (UINT8)~MCB_DIT0_START;
++      }
++      if(McResCtrl_IsSrcUsed(eMCDRV_SRC_DIR0) == 0)
++      {/*     DIR is unused   */
++              bReg &= (UINT8)~MCB_DIR0_SRC_START;
++              bReg &= (UINT8)~MCB_DIR0_START;
++      }
++      if((bReg & 0x0F) == 0)
++      {
++              bReg &= (UINT8)~MCB_DITIM0_START;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_DIX0_START, bReg);
++
++      bReg    = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DIX1_START);
++      if(McResCtrl_GetDITSource(eMCDRV_DIO_1) == eMCDRV_SRC_NONE)
++      {/*     DIT is unused   */
++              bReg &= (UINT8)~MCB_DIT1_SRC_START;
++              bReg &= (UINT8)~MCB_DIT1_START;
++      }
++      if(McResCtrl_IsSrcUsed(eMCDRV_SRC_DIR1) == 0)
++      {/*     DIR is unused   */
++              bReg &= (UINT8)~MCB_DIR1_SRC_START;
++              bReg &= (UINT8)~MCB_DIR1_START;
++      }
++      if((bReg & 0x0F) == 0)
++      {
++              bReg &= (UINT8)~MCB_DITIM1_START;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_DIX1_START, bReg);
++
++      bReg    = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DIX2_START);
++      if(McResCtrl_GetDITSource(eMCDRV_DIO_2) == eMCDRV_SRC_NONE)
++      {/*     DIT is unused   */
++              bReg &= (UINT8)~MCB_DIT2_SRC_START;
++              bReg &= (UINT8)~MCB_DIT2_START;
++      }
++      if(McResCtrl_IsSrcUsed(eMCDRV_SRC_DIR2) == 0)
++      {/*     DIR is unused   */
++              bReg &= (UINT8)~MCB_DIR2_SRC_START;
++              bReg &= (UINT8)~MCB_DIR2_START;
++      }
++      if((bReg & 0x0F) == 0)
++      {
++              bReg &= (UINT8)~MCB_DITIM2_START;
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_DIX2_START, bReg);
++
++      if((McResCtrl_IsDstUsed(eMCDRV_DST_ADC0, eMCDRV_DST_CH0) == 0)
++      && (McResCtrl_IsDstUsed(eMCDRV_DST_ADC0, eMCDRV_DST_CH1) == 0))
++      {/*     ADC0 source is unused   */
++              AddStopADC();
++      }
++      if(McResCtrl_IsSrcUsed(eMCDRV_SRC_PDM) == 0)
++      {/*     PDM is unused   */
++              AddStopPDM();
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McPacket_AddStop", &sdRet);
++#endif
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    McPacket_AddVol
++ *
++ *    Description:
++ *                    Add volume mute packet.
++ *    Arguments:
++ *                    dUpdate                 target volume items
++ *                    eMode                   update mode
++ *                    pdSVolDoneParam wait soft volume complete flag
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddVol
++(
++      UINT32                                  dUpdate,
++      MCDRV_VOLUPDATE_MODE    eMode,
++      UINT32*                                 pdSVolDoneParam
++)
++{
++      SINT32                  sdRet   = MCDRV_SUCCESS;
++      UINT8                   bVolL;
++      UINT8                   bVolR;
++      UINT8                   bLAT;
++      UINT8                   bReg;
++      MCDRV_INIT_INFO sInitInfo;
++      MCDRV_VOL_INFO  sVolInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McPacket_AddVol");
++#endif
++
++      McResCtrl_GetInitInfo(&sInitInfo);
++      McResCtrl_GetVolReg(&sVolInfo);
++
++      if((dUpdate & MCDRV_VOLUPDATE_ANAOUT_ALL) != (UINT32)0)
++      {
++              *pdSVolDoneParam        = 0;
++
++              bVolL   = (UINT8)sVolInfo.aswA_Hp[0]&MCB_HPVOL_L;
++              bVolR   = (UINT8)sVolInfo.aswA_Hp[1]&MCB_HPVOL_R;
++              if(bVolL != (McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_HPVOL_L) & MCB_HPVOL_L))
++              {
++                      if((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolL == MCDRV_REG_MUTE))
++                      {
++                              if(((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolR == MCDRV_REG_MUTE))
++                              && (bVolR != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_HPVOL_R)))
++                              {
++                                      bLAT    = MCB_ALAT_HP;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|MCB_SVOL_HP|bVolL;
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_HPVOL_L, bReg);
++                              if(bVolL == MCDRV_REG_MUTE)
++                              {
++                                      *pdSVolDoneParam        |= (MCB_HPL_BUSY<<8);
++                              }
++                      }
++              }
++              if((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolR == MCDRV_REG_MUTE))
++              {
++                      if((bVolR == MCDRV_REG_MUTE) && (McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_HPVOL_R) != 0))
++                      {
++                              *pdSVolDoneParam        |= (UINT8)MCB_HPR_BUSY;
++                      }
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_HPVOL_R, bVolR);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswA_Sp[0]&MCB_SPVOL_L;
++              bVolR   = (UINT8)sVolInfo.aswA_Sp[1]&MCB_SPVOL_R;
++              if(bVolL != (McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_SPVOL_L) & MCB_SPVOL_L))
++              {
++                      if((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolL == MCDRV_REG_MUTE))
++                      {
++                              if(((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolR == MCDRV_REG_MUTE))
++                              && (bVolR != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_SPVOL_R)))
++                              {
++                                      bLAT    = MCB_ALAT_SP;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|MCB_SVOL_SP|bVolL;
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_SPVOL_L, bReg);
++                              if(bVolL == MCDRV_REG_MUTE)
++                              {
++                                      *pdSVolDoneParam        |= (MCB_SPL_BUSY<<8);
++                              }
++                      }
++              }
++              if((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolR == MCDRV_REG_MUTE))
++              {
++                      if((bVolR == MCDRV_REG_MUTE) && (McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_SPVOL_R) != 0))
++                      {
++                              *pdSVolDoneParam        |= (UINT8)MCB_SPR_BUSY;
++                      }
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_SPVOL_R, bVolR);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswA_Rc[0]&MCB_RCVOL;
++              if(bVolL != (McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_RCVOL) & MCB_RCVOL))
++              {
++                      if((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolL == MCDRV_REG_MUTE))
++                      {
++                              bReg    = MCB_SVOL_RC|bVolL;
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_RCVOL, bReg);
++                              if(bVolL == MCDRV_REG_MUTE)
++                              {
++                                      *pdSVolDoneParam        |= (MCB_RC_BUSY<<8);
++                              }
++                      }
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswA_Lout1[0]&MCB_LO1VOL_L;
++              bVolR   = (UINT8)sVolInfo.aswA_Lout1[1]&MCB_LO1VOL_R;
++              if(bVolL != (McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_LO1VOL_L) & MCB_LO1VOL_L))
++              {
++                      if((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolL == MCDRV_REG_MUTE))
++                      {
++                              if(((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolR == MCDRV_REG_MUTE))
++                              && (bVolR != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_LO1VOL_R)))
++                              {
++                                      bLAT    = MCB_ALAT_LO1;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|bVolL;
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_LO1VOL_L, bReg);
++                      }
++              }
++              if((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolR == MCDRV_REG_MUTE))
++              {
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_LO1VOL_R, bVolR);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswA_Lout2[0]&MCB_LO2VOL_L;
++              bVolR   = (UINT8)sVolInfo.aswA_Lout2[1]&MCB_LO2VOL_R;
++              if(bVolL != (McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_LO2VOL_L) & MCB_LO2VOL_L))
++              {
++                      if((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolL == MCDRV_REG_MUTE))
++                      {
++                              if(((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolR == MCDRV_REG_MUTE))
++                              && (bVolR != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_LO2VOL_R)))
++                              {
++                                      bLAT    = MCB_ALAT_LO2;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|bVolL;
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_LO2VOL_L, bReg);
++                      }
++              }
++              if((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolR == MCDRV_REG_MUTE))
++              {
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_LO2VOL_R, bVolR);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswA_HpGain[0];
++              if(bVolL != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_HP_GAIN))
++              {
++                      if((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolL == MCDRV_REG_MUTE))
++                      {
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_HP_GAIN, bVolL);
++                      }
++              }
++      }
++      if((dUpdate & ~MCDRV_VOLUPDATE_ANAOUT_ALL) != (UINT32)0)
++      {
++              bVolL   = (UINT8)sVolInfo.aswA_Lin1[0]&MCB_LI1VOL_L;
++              bVolR   = (UINT8)sVolInfo.aswA_Lin1[1]&MCB_LI1VOL_R;
++              if(bVolL != (McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_LI1VOL_L) & MCB_LI1VOL_L))
++              {
++                      if((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolL == MCDRV_REG_MUTE))
++                      {
++                              if(((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolR == MCDRV_REG_MUTE))
++                              && (bVolR != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_LI1VOL_R)))
++                              {
++                                      bLAT    = MCB_ALAT_LI1;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|bVolL;
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_LI1VOL_L, bReg);
++                      }
++              }
++              if((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolR == MCDRV_REG_MUTE))
++              {
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_LI1VOL_R, bVolR);
++              }
++
++              if(McDevProf_IsValid(eMCDRV_FUNC_LI2) == 1)
++              {
++                      bVolL   = (UINT8)sVolInfo.aswA_Lin2[0]&MCB_LI2VOL_L;
++                      bVolR   = (UINT8)sVolInfo.aswA_Lin2[1]&MCB_LI2VOL_R;
++                      if(bVolL != (McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_LI2VOL_L) & MCB_LI2VOL_L))
++                      {
++                              if((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolL == MCDRV_REG_MUTE))
++                              {
++                                      if(((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolR == MCDRV_REG_MUTE))
++                                      && (bVolR != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_LI2VOL_R)))
++                                      {
++                                              bLAT    = MCB_ALAT_LI2;
++                                      }
++                                      else
++                                      {
++                                              bLAT    = 0;
++                                      }
++                                      bReg    = bLAT|bVolL;
++                                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_LI2VOL_L, bReg);
++                              }
++                      }
++                      if((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolR == MCDRV_REG_MUTE))
++                      {
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_LI2VOL_R, bVolR);
++                      }
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswA_Mic1[0]&MCB_MC1VOL;
++              if((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolL == MCDRV_REG_MUTE))
++              {
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_MC1VOL, bVolL);
++              }
++              bVolL   = (UINT8)sVolInfo.aswA_Mic2[0]&MCB_MC2VOL;
++              if((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolL == MCDRV_REG_MUTE))
++              {
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_MC2VOL, bVolL);
++              }
++              bVolL   = (UINT8)sVolInfo.aswA_Mic3[0]&MCB_MC3VOL;
++              if((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolL == MCDRV_REG_MUTE))
++              {
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_MC3VOL, bVolL);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswA_Ad0[0]&MCB_ADVOL_L;
++              bVolR   = (UINT8)sVolInfo.aswA_Ad0[1]&MCB_ADVOL_R;
++              if(bVolL != (McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_ADVOL_L) & MCB_ADVOL_L))
++              {
++                      if((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolL == MCDRV_REG_MUTE))
++                      {
++                              if(((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolR == MCDRV_REG_MUTE))
++                              && (bVolR != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_ADVOL_R)))
++                              {
++                                      bLAT    = MCB_ALAT_AD;
++                              }
++                              else
++                              {
++                                      bLAT    = 0;
++                              }
++                              bReg    = bLAT|bVolL;
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_ADVOL_L, bReg);
++                      }
++              }
++              if((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolR == MCDRV_REG_MUTE))
++              {
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_ADVOL_R, bVolR);
++              }
++
++              bVolL   = (UINT8)sVolInfo.aswA_Mic2Gain[0]&0x03;
++              bVolL   = (UINT8)((bVolL << 4) & MCB_MC2GAIN) | ((UINT8)sVolInfo.aswA_Mic1Gain[0]&MCB_MC1GAIN);
++              bVolL |= ((sInitInfo.bMic2Sng << 6) & MCB_MC2SNG);
++              bVolL |= ((sInitInfo.bMic1Sng << 2) & MCB_MC1SNG);
++              if(eMode == eMCDRV_VOLUPDATE_MUTE)
++              {
++                      bReg    = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_MC_GAIN);
++                      if(((bReg & MCB_MC2GAIN) == 0) && ((bReg & MCB_MC1GAIN) == 0))
++                      {
++                              ;
++                      }
++                      else
++                      {
++                              if((bReg & MCB_MC2GAIN) == 0)
++                              {
++                                      bVolL &= (UINT8)~MCB_MC2GAIN;
++                              }
++                              else if((bReg & MCB_MC1GAIN) == 0)
++                              {
++                                      bVolL &= (UINT8)~MCB_MC1GAIN;
++                              }
++                              else
++                              {
++                              }
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_MC_GAIN, bVolL);
++                      }
++              }
++              else
++              {
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_MC_GAIN, bVolL);
++              }
++
++              bVolL   = ((UINT8)sVolInfo.aswA_Mic3Gain[0]&MCB_MC3GAIN) | ((sInitInfo.bMic3Sng << 2) & MCB_MC3SNG);
++              if(eMode == eMCDRV_VOLUPDATE_MUTE)
++              {
++                      bReg    = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_MC3_GAIN);
++                      if((bReg & MCB_MC3GAIN) == 0)
++                      {
++                              ;
++                      }
++                      else
++                      {
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_MC3_GAIN, bVolL);
++                      }
++              }
++              else
++              {
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_MC3_GAIN, bVolL);
++              }
++
++              /*      DIT0_INVOL      */
++              bVolL   = (UINT8)sVolInfo.aswD_Dit0[0]&MCB_DIT0_INVOLL;
++              bVolR   = (UINT8)sVolInfo.aswD_Dit0[1]&MCB_DIT0_INVOLR;
++              AddDigVolPacket(bVolL, bVolR, MCI_DIT0_INVOLL, MCB_DIT0_INLAT, MCI_DIT0_INVOLR, eMode);
++
++              /*      DIT1_INVOL      */
++              bVolL   = (UINT8)sVolInfo.aswD_Dit1[0]&MCB_DIT1_INVOLL;
++              bVolR   = (UINT8)sVolInfo.aswD_Dit1[1]&MCB_DIT1_INVOLR;
++              AddDigVolPacket(bVolL, bVolR, MCI_DIT1_INVOLL, MCB_DIT1_INLAT, MCI_DIT1_INVOLR, eMode);
++
++              /*      DIT2_INVOL      */
++              bVolL   = (UINT8)sVolInfo.aswD_Dit2[0]&MCB_DIT2_INVOLL;
++              bVolR   = (UINT8)sVolInfo.aswD_Dit2[1]&MCB_DIT2_INVOLR;
++              AddDigVolPacket(bVolL, bVolR, MCI_DIT2_INVOLL, MCB_DIT2_INLAT, MCI_DIT2_INVOLR, eMode);
++
++              /*      PDM0_VOL        */
++              bVolL   = (UINT8)sVolInfo.aswD_Pdm[0]&MCB_PDM0_VOLL;
++              bVolR   = (UINT8)sVolInfo.aswD_Pdm[1]&MCB_PDM0_VOLR;
++              AddDigVolPacket(bVolL, bVolR, MCI_PDM0_VOLL, MCB_PDM0_LAT, MCI_PDM0_VOLR, eMode);
++
++              /*      DIR0_VOL        */
++              bVolL   = (UINT8)sVolInfo.aswD_Dir0[0]&MCB_DIR0_VOLL;
++              bVolR   = (UINT8)sVolInfo.aswD_Dir0[1]&MCB_DIR0_VOLR;
++              AddDigVolPacket(bVolL, bVolR, MCI_DIR0_VOLL, MCB_DIR0_LAT, MCI_DIR0_VOLR, eMode);
++
++              /*      DIR1_VOL        */
++              bVolL   = (UINT8)sVolInfo.aswD_Dir1[0]&MCB_DIR1_VOLL;
++              bVolR   = (UINT8)sVolInfo.aswD_Dir1[1]&MCB_DIR1_VOLR;
++              AddDigVolPacket(bVolL, bVolR, MCI_DIR1_VOLL, MCB_DIR1_LAT, MCI_DIR1_VOLR, eMode);
++
++              /*      DIR2_VOL        */
++              bVolL   = (UINT8)sVolInfo.aswD_Dir2[0]&MCB_DIR2_VOLL;
++              bVolR   = (UINT8)sVolInfo.aswD_Dir2[1]&MCB_DIR2_VOLR;
++              AddDigVolPacket(bVolL, bVolR, MCI_DIR2_VOLL, MCB_DIR2_LAT, MCI_DIR2_VOLR, eMode);
++
++              /*      ADC_VOL */
++              bVolL   = (UINT8)sVolInfo.aswD_Ad0[0]&MCB_ADC_VOLL;
++              bVolR   = (UINT8)sVolInfo.aswD_Ad0[1]&MCB_ADC_VOLR;
++              AddDigVolPacket(bVolL, bVolR, MCI_ADC_VOLL, MCB_ADC_LAT, MCI_ADC_VOLR, eMode);
++
++              if(McDevProf_IsValid(eMCDRV_FUNC_ADC1) == 1)
++              {
++#if 0
++                      bVolL   = (UINT8)sVolInfo.aswD_Ad1[0]&MCB_ADC1_VOLL;
++                      bVolR   = (UINT8)sVolInfo.aswD_Ad1[1]&MCB_ADC1_VOLR;
++                      AddDigVolPacket(bVolL, bVolR, MCI_ADC1_VOLL, MCB_ADC1_LAT, MCI_ADC1_VOLR, eMode);
++#endif
++              }
++
++              /*      AENG6_VOL       */
++              bVolL   = (UINT8)sVolInfo.aswD_Aeng6[0]&MCB_AENG6_VOLL;
++              bVolR   = (UINT8)sVolInfo.aswD_Aeng6[1]&MCB_AENG6_VOLR;
++              AddDigVolPacket(bVolL, bVolR, MCI_AENG6_VOLL, MCB_AENG6_LAT, MCI_AENG6_VOLR, eMode);
++
++              /*      ADC_ATT */
++              bVolL   = (UINT8)sVolInfo.aswD_Ad0Att[0]&MCB_ADC_ATTL;
++              bVolR   = (UINT8)sVolInfo.aswD_Ad0Att[1]&MCB_ADC_ATTR;
++              AddDigVolPacket(bVolL, bVolR, MCI_ADC_ATTL, MCB_ADC_ALAT, MCI_ADC_ATTR, eMode);
++
++              /*      DIR0_ATT        */
++              bVolL   = (UINT8)sVolInfo.aswD_Dir0Att[0]&MCB_DIR0_ATTL;
++              bVolR   = (UINT8)sVolInfo.aswD_Dir0Att[1]&MCB_DIR0_ATTR;
++              AddDigVolPacket(bVolL, bVolR, MCI_DIR0_ATTL, MCB_DIR0_ALAT, MCI_DIR0_ATTR, eMode);
++
++              /*      DIR1_ATT        */
++              bVolL   = (UINT8)sVolInfo.aswD_Dir1Att[0]&MCB_DIR1_ATTL;
++              bVolR   = (UINT8)sVolInfo.aswD_Dir1Att[1]&MCB_DIR1_ATTR;
++              AddDigVolPacket(bVolL, bVolR, MCI_DIR1_ATTL, MCB_DIR1_ALAT, MCI_DIR1_ATTR, eMode);
++
++              /*      DIR2_ATT        */
++              bVolL   = (UINT8)sVolInfo.aswD_Dir2Att[0]&MCB_DIR2_ATTL;
++              bVolR   = (UINT8)sVolInfo.aswD_Dir2Att[1]&MCB_DIR2_ATTR;
++              AddDigVolPacket(bVolL, bVolR, MCI_DIR2_ATTL, MCB_DIR2_ALAT, MCI_DIR2_ATTR, eMode);
++
++              /*      ST_VOL  */
++              if(McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_AENG6_SOURCE) == MCB_AENG6_PDM)
++              {
++                      bVolL   = (UINT8)sVolInfo.aswD_SideTone[0]&MCB_ST_VOLL;
++                      bVolR   = (UINT8)sVolInfo.aswD_SideTone[1]&MCB_ST_VOLR;
++                      AddDigVolPacket(bVolL, bVolR, MCI_ST_VOLL, MCB_ST_LAT, MCI_ST_VOLR, eMode);
++              }
++
++              /*      MASTER_OUT      */
++              bVolL   = (UINT8)sVolInfo.aswD_DacMaster[0]&MCB_MASTER_OUTL;
++              bVolR   = (UINT8)sVolInfo.aswD_DacMaster[1]&MCB_MASTER_OUTR;
++              AddDigVolPacket(bVolL, bVolR, MCI_MASTER_OUTL, MCB_MASTER_OLAT, MCI_MASTER_OUTR, eMode);
++
++              /*      VOICE_ATT       */
++              bVolL   = (UINT8)sVolInfo.aswD_DacVoice[0]&MCB_VOICE_ATTL;
++              bVolR   = (UINT8)sVolInfo.aswD_DacVoice[1]&MCB_VOICE_ATTR;
++              AddDigVolPacket(bVolL, bVolR, MCI_VOICE_ATTL, MCB_VOICE_LAT, MCI_VOICE_ATTR, eMode);
++
++              /*      DAC_ATT */
++              bVolL   = (UINT8)sVolInfo.aswD_DacAtt[0]&MCB_DAC_ATTL;
++              bVolR   = (UINT8)sVolInfo.aswD_DacAtt[1]&MCB_DAC_ATTR;
++              AddDigVolPacket(bVolL, bVolR, MCI_DAC_ATTL, MCB_DAC_LAT, MCI_DAC_ATTR, eMode);
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McPacket_AddVol", &sdRet);
++#endif
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    AddDigVolPacket
++ *
++ *    Description:
++ *                    Add digital vol setup packet.
++ *    Arguments:
++ *                            bVolL           Left volume
++ *                            bVolR           Right volume
++ *                            bVolLAddr       Left volume register address
++ *                            bLAT            LAT
++ *                            bVolRAddr       Right volume register address
++ *                            eMode           update mode
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   AddDigVolPacket
++(
++      UINT8   bVolL,
++      UINT8   bVolR,
++      UINT8   bVolLAddr,
++      UINT8   bLAT,
++      UINT8   bVolRAddr,
++      MCDRV_VOLUPDATE_MODE    eMode
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("AddDigVolPacket");
++#endif
++
++      if(bVolL != (McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, bVolLAddr) & (UINT8)~bLAT))
++      {
++              if((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolL == MCDRV_REG_MUTE))
++              {
++                      if(((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolR == MCDRV_REG_MUTE))
++                      && (bVolR != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, bVolRAddr)))
++                      {
++                      }
++                      else
++                      {
++                              bLAT    = 0;
++                      }
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)bVolLAddr, bLAT|bVolL);
++              }
++      }
++      if((eMode != eMCDRV_VOLUPDATE_MUTE) || (bVolR == MCDRV_REG_MUTE))
++      {
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)bVolRAddr, bVolR);
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("AddDigVolPacket", 0);
++#endif
++}
++
++/****************************************************************************
++ *    AddStopADC
++ *
++ *    Description:
++ *                    Add stop ADC packet.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   AddStopADC
++(
++      void
++)
++{
++      UINT8   bReg;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("AddStopADC");
++#endif
++
++      bReg    = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_CODEC, MCI_AD_START);
++
++      if((bReg & MCB_AD_START) != 0)
++      {
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_AD_START, bReg&(UINT8)~MCB_AD_START);
++      }
++
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_EVTWAIT | MCDRV_EVT_ADCMUTE, 0);
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("AddStopADC", 0);
++#endif
++}
++
++/****************************************************************************
++ *    AddStopPDM
++ *
++ *    Description:
++ *                    Add stop PDM packet.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   AddStopPDM
++(
++      void
++)
++{
++      UINT8   bReg;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("AddStopPDM");
++#endif
++
++      bReg    = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_PDM_START);
++
++      if((bReg & MCB_PDM_START) != 0)
++      {
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_PDM_START, bReg&(UINT8)~MCB_PDM_START);
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("AddStopPDM", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McPacket_AddDigitalIO
++ *
++ *    Description:
++ *                    Add DigitalI0 setup packet.
++ *    Arguments:
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddDigitalIO
++(
++      UINT32  dUpdateInfo
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bReg;
++      MCDRV_POWER_INFO        sPowerInfo;
++      MCDRV_POWER_UPDATE      sPowerUpdate;
++      MCDRV_DIO_INFO          sDioInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McPacket_AddDigitalIO");
++#endif
++
++      if(IsModifiedDIO(dUpdateInfo) != 0)
++      {
++              McResCtrl_GetCurPowerInfo(&sPowerInfo);
++              sdRet   = PowerUpDig(MCDRV_DPB_UP);
++              if(sdRet == MCDRV_SUCCESS)
++              {
++                      if((dUpdateInfo & MCDRV_DIO0_COM_UPDATE_FLAG) != (UINT32)0)
++                      {
++                              AddDIOCommon(eMCDRV_DIO_0);
++                      }
++                      if((dUpdateInfo & MCDRV_DIO1_COM_UPDATE_FLAG) != (UINT32)0)
++                      {
++                              AddDIOCommon(eMCDRV_DIO_1);
++                      }
++                      if((dUpdateInfo & MCDRV_DIO2_COM_UPDATE_FLAG) != (UINT32)0)
++                      {
++                              AddDIOCommon(eMCDRV_DIO_2);
++                      }
++
++                      /*      DI*_BCKP        */
++                      if(((dUpdateInfo & MCDRV_DIO0_COM_UPDATE_FLAG) != (UINT32)0)
++                      || ((dUpdateInfo & MCDRV_DIO1_COM_UPDATE_FLAG) != (UINT32)0)
++                      || ((dUpdateInfo & MCDRV_DIO2_COM_UPDATE_FLAG) != (UINT32)0))
++                      {
++                              McResCtrl_GetDioInfo(&sDioInfo);
++                              bReg    = 0;
++                              if(sDioInfo.asPortInfo[0].sDioCommon.bBckInvert == MCDRV_BCLK_INVERT)
++                              {
++                                      bReg |= MCB_DI0_BCKP;
++                              }
++                              if(sDioInfo.asPortInfo[1].sDioCommon.bBckInvert == MCDRV_BCLK_INVERT)
++                              {
++                                      bReg |= MCB_DI1_BCKP;
++                              }
++                              if(sDioInfo.asPortInfo[2].sDioCommon.bBckInvert == MCDRV_BCLK_INVERT)
++                              {
++                                      bReg |= MCB_DI2_BCKP;
++                              }
++                              if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_BASE, MCI_BCKP))
++                              {
++                                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_BCKP, bReg);
++                              }
++                      }
++
++                      if((dUpdateInfo & MCDRV_DIO0_DIR_UPDATE_FLAG) != (UINT32)0)
++                      {
++                              AddDIODIR(eMCDRV_DIO_0);
++                      }
++                      if((dUpdateInfo & MCDRV_DIO1_DIR_UPDATE_FLAG) != (UINT32)0)
++                      {
++                              AddDIODIR(eMCDRV_DIO_1);
++                      }
++                      if((dUpdateInfo & MCDRV_DIO2_DIR_UPDATE_FLAG) != (UINT32)0)
++                      {
++                              AddDIODIR(eMCDRV_DIO_2);
++                      }
++
++                      if((dUpdateInfo & MCDRV_DIO0_DIT_UPDATE_FLAG) != (UINT32)0)
++                      {
++                              AddDIODIT(eMCDRV_DIO_0);
++                      }
++                      if((dUpdateInfo & MCDRV_DIO1_DIT_UPDATE_FLAG) != (UINT32)0)
++                      {
++                              AddDIODIT(eMCDRV_DIO_1);
++                      }
++                      if((dUpdateInfo & MCDRV_DIO2_DIT_UPDATE_FLAG) != (UINT32)0)
++                      {
++                              AddDIODIT(eMCDRV_DIO_2);
++                      }
++
++                      /*      unused path power down  */
++                      sPowerUpdate.dDigital           = MCDRV_POWUPDATE_DIGITAL_ALL;
++                      sPowerUpdate.abAnalog[0]        = 
++                      sPowerUpdate.abAnalog[1]        = 
++                      sPowerUpdate.abAnalog[2]        = 
++                      sPowerUpdate.abAnalog[3]        = 
++                      sPowerUpdate.abAnalog[4]        = 0;
++                      sdRet   = McPacket_AddPowerDown(&sPowerInfo, &sPowerUpdate);
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McPacket_AddDigitalIO", &sdRet);
++#endif
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    IsModifiedDIO
++ *
++ *    Description:
++ *                    Is modified DigitalIO.
++ *    Arguments:
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    0:not modified/1:modified
++ *
++ ****************************************************************************/
++static UINT8  IsModifiedDIO
++(
++      UINT32          dUpdateInfo
++)
++{
++      UINT8   bModified       = 0;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("IsModifiedDIO");
++#endif
++
++      if((((dUpdateInfo & MCDRV_DIO0_COM_UPDATE_FLAG) != (UINT32)0) && (IsModifiedDIOCommon(eMCDRV_DIO_0) != 0))
++      || (((dUpdateInfo & MCDRV_DIO1_COM_UPDATE_FLAG) != (UINT32)0) && (IsModifiedDIOCommon(eMCDRV_DIO_1) != 0))
++      || (((dUpdateInfo & MCDRV_DIO2_COM_UPDATE_FLAG) != (UINT32)0) && (IsModifiedDIOCommon(eMCDRV_DIO_2) != 0)))
++      {
++              bModified       = 1;
++      }
++      else if((((dUpdateInfo & MCDRV_DIO0_DIR_UPDATE_FLAG) != (UINT32)0) && (IsModifiedDIODIR(eMCDRV_DIO_0) != 0))
++      || (((dUpdateInfo & MCDRV_DIO1_DIR_UPDATE_FLAG) != (UINT32)0) && (IsModifiedDIODIR(eMCDRV_DIO_1) != 0))
++      || (((dUpdateInfo & MCDRV_DIO2_DIR_UPDATE_FLAG) != (UINT32)0) && (IsModifiedDIODIR(eMCDRV_DIO_2) != 0)))
++      {
++              bModified       = 1;
++      }
++      else if((((dUpdateInfo & MCDRV_DIO0_DIT_UPDATE_FLAG) != (UINT32)0) && (IsModifiedDIODIT(eMCDRV_DIO_0) != 0))
++      || (((dUpdateInfo & MCDRV_DIO1_DIT_UPDATE_FLAG) != (UINT32)0) && (IsModifiedDIODIT(eMCDRV_DIO_1) != 0))
++      || (((dUpdateInfo & MCDRV_DIO2_DIT_UPDATE_FLAG) != (UINT32)0) && (IsModifiedDIODIT(eMCDRV_DIO_2) != 0)))
++      {
++              bModified       = 1;
++      }
++      else
++      {
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = (SINT32)bModified;
++      McDebugLog_FuncOut("IsModifiedDIO", &sdRet);
++#endif
++      return bModified;
++}
++
++/****************************************************************************
++ *    IsModifiedDIOCommon
++ *
++ *    Description:
++ *                    Is modified DigitalIO Common.
++ *    Arguments:
++ *                    ePort           port number
++ *    Return:
++ *                    0:not modified/1:modified
++ *
++ ****************************************************************************/
++static UINT8  IsModifiedDIOCommon
++(
++      MCDRV_DIO_PORT_NO       ePort
++)
++{
++      UINT8   bReg;
++      UINT8   bRegOffset;
++      UINT8   bModified       = 0;
++      MCDRV_DIO_INFO  sDioInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("IsModifiedDIOCommon");
++#endif
++
++      if(ePort == eMCDRV_DIO_0)
++      {
++              bRegOffset      = 0;
++      }
++      else if(ePort == eMCDRV_DIO_1)
++      {
++              bRegOffset      = MCI_DIMODE1 - MCI_DIMODE0;
++      }
++      else if(ePort == eMCDRV_DIO_2)
++      {
++              bRegOffset      = MCI_DIMODE2 - MCI_DIMODE0;
++      }
++      else
++      {
++              #if (MCDRV_DEBUG_LEVEL>=4)
++                      sdRet   = MCDRV_ERROR;
++                      McDebugLog_FuncOut("IsModifiedDIOCommon", &sdRet);
++              #endif
++              return 0;
++      }
++
++      McResCtrl_GetDioInfo(&sDioInfo);
++
++      if(sDioInfo.asPortInfo[ePort].sDioCommon.bInterface != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DIMODE0+bRegOffset))
++      {
++              bModified       = 1;
++      }
++
++      bReg    = (sDioInfo.asPortInfo[ePort].sDioCommon.bAutoFs << 7)
++                      | (sDioInfo.asPortInfo[ePort].sDioCommon.bBckFs << 4)
++                      | sDioInfo.asPortInfo[ePort].sDioCommon.bFs;
++      if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DI_FS0+bRegOffset))
++      {
++              bModified       = 1;
++      }
++
++      bReg    = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DI0_SRC+bRegOffset);
++      if((sDioInfo.asPortInfo[ePort].sDioCommon.bAutoFs == 0)
++      && (sDioInfo.asPortInfo[ePort].sDioCommon.bMasterSlave == MCDRV_DIO_SLAVE))
++      {
++              bReg |= MCB_DICOMMON_SRC_RATE_SET;
++      }
++      if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DI0_SRC+bRegOffset))
++      {
++              bModified       = 1;
++      }
++      if(sDioInfo.asPortInfo[ePort].sDioCommon.bInterface == MCDRV_DIO_PCM)
++      {
++              bReg    = (sDioInfo.asPortInfo[ePort].sDioCommon.bPcmHizTim << 7)
++                              | (sDioInfo.asPortInfo[ePort].sDioCommon.bPcmClkDown << 6)
++                              | (sDioInfo.asPortInfo[ePort].sDioCommon.bPcmFrame << 5)
++                              | (sDioInfo.asPortInfo[ePort].sDioCommon.bPcmHighPeriod);
++              if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_HIZ_REDGE0+bRegOffset))
++              {
++                      bModified       = 1;
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = (SINT32)bModified;
++      McDebugLog_FuncOut("IsModifiedDIOCommon", &sdRet);
++#endif
++      return bModified;
++}
++
++/****************************************************************************
++ *    IsModifiedDIODIR
++ *
++ *    Description:
++ *                    Is modified DigitalIO DIR.
++ *    Arguments:
++ *                    ePort           port number
++ *    Return:
++ *                    0:not modified/1:modified
++ *
++ ****************************************************************************/
++static UINT8  IsModifiedDIODIR
++(
++      MCDRV_DIO_PORT_NO       ePort
++)
++{
++      UINT8   bReg;
++      UINT8   bRegOffset;
++      UINT8   bModified       = 0;
++      MCDRV_DIO_INFO  sDioInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("IsModifiedDIODIR");
++#endif
++
++      if(ePort == eMCDRV_DIO_0)
++      {
++              bRegOffset      = 0;
++      }
++      else if(ePort == eMCDRV_DIO_1)
++      {
++              bRegOffset      = MCI_DIMODE1 - MCI_DIMODE0;
++      }
++      else if(ePort == eMCDRV_DIO_2)
++      {
++              bRegOffset      = MCI_DIMODE2 - MCI_DIMODE0;
++      }
++      else
++      {
++              #if (MCDRV_DEBUG_LEVEL>=4)
++                      sdRet   = MCDRV_ERROR;
++                      McDebugLog_FuncOut("IsModifiedDIODIR", &sdRet);
++              #endif
++              return 0;
++      }
++
++      McResCtrl_GetDioInfo(&sDioInfo);
++
++      bReg    = (UINT8)(sDioInfo.asPortInfo[ePort].sDir.wSrcRate>>8);
++      if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DIRSRC_RATE0_MSB+bRegOffset))
++      {
++              bModified       = 1;
++      }
++
++      bReg    = (UINT8)sDioInfo.asPortInfo[ePort].sDir.wSrcRate;
++      if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DIRSRC_RATE0_LSB+bRegOffset))
++      {
++              bModified       = 1;
++      }
++
++      if(sDioInfo.asPortInfo[ePort].sDioCommon.bInterface == MCDRV_DIO_DA)
++      {
++              bReg    = (sDioInfo.asPortInfo[ePort].sDit.sDaFormat.bMode << 6)
++                              | (sDioInfo.asPortInfo[ePort].sDit.sDaFormat.bBitSel << 4)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sDaFormat.bMode << 2)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sDaFormat.bBitSel);
++              if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DIX0_FMT+bRegOffset))
++              {
++                      bModified       = 1;
++              }
++              /*      DIR*_CH */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDir.abSlot[1] << 4) | (sDioInfo.asPortInfo[ePort].sDir.abSlot[0]);
++              if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DIR0_CH+bRegOffset))
++              {
++                      bModified       = 1;
++              }
++      }
++      else
++      {
++              /*      PCM_MONO_RX*, PCM_EXTEND_RX*, PCM_LSBON_RX*, PCM_LAW_RX*, PCM_BIT_RX*   */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDir.sPcmFormat.bMono << 7)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sPcmFormat.bOrder << 4)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sPcmFormat.bLaw << 2)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sPcmFormat.bBitSel);
++              if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_PCM_RX0+bRegOffset))
++              {
++                      bModified       = 1;
++              }
++              /*      PCM_CH1_RX*, PCM_CH0_RX*        */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDir.abSlot[1] << 4) | (sDioInfo.asPortInfo[ePort].sDir.abSlot[0]);
++              if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_PCM_SLOT_RX0+bRegOffset))
++              {
++                      bModified       = 1;
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = (SINT32)bModified;
++      McDebugLog_FuncOut("IsModifiedDIODIR", &sdRet);
++#endif
++      return bModified;
++}
++
++/****************************************************************************
++ *    IsModifiedDIODIT
++ *
++ *    Description:
++ *                    Is modified DigitalIO DIT.
++ *    Arguments:
++ *                    ePort           port number
++ *    Return:
++ *                    0:not modified/1:modified
++ *
++ ****************************************************************************/
++static UINT8  IsModifiedDIODIT
++(
++      MCDRV_DIO_PORT_NO       ePort
++)
++{
++      UINT8   bReg;
++      UINT8   bRegOffset;
++      UINT8   bModified       = 0;
++      MCDRV_DIO_INFO  sDioInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("IsModifiedDIODIT");
++#endif
++
++      if(ePort == eMCDRV_DIO_0)
++      {
++              bRegOffset      = 0;
++      }
++      else if(ePort == eMCDRV_DIO_1)
++      {
++              bRegOffset      = MCI_DIMODE1 - MCI_DIMODE0;
++      }
++      else if(ePort == eMCDRV_DIO_2)
++      {
++              bRegOffset      = MCI_DIMODE2 - MCI_DIMODE0;
++      }
++      else
++      {
++              #if (MCDRV_DEBUG_LEVEL>=4)
++                      sdRet   = MCDRV_ERROR;
++                      McDebugLog_FuncOut("IsModifiedDIODIT", &sdRet);
++              #endif
++              return 0;
++      }
++
++      McResCtrl_GetDioInfo(&sDioInfo);
++
++      bReg    = (UINT8)(sDioInfo.asPortInfo[ePort].sDit.wSrcRate>>8);
++      if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DITSRC_RATE0_MSB+bRegOffset))
++      {
++              bModified       = 1;
++      }
++      bReg    = (UINT8)sDioInfo.asPortInfo[ePort].sDit.wSrcRate;
++      if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DITSRC_RATE0_LSB+bRegOffset))
++      {
++              bModified       = 1;
++      }
++
++      if(sDioInfo.asPortInfo[ePort].sDioCommon.bInterface == MCDRV_DIO_DA)
++      {
++              /*      DIT*_FMT, DIT*_BIT, DIR*_FMT, DIR*_BIT  */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDit.sDaFormat.bMode << 6)
++                              | (sDioInfo.asPortInfo[ePort].sDit.sDaFormat.bBitSel << 4)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sDaFormat.bMode << 2)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sDaFormat.bBitSel);
++              if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DIX0_FMT+bRegOffset))
++              {
++                      bModified       = 1;
++              }
++
++              /*      DIT*_SLOT       */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDit.abSlot[1] << 4) | (sDioInfo.asPortInfo[ePort].sDit.abSlot[0]);
++              if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DIT0_SLOT+bRegOffset))
++              {
++                      bModified       = 1;
++              }
++      }
++      else
++      {
++              /*      PCM_MONO_TX*, PCM_EXTEND_TX*, PCM_LSBON_TX*, PCM_LAW_TX*, PCM_BIT_TX*   */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDit.sPcmFormat.bMono << 7)
++                              | (sDioInfo.asPortInfo[ePort].sDit.sPcmFormat.bOrder << 4)
++                              | (sDioInfo.asPortInfo[ePort].sDit.sPcmFormat.bLaw << 2)
++                              | (sDioInfo.asPortInfo[ePort].sDit.sPcmFormat.bBitSel);
++              if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_PCM_TX0+bRegOffset))
++              {
++                      bModified       = 1;
++              }
++
++              /*      PCM_CH1_TX*, PCM_CH0_TX*        */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDit.abSlot[1] << 4) | (sDioInfo.asPortInfo[ePort].sDit.abSlot[0]);
++              if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_PCM_SLOT_TX0+bRegOffset))
++              {
++                      bModified       = 1;
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = (SINT32)bModified;
++      McDebugLog_FuncOut("IsModifiedDIODIT", &sdRet);
++#endif
++      return bModified;
++}
++
++/****************************************************************************
++ *    AddDIOCommon
++ *
++ *    Description:
++ *                    Add DigitalI0 Common setup packet.
++ *    Arguments:
++ *                    ePort           port number
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   AddDIOCommon
++(
++      MCDRV_DIO_PORT_NO       ePort
++)
++{
++      UINT8   bReg;
++      UINT8   bRegOffset;
++      MCDRV_DIO_INFO  sDioInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("AddDIOCommon");
++#endif
++
++      if(ePort == eMCDRV_DIO_0)
++      {
++              bRegOffset      = 0;
++      }
++      else if(ePort == eMCDRV_DIO_1)
++      {
++              bRegOffset      = MCI_DIMODE1 - MCI_DIMODE0;
++      }
++      else if(ePort == eMCDRV_DIO_2)
++      {
++              bRegOffset      = MCI_DIMODE2 - MCI_DIMODE0;
++      }
++      else
++      {
++
++              #if (MCDRV_DEBUG_LEVEL>=4)
++                      sdRet   = MCDRV_ERROR;
++                      McDebugLog_FuncOut("AddDIOCommon", &sdRet);
++              #endif
++              return;
++      }
++
++      McResCtrl_GetDioInfo(&sDioInfo);
++
++      /*      DIMODE* */
++      if(sDioInfo.asPortInfo[ePort].sDioCommon.bInterface != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DIMODE0+bRegOffset))
++      {
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)(MCI_DIMODE0+bRegOffset),
++                                                      sDioInfo.asPortInfo[ePort].sDioCommon.bInterface);
++      }
++
++      /*      DIAUTO_FS*, DIBCK*, DIFS*       */
++      bReg    = (sDioInfo.asPortInfo[ePort].sDioCommon.bAutoFs << 7)
++                      | (sDioInfo.asPortInfo[ePort].sDioCommon.bBckFs << 4)
++                      | sDioInfo.asPortInfo[ePort].sDioCommon.bFs;
++      if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DI_FS0+bRegOffset))
++      {
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)(MCI_DI_FS0+bRegOffset), bReg);
++      }
++
++      /*      DI*_SRCRATE_SET */
++      bReg    = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DI0_SRC+bRegOffset);
++      if((sDioInfo.asPortInfo[ePort].sDioCommon.bAutoFs == 0)
++      && (sDioInfo.asPortInfo[ePort].sDioCommon.bMasterSlave == MCDRV_DIO_SLAVE))
++      {
++              bReg |= MCB_DICOMMON_SRC_RATE_SET;
++      }
++      else
++      {
++              bReg &= (UINT8)~MCB_DICOMMON_SRC_RATE_SET;
++      }
++      if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DI0_SRC+bRegOffset))
++      {
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)(MCI_DI0_SRC+bRegOffset), bReg);
++      }
++
++      /*      HIZ_REDGE*, PCM_CLKDOWN*, PCM_FRAME*, PCM_HPERIOD*      */
++      if(sDioInfo.asPortInfo[ePort].sDioCommon.bInterface == MCDRV_DIO_PCM)
++      {
++              bReg    = (sDioInfo.asPortInfo[ePort].sDioCommon.bPcmHizTim << 7)
++                              | (sDioInfo.asPortInfo[ePort].sDioCommon.bPcmClkDown << 6)
++                              | (sDioInfo.asPortInfo[ePort].sDioCommon.bPcmFrame << 5)
++                              | (sDioInfo.asPortInfo[ePort].sDioCommon.bPcmHighPeriod);
++              if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_HIZ_REDGE0+bRegOffset))
++              {
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)(MCI_HIZ_REDGE0+bRegOffset), bReg);
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("AddDIOCommon", 0);
++#endif
++}
++
++/****************************************************************************
++ *    AddDIODIR
++ *
++ *    Description:
++ *                    Add DigitalI0 DIR setup packet.
++ *    Arguments:
++ *                    ePort           port number
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   AddDIODIR
++(
++      MCDRV_DIO_PORT_NO       ePort
++)
++{
++      UINT8   bReg;
++      UINT8   bRegOffset;
++      UINT16  wSrcRate;
++      MCDRV_DIO_INFO  sDioInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("AddDIODIR");
++#endif
++
++      if(ePort == eMCDRV_DIO_0)
++      {
++              bRegOffset      = 0;
++      }
++      else if(ePort == eMCDRV_DIO_1)
++      {
++              bRegOffset      = MCI_DIMODE1 - MCI_DIMODE0;
++      }
++      else if(ePort == eMCDRV_DIO_2)
++      {
++              bRegOffset      = MCI_DIMODE2 - MCI_DIMODE0;
++      }
++      else
++      {
++              #if (MCDRV_DEBUG_LEVEL>=4)
++                      sdRet   = MCDRV_ERROR;
++                      McDebugLog_FuncOut("AddDIODIR", &sdRet);
++              #endif
++              return;
++      }
++
++      McResCtrl_GetDioInfo(&sDioInfo);
++
++      /*      DIRSRC_RATE*    */
++      wSrcRate        = sDioInfo.asPortInfo[ePort].sDir.wSrcRate;
++      if(wSrcRate == 0)
++      {
++              switch(sDioInfo.asPortInfo[ePort].sDioCommon.bFs)
++              {
++              case MCDRV_FS_48000:
++                      wSrcRate        = MCDRV_DIR_SRCRATE_48000;
++                      break;
++              case MCDRV_FS_44100:
++                      wSrcRate        = MCDRV_DIR_SRCRATE_44100;
++                      break;
++              case MCDRV_FS_32000:
++                      wSrcRate        = MCDRV_DIR_SRCRATE_32000;
++                      break;
++              case MCDRV_FS_24000:
++                      wSrcRate        = MCDRV_DIR_SRCRATE_24000;
++                      break;
++              case MCDRV_FS_22050:
++                      wSrcRate        = MCDRV_DIR_SRCRATE_22050;
++                      break;
++              case MCDRV_FS_16000:
++                      wSrcRate        = MCDRV_DIR_SRCRATE_16000;
++                      break;
++              case MCDRV_FS_12000:
++                      wSrcRate        = MCDRV_DIR_SRCRATE_12000;
++                      break;
++              case MCDRV_FS_11025:
++                      wSrcRate        = MCDRV_DIR_SRCRATE_11025;
++                      break;
++              case MCDRV_FS_8000:
++                      wSrcRate        = MCDRV_DIR_SRCRATE_8000;
++                      break;
++              default:
++                      /* unreachable */
++                      wSrcRate = 0;
++                      break;
++              }
++      }
++      bReg    = (UINT8)(wSrcRate>>8);
++      if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DIRSRC_RATE0_MSB+bRegOffset))
++      {
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)(MCI_DIRSRC_RATE0_MSB+bRegOffset), bReg);
++      }
++      bReg    = (UINT8)wSrcRate;
++      if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DIRSRC_RATE0_LSB+bRegOffset))
++      {
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)(MCI_DIRSRC_RATE0_LSB+bRegOffset), bReg);
++      }
++
++      /*      DIT*_FMT, DIT*_BIT, DIR*_FMT, DIR*_BIT  */
++      if(sDioInfo.asPortInfo[ePort].sDioCommon.bInterface == MCDRV_DIO_DA)
++      {
++              bReg    = (sDioInfo.asPortInfo[ePort].sDit.sDaFormat.bMode << 6)
++                              | (sDioInfo.asPortInfo[ePort].sDit.sDaFormat.bBitSel << 4)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sDaFormat.bMode << 2)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sDaFormat.bBitSel);
++              if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DIX0_FMT+bRegOffset))
++              {
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)(MCI_DIX0_FMT+bRegOffset), bReg);
++              }
++              /*      DIR*_CH */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDir.abSlot[1] << 4) | (sDioInfo.asPortInfo[ePort].sDir.abSlot[0]);
++              if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DIR0_CH+bRegOffset))
++              {
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)(MCI_DIR0_CH+bRegOffset), bReg);
++              }
++      }
++      else
++      {
++              /*      PCM_MONO_RX*, PCM_EXTEND_RX*, PCM_LSBON_RX*, PCM_LAW_RX*, PCM_BIT_RX*   */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDir.sPcmFormat.bMono << 7)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sPcmFormat.bOrder << 4)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sPcmFormat.bLaw << 2)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sPcmFormat.bBitSel);
++              if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_PCM_RX0+bRegOffset))
++              {
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)(MCI_PCM_RX0+bRegOffset), bReg);
++              }
++              /*      PCM_CH1_RX*, PCM_CH0_RX*        */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDir.abSlot[1] << 4) | (sDioInfo.asPortInfo[ePort].sDir.abSlot[0]);
++              if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_PCM_SLOT_RX0+bRegOffset))
++              {
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)(MCI_PCM_SLOT_RX0+bRegOffset), bReg);
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("AddDIODIR", 0);
++#endif
++}
++
++/****************************************************************************
++ *    AddDIODIT
++ *
++ *    Description:
++ *                    Add DigitalI0 DIT setup packet.
++ *    Arguments:
++ *                    ePort           port number
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   AddDIODIT
++(
++      MCDRV_DIO_PORT_NO       ePort
++)
++{
++      UINT8   bReg;
++      UINT8   bRegOffset;
++      UINT16  wSrcRate;
++      MCDRV_DIO_INFO  sDioInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("AddDIODIT");
++#endif
++
++      if(ePort == eMCDRV_DIO_0)
++      {
++              bRegOffset      = 0;
++      }
++      else if(ePort == eMCDRV_DIO_1)
++      {
++              bRegOffset      = MCI_DIMODE1 - MCI_DIMODE0;
++      }
++      else if(ePort == eMCDRV_DIO_2)
++      {
++              bRegOffset      = MCI_DIMODE2 - MCI_DIMODE0;
++      }
++      else
++      {
++              #if (MCDRV_DEBUG_LEVEL>=4)
++                      sdRet   = MCDRV_ERROR;
++                      McDebugLog_FuncOut("AddDIODIT", &sdRet);
++              #endif
++              return;
++      }
++
++      McResCtrl_GetDioInfo(&sDioInfo);
++
++      wSrcRate        = sDioInfo.asPortInfo[ePort].sDit.wSrcRate;
++      if(wSrcRate == 0)
++      {
++              switch(sDioInfo.asPortInfo[ePort].sDioCommon.bFs)
++              {
++              case MCDRV_FS_48000:
++                      wSrcRate        = MCDRV_DIT_SRCRATE_48000;
++                      break;
++              case MCDRV_FS_44100:
++                      wSrcRate        = MCDRV_DIT_SRCRATE_44100;
++                      break;
++              case MCDRV_FS_32000:
++                      wSrcRate        = MCDRV_DIT_SRCRATE_32000;
++                      break;
++              case MCDRV_FS_24000:
++                      wSrcRate        = MCDRV_DIT_SRCRATE_24000;
++                      break;
++              case MCDRV_FS_22050:
++                      wSrcRate        = MCDRV_DIT_SRCRATE_22050;
++                      break;
++              case MCDRV_FS_16000:
++                      wSrcRate        = MCDRV_DIT_SRCRATE_16000;
++                      break;
++              case MCDRV_FS_12000:
++                      wSrcRate        = MCDRV_DIT_SRCRATE_12000;
++                      break;
++              case MCDRV_FS_11025:
++                      wSrcRate        = MCDRV_DIT_SRCRATE_11025;
++                      break;
++              case MCDRV_FS_8000:
++                      wSrcRate        = MCDRV_DIT_SRCRATE_8000;
++                      break;
++              default:
++                      /* unreachable */
++                      wSrcRate = 0;
++                      break;
++              }
++      }
++      /*      DITSRC_RATE*    */
++      bReg    = (UINT8)(wSrcRate>>8);
++      if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DITSRC_RATE0_MSB+bRegOffset))
++      {
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)(MCI_DITSRC_RATE0_MSB+bRegOffset), bReg);
++      }
++      bReg    = (UINT8)wSrcRate;
++      if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DITSRC_RATE0_LSB+bRegOffset))
++      {
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)(MCI_DITSRC_RATE0_LSB+bRegOffset), bReg);
++      }
++
++      if(sDioInfo.asPortInfo[ePort].sDioCommon.bInterface == MCDRV_DIO_DA)
++      {
++              /*      DIT*_FMT, DIT*_BIT, DIR*_FMT, DIR*_BIT  */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDit.sDaFormat.bMode << 6)
++                              | (sDioInfo.asPortInfo[ePort].sDit.sDaFormat.bBitSel << 4)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sDaFormat.bMode << 2)
++                              | (sDioInfo.asPortInfo[ePort].sDir.sDaFormat.bBitSel);
++              if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DIX0_FMT+bRegOffset))
++              {
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)(MCI_DIX0_FMT+bRegOffset), bReg);
++              }
++
++              /*      DIT*_SLOT       */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDit.abSlot[1] << 4) | (sDioInfo.asPortInfo[ePort].sDit.abSlot[0]);
++              if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DIT0_SLOT+bRegOffset))
++              {
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)(MCI_DIT0_SLOT+bRegOffset), bReg);
++              }
++      }
++      else
++      {
++              /*      PCM_MONO_TX*, PCM_EXTEND_TX*, PCM_LSBON_TX*, PCM_LAW_TX*, PCM_BIT_TX*   */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDit.sPcmFormat.bMono << 7)
++                              | (sDioInfo.asPortInfo[ePort].sDit.sPcmFormat.bOrder << 4)
++                              | (sDioInfo.asPortInfo[ePort].sDit.sPcmFormat.bLaw << 2)
++                              | (sDioInfo.asPortInfo[ePort].sDit.sPcmFormat.bBitSel);
++              if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_PCM_TX0+bRegOffset))
++              {
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)(MCI_PCM_TX0+bRegOffset), bReg);
++              }
++
++              /*      PCM_CH1_TX*, PCM_CH0_TX*        */
++              bReg    = (sDioInfo.asPortInfo[ePort].sDit.abSlot[1] << 4) | (sDioInfo.asPortInfo[ePort].sDit.abSlot[0]);
++              if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_PCM_SLOT_TX0+bRegOffset))
++              {
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)(MCI_PCM_SLOT_TX0+bRegOffset), bReg);
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("AddDIODIT", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McPacket_AddDAC
++ *
++ *    Description:
++ *                    Add DAC setup packet.
++ *    Arguments:
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddDAC
++(
++      UINT32                  dUpdateInfo
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      MCDRV_POWER_INFO        sPowerInfo;
++      MCDRV_POWER_UPDATE      sPowerUpdate;
++      MCDRV_DAC_INFO          sDacInfo;
++      UINT8   bReg;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McPacket_AddDAC");
++#endif
++
++      McResCtrl_GetDacInfo(&sDacInfo);
++
++      if(((dUpdateInfo & MCDRV_DAC_MSWP_UPDATE_FLAG) != (UINT32)0) || ((dUpdateInfo & MCDRV_DAC_VSWP_UPDATE_FLAG) != (UINT32)0))
++      {
++              bReg    = (sDacInfo.bMasterSwap<<4)|sDacInfo.bVoiceSwap;
++              if(bReg == McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_SWP))
++              {
++                      dUpdateInfo     &= ~(MCDRV_DAC_MSWP_UPDATE_FLAG|MCDRV_DAC_VSWP_UPDATE_FLAG);
++              }
++      }
++      if((dUpdateInfo & MCDRV_DAC_HPF_UPDATE_FLAG) != (UINT32)0)
++      {
++              if(sDacInfo.bDcCut == McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_CODEC, MCI_DCCUTOFF))
++              {
++                      dUpdateInfo     &= ~(MCDRV_DAC_HPF_UPDATE_FLAG);
++              }
++      }
++
++      if(dUpdateInfo != (UINT32)0)
++      {
++              McResCtrl_GetCurPowerInfo(&sPowerInfo);
++              sdRet   = PowerUpDig(MCDRV_DPB_UP);
++              if(sdRet == MCDRV_SUCCESS)
++              {
++                      if(((dUpdateInfo & MCDRV_DAC_MSWP_UPDATE_FLAG) != (UINT32)0) || ((dUpdateInfo & MCDRV_DAC_VSWP_UPDATE_FLAG) != (UINT32)0))
++                      {
++                              bReg    = (sDacInfo.bMasterSwap<<4)|sDacInfo.bVoiceSwap;
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_SWP, bReg);
++                      }
++                      if((dUpdateInfo & MCDRV_DAC_HPF_UPDATE_FLAG) != (UINT32)0)
++                      {
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DCCUTOFF, sDacInfo.bDcCut);
++                      }
++
++                      /*      unused path power down  */
++                      sPowerUpdate.dDigital           = MCDRV_POWUPDATE_DIGITAL_ALL;
++                      sPowerUpdate.abAnalog[0]        = 
++                      sPowerUpdate.abAnalog[1]        = 
++                      sPowerUpdate.abAnalog[2]        = 
++                      sPowerUpdate.abAnalog[3]        = 
++                      sPowerUpdate.abAnalog[4]        = 0;
++                      sdRet   = McPacket_AddPowerDown(&sPowerInfo, &sPowerUpdate);
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McPacket_AddDAC", &sdRet);
++#endif
++      return sdRet;
++}
++
++/****************************************************************************
++ *    McPacket_AddADC
++ *
++ *    Description:
++ *                    Add ADC setup packet.
++ *    Arguments:
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddADC
++(
++      UINT32                  dUpdateInfo
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bReg;
++      MCDRV_POWER_INFO        sPowerInfo;
++      MCDRV_POWER_UPDATE      sPowerUpdate;
++      MCDRV_ADC_INFO          sAdcInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McPacket_AddADC");
++#endif
++
++      McResCtrl_GetAdcInfo(&sAdcInfo);
++
++      if(((dUpdateInfo & MCDRV_ADCADJ_UPDATE_FLAG) != (UINT32)0) || ((dUpdateInfo & MCDRV_ADCAGC_UPDATE_FLAG) != (UINT32)0))
++      {
++              bReg    = (sAdcInfo.bAgcOn<<2)|sAdcInfo.bAgcAdjust;
++              if(bReg == McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_CODEC, MCI_AD_AGC))
++              {
++                      dUpdateInfo     &= ~(MCDRV_ADCADJ_UPDATE_FLAG|MCDRV_ADCAGC_UPDATE_FLAG);
++              }
++      }
++      if((dUpdateInfo & MCDRV_ADCMONO_UPDATE_FLAG) != (UINT32)0)
++      {
++              bReg    = (UINT8)((McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_CODEC, MCI_AD_START) & MCB_AD_START) | (sAdcInfo.bMono << 1));
++              if(bReg == McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_CODEC, MCI_AD_START))
++              {
++                      dUpdateInfo     &= ~(MCDRV_ADCMONO_UPDATE_FLAG);
++              }
++      }
++
++      if(dUpdateInfo != (UINT32)0)
++      {
++              McResCtrl_GetCurPowerInfo(&sPowerInfo);
++              sdRet   = PowerUpDig(MCDRV_DPB_UP);
++              if(sdRet == MCDRV_SUCCESS)
++              {
++                      if(((dUpdateInfo & MCDRV_ADCADJ_UPDATE_FLAG) != (UINT32)0) || ((dUpdateInfo & MCDRV_ADCAGC_UPDATE_FLAG) != (UINT32)0))
++                      {
++                              bReg    = (sAdcInfo.bAgcOn<<2)|sAdcInfo.bAgcAdjust;
++                              if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_CODEC, MCI_AD_AGC))
++                              {
++                                      AddStopADC();
++                                      sdRet   = McDevIf_ExecutePacket();
++                              }
++                              if(MCDRV_SUCCESS == sdRet)
++                              {
++                                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_AD_AGC, bReg);
++                              }
++                      }
++                      if(sdRet == MCDRV_SUCCESS)
++                      {
++                              if((dUpdateInfo & MCDRV_ADCMONO_UPDATE_FLAG) != (UINT32)0)
++                              {
++                                      bReg    = (UINT8)((McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_CODEC, MCI_AD_START) & MCB_AD_START) | (sAdcInfo.bMono << 1));
++                                      if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_CODEC, MCI_AD_START))
++                                      {
++                                              AddStopADC();
++                                              sdRet   = McDevIf_ExecutePacket();
++                                      }
++                                      if(sdRet == MCDRV_SUCCESS)
++                                      {
++                                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_AD_START, (sAdcInfo.bMono << 1));
++                                      }
++                              }
++                              if(sdRet == MCDRV_SUCCESS)
++                              {
++                                      /*      unused path power down  */
++                                      sPowerUpdate.dDigital           = MCDRV_POWUPDATE_DIGITAL_ALL;
++                                      sPowerUpdate.abAnalog[0]        = 
++                                      sPowerUpdate.abAnalog[1]        = 
++                                      sPowerUpdate.abAnalog[2]        = 
++                                      sPowerUpdate.abAnalog[3]        = 
++                                      sPowerUpdate.abAnalog[4]        = 0;
++                                      sdRet   = McPacket_AddPowerDown(&sPowerInfo, &sPowerUpdate);
++                                      if(sdRet == MCDRV_SUCCESS)
++                                      {
++                                              sdRet   = McPacket_AddStart();
++                                      }
++                              }
++                      }
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McPacket_AddADC", &sdRet);
++#endif
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    McPacket_AddSP
++ *
++ *    Description:
++ *                    Add SP setup packet.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddSP
++(
++      void
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      MCDRV_SP_INFO   sSpInfo;
++      UINT8   bReg;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McPacket_AddSP");
++#endif
++
++      bReg    = (UINT8)(McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_SP_MODE) & (UINT8)~MCB_SP_SWAP);
++
++      McResCtrl_GetSpInfo(&sSpInfo);
++
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)MCI_SP_MODE, bReg|sSpInfo.bSwap);
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McPacket_AddSP", &sdRet);
++#endif
++      return sdRet;
++}
++
++/****************************************************************************
++ *    McPacket_AddDNG
++ *
++ *    Description:
++ *                    Add Digital Noise Gate setup packet.
++ *    Arguments:
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddDNG
++(
++      UINT32  dUpdateInfo
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      MCDRV_DNG_INFO  sDngInfo;
++      UINT8   bReg;
++      UINT8   bRegDNGON;
++      UINT8   bItem;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McPacket_AddDNG");
++#endif
++
++      McResCtrl_GetDngInfo(&sDngInfo);
++
++      for(bItem = MCDRV_DNG_ITEM_HP; bItem <= MCDRV_DNG_ITEM_RC; bItem++)
++      {
++              bRegDNGON       = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_DNGON_HP+(bItem*3));
++
++              /*      ReleseTime, Attack Time */
++              if(((dUpdateInfo & (MCDRV_DNGREL_HP_UPDATE_FLAG<<(8*bItem))) != 0UL) || ((dUpdateInfo & (MCDRV_DNGATK_HP_UPDATE_FLAG<<(8*bItem))) != 0UL))
++              {
++                      bReg    = (sDngInfo.abRelease[bItem]<<4)|sDngInfo.abAttack[bItem];
++                      if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_DNGATRT_HP+(bItem*3)))
++                      {
++                              if((bRegDNGON&0x01) != 0)
++                              {/*     DNG on  */
++                                      /*      DNG off */
++                                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)(MCI_DNGON_HP+(bItem*3)), bRegDNGON&0xFE);
++                              }
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)(MCI_DNGATRT_HP+(bItem*3)), bReg);
++                      }
++              }
++
++              /*      Target  */
++              if((dUpdateInfo & (MCDRV_DNGTARGET_HP_UPDATE_FLAG<<(8*bItem))) != 0UL)
++              {
++                      bReg    = sDngInfo.abTarget[bItem]<<4;
++                      if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_DNGTARGET_HP+(bItem*3)))
++                      {
++                              if((bRegDNGON&0x01) != 0)
++                              {/*     DNG on  */
++                                      /*      DNG off */
++                                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)(MCI_DNGON_HP+(bItem*3)), bRegDNGON&0xFE);
++                              }
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)(MCI_DNGTARGET_HP+(bItem*3)), bReg);
++                      }
++              }
++
++              /*      Threshold, HoldTime     */
++              if(((dUpdateInfo & (MCDRV_DNGTHRES_HP_UPDATE_FLAG<<(8*bItem))) != 0UL)
++              || ((dUpdateInfo & (MCDRV_DNGHOLD_HP_UPDATE_FLAG<<(8*bItem))) != 0UL))
++              {
++                      bReg    = (sDngInfo.abThreshold[bItem]<<4)|(sDngInfo.abHold[bItem]<<1);
++                      if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_DNGON_HP+(bItem*3)))
++                      {
++                              if((bRegDNGON&0x01) != 0)
++                              {/*     DNG on  */
++                                      /*      DNG off */
++                                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)(MCI_DNGON_HP+(bItem*3)), bRegDNGON&0xFE);
++                              }
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)(MCI_DNGON_HP+(bItem*3)), bReg);
++                      }
++                      bRegDNGON       = bReg | (bRegDNGON&0x01);
++              }
++
++              /*      DNGON   */
++              if((dUpdateInfo & (MCDRV_DNGSW_HP_UPDATE_FLAG<<(8*bItem))) != 0UL)
++              {
++                      bRegDNGON       = (bRegDNGON&0xFE) | sDngInfo.abOnOff[bItem];
++              }
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_ANA | (UINT32)(MCI_DNGON_HP+(bItem*3)), bRegDNGON);
++      }
++
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McPacket_AddDNG", &sdRet);
++#endif
++      return sdRet;
++}
++
++/****************************************************************************
++ *    McPacket_AddAE
++ *
++ *    Description:
++ *                    Add Audio Engine setup packet.
++ *    Arguments:
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddAE
++(
++      UINT32  dUpdateInfo
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bReg;
++      UINT8   i;
++      UINT32  dXFadeParam     = 0;
++      MCDRV_AE_INFO   sAeInfo;
++      MCDRV_PATH_INFO sPathInfo;
++      MCDRV_POWER_INFO        sPowerInfo;
++      MCDRV_POWER_UPDATE      sPowerUpdate;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McPacket_AddAE");
++#endif
++
++      McResCtrl_GetPathInfo(&sPathInfo);
++      McResCtrl_GetAeInfo(&sAeInfo);
++
++      if(McResCtrl_IsDstUsed(eMCDRV_DST_AE, eMCDRV_DST_CH0) == 1)
++      {/*     AE is used      */
++              bReg    = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_A, MCI_BDSP_ST);
++              if(McDevProf_IsValid(eMCDRV_FUNC_DBEX) == 1)
++              {
++                      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_BEXWIDE_ONOFF) != (UINT32)0)
++                      {
++                              if((((sAeInfo.bOnOff & MCDRV_BEXWIDE_ON) != 0) && ((bReg & MCB_DBEXON) != 0))
++                              || (((sAeInfo.bOnOff & MCDRV_BEXWIDE_ON) == 0) && ((bReg & MCB_DBEXON) == 0)))
++                              {
++                                      dUpdateInfo     &= ~MCDRV_AEUPDATE_FLAG_BEXWIDE_ONOFF;
++                              }
++                      }
++              }
++              if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_DRC_ONOFF) != (UINT32)0)
++              {
++                      if((((sAeInfo.bOnOff & MCDRV_DRC_ON) != 0) && ((bReg & MCB_DRCON) != 0))
++                      || (((sAeInfo.bOnOff & MCDRV_DRC_ON) == 0) && ((bReg & MCB_DRCON) == 0)))
++                      {
++                              dUpdateInfo     &= ~MCDRV_AEUPDATE_FLAG_DRC_ONOFF;
++                      }
++              }
++              if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ5_ONOFF) != (UINT32)0)
++              {
++                      if((((sAeInfo.bOnOff & MCDRV_EQ5_ON) != 0) && ((bReg & MCB_EQ5ON) != 0))
++                      || (((sAeInfo.bOnOff & MCDRV_EQ5_ON) == 0) && ((bReg & MCB_EQ5ON) == 0)))
++                      {
++                              dUpdateInfo     &= ~MCDRV_AEUPDATE_FLAG_EQ5_ONOFF;
++                      }
++              }
++              if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ3_ONOFF) != (UINT32)0)
++              {
++                      if((((sAeInfo.bOnOff & MCDRV_EQ3_ON) != 0) && ((bReg & MCB_EQ3ON) != 0))
++                      || (((sAeInfo.bOnOff & MCDRV_EQ3_ON) == 0) && ((bReg & MCB_EQ3ON) == 0)))
++                      {
++                              dUpdateInfo     &= ~MCDRV_AEUPDATE_FLAG_EQ3_ONOFF;
++                      }
++              }
++              if(dUpdateInfo != (UINT32)0)
++              {
++                      /*      on/off setting or param changed */
++                      if(((dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ5) != (UINT32)0)
++                      || ((dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ3) != (UINT32)0)
++                      || ((dUpdateInfo & MCDRV_AEUPDATE_FLAG_BEX) != (UINT32)0)
++                      || ((dUpdateInfo & MCDRV_AEUPDATE_FLAG_WIDE) != (UINT32)0)
++                      || ((dUpdateInfo & MCDRV_AEUPDATE_FLAG_DRC) != (UINT32)0)
++                      || ((dUpdateInfo & MCDRV_AEUPDATE_FLAG_BEXWIDE_ONOFF) != (UINT32)0)
++                      || ((dUpdateInfo & MCDRV_AEUPDATE_FLAG_DRC_ONOFF) != (UINT32)0)
++                      || ((dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ5_ONOFF) != (UINT32)0)
++                      || ((dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ3_ONOFF) != (UINT32)0))
++                      {
++                              dXFadeParam     = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_DAC_INS);
++                              dXFadeParam     <<= 8;
++                              dXFadeParam     |= McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_INS);
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_DAC_INS, 0);
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_INS, 0);
++                      }
++                      sdRet   = McDevIf_ExecutePacket();
++                      if(sdRet == MCDRV_SUCCESS)
++                      {
++                              /*      wait xfade complete     */
++                              if(dXFadeParam != (UINT32)0)
++                              {
++                                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_EVTWAIT | MCDRV_EVT_INSFLG | dXFadeParam, 0);
++                                      bReg    = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_A, MCI_BDSP_ST);
++                                      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ5) != (UINT32)0)
++                                      {
++                                              bReg    &= (UINT8)~MCB_EQ5ON;
++                                      }
++                                      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ3) != (UINT32)0)
++                                      {
++                                              bReg    &= (UINT8)~MCB_EQ3ON;
++                                      }
++                                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_A | (UINT32)MCI_BDSP_ST, bReg);
++                              }
++
++                              bReg    = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_A, MCI_BDSP_ST);
++                              if((bReg & MCB_BDSP_ST) == MCB_BDSP_ST)
++                              {
++                                      /*      Stop BDSP       */
++                                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_A | (UINT32)MCI_BDSP_ST, 0);
++                                      /*      Reset TRAM      */
++                                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_A | (UINT32)MCI_BDSP_RST, MCB_TRAM_RST);
++                                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_A | (UINT32)MCI_BDSP_RST, 0);
++                              }
++                      }
++              }
++      }
++
++      if((dUpdateInfo != (UINT32)0) && (sdRet == MCDRV_SUCCESS))
++      {
++              if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_DRC) != (UINT32)0)
++              {
++                      McResCtrl_GetPowerInfo(&sPowerInfo);
++                      sPowerInfo.dDigital     &= ~MCDRV_POWINFO_DIGITAL_DP0;
++                      sPowerInfo.dDigital     &= ~MCDRV_POWINFO_DIGITAL_DP1;
++                      sPowerInfo.dDigital     &= ~MCDRV_POWINFO_DIGITAL_DP2;
++                      sPowerInfo.dDigital     &= ~MCDRV_POWINFO_DIGITAL_DPBDSP;
++                      sPowerInfo.dDigital     &= ~MCDRV_POWINFO_DIGITAL_PLLRST0;
++                      sPowerUpdate.dDigital   = MCDRV_POWUPDATE_DIGITAL_ALL;
++                      sPowerUpdate.abAnalog[0]        = 
++                      sPowerUpdate.abAnalog[1]        = 
++                      sPowerUpdate.abAnalog[2]        = 
++                      sPowerUpdate.abAnalog[3]        = 
++                      sPowerUpdate.abAnalog[4]        = 0;
++                      sdRet   = McPacket_AddPowerUp(&sPowerInfo, &sPowerUpdate);
++                      if(MCDRV_SUCCESS == sdRet)
++                      {
++                              sdRet   = McDevIf_ExecutePacket();
++                      }
++                      if(MCDRV_SUCCESS == sdRet)
++                      {
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_FORCE_WRITE | MCDRV_PACKET_REGTYPE_A | (UINT32)MCI_BDSP_ADR, 0);
++                              sdRet   = McDevIf_ExecutePacket();
++                              if(MCDRV_SUCCESS == sdRet)
++                              {
++                                      McDevIf_AddPacketRepeat(MCDRV_PACKET_TYPE_FORCE_WRITE | MCDRV_PACKET_REGTYPE_A | (UINT32)MCI_BDSP_WINDOW, sAeInfo.abDrc, DRC_PARAM_SIZE);
++                              }
++                      }
++              }
++
++              if(MCDRV_SUCCESS == sdRet)
++              {
++                      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ5) != (UINT32)0)
++                      {
++                              for(i = 0; i < EQ5_PARAM_SIZE; i++)
++                              {
++                                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_FORCE_WRITE | MCDRV_PACKET_REGTYPE_B_AE | (UINT32)(MCI_BAND0_CEQ0+i), sAeInfo.abEq5[i]);
++                              }
++                      }
++                      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ3) != (UINT32)0)
++                      {
++                              for(i = 0; i < EQ3_PARAM_SIZE; i++)
++                              {
++                                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_FORCE_WRITE | MCDRV_PACKET_REGTYPE_B_AE | (UINT32)(MCI_BAND5_CEQ0+i), sAeInfo.abEq3[i]);
++                              }
++                      }
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McPacket_AddAE", &sdRet);
++#endif
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    McPacket_AddPDM
++ *
++ *    Description:
++ *                    Add PDM setup packet.
++ *    Arguments:
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddPDM
++(
++      UINT32                  dUpdateInfo
++)
++{
++      SINT32                          sdRet           = MCDRV_SUCCESS;
++      UINT8                           bReg;
++      MCDRV_POWER_INFO        sPowerInfo;
++      MCDRV_POWER_UPDATE      sPowerUpdate;
++      MCDRV_PDM_INFO          sPdmInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McPacket_AddPDM");
++#endif
++
++      McResCtrl_GetPdmInfo(&sPdmInfo);
++      if(((dUpdateInfo & MCDRV_PDMADJ_UPDATE_FLAG) != (UINT32)0) || ((dUpdateInfo & MCDRV_PDMAGC_UPDATE_FLAG) != (UINT32)0))
++      {
++              bReg    = (sPdmInfo.bAgcOn<<2)|sPdmInfo.bAgcAdjust;
++              if(bReg == McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_PDM_AGC))
++              {
++                      dUpdateInfo &= ~(MCDRV_PDMADJ_UPDATE_FLAG|MCDRV_PDMAGC_UPDATE_FLAG);
++              }
++      }
++      if((dUpdateInfo & MCDRV_PDMMONO_UPDATE_FLAG) != (UINT32)0)
++      {
++              bReg    = (UINT8)(McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_PDM_START) & (UINT8)MCB_PDM_MN);
++              if((sPdmInfo.bMono<<1) == bReg)
++              {
++                      dUpdateInfo &= ~(MCDRV_PDMMONO_UPDATE_FLAG);
++              }
++      }
++      if(((dUpdateInfo & MCDRV_PDMCLK_UPDATE_FLAG) != (UINT32)0)
++      || ((dUpdateInfo & MCDRV_PDMEDGE_UPDATE_FLAG) != (UINT32)0)
++      || ((dUpdateInfo & MCDRV_PDMWAIT_UPDATE_FLAG) != (UINT32)0)
++      || ((dUpdateInfo & MCDRV_PDMSEL_UPDATE_FLAG) != (UINT32)0))
++      {
++              bReg    = (sPdmInfo.bPdmWait<<5) | (sPdmInfo.bPdmEdge<<4) | (sPdmInfo.bPdmSel<<2) | sPdmInfo.bClk;
++              if(bReg == McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_PDM_STWAIT))
++              {
++                      dUpdateInfo &= ~(MCDRV_PDMCLK_UPDATE_FLAG|MCDRV_PDMEDGE_UPDATE_FLAG|MCDRV_PDMWAIT_UPDATE_FLAG|MCDRV_PDMSEL_UPDATE_FLAG);
++              }
++      }
++      if(dUpdateInfo != (UINT32)0)
++      {
++              McResCtrl_GetCurPowerInfo(&sPowerInfo);
++              sdRet   = PowerUpDig(MCDRV_DPB_UP);
++              if(sdRet == MCDRV_SUCCESS)
++              {
++                      if(((dUpdateInfo & MCDRV_PDMADJ_UPDATE_FLAG) != (UINT32)0) || ((dUpdateInfo & MCDRV_PDMAGC_UPDATE_FLAG) != (UINT32)0))
++                      {
++                              bReg    = (sPdmInfo.bAgcOn<<2)|sPdmInfo.bAgcAdjust;
++                              if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_PDM_AGC))
++                              {
++                                      AddStopPDM();
++                                      sdRet   = McDevIf_ExecutePacket();
++                              }
++                              if(sdRet == MCDRV_SUCCESS)
++                              {
++                                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_PDM_AGC, bReg);
++                              }
++                      }
++              }
++              if(sdRet == MCDRV_SUCCESS)
++              {
++                      if((dUpdateInfo & MCDRV_PDMMONO_UPDATE_FLAG) != (UINT32)0)
++                      {
++                              bReg    = (UINT8)((McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_PDM_START) & (UINT8)~MCB_PDM_MN) | (sPdmInfo.bMono<<1));
++                              if(bReg != McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_MIXER, MCI_PDM_START))
++                              {
++                                      AddStopPDM();
++                                      sdRet   = McDevIf_ExecutePacket();
++                                      if(MCDRV_SUCCESS == sdRet)
++                                      {
++                                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_PDM_START, (sPdmInfo.bMono<<1));
++                                      }
++                              }
++                      }
++              }
++              if(sdRet == MCDRV_SUCCESS)
++              {
++                      if(((dUpdateInfo & MCDRV_PDMCLK_UPDATE_FLAG) != (UINT32)0)
++                      || ((dUpdateInfo & MCDRV_PDMEDGE_UPDATE_FLAG) != (UINT32)0)
++                      || ((dUpdateInfo & MCDRV_PDMWAIT_UPDATE_FLAG) != (UINT32)0)
++                      || ((dUpdateInfo & MCDRV_PDMSEL_UPDATE_FLAG) != (UINT32)0))
++                      {
++                              bReg    = (sPdmInfo.bPdmWait<<5) | (sPdmInfo.bPdmEdge<<4) | (sPdmInfo.bPdmSel<<2) | sPdmInfo.bClk;
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_MIXER | (UINT32)MCI_PDM_STWAIT, bReg);
++                      }
++
++                      /*      unused path power down  */
++                      sPowerUpdate.dDigital           = MCDRV_POWUPDATE_DIGITAL_ALL;
++                      sPowerUpdate.abAnalog[0]        = 
++                      sPowerUpdate.abAnalog[1]        = 
++                      sPowerUpdate.abAnalog[2]        = 
++                      sPowerUpdate.abAnalog[3]        = 
++                      sPowerUpdate.abAnalog[4]        = 0;
++                      sdRet   = McPacket_AddPowerDown(&sPowerInfo, &sPowerUpdate);
++                      if(sdRet == MCDRV_SUCCESS)
++                      {
++                              sdRet   = McPacket_AddStart();
++                      }
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McPacket_AddPDM", &sdRet);
++#endif
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    McPacket_AddGPMode
++ *
++ *    Description:
++ *                    Add GP mode setup packet.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddGPMode
++(
++      void
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bReg;
++      MCDRV_INIT_INFO sInitInfo;
++      MCDRV_GP_MODE   sGPMode;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McPacket_AddGPMode");
++#endif
++
++      McResCtrl_GetInitInfo(&sInitInfo);
++      McResCtrl_GetGPMode(&sGPMode);
++
++      bReg    = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_BASE, MCI_PA_MSK);
++
++      if(sInitInfo.bPad0Func == MCDRV_PAD_GPIO)
++      {
++              if(sGPMode.abGpDdr[0] == MCDRV_GPDDR_IN)
++              {
++                      bReg    &= (UINT8)~MCB_PA0_DDR;
++              }
++              else
++              {
++                      bReg    |= MCB_PA0_DDR;
++              }
++      }
++      if(sInitInfo.bPad1Func == MCDRV_PAD_GPIO)
++      {
++              if(sGPMode.abGpDdr[1] == MCDRV_GPDDR_IN)
++              {
++                      bReg    &= (UINT8)~MCB_PA1_DDR;
++              }
++              else
++              {
++                      bReg    |= MCB_PA1_DDR;
++              }
++      }
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_PA_MSK, bReg);
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McPacket_AddGPMode", &sdRet);
++#endif
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    McPacket_AddGPMask
++ *
++ *    Description:
++ *                    Add GP mask setup packet.
++ *    Arguments:
++ *                    dPadNo          PAD number
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddGPMask
++(
++      UINT32  dPadNo
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bReg;
++      MCDRV_INIT_INFO sInitInfo;
++      MCDRV_GP_MODE   sGPMode;
++      UINT8   abMask[GPIO_PAD_NUM];
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McPacket_AddGPMask");
++#endif
++
++      McResCtrl_GetInitInfo(&sInitInfo);
++      McResCtrl_GetGPMode(&sGPMode);
++      McResCtrl_GetGPMask(abMask);
++
++      if(dPadNo == MCDRV_GP_PAD0)
++      {
++              if((sInitInfo.bPad0Func == MCDRV_PAD_GPIO) && (sGPMode.abGpDdr[0] == MCDRV_GPDDR_IN))
++              {
++                      bReg    = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_BASE, MCI_PA_MSK);
++                      if(abMask[0] == MCDRV_GPMASK_OFF)
++                      {
++                              bReg    &= (UINT8)~MCB_PA0_MSK;
++                      }
++                      else
++                      {
++                              bReg    |= MCB_PA0_MSK;
++                      }
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_PA_MSK, bReg);
++              }
++      }
++      else if(dPadNo == MCDRV_GP_PAD1)
++      {
++              if((sInitInfo.bPad1Func == MCDRV_PAD_GPIO) && (sGPMode.abGpDdr[1] == MCDRV_GPDDR_IN))
++              {
++                      bReg    = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_BASE, MCI_PA_MSK);
++                      if(abMask[1] == MCDRV_GPMASK_OFF)
++                      {
++                              bReg    &= (UINT8)~MCB_PA1_MSK;
++                      }
++                      else
++                      {
++                              bReg    |= MCB_PA1_MSK;
++                      }
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_PA_MSK, bReg);
++              }
++      }
++      else
++      {
++              sdRet   = MCDRV_ERROR;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McPacket_AddGPMask", &sdRet);
++#endif
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    McPacket_AddGPSet
++ *
++ *    Description:
++ *                    Add GPIO output packet.
++ *    Arguments:
++ *                    bGpio           pin state setting
++ *                    dPadNo          PAD number
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddGPSet
++(
++      UINT8   bGpio,
++      UINT32  dPadNo
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bReg;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McPacket_AddGPSet");
++#endif
++
++      bReg    = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_BASE, MCI_PA_SCU_PA);
++
++      if(dPadNo == MCDRV_GP_PAD0)
++      {
++              if(bGpio == MCDRV_GP_LOW)
++              {
++                      bReg    &= (UINT8)~MCB_PA_SCU_PA0;
++              }
++              else if(bGpio == MCDRV_GP_HIGH)
++              {
++                      bReg    |= MCB_PA_SCU_PA0;
++              }
++              else
++              {
++              }
++      }
++      else if(dPadNo == MCDRV_GP_PAD1)
++      {
++              if(bGpio == MCDRV_GP_LOW)
++              {
++                      bReg    &= (UINT8)~MCB_PA_SCU_PA1;
++              }
++              else if(bGpio == MCDRV_GP_HIGH)
++              {
++                      bReg    |= MCB_PA_SCU_PA1;
++              }
++              else
++              {
++              }
++      }
++      else
++      {
++              sdRet   = MCDRV_ERROR;
++      }
++
++      if(sdRet == MCDRV_SUCCESS)
++      {
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_BASE | (UINT32)MCI_PA_SCU_PA, bReg);
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McPacket_AddGPSet", &sdRet);
++#endif
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    McPacket_AddSysEq
++ *
++ *    Description:
++ *                    Add GPIO output packet.
++ *    Arguments:
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddSysEq
++(
++      UINT32  dUpdateInfo
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bRegEQOn;
++      UINT8   bReg;
++      MCDRV_SYSEQ_INFO        sSysEq;
++      UINT8   i;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McPacket_AddSysEq");
++#endif
++
++      bRegEQOn        = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_CODEC, MCI_SYSTEM_EQON);
++
++      McResCtrl_GetSysEq(&sSysEq);
++
++      if((dUpdateInfo & MCDRV_SYSEQ_PARAM_UPDATE_FLAG) != 0UL)
++      {
++              if((bRegEQOn & MCB_SYSTEM_EQON) != 0)
++              {/*     EQ on   */
++                      /*      EQ off  */
++                      bReg    = bRegEQOn;
++                      bReg    &= (UINT8)~MCB_SYSTEM_EQON;
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_SYSTEM_EQON, bReg);
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_EVTWAIT | MCDRV_EVT_SYSEQ_FLAG_RESET, 0);
++              }
++              /*      EQ coef */
++              for(i = 0; i < sizeof(sSysEq.abParam); i++)
++              {
++                      McDevIf_AddPacket(MCDRV_PACKET_TYPE_FORCE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)(MCI_SYS_CEQ0_19_12+i), sSysEq.abParam[i]);
++              }
++      }
++
++      if((dUpdateInfo & MCDRV_SYSEQ_ONOFF_UPDATE_FLAG) != 0UL)
++      {
++              bRegEQOn        &= (UINT8)~MCB_SYSTEM_EQON;
++              bRegEQOn        |= sSysEq.bOnOff;
++      }
++
++      McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_SYSTEM_EQON, bRegEQOn);
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McPacket_AddSysEq", &sdRet);
++#endif
++      return sdRet;
++}
++
++/****************************************************************************
++ *    McPacket_AddClockSwitch
++ *
++ *    Description:
++ *                    Add switch clock packet.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *
++ ****************************************************************************/
++SINT32        McPacket_AddClockSwitch
++(
++      void
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT8   bReg;
++      MCDRV_CLKSW_INFO        sClockInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McPacket_AddClockSwitch");
++#endif
++
++      bReg    = McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_CODEC, MCI_DPADIF);
++
++      McResCtrl_GetClockSwitch(&sClockInfo);
++
++      if((bReg & (MCB_DP0_CLKI1 | MCB_DP0_CLKI0)) != (MCB_DP0_CLKI1 | MCB_DP0_CLKI0))
++      {
++              if(sClockInfo.bClkSrc == MCDRV_CLKSW_CLKI0)
++              {
++                      if((bReg & MCB_DP0_CLKI1) == 0)
++                      {/*     CLKI1->CLKI0    */
++                              bReg    &= (UINT8)~MCB_DP0_CLKI0;
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DPADIF, bReg);
++                              if((bReg & MCB_CLKINPUT) != 0)
++                              {
++                                      bReg    |= MCB_CLKSRC;
++                              }
++                              else
++                              {
++                                      bReg    &= (UINT8)~MCB_CLKSRC;
++                              }
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DPADIF, bReg);
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_EVTWAIT | MCDRV_EVT_CLKBUSY_RESET, 0);
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_EVTWAIT | MCDRV_EVT_CLKSRC_RESET, 0);
++                              bReg    |= MCB_DP0_CLKI1;
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DPADIF, bReg);
++                      }
++              }
++              else
++              {
++                      if((bReg & MCB_DP0_CLKI0) == 0)
++                      {/*     CLKI0->CLKI1    */
++                              bReg    &= (UINT8)~MCB_DP0_CLKI1;
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DPADIF, bReg);
++                              if((bReg & MCB_CLKINPUT) == 0)
++                              {
++                                      bReg    |= MCB_CLKSRC;
++                              }
++                              else
++                              {
++                                      bReg    &= (UINT8)~MCB_CLKSRC;
++                              }
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DPADIF, bReg);
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_EVTWAIT | MCDRV_EVT_CLKBUSY_RESET, 0);
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_EVTWAIT | MCDRV_EVT_CLKSRC_SET, 0);
++                              bReg    |= MCB_DP0_CLKI0;
++                              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DPADIF, bReg);
++                      }
++              }
++      }
++      else
++      {
++              if(sClockInfo.bClkSrc == MCDRV_CLKSW_CLKI0)
++              {
++                      if((bReg & MCB_CLKSRC) != 0)
++                      {
++                              bReg    |= MCB_CLKINPUT;
++                      }
++                      else
++                      {
++                              bReg    &= (UINT8)~MCB_CLKINPUT;
++                      }
++              }
++              else
++              {
++                      if((bReg & MCB_CLKSRC) == 0)
++                      {
++                              bReg    |= MCB_CLKINPUT;
++                      }
++                      else
++                      {
++                              bReg    &= (UINT8)~MCB_CLKINPUT;
++                      }
++              }
++              McDevIf_AddPacket(MCDRV_PACKET_TYPE_WRITE | MCDRV_PACKET_REGTYPE_B_CODEC | (UINT32)MCI_DPADIF, bReg);
++              sdRet   = McDevIf_ExecutePacket();
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McPacket_AddClockSwitch", &sdRet);
++#endif
++
++      return sdRet;
++}
++
++
++/****************************************************************************
++ *    PowerUpDig
++ *
++ *    Description:
++ *                    Digital power up.
++ *    Arguments:
++ *                    bDPBUp          1:DPB power up
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_RESOURCEOVER
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++static SINT32 PowerUpDig
++(
++      UINT8   bDPBUp
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      MCDRV_POWER_INFO        sPowerInfo;
++      MCDRV_POWER_UPDATE      sPowerUpdate;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("PowerUpDig");
++#endif
++
++      McResCtrl_GetCurPowerInfo(&sPowerInfo);
++      sPowerInfo.dDigital     &= ~MCDRV_POWINFO_DIGITAL_DP0;
++      sPowerInfo.dDigital     &= ~MCDRV_POWINFO_DIGITAL_DP1;
++      sPowerInfo.dDigital     &= ~MCDRV_POWINFO_DIGITAL_DP2;
++      sPowerInfo.dDigital     &= ~MCDRV_POWINFO_DIGITAL_PLLRST0;
++      if(bDPBUp == MCDRV_DPB_UP)
++      {
++              sPowerInfo.dDigital     &= ~MCDRV_POWINFO_DIGITAL_DPB;
++      }
++      sPowerUpdate.dDigital   = MCDRV_POWUPDATE_DIGITAL_ALL;
++      sdRet   = McPacket_AddPowerUp(&sPowerInfo, &sPowerUpdate);
++      if(MCDRV_SUCCESS == sdRet)
++      {
++              sdRet   = McDevIf_ExecutePacket();
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("PowerUpDig", &sdRet);
++#endif
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    GetMaxWait
++ *
++ *    Description:
++ *                    Get maximum wait time.
++ *    Arguments:
++ *                    bRegChange      analog power management register update information
++ *    Return:
++ *                    wait time
++ *
++ ****************************************************************************/
++static UINT32 GetMaxWait
++(
++      UINT8   bRegChange
++)
++{
++      UINT32  dWaitTimeMax    = 0;
++      MCDRV_INIT_INFO sInitInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("GetMaxWait");
++#endif
++
++      McResCtrl_GetInitInfo(&sInitInfo);
++
++      if((bRegChange & MCB_PWM_LI) != 0)
++      {
++              if(sInitInfo.sWaitTime.dLine1Cin > dWaitTimeMax)
++              {
++                      dWaitTimeMax    = sInitInfo.sWaitTime.dLine1Cin;
++              }
++      }
++      if(((bRegChange & MCB_PWM_MB1) != 0) || ((bRegChange & MCB_PWM_MC1) != 0))
++      {
++              if(sInitInfo.sWaitTime.dMic1Cin > dWaitTimeMax)
++              {
++                      dWaitTimeMax    = sInitInfo.sWaitTime.dMic1Cin;
++              }
++      }
++      if(((bRegChange & MCB_PWM_MB2) != 0) || ((bRegChange & MCB_PWM_MC2) != 0))
++      {
++              if(sInitInfo.sWaitTime.dMic2Cin > dWaitTimeMax)
++              {
++                      dWaitTimeMax    = sInitInfo.sWaitTime.dMic2Cin;
++              }
++      }
++      if(((bRegChange & MCB_PWM_MB3) != 0) || ((bRegChange & MCB_PWM_MC3) != 0))
++      {
++              if(sInitInfo.sWaitTime.dMic3Cin > dWaitTimeMax)
++              {
++                      dWaitTimeMax    = sInitInfo.sWaitTime.dMic3Cin;
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = (SINT32)dWaitTimeMax;
++      McDebugLog_FuncOut("GetMaxWait", &sdRet);
++#endif
++
++      return dWaitTimeMax;
++}
++
+diff --git a/sound/soc/codecs/mc1n2/mcpacking.h b/sound/soc/codecs/mc1n2/mcpacking.h
+new file mode 100644
+index 0000000..04202fc
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mcpacking.h
+@@ -0,0 +1,91 @@
++/****************************************************************************
++ *
++ *            Copyright(c) 2010 Yamaha Corporation. All rights reserved.
++ *
++ *            Module          : mcpacking.h
++ *
++ *            Description     : MC Driver Packet packing header
++ *
++ *            Version         : 1.0.0         2010.08.24
++ *
++ ****************************************************************************/
++
++#ifndef _MCPACKING_H_
++#define _MCPACKING_H_
++
++#include "mctypedef.h"
++#include "mcdriver.h"
++
++/* volume update */
++typedef enum
++{
++      eMCDRV_VOLUPDATE_MUTE,
++      eMCDRV_VOLUPDATE_ALL
++} MCDRV_VOLUPDATE_MODE;
++
++/*    power setting   */
++#define       MCDRV_POWINFO_DIGITAL_DP0                       ((UINT32)0x0001)
++#define       MCDRV_POWINFO_DIGITAL_DP1                       ((UINT32)0x0002)
++#define       MCDRV_POWINFO_DIGITAL_DP2                       ((UINT32)0x0004)
++#define       MCDRV_POWINFO_DIGITAL_DPB                       ((UINT32)0x0008)
++#define       MCDRV_POWINFO_DIGITAL_DPDI0                     ((UINT32)0x0010)
++#define       MCDRV_POWINFO_DIGITAL_DPDI1                     ((UINT32)0x0020)
++#define       MCDRV_POWINFO_DIGITAL_DPDI2                     ((UINT32)0x0040)
++#define       MCDRV_POWINFO_DIGITAL_DPPDM                     ((UINT32)0x0080)
++#define       MCDRV_POWINFO_DIGITAL_DPBDSP            ((UINT32)0x0100)
++#define       MCDRV_POWINFO_DIGITAL_DPADIF            ((UINT32)0x0200)
++#define       MCDRV_POWINFO_DIGITAL_PLLRST0           ((UINT32)0x0400)
++typedef struct
++{
++      UINT32  dDigital;
++      UINT8   abAnalog[5];
++} MCDRV_POWER_INFO;
++
++/* power update */
++typedef struct
++{
++      UINT32  dDigital;
++      UINT8   abAnalog[5];
++} MCDRV_POWER_UPDATE;
++
++#define       MCDRV_POWUPDATE_DIGITAL_ALL                     (0xFFFFFFFFUL)
++#define       MCDRV_POWUPDATE_ANALOG0_ALL                     (0x0F)
++#define       MCDRV_POWUPDATE_ANALOG1_ALL                     (0xFF)
++#define       MCDRV_POWUPDATE_ANALOG2_ALL                     (0x3F)
++#define       MCDRV_POWUPDATE_ANALOG3_ALL                     (0x1F)
++#define       MCDRV_POWUPDATE_ANALOG4_ALL                     (0xF0)
++#define       MCDRV_POWUPDATE_ANALOG0_IN                      (0x0D)
++#define       MCDRV_POWUPDATE_ANALOG1_IN                      (0xC0)
++#define       MCDRV_POWUPDATE_ANALOG2_IN                      (0x00)
++#define       MCDRV_POWUPDATE_ANALOG3_IN                      (0x1F)
++#define       MCDRV_POWUPDATE_ANALOG4_IN                      (0xF0)
++#define       MCDRV_POWUPDATE_ANALOG0_OUT                     (0x02)
++#define       MCDRV_POWUPDATE_ANALOG1_OUT                     (0x3F)
++#define       MCDRV_POWUPDATE_ANALOG2_OUT                     (0x3F)
++#define       MCDRV_POWUPDATE_ANALOG3_OUT                     (0x00)
++#define       MCDRV_POWUPDATE_ANALOG4_OUT                     (0x00)
++
++
++SINT32                McPacket_AddInit                        (const MCDRV_INIT_INFO* psInitInfo);
++SINT32                McPacket_AddVol                         (UINT32 dUpdate, MCDRV_VOLUPDATE_MODE eMode, UINT32* pdSVolDoneParam);
++SINT32                McPacket_AddPowerUp                     (const MCDRV_POWER_INFO* psPowerInfo, const MCDRV_POWER_UPDATE* psPowerUpdate);
++SINT32                McPacket_AddPowerDown           (const MCDRV_POWER_INFO* psPowerInfo, const MCDRV_POWER_UPDATE* psPowerUpdate);
++SINT32                McPacket_AddPathSet                     (void);
++SINT32                McPacket_AddMixSet                      (void);
++SINT32                McPacket_AddStart                       (void);
++SINT32                McPacket_AddStop                        (void);
++SINT32                McPacket_AddDigitalIO           (UINT32 dUpdateInfo);
++SINT32                McPacket_AddDAC                         (UINT32 dUpdateInfo);
++SINT32                McPacket_AddADC                         (UINT32 dUpdateInfo);
++SINT32                McPacket_AddSP                          (void);
++SINT32                McPacket_AddDNG                         (UINT32 dUpdateInfo);
++SINT32                McPacket_AddAE                          (UINT32 dUpdateInfo);
++SINT32                McPacket_AddPDM                         (UINT32 dUpdateInfo);
++SINT32                McPacket_AddGPMode                      (void);
++SINT32                McPacket_AddGPMask                      (UINT32 dPadNo);
++SINT32                McPacket_AddGPSet                       (UINT8 bGpio, UINT32 dPadNo);
++SINT32                McPacket_AddSysEq                       (UINT32 dUpdateInfo);
++SINT32                McPacket_AddClockSwitch         (void);
++
++
++#endif /* _MCPACKING_H_ */
+diff --git a/sound/soc/codecs/mc1n2/mcresctrl.c b/sound/soc/codecs/mc1n2/mcresctrl.c
+new file mode 100644
+index 0000000..bb30235
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mcresctrl.c
+@@ -0,0 +1,9419 @@
++/****************************************************************************
++ *
++ *            Copyright(c) 2010 Yamaha Corporation. All rights reserved.
++ *
++ *            Module          : mcresctrl.c
++ *
++ *            Description     : MC Driver resource control
++ *
++ *            Version         : 1.0.0         2010.09.10
++ *
++ ****************************************************************************/
++
++
++#include "mcresctrl.h"
++#include "mcdevif.h"
++#include "mcservice.h"
++#include "mcdriver.h"
++#include "mcdefs.h"
++#include "mcdevprof.h"
++#include "mcmachdep.h"
++#if MCDRV_DEBUG_LEVEL
++#include "mcdebuglog.h"
++#endif
++
++
++
++/* wait time */
++#define       MCDRV_INTERVAL_MUTE     (1000)
++#define       MCDRV_TIME_OUT_MUTE     (1000)
++
++
++static MCDRV_STATE    geState = eMCDRV_STATE_NOTINIT;
++
++static MCDRV_GLOBAL_INFO      gsGlobalInfo;
++static MCDRV_PACKET                   gasPacket[MCDRV_MAX_PACKETS+1];
++
++/* register next address */
++static const UINT16   gawNextAddressA[MCDRV_A_REG_NUM] =
++{
++      0,              1,              2,              0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 8,              0xFFFF, 0xFFFF, 0xFFFF, 12,             13,             14,             15,
++      16,             17,             18,             19,             20,             21,             22,             23,             0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
++      0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
++      0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF
++};
++
++static const UINT16   gawNextAddressB_BASE[MCDRV_B_BASE_REG_NUM] =
++{
++      1,              2,              3,              4,              5,              6,              7,              0xFFFF, 9,              10,             11,             12,             13,             0xFFFF, 0xFFFF, 0xFFFF,
++      0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 26,             0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 31,             0xFFFF
++};
++
++static const UINT16   gawNextAddressB_MIXER[MCDRV_B_MIXER_REG_NUM] =
++{
++      1,              2,              3,              4,              5,              6,              7,              8,              9,              10,             11,             12,             13,             14,             15,             16,
++      17,             18,             19,             20,             21,             22,             23,             24,             25,             26,             27,             28,             29,             30,             31,             32,
++      33,             34,             35,             36,             37,             38,             39,             40,             41,             42,             43,             44,             45,             46,             47,             48,
++      49,             50,             51,             52,             53,             54,             55,             56,             57,             58,             59,             60,             61,             62,             63,             64,
++      65,             66,             67,             68,             69,             70,             71,             72,             73,             74,             75,             76,             77,             78,             79,             80,
++      81,             82,             83,             84,             85,             86,             87,             88,             89,             90,             91,             92,             93,             94,             95,             96,
++      97,             98,             99,             100,    101,    102,    103,    104,    105,    106,    107,    108,    109,    110,    111,    112,
++      113,    114,    115,    116,    117,    118,    119,    120,    121,    122,    123,    124,    125,    126,    127,    128,
++      129,    130,    131,    132,    133,    134,    135,    136,    137,    138,    139,    140,    141,    142,    143,    144,
++      145,    146,    147,    148,    149,    150,    151,    152,    153,    154,    155,    156,    157,    158,    159,    160,
++      161,    162,    163,    164,    165,    166,    167,    168,    169,    170,    171,    172,    173,    174,    175,    176,
++      177,    178,    179,    180,    181,    182,    183,    184,    185,    186,    187,    188,    189,    190,    191,    192,
++      193,    194,    195,    196,    197,    198,    199,    200,    201,    202,    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
++      0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF
++};
++
++static const UINT16   gawNextAddressB_AE[MCDRV_B_AE_REG_NUM] =
++{
++      1,              2,              3,              4,              5,              6,              7,              8,              9,              10,             11,             12,             13,             14,             15,             16,
++      17,             18,             19,             20,             21,             22,             23,             24,             25,             26,             27,             28,             29,             30,             31,             32,
++      33,             34,             35,             36,             37,             38,             39,             40,             41,             42,             43,             44,             45,             46,             47,             48,
++      49,             50,             51,             52,             53,             54,             55,             56,             57,             58,             59,             60,             61,             62,             63,             64,
++      65,             66,             67,             68,             69,             70,             71,             72,             73,             74,             75,             76,             77,             78,             79,             80,
++      81,             82,             83,             84,             85,             86,             87,             88,             89,             90,             91,             92,             93,             94,             95,             96,
++      97,             98,             99,             100,    101,    102,    103,    104,    105,    106,    107,    108,    109,    110,    111,    112,
++      113,    114,    115,    116,    117,    118,    119,    120,    121,    122,    123,    124,    125,    126,    127,    128,
++      129,    130,    131,    132,    133,    134,    135,    136,    137,    138,    139,    140,    141,    142,    143,    144,
++      145,    146,    147,    148,    149,    150,    151,    152,    153,    154,    155,    156,    157,    158,    159,    160,
++      161,    162,    163,    164,    165,    166,    167,    168,    169,    170,    171,    172,    173,    174,    175,    176,
++      177,    178,    179,    180,    181,    182,    183,    184,    185,    186,    187,    188,    189,    190,    191,    192,
++      193,    194,    195,    196,    197,    198,    199,    200,    201,    202,    203,    204,    205,    206,    207,    208,
++      209,    210,    211,    212,    213,    214,    215,    216,    217,    218,    219,    220,    221,    222,    223,    224,
++      225,    226,    227,    228,    229,    230,    231,    232,    233,    234,    235,    236,    237,    238,    239,    240,
++      241,    242,    243,    244,    245,    246,    247,    248,    249,    250,    251,    252,    253,    254,    0xFFFF
++};
++
++static const UINT16   gawNextAddressB_CDSP[MCDRV_B_CDSP_REG_NUM] =
++{
++      1,              2,              3,              4,              5,              6,              7,              8,              9,              10,             11,             12,             13,             14,             15,             16,
++      17,             18,             19,             20,             21,             22,             23,             24,             25,             26,             27,             28,             29,             30,             31,             32,
++      33,             34,             35,             36,             37,             38,             39,             40,             41,             42,             43,             44,             45,             46,             47,             48,
++      49,             50,             51,             52,             53,             54,             55,             56,             57,             58,             59,             60,             61,             62,             63,             64,
++      65,             66,             67,             68,             69,             70,             71,             72,             73,             74,             75,             76,             77,             78,             79,             80,
++      81,             82,             83,             84,             85,             86,             87,             88,             89,             90,             91,             92,             93,             94,             95,             96,
++      97,             98,             99,             100,    101,    102,    103,    104,    105,    106,    107,    108,    109,    110,    111,    112,
++      113,    114,    115,    116,    117,    118,    119,    120,    121,    122,    123,    124,    125,    126,    127,    128,
++      129,    0xFFFF
++};
++
++static const UINT16   gawNextAddressB_CODEC[MCDRV_B_CODEC_REG_NUM] =
++{
++      1,              2,              3,              4,              5,              6,              7,              8,              9,              10,             11,             12,             13,             14,             15,             16,
++      17,             18,             19,             20,             21,             22,             23,             24,             25,             26,             27,             28,             29,             30,             31,             32,
++      33,             34,             35,             36,             37,             38,             39,             40,             41,             42,             43,             44,             45,             46,             47,             48,
++      49,             50,             51,             52,             53,             54,             55,             56,             57,             58,             59,             60,             61,             62,             63,             64,
++      65,             66,             67,             68,             69,             70,             71,             72,             73,             74,             75,             76,             77,             78,             79,             80,
++      81,             82,             83,             84,             85,             86,             87,             88,             89,             90,             91,             92,             93,             94,             95,             96,
++      97,             98,             99,             100,    101,    102,    103,    104,    105,    106,    107,    108,    109,    110,    111,    112,
++      113,    114,    115,    116,    117,    118,    119,    120,    121,    122,    123,    124,    125,    126,    127,    0xFFFF
++};
++
++static const UINT16   gawNextAddressB_Ana[MCDRV_B_ANA_REG_NUM] =
++{
++      1,              2,              3,              4,              5,              6,              7,              8,              9,              10,             11,             12,             13,             14,             15,             16,
++      17,             18,             19,             20,             21,             22,             23,             24,             25,             26,             27,             28,             29,             30,             31,             32,
++      33,             34,             35,             36,             37,             38,             39,             40,             41,             42,             43,             44,             45,             46,             47,             48,
++      49,             50,             51,             52,             53,             54,             55,             56,             57,             58,             59,             60,             61,             62,             63,             64,
++      65,             66,             67,             68,             69,             70,             71,             72,             73,             74,             75,             76,             77,             0xFFFF, 79,             80,
++      81,             82,             83,             84,             85,             86,             87,             88,             89,             90,             91,             92,             93,             94,             95,             96,
++      97,             98,             99,             100,    101,    102,    103,    104,    105,    106,    107,    108,    109,    110,    111,    112,
++      113,    114,    115,    116,    117,    118,    119,    120,    121,    122,    123,    124,    125,    126,    127,    0xFFFF
++};
++
++/*    register access available       */
++static const MCDRV_REG_ACCSESS        gawRegAccessAvailableA[256] =
++{
++      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_READ_ONLY,       eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,
++      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_WRITE_ONLY,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++};
++static const MCDRV_REG_ACCSESS        gawRegAccessAvailableB_BASE[256] =
++{
++      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++};
++static const MCDRV_REG_ACCSESS        gawRegAccessAvailableB_ANA[256] =
++{
++      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_READ_ONLY,       eMCDRV_READ_ONLY,       eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,
++      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,
++      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_ONLY,
++      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,
++      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,
++      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_ONLY,       eMCDRV_ACCESS_DENY,
++      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,
++      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_READ_ONLY,       eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++};
++static const MCDRV_REG_ACCSESS        gawRegAccessAvailableB_CODEC[256] =
++{
++      eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_READ_ONLY,       eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,
++      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,
++      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,
++      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,
++      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_READ_WRITE,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++};
++static const MCDRV_REG_ACCSESS        gawRegAccessAvailableB_MIX[256] =
++{
++      eMCDRV_READ_ONLY,       eMCDRV_READ_ONLY,       eMCDRV_READ_ONLY,       eMCDRV_READ_ONLY,       eMCDRV_READ_ONLY,       eMCDRV_READ_ONLY,       eMCDRV_READ_ONLY,       eMCDRV_READ_ONLY,
++      eMCDRV_READ_ONLY,       eMCDRV_READ_ONLY,       eMCDRV_READ_ONLY,       eMCDRV_READ_ONLY,       eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,
++      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,
++      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,
++      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,
++      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,
++      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,
++      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,
++      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,
++      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,
++      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,
++      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,
++      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_READ_WRITE,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++};
++static const MCDRV_REG_ACCSESS        gawRegAccessAvailableB_AE[256] =
++{
++      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,
++      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,
++      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,
++      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,
++      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,
++      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,
++      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,
++      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,
++      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,
++      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,
++      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,
++      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,
++      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,
++      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,
++      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,
++      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,
++      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,
++      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,
++      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,
++      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,
++      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,
++      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,
++      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_WRITE_ONLY,      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++      eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,     eMCDRV_ACCESS_DENY,
++};
++
++
++static void           SetRegDefault(void);
++static void           InitPathInfo(void);
++static void           InitVolInfo(void);
++static void           InitDioInfo(void);
++static void           InitDacInfo(void);
++static void           InitAdcInfo(void);
++static void           InitSpInfo(void);
++static void           InitDngInfo(void);
++static void           InitAeInfo(void);
++static void           InitPdmInfo(void);
++static void           InitGpMode(void);
++static void           InitGpMask(void);
++static void           InitSysEq(void);
++static void           InitClockSwitch(void);
++
++static void           ValidateADC(void);
++static void           ValidateDAC(void);
++static void           ValidateAE(void);
++static void           ValidateMix(void);
++
++static void           SetHPSourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetSPSourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetRCVSourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetLO1SourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetLO2SourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetPMSourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetDIT0SourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetDIT1SourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetDIT2SourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetDACSourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetAESourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetCDSPSourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetADC0SourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetADC1SourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetMixSourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++static void           SetBiasSourceOnOff(const MCDRV_PATH_INFO* psPathInfo);
++
++static void           SetDIOCommon(const MCDRV_DIO_INFO* psDioInfo, UINT8 bPort);
++static void           SetDIODIR(const MCDRV_DIO_INFO* psDioInfo, UINT8 bPort);
++static void           SetDIODIT(const MCDRV_DIO_INFO* psDioInfo, UINT8 bPort);
++
++static SINT16 GetDigitalVolReg(SINT16 swVol);
++static SINT16 GetADVolReg(SINT16 swVol);
++static SINT16 GetLIVolReg(SINT16 swVol);
++static SINT16 GetMcVolReg(SINT16 swVol);
++static SINT16 GetMcGainReg(SINT16 swVol);
++static SINT16 GetHpVolReg(SINT16 swVol);
++static SINT16 GetHpGainReg(SINT16 swVol);
++static SINT16 GetSpVolReg(SINT16 swVol);
++static SINT16 GetRcVolReg(SINT16 swVol);
++static SINT16 GetLoVolReg(SINT16 swVol);
++
++static SINT32 WaitBitSet(UINT8 bSlaveAddr, UINT16 wRegAddr, UINT8 bBit, UINT32 dCycleTime, UINT32 dTimeOut);
++static SINT32 WaitBitRelease(UINT8 bSlaveAddr, UINT16 wRegAddr, UINT8 bBit, UINT32 dCycleTime, UINT32 dTimeOut);
++
++/****************************************************************************
++ *    McResCtrl_SetHwId
++ *
++ *    Description:
++ *                    Set hardware ID.
++ *    Arguments:
++ *                    bHwId   hardware ID
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_INIT
++ *
++ ****************************************************************************/
++SINT32        McResCtrl_SetHwId
++(
++      UINT8   bHwId
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_SetHwId");
++#endif
++
++      gsGlobalInfo.bHwId      = bHwId;
++
++      switch (bHwId)
++      {
++      case MCDRV_HWID_AA:
++              McDevProf_SetDevId(eMCDRV_DEV_ID_1N2);
++              break;
++      case MCDRV_HWID_AB:
++              McDevProf_SetDevId(eMCDRV_DEV_ID_1N2);
++              break;
++      default:
++              sdRet   = MCDRV_ERROR_INIT;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_SetHwId", &sdRet);
++#endif
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    McResCtrl_GetHwId
++ *
++ *    Description:
++ *                    Get hardware ID.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    hardware ID
++ *
++ ****************************************************************************/
++UINT8 McResCtrl_GetHwId
++(
++      void
++)
++{
++      SINT32  sdRet   = gsGlobalInfo.bHwId;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_GetHwId");
++#endif
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_GetHwId", &sdRet);
++#endif
++
++      return (UINT8)sdRet;
++}
++
++/****************************************************************************
++ *    McResCtrl_Init
++ *
++ *    Description:
++ *                    initialize the resource controller.
++ *    Arguments:
++ *                    psInitInfo      pointer to the initialize information struct
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_Init
++(
++      const MCDRV_INIT_INFO*  psInitInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_Init");
++#endif
++
++      gsGlobalInfo.ePacketBufAlloc    = eMCDRV_PACKETBUF_FREE;
++      SetRegDefault();
++
++      gsGlobalInfo.sInitInfo.bCkSel   = psInitInfo->bCkSel;
++      gsGlobalInfo.sInitInfo.bDivR0   = psInitInfo->bDivR0;
++      gsGlobalInfo.sInitInfo.bDivF0   = psInitInfo->bDivF0;
++      gsGlobalInfo.sInitInfo.bDivR1   = psInitInfo->bDivR1;
++      gsGlobalInfo.sInitInfo.bDivF1   = psInitInfo->bDivF1;
++      if(McDevProf_IsValid(eMCDRV_FUNC_RANGE) == 1)
++      {
++              gsGlobalInfo.sInitInfo.bRange0  = psInitInfo->bRange0;
++              gsGlobalInfo.sInitInfo.bRange1  = psInitInfo->bRange1;
++      }
++      else
++      {
++              gsGlobalInfo.sInitInfo.bRange0  = 0;
++              gsGlobalInfo.sInitInfo.bRange1  = 0;
++      }
++      if(McDevProf_IsValid(eMCDRV_FUNC_BYPASS) == 1)
++      {
++              gsGlobalInfo.sInitInfo.bBypass  = psInitInfo->bBypass;
++      }
++      else
++      {
++              gsGlobalInfo.sInitInfo.bBypass  = 0;
++      }
++      gsGlobalInfo.sInitInfo.bDioSdo0Hiz      = psInitInfo->bDioSdo0Hiz;
++      gsGlobalInfo.sInitInfo.bDioSdo1Hiz      = psInitInfo->bDioSdo1Hiz;
++      gsGlobalInfo.sInitInfo.bDioSdo2Hiz      = psInitInfo->bDioSdo2Hiz;
++      gsGlobalInfo.sInitInfo.bDioClk0Hiz      = psInitInfo->bDioClk0Hiz;
++      gsGlobalInfo.sInitInfo.bDioClk1Hiz      = psInitInfo->bDioClk1Hiz;
++      gsGlobalInfo.sInitInfo.bDioClk2Hiz      = psInitInfo->bDioClk2Hiz;
++      gsGlobalInfo.sInitInfo.bPcmHiz          = psInitInfo->bPcmHiz;
++      gsGlobalInfo.sInitInfo.bLineIn1Dif      = psInitInfo->bLineIn1Dif;
++      if(McDevProf_IsValid(eMCDRV_FUNC_LI2) == 1)
++      {
++              gsGlobalInfo.sInitInfo.bLineIn2Dif      = psInitInfo->bLineIn2Dif;
++      }
++      else
++      {
++              gsGlobalInfo.sInitInfo.bLineIn2Dif      = MCDRV_LINE_STEREO;
++      }
++      gsGlobalInfo.sInitInfo.bLineOut1Dif     = psInitInfo->bLineOut1Dif;
++      gsGlobalInfo.sInitInfo.bLineOut2Dif     = psInitInfo->bLineOut2Dif;
++      gsGlobalInfo.sInitInfo.bSpmn            = psInitInfo->bSpmn;
++      gsGlobalInfo.sInitInfo.bMic1Sng         = psInitInfo->bMic1Sng;
++      gsGlobalInfo.sInitInfo.bMic2Sng         = psInitInfo->bMic2Sng;
++      gsGlobalInfo.sInitInfo.bMic3Sng         = psInitInfo->bMic3Sng;
++      gsGlobalInfo.sInitInfo.bPowerMode       = psInitInfo->bPowerMode;
++      gsGlobalInfo.sInitInfo.bSpHiz           = psInitInfo->bSpHiz;
++      gsGlobalInfo.sInitInfo.bLdo                     = psInitInfo->bLdo;
++      gsGlobalInfo.sInitInfo.bPad0Func        = psInitInfo->bPad0Func;
++      gsGlobalInfo.sInitInfo.bPad1Func        = psInitInfo->bPad1Func;
++      if(McDevProf_IsValid(eMCDRV_FUNC_PAD2) == 1)
++      {
++              gsGlobalInfo.sInitInfo.bPad2Func        = psInitInfo->bPad2Func;
++      }
++      else
++      {
++              gsGlobalInfo.sInitInfo.bPad2Func        = MCDRV_PAD_GPIO;
++      }
++      gsGlobalInfo.sInitInfo.bAvddLev         = psInitInfo->bAvddLev;
++      gsGlobalInfo.sInitInfo.bVrefLev         = psInitInfo->bVrefLev;
++      gsGlobalInfo.sInitInfo.bDclGain         = psInitInfo->bDclGain;
++      gsGlobalInfo.sInitInfo.bDclLimit        = psInitInfo->bDclLimit;
++      gsGlobalInfo.sInitInfo.bCpMod           = psInitInfo->bCpMod;
++      gsGlobalInfo.sInitInfo.bReserved1       = psInitInfo->bReserved1;
++      gsGlobalInfo.sInitInfo.bReserved2       = psInitInfo->bReserved2;
++      gsGlobalInfo.sInitInfo.bReserved3       = psInitInfo->bReserved3;
++      gsGlobalInfo.sInitInfo.bReserved4       = psInitInfo->bReserved4;
++      gsGlobalInfo.sInitInfo.bReserved5       = psInitInfo->bReserved5;
++      gsGlobalInfo.sInitInfo.sWaitTime        = psInitInfo->sWaitTime;
++
++      InitPathInfo();
++      InitVolInfo();
++      InitDioInfo();
++      InitDacInfo();
++      InitAdcInfo();
++      InitSpInfo();
++      InitDngInfo();
++      InitAeInfo();
++      InitPdmInfo();
++      InitGpMode();
++      InitGpMask();
++      InitSysEq();
++      InitClockSwitch();
++
++      McResCtrl_InitRegUpdate();
++
++      gsGlobalInfo.eAPMode = eMCDRV_APM_OFF;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_Init", 0);
++#endif
++}
++
++/****************************************************************************
++ *    SetRegDefault
++ *
++ *    Description:
++ *                    Initialize the virtual registers.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetRegDefault
++(
++      void
++)
++{
++      UINT16  i;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("SetRegDefault");
++#endif
++
++      for(i = 0; i < MCDRV_A_REG_NUM; i++)
++      {
++              gsGlobalInfo.abRegValA[i]       = 0;
++      }
++      gsGlobalInfo.abRegValA[MCI_RST]         = MCI_RST_DEF;
++      gsGlobalInfo.abRegValA[MCI_HW_ID]       = MCI_HW_ID_DEF;
++
++      for(i = 0; i < MCDRV_B_BASE_REG_NUM; i++)
++      {
++              gsGlobalInfo.abRegValB_BASE[i]  = 0;
++      }
++      gsGlobalInfo.abRegValB_BASE[MCI_RSTB]                           = MCI_RSTB_DEF;
++      gsGlobalInfo.abRegValB_BASE[MCI_PWM_DIGITAL]            = MCI_PWM_DIGITAL_DEF;
++      gsGlobalInfo.abRegValB_BASE[MCI_PWM_DIGITAL_1]          = MCI_PWM_DIGITAL_1_DEF;
++      gsGlobalInfo.abRegValB_BASE[MCI_PWM_DIGITAL_CDSP]       = MCI_PWM_DIGITAL_CDSP_DEF;
++      gsGlobalInfo.abRegValB_BASE[MCI_PWM_DIGITAL_BDSP]       = MCI_PWM_DIGITAL_BDSP_DEF;
++      gsGlobalInfo.abRegValB_BASE[MCI_SD_MSK]                         = MCI_SD_MSK_DEF;
++      gsGlobalInfo.abRegValB_BASE[MCI_SD_MSK_1]                       = MCI_SD_MSK_1_DEF;
++      gsGlobalInfo.abRegValB_BASE[MCI_BCLK_MSK]                       = MCI_BCLK_MSK_DEF;
++      gsGlobalInfo.abRegValB_BASE[MCI_BCLK_MSK_1]                     = MCI_BCLK_MSK_1_DEF;
++      gsGlobalInfo.abRegValB_BASE[MCI_BCKP]                           = MCI_BCKP_DEF;
++      gsGlobalInfo.abRegValB_BASE[MCI_PA_MSK]                         = MCI_PA_MSK_DEF;
++
++      for(i = 0; i < MCDRV_B_MIXER_REG_NUM; i++)
++      {
++              gsGlobalInfo.abRegValB_MIXER[i] = 0;
++      }
++      gsGlobalInfo.abRegValB_MIXER[MCI_DIT_ININTP]    = MCI_DIT_ININTP_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_DIR_INTP]              = MCI_DIR_INTP_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_ADC_INTP]              = MCI_ADC_INTP_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_AINTP]                 = MCI_AINTP_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_IINTP]                 = MCI_IINTP_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_DAC_INTP]              = MCI_DAC_INTP_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_DIR0_CH]               = MCI_DIR0_CH_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_DIT0_SLOT]             = MCI_DIT0_SLOT_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_PCM_RX0]               = MCI_PCM_RX0_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_PCM_TX0]               = MCI_PCM_TX0_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_PCM_SLOT_TX0]  = MCI_PCM_SLOT_TX0_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_DIR1_CH]               = MCI_DIR1_CH_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_DIT1_SLOT]             = MCI_DIT1_SLOT_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_PCM_RX1]               = MCI_PCM_RX1_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_PCM_TX1]               = MCI_PCM_TX1_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_PCM_SLOT_TX1]  = MCI_PCM_SLOT_TX1_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_DIR2_CH]               = MCI_DIR2_CH_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_DIT2_SLOT]             = MCI_DIT2_SLOT_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_PCM_RX2]               = MCI_PCM_RX2_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_PCM_TX2]               = MCI_PCM_TX2_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_PCM_SLOT_TX2]  = MCI_PCM_SLOT_TX2_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_CDI_CH]                = MCI_CDI_CH_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_CDO_SLOT]              = MCI_CDO_SLOT_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_PDM_AGC]               = MCI_PDM_AGC_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_PDM_STWAIT]    = MCI_PDM_STWAIT_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_CHP_H]                 = MCI_CHP_H_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_CHP_M]                 = MCI_CHP_M_DEF;
++      gsGlobalInfo.abRegValB_MIXER[MCI_CHP_L]                 = MCI_CHP_L_DEF;
++
++      for(i = 0; i < MCDRV_B_AE_REG_NUM; i++)
++      {
++              gsGlobalInfo.abRegValB_AE[i]    = 0;
++      }
++      gsGlobalInfo.abRegValB_AE[MCI_BAND0_CEQ0]       = MCI_BAND0_CEQ0_H_DEF;
++      gsGlobalInfo.abRegValB_AE[MCI_BAND1_CEQ0]       = MCI_BAND1_CEQ0_H_DEF;
++      gsGlobalInfo.abRegValB_AE[MCI_BAND2_CEQ0]       = MCI_BAND2_CEQ0_H_DEF;
++      gsGlobalInfo.abRegValB_AE[MCI_BAND3H_CEQ0]      = MCI_BAND3H_CEQ0_H_DEF;
++      gsGlobalInfo.abRegValB_AE[MCI_BAND4H_CEQ0]      = MCI_BAND4H_CEQ0_H_DEF;
++      gsGlobalInfo.abRegValB_AE[MCI_BAND5_CEQ0]       = MCI_BAND5_CEQ0_H_DEF;
++      gsGlobalInfo.abRegValB_AE[MCI_BAND6H_CEQ0]      = MCI_BAND6H_CEQ0_H_DEF;
++      gsGlobalInfo.abRegValB_AE[MCI_BAND7H_CEQ0]      = MCI_BAND7H_CEQ0_H_DEF;
++      gsGlobalInfo.abRegValB_AE[MCI_PDM_CHP0_H]       = MCI_PDM_CHP0_H_DEF;
++      gsGlobalInfo.abRegValB_AE[MCI_PDM_CHP0_M]       = MCI_PDM_CHP0_M_DEF;
++      gsGlobalInfo.abRegValB_AE[MCI_PDM_CHP0_L]       = MCI_PDM_CHP0_L_DEF;
++      gsGlobalInfo.abRegValB_AE[MCI_PDM_CHP1_H]       = MCI_PDM_CHP1_H_DEF;
++      gsGlobalInfo.abRegValB_AE[MCI_PDM_CHP1_M]       = MCI_PDM_CHP1_M_DEF;
++      gsGlobalInfo.abRegValB_AE[MCI_PDM_CHP1_L]       = MCI_PDM_CHP1_L_DEF;
++      gsGlobalInfo.abRegValB_AE[MCI_PDM_CHP3_H]       = MCI_PDM_CHP3_H_DEF;
++      gsGlobalInfo.abRegValB_AE[MCI_PDM_CHP3_M]       = MCI_PDM_CHP3_M_DEF;
++      gsGlobalInfo.abRegValB_AE[MCI_PDM_CHP3_L]       = MCI_PDM_CHP3_L_DEF;
++
++      for(i = 0; i < MCDRV_B_CDSP_REG_NUM; i++)
++      {
++              gsGlobalInfo.abRegValB_CDSP[i]  = 0;
++      }
++      gsGlobalInfo.abRegValB_CDSP[MCI_JOEMP]          = MCI_JOEMP_DEF;
++      gsGlobalInfo.abRegValB_CDSP[MCI_JEEMP]          = MCI_JEEMP_DEF;
++      gsGlobalInfo.abRegValB_CDSP[MCI_CDSP_SRST]      = MCI_CDSP_SRST_DEF;
++
++      for(i = 0; i < MCDRV_B_ANA_REG_NUM; i++)
++      {
++              gsGlobalInfo.abRegValB_ANA[i]   = 0;
++      }
++      gsGlobalInfo.abRegValB_ANA[MCI_ANA_RST]                 = MCI_ANA_RST_DEF;
++      gsGlobalInfo.abRegValB_ANA[MCI_PWM_ANALOG_0]    = MCI_PWM_ANALOG_0_DEF;
++      gsGlobalInfo.abRegValB_ANA[MCI_PWM_ANALOG_1]    = MCI_PWM_ANALOG_1_DEF;
++      gsGlobalInfo.abRegValB_ANA[MCI_PWM_ANALOG_2]    = MCI_PWM_ANALOG_2_DEF;
++      gsGlobalInfo.abRegValB_ANA[MCI_PWM_ANALOG_3]    = MCI_PWM_ANALOG_3_DEF;
++      gsGlobalInfo.abRegValB_ANA[MCI_PWM_ANALOG_4]    = MCI_PWM_ANALOG_4_DEF;
++      gsGlobalInfo.abRegValB_ANA[MCI_HPVOL_L]                 = MCI_HPVOL_L_DEF;
++      gsGlobalInfo.abRegValB_ANA[MCI_SPVOL_L]                 = MCI_SPVOL_L_DEF;
++      gsGlobalInfo.abRegValB_ANA[MCI_RCVOL]                   = MCI_RCVOL_DEF;
++      gsGlobalInfo.abRegValB_ANA[MCI_LEV]                             = MCI_LEV_DEF;
++      gsGlobalInfo.abRegValB_ANA[MCI_DNGATRT_HP]              = MCI_DNGATRT_HP_DEF;
++      gsGlobalInfo.abRegValB_ANA[MCI_DNGTARGET_HP]    = MCI_DNGTARGET_HP_DEF;
++      gsGlobalInfo.abRegValB_ANA[MCI_DNGON_HP]                = MCI_DNGON_HP_DEF;
++      gsGlobalInfo.abRegValB_ANA[MCI_DNGATRT_SP]              = MCI_DNGATRT_SP_DEF;
++      gsGlobalInfo.abRegValB_ANA[MCI_DNGTARGET_SP]    = MCI_DNGTARGET_SP_DEF;
++      gsGlobalInfo.abRegValB_ANA[MCI_DNGON_SP]                = MCI_DNGON_SP_DEF;
++      gsGlobalInfo.abRegValB_ANA[MCI_DNGATRT_RC]              = MCI_DNGATRT_RC_DEF;
++      gsGlobalInfo.abRegValB_ANA[MCI_DNGTARGET_RC]    = MCI_DNGTARGET_RC_DEF;
++      gsGlobalInfo.abRegValB_ANA[MCI_DNGON_RC]                = MCI_DNGON_RC_DEF;
++
++      for(i = 0; i < MCDRV_B_CODEC_REG_NUM; i++)
++      {
++              gsGlobalInfo.abRegValB_CODEC[i] = 0;
++      }
++      gsGlobalInfo.abRegValB_CODEC[MCI_DPADIF]                = MCI_DPADIF_DEF;
++      gsGlobalInfo.abRegValB_CODEC[MCI_PLL_RST]               = MCI_PLL_RST_DEF;
++      gsGlobalInfo.abRegValB_CODEC[MCI_DIVR0]                 = MCI_DIVR0_DEF;
++      gsGlobalInfo.abRegValB_CODEC[MCI_DIVF0]                 = MCI_DIVF0_DEF;
++      gsGlobalInfo.abRegValB_CODEC[MCI_DIVR1]                 = MCI_DIVR1_DEF;
++      gsGlobalInfo.abRegValB_CODEC[MCI_DIVF1]                 = MCI_DIVF1_DEF;
++      gsGlobalInfo.abRegValB_CODEC[MCI_AD_AGC]                = MCI_AD_AGC_DEF;
++      gsGlobalInfo.abRegValB_CODEC[MCI_DAC_CONFIG]    = MCI_DAC_CONFIG_DEF;
++      gsGlobalInfo.abRegValB_CODEC[MCI_SYS_CEQ0_19_12]= MCI_SYS_CEQ0_19_12_DEF;
++      gsGlobalInfo.abRegValB_CODEC[MCI_SYS_CEQ0_11_4] = MCI_SYS_CEQ0_11_4_DEF;
++      gsGlobalInfo.abRegValB_CODEC[MCI_SYS_CEQ0_3_0]  = MCI_SYS_CEQ0_3_0_DEF;
++      gsGlobalInfo.abRegValB_CODEC[MCI_SYS_CEQ1_19_12]= MCI_SYS_CEQ1_19_12_DEF;
++      gsGlobalInfo.abRegValB_CODEC[MCI_SYS_CEQ1_11_4] = MCI_SYS_CEQ1_11_4_DEF;
++      gsGlobalInfo.abRegValB_CODEC[MCI_SYS_CEQ1_3_0]  = MCI_SYS_CEQ1_3_0_DEF;
++      gsGlobalInfo.abRegValB_CODEC[MCI_SYS_CEQ2_19_12]= MCI_SYS_CEQ2_19_12_DEF;
++      gsGlobalInfo.abRegValB_CODEC[MCI_SYS_CEQ2_11_4] = MCI_SYS_CEQ2_11_4_DEF;
++      gsGlobalInfo.abRegValB_CODEC[MCI_SYS_CEQ2_3_0]  = MCI_SYS_CEQ2_3_0_DEF;
++      gsGlobalInfo.abRegValB_CODEC[MCI_SYS_CEQ3_19_12]= MCI_SYS_CEQ3_19_12_DEF;
++      gsGlobalInfo.abRegValB_CODEC[MCI_SYS_CEQ3_11_4] = MCI_SYS_CEQ3_11_4_DEF;
++      gsGlobalInfo.abRegValB_CODEC[MCI_SYS_CEQ3_3_0]  = MCI_SYS_CEQ3_3_0_DEF;
++      gsGlobalInfo.abRegValB_CODEC[MCI_SYS_CEQ4_19_12]= MCI_SYS_CEQ4_19_12_DEF;
++      gsGlobalInfo.abRegValB_CODEC[MCI_SYS_CEQ4_11_4] = MCI_SYS_CEQ4_11_4_DEF;
++      gsGlobalInfo.abRegValB_CODEC[MCI_SYS_CEQ4_3_0]  = MCI_SYS_CEQ4_3_0_DEF;
++      gsGlobalInfo.abRegValB_CODEC[MCI_SYSTEM_EQON]   = MCI_SYSTEM_EQON_DEF;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("SetRegDefault", 0);
++#endif
++}
++
++/****************************************************************************
++ *    InitPathInfo
++ *
++ *    Description:
++ *                    Initialize path info.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   InitPathInfo
++(
++      void
++)
++{
++      UINT8   bCh, bBlockIdx;
++      UINT8   abOnOff[SOURCE_BLOCK_NUM];
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("InitPathInfo");
++#endif
++
++      abOnOff[0]      = (MCDRV_SRC0_MIC1_OFF|MCDRV_SRC0_MIC2_OFF|MCDRV_SRC0_MIC3_OFF);
++      abOnOff[1]      = (MCDRV_SRC1_LINE1_L_OFF|MCDRV_SRC1_LINE1_R_OFF|MCDRV_SRC1_LINE1_M_OFF);
++      abOnOff[2]      = (MCDRV_SRC2_LINE2_L_OFF|MCDRV_SRC2_LINE2_R_OFF|MCDRV_SRC2_LINE2_M_OFF);
++      abOnOff[3]      = (MCDRV_SRC3_DIR0_OFF|MCDRV_SRC3_DIR1_OFF|MCDRV_SRC3_DIR2_OFF|MCDRV_SRC3_DIR2_DIRECT_OFF);
++      abOnOff[4]      = (MCDRV_SRC4_DTMF_OFF|MCDRV_SRC4_PDM_OFF|MCDRV_SRC4_ADC0_OFF|MCDRV_SRC4_ADC1_OFF);
++      abOnOff[5]      = (MCDRV_SRC5_DAC_L_OFF|MCDRV_SRC5_DAC_R_OFF|MCDRV_SRC5_DAC_M_OFF);
++      abOnOff[6]      = (MCDRV_SRC6_MIX_OFF|MCDRV_SRC6_AE_OFF|MCDRV_SRC6_CDSP_OFF|MCDRV_SRC6_CDSP_DIRECT_OFF);
++
++      for(bCh = 0; bCh < HP_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo.sPathInfo.asHpOut[bCh].abSrcOnOff[bBlockIdx]       = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < SP_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo.sPathInfo.asSpOut[bCh].abSrcOnOff[bBlockIdx]       = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < RC_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo.sPathInfo.asRcOut[bCh].abSrcOnOff[bBlockIdx]       = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < LOUT1_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo.sPathInfo.asLout1[bCh].abSrcOnOff[bBlockIdx]       = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < LOUT2_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo.sPathInfo.asLout2[bCh].abSrcOnOff[bBlockIdx]       = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < PEAK_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo.sPathInfo.asPeak[bCh].abSrcOnOff[bBlockIdx]        = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < DIT0_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo.sPathInfo.asDit0[bCh].abSrcOnOff[bBlockIdx]        = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < DIT1_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo.sPathInfo.asDit1[bCh].abSrcOnOff[bBlockIdx]        = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < DIT2_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo.sPathInfo.asDit2[bCh].abSrcOnOff[bBlockIdx]        = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < DAC_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[bBlockIdx] = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < AE_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo.sPathInfo.asAe[bCh].abSrcOnOff[bBlockIdx]  = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < CDSP_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo.sPathInfo.asCdsp[bCh].abSrcOnOff[bBlockIdx]        = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < ADC0_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo.sPathInfo.asAdc0[bCh].abSrcOnOff[bBlockIdx]        = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < ADC1_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo.sPathInfo.asAdc1[bCh].abSrcOnOff[bBlockIdx]        = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < MIX_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo.sPathInfo.asMix[bCh].abSrcOnOff[bBlockIdx] = abOnOff[bBlockIdx];
++              }
++      }
++      for(bCh = 0; bCh < BIAS_PATH_CHANNELS; bCh++)
++      {
++              for(bBlockIdx = 0; bBlockIdx < SOURCE_BLOCK_NUM; bBlockIdx++)
++              {
++                      gsGlobalInfo.sPathInfo.asBias[bCh].abSrcOnOff[bBlockIdx]        = abOnOff[bBlockIdx];
++              }
++      }
++      gsGlobalInfo.sPathInfoVirtual   = gsGlobalInfo.sPathInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("InitPathInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    InitVolInfo
++ *
++ *    Description:
++ *                    Initialize volume info.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   InitVolInfo
++(
++      void
++)
++{
++      UINT8   bCh;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("InitVolInfo");
++#endif
++
++      for(bCh = 0; bCh < AD0_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswD_Ad0[bCh]                     = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < AD1_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswD_Ad1[bCh]                     = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < AENG6_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswD_Aeng6[bCh]           = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < PDM_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswD_Pdm[bCh]                     = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DTMF_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswD_Dtmfb[bCh]           = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DIO0_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswD_Dir0[bCh]            = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DIO1_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswD_Dir1[bCh]            = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DIO2_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswD_Dir2[bCh]            = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < AD0_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswD_Ad0Att[bCh]          = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < AD1_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswD_Ad1Att[bCh]          = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DIO0_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswD_Dir0Att[bCh]         = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DIO1_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswD_Dir1Att[bCh]         = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DIO2_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswD_Dir2Att[bCh]         = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < PDM_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswD_SideTone[bCh]        = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DTFM_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswD_DtmfAtt[bCh]         = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DAC_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswD_DacMaster[bCh]       = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DAC_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswD_DacVoice[bCh]        = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DAC_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswD_DacAtt[bCh]          = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DIO0_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswD_Dit0[bCh]            = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DIO1_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswD_Dit1[bCh]            = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < DIO2_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswD_Dit2[bCh]            = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < AD0_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswA_Ad0[bCh]                     = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < AD1_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswA_Ad1[bCh]                     = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < LIN1_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswA_Lin1[bCh]            = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < LIN2_VOL_CHANNELS; bCh++)    
++      {
++              gsGlobalInfo.sVolInfo.aswA_Lin2[bCh]            = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < MIC1_VOL_CHANNELS; bCh++)    
++      {
++              gsGlobalInfo.sVolInfo.aswA_Mic1[bCh]            = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < MIC2_VOL_CHANNELS; bCh++)    
++      {
++              gsGlobalInfo.sVolInfo.aswA_Mic2[bCh]            = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < MIC3_VOL_CHANNELS; bCh++)    
++      {
++              gsGlobalInfo.sVolInfo.aswA_Mic3[bCh]            = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < HP_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswA_Hp[bCh]                      = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < SP_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswA_Sp[bCh]                      = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < RC_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswA_Rc[bCh]                      = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < LOUT1_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswA_Lout1[bCh]           = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < LOUT2_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswA_Lout2[bCh]           = MCDRV_LOGICAL_VOL_MUTE;
++      }
++      for(bCh = 0; bCh < MIC1_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswA_Mic1Gain[bCh]        = MCDRV_LOGICAL_MICGAIN_DEF;
++      }
++      for(bCh = 0; bCh < MIC2_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswA_Mic2Gain[bCh]        = MCDRV_LOGICAL_MICGAIN_DEF;
++      }
++      for(bCh = 0; bCh < MIC3_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswA_Mic3Gain[bCh]        = MCDRV_LOGICAL_MICGAIN_DEF;
++      }
++      for(bCh = 0; bCh < HPGAIN_VOL_CHANNELS; bCh++)
++      {
++              gsGlobalInfo.sVolInfo.aswA_HpGain[bCh]          = MCDRV_LOGICAL_HPGAIN_DEF;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("InitVolInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    InitDioInfo
++ *
++ *    Description:
++ *                    Initialize Digital I/O info.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   InitDioInfo
++(
++      void
++)
++{
++      UINT8   bDioIdx, bDioCh;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("InitDioInfo");
++#endif
++
++      for(bDioIdx = 0; bDioIdx < 3; bDioIdx++)
++      {
++              gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDioCommon.bMasterSlave       = MCDRV_DIO_SLAVE;
++              gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDioCommon.bAutoFs            = MCDRV_AUTOFS_ON;
++              gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDioCommon.bFs                        = MCDRV_FS_48000;
++              gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDioCommon.bBckFs                     = MCDRV_BCKFS_64;
++              gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDioCommon.bInterface         = MCDRV_DIO_DA;
++              gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDioCommon.bBckInvert         = MCDRV_BCLK_NORMAL;
++              gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDioCommon.bPcmHizTim         = MCDRV_PCMHIZTIM_FALLING;
++              gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDioCommon.bPcmClkDown        = MCDRV_PCM_CLKDOWN_OFF;
++              gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDioCommon.bPcmFrame          = MCDRV_PCM_SHORTFRAME;
++              gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDioCommon.bPcmHighPeriod     = 0;
++
++              gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDir.wSrcRate                         = 0x0000;
++              gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDir.sDaFormat.bBitSel        = MCDRV_BITSEL_16;
++              gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDir.sDaFormat.bMode          = MCDRV_DAMODE_HEADALIGN;
++              gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDir.sPcmFormat.bMono         = MCDRV_PCM_MONO;
++              gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDir.sPcmFormat.bOrder        = MCDRV_PCM_MSB_FIRST;
++              gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDir.sPcmFormat.bLaw          = MCDRV_PCM_LINEAR;
++              gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDir.sPcmFormat.bBitSel       = MCDRV_PCM_BITSEL_8;
++              for(bDioCh = 0; bDioCh < DIO_CHANNELS; bDioCh++)
++              {
++                      gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDir.abSlot[bDioCh]   = bDioCh;
++              }
++
++              gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDit.wSrcRate                         = 0x0000;
++              gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDit.sDaFormat.bBitSel        = MCDRV_BITSEL_16;
++              gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDit.sDaFormat.bMode          = MCDRV_DAMODE_HEADALIGN;
++              gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDit.sPcmFormat.bMono         = MCDRV_PCM_MONO;
++              gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDit.sPcmFormat.bOrder        = MCDRV_PCM_MSB_FIRST;
++              gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDit.sPcmFormat.bLaw          = MCDRV_PCM_LINEAR;
++              gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDit.sPcmFormat.bBitSel       = MCDRV_PCM_BITSEL_8;
++              for(bDioCh = 0; bDioCh < DIO_CHANNELS; bDioCh++)
++              {
++                      gsGlobalInfo.sDioInfo.asPortInfo[bDioIdx].sDit.abSlot[bDioCh]   = bDioCh;
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("InitDioInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    InitDacInfo
++ *
++ *    Description:
++ *                    Initialize Dac info.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   InitDacInfo
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("InitDacInfo");
++#endif
++
++      gsGlobalInfo.sDacInfo.bMasterSwap       = MCDRV_DSWAP_OFF;
++      gsGlobalInfo.sDacInfo.bVoiceSwap        = MCDRV_DSWAP_OFF;
++      gsGlobalInfo.sDacInfo.bDcCut            = MCDRV_DCCUT_ON;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("InitDacInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    InitAdcInfo
++ *
++ *    Description:
++ *                    Initialize Adc info.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   InitAdcInfo
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("InitAdcInfo");
++#endif
++
++      gsGlobalInfo.sAdcInfo.bAgcAdjust        = MCDRV_AGCADJ_0;
++      gsGlobalInfo.sAdcInfo.bAgcOn            = MCDRV_AGC_OFF;
++      gsGlobalInfo.sAdcInfo.bMono                     = MCDRV_ADC_STEREO;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("InitAdcInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    InitSpInfo
++ *
++ *    Description:
++ *                    Initialize SP info.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   InitSpInfo
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("InitSpInfo");
++#endif
++
++      gsGlobalInfo.sSpInfo.bSwap      = MCDRV_SPSWAP_OFF;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("InitSpInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    InitDngInfo
++ *
++ *    Description:
++ *                    Initialize DNG info.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   InitDngInfo
++(
++      void
++)
++{
++      UINT8   bItem;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("InitDngInfo");
++#endif
++
++      for(bItem = MCDRV_DNG_ITEM_HP; bItem <= MCDRV_DNG_ITEM_RC; bItem++)
++      {
++              gsGlobalInfo.sDngInfo.abOnOff[bItem]            = MCDRV_DNG_OFF;
++              gsGlobalInfo.sDngInfo.abThreshold[bItem]        = MCDRV_DNG_THRES_60;
++              gsGlobalInfo.sDngInfo.abHold[bItem]             = MCDRV_DNG_HOLD_500;
++              gsGlobalInfo.sDngInfo.abAttack[bItem]   = MCDRV_DNG_ATTACK_800;
++              gsGlobalInfo.sDngInfo.abRelease[bItem]  = MCDRV_DNG_RELEASE_940;
++              gsGlobalInfo.sDngInfo.abTarget[bItem]   = MCDRV_DNG_TARGET_MUTE;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("InitDngInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    InitAeInfo
++ *
++ *    Description:
++ *                    Initialize Audio Engine info.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   InitAeInfo
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("InitAeInfo");
++#endif
++
++      gsGlobalInfo.sAeInfo.bOnOff             = 0;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("InitAeInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    InitPdmInfo
++ *
++ *    Description:
++ *                    Initialize Pdm info.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   InitPdmInfo
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("InitPdmInfo");
++#endif
++
++      gsGlobalInfo.sPdmInfo.bClk                      = MCDRV_PDM_CLK_64;
++      gsGlobalInfo.sPdmInfo.bAgcAdjust        = MCDRV_AGCADJ_0;
++      gsGlobalInfo.sPdmInfo.bAgcOn            = MCDRV_AGC_OFF;
++      gsGlobalInfo.sPdmInfo.bPdmEdge          = MCDRV_PDMEDGE_LH;
++      gsGlobalInfo.sPdmInfo.bPdmWait          = MCDRV_PDMWAIT_10;
++      gsGlobalInfo.sPdmInfo.bPdmSel           = MCDRV_PDMSEL_L1R2;
++      gsGlobalInfo.sPdmInfo.bMono                     = MCDRV_PDM_STEREO;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("InitPdmInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    InitGpMode
++ *
++ *    Description:
++ *                    Initialize Gp mode.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   InitGpMode
++(
++      void
++)
++{
++      UINT8   bGpioIdx;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("InitGpMode");
++#endif
++
++      for(bGpioIdx = 0; bGpioIdx < GPIO_PAD_NUM; bGpioIdx++)
++      {
++              gsGlobalInfo.sGpMode.abGpDdr[bGpioIdx]          = MCDRV_GPDDR_IN;
++              gsGlobalInfo.sGpMode.abGpMode[bGpioIdx]         = MCDRV_GPMODE_RISING;
++              gsGlobalInfo.sGpMode.abGpHost[bGpioIdx]         = MCDRV_GPHOST_SCU;
++              gsGlobalInfo.sGpMode.abGpInvert[bGpioIdx]       = MCDRV_GPINV_NORMAL;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("InitGpMode", 0);
++#endif
++}
++
++/****************************************************************************
++ *    InitGpMask
++ *
++ *    Description:
++ *                    Initialize Gp mask.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   InitGpMask
++(
++      void
++)
++{
++      UINT8   bGpioIdx;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("InitGpMask");
++#endif
++
++      for(bGpioIdx = 0; bGpioIdx < GPIO_PAD_NUM; bGpioIdx++)
++      {
++              gsGlobalInfo.abGpMask[bGpioIdx]         = MCDRV_GPMASK_ON;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("InitGpMask", 0);
++#endif
++}
++
++/****************************************************************************
++ *    InitSysEq
++ *
++ *    Description:
++ *                    Initialize System EQ.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   InitSysEq
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("InitSysEq");
++#endif
++
++      gsGlobalInfo.sSysEq.bOnOff              = MCDRV_SYSEQ_ON;
++      gsGlobalInfo.sSysEq.abParam[0]  = 0x10;
++      gsGlobalInfo.sSysEq.abParam[1]  = 0xC4;
++      gsGlobalInfo.sSysEq.abParam[2]  = 0x50;
++      gsGlobalInfo.sSysEq.abParam[3]  = 0x12;
++      gsGlobalInfo.sSysEq.abParam[4]  = 0xC4;
++      gsGlobalInfo.sSysEq.abParam[5]  = 0x40;
++      gsGlobalInfo.sSysEq.abParam[6]  = 0x02;
++      gsGlobalInfo.sSysEq.abParam[7]  = 0xA9;
++      gsGlobalInfo.sSysEq.abParam[8]  = 0x60;
++      gsGlobalInfo.sSysEq.abParam[9]  = 0xED;
++      gsGlobalInfo.sSysEq.abParam[10] = 0x3B;
++      gsGlobalInfo.sSysEq.abParam[11] = 0xC0;
++      gsGlobalInfo.sSysEq.abParam[12] = 0xFC;
++      gsGlobalInfo.sSysEq.abParam[13] = 0x92;
++      gsGlobalInfo.sSysEq.abParam[14] = 0x40;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("InitSysEq", 0);
++#endif
++}
++
++/****************************************************************************
++ *    InitClockSwitch
++ *
++ *    Description:
++ *                    Initialize switch clock info.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   InitClockSwitch
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("InitClockSwitch");
++#endif
++
++      gsGlobalInfo.sClockSwitch.bClkSrc       = MCDRV_CLKSW_CLKI0;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("InitClockSwitch", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_UpdateState
++ *
++ *    Description:
++ *                    update state.
++ *    Arguments:
++ *                    eState  state
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_UpdateState
++(
++      MCDRV_STATE     eState
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_UpdateState");
++#endif
++
++      geState = eState;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_UpdateState", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_GetState
++ *
++ *    Description:
++ *                    Get state.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    current state
++ *
++ ****************************************************************************/
++MCDRV_STATE   McResCtrl_GetState
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet   = geState;
++      McDebugLog_FuncIn("McResCtrl_GetState");
++#endif
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_GetState", &sdRet);
++#endif
++
++      return geState;
++}
++
++/****************************************************************************
++ *    McResCtrl_GetRegVal
++ *
++ *    Description:
++ *                    Get register value.
++ *    Arguments:
++ *                    wRegType        register type
++ *                    wRegAddr        address
++ *    Return:
++ *                    register value
++ *
++ ****************************************************************************/
++UINT8 McResCtrl_GetRegVal
++(
++      UINT16  wRegType,
++      UINT16  wRegAddr
++)
++{
++      UINT8   bVal    = 0;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("McResCtrl_GetRegVal");
++#endif
++
++      switch(wRegType)
++      {
++      case    MCDRV_PACKET_REGTYPE_A:
++              bVal    = gsGlobalInfo.abRegValA[wRegAddr];
++              break;
++      case    MCDRV_PACKET_REGTYPE_B_BASE:
++              bVal    = gsGlobalInfo.abRegValB_BASE[wRegAddr];
++              break;
++      case    MCDRV_PACKET_REGTYPE_B_MIXER:
++              bVal    = gsGlobalInfo.abRegValB_MIXER[wRegAddr];
++              break;
++      case    MCDRV_PACKET_REGTYPE_B_AE:
++              bVal    = gsGlobalInfo.abRegValB_AE[wRegAddr];
++              break;
++      case    MCDRV_PACKET_REGTYPE_B_CDSP:
++              bVal    = gsGlobalInfo.abRegValB_CDSP[wRegAddr];
++              break;
++      case    MCDRV_PACKET_REGTYPE_B_CODEC:
++              bVal    = gsGlobalInfo.abRegValB_CODEC[wRegAddr];
++              break;
++      case    MCDRV_PACKET_REGTYPE_B_ANA:
++              bVal    = gsGlobalInfo.abRegValB_ANA[wRegAddr];
++              break;
++      default:
++              break;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = (SINT32)bVal;
++      McDebugLog_FuncOut("McResCtrl_GetRegVal", &sdRet);
++#endif
++
++      return bVal;
++}
++
++/****************************************************************************
++ *    McResCtrl_SetRegVal
++ *
++ *    Description:
++ *                    Set register value.
++ *    Arguments:
++ *                    wRegType        register type
++ *                    wRegAddr        address
++ *                    bRegVal         register value
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetRegVal
++(
++      UINT16  wRegType,
++      UINT16  wRegAddr,
++      UINT8   bRegVal
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_SetRegVal");
++#endif
++
++      switch(wRegType)
++      {
++      case    MCDRV_PACKET_REGTYPE_A:
++              gsGlobalInfo.abRegValA[wRegAddr]                = bRegVal;
++              break;
++      case    MCDRV_PACKET_REGTYPE_B_BASE:
++              gsGlobalInfo.abRegValB_BASE[wRegAddr]   = bRegVal;
++              break;
++      case    MCDRV_PACKET_REGTYPE_B_MIXER:
++              gsGlobalInfo.abRegValB_MIXER[wRegAddr]  = bRegVal;
++              break;
++      case    MCDRV_PACKET_REGTYPE_B_AE:
++              gsGlobalInfo.abRegValB_AE[wRegAddr]             = bRegVal;
++              break;
++      case    MCDRV_PACKET_REGTYPE_B_CDSP:
++              gsGlobalInfo.abRegValB_CDSP[wRegAddr]   = bRegVal;
++              break;
++      case    MCDRV_PACKET_REGTYPE_B_CODEC:
++              gsGlobalInfo.abRegValB_CODEC[wRegAddr]  = bRegVal;
++              break;
++      case    MCDRV_PACKET_REGTYPE_B_ANA:
++              gsGlobalInfo.abRegValB_ANA[wRegAddr]    = bRegVal;
++              break;
++      default:
++              break;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_SetRegVal", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_GetInitInfo
++ *
++ *    Description:
++ *                    Get Initialize information.
++ *    Arguments:
++ *                    psInitInfo      Initialize information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetInitInfo
++(
++      MCDRV_INIT_INFO*        psInitInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_GetInitInfo");
++#endif
++
++      *psInitInfo     = gsGlobalInfo.sInitInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_GetInitInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_SetClockInfo
++ *
++ *    Description:
++ *                    Set clock information.
++ *    Arguments:
++ *                    psClockInfo     clock information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetClockInfo
++(
++      const MCDRV_CLOCK_INFO* psClockInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_SetClockInfo");
++#endif
++
++
++      gsGlobalInfo.sInitInfo.bCkSel   = psClockInfo->bCkSel;
++      gsGlobalInfo.sInitInfo.bDivR0   = psClockInfo->bDivR0;
++      gsGlobalInfo.sInitInfo.bDivF0   = psClockInfo->bDivF0;
++      gsGlobalInfo.sInitInfo.bDivR1   = psClockInfo->bDivR1;
++      gsGlobalInfo.sInitInfo.bDivF1   = psClockInfo->bDivF1;
++      if(McDevProf_IsValid(eMCDRV_FUNC_RANGE) == 1)
++      {
++              gsGlobalInfo.sInitInfo.bRange0  = psClockInfo->bRange0;
++              gsGlobalInfo.sInitInfo.bRange1  = psClockInfo->bRange1;
++      }
++      if(McDevProf_IsValid(eMCDRV_FUNC_BYPASS) == 1)
++      {
++              gsGlobalInfo.sInitInfo.bBypass  = psClockInfo->bBypass;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_SetClockInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_SetPathInfo
++ *
++ *    Description:
++ *                    Set path information.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetPathInfo
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_SetPathInfo");
++#endif
++
++
++      gsGlobalInfo.sPathInfo  = gsGlobalInfo.sPathInfoVirtual;
++
++      /*      HP source on/off        */
++      SetHPSourceOnOff(psPathInfo);
++
++      /*      SP source on/off        */
++      SetSPSourceOnOff(psPathInfo);
++
++      /*      RCV source on/off       */
++      SetRCVSourceOnOff(psPathInfo);
++
++      /*      LOut1 source on/off     */
++      SetLO1SourceOnOff(psPathInfo);
++
++      /*      LOut2 source on/off     */
++      SetLO2SourceOnOff(psPathInfo);
++
++      /*      Peak source on/off      */
++      SetPMSourceOnOff(psPathInfo);
++
++      /*      DIT0 source on/off      */
++      SetDIT0SourceOnOff(psPathInfo);
++
++      /*      DIT1 source on/off      */
++      SetDIT1SourceOnOff(psPathInfo);
++
++      /*      DIT2 source on/off      */
++      SetDIT2SourceOnOff(psPathInfo);
++
++      /*      DAC source on/off       */
++      SetDACSourceOnOff(psPathInfo);
++
++      /*      AE source on/off        */
++      SetAESourceOnOff(psPathInfo);
++
++      /*      CDSP source on/off      */
++      SetCDSPSourceOnOff(psPathInfo);
++
++      /*      ADC0 source on/off      */
++      SetADC0SourceOnOff(psPathInfo);
++
++      /*      ADC1 source on/off      */
++      SetADC1SourceOnOff(psPathInfo);
++
++      /*      Mix source on/off       */
++      SetMixSourceOnOff(psPathInfo);
++
++      /*      Bias source on/off      */
++      SetBiasSourceOnOff(psPathInfo);
++
++      gsGlobalInfo.sPathInfoVirtual   = gsGlobalInfo.sPathInfo;
++
++      ValidateADC();
++      ValidateDAC();
++
++      ValidateAE();
++      ValidateMix();
++      ValidateAE();
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_SetPathInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    ValidateADC
++ *
++ *    Description:
++ *                    Validate ADC setting.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   ValidateADC
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("ValidateADC");
++#endif
++
++      if((McResCtrl_IsDstUsed(eMCDRV_DST_ADC0, eMCDRV_DST_CH0) == 0)
++      && (McResCtrl_IsDstUsed(eMCDRV_DST_ADC0, eMCDRV_DST_CH1) == 0))
++      {/*     ADC0 source all off     */
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]        &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]        &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]         &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]        &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]        |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]        |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]         |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]        |= MCDRV_SRC4_ADC0_OFF;
++      }
++
++      if(McResCtrl_IsSrcUsed(eMCDRV_SRC_ADC0) == 0)
++      {
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]               &= (UINT8)~MCDRV_SRC0_MIC1_ON;
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]               &= (UINT8)~MCDRV_SRC0_MIC2_ON;
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]               &= (UINT8)~MCDRV_SRC0_MIC3_ON;
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]    &= (UINT8)~MCDRV_SRC1_LINE1_L_ON;
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]    &= (UINT8)~MCDRV_SRC1_LINE1_M_ON;
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]               &= (UINT8)~MCDRV_SRC0_MIC1_ON;
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]               &= (UINT8)~MCDRV_SRC0_MIC2_ON;
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]               &= (UINT8)~MCDRV_SRC0_MIC3_ON;
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]    &= (UINT8)~MCDRV_SRC1_LINE1_R_ON;
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]    &= (UINT8)~MCDRV_SRC1_LINE1_M_ON;
++
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]               |= MCDRV_SRC0_MIC1_OFF;
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]               |= MCDRV_SRC0_MIC2_OFF;
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]               |= MCDRV_SRC0_MIC3_OFF;
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]    |= MCDRV_SRC1_LINE1_L_OFF;
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]    |= MCDRV_SRC1_LINE1_M_OFF;
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]               |= MCDRV_SRC0_MIC1_OFF;
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]               |= MCDRV_SRC0_MIC2_OFF;
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]               |= MCDRV_SRC0_MIC3_OFF;
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]    |= MCDRV_SRC1_LINE1_R_OFF;
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]    |= MCDRV_SRC1_LINE1_M_OFF;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("ValidateADC", 0);
++#endif
++}
++
++/****************************************************************************
++ *    ValidateDAC
++ *
++ *    Description:
++ *                    Validate DAC setting.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   ValidateDAC
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("ValidateDAC");
++#endif
++
++      if((McResCtrl_IsSrcUsed(eMCDRV_SRC_DAC_L) == 0)
++      && (McResCtrl_IsSrcUsed(eMCDRV_SRC_DAC_M) == 0)
++      && (McResCtrl_IsSrcUsed(eMCDRV_SRC_DAC_R) == 0))
++      {/*     DAC is unused   */
++              gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]         &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]        &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]        &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]        &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]        &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]          &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]         &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]         &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]        &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]        &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]        &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]        &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_AE_BLOCK]          &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]         &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]         |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]        |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]        |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]        |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]        |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]          |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]         |= MCDRV_SRC6_MIX_OFF;
++              gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]         |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]        |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]        |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]        |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]        |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_AE_BLOCK]          |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]         |= MCDRV_SRC6_MIX_OFF;
++
++              ValidateADC();
++      }
++
++      if((McResCtrl_GetDACSource(eMCDRV_DAC_MASTER) == eMCDRV_SRC_NONE)
++      && (McResCtrl_GetDACSource(eMCDRV_DAC_VOICE) == eMCDRV_SRC_NONE))
++      {/*     DAC source all off      */
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_L_ON;
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_M_ON;
++              gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_R_ON;
++              gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_L_ON;
++              gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_M_ON;
++              gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_R_ON;
++              gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_M_ON;
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_L_ON;
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_R_ON;
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_L_ON;
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_M_ON;
++              gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_R_ON;
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_L_ON;
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_M_ON;
++              gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_R_ON;
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     |= MCDRV_SRC5_DAC_L_OFF;
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     |= MCDRV_SRC5_DAC_M_OFF;
++              gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     |= MCDRV_SRC5_DAC_R_OFF;
++              gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     |= MCDRV_SRC5_DAC_L_OFF;
++              gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     |= MCDRV_SRC5_DAC_M_OFF;
++              gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     |= MCDRV_SRC5_DAC_R_OFF;
++              gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     |= MCDRV_SRC5_DAC_M_OFF;
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     |= MCDRV_SRC5_DAC_L_OFF;
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     |= MCDRV_SRC5_DAC_R_OFF;
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     |= MCDRV_SRC5_DAC_L_OFF;
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     |= MCDRV_SRC5_DAC_M_OFF;
++              gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     |= MCDRV_SRC5_DAC_R_OFF;
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     |= MCDRV_SRC5_DAC_L_OFF;
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     |= MCDRV_SRC5_DAC_M_OFF;
++              gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     |= MCDRV_SRC5_DAC_R_OFF;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("ValidateDAC", 0);
++#endif
++}
++
++/****************************************************************************
++ *    VlidateAE
++ *
++ *    Description:
++ *                    Validate AE path setting.
++ *    Arguments:
++ *                    eCh     AE path channel
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   ValidateAE
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("ValidateAE");
++#endif
++
++      if(McResCtrl_GetAESource() == eMCDRV_SRC_NONE)
++      {/*     AE source all off       */
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]  &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_AE_BLOCK]  &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]  &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]  |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_AE_BLOCK]  |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]  |= MCDRV_SRC6_AE_OFF;
++
++              ValidateDAC();
++      }
++      else if(McResCtrl_IsSrcUsed(eMCDRV_SRC_AE) == 0)
++      {
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]  &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]  &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]  |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]  |= MCDRV_SRC6_MIX_OFF;
++      }
++      else
++      {
++      }
++
++      ValidateMix();
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("ValidateAE", 0);
++#endif
++}
++
++/****************************************************************************
++ *    ValidateMix
++ *
++ *    Description:
++ *                    Validate Mix path setting.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   ValidateMix
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("ValidateMix");
++#endif
++
++      if(McResCtrl_IsDstUsed(eMCDRV_DST_MIX, eMCDRV_DST_CH0) == 0)
++      {/*     MIX source all off      */
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]         &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]         &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]          &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_OFF;
++              gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]         |= MCDRV_SRC6_MIX_OFF;
++              gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]         |= MCDRV_SRC6_MIX_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]          |= MCDRV_SRC6_MIX_OFF;
++
++              ValidateDAC();
++      }
++      else if(McResCtrl_IsSrcUsed(eMCDRV_SRC_MIX) == 0)
++      {
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]         &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]        &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]        &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]        &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]        &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]          &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]         |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]        |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]        |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]        |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]        |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]          |= MCDRV_SRC6_AE_OFF;
++      }
++      else
++      {
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("ValidateMix", 0);
++#endif
++}
++
++/****************************************************************************
++ *    SetHPSourceOnOff
++ *
++ *    Description:
++ *                    Set HP source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetHPSourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("SetHPSourceOnOff");
++#endif
++
++      if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_ON)
++      {
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC1_OFF;
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      |= MCDRV_SRC0_MIC1_ON;
++      }
++      else if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC1_ON;
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      |= MCDRV_SRC0_MIC1_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_ON)
++      {
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC2_OFF;
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      |= MCDRV_SRC0_MIC2_ON;
++      }
++      else if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC2_ON;
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      |= MCDRV_SRC0_MIC2_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_ON)
++      {
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC3_OFF;
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      |= MCDRV_SRC0_MIC3_ON;
++      }
++      else if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC3_ON;
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      |= MCDRV_SRC0_MIC3_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++      {
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_L_OFF;
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]   |= MCDRV_SRC1_LINE1_L_ON;
++      }
++      else if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_L_ON;
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]   |= MCDRV_SRC1_LINE1_L_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_M_OFF;
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]   |= MCDRV_SRC1_LINE1_M_ON;
++      }
++      else if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_M_ON;
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]   |= MCDRV_SRC1_LINE1_M_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++      {
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_L_OFF;
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     |= MCDRV_SRC5_DAC_L_ON;
++      }
++      else if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_L_ON;
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     |= MCDRV_SRC5_DAC_L_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++      {
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_M_OFF;
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     |= MCDRV_SRC5_DAC_M_ON;
++      }
++      else if((psPathInfo->asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_M_ON;
++              gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     |= MCDRV_SRC5_DAC_M_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_ON)
++      {
++              gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC1_OFF;
++              gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      |= MCDRV_SRC0_MIC1_ON;
++      }
++      else if((psPathInfo->asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC1_ON;
++              gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      |= MCDRV_SRC0_MIC1_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_ON)
++      {
++              gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC2_OFF;
++              gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      |= MCDRV_SRC0_MIC2_ON;
++      }
++      else if((psPathInfo->asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC2_ON;
++              gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      |= MCDRV_SRC0_MIC2_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_ON)
++      {
++              gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC3_OFF;
++              gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      |= MCDRV_SRC0_MIC3_ON;
++      }
++      else if((psPathInfo->asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC3_ON;
++              gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      |= MCDRV_SRC0_MIC3_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asHpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_ON)
++      {
++              gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_R_OFF;
++              gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]   |= MCDRV_SRC1_LINE1_R_ON;
++      }
++      else if((psPathInfo->asHpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_R_ON;
++              gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]   |= MCDRV_SRC1_LINE1_R_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asHpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & (MCDRV_SRC5_DAC_R_ON|MCDRV_SRC5_DAC_R_OFF)) == MCDRV_SRC5_DAC_R_ON)
++      {
++              gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_R_OFF;
++              gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     |= MCDRV_SRC5_DAC_R_ON;
++      }
++      else if((psPathInfo->asHpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & (MCDRV_SRC5_DAC_R_ON|MCDRV_SRC5_DAC_R_OFF)) == MCDRV_SRC5_DAC_R_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_R_ON;
++              gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     |= MCDRV_SRC5_DAC_R_OFF;
++      }
++      else
++      {
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("SetHPSourceOnOff", 0);
++#endif
++}
++
++/****************************************************************************
++ *    SetSPSourceOnOff
++ *
++ *    Description:
++ *                    Set SP source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetSPSourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("SetSPSourceOnOff");
++#endif
++
++      if((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++      {
++              gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_L_OFF;
++              gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]   |= MCDRV_SRC1_LINE1_L_ON;
++      }
++      else if((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_L_ON;
++              gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]   |= MCDRV_SRC1_LINE1_L_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_M_OFF;
++              gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]   |= MCDRV_SRC1_LINE1_M_ON;
++      }
++      else if((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_M_ON;
++              gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]   |= MCDRV_SRC1_LINE1_M_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++      {
++              gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_L_OFF;
++              gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     |= MCDRV_SRC5_DAC_L_ON;
++      }
++      else if((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_L_ON;
++              gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     |= MCDRV_SRC5_DAC_L_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++      {
++              gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_M_OFF;
++              gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     |= MCDRV_SRC5_DAC_M_ON;
++      }
++      else if((psPathInfo->asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_M_ON;
++              gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     |= MCDRV_SRC5_DAC_M_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_ON)
++      {
++              gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_R_OFF;
++              gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]   |= MCDRV_SRC1_LINE1_R_ON;
++      }
++      else if((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_R_ON;
++              gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]   |= MCDRV_SRC1_LINE1_R_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_M_OFF;
++              gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]   |= MCDRV_SRC1_LINE1_M_ON;
++      }
++      else if((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_M_ON;
++              gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]   |= MCDRV_SRC1_LINE1_M_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & (MCDRV_SRC5_DAC_R_ON|MCDRV_SRC5_DAC_R_OFF)) == MCDRV_SRC5_DAC_R_ON)
++      {
++              gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_R_OFF;
++              gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     |= MCDRV_SRC5_DAC_R_ON;
++      }
++      else if((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & (MCDRV_SRC5_DAC_R_ON|MCDRV_SRC5_DAC_R_OFF)) == MCDRV_SRC5_DAC_R_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_R_ON;
++              gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     |= MCDRV_SRC5_DAC_R_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++      {
++              gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_M_OFF;
++              gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     |= MCDRV_SRC5_DAC_M_ON;
++      }
++      else if((psPathInfo->asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_M_ON;
++              gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     |= MCDRV_SRC5_DAC_M_OFF;
++      }
++      else
++      {
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("SetSPSourceOnOff", 0);
++#endif
++}
++
++/****************************************************************************
++ *    SetRCVSourceOnOff
++ *
++ *    Description:
++ *                    Set RCV source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetRCVSourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("SetRCVSourceOnOff");
++#endif
++
++      if((psPathInfo->asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_ON)
++      {
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC1_OFF;
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      |= MCDRV_SRC0_MIC1_ON;
++      }
++      else if((psPathInfo->asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC1_ON;
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      |= MCDRV_SRC0_MIC1_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_ON)
++      {
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC2_OFF;
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      |= MCDRV_SRC0_MIC2_ON;
++      }
++      else if((psPathInfo->asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC2_ON;
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      |= MCDRV_SRC0_MIC2_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_ON)
++      {
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC3_OFF;
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      |= MCDRV_SRC0_MIC3_ON;
++      }
++      else if((psPathInfo->asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC3_ON;
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      |= MCDRV_SRC0_MIC3_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asRcOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_M_OFF;
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]   |= MCDRV_SRC1_LINE1_M_ON;
++      }
++      else if((psPathInfo->asRcOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_M_ON;
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]   |= MCDRV_SRC1_LINE1_M_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++      {
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_L_OFF;
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     |= MCDRV_SRC5_DAC_L_ON;
++      }
++      else if((psPathInfo->asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_L_ON;
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     |= MCDRV_SRC5_DAC_L_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & (MCDRV_SRC5_DAC_R_ON|MCDRV_SRC5_DAC_R_OFF)) == MCDRV_SRC5_DAC_R_ON)
++      {
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_R_OFF;
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     |= MCDRV_SRC5_DAC_R_ON;
++      }
++      else if((psPathInfo->asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & (MCDRV_SRC5_DAC_R_ON|MCDRV_SRC5_DAC_R_OFF)) == MCDRV_SRC5_DAC_R_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_R_ON;
++              gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     |= MCDRV_SRC5_DAC_R_OFF;
++      }
++      else
++      {
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("SetRCVSourceOnOff", 0);
++#endif
++}
++
++/****************************************************************************
++ *    SetLO1SourceOnOff
++ *
++ *    Description:
++ *                    Set LOut1 source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetLO1SourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("SetLO1SourceOnOff");
++#endif
++
++      if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_ON)
++      {
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC1_OFF;
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      |= MCDRV_SRC0_MIC1_ON;
++      }
++      else if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC1_ON;
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      |= MCDRV_SRC0_MIC1_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_ON)
++      {
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC2_OFF;
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      |= MCDRV_SRC0_MIC2_ON;
++      }
++      else if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC2_ON;
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      |= MCDRV_SRC0_MIC2_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_ON)
++      {
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC3_OFF;
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      |= MCDRV_SRC0_MIC3_ON;
++      }
++      else if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC3_ON;
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      |= MCDRV_SRC0_MIC3_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++      {
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_L_OFF;
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]   |= MCDRV_SRC1_LINE1_L_ON;
++      }
++      else if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_L_ON;
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]   |= MCDRV_SRC1_LINE1_L_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_M_OFF;
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]   |= MCDRV_SRC1_LINE1_M_ON;
++      }
++      else if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_M_ON;
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]   |= MCDRV_SRC1_LINE1_M_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++      {
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_L_OFF;
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     |= MCDRV_SRC5_DAC_L_ON;
++      }
++      else if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_L_ON;
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     |= MCDRV_SRC5_DAC_L_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++      {
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_M_OFF;
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     |= MCDRV_SRC5_DAC_M_ON;
++      }
++      else if((psPathInfo->asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_M_ON;
++              gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     |= MCDRV_SRC5_DAC_M_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asLout1[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_ON)
++      {
++              gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC1_OFF;
++              gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      |= MCDRV_SRC0_MIC1_ON;
++      }
++      else if((psPathInfo->asLout1[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC1_ON;
++              gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      |= MCDRV_SRC0_MIC1_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asLout1[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_ON)
++      {
++              gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC2_OFF;
++              gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      |= MCDRV_SRC0_MIC2_ON;
++      }
++      else if((psPathInfo->asLout1[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC2_ON;
++              gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      |= MCDRV_SRC0_MIC2_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asLout1[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_ON)
++      {
++              gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC3_OFF;
++              gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      |= MCDRV_SRC0_MIC3_ON;
++      }
++      else if((psPathInfo->asLout1[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC3_ON;
++              gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      |= MCDRV_SRC0_MIC3_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asLout1[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_ON)
++      {
++              gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_R_OFF;
++              gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]   |= MCDRV_SRC1_LINE1_R_ON;
++      }
++      else if((psPathInfo->asLout1[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_R_ON;
++              gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]   |= MCDRV_SRC1_LINE1_R_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asLout1[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & (MCDRV_SRC5_DAC_R_ON|MCDRV_SRC5_DAC_R_OFF)) == MCDRV_SRC5_DAC_R_ON)
++      {
++              gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_R_OFF;
++              gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     |= MCDRV_SRC5_DAC_R_ON;
++      }
++      else if((psPathInfo->asLout1[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & (MCDRV_SRC5_DAC_R_ON|MCDRV_SRC5_DAC_R_OFF)) == MCDRV_SRC5_DAC_R_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_R_ON;
++              gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     |= MCDRV_SRC5_DAC_R_OFF;
++      }
++      else
++      {
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("SetLO1SourceOnOff", 0);
++#endif
++}
++
++/****************************************************************************
++ *    SetLO2SourceOnOff
++ *
++ *    Description:
++ *                    Set LOut2 source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetLO2SourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("SetLO2SourceOnOff");
++#endif
++
++      if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_ON)
++      {
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC1_OFF;
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      |= MCDRV_SRC0_MIC1_ON;
++      }
++      else if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC1_ON;
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      |= MCDRV_SRC0_MIC1_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_ON)
++      {
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC2_OFF;
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      |= MCDRV_SRC0_MIC2_ON;
++      }
++      else if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC2_ON;
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      |= MCDRV_SRC0_MIC2_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_ON)
++      {
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC3_OFF;
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      |= MCDRV_SRC0_MIC3_ON;
++      }
++      else if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC3_ON;
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      |= MCDRV_SRC0_MIC3_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++      {
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_L_OFF;
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]   |= MCDRV_SRC1_LINE1_L_ON;
++      }
++      else if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_L_ON;
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]   |= MCDRV_SRC1_LINE1_L_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_M_OFF;
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]   |= MCDRV_SRC1_LINE1_M_ON;
++      }
++      else if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_M_ON;
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]   |= MCDRV_SRC1_LINE1_M_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_ON)
++      {
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_L_OFF;
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     |= MCDRV_SRC5_DAC_L_ON;
++      }
++      else if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & (MCDRV_SRC5_DAC_L_ON|MCDRV_SRC5_DAC_L_OFF)) == MCDRV_SRC5_DAC_L_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_L_ON;
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK]     |= MCDRV_SRC5_DAC_L_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_ON)
++      {
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_M_OFF;
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     |= MCDRV_SRC5_DAC_M_ON;
++      }
++      else if((psPathInfo->asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & (MCDRV_SRC5_DAC_M_ON|MCDRV_SRC5_DAC_M_OFF)) == MCDRV_SRC5_DAC_M_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_M_ON;
++              gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK]     |= MCDRV_SRC5_DAC_M_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asLout2[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_ON)
++      {
++              gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC1_OFF;
++              gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      |= MCDRV_SRC0_MIC1_ON;
++      }
++      else if((psPathInfo->asLout2[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC1_ON;
++              gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]      |= MCDRV_SRC0_MIC1_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asLout2[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_ON)
++      {
++              gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC2_OFF;
++              gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      |= MCDRV_SRC0_MIC2_ON;
++      }
++      else if((psPathInfo->asLout2[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC2_ON;
++              gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]      |= MCDRV_SRC0_MIC2_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asLout2[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_ON)
++      {
++              gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC3_OFF;
++              gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      |= MCDRV_SRC0_MIC3_ON;
++      }
++      else if((psPathInfo->asLout2[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      &= (UINT8)~MCDRV_SRC0_MIC3_ON;
++              gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]      |= MCDRV_SRC0_MIC3_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asLout2[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_ON)
++      {
++              gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_R_OFF;
++              gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]   |= MCDRV_SRC1_LINE1_R_ON;
++      }
++      else if((psPathInfo->asLout2[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]   &= (UINT8)~MCDRV_SRC1_LINE1_R_ON;
++              gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]   |= MCDRV_SRC1_LINE1_R_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asLout2[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & (MCDRV_SRC5_DAC_R_ON|MCDRV_SRC5_DAC_R_OFF)) == MCDRV_SRC5_DAC_R_ON)
++      {
++              gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_R_OFF;
++              gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     |= MCDRV_SRC5_DAC_R_ON;
++      }
++      else if((psPathInfo->asLout2[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & (MCDRV_SRC5_DAC_R_ON|MCDRV_SRC5_DAC_R_OFF)) == MCDRV_SRC5_DAC_R_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     &= (UINT8)~MCDRV_SRC5_DAC_R_ON;
++              gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK]     |= MCDRV_SRC5_DAC_R_OFF;
++      }
++      else
++      {
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("SetLO2SourceOnOff", 0);
++#endif
++}
++
++/****************************************************************************
++ *    SetPMSourceOnOff
++ *
++ *    Description:
++ *                    Set PeakMeter source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetPMSourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("SetPMSourceOnOff");
++#endif
++
++      (void)psPathInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("SetPMSourceOnOff", 0);
++#endif
++}
++
++/****************************************************************************
++ *    SetDIT0SourceOnOff
++ *
++ *    Description:
++ *                    Set DIT0 source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetDIT0SourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("SetDIT0SourceOnOff");
++#endif
++
++      if(((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      && (gsGlobalInfo.sInitInfo.bPad0Func == MCDRV_PAD_PDMCK))
++      {
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        &= (UINT8)~MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        |= MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        |= MCDRV_SRC4_PDM_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++      {
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       |= MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       |= MCDRV_SRC3_DIR0_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++      {
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       |= MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       |= MCDRV_SRC3_DIR1_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++      {
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       |= MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       |= MCDRV_SRC3_DIR2_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++      {
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         &= (UINT8)~MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         |= MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         |= MCDRV_SRC6_AE_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++      {
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_OFF;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_ON;
++      }
++      else if((psPathInfo->asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_OFF;
++      }
++      else
++      {
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("SetDIT0SourceOnOff", 0);
++#endif
++}
++
++/****************************************************************************
++ *    SetDIT1SourceOnOff
++ *
++ *    Description:
++ *                    Set DIT1 source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetDIT1SourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("SetDIT1SourceOnOff");
++#endif
++
++      if(((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      && (gsGlobalInfo.sInitInfo.bPad0Func == MCDRV_PAD_PDMCK))
++      {
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        &= (UINT8)~MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        |= MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        |= MCDRV_SRC4_PDM_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++      {
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       |= MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       |= MCDRV_SRC3_DIR0_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++      {
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       |= MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       |= MCDRV_SRC3_DIR1_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++      {
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       |= MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       |= MCDRV_SRC3_DIR2_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++      {
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         &= (UINT8)~MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         |= MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         |= MCDRV_SRC6_AE_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++      {
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_OFF;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_ON;
++      }
++      else if((psPathInfo->asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_OFF;
++      }
++      else
++      {
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("SetDIT1SourceOnOff", 0);
++#endif
++}
++
++/****************************************************************************
++ *    SetDIT2SourceOnOff
++ *
++ *    Description:
++ *                    Set DIT2 source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetDIT2SourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("SetDIT2SourceOnOff");
++#endif
++
++      if(((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      && (gsGlobalInfo.sInitInfo.bPad0Func == MCDRV_PAD_PDMCK))
++      {
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        &= (UINT8)~MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        |= MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        |= MCDRV_SRC4_PDM_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++      {
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       |= MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       |= MCDRV_SRC3_DIR0_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++      {
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       |= MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       |= MCDRV_SRC3_DIR1_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++      {
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       |= MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       |= MCDRV_SRC3_DIR2_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++      {
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         &= (UINT8)~MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         |= MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         |= MCDRV_SRC6_AE_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++      {
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]        |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]       |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]       |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]       |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]       |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]         |= MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_OFF;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_ON;
++      }
++      else if((psPathInfo->asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]        |= MCDRV_SRC6_MIX_OFF;
++      }
++      else
++      {
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("SetDIT2SourceOnOff", 0);
++#endif
++}
++
++/****************************************************************************
++ *    SetDACSourceOnOff
++ *
++ *    Description:
++ *                    Set DAC source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetDACSourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++      UINT8   bCh;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("SetDACSourceOnOff");
++#endif
++
++      for(bCh = 0; bCh < DAC_PATH_CHANNELS; bCh++)
++      {
++              if(((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++              && (gsGlobalInfo.sInitInfo.bPad0Func == MCDRV_PAD_PDMCK))
++              {
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       &= (UINT8)~MCDRV_SRC4_PDM_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       |= MCDRV_SRC4_PDM_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      |= MCDRV_SRC4_ADC0_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      |= MCDRV_SRC3_DIR0_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      |= MCDRV_SRC3_DIR1_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      |= MCDRV_SRC3_DIR2_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]        &= (UINT8)~MCDRV_SRC6_AE_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]        |= MCDRV_SRC6_AE_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       &= (UINT8)~MCDRV_SRC6_MIX_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       |= MCDRV_SRC6_MIX_OFF;
++              }
++              else if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_OFF)
++              {
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       &= (UINT8)~MCDRV_SRC4_PDM_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       |= MCDRV_SRC4_PDM_OFF;
++              }
++              else
++              {
++              }
++
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++              {
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       &= (UINT8)~MCDRV_SRC4_PDM_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       |= MCDRV_SRC4_PDM_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      &= (UINT8)~MCDRV_SRC4_ADC0_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      |= MCDRV_SRC4_ADC0_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      |= MCDRV_SRC3_DIR0_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      |= MCDRV_SRC3_DIR1_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      |= MCDRV_SRC3_DIR2_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]        &= (UINT8)~MCDRV_SRC6_AE_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]        |= MCDRV_SRC6_AE_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       &= (UINT8)~MCDRV_SRC6_MIX_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       |= MCDRV_SRC6_MIX_OFF;
++              }
++              else if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_OFF)
++              {
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      |= MCDRV_SRC4_ADC0_OFF;
++              }
++              else
++              {
++              }
++
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++              {
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       &= (UINT8)~MCDRV_SRC4_PDM_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       |= MCDRV_SRC4_PDM_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      |= MCDRV_SRC4_ADC0_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR0_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      |= MCDRV_SRC3_DIR0_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      |= MCDRV_SRC3_DIR1_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      |= MCDRV_SRC3_DIR2_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]        &= (UINT8)~MCDRV_SRC6_AE_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]        |= MCDRV_SRC6_AE_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       &= (UINT8)~MCDRV_SRC6_MIX_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       |= MCDRV_SRC6_MIX_OFF;
++              }
++              else if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_OFF)
++              {
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      |= MCDRV_SRC3_DIR0_OFF;
++              }
++              else
++              {
++              }
++
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++              {
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       &= (UINT8)~MCDRV_SRC4_PDM_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       |= MCDRV_SRC4_PDM_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      |= MCDRV_SRC4_ADC0_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      |= MCDRV_SRC3_DIR0_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR1_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      |= MCDRV_SRC3_DIR1_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      |= MCDRV_SRC3_DIR2_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]        &= (UINT8)~MCDRV_SRC6_AE_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]        |= MCDRV_SRC6_AE_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       &= (UINT8)~MCDRV_SRC6_MIX_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       |= MCDRV_SRC6_MIX_OFF;
++              }
++              else if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_OFF)
++              {
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      |= MCDRV_SRC3_DIR1_OFF;
++              }
++              else
++              {
++              }
++
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++              {
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       &= (UINT8)~MCDRV_SRC4_PDM_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       |= MCDRV_SRC4_PDM_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      |= MCDRV_SRC4_ADC0_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      |= MCDRV_SRC3_DIR0_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      |= MCDRV_SRC3_DIR1_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR2_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      |= MCDRV_SRC3_DIR2_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]        &= (UINT8)~MCDRV_SRC6_AE_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]        |= MCDRV_SRC6_AE_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       &= (UINT8)~MCDRV_SRC6_MIX_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       |= MCDRV_SRC6_MIX_OFF;
++              }
++              else if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_OFF)
++              {
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      |= MCDRV_SRC3_DIR2_OFF;
++              }
++              else
++              {
++              }
++
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++              {
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       &= (UINT8)~MCDRV_SRC4_PDM_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       |= MCDRV_SRC4_PDM_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      |= MCDRV_SRC4_ADC0_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      |= MCDRV_SRC3_DIR0_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      |= MCDRV_SRC3_DIR1_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      |= MCDRV_SRC3_DIR2_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]        &= (UINT8)~MCDRV_SRC6_AE_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]        |= MCDRV_SRC6_AE_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       &= (UINT8)~MCDRV_SRC6_MIX_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       |= MCDRV_SRC6_MIX_OFF;
++              }
++              else if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_OFF)
++              {
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]        &= (UINT8)~MCDRV_SRC6_AE_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]        |= MCDRV_SRC6_AE_OFF;
++              }
++              else
++              {
++              }
++
++              if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++              {
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       &= (UINT8)~MCDRV_SRC4_PDM_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]       |= MCDRV_SRC4_PDM_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]      |= MCDRV_SRC4_ADC0_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]      |= MCDRV_SRC3_DIR0_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]      |= MCDRV_SRC3_DIR1_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]      |= MCDRV_SRC3_DIR2_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]        &= (UINT8)~MCDRV_SRC6_AE_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK]        |= MCDRV_SRC6_AE_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       &= (UINT8)~MCDRV_SRC6_MIX_OFF;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       |= MCDRV_SRC6_MIX_ON;
++              }
++              else if((psPathInfo->asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_OFF)
++              {
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       &= (UINT8)~MCDRV_SRC6_MIX_ON;
++                      gsGlobalInfo.sPathInfo.asDac[bCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]       |= MCDRV_SRC6_MIX_OFF;
++              }
++              else
++              {
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("SetDACSourceOnOff", 0);
++#endif
++}
++
++/****************************************************************************
++ *    SetAESourceOnOff
++ *
++ *    Description:
++ *                    Set AE source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetAESourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("SetAESourceOnOff");
++#endif
++
++      if(((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      && (gsGlobalInfo.sInitInfo.bPad0Func == MCDRV_PAD_PDMCK))
++      {
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]  &= (UINT8)~MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]  |= MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]  &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]  |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]  &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]  |= MCDRV_SRC4_PDM_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]  &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]  |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] &= (UINT8)~MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] |= MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]  &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]  |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] |= MCDRV_SRC4_ADC0_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++      {
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]  &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]  |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] &= (UINT8)~MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] |= MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]  &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]  |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] |= MCDRV_SRC3_DIR0_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++      {
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]  &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]  |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] &= (UINT8)~MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] |= MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]  &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]  |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] |= MCDRV_SRC3_DIR1_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++      {
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]  &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]  |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] &= (UINT8)~MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] |= MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]  &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]  |= MCDRV_SRC6_MIX_OFF;
++      }
++      else if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] |= MCDRV_SRC3_DIR2_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_ON)
++      {
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]  &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK]  |= MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] |= MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] |= MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] |= MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] |= MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]  &= (UINT8)~MCDRV_SRC6_MIX_OFF;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]  |= MCDRV_SRC6_MIX_ON;
++      }
++      else if((psPathInfo->asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & (MCDRV_SRC6_MIX_ON|MCDRV_SRC6_MIX_OFF)) == MCDRV_SRC6_MIX_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]  &= (UINT8)~MCDRV_SRC6_MIX_ON;
++              gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK]  |= MCDRV_SRC6_MIX_OFF;
++      }
++      else
++      {
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("SetAESourceOnOff", 0);
++#endif
++}
++
++/****************************************************************************
++ *    SetCDSPSourceOnOff
++ *
++ *    Description:
++ *                    Set CDSP source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetCDSPSourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("SetCDSPSourceOnOff");
++#endif
++
++      (void)psPathInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("SetCDSPSourceOnOff", 0);
++#endif
++}
++
++/****************************************************************************
++ *    SetADC0SourceOnOff
++ *
++ *    Description:
++ *                    Set ADC0 source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetADC0SourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("SetADC0SourceOnOff");
++#endif
++
++      if((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_ON)
++      {
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]       &= (UINT8)~MCDRV_SRC0_MIC1_OFF;
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]       |= MCDRV_SRC0_MIC1_ON;
++      }
++      else if((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]       &= (UINT8)~MCDRV_SRC0_MIC1_ON;
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]       |= MCDRV_SRC0_MIC1_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_ON)
++      {
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]       &= (UINT8)~MCDRV_SRC0_MIC2_OFF;
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]       |= MCDRV_SRC0_MIC2_ON;
++      }
++      else if((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]       &= (UINT8)~MCDRV_SRC0_MIC2_ON;
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]       |= MCDRV_SRC0_MIC2_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_ON)
++      {
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]       &= (UINT8)~MCDRV_SRC0_MIC3_OFF;
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]       |= MCDRV_SRC0_MIC3_ON;
++      }
++      else if((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]       &= (UINT8)~MCDRV_SRC0_MIC3_ON;
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]       |= MCDRV_SRC0_MIC3_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_ON)
++      {
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]    &= (UINT8)~MCDRV_SRC1_LINE1_L_OFF;
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]    |= MCDRV_SRC1_LINE1_L_ON;
++      }
++      else if((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & (MCDRV_SRC1_LINE1_L_ON|MCDRV_SRC1_LINE1_L_OFF)) == MCDRV_SRC1_LINE1_L_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]    &= (UINT8)~MCDRV_SRC1_LINE1_L_ON;
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK]    |= MCDRV_SRC1_LINE1_L_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]    &= (UINT8)~MCDRV_SRC1_LINE1_M_OFF;
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]    |= MCDRV_SRC1_LINE1_M_ON;
++      }
++      else if((psPathInfo->asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]    &= (UINT8)~MCDRV_SRC1_LINE1_M_ON;
++              gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]    |= MCDRV_SRC1_LINE1_M_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_ON)
++      {
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]       &= (UINT8)~MCDRV_SRC0_MIC1_OFF;
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]       |= MCDRV_SRC0_MIC1_ON;
++      }
++      else if((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]       &= (UINT8)~MCDRV_SRC0_MIC1_ON;
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]       |= MCDRV_SRC0_MIC1_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_ON)
++      {
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]       &= (UINT8)~MCDRV_SRC0_MIC2_OFF;
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]       |= MCDRV_SRC0_MIC2_ON;
++      }
++      else if((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]       &= (UINT8)~MCDRV_SRC0_MIC2_ON;
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]       |= MCDRV_SRC0_MIC2_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_ON)
++      {
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]       &= (UINT8)~MCDRV_SRC0_MIC3_OFF;
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]       |= MCDRV_SRC0_MIC3_ON;
++      }
++      else if((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]       &= (UINT8)~MCDRV_SRC0_MIC3_ON;
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]       |= MCDRV_SRC0_MIC3_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_ON)
++      {
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]    &= (UINT8)~MCDRV_SRC1_LINE1_R_OFF;
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]    |= MCDRV_SRC1_LINE1_R_ON;
++      }
++      else if((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & (MCDRV_SRC1_LINE1_R_ON|MCDRV_SRC1_LINE1_R_OFF)) == MCDRV_SRC1_LINE1_R_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]    &= (UINT8)~MCDRV_SRC1_LINE1_R_ON;
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK]    |= MCDRV_SRC1_LINE1_R_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_ON)
++      {
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]    &= (UINT8)~MCDRV_SRC1_LINE1_M_OFF;
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]    |= MCDRV_SRC1_LINE1_M_ON;
++      }
++      else if((psPathInfo->asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & (MCDRV_SRC1_LINE1_M_ON|MCDRV_SRC1_LINE1_M_OFF)) == MCDRV_SRC1_LINE1_M_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]    &= (UINT8)~MCDRV_SRC1_LINE1_M_ON;
++              gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK]    |= MCDRV_SRC1_LINE1_M_OFF;
++      }
++      else
++      {
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("SetADC0SourceOnOff", 0);
++#endif
++}
++
++/****************************************************************************
++ *    SetADC1SourceOnOff
++ *
++ *    Description:
++ *                    Set ADC1 source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetADC1SourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("SetADC1SourceOnOff");
++#endif
++
++      (void)psPathInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("SetADC1SourceOnOff", 0);
++#endif
++}
++
++/****************************************************************************
++ *    SetMixSourceOnOff
++ *
++ *    Description:
++ *                    Set Mix source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetMixSourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("SetMixSourceOnOff");
++#endif
++
++      if(((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_ON)
++      && (gsGlobalInfo.sInitInfo.bPad0Func == MCDRV_PAD_PDMCK))
++      {
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] &= (UINT8)~MCDRV_SRC4_PDM_OFF;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] |= MCDRV_SRC4_PDM_ON;
++      }
++      else if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & (MCDRV_SRC4_PDM_ON|MCDRV_SRC4_PDM_OFF)) == MCDRV_SRC4_PDM_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] &= (UINT8)~MCDRV_SRC4_PDM_ON;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] |= MCDRV_SRC4_PDM_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_ON)
++      {
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]        &= (UINT8)~MCDRV_SRC4_ADC0_OFF;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]        |= MCDRV_SRC4_ADC0_ON;
++      }
++      else if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & (MCDRV_SRC4_ADC0_ON|MCDRV_SRC4_ADC0_OFF)) == MCDRV_SRC4_ADC0_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]        &= (UINT8)~MCDRV_SRC4_ADC0_ON;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK]        |= MCDRV_SRC4_ADC0_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_ON)
++      {
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]        &= (UINT8)~MCDRV_SRC3_DIR0_OFF;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]        |= MCDRV_SRC3_DIR0_ON;
++      }
++      else if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & (MCDRV_SRC3_DIR0_ON|MCDRV_SRC3_DIR0_OFF)) == MCDRV_SRC3_DIR0_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]        &= (UINT8)~MCDRV_SRC3_DIR0_ON;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK]        |= MCDRV_SRC3_DIR0_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_ON)
++      {
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]        &= (UINT8)~MCDRV_SRC3_DIR1_OFF;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]        |= MCDRV_SRC3_DIR1_ON;
++      }
++      else if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & (MCDRV_SRC3_DIR1_ON|MCDRV_SRC3_DIR1_OFF)) == MCDRV_SRC3_DIR1_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]        &= (UINT8)~MCDRV_SRC3_DIR1_ON;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK]        |= MCDRV_SRC3_DIR1_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_ON)
++      {
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]        &= (UINT8)~MCDRV_SRC3_DIR2_OFF;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]        |= MCDRV_SRC3_DIR2_ON;
++      }
++      else if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & (MCDRV_SRC3_DIR2_ON|MCDRV_SRC3_DIR2_OFF)) == MCDRV_SRC3_DIR2_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]        &= (UINT8)~MCDRV_SRC3_DIR2_ON;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK]        |= MCDRV_SRC3_DIR2_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_ON)
++      {
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]  &= (UINT8)~MCDRV_SRC6_AE_OFF;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]  |= MCDRV_SRC6_AE_ON;
++      }
++      else if((psPathInfo->asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & (MCDRV_SRC6_AE_ON|MCDRV_SRC6_AE_OFF)) == MCDRV_SRC6_AE_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]  &= (UINT8)~MCDRV_SRC6_AE_ON;
++              gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK]  |= MCDRV_SRC6_AE_OFF;
++      }
++      else
++      {
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("SetMixSourceOnOff", 0);
++#endif
++}
++
++/****************************************************************************
++ *    SetExtBiasOnOff
++ *
++ *    Description:
++ *                    Set Bias source On/Off.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetBiasSourceOnOff
++(
++      const MCDRV_PATH_INFO*  psPathInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("SetBiasSourceOnOff");
++#endif
++
++      if((psPathInfo->asBias[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_ON)
++      {
++              gsGlobalInfo.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]       &= (UINT8)~MCDRV_SRC0_MIC1_OFF;
++              gsGlobalInfo.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]       |= MCDRV_SRC0_MIC1_ON;
++      }
++      else if((psPathInfo->asBias[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & (MCDRV_SRC0_MIC1_ON|MCDRV_SRC0_MIC1_OFF)) == MCDRV_SRC0_MIC1_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]       &= (UINT8)~MCDRV_SRC0_MIC1_ON;
++              gsGlobalInfo.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK]       |= MCDRV_SRC0_MIC1_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asBias[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_ON)
++      {
++              gsGlobalInfo.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]       &= (UINT8)~MCDRV_SRC0_MIC2_OFF;
++              gsGlobalInfo.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]       |= MCDRV_SRC0_MIC2_ON;
++      }
++      else if((psPathInfo->asBias[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & (MCDRV_SRC0_MIC2_ON|MCDRV_SRC0_MIC2_OFF)) == MCDRV_SRC0_MIC2_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]       &= (UINT8)~MCDRV_SRC0_MIC2_ON;
++              gsGlobalInfo.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK]       |= MCDRV_SRC0_MIC2_OFF;
++      }
++      else
++      {
++      }
++
++      if((psPathInfo->asBias[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_ON)
++      {
++              gsGlobalInfo.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]       &= (UINT8)~MCDRV_SRC0_MIC3_OFF;
++              gsGlobalInfo.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]       |= MCDRV_SRC0_MIC3_ON;
++      }
++      else if((psPathInfo->asBias[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & (MCDRV_SRC0_MIC3_ON|MCDRV_SRC0_MIC3_OFF)) == MCDRV_SRC0_MIC3_OFF)
++      {
++              gsGlobalInfo.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]       &= (UINT8)~MCDRV_SRC0_MIC3_ON;
++              gsGlobalInfo.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK]       |= MCDRV_SRC0_MIC3_OFF;
++      }
++      else
++      {
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("SetBiasSourceOnOff", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_GetPathInfo
++ *
++ *    Description:
++ *                    Get path information.
++ *    Arguments:
++ *                    psPathInfo      path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetPathInfo
++(
++      MCDRV_PATH_INFO*        psPathInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_GetPathInfo");
++#endif
++
++      *psPathInfo     = gsGlobalInfo.sPathInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_GetPathInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_GetPathInfoVirtual
++ *
++ *    Description:
++ *                    Get virtaul path information.
++ *    Arguments:
++ *                    psPathInfo      virtaul path information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetPathInfoVirtual
++(
++      MCDRV_PATH_INFO*        psPathInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_GetPathInfoVirtual");
++#endif
++
++      *psPathInfo     = gsGlobalInfo.sPathInfoVirtual;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_GetPathInfoVirtual", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_SetDioInfo
++ *
++ *    Description:
++ *                    Set digital io information.
++ *    Arguments:
++ *                    psDioInfo       digital io information
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetDioInfo
++(
++      const MCDRV_DIO_INFO*   psDioInfo,
++      UINT32  dUpdateInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_SetDioInfo");
++#endif
++
++
++      if((dUpdateInfo & MCDRV_DIO0_COM_UPDATE_FLAG) != 0UL)
++      {
++              SetDIOCommon(psDioInfo, 0);
++      }
++      if((dUpdateInfo & MCDRV_DIO1_COM_UPDATE_FLAG) != 0UL)
++      {
++              SetDIOCommon(psDioInfo, 1);
++      }
++      if((dUpdateInfo & MCDRV_DIO2_COM_UPDATE_FLAG) != 0UL)
++      {
++              SetDIOCommon(psDioInfo, 2);
++      }
++
++      if((dUpdateInfo & MCDRV_DIO0_DIR_UPDATE_FLAG) != 0UL)
++      {
++              SetDIODIR(psDioInfo, 0);
++      }
++      if((dUpdateInfo & MCDRV_DIO1_DIR_UPDATE_FLAG) != 0UL)
++      {
++              SetDIODIR(psDioInfo, 1);
++      }
++      if((dUpdateInfo & MCDRV_DIO2_DIR_UPDATE_FLAG) != 0UL)
++      {
++              SetDIODIR(psDioInfo, 2);
++      }
++
++      if((dUpdateInfo & MCDRV_DIO0_DIT_UPDATE_FLAG) != 0UL)
++      {
++              SetDIODIT(psDioInfo, 0);
++      }
++      if((dUpdateInfo & MCDRV_DIO1_DIT_UPDATE_FLAG) != 0UL)
++      {
++              SetDIODIT(psDioInfo, 1);
++      }
++      if((dUpdateInfo & MCDRV_DIO2_DIT_UPDATE_FLAG) != 0UL)
++      {
++              SetDIODIT(psDioInfo, 2);
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_SetDioInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    SetDIOCommon
++ *
++ *    Description:
++ *                    Set digital io common information.
++ *    Arguments:
++ *                    psDioInfo       digital io information
++ *                    bPort           port number
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetDIOCommon
++(
++      const MCDRV_DIO_INFO*   psDioInfo,
++      UINT8   bPort
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("SetDIOCommon");
++#endif
++
++      if((psDioInfo->asPortInfo[bPort].sDioCommon.bMasterSlave == MCDRV_DIO_SLAVE)
++      || (psDioInfo->asPortInfo[bPort].sDioCommon.bMasterSlave == MCDRV_DIO_MASTER))
++      {
++              gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDioCommon.bMasterSlave = psDioInfo->asPortInfo[bPort].sDioCommon.bMasterSlave;
++      }
++      if((psDioInfo->asPortInfo[bPort].sDioCommon.bAutoFs == MCDRV_AUTOFS_OFF)
++      || (psDioInfo->asPortInfo[bPort].sDioCommon.bAutoFs == MCDRV_AUTOFS_ON))
++      {
++              gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDioCommon.bAutoFs      = psDioInfo->asPortInfo[bPort].sDioCommon.bAutoFs;
++      }
++      if((psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_48000)
++      || (psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_44100)
++      || (psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_32000)
++      || (psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_24000)
++      || (psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_22050)
++      || (psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_16000)
++      || (psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_12000)
++      || (psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_11025)
++      || (psDioInfo->asPortInfo[bPort].sDioCommon.bFs == MCDRV_FS_8000))
++      {
++              gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDioCommon.bFs  = psDioInfo->asPortInfo[bPort].sDioCommon.bFs;
++      }
++      if((psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs == MCDRV_BCKFS_64)
++      || (psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs == MCDRV_BCKFS_48)
++      || (psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs == MCDRV_BCKFS_32)
++      || (psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs == MCDRV_BCKFS_512)
++      || (psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs == MCDRV_BCKFS_256)
++      || (psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs == MCDRV_BCKFS_128)
++      || (psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs == MCDRV_BCKFS_16))
++      {
++              gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDioCommon.bBckFs       = psDioInfo->asPortInfo[bPort].sDioCommon.bBckFs;
++      }
++      if((psDioInfo->asPortInfo[bPort].sDioCommon.bInterface == MCDRV_DIO_DA)
++      || (psDioInfo->asPortInfo[bPort].sDioCommon.bInterface == MCDRV_DIO_PCM))
++      {
++              gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDioCommon.bInterface   = psDioInfo->asPortInfo[bPort].sDioCommon.bInterface;
++      }
++      if((psDioInfo->asPortInfo[bPort].sDioCommon.bBckInvert == MCDRV_BCLK_NORMAL)
++      || (psDioInfo->asPortInfo[bPort].sDioCommon.bBckInvert == MCDRV_BCLK_INVERT))
++      {
++              gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDioCommon.bBckInvert   = psDioInfo->asPortInfo[bPort].sDioCommon.bBckInvert;
++      }
++      if(psDioInfo->asPortInfo[bPort].sDioCommon.bInterface == MCDRV_DIO_PCM)
++      {
++              if((psDioInfo->asPortInfo[bPort].sDioCommon.bPcmHizTim == MCDRV_PCMHIZTIM_FALLING)
++              || (psDioInfo->asPortInfo[bPort].sDioCommon.bPcmHizTim == MCDRV_PCMHIZTIM_RISING))
++              {
++                      gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDioCommon.bPcmHizTim   = psDioInfo->asPortInfo[bPort].sDioCommon.bPcmHizTim;
++              }
++              if((psDioInfo->asPortInfo[bPort].sDioCommon.bPcmClkDown == MCDRV_PCM_CLKDOWN_OFF)
++              || (psDioInfo->asPortInfo[bPort].sDioCommon.bPcmClkDown == MCDRV_PCM_CLKDOWN_HALF))
++              {
++                      gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDioCommon.bPcmClkDown  = psDioInfo->asPortInfo[bPort].sDioCommon.bPcmClkDown;
++              }
++              if((psDioInfo->asPortInfo[bPort].sDioCommon.bPcmFrame == MCDRV_PCM_SHORTFRAME)
++              || (psDioInfo->asPortInfo[bPort].sDioCommon.bPcmFrame == MCDRV_PCM_LONGFRAME))
++              {
++                      gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDioCommon.bPcmFrame    = psDioInfo->asPortInfo[bPort].sDioCommon.bPcmFrame;
++              }
++              if(psDioInfo->asPortInfo[bPort].sDioCommon.bPcmHighPeriod <= 31)
++              {
++                      gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDioCommon.bPcmHighPeriod       = psDioInfo->asPortInfo[bPort].sDioCommon.bPcmHighPeriod;
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("SetDIOCommon", 0);
++#endif
++}
++
++/****************************************************************************
++ *    SetDIODIR
++ *
++ *    Description:
++ *                    Set digital io dir information.
++ *    Arguments:
++ *                    psDioInfo       digital io information
++ *                    bPort           port number
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetDIODIR
++(
++      const MCDRV_DIO_INFO*   psDioInfo,
++      UINT8   bPort
++)
++{
++      UINT8   bDIOCh;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("SetDIODIR");
++#endif
++
++      gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDir.wSrcRate   = psDioInfo->asPortInfo[bPort].sDir.wSrcRate;
++      if(gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDioCommon.bInterface == MCDRV_DIO_DA)
++      {
++              if((psDioInfo->asPortInfo[bPort].sDir.sDaFormat.bBitSel == MCDRV_BITSEL_16)
++              || (psDioInfo->asPortInfo[bPort].sDir.sDaFormat.bBitSel == MCDRV_BITSEL_20)
++              || (psDioInfo->asPortInfo[bPort].sDir.sDaFormat.bBitSel == MCDRV_BITSEL_24))
++              {
++                      gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDir.sDaFormat.bBitSel  = psDioInfo->asPortInfo[bPort].sDir.sDaFormat.bBitSel;
++              }
++              if((psDioInfo->asPortInfo[bPort].sDir.sDaFormat.bMode == MCDRV_DAMODE_HEADALIGN)
++              || (psDioInfo->asPortInfo[bPort].sDir.sDaFormat.bMode == MCDRV_DAMODE_I2S)
++              || (psDioInfo->asPortInfo[bPort].sDir.sDaFormat.bMode == MCDRV_DAMODE_TAILALIGN))
++              {
++                      gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDir.sDaFormat.bMode    = psDioInfo->asPortInfo[bPort].sDir.sDaFormat.bMode;
++              }
++      }
++      else if(gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDioCommon.bInterface == MCDRV_DIO_PCM)
++      {
++              if((psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bMono == MCDRV_PCM_STEREO)
++              || (psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bMono == MCDRV_PCM_MONO))
++              {
++                      gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDir.sPcmFormat.bMono   = psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bMono;
++              }
++              if((psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bOrder == MCDRV_PCM_MSB_FIRST)
++              || (psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bOrder == MCDRV_PCM_LSB_FIRST)
++              || (psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bOrder == MCDRV_PCM_MSB_FIRST_SIGN)
++              || (psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bOrder == MCDRV_PCM_LSB_FIRST_SIGN)
++              || (psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bOrder == MCDRV_PCM_MSB_FIRST_ZERO)
++              || (psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bOrder == MCDRV_PCM_LSB_FIRST_ZERO))
++              {
++                      gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDir.sPcmFormat.bOrder  = psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bOrder;
++              }
++              if((psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bLaw == MCDRV_PCM_LINEAR)
++              || (psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bLaw == MCDRV_PCM_ALAW)
++              || (psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bLaw == MCDRV_PCM_MULAW))
++              {
++                      gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDir.sPcmFormat.bLaw    = psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bLaw;
++              }
++              if((psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_8)
++              || (psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_13)
++              || (psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_14)
++              || (psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_16))
++              {
++                      gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDir.sPcmFormat.bBitSel = psDioInfo->asPortInfo[bPort].sDir.sPcmFormat.bBitSel;
++              }
++      }
++      else
++      {
++      }
++
++      for(bDIOCh = 0; bDIOCh < DIO_CHANNELS; bDIOCh++)
++      {
++              if(psDioInfo->asPortInfo[bPort].sDir.abSlot[bDIOCh] < 2)
++              {
++                      gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDir.abSlot[bDIOCh]     = psDioInfo->asPortInfo[bPort].sDir.abSlot[bDIOCh];
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("SetDIODIR", 0);
++#endif
++}
++
++/****************************************************************************
++ *    SetDIODIT
++ *
++ *    Description:
++ *                    Set digital io dit information.
++ *    Arguments:
++ *                    psDioInfo       digital io information
++ *                    bPort           port number
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++static void   SetDIODIT
++(
++      const MCDRV_DIO_INFO*   psDioInfo,
++      UINT8   bPort
++)
++{
++      UINT8   bDIOCh;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("SetDIODIT");
++#endif
++
++      gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDit.wSrcRate   = psDioInfo->asPortInfo[bPort].sDit.wSrcRate;
++      if(gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDioCommon.bInterface == MCDRV_DIO_DA)
++      {
++              if((psDioInfo->asPortInfo[bPort].sDit.sDaFormat.bBitSel == MCDRV_BITSEL_16)
++              || (psDioInfo->asPortInfo[bPort].sDit.sDaFormat.bBitSel == MCDRV_BITSEL_20)
++              || (psDioInfo->asPortInfo[bPort].sDit.sDaFormat.bBitSel == MCDRV_BITSEL_24))
++              {
++                      gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDit.sDaFormat.bBitSel  = psDioInfo->asPortInfo[bPort].sDit.sDaFormat.bBitSel;
++              }
++              if((psDioInfo->asPortInfo[bPort].sDit.sDaFormat.bMode == MCDRV_DAMODE_HEADALIGN)
++              || (psDioInfo->asPortInfo[bPort].sDit.sDaFormat.bMode == MCDRV_DAMODE_I2S)
++              || (psDioInfo->asPortInfo[bPort].sDit.sDaFormat.bMode == MCDRV_DAMODE_TAILALIGN))
++              {
++                      gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDit.sDaFormat.bMode    = psDioInfo->asPortInfo[bPort].sDit.sDaFormat.bMode;
++              }
++      }
++      else if(gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDioCommon.bInterface == MCDRV_DIO_PCM)
++      {
++              if((psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bMono == MCDRV_PCM_STEREO)
++              || (psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bMono == MCDRV_PCM_MONO))
++              {
++                      gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDit.sPcmFormat.bMono   = psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bMono;
++              }
++              if((psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bOrder == MCDRV_PCM_MSB_FIRST)
++              || (psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bOrder == MCDRV_PCM_LSB_FIRST)
++              || (psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bOrder == MCDRV_PCM_MSB_FIRST_SIGN)
++              || (psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bOrder == MCDRV_PCM_LSB_FIRST_SIGN)
++              || (psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bOrder == MCDRV_PCM_MSB_FIRST_ZERO)
++              || (psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bOrder == MCDRV_PCM_LSB_FIRST_ZERO))
++              {
++                      gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDit.sPcmFormat.bOrder  = psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bOrder;
++              }
++              if((psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bLaw == MCDRV_PCM_LINEAR)
++              || (psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bLaw == MCDRV_PCM_ALAW)
++              || (psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bLaw == MCDRV_PCM_MULAW))
++              {
++                      gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDit.sPcmFormat.bLaw    = psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bLaw;
++              }
++              if((psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_8)
++              || (psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_13)
++              || (psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_14)
++              || (psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bBitSel == MCDRV_PCM_BITSEL_16))
++              {
++                      gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDit.sPcmFormat.bBitSel = psDioInfo->asPortInfo[bPort].sDit.sPcmFormat.bBitSel;
++              }
++      }
++      else
++      {
++      }
++
++      for(bDIOCh = 0; bDIOCh < DIO_CHANNELS; bDIOCh++)
++      {
++              if(psDioInfo->asPortInfo[bPort].sDit.abSlot[bDIOCh] < 2)
++              {
++                      gsGlobalInfo.sDioInfo.asPortInfo[bPort].sDit.abSlot[bDIOCh]     = psDioInfo->asPortInfo[bPort].sDit.abSlot[bDIOCh];
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("SetDIODIT", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_GetDioInfo
++ *
++ *    Description:
++ *                    Get digital io information.
++ *    Arguments:
++ *                    psDioInfo       digital io information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetDioInfo
++(
++      MCDRV_DIO_INFO* psDioInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_GetDioInfo");
++#endif
++
++      *psDioInfo      = gsGlobalInfo.sDioInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_GetDioInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_SetVolInfo
++ *
++ *    Description:
++ *                    Update volume.
++ *    Arguments:
++ *                    psVolInfo               volume setting
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetVolInfo
++(
++      const MCDRV_VOL_INFO*   psVolInfo
++)
++{
++      UINT8   bCh;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_SetVolInfo");
++#endif
++
++
++      for(bCh = 0; bCh < AD0_VOL_CHANNELS; bCh++)
++      {
++              if(((UINT16)psVolInfo->aswD_Ad0[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswD_Ad0[bCh]     = (SINT16)((UINT16)psVolInfo->aswD_Ad0[bCh] & 0xFFFE);
++              }
++              if(((UINT16)psVolInfo->aswD_Ad0Att[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswD_Ad0Att[bCh]  = (SINT16)((UINT16)psVolInfo->aswD_Ad0Att[bCh] & 0xFFFE);
++              }
++              if(((UINT16)psVolInfo->aswA_Ad0[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswA_Ad0[bCh]     = (SINT16)((UINT16)psVolInfo->aswA_Ad0[bCh] & 0xFFFE);
++              }
++      }
++      for(bCh = 0; bCh < AD1_VOL_CHANNELS; bCh++)
++      {
++              if(((UINT16)psVolInfo->aswD_Ad1[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswD_Ad1[bCh]     = (SINT16)((UINT16)psVolInfo->aswD_Ad1[bCh] & 0xFFFE);
++              }
++              if(((UINT16)psVolInfo->aswD_Ad1Att[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswD_Ad1Att[bCh]  = (SINT16)((UINT16)psVolInfo->aswD_Ad1Att[bCh] & 0xFFFE);
++              }
++              if(((UINT16)psVolInfo->aswA_Ad1[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswA_Ad1[bCh]     = (SINT16)((UINT16)psVolInfo->aswA_Ad1[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < AENG6_VOL_CHANNELS; bCh++)
++      {
++              if(((UINT16)psVolInfo->aswD_Aeng6[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswD_Aeng6[bCh]   = (SINT16)((UINT16)psVolInfo->aswD_Aeng6[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < PDM_VOL_CHANNELS; bCh++)
++      {
++              if(((UINT16)psVolInfo->aswD_Pdm[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswD_Pdm[bCh]     = (SINT16)((UINT16)psVolInfo->aswD_Pdm[bCh] & 0xFFFE);
++              }
++              if(((UINT16)psVolInfo->aswD_SideTone[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswD_SideTone[bCh]        = (SINT16)((UINT16)psVolInfo->aswD_SideTone[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < DTMF_VOL_CHANNELS; bCh++)
++      {
++              if(((UINT16)psVolInfo->aswD_Dtmfb[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswD_Dtmfb[bCh]   = (SINT16)((UINT16)psVolInfo->aswD_Dtmfb[bCh] & 0xFFFE);
++              }
++              if(((UINT16)psVolInfo->aswD_DtmfAtt[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswD_DtmfAtt[bCh] = (SINT16)((UINT16)psVolInfo->aswD_DtmfAtt[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < DIO0_VOL_CHANNELS; bCh++)
++      {
++              if(((UINT16)psVolInfo->aswD_Dir0[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswD_Dir0[bCh]    = (SINT16)((UINT16)psVolInfo->aswD_Dir0[bCh] & 0xFFFE);
++              }
++              if(((UINT16)psVolInfo->aswD_Dir0Att[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswD_Dir0Att[bCh] = (SINT16)((UINT16)psVolInfo->aswD_Dir0Att[bCh] & 0xFFFE);
++              }
++              if(((UINT16)psVolInfo->aswD_Dit0[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswD_Dit0[bCh]    = (SINT16)((UINT16)psVolInfo->aswD_Dit0[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < DIO1_VOL_CHANNELS; bCh++)
++      {
++              if(((UINT16)psVolInfo->aswD_Dir1[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswD_Dir1[bCh]    = (SINT16)((UINT16)psVolInfo->aswD_Dir1[bCh] & 0xFFFE);
++              }
++              if(((UINT16)psVolInfo->aswD_Dir1Att[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswD_Dir1Att[bCh] = (SINT16)((UINT16)psVolInfo->aswD_Dir1Att[bCh] & 0xFFFE);
++              }
++              if(((UINT16)psVolInfo->aswD_Dit1[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswD_Dit1[bCh]    = (SINT16)((UINT16)psVolInfo->aswD_Dit1[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < DIO2_VOL_CHANNELS; bCh++)
++      {
++              if(((UINT16)psVolInfo->aswD_Dir2[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswD_Dir2[bCh]    = (SINT16)((UINT16)psVolInfo->aswD_Dir2[bCh] & 0xFFFE);
++              }
++              if(((UINT16)psVolInfo->aswD_Dir2Att[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswD_Dir2Att[bCh] = (SINT16)((UINT16)psVolInfo->aswD_Dir2Att[bCh] & 0xFFFE);
++              }
++              if(((UINT16)psVolInfo->aswD_Dit2[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswD_Dit2[bCh]    = (SINT16)((UINT16)psVolInfo->aswD_Dit2[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < DAC_VOL_CHANNELS; bCh++)
++      {
++              if(((UINT16)psVolInfo->aswD_DacMaster[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswD_DacMaster[bCh]       = (SINT16)((UINT16)psVolInfo->aswD_DacMaster[bCh] & 0xFFFE);
++              }
++              if(((UINT16)psVolInfo->aswD_DacVoice[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswD_DacVoice[bCh]        = (SINT16)((UINT16)psVolInfo->aswD_DacVoice[bCh] & 0xFFFE);
++              }
++              if(((UINT16)psVolInfo->aswD_DacAtt[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswD_DacAtt[bCh]  = (SINT16)((UINT16)psVolInfo->aswD_DacAtt[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < LIN1_VOL_CHANNELS; bCh++)
++      {
++              if(((UINT16)psVolInfo->aswA_Lin1[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswA_Lin1[bCh]    = (SINT16)((UINT16)psVolInfo->aswA_Lin1[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < LIN2_VOL_CHANNELS; bCh++)
++      {
++              if(((UINT16)psVolInfo->aswA_Lin2[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswA_Lin2[bCh]    = (SINT16)((UINT16)psVolInfo->aswA_Lin2[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < MIC1_VOL_CHANNELS; bCh++)
++      {
++              if(((UINT16)psVolInfo->aswA_Mic1[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswA_Mic1[bCh]    = (SINT16)((UINT16)psVolInfo->aswA_Mic1[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < MIC2_VOL_CHANNELS; bCh++)
++      {
++              if(((UINT16)psVolInfo->aswA_Mic2[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswA_Mic2[bCh]    = (SINT16)((UINT16)psVolInfo->aswA_Mic2[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < MIC3_VOL_CHANNELS; bCh++)
++      {
++              if(((UINT16)psVolInfo->aswA_Mic3[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswA_Mic3[bCh]    = (SINT16)((UINT16)psVolInfo->aswA_Mic3[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < HP_VOL_CHANNELS; bCh++)
++      {
++              if(((UINT16)psVolInfo->aswA_Hp[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswA_Hp[bCh]      = (SINT16)((UINT16)psVolInfo->aswA_Hp[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < SP_VOL_CHANNELS; bCh++)
++      {
++              if(((UINT16)psVolInfo->aswA_Sp[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswA_Sp[bCh]      = (SINT16)((UINT16)psVolInfo->aswA_Sp[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < RC_VOL_CHANNELS; bCh++)
++      {
++              if(((UINT16)psVolInfo->aswA_Rc[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswA_Rc[bCh]      = (SINT16)((UINT16)psVolInfo->aswA_Rc[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < LOUT1_VOL_CHANNELS; bCh++)
++      {
++              if(((UINT16)psVolInfo->aswA_Lout1[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswA_Lout1[bCh]   = (SINT16)((UINT16)psVolInfo->aswA_Lout1[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < LOUT2_VOL_CHANNELS; bCh++)
++      {
++              if(((UINT16)psVolInfo->aswA_Lout2[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswA_Lout2[bCh]   = (SINT16)((UINT16)psVolInfo->aswA_Lout2[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < MIC1_VOL_CHANNELS; bCh++)
++      {
++              if(((UINT16)psVolInfo->aswA_Mic1Gain[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswA_Mic1Gain[bCh]        = (SINT16)((UINT16)psVolInfo->aswA_Mic1Gain[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < MIC2_VOL_CHANNELS; bCh++)
++      {
++              if(((UINT16)psVolInfo->aswA_Mic2Gain[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswA_Mic2Gain[bCh]        = (SINT16)((UINT16)psVolInfo->aswA_Mic2Gain[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < MIC3_VOL_CHANNELS; bCh++)
++      {
++              if(((UINT16)psVolInfo->aswA_Mic3Gain[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswA_Mic3Gain[bCh]        = (SINT16)((UINT16)psVolInfo->aswA_Mic3Gain[bCh] & 0xFFFE);
++              }
++      }
++
++      for(bCh = 0; bCh < HPGAIN_VOL_CHANNELS; bCh++)
++      {
++              if(((UINT16)psVolInfo->aswA_HpGain[bCh] & 0x01) != 0)
++              {
++                      gsGlobalInfo.sVolInfo.aswA_HpGain[bCh]  = (SINT16)((UINT16)psVolInfo->aswA_HpGain[bCh] & 0xFFFE);
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_SetVolInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_GetVolInfo
++ *
++ *    Description:
++ *                    Get volume setting.
++ *    Arguments:
++ *                    psVolInfo               volume setting
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetVolInfo
++(
++      MCDRV_VOL_INFO* psVolInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_GetVolInfo");
++#endif
++
++      *psVolInfo      = gsGlobalInfo.sVolInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_GetVolInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_SetDacInfo
++ *
++ *    Description:
++ *                    Set DAC information.
++ *    Arguments:
++ *                    psDacInfo       DAC information
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetDacInfo
++(
++      const MCDRV_DAC_INFO*   psDacInfo,
++      UINT32  dUpdateInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_SetDacInfo");
++#endif
++
++
++      if((dUpdateInfo & MCDRV_DAC_MSWP_UPDATE_FLAG) != 0UL)
++      {
++              switch(psDacInfo->bMasterSwap)
++              {
++              case    MCDRV_DSWAP_OFF:
++              case    MCDRV_DSWAP_SWAP:
++              case    MCDRV_DSWAP_MUTE:
++              case    MCDRV_DSWAP_RMVCENTER:
++              case    MCDRV_DSWAP_MONO:
++              case    MCDRV_DSWAP_MONOHALF:
++              case    MCDRV_DSWAP_BOTHL:
++              case    MCDRV_DSWAP_BOTHR:
++                      gsGlobalInfo.sDacInfo.bMasterSwap       = psDacInfo->bMasterSwap;
++                      break;
++              default:
++                      break;
++              }
++      }
++      if((dUpdateInfo & MCDRV_DAC_VSWP_UPDATE_FLAG) != 0UL)
++      {
++              switch(psDacInfo->bVoiceSwap)
++              {
++              case    MCDRV_DSWAP_OFF:
++              case    MCDRV_DSWAP_SWAP:
++              case    MCDRV_DSWAP_MUTE:
++              case    MCDRV_DSWAP_RMVCENTER:
++              case    MCDRV_DSWAP_MONO:
++              case    MCDRV_DSWAP_MONOHALF:
++              case    MCDRV_DSWAP_BOTHL:
++              case    MCDRV_DSWAP_BOTHR:
++                      gsGlobalInfo.sDacInfo.bVoiceSwap        = psDacInfo->bVoiceSwap;
++                      break;
++              default:
++                      break;
++              }
++      }
++      if((dUpdateInfo & MCDRV_DAC_HPF_UPDATE_FLAG) != 0UL)
++      {
++              if((psDacInfo->bDcCut == MCDRV_DCCUT_ON) || (psDacInfo->bDcCut == MCDRV_DCCUT_OFF))
++              {
++                      gsGlobalInfo.sDacInfo.bDcCut    = psDacInfo->bDcCut;
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_SetDacInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_GetDacInfo
++ *
++ *    Description:
++ *                    Get DAC information.
++ *    Arguments:
++ *                    psDacInfo       DAC information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetDacInfo
++(
++      MCDRV_DAC_INFO* psDacInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_GetDacInfo");
++#endif
++
++      *psDacInfo      = gsGlobalInfo.sDacInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_GetDacInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_SetAdcInfo
++ *
++ *    Description:
++ *                    Set ADC information.
++ *    Arguments:
++ *                    psAdcInfo       ADC information
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetAdcInfo
++(
++      const MCDRV_ADC_INFO*   psAdcInfo,
++      UINT32  dUpdateInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_SetAdcInfo");
++#endif
++
++
++      if((dUpdateInfo & MCDRV_ADCADJ_UPDATE_FLAG) != 0UL)
++      {
++              switch(psAdcInfo->bAgcAdjust)
++              {
++              case    MCDRV_AGCADJ_24:
++              case    MCDRV_AGCADJ_18:
++              case    MCDRV_AGCADJ_12:
++              case    MCDRV_AGCADJ_0:
++                      gsGlobalInfo.sAdcInfo.bAgcAdjust        = psAdcInfo->bAgcAdjust;
++                      break;
++              default:
++                      break;
++              }
++      }
++      if((dUpdateInfo & MCDRV_ADCAGC_UPDATE_FLAG) != 0UL)
++      {
++              if((psAdcInfo->bAgcOn == MCDRV_AGC_OFF) || (psAdcInfo->bAgcOn == MCDRV_AGC_ON))
++              {
++                      gsGlobalInfo.sAdcInfo.bAgcOn    = psAdcInfo->bAgcOn;
++              }
++      }
++      if((dUpdateInfo & MCDRV_ADCMONO_UPDATE_FLAG) != 0UL)
++      {
++              if((psAdcInfo->bMono == MCDRV_ADC_STEREO) || (psAdcInfo->bMono == MCDRV_ADC_MONO))
++              {
++                      gsGlobalInfo.sAdcInfo.bMono     = psAdcInfo->bMono;
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_SetAdcInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_GetAdcInfo
++ *
++ *    Description:
++ *                    Get ADC information.
++ *    Arguments:
++ *                    psAdcInfo       ADC information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetAdcInfo
++(
++      MCDRV_ADC_INFO* psAdcInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_GetAdcInfo");
++#endif
++
++      *psAdcInfo      = gsGlobalInfo.sAdcInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_GetAdcInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_SetSpInfo
++ *
++ *    Description:
++ *                    Set SP information.
++ *    Arguments:
++ *                    psSpInfo        SP information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetSpInfo
++(
++      const MCDRV_SP_INFO*    psSpInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_SetSpInfo");
++#endif
++
++
++      if((psSpInfo->bSwap == MCDRV_SPSWAP_OFF) || (psSpInfo->bSwap == MCDRV_SPSWAP_SWAP))
++      {
++              gsGlobalInfo.sSpInfo.bSwap      = psSpInfo->bSwap;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_SetSpInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_GetSpInfo
++ *
++ *    Description:
++ *                    Get SP information.
++ *    Arguments:
++ *                    psSpInfo        SP information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetSpInfo
++(
++      MCDRV_SP_INFO*  psSpInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_GetSpInfo");
++#endif
++
++      *psSpInfo       = gsGlobalInfo.sSpInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_GetSpInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_SetDngInfo
++ *
++ *    Description:
++ *                    Set Digital Noise Gate information.
++ *    Arguments:
++ *                    psDngInfo       DNG information
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetDngInfo
++(
++      const MCDRV_DNG_INFO*   psDngInfo,
++      UINT32  dUpdateInfo
++)
++{
++      UINT8   bItem;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_SetDngInfo");
++#endif
++
++
++      for(bItem = MCDRV_DNG_ITEM_HP; bItem <= MCDRV_DNG_ITEM_RC; bItem++)
++      {
++              if((dUpdateInfo & (MCDRV_DNGSW_HP_UPDATE_FLAG<<(8*bItem))) != 0UL)
++              {
++                      if((psDngInfo->abOnOff[bItem] == MCDRV_DNG_OFF) || (psDngInfo->abOnOff[bItem] == MCDRV_DNG_ON))
++                      {
++                              gsGlobalInfo.sDngInfo.abOnOff[bItem]    = psDngInfo->abOnOff[bItem];
++                      }
++              }
++              if((dUpdateInfo & (MCDRV_DNGTHRES_HP_UPDATE_FLAG<<(8*bItem))) != 0UL)
++              {
++                      switch(psDngInfo->abThreshold[bItem])
++                      {
++                      case    MCDRV_DNG_THRES_30:
++                      case    MCDRV_DNG_THRES_36:
++                      case    MCDRV_DNG_THRES_42:
++                      case    MCDRV_DNG_THRES_48:
++                      case    MCDRV_DNG_THRES_54:
++                      case    MCDRV_DNG_THRES_60:
++                      case    MCDRV_DNG_THRES_66:
++                      case    MCDRV_DNG_THRES_72:
++                      case    MCDRV_DNG_THRES_78:
++                      case    MCDRV_DNG_THRES_84:
++                              gsGlobalInfo.sDngInfo.abThreshold[bItem]        = psDngInfo->abThreshold[bItem];
++                              break;
++                      default:
++                              break;
++                      }
++              }
++              if((dUpdateInfo & (MCDRV_DNGHOLD_HP_UPDATE_FLAG<<(8*bItem))) != 0UL)
++              {
++                      switch(psDngInfo->abHold[bItem])
++                      {
++                      case    MCDRV_DNG_HOLD_30:
++                      case    MCDRV_DNG_HOLD_120:
++                      case    MCDRV_DNG_HOLD_500:
++                              gsGlobalInfo.sDngInfo.abHold[bItem]     = psDngInfo->abHold[bItem];
++                              break;
++                      default:
++                              break;
++                      }
++              }
++              if((dUpdateInfo & (MCDRV_DNGATK_HP_UPDATE_FLAG<<(8*bItem))) != 0UL)
++              {
++                      switch(psDngInfo->abAttack[bItem])
++                      {
++                      case    MCDRV_DNG_ATTACK_25:
++                      case    MCDRV_DNG_ATTACK_100:
++                      case    MCDRV_DNG_ATTACK_400:
++                      case    MCDRV_DNG_ATTACK_800:
++                              gsGlobalInfo.sDngInfo.abAttack[bItem]   = psDngInfo->abAttack[bItem];
++                              break;
++                      default:
++                              break;
++                      }
++              }
++              if((dUpdateInfo & (MCDRV_DNGREL_HP_UPDATE_FLAG<<(8*bItem))) != 0UL)
++              {
++                      switch(psDngInfo->abRelease[bItem])
++                      {
++                      case    MCDRV_DNG_RELEASE_7950:
++                      case    MCDRV_DNG_RELEASE_470:
++                      case    MCDRV_DNG_RELEASE_940:
++                              gsGlobalInfo.sDngInfo.abRelease[bItem]  = psDngInfo->abRelease[bItem];
++                              break;
++                      default:
++                              break;
++                      }
++              }
++              if((dUpdateInfo & (MCDRV_DNGTARGET_HP_UPDATE_FLAG<<(8*bItem))) != 0UL)
++              {
++                      switch(psDngInfo->abTarget[bItem])
++                      {
++                      case    MCDRV_DNG_TARGET_6:
++                      case    MCDRV_DNG_TARGET_9:
++                      case    MCDRV_DNG_TARGET_12:
++                      case    MCDRV_DNG_TARGET_15:
++                      case    MCDRV_DNG_TARGET_18:
++                      case    MCDRV_DNG_TARGET_MUTE:
++                              gsGlobalInfo.sDngInfo.abTarget[bItem]   = psDngInfo->abTarget[bItem];
++                              break;
++                      default:
++                              break;
++                      }
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_SetDngInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_GetDngInfo
++ *
++ *    Description:
++ *                    Get Digital Noise Gate information.
++ *    Arguments:
++ *                    psDngInfo       DNG information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetDngInfo
++(
++      MCDRV_DNG_INFO* psDngInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_GetDngInfo");
++#endif
++
++      *psDngInfo      = gsGlobalInfo.sDngInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_GetDngInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_SetAeInfo
++ *
++ *    Description:
++ *                    Set Audio Engine information.
++ *    Arguments:
++ *                    psAeInfo        AE information
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetAeInfo
++(
++      const MCDRV_AE_INFO*    psAeInfo,
++      UINT32  dUpdateInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_SetAeInfo");
++#endif
++
++
++      if((McDevProf_IsValid(eMCDRV_FUNC_DBEX) == 1)
++      && ((dUpdateInfo & MCDRV_AEUPDATE_FLAG_BEXWIDE_ONOFF) != 0UL))
++      {
++              if((psAeInfo->bOnOff & MCDRV_BEXWIDE_ON) != 0)
++              {
++                      gsGlobalInfo.sAeInfo.bOnOff     |= MCDRV_BEXWIDE_ON;
++              }
++              else
++              {
++                      gsGlobalInfo.sAeInfo.bOnOff &= (UINT8)~MCDRV_BEXWIDE_ON;
++              }
++      }
++      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_DRC_ONOFF) != 0UL)
++      {
++              if((psAeInfo->bOnOff & MCDRV_DRC_ON) != 0)
++              {
++                      gsGlobalInfo.sAeInfo.bOnOff     |= MCDRV_DRC_ON;
++              }
++              else
++              {
++                      gsGlobalInfo.sAeInfo.bOnOff &= (UINT8)~MCDRV_DRC_ON;
++              }
++      }
++      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ5_ONOFF) != 0UL)
++      {
++              if((psAeInfo->bOnOff & MCDRV_EQ5_ON) != 0)
++              {
++                      gsGlobalInfo.sAeInfo.bOnOff     |= MCDRV_EQ5_ON;
++              }
++              else
++              {
++                      gsGlobalInfo.sAeInfo.bOnOff &= (UINT8)~MCDRV_EQ5_ON;
++              }
++      }
++      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ3_ONOFF) != 0UL)
++      {
++              if((psAeInfo->bOnOff & MCDRV_EQ3_ON) != 0)
++              {
++                      gsGlobalInfo.sAeInfo.bOnOff     |= MCDRV_EQ3_ON;
++              }
++              else
++              {
++                      gsGlobalInfo.sAeInfo.bOnOff &= (UINT8)~MCDRV_EQ3_ON;
++              }
++      }
++
++      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_BEX) != 0UL)
++      {
++              McSrv_MemCopy(psAeInfo->abBex, gsGlobalInfo.sAeInfo.abBex, BEX_PARAM_SIZE);
++      }
++
++      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_WIDE) != 0UL)
++      {
++              McSrv_MemCopy(psAeInfo->abWide, gsGlobalInfo.sAeInfo.abWide, WIDE_PARAM_SIZE);
++      }
++
++      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_DRC) != 0UL)
++      {
++              McSrv_MemCopy(psAeInfo->abDrc, gsGlobalInfo.sAeInfo.abDrc, DRC_PARAM_SIZE);
++      }
++
++      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ5) != 0UL)
++      {
++              McSrv_MemCopy(psAeInfo->abEq5, gsGlobalInfo.sAeInfo.abEq5, EQ5_PARAM_SIZE);
++      }
++
++      if((dUpdateInfo & MCDRV_AEUPDATE_FLAG_EQ3) != 0UL)
++      {
++              McSrv_MemCopy(psAeInfo->abEq3, gsGlobalInfo.sAeInfo.abEq3, EQ3_PARAM_SIZE);
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_SetAeInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_GetAeInfo
++ *
++ *    Description:
++ *                    Get Audio Engine information.
++ *    Arguments:
++ *                    psAeInfo        AE information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetAeInfo
++(
++      MCDRV_AE_INFO*  psAeInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_GetAeInfo");
++#endif
++
++      *psAeInfo       = gsGlobalInfo.sAeInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_GetAeInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_SetPdmInfo
++ *
++ *    Description:
++ *                    Set PDM information.
++ *    Arguments:
++ *                    psPdmInfo       PDM information
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetPdmInfo
++(
++      const MCDRV_PDM_INFO*   psPdmInfo,
++      UINT32  dUpdateInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_SetPdmInfo");
++#endif
++
++
++      if((dUpdateInfo & MCDRV_PDMCLK_UPDATE_FLAG) != 0UL)
++      {
++              switch(psPdmInfo->bClk)
++              {
++              case    MCDRV_PDM_CLK_128:
++              case    MCDRV_PDM_CLK_64:
++              case    MCDRV_PDM_CLK_32:
++                      gsGlobalInfo.sPdmInfo.bClk      = psPdmInfo->bClk;
++                      break;
++              default:
++                      break;
++              }
++      }
++      if((dUpdateInfo & MCDRV_PDMADJ_UPDATE_FLAG) != 0UL)
++      {
++              switch(psPdmInfo->bAgcAdjust)
++              {
++              case    MCDRV_AGCADJ_24:
++              case    MCDRV_AGCADJ_18:
++              case    MCDRV_AGCADJ_12:
++              case    MCDRV_AGCADJ_0:
++                      gsGlobalInfo.sPdmInfo.bAgcAdjust        = psPdmInfo->bAgcAdjust;
++                      break;
++              default:
++                      break;
++              }
++      }
++      if((dUpdateInfo & MCDRV_PDMAGC_UPDATE_FLAG) != 0UL)
++      {
++              switch(psPdmInfo->bAgcOn)
++              {
++              case    MCDRV_AGC_OFF:
++              case    MCDRV_AGC_ON:
++                      gsGlobalInfo.sPdmInfo.bAgcOn    = psPdmInfo->bAgcOn;
++                      break;
++              default:
++                      break;
++              }
++      }
++      if((dUpdateInfo & MCDRV_PDMEDGE_UPDATE_FLAG) != 0UL)
++      {
++              switch(psPdmInfo->bPdmEdge)
++              {
++              case    MCDRV_PDMEDGE_LH:
++              case    MCDRV_PDMEDGE_HL:
++                      gsGlobalInfo.sPdmInfo.bPdmEdge  = psPdmInfo->bPdmEdge;
++                      break;
++              default:
++                      break;
++              }
++      }
++      if((dUpdateInfo & MCDRV_PDMWAIT_UPDATE_FLAG) != 0UL)
++      {
++              switch(psPdmInfo->bPdmWait)
++              {
++              case    MCDRV_PDMWAIT_0:
++              case    MCDRV_PDMWAIT_1:
++              case    MCDRV_PDMWAIT_10:
++              case    MCDRV_PDMWAIT_20:
++                      gsGlobalInfo.sPdmInfo.bPdmWait  = psPdmInfo->bPdmWait;
++                      break;
++              default:
++                      break;
++              }
++      }
++      if((dUpdateInfo & MCDRV_PDMSEL_UPDATE_FLAG) != 0UL)
++      {
++              switch(psPdmInfo->bPdmSel)
++              {
++              case    MCDRV_PDMSEL_L1R2:
++              case    MCDRV_PDMSEL_L2R1:
++              case    MCDRV_PDMSEL_L1R1:
++              case    MCDRV_PDMSEL_L2R2:
++                      gsGlobalInfo.sPdmInfo.bPdmSel   = psPdmInfo->bPdmSel;
++                      break;
++              default:
++                      break;
++              }
++      }
++      if((dUpdateInfo & MCDRV_PDMMONO_UPDATE_FLAG) != 0UL)
++      {
++              switch(psPdmInfo->bMono)
++              {
++              case    MCDRV_PDM_STEREO:
++              case    MCDRV_PDM_MONO:
++                      gsGlobalInfo.sPdmInfo.bMono     = psPdmInfo->bMono;
++                      break;
++              default:
++                      break;
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_SetPdmInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_GetPdmInfo
++ *
++ *    Description:
++ *                    Get PDM information.
++ *    Arguments:
++ *                    psPdmInfo       PDM information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetPdmInfo
++(
++      MCDRV_PDM_INFO* psPdmInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_GetPdmInfo");
++#endif
++
++      *psPdmInfo      = gsGlobalInfo.sPdmInfo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_GetPdmInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_SetGPMode
++ *
++ *    Description:
++ *                    Set GP mode.
++ *    Arguments:
++ *                    psGpMode        GP mode
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetGPMode
++(
++      const MCDRV_GP_MODE*    psGpMode
++)
++{
++      UINT8   bPad;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_SetGPMode");
++#endif
++
++
++      for(bPad = 0; bPad < GPIO_PAD_NUM; bPad++)
++      {
++              if((psGpMode->abGpDdr[bPad] == MCDRV_GPDDR_IN)
++              || (psGpMode->abGpDdr[bPad] == MCDRV_GPDDR_OUT))
++              {
++                      gsGlobalInfo.sGpMode.abGpDdr[bPad]      = psGpMode->abGpDdr[bPad];
++              }
++              if(McDevProf_IsValid(eMCDRV_FUNC_GPMODE) == 1)
++              {
++                      if((psGpMode->abGpMode[bPad] == MCDRV_GPMODE_RISING)
++                      || (psGpMode->abGpMode[bPad] == MCDRV_GPMODE_FALLING)
++                      || (psGpMode->abGpMode[bPad] == MCDRV_GPMODE_BOTH))
++                      {
++                              gsGlobalInfo.sGpMode.abGpMode[bPad]     = psGpMode->abGpMode[bPad];
++                      }
++                      if((psGpMode->abGpHost[bPad] == MCDRV_GPHOST_SCU)
++                      || (psGpMode->abGpHost[bPad] == MCDRV_GPHOST_CDSP))
++                      {
++                              gsGlobalInfo.sGpMode.abGpHost[bPad]     = psGpMode->abGpHost[bPad];
++                      }
++                      if((psGpMode->abGpInvert[bPad] == MCDRV_GPINV_NORMAL)
++                      || (psGpMode->abGpInvert[bPad] == MCDRV_GPINV_INVERT))
++                      {
++                              gsGlobalInfo.sGpMode.abGpInvert[bPad]   = psGpMode->abGpInvert[bPad];
++                      }
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_SetGPMode", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_GetGPMode
++ *
++ *    Description:
++ *                    Get GP mode.
++ *    Arguments:
++ *                    psGpMode        GP mode
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetGPMode
++(
++      MCDRV_GP_MODE*  psGpMode
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_GetGPMode");
++#endif
++
++      *psGpMode       = gsGlobalInfo.sGpMode;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_GetGPMode", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_SetGPMask
++ *
++ *    Description:
++ *                    Set GP mask.
++ *    Arguments:
++ *                    bMask   GP mask
++ *                    dPadNo  PAD Number
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetGPMask
++(
++      UINT8   bMask,
++      UINT32  dPadNo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_SetGPMask");
++#endif
++
++      if(dPadNo == MCDRV_GP_PAD0)
++      {
++              if((gsGlobalInfo.sInitInfo.bPad0Func == MCDRV_PAD_GPIO)
++              && (gsGlobalInfo.sGpMode.abGpDdr[dPadNo] == MCDRV_GPDDR_IN))
++              {
++                      if((bMask == MCDRV_GPMASK_ON) || (bMask == MCDRV_GPMASK_OFF))
++                      {
++                              gsGlobalInfo.abGpMask[dPadNo]   = bMask;
++                      }
++              }
++      }
++      else if(dPadNo == MCDRV_GP_PAD1)
++      {
++              if((gsGlobalInfo.sInitInfo.bPad1Func == MCDRV_PAD_GPIO)
++              && (gsGlobalInfo.sGpMode.abGpDdr[dPadNo] == MCDRV_GPDDR_IN))
++              {
++                      if((bMask == MCDRV_GPMASK_ON) || (bMask == MCDRV_GPMASK_OFF))
++                      {
++                              gsGlobalInfo.abGpMask[dPadNo]   = bMask;
++                      }
++              }
++      }
++      else
++      {
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_SetGPMask", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_GetGPMask
++ *
++ *    Description:
++ *                    Get GP mask.
++ *    Arguments:
++ *                    pabMask GP mask
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetGPMask
++(
++      UINT8*  pabMask
++)
++{
++      UINT8   bPadNo;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_GetGPMask");
++#endif
++
++      for(bPadNo = 0; bPadNo < GPIO_PAD_NUM; bPadNo++)
++      {
++              pabMask[bPadNo] = gsGlobalInfo.abGpMask[bPadNo];
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_GetGPMask", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_GetSysEq
++ *
++ *    Description:
++ *                    Get System EQ.
++ *    Arguments:
++ *                    psSysEq         pointer to MCDRV_SYSEQ_INFO struct
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetSysEq
++(
++      MCDRV_SYSEQ_INFO*       psSysEq
++)
++{
++      UINT8   i;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_GetSysEq");
++#endif
++
++      psSysEq->bOnOff = gsGlobalInfo.sSysEq.bOnOff;
++      for(i = 0; i < sizeof(gsGlobalInfo.sSysEq.abParam); i++)
++      {
++              psSysEq->abParam[i]     = gsGlobalInfo.sSysEq.abParam[i];
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_GetSysEq", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_SetSysEq
++ *
++ *    Description:
++ *                    Set System EQ.
++ *    Arguments:
++ *                    psSysEq         pointer to MCDRV_SYSEQ_INFO struct
++ *                    dUpdateInfo     update information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetSysEq
++(
++      const MCDRV_SYSEQ_INFO* psSysEq,
++      UINT32                                  dUpdateInfo
++)
++{
++      UINT8   i;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_SetSysEq");
++#endif
++
++      if((dUpdateInfo & MCDRV_SYSEQ_ONOFF_UPDATE_FLAG) != 0UL)
++      {
++              if((psSysEq->bOnOff == MCDRV_SYSEQ_OFF) || (psSysEq->bOnOff == MCDRV_SYSEQ_ON))
++              {
++                      gsGlobalInfo.sSysEq.bOnOff      = psSysEq->bOnOff;
++              }
++      }
++
++      if((dUpdateInfo & MCDRV_SYSEQ_PARAM_UPDATE_FLAG) != 0UL)
++      {
++              for(i = 0; i < sizeof(gsGlobalInfo.sSysEq.abParam); i++)
++              {
++                      gsGlobalInfo.sSysEq.abParam[i]  = psSysEq->abParam[i];
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_SetSysEq", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_GetClockSwitch
++ *
++ *    Description:
++ *                    Get switch clock info.
++ *    Arguments:
++ *                    psClockInfo             pointer to MCDRV_CLKSW_INFO struct
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetClockSwitch
++(
++      MCDRV_CLKSW_INFO*       psClockInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_GetClockSwitch");
++#endif
++
++      psClockInfo->bClkSrc    = gsGlobalInfo.sClockSwitch.bClkSrc;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_GetClockSwitch", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_SetClockSwitch
++ *
++ *    Description:
++ *                    Get switch clock info.
++ *    Arguments:
++ *                    psClockInfo             pointer to MCDRV_CLKSW_INFO struct
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_SetClockSwitch
++(
++      const MCDRV_CLKSW_INFO* psClockInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_SetClockSwitch");
++#endif
++
++      gsGlobalInfo.sClockSwitch.bClkSrc       = psClockInfo->bClkSrc;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_SetClockSwitch", 0);
++#endif
++}
++
++
++/****************************************************************************
++ *    McResCtrl_GetVolReg
++ *
++ *    Description:
++ *                    Get value of volume registers.
++ *    Arguments:
++ *                    psVolInfo       volume information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetVolReg
++(
++      MCDRV_VOL_INFO* psVolInfo
++)
++{
++      UINT8   bCh;
++      MCDRV_DST_CH    abDSTCh[]       = {eMCDRV_DST_CH0, eMCDRV_DST_CH1};
++      SINT16  swGainUp;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_GetVolReg");
++#endif
++
++
++      *psVolInfo      = gsGlobalInfo.sVolInfo;
++
++      if(gsGlobalInfo.sInitInfo.bDclGain == MCDRV_DCLGAIN_6)
++      {
++              swGainUp        = 6 * 256;
++      }
++      else if(gsGlobalInfo.sInitInfo.bDclGain == MCDRV_DCLGAIN_12)
++      {
++              swGainUp        = 12 * 256;
++      }
++      else if(gsGlobalInfo.sInitInfo.bDclGain == MCDRV_DCLGAIN_18)
++      {
++              swGainUp        = 18 * 256;
++      }
++      else
++      {
++              swGainUp        = 0;
++      }
++
++      psVolInfo->aswA_HpGain[0]       = MCDRV_REG_MUTE;
++      if(McResCtrl_IsDstUsed(eMCDRV_DST_HP, eMCDRV_DST_CH0) == 0)
++      {
++              psVolInfo->aswA_Hp[0]   = MCDRV_REG_MUTE;
++      }
++      else
++      {
++              psVolInfo->aswA_Hp[0]           = GetHpVolReg(gsGlobalInfo.sVolInfo.aswA_Hp[0]);
++              psVolInfo->aswA_HpGain[0]       = GetHpGainReg(gsGlobalInfo.sVolInfo.aswA_HpGain[0]);
++      }
++      if(McResCtrl_IsDstUsed(eMCDRV_DST_HP, eMCDRV_DST_CH1) == 0)
++      {
++              psVolInfo->aswA_Hp[1]   = MCDRV_REG_MUTE;
++      }
++      else
++      {
++              psVolInfo->aswA_Hp[1]   = GetHpVolReg(gsGlobalInfo.sVolInfo.aswA_Hp[1]);
++              psVolInfo->aswA_HpGain[0]       = GetHpGainReg(gsGlobalInfo.sVolInfo.aswA_HpGain[0]);
++      }
++
++      if(McResCtrl_IsDstUsed(eMCDRV_DST_SP, eMCDRV_DST_CH0) == 0)
++      {
++              psVolInfo->aswA_Sp[0]   = MCDRV_REG_MUTE;
++      }
++      else
++      {
++              psVolInfo->aswA_Sp[0]   = GetSpVolReg(gsGlobalInfo.sVolInfo.aswA_Sp[0]);
++      }
++      if(McResCtrl_IsDstUsed(eMCDRV_DST_SP, eMCDRV_DST_CH1) == 0)
++      {
++              psVolInfo->aswA_Sp[1]   = MCDRV_REG_MUTE;
++      }
++      else
++      {
++              psVolInfo->aswA_Sp[1]   = GetSpVolReg(gsGlobalInfo.sVolInfo.aswA_Sp[1]);
++      }
++
++      if(McResCtrl_IsDstUsed(eMCDRV_DST_RCV, eMCDRV_DST_CH0) == 0)
++      {
++              psVolInfo->aswA_Rc[0]   = MCDRV_REG_MUTE;
++      }
++      else
++      {
++              psVolInfo->aswA_Rc[0]   = GetRcVolReg(gsGlobalInfo.sVolInfo.aswA_Rc[0]);
++      }
++
++      if(McResCtrl_IsDstUsed(eMCDRV_DST_LOUT1, eMCDRV_DST_CH0) == 0)
++      {
++              psVolInfo->aswA_Lout1[0]        = MCDRV_REG_MUTE;
++      }
++      else
++      {
++              psVolInfo->aswA_Lout1[0]        = GetLoVolReg(gsGlobalInfo.sVolInfo.aswA_Lout1[0]);
++      }
++      if(McResCtrl_IsDstUsed(eMCDRV_DST_LOUT1, eMCDRV_DST_CH1) == 0)
++      {
++              psVolInfo->aswA_Lout1[1]        = MCDRV_REG_MUTE;
++      }
++      else
++      {
++              psVolInfo->aswA_Lout1[1]        = GetLoVolReg(gsGlobalInfo.sVolInfo.aswA_Lout1[1]);
++      }
++
++      if(McResCtrl_IsDstUsed(eMCDRV_DST_LOUT2, eMCDRV_DST_CH0) == 0)
++      {
++              psVolInfo->aswA_Lout2[0]        = MCDRV_REG_MUTE;
++      }
++      else
++      {
++              psVolInfo->aswA_Lout2[0]        = GetLoVolReg(gsGlobalInfo.sVolInfo.aswA_Lout2[0]);
++      }
++      if(McResCtrl_IsDstUsed(eMCDRV_DST_LOUT2, eMCDRV_DST_CH1) == 0)
++      {
++              psVolInfo->aswA_Lout2[1]        = MCDRV_REG_MUTE;
++      }
++      else
++      {
++              psVolInfo->aswA_Lout2[1]        = GetLoVolReg(gsGlobalInfo.sVolInfo.aswA_Lout2[1]);
++      }
++
++      for(bCh = 0; bCh < AD0_VOL_CHANNELS; bCh++)
++      {
++              if(McResCtrl_IsDstUsed(eMCDRV_DST_ADC0, abDSTCh[bCh]) == 0)
++              {/*     ADC0 source all off     */
++                      psVolInfo->aswA_Ad0[bCh]        = MCDRV_REG_MUTE;
++                      psVolInfo->aswD_Ad0[bCh]        = MCDRV_REG_MUTE;
++              }
++              else
++              {
++                      psVolInfo->aswA_Ad0[bCh]        = GetADVolReg(gsGlobalInfo.sVolInfo.aswA_Ad0[bCh]);
++                      psVolInfo->aswD_Ad0[bCh]        = GetDigitalVolReg(gsGlobalInfo.sVolInfo.aswD_Ad0[bCh] - swGainUp);
++              }
++      }
++      if(((gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON)
++      || ((gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON)
++      || (((gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON)
++              && ((McResCtrl_GetAESource() == eMCDRV_SRC_PDM) || (McResCtrl_GetAESource() == eMCDRV_SRC_ADC0))))
++      {
++              for(bCh = 0; bCh < AD0_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Ad0Att[bCh]     = GetDigitalVolReg(gsGlobalInfo.sVolInfo.aswD_Ad0Att[bCh]);
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < AD0_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Ad0Att[bCh]     = MCDRV_REG_MUTE;
++              }
++      }
++
++      if(McDevProf_IsValid(eMCDRV_FUNC_ADC1) == 1)
++      {
++              if(McResCtrl_IsDstUsed(eMCDRV_DST_ADC1, eMCDRV_DST_CH0) == 0)
++              {/*     ADC1 source all off     */
++                      for(bCh = 0; bCh < AD1_VOL_CHANNELS; bCh++)
++                      {
++                              psVolInfo->aswA_Ad1[bCh]        = MCDRV_REG_MUTE;
++                              psVolInfo->aswD_Ad1[bCh]        = MCDRV_REG_MUTE;
++                      }
++              }
++              else
++              {
++                      for(bCh = 0; bCh < AD1_VOL_CHANNELS; bCh++)
++                      {
++                              psVolInfo->aswA_Ad1[bCh]        = GetADVolReg(gsGlobalInfo.sVolInfo.aswA_Ad1[bCh]);
++                              psVolInfo->aswD_Ad1[bCh]        = GetDigitalVolReg(gsGlobalInfo.sVolInfo.aswD_Ad1[bCh] - swGainUp);
++                      }
++              }
++              if((gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC1_BLOCK] & MCDRV_SRC4_ADC1_ON) == MCDRV_SRC4_ADC1_ON)
++              {
++                      for(bCh = 0; bCh < AD1_VOL_CHANNELS; bCh++)
++                      {
++                              psVolInfo->aswD_Ad1Att[bCh]     = GetDigitalVolReg(gsGlobalInfo.sVolInfo.aswD_Ad1Att[bCh]);
++                      }
++              }
++              else
++              {
++                      for(bCh = 0; bCh < AD1_VOL_CHANNELS; bCh++)
++                      {
++                              psVolInfo->aswD_Ad1Att[bCh]     = MCDRV_REG_MUTE;
++                      }
++              }
++      }
++
++      if(((gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++      || ((gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++      || ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++      || ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++      || ((gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++      || ((gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      || ((gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      || ((gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      || ((gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      || ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      || ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      || ((gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON))
++      {
++              psVolInfo->aswA_Lin1[0] = GetLIVolReg(gsGlobalInfo.sVolInfo.aswA_Lin1[0]);
++      }
++      else
++      {
++              psVolInfo->aswA_Lin1[0] = MCDRV_REG_MUTE;
++      }
++
++      if(((gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON)
++      || ((gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON)
++      || ((gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON)
++      || ((gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON)
++      || ((gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      || ((gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      || ((gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      || ((gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      || ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      || ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++      || ((gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON))
++      {
++              psVolInfo->aswA_Lin1[1] = GetLIVolReg(gsGlobalInfo.sVolInfo.aswA_Lin1[1]);
++      }
++      else
++      {
++              psVolInfo->aswA_Lin1[1] = MCDRV_REG_MUTE;
++      }
++
++      if(McDevProf_IsValid(eMCDRV_FUNC_LI2) == 1)
++      {
++              psVolInfo->aswA_Lin2[0] = MCDRV_REG_MUTE;
++              psVolInfo->aswA_Lin2[1] = MCDRV_REG_MUTE;
++      }
++
++      if(McResCtrl_IsSrcUsed(eMCDRV_SRC_MIC1) == 0)
++      {/*     MIC1 is unused  */
++              for(bCh = 0; bCh < MIC1_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswA_Mic1[bCh]               = MCDRV_REG_MUTE;
++                      psVolInfo->aswA_Mic1Gain[bCh]   = (SINT16)(McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_MC_GAIN) & MCB_MC1GAIN);
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < MIC1_VOL_CHANNELS; bCh++)
++              {
++                      if(((gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) != MCDRV_SRC0_MIC1_ON)
++                      && ((gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) != MCDRV_SRC0_MIC1_ON)
++                      && ((gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) != MCDRV_SRC0_MIC1_ON)
++                      && ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) != MCDRV_SRC0_MIC1_ON)
++                      && ((gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) != MCDRV_SRC0_MIC1_ON)
++                      && ((gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) != MCDRV_SRC0_MIC1_ON)
++                      && ((gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) != MCDRV_SRC0_MIC1_ON))
++                      {
++                              psVolInfo->aswA_Mic1[bCh]       = MCDRV_REG_MUTE;
++                      }
++                      else
++                      {
++                              psVolInfo->aswA_Mic1[bCh]       = GetMcVolReg(gsGlobalInfo.sVolInfo.aswA_Mic1[bCh]);
++                      }
++                      psVolInfo->aswA_Mic1Gain[bCh]   = GetMcGainReg(gsGlobalInfo.sVolInfo.aswA_Mic1Gain[bCh]);
++              }
++      }
++      if(McResCtrl_IsSrcUsed(eMCDRV_SRC_MIC2) == 0)
++      {/*     MIC2 is unused  */
++              for(bCh = 0; bCh < MIC2_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswA_Mic2[bCh]               = MCDRV_REG_MUTE;
++                      psVolInfo->aswA_Mic2Gain[bCh]   = (SINT16)((McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_MC_GAIN) & MCB_MC2GAIN) >> 4);
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < MIC2_VOL_CHANNELS; bCh++)
++              {
++                      if(((gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) != MCDRV_SRC0_MIC2_ON)
++                      && ((gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) != MCDRV_SRC0_MIC2_ON)
++                      && ((gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) != MCDRV_SRC0_MIC2_ON)
++                      && ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) != MCDRV_SRC0_MIC2_ON)
++                      && ((gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) != MCDRV_SRC0_MIC2_ON)
++                      && ((gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) != MCDRV_SRC0_MIC2_ON)
++                      && ((gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) != MCDRV_SRC0_MIC2_ON))
++                      {
++                              psVolInfo->aswA_Mic2[bCh]       = MCDRV_REG_MUTE;
++                      }
++                      else
++                      {
++                              psVolInfo->aswA_Mic2[bCh]       = GetMcVolReg(gsGlobalInfo.sVolInfo.aswA_Mic2[bCh]);
++                      }
++                      psVolInfo->aswA_Mic2Gain[bCh]   = GetMcGainReg(gsGlobalInfo.sVolInfo.aswA_Mic2Gain[bCh]);
++              }
++      }
++      if(McResCtrl_IsSrcUsed(eMCDRV_SRC_MIC3) == 0)
++      {/*     MIC3 is unused  */
++              for(bCh = 0; bCh < MIC3_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswA_Mic3[bCh]               = MCDRV_REG_MUTE;
++                      psVolInfo->aswA_Mic3Gain[bCh]   = (SINT16)(McResCtrl_GetRegVal(MCDRV_PACKET_REGTYPE_B_ANA, MCI_MC3_GAIN) & MCB_MC3GAIN);
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < MIC3_VOL_CHANNELS; bCh++)
++              {
++                      if(((gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) != MCDRV_SRC0_MIC3_ON)
++                      && ((gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) != MCDRV_SRC0_MIC3_ON)
++                      && ((gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) != MCDRV_SRC0_MIC3_ON)
++                      && ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) != MCDRV_SRC0_MIC3_ON)
++                      && ((gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) != MCDRV_SRC0_MIC3_ON)
++                      && ((gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) != MCDRV_SRC0_MIC3_ON)
++                      && ((gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) != MCDRV_SRC0_MIC3_ON))
++                      {
++                              psVolInfo->aswA_Mic3[bCh]       = MCDRV_REG_MUTE;
++                      }
++                      else
++                      {
++                              psVolInfo->aswA_Mic3[bCh]       = GetMcVolReg(gsGlobalInfo.sVolInfo.aswA_Mic3[bCh]);
++                      }
++                      psVolInfo->aswA_Mic3Gain[bCh]   = GetMcGainReg(gsGlobalInfo.sVolInfo.aswA_Mic3Gain[bCh]);
++              }
++      }
++
++      if(McResCtrl_IsSrcUsed(eMCDRV_SRC_DIR0) == 0)
++      {/*     DIR0 is unused  */
++              for(bCh = 0; bCh < DIO0_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dir0[bCh]               = MCDRV_REG_MUTE;
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < DIO0_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dir0[bCh]               = GetDigitalVolReg(gsGlobalInfo.sVolInfo.aswD_Dir0[bCh] - swGainUp);
++              }
++      }
++      if(((gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) == MCDRV_SRC3_DIR0_ON)
++      || (((gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON)
++              && (McResCtrl_GetAESource() == eMCDRV_SRC_DIR0)))
++      {
++              for(bCh = 0; bCh < DIO0_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dir0Att[bCh]    = GetDigitalVolReg(gsGlobalInfo.sVolInfo.aswD_Dir0Att[bCh]);
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < DIO0_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dir0Att[bCh]    = MCDRV_REG_MUTE;
++              }
++      }
++      if(McResCtrl_IsSrcUsed(eMCDRV_SRC_DIR1) == 0)
++      {/*     DIR1 is unused  */
++              for(bCh = 0; bCh < DIO1_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dir1[bCh]               = MCDRV_REG_MUTE;
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < DIO1_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dir1[bCh]               = GetDigitalVolReg(gsGlobalInfo.sVolInfo.aswD_Dir1[bCh] - swGainUp);
++              }
++      }
++      if(((gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) == MCDRV_SRC3_DIR1_ON)
++      || (((gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON)
++              && (McResCtrl_GetAESource() == eMCDRV_SRC_DIR1)))
++      {
++              for(bCh = 0; bCh < DIO1_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dir1Att[bCh]    = GetDigitalVolReg(gsGlobalInfo.sVolInfo.aswD_Dir1Att[bCh]);
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < DIO1_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dir1Att[bCh]    = MCDRV_REG_MUTE;
++              }
++      }
++      if(McResCtrl_IsSrcUsed(eMCDRV_SRC_DIR2) == 0)
++      {/*     DIR2 is unused  */
++              for(bCh = 0; bCh < DIO2_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dir2[bCh]               = MCDRV_REG_MUTE;
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < DIO2_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dir2[bCh]               = GetDigitalVolReg(gsGlobalInfo.sVolInfo.aswD_Dir2[bCh] - swGainUp);
++              }
++      }
++      if(((gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) == MCDRV_SRC3_DIR2_ON)
++      || (((gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON)
++              && (McResCtrl_GetAESource() == eMCDRV_SRC_DIR2)))
++      {
++              for(bCh = 0; bCh < DIO2_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dir2Att[bCh]    = GetDigitalVolReg(gsGlobalInfo.sVolInfo.aswD_Dir2Att[bCh]);
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < DIO2_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dir2Att[bCh]    = MCDRV_REG_MUTE;
++              }
++      }
++
++      if(McResCtrl_GetDITSource(eMCDRV_DIO_0) == eMCDRV_SRC_NONE)
++      {/*     DIT0 source all off     */
++              for(bCh = 0; bCh < DIO0_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dit0[bCh]       = MCDRV_REG_MUTE;
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < DIO0_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dit0[bCh]       = GetDigitalVolReg(gsGlobalInfo.sVolInfo.aswD_Dit0[bCh] + swGainUp);
++              }
++      }
++      if(McResCtrl_GetDITSource(eMCDRV_DIO_1) == eMCDRV_SRC_NONE)
++      {/*     DIT1 source all off     */
++              for(bCh = 0; bCh < DIO1_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dit1[bCh]       = MCDRV_REG_MUTE;
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < DIO1_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dit1[bCh]       = GetDigitalVolReg(gsGlobalInfo.sVolInfo.aswD_Dit1[bCh] + swGainUp);
++              }
++      }
++      if(McResCtrl_GetDITSource(eMCDRV_DIO_2) == eMCDRV_SRC_NONE)
++      {/*     DIT2 source all off     */
++              for(bCh = 0; bCh < DIO2_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dit2[bCh]       = MCDRV_REG_MUTE;
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < DIO2_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dit2[bCh]       = GetDigitalVolReg(gsGlobalInfo.sVolInfo.aswD_Dit2[bCh] + swGainUp);
++              }
++      }
++
++      if((McResCtrl_GetDACSource(eMCDRV_DAC_MASTER) == eMCDRV_SRC_NONE)
++      && (McResCtrl_GetDACSource(eMCDRV_DAC_VOICE) == eMCDRV_SRC_NONE))
++      {
++              for(bCh = 0; bCh < DAC_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_DacAtt[bCh]             = MCDRV_REG_MUTE;
++                      psVolInfo->aswD_DacMaster[bCh]  = MCDRV_REG_MUTE;
++                      psVolInfo->aswD_DacVoice[bCh]   = MCDRV_REG_MUTE;
++              }
++      }
++      else
++      {
++              if(McResCtrl_GetDACSource(eMCDRV_DAC_MASTER) == eMCDRV_SRC_NONE)
++              {
++                      for(bCh = 0; bCh < DAC_VOL_CHANNELS; bCh++)
++                      {
++                              psVolInfo->aswD_DacMaster[bCh]  = MCDRV_REG_MUTE;
++                      }
++              }
++              else
++              {
++                      for(bCh = 0; bCh < DAC_VOL_CHANNELS; bCh++)
++                      {
++                              psVolInfo->aswD_DacMaster[bCh]  = GetDigitalVolReg(gsGlobalInfo.sVolInfo.aswD_DacMaster[bCh]);
++                      }
++              }
++              if(McResCtrl_GetDACSource(eMCDRV_DAC_VOICE) == eMCDRV_SRC_NONE)
++              {
++                      for(bCh = 0; bCh < DAC_VOL_CHANNELS; bCh++)
++                      {
++                              psVolInfo->aswD_DacVoice[bCh]   = MCDRV_REG_MUTE;
++                      }
++              }
++              else
++              {
++                      for(bCh = 0; bCh < DAC_VOL_CHANNELS; bCh++)
++                      {
++                              psVolInfo->aswD_DacVoice[bCh]   = GetDigitalVolReg(gsGlobalInfo.sVolInfo.aswD_DacVoice[bCh]);
++                      }
++              }
++              for(bCh = 0; bCh < DAC_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_DacAtt[bCh]     = GetDigitalVolReg(gsGlobalInfo.sVolInfo.aswD_DacAtt[bCh]);
++              }
++      }
++
++      if((McResCtrl_IsSrcUsed(eMCDRV_SRC_PDM) == 0)
++      && (McResCtrl_IsSrcUsed(eMCDRV_SRC_ADC0) == 0))
++      {/*     PDM&ADC0 is unused      */
++              for(bCh = 0; bCh < AENG6_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Aeng6[bCh]      = MCDRV_REG_MUTE;
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < AENG6_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Aeng6[bCh]      = GetDigitalVolReg(gsGlobalInfo.sVolInfo.aswD_Aeng6[bCh]);
++              }
++      }
++
++      if(McResCtrl_IsSrcUsed(eMCDRV_SRC_PDM) == 0)
++      {/*     PDM is unused   */
++              for(bCh = 0; bCh < PDM_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Pdm[bCh]                = MCDRV_REG_MUTE;
++                      psVolInfo->aswD_SideTone[bCh]   = MCDRV_REG_MUTE;
++              }
++      }
++      else
++      {
++              for(bCh = 0; bCh < PDM_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Pdm[bCh]                = GetDigitalVolReg(gsGlobalInfo.sVolInfo.aswD_Pdm[bCh] - swGainUp);
++                      psVolInfo->aswD_SideTone[bCh]   = GetDigitalVolReg(gsGlobalInfo.sVolInfo.aswD_SideTone[bCh] - swGainUp);
++              }
++      }
++
++      if(McDevProf_IsValid(eMCDRV_FUNC_DTMF) == 1)
++      {
++              /*      DTMF    */
++              for(bCh = 0; bCh < DTMF_VOL_CHANNELS; bCh++)
++              {
++                      psVolInfo->aswD_Dtmfb[bCh]              = GetDigitalVolReg(gsGlobalInfo.sVolInfo.aswD_Dtmfb[bCh] - swGainUp);
++                      psVolInfo->aswD_DtmfAtt[bCh]    = GetDigitalVolReg(gsGlobalInfo.sVolInfo.aswD_DtmfAtt[bCh] - swGainUp);
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_GetVolReg", 0);
++#endif
++}
++
++/****************************************************************************
++ *    GetDigitalVolReg
++ *
++ *    Description:
++ *                    Get value of digital volume registers.
++ *    Arguments:
++ *                    swVol   volume(dB value*256)
++ *    Return:
++ *                    value of registers
++ *
++ ****************************************************************************/
++static SINT16 GetDigitalVolReg
++(
++      SINT16  swVol
++)
++{
++      SINT16  swRet;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("GetDigitalVolReg");
++#endif
++
++      if(swVol < (-74*256))
++      {
++              swRet   = 0;
++      }
++      else if(swVol < 0)
++      {
++              swRet   = 96 + (swVol-128)/256;
++      }
++      else
++      {
++              swRet   = 96 + (swVol+128)/256;
++      }
++
++      if(swRet < 22)
++      {
++              swRet   = 0;
++      }
++
++      if(swRet > 114)
++      {
++              swRet   = 114;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = swRet;
++      McDebugLog_FuncOut("GetDigitalVolReg", &sdRet);
++#endif
++
++      return swRet;
++}
++
++/****************************************************************************
++ *    GetADVolReg
++ *
++ *    Description:
++ *                    Get update value of analog AD volume registers.
++ *    Arguments:
++ *                    swVol   volume(dB value*256)
++ *    Return:
++ *                    value of registers
++ *
++ ****************************************************************************/
++static SINT16 GetADVolReg
++(
++      SINT16  swVol
++)
++{
++      SINT16  swRet;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("GetADVolReg");
++#endif
++
++      if(swVol < (-27*256))
++      {
++              swRet   = 0;
++      }
++      else if(swVol < 0)
++      {
++              swRet   = 19 + (swVol-192) * 2 / (256*3);
++      }
++      else
++      {
++              swRet   = 19 + (swVol+192) * 2 / (256*3);
++      }
++
++      if(swRet < 0)
++      {
++              swRet   = 0;
++      }
++
++      if(swRet > 31)
++      {
++              swRet   = 31;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = swRet;
++      McDebugLog_FuncOut("GetADVolReg", &sdRet);
++#endif
++
++      return swRet;
++}
++
++/****************************************************************************
++ *    GetLIVolReg
++ *
++ *    Description:
++ *                    Get update value of analog LIN volume registers.
++ *    Arguments:
++ *                    swVol   volume(dB value*256)
++ *    Return:
++ *                    value of registers
++ *
++ ****************************************************************************/
++static SINT16 GetLIVolReg
++(
++      SINT16  swVol
++)
++{
++      SINT16  swRet;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("GetLIVolReg");
++#endif
++
++      if(swVol < (-30*256))
++      {
++              swRet   = 0;
++      }
++      else if(swVol < 0)
++      {
++              swRet   = 21 + (swVol-192) * 2 / (256*3);
++      }
++      else
++      {
++              swRet   = 21 + (swVol+192) * 2 / (256*3);
++      }
++
++      if(swRet < 0)
++      {
++              swRet   = 0;
++      }
++      if(swRet > 31)
++      {
++              swRet   = 31;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = swRet;
++      McDebugLog_FuncOut("GetLIVolReg", &sdRet);
++#endif
++      return swRet;
++}
++
++/****************************************************************************
++ *    GetMcVolReg
++ *
++ *    Description:
++ *                    Get update value of analog Mic volume registers.
++ *    Arguments:
++ *                    swVol   volume(dB value*256)
++ *    Return:
++ *                    value of registers
++ *
++ ****************************************************************************/
++static SINT16 GetMcVolReg
++(
++      SINT16  swVol
++)
++{
++      SINT16  swRet;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("GetMcVolReg");
++#endif
++
++      if(swVol < (-30*256))
++      {
++              swRet   = 0;
++      }
++      else if(swVol < 0)
++      {
++              swRet   = 21 + (swVol-192) * 2 / (256*3);
++      }
++      else
++      {
++              swRet   = 21 + (swVol+192) * 2 / (256*3);
++      }
++
++      if(swRet < 0)
++      {
++              swRet   = 0;
++      }
++      if(swRet > 31)
++      {
++              swRet   = 31;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = swRet;
++      McDebugLog_FuncOut("GetMcVolReg", &sdRet);
++#endif
++      return swRet;
++}
++
++/****************************************************************************
++ *    GetMcGainReg
++ *
++ *    Description:
++ *                    Get update value of analog Mic gain registers.
++ *    Arguments:
++ *                    swVol   volume(dB value*256)
++ *    Return:
++ *                    value of registers
++ *
++ ****************************************************************************/
++static SINT16 GetMcGainReg
++(
++      SINT16  swVol
++)
++{
++      SINT16  swGain  = (swVol+128)/256;
++      SINT16  swRet   = 3;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("GetMcGainReg");
++#endif
++
++      if(swGain < 18)
++      {
++              swRet   = 0;
++      }
++      else if(swGain < 23)
++      {
++              swRet   = 1;
++      }
++      else if(swGain < 28)
++      {
++              swRet   = 2;
++      }
++      else
++      {
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = swRet;
++      McDebugLog_FuncOut("GetMcGainReg", &sdRet);
++#endif
++
++      return swRet;
++}
++
++/****************************************************************************
++ *    GetHpVolReg
++ *
++ *    Description:
++ *                    Get update value of analog Hp volume registers.
++ *    Arguments:
++ *                    swVol   volume(dB value*256)
++ *    Return:
++ *                    value of registers
++ *
++ ****************************************************************************/
++static SINT16 GetHpVolReg
++(
++      SINT16  swVol
++)
++{
++      SINT16  swDB    = swVol/256;
++      SINT16  swRet;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("GetHpVolReg");
++#endif
++
++      if(swVol >= 0)
++      {
++              swRet   = 31;
++      }
++      else if(swDB <= -8)
++      {
++              if(swVol < (-36*256))
++              {
++                      swRet   = 0;
++              }
++              else if(swDB <= -32)
++              {
++                      swRet   = 1;
++              }
++              else if(swDB <= -26)
++              {
++                      swRet   = 2;
++              }
++              else if(swDB <= -23)
++              {
++                      swRet   = 3;
++              }
++              else if(swDB <= -21)
++              {
++                      swRet   = 4;
++              }
++              else if(swDB <= -19)
++              {
++                      swRet   = 5;
++              }
++              else if(swDB <= -17)
++              {
++                      swRet   = 6;
++              }
++              else
++              {
++                      swRet   = 23+(swVol-128)/256;
++              }
++      }
++      else
++      {
++              swRet   = 31 + (swVol-64)*2/256;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = swRet;
++      McDebugLog_FuncOut("GetHpVolReg", &sdRet);
++#endif
++
++      return swRet;
++}
++
++/****************************************************************************
++ *    GetHpGainReg
++ *
++ *    Description:
++ *                    Get update value of analog Hp gain registers.
++ *    Arguments:
++ *                    swVol   volume(dB value*256)
++ *    Return:
++ *                    value of registers
++ *
++ ****************************************************************************/
++static SINT16 GetHpGainReg
++(
++      SINT16  swVol
++)
++{
++      SINT16  swDB    = swVol/(256/4);
++      SINT16  swRet;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("GetHpGainReg");
++#endif
++
++      if(swDB < 3)
++      {
++              swRet   = 0;
++      }
++      else if(swDB < 9)
++      {
++              swRet   = 1;
++      }
++      else if(swDB < 18)
++      {
++              swRet   = 2;
++      }
++      else
++      {
++              swRet   = 3;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = swRet;
++      McDebugLog_FuncOut("GetHpGainReg", &sdRet);
++#endif
++
++      return swRet;
++}
++
++/****************************************************************************
++ *    GetSpVolReg
++ *
++ *    Description:
++ *                    Get update value of analog Sp volume registers.
++ *    Arguments:
++ *                    swVol   volume(dB value*256)
++ *    Return:
++ *                    value of registers
++ *
++ ****************************************************************************/
++static SINT16 GetSpVolReg
++(
++      SINT16  swVol
++)
++{
++      SINT16  swDB    = swVol/256;
++      SINT16  swRet;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("GetSpVolReg");
++#endif
++
++      if(swVol >= 0)
++      {
++              swRet   = 31;
++      }
++      else if(swDB <= -8)
++      {
++              if(swVol < (-36*256))
++              {
++                      swRet   = 0;
++              }
++              else if(swDB <= -32)
++              {
++                      swRet   = 1;
++              }
++              else if(swDB <= -26)
++              {
++                      swRet   = 2;
++              }
++              else if(swDB <= -23)
++              {
++                      swRet   = 3;
++              }
++              else if(swDB <= -21)
++              {
++                      swRet   = 4;
++              }
++              else if(swDB <= -19)
++              {
++                      swRet   = 5;
++              }
++              else if(swDB <= -17)
++              {
++                      swRet   = 6;
++              }
++              else
++              {
++                      swRet   = 23+(swVol-128)/256;
++              }
++      }
++      else
++      {
++              swRet   = 31 + (swVol-64)*2/256;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = swRet;
++      McDebugLog_FuncOut("GetSpVolReg", &sdRet);
++#endif
++
++      return swRet;
++}
++
++/****************************************************************************
++ *    GetRcVolReg
++ *
++ *    Description:
++ *                    Get update value of analog Rcv volume registers.
++ *    Arguments:
++ *                    swVol   volume(dB value*256)
++ *    Return:
++ *                    value of registers
++ *
++ ****************************************************************************/
++static SINT16 GetRcVolReg
++(
++      SINT16  swVol
++)
++{
++      SINT16  swDB    = swVol/256;
++      SINT16  swRet;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("GetRcVolReg");
++#endif
++
++      if(swVol >= 0)
++      {
++              swRet   = 31;
++      }
++      else if(swDB <= -8)
++      {
++              if(swVol < (-36*256))
++              {
++                      swRet   = 0;
++              }
++              else if(swDB <= -32)
++              {
++                      swRet   = 1;
++              }
++              else if(swDB <= -26)
++              {
++                      swRet   = 2;
++              }
++              else if(swDB <= -23)
++              {
++                      swRet   = 3;
++              }
++              else if(swDB <= -21)
++              {
++                      swRet   = 4;
++              }
++              else if(swDB <= -19)
++              {
++                      swRet   = 5;
++              }
++              else if(swDB <= -17)
++              {
++                      swRet   = 6;
++              }
++              else
++              {
++                      swRet   = 23+(swVol-128)/256;
++              }
++      }
++      else
++      {
++              swRet   = 31 + (swVol-64)*2/256;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = swRet;
++      McDebugLog_FuncOut("GetRcVolReg", &sdRet);
++#endif
++
++      return swRet;
++}
++
++/****************************************************************************
++ *    GetLoVolReg
++ *
++ *    Description:
++ *                    Get update value of analog Lout volume registers.
++ *    Arguments:
++ *                    swVol   volume(dB value*256)
++ *    Return:
++ *                    value of registers
++ *
++ ****************************************************************************/
++static SINT16 GetLoVolReg
++(
++      SINT16  swVol
++)
++{
++      SINT16  swRet   = 31 + (swVol-128)/256;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("GetLoVolReg");
++#endif
++
++      if(swVol < (-30*256))
++      {
++              swRet   = 0;
++      }
++      if(swRet < 0)
++      {
++              swRet   = 0;
++      }
++      if(swRet > 31)
++      {
++              swRet   = 31;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = swRet;
++      McDebugLog_FuncOut("GetLoVolReg", &sdRet);
++#endif
++      return swRet;
++}
++
++/****************************************************************************
++ *    McResCtrl_GetPowerInfo
++ *
++ *    Description:
++ *                    Get power information.
++ *    Arguments:
++ *                    psPowerInfo     power information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetPowerInfo
++(
++      MCDRV_POWER_INFO*       psPowerInfo
++)
++{
++      UINT8   i;
++      UINT8   bAnalogOn       = 0;
++      UINT8   bPowerMode      = gsGlobalInfo.sInitInfo.bPowerMode;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_GetPowerInfo");
++#endif
++
++      /*      Digital power   */
++      psPowerInfo->dDigital   = 0;
++      if((bPowerMode & MCDRV_POWMODE_CLKON) == 0)
++      {
++              psPowerInfo->dDigital |= (MCDRV_POWINFO_DIGITAL_DP0 | MCDRV_POWINFO_DIGITAL_DP1 | MCDRV_POWINFO_DIGITAL_DP2 | MCDRV_POWINFO_DIGITAL_PLLRST0);
++      }
++      if((McResCtrl_GetDITSource(eMCDRV_DIO_0)        != eMCDRV_SRC_NONE)
++      || (McResCtrl_GetDITSource(eMCDRV_DIO_1)        != eMCDRV_SRC_NONE)
++      || (McResCtrl_GetDITSource(eMCDRV_DIO_2)        != eMCDRV_SRC_NONE)
++      || (McResCtrl_IsSrcUsed(eMCDRV_SRC_DAC_L)       != 0)
++      || (McResCtrl_IsSrcUsed(eMCDRV_SRC_DAC_M)       != 0)
++      || (McResCtrl_IsSrcUsed(eMCDRV_SRC_DAC_R)       != 0)
++      || (McResCtrl_IsSrcUsed(eMCDRV_SRC_ADC0)        != 0)
++      || (McResCtrl_IsSrcUsed(eMCDRV_SRC_AE)          != 0)
++      || (McResCtrl_IsSrcUsed(eMCDRV_SRC_MIX)         != 0))
++      {
++              /*      DP0-2, PLLRST0 on       */
++              psPowerInfo->dDigital &= ~(MCDRV_POWINFO_DIGITAL_DP0 | MCDRV_POWINFO_DIGITAL_DP1 | MCDRV_POWINFO_DIGITAL_DP2 | MCDRV_POWINFO_DIGITAL_PLLRST0);
++      }
++      else
++      {
++              psPowerInfo->dDigital |= MCDRV_POWINFO_DIGITAL_DPB;
++      }
++
++      /*      DPBDSP  */
++      if((McResCtrl_IsSrcUsed(eMCDRV_SRC_AE) == 0)
++      || ((gsGlobalInfo.sAeInfo.bOnOff&(MCDRV_BEXWIDE_ON|MCDRV_DRC_ON)) == 0))
++      {
++              psPowerInfo->dDigital |= MCDRV_POWINFO_DIGITAL_DPBDSP;
++      }
++
++      /*      DPADIF  */
++      if(McResCtrl_IsSrcUsed(eMCDRV_SRC_ADC0) == 0)
++      {
++              psPowerInfo->dDigital |= MCDRV_POWINFO_DIGITAL_DPADIF;
++      }
++
++      /*      DPPDM   */
++      if((gsGlobalInfo.sInitInfo.bPad0Func != MCDRV_PAD_PDMCK) || (McResCtrl_IsSrcUsed(eMCDRV_SRC_PDM) == 0))
++      {
++              psPowerInfo->dDigital |= MCDRV_POWINFO_DIGITAL_DPPDM;
++      }
++
++      /*      DPDI*   */
++      if((gsGlobalInfo.sDioInfo.asPortInfo[0].sDioCommon.bMasterSlave == MCDRV_DIO_SLAVE)
++      || (((McResCtrl_IsSrcUsed(eMCDRV_SRC_DIR0) == 0) && (McResCtrl_GetDITSource(eMCDRV_DIO_0) == eMCDRV_SRC_NONE))))
++      {
++              psPowerInfo->dDigital |= MCDRV_POWINFO_DIGITAL_DPDI0;
++      }
++      if((gsGlobalInfo.sDioInfo.asPortInfo[1].sDioCommon.bMasterSlave == MCDRV_DIO_SLAVE)
++      || (((McResCtrl_IsSrcUsed(eMCDRV_SRC_DIR1) == 0) && (McResCtrl_GetDITSource(eMCDRV_DIO_1) == eMCDRV_SRC_NONE))))
++      {
++              psPowerInfo->dDigital |= MCDRV_POWINFO_DIGITAL_DPDI1;
++      }
++      if((gsGlobalInfo.sDioInfo.asPortInfo[2].sDioCommon.bMasterSlave == MCDRV_DIO_SLAVE)
++      || (((McResCtrl_IsSrcUsed(eMCDRV_SRC_DIR2) == 0) && (McResCtrl_GetDITSource(eMCDRV_DIO_2) == eMCDRV_SRC_NONE))))
++      {
++              psPowerInfo->dDigital |= MCDRV_POWINFO_DIGITAL_DPDI2;
++      }
++
++      /*      Analog power    */
++      for(i = 0; i < 5; i++)
++      {
++              psPowerInfo->abAnalog[i]        = 0;
++      }
++
++      /*      SPL*    */
++      if(McResCtrl_IsDstUsed(eMCDRV_DST_SP, eMCDRV_DST_CH0) == 0)
++      {
++              psPowerInfo->abAnalog[1] |= MCB_PWM_SPL1;
++              psPowerInfo->abAnalog[1] |= MCB_PWM_SPL2;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      /*      SPR*    */
++      if(McResCtrl_IsDstUsed(eMCDRV_DST_SP, eMCDRV_DST_CH1) == 0)
++      {
++              psPowerInfo->abAnalog[1] |= MCB_PWM_SPR1;
++              psPowerInfo->abAnalog[1] |= MCB_PWM_SPR2;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++
++      /*      HPL     */
++      if(McResCtrl_IsDstUsed(eMCDRV_DST_HP, eMCDRV_DST_CH0) == 0)
++      {
++              psPowerInfo->abAnalog[1] |= MCB_PWM_HPL;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      /*      HPR     */
++      if(McResCtrl_IsDstUsed(eMCDRV_DST_HP, eMCDRV_DST_CH1) == 0)
++      {
++              psPowerInfo->abAnalog[1] |= MCB_PWM_HPR;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      /*      CP      */
++      if(((psPowerInfo->abAnalog[1] & MCB_PWM_HPL) != 0) && ((psPowerInfo->abAnalog[1] & MCB_PWM_HPR) != 0))
++      {
++              psPowerInfo->abAnalog[0] |= MCB_PWM_CP;
++      }
++
++      /*      LOUT1L  */
++      if(McResCtrl_IsDstUsed(eMCDRV_DST_LOUT1, eMCDRV_DST_CH0) == 0)
++      {
++              psPowerInfo->abAnalog[2] |= MCB_PWM_LO1L;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      /*      LOUT1R  */
++      if(McResCtrl_IsDstUsed(eMCDRV_DST_LOUT1, eMCDRV_DST_CH1) == 0)
++      {
++              psPowerInfo->abAnalog[2] |= MCB_PWM_LO1R;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      /*      LOUT2L  */
++      if(McResCtrl_IsDstUsed(eMCDRV_DST_LOUT2, eMCDRV_DST_CH0) == 0)
++      {
++              psPowerInfo->abAnalog[2] |= MCB_PWM_LO2L;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      /*      LOUT2R  */
++      if(McResCtrl_IsDstUsed(eMCDRV_DST_LOUT2, eMCDRV_DST_CH1) == 0)
++      {
++              psPowerInfo->abAnalog[2] |= MCB_PWM_LO2R;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      /*      RCV     */
++      if(McResCtrl_IsDstUsed(eMCDRV_DST_RCV, eMCDRV_DST_CH0) == 0)
++      {
++              psPowerInfo->abAnalog[2] |= MCB_PWM_RC1;
++              psPowerInfo->abAnalog[2] |= MCB_PWM_RC2;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      /*      DA      */
++      if((McResCtrl_IsDstUsed(eMCDRV_DST_DAC, eMCDRV_DST_CH0) == 0)
++      && (McResCtrl_IsDstUsed(eMCDRV_DST_DAC, eMCDRV_DST_CH1) == 0))
++      {
++              psPowerInfo->abAnalog[3] |= MCB_PWM_DAL;
++              psPowerInfo->abAnalog[3] |= MCB_PWM_DAR;
++      }
++      else
++      {
++              if((McResCtrl_IsSrcUsed(eMCDRV_SRC_DAC_L) == 0)
++              && (McResCtrl_IsSrcUsed(eMCDRV_SRC_DAC_M) == 0))
++              {
++                      psPowerInfo->abAnalog[3] |= MCB_PWM_DAL;
++              }
++              if((McResCtrl_IsSrcUsed(eMCDRV_SRC_DAC_R) == 0)
++              && (McResCtrl_IsSrcUsed(eMCDRV_SRC_DAC_M) == 0))
++              {
++                      psPowerInfo->abAnalog[3] |= MCB_PWM_DAR;
++              }
++              bAnalogOn       = 1;
++      }
++      /*      ADC0L   */
++      if(McResCtrl_IsDstUsed(eMCDRV_DST_ADC0, eMCDRV_DST_CH0) == 1)
++      {
++              bAnalogOn       = 1;
++      }
++      else
++      {
++              if((McDevProf_IsValid(eMCDRV_FUNC_LI2) == 1)
++              && (((gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE2_L_BLOCK] & MCDRV_SRC2_LINE2_L_ON) == MCDRV_SRC2_LINE2_L_ON)
++                      || ((gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE2_M_BLOCK] & MCDRV_SRC2_LINE2_M_ON) == MCDRV_SRC2_LINE2_M_ON)))
++              {
++                      bAnalogOn       = 1;
++              }
++              else
++              {
++                      psPowerInfo->abAnalog[1] |= MCB_PWM_ADL;
++              }
++      }
++      /*      ADC0R   */
++      if(McResCtrl_IsDstUsed(eMCDRV_DST_ADC0, eMCDRV_DST_CH1) == 1)
++      {
++              bAnalogOn       = 1;
++      }
++      else
++      {
++              if((McDevProf_IsValid(eMCDRV_FUNC_LI2) == 1)
++              && (((gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE2_R_BLOCK] & MCDRV_SRC2_LINE2_R_ON) == MCDRV_SRC2_LINE2_R_ON)
++                      || ((gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE2_M_BLOCK] & MCDRV_SRC2_LINE2_M_ON) == MCDRV_SRC2_LINE2_M_ON)))
++              {
++                      bAnalogOn       = 1;
++              }
++              else
++              {
++                      psPowerInfo->abAnalog[1] |= MCB_PWM_ADR;
++              }
++      }
++      if(McDevProf_IsValid(eMCDRV_FUNC_ADC1) == 1)
++      {
++      }
++      /*      LI      */
++      if((McResCtrl_IsSrcUsed(eMCDRV_SRC_LINE1_L) == 0)
++      && (McResCtrl_IsSrcUsed(eMCDRV_SRC_LINE1_M) == 0)
++      && (McResCtrl_IsSrcUsed(eMCDRV_SRC_LINE1_R) == 0))
++      {
++              psPowerInfo->abAnalog[4] |= MCB_PWM_LI;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      if(McDevProf_IsValid(eMCDRV_FUNC_LI2) == 1)
++      {
++              if((McResCtrl_IsSrcUsed(eMCDRV_SRC_LINE2_L) == 0)
++              && (McResCtrl_IsSrcUsed(eMCDRV_SRC_LINE2_M) == 0)
++              && (McResCtrl_IsSrcUsed(eMCDRV_SRC_LINE2_R) == 0))
++              {
++                      /*psPowerInfo->abAnalog[4] |= MCB_PWM_LI2;*/
++              }
++              else
++              {
++                      bAnalogOn       = 1;
++              }
++      }
++      /*      MC1     */
++      if(McResCtrl_IsSrcUsed(eMCDRV_SRC_MIC1) == 0)
++      {
++              psPowerInfo->abAnalog[4] |= MCB_PWM_MC1;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      /*      MC2     */
++      if(McResCtrl_IsSrcUsed(eMCDRV_SRC_MIC2) == 0)
++      {
++              psPowerInfo->abAnalog[4] |= MCB_PWM_MC2;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      /*      MC3     */
++      if(McResCtrl_IsSrcUsed(eMCDRV_SRC_MIC3) == 0)
++      {
++              psPowerInfo->abAnalog[4] |= MCB_PWM_MC3;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      if((gsGlobalInfo.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) != MCDRV_SRC0_MIC1_ON)
++      {
++              psPowerInfo->abAnalog[3] |= MCB_PWM_MB1;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      if((gsGlobalInfo.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) != MCDRV_SRC0_MIC2_ON)
++      {
++              psPowerInfo->abAnalog[3] |= MCB_PWM_MB2;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++      if((gsGlobalInfo.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) != MCDRV_SRC0_MIC3_ON)
++      {
++              psPowerInfo->abAnalog[3] |= MCB_PWM_MB3;
++      }
++      else
++      {
++              bAnalogOn       = 1;
++      }
++
++      /*      VR/LDOA/REFA    */
++      if ((0 == bAnalogOn) && ((bPowerMode & MCDRV_POWMODE_VREFON) == 0))
++      {
++              psPowerInfo->abAnalog[0] |= MCB_PWM_VR;
++              psPowerInfo->abAnalog[0] |= MCB_PWM_REFA;
++              psPowerInfo->abAnalog[0] |= MCB_PWM_LDOA;
++      }
++      else
++      {
++              if (MCDRV_LDO_OFF == gsGlobalInfo.sInitInfo.bLdo)
++              {
++                      psPowerInfo->abAnalog[0] |= MCB_PWM_LDOA;
++              }
++              else
++              {
++                      psPowerInfo->abAnalog[0] |= MCB_PWM_REFA;
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_GetPowerInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_GetPowerInfoRegAccess
++ *
++ *    Description:
++ *                    Get power information to access register.
++ *    Arguments:
++ *                    psRegInfo       register information
++ *                    psPowerInfo     power information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetPowerInfoRegAccess
++(
++      const MCDRV_REG_INFO*   psRegInfo,
++      MCDRV_POWER_INFO*               psPowerInfo
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_GetPowerInfoRegAccess");
++#endif
++
++
++      McResCtrl_GetPowerInfo(psPowerInfo);
++
++      switch(psRegInfo->bRegType)
++      {
++      default:
++      case    MCDRV_REGTYPE_A:
++      case    MCDRV_REGTYPE_B_BASE:
++      case    MCDRV_REGTYPE_B_AE:
++              break;
++      case    MCDRV_REGTYPE_B_ANALOG:
++              switch(psRegInfo->bAddress)
++              {
++              case    MCI_APMOFF:
++              case    MCI_HPVOL_L:
++              case    MCI_HPVOL_R:
++              case    MCI_SPVOL_L:
++              case    MCI_SPVOL_R:
++              case    MCI_RCVOL:
++              case    MCI_HPL_MIX:
++              case    MCI_HPL_MONO:
++              case    MCI_HPR_MIX:
++              case    MCI_SPL_MIX:
++              case    MCI_SPL_MONO:
++              case    MCI_SPR_MIX:
++              case    MCI_SPR_MONO:
++              case    MCI_RC_MIX:
++                      psPowerInfo->abAnalog[0]        &= (UINT8)~MCB_PWM_VR;
++                      break;
++              default:
++                      break;
++              }
++              break;
++
++      case    MCDRV_REGTYPE_B_CODEC:
++              switch(psRegInfo->bAddress)
++              {
++              case    MCI_DPADIF:
++              case    MCI_CD_HW_ID:
++              case    MCI_PLL_RST:
++              case    MCI_DIVR0:
++              case    MCI_DIVF0:
++              case    MCI_DIVR1:
++              case    MCI_DIVF1:
++              case    MCI_AD_AGC:
++              case    MCI_DCCUTOFF:
++              case    MCI_DCL:
++                      break;
++              default:
++                      if((psRegInfo->bAddress >= MCI_SYS_CEQ0_19_12) && (psRegInfo->bAddress <= MCI_SYS_CEQ4_3_0))
++                      {
++                              break;
++                      }
++                      psPowerInfo->dDigital   &= ~(MCDRV_POWINFO_DIGITAL_DP0 | MCDRV_POWINFO_DIGITAL_DP1
++                                                                              | MCDRV_POWINFO_DIGITAL_DP2 | MCDRV_POWINFO_DIGITAL_PLLRST0 | MCDRV_POWINFO_DIGITAL_DPB);
++                      break;
++              }
++              break;
++
++      case    MCDRV_REGTYPE_B_MIXER:
++              switch(psRegInfo->bAddress)
++              {
++              case    MCI_SWP:
++              case    MCI_DIMODE0:
++              case    MCI_DIMODE1:
++              case    MCI_DIMODE2:
++              case    MCI_DI_FS0:
++              case    MCI_DI_FS1:
++              case    MCI_DI_FS2:
++              case    MCI_DI0_SRC:
++              case    MCI_DI1_SRC:
++              case    MCI_DI2_SRC:
++              case    MCI_DIRSRC_RATE0_MSB:
++              case    MCI_DIRSRC_RATE0_LSB:
++              case    MCI_DIRSRC_RATE1_MSB:
++              case    MCI_DIRSRC_RATE1_LSB:
++              case    MCI_DIRSRC_RATE2_MSB:
++              case    MCI_DIRSRC_RATE2_LSB:
++              case    MCI_DIX0_FMT:
++              case    MCI_DIX1_FMT:
++              case    MCI_DIX2_FMT:
++              case    MCI_DIR0_CH:
++              case    MCI_DIR1_CH:
++              case    MCI_DIR2_CH:
++              case    MCI_DIT0_SLOT:
++              case    MCI_DIT1_SLOT:
++              case    MCI_DIT2_SLOT:
++              case    MCI_HIZ_REDGE0:
++              case    MCI_HIZ_REDGE1:
++              case    MCI_HIZ_REDGE2:
++              case    MCI_PCM_RX0:
++              case    MCI_PCM_RX1:
++              case    MCI_PCM_RX2:
++              case    MCI_PCM_SLOT_RX0:
++              case    MCI_PCM_SLOT_RX1:
++              case    MCI_PCM_SLOT_RX2:
++              case    MCI_PCM_TX0:
++              case    MCI_PCM_TX1:
++              case    MCI_PCM_TX2:
++              case    MCI_PCM_SLOT_TX0:
++              case    MCI_PCM_SLOT_TX1:
++              case    MCI_PCM_SLOT_TX2:
++              case    MCI_PDM_AGC:
++              case    MCI_PDM_STWAIT:
++                      break;
++              default:
++                      psPowerInfo->dDigital   &= ~(MCDRV_POWINFO_DIGITAL_DP0 | MCDRV_POWINFO_DIGITAL_DP1
++                                                                              | MCDRV_POWINFO_DIGITAL_DP2 | MCDRV_POWINFO_DIGITAL_PLLRST0 | MCDRV_POWINFO_DIGITAL_DPB);
++                      break;
++              }
++              break;
++
++      case    MCDRV_REGTYPE_B_CDSP:
++              break;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_GetPowerInfoRegAccess", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_GetCurPowerInfo
++ *
++ *    Description:
++ *                    Get current power setting.
++ *    Arguments:
++ *                    psPowerInfo     power information
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_GetCurPowerInfo
++(
++      MCDRV_POWER_INFO*       psPowerInfo
++)
++{
++      UINT8   bReg;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_GetCurPowerInfo");
++#endif
++
++
++      psPowerInfo->abAnalog[0]        = gsGlobalInfo.abRegValB_ANA[MCI_PWM_ANALOG_0];
++      psPowerInfo->abAnalog[1]        = gsGlobalInfo.abRegValB_ANA[MCI_PWM_ANALOG_1];
++      psPowerInfo->abAnalog[2]        = gsGlobalInfo.abRegValB_ANA[MCI_PWM_ANALOG_2];
++      psPowerInfo->abAnalog[3]        = gsGlobalInfo.abRegValB_ANA[MCI_PWM_ANALOG_3];
++      psPowerInfo->abAnalog[4]        = gsGlobalInfo.abRegValB_ANA[MCI_PWM_ANALOG_4];
++
++      psPowerInfo->dDigital   = 0;
++      bReg    = gsGlobalInfo.abRegValB_CODEC[MCI_DPADIF];
++      if((bReg & (MCB_DP0_CLKI1|MCB_DP0_CLKI0)) == (MCB_DP0_CLKI1|MCB_DP0_CLKI0))
++      {
++              psPowerInfo->dDigital   |= MCDRV_POWINFO_DIGITAL_DP0;
++      }
++      bReg    = gsGlobalInfo.abRegValB_BASE[MCI_PWM_DIGITAL];
++      if((bReg & MCB_PWM_DP1) == MCB_PWM_DP1)
++      {
++              psPowerInfo->dDigital   |= MCDRV_POWINFO_DIGITAL_DP1;
++      }
++      if((bReg & MCB_PWM_DP2) == MCB_PWM_DP2)
++      {
++              psPowerInfo->dDigital   |= MCDRV_POWINFO_DIGITAL_DP2;
++      }
++
++      bReg    = gsGlobalInfo.abRegValB_BASE[MCI_PWM_DIGITAL_1];
++      if((bReg & MCB_PWM_DPB) == MCB_PWM_DPB)
++      {
++              psPowerInfo->dDigital   |= MCDRV_POWINFO_DIGITAL_DPB;
++      }
++      if((bReg & MCB_PWM_DPDI0) == MCB_PWM_DPDI0)
++      {
++              psPowerInfo->dDigital   |= MCDRV_POWINFO_DIGITAL_DPDI0;
++      }
++      if((bReg & MCB_PWM_DPDI1) == MCB_PWM_DPDI1)
++      {
++              psPowerInfo->dDigital   |= MCDRV_POWINFO_DIGITAL_DPDI1;
++      }
++      if((bReg & MCB_PWM_DPDI2) == MCB_PWM_DPDI2)
++      {
++              psPowerInfo->dDigital   |= MCDRV_POWINFO_DIGITAL_DPDI2;
++      }
++      if((bReg & MCB_PWM_DPPDM) == MCB_PWM_DPPDM)
++      {
++              psPowerInfo->dDigital   |= MCDRV_POWINFO_DIGITAL_DPPDM;
++      }
++
++      bReg    = gsGlobalInfo.abRegValB_BASE[MCI_PWM_DIGITAL_BDSP];
++      if((bReg & MCB_PWM_DPBDSP) == MCB_PWM_DPBDSP)
++      {
++              psPowerInfo->dDigital   |= MCDRV_POWINFO_DIGITAL_DPBDSP;
++      }
++
++      bReg    = gsGlobalInfo.abRegValB_CODEC[MCI_PLL_RST];
++      if((bReg & MCB_PLLRST0) == MCB_PLLRST0)
++      {
++              psPowerInfo->dDigital   |= MCDRV_POWINFO_DIGITAL_PLLRST0;
++      }
++
++      bReg    = gsGlobalInfo.abRegValB_CODEC[MCI_DPADIF];
++      if((bReg & MCB_DPADIF) == MCB_DPADIF)
++      {
++              psPowerInfo->dDigital   |= MCDRV_POWINFO_DIGITAL_DPADIF;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_GetCurPowerInfo", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_GetDACSource
++ *
++ *    Description:
++ *                    Get DAC source information.
++ *    Arguments:
++ *                    eCh     0:Master/1:Voice
++ *    Return:
++ *                    path source(MCDRV_SRC_TYPE)
++ *
++ ****************************************************************************/
++MCDRV_SRC_TYPE        McResCtrl_GetDACSource
++(
++      MCDRV_DAC_CH    eCh
++)
++{
++      MCDRV_SRC_TYPE  eSrcType        = eMCDRV_SRC_NONE;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("McResCtrl_GetDACSource");
++#endif
++
++
++      if((gsGlobalInfo.sPathInfo.asDac[eCh].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON)
++      {
++              eSrcType        = eMCDRV_SRC_PDM;
++      }
++      else if((gsGlobalInfo.sPathInfo.asDac[eCh].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON)
++      {
++              eSrcType        = eMCDRV_SRC_ADC0;
++      }
++      else if((gsGlobalInfo.sPathInfo.asDac[eCh].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) == MCDRV_SRC3_DIR0_ON)
++      {
++              eSrcType        = eMCDRV_SRC_DIR0;
++      }
++      else if((gsGlobalInfo.sPathInfo.asDac[eCh].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) == MCDRV_SRC3_DIR1_ON)
++      {
++              eSrcType        = eMCDRV_SRC_DIR1;
++      }
++      else if((gsGlobalInfo.sPathInfo.asDac[eCh].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) == MCDRV_SRC3_DIR2_ON)
++      {
++              eSrcType        = eMCDRV_SRC_DIR2;
++      }
++      else if((gsGlobalInfo.sPathInfo.asDac[eCh].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & MCDRV_SRC6_MIX_ON) == MCDRV_SRC6_MIX_ON)
++      {
++              eSrcType        = eMCDRV_SRC_MIX;
++      }
++      else if((gsGlobalInfo.sPathInfo.asDac[eCh].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON)
++      {
++              eSrcType        = McResCtrl_GetAESource();
++      }
++      else
++      {
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = eSrcType;
++      McDebugLog_FuncOut("McResCtrl_GetDACSource", &sdRet);
++#endif
++      return eSrcType;
++}
++
++/****************************************************************************
++ *    McResCtrl_GetDITSource
++ *
++ *    Description:
++ *                    Get DIT source information.
++ *    Arguments:
++ *                    ePort   port number
++ *    Return:
++ *                    path source(MCDRV_SRC_TYPE)
++ *
++ ****************************************************************************/
++MCDRV_SRC_TYPE        McResCtrl_GetDITSource
++(
++      MCDRV_DIO_PORT_NO       ePort
++)
++{
++      MCDRV_SRC_TYPE  eSrcType        = eMCDRV_SRC_NONE;
++      MCDRV_CHANNEL*  pasDit          = NULL;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("McResCtrl_GetDITSource");
++#endif
++
++      if(ePort == 0)
++      {
++              pasDit  = &gsGlobalInfo.sPathInfo.asDit0[0];
++      }
++      else if(ePort == 1)
++      {
++              pasDit  = &gsGlobalInfo.sPathInfo.asDit1[0];
++      }
++      else if(ePort == 2)
++      {
++              pasDit  = &gsGlobalInfo.sPathInfo.asDit2[0];
++      }
++      else
++      {
++      }
++
++      if(pasDit != NULL)
++      {
++              if((pasDit->abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON)
++              {
++                      eSrcType        = eMCDRV_SRC_PDM;
++              }
++              else if((pasDit->abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON)
++              {
++                      eSrcType        = eMCDRV_SRC_ADC0;
++              }
++              else if((pasDit->abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) == MCDRV_SRC3_DIR0_ON)
++              {
++                      eSrcType        = eMCDRV_SRC_DIR0;
++              }
++              else if((pasDit->abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) == MCDRV_SRC3_DIR1_ON)
++              {
++                      eSrcType        = eMCDRV_SRC_DIR1;
++              }
++              else if((pasDit->abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) == MCDRV_SRC3_DIR2_ON)
++              {
++                      eSrcType        = eMCDRV_SRC_DIR2;
++              }
++              else if((pasDit->abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & MCDRV_SRC6_MIX_ON) == MCDRV_SRC6_MIX_ON)
++              {
++                      eSrcType        = eMCDRV_SRC_MIX;
++              }
++              else if((pasDit->abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON)
++              {
++                      eSrcType        = McResCtrl_GetAESource();
++              }
++              else
++              {
++              }
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = eSrcType;
++      McDebugLog_FuncOut("McResCtrl_GetDITSource", &sdRet);
++#endif
++
++      return eSrcType;
++}
++
++/****************************************************************************
++ *    McResCtrl_GetAESource
++ *
++ *    Description:
++ *                    Get AE source information.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    path source(MCDRV_SRC_TYPE)
++ *
++ ****************************************************************************/
++MCDRV_SRC_TYPE        McResCtrl_GetAESource
++(
++      void
++)
++{
++      MCDRV_SRC_TYPE  eSrcType        = eMCDRV_SRC_NONE;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("McResCtrl_GetAESource");
++#endif
++
++      if((gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON)
++      {
++              eSrcType        = eMCDRV_SRC_PDM;
++      }
++      else if((gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON)
++      {
++              eSrcType        = eMCDRV_SRC_ADC0;
++      }
++      else if((gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) == MCDRV_SRC3_DIR0_ON)
++      {
++              eSrcType        = eMCDRV_SRC_DIR0;
++      }
++      else if((gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) == MCDRV_SRC3_DIR1_ON)
++      {
++              eSrcType        = eMCDRV_SRC_DIR1;
++      }
++      else if((gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) == MCDRV_SRC3_DIR2_ON)
++      {
++              eSrcType        = eMCDRV_SRC_DIR2;
++      }
++      else if((gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & MCDRV_SRC6_MIX_ON) == MCDRV_SRC6_MIX_ON)
++      {
++              eSrcType        = eMCDRV_SRC_MIX;
++      }
++      else
++      {
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = eSrcType;
++      McDebugLog_FuncOut("McResCtrl_GetAESource", &sdRet);
++#endif
++
++      return eSrcType;
++}
++
++/****************************************************************************
++ *    McResCtrl_IsSrcUsed
++ *
++ *    Description:
++ *                    Is Src used
++ *    Arguments:
++ *                    ePathSrc        path src type
++ *    Return:
++ *                    0:unused/1:used
++ *
++ ****************************************************************************/
++UINT8 McResCtrl_IsSrcUsed
++(
++      MCDRV_SRC_TYPE  ePathSrc
++)
++{
++      UINT8   bUsed   = 0;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("McResCtrl_IsSrcUsed");
++#endif
++
++      switch(ePathSrc)
++      {
++      case    eMCDRV_SRC_MIC1:
++              if(((gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON)
++              || ((gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON)
++              || ((gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON)
++              || ((gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON)
++              || ((gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON))
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_MIC2:
++              if(((gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON)
++              || ((gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON)
++              || ((gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON)
++              || ((gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON)
++              || ((gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON))
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_MIC3:
++              if(((gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON)
++              || ((gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON)
++              || ((gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON)
++              || ((gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON)
++              || ((gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON))
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_LINE1_L:
++              if(((gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++              || ((gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++              || ((gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON))
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_LINE1_R:
++              if(((gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON)
++              || ((gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON)
++              || ((gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON))
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_LINE1_M:
++              if(((gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++              || ((gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++              || ((gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++              || ((gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++              || ((gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++              || ((gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON))
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_LINE2_L:
++              if(((gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE2_L_BLOCK] & MCDRV_SRC2_LINE2_L_ON) == MCDRV_SRC2_LINE2_L_ON)
++              || ((gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE2_L_BLOCK] & MCDRV_SRC2_LINE2_L_ON) == MCDRV_SRC2_LINE2_L_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE2_L_BLOCK] & MCDRV_SRC2_LINE2_L_ON) == MCDRV_SRC2_LINE2_L_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE2_L_BLOCK] & MCDRV_SRC2_LINE2_L_ON) == MCDRV_SRC2_LINE2_L_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE2_L_BLOCK] & MCDRV_SRC2_LINE2_L_ON) == MCDRV_SRC2_LINE2_L_ON)
++              || ((gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE2_L_BLOCK] & MCDRV_SRC2_LINE2_L_ON) == MCDRV_SRC2_LINE2_L_ON))
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_LINE2_R:
++              if(((gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_LINE2_R_BLOCK] & MCDRV_SRC2_LINE2_R_ON) == MCDRV_SRC2_LINE2_R_ON)
++              || ((gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE2_R_BLOCK] & MCDRV_SRC2_LINE2_R_ON) == MCDRV_SRC2_LINE2_R_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_LINE2_R_BLOCK] & MCDRV_SRC2_LINE2_R_ON) == MCDRV_SRC2_LINE2_R_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_LINE2_R_BLOCK] & MCDRV_SRC2_LINE2_R_ON) == MCDRV_SRC2_LINE2_R_ON)
++              || ((gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE2_R_BLOCK] & MCDRV_SRC2_LINE2_R_ON) == MCDRV_SRC2_LINE2_R_ON))
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_LINE2_M:
++              if(((gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE2_M_BLOCK] & MCDRV_SRC2_LINE2_M_ON) == MCDRV_SRC2_LINE2_M_ON)
++              || ((gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE2_M_BLOCK] & MCDRV_SRC2_LINE2_M_ON) == MCDRV_SRC2_LINE2_M_ON)
++              || ((gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE2_M_BLOCK] & MCDRV_SRC2_LINE2_M_ON) == MCDRV_SRC2_LINE2_M_ON)
++              || ((gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_LINE2_M_BLOCK] & MCDRV_SRC2_LINE2_M_ON) == MCDRV_SRC2_LINE2_M_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE2_M_BLOCK] & MCDRV_SRC2_LINE2_M_ON) == MCDRV_SRC2_LINE2_M_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE2_M_BLOCK] & MCDRV_SRC2_LINE2_M_ON) == MCDRV_SRC2_LINE2_M_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE2_M_BLOCK] & MCDRV_SRC2_LINE2_M_ON) == MCDRV_SRC2_LINE2_M_ON)
++              || ((gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE2_M_BLOCK] & MCDRV_SRC2_LINE2_M_ON) == MCDRV_SRC2_LINE2_M_ON)
++              || ((gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE2_M_BLOCK] & MCDRV_SRC2_LINE2_M_ON) == MCDRV_SRC2_LINE2_M_ON))
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_DIR0:
++              if(((gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) == MCDRV_SRC3_DIR0_ON)
++              || ((gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) == MCDRV_SRC3_DIR0_ON)
++              || ((gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) == MCDRV_SRC3_DIR0_ON)
++              || ((gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) == MCDRV_SRC3_DIR0_ON)
++              || ((gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) == MCDRV_SRC3_DIR0_ON)
++              || ((gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) == MCDRV_SRC3_DIR0_ON)
++              || ((gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) == MCDRV_SRC3_DIR0_ON))
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_DIR1:
++              if(((gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) == MCDRV_SRC3_DIR1_ON)
++              || ((gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) == MCDRV_SRC3_DIR1_ON)
++              || ((gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) == MCDRV_SRC3_DIR1_ON)
++              || ((gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) == MCDRV_SRC3_DIR1_ON)
++              || ((gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) == MCDRV_SRC3_DIR1_ON)
++              || ((gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) == MCDRV_SRC3_DIR1_ON)
++              || ((gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) == MCDRV_SRC3_DIR1_ON))
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_DIR2:
++              if(((gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) == MCDRV_SRC3_DIR2_ON)
++              || ((gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) == MCDRV_SRC3_DIR2_ON)
++              || ((gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) == MCDRV_SRC3_DIR2_ON)
++              || ((gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) == MCDRV_SRC3_DIR2_ON)
++              || ((gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) == MCDRV_SRC3_DIR2_ON)
++              || ((gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) == MCDRV_SRC3_DIR2_ON)
++              || ((gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) == MCDRV_SRC3_DIR2_ON))
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_DTMF:
++              break;
++
++      case    eMCDRV_SRC_PDM:
++              if(((gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON)
++              || ((gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON)
++              || ((gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON)
++              || ((gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON)
++              || ((gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON)
++              || ((gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON)
++              || ((gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON))
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_ADC0:
++              if(((gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON)
++              || ((gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON)
++              || ((gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON)
++              || ((gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON)
++              || ((gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON)
++              || ((gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON)
++              || ((gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON))
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_ADC1:
++              break;
++
++      case    eMCDRV_SRC_DAC_L:
++              if(((gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON)
++              || ((gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON)
++              || ((gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON))
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_DAC_R:
++              if(((gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON)
++              || ((gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON)
++              || ((gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON))
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_DAC_M:
++              if(((gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON)
++              || ((gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON)
++              || ((gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON)
++              || ((gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON))
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_AE:
++              if(((gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON)
++              || ((gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON)
++              || ((gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON)
++              || ((gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON)
++              || ((gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON)
++              || ((gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON))
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_CDSP:
++              break;
++
++      case    eMCDRV_SRC_MIX:
++              if(((gsGlobalInfo.sPathInfo.asDit0[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & MCDRV_SRC6_MIX_ON) == MCDRV_SRC6_MIX_ON)
++              || ((gsGlobalInfo.sPathInfo.asDit1[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & MCDRV_SRC6_MIX_ON) == MCDRV_SRC6_MIX_ON)
++              || ((gsGlobalInfo.sPathInfo.asDit2[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & MCDRV_SRC6_MIX_ON) == MCDRV_SRC6_MIX_ON)
++              || ((gsGlobalInfo.sPathInfo.asDac[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & MCDRV_SRC6_MIX_ON) == MCDRV_SRC6_MIX_ON)
++              || ((gsGlobalInfo.sPathInfo.asDac[1].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & MCDRV_SRC6_MIX_ON) == MCDRV_SRC6_MIX_ON)
++              || ((gsGlobalInfo.sPathInfo.asAe[0].abSrcOnOff[MCDRV_SRC_MIX_BLOCK] & MCDRV_SRC6_MIX_ON) == MCDRV_SRC6_MIX_ON))
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_SRC_DIR2_DIRECT:
++              break;
++
++      case    eMCDRV_SRC_CDSP_DIRECT:
++              break;
++
++      default:
++              break;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = (SINT32)bUsed;
++      McDebugLog_FuncOut("McResCtrl_IsSrcUsed", &sdRet);
++#endif
++
++      return bUsed;
++}
++
++/****************************************************************************
++ *    McResCtrl_IsDstUsed
++ *
++ *    Description:
++ *                    Is Destination used
++ *    Arguments:
++ *                    eType   path destination
++ *                    eCh             channel
++ *    Return:
++ *                    0:unused/1:used
++ *
++ ****************************************************************************/
++UINT8 McResCtrl_IsDstUsed
++(
++      MCDRV_DST_TYPE  eType,
++      MCDRV_DST_CH    eCh
++)
++{
++      UINT8   bUsed   = 0;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("McResCtrl_IsDstUsed");
++#endif
++
++      switch(eType)
++      {
++      case    eMCDRV_DST_HP:
++              if(eCh == eMCDRV_DST_CH0)
++              {
++                      if(((gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON)
++                      || ((gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON)
++                      || ((gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON)
++                      || ((gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++                      || ((gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++                      || ((gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON)
++                      || ((gsGlobalInfo.sPathInfo.asHpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON))
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else if(eCh == eMCDRV_DST_CH1)
++              {
++                      if(((gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON)
++                      || ((gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON)
++                      || ((gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON)
++                      || ((gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON)
++                      || ((gsGlobalInfo.sPathInfo.asHpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON))
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else
++              {
++              }
++              break;
++
++      case    eMCDRV_DST_SP:
++              if(eCh == eMCDRV_DST_CH0)
++              {
++                      if(((gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++                      || ((gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++                      || ((gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON)
++                      || ((gsGlobalInfo.sPathInfo.asSpOut[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON))
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else if(eCh == eMCDRV_DST_CH1)
++              {
++                      if(((gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON)
++                      || ((gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++                      || ((gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON)
++                      || ((gsGlobalInfo.sPathInfo.asSpOut[1].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON))
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else
++              {
++              }
++              break;
++
++      case    eMCDRV_DST_RCV:
++              if(eCh == eMCDRV_DST_CH0)
++              {
++                      if(((gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON)
++                      || ((gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON)
++                      || ((gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON)
++                      || ((gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++                      || ((gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON)
++                      || ((gsGlobalInfo.sPathInfo.asRcOut[0].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) ==MCDRV_SRC5_DAC_R_ON))
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else
++              {
++              }
++              break;
++
++      case    eMCDRV_DST_LOUT1:
++              if(eCh == eMCDRV_DST_CH0)
++              {
++                      if(((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON)
++                      || ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON)
++                      || ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON)
++                      || ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++                      || ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++                      || ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON)
++                      || ((gsGlobalInfo.sPathInfo.asLout1[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON))
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else if(eCh == eMCDRV_DST_CH1)
++              {
++                      if(((gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON)
++                      || ((gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON)
++                      || ((gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON)
++                      || ((gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON)
++                      || ((gsGlobalInfo.sPathInfo.asLout1[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON))
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else
++              {
++              }
++              break;
++
++      case    eMCDRV_DST_LOUT2:
++              if(eCh == eMCDRV_DST_CH0)
++              {
++                      if(((gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON)
++                      || ((gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON)
++                      || ((gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON)
++                      || ((gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++                      || ((gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON)
++                      || ((gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_L_BLOCK] & MCDRV_SRC5_DAC_L_ON) == MCDRV_SRC5_DAC_L_ON)
++                      || ((gsGlobalInfo.sPathInfo.asLout2[0].abSrcOnOff[MCDRV_SRC_DAC_M_BLOCK] & MCDRV_SRC5_DAC_M_ON) == MCDRV_SRC5_DAC_M_ON))
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else if(eCh == eMCDRV_DST_CH1)
++              {
++                      if(((gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON)
++                      || ((gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON)
++                      || ((gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON)
++                      || ((gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON)
++                      || ((gsGlobalInfo.sPathInfo.asLout2[1].abSrcOnOff[MCDRV_SRC_DAC_R_BLOCK] & MCDRV_SRC5_DAC_R_ON) == MCDRV_SRC5_DAC_R_ON))
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else
++              {
++              }
++              break;
++
++      case    eMCDRV_DST_PEAK:
++              break;
++
++      case    eMCDRV_DST_DIT0:
++              if(eCh == eMCDRV_DST_CH0)
++              {
++                      if(McResCtrl_GetDITSource(eMCDRV_DIO_0) != eMCDRV_SRC_NONE)
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else
++              {
++              }
++              break;
++
++      case    eMCDRV_DST_DIT1:
++              if(eCh == eMCDRV_DST_CH0)
++              {
++                      if(McResCtrl_GetDITSource(eMCDRV_DIO_1) != eMCDRV_SRC_NONE)
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else
++              {
++              }
++              break;
++
++      case    eMCDRV_DST_DIT2:
++              if(eCh == eMCDRV_DST_CH0)
++              {
++                      if(McResCtrl_GetDITSource(eMCDRV_DIO_2) != eMCDRV_SRC_NONE)
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else
++              {
++              }
++              break;
++
++      case    eMCDRV_DST_DAC:
++              if(eCh == eMCDRV_DST_CH0)
++              {
++                      if(McResCtrl_GetDACSource(eMCDRV_DAC_MASTER) != eMCDRV_SRC_NONE)
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else if(eCh == eMCDRV_DST_CH1)
++              {
++                      if(McResCtrl_GetDACSource(eMCDRV_DAC_VOICE) != eMCDRV_SRC_NONE)
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else
++              {
++              }
++              break;
++
++      case    eMCDRV_DST_AE:
++              if(eCh == eMCDRV_DST_CH0)
++              {
++                      if(McResCtrl_GetAESource() != eMCDRV_SRC_NONE)
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else
++              {
++              }
++              break;
++
++      case    eMCDRV_DST_CDSP:
++              break;
++
++      case    eMCDRV_DST_ADC0:
++              if(eCh == eMCDRV_DST_CH0)
++              {
++                      if(((gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON)
++                      || ((gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON)
++                      || ((gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON)
++                      || ((gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++                      || ((gsGlobalInfo.sPathInfo.asAdc0[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON))
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else if(eCh == eMCDRV_DST_CH1)
++              {
++                      if(((gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON)
++                      || ((gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON)
++                      || ((gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON)
++                      || ((gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_R_BLOCK] & MCDRV_SRC1_LINE1_R_ON) == MCDRV_SRC1_LINE1_R_ON)
++                      || ((gsGlobalInfo.sPathInfo.asAdc0[1].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON))
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else
++              {
++              }
++              break;
++
++      case    eMCDRV_DST_ADC1:
++              if(McDevProf_IsValid(eMCDRV_FUNC_ADC1) == 1)
++              {
++                      if(eCh == eMCDRV_DST_CH0)
++                      {
++                              if(((gsGlobalInfo.sPathInfo.asAdc1[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON)
++                              || ((gsGlobalInfo.sPathInfo.asAdc1[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON)
++                              || ((gsGlobalInfo.sPathInfo.asAdc1[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON)
++                              || ((gsGlobalInfo.sPathInfo.asAdc1[0].abSrcOnOff[MCDRV_SRC_LINE1_L_BLOCK] & MCDRV_SRC1_LINE1_L_ON) == MCDRV_SRC1_LINE1_L_ON)
++                              || ((gsGlobalInfo.sPathInfo.asAdc1[0].abSrcOnOff[MCDRV_SRC_LINE1_M_BLOCK] & MCDRV_SRC1_LINE1_M_ON) == MCDRV_SRC1_LINE1_M_ON))
++                              {
++                                      bUsed   = 1;
++                              }
++                      }
++                      else
++                      {
++                      }
++              }
++              break;
++
++      case    eMCDRV_DST_MIX:
++              if(eCh != 0)
++              {
++                      break;
++              }
++              if(((gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_PDM_BLOCK] & MCDRV_SRC4_PDM_ON) == MCDRV_SRC4_PDM_ON)
++              || ((gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_ADC0_BLOCK] & MCDRV_SRC4_ADC0_ON) == MCDRV_SRC4_ADC0_ON)
++              || ((gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR0_BLOCK] & MCDRV_SRC3_DIR0_ON) == MCDRV_SRC3_DIR0_ON)
++              || ((gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR1_BLOCK] & MCDRV_SRC3_DIR1_ON) == MCDRV_SRC3_DIR1_ON)
++              || ((gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_DIR2_BLOCK] & MCDRV_SRC3_DIR2_ON) == MCDRV_SRC3_DIR2_ON)
++              || ((gsGlobalInfo.sPathInfo.asMix[0].abSrcOnOff[MCDRV_SRC_AE_BLOCK] & MCDRV_SRC6_AE_ON) == MCDRV_SRC6_AE_ON))
++              {
++                      bUsed   = 1;
++              }
++              break;
++
++      case    eMCDRV_DST_BIAS:
++              if(eCh == eMCDRV_DST_CH0)
++              {
++                      if(((gsGlobalInfo.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC1_BLOCK] & MCDRV_SRC0_MIC1_ON) == MCDRV_SRC0_MIC1_ON)
++                      || ((gsGlobalInfo.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC2_BLOCK] & MCDRV_SRC0_MIC2_ON) == MCDRV_SRC0_MIC2_ON)
++                      || ((gsGlobalInfo.sPathInfo.asBias[0].abSrcOnOff[MCDRV_SRC_MIC3_BLOCK] & MCDRV_SRC0_MIC3_ON) == MCDRV_SRC0_MIC3_ON))
++                      {
++                              bUsed   = 1;
++                      }
++              }
++              else
++              {
++              }
++              break;
++
++      default:
++              break;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = (SINT32)bUsed;
++      McDebugLog_FuncOut("McResCtrl_IsDstUsed", &sdRet);
++#endif
++
++      return bUsed;
++}
++
++/****************************************************************************
++ *    McResCtrl_GetRegAccess
++ *
++ *    Description:
++ *                    Get register access availability
++ *    Arguments:
++ *                    psRegInfo       register information
++ *    Return:
++ *                    MCDRV_REG_ACCSESS
++ *
++ ****************************************************************************/
++MCDRV_REG_ACCSESS     McResCtrl_GetRegAccess
++(
++      const MCDRV_REG_INFO*   psRegInfo
++)
++{
++      MCDRV_REG_ACCSESS       eAccess = eMCDRV_ACCESS_DENY;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("McResCtrl_GetRegAccess");
++#endif
++
++      switch(psRegInfo->bRegType)
++      {
++      case    MCDRV_REGTYPE_A:
++              eAccess = gawRegAccessAvailableA[psRegInfo->bAddress];
++              break;
++      case    MCDRV_REGTYPE_B_BASE:
++              eAccess = gawRegAccessAvailableB_BASE[psRegInfo->bAddress];
++              break;
++      case    MCDRV_REGTYPE_B_ANALOG:
++              eAccess = gawRegAccessAvailableB_ANA[psRegInfo->bAddress];
++              break;
++      case    MCDRV_REGTYPE_B_CODEC:
++              eAccess = gawRegAccessAvailableB_CODEC[psRegInfo->bAddress];
++              break;
++      case    MCDRV_REGTYPE_B_MIXER:
++              eAccess = gawRegAccessAvailableB_MIX[psRegInfo->bAddress];
++              break;
++      case    MCDRV_REGTYPE_B_AE:
++              eAccess = gawRegAccessAvailableB_AE[psRegInfo->bAddress];
++              break;
++      default:
++              break;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = eAccess;
++      McDebugLog_FuncOut("McResCtrl_GetRegAccess", &sdRet);
++#endif
++
++      return eAccess;
++}
++
++/****************************************************************************
++ *    McResCtrl_GetAPMode
++ *
++ *    Description:
++ *                    get auto power management mode.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    eMCDRV_APM_ON
++ *                    eMCDRV_APM_OFF
++ *
++ ****************************************************************************/
++MCDRV_PMODE   McResCtrl_GetAPMode
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet   = gsGlobalInfo.eAPMode;
++      McDebugLog_FuncIn("McResCtrl_GetAPMode");
++#endif
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_GetAPMode", &sdRet);
++#endif
++
++      return gsGlobalInfo.eAPMode;
++}
++
++
++/****************************************************************************
++ *    McResCtrl_AllocPacketBuf
++ *
++ *    Description:
++ *                    allocate the buffer for register setting packets.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    pointer to the area to store packets
++ *
++ ****************************************************************************/
++MCDRV_PACKET* McResCtrl_AllocPacketBuf
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("McResCtrl_AllocPacketBuf");
++#endif
++
++      if(eMCDRV_PACKETBUF_ALLOCATED == gsGlobalInfo.ePacketBufAlloc)
++      {
++              #if (MCDRV_DEBUG_LEVEL>=4)
++                      sdRet   = 0;
++                      McDebugLog_FuncOut("McResCtrl_AllocPacketBuf", &sdRet);
++              #endif
++              return NULL;
++      }
++
++      gsGlobalInfo.ePacketBufAlloc = eMCDRV_PACKETBUF_ALLOCATED;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_AllocPacketBuf", 0);
++#endif
++      return gasPacket;
++}
++
++/****************************************************************************
++ *    McResCtrl_ReleasePacketBuf
++ *
++ *    Description:
++ *                    Release the buffer for register setting packets.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_ReleasePacketBuf
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_ReleasePacketBuf");
++#endif
++
++      gsGlobalInfo.ePacketBufAlloc = eMCDRV_PACKETBUF_FREE;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_ReleasePacketBuf", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_InitRegUpdate
++ *
++ *    Description:
++ *                    Initialize the process of register update.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_InitRegUpdate
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_InitRegUpdate");
++#endif
++
++      gsGlobalInfo.sCtrlPacket.wDataNum       = 0;
++      gsGlobalInfo.wCurSlaveAddress           = 0xFFFF;
++      gsGlobalInfo.wCurRegType                        = 0xFFFF;
++      gsGlobalInfo.wCurRegAddress                     = 0xFFFF;
++      gsGlobalInfo.wDataContinueCount         = 0;
++      gsGlobalInfo.wPrevAddressIndex          = 0;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_InitRegUpdate", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_AddRegUpdate
++ *
++ *    Description:
++ *                    Add register update packet and save register value.
++ *    Arguments:
++ *                    wRegType        register type
++ *                    wAddress        address
++ *                    bData           write data
++ *                    eUpdateMode     updete mode
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_AddRegUpdate
++(
++      UINT16  wRegType,
++      UINT16  wAddress,
++      UINT8   bData,
++      MCDRV_UPDATE_MODE       eUpdateMode
++)
++{
++      UINT8                   *pbRegVal;
++      UINT8                   bAddressADR;
++      UINT8                   bAddressWINDOW;
++      UINT8                   *pbCtrlData;
++      UINT16                  *pwCtrlDataNum;
++      const UINT16    *pwNextAddress;
++      UINT16                  wNextAddress;
++      UINT16                  wSlaveAddress;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_AddRegUpdate");
++#endif
++
++      switch (wRegType)
++      {
++      case MCDRV_PACKET_REGTYPE_A:
++              wSlaveAddress   = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              pbRegVal                = gsGlobalInfo.abRegValA;
++              pwNextAddress   = gawNextAddressA;
++              bAddressADR             = (UINT8)wAddress;
++              bAddressWINDOW  = bAddressADR;
++              if(MCDRV_A_REG_NUM <= wAddress)
++              {
++                      #if (MCDRV_DEBUG_LEVEL>=4)
++                              McDebugLog_FuncOut("McResCtrl_AddRegUpdate", 0);
++                      #endif
++                      return;
++              }
++              break;
++
++      case MCDRV_PACKET_REGTYPE_B_BASE:
++              wSlaveAddress   = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              pbRegVal                = gsGlobalInfo.abRegValB_BASE;
++              pwNextAddress   = gawNextAddressB_BASE;
++              bAddressADR             = MCI_BASE_ADR;
++              bAddressWINDOW  = MCI_BASE_WINDOW;
++              if(MCDRV_B_BASE_REG_NUM <= wAddress)
++              {
++                      #if (MCDRV_DEBUG_LEVEL>=4)
++                              McDebugLog_FuncOut("McResCtrl_AddRegUpdate", 0);
++                      #endif
++                      return;
++              }
++              break;
++
++      case MCDRV_PACKET_REGTYPE_B_CODEC:
++              wSlaveAddress   = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              pbRegVal                = gsGlobalInfo.abRegValB_CODEC;
++              pwNextAddress   = gawNextAddressB_CODEC;
++              bAddressADR             = MCI_CD_ADR;
++              bAddressWINDOW  = MCI_CD_WINDOW;
++              if(MCDRV_B_CODEC_REG_NUM <= wAddress)
++              {
++                      #if (MCDRV_DEBUG_LEVEL>=4)
++                              McDebugLog_FuncOut("McResCtrl_AddRegUpdate", 0);
++                      #endif
++                      return;
++              }
++              break;
++
++      case MCDRV_PACKET_REGTYPE_B_ANA:
++              wSlaveAddress   = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_ANA);
++              pbRegVal                = gsGlobalInfo.abRegValB_ANA;
++              pwNextAddress   = gawNextAddressB_Ana;
++              bAddressADR             = MCI_ANA_ADR;
++              bAddressWINDOW  = MCI_ANA_WINDOW;
++              if(MCDRV_B_ANA_REG_NUM <= wAddress)
++              {
++                      #if (MCDRV_DEBUG_LEVEL>=4)
++                              McDebugLog_FuncOut("McResCtrl_AddRegUpdate", 0);
++                      #endif
++                      return;
++              }
++              break;
++
++      case MCDRV_PACKET_REGTYPE_B_MIXER:
++              wSlaveAddress   = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              pbRegVal                = gsGlobalInfo.abRegValB_MIXER;
++              pwNextAddress   = gawNextAddressB_MIXER;
++              bAddressADR             = MCI_MIX_ADR;
++              bAddressWINDOW  = MCI_MIX_WINDOW;
++              if(MCDRV_B_MIXER_REG_NUM <= wAddress)
++              {
++                      #if (MCDRV_DEBUG_LEVEL>=4)
++                              McDebugLog_FuncOut("McResCtrl_AddRegUpdate", 0);
++                      #endif
++                      return;
++              }
++              break;
++
++      case MCDRV_PACKET_REGTYPE_B_AE:
++              wSlaveAddress   = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              pbRegVal                = gsGlobalInfo.abRegValB_AE;
++              pwNextAddress   = gawNextAddressB_AE;
++              bAddressADR             = MCI_AE_ADR;
++              bAddressWINDOW  = MCI_AE_WINDOW;
++              if(MCDRV_B_AE_REG_NUM <= wAddress)
++              {
++                      #if (MCDRV_DEBUG_LEVEL>=4)
++                              McDebugLog_FuncOut("McResCtrl_AddRegUpdate", 0);
++                      #endif
++                      return;
++              }
++              break;
++
++      case MCDRV_PACKET_REGTYPE_B_CDSP:
++              wSlaveAddress   = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              pbRegVal                = gsGlobalInfo.abRegValB_CDSP;
++              pwNextAddress   = gawNextAddressB_CDSP;
++              bAddressADR             = MCI_CDSP_ADR;
++              bAddressWINDOW  = MCI_CDSP_WINDOW;
++              if(MCDRV_B_CDSP_REG_NUM <= wAddress)
++              {
++                      #if (MCDRV_DEBUG_LEVEL>=4)
++                              McDebugLog_FuncOut("McResCtrl_AddRegUpdate", 0);
++                      #endif
++                      return;
++              }
++              break;
++
++      default:
++              #if (MCDRV_DEBUG_LEVEL>=4)
++                      McDebugLog_FuncOut("McResCtrl_AddRegUpdate", 0);
++              #endif
++              return;
++      }
++
++      if((gsGlobalInfo.wCurSlaveAddress != 0xFFFF) && (gsGlobalInfo.wCurSlaveAddress != wSlaveAddress))
++      {
++              McResCtrl_ExecuteRegUpdate();
++              McResCtrl_InitRegUpdate();
++      }
++
++      if((gsGlobalInfo.wCurRegType != 0xFFFF) && (gsGlobalInfo.wCurRegType != wRegType))
++      {
++              McResCtrl_ExecuteRegUpdate();
++              McResCtrl_InitRegUpdate();
++      }
++
++      if((eMCDRV_UPDATE_FORCE == eUpdateMode) || (bData != pbRegVal[wAddress]))
++      {
++              if(gsGlobalInfo.wCurRegAddress == 0xFFFF)
++              {
++                      gsGlobalInfo.wCurRegAddress     = wAddress;
++              }
++
++              if (eMCDRV_UPDATE_DUMMY != eUpdateMode)
++              {
++                      pbCtrlData              = gsGlobalInfo.sCtrlPacket.abData;
++                      pwCtrlDataNum   = &(gsGlobalInfo.sCtrlPacket.wDataNum);
++                      wNextAddress    = pwNextAddress[gsGlobalInfo.wCurRegAddress];
++
++                      if ((wSlaveAddress == gsGlobalInfo.wCurSlaveAddress)
++                      && (wRegType == gsGlobalInfo.wCurRegType)
++                      && (0xFFFF != wNextAddress)
++                      && (wAddress != wNextAddress))
++                      {
++                              if (pwNextAddress[wNextAddress] == wAddress)
++                              {
++                                      if (0 == gsGlobalInfo.wDataContinueCount)
++                                      {
++                                              pbCtrlData[gsGlobalInfo.wPrevAddressIndex] |= MCDRV_BURST_WRITE_ENABLE;
++                                      }
++                                      pbCtrlData[*pwCtrlDataNum]      = pbRegVal[wNextAddress];
++                                      (*pwCtrlDataNum)++;
++                                      gsGlobalInfo.wDataContinueCount++;
++                                      wNextAddress                            = pwNextAddress[wNextAddress];
++                              }
++                              else if ((0xFFFF != pwNextAddress[wNextAddress])
++                                              && (pwNextAddress[pwNextAddress[wNextAddress]] == wAddress))
++                              {
++                                      if (0 == gsGlobalInfo.wDataContinueCount)
++                                      {
++                                              pbCtrlData[gsGlobalInfo.wPrevAddressIndex] |= MCDRV_BURST_WRITE_ENABLE;
++                                      }
++                                      pbCtrlData[*pwCtrlDataNum]      = pbRegVal[wNextAddress];
++                                      (*pwCtrlDataNum)++;
++                                      pbCtrlData[*pwCtrlDataNum]      = pbRegVal[pwNextAddress[wNextAddress]];
++                                      (*pwCtrlDataNum)++;
++                                      gsGlobalInfo.wDataContinueCount += 2;
++                                      wNextAddress                            = pwNextAddress[pwNextAddress[wNextAddress]];
++                              }
++                              else
++                              {
++                              }
++                      }
++
++                      if ((0 == *pwCtrlDataNum) || (wAddress != wNextAddress))
++                      {
++                              if (0 != gsGlobalInfo.wDataContinueCount)
++                              {
++                                      McResCtrl_ExecuteRegUpdate();
++                                      McResCtrl_InitRegUpdate();
++                              }
++
++                              if (MCDRV_PACKET_REGTYPE_A == (UINT32)wRegType)
++                              {
++                                      pbCtrlData[*pwCtrlDataNum]              = (bAddressADR << 1);
++                                      gsGlobalInfo.wPrevAddressIndex  = *pwCtrlDataNum;
++                                      (*pwCtrlDataNum)++;
++                              }
++                              else
++                              {
++                                      pbCtrlData[(*pwCtrlDataNum)++]  = (bAddressADR << 1);
++                                      pbCtrlData[(*pwCtrlDataNum)++]  = (UINT8)wAddress;
++                                      pbCtrlData[*pwCtrlDataNum]              = (bAddressWINDOW << 1);
++                                      gsGlobalInfo.wPrevAddressIndex  = (*pwCtrlDataNum)++;
++                              }
++                      }
++                      else
++                      {
++                              if (0 == gsGlobalInfo.wDataContinueCount)
++                              {
++                                      pbCtrlData[gsGlobalInfo.wPrevAddressIndex] |= MCDRV_BURST_WRITE_ENABLE;
++                              }
++                              gsGlobalInfo.wDataContinueCount++;
++                      }
++
++                      pbCtrlData[(*pwCtrlDataNum)++]  = bData;
++              }
++
++              gsGlobalInfo.wCurSlaveAddress   = wSlaveAddress;
++              gsGlobalInfo.wCurRegType                = wRegType;
++              gsGlobalInfo.wCurRegAddress             = wAddress;
++
++              /* save register value */
++              pbRegVal[wAddress] = bData;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_AddRegUpdate", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_ExecuteRegUpdate
++ *
++ *    Description:
++ *                    Add register update packet and save register value.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McResCtrl_ExecuteRegUpdate
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_ExecuteRegUpdate");
++#endif
++
++      if (0 != gsGlobalInfo.sCtrlPacket.wDataNum)
++      {
++              McSrv_WriteI2C((UINT8)gsGlobalInfo.wCurSlaveAddress, gsGlobalInfo.sCtrlPacket.abData, gsGlobalInfo.sCtrlPacket.wDataNum);
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_ExecuteRegUpdate", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McResCtrl_WaitEvent
++ *
++ *    Description:
++ *                    Wait event.
++ *    Arguments:
++ *                    dEvent  event to wait
++ *                    dParam  event parameter
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++SINT32        McResCtrl_WaitEvent
++(
++      UINT32  dEvent,
++      UINT32  dParam
++)
++{
++      SINT32  sdRet   = MCDRV_SUCCESS;
++      UINT32  dInterval;
++      UINT32  dTimeOut;
++      UINT8   bSlaveAddr;
++      UINT8   abWriteData[2];
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McResCtrl_WaitEvent");
++#endif
++
++
++      switch(dEvent)
++      {
++      case    MCDRV_EVT_INSFLG:
++              dInterval       = gsGlobalInfo.sInitInfo.sWaitTime.dSvolInterval;
++              dTimeOut        = gsGlobalInfo.sInitInfo.sWaitTime.dSvolTimeOut;
++              bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              if((dParam>>8) != (UINT32)0)
++              {
++                      abWriteData[0]  = MCI_MIX_ADR<<1;
++                      abWriteData[1]  = MCI_DAC_INS_FLAG;
++                      McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++                      sdRet   = WaitBitRelease(bSlaveAddr, MCI_MIX_WINDOW, (UINT8)(dParam>>8), dInterval, dTimeOut);
++                      if(MCDRV_SUCCESS != sdRet)
++                      {
++                              break;
++                      }
++              }
++              else if((dParam&(UINT32)0xFF) != (UINT32)0)
++              {
++                      abWriteData[0]  = MCI_MIX_ADR<<1;
++                      abWriteData[1]  = MCI_INS_FLAG;
++                      McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++                      sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_MIX_WINDOW, (UINT8)(dParam&(UINT32)0xFF), dInterval, dTimeOut);
++              }
++              else
++              {
++              }
++              break;
++
++      case    MCDRV_EVT_ALLMUTE:
++              dInterval       = gsGlobalInfo.sInitInfo.sWaitTime.dSvolInterval;
++              dTimeOut        = gsGlobalInfo.sInitInfo.sWaitTime.dSvolTimeOut;
++              bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              abWriteData[0]  = MCI_MIX_ADR<<1;
++              abWriteData[1]  = MCI_DIT_INVFLAGL;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_MIX_WINDOW, (MCB_DIT0_INVFLAGL|MCB_DIT1_INVFLAGL|MCB_DIT2_INVFLAGL), dInterval, dTimeOut);
++              if(MCDRV_SUCCESS != sdRet)
++              {
++                      break;
++              }
++              abWriteData[0]  = MCI_MIX_ADR<<1;
++              abWriteData[1]  = MCI_DIT_INVFLAGR;
++              McSrv_WriteI2C(McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG), abWriteData, 2);
++              sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_MIX_WINDOW, (MCB_DIT0_INVFLAGR|MCB_DIT1_INVFLAGR|MCB_DIT2_INVFLAGR), dInterval, dTimeOut);
++              if(MCDRV_SUCCESS != sdRet)
++              {
++                      break;
++              }
++              abWriteData[0]  = MCI_MIX_ADR<<1;
++              abWriteData[1]  = MCI_DIR_VFLAGL;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_MIX_WINDOW, (MCB_PDM0_VFLAGL|MCB_DIR0_VFLAGL|MCB_DIR1_VFLAGL|MCB_DIR2_VFLAGL), dInterval, dTimeOut);
++              if(MCDRV_SUCCESS != sdRet)
++              {
++                      break;
++              }
++              abWriteData[0]  = MCI_MIX_ADR<<1;
++              abWriteData[1]  = MCI_DIR_VFLAGR;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_MIX_WINDOW, (MCB_PDM0_VFLAGR|MCB_DIR0_VFLAGR|MCB_DIR1_VFLAGR|MCB_DIR2_VFLAGR), dInterval, dTimeOut);
++              if(MCDRV_SUCCESS != sdRet)
++              {
++                      break;
++              }
++              abWriteData[0]  = MCI_MIX_ADR<<1;
++              abWriteData[1]  = MCI_AD_VFLAGL;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_MIX_WINDOW, (MCB_ADC_VFLAGL|MCB_AENG6_VFLAGL), dInterval, dTimeOut);
++              if(MCDRV_SUCCESS != sdRet)
++              {
++                      break;
++              }
++              abWriteData[0]  = MCI_MIX_ADR<<1;
++              abWriteData[1]  = MCI_AD_VFLAGR;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_MIX_WINDOW, (MCB_ADC_VFLAGR|MCB_AENG6_VFLAGR), dInterval, dTimeOut);
++              if(MCDRV_SUCCESS != sdRet)
++              {
++                      break;
++              }
++              abWriteData[0]  = MCI_MIX_ADR<<1;
++              abWriteData[1]  = MCI_AFLAGL;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_MIX_WINDOW, (MCB_ADC_AFLAGL|MCB_DIR0_AFLAGL|MCB_DIR1_AFLAGL|MCB_DIR2_AFLAGL), dInterval, dTimeOut);
++              if(MCDRV_SUCCESS != sdRet)
++              {
++                      break;
++              }
++              abWriteData[0]  = MCI_MIX_ADR<<1;
++              abWriteData[1]  = MCI_AFLAGR;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_MIX_WINDOW, (MCB_ADC_AFLAGR|MCB_DIR0_AFLAGR|MCB_DIR1_AFLAGR|MCB_DIR2_AFLAGR), dInterval, dTimeOut);
++              if(MCDRV_SUCCESS != sdRet)
++              {
++                      break;
++              }
++              abWriteData[0]  = MCI_MIX_ADR<<1;
++              abWriteData[1]  = MCI_DAC_FLAGL;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_MIX_WINDOW, (MCB_ST_FLAGL|MCB_MASTER_OFLAGL|MCB_VOICE_FLAGL|MCB_DAC_FLAGL), dInterval, dTimeOut);
++              if(MCDRV_SUCCESS != sdRet)
++              {
++                      break;
++              }
++              abWriteData[0]  = MCI_MIX_ADR<<1;
++              abWriteData[1]  = MCI_DAC_FLAGR;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_MIX_WINDOW, (MCB_ST_FLAGR|MCB_MASTER_OFLAGR|MCB_VOICE_FLAGR|MCB_DAC_FLAGR), dInterval, dTimeOut);
++              break;
++
++      case    MCDRV_EVT_DITMUTE:
++              dInterval       = gsGlobalInfo.sInitInfo.sWaitTime.dSvolInterval;
++              dTimeOut        = gsGlobalInfo.sInitInfo.sWaitTime.dSvolTimeOut;
++              bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              if((dParam>>8) != (UINT32)0)
++              {
++                      abWriteData[0]  = MCI_MIX_ADR<<1;
++                      abWriteData[1]  = MCI_DIT_INVFLAGL;
++                      McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++                      sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_MIX_WINDOW, (UINT8)(dParam>>8), dInterval, dTimeOut);
++                      if(MCDRV_SUCCESS != sdRet)
++                      {
++                              break;
++                      }
++              }
++              if((dParam&(UINT32)0xFF) != (UINT32)0)
++              {
++                      abWriteData[0]  = MCI_MIX_ADR<<1;
++                      abWriteData[1]  = MCI_DIT_INVFLAGR;
++                      McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++                      sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_MIX_WINDOW, (UINT8)(dParam&(UINT32)0xFF), dInterval, dTimeOut);
++              }
++              break;
++
++      case    MCDRV_EVT_DACMUTE:
++              dInterval       = gsGlobalInfo.sInitInfo.sWaitTime.dSvolInterval;
++              dTimeOut        = gsGlobalInfo.sInitInfo.sWaitTime.dSvolTimeOut;
++              bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              if((dParam>>8) != (UINT32)0)
++              {
++                      abWriteData[0]  = MCI_MIX_ADR<<1;
++                      abWriteData[1]  = MCI_DAC_FLAGL;
++                      McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++                      sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_MIX_WINDOW, (UINT8)(dParam>>8), dInterval, dTimeOut);
++                      if(MCDRV_SUCCESS != sdRet)
++                      {
++                              break;
++                      }
++              }
++              if((dParam&(UINT32)0xFF) != (UINT32)0)
++              {
++                      abWriteData[0]  = MCI_MIX_ADR<<1;
++                      abWriteData[1]  = MCI_DAC_FLAGR;
++                      McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++                      sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_MIX_WINDOW, (UINT8)(dParam&(UINT32)0xFF), dInterval, dTimeOut);
++              }
++              break;
++
++      case    MCDRV_EVT_SVOL_DONE:
++              dInterval       = gsGlobalInfo.sInitInfo.sWaitTime.dSvolInterval;
++              dTimeOut        = gsGlobalInfo.sInitInfo.sWaitTime.dSvolTimeOut;
++              bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_ANA);
++              if((dParam>>8) != (UINT32)0)
++              {
++                      abWriteData[0]  = MCI_ANA_ADR<<1;
++                      abWriteData[1]  = MCI_BUSY1;
++                      McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++                      sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_ANA_WINDOW, (UINT8)(dParam>>8), dInterval, dTimeOut);
++                      if(MCDRV_SUCCESS != sdRet)
++                      {
++                              break;
++                      }
++              }
++              if((dParam&(UINT32)0xFF) != (UINT32)0)
++              {
++                      abWriteData[0]  = MCI_ANA_ADR<<1;
++                      abWriteData[1]  = MCI_BUSY2;
++                      McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++                      sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_ANA_WINDOW, (UINT8)(dParam&(UINT8)0xFF), dInterval, dTimeOut);
++              }
++              break;
++
++      case    MCDRV_EVT_APM_DONE:
++              dInterval       = gsGlobalInfo.sInitInfo.sWaitTime.dSvolInterval;
++              dTimeOut        = gsGlobalInfo.sInitInfo.sWaitTime.dSvolTimeOut;
++              bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_ANA);
++              abWriteData[0]  = MCI_ANA_ADR<<1;
++              abWriteData[1]  = MCI_AP_A1;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitSet(bSlaveAddr, (UINT16)MCI_ANA_WINDOW, (UINT8)(dParam>>8), dInterval, dTimeOut);
++              if(MCDRV_SUCCESS != sdRet)
++              {
++                      break;
++              }
++              abWriteData[0]  = MCI_ANA_ADR<<1;
++              abWriteData[1]  = MCI_AP_A2;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitSet(bSlaveAddr, (UINT16)MCI_ANA_WINDOW, (UINT8)(dParam&(UINT8)0xFF), dInterval, dTimeOut);
++              break;
++
++      case    MCDRV_EVT_ANA_RDY:
++              dInterval       = gsGlobalInfo.sInitInfo.sWaitTime.dAnaRdyInterval;
++              dTimeOut        = gsGlobalInfo.sInitInfo.sWaitTime.dAnaRdyTimeOut;
++              bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_ANA);
++              abWriteData[0]  = MCI_ANA_ADR<<1;
++              abWriteData[1]  = MCI_RDY_FLAG;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitSet(bSlaveAddr, (UINT16)MCI_ANA_WINDOW, (UINT8)dParam, dInterval, dTimeOut);
++              break;
++
++      case    MCDRV_EVT_SYSEQ_FLAG_RESET:
++              dInterval       = gsGlobalInfo.sInitInfo.sWaitTime.dSvolInterval;
++              dTimeOut        = gsGlobalInfo.sInitInfo.sWaitTime.dSvolTimeOut;
++              bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              abWriteData[0]  = MCI_CD_ADR<<1;
++              abWriteData[1]  = MCI_SYSTEM_EQON;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_CD_WINDOW, MCB_SYSEQ_FLAG, dInterval, dTimeOut);
++              break;
++
++      case    MCDRV_EVT_CLKBUSY_RESET:
++              dInterval       = gsGlobalInfo.sInitInfo.sWaitTime.dSvolInterval;
++              dTimeOut        = gsGlobalInfo.sInitInfo.sWaitTime.dSvolTimeOut;
++              bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              abWriteData[0]  = MCI_CD_ADR<<1;
++              abWriteData[1]  = MCI_DPADIF;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_CD_WINDOW, MCB_CLKBUSY, dInterval, dTimeOut);
++              break;
++
++      case    MCDRV_EVT_CLKSRC_SET:
++              dInterval       = gsGlobalInfo.sInitInfo.sWaitTime.dSvolInterval;
++              dTimeOut        = gsGlobalInfo.sInitInfo.sWaitTime.dSvolTimeOut;
++              bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              abWriteData[0]  = MCI_CD_ADR<<1;
++              abWriteData[1]  = MCI_DPADIF;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitSet(bSlaveAddr, (UINT16)MCI_CD_WINDOW, MCB_CLKSRC, dInterval, dTimeOut);
++              break;
++
++      case    MCDRV_EVT_CLKSRC_RESET:
++              dInterval       = gsGlobalInfo.sInitInfo.sWaitTime.dSvolInterval;
++              dTimeOut        = gsGlobalInfo.sInitInfo.sWaitTime.dSvolTimeOut;
++              bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              abWriteData[0]  = MCI_CD_ADR<<1;
++              abWriteData[1]  = MCI_DPADIF;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_CD_WINDOW, MCB_CLKSRC, dInterval, dTimeOut);
++              break;
++
++      case    MCDRV_EVT_ADCMUTE:
++              dInterval       = gsGlobalInfo.sInitInfo.sWaitTime.dSvolInterval;
++              dTimeOut        = gsGlobalInfo.sInitInfo.sWaitTime.dSvolTimeOut;
++              bSlaveAddr      = McDevProf_GetSlaveAddr(eMCDRV_SLAVE_ADDR_DIG);
++              abWriteData[0]   = MCI_MIX_ADR<<1;
++              abWriteData[1]   = MCI_AD_VFLAGL;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_MIX_WINDOW, MCB_ADC_VFLAGL, dInterval, dTimeOut);
++              if(MCDRV_SUCCESS != sdRet)
++              {
++                       break;
++              }
++              abWriteData[1]   = MCI_AD_VFLAGR;
++              McSrv_WriteI2C(bSlaveAddr, abWriteData, 2);
++              sdRet   = WaitBitRelease(bSlaveAddr, (UINT16)MCI_MIX_WINDOW, MCB_ADC_VFLAGR, dInterval, dTimeOut);
++              break;
++
++
++      default:
++              sdRet   = MCDRV_ERROR_ARGUMENT;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McResCtrl_WaitEvent", &sdRet);
++#endif
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    WaitBitSet
++ *
++ *    Description:
++ *                    Wait register bit to set.
++ *    Arguments:
++ *                    bSlaveAddr      slave address
++ *                    wRegAddr        register address
++ *                    bBit            bit
++ *                    dCycleTime      cycle time to poll [us]
++ *                    dTimeOut        number of read cycles for time out
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++static SINT32 WaitBitSet
++(
++      UINT8   bSlaveAddr,
++      UINT16  wRegAddr,
++      UINT8   bBit,
++      UINT32  dCycleTime,
++      UINT32  dTimeOut
++)
++{
++      UINT8   bData;
++      UINT32  dCycles;
++      SINT32  sdRet;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("WaitBitSet");
++#endif
++
++
++      dCycles = 0;
++      sdRet   = MCDRV_ERROR_TIMEOUT;
++
++      while(dCycles < dTimeOut)
++      {
++              bData   = McSrv_ReadI2C(bSlaveAddr, wRegAddr);
++              if((bData & bBit) == bBit)
++              {
++                      sdRet   = MCDRV_SUCCESS;
++                      break;
++              }
++
++              McSrv_Sleep(dCycleTime);
++              dCycles++;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("WaitBitSet", &sdRet);
++#endif
++
++      return sdRet;
++}
++
++/****************************************************************************
++ *    WaitBitRelease
++ *
++ *    Description:
++ *                    Wait register bit to release.
++ *    Arguments:
++ *                    bSlaveAddr      slave address
++ *                    wRegAddr        register address
++ *                    bBit            bit
++ *                    dCycleTime      cycle time to poll [us]
++ *                    dTimeOut        number of read cycles for time out
++ *    Return:
++ *                    MCDRV_SUCCESS
++ *                    MCDRV_ERROR_TIMEOUT
++ *
++ ****************************************************************************/
++static SINT32 WaitBitRelease
++(
++      UINT8   bSlaveAddr,
++      UINT16  wRegAddr,
++      UINT8   bBit,
++      UINT32  dCycleTime,
++      UINT32  dTimeOut
++)
++{
++      UINT8   bData;
++      UINT32  dCycles;
++      SINT32  sdRet;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("WaitBitRelease");
++#endif
++
++
++      dCycles = 0;
++      sdRet   = MCDRV_ERROR_TIMEOUT;
++
++      while(dCycles < dTimeOut)
++      {
++              bData   = McSrv_ReadI2C(bSlaveAddr, wRegAddr);
++              if(0 == (bData & bBit))
++              {
++                      sdRet   = MCDRV_SUCCESS;
++                      break;
++              }
++
++              McSrv_Sleep(dCycleTime);
++              dCycles++;
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("WaitBitRelease", &sdRet);
++#endif
++
++      return sdRet;
++}
++
+diff --git a/sound/soc/codecs/mc1n2/mcresctrl.h b/sound/soc/codecs/mc1n2/mcresctrl.h
+new file mode 100644
+index 0000000..b5f1399
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mcresctrl.h
+@@ -0,0 +1,263 @@
++/****************************************************************************
++ *
++ *            Copyright(c) 2010 Yamaha Corporation. All rights reserved.
++ *
++ *            Module          : mcresctrl.h
++ *
++ *            Description     : MC Driver resource control header
++ *
++ *            Version         : 1.0.0         2010.09.01
++ *
++ ****************************************************************************/
++
++#ifndef _MCRESCTRL_H_
++#define _MCRESCTRL_H_
++
++#include "mcdevif.h"
++#include "mcpacking.h"
++
++/* HW_ID */
++#define       MCDRV_HWID_AA   (0x78)
++#define       MCDRV_HWID_AB   (0x79)
++
++#define       MCDRV_BURST_WRITE_ENABLE        (0x01)
++
++/*    eState setting  */
++typedef enum _MCDRV_STATE
++{
++      eMCDRV_STATE_NOTINIT,
++      eMCDRV_STATE_READY
++} MCDRV_STATE;
++
++/*    volume setting  */
++#define       MCDRV_LOGICAL_VOL_MUTE          (-24576)        /*      -96dB   */
++#define       MCDRV_LOGICAL_MICGAIN_DEF       (3840)          /*      15dB    */
++#define       MCDRV_LOGICAL_HPGAIN_DEF        (0)                     /*      0dB             */
++
++#define       MCDRV_VOLUPDATE_ALL                     (0xFFFFFFFFUL)
++#define       MCDRV_VOLUPDATE_ANAOUT_ALL      (0x00000001UL)
++
++#define       MCDRV_REG_MUTE  (0x00)
++
++/*    DAC source setting      */
++typedef enum _MCDRV_DAC_CH
++{
++      eMCDRV_DAC_MASTER       = 0,
++      eMCDRV_DAC_VOICE
++} MCDRV_DAC_CH;
++
++/*    DIO port setting        */
++typedef enum _MCDRV_DIO_PORT_NO
++{
++      eMCDRV_DIO_0    = 0,
++      eMCDRV_DIO_1,
++      eMCDRV_DIO_2
++} MCDRV_DIO_PORT_NO;
++
++/*    Path source setting     */
++typedef enum _MCDRV_SRC_TYPE
++{
++      eMCDRV_SRC_NONE                 = (0),
++      eMCDRV_SRC_MIC1                 = (1<<0),
++      eMCDRV_SRC_MIC2                 = (1<<1),
++      eMCDRV_SRC_MIC3                 = (1<<2),
++      eMCDRV_SRC_LINE1_L              = (1<<3),
++      eMCDRV_SRC_LINE1_R              = (1<<4),
++      eMCDRV_SRC_LINE1_M              = (1<<5),
++      eMCDRV_SRC_LINE2_L              = (1<<6),
++      eMCDRV_SRC_LINE2_R              = (1<<7),
++      eMCDRV_SRC_LINE2_M              = (1<<8),
++      eMCDRV_SRC_DIR0                 = (1<<9),
++      eMCDRV_SRC_DIR1                 = (1<<10),
++      eMCDRV_SRC_DIR2                 = (1<<11),
++      eMCDRV_SRC_DTMF                 = (1<<12),
++      eMCDRV_SRC_PDM                  = (1<<13),
++      eMCDRV_SRC_ADC0                 = (1<<14),
++      eMCDRV_SRC_ADC1                 = (1<<15),
++      eMCDRV_SRC_DAC_L                = (1<<16),
++      eMCDRV_SRC_DAC_R                = (1<<17),
++      eMCDRV_SRC_DAC_M                = (1<<18),
++      eMCDRV_SRC_AE                   = (1<<19),
++      eMCDRV_SRC_CDSP                 = (1<<20),
++      eMCDRV_SRC_MIX                  = (1<<21),
++      eMCDRV_SRC_DIR2_DIRECT  = (1<<22),
++      eMCDRV_SRC_CDSP_DIRECT  = (1<<23)
++} MCDRV_SRC_TYPE;
++
++/*    Path destination setting        */
++typedef enum _MCDRV_DST_CH
++{
++      eMCDRV_DST_CH0  = 0,
++      eMCDRV_DST_CH1
++} MCDRV_DST_CH;
++typedef enum _MCDRV_DST_TYPE
++{
++      eMCDRV_DST_HP   = 0,
++      eMCDRV_DST_SP,
++      eMCDRV_DST_RCV,
++      eMCDRV_DST_LOUT1,
++      eMCDRV_DST_LOUT2,
++      eMCDRV_DST_PEAK,
++      eMCDRV_DST_DIT0,
++      eMCDRV_DST_DIT1,
++      eMCDRV_DST_DIT2,
++      eMCDRV_DST_DAC,
++      eMCDRV_DST_AE,
++      eMCDRV_DST_CDSP,
++      eMCDRV_DST_ADC0,
++      eMCDRV_DST_ADC1,
++      eMCDRV_DST_MIX,
++      eMCDRV_DST_BIAS
++} MCDRV_DST_TYPE;
++
++/*    Register accsess availability   */
++typedef enum _MCDRV_REG_ACCSESS
++{
++      eMCDRV_ACCESS_DENY      = 0,
++      eMCDRV_READ_ONLY        = 0x01,
++      eMCDRV_WRITE_ONLY       = 0x02,
++      eMCDRV_READ_WRITE       = eMCDRV_READ_ONLY | eMCDRV_WRITE_ONLY
++} MCDRV_REG_ACCSESS;
++
++
++/*    UpdateReg parameter     */
++typedef enum _MCDRV_UPDATE_MODE
++{
++      eMCDRV_UPDATE_NORMAL,
++      eMCDRV_UPDATE_FORCE,
++      eMCDRV_UPDATE_DUMMY
++} MCDRV_UPDATE_MODE;
++
++/*    ePacketBufAlloc setting */
++typedef enum _MCDRV_PACKETBUF_ALLOC
++{
++      eMCDRV_PACKETBUF_FREE,
++      eMCDRV_PACKETBUF_ALLOCATED
++} MCDRV_PACKETBUF_ALLOC;
++
++/* power management sequence mode */
++typedef enum _MCDRV_PMODE
++{
++      eMCDRV_APM_ON,
++      eMCDRV_APM_OFF
++} MCDRV_PMODE;
++
++#define       MCDRV_A_REG_NUM                 (64)
++#define       MCDRV_B_BASE_REG_NUM    (32)
++#define       MCDRV_B_MIXER_REG_NUM   (218)
++#define       MCDRV_B_AE_REG_NUM              (255)
++#define       MCDRV_B_CDSP_REG_NUM    (130)
++#define       MCDRV_B_CODEC_REG_NUM   (128)
++#define       MCDRV_B_ANA_REG_NUM             (128)
++
++/* control packet for serial host interface */
++#define       MCDRV_MAX_CTRL_DATA_NUM (1024)
++typedef struct
++{
++      UINT8   abData[MCDRV_MAX_CTRL_DATA_NUM];
++      UINT16  wDataNum;
++} MCDRV_SERIAL_CTRL_PACKET;
++
++/*    global information      */
++typedef struct
++{
++      UINT8                                           bHwId;
++      MCDRV_PACKETBUF_ALLOC           ePacketBufAlloc;
++      UINT8                                           abRegValA[MCDRV_A_REG_NUM];
++      UINT8                                           abRegValB_BASE[MCDRV_B_BASE_REG_NUM];
++      UINT8                                           abRegValB_MIXER[MCDRV_B_MIXER_REG_NUM];
++      UINT8                                           abRegValB_AE[MCDRV_B_AE_REG_NUM];
++      UINT8                                           abRegValB_CDSP[MCDRV_B_CDSP_REG_NUM];
++      UINT8                                           abRegValB_CODEC[MCDRV_B_CODEC_REG_NUM];
++      UINT8                                           abRegValB_ANA[MCDRV_B_ANA_REG_NUM];
++
++      MCDRV_INIT_INFO                         sInitInfo;
++      MCDRV_PATH_INFO                         sPathInfo;
++      MCDRV_PATH_INFO                         sPathInfoVirtual;
++      MCDRV_VOL_INFO                          sVolInfo;
++      MCDRV_DIO_INFO                          sDioInfo;
++      MCDRV_DAC_INFO                          sDacInfo;
++      MCDRV_ADC_INFO                          sAdcInfo;
++      MCDRV_SP_INFO                           sSpInfo;
++      MCDRV_DNG_INFO                          sDngInfo;
++      MCDRV_AE_INFO                           sAeInfo;
++      MCDRV_PDM_INFO                          sPdmInfo;
++      MCDRV_GP_MODE                           sGpMode;
++      UINT8                                           abGpMask[GPIO_PAD_NUM];
++      MCDRV_SYSEQ_INFO                        sSysEq;
++      MCDRV_CLKSW_INFO                        sClockSwitch;
++
++      MCDRV_SERIAL_CTRL_PACKET        sCtrlPacket;
++      UINT16                                          wCurSlaveAddress;
++      UINT16                                          wCurRegType;
++      UINT16                                          wCurRegAddress;
++      UINT16                                          wDataContinueCount;
++      UINT16                                          wPrevAddressIndex;
++
++      MCDRV_PMODE                                     eAPMode;
++} MCDRV_GLOBAL_INFO;
++
++
++
++SINT32                        McResCtrl_SetHwId                               (UINT8 bHwId);
++UINT8                 McResCtrl_GetHwId                               (void);
++void                  McResCtrl_Init                                  (const MCDRV_INIT_INFO* psInitInfo);
++void                  McResCtrl_UpdateState                   (MCDRV_STATE eState);
++MCDRV_STATE           McResCtrl_GetState                              (void);
++UINT8                 McResCtrl_GetRegVal                             (UINT16 wRegType, UINT16 wRegAddr);
++void                  McResCtrl_SetRegVal                             (UINT16 wRegType, UINT16 wRegAddr, UINT8 bRegVal);
++
++void                  McResCtrl_GetInitInfo                   (MCDRV_INIT_INFO* psInitInfo);
++void                  McResCtrl_SetClockInfo                  (const MCDRV_CLOCK_INFO* psClockInfo);
++void                  McResCtrl_SetPathInfo                   (const MCDRV_PATH_INFO* psPathInfo);
++void                  McResCtrl_GetPathInfo                   (MCDRV_PATH_INFO* psPathInfo);
++void                  McResCtrl_GetPathInfoVirtual    (MCDRV_PATH_INFO* psPathInfo);
++void                  McResCtrl_SetDioInfo                    (const MCDRV_DIO_INFO* psDioInfo, UINT32 dUpdateInfo);
++void                  McResCtrl_GetDioInfo                    (MCDRV_DIO_INFO* psDioInfo);
++void                  McResCtrl_SetVolInfo                    (const MCDRV_VOL_INFO* psVolInfo);
++void                  McResCtrl_GetVolInfo                    (MCDRV_VOL_INFO* psVolInfo);
++void                  McResCtrl_SetDacInfo                    (const MCDRV_DAC_INFO* psDacInfo, UINT32 dUpdateInfo);
++void                  McResCtrl_GetDacInfo                    (MCDRV_DAC_INFO* psDacInfo);
++void                  McResCtrl_SetAdcInfo                    (const MCDRV_ADC_INFO* psAdcInfo, UINT32 dUpdateInfo);
++void                  McResCtrl_GetAdcInfo                    (MCDRV_ADC_INFO* psAdcInfo);
++void                  McResCtrl_SetSpInfo                             (const MCDRV_SP_INFO* psSpInfo);
++void                  McResCtrl_GetSpInfo                             (MCDRV_SP_INFO* psSpInfo);
++void                  McResCtrl_SetDngInfo                    (const MCDRV_DNG_INFO* psDngInfo, UINT32 dUpdateInfo);
++void                  McResCtrl_GetDngInfo                    (MCDRV_DNG_INFO* psDngInfo);
++void                  McResCtrl_SetAeInfo                             (const MCDRV_AE_INFO* psAeInfo, UINT32 dUpdateInfo);
++void                  McResCtrl_GetAeInfo                             (MCDRV_AE_INFO* psAeInfo);
++void                  McResCtrl_SetPdmInfo                    (const MCDRV_PDM_INFO* psPdmInfo, UINT32 dUpdateInfo);
++void                  McResCtrl_GetPdmInfo                    (MCDRV_PDM_INFO* psPdmInfo);
++void                  McResCtrl_SetGPMode                             (const MCDRV_GP_MODE* psGpMode);
++void                  McResCtrl_GetGPMode                             (MCDRV_GP_MODE* psGpMode);
++void                  McResCtrl_SetGPMask                             (UINT8 bMask, UINT32 dPadNo);
++void                  McResCtrl_GetGPMask                             (UINT8* pabMask);
++void                  McResCtrl_GetSysEq                              (MCDRV_SYSEQ_INFO* psSysEq);
++void                  McResCtrl_SetSysEq                              (const MCDRV_SYSEQ_INFO* psSysEq, UINT32 dUpdateInfo);
++void                  McResCtrl_GetClockSwitch                (MCDRV_CLKSW_INFO* psClockInfo);
++void                  McResCtrl_SetClockSwitch                (const MCDRV_CLKSW_INFO* psClockInfo);
++
++void                  McResCtrl_GetVolReg                             (MCDRV_VOL_INFO* psVolInfo);
++void                  McResCtrl_GetPowerInfo                  (MCDRV_POWER_INFO* psPowerInfo);
++void                  McResCtrl_GetPowerInfoRegAccess (const MCDRV_REG_INFO* psRegInfo, MCDRV_POWER_INFO* psPowerInfo);
++void                  McResCtrl_GetCurPowerInfo               (MCDRV_POWER_INFO* psPowerInfo);
++MCDRV_SRC_TYPE        McResCtrl_GetDACSource                  (MCDRV_DAC_CH eCh);
++MCDRV_SRC_TYPE        McResCtrl_GetDITSource                  (MCDRV_DIO_PORT_NO ePort);
++MCDRV_SRC_TYPE        McResCtrl_GetAESource                   (void);
++UINT8                 McResCtrl_IsSrcUsed                             (MCDRV_SRC_TYPE ePathSrc);
++UINT8                 McResCtrl_IsDstUsed                             (MCDRV_DST_TYPE eType, MCDRV_DST_CH eCh);
++MCDRV_REG_ACCSESS     McResCtrl_GetRegAccess          (const MCDRV_REG_INFO* psRegInfo);
++
++MCDRV_PMODE           McResCtrl_GetAPMode                             (void);
++
++MCDRV_PACKET* McResCtrl_AllocPacketBuf                (void);
++void                  McResCtrl_ReleasePacketBuf              (void);
++
++void                  McResCtrl_InitRegUpdate                 (void);
++void                  McResCtrl_AddRegUpdate                  (UINT16 wRegType, UINT16 wAddress, UINT8 bData, MCDRV_UPDATE_MODE eUpdateMode);
++void                  McResCtrl_ExecuteRegUpdate              (void);
++SINT32                        McResCtrl_WaitEvent                             (UINT32 dEvent, UINT32 dParam);
++
++
++
++#endif /* _MCRESCTRL_H_ */
+diff --git a/sound/soc/codecs/mc1n2/mcservice.c b/sound/soc/codecs/mc1n2/mcservice.c
+new file mode 100644
+index 0000000..27ee6d5
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mcservice.c
+@@ -0,0 +1,365 @@
++/****************************************************************************
++ *
++ *            Copyright(c) 2010 Yamaha Corporation. All rights reserved.
++ *
++ *            Module          : mcservice.c
++ *
++ *            Description     : MC Driver service routine
++ *
++ *            Version         : 1.0.0         2010.09.10
++ *
++ ****************************************************************************/
++
++
++#include "mcservice.h"
++#include "mcmachdep.h"
++#if (MCDRV_DEBUG_LEVEL>=4)
++#include "mcdebuglog.h"
++#endif
++
++
++/****************************************************************************
++ *    McSrv_SystemInit
++ *
++ *    Description:
++ *                    Initialize the system.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McSrv_SystemInit
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McSrv_SystemInit");
++#endif
++
++      machdep_SystemInit();
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McSrv_SystemInit", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McSrv_SystemTerm
++ *
++ *    Description:
++ *                    Terminate the system.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McSrv_SystemTerm
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McSrv_SystemTerm");
++#endif
++
++      machdep_SystemTerm();
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McSrv_SystemTerm", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McSrv_ClockStart
++ *
++ *    Description:
++ *                    Start clock.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McSrv_ClockStart
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McSrv_ClockStart");
++#endif
++
++      machdep_ClockStart();
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McSrv_ClockStart", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McSrv_ClockStop
++ *
++ *    Description:
++ *                    Stop clock.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McSrv_ClockStop
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McSrv_ClockStop");
++#endif
++
++      machdep_ClockStop();
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McSrv_ClockStop", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McSrv_WriteI2C
++ *
++ *    Description:
++ *                    Write data to register.
++ *    Arguments:
++ *                    bSlaveAddr      slave address
++ *                    pbData          data
++ *                    dSize           data size
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McSrv_WriteI2C
++(
++      UINT8   bSlaveAddr,
++      UINT8   *pbData,
++      UINT32  dSize
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McSrv_WriteI2C");
++#endif
++
++      McSrv_DisableIrq();
++      machdep_WriteI2C( bSlaveAddr, pbData, dSize );
++      McSrv_EnableIrq();
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McSrv_WriteI2C", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McSrv_ReadI2C
++ *
++ *    Function:
++ *                    Read a byte data from the register.
++ *    Arguments:
++ *                    bSlaveAddr      slave address
++ *                    dRegAddr        address of register
++ *    Return:
++ *                    read data
++ *
++ ****************************************************************************/
++UINT8 McSrv_ReadI2C
++(
++      UINT8   bSlaveAddr,
++      UINT32  dRegAddr
++)
++{
++      UINT8   bReg;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      SINT32  sdRet;
++      McDebugLog_FuncIn("McSrv_ReadI2C");
++#endif
++
++      McSrv_DisableIrq();
++      bReg    = machdep_ReadI2C( bSlaveAddr, dRegAddr );
++      McSrv_EnableIrq();
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      sdRet   = (SINT32)bReg;
++      McDebugLog_FuncOut("McSrv_ReadI2C", &sdRet);
++#endif
++
++      return bReg;
++}
++
++/***************************************************************************
++ *    McSrv_Sleep
++ *
++ *    Function:
++ *                    Sleep for a specified interval.
++ *    Arguments:
++ *                    dSleepTime      sleep time [us]
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McSrv_Sleep
++(
++      UINT32  dSleepTime
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McSrv_Sleep");
++#endif
++
++      machdep_Sleep( dSleepTime );
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McSrv_Sleep", 0);
++#endif
++}
++
++/****************************************************************************
++ *    McSrv_Lock
++ *
++ *    Description:
++ *                    Lock a call of the driver.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McSrv_Lock
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McSrv_Lock");
++#endif
++
++      machdep_Lock();
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McSrv_Lock", 0);
++#endif
++}
++
++/***************************************************************************
++ *    McSrv_Unlock
++ *
++ *    Function:
++ *                    Unlock a call of the driver.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McSrv_Unlock
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McSrv_Unlock");
++#endif
++
++      machdep_Unlock();
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McSrv_Unlock", 0);
++#endif
++}
++
++/***************************************************************************
++ *    McSrv_MemCopy
++ *
++ *    Function:
++ *                    Copy memory.
++ *    Arguments:
++ *                    pbSrc   copy source
++ *                    pbDest  copy destination
++ *                    dSize   size
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McSrv_MemCopy
++(
++      const UINT8     *pbSrc,
++      UINT8           *pbDest,
++      UINT32          dSize
++)
++{
++      UINT32  i;
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McSrv_MemCopy");
++#endif
++
++      for ( i = 0; i < dSize; i++ )
++      {
++              pbDest[i] = pbSrc[i];
++      }
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McSrv_MemCopy", 0);
++#endif
++}
++
++/***************************************************************************
++ *    McSrv_DisableIrq
++ *
++ *    Function:
++ *                    Disable interrupt.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McSrv_DisableIrq
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McSrv_DisableIrq");
++#endif
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McSrv_DisableIrq", 0);
++#endif
++}
++
++/***************************************************************************
++ *    McSrv_EnableIrq
++ *
++ *    Function:
++ *                    Enable interrupt.
++ *    Arguments:
++ *                    none
++ *    Return:
++ *                    none
++ *
++ ****************************************************************************/
++void  McSrv_EnableIrq
++(
++      void
++)
++{
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncIn("McSrv_EnableIrq");
++#endif
++
++#if (MCDRV_DEBUG_LEVEL>=4)
++      McDebugLog_FuncOut("McSrv_EnableIrq", 0);
++#endif
++}
++
+diff --git a/sound/soc/codecs/mc1n2/mcservice.h b/sound/soc/codecs/mc1n2/mcservice.h
+new file mode 100644
+index 0000000..3d72722
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mcservice.h
+@@ -0,0 +1,34 @@
++/****************************************************************************
++ *
++ *            Copyright(c) 2010 Yamaha Corporation. All rights reserved.
++ *
++ *            Module          : mcservice.h
++ *
++ *            Description     : MC Driver service routine header
++ *
++ *            Version         : 1.0.0         2010.03.18
++ *
++ ****************************************************************************/
++
++#ifndef _MCSERVICE_H_
++#define _MCSERVICE_H_
++
++#include "mctypedef.h"
++
++
++void  McSrv_SystemInit        ( void );
++void  McSrv_SystemTerm        ( void );
++void  McSrv_ClockStart        ( void );
++void  McSrv_ClockStop         ( void );
++void  McSrv_WriteI2C          ( UINT8 bSlaveAddr, UINT8 *pbData, UINT32 dSize );
++UINT8 McSrv_ReadI2C           ( UINT8 bSlaveAddr, UINT32 dRegAddr );
++void  McSrv_Sleep                     ( UINT32 dSleepTime );
++void  McSrv_Lock                      ( void );
++void  McSrv_Unlock            ( void );
++void  McSrv_MemCopy           ( const UINT8 *pbSrc, UINT8 *pbDest, UINT32 dSize );
++void  McSrv_DisableIrq        ( void );
++void  McSrv_EnableIrq         ( void );
++
++
++
++#endif /* _MCSERVICE_H_ */
+diff --git a/sound/soc/codecs/mc1n2/mctypedef.h b/sound/soc/codecs/mc1n2/mctypedef.h
+new file mode 100644
+index 0000000..794fec1
+--- /dev/null
++++ b/sound/soc/codecs/mc1n2/mctypedef.h
+@@ -0,0 +1,38 @@
++/****************************************************************************
++ *
++ *            Copyright(c) 2010 Yamaha Corporation. All rights reserved.
++ *
++ *            Module          : mctypedef.h
++ *
++ *            Description     : MC Device Type definitions
++ *
++ *            Version         : 1.0.0         2010.03.18
++ *
++ ****************************************************************************/
++
++#ifndef _MCTYPEDEF_H_
++#define _MCTYPEDEF_H_
++
++#ifndef NULL
++ #define NULL                                         ((void *)0)
++#endif
++#ifndef UINT8
++ #define      UINT8                                   unsigned char
++#endif
++#ifndef UINT16
++ #define      UINT16                                  unsigned short
++#endif
++#ifndef UINT32
++ #define      UINT32                                  unsigned long
++#endif
++#ifndef SINT8
++ #define      SINT8                                   signed char
++#endif
++#ifndef SINT16
++ #define      SINT16                                  signed short
++#endif
++#ifndef SINT32
++ #define      SINT32                                  signed long
++#endif
++
++#endif        /*_MCTYPEDEF_H_*/
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0145-sound-soc-samsung-Add-Trats-platform-audio-driver.patch b/patches.tizen/0145-sound-soc-samsung-Add-Trats-platform-audio-driver.patch
new file mode 100644 (file)
index 0000000..f5de919
--- /dev/null
@@ -0,0 +1,397 @@
+From efbbb1b1e58e713467f89f67f1122644c8fcff00 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 28 Feb 2013 19:41:30 +0100
+Subject: [PATCH 0145/1302] sound: soc: samsung: Add Trats platform audio
+ driver
+
+This patch adds ASoC platform glue driver for Trats board.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ sound/soc/samsung/Kconfig       |   6 +
+ sound/soc/samsung/Makefile      |   2 +
+ sound/soc/samsung/trats_mc1n2.c | 334 ++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 342 insertions(+)
+ create mode 100644 sound/soc/samsung/trats_mc1n2.c
+
+diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
+index 475fb0d..0d321fc 100644
+--- a/sound/soc/samsung/Kconfig
++++ b/sound/soc/samsung/Kconfig
+@@ -199,6 +199,12 @@ config SND_SOC_TOBERMORY
+       select SND_SAMSUNG_I2S
+       select SND_SOC_WM8962
++config SND_SOC_TRATS
++      tristate "Audio support for Samsung Trats"
++      depends on SND_SOC_SAMSUNG && CPU_EXYNOS4210
++      select SND_SAMSUNG_I2S
++      select SND_SOC_MC1N2
++
+ config SND_SOC_BELLS
+       tristate "Audio support for Wolfson Bells"
+       depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410
+diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile
+index 709f605..d2e9b37 100644
+--- a/sound/soc/samsung/Makefile
++++ b/sound/soc/samsung/Makefile
+@@ -40,6 +40,7 @@ snd-soc-smdk-wm8580pcm-objs := smdk_wm8580pcm.o
+ snd-soc-smdk-wm8994pcm-objs := smdk_wm8994pcm.o
+ snd-soc-speyside-objs := speyside.o
+ snd-soc-tobermory-objs := tobermory.o
++snd-soc-trats-objs := trats_mc1n2.o
+ snd-soc-lowland-objs := lowland.o
+ snd-soc-littlemill-objs := littlemill.o
+ snd-soc-bells-objs := bells.o
+@@ -64,6 +65,7 @@ obj-$(CONFIG_SND_SOC_SMDK_WM8580_PCM) += snd-soc-smdk-wm8580pcm.o
+ obj-$(CONFIG_SND_SOC_SMDK_WM8994_PCM) += snd-soc-smdk-wm8994pcm.o
+ obj-$(CONFIG_SND_SOC_SPEYSIDE) += snd-soc-speyside.o
+ obj-$(CONFIG_SND_SOC_TOBERMORY) += snd-soc-tobermory.o
++obj-$(CONFIG_SND_SOC_TRATS) += snd-soc-trats.o
+ obj-$(CONFIG_SND_SOC_LOWLAND) += snd-soc-lowland.o
+ obj-$(CONFIG_SND_SOC_LITTLEMILL) += snd-soc-littlemill.o
+ obj-$(CONFIG_SND_SOC_BELLS) += snd-soc-bells.o
+diff --git a/sound/soc/samsung/trats_mc1n2.c b/sound/soc/samsung/trats_mc1n2.c
+new file mode 100644
+index 0000000..83701dd
+--- /dev/null
++++ b/sound/soc/samsung/trats_mc1n2.c
+@@ -0,0 +1,334 @@
++/*
++ *  u1_mc1n2.c
++ *
++ *  Copyright (c) 2009 Samsung Electronics Co. Ltd
++ *  Author: aitdark.park  <aitdark.park@samsung.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/clk.h>
++#include <linux/delay.h>
++#include <linux/module.h>
++#include <linux/io.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/suspend.h>
++
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++
++#include "../codecs/mc1n2/mc1n2.h"
++
++static bool xclkout_enabled;
++static struct clk *clkout;
++
++int mc1n2_set_mclk_source(bool on)
++{
++      if (xclkout_enabled == on)
++              return 0;
++
++      if (on)
++              clk_prepare_enable(clkout);
++      else
++              clk_disable_unprepare(clkout);
++
++      xclkout_enabled = on;
++      msleep(10);
++
++      return 0;
++}
++EXPORT_SYMBOL(mc1n2_set_mclk_source);
++
++static int u1_hifi_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_dai *cpu_dai = rtd->cpu_dai;
++      struct snd_soc_dai *codec_dai = rtd->codec_dai;
++      int ret;
++
++      /* Set the codec DAI configuration */
++      ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
++                              | SND_SOC_DAIFMT_NB_NF
++                              | SND_SOC_DAIFMT_CBM_CFM);
++      if (ret < 0)
++              return ret;
++
++      /* Set the cpu DAI configuration */
++      ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
++                              | SND_SOC_DAIFMT_NB_NF
++                              | SND_SOC_DAIFMT_CBM_CFM);
++      if (ret < 0)
++              return ret;
++/* check later
++      ret = snd_soc_dai_set_sysclk(cpu_dai, S3C_I2SV2_CLKSRC_CDCLK,
++                              0, SND_SOC_CLOCK_IN);
++      if (ret < 0)
++              return ret;
++
++      ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_MUX,
++                              0, SND_SOC_CLOCK_IN);
++      if (ret < 0)
++              return ret;
++*/
++
++      ret = snd_soc_dai_set_clkdiv(codec_dai, MC1N2_BCLK_MULT, MC1N2_LRCK_X32);
++
++      if (ret < 0)
++              return ret;
++
++      return 0;
++}
++
++/* U1 Audio  extra controls */
++#define U1_AUDIO_OFF  0
++#define U1_HEADSET_OUT        1
++#define U1_MIC_IN     2
++#define U1_LINE_IN    3
++
++static int u1_aud_mode;
++
++static const char *u1_aud_scenario[] = {
++      [U1_AUDIO_OFF] = "Off",
++      [U1_HEADSET_OUT] = "Playback Headphones",
++      [U1_MIC_IN] = "Capture Mic",
++      [U1_LINE_IN] = "Capture Line",
++};
++
++static void u1_aud_ext_control(struct snd_soc_codec *codec)
++{
++      struct snd_soc_dapm_context *dapm = &codec->dapm;
++
++      switch (u1_aud_mode) {
++      case U1_HEADSET_OUT:
++              snd_soc_dapm_enable_pin(dapm, "Headset Out");
++              snd_soc_dapm_disable_pin(dapm, "Mic In");
++              snd_soc_dapm_disable_pin(dapm, "Line In");
++              break;
++      case U1_MIC_IN:
++              snd_soc_dapm_disable_pin(dapm, "Headset Out");
++              snd_soc_dapm_enable_pin(dapm, "Mic In");
++              snd_soc_dapm_disable_pin(dapm, "Line In");
++              break;
++      case U1_LINE_IN:
++              snd_soc_dapm_disable_pin(dapm, "Headset Out");
++              snd_soc_dapm_disable_pin(dapm, "Mic In");
++              snd_soc_dapm_enable_pin(dapm, "Line In");
++              break;
++      case U1_AUDIO_OFF:
++      default:
++              snd_soc_dapm_disable_pin(dapm, "Headset Out");
++              snd_soc_dapm_disable_pin(dapm, "Mic In");
++              snd_soc_dapm_disable_pin(dapm, "Line In");
++              break;
++      }
++
++      snd_soc_dapm_sync(dapm);
++}
++
++static int u1_mc1n2_getp(struct snd_kcontrol *kcontrol,
++                              struct snd_ctl_elem_value *ucontrol)
++{
++      ucontrol->value.integer.value[0] = u1_aud_mode;
++      return 0;
++}
++
++static int u1_mc1n2_setp(struct snd_kcontrol *kcontrol,
++                              struct snd_ctl_elem_value *ucontrol)
++{
++      struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
++
++      if (u1_aud_mode == ucontrol->value.integer.value[0])
++              return 0;
++
++      u1_aud_mode = ucontrol->value.integer.value[0];
++      u1_aud_ext_control(codec);
++
++      return 1;
++}
++
++static const struct snd_soc_dapm_widget u1_dapm_widgets[] = {
++      SND_SOC_DAPM_HP("Headset Out", NULL),
++      SND_SOC_DAPM_MIC("Mic In", NULL),
++      SND_SOC_DAPM_LINE("Line In", NULL),
++};
++
++static const struct soc_enum u1_aud_enum[] = {
++      SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(u1_aud_scenario),
++                          u1_aud_scenario),
++};
++
++static const struct snd_kcontrol_new u1_aud_controls[] = {
++      SOC_ENUM_EXT("U1 Audio Mode", u1_aud_enum[0],
++                   u1_mc1n2_getp, u1_mc1n2_setp),
++};
++
++static const struct snd_soc_dapm_route u1_dapm_routes[] = {
++      /* Connections to Headset */
++      {"Headset Out", NULL, "HPOUT1L"},
++      {"Headset Out", NULL, "HPOUT1R"},
++      /* Connections to Mics */
++      {"IN1LN", NULL, "Mic In"},
++      {"IN1RN", NULL, "Mic In"},
++      /* Connections to Line In */
++      {"IN2LN", NULL, "Line In"},
++      {"IN2RN", NULL, "Line In"},
++};
++
++static int u1_hifiaudio_init(struct snd_soc_pcm_runtime *rtd)
++{
++      return 0;
++}
++
++/*
++ * U1 MC1N2 DAI operations.
++ */
++static struct snd_soc_ops u1_hifi_ops = {
++      .hw_params = u1_hifi_hw_params,
++};
++
++static struct snd_soc_dai_link u1_dai[] = {
++#if defined(CONFIG_SND_SAMSUNG_LP) || defined(CONFIG_SND_SAMSUNG_ALP)
++      { /* Sec_Fifo DAI i/f */
++              .name = "MC1N2 Sec_FIFO TX",
++              .stream_name = "Sec_Dai",
++              .cpu_dai_name = "samsung-i2s.4",
++              .codec_dai_name = "mc1n2-da0i",
++#ifndef CONFIG_SND_SOC_SAMSUNG_USE_DMA_WRAPPER
++              .platform_name = "samsung-audio-idma",
++#else
++              .platform_name = "samsung-audio",
++#endif
++              .codec_name = "mc1n2.6-003a",
++              .init = u1_hifiaudio_init,
++              .ops = &u1_hifi_ops,
++      },
++#endif
++      { /* Primary DAI i/f */
++              .name = "MC1N2 AIF1",
++              .stream_name = "hifiaudio",
++              .cpu_dai_name = "samsung-i2s.0",
++              .codec_dai_name = "mc1n2-da0i",
++              .platform_name = "samsung-audio",
++              .codec_name = "mc1n2.6-003a",
++              .init = u1_hifiaudio_init,
++              .ops = &u1_hifi_ops,
++      }
++};
++
++static int u1_card_suspend(struct snd_soc_card *card)
++{
++#warning FIXME
++#if 0
++      exynos4_sys_powerdown_parent_control(xclkout_enabled ? 1 : 0);
++#endif
++      return 0;
++}
++
++static struct snd_soc_card u1_snd_card = {
++      .name = "U1-YMU823",
++      .dai_link = u1_dai,
++      .num_links = ARRAY_SIZE(u1_dai),
++
++      .suspend_post = u1_card_suspend,
++};
++
++/* setup codec data from mc1n2 codec driver */
++extern void set_mc1n2_codec_data(struct mc1n2_setup *setup);
++
++static struct platform_device *u1_snd_device;
++
++static int u1_snd_probe(struct platform_device *pdev)
++{
++      int ret;
++      struct clk *out_mux;
++      struct clk *parent;
++
++      if (pdev->dev.of_node) {
++              struct device_node *np = pdev->dev.of_node;
++              struct snd_soc_dai_link *link = u1_dai;
++
++              link->cpu_dai_name = NULL;
++              link->cpu_of_node = of_parse_phandle(np,
++                                              "samsung,i2s-controller", 0);
++              if (!link->cpu_of_node) {
++                      dev_err(&pdev->dev, "failed to parse samsung,i2s-controller phandle\n");
++                      return -EINVAL;
++              }
++
++              link->platform_name = NULL;
++              link->platform_of_node = link->cpu_of_node;
++
++              link->codec_name = NULL;
++              link->codec_of_node = of_parse_phandle(np,
++                                              "samsung,audio-codec", 0);
++              if (!link->codec_of_node) {
++                      dev_err(&pdev->dev, "failed to parse samsung,audio-codec phandle\n");
++                      return -EINVAL;
++              }
++      }
++
++      clkout = clk_get(&pdev->dev, "out");
++      if (IS_ERR(clkout)) {
++              dev_err(&pdev->dev, "failed to get out clock\n");
++              return PTR_ERR(clkout);
++      }
++
++      out_mux = clk_get(&pdev->dev, "out-mux");
++      if (IS_ERR(out_mux)) {
++              dev_err(&pdev->dev, "failed to get out mux clock\n");
++              return PTR_ERR(out_mux);
++      }
++
++      parent = clk_get(&pdev->dev, "parent");
++      if (IS_ERR(parent)) {
++              dev_err(&pdev->dev, "failed to get parent clock\n");
++              return PTR_ERR(parent);
++      }
++
++      clk_set_parent(out_mux, parent);
++      mc1n2_set_mclk_source(true);
++
++      u1_snd_device = platform_device_alloc("soc-audio", -1);
++      if (!u1_snd_device)
++              return -ENOMEM;
++
++      platform_set_drvdata(u1_snd_device, &u1_snd_card);
++
++      ret = platform_device_add(u1_snd_device);
++      if (ret) {
++              platform_device_put(u1_snd_device);
++      }
++
++      return ret;
++}
++
++static void u1_snd_remove(struct platform_device *pdev)
++{
++      platform_device_unregister(u1_snd_device);
++}
++
++static struct of_device_id u1_snd_of_matches[] = {
++      { .compatible = "samsung,u1-platform-snd", },
++      {}
++};
++
++static struct platform_driver u1_snd_driver = {
++      .driver = {
++              .name = "u1-platform-snd",
++              .of_match_table = u1_snd_of_matches,
++      },
++      .probe  = u1_snd_probe,
++      .remove = u1_snd_remove,
++};
++module_platform_driver(u1_snd_driver);
++
++MODULE_AUTHOR("aitdark, aitdark.park@samsung.com");
++MODULE_DESCRIPTION("ALSA SoC U1 MC1N2");
++MODULE_LICENSE("GPL");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0146-ARM-dts-exynos4210-trats-Add-LDO1-regulator-node.patch b/patches.tizen/0146-ARM-dts-exynos4210-trats-Add-LDO1-regulator-node.patch
new file mode 100644 (file)
index 0000000..15c2cfa
--- /dev/null
@@ -0,0 +1,35 @@
+From b7a29cebc57e548d3ea757013199c404f9d036c8 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 28 Feb 2013 19:42:08 +0100
+Subject: [PATCH 0146/1302] ARM: dts: exynos4210-trats: Add LDO1 regulator node
+
+This patch adds missing node for LDO1 regulator required by audio
+components.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index a399016..d87f19a 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -305,6 +305,13 @@
+                                                        <1200000>, <1200000>;
+                       regulators {
++                              vadc_reg: LDO1 {
++                                      regulator-name = "VADC_3.3V_C210";
++                                      regulator-min-microvolt = <3300000>;
++                                      regulator-max-microvolt = <3300000>;
++                                      regulator-always-on;
++                              };
++
+                               valive_reg: LDO2 {
+                                    regulator-name = "VALIVE_1.1V_C210";
+                                    regulator-min-microvolt = <1100000>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0147-ARM-dts-exynos4210-trats-Add-nodes-for-audio-hardwar.patch b/patches.tizen/0147-ARM-dts-exynos4210-trats-Add-nodes-for-audio-hardwar.patch
new file mode 100644 (file)
index 0000000..6c5efe7
--- /dev/null
@@ -0,0 +1,65 @@
+From da6368e7a5eeeb9aaac7233ac392a6b12f56d434 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 28 Feb 2013 19:42:59 +0100
+Subject: [PATCH 0147/1302] ARM: dts: exynos4210-trats: Add nodes for audio
+ hardware
+
+This patch adds nodes for audio hardware present on Trats board.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index d87f19a..7061c88 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -448,6 +448,22 @@
+               };
+       };
++      i2c@138C0000 {
++              samsung,i2c-sda-delay = <100>;
++              samsung,i2c-slave-addr = <0x10>;
++              samsung,i2c-max-bus-freq = <400000>;
++              pinctrl-0 = <&i2c6_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              mc1n2: codec@3a {
++                      compatible = "yamaha,mc1n2";
++                      reg = <0x3a>;
++                      vadc-supply = <&vadc_reg>;
++                      gpios = <&gpe1 4 0>, <&gpe2 0 0>;
++              };
++      };
++
+       usbphy@125B0000 {
+               status = "okay";
+       };
+@@ -594,6 +610,20 @@
+               };
+       };
++      i2s0: i2s@03830000 {
++              pinctrl-0 = <&i2s0_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++      };
++
++      sound {
++              compatible = "samsung,u1-platform-snd";
++              clocks = <&clock 2>, <&clock 395>, <&clock 21>;
++              clock-names = "parent", "out-mux", "out";
++              samsung,i2s-controller = <&i2s0>;
++              samsung,audio-codec = <&mc1n2>;
++      };
++
+       cpufreq {
+               /* No freq_table property to use default table. */
+               vdd_arm-supply = <&varm_breg>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0148-cpufreq-Make-ARM_EXYNOS-_CPUFREQ-depend-on-ARM_EXYNO.patch b/patches.tizen/0148-cpufreq-Make-ARM_EXYNOS-_CPUFREQ-depend-on-ARM_EXYNO.patch
new file mode 100644 (file)
index 0000000..5a1cd5c
--- /dev/null
@@ -0,0 +1,44 @@
+From df80e636d39ee0ff7bae0dd65c0c1674973fa8a4 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 28 Feb 2013 20:06:13 +0100
+Subject: [PATCH 0148/1302] cpufreq: Make ARM_EXYNOS*_CPUFREQ depend on
+ ARM_EXYNOS_CPUFREQ
+
+This patch adds dependency on ARM_EXYNOS_CPUFREQ to particular SoC
+drivers to avoid compilation errors when ARM_EXYNOS_CPUFREQ is disabled.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/Kconfig.arm | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
+index 6e57543..85d3f39 100644
+--- a/drivers/cpufreq/Kconfig.arm
++++ b/drivers/cpufreq/Kconfig.arm
+@@ -27,18 +27,21 @@ config ARM_EXYNOS_CPUFREQ
+ config ARM_EXYNOS4210_CPUFREQ
+       def_bool CPU_EXYNOS4210
++      depends on ARM_EXYNOS_CPUFREQ
+       help
+         This adds the CPUFreq driver for Samsung EXYNOS4210
+         SoC (S5PV310 or S5PC210).
+ config ARM_EXYNOS4X12_CPUFREQ
+       def_bool (SOC_EXYNOS4212 || SOC_EXYNOS4412)
++      depends on ARM_EXYNOS_CPUFREQ
+       help
+         This adds the CPUFreq driver for Samsung EXYNOS4X12
+         SoC (EXYNOS4212 or EXYNOS4412).
+ config ARM_EXYNOS5250_CPUFREQ
+       def_bool SOC_EXYNOS5250
++      depends on ARM_EXYNOS_CPUFREQ
+       help
+         This adds the CPUFreq driver for Samsung EXYNOS5250
+         SoC.
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0149-power-max8997-charger-Fix-getting-platform-data.patch b/patches.tizen/0149-power-max8997-charger-Fix-getting-platform-data.patch
new file mode 100644 (file)
index 0000000..a4dd677
--- /dev/null
@@ -0,0 +1,30 @@
+From 9205fe5c16b70cfdb2c67d3aa5910ef9e6aa2583 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 1 Mar 2013 15:22:45 +0100
+Subject: [PATCH 0149/1302] power: max8997-charger: Fix getting platform data
+
+This patch fixes incorrect way of getting platform data, which should be
+read from MFD private data structure instead.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/power/max8997_charger.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/power/max8997_charger.c b/drivers/power/max8997_charger.c
+index 4bdedfe..732a969 100644
+--- a/drivers/power/max8997_charger.c
++++ b/drivers/power/max8997_charger.c
+@@ -91,7 +91,7 @@ static int max8997_battery_probe(struct platform_device *pdev)
+       int ret = 0;
+       struct charger_data *charger;
+       struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
+-      struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev);
++      struct max8997_platform_data *pdata = iodev->pdata;
+       if (!pdata)
+               return -EINVAL;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0150-ARM-dts-exynos4210-trats-Add-node-for-max17042-batte.patch b/patches.tizen/0150-ARM-dts-exynos4210-trats-Add-node-for-max17042-batte.patch
new file mode 100644 (file)
index 0000000..210ea44
--- /dev/null
@@ -0,0 +1,43 @@
+From c4d7b6cc0f3a3778528f0398da9c9c4d8e81bdb4 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 1 Mar 2013 15:24:46 +0100
+Subject: [PATCH 0150/1302] ARM: dts: exynos4210-trats: Add node for max17042
+ battery fuel gauge
+
+This patch adds device tree node for max17042 battery fuel gauge present
+on Trats board.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index 7061c88..a7ed9af 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -464,6 +464,20 @@
+               };
+       };
++      i2c-gpio-0 {
++              compatible = "i2c-gpio";
++              gpios = <&gpy4 0 0>, <&gpy4 1 0>;
++              i2c-gpio,delay-us = <5>;
++              #address-cells = <1>;
++              #size-cells = <0>;
++
++              battery@36 {
++                      compatible = "maxim,max17042";
++                      reg = <0x36>;
++                      maxim,rsns-microohm = <10000>;
++              };
++      };
++
+       usbphy@125B0000 {
+               status = "okay";
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0151-gpu-drm-exynos-fimd-Fix-parsing-video-mode-from-inco.patch b/patches.tizen/0151-gpu-drm-exynos-fimd-Fix-parsing-video-mode-from-inco.patch
new file mode 100644 (file)
index 0000000..993d918
--- /dev/null
@@ -0,0 +1,47 @@
+From 73a7ec7bd91c36a2101f9a5474b8e556a9ab1500 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 1 Mar 2013 15:25:55 +0100
+Subject: [PATCH 0151/1302] gpu: drm: exynos: fimd: Fix parsing video mode from
+ incorrect DT node
+
+This patch fixes the driver to parse video mode from display node
+received by parsing samsung,fimd-display phandle, falling back
+to parsing from fimd node only if no display phandle is specified.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_fimd.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+index 8ffbe2d..0d7e42b 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+@@ -913,14 +913,21 @@ static int fimd_probe(struct platform_device *pdev)
+       DRM_DEBUG_KMS("%s\n", __FILE__);
+       if (dev->of_node) {
++              struct device_node *display_np;
++
++              display_np = of_parse_phandle(dev->of_node,
++                                              "samsung,fimd-display", 0);
++              if (!display_np)
++                      display_np = dev->of_node;
++
+               pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+               if (!pdata) {
+                       DRM_ERROR("memory allocation for pdata failed\n");
+                       return -ENOMEM;
+               }
+-              ret = of_get_fb_videomode(dev->of_node, &pdata->panel.timing,
+-                                      OF_USE_NATIVE_MODE);
++              ret = of_get_fb_videomode(display_np,
++                              &pdata->panel.timing, OF_USE_NATIVE_MODE);
+               if (ret) {
+                       DRM_ERROR("failed: of_get_fb_videomode() : %d\n", ret);
+                       return ret;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0152-gpu-drm-exynos-fimd-Parse-display-physical-size-from.patch b/patches.tizen/0152-gpu-drm-exynos-fimd-Parse-display-physical-size-from.patch
new file mode 100644 (file)
index 0000000..f52551e
--- /dev/null
@@ -0,0 +1,35 @@
+From 79b306fc51b037b186e46dc6643e7ece4a75c958 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 1 Mar 2013 15:27:05 +0100
+Subject: [PATCH 0152/1302] gpu: drm: exynos: fimd: Parse display physical size
+ from DT
+
+This patch adds a temporary solution for getting physical display size
+from device tree by parsing driver-specific properties in display node.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_fimd.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+index 0d7e42b..e8465f5 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+@@ -932,6 +932,12 @@ static int fimd_probe(struct platform_device *pdev)
+                       DRM_ERROR("failed: of_get_fb_videomode() : %d\n", ret);
+                       return ret;
+               }
++
++              /* FIXME */
++              of_property_read_u32(display_np, "samsung,panel-width-mm",
++                                              &pdata->panel.width_mm);
++              of_property_read_u32(display_np, "samsung,panel-height-mm",
++                                              &pdata->panel.height_mm);
+       } else {
+               pdata = dev->platform_data;
+               if (!pdata) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0153-ARM-dts-exynos4210-trats-Add-physical-display-size-p.patch b/patches.tizen/0153-ARM-dts-exynos4210-trats-Add-physical-display-size-p.patch
new file mode 100644 (file)
index 0000000..2155329
--- /dev/null
@@ -0,0 +1,30 @@
+From 3b5a15a3b09787f5beacd3fe8bb06e80f926eeaf Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 1 Mar 2013 15:27:59 +0100
+Subject: [PATCH 0153/1302] ARM: dts: exynos4210-trats: Add physical display
+ size properties
+
+This patch adds physical size properties to panel node.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index a7ed9af..6b7dd39 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -511,6 +511,8 @@
+               video-source = <&dsi_0>;
+               flip-horizontal;
+               flip-vertical;
++              samsung,panel-width-mm = <58>; /* FIXME */
++              samsung,panel-height-mm = <103>; /* FIXME */
+               display-timings {
+                       native-mode = <&timing0>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0154-ARM-dts-exynos4412-redwood-Add-physical-display-size.patch b/patches.tizen/0154-ARM-dts-exynos4412-redwood-Add-physical-display-size.patch
new file mode 100644 (file)
index 0000000..40d8f21
--- /dev/null
@@ -0,0 +1,30 @@
+From fb6d3fd14b7aae523a27f1ec53386aa05d97cbcb Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 1 Mar 2013 16:03:00 +0100
+Subject: [PATCH 0154/1302] ARM: dts: exynos4412-redwood: Add physical display
+ size properties
+
+This patch adds physical size properties to panel node.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-redwood.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-redwood.dts b/arch/arm/boot/dts/exynos4412-redwood.dts
+index 5df54e8..475889a 100644
+--- a/arch/arm/boot/dts/exynos4412-redwood.dts
++++ b/arch/arm/boot/dts/exynos4412-redwood.dts
+@@ -456,6 +456,8 @@
+               video-source = <&dsi_0>;
+               flip-horizontal;
+               flip-vertical;
++              samsung,panel-width-mm = <59>; /* FIXME */
++              samsung,panel-height-mm = <105>; /* FIXME */
+               display-timings {
+                       native-mode = <&timing0>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0155-ARM-dts-exynos4412-slp_pq-Add-physical-display-size-.patch b/patches.tizen/0155-ARM-dts-exynos4412-slp_pq-Add-physical-display-size-.patch
new file mode 100644 (file)
index 0000000..641773e
--- /dev/null
@@ -0,0 +1,30 @@
+From d2ba7e45dd20d3193af2d997e58a8ba7e87c9320 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 1 Mar 2013 16:03:12 +0100
+Subject: [PATCH 0155/1302] ARM: dts: exynos4412-slp_pq: Add physical display
+ size properties
+
+This patch adds physical size properties to panel node.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 77ee50e..df32808 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -517,6 +517,8 @@
+               vdd3-supply = <&lcd_vdd3_reg>;
+               vci-supply = <&ldo25_reg>;
+               video-source = <&dsi_0>;
++              samsung,panel-width-mm = <58>; /* FIXME */
++              samsung,panel-height-mm = <103>; /* FIXME */
+               display-timings {
+                       native-mode = <&timing0>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0156-ARM-dts-exynos4412-redwood-added-rear-camera-support.patch b/patches.tizen/0156-ARM-dts-exynos4412-redwood-added-rear-camera-support.patch
new file mode 100644 (file)
index 0000000..729ee7a
--- /dev/null
@@ -0,0 +1,166 @@
+From 9f4526774d2c9b0cb42842640638cb5a72dcfabc Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Tue, 5 Mar 2013 10:10:28 +0100
+Subject: [PATCH 0156/1302] ARM: dts: exynos4412-redwood: added rear camera
+ support
+
+Added:
+- camera node,
+- fimc nodes,
+- csis_0 node,
+- camera regulators,
+- s5c73m3 node.
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-redwood.dts | 119 +++++++++++++++++++++++++++++++
+ 1 file changed, 119 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-redwood.dts b/arch/arm/boot/dts/exynos4412-redwood.dts
+index 475889a..17f704e 100644
+--- a/arch/arm/boot/dts/exynos4412-redwood.dts
++++ b/arch/arm/boot/dts/exynos4412-redwood.dts
+@@ -134,6 +134,35 @@
+               };
+       };
++      i2c_0: i2c@13860000 {
++              samsung,i2c-sda-delay = <100>;
++              samsung,i2c-slave-addr = <0x10>;
++              samsung,i2c-max-bus-freq = <400000>;
++              pinctrl-0 = <&i2c0_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              s5c73m3@3c {
++                      compatible = "samsung,s5c73m3";
++                      reg = <0x3c>;
++                      gpios = <&gpm0 1 1>, /* ISP_STANDBY */
++                              <&gpf1 3 1>; /* ISP_RESET */
++                      vdd-int-supply = <&buck9_reg>;
++                      vddio-cis-supply = <&ldo9_reg>;
++                      vdda-supply = <&ldo17_reg>;
++                      vddio-host-supply = <&ldo18_reg>;
++                      vdd-af-supply = <&cam_af_reg>;
++                      vdd-reg-supply = <&cam_io_reg>;
++                      clock-frequency = <24000000>;
++
++                      port {
++                              s5c73m3_ep: endpoint {
++                                      remote-endpoint = <&csis0_ep>;
++                              };
++                      };
++              };
++      };
++
+       i2c@13890000 {
+               samsung,i2c-sda-delay = <100>;
+               samsung,i2c-slave-addr = <0x10>;
+@@ -446,6 +475,34 @@
+               enable-active-high;
+       };
++      cam_af_reg: voltage-regulator@2 {
++              compatible = "regulator-fixed";
++              regulator-name = "CAM_AF";
++              regulator-min-microvolt = <2800000>;
++              regulator-max-microvolt = <2800000>;
++              gpio = <&gpm0 4 0>;
++              enable-active-high;
++      };
++
++      cam_io_reg: voltage-regulator@3 {
++              compatible = "regulator-fixed";
++              regulator-name = "CAM_SENSOR_A";
++              regulator-min-microvolt = <2800000>;
++              regulator-max-microvolt = <2800000>;
++              gpio = <&gpm0 2 0>;
++              enable-active-high;
++      };
++
++      cam_isp_core_reg: voltage-regulator@4 {
++              compatible = "regulator-fixed";
++              regulator-name = "CAM_ISP_CORE_1.2V_EN";
++              regulator-min-microvolt = <1200000>;
++              regulator-max-microvolt = <1200000>;
++              gpio = <&gpm0 3 0>;
++              enable-active-high;
++              regulator-always-on;
++      };
++
+       fimd0_lcd: panel {
+               compatible = "samsung,s6d6aa1";
+               reset-gpio = <&gpf2 1 0>;
+@@ -516,6 +573,68 @@
+               vusb_a-supply = <&ldo12_reg>;
+       };
++      spi_1: spi@13930000 {
++              pinctrl-names = "default";
++              pinctrl-0 = <&spi1_bus>;
++              status = "okay";
++
++              s5c73m3_spi: s5c73m3 {
++                      compatible = "samsung,s5c73m3";
++                      spi-max-frequency = <50000000>;
++                      reg = <0>;
++                      controller-data {
++                              cs-gpio = <&gpb 5 0>;
++                              samsung,spi-feedback-delay = <2>;
++                      };
++              };
++      };
++
++      camera {
++              status = "okay";
++
++              pinctrl-names = "default";
++              pinctrl-0 = <&cam_port_a_clk_active>;
++
++              fimc_0: fimc@11800000 {
++                      clock-frequency = <176000000>;
++                      status = "okay";
++              };
++
++              fimc_1: fimc@11810000 {
++                      clock-frequency = <176000000>;
++                      status = "okay";
++              };
++
++              fimc_2: fimc@11820000 {
++                      clock-frequency = <176000000>;
++                      status = "okay";
++              };
++
++              fimc_3: fimc@11830000 {
++                      clock-frequency = <176000000>;
++                      status = "okay";
++              };
++
++              csis_0: csis@11880000 {
++                      status = "okay";
++                      vddcore-supply = <&ldo8_reg>;
++                      vddio-supply = <&ldo10_reg>;
++                      clock-frequency = <160000000>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++
++                      /* Camera C (3) MIPI CSI-2 (CSIS0) */
++                      port@3 {
++                              reg = <3>;
++                              csis0_ep: endpoint {
++                                      remote-endpoint = <&s5c73m3_ep>;
++                                      data-lanes = <1 2 3 4>;
++                                      samsung,csis-hs-settle = <12>;
++                              };
++                      };
++              };
++      };
++
+       mfc: codec@13400000 {
+               status = "okay";
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0157-mfd-wm8994-irq-Enable-initialization-with-NULL-platf.patch b/patches.tizen/0157-mfd-wm8994-irq-Enable-initialization-with-NULL-platf.patch
new file mode 100644 (file)
index 0000000..5a777c7
--- /dev/null
@@ -0,0 +1,45 @@
+From 6b8ecea12093f6bdfb357f2c26f8c6e15edb8013 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Tue, 5 Mar 2013 17:40:41 +0100
+Subject: [PATCH 0157/1302] mfd: wm8994-irq: Enable initialization with NULL
+ platform_data
+
+Interrupts are disabled, until the FIFO error interrupt flooding
+issue is resolved.
+
+TODO: Add proper support for device tree based initialization.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mfd/wm8994-irq.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mfd/wm8994-irq.c b/drivers/mfd/wm8994-irq.c
+index a050e56..a348d5d 100644
+--- a/drivers/mfd/wm8994-irq.c
++++ b/drivers/mfd/wm8994-irq.c
+@@ -144,16 +144,18 @@ int wm8994_irq_init(struct wm8994 *wm8994)
+       unsigned long irqflags;
+       struct wm8994_pdata *pdata = wm8994->dev->platform_data;
+-      if (!wm8994->irq) {
++      if (!pdata || !wm8994->irq) {
+               dev_warn(wm8994->dev,
+                        "No interrupt specified, no interrupts\n");
+               wm8994->irq_base = 0;
+               return 0;
+       }
++      wm8994->irq_base = -1;
++
+       /* select user or default irq flags */
+       irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
+-      if (pdata->irq_flags)
++      if (pdata && pdata->irq_flags)
+               irqflags = pdata->irq_flags;
+       ret = regmap_add_irq_chip(wm8994->regmap, wm8994->irq,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0158-sound-Add-exynos4-wm1811-machine-driver.patch b/patches.tizen/0158-sound-Add-exynos4-wm1811-machine-driver.patch
new file mode 100644 (file)
index 0000000..2fae05f
--- /dev/null
@@ -0,0 +1,1450 @@
+From 1ac67c8c475ff3fd1dd0e58c2734adb7a968e227 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Mon, 4 Mar 2013 17:49:37 +0100
+Subject: [PATCH 0158/1302] sound: Add exynos4/wm1811 machine driver
+
+TODO:
+ - complete bindings documentation,
+ - enable remaining audio interfaces (Voice, Bluetooth,
+   Secondary DAI).
+
+Signed-off-by: KwangHui Cho <kwanghui.cho@samsung.com>
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../bindings/sound/samsung-exynos4-wm1811.txt      |   46 +
+ sound/soc/samsung/Kconfig                          |   12 +
+ sound/soc/samsung/Makefile                         |    2 +
+ sound/soc/samsung/exynos4_wm1811.c                 | 1323 ++++++++++++++++++++
+ 4 files changed, 1383 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/sound/samsung-exynos4-wm1811.txt
+ create mode 100644 sound/soc/samsung/exynos4_wm1811.c
+
+diff --git a/Documentation/devicetree/bindings/sound/samsung-exynos4-wm1811.txt b/Documentation/devicetree/bindings/sound/samsung-exynos4-wm1811.txt
+new file mode 100644
+index 0000000..a4e0e10
+--- /dev/null
++++ b/Documentation/devicetree/bindings/sound/samsung-exynos4-wm1811.txt
+@@ -0,0 +1,46 @@
++Samsung Exynos4 audio complex
++
++Required properties:
++
++- compatible : "samsung,exynos4-wm1811";
++- samsung,model : the user-visible name of this sound complex;
++- samsung,audio-routing : A list of the connections between audio components.
++  Each entry is a pair of strings, the first being the connection's sink,
++  the second being the connection's source. Valid names for sources and
++  sinks are the WM8903's pins, and the jacks on the board:
++
++  ...
++
++  * Headphone Jack
++  * Int Spk
++  * Mic Jack
++
++- samsung,i2s-controller : the phandle of the Tegra I2S1 controller;
++- samsung,audio-codec : the phandle of the WM8903 audio codec.
++
++Optional properties:
++- nvidia,spkr-en-gpios : The GPIO that enables the speakers;
++- nvidia,hp-mute-gpios : The GPIO that mutes the headphones;
++- nvidia,hp-det-gpios : The GPIO that detect headphones are plugged in;
++- nvidia,int-mic-en-gpios : The GPIO that enables the internal microphone;
++- nvidia,ext-mic-en-gpios : The GPIO that enables the external microphone.
++
++Example:
++
++sound {
++      compatible = "samsung,exynos-wm1811";
++      nvidia,model = "redwood-wm1811";
++
++      samsung,audio-routing =
++              "Headphone Jack", "HPOUTR",
++              "Headphone Jack", "HPOUTL",
++              "IN1L", "Mic Jack";
++
++      samsung,i2s-controller = <&i2s0>;
++      samsung,audio-codec = <&wm1811>;
++
++      nvidia,spkr-en-gpios = <&codec 2 0>;
++      nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */
++      nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */
++};
++
+diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
+index 0d321fc..fe8819b 100644
+--- a/sound/soc/samsung/Kconfig
++++ b/sound/soc/samsung/Kconfig
+@@ -70,6 +70,10 @@ config SND_SOC_SAMSUNG_SMDK_WM8994
+       help
+               Say Y if you want to add support for SoC audio on the SMDKs.
++config SND_SAMSUNG_I2S_MASTER
++      bool "I2S Master Mode"
++      depends on SND_SAMSUNG_I2S
++
+ config SND_SOC_SAMSUNG_SMDK2443_WM9710
+       tristate "SoC AC97 Audio support for SMDK2443 - WM9710"
+       depends on SND_SOC_SAMSUNG && MACH_SMDK2443
+@@ -228,3 +232,11 @@ config SND_SOC_LITTLEMILL
+       select SND_SAMSUNG_I2S
+       select MFD_WM8994
+       select SND_SOC_WM8994
++
++config SND_SOC_SAMSUNG_EXYNOS4_WM1811
++      tristate "SoC I2S Audio support for WM1811 on Tizen Exynos4 board"
++      depends on SND_SOC_SAMSUNG
++      select SND_SOC_WM8994
++      select SND_SAMSUNG_I2S
++      help
++        Say Y if you want to add support for SoC audio on the Tizen Exynos4 board.
+diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile
+index d2e9b37..1e212e4 100644
+--- a/sound/soc/samsung/Makefile
++++ b/sound/soc/samsung/Makefile
+@@ -44,6 +44,7 @@ snd-soc-trats-objs := trats_mc1n2.o
+ snd-soc-lowland-objs := lowland.o
+ snd-soc-littlemill-objs := littlemill.o
+ snd-soc-bells-objs := bells.o
++snd-soc-exynos4-wm1811-objs := exynos4_wm1811.o
+ obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o
+ obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
+@@ -69,3 +70,4 @@ obj-$(CONFIG_SND_SOC_TRATS) += snd-soc-trats.o
+ obj-$(CONFIG_SND_SOC_LOWLAND) += snd-soc-lowland.o
+ obj-$(CONFIG_SND_SOC_LITTLEMILL) += snd-soc-littlemill.o
+ obj-$(CONFIG_SND_SOC_BELLS) += snd-soc-bells.o
++obj-$(CONFIG_SND_SOC_SAMSUNG_EXYNOS4_WM1811) += snd-soc-exynos4-wm1811.o
+diff --git a/sound/soc/samsung/exynos4_wm1811.c b/sound/soc/samsung/exynos4_wm1811.c
+new file mode 100644
+index 0000000..fb6385f
+--- /dev/null
++++ b/sound/soc/samsung/exynos4_wm1811.c
+@@ -0,0 +1,1323 @@
++/*
++ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
++ *
++ * Authors: KwangHui Cho <kwanghui.cho@samsung.com>
++ *          Sylwester Nawrocki <s.nawrocki@samsung.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.
++ */
++#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
++
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/gpio.h>
++#include <linux/input.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/mfd/wm8994/core.h>
++#include <linux/mfd/wm8994/registers.h>
++#include <linux/mfd/wm8994/pdata.h>
++#include <linux/mfd/wm8994/gpio.h>
++#include <linux/of_gpio.h>
++#include <linux/platform_device.h>
++#include <linux/pm.h>
++#include <linux/pm_wakeup.h>
++#include <linux/regulator/machine.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++#include <linux/workqueue.h>
++
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/jack.h>
++
++#include "i2s.h"
++#include "i2s-regs.h"
++#include "s3c-i2s-v2.h"
++#include "../codecs/wm8994.h"
++
++#define XTAL_24MHZ_AP                 24000000
++#define CODEC_CLK32K                  32768
++#define CODEC_DEFAULT_SYNC_CLK                11289600
++
++#define WM1811_JACKDET_MODE_NONE      0x0000
++#define WM1811_JACKDET_MODE_JACK      0x0100
++#define WM1811_JACKDET_MODE_MIC               0x0080
++#define WM1811_JACKDET_MODE_AUDIO     0x0180
++
++#define WM1811_JACKDET_BTN0           0x04
++#define WM1811_JACKDET_BTN1           0x10
++#define WM1811_JACKDET_BTN2           0x08
++
++#define SND_SOC_DAPM_SPKMODE(wname, wevent) \
++{       .id = snd_soc_dapm_spk, .name = wname, .kcontrol_news = NULL, \
++      .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
++      .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD}
++
++
++static char *mic_names[] = {
++      "Main Mic",
++      "Sub Mic",
++};
++
++static const struct wm8958_micd_rate machine_det_rates[] = {
++      { CODEC_CLK32K,                 true,  0, 0 },
++      { CODEC_CLK32K,                 false, 0, 0 },
++      { CODEC_DEFAULT_SYNC_CLK,       true,  0xa, 0xb },
++      { CODEC_DEFAULT_SYNC_CLK,       false, 0xa, 0xb },
++};
++
++static const struct wm8958_micd_rate machine_jackdet_rates[] = {
++      { CODEC_CLK32K,                 true,  0, 0 },
++      { CODEC_CLK32K,                 false, 0, 0 },
++      { CODEC_DEFAULT_SYNC_CLK,       true, 12, 12 },
++      { CODEC_DEFAULT_SYNC_CLK,       false, 7, 7 },
++};
++
++static int aif2_mode;
++const char *aif2_mode_text[] = {
++      "Slave", "Master"
++};
++enum {
++      MODE_CODEC_SLAVE,
++      MODE_CODEC_MASTER,
++};
++
++/* TODO: convert to DT properties */
++enum {
++      MIC_MAIN,
++      MIC_SUB,
++      MIC_MAX
++};
++
++enum exynos4_wm1811_gpios {
++      GPIO_VPS_SOUND,
++      GPIO_MIC_BIAS,
++      GPIO_MIC_SUB_BIAS,
++      GPIO_NUM
++};
++
++/* To support PBA function test */
++static struct class *audio_class;
++static struct device *jack_dev;
++static struct device *caps_dev;
++
++struct exynos_wm1811 {
++      struct snd_soc_jack jack;
++      struct snd_soc_codec *codec;
++      struct clk *codec_mclk;
++
++      int gpio_mic_bias[MIC_MAX];
++      int gpio_vps_en;
++      /* int gpios[GPIO_NUM]; */
++
++      u32 mic_avail[MIC_MAX];
++      bool ignore_earjack;
++      bool cp_wb_support;
++
++      /* Exynos4 EPLL clock */
++      struct clk *clk_pll;
++};
++
++static const struct soc_enum aif2_mode_enum[] = {
++      SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(aif2_mode_text), aif2_mode_text),
++};
++
++static int get_aif2_mode(struct snd_kcontrol *kcontrol,
++              struct snd_ctl_elem_value *ucontrol)
++{
++      ucontrol->value.integer.value[0] = aif2_mode;
++      return 0;
++}
++
++static int set_aif2_mode(struct snd_kcontrol *kcontrol,
++              struct snd_ctl_elem_value *ucontrol)
++{
++      if (aif2_mode == ucontrol->value.integer.value[0])
++              return 0;
++
++      aif2_mode = ucontrol->value.integer.value[0];
++
++      WARN_ON((aif2_mode != MODE_CODEC_SLAVE) &&
++              (aif2_mode != MODE_CODEC_MASTER));
++
++      pr_info("set AIF2 mode: %s\n", aif2_mode_text[aif2_mode]);
++      return 0;
++}
++
++static int exynos_snd_micbias(struct snd_soc_dapm_widget *w,
++                           struct snd_kcontrol *kcontrol, int event)
++{
++      struct snd_soc_codec *codec = w->codec;
++      struct exynos_wm1811 *machine = snd_soc_card_get_drvdata(codec->card);
++      unsigned int mic;
++
++      dev_info(codec->dev, "Mic Bias: %s event is %02X", w->name, event);
++
++      if (!strncmp(w->name, mic_names[MIC_MAIN], strlen(mic_names[MIC_MAIN])))
++              mic = MIC_MAIN;
++      else if (!strncmp(w->name, mic_names[MIC_SUB],
++                        strlen(mic_names[MIC_SUB])))
++              mic = MIC_SUB;
++      else {
++              pr_err("Sound: Unknown dapm widget %s\n", w->name);
++              return 0;
++      }
++
++      if (!machine->mic_avail[mic]) {
++              dev_err(codec->dev, "%s is not available on this board",
++                      mic_names[mic]);
++              return 0;
++      }
++
++      if (gpio_is_valid(machine->gpio_mic_bias[mic])) {
++              switch (event) {
++              case SND_SOC_DAPM_PRE_PMU:
++                      pr_info("Sound: %s bias enable", mic_names[mic]);
++                      gpio_set_value(machine->gpio_mic_bias[mic], 1);
++                      /* add delay to remove main mic pop up noise */
++                      msleep(150);
++                      break;
++              case SND_SOC_DAPM_POST_PMD:
++                      pr_info("Sound: %s bias disable", mic_names[mic]);
++                      gpio_set_value(machine->gpio_mic_bias[mic], 0);
++                      break;
++              }
++      } else {
++              /* if EXYNOS gpio is not assigned to external ldo control
++                 that means MICBIAS1 (A9 pin) is used for mic bias supply */
++              switch (event) {
++              case SND_SOC_DAPM_PRE_PMU:
++                      pr_info("Sound: %s bias enable", mic_names[mic]);
++                      snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
++                              WM8994_MICB1_ENA_MASK, WM8994_MICB1_ENA);
++                      break;
++              case SND_SOC_DAPM_POST_PMD:
++                      pr_info("Sound: %s bias disable", mic_names[mic]);
++                      snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
++                              WM8994_MICB1_ENA_MASK, 0);
++                      break;
++              }
++      }
++
++      return 0;
++}
++
++static int exynos_snd_spkmode(struct snd_soc_dapm_widget *w,
++                           struct snd_kcontrol *kcontrol, int event)
++{
++      struct snd_soc_codec *codec = w->codec;
++      int ret = 0;
++
++      switch (event) {
++      case SND_SOC_DAPM_PRE_PMU:
++              dev_info(codec->dev, "set speaker L+R mix");
++              ret = snd_soc_update_bits(codec, WM8994_SPKOUT_MIXERS,
++                                WM8994_SPKMIXR_TO_SPKOUTL_MASK,
++                                WM8994_SPKMIXR_TO_SPKOUTL);
++              break;
++      case SND_SOC_DAPM_POST_PMD:
++              dev_info(codec->dev, "unset speaker L+R mix");
++              ret = snd_soc_update_bits(codec, WM8994_SPKOUT_MIXERS,
++                                WM8994_SPKMIXR_TO_SPKOUTL_MASK,
++                                0);
++              break;
++      }
++
++      return ret;
++}
++
++static int exynos_snd_vps_switch(struct snd_soc_dapm_widget *w,
++                           struct snd_kcontrol *kcontrol, int event)
++{
++      struct snd_soc_codec *codec = w->codec;
++      struct exynos_wm1811 *machine = snd_soc_card_get_drvdata(codec->card);
++
++      if (!gpio_is_valid(machine->gpio_vps_en))
++              return 0;
++
++      switch (event) {
++      case SND_SOC_DAPM_POST_PMU:
++              pr_info("vps switch enable");
++              gpio_set_value(machine->gpio_vps_en, 1);
++              break;
++      case SND_SOC_DAPM_PRE_PMD:
++              pr_info("vps switch disable");
++              gpio_set_value(machine->gpio_vps_en, 0);
++              break;
++      }
++
++      return 0;
++}
++
++static void codec_micd_set_rate(struct snd_soc_codec *codec)
++{
++      struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
++      int best, i, sysclk, val;
++      bool idle;
++      const struct wm8958_micd_rate *rates = NULL;
++      int num_rates = 0;
++
++      idle = !wm8994->jack_mic;
++
++      sysclk = snd_soc_read(codec, WM8994_CLOCKING_1);
++      if (sysclk & WM8994_SYSCLK_SRC)
++              sysclk = wm8994->aifclk[1];
++      else
++              sysclk = wm8994->aifclk[0];
++
++      if (wm8994->jackdet) {
++              rates = machine_jackdet_rates;
++              num_rates = ARRAY_SIZE(machine_jackdet_rates);
++      } else {
++              rates = machine_det_rates;
++              num_rates = ARRAY_SIZE(machine_det_rates);
++      }
++
++      best = 0;
++      for (i = 0; i < num_rates; i++) {
++              if (rates[i].idle != idle)
++                      continue;
++              if (abs(rates[i].sysclk - sysclk) <
++                  abs(rates[best].sysclk - sysclk))
++                      best = i;
++              else if (rates[best].idle != idle)
++                      best = i;
++      }
++
++      val = rates[best].start << WM8958_MICD_BIAS_STARTTIME_SHIFT
++              | rates[best].rate << WM8958_MICD_RATE_SHIFT;
++
++      snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
++                          WM8958_MICD_BIAS_STARTTIME_MASK |
++                          WM8958_MICD_RATE_MASK, val);
++}
++
++static void codec_micdet(u16 status, void *data)
++{
++      struct exynos_wm1811 *machine = data;
++      struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(machine->codec);
++      int report;
++      static int check_report;
++
++      dev_info(machine->codec->dev, "jack status 0x%x", status);
++      /*
++       * LCD is still off even though earjack event has occurred.
++       * So platform daemon need time to deal this event
++       */
++      pm_wakeup_event(machine->codec->dev, 500);
++      /* Either nothing present or just starting detection */
++      if (!(status & WM8958_MICD_STS)) {
++              if (!wm8994->jackdet) {
++                      /* If nothing present then clear our statuses */
++                      dev_dbg(machine->codec->dev, "Detected open circuit\n");
++                      wm8994->jack_mic = false;
++                      wm8994->mic_detecting = true;
++
++                      codec_micd_set_rate(machine->codec);
++
++                      snd_soc_jack_report(wm8994->micdet[0].jack, 0,
++                                          wm8994->btn_mask |
++                                           SND_JACK_HEADSET);
++              }
++              return;
++      }
++      /*
++       * If the measurement is showing a high impedence we've got
++       * a microphone.
++       */
++      if (wm8994->mic_detecting && (status & 0x400)) {
++              dev_info(machine->codec->dev, "Detected microphone\n");
++
++              wm8994->mic_detecting = false;
++              wm8994->jack_mic = true;
++
++              codec_micd_set_rate(machine->codec);
++
++              snd_soc_jack_report(wm8994->micdet[0].jack,
++                              SND_JACK_HEADSET, SND_JACK_HEADSET);
++      }
++
++      if (wm8994->mic_detecting && status & 0x4) {
++              dev_info(machine->codec->dev, "Detected headphone\n");
++              wm8994->mic_detecting = false;
++
++              codec_micd_set_rate(machine->codec);
++
++              snd_soc_jack_report(wm8994->micdet[0].jack,
++                              SND_JACK_HEADPHONE, SND_JACK_HEADSET);
++
++              /* If we have jackdet that will detect removal */
++              if (wm8994->jackdet) {
++                      mutex_lock(&wm8994->accdet_lock);
++
++                      snd_soc_update_bits(machine->codec,
++                                      WM8958_MIC_DETECT_1,
++                                      WM8958_MICD_ENA, 0);
++
++                      if (wm8994->active_refcount) {
++                              snd_soc_update_bits(machine->codec,
++                                      WM8994_ANTIPOP_2,
++                                      WM1811_JACKDET_MODE_MASK,
++                                      WM1811_JACKDET_MODE_AUDIO);
++                      }
++
++                      mutex_unlock(&wm8994->accdet_lock);
++#if 0
++                      if (wm8994->pdata->jd_ext_cap) {
++                              mutex_lock(&wm1811->codec->mutex);
++                              snd_soc_dapm_disable_pin(&wm1811->codec->dapm,
++                                                      "MICBIAS2");
++                              snd_soc_dapm_sync(&wm1811->codec->dapm);
++                              mutex_unlock(&wm1811->codec->mutex);
++                      }
++#endif
++
++              }
++      }
++
++      /* Report short circuit as a button */
++      if (wm8994->jack_mic) {
++              report = 0;
++              if (status & WM1811_JACKDET_BTN0)
++                      report |= SND_JACK_BTN_0;
++
++              if (status & WM1811_JACKDET_BTN1)
++                      report |= SND_JACK_BTN_1;
++
++              if (status & WM1811_JACKDET_BTN2)
++                      report |= SND_JACK_BTN_2;
++
++              /* TODO : Check this on wm1811a */
++              if (check_report != report) {
++                      dev_info(machine->codec->dev,
++                              "Report Button: %08x (%08X)", report, status);
++                      snd_soc_jack_report(wm8994->micdet[0].jack, report,
++                                          wm8994->btn_mask);
++                      check_report = report;
++              } else
++                      dev_info(machine->codec->dev, "Skip button report");
++      }
++}
++
++#ifndef CONFIG_SND_SAMSUNG_I2S_MASTER
++static int machine_aif1_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_dai *cpu_dai = rtd->cpu_dai;
++      struct snd_soc_dai *codec_dai = rtd->codec_dai;
++      unsigned int pll_out;
++      int ret;
++
++      pr_info("params_rate: %d\n", params_rate(params));
++
++      if (params_rate(params) == 8000 || params_rate(params) == 11025)
++              pll_out = params_rate(params) * 512;
++      else
++              pll_out = params_rate(params) * 256;
++
++      ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
++                                      | SND_SOC_DAIFMT_NB_NF
++                                      | SND_SOC_DAIFMT_CBM_CFM);
++      if (ret < 0)
++              return ret;
++
++      /* Set the cpu DAI configuration */
++      ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
++                                      | SND_SOC_DAIFMT_NB_NF
++                                      | SND_SOC_DAIFMT_CBM_CFM);
++      if (ret < 0)
++              return ret;
++
++      /* Switch FLL */
++      ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_MCLK1,
++                                XTAL_24MHZ_AP, pll_out);
++      if (ret < 0)
++              dev_err(codec_dai->dev, "Unable to start FLL1: %d\n", ret);
++
++      ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1,
++                                   pll_out, SND_SOC_CLOCK_IN);
++      if (ret < 0) {
++              dev_err(codec_dai->dev,
++                      "Unable to switch to FLL1: %d\n", ret);
++              return ret;
++      }
++
++      ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_OPCLK,
++                                      0, MOD_OPCLK_PCLK);
++      if (ret < 0) {
++              dev_err(cpu_dai->dev,
++                      "Unable to set i2s opclk: 0x%x\n", ret);
++              return ret;
++      }
++
++      codec_micd_set_rate(codec_dai->codec);
++
++      dev_info(codec_dai->dev,
++              "AIF1 DAI %s params ch %d, rate %d as i2s slave\n",
++              ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? \
++                                              "playback" : "capture"),
++                                              params_channels(params),
++                                              params_rate(params));
++      return 0;
++}
++#else /* CONFIG_SND_SAMSUNG_I2S_MASTER */
++
++static int machine_aif1_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_dai *codec_dai = rtd->codec_dai;
++      struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
++      int bfs, psr, rfs, ret;
++      unsigned long rclk, epll_freq;
++
++      switch (params_format(params)) {
++      case SNDRV_PCM_FORMAT_U24:
++      case SNDRV_PCM_FORMAT_S24:
++              bfs = 48;
++              break;
++      case SNDRV_PCM_FORMAT_U16_LE:
++      case SNDRV_PCM_FORMAT_S16_LE:
++              bfs = 32;
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      switch (params_rate(params)) {
++      case 16000:
++      case 22050:
++      case 24000:
++      case 32000:
++      case 44100:
++      case 48000:
++      case 88200:
++      case 96000:
++              if (bfs == 48)
++                      rfs = 384;
++              else
++                      rfs = 256;
++              break;
++      case 64000:
++              rfs = 384;
++              break;
++      case 8000:
++      case 11025:
++      case 12000:
++              if (bfs == 48)
++                      rfs = 768;
++              else
++                      rfs = 512;
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      rclk = params_rate(params) * rfs;
++
++      switch (rclk) {
++      case 4096000:
++      case 5644800:
++      case 6144000:
++      case 8467200:
++      case 9216000:
++              psr = 8;
++              break;
++      case 8192000:
++      case 11289600:
++      case 12288000:
++      case 16934400:
++      case 18432000:
++              psr = 4;
++              break;
++      case 22579200:
++      case 24576000:
++      case 33868800:
++      case 36864000:
++              psr = 2;
++              break;
++      case 67737600:
++      case 73728000:
++              psr = 1;
++              break;
++      default:
++              printk(KERN_INFO "Not yet supported!\n");
++              return -EINVAL;
++      }
++
++      epll_freq = rclk * psr;
++
++      if (epll_freq != clk_get_rate(machine->clk_pll)) {
++              ret = clk_set_rate(machine->clk_pll, epll_freq);
++              if (ret < 0)
++                      return ret;
++              pr_info("%s: fout_epll: %ld (%ld) Hz\n", __func__,
++                      clk_get_rate(machine->clk_pll), epll_freq);
++      }
++
++      ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
++                                      | SND_SOC_DAIFMT_NB_NF
++                                      | SND_SOC_DAIFMT_CBS_CFS);
++      if (ret < 0)
++              return ret;
++
++      ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
++                                      | SND_SOC_DAIFMT_NB_NF
++                                      | SND_SOC_DAIFMT_CBS_CFS);
++      if (ret < 0)
++              return ret;
++
++      ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK1,
++                                      rclk, SND_SOC_CLOCK_IN);
++      if (ret < 0)
++              return ret;
++
++      ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_CDCLK,
++                                      0, SND_SOC_CLOCK_OUT);
++      if (ret < 0)
++              return ret;
++
++      ret = snd_soc_dai_set_clkdiv(cpu_dai, SAMSUNG_I2S_DIV_BCLK, bfs);
++      if (ret < 0)
++              return ret;
++
++      return 0;
++}
++#endif /* CONFIG_SND_SAMSUNG_I2S_MASTER */
++
++/*
++ * WM1811 DAI operations.
++ */
++static struct snd_soc_ops machine_aif1_ops = {
++      .hw_params = machine_aif1_hw_params,
++};
++
++static int machine_aif2_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_dai *codec_dai = rtd->codec_dai;
++      int ret;
++      int prate;
++      int bclk;
++      unsigned int fmt;
++      int pll_src;
++      unsigned int pll_freq_in;
++
++      prate = params_rate(params);
++      switch (params_rate(params)) {
++      case 8000:
++      case 16000:
++             break;
++      default:
++              dev_warn(codec_dai->dev, "Unsupported LRCLK %d, falling back to 8kHz\n",
++                      (int)params_rate(params));
++              prate = 8000;
++      }
++
++      fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF;
++      if (aif2_mode == MODE_CODEC_SLAVE)
++              fmt |= SND_SOC_DAIFMT_CBS_CFS;
++      else /* MODE_CODEC_MASTER */
++              fmt |= SND_SOC_DAIFMT_CBM_CFM;
++
++      /* Set the codec DAI configuration */
++      ret = snd_soc_dai_set_fmt(codec_dai, fmt);
++
++      if (ret < 0)
++              return ret;
++
++      switch (prate) {
++      case 8000:
++              bclk = 256000;
++              break;
++      case 16000:
++              bclk = 512000;
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      if (aif2_mode == MODE_CODEC_SLAVE) {
++              pll_src = WM8994_FLL_SRC_BCLK;
++              pll_freq_in = bclk;
++      } else {
++              pll_src = WM8994_FLL_SRC_MCLK1;
++              pll_freq_in = XTAL_24MHZ_AP;
++      }
++      ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2,
++                              pll_src, pll_freq_in,
++                              prate * 256);
++      if (ret < 0)
++              dev_err(codec_dai->dev, "Unable to configure FLL2: %d\n", ret);
++
++      ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL2,
++                                      prate * 256, SND_SOC_CLOCK_IN);
++      if (ret < 0)
++              dev_err(codec_dai->dev, "Unable to switch to FLL2: %d\n", ret);
++
++      dev_info(codec_dai->dev,
++              "AIF2 DAI %s params ch %d, rate %d as Clock %s\n",
++              ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? \
++                                              "playback" : "capture"),
++                                              params_channels(params),
++                                              params_rate(params),
++                                              aif2_mode_text[aif2_mode]);
++      return 0;
++}
++
++static struct snd_soc_ops machine_aif2_ops = {
++      .hw_params = machine_aif2_hw_params,
++};
++
++static int machine_aif3_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_dai *codec_dai = rtd->codec_dai;
++
++      dev_info(codec_dai->dev, "AIF3 DAI %s params ch %d, rate %d\n",
++              ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? \
++                                              "playback" : "capture"),
++                                              params_channels(params),
++                                              params_rate(params));
++      return 0;
++}
++
++static struct snd_soc_ops machine_aif3_ops = {
++      .hw_params = machine_aif3_hw_params,
++};
++
++static const struct snd_kcontrol_new card_controls[] = {
++      SOC_DAPM_PIN_SWITCH("HP"),
++      SOC_DAPM_PIN_SWITCH("SPK"),
++      SOC_DAPM_PIN_SWITCH("RCV"),
++      SOC_DAPM_PIN_SWITCH("LINE"),
++      SOC_DAPM_PIN_SWITCH("HDMI"),
++
++      SOC_DAPM_PIN_SWITCH("Main Mic"),
++      SOC_DAPM_PIN_SWITCH("Sub Mic"),
++      SOC_DAPM_PIN_SWITCH("Headset Mic"),
++};
++
++static const struct snd_kcontrol_new codec_controls[] = {
++      SOC_ENUM_EXT("AIF2 Mode", aif2_mode_enum[0],
++              get_aif2_mode, set_aif2_mode),
++};
++
++const struct snd_soc_dapm_widget machine_dapm_widgets[] = {
++      SND_SOC_DAPM_HP("HP", NULL),
++      SND_SOC_DAPM_SPKMODE("SPK", exynos_snd_spkmode),
++      SND_SOC_DAPM_SPK("RCV", NULL),
++      SND_SOC_DAPM_LINE("LINE", exynos_snd_vps_switch),
++      SND_SOC_DAPM_LINE("HDMI", NULL),
++
++      SND_SOC_DAPM_MIC("Headset Mic", NULL),
++      SND_SOC_DAPM_MIC("Main Mic", exynos_snd_micbias),
++      SND_SOC_DAPM_MIC("Sub Mic", exynos_snd_micbias),
++
++};
++
++const struct snd_soc_dapm_route machine_dapm_routes[] = {
++      { "HP", NULL, "HPOUT1L" },
++      { "HP", NULL, "HPOUT1R" },
++
++      { "SPK", NULL, "SPKOUTLN" },
++      { "SPK", NULL, "SPKOUTLP" },
++      { "SPK", NULL, "SPKOUTRN" },
++      { "SPK", NULL, "SPKOUTRP" },
++
++      { "RCV", NULL, "HPOUT2N" },
++      { "RCV", NULL, "HPOUT2P" },
++
++      { "LINE", NULL, "LINEOUT2N" },
++      { "LINE", NULL, "LINEOUT2P" },
++
++      { "HDMI", NULL, "LINEOUT1N" }, /* Not connected */
++      { "HDMI", NULL, "LINEOUT1P" }, /* Not connected */
++};
++
++const struct snd_soc_dapm_route wm1811_input_dapm_routes[] = {
++      { "IN1LP", NULL, "Main Mic" },
++      { "IN1LN", NULL, "Main Mic" },
++
++      { "IN1RP", NULL, "Sub Mic" },
++      { "IN1RN", NULL, "Sub Mic" },
++
++      { "IN2LP:VXRN", NULL, "MICBIAS2" },
++      { "MICBIAS2", NULL, "Headset Mic" },
++};
++
++const struct snd_soc_dapm_route redwood_input_dapm_routes[] = {
++      { "IN1LP", NULL, "Main Mic" },
++      { "IN1LN", NULL, "Main Mic" },
++
++      { "IN1RP", NULL, "MICBIAS2" },
++      { "IN1RN", NULL, "MICBIAS2" },
++
++      { "IN2LP:VXRN", NULL, "MICBIAS2" },
++      { "MICBIAS2", NULL, "Headset Mic" },
++};
++
++const struct snd_soc_dapm_route redwood45_input_dapm_routes[] = {
++      { "IN2LP:VXRN", NULL, "Main Mic" },
++      { "IN2LN", NULL, "Main Mic" },
++
++      /* if add route of MICBIAS1 to "Sub Mic",
++         it could be automatically controlled by dapm sequence
++         but we have alternative boards of n035 and redwood45
++         so MICBIAS1 should be controlled another SND_SOC_DAPM_MIC
++         "Sub Mic" control function */
++      { "IN1RP", NULL, "Sub Mic" },
++      { "IN1RN", NULL, "Sub Mic" },
++
++      { "IN1RP", NULL, "MICBIAS2" },
++      { "MICBIAS2", NULL, "Headset Mic" },
++};
++
++static ssize_t earjack_select_jack_show(struct device *dev,
++      struct device_attribute *attr, char *buf)
++{
++      pr_info("Sound: %s operate nothing", __func__);
++
++      return 0;
++}
++
++static ssize_t earjack_select_jack_store(struct device *dev,
++      struct device_attribute *attr, const char *buf, size_t size)
++{
++      struct snd_soc_codec *codec = dev_get_drvdata(dev);
++      struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
++      int report = 0;
++
++      wm8994->mic_detecting = false;
++      wm8994->jack_mic = true;
++
++      codec_micd_set_rate(codec);
++
++      if ((!size) || (buf[0] == '0')) {
++              snd_soc_jack_report(wm8994->micdet[0].jack,
++                                  0, SND_JACK_HEADSET);
++              dev_info(codec->dev, "Forced remove earjack\n");
++      } else {
++              if (buf[0] == '1') {
++                      dev_info(codec->dev, "Forced detect microphone\n");
++                      report = SND_JACK_HEADSET;
++              } else {
++                      dev_info(codec->dev, "Forced detect headphone\n");
++                      report = SND_JACK_HEADPHONE;
++              }
++              snd_soc_jack_report(wm8994->micdet[0].jack,
++                                  report, SND_JACK_HEADSET);
++      }
++
++      return size;
++}
++
++static DEVICE_ATTR(select_jack, S_IRUGO | S_IWUSR | S_IWGRP,
++                 earjack_select_jack_show, earjack_select_jack_store);
++
++static ssize_t audio_caps_cp_show(struct device *dev,
++                      struct device_attribute *attr, char *buf)
++{
++      struct exynos_wm1811 *machine = dev_get_drvdata(dev);
++
++      if (machine->cp_wb_support == true)
++              return sprintf(buf, "wb\n") + 1;
++      else
++              return sprintf(buf, "nb\n") + 1;
++}
++static DEVICE_ATTR(cp_caps, S_IRUGO, audio_caps_cp_show, NULL);
++
++static ssize_t audio_caps_mic_count_show(struct device *dev,
++              struct device_attribute *attr, char *buf)
++{
++      struct exynos_wm1811 *machine = dev_get_drvdata(dev);
++      int i, cnt = 0;
++
++      if (!machine)
++              return 0;
++
++      for (i = 0; i < MIC_MAX; i++) {
++              if (machine->mic_avail[i])
++                      cnt++;
++      }
++
++      return sprintf(buf, "%d\n", cnt);
++}
++static DEVICE_ATTR(mic_count, S_IRUGO, audio_caps_mic_count_show, NULL);
++
++static int machine_init_paiftx(struct snd_soc_pcm_runtime *rtd)
++{
++      struct snd_soc_codec *codec = rtd->codec;
++      struct snd_soc_card *card = rtd->card;
++      struct exynos_wm1811 *machine = snd_soc_card_get_drvdata(card);
++      struct snd_soc_dai *aif1_dai = rtd->codec_dai;
++      struct wm8994 *wm8994 = dev_get_drvdata(codec->dev->parent);
++      int ret;
++
++      ret = clk_prepare_enable(machine->codec_mclk);
++      if (ret < 0)
++              return ret;
++
++      ret = snd_soc_add_card_controls(card, card_controls,
++                                      ARRAY_SIZE(card_controls));
++      if (ret != 0)
++              dev_err(card->dev, "Failed to add card ctrls: %d\n", ret);
++
++      ret = snd_soc_add_codec_controls(codec, codec_controls,
++                                      ARRAY_SIZE(codec_controls));
++      if (ret != 0)
++              dev_err(codec->dev, "Failed to add codec ctrls: %d\n", ret);
++
++      ret = snd_soc_dapm_new_controls(&codec->dapm, machine_dapm_widgets,
++                                         ARRAY_SIZE(machine_dapm_widgets));
++      if (ret != 0)
++              dev_err(codec->dev, "Failed to add DAPM widgets: %d\n", ret);
++
++      ret = snd_soc_dapm_add_routes(&codec->dapm, machine_dapm_routes,
++                                         ARRAY_SIZE(machine_dapm_routes));
++      if (ret != 0)
++              dev_err(codec->dev, "Failed to add DAPM routes: %d\n", ret);
++
++      if (!strcmp(card->name, "redwood45")) {
++              ret = snd_soc_dapm_add_routes(&codec->dapm,
++                              redwood45_input_dapm_routes,
++                              ARRAY_SIZE(redwood45_input_dapm_routes));
++      } else if (!strcmp(card->name, "redwood")) {
++              ret = snd_soc_dapm_add_routes(&codec->dapm,
++                                      redwood_input_dapm_routes,
++                                      ARRAY_SIZE(redwood_input_dapm_routes));
++      } else {
++              ret = snd_soc_dapm_add_routes(&codec->dapm,
++                                      wm1811_input_dapm_routes,
++                                      ARRAY_SIZE(wm1811_input_dapm_routes));
++      }
++
++      if (ret != 0)
++              dev_err(codec->dev,
++                      "Failed to add DAPM input routes: %d\n", ret);
++
++      ret = snd_soc_dai_set_sysclk(aif1_dai, WM8994_SYSCLK_MCLK2,
++                                   CODEC_CLK32K, SND_SOC_CLOCK_IN);
++      if (ret < 0)
++              dev_err(codec->dev, "Failed to boot clocking\n");
++
++      /* Force AIF1CLK on as it will be master for jack detection */
++      ret = snd_soc_dapm_force_enable_pin(&codec->dapm, "AIF1CLK");
++      if (ret < 0)
++              dev_err(codec->dev, "Failed to enable AIF1CLK: %d\n", ret);
++
++      /* check sub mic support */
++      if (machine && !machine->mic_avail[MIC_SUB])
++              snd_soc_dapm_nc_pin(&codec->dapm, "Sub Mic");
++      else
++              snd_soc_dapm_ignore_suspend(&codec->dapm, "Sub Mic");
++
++      /* check earjack support */
++      if (machine->ignore_earjack)
++              snd_soc_dapm_nc_pin(&codec->dapm, "Headset Mic");
++      else
++              snd_soc_dapm_ignore_suspend(&codec->dapm, "Headset Mic");
++
++      /* disable codec ldo for mic mias when using ext mic bias */
++      if (!machine->gpio_mic_bias[MIC_MAIN] &&
++          !machine->gpio_mic_bias[MIC_SUB])
++              snd_soc_dapm_nc_pin(&codec->dapm, "MICBIAS1");
++
++      /* disable fm radio analog input */
++      snd_soc_dapm_nc_pin(&codec->dapm, "IN2RN");
++      snd_soc_dapm_nc_pin(&codec->dapm, "IN2RP:VXRP");
++
++      snd_soc_dapm_ignore_suspend(&codec->dapm, "RCV");
++      snd_soc_dapm_ignore_suspend(&codec->dapm, "SPK");
++      snd_soc_dapm_ignore_suspend(&codec->dapm, "HP");
++      snd_soc_dapm_ignore_suspend(&codec->dapm, "Main Mic");
++      snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF1DACDAT");
++      snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF2DACDAT");
++      snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF3DACDAT");
++      snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF1ADCDAT");
++      snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF2ADCDAT");
++      snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF3ADCDAT");
++
++      machine->codec = codec;
++
++      codec_micd_set_rate(codec);
++
++      ret = snd_soc_jack_new(codec, "Headset Jack",
++                              SND_JACK_HEADSET | SND_JACK_BTN_0 |
++                              SND_JACK_BTN_1 | SND_JACK_BTN_2,
++                              &machine->jack);
++      if (ret < 0)
++              dev_err(codec->dev, "Failed to create jack: %d\n", ret);
++
++      ret = snd_jack_set_key(machine->jack.jack, SND_JACK_BTN_0, KEY_MEDIA);
++      if (ret < 0)
++              dev_err(codec->dev, "Failed to set KEY_MEDIA: %d\n", ret);
++
++      ret = snd_jack_set_key(machine->jack.jack, SND_JACK_BTN_1,
++                                                      KEY_VOLUMEDOWN);
++      if (ret < 0)
++              dev_err(codec->dev, "Failed to set KEY_VOLUMEUP: %d\n", ret);
++
++      ret = snd_jack_set_key(machine->jack.jack, SND_JACK_BTN_2,
++                                                      KEY_VOLUMEUP);
++      if (ret < 0)
++              dev_err(codec->dev, "Failed to set KEY_VOLUMEDOWN: %d\n", ret);
++
++      /* TODO : check this on fast boot environment */
++      machine->jack.status = 0;
++
++      /* check earjack support */
++      if (machine->ignore_earjack) {
++              dev_info(codec->dev,
++                      "Earjack event doesn't support for this board");
++              ret = snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
++                              WM8958_MICD_ENA, 0);
++              if (ret < 0)
++                      dev_err(codec->dev,
++                              "Failed to disable mic detection: %d\n", ret);
++      } else {
++#if 0
++              ret = wm8958_mic_detect(codec,
++                              &machine->jack, codec_micdet, machine);
++              if (ret < 0)
++                      dev_err(codec->dev,
++                              "Failed start detection: %d\n", ret);
++#endif
++              /* To wakeup for earjack event in suspend mode */
++              enable_irq_wake(wm8994->irq);
++              device_init_wakeup(machine->codec->dev, true);
++      }
++
++      /* To support PBA function test */
++      audio_class = class_create(THIS_MODULE, "audio");
++
++      if (IS_ERR(audio_class))
++              pr_err("Failed to create class\n");
++
++      jack_dev = device_create(audio_class, NULL, 0, codec, "earjack");
++
++      if (device_create_file(jack_dev, &dev_attr_select_jack) < 0)
++              pr_err("Failed to create device file (%s)!\n",
++                      dev_attr_select_jack.attr.name);
++
++      caps_dev = device_create(audio_class, NULL, 0, NULL, "caps");
++      dev_set_drvdata(caps_dev, machine);
++
++      if (device_create_file(caps_dev, &dev_attr_cp_caps) < 0)
++              pr_err("Failed to create device file (%s)!\n",
++                      dev_attr_cp_caps.attr.name);
++
++      if (device_create_file(caps_dev, &dev_attr_mic_count) < 0)
++              pr_err("Failed to create device file (%s)!\n",
++                      dev_attr_mic_count.attr.name);
++
++      return snd_soc_dapm_sync(&codec->dapm);
++}
++
++static struct snd_soc_dai_link machine_dai[] = {
++      {
++              /* Primary DAI i/f */
++              .name = "WM1811 AIF1",
++              .stream_name = "Pri_Dai",
++              .cpu_dai_name = "samsung-i2s.0",
++              .codec_dai_name = "wm8994-aif1",
++              .platform_name = "samsung-i2s.0",
++              .codec_name = "wm8994-codec",
++              .init = machine_init_paiftx,
++              .ops = &machine_aif1_ops,
++      }, {
++              .name = "WM1811 Voice",
++              .stream_name = "Voice Tx/Rx",
++              .cpu_dai_name = "voice-modem",
++              .codec_dai_name = "wm8994-aif2",
++              .platform_name = "snd-soc-dummy",
++              .codec_name = "wm8994-codec",
++              .ops = &machine_aif2_ops,
++              .ignore_suspend = 1,
++      }, {
++              .name = "WM1811 BT",
++              .stream_name = "BT Tx/Rx",
++              .cpu_dai_name = "voice-bluetooth",
++              .codec_dai_name = "wm8994-aif3",
++              .platform_name = "snd-soc-dummy",
++              .codec_name = "wm8994-codec",
++              .ops = &machine_aif3_ops,
++              .ignore_suspend = 1,
++      }, {
++              /* Sec_Fifo DAI i/f */
++              .cpu_dai_name = "samsung-i2s.4",
++              .codec_dai_name = "wm8994-aif1",
++#ifdef CONFIG_SND_SAMSUNG_USE_IDMA
++              .name = "Sec_FIFO TX",
++              .stream_name = "Sec_Dai",
++              .platform_name = "samsung-idma",
++#else
++              .name = "WM1811 AIF1 Playback",
++              .stream_name = "Pri_Dai Playback",
++              .platform_name = "samsung-audio",
++#endif
++              .codec_name = "wm8994-codec",
++              .ops = &machine_aif1_ops,
++      },
++};
++
++static int machine_card_suspend_post(struct snd_soc_card *card)
++{
++      struct exynos_wm1811 *machine = snd_soc_card_get_drvdata(card);
++      struct snd_soc_codec *codec = card->rtd->codec;
++      struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai;
++      struct snd_soc_dai *aif2_dai = card->rtd[1].codec_dai;
++      int ret;
++
++
++      if (!codec->active) {
++              /* change sysclk from pll out of mclk1 to mclk2
++                 to disable mclk1 from AP */
++              dev_info(codec->dev, "use mclk2 and disable fll");
++              ret = snd_soc_dai_set_sysclk(aif2_dai,
++                              WM8994_SYSCLK_MCLK2,
++                              CODEC_CLK32K,
++                              SND_SOC_CLOCK_IN);
++              if (ret < 0)
++                      dev_err(codec->dev,
++                      "Unable to switch aif2 sysclk to MCLK2: %d\n", ret);
++
++              ret = snd_soc_dai_set_pll(aif2_dai, WM8994_FLL2, 0, 0, 0);
++              if (ret < 0)
++                      dev_err(codec->dev,
++                              "Unable to stop FLL2: %d\n", ret);
++
++              ret = snd_soc_dai_set_sysclk(aif1_dai,
++                              WM8994_SYSCLK_MCLK2,
++                              CODEC_CLK32K,
++                              SND_SOC_CLOCK_IN);
++              if (ret < 0)
++                      dev_err(codec->dev,
++                      "Unable to switch aif1 sysclk to MCLK2: %d\n", ret);
++
++              ret = snd_soc_dai_set_pll(aif1_dai, WM8994_FLL1, 0, 0, 0);
++              if (ret < 0)
++                      dev_err(codec->dev, "Unsable to stop FLL1: 0x%x", ret);
++
++              /* Jack det rate and mic det rate should be changed
++              to match the above changed sysclk */
++              codec_micd_set_rate(codec);
++
++              clk_disable_unprepare(machine->codec_mclk);
++      }
++
++      snd_soc_dapm_sync(&codec->dapm);
++      return 0;
++}
++
++static int machine_card_resume_pre(struct snd_soc_card *card)
++{
++      struct exynos_wm1811 *machine = snd_soc_card_get_drvdata(card);
++      struct snd_soc_codec *codec = card->rtd->codec;
++      struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai;
++      int reg = 0;
++      int ret;
++
++      if (!codec->active)
++              clk_prepare_enable(machine->codec_mclk);
++
++      /* change sysclk from mclk2 to pll out of mclk1 */
++      ret = snd_soc_dai_set_pll(aif1_dai, WM8994_FLL1,
++                      WM8994_FLL_SRC_MCLK1,
++                      XTAL_24MHZ_AP,
++                      CODEC_DEFAULT_SYNC_CLK);
++      if (ret < 0)
++              dev_err(aif1_dai->dev, "Unable to start FLL1: 0x%x\n", ret);
++
++      ret = snd_soc_dai_set_sysclk(aif1_dai, WM8994_SYSCLK_FLL1,
++                      CODEC_DEFAULT_SYNC_CLK, SND_SOC_CLOCK_IN);
++      if (ret < 0)
++              dev_err(aif1_dai->dev,
++                      "Unable to switch sysclk to FLL1: 0x%x\n", ret);
++
++      codec_micd_set_rate(codec);
++
++      /* workaround for jack detection
++       * sometimes WM8994_GPIO_1 type changed wrong function type
++       * so if type mismatched, update to IRQ type
++       */
++      reg = snd_soc_read(codec, WM8994_GPIO_1);
++
++      if ((reg & WM8994_GPN_FN_MASK) != WM8994_GP_FN_IRQ) {
++              dev_err(codec->dev, "%s: GPIO1 type 0x%x\n", __func__, reg);
++              snd_soc_write(codec, WM8994_GPIO_1, WM8994_GP_FN_IRQ);
++      }
++
++      return 0;
++}
++
++static int exynos4_wm1811_parse_dt(struct exynos_wm1811 *machine,
++                                 struct device *dev)
++{
++      struct device_node *node = dev->of_node;
++      int gpio, ret, i;
++
++      of_property_read_u32_array(node, "samsung,mic-availability",
++                                 machine->mic_avail,
++                                 ARRAY_SIZE(machine->mic_avail));
++      machine->ignore_earjack = of_property_read_bool(node,
++                                      "samsung,ignore-earjack");
++      machine->cp_wb_support = of_property_read_bool(node, "samsung,cp-wb");
++      machine->gpio_vps_en = -EINVAL;
++
++      for (i = MIC_MAIN; i < MIC_MAX; i++) {
++              machine->gpio_mic_bias[i] = -EINVAL;
++
++              if (!machine->mic_avail[i])
++                      break;
++
++              gpio = of_get_named_gpio(node, "samsung,mic-en-gpios", i);
++
++              if (!gpio_is_valid(gpio)) {
++                      dev_info(dev, "%s uses CODEC MICBIAS1\n", mic_names[i]);
++                      continue;
++              }
++              ret = devm_gpio_request_one(dev, gpio, GPIOF_OUT_INIT_LOW,
++                                                      mic_names[i]);
++              if (ret) {
++                      dev_err(dev, "%s gpio request failed\n", mic_names[i]);
++                      continue;
++              }
++              dev_info(dev, "%s enable GPIO initialized\n", mic_names[i]);
++              machine->gpio_mic_bias[i] = gpio;
++      }
++
++      gpio = of_get_named_gpio(node, "samsung,vps-en-gpios", 0);
++      if (!gpio_is_valid(gpio))
++              return 0;
++      ret = devm_gpio_request_one(dev, gpio, GPIOF_OUT_INIT_LOW, "wm1811");
++      if (!ret)
++              machine->gpio_vps_en = gpio;
++
++      pr_info("gpio: %d, ret: %d\n", ret, gpio);
++      return ret;
++}
++
++static int exynos4_wm1811_probe(struct platform_device *pdev)
++{
++      struct snd_soc_dai_link *dai_link = &machine_dai[0];
++      struct exynos_wm1811 *machine;
++      struct snd_soc_card *card;
++      struct clk *parent, *out_mux;
++      int ret;
++
++      if (!pdev->dev.of_node)
++              return -ENODEV;
++
++      card = devm_kzalloc(&pdev->dev, sizeof(*card), GFP_KERNEL);
++      if (!card)
++              return -ENOMEM;
++
++      card->dai_link = machine_dai;
++      /* FIXME: Enable all audio interfaces */
++      card->num_links = 1; /* ARRAY_SIZE(machine_dai); */
++      card->suspend_post = machine_card_suspend_post;
++      card->resume_pre = machine_card_resume_pre;
++      card->dev = &pdev->dev;
++
++      machine = devm_kzalloc(&pdev->dev, sizeof(*machine), GFP_KERNEL);
++      if (!machine)
++              return -ENOMEM;
++
++      ret = exynos4_wm1811_parse_dt(machine, &pdev->dev);
++      if (ret < 0)
++              return ret;
++
++      dai_link->cpu_dai_name = NULL;
++      dai_link->cpu_of_node = of_parse_phandle(pdev->dev.of_node,
++                                              "samsung,i2s-controller", 0);
++      if (dai_link->cpu_of_node == NULL) {
++              dev_err(&pdev->dev, "i2s-controller property parse error\n");
++              return -EINVAL;
++      }
++      dai_link->platform_name = NULL;
++      dai_link->platform_of_node = dai_link->cpu_of_node;
++
++      machine->codec_mclk = clk_get(&pdev->dev, "out");
++      if (IS_ERR(machine->codec_mclk)) {
++              dev_err(&pdev->dev, "failed to get out clock\n");
++              return PTR_ERR(machine->codec_mclk);
++      }
++
++      out_mux = clk_get(&pdev->dev, "out-mux");
++      if (IS_ERR(out_mux)) {
++              dev_err(&pdev->dev, "failed to get out mux clock\n");
++              return PTR_ERR(out_mux);
++      }
++
++      parent = clk_get(&pdev->dev, "parent");
++      if (IS_ERR(parent)) {
++              dev_err(&pdev->dev, "failed to get parent clock\n");
++              return PTR_ERR(parent);
++      }
++
++      clk_set_parent(out_mux, parent);
++
++      machine->clk_pll = clk_get(&pdev->dev, "pll");
++      if (IS_ERR(machine->clk_pll)) {
++              dev_err(&pdev->dev, "failed to get pll clock\n");
++              return PTR_ERR(machine->clk_pll);
++      }
++
++      ret = snd_soc_of_parse_card_name(card, "samsung,model");
++      if (ret)
++              return -ENODEV;
++
++      dev_info(&pdev->dev, "Card name is %s\n", card->name);
++      /* FIXME: Clean up on error path */
++
++      snd_soc_card_set_drvdata(card, machine);
++
++      return snd_soc_register_card(card);
++}
++
++static int exynos4_wm1811_remove(struct platform_device *pdev)
++{
++      struct snd_soc_card *card = platform_get_drvdata(pdev);
++      struct exynos_wm1811 *machine = snd_soc_card_get_drvdata(card);
++
++      snd_soc_unregister_card(card);
++      clk_put(machine->codec_mclk);
++      clk_put(machine->clk_pll);
++      return 0;
++}
++
++static const struct of_device_id exynos4_wm1811_of_match[] = {
++      {
++              .compatible = "samsung,exynos4-wm1811",
++      },
++      { /* sentinel */ },
++};
++MODULE_DEVICE_TABLE(of, exynos4_wm1811_of_match);
++
++static struct platform_driver exynos4_wm1811_driver = {
++      .driver = {
++              .name = "exynos4-wm1811",
++              .of_match_table = exynos4_wm1811_of_match,
++              .owner = THIS_MODULE,
++              .pm = &snd_soc_pm_ops,
++      },
++      .probe = exynos4_wm1811_probe,
++      .remove = exynos4_wm1811_remove,
++};
++
++module_platform_driver(exynos4_wm1811_driver);
++
++MODULE_AUTHOR("KwangHui Cho <kwanghui.cho@samsung.com>");
++MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
++MODULE_DESCRIPTION("Exynos4+WM1811 machine ASoC driver");
++MODULE_LICENSE("GPL");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0159-ARM-dts-Add-audio-device-nodes-for-PQ-board.patch b/patches.tizen/0159-ARM-dts-Add-audio-device-nodes-for-PQ-board.patch
new file mode 100644 (file)
index 0000000..0a22798
--- /dev/null
@@ -0,0 +1,119 @@
+From 9759e5759368dbdb0806dce2901c3ed85808c588 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 1 Mar 2013 19:22:32 +0100
+Subject: [PATCH 0159/1302] ARM: dts: Add audio device nodes for PQ board
+
+This patch adds wm1811 codec, I2S0 and the sound device nodes.
+
+TODO:
+ - regulator definitions may need to be corrected.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 75 +++++++++++++++++++++++++++++++++
+ 1 file changed, 75 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index df32808..08e45b1 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -188,6 +188,34 @@
+               };
+       };
++      i2c@138A0000 {
++              samsung,i2c-sda-delay = <100>;
++              samsung,i2c-max-bus-freq = <100000>;
++              pinctrl-0 = <&i2c4_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              wm1811: wm1811@1a {
++                      compatible = "wlf,wm1811";
++                      reg = <0x1a>;
++                      gpios = <&gpj0 4 0>; /* Temporary, LDO_EN */
++                      interrupt-parent = <&gpx3>;
++                      interrupts = <6 4>;
++
++                      DBVDD1-supply = <&ldo3_reg>;
++                      DBVDD2-supply = <&vbatt_reg>;
++                      DBVDD3-supply = <&vbatt_reg>;
++                      DCVDD-supply = <&vbatt_reg>;
++                      AVDD1-supply = <&vbatt_reg>;
++                      AVDD2-supply = <&vbatt_reg>;
++                      AVDD3-supply = <&vbatt_reg>;
++                      CPVDD-supply = <&vbatt_reg>;
++                      SPKVDD1-supply = <&vbatt_reg>;
++                      SPKVDD2-supply = <&vbatt_reg>;
++                      LDO1VDD-supply = <&vbatt_reg>;
++              };
++      };
++
+       i2c@138D0000 {
+               samsung,i2c-sda-delay = <100>;
+               samsung,i2c-slave-addr = <0x10>;
+@@ -508,6 +536,36 @@
+               regulator-always-on;
+       };
++      vbatt_reg: voltage-regulator@5 {
++              compatible = "regulator-fixed";
++              regulator-name = "VBATT";
++              regulator-min-microvolt = <5000000>;
++              regulator-max-microvolt = <5000000>;
++              gpio = <>;
++              regulator-always-on;
++      };
++
++      wm1811_regulator {
++              compatible = "wlf,wm8994-ldo";
++              status = "disabled";
++              voltage-regulators {
++                      wm1811_ldo1_reg: ldo@1 {
++                              regulator-compatible = "LDO1";
++                              regulator-name = "WM1811_LDO1";
++                              regulator-min-microvolt = <2400000>;
++                              regulator-max-microvolt = <2400000>;
++                      };
++
++                      wm1811_ldo2_reg: ldo@2 {
++                              regulator-compatible = "LDO2";
++                              regulator-name = "WM1811_LDO2";
++                              regulator-min-microvolt = <1200000>;
++                              regulator-max-microvolt = <1200000>;
++                              regulator-always-on;
++                      };
++              };
++      };
++
+       fimd0_lcd: panel {
+               compatible = "samsung,s6e8aa0";
+               reset-gpio = <&gpy4 5 0>;
+@@ -707,6 +765,23 @@
+               };
+       };
++      i2s0: i2s@03830000 {
++              pinctrl-0 = <&i2s0_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++      };
++
++      sound {
++              compatible = "samsung,exynos4-wm1811";
++              clocks = <&clock 2>, <&clock 395>, <&clock 21>, <&clock 6>;
++              clock-names = "parent", "out-mux", "out", "pll" /* EPLL */;
++              samsung,i2s-controller = <&i2s0>;
++              samsung,audio-codec = <&wm1811>;
++              samsung,model = "wm1811";
++              samsung,mic-availability = <1 1>;
++              samsung,mic-en-gpios = <&gpf1 7 0>, <&gpf2 0 0>;
++      };
++
+       gpu@13000000 {
+               status = "okay";
+               vdd_g3d-supply = <&buck4_reg>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0160-ARM-dts-Move-isp-i2c-node-to-root-level.patch b/patches.tizen/0160-ARM-dts-Move-isp-i2c-node-to-root-level.patch
new file mode 100644 (file)
index 0000000..a242fcd
--- /dev/null
@@ -0,0 +1,94 @@
+From 35bd5b1de8345de5276fc259d16e364bebb612dd Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Tue, 26 Feb 2013 17:40:10 +0100
+Subject: [PATCH 0160/1302] ARM: dts: Move isp-i2c node to root level
+
+There is no need for the ISP I2C controller nodes to be children
+of the fimc-is node. The I2C controllers could be also used as
+standalone devices, without relation to FIMC-IS.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 38 +++++++++++++++------------------
+ arch/arm/boot/dts/exynos4x12.dtsi       |  8 +++++++
+ 2 files changed, 25 insertions(+), 21 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 08e45b1..214b35b 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -651,6 +651,23 @@
+               };
+       };
++      i2c0_isp: i2c-isp@12130000 {
++              s5k6a3@10 {
++                      compatible = "samsung,s5k6a3";
++                      reg = <0x10>;
++                      svdda-supply = <&cam_io_reg>;
++                      svddio-supply = <&ldo19_reg>;
++                      clock-frequency = <24000000>;
++                      gpios = <&gpm1 6 0>;
++                      port {
++                              is_s5k6a3_ep: endpoint {
++                                      remote-endpoint = <&csis1_ep>;
++                                      data-lanes = <1>;
++                              };
++                      };
++              };
++      };
++
+       camera {
+               status = "okay";
+@@ -729,27 +746,6 @@
+                       fimc_lite_1: fimc-lite@123A0000 {
+                               status = "okay";
+                       };
+-
+-                      fimc-is-i2c@0 {
+-                              /* compatible = "samsung,exynos4212-is-i2c"; */
+-                              #address-cells = <1>;
+-                              #size-cells = <0>;
+-
+-                              s5k6a3@10 {
+-                                      compatible = "samsung,s5k6a3";
+-                                      reg = <0x10>;
+-                                      svdda-supply = <&cam_io_reg>;
+-                                      svddio-supply = <&ldo19_reg>;
+-                                      clock-frequency = <24000000>;
+-                                      gpios = <&gpm1 6 0>;
+-                                      port {
+-                                              is_s5k6a3_ep: endpoint {
+-                                                      remote-endpoint = <&csis1_ep>;
+-                                                      data-lanes = <1>;
+-                                              };
+-                                      };
+-                              };
+-                      };
+               };
+       };
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index 1e7784e..a85d168 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -194,6 +194,14 @@
+               };
+       };
++      i2c0_isp: i2c-isp@12130000 {
++              compatible = "samsung,exynos4212-is-i2c",
++                           "samsung,s3c2440-i2c";
++              reg = <0x12130000 0x100>;
++              #address-cells = <1>;
++              #size-cells = <0>;
++      };
++
+       camera {
+               clocks = <&clock 132>, <&clock 133>, <&clock 351>, <&clock 352>,
+                        <&clock 388>, <&clock 389>, <&clock 17>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0161-ARM-dts-Add-pmu-subnode-for-Exynos4-fimc-is-device.patch b/patches.tizen/0161-ARM-dts-Add-pmu-subnode-for-Exynos4-fimc-is-device.patch
new file mode 100644 (file)
index 0000000..205184a
--- /dev/null
@@ -0,0 +1,30 @@
+From 020683975a2bf412987504ff9b7673af50dff239 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Tue, 26 Feb 2013 16:54:27 +0100
+Subject: [PATCH 0161/1302] ARM: dts: Add pmu subnode for Exynos4 fimc-is
+ device
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12.dtsi | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index a85d168..ceb7218 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -256,6 +256,10 @@
+                       #size-cells = <1>;
+                       ranges;
++                      pmu {
++                              reg = <0x10020000 0x3000>;
++                      };
++
+                       fimc_lite_0: fimc-lite@12390000 {
+                               compatible = "samsung,exynos4212-fimc-lite";
+                               reg = <0x12390000 0x1000>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0162-m5mols-Fix-regulator_enable-errors-handling.patch b/patches.tizen/0162-m5mols-Fix-regulator_enable-errors-handling.patch
new file mode 100644 (file)
index 0000000..da40ee6
--- /dev/null
@@ -0,0 +1,45 @@
+From e47902a0cfdaee797a813608aeaf8c0608a2ef60 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Tue, 12 Mar 2013 18:00:46 +0100
+Subject: [PATCH 0162/1302] m5mols: Fix regulator_enable() errors handling
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This fixes following compilation warning:
+
+drivers/media/i2c/m5mols/m5mols_core.c: In function ‘m5mols_sensor_power’:
+drivers/media/i2c/m5mols/m5mols_core.c:754: warning: array subscript is above array bounds
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/m5mols/m5mols_core.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c
+index a8ae5d8..4d174c3 100644
+--- a/drivers/media/i2c/m5mols/m5mols_core.c
++++ b/drivers/media/i2c/m5mols/m5mols_core.c
+@@ -748,12 +748,14 @@ static int regulator_bulk_enable_sync(int num_consumers,
+       for (i = 0; i < ARRAY_SIZE(supplies); ++i) {
+               ret = regulator_enable(supplies[i].consumer);
++              if (ret < 0) {
++                      for (; i >= 0; --i)
++                              regulator_disable(supplies[i].consumer);
++                      return ret;
++              }
+       }
+-      if (ret < 0)
+-              for (; i >= 0; --i)
+-                      regulator_disable(supplies[i].consumer);
+-      return ret;
++      return 0;
+ }
+ static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0163-ARM-dts-exynos-re-enabled-ISP-power-domain.patch b/patches.tizen/0163-ARM-dts-exynos-re-enabled-ISP-power-domain.patch
new file mode 100644 (file)
index 0000000..c43718b
--- /dev/null
@@ -0,0 +1,34 @@
+From 1e3b5d934a9de60212ac516d06319469d1074e6e Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Mon, 11 Mar 2013 14:26:30 +0100
+Subject: [PATCH 0163/1302] ARM: dts: exynos: re-enabled ISP power domain
+
+ISP power domain could be enabled after fixing
+ISP clock flags in previous commit.
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12.dtsi | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index ceb7218..289062f 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -31,11 +31,7 @@
+       };
+       pd_isp: isp-power-domain@10023CA0 {
+-              /*
+-               * FIXME: ISP power domain needs special handling
+-               * (Implement proper ISP power domain on/off sequence)
+-               */
+-              /* compatible = "samsung,exynos4210-pd"; */
++              compatible = "samsung,exynos4210-pd";
+               reg = <0x10023CA0 0x20>;
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0164-sound-exynos4_wm1811-Disable-suspend-code-for-uninit.patch b/patches.tizen/0164-sound-exynos4_wm1811-Disable-suspend-code-for-uninit.patch
new file mode 100644 (file)
index 0000000..e1c3988
--- /dev/null
@@ -0,0 +1,42 @@
+From e54508aef75ad328879a0aaa9119846e6095b267 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 13 Mar 2013 20:02:57 +0100
+Subject: [PATCH 0164/1302] sound: exynos4_wm1811: Disable suspend code for
+ uninitialized AIF
+
+Currently there is only AIF1 interface initialized in this driver.
+Temporarily disable code that tries to suspend AIF2 until support
+for this interface is added.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ sound/soc/samsung/exynos4_wm1811.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/samsung/exynos4_wm1811.c b/sound/soc/samsung/exynos4_wm1811.c
+index fb6385f..a1dbce6 100644
+--- a/sound/soc/samsung/exynos4_wm1811.c
++++ b/sound/soc/samsung/exynos4_wm1811.c
+@@ -1083,6 +1083,9 @@ static int machine_card_suspend_post(struct snd_soc_card *card)
+               /* change sysclk from pll out of mclk1 to mclk2
+                  to disable mclk1 from AP */
+               dev_info(codec->dev, "use mclk2 and disable fll");
++
++/* Disable this code until support for AIF2 interface is added. */
++#if 0
+               ret = snd_soc_dai_set_sysclk(aif2_dai,
+                               WM8994_SYSCLK_MCLK2,
+                               CODEC_CLK32K,
+@@ -1095,7 +1098,7 @@ static int machine_card_suspend_post(struct snd_soc_card *card)
+               if (ret < 0)
+                       dev_err(codec->dev,
+                               "Unable to stop FLL2: %d\n", ret);
+-
++#endif
+               ret = snd_soc_dai_set_sysclk(aif1_dai,
+                               WM8994_SYSCLK_MCLK2,
+                               CODEC_CLK32K,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0165-ARM-dts-Add-detailed-FIMC-properties-to-exynos4x12.d.patch b/patches.tizen/0165-ARM-dts-Add-detailed-FIMC-properties-to-exynos4x12.d.patch
new file mode 100644 (file)
index 0000000..dd4b308
--- /dev/null
@@ -0,0 +1,62 @@
+From 27ade149b87f706672a3dfa50a5bc34bbd464708 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Sun, 24 Feb 2013 22:14:06 +0100
+Subject: [PATCH 0165/1302] ARM: dts: Add detailed FIMC properties to
+ exynos4x12.dtsi
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12.dtsi | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index 289062f..a3ed9ff 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -208,24 +208,42 @@
+                       compatible = "samsung,exynos4212-fimc";
+                       clocks = <&clock 256>, <&clock 128>, <&clock 384>, <&clock 17>;
+                       clock-names = "fimc", "sclk_fimc", "mux", "parent";
++                      samsung,pix-limits = <4224 8192 1920 4224>;
++                      samsung,mainscaler-ext;
++                      samsung,isp-wb;
++                      samsung,cam-if;
+               };
+               fimc_1: fimc@11810000 {
+                       compatible = "samsung,exynos4212-fimc";
+                       clocks = <&clock 257>, <&clock 129>, <&clock 385>, <&clock 17>;
+                       clock-names = "fimc", "sclk_fimc", "mux", "parent";
++                      samsung,pix-limits = <4224 8192 1920 4224>;
++                      samsung,mainscaler-ext;
++                      samsung,isp-wb;
++                      samsung,cam-if;
+               };
+               fimc_2: fimc@11820000 {
+                       compatible = "samsung,exynos4212-fimc";
+                       clocks = <&clock 258>, <&clock 130>, <&clock 386>, <&clock 17>;
+                       clock-names = "fimc", "sclk_fimc", "mux", "parent";
++                      samsung,pix-limits = <4224 8192 1920 4224>;
++                      samsung,mainscaler-ext;
++                      samsung,isp-wb;
++                      samsung,lcd-wb;
++                      samsung,cam-if;
+               };
+               fimc_3: fimc@11830000 {
+                       compatible = "samsung,exynos4212-fimc";
+                       clocks = <&clock 259>, <&clock 131>, <&clock 387>, <&clock 17>;
+                       clock-names = "fimc", "sclk_fimc", "mux", "parent";
++                      samsung,pix-limits = <1920 8192 1366 1920>;
++                      samsung,rotators = <0>;
++                      samsung,mainscaler-ext;
++                      samsung,isp-wb;
++                      samsung,lcd-wb;
+               };
+               csis_0: csis@11880000 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0166-ARM-dts-Add-detailed-FIMC-properties-to-exynos4210.d.patch b/patches.tizen/0166-ARM-dts-Add-detailed-FIMC-properties-to-exynos4210.d.patch
new file mode 100644 (file)
index 0000000..7ea1cfa
--- /dev/null
@@ -0,0 +1,54 @@
+From b1cc84d6d4cff839589c27089580a5a753add7d1 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 14 Mar 2013 19:28:27 +0100
+Subject: [PATCH 0166/1302] ARM: dts: Add detailed FIMC properties to
+ exynos4210.dtsi
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210.dtsi | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
+index fe5aa7a..0fa11d3 100644
+--- a/arch/arm/boot/dts/exynos4210.dtsi
++++ b/arch/arm/boot/dts/exynos4210.dtsi
+@@ -174,21 +174,34 @@
+               fimc_0: fimc@11800000 {
+                       clocks = <&clock 256>, <&clock 128>, <&clock 384>, <&clock 9>;
+                       clock-names = "fimc", "sclk_fimc", "mux", "parent";
++                      samsung,pix-limits = <4224 8192 1920 4224>;
++                      samsung,mainscaler-ext;
++                      samsung,cam-if;
+               };
+               fimc_1: fimc@11810000 {
+                       clocks = <&clock 257>, <&clock 129>, <&clock 385>, <&clock 9>;
+                       clock-names = "fimc", "sclk_fimc", "mux", "parent";
++                      samsung,pix-limits = <4224 8192 1920 4224>;
++                      samsung,mainscaler-ext;
++                      samsung,cam-if;
+               };
+               fimc_2: fimc@11820000 {
+                       clocks = <&clock 258>, <&clock 130>, <&clock 386>, <&clock 9>;
+                       clock-names = "fimc", "sclk_fimc", "mux", "parent";
++                      samsung,pix-limits = <4224 8192 1920 4224>;
++                      samsung,mainscaler-ext;
++                      samsung,lcd-wb;
+               };
+               fimc_3: fimc@11830000 {
+                       clocks = <&clock 259>, <&clock 131>, <&clock 387>, <&clock 9>;
+                       clock-names = "fimc", "sclk_fimc", "mux", "parent";
++                      samsung,pix-limits = <1920 8192 1366 1920>;
++                      samsung,rotators = <0>;
++                      samsung,mainscaler-ext;
++                      samsung,lcd-wb;
+               };
+               csis_0: csis@11880000 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0167-ARM-dts-PQ-mipi-csis-clock-frequency-correction.patch b/patches.tizen/0167-ARM-dts-PQ-mipi-csis-clock-frequency-correction.patch
new file mode 100644 (file)
index 0000000..942e108
--- /dev/null
@@ -0,0 +1,36 @@
+From ddcec36daf6294a3ca6c1f612e4e0df32fbd4d4a Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 7 Mar 2013 15:08:22 +0100
+Subject: [PATCH 0167/1302] ARM: dts: PQ mipi-csis clock frequency correction
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 214b35b..23bc1ac 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -698,7 +698,7 @@
+                       status = "okay";
+                       vddcore-supply = <&ldo8_reg>;
+                       vddio-supply = <&ldo10_reg>;
+-                      clock-frequency = <160000000>;
++                      clock-frequency = <176000000>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+@@ -717,7 +717,7 @@
+                       status = "okay";
+                       vddcore-supply = <&ldo8_reg>;
+                       vddio-supply = <&ldo10_reg>;
+-                      clock-frequency = <160000000>;
++                      clock-frequency = <176000000>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0168-ARM-dts-exynos4-Update-i2c-isp-node-in-exynos4412-sl.patch b/patches.tizen/0168-ARM-dts-exynos4-Update-i2c-isp-node-in-exynos4412-sl.patch
new file mode 100644 (file)
index 0000000..653aa3c
--- /dev/null
@@ -0,0 +1,99 @@
+From 8d05c13f1de2dd807ca6e35e2161c85e9506123d Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 6 Feb 2013 18:34:42 +0100
+Subject: [PATCH 0168/1302] ARM: dts: exynos4: Update i2c-isp node in
+ exynos4412-slp_pq.dts
+
+Update compatible property and add pinctrl properties for ISP I2C1
+device node.
+
+ARM: dts: Add camera device nodes for PQ board
+
+This patch adds all nodes for camera devices on an example Exynos4412 SoC
+based board. This is all what's required in the board dts file to enable
+rear facing camera (S5C73M3 sensor).
+
+The aliases node contains entries required for the camera processing
+data path entity drivers.
+
+The sensor nodes use standard port/remote-endpoint nodes convention.
+Internal SoC links between entities are not specified this way and
+are coded in the driver instead.
+
+The S5C73M3 sensor uses two control buses: I2C and SPI. There are
+two, i2c_0 and spi_1 bus controller child nodes assigned to it.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 39 ++++++++++++++++++---------------
+ 1 file changed, 21 insertions(+), 18 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 23bc1ac..a832bc2 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -651,23 +651,6 @@
+               };
+       };
+-      i2c0_isp: i2c-isp@12130000 {
+-              s5k6a3@10 {
+-                      compatible = "samsung,s5k6a3";
+-                      reg = <0x10>;
+-                      svdda-supply = <&cam_io_reg>;
+-                      svddio-supply = <&ldo19_reg>;
+-                      clock-frequency = <24000000>;
+-                      gpios = <&gpm1 6 0>;
+-                      port {
+-                              is_s5k6a3_ep: endpoint {
+-                                      remote-endpoint = <&csis1_ep>;
+-                                      data-lanes = <1>;
+-                              };
+-                      };
+-              };
+-      };
+-
+       camera {
+               status = "okay";
+@@ -735,7 +718,7 @@
+               fimc-is@12000000 {
+                       status = "okay";
+-                      pinctrl-0 = <&fimc_is_i2c0 &fimc_is_i2c1 &fimc_is_uart>;
++                      pinctrl-0 = <&fimc_is_uart>;
+                       pinctrl-names = "default";
+                       memory-region = <&fimc_mem>;
+@@ -746,6 +729,26 @@
+                       fimc_lite_1: fimc-lite@123A0000 {
+                               status = "okay";
+                       };
++
++                      i2c1_isp: i2c-isp@12140000 {
++                              pinctrl-0 = <&fimc_is_i2c1>;
++                              pinctrl-names = "default";
++
++                              s5k6a3@10 {
++                                      compatible = "samsung,s5k6a3";
++                                      reg = <0x10>;
++                                      svdda-supply = <&cam_io_reg>;
++                                      svddio-supply = <&ldo19_reg>;
++                                      clock-frequency = <24000000>;
++                                      gpios = <&gpm1 6 0>;
++                                      port {
++                                              is_s5k6a3_ep: endpoint {
++                                                      remote-endpoint = <&csis1_ep>;
++                                                      data-lanes = <1>;
++                                              };
++                                      };
++                              };
++                      };
+               };
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0169-ARM-dts-Add-SYSREG-block-node-for-Exynos4-SoC-series.patch b/patches.tizen/0169-ARM-dts-Add-SYSREG-block-node-for-Exynos4-SoC-series.patch
new file mode 100644 (file)
index 0000000..282b69b
--- /dev/null
@@ -0,0 +1,38 @@
+From 3340adf4cef9507029ed75c93d6e94499ef6ea53 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 13 Mar 2013 13:30:19 +0100
+Subject: [PATCH 0169/1302] ARM: dts: Add SYSREG block node for Exynos4 SoC
+ series
+
+The sysreg node corresponds to SYSREG block registers. It is used
+to instantiate the MFD syscon driver that exposes a regmap interface
+for SYSREG registers.
+
+Not the sysreg clock is not currently handled by the syscon driver
+in any way.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index 2d2df61..d1d7f1e 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -115,6 +115,11 @@
+               arm,tag-latency = <1 1 0>;
+       };
++      sys_reg: sysreg {
++              compatible = "exynos4-sysreg", "syscon";
++              reg = <0x10010000 0x400>;
++      };
++
+       dsi_0: dsi@11C80000 {
+               compatible = "samsung,exynos4210-mipi-dsi";
+               reg = <0x11C80000 0x10000>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0170-ARM-dts-exynos4-Add-sysreg-properties-to-fimc-nodes.patch b/patches.tizen/0170-ARM-dts-exynos4-Add-sysreg-properties-to-fimc-nodes.patch
new file mode 100644 (file)
index 0000000..4805aad
--- /dev/null
@@ -0,0 +1,54 @@
+From eddb469dea7e4b273fc2a509598419a9808252fb Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 13 Mar 2013 17:45:31 +0100
+Subject: [PATCH 0170/1302] ARM: dts: exynos4: Add sysreg properties to fimc
+ nodes
+
+Through the "samsung,sysreg" property the driver can get a handle
+to regmap instance exposing the SYSREG block registers.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index d1d7f1e..b3dee47 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -144,6 +144,7 @@
+                       reg = <0x11800000 0x1000>;
+                       interrupts = <0 84 0>;
+                       samsung,power-domain = <&pd_cam>;
++                      samsung,sysreg = <&sys_reg>;
+                       status = "disabled";
+               };
+@@ -152,6 +153,7 @@
+                       reg = <0x11810000 0x1000>;
+                       interrupts = <0 85 0>;
+                       samsung,power-domain = <&pd_cam>;
++                      samsung,sysreg = <&sys_reg>;
+                       status = "disabled";
+               };
+@@ -160,6 +162,7 @@
+                       reg = <0x11820000 0x1000>;
+                       interrupts = <0 86 0>;
+                       samsung,power-domain = <&pd_cam>;
++                      samsung,sysreg = <&sys_reg>;
+                       status = "disabled";
+               };
+@@ -168,6 +171,7 @@
+                       reg = <0x11830000 0x1000>;
+                       interrupts = <0 87 0>;
+                       samsung,power-domain = <&pd_cam>;
++                      samsung,sysreg = <&sys_reg>;
+                       status = "disabled";
+               };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0171-ARM-dts-exynos4-Move-fimc-lite-nodes-to-root-level.patch b/patches.tizen/0171-ARM-dts-exynos4-Move-fimc-lite-nodes-to-root-level.patch
new file mode 100644 (file)
index 0000000..b393f0d
--- /dev/null
@@ -0,0 +1,111 @@
+From 78e3c415e8e571060179b0c47be61f733e29903f Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Tue, 20 Aug 2013 13:39:37 +0200
+Subject: [PATCH 0171/1302] ARM: dts: exynos4: Move fimc-lite nodes to root
+ level
+
+There is no need for the fimc-lite nodes to be children of
+fimc-is node. FIMC-LITE can work independently of the FIMC-IS.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 16 ++++++-------
+ arch/arm/boot/dts/exynos4x12.dtsi       | 40 ++++++++++++++++-----------------
+ 2 files changed, 28 insertions(+), 28 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index a832bc2..9fb3fc4 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -716,20 +716,20 @@
+                       };
+               };
++              fimc_lite_0: fimc-lite@12390000 {
++                      status = "okay";
++              };
++
++              fimc_lite_1: fimc-lite@123A0000 {
++                      status = "okay";
++              };
++
+               fimc-is@12000000 {
+                       status = "okay";
+                       pinctrl-0 = <&fimc_is_uart>;
+                       pinctrl-names = "default";
+                       memory-region = <&fimc_mem>;
+-                      fimc_lite_0: fimc-lite@12390000 {
+-                              status = "okay";
+-                      };
+-
+-                      fimc_lite_1: fimc-lite@123A0000 {
+-                              status = "okay";
+-                      };
+-
+                       i2c1_isp: i2c-isp@12140000 {
+                               pinctrl-0 = <&fimc_is_i2c1>;
+                               pinctrl-names = "default";
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index a3ed9ff..5ec7245 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -256,6 +256,26 @@
+                       clock-names = "csis", "sclk_csis", "mux", "parent";
+               };
++              fimc_lite_0: fimc-lite@12390000 {
++                      compatible = "samsung,exynos4212-fimc-lite";
++                      reg = <0x12390000 0x1000>;
++                      interrupts = <0 105 0>;
++                      samsung,power-domain = <&pd_isp>;
++                      clocks = <&clock 353>;
++                      clock-names = "flite";
++                      status = "disabled";
++              };
++
++              fimc_lite_1: fimc-lite@123A0000 {
++                      compatible = "samsung,exynos4212-fimc-lite";
++                      reg = <0x123A0000 0x1000>;
++                      interrupts = <0 106 0>;
++                      samsung,power-domain = <&pd_isp>;
++                      clocks = <&clock 354>;
++                      clock-names = "flite";
++                      status = "disabled";
++              };
++
+               fimc_is: fimc-is@12000000 {
+                       compatible = "samsung,exynos4212-fimc-is", "simple-bus";
+                       reg = <0x12000000 0x260000>;
+@@ -273,26 +293,6 @@
+                       pmu {
+                               reg = <0x10020000 0x3000>;
+                       };
+-
+-                      fimc_lite_0: fimc-lite@12390000 {
+-                              compatible = "samsung,exynos4212-fimc-lite";
+-                              reg = <0x12390000 0x1000>;
+-                              interrupts = <0 105 0>;
+-                              samsung,power-domain = <&pd_isp>;
+-                              clocks = <&clock 353>;
+-                              clock-names = "flite";
+-                              status = "disabled";
+-                      };
+-
+-                      fimc_lite_1: fimc-lite@123A0000 {
+-                              compatible = "samsung,exynos4212-fimc-lite";
+-                              reg = <0x123A0000 0x1000>;
+-                              interrupts = <0 106 0>;
+-                              samsung,power-domain = <&pd_isp>;
+-                              clocks = <&clock 354>;
+-                              clock-names = "flite";
+-                              status = "disabled";
+-                      };
+               };
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0172-ARM-dts-exynos4-Make-ISP-I2C1-device-node-a-child-of.patch b/patches.tizen/0172-ARM-dts-exynos4-Make-ISP-I2C1-device-node-a-child-of.patch
new file mode 100644 (file)
index 0000000..8a4e168
--- /dev/null
@@ -0,0 +1,48 @@
+From f5103ad55a924effbc1d8df434fd89d007990eb2 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 13 Mar 2013 19:28:36 +0100
+Subject: [PATCH 0172/1302] ARM: dts: exynos4: Make ISP I2C1 device node a
+ child of fimc-is node
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12.dtsi | 15 +++++++--------
+ 1 file changed, 7 insertions(+), 8 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index 5ec7245..c2cdbffb 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -190,14 +190,6 @@
+               };
+       };
+-      i2c0_isp: i2c-isp@12130000 {
+-              compatible = "samsung,exynos4212-is-i2c",
+-                           "samsung,s3c2440-i2c";
+-              reg = <0x12130000 0x100>;
+-              #address-cells = <1>;
+-              #size-cells = <0>;
+-      };
+-
+       camera {
+               clocks = <&clock 132>, <&clock 133>, <&clock 351>, <&clock 352>,
+                        <&clock 388>, <&clock 389>, <&clock 17>;
+@@ -293,6 +285,13 @@
+                       pmu {
+                               reg = <0x10020000 0x3000>;
+                       };
++
++                      i2c1_isp: i2c-isp@12140000 {
++                              compatible = "samsung,exynos4212-i2c-isp";
++                              reg = <0x12130000 0x100>;
++                              #address-cells = <1>;
++                              #size-cells = <0>;
++                      };
+               };
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0173-ARM-configs-Add-tizen_defconfig.patch b/patches.tizen/0173-ARM-configs-Add-tizen_defconfig.patch
new file mode 100644 (file)
index 0000000..74c42de
--- /dev/null
@@ -0,0 +1,3120 @@
+From 1d9bdde1442d64a85695fdfa523984e6ac886d17 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 20 Feb 2013 19:41:00 +0100
+Subject: [PATCH 0173/1302] ARM: configs: Add tizen_defconfig
+
+This patch adds a config which is made to work on Trats, SLP PQ, M0 and
+Redwood targets with Tizen userspace.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_defconfig | 3096 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 3096 insertions(+)
+ create mode 100644 arch/arm/configs/tizen_defconfig
+
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+new file mode 100644
+index 0000000..ffc5b79
+--- /dev/null
++++ b/arch/arm/configs/tizen_defconfig
+@@ -0,0 +1,3096 @@
++#
++# Automatically generated file; DO NOT EDIT.
++# Linux/arm 3.8.0 Kernel Configuration
++#
++CONFIG_ARM=y
++CONFIG_ARM_HAS_SG_CHAIN=y
++CONFIG_NEED_SG_DMA_LENGTH=y
++CONFIG_ARM_DMA_USE_IOMMU=y
++CONFIG_ARM_DMA_IOMMU_ALIGNMENT=8
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++CONFIG_HAVE_PROC_CPU=y
++CONFIG_NO_IOPORT=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++CONFIG_ARCH_HAS_CPUFREQ=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_NEED_DMA_MAP_STATE=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_ARM_PATCH_PHYS_VIRT=y
++CONFIG_NEED_MACH_GPIO_H=y
++CONFIG_NEED_MACH_MEMORY_H=y
++CONFIG_GENERIC_BUG=y
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++CONFIG_HAVE_IRQ_WORK=y
++CONFIG_IRQ_WORK=y
++CONFIG_BUILDTIME_EXTABLE_SORT=y
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_CROSS_COMPILE=""
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_HAVE_KERNEL_GZIP=y
++CONFIG_HAVE_KERNEL_LZMA=y
++CONFIG_HAVE_KERNEL_XZ=y
++CONFIG_HAVE_KERNEL_LZO=y
++CONFIG_KERNEL_GZIP=y
++# CONFIG_KERNEL_LZMA is not set
++# CONFIG_KERNEL_XZ is not set
++# CONFIG_KERNEL_LZO is not set
++CONFIG_DEFAULT_HOSTNAME="(none)"
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_FHANDLE is not set
++CONFIG_AUDIT=y
++# CONFIG_AUDIT_LOGINUID_IMMUTABLE is not set
++CONFIG_HAVE_GENERIC_HARDIRQS=y
++
++#
++# IRQ subsystem
++#
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_GENERIC_IRQ_SHOW=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_CHIP=y
++CONFIG_IRQ_DOMAIN=y
++# CONFIG_IRQ_DOMAIN_DEBUG is not set
++CONFIG_KTIME_SCALAR=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
++
++#
++# Timers subsystem
++#
++CONFIG_TICK_ONESHOT=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
++
++#
++# CPU/Task time and stats accounting
++#
++CONFIG_TICK_CPU_ACCOUNTING=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++
++#
++# RCU Subsystem
++#
++CONFIG_TREE_PREEMPT_RCU=y
++CONFIG_PREEMPT_RCU=y
++CONFIG_RCU_FANOUT=32
++CONFIG_RCU_FANOUT_LEAF=16
++# CONFIG_RCU_FANOUT_EXACT is not set
++# CONFIG_RCU_FAST_NO_HZ is not set
++# CONFIG_TREE_RCU_TRACE is not set
++# CONFIG_RCU_BOOST is not set
++# CONFIG_RCU_NOCB_CPU is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=19
++CONFIG_CGROUPS=y
++CONFIG_CGROUP_DEBUG=y
++CONFIG_CGROUP_FREEZER=y
++# CONFIG_CGROUP_DEVICE is not set
++# CONFIG_CPUSETS is not set
++CONFIG_CGROUP_CPUACCT=y
++CONFIG_RESOURCE_COUNTERS=y
++CONFIG_MEMCG=y
++CONFIG_MEMCG_SWAP=y
++CONFIG_MEMCG_SWAP_ENABLED=y
++# CONFIG_MEMCG_KMEM is not set
++# CONFIG_CGROUP_PERF is not set
++CONFIG_CGROUP_SCHED=y
++CONFIG_FAIR_GROUP_SCHED=y
++# CONFIG_CFS_BANDWIDTH is not set
++CONFIG_RT_GROUP_SCHED=y
++# CONFIG_BLK_CGROUP is not set
++# CONFIG_CHECKPOINT_RESTORE is not set
++CONFIG_NAMESPACES=y
++CONFIG_UTS_NS=y
++CONFIG_IPC_NS=y
++CONFIG_USER_NS=y
++CONFIG_PID_NS=y
++CONFIG_NET_NS=y
++CONFIG_UIDGID_CONVERTED=y
++CONFIG_UIDGID_STRICT_TYPE_CHECKS=y
++# CONFIG_SCHED_AUTOGROUP is not set
++CONFIG_MM_OWNER=y
++# CONFIG_SYSFS_DEPRECATED is not set
++# CONFIG_RELAY is not set
++# CONFIG_BLK_DEV_INITRD is not set
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++CONFIG_EXPERT=y
++CONFIG_HAVE_UID16=y
++CONFIG_UID16=y
++# CONFIG_SYSCTL_SYSCALL is not set
++CONFIG_KALLSYMS=y
++CONFIG_KALLSYMS_ALL=y
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++CONFIG_EMBEDDED=y
++CONFIG_HAVE_PERF_EVENTS=y
++CONFIG_PERF_USE_VMALLOC=y
++
++#
++# Kernel Performance Events And Counters
++#
++CONFIG_PERF_EVENTS=y
++CONFIG_DEBUG_PERF_USE_VMALLOC=y
++CONFIG_VM_EVENT_COUNTERS=y
++# CONFIG_SLUB_DEBUG is not set
++CONFIG_COMPAT_BRK=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++CONFIG_PROFILING=y
++CONFIG_TRACEPOINTS=y
++CONFIG_OPROFILE=y
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_JUMP_LABEL=y
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_ARCH_TRACEHOOK=y
++CONFIG_HAVE_DMA_ATTRS=y
++CONFIG_HAVE_DMA_CONTIGUOUS=y
++CONFIG_USE_GENERIC_SMP_HELPERS=y
++CONFIG_GENERIC_SMP_IDLE_THREAD=y
++CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
++CONFIG_HAVE_CLK=y
++CONFIG_HAVE_DMA_API_DEBUG=y
++CONFIG_HAVE_HW_BREAKPOINT=y
++CONFIG_HAVE_ARCH_JUMP_LABEL=y
++CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
++CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
++CONFIG_MODULES_USE_ELF_REL=y
++CONFIG_CLONE_BACKWARDS=y
++
++#
++# GCOV-based kernel profiling
++#
++# CONFIG_GCOV_KERNEL is not set
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_RT_MUTEXES=y
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++CONFIG_MODULE_FORCE_LOAD=y
++CONFIG_MODULE_UNLOAD=y
++CONFIG_MODULE_FORCE_UNLOAD=y
++CONFIG_MODVERSIONS=y
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++# CONFIG_MODULE_SIG is not set
++CONFIG_STOP_MACHINE=y
++CONFIG_BLOCK=y
++CONFIG_LBDAF=y
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_BSGLIB is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++CONFIG_EFI_PARTITION=y
++# CONFIG_SYSV68_PARTITION is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_UNINLINE_SPIN_UNLOCK=y
++CONFIG_MUTEX_SPIN_ON_OWNER=y
++CONFIG_FREEZER=y
++
++#
++# System Type
++#
++CONFIG_MMU=y
++# CONFIG_ARCH_MULTIPLATFORM is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_BCM2835 is not set
++# CONFIG_ARCH_CNS3XXX is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_GEMINI is not set
++# CONFIG_ARCH_SIRF is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_MXS is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_DOVE is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_MMP is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_W90X900 is not set
++# CONFIG_ARCH_LPC32XX is not set
++# CONFIG_ARCH_TEGRA is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_MSM is not set
++# CONFIG_ARCH_SHMOBILE is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C24XX is not set
++# CONFIG_ARCH_S3C64XX is not set
++# CONFIG_ARCH_S5P64X0 is not set
++# CONFIG_ARCH_S5PC100 is not set
++# CONFIG_ARCH_S5PV210 is not set
++CONFIG_ARCH_EXYNOS=y
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_U300 is not set
++# CONFIG_ARCH_U8500 is not set
++# CONFIG_ARCH_NOMADIK is not set
++# CONFIG_PLAT_SPEAR is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_VT8500_SINGLE is not set
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_KEYBOARD_GPIO_POLLED is not set
++CONFIG_PLAT_SAMSUNG=y
++CONFIG_PLAT_S5P=y
++
++#
++# Boot options
++#
++# CONFIG_S3C_BOOT_WATCHDOG is not set
++# CONFIG_S3C_BOOT_ERROR_RESET is not set
++CONFIG_S3C_BOOT_UART_FORCE_FIFO=y
++CONFIG_S3C_LOWLEVEL_UART_PORT=2
++# CONFIG_S5P_CLOCK is not set
++CONFIG_SAMSUNG_IRQ_VIC_TIMER=y
++CONFIG_S5P_IRQ=y
++CONFIG_SAMSUNG_GPIOLIB_4BIT=y
++CONFIG_S5P_GPIO_DRVSTR=y
++CONFIG_SAMSUNG_GPIO_EXTRA=0
++CONFIG_S3C_GPIO_SPACE=0
++CONFIG_S3C_GPIO_TRACK=y
++CONFIG_S3C_ADC=y
++CONFIG_S3C24XX_PWM=y
++CONFIG_S5P_SETUP_MIPIPHY=y
++CONFIG_SAMSUNG_DMADEV=y
++
++#
++# Power management
++#
++# CONFIG_SAMSUNG_PM_DEBUG is not set
++# CONFIG_SAMSUNG_PM_CHECK is not set
++CONFIG_S5P_PM=y
++CONFIG_S5P_SLEEP=y
++CONFIG_DEBUG_S3C_UART=2
++
++#
++# SAMSUNG EXYNOS SoCs Support
++#
++CONFIG_ARCH_EXYNOS4=y
++# CONFIG_ARCH_EXYNOS5 is not set
++
++#
++# EXYNOS SoCs
++#
++CONFIG_CPU_EXYNOS4210=y
++CONFIG_SOC_EXYNOS4212=y
++CONFIG_SOC_EXYNOS4412=y
++CONFIG_EXYNOS4_MCT=y
++CONFIG_EXYNOS4_SETUP_USB_PHY=y
++CONFIG_SEC_DEBUG=y
++
++#
++# EXYNOS4210 Boards
++#
++# CONFIG_MACH_SMDKC210 is not set
++# CONFIG_MACH_SMDKV310 is not set
++# CONFIG_MACH_ARMLEX4210 is not set
++# CONFIG_MACH_UNIVERSAL_C210 is not set
++# CONFIG_MACH_NURI is not set
++# CONFIG_MACH_ORIGEN is not set
++
++#
++# EXYNOS4212 Boards
++#
++# CONFIG_MACH_SMDK4212 is not set
++
++#
++# EXYNOS4412 Boards
++#
++# CONFIG_MACH_SMDK4412 is not set
++
++#
++# Flattened Device Tree based board for EXYNOS SoCs
++#
++CONFIG_MACH_EXYNOS4_DT=y
++
++#
++# Configuration for HSMMC 8-bit bus width
++#
++# CONFIG_EXYNOS4_SDHCI_CH0_8BIT is not set
++# CONFIG_EXYNOS4_SDHCI_CH2_8BIT is not set
++# CONFIG_ARCH_VT8500 is not set
++
++#
++# Processor Type
++#
++CONFIG_CPU_V7=y
++CONFIG_CPU_32v6K=y
++CONFIG_CPU_32v7=y
++CONFIG_CPU_ABRT_EV7=y
++CONFIG_CPU_PABRT_V7=y
++CONFIG_CPU_CACHE_V7=y
++CONFIG_CPU_CACHE_VIPT=y
++CONFIG_CPU_COPY_V6=y
++CONFIG_CPU_TLB_V7=y
++CONFIG_CPU_HAS_ASID=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_LPAE is not set
++# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
++CONFIG_ARM_THUMB=y
++# CONFIG_ARM_THUMBEE is not set
++# CONFIG_ARM_VIRT_EXT is not set
++CONFIG_SWP_EMULATE=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_BPREDICT_DISABLE is not set
++CONFIG_OUTER_CACHE=y
++CONFIG_OUTER_CACHE_SYNC=y
++CONFIG_MIGHT_HAVE_CACHE_L2X0=y
++CONFIG_CACHE_L2X0=y
++CONFIG_CACHE_PL310=y
++CONFIG_ARM_L1_CACHE_SHIFT_6=y
++CONFIG_ARM_L1_CACHE_SHIFT=6
++CONFIG_ARM_DMA_MEM_BUFFERABLE=y
++CONFIG_ARM_NR_BANKS=8
++CONFIG_MULTI_IRQ_HANDLER=y
++# CONFIG_ARM_ERRATA_430973 is not set
++# CONFIG_ARM_ERRATA_458693 is not set
++# CONFIG_ARM_ERRATA_460075 is not set
++# CONFIG_ARM_ERRATA_742230 is not set
++# CONFIG_ARM_ERRATA_742231 is not set
++# CONFIG_PL310_ERRATA_588369 is not set
++# CONFIG_ARM_ERRATA_720789 is not set
++# CONFIG_PL310_ERRATA_727915 is not set
++CONFIG_ARM_ERRATA_743622=y
++CONFIG_ARM_ERRATA_751472=y
++# CONFIG_PL310_ERRATA_753970 is not set
++CONFIG_ARM_ERRATA_754322=y
++# CONFIG_ARM_ERRATA_754327 is not set
++CONFIG_ARM_ERRATA_764369=y
++# CONFIG_PL310_ERRATA_769419 is not set
++# CONFIG_ARM_ERRATA_775420 is not set
++CONFIG_ARM_GIC=y
++CONFIG_GIC_NON_BANKED=y
++
++#
++# Bus support
++#
++CONFIG_ARM_AMBA=y
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_HAVE_SMP=y
++CONFIG_SMP=y
++CONFIG_SMP_ON_UP=y
++CONFIG_ARM_CPU_TOPOLOGY=y
++CONFIG_SCHED_MC=y
++# CONFIG_SCHED_SMT is not set
++CONFIG_HAVE_ARM_SCU=y
++CONFIG_ARM_ARCH_TIMER=y
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
++CONFIG_NR_CPUS=4
++CONFIG_HOTPLUG_CPU=y
++CONFIG_LOCAL_TIMERS=y
++CONFIG_ARCH_NR_GPIO=0
++# CONFIG_PREEMPT_NONE is not set
++# CONFIG_PREEMPT_VOLUNTARY is not set
++CONFIG_PREEMPT=y
++CONFIG_PREEMPT_COUNT=y
++CONFIG_HZ=200
++# CONFIG_THUMB2_KERNEL is not set
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y
++CONFIG_ARCH_SPARSEMEM_ENABLE=y
++CONFIG_ARCH_SPARSEMEM_DEFAULT=y
++CONFIG_ARCH_SELECT_MEMORY_MODEL=y
++CONFIG_HAVE_ARCH_PFN_VALID=y
++CONFIG_HIGHMEM=y
++# CONFIG_HIGHPTE is not set
++CONFIG_HW_PERF_EVENTS=y
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_SPARSEMEM_MANUAL=y
++CONFIG_SPARSEMEM=y
++CONFIG_HAVE_MEMORY_PRESENT=y
++CONFIG_SPARSEMEM_EXTREME=y
++CONFIG_HAVE_MEMBLOCK=y
++CONFIG_MEMORY_ISOLATION=y
++CONFIG_SPLIT_PTLOCK_CPUS=4
++CONFIG_COMPACTION=y
++CONFIG_MIGRATION=y
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++# CONFIG_KSM is not set
++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
++CONFIG_CROSS_MEMORY_ATTACH=y
++# CONFIG_CLEANCACHE is not set
++# CONFIG_FRONTSWAP is not set
++CONFIG_FORCE_MAX_ZONEORDER=11
++CONFIG_ALIGNMENT_TRAP=y
++# CONFIG_UACCESS_WITH_MEMCPY is not set
++# CONFIG_SECCOMP is not set
++# CONFIG_CC_STACKPROTECTOR is not set
++# CONFIG_XEN is not set
++
++#
++# Boot options
++#
++CONFIG_USE_OF=y
++CONFIG_ATAGS=y
++# CONFIG_DEPRECATED_PARAM_STRUCT is not set
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++CONFIG_ARM_APPENDED_DTB=y
++CONFIG_ARM_ATAG_DTB_COMPAT=y
++CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y
++# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set
++CONFIG_CMDLINE=""
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++# CONFIG_CRASH_DUMP is not set
++# CONFIG_AUTO_ZRELADDR is not set
++
++#
++# CPU Power Management
++#
++
++#
++# CPU Frequency scaling
++#
++CONFIG_CPU_FREQ=y
++CONFIG_CPU_FREQ_TABLE=y
++CONFIG_CPU_FREQ_GOV_COMMON=y
++CONFIG_CPU_FREQ_STAT=y
++# CONFIG_CPU_FREQ_STAT_DETAILS is not set
++# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
++# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
++# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
++CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
++# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
++CONFIG_CPU_FREQ_GOV_POWERSAVE=y
++CONFIG_CPU_FREQ_GOV_USERSPACE=y
++CONFIG_CPU_FREQ_GOV_ONDEMAND=y
++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
++
++#
++# ARM CPU frequency scaling drivers
++#
++CONFIG_ARM_EXYNOS_CPUFREQ=y
++CONFIG_ARM_EXYNOS4210_CPUFREQ=y
++CONFIG_ARM_EXYNOS4X12_CPUFREQ=y
++# CONFIG_ARM_EXYNOS5250_CPUFREQ is not set
++CONFIG_CPU_IDLE=y
++# CONFIG_CPU_IDLE_MULTIPLE_DRIVERS is not set
++CONFIG_CPU_IDLE_GOV_LADDER=y
++CONFIG_CPU_IDLE_GOV_MENU=y
++# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++# CONFIG_FPE_NWFPE is not set
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_VFP=y
++CONFIG_VFPv3=y
++CONFIG_NEON=y
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
++CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
++CONFIG_HAVE_AOUT=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++CONFIG_COREDUMP=y
++
++#
++# Power management options
++#
++# CONFIG_SUSPEND is not set
++CONFIG_PM_RUNTIME=y
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++# CONFIG_APM_EMULATION is not set
++CONFIG_PM_CLK=y
++CONFIG_PM_GENERIC_DOMAINS=y
++CONFIG_PM_GENERIC_DOMAINS_RUNTIME=y
++CONFIG_CPU_PM=y
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_ARM_CPU_SUSPEND=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_DIAG is not set
++CONFIG_UNIX=y
++# CONFIG_UNIX_DIAG is not set
++CONFIG_XFRM=y
++CONFIG_XFRM_ALGO=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++CONFIG_XFRM_IPCOMP=y
++CONFIG_NET_KEY=y
++# CONFIG_NET_KEY_MIGRATE is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++CONFIG_IP_ADVANCED_ROUTER=y
++# CONFIG_IP_FIB_TRIE_STATS is not set
++CONFIG_IP_MULTIPLE_TABLES=y
++# CONFIG_IP_ROUTE_MULTIPATH is not set
++# CONFIG_IP_ROUTE_VERBOSE is not set
++# CONFIG_IP_PNP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE_DEMUX is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++CONFIG_INET_AH=y
++CONFIG_INET_ESP=y
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++CONFIG_INET_TUNNEL=y
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++CONFIG_INET_LRO=y
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_INET_UDP_DIAG is not set
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++CONFIG_IPV6=y
++CONFIG_IPV6_PRIVACY=y
++CONFIG_IPV6_ROUTER_PREF=y
++# CONFIG_IPV6_ROUTE_INFO is not set
++CONFIG_IPV6_OPTIMISTIC_DAD=y
++CONFIG_INET6_AH=y
++CONFIG_INET6_ESP=y
++CONFIG_INET6_IPCOMP=y
++CONFIG_IPV6_MIP6=y
++CONFIG_INET6_XFRM_TUNNEL=y
++CONFIG_INET6_TUNNEL=y
++CONFIG_INET6_XFRM_MODE_TRANSPORT=y
++CONFIG_INET6_XFRM_MODE_TUNNEL=y
++CONFIG_INET6_XFRM_MODE_BEET=y
++# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
++CONFIG_IPV6_SIT=y
++# CONFIG_IPV6_SIT_6RD is not set
++CONFIG_IPV6_NDISC_NODETYPE=y
++CONFIG_IPV6_TUNNEL=y
++# CONFIG_IPV6_GRE is not set
++CONFIG_IPV6_MULTIPLE_TABLES=y
++# CONFIG_IPV6_SUBTREES is not set
++# CONFIG_IPV6_MROUTE is not set
++CONFIG_NETLABEL=y
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++CONFIG_NETFILTER_ADVANCED=y
++
++#
++# Core Netfilter Configuration
++#
++CONFIG_NETFILTER_NETLINK=y
++# CONFIG_NETFILTER_NETLINK_ACCT is not set
++CONFIG_NETFILTER_NETLINK_QUEUE=y
++CONFIG_NETFILTER_NETLINK_LOG=y
++CONFIG_NF_CONNTRACK=y
++CONFIG_NF_CONNTRACK_MARK=y
++CONFIG_NF_CONNTRACK_PROCFS=y
++CONFIG_NF_CONNTRACK_EVENTS=y
++# CONFIG_NF_CONNTRACK_TIMEOUT is not set
++# CONFIG_NF_CONNTRACK_TIMESTAMP is not set
++CONFIG_NF_CT_PROTO_DCCP=y
++CONFIG_NF_CT_PROTO_GRE=y
++CONFIG_NF_CT_PROTO_SCTP=y
++CONFIG_NF_CT_PROTO_UDPLITE=y
++CONFIG_NF_CONNTRACK_AMANDA=y
++CONFIG_NF_CONNTRACK_FTP=y
++CONFIG_NF_CONNTRACK_H323=y
++CONFIG_NF_CONNTRACK_IRC=y
++CONFIG_NF_CONNTRACK_BROADCAST=y
++CONFIG_NF_CONNTRACK_NETBIOS_NS=y
++# CONFIG_NF_CONNTRACK_SNMP is not set
++CONFIG_NF_CONNTRACK_PPTP=y
++CONFIG_NF_CONNTRACK_SANE=y
++# CONFIG_NF_CONNTRACK_SIP is not set
++CONFIG_NF_CONNTRACK_TFTP=y
++CONFIG_NF_CT_NETLINK=y
++# CONFIG_NF_CT_NETLINK_TIMEOUT is not set
++# CONFIG_NETFILTER_NETLINK_QUEUE_CT is not set
++CONFIG_NF_NAT=y
++CONFIG_NF_NAT_NEEDED=y
++CONFIG_NF_NAT_PROTO_DCCP=y
++CONFIG_NF_NAT_PROTO_UDPLITE=y
++CONFIG_NF_NAT_PROTO_SCTP=y
++CONFIG_NF_NAT_AMANDA=y
++CONFIG_NF_NAT_FTP=y
++CONFIG_NF_NAT_IRC=y
++# CONFIG_NF_NAT_SIP is not set
++CONFIG_NF_NAT_TFTP=y
++CONFIG_NETFILTER_TPROXY=y
++CONFIG_NETFILTER_XTABLES=y
++
++#
++# Xtables combined modules
++#
++CONFIG_NETFILTER_XT_MARK=y
++CONFIG_NETFILTER_XT_CONNMARK=y
++
++#
++# Xtables targets
++#
++# CONFIG_NETFILTER_XT_TARGET_AUDIT is not set
++# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set
++CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
++CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
++# CONFIG_NETFILTER_XT_TARGET_CT is not set
++# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
++# CONFIG_NETFILTER_XT_TARGET_HL is not set
++# CONFIG_NETFILTER_XT_TARGET_HMARK is not set
++# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set
++# CONFIG_NETFILTER_XT_TARGET_LED is not set
++# CONFIG_NETFILTER_XT_TARGET_LOG is not set
++CONFIG_NETFILTER_XT_TARGET_MARK=y
++CONFIG_NETFILTER_XT_TARGET_NETMAP=y
++CONFIG_NETFILTER_XT_TARGET_NFLOG=y
++CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
++# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set
++# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
++CONFIG_NETFILTER_XT_TARGET_REDIRECT=y
++# CONFIG_NETFILTER_XT_TARGET_TEE is not set
++CONFIG_NETFILTER_XT_TARGET_TPROXY=y
++CONFIG_NETFILTER_XT_TARGET_TRACE=y
++# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
++# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
++
++#
++# Xtables matches
++#
++# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set
++# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
++CONFIG_NETFILTER_XT_MATCH_COMMENT=y
++CONFIG_NETFILTER_XT_MATCH_CONNBYTES=y
++CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
++CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
++# CONFIG_NETFILTER_XT_MATCH_CPU is not set
++# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
++# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set
++# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
++CONFIG_NETFILTER_XT_MATCH_ECN=y
++# CONFIG_NETFILTER_XT_MATCH_ESP is not set
++CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
++CONFIG_NETFILTER_XT_MATCH_HELPER=y
++CONFIG_NETFILTER_XT_MATCH_HL=y
++CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
++CONFIG_NETFILTER_XT_MATCH_LENGTH=y
++CONFIG_NETFILTER_XT_MATCH_LIMIT=y
++CONFIG_NETFILTER_XT_MATCH_MAC=y
++CONFIG_NETFILTER_XT_MATCH_MARK=y
++# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
++# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set
++# CONFIG_NETFILTER_XT_MATCH_OSF is not set
++# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
++CONFIG_NETFILTER_XT_MATCH_POLICY=y
++CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
++CONFIG_NETFILTER_XT_MATCH_QUOTA=y
++# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
++# CONFIG_NETFILTER_XT_MATCH_REALM is not set
++# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
++# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
++CONFIG_NETFILTER_XT_MATCH_SOCKET=y
++CONFIG_NETFILTER_XT_MATCH_STATE=y
++CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
++CONFIG_NETFILTER_XT_MATCH_STRING=y
++# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
++CONFIG_NETFILTER_XT_MATCH_TIME=y
++CONFIG_NETFILTER_XT_MATCH_U32=y
++# CONFIG_IP_SET is not set
++# CONFIG_IP_VS is not set
++
++#
++# IP: Netfilter Configuration
++#
++CONFIG_NF_DEFRAG_IPV4=y
++CONFIG_NF_CONNTRACK_IPV4=y
++CONFIG_NF_CONNTRACK_PROC_COMPAT=y
++# CONFIG_IP_NF_QUEUE is not set
++CONFIG_IP_NF_IPTABLES=y
++CONFIG_IP_NF_MATCH_AH=y
++CONFIG_IP_NF_MATCH_ECN=y
++# CONFIG_IP_NF_MATCH_RPFILTER is not set
++CONFIG_IP_NF_MATCH_TTL=y
++CONFIG_IP_NF_FILTER=y
++CONFIG_IP_NF_TARGET_REJECT=y
++# CONFIG_IP_NF_TARGET_ULOG is not set
++CONFIG_NF_NAT_IPV4=y
++CONFIG_IP_NF_TARGET_MASQUERADE=y
++CONFIG_IP_NF_TARGET_NETMAP=y
++CONFIG_IP_NF_TARGET_REDIRECT=y
++CONFIG_NF_NAT_PROTO_GRE=y
++CONFIG_NF_NAT_PPTP=y
++CONFIG_NF_NAT_H323=y
++CONFIG_IP_NF_MANGLE=y
++# CONFIG_IP_NF_TARGET_CLUSTERIP is not set
++# CONFIG_IP_NF_TARGET_ECN is not set
++# CONFIG_IP_NF_TARGET_TTL is not set
++CONFIG_IP_NF_RAW=y
++# CONFIG_IP_NF_SECURITY is not set
++CONFIG_IP_NF_ARPTABLES=y
++CONFIG_IP_NF_ARPFILTER=y
++CONFIG_IP_NF_ARP_MANGLE=y
++
++#
++# IPv6: Netfilter Configuration
++#
++CONFIG_NF_DEFRAG_IPV6=y
++CONFIG_NF_CONNTRACK_IPV6=y
++CONFIG_IP6_NF_IPTABLES=y
++# CONFIG_IP6_NF_MATCH_AH is not set
++# CONFIG_IP6_NF_MATCH_EUI64 is not set
++# CONFIG_IP6_NF_MATCH_FRAG is not set
++# CONFIG_IP6_NF_MATCH_OPTS is not set
++# CONFIG_IP6_NF_MATCH_HL is not set
++# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
++# CONFIG_IP6_NF_MATCH_MH is not set
++# CONFIG_IP6_NF_MATCH_RPFILTER is not set
++# CONFIG_IP6_NF_MATCH_RT is not set
++# CONFIG_IP6_NF_TARGET_HL is not set
++CONFIG_IP6_NF_FILTER=y
++CONFIG_IP6_NF_TARGET_REJECT=y
++CONFIG_IP6_NF_MANGLE=y
++CONFIG_IP6_NF_RAW=y
++# CONFIG_IP6_NF_SECURITY is not set
++CONFIG_NF_NAT_IPV6=y
++CONFIG_IP6_NF_TARGET_MASQUERADE=y
++CONFIG_IP6_NF_TARGET_NPT=y
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_RDS is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_L2TP is not set
++# CONFIG_BRIDGE is not set
++CONFIG_HAVE_NET_DSA=y
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_WAN_ROUTER is not set
++CONFIG_PHONET=y
++# CONFIG_IEEE802154 is not set
++CONFIG_NET_SCHED=y
++
++#
++# Queueing/Scheduling
++#
++# CONFIG_NET_SCH_CBQ is not set
++CONFIG_NET_SCH_HTB=y
++# CONFIG_NET_SCH_HFSC is not set
++# CONFIG_NET_SCH_PRIO is not set
++# CONFIG_NET_SCH_MULTIQ is not set
++# CONFIG_NET_SCH_RED is not set
++# CONFIG_NET_SCH_SFB is not set
++# CONFIG_NET_SCH_SFQ is not set
++# CONFIG_NET_SCH_TEQL is not set
++# CONFIG_NET_SCH_TBF is not set
++# CONFIG_NET_SCH_GRED is not set
++# CONFIG_NET_SCH_DSMARK is not set
++# CONFIG_NET_SCH_NETEM is not set
++# CONFIG_NET_SCH_DRR is not set
++# CONFIG_NET_SCH_MQPRIO is not set
++# CONFIG_NET_SCH_CHOKE is not set
++# CONFIG_NET_SCH_QFQ is not set
++# CONFIG_NET_SCH_CODEL is not set
++# CONFIG_NET_SCH_FQ_CODEL is not set
++CONFIG_NET_SCH_INGRESS=y
++# CONFIG_NET_SCH_PLUG is not set
++
++#
++# Classification
++#
++CONFIG_NET_CLS=y
++# CONFIG_NET_CLS_BASIC is not set
++# CONFIG_NET_CLS_TCINDEX is not set
++# CONFIG_NET_CLS_ROUTE4 is not set
++# CONFIG_NET_CLS_FW is not set
++CONFIG_NET_CLS_U32=y
++# CONFIG_CLS_U32_PERF is not set
++# CONFIG_CLS_U32_MARK is not set
++# CONFIG_NET_CLS_RSVP is not set
++# CONFIG_NET_CLS_RSVP6 is not set
++# CONFIG_NET_CLS_FLOW is not set
++# CONFIG_NET_CLS_CGROUP is not set
++CONFIG_NET_EMATCH=y
++CONFIG_NET_EMATCH_STACK=32
++# CONFIG_NET_EMATCH_CMP is not set
++# CONFIG_NET_EMATCH_NBYTE is not set
++CONFIG_NET_EMATCH_U32=y
++# CONFIG_NET_EMATCH_META is not set
++# CONFIG_NET_EMATCH_TEXT is not set
++CONFIG_NET_CLS_ACT=y
++CONFIG_NET_ACT_POLICE=y
++CONFIG_NET_ACT_GACT=y
++# CONFIG_GACT_PROB is not set
++CONFIG_NET_ACT_MIRRED=y
++# CONFIG_NET_ACT_IPT is not set
++# CONFIG_NET_ACT_NAT is not set
++# CONFIG_NET_ACT_PEDIT is not set
++# CONFIG_NET_ACT_SIMP is not set
++# CONFIG_NET_ACT_SKBEDIT is not set
++# CONFIG_NET_ACT_CSUM is not set
++# CONFIG_NET_CLS_IND is not set
++CONFIG_NET_SCH_FIFO=y
++# CONFIG_DCB is not set
++# CONFIG_BATMAN_ADV is not set
++# CONFIG_OPENVSWITCH is not set
++CONFIG_RPS=y
++CONFIG_RFS_ACCEL=y
++CONFIG_XPS=y
++# CONFIG_NETPRIO_CGROUP is not set
++CONFIG_BQL=y
++# CONFIG_BPF_JIT is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_NET_DROP_MONITOR is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++CONFIG_BT=y
++CONFIG_BT_RFCOMM=y
++CONFIG_BT_RFCOMM_TTY=y
++CONFIG_BT_BNEP=y
++# CONFIG_BT_BNEP_MC_FILTER is not set
++# CONFIG_BT_BNEP_PROTO_FILTER is not set
++CONFIG_BT_HIDP=y
++
++#
++# Bluetooth device drivers
++#
++# CONFIG_BT_HCIBTUSB is not set
++# CONFIG_BT_HCIBTSDIO is not set
++CONFIG_BT_HCIUART=y
++CONFIG_BT_HCIUART_H4=y
++# CONFIG_BT_HCIUART_BCSP is not set
++# CONFIG_BT_HCIUART_ATH3K is not set
++# CONFIG_BT_HCIUART_LL is not set
++# CONFIG_BT_HCIUART_3WIRE is not set
++# CONFIG_BT_HCIBCM203X is not set
++# CONFIG_BT_HCIBPA10X is not set
++# CONFIG_BT_HCIBFUSB is not set
++# CONFIG_BT_HCIVHCI is not set
++# CONFIG_BT_MRVL is not set
++# CONFIG_AF_RXRPC is not set
++CONFIG_FIB_RULES=y
++CONFIG_WIRELESS=y
++CONFIG_WEXT_CORE=y
++CONFIG_WEXT_PROC=y
++CONFIG_CFG80211=y
++# CONFIG_NL80211_TESTMODE is not set
++# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
++# CONFIG_CFG80211_REG_DEBUG is not set
++# CONFIG_CFG80211_CERTIFICATION_ONUS is not set
++CONFIG_CFG80211_DEFAULT_PS=y
++# CONFIG_CFG80211_DEBUGFS is not set
++# CONFIG_CFG80211_INTERNAL_REGDB is not set
++CONFIG_CFG80211_WEXT=y
++# CONFIG_LIB80211 is not set
++# CONFIG_MAC80211 is not set
++# CONFIG_WIMAX is not set
++CONFIG_RFKILL=y
++CONFIG_RFKILL_LEDS=y
++# CONFIG_RFKILL_INPUT is not set
++# CONFIG_RFKILL_REGULATOR is not set
++# CONFIG_RFKILL_GPIO is not set
++# CONFIG_NET_9P is not set
++# CONFIG_CAIF is not set
++# CONFIG_CEPH_LIB is not set
++# CONFIG_NFC is not set
++CONFIG_HAVE_BPF_JIT=y
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_DEVTMPFS=y
++CONFIG_DEVTMPFS_MOUNT=y
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_GENERIC_CPU_DEVICES is not set
++CONFIG_REGMAP=y
++CONFIG_REGMAP_I2C=y
++CONFIG_REGMAP_SPI=y
++CONFIG_REGMAP_MMIO=y
++CONFIG_REGMAP_IRQ=y
++CONFIG_DMA_SHARED_BUFFER=y
++CONFIG_CMA=y
++CONFIG_CMA_DEBUG=y
++
++#
++# Default contiguous memory area size:
++#
++CONFIG_CMA_SIZE_MBYTES=256
++CONFIG_CMA_SIZE_SEL_MBYTES=y
++# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
++# CONFIG_CMA_SIZE_SEL_MIN is not set
++# CONFIG_CMA_SIZE_SEL_MAX is not set
++CONFIG_CMA_ALIGNMENT=8
++CONFIG_CMA_AREAS=7
++
++#
++# Bus devices
++#
++# CONFIG_CONNECTOR is not set
++# CONFIG_MTD is not set
++CONFIG_DTC=y
++CONFIG_OF=y
++
++#
++# Device Tree and Open Firmware support
++#
++CONFIG_PROC_DEVICETREE=y
++# CONFIG_OF_SELFTEST is not set
++CONFIG_OF_FLATTREE=y
++CONFIG_OF_EARLY_FLATTREE=y
++CONFIG_OF_ADDRESS=y
++CONFIG_OF_IRQ=y
++CONFIG_OF_DEVICE=y
++CONFIG_OF_I2C=y
++CONFIG_OF_NET=y
++CONFIG_OF_MDIO=y
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
++CONFIG_BLK_DEV_CRYPTOLOOP=y
++# CONFIG_BLK_DEV_DRBD is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=16384
++# CONFIG_BLK_DEV_XIP is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_MG_DISK is not set
++# CONFIG_BLK_DEV_RBD is not set
++
++#
++# Misc devices
++#
++# CONFIG_SENSORS_LIS3LV02D is not set
++# CONFIG_AD525X_DPOT is not set
++# CONFIG_ATMEL_PWM is not set
++# CONFIG_ICS932S401 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_APDS9802ALS is not set
++# CONFIG_ISL29003 is not set
++# CONFIG_ISL29020 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_SENSORS_BH1780 is not set
++# CONFIG_SENSORS_BH1770 is not set
++# CONFIG_SENSORS_APDS990X is not set
++# CONFIG_HMC6352 is not set
++# CONFIG_DS1682 is not set
++# CONFIG_TI_DAC7512 is not set
++# CONFIG_BMP085_I2C is not set
++# CONFIG_BMP085_SPI is not set
++# CONFIG_USB_SWITCH_FSA9480 is not set
++CONFIG_SLP_GLOBAL_LOCK=y
++# CONFIG_C2PORT is not set
++
++#
++# EEPROM support
++#
++# CONFIG_EEPROM_AT24 is not set
++# CONFIG_EEPROM_AT25 is not set
++# CONFIG_EEPROM_LEGACY is not set
++# CONFIG_EEPROM_MAX6875 is not set
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_EEPROM_93XX46 is not set
++
++#
++# Texas Instruments shared transport line discipline
++#
++# CONFIG_TI_ST is not set
++# CONFIG_SENSORS_LIS3_SPI is not set
++# CONFIG_SENSORS_LIS3_I2C is not set
++
++#
++# Altera FPGA firmware download module
++#
++# CONFIG_ALTERA_STAPL is not set
++
++#
++# SCSI device support
++#
++CONFIG_SCSI_MOD=y
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_ISCSI_BOOT_SYSFS is not set
++# CONFIG_LIBFC is not set
++# CONFIG_LIBFCOE is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_SCSI_OSD_INITIATOR is not set
++# CONFIG_ATA is not set
++CONFIG_MD=y
++# CONFIG_BLK_DEV_MD is not set
++CONFIG_BLK_DEV_DM=y
++CONFIG_DM_DEBUG=y
++CONFIG_DM_CRYPT=y
++# CONFIG_DM_SNAPSHOT is not set
++# CONFIG_DM_THIN_PROVISIONING is not set
++# CONFIG_DM_MIRROR is not set
++# CONFIG_DM_RAID is not set
++# CONFIG_DM_ZERO is not set
++# CONFIG_DM_MULTIPATH is not set
++# CONFIG_DM_DELAY is not set
++CONFIG_DM_UEVENT=y
++# CONFIG_DM_FLAKEY is not set
++# CONFIG_DM_VERITY is not set
++# CONFIG_TARGET_CORE is not set
++CONFIG_NETDEVICES=y
++CONFIG_NET_CORE=y
++# CONFIG_BONDING is not set
++# CONFIG_DUMMY is not set
++# CONFIG_EQUALIZER is not set
++CONFIG_MII=y
++# CONFIG_IFB is not set
++# CONFIG_NET_TEAM is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_VXLAN is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++
++#
++# CAIF transport drivers
++#
++
++#
++# Distributed Switch Architecture drivers
++#
++# CONFIG_NET_DSA_MV88E6XXX is not set
++# CONFIG_NET_DSA_MV88E6060 is not set
++# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
++# CONFIG_NET_DSA_MV88E6131 is not set
++# CONFIG_NET_DSA_MV88E6123_61_65 is not set
++CONFIG_ETHERNET=y
++CONFIG_NET_CADENCE=y
++# CONFIG_ARM_AT91_ETHER is not set
++# CONFIG_MACB is not set
++CONFIG_NET_VENDOR_BROADCOM=y
++# CONFIG_B44 is not set
++# CONFIG_NET_CALXEDA_XGMAC is not set
++CONFIG_NET_VENDOR_CIRRUS=y
++# CONFIG_CS89x0 is not set
++# CONFIG_DM9000 is not set
++# CONFIG_DNET is not set
++CONFIG_NET_VENDOR_FARADAY=y
++# CONFIG_FTMAC100 is not set
++# CONFIG_FTGMAC100 is not set
++CONFIG_NET_VENDOR_INTEL=y
++CONFIG_NET_VENDOR_I825XX=y
++CONFIG_NET_VENDOR_MARVELL=y
++# CONFIG_MVMDIO is not set
++CONFIG_NET_VENDOR_MICREL=y
++# CONFIG_KS8842 is not set
++# CONFIG_KS8851 is not set
++# CONFIG_KS8851_MLL is not set
++CONFIG_NET_VENDOR_MICROCHIP=y
++# CONFIG_ENC28J60 is not set
++CONFIG_NET_VENDOR_NATSEMI=y
++CONFIG_NET_VENDOR_8390=y
++# CONFIG_AX88796 is not set
++# CONFIG_ETHOC is not set
++CONFIG_NET_VENDOR_SEEQ=y
++# CONFIG_SEEQ8005 is not set
++CONFIG_NET_VENDOR_SMSC=y
++# CONFIG_SMC91X is not set
++# CONFIG_SMC911X is not set
++CONFIG_SMSC911X=y
++# CONFIG_SMSC911X_ARCH_HOOKS is not set
++CONFIG_NET_VENDOR_STMICRO=y
++# CONFIG_STMMAC_ETH is not set
++CONFIG_NET_VENDOR_WIZNET=y
++# CONFIG_WIZNET_W5100 is not set
++# CONFIG_WIZNET_W5300 is not set
++CONFIG_PHYLIB=y
++
++#
++# MII PHY device drivers
++#
++# CONFIG_AT803X_PHY is not set
++# CONFIG_AMD_PHY is not set
++# CONFIG_MARVELL_PHY is not set
++# CONFIG_DAVICOM_PHY is not set
++# CONFIG_QSEMI_PHY is not set
++# CONFIG_LXT_PHY is not set
++# CONFIG_CICADA_PHY is not set
++# CONFIG_VITESSE_PHY is not set
++# CONFIG_SMSC_PHY is not set
++# CONFIG_BROADCOM_PHY is not set
++# CONFIG_BCM87XX_PHY is not set
++# CONFIG_ICPLUS_PHY is not set
++# CONFIG_REALTEK_PHY is not set
++# CONFIG_NATIONAL_PHY is not set
++# CONFIG_STE10XP is not set
++# CONFIG_LSI_ET1011C_PHY is not set
++# CONFIG_MICREL_PHY is not set
++# CONFIG_FIXED_PHY is not set
++# CONFIG_MDIO_BITBANG is not set
++# CONFIG_MDIO_BUS_MUX_GPIO is not set
++# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
++# CONFIG_MICREL_KS8995MA is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++CONFIG_USB_USBNET=y
++CONFIG_USB_NET_AX8817X=y
++CONFIG_USB_NET_CDCETHER=y
++# CONFIG_USB_NET_CDC_EEM is not set
++CONFIG_USB_NET_CDC_NCM=y
++# CONFIG_USB_NET_CDC_MBIM is not set
++# CONFIG_USB_NET_DM9601 is not set
++CONFIG_USB_NET_SMSC75XX=y
++CONFIG_USB_NET_SMSC95XX=y
++# CONFIG_USB_NET_GL620A is not set
++CONFIG_USB_NET_NET1080=y
++# CONFIG_USB_NET_PLUSB is not set
++# CONFIG_USB_NET_MCS7830 is not set
++# CONFIG_USB_NET_RNDIS_HOST is not set
++CONFIG_USB_NET_CDC_SUBSET=y
++# CONFIG_USB_ALI_M5632 is not set
++# CONFIG_USB_AN2720 is not set
++CONFIG_USB_BELKIN=y
++CONFIG_USB_ARMLINUX=y
++# CONFIG_USB_EPSON2888 is not set
++# CONFIG_USB_KC2190 is not set
++CONFIG_USB_NET_ZAURUS=y
++# CONFIG_USB_NET_CX82310_ETH is not set
++# CONFIG_USB_NET_KALMIA is not set
++# CONFIG_USB_NET_QMI_WWAN is not set
++# CONFIG_USB_HSO is not set
++# CONFIG_USB_NET_INT51X1 is not set
++# CONFIG_USB_CDC_PHONET is not set
++# CONFIG_USB_IPHETH is not set
++# CONFIG_USB_SIERRA_NET is not set
++# CONFIG_USB_VL600 is not set
++CONFIG_WLAN=y
++# CONFIG_USB_ZD1201 is not set
++# CONFIG_USB_NET_RNDIS_WLAN is not set
++# CONFIG_ATH_CARDS is not set
++# CONFIG_BRCMFMAC is not set
++# CONFIG_HOSTAP is not set
++# CONFIG_LIBERTAS is not set
++# CONFIG_WL_TI is not set
++# CONFIG_MWIFIEX is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
++# CONFIG_WAN is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++# CONFIG_INPUT_SPARSEKMAP is not set
++# CONFIG_INPUT_MATRIXKMAP is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++# CONFIG_KEYBOARD_ADP5588 is not set
++# CONFIG_KEYBOARD_ADP5589 is not set
++# CONFIG_KEYBOARD_ATKBD is not set
++# CONFIG_KEYBOARD_QT1070 is not set
++# CONFIG_KEYBOARD_QT2160 is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++CONFIG_KEYBOARD_GPIO=y
++# CONFIG_KEYBOARD_TCA6416 is not set
++# CONFIG_KEYBOARD_TCA8418 is not set
++# CONFIG_KEYBOARD_MATRIX is not set
++# CONFIG_KEYBOARD_LM8323 is not set
++# CONFIG_KEYBOARD_LM8333 is not set
++# CONFIG_KEYBOARD_MAX7359 is not set
++# CONFIG_KEYBOARD_MCS is not set
++# CONFIG_KEYBOARD_MPR121 is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_OPENCORES is not set
++# CONFIG_KEYBOARD_SAMSUNG is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++# CONFIG_TOUCHSCREEN_ADS7846 is not set
++# CONFIG_TOUCHSCREEN_AD7877 is not set
++# CONFIG_TOUCHSCREEN_AD7879 is not set
++CONFIG_TOUCHSCREEN_ATMEL_MXT=y
++# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set
++# CONFIG_TOUCHSCREEN_BU21013 is not set
++# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set
++# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set
++# CONFIG_TOUCHSCREEN_DYNAPRO is not set
++# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
++# CONFIG_TOUCHSCREEN_EETI is not set
++# CONFIG_TOUCHSCREEN_EGALAX is not set
++# CONFIG_TOUCHSCREEN_FUJITSU is not set
++# CONFIG_TOUCHSCREEN_ILI210X is not set
++# CONFIG_TOUCHSCREEN_GUNZE is not set
++# CONFIG_TOUCHSCREEN_ELO is not set
++# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
++# CONFIG_TOUCHSCREEN_WACOM_I2C is not set
++# CONFIG_TOUCHSCREEN_MAX11801 is not set
++# CONFIG_TOUCHSCREEN_MCS5000 is not set
++CONFIG_TOUCHSCREEN_MMS114=y
++# CONFIG_TOUCHSCREEN_MTOUCH is not set
++# CONFIG_TOUCHSCREEN_INEXIO is not set
++# CONFIG_TOUCHSCREEN_MK712 is not set
++# CONFIG_TOUCHSCREEN_PENMOUNT is not set
++# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set
++# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
++# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
++# CONFIG_TOUCHSCREEN_PIXCIR is not set
++# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
++# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
++# CONFIG_TOUCHSCREEN_TSC_SERIO is not set
++# CONFIG_TOUCHSCREEN_TSC2005 is not set
++# CONFIG_TOUCHSCREEN_TSC2007 is not set
++# CONFIG_TOUCHSCREEN_W90X900 is not set
++# CONFIG_TOUCHSCREEN_ST1232 is not set
++# CONFIG_TOUCHSCREEN_TPS6507X is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_AMBAKMI is not set
++# CONFIG_SERIO_LIBPS2 is not set
++# CONFIG_SERIO_RAW is not set
++# CONFIG_SERIO_ALTERA_PS2 is not set
++# CONFIG_SERIO_PS2MULT is not set
++# CONFIG_SERIO_ARC_PS2 is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++CONFIG_VT_HW_CONSOLE_BINDING=y
++CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_N_GSM is not set
++# CONFIG_TRACE_SINK is not set
++CONFIG_DEVKMEM=y
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++# CONFIG_SERIAL_8250_CONSOLE is not set
++CONFIG_SERIAL_8250_NR_UARTS=4
++CONFIG_SERIAL_8250_RUNTIME_UARTS=4
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_DW is not set
++# CONFIG_SERIAL_8250_EM is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_AMBA_PL010 is not set
++# CONFIG_SERIAL_AMBA_PL011 is not set
++CONFIG_SERIAL_SAMSUNG=y
++CONFIG_SERIAL_SAMSUNG_UARTS_4=y
++CONFIG_SERIAL_SAMSUNG_UARTS=4
++# CONFIG_SERIAL_SAMSUNG_DEBUG is not set
++CONFIG_SERIAL_SAMSUNG_CONSOLE=y
++# CONFIG_SERIAL_MAX3100 is not set
++# CONFIG_SERIAL_MAX310X is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_SERIAL_OF_PLATFORM=y
++# CONFIG_SERIAL_SCCNXP is not set
++# CONFIG_SERIAL_TIMBERDALE is not set
++# CONFIG_SERIAL_ALTERA_JTAGUART is not set
++# CONFIG_SERIAL_ALTERA_UART is not set
++# CONFIG_SERIAL_IFX6X60 is not set
++# CONFIG_SERIAL_XILINX_PS_UART is not set
++# CONFIG_SERIAL_ARC is not set
++# CONFIG_TTY_PRINTK is not set
++# CONFIG_HVC_DCC is not set
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=y
++# CONFIG_HW_RANDOM_TIMERIOMEM is not set
++# CONFIG_HW_RANDOM_ATMEL is not set
++# CONFIG_HW_RANDOM_EXYNOS is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_COMPAT=y
++# CONFIG_I2C_CHARDEV is not set
++# CONFIG_I2C_MUX is not set
++CONFIG_I2C_HELPER_AUTO=y
++CONFIG_I2C_ALGOBIT=y
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++# CONFIG_I2C_CBUS_GPIO is not set
++# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
++CONFIG_I2C_GPIO=y
++# CONFIG_I2C_NOMADIK is not set
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_PXA_PCI is not set
++CONFIG_HAVE_S3C2410_I2C=y
++CONFIG_I2C_S3C2410=y
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_XILINX is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_DIOLAN_U2C is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++CONFIG_SPI=y
++# CONFIG_SPI_DEBUG is not set
++CONFIG_SPI_MASTER=y
++
++#
++# SPI Master Controller Drivers
++#
++# CONFIG_SPI_ALTERA is not set
++CONFIG_SPI_BITBANG=y
++CONFIG_SPI_GPIO=y
++# CONFIG_SPI_OC_TINY is not set
++# CONFIG_SPI_PL022 is not set
++# CONFIG_SPI_PXA2XX_PCI is not set
++CONFIG_SPI_S3C64XX=y
++# CONFIG_SPI_SC18IS602 is not set
++# CONFIG_SPI_XCOMM is not set
++# CONFIG_SPI_XILINX is not set
++# CONFIG_SPI_DESIGNWARE is not set
++
++#
++# SPI Protocol Masters
++#
++# CONFIG_SPI_SPIDEV is not set
++# CONFIG_SPI_TLE62X0 is not set
++# CONFIG_HSI is not set
++
++#
++# PPS support
++#
++# CONFIG_PPS is not set
++
++#
++# PPS generators support
++#
++
++#
++# PTP clock support
++#
++# CONFIG_PTP_1588_CLOCK is not set
++
++#
++# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
++#
++# CONFIG_PTP_1588_CLOCK_PCH is not set
++CONFIG_PINCTRL=y
++
++#
++# Pin controllers
++#
++CONFIG_PINMUX=y
++CONFIG_PINCONF=y
++# CONFIG_DEBUG_PINCTRL is not set
++# CONFIG_PINCTRL_SINGLE is not set
++CONFIG_PINCTRL_SAMSUNG=y
++CONFIG_PINCTRL_EXYNOS=y
++# CONFIG_PINCTRL_EXYNOS5440 is not set
++CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIOLIB=y
++CONFIG_OF_GPIO=y
++# CONFIG_DEBUG_GPIO is not set
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO drivers:
++#
++# CONFIG_GPIO_GENERIC_PLATFORM is not set
++# CONFIG_GPIO_EM is not set
++# CONFIG_GPIO_PL061 is not set
++# CONFIG_GPIO_TS5500 is not set
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX7300 is not set
++# CONFIG_GPIO_MAX732X is not set
++# CONFIG_GPIO_PCF857X is not set
++# CONFIG_GPIO_SX150X is not set
++CONFIG_GPIO_WM8994=y
++# CONFIG_GPIO_ADP5588 is not set
++# CONFIG_GPIO_ADNP is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_GPIO_MC33880 is not set
++# CONFIG_GPIO_74X164 is not set
++
++#
++# AC97 GPIO expanders:
++#
++
++#
++# MODULbus GPIO expanders:
++#
++
++#
++# USB GPIO expanders:
++#
++# CONFIG_W1 is not set
++CONFIG_POWER_SUPPLY=y
++# CONFIG_POWER_SUPPLY_DEBUG is not set
++# CONFIG_PDA_POWER is not set
++# CONFIG_TEST_POWER is not set
++# CONFIG_BATTERY_DS2780 is not set
++# CONFIG_BATTERY_DS2781 is not set
++# CONFIG_BATTERY_DS2782 is not set
++# CONFIG_BATTERY_SBS is not set
++# CONFIG_BATTERY_BQ27x00 is not set
++CONFIG_BATTERY_MAX17040=y
++CONFIG_BATTERY_MAX17042=y
++# CONFIG_BATTERY_S3C_ADC is not set
++# CONFIG_CHARGER_ISP1704 is not set
++# CONFIG_CHARGER_MAX8903 is not set
++# CONFIG_CHARGER_LP8727 is not set
++# CONFIG_CHARGER_GPIO is not set
++# CONFIG_CHARGER_MANAGER is not set
++CONFIG_CHARGER_MAX8997=y
++# CONFIG_CHARGER_BQ2415X is not set
++# CONFIG_CHARGER_SMB347 is not set
++# CONFIG_POWER_RESET is not set
++# CONFIG_POWER_AVS is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++CONFIG_WATCHDOG=y
++CONFIG_WATCHDOG_CORE=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++
++#
++# Watchdog Device Drivers
++#
++# CONFIG_SOFT_WATCHDOG is not set
++# CONFIG_ARM_SP805_WATCHDOG is not set
++CONFIG_HAVE_S3C2410_WATCHDOG=y
++CONFIG_S3C2410_WATCHDOG=y
++# CONFIG_DW_WATCHDOG is not set
++# CONFIG_MAX63XX_WATCHDOG is not set
++
++#
++# USB-based Watchdog Cards
++#
++# CONFIG_USBPCWATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++CONFIG_BCMA_POSSIBLE=y
++
++#
++# Broadcom specific AMBA
++#
++# CONFIG_BCMA is not set
++
++#
++# Multifunction device drivers
++#
++CONFIG_MFD_CORE=y
++# CONFIG_MFD_88PM860X is not set
++# CONFIG_MFD_88PM800 is not set
++# CONFIG_MFD_88PM805 is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_MFD_TI_AM335X_TSCADC is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_HTC_I2CPLD is not set
++# CONFIG_MFD_LM3533 is not set
++# CONFIG_TPS6105X is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_TPS6507X is not set
++# CONFIG_MFD_TPS65217 is not set
++# CONFIG_MFD_TPS6586X is not set
++# CONFIG_MFD_TPS65910 is not set
++# CONFIG_MFD_TPS65912_I2C is not set
++# CONFIG_MFD_TPS65912_SPI is not set
++# CONFIG_MFD_TPS80031 is not set
++# CONFIG_TWL4030_CORE is not set
++# CONFIG_TWL6040_CORE is not set
++# CONFIG_MFD_STMPE is not set
++# CONFIG_MFD_TC3589X is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_T7L66XB is not set
++# CONFIG_MFD_SMSC is not set
++# CONFIG_MFD_TC6387XB is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_DA9052_SPI is not set
++# CONFIG_MFD_DA9052_I2C is not set
++# CONFIG_MFD_DA9055 is not set
++# CONFIG_PMIC_ADP5520 is not set
++# CONFIG_MFD_LP8788 is not set
++CONFIG_MFD_MAX77686=y
++CONFIG_MFD_MAX77693=y
++# CONFIG_MFD_MAX8907 is not set
++# CONFIG_MFD_MAX8925 is not set
++CONFIG_MFD_MAX8997=y
++# CONFIG_MFD_MAX8998 is not set
++CONFIG_MFD_SEC_CORE=y
++# CONFIG_MFD_ARIZONA_I2C is not set
++# CONFIG_MFD_ARIZONA_SPI is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM831X_I2C is not set
++# CONFIG_MFD_WM831X_SPI is not set
++# CONFIG_MFD_WM8350_I2C is not set
++CONFIG_MFD_WM8994=y
++# CONFIG_MFD_PCF50633 is not set
++# CONFIG_MFD_MC13XXX_SPI is not set
++# CONFIG_MFD_MC13XXX_I2C is not set
++# CONFIG_ABX500_CORE is not set
++# CONFIG_EZX_PCAP is not set
++# CONFIG_MFD_WL1273_CORE is not set
++CONFIG_MFD_TPS65090=y
++# CONFIG_MFD_AAT2870_CORE is not set
++# CONFIG_MFD_RC5T583 is not set
++CONFIG_MFD_SYSCON=y
++# CONFIG_MFD_PALMAS is not set
++# CONFIG_MFD_VIPERBOARD is not set
++# CONFIG_MFD_RETU is not set
++# CONFIG_MFD_AS3711 is not set
++CONFIG_REGULATOR=y
++# CONFIG_REGULATOR_DEBUG is not set
++# CONFIG_REGULATOR_DUMMY is not set
++CONFIG_REGULATOR_FIXED_VOLTAGE=y
++# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
++# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
++# CONFIG_REGULATOR_GPIO is not set
++# CONFIG_REGULATOR_AD5398 is not set
++# CONFIG_REGULATOR_FAN53555 is not set
++# CONFIG_REGULATOR_ANATOP is not set
++# CONFIG_REGULATOR_ISL6271A is not set
++# CONFIG_REGULATOR_MAX1586 is not set
++# CONFIG_REGULATOR_MAX8649 is not set
++# CONFIG_REGULATOR_MAX8660 is not set
++# CONFIG_REGULATOR_MAX8952 is not set
++# CONFIG_REGULATOR_MAX8973 is not set
++CONFIG_REGULATOR_MAX8997=y
++CONFIG_REGULATOR_MAX77686=y
++CONFIG_REGULATOR_MAX77693=y
++# CONFIG_REGULATOR_LP3971 is not set
++# CONFIG_REGULATOR_LP3972 is not set
++# CONFIG_REGULATOR_LP872X is not set
++# CONFIG_REGULATOR_S2MPS11 is not set
++# CONFIG_REGULATOR_S5M8767 is not set
++# CONFIG_REGULATOR_TPS51632 is not set
++# CONFIG_REGULATOR_TPS62360 is not set
++# CONFIG_REGULATOR_TPS65023 is not set
++# CONFIG_REGULATOR_TPS6507X is not set
++# CONFIG_REGULATOR_TPS65090 is not set
++# CONFIG_REGULATOR_TPS6524X is not set
++CONFIG_REGULATOR_WM8994=y
++CONFIG_MEDIA_SUPPORT=y
++
++#
++# Multimedia core support
++#
++CONFIG_MEDIA_CAMERA_SUPPORT=y
++# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set
++# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set
++# CONFIG_MEDIA_RADIO_SUPPORT is not set
++# CONFIG_MEDIA_RC_SUPPORT is not set
++CONFIG_MEDIA_CONTROLLER=y
++CONFIG_VIDEO_DEV=y
++CONFIG_VIDEO_V4L2_SUBDEV_API=y
++CONFIG_VIDEO_V4L2=y
++# CONFIG_VIDEO_ADV_DEBUG is not set
++# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
++CONFIG_V4L2_MEM2MEM_DEV=y
++CONFIG_VIDEOBUF2_CORE=y
++CONFIG_VIDEOBUF2_MEMOPS=y
++CONFIG_VIDEOBUF2_DMA_CONTIG=y
++
++#
++# Media drivers
++#
++# CONFIG_MEDIA_USB_SUPPORT is not set
++CONFIG_V4L_PLATFORM_DRIVERS=y
++# CONFIG_VIDEO_TIMBERDALE is not set
++# CONFIG_SOC_CAMERA is not set
++CONFIG_VIDEO_SAMSUNG_S5P_FIMC=y
++CONFIG_VIDEO_S5P_FIMC=y
++CONFIG_VIDEO_S5P_MIPI_CSIS=y
++CONFIG_VIDEO_EXYNOS_FIMC_LITE=y
++CONFIG_VIDEO_EXYNOS4_FIMC_IS=y
++# CONFIG_VIDEO_SAMSUNG_S5P_TV is not set
++CONFIG_V4L_MEM2MEM_DRIVERS=y
++# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set
++# CONFIG_VIDEO_SAMSUNG_S5P_G2D is not set
++# CONFIG_VIDEO_SAMSUNG_S5P_JPEG is not set
++CONFIG_VIDEO_SAMSUNG_S5P_MFC=y
++# CONFIG_V4L_TEST_DRIVERS is not set
++
++#
++# Supported MMC/SDIO adapters
++#
++# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
++
++#
++# Media ancillary drivers (tuners, sensors, i2c, frontends)
++#
++
++#
++# Encoders, decoders, sensors and other helper chips
++#
++
++#
++# Audio decoders, processors and mixers
++#
++# CONFIG_VIDEO_TVAUDIO is not set
++# CONFIG_VIDEO_TDA7432 is not set
++# CONFIG_VIDEO_TDA9840 is not set
++# CONFIG_VIDEO_TEA6415C is not set
++# CONFIG_VIDEO_TEA6420 is not set
++# CONFIG_VIDEO_MSP3400 is not set
++# CONFIG_VIDEO_CS5345 is not set
++# CONFIG_VIDEO_CS53L32A is not set
++# CONFIG_VIDEO_TLV320AIC23B is not set
++# CONFIG_VIDEO_WM8775 is not set
++# CONFIG_VIDEO_WM8739 is not set
++# CONFIG_VIDEO_VP27SMPX is not set
++
++#
++# RDS decoders
++#
++# CONFIG_VIDEO_SAA6588 is not set
++
++#
++# Video decoders
++#
++# CONFIG_VIDEO_ADV7180 is not set
++# CONFIG_VIDEO_ADV7183 is not set
++# CONFIG_VIDEO_ADV7604 is not set
++# CONFIG_VIDEO_BT819 is not set
++# CONFIG_VIDEO_BT856 is not set
++# CONFIG_VIDEO_BT866 is not set
++# CONFIG_VIDEO_KS0127 is not set
++# CONFIG_VIDEO_SAA7110 is not set
++# CONFIG_VIDEO_SAA711X is not set
++# CONFIG_VIDEO_SAA7191 is not set
++# CONFIG_VIDEO_TVP514X is not set
++# CONFIG_VIDEO_TVP5150 is not set
++# CONFIG_VIDEO_TVP7002 is not set
++# CONFIG_VIDEO_VPX3220 is not set
++
++#
++# Video and audio decoders
++#
++# CONFIG_VIDEO_SAA717X is not set
++# CONFIG_VIDEO_CX25840 is not set
++
++#
++# MPEG video encoders
++#
++# CONFIG_VIDEO_CX2341X is not set
++
++#
++# Video encoders
++#
++# CONFIG_VIDEO_SAA7127 is not set
++# CONFIG_VIDEO_SAA7185 is not set
++# CONFIG_VIDEO_ADV7170 is not set
++# CONFIG_VIDEO_ADV7175 is not set
++# CONFIG_VIDEO_ADV7343 is not set
++# CONFIG_VIDEO_ADV7393 is not set
++# CONFIG_VIDEO_AD9389B is not set
++# CONFIG_VIDEO_AK881X is not set
++
++#
++# Camera sensor devices
++#
++# CONFIG_VIDEO_OV7670 is not set
++# CONFIG_VIDEO_VS6624 is not set
++# CONFIG_VIDEO_MT9M032 is not set
++# CONFIG_VIDEO_MT9P031 is not set
++# CONFIG_VIDEO_MT9T001 is not set
++# CONFIG_VIDEO_MT9V011 is not set
++# CONFIG_VIDEO_MT9V032 is not set
++# CONFIG_VIDEO_TCM825X is not set
++# CONFIG_VIDEO_SR030PC30 is not set
++# CONFIG_VIDEO_NOON010PC30 is not set
++CONFIG_VIDEO_M5MOLS=y
++# CONFIG_VIDEO_S5K6AA is not set
++# CONFIG_VIDEO_S5K4ECGX is not set
++CONFIG_VIDEO_S5K5BAFX=y
++# CONFIG_VIDEO_SMIAPP is not set
++CONFIG_VIDEO_S5C73M3=y
++
++#
++# Flash devices
++#
++# CONFIG_VIDEO_ADP1653 is not set
++# CONFIG_VIDEO_AS3645A is not set
++
++#
++# Video improvement chips
++#
++# CONFIG_VIDEO_UPD64031A is not set
++# CONFIG_VIDEO_UPD64083 is not set
++
++#
++# Miscelaneous helper chips
++#
++# CONFIG_VIDEO_THS7303 is not set
++# CONFIG_VIDEO_M52790 is not set
++
++#
++# Sensors used on soc_camera driver
++#
++
++#
++# Customise DVB Frontends
++#
++CONFIG_DVB_AU8522=m
++CONFIG_DVB_AU8522_V4L=m
++CONFIG_DVB_TUNER_DIB0070=m
++CONFIG_DVB_TUNER_DIB0090=m
++
++#
++# Tools to develop new frontends
++#
++# CONFIG_DVB_DUMMY_FE is not set
++
++#
++# Graphics support
++#
++
++#
++# ARM GPU Configuration
++#
++CONFIG_MALI_400MP_UMP=y
++# CONFIG_MALI_DED_ONLY is not set
++# CONFIG_MALI_DED_MMU is not set
++CONFIG_MALI_OSMEM_ONLY=y
++# CONFIG_MALI_DED_OSMEM is not set
++# CONFIG_UMP_DED_ONLY is not set
++CONFIG_UMP_OSMEM_ONLY=y
++# CONFIG_UMP_VCM_ONLY is not set
++CONFIG_UMP_MEM_SIZE=512
++# CONFIG_MALI_UMP_R2P4 is not set
++CONFIG_MALI_UMP_R3P0=y
++# CONFIG_VIDEO_MALI400MP_UMP_DEBUG is not set
++# CONFIG_VIDEO_MALI400MP_STREAMLINE_PROFILING is not set
++CONFIG_VIDEO_MALI400MP_DVFS=y
++CONFIG_DRM=y
++CONFIG_DRM_KMS_HELPER=y
++# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set
++
++#
++# I2C encoder or helper chips
++#
++# CONFIG_DRM_I2C_CH7006 is not set
++# CONFIG_DRM_I2C_SIL164 is not set
++CONFIG_DRM_EXYNOS=y
++# CONFIG_DRM_EXYNOS_IOMMU is not set
++CONFIG_DRM_EXYNOS_DMABUF=y
++CONFIG_DRM_EXYNOS_FIMD=y
++# CONFIG_DRM_EXYNOS_HDMI is not set
++CONFIG_DRM_EXYNOS_VIDI=y
++CONFIG_DRM_EXYNOS_G2D=y
++CONFIG_DRM_EXYNOS_IPP=y
++CONFIG_DRM_EXYNOS_FIMC=y
++CONFIG_DRM_EXYNOS_ROTATOR=y
++# CONFIG_DRM_UDL is not set
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_DISPLAY_TIMING=y
++CONFIG_VIDEOMODE=y
++CONFIG_OF_DISPLAY_TIMING=y
++CONFIG_OF_VIDEOMODE=y
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++# CONFIG_FB_BOOT_VESA_SUPPORT is not set
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++# CONFIG_FB_SYS_FILLRECT is not set
++# CONFIG_FB_SYS_COPYAREA is not set
++# CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_FOREIGN_ENDIAN is not set
++# CONFIG_FB_SYS_FOPS is not set
++# CONFIG_FB_WMT_GE_ROPS is not set
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++CONFIG_FB_MODE_HELPERS=y
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_ARMCLCD is not set
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_TMIO is not set
++# CONFIG_FB_SMSCUFX is not set
++# CONFIG_FB_UDL is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_BROADSHEET is not set
++# CONFIG_FB_AUO_K190X is not set
++# CONFIG_EXYNOS_VIDEO is not set
++CONFIG_BACKLIGHT_LCD_SUPPORT=y
++CONFIG_LCD_CLASS_DEVICE=y
++# CONFIG_LCD_L4F00242T03 is not set
++# CONFIG_LCD_LMS283GF05 is not set
++# CONFIG_LCD_LTV350QV is not set
++# CONFIG_LCD_ILI9320 is not set
++# CONFIG_LCD_TDO24M is not set
++# CONFIG_LCD_VGG2432A4 is not set
++# CONFIG_LCD_PLATFORM is not set
++# CONFIG_LCD_S6E63M0 is not set
++# CONFIG_LCD_LD9040 is not set
++# CONFIG_LCD_AMS369FG06 is not set
++CONFIG_BACKLIGHT_CLASS_DEVICE=y
++CONFIG_BACKLIGHT_GENERIC=y
++# CONFIG_BACKLIGHT_PWM is not set
++# CONFIG_BACKLIGHT_ADP8860 is not set
++# CONFIG_BACKLIGHT_ADP8870 is not set
++# CONFIG_BACKLIGHT_LM3630 is not set
++# CONFIG_BACKLIGHT_LM3639 is not set
++# CONFIG_BACKLIGHT_LP855X is not set
++CONFIG_DISPLAY_CORE=y
++CONFIG_DISPLAY_PANEL_S6D6AA1=y
++CONFIG_DISPLAY_PANEL_S6E8AA0=y
++CONFIG_DISPLAY_PANEL_S6E8AX0=y
++CONFIG_DISPLAY_SOURCE_EXYNOS_DSI=y
++
++#
++# Console display driver support
++#
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
++# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
++CONFIG_FONTS=y
++# CONFIG_FONT_8x8 is not set
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_6x11 is not set
++CONFIG_FONT_7x14=y
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++# CONFIG_FONT_MINI_4x6 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_10x18 is not set
++CONFIG_LOGO=y
++CONFIG_LOGO_LINUX_MONO=y
++CONFIG_LOGO_LINUX_VGA16=y
++CONFIG_LOGO_LINUX_CLUT224=y
++# CONFIG_FB_SSD1307 is not set
++CONFIG_SOUND=y
++CONFIG_SOUND_OSS_CORE=y
++CONFIG_SOUND_OSS_CORE_PRECLAIM=y
++CONFIG_SND=y
++CONFIG_SND_TIMER=y
++CONFIG_SND_PCM=y
++CONFIG_SND_HWDEP=y
++CONFIG_SND_COMPRESS_OFFLOAD=y
++CONFIG_SND_JACK=y
++# CONFIG_SND_SEQUENCER is not set
++CONFIG_SND_OSSEMUL=y
++CONFIG_SND_MIXER_OSS=y
++CONFIG_SND_PCM_OSS=y
++CONFIG_SND_PCM_OSS_PLUGINS=y
++CONFIG_SND_HRTIMER=y
++# CONFIG_SND_DYNAMIC_MINORS is not set
++CONFIG_SND_SUPPORT_OLD_API=y
++CONFIG_SND_VERBOSE_PROCFS=y
++# CONFIG_SND_VERBOSE_PRINTK is not set
++CONFIG_SND_DEBUG=y
++# CONFIG_SND_DEBUG_VERBOSE is not set
++# CONFIG_SND_PCM_XRUN_DEBUG is not set
++# CONFIG_SND_RAWMIDI_SEQ is not set
++# CONFIG_SND_OPL3_LIB_SEQ is not set
++# CONFIG_SND_OPL4_LIB_SEQ is not set
++# CONFIG_SND_SBAWE_SEQ is not set
++# CONFIG_SND_EMU10K1_SEQ is not set
++# CONFIG_SND_DRIVERS is not set
++# CONFIG_SND_ARM is not set
++# CONFIG_SND_SPI is not set
++# CONFIG_SND_USB is not set
++CONFIG_SND_SOC=y
++# CONFIG_SND_DESIGNWARE_I2S is not set
++CONFIG_SND_SOC_SAMSUNG=y
++CONFIG_SND_SAMSUNG_PCM=y
++CONFIG_SND_SAMSUNG_SPDIF=y
++CONFIG_SND_SAMSUNG_I2S=y
++CONFIG_SND_SOC_SAMSUNG_SMDK_WM8994=y
++# CONFIG_SND_SAMSUNG_I2S_MASTER is not set
++CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF=y
++CONFIG_SND_SOC_SMDK_WM8994_PCM=y
++CONFIG_SND_SOC_TRATS=y
++CONFIG_SND_SOC_SAMSUNG_EXYNOS4_WM1811=y
++CONFIG_SND_SOC_I2C_AND_SPI=y
++# CONFIG_SND_SOC_ALL_CODECS is not set
++CONFIG_SND_SOC_WM_HUBS=y
++CONFIG_SND_SOC_SPDIF=y
++CONFIG_SND_SOC_WM8994=y
++CONFIG_SND_SOC_MC1N2=y
++CONFIG_SND_SOC_USE_EXTERNAL_MIC_BIAS=y
++# CONFIG_SND_SOC_MC1N2_DEBUG is not set
++# CONFIG_SND_SIMPLE_CARD is not set
++# CONFIG_SOUND_PRIME is not set
++
++#
++# HID support
++#
++CONFIG_HID=y
++# CONFIG_HID_BATTERY_STRENGTH is not set
++# CONFIG_HIDRAW is not set
++# CONFIG_UHID is not set
++CONFIG_HID_GENERIC=y
++
++#
++# Special HID drivers
++#
++# CONFIG_HID_A4TECH is not set
++# CONFIG_HID_ACRUX is not set
++# CONFIG_HID_APPLE is not set
++# CONFIG_HID_AUREAL is not set
++# CONFIG_HID_BELKIN is not set
++# CONFIG_HID_CHERRY is not set
++# CONFIG_HID_CHICONY is not set
++# CONFIG_HID_PRODIKEYS is not set
++# CONFIG_HID_CYPRESS is not set
++# CONFIG_HID_DRAGONRISE is not set
++# CONFIG_HID_EMS_FF is not set
++# CONFIG_HID_ELECOM is not set
++# CONFIG_HID_EZKEY is not set
++# CONFIG_HID_HOLTEK is not set
++# CONFIG_HID_KEYTOUCH is not set
++# CONFIG_HID_KYE is not set
++# CONFIG_HID_UCLOGIC is not set
++# CONFIG_HID_WALTOP is not set
++# CONFIG_HID_GYRATION is not set
++# CONFIG_HID_ICADE is not set
++# CONFIG_HID_TWINHAN is not set
++# CONFIG_HID_KENSINGTON is not set
++# CONFIG_HID_LCPOWER is not set
++# CONFIG_HID_LENOVO_TPKBD is not set
++# CONFIG_HID_LOGITECH is not set
++# CONFIG_HID_MAGICMOUSE is not set
++# CONFIG_HID_MICROSOFT is not set
++# CONFIG_HID_MONTEREY is not set
++# CONFIG_HID_MULTITOUCH is not set
++# CONFIG_HID_NTRIG is not set
++# CONFIG_HID_ORTEK is not set
++# CONFIG_HID_PANTHERLORD is not set
++# CONFIG_HID_PETALYNX is not set
++# CONFIG_HID_PICOLCD is not set
++# CONFIG_HID_PRIMAX is not set
++# CONFIG_HID_PS3REMOTE is not set
++# CONFIG_HID_ROCCAT is not set
++# CONFIG_HID_SAITEK is not set
++# CONFIG_HID_SAMSUNG is not set
++# CONFIG_HID_SONY is not set
++# CONFIG_HID_SPEEDLINK is not set
++# CONFIG_HID_SUNPLUS is not set
++# CONFIG_HID_GREENASIA is not set
++# CONFIG_HID_SMARTJOYPLUS is not set
++# CONFIG_HID_TIVO is not set
++# CONFIG_HID_TOPSEED is not set
++# CONFIG_HID_THRUSTMASTER is not set
++# CONFIG_HID_WACOM is not set
++# CONFIG_HID_WIIMOTE is not set
++# CONFIG_HID_ZEROPLUS is not set
++# CONFIG_HID_ZYDACRON is not set
++# CONFIG_HID_SENSOR_HUB is not set
++
++#
++# USB HID support
++#
++CONFIG_USB_HID=y
++# CONFIG_HID_PID is not set
++# CONFIG_USB_HIDDEV is not set
++
++#
++# I2C HID support
++#
++# CONFIG_I2C_HID is not set
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++# CONFIG_USB_ARCH_HAS_XHCI is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_COMMON=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB=y
++CONFIG_USB_DEBUG=y
++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
++
++#
++# Miscellaneous USB options
++#
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_SUSPEND is not set
++# CONFIG_USB_OTG_WHITELIST is not set
++# CONFIG_USB_OTG_BLACKLIST_HUB is not set
++# CONFIG_USB_DWC3 is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++CONFIG_USB_EHCI_HCD=y
++# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
++CONFIG_USB_EHCI_TT_NEWSCHED=y
++CONFIG_USB_EHCI_S5P=y
++# CONFIG_USB_OXU210HP_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_ISP1760_HCD is not set
++# CONFIG_USB_ISP1362_HCD is not set
++# CONFIG_USB_OHCI_HCD is not set
++# CONFIG_USB_EHCI_HCD_PLATFORM is not set
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_MUSB_HDRC is not set
++# CONFIG_USB_CHIPIDEA is not set
++# CONFIG_USB_RENESAS_USBHS is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
++#
++
++#
++# also be needed; see USB_STORAGE Help for more info
++#
++# CONFIG_USB_STORAGE is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_SEVSEG is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_SISUSBVGA is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_YUREX is not set
++# CONFIG_USB_EZUSB_FX2 is not set
++
++#
++# USB Physical Layer drivers
++#
++# CONFIG_USB_ISP1301 is not set
++# CONFIG_USB_RCAR_PHY is not set
++CONFIG_SAMSUNG_USBPHY=y
++CONFIG_USB_GADGET=y
++# CONFIG_USB_GADGET_DEBUG is not set
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++# CONFIG_USB_GADGET_DEBUG_FS is not set
++CONFIG_USB_GADGET_VBUS_DRAW=2
++CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
++
++#
++# USB Peripheral Controller
++#
++# CONFIG_USB_FUSB300 is not set
++# CONFIG_USB_R8A66597 is not set
++CONFIG_USB_S3C_HSOTG=y
++# CONFIG_USB_MV_UDC is not set
++# CONFIG_USB_M66592 is not set
++# CONFIG_USB_NET2272 is not set
++# CONFIG_USB_DUMMY_HCD is not set
++CONFIG_USB_LIBCOMPOSITE=y
++# CONFIG_USB_ZERO is not set
++# CONFIG_USB_AUDIO is not set
++CONFIG_USB_ETH=y
++CONFIG_USB_ETH_RNDIS=y
++# CONFIG_USB_ETH_EEM is not set
++# CONFIG_USB_G_NCM is not set
++# CONFIG_USB_GADGETFS is not set
++# CONFIG_USB_FUNCTIONFS is not set
++# CONFIG_USB_MASS_STORAGE is not set
++# CONFIG_USB_G_SERIAL is not set
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++# CONFIG_USB_CDC_COMPOSITE is not set
++# CONFIG_USB_G_NOKIA is not set
++# CONFIG_USB_G_ACM_MS is not set
++# CONFIG_USB_G_MULTI is not set
++# CONFIG_USB_G_HID is not set
++# CONFIG_USB_G_DBGP is not set
++# CONFIG_USB_G_WEBCAM is not set
++
++#
++# OTG and related infrastructure
++#
++CONFIG_USB_OTG_UTILS=y
++# CONFIG_USB_GPIO_VBUS is not set
++# CONFIG_USB_ULPI is not set
++# CONFIG_NOP_USB_XCEIV is not set
++CONFIG_MMC=y
++# CONFIG_MMC_DEBUG is not set
++# CONFIG_MMC_UNSAFE_RESUME is not set
++# CONFIG_MMC_CLKGATE is not set
++
++#
++# MMC/SD/SDIO Card Drivers
++#
++CONFIG_MMC_BLOCK=y
++CONFIG_MMC_BLOCK_MINORS=8
++CONFIG_MMC_BLOCK_BOUNCE=y
++# CONFIG_SDIO_UART is not set
++# CONFIG_MMC_TEST is not set
++
++#
++# MMC/SD/SDIO Host Controller Drivers
++#
++# CONFIG_MMC_ARMMMCI is not set
++CONFIG_MMC_SDHCI=y
++CONFIG_MMC_SDHCI_PLTFM=y
++CONFIG_MMC_SDHCI_S3C=y
++# CONFIG_MMC_SDHCI_PXAV3 is not set
++# CONFIG_MMC_SDHCI_PXAV2 is not set
++# CONFIG_MMC_SDHCI_S3C_DMA is not set
++CONFIG_MMC_DW=y
++CONFIG_MMC_DW_IDMAC=y
++CONFIG_MMC_DW_PLTFM=y
++# CONFIG_MMC_DW_EXYNOS is not set
++# CONFIG_MMC_VUB300 is not set
++# CONFIG_MMC_USHC is not set
++# CONFIG_MEMSTICK is not set
++CONFIG_NEW_LEDS=y
++CONFIG_LEDS_CLASS=y
++
++#
++# LED drivers
++#
++# CONFIG_LEDS_LM3530 is not set
++# CONFIG_LEDS_LM3642 is not set
++# CONFIG_LEDS_PCA9532 is not set
++CONFIG_LEDS_GPIO=y
++# CONFIG_LEDS_LP3944 is not set
++# CONFIG_LEDS_LP5521 is not set
++# CONFIG_LEDS_LP5523 is not set
++# CONFIG_LEDS_PCA955X is not set
++# CONFIG_LEDS_PCA9633 is not set
++# CONFIG_LEDS_DAC124S085 is not set
++# CONFIG_LEDS_REGULATOR is not set
++# CONFIG_LEDS_BD2802 is not set
++# CONFIG_LEDS_LT3593 is not set
++# CONFIG_LEDS_RENESAS_TPU is not set
++# CONFIG_LEDS_TCA6507 is not set
++# CONFIG_LEDS_MAX8997 is not set
++# CONFIG_LEDS_LM355x is not set
++# CONFIG_LEDS_OT200 is not set
++# CONFIG_LEDS_BLINKM is not set
++CONFIG_LEDS_TRIGGERS=y
++
++#
++# LED Triggers
++#
++# CONFIG_LEDS_TRIGGER_TIMER is not set
++CONFIG_LEDS_TRIGGER_ONESHOT=y
++CONFIG_LEDS_TRIGGER_HEARTBEAT=y
++CONFIG_LEDS_TRIGGER_BACKLIGHT=y
++CONFIG_LEDS_TRIGGER_CPU=y
++CONFIG_LEDS_TRIGGER_GPIO=y
++CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
++
++#
++# iptables trigger is under Netfilter config (LED target)
++#
++CONFIG_LEDS_TRIGGER_TRANSIENT=y
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_EDAC is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++# CONFIG_RTC_DRV_DS1307 is not set
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_DS3232 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_MAX8997 is not set
++# CONFIG_RTC_DRV_MAX77686 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_ISL12022 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8523 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_BQ32K is not set
++# CONFIG_RTC_DRV_S35390A is not set
++# CONFIG_RTC_DRV_FM3130 is not set
++# CONFIG_RTC_DRV_RX8581 is not set
++# CONFIG_RTC_DRV_RX8025 is not set
++# CONFIG_RTC_DRV_EM3027 is not set
++# CONFIG_RTC_DRV_RV3029C2 is not set
++
++#
++# SPI RTC drivers
++#
++# CONFIG_RTC_DRV_M41T93 is not set
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
++# CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
++# CONFIG_RTC_DRV_PCF2123 is not set
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_MSM6242 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_RP5C01 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++# CONFIG_RTC_DRV_DS2404 is not set
++
++#
++# on-CPU RTC drivers
++#
++CONFIG_HAVE_S3C_RTC=y
++CONFIG_RTC_DRV_S3C=y
++# CONFIG_RTC_DRV_PL030 is not set
++# CONFIG_RTC_DRV_PL031 is not set
++# CONFIG_RTC_DRV_SNVS is not set
++CONFIG_DMADEVICES=y
++# CONFIG_DMADEVICES_DEBUG is not set
++
++#
++# DMA Devices
++#
++# CONFIG_AMBA_PL08X is not set
++# CONFIG_DW_DMAC is not set
++# CONFIG_TIMB_DMA is not set
++CONFIG_PL330_DMA=y
++CONFIG_DMA_ENGINE=y
++
++#
++# DMA Clients
++#
++# CONFIG_NET_DMA is not set
++# CONFIG_ASYNC_TX_DMA is not set
++# CONFIG_DMATEST is not set
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_UIO is not set
++# CONFIG_VFIO is not set
++
++#
++# Virtio drivers
++#
++# CONFIG_VIRTIO_MMIO is not set
++
++#
++# Microsoft Hyper-V guest support
++#
++CONFIG_STAGING=y
++# CONFIG_USBIP_CORE is not set
++# CONFIG_PRISM2_USB is not set
++# CONFIG_ECHO is not set
++# CONFIG_ASUS_OLED is not set
++# CONFIG_RTLLIB is not set
++# CONFIG_R8712U is not set
++# CONFIG_RTS5139 is not set
++# CONFIG_TRANZPORT is not set
++# CONFIG_LINE6_USB is not set
++# CONFIG_VT6656 is not set
++# CONFIG_ZSMALLOC is not set
++# CONFIG_USB_ENESTORAGE is not set
++# CONFIG_BCM_WIMAX is not set
++# CONFIG_FT1000 is not set
++
++#
++# Speakup console speech
++#
++# CONFIG_SPEAKUP is not set
++# CONFIG_TOUCHSCREEN_CLEARPAD_TM1217 is not set
++# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set
++# CONFIG_STAGING_MEDIA is not set
++
++#
++# Android
++#
++CONFIG_ANDROID=y
++CONFIG_ANDROID_BINDER_IPC=y
++CONFIG_ASHMEM=y
++CONFIG_ANDROID_LOGGER=y
++CONFIG_ANDROID_TIMED_OUTPUT=y
++CONFIG_ANDROID_TIMED_GPIO=y
++# CONFIG_ANDROID_LOW_MEMORY_KILLER is not set
++# CONFIG_ANDROID_INTF_ALARM_DEV is not set
++# CONFIG_USB_WPAN_HCD is not set
++# CONFIG_WIMAX_GDM72XX is not set
++# CONFIG_CSR_WIFI is not set
++# CONFIG_CED1401 is not set
++# CONFIG_DGRP is not set
++CONFIG_CLKDEV_LOOKUP=y
++CONFIG_HAVE_CLK_PREPARE=y
++CONFIG_COMMON_CLK=y
++
++#
++# Common Clock Framework
++#
++CONFIG_COMMON_CLK_DEBUG=y
++CONFIG_COMMON_CLK_MAX77686=y
++
++#
++# Hardware Spinlock drivers
++#
++CONFIG_IOMMU_API=y
++CONFIG_IOMMU_SUPPORT=y
++CONFIG_OF_IOMMU=y
++CONFIG_EXYNOS_IOMMU=y
++# CONFIG_EXYNOS_IOMMU_DEBUG is not set
++
++#
++# Remoteproc drivers (EXPERIMENTAL)
++#
++# CONFIG_STE_MODEM_RPROC is not set
++
++#
++# Rpmsg drivers (EXPERIMENTAL)
++#
++# CONFIG_VIRT_DRIVERS is not set
++# CONFIG_PM_DEVFREQ is not set
++# CONFIG_EXTCON is not set
++# CONFIG_MEMORY is not set
++# CONFIG_IIO is not set
++CONFIG_PWM=y
++CONFIG_PWM_SAMSUNG=y
++# CONFIG_IPACK_BUS is not set
++
++#
++# File systems
++#
++CONFIG_DCACHE_WORD_ACCESS=y
++# CONFIG_EXT2_FS is not set
++# CONFIG_EXT3_FS is not set
++CONFIG_EXT4_FS=y
++CONFIG_EXT4_USE_FOR_EXT23=y
++CONFIG_EXT4_FS_POSIX_ACL=y
++CONFIG_EXT4_FS_SECURITY=y
++# CONFIG_EXT4_DEBUG is not set
++CONFIG_JBD2=y
++# CONFIG_JBD2_DEBUG is not set
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_BTRFS_FS is not set
++# CONFIG_NILFS2_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_FILE_LOCKING=y
++CONFIG_FSNOTIFY=y
++# CONFIG_DNOTIFY is not set
++CONFIG_INOTIFY_USER=y
++CONFIG_FANOTIFY=y
++# CONFIG_FANOTIFY_ACCESS_PERMISSIONS is not set
++# CONFIG_QUOTA is not set
++# CONFIG_QUOTACTL is not set
++# CONFIG_AUTOFS4_FS is not set
++CONFIG_FUSE_FS=y
++# CONFIG_CUSE is not set
++CONFIG_GENERIC_ACL=y
++
++#
++# Caches
++#
++# CONFIG_FSCACHE is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++CONFIG_TMPFS_XATTR=y
++# CONFIG_HUGETLB_PAGE is not set
++# CONFIG_CONFIGFS_FS is not set
++CONFIG_MISC_FILESYSTEMS=y
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_LOGFS is not set
++# CONFIG_CRAMFS is not set
++CONFIG_SQUASHFS=y
++CONFIG_SQUASHFS_XATTR=y
++CONFIG_SQUASHFS_ZLIB=y
++CONFIG_SQUASHFS_LZO=y
++# CONFIG_SQUASHFS_XZ is not set
++CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y
++# CONFIG_SQUASHFS_EMBEDDED is not set
++CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_QNX6FS_FS is not set
++CONFIG_ROMFS_FS=y
++CONFIG_ROMFS_BACKED_BY_BLOCK=y
++CONFIG_ROMFS_ON_BLOCK=y
++# CONFIG_PSTORE is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_F2FS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++# CONFIG_NFS_FS is not set
++# CONFIG_NFSD is not set
++# CONFIG_CEPH_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_MAC_ROMAN is not set
++# CONFIG_NLS_MAC_CELTIC is not set
++# CONFIG_NLS_MAC_CENTEURO is not set
++# CONFIG_NLS_MAC_CROATIAN is not set
++# CONFIG_NLS_MAC_CYRILLIC is not set
++# CONFIG_NLS_MAC_GAELIC is not set
++# CONFIG_NLS_MAC_GREEK is not set
++# CONFIG_NLS_MAC_ICELAND is not set
++# CONFIG_NLS_MAC_INUIT is not set
++# CONFIG_NLS_MAC_ROMANIAN is not set
++# CONFIG_NLS_MAC_TURKISH is not set
++CONFIG_NLS_UTF8=y
++
++#
++# Kernel hacking
++#
++CONFIG_PRINTK_TIME=y
++CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_STRIP_ASM_SYMS is not set
++# CONFIG_READABLE_ASM is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++CONFIG_DEBUG_FS=y
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_SECTION_MISMATCH is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++# CONFIG_LOCKUP_DETECTOR is not set
++# CONFIG_PANIC_ON_OOPS is not set
++CONFIG_PANIC_ON_OOPS_VALUE=0
++CONFIG_DETECT_HUNG_TASK=y
++CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
++# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
++CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
++CONFIG_SCHED_DEBUG=y
++CONFIG_SCHEDSTATS=y
++# CONFIG_TIMER_STATS is not set
++# CONFIG_DEBUG_OBJECTS is not set
++# CONFIG_SLUB_STATS is not set
++CONFIG_HAVE_DEBUG_KMEMLEAK=y
++# CONFIG_DEBUG_KMEMLEAK is not set
++# CONFIG_DEBUG_PREEMPT is not set
++# CONFIG_DEBUG_RT_MUTEXES is not set
++# CONFIG_RT_MUTEX_TESTER is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_LOCK_ALLOC is not set
++# CONFIG_PROVE_LOCKING is not set
++# CONFIG_PROVE_RCU_DELAY is not set
++# CONFIG_SPARSE_RCU_POINTER is not set
++# CONFIG_LOCK_STAT is not set
++# CONFIG_DEBUG_ATOMIC_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++CONFIG_STACKTRACE=y
++# CONFIG_DEBUG_STACK_USAGE is not set
++# CONFIG_DEBUG_KOBJECT is not set
++# CONFIG_DEBUG_HIGHMEM is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_INFO_REDUCED is not set
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_WRITECOUNT is not set
++# CONFIG_DEBUG_MEMORY_INIT is not set
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_TEST_LIST_SORT is not set
++# CONFIG_DEBUG_SG is not set
++# CONFIG_DEBUG_NOTIFIERS is not set
++# CONFIG_DEBUG_CREDENTIALS is not set
++# CONFIG_BOOT_PRINTK_DELAY is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++CONFIG_RCU_CPU_STALL_TIMEOUT=60
++CONFIG_RCU_CPU_STALL_VERBOSE=y
++# CONFIG_RCU_CPU_STALL_INFO is not set
++# CONFIG_RCU_TRACE is not set
++# CONFIG_BACKTRACE_SELF_TEST is not set
++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
++# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
++# CONFIG_DEBUG_PER_CPU_MAPS is not set
++# CONFIG_LKDTM is not set
++# CONFIG_NOTIFIER_ERROR_INJECTION is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_DEBUG_PAGEALLOC is not set
++CONFIG_NOP_TRACER=y
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
++CONFIG_HAVE_DYNAMIC_FTRACE=y
++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
++CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
++CONFIG_HAVE_C_RECORDMCOUNT=y
++CONFIG_TRACER_MAX_TRACE=y
++CONFIG_TRACE_CLOCK=y
++CONFIG_RING_BUFFER=y
++CONFIG_EVENT_TRACING=y
++CONFIG_EVENT_POWER_TRACING_DEPRECATED=y
++CONFIG_CONTEXT_SWITCH_TRACER=y
++CONFIG_RING_BUFFER_ALLOW_SWAP=y
++CONFIG_TRACING=y
++CONFIG_GENERIC_TRACER=y
++CONFIG_TRACING_SUPPORT=y
++CONFIG_FTRACE=y
++# CONFIG_FUNCTION_TRACER is not set
++# CONFIG_IRQSOFF_TRACER is not set
++# CONFIG_PREEMPT_TRACER is not set
++CONFIG_SCHED_TRACER=y
++# CONFIG_FTRACE_SYSCALLS is not set
++CONFIG_BRANCH_PROFILE_NONE=y
++# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
++# CONFIG_PROFILE_ALL_BRANCHES is not set
++# CONFIG_STACK_TRACER is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_PROBE_EVENTS is not set
++# CONFIG_FTRACE_STARTUP_TEST is not set
++# CONFIG_RING_BUFFER_BENCHMARK is not set
++# CONFIG_RBTREE_TEST is not set
++# CONFIG_INTERVAL_TREE_TEST is not set
++CONFIG_DYNAMIC_DEBUG=y
++# CONFIG_DMA_API_DEBUG is not set
++# CONFIG_ATOMIC64_SELFTEST is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_KGDB is not set
++# CONFIG_TEST_KSTRTOX is not set
++# CONFIG_STRICT_DEVMEM is not set
++CONFIG_ARM_UNWIND=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_S3C_UART0 is not set
++# CONFIG_DEBUG_S3C_UART1 is not set
++CONFIG_DEBUG_S3C_UART2=y
++# CONFIG_DEBUG_S3C_UART3 is not set
++# CONFIG_DEBUG_LL_UART_NONE is not set
++# CONFIG_DEBUG_ICEDCC is not set
++# CONFIG_DEBUG_SEMIHOSTING is not set
++CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
++CONFIG_EARLY_PRINTK=y
++# CONFIG_OC_ETM is not set
++# CONFIG_PID_IN_CONTEXTIDR is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY_DMESG_RESTRICT is not set
++CONFIG_SECURITY=y
++# CONFIG_SECURITYFS is not set
++CONFIG_SECURITY_NETWORK=y
++# CONFIG_SECURITY_NETWORK_XFRM is not set
++# CONFIG_SECURITY_PATH is not set
++# CONFIG_SECURITY_SELINUX is not set
++CONFIG_SECURITY_SMACK=y
++# CONFIG_SECURITY_TOMOYO is not set
++# CONFIG_SECURITY_APPARMOR is not set
++# CONFIG_SECURITY_YAMA is not set
++# CONFIG_IMA is not set
++CONFIG_DEFAULT_SECURITY_SMACK=y
++# CONFIG_DEFAULT_SECURITY_DAC is not set
++CONFIG_DEFAULT_SECURITY="smack"
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD=y
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_PCOMP2=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_USER is not set
++CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_PCRYPT is not set
++CONFIG_CRYPTO_WORKQUEUE=y
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_AUTHENC=y
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++CONFIG_CRYPTO_ECB=y
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++CONFIG_CRYPTO_HMAC=y
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_VMAC is not set
++
++#
++# Digest
++#
++CONFIG_CRYPTO_CRC32C=y
++# CONFIG_CRYPTO_GHASH is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++CONFIG_CRYPTO_SHA1=y
++# CONFIG_CRYPTO_SHA1_ARM is not set
++CONFIG_CRYPTO_SHA256=y
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_AES_ARM is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++CONFIG_CRYPTO_DEFLATE=y
++# CONFIG_CRYPTO_ZLIB is not set
++CONFIG_CRYPTO_LZO=y
++
++#
++# Random Number Generation
++#
++CONFIG_CRYPTO_ANSI_CPRNG=y
++# CONFIG_CRYPTO_USER_API_HASH is not set
++# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
++CONFIG_CRYPTO_HW=y
++CONFIG_BINARY_PRINTF=y
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_GENERIC_STRNCPY_FROM_USER=y
++CONFIG_GENERIC_STRNLEN_USER=y
++CONFIG_GENERIC_PCI_IOMAP=y
++CONFIG_GENERIC_IO=y
++CONFIG_PERCPU_RWSEM=y
++CONFIG_CRC_CCITT=y
++CONFIG_CRC16=y
++# CONFIG_CRC_T10DIF is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC32_SELFTEST is not set
++CONFIG_CRC32_SLICEBY8=y
++# CONFIG_CRC32_SLICEBY4 is not set
++# CONFIG_CRC32_SARWATE is not set
++# CONFIG_CRC32_BIT is not set
++# CONFIG_CRC7 is not set
++CONFIG_LIBCRC32C=y
++# CONFIG_CRC8 is not set
++CONFIG_AUDIT_GENERIC=y
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_LZO_COMPRESS=y
++CONFIG_LZO_DECOMPRESS=y
++CONFIG_XZ_DEC=y
++CONFIG_XZ_DEC_X86=y
++CONFIG_XZ_DEC_POWERPC=y
++CONFIG_XZ_DEC_IA64=y
++CONFIG_XZ_DEC_ARM=y
++CONFIG_XZ_DEC_ARMTHUMB=y
++CONFIG_XZ_DEC_SPARC=y
++CONFIG_XZ_DEC_BCJ=y
++# CONFIG_XZ_DEC_TEST is not set
++CONFIG_TEXTSEARCH=y
++CONFIG_TEXTSEARCH_KMP=y
++CONFIG_TEXTSEARCH_BM=y
++CONFIG_TEXTSEARCH_FSM=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_DMA=y
++CONFIG_CPU_RMAP=y
++CONFIG_DQL=y
++CONFIG_NLATTR=y
++CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
++# CONFIG_AVERAGE is not set
++# CONFIG_CORDIC is not set
++# CONFIG_DDR is not set
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0174-ARM-i2c-s3c2410-register-resume-early-function.patch b/patches.tizen/0174-ARM-i2c-s3c2410-register-resume-early-function.patch
new file mode 100644 (file)
index 0000000..5e6ebdc
--- /dev/null
@@ -0,0 +1,38 @@
+From df6bc96ef20ee9a26618e82bb15291490d92d272 Mon Sep 17 00:00:00 2001
+From: Donghwa Lee <dh09.lee@samsung.com>
+Date: Wed, 20 Mar 2013 19:44:23 +0900
+Subject: [PATCH 0174/1302] ARM: i2c-s3c2410: register resume early function
+
+register i2c-s3c2410 resume function earlier than other device.
+
+Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/i2c/busses/i2c-s3c2410.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
+index cab1c91..7c6c3eb 100644
+--- a/drivers/i2c/busses/i2c-s3c2410.c
++++ b/drivers/i2c/busses/i2c-s3c2410.c
+@@ -1199,7 +1199,7 @@ static int s3c24xx_i2c_suspend_noirq(struct device *dev)
+       return 0;
+ }
+-static int s3c24xx_i2c_resume(struct device *dev)
++static int s3c24xx_i2c_resume_early(struct device *dev)
+ {
+       struct platform_device *pdev = to_platform_device(dev);
+       struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
+@@ -1217,7 +1217,7 @@ static int s3c24xx_i2c_resume(struct device *dev)
+ static const struct dev_pm_ops s3c24xx_i2c_dev_pm_ops = {
+ #ifdef CONFIG_PM_SLEEP
+       .suspend_noirq = s3c24xx_i2c_suspend_noirq,
+-      .resume = s3c24xx_i2c_resume,
++      .resume_early = s3c24xx_i2c_resume_early,
+ #endif
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0175-ARM-dts-exynos4412-redwood-Add-menu-key.patch b/patches.tizen/0175-ARM-dts-exynos4412-redwood-Add-menu-key.patch
new file mode 100644 (file)
index 0000000..3df5609
--- /dev/null
@@ -0,0 +1,38 @@
+From cdfed0ec79879f81a7a5349aab6fd0e3cdf6d25b Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Wed, 20 Mar 2013 20:47:51 +0900
+Subject: [PATCH 0175/1302] ARM: dts: exynos4412-redwood: Add menu key
+
+This patch adds a node of menu key. The redwood has menu(home) key and its key
+code is 139.
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-redwood.dts | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-redwood.dts b/arch/arm/boot/dts/exynos4412-redwood.dts
+index 17f704e..0f86fea 100644
+--- a/arch/arm/boot/dts/exynos4412-redwood.dts
++++ b/arch/arm/boot/dts/exynos4412-redwood.dts
+@@ -132,6 +132,16 @@
+                       debounce-interval = <10>;
+                       gpio-key,wakeup;
+               };
++
++              key@139 {
++                      interrupt-parent = <&gpx0>;
++                      interrupts = <1 0>;
++                      gpios = <&gpx0 1 1>;
++                      linux,code = <139>;
++                      label = "menu";
++                      debounce-interval = <10>;
++                      gpio-key,wakeup;
++              };
+       };
+       i2c_0: i2c@13860000 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0176-ARM-DISPLAY-support-suspend-resume-for-mipi-dsi-of-D.patch b/patches.tizen/0176-ARM-DISPLAY-support-suspend-resume-for-mipi-dsi-of-D.patch
new file mode 100644 (file)
index 0000000..fb4cdc1
--- /dev/null
@@ -0,0 +1,93 @@
+From f6224da85d9e3dd3522df3ae8818b20755b76736 Mon Sep 17 00:00:00 2001
+From: Donghwa Lee <dh09.lee@samsung.com>
+Date: Thu, 21 Mar 2013 09:45:29 +0900
+Subject: [PATCH 0176/1302] ARM: DISPLAY: support suspend/resume for mipi dsi
+ of DISPLAY CORE
+
+Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/video/display/source-exynos_dsi.c | 37 ++++++++++++++++++++++++++-----
+ 1 file changed, 32 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/video/display/source-exynos_dsi.c b/drivers/video/display/source-exynos_dsi.c
+index 145d57b..d7094f4 100644
+--- a/drivers/video/display/source-exynos_dsi.c
++++ b/drivers/video/display/source-exynos_dsi.c
+@@ -989,7 +989,9 @@ static int exynos_dsi_enable(struct video_source *src)
+               return ret;
+       dsi->params = params.p.dsi;
+-      regulator_bulk_enable(ARRAY_SIZE(dsi->supplies), dsi->supplies);
++      ret = regulator_bulk_enable(ARRAY_SIZE(dsi->supplies), dsi->supplies);
++      if (ret < 0)
++              return ret;
+       clk_prepare_enable(dsi->bus_clk);
+       clk_prepare_enable(dsi->pll_clk);
+@@ -1008,6 +1010,7 @@ static int exynos_dsi_enable(struct video_source *src)
+ static int exynos_dsi_disable(struct video_source *src)
+ {
+       struct exynos_dsi *dsi = src_to_dsi(src);
++      int ret;
+       if (!dsi->enabled)
+               return 0;
+@@ -1025,7 +1028,9 @@ static int exynos_dsi_disable(struct video_source *src)
+       clk_disable_unprepare(dsi->pll_clk);
+       clk_disable_unprepare(dsi->bus_clk);
+-      regulator_bulk_disable(ARRAY_SIZE(dsi->supplies), dsi->supplies);
++      ret = regulator_bulk_disable(ARRAY_SIZE(dsi->supplies), dsi->supplies);
++      if (ret < 0)
++              return ret;
+       return 0;
+ }
+@@ -1297,18 +1302,40 @@ static int exynos_dsi_remove(struct platform_device *pdev)
+  * Power management
+  */
++#ifdef CONFIG_PM_SLEEP
+ static int exynos_dsi_suspend(struct device *dev)
+ {
+       struct exynos_dsi *dsi = dev_get_drvdata(dev);
++      struct video_source *src = &dsi->out;
++      int ret;
+-      if (dsi->enabled)
+-              return -EBUSY;
++      if (dsi->enabled) {
++              ret = display_entity_set_state(src->sink, DISPLAY_ENTITY_STATE_OFF);
++              if (ret < 0)
++                      return -EBUSY;
++      }
+       return 0;
+ }
++static int exynos_dsi_resume(struct device *dev)
++{
++      struct exynos_dsi *dsi = dev_get_drvdata(dev);
++      struct video_source *src = &dsi->out;
++      int ret;
++
++      if (!dsi->enabled) {
++              ret = display_entity_set_state(src->sink, DISPLAY_ENTITY_STATE_ON);
++              if (ret < 0)
++                      return -EBUSY;
++      }
++
++      return 0;
++}
++#endif
++
+ static const struct dev_pm_ops exynos_dsi_pm_ops = {
+-      SET_SYSTEM_SLEEP_PM_OPS(exynos_dsi_suspend, NULL)
++      SET_SYSTEM_SLEEP_PM_OPS(exynos_dsi_suspend, exynos_dsi_resume)
+ };
+ /*
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0177-ARM-dts-change-mdma-clock-node-of-4x12.patch b/patches.tizen/0177-ARM-dts-change-mdma-clock-node-of-4x12.patch
new file mode 100644 (file)
index 0000000..a691be9
--- /dev/null
@@ -0,0 +1,34 @@
+From 753ae81eb752c83c0451b96ab18cfeeb5f2e6093 Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Fri, 22 Mar 2013 14:11:09 +0900
+Subject: [PATCH 0177/1302] ARM: dts: change mdma clock node of 4x12
+
+A MDMA gate clock is controlled by CLK_GATE_IP_IMAGE. Its base address differs
+4210 and 4x12. If we use a 4x12 board, we should use right clock node of mdma.
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12.dtsi | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index c2cdbffb..9d386fc 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -71,6 +71,12 @@
+               };
+       };
++      amba {
++              mdma1: mdma@12850000 {
++                      clocks = <&clock 350>;
++              };
++      };
++
+       mshc@12550000 {
+               compatible = "samsung,exynos4412-dw-mshc";
+               reg = <0x12550000 0x1000>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0178-ARM-dts-exynos4210-trats-Adjust-regulator-configurat.patch b/patches.tizen/0178-ARM-dts-exynos4210-trats-Adjust-regulator-configurat.patch
new file mode 100644 (file)
index 0000000..c4c50e7
--- /dev/null
@@ -0,0 +1,126 @@
+From a7964b0f4b64e73b5b976ee49ec110248ea973a9 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 20 Mar 2013 12:24:57 +0100
+Subject: [PATCH 0178/1302] ARM: dts: exynos4210-trats: Adjust regulator
+ configuration
+
+This patch modifies configuration of voltage regulators to match those
+used in exynos-3.0-dev kernel.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 61 ++++++++++++++++++++++++++--------
+ 1 file changed, 48 insertions(+), 13 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index 6b7dd39..0508e6c0 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -320,15 +320,24 @@
+                               };
+                               vusb_reg: LDO3 {
+-                                   regulator-name = "VUSB_1.1V_C210";
+-                                   regulator-min-microvolt = <1100000>;
+-                                   regulator-max-microvolt = <1100000>;
++                                      regulator-name = "VUSB_1.1V_C210";
++                                      regulator-min-microvolt = <1100000>;
++                                      regulator-max-microvolt = <1100000>;
++                                      regulator-always-on;
+                               };
+                               vmipi_reg: LDO4 {
+-                                   regulator-name = "VMIPI_1.8V";
+-                                   regulator-min-microvolt = <1800000>;
+-                                   regulator-max-microvolt = <1800000>;
++                                      regulator-name = "VMIPI_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              vhsic_reg: LDO5 {
++                                      regulator-name = "VHSIC_1.2V";
++                                      regulator-min-microvolt = <1200000>;
++                                      regulator-max-microvolt = <1200000>;
++                                      regulator-always-on;
+                               };
+                               vpda_reg: LDO6 {
+@@ -345,9 +354,10 @@
+                               };
+                               vusbdac_reg: LDO8 {
+-                                   regulator-name = "VUSB/VDAC_3.3V_C210";
++                                   regulator-name = "VUSB_3.3V";
+                                    regulator-min-microvolt = <3300000>;
+                                    regulator-max-microvolt = <3300000>;
++                                   regulator-always-on;
+                               };
+                               vccpda_reg: LDO9 {
+@@ -364,6 +374,12 @@
+                                    regulator-always-on;
+                               };
++                              vtouch_reg: LDO11 {
++                                      regulator-name = "TOUCH_2.8V";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
++                              };
++
+                               vtcam_reg: LDO12 {
+                                    regulator-name = "VT_CAM_1.8V";
+                                    regulator-min-microvolt = <1800000>;
+@@ -371,15 +387,22 @@
+                               };
+                               vcclcd_reg: LDO13 {
+-                                   regulator-name = "VCC_3.3V_LCD";
+-                                   regulator-min-microvolt = <3300000>;
+-                                   regulator-max-microvolt = <3300000>;
++                                   regulator-name = "VCC_3.0V_LCD";
++                                   regulator-min-microvolt = <3000000>;
++                                   regulator-max-microvolt = <3000000>;
++                              };
++
++                              vmotor_reg: LDO14 {
++                                      regulator-name = "VCC_2.8V_MOTOR";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
+                               };
+                               vlcd_reg: LDO15 {
+-                                   regulator-name = "VLCD_2.2V";
+-                                   regulator-min-microvolt = <2200000>;
+-                                   regulator-max-microvolt = <2200000>;
++                                      regulator-name = "VLCD_2.2V";
++                                      regulator-min-microvolt = <2200000>;
++                                      regulator-max-microvolt = <2200000>;
++                                      regulator-always-on;
+                               };
+                               camsensor_reg: LDO16 {
+@@ -388,6 +411,18 @@
+                                    regulator-max-microvolt = <1800000>;
+                               };
++                              vtf_reg: LDO17 {
++                                      regulator-name = "VTF_2.8V";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
++                              };
++
++                              vtouch_led_reg: LDO18 {
++                                      regulator-name = "TOUCH_LED_3.3V";
++                                      regulator-min-microvolt = <3000000>;
++                                      regulator-max-microvolt = <3300000>;
++                              };
++
+                               vddq_reg: LDO21 {
+                                    regulator-name = "VDDQ_M1M2_1.2V";
+                                    regulator-min-microvolt = <1200000>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0179-ARM-EXYNOS-Fix-incorrect-usage-of-S5P_ARM_CORE1_-reg.patch b/patches.tizen/0179-ARM-EXYNOS-Fix-incorrect-usage-of-S5P_ARM_CORE1_-reg.patch
new file mode 100644 (file)
index 0000000..b56c9a8
--- /dev/null
@@ -0,0 +1,96 @@
+From b5fc541c112beb40e0a35b9c3161bb6ea386191e Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 8 Feb 2013 14:57:03 +0100
+Subject: [PATCH 0179/1302] ARM: EXYNOS: Fix incorrect usage of S5P_ARM_CORE1_*
+ registers
+
+S5P_ARM_CORE1_* registers affect only core 1. To control further cores
+properly another registers must be used.
+
+This patch replaces S5P_ARM_CORE1_* register definitions with
+S5P_ARM_CORE_*(x) macro which return addresses of registers for specified
+core.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/mach-exynos/hotplug.c               |  6 +++---
+ arch/arm/mach-exynos/include/mach/regs-pmu.h | 10 +++++++---
+ arch/arm/mach-exynos/platsmp.c               |  9 +++++----
+ 3 files changed, 15 insertions(+), 10 deletions(-)
+
+diff --git a/arch/arm/mach-exynos/hotplug.c b/arch/arm/mach-exynos/hotplug.c
+index af90cfa..4b8e1f7 100644
+--- a/arch/arm/mach-exynos/hotplug.c
++++ b/arch/arm/mach-exynos/hotplug.c
+@@ -93,10 +93,10 @@ static inline void cpu_leave_lowpower(void)
+ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
+ {
+       for (;;) {
++              void __iomem *reg_base;
+-              /* make cpu1 to be turned off at next WFI command */
+-              if (cpu == 1)
+-                      __raw_writel(0, S5P_ARM_CORE1_CONFIGURATION);
++              reg_base = S5P_ARM_CORE_CONFIGURATION(cpu_logical_map(cpu));
++              __raw_writel(0, reg_base);
+               /*
+                * here's the WFI
+diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu.h b/arch/arm/mach-exynos/include/mach/regs-pmu.h
+index 57344b7..cf40b86 100644
+--- a/arch/arm/mach-exynos/include/mach/regs-pmu.h
++++ b/arch/arm/mach-exynos/include/mach/regs-pmu.h
+@@ -125,10 +125,14 @@
+ #define S5P_GPS_ALIVE_LOWPWR                  S5P_PMUREG(0x13A0)
+ #define S5P_ARM_CORE0_CONFIGURATION           S5P_PMUREG(0x2000)
++#define S5P_ARM_CORE0_STATUS                  S5P_PMUREG(0x2004)
+ #define S5P_ARM_CORE0_OPTION                  S5P_PMUREG(0x2008)
+-#define S5P_ARM_CORE1_CONFIGURATION           S5P_PMUREG(0x2080)
+-#define S5P_ARM_CORE1_STATUS                  S5P_PMUREG(0x2084)
+-#define S5P_ARM_CORE1_OPTION                  S5P_PMUREG(0x2088)
++#define S5P_ARM_CORE_CONFIGURATION(_nr)               \
++              (S5P_ARM_CORE0_CONFIGURATION + ((_nr) * 0x80))
++#define S5P_ARM_CORE_STATUS(_nr)              \
++              (S5P_ARM_CORE0_STATUS + ((_nr) * 0x80))
++#define S5P_ARM_CORE_OPTION(_nr)              \
++              (S5P_ARM_CORE0_OPTION + ((_nr) * 0x80))
+ #define S5P_ARM_COMMON_OPTION                 S5P_PMUREG(0x2408)
+ #define S5P_TOP_PWR_OPTION                    S5P_PMUREG(0x2C48)
+diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
+index a0e8ff7..8da3ec0 100644
+--- a/arch/arm/mach-exynos/platsmp.c
++++ b/arch/arm/mach-exynos/platsmp.c
+@@ -109,14 +109,15 @@ static int __cpuinit exynos_boot_secondary(unsigned int cpu, struct task_struct
+        */
+       write_pen_release(phys_cpu);
+-      if (!(__raw_readl(S5P_ARM_CORE1_STATUS) & S5P_CORE_LOCAL_PWR_EN)) {
++      if (!(__raw_readl(S5P_ARM_CORE_STATUS(phys_cpu))
++              & S5P_CORE_LOCAL_PWR_EN)) {
+               __raw_writel(S5P_CORE_LOCAL_PWR_EN,
+-                           S5P_ARM_CORE1_CONFIGURATION);
++                           S5P_ARM_CORE_CONFIGURATION(phys_cpu));
+               timeout = 10;
+               /* wait max 10 ms until cpu1 is on */
+-              while ((__raw_readl(S5P_ARM_CORE1_STATUS)
++              while ((__raw_readl(S5P_ARM_CORE_STATUS(phys_cpu))
+                       & S5P_CORE_LOCAL_PWR_EN) != S5P_CORE_LOCAL_PWR_EN) {
+                       if (timeout-- == 0)
+                               break;
+@@ -125,7 +126,7 @@ static int __cpuinit exynos_boot_secondary(unsigned int cpu, struct task_struct
+               }
+               if (timeout == 0) {
+-                      printk(KERN_ERR "cpu1 power enable failed");
++                      printk(KERN_ERR "cpu%u power enable failed", cpu);
+                       spin_unlock(&boot_lock);
+                       return -ETIMEDOUT;
+               }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0180-video-display-panel-s6e8aa0-Add-support-for-suspend-.patch b/patches.tizen/0180-video-display-panel-s6e8aa0-Add-support-for-suspend-.patch
new file mode 100644 (file)
index 0000000..26e132d
--- /dev/null
@@ -0,0 +1,62 @@
+From 8f989957167829755174e5759a53a1dc76041764 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Tue, 26 Mar 2013 14:52:33 +0100
+Subject: [PATCH 0180/1302] video: display: panel-s6e8aa0: Add support for
+ suspend/resume
+
+This patch adds suspend and resume callbacks to the driver to turn off
+the display on suspend and turn it back on on resume if it was enabled
+before.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/video/display/panel-s6e8aa0.c | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+diff --git a/drivers/video/display/panel-s6e8aa0.c b/drivers/video/display/panel-s6e8aa0.c
+index 59c1ec9..3f69187 100644
+--- a/drivers/video/display/panel-s6e8aa0.c
++++ b/drivers/video/display/panel-s6e8aa0.c
+@@ -1227,6 +1227,30 @@ static int s6e8aa0_remove(struct platform_device *pdev)
+       return 0;
+ }
++static int s6e8aa0_suspend(struct device *dev)
++{
++      struct s6e8aa0 *lcd = dev_get_drvdata(dev);
++
++      if (lcd->power != FB_BLANK_UNBLANK)
++              return 0;
++
++      return display_entity_set_state(&lcd->entity, DISPLAY_ENTITY_STATE_OFF);
++}
++
++static int s6e8aa0_resume(struct device *dev)
++{
++      struct s6e8aa0 *lcd = dev_get_drvdata(dev);
++
++      if (lcd->power != FB_BLANK_UNBLANK)
++              return 0;
++
++      return display_entity_set_state(&lcd->entity, DISPLAY_ENTITY_STATE_ON);
++}
++
++static struct dev_pm_ops s6e8aa0_pm_ops = {
++      SET_SYSTEM_SLEEP_PM_OPS(s6e8aa0_suspend, s6e8aa0_resume)
++};
++
+ static struct platform_driver s6e8aa0_driver = {
+       .probe = s6e8aa0_probe,
+       .remove = s6e8aa0_remove,
+@@ -1234,6 +1258,7 @@ static struct platform_driver s6e8aa0_driver = {
+               .name = "panel_s6e8aa0",
+               .owner = THIS_MODULE,
+               .of_match_table = of_match_ptr(s6e8aa0_of_match),
++              .pm = &s6e8aa0_pm_ops,
+       },
+ };
+ module_platform_driver(s6e8aa0_driver);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0181-video-display-panel-s6d6aa1-Add-support-for-suspend-.patch b/patches.tizen/0181-video-display-panel-s6d6aa1-Add-support-for-suspend-.patch
new file mode 100644 (file)
index 0000000..e0d25dc
--- /dev/null
@@ -0,0 +1,62 @@
+From ad6f54924f99c2ac75f295cc3114ae4e9091d508 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Tue, 26 Mar 2013 14:54:56 +0100
+Subject: [PATCH 0181/1302] video: display: panel-s6d6aa1: Add support for
+ suspend/resume
+
+This patch adds suspend and resume callbacks to the driver to turn off
+the display on suspend and turn it back on on resume if it was enabled
+before.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/video/display/panel-s6d6aa1.c | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+diff --git a/drivers/video/display/panel-s6d6aa1.c b/drivers/video/display/panel-s6d6aa1.c
+index d62def9..6f6080c 100644
+--- a/drivers/video/display/panel-s6d6aa1.c
++++ b/drivers/video/display/panel-s6d6aa1.c
+@@ -751,6 +751,30 @@ static int s6d6aa1_remove(struct platform_device *dev)
+       return 0;
+ }
++static int s6d6aa1_suspend(struct device *dev)
++{
++      struct s6d6aa1 *lcd = dev_get_drvdata(dev);
++
++      if (lcd->power != FB_BLANK_UNBLANK)
++              return 0;
++
++      return display_entity_set_state(&lcd->entity, DISPLAY_ENTITY_STATE_OFF);
++}
++
++static int s6d6aa1_resume(struct device *dev)
++{
++      struct s6d6aa1 *lcd = dev_get_drvdata(dev);
++
++      if (lcd->power != FB_BLANK_UNBLANK)
++              return 0;
++
++      return display_entity_set_state(&lcd->entity, DISPLAY_ENTITY_STATE_ON);
++}
++
++static struct dev_pm_ops s6d6aa1_pm_ops = {
++      SET_SYSTEM_SLEEP_PM_OPS(s6d6aa1_suspend, s6d6aa1_resume)
++};
++
+ static struct platform_driver s6d6aa1_driver = {
+       .probe = s6d6aa1_probe,
+       .remove = s6d6aa1_remove,
+@@ -758,6 +782,7 @@ static struct platform_driver s6d6aa1_driver = {
+               .name = "panel_s6d6aa1",
+               .owner = THIS_MODULE,
+               .of_match_table = of_match_ptr(s6d6aa1_of_match),
++              .pm = &s6d6aa1_pm_ops,
+       },
+ };
+ module_platform_driver(s6d6aa1_driver);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0182-packaging-add-.spec-file-to-generate-kernel-headers.patch b/patches.tizen/0182-packaging-add-.spec-file-to-generate-kernel-headers.patch
new file mode 100644 (file)
index 0000000..54e02f9
--- /dev/null
@@ -0,0 +1,67 @@
+From 1040b2b7d76c201b09dc4c7bfff1c08a414b5a31 Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Wed, 27 Mar 2013 16:55:49 +0900
+Subject: [PATCH 0182/1302] packaging: add .spec file to generate
+ kernel-headers
+
+This patch is able to generate kernel-headers by GBS. I'll add build script
+to generate a kernel binary.
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ packaging/linux-kernel.spec | 42 ++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 42 insertions(+)
+ create mode 100644 packaging/linux-kernel.spec
+
+diff --git a/packaging/linux-kernel.spec b/packaging/linux-kernel.spec
+new file mode 100644
+index 0000000..dbd105f
+--- /dev/null
++++ b/packaging/linux-kernel.spec
+@@ -0,0 +1,42 @@
++Name: linux-kernel
++Summary: The Linux Kernel
++Version: 3.8.3
++Release: 1
++License: GPL
++Group: System Environment/Kernel
++Vendor: The Linux Community
++URL: http://www.kernel.org
++Source0:   %{name}-%{version}.tar.gz
++BuildRoot: %{_tmppath}/%{name}-%{PACKAGE_VERSION}-root
++
++%description
++The Linux Kernel, the operating system core itself
++
++%package headers
++Summary: Header files for the Linux kernel for use by glibc
++Group: Development/System
++Obsoletes: kernel-headers
++Provides: kernel-headers = %{version}
++%description headers
++Kernel-headers includes the C header files that specify the interface
++between the Linux kernel and userspace libraries and programs.  The
++header files define structures and constants that are needed for
++building most standard programs and are also needed for rebuilding the
++glibc package.
++
++%prep
++%setup -q
++
++%build
++
++%install
++QA_SKIP_BUILD_ROOT="DO_NOT_WANT"; export QA_SKIP_BUILD_ROOT
++mkdir $RPM_BUILD_ROOT/usr
++make ARCH=arm INSTALL_HDR_PATH=$RPM_BUILD_ROOT/usr headers_install
++
++%clean
++rm -rf $RPM_BUILD_ROOT
++
++%files headers
++%defattr (-, root, root)
++/usr/include
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0183-ARM-dts-Add-ak8975-device-node-for-PQ-M0-board.patch b/patches.tizen/0183-ARM-dts-Add-ak8975-device-node-for-PQ-M0-board.patch
new file mode 100644 (file)
index 0000000..7721d2b
--- /dev/null
@@ -0,0 +1,44 @@
+From bbf42fbabbcaba4d8e6df25649cbf55c5b211e08 Mon Sep 17 00:00:00 2001
+From: Jacek Anaszewski <j.anaszewski@samsung.com>
+Date: Fri, 29 Mar 2013 12:09:10 +0100
+Subject: [PATCH 0183/1302] ARM: dts: Add ak8975 device node for PQ/M0 board
+
+This patch adds ak8975 magnetometer node and corresponding
+i2c-gpio bus node for PQ/M0 board.
+
+Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 9fb3fc4..55fee8d0 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -139,6 +139,22 @@
+               };
+       };
++      i2c-gpio-0 {
++              compatible = "i2c-gpio";
++              gpios = <&gpy2 4 0>, <&gpy2 5 0>;
++              i2c-gpio,delay-us = <2>;
++              #address-cells = <1>;
++              #size-cells = <0>;
++              status = "okay";
++
++              ak8975@0C {
++                      compatible = "ak8975";
++                      reg = <0x0C>;
++                      gpios = <&gpj0 7 0>;
++                      position = <2>;
++              };
++      };
++
+       i2c_0: i2c@13860000 {
+               samsung,i2c-sda-delay = <100>;
+               samsung,i2c-slave-addr = <0x10>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0184-ARM-dts-Add-I2C-bus-and-the-device-node-for-LPS331-s.patch b/patches.tizen/0184-ARM-dts-Add-I2C-bus-and-the-device-node-for-LPS331-s.patch
new file mode 100644 (file)
index 0000000..fe7d2f7
--- /dev/null
@@ -0,0 +1,41 @@
+From 2dc541d4af5cf908c3458a5679c319018fe1840e Mon Sep 17 00:00:00 2001
+From: Jacek Anaszewski <j.anaszewski@samsung.com>
+Date: Tue, 2 Apr 2013 14:54:51 +0200
+Subject: [PATCH 0184/1302] ARM: dts: Add I2C bus and the device node for
+ LPS331 sensor for PQ board
+
+Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 55fee8d0..d44c93c 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -155,6 +155,21 @@
+               };
+       };
++      i2c-gpio-1 {
++              compatible = "i2c-gpio";
++              gpios = <&gpy2 2 0>, <&gpy2 3 0>;
++              i2c-gpio,delay-us = <2>;
++              #address-cells = <1>;
++              #size-cells = <0>;
++              status = "okay";
++
++              lps331ap@5D {
++                      compatible = "lps331ap";
++                      reg = <0x5D>;
++                      gpios = <&gpf0 5 0>;
++              };
++      };
++
+       i2c_0: i2c@13860000 {
+               samsung,i2c-sda-delay = <100>;
+               samsung,i2c-slave-addr = <0x10>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0185-ARM-dts-Add-clock-properties-to-ISP-I2C-node-in-exyn.patch b/patches.tizen/0185-ARM-dts-Add-clock-properties-to-ISP-I2C-node-in-exyn.patch
new file mode 100644 (file)
index 0000000..97c07c6
--- /dev/null
@@ -0,0 +1,28 @@
+From 1818453ae06d5492df531759debdb15039818065 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 28 Mar 2013 15:28:55 +0100
+Subject: [PATCH 0185/1302] ARM: dts: Add clock properties to ISP I2C node in
+ exynos4x12.dtsi
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12.dtsi | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index 9d386fc..93cb006 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -295,6 +295,8 @@
+                       i2c1_isp: i2c-isp@12140000 {
+                               compatible = "samsung,exynos4212-i2c-isp";
+                               reg = <0x12130000 0x100>;
++                              clocks = <&clock 370>;
++                              clock-names = "i2c_isp";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0186-ARM-dts-Add-missing-clocks-to-fimc-is-node-in-exynos.patch b/patches.tizen/0186-ARM-dts-Add-missing-clocks-to-fimc-is-node-in-exynos.patch
new file mode 100644 (file)
index 0000000..490e1fd
--- /dev/null
@@ -0,0 +1,43 @@
+From 45b59af6d1b72067c7187e745bfdd134283285d5 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 28 Mar 2013 21:29:23 +0100
+Subject: [PATCH 0186/1302] ARM: dts: Add missing clocks to fimc-is node in
+ exynos4x12.dtsi
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12.dtsi | 17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index 93cb006..1e016a9 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -280,9 +280,20 @@
+                       interrupts = <0 90 0>, <0 95 0>;
+                       samsung,power-domain = <&pd_isp>;
+                       clocks = <&clock 353>, <&clock 354>, <&clock 355>,
+-                               <&clock 356>, <&clock 342>, <&clock 17>;
+-                      clock-names = "flite0", "flite1", "ppmuispx",
+-                              "ppmuispmx", "sysreg", "mpll";
++                              <&clock 356>, <&clock 342>, <&clock 17>,
++                              <&clock 357>, <&clock 358>, <&clock 359>,
++                              <&clock 360>, <&clock 512>,<&clock 513>,
++                              <&clock 514>, <&clock 515>, <&clock 176>,
++                              <&clock 13>, <&clock 516>, <&clock 22>,
++                              <&clock 517>;
++                      clock-names = "lite0", "lite1", "ppmuispx",
++                                    "ppmuispmx", "sysreg", "mpll",
++                                    "isp", "drc", "fd",
++                                    "mcuisp", "ispdiv0", "ispdiv1",
++                                    "mcuispdiv0", "mcuispdiv1", "uart",
++                                    "aclk200", "div_aclk200", "aclk400mcuisp",
++                                    "div_aclk400mcuisp";
++
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0187-dts-pq-Add-max77693-s-initial-data-to-pq-s-device-tr.patch b/patches.tizen/0187-dts-pq-Add-max77693-s-initial-data-to-pq-s-device-tr.patch
new file mode 100644 (file)
index 0000000..08aa810
--- /dev/null
@@ -0,0 +1,79 @@
+From 338c04bf0914cf55399134bfdbabb6ba3d52a574 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Fri, 5 Apr 2013 16:13:17 +0900
+Subject: [PATCH 0187/1302] dts: pq: Add max77693's initial data to pq's device
+ tree.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 53 +++++++++++++++++++++++++++++++++
+ 1 file changed, 53 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index d44c93c..54213ca 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -530,6 +530,59 @@
+               };
+       };
++      i2c_if_pmic: i2c@0 {
++              compatible = "i2c-gpio";
++              gpios = <&gpm2 0 0
++                       &gpm2 1 0
++                      >;
++              #address-cells = <1>;
++              #size-cells = <0>;
++
++              max77693@66 {
++                      compatible = "maxim,max77693";
++                      interrupt-parent = <&gpx1>;
++                      interrupts = <5 0>;
++                      wakeup = <1>;
++                      reg = <0x66>;
++
++                      regulators {
++                              esafeout@1 {
++                                      regulator-compatible = "ESAFEOUT1";
++                                      regulator-name = "ESAFEOUT1";
++                                      regulator-min-microvolt = <4900000>;
++                                      regulator-max-microvolt = <4900000>;
++                              };
++                              esafeout@2 {
++                                      regulator-compatible = "ESAFEOUT2";
++                                      regulator-name = "ESAFEOUT2";
++                                      regulator-min-microvolt = <4900000>;
++                                      regulator-max-microvolt = <4900000>;
++                              };
++                              charger@0 {
++                                      regulator-compatible = "CHARGER";
++                                      regulator-name = "CHARGER";
++                                      regulator-min-microvolt = <100000>;
++                                      regulator-max-microvolt = <2100000>;
++                                      number-of-consumer-supplies = <1>;
++                                      consumer-suppilies@0 {
++                                              consumer-name = "vinchg1";
++                                              supply-name = "charger-manager.0";
++                                      };
++                              };
++                      };
++                      muic_regs {
++                              intmask@1 {
++                                      addr = <0x7>;
++                                      data = <0x9>;
++                              };
++                              intmask@2 {
++                                      addr = <0x8>;
++                                      data = <0x1>;
++                              };
++                      };
++              };      
++      };
++
+       lcd_vdd3_reg: voltage-regulator@1 {
+               compatible = "regulator-fixed";
+               regulator-name = "LCD_VDD_2.2V";
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0188-mfd-max77693-Support-device-tree-in-max77693-mfd-dri.patch b/patches.tizen/0188-mfd-max77693-Support-device-tree-in-max77693-mfd-dri.patch
new file mode 100644 (file)
index 0000000..638f6a6
--- /dev/null
@@ -0,0 +1,74 @@
+From 2930b9ae915cc9fec6a08858d37e9e770d7a0a40 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Fri, 5 Apr 2013 15:45:21 +0900
+Subject: [PATCH 0188/1302] mfd: max77693: Support device tree in max77693 mfd
+ driver.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mfd/max77693.c | 34 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 34 insertions(+)
+
+diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c
+index 9e60fed..0f925af 100644
+--- a/drivers/mfd/max77693.c
++++ b/drivers/mfd/max77693.c
+@@ -106,6 +106,35 @@ static const struct regmap_config max77693_regmap_config = {
+       .max_register = MAX77693_PMIC_REG_END,
+ };
++#ifdef CONFIG_OF
++static struct of_device_id max77693_pmic_dt_match[] = {
++      { .compatible = "maxim,max77693", },
++      {},
++};
++
++static struct max77693_platform_data *max77693_i2c_parse_dt_data(struct device
++                                                              *dev)
++{
++      struct max77693_platform_data *pdata;
++      struct device_node *np = dev->of_node;
++
++      pdata = devm_kzalloc(dev, sizeof(struct max77693_platform_data),
++                           GFP_KERNEL);
++      if (!pdata)
++              return ERR_PTR(ENOMEM);
++
++      of_property_read_u32(np, "wakeup", &pdata->wakeup);
++
++      return pdata;
++}
++#else
++static struct max77693_platform_data *max77693_i2c_parse_dt_data(struct device
++                                                              *dev)
++{
++      return NULL;
++}
++#endif
++
+ static int max77693_i2c_probe(struct i2c_client *i2c,
+                             const struct i2c_device_id *id)
+ {
+@@ -114,6 +143,10 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
+       u8 reg_data;
+       int ret = 0;
++      if (i2c->dev.of_node)
++              pdata = i2c->dev.platform_data =
++                      max77693_i2c_parse_dt_data(&i2c->dev);
++
+       if (!pdata) {
+               dev_err(&i2c->dev, "No platform data found.\n");
+               return -EINVAL;
+@@ -240,6 +273,7 @@ static struct i2c_driver max77693_i2c_driver = {
+                  .name = "max77693",
+                  .owner = THIS_MODULE,
+                  .pm = &max77693_pm,
++                 .of_match_table = of_match_ptr(max77693_pmic_dt_match),
+       },
+       .probe = max77693_i2c_probe,
+       .remove = max77693_i2c_remove,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0189-power-max77693-Add-max77693-charger-dirver.patch b/patches.tizen/0189-power-max77693-Add-max77693-charger-dirver.patch
new file mode 100644 (file)
index 0000000..bea9212
--- /dev/null
@@ -0,0 +1,936 @@
+From afca7e3c520749e16a1ba0dce4045cf622195a50 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Tue, 2 Apr 2013 17:08:58 +0900
+Subject: [PATCH 0189/1302] power: max77693: Add max77693 charger dirver.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/power/Makefile                 |   2 +
+ drivers/power/max77693_charger.c       | 689 +++++++++++++++++++++++++++++++++
+ include/linux/mfd/max77693.h           |   8 +
+ include/linux/power/max77693_charger.h | 177 +++++++++
+ 4 files changed, 876 insertions(+)
+ create mode 100644 drivers/power/max77693_charger.c
+ create mode 100644 include/linux/power/max77693_charger.h
+
+diff --git a/drivers/power/Makefile b/drivers/power/Makefile
+index 653bf6c..a917c98 100644
+--- a/drivers/power/Makefile
++++ b/drivers/power/Makefile
+@@ -49,6 +49,8 @@ obj-$(CONFIG_CHARGER_GPIO)   += gpio-charger.o
+ obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o
+ obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o
+ obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o
++obj-$(CONFIG_CHARGER_MAX77693)        += max77693_charger.o
++obj-y                         += max77693_charger.o
+ obj-$(CONFIG_CHARGER_BQ2415X) += bq2415x_charger.o
+ obj-$(CONFIG_POWER_AVS)               += avs/
+ obj-$(CONFIG_CHARGER_SMB347)  += smb347-charger.o
+diff --git a/drivers/power/max77693_charger.c b/drivers/power/max77693_charger.c
+new file mode 100644
+index 0000000..340aec0
+--- /dev/null
++++ b/drivers/power/max77693_charger.c
+@@ -0,0 +1,689 @@
++/*
++ * max77693_charger.c
++ *
++ * Copyright (C) 2011 Samsung Electronics
++ * SangYoung Son <hello.son@samsung.com>
++ *
++ * Copyright (C) 2012 Samsung Electronics
++ * MyungJoo Ham <myungjoo.ham@samsung.com>
++ *
++ * Simplified hello.son's driver removing unnecessary features for
++ * charger-manager; supporting power-supply-class is the main role.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 and
++ * only version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * "Input current" in the original driver is controlled by regulator
++ * "CHARGER".
++ * "Charge current" in the original driver is controlled by regulator
++ * "CHARGER_CC".
++ */
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/err.h>
++#include <linux/i2c.h>
++#include <linux/delay.h>
++#include <linux/power_supply.h>
++#include <linux/gpio.h>
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/slab.h>
++#include <linux/mfd/max77693.h>
++#include <linux/mfd/max77693-private.h>
++#include <linux/power/charger-manager.h>
++#include <linux/extcon.h>
++#include <plat/gpio-cfg.h>
++
++/* MAX77693 Registers(defined @max77693-private.h) */
++
++/* MAX77693_CHG_REG_CHG_INT */
++#define MAX77693_BYP_I                        (1 << 0)
++#define MAX77693_THM_I                        (1 << 2)
++#define MAX77693_BAT_I                        (1 << 3)
++#define MAX77693_CHG_I                        (1 << 4)
++#define MAX77693_CHGIN_I              (1 << 6)
++
++/* MAX77693_CHG_REG_CHG_INT_MASK */
++#define MAX77693_BYP_IM                       (1 << 0)
++#define MAX77693_THM_IM                       (1 << 2)
++#define MAX77693_BAT_IM                       (1 << 3)
++#define MAX77693_CHG_IM                       (1 << 4)
++#define MAX77693_CHGIN_IM             (1 << 6)
++
++/* MAX77693_CHG_REG_CHG_INT_OK */
++#define MAX77693_BYP_OK                       0x01
++#define MAX77693_BYP_OK_SHIFT         0
++#define MAX77693_THM_OK                       0x04
++#define MAX77693_THM_OK_SHIFT         2
++#define MAX77693_BAT_OK                       0x08
++#define MAX77693_BAT_OK_SHIFT         3
++#define MAX77693_CHG_OK                       0x10
++#define MAX77693_CHG_OK_SHIFT         4
++#define MAX77693_CHGIN_OK             0x40
++#define MAX77693_CHGIN_OK_SHIFT               6
++#define MAX77693_DETBAT                       0x80
++#define MAX77693_DETBAT_SHIFT         7
++
++/* MAX77693_CHG_REG_CHG_DTLS_00 */
++#define MAX77693_THM_DTLS             0x07
++#define MAX77693_THM_DTLS_SHIFT               0
++#define MAX77693_CHGIN_DTLS           0x60
++#define MAX77693_CHGIN_DTLS_SHIFT     5
++
++/* MAX77693_CHG_REG_CHG_DTLS_01 */
++#define MAX77693_CHG_DTLS             0x0F
++#define MAX77693_CHG_DTLS_SHIFT               0
++#define MAX77693_BAT_DTLS             0x70
++#define MAX77693_BAT_DTLS_SHIFT               4
++
++/* MAX77693_CHG_REG_CHG_DTLS_02 */
++#define MAX77693_BYP_DTLS             0x0F
++#define MAX77693_BYP_DTLS_SHIFT               0
++#define MAX77693_BYP_DTLS0    0x1
++#define MAX77693_BYP_DTLS1    0x2
++#define MAX77693_BYP_DTLS2    0x4
++#define MAX77693_BYP_DTLS3    0x8
++
++/* MAX77693_CHG_REG_CHG_CNFG_00 */
++#define MAX77693_MODE_DEFAULT 0x04
++#define MAX77693_MODE_CHGR    0x01
++#define MAX77693_MODE_OTG     0x02
++#define MAX77693_MODE_BUCK    0x04
++
++/* MAX77693_CHG_REG_CHG_CNFG_02 */
++#define MAX77693_CHG_CC               0x3F
++
++/* MAX77693_CHG_REG_CHG_CNFG_04 */
++#define MAX77693_CHG_MINVSYS_MASK     0xE0
++#define MAX77693_CHG_MINVSYS_SHIFT    5
++#define MAX77693_CHG_MINVSYS_3_6V     0x06
++#define MAX77693_CHG_CV_PRM_MASK              0x1F
++#define MAX77693_CHG_CV_PRM_SHIFT             0
++#define MAX77693_CHG_CV_PRM_4_20V             0x16
++#define MAX77693_CHG_CV_PRM_4_35V             0x1D
++#define MAX77693_CHG_CV_PRM_4_40V             0x1F
++
++/* MAX77693_CHG_REG_CHG_CNFG_06 */
++#define MAX77693_CHG_CHGPROT          0x0C
++#define MAX77693_CHG_CHGPROT_SHIFT    2
++#define MAX77693_CHG_CHGPROT_UNLOCK   0x03
++
++/* MAX77693_CHG_REG_CHG_CNFG_09 */
++#define MAX77693_CHG_CHGIN_LIM        0x7F
++
++/* MAX77693_MUIC_REG_CDETCTRL1 */
++#define MAX77693_CHGTYPMAN            0x02
++#define MAX77693_CHGTYPMAN_SHIFT      1
++
++/* MAX77693_MUIC_REG_STATUS2 */
++#define MAX77693_VBVOLT                       0x40
++#define MAX77693_VBVOLT_SHIFT         6
++#define MAX77693_DXOVP                        0x20
++#define MAX77693_DXOVP_SHIFT          5
++#define MAX77693_CHGDETRUN            0x08
++#define MAX77693_CHGDETRUN_SHIFT      3
++#define MAX77693_CHGTYPE              0x07
++#define MAX77693_CHGTYPE_SHIFT                0
++
++/* irq */
++#define IRQ_DEBOUNCE_TIME     20      /* msec */
++
++/* charger unlock */
++#define CHG_UNLOCK_RETRY      10
++#define CHG_UNLOCK_DELAY      100
++
++/* power stabe guarantee */
++#define STABLE_POWER_DELAY    500
++
++/* charger type detection */
++#define DET_ERR_RETRY 5
++#define DET_ERR_DELAY 200
++
++/* soft charging */
++#define SOFT_CHG_START_CURR   100     /* mA */
++#define SOFT_CHG_START_DUR    100     /* ms */
++#define SOFT_CHG_CURR_STEP    100     /* mA */
++#define SOFT_CHG_STEP_DUR     20      /* ms */
++
++/* soft regulation */
++#define SW_REG_CURR_STEP_MA   100
++#define SW_REG_START_DELAY    500
++#define SW_REG_STEP_DELAY     100
++
++struct max77693_charger_data {
++      struct max77693_dev     *max77693;
++
++      struct power_supply     charger;
++
++      /* mutex */
++      struct mutex irq_lock;
++      struct mutex ops_lock;
++
++      unsigned int    charging_state;
++      unsigned int    charging_type;
++      unsigned int    battery_state;
++      unsigned int    battery_present;
++      unsigned int    cable_type;
++      unsigned int    charging_current;
++      unsigned int    vbus_state;
++
++      int             irq_bypass;
++      int             irq_therm;
++      int             irq_battery;
++      int             irq_charge;
++      int             irq_chargin;
++
++      /* software regulation */
++      bool            soft_reg_state;
++      int             soft_reg_current;
++      bool            soft_reg_ing;
++
++      /* unsufficient power */
++      bool            reg_loop_deted;
++
++      struct max77693_charger_platform_data   *charger_pdata;
++
++      int             irq;
++      u8              irq_reg;
++      int             irq_cnt;
++};
++
++static int max77693_get_battery_present(struct max77693_charger_data *chg_data)
++{
++      struct regmap *rmap = chg_data->max77693->regmap;
++      u8 reg_data;
++
++      max77693_read_reg(rmap, MAX77693_CHG_REG_CHG_INT_OK, &reg_data);
++      reg_data = ((reg_data & MAX77693_DETBAT) >> MAX77693_DETBAT_SHIFT);
++
++      return !reg_data;
++}
++
++static int max77693_get_vbus_state(struct max77693_charger_data *chg_data)
++{
++      struct regmap *rmap = chg_data->max77693->regmap;
++      int state;
++      u8 reg_data;
++
++      max77693_read_reg(rmap, MAX77693_CHG_REG_CHG_DETAILS_00, &reg_data);
++      reg_data = ((reg_data & MAX77693_CHGIN_DTLS) >>
++                              MAX77693_CHGIN_DTLS_SHIFT);
++
++      switch (reg_data) {
++      case 0x00:
++              /* V chgin < UVLO */
++              state = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
++              break;
++      case 0x01:
++              /* V chgin < V batt + minimum threshold */
++              state = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
++              break;
++      case 0x02:
++              /* V chgin > OVLO */
++              state = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
++              break;
++      case 0x03:
++              state = POWER_SUPPLY_HEALTH_GOOD;
++              break;
++      default:
++              state = POWER_SUPPLY_HEALTH_UNKNOWN;
++              break;
++      }
++
++      chg_data->vbus_state = state;
++      return state;
++}
++
++static int max77693_get_charger_type(struct max77693_charger_data *chg_data)
++{
++      struct regmap *rmap = chg_data->max77693->regmap;
++      int state;
++      u8 reg_data;
++
++      max77693_read_reg(rmap, MAX77693_CHG_REG_CHG_DETAILS_01, &reg_data);
++      reg_data = ((reg_data & MAX77693_CHG_DTLS) >> MAX77693_CHG_DTLS_SHIFT);
++
++      switch (reg_data) {
++      case 0x0:
++              state = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
++              break;
++      case 0x1:
++      case 0x2:
++      case 0x3:
++              state = POWER_SUPPLY_CHARGE_TYPE_FAST;
++              break;
++      case 0x4 ... 0x8:
++      case 0xA:
++      case 0xB:
++              state = POWER_SUPPLY_CHARGE_TYPE_NONE;
++              break;
++      default:
++              state = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
++              break;
++      }
++
++      chg_data->charging_type = state;
++      return state;
++}
++
++static int max77693_get_charger_state(struct max77693_charger_data *chg_data)
++{
++      struct regmap *rmap = chg_data->max77693->regmap;
++      int state;
++      u8 reg_data;
++
++      max77693_read_reg(rmap, MAX77693_CHG_REG_CHG_DETAILS_01, &reg_data);
++      reg_data = ((reg_data & MAX77693_CHG_DTLS) >> MAX77693_CHG_DTLS_SHIFT);
++      switch (reg_data) {
++      case 0x0:
++      case 0x1:
++      case 0x2:
++              /*
++               * Note that whether to consider 0x3 as CHARGING or FULL
++               * is arguable.
++               * According to TN's standard 0x3 (TOP-OFF) should be
++               * "FULL".
++               * According to the strict semantics of "FULL", this is
++               * "CHARGING".
++               */
++      case 0x3:
++              state = POWER_SUPPLY_STATUS_CHARGING;
++              break;
++      case 0x4:
++              state = POWER_SUPPLY_STATUS_FULL;
++              break;
++      case 0x5:
++      case 0x6:
++      case 0x7:
++              state = POWER_SUPPLY_STATUS_NOT_CHARGING;
++              break;
++      case 0x8:
++      case 0xA:
++      case 0xB:
++              state = POWER_SUPPLY_STATUS_DISCHARGING;
++              break;
++      default:
++              state = POWER_SUPPLY_STATUS_UNKNOWN;
++              break;
++      }
++
++      chg_data->charging_state = state;
++      return state;
++}
++
++static int max77693_get_online(struct max77693_charger_data *chg_data)
++{
++      struct regmap *rmap = chg_data->max77693->regmap;
++      u8 reg_data;
++
++      max77693_read_reg(rmap, MAX77693_CHG_REG_CHG_INT_OK, &reg_data);
++      return !!(reg_data & MAX77693_CHGIN_I);
++}
++
++static int max77693_get_battery_health(struct max77693_charger_data *chg_data)
++{
++      struct regmap *rmap = chg_data->max77693->regmap;
++      int state;
++      bool low_bat = false;
++      u8 reg_data;
++
++      max77693_read_reg(rmap, MAX77693_CHG_REG_CHG_DETAILS_01, &reg_data);
++      reg_data = ((reg_data & MAX77693_BAT_DTLS) >> MAX77693_BAT_DTLS_SHIFT);
++      switch (reg_data) {
++      case 0x00: /* NO BATT */
++              state = POWER_SUPPLY_HEALTH_DEAD;
++              break;
++      case 0x01: /* V Batt < Prequalification */
++              low_bat = true;
++              state = POWER_SUPPLY_HEALTH_GOOD;
++              break;
++      case 0x02: /* Takes too much time to charge. Damaged battery? */
++              state = POWER_SUPPLY_HEALTH_DEAD;
++              break;
++      case 0x03: /* V Batt > Good > Prequal */
++              state = POWER_SUPPLY_HEALTH_GOOD;
++              break;
++      case 0x04: /* Good > V Batt > Prequal. Not good enough */
++              low_bat = true;
++              state = POWER_SUPPLY_HEALTH_GOOD;
++              break;
++      case 0x05: /* V Batt > Overvoltage */
++              state = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
++              break;
++      case 0x06: /* I Batt > Overcurrent */
++              state = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
++      default:
++              state = POWER_SUPPLY_HEALTH_UNKNOWN;
++              break;
++      }
++
++      if (state == POWER_SUPPLY_HEALTH_GOOD)
++              state = max77693_get_vbus_state(chg_data);
++
++      /* Battery is healthy and fully-charged, but has low voltage? */
++      if (state == POWER_SUPPLY_HEALTH_GOOD && low_bat &&
++          max77693_get_charger_state(chg_data) == POWER_SUPPLY_STATUS_FULL)
++              state = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
++
++      chg_data->battery_state = state;
++      return state;
++}
++
++static bool max77693_charger_unlock(struct max77693_charger_data *chg_data)
++{
++      struct regmap *rmap = chg_data->max77693->regmap;
++      u8 reg_data;
++      u8 chgprot;
++      int retry_cnt = 0;
++      bool need_init = false;
++      pr_debug("%s\n", __func__);
++
++      max77693_read_reg(rmap, MAX77693_CHG_REG_CHG_CNFG_06, &reg_data);
++      chgprot = ((reg_data & MAX77693_CHG_CHGPROT) >>
++                              MAX77693_CHG_CHGPROT_SHIFT);
++
++      if (chgprot == MAX77693_CHG_CHGPROT_UNLOCK) {
++              pr_debug("%s: unlocked state, return\n", __func__);
++              need_init = false;
++              goto unlock_finish;
++      }
++
++      do {
++              max77693_write_reg(rmap, MAX77693_CHG_REG_CHG_CNFG_06,
++                                      (MAX77693_CHG_CHGPROT_UNLOCK <<
++                                      MAX77693_CHG_CHGPROT_SHIFT));
++
++              max77693_read_reg(rmap, MAX77693_CHG_REG_CHG_CNFG_06, &reg_data);
++              chgprot = ((reg_data & MAX77693_CHG_CHGPROT) >>
++                                      MAX77693_CHG_CHGPROT_SHIFT);
++
++              if (chgprot != MAX77693_CHG_CHGPROT_UNLOCK) {
++                      pr_err("%s: unlock err, chgprot(0x%x), retry(%d)\n",
++                                      __func__, chgprot, retry_cnt);
++                      msleep(CHG_UNLOCK_DELAY);
++              } else {
++                      pr_info("%s: unlock success, chgprot(0x%x)\n",
++                                                      __func__, chgprot);
++                      need_init = true;
++                      break;
++              }
++      } while ((chgprot != MAX77693_CHG_CHGPROT_UNLOCK) &&
++                              (++retry_cnt < CHG_UNLOCK_RETRY));
++
++unlock_finish:
++      return need_init;
++}
++
++static void max77693_charger_reg_init(struct max77693_charger_data *chg_data)
++{
++      struct regmap *rmap = chg_data->max77693->regmap;
++      u8 reg_data;
++
++      /*
++       * fast charge timer 10hrs
++       * restart threshold disable
++       * pre-qual charge enable(default)
++       */
++      reg_data = (0x04 << 0) | (0x03 << 4);
++      max77693_write_reg(rmap, MAX77693_CHG_REG_CHG_CNFG_01, reg_data);
++
++      /*
++       * charge current 466mA(default)
++       * otg current limit 900mA
++       */
++      reg_data = (1 << 7);
++      max77693_write_reg(rmap, MAX77693_CHG_REG_CHG_CNFG_02, reg_data);
++
++      /*
++       * top off current 100mA
++       * top off timer 0min
++       */
++      reg_data = (0x00 << 0); /* 100mA */
++
++      reg_data |= (0x00 << 3);
++      max77693_write_reg(rmap, MAX77693_CHG_REG_CHG_CNFG_03, reg_data);
++
++      /*
++       * cv voltage 4.2V or 4.35V
++       * MINVSYS 3.6V(default)
++       */
++      reg_data &= (~MAX77693_CHG_MINVSYS_MASK);
++      reg_data |= (MAX77693_CHG_MINVSYS_3_6V << MAX77693_CHG_MINVSYS_SHIFT);
++      reg_data &= (~MAX77693_CHG_CV_PRM_MASK);
++#if defined(CONFIG_MACH_M0)
++      if ((system_rev != 3) && (system_rev >= 1))
++              reg_data |= (MAX77693_CHG_CV_PRM_4_35V << 0);
++      else
++              reg_data |= (MAX77693_CHG_CV_PRM_4_20V << 0);
++#else /* C1, C2, M3, T0, ... */
++              reg_data |= (MAX77693_CHG_CV_PRM_4_35V << 0);
++#endif
++
++      /*
++       * For GC1 Model,  MINVSYS is 3.4V.
++       *  For GC1 Model  PRMV( Primary Charge Regn. Voltage) = 4.2V.
++       * Actual expected regulated voltage needs to be 4.2V but due to
++       * internal resistance and circuit deviation we might have to set the
++       * benchmark a bit higher sometimes. (4.225V now)
++       */
++#if defined(CONFIG_MACH_GC1)
++      reg_data &= (~MAX77693_CHG_CV_PRM_MASK);
++      reg_data |= (0x17 << MAX77693_CHG_CV_PRM_SHIFT);
++      reg_data &= (~MAX77693_CHG_MINVSYS_MASK);
++      reg_data |= (0x4 << MAX77693_CHG_MINVSYS_SHIFT);
++#endif
++      max77693_write_reg(rmap, MAX77693_CHG_REG_CHG_CNFG_04, reg_data);
++
++      /* VBYPSET 5V */
++      reg_data = 0x50;
++      max77693_write_reg(rmap, MAX77693_CHG_REG_CHG_CNFG_11, reg_data);
++}
++
++/* Support property from charger */
++static enum power_supply_property max77693_charger_props[] = {
++      POWER_SUPPLY_PROP_STATUS,
++      POWER_SUPPLY_PROP_CHARGE_TYPE,
++      POWER_SUPPLY_PROP_HEALTH,
++      POWER_SUPPLY_PROP_PRESENT,
++      POWER_SUPPLY_PROP_ONLINE,
++      POWER_SUPPLY_PROP_MODEL_NAME,
++      POWER_SUPPLY_PROP_MANUFACTURER,
++};
++
++static const char *model_name = "MAX77693";
++static const char *manufacturer = "Maxim Semiconductor";
++static int max77693_charger_get_property(struct power_supply *psy,
++                          enum power_supply_property psp,
++                          union power_supply_propval *val)
++{
++      struct max77693_charger_data *chg_data = container_of(psy,
++                                                struct max77693_charger_data,
++                                                charger);
++      int ret = 0;
++
++      switch (psp) {
++      case POWER_SUPPLY_PROP_STATUS:
++              val->intval = max77693_get_charger_state(chg_data);
++              break;
++      case POWER_SUPPLY_PROP_CHARGE_TYPE:
++              val->intval = max77693_get_charger_type(chg_data);
++              break;
++      case POWER_SUPPLY_PROP_HEALTH:
++              val->intval = max77693_get_battery_health(chg_data);
++              break;
++      case POWER_SUPPLY_PROP_PRESENT:
++              val->intval = max77693_get_battery_present(chg_data);
++              break;
++      case POWER_SUPPLY_PROP_ONLINE:
++              val->intval = max77693_get_online(chg_data);
++              break;
++      case POWER_SUPPLY_PROP_MODEL_NAME:
++              val->strval = model_name;
++              break;
++      case POWER_SUPPLY_PROP_MANUFACTURER:
++              val->strval = manufacturer;
++              break;
++      default:
++              return -EINVAL;
++      }
++      /*
++       * TODO: support chaging type...
++              val->intval = max77693_get_cable_type(chg_data);
++      */
++
++      return ret;
++}
++
++static void max77693_charger_initialize(struct max77693_charger_data *chg_data)
++{
++      struct max77693_charger_platform_data *charger_pdata =
++                                      chg_data->charger_pdata;
++      struct regmap *rmap = chg_data->max77693->regmap;
++      int i;
++
++      for (i = 0; i < charger_pdata->num_init_data; i++)
++              max77693_write_reg(rmap, charger_pdata->init_data[i].addr,
++                              charger_pdata->init_data[i].data);
++}
++
++static int max77693_charger_probe(struct platform_device *pdev)
++{
++      struct max77693_charger_data *chg_data;
++      struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent);
++      struct max77693_platform_data *pdata = dev_get_platdata(max77693->dev);
++      int ret;
++
++      pr_info("%s: charger init start\n", __func__);
++
++      chg_data = devm_kzalloc(&pdev->dev, sizeof(struct max77693_charger_data), GFP_KERNEL);
++      if (!chg_data)
++              return -ENOMEM;
++
++      platform_set_drvdata(pdev, chg_data);
++      chg_data->max77693 = max77693;
++
++      mutex_init(&chg_data->irq_lock);
++      mutex_init(&chg_data->ops_lock);
++
++      /* unlock charger setting protect */
++      max77693_charger_unlock(chg_data);
++
++      chg_data->charger_pdata = pdata->charger_data;
++      if (pdata->charger_data && pdata->charger_data->init_data)
++              max77693_charger_initialize(chg_data);
++      else
++              max77693_charger_reg_init(chg_data);
++
++      chg_data->charger.name = "max77693-charger",
++      chg_data->charger.type = POWER_SUPPLY_TYPE_BATTERY,
++      chg_data->charger.properties = max77693_charger_props,
++      chg_data->charger.num_properties = ARRAY_SIZE(max77693_charger_props),
++      chg_data->charger.get_property = max77693_charger_get_property,
++
++      ret = power_supply_register(&pdev->dev, &chg_data->charger);
++      if (ret) {
++              pr_err("%s: failed: power supply register\n", __func__);
++              goto err_kfree;
++      }
++
++      return 0;
++
++err_kfree:
++      mutex_destroy(&chg_data->ops_lock);
++      mutex_destroy(&chg_data->irq_lock);
++      return ret;
++}
++
++static int max77693_charger_remove(struct platform_device *pdev)
++{
++      struct max77693_charger_data *chg_data = platform_get_drvdata(pdev);
++
++      mutex_destroy(&chg_data->ops_lock);
++      mutex_destroy(&chg_data->irq_lock);
++
++      power_supply_unregister(&chg_data->charger);
++
++      return 0;
++}
++
++/*
++ * WORKAROUND: (test and remove w/ later MAX77693 chips)
++ * TODO: read chip revision and bypass this code if revision > ?
++ * Several interrupts occur while charging through TA.
++ * Suspended state cannot be maintained by the interrupts.
++ */
++static u8 saved_int_mask;
++static int max77693_charger_suspend(struct device *dev)
++{
++      struct max77693_dev *max77693 = dev_get_drvdata(dev->parent);
++      u8 int_mask;
++
++      /* Save the masking value */
++      max77693_read_reg(max77693->regmap,
++                      MAX77693_CHG_REG_CHG_INT_MASK,
++                      &saved_int_mask);
++
++      /* Mask all the interrupts related to charger */
++      int_mask = 0xff;
++      max77693_write_reg(max77693->regmap,
++                      MAX77693_CHG_REG_CHG_INT_MASK,
++                      int_mask);
++      return 0;
++}
++
++static int max77693_charger_resume(struct device *dev)
++{
++      struct max77693_dev *max77693 = dev_get_drvdata(dev->parent);
++
++      /* Restore the saved masking value */
++      max77693_write_reg(max77693->regmap,
++                      MAX77693_CHG_REG_CHG_INT_MASK,
++                      saved_int_mask);
++      return 0;
++}
++
++static SIMPLE_DEV_PM_OPS(max77693_charger_pm_ops, max77693_charger_suspend,
++                      max77693_charger_resume);
++
++#ifdef CONFIG_OF
++static struct of_device_id max77693_charger_of_match[] __initconst = {
++      { .compatible = "samsung,max77693-charger", },
++      { },
++};
++#endif
++
++static struct platform_driver max77693_charger_driver = {
++      .driver = {
++              .owner  = THIS_MODULE,
++              .name   = "max77693-charger",
++              .pm     = &max77693_charger_pm_ops,
++              .of_match_table = of_match_ptr(max77693_charger_of_match),
++      },
++      .probe          = max77693_charger_probe,
++      .remove         = max77693_charger_remove,
++};
++
++static int __init max77693_charger_init(void)
++{
++      return platform_driver_register(&max77693_charger_driver);
++}
++
++static void __exit max77693_charger_exit(void)
++{
++      platform_driver_unregister(&max77693_charger_driver);
++}
++
++module_init(max77693_charger_init);
++module_exit(max77693_charger_exit);
++
++MODULE_AUTHOR("SangYoung Son <hello.son@samsung.com>");
++MODULE_DESCRIPTION("max77693 Charger driver");
++MODULE_LICENSE("GPL");
+diff --git a/include/linux/mfd/max77693.h b/include/linux/mfd/max77693.h
+index 77d8207..f42ae8a 100644
+--- a/include/linux/mfd/max77693.h
++++ b/include/linux/mfd/max77693.h
+@@ -54,6 +54,11 @@ struct max77693_reg_data {
+       u8 data;
+ };
++struct max77693_charger_platform_data {
++      struct max77693_reg_data *init_data;
++      int num_init_data;
++};
++
+ struct max77693_muic_platform_data {
+       struct max77693_reg_data *init_data;
+       int num_init_data;
+@@ -78,6 +83,9 @@ struct max77693_platform_data {
+       struct max77693_regulator_data *regulators;
+       int num_regulators;
++      /* charger data */
++      struct max77693_charger_platform_data *charger_data;
++
+       /* muic data */
+       struct max77693_muic_platform_data *muic_data;
+ };
+diff --git a/include/linux/power/max77693_charger.h b/include/linux/power/max77693_charger.h
+new file mode 100644
+index 0000000..0ad2f39
+--- /dev/null
++++ b/include/linux/power/max77693_charger.h
+@@ -0,0 +1,177 @@
++/*
++ * max77693_charger.h
++ * Samsung max77693 Charger Header
++ *
++ * Copyright (C) 2012 Samsung Electronics, Inc.
++ *
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++#ifndef __MAX77693_CHARGER_H
++#define __MAX77693_CHARGER_H __FILE__
++#include <linux/mfd/core.h>
++#include <linux/mfd/max77693_sec.h>
++#include <linux/mfd/max77693-private_sec.h>
++#include <linux/regulator/machine.h>
++
++#define ENABLE 1
++#define DISABLE 0
++
++/* macro */
++#define MAX(x, y)     ((x) > (y) ? (x) : (y))
++#define MIN(x, y)     ((x) < (y) ? (x) : (y))
++#define ABS(x)                ((x) < 0 ? (-1 * (x)) : (x))
++/*
++ * Use for battery
++ */
++#define OFF_CURR      0       /* charger off current */
++#define KEEP_CURR     -1      /* keep previous current */
++
++/* MAX77693_CHG_REG_CHG_INT */
++#define MAX77693_BYP_I                  (1 << 0)
++#if defined(CONFIG_CHARGER_MAX77803)
++#define MAX77693_BATP_I                       (1 << 2)
++#else
++#define MAX77693_THM_I                  (1 << 2)
++#endif
++#define MAX77693_BAT_I                  (1 << 3)
++#define MAX77693_CHG_I                  (1 << 4)
++#if defined(CONFIG_CHARGER_MAX77803)
++#define MAX77693_WCIN_I                       (1 << 5)
++#endif
++#define MAX77693_CHGIN_I                (1 << 6)
++
++/* MAX77693_CHG_REG_CHG_INT_MASK */
++#define MAX77693_BYP_IM                 (1 << 0)
++#define MAX77693_THM_IM                 (1 << 2)
++#define MAX77693_BAT_IM                 (1 << 3)
++#define MAX77693_CHG_IM                 (1 << 4)
++#if defined(CONFIG_CHARGER_MAX77803)
++#define MAX77693_WCIN_IM              (1 << 5)
++#endif
++#define MAX77693_CHGIN_IM               (1 << 6)
++
++/* MAX77693_CHG_REG_CHG_INT_OK */
++#define MAX77693_BYP_OK                 0x01
++#define MAX77693_BYP_OK_SHIFT           0
++#if defined(CONFIG_CHARGER_MAX77803)
++#define MAX77693_BATP_OK              0x04
++#define MAX77693_BATP_OK_SHIFT                2
++#else
++#define MAX77693_THM_OK                 0x04
++#define MAX77693_THM_OK_SHIFT           2
++#endif
++#define MAX77693_BAT_OK                 0x08
++#define MAX77693_BAT_OK_SHIFT           3
++#define MAX77693_CHG_OK                 0x10
++#define MAX77693_CHG_OK_SHIFT           4
++#if defined(CONFIG_CHARGER_MAX77803)
++#define MAX77693_WCIN_OK              0x20
++#define MAX77693_WCIN_OK_SHIFT                5
++#endif
++#define MAX77693_CHGIN_OK               0x40
++#define MAX77693_CHGIN_OK_SHIFT         6
++#define MAX77693_DETBAT                 0x80
++#define MAX77693_DETBAT_SHIFT           7
++
++/* MAX77693_CHG_REG_CHG_DTLS_00 */
++#if defined(CONFIG_CHARGER_MAX77803)
++#define MAX77693_BATP_DTLS            0x01
++#define MAX77693_BATP_DTLS_SHIFT      0
++#else
++#define MAX77693_THM_DTLS               0x07
++#define MAX77693_THM_DTLS_SHIFT         0
++#endif
++#if defined(CONFIG_CHARGER_MAX77803)
++#define MAX77693_WCIN_DTLS            0x18
++#define MAX77693_WCIN_DTLS_SHIFT      3
++#endif
++#define MAX77693_CHGIN_DTLS             0x60
++#define MAX77693_CHGIN_DTLS_SHIFT       5
++
++/* MAX77693_CHG_REG_CHG_DTLS_01 */
++#define MAX77693_CHG_DTLS               0x0F
++#define MAX77693_CHG_DTLS_SHIFT         0
++#define MAX77693_BAT_DTLS               0x70
++#define MAX77693_BAT_DTLS_SHIFT         4
++
++/* MAX77693_CHG_REG_CHG_DTLS_02 */
++#define MAX77693_BYP_DTLS               0x0F
++#define MAX77693_BYP_DTLS_SHIFT         0
++#define MAX77693_BYP_DTLS0      0x1
++#define MAX77693_BYP_DTLS1      0x2
++#define MAX77693_BYP_DTLS2      0x4
++#define MAX77693_BYP_DTLS3      0x8
++
++/* MAX77693_CHG_REG_CHG_CNFG_00 */
++#define MAX77693_MODE_DEFAULT   0x04
++#define MAX77693_MODE_CHGR      0x01
++#define MAX77693_MODE_OTG       0x02
++#define MAX77693_MODE_BUCK      0x04
++
++/* MAX77693_CHG_REG_CHG_CNFG_02 */
++#define MAX77693_CHG_CC         0x3F
++
++/* MAX77693_CHG_REG_CHG_CNFG_03 */
++#define MAX77693_CHG_TO_ITH           0x07
++
++/* MAX77693_CHG_REG_CHG_CNFG_04 */
++#define MAX77693_CHG_MINVSYS_MASK       0xE0
++#define MAX77693_CHG_MINVSYS_SHIFT      5
++#define MAX77693_CHG_PRM_MASK           0x1F
++#define MAX77693_CHG_PRM_SHIFT          0
++
++/* MAX77693_CHG_REG_CHG_CNFG_09 */
++#define MAX77693_CHG_CHGIN_LIM  0x7F
++
++/* MAX77693_CHG_REG_CHG_CNFG_12 */
++#define MAX77693_CHG_WCINSEL          0x40
++
++/* MAX77693_MUIC_REG_CDETCTRL1 */
++#define MAX77693_CHGTYPMAN              0x02
++#define MAX77693_CHGTYPMAN_SHIFT        1
++
++/* MAX77693_MUIC_REG_STATUS2 */
++#define MAX77693_VBVOLT                 0x40
++#define MAX77693_VBVOLT_SHIFT           6
++#define MAX77693_CHGDETRUN              0x08
++#define MAX77693_CHGDETRUN_SHIFT        3
++#define MAX77693_CHGTYPE                0x07
++#define MAX77693_CHGTYPE_SHIFT          0
++
++/* irq */
++#define IRQ_DEBOUNCE_TIME       20      /* msec */
++
++/* charger type detection */
++#define DET_ERR_RETRY   5
++#define DET_ERR_DELAY   200
++
++/* soft charging */
++#define SOFT_CHG_START_CURR     100     /* mA */
++#define SOFT_CHG_START_DUR      100     /* ms */
++#define SOFT_CHG_CURR_STEP      100     /* mA */
++#define SOFT_CHG_STEP_DUR       20      /* ms */
++
++#define DEFAULT_AC_CURRENT    1600    /* mA */
++#define DEFAULT_USB_CURRENT   500     /* mA */
++
++#ifndef CONFIG_MACH_SLP_ADONIS
++enum {
++      POWER_SUPPLY_VBUS_UNKNOWN = 0,
++      POWER_SUPPLY_VBUS_UVLO,
++      POWER_SUPPLY_VBUS_WEAK,
++      POWER_SUPPLY_VBUS_OVLO,
++      POWER_SUPPLY_VBUS_GOOD,
++};
++#endif
++
++extern sec_battery_platform_data_t sec_battery_pdata;
++#endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0190-regulator-max77693-Support-to-parse-data-from-device.patch b/patches.tizen/0190-regulator-max77693-Support-to-parse-data-from-device.patch
new file mode 100644 (file)
index 0000000..5b67542
--- /dev/null
@@ -0,0 +1,108 @@
+From dbe528492fe2349dc092258a87261b3423ec31b5 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Fri, 5 Apr 2013 15:48:47 +0900
+Subject: [PATCH 0190/1302] regulator: max77693: Support to parse data from
+ device tree
+
+This patch supports max77693 regulator driver to get a initial
+data from device tree.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/regulator/max77693.c | 58 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 58 insertions(+)
+
+diff --git a/drivers/regulator/max77693.c b/drivers/regulator/max77693.c
+index 0720ea8..60842a8 100644
+--- a/drivers/regulator/max77693.c
++++ b/drivers/regulator/max77693.c
+@@ -33,6 +33,7 @@
+ #include <linux/regulator/machine.h>
+ #include <linux/mfd/max77693.h>
+ #include <linux/mfd/max77693-private.h>
++#include <linux/regulator/of_regulator.h>
+ struct max77693_data {
+       struct device *dev;
+@@ -669,7 +670,57 @@ static struct regulator_desc regulators[] = {
+               .owner = THIS_MODULE,
+       },
+ };
++#ifdef CONFIG_OF
++static int max77693_pmic_dt_parse_pdata(struct platform_device *pdev,
++                                      struct max77693_platform_data *pdata)
++{
++      struct max77693_dev *iodev = dev_get_drvdata(pdev->dev.parent);
++      struct device_node *np;
++      struct max77693_regulator_data *rdata;
++      struct of_regulator_match rmatch;
++      int i, ret, cnt = 0;
++
++      np = of_find_node_by_name(iodev->dev->of_node, "regulators");
++      if (!np)
++              return -EINVAL;
++
++      of_property_read_u32(np, "number-of-regulators", &pdata->num_regulators);
++
++      /* Keep going whether the number of regulators prdefined or not*/
++      if (!pdata->num_regulators) {
++              dev_err(&pdev->dev,
++                      "failed to get the number of regulators supported\n");
++              pdata->num_regulators = ARRAY_SIZE(regulators);
++      }
++
++      rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) *
++                           pdata->num_regulators, GFP_KERNEL);
++      if (!rdata)
++              return -ENOMEM;
++
++      for (i = 0; i < pdata->num_regulators; i++) {
++              rmatch.name = regulators[i].name;
++              ret = of_regulator_match(&pdev->dev, np, &rmatch, 1);
++              if (ret == 1)
++                      rdata[cnt++].id = regulators[i].id;
++              else
++                      continue;
++              rdata[i].initdata = rmatch.init_data;
++              rdata[i].of_node = rmatch.of_node;
++      }
++
++      pdata->regulators = rdata;
++      pdata->num_regulators = cnt;
++      return 0;
++}
++#else
++static int max77693_pmic_dt_parse_pdata(struct platform_device *pdev,
++                                      struct max77693_platform_data *pdata)
++{
++      return 0;
++}
++#endif
+ static int max77693_pmic_probe(struct platform_device *pdev)
+ {
+       struct max77693_dev *iodev = dev_get_drvdata(pdev->dev.parent);
+@@ -679,12 +730,19 @@ static int max77693_pmic_probe(struct platform_device *pdev)
+       struct regulator_config config = {};
+       dev_info(&pdev->dev, "%s\n", __func__);
++
+       if (!pdata) {
+               pr_info("[%s:%d] !pdata\n", __FILE__, __LINE__);
+               dev_err(pdev->dev.parent, "No platform init data supplied.\n");
+               return -ENODEV;
+       }
++      if (iodev->dev->of_node) {
++              ret = max77693_pmic_dt_parse_pdata(pdev, pdata);
++              if (ret)
++                      return ret;
++      }
++
+       max77693 = devm_kzalloc(&pdev->dev, sizeof(struct max77693_data),
+                               GFP_KERNEL);
+       if (!max77693) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0191-mfd-max77686-Fix-NULL-pointer-error-of-max77686-plat.patch b/patches.tizen/0191-mfd-max77686-Fix-NULL-pointer-error-of-max77686-plat.patch
new file mode 100644 (file)
index 0000000..b673002
--- /dev/null
@@ -0,0 +1,35 @@
+From 9f18b39593f9ed17e5ad75410de039bf416646ea Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Fri, 5 Apr 2013 15:55:47 +0900
+Subject: [PATCH 0191/1302] mfd: max77686: Fix NULL pointer error of max77686
+ platform data.
+
+If max77686 mfd driver gets the initial data from device tree,
+dev->plat_data might be NULL. So, when sub devices want to get
+parent platform data, it can get only NULL pointer even parent
+mfd driver probed completely. So we need to re-initialize
+dev->plat_data at end of parsing device tree.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mfd/max77686.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c
+index 1cbb176..91c81cd 100644
+--- a/drivers/mfd/max77686.c
++++ b/drivers/mfd/max77686.c
+@@ -81,7 +81,8 @@ static int max77686_i2c_probe(struct i2c_client *i2c,
+       int ret = 0;
+       if (i2c->dev.of_node)
+-              pdata = max77686_i2c_parse_dt_pdata(&i2c->dev);
++              pdata = i2c->dev.platform_data =
++                      max77686_i2c_parse_dt_pdata(&i2c->dev);
+       if (!pdata) {
+               ret = -EIO;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0192-power-max77693-Add-kernel-configuation-of-Max77693-c.patch b/patches.tizen/0192-power-max77693-Add-kernel-configuation-of-Max77693-c.patch
new file mode 100644 (file)
index 0000000..ff8f15b
--- /dev/null
@@ -0,0 +1,49 @@
+From 2931c0cbbae766b5153c3b36197c337a0bc0866c Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Fri, 5 Apr 2013 18:01:53 +0900
+Subject: [PATCH 0192/1302] power: max77693: Add kernel configuation of
+ Max77693 charger
+
+The patch 'power: max77693: Add max77693 charger driver.'
+omitted CHARGER_MAX77693 kerenel configuration.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/power/Kconfig  | 7 +++++++
+ drivers/power/Makefile | 1 -
+ 2 files changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
+index 7b8979c..164a146 100644
+--- a/drivers/power/Kconfig
++++ b/drivers/power/Kconfig
+@@ -324,6 +324,13 @@ config CHARGER_MAX8998
+         Say Y to enable support for the battery charger control sysfs and
+         platform data of MAX8998/LP3974 PMICs.
++config CHARGER_MAX77693
++      tristate "Maxim MAX77693 PMIC battery charger driver"
++      depends on MFD_MAX77693 && REGULATOR_MAX77693
++      help
++        Say Y to enable support for the battery charger control sysfs and
++        platform data of MAX77693 PMICs.
++
+ config CHARGER_BQ2415X
+       tristate "TI BQ2415x battery charger driver"
+       depends on I2C
+diff --git a/drivers/power/Makefile b/drivers/power/Makefile
+index a917c98..ff4d1d3 100644
+--- a/drivers/power/Makefile
++++ b/drivers/power/Makefile
+@@ -50,7 +50,6 @@ obj-$(CONFIG_CHARGER_MANAGER)        += charger-manager.o
+ obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o
+ obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o
+ obj-$(CONFIG_CHARGER_MAX77693)        += max77693_charger.o
+-obj-y                         += max77693_charger.o
+ obj-$(CONFIG_CHARGER_BQ2415X) += bq2415x_charger.o
+ obj-$(CONFIG_POWER_AVS)               += avs/
+ obj-$(CONFIG_CHARGER_SMB347)  += smb347-charger.o
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0193-ARM-clock-cpufreq-Correct-MPLL-clock-and-DTS-binding.patch b/patches.tizen/0193-ARM-clock-cpufreq-Correct-MPLL-clock-and-DTS-binding.patch
new file mode 100644 (file)
index 0000000..5ab02fb
--- /dev/null
@@ -0,0 +1,48 @@
+From 2e63163dc07e1f60cbd6c0f9f8f7880ceb96629a Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Fri, 5 Apr 2013 18:31:42 +0200
+Subject: [PATCH 0193/1302] ARM:clock:cpufreq: Correct MPLL clock and DTS
+ binding
+
+According to specification the mout_mpll_user_c clock shall be used instead
+of sclk.
+
+Moreover correct clock number (18) was assigned to mout_mpll_user_c.
+It coply with ./Documentation/devicetree/bindings/clock/exynos4-clock.txt
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12.dtsi    | 2 +-
+ drivers/cpufreq/exynos4x12-cpufreq.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index 1e016a9..149c0dd 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -333,7 +333,7 @@
+       cpufreq {
+               compatible = "samsung,exynos-cpufreq";
+-              clocks = <&clock 12>, <&clock 19>, <&clock 9>, <&clock 20>;
++              clocks = <&clock 12>, <&clock 19>, <&clock 18>, <&clock 20>;
+               clock-names = "arm_clk", "mout_core", "mout_mpll_user_c",
+                                                               "mout_apll";
+               status = "disabled";
+diff --git a/drivers/cpufreq/exynos4x12-cpufreq.c b/drivers/cpufreq/exynos4x12-cpufreq.c
+index 02d5353..1359fd9 100644
+--- a/drivers/cpufreq/exynos4x12-cpufreq.c
++++ b/drivers/cpufreq/exynos4x12-cpufreq.c
+@@ -213,7 +213,7 @@ int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
+       if (IS_ERR(mout_core))
+               goto err_moutcore;
+-      sclk_mpll = clk_get(info->dev, "sclk_mpll_user_c");
++      sclk_mpll = clk_get(info->dev, "mout_mpll_user_c");
+       if (IS_ERR(sclk_mpll))
+               goto err_sclk_mpll;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0194-ARM-dts-Update-ISP-clocks-in-exyno4x12.dtsi.patch b/patches.tizen/0194-ARM-dts-Update-ISP-clocks-in-exyno4x12.dtsi.patch
new file mode 100644 (file)
index 0000000..5f8931a
--- /dev/null
@@ -0,0 +1,36 @@
+From 30d1d3f90ff38095e0977c2883c0990fc58ce4be Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 5 Apr 2013 18:50:54 +0200
+Subject: [PATCH 0194/1302] ARM: dts: Update ISP clocks in exyno4x12.dtsi
+
+Update fimc-is node clock properties to match changed div clocks
+base index.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12.dtsi | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index 149c0dd..c0c75d9 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -282,10 +282,10 @@
+                       clocks = <&clock 353>, <&clock 354>, <&clock 355>,
+                               <&clock 356>, <&clock 342>, <&clock 17>,
+                               <&clock 357>, <&clock 358>, <&clock 359>,
+-                              <&clock 360>, <&clock 512>,<&clock 513>,
+-                              <&clock 514>, <&clock 515>, <&clock 176>,
+-                              <&clock 13>, <&clock 516>, <&clock 22>,
+-                              <&clock 517>;
++                              <&clock 360>, <&clock 450>,<&clock 451>,
++                              <&clock 452>, <&clock 453>, <&clock 176>,
++                              <&clock 13>, <&clock 454>, <&clock 396>,
++                              <&clock 455>;
+                       clock-names = "lite0", "lite1", "ppmuispx",
+                                     "ppmuispmx", "sysreg", "mpll",
+                                     "isp", "drc", "fd",
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0195-ARM-dts-Update-the-wm1811-codec-node-in-exynos4412-s.patch b/patches.tizen/0195-ARM-dts-Update-the-wm1811-codec-node-in-exynos4412-s.patch
new file mode 100644 (file)
index 0000000..b63d906
--- /dev/null
@@ -0,0 +1,83 @@
+From d20c867d7a2a8130fb5614a08767fbb5e6b14149 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 11 Apr 2013 17:32:41 +0200
+Subject: [PATCH 0195/1302] ARM: dts: Update the wm1811 codec node in
+ exynos4412-slp_pq.dts
+
+Add required properties for the wm1811 codec node according
+to the DT binding.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 38 ++++++++++-----------------------
+ 1 file changed, 11 insertions(+), 27 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 54213ca..062b204 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -229,21 +229,26 @@
+               wm1811: wm1811@1a {
+                       compatible = "wlf,wm1811";
+                       reg = <0x1a>;
+-                      gpios = <&gpj0 4 0>; /* Temporary, LDO_EN */
+                       interrupt-parent = <&gpx3>;
+                       interrupts = <6 4>;
++                      wlf,gpio-cfg = <0x3 0x0 0x0 0x0 0x0 0x0
++                                      0x0 0x8000 0x0 0x0 0x0>;
++                      wlf,micbias-cfg = <0x2f 0x2b>;
++
++                      wlf,lineout2-feedback;
++                      wlf,lineout1-se;
++                      wlf,lineout2-se;
++
++                      AVDD2-supply = <&vbatt_reg>;
+                       DBVDD1-supply = <&ldo3_reg>;
+                       DBVDD2-supply = <&vbatt_reg>;
+                       DBVDD3-supply = <&vbatt_reg>;
+-                      DCVDD-supply = <&vbatt_reg>;
+-                      AVDD1-supply = <&vbatt_reg>;
+-                      AVDD2-supply = <&vbatt_reg>;
+-                      AVDD3-supply = <&vbatt_reg>;
+                       CPVDD-supply = <&vbatt_reg>;
+                       SPKVDD1-supply = <&vbatt_reg>;
+                       SPKVDD2-supply = <&vbatt_reg>;
+-                      LDO1VDD-supply = <&vbatt_reg>;
++
++                      wlf,ldo1ena = <&gpj0 4 0>;
+               };
+       };
+@@ -629,27 +634,6 @@
+               regulator-always-on;
+       };
+-      wm1811_regulator {
+-              compatible = "wlf,wm8994-ldo";
+-              status = "disabled";
+-              voltage-regulators {
+-                      wm1811_ldo1_reg: ldo@1 {
+-                              regulator-compatible = "LDO1";
+-                              regulator-name = "WM1811_LDO1";
+-                              regulator-min-microvolt = <2400000>;
+-                              regulator-max-microvolt = <2400000>;
+-                      };
+-
+-                      wm1811_ldo2_reg: ldo@2 {
+-                              regulator-compatible = "LDO2";
+-                              regulator-name = "WM1811_LDO2";
+-                              regulator-min-microvolt = <1200000>;
+-                              regulator-max-microvolt = <1200000>;
+-                              regulator-always-on;
+-                      };
+-              };
+-      };
+-
+       fimd0_lcd: panel {
+               compatible = "samsung,s6e8aa0";
+               reset-gpio = <&gpy4 5 0>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0196-iio-ak8975-Add-support-for-gpios-DT-property.patch b/patches.tizen/0196-iio-ak8975-Add-support-for-gpios-DT-property.patch
new file mode 100644 (file)
index 0000000..e4f06c6
--- /dev/null
@@ -0,0 +1,76 @@
+From 784caada8f244c70a5988aa58033f3e8fdc522e4 Mon Sep 17 00:00:00 2001
+From: Jacek Anaszewski <j.anaszewski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
+Date: Tue, 7 May 2013 12:41:38 +0200
+Subject: [PATCH 0196/1302] iio:ak8975 Add support for gpios DT property
+
+Add support for parsing 'gpios' property when initializing
+from oftree.
+This patch adds also the binding documentation file.
+
+Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/iio/magnetometer/ak8975.txt    | 18 ++++++++++++++++++
+ drivers/iio/magnetometer/ak8975.c                      | 12 +++++++++---
+ 2 files changed, 27 insertions(+), 3 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt
+
+diff --git a/Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt b/Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt
+new file mode 100644
+index 0000000..011679f
+--- /dev/null
++++ b/Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt
+@@ -0,0 +1,18 @@
++* AsahiKASEI AK8975 magnetometer sensor
++
++Required properties:
++
++  - compatible : should be "asahi-kasei,ak8975"
++  - reg : the I2C address of the magnetometer
++
++Optional properties:
++
++  - gpios : should be device tree identifier of the magnetometer DRDY pin
++
++Example:
++
++ak8975@0c {
++        compatible = "asahi-kasei,ak8975";
++        reg = <0x0c>;
++        gpios = <&gpj0 7 0>;
++};
+diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c
+index af6c320..d75cc23 100644
+--- a/drivers/iio/magnetometer/ak8975.c
++++ b/drivers/iio/magnetometer/ak8975.c
+@@ -29,6 +29,7 @@
+ #include <linux/delay.h>
+ #include <linux/gpio.h>
++#include <linux/of_gpio.h>
+ #include <linux/iio/iio.h>
+ #include <linux/iio/sysfs.h>
+@@ -384,10 +385,15 @@ static int ak8975_probe(struct i2c_client *client,
+       int err;
+       /* Grab and set up the supplied GPIO. */
+-      if (client->dev.platform_data == NULL)
+-              eoc_gpio = -1;
+-      else
++      if (client->dev.platform_data)
+               eoc_gpio = *(int *)(client->dev.platform_data);
++      else if (client->dev.of_node)
++              eoc_gpio = of_get_gpio(client->dev.of_node, 0);
++      else
++              eoc_gpio = -1;
++
++      if (eoc_gpio == -EPROBE_DEFER)
++              return -EPROBE_DEFER;
+       /* We may not have a GPIO based IRQ to scan, that is fine, we will
+          poll if so */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0197-iio-ak8975-Implement-data-ready-interrupt-handling.patch b/patches.tizen/0197-iio-ak8975-Implement-data-ready-interrupt-handling.patch
new file mode 100644 (file)
index 0000000..f2eb33e
--- /dev/null
@@ -0,0 +1,196 @@
+From 120874f322f78998ded9d1e175f7ee4ca4db69d0 Mon Sep 17 00:00:00 2001
+From: Jacek Anaszewski <j.anaszewski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
+Date: Tue, 7 May 2013 12:41:39 +0200
+Subject: [PATCH 0197/1302] iio:ak8975 Implement data ready interrupt handling
+
+Implement "data ready" interrupt handling in addition to the
+two existing read modes - DRDY GPIO polling and ST1 register
+DRDY bit polling.
+
+Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iio/magnetometer/ak8975.c | 91 ++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 89 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c
+index d75cc23..7105f22 100644
+--- a/drivers/iio/magnetometer/ak8975.c
++++ b/drivers/iio/magnetometer/ak8975.c
+@@ -24,10 +24,11 @@
+ #include <linux/kernel.h>
+ #include <linux/slab.h>
+ #include <linux/i2c.h>
++#include <linux/interrupt.h>
+ #include <linux/err.h>
+ #include <linux/mutex.h>
+ #include <linux/delay.h>
+-
++#include <linux/bitops.h>
+ #include <linux/gpio.h>
+ #include <linux/of_gpio.h>
+@@ -83,6 +84,7 @@
+  */
+ #define AK8975_MAX_CONVERSION_TIMEOUT 500
+ #define AK8975_CONVERSION_DONE_POLL_TIME 10
++#define AK8975_DATA_READY_TIMEOUT     ((100*HZ)/1000)
+ /*
+  * Per-instance context data for the device.
+@@ -95,6 +97,9 @@ struct ak8975_data {
+       long                    raw_to_gauss[3];
+       u8                      reg_cache[AK8975_MAX_REGS];
+       int                     eoc_gpio;
++      int                     eoc_irq;
++      wait_queue_head_t       data_ready_queue;
++      unsigned long           flags;
+ };
+ static const int ak8975_index_to_reg[] = {
+@@ -124,6 +129,51 @@ static int ak8975_write_data(struct i2c_client *client,
+ }
+ /*
++ * Handle data ready irq
++ */
++static irqreturn_t ak8975_irq_handler(int irq, void *data)
++{
++      struct ak8975_data *ak8975 = data;
++
++      set_bit(0, &ak8975->flags);
++      wake_up(&ak8975->data_ready_queue);
++
++      return IRQ_HANDLED;
++}
++
++/*
++ * Install data ready interrupt handler
++ */
++static int ak8975_setup_irq(struct ak8975_data *data)
++{
++      struct i2c_client *client = data->client;
++      int rc;
++      int irq;
++
++      if (client->irq)
++              irq = client->irq;
++      else
++              irq = gpio_to_irq(data->eoc_gpio);
++
++      rc = request_irq(irq, ak8975_irq_handler,
++                       IRQF_TRIGGER_RISING | IRQF_ONESHOT,
++                       dev_name(&client->dev), data);
++      if (rc < 0) {
++              dev_err(&client->dev,
++                      "irq %d request failed, (gpio %d): %d\n",
++                      irq, data->eoc_gpio, rc);
++              return rc;
++      }
++
++      init_waitqueue_head(&data->data_ready_queue);
++      clear_bit(0, &data->flags);
++      data->eoc_irq = irq;
++
++      return rc;
++}
++
++
++/*
+  * Perform some start-of-day setup, including reading the asa calibration
+  * values and caching them.
+  */
+@@ -171,6 +221,16 @@ static int ak8975_setup(struct i2c_client *client)
+                               AK8975_REG_CNTL_MODE_POWER_DOWN,
+                               AK8975_REG_CNTL_MODE_MASK,
+                               AK8975_REG_CNTL_MODE_SHIFT);
++
++      if (data->eoc_gpio > 0 || client->irq) {
++              ret = ak8975_setup_irq(data);
++              if (ret < 0) {
++                      dev_err(&client->dev,
++                              "Error setting data ready interrupt\n");
++                      return ret;
++              }
++      }
++
+       if (ret < 0) {
+               dev_err(&client->dev, "Error in setting power-down mode\n");
+               return ret;
+@@ -267,9 +327,23 @@ static int wait_conversion_complete_polled(struct ak8975_data *data)
+               dev_err(&client->dev, "Conversion timeout happened\n");
+               return -EINVAL;
+       }
++
+       return read_status;
+ }
++/* Returns 0 if the end of conversion interrupt occured or -ETIME otherwise */
++static int wait_conversion_complete_interrupt(struct ak8975_data *data)
++{
++      int ret;
++
++      ret = wait_event_timeout(data->data_ready_queue,
++                               test_bit(0, &data->flags),
++                               AK8975_DATA_READY_TIMEOUT);
++      clear_bit(0, &data->flags);
++
++      return ret > 0 ? 0 : -ETIME;
++}
++
+ /*
+  * Emits the raw flux value for the x, y, or z axis.
+  */
+@@ -295,13 +369,16 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
+       }
+       /* Wait for the conversion to complete. */
+-      if (gpio_is_valid(data->eoc_gpio))
++      if (data->eoc_irq)
++              ret = wait_conversion_complete_interrupt(data);
++      else if (gpio_is_valid(data->eoc_gpio))
+               ret = wait_conversion_complete_gpio(data);
+       else
+               ret = wait_conversion_complete_polled(data);
+       if (ret < 0)
+               goto exit;
++      /* This will be executed only for non-interrupt based waiting case */
+       if (ret & AK8975_REG_ST1_DRDY_MASK) {
+               ret = i2c_smbus_read_byte_data(client, AK8975_REG_ST2);
+               if (ret < 0) {
+@@ -415,6 +492,11 @@ static int ak8975_probe(struct i2c_client *client,
+       }
+       data = iio_priv(indio_dev);
+       i2c_set_clientdata(client, indio_dev);
++
++      data->client = client;
++      data->eoc_gpio = eoc_gpio;
++      data->eoc_irq = 0;
++
+       /* Perform some basic start-of-day setup of the device. */
+       err = ak8975_setup(client);
+       if (err < 0) {
+@@ -439,6 +521,8 @@ static int ak8975_probe(struct i2c_client *client,
+ exit_free_iio:
+       iio_device_free(indio_dev);
++      if (data->eoc_irq)
++              free_irq(data->eoc_irq, data);
+ exit_gpio:
+       if (gpio_is_valid(eoc_gpio))
+               gpio_free(eoc_gpio);
+@@ -453,6 +537,9 @@ static int ak8975_remove(struct i2c_client *client)
+       iio_device_unregister(indio_dev);
++      if (data->eoc_irq)
++              free_irq(data->eoc_irq, data);
++
+       if (gpio_is_valid(data->eoc_gpio))
+               gpio_free(data->eoc_gpio);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0198-video-display-panel-s6e8aa0-support-others-panel-ver.patch b/patches.tizen/0198-video-display-panel-s6e8aa0-support-others-panel-ver.patch
new file mode 100644 (file)
index 0000000..25ea28d
--- /dev/null
@@ -0,0 +1,197 @@
+From 67a4eb3390ea90e47cca6773e081d4c80bac9b10 Mon Sep 17 00:00:00 2001
+From: Donghwa Lee <dh09.lee@samsung.com>
+Date: Thu, 18 Apr 2013 14:30:29 +0900
+Subject: [PATCH 0198/1302] video: display: panel-s6e8aa0: support others panel
+ version configuration
+
+existing driver only supports v32 and v142, but we have to support a large
+variety of panel version. This patch is just workaround code.
+
+Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/video/display/panel-s6e8aa0.c | 161 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 161 insertions(+)
+
+diff --git a/drivers/video/display/panel-s6e8aa0.c b/drivers/video/display/panel-s6e8aa0.c
+index 3f69187..30ed901 100644
+--- a/drivers/video/display/panel-s6e8aa0.c
++++ b/drivers/video/display/panel-s6e8aa0.c
+@@ -579,6 +579,136 @@ static const s6e8aa0_gamma_table s6e8aa0_gamma_tables_v142[GAMMA_LEVEL_NUM] = {
+       },
+ };
++static const s6e8aa0_gamma_table s6e8aa0_gamma_tables_v96[GAMMA_LEVEL_NUM] = {
++      {
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x00, 0xff,
++              0xdf, 0x1f, 0xd7, 0xdc, 0xb7, 0xe1, 0xc0, 0xaf,
++              0xc4, 0xd2, 0xd0, 0xcf, 0x00, 0x4d, 0x00, 0x40,
++              0x00, 0x5f,
++      }, {
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x00, 0xff,
++              0xd5, 0x35, 0xcf, 0xdc, 0xc1, 0xe1, 0xbf, 0xb3,
++              0xc1, 0xd2, 0xd1, 0xce, 0x00, 0x53, 0x00, 0x46,
++              0x00, 0x67,
++      }, {
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x00, 0xff,
++              0xd2, 0x64, 0xcf, 0xdb, 0xc6, 0xe1, 0xbd, 0xb3,
++              0xbd, 0xd2, 0xd2, 0xce, 0x00, 0x59, 0x00, 0x4b,
++              0x00, 0x6e,
++      }, {
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x00, 0xff,
++              0xd0, 0x7c, 0xcf, 0xdb, 0xc9, 0xe0, 0xbc, 0xb4,
++              0xbb, 0xcf, 0xd1, 0xcc, 0x00, 0x5f, 0x00, 0x50,
++              0x00, 0x75,
++      }, {
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x00, 0xff,
++              0xd0, 0x8e, 0xd1, 0xdb, 0xcc, 0xdf, 0xbb, 0xb6,
++              0xb9, 0xd0, 0xd1, 0xcd, 0x00, 0x63, 0x00, 0x54,
++              0x00, 0x7a,
++      }, {
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x00, 0xffF,
++              0xd1, 0x9e, 0xd5, 0xda, 0xcd, 0xdd, 0xbb, 0xb7,
++              0xb9, 0xce, 0xce, 0xc9, 0x00, 0x68, 0x00, 0x59,
++              0x00, 0x81,
++      }, {
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x00, 0xff,
++              0xd0, 0xa5, 0xd6, 0xda, 0xcf, 0xdd, 0xbb, 0xb7,
++              0xb8, 0xcc, 0xcd, 0xc7, 0x00, 0x6c, 0x00, 0x5c,
++              0x00, 0x86,
++      }, {
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x1f, 0xfe,
++              0xd0, 0xae, 0xd7, 0xd9, 0xd0, 0xdb, 0xb9, 0xb6,
++              0xb5, 0xca, 0xcc, 0xc5, 0x00, 0x74, 0x00, 0x63,
++              0x00, 0x90,
++      }, {
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x1f, 0xf9,
++              0xcf, 0xb0, 0xd6, 0xd9, 0xd1, 0xdb, 0xb9, 0xb6,
++              0xb4, 0xca, 0xcb, 0xc5, 0x00, 0x77, 0x00, 0x66,
++              0x00, 0x94,
++      }, {
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x1f, 0xf7,
++              0xcf, 0xb3, 0xd7, 0xd8, 0xd1, 0xd9, 0xb7, 0xb6,
++              0xb3, 0xc9, 0xca, 0xc3, 0x00, 0x7b, 0x00, 0x69,
++              0x00, 0x99,
++
++      }, {
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xfd, 0x2f, 0xf7,
++              0xdf, 0xb5, 0xd6, 0xd8, 0xd1, 0xd8, 0xb6, 0xb5,
++              0xb2, 0xca, 0xcb, 0xc4, 0x00, 0x7e, 0x00, 0x6c,
++              0x00, 0x9d,
++      }, {
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xfa, 0x2f, 0xf5,
++              0xce, 0xb6, 0xd5, 0xd7, 0xd2, 0xd8, 0xb6, 0xb4,
++              0xb0, 0xc7, 0xc9, 0xc1, 0x00, 0x84, 0x00, 0x71,
++              0x00, 0xa5,
++      }, {
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xf7, 0x2f, 0xf2,
++              0xce, 0xb9, 0xd5, 0xd8, 0xd2, 0xd8, 0xb4, 0xb4,
++              0xaf, 0xc7, 0xc9, 0xc1, 0x00, 0x87, 0x00, 0x73,
++              0x00, 0xa8,
++      }, {
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xf5, 0x2f, 0xf0,
++              0xdf, 0xba, 0xd5, 0xd7, 0xd2, 0xd7, 0xb4, 0xb4,
++              0xaf, 0xc5, 0xc7, 0xbf, 0x00, 0x8a, 0x00, 0x76,
++              0x00, 0xac,
++      }, {
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xf2, 0x2f, 0xed,
++              0xcE, 0xbb, 0xd4, 0xd6, 0xd2, 0xd6, 0xb5, 0xb4,
++              0xaF, 0xc5, 0xc7, 0xbf, 0x00, 0x8c, 0x00, 0x78,
++              0x00, 0xaf,
++      }, {
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xef, 0x2f, 0xeb,
++              0xcd, 0xbb, 0xd2, 0xd7, 0xd3, 0xd6, 0xb3, 0xb4,
++              0xae, 0xc5, 0xc6, 0xbe, 0x00, 0x91, 0x00, 0x7d,
++              0x00, 0xb6,
++      }, {
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xee, 0x2f, 0xea,
++              0xce, 0xbd, 0xd4, 0xd6, 0xd2, 0xd5, 0xb2, 0xb3,
++              0xad, 0xc3, 0xc4, 0xbb, 0x00, 0x94, 0x00, 0x7f,
++              0x00, 0xba,
++      }, {
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xec, 0x2f, 0xe8,
++              0xce, 0xbe, 0xd3, 0xd6, 0xd3, 0xd5, 0xb2, 0xb2,
++              0xac, 0xc3, 0xc5, 0xbc, 0x00, 0x96, 0x00, 0x81,
++              0x00, 0xbd,
++      }, {
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xeb, 0x2f, 0xe7,
++              0xce, 0xbf, 0xd3, 0xd6, 0xd2, 0xd5, 0xb1, 0xb2,
++              0xab, 0xc2, 0xc4, 0xbb, 0x00, 0x99, 0x00, 0x83,
++              0x00, 0xc0,
++      }, {
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xef, 0x5f, 0xe9,
++              0xca, 0xbf, 0xd3, 0xd5, 0xd2, 0xd4, 0xb2, 0xb2,
++              0xab, 0xc1, 0xc4, 0xba, 0x00, 0x9b, 0x00, 0x85,
++              0x00, 0xc3,
++      }, {
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xea, 0x5f, 0xe8,
++              0xee, 0xbf, 0xd2, 0xd5, 0xd2, 0xd4, 0xb1, 0xb2,
++              0xab, 0xc1, 0xc2, 0xb9, 0x00, 0x9D, 0x00, 0x87,
++              0x00, 0xc6,
++      }, {
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xe9, 0x5f, 0xe7,
++              0xcd, 0xbf, 0xd2, 0xd6, 0xd2, 0xd4, 0xb1, 0xb2,
++              0xab, 0xbe, 0xc0, 0xb7, 0x00, 0xa1, 0x00, 0x8a,
++              0x00, 0xca,
++      }, {
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xe8, 0x61, 0xe6,
++              0xcd, 0xbf, 0xd1, 0xd6, 0xd3, 0xd4, 0xaf, 0xb0,
++              0xa9, 0xbe, 0xc1, 0xb7, 0x00, 0xa3, 0x00, 0x8b,
++              0x00, 0xce,
++      }, {
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xe8, 0x62, 0xe5,
++              0xcc, 0xc0, 0xd0, 0xd6, 0xd2, 0xd4, 0xaf, 0xb1,
++              0xa9, 0xbd, 0xc0, 0xb6, 0x00, 0xa5, 0x00, 0x8d,
++              0x00, 0xd0,
++      }, {
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xe7, 0x7f, 0xe3,
++              0xcc, 0xc1, 0xd0, 0xd5, 0xd3, 0xd3, 0xae, 0xaf,
++              0xa8, 0xbe, 0xc0, 0xb7, 0x00, 0xa8, 0x00, 0x90,
++              0x00, 0xd3,
++      }
++};
++
+ static const s6e8aa0_gamma_table s6e8aa0_gamma_tables_v32[GAMMA_LEVEL_NUM] = {
+       {
+               0xfa, 0x01, 0x43, 0x14, 0x45, 0x72, 0x5e, 0x6b,
+@@ -874,6 +1004,37 @@ static const struct s6e8aa0_variant s6e8aa0_variants[] = {
+               .elvss_nvm_set = s6e8aa0_elvss_nvm_set_v142,
+               .brightness_set = s6e8aa0_brightness_set_v142,
+               .gamma_tables = s6e8aa0_gamma_tables_v142,
++      }, {
++              /* FIXME: support M0 panel v96
++               * need to suitable panel specification
++               */
++              .version = 96,
++              .panel_cond_set = s6e8aa0_panel_cond_set,
++              .panel_cond_table = s6e8aa0_panel_cond_v32,
++              .panel_cond_len = ARRAY_SIZE(s6e8aa0_panel_cond_v32),
++              .pentile_ctl_table = s6e8aa0_pentile_ctl_table_v32,
++              .pentile_ctl_len = ARRAY_SIZE(s6e8aa0_pentile_ctl_table_v32),
++              .power_ctl_table = s6e8aa0_power_ctl_table_v32,
++              .power_ctl_len = ARRAY_SIZE(s6e8aa0_power_ctl_table_v32),
++              .elvss_nvm_set = s6e8aa0_elvss_nvm_set,
++              .elvss_nvm_table = s6e8aa0_elvss_nvm_table_v32,
++              .elvss_nvm_len = ARRAY_SIZE(s6e8aa0_elvss_nvm_table_v32),
++              .brightness_set = s6e8aa0_brightness_set,
++              .gamma_tables = s6e8aa0_gamma_tables_v96,
++      
++      }, {
++              /* FIXME: support U1HD panel v210
++               * need to suitable panel specification
++               */
++              .version = 210,
++              .panel_cond_set = s6e8aa0_panel_cond_set_v142,
++              .pentile_ctl_table = s6e8aa0_pentile_ctl_table,
++              .pentile_ctl_len = ARRAY_SIZE(s6e8aa0_pentile_ctl_table),
++              .power_ctl_table = s6e8aa0_power_ctl_table,
++              .power_ctl_len = ARRAY_SIZE(s6e8aa0_power_ctl_table),
++              .elvss_nvm_set = s6e8aa0_elvss_nvm_set_v142,
++              .brightness_set = s6e8aa0_brightness_set_v142,
++              .gamma_tables = s6e8aa0_gamma_tables_v142,
+       }
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0199-drm-exynos-Remove-MODULE_DEVICE_TABLE-table-from-vid.patch b/patches.tizen/0199-drm-exynos-Remove-MODULE_DEVICE_TABLE-table-from-vid.patch
new file mode 100644 (file)
index 0000000..775b775
--- /dev/null
@@ -0,0 +1,42 @@
+From b1269fe543da347d1b68dac800055e4ef85fe8e4 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 19 Apr 2013 15:38:50 +0200
+Subject: [PATCH 0199/1302] drm/exynos: Remove MODULE_DEVICE_TABLE table from
+ vidi driver
+
+Currently there are multiple OF module_device_tables defined which
+prevents building the whole driver as a module. The compiler error
+is as below.
+
+LD [M]  drivers/gpu/drm/exynos/exynosdrm.o
+drivers/gpu/drm/exynos/exynos_drm_vidi.o: In function `.LANCHOR0':
+exynos_drm_vidi.c:(.rodata+0x26c): multiple definition of `__mod_of_device_table'
+drivers/gpu/drm/exynos/exynos_drm_fimd.o:exynos_drm_fimd.c:(.rodata+0x170): first defined here
+/usr/bin/arm-linux-gnueabi-ld: Warning: size of symbol `__mod_of_device_table' changed from 588
+in drivers/gpu/drm/exynos/exynos_drm_fimd.o to 392 in drivers/gpu/drm/exynos/exynos_drm_vidi.o
+make[4]: *** [drivers/gpu/drm/exynos/exynosdrm.o] Error 1
+
+Fix this by removing MODULE_DEVICE_TABLE(of,...) entry for the vidi driver,
+leaving the one for FIMD driver.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_vidi.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+index c966e23..3b2aa26 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+@@ -90,7 +90,6 @@ static const struct of_device_id vidi_driver_dt_match[] = {
+       { .compatible = "samsung,exynos-drm-vidi" },
+       {},
+ };
+-MODULE_DEVICE_TABLE(of, vidi_driver_dt_match);
+ #endif
+ static bool vidi_display_is_connected(struct device *dev)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0200-exynos4-is-Add-fimc-parent-clock-setup.patch b/patches.tizen/0200-exynos4-is-Add-fimc-parent-clock-setup.patch
new file mode 100644 (file)
index 0000000..c99dc10
--- /dev/null
@@ -0,0 +1,186 @@
+From dced246c3a5cb5500d700b43a177cb80a92b5669 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Tue, 5 Feb 2013 11:16:10 +0100
+Subject: [PATCH 0200/1302] exynos4-is: Add fimc parent clock setup
+
+With this patch the driver will set "parent" clock as a parent
+clock of "mux" clock. When the samsung clocks driver is reworked
+to use new composite clock type, the "mux" clock can be removed.
+
+"parent" clock should be set in related dtsi file and can be
+overwritten in a board dts file. This way it is ensured the
+SCLK_FIMC clock has correct parent clock set, and the parent
+clock can be selected per each board if required.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-core.c | 63 ++++++++++++++++++---------
+ drivers/media/platform/exynos4-is/fimc-core.h |  6 ++-
+ 2 files changed, 46 insertions(+), 23 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c
+index 379a5e9..e856730 100644
+--- a/drivers/media/platform/exynos4-is/fimc-core.c
++++ b/drivers/media/platform/exynos4-is/fimc-core.c
+@@ -34,8 +34,8 @@
+ #include "fimc-reg.h"
+ #include "media-dev.h"
+-static char *fimc_clocks[MAX_FIMC_CLOCKS] = {
+-      "sclk_fimc", "fimc"
++static char *fimc_clocks[CLK_FIMC_MAX] = {
++      "sclk_fimc", "fimc", "mux", "parent"
+ };
+ static struct fimc_fmt fimc_formats[] = {
+@@ -803,10 +803,10 @@ struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code,
+       return def_fmt;
+ }
+-static void fimc_clk_put(struct fimc_dev *fimc)
++static void fimc_put_clocks(struct fimc_dev *fimc)
+ {
+       int i;
+-      for (i = 0; i < MAX_FIMC_CLOCKS; i++) {
++      for (i = 0; i < CLK_FIMC_MAX; i++) {
+               if (IS_ERR(fimc->clock[i]))
+                       continue;
+               clk_unprepare(fimc->clock[i]);
+@@ -815,15 +815,21 @@ static void fimc_clk_put(struct fimc_dev *fimc)
+       }
+ }
+-static int fimc_clk_get(struct fimc_dev *fimc)
++static int fimc_get_clocks(struct fimc_dev *fimc)
+ {
++      struct device *dev = &fimc->pdev->dev;
++      unsigned int num_clocks = CLK_FIMC_MAX;
+       int i, ret;
+-      for (i = 0; i < MAX_FIMC_CLOCKS; i++)
++      /* Skip parent and mux clocks for non-dt platforms */
++      if (!dev->of_node)
++              num_clocks -= 2;
++
++      for (i = 0; i < CLK_FIMC_MAX; i++)
+               fimc->clock[i] = ERR_PTR(-EINVAL);
+-      for (i = 0; i < MAX_FIMC_CLOCKS; i++) {
+-              fimc->clock[i] = clk_get(&fimc->pdev->dev, fimc_clocks[i]);
++      for (i = 0; i < num_clocks; i++) {
++              fimc->clock[i] = clk_get(dev, fimc_clocks[i]);
+               if (IS_ERR(fimc->clock[i])) {
+                       ret = PTR_ERR(fimc->clock[i]);
+                       goto err;
+@@ -837,12 +843,32 @@ static int fimc_clk_get(struct fimc_dev *fimc)
+       }
+       return 0;
+ err:
+-      fimc_clk_put(fimc);
+-      dev_err(&fimc->pdev->dev, "failed to get clock: %s\n",
+-              fimc_clocks[i]);
++      fimc_put_clocks(fimc);
++      dev_err(dev, "failed to get clock: %s\n", fimc_clocks[i]);
+       return -ENXIO;
+ }
++static int fimc_setup_clocks(struct fimc_dev *fimc, unsigned long freq)
++{
++      int ret;
++
++      if (!IS_ERR(fimc->clock[CLK_PARENT])) {
++              ret = clk_set_parent(fimc->clock[CLK_MUX],
++                                   fimc->clock[CLK_PARENT]);
++              if (ret < 0) {
++                      dev_err(&fimc->pdev->dev,
++                              "%s(): failed to set parent: %d\n",
++                              __func__, ret);
++                      return ret;
++              }
++      }
++      ret = clk_set_rate(fimc->clock[CLK_BUS], freq);
++      if (ret < 0)
++              return ret;
++
++      return clk_enable(fimc->clock[CLK_BUS]);
++}
++
+ static int fimc_m2m_suspend(struct fimc_dev *fimc)
+ {
+       unsigned long flags;
+@@ -992,18 +1018,13 @@ static int fimc_probe(struct platform_device *pdev)
+               return -ENXIO;
+       }
+-      ret = fimc_clk_get(fimc);
+-      if (ret)
++      ret = fimc_get_clocks(fimc);
++      if (ret < 0)
+               return ret;
+-
+       if (lclk_freq == 0)
+               lclk_freq = fimc->drv_data->lclk_frequency;
+-      ret = clk_set_rate(fimc->clock[CLK_BUS], lclk_freq);
+-      if (ret < 0)
+-              return ret;
+-
+-      ret = clk_enable(fimc->clock[CLK_BUS]);
++      ret = fimc_setup_clocks(fimc, lclk_freq);
+       if (ret < 0)
+               return ret;
+@@ -1040,7 +1061,7 @@ err_sd:
+       fimc_unregister_capture_subdev(fimc);
+ err_clk:
+       clk_disable(fimc->clock[CLK_BUS]);
+-      fimc_clk_put(fimc);
++      fimc_put_clocks(fimc);
+       return ret;
+ }
+@@ -1127,7 +1148,7 @@ static int fimc_remove(struct platform_device *pdev)
+       vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx);
+       clk_disable(fimc->clock[CLK_BUS]);
+-      fimc_clk_put(fimc);
++      fimc_put_clocks(fimc);
+       dev_info(&pdev->dev, "driver unloaded\n");
+       return 0;
+diff --git a/drivers/media/platform/exynos4-is/fimc-core.h b/drivers/media/platform/exynos4-is/fimc-core.h
+index 539a3f7..8666e4b 100644
+--- a/drivers/media/platform/exynos4-is/fimc-core.h
++++ b/drivers/media/platform/exynos4-is/fimc-core.h
+@@ -34,7 +34,6 @@
+ /* Time to wait for next frame VSYNC interrupt while stopping operation. */
+ #define FIMC_SHUTDOWN_TIMEOUT ((100*HZ)/1000)
+-#define MAX_FIMC_CLOCKS               2
+ #define FIMC_DRIVER_NAME      "exynos4-fimc"
+ #define FIMC_MAX_DEVS         4
+ #define FIMC_MAX_OUT_BUFS     4
+@@ -53,6 +52,9 @@
+ enum {
+       CLK_BUS,
+       CLK_GATE,
++      CLK_MUX,
++      CLK_PARENT,
++      CLK_FIMC_MAX,
+ };
+ enum fimc_dev_flags {
+@@ -426,7 +428,7 @@ struct fimc_dev {
+       const struct fimc_variant       *variant;
+       const struct fimc_drvdata       *drv_data;
+       int                             id;
+-      struct clk                      *clock[MAX_FIMC_CLOCKS];
++      struct clk                      *clock[CLK_FIMC_MAX];
+       void __iomem                    *regs;
+       wait_queue_head_t               irq_queue;
+       struct v4l2_device              *v4l2_dev;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0201-exynos4-is-Add-csis-parent-clock-setup.patch b/patches.tizen/0201-exynos4-is-Add-csis-parent-clock-setup.patch
new file mode 100644 (file)
index 0000000..2d17444
--- /dev/null
@@ -0,0 +1,173 @@
+From 6e06900a842ebac58514adad74b17e9722d2cf89 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Tue, 5 Feb 2013 12:19:19 +0100
+Subject: [PATCH 0201/1302] exynos4-is: Add csis parent clock setup
+
+With this patch the driver will set "parent" clock as a parent
+clock of "mux" clock. When the samsung clocks driver is reworked
+to use new composite clock type, the "mux" clock can be removed.
+
+"parent" clock should be set in relevant dtsi file and can be
+overwritten in a board dts file. This way it is ensured the
+SCLK_CSIS has correct parent clock set, and the parent clock
+can be selected per each board if required.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/mipi-csis.c | 68 ++++++++++++++++++---------
+ 1 file changed, 46 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
+index 254d70f..ae99803 100644
+--- a/drivers/media/platform/exynos4-is/mipi-csis.c
++++ b/drivers/media/platform/exynos4-is/mipi-csis.c
+@@ -108,13 +108,17 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)");
+ #define S5PCSIS_PKTDATA_SIZE          SZ_4K
+ enum {
+-      CSIS_CLK_MUX,
++      CSIS_CLK_BUS,
+       CSIS_CLK_GATE,
++      CSIS_CLK_MUX,
++      CSIS_CLK_PARENT,
+ };
+ static char *csi_clock_name[] = {
+-      [CSIS_CLK_MUX]  = "sclk_csis",
++      [CSIS_CLK_BUS]  = "sclk_csis",
+       [CSIS_CLK_GATE] = "csis",
++      [CSIS_CLK_MUX] = "mux",
++      [CSIS_CLK_PARENT] = "parent",
+ };
+ #define NUM_CSIS_CLOCKS       ARRAY_SIZE(csi_clock_name)
+ #define DEFAULT_SCLK_CSIS_FREQ        166000000UL
+@@ -362,7 +366,7 @@ static void s5pcsis_set_params(struct csis_state *state)
+       s5pcsis_write(state, S5PCSIS_CTRL, val | S5PCSIS_CTRL_UPDATE_SHADOW);
+ }
+-static void s5pcsis_clk_put(struct csis_state *state)
++static void s5pcsis_put_clocks(struct csis_state *state)
+ {
+       int i;
+@@ -375,15 +379,20 @@ static void s5pcsis_clk_put(struct csis_state *state)
+       }
+ }
+-static int s5pcsis_clk_get(struct csis_state *state)
++static int s5pcsis_get_clocks(struct csis_state *state)
+ {
+       struct device *dev = &state->pdev->dev;
++      unsigned int num_clocks = NUM_CSIS_CLOCKS;
+       int i, ret;
++      /* Skip parent and mux clocks for non-dt platforms */
++      if (!dev->of_node)
++              num_clocks -= 2;
++
+       for (i = 0; i < NUM_CSIS_CLOCKS; i++)
+               state->clock[i] = ERR_PTR(-EINVAL);
+-      for (i = 0; i < NUM_CSIS_CLOCKS; i++) {
++      for (i = 0; i < num_clocks; i++) {
+               state->clock[i] = clk_get(dev, csi_clock_name[i]);
+               if (IS_ERR(state->clock[i])) {
+                       ret = PTR_ERR(state->clock[i]);
+@@ -398,11 +407,32 @@ static int s5pcsis_clk_get(struct csis_state *state)
+       }
+       return 0;
+ err:
+-      s5pcsis_clk_put(state);
++      s5pcsis_put_clocks(state);
+       dev_err(dev, "failed to get clock: %s\n", csi_clock_name[i]);
+       return ret;
+ }
++static int s5pcsis_setup_clocks(struct csis_state *state)
++{
++      int ret;
++
++      if (!IS_ERR(state->clock[CSIS_CLK_PARENT])) {
++              ret = clk_set_parent(state->clock[CSIS_CLK_MUX],
++                                   state->clock[CSIS_CLK_PARENT]);
++              if (ret < 0) {
++                      dev_err(&state->pdev->dev,
++                              "%s(): failed to set parent: %d\n",
++                              __func__, ret);
++                      return ret;
++              }
++      }
++      ret = clk_set_rate(state->clock[CSIS_CLK_BUS],
++                                      state->clk_frequency);
++      if (ret < 0)
++              return ret;
++      return clk_enable(state->clock[CSIS_CLK_BUS]);
++}
++
+ static void dump_regs(struct csis_state *state, const char *label)
+ {
+       struct {
+@@ -719,8 +749,10 @@ static int s5pcsis_get_platform_data(struct platform_device *pdev,
+               dev_err(&pdev->dev, "Platform data not specified\n");
+               return -EINVAL;
+       }
+-
+-      state->clk_frequency = pdata->clk_rate;
++      if (pdata->clk_rate)
++              state->clk_frequency = pdata->clk_rate;
++      else
++              state->clk_frequency = DEFAULT_SCLK_CSIS_FREQ;
+       state->num_lanes = pdata->lanes;
+       state->hs_settle = pdata->hs_settle;
+       state->index = max(0, pdev->id);
+@@ -819,19 +851,11 @@ static int s5pcsis_probe(struct platform_device *pdev)
+       if (ret)
+               return ret;
+-      ret = s5pcsis_clk_get(state);
++      ret = s5pcsis_get_clocks(state);
+       if (ret < 0)
+               return ret;
+-      if (state->clk_frequency)
+-              ret = clk_set_rate(state->clock[CSIS_CLK_MUX],
+-                                 state->clk_frequency);
+-      else
+-              dev_WARN(dev, "No clock frequency specified!\n");
+-      if (ret < 0)
+-              goto e_clkput;
+-
+-      ret = clk_enable(state->clock[CSIS_CLK_MUX]);
++      ret = s5pcsis_setup_clocks(state);
+       if (ret < 0)
+               goto e_clkput;
+@@ -874,9 +898,9 @@ static int s5pcsis_probe(struct platform_device *pdev)
+       return 0;
+ e_clkdis:
+-      clk_disable(state->clock[CSIS_CLK_MUX]);
++      clk_disable(state->clock[CSIS_CLK_BUS]);
+ e_clkput:
+-      s5pcsis_clk_put(state);
++      s5pcsis_put_clocks(state);
+       return ret;
+ }
+@@ -979,9 +1003,9 @@ static int s5pcsis_remove(struct platform_device *pdev)
+       pm_runtime_disable(&pdev->dev);
+       s5pcsis_pm_suspend(&pdev->dev, false);
+-      clk_disable(state->clock[CSIS_CLK_MUX]);
++      clk_disable(state->clock[CSIS_CLK_BUS]);
+       pm_runtime_set_suspended(&pdev->dev);
+-      s5pcsis_clk_put(state);
++      s5pcsis_put_clocks(state);
+       media_entity_cleanup(&state->sd.entity);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0202-media-media-Rename-media_entity_remote_source-to-med.patch b/patches.tizen/0202-media-media-Rename-media_entity_remote_source-to-med.patch
new file mode 100644 (file)
index 0000000..bf67005
--- /dev/null
@@ -0,0 +1,333 @@
+From 7d02b7df04beaa702ac7766cd40d42ccba63107e Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Mon, 3 Jun 2013 05:16:13 -0300
+Subject: [PATCH 0202/1302] [media] media: Rename media_entity_remote_source to
+ media_entity_remote_pad
+
+Function media_entity_remote_source actually returns the remote pad to
+the given one, regardless if this is the source or the sink pad.
+Name media_entity_remote_pad is more adequate for this function.
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Sakari Ailus <sakari.ailus@iki.fi>
+Acked-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/media-framework.txt                |  2 +-
+ drivers/media/media-entity.c                     | 13 ++++++-------
+ drivers/media/platform/exynos4-is/fimc-capture.c |  6 +++---
+ drivers/media/platform/exynos4-is/fimc-lite.c    |  4 ++--
+ drivers/media/platform/exynos4-is/media-dev.c    |  2 +-
+ drivers/media/platform/omap3isp/isp.c            |  6 +++---
+ drivers/media/platform/omap3isp/ispccdc.c        |  2 +-
+ drivers/media/platform/omap3isp/ispccp2.c        |  2 +-
+ drivers/media/platform/omap3isp/ispcsi2.c        |  2 +-
+ drivers/media/platform/omap3isp/ispvideo.c       |  6 +++---
+ drivers/media/platform/s3c-camif/camif-capture.c |  2 +-
+ drivers/staging/media/davinci_vpfe/vpfe_video.c  | 12 ++++++------
+ include/media/media-entity.h                     |  2 +-
+ 13 files changed, 30 insertions(+), 31 deletions(-)
+
+diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt
+index 77bd0a4..3702eff 100644
+--- a/Documentation/media-framework.txt
++++ b/Documentation/media-framework.txt
+@@ -265,7 +265,7 @@ connected to another pad through an enabled link
+       media_entity_find_link(struct media_pad *source,
+                              struct media_pad *sink);
+-      media_entity_remote_source(struct media_pad *pad);
++      media_entity_remote_pad(struct media_pad *pad);
+ Refer to the kerneldoc documentation for more information.
+diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
+index e1cd132..0438209 100644
+--- a/drivers/media/media-entity.c
++++ b/drivers/media/media-entity.c
+@@ -560,17 +560,16 @@ media_entity_find_link(struct media_pad *source, struct media_pad *sink)
+ EXPORT_SYMBOL_GPL(media_entity_find_link);
+ /**
+- * media_entity_remote_source - Find the source pad at the remote end of a link
+- * @pad: Sink pad at the local end of the link
++ * media_entity_remote_pad - Find the pad at the remote end of a link
++ * @pad: Pad at the local end of the link
+  *
+- * Search for a remote source pad connected to the given sink pad by iterating
+- * over all links originating or terminating at that pad until an enabled link
+- * is found.
++ * Search for a remote pad connected to the given pad by iterating over all
++ * links originating or terminating at that pad until an enabled link is found.
+  *
+  * Return a pointer to the pad at the remote end of the first found enabled
+  * link, or NULL if no enabled link has been found.
+  */
+-struct media_pad *media_entity_remote_source(struct media_pad *pad)
++struct media_pad *media_entity_remote_pad(struct media_pad *pad)
+ {
+       unsigned int i;
+@@ -590,4 +589,4 @@ struct media_pad *media_entity_remote_source(struct media_pad *pad)
+       return NULL;
+ }
+-EXPORT_SYMBOL_GPL(media_entity_remote_source);
++EXPORT_SYMBOL_GPL(media_entity_remote_pad);
+diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
+index 528f413..a8b9b06 100644
+--- a/drivers/media/platform/exynos4-is/fimc-capture.c
++++ b/drivers/media/platform/exynos4-is/fimc-capture.c
+@@ -773,7 +773,7 @@ static struct media_entity *fimc_pipeline_get_head(struct media_entity *me)
+       struct media_pad *pad = &me->pads[0];
+       while (!(pad->flags & MEDIA_PAD_FL_SOURCE)) {
+-              pad = media_entity_remote_source(pad);
++              pad = media_entity_remote_pad(pad);
+               if (!pad)
+                       break;
+               me = pad->entity;
+@@ -845,7 +845,7 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
+                                       return ret;
+                       }
+-                      pad = media_entity_remote_source(&me->pads[sfmt.pad]);
++                      pad = media_entity_remote_pad(&me->pads[sfmt.pad]);
+                       if (!pad)
+                               return -EINVAL;
+                       me = pad->entity;
+@@ -1146,7 +1146,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc)
+                       if (p->flags & MEDIA_PAD_FL_SINK) {
+                               sink_pad = p;
+-                              src_pad = media_entity_remote_source(sink_pad);
++                              src_pad = media_entity_remote_pad(sink_pad);
+                               if (src_pad)
+                                       break;
+                       }
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
+index 14bb7bc..2f11ae4 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite.c
++++ b/drivers/media/platform/exynos4-is/fimc-lite.c
+@@ -139,7 +139,7 @@ static struct v4l2_subdev *__find_remote_sensor(struct media_entity *me)
+       while (pad->flags & MEDIA_PAD_FL_SINK) {
+               /* source pad */
+-              pad = media_entity_remote_source(pad);
++              pad = media_entity_remote_pad(pad);
+               if (pad == NULL ||
+                   media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+                       break;
+@@ -786,7 +786,7 @@ static int fimc_pipeline_validate(struct fimc_lite *fimc)
+                               return -EPIPE;
+               }
+               /* Retrieve format at the source pad */
+-              pad = media_entity_remote_source(pad);
++              pad = media_entity_remote_pad(pad);
+               if (pad == NULL ||
+                   media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+                       break;
+diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
+index b5b480b..7f94842 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.c
++++ b/drivers/media/platform/exynos4-is/media-dev.c
+@@ -62,7 +62,7 @@ static void fimc_pipeline_prepare(struct fimc_pipeline *p,
+                       struct media_pad *spad = &me->pads[i];
+                       if (!(spad->flags & MEDIA_PAD_FL_SINK))
+                               continue;
+-                      pad = media_entity_remote_source(spad);
++                      pad = media_entity_remote_pad(spad);
+                       if (pad)
+                               break;
+               }
+diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
+index 1d7dbd5..4c4bd3d 100644
+--- a/drivers/media/platform/omap3isp/isp.c
++++ b/drivers/media/platform/omap3isp/isp.c
+@@ -877,7 +877,7 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe,
+               if (!(pad->flags & MEDIA_PAD_FL_SINK))
+                       break;
+-              pad = media_entity_remote_source(pad);
++              pad = media_entity_remote_pad(pad);
+               if (pad == NULL ||
+                   media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+                       break;
+@@ -967,7 +967,7 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)
+               if (!(pad->flags & MEDIA_PAD_FL_SINK))
+                       break;
+-              pad = media_entity_remote_source(pad);
++              pad = media_entity_remote_pad(pad);
+               if (pad == NULL ||
+                   media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+                       break;
+@@ -1083,7 +1083,7 @@ static int isp_pipeline_is_last(struct media_entity *me)
+       pipe = to_isp_pipeline(me);
+       if (pipe->stream_state == ISP_PIPELINE_STREAM_STOPPED)
+               return 0;
+-      pad = media_entity_remote_source(&pipe->output->pad);
++      pad = media_entity_remote_pad(&pipe->output->pad);
+       return pad->entity == me;
+ }
+diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c
+index 60e60aa..907a205 100644
+--- a/drivers/media/platform/omap3isp/ispccdc.c
++++ b/drivers/media/platform/omap3isp/ispccdc.c
+@@ -1120,7 +1120,7 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc)
+       u32 syn_mode;
+       u32 ccdc_pattern;
+-      pad = media_entity_remote_source(&ccdc->pads[CCDC_PAD_SINK]);
++      pad = media_entity_remote_pad(&ccdc->pads[CCDC_PAD_SINK]);
+       sensor = media_entity_to_v4l2_subdev(pad->entity);
+       if (ccdc->input == CCDC_INPUT_PARALLEL)
+               pdata = &((struct isp_v4l2_subdevs_group *)sensor->host_priv)
+diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c
+index c5d84c9..13982b0 100644
+--- a/drivers/media/platform/omap3isp/ispccp2.c
++++ b/drivers/media/platform/omap3isp/ispccp2.c
+@@ -360,7 +360,7 @@ static int ccp2_if_configure(struct isp_ccp2_device *ccp2)
+       ccp2_pwr_cfg(ccp2);
+-      pad = media_entity_remote_source(&ccp2->pads[CCP2_PAD_SINK]);
++      pad = media_entity_remote_pad(&ccp2->pads[CCP2_PAD_SINK]);
+       sensor = media_entity_to_v4l2_subdev(pad->entity);
+       pdata = sensor->host_priv;
+diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c
+index 783f4b0..6db245d 100644
+--- a/drivers/media/platform/omap3isp/ispcsi2.c
++++ b/drivers/media/platform/omap3isp/ispcsi2.c
+@@ -573,7 +573,7 @@ static int csi2_configure(struct isp_csi2_device *csi2)
+       if (csi2->contexts[0].enabled || csi2->ctrl.if_enable)
+               return -EBUSY;
+-      pad = media_entity_remote_source(&csi2->pads[CSI2_PAD_SINK]);
++      pad = media_entity_remote_pad(&csi2->pads[CSI2_PAD_SINK]);
+       sensor = media_entity_to_v4l2_subdev(pad->entity);
+       pdata = sensor->host_priv;
+diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c
+index 8dac175..a908d00 100644
+--- a/drivers/media/platform/omap3isp/ispvideo.c
++++ b/drivers/media/platform/omap3isp/ispvideo.c
+@@ -219,7 +219,7 @@ isp_video_remote_subdev(struct isp_video *video, u32 *pad)
+ {
+       struct media_pad *remote;
+-      remote = media_entity_remote_source(&video->pad);
++      remote = media_entity_remote_pad(&video->pad);
+       if (remote == NULL ||
+           media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+@@ -314,7 +314,7 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe)
+                * entity can be found, and stop checking the pipeline if the
+                * source entity isn't a subdev.
+                */
+-              pad = media_entity_remote_source(pad);
++              pad = media_entity_remote_pad(pad);
+               if (pad == NULL)
+                       return -EPIPE;
+@@ -901,7 +901,7 @@ static int isp_video_check_external_subdevs(struct isp_video *video,
+                       continue;
+               /* ISP entities have always sink pad == 0. Find source. */
+-              source_pad = media_entity_remote_source(&ents[i]->pads[0]);
++              source_pad = media_entity_remote_pad(&ents[i]->pads[0]);
+               if (source_pad == NULL)
+                       continue;
+diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c
+index 70438a0..40b298a 100644
+--- a/drivers/media/platform/s3c-camif/camif-capture.c
++++ b/drivers/media/platform/s3c-camif/camif-capture.c
+@@ -845,7 +845,7 @@ static int camif_pipeline_validate(struct camif_dev *camif)
+       int ret;
+       /* Retrieve format at the sensor subdev source pad */
+-      pad = media_entity_remote_source(&camif->pads[0]);
++      pad = media_entity_remote_pad(&camif->pads[0]);
+       if (!pad || media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+               return -EPIPE;
+diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c
+index ba913f1..cb5410b 100644
+--- a/drivers/staging/media/davinci_vpfe/vpfe_video.c
++++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c
+@@ -39,7 +39,7 @@ static struct media_entity *vpfe_get_input_entity
+       struct vpfe_device *vpfe_dev = video->vpfe_dev;
+       struct media_pad *remote;
+-      remote = media_entity_remote_source(&vpfe_dev->vpfe_isif.pads[0]);
++      remote = media_entity_remote_pad(&vpfe_dev->vpfe_isif.pads[0]);
+       if (remote == NULL) {
+               pr_err("Invalid media connection to isif/ccdc\n");
+               return NULL;
+@@ -56,7 +56,7 @@ static int vpfe_update_current_ext_subdev(struct vpfe_video_device *video)
+       struct media_pad *remote;
+       int i;
+-      remote = media_entity_remote_source(&vpfe_dev->vpfe_isif.pads[0]);
++      remote = media_entity_remote_pad(&vpfe_dev->vpfe_isif.pads[0]);
+       if (remote == NULL) {
+               pr_err("Invalid media connection to isif/ccdc\n");
+               return -EINVAL;
+@@ -89,7 +89,7 @@ static int vpfe_update_current_ext_subdev(struct vpfe_video_device *video)
+ static struct v4l2_subdev *
+ vpfe_video_remote_subdev(struct vpfe_video_device *video, u32 *pad)
+ {
+-      struct media_pad *remote = media_entity_remote_source(&video->pad);
++      struct media_pad *remote = media_entity_remote_pad(&video->pad);
+       if (remote == NULL || remote->entity->type != MEDIA_ENT_T_V4L2_SUBDEV)
+               return NULL;
+@@ -114,7 +114,7 @@ __vpfe_video_get_format(struct vpfe_video_device *video,
+               return -EINVAL;
+       fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+-      remote = media_entity_remote_source(&video->pad);
++      remote = media_entity_remote_pad(&video->pad);
+       fmt.pad = remote->index;
+       ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
+@@ -245,7 +245,7 @@ static int vpfe_video_validate_pipeline(struct vpfe_pipeline *pipe)
+                       return -EPIPE;
+               /* Retrieve the source format */
+-              pad = media_entity_remote_source(pad);
++              pad = media_entity_remote_pad(pad);
+               if (pad == NULL ||
+                       pad->entity->type != MEDIA_ENT_T_V4L2_SUBDEV)
+                       break;
+@@ -667,7 +667,7 @@ static int vpfe_enum_fmt(struct file *file, void  *priv,
+               return -EINVAL;
+       }
+       /* get the remote pad */
+-      remote = media_entity_remote_source(&video->pad);
++      remote = media_entity_remote_pad(&video->pad);
+       if (remote == NULL) {
+               v4l2_err(&vpfe_dev->v4l2_dev,
+                        "invalid remote pad for video node\n");
+diff --git a/include/media/media-entity.h b/include/media/media-entity.h
+index 0c16f51..4eefedc 100644
+--- a/include/media/media-entity.h
++++ b/include/media/media-entity.h
+@@ -132,7 +132,7 @@ int __media_entity_setup_link(struct media_link *link, u32 flags);
+ int media_entity_setup_link(struct media_link *link, u32 flags);
+ struct media_link *media_entity_find_link(struct media_pad *source,
+               struct media_pad *sink);
+-struct media_pad *media_entity_remote_source(struct media_pad *pad);
++struct media_pad *media_entity_remote_pad(struct media_pad *pad);
+ struct media_entity *media_entity_get(struct media_entity *entity);
+ void media_entity_put(struct media_entity *entity);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0203-exynos4-is-Fix-example-dts-in-.-bindings-samsung-fim.patch b/patches.tizen/0203-exynos4-is-Fix-example-dts-in-.-bindings-samsung-fim.patch
new file mode 100644 (file)
index 0000000..67e6527
--- /dev/null
@@ -0,0 +1,58 @@
+From 0a79f52a79040f7f2319bb806f444ba41c47e91a Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 8 May 2013 19:24:14 +0200
+Subject: [PATCH 0203/1302] exynos4-is: Fix example dts in
+ .../bindings/samsung-fimc.txt
+
+The s5c73m3 sensor node should be off an I2C bus controller node.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/media/samsung-fimc.txt     | 26 +++++++++++-----------
+ 1 file changed, 13 insertions(+), 13 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/media/samsung-fimc.txt b/Documentation/devicetree/bindings/media/samsung-fimc.txt
+index 51c776b..96312f6 100644
+--- a/Documentation/devicetree/bindings/media/samsung-fimc.txt
++++ b/Documentation/devicetree/bindings/media/samsung-fimc.txt
+@@ -127,22 +127,22 @@ Example:
+                               };
+                       };
+               };
+-      };
+-      /* MIPI CSI-2 bus IF sensor */
+-      s5c73m3: sensor@0x1a {
+-              compatible = "samsung,s5c73m3";
+-              reg = <0x1a>;
+-              vddio-supply = <...>;
++              /* MIPI CSI-2 bus IF sensor */
++              s5c73m3: sensor@0x1a {
++                      compatible = "samsung,s5c73m3";
++                      reg = <0x1a>;
++                      vddio-supply = <...>;
+-              clock-frequency = <24000000>;
+-              clocks = <...>;
+-              clock-names = "mclk";
++                      clock-frequency = <24000000>;
++                      clocks = <...>;
++                      clock-names = "mclk";
+-              port {
+-                      s5c73m3_1: endpoint {
+-                              data-lanes = <1 2 3 4>;
+-                              remote-endpoint = <&csis0_ep>;
++                      port {
++                              s5c73m3_1: endpoint {
++                                      data-lanes = <1 2 3 4>;
++                                      remote-endpoint = <&csis0_ep>;
++                              };
+                       };
+               };
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0204-media-media-Add-a-function-removing-all-links-of-a-m.patch b/patches.tizen/0204-media-media-Add-a-function-removing-all-links-of-a-m.patch
new file mode 100644 (file)
index 0000000..279f589
--- /dev/null
@@ -0,0 +1,110 @@
+From 832148209949f030c09b69b60cca64415f63e9cd Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 9 May 2013 08:29:32 -0300
+Subject: [PATCH 0204/1302] [media] media: Add a function removing all links of
+ a media entity
+
+This function allows to remove all media entity's links to other
+entities, leaving no references to a media entity's links array
+at its remote entities.
+Currently, when a driver of some entity is removed it will free its
+media entities links[] array, leaving dangling pointers at other
+entities that are part of same media graph. This is troublesome when
+drivers of a media device entities are in separate kernel modules,
+removing only some modules will leave others in an incorrect state.
+This function is intended to be used when an entity is being
+unregistered from a media device.
+With an assumption that normally the media links should be created
+between media entities registered to a media device, with the graph
+mutex held.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Acked-by: Sakari Ailus <sakari.ailus@iki.fi>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/media-entity.c | 50 ++++++++++++++++++++++++++++++++++++++++++++
+ include/media/media-entity.h |  3 +++
+ 2 files changed, 53 insertions(+)
+
+diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
+index 0438209..987df7d3 100644
+--- a/drivers/media/media-entity.c
++++ b/drivers/media/media-entity.c
+@@ -429,6 +429,56 @@ media_entity_create_link(struct media_entity *source, u16 source_pad,
+ }
+ EXPORT_SYMBOL_GPL(media_entity_create_link);
++void __media_entity_remove_links(struct media_entity *entity)
++{
++      unsigned int i;
++
++      for (i = 0; i < entity->num_links; i++) {
++              struct media_link *link = &entity->links[i];
++              struct media_entity *remote;
++              unsigned int r = 0;
++
++              if (link->source->entity == entity)
++                      remote = link->sink->entity;
++              else
++                      remote = link->source->entity;
++
++              while (r < remote->num_links) {
++                      struct media_link *rlink = &remote->links[r];
++
++                      if (rlink != link->reverse) {
++                              r++;
++                              continue;
++                      }
++
++                      if (link->source->entity == entity)
++                              remote->num_backlinks--;
++
++                      if (--remote->num_links == 0)
++                              break;
++
++                      /* Insert last entry in place of the dropped link. */
++                      *rlink = remote->links[remote->num_links];
++              }
++      }
++
++      entity->num_links = 0;
++      entity->num_backlinks = 0;
++}
++EXPORT_SYMBOL_GPL(__media_entity_remove_links);
++
++void media_entity_remove_links(struct media_entity *entity)
++{
++      /* Do nothing if the entity is not registered. */
++      if (entity->parent == NULL)
++              return;
++
++      mutex_lock(&entity->parent->graph_mutex);
++      __media_entity_remove_links(entity);
++      mutex_unlock(&entity->parent->graph_mutex);
++}
++EXPORT_SYMBOL_GPL(media_entity_remove_links);
++
+ static int __media_entity_setup_link_notify(struct media_link *link, u32 flags)
+ {
+       int ret;
+diff --git a/include/media/media-entity.h b/include/media/media-entity.h
+index 4eefedc..06bacf9 100644
+--- a/include/media/media-entity.h
++++ b/include/media/media-entity.h
+@@ -128,6 +128,9 @@ void media_entity_cleanup(struct media_entity *entity);
+ int media_entity_create_link(struct media_entity *source, u16 source_pad,
+               struct media_entity *sink, u16 sink_pad, u32 flags);
++void __media_entity_remove_links(struct media_entity *entity);
++void media_entity_remove_links(struct media_entity *entity);
++
+ int __media_entity_setup_link(struct media_link *link, u32 flags);
+ int media_entity_setup_link(struct media_link *link, u32 flags);
+ struct media_link *media_entity_find_link(struct media_pad *source,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0205-media-V4L-Remove-all-links-of-the-media-entity-when-.patch b/patches.tizen/0205-media-V4L-Remove-all-links-of-the-media-entity-when-.patch
new file mode 100644 (file)
index 0000000..b4e31ce
--- /dev/null
@@ -0,0 +1,46 @@
+From e50f95c025680f791d67967e1c0447415f67fbf6 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 9 May 2013 08:29:33 -0300
+Subject: [PATCH 0205/1302] [media] V4L: Remove all links of the media entity
+ when unregistering subdev
+
+Remove all links of the subdev's media entity after internal_ops
+'unregistered' call and right before unregistering the entity from
+a media device.
+It is assumed here that an unregistered (orphan) media entity cannot
+have links to other entities registered to a media device.
+It is also assumed the media links should be created/removed with
+the media graph's mutex held.
+The above implies that the caller of v4l2_device_unregister_subdev()
+must not hold the graph's mutex.
+
+Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Sakari Ailus <sakari.ailus@iki.fi>
+Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/v4l2-core/v4l2-device.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c
+index 8ed5da2..2dbfebc0 100644
+--- a/drivers/media/v4l2-core/v4l2-device.c
++++ b/drivers/media/v4l2-core/v4l2-device.c
+@@ -269,8 +269,10 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd)
+       sd->v4l2_dev = NULL;
+ #if defined(CONFIG_MEDIA_CONTROLLER)
+-      if (v4l2_dev->mdev)
++      if (v4l2_dev->mdev) {
++              media_entity_remove_links(&sd->entity);
+               media_device_unregister_entity(&sd->entity);
++      }
+ #endif
+       video_unregister_device(sd->devnode);
+       module_put(sd->owner);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0206-s5c73m3-Do-not-ignore-errors-from-regulator_enable.patch b/patches.tizen/0206-s5c73m3-Do-not-ignore-errors-from-regulator_enable.patch
new file mode 100644 (file)
index 0000000..66bea1c
--- /dev/null
@@ -0,0 +1,45 @@
+From e709dfed98a95a19621910b4e8a5202a2a83116b Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Sat, 1 Jun 2013 00:43:35 +0200
+Subject: [PATCH 0206/1302] s5c73m3: Do not ignore errors from
+ regulator_enable()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This fixes following compilation warning:
+
+drivers/media/i2c/s5c73m3/s5c73m3-core.c: In function ‘__s5c73m3_power_off’:
+drivers/media/i2c/s5c73m3/s5c73m3-core.c:1389:19: warning: ignoring return value
+of ‘regulator_enable’, declared with attribute warn_unused_result
+
+Cc: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/s5c73m3/s5c73m3-core.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+index 77f59fa..b79e100 100644
+--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
++++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+@@ -1386,9 +1386,12 @@ static int __s5c73m3_power_off(struct s5c73m3 *state)
+       }
+       return 0;
+ err:
+-      for (++i; i < S5C73M3_MAX_SUPPLIES; i++)
+-              regulator_enable(state->supplies[i].consumer);
+-
++      for (++i; i < S5C73M3_MAX_SUPPLIES; i++) {
++              int r = regulator_enable(state->supplies[i].consumer);
++              if (r < 0)
++                      v4l2_err(&state->oif_sd, "Failed to reenable %s: %d\n",
++                               state->supplies[i].supply, r);
++      }
+       return ret;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0207-media-exynos4-is-Remove-redundant-NULL-check-in-fimc.patch b/patches.tizen/0207-media-exynos4-is-Remove-redundant-NULL-check-in-fimc.patch
new file mode 100644 (file)
index 0000000..f2241ea
--- /dev/null
@@ -0,0 +1,49 @@
+From 0b2dc66accfc533cf1405a391cda69a99a0fe3df Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Tue, 30 Apr 2013 00:51:33 -0300
+Subject: [PATCH 0207/1302] [media] exynos4-is: Remove redundant NULL check in
+ fimc-lite.c
+
+clk_unprepare checks for NULL pointer. Hence convert IS_ERR_OR_NULL
+to IS_ERR only.
+[s.nawrocki: replaced initialisations to NULL with ERR_PTR() value]
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-lite.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
+index 2f11ae4..80ebf43 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite.c
++++ b/drivers/media/platform/exynos4-is/fimc-lite.c
+@@ -1417,12 +1417,12 @@ static void fimc_lite_unregister_capture_subdev(struct fimc_lite *fimc)
+ static void fimc_lite_clk_put(struct fimc_lite *fimc)
+ {
+-      if (IS_ERR_OR_NULL(fimc->clock))
++      if (IS_ERR(fimc->clock))
+               return;
+       clk_unprepare(fimc->clock);
+       clk_put(fimc->clock);
+-      fimc->clock = NULL;
++      fimc->clock = ERR_PTR(-EINVAL);
+ }
+ static int fimc_lite_clk_get(struct fimc_lite *fimc)
+@@ -1436,7 +1436,7 @@ static int fimc_lite_clk_get(struct fimc_lite *fimc)
+       ret = clk_prepare(fimc->clock);
+       if (ret < 0) {
+               clk_put(fimc->clock);
+-              fimc->clock = NULL;
++              fimc->clock = ERR_PTR(-EINVAL);
+       }
+       return ret;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0208-media-exynos4-is-Remove-platform_device_id-table-at-.patch b/patches.tizen/0208-media-exynos4-is-Remove-platform_device_id-table-at-.patch
new file mode 100644 (file)
index 0000000..08739bb
--- /dev/null
@@ -0,0 +1,59 @@
+From 01e780c5ae17a4c4fb3610cda5540efe2e1e82e3 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Tue, 30 Apr 2013 09:27:08 -0300
+Subject: [PATCH 0208/1302] [media] exynos4-is: Remove platform_device_id table
+ at fimc-lite driver
+
+The driver id_table is unused since all SoCs containing the FIMC-LITE
+IP block have been dt-only. Just remove it.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-lite.c | 14 ++------------
+ 1 file changed, 2 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
+index 80ebf43..d770f33 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite.c
++++ b/drivers/media/platform/exynos4-is/fimc-lite.c
+@@ -1,8 +1,8 @@
+ /*
+  * Samsung EXYNOS FIMC-LITE (camera host interface) driver
+ *
+- * Copyright (C) 2012 Samsung Electronics Co., Ltd.
+- * Sylwester Nawrocki <s.nawrocki@samsung.com>
++ * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
++ * Author: Sylwester Nawrocki <s.nawrocki@samsung.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
+@@ -1626,15 +1626,6 @@ static struct flite_drvdata fimc_lite_drvdata_exynos4 = {
+       .out_hor_offs_align     = 8,
+ };
+-static struct platform_device_id fimc_lite_driver_ids[] = {
+-      {
+-              .name           = "exynos-fimc-lite",
+-              .driver_data    = (unsigned long)&fimc_lite_drvdata_exynos4,
+-      },
+-      { /* sentinel */ },
+-};
+-MODULE_DEVICE_TABLE(platform, fimc_lite_driver_ids);
+-
+ static const struct of_device_id flite_of_match[] = {
+       {
+               .compatible = "samsung,exynos4212-fimc-lite",
+@@ -1647,7 +1638,6 @@ MODULE_DEVICE_TABLE(of, flite_of_match);
+ static struct platform_driver fimc_lite_driver = {
+       .probe          = fimc_lite_probe,
+       .remove         = fimc_lite_remove,
+-      .id_table       = fimc_lite_driver_ids,
+       .driver = {
+               .of_match_table = flite_of_match,
+               .name           = FIMC_LITE_DRV_NAME,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0209-media-exynos4-is-Correct-querycap-ioctl-handling-at-.patch b/patches.tizen/0209-media-exynos4-is-Correct-querycap-ioctl-handling-at-.patch
new file mode 100644 (file)
index 0000000..f3231bf
--- /dev/null
@@ -0,0 +1,57 @@
+From 4b4b5b8b5831489744648a1bc49040a5f37ef267 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Tue, 30 Apr 2013 09:27:53 -0300
+Subject: [PATCH 0209/1302] [media] exynos4-is: Correct querycap ioctl handling
+ at fimc-lite driver
+
+Fill in properly bus_info and card fields and set device_caps.
+The querycap ioctl handler is renamed for consistency with the
+other ioctls.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-lite.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
+index d770f33..5634799 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite.c
++++ b/drivers/media/platform/exynos4-is/fimc-lite.c
+@@ -637,13 +637,18 @@ static void fimc_lite_try_compose(struct fimc_lite *fimc, struct v4l2_rect *r)
+ /*
+  * Video node ioctl operations
+  */
+-static int fimc_vidioc_querycap_capture(struct file *file, void *priv,
++static int fimc_lite_querycap(struct file *file, void *priv,
+                                       struct v4l2_capability *cap)
+ {
++      struct fimc_lite *fimc = video_drvdata(file);
++
+       strlcpy(cap->driver, FIMC_LITE_DRV_NAME, sizeof(cap->driver));
+-      cap->bus_info[0] = 0;
+-      cap->card[0] = 0;
+-      cap->capabilities = V4L2_CAP_STREAMING;
++      strlcpy(cap->card, FIMC_LITE_DRV_NAME, sizeof(cap->card));
++      snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
++                                      dev_name(&fimc->pdev->dev));
++
++      cap->device_caps = V4L2_CAP_STREAMING;
++      cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+       return 0;
+ }
+@@ -938,7 +943,7 @@ static int fimc_lite_s_selection(struct file *file, void *fh,
+ }
+ static const struct v4l2_ioctl_ops fimc_lite_ioctl_ops = {
+-      .vidioc_querycap                = fimc_vidioc_querycap_capture,
++      .vidioc_querycap                = fimc_lite_querycap,
+       .vidioc_enum_fmt_vid_cap_mplane = fimc_lite_enum_fmt_mplane,
+       .vidioc_try_fmt_vid_cap_mplane  = fimc_lite_try_fmt_mplane,
+       .vidioc_s_fmt_vid_cap_mplane    = fimc_lite_s_fmt_mplane,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0210-media-exynos4-is-Staticize-local-symbols.patch b/patches.tizen/0210-media-exynos4-is-Staticize-local-symbols.patch
new file mode 100644 (file)
index 0000000..4394f42
--- /dev/null
@@ -0,0 +1,80 @@
+From 9a45a3b630360d4fabff206b691fd3cc4e75106e Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Tue, 16 Apr 2013 02:02:21 -0300
+Subject: [PATCH 0210/1302] [media] exynos4-is: Staticize local symbols
+
+These symbols are used only in their respective files and hence
+should be made static.
+[s.nawrocki@samsung.com: dropped the __fimc_is_hw_update_param()
+ function change]
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-is-i2c.c   | 2 +-
+ drivers/media/platform/exynos4-is/fimc-is-param.c | 4 ++--
+ drivers/media/platform/exynos4-is/fimc-is.c       | 4 ++--
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-is-i2c.c b/drivers/media/platform/exynos4-is/fimc-is-i2c.c
+index c397777..617a798 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is-i2c.c
++++ b/drivers/media/platform/exynos4-is/fimc-is-i2c.c
+@@ -96,7 +96,7 @@ static int fimc_is_i2c_resume(struct device *dev)
+       return clk_prepare_enable(isp_i2c->clock);
+ }
+-UNIVERSAL_DEV_PM_OPS(fimc_is_i2c_pm_ops, fimc_is_i2c_suspend,
++static UNIVERSAL_DEV_PM_OPS(fimc_is_i2c_pm_ops, fimc_is_i2c_suspend,
+                    fimc_is_i2c_resume, NULL);
+ static const struct of_device_id fimc_is_i2c_of_match[] = {
+diff --git a/drivers/media/platform/exynos4-is/fimc-is-param.c b/drivers/media/platform/exynos4-is/fimc-is-param.c
+index 53fe2a2..c435db0 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is-param.c
++++ b/drivers/media/platform/exynos4-is/fimc-is-param.c
+@@ -38,7 +38,7 @@ static void __hw_param_copy(void *dst, void *src)
+       memcpy(dst, src, FIMC_IS_PARAM_MAX_SIZE);
+ }
+-void __fimc_is_hw_update_param_global_shotmode(struct fimc_is *is)
++static void __fimc_is_hw_update_param_global_shotmode(struct fimc_is *is)
+ {
+       struct param_global_shotmode *dst, *src;
+@@ -47,7 +47,7 @@ void __fimc_is_hw_update_param_global_shotmode(struct fimc_is *is)
+       __hw_param_copy(dst, src);
+ }
+-void __fimc_is_hw_update_param_sensor_framerate(struct fimc_is *is)
++static void __fimc_is_hw_update_param_sensor_framerate(struct fimc_is *is)
+ {
+       struct param_sensor_framerate *dst, *src;
+diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c
+index 0741945..b127d08 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is.c
++++ b/drivers/media/platform/exynos4-is/fimc-is.c
+@@ -129,7 +129,7 @@ static int fimc_is_setup_clocks(struct fimc_is *is)
+                                       ATCLK_MCUISP_FREQUENCY);
+ }
+-int fimc_is_enable_clocks(struct fimc_is *is)
++static int fimc_is_enable_clocks(struct fimc_is *is)
+ {
+       int i, ret;
+@@ -149,7 +149,7 @@ int fimc_is_enable_clocks(struct fimc_is *is)
+       return 0;
+ }
+-void fimc_is_disable_clocks(struct fimc_is *is)
++static void fimc_is_disable_clocks(struct fimc_is *is)
+ {
+       int i;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0211-media-exynos4-is-Move-common-functions-to-a-separate.patch b/patches.tizen/0211-media-exynos4-is-Move-common-functions-to-a-separate.patch
new file mode 100644 (file)
index 0000000..c27b4d2
--- /dev/null
@@ -0,0 +1,206 @@
+From 45e2440860d70e94120f143b713692508799d974 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Mon, 10 Jun 2013 08:51:44 -0300
+Subject: [PATCH 0211/1302] [media] exynos4-is: Move common functions to a
+ separate module
+
+Create a common module (exynos4-is-common.ko) for common functions
+used across the exynos4-is video device and subdev drivers.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/Kconfig     |  7 ++++-
+ drivers/media/platform/exynos4-is/Makefile    |  5 +++-
+ drivers/media/platform/exynos4-is/common.c    | 41 +++++++++++++++++++++++++++
+ drivers/media/platform/exynos4-is/common.h    | 12 ++++++++
+ drivers/media/platform/exynos4-is/fimc-lite.c | 29 ++-----------------
+ 5 files changed, 66 insertions(+), 28 deletions(-)
+ create mode 100644 drivers/media/platform/exynos4-is/common.c
+ create mode 100644 drivers/media/platform/exynos4-is/common.h
+
+diff --git a/drivers/media/platform/exynos4-is/Kconfig b/drivers/media/platform/exynos4-is/Kconfig
+index 6ff99b5..c622532 100644
+--- a/drivers/media/platform/exynos4-is/Kconfig
++++ b/drivers/media/platform/exynos4-is/Kconfig
+@@ -8,12 +8,16 @@ config VIDEO_SAMSUNG_EXYNOS4_IS
+ if VIDEO_SAMSUNG_EXYNOS4_IS
++config VIDEO_EXYNOS4_IS_COMMON
++       tristate
++
+ config VIDEO_S5P_FIMC
+       tristate "S5P/EXYNOS4 FIMC/CAMIF camera interface driver"
+       depends on I2C
+       select VIDEOBUF2_DMA_CONTIG
+       select V4L2_MEM2MEM_DEV
+       select MFD_SYSCON if OF
++      select VIDEO_EXYNOS4_IS_COMMON
+       help
+         This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC camera host
+         interface and video postprocessor (FIMC) devices.
+@@ -38,6 +42,7 @@ config VIDEO_EXYNOS_FIMC_LITE
+       tristate "EXYNOS FIMC-LITE camera interface driver"
+       depends on I2C
+       select VIDEOBUF2_DMA_CONTIG
++      select VIDEO_EXYNOS4_IS_COMMON
+       help
+         This is a V4L2 driver for Samsung EXYNOS4/5 SoC FIMC-LITE camera
+         host interface.
+@@ -58,4 +63,4 @@ config VIDEO_EXYNOS4_FIMC_IS
+         To compile this driver as a module, choose M here: the
+         module will be called exynos4-fimc-is.
+-endif # VIDEO_SAMSUNG_S5P_FIMC
++endif # VIDEO_SAMSUNG_EXYNOS4_IS
+diff --git a/drivers/media/platform/exynos4-is/Makefile b/drivers/media/platform/exynos4-is/Makefile
+index f25f463..c2ff29b 100644
+--- a/drivers/media/platform/exynos4-is/Makefile
++++ b/drivers/media/platform/exynos4-is/Makefile
+@@ -1,10 +1,13 @@
+ s5p-fimc-objs := fimc-core.o fimc-reg.o fimc-m2m.o fimc-capture.o media-dev.o
+ exynos-fimc-lite-objs += fimc-lite-reg.o fimc-lite.o
++s5p-csis-objs := mipi-csis.o
++exynos4-is-common-objs := common.o
++
+ exynos-fimc-is-objs := fimc-is.o fimc-isp.o fimc-is-sensor.o fimc-is-regs.o
+ exynos-fimc-is-objs += fimc-is-param.o fimc-is-errno.o fimc-is-i2c.o
+-s5p-csis-objs := mipi-csis.o
+ obj-$(CONFIG_VIDEO_S5P_MIPI_CSIS)     += s5p-csis.o
+ obj-$(CONFIG_VIDEO_EXYNOS_FIMC_LITE)  += exynos-fimc-lite.o
+ obj-$(CONFIG_VIDEO_EXYNOS4_FIMC_IS)   += exynos-fimc-is.o
+ obj-$(CONFIG_VIDEO_S5P_FIMC)          += s5p-fimc.o
++obj-$(CONFIG_VIDEO_EXYNOS4_IS_COMMON) += exynos4-is-common.o
+diff --git a/drivers/media/platform/exynos4-is/common.c b/drivers/media/platform/exynos4-is/common.c
+new file mode 100644
+index 0000000..57f9010
+--- /dev/null
++++ b/drivers/media/platform/exynos4-is/common.c
+@@ -0,0 +1,41 @@
++/*
++ * Samsung S5P/EXYNOS4 SoC Camera Subsystem driver
++ *
++ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
++ * Author: Sylwester Nawrocki <s.nawrocki@samsung.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/module.h>
++#include <media/s5p_fimc.h>
++#include "common.h"
++
++/* Called with the media graph mutex held or entity->stream_count > 0. */
++struct v4l2_subdev *fimc_find_remote_sensor(struct media_entity *entity)
++{
++      struct media_pad *pad = &entity->pads[0];
++      struct v4l2_subdev *sd;
++
++      while (pad->flags & MEDIA_PAD_FL_SINK) {
++              /* source pad */
++              pad = media_entity_remote_pad(pad);
++              if (pad == NULL ||
++                  media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
++                      break;
++
++              sd = media_entity_to_v4l2_subdev(pad->entity);
++
++              if (sd->grp_id == GRP_ID_FIMC_IS_SENSOR ||
++                  sd->grp_id == GRP_ID_SENSOR)
++                      return sd;
++              /* sink pad */
++              pad = &sd->entity.pads[0];
++      }
++      return NULL;
++}
++EXPORT_SYMBOL(fimc_find_remote_sensor);
++
++MODULE_LICENSE("GPL");
+diff --git a/drivers/media/platform/exynos4-is/common.h b/drivers/media/platform/exynos4-is/common.h
+new file mode 100644
+index 0000000..3c39803
+--- /dev/null
++++ b/drivers/media/platform/exynos4-is/common.h
+@@ -0,0 +1,12 @@
++/*
++ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
++ *
++ * 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 <media/media-entity.h>
++#include <media/v4l2-subdev.h>
++
++struct v4l2_subdev *fimc_find_remote_sensor(struct media_entity *entity);
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
+index 5634799..6daa885 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite.c
++++ b/drivers/media/platform/exynos4-is/fimc-lite.c
+@@ -32,6 +32,7 @@
+ #include <media/videobuf2-dma-contig.h>
+ #include <media/s5p_fimc.h>
++#include "common.h"
+ #include "fimc-core.h"
+ #include "fimc-lite.h"
+ #include "fimc-lite-reg.h"
+@@ -131,30 +132,6 @@ static const struct fimc_fmt *fimc_lite_find_format(const u32 *pixelformat,
+       return def_fmt;
+ }
+-/* Called with the media graph mutex held or @me stream_count > 0. */
+-static struct v4l2_subdev *__find_remote_sensor(struct media_entity *me)
+-{
+-      struct media_pad *pad = &me->pads[0];
+-      struct v4l2_subdev *sd;
+-
+-      while (pad->flags & MEDIA_PAD_FL_SINK) {
+-              /* source pad */
+-              pad = media_entity_remote_pad(pad);
+-              if (pad == NULL ||
+-                  media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+-                      break;
+-
+-              sd = media_entity_to_v4l2_subdev(pad->entity);
+-
+-              if (sd->grp_id == GRP_ID_FIMC_IS_SENSOR ||
+-                  sd->grp_id == GRP_ID_SENSOR)
+-                      return sd;
+-              /* sink pad */
+-              pad = &sd->entity.pads[0];
+-      }
+-      return NULL;
+-}
+-
+ static int fimc_lite_hw_init(struct fimc_lite *fimc, bool isp_output)
+ {
+       struct fimc_source_info *si;
+@@ -830,7 +807,7 @@ static int fimc_lite_streamon(struct file *file, void *priv,
+       if (ret < 0)
+               goto err_p_stop;
+-      fimc->sensor = __find_remote_sensor(&fimc->subdev.entity);
++      fimc->sensor = fimc_find_remote_sensor(&fimc->subdev.entity);
+       ret = vb2_ioctl_streamon(file, priv, type);
+       if (!ret) {
+@@ -1212,7 +1189,7 @@ static int fimc_lite_subdev_s_stream(struct v4l2_subdev *sd, int on)
+        * The pipeline links are protected through entity.stream_count
+        * so there is no need to take the media graph mutex here.
+        */
+-      fimc->sensor = __find_remote_sensor(&sd->entity);
++      fimc->sensor = fimc_find_remote_sensor(&sd->entity);
+       if (atomic_read(&fimc->out_path) != FIMC_IO_ISP)
+               return -ENOIOCTLCMD;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0212-media-exynos4-is-Add-struct-exynos_video_entity.patch b/patches.tizen/0212-media-exynos4-is-Add-struct-exynos_video_entity.patch
new file mode 100644 (file)
index 0000000..bb389de
--- /dev/null
@@ -0,0 +1,456 @@
+From f8851e794aceb7609ee85fa1e45d75fb855e84b3 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 31 May 2013 11:37:18 -0300
+Subject: [PATCH 0212/1302] [media] exynos4-is: Add struct exynos_video_entity
+
+This patch introduces common structure for the video entities
+to handle all video nodes and media pipelines associated with
+them in more generic way.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-capture.c  | 43 +++++++++++++----------
+ drivers/media/platform/exynos4-is/fimc-core.h     |  4 +--
+ drivers/media/platform/exynos4-is/fimc-lite-reg.c |  2 +-
+ drivers/media/platform/exynos4-is/fimc-lite.c     | 20 +++++------
+ drivers/media/platform/exynos4-is/fimc-lite.h     |  4 +--
+ drivers/media/platform/exynos4-is/fimc-reg.c      |  7 ++--
+ drivers/media/platform/exynos4-is/media-dev.c     |  4 +--
+ drivers/media/platform/exynos4-is/media-dev.h     |  8 ++---
+ include/media/s5p_fimc.h                          |  5 +++
+ 9 files changed, 55 insertions(+), 42 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
+index a8b9b06..b80ca59 100644
+--- a/drivers/media/platform/exynos4-is/fimc-capture.c
++++ b/drivers/media/platform/exynos4-is/fimc-capture.c
+@@ -320,6 +320,7 @@ static void buffer_queue(struct vb2_buffer *vb);
+ int fimc_capture_resume(struct fimc_dev *fimc)
+ {
+       struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
++      struct exynos_video_entity *ve = &vid_cap->ve;
+       struct fimc_vid_buffer *buf;
+       int i;
+@@ -329,7 +330,7 @@ int fimc_capture_resume(struct fimc_dev *fimc)
+       INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
+       vid_cap->buf_index = 0;
+       fimc_pipeline_call(fimc, open, &fimc->pipeline,
+-                         &vid_cap->vfd.entity, false);
++                         &ve->vdev.entity, false);
+       fimc_capture_hw_init(fimc);
+       clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
+@@ -397,7 +398,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
+               unsigned long size = ctx->d_frame.payload[i];
+               if (vb2_plane_size(vb, i) < size) {
+-                      v4l2_err(&ctx->fimc_dev->vid_cap.vfd,
++                      v4l2_err(&ctx->fimc_dev->vid_cap.ve.vdev,
+                                "User buffer too small (%ld < %ld)\n",
+                                vb2_plane_size(vb, i), size);
+                       return -EINVAL;
+@@ -415,6 +416,7 @@ static void buffer_queue(struct vb2_buffer *vb)
+       struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+       struct fimc_dev *fimc = ctx->fimc_dev;
+       struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
++      struct exynos_video_entity *ve = &vid_cap->ve;
+       unsigned long flags;
+       int min_bufs;
+@@ -454,7 +456,7 @@ static void buffer_queue(struct vb2_buffer *vb)
+               ret = fimc_pipeline_call(fimc, set_stream, &fimc->pipeline, 1);
+               if (ret < 0)
+-                      v4l2_err(&vid_cap->vfd, "stream on failed: %d\n", ret);
++                      v4l2_err(&ve->vdev, "stream on failed: %d\n", ret);
+               return;
+       }
+       spin_unlock_irqrestore(&fimc->slock, flags);
+@@ -503,11 +505,12 @@ static int fimc_capture_set_default_format(struct fimc_dev *fimc);
+ static int fimc_capture_open(struct file *file)
+ {
+       struct fimc_dev *fimc = video_drvdata(file);
++      struct exynos_video_entity *ve = &fimc->vid_cap.ve;
+       int ret = -EBUSY;
+       dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
+-      fimc_md_graph_lock(fimc);
++      fimc_md_graph_lock(ve);
+       mutex_lock(&fimc->lock);
+       if (fimc_m2m_active(fimc))
+@@ -526,7 +529,7 @@ static int fimc_capture_open(struct file *file)
+       if (v4l2_fh_is_singular_file(file)) {
+               ret = fimc_pipeline_call(fimc, open, &fimc->pipeline,
+-                                       &fimc->vid_cap.vfd.entity, true);
++                                       &fimc->vid_cap.ve.vdev.entity, true);
+               if (!ret && !fimc->vid_cap.user_subdev_api)
+                       ret = fimc_capture_set_default_format(fimc);
+@@ -544,7 +547,7 @@ static int fimc_capture_open(struct file *file)
+       }
+ unlock:
+       mutex_unlock(&fimc->lock);
+-      fimc_md_graph_unlock(fimc);
++      fimc_md_graph_unlock(ve);
+       return ret;
+ }
+@@ -560,7 +563,7 @@ static int fimc_capture_release(struct file *file)
+       if (v4l2_fh_is_singular_file(file)) {
+               if (vc->streaming) {
+-                      media_entity_pipeline_stop(&vc->vfd.entity);
++                      media_entity_pipeline_stop(&vc->ve.vdev.entity);
+                       vc->streaming = false;
+               }
+               clear_bit(ST_CAPT_BUSY, &fimc->state);
+@@ -935,11 +938,12 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
+       struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
+       struct fimc_dev *fimc = video_drvdata(file);
+       struct fimc_ctx *ctx = fimc->vid_cap.ctx;
++      struct exynos_video_entity *ve = &fimc->vid_cap.ve;
+       struct v4l2_mbus_framefmt mf;
+       struct fimc_fmt *ffmt = NULL;
+       int ret = 0;
+-      fimc_md_graph_lock(fimc);
++      fimc_md_graph_lock(ve);
+       mutex_lock(&fimc->lock);
+       if (fimc_jpeg_fourcc(pix->pixelformat)) {
+@@ -975,7 +979,7 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
+                                       pix->plane_fmt, ffmt->memplanes, true);
+ unlock:
+       mutex_unlock(&fimc->lock);
+-      fimc_md_graph_unlock(fimc);
++      fimc_md_graph_unlock(ve);
+       return ret;
+ }
+@@ -1076,7 +1080,7 @@ static int fimc_cap_s_fmt_mplane(struct file *file, void *priv,
+       struct fimc_dev *fimc = video_drvdata(file);
+       int ret;
+-      fimc_md_graph_lock(fimc);
++      fimc_md_graph_lock(&fimc->vid_cap.ve);
+       mutex_lock(&fimc->lock);
+       /*
+        * The graph is walked within __fimc_capture_set_format() to set
+@@ -1088,8 +1092,8 @@ static int fimc_cap_s_fmt_mplane(struct file *file, void *priv,
+        */
+       ret = __fimc_capture_set_format(fimc, f);
++      fimc_md_graph_unlock(&fimc->vid_cap.ve);
+       mutex_unlock(&fimc->lock);
+-      fimc_md_graph_unlock(fimc);
+       return ret;
+ }
+@@ -1209,7 +1213,7 @@ static int fimc_cap_streamon(struct file *file, void *priv,
+       struct fimc_dev *fimc = video_drvdata(file);
+       struct fimc_pipeline *p = &fimc->pipeline;
+       struct fimc_vid_cap *vc = &fimc->vid_cap;
+-      struct media_entity *entity = &vc->vfd.entity;
++      struct media_entity *entity = &vc->ve.vdev.entity;
+       struct fimc_source_info *si = NULL;
+       struct v4l2_subdev *sd;
+       int ret;
+@@ -1259,14 +1263,15 @@ static int fimc_cap_streamoff(struct file *file, void *priv,
+                           enum v4l2_buf_type type)
+ {
+       struct fimc_dev *fimc = video_drvdata(file);
++      struct fimc_vid_cap *vc = &fimc->vid_cap;
+       int ret;
+       ret = vb2_ioctl_streamoff(file, priv, type);
+       if (ret < 0)
+               return ret;
+-      media_entity_pipeline_stop(&fimc->vid_cap.vfd.entity);
+-      fimc->vid_cap.streaming = false;
++      media_entity_pipeline_stop(&vc->ve.vdev.entity);
++      vc->streaming = false;
+       return 0;
+ }
+@@ -1735,7 +1740,7 @@ static int fimc_capture_set_default_format(struct fimc_dev *fimc)
+ static int fimc_register_capture_device(struct fimc_dev *fimc,
+                                struct v4l2_device *v4l2_dev)
+ {
+-      struct video_device *vfd = &fimc->vid_cap.vfd;
++      struct video_device *vfd = &fimc->vid_cap.ve.vdev;
+       struct vb2_queue *q = &fimc->vid_cap.vbq;
+       struct fimc_ctx *ctx;
+       struct fimc_vid_cap *vid_cap;
+@@ -1840,15 +1845,17 @@ static int fimc_capture_subdev_registered(struct v4l2_subdev *sd)
+ static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd)
+ {
+       struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
++      struct video_device *vdev;
+       if (fimc == NULL)
+               return;
+       fimc_unregister_m2m_device(fimc);
++      vdev = &fimc->vid_cap.ve.vdev;
+-      if (video_is_registered(&fimc->vid_cap.vfd)) {
+-              video_unregister_device(&fimc->vid_cap.vfd);
+-              media_entity_cleanup(&fimc->vid_cap.vfd.entity);
++      if (video_is_registered(vdev)) {
++              video_unregister_device(vdev);
++              media_entity_cleanup(&vdev->entity);
+               fimc->pipeline_ops = NULL;
+       }
+       kfree(fimc->vid_cap.ctx);
+diff --git a/drivers/media/platform/exynos4-is/fimc-core.h b/drivers/media/platform/exynos4-is/fimc-core.h
+index 8666e4b..401b746 100644
+--- a/drivers/media/platform/exynos4-is/fimc-core.h
++++ b/drivers/media/platform/exynos4-is/fimc-core.h
+@@ -285,8 +285,8 @@ struct fimc_m2m_device {
+ /**
+  * struct fimc_vid_cap - camera capture device information
+  * @ctx: hardware context data
+- * @vfd: video device node for camera capture mode
+  * @subdev: subdev exposing the FIMC processing block
++ * @ve: exynos video device entity structure
+  * @vd_pad: fimc video capture node pad
+  * @sd_pads: fimc video processing block pads
+  * @ci_fmt: image format at the FIMC camera input (and the scaler output)
+@@ -307,8 +307,8 @@ struct fimc_m2m_device {
+ struct fimc_vid_cap {
+       struct fimc_ctx                 *ctx;
+       struct vb2_alloc_ctx            *alloc_ctx;
+-      struct video_device             vfd;
+       struct v4l2_subdev              subdev;
++      struct exynos_video_entity      ve;
+       struct media_pad                vd_pad;
+       struct media_pad                sd_pads[FIMC_SD_PADS_NUM];
+       struct v4l2_mbus_framefmt       ci_fmt;
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite-reg.c b/drivers/media/platform/exynos4-is/fimc-lite-reg.c
+index 8cc0d39..eb4f763 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite-reg.c
++++ b/drivers/media/platform/exynos4-is/fimc-lite-reg.c
+@@ -137,7 +137,7 @@ void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f)
+       }
+       if (i == 0 && src_pixfmt_map[i][0] != pixelcode) {
+-              v4l2_err(&dev->vfd,
++              v4l2_err(&dev->ve.vdev,
+                        "Unsupported pixel code, falling back to %#08x\n",
+                        src_pixfmt_map[i][0]);
+       }
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
+index 6daa885..64198b8 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite.c
++++ b/drivers/media/platform/exynos4-is/fimc-lite.c
+@@ -392,7 +392,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
+               unsigned long size = fimc->payload[i];
+               if (vb2_plane_size(vb, i) < size) {
+-                      v4l2_err(&fimc->vfd,
++                      v4l2_err(&fimc->ve.vdev,
+                                "User buffer too small (%ld < %ld)\n",
+                                vb2_plane_size(vb, i), size);
+                       return -EINVAL;
+@@ -458,7 +458,7 @@ static void fimc_lite_clear_event_counters(struct fimc_lite *fimc)
+ static int fimc_lite_open(struct file *file)
+ {
+       struct fimc_lite *fimc = video_drvdata(file);
+-      struct media_entity *me = &fimc->vfd.entity;
++      struct media_entity *me = &fimc->ve.vdev.entity;
+       int ret;
+       mutex_lock(&me->parent->graph_mutex);
+@@ -509,7 +509,7 @@ static int fimc_lite_release(struct file *file)
+       if (v4l2_fh_is_singular_file(file) &&
+           atomic_read(&fimc->out_path) == FIMC_IO_DMA) {
+               if (fimc->streaming) {
+-                      media_entity_pipeline_stop(&fimc->vfd.entity);
++                      media_entity_pipeline_stop(&fimc->ve.vdev.entity);
+                       fimc->streaming = false;
+               }
+               clear_bit(ST_FLITE_IN_USE, &fimc->state);
+@@ -792,7 +792,7 @@ static int fimc_lite_streamon(struct file *file, void *priv,
+                             enum v4l2_buf_type type)
+ {
+       struct fimc_lite *fimc = video_drvdata(file);
+-      struct media_entity *entity = &fimc->vfd.entity;
++      struct media_entity *entity = &fimc->ve.vdev.entity;
+       struct fimc_pipeline *p = &fimc->pipeline;
+       int ret;
+@@ -830,7 +830,7 @@ static int fimc_lite_streamoff(struct file *file, void *priv,
+       if (ret < 0)
+               return ret;
+-      media_entity_pipeline_stop(&fimc->vfd.entity);
++      media_entity_pipeline_stop(&fimc->ve.vdev.entity);
+       fimc->streaming = false;
+       return 0;
+ }
+@@ -1234,7 +1234,7 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
+ {
+       struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
+       struct vb2_queue *q = &fimc->vb_queue;
+-      struct video_device *vfd = &fimc->vfd;
++      struct video_device *vfd = &fimc->ve.vdev;
+       int ret;
+       memset(vfd, 0, sizeof(*vfd));
+@@ -1298,9 +1298,9 @@ static void fimc_lite_subdev_unregistered(struct v4l2_subdev *sd)
+       if (fimc == NULL)
+               return;
+-      if (video_is_registered(&fimc->vfd)) {
+-              video_unregister_device(&fimc->vfd);
+-              media_entity_cleanup(&fimc->vfd.entity);
++      if (video_is_registered(&fimc->ve.vdev)) {
++              video_unregister_device(&fimc->ve.vdev);
++              media_entity_cleanup(&fimc->ve.vdev.entity);
+               fimc->pipeline_ops = NULL;
+       }
+ }
+@@ -1548,7 +1548,7 @@ static int fimc_lite_resume(struct device *dev)
+       INIT_LIST_HEAD(&fimc->active_buf_q);
+       fimc_pipeline_call(fimc, open, &fimc->pipeline,
+-                         &fimc->vfd.entity, false);
++                         &fimc->ve.vdev.entity, false);
+       fimc_lite_hw_init(fimc, atomic_read(&fimc->out_path) == FIMC_IO_ISP);
+       clear_bit(ST_FLITE_SUSPENDED, &fimc->state);
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite.h b/drivers/media/platform/exynos4-is/fimc-lite.h
+index 47da5e0..fa3886a 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite.h
++++ b/drivers/media/platform/exynos4-is/fimc-lite.h
+@@ -95,8 +95,8 @@ struct flite_buffer {
+  * struct fimc_lite - fimc lite structure
+  * @pdev: pointer to FIMC-LITE platform device
+  * @dd: SoC specific driver data structure
++ * @ve: exynos video device entity structure
+  * @v4l2_dev: pointer to top the level v4l2_device
+- * @vfd: video device node
+  * @fh: v4l2 file handle
+  * @alloc_ctx: videobuf2 memory allocator context
+  * @subdev: FIMC-LITE subdev
+@@ -130,8 +130,8 @@ struct flite_buffer {
+ struct fimc_lite {
+       struct platform_device  *pdev;
+       struct flite_drvdata    *dd;
++      struct exynos_video_entity ve;
+       struct v4l2_device      *v4l2_dev;
+-      struct video_device     vfd;
+       struct v4l2_fh          fh;
+       struct vb2_alloc_ctx    *alloc_ctx;
+       struct v4l2_subdev      subdev;
+diff --git a/drivers/media/platform/exynos4-is/fimc-reg.c b/drivers/media/platform/exynos4-is/fimc-reg.c
+index f079f36..1db8cb4 100644
+--- a/drivers/media/platform/exynos4-is/fimc-reg.c
++++ b/drivers/media/platform/exynos4-is/fimc-reg.c
+@@ -618,7 +618,7 @@ int fimc_hw_set_camera_source(struct fimc_dev *fimc,
+               }
+               if (i == ARRAY_SIZE(pix_desc)) {
+-                      v4l2_err(&vc->vfd,
++                      v4l2_err(&vc->ve.vdev,
+                                "Camera color format not supported: %d\n",
+                                vc->ci_fmt.code);
+                       return -EINVAL;
+@@ -698,7 +698,7 @@ int fimc_hw_set_camera_type(struct fimc_dev *fimc,
+                       cfg |= FIMC_REG_CIGCTRL_CAM_JPEG;
+                       break;
+               default:
+-                      v4l2_err(&vid_cap->vfd,
++                      v4l2_err(&vid_cap->ve.vdev,
+                                "Not supported camera pixel format: %#x\n",
+                                vid_cap->ci_fmt.code);
+                       return -EINVAL;
+@@ -721,7 +721,8 @@ int fimc_hw_set_camera_type(struct fimc_dev *fimc,
+                       WARN_ONCE(1, "ISP Writeback input is not supported\n");
+               break;
+       default:
+-              v4l2_err(&vid_cap->vfd, "Invalid FIMC bus type selected: %d\n",
++              v4l2_err(&vid_cap->ve.vdev,
++                       "Invalid FIMC bus type selected: %d\n",
+                        source->fimc_bus_type);
+               return -EINVAL;
+       }
+diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
+index 7f94842..d487d87 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.c
++++ b/drivers/media/platform/exynos4-is/media-dev.c
+@@ -929,7 +929,7 @@ static int __fimc_md_create_flite_source_links(struct fimc_md *fmd)
+                       continue;
+               source = &fimc->subdev.entity;
+-              sink = &fimc->vfd.entity;
++              sink = &fimc->ve.vdev.entity;
+               /* FIMC-LITE's subdev and video node */
+               ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_DMA,
+                                              sink, 0, 0);
+@@ -1066,7 +1066,7 @@ static int fimc_md_create_links(struct fimc_md *fmd)
+                       continue;
+               source = &fmd->fimc[i]->vid_cap.subdev.entity;
+-              sink = &fmd->fimc[i]->vid_cap.vfd.entity;
++              sink = &fmd->fimc[i]->vid_cap.ve.vdev.entity;
+               ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE,
+                                             sink, 0, flags);
+diff --git a/drivers/media/platform/exynos4-is/media-dev.h b/drivers/media/platform/exynos4-is/media-dev.h
+index 44d86b6..3e9680c 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.h
++++ b/drivers/media/platform/exynos4-is/media-dev.h
+@@ -127,14 +127,14 @@ static inline struct fimc_md *entity_to_fimc_mdev(struct media_entity *me)
+               container_of(me->parent, struct fimc_md, media_dev);
+ }
+-static inline void fimc_md_graph_lock(struct fimc_dev *fimc)
++static inline void fimc_md_graph_lock(struct exynos_video_entity *ve)
+ {
+-      mutex_lock(&fimc->vid_cap.vfd.entity.parent->graph_mutex);
++      mutex_lock(&ve->vdev.entity.parent->graph_mutex);
+ }
+-static inline void fimc_md_graph_unlock(struct fimc_dev *fimc)
++static inline void fimc_md_graph_unlock(struct exynos_video_entity *ve)
+ {
+-      mutex_unlock(&fimc->vid_cap.vfd.entity.parent->graph_mutex);
++      mutex_unlock(&ve->vdev.entity.parent->graph_mutex);
+ }
+ int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on);
+diff --git a/include/media/s5p_fimc.h b/include/media/s5p_fimc.h
+index f509690..f5313b4 100644
+--- a/include/media/s5p_fimc.h
++++ b/include/media/s5p_fimc.h
+@@ -13,6 +13,7 @@
+ #define S5P_FIMC_H_
+ #include <media/media-entity.h>
++#include <media/v4l2-dev.h>
+ #include <media/v4l2-mediabus.h>
+ /*
+@@ -157,6 +158,10 @@ struct fimc_pipeline {
+       struct media_pipeline *m_pipeline;
+ };
++struct exynos_video_entity {
++      struct video_device vdev;
++};
++
+ /*
+  * Media pipeline operations to be called from within the fimc(-lite)
+  * video node when it is the last entity of the pipeline. Implemented
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0213-media-exynos4-is-Preserve-state-of-controls-between-.patch b/patches.tizen/0213-media-exynos4-is-Preserve-state-of-controls-between-.patch
new file mode 100644 (file)
index 0000000..694e102
--- /dev/null
@@ -0,0 +1,265 @@
+From 2928e68c6d98ddeea077778f9de27531723065db Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 31 May 2013 11:37:19 -0300
+Subject: [PATCH 0213/1302] [media] exynos4-is: Preserve state of controls
+ between /dev/video open/close
+
+This patch moves the code for inheriting subdev v4l2 controls on the
+FIMC video capture nodes from open()/close() fops to the link setup
+notification callback. This allows for the state of the FIMC controls
+to be always kept, in opposite to the current situation when it is
+lost when last process closes video device.
+There is no visible change for the original V4L2 compliant interface.
+For the MC aware applications (user_subdev_api == true) inheriting
+of the controls is dropped, since there can be same controls on the
+subdevs withing single pipeline, now when the ISP (FIMC-IS) is also
+used.
+This patch is a prerequisite to allow /dev/video device to be opened
+without errors even if there is no media links connecting it to an
+image source (sensor) subdev. This is required for a libv4l2 plugin
+to be initialized while a video node is opened and it also should be
+possible to always open the device to query the capabilities.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-capture.c | 96 ++++++++++++------------
+ drivers/media/platform/exynos4-is/fimc-core.h    |  3 +
+ drivers/media/platform/exynos4-is/media-dev.c    |  4 -
+ 3 files changed, 50 insertions(+), 53 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
+index b80ca59..07089de 100644
+--- a/drivers/media/platform/exynos4-is/fimc-capture.c
++++ b/drivers/media/platform/exynos4-is/fimc-capture.c
+@@ -27,9 +27,10 @@
+ #include <media/videobuf2-core.h>
+ #include <media/videobuf2-dma-contig.h>
+-#include "media-dev.h"
++#include "common.h"
+ #include "fimc-core.h"
+ #include "fimc-reg.h"
++#include "media-dev.h"
+ static int fimc_capture_hw_init(struct fimc_dev *fimc)
+ {
+@@ -472,40 +473,13 @@ static struct vb2_ops fimc_capture_qops = {
+       .stop_streaming         = stop_streaming,
+ };
+-/**
+- * fimc_capture_ctrls_create - initialize the control handler
+- * Initialize the capture video node control handler and fill it
+- * with the FIMC controls. Inherit any sensor's controls if the
+- * 'user_subdev_api' flag is false (default behaviour).
+- * This function need to be called with the graph mutex held.
+- */
+-int fimc_capture_ctrls_create(struct fimc_dev *fimc)
+-{
+-      struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
+-      struct v4l2_subdev *sensor = fimc->pipeline.subdevs[IDX_SENSOR];
+-      int ret;
+-
+-      if (WARN_ON(vid_cap->ctx == NULL))
+-              return -ENXIO;
+-      if (vid_cap->ctx->ctrls.ready)
+-              return 0;
+-
+-      ret = fimc_ctrls_create(vid_cap->ctx);
+-
+-      if (ret || vid_cap->user_subdev_api || !sensor ||
+-          !vid_cap->ctx->ctrls.ready)
+-              return ret;
+-
+-      return v4l2_ctrl_add_handler(&vid_cap->ctx->ctrls.handler,
+-                                   sensor->ctrl_handler, NULL);
+-}
+-
+ static int fimc_capture_set_default_format(struct fimc_dev *fimc);
+ static int fimc_capture_open(struct file *file)
+ {
+       struct fimc_dev *fimc = video_drvdata(file);
+-      struct exynos_video_entity *ve = &fimc->vid_cap.ve;
++      struct fimc_vid_cap *vc = &fimc->vid_cap;
++      struct exynos_video_entity *ve = &vc->ve;
+       int ret = -EBUSY;
+       dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
+@@ -530,12 +504,20 @@ static int fimc_capture_open(struct file *file)
+       if (v4l2_fh_is_singular_file(file)) {
+               ret = fimc_pipeline_call(fimc, open, &fimc->pipeline,
+                                        &fimc->vid_cap.ve.vdev.entity, true);
+-
+-              if (!ret && !fimc->vid_cap.user_subdev_api)
++              if (ret == 0)
+                       ret = fimc_capture_set_default_format(fimc);
+-              if (!ret)
+-                      ret = fimc_capture_ctrls_create(fimc);
++              if (ret == 0 && vc->user_subdev_api && vc->inh_sensor_ctrls) {
++                      /*
++                       * Recreate controls of the the video node to drop
++                       * any controls inherited from the sensor subdev.
++                       */
++                      fimc_ctrls_delete(vc->ctx);
++
++                      ret = fimc_ctrls_create(vc->ctx);
++                      if (ret == 0)
++                              vc->inh_sensor_ctrls = false;
++              }
+               if (ret < 0) {
+                       clear_bit(ST_CAPT_BUSY, &fimc->state);
+@@ -574,10 +556,6 @@ static int fimc_capture_release(struct file *file)
+       }
+       pm_runtime_put(&fimc->pdev->dev);
+-
+-      if (v4l2_fh_is_singular_file(file))
+-              fimc_ctrls_delete(fimc->vid_cap.ctx);
+-
+       ret = vb2_fop_release(file);
+       mutex_unlock(&fimc->lock);
+@@ -1410,6 +1388,8 @@ static int fimc_link_setup(struct media_entity *entity,
+ {
+       struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
+       struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
++      struct fimc_vid_cap *vc = &fimc->vid_cap;
++      struct v4l2_subdev *sensor;
+       if (media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+               return -EINVAL;
+@@ -1421,15 +1401,26 @@ static int fimc_link_setup(struct media_entity *entity,
+           local->entity->name, remote->entity->name, flags,
+           fimc->vid_cap.input);
+-      if (flags & MEDIA_LNK_FL_ENABLED) {
+-              if (fimc->vid_cap.input != 0)
+-                      return -EBUSY;
+-              fimc->vid_cap.input = sd->grp_id;
++      if (!(flags & MEDIA_LNK_FL_ENABLED)) {
++              fimc->vid_cap.input = 0;
+               return 0;
+       }
+-      fimc->vid_cap.input = 0;
+-      return 0;
++      if (vc->input != 0)
++              return -EBUSY;
++
++      vc->input = sd->grp_id;
++
++      if (vc->user_subdev_api || vc->inh_sensor_ctrls)
++              return 0;
++
++      /* Inherit V4L2 controls from the image sensor subdev. */
++      sensor = fimc_find_remote_sensor(&vc->subdev.entity);
++      if (sensor == NULL)
++              return 0;
++
++      return v4l2_ctrl_add_handler(&vc->ctx->ctrls.handler,
++                                   sensor->ctrl_handler, NULL);
+ }
+ static const struct media_entity_operations fimc_sd_media_ops = {
+@@ -1789,12 +1780,16 @@ static int fimc_register_capture_device(struct fimc_dev *fimc,
+       ret = vb2_queue_init(q);
+       if (ret)
+-              goto err_ent;
++              goto err_free_ctx;
+       vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK;
+       ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad, 0);
+       if (ret)
+-              goto err_ent;
++              goto err_free_ctx;
++
++      ret = fimc_ctrls_create(ctx);
++      if (ret)
++              goto err_me_cleanup;
+       /*
+        * For proper order of acquiring/releasing the video
+        * and the graph mutex.
+@@ -1804,7 +1799,7 @@ static int fimc_register_capture_device(struct fimc_dev *fimc,
+       ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
+       if (ret)
+-              goto err_vd;
++              goto err_ctrl_free;
+       v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n",
+                 vfd->name, video_device_node_name(vfd));
+@@ -1812,9 +1807,11 @@ static int fimc_register_capture_device(struct fimc_dev *fimc,
+       vfd->ctrl_handler = &ctx->ctrls.handler;
+       return 0;
+-err_vd:
++err_ctrl_free:
++      fimc_ctrls_delete(ctx);
++err_me_cleanup:
+       media_entity_cleanup(&vfd->entity);
+-err_ent:
++err_free_ctx:
+       kfree(ctx);
+       return ret;
+ }
+@@ -1856,6 +1853,7 @@ static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd)
+       if (video_is_registered(vdev)) {
+               video_unregister_device(vdev);
+               media_entity_cleanup(&vdev->entity);
++              fimc_ctrls_delete(fimc->vid_cap.ctx);
+               fimc->pipeline_ops = NULL;
+       }
+       kfree(fimc->vid_cap.ctx);
+diff --git a/drivers/media/platform/exynos4-is/fimc-core.h b/drivers/media/platform/exynos4-is/fimc-core.h
+index 401b746..86bb8e6 100644
+--- a/drivers/media/platform/exynos4-is/fimc-core.h
++++ b/drivers/media/platform/exynos4-is/fimc-core.h
+@@ -303,6 +303,8 @@ struct fimc_m2m_device {
+  * @refcnt: driver's private reference counter
+  * @input: capture input type, grp_id of the attached subdev
+  * @user_subdev_api: true if subdevs are not configured by the host driver
++ * @inh_sensor_ctrls: a flag indicating v4l2 controls are inherited from
++ *                  an image sensor subdev
+  */
+ struct fimc_vid_cap {
+       struct fimc_ctx                 *ctx;
+@@ -326,6 +328,7 @@ struct fimc_vid_cap {
+       int                             refcnt;
+       u32                             input;
+       bool                            user_subdev_api;
++      bool                            inh_sensor_ctrls;
+ };
+ /**
+diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
+index d487d87..d4ee88f 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.c
++++ b/drivers/media/platform/exynos4-is/media-dev.c
+@@ -1272,8 +1272,6 @@ static int fimc_md_link_notify(struct media_pad *source,
+       if (!(flags & MEDIA_LNK_FL_ENABLED)) {
+               if (ref_count > 0) {
+                       ret = __fimc_pipeline_close(pipeline);
+-                      if (!ret && fimc)
+-                              fimc_ctrls_delete(fimc->vid_cap.ctx);
+               }
+               for (i = 0; i < IDX_MAX; i++)
+                       pipeline->subdevs[i] = NULL;
+@@ -1285,8 +1283,6 @@ static int fimc_md_link_notify(struct media_pad *source,
+                */
+               ret = __fimc_pipeline_open(pipeline,
+                                          source->entity, true);
+-              if (!ret && fimc)
+-                      ret = fimc_capture_ctrls_create(fimc);
+       }
+       mutex_unlock(lock);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0214-media-exynos4-is-Media-graph-video-device-locking-re.patch b/patches.tizen/0214-media-exynos4-is-Media-graph-video-device-locking-re.patch
new file mode 100644 (file)
index 0000000..5605b24
--- /dev/null
@@ -0,0 +1,365 @@
+From 6bba13b08408e0ccaa2af3bebf63d85cbc46c70e Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 31 May 2013 11:37:20 -0300
+Subject: [PATCH 0214/1302] [media] exynos4-is: Media graph/video device
+ locking rework
+
+Remove driver private video node reference counters and use entity->use_count
+instead. This makes the video pipelines power handling more similar to the
+method used in omap3isp driver.
+Now the graph mutex is taken always after the video mutex, as it is not
+possible to ensure apposite order at the all modules.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-capture.c | 59 +++++++++++-------------
+ drivers/media/platform/exynos4-is/fimc-core.h    |  2 -
+ drivers/media/platform/exynos4-is/fimc-lite.c    | 23 +++++----
+ drivers/media/platform/exynos4-is/fimc-lite.h    |  2 -
+ drivers/media/platform/exynos4-is/media-dev.c    | 12 +----
+ 5 files changed, 42 insertions(+), 56 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
+index 07089de..b6055d2 100644
+--- a/drivers/media/platform/exynos4-is/fimc-capture.c
++++ b/drivers/media/platform/exynos4-is/fimc-capture.c
+@@ -484,7 +484,6 @@ static int fimc_capture_open(struct file *file)
+       dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
+-      fimc_md_graph_lock(ve);
+       mutex_lock(&fimc->lock);
+       if (fimc_m2m_active(fimc))
+@@ -502,6 +501,8 @@ static int fimc_capture_open(struct file *file)
+       }
+       if (v4l2_fh_is_singular_file(file)) {
++              fimc_md_graph_lock(ve);
++
+               ret = fimc_pipeline_call(fimc, open, &fimc->pipeline,
+                                        &fimc->vid_cap.ve.vdev.entity, true);
+               if (ret == 0)
+@@ -518,18 +519,19 @@ static int fimc_capture_open(struct file *file)
+                       if (ret == 0)
+                               vc->inh_sensor_ctrls = false;
+               }
++              if (ret == 0)
++                      ve->vdev.entity.use_count++;
++
++              fimc_md_graph_unlock(ve);
+               if (ret < 0) {
+                       clear_bit(ST_CAPT_BUSY, &fimc->state);
+                       pm_runtime_put_sync(&fimc->pdev->dev);
+                       v4l2_fh_release(file);
+-              } else {
+-                      fimc->vid_cap.refcnt++;
+               }
+       }
+ unlock:
+       mutex_unlock(&fimc->lock);
+-      fimc_md_graph_unlock(ve);
+       return ret;
+ }
+@@ -537,26 +539,32 @@ static int fimc_capture_release(struct file *file)
+ {
+       struct fimc_dev *fimc = video_drvdata(file);
+       struct fimc_vid_cap *vc = &fimc->vid_cap;
++      bool close = v4l2_fh_is_singular_file(file);
+       int ret;
+       dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
+       mutex_lock(&fimc->lock);
+-      if (v4l2_fh_is_singular_file(file)) {
+-              if (vc->streaming) {
+-                      media_entity_pipeline_stop(&vc->ve.vdev.entity);
+-                      vc->streaming = false;
+-              }
++      if (close && vc->streaming) {
++              media_entity_pipeline_stop(&vc->ve.vdev.entity);
++              vc->streaming = false;
++      }
++
++      ret = vb2_fop_release(file);
++
++      if (close) {
+               clear_bit(ST_CAPT_BUSY, &fimc->state);
+               fimc_stop_capture(fimc, false);
+               fimc_pipeline_call(fimc, close, &fimc->pipeline);
+               clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
+-              fimc->vid_cap.refcnt--;
++
++              fimc_md_graph_lock(&vc->ve);
++              vc->ve.vdev.entity.use_count--;
++              fimc_md_graph_unlock(&vc->ve);
+       }
+       pm_runtime_put(&fimc->pdev->dev);
+-      ret = vb2_fop_release(file);
+       mutex_unlock(&fimc->lock);
+       return ret;
+@@ -921,9 +929,6 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
+       struct fimc_fmt *ffmt = NULL;
+       int ret = 0;
+-      fimc_md_graph_lock(ve);
+-      mutex_lock(&fimc->lock);
+-
+       if (fimc_jpeg_fourcc(pix->pixelformat)) {
+               fimc_capture_try_format(ctx, &pix->width, &pix->height,
+                                       NULL, &pix->pixelformat,
+@@ -934,16 +939,18 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
+       ffmt = fimc_capture_try_format(ctx, &pix->width, &pix->height,
+                                      NULL, &pix->pixelformat,
+                                      FIMC_SD_PAD_SOURCE);
+-      if (!ffmt) {
+-              ret = -EINVAL;
+-              goto unlock;
+-      }
++      if (!ffmt)
++              return -EINVAL;
+       if (!fimc->vid_cap.user_subdev_api) {
+               mf.width = pix->width;
+               mf.height = pix->height;
+               mf.code = ffmt->mbus_code;
++
++              fimc_md_graph_lock(ve);
+               fimc_pipeline_try_format(ctx, &mf, &ffmt, false);
++              fimc_md_graph_unlock(ve);
++
+               pix->width = mf.width;
+               pix->height = mf.height;
+               if (ffmt)
+@@ -955,9 +962,6 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
+       if (ffmt->flags & FMT_FLAGS_COMPRESSED)
+               fimc_get_sensor_frame_desc(fimc->pipeline.subdevs[IDX_SENSOR],
+                                       pix->plane_fmt, ffmt->memplanes, true);
+-unlock:
+-      mutex_unlock(&fimc->lock);
+-      fimc_md_graph_unlock(ve);
+       return ret;
+ }
+@@ -1059,19 +1063,14 @@ static int fimc_cap_s_fmt_mplane(struct file *file, void *priv,
+       int ret;
+       fimc_md_graph_lock(&fimc->vid_cap.ve);
+-      mutex_lock(&fimc->lock);
+       /*
+        * The graph is walked within __fimc_capture_set_format() to set
+        * the format at subdevs thus the graph mutex needs to be held at
+-       * this point and acquired before the video mutex, to avoid  AB-BA
+-       * deadlock when fimc_md_link_notify() is called by other thread.
+-       * Ideally the graph walking and setting format at the whole pipeline
+-       * should be removed from this driver and handled in userspace only.
++       * this point.
+        */
+       ret = __fimc_capture_set_format(fimc, f);
+       fimc_md_graph_unlock(&fimc->vid_cap.ve);
+-      mutex_unlock(&fimc->lock);
+       return ret;
+ }
+@@ -1790,12 +1789,6 @@ static int fimc_register_capture_device(struct fimc_dev *fimc,
+       ret = fimc_ctrls_create(ctx);
+       if (ret)
+               goto err_me_cleanup;
+-      /*
+-       * For proper order of acquiring/releasing the video
+-       * and the graph mutex.
+-       */
+-      v4l2_disable_ioctl_locking(vfd, VIDIOC_TRY_FMT);
+-      v4l2_disable_ioctl_locking(vfd, VIDIOC_S_FMT);
+       ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
+       if (ret)
+diff --git a/drivers/media/platform/exynos4-is/fimc-core.h b/drivers/media/platform/exynos4-is/fimc-core.h
+index 86bb8e6..09c061d 100644
+--- a/drivers/media/platform/exynos4-is/fimc-core.h
++++ b/drivers/media/platform/exynos4-is/fimc-core.h
+@@ -300,7 +300,6 @@ struct fimc_m2m_device {
+  * @frame_count: the frame counter for statistics
+  * @reqbufs_count: the number of buffers requested in REQBUFS ioctl
+  * @input_index: input (camera sensor) index
+- * @refcnt: driver's private reference counter
+  * @input: capture input type, grp_id of the attached subdev
+  * @user_subdev_api: true if subdevs are not configured by the host driver
+  * @inh_sensor_ctrls: a flag indicating v4l2 controls are inherited from
+@@ -325,7 +324,6 @@ struct fimc_vid_cap {
+       unsigned int                    reqbufs_count;
+       bool                            streaming;
+       int                             input_index;
+-      int                             refcnt;
+       u32                             input;
+       bool                            user_subdev_api;
+       bool                            inh_sensor_ctrls;
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
+index 64198b8..0f372bf 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite.c
++++ b/drivers/media/platform/exynos4-is/fimc-lite.c
+@@ -461,8 +461,6 @@ static int fimc_lite_open(struct file *file)
+       struct media_entity *me = &fimc->ve.vdev.entity;
+       int ret;
+-      mutex_lock(&me->parent->graph_mutex);
+-
+       mutex_lock(&fimc->lock);
+       if (atomic_read(&fimc->out_path) != FIMC_IO_DMA) {
+               ret = -EBUSY;
+@@ -482,11 +480,19 @@ static int fimc_lite_open(struct file *file)
+           atomic_read(&fimc->out_path) != FIMC_IO_DMA)
+               goto unlock;
++      mutex_lock(&me->parent->graph_mutex);
++
+       ret = fimc_pipeline_call(fimc, open, &fimc->pipeline,
+                                               me, true);
++
++      /* Mark video pipeline ending at this video node as in use. */
++      if (ret == 0)
++              me->use_count++;
++
++      mutex_unlock(&me->parent->graph_mutex);
++
+       if (!ret) {
+               fimc_lite_clear_event_counters(fimc);
+-              fimc->ref_count++;
+               goto unlock;
+       }
+@@ -496,26 +502,28 @@ err_pm:
+       clear_bit(ST_FLITE_IN_USE, &fimc->state);
+ unlock:
+       mutex_unlock(&fimc->lock);
+-      mutex_unlock(&me->parent->graph_mutex);
+       return ret;
+ }
+ static int fimc_lite_release(struct file *file)
+ {
+       struct fimc_lite *fimc = video_drvdata(file);
++      struct media_entity *entity = &fimc->ve.vdev.entity;
+       mutex_lock(&fimc->lock);
+       if (v4l2_fh_is_singular_file(file) &&
+           atomic_read(&fimc->out_path) == FIMC_IO_DMA) {
+               if (fimc->streaming) {
+-                      media_entity_pipeline_stop(&fimc->ve.vdev.entity);
++                      media_entity_pipeline_stop(entity);
+                       fimc->streaming = false;
+               }
+               clear_bit(ST_FLITE_IN_USE, &fimc->state);
+               fimc_lite_stop_capture(fimc, false);
+               fimc_pipeline_call(fimc, close, &fimc->pipeline);
+-              fimc->ref_count--;
++              mutex_lock(&entity->parent->graph_mutex);
++              entity->use_count--;
++              mutex_unlock(&entity->parent->graph_mutex);
+       }
+       vb2_fop_release(file);
+@@ -954,8 +962,6 @@ static int fimc_lite_link_setup(struct media_entity *entity,
+                __func__, remote->entity->name, local->entity->name,
+                flags, fimc->source_subdev_grp_id);
+-      mutex_lock(&fimc->lock);
+-
+       switch (local->index) {
+       case FLITE_SD_PAD_SINK:
+               if (remote_ent_type != MEDIA_ENT_T_V4L2_SUBDEV) {
+@@ -997,7 +1003,6 @@ static int fimc_lite_link_setup(struct media_entity *entity,
+       }
+       mb();
+-      mutex_unlock(&fimc->lock);
+       return ret;
+ }
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite.h b/drivers/media/platform/exynos4-is/fimc-lite.h
+index fa3886a..25abba9 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite.h
++++ b/drivers/media/platform/exynos4-is/fimc-lite.h
+@@ -125,7 +125,6 @@ struct flite_buffer {
+  * @active_buf_count: number of video buffers scheduled in hardware
+  * @frame_count: the captured frames counter
+  * @reqbufs_count: the number of buffers requested with REQBUFS ioctl
+- * @ref_count: driver's private reference counter
+  */
+ struct fimc_lite {
+       struct platform_device  *pdev;
+@@ -163,7 +162,6 @@ struct fimc_lite {
+       struct vb2_queue        vb_queue;
+       unsigned int            frame_count;
+       unsigned int            reqbufs_count;
+-      int                     ref_count;
+       struct fimc_lite_events events;
+       bool                    streaming;
+diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
+index d4ee88f..a0b9931 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.c
++++ b/drivers/media/platform/exynos4-is/media-dev.c
+@@ -1238,9 +1238,7 @@ static int fimc_md_link_notify(struct media_pad *source,
+       struct fimc_dev *fimc = NULL;
+       struct fimc_pipeline *pipeline;
+       struct v4l2_subdev *sd;
+-      struct mutex *lock;
+       int i, ret = 0;
+-      int ref_count;
+       if (media_entity_type(sink->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+               return 0;
+@@ -1253,29 +1251,24 @@ static int fimc_md_link_notify(struct media_pad *source,
+               if (WARN_ON(fimc_lite == NULL))
+                       return 0;
+               pipeline = &fimc_lite->pipeline;
+-              lock = &fimc_lite->lock;
+               break;
+       case GRP_ID_FIMC:
+               fimc = v4l2_get_subdevdata(sd);
+               if (WARN_ON(fimc == NULL))
+                       return 0;
+               pipeline = &fimc->pipeline;
+-              lock = &fimc->lock;
+               break;
+       default:
+               return 0;
+       }
+-      mutex_lock(lock);
+-      ref_count = fimc ? fimc->vid_cap.refcnt : fimc_lite->ref_count;
+-
+       if (!(flags & MEDIA_LNK_FL_ENABLED)) {
+-              if (ref_count > 0) {
++              if (sink->entity->use_count > 0) {
+                       ret = __fimc_pipeline_close(pipeline);
+               }
+               for (i = 0; i < IDX_MAX; i++)
+                       pipeline->subdevs[i] = NULL;
+-      } else if (ref_count > 0) {
++      } else if (sink->entity->use_count > 0) {
+               /*
+                * Link activation. Enable power of pipeline elements only if
+                * the pipeline is already in use, i.e. its video node is open.
+@@ -1285,7 +1278,6 @@ static int fimc_md_link_notify(struct media_pad *source,
+                                          source->entity, true);
+       }
+-      mutex_unlock(lock);
+       return ret ? -EPIPE : ret;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0215-media-exynos4-is-Do-not-use-asynchronous-runtime-PM-.patch b/patches.tizen/0215-media-exynos4-is-Do-not-use-asynchronous-runtime-PM-.patch
new file mode 100644 (file)
index 0000000..37d2d36
--- /dev/null
@@ -0,0 +1,43 @@
+From 37616e197963d2b782758711393545dc77abd26f Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 31 May 2013 11:37:21 -0300
+Subject: [PATCH 0215/1302] [media] exynos4-is: Do not use asynchronous runtime
+ PM in release fop
+
+Use pm_runtime_put_sync() instead of pm_runtime_put() to avoid races
+in handling the 'state' bit flags when the fimc-capture drivers'
+runtime_resume callback is called from the PM workqueue.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-capture.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
+index b6055d2..b2f9581 100644
+--- a/drivers/media/platform/exynos4-is/fimc-capture.c
++++ b/drivers/media/platform/exynos4-is/fimc-capture.c
+@@ -496,7 +496,7 @@ static int fimc_capture_open(struct file *file)
+       ret = v4l2_fh_open(file);
+       if (ret) {
+-              pm_runtime_put(&fimc->pdev->dev);
++              pm_runtime_put_sync(&fimc->pdev->dev);
+               goto unlock;
+       }
+@@ -564,7 +564,7 @@ static int fimc_capture_release(struct file *file)
+               fimc_md_graph_unlock(&vc->ve);
+       }
+-      pm_runtime_put(&fimc->pdev->dev);
++      pm_runtime_put_sync(&fimc->pdev->dev);
+       mutex_unlock(&fimc->lock);
+       return ret;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0216-media-exynos4-is-Use-common-exynos_media_pipeline-da.patch b/patches.tizen/0216-media-exynos4-is-Use-common-exynos_media_pipeline-da.patch
new file mode 100644 (file)
index 0000000..34327fc
--- /dev/null
@@ -0,0 +1,769 @@
+From 4791daa5d1d1d1a72600e30232eeb0a04ea83136 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 31 May 2013 11:37:22 -0300
+Subject: [PATCH 0216/1302] [media] exynos4-is: Use common
+ exynos_media_pipeline data structure
+
+This enumeration is now private to exynos4-is and the exynos5 camera
+subsystem driver may have the subdevs handling designed differently.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-capture.c |  67 ++++++++------
+ drivers/media/platform/exynos4-is/fimc-core.h    |   2 -
+ drivers/media/platform/exynos4-is/fimc-lite.c    |  29 +++---
+ drivers/media/platform/exynos4-is/fimc-lite.h    |   2 -
+ drivers/media/platform/exynos4-is/media-dev.c    | 110 ++++++++++++++---------
+ drivers/media/platform/exynos4-is/media-dev.h    |  38 ++++++++
+ include/media/s5p_fimc.h                         |  53 ++++++-----
+ 7 files changed, 187 insertions(+), 114 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
+index b2f9581..33c6a2f 100644
+--- a/drivers/media/platform/exynos4-is/fimc-capture.c
++++ b/drivers/media/platform/exynos4-is/fimc-capture.c
+@@ -120,8 +120,7 @@ static int fimc_capture_state_cleanup(struct fimc_dev *fimc, bool suspend)
+       spin_unlock_irqrestore(&fimc->slock, flags);
+       if (streaming)
+-              return fimc_pipeline_call(fimc, set_stream,
+-                                        &fimc->pipeline, 0);
++              return fimc_pipeline_call(&cap->ve, set_stream, 0);
+       else
+               return 0;
+ }
+@@ -179,8 +178,9 @@ static int fimc_capture_config_update(struct fimc_ctx *ctx)
+ void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf)
+ {
+-      struct v4l2_subdev *csis = fimc->pipeline.subdevs[IDX_CSIS];
+       struct fimc_vid_cap *cap = &fimc->vid_cap;
++      struct fimc_pipeline *p = to_fimc_pipeline(cap->ve.pipe);
++      struct v4l2_subdev *csis = p->subdevs[IDX_CSIS];
+       struct fimc_frame *f = &cap->ctx->d_frame;
+       struct fimc_vid_buffer *v_buf;
+       struct timeval *tv;
+@@ -288,8 +288,7 @@ static int start_streaming(struct vb2_queue *q, unsigned int count)
+               fimc_activate_capture(ctx);
+               if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
+-                      return fimc_pipeline_call(fimc, set_stream,
+-                                                &fimc->pipeline, 1);
++                      return fimc_pipeline_call(&vid_cap->ve, set_stream, 1);
+       }
+       return 0;
+@@ -313,7 +312,7 @@ int fimc_capture_suspend(struct fimc_dev *fimc)
+       int ret = fimc_stop_capture(fimc, suspend);
+       if (ret)
+               return ret;
+-      return fimc_pipeline_call(fimc, close, &fimc->pipeline);
++      return fimc_pipeline_call(&fimc->vid_cap.ve, close);
+ }
+ static void buffer_queue(struct vb2_buffer *vb);
+@@ -330,8 +329,7 @@ int fimc_capture_resume(struct fimc_dev *fimc)
+       INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
+       vid_cap->buf_index = 0;
+-      fimc_pipeline_call(fimc, open, &fimc->pipeline,
+-                         &ve->vdev.entity, false);
++      fimc_pipeline_call(ve, open, &ve->vdev.entity, false);
+       fimc_capture_hw_init(fimc);
+       clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
+@@ -455,7 +453,7 @@ static void buffer_queue(struct vb2_buffer *vb)
+               if (test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
+                       return;
+-              ret = fimc_pipeline_call(fimc, set_stream, &fimc->pipeline, 1);
++              ret = fimc_pipeline_call(ve, set_stream, 1);
+               if (ret < 0)
+                       v4l2_err(&ve->vdev, "stream on failed: %d\n", ret);
+               return;
+@@ -503,8 +501,8 @@ static int fimc_capture_open(struct file *file)
+       if (v4l2_fh_is_singular_file(file)) {
+               fimc_md_graph_lock(ve);
+-              ret = fimc_pipeline_call(fimc, open, &fimc->pipeline,
+-                                       &fimc->vid_cap.ve.vdev.entity, true);
++              ret = fimc_pipeline_call(ve, open, &ve->vdev.entity, true);
++
+               if (ret == 0)
+                       ret = fimc_capture_set_default_format(fimc);
+@@ -555,8 +553,7 @@ static int fimc_capture_release(struct file *file)
+       if (close) {
+               clear_bit(ST_CAPT_BUSY, &fimc->state);
+-              fimc_stop_capture(fimc, false);
+-              fimc_pipeline_call(fimc, close, &fimc->pipeline);
++              fimc_pipeline_call(&vc->ve, close);
+               clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
+               fimc_md_graph_lock(&vc->ve);
+@@ -786,7 +783,8 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
+                                   bool set)
+ {
+       struct fimc_dev *fimc = ctx->fimc_dev;
+-      struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR];
++      struct fimc_pipeline *p = to_fimc_pipeline(fimc->vid_cap.ve.pipe);
++      struct v4l2_subdev *sd = p->subdevs[IDX_SENSOR];
+       struct v4l2_subdev_format sfmt;
+       struct v4l2_mbus_framefmt *mf = &sfmt.format;
+       struct media_entity *me;
+@@ -926,6 +924,7 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
+       struct fimc_ctx *ctx = fimc->vid_cap.ctx;
+       struct exynos_video_entity *ve = &fimc->vid_cap.ve;
+       struct v4l2_mbus_framefmt mf;
++      struct v4l2_subdev *sensor;
+       struct fimc_fmt *ffmt = NULL;
+       int ret = 0;
+@@ -959,9 +958,18 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
+       fimc_adjust_mplane_format(ffmt, pix->width, pix->height, pix);
+-      if (ffmt->flags & FMT_FLAGS_COMPRESSED)
+-              fimc_get_sensor_frame_desc(fimc->pipeline.subdevs[IDX_SENSOR],
+-                                      pix->plane_fmt, ffmt->memplanes, true);
++      if (ffmt->flags & FMT_FLAGS_COMPRESSED) {
++              fimc_md_graph_lock(ve);
++
++              sensor = __fimc_md_get_subdev(ve->pipe, IDX_SENSOR);
++              if (sensor)
++                      fimc_get_sensor_frame_desc(sensor, pix->plane_fmt,
++                                                 ffmt->memplanes, true);
++              else
++                      ret = -EPIPE;
++
++              fimc_md_graph_unlock(ve);
++      }
+       return ret;
+ }
+@@ -986,6 +994,7 @@ static int __fimc_capture_set_format(struct fimc_dev *fimc,
+       struct fimc_ctx *ctx = fimc->vid_cap.ctx;
+       struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
+       struct v4l2_mbus_framefmt *mf = &fimc->vid_cap.ci_fmt;
++      struct fimc_pipeline *p = to_fimc_pipeline(fimc->vid_cap.ve.pipe);
+       struct fimc_frame *ff = &ctx->d_frame;
+       struct fimc_fmt *s_fmt = NULL;
+       int ret, i;
+@@ -1027,7 +1036,7 @@ static int __fimc_capture_set_format(struct fimc_dev *fimc,
+       fimc_adjust_mplane_format(ff->fmt, pix->width, pix->height, pix);
+       if (ff->fmt->flags & FMT_FLAGS_COMPRESSED) {
+-              ret = fimc_get_sensor_frame_desc(fimc->pipeline.subdevs[IDX_SENSOR],
++              ret = fimc_get_sensor_frame_desc(p->subdevs[IDX_SENSOR],
+                                       pix->plane_fmt, ff->fmt->memplanes,
+                                       true);
+               if (ret < 0)
+@@ -1078,14 +1087,20 @@ static int fimc_cap_enum_input(struct file *file, void *priv,
+                              struct v4l2_input *i)
+ {
+       struct fimc_dev *fimc = video_drvdata(file);
+-      struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR];
++      struct exynos_video_entity *ve = &fimc->vid_cap.ve;
++      struct v4l2_subdev *sd;
+       if (i->index != 0)
+               return -EINVAL;
+       i->type = V4L2_INPUT_TYPE_CAMERA;
++      fimc_md_graph_lock(ve);
++      sd = __fimc_md_get_subdev(ve->pipe, IDX_SENSOR);
++      fimc_md_graph_unlock(ve);
++
+       if (sd)
+               strlcpy(i->name, sd->name, sizeof(i->name));
++
+       return 0;
+ }
+@@ -1111,6 +1126,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc)
+       struct v4l2_subdev_format sink_fmt, src_fmt;
+       struct fimc_vid_cap *vc = &fimc->vid_cap;
+       struct v4l2_subdev *sd = &vc->subdev;
++      struct fimc_pipeline *p = to_fimc_pipeline(vc->ve.pipe);
+       struct media_pad *sink_pad, *src_pad;
+       int i, ret;
+@@ -1164,7 +1180,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc)
+                   src_fmt.format.code != sink_fmt.format.code)
+                       return -EPIPE;
+-              if (sd == fimc->pipeline.subdevs[IDX_SENSOR] &&
++              if (sd == p->subdevs[IDX_SENSOR] &&
+                   fimc_user_defined_mbus_fmt(src_fmt.format.code)) {
+                       struct v4l2_plane_pix_format plane_fmt[FIMC_MAX_PLANES];
+                       struct fimc_frame *frame = &vc->ctx->d_frame;
+@@ -1188,7 +1204,6 @@ static int fimc_cap_streamon(struct file *file, void *priv,
+                            enum v4l2_buf_type type)
+ {
+       struct fimc_dev *fimc = video_drvdata(file);
+-      struct fimc_pipeline *p = &fimc->pipeline;
+       struct fimc_vid_cap *vc = &fimc->vid_cap;
+       struct media_entity *entity = &vc->ve.vdev.entity;
+       struct fimc_source_info *si = NULL;
+@@ -1198,11 +1213,11 @@ static int fimc_cap_streamon(struct file *file, void *priv,
+       if (fimc_capture_active(fimc))
+               return -EBUSY;
+-      ret = media_entity_pipeline_start(entity, p->m_pipeline);
++      ret = media_entity_pipeline_start(entity, &vc->ve.pipe->mp);
+       if (ret < 0)
+               return ret;
+-      sd = p->subdevs[IDX_SENSOR];
++      sd = __fimc_md_get_subdev(vc->ve.pipe, IDX_SENSOR);
+       if (sd)
+               si = v4l2_get_subdev_hostdata(sd);
+@@ -1821,12 +1836,12 @@ static int fimc_capture_subdev_registered(struct v4l2_subdev *sd)
+       if (ret)
+               return ret;
+-      fimc->pipeline_ops = v4l2_get_subdev_hostdata(sd);
++      fimc->vid_cap.ve.pipe = v4l2_get_subdev_hostdata(sd);
+       ret = fimc_register_capture_device(fimc, sd->v4l2_dev);
+       if (ret) {
+               fimc_unregister_m2m_device(fimc);
+-              fimc->pipeline_ops = NULL;
++              fimc->vid_cap.ve.pipe = NULL;
+       }
+       return ret;
+@@ -1847,7 +1862,7 @@ static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd)
+               video_unregister_device(vdev);
+               media_entity_cleanup(&vdev->entity);
+               fimc_ctrls_delete(fimc->vid_cap.ctx);
+-              fimc->pipeline_ops = NULL;
++              fimc->vid_cap.ve.pipe = NULL;
+       }
+       kfree(fimc->vid_cap.ctx);
+       fimc->vid_cap.ctx = NULL;
+diff --git a/drivers/media/platform/exynos4-is/fimc-core.h b/drivers/media/platform/exynos4-is/fimc-core.h
+index 09c061d..bba6b25 100644
+--- a/drivers/media/platform/exynos4-is/fimc-core.h
++++ b/drivers/media/platform/exynos4-is/fimc-core.h
+@@ -437,8 +437,6 @@ struct fimc_dev {
+       struct fimc_vid_cap             vid_cap;
+       unsigned long                   state;
+       struct vb2_alloc_ctx            *alloc_ctx;
+-      struct fimc_pipeline            pipeline;
+-      const struct fimc_pipeline_ops  *pipeline_ops;
+ };
+ /**
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
+index 0f372bf..24e2a0f 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite.c
++++ b/drivers/media/platform/exynos4-is/fimc-lite.c
+@@ -210,7 +210,7 @@ static int fimc_lite_reinit(struct fimc_lite *fimc, bool suspend)
+       if (!streaming)
+               return 0;
+-      return fimc_pipeline_call(fimc, set_stream, &fimc->pipeline, 0);
++      return fimc_pipeline_call(&fimc->ve, set_stream, 0);
+ }
+ static int fimc_lite_stop_capture(struct fimc_lite *fimc, bool suspend)
+@@ -324,8 +324,7 @@ static int start_streaming(struct vb2_queue *q, unsigned int count)
+               flite_hw_capture_start(fimc);
+               if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
+-                      fimc_pipeline_call(fimc, set_stream,
+-                                         &fimc->pipeline, 1);
++                      fimc_pipeline_call(&fimc->ve, set_stream, 1);
+       }
+       if (debug > 0)
+               flite_hw_dump_regs(fimc, __func__);
+@@ -429,8 +428,7 @@ static void buffer_queue(struct vb2_buffer *vb)
+               spin_unlock_irqrestore(&fimc->slock, flags);
+               if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
+-                      fimc_pipeline_call(fimc, set_stream,
+-                                         &fimc->pipeline, 1);
++                      fimc_pipeline_call(&fimc->ve, set_stream, 1);
+               return;
+       }
+       spin_unlock_irqrestore(&fimc->slock, flags);
+@@ -482,8 +480,7 @@ static int fimc_lite_open(struct file *file)
+       mutex_lock(&me->parent->graph_mutex);
+-      ret = fimc_pipeline_call(fimc, open, &fimc->pipeline,
+-                                              me, true);
++      ret = fimc_pipeline_call(&fimc->ve, open, me, true);
+       /* Mark video pipeline ending at this video node as in use. */
+       if (ret == 0)
+@@ -518,9 +515,10 @@ static int fimc_lite_release(struct file *file)
+                       media_entity_pipeline_stop(entity);
+                       fimc->streaming = false;
+               }
+-              clear_bit(ST_FLITE_IN_USE, &fimc->state);
+               fimc_lite_stop_capture(fimc, false);
+-              fimc_pipeline_call(fimc, close, &fimc->pipeline);
++              fimc_pipeline_call(&fimc->ve, close);
++              clear_bit(ST_FLITE_IN_USE, &fimc->state);
++
+               mutex_lock(&entity->parent->graph_mutex);
+               entity->use_count--;
+               mutex_unlock(&entity->parent->graph_mutex);
+@@ -801,13 +799,12 @@ static int fimc_lite_streamon(struct file *file, void *priv,
+ {
+       struct fimc_lite *fimc = video_drvdata(file);
+       struct media_entity *entity = &fimc->ve.vdev.entity;
+-      struct fimc_pipeline *p = &fimc->pipeline;
+       int ret;
+       if (fimc_lite_active(fimc))
+               return -EBUSY;
+-      ret = media_entity_pipeline_start(entity, p->m_pipeline);
++      ret = media_entity_pipeline_start(entity, &fimc->ve.pipe->mp);
+       if (ret < 0)
+               return ret;
+@@ -1282,12 +1279,12 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
+               return ret;
+       video_set_drvdata(vfd, fimc);
+-      fimc->pipeline_ops = v4l2_get_subdev_hostdata(sd);
++      fimc->ve.pipe = v4l2_get_subdev_hostdata(sd);
+       ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
+       if (ret < 0) {
+               media_entity_cleanup(&vfd->entity);
+-              fimc->pipeline_ops = NULL;
++              fimc->ve.pipe = NULL;
+               return ret;
+       }
+@@ -1306,7 +1303,7 @@ static void fimc_lite_subdev_unregistered(struct v4l2_subdev *sd)
+       if (video_is_registered(&fimc->ve.vdev)) {
+               video_unregister_device(&fimc->ve.vdev);
+               media_entity_cleanup(&fimc->ve.vdev.entity);
+-              fimc->pipeline_ops = NULL;
++              fimc->ve.pipe = NULL;
+       }
+ }
+@@ -1552,7 +1549,7 @@ static int fimc_lite_resume(struct device *dev)
+               return 0;
+       INIT_LIST_HEAD(&fimc->active_buf_q);
+-      fimc_pipeline_call(fimc, open, &fimc->pipeline,
++      fimc_pipeline_call(&fimc->ve, open,
+                          &fimc->ve.vdev.entity, false);
+       fimc_lite_hw_init(fimc, atomic_read(&fimc->out_path) == FIMC_IO_ISP);
+       clear_bit(ST_FLITE_SUSPENDED, &fimc->state);
+@@ -1579,7 +1576,7 @@ static int fimc_lite_suspend(struct device *dev)
+       if (ret < 0 || !fimc_lite_active(fimc))
+               return ret;
+-      return fimc_pipeline_call(fimc, close, &fimc->pipeline);
++      return fimc_pipeline_call(&fimc->ve, close);
+ }
+ #endif /* CONFIG_PM_SLEEP */
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite.h b/drivers/media/platform/exynos4-is/fimc-lite.h
+index 25abba9..c7aa084 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite.h
++++ b/drivers/media/platform/exynos4-is/fimc-lite.h
+@@ -140,8 +140,6 @@ struct fimc_lite {
+       struct v4l2_ctrl_handler ctrl_handler;
+       struct v4l2_ctrl        *test_pattern;
+       int                     index;
+-      struct fimc_pipeline    pipeline;
+-      const struct fimc_pipeline_ops *pipeline_ops;
+       struct mutex            lock;
+       spinlock_t              slock;
+diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
+index a0b9931..4062af2 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.c
++++ b/drivers/media/platform/exynos4-is/media-dev.c
+@@ -46,7 +46,7 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd,
+  * Caller holds the graph mutex.
+  */
+ static void fimc_pipeline_prepare(struct fimc_pipeline *p,
+-                                struct media_entity *me)
++                                      struct media_entity *me)
+ {
+       struct v4l2_subdev *sd;
+       int i;
+@@ -168,10 +168,11 @@ error:
+  *
+  * Called with the graph mutex held.
+  */
+-static int __fimc_pipeline_open(struct fimc_pipeline *p,
++static int __fimc_pipeline_open(struct exynos_media_pipeline *ep,
+                               struct media_entity *me, bool prepare)
+ {
+       struct fimc_md *fmd = entity_to_fimc_mdev(me);
++      struct fimc_pipeline *p = to_fimc_pipeline(ep);
+       struct v4l2_subdev *sd;
+       int ret;
+@@ -214,8 +215,9 @@ err_wbclk:
+  *
+  * Disable power of all subdevs and turn the external sensor clock off.
+  */
+-static int __fimc_pipeline_close(struct fimc_pipeline *p)
++static int __fimc_pipeline_close(struct exynos_media_pipeline *ep)
+ {
++      struct fimc_pipeline *p = to_fimc_pipeline(ep);
+       struct v4l2_subdev *sd = p ? p->subdevs[IDX_SENSOR] : NULL;
+       struct fimc_md *fmd;
+       int ret = 0;
+@@ -242,12 +244,13 @@ static int __fimc_pipeline_close(struct fimc_pipeline *p)
+  * @pipeline: video pipeline structure
+  * @on: passed as the s_stream() callback argument
+  */
+-static int __fimc_pipeline_s_stream(struct fimc_pipeline *p, bool on)
++static int __fimc_pipeline_s_stream(struct exynos_media_pipeline *ep, bool on)
+ {
+       static const u8 seq[2][IDX_MAX] = {
+               { IDX_FIMC, IDX_SENSOR, IDX_IS_ISP, IDX_CSIS, IDX_FLITE },
+               { IDX_CSIS, IDX_FLITE, IDX_FIMC, IDX_SENSOR, IDX_IS_ISP },
+       };
++      struct fimc_pipeline *p = to_fimc_pipeline(ep);
+       int i, ret = 0;
+       if (p->subdevs[IDX_SENSOR] == NULL)
+@@ -271,12 +274,38 @@ error:
+ }
+ /* Media pipeline operations for the FIMC/FIMC-LITE video device driver */
+-static const struct fimc_pipeline_ops fimc_pipeline_ops = {
++static const struct exynos_media_pipeline_ops fimc_pipeline_ops = {
+       .open           = __fimc_pipeline_open,
+       .close          = __fimc_pipeline_close,
+       .set_stream     = __fimc_pipeline_s_stream,
+ };
++static struct exynos_media_pipeline *fimc_md_pipeline_create(
++                                              struct fimc_md *fmd)
++{
++      struct fimc_pipeline *p;
++
++      p = kzalloc(sizeof(*p), GFP_KERNEL);
++      if (!p)
++              return NULL;
++
++      list_add_tail(&p->list, &fmd->pipelines);
++
++      p->ep.ops = &fimc_pipeline_ops;
++      return &p->ep;
++}
++
++static void fimc_md_pipelines_free(struct fimc_md *fmd)
++{
++      while (!list_empty(&fmd->pipelines)) {
++              struct fimc_pipeline *p;
++
++              p = list_entry(fmd->pipelines.next, typeof(*p), list);
++              list_del(&p->list);
++              kfree(p);
++      }
++}
++
+ /*
+  * Sensor subdevice helper functions
+  */
+@@ -592,6 +621,7 @@ static int register_fimc_lite_entity(struct fimc_md *fmd,
+                                    struct fimc_lite *fimc_lite)
+ {
+       struct v4l2_subdev *sd;
++      struct exynos_media_pipeline *ep;
+       int ret;
+       if (WARN_ON(fimc_lite->index >= FIMC_LITE_MAX_DEVS ||
+@@ -600,7 +630,12 @@ static int register_fimc_lite_entity(struct fimc_md *fmd,
+       sd = &fimc_lite->subdev;
+       sd->grp_id = GRP_ID_FLITE;
+-      v4l2_set_subdev_hostdata(sd, (void *)&fimc_pipeline_ops);
++
++      ep = fimc_md_pipeline_create(fmd);
++      if (!ep)
++              return -ENOMEM;
++
++      v4l2_set_subdev_hostdata(sd, ep);
+       ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
+       if (!ret)
+@@ -614,6 +649,7 @@ static int register_fimc_lite_entity(struct fimc_md *fmd,
+ static int register_fimc_entity(struct fimc_md *fmd, struct fimc_dev *fimc)
+ {
+       struct v4l2_subdev *sd;
++      struct exynos_media_pipeline *ep;
+       int ret;
+       if (WARN_ON(fimc->id >= FIMC_MAX_DEVS || fmd->fimc[fimc->id]))
+@@ -621,7 +657,12 @@ static int register_fimc_entity(struct fimc_md *fmd, struct fimc_dev *fimc)
+       sd = &fimc->vid_cap.subdev;
+       sd->grp_id = GRP_ID_FIMC;
+-      v4l2_set_subdev_hostdata(sd, (void *)&fimc_pipeline_ops);
++
++      ep = fimc_md_pipeline_create(fmd);
++      if (!ep)
++              return -ENOMEM;
++
++      v4l2_set_subdev_hostdata(sd, ep);
+       ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
+       if (!ret) {
+@@ -797,17 +838,19 @@ static void fimc_md_unregister_entities(struct fimc_md *fmd)
+       int i;
+       for (i = 0; i < FIMC_MAX_DEVS; i++) {
+-              if (fmd->fimc[i] == NULL)
++              struct fimc_dev *dev = fmd->fimc[i];
++              if (dev == NULL)
+                       continue;
+-              v4l2_device_unregister_subdev(&fmd->fimc[i]->vid_cap.subdev);
+-              fmd->fimc[i]->pipeline_ops = NULL;
++              v4l2_device_unregister_subdev(&dev->vid_cap.subdev);
++              dev->vid_cap.ve.pipe = NULL;
+               fmd->fimc[i] = NULL;
+       }
+       for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) {
+-              if (fmd->fimc_lite[i] == NULL)
++              struct fimc_lite *dev = fmd->fimc_lite[i];
++              if (dev == NULL)
+                       continue;
+-              v4l2_device_unregister_subdev(&fmd->fimc_lite[i]->subdev);
+-              fmd->fimc_lite[i]->pipeline_ops = NULL;
++              v4l2_device_unregister_subdev(&dev->subdev);
++              dev->ve.pipe = NULL;
+               fmd->fimc_lite[i] = NULL;
+       }
+       for (i = 0; i < CSIS_MAX_ENTITIES; i++) {
+@@ -1234,38 +1277,22 @@ int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on)
+ static int fimc_md_link_notify(struct media_pad *source,
+                              struct media_pad *sink, u32 flags)
+ {
+-      struct fimc_lite *fimc_lite = NULL;
+-      struct fimc_dev *fimc = NULL;
++      struct exynos_video_entity *ve;
++      struct video_device *vdev;
+       struct fimc_pipeline *pipeline;
+-      struct v4l2_subdev *sd;
+       int i, ret = 0;
+-      if (media_entity_type(sink->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
++      if (media_entity_type(sink->entity) != MEDIA_ENT_T_DEVNODE_V4L)
+               return 0;
+-      sd = media_entity_to_v4l2_subdev(sink->entity);
+-
+-      switch (sd->grp_id) {
+-      case GRP_ID_FLITE:
+-              fimc_lite = v4l2_get_subdevdata(sd);
+-              if (WARN_ON(fimc_lite == NULL))
+-                      return 0;
+-              pipeline = &fimc_lite->pipeline;
+-              break;
+-      case GRP_ID_FIMC:
+-              fimc = v4l2_get_subdevdata(sd);
+-              if (WARN_ON(fimc == NULL))
+-                      return 0;
+-              pipeline = &fimc->pipeline;
+-              break;
+-      default:
+-              return 0;
+-      }
++      vdev = media_entity_to_video_device(sink->entity);
++      ve = vdev_to_exynos_video_entity(vdev);
++      pipeline = to_fimc_pipeline(ve->pipe);
++
++      if (!(flags & MEDIA_LNK_FL_ENABLED) && pipeline->subdevs[IDX_SENSOR]) {
++              if (sink->entity->use_count > 0)
++                      ret = __fimc_pipeline_close(ve->pipe);
+-      if (!(flags & MEDIA_LNK_FL_ENABLED)) {
+-              if (sink->entity->use_count > 0) {
+-                      ret = __fimc_pipeline_close(pipeline);
+-              }
+               for (i = 0; i < IDX_MAX; i++)
+                       pipeline->subdevs[i] = NULL;
+       } else if (sink->entity->use_count > 0) {
+@@ -1274,8 +1301,7 @@ static int fimc_md_link_notify(struct media_pad *source,
+                * the pipeline is already in use, i.e. its video node is open.
+                * Recreate the controls destroyed during the link deactivation.
+                */
+-              ret = __fimc_pipeline_open(pipeline,
+-                                         source->entity, true);
++              ret = __fimc_pipeline_open(ve->pipe, sink->entity, true);
+       }
+       return ret ? -EPIPE : ret;
+@@ -1358,6 +1384,7 @@ static int fimc_md_probe(struct platform_device *pdev)
+       spin_lock_init(&fmd->slock);
+       fmd->pdev = pdev;
++      INIT_LIST_HEAD(&fmd->pipelines);
+       strlcpy(fmd->media_dev.model, "SAMSUNG S5P FIMC",
+               sizeof(fmd->media_dev.model));
+@@ -1445,6 +1472,7 @@ static int fimc_md_remove(struct platform_device *pdev)
+               return 0;
+       device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode);
+       fimc_md_unregister_entities(fmd);
++      fimc_md_pipelines_free(fmd);
+       media_device_unregister(&fmd->media_dev);
+       fimc_md_put_clocks(fmd);
+       return 0;
+diff --git a/drivers/media/platform/exynos4-is/media-dev.h b/drivers/media/platform/exynos4-is/media-dev.h
+index 3e9680c..a704eea 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.h
++++ b/drivers/media/platform/exynos4-is/media-dev.h
+@@ -18,6 +18,7 @@
+ #include <media/media-entity.h>
+ #include <media/v4l2-device.h>
+ #include <media/v4l2-subdev.h>
++#include <media/s5p_fimc.h>
+ #include "fimc-core.h"
+ #include "fimc-lite.h"
+@@ -40,6 +41,29 @@ enum {
+       FIMC_MAX_WBCLKS
+ };
++enum fimc_subdev_index {
++      IDX_SENSOR,
++      IDX_CSIS,
++      IDX_FLITE,
++      IDX_IS_ISP,
++      IDX_FIMC,
++      IDX_MAX,
++};
++
++/*
++ * This structure represents a chain of media entities, including a data
++ * source entity (e.g. an image sensor subdevice), a data capture entity
++ * - a video capture device node and any remaining entities.
++ */
++struct fimc_pipeline {
++      struct exynos_media_pipeline ep;
++      struct list_head list;
++      struct media_entity *vdev_entity;
++      struct v4l2_subdev *subdevs[IDX_MAX];
++};
++
++#define to_fimc_pipeline(_ep) container_of(_ep, struct fimc_pipeline, ep)
++
+ struct fimc_csis_info {
+       struct v4l2_subdev *sd;
+       int id;
+@@ -104,7 +128,9 @@ struct fimc_md {
+               struct pinctrl_state *state_idle;
+       } pinctl;
+       bool user_subdev_api;
++
+       spinlock_t slock;
++      struct list_head pipelines;
+ };
+ #define is_subdev_pad(pad) (pad == NULL || \
+@@ -149,4 +175,16 @@ static inline bool fimc_md_is_isp_available(struct device_node *node)
+ #define fimc_md_is_isp_available(node) (false)
+ #endif /* CONFIG_OF */
++static inline struct v4l2_subdev *__fimc_md_get_subdev(
++                              struct exynos_media_pipeline *ep,
++                              unsigned int index)
++{
++      struct fimc_pipeline *p = to_fimc_pipeline(ep);
++
++      if (!p || index >= IDX_MAX)
++              return NULL;
++      else
++              return p->subdevs[index];
++}
++
+ #endif
+diff --git a/include/media/s5p_fimc.h b/include/media/s5p_fimc.h
+index f5313b4..0afadb6 100644
+--- a/include/media/s5p_fimc.h
++++ b/include/media/s5p_fimc.h
+@@ -141,41 +141,40 @@ struct fimc_fmt {
+ #define FMT_FLAGS_YUV         (1 << 7)
+ };
+-enum fimc_subdev_index {
+-      IDX_SENSOR,
+-      IDX_CSIS,
+-      IDX_FLITE,
+-      IDX_IS_ISP,
+-      IDX_FIMC,
+-      IDX_MAX,
+-};
+-
+-struct media_pipeline;
+-struct v4l2_subdev;
++struct exynos_media_pipeline;
+-struct fimc_pipeline {
+-      struct v4l2_subdev *subdevs[IDX_MAX];
+-      struct media_pipeline *m_pipeline;
++/*
++ * Media pipeline operations to be called from within a video node,  i.e. the
++ * last entity within the pipeline. Implemented by related media device driver.
++ */
++struct exynos_media_pipeline_ops {
++      int (*prepare)(struct exynos_media_pipeline *p,
++                                              struct media_entity *me);
++      int (*unprepare)(struct exynos_media_pipeline *p);
++      int (*open)(struct exynos_media_pipeline *p, struct media_entity *me,
++                                                      bool resume);
++      int (*close)(struct exynos_media_pipeline *p);
++      int (*set_stream)(struct exynos_media_pipeline *p, bool state);
+ };
+ struct exynos_video_entity {
+       struct video_device vdev;
++      struct exynos_media_pipeline *pipe;
+ };
+-/*
+- * Media pipeline operations to be called from within the fimc(-lite)
+- * video node when it is the last entity of the pipeline. Implemented
+- * by corresponding media device driver.
+- */
+-struct fimc_pipeline_ops {
+-      int (*open)(struct fimc_pipeline *p, struct media_entity *me,
+-                        bool resume);
+-      int (*close)(struct fimc_pipeline *p);
+-      int (*set_stream)(struct fimc_pipeline *p, bool state);
++struct exynos_media_pipeline {
++      struct media_pipeline mp;
++      const struct exynos_media_pipeline_ops *ops;
+ };
+-#define fimc_pipeline_call(f, op, p, args...)                         \
+-      (!(f) ? -ENODEV : (((f)->pipeline_ops && (f)->pipeline_ops->op) ? \
+-                          (f)->pipeline_ops->op((p), ##args) : -ENOIOCTLCMD))
++static inline struct exynos_video_entity *vdev_to_exynos_video_entity(
++                                      struct video_device *vdev)
++{
++      return container_of(vdev, struct exynos_video_entity, vdev);
++}
++
++#define fimc_pipeline_call(ent, op, args...)                            \
++      (!(ent) ? -ENOENT : (((ent)->pipe->ops && (ent)->pipe->ops->op) ? \
++      (ent)->pipe->ops->op(((ent)->pipe), ##args) : -ENOIOCTLCMD))      \
+ #endif /* S5P_FIMC_H_ */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0217-media-exynos4-is-Remove-WARN_ON-from-__fimc_pipeline.patch b/patches.tizen/0217-media-exynos4-is-Remove-WARN_ON-from-__fimc_pipeline.patch
new file mode 100644 (file)
index 0000000..0885220
--- /dev/null
@@ -0,0 +1,49 @@
+From df253edb02860be7a984e507286caa3bc6f3aa45 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 31 May 2013 11:37:23 -0300
+Subject: [PATCH 0217/1302] [media] exynos4-is: Remove WARN_ON() from
+ __fimc_pipeline_close()
+
+It's not a critical error to call __fimc_pipeline_close() with missing
+sensor subdev entity. Replace WARN_ON() with pr_warn() and return 0
+instead of -EINVAL to fix control flow in some conditions.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/media-dev.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
+index 4062af2..0b5a7ef 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.c
++++ b/drivers/media/platform/exynos4-is/media-dev.c
+@@ -220,16 +220,16 @@ static int __fimc_pipeline_close(struct exynos_media_pipeline *ep)
+       struct fimc_pipeline *p = to_fimc_pipeline(ep);
+       struct v4l2_subdev *sd = p ? p->subdevs[IDX_SENSOR] : NULL;
+       struct fimc_md *fmd;
+-      int ret = 0;
+-
+-      if (WARN_ON(sd == NULL))
+-              return -EINVAL;
++      int ret;
+-      if (p->subdevs[IDX_SENSOR]) {
+-              ret = fimc_pipeline_s_power(p, 0);
+-              fimc_md_set_camclk(sd, false);
++      if (sd == NULL) {
++              pr_warn("%s(): No sensor subdev\n", __func__);
++              return 0;
+       }
++      ret = fimc_pipeline_s_power(p, 0);
++      fimc_md_set_camclk(sd, false);
++
+       fmd = entity_to_fimc_mdev(&sd->entity);
+       /* Disable PXLASYNC clock if this pipeline includes FIMC-IS */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0218-media-exynos4-is-Fix-sensor-subdev-FIMC-notification.patch b/patches.tizen/0218-media-exynos4-is-Fix-sensor-subdev-FIMC-notification.patch
new file mode 100644 (file)
index 0000000..b3812c4
--- /dev/null
@@ -0,0 +1,122 @@
+From e5923bed8799269f4cc276f2842472e4cb913984 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 31 May 2013 11:37:24 -0300
+Subject: [PATCH 0218/1302] [media] exynos4-is: Fix sensor subdev -> FIMC
+ notification setup
+
+Ensure the v4l2_device notifications from sensor subdev works
+also after the media links reconfiguration.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/media-dev.c | 47 ++++++++++++++++++---------
+ 1 file changed, 31 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
+index 0b5a7ef..805d8f5b 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.c
++++ b/drivers/media/platform/exynos4-is/media-dev.c
+@@ -1,8 +1,8 @@
+ /*
+  * S5P/EXYNOS4 SoC series camera host interface media device driver
+  *
+- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd.
+- * Sylwester Nawrocki <s.nawrocki@samsung.com>
++ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd.
++ * Author: Sylwester Nawrocki <s.nawrocki@samsung.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
+@@ -39,6 +39,26 @@
+ static int __fimc_md_set_camclk(struct fimc_md *fmd,
+                               struct fimc_source_info *si,
+                               bool on);
++
++/* Set up image sensor subdev -> FIMC capture node notifications. */
++static void __setup_sensor_notification(struct fimc_md *fmd,
++                                      struct v4l2_subdev *sensor,
++                                      struct v4l2_subdev *fimc_sd)
++{
++      struct fimc_source_info *src_inf;
++      struct fimc_sensor_info *md_si;
++      unsigned long flags;
++
++      src_inf = v4l2_get_subdev_hostdata(sensor);
++      if (!src_inf || WARN_ON(fmd == NULL))
++              return;
++
++      md_si = source_to_sensor_info(src_inf);
++      spin_lock_irqsave(&fmd->slock, flags);
++      md_si->host = v4l2_get_subdevdata(fimc_sd);
++      spin_unlock_irqrestore(&fmd->slock, flags);
++}
++
+ /**
+  * fimc_pipeline_prepare - update pipeline information with subdevice pointers
+  * @me: media entity terminating the pipeline
+@@ -48,7 +68,9 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd,
+ static void fimc_pipeline_prepare(struct fimc_pipeline *p,
+                                       struct media_entity *me)
+ {
++      struct fimc_md *fmd = entity_to_fimc_mdev(me);
+       struct v4l2_subdev *sd;
++      struct v4l2_subdev *sensor = NULL;
+       int i;
+       for (i = 0; i < IDX_MAX; i++)
+@@ -73,8 +95,10 @@ static void fimc_pipeline_prepare(struct fimc_pipeline *p,
+               sd = media_entity_to_v4l2_subdev(pad->entity);
+               switch (sd->grp_id) {
+-              case GRP_ID_FIMC_IS_SENSOR:
+               case GRP_ID_SENSOR:
++                      sensor = sd;
++                      /* fall through */
++              case GRP_ID_FIMC_IS_SENSOR:
+                       p->subdevs[IDX_SENSOR] = sd;
+                       break;
+               case GRP_ID_CSIS:
+@@ -84,7 +108,7 @@ static void fimc_pipeline_prepare(struct fimc_pipeline *p,
+                       p->subdevs[IDX_FLITE] = sd;
+                       break;
+               case GRP_ID_FIMC:
+-                      /* No need to control FIMC subdev through subdev ops */
++                      p->subdevs[IDX_FIMC] = sd;
+                       break;
+               case GRP_ID_FIMC_IS:
+                       p->subdevs[IDX_IS_ISP] = sd;
+@@ -96,6 +120,9 @@ static void fimc_pipeline_prepare(struct fimc_pipeline *p,
+               if (me->num_pads == 1)
+                       break;
+       }
++
++      if (sensor && p->subdevs[IDX_FIMC])
++              __setup_sensor_notification(fmd, sensor, p->subdevs[IDX_FIMC]);
+ }
+ /**
+@@ -923,18 +950,6 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd,
+               v4l2_info(&fmd->v4l2_dev, "created link [%s] %c> [%s]\n",
+                         source->name, flags ? '=' : '-', sink->name);
+-
+-              if (flags == 0 || sensor == NULL)
+-                      continue;
+-
+-              if (!WARN_ON(si == NULL)) {
+-                      unsigned long irq_flags;
+-                      struct fimc_sensor_info *inf = source_to_sensor_info(si);
+-
+-                      spin_lock_irqsave(&fmd->slock, irq_flags);
+-                      inf->host = fmd->fimc[i];
+-                      spin_unlock_irqrestore(&fmd->slock, irq_flags);
+-              }
+       }
+       for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0219-media-exynos4-is-Add-locking-at-fimc-lite-subdev-unr.patch b/patches.tizen/0219-media-exynos4-is-Add-locking-at-fimc-lite-subdev-unr.patch
new file mode 100644 (file)
index 0000000..8f0cb92
--- /dev/null
@@ -0,0 +1,67 @@
+From 3269d1ea7c19fa0b09980f70618fe0769078ddde Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 31 May 2013 11:37:25 -0300
+Subject: [PATCH 0219/1302] [media] exynos4-is: Add locking at fimc(-lite)
+ subdev unregistered handler
+
+Protect the fimc/fimc-lite video nodes unregistration with their video
+lock. This prevents a kernel crash when e.g. udev opens a video node
+right after the driver registers it and then the driver tries to
+unregister it and defers its probing. Using video_is_unregistered()
+together with the video mutex allows safe unregistration of the video
+nodes at any time.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-capture.c | 4 ++++
+ drivers/media/platform/exynos4-is/fimc-lite.c    | 4 ++++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
+index 33c6a2f..1578aa4 100644
+--- a/drivers/media/platform/exynos4-is/fimc-capture.c
++++ b/drivers/media/platform/exynos4-is/fimc-capture.c
+@@ -1855,6 +1855,8 @@ static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd)
+       if (fimc == NULL)
+               return;
++      mutex_lock(&fimc->lock);
++
+       fimc_unregister_m2m_device(fimc);
+       vdev = &fimc->vid_cap.ve.vdev;
+@@ -1866,6 +1868,8 @@ static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd)
+       }
+       kfree(fimc->vid_cap.ctx);
+       fimc->vid_cap.ctx = NULL;
++
++      mutex_unlock(&fimc->lock);
+ }
+ static const struct v4l2_subdev_internal_ops fimc_capture_sd_internal_ops = {
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
+index 24e2a0f..3f76f8a 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite.c
++++ b/drivers/media/platform/exynos4-is/fimc-lite.c
+@@ -1300,11 +1300,15 @@ static void fimc_lite_subdev_unregistered(struct v4l2_subdev *sd)
+       if (fimc == NULL)
+               return;
++      mutex_lock(&fimc->lock);
++
+       if (video_is_registered(&fimc->ve.vdev)) {
+               video_unregister_device(&fimc->ve.vdev);
+               media_entity_cleanup(&fimc->ve.vdev.entity);
+               fimc->ve.pipe = NULL;
+       }
++
++      mutex_unlock(&fimc->lock);
+ }
+ static const struct v4l2_subdev_internal_ops fimc_lite_subdev_internal_ops = {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0220-media-exynos4-is-Remove-leftovers-of-non-dt-FIMC-LIT.patch b/patches.tizen/0220-media-exynos4-is-Remove-leftovers-of-non-dt-FIMC-LIT.patch
new file mode 100644 (file)
index 0000000..d585c90
--- /dev/null
@@ -0,0 +1,34 @@
+From 73ad5fe43ac46bf6d54cf49a7c882b47bd57897b Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 31 May 2013 13:46:59 -0300
+Subject: [PATCH 0220/1302] [media] exynos4-is: Remove leftovers of non-dt
+ FIMC-LITE support
+
+FIMC-LITE devices are never looked up by iterating over all platform
+devices with bus_for_each_device() as these IP blocks are available
+only on dt-only Exynos SoC platforms.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/media-dev.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
+index 805d8f5b..777b74f 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.c
++++ b/drivers/media/platform/exynos4-is/media-dev.c
+@@ -804,8 +804,6 @@ static int fimc_md_pdev_match(struct device *dev, void *data)
+       if (!strcmp(pdev->name, CSIS_DRIVER_NAME)) {
+               plat_entity = IDX_CSIS;
+-      } else if (!strcmp(pdev->name, FIMC_LITE_DRV_NAME)) {
+-              plat_entity = IDX_FLITE;
+       } else {
+               p = strstr(pdev->name, "fimc");
+               if (p && *(p + 4) == 0)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0221-media-exynos4-is-Simplify-bitmask-usage.patch b/patches.tizen/0221-media-exynos4-is-Simplify-bitmask-usage.patch
new file mode 100644 (file)
index 0000000..66d63eb
--- /dev/null
@@ -0,0 +1,407 @@
+From 3e92f9b985bae3487f7d1b48ef1ff4fb2e049eec Mon Sep 17 00:00:00 2001
+From: Phil Carmody <phil.carmody@partner.samsung.com>
+Date: Fri, 31 May 2013 13:47:00 -0300
+Subject: [PATCH 0221/1302] [media] exynos4-is: Simplify bitmask usage
+
+Merge the two sets of flags into one array to simplify accessing
+arbitrary bits from them.
+
+Signed-off-by: Phil Carmody <phil.carmody@partner.samsung.com>
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-is-param.c | 80 +++++++++++------------
+ drivers/media/platform/exynos4-is/fimc-is-regs.c  |  4 +-
+ drivers/media/platform/exynos4-is/fimc-is.c       |  8 +--
+ drivers/media/platform/exynos4-is/fimc-is.h       |  8 +--
+ drivers/media/platform/exynos4-is/fimc-isp.c      |  4 +-
+ 5 files changed, 49 insertions(+), 55 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-is-param.c b/drivers/media/platform/exynos4-is/fimc-is-param.c
+index c435db0..c7e7f69 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is-param.c
++++ b/drivers/media/platform/exynos4-is/fimc-is-param.c
+@@ -168,8 +168,8 @@ unsigned int __get_pending_param_count(struct fimc_is *is)
+       unsigned int count;
+       spin_lock_irqsave(&is->slock, flags);
+-      count = hweight32(config->p_region_index1);
+-      count += hweight32(config->p_region_index2);
++      count = hweight32(config->p_region_index[0]);
++      count += hweight32(config->p_region_index[1]);
+       spin_unlock_irqrestore(&is->slock, flags);
+       return count;
+@@ -177,31 +177,30 @@ unsigned int __get_pending_param_count(struct fimc_is *is)
+ int __is_hw_update_params(struct fimc_is *is)
+ {
+-      unsigned long *p_index1, *p_index2;
++      unsigned long *p_index;
+       int i, id, ret = 0;
+       id = is->config_index;
+-      p_index1 = &is->config[id].p_region_index1;
+-      p_index2 = &is->config[id].p_region_index2;
++      p_index = &is->config[id].p_region_index[0];
+-      if (test_bit(PARAM_GLOBAL_SHOTMODE, p_index1))
++      if (test_bit(PARAM_GLOBAL_SHOTMODE, p_index))
+               __fimc_is_hw_update_param_global_shotmode(is);
+-      if (test_bit(PARAM_SENSOR_FRAME_RATE, p_index1))
++      if (test_bit(PARAM_SENSOR_FRAME_RATE, p_index))
+               __fimc_is_hw_update_param_sensor_framerate(is);
+       for (i = PARAM_ISP_CONTROL; i < PARAM_DRC_CONTROL; i++) {
+-              if (test_bit(i, p_index1))
++              if (test_bit(i, p_index))
+                       ret = __fimc_is_hw_update_param(is, i);
+       }
+       for (i = PARAM_DRC_CONTROL; i < PARAM_SCALERC_CONTROL; i++) {
+-              if (test_bit(i, p_index1))
++              if (test_bit(i, p_index))
+                       ret = __fimc_is_hw_update_param(is, i);
+       }
+       for (i = PARAM_FD_CONTROL; i <= PARAM_FD_CONFIG; i++) {
+-              if (test_bit((i - 32), p_index2))
++              if (test_bit(i, p_index))
+                       ret = __fimc_is_hw_update_param(is, i);
+       }
+@@ -243,7 +242,7 @@ void __is_set_frame_size(struct fimc_is *is, struct v4l2_mbus_framefmt *mf)
+       fd->otf_input.height = mf->height;
+       if (test_bit(PARAM_ISP_OTF_INPUT,
+-                    &is->config[index].p_region_index1))
++                    &is->config[index].p_region_index[0]))
+               return;
+       /* Update field */
+@@ -368,7 +367,7 @@ void __is_set_isp_adjust(struct fimc_is *is, u32 cmd, u32 val)
+       unsigned long *p_index;
+       struct isp_param *isp;
+-      p_index = &is->config[index].p_region_index1;
++      p_index = &is->config[index].p_region_index[0];
+       isp = &is->config[index].isp;
+       switch (cmd) {
+@@ -415,7 +414,7 @@ void __is_set_isp_metering(struct fimc_is *is, u32 id, u32 val)
+       struct isp_param *isp;
+       unsigned long *p_index;
+-      p_index = &is->config[index].p_region_index1;
++      p_index = &is->config[index].p_region_index[0];
+       isp = &is->config[index].isp;
+       switch (id) {
+@@ -476,7 +475,7 @@ void __is_set_fd_control(struct fimc_is *is, u32 val)
+       struct fd_param *fd;
+       unsigned long *p_index;
+-      p_index = &is->config[index].p_region_index2;
++      p_index = &is->config[index].p_region_index[1];
+       fd = &is->config[index].fd;
+       fd->control.cmd = val;
+@@ -491,7 +490,7 @@ void __is_set_fd_config_maxface(struct fimc_is *is, u32 val)
+       struct fd_param *fd;
+       unsigned long *p_index;
+-      p_index = &is->config[index].p_region_index2;
++      p_index = &is->config[index].p_region_index[1];
+       fd = &is->config[index].fd;
+       fd->config.max_number = val;
+@@ -511,7 +510,7 @@ void __is_set_fd_config_rollangle(struct fimc_is *is, u32 val)
+       struct fd_param *fd;
+       unsigned long *p_index;
+-      p_index = &is->config[index].p_region_index2;
++      p_index = &is->config[index].p_region_index[1];
+       fd = &is->config[index].fd;
+       fd->config.roll_angle = val;
+@@ -531,7 +530,7 @@ void __is_set_fd_config_yawangle(struct fimc_is *is, u32 val)
+       struct fd_param *fd;
+       unsigned long *p_index;
+-      p_index = &is->config[index].p_region_index2;
++      p_index = &is->config[index].p_region_index[1];
+       fd = &is->config[index].fd;
+       fd->config.yaw_angle = val;
+@@ -551,7 +550,7 @@ void __is_set_fd_config_smilemode(struct fimc_is *is, u32 val)
+       struct fd_param *fd;
+       unsigned long *p_index;
+-      p_index = &is->config[index].p_region_index2;
++      p_index = &is->config[index].p_region_index[1];
+       fd = &is->config[index].fd;
+       fd->config.smile_mode = val;
+@@ -571,7 +570,7 @@ void __is_set_fd_config_blinkmode(struct fimc_is *is, u32 val)
+       struct fd_param *fd;
+       unsigned long *p_index;
+-      p_index = &is->config[index].p_region_index2;
++      p_index = &is->config[index].p_region_index[1];
+       fd = &is->config[index].fd;
+       fd->config.blink_mode = val;
+@@ -591,7 +590,7 @@ void __is_set_fd_config_eyedetect(struct fimc_is *is, u32 val)
+       struct fd_param *fd;
+       unsigned long *p_index;
+-      p_index = &is->config[index].p_region_index2;
++      p_index = &is->config[index].p_region_index[1];
+       fd = &is->config[index].fd;
+       fd->config.eye_detect = val;
+@@ -611,7 +610,7 @@ void __is_set_fd_config_mouthdetect(struct fimc_is *is, u32 val)
+       struct fd_param *fd;
+       unsigned long *p_index;
+-      p_index = &is->config[index].p_region_index2;
++      p_index = &is->config[index].p_region_index[1];
+       fd = &is->config[index].fd;
+       fd->config.mouth_detect = val;
+@@ -631,7 +630,7 @@ void __is_set_fd_config_orientation(struct fimc_is *is, u32 val)
+       struct fd_param *fd;
+       unsigned long *p_index;
+-      p_index = &is->config[index].p_region_index2;
++      p_index = &is->config[index].p_region_index[1];
+       fd = &is->config[index].fd;
+       fd->config.orientation = val;
+@@ -651,7 +650,7 @@ void __is_set_fd_config_orientation_val(struct fimc_is *is, u32 val)
+       struct fd_param *fd;
+       unsigned long *p_index;
+-      p_index = &is->config[index].p_region_index2;
++      p_index = &is->config[index].p_region_index[1];
+       fd = &is->config[index].fd;
+       fd->config.orientation_value = val;
+@@ -672,7 +671,7 @@ void fimc_is_set_initial_params(struct fimc_is *is)
+       struct isp_param *isp;
+       struct drc_param *drc;
+       struct fd_param *fd;
+-      unsigned long *p_index1, *p_index2;
++      unsigned long *p_index;
+       unsigned int index;
+       index = is->config_index;
+@@ -681,8 +680,7 @@ void fimc_is_set_initial_params(struct fimc_is *is)
+       isp = &is->config[index].isp;
+       drc = &is->config[index].drc;
+       fd = &is->config[index].fd;
+-      p_index1 = &is->config[index].p_region_index1;
+-      p_index2 = &is->config[index].p_region_index2;
++      p_index = &is->config[index].p_region_index[0];
+       /* Global */
+       global->shotmode.cmd = 1;
+@@ -695,7 +693,7 @@ void fimc_is_set_initial_params(struct fimc_is *is)
+       fimc_is_set_param_bit(is, PARAM_ISP_CONTROL);
+       isp->otf_input.cmd = OTF_INPUT_COMMAND_ENABLE;
+-      if (!test_bit(PARAM_ISP_OTF_INPUT, p_index1)) {
++      if (!test_bit(PARAM_ISP_OTF_INPUT, p_index)) {
+               isp->otf_input.width = DEFAULT_PREVIEW_STILL_WIDTH;
+               isp->otf_input.height = DEFAULT_PREVIEW_STILL_HEIGHT;
+               fimc_is_set_param_bit(is, PARAM_ISP_OTF_INPUT);
+@@ -738,20 +736,20 @@ void fimc_is_set_initial_params(struct fimc_is *is)
+       isp->aa.target = ISP_AA_TARGET_AE | ISP_AA_TARGET_AWB;
+       fimc_is_set_param_bit(is, PARAM_ISP_AA);
+-      if (!test_bit(PARAM_ISP_FLASH, p_index1))
++      if (!test_bit(PARAM_ISP_FLASH, p_index))
+               __is_set_isp_flash(is, ISP_FLASH_COMMAND_DISABLE,
+                                               ISP_FLASH_REDEYE_DISABLE);
+-      if (!test_bit(PARAM_ISP_AWB, p_index1))
++      if (!test_bit(PARAM_ISP_AWB, p_index))
+               __is_set_isp_awb(is, ISP_AWB_COMMAND_AUTO, 0);
+-      if (!test_bit(PARAM_ISP_IMAGE_EFFECT, p_index1))
++      if (!test_bit(PARAM_ISP_IMAGE_EFFECT, p_index))
+               __is_set_isp_effect(is, ISP_IMAGE_EFFECT_DISABLE);
+-      if (!test_bit(PARAM_ISP_ISO, p_index1))
++      if (!test_bit(PARAM_ISP_ISO, p_index))
+               __is_set_isp_iso(is, ISP_ISO_COMMAND_AUTO, 0);
+-      if (!test_bit(PARAM_ISP_ADJUST, p_index1)) {
++      if (!test_bit(PARAM_ISP_ADJUST, p_index)) {
+               __is_set_isp_adjust(is, ISP_ADJUST_COMMAND_MANUAL_CONTRAST, 0);
+               __is_set_isp_adjust(is,
+                               ISP_ADJUST_COMMAND_MANUAL_SATURATION, 0);
+@@ -762,7 +760,7 @@ void fimc_is_set_initial_params(struct fimc_is *is)
+               __is_set_isp_adjust(is, ISP_ADJUST_COMMAND_MANUAL_HUE, 0);
+       }
+-      if (!test_bit(PARAM_ISP_METERING, p_index1)) {
++      if (!test_bit(PARAM_ISP_METERING, p_index)) {
+               __is_set_isp_metering(is, 0, ISP_METERING_COMMAND_CENTER);
+               __is_set_isp_metering(is, 1, 0);
+               __is_set_isp_metering(is, 2, 0);
+@@ -770,11 +768,11 @@ void fimc_is_set_initial_params(struct fimc_is *is)
+               __is_set_isp_metering(is, 4, 0);
+       }
+-      if (!test_bit(PARAM_ISP_AFC, p_index1))
++      if (!test_bit(PARAM_ISP_AFC, p_index))
+               __is_set_isp_afc(is, ISP_AFC_COMMAND_AUTO, 0);
+       isp->otf_output.cmd = OTF_OUTPUT_COMMAND_ENABLE;
+-      if (!test_bit(PARAM_ISP_OTF_OUTPUT, p_index1)) {
++      if (!test_bit(PARAM_ISP_OTF_OUTPUT, p_index)) {
+               isp->otf_output.width = DEFAULT_PREVIEW_STILL_WIDTH;
+               isp->otf_output.height = DEFAULT_PREVIEW_STILL_HEIGHT;
+               fimc_is_set_param_bit(is, PARAM_ISP_OTF_OUTPUT);
+@@ -784,7 +782,7 @@ void fimc_is_set_initial_params(struct fimc_is *is)
+       isp->otf_output.order = 0;
+       isp->otf_output.err = OTF_OUTPUT_ERROR_NONE;
+-      if (!test_bit(PARAM_ISP_DMA1_OUTPUT, p_index1)) {
++      if (!test_bit(PARAM_ISP_DMA1_OUTPUT, p_index)) {
+               isp->dma1_output.cmd = DMA_OUTPUT_COMMAND_DISABLE;
+               isp->dma1_output.width = 0;
+               isp->dma1_output.height = 0;
+@@ -800,7 +798,7 @@ void fimc_is_set_initial_params(struct fimc_is *is)
+               fimc_is_set_param_bit(is, PARAM_ISP_DMA1_OUTPUT);
+       }
+-      if (!test_bit(PARAM_ISP_DMA2_OUTPUT, p_index1)) {
++      if (!test_bit(PARAM_ISP_DMA2_OUTPUT, p_index)) {
+               isp->dma2_output.cmd = DMA_OUTPUT_COMMAND_DISABLE;
+               isp->dma2_output.width = 0;
+               isp->dma2_output.height = 0;
+@@ -817,7 +815,7 @@ void fimc_is_set_initial_params(struct fimc_is *is)
+       }
+       /* Sensor */
+-      if (!test_bit(PARAM_SENSOR_FRAME_RATE, p_index1)) {
++      if (!test_bit(PARAM_SENSOR_FRAME_RATE, p_index)) {
+               if (is->config_index == 0)
+                       __is_set_sensor(is, 0);
+       }
+@@ -827,7 +825,7 @@ void fimc_is_set_initial_params(struct fimc_is *is)
+       __is_set_drc_control(is, CONTROL_BYPASS_ENABLE);
+       drc->otf_input.cmd = OTF_INPUT_COMMAND_ENABLE;
+-      if (!test_bit(PARAM_DRC_OTF_INPUT, p_index1)) {
++      if (!test_bit(PARAM_DRC_OTF_INPUT, p_index)) {
+               drc->otf_input.width = DEFAULT_PREVIEW_STILL_WIDTH;
+               drc->otf_input.height = DEFAULT_PREVIEW_STILL_HEIGHT;
+               fimc_is_set_param_bit(is, PARAM_DRC_OTF_INPUT);
+@@ -850,7 +848,7 @@ void fimc_is_set_initial_params(struct fimc_is *is)
+       fimc_is_set_param_bit(is, PARAM_DRC_DMA_INPUT);
+       drc->otf_output.cmd = OTF_OUTPUT_COMMAND_ENABLE;
+-      if (!test_bit(PARAM_DRC_OTF_OUTPUT, p_index1)) {
++      if (!test_bit(PARAM_DRC_OTF_OUTPUT, p_index)) {
+               drc->otf_output.width = DEFAULT_PREVIEW_STILL_WIDTH;
+               drc->otf_output.height = DEFAULT_PREVIEW_STILL_HEIGHT;
+               fimc_is_set_param_bit(is, PARAM_DRC_OTF_OUTPUT);
+@@ -865,7 +863,7 @@ void fimc_is_set_initial_params(struct fimc_is *is)
+       fd->control.bypass = CONTROL_BYPASS_DISABLE;
+       fd->otf_input.cmd = OTF_INPUT_COMMAND_ENABLE;
+-      if (!test_bit((PARAM_FD_OTF_INPUT - 32), p_index2)) {
++      if (!test_bit(PARAM_FD_OTF_INPUT, p_index)) {
+               fd->otf_input.width = DEFAULT_PREVIEW_STILL_WIDTH;
+               fd->otf_input.height = DEFAULT_PREVIEW_STILL_HEIGHT;
+               fimc_is_set_param_bit(is, PARAM_FD_OTF_INPUT);
+diff --git a/drivers/media/platform/exynos4-is/fimc-is-regs.c b/drivers/media/platform/exynos4-is/fimc-is-regs.c
+index d05eaa2..63c68ec 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is-regs.c
++++ b/drivers/media/platform/exynos4-is/fimc-is-regs.c
+@@ -89,8 +89,8 @@ int fimc_is_hw_set_param(struct fimc_is *is)
+       mcuctl_write(is->config_index, is, MCUCTL_REG_ISSR(2));
+       mcuctl_write(param_count, is, MCUCTL_REG_ISSR(3));
+-      mcuctl_write(config->p_region_index1, is, MCUCTL_REG_ISSR(4));
+-      mcuctl_write(config->p_region_index2, is, MCUCTL_REG_ISSR(5));
++      mcuctl_write(config->p_region_index[0], is, MCUCTL_REG_ISSR(4));
++      mcuctl_write(config->p_region_index[1], is, MCUCTL_REG_ISSR(5));
+       fimc_is_hw_set_intgr0_gd0(is);
+       return 0;
+diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c
+index b127d08..967f6a9 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is.c
++++ b/drivers/media/platform/exynos4-is/fimc-is.c
+@@ -527,8 +527,8 @@ static void fimc_is_general_irq_handler(struct fimc_is *is)
+                       break;
+               case HIC_SET_PARAMETER:
+-                      is->config[is->config_index].p_region_index1 = 0;
+-                      is->config[is->config_index].p_region_index2 = 0;
++                      is->config[is->config_index].p_region_index[0] = 0;
++                      is->config[is->config_index].p_region_index[1] = 0;
+                       set_bit(IS_ST_BLOCK_CMD_CLEARED, &is->state);
+                       pr_debug("HIC_SET_PARAMETER\n");
+                       break;
+@@ -587,8 +587,8 @@ static void fimc_is_general_irq_handler(struct fimc_is *is)
+               switch (is->i2h_cmd.args[0]) {
+               case HIC_SET_PARAMETER:
+-                      is->config[is->config_index].p_region_index1 = 0;
+-                      is->config[is->config_index].p_region_index2 = 0;
++                      is->config[is->config_index].p_region_index[0] = 0;
++                      is->config[is->config_index].p_region_index[1] = 0;
+                       set_bit(IS_ST_BLOCK_CMD_CLEARED, &is->state);
+                       break;
+               }
+diff --git a/drivers/media/platform/exynos4-is/fimc-is.h b/drivers/media/platform/exynos4-is/fimc-is.h
+index d7db133..08fa518 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is.h
++++ b/drivers/media/platform/exynos4-is/fimc-is.h
+@@ -225,8 +225,7 @@ struct chain_config {
+       struct drc_param        drc;
+       struct fd_param         fd;
+-      unsigned long           p_region_index1;
+-      unsigned long           p_region_index2;
++      unsigned long           p_region_index[2];
+ };
+ /**
+@@ -302,10 +301,7 @@ static inline void fimc_is_set_param_bit(struct fimc_is *is, int num)
+ {
+       struct chain_config *cfg = &is->config[is->config_index];
+-      if (num >= 32)
+-              set_bit(num - 32, &cfg->p_region_index2);
+-      else
+-              set_bit(num, &cfg->p_region_index1);
++      set_bit(num, &cfg->p_region_index[0]);
+ }
+ static inline void fimc_is_set_param_ctrl_cmd(struct fimc_is *is, int cmd)
+diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c
+index 7ede30b..3a29e41 100644
+--- a/drivers/media/platform/exynos4-is/fimc-isp.c
++++ b/drivers/media/platform/exynos4-is/fimc-isp.c
+@@ -317,8 +317,8 @@ static int fimc_isp_subdev_s_power(struct v4l2_subdev *sd, int on)
+               clear_bit(IS_ST_PWR_ON, &is->state);
+               clear_bit(IS_ST_INIT_DONE, &is->state);
+               is->state = 0;
+-              is->config[is->config_index].p_region_index1 = 0;
+-              is->config[is->config_index].p_region_index2 = 0;
++              is->config[is->config_index].p_region_index[0] = 0;
++              is->config[is->config_index].p_region_index[1] = 0;
+               set_bit(IS_ST_IDLE, &is->state);
+               wmb();
+       }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0222-media-exynos4-is-Remove-unused-code.patch b/patches.tizen/0222-media-exynos4-is-Remove-unused-code.patch
new file mode 100644 (file)
index 0000000..9523bc3
--- /dev/null
@@ -0,0 +1,78 @@
+From 17797b9f54158e889f51fc19b7fb52b5ffcf261d Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 31 May 2013 13:47:01 -0300
+Subject: [PATCH 0222/1302] [media] exynos4-is: Remove unused code
+
+Remove unused macros and fields of struct fimc_is_video.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-isp.h  | 13 +------------
+ drivers/media/platform/exynos4-is/media-dev.h |  8 --------
+ 2 files changed, 1 insertion(+), 20 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-isp.h b/drivers/media/platform/exynos4-is/fimc-isp.h
+index 800aba7..f5c802c 100644
+--- a/drivers/media/platform/exynos4-is/fimc-isp.h
++++ b/drivers/media/platform/exynos4-is/fimc-isp.h
+@@ -118,7 +118,6 @@ struct fimc_is_video {
+       unsigned int            frame_count;
+       unsigned int            reqbufs_count;
+       int                     streaming;
+-      unsigned long           payload[FIMC_ISP_MAX_PLANES];
+       const struct fimc_fmt   *format;
+ };
+@@ -128,15 +127,9 @@ struct fimc_is_video {
+  * @alloc_ctx: videobuf2 memory allocator context
+  * @subdev: ISP v4l2_subdev
+  * @subdev_pads: the ISP subdev media pads
+- * @ctrl_handler: v4l2 controls handler
+  * @test_pattern: test pattern controls
+- * @pipeline: video capture pipeline data structure
++ * @ctrls: v4l2 controls structure
+  * @video_lock: mutex serializing video device and the subdev operations
+- * @fmt: pointer to color format description structure
+- * @payload: image size in bytes (w x h x bpp)
+- * @inp_frame: camera input frame structure
+- * @out_frame: DMA output frame structure
+- * @source_subdev_grp_id: group id of remote source subdev
+  * @cac_margin_x: horizontal CAC margin in pixels
+  * @cac_margin_y: vertical CAC margin in pixels
+  * @state: driver state flags
+@@ -154,10 +147,6 @@ struct fimc_isp {
+       struct mutex                    video_lock;
+       struct mutex                    subdev_lock;
+-      struct fimc_isp_frame           inp_frame;
+-      struct fimc_isp_frame           out_frame;
+-      unsigned int                    source_subdev_grp_id;
+-
+       unsigned int                    cac_margin_x;
+       unsigned int                    cac_margin_y;
+diff --git a/drivers/media/platform/exynos4-is/media-dev.h b/drivers/media/platform/exynos4-is/media-dev.h
+index a704eea..62599fd 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.h
++++ b/drivers/media/platform/exynos4-is/media-dev.h
+@@ -133,14 +133,6 @@ struct fimc_md {
+       struct list_head pipelines;
+ };
+-#define is_subdev_pad(pad) (pad == NULL || \
+-      media_entity_type(pad->entity) == MEDIA_ENT_T_V4L2_SUBDEV)
+-
+-#define me_subtype(me) \
+-      ((me->type) & (MEDIA_ENT_TYPE_MASK | MEDIA_ENT_SUBTYPE_MASK))
+-
+-#define subdev_has_devnode(__sd) (__sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE)
+-
+ static inline
+ struct fimc_sensor_info *source_to_sensor_info(struct fimc_source_info *si)
+ {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0223-media-exynos4-is-Refactor-vidioc_s_fmt-vidioc_try_fm.patch b/patches.tizen/0223-media-exynos4-is-Refactor-vidioc_s_fmt-vidioc_try_fm.patch
new file mode 100644 (file)
index 0000000..7e15744
--- /dev/null
@@ -0,0 +1,268 @@
+From 421c0586f090483cf94a9847ef8b4bcfa8bceef9 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 31 May 2013 13:47:02 -0300
+Subject: [PATCH 0223/1302] [media] exynos4-is: Refactor vidioc_s_fmt,
+ vidioc_try_fmt handlers
+
+Remove duplicated code in the vidioc_try_fmt and vidioc_s_fmt handlers.
+This is a pre-requsite to allow successful fimc.capture video open even
+if its corresponding media entities are not linked into a complete
+pipeline.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-capture.c | 158 +++++++++++------------
+ 1 file changed, 75 insertions(+), 83 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
+index 1578aa4..2b045b6 100644
+--- a/drivers/media/platform/exynos4-is/fimc-capture.c
++++ b/drivers/media/platform/exynos4-is/fimc-capture.c
+@@ -503,9 +503,6 @@ static int fimc_capture_open(struct file *file)
+               ret = fimc_pipeline_call(ve, open, &ve->vdev.entity, true);
+-              if (ret == 0)
+-                      ret = fimc_capture_set_default_format(fimc);
+-
+               if (ret == 0 && vc->user_subdev_api && vc->inh_sensor_ctrls) {
+                       /*
+                        * Recreate controls of the the video node to drop
+@@ -522,6 +519,9 @@ static int fimc_capture_open(struct file *file)
+               fimc_md_graph_unlock(ve);
++              if (ret == 0)
++                      ret = fimc_capture_set_default_format(fimc);
++
+               if (ret < 0) {
+                       clear_bit(ST_CAPT_BUSY, &fimc->state);
+                       pm_runtime_put_sync(&fimc->pdev->dev);
+@@ -916,55 +916,83 @@ static int fimc_cap_g_fmt_mplane(struct file *file, void *fh,
+       return 0;
+ }
+-static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
+-                                 struct v4l2_format *f)
++/*
++ * Try or set format on the fimc.X.capture video node and additionally
++ * on the whole pipeline if @try is false.
++ * Locking: the caller must _not_ hold the graph mutex.
++ */
++static int __video_try_or_set_format(struct fimc_dev *fimc,
++                                   struct v4l2_format *f, bool try,
++                                   struct fimc_fmt **inp_fmt,
++                                   struct fimc_fmt **out_fmt)
+ {
+       struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
+-      struct fimc_dev *fimc = video_drvdata(file);
+-      struct fimc_ctx *ctx = fimc->vid_cap.ctx;
+-      struct exynos_video_entity *ve = &fimc->vid_cap.ve;
+-      struct v4l2_mbus_framefmt mf;
+-      struct v4l2_subdev *sensor;
+-      struct fimc_fmt *ffmt = NULL;
++      struct fimc_vid_cap *vc = &fimc->vid_cap;
++      struct exynos_video_entity *ve = &vc->ve;
++      struct fimc_ctx *ctx = vc->ctx;
++      unsigned int width = 0, height = 0;
+       int ret = 0;
++      /* Pre-configure format at the camera input interface, for JPEG only */
+       if (fimc_jpeg_fourcc(pix->pixelformat)) {
+               fimc_capture_try_format(ctx, &pix->width, &pix->height,
+                                       NULL, &pix->pixelformat,
+                                       FIMC_SD_PAD_SINK_CAM);
+-              ctx->s_frame.f_width  = pix->width;
+-              ctx->s_frame.f_height = pix->height;
++              if (try) {
++                      width = pix->width;
++                      height = pix->height;
++              } else {
++                      ctx->s_frame.f_width = pix->width;
++                      ctx->s_frame.f_height = pix->height;
++              }
+       }
+-      ffmt = fimc_capture_try_format(ctx, &pix->width, &pix->height,
+-                                     NULL, &pix->pixelformat,
+-                                     FIMC_SD_PAD_SOURCE);
+-      if (!ffmt)
++
++      /* Try the format at the scaler and the DMA output */
++      *out_fmt = fimc_capture_try_format(ctx, &pix->width, &pix->height,
++                                        NULL, &pix->pixelformat,
++                                        FIMC_SD_PAD_SOURCE);
++      if (*out_fmt == NULL)
+               return -EINVAL;
+-      if (!fimc->vid_cap.user_subdev_api) {
+-              mf.width = pix->width;
+-              mf.height = pix->height;
+-              mf.code = ffmt->mbus_code;
++      /* Restore image width/height for JPEG (no resizing supported). */
++      if (try && fimc_jpeg_fourcc(pix->pixelformat)) {
++              pix->width = width;
++              pix->height = height;
++      }
++
++      /* Try to match format at the host and the sensor */
++      if (!vc->user_subdev_api) {
++              struct v4l2_mbus_framefmt mbus_fmt;
++              struct v4l2_mbus_framefmt *mf;
++
++              mf = try ? &mbus_fmt : &fimc->vid_cap.ci_fmt;
++
++              mf->code = (*out_fmt)->mbus_code;
++              mf->width = pix->width;
++              mf->height = pix->height;
+               fimc_md_graph_lock(ve);
+-              fimc_pipeline_try_format(ctx, &mf, &ffmt, false);
++              ret = fimc_pipeline_try_format(ctx, mf, inp_fmt, try);
+               fimc_md_graph_unlock(ve);
+-              pix->width = mf.width;
+-              pix->height = mf.height;
+-              if (ffmt)
+-                      pix->pixelformat = ffmt->fourcc;
++              if (ret < 0)
++                      return ret;
++
++              pix->width = mf->width;
++              pix->height = mf->height;
+       }
+-      fimc_adjust_mplane_format(ffmt, pix->width, pix->height, pix);
++      fimc_adjust_mplane_format(*out_fmt, pix->width, pix->height, pix);
++
++      if ((*out_fmt)->flags & FMT_FLAGS_COMPRESSED) {
++              struct v4l2_subdev *sensor;
+-      if (ffmt->flags & FMT_FLAGS_COMPRESSED) {
+               fimc_md_graph_lock(ve);
+               sensor = __fimc_md_get_subdev(ve->pipe, IDX_SENSOR);
+               if (sensor)
+                       fimc_get_sensor_frame_desc(sensor, pix->plane_fmt,
+-                                                 ffmt->memplanes, true);
++                                                 (*out_fmt)->memplanes, try);
+               else
+                       ret = -EPIPE;
+@@ -974,6 +1002,15 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
+       return ret;
+ }
++static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
++                                 struct v4l2_format *f)
++{
++      struct fimc_dev *fimc = video_drvdata(file);
++      struct fimc_fmt *out_fmt = NULL, *inp_fmt = NULL;
++
++      return __video_try_or_set_format(fimc, f, true, &inp_fmt, &out_fmt);
++}
++
+ static void fimc_capture_mark_jpeg_xfer(struct fimc_ctx *ctx,
+                                       enum fimc_color_fmt color)
+ {
+@@ -991,58 +1028,23 @@ static void fimc_capture_mark_jpeg_xfer(struct fimc_ctx *ctx,
+ static int __fimc_capture_set_format(struct fimc_dev *fimc,
+                                    struct v4l2_format *f)
+ {
+-      struct fimc_ctx *ctx = fimc->vid_cap.ctx;
++      struct fimc_vid_cap *vc = &fimc->vid_cap;
++      struct fimc_ctx *ctx = vc->ctx;
+       struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
+-      struct v4l2_mbus_framefmt *mf = &fimc->vid_cap.ci_fmt;
+-      struct fimc_pipeline *p = to_fimc_pipeline(fimc->vid_cap.ve.pipe);
+       struct fimc_frame *ff = &ctx->d_frame;
+-      struct fimc_fmt *s_fmt = NULL;
++      struct fimc_fmt *inp_fmt = NULL;
+       int ret, i;
+       if (vb2_is_busy(&fimc->vid_cap.vbq))
+               return -EBUSY;
+-      /* Pre-configure format at camera interface input, for JPEG only */
+-      if (fimc_jpeg_fourcc(pix->pixelformat)) {
+-              fimc_capture_try_format(ctx, &pix->width, &pix->height,
+-                                      NULL, &pix->pixelformat,
+-                                      FIMC_SD_PAD_SINK_CAM);
+-              ctx->s_frame.f_width  = pix->width;
+-              ctx->s_frame.f_height = pix->height;
+-      }
+-      /* Try the format at the scaler and the DMA output */
+-      ff->fmt = fimc_capture_try_format(ctx, &pix->width, &pix->height,
+-                                        NULL, &pix->pixelformat,
+-                                        FIMC_SD_PAD_SOURCE);
+-      if (!ff->fmt)
+-              return -EINVAL;
++      ret = __video_try_or_set_format(fimc, f, false, &inp_fmt, &ff->fmt);
++      if (ret < 0)
++              return ret;
+       /* Update RGB Alpha control state and value range */
+       fimc_alpha_ctrl_update(ctx);
+-      /* Try to match format at the host and the sensor */
+-      if (!fimc->vid_cap.user_subdev_api) {
+-              mf->code   = ff->fmt->mbus_code;
+-              mf->width  = pix->width;
+-              mf->height = pix->height;
+-              ret = fimc_pipeline_try_format(ctx, mf, &s_fmt, true);
+-              if (ret)
+-                      return ret;
+-
+-              pix->width  = mf->width;
+-              pix->height = mf->height;
+-      }
+-
+-      fimc_adjust_mplane_format(ff->fmt, pix->width, pix->height, pix);
+-
+-      if (ff->fmt->flags & FMT_FLAGS_COMPRESSED) {
+-              ret = fimc_get_sensor_frame_desc(p->subdevs[IDX_SENSOR],
+-                                      pix->plane_fmt, ff->fmt->memplanes,
+-                                      true);
+-              if (ret < 0)
+-                      return ret;
+-      }
+-
+       for (i = 0; i < ff->fmt->memplanes; i++) {
+               ff->bytesperline[i] = pix->plane_fmt[i].bytesperline;
+               ff->payload[i] = pix->plane_fmt[i].sizeimage;
+@@ -1056,8 +1058,8 @@ static int __fimc_capture_set_format(struct fimc_dev *fimc,
+       fimc_capture_mark_jpeg_xfer(ctx, ff->fmt->color);
+       /* Reset cropping and set format at the camera interface input */
+-      if (!fimc->vid_cap.user_subdev_api) {
+-              ctx->s_frame.fmt = s_fmt;
++      if (!vc->user_subdev_api) {
++              ctx->s_frame.fmt = inp_fmt;
+               set_frame_bounds(&ctx->s_frame, pix->width, pix->height);
+               set_frame_crop(&ctx->s_frame, 0, 0, pix->width, pix->height);
+       }
+@@ -1069,18 +1071,8 @@ static int fimc_cap_s_fmt_mplane(struct file *file, void *priv,
+                                struct v4l2_format *f)
+ {
+       struct fimc_dev *fimc = video_drvdata(file);
+-      int ret;
+-      fimc_md_graph_lock(&fimc->vid_cap.ve);
+-      /*
+-       * The graph is walked within __fimc_capture_set_format() to set
+-       * the format at subdevs thus the graph mutex needs to be held at
+-       * this point.
+-       */
+-      ret = __fimc_capture_set_format(fimc, f);
+-
+-      fimc_md_graph_unlock(&fimc->vid_cap.ve);
+-      return ret;
++      return __fimc_capture_set_format(fimc, f);
+ }
+ static int fimc_cap_enum_input(struct file *file, void *priv,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0224-media-exynos4-is-Move-__fimc_videoc_querycap-functio.patch b/patches.tizen/0224-media-exynos4-is-Move-__fimc_videoc_querycap-functio.patch
new file mode 100644 (file)
index 0000000..e6754d9
--- /dev/null
@@ -0,0 +1,109 @@
+From e08d86bed0a7f5ddd8b2aa46f5977628b894e339 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 31 May 2013 13:47:03 -0300
+Subject: [PATCH 0224/1302] [media] exynos4-is: Move __fimc_videoc_querycap()
+ function to the common module
+
+Move __fimc_videoc_querycap() function to the common exynos4-is-common.ko
+module so it don't need to be reimplemented in multiple video node drivers
+of the exynos4-is.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/common.c    | 12 ++++++++++++
+ drivers/media/platform/exynos4-is/common.h    |  4 ++++
+ drivers/media/platform/exynos4-is/fimc-core.c | 11 -----------
+ drivers/media/platform/exynos4-is/fimc-core.h |  2 --
+ drivers/media/platform/exynos4-is/fimc-m2m.c  |  1 +
+ 5 files changed, 17 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/common.c b/drivers/media/platform/exynos4-is/common.c
+index 57f9010..0ec210b 100644
+--- a/drivers/media/platform/exynos4-is/common.c
++++ b/drivers/media/platform/exynos4-is/common.c
+@@ -38,4 +38,16 @@ struct v4l2_subdev *fimc_find_remote_sensor(struct media_entity *entity)
+ }
+ EXPORT_SYMBOL(fimc_find_remote_sensor);
++void __fimc_vidioc_querycap(struct device *dev, struct v4l2_capability *cap,
++                                              unsigned int caps)
++{
++      strlcpy(cap->driver, dev->driver->name, sizeof(cap->driver));
++      strlcpy(cap->card, dev->driver->name, sizeof(cap->card));
++      snprintf(cap->bus_info, sizeof(cap->bus_info),
++                              "platform:%s", dev_name(dev));
++      cap->device_caps = caps;
++      cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
++}
++EXPORT_SYMBOL(__fimc_vidioc_querycap);
++
+ MODULE_LICENSE("GPL");
+diff --git a/drivers/media/platform/exynos4-is/common.h b/drivers/media/platform/exynos4-is/common.h
+index 3c39803..75b9c71 100644
+--- a/drivers/media/platform/exynos4-is/common.h
++++ b/drivers/media/platform/exynos4-is/common.h
+@@ -6,7 +6,11 @@
+  * published by the Free Software Foundation.
+  */
++#include <linux/device.h>
++#include <linux/videodev2.h>
+ #include <media/media-entity.h>
+ #include <media/v4l2-subdev.h>
+ struct v4l2_subdev *fimc_find_remote_sensor(struct media_entity *entity);
++void __fimc_vidioc_querycap(struct device *dev, struct v4l2_capability *cap,
++                          unsigned int caps);
+diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c
+index e856730..aa6716e 100644
+--- a/drivers/media/platform/exynos4-is/fimc-core.c
++++ b/drivers/media/platform/exynos4-is/fimc-core.c
+@@ -213,17 +213,6 @@ struct fimc_fmt *fimc_get_format(unsigned int index)
+       return &fimc_formats[index];
+ }
+-void __fimc_vidioc_querycap(struct device *dev, struct v4l2_capability *cap,
+-                                              unsigned int caps)
+-{
+-      strlcpy(cap->driver, dev->driver->name, sizeof(cap->driver));
+-      strlcpy(cap->card, dev->driver->name, sizeof(cap->card));
+-      snprintf(cap->bus_info, sizeof(cap->bus_info),
+-                              "platform:%s", dev_name(dev));
+-      cap->device_caps = caps;
+-      cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+-}
+-
+ int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh,
+                           int dw, int dh, int rotation)
+ {
+diff --git a/drivers/media/platform/exynos4-is/fimc-core.h b/drivers/media/platform/exynos4-is/fimc-core.h
+index bba6b25..0f25ce0 100644
+--- a/drivers/media/platform/exynos4-is/fimc-core.h
++++ b/drivers/media/platform/exynos4-is/fimc-core.h
+@@ -621,8 +621,6 @@ static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx,
+ /* fimc-core.c */
+ int fimc_vidioc_enum_fmt_mplane(struct file *file, void *priv,
+                               struct v4l2_fmtdesc *f);
+-void __fimc_vidioc_querycap(struct device *dev, struct v4l2_capability *cap,
+-                                              unsigned int caps);
+ int fimc_ctrls_create(struct fimc_ctx *ctx);
+ void fimc_ctrls_delete(struct fimc_ctx *ctx);
+ void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active);
+diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c
+index bde1f47..8d33b68 100644
+--- a/drivers/media/platform/exynos4-is/fimc-m2m.c
++++ b/drivers/media/platform/exynos4-is/fimc-m2m.c
+@@ -27,6 +27,7 @@
+ #include <media/videobuf2-core.h>
+ #include <media/videobuf2-dma-contig.h>
++#include "common.h"
+ #include "fimc-core.h"
+ #include "fimc-reg.h"
+ #include "media-dev.h"
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0225-media-exynos4-is-Add-isp_dbg-macro.patch b/patches.tizen/0225-media-exynos4-is-Add-isp_dbg-macro.patch
new file mode 100644 (file)
index 0000000..c74ef01
--- /dev/null
@@ -0,0 +1,91 @@
+From 34420f192d96cc03beed2d88db8de6607ea79beb Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 31 May 2013 13:47:04 -0300
+Subject: [PATCH 0225/1302] [media] exynos4-is: Add isp_dbg() macro
+
+Add a debug trace macro for the FIMC-IS ISP subdev and the ISP video
+node drivers which are going to be added in subsequent patches.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-isp.c | 16 ++++++++--------
+ drivers/media/platform/exynos4-is/fimc-isp.h |  5 +++++
+ 2 files changed, 13 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c
+index 3a29e41..ecb82a9 100644
+--- a/drivers/media/platform/exynos4-is/fimc-isp.c
++++ b/drivers/media/platform/exynos4-is/fimc-isp.c
+@@ -30,8 +30,8 @@
+ #include "fimc-is-regs.h"
+ #include "fimc-is.h"
+-static int debug;
+-module_param_named(debug_isp, debug, int, S_IRUGO | S_IWUSR);
++int fimc_isp_debug;
++module_param_named(debug_isp, fimc_isp_debug, int, S_IRUGO | S_IWUSR);
+ static const struct fimc_fmt fimc_isp_formats[FIMC_ISP_NUM_FORMATS] = {
+       {
+@@ -157,8 +157,8 @@ static int fimc_isp_subdev_get_fmt(struct v4l2_subdev *sd,
+       mutex_unlock(&isp->subdev_lock);
+-      v4l2_dbg(1, debug, sd, "%s: pad%d: fmt: 0x%x, %dx%d\n",
+-               __func__, fmt->pad, mf->code, mf->width, mf->height);
++      isp_dbg(1, sd, "%s: pad%d: fmt: 0x%x, %dx%d\n", __func__,
++              fmt->pad, mf->code, mf->width, mf->height);
+       return 0;
+ }
+@@ -191,7 +191,7 @@ static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd,
+       struct v4l2_mbus_framefmt *mf = &fmt->format;
+       int ret = 0;
+-      v4l2_dbg(1, debug, sd, "%s: pad%d: code: 0x%x, %dx%d\n",
++      isp_dbg(1, sd, "%s: pad%d: code: 0x%x, %dx%d\n",
+                __func__, fmt->pad, mf->code, mf->width, mf->height);
+       mf->colorspace = V4L2_COLORSPACE_SRGB;
+@@ -221,7 +221,7 @@ static int fimc_isp_subdev_s_stream(struct v4l2_subdev *sd, int on)
+       struct fimc_is *is = fimc_isp_to_is(isp);
+       int ret;
+-      v4l2_dbg(1, debug, sd, "%s: on: %d\n", __func__, on);
++      isp_dbg(1, sd, "%s: on: %d\n", __func__, on);
+       if (!test_bit(IS_ST_INIT_DONE, &is->state))
+               return -EBUSY;
+@@ -235,8 +235,8 @@ static int fimc_isp_subdev_s_stream(struct v4l2_subdev *sd, int on)
+                               return ret;
+               }
+-              v4l2_dbg(1, debug, sd, "changing mode to %d\n",
+-                                              is->config_index);
++              isp_dbg(1, sd, "changing mode to %d\n", is->config_index);
++
+               ret = fimc_is_itf_mode_change(is);
+               if (ret)
+                       return -EINVAL;
+diff --git a/drivers/media/platform/exynos4-is/fimc-isp.h b/drivers/media/platform/exynos4-is/fimc-isp.h
+index f5c802c..756063e 100644
+--- a/drivers/media/platform/exynos4-is/fimc-isp.h
++++ b/drivers/media/platform/exynos4-is/fimc-isp.h
+@@ -26,6 +26,11 @@
+ #include <media/v4l2-mediabus.h>
+ #include <media/s5p_fimc.h>
++extern int fimc_isp_debug;
++
++#define isp_dbg(level, dev, fmt, arg...) \
++      v4l2_dbg(level, fimc_isp_debug, dev, fmt, ## arg)
++
+ /* FIXME: revisit these constraints */
+ #define FIMC_ISP_SINK_WIDTH_MIN               (16 + 8)
+ #define FIMC_ISP_SINK_HEIGHT_MIN      (12 + 8)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0226-media-media-Change-media-device-link_notify-behaviou.patch b/patches.tizen/0226-media-media-Change-media-device-link_notify-behaviou.patch
new file mode 100644 (file)
index 0000000..e067f6c
--- /dev/null
@@ -0,0 +1,220 @@
+From 9ea8551ecafd1124978ee96c28904828ef002b6f Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 31 May 2013 10:37:26 -0300
+Subject: [PATCH 0226/1302] [media] media: Change media device link_notify
+ behaviour
+
+Currently the media device link_notify callback is invoked before the
+actual change of state of a link when the link is being enabled, and
+after the actual change of state when the link is being disabled.
+This doesn't allow a media device driver to perform any operations
+on a full graph before a link is disabled, as well as performing
+any tasks on a modified graph right after a link's state is changed.
+This patch modifies signature of the link_notify callback. This
+callback is now called always before and after a link's state change.
+To distinguish the notifications a 'notification' argument is added
+to the link_notify callback: MEDIA_DEV_NOTIFY_PRE_LINK_CH indicates
+notification before link's state change and
+MEDIA_DEV_NOTIFY_POST_LINK_CH corresponds to a notification after
+link flags change.
+
+[mchehab@redhat.com: whitespace cleanups]
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Acked-by: Sakari Ailus <sakari.ailus@iki.fi>
+
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/media-entity.c                  | 18 ++++--------
+ drivers/media/platform/exynos4-is/media-dev.c | 18 ++++++------
+ drivers/media/platform/omap3isp/isp.c         | 41 ++++++++++++++++-----------
+ include/media/media-device.h                  |  9 ++++--
+ 4 files changed, 47 insertions(+), 39 deletions(-)
+
+diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
+index 987df7d3..cb30ffb 100644
+--- a/drivers/media/media-entity.c
++++ b/drivers/media/media-entity.c
+@@ -546,25 +546,17 @@ int __media_entity_setup_link(struct media_link *link, u32 flags)
+       mdev = source->parent;
+-      if ((flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify) {
+-              ret = mdev->link_notify(link->source, link->sink,
+-                                      MEDIA_LNK_FL_ENABLED);
++      if (mdev->link_notify) {
++              ret = mdev->link_notify(link, flags,
++                                      MEDIA_DEV_NOTIFY_PRE_LINK_CH);
+               if (ret < 0)
+                       return ret;
+       }
+       ret = __media_entity_setup_link_notify(link, flags);
+-      if (ret < 0)
+-              goto err;
+-      if (!(flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify)
+-              mdev->link_notify(link->source, link->sink, 0);
+-
+-      return 0;
+-
+-err:
+-      if ((flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify)
+-              mdev->link_notify(link->source, link->sink, 0);
++      if (mdev->link_notify)
++              mdev->link_notify(link, flags, MEDIA_DEV_NOTIFY_POST_LINK_CH);
+       return ret;
+ }
+diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
+index 777b74f..2ec2c49 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.c
++++ b/drivers/media/platform/exynos4-is/media-dev.c
+@@ -1287,34 +1287,36 @@ int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on)
+       return __fimc_md_set_camclk(fmd, si, on);
+ }
+-static int fimc_md_link_notify(struct media_pad *source,
+-                             struct media_pad *sink, u32 flags)
++static int fimc_md_link_notify(struct media_link *link, u32 flags,
++                                              unsigned int notification)
+ {
++      struct media_entity *sink = link->sink->entity;
+       struct exynos_video_entity *ve;
+       struct video_device *vdev;
+       struct fimc_pipeline *pipeline;
+       int i, ret = 0;
+-      if (media_entity_type(sink->entity) != MEDIA_ENT_T_DEVNODE_V4L)
++      if (media_entity_type(sink) != MEDIA_ENT_T_DEVNODE_V4L ||
++          notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH)
+               return 0;
+-      vdev = media_entity_to_video_device(sink->entity);
++      vdev = media_entity_to_video_device(sink);
+       ve = vdev_to_exynos_video_entity(vdev);
+       pipeline = to_fimc_pipeline(ve->pipe);
+-      if (!(flags & MEDIA_LNK_FL_ENABLED) && pipeline->subdevs[IDX_SENSOR]) {
+-              if (sink->entity->use_count > 0)
++      if (!(link->flags & MEDIA_LNK_FL_ENABLED) && pipeline->subdevs[IDX_SENSOR]) {
++              if (sink->use_count > 0)
+                       ret = __fimc_pipeline_close(ve->pipe);
+               for (i = 0; i < IDX_MAX; i++)
+                       pipeline->subdevs[i] = NULL;
+-      } else if (sink->entity->use_count > 0) {
++      } else if (sink->use_count > 0) {
+               /*
+                * Link activation. Enable power of pipeline elements only if
+                * the pipeline is already in use, i.e. its video node is open.
+                * Recreate the controls destroyed during the link deactivation.
+                */
+-              ret = __fimc_pipeline_open(ve->pipe, sink->entity, true);
++              ret = __fimc_pipeline_open(ve->pipe, sink, true);
+       }
+       return ret ? -EPIPE : ret;
+diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
+index 4c4bd3d..40b02ba 100644
+--- a/drivers/media/platform/omap3isp/isp.c
++++ b/drivers/media/platform/omap3isp/isp.c
+@@ -792,9 +792,9 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use)
+ /*
+  * isp_pipeline_link_notify - Link management notification callback
+- * @source: Pad at the start of the link
+- * @sink: Pad at the end of the link
++ * @link: The link
+  * @flags: New link flags that will be applied
++ * @notification: The link's state change notification type (MEDIA_DEV_NOTIFY_*)
+  *
+  * React to link management on powered pipelines by updating the use count of
+  * all entities in the source and sink sides of the link. Entities are powered
+@@ -804,29 +804,38 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use)
+  * off is assumed to never fail. This function will not fail for disconnection
+  * events.
+  */
+-static int isp_pipeline_link_notify(struct media_pad *source,
+-                                  struct media_pad *sink, u32 flags)
++static int isp_pipeline_link_notify(struct media_link *link, u32 flags,
++                                  unsigned int notification)
+ {
+-      int source_use = isp_pipeline_pm_use_count(source->entity);
+-      int sink_use = isp_pipeline_pm_use_count(sink->entity);
++      struct media_entity *source = link->source->entity;
++      struct media_entity *sink = link->sink->entity;
++      int source_use = isp_pipeline_pm_use_count(source);
++      int sink_use = isp_pipeline_pm_use_count(sink);
+       int ret;
+-      if (!(flags & MEDIA_LNK_FL_ENABLED)) {
++      if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
++          !(link->flags & MEDIA_LNK_FL_ENABLED)) {
+               /* Powering off entities is assumed to never fail. */
+-              isp_pipeline_pm_power(source->entity, -sink_use);
+-              isp_pipeline_pm_power(sink->entity, -source_use);
++              isp_pipeline_pm_power(source, -sink_use);
++              isp_pipeline_pm_power(sink, -source_use);
+               return 0;
+       }
+-      ret = isp_pipeline_pm_power(source->entity, sink_use);
+-      if (ret < 0)
+-              return ret;
++      if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
++              (flags & MEDIA_LNK_FL_ENABLED)) {
+-      ret = isp_pipeline_pm_power(sink->entity, source_use);
+-      if (ret < 0)
+-              isp_pipeline_pm_power(source->entity, -sink_use);
++              ret = isp_pipeline_pm_power(source, sink_use);
++              if (ret < 0)
++                      return ret;
+-      return ret;
++              ret = isp_pipeline_pm_power(sink, source_use);
++              if (ret < 0)
++                      isp_pipeline_pm_power(source, -sink_use);
++
++              return ret;
++      }
++
++      return 0;
+ }
+ /* -----------------------------------------------------------------------------
+diff --git a/include/media/media-device.h b/include/media/media-device.h
+index eaade98..12155a9 100644
+--- a/include/media/media-device.h
++++ b/include/media/media-device.h
+@@ -45,6 +45,7 @@ struct device;
+  * @entities: List of registered entities
+  * @lock:     Entities list lock
+  * @graph_mutex: Entities graph operation lock
++ * @link_notify: Link state change notification callback
+  *
+  * This structure represents an abstract high-level media device. It allows easy
+  * access to entities and provides basic media device-level support. The
+@@ -75,10 +76,14 @@ struct media_device {
+       /* Serializes graph operations. */
+       struct mutex graph_mutex;
+-      int (*link_notify)(struct media_pad *source,
+-                         struct media_pad *sink, u32 flags);
++      int (*link_notify)(struct media_link *link, u32 flags,
++                         unsigned int notification);
+ };
++/* Supported link_notify @notification values. */
++#define MEDIA_DEV_NOTIFY_PRE_LINK_CH  0
++#define MEDIA_DEV_NOTIFY_POST_LINK_CH 1
++
+ /* media_devnode to media_device */
+ #define to_media_device(node) container_of(node, struct media_device, devnode)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0227-media-exynos4-is-Extend-link_notify-handler-to-suppo.patch b/patches.tizen/0227-media-exynos4-is-Extend-link_notify-handler-to-suppo.patch
new file mode 100644 (file)
index 0000000..f8c7947
--- /dev/null
@@ -0,0 +1,152 @@
+From 8520713cf67297f1a226fbb3e73de2ef62ce3951 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 31 May 2013 10:37:27 -0300
+Subject: [PATCH 0227/1302] [media] exynos4-is: Extend link_notify handler to
+ support fimc-is/lite pipelines
+
+This patch corrects the link_notify handler to support more complex
+pipelines, including fimc-lite and fimc-is entities.
+After the FIMC-IS driver addition the assumptions made in the link_notify
+callback are no longer valid, e.g. the link between fimc-lite subdev and
+its video node is not immutable any more and there is more subdevs than
+just sensor, MIPI-CSIS and FIMC(-LITE).
+The graph is now walked and for each video node found a media pipeline
+which ends at this node is disabled/enabled (the subdevs are powered
+on/off).
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/media-dev.c | 103 ++++++++++++++++++++------
+ 1 file changed, 81 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
+index 2ec2c49..91f21e2 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.c
++++ b/drivers/media/platform/exynos4-is/media-dev.c
+@@ -1287,39 +1287,98 @@ int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on)
+       return __fimc_md_set_camclk(fmd, si, on);
+ }
+-static int fimc_md_link_notify(struct media_link *link, u32 flags,
+-                                              unsigned int notification)
++static int __fimc_md_modify_pipeline(struct media_entity *entity, bool enable)
+ {
+-      struct media_entity *sink = link->sink->entity;
+       struct exynos_video_entity *ve;
++      struct fimc_pipeline *p;
+       struct video_device *vdev;
+-      struct fimc_pipeline *pipeline;
+-      int i, ret = 0;
++      int ret;
+-      if (media_entity_type(sink) != MEDIA_ENT_T_DEVNODE_V4L ||
+-          notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH)
++      vdev = media_entity_to_video_device(entity);
++      if (vdev->entity.use_count == 0)
+               return 0;
+-      vdev = media_entity_to_video_device(sink);
+       ve = vdev_to_exynos_video_entity(vdev);
+-      pipeline = to_fimc_pipeline(ve->pipe);
++      p = to_fimc_pipeline(ve->pipe);
++      /*
++       * Nothing to do if we are disabling the pipeline, some link
++       * has been disconnected and p->subdevs array is cleared now.
++       */
++      if (!enable && p->subdevs[IDX_SENSOR] == NULL)
++              return 0;
+-      if (!(link->flags & MEDIA_LNK_FL_ENABLED) && pipeline->subdevs[IDX_SENSOR]) {
+-              if (sink->use_count > 0)
+-                      ret = __fimc_pipeline_close(ve->pipe);
++      if (enable)
++              ret = __fimc_pipeline_open(ve->pipe, entity, true);
++      else
++              ret = __fimc_pipeline_close(ve->pipe);
+-              for (i = 0; i < IDX_MAX; i++)
+-                      pipeline->subdevs[i] = NULL;
+-      } else if (sink->use_count > 0) {
+-              /*
+-               * Link activation. Enable power of pipeline elements only if
+-               * the pipeline is already in use, i.e. its video node is open.
+-               * Recreate the controls destroyed during the link deactivation.
+-               */
+-              ret = __fimc_pipeline_open(ve->pipe, sink, true);
++      if (ret == 0 && !enable)
++              memset(p->subdevs, 0, sizeof(p->subdevs));
++
++      return ret;
++}
++
++/* Locking: called with entity->parent->graph_mutex mutex held. */
++static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)
++{
++      struct media_entity *entity_err = entity;
++      struct media_entity_graph graph;
++      int ret;
++
++      /*
++       * Walk current graph and call the pipeline open/close routine for each
++       * opened video node that belongs to the graph of entities connected
++       * through active links. This is needed as we cannot power on/off the
++       * subdevs in random order.
++       */
++      media_entity_graph_walk_start(&graph, entity);
++
++      while ((entity = media_entity_graph_walk_next(&graph))) {
++              if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
++                      continue;
++
++              ret  = __fimc_md_modify_pipeline(entity, enable);
++
++              if (ret < 0)
++                      goto err;
++      }
++
++      return 0;
++ err:
++      media_entity_graph_walk_start(&graph, entity_err);
++
++      while ((entity_err = media_entity_graph_walk_next(&graph))) {
++              if (media_entity_type(entity_err) != MEDIA_ENT_T_DEVNODE)
++                      continue;
++
++              __fimc_md_modify_pipeline(entity_err, !enable);
++
++              if (entity_err == entity)
++                      break;
++      }
++
++      return ret;
++}
++
++static int fimc_md_link_notify(struct media_link *link, unsigned int flags,
++                              unsigned int notification)
++{
++      struct media_entity *sink = link->sink->entity;
++      int ret = 0;
++
++      /* Before link disconnection */
++      if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH) {
++              if (!(flags & MEDIA_LNK_FL_ENABLED))
++                      ret = __fimc_md_modify_pipelines(sink, false);
++              else
++                      ; /* TODO: Link state change validation */
++      /* After link activation */
++      } else if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
++                 (link->flags & MEDIA_LNK_FL_ENABLED)) {
++              ret = __fimc_md_modify_pipelines(sink, true);
+       }
+-      return ret ? -EPIPE : ret;
++      return ret ? -EPIPE : 0;
+ }
+ static ssize_t fimc_md_sysfs_show(struct device *dev,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0228-clk-exynos4-Add-clock-entries-for-TMU.patch b/patches.tizen/0228-clk-exynos4-Add-clock-entries-for-TMU.patch
new file mode 100644 (file)
index 0000000..d7127b8
--- /dev/null
@@ -0,0 +1,61 @@
+From 1d3cdd41daa1da8e9070f86a3eb2a341c4cff554 Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Mon, 22 Apr 2013 02:55:46 +0000
+Subject: [PATCH 0228/1302] clk: exynos4: Add clock entries for TMU
+
+Added clock entries for thermal management unit (TMU) for
+Exynos4 SoCs.
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Cc: Thomas Abraham <thomas.abraham@linaro.org>
+Cc: Mike Turquette <mturquette@linaro.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/devicetree/bindings/clock/exynos4-clock.txt | 1 +
+ drivers/clk/samsung/clk-exynos4.c                         | 4 +++-
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/Documentation/devicetree/bindings/clock/exynos4-clock.txt b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
+index 9017baa..76feb47 100644
+--- a/Documentation/devicetree/bindings/clock/exynos4-clock.txt
++++ b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
+@@ -236,6 +236,7 @@ Exynos4 SoC and this is specified where applicable.
+   spi0_isp_sclk       380     Exynos4x12
+   spi1_isp_sclk       381     Exynos4x12
+   uart_isp_sclk       382     Exynos4x12
++  tmu_apbif         383
+               [Mux Clocks]
+diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
+index c84247a..be86c98 100644
+--- a/drivers/clk/samsung/clk-exynos4.c
++++ b/drivers/clk/samsung/clk-exynos4.c
+@@ -172,7 +172,7 @@ enum exynos4_clks {
+       gicisp, smmu_isp, smmu_drc, smmu_fd, smmu_lite0, smmu_lite1, mcuctl_isp,
+       mpwm_isp, i2c0_isp, i2c1_isp, mtcadc_isp, pwm_isp, wdt_isp, uart_isp,
+       asyncaxim, smmu_ispcx, spi0_isp, spi1_isp, pwm_isp_sclk, spi0_isp_sclk,
+-      spi1_isp_sclk, uart_isp_sclk,
++      spi1_isp_sclk, uart_isp_sclk, tmu_apbif,
+       /* mux clocks */
+       mout_fimc0 = 384, mout_fimc1, mout_fimc2, mout_fimc3, mout_cam0,
+@@ -814,6 +814,7 @@ struct samsung_gate_clock exynos4210_gate_clks[] __initdata = {
+       GATE_A(keyif, "keyif", "aclk100", E4210_GATE_IP_PERIR, 16, 0, 0, "keypad"),
+       GATE_DA(sclk_fimd1, "exynos4-fb.1", "sclk_fimd1", "div_fimd1",
+                       E4210_SRC_MASK_LCD1, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"),
++      GATE(tmu_apbif, "tmu_apbif", "aclk100", E4210_GATE_IP_PERIR, 17, 0, 0),
+ };
+ /* list of gate clocks supported in exynos4x12 soc */
+@@ -840,6 +841,7 @@ struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = {
+       GATE_A(rtc, "rtc", "aclk100", E4X12_GATE_IP_PERIR, 15, 0, 0, "rtc"),
+       GATE_A(keyif, "keyif", "aclk100",
+                       E4X12_GATE_IP_PERIR, 16, 0, 0, "keypad"),
++      GATE(tmu_apbif, "tmu_apbif", "aclk100", E4X12_GATE_IP_PERIR, 17, 0, 0),
+       GATE(sclk_pwm_isp, "sclk_pwm_isp", "div_pwm_isp",
+                       E4X12_SRC_MASK_ISP, 0, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_spi0_isp, "sclk_spi0_isp", "div_spi0_isp_pre",
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0229-ARM-dts-thermal-exynos4-TMU-device-tree-support-for-.patch b/patches.tizen/0229-ARM-dts-thermal-exynos4-TMU-device-tree-support-for-.patch
new file mode 100644 (file)
index 0000000..20759ef
--- /dev/null
@@ -0,0 +1,37 @@
+From e6c2dd06665c1192987f77bafcae8eae4f280cff Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Fri, 19 Apr 2013 16:45:53 +0200
+Subject: [PATCH 0229/1302] ARM: dts: thermal: exynos4: TMU device tree support
+ for Exynos4412 targets
+
+Device tree support for TMU at Exynos4x12 targets.
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12.dtsi | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index c0c75d9..1364030 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -338,4 +338,14 @@
+                                                               "mout_apll";
+               status = "disabled";
+       };
++
++      tmu@100C0000 {
++              compatible = "samsung,exynos4412-tmu";
++              interrupt-parent = <&combiner>;
++              reg = <0x100C0000 0x100>;
++              interrupts = <2 4>;
++              clocks = <&clock 383>;
++              clock-names = "tmu_apbif";
++              status = "disabled";
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0230-Thermal-exynos-Support-for-TMU-regulator-defined-at-.patch b/patches.tizen/0230-Thermal-exynos-Support-for-TMU-regulator-defined-at-.patch
new file mode 100644 (file)
index 0000000..8bba1c4
--- /dev/null
@@ -0,0 +1,71 @@
+From 7ae7d14821714bfda8bf052e683d8a7863a2d982 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Fri, 19 Apr 2013 17:09:21 +0200
+Subject: [PATCH 0230/1302] Thermal: exynos: Support for TMU regulator defined
+ at device tree
+
+TMU probe function now checks for a device tree defined regulator.
+For compatibility reasons it is allowed to probe driver even without
+this regulator defined.
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/exynos_thermal.c | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+diff --git a/drivers/thermal/exynos_thermal.c b/drivers/thermal/exynos_thermal.c
+index 788b1dd..84794b3 100644
+--- a/drivers/thermal/exynos_thermal.c
++++ b/drivers/thermal/exynos_thermal.c
+@@ -38,6 +38,7 @@
+ #include <linux/cpufreq.h>
+ #include <linux/cpu_cooling.h>
+ #include <linux/of.h>
++#include <linux/regulator/consumer.h>
+ /* Exynos generic registers */
+ #define EXYNOS_TMU_REG_TRIMINFO               0x0
+@@ -117,6 +118,8 @@
+ #define EXYNOS_ZONE_COUNT     3
++#define EXYNOS_TMU_REGULATOR "vdd_ts"
++
+ struct exynos_tmu_data {
+       struct exynos_tmu_platform_data *pdata;
+       struct resource *mem;
+@@ -900,6 +903,7 @@ static int exynos_tmu_probe(struct platform_device *pdev)
+ {
+       struct exynos_tmu_data *data;
+       struct exynos_tmu_platform_data *pdata = pdev->dev.platform_data;
++      struct regulator *reg;
+       int ret, i;
+       if (!pdata)
+@@ -909,6 +913,21 @@ static int exynos_tmu_probe(struct platform_device *pdev)
+               dev_err(&pdev->dev, "No platform init data supplied.\n");
+               return -ENODEV;
+       }
++
++      reg = regulator_get(&pdev->dev, EXYNOS_TMU_REGULATOR);
++      if (!IS_ERR(reg)) {
++              ret = regulator_enable(reg);
++              if (ret) {
++                      dev_err(&pdev->dev, "Regulator %s not enabled.\n",
++                              EXYNOS_TMU_REGULATOR);
++                      return ret;
++              }
++      } else {
++              dev_warn(&pdev->dev,
++                       "Regulator %s not defined at device tree.\n",
++                       EXYNOS_TMU_REGULATOR);
++      }
++
+       data = devm_kzalloc(&pdev->dev, sizeof(struct exynos_tmu_data),
+                                       GFP_KERNEL);
+       if (!data) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0231-ARM-dts-thermal-exynos4-Add-documentation-for-Exynos.patch b/patches.tizen/0231-ARM-dts-thermal-exynos4-Add-documentation-for-Exynos.patch
new file mode 100644 (file)
index 0000000..50642c6
--- /dev/null
@@ -0,0 +1,51 @@
+From c606915595ff774eb6072c37fae7ef7da028c2e4 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Fri, 19 Apr 2013 17:31:16 +0200
+Subject: [PATCH 0231/1302] ARM: dts: thermal: exynos4: Add documentation for
+ Exynos SoC thermal bindings
+
+Proper description for Exynos4 bindings added to Documentation/devicetree/
+bindings
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/thermal/exynos-thermal.txt | 25 ++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/thermal/exynos-thermal.txt
+
+diff --git a/Documentation/devicetree/bindings/thermal/exynos-thermal.txt b/Documentation/devicetree/bindings/thermal/exynos-thermal.txt
+new file mode 100644
+index 0000000..535fd0e
+--- /dev/null
++++ b/Documentation/devicetree/bindings/thermal/exynos-thermal.txt
+@@ -0,0 +1,25 @@
++* Exynos Thermal Management Unit (TMU)
++
++** Required properties:
++
++- compatible : One of the following:
++             "samsung,exynos4412-tmu"
++             "samsung,exynos4210-tmu"
++             "samsung,exynos5250-tmu"
++- interrupt-parent : The phandle for the interrupt controller
++- reg : Address range of the thermal registers
++- interrupts : Should contain interrupt for thermal system
++- clocks : The main clock for TMU device
++- clock-names : Thermal system clock name
++
++Example:
++
++      tmu@100C0000 {
++              compatible = "samsung,exynos4412-tmu";
++              interrupt-parent = <&combiner>;
++              reg = <0x100C0000 0x100>;
++              interrupts = <2 4>;
++              clocks = <&clock 383>;
++              clock-names = "tmu_apbif";
++              status = "disabled";
++      };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0232-ARM-dts-thermal-exynos4-TMU-voltage-regulator-suppor.patch b/patches.tizen/0232-ARM-dts-thermal-exynos4-TMU-voltage-regulator-suppor.patch
new file mode 100644 (file)
index 0000000..1fbe026
--- /dev/null
@@ -0,0 +1,40 @@
+From a141f154c731efd0478713c1ffc12133965e15d4 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Fri, 19 Apr 2013 16:50:42 +0200
+Subject: [PATCH 0232/1302] ARM: dts: thermal: exynos4: TMU voltage regulator
+ support at REDWOOD
+
+This regulator must be enabled at REDWOOD target to allow temperature
+sensor to work.
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-redwood.dts | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-redwood.dts b/arch/arm/boot/dts/exynos4412-redwood.dts
+index 0f86fea..6ceeb8d 100644
+--- a/arch/arm/boot/dts/exynos4412-redwood.dts
++++ b/arch/arm/boot/dts/exynos4412-redwood.dts
+@@ -661,4 +661,16 @@
+               status = "okay";
+               vdd_g3d-supply = <&buck4_reg>;
+       };
++
++      cpufreq {
++              status = "okay";
++              overclocking = "okay";
++              max_overclocking_freq = <1500000>;
++      };
++
++      tmu@100C0000 {
++              vdd_ts-supply = <&ldo10_reg>;
++              status = "okay";
++      };
++
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0233-ARM-dts-Support-device-tree-of-fuel-gauge-max77693-i.patch b/patches.tizen/0233-ARM-dts-Support-device-tree-of-fuel-gauge-max77693-i.patch
new file mode 100644 (file)
index 0000000..2d0331c
--- /dev/null
@@ -0,0 +1,42 @@
+From 5c8941a2c5f95aad9838f2ba83f67183ee59aa8d Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Thu, 9 May 2013 20:26:09 +0900
+Subject: [PATCH 0233/1302] ARM: dts: Support device tree of fuel
+ gauge(max77693) in PQ/M0
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 062b204..672d720 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -588,6 +588,22 @@
+               };      
+       };
++      i2c_fuel: i2c@1 {
++              compatible = "i2c-gpio";
++              gpios = <&gpf1 5 0
++                       &gpf1 4 0
++                      >;
++              #address-cells = <1>;
++              #size-cells = <0>;
++
++              max17047@36 {
++                      compatible = "maxim,max17047";
++                      interrupt-parent = <&gpx2>;
++                      interrupts = <3 2>;
++                      reg = <0x36>;
++              };
++      };
++
+       lcd_vdd3_reg: voltage-regulator@1 {
+               compatible = "regulator-fixed";
+               regulator-name = "LCD_VDD_2.2V";
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0234-fuelgauge-max1704xx-Fix-max17042-driver-to-work-prop.patch b/patches.tizen/0234-fuelgauge-max1704xx-Fix-max17042-driver-to-work-prop.patch
new file mode 100644 (file)
index 0000000..bfb84d1
--- /dev/null
@@ -0,0 +1,54 @@
+From a1c724db8d164796311b4c14d840e398201eac20 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Thu, 9 May 2013 20:29:13 +0900
+Subject: [PATCH 0234/1302] fuelgauge: max1704xx: Fix max17042 driver to work
+ properly.
+
+Fixed :
+- Read battery capacity from VFG(voltage fuel gauge) for ModelGuage M1.
+- Fix error of registering alarm irq to generic irq framework.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/power/max17042_battery.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/power/max17042_battery.c b/drivers/power/max17042_battery.c
+index d664ef5..ab5324b 100644
+--- a/drivers/power/max17042_battery.c
++++ b/drivers/power/max17042_battery.c
+@@ -126,6 +126,7 @@ static int max17042_get_property(struct power_supply *psy,
+       struct max17042_chip *chip = container_of(psy,
+                               struct max17042_chip, battery);
+       int ret;
++      u8 reg;
+       if (!chip->init_complete)
+               return -EAGAIN;
+@@ -189,7 +190,12 @@ static int max17042_get_property(struct power_supply *psy,
+               val->intval = ret * 625 / 8;
+               break;
+       case POWER_SUPPLY_PROP_CAPACITY:
+-              ret = max17042_read_reg(chip->client, MAX17042_RepSOC);
++              if (chip->pdata->enable_current_sense)
++                      reg = MAX17042_RepSOC;
++              else
++                      reg = MAX17042_VFSOC;           /* SOC from VFG */
++
++              ret = max17042_read_reg(chip->client, reg);
+               if (ret < 0)
+                       return ret;
+@@ -751,7 +757,7 @@ static int max17042_probe(struct i2c_client *client,
+       if (client->irq) {
+               ret = request_threaded_irq(client->irq, NULL,
+                                               max17042_thread_handler,
+-                                              IRQF_TRIGGER_FALLING,
++                                              IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+                                               chip->battery.name, chip);
+               if (!ret) {
+                       reg =  max17042_read_reg(client, MAX17042_CONFIG);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0235-ARM-dts-Modify-lps331ap-device-node-for-PQ-M0-board.patch b/patches.tizen/0235-ARM-dts-Modify-lps331ap-device-node-for-PQ-M0-board.patch
new file mode 100644 (file)
index 0000000..d71b067
--- /dev/null
@@ -0,0 +1,47 @@
+From 7079855f42e08955fac651bc1124707fb59abcd5 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 9 May 2013 17:50:17 +0200
+Subject: [PATCH 0235/1302] ARM: dts: Modify lps331ap device node for PQ/M0
+ board
+
+This patch adds interrupt-map support for the lps331ap
+device node for PQ/M0 board, so that it facilitates
+passing information about device's interrupt sources used.
+
+Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 672d720..d8d8351 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -163,10 +163,19 @@
+               #size-cells = <0>;
+               status = "okay";
+-              lps331ap@5D {
++              lps331ap@5d {
+                       compatible = "lps331ap";
+-                      reg = <0x5D>;
+-                      gpios = <&gpf0 5 0>;
++                      reg = <0x5d>;
++                      gpios = <&gpf0 5 0>; /* Used only by legacy driver */
++                      interrupt-parent = <&irq_map>;
++                      interrupts = <0>, <1>;
++
++                      irq_map: irq-map {
++                              #interrupt-cells = <1>;
++                              #address-cells = <0>;
++                              #size-cells = <0>;
++                              interrupt-map = <1 &gpf0 5 0>;
++                      };
+               };
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0236-arm-dts-Update-max77686-s-device-tree-for-M0-PQ.patch b/patches.tizen/0236-arm-dts-Update-max77686-s-device-tree-for-M0-PQ.patch
new file mode 100644 (file)
index 0000000..4855d08
--- /dev/null
@@ -0,0 +1,63 @@
+From b8c914272fa254664973ba9e438b4f564596dede Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Fri, 10 May 2013 17:58:35 +0900
+Subject: [PATCH 0236/1302] arm: dts: Update max77686's device tree for M0/PQ.
+
+- IRQ type update : from 0 to 2 (FALLING_EDGE)
+- Remove unnecessary data : consumer supplies, min/max uV..
+- Change data of charger ldo from voltage to current.
+
+[s.nawrocki: redundant closing parenthesis removed to fix build break]
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 17 +++++------------
+ 1 file changed, 5 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index d8d8351..7e89324 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -555,7 +555,7 @@
+               max77693@66 {
+                       compatible = "maxim,max77693";
+                       interrupt-parent = <&gpx1>;
+-                      interrupts = <5 0>;
++                      interrupts = <5 2>;
+                       wakeup = <1>;
+                       reg = <0x66>;
+@@ -563,25 +563,18 @@
+                               esafeout@1 {
+                                       regulator-compatible = "ESAFEOUT1";
+                                       regulator-name = "ESAFEOUT1";
+-                                      regulator-min-microvolt = <4900000>;
+-                                      regulator-max-microvolt = <4900000>;
++                                      regulator-boot-on;
+                               };
+                               esafeout@2 {
+                                       regulator-compatible = "ESAFEOUT2";
+                                       regulator-name = "ESAFEOUT2";
+-                                      regulator-min-microvolt = <4900000>;
+-                                      regulator-max-microvolt = <4900000>;
+                               };
+                               charger@0 {
+                                       regulator-compatible = "CHARGER";
+                                       regulator-name = "CHARGER";
+-                                      regulator-min-microvolt = <100000>;
+-                                      regulator-max-microvolt = <2100000>;
+-                                      number-of-consumer-supplies = <1>;
+-                                      consumer-suppilies@0 {
+-                                              consumer-name = "vinchg1";
+-                                              supply-name = "charger-manager.0";
+-                                      };
++                                      regulator-min-microamp = <60000>;
++                                      regulator-max-microamp = <2580000>;
++                                      regulator-boot-on;
+                               };
+                       };
+                       muic_regs {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0237-s5k5baf-add-camera-sensor-driver.patch b/patches.tizen/0237-s5k5baf-add-camera-sensor-driver.patch
new file mode 100644 (file)
index 0000000..9f854ee
--- /dev/null
@@ -0,0 +1,2194 @@
+From 5c0169f9ef453886c7640255ac399dd03ae94157 Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Fri, 10 May 2013 15:44:15 +0200
+Subject: [PATCH 0237/1302] s5k5baf: add camera sensor driver
+
+Driver for Samsung S5K5BAF UXGA 1/5" 2M CMOS Image Sensor with embedded
+SoC ISP. The driver exposes the sensor as two V4L2 subdevices:
+
+- S5K5BAF-CIS - pure CMOS Image Sensor, fixed 1600x1200 format,
+  no controls.
+- S5K5BAF-ISP - Image Signal Processor, formats up to 1600x1200,
+  pre/post ISP cropping, downscaling via selection API, controls.
+
+The private V4L2_CID_{RED/GREEN/BLUE}_GAIN controls will be replaced
+with V4L2_CID_{RED/BLUE}_BALANCE controls in subsequent patch.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+---
+v3:
+- narrowed state->error usage to i2c and power errors
+
+v2:
+- lower-cased driver name,
+- removed underscore from regulator names,
+- removed platform data code,
+- v4l controls grouped in anonymous structs,
+- added s5k5baf_clear_error function,
+- private controls definitions moved to uapi header file,
+- added v4l2-controls.h reservation for private controls,
+- corrected subdev registered/unregistered code,
+- .log_status sudbev op set to v4l2 helper,
+- moved entity link creation to probe routines,
+- added cleanup on error to probe function.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/media/samsung-s5k5baf.txt  |   53 +
+ MAINTAINERS                                        |    8 +
+ drivers/media/i2c/Kconfig                          |    7 +
+ drivers/media/i2c/Makefile                         |    1 +
+ drivers/media/i2c/s5k5baf.c                        | 1986 ++++++++++++++++++++
+ include/uapi/linux/s5k5baf.h                       |   19 +
+ include/uapi/linux/v4l2-controls.h                 |    5 +
+ 7 files changed, 2079 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/media/samsung-s5k5baf.txt
+ create mode 100644 drivers/media/i2c/s5k5baf.c
+ create mode 100644 include/uapi/linux/s5k5baf.h
+
+diff --git a/Documentation/devicetree/bindings/media/samsung-s5k5baf.txt b/Documentation/devicetree/bindings/media/samsung-s5k5baf.txt
+new file mode 100644
+index 0000000..0e46743
+--- /dev/null
++++ b/Documentation/devicetree/bindings/media/samsung-s5k5baf.txt
+@@ -0,0 +1,53 @@
++Samsung S5K5BAF UXGA 1/5" 2M CMOS Image Sensor with embedded SoC ISP
++-------------------------------------------------------------
++
++Required properties:
++
++- compatible    : "samsung,s5k5baf";
++- reg           : i2c slave address of the sensor;
++- vdda-supply   : analog power supply 2.8V (2.6V to 3.0V);
++- vddreg-supply         : regulator input power supply 1.8V (1.7V to 1.9V)
++                    or 2.8V (2.6V to 3.0);
++- vddio-supply          : I/O power supply 1.8V (1.65V to 1.95V)
++                    or 2.8V (2.5V to 3.1V);
++- gpios                 : GPIOs connected to STDBYN and RSTN pins,
++                    in order: STBYN, RSTN;
++- clock-frequency : master clock frequency in Hz;
++
++Optional properties:
++
++- clocks        : contains the sensor's master clock specifier;
++- clock-names   : contains "mclk" entry;
++- samsung,hflip         : horizontal image flip;
++- samsung,vflip         : vertical image flip;
++
++The device node should contain one 'port' child node with one child 'endpoint'
++node, according to the bindings defined in Documentation/devicetree/bindings/
++media/video-interfaces.txt. The following are properties specific to those nodes.
++
++endpoint node
++-------------
++
++- data-lanes    : (optional) an array specifying active physical MIPI-CSI2
++                  data output lanes and their mapping to logical lanes; the
++                  array's content is unused, only its length is meaningful;
++
++Example:
++
++s5k5bafx@2d {
++      compatible = "samsung,s5k5baf";
++      reg = <0x2d>;
++      vdda-supply = <&cam_io_en_reg>;
++      vdd_reg-supply = <&vt_core_15v_reg>;
++      vddio-supply = <&vtcam_reg>;
++      gpios = <&gpl2 0 1>,
++              <&gpl2 1 1>;
++      clock-frequency = <24000000>;
++
++      port {
++              s5k5bafx_ep: endpoint {
++                      remote-endpoint = <&csis1_ep>;
++                      data-lanes = <1>;
++              };
++      };
++};
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 48c7480..0775741 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -6980,6 +6980,14 @@ L:      linux-media@vger.kernel.org
+ S:    Supported
+ F:    drivers/media/i2c/s5c73m3/*
++SAMSUNG S5K5BAF CAMERA DRIVER
++M:    Kyungmin Park <kyungmin.park@samsung.com>
++M:    Andrzej Hajda <a.hajda@samsung.com>
++L:    linux-media@vger.kernel.org
++S:    Supported
++F:    drivers/media/i2c/s5k5baf.c
++F:    include/media/s5k5baf.h
++
+ SERIAL DRIVERS
+ M:    Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ L:    linux-serial@vger.kernel.org
+diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
+index f981d50..9c6279a 100644
+--- a/drivers/media/i2c/Kconfig
++++ b/drivers/media/i2c/Kconfig
+@@ -553,6 +553,13 @@ config VIDEO_S5K4ECGX
+           This is a V4L2 sensor-level driver for Samsung S5K4ECGX 5M
+           camera sensor with an embedded SoC image signal processor.
++config VIDEO_S5K5BAF
++      tristate "Samsung S5K5BAF sensor support"
++      depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
++      ---help---
++        This is a V4L2 sensor-level driver for Samsung S5K5BAF 2M
++        camera sensor with an embedded SoC image signal processor.
++
+ source "drivers/media/i2c/smiapp/Kconfig"
+ config VIDEO_S5C73M3
+diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
+index 720f42d..6aeef24 100644
+--- a/drivers/media/i2c/Makefile
++++ b/drivers/media/i2c/Makefile
+@@ -64,6 +64,7 @@ obj-$(CONFIG_VIDEO_SR030PC30)        += sr030pc30.o
+ obj-$(CONFIG_VIDEO_NOON010PC30)       += noon010pc30.o
+ obj-$(CONFIG_VIDEO_S5K6AA)    += s5k6aa.o
+ obj-$(CONFIG_VIDEO_S5K4ECGX)  += s5k4ecgx.o
++obj-$(CONFIG_VIDEO_S5K5BAF)   += s5k5baf.o
+ obj-$(CONFIG_VIDEO_S5C73M3)   += s5c73m3/
+ obj-$(CONFIG_VIDEO_ADP1653)   += adp1653.o
+ obj-$(CONFIG_VIDEO_AS3645A)   += as3645a.o
+diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
+new file mode 100644
+index 0000000..cb4eec0
+--- /dev/null
++++ b/drivers/media/i2c/s5k5baf.c
+@@ -0,0 +1,1986 @@
++/*
++ * Driver for Samsung S5K5BAF UXGA 1/5" 2M CMOS Image Sensor
++ * with embedded SoC ISP.
++ *
++ * Copyright (C) 2013, Samsung Electronics Co., Ltd.
++ * Andrzej Hajda <a.hajda@samsung.com>
++ *
++ * Based on S5K6AA driver authored by Sylwester Nawrocki
++ * Copyright (C) 2013, Samsung Electronics Co., Ltd.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/gpio.h>
++#include <linux/i2c.h>
++#include <linux/media.h>
++#include <linux/module.h>
++#include <linux/of_gpio.h>
++#include <linux/regulator/consumer.h>
++#include <linux/s5k5baf.h>
++#include <linux/slab.h>
++
++#include <media/media-entity.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-subdev.h>
++#include <media/v4l2-mediabus.h>
++#include <media/v4l2-of.h>
++
++static int debug;
++module_param(debug, int, 0644);
++
++#define S5K5BAF_DRIVER_NAME           "s5k5baf"
++
++#define S5K5BAF_OUT_WIDTH_DEF         640
++#define S5K5BAF_OUT_HEIGHT_DEF                480
++#define S5K5BAF_CIS_WIDTH             1600
++#define S5K5BAF_CIS_HEIGHT            1200
++#define S5K5BAF_WIN_WIDTH_MIN         8
++#define S5K5BAF_WIN_HEIGHT_MIN                8
++
++#define AHB_MSB_ADDR_PTR              0xfcfc
++
++/*
++ * Register interface pages (the most significant word of the address)
++ */
++#define PAGE_IF_HW                    0xd000
++#define PAGE_IF_SW                    0x7000
++
++/*
++ * H/W register Interface (PAGE_IF_HW)
++ */
++#define REG_SW_LOAD_COMPLETE          0x0014
++#define REG_CMDWR_PAGE                        0x0028
++#define REG_CMDWR_ADDR                        0x002a
++#define REG_CMDRD_PAGE                        0x002c
++#define REG_CMDRD_ADDR                        0x002e
++#define REG_CMD_BUF                   0x0f12
++#define REG_SET_HOST_INT              0x1000
++#define REG_CLEAR_HOST_INT            0x1030
++#define REG_PATTERN_SET                       0x3100
++#define REG_PATTERN_WIDTH             0x3118
++#define REG_PATTERN_HEIGHT            0x311a
++#define REG_PATTERN_PARAM             0x311c
++
++/*
++ * S/W register interface (PAGE_IF_SW)
++ */
++
++/* Firmware revision information */
++#define REG_FW_APIVER                 0x012e
++#define  S5K5BAF_FW_APIVER            0x0001
++#define REG_FW_REVISION                       0x0130
++#define REG_FW_SENSOR_ID              0x0152
++
++/* Initialization parameters */
++/* Master clock frequency in KHz */
++#define REG_I_INCLK_FREQ_L            0x01b8
++#define REG_I_INCLK_FREQ_H            0x01ba
++#define  MIN_MCLK_FREQ_KHZ            6000U
++#define  MAX_MCLK_FREQ_KHZ            48000U
++#define REG_I_USE_NPVI_CLOCKS         0x01c6
++#define  NPVI_CLOCKS                  1
++#define REG_I_USE_NMIPI_CLOCKS                0x01c8
++#define  NMIPI_CLOCKS                 1
++#define REG_I_BLOCK_INTERNAL_PLL_CALC 0x01ca
++
++/* Clock configurations, n = 0..2. REG_I_* frequency unit is 4 kHz. */
++#define REG_I_OPCLK_4KHZ(n)           ((n) * 6 + 0x01cc)
++#define REG_I_MIN_OUTRATE_4KHZ(n)     ((n) * 6 + 0x01ce)
++#define REG_I_MAX_OUTRATE_4KHZ(n)     ((n) * 6 + 0x01d0)
++#define  SCLK_PVI_FREQ                        24000
++#define  SCLK_MIPI_FREQ                       48000
++#define  PCLK_MIN_FREQ                        6000
++#define  PCLK_MAX_FREQ                        48000
++#define REG_I_USE_REGS_API            0x01de
++#define REG_I_INIT_PARAMS_UPDATED     0x01e0
++#define REG_I_ERROR_INFO              0x01e2
++
++/* General purpose parameters */
++#define REG_USER_BRIGHTNESS           0x01e4
++#define REG_USER_CONTRAST             0x01e6
++#define REG_USER_SATURATION           0x01e8
++#define REG_USER_SHARPBLUR            0x01ea
++
++#define REG_G_SPEC_EFFECTS            0x01ee
++#define REG_G_ENABLE_PREV             0x01f0
++#define REG_G_ENABLE_PREV_CHG         0x01f2
++#define REG_G_NEW_CFG_SYNC            0x01f8
++#define REG_G_PREVREQ_IN_WIDTH                0x01fa
++#define REG_G_PREVREQ_IN_HEIGHT               0x01fc
++#define REG_G_PREVREQ_IN_XOFFS                0x01fe
++#define REG_G_PREVREQ_IN_YOFFS                0x0200
++#define REG_G_PREVZOOM_IN_WIDTH               0x020a
++#define REG_G_PREVZOOM_IN_HEIGHT      0x020c
++#define REG_G_PREVZOOM_IN_XOFFS               0x020e
++#define REG_G_PREVZOOM_IN_YOFFS               0x0210
++#define REG_G_INPUTS_CHANGE_REQ               0x021a
++#define REG_G_ACTIVE_PREV_CFG         0x021c
++#define REG_G_PREV_CFG_CHG            0x021e
++#define REG_G_PREV_OPEN_AFTER_CH      0x0220
++#define REG_G_PREV_CFG_ERROR          0x0222
++#define  CFG_ERROR_RANGE              0x0b
++#define REG_G_PREV_CFG_BYPASS_CHANGED 0x022a
++#define REG_G_ACTUAL_P_FR_TIME                0x023a
++#define REG_G_ACTUAL_P_OUT_RATE               0x023c
++#define REG_G_ACTUAL_C_FR_TIME                0x023e
++#define REG_G_ACTUAL_C_OUT_RATE               0x0240
++
++/* Preview control section. n = 0...4. */
++#define PREG(n, x)                    ((n) * 0x26 + x)
++#define REG_P_OUT_WIDTH(n)            PREG(n, 0x0242)
++#define REG_P_OUT_HEIGHT(n)           PREG(n, 0x0244)
++#define REG_P_FMT(n)                  PREG(n, 0x0246)
++#define REG_P_MAX_OUT_RATE(n)         PREG(n, 0x0248)
++#define REG_P_MIN_OUT_RATE(n)         PREG(n, 0x024a)
++#define REG_P_PVI_MASK(n)             PREG(n, 0x024c)
++#define  PVI_MASK_MIPI                        0x52
++#define REG_P_CLK_INDEX(n)            PREG(n, 0x024e)
++#define  CLK_PVI_INDEX                        0
++#define  CLK_MIPI_INDEX                       NPVI_CLOCKS
++#define REG_P_FR_RATE_TYPE(n)         PREG(n, 0x0250)
++#define  FR_RATE_DYNAMIC              0
++#define  FR_RATE_FIXED                        1
++#define  FR_RATE_FIXED_ACCURATE               2
++#define REG_P_FR_RATE_Q_TYPE(n)               PREG(n, 0x0252)
++#define  FR_RATE_Q_DYNAMIC            0
++#define  FR_RATE_Q_BEST_FRRATE                1 /* Binning enabled */
++#define  FR_RATE_Q_BEST_QUALITY               2 /* Binning disabled */
++/* Frame period in 0.1 ms units */
++#define REG_P_MAX_FR_TIME(n)          PREG(n, 0x0254)
++#define REG_P_MIN_FR_TIME(n)          PREG(n, 0x0256)
++#define  S5K5BAF_MIN_FR_TIME          333  /* x100 us */
++#define  S5K5BAF_MAX_FR_TIME          6500 /* x100 us */
++/* The below 5 registers are for "device correction" values */
++#define REG_P_SATURATION(n)           PREG(n, 0x0258)
++#define REG_P_SHARP_BLUR(n)           PREG(n, 0x025a)
++#define REG_P_GLAMOUR(n)              PREG(n, 0x025c)
++#define REG_P_COLORTEMP(n)            PREG(n, 0x025e)
++#define REG_P_GAMMA_INDEX(n)          PREG(n, 0x0260)
++#define REG_P_PREV_MIRROR(n)          PREG(n, 0x0262)
++#define REG_P_CAP_MIRROR(n)           PREG(n, 0x0264)
++#define REG_P_CAP_ROTATION(n)         PREG(n, 0x0266)
++
++/* Extended image property controls */
++/* Exposure time in 10 us units */
++#define REG_SF_USR_EXPOSURE_L         0x03bc
++#define REG_SF_USR_EXPOSURE_H         0x03be
++#define REG_SF_USR_EXPOSURE_CHG               0x03c0
++#define REG_SF_USR_TOT_GAIN           0x03c2
++#define REG_SF_USR_TOT_GAIN_CHG               0x03c4
++#define REG_SF_RGAIN                  0x03c6
++#define REG_SF_RGAIN_CHG              0x03c8
++#define REG_SF_GGAIN                  0x03ca
++#define REG_SF_GGAIN_CHG              0x03cc
++#define REG_SF_BGAIN                  0x03ce
++#define REG_SF_BGAIN_CHG              0x03d0
++#define REG_SF_WBGAIN_CHG             0x03d2
++#define REG_SF_FLICKER_QUANT          0x03d4
++#define REG_SF_FLICKER_QUANT_CHG      0x03d6
++
++/* Output interface (parallel/MIPI) setup */
++#define REG_OIF_EN_MIPI_LANES         0x03f2
++#define REG_OIF_EN_PACKETS            0x03f4
++#define  EN_PACKETS_CSI2              0xc3
++#define REG_OIF_CFG_CHG                       0x03f6
++
++/* Auto-algorithms enable mask */
++#define REG_DBG_AUTOALG_EN            0x03f8
++#define  AALG_ALL_EN                  BIT(0)
++#define  AALG_AE_EN                   BIT(1)
++#define  AALG_DIVLEI_EN                       BIT(2)
++#define  AALG_WB_EN                   BIT(3)
++#define  AALG_USE_WB_FOR_ISP          BIT(4)
++#define  AALG_FLICKER_EN              BIT(5)
++#define  AALG_FIT_EN                  BIT(6)
++#define  AALG_WRHW_EN                 BIT(7)
++
++#define REG_PTR_CCM_HORIZON           0x06d0
++#define REG_PTR_CCM_INCANDESCENT      0x06d4
++#define REG_PTR_CCM_WARM_WHITE                0x06d8
++#define REG_PTR_CCM_COOL_WHITE                0x06dc
++#define REG_PTR_CCM_DL50              0x06e0
++#define REG_PTR_CCM_DL65              0x06e4
++#define REG_PTR_CCM_OUTDOOR           0x06ec
++
++#define REG_ARR_CCM(n)                        (0x2800 + 36 * (n))
++
++static const char * const s5k5baf_supply_names[] = {
++      "vdda",         /* Analog power supply 2.8V (2.6V to 3.0V) */
++      "vddreg",       /* Regulator input power supply 1.8V (1.7V to 1.9V)
++                         or 2.8V (2.6V to 3.0) */
++      "vddio",        /* I/O power supply 1.8V (1.65V to 1.95V)
++                         or 2.8V (2.5V to 3.1V) */
++};
++#define S5K5BAF_NUM_SUPPLIES ARRAY_SIZE(s5k5baf_supply_names)
++
++struct s5k5baf_gpio {
++      int gpio;
++      int level;
++};
++
++enum s5k5baf_gpio_id {
++      STBY,
++      RST,
++      GPIO_NUM,
++};
++
++struct s5k5baf_pixfmt {
++      enum v4l2_mbus_pixelcode code;
++      u32 colorspace;
++      /* REG_P_FMT(x) register value */
++      u16 reg_p_fmt;
++};
++
++struct s5k5baf_ctrls {
++      struct v4l2_ctrl_handler handler;
++      struct { /* Auto / manual white balance cluster */
++              struct v4l2_ctrl *awb;
++              struct v4l2_ctrl *gain_red;
++              struct v4l2_ctrl *gain_blue;
++              struct v4l2_ctrl *gain_green;
++      };
++      struct { /* Mirror cluster */
++              struct v4l2_ctrl *hflip;
++              struct v4l2_ctrl *vflip;
++      };
++      struct { /* Auto exposure / manual exposure and gain cluster */
++              struct v4l2_ctrl *auto_exp;
++              struct v4l2_ctrl *exposure;
++              struct v4l2_ctrl *gain;
++      };
++};
++
++struct s5k5baf {
++      u32 mclk_frequency;
++      struct s5k5baf_gpio gpios[2];
++      enum v4l2_mbus_type bus_type;
++      u8 nlanes;
++      u8 hflip:1;
++      u8 vflip:1;
++      struct regulator_bulk_data supplies[S5K5BAF_NUM_SUPPLIES];
++
++      struct v4l2_subdev cis_sd;
++      struct media_pad cis_pad;
++
++      struct v4l2_subdev sd;
++      struct media_pad pads[2];
++
++      /* protects the struct members below */
++      struct mutex lock;
++
++      int error;
++
++      struct v4l2_rect crop_sink;
++      struct v4l2_rect compose;
++      struct v4l2_rect crop_source;
++      /* index to s5k5baf_formats array */
++      int pixfmt;
++      /* actual frame interval in 100us */
++      u16 fiv;
++      /* requested frame interval in 100us */
++      u16 req_fiv;
++
++      struct s5k5baf_ctrls ctrls;
++
++      unsigned int streaming:1;
++      unsigned int apply_cfg:1;
++      unsigned int apply_crop:1;
++      unsigned int power;
++};
++
++static const struct s5k5baf_pixfmt s5k5baf_formats[] = {
++      { V4L2_MBUS_FMT_VYUY8_2X8,      V4L2_COLORSPACE_JPEG,   5 },
++      /* range 16-240 */
++      { V4L2_MBUS_FMT_VYUY8_2X8,      V4L2_COLORSPACE_REC709, 6 },
++      { V4L2_MBUS_FMT_RGB565_2X8_BE,  V4L2_COLORSPACE_JPEG,   0 },
++};
++
++static struct v4l2_rect s5k5baf_cis_rect = { 0, 0, S5K5BAF_CIS_WIDTH,
++                                   S5K5BAF_CIS_HEIGHT };
++static struct v4l2_rect s5k5baf_def_rect = { 0, 0, S5K5BAF_OUT_WIDTH_DEF,
++                                   S5K5BAF_OUT_HEIGHT_DEF };
++
++static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
++{
++      return &container_of(ctrl->handler, struct s5k5baf, ctrls.handler)->sd;
++}
++
++static inline bool s5k5baf_is_cis_subdev(struct v4l2_subdev *sd)
++{
++      return sd->entity.type == MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
++}
++
++static inline struct s5k5baf *to_s5k5baf(struct v4l2_subdev *sd)
++{
++      if (s5k5baf_is_cis_subdev(sd))
++              return container_of(sd, struct s5k5baf, cis_sd);
++      else
++              return container_of(sd, struct s5k5baf, sd);
++}
++
++static u16 s5k5baf_i2c_read(struct s5k5baf *state, u16 addr)
++{
++      struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
++      u16 w, r;
++      struct i2c_msg msg[] = {
++              {.addr = c->addr, .flags = 0, .len = 2, .buf = (u8 *)&w},
++              {.addr = c->addr, .flags = I2C_M_RD, .len = 2, .buf = (u8 *)&r},
++      };
++      int ret;
++
++      if (state->error)
++              return 0;
++
++      w = htons(addr);
++      ret = i2c_transfer(c->adapter, msg, 2);
++      r = ntohs(r);
++
++      v4l2_dbg(3, debug, c, "i2c_read: 0x%04x : 0x%04x\n", addr, r);
++
++      if (ret != 2) {
++              v4l2_err(c, "i2c_read: error during transfer (%d)\n", ret);
++              state->error = ret;
++      }
++      return r;
++}
++
++static void s5k5baf_i2c_write(struct s5k5baf *state, u16 addr, u16 val)
++{
++      u8 buf[4] = { addr >> 8, addr & 0xFF, val >> 8, val & 0xFF };
++      struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
++      int ret;
++
++      if (state->error)
++              return;
++
++      ret = i2c_master_send(c, buf, 4);
++      v4l2_dbg(3, debug, c, "i2c_write: 0x%04x : 0x%04x\n", addr, val);
++
++      if (ret != 4) {
++              v4l2_err(c, "i2c_write: error during transfer (%d)\n", ret);
++              state->error = ret;
++      }
++}
++
++static u16 s5k5baf_read(struct s5k5baf *state, u16 addr)
++{
++      s5k5baf_i2c_write(state, REG_CMDRD_ADDR, addr);
++      return s5k5baf_i2c_read(state, REG_CMD_BUF);
++}
++
++static void s5k5baf_write(struct s5k5baf *state, u16 addr, u16 val)
++{
++      s5k5baf_i2c_write(state, REG_CMDWR_ADDR, addr);
++      s5k5baf_i2c_write(state, REG_CMD_BUF, val);
++}
++
++static void s5k5baf_write_arr_seq(struct s5k5baf *state, u16 addr,
++                                u16 count, const u16 *seq)
++{
++      struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
++      u16 buf[count + 1];
++      int ret, n;
++
++      s5k5baf_i2c_write(state, REG_CMDWR_ADDR, addr);
++      if (state->error)
++              return;
++
++      buf[0] = __constant_htons(REG_CMD_BUF);
++      for (n = 1; n <= count; ++n)
++              buf[n] = htons(*seq++);
++
++      n *= 2;
++      ret = i2c_master_send(c, (char *)buf, n);
++      v4l2_dbg(3, debug, c, "i2c_write_seq(count=%d): %*ph\n", count,
++               min(2 * count, 64), seq - count);
++
++      if (ret != n) {
++              v4l2_err(c, "i2c_write_seq: error during transfer (%d)\n", ret);
++              state->error = ret;
++      }
++}
++
++#define s5k5baf_write_seq(state, addr, seq...) \
++      s5k5baf_write_arr_seq(state, addr, sizeof((char[]){ seq }), \
++                            (const u16 []){ seq });
++
++/* add items count at the beginning of the list */
++#define NSEQ(seq...) sizeof((char[]){ seq }), seq
++
++/*
++ * s5k5baf_write_nseq() - Writes sequences of values to sensor memory via i2c
++ * @nseq: sequence of u16 words in format:
++ *    (N, address, value[1]...value[N-1])*,0
++ * Ex.:
++ *    u16 seq[] = { NSEQ(0x4000, 1, 1), NSEQ(0x4010, 640, 480), 0 };
++ *    ret = s5k5baf_write_nseq(c, seq);
++ */
++static void s5k5baf_write_nseq(struct s5k5baf *state, const u16 *nseq)
++{
++      int count;
++
++      while ((count = *nseq++)) {
++              u16 addr = *nseq++;
++              --count;
++
++              s5k5baf_write_arr_seq(state, addr, count, nseq);
++              nseq += count;
++      }
++}
++
++static void s5k5baf_synchronize(struct s5k5baf *state, int timeout, u16 addr)
++{
++      unsigned long end = jiffies + msecs_to_jiffies(timeout);
++      u16 reg;
++
++      s5k5baf_write(state, addr, 1);
++      do {
++              reg = s5k5baf_read(state, addr);
++              if (state->error || !reg)
++                      return;
++              usleep_range(5000, 10000);
++      } while (time_is_after_jiffies(end));
++
++      v4l2_err(&state->sd, "timeout on register synchronize (%#x)\n", addr);
++      state->error = -ETIMEDOUT;
++}
++
++static void s5k5baf_hw_patch(struct s5k5baf *state)
++{
++      static const u16 nseq_patch[] = {
++              NSEQ(0x1668,
++              0xb5fe, 0x0007, 0x683c, 0x687e, 0x1da5, 0x88a0, 0x2800, 0xd00b,
++              0x88a8, 0x2800, 0xd008, 0x8820, 0x8829, 0x4288, 0xd301, 0x1a40,
++              0xe000, 0x1a08, 0x9001, 0xe001, 0x2019, 0x9001, 0x4916, 0x466b,
++              0x8a48, 0x8118, 0x8a88, 0x8158, 0x4814, 0x8940, 0x0040, 0x2103,
++              0xf000, 0xf826, 0x88a1, 0x4288, 0xd908, 0x8828, 0x8030, 0x8868,
++              0x8070, 0x88a8, 0x6038, 0xbcfe, 0xbc08, 0x4718, 0x88a9, 0x4288,
++              0xd906, 0x8820, 0x8030, 0x8860, 0x8070, 0x88a0, 0x6038, 0xe7f2,
++              0x9801, 0xa902, 0xf000, 0xf812, 0x0033, 0x0029, 0x9a02, 0x0020,
++              0xf000, 0xf814, 0x6038, 0xe7e6, 0x1a28, 0x7000, 0x0d64, 0x7000,
++              0x4778, 0x46c0, 0xf004, 0xe51f, 0xa464, 0x0000, 0x4778, 0x46c0,
++              0xc000, 0xe59f, 0xff1c, 0xe12f, 0x6009, 0x0000, 0x4778, 0x46c0,
++              0xc000, 0xe59f, 0xff1c, 0xe12f, 0x622f, 0x0000),
++              NSEQ(0x2080,
++              0xb510, 0xf000, 0xf8f4, 0xbc10, 0xbc08, 0x4718, 0xb5f0, 0xb08b,
++              0x0006, 0x2000, 0x9004, 0x6835, 0x6874, 0x68b0, 0x900a, 0x68f0,
++              0x9009, 0x4f7d, 0x8979, 0x084a, 0x88a8, 0x88a3, 0x4298, 0xd300,
++              0x0018, 0xf000, 0xf907, 0x9007, 0x0021, 0x0028, 0xaa04, 0xf000,
++              0xf909, 0x9006, 0x88a8, 0x2800, 0xd102, 0x27ff, 0x1c7f, 0xe047,
++              0x88a0, 0x2800, 0xd101, 0x2700, 0xe042, 0x8820, 0x466b, 0x8198,
++              0x8860, 0x81d8, 0x8828, 0x8118, 0x8868, 0x8158, 0xa802, 0xc803,
++              0xf000, 0xf8f8, 0x9008, 0x8aba, 0x9808, 0x466b, 0x4342, 0x9202,
++              0x8820, 0x8198, 0x8860, 0x81d8, 0x980a, 0x9903, 0xf000, 0xf8ea,
++              0x9a02, 0x17d1, 0x0e09, 0x1889, 0x1209, 0x4288, 0xdd1f, 0x8820,
++              0x466b, 0x8198, 0x8860, 0x81d8, 0x980a, 0x9903, 0xf000, 0xf8da,
++              0x9001, 0x8828, 0x466b, 0x8118, 0x8868, 0x8158, 0x980a, 0x9902,
++              0xf000, 0xf8d0, 0x8ab9, 0x9a08, 0x4351, 0x17ca, 0x0e12, 0x1851,
++              0x120a, 0x9901, 0xf000, 0xf8b6, 0x0407, 0x0c3f, 0xe000, 0x2700,
++              0x8820, 0x466b, 0xaa05, 0x8198, 0x8860, 0x81d8, 0x8828, 0x8118,
++              0x8868, 0x8158, 0xa802, 0xc803, 0x003b, 0xf000, 0xf8bb, 0x88a1,
++              0x88a8, 0x003a, 0xf000, 0xf8be, 0x0004, 0xa804, 0xc803, 0x9a09,
++              0x9b07, 0xf000, 0xf8af, 0xa806, 0xc805, 0x0021, 0xf000, 0xf8b2,
++              0x6030, 0xb00b, 0xbcf0, 0xbc08, 0x4718, 0xb5f1, 0x9900, 0x680c,
++              0x493a, 0x694b, 0x698a, 0x4694, 0x69cd, 0x6a0e, 0x4f38, 0x42bc,
++              0xd800, 0x0027, 0x4937, 0x6b89, 0x0409, 0x0c09, 0x4a35, 0x1e92,
++              0x6bd2, 0x0412, 0x0c12, 0x429f, 0xd801, 0x0020, 0xe031, 0x001f,
++              0x434f, 0x0a3f, 0x42a7, 0xd301, 0x0018, 0xe02a, 0x002b, 0x434b,
++              0x0a1b, 0x42a3, 0xd303, 0x0220, 0xf000, 0xf88c, 0xe021, 0x0029,
++              0x4351, 0x0a09, 0x42a1, 0xd301, 0x0028, 0xe01a, 0x0031, 0x4351,
++              0x0a09, 0x42a1, 0xd304, 0x0220, 0x0011, 0xf000, 0xf87b, 0xe010,
++              0x491e, 0x8c89, 0x000a, 0x4372, 0x0a12, 0x42a2, 0xd301, 0x0030,
++              0xe007, 0x4662, 0x434a, 0x0a12, 0x42a2, 0xd302, 0x0220, 0xf000,
++              0xf869, 0x4b16, 0x4d18, 0x8d99, 0x1fca, 0x3af9, 0xd00a, 0x2001,
++              0x0240, 0x8468, 0x0220, 0xf000, 0xf85d, 0x9900, 0x6008, 0xbcf8,
++              0xbc08, 0x4718, 0x8d19, 0x8469, 0x9900, 0x6008, 0xe7f7, 0xb570,
++              0x2200, 0x490e, 0x480e, 0x2401, 0xf000, 0xf852, 0x0022, 0x490d,
++              0x480d, 0x2502, 0xf000, 0xf84c, 0x490c, 0x480d, 0x002a, 0xf000,
++              0xf847, 0xbc70, 0xbc08, 0x4718, 0x0d64, 0x7000, 0x0470, 0x7000,
++              0xa120, 0x0007, 0x0402, 0x7000, 0x14a0, 0x7000, 0x208d, 0x7000,
++              0x622f, 0x0000, 0x1669, 0x7000, 0x6445, 0x0000, 0x21ab, 0x7000,
++              0x2aa9, 0x0000, 0x4778, 0x46c0, 0xc000, 0xe59f, 0xff1c, 0xe12f,
++              0x5f49, 0x0000, 0x4778, 0x46c0, 0xc000, 0xe59f, 0xff1c, 0xe12f,
++              0x5fc7, 0x0000, 0x4778, 0x46c0, 0xc000, 0xe59f, 0xff1c, 0xe12f,
++              0x5457, 0x0000, 0x4778, 0x46c0, 0xc000, 0xe59f, 0xff1c, 0xe12f,
++              0x5fa3, 0x0000, 0x4778, 0x46c0, 0xc000, 0xe59f, 0xff1c, 0xe12f,
++              0x51f9, 0x0000, 0x4778, 0x46c0, 0xf004, 0xe51f, 0xa464, 0x0000,
++              0x4778, 0x46c0, 0xc000, 0xe59f, 0xff1c, 0xe12f, 0xa007, 0x0000,
++              0x6546, 0x2062, 0x3120, 0x3220, 0x3130, 0x0030, 0xe010, 0x0208,
++              0x0058, 0x0000),
++              0
++      };
++
++      s5k5baf_write_nseq(state, nseq_patch);
++}
++
++static void s5k5baf_hw_set_clocks(struct s5k5baf *state)
++{
++      unsigned long mclk = state->mclk_frequency / 1000;
++      u16 status;
++      static const u16 nseq_clk_cfg[] = {
++              NSEQ(REG_I_USE_NPVI_CLOCKS,
++                NPVI_CLOCKS, NMIPI_CLOCKS, 0,
++                SCLK_PVI_FREQ / 4, PCLK_MIN_FREQ / 4, PCLK_MAX_FREQ / 4,
++                SCLK_MIPI_FREQ / 4, PCLK_MIN_FREQ / 4, PCLK_MAX_FREQ / 4),
++              NSEQ(REG_I_USE_REGS_API, 1),
++              0
++      };
++
++      s5k5baf_write_seq(state, REG_I_INCLK_FREQ_L, mclk & 0xffff, mclk >> 16);
++      s5k5baf_write_nseq(state, nseq_clk_cfg);
++
++      s5k5baf_synchronize(state, 250, REG_I_INIT_PARAMS_UPDATED);
++      status = s5k5baf_read(state, REG_I_ERROR_INFO);
++      if (!state->error && status) {
++              v4l2_err(&state->sd, "error configuring PLL (%d)\n", status);
++              state->error = -EINVAL;
++      }
++}
++
++static void s5k5baf_hw_set_ccm(struct s5k5baf *state)
++{
++      static const u16 nseq_cfg[] = {
++              NSEQ(REG_PTR_CCM_HORIZON,
++              REG_ARR_CCM(0), PAGE_IF_SW,
++              REG_ARR_CCM(1), PAGE_IF_SW,
++              REG_ARR_CCM(2), PAGE_IF_SW,
++              REG_ARR_CCM(3), PAGE_IF_SW,
++              REG_ARR_CCM(4), PAGE_IF_SW,
++              REG_ARR_CCM(5), PAGE_IF_SW),
++              NSEQ(REG_PTR_CCM_OUTDOOR,
++              REG_ARR_CCM(6), PAGE_IF_SW),
++              NSEQ(REG_ARR_CCM(0),
++              /* horizon */
++              0x010d, 0xffa7, 0xfff5, 0x003b, 0x00ef, 0xff38,
++              0xfe42, 0x0270, 0xff71, 0xfeed, 0x0198, 0x0198,
++              0xff95, 0xffa3, 0x0260, 0x00ec, 0xff33, 0x00f4,
++              /* incandescent */
++              0x010d, 0xffa7, 0xfff5, 0x003b, 0x00ef, 0xff38,
++              0xfe42, 0x0270, 0xff71, 0xfeed, 0x0198, 0x0198,
++              0xff95, 0xffa3, 0x0260, 0x00ec, 0xff33, 0x00f4,
++              /* warm white */
++              0x01ea, 0xffb9, 0xffdb, 0x0127, 0x0109, 0xff3c,
++              0xff2b, 0x021b, 0xff48, 0xff03, 0x0207, 0x0113,
++              0xffca, 0xff93, 0x016f, 0x0164, 0xff55, 0x0163,
++              /* cool white */
++              0x01ea, 0xffb9, 0xffdb, 0x0127, 0x0109, 0xff3c,
++              0xff2b, 0x021b, 0xff48, 0xff03, 0x0207, 0x0113,
++              0xffca, 0xff93, 0x016f, 0x0164, 0xff55, 0x0163,
++              /* daylight 5000K */
++              0x0194, 0xffad, 0xfffe, 0x00c5, 0x0103, 0xff5d,
++              0xfee3, 0x01ae, 0xff27, 0xff18, 0x018f, 0x00c8,
++              0xffe8, 0xffaa, 0x01c8, 0x0132, 0xff3e, 0x0100,
++              /* daylight 6500K */
++              0x0194, 0xffad, 0xfffe, 0x00c5, 0x0103, 0xff5d,
++              0xfee3, 0x01ae, 0xff27, 0xff18, 0x018f, 0x00c8,
++              0xffe8, 0xffaa, 0x01c8, 0x0132, 0xff3e, 0x0100,
++              /* outdoor */
++              0x01cc, 0xffc3, 0x0009, 0x00a2, 0x0106, 0xff3f,
++              0xfed8, 0x01fe, 0xff08, 0xfec7, 0x00f5, 0x0119,
++              0xffdf, 0x0024, 0x01a8, 0x0170, 0xffad, 0x011b),
++              0
++      };
++      s5k5baf_write_nseq(state, nseq_cfg);
++}
++
++static void s5k5baf_hw_set_cis(struct s5k5baf *state)
++{
++      static const u16 nseq_cfg[] = {
++              NSEQ(0xc202, 0x0700),
++              NSEQ(0xf260, 0x0001),
++              NSEQ(0xf414, 0x0030),
++              NSEQ(0xc204, 0x0100),
++              NSEQ(0xf402, 0x0092, 0x007f),
++              NSEQ(0xf700, 0x0040),
++              NSEQ(0xf708,
++              0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
++              0x0040, 0x0040, 0x0040, 0x0040, 0x0040,
++              0x0001, 0x0015, 0x0001, 0x0040),
++              NSEQ(0xf48a, 0x0048),
++              NSEQ(0xf10a, 0x008b),
++              NSEQ(0xf900, 0x0067),
++              NSEQ(0xf406, 0x0092, 0x007f, 0x0003, 0x0003, 0x0003),
++              NSEQ(0xf442, 0x0000, 0x0000),
++              NSEQ(0xf448, 0x0000),
++              NSEQ(0xf456, 0x0001, 0x0010, 0x0000),
++              NSEQ(0xf41a, 0x00ff, 0x0003, 0x0030),
++              NSEQ(0xf410, 0x0001, 0x0000),
++              NSEQ(0xf416, 0x0001),
++              NSEQ(0xf424, 0x0000),
++              NSEQ(0xf422, 0x0000),
++              NSEQ(0xf41e, 0x0000),
++              NSEQ(0xf428, 0x0000, 0x0000, 0x0000),
++              NSEQ(0xf430, 0x0000, 0x0000, 0x0008, 0x0005, 0x000f, 0x0001,
++              0x0040, 0x0040, 0x0010),
++              NSEQ(0xf4d6, 0x0090, 0x0000),
++              NSEQ(0xf47c, 0x000c, 0x0000),
++              NSEQ(0xf49a, 0x0008, 0x0000),
++              NSEQ(0xf4a2, 0x0008, 0x0000),
++              NSEQ(0xf4b2, 0x0013, 0x0000, 0x0013, 0x0000),
++              NSEQ(0xf4aa, 0x009b, 0x00fb, 0x009b, 0x00fb),
++              0
++      };
++
++      s5k5baf_i2c_write(state, REG_CMDWR_PAGE, PAGE_IF_HW);
++      s5k5baf_write_nseq(state, nseq_cfg);
++      s5k5baf_i2c_write(state, REG_CMDWR_PAGE, PAGE_IF_SW);
++}
++
++static void s5k5baf_hw_sync_cfg(struct s5k5baf *state)
++{
++      s5k5baf_write(state, REG_G_PREV_CFG_CHG, 1);
++      if (state->apply_crop) {
++              s5k5baf_write(state, REG_G_INPUTS_CHANGE_REQ, 1);
++              s5k5baf_write(state, REG_G_PREV_CFG_BYPASS_CHANGED, 1);
++      }
++      s5k5baf_synchronize(state, 500, REG_G_NEW_CFG_SYNC);
++
++}
++/* Set horizontal and vertical image flipping */
++static void s5k5baf_hw_set_mirror(struct s5k5baf *state, int horiz_flip)
++{
++      u16 vflip = state->ctrls.vflip->val ^ state->vflip;
++      u16 flip = (horiz_flip ^ state->hflip) | (vflip << 1);
++
++      s5k5baf_write(state, REG_P_PREV_MIRROR(0), flip);
++      if (state->streaming)
++              s5k5baf_hw_sync_cfg(state);
++}
++
++/* Configure auto/manual white balance and R/G/B gains */
++static void s5k5baf_hw_set_awb(struct s5k5baf *state, int awb)
++{
++      struct s5k5baf_ctrls *ctrls = &state->ctrls;
++      u16 reg;
++
++      reg = s5k5baf_read(state, REG_DBG_AUTOALG_EN);
++
++      if (!awb)
++              s5k5baf_write_seq(state, REG_SF_RGAIN,
++                                ctrls->gain_red->val, 1,
++                                ctrls->gain_green->val, 1,
++                                ctrls->gain_blue->val, 1);
++      reg = awb ? reg | AALG_WB_EN : reg & ~AALG_WB_EN;
++      s5k5baf_write(state, REG_DBG_AUTOALG_EN, reg);
++}
++
++/* Program FW with exposure time, 'exposure' in us units */
++static void s5k5baf_hw_set_user_exposure(struct s5k5baf *state, int exposure)
++{
++      unsigned int time = exposure / 10;
++
++      s5k5baf_write_seq(state, REG_SF_USR_EXPOSURE_L,
++                        time & 0xffff, time >> 16, 1);
++}
++
++static void s5k5baf_hw_set_user_gain(struct s5k5baf *state, int gain)
++{
++      s5k5baf_write_seq(state, REG_SF_USR_TOT_GAIN, gain, 1);
++}
++
++/* Set auto/manual exposure and total gain */
++static void s5k5baf_hw_set_auto_exposure(struct s5k5baf *state, int value)
++{
++      unsigned int exp_time = state->ctrls.exposure->val;
++      u16 auto_alg;
++
++      auto_alg = s5k5baf_read(state, REG_DBG_AUTOALG_EN);
++
++      if (value == V4L2_EXPOSURE_AUTO) {
++              auto_alg |= AALG_AE_EN | AALG_DIVLEI_EN;
++      } else {
++              s5k5baf_hw_set_user_exposure(state, exp_time);
++              s5k5baf_hw_set_user_gain(state, state->ctrls.gain->val);
++              auto_alg &= ~(AALG_AE_EN | AALG_DIVLEI_EN);
++      }
++
++      s5k5baf_write(state, REG_DBG_AUTOALG_EN, auto_alg);
++}
++
++static void s5k5baf_hw_set_anti_flicker(struct s5k5baf *state, int v)
++{
++      u16 auto_alg;
++
++      auto_alg = s5k5baf_read(state, REG_DBG_AUTOALG_EN);
++
++      if (v == V4L2_CID_POWER_LINE_FREQUENCY_AUTO) {
++              auto_alg |= AALG_FLICKER_EN;
++      } else {
++              auto_alg &= ~AALG_FLICKER_EN;
++              /* The V4L2_CID_LINE_FREQUENCY control values match
++               * the register values */
++              s5k5baf_write_seq(state, REG_SF_FLICKER_QUANT, v, 1);
++      }
++
++      s5k5baf_write(state, REG_DBG_AUTOALG_EN, auto_alg);
++}
++
++static void s5k5baf_hw_set_colorfx(struct s5k5baf *state, int val)
++{
++      static const u16 colorfx[] = {
++              [V4L2_COLORFX_NONE] = 0,
++              [V4L2_COLORFX_BW] = 1,
++              [V4L2_COLORFX_NEGATIVE] = 2,
++              [V4L2_COLORFX_SEPIA] = 3,
++              [V4L2_COLORFX_SKY_BLUE] = 4,
++              [V4L2_COLORFX_SKETCH] = 5,
++      };
++
++      if (val >= ARRAY_SIZE(colorfx)) {
++              v4l2_err(&state->sd, "colorfx(%d) out of range(%d)\n",
++                       val, ARRAY_SIZE(colorfx));
++              state->error = -EINVAL;
++      } else {
++              s5k5baf_write(state, REG_G_SPEC_EFFECTS, colorfx[val]);
++      }
++}
++
++static int s5k5baf_find_pixfmt(struct v4l2_mbus_framefmt *mf)
++{
++      int i, c = -1;
++
++      for (i = 0; i < ARRAY_SIZE(s5k5baf_formats); i++) {
++              if (mf->colorspace != s5k5baf_formats[i].colorspace)
++                      continue;
++              if (mf->code == s5k5baf_formats[i].code)
++                      return i;
++              if (c < 0)
++                      c = i;
++      }
++      return (c < 0) ? 0 : c;
++}
++
++static void s5k5baf_hw_set_video_bus(struct s5k5baf *state)
++{
++      u16 en_packets;
++
++      switch (state->bus_type) {
++      case V4L2_MBUS_CSI2:
++              en_packets = EN_PACKETS_CSI2;
++              break;
++      case V4L2_MBUS_PARALLEL:
++              en_packets = 0;
++              break;
++      default:
++              v4l2_err(&state->sd, "unknown video bus: %d\n", state->bus_type);
++              state->error = -EINVAL;
++              return;
++      };
++
++      s5k5baf_write_seq(state, REG_OIF_EN_MIPI_LANES,
++                        state->nlanes, en_packets, 1);
++}
++
++static u16 s5k5baf_get_cfg_error(struct s5k5baf *state)
++{
++      u16 err = s5k5baf_read(state, REG_G_PREV_CFG_ERROR);
++      if (err)
++              s5k5baf_write(state, REG_G_PREV_CFG_ERROR, 0);
++      return err;
++}
++
++static void s5k5baf_hw_set_fiv(struct s5k5baf *state, u16 fiv)
++{
++      s5k5baf_write(state, REG_P_MAX_FR_TIME(0), fiv);
++      s5k5baf_hw_sync_cfg(state);
++}
++
++static void s5k5baf_hw_find_min_fiv(struct s5k5baf *state)
++{
++      u16 err, fiv;
++      int n;
++
++      fiv = s5k5baf_read(state,  REG_G_ACTUAL_P_FR_TIME);
++      if (state->error)
++              return;
++
++      for (n = 5; n > 0; --n) {
++              s5k5baf_hw_set_fiv(state, fiv);
++              err = s5k5baf_get_cfg_error(state);
++              if (state->error)
++                      return;
++              switch (err) {
++              case CFG_ERROR_RANGE:
++                      ++fiv;
++                      break;
++              case 0:
++                      state->fiv = fiv;
++                      v4l2_info(&state->sd,
++                                "found valid frame interval: %d00us\n", fiv);
++                      return;
++              default:
++                      v4l2_err(&state->sd,
++                               "error setting frame interval: %d\n", err);
++                      state->error = -EINVAL;
++              }
++      };
++      v4l2_err(&state->sd, "cannot find correct frame interval\n");
++      state->error = -ERANGE;
++}
++
++static void s5k5baf_hw_validate_cfg(struct s5k5baf *state)
++{
++      u16 err;
++
++      err = s5k5baf_get_cfg_error(state);
++      if (state->error)
++              return;
++
++      switch (err) {
++      case 0:
++              state->apply_cfg = 1;
++              return;
++      case CFG_ERROR_RANGE:
++              s5k5baf_hw_find_min_fiv(state);
++              if (!state->error)
++                      state->apply_cfg = 1;
++              return;
++      default:
++              v4l2_err(&state->sd,
++                       "error setting format: %d\n", err);
++              state->error = -EINVAL;
++      }
++}
++
++static void s5k5baf_rescale(struct v4l2_rect *r, const struct v4l2_rect *v,
++                          const struct v4l2_rect *n,
++                          const struct v4l2_rect *d)
++{
++      r->left = v->left * n->width / d->width;
++      r->top = v->top * n->height / d->height;
++      r->width = v->width * n->width / d->width;
++      r->height = v->height * n->height / d->height;
++}
++
++static void s5k5baf_hw_set_crop_rects(struct s5k5baf *state)
++{
++      struct v4l2_rect *p, r;
++      u16 err;
++
++      p = &state->crop_sink;
++      s5k5baf_write_seq(state, REG_G_PREVREQ_IN_WIDTH, p->width, p->height,
++                        p->left, p->top);
++
++      s5k5baf_rescale(&r, &state->crop_source, &state->crop_sink,
++                      &state->compose);
++      s5k5baf_write_seq(state, REG_G_PREVZOOM_IN_WIDTH, r.width, r.height,
++                        r.left, r.top);
++
++      s5k5baf_synchronize(state, 500, REG_G_INPUTS_CHANGE_REQ);
++      s5k5baf_synchronize(state, 500, REG_G_PREV_CFG_BYPASS_CHANGED);
++      err = s5k5baf_get_cfg_error(state);
++      if (state->error)
++              return;
++
++      switch (err) {
++      case 0:
++              break;
++      case CFG_ERROR_RANGE:
++              /* retry crop with frame interval set to max */
++              s5k5baf_hw_set_fiv(state, S5K5BAF_MAX_FR_TIME);
++              err = s5k5baf_get_cfg_error(state);
++              if (state->error)
++                      return;
++              if (err) {
++                      v4l2_err(&state->sd,
++                               "crop error on max frame interval: %d\n", err);
++                      state->error = -EINVAL;
++              }
++              s5k5baf_hw_set_fiv(state, state->req_fiv);
++              s5k5baf_hw_validate_cfg(state);
++              break;
++      default:
++              v4l2_err(&state->sd, "crop error: %d\n", err);
++              state->error = -EINVAL;
++              return;
++      }
++
++      if (!state->apply_cfg)
++              return;
++
++      p = &state->crop_source;
++      s5k5baf_write_seq(state, REG_P_OUT_WIDTH(0), p->width, p->height);
++      s5k5baf_hw_set_fiv(state, state->req_fiv);
++      s5k5baf_hw_validate_cfg(state);
++}
++
++static void s5k5baf_hw_set_config(struct s5k5baf *state)
++{
++      u16 reg_fmt = s5k5baf_formats[state->pixfmt].reg_p_fmt;
++      struct v4l2_rect *r = &state->crop_source;
++
++      s5k5baf_write_seq(state, REG_P_OUT_WIDTH(0),
++                        r->width, r->height, reg_fmt,
++                        PCLK_MAX_FREQ >> 2, PCLK_MIN_FREQ >> 2,
++                        PVI_MASK_MIPI, CLK_MIPI_INDEX,
++                        FR_RATE_FIXED, FR_RATE_Q_DYNAMIC,
++                        state->req_fiv, S5K5BAF_MIN_FR_TIME);
++      s5k5baf_hw_sync_cfg(state);
++      s5k5baf_hw_validate_cfg(state);
++}
++
++
++static void s5k5baf_hw_set_test_pattern(struct s5k5baf *state, int id)
++{
++      s5k5baf_i2c_write(state, REG_PATTERN_WIDTH, 800);
++      s5k5baf_i2c_write(state, REG_PATTERN_HEIGHT, 511);
++      s5k5baf_i2c_write(state, REG_PATTERN_PARAM, 0);
++      s5k5baf_i2c_write(state, REG_PATTERN_SET, id);
++}
++
++static void s5k5baf_gpio_assert(struct s5k5baf *state, int id)
++{
++      struct s5k5baf_gpio *gpio = &state->gpios[id];
++
++      gpio_set_value(gpio->gpio, gpio->level);
++}
++
++static void s5k5baf_gpio_deassert(struct s5k5baf *state, int id)
++{
++      struct s5k5baf_gpio *gpio = &state->gpios[id];
++
++      gpio_set_value(gpio->gpio, !gpio->level);
++}
++
++static void s5k5baf_power_on(struct s5k5baf *state)
++{
++      int ret;
++
++      ret = regulator_bulk_enable(S5K5BAF_NUM_SUPPLIES, state->supplies);
++      if (ret) {
++              state->error = ret;
++              return;
++      }
++
++      s5k5baf_gpio_deassert(state, STBY);
++      usleep_range(50, 100);
++      s5k5baf_gpio_deassert(state, RST);
++}
++
++static void s5k5baf_power_off(struct s5k5baf *state)
++{
++      int ret;
++
++      state->streaming = 0;
++      state->apply_cfg = 0;
++      state->apply_crop = 0;
++      s5k5baf_gpio_assert(state, RST);
++      s5k5baf_gpio_assert(state, STBY);
++      ret = regulator_bulk_disable(S5K5BAF_NUM_SUPPLIES, state->supplies);
++      if (ret && !state->error)
++              state->error = ret;
++}
++
++static void s5k5baf_hw_init(struct s5k5baf *state)
++{
++      s5k5baf_i2c_write(state, AHB_MSB_ADDR_PTR, PAGE_IF_HW);
++      s5k5baf_i2c_write(state, REG_CLEAR_HOST_INT, 0);
++      s5k5baf_i2c_write(state, REG_SW_LOAD_COMPLETE, 1);
++      s5k5baf_i2c_write(state, REG_CMDRD_PAGE, PAGE_IF_SW);
++      s5k5baf_i2c_write(state, REG_CMDWR_PAGE, PAGE_IF_SW);
++}
++
++static int s5k5baf_clear_error(struct s5k5baf *state)
++{
++      int ret = state->error;
++
++      state->error = 0;
++      return ret;
++}
++
++/*
++ * V4L2 subdev core and video operations
++ */
++
++static void s5k5baf_initialize_data(struct s5k5baf *state)
++{
++      state->crop_sink = s5k5baf_cis_rect;
++      state->compose = s5k5baf_def_rect;
++      state->crop_source = state->compose;
++      state->pixfmt = 0;
++      state->req_fiv = 10000 / 15;
++      state->fiv = state->req_fiv;
++}
++
++static int s5k5baf_set_power(struct v4l2_subdev *sd, int on)
++{
++      struct s5k5baf *state = to_s5k5baf(sd);
++      int ret;
++
++      mutex_lock(&state->lock);
++
++      if (!on == state->power) {
++              if (on) {
++                      s5k5baf_initialize_data(state);
++                      s5k5baf_power_on(state);
++                      s5k5baf_hw_init(state);
++                      s5k5baf_hw_patch(state);
++                      s5k5baf_i2c_write(state, REG_SET_HOST_INT, 1);
++                      s5k5baf_hw_set_clocks(state);
++                      s5k5baf_hw_set_video_bus(state);
++                      s5k5baf_hw_set_cis(state);
++                      s5k5baf_hw_set_ccm(state);
++              } else {
++                      s5k5baf_power_off(state);
++              }
++
++              if (!state->error)
++                      state->power += on ? 1 : -1;
++      }
++
++      ret = s5k5baf_clear_error(state);
++      mutex_unlock(&state->lock);
++
++      if (!ret && on && state->power == 1)
++              ret = v4l2_ctrl_handler_setup(&state->ctrls.handler);
++
++      return ret;
++}
++
++static void s5k5baf_hw_set_stream(struct s5k5baf *state, int enable)
++{
++      s5k5baf_write_seq(state, REG_G_ENABLE_PREV, enable, 1);
++}
++
++static int s5k5baf_s_stream(struct v4l2_subdev *sd, int on)
++{
++      struct s5k5baf *state = to_s5k5baf(sd);
++      int ret;
++
++      if (state->streaming == !!on)
++              return 0;
++
++      mutex_lock(&state->lock);
++
++      if (!on) {
++              s5k5baf_hw_set_stream(state, 0);
++              goto out;
++      }
++
++      s5k5baf_hw_set_config(state);
++      s5k5baf_hw_set_stream(state, 1);
++      s5k5baf_i2c_write(state, 0xb0cc, 0x000b);
++
++      if (!state->error)
++              state->streaming = 1;
++
++out:
++      ret = s5k5baf_clear_error(state);
++      mutex_unlock(&state->lock);
++
++      return ret;
++}
++
++static int s5k5baf_g_frame_interval(struct v4l2_subdev *sd,
++                                 struct v4l2_subdev_frame_interval *fi)
++{
++      struct s5k5baf *state = to_s5k5baf(sd);
++
++      mutex_lock(&state->lock);
++      fi->interval.numerator = state->fiv;
++      fi->interval.denominator = 10000;
++      mutex_unlock(&state->lock);
++
++      return 0;
++}
++
++static void s5k5baf_set_frame_interval(struct s5k5baf *state,
++                                     struct v4l2_subdev_frame_interval *fi)
++{
++      struct v4l2_fract *i = &fi->interval;
++
++      if (fi->interval.denominator == 0)
++              state->req_fiv = S5K5BAF_MAX_FR_TIME;
++      else
++              state->req_fiv = clamp_t(u32,
++                                       i->numerator * 10000 / i->denominator,
++                                       S5K5BAF_MIN_FR_TIME,
++                                       S5K5BAF_MAX_FR_TIME);
++
++      state->fiv = state->req_fiv;
++      if (state->apply_cfg) {
++              s5k5baf_hw_set_fiv(state, state->req_fiv);
++              s5k5baf_hw_validate_cfg(state);
++      }
++      *i = (struct v4l2_fract){state->fiv, 10000};
++      if (state->fiv == state->req_fiv)
++              v4l2_info(&state->sd, "frame interval changed to %d00us\n",
++                        state->fiv);
++}
++
++static int s5k5baf_s_frame_interval(struct v4l2_subdev *sd,
++                                 struct v4l2_subdev_frame_interval *fi)
++{
++      struct s5k5baf *state = to_s5k5baf(sd);
++
++      mutex_lock(&state->lock);
++      s5k5baf_set_frame_interval(state, fi);
++      mutex_unlock(&state->lock);
++      return 0;
++}
++
++/*
++ * V4L2 subdev pad level and video operations
++ */
++static int s5k5baf_enum_frame_interval(struct v4l2_subdev *sd,
++                            struct v4l2_subdev_fh *fh,
++                            struct v4l2_subdev_frame_interval_enum *fie)
++{
++      if (fie->index > S5K5BAF_MAX_FR_TIME - S5K5BAF_MIN_FR_TIME ||
++          fie->pad != 0)
++              return -EINVAL;
++
++      v4l_bound_align_image(&fie->width, S5K5BAF_WIN_WIDTH_MIN,
++                            S5K5BAF_CIS_WIDTH, 1,
++                            &fie->height, S5K5BAF_WIN_HEIGHT_MIN,
++                            S5K5BAF_CIS_HEIGHT, 1, 0);
++
++      fie->interval.numerator = S5K5BAF_MIN_FR_TIME + fie->index;
++      fie->interval.denominator = 10000;
++
++      return 0;
++}
++
++static int s5k5baf_enum_mbus_code(struct v4l2_subdev *sd,
++                               struct v4l2_subdev_fh *fh,
++                               struct v4l2_subdev_mbus_code_enum *code)
++{
++      if (code->pad == 0) {
++              if (code->index > 0)
++                      return -EINVAL;
++              code->code = V4L2_MBUS_FMT_FIXED;
++              return 0;
++      }
++
++      if (code->index >= ARRAY_SIZE(s5k5baf_formats))
++              return -EINVAL;
++
++      code->code = s5k5baf_formats[code->index].code;
++      return 0;
++}
++
++static int s5k5baf_enum_frame_size(struct v4l2_subdev *sd,
++                                struct v4l2_subdev_fh *fh,
++                                struct v4l2_subdev_frame_size_enum *fse)
++{
++      int i;
++
++      if (fse->index > 0)
++              return -EINVAL;
++
++      if (fse->pad == 0) {
++              fse->code = V4L2_MBUS_FMT_FIXED;
++              fse->min_width = S5K5BAF_CIS_WIDTH;
++              fse->max_width = S5K5BAF_CIS_WIDTH;
++              fse->min_height = S5K5BAF_CIS_HEIGHT;
++              fse->max_height = S5K5BAF_CIS_HEIGHT;
++              return 0;
++      }
++
++      i = ARRAY_SIZE(s5k5baf_formats);
++      while (--i)
++              if (fse->code == s5k5baf_formats[i].code)
++                      break;
++      fse->code = s5k5baf_formats[i].code;
++      fse->min_width = S5K5BAF_WIN_WIDTH_MIN;
++      fse->max_width = S5K5BAF_CIS_WIDTH;
++      fse->max_height = S5K5BAF_WIN_HEIGHT_MIN;
++      fse->min_height = S5K5BAF_CIS_HEIGHT;
++
++      return 0;
++}
++
++static void s5k5baf_try_cis_format(struct v4l2_mbus_framefmt *mf)
++{
++      mf->width = S5K5BAF_CIS_WIDTH;
++      mf->height = S5K5BAF_CIS_HEIGHT;
++      mf->code = V4L2_MBUS_FMT_FIXED;
++      mf->colorspace = V4L2_COLORSPACE_JPEG;
++      mf->field = V4L2_FIELD_NONE;
++}
++
++static int s5k5baf_try_isp_format(struct v4l2_mbus_framefmt *mf)
++{
++      int pixfmt;
++
++      v4l_bound_align_image(&mf->width, S5K5BAF_WIN_WIDTH_MIN,
++                            S5K5BAF_CIS_WIDTH, 1,
++                            &mf->height, S5K5BAF_WIN_HEIGHT_MIN,
++                            S5K5BAF_CIS_HEIGHT, 1, 0);
++
++      pixfmt = s5k5baf_find_pixfmt(mf);
++
++      mf->colorspace = s5k5baf_formats[pixfmt].colorspace;
++      mf->code = s5k5baf_formats[pixfmt].code;
++      mf->field = V4L2_FIELD_NONE;
++
++      return pixfmt;
++}
++
++static int s5k5baf_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
++                        struct v4l2_subdev_format *fmt)
++{
++      struct s5k5baf *state = to_s5k5baf(sd);
++      const struct s5k5baf_pixfmt *pixfmt;
++      struct v4l2_mbus_framefmt *mf;
++
++      memset(fmt->reserved, 0, sizeof(fmt->reserved));
++
++      if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
++              mf = v4l2_subdev_get_try_format(fh, fmt->pad);
++              fmt->format = *mf;
++              return 0;
++      }
++
++      mf = &fmt->format;
++      if (fmt->pad == 0) {
++              s5k5baf_try_cis_format(mf);
++              return 0;
++      }
++      mf->field = V4L2_FIELD_NONE;
++      mutex_lock(&state->lock);
++      pixfmt = &s5k5baf_formats[state->pixfmt];
++      mf->width = state->crop_source.width;
++      mf->height = state->crop_source.height;
++      mf->code = pixfmt->code;
++      mf->colorspace = pixfmt->colorspace;
++      mutex_unlock(&state->lock);
++
++      return 0;
++}
++
++static int s5k5baf_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
++                        struct v4l2_subdev_format *fmt)
++{
++      struct v4l2_mbus_framefmt *mf = &fmt->format;
++      struct s5k5baf *state = to_s5k5baf(sd);
++      const struct s5k5baf_pixfmt *pixfmt;
++      int ret = 0;
++
++      if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
++              *v4l2_subdev_get_try_format(fh, fmt->pad) = *mf;
++              return 0;
++      }
++
++      if (fmt->pad == 0) {
++              s5k5baf_try_cis_format(mf);
++              return 0;
++      }
++
++      mutex_lock(&state->lock);
++
++      if (state->streaming) {
++              ret = -EBUSY;
++              goto out;
++      }
++
++      state->pixfmt = s5k5baf_try_isp_format(mf);
++      pixfmt = &s5k5baf_formats[state->pixfmt];
++      mf->code = pixfmt->code;
++      mf->colorspace = pixfmt->colorspace;
++      mf->width = state->crop_source.width;
++      mf->height = state->crop_source.height;
++
++out:
++      mutex_unlock(&state->lock);
++
++      return ret;
++}
++
++enum selection_rect {R_CIS, R_CROP_SINK, R_COMPOSE, R_CROP_SOURCE, R_INVALID};
++
++static enum selection_rect s5k5baf_get_sel_rect(u32 pad, u32 target)
++{
++      switch (target) {
++      case V4L2_SEL_TGT_CROP_BOUNDS:
++              return pad ? R_COMPOSE : R_CIS;
++      case V4L2_SEL_TGT_CROP:
++              return pad ? R_CROP_SOURCE : R_CROP_SINK;
++      case V4L2_SEL_TGT_COMPOSE_BOUNDS:
++              return pad ? R_INVALID : R_CROP_SINK;
++      case V4L2_SEL_TGT_COMPOSE:
++              return pad ? R_INVALID : R_COMPOSE;
++      default:
++              return R_INVALID;
++      }
++}
++
++static int s5k5baf_is_bound_tgt(u32 target)
++{
++      return (target == V4L2_SEL_TGT_CROP_BOUNDS ||
++              target == V4L2_SEL_TGT_COMPOSE_BOUNDS);
++}
++
++static int s5k5baf_get_selection(struct v4l2_subdev *sd,
++                               struct v4l2_subdev_fh *fh,
++                               struct v4l2_subdev_selection *sel)
++{
++      static enum selection_rect rtype;
++      struct s5k5baf *state = to_s5k5baf(sd);
++
++      rtype = s5k5baf_get_sel_rect(sel->pad, sel->target);
++
++      switch (rtype) {
++      case R_INVALID:
++              return -EINVAL;
++      case R_CIS:
++              sel->r = s5k5baf_cis_rect;
++              return 0;
++      default:
++              break;
++      }
++
++      if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
++              if (rtype == R_COMPOSE)
++                      sel->r = *v4l2_subdev_get_try_compose(fh, sel->pad);
++              else
++                      sel->r = *v4l2_subdev_get_try_crop(fh, sel->pad);
++              return 0;
++      }
++
++      mutex_lock(&state->lock);
++      switch (rtype) {
++      case R_CROP_SINK:
++              sel->r = state->crop_sink;
++              break;
++      case R_COMPOSE:
++              sel->r = state->compose;
++              break;
++      case R_CROP_SOURCE:
++              sel->r = state->crop_source;
++              break;
++      default:
++              break;
++      }
++      if (s5k5baf_is_bound_tgt(sel->target)) {
++              sel->r.left = 0;
++              sel->r.top = 0;
++      }
++      mutex_unlock(&state->lock);
++
++      return 0;
++}
++
++/* bounds range [start, start+len) to [0, max) and aligns to 2 */
++static void s5k5baf_bound_range(u32 *start, u32 *len, u32 max)
++{
++      if (*len > max)
++              *len = max;
++      if (*start + *len > max)
++              *start = max - *len;
++      *start &= ~1;
++      *len &= ~1;
++      if (*len < S5K5BAF_WIN_WIDTH_MIN)
++              *len = S5K5BAF_WIN_WIDTH_MIN;
++}
++
++static void s5k5baf_bound_rect(struct v4l2_rect *r, u32 width, u32 height)
++{
++      s5k5baf_bound_range(&r->left, &r->width, width);
++      s5k5baf_bound_range(&r->top, &r->height, height);
++}
++
++static void s5k5baf_set_rect_and_adjust(struct v4l2_rect **rects,
++                                      enum selection_rect first,
++                                      struct v4l2_rect *v)
++{
++      struct v4l2_rect *r, *br;
++      enum selection_rect i = first;
++
++      *rects[first] = *v;
++      do {
++              r = rects[i];
++              br = rects[i - 1];
++              s5k5baf_bound_rect(r, br->width, br->height);
++      } while (++i != R_INVALID);
++      *v = *rects[first];
++}
++
++static bool s5k5baf_cmp_rect(const struct v4l2_rect *r1,
++                           const struct v4l2_rect *r2)
++{
++      return !memcmp(r1, r2, sizeof(*r1));
++}
++
++static int s5k5baf_set_selection(struct v4l2_subdev *sd,
++                               struct v4l2_subdev_fh *fh,
++                               struct v4l2_subdev_selection *sel)
++{
++      static enum selection_rect rtype;
++      struct s5k5baf *state = to_s5k5baf(sd);
++      struct v4l2_rect **rects;
++      int ret;
++
++      rtype = s5k5baf_get_sel_rect(sel->pad, sel->target);
++      if (rtype == R_INVALID || s5k5baf_is_bound_tgt(sel->target))
++              return -EINVAL;
++
++      /* allow only scaling on compose */
++      if (rtype == R_COMPOSE) {
++              sel->r.left = 0;
++              sel->r.top = 0;
++      }
++
++      if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
++              rects = (struct v4l2_rect * []) {
++                              &s5k5baf_cis_rect,
++                              v4l2_subdev_get_try_crop(fh, 0),
++                              v4l2_subdev_get_try_compose(fh, 0),
++                              v4l2_subdev_get_try_crop(fh, 1)
++                      };
++              s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r);
++              return 0;
++      }
++
++      rects = (struct v4l2_rect * []) {
++                      &s5k5baf_cis_rect,
++                      &state->crop_sink,
++                      &state->compose,
++                      &state->crop_source
++              };
++      mutex_lock(&state->lock);
++      if (state->streaming) {
++              /* adjust sel->r to avoid output resolution change */
++              if (rtype < R_CROP_SOURCE) {
++                      if (sel->r.width < state->crop_source.width)
++                              sel->r.width = state->crop_source.width;
++                      if (sel->r.height < state->crop_source.height)
++                              sel->r.height = state->crop_source.height;
++              } else {
++                      sel->r.width = state->crop_source.width;
++                      sel->r.height = state->crop_source.height;
++              }
++      }
++      s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r);
++      if (!s5k5baf_cmp_rect(&state->crop_sink, &s5k5baf_cis_rect) ||
++          !s5k5baf_cmp_rect(&state->compose, &s5k5baf_def_rect))
++              state->apply_crop = 1;
++      s5k5baf_hw_set_crop_rects(state);
++      ret = s5k5baf_clear_error(state);
++      mutex_unlock(&state->lock);
++
++      return ret;
++}
++
++static const struct v4l2_subdev_pad_ops s5k5baf_cis_pad_ops = {
++      .enum_mbus_code         = s5k5baf_enum_mbus_code,
++      .enum_frame_size        = s5k5baf_enum_frame_size,
++      .get_fmt                = s5k5baf_get_fmt,
++      .set_fmt                = s5k5baf_set_fmt,
++};
++
++static const struct v4l2_subdev_pad_ops s5k5baf_pad_ops = {
++      .enum_mbus_code         = s5k5baf_enum_mbus_code,
++      .enum_frame_size        = s5k5baf_enum_frame_size,
++      .enum_frame_interval    = s5k5baf_enum_frame_interval,
++      .get_fmt                = s5k5baf_get_fmt,
++      .set_fmt                = s5k5baf_set_fmt,
++      .get_selection          = s5k5baf_get_selection,
++      .set_selection          = s5k5baf_set_selection,
++};
++
++static const struct v4l2_subdev_video_ops s5k5baf_video_ops = {
++      .g_frame_interval       = s5k5baf_g_frame_interval,
++      .s_frame_interval       = s5k5baf_s_frame_interval,
++      .s_stream               = s5k5baf_s_stream,
++};
++
++/*
++ * V4L2 subdev controls
++ */
++
++static int s5k5baf_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++      struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
++      struct s5k5baf *state = to_s5k5baf(sd);
++      int ret;
++
++      v4l2_dbg(1, debug, sd, "ctrl: %s, value: %d\n", ctrl->name, ctrl->val);
++
++      mutex_lock(&state->lock);
++
++      if (state->power == 0)
++              goto unlock;
++
++      switch (ctrl->id) {
++      case V4L2_CID_AUTO_WHITE_BALANCE:
++              s5k5baf_hw_set_awb(state, ctrl->val);
++              break;
++
++      case V4L2_CID_BRIGHTNESS:
++              s5k5baf_write(state, REG_USER_BRIGHTNESS, ctrl->val);
++              break;
++
++      case V4L2_CID_COLORFX:
++              s5k5baf_hw_set_colorfx(state, ctrl->val);
++              break;
++
++      case V4L2_CID_CONTRAST:
++              s5k5baf_write(state, REG_USER_CONTRAST, ctrl->val);
++              break;
++
++      case V4L2_CID_EXPOSURE_AUTO:
++              s5k5baf_hw_set_auto_exposure(state, ctrl->val);
++              break;
++
++      case V4L2_CID_HFLIP:
++              s5k5baf_hw_set_mirror(state, ctrl->val);
++              break;
++
++      case V4L2_CID_POWER_LINE_FREQUENCY:
++              s5k5baf_hw_set_anti_flicker(state, ctrl->val);
++              break;
++
++      case V4L2_CID_SATURATION:
++              s5k5baf_write(state, REG_USER_SATURATION, ctrl->val);
++              break;
++
++      case V4L2_CID_SHARPNESS:
++              s5k5baf_write(state, REG_USER_SHARPBLUR, ctrl->val);
++              break;
++
++      case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
++              s5k5baf_write(state, REG_P_COLORTEMP(0), ctrl->val);
++              if (state->apply_cfg)
++                      s5k5baf_hw_sync_cfg(state);
++              break;
++
++      case V4L2_CID_TEST_PATTERN:
++              s5k5baf_hw_set_test_pattern(state, ctrl->val);
++              break;
++      }
++unlock:
++      ret = s5k5baf_clear_error(state);
++      mutex_unlock(&state->lock);
++      return ret;
++}
++
++static const struct v4l2_ctrl_ops s5k5baf_ctrl_ops = {
++      .s_ctrl = s5k5baf_s_ctrl,
++};
++
++static const struct v4l2_ctrl_config s5k5baf_ctrls[] = {
++      {
++              .ops    = &s5k5baf_ctrl_ops,
++              .id     = V4L2_CID_RED_GAIN,
++              .type   = V4L2_CTRL_TYPE_INTEGER,
++              .name   = "Gain, Red",
++              .min    = 0,
++              .max    = 256,
++              .def    = 127,
++              .step   = 1,
++      }, {
++              .ops    = &s5k5baf_ctrl_ops,
++              .id     = V4L2_CID_GREEN_GAIN,
++              .type   = V4L2_CTRL_TYPE_INTEGER,
++              .name   = "Gain, Green",
++              .min    = 0,
++              .max    = 256,
++              .def    = 127,
++              .step   = 1,
++      }, {
++              .ops    = &s5k5baf_ctrl_ops,
++              .id     = V4L2_CID_BLUE_GAIN,
++              .type   = V4L2_CTRL_TYPE_INTEGER,
++              .name   = "Gain, Blue",
++              .min    = 0,
++              .max    = 256,
++              .def    = 127,
++              .step   = 1,
++      },
++};
++
++static const char * const s5k5baf_test_pattern_menu[] = {
++      "Disabled",
++      "Blank",
++      "Bars",
++      "Gradients",
++      "Textile",
++      "Textile2",
++      "Squares"
++};
++
++static int s5k5baf_initialize_ctrls(struct s5k5baf *state)
++{
++      const struct v4l2_ctrl_ops *ops = &s5k5baf_ctrl_ops;
++      struct s5k5baf_ctrls *ctrls = &state->ctrls;
++      struct v4l2_ctrl_handler *hdl = &ctrls->handler;
++      int ret;
++
++      ret = v4l2_ctrl_handler_init(hdl, 16);
++      if (ret) {
++              v4l2_err(&state->sd, "cannot init ctrl handler (%d)\n", ret);
++              return ret;
++      }
++
++      /* Auto white balance cluster */
++      ctrls->awb = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTO_WHITE_BALANCE,
++                                     0, 1, 1, 1);
++      ctrls->gain_red = v4l2_ctrl_new_custom(hdl, &s5k5baf_ctrls[0], NULL);
++      ctrls->gain_green = v4l2_ctrl_new_custom(hdl, &s5k5baf_ctrls[1], NULL);
++      ctrls->gain_blue = v4l2_ctrl_new_custom(hdl, &s5k5baf_ctrls[2], NULL);
++      v4l2_ctrl_auto_cluster(4, &ctrls->awb, 0, false);
++
++      ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
++      ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
++      v4l2_ctrl_cluster(2, &ctrls->hflip);
++
++      ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops,
++                              V4L2_CID_EXPOSURE_AUTO,
++                              V4L2_EXPOSURE_MANUAL, 0, V4L2_EXPOSURE_AUTO);
++      /* Exposure time: x 1 us */
++      ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
++                                          0, 6000000U, 1, 100000U);
++      /* Total gain: 256 <=> 1x */
++      ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN,
++                                      0, 256, 1, 256);
++      v4l2_ctrl_auto_cluster(3, &ctrls->auto_exp, 0, false);
++
++      v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_POWER_LINE_FREQUENCY,
++                             V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
++                             V4L2_CID_POWER_LINE_FREQUENCY_AUTO);
++
++      v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_COLORFX,
++                             V4L2_COLORFX_SKY_BLUE, ~0x6f, V4L2_COLORFX_NONE);
++
++      v4l2_ctrl_new_std(hdl, ops, V4L2_CID_WHITE_BALANCE_TEMPERATURE,
++                        0, 256, 1, 0);
++
++      v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION, -127, 127, 1, 0);
++      v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, -127, 127, 1, 0);
++      v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -127, 127, 1, 0);
++      v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SHARPNESS, -127, 127, 1, 0);
++
++      v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_TEST_PATTERN,
++                                   ARRAY_SIZE(s5k5baf_test_pattern_menu) - 1,
++                                   0, 0, s5k5baf_test_pattern_menu);
++
++      if (hdl->error) {
++              v4l2_err(&state->sd, "error creating controls (%d)\n",
++                       hdl->error);
++              ret = hdl->error;
++              v4l2_ctrl_handler_free(hdl);
++              return ret;
++      }
++
++      state->sd.ctrl_handler = hdl;
++      return 0;
++}
++
++/*
++ * V4L2 subdev internal operations
++ */
++static int s5k5baf_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
++{
++      struct v4l2_mbus_framefmt *mf;
++      struct v4l2_rect *r;
++
++      mf = v4l2_subdev_get_try_format(fh, 0);
++      s5k5baf_try_cis_format(mf);
++
++      if (s5k5baf_is_cis_subdev(sd))
++              return 0;
++
++      mf = v4l2_subdev_get_try_format(fh, 1);
++      mf->colorspace = s5k5baf_formats[0].colorspace;
++      mf->code = s5k5baf_formats[0].code;
++      mf->width = s5k5baf_def_rect.width;
++      mf->height = s5k5baf_def_rect.height;
++      mf->field = V4L2_FIELD_NONE;
++
++      *v4l2_subdev_get_try_crop(fh, 0) = s5k5baf_cis_rect;
++      r = v4l2_subdev_get_try_compose(fh, 0);
++      *r = s5k5baf_def_rect;
++      *v4l2_subdev_get_try_crop(fh, 1) = *r;
++
++      return 0;
++}
++
++static void s5k5baf_check_fw_revision(struct s5k5baf *state)
++{
++      u16 api_ver = 0, fw_rev = 0, s_id = 0;
++
++      api_ver = s5k5baf_read(state, REG_FW_APIVER);
++      fw_rev = s5k5baf_read(state, REG_FW_REVISION) & 0xff;
++      s_id = s5k5baf_read(state, REG_FW_SENSOR_ID);
++      if (state->error)
++              return;
++
++      v4l2_info(&state->sd, "FW API=%#x, revision=%#x sensor_id=%#x\n",
++                api_ver, fw_rev, s_id);
++
++      if (api_ver == S5K5BAF_FW_APIVER)
++              return;
++
++      v4l2_err(&state->sd, "FW API version not supported\n");
++      state->error = -ENODEV;
++}
++
++static int s5k5baf_registered(struct v4l2_subdev *sd)
++{
++      struct s5k5baf *state = to_s5k5baf(sd);
++      int ret;
++
++      ret = v4l2_device_register_subdev(sd->v4l2_dev, &state->cis_sd);
++      if (ret) {
++              v4l2_err(sd, "failed to register subdev %s\n",
++                       state->cis_sd.name);
++              return ret;
++      }
++
++      mutex_lock(&state->lock);
++
++      s5k5baf_power_on(state);
++      s5k5baf_hw_init(state);
++      s5k5baf_check_fw_revision(state);
++      s5k5baf_power_off(state);
++      ret = s5k5baf_clear_error(state);
++
++      mutex_unlock(&state->lock);
++
++      if (ret)
++              v4l2_device_unregister_subdev(&state->cis_sd);
++
++      return ret;
++}
++
++static void s5k5baf_unregistered(struct v4l2_subdev *sd)
++{
++      struct s5k5baf *state = to_s5k5baf(sd);
++      v4l2_device_unregister_subdev(&state->cis_sd);
++}
++
++static const struct v4l2_subdev_ops s5k5baf_cis_subdev_ops = {
++      .pad    = &s5k5baf_cis_pad_ops,
++};
++
++static const struct v4l2_subdev_internal_ops s5k5baf_cis_subdev_internal_ops = {
++      .open = s5k5baf_open,
++};
++
++static const struct v4l2_subdev_internal_ops s5k5baf_subdev_internal_ops = {
++      .registered = s5k5baf_registered,
++      .unregistered = s5k5baf_unregistered,
++      .open = s5k5baf_open,
++};
++
++static const struct v4l2_subdev_core_ops s5k5baf_core_ops = {
++      .s_power = s5k5baf_set_power,
++      .log_status = v4l2_ctrl_subdev_log_status,
++};
++
++static const struct v4l2_subdev_ops s5k5baf_subdev_ops = {
++      .core = &s5k5baf_core_ops,
++      .pad = &s5k5baf_pad_ops,
++      .video = &s5k5baf_video_ops,
++};
++
++static int s5k5baf_configure_gpios(struct s5k5baf *state)
++{
++      static const char const *name[] = { "S5K5BAF_STBY", "S5K5BAF_RST" };
++      struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
++      struct s5k5baf_gpio *g = state->gpios;
++      int ret, i;
++
++      for (i = 0; i < GPIO_NUM; ++i) {
++              int flags = GPIOF_EXPORT | GPIOF_DIR_OUT;
++              if (g[i].level)
++                      flags |= GPIOF_INIT_HIGH;
++              ret = devm_gpio_request_one(&c->dev, g[i].gpio, flags, name[i]);
++              if (ret) {
++                      v4l2_err(c, "failed to request gpio %s\n", name[i]);
++                      return ret;
++              }
++      }
++      return 0;
++}
++
++static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev)
++{
++      struct device_node *node = dev->of_node;
++      struct device_node *node_ep;
++      struct v4l2_of_endpoint ep;
++      enum of_gpio_flags of_flags;
++
++      if (!node) {
++              dev_err(dev, "no device-tree node provided\n");
++              return -EINVAL;
++      }
++
++      of_property_read_u32(node, "clock-frequency", &state->mclk_frequency);
++      state->hflip = of_property_read_bool(node, "samsung,hflip");
++      state->vflip = of_property_read_bool(node, "samsung,vflip");
++      state->gpios[STBY].gpio = of_get_gpio_flags(node, STBY, &of_flags);
++      state->gpios[STBY].level = !(of_flags & OF_GPIO_ACTIVE_LOW);
++      state->gpios[RST].gpio = of_get_gpio_flags(node, RST, &of_flags);
++      state->gpios[RST].level = !(of_flags & OF_GPIO_ACTIVE_LOW);
++
++      node_ep = v4l2_of_get_next_endpoint(node, NULL);
++      if (!node_ep) {
++              dev_err(dev, "no endpoint defined\n");
++              return -EINVAL;
++      }
++      v4l2_of_parse_endpoint(node_ep, &ep);
++      of_node_put(node_ep);
++      state->bus_type = ep.bus_type;
++      if (state->bus_type == V4L2_MBUS_CSI2)
++              state->nlanes = ep.bus.mipi_csi2.num_data_lanes;
++      return 0;
++}
++
++static int s5k5baf_configure_subdevs(struct s5k5baf *state,
++                                   struct i2c_client *c)
++{
++      struct v4l2_subdev *sd;
++      int ret;
++
++      sd = &state->cis_sd;
++      v4l2_subdev_init(sd, &s5k5baf_cis_subdev_ops);
++      sd->owner = c->driver->driver.owner;
++      v4l2_set_subdevdata(sd, state);
++      strlcpy(sd->name, "S5K5BAF-CIS", sizeof(sd->name));
++
++      sd->internal_ops = &s5k5baf_cis_subdev_internal_ops;
++      sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++      state->cis_pad.flags = MEDIA_PAD_FL_SOURCE;
++      sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
++      ret = media_entity_init(&sd->entity, 1, &state->cis_pad, 0);
++      if (ret)
++              goto err;
++
++      sd = &state->sd;
++      v4l2_i2c_subdev_init(sd, c, &s5k5baf_subdev_ops);
++      strlcpy(sd->name, "S5K5BAF-ISP", sizeof(sd->name));
++
++      sd->internal_ops = &s5k5baf_subdev_internal_ops;
++      sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++      state->pads[0].flags = MEDIA_PAD_FL_SINK;
++      state->pads[1].flags = MEDIA_PAD_FL_SOURCE;
++      sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
++      ret = media_entity_init(&sd->entity, 2, state->pads, 0);
++      if (ret)
++              goto err_cis;
++
++      ret = media_entity_create_link(&state->cis_sd.entity,
++                                     0, &state->sd.entity, 0,
++                                     MEDIA_LNK_FL_IMMUTABLE |
++                                     MEDIA_LNK_FL_ENABLED);
++
++      if (!ret)
++              return 0;
++
++      media_entity_cleanup(&state->sd.entity);
++err_cis:
++      media_entity_cleanup(&state->cis_sd.entity);
++err:
++      dev_err(&c->dev, "cannot init media entity %s\n", sd->name);
++      return ret;
++}
++
++static int s5k5baf_configure_regulators(struct s5k5baf *state)
++{
++      struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
++      int ret;
++      int i;
++
++      for (i = 0; i < S5K5BAF_NUM_SUPPLIES; i++)
++              state->supplies[i].supply = s5k5baf_supply_names[i];
++
++      ret = devm_regulator_bulk_get(&c->dev, S5K5BAF_NUM_SUPPLIES,
++                                    state->supplies);
++      if (ret)
++              v4l2_err(c, "failed to get regulators\n");
++      return ret;
++}
++
++static int s5k5baf_probe(struct i2c_client *c,
++                      const struct i2c_device_id *id)
++{
++      struct s5k5baf *state;
++      int ret;
++
++      state = devm_kzalloc(&c->dev, sizeof(*state), GFP_KERNEL);
++      if (!state)
++              return -ENOMEM;
++
++      mutex_init(&state->lock);
++
++      ret = s5k5baf_parse_device_node(state, &c->dev);
++      if (ret)
++              goto err;
++
++      ret = s5k5baf_configure_subdevs(state, c);
++      if (ret)
++              goto err;
++
++      ret = s5k5baf_configure_gpios(state);
++      if (ret)
++              goto err;
++
++      ret = s5k5baf_configure_regulators(state);
++      if (ret)
++              goto err;
++
++      ret = s5k5baf_initialize_ctrls(state);
++      if (ret)
++              goto err;
++
++      return 0;
++err:
++      media_entity_cleanup(&state->sd.entity);
++      media_entity_cleanup(&state->cis_sd.entity);
++      return ret;
++}
++
++static int s5k5baf_remove(struct i2c_client *c)
++{
++      struct v4l2_subdev *sd = i2c_get_clientdata(c);
++      struct s5k5baf *state = to_s5k5baf(sd);
++
++      v4l2_device_unregister_subdev(sd);
++      v4l2_ctrl_handler_free(sd->ctrl_handler);
++      media_entity_cleanup(&sd->entity);
++
++      sd = &state->cis_sd;
++      v4l2_device_unregister_subdev(sd);
++      media_entity_cleanup(&sd->entity);
++
++      return 0;
++}
++
++static const struct i2c_device_id s5k5baf_id[] = {
++      { S5K5BAF_DRIVER_NAME, 0 },
++      { },
++};
++MODULE_DEVICE_TABLE(i2c, s5k5baf_id);
++
++static const struct of_device_id s5k5baf_of_match[] = {
++      { .compatible = "samsung,s5k5baf" },
++      { }
++};
++MODULE_DEVICE_TABLE(of, s5k5baf_of_match);
++
++static struct i2c_driver s5k5baf_i2c_driver = {
++      .driver = {
++              .of_match_table = s5k5baf_of_match,
++              .name = S5K5BAF_DRIVER_NAME
++      },
++      .probe          = s5k5baf_probe,
++      .remove         = s5k5baf_remove,
++      .id_table       = s5k5baf_id,
++};
++
++module_i2c_driver(s5k5baf_i2c_driver);
++
++MODULE_DESCRIPTION("Samsung S5K5BAF(X) UXGA camera driver");
++MODULE_AUTHOR("Andrzej Hajda <a.hajda@samsung.com>");
++MODULE_LICENSE("GPL");
+diff --git a/include/uapi/linux/s5k5baf.h b/include/uapi/linux/s5k5baf.h
+new file mode 100644
+index 0000000..e1fcb56
+--- /dev/null
++++ b/include/uapi/linux/s5k5baf.h
+@@ -0,0 +1,19 @@
++/*
++ * S5K5BAF camera sensor driver header
++ *
++ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++
++#ifndef _UAPI_LINUX_S5K5BAF_H
++#define _UAPI_LINUX_S5K5BAF_H
++
++#define V4L2_CID_RED_GAIN     (V4L2_CID_CAMERA_S5K5BAF_BASE + 0)
++#define V4L2_CID_GREEN_GAIN   (V4L2_CID_CAMERA_S5K5BAF_BASE + 1)
++#define V4L2_CID_BLUE_GAIN    (V4L2_CID_CAMERA_S5K5BAF_BASE + 2)
++
++#endif /* _UAPI_LINUX_S5K5BAF_H */
+diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
+index 69bd5bb..305d098 100644
+--- a/include/uapi/linux/v4l2-controls.h
++++ b/include/uapi/linux/v4l2-controls.h
+@@ -700,6 +700,11 @@ enum v4l2_auto_focus_range {
+       V4L2_AUTO_FOCUS_RANGE_INFINITY          = 3,
+ };
++/* Camera class private control IDs */
++
++/* The base for the s5k5baf driver controls. See linux/s5k5baf.h for the list
++ * of controls. We reserve 16 controls for this driver. */
++#define V4L2_CID_CAMERA_S5K5BAF_BASE          (V4L2_CID_CAMERA_CLASS_BASE + 0x1000)
+ /* FM Modulator class control IDs */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0238-ARM-dts-exynos4210-trats.patch b/patches.tizen/0238-ARM-dts-exynos4210-trats.patch
new file mode 100644 (file)
index 0000000..258169f
--- /dev/null
@@ -0,0 +1,40 @@
+From 33dde54edf2a1b324c1f910732f758a04998113c Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Wed, 15 May 2013 13:04:14 +0200
+Subject: [PATCH 0238/1302] ARM: dts: exynos4210-trats
+
+Adjusted front camera configuration to work with s5k5baf driver.
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index 0508e6c0..4ebf3e6 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -199,15 +199,16 @@
+                       compatible = "samsung,s5k5baf";
+                       reg = <0x2d>;
+                       vdda-supply = <&cam_io_en_reg>;
+-                      vdd_reg-supply = <&vt_core_15v_reg>;
++                      vddreg-supply = <&vt_core_15v_reg>;
+                       vddio-supply = <&vtcam_reg>;
+-                      gpios = <&gpl2 1 1>,
+-                              <&gpl2 0 1>;
++                      gpios = <&gpl2 0 1>,
++                              <&gpl2 1 1>;
+                       clock-frequency = <24000000>;
+                       port {
+                               s5k5bafx_ep: endpoint {
+                                       remote-endpoint = <&csis1_ep>;
++                                      data-lanes = <1>;
+                               };
+                       };
+               };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0239-power-max17042-Fix-deadlock-caused-by-deferred-initi.patch b/patches.tizen/0239-power-max17042-Fix-deadlock-caused-by-deferred-initi.patch
new file mode 100644 (file)
index 0000000..0d12931
--- /dev/null
@@ -0,0 +1,113 @@
+From 3714105bcc428c82ec39f6ae4d6a3baf7d17717e Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Tue, 21 May 2013 18:04:27 +0200
+Subject: [PATCH 0239/1302] power: max17042: Fix deadlock caused by deferred
+ initialization
+
+There is no need to defer chip initialization from probe. In addition,
+current implementation caused a deadlock, which made boot hang from time
+to time.
+
+This patch removes deferred initialization and adds chip initialization
+to probe, before the power supply is registered.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/power/max17042_battery.c | 40 ++++++++++++++++++++--------------------
+ 1 file changed, 20 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/power/max17042_battery.c b/drivers/power/max17042_battery.c
+index ab5324b..dbe2e08 100644
+--- a/drivers/power/max17042_battery.c
++++ b/drivers/power/max17042_battery.c
+@@ -70,8 +70,6 @@ struct max17042_chip {
+       struct power_supply battery;
+       enum max170xx_chip_type chip_type;
+       struct max17042_platform_data *pdata;
+-      struct work_struct work;
+-      int    init_complete;
+ };
+ static int max17042_write_reg(struct i2c_client *client, u8 reg, u16 value)
+@@ -128,9 +126,6 @@ static int max17042_get_property(struct power_supply *psy,
+       int ret;
+       u8 reg;
+-      if (!chip->init_complete)
+-              return -EAGAIN;
+-
+       switch (psp) {
+       case POWER_SUPPLY_PROP_PRESENT:
+               ret = max17042_read_reg(chip->client, MAX17042_STATUS);
+@@ -638,20 +633,18 @@ static irqreturn_t max17042_thread_handler(int id, void *dev)
+       return IRQ_HANDLED;
+ }
+-static void max17042_init_worker(struct work_struct *work)
++static int max17042_init_worker(struct max17042_chip *chip)
+ {
+-      struct max17042_chip *chip = container_of(work,
+-                              struct max17042_chip, work);
+       int ret;
+       /* Initialize registers according to values from the platform data */
+       if (chip->pdata->enable_por_init && chip->pdata->config_data) {
+               ret = max17042_init_chip(chip);
+               if (ret)
+-                      return;
++                      return ret;
+       }
+-      chip->init_complete = 1;
++      return 0;
+ }
+ #ifdef CONFIG_OF
+@@ -748,12 +741,6 @@ static int max17042_probe(struct i2c_client *client,
+               max17042_write_reg(client, MAX17042_LearnCFG, 0x0007);
+       }
+-      ret = power_supply_register(&client->dev, &chip->battery);
+-      if (ret) {
+-              dev_err(&client->dev, "failed: power supply register\n");
+-              return ret;
+-      }
+-
+       if (client->irq) {
+               ret = request_threaded_irq(client->irq, NULL,
+                                               max17042_thread_handler,
+@@ -773,13 +760,26 @@ static int max17042_probe(struct i2c_client *client,
+       reg = max17042_read_reg(chip->client, MAX17042_STATUS);
+       if (reg & STATUS_POR_BIT) {
+-              INIT_WORK(&chip->work, max17042_init_worker);
+-              schedule_work(&chip->work);
+-      } else {
+-              chip->init_complete = 1;
++              ret = max17042_init_worker(chip);
++              if (ret) {
++                      dev_err(&client->dev, "failed: chip init\n");
++                      goto err_irq;
++              }
++      }
++
++      ret = power_supply_register(&client->dev, &chip->battery);
++      if (ret) {
++              dev_err(&client->dev, "failed: power supply register\n");
++              goto err_irq;
+       }
+       return 0;
++
++err_irq:
++      if (client->irq)
++              free_irq(client->irq, chip);
++
++      return ret;
+ }
+ static int max17042_remove(struct i2c_client *client)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0240-ARM-dts-exynos4210-trats-Add-aliases-for-bit-banged-.patch b/patches.tizen/0240-ARM-dts-exynos4210-trats-Add-aliases-for-bit-banged-.patch
new file mode 100644 (file)
index 0000000..b3caea8
--- /dev/null
@@ -0,0 +1,52 @@
+From 6abdbf1aa571e28c8379cd0a2b3e12f2ee7a2cda Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Tue, 21 May 2013 18:28:10 +0200
+Subject: [PATCH 0240/1302] ARM: dts: exynos4210-trats: Add aliases for
+ bit-banged I2C buses
+
+This patch adds missing aliases of bit-banged I2C buses required for
+numbered I2C bus registration.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index 4ebf3e6..7dc92cf 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -19,6 +19,11 @@
+       model = "Samsung Trats based on Exynos4210";
+       compatible = "samsung,trats", "samsung,exynos4210";
++      aliases {
++              i2c8 = &i2c_s5k5baf;
++              i2c9 = &i2c_max17042;
++      };
++
+       memory {
+               reg =  <0x40000000 0x10000000
+                       0x50000000 0x10000000
+@@ -187,7 +192,7 @@
+               };
+       };
+-      i2c-gpio {
++      i2c_s5k5baf: i2c-gpio {
+               compatible = "i2c-gpio";
+               gpios = <&gpc1 0 0>, <&gpc1 2 0>;
+               i2c-gpio,delay-us = <2>;
+@@ -500,7 +505,7 @@
+               };
+       };
+-      i2c-gpio-0 {
++      i2c_max17042: i2c-gpio-0 {
+               compatible = "i2c-gpio";
+               gpios = <&gpy4 0 0>, <&gpy4 1 0>;
+               i2c-gpio,delay-us = <5>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0241-ARM-dts-exynos4412-slp_pq-Add-aliases-for-bit-banged.patch b/patches.tizen/0241-ARM-dts-exynos4412-slp_pq-Add-aliases-for-bit-banged.patch
new file mode 100644 (file)
index 0000000..24879cb
--- /dev/null
@@ -0,0 +1,54 @@
+From 30aee1cf6402bc6046179c564e4f8de676a30cf7 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Tue, 21 May 2013 18:28:10 +0200
+Subject: [PATCH 0241/1302] ARM: dts: exynos4412-slp_pq: Add aliases for
+ bit-banged I2C buses
+
+This patch adds missing aliases of bit-banged I2C buses required for
+numbered I2C bus registration.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 7e89324..c052fc0 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -19,6 +19,13 @@
+       model = "Samsung SLP PQ based on Exynos4412";
+       compatible = "samsung,slp_pq", "samsung,exynos4412";
++      aliases {
++              i2c8 = &i2c_ak8975;
++              i2c9 = &i2c_lps331ap;
++              i2c10 = &i2c_if_pmic;
++              i2c11 = &i2c_fuel;
++      };
++
+       memory {
+               reg =  <0x40000000 0x10000000
+                       0x50000000 0x10000000
+@@ -139,7 +146,7 @@
+               };
+       };
+-      i2c-gpio-0 {
++      i2c_ak8975: i2c-gpio-0 {
+               compatible = "i2c-gpio";
+               gpios = <&gpy2 4 0>, <&gpy2 5 0>;
+               i2c-gpio,delay-us = <2>;
+@@ -155,7 +162,7 @@
+               };
+       };
+-      i2c-gpio-1 {
++      i2c_lps331ap: i2c-gpio-1 {
+               compatible = "i2c-gpio";
+               gpios = <&gpy2 2 0>, <&gpy2 3 0>;
+               i2c-gpio,delay-us = <2>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0242-ARM-dts-Correct-aclk400_mcuisp-clock-index-at-fimc-i.patch b/patches.tizen/0242-ARM-dts-Correct-aclk400_mcuisp-clock-index-at-fimc-i.patch
new file mode 100644 (file)
index 0000000..f1891dd
--- /dev/null
@@ -0,0 +1,30 @@
+From 50a4f8ec1068441a57472d963c63bd7fb93b926d Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Mon, 27 May 2013 15:55:54 +0200
+Subject: [PATCH 0242/1302] ARM: dts: Correct aclk400_mcuisp clock index at
+ fimc-is node
+
+Adjust to the upstream clocks definition differences.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index 1364030..caaff80 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -284,7 +284,7 @@
+                               <&clock 357>, <&clock 358>, <&clock 359>,
+                               <&clock 360>, <&clock 450>,<&clock 451>,
+                               <&clock 452>, <&clock 453>, <&clock 176>,
+-                              <&clock 13>, <&clock 454>, <&clock 396>,
++                              <&clock 13>, <&clock 454>, <&clock 395>,
+                               <&clock 455>;
+                       clock-names = "lite0", "lite1", "ppmuispx",
+                                     "ppmuispmx", "sysreg", "mpll",
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0243-gpu-mali-Remove-Exynos-PM-domain-checks-in-debug-cod.patch b/patches.tizen/0243-gpu-mali-Remove-Exynos-PM-domain-checks-in-debug-cod.patch
new file mode 100644 (file)
index 0000000..1de1498
--- /dev/null
@@ -0,0 +1,67 @@
+From d8d188334712ee28e4205bb0f53319d5c466ed60 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Mon, 27 May 2013 18:06:38 +0200
+Subject: [PATCH 0243/1302] gpu: mali: Remove Exynos PM domain checks in debug
+ code
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This fixes following compilation warning when Mali debug options are enabled:
+
+  CC      drivers/gpu/arm/mali400/mali/linux/mali_osk_low_level_mem.o
+drivers/gpu/arm/mali400/mali/linux/mali_osk_low_level_mem.c: In function ‘_mali_osk_mem_iowrite32_relaxed’:
+drivers/gpu/arm/mali400/mali/linux/mali_osk_low_level_mem.c:436: error: ‘EXYNOS4_G3D_CONFIGURATION’ undeclared (first use in this function)
+drivers/gpu/arm/mali400/mali/linux/mali_osk_low_level_mem.c:436: error: (Each undeclared identifier is reported only once
+drivers/gpu/arm/mali400/mali/linux/mali_osk_low_level_mem.c:436: error: for each function it appears in.)
+drivers/gpu/arm/mali400/mali/linux/mali_osk_low_level_mem.c: In function ‘_mali_osk_mem_ioread32’:
+drivers/gpu/arm/mali400/mali/linux/mali_osk_low_level_mem.c:453: error: ‘EXYNOS4_G3D_CONFIGURATION’ undeclared (first use in this function)
+drivers/gpu/arm/mali400/mali/linux/mali_osk_low_level_mem.c: In function ‘_mali_osk_mem_iowrite32’:
+drivers/gpu/arm/mali400/mali/linux/mali_osk_low_level_mem.c:469: error: ‘EXYNOS4_G3D_CONFIGURATION’ undeclared (first use in this function)
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/arm/mali400/mali/linux/mali_osk_low_level_mem.c | 12 ------------
+ 1 file changed, 12 deletions(-)
+
+diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_osk_low_level_mem.c b/drivers/gpu/arm/mali400/mali/linux/mali_osk_low_level_mem.c
+index 258f8b6..a97f990 100644
+--- a/drivers/gpu/arm/mali400/mali/linux/mali_osk_low_level_mem.c
++++ b/drivers/gpu/arm/mali400/mali/linux/mali_osk_low_level_mem.c
+@@ -432,10 +432,6 @@ void inline _mali_osk_mem_unreqregion( u32 phys, u32 size )
+ void inline _mali_osk_mem_iowrite32_relaxed( volatile mali_io_address addr, u32 offset, u32 val )
+ {
+-#ifdef CONFIG_SLP_MALI_DBG
+-      if (!(__raw_readl(EXYNOS4_G3D_CONFIGURATION) & 0x7))
+-              panic("%s:addr[0x%x]\n", __func__, (u32)addr + offset);
+-#endif
+       __raw_writel(cpu_to_le32(val),((u8*)addr) + offset);
+ }
+@@ -449,10 +445,6 @@ void inline _mali_osk_mem_iowrite32_relaxed_cpu( volatile mali_io_address addr,
+ u32 inline _mali_osk_mem_ioread32( volatile mali_io_address addr, u32 offset )
+ {
+-#ifdef CONFIG_SLP_MALI_DBG
+-      if (!(__raw_readl(EXYNOS4_G3D_CONFIGURATION) & 0x7))
+-              panic("%s:addr[0x%x]\n", __func__, (u32)addr + offset);
+-#endif
+       return ioread32(((u8*)addr) + offset);
+ }
+@@ -465,10 +457,6 @@ u32 inline _mali_osk_mem_ioread32_cpu(volatile mali_io_address addr, u32 offset)
+ void inline _mali_osk_mem_iowrite32( volatile mali_io_address addr, u32 offset, u32 val )
+ {
+-#ifdef CONFIG_SLP_MALI_DBG
+-      if (!(__raw_readl(EXYNOS4_G3D_CONFIGURATION) & 0x7))
+-              panic("%s:addr[0x%x]\n", __func__, (u32)addr + offset);
+-#endif
+       iowrite32(val, ((u8*)addr) + offset);
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0244-drm-exynos-add-device-tree-support-for-rotator.patch b/patches.tizen/0244-drm-exynos-add-device-tree-support-for-rotator.patch
new file mode 100644 (file)
index 0000000..a9b2c2b
--- /dev/null
@@ -0,0 +1,185 @@
+From 4e56b7bb772f5f46f6123a5314155e5c263e9c92 Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Fri, 31 May 2013 18:38:59 +0900
+Subject: [PATCH 0244/1302] drm/exynos: add device tree support for rotator
+
+The exynos4 platform is only dt-based since 3.10, we should convert driver data
+and ids to dt-based parsing methods. The rotator driver has a limit table to get
+size limit. The minimum size of RGB888 format is 8 x 8 and maximum size is 8K x
+8K. The other format, YCbCr420 2-Plane has 32 x 32 min size and 32K x 32K max
+size. Each format should be multiple of 'align' value.
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_rotator.c | 110 ++++++++++++++++++++--------
+ 1 file changed, 80 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
+index 9b6c709..039e23a 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_rotator.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
+@@ -96,7 +96,7 @@ struct rot_context {
+       struct resource *regs_res;
+       void __iomem    *regs;
+       struct clk      *clock;
+-      struct rot_limit_table  *limit_tbl;
++      struct rot_limit_table  limit_tbl;
+       int     irq;
+       int     cur_buf_id[EXYNOS_DRM_OPS_MAX];
+       bool    suspended;
+@@ -167,7 +167,7 @@ static irqreturn_t rotator_irq_handler(int irq, void *arg)
+ static void rotator_align_size(struct rot_context *rot, u32 fmt, u32 *hsize,
+               u32 *vsize)
+ {
+-      struct rot_limit_table *limit_tbl = rot->limit_tbl;
++      struct rot_limit_table *limit_tbl = &rot->limit_tbl;
+       struct rot_limit *limit;
+       u32 mask, val;
+@@ -639,6 +639,72 @@ static int rotator_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd)
+       return 0;
+ }
++static const struct of_device_id exynos_rotator_match[] = {
++      {
++              .compatible = "samsung,exynos4210-rotator",
++      },
++      {},
++};
++MODULE_DEVICE_TABLE(of, exynos_rotator_match);
++
++static int rotator_parse_dt_tbl(struct device_node *np, struct rot_limit *rlim)
++{
++      int ret;
++
++      ret = of_property_read_u32(np, "min_w", &rlim->min_w);
++      if (ret)
++              return ret;
++
++      ret = of_property_read_u32(np, "min_h", &rlim->min_h);
++      if (ret)
++              return ret;
++
++      ret = of_property_read_u32(np, "max_w", &rlim->max_w);
++      if (ret)
++              return ret;
++
++      ret = of_property_read_u32(np, "max_h", &rlim->max_h);
++      if (ret)
++              return ret;
++
++      ret = of_property_read_u32(np, "align", &rlim->align);
++      if (ret)
++              return ret;
++
++      return 0;
++}
++
++static int rotator_parse_dt(struct device *dev, struct rot_context *rot)
++{
++      struct device_node *ycbcr_node, *rgb888_node;
++      int ret;
++
++      ycbcr_node = of_get_child_by_name(dev->of_node, "ycbcr420_2p");
++      if (!ycbcr_node) {
++              dev_err(dev, "can't find ycbcr420_2p node\n");
++              return -ENODEV;
++      }
++
++      rgb888_node = of_get_child_by_name(dev->of_node, "rgb888");
++      if (!rgb888_node) {
++              dev_err(dev, "can't find rgb888 node\n");
++              return -ENODEV;
++      }
++
++      ret = rotator_parse_dt_tbl(ycbcr_node, &rot->limit_tbl.ycbcr420_2p);
++      if (ret) {
++              dev_err(dev, "failed to parse ycbcr420 data\n");
++              return ret;
++      }
++      ret = rotator_parse_dt_tbl(rgb888_node, &rot->limit_tbl.rgb888);
++      if (ret) {
++              dev_err(dev, "failed to parse rgb888 data\n");
++              return ret;
++      }
++
++      return 0;
++}
++
+ static int rotator_probe(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+@@ -646,14 +712,23 @@ static int rotator_probe(struct platform_device *pdev)
+       struct exynos_drm_ippdrv *ippdrv;
+       int ret;
++      if (!dev->of_node) {
++              dev_err(dev, "Cannot find device tree node\n");
++              return -ENODEV;
++      }
++
+       rot = devm_kzalloc(dev, sizeof(*rot), GFP_KERNEL);
+       if (!rot) {
+               dev_err(dev, "failed to allocate rot\n");
+               return -ENOMEM;
+       }
+-      rot->limit_tbl = (struct rot_limit_table *)
+-                              platform_get_device_id(pdev)->driver_data;
++      ret = rotator_parse_dt(dev, rot);
++      if (ret) {
++              dev_err(dev, "failed parse dt info\n");
++              devm_kfree(dev, rot);
++              return ret;
++      }
+       rot->regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       rot->regs = devm_ioremap_resource(dev, rot->regs_res);
+@@ -725,31 +800,6 @@ static int rotator_remove(struct platform_device *pdev)
+       return 0;
+ }
+-static struct rot_limit_table rot_limit_tbl = {
+-      .ycbcr420_2p = {
+-              .min_w = 32,
+-              .min_h = 32,
+-              .max_w = SZ_32K,
+-              .max_h = SZ_32K,
+-              .align = 3,
+-      },
+-      .rgb888 = {
+-              .min_w = 8,
+-              .min_h = 8,
+-              .max_w = SZ_8K,
+-              .max_h = SZ_8K,
+-              .align = 2,
+-      },
+-};
+-
+-static struct platform_device_id rotator_driver_ids[] = {
+-      {
+-              .name           = "exynos-rot",
+-              .driver_data    = (unsigned long)&rot_limit_tbl,
+-      },
+-      {},
+-};
+-
+ static int rotator_clk_crtl(struct rot_context *rot, bool enable)
+ {
+       DRM_DEBUG_KMS("%s\n", __func__);
+@@ -821,10 +871,10 @@ static const struct dev_pm_ops rotator_pm_ops = {
+ struct platform_driver rotator_driver = {
+       .probe          = rotator_probe,
+       .remove         = rotator_remove,
+-      .id_table       = rotator_driver_ids,
+       .driver         = {
+               .name   = "exynos-rot",
+               .owner  = THIS_MODULE,
+               .pm     = &rotator_pm_ops,
++              .of_match_table = of_match_ptr(exynos_rotator_match),
+       },
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0245-ARM-dts-add-a-rotator-node-for-exynos4.patch b/patches.tizen/0245-ARM-dts-add-a-rotator-node-for-exynos4.patch
new file mode 100644 (file)
index 0000000..b57a1f7
--- /dev/null
@@ -0,0 +1,52 @@
+From 4ecea92d099121d850dd263243e0295c1f125a6f Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Fri, 31 May 2013 18:56:21 +0900
+Subject: [PATCH 0245/1302] ARM: dts: add a rotator node for exynos4
+
+This patch adds a device node of rotator for exynos4 platform. It has proper
+register and clock information. It also has limit table to get restrictions of
+the image size.
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi | 23 +++++++++++++++++++++++
+ 1 file changed, 23 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index b3dee47..a18cba6 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -131,6 +131,29 @@
+               status = "disabled";
+       };
++      rotator: rotator@12810000 {
++              compatible = "samsung,exynos4210-rotator";
++              reg = <0x12810000 0x1000>;
++              interrupts = <0 83 0>;
++              clocks = <&clock 278>;
++              clock-names = "rotator";
++              status = "disabled";
++              ycbcr420_2p {
++                      min_w = <32>;
++                      min_h = <32>;
++                      max_w = <32768>;
++                      max_h = <32768>;
++                      align = <3>;
++              };
++              rgb888 {
++                      min_w = <8>;
++                      min_h = <8>;
++                      max_w = <8192>;
++                      max_h = <8192>;
++                      align = <2>;
++              };
++      };
++
+       camera {
+               compatible = "samsung,fimc", "simple-bus";
+               status = "disabled";
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0246-ARM-dts-enable-rotator-node-for-redwood.patch b/patches.tizen/0246-ARM-dts-enable-rotator-node-for-redwood.patch
new file mode 100644 (file)
index 0000000..026897a
--- /dev/null
@@ -0,0 +1,29 @@
+From aa5c9aaec82a37aaf6942262ad9e1fb20038925e Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Fri, 31 May 2013 18:59:03 +0900
+Subject: [PATCH 0246/1302] ARM: dts: enable rotator node for redwood
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-redwood.dts | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-redwood.dts b/arch/arm/boot/dts/exynos4412-redwood.dts
+index 6ceeb8d..63efffa 100644
+--- a/arch/arm/boot/dts/exynos4412-redwood.dts
++++ b/arch/arm/boot/dts/exynos4412-redwood.dts
+@@ -599,6 +599,10 @@
+               };
+       };
++      rotator: rotator@12810000 {
++              status = "okay";
++      };
++
+       camera {
+               status = "okay";
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0247-drm-exynos-add-dt-binding-documentation-for-rotator.patch b/patches.tizen/0247-drm-exynos-add-dt-binding-documentation-for-rotator.patch
new file mode 100644 (file)
index 0000000..5f3fef5
--- /dev/null
@@ -0,0 +1,57 @@
+From e13ddaaa3921ac43888f26fae91ca88740750f4e Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Fri, 31 May 2013 19:47:57 +0900
+Subject: [PATCH 0247/1302] drm/exynos: add dt-binding documentation for
+ rotator
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../bindings/drm/exynos/samsung-rotator.txt        | 35 ++++++++++++++++++++++
+ 1 file changed, 35 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/drm/exynos/samsung-rotator.txt
+
+diff --git a/Documentation/devicetree/bindings/drm/exynos/samsung-rotator.txt b/Documentation/devicetree/bindings/drm/exynos/samsung-rotator.txt
+new file mode 100644
+index 0000000..6b1d704
+--- /dev/null
++++ b/Documentation/devicetree/bindings/drm/exynos/samsung-rotator.txt
+@@ -0,0 +1,35 @@
++* Samsung Image Rotator
++
++Required properties:
++  - compatible : value should be the "samsung,exynos4210".
++  - reg : Physical base address of the IP registers and length of memory
++        mapped region.
++  - interrupts : interrupt number to the CPU.
++  - clocks : clock number of exynos4 rotator clock.
++  - clocks : clock name of rotator
++  - status : "okay" or "disabled"
++  - limit table for image formats : min_w/min_h/max_w/max_h for min/max of image
++
++Example:
++      rotator: rotator@12810000 {
++              compatible = "samsung,exynos4210-rotator";
++              reg = <0x12810000 0x1000>;
++              interrupts = <0 83 0>;
++              clocks = <&clock 278>;
++              clock-names = "rotator";
++              status = "disabled";
++              ycbcr420_2p {
++                      min_w = <32>;
++                      min_h = <32>;
++                      max_w = <32768>;
++                      max_h = <32768>;
++                      align = <3>;
++              };
++              rgb888 {
++                      min_w = <8>;
++                      min_h = <8>;
++                      max_w = <8192>;
++                      max_h = <8192>;
++                      align = <2>;
++              };
++      };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0248-drm-exynos-add-g2d-compatible-node-for-exynos4212.patch b/patches.tizen/0248-drm-exynos-add-g2d-compatible-node-for-exynos4212.patch
new file mode 100644 (file)
index 0000000..a954141
--- /dev/null
@@ -0,0 +1,28 @@
+From 82f6fe7d4fc48db171e42925bae6f90e8cd05665 Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Fri, 31 May 2013 20:37:02 +0900
+Subject: [PATCH 0248/1302] drm/exynos: add g2d compatible node for exynos4212
+
+This patch adds a g2d node compatible with exynos4212.
+
+Signe-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_g2d.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+index af75434..7a6e310 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+@@ -1522,6 +1522,7 @@ static SIMPLE_DEV_PM_OPS(g2d_pm_ops, g2d_suspend, g2d_resume);
+ #ifdef CONFIG_OF
+ static const struct of_device_id exynos_g2d_match[] = {
++      { .compatible = "samsung,exynos4212-g2d" },
+       { .compatible = "samsung,exynos5250-g2d" },
+       {},
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0249-ARM-dts-Add-g2d-clock-properties.patch b/patches.tizen/0249-ARM-dts-Add-g2d-clock-properties.patch
new file mode 100644 (file)
index 0000000..9dcd59d
--- /dev/null
@@ -0,0 +1,29 @@
+From 48cb1dc3d2e22813c27f34fed73b554721fb4e7a Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Fri, 31 May 2013 20:39:07 +0900
+Subject: [PATCH 0249/1302] ARM: dts: Add g2d clock properties
+
+This patch adds g2d's clock properties.
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12.dtsi | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index caaff80..30da6ca 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -102,6 +102,8 @@
+               compatible = "samsung,exynos4212-g2d";
+               reg = <0x10800000 0x1000>;
+               interrupts = <0 89 0>;
++              clocks = <&clock 277>;
++              clock-names = "fimg2d";
+               status = "disabled";
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0250-ARM-dts-enable-g2d-device-for-redwood.patch b/patches.tizen/0250-ARM-dts-enable-g2d-device-for-redwood.patch
new file mode 100644 (file)
index 0000000..58c9fc9
--- /dev/null
@@ -0,0 +1,29 @@
+From 50cf3b10145b836ae94a9a7c1362b1695dbc5eb8 Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Fri, 31 May 2013 20:39:25 +0900
+Subject: [PATCH 0250/1302] ARM: dts: enable g2d device for redwood
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-redwood.dts | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-redwood.dts b/arch/arm/boot/dts/exynos4412-redwood.dts
+index 63efffa..3712c14 100644
+--- a/arch/arm/boot/dts/exynos4412-redwood.dts
++++ b/arch/arm/boot/dts/exynos4412-redwood.dts
+@@ -599,6 +599,10 @@
+               };
+       };
++      g2d@10800000 {
++              status = "okay";
++      };
++
+       rotator: rotator@12810000 {
+               status = "okay";
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0251-ARM-dts-usbphy-add-SYSREG-reg-info-for-exynos4x12.patch b/patches.tizen/0251-ARM-dts-usbphy-add-SYSREG-reg-info-for-exynos4x12.patch
new file mode 100644 (file)
index 0000000..9bceeff
--- /dev/null
@@ -0,0 +1,28 @@
+From 1969de1ca1f2d134f527043777ac06d77808af23 Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Mon, 10 Jun 2013 13:58:29 +0900
+Subject: [PATCH 0251/1302] ARM: dts: usbphy: add SYSREG reg info for
+ exynos4x12
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index 30da6ca..be4adc2 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -194,7 +194,7 @@
+               status = "disabled";
+               usbphy-sys {
+-                      reg = <0x10020704 0x8>;
++                      reg = <0x10020704 0x8>, <0x1001021C 0x4>;
+               };
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0252-ARM-configs-Update-tizen_defconfig.patch b/patches.tizen/0252-ARM-configs-Update-tizen_defconfig.patch
new file mode 100644 (file)
index 0000000..39b2190
--- /dev/null
@@ -0,0 +1,1440 @@
+From 76bb08a27e4ad4688389415a369746414ca000a5 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Mon, 10 Jun 2013 19:07:43 +0200
+Subject: [PATCH 0252/1302] ARM: configs: Update tizen_defconfig
+
+This patch updates tizen_defconfig to:
+
+ - enable suspend/resume.
+ - enable support for IIO devices,
+ - enable LSM330DLC accelerometer and gyroscope sensor drivers,
+ - enable legacy AK8975 magnetometer and LPS331 sensor drivers,
+ - enable AK8975 sensor IIO driver, MAX77693 charger, FIMC-IS,
+ - add extra gpios for wm8994 GPIO driver (this allows to register
+   successfully the wm8994 GPIO chip),
+ - enable MALI UMP.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_defconfig | 537 +++++++++++++++++++++++++++++----------
+ 1 file changed, 409 insertions(+), 128 deletions(-)
+
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index ffc5b79..8b4dc03 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -1,6 +1,6 @@
+ #
+ # Automatically generated file; DO NOT EDIT.
+-# Linux/arm 3.8.0 Kernel Configuration
++# Linux/arm 3.10.0-rc5 Kernel Configuration
+ #
+ CONFIG_ARM=y
+ CONFIG_ARM_HAS_SG_CHAIN=y
+@@ -8,7 +8,6 @@ CONFIG_NEED_SG_DMA_LENGTH=y
+ CONFIG_ARM_DMA_USE_IOMMU=y
+ CONFIG_ARM_DMA_IOMMU_ALIGNMENT=8
+ CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+-CONFIG_GENERIC_GPIO=y
+ CONFIG_HAVE_PROC_CPU=y
+ CONFIG_NO_IOPORT=y
+ CONFIG_STACKTRACE_SUPPORT=y
+@@ -25,14 +24,12 @@ CONFIG_NEED_MACH_GPIO_H=y
+ CONFIG_NEED_MACH_MEMORY_H=y
+ CONFIG_GENERIC_BUG=y
+ CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+-CONFIG_HAVE_IRQ_WORK=y
+ CONFIG_IRQ_WORK=y
+ CONFIG_BUILDTIME_EXTABLE_SORT=y
+ #
+ # General setup
+ #
+-CONFIG_EXPERIMENTAL=y
+ CONFIG_INIT_ENV_ARG_LIMIT=32
+ CONFIG_CROSS_COMPILE=""
+ CONFIG_LOCALVERSION=""
+@@ -68,12 +65,16 @@ CONFIG_IRQ_DOMAIN=y
+ CONFIG_KTIME_SCALAR=y
+ CONFIG_GENERIC_CLOCKEVENTS=y
+ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++CONFIG_ARCH_HAS_TICK_BROADCAST=y
+ CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+ #
+ # Timers subsystem
+ #
+ CONFIG_TICK_ONESHOT=y
++CONFIG_NO_HZ_COMMON=y
++# CONFIG_HZ_PERIODIC is not set
++CONFIG_NO_HZ_IDLE=y
+ CONFIG_NO_HZ=y
+ CONFIG_HIGH_RES_TIMERS=y
+@@ -81,6 +82,7 @@ CONFIG_HIGH_RES_TIMERS=y
+ # CPU/Task time and stats accounting
+ #
+ CONFIG_TICK_CPU_ACCOUNTING=y
++# CONFIG_IRQ_TIME_ACCOUNTING is not set
+ # CONFIG_BSD_PROCESS_ACCT is not set
+ # CONFIG_TASKSTATS is not set
+@@ -89,6 +91,8 @@ CONFIG_TICK_CPU_ACCOUNTING=y
+ #
+ CONFIG_TREE_PREEMPT_RCU=y
+ CONFIG_PREEMPT_RCU=y
++CONFIG_RCU_STALL_COMMON=y
++# CONFIG_RCU_USER_QS is not set
+ CONFIG_RCU_FANOUT=32
+ CONFIG_RCU_FANOUT_LEAF=16
+ # CONFIG_RCU_FANOUT_EXACT is not set
+@@ -132,13 +136,13 @@ CONFIG_MM_OWNER=y
+ # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+ CONFIG_SYSCTL=y
+ CONFIG_ANON_INODES=y
+-CONFIG_EXPERT=y
+ CONFIG_HAVE_UID16=y
++CONFIG_HOTPLUG=y
++CONFIG_EXPERT=y
+ CONFIG_UID16=y
+ # CONFIG_SYSCTL_SYSCALL is not set
+ CONFIG_KALLSYMS=y
+ CONFIG_KALLSYMS_ALL=y
+-CONFIG_HOTPLUG=y
+ CONFIG_PRINTK=y
+ CONFIG_BUG=y
+ CONFIG_ELF_CORE=y
+@@ -171,6 +175,7 @@ CONFIG_OPROFILE=y
+ CONFIG_HAVE_OPROFILE=y
+ # CONFIG_KPROBES is not set
+ CONFIG_JUMP_LABEL=y
++# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
+ CONFIG_HAVE_KPROBES=y
+ CONFIG_HAVE_KRETPROBES=y
+ CONFIG_HAVE_ARCH_TRACEHOOK=y
+@@ -185,9 +190,12 @@ CONFIG_HAVE_HW_BREAKPOINT=y
+ CONFIG_HAVE_ARCH_JUMP_LABEL=y
+ CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+ CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
++CONFIG_HAVE_CONTEXT_TRACKING=y
+ CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+ CONFIG_MODULES_USE_ELF_REL=y
+ CONFIG_CLONE_BACKWARDS=y
++CONFIG_OLD_SIGSUSPEND3=y
++CONFIG_OLD_SIGACTION=y
+ #
+ # GCOV-based kernel profiling
+@@ -255,17 +263,12 @@ CONFIG_MMU=y
+ # CONFIG_ARCH_REALVIEW is not set
+ # CONFIG_ARCH_VERSATILE is not set
+ # CONFIG_ARCH_AT91 is not set
+-# CONFIG_ARCH_BCM2835 is not set
+-# CONFIG_ARCH_CNS3XXX is not set
+ # CONFIG_ARCH_CLPS711X is not set
+ # CONFIG_ARCH_GEMINI is not set
+-# CONFIG_ARCH_SIRF is not set
+ # CONFIG_ARCH_EBSA110 is not set
+ # CONFIG_ARCH_EP93XX is not set
+ # CONFIG_ARCH_FOOTBRIDGE is not set
+-# CONFIG_ARCH_MXS is not set
+ # CONFIG_ARCH_NETX is not set
+-# CONFIG_ARCH_H720X is not set
+ # CONFIG_ARCH_IOP13XX is not set
+ # CONFIG_ARCH_IOP32X is not set
+ # CONFIG_ARCH_IOP33X is not set
+@@ -278,7 +281,6 @@ CONFIG_MMU=y
+ # CONFIG_ARCH_KS8695 is not set
+ # CONFIG_ARCH_W90X900 is not set
+ # CONFIG_ARCH_LPC32XX is not set
+-# CONFIG_ARCH_TEGRA is not set
+ # CONFIG_ARCH_PXA is not set
+ # CONFIG_ARCH_MSM is not set
+ # CONFIG_ARCH_SHMOBILE is not set
+@@ -292,12 +294,8 @@ CONFIG_MMU=y
+ CONFIG_ARCH_EXYNOS=y
+ # CONFIG_ARCH_SHARK is not set
+ # CONFIG_ARCH_U300 is not set
+-# CONFIG_ARCH_U8500 is not set
+-# CONFIG_ARCH_NOMADIK is not set
+-# CONFIG_PLAT_SPEAR is not set
+ # CONFIG_ARCH_DAVINCI is not set
+-# CONFIG_ARCH_OMAP is not set
+-# CONFIG_ARCH_VT8500_SINGLE is not set
++# CONFIG_ARCH_OMAP1 is not set
+ # CONFIG_GPIO_PCA953X is not set
+ # CONFIG_KEYBOARD_GPIO_POLLED is not set
+ CONFIG_PLAT_SAMSUNG=y
+@@ -306,19 +304,19 @@ CONFIG_PLAT_S5P=y
+ #
+ # Boot options
+ #
+-# CONFIG_S3C_BOOT_WATCHDOG is not set
+ # CONFIG_S3C_BOOT_ERROR_RESET is not set
+ CONFIG_S3C_BOOT_UART_FORCE_FIFO=y
+ CONFIG_S3C_LOWLEVEL_UART_PORT=2
+ # CONFIG_S5P_CLOCK is not set
+ CONFIG_SAMSUNG_IRQ_VIC_TIMER=y
+-CONFIG_S5P_IRQ=y
++# CONFIG_S5P_IRQ is not set
+ CONFIG_SAMSUNG_GPIOLIB_4BIT=y
+ CONFIG_S5P_GPIO_DRVSTR=y
+-CONFIG_SAMSUNG_GPIO_EXTRA=0
++CONFIG_SAMSUNG_GPIO_EXTRA=11
+ CONFIG_S3C_GPIO_SPACE=0
+ CONFIG_S3C_GPIO_TRACK=y
+ CONFIG_S3C_ADC=y
++CONFIG_S5P_DEV_MFC=y
+ CONFIG_S3C24XX_PWM=y
+ CONFIG_S5P_SETUP_MIPIPHY=y
+ CONFIG_SAMSUNG_DMADEV=y
+@@ -331,6 +329,7 @@ CONFIG_SAMSUNG_DMADEV=y
+ CONFIG_S5P_PM=y
+ CONFIG_S5P_SLEEP=y
+ CONFIG_DEBUG_S3C_UART=2
++# CONFIG_PLAT_SPEAR is not set
+ #
+ # SAMSUNG EXYNOS SoCs Support
+@@ -344,8 +343,7 @@ CONFIG_ARCH_EXYNOS4=y
+ CONFIG_CPU_EXYNOS4210=y
+ CONFIG_SOC_EXYNOS4212=y
+ CONFIG_SOC_EXYNOS4412=y
+-CONFIG_EXYNOS4_MCT=y
+-CONFIG_EXYNOS4_SETUP_USB_PHY=y
++CONFIG_EXYNOS_ATAGS=y
+ CONFIG_SEC_DEBUG=y
+ #
+@@ -378,7 +376,6 @@ CONFIG_MACH_EXYNOS4_DT=y
+ #
+ # CONFIG_EXYNOS4_SDHCI_CH0_8BIT is not set
+ # CONFIG_EXYNOS4_SDHCI_CH2_8BIT is not set
+-# CONFIG_ARCH_VT8500 is not set
+ #
+ # Processor Type
+@@ -403,7 +400,7 @@ CONFIG_CPU_CP15_MMU=y
+ # CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+ CONFIG_ARM_THUMB=y
+ # CONFIG_ARM_THUMBEE is not set
+-# CONFIG_ARM_VIRT_EXT is not set
++CONFIG_ARM_VIRT_EXT=y
+ CONFIG_SWP_EMULATE=y
+ # CONFIG_CPU_ICACHE_DISABLE is not set
+ # CONFIG_CPU_DCACHE_DISABLE is not set
+@@ -434,8 +431,7 @@ CONFIG_ARM_ERRATA_754322=y
+ CONFIG_ARM_ERRATA_764369=y
+ # CONFIG_PL310_ERRATA_769419 is not set
+ # CONFIG_ARM_ERRATA_775420 is not set
+-CONFIG_ARM_GIC=y
+-CONFIG_GIC_NON_BANKED=y
++# CONFIG_ARM_ERRATA_798181 is not set
+ #
+ # Bus support
+@@ -454,13 +450,15 @@ CONFIG_ARM_CPU_TOPOLOGY=y
+ CONFIG_SCHED_MC=y
+ # CONFIG_SCHED_SMT is not set
+ CONFIG_HAVE_ARM_SCU=y
+-CONFIG_ARM_ARCH_TIMER=y
++# CONFIG_HAVE_ARM_ARCH_TIMER is not set
++# CONFIG_MCPM is not set
+ CONFIG_VMSPLIT_3G=y
+ # CONFIG_VMSPLIT_2G is not set
+ # CONFIG_VMSPLIT_1G is not set
+ CONFIG_PAGE_OFFSET=0xC0000000
+ CONFIG_NR_CPUS=4
+ CONFIG_HOTPLUG_CPU=y
++# CONFIG_ARM_PSCI is not set
+ CONFIG_LOCAL_TIMERS=y
+ CONFIG_ARCH_NR_GPIO=0
+ # CONFIG_PREEMPT_NONE is not set
+@@ -468,6 +466,7 @@ CONFIG_ARCH_NR_GPIO=0
+ CONFIG_PREEMPT=y
+ CONFIG_PREEMPT_COUNT=y
+ CONFIG_HZ=200
++CONFIG_SCHED_HRTICK=y
+ # CONFIG_THUMB2_KERNEL is not set
+ CONFIG_AEABI=y
+ CONFIG_OABI_COMPAT=y
+@@ -486,13 +485,13 @@ CONFIG_HAVE_MEMORY_PRESENT=y
+ CONFIG_SPARSEMEM_EXTREME=y
+ CONFIG_HAVE_MEMBLOCK=y
+ CONFIG_MEMORY_ISOLATION=y
++# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+ CONFIG_SPLIT_PTLOCK_CPUS=4
+ CONFIG_COMPACTION=y
+ CONFIG_MIGRATION=y
+ # CONFIG_PHYS_ADDR_T_64BIT is not set
+ CONFIG_ZONE_DMA_FLAG=0
+ CONFIG_BOUNCE=y
+-CONFIG_VIRT_TO_BUS=y
+ # CONFIG_KSM is not set
+ CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+ CONFIG_CROSS_MEMORY_ATTACH=y
+@@ -553,6 +552,7 @@ CONFIG_ARM_EXYNOS_CPUFREQ=y
+ CONFIG_ARM_EXYNOS4210_CPUFREQ=y
+ CONFIG_ARM_EXYNOS4X12_CPUFREQ=y
+ # CONFIG_ARM_EXYNOS5250_CPUFREQ is not set
++# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set
+ CONFIG_CPU_IDLE=y
+ # CONFIG_CPU_IDLE_MULTIPLE_DRIVERS is not set
+ CONFIG_CPU_IDLE_GOV_LADDER=y
+@@ -578,6 +578,7 @@ CONFIG_NEON=y
+ CONFIG_BINFMT_ELF=y
+ CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+ CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
++CONFIG_BINFMT_SCRIPT=y
+ CONFIG_HAVE_AOUT=y
+ # CONFIG_BINFMT_AOUT is not set
+ # CONFIG_BINFMT_MISC is not set
+@@ -586,13 +587,22 @@ CONFIG_COREDUMP=y
+ #
+ # Power management options
+ #
+-# CONFIG_SUSPEND is not set
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++CONFIG_PM_SLEEP=y
++CONFIG_PM_SLEEP_SMP=y
++# CONFIG_PM_AUTOSLEEP is not set
++# CONFIG_PM_WAKELOCKS is not set
+ CONFIG_PM_RUNTIME=y
+ CONFIG_PM=y
+-# CONFIG_PM_DEBUG is not set
++CONFIG_PM_DEBUG=y
++CONFIG_PM_ADVANCED_DEBUG=y
++# CONFIG_PM_TEST_SUSPEND is not set
++CONFIG_PM_SLEEP_DEBUG=y
+ # CONFIG_APM_EMULATION is not set
+ CONFIG_PM_CLK=y
+ CONFIG_PM_GENERIC_DOMAINS=y
++CONFIG_PM_GENERIC_DOMAINS_SLEEP=y
+ CONFIG_PM_GENERIC_DOMAINS_RUNTIME=y
+ CONFIG_CPU_PM=y
+ CONFIG_ARCH_SUSPEND_POSSIBLE=y
+@@ -625,6 +635,7 @@ CONFIG_IP_MULTIPLE_TABLES=y
+ # CONFIG_IP_PNP is not set
+ # CONFIG_NET_IPIP is not set
+ # CONFIG_NET_IPGRE_DEMUX is not set
++CONFIG_NET_IP_TUNNEL=y
+ # CONFIG_IP_MROUTE is not set
+ # CONFIG_ARPD is not set
+ # CONFIG_SYN_COOKIES is not set
+@@ -755,9 +766,11 @@ CONFIG_NETFILTER_XT_TARGET_TRACE=y
+ # Xtables matches
+ #
+ # CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set
++# CONFIG_NETFILTER_XT_MATCH_BPF is not set
+ # CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
+ CONFIG_NETFILTER_XT_MATCH_COMMENT=y
+ CONFIG_NETFILTER_XT_MATCH_CONNBYTES=y
++# CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set
+ CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+ CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+ CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+@@ -802,7 +815,6 @@ CONFIG_NETFILTER_XT_MATCH_U32=y
+ CONFIG_NF_DEFRAG_IPV4=y
+ CONFIG_NF_CONNTRACK_IPV4=y
+ CONFIG_NF_CONNTRACK_PROC_COMPAT=y
+-# CONFIG_IP_NF_QUEUE is not set
+ CONFIG_IP_NF_IPTABLES=y
+ CONFIG_IP_NF_MATCH_AH=y
+ CONFIG_IP_NF_MATCH_ECN=y
+@@ -867,7 +879,6 @@ CONFIG_HAVE_NET_DSA=y
+ # CONFIG_ATALK is not set
+ # CONFIG_X25 is not set
+ # CONFIG_LAPB is not set
+-# CONFIG_WAN_ROUTER is not set
+ CONFIG_PHONET=y
+ # CONFIG_IEEE802154 is not set
+ CONFIG_NET_SCHED=y
+@@ -935,6 +946,9 @@ CONFIG_NET_SCH_FIFO=y
+ # CONFIG_DCB is not set
+ # CONFIG_BATMAN_ADV is not set
+ # CONFIG_OPENVSWITCH is not set
++# CONFIG_VSOCKETS is not set
++# CONFIG_NETLINK_MMAP is not set
++# CONFIG_NETLINK_DIAG is not set
+ CONFIG_RPS=y
+ CONFIG_RFS_ACCEL=y
+ CONFIG_XPS=y
+@@ -1017,6 +1031,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ CONFIG_FW_LOADER=y
+ CONFIG_FIRMWARE_IN_KERNEL=y
+ CONFIG_EXTRA_FIRMWARE=""
++CONFIG_FW_LOADER_USER_HELPER=y
+ # CONFIG_DEBUG_DRIVER is not set
+ # CONFIG_DEBUG_DEVRES is not set
+ # CONFIG_SYS_HYPERVISOR is not set
+@@ -1085,7 +1100,9 @@ CONFIG_BLK_DEV_RAM_SIZE=16384
+ # CONFIG_SENSORS_LIS3LV02D is not set
+ # CONFIG_AD525X_DPOT is not set
+ # CONFIG_ATMEL_PWM is not set
++# CONFIG_DUMMY_IRQ is not set
+ # CONFIG_ICS932S401 is not set
++# CONFIG_ATMEL_SSC is not set
+ # CONFIG_ENCLOSURE_SERVICES is not set
+ # CONFIG_APDS9802ALS is not set
+ # CONFIG_ISL29003 is not set
+@@ -1100,7 +1117,9 @@ CONFIG_BLK_DEV_RAM_SIZE=16384
+ # CONFIG_BMP085_I2C is not set
+ # CONFIG_BMP085_SPI is not set
+ # CONFIG_USB_SWITCH_FSA9480 is not set
++# CONFIG_LATTICE_ECP3_CONFIG is not set
+ CONFIG_SLP_GLOBAL_LOCK=y
++# CONFIG_SRAM is not set
+ # CONFIG_C2PORT is not set
+ #
+@@ -1162,6 +1181,7 @@ CONFIG_CHR_DEV_SG=y
+ CONFIG_SCSI_LOWLEVEL=y
+ # CONFIG_ISCSI_TCP is not set
+ # CONFIG_ISCSI_BOOT_SYSFS is not set
++# CONFIG_SCSI_UFSHCD is not set
+ # CONFIG_LIBFC is not set
+ # CONFIG_LIBFCOE is not set
+ # CONFIG_SCSI_DEBUG is not set
+@@ -1170,11 +1190,13 @@ CONFIG_SCSI_LOWLEVEL=y
+ # CONFIG_ATA is not set
+ CONFIG_MD=y
+ # CONFIG_BLK_DEV_MD is not set
++# CONFIG_BCACHE is not set
+ CONFIG_BLK_DEV_DM=y
+ CONFIG_DM_DEBUG=y
+ CONFIG_DM_CRYPT=y
+ # CONFIG_DM_SNAPSHOT is not set
+ # CONFIG_DM_THIN_PROVISIONING is not set
++# CONFIG_DM_CACHE is not set
+ # CONFIG_DM_MIRROR is not set
+ # CONFIG_DM_RAID is not set
+ # CONFIG_DM_ZERO is not set
+@@ -1241,7 +1263,6 @@ CONFIG_NET_VENDOR_8390=y
+ # CONFIG_AX88796 is not set
+ # CONFIG_ETHOC is not set
+ CONFIG_NET_VENDOR_SEEQ=y
+-# CONFIG_SEEQ8005 is not set
+ CONFIG_NET_VENDOR_SMSC=y
+ # CONFIG_SMC91X is not set
+ # CONFIG_SMC911X is not set
+@@ -1289,8 +1310,10 @@ CONFIG_PHYLIB=y
+ # CONFIG_USB_KAWETH is not set
+ # CONFIG_USB_PEGASUS is not set
+ # CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_RTL8152 is not set
+ CONFIG_USB_USBNET=y
+ CONFIG_USB_NET_AX8817X=y
++CONFIG_USB_NET_AX88179_178A=y
+ CONFIG_USB_NET_CDCETHER=y
+ # CONFIG_USB_NET_CDC_EEM is not set
+ CONFIG_USB_NET_CDC_NCM=y
+@@ -1343,7 +1366,7 @@ CONFIG_INPUT=y
+ # CONFIG_INPUT_FF_MEMLESS is not set
+ # CONFIG_INPUT_POLLDEV is not set
+ # CONFIG_INPUT_SPARSEKMAP is not set
+-# CONFIG_INPUT_MATRIXKMAP is not set
++CONFIG_INPUT_MATRIXKMAP=y
+ #
+ # Userland interfaces
+@@ -1377,7 +1400,7 @@ CONFIG_KEYBOARD_GPIO=y
+ # CONFIG_KEYBOARD_MPR121 is not set
+ # CONFIG_KEYBOARD_NEWTON is not set
+ # CONFIG_KEYBOARD_OPENCORES is not set
+-# CONFIG_KEYBOARD_SAMSUNG is not set
++CONFIG_KEYBOARD_SAMSUNG=y
+ # CONFIG_KEYBOARD_STOWAWAY is not set
+ # CONFIG_KEYBOARD_SUNKBD is not set
+ # CONFIG_KEYBOARD_XTKBD is not set
+@@ -1435,14 +1458,17 @@ CONFIG_SERIO_SERPORT=y
+ # CONFIG_SERIO_ALTERA_PS2 is not set
+ # CONFIG_SERIO_PS2MULT is not set
+ # CONFIG_SERIO_ARC_PS2 is not set
++# CONFIG_SERIO_APBPS2 is not set
+ # CONFIG_GAMEPORT is not set
+ #
+ # Character devices
+ #
++CONFIG_TTY=y
+ CONFIG_VT=y
+ CONFIG_CONSOLE_TRANSLATIONS=y
+ CONFIG_VT_CONSOLE=y
++CONFIG_VT_CONSOLE_SLEEP=y
+ CONFIG_HW_CONSOLE=y
+ CONFIG_VT_HW_CONSOLE_BINDING=y
+ CONFIG_UNIX98_PTYS=y
+@@ -1457,7 +1483,9 @@ CONFIG_DEVKMEM=y
+ # Serial drivers
+ #
+ CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
+ # CONFIG_SERIAL_8250_CONSOLE is not set
++CONFIG_SERIAL_8250_DMA=y
+ CONFIG_SERIAL_8250_NR_UARTS=4
+ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+ # CONFIG_SERIAL_8250_EXTENDED is not set
+@@ -1548,6 +1576,7 @@ CONFIG_SPI_MASTER=y
+ # CONFIG_SPI_ALTERA is not set
+ CONFIG_SPI_BITBANG=y
+ CONFIG_SPI_GPIO=y
++# CONFIG_SPI_FSL_SPI is not set
+ # CONFIG_SPI_OC_TINY is not set
+ # CONFIG_SPI_PL022 is not set
+ # CONFIG_SPI_PXA2XX_PCI is not set
+@@ -1562,6 +1591,11 @@ CONFIG_SPI_S3C64XX=y
+ #
+ # CONFIG_SPI_SPIDEV is not set
+ # CONFIG_SPI_TLE62X0 is not set
++
++#
++# Qualcomm MSM SSBI bus support
++#
++# CONFIG_SSBI is not set
+ # CONFIG_HSI is not set
+ #
+@@ -1596,6 +1630,7 @@ CONFIG_PINCTRL_EXYNOS=y
+ # CONFIG_PINCTRL_EXYNOS5440 is not set
+ CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
+ CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIO_DEVRES=y
+ CONFIG_GPIOLIB=y
+ CONFIG_OF_GPIO=y
+ # CONFIG_DEBUG_GPIO is not set
+@@ -1607,7 +1642,9 @@ CONFIG_GPIO_SYSFS=y
+ # CONFIG_GPIO_GENERIC_PLATFORM is not set
+ # CONFIG_GPIO_EM is not set
+ # CONFIG_GPIO_PL061 is not set
++# CONFIG_GPIO_RCAR is not set
+ # CONFIG_GPIO_TS5500 is not set
++# CONFIG_GPIO_GRGPIO is not set
+ #
+ # I2C GPIO expanders:
+@@ -1647,6 +1684,7 @@ CONFIG_GPIO_WM8994=y
+ CONFIG_POWER_SUPPLY=y
+ # CONFIG_POWER_SUPPLY_DEBUG is not set
+ # CONFIG_PDA_POWER is not set
++# CONFIG_GENERIC_ADC_BATTERY is not set
+ # CONFIG_TEST_POWER is not set
+ # CONFIG_BATTERY_DS2780 is not set
+ # CONFIG_BATTERY_DS2781 is not set
+@@ -1656,15 +1694,18 @@ CONFIG_POWER_SUPPLY=y
+ CONFIG_BATTERY_MAX17040=y
+ CONFIG_BATTERY_MAX17042=y
+ # CONFIG_BATTERY_S3C_ADC is not set
+-# CONFIG_CHARGER_ISP1704 is not set
+ # CONFIG_CHARGER_MAX8903 is not set
+ # CONFIG_CHARGER_LP8727 is not set
+ # CONFIG_CHARGER_GPIO is not set
+ # CONFIG_CHARGER_MANAGER is not set
+ CONFIG_CHARGER_MAX8997=y
++CONFIG_CHARGER_MAX77693=y
+ # CONFIG_CHARGER_BQ2415X is not set
+ # CONFIG_CHARGER_SMB347 is not set
++# CONFIG_CHARGER_TPS65090 is not set
++# CONFIG_BATTERY_GOLDFISH is not set
+ # CONFIG_POWER_RESET is not set
++# CONFIG_POWER_RESET_RESTART is not set
+ # CONFIG_POWER_AVS is not set
+ # CONFIG_HWMON is not set
+ # CONFIG_THERMAL is not set
+@@ -1703,47 +1744,64 @@ CONFIG_BCMA_POSSIBLE=y
+ # Multifunction device drivers
+ #
+ CONFIG_MFD_CORE=y
+-# CONFIG_MFD_88PM860X is not set
+-# CONFIG_MFD_88PM800 is not set
+-# CONFIG_MFD_88PM805 is not set
+-# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_AS3711 is not set
++# CONFIG_PMIC_ADP5520 is not set
++# CONFIG_MFD_AAT2870_CORE is not set
++# CONFIG_MFD_CROS_EC is not set
+ # CONFIG_MFD_ASIC3 is not set
+-# CONFIG_MFD_TI_AM335X_TSCADC is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_DA9052_SPI is not set
++# CONFIG_MFD_DA9052_I2C is not set
++# CONFIG_MFD_DA9055 is not set
++# CONFIG_MFD_MC13XXX_SPI is not set
++# CONFIG_MFD_MC13XXX_I2C is not set
+ # CONFIG_HTC_EGPIO is not set
+ # CONFIG_HTC_PASIC3 is not set
+ # CONFIG_HTC_I2CPLD is not set
+-# CONFIG_MFD_LM3533 is not set
++# CONFIG_MFD_88PM800 is not set
++# CONFIG_MFD_88PM805 is not set
++# CONFIG_MFD_88PM860X is not set
++CONFIG_MFD_MAX77686=y
++CONFIG_MFD_MAX77693=y
++# CONFIG_MFD_MAX8907 is not set
++# CONFIG_MFD_MAX8925 is not set
++CONFIG_MFD_MAX8997=y
++# CONFIG_MFD_MAX8998 is not set
++# CONFIG_EZX_PCAP is not set
++# CONFIG_MFD_VIPERBOARD is not set
++# CONFIG_MFD_RETU is not set
++# CONFIG_MFD_PCF50633 is not set
++# CONFIG_MFD_RC5T583 is not set
++CONFIG_MFD_SEC_CORE=y
++# CONFIG_MFD_SI476X_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_SMSC is not set
++# CONFIG_ABX500_CORE is not set
++# CONFIG_MFD_STMPE is not set
++CONFIG_MFD_SYSCON=y
++# CONFIG_MFD_TI_AM335X_TSCADC is not set
++# CONFIG_MFD_LP8788 is not set
++# CONFIG_MFD_PALMAS is not set
+ # CONFIG_TPS6105X is not set
+ # CONFIG_TPS65010 is not set
+ # CONFIG_TPS6507X is not set
++CONFIG_MFD_TPS65090=y
+ # CONFIG_MFD_TPS65217 is not set
+ # CONFIG_MFD_TPS6586X is not set
+ # CONFIG_MFD_TPS65910 is not set
++# CONFIG_MFD_TPS65912 is not set
+ # CONFIG_MFD_TPS65912_I2C is not set
+ # CONFIG_MFD_TPS65912_SPI is not set
+ # CONFIG_MFD_TPS80031 is not set
+ # CONFIG_TWL4030_CORE is not set
+ # CONFIG_TWL6040_CORE is not set
+-# CONFIG_MFD_STMPE is not set
++# CONFIG_MFD_WL1273_CORE is not set
++# CONFIG_MFD_LM3533 is not set
+ # CONFIG_MFD_TC3589X is not set
+ # CONFIG_MFD_TMIO is not set
+ # CONFIG_MFD_T7L66XB is not set
+-# CONFIG_MFD_SMSC is not set
+ # CONFIG_MFD_TC6387XB is not set
+ # CONFIG_MFD_TC6393XB is not set
+-# CONFIG_PMIC_DA903X is not set
+-# CONFIG_MFD_DA9052_SPI is not set
+-# CONFIG_MFD_DA9052_I2C is not set
+-# CONFIG_MFD_DA9055 is not set
+-# CONFIG_PMIC_ADP5520 is not set
+-# CONFIG_MFD_LP8788 is not set
+-CONFIG_MFD_MAX77686=y
+-CONFIG_MFD_MAX77693=y
+-# CONFIG_MFD_MAX8907 is not set
+-# CONFIG_MFD_MAX8925 is not set
+-CONFIG_MFD_MAX8997=y
+-# CONFIG_MFD_MAX8998 is not set
+-CONFIG_MFD_SEC_CORE=y
+ # CONFIG_MFD_ARIZONA_I2C is not set
+ # CONFIG_MFD_ARIZONA_SPI is not set
+ # CONFIG_MFD_WM8400 is not set
+@@ -1751,20 +1809,6 @@ CONFIG_MFD_SEC_CORE=y
+ # CONFIG_MFD_WM831X_SPI is not set
+ # CONFIG_MFD_WM8350_I2C is not set
+ CONFIG_MFD_WM8994=y
+-# CONFIG_MFD_PCF50633 is not set
+-# CONFIG_MFD_MC13XXX_SPI is not set
+-# CONFIG_MFD_MC13XXX_I2C is not set
+-# CONFIG_ABX500_CORE is not set
+-# CONFIG_EZX_PCAP is not set
+-# CONFIG_MFD_WL1273_CORE is not set
+-CONFIG_MFD_TPS65090=y
+-# CONFIG_MFD_AAT2870_CORE is not set
+-# CONFIG_MFD_RC5T583 is not set
+-CONFIG_MFD_SYSCON=y
+-# CONFIG_MFD_PALMAS is not set
+-# CONFIG_MFD_VIPERBOARD is not set
+-# CONFIG_MFD_RETU is not set
+-# CONFIG_MFD_AS3711 is not set
+ CONFIG_REGULATOR=y
+ # CONFIG_REGULATOR_DEBUG is not set
+ # CONFIG_REGULATOR_DUMMY is not set
+@@ -1787,6 +1831,7 @@ CONFIG_REGULATOR_MAX77693=y
+ # CONFIG_REGULATOR_LP3971 is not set
+ # CONFIG_REGULATOR_LP3972 is not set
+ # CONFIG_REGULATOR_LP872X is not set
++# CONFIG_REGULATOR_LP8755 is not set
+ # CONFIG_REGULATOR_S2MPS11 is not set
+ # CONFIG_REGULATOR_S5M8767 is not set
+ # CONFIG_REGULATOR_TPS51632 is not set
+@@ -1816,6 +1861,8 @@ CONFIG_V4L2_MEM2MEM_DEV=y
+ CONFIG_VIDEOBUF2_CORE=y
+ CONFIG_VIDEOBUF2_MEMOPS=y
+ CONFIG_VIDEOBUF2_DMA_CONTIG=y
++# CONFIG_VIDEO_V4L2_INT_DEVICE is not set
++# CONFIG_TTPCI_EEPROM is not set
+ #
+ # Media drivers
+@@ -1824,7 +1871,8 @@ CONFIG_VIDEOBUF2_DMA_CONTIG=y
+ CONFIG_V4L_PLATFORM_DRIVERS=y
+ # CONFIG_VIDEO_TIMBERDALE is not set
+ # CONFIG_SOC_CAMERA is not set
+-CONFIG_VIDEO_SAMSUNG_S5P_FIMC=y
++CONFIG_VIDEO_SAMSUNG_EXYNOS4_IS=y
++CONFIG_VIDEO_EXYNOS4_IS_COMMON=y
+ CONFIG_VIDEO_S5P_FIMC=y
+ CONFIG_VIDEO_S5P_MIPI_CSIS=y
+ CONFIG_VIDEO_EXYNOS_FIMC_LITE=y
+@@ -1835,16 +1883,18 @@ CONFIG_V4L_MEM2MEM_DRIVERS=y
+ # CONFIG_VIDEO_SAMSUNG_S5P_G2D is not set
+ # CONFIG_VIDEO_SAMSUNG_S5P_JPEG is not set
+ CONFIG_VIDEO_SAMSUNG_S5P_MFC=y
++# CONFIG_VIDEO_SH_VEU is not set
+ # CONFIG_V4L_TEST_DRIVERS is not set
+ #
+ # Supported MMC/SDIO adapters
+ #
+-# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
++# CONFIG_CYPRESS_FIRMWARE is not set
+ #
+ # Media ancillary drivers (tuners, sensors, i2c, frontends)
+ #
++# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
+ #
+ # Encoders, decoders, sensors and other helper chips
+@@ -1862,9 +1912,11 @@ CONFIG_VIDEO_SAMSUNG_S5P_MFC=y
+ # CONFIG_VIDEO_CS5345 is not set
+ # CONFIG_VIDEO_CS53L32A is not set
+ # CONFIG_VIDEO_TLV320AIC23B is not set
++# CONFIG_VIDEO_UDA1342 is not set
+ # CONFIG_VIDEO_WM8775 is not set
+ # CONFIG_VIDEO_WM8739 is not set
+ # CONFIG_VIDEO_VP27SMPX is not set
++# CONFIG_VIDEO_SONY_BTF_MPX is not set
+ #
+ # RDS decoders
+@@ -1887,6 +1939,9 @@ CONFIG_VIDEO_SAMSUNG_S5P_MFC=y
+ # CONFIG_VIDEO_TVP514X is not set
+ # CONFIG_VIDEO_TVP5150 is not set
+ # CONFIG_VIDEO_TVP7002 is not set
++# CONFIG_VIDEO_TW2804 is not set
++# CONFIG_VIDEO_TW9903 is not set
++# CONFIG_VIDEO_TW9906 is not set
+ # CONFIG_VIDEO_VPX3220 is not set
+ #
+@@ -1896,11 +1951,6 @@ CONFIG_VIDEO_SAMSUNG_S5P_MFC=y
+ # CONFIG_VIDEO_CX25840 is not set
+ #
+-# MPEG video encoders
+-#
+-# CONFIG_VIDEO_CX2341X is not set
+-
+-#
+ # Video encoders
+ #
+ # CONFIG_VIDEO_SAA7127 is not set
+@@ -1915,20 +1965,21 @@ CONFIG_VIDEO_SAMSUNG_S5P_MFC=y
+ #
+ # Camera sensor devices
+ #
++# CONFIG_VIDEO_OV7640 is not set
+ # CONFIG_VIDEO_OV7670 is not set
++# CONFIG_VIDEO_OV9650 is not set
+ # CONFIG_VIDEO_VS6624 is not set
+ # CONFIG_VIDEO_MT9M032 is not set
+ # CONFIG_VIDEO_MT9P031 is not set
+ # CONFIG_VIDEO_MT9T001 is not set
+ # CONFIG_VIDEO_MT9V011 is not set
+ # CONFIG_VIDEO_MT9V032 is not set
+-# CONFIG_VIDEO_TCM825X is not set
+ # CONFIG_VIDEO_SR030PC30 is not set
+ # CONFIG_VIDEO_NOON010PC30 is not set
+ CONFIG_VIDEO_M5MOLS=y
+ # CONFIG_VIDEO_S5K6AA is not set
+ # CONFIG_VIDEO_S5K4ECGX is not set
+-CONFIG_VIDEO_S5K5BAFX=y
++CONFIG_VIDEO_S5K5BAF=y
+ # CONFIG_VIDEO_SMIAPP is not set
+ CONFIG_VIDEO_S5C73M3=y
+@@ -1974,20 +2025,13 @@ CONFIG_DVB_TUNER_DIB0090=m
+ #
+ # ARM GPU Configuration
+ #
+-CONFIG_MALI_400MP_UMP=y
+-# CONFIG_MALI_DED_ONLY is not set
+-# CONFIG_MALI_DED_MMU is not set
+-CONFIG_MALI_OSMEM_ONLY=y
+-# CONFIG_MALI_DED_OSMEM is not set
+-# CONFIG_UMP_DED_ONLY is not set
+-CONFIG_UMP_OSMEM_ONLY=y
+-# CONFIG_UMP_VCM_ONLY is not set
+-CONFIG_UMP_MEM_SIZE=512
+-# CONFIG_MALI_UMP_R2P4 is not set
+-CONFIG_MALI_UMP_R3P0=y
+-# CONFIG_VIDEO_MALI400MP_UMP_DEBUG is not set
+-# CONFIG_VIDEO_MALI400MP_STREAMLINE_PROFILING is not set
+-CONFIG_VIDEO_MALI400MP_DVFS=y
++CONFIG_MALI400=y
++# CONFIG_MALI400_DEBUG is not set
++# CONFIG_MALI400_PROFILING is not set
++CONFIG_MALI400_UMP=y
++# CONFIG_UMP_DEBUG is not set
++# CONFIG_MALI_DVFS is not set
++# CONFIG_SLP_MALI_DBG is not set
+ CONFIG_DRM=y
+ CONFIG_DRM_KMS_HELPER=y
+ # CONFIG_DRM_LOAD_EDID_FIRMWARE is not set
+@@ -1997,6 +2041,7 @@ CONFIG_DRM_KMS_HELPER=y
+ #
+ # CONFIG_DRM_I2C_CH7006 is not set
+ # CONFIG_DRM_I2C_SIL164 is not set
++# CONFIG_DRM_I2C_NXP_TDA998X is not set
+ CONFIG_DRM_EXYNOS=y
+ # CONFIG_DRM_EXYNOS_IOMMU is not set
+ CONFIG_DRM_EXYNOS_DMABUF=y
+@@ -2008,12 +2053,11 @@ CONFIG_DRM_EXYNOS_IPP=y
+ CONFIG_DRM_EXYNOS_FIMC=y
+ CONFIG_DRM_EXYNOS_ROTATOR=y
+ # CONFIG_DRM_UDL is not set
++# CONFIG_DRM_TILCDC is not set
+ # CONFIG_VGASTATE is not set
+ # CONFIG_VIDEO_OUTPUT_CONTROL is not set
+-CONFIG_DISPLAY_TIMING=y
+-CONFIG_VIDEOMODE=y
+-CONFIG_OF_DISPLAY_TIMING=y
+-CONFIG_OF_VIDEOMODE=y
++CONFIG_VIDEOMODE_HELPERS=y
++CONFIG_HDMI=y
+ CONFIG_FB=y
+ # CONFIG_FIRMWARE_EDID is not set
+ # CONFIG_FB_DDC is not set
+@@ -2027,7 +2071,6 @@ CONFIG_FB_CFB_IMAGEBLIT=y
+ # CONFIG_FB_SYS_IMAGEBLIT is not set
+ # CONFIG_FB_FOREIGN_ENDIAN is not set
+ # CONFIG_FB_SYS_FOPS is not set
+-# CONFIG_FB_WMT_GE_ROPS is not set
+ # CONFIG_FB_SVGALIB is not set
+ # CONFIG_FB_MACMODES is not set
+ # CONFIG_FB_BACKLIGHT is not set
+@@ -2040,18 +2083,22 @@ CONFIG_FB_MODE_HELPERS=y
+ # CONFIG_FB_ARMCLCD is not set
+ # CONFIG_FB_S1D13XXX is not set
+ # CONFIG_FB_TMIO is not set
++# CONFIG_FB_S3C is not set
+ # CONFIG_FB_SMSCUFX is not set
+ # CONFIG_FB_UDL is not set
++# CONFIG_FB_GOLDFISH is not set
+ # CONFIG_FB_VIRTUAL is not set
+ # CONFIG_FB_METRONOME is not set
+ # CONFIG_FB_BROADSHEET is not set
+ # CONFIG_FB_AUO_K190X is not set
++# CONFIG_FB_SIMPLE is not set
+ # CONFIG_EXYNOS_VIDEO is not set
+ CONFIG_BACKLIGHT_LCD_SUPPORT=y
+ CONFIG_LCD_CLASS_DEVICE=y
+ # CONFIG_LCD_L4F00242T03 is not set
+ # CONFIG_LCD_LMS283GF05 is not set
+ # CONFIG_LCD_LTV350QV is not set
++# CONFIG_LCD_ILI922X is not set
+ # CONFIG_LCD_ILI9320 is not set
+ # CONFIG_LCD_TDO24M is not set
+ # CONFIG_LCD_VGG2432A4 is not set
+@@ -2059,6 +2106,8 @@ CONFIG_LCD_CLASS_DEVICE=y
+ # CONFIG_LCD_S6E63M0 is not set
+ # CONFIG_LCD_LD9040 is not set
+ # CONFIG_LCD_AMS369FG06 is not set
++# CONFIG_LCD_LMS501KF03 is not set
++# CONFIG_LCD_HX8357 is not set
+ CONFIG_BACKLIGHT_CLASS_DEVICE=y
+ CONFIG_BACKLIGHT_GENERIC=y
+ # CONFIG_BACKLIGHT_PWM is not set
+@@ -2070,7 +2119,6 @@ CONFIG_BACKLIGHT_GENERIC=y
+ CONFIG_DISPLAY_CORE=y
+ CONFIG_DISPLAY_PANEL_S6D6AA1=y
+ CONFIG_DISPLAY_PANEL_S6E8AA0=y
+-CONFIG_DISPLAY_PANEL_S6E8AX0=y
+ CONFIG_DISPLAY_SOURCE_EXYNOS_DSI=y
+ #
+@@ -2128,6 +2176,7 @@ CONFIG_SND_DEBUG=y
+ # CONFIG_SND_SPI is not set
+ # CONFIG_SND_USB is not set
+ CONFIG_SND_SOC=y
++# CONFIG_SND_ATMEL_SOC is not set
+ # CONFIG_SND_DESIGNWARE_I2S is not set
+ CONFIG_SND_SOC_SAMSUNG=y
+ CONFIG_SND_SAMSUNG_PCM=y
+@@ -2165,6 +2214,7 @@ CONFIG_HID_GENERIC=y
+ # CONFIG_HID_A4TECH is not set
+ # CONFIG_HID_ACRUX is not set
+ # CONFIG_HID_APPLE is not set
++# CONFIG_HID_APPLEIR is not set
+ # CONFIG_HID_AUREAL is not set
+ # CONFIG_HID_BELKIN is not set
+ # CONFIG_HID_CHERRY is not set
+@@ -2203,11 +2253,13 @@ CONFIG_HID_GENERIC=y
+ # CONFIG_HID_SAMSUNG is not set
+ # CONFIG_HID_SONY is not set
+ # CONFIG_HID_SPEEDLINK is not set
++# CONFIG_HID_STEELSERIES is not set
+ # CONFIG_HID_SUNPLUS is not set
+ # CONFIG_HID_GREENASIA is not set
+ # CONFIG_HID_SMARTJOYPLUS is not set
+ # CONFIG_HID_TIVO is not set
+ # CONFIG_HID_TOPSEED is not set
++# CONFIG_HID_THINGM is not set
+ # CONFIG_HID_THRUSTMASTER is not set
+ # CONFIG_HID_WACOM is not set
+ # CONFIG_HID_WIIMOTE is not set
+@@ -2239,11 +2291,11 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+ #
+ # Miscellaneous USB options
+ #
++CONFIG_USB_DEFAULT_PERSIST=y
+ # CONFIG_USB_DYNAMIC_MINORS is not set
+-# CONFIG_USB_SUSPEND is not set
++# CONFIG_USB_OTG is not set
+ # CONFIG_USB_OTG_WHITELIST is not set
+ # CONFIG_USB_OTG_BLACKLIST_HUB is not set
+-# CONFIG_USB_DWC3 is not set
+ # CONFIG_USB_MON is not set
+ # CONFIG_USB_WUSB_CBAF is not set
+@@ -2255,16 +2307,15 @@ CONFIG_USB_EHCI_HCD=y
+ # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+ CONFIG_USB_EHCI_TT_NEWSCHED=y
+ CONFIG_USB_EHCI_S5P=y
++# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+ # CONFIG_USB_OXU210HP_HCD is not set
+ # CONFIG_USB_ISP116X_HCD is not set
+ # CONFIG_USB_ISP1760_HCD is not set
+ # CONFIG_USB_ISP1362_HCD is not set
+ # CONFIG_USB_OHCI_HCD is not set
+-# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+ # CONFIG_USB_SL811_HCD is not set
+ # CONFIG_USB_R8A66597_HCD is not set
+ # CONFIG_USB_MUSB_HDRC is not set
+-# CONFIG_USB_CHIPIDEA is not set
+ # CONFIG_USB_RENESAS_USBHS is not set
+ #
+@@ -2289,6 +2340,8 @@ CONFIG_USB_EHCI_S5P=y
+ #
+ # CONFIG_USB_MDC800 is not set
+ # CONFIG_USB_MICROTEK is not set
++# CONFIG_USB_DWC3 is not set
++# CONFIG_USB_CHIPIDEA is not set
+ #
+ # USB port drivers
+@@ -2319,13 +2372,18 @@ CONFIG_USB_EHCI_S5P=y
+ # CONFIG_USB_ISIGHTFW is not set
+ # CONFIG_USB_YUREX is not set
+ # CONFIG_USB_EZUSB_FX2 is not set
+-
+-#
+-# USB Physical Layer drivers
+-#
++# CONFIG_USB_HSIC_USB3503 is not set
++CONFIG_USB_PHY=y
++# CONFIG_NOP_USB_XCEIV is not set
++# CONFIG_OMAP_CONTROL_USB is not set
++# CONFIG_OMAP_USB3 is not set
++CONFIG_SAMSUNG_USBPHY=y
++CONFIG_SAMSUNG_USB2PHY=y
++# CONFIG_SAMSUNG_USB3PHY is not set
++# CONFIG_USB_GPIO_VBUS is not set
+ # CONFIG_USB_ISP1301 is not set
+ # CONFIG_USB_RCAR_PHY is not set
+-CONFIG_SAMSUNG_USBPHY=y
++# CONFIG_USB_ULPI is not set
+ CONFIG_USB_GADGET=y
+ # CONFIG_USB_GADGET_DEBUG is not set
+ # CONFIG_USB_GADGET_DEBUG_FILES is not set
+@@ -2338,8 +2396,10 @@ CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
+ #
+ # CONFIG_USB_FUSB300 is not set
+ # CONFIG_USB_R8A66597 is not set
++# CONFIG_USB_PXA27X is not set
+ CONFIG_USB_S3C_HSOTG=y
+ # CONFIG_USB_MV_UDC is not set
++# CONFIG_USB_MV_U3D is not set
+ # CONFIG_USB_M66592 is not set
+ # CONFIG_USB_NET2272 is not set
+ # CONFIG_USB_DUMMY_HCD is not set
+@@ -2363,14 +2423,6 @@ CONFIG_USB_ETH_RNDIS=y
+ # CONFIG_USB_G_HID is not set
+ # CONFIG_USB_G_DBGP is not set
+ # CONFIG_USB_G_WEBCAM is not set
+-
+-#
+-# OTG and related infrastructure
+-#
+-CONFIG_USB_OTG_UTILS=y
+-# CONFIG_USB_GPIO_VBUS is not set
+-# CONFIG_USB_ULPI is not set
+-# CONFIG_NOP_USB_XCEIV is not set
+ CONFIG_MMC=y
+ # CONFIG_MMC_DEBUG is not set
+ # CONFIG_MMC_UNSAFE_RESUME is not set
+@@ -2415,9 +2467,11 @@ CONFIG_LEDS_GPIO=y
+ # CONFIG_LEDS_LP3944 is not set
+ # CONFIG_LEDS_LP5521 is not set
+ # CONFIG_LEDS_LP5523 is not set
++# CONFIG_LEDS_LP5562 is not set
+ # CONFIG_LEDS_PCA955X is not set
+ # CONFIG_LEDS_PCA9633 is not set
+ # CONFIG_LEDS_DAC124S085 is not set
++# CONFIG_LEDS_PWM is not set
+ # CONFIG_LEDS_REGULATOR is not set
+ # CONFIG_LEDS_BD2802 is not set
+ # CONFIG_LEDS_LT3593 is not set
+@@ -2427,11 +2481,11 @@ CONFIG_LEDS_GPIO=y
+ # CONFIG_LEDS_LM355x is not set
+ # CONFIG_LEDS_OT200 is not set
+ # CONFIG_LEDS_BLINKM is not set
+-CONFIG_LEDS_TRIGGERS=y
+ #
+ # LED Triggers
+ #
++CONFIG_LEDS_TRIGGERS=y
+ # CONFIG_LEDS_TRIGGER_TIMER is not set
+ CONFIG_LEDS_TRIGGER_ONESHOT=y
+ CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+@@ -2444,11 +2498,17 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+ # iptables trigger is under Netfilter config (LED target)
+ #
+ CONFIG_LEDS_TRIGGER_TRANSIENT=y
++# CONFIG_LEDS_TRIGGER_CAMERA is not set
++CONFIG_SENSORS_CORE=y
++CONFIG_SENSORS_AK8975_=y
++CONFIG_SENSORS_LSM330DLC=y
++CONFIG_SENSORS_LPS331=y
+ # CONFIG_ACCESSIBILITY is not set
+ # CONFIG_EDAC is not set
+ CONFIG_RTC_LIB=y
+ CONFIG_RTC_CLASS=y
+ CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_SYSTOHC=y
+ CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+ # CONFIG_RTC_DEBUG is not set
+@@ -2499,6 +2559,7 @@ CONFIG_RTC_INTF_DEV=y
+ # CONFIG_RTC_DRV_RS5C348 is not set
+ # CONFIG_RTC_DRV_DS3234 is not set
+ # CONFIG_RTC_DRV_PCF2123 is not set
++# CONFIG_RTC_DRV_RX4581 is not set
+ #
+ # Platform RTC drivers
+@@ -2526,6 +2587,11 @@ CONFIG_RTC_DRV_S3C=y
+ # CONFIG_RTC_DRV_PL030 is not set
+ # CONFIG_RTC_DRV_PL031 is not set
+ # CONFIG_RTC_DRV_SNVS is not set
++
++#
++# HID Sensor RTC drivers
++#
++# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
+ CONFIG_DMADEVICES=y
+ # CONFIG_DMADEVICES_DEBUG is not set
+@@ -2537,6 +2603,7 @@ CONFIG_DMADEVICES=y
+ # CONFIG_TIMB_DMA is not set
+ CONFIG_PL330_DMA=y
+ CONFIG_DMA_ENGINE=y
++CONFIG_DMA_OF=y
+ #
+ # DMA Clients
+@@ -2547,6 +2614,7 @@ CONFIG_DMA_ENGINE=y
+ # CONFIG_AUXDISPLAY is not set
+ # CONFIG_UIO is not set
+ # CONFIG_VFIO is not set
++# CONFIG_VIRT_DRIVERS is not set
+ #
+ # Virtio drivers
+@@ -2560,6 +2628,7 @@ CONFIG_STAGING=y
+ # CONFIG_USBIP_CORE is not set
+ # CONFIG_PRISM2_USB is not set
+ # CONFIG_ECHO is not set
++# CONFIG_COMEDI is not set
+ # CONFIG_ASUS_OLED is not set
+ # CONFIG_RTLLIB is not set
+ # CONFIG_R8712U is not set
+@@ -2567,6 +2636,101 @@ CONFIG_STAGING=y
+ # CONFIG_TRANZPORT is not set
+ # CONFIG_LINE6_USB is not set
+ # CONFIG_VT6656 is not set
++
++#
++# IIO staging drivers
++#
++
++#
++# Accelerometers
++#
++# CONFIG_ADIS16201 is not set
++# CONFIG_ADIS16203 is not set
++# CONFIG_ADIS16204 is not set
++# CONFIG_ADIS16209 is not set
++# CONFIG_ADIS16220 is not set
++# CONFIG_ADIS16240 is not set
++# CONFIG_LIS3L02DQ is not set
++
++#
++# Analog to digital converters
++#
++# CONFIG_AD7291 is not set
++# CONFIG_AD7606 is not set
++# CONFIG_AD799X is not set
++# CONFIG_AD7780 is not set
++# CONFIG_AD7816 is not set
++# CONFIG_AD7192 is not set
++# CONFIG_AD7280 is not set
++
++#
++# Analog digital bi-direction converters
++#
++# CONFIG_ADT7316 is not set
++
++#
++# Capacitance to digital converters
++#
++# CONFIG_AD7150 is not set
++# CONFIG_AD7152 is not set
++# CONFIG_AD7746 is not set
++
++#
++# Direct Digital Synthesis
++#
++# CONFIG_AD5930 is not set
++# CONFIG_AD9832 is not set
++# CONFIG_AD9834 is not set
++# CONFIG_AD9850 is not set
++# CONFIG_AD9852 is not set
++# CONFIG_AD9910 is not set
++# CONFIG_AD9951 is not set
++
++#
++# Digital gyroscope sensors
++#
++# CONFIG_ADIS16060 is not set
++# CONFIG_ADIS16130 is not set
++# CONFIG_ADIS16260 is not set
++
++#
++# Network Analyzer, Impedance Converters
++#
++# CONFIG_AD5933 is not set
++
++#
++# Light sensors
++#
++# CONFIG_SENSORS_ISL29018 is not set
++# CONFIG_SENSORS_ISL29028 is not set
++# CONFIG_TSL2583 is not set
++# CONFIG_TSL2x7x is not set
++
++#
++# Magnetometer sensors
++#
++# CONFIG_SENSORS_HMC5843 is not set
++
++#
++# Active energy metering IC
++#
++# CONFIG_ADE7753 is not set
++# CONFIG_ADE7754 is not set
++# CONFIG_ADE7758 is not set
++# CONFIG_ADE7759 is not set
++# CONFIG_ADE7854 is not set
++
++#
++# Resolver to digital converters
++#
++# CONFIG_AD2S90 is not set
++# CONFIG_AD2S1200 is not set
++# CONFIG_AD2S1210 is not set
++
++#
++# Triggers - standalone
++#
++# CONFIG_IIO_SIMPLE_DUMMY is not set
+ # CONFIG_ZSMALLOC is not set
+ # CONFIG_USB_ENESTORAGE is not set
+ # CONFIG_BCM_WIMAX is not set
+@@ -2591,6 +2755,7 @@ CONFIG_ANDROID_TIMED_OUTPUT=y
+ CONFIG_ANDROID_TIMED_GPIO=y
+ # CONFIG_ANDROID_LOW_MEMORY_KILLER is not set
+ # CONFIG_ANDROID_INTF_ALARM_DEV is not set
++# CONFIG_SYNC is not set
+ # CONFIG_USB_WPAN_HCD is not set
+ # CONFIG_WIMAX_GDM72XX is not set
+ # CONFIG_CSR_WIFI is not set
+@@ -2605,10 +2770,14 @@ CONFIG_COMMON_CLK=y
+ #
+ CONFIG_COMMON_CLK_DEBUG=y
+ CONFIG_COMMON_CLK_MAX77686=y
++# CONFIG_COMMON_CLK_SI5351 is not set
+ #
+ # Hardware Spinlock drivers
+ #
++CONFIG_CLKSRC_OF=y
++CONFIG_CLKSRC_EXYNOS_MCT=y
++# CONFIG_MAILBOX is not set
+ CONFIG_IOMMU_API=y
+ CONFIG_IOMMU_SUPPORT=y
+ CONFIG_OF_IOMMU=y
+@@ -2616,21 +2785,120 @@ CONFIG_EXYNOS_IOMMU=y
+ # CONFIG_EXYNOS_IOMMU_DEBUG is not set
+ #
+-# Remoteproc drivers (EXPERIMENTAL)
++# Remoteproc drivers
+ #
+ # CONFIG_STE_MODEM_RPROC is not set
+ #
+-# Rpmsg drivers (EXPERIMENTAL)
++# Rpmsg drivers
+ #
+-# CONFIG_VIRT_DRIVERS is not set
+ # CONFIG_PM_DEVFREQ is not set
+ # CONFIG_EXTCON is not set
+ # CONFIG_MEMORY is not set
+-# CONFIG_IIO is not set
++CONFIG_IIO=y
++# CONFIG_IIO_BUFFER is not set
++# CONFIG_IIO_TRIGGER is not set
++
++#
++# Accelerometers
++#
++# CONFIG_KXSD9 is not set
++# CONFIG_IIO_ST_ACCEL_3AXIS is not set
++
++#
++# Analog to digital converters
++#
++# CONFIG_AD7266 is not set
++# CONFIG_AD7298 is not set
++# CONFIG_AD7923 is not set
++# CONFIG_AD7791 is not set
++# CONFIG_AD7793 is not set
++# CONFIG_AD7476 is not set
++# CONFIG_AD7887 is not set
++# CONFIG_EXYNOS_ADC is not set
++# CONFIG_MAX1363 is not set
++# CONFIG_TI_ADC081C is not set
++
++#
++# Amplifiers
++#
++# CONFIG_AD8366 is not set
++
++#
++# Barometer sensors
++#
++
++#
++# Hid Sensor IIO Common
++#
++
++#
++# Digital to analog converters
++#
++# CONFIG_AD5064 is not set
++# CONFIG_AD5360 is not set
++# CONFIG_AD5380 is not set
++# CONFIG_AD5421 is not set
++# CONFIG_AD5624R_SPI is not set
++# CONFIG_AD5446 is not set
++# CONFIG_AD5449 is not set
++# CONFIG_AD5504 is not set
++# CONFIG_AD5755 is not set
++# CONFIG_AD5764 is not set
++# CONFIG_AD5791 is not set
++# CONFIG_AD5686 is not set
++# CONFIG_MAX517 is not set
++# CONFIG_MCP4725 is not set
++
++#
++# Frequency Synthesizers DDS/PLL
++#
++
++#
++# Clock Generator/Distribution
++#
++# CONFIG_AD9523 is not set
++
++#
++# Phase-Locked Loop (PLL) frequency synthesizers
++#
++# CONFIG_ADF4350 is not set
++
++#
++# Digital gyroscope sensors
++#
++# CONFIG_ADIS16080 is not set
++# CONFIG_ADIS16136 is not set
++# CONFIG_ADXRS450 is not set
++# CONFIG_IIO_ST_GYRO_3AXIS is not set
++# CONFIG_ITG3200 is not set
++
++#
++# Inertial measurement units
++#
++# CONFIG_ADIS16400 is not set
++# CONFIG_ADIS16480 is not set
++# CONFIG_INV_MPU6050_IIO is not set
++
++#
++# Light sensors
++#
++# CONFIG_ADJD_S311 is not set
++# CONFIG_SENSORS_TSL2563 is not set
++# CONFIG_VCNL4000 is not set
++
++#
++# Magnetometer sensors
++#
++CONFIG_AK8975=y
++# CONFIG_IIO_ST_MAGN_3AXIS is not set
+ CONFIG_PWM=y
+ CONFIG_PWM_SAMSUNG=y
++CONFIG_IRQCHIP=y
++CONFIG_ARM_GIC=y
++CONFIG_GIC_NON_BANKED=y
+ # CONFIG_IPACK_BUS is not set
++# CONFIG_RESET_CONTROLLER is not set
+ #
+ # File systems
+@@ -2650,6 +2918,7 @@ CONFIG_FS_MBCACHE=y
+ # CONFIG_JFS_FS is not set
+ # CONFIG_XFS_FS is not set
+ # CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
+ # CONFIG_BTRFS_FS is not set
+ # CONFIG_NILFS2_FS is not set
+ CONFIG_FS_POSIX_ACL=y
+@@ -2698,7 +2967,7 @@ CONFIG_TMPFS=y
+ CONFIG_TMPFS_POSIX_ACL=y
+ CONFIG_TMPFS_XATTR=y
+ # CONFIG_HUGETLB_PAGE is not set
+-# CONFIG_CONFIGFS_FS is not set
++CONFIG_CONFIGFS_FS=y
+ CONFIG_MISC_FILESYSTEMS=y
+ # CONFIG_ADFS_FS is not set
+ # CONFIG_AFFS_FS is not set
+@@ -2789,6 +3058,7 @@ CONFIG_NLS_ISO8859_1=y
+ # CONFIG_NLS_MAC_ROMANIAN is not set
+ # CONFIG_NLS_MAC_TURKISH is not set
+ CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
+ #
+ # Kernel hacking
+@@ -2828,8 +3098,6 @@ CONFIG_HAVE_DEBUG_KMEMLEAK=y
+ # CONFIG_DEBUG_MUTEXES is not set
+ # CONFIG_DEBUG_LOCK_ALLOC is not set
+ # CONFIG_PROVE_LOCKING is not set
+-# CONFIG_PROVE_RCU_DELAY is not set
+-# CONFIG_SPARSE_RCU_POINTER is not set
+ # CONFIG_LOCK_STAT is not set
+ # CONFIG_DEBUG_ATOMIC_SLEEP is not set
+ # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+@@ -2849,6 +3117,12 @@ CONFIG_DEBUG_INFO=y
+ # CONFIG_DEBUG_NOTIFIERS is not set
+ # CONFIG_DEBUG_CREDENTIALS is not set
+ # CONFIG_BOOT_PRINTK_DELAY is not set
++
++#
++# RCU Debugging
++#
++# CONFIG_PROVE_RCU_DELAY is not set
++# CONFIG_SPARSE_RCU_POINTER is not set
+ # CONFIG_RCU_TORTURE_TEST is not set
+ CONFIG_RCU_CPU_STALL_TIMEOUT=60
+ CONFIG_RCU_CPU_STALL_VERBOSE=y
+@@ -2873,7 +3147,6 @@ CONFIG_TRACER_MAX_TRACE=y
+ CONFIG_TRACE_CLOCK=y
+ CONFIG_RING_BUFFER=y
+ CONFIG_EVENT_TRACING=y
+-CONFIG_EVENT_POWER_TRACING_DEPRECATED=y
+ CONFIG_CONTEXT_SWITCH_TRACER=y
+ CONFIG_RING_BUFFER_ALLOW_SWAP=y
+ CONFIG_TRACING=y
+@@ -2885,6 +3158,8 @@ CONFIG_FTRACE=y
+ # CONFIG_PREEMPT_TRACER is not set
+ CONFIG_SCHED_TRACER=y
+ # CONFIG_FTRACE_SYSCALLS is not set
++CONFIG_TRACER_SNAPSHOT=y
++# CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP is not set
+ CONFIG_BRANCH_PROFILE_NONE=y
+ # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+ # CONFIG_PROFILE_ALL_BRANCHES is not set
+@@ -2893,6 +3168,7 @@ CONFIG_BRANCH_PROFILE_NONE=y
+ # CONFIG_PROBE_EVENTS is not set
+ # CONFIG_FTRACE_STARTUP_TEST is not set
+ # CONFIG_RING_BUFFER_BENCHMARK is not set
++# CONFIG_RING_BUFFER_STARTUP_TEST is not set
+ # CONFIG_RBTREE_TEST is not set
+ # CONFIG_INTERVAL_TREE_TEST is not set
+ CONFIG_DYNAMIC_DEBUG=y
+@@ -2901,6 +3177,7 @@ CONFIG_DYNAMIC_DEBUG=y
+ # CONFIG_SAMPLES is not set
+ CONFIG_HAVE_ARCH_KGDB=y
+ # CONFIG_KGDB is not set
++# CONFIG_TEST_STRING_HELPERS is not set
+ # CONFIG_TEST_KSTRTOX is not set
+ # CONFIG_STRICT_DEVMEM is not set
+ CONFIG_ARM_UNWIND=y
+@@ -2913,7 +3190,9 @@ CONFIG_DEBUG_S3C_UART2=y
+ # CONFIG_DEBUG_LL_UART_NONE is not set
+ # CONFIG_DEBUG_ICEDCC is not set
+ # CONFIG_DEBUG_SEMIHOSTING is not set
+-CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
++CONFIG_DEBUG_EXYNOS_UART=y
++CONFIG_DEBUG_LL_INCLUDE="debug/exynos.S"
++CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"
+ CONFIG_EARLY_PRINTK=y
+ # CONFIG_OC_ETM is not set
+ # CONFIG_PID_IN_CONTEXTIDR is not set
+@@ -2986,6 +3265,7 @@ CONFIG_CRYPTO_ECB=y
+ #
+ # Hash modes
+ #
++# CONFIG_CRYPTO_CMAC is not set
+ CONFIG_CRYPTO_HMAC=y
+ # CONFIG_CRYPTO_XCBC is not set
+ # CONFIG_CRYPTO_VMAC is not set
+@@ -2994,6 +3274,7 @@ CONFIG_CRYPTO_HMAC=y
+ # Digest
+ #
+ CONFIG_CRYPTO_CRC32C=y
++# CONFIG_CRYPTO_CRC32 is not set
+ # CONFIG_CRYPTO_GHASH is not set
+ # CONFIG_CRYPTO_MD4 is not set
+ CONFIG_CRYPTO_MD5=y
+@@ -3053,7 +3334,6 @@ CONFIG_GENERIC_STRNCPY_FROM_USER=y
+ CONFIG_GENERIC_STRNLEN_USER=y
+ CONFIG_GENERIC_PCI_IOMAP=y
+ CONFIG_GENERIC_IO=y
+-CONFIG_PERCPU_RWSEM=y
+ CONFIG_CRC_CCITT=y
+ CONFIG_CRC16=y
+ # CONFIG_CRC_T10DIF is not set
+@@ -3094,3 +3374,4 @@ CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+ # CONFIG_AVERAGE is not set
+ # CONFIG_CORDIC is not set
+ # CONFIG_DDR is not set
++# CONFIG_VIRTUALIZATION is not set
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0253-regulator-max77693-Modify-platform-deivce-id-accordi.patch b/patches.tizen/0253-regulator-max77693-Modify-platform-deivce-id-accordi.patch
new file mode 100644 (file)
index 0000000..86339e6
--- /dev/null
@@ -0,0 +1,37 @@
+From 35dc664b8254f125cfb688390c099254fe0a89b6 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Tue, 11 Jun 2013 00:12:17 +0900
+Subject: [PATCH 0253/1302] regulator: max77693: Modify platform deivce id
+ according to mfd driver.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/regulator/max77693.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/regulator/max77693.c b/drivers/regulator/max77693.c
+index 60842a8..fb802d5 100644
+--- a/drivers/regulator/max77693.c
++++ b/drivers/regulator/max77693.c
+@@ -812,7 +812,7 @@ static int max77693_pmic_remove(struct platform_device *pdev)
+ }
+ static const struct platform_device_id max77693_pmic_id[] = {
+-      {"max77693-safeout", 0},
++      {"max77693-pmic", 0},
+       {},
+ };
+@@ -820,7 +820,7 @@ MODULE_DEVICE_TABLE(platform, max77693_pmic_id);
+ static struct platform_driver max77693_pmic_driver = {
+       .driver = {
+-                 .name = "max77693-safeout",
++                 .name = "max77693-pmic",
+                  .owner = THIS_MODULE,
+                  },
+       .probe = max77693_pmic_probe,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0254-regulator-max77693-Pass-of_node-when-regulator-is-re.patch b/patches.tizen/0254-regulator-max77693-Pass-of_node-when-regulator-is-re.patch
new file mode 100644 (file)
index 0000000..bf4cab8
--- /dev/null
@@ -0,0 +1,31 @@
+From 3558940e59ffb3c7c9cfd3c88324941503341fa0 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Tue, 11 Jun 2013 00:13:39 +0900
+Subject: [PATCH 0254/1302] regulator: max77693: Pass of_node when regulator is
+ registered.
+
+Since of_get_regulator() retrieve regulator's list with of_node pointer,
+all regulator is required to hold their device tree node if regulator driver
+uses device tree.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/regulator/max77693.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/regulator/max77693.c b/drivers/regulator/max77693.c
+index fb802d5..8f170e9b 100644
+--- a/drivers/regulator/max77693.c
++++ b/drivers/regulator/max77693.c
+@@ -772,6 +772,7 @@ static int max77693_pmic_probe(struct platform_device *pdev)
+               int id = pdata->regulators[i].id;
+               config.init_data = pdata->regulators[i].initdata;
++              config.of_node = pdata->regulators[i].of_node;
+               pr_info("[%s:%d] for in pdata->num_regulators:%d\n", __FILE__,
+                       __LINE__, pdata->num_regulators);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0255-regulator-max77693-Do-code-clean.patch b/patches.tizen/0255-regulator-max77693-Do-code-clean.patch
new file mode 100644 (file)
index 0000000..a5846c0
--- /dev/null
@@ -0,0 +1,198 @@
+From 087f9725e11cdf51871d26ebe4272b33defabd29 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Tue, 11 Jun 2013 00:23:40 +0900
+Subject: [PATCH 0255/1302] regulator: max77693: Do code clean.
+
+This patch removes unnecessary dev_info, and changes some of them to dev_dbg.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/regulator/max77693.c | 37 ++++++++++++++++---------------------
+ 1 file changed, 16 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/regulator/max77693.c b/drivers/regulator/max77693.c
+index 8f170e9b..5f70b91 100644
+--- a/drivers/regulator/max77693.c
++++ b/drivers/regulator/max77693.c
+@@ -68,7 +68,6 @@ static const struct voltage_map_desc *reg_voltage_map[] = {
+ static inline int max77693_get_rid(struct regulator_dev *rdev)
+ {
+-      dev_info(&rdev->dev, "func:%s\n", __func__);
+       return rdev_get_id(rdev);
+ }
+@@ -76,7 +75,7 @@ static int max77693_list_voltage_safeout(struct regulator_dev *rdev,
+                                        unsigned int selector)
+ {
+       int rid = max77693_get_rid(rdev);
+-      dev_info(&rdev->dev, "func:%s\n", __func__);
++
+       if (rid == MAX77693_ESAFEOUT1 || rid == MAX77693_ESAFEOUT2) {
+               switch (selector) {
+               case 0:
+@@ -99,7 +98,6 @@ static int max77693_get_enable_register(struct regulator_dev *rdev,
+                                       int *reg, int *mask, int *pattern)
+ {
+       int rid = max77693_get_rid(rdev);
+-      dev_info(&rdev->dev, "func:%s\n", __func__);
+       switch (rid) {
+       case MAX77693_ESAFEOUT1...MAX77693_ESAFEOUT2:
+               *reg = MAX77693_CHG_REG_SAFEOUT_CTRL;
+@@ -123,7 +121,7 @@ static int max77693_get_disable_register(struct regulator_dev *rdev,
+                                       int *reg, int *mask, int *pattern)
+ {
+       int rid = max77693_get_rid(rdev);
+-      dev_info(&rdev->dev, "func:%s\n", __func__);
++
+       switch (rid) {
+       case MAX77693_ESAFEOUT1...MAX77693_ESAFEOUT2:
+               *reg = MAX77693_CHG_REG_SAFEOUT_CTRL;
+@@ -146,8 +144,8 @@ static int max77693_get_disable_register(struct regulator_dev *rdev,
+ static int max77693_reg_is_enabled(struct regulator_dev *rdev)
+ {
+       int ret, reg, mask, pattern;
++
+       u8 val;
+-      dev_info(&rdev->dev, "func:%s\n", __func__);
+       ret = max77693_get_enable_register(rdev, &reg, &mask, &pattern);
+       if (ret == -EINVAL)
+               return 1;       /* "not controllable" */
+@@ -164,7 +162,7 @@ static int max77693_reg_is_enabled(struct regulator_dev *rdev)
+ static int max77693_reg_enable(struct regulator_dev *rdev)
+ {
+       int ret, reg, mask, pattern;
+-      dev_info(&rdev->dev, "func:%s\n", __func__);
++
+       ret = max77693_get_enable_register(rdev, &reg, &mask, &pattern);
+       if (ret)
+               return ret;
+@@ -175,7 +173,7 @@ static int max77693_reg_enable(struct regulator_dev *rdev)
+ static int max77693_reg_disable(struct regulator_dev *rdev)
+ {
+       int ret, reg, mask, pattern;
+-      dev_info(&rdev->dev, "func:%s\n", __func__);
++
+       ret = max77693_get_disable_register(rdev, &reg, &mask, &pattern);
+       if (ret)
+               return ret;
+@@ -188,7 +186,7 @@ static int max77693_get_voltage_register(struct regulator_dev *rdev,
+ {
+       int rid = max77693_get_rid(rdev);
+       int reg, shift = 0, mask = 0x3f;
+-      dev_info(&rdev->dev, "func:%s\n", __func__);
++
+       switch (rid) {
+       case MAX77693_ESAFEOUT1...MAX77693_ESAFEOUT2:
+               reg = MAX77693_CHG_REG_SAFEOUT_CTRL;
+@@ -217,7 +215,7 @@ static int max77693_list_voltage(struct regulator_dev *rdev,
+       const struct voltage_map_desc *desc;
+       int rid = max77693_get_rid(rdev);
+       int val;
+-      dev_info(&rdev->dev, "func:%s\n", __func__);
++
+       if (rid >= ARRAY_SIZE(reg_voltage_map) || rid < 0)
+               return -EINVAL;
+@@ -245,7 +243,7 @@ static int max77693_get_voltage(struct regulator_dev *rdev)
+       int reg, shift, mask, ret;
+       u8 val;
+-      dev_info(&rdev->dev, "func:%s\n", __func__);
++
+       ret = max77693_get_voltage_register(rdev, &reg, &shift, &mask);
+       if (ret)
+               return ret;
+@@ -348,7 +346,7 @@ static int max77693_set_voltage_safeout(struct regulator_dev *rdev,
+       int reg, shift = 0, mask, ret;
+       int i = 0;
+       u8 val;
+-      dev_info(&rdev->dev, "func:%s\n", __func__);
++
+       if (rid != MAX77693_ESAFEOUT1 && rid != MAX77693_ESAFEOUT2)
+               return -EINVAL;
+@@ -377,7 +375,6 @@ static int max77693_set_voltage_safeout(struct regulator_dev *rdev,
+ static int max77693_reg_enable_suspend(struct regulator_dev *rdev)
+ {
+-      dev_info(&rdev->dev, "func:%s\n", __func__);
+       return 0;
+ }
+@@ -386,7 +383,7 @@ static int max77693_reg_disable_suspend(struct regulator_dev *rdev)
+       struct max77693_data *max77693 = rdev_get_drvdata(rdev);
+       int ret, reg, mask, pattern;
+       int rid = max77693_get_rid(rdev);
+-      dev_info(&rdev->dev, "func:%s\n", __func__);
++
+       ret = max77693_get_disable_register(rdev, &reg, &mask, &pattern);
+       if (ret)
+               return ret;
+@@ -459,7 +456,7 @@ static void max77693_muic_enable_otg(struct regulator_dev *rdev, int enable)
+       u8 cdetctrl1;
+       u8 chg_cnfg_00;
+-      dev_info(&rdev->dev, "enable(%d)\n", enable);
++      dev_dbg(&rdev->dev, "enable(%d)\n", enable);
+       /*
+        * FIXME: This function write/read directly the register of max77693
+@@ -527,7 +524,7 @@ static void max77693_muic_enable_otg(struct regulator_dev *rdev, int enable)
+                       MAX77693_CHG_REG_CHG_INT_MASK, &int_mask);
+       }
+-      dev_info(&rdev->dev,
++      dev_dbg(&rdev->dev,
+               "INT_MASK(0x%x), CDETCTRL1(0x%x), CHG_CNFG_00(0x%x)\n",
+               int_mask, cdetctrl1, chg_cnfg_00);
+ }
+@@ -539,7 +536,7 @@ static void max77693_muic_enable_otg(struct regulator_dev *rdev, int enable)
+  */
+ static void max77693_muic_enable_usb(struct regulator_dev *rdev, int enable)
+ {
+-      dev_info(&rdev->dev, "enable(%d)\n", enable);
++      dev_dbg(&rdev->dev, "enable(%d)\n", enable);
+       if (enable) {
+               /* OTG on, boost on */
+@@ -729,8 +726,6 @@ static int max77693_pmic_probe(struct platform_device *pdev)
+       int i, ret, size;
+       struct regulator_config config = {};
+-      dev_info(&pdev->dev, "%s\n", __func__);
+-
+       if (!pdata) {
+               pr_info("[%s:%d] !pdata\n", __FILE__, __LINE__);
+               dev_err(pdev->dev.parent, "No platform init data supplied.\n");
+@@ -765,7 +760,7 @@ static int max77693_pmic_probe(struct platform_device *pdev)
+       config.driver_data = max77693;
+       platform_set_drvdata(pdev, max77693);
+-      pr_info("[%s:%d] pdata->num_regulators:%d\n", __FILE__, __LINE__,
++      pr_debug("[%s:%d] pdata->num_regulators:%d\n", __FILE__, __LINE__,
+               pdata->num_regulators);
+       for (i = 0; i < pdata->num_regulators; i++) {
+               const struct voltage_map_desc *desc;
+@@ -774,7 +769,7 @@ static int max77693_pmic_probe(struct platform_device *pdev)
+               config.init_data = pdata->regulators[i].initdata;
+               config.of_node = pdata->regulators[i].of_node;
+-              pr_info("[%s:%d] for in pdata->num_regulators:%d\n", __FILE__,
++              pr_debug("[%s:%d] for in pdata->num_regulators:%d\n", __FILE__,
+                       __LINE__, pdata->num_regulators);
+               desc = reg_voltage_map[id];
+               if (id == MAX77693_ESAFEOUT1 || id == MAX77693_ESAFEOUT2)
+@@ -804,7 +799,7 @@ static int max77693_pmic_remove(struct platform_device *pdev)
+       struct max77693_data *max77693 = platform_get_drvdata(pdev);
+       struct regulator_dev **rdev = max77693->rdev;
+       int i;
+-      dev_info(&pdev->dev, "%s\n", __func__);
++
+       for (i = 0; i < max77693->num_regulators; i++)
+               if (rdev[i])
+                       regulator_unregister(rdev[i]);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0256-clk-Prevent-potential-null-pointer-dereference-in-cl.patch b/patches.tizen/0256-clk-Prevent-potential-null-pointer-dereference-in-cl.patch
new file mode 100644 (file)
index 0000000..14a29df
--- /dev/null
@@ -0,0 +1,31 @@
+From 9ffedfcc2ee4101d18384dd2e918748842fd376f Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 14 Jun 2013 17:10:49 +0200
+Subject: [PATCH 0256/1302] clk: Prevent potential null pointer dereference in
+ clk_set_rate()
+
+Ensure the passed clk pointer is not dereferenced if it is invalid.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/clk.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
+index 1144e8c..8d790a8 100644
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -1212,6 +1212,9 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
+       struct clk *top, *fail_clk;
+       int ret = 0;
++      if (IS_ERR_OR_NULL(clk))
++              return -EINVAL;
++
+       /* prevent racing with updates to the clock topology */
+       clk_prepare_lock();
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0257-clk-exynos4-Add-CLK_GET_RATE_NOCACHE-flag-for-the-Ex.patch b/patches.tizen/0257-clk-exynos4-Add-CLK_GET_RATE_NOCACHE-flag-for-the-Ex.patch
new file mode 100644 (file)
index 0000000..ad15c50
--- /dev/null
@@ -0,0 +1,128 @@
+From ce0efcf11eba1ee93ece8a376a69cbc89e70f93b Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 14 Jun 2013 17:16:18 +0200
+Subject: [PATCH 0257/1302] clk: exynos4: Add CLK_GET_RATE_NOCACHE flag for the
+ Exynos4x12 ISP clocks
+
+The ISP clock registers belong to the ISP power domain and may change
+their values if this power domain is switched off/on. Add
+CLK_GET_RATE_NOCACHE flags to ensure clk_set_rate() and clk_get_rate()
+work properly and do not use invalid cached values.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/samsung/clk-exynos4.c | 64 +++++++++++++++++++++------------------
+ 1 file changed, 34 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
+index be86c98..9994b8d 100644
+--- a/drivers/clk/samsung/clk-exynos4.c
++++ b/drivers/clk/samsung/clk-exynos4.c
+@@ -582,11 +582,15 @@ struct samsung_div_clock exynos4x12_div_clks[] __initdata = {
+       DIV(none, "div_spi1_isp", "mout_spi1_isp", E4X12_DIV_ISP, 16, 4),
+       DIV(none, "div_spi1_isp_pre", "div_spi1_isp", E4X12_DIV_ISP, 20, 8),
+       DIV(none, "div_uart_isp", "mout_uart_isp", E4X12_DIV_ISP, 28, 4),
+-      DIV(div_isp0, "div_isp0", "aclk200", E4X12_DIV_ISP0, 0, 3),
+-      DIV(div_isp1, "div_isp1", "aclk200", E4X12_DIV_ISP0, 4, 3),
++      DIV_F(div_isp0, "div_isp0", "aclk200", E4X12_DIV_ISP0, 0, 3,
++                                              CLK_GET_RATE_NOCACHE, 0),
++      DIV_F(div_isp1, "div_isp1", "aclk200", E4X12_DIV_ISP0, 4, 3,
++                                              CLK_GET_RATE_NOCACHE, 0),
+       DIV(none, "div_mpwm", "div_isp1", E4X12_DIV_ISP1, 0, 3),
+-      DIV(div_mcuisp0, "div_mcuisp0", "aclk400_mcuisp", E4X12_DIV_ISP1, 4, 3),
+-      DIV(div_mcuisp1, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1, 8, 3),
++      DIV_F(div_mcuisp0, "div_mcuisp0", "aclk400_mcuisp", E4X12_DIV_ISP1,
++                                              4, 3, CLK_GET_RATE_NOCACHE, 0),
++      DIV_F(div_mcuisp1, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1,
++                                              8, 3, CLK_GET_RATE_NOCACHE, 0),
+ };
+ /* list of gate clocks supported in all exynos4 soc's */
+@@ -861,57 +865,57 @@ struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = {
+       GATE_A(wdt, "watchdog", "aclk100",
+                       E4X12_GATE_IP_PERIR, 14, 0, 0, "watchdog"),
+       GATE(fimc_isp, "isp", "aclk200", E4X12_GATE_ISP0, 0,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(fimc_drc, "drc", "aclk200", E4X12_GATE_ISP0, 1,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(fimc_fd, "fd", "aclk200", E4X12_GATE_ISP0, 2,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(fimc_lite0, "lite0", "aclk200", E4X12_GATE_ISP0, 3,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(fimc_lite1, "lite1", "aclk200", E4X12_GATE_ISP0, 4,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(mcuisp, "mcuisp", "aclk200", E4X12_GATE_ISP0, 5,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(gicisp, "gicisp", "aclk200", E4X12_GATE_ISP0, 7,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(smmu_isp, "smmu_isp", "aclk200", E4X12_GATE_ISP0, 8,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(smmu_drc, "smmu_drc", "aclk200", E4X12_GATE_ISP0, 9,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(smmu_fd, "smmu_fd", "aclk200", E4X12_GATE_ISP0, 10,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(smmu_lite0, "smmu_lite0", "aclk200", E4X12_GATE_ISP0, 11,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(smmu_lite1, "smmu_lite1", "aclk200", E4X12_GATE_ISP0, 12,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(ppmuispmx, "ppmuispmx", "aclk200", E4X12_GATE_ISP0, 20,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(ppmuispx, "ppmuispx", "aclk200", E4X12_GATE_ISP0, 21,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(mcuctl_isp, "mcuctl_isp", "aclk200", E4X12_GATE_ISP0, 23,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(mpwm_isp, "mpwm_isp", "aclk200", E4X12_GATE_ISP0, 24,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(i2c0_isp, "i2c0_isp", "aclk200", E4X12_GATE_ISP0, 25,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(i2c1_isp, "i2c1_isp", "aclk200", E4X12_GATE_ISP0, 26,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(mtcadc_isp, "mtcadc_isp", "aclk200", E4X12_GATE_ISP0, 27,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(pwm_isp, "pwm_isp", "aclk200", E4X12_GATE_ISP0, 28,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(wdt_isp, "wdt_isp", "aclk200", E4X12_GATE_ISP0, 30,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(uart_isp, "uart_isp", "aclk200", E4X12_GATE_ISP0, 31,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(asyncaxim, "asyncaxim", "aclk200", E4X12_GATE_ISP1, 0,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(smmu_ispcx, "smmu_ispcx", "aclk200", E4X12_GATE_ISP1, 4,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(spi0_isp, "spi0_isp", "aclk200", E4X12_GATE_ISP1, 12,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(spi1_isp, "spi1_isp", "aclk200", E4X12_GATE_ISP1, 13,
+-                      CLK_IGNORE_UNUSED, 0),
++                      CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+ };
+ static struct of_device_id exynos4_clkout_ids[] __initdata = {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0258-ARM-dts-Add-camera-device-nodes-for-M0-rev-1.1-board.patch b/patches.tizen/0258-ARM-dts-Add-camera-device-nodes-for-M0-rev-1.1-board.patch
new file mode 100644 (file)
index 0000000..9cf82f4
--- /dev/null
@@ -0,0 +1,139 @@
+From 4cf948a01172bc55e6ed863192bfd4df87cc7287 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 14 Jun 2013 18:43:38 +0200
+Subject: [PATCH 0258/1302] ARM: dts: Add camera device nodes for M0 rev 1.1
+ board
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-m0.dts | 115 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 115 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-m0.dts b/arch/arm/boot/dts/exynos4412-m0.dts
+index 300ce10..8e75628 100644
+--- a/arch/arm/boot/dts/exynos4412-m0.dts
++++ b/arch/arm/boot/dts/exynos4412-m0.dts
+@@ -19,4 +19,119 @@
+       compatible = "samsung,m0", "samsung,exynos4412";
+       /* Nothing to override here yet. */
++
++      pinctrl@11400000 {
++              vt_cam_id: vt-cam-id {
++                      samsung,pins = "gpf1-2";
++                      samsung,pin-function = <2>;
++                      samsung,pin-pud = <1>;
++                      samsung,pin-drv = <3>;
++              };
++      };
++
++      camera {
++              status = "okay";
++
++              pinctrl-names = "default";
++              pinctrl-0 = <&cam_port_a_clk_active &cam_port_b_clk_active>;
++
++              fimc_0: fimc@11800000 {
++                      clock-frequency = <160000000>;
++                      status = "okay";
++              };
++
++              fimc_1: fimc@11810000 {
++                      clock-frequency = <160000000>;
++                      status = "okay";
++              };
++
++              fimc_2: fimc@11820000 {
++                      clock-frequency = <160000000>;
++                      status = "okay";
++              };
++
++              fimc_3: fimc@11830000 {
++                      clock-frequency = <160000000>;
++                      status = "okay";
++              };
++
++              csis_0: csis@11880000 {
++                      status = "okay";
++                      vddcore-supply = <&ldo8_reg>;
++                      vddio-supply = <&ldo10_reg>;
++                      clock-frequency = <160000000>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++
++                      /* Camera C (3) MIPI CSI-2 (CSIS0) */
++                      port@3 {
++                              reg = <3>;
++                              csis0_ep: endpoint {
++                                      remote-endpoint = <&s5c73m3_ep>;
++                                      data-lanes = <1 2 3 4>;
++                                      samsung,csis-hs-settle = <12>;
++                                      samsung,csis-wclk;
++                              };
++                      };
++              };
++
++              csis_1: csis@11890000 {
++                      status = "okay";
++                      vddcore-supply = <&ldo8_reg>;
++                      vddio-supply = <&ldo10_reg>;
++                      clock-frequency = <160000000>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++
++                      /* Camera D (4) MIPI CSI-2 (CSIS1) */
++                      port@4 {
++                              reg = <4>;
++                              csis1_ep: endpoint {
++                                      remote-endpoint = <&is_s5k6a3_ep>;
++                                      data-lanes = <1>;
++                                      samsung,csis-hs-settle = <18>;
++                                      samsung,csis-wclk;
++                              };
++                      };
++              };
++
++              fimc_lite_0: fimc-lite@12390000 {
++                      status = "okay";
++              };
++
++              fimc_lite_1: fimc-lite@123A0000 {
++                      status = "okay";
++              };
++
++              fimc-is@12000000 {
++                      linux,contiguous-region = <&fimc_mem>;
++                      status = "okay";
++                      pinctrl-0 = <&fimc_is_uart>;
++                      pinctrl-names = "default";
++
++                      i2c1_isp: i2c-isp@12140000 {
++                              pinctrl-0 = <&fimc_is_i2c1>;
++                              pinctrl-names = "default";
++
++                              s5k6a3@10 {
++                                      compatible = "samsung,s5k6a3";
++                                      reg = <0x10>;
++                                      svdda-supply = <&cam_io_reg>;
++                                      svddio-supply = <&ldo19_reg>;
++                                      clock-frequency = <24000000>;
++                                      samsung,camclk-out = <1>;
++                                      gpios = <&gpm1 6 0>;
++                                      pinctrl-names = "default";
++                                      pinctrl-0 = <&vt_cam_id>;
++
++                                      port {
++                                              is_s5k6a3_ep: endpoint {
++                                                      remote-endpoint = <&csis1_ep>;
++                                                      data-lanes = <1>;
++                                              };
++                                      };
++                              };
++                      };
++              };
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0259-iio-st_accel-Add-DT-bindings.patch b/patches.tizen/0259-iio-st_accel-Add-DT-bindings.patch
new file mode 100644 (file)
index 0000000..2767b94
--- /dev/null
@@ -0,0 +1,164 @@
+From b70b824c90bb46449bfbadee3ab5f312edfe670a Mon Sep 17 00:00:00 2001
+From: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Date: Mon, 17 Jun 2013 15:43:30 +0200
+Subject: [PATCH 0259/1302] iio: st_accel: Add DT bindings
+
+Signed-off-by: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/iio/accelerometer/st_accel | 47 ++++++++++++++++++++++
+ drivers/iio/accel/st_accel.h                       | 16 ++++----
+ drivers/iio/accel/st_accel_i2c.c                   | 17 ++++++++
+ drivers/iio/accel/st_accel_spi.c                   | 17 ++++++++
+ 4 files changed, 89 insertions(+), 8 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/iio/accelerometer/st_accel
+
+diff --git a/Documentation/devicetree/bindings/iio/accelerometer/st_accel b/Documentation/devicetree/bindings/iio/accelerometer/st_accel
+new file mode 100644
+index 0000000..0c5bc26
+--- /dev/null
++++ b/Documentation/devicetree/bindings/iio/accelerometer/st_accel
+@@ -0,0 +1,47 @@
++STMicroelectronics 3D  accelerometer
++
++Required properties:
++
++  - compatible : should be one from
++      "st,lsm330dlhc_accel"
++      "st,lis3dh"
++      "st,lsm330d_accel"
++      "st,lsm330dl_accel"
++      "st,lsm330dlc_accel"
++      "st,lsm331dlh"
++      "st,lsm303dl_accel"
++      "st,lsm303dlh_accel"
++      "st,lsm303dlm_accel"
++      "st,lsm330_accelc"
++
++  - reg : the I2C address of the accelerometer
++
++Optional properties:
++
++  - irq-map-policy: irqs from interrupt-map assigment policy
++      0: no irqs
++      1: map first irq to irq_data_ready
++      2: map first irq to irq_event
++      3..n: future improvements
++  - interrupt-parent: should contain interrupt map
++
++Example:
++
++lsm330dlc_accel@19 {
++      compatible = "st,lsm330dlc_accel";
++      reg = <0x19>;
++      irq-map-policy = <1>;
++      interrupt-controller;
++      #interrups-cells = <2>;
++      interrupt-parent = <&lsm330dlc_accel_map>;
++      interrupts= <1 0>;
++
++      lsm330dlc_accel_map: lsm330dlc-accel-map {
++              compatible = "samsung,lsm330dlc-accel-map";
++              #interrupt-cells = <2>;
++              #address-cells = <0>;
++              #size-cells = <0>;
++              interrupt-map = <0x1 0 &gpx0 0 0>;
++      };
++};
++
+diff --git a/drivers/iio/accel/st_accel.h b/drivers/iio/accel/st_accel.h
+index 37949b9..699adab 100644
+--- a/drivers/iio/accel/st_accel.h
++++ b/drivers/iio/accel/st_accel.h
+@@ -14,16 +14,16 @@
+ #include <linux/types.h>
+ #include <linux/iio/common/st_sensors.h>
+-#define LSM303DLHC_ACCEL_DEV_NAME     "lsm303dlhc_accel"
++#define LSM303DLHC_ACCEL_DEV_NAME     "lsm303dlhc-accel"
+ #define LIS3DH_ACCEL_DEV_NAME         "lis3dh"
+-#define LSM330D_ACCEL_DEV_NAME                "lsm330d_accel"
+-#define LSM330DL_ACCEL_DEV_NAME               "lsm330dl_accel"
+-#define LSM330DLC_ACCEL_DEV_NAME      "lsm330dlc_accel"
++#define LSM330D_ACCEL_DEV_NAME                "lsm330d-accel"
++#define LSM330DL_ACCEL_DEV_NAME               "lsm330dl-accel"
++#define LSM330DLC_ACCEL_DEV_NAME      "lsm330dlc-accel"
+ #define LIS331DLH_ACCEL_DEV_NAME      "lis331dlh"
+-#define LSM303DL_ACCEL_DEV_NAME               "lsm303dl_accel"
+-#define LSM303DLH_ACCEL_DEV_NAME      "lsm303dlh_accel"
+-#define LSM303DLM_ACCEL_DEV_NAME      "lsm303dlm_accel"
+-#define LSM330_ACCEL_DEV_NAME         "lsm330_accel"
++#define LSM303DL_ACCEL_DEV_NAME               "lsm303dl-accel"
++#define LSM303DLH_ACCEL_DEV_NAME      "lsm303dlh-accel"
++#define LSM303DLM_ACCEL_DEV_NAME      "lsm303dlm-accel"
++#define LSM330_ACCEL_DEV_NAME         "lsm330-accel"
+ int st_accel_common_probe(struct iio_dev *indio_dev);
+ void st_accel_common_remove(struct iio_dev *indio_dev);
+diff --git a/drivers/iio/accel/st_accel_i2c.c b/drivers/iio/accel/st_accel_i2c.c
+index ffc9d09..63992f2 100644
+--- a/drivers/iio/accel/st_accel_i2c.c
++++ b/drivers/iio/accel/st_accel_i2c.c
+@@ -70,10 +70,27 @@ static const struct i2c_device_id st_accel_id_table[] = {
+ };
+ MODULE_DEVICE_TABLE(i2c, st_accel_id_table);
++#ifdef CONFIG_OF
++static struct of_device_id st_accel_dt_match[] = {
++      { .compatible = "st,lsm330dlhc_accel" },
++      { .compatible = "st,lis3dh" },
++      { .compatible = "st,lsm330d-accel" },
++      { .compatible = "st,lsm330dl-accel" },
++      { .compatible = "st,lsm330dlc-accel" },
++      { .compatible = "st,lsm331dlh" },
++      { .compatible = "st,lsm303dl-accel" },
++      { .compatible = "st,lsm303dlh-accel" },
++      { .compatible = "st,lsm303dlm-accel" },
++      { .compatible = "st,lsm330-accel" },
++      { }
++};
++#endif
++
+ static struct i2c_driver st_accel_driver = {
+       .driver = {
+               .owner = THIS_MODULE,
+               .name = "st-accel-i2c",
++              .of_match_table = of_match_ptr(st_accel_dt_match),
+       },
+       .probe = st_accel_i2c_probe,
+       .remove = st_accel_i2c_remove,
+diff --git a/drivers/iio/accel/st_accel_spi.c b/drivers/iio/accel/st_accel_spi.c
+index 22b35bf..671fd48 100644
+--- a/drivers/iio/accel/st_accel_spi.c
++++ b/drivers/iio/accel/st_accel_spi.c
+@@ -69,10 +69,27 @@ static const struct spi_device_id st_accel_id_table[] = {
+ };
+ MODULE_DEVICE_TABLE(spi, st_accel_id_table);
++#ifdef CONFIG_OF
++static struct of_device_id st_accel_dt_match[] = {
++      { .compatible = "st,lsm330dlhc-accel" },
++      { .compatible = "st,lis3dh" },
++      { .compatible = "st,lsm330d-accel" },
++      { .compatible = "st,lsm330dl-accel" },
++      { .compatible = "st,lsm330dlc-accel" },
++      { .compatible = "st,lsm331dlh" },
++      { .compatible = "st,lsm303dl-accel" },
++      { .compatible = "st,lsm303dlh-accel" },
++      { .compatible = "st,lsm303dlm-accel" },
++      { .compatible = "st,lsm330-accel" },
++      { }
++};
++#endif
++
+ static struct spi_driver st_accel_driver = {
+       .driver = {
+               .owner = THIS_MODULE,
+               .name = "st-accel-spi",
++              .of_match_table = of_match_ptr(st_accel_dt_match),
+       },
+       .probe = st_accel_spi_probe,
+       .remove = st_accel_spi_remove,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0260-iio-st_gyro-Add-DT-bindings.patch b/patches.tizen/0260-iio-st_gyro-Add-DT-bindings.patch
new file mode 100644 (file)
index 0000000..fb2eebb
--- /dev/null
@@ -0,0 +1,149 @@
+From ee241f53a6803d8d7b362e76c388d84076436a5c Mon Sep 17 00:00:00 2001
+From: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Date: Mon, 17 Jun 2013 15:49:49 +0200
+Subject: [PATCH 0260/1302] iio: st_gyro: Add DT bindings
+
+Signed-off-by: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/iio/gyroscope/st_gyroscope | 44 ++++++++++++++++++++++
+ drivers/iio/gyro/st_gyro.h                         | 10 ++---
+ drivers/iio/gyro/st_gyro_i2c.c                     | 14 +++++++
+ drivers/iio/gyro/st_gyro_spi.c                     | 14 +++++++
+ 4 files changed, 77 insertions(+), 5 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/iio/gyroscope/st_gyroscope
+
+diff --git a/Documentation/devicetree/bindings/iio/gyroscope/st_gyroscope b/Documentation/devicetree/bindings/iio/gyroscope/st_gyroscope
+new file mode 100644
+index 0000000..f45d62f
+--- /dev/null
++++ b/Documentation/devicetree/bindings/iio/gyroscope/st_gyroscope
+@@ -0,0 +1,44 @@
++STMicroelectronics 3D  gyroscope
++
++Required properties:
++
++  - compatible : should be one from
++      "st,l3g4200d"
++      "st,lsm330d_gyro"
++      "st,lsm330dl_gyro"
++      "st,lsm330dlc_gyro"
++      "st,l3gd20"
++      "st,l3gd20h"
++      "st,l3g4is_ui"
++      "st,lsm330_gyro"
++
++  - reg : the I2C address of the accelerometer
++
++Optional properties:
++
++  - irq-map-policy: irqs from interrupt-map assigment policy
++      0: no irqs
++      1: map first irq to irq_data_ready
++      2: map first irq to irq_event
++      3..n: future improvements
++  - interrupt-parent: should contain interrupt map
++
++Example:
++
++      lsm330dlc_gyro@6b {
++              compatible = "st,lsm330dlc_gyro";
++              reg = <0x6b>;
++              irq-map-policy = <0>;
++              interrupt-controller;
++              #interrups-cells = <2>;
++              interrupt-parent = <&lsm330dlc_gyro_map>;
++              interrupts= <1 0>;
++
++              lsm330dlc_gyro_map: lsm330dlc-gyro-map {
++                              compatible = "samsung,lsm330dlc-gyro-map";
++                              #interrupt-cells = <2>;
++                              #address-cells = <0>;
++                              #size-cells = <0>;
++                              interrupt-map = <0x1 0 &gpf0 3 0>;
++              };
++      };
+diff --git a/drivers/iio/gyro/st_gyro.h b/drivers/iio/gyro/st_gyro.h
+index 3ad9907..7fdfa8f 100644
+--- a/drivers/iio/gyro/st_gyro.h
++++ b/drivers/iio/gyro/st_gyro.h
+@@ -15,13 +15,13 @@
+ #include <linux/iio/common/st_sensors.h>
+ #define L3G4200D_GYRO_DEV_NAME                "l3g4200d"
+-#define LSM330D_GYRO_DEV_NAME         "lsm330d_gyro"
+-#define LSM330DL_GYRO_DEV_NAME                "lsm330dl_gyro"
+-#define LSM330DLC_GYRO_DEV_NAME               "lsm330dlc_gyro"
++#define LSM330D_GYRO_DEV_NAME         "lsm330d-gyro"
++#define LSM330DL_GYRO_DEV_NAME                "lsm330dl-gyro"
++#define LSM330DLC_GYRO_DEV_NAME               "lsm330dlc-gyro"
+ #define L3GD20_GYRO_DEV_NAME          "l3gd20"
+ #define L3GD20H_GYRO_DEV_NAME         "l3gd20h"
+-#define L3G4IS_GYRO_DEV_NAME          "l3g4is_ui"
+-#define LSM330_GYRO_DEV_NAME          "lsm330_gyro"
++#define L3G4IS_GYRO_DEV_NAME          "l3g4is-ui"
++#define LSM330_GYRO_DEV_NAME          "lsm330-gyro"
+ int st_gyro_common_probe(struct iio_dev *indio_dev);
+ void st_gyro_common_remove(struct iio_dev *indio_dev);
+diff --git a/drivers/iio/gyro/st_gyro_i2c.c b/drivers/iio/gyro/st_gyro_i2c.c
+index 8a31050..02ae61b 100644
+--- a/drivers/iio/gyro/st_gyro_i2c.c
++++ b/drivers/iio/gyro/st_gyro_i2c.c
+@@ -68,10 +68,24 @@ static const struct i2c_device_id st_gyro_id_table[] = {
+ };
+ MODULE_DEVICE_TABLE(i2c, st_gyro_id_table);
++#ifdef CONFIG_OF
++static struct of_device_id st_gyro_dt_match[] = {
++      { .compatible = "st,l3g4200d" },
++      { .compatible = "st,lsm330d-gyro" },
++      { .compatible = "st,lsm330dl-gyro" },
++      { .compatible = "st,lsm330dlc-gyro" },
++      { .compatible = "st,l3gd20" },
++      { .compatible = "st,l3gd20h" },
++      { .compatible = "st,l3g4is-ui" },
++      { .compatible = "st,lsm330-gyro" },
++};
++#endif
++
+ static struct i2c_driver st_gyro_driver = {
+       .driver = {
+               .owner = THIS_MODULE,
+               .name = "st-gyro-i2c",
++              .of_match_table = of_match_ptr(st_gyro_dt_match),
+       },
+       .probe = st_gyro_i2c_probe,
+       .remove = st_gyro_i2c_remove,
+diff --git a/drivers/iio/gyro/st_gyro_spi.c b/drivers/iio/gyro/st_gyro_spi.c
+index f354039..e82a868 100644
+--- a/drivers/iio/gyro/st_gyro_spi.c
++++ b/drivers/iio/gyro/st_gyro_spi.c
+@@ -67,10 +67,24 @@ static const struct spi_device_id st_gyro_id_table[] = {
+ };
+ MODULE_DEVICE_TABLE(spi, st_gyro_id_table);
++#ifdef CONFIG_OF
++static struct of_device_id st_gyro_dt_match[] = {
++      { .compatible = "st,l3g4200d" },
++      { .compatible = "st,lsm330d-gyro" },
++      { .compatible = "st,lsm330dl-gyro" },
++      { .compatible = "st,lsm330dlc-gyro" },
++      { .compatible = "st,l3gd20" },
++      { .compatible = "st,l3gd20h" },
++      { .compatible = "st,l3g4is-ui" },
++      { .compatible = "st,lsm330-gyro" },
++};
++#endif
++
+ static struct spi_driver st_gyro_driver = {
+       .driver = {
+               .owner = THIS_MODULE,
+               .name = "st-gyro-spi",
++              .of_match_table = of_match_ptr(st_gyro_dt_match),
+       },
+       .probe = st_gyro_spi_probe,
+       .remove = st_gyro_spi_remove,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0261-iio-st_sensors-Add-handling-of-multiple-interrupts.patch b/patches.tizen/0261-iio-st_sensors-Add-handling-of-multiple-interrupts.patch
new file mode 100644 (file)
index 0000000..146ae1c
--- /dev/null
@@ -0,0 +1,175 @@
+From 17a938cb6784d6c40b98aeb0d3bf587861eef1dd Mon Sep 17 00:00:00 2001
+From: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Date: Thu, 23 May 2013 13:35:28 +0200
+Subject: [PATCH 0261/1302] iio: st_sensors: Add handling of multiple
+ interrupts
+
+This patch adds handling of multiple interrupts for st_sensors.
+Each mapped interrupt can be declared from DT.
+
+Signed-off-by: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iio/common/st_sensors/st_sensors_i2c.c | 32 ++++++++++++++++++++++---
+ drivers/iio/common/st_sensors/st_sensors_spi.c | 33 +++++++++++++++++++++++---
+ include/linux/iio/common/st_sensors.h          |  9 +++++++
+ 3 files changed, 68 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/iio/common/st_sensors/st_sensors_i2c.c b/drivers/iio/common/st_sensors/st_sensors_i2c.c
+index 38af944..5ef7682 100644
+--- a/drivers/iio/common/st_sensors/st_sensors_i2c.c
++++ b/drivers/iio/common/st_sensors/st_sensors_i2c.c
+@@ -8,6 +8,8 @@
+  * Licensed under the GPL-2.
+  */
++#include <linux/of.h>
++#include <linux/of_irq.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/slab.h>
+@@ -18,11 +20,33 @@
+ #define ST_SENSORS_I2C_MULTIREAD      0x80
+-static unsigned int st_sensors_i2c_get_irq(struct iio_dev *indio_dev)
++static unsigned int st_sensors_i2c_get_data_rdy_irq(struct iio_dev *indio_dev)
+ {
+       struct st_sensor_data *sdata = iio_priv(indio_dev);
+-      return to_i2c_client(sdata->dev)->irq;
++      return sdata->irq_map[ST_SENSORS_INT1];
++}
++
++static void st_sensors_i2c_map_irqs(struct i2c_client *client,
++              struct iio_dev *indio_dev)
++{
++      struct st_sensor_data *sdata = iio_priv(indio_dev);
++      struct device_node *np = client->dev.of_node;
++      u32 irq_policy = 0;
++
++      of_property_read_u32(np, "irq-map-policy", &irq_policy);
++
++      switch (irq_policy) {
++      case ST_SENSORS_MAP_ONLY_DRDY_IRQ:
++              sdata->irq_map[ST_SENSORS_INT1] = irq_of_parse_and_map(np, 0);
++              break;
++      case ST_SENSORS_MAP_ONLY_EVENT_IRQ:
++              sdata->irq_map[ST_SENSORS_INT2] = irq_of_parse_and_map(np, 0);
++              break;
++      default:
++              sdata->irq_map[ST_SENSORS_INT1] = 0;
++              sdata->irq_map[ST_SENSORS_INT2] = 0;
++      }
+ }
+ static int st_sensors_i2c_read_byte(struct st_sensor_transfer_buffer *tb,
+@@ -72,7 +96,9 @@ void st_sensors_i2c_configure(struct iio_dev *indio_dev,
+       indio_dev->name = client->name;
+       sdata->tf = &st_sensors_tf_i2c;
+-      sdata->get_irq_data_ready = st_sensors_i2c_get_irq;
++
++      st_sensors_i2c_map_irqs(client, indio_dev);
++      sdata->get_irq_data_ready = st_sensors_i2c_get_data_rdy_irq;
+ }
+ EXPORT_SYMBOL(st_sensors_i2c_configure);
+diff --git a/drivers/iio/common/st_sensors/st_sensors_spi.c b/drivers/iio/common/st_sensors/st_sensors_spi.c
+index 251baf6..69c7069 100644
+--- a/drivers/iio/common/st_sensors/st_sensors_spi.c
++++ b/drivers/iio/common/st_sensors/st_sensors_spi.c
+@@ -8,6 +8,8 @@
+  * Licensed under the GPL-2.
+  */
++#include <linux/of.h>
++#include <linux/of_irq.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/slab.h>
+@@ -19,11 +21,34 @@
+ #define ST_SENSORS_SPI_MULTIREAD      0xc0
+ #define ST_SENSORS_SPI_READ           0x80
+-static unsigned int st_sensors_spi_get_irq(struct iio_dev *indio_dev)
++static unsigned int st_sensors_spi_get_data_rdy_irq(struct iio_dev *indio_dev)
+ {
+       struct st_sensor_data *sdata = iio_priv(indio_dev);
+-      return to_spi_device(sdata->dev)->irq;
++      return sdata->irq_map[ST_SENSORS_INT1];
++}
++
++static void st_sensors_spi_map_irqs(struct spi_device *spi,
++              struct iio_dev *indio_dev)
++{
++      struct st_sensor_data *sdata = iio_priv(indio_dev);
++      struct device_node *np = spi->dev.of_node;
++      u32 irq_policy = 0;
++
++      of_property_read_u32(np, "irq-map-policy", &irq_policy);
++
++      switch (irq_policy) {
++      case ST_SENSORS_MAP_ONLY_DRDY_IRQ:
++              sdata->irq_map[ST_SENSORS_INT1] = irq_of_parse_and_map(np, 0);
++              break;
++      case ST_SENSORS_MAP_ONLY_EVENT_IRQ:
++              sdata->irq_map[ST_SENSORS_INT2] = irq_of_parse_and_map(np, 0);
++              break;
++      default:
++              sdata->irq_map[ST_SENSORS_INT1] = 0;
++              sdata->irq_map[ST_SENSORS_INT2] = 0;
++              break;
++      }
+ }
+ static int st_sensors_spi_read(struct st_sensor_transfer_buffer *tb,
+@@ -112,7 +137,9 @@ void st_sensors_spi_configure(struct iio_dev *indio_dev,
+       indio_dev->name = spi->modalias;
+       sdata->tf = &st_sensors_tf_spi;
+-      sdata->get_irq_data_ready = st_sensors_spi_get_irq;
++
++      st_sensors_spi_map_irqs(spi, indio_dev);
++      sdata->get_irq_data_ready = st_sensors_spi_get_data_rdy_irq;
+ }
+ EXPORT_SYMBOL(st_sensors_spi_configure);
+diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h
+index 172c5b2..2fd12a6 100644
+--- a/include/linux/iio/common/st_sensors.h
++++ b/include/linux/iio/common/st_sensors.h
+@@ -42,6 +42,13 @@
+ #define ST_SENSORS_MAX_NAME                   17
+ #define ST_SENSORS_MAX_4WAI                   7
++#define ST_SENSORS_INT_MAX                    2
++#define ST_SENSORS_INT1                               0
++#define ST_SENSORS_INT2                               1
++#define ST_SENSORS_MAP_ONLY_DRDY_IRQ          1
++#define ST_SENSORS_MAP_ONLY_EVENT_IRQ         2
++
++
+ #define ST_SENSORS_LSM_CHANNELS(device_type, index, mod, endian, bits, addr) \
+ { \
+       .type = device_type, \
+@@ -204,6 +211,7 @@ struct st_sensors {
+  * @multiread_bit: Use or not particular bit for [I2C/SPI] multiread.
+  * @buffer_data: Data used by buffer part.
+  * @odr: Output data rate of the sensor [Hz].
++ * @irq_map: Container of mapped IRQs.
+  * @get_irq_data_ready: Function to get the IRQ used for data ready signal.
+  * @tf: Transfer function structure used by I/O operations.
+  * @tb: Transfer buffers and mutex used by I/O operations.
+@@ -220,6 +228,7 @@ struct st_sensor_data {
+       char *buffer_data;
+       unsigned int odr;
++      unsigned int irq_map[ST_SENSORS_INT_MAX];
+       unsigned int (*get_irq_data_ready) (struct iio_dev *indio_dev);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0262-iio-st_sensors-Add-threshold-events-support.patch b/patches.tizen/0262-iio-st_sensors-Add-threshold-events-support.patch
new file mode 100644 (file)
index 0000000..79a3277
--- /dev/null
@@ -0,0 +1,469 @@
+From 74ed2b4642c43e0963465998c64fcc7bfd3b4a98 Mon Sep 17 00:00:00 2001
+From: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Date: Thu, 23 May 2013 16:02:45 +0200
+Subject: [PATCH 0262/1302] iio: st_sensors Add threshold events support
+
+This patch adds threshold events support for the ST common
+library.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iio/common/st_sensors/st_sensors_core.c | 213 ++++++++++++++++++++++++
+ drivers/iio/common/st_sensors/st_sensors_i2c.c  |   8 +
+ drivers/iio/common/st_sensors/st_sensors_spi.c  |   8 +
+ include/linux/iio/common/st_sensors.h           |  75 +++++++++
+ 4 files changed, 304 insertions(+)
+
+diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c
+index ed9bc8a..53fbc50 100644
+--- a/drivers/iio/common/st_sensors/st_sensors_core.c
++++ b/drivers/iio/common/st_sensors/st_sensors_core.c
+@@ -13,7 +13,9 @@
+ #include <linux/slab.h>
+ #include <linux/delay.h>
+ #include <linux/iio/iio.h>
++#include <linux/iio/events.h>
+ #include <asm/unaligned.h>
++#include <linux/interrupt.h>
+ #include <linux/iio/common/st_sensors.h>
+@@ -442,6 +444,217 @@ ssize_t st_sensors_sysfs_scale_avail(struct device *dev,
+ }
+ EXPORT_SYMBOL(st_sensors_sysfs_scale_avail);
++static struct st_sensor_event *st_sensor_find_event_data(struct
++              st_sensor_data * sdata, u64 event_code)
++{
++      int i;
++      int mod = IIO_EVENT_CODE_EXTRACT_MODIFIER(event_code);
++      int type = IIO_EVENT_CODE_EXTRACT_TYPE(event_code);
++      int chan_type = IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code);
++      int dir = IIO_EVENT_CODE_EXTRACT_DIR(event_code);
++      struct st_sensor_event_irq *irq = &sdata->sensor->event_irq;
++      struct st_sensor_event *event;
++
++      if (irq->event_count == 0)
++              return NULL;
++
++      for (i = 0; i < irq->event_count; i++) {
++              event = &irq->events[i];
++
++              if (event->modifier == mod &&
++                      event->event_type == type &&
++                      event->direction == dir &&
++                      event->chan_type == chan_type)
++                              return event;
++      }
++
++      return NULL;
++}
++
++int st_sensors_read_event_config(struct iio_dev *indio_dev,
++                              u64 event_code)
++{
++      struct st_sensor_data *sdata  = iio_priv(indio_dev);
++      struct st_sensor_event *event =
++              st_sensor_find_event_data(sdata, event_code);
++
++      if (event)
++              return (bool)(sdata->events_flag & (1 << event->bit));
++
++      return -EINVAL;
++}
++EXPORT_SYMBOL(st_sensors_read_event_config);
++
++int st_sensors_write_event_config(struct iio_dev *indio_dev,
++                                u64 event_code,
++                                int state)
++{
++      struct st_sensor_data *sdata = iio_priv(indio_dev);
++      struct st_sensor_event *event =
++              st_sensor_find_event_data(sdata, event_code);
++      int unsigned mask;
++      int err = -EINVAL;
++
++      mutex_lock(&indio_dev->mlock);
++
++      if (!event)
++              goto error;
++
++      mask = (1 << event->bit);
++      err =  st_sensors_write_data_with_mask(indio_dev,
++                      sdata->sensor->event_irq.ctrl_reg.addr,
++                      mask, (bool)state);
++      if (err < 0)
++              goto error;
++
++      if (state)
++              sdata->events_flag |= mask;
++      else
++              sdata->events_flag &= ~mask;
++
++      mutex_unlock(&indio_dev->mlock);
++
++      return 0;
++
++error:
++      mutex_unlock(&indio_dev->mlock);
++      return err;
++}
++EXPORT_SYMBOL(st_sensors_write_event_config);
++
++int st_sensors_read_event_value(struct iio_dev *indio_dev,
++                                u64 event_code,
++                                int *val)
++{
++      struct st_sensor_data *sdata = iio_priv(indio_dev);
++      struct st_sensor_event *event =
++              st_sensor_find_event_data(sdata, event_code);
++      u8 byte;
++      int err;
++
++      if (!event)
++              goto error;
++
++      mutex_lock(&indio_dev->mlock);
++
++      err = sdata->tf->read_byte(&sdata->tb, sdata->dev,
++                      event->event_ths_reg.addr, &byte);
++      if (!err)
++              *val = byte;
++
++      mutex_unlock(&indio_dev->mlock);
++      return err;
++
++error:
++      return -EINVAL;
++
++}
++EXPORT_SYMBOL(st_sensors_read_event_value);
++
++int st_sensors_write_event_value(struct iio_dev *indio_dev,
++                                u64 event_code,
++                                int val)
++{
++      struct st_sensor_data *sdata = iio_priv(indio_dev);
++      struct st_sensor_event *event =
++              st_sensor_find_event_data(sdata, event_code);
++      int err;
++
++      if (!event)
++              goto error;
++
++      mutex_lock(&indio_dev->mlock);
++
++      err =  st_sensors_write_data_with_mask(indio_dev,
++                      event->event_ths_reg.addr,
++                      event->event_ths_reg.mask,
++                      (u8)val);
++
++      mutex_unlock(&indio_dev->mlock);
++
++      return err;
++error:
++      return -EINVAL;
++
++}
++EXPORT_SYMBOL(st_sensors_write_event_value);
++
++static irqreturn_t st_sensor_event_handler(int irq, void *private)
++{
++      struct iio_dev *indio_dev = private;
++      struct st_sensor_data *sdata = iio_priv(indio_dev);
++      struct st_sensor_event_irq *irq_data =
++              &sdata->sensor->event_irq;
++      struct st_sensor_event *event;
++      s64 timestamp = iio_get_time_ns();
++      u8 status, mask, i;
++      int err = -EIO;
++
++      if (sdata)
++              err = sdata->tf->read_byte(&sdata->tb,
++                              sdata->dev,
++                              irq_data->status_reg.addr,
++                              &status);
++
++      if (err < 0)
++              goto exit;
++
++      for (i = 0; i < irq_data->event_count; i++) {
++              event = &irq_data->events[i];
++              mask = (1 << event->bit);
++              if (status & mask)
++                      iio_push_event(indio_dev,
++                              IIO_MOD_EVENT_CODE(event->chan_type,
++                                      0,
++                                      event->modifier,
++                                      event->event_type,
++                                      event->direction),
++                              timestamp);
++      }
++
++exit:
++
++      return IRQ_HANDLED;
++}
++
++int st_sensors_request_event_irq(struct iio_dev *indio_dev)
++{
++      int err;
++      struct st_sensor_data *sdata = iio_priv(indio_dev);
++
++      err = request_threaded_irq(sdata->get_irq_event(indio_dev),
++                      NULL,
++                      st_sensor_event_handler,
++                      IRQF_TRIGGER_RISING | IRQF_ONESHOT,
++                      dev_name(&indio_dev->dev),
++                      indio_dev);
++
++      return err;
++}
++
++int st_sensors_enable_events(struct iio_dev *indio_dev)
++{
++      int err;
++      struct st_sensor_data *sdata = iio_priv(indio_dev);
++      struct st_sensor_event_irq *irq = &sdata->sensor->event_irq;
++
++      err = st_sensors_write_data_with_mask(indio_dev,
++                      irq->addr,
++                      irq->mask,
++                      1);
++
++      if (err < 0)
++              goto error;
++
++      err = st_sensors_write_data_with_mask(indio_dev,
++                      irq->ctrl_reg.addr,
++                      irq->ctrl_reg.mask,
++                      irq->ctrl_reg.val);
++error:
++      return err;
++}
++EXPORT_SYMBOL(st_sensors_enable_events);
++
+ MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
+ MODULE_DESCRIPTION("STMicroelectronics ST-sensors core");
+ MODULE_LICENSE("GPL v2");
+diff --git a/drivers/iio/common/st_sensors/st_sensors_i2c.c b/drivers/iio/common/st_sensors/st_sensors_i2c.c
+index 5ef7682..0ab9b90 100644
+--- a/drivers/iio/common/st_sensors/st_sensors_i2c.c
++++ b/drivers/iio/common/st_sensors/st_sensors_i2c.c
+@@ -27,6 +27,13 @@ static unsigned int st_sensors_i2c_get_data_rdy_irq(struct iio_dev *indio_dev)
+       return sdata->irq_map[ST_SENSORS_INT1];
+ }
++static unsigned int st_sensors_i2c_get_event_irq(struct iio_dev *indio_dev)
++{
++      struct st_sensor_data *sdata = iio_priv(indio_dev);
++
++      return sdata->irq_map[ST_SENSORS_INT2];
++}
++
+ static void st_sensors_i2c_map_irqs(struct i2c_client *client,
+               struct iio_dev *indio_dev)
+ {
+@@ -99,6 +106,7 @@ void st_sensors_i2c_configure(struct iio_dev *indio_dev,
+       st_sensors_i2c_map_irqs(client, indio_dev);
+       sdata->get_irq_data_ready = st_sensors_i2c_get_data_rdy_irq;
++      sdata->get_irq_event = st_sensors_i2c_get_event_irq;
+ }
+ EXPORT_SYMBOL(st_sensors_i2c_configure);
+diff --git a/drivers/iio/common/st_sensors/st_sensors_spi.c b/drivers/iio/common/st_sensors/st_sensors_spi.c
+index 69c7069..b4a03f6 100644
+--- a/drivers/iio/common/st_sensors/st_sensors_spi.c
++++ b/drivers/iio/common/st_sensors/st_sensors_spi.c
+@@ -28,6 +28,13 @@ static unsigned int st_sensors_spi_get_data_rdy_irq(struct iio_dev *indio_dev)
+       return sdata->irq_map[ST_SENSORS_INT1];
+ }
++static unsigned int st_sensors_spi_get_event_irq(struct iio_dev *indio_dev)
++{
++      struct st_sensor_data *sdata = iio_priv(indio_dev);
++
++      return sdata->irq_map[ST_SENSORS_INT2];
++}
++
+ static void st_sensors_spi_map_irqs(struct spi_device *spi,
+               struct iio_dev *indio_dev)
+ {
+@@ -140,6 +147,7 @@ void st_sensors_spi_configure(struct iio_dev *indio_dev,
+       st_sensors_spi_map_irqs(spi, indio_dev);
+       sdata->get_irq_data_ready = st_sensors_spi_get_data_rdy_irq;
++      sdata->get_irq_event = st_sensors_spi_get_event_irq;
+ }
+ EXPORT_SYMBOL(st_sensors_spi_configure);
+diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h
+index 2fd12a6..45862fc 100644
+--- a/include/linux/iio/common/st_sensors.h
++++ b/include/linux/iio/common/st_sensors.h
+@@ -14,6 +14,7 @@
+ #include <linux/i2c.h>
+ #include <linux/spi/spi.h>
+ #include <linux/irqreturn.h>
++#include <linux/iio/events.h>
+ #include <linux/iio/trigger.h>
+ #include <linux/bitops.h>
+@@ -22,6 +23,7 @@
+ #define ST_SENSORS_ODR_LIST_MAX                       10
+ #define ST_SENSORS_FULLSCALE_AVL_MAX          10
++#define ST_SENSORS_EVENTS_MAX                 10
+ #define ST_SENSORS_NUMBER_ALL_CHANNELS                4
+ #define ST_SENSORS_NUMBER_DATA_CHANNELS               3
+@@ -48,6 +50,9 @@
+ #define ST_SENSORS_MAP_ONLY_DRDY_IRQ          1
+ #define ST_SENSORS_MAP_ONLY_EVENT_IRQ         2
++#define ST_SENSORS_LSM_EVENTS_MASK \
++              (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | \
++              IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING))
+ #define ST_SENSORS_LSM_CHANNELS(device_type, index, mod, endian, bits, addr) \
+ { \
+@@ -56,6 +61,7 @@
+       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+                       BIT(IIO_CHAN_INFO_SCALE), \
+       .scan_index = index, \
++      .channel = mod, \
+       .channel2 = mod, \
+       .address = addr, \
+       .scan_type = { \
+@@ -65,6 +71,7 @@
+               .storagebits = 16, \
+               .endianness = endian, \
+       }, \
++      .event_mask = ST_SENSORS_LSM_EVENTS_MASK, \
+ }
+ #define ST_SENSOR_DEV_ATTR_SAMP_FREQ() \
+@@ -116,6 +123,12 @@ struct st_sensor_fullscale {
+       struct st_sensor_fullscale_avl fs_avl[ST_SENSORS_FULLSCALE_AVL_MAX];
+ };
++struct st_sensor_register {
++      u8 addr;
++      u8 mask;
++      u8 val;
++};
++
+ /**
+  * struct st_sensor_bdu - ST sensor device block data update
+  * @addr: address of the register.
+@@ -144,6 +157,47 @@ struct st_sensor_data_ready_irq {
+ };
+ /**
++ * struct st_sensor_event - event data.
++ * @bit: position of bit in status register related to event
++ * @chan: channel number.
++ * @chan_type: channel type.
++ * @modifier: modifier for the channel.
++ * @event_type: type of the event.
++ * @direction: direction of the event.
++ * @event_ths_reg:  represents the threshold
++ *    register of event.
++ */
++struct st_sensor_event {
++      u8 bit;
++      u8 chan;
++      enum iio_chan_type chan_type;
++      enum iio_modifier modifier;
++      enum iio_event_type event_type;
++      enum iio_event_direction direction;
++      struct st_sensor_register event_ths_reg;
++};
++
++/**
++ * struct st_sensor_event_irq -ST sensor event interrupt.
++ * @addr: address of the interrupt register.
++ * @mask: mask to write on/off value.
++ * @event_count: number of events declared in @events array.
++ * @ctrl_reg: represents the control register
++ *    of event system
++ * @status_reg: status register of event subsystem.
++ * @events array: of driver events declared by user
++ */
++struct st_sensor_event_irq {
++      u8 addr;
++      u8 mask;
++      u8 event_count;
++      struct st_sensor_register ctrl_reg;
++      struct st_sensor_register status_reg;
++      struct st_sensor_event events[ST_SENSORS_EVENTS_MAX];
++};
++
++
++/**
+  * struct st_sensor_transfer_buffer - ST sensor device I/O buffer
+  * @buf_lock: Mutex to protect rx and tx buffers.
+  * @tx_buf: Buffer used by SPI transfer function to send data to the sensors.
+@@ -184,6 +238,7 @@ struct st_sensor_transfer_function {
+  * @fs: Full scale register and full scale list available.
+  * @bdu: Block data update register.
+  * @drdy_irq: Data ready register of the sensor.
++ * @event_irq: Event register of the sensor
+  * @multi_read_bit: Use or not particular bit for [I2C/SPI] multi-read.
+  * @bootime: samples to discard when sensor passing from power-down to power-up.
+  */
+@@ -197,6 +252,7 @@ struct st_sensors {
+       struct st_sensor_fullscale fs;
+       struct st_sensor_bdu bdu;
+       struct st_sensor_data_ready_irq drdy_irq;
++      struct st_sensor_event_irq event_irq;
+       bool multi_read_bit;
+       unsigned int bootime;
+ };
+@@ -211,8 +267,10 @@ struct st_sensors {
+  * @multiread_bit: Use or not particular bit for [I2C/SPI] multiread.
+  * @buffer_data: Data used by buffer part.
+  * @odr: Output data rate of the sensor [Hz].
++ * @events_flag: Data used by event part.
+  * @irq_map: Container of mapped IRQs.
+  * @get_irq_data_ready: Function to get the IRQ used for data ready signal.
++ * @get_irq_event: Function to get the IRQ used for event signal.
+  * @tf: Transfer function structure used by I/O operations.
+  * @tb: Transfer buffers and mutex used by I/O operations.
+  */
+@@ -228,9 +286,11 @@ struct st_sensor_data {
+       char *buffer_data;
+       unsigned int odr;
++      unsigned int events_flag;
+       unsigned int irq_map[ST_SENSORS_INT_MAX];
+       unsigned int (*get_irq_data_ready) (struct iio_dev *indio_dev);
++      unsigned int (*get_irq_event) (struct iio_dev *indio_dev);
+       const struct st_sensor_transfer_function *tf;
+       struct st_sensor_transfer_buffer tb;
+@@ -290,4 +350,19 @@ ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev,
+ ssize_t st_sensors_sysfs_scale_avail(struct device *dev,
+                               struct device_attribute *attr, char *buf);
++int st_sensors_read_event_config(struct iio_dev *indio_dev,
++                              u64 event_code);
++
++int st_sensors_write_event_config(struct iio_dev *indio_dev,
++                                u64 event_code, int state);
++
++int st_sensors_read_event_value(struct iio_dev *indio_dev,
++                                u64 event_code, int *val);
++
++int st_sensors_write_event_value(struct iio_dev *indio_dev,
++                                u64 event_code, int val);
++
++int st_sensors_request_event_irq(struct iio_dev *indio_dev);
++
++int st_sensors_enable_events(struct iio_dev *indio_dev);
+ #endif /* ST_SENSORS_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0263-iio-accel-Add-event-subsystem-to-st_accel-driver.patch b/patches.tizen/0263-iio-accel-Add-event-subsystem-to-st_accel-driver.patch
new file mode 100644 (file)
index 0000000..85fa5cc
--- /dev/null
@@ -0,0 +1,245 @@
+From dfae0691539a5a2daa064eccd21ac10baf7b5c08 Mon Sep 17 00:00:00 2001
+From: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Date: Fri, 24 May 2013 14:17:48 +0200
+Subject: [PATCH 0263/1302] iio: accel Add event subsystem to st_accel driver
+
+This patch adds event support for iio st_accel driver.
+
+Signed-off-by: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iio/accel/st_accel_core.c | 148 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 148 insertions(+)
+
+diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
+index e0f5a3c..523b009 100644
+--- a/drivers/iio/accel/st_accel_core.c
++++ b/drivers/iio/accel/st_accel_core.c
+@@ -19,6 +19,7 @@
+ #include <linux/gpio.h>
+ #include <linux/irq.h>
+ #include <linux/iio/iio.h>
++#include <linux/iio/events.h>
+ #include <linux/iio/sysfs.h>
+ #include <linux/iio/trigger.h>
+ #include <linux/iio/buffer.h>
+@@ -65,6 +66,20 @@
+ #define ST_ACCEL_1_DRDY_IRQ_ADDR              0x22
+ #define ST_ACCEL_1_DRDY_IRQ_MASK              0x10
+ #define ST_ACCEL_1_MULTIREAD_BIT              true
++#define ST_ACCEL_1_EVENT_IRQ_ADDR             0x22
++#define ST_ACCEL_1_EVENT_IRQ_MASK             0x40
++#define ST_ACCEL_1_EVENT_CTRL_REG             0x30
++#define ST_ACCEL_1_EVENT_CTRL_MASK            0xc0
++#define ST_ACCEL_1_EVENT_CTRL_DEFAULT_VAL     0x01
++#define ST_ACCEL_1_THS_REG                    0x32
++#define ST_ACCEL_1_EVENT_STATUS_REG           0x31
++#define ST_ACCEL_1_EVENT_STATUS_REG_MASK      0x7f
++#define ST_ACCEL_1_INT1_XL                    0
++#define ST_ACCEL_1_INT1_XH                    1
++#define ST_ACCEL_1_INT1_YL                    2
++#define ST_ACCEL_1_INT1_YH                    3
++#define ST_ACCEL_1_INT1_ZL                    4
++#define ST_ACCEL_1_INT1_ZH                    5
+ /* CUSTOM VALUES FOR SENSOR 2 */
+ #define ST_ACCEL_2_WAI_EXP                    0x32
+@@ -89,6 +104,20 @@
+ #define ST_ACCEL_2_DRDY_IRQ_ADDR              0x22
+ #define ST_ACCEL_2_DRDY_IRQ_MASK              0x02
+ #define ST_ACCEL_2_MULTIREAD_BIT              true
++#define ST_ACCEL_2_EVENT_IRQ_ADDR             0x22
++#define ST_ACCEL_2_EVENT_IRQ_MASK             0x01
++#define ST_ACCEL_2_EVENT_CTRL_REG             0x30
++#define ST_ACCEL_2_EVENT_CTRL_MASK            0xc0
++#define ST_ACCEL_2_EVENT_CTRL_DEFAULT_VAL     0x01
++#define ST_ACCEL_2_THS_REG                    0x32
++#define ST_ACCEL_2_EVENT_STATUS_REG           0x31
++#define ST_ACCEL_2_EVENT_STATUS_REG_MASK      0x7f
++#define ST_ACCEL_2_INT1_XL                    0
++#define ST_ACCEL_2_INT1_XH                    1
++#define ST_ACCEL_2_INT1_YL                    2
++#define ST_ACCEL_2_INT1_YH                    3
++#define ST_ACCEL_2_INT1_ZL                    4
++#define ST_ACCEL_2_INT1_ZH                    5
+ /* CUSTOM VALUES FOR SENSOR 3 */
+ #define ST_ACCEL_3_WAI_EXP                    0x40
+@@ -124,6 +153,20 @@
+ #define ST_ACCEL_3_IG1_EN_MASK                        0x08
+ #define ST_ACCEL_3_MULTIREAD_BIT              false
++#define ST_SENSORS_LSM_ACCEL_EVENT(ch, mod, dir, bit_pos, ths_reg) \
++{ \
++      .bit = bit_pos,\
++      .chan = ch, \
++      .chan_type = IIO_ACCEL, \
++      .modifier = mod, \
++      .event_type = IIO_EV_TYPE_THRESH, \
++      .direction = dir, \
++      .event_ths_reg = { \
++              .addr = ths_reg, \
++              .mask = 0x7f, \
++      }, \
++}
++
+ static const struct iio_chan_spec st_accel_12bit_channels[] = {
+       ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, ST_SENSORS_SCAN_X, IIO_MOD_X, IIO_LE,
+               ST_SENSORS_DEFAULT_12_REALBITS, ST_ACCEL_DEFAULT_OUT_X_L_ADDR),
+@@ -214,6 +257,46 @@ static const struct st_sensors st_accel_sensors[] = {
+               },
+               .multi_read_bit = ST_ACCEL_1_MULTIREAD_BIT,
+               .bootime = 2,
++              .event_irq = {
++                      .addr = ST_ACCEL_1_EVENT_IRQ_ADDR,
++                      .mask = ST_ACCEL_1_EVENT_IRQ_MASK,
++                      .event_count = 6,
++                      .ctrl_reg = {
++                              .addr = ST_ACCEL_1_EVENT_CTRL_REG,
++                              .mask = ST_ACCEL_1_EVENT_CTRL_MASK,
++                              .val = ST_ACCEL_1_EVENT_CTRL_DEFAULT_VAL,
++                      },
++                      .status_reg = {
++                              .addr = ST_ACCEL_1_EVENT_STATUS_REG,
++                              .mask = ST_ACCEL_1_EVENT_STATUS_REG_MASK,
++                      },
++                      .events = {
++                              ST_SENSORS_LSM_ACCEL_EVENT(0, IIO_MOD_X,
++                                              IIO_EV_DIR_FALLING,
++                                              ST_ACCEL_1_INT1_XL,
++                                              ST_ACCEL_1_THS_REG),
++                              ST_SENSORS_LSM_ACCEL_EVENT(0, IIO_MOD_X,
++                                              IIO_EV_DIR_RISING,
++                                              ST_ACCEL_1_INT1_XH,
++                                              ST_ACCEL_1_THS_REG),
++                              ST_SENSORS_LSM_ACCEL_EVENT(1, IIO_MOD_Y,
++                                              IIO_EV_DIR_FALLING,
++                                              ST_ACCEL_1_INT1_YL,
++                                              ST_ACCEL_1_THS_REG),
++                              ST_SENSORS_LSM_ACCEL_EVENT(1, IIO_MOD_Y,
++                                              IIO_EV_DIR_RISING,
++                                              ST_ACCEL_1_INT1_YH,
++                                              ST_ACCEL_1_THS_REG),
++                              ST_SENSORS_LSM_ACCEL_EVENT(2, IIO_MOD_Z,
++                                              IIO_EV_DIR_FALLING,
++                                              ST_ACCEL_1_INT1_ZL,
++                                              ST_ACCEL_1_THS_REG),
++                              ST_SENSORS_LSM_ACCEL_EVENT(2, IIO_MOD_Z,
++                                              IIO_EV_DIR_RISING,
++                                              ST_ACCEL_1_INT1_ZH,
++                                              ST_ACCEL_1_THS_REG),
++                      },
++              },
+       },
+       {
+               .wai = ST_ACCEL_2_WAI_EXP,
+@@ -275,6 +358,47 @@ static const struct st_sensors st_accel_sensors[] = {
+               },
+               .multi_read_bit = ST_ACCEL_2_MULTIREAD_BIT,
+               .bootime = 2,
++              .event_irq = {
++                      .addr = ST_ACCEL_2_EVENT_IRQ_ADDR,
++                      .mask = ST_ACCEL_2_EVENT_IRQ_MASK,
++                      .event_count = 6,
++                      .ctrl_reg = {
++                              .addr = ST_ACCEL_2_EVENT_CTRL_REG,
++                              .mask = ST_ACCEL_2_EVENT_CTRL_MASK,
++                              .val = ST_ACCEL_2_EVENT_CTRL_DEFAULT_VAL,
++                      },
++                      .status_reg = {
++                              .addr = ST_ACCEL_2_EVENT_STATUS_REG,
++                              .mask = ST_ACCEL_2_EVENT_STATUS_REG_MASK,
++                      },
++                      .events = {
++                              ST_SENSORS_LSM_ACCEL_EVENT(0, IIO_MOD_X,
++                                              IIO_EV_DIR_FALLING,
++                                              ST_ACCEL_2_INT1_XL,
++                                              ST_ACCEL_2_THS_REG),
++                              ST_SENSORS_LSM_ACCEL_EVENT(0, IIO_MOD_X,
++                                              IIO_EV_DIR_RISING,
++                                              ST_ACCEL_2_INT1_XH,
++                                              ST_ACCEL_2_THS_REG),
++                              ST_SENSORS_LSM_ACCEL_EVENT(1, IIO_MOD_Y,
++                                              IIO_EV_DIR_FALLING,
++                                              ST_ACCEL_2_INT1_YL,
++                                              ST_ACCEL_2_THS_REG),
++                              ST_SENSORS_LSM_ACCEL_EVENT(1, IIO_MOD_Y,
++                                              IIO_EV_DIR_RISING,
++                                              ST_ACCEL_2_INT1_YH,
++                                              ST_ACCEL_2_THS_REG),
++                              ST_SENSORS_LSM_ACCEL_EVENT(2, IIO_MOD_Z,
++                                              IIO_EV_DIR_FALLING,
++                                              ST_ACCEL_2_INT1_ZL,
++                                              ST_ACCEL_2_THS_REG),
++                              ST_SENSORS_LSM_ACCEL_EVENT(2, IIO_MOD_Z,
++                                              IIO_EV_DIR_RISING,
++                                              ST_ACCEL_2_INT1_ZH,
++                                              ST_ACCEL_2_THS_REG),
++                      },
++              },
++
+       },
+       {
+               .wai = ST_ACCEL_3_WAI_EXP,
+@@ -417,6 +541,10 @@ static const struct iio_info accel_info = {
+       .attrs = &st_accel_attribute_group,
+       .read_raw = &st_accel_read_raw,
+       .write_raw = &st_accel_write_raw,
++      .read_event_value = &st_sensors_read_event_value,
++      .write_event_value = &st_sensors_write_event_value,
++      .read_event_config = &st_sensors_read_event_config,
++      .write_event_config = &st_sensors_write_event_config,
+ };
+ #ifdef CONFIG_IIO_TRIGGER
+@@ -432,6 +560,7 @@ static const struct iio_trigger_ops st_accel_trigger_ops = {
+ int st_accel_common_probe(struct iio_dev *indio_dev)
+ {
+       int err;
++      int i;
+       struct st_sensor_data *adata = iio_priv(indio_dev);
+       indio_dev->modes = INDIO_DIRECT_MODE;
+@@ -465,6 +594,19 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
+                       goto st_accel_probe_trigger_error;
+       }
++      if (adata->get_irq_event(indio_dev) > 0) {
++              err = st_sensors_request_event_irq(indio_dev);
++              if (err < 0)
++                      goto st_accel_request_irq_event_error;
++
++              err = st_sensors_enable_events(indio_dev);
++              if (err < 0)
++                      goto st_accel_enable_events_error;
++      } else {
++              for (i = 0; i < indio_dev->num_channels; i++)
++                      adata->sensor->ch[i].event_mask = 0;
++      }
++
+       err = iio_device_register(indio_dev);
+       if (err)
+               goto st_accel_device_register_error;
+@@ -474,6 +616,10 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
+ st_accel_device_register_error:
+       if (adata->get_irq_data_ready(indio_dev) > 0)
+               st_sensors_deallocate_trigger(indio_dev);
++st_accel_enable_events_error:
++      if (adata->get_irq_event(indio_dev) > 0)
++              free_irq(adata->get_irq_event(indio_dev), indio_dev);
++st_accel_request_irq_event_error:
+ st_accel_probe_trigger_error:
+       if (adata->get_irq_data_ready(indio_dev) > 0)
+               st_accel_deallocate_ring(indio_dev);
+@@ -491,6 +637,8 @@ void st_accel_common_remove(struct iio_dev *indio_dev)
+               st_sensors_deallocate_trigger(indio_dev);
+               st_accel_deallocate_ring(indio_dev);
+       }
++      if (adata->get_irq_event(indio_dev) > 0)
++              free_irq(adata->get_irq_event(indio_dev), indio_dev);
+       iio_device_free(indio_dev);
+ }
+ EXPORT_SYMBOL(st_accel_common_remove);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0264-ARM-dts-exnos4412-redwood.dts-Add-lsm330dlc-node-for.patch b/patches.tizen/0264-ARM-dts-exnos4412-redwood.dts-Add-lsm330dlc-node-for.patch
new file mode 100644 (file)
index 0000000..05bbdb8
--- /dev/null
@@ -0,0 +1,71 @@
+From 59a032170d84df8a6359362b4cfe035f564bfe8a Mon Sep 17 00:00:00 2001
+From: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Date: Mon, 17 Jun 2013 09:09:22 +0200
+Subject: [PATCH 0264/1302] ARM: dts: exnos4412-redwood.dts: Add lsm330dlc node
+ for redwood
+
+Signed-off-by: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-redwood.dts | 45 ++++++++++++++++++++++++++++++++
+ 1 file changed, 45 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-redwood.dts b/arch/arm/boot/dts/exynos4412-redwood.dts
+index 3712c14..74b70a9 100644
+--- a/arch/arm/boot/dts/exynos4412-redwood.dts
++++ b/arch/arm/boot/dts/exynos4412-redwood.dts
+@@ -173,6 +173,51 @@
+               };
+       };
++      i2c@13870000 {
++              samsung,i2c-sda-delay = <100>;
++              samsung,i2c-slave-addr = <0x10>;
++              samsung,i2c-max-bus-freq = <400000>;
++              pinctrl-0 = <&i2c1_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              lsm330dlc_gyro@6b {
++                      compatible = "st,lsm330dlc-gyro";
++                      reg = <0x6b>;
++                      irq-map-policy = <1>;
++                      interrupt-controller;
++                      #interrups-cells = <2>;
++                      interrupt-parent = <&lsm330dlc_gyro_map>;
++                      interrupts= <1 0>;
++
++                      lsm330dlc_gyro_map: lsm330dlc-gyro-map {
++                              compatible = "samsung,lsm330dlc-gyro-map";
++                              #interrupt-cells = <2>;
++                              #address-cells = <0>;
++                              #size-cells = <0>;
++                              interrupt-map = <0x1 0 &gpf0 3 0>;
++                      };
++              };
++
++              lsm330dlc_accel@19 {
++                      compatible = "st,lsm330dlc-accel";
++                      reg = <0x19>;
++                      irq-map-policy = <2>;
++                      interrupt-controller;
++                      #interrups-cells = <2>;
++                      interrupt-parent = <&lsm330dlc_accel_map>;
++                      interrupts= <1 0>;
++
++                      lsm330dlc_accel_map: lsm330dlc-accel-map {
++                              compatible = "samsung,lsm330dlc-accel-map";
++                              #interrupt-cells = <2>;
++                              #address-cells = <0>;
++                              #size-cells = <0>;
++                              interrupt-map = <0x1 0 &gpx0 0 0>;
++                      };
++              };
++      };
++
+       i2c@13890000 {
+               samsung,i2c-sda-delay = <100>;
+               samsung,i2c-slave-addr = <0x10>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0265-ARM-dts-exynos-slp_pq.dts-Add-lsm330dlc-node-for-slp.patch b/patches.tizen/0265-ARM-dts-exynos-slp_pq.dts-Add-lsm330dlc-node-for-slp.patch
new file mode 100644 (file)
index 0000000..d65b447
--- /dev/null
@@ -0,0 +1,71 @@
+From a3d53e0e67cf8eb6bbbd285b9ba67dbe3835d1d2 Mon Sep 17 00:00:00 2001
+From: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Date: Mon, 17 Jun 2013 09:14:23 +0200
+Subject: [PATCH 0265/1302] ARM: dts: exynos-slp_pq.dts: Add lsm330dlc node for
+ slp_pq
+
+Signed-off-by: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 45 +++++++++++++++++++++++++++++++++
+ 1 file changed, 45 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index c052fc0..c6a543b 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -215,6 +215,51 @@
+               };
+       };
++      i2c@13870000 {
++              samsung,i2c-sda-delay = <100>;
++              samsung,i2c-slave-addr = <0x10>;
++              samsung,i2c-max-bus-freq = <400000>;
++              pinctrl-0 = <&i2c1_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              lsm330dlc_gyro@6b {
++                      compatible = "st,lsm330dlc-gyro";
++                      reg = <0x6b>;
++                      irq-map-policy = <1>;
++                      interrupt-controller;
++                      #interrups-cells = <2>;
++                      interrupt-parent = <&lsm330dlc_gyro_map>;
++                      interrupts= <1 0>;
++
++                      lsm330dlc_gyro_map: lsm330dlc-gyro-map {
++                              compatible = "samsung,lsm330dlc-gyro-map";
++                              #interrupt-cells = <2>;
++                              #address-cells = <0>;
++                              #size-cells = <0>;
++                              interrupt-map = <0x1 0 &gpf0 3 0>;
++                      };
++              };
++
++              lsm330dlc_accel@19 {
++                      compatible = "st,lsm330dlc-accel";
++                      reg = <0x19>;
++                      irq-map-policy = <2>;
++                      interrupt-controller;
++                      #interrups-cells = <2>;
++                      interrupt-parent = <&lsm330dlc_accel_map>;
++                      interrupts= <1 0>;
++
++                      lsm330dlc_accel_map: lsm330dlc-accel-map {
++                              compatible = "samsung,lsm330dlc-accel-map";
++                              #interrupt-cells = <2>;
++                              #address-cells = <0>;
++                              #size-cells = <0>;
++                              interrupt-map = <0x1 0 &gpx0 0 0>;
++                      };
++              };
++      };
++
+       i2c@13890000 {
+               samsung,i2c-sda-delay = <100>;
+               samsung,i2c-slave-addr = <0x10>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0266-ARM-dts-enable-sd-card.patch b/patches.tizen/0266-ARM-dts-enable-sd-card.patch
new file mode 100644 (file)
index 0000000..e92d215
--- /dev/null
@@ -0,0 +1,38 @@
+From 376a2908c1c5c89ea457d7a9109f0bf05e8a67c9 Mon Sep 17 00:00:00 2001
+From: Jaehoon Chung <jh80.chung@samsung.com>
+Date: Thu, 20 Jun 2013 13:39:35 +0900
+Subject: [PATCH 0266/1302] ARM: dts: enable sd-card
+
+In oreder to use the SD-card, enabled the sd-card into devicetree.
+
+Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index c6a543b..d274e36 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -98,6 +98,17 @@
+               status = "okay";
+       };
++      sdhci_sd: sdhci@12530000 {
++              bus-width = <4>;
++              cd-gpios = <&gpx3 4 0>;
++              cd-inverted;
++              interrupts = <0 75 0>;
++              pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4>;
++              pinctrl-names = "default";
++              vmmc-supply = <&ldo21_reg>;
++              status = "okay";
++      };
++
+       serial@13800000 {
+               status = "okay";
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0267-iio-Add-driver-for-the-LPS331AP-barometer-sensor.patch b/patches.tizen/0267-iio-Add-driver-for-the-LPS331AP-barometer-sensor.patch
new file mode 100644 (file)
index 0000000..bdac1c0
--- /dev/null
@@ -0,0 +1,1390 @@
+From 527ea6d2bb301d25b4fd54ce4b8d1e2c7fac9193 Mon Sep 17 00:00:00 2001
+From: Jacek Anaszewski <j.anaszewski@samsung.com>
+Date: Fri, 21 Jun 2013 10:52:31 +0200
+Subject: [PATCH 0267/1302] iio: Add driver for the LPS331AP barometer sensor
+
+Add new driver for the barometer device. The driver is
+compliant with IIO framework, and exposes two channels
+for reading the pressure and the temperature. The output
+data can be read either in 'one shot' mode or by exploiting
+IIO events.
+
+Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
+Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/iio/barometer/lps331ap.txt |   40 +
+ drivers/iio/Kconfig                                |    1 +
+ drivers/iio/Makefile                               |    1 +
+ drivers/iio/barometer/Kconfig                      |   12 +
+ drivers/iio/barometer/Makefile                     |    7 +
+ drivers/iio/barometer/lps331ap.c                   | 1252 ++++++++++++++++++++
+ 6 files changed, 1313 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/iio/barometer/lps331ap.txt
+ create mode 100644 drivers/iio/barometer/Kconfig
+ create mode 100644 drivers/iio/barometer/Makefile
+ create mode 100644 drivers/iio/barometer/lps331ap.c
+
+diff --git a/Documentation/devicetree/bindings/iio/barometer/lps331ap.txt b/Documentation/devicetree/bindings/iio/barometer/lps331ap.txt
+new file mode 100644
+index 0000000..f0e44bc
+--- /dev/null
++++ b/Documentation/devicetree/bindings/iio/barometer/lps331ap.txt
+@@ -0,0 +1,40 @@
++* STMicroelectronics LPS331AP barometer sensor
++
++Required properties:
++
++  - compatible : should be "st,lps331ap"
++  - reg : the I2C address of the barometer
++
++Optional properties:
++
++  - interrupt-parent : phandle to the interrupt map subnode
++  - interrupts : interrupt mapping for LPS331AP interrupt sources:
++               2 sources: 0 - INT1, 1 - INT2
++  - irq-map : irq sub-node defining interrupt map
++              (all properties listed below are required):
++      - #interrupt-cells : should be 1
++      - #address-cells : should be 0
++      - #size-cells : should be 0
++      - interrupt-map : table of entries consisting of three child elements:
++          - unit_interrupt_specifier - 0 : INT1, 1 : INT2
++          - interrupt parent phandle
++          - parent unit interrupt specifier consisiting of two elements:
++              - index of the interrupt within the controller
++              - flags : should be 0
++
++Example:
++
++lps331ap@5d {
++      compatible = "lps331ap";
++      reg = <0x5d>;
++      interrupt-parent = <&irq_map>;
++      interrupts = <0>, <1>;
++
++      irq_map: irq-map {
++              #interrupt-cells = <1>;
++              #address-cells = <0>;
++              #size-cells = <0>;
++              interrupt-map = <0 &gpf0 5 0>,
++                              <1 &gpx0 3 0>;
++      };
++};
+diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig
+index b2f963b..edf69ff 100644
+--- a/drivers/iio/Kconfig
++++ b/drivers/iio/Kconfig
+@@ -63,6 +63,7 @@ config IIO_CONSUMERS_PER_TRIGGER
+ source "drivers/iio/accel/Kconfig"
+ source "drivers/iio/adc/Kconfig"
+ source "drivers/iio/amplifiers/Kconfig"
++source "drivers/iio/barometer/Kconfig"
+ source "drivers/iio/common/Kconfig"
+ source "drivers/iio/dac/Kconfig"
+ source "drivers/iio/frequency/Kconfig"
+diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile
+index a0e8cdd..cfcc812 100644
+--- a/drivers/iio/Makefile
++++ b/drivers/iio/Makefile
+@@ -14,6 +14,7 @@ obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o
+ obj-y += accel/
+ obj-y += adc/
+ obj-y += amplifiers/
++obj-y += barometer/
+ obj-y += common/
+ obj-y += dac/
+ obj-y += gyro/
+diff --git a/drivers/iio/barometer/Kconfig b/drivers/iio/barometer/Kconfig
+new file mode 100644
+index 0000000..927c06c
+--- /dev/null
++++ b/drivers/iio/barometer/Kconfig
+@@ -0,0 +1,12 @@
++#
++# Magnetometer sensors
++#
++menu "Barometer sensors"
++
++config SENSORS_LPS331
++        tristate "STMicro LPS331 driver"
++        depends on I2C
++        help
++          Driver for STMicro LPS331
++
++endmenu
+diff --git a/drivers/iio/barometer/Makefile b/drivers/iio/barometer/Makefile
+new file mode 100644
+index 0000000..8beba1c
+--- /dev/null
++++ b/drivers/iio/barometer/Makefile
+@@ -0,0 +1,7 @@
++#
++# Makefile for the sensors drivers.
++#
++
++# Each configuration option enables a list of files.
++
++obj-$(CONFIG_SENSORS_LPS331)            += lps331ap.o
+diff --git a/drivers/iio/barometer/lps331ap.c b/drivers/iio/barometer/lps331ap.c
+new file mode 100644
+index 0000000..1e7cf07
+--- /dev/null
++++ b/drivers/iio/barometer/lps331ap.c
+@@ -0,0 +1,1252 @@
++/*
++* STMicroelectronics LPS331AP Pressure / Temperature Sensor module driver
++*
++* Copyright (C) 2013 Samsung Electronics Co., Ltd.
++* Author: Jacek Anaszewski <j.anaszewski@samsung.com>
++*
++* Copyright (C) 2010 STMicroelectronics- MSH - Motion Mems BU - Application Team
++* Authors:
++*     Matteo Dameno <matteo.dameno@st.com>
++*     Carmine Iascone <carmine.iascone@st.com>
++*
++* Both authors are willing to be considered the contact and update points for
++* the driver.
++*
++* The device can be controlled by IIO sysfs interface from the location
++* /sys/bus/iio/devices/iio:deviceN, where N is the variable IIO device
++* number. The LPS331AP device can be identified by reading the 'name'
++* attribute.
++* Output data from the device can be read in two ways - on demand and by
++* initiating IIO events for the device. The former mode allows for power
++* saving as it instructs the device to do a 'one shot' measurement and return
++* to the power down mode, whereas the latter enables cyclic measurements
++* with the period managed through the 'odr' attribute, where possible settings
++* are: 40ms, 80ms, 143ms and 1000ms. The value has to be given in miliseconds.
++* Every integer value is accepted - the driver will round it to the nearest
++* bottom odr setting.
++*
++* Initialization of 'one shot' measurement:
++*     - read in_pressure_raw or in_temp_raw sysfs attribute
++* Managing cyclic measurements:
++*     1) enable:
++*             - write 1 to the events/in_pressure_mag_either_en and/or
++*               events/in_temp_mag_either_en attribute
++*     2) read:
++*             - perform periodic read of events/in_pressure_mag_either_value
++*               and/or events/in_temp_mag_either_value atrributes
++*     3) alter output data rate:
++*             - write value of 40, 80, 143 or 1000 to the 'odr' attribute
++*     1) disable:
++*             - write 0 to the events/in_pressure_mag_either_en and/or
++*               events/in_temp_mag_either_en attribute
++*
++* Read pressures and temperatures output can be converted in units of
++* measurement by dividing them respectively by in_pressure_scale and
++* in_temp_scale. Temperature values must then be added by the constant float
++* in_temp_offset expressed as Celsius degrees.
++*
++* Obtained values are then expessed as
++* mbar (=0.1 kPa) and Celsius degrees.
++*
++* This program is free software; you can redistribute it and/or
++* modify it under the terms of the GNU General Public License
++* version 2 as published by the Free Software Foundation.
++*
++* This program is distributed in the hope that it will be useful, but
++* WITHOUT ANY WARRANTY; without even the implied warranty of
++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++* General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
++* 02110-1301 USA
++*/
++
++#include <linux/module.h>
++#include <linux/ratelimit.h>
++#include <linux/err.h>
++#include <linux/errno.h>
++#include <linux/delay.h>
++#include <linux/i2c.h>
++#include <linux/interrupt.h>
++#include <linux/gpio.h>
++#include <linux/of_gpio.h>
++#include <linux/of_irq.h>
++#include <linux/device.h>
++#include <linux/kernel.h>
++#include <linux/iio/iio.h>
++#include <linux/iio/sysfs.h>
++#include <linux/iio/events.h>
++#include <linux/bitops.h>
++
++#define LPS331AP_VENDOR               "STM"
++#define LPS331AP_CHIP_ID              "LPS331"
++
++#define PR_ABS_MAX    8388607 /* 24 bit 2'compl */
++#define PR_ABS_MIN    -8388608
++
++#define WHOAMI_LPS331AP_PRS   0xBB    /* Expected content for WAI */
++
++/* Control registers */
++#define REF_P_XL      0x08    /*      pressure reference      */
++#define REF_P_L               0x09    /*      pressure reference      */
++#define REF_P_H               0x0a    /*      pressure reference      */
++#define REF_T_L               0x0b    /*      temperature reference   */
++#define REF_T_H               0x0c    /*      temperature reference   */
++
++#define WHO_AM_I      0x0f    /*      WhoAmI register         */
++#define TP_RESOL      0x10    /*      Pres Temp resolution set */
++#define DGAIN_L               0x18    /*      Dig Gain (3 regs)       */
++
++#define CTRL_REG1     0x20    /*      power / ODR control reg */
++#define CTRL_REG2     0x21    /*      boot reg                */
++#define CTRL_REG3     0x22    /*      interrupt control reg   */
++#define INT_CFG_REG   0x23    /*      2nterrupt config reg    */
++#define INT_SRC_REG   0x24    /*      interrupt source reg    */
++#define THS_P_L               0x25    /*      pressure threshold      */
++#define THS_P_H               0x26    /*      pressure threshold      */
++#define STATUS_REG    0X27    /*      status reg              */
++
++#define PRESS_OUT_XL  0x28    /*      press output (3 regs)   */
++#define TEMP_OUT_L    0x2b    /*      temper output (2 regs)  */
++#define DELTAREG_1    0x3c    /*      deltaPressure reg1       */
++#define DELTAREG_2    0x3d    /*      deltaPressure reg2       */
++#define DELTAREG_3    0x3e    /*      deltaPressure reg3       */
++
++/* Register aliases */
++#define P_REF_INDATA_REG      REF_P_XL
++#define T_REF_INDATA_REG      REF_T_L
++#define P_THS_INDATA_REG      THS_P_L
++#define P_OUTDATA_REG         PRESS_OUT_XL
++#define T_OUTDATA_REG         TEMP_OUT_L
++#define OUTDATA_REG           PRESS_OUT_XL
++
++/* Register masks */
++#define LPS331AP_PRS_ENABLE_MASK      0x80    /*  ctrl_reg1 */
++#define LPS331AP_PRS_ODR_MASK         0x70    /*  ctrl_reg1 */
++#define LPS331AP_PRS_DIFF_MASK                0x08    /*  ctrl_reg1 */
++#define LPS331AP_PRS_BDU_MASK         0x04    /*  ctrl_reg1 */
++#define LPS331AP_PRS_DELTA_EN_MASK    0x02    /*  ctrl_reg1 */
++#define LPS331AP_PRS_BOOT_MASK                0x80    /*  ctrl_reg2 */
++#define LPS331AP_PRS_SWRESET_MASK     0x04    /*  ctrl_reg2 */
++#define LPS331AP_PRS_AUTOZ_MASK               0x02    /*  ctrl_reg2 */
++#define LPS331AP_PRS_ONE_SHOT         0x01    /*  ctrl_reg2 */
++#define LPS331AP_PRS_INT1_MASK                0x07    /*  ctrl_reg3 */
++#define LPS331AP_PRS_INT2_MASK                0x38    /*  ctrl_reg3 */
++#define LPS331AP_PRS_PP_OD_MASK               0x40    /*  ctrl_reg3 */
++
++#define LPS331AP_PRS_PM_NORMAL                0x80    /* Power Normal Mode */
++#define LPS331AP_PRS_PM_OFF           0x00    /* Power Down */
++
++#define LPS331AP_PRS_DIFF_ON          0x08    /* En Difference circuitry */
++#define LPS331AP_PRS_DIFF_OFF         0x00    /* Dis Difference circuitry */
++
++#define LPS331AP_PRS_AUTOZ_ON         0x02    /* En AutoZero Function */
++#define LPS331AP_PRS_AUTOZ_OFF                0x00    /* Dis Difference Function */
++
++#define LPS331AP_PRS_BDU_ON           0x04    /* En BDU Block Data Upd */
++#define LPS331AP_PRS_DELTA_EN_ON      0x02    /* En Delta Press registers */
++#define LPS331AP_PRS_DIFF_EN          0x08    /* En diff pressure computing */
++#define LPS331AP_PRS_RES_AVGTEMP_064  0x60
++#define LPS331AP_PRS_RES_AVGTEMP_128  0x70
++#define LPS331AP_PRS_RES_AVGPRES_512  0x0a
++#define LPS331AP_PRS_RES_AVGPRES_384  0x09
++
++#define LPS331AP_PRS_RES_MAX          (LPS331AP_PRS_RES_AVGTEMP_128  | \
++                                              LPS331AP_PRS_RES_AVGPRES_512)
++                                              /* Max Resol. for 1/7/12,5Hz */
++
++#define LPS331AP_PRS_RES_25HZ         (LPS331AP_PRS_RES_AVGTEMP_128  | \
++                                              LPS331AP_PRS_RES_AVGPRES_384)
++                                              /* Max Resol. for 25Hz */
++#define LPS331AP_PRS_DRDY_INT1                0x04    /* En INT1 'data ready' */
++#define LPS331AP_PRS_DRDY_INT2                0x20    /* En INT2 'data ready' */
++#define LPS331AP_PRS_P_HIGH_INT1      0x01    /* En INT1 P_high */
++#define LPS331AP_PRS_P_HIGH_INT2      0x08    /* En INT2 P_high */
++#define LPS331AP_PRS_P_LOW_INT1               0x02    /* En INT1 P_low */
++#define LPS331AP_PRS_P_LOW_INT2               0x10    /* En INT2 P_low */
++#define LPS331AP_PRS_PH_E             0x01    /* En prs high evt interrupt */
++#define LPS331AP_PRS_PL_E             0x02    /* En prs low evt interrupt */
++
++#define LPS331AP_PRS_INT_FLAG_PH      0x01    /* Diff press high int flag */
++#define LPS331AP_PRS_INT_FLAG_PL      0x02    /* Diff press low int flag */
++#define LPS331AP_PRS_INT_FLAG_IA      0x04    /* Any int flag */
++
++#define LPS331AP_PRESS_SCALE          4096
++#define LPS331AP_TEMP_SCALE           480
++#define LPS331AP_TEMP_OFFSET_INT      42
++#define LPS331AP_TEMP_OFFSET_FRACT    500000
++
++#define I2C_AUTO_INCREMENT            0x80
++
++/* Register cache indices */
++#define LPS331AP_RES_REF_P_XL         0
++#define LPS331AP_RES_REF_P_L          1
++#define LPS331AP_RES_REF_P_H          2
++#define LPS331AP_RES_REF_T_L          3
++#define LPS331AP_RES_REF_T_H          4
++#define LPS331AP_RES_TP_RESOL         5
++#define LPS331AP_RES_CTRL_REG1                6
++#define LPS331AP_RES_CTRL_REG2                7
++#define LPS331AP_RES_CTRL_REG3                8
++#define LPS331AP_RES_INT_CFG_REG      9
++#define LPS331AP_RES_THS_P_L          10
++#define LPS331AP_RES_THS_P_H          11
++#define REG_ENTRIES                   12
++
++/* Poll delays */
++#define LPS331AP_ODR_DELAY_DEFAULT    200
++#define LPS331AP_ODR_DELAY_MINIMUM    40
++#define LPS331AP_DATA_READY_TIMEOUT   (HZ * 2)
++#define LPS331AP_DATA_READY_POLL_TIME 10
++
++#define LPS331AP_PRS_DEV_NAME         "lps331ap"
++
++/* Barometer and Termometer output data rate (ODR) */
++#define LPS331AP_PRS_ODR_ONESH        0x00    /* one shot both                */
++#define LPS331AP_PRS_ODR_1_1  0x10    /*  1  Hz baro,  1  Hz term ODR */
++#define LPS331AP_PRS_ODR_7_7  0x50    /*  7  Hz baro,  7  Hz term ODR */
++#define LPS331AP_PRS_ODR_12_12        0x60    /* 12.5Hz baro, 12.5Hz term ODR */
++#define LPS331AP_PRS_ODR_25_25        0x70    /* 25  Hz baro, 25  Hz term ODR */
++
++enum {
++      LPS331AP_LPS331AP_VENDOR,
++      LPS331AP_NAME,
++      LPS331AP_ODR,
++      LPS331AP_PRESSURE_REF_LEVEL,
++};
++
++enum {
++      LPS331AP_INTERRUPT_SRC_NONE,
++      LPS331AP_INTERRUPT_SRC_INT1,
++      LPS331AP_INTERRUPT_SRC_INT2
++};
++
++enum prs_state {
++      FL_HW_ENABLED,
++      FL_HW_INITIALIZED,
++      FL_PRESS_EV_ENABLED,
++      FL_TEMP_EV_ENABLED
++};
++
++static const struct {
++      unsigned int cutoff_ms;
++      unsigned int mask;
++} lps331ap_odr_table[] = {
++      { 40, LPS331AP_PRS_ODR_25_25 },
++      { 80, LPS331AP_PRS_ODR_12_12 },
++      { 143, LPS331AP_PRS_ODR_7_7 },
++      { 1000, LPS331AP_PRS_ODR_1_1 }
++};
++
++struct outputdata {
++      unsigned int press;
++      int temperature;
++};
++
++struct lps331ap_data {
++      struct i2c_client *client;
++      struct mutex lock;
++      struct outputdata press_temp;
++
++      unsigned int output_data_rate;
++      unsigned long flags;
++      u8 reg_cache[REG_ENTRIES];
++
++      int lps_irq;
++      int lps_irq_src;
++};
++
++static int lps331ap_i2c_read(struct lps331ap_data *prs,
++                                              u8 *buf, int len)
++{
++      int err;
++      struct i2c_msg msgs[] = {
++              {
++                      .addr = prs->client->addr,
++                      .flags = prs->client->flags & I2C_M_TEN,
++                      .len = 1,
++                      .buf = buf,
++              },
++              {
++                      .addr = prs->client->addr,
++                      .flags = (prs->client->flags & I2C_M_TEN) | I2C_M_RD,
++                      .len = len,
++                      .buf = buf,
++              },
++      };
++
++      err = i2c_transfer(prs->client->adapter, msgs, 2);
++      if (err != 2) {
++              dev_err(&prs->client->dev, "read transfer error = %d\n", err);
++              err = -EIO;
++      }
++      return err;
++}
++
++static int lps331ap_i2c_write(struct lps331ap_data *prs,
++                                              u8 *buf, int len)
++{
++      int err;
++      struct i2c_msg msgs[] = {
++              {
++                      .addr = prs->client->addr,
++                      .flags = prs->client->flags & I2C_M_TEN,
++                      .len = len + 1,
++                      .buf = buf,
++              },
++      };
++
++      err = i2c_transfer(prs->client->adapter, msgs, 1);
++      if (err != 1) {
++              dev_err(&prs->client->dev, "write transfer error\n");
++              err = -EIO;
++      }
++      return err;
++}
++
++static int lps331ap_hw_init(struct lps331ap_data *prs)
++{
++      int err;
++      u8 buf[6];
++
++      dev_dbg(&prs->client->dev, "hw init start\n");
++
++      buf[0] = WHO_AM_I;
++      err = lps331ap_i2c_read(prs, buf, 1);
++      if (err < 0) {
++              dev_err(&prs->client->dev,
++              "error reading WHO_AM_I: is device available/working?\n");
++              goto err_hw_init;
++      }
++
++      if (buf[0] != WHOAMI_LPS331AP_PRS) {
++              err = -ENODEV;
++              dev_err(&prs->client->dev,
++                      "device unknown. Expected: 0x%02x, Replies: 0x%02x\n",
++                      WHOAMI_LPS331AP_PRS, buf[0]);
++              goto err_hw_init;
++      }
++
++      buf[0] = (I2C_AUTO_INCREMENT | P_REF_INDATA_REG);
++      buf[1] = prs->reg_cache[LPS331AP_RES_REF_P_XL];
++      buf[2] = prs->reg_cache[LPS331AP_RES_REF_P_L];
++      buf[3] = prs->reg_cache[LPS331AP_RES_REF_P_H];
++      buf[4] = prs->reg_cache[LPS331AP_RES_REF_T_L];
++      buf[5] = prs->reg_cache[LPS331AP_RES_REF_T_H];
++      err = lps331ap_i2c_write(prs, buf, 5);
++      if (err < 0)
++              goto err_hw_init;
++
++      buf[0] = TP_RESOL;
++      buf[1] = prs->reg_cache[LPS331AP_RES_TP_RESOL];
++      err = lps331ap_i2c_write(prs, buf, 1);
++      if (err < 0)
++              goto err_hw_init;
++
++      buf[0] = (I2C_AUTO_INCREMENT | P_THS_INDATA_REG);
++      buf[1] = prs->reg_cache[LPS331AP_RES_THS_P_L];
++      buf[2] = prs->reg_cache[LPS331AP_RES_THS_P_H];
++      err = lps331ap_i2c_write(prs, buf, 2);
++      if (err < 0)
++              goto err_hw_init;
++
++      /* clear INT_ACK flag */
++      buf[0] = INT_SRC_REG;
++      err = lps331ap_i2c_read(prs, buf, 1);
++      if (err < 0)
++              return err;
++
++      /* CTRL_REG3 register has to be initialized before powering on */
++      buf[0] = CTRL_REG3;
++      buf[1] = prs->reg_cache[LPS331AP_RES_CTRL_REG3];
++      err = lps331ap_i2c_write(prs, buf, 1);
++      if (err < 0)
++              goto err_hw_init;
++
++      buf[0] = (I2C_AUTO_INCREMENT | CTRL_REG1);
++      buf[1] = prs->reg_cache[LPS331AP_RES_CTRL_REG1];
++      buf[2] = prs->reg_cache[LPS331AP_RES_CTRL_REG2];
++      err = lps331ap_i2c_write(prs, buf, 2);
++      if (err < 0)
++              goto err_hw_init;
++
++      set_bit(FL_HW_INITIALIZED, &prs->flags);
++      dev_dbg(&prs->client->dev, "hw init done\n");
++
++      return 0;
++
++err_hw_init:
++      clear_bit(FL_HW_INITIALIZED, &prs->flags);
++      dev_err(&prs->client->dev, "hw init error 0x%02x,0x%02x: %d\n",
++              buf[0], buf[1], err);
++      return err;
++}
++
++static int lps331ap_device_power_off(struct lps331ap_data *prs)
++{
++      int err;
++      u8 buf[2];
++
++      prs->reg_cache[LPS331AP_RES_CTRL_REG1]
++          &= ~LPS331AP_PRS_PM_NORMAL;
++
++      buf[0] = CTRL_REG1;
++      buf[1] = prs->reg_cache[LPS331AP_RES_CTRL_REG1];
++
++      err = lps331ap_i2c_write(prs, buf, 1);
++      if (err < 0)
++              return err;
++
++      return 0;
++}
++
++static int lps331ap_device_power_on(struct lps331ap_data *prs)
++{
++      u8 buf[2];
++      int err;
++
++      prs->reg_cache[LPS331AP_RES_CTRL_REG1] |= LPS331AP_PRS_PM_NORMAL;
++
++      if (!test_bit(FL_HW_INITIALIZED, &prs->flags)) {
++              err = lps331ap_hw_init(prs);
++              lps331ap_device_power_off(prs);
++      } else {
++              buf[0] = CTRL_REG1;
++              buf[1] = prs->reg_cache[LPS331AP_RES_CTRL_REG1];
++              err = lps331ap_i2c_write(prs, buf, 1);
++      }
++
++      return err;
++}
++
++static int lps331ap_update_odr(struct lps331ap_data *prs, int delay_ms)
++{
++      int err = -1;
++      int i;
++
++      u8 buf[2];
++      u8 init_val, updated_val;
++      u8 curr_val, new_val;
++      u8 mask = LPS331AP_PRS_ODR_MASK;
++      u8 resol = LPS331AP_PRS_RES_MAX;
++
++      /*
++       * Following, looks for the longest possible odr interval scrolling the
++       * odr_table vector from the end (longest period) backward (shortest
++       * period), to support the poll_interval requested by the system.
++       * It must be the longest period shorter then the set poll period.
++       */
++      for (i = ARRAY_SIZE(lps331ap_odr_table) - 1; i >= 0; i--) {
++              if ((lps331ap_odr_table[i].cutoff_ms <= delay_ms)
++                  || (i == 0))
++                      break;
++      }
++
++      prs->output_data_rate = lps331ap_odr_table[i].cutoff_ms;
++
++      new_val = lps331ap_odr_table[i].mask;
++      if (new_val == LPS331AP_PRS_ODR_25_25)
++              resol = LPS331AP_PRS_RES_25HZ;
++
++      if (!test_bit(FL_HW_ENABLED, &prs->flags))
++              return 0;
++
++      buf[0] = CTRL_REG1;
++      err = lps331ap_i2c_read(prs, buf, 1);
++      if (err < 0)
++              goto error;
++      /* work on all but ENABLE bits */
++      init_val = buf[0];
++      prs->reg_cache[LPS331AP_RES_CTRL_REG1] = init_val;
++
++      /* disable */
++      curr_val = ((LPS331AP_PRS_ENABLE_MASK & LPS331AP_PRS_PM_OFF)
++                  | ((~LPS331AP_PRS_ENABLE_MASK) & init_val));
++      buf[0] = CTRL_REG1;
++      buf[1] = curr_val;
++      err = lps331ap_i2c_write(prs, buf, 1);
++      if (err < 0)
++              goto error;
++
++      buf[0] = CTRL_REG1;
++      updated_val = ((mask & new_val) | ((~mask) & curr_val));
++
++      buf[0] = CTRL_REG1;
++      buf[1] = updated_val;
++      err = lps331ap_i2c_write(prs, buf, 1);
++      if (err < 0)
++              goto error;
++
++      /* enable */
++      curr_val = ((LPS331AP_PRS_ENABLE_MASK & LPS331AP_PRS_PM_NORMAL)
++                  | ((~LPS331AP_PRS_ENABLE_MASK) & updated_val));
++      buf[0] = CTRL_REG1;
++      buf[1] = curr_val;
++      err = lps331ap_i2c_write(prs, buf, 1);
++      if (err < 0)
++              goto error;
++
++      buf[0] = TP_RESOL;
++      buf[1] = resol;
++      err = lps331ap_i2c_write(prs, buf, 1);
++      if (err < 0)
++              goto error;
++
++      prs->reg_cache[LPS331AP_RES_CTRL_REG1] = curr_val;
++      prs->reg_cache[LPS331AP_RES_TP_RESOL] = resol;
++
++      return err;
++
++error:
++      dev_err(&prs->client->dev, "update odr failed 0x%02x,0x%02x: %d\n",
++              buf[0], buf[1], err);
++
++      return err;
++}
++
++static int lps331ap_set_press_reference(struct lps331ap_data *prs,
++                                               s32 new_reference)
++{
++      u8 buf[4], *ref;
++      __le32 new_ref;
++      int err;
++
++      new_ref = cpu_to_le32(new_reference);
++      ref = (u8 *)&new_ref;
++
++      buf[0] = (I2C_AUTO_INCREMENT | P_REF_INDATA_REG);
++      buf[1] = ref[0];
++      buf[2] = ref[1];
++      buf[3] = ref[2];
++
++      err = lps331ap_i2c_write(prs, buf, 3);
++      if (err < 0)
++              return err;
++
++      prs->reg_cache[LPS331AP_RES_REF_P_XL] = ref[0];
++      prs->reg_cache[LPS331AP_RES_REF_P_L] = ref[1];
++      prs->reg_cache[LPS331AP_RES_REF_P_H] = ref[2];
++
++      return 0;
++}
++
++static int lps331ap_get_press_reference(struct lps331ap_data *prs,
++                                                      s32 *reference)
++{
++      u8 buf[4];
++      int err;
++
++      memset(buf, 0, sizeof(buf));
++      buf[0] = (I2C_AUTO_INCREMENT | P_REF_INDATA_REG);
++      err = lps331ap_i2c_read(prs, buf, 3);
++
++      if (err < 0)
++              return err;
++
++      *reference = le32_to_cpup((__le32 *) buf);
++
++      return 0;
++}
++
++static int lps331ap_enable(struct lps331ap_data *prs)
++{
++      int err;
++
++      if (!test_bit(FL_HW_ENABLED, &prs->flags)) {
++              err = lps331ap_device_power_on(prs);
++              if (err < 0) {
++                      clear_bit(FL_HW_ENABLED, &prs->flags);
++                      return err;
++              }
++              set_bit(FL_HW_ENABLED, &prs->flags);
++      }
++
++      return 0;
++}
++
++static int lps331ap_disable(struct lps331ap_data *prs)
++{
++      int err;
++
++      if (!test_bit(FL_HW_ENABLED, &prs->flags))
++              return 0;
++
++      err = lps331ap_device_power_off(prs);
++      clear_bit(FL_HW_ENABLED, &prs->flags);
++
++      return err;
++}
++
++static int lps331ap_get_presstemp_data(struct lps331ap_data *prs,
++                                              struct outputdata *out)
++{
++      /*
++       * Data bytes from hardware:
++       * PRESS_OUT_XL, PRESS_OUT_L, PRESS_OUT_H,
++       * TEMP_OUT_L, TEMP_OUT_H.
++       */
++      u8 prs_data[5] = { 0, };
++      int err = 0;
++
++      s32 pressure = 0;
++      s16 temperature = 0;
++
++      int reg_to_read = 5;
++
++      prs_data[0] = (I2C_AUTO_INCREMENT | OUTDATA_REG);
++      err = lps331ap_i2c_read(prs, prs_data, reg_to_read);
++      if (err < 0)
++              return err;
++
++      dev_dbg(&prs->client->dev,
++              "temp out tH = 0x%02x, tL = 0x%02x",
++              prs_data[4], prs_data[3]);
++      dev_dbg(&prs->client->dev,
++              "press_out: pH = 0x%02x, pL = 0x%02x, pXL= 0x%02x\n",
++              prs_data[2], prs_data[1], prs_data[0]);
++
++      pressure = (s32) ((((s8) prs_data[2]) << 16) |
++                        (prs_data[1] << 8) | (prs_data[0]));
++      temperature = (s16) ((((s8) prs_data[4]) << 8) | (prs_data[3]));
++
++      out->press = pressure;
++      out->temperature = temperature;
++
++      return 0;
++}
++
++static ssize_t lps331ap_get_press_ref(struct device *dev,
++                              struct device_attribute *attr, char *buf)
++{
++      struct iio_dev *dev_info = dev_to_iio_dev(dev);
++      struct lps331ap_data *prs = iio_priv(dev_info);
++      s32 val;
++      int err;
++
++      mutex_lock(&prs->lock);
++      err = lps331ap_get_press_reference(prs, &val);
++      mutex_unlock(&prs->lock);
++      if (err < 0)
++              return err;
++
++      return sprintf(buf, "%d\n", val);
++}
++
++static ssize_t lps331ap_set_press_ref(struct device *dev,
++                     struct device_attribute *attr,
++                     const char *buf, size_t size)
++{
++      struct iio_dev *dev_info = dev_to_iio_dev(dev);
++      struct lps331ap_data *prs = iio_priv(dev_info);
++      long val;
++      int err;
++
++      if (kstrtol(buf, 10, &val))
++              return -EINVAL;
++
++      if (val < PR_ABS_MIN || val > PR_ABS_MAX)
++              return -EINVAL;
++
++      mutex_lock(&prs->lock);
++      err = lps331ap_set_press_reference(prs, val);
++      mutex_unlock(&prs->lock);
++
++      return err < 0 ? err : size;
++}
++static ssize_t lps331ap_get_odr(struct device *dev,
++                              struct device_attribute *attr, char *buf)
++{
++      int val;
++      struct iio_dev *dev_info = dev_to_iio_dev(dev);
++      struct lps331ap_data *prs = iio_priv(dev_info);
++
++      mutex_lock(&prs->lock);
++      val = prs->output_data_rate;
++      mutex_unlock(&prs->lock);
++
++      return sprintf(buf, "%d\n", val);
++}
++
++static ssize_t lps331ap_set_odr(struct device *dev,
++               struct device_attribute *attr, const char *buf, size_t size)
++{
++      struct iio_dev *dev_info = dev_to_iio_dev(dev);
++      struct lps331ap_data *prs = iio_priv(dev_info);
++      unsigned long delay_ms = 0;
++      unsigned int delay_min = LPS331AP_ODR_DELAY_MINIMUM;
++
++      if (kstrtoul(buf, 10, &delay_ms))
++              return -EINVAL;
++      if (!delay_ms)
++              return -EINVAL;
++
++      dev_dbg(&prs->client->dev, "delay_ms passed = %ld\n", delay_ms);
++      delay_ms = max_t(unsigned int, (unsigned int)delay_ms, delay_min);
++
++      mutex_lock(&prs->lock);
++      prs->output_data_rate = delay_ms;
++      lps331ap_update_odr(prs, delay_ms);
++
++      if (delay_ms == LPS331AP_ODR_DELAY_MINIMUM)
++              dev_dbg(&prs->client->dev, "delay limited to 40ms\n");
++
++      mutex_unlock(&prs->lock);
++
++      return size;
++}
++
++static ssize_t lps331_vendor_show(struct device *dev,
++                              struct device_attribute *attr, char *buf)
++{
++      return sprintf(buf, "%s\n", LPS331AP_VENDOR);
++}
++
++static ssize_t lps331_name_show(struct device *dev,
++                              struct device_attribute *attr, char *buf)
++{
++      return sprintf(buf, "%s\n", LPS331AP_CHIP_ID);
++}
++
++static int lps331ap_wait_one_shot_ready_polled(struct iio_dev *indio_dev)
++{
++      struct lps331ap_data *prs = iio_priv(indio_dev);
++      u32 timeout_ms = LPS331AP_DATA_READY_TIMEOUT;
++      u8 buf;
++      int err;
++
++      /* Wait for the conversion to complete. */
++      while (timeout_ms) {
++              msleep(LPS331AP_DATA_READY_POLL_TIME);
++              buf = CTRL_REG2;
++              err = lps331ap_i2c_read(prs, &buf, 1);
++              if (err < 0)
++                      return err;
++              if (!(buf & LPS331AP_PRS_ONE_SHOT))
++                      break;
++              timeout_ms -= LPS331AP_DATA_READY_POLL_TIME;
++      }
++      if (!timeout_ms) {
++              dev_err(&prs->client->dev, "Conversion timeout occurred.\n");
++              return -ETIME;
++      }
++
++      return err;
++}
++
++static u8 get_drdy_reg_mask(struct lps331ap_data *prs)
++{
++      if (prs->lps_irq_src == LPS331AP_INTERRUPT_SRC_INT1)
++              return LPS331AP_PRS_DRDY_INT1;
++      else
++              return LPS331AP_PRS_DRDY_INT2;
++}
++
++static int lps331ap_read_presstemp(struct iio_dev *indio_dev, int index,
++                                      int *val)
++{
++      struct lps331ap_data *prs = iio_priv(indio_dev);
++      u8 drdy_reg_mask;
++      int enabled;
++      char buf[2], curr_odr;
++      int err;
++
++      mutex_lock(&prs->lock);
++
++      drdy_reg_mask = get_drdy_reg_mask(prs);
++      /*
++       * Set 'one shot' mode if either device is in power down mode
++       * or it is powered up but 'data ready' interrupt isn't enabled.
++       * If this condition evaluates to false then it means that the recent
++       * output is being cached periodically by 'data ready' interrupt
++       * handler, so we can return the cached value.
++       */
++      enabled = test_bit(FL_HW_ENABLED, &prs->flags);
++      if (!enabled ||
++          !(prs->reg_cache[LPS331AP_RES_CTRL_REG3] & drdy_reg_mask)) {
++              /* ensure device is in power down mode */
++              lps331ap_disable(prs);
++
++              /* set ODR configuration to 'one shot' */
++              curr_odr = prs->reg_cache[LPS331AP_RES_CTRL_REG1]
++                  & LPS331AP_PRS_ODR_MASK;
++              prs->reg_cache[LPS331AP_RES_CTRL_REG1]
++                  &= ~LPS331AP_PRS_ODR_MASK;
++              buf[0] = CTRL_REG1;
++              buf[1] = prs->reg_cache[LPS331AP_RES_CTRL_REG1];
++              err = lps331ap_i2c_write(prs, buf, 1);
++              if (err < 0)
++                      goto exit;
++
++              /* power on the device */
++              err = lps331ap_enable(prs);
++              if (err < 0)
++                      goto exit;
++
++              /* set ONE_SHOT mode */
++              buf[0] = CTRL_REG2;
++              buf[1] = prs->reg_cache[LPS331AP_RES_CTRL_REG2]
++                  | LPS331AP_PRS_ONE_SHOT;
++              err = lps331ap_i2c_write(prs, buf, 1);
++
++              if (err < 0)
++                      goto exit;
++
++              /* wait for the end of coversion */
++              err = lps331ap_wait_one_shot_ready_polled(indio_dev);
++              if (err < 0)
++                      goto exit;
++
++              /* read output data */
++              err = lps331ap_get_presstemp_data(prs, &prs->press_temp);
++              if (err < 0)
++                      goto exit;
++
++              /* bring back previous ODR settings */
++              prs->reg_cache[LPS331AP_RES_CTRL_REG1]
++                  |= curr_odr;
++              buf[0] = CTRL_REG1;
++              buf[1] = prs->reg_cache[LPS331AP_RES_CTRL_REG1];
++              err = lps331ap_i2c_write(prs, buf, 1);
++
++              if (!enabled)
++                      lps331ap_disable(prs);
++      }
++
++      *val = index == 0 ? prs->press_temp.press : prs->press_temp.temperature;
++
++      mutex_unlock(&prs->lock);
++
++      return IIO_VAL_INT;
++
++exit:
++      mutex_unlock(&prs->lock);
++      return -EINVAL;
++}
++
++static irqreturn_t lps331ap_irq_handler(int irq, void *data)
++{
++      struct iio_dev *indio_dev = data;
++      struct lps331ap_data *prs = iio_priv(indio_dev);
++      int err;
++
++      if (test_bit(FL_PRESS_EV_ENABLED, &prs->flags))
++              iio_push_event(indio_dev,
++                             IIO_UNMOD_EVENT_CODE(IIO_PRESSURE, 0,
++                                                  IIO_EV_TYPE_MAG,
++                                                  IIO_EV_DIR_EITHER),
++                             iio_get_time_ns());
++      if (test_bit(FL_TEMP_EV_ENABLED, &prs->flags))
++              iio_push_event(indio_dev,
++                             IIO_UNMOD_EVENT_CODE(IIO_TEMP, 1,
++                                                  IIO_EV_TYPE_MAG,
++                                                  IIO_EV_DIR_EITHER),
++                             iio_get_time_ns());
++
++      err = lps331ap_get_presstemp_data(prs, &prs->press_temp);
++      if (err < 0)
++              dev_err_ratelimited(&prs->client->dev,
++                                  "get_presstemp_data failed\n");
++
++      return IRQ_HANDLED;
++}
++
++static int lps331ap_setup_irq(struct iio_dev *indio_dev)
++{
++      struct lps331ap_data *prs = iio_priv(indio_dev);
++      struct i2c_client *client = prs->client;
++      int err;
++
++      err = request_threaded_irq(prs->lps_irq, NULL,
++                                 lps331ap_irq_handler,
++                                 IRQF_TRIGGER_RISING | IRQF_ONESHOT,
++                                 dev_name(&client->dev), indio_dev);
++      if (err < 0) {
++              dev_err(&client->dev,
++                      "irq %d request failed: %d\n",
++                      prs->lps_irq, err);
++              return err;
++      }
++
++      return 0;
++}
++
++static int lps331ap_read_raw(struct iio_dev *indio_dev,
++                struct iio_chan_spec const *chan,
++                int *val, int *val2, long mask)
++{
++      switch (mask) {
++      case IIO_CHAN_INFO_RAW:
++              return lps331ap_read_presstemp(indio_dev, chan->address, val);
++      case IIO_CHAN_INFO_SCALE:
++              switch (chan->type) {
++              case IIO_PRESSURE:
++                      *val = LPS331AP_PRESS_SCALE;
++                      return IIO_VAL_INT;
++              case IIO_TEMP:
++                      *val = LPS331AP_TEMP_SCALE;
++                      return IIO_VAL_INT;
++              default:
++                      return -EINVAL;
++              }
++      case IIO_CHAN_INFO_OFFSET:
++              /* Only the temperature channel has an offset. */
++              *val = LPS331AP_TEMP_OFFSET_INT;
++              *val2 = LPS331AP_TEMP_OFFSET_FRACT;
++              return IIO_VAL_INT_PLUS_MICRO;
++      }
++
++      return -EINVAL;
++}
++
++static int lps331ap_read_event_val(struct iio_dev *indio_dev, u64 event_code,
++                                      int *val)
++{
++      struct lps331ap_data *prs = iio_priv(indio_dev);
++      int chan_type = IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code);
++      int event_type = IIO_EVENT_CODE_EXTRACT_TYPE(event_code);
++      u8 drdy_reg_mask;
++
++      drdy_reg_mask = get_drdy_reg_mask(prs);
++
++      if (event_type == IIO_EV_TYPE_MAG) {
++              /*
++               * If events are enabled the output data is being
++               * cached in the interrupt handler and thus we
++               * can return it here.
++               */
++              if (prs->reg_cache[LPS331AP_RES_CTRL_REG3]
++                  & drdy_reg_mask)
++                      switch (chan_type) {
++                      case IIO_PRESSURE:
++                              *val = prs->press_temp.press;
++                              break;
++                      case IIO_TEMP:
++                              *val = prs->press_temp.temperature;
++                              break;
++              } else
++                      return -EINVAL;
++      }
++
++      return 0;
++}
++
++static int lps331ap_write_event_config(struct iio_dev *indio_dev,
++                          u64 event_code, int state)
++{
++      struct lps331ap_data *prs = iio_priv(indio_dev);
++      int event_type = IIO_EVENT_CODE_EXTRACT_TYPE(event_code);
++      int chan_type = IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code);
++      u8 ctrl_reg3 = prs->reg_cache[LPS331AP_RES_CTRL_REG3];
++      u8 drdy_reg_mask;
++      char buf[2];
++      enum prs_state event_state = (chan_type == IIO_PRESSURE) ?
++          FL_PRESS_EV_ENABLED : FL_TEMP_EV_ENABLED;
++      int err = 0;
++
++      if (prs->lps_irq_src == LPS331AP_INTERRUPT_SRC_NONE) {
++              dev_err(&prs->client->dev,
++                      "current platform doesn't support LPS331 interrupts\n");
++              return -EINVAL;
++      }
++
++      mutex_lock(&prs->lock);
++
++      drdy_reg_mask = get_drdy_reg_mask(prs);
++
++      if (state) {
++              /* Don't do anything if the event is already enabled. */
++              if (test_bit(event_state, &prs->flags))
++                      goto done;
++              switch (event_type) {
++              case IIO_EV_TYPE_MAG:
++                      ctrl_reg3 |= drdy_reg_mask;
++                      set_bit(event_state, &prs->flags);
++                      break;
++              default:
++                      goto err_unsupported_event_type;
++              }
++      } else {
++              switch (event_type) {
++              case IIO_EV_TYPE_MAG:
++                      clear_bit(event_state, &prs->flags);
++                      /*
++                       * Disable 'data ready' interrupt only if
++                       * there is no enabled event.
++                       */
++                      if (!test_bit(FL_PRESS_EV_ENABLED, &prs->flags) &&
++                          !test_bit(FL_TEMP_EV_ENABLED, &prs->flags))
++                              ctrl_reg3 &= ~drdy_reg_mask;
++                      break;
++              default:
++                      goto err_unsupported_event_type;
++              }
++      }
++
++      /* Setup new interrupt configuration. */
++      prs->reg_cache[LPS331AP_RES_CTRL_REG3] = ctrl_reg3;
++
++      buf[0] = CTRL_REG3;
++      buf[1] = prs->reg_cache[LPS331AP_RES_CTRL_REG3];
++      err = lps331ap_i2c_write(prs, buf, 1);
++      if (err < 0)
++              goto err_write_event_config;
++
++      /*
++       * The device should be powered on only
++       * if at least one event is enabled.
++       */
++      if (ctrl_reg3 & drdy_reg_mask) {
++              err = lps331ap_enable(prs);
++              if (err < 0)
++                      goto err_write_event_config;
++      } else {
++              err = lps331ap_disable(prs);
++              if (err < 0)
++                      goto err_write_event_config;
++      }
++
++      /* clear INT_ACK flag */
++      buf[0] = INT_SRC_REG;
++      err = lps331ap_i2c_read(prs, buf, 1);
++      if (err < 0)
++              goto err_write_event_config;
++done:
++      mutex_unlock(&prs->lock);
++
++      return 0;
++
++err_unsupported_event_type:
++      err = -EINVAL;
++      dev_err(&prs->client->dev, "unsupported event type\n");
++err_write_event_config:
++      clear_bit(event_state, &prs->flags);
++      mutex_unlock(&prs->lock);
++      dev_err(&prs->client->dev, "writing event config failed\n");
++
++      return err;
++}
++
++static int lps331ap_read_event_config(struct iio_dev *indio_dev,
++                                      u64 event_code)
++{
++      struct lps331ap_data *prs = iio_priv(indio_dev);
++      int event_type = IIO_EVENT_CODE_EXTRACT_TYPE(event_code);
++      int chan_type = IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code);
++      enum prs_state event_state = (chan_type == IIO_PRESSURE) ?
++          FL_PRESS_EV_ENABLED : FL_TEMP_EV_ENABLED;
++      int val;
++
++      if (prs->lps_irq_src == LPS331AP_INTERRUPT_SRC_NONE)
++              return -EINVAL;
++
++      switch (event_type) {
++      case IIO_EV_TYPE_MAG:
++              val = test_bit(event_state, &prs->flags);
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      return val;
++}
++
++static IIO_DEVICE_ATTR(odr, 0664,
++                     lps331ap_get_odr, lps331ap_set_odr, LPS331AP_ODR);
++static IIO_DEVICE_ATTR(pressure_reference_level, 0664,
++                     lps331ap_get_press_ref,
++                     lps331ap_set_press_ref, LPS331AP_PRESSURE_REF_LEVEL);
++static IIO_DEVICE_ATTR(vendor, 0644, lps331_vendor_show, NULL,
++                     LPS331AP_LPS331AP_VENDOR);
++static IIO_DEVICE_ATTR(name, 0644, lps331_name_show, NULL, LPS331AP_NAME);
++
++static struct attribute *lps331ap_attributes[] = {
++      &iio_dev_attr_vendor.dev_attr.attr,
++      &iio_dev_attr_name.dev_attr.attr,
++      &iio_dev_attr_odr.dev_attr.attr,
++      &iio_dev_attr_pressure_reference_level.dev_attr.attr,
++      NULL
++};
++
++static struct attribute_group lps331ap_attribute_group = {
++      .attrs = lps331ap_attributes,
++};
++
++#define LPS331AP_PRESSURE_CHANNEL(index)                      \
++      {                                                       \
++              .channel = index,                               \
++              .address = index,                               \
++              .type = IIO_PRESSURE,                           \
++              .modified = 0,                                  \
++              .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
++                           BIT(IIO_CHAN_INFO_SCALE),          \
++              .event_mask = IIO_EV_BIT(IIO_EV_TYPE_MAG,       \
++                                      IIO_EV_DIR_EITHER),     \
++      }
++
++#define LPS331AP_TEMP_CHANNEL(index)                          \
++      {                                                       \
++              .channel = index,                               \
++              .address = index,                               \
++              .type = IIO_TEMP,                               \
++              .modified = 0,                                  \
++              .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
++                           BIT(IIO_CHAN_INFO_SCALE) |         \
++                           BIT(IIO_CHAN_INFO_OFFSET),         \
++              .event_mask = IIO_EV_BIT(IIO_EV_TYPE_MAG,       \
++                                      IIO_EV_DIR_EITHER),     \
++      }
++
++static const struct iio_chan_spec lps331ap_channels[] = {
++      LPS331AP_PRESSURE_CHANNEL(0), LPS331AP_TEMP_CHANNEL(1),
++};
++
++static const struct iio_info lps331ap_info = {
++      .attrs = &lps331ap_attribute_group,
++      .read_raw = &lps331ap_read_raw,
++      .read_event_value = &lps331ap_read_event_val,
++      .read_event_config = &lps331ap_read_event_config,
++      .write_event_config = &lps331ap_write_event_config,
++      .driver_module = THIS_MODULE,
++};
++
++static int lps331ap_probe(struct i2c_client *client,
++                                      const struct i2c_device_id *id)
++{
++      struct lps331ap_data *prs;
++      struct iio_dev *indio_dev;
++      int int1_src, int2_src;
++      int err = -EINVAL;
++
++      indio_dev = iio_device_alloc(sizeof(struct lps331ap_data));
++      if (indio_dev == NULL)
++              return -ENOMEM;
++
++      prs = iio_priv(indio_dev);
++
++      if (client->dev.of_node) {
++              int1_src = irq_of_parse_and_map(client->dev.of_node, 0);
++              int2_src = irq_of_parse_and_map(client->dev.of_node, 1);
++
++              if (int1_src) {
++                      prs->lps_irq = int1_src;
++                      prs->lps_irq_src = LPS331AP_INTERRUPT_SRC_INT1;
++              } else if (int2_src) {
++                      prs->lps_irq = int2_src;
++                      prs->lps_irq_src = LPS331AP_INTERRUPT_SRC_INT2;
++              } else {
++                      prs->lps_irq_src = LPS331AP_INTERRUPT_SRC_NONE;
++              }
++      } else {
++              prs->lps_irq = -EINVAL;
++      }
++
++      prs->output_data_rate = LPS331AP_ODR_DELAY_DEFAULT;
++      prs->client = client;
++      mutex_init(&prs->lock);
++      indio_dev->dev.parent = &client->dev;
++      indio_dev->channels = lps331ap_channels;
++      indio_dev->num_channels = ARRAY_SIZE(lps331ap_channels);
++      indio_dev->info = &lps331ap_info;
++      indio_dev->modes = INDIO_DIRECT_MODE;
++
++      if (prs->lps_irq) {
++              err = lps331ap_setup_irq(indio_dev);
++              if (err < 0) {
++                      dev_err(&client->dev,
++                              "Error setting data ready interrupt\n");
++                      goto err_free_data;
++              }
++      }
++
++      i2c_set_clientdata(client, indio_dev);
++
++      memset(prs->reg_cache, 0, sizeof(prs->reg_cache));
++
++      /* Do not update output registers until MSB and LSB reading. */
++      prs->reg_cache[LPS331AP_RES_CTRL_REG1] = LPS331AP_PRS_BDU_ON;
++
++      /* Perform hw init. */
++      err = lps331ap_device_power_on(prs);
++      if (err < 0) {
++              dev_err(&client->dev, "power on failed: %d\n", err);
++              goto err_free_data;
++      }
++
++      set_bit(FL_HW_ENABLED, &prs->flags);
++
++      err = lps331ap_update_odr(prs, prs->output_data_rate);
++      if (err < 0) {
++              dev_err(&client->dev, "update_odr failed\n");
++              goto err_power_off;
++      }
++
++      lps331ap_device_power_off(prs);
++
++      clear_bit(FL_HW_ENABLED, &prs->flags);
++
++      err = iio_device_register(indio_dev);
++      if (err < 0)
++              goto err_free_data;
++
++      return 0;
++
++err_power_off:
++      lps331ap_device_power_off(prs);
++err_free_data:
++      if (prs->lps_irq)
++              free_irq(prs->lps_irq, indio_dev);
++      iio_device_free(indio_dev);
++
++      return err;
++}
++
++static int lps331ap_remove(struct i2c_client *client)
++{
++      struct iio_dev *indio_dev = i2c_get_clientdata(client);
++      struct lps331ap_data *prs = iio_priv(indio_dev);
++
++      if (prs->lps_irq)
++              free_irq(prs->lps_irq, indio_dev);
++
++      lps331ap_device_power_off(prs);
++
++      iio_device_unregister(indio_dev);
++      iio_device_free(indio_dev);
++
++      return 0;
++}
++
++static const struct i2c_device_id lps331ap_id[] = {
++      { LPS331AP_PRS_DEV_NAME, 0 },
++      { },
++};
++
++MODULE_DEVICE_TABLE(i2c, lps331ap_id);
++
++#ifdef CONFIG_OF
++static const struct of_device_id lps331ap_of_match[] = {
++      { .compatible = "st,lps331ap" },
++      { .compatible = "lps331ap" },
++      { }
++};
++#endif
++
++static struct i2c_driver lps331ap_driver = {
++      .driver = {
++              .name = LPS331AP_PRS_DEV_NAME,
++              .of_match_table = of_match_ptr(lps331ap_of_match),
++      },
++      .probe = lps331ap_probe,
++      .remove = lps331ap_remove,
++      .id_table = lps331ap_id,
++};
++
++module_i2c_driver(lps331ap_driver);
++
++MODULE_DESCRIPTION("STMicrolectronics LPS331AP pressure sensor IIO driver");
++MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
++MODULE_AUTHOR("Matteo Dameno, STMicroelectronic <matteo.dameno@st.com>");
++MODULE_AUTHOR("Carmine Iascone, STMicroelectronic <carmine.iascone@st.com>");
++MODULE_LICENSE("GPL");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0268-iio-Add-driver-for-the-gp2ap002a00f-light-proximity-.patch b/patches.tizen/0268-iio-Add-driver-for-the-gp2ap002a00f-light-proximity-.patch
new file mode 100644 (file)
index 0000000..a33c08b
--- /dev/null
@@ -0,0 +1,1249 @@
+From 707fd33eb66f97e04f1b980d642b7f9b32ba2317 Mon Sep 17 00:00:00 2001
+From: Jacek Anaszewski <j.anaszewski@samsung.com>
+Date: Mon, 17 Jun 2013 13:21:21 +0200
+Subject: [PATCH 0268/1302] iio: Add driver for the gp2ap002a00f
+ light/proximity sensor
+
+Add a new driver for the ambient light/proximity sensor
+device. The driver exposes three channels: light_clear
+light_ir and proximity. It also supports high and low
+ambient light threshold event and proximity detection
+event.
+
+Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/iio/light/gp2ap002a00f.txt |   20 +
+ drivers/iio/light/Kconfig                          |   12 +
+ drivers/iio/light/Makefile                         |    1 +
+ drivers/iio/light/gp2ap002a00f.c                   | 1158 ++++++++++++++++++++
+ 4 files changed, 1191 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/iio/light/gp2ap002a00f.txt
+ create mode 100644 drivers/iio/light/gp2ap002a00f.c
+
+diff --git a/Documentation/devicetree/bindings/iio/light/gp2ap002a00f.txt b/Documentation/devicetree/bindings/iio/light/gp2ap002a00f.txt
+new file mode 100644
+index 0000000..23face7
+--- /dev/null
++++ b/Documentation/devicetree/bindings/iio/light/gp2ap002a00f.txt
+@@ -0,0 +1,20 @@
++* Sharp GP2AP002A00F I2C Proximity/Opto sensor
++
++Required properties:
++
++  - compatible : should be "sharp,gp2ap002a00f"
++  - reg : the I2C address of the light sensor
++  - interrupt-parent : phandle to the parent interrupt controller
++  - interrupts : should be INT interrupt pin
++  - vled-supply : VLED power supply, as covered
++                in Documentation/devicetree/bindings/regulator/regulator.txt
++
++Example:
++
++gp2ap002a00f@39 {
++      compatible = "sharp,gp2ap002a00f";
++      reg = <0x39>;
++      interrupt-parent = <&gpx0>;
++      interrupts = <2 0>;
++      vled-supply = <...>;
++};
+diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
+index 5ef1a39..176ef6d 100644
+--- a/drivers/iio/light/Kconfig
++++ b/drivers/iio/light/Kconfig
+@@ -52,6 +52,18 @@ config VCNL4000
+        To compile this driver as a module, choose M here: the
+        module will be called vcnl4000.
++config GP2AP002A00F
++      tristate "Sharp GP2AP002A00F I2C Proximity/Opto sensor driver"
++      depends on I2C
++      select IIO_BUFFER
++      select IIO_TRIGGERED_BUFFER
++      help
++        Say Y here if you have a Sharp GP2AP002A00F proximity/als combo-chip
++        hooked to an I2C bus.
++
++        To compile this driver as a module, choose M here: the
++        module will be called gp2ap002a00f.
++
+ config HID_SENSOR_ALS
+       depends on HID_SENSOR_HUB
+       select IIO_BUFFER
+diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile
+index 040d9c7..9621b18 100644
+--- a/drivers/iio/light/Makefile
++++ b/drivers/iio/light/Makefile
+@@ -7,3 +7,4 @@ obj-$(CONFIG_SENSORS_LM3533)   += lm3533-als.o
+ obj-$(CONFIG_SENSORS_TSL2563) += tsl2563.o
+ obj-$(CONFIG_VCNL4000)                += vcnl4000.o
+ obj-$(CONFIG_HID_SENSOR_ALS)  += hid-sensor-als.o
++obj-$(CONFIG_GP2AP002A00F)    += gp2ap002a00f.o
+diff --git a/drivers/iio/light/gp2ap002a00f.c b/drivers/iio/light/gp2ap002a00f.c
+new file mode 100644
+index 0000000..be5af2e
+--- /dev/null
++++ b/drivers/iio/light/gp2ap002a00f.c
+@@ -0,0 +1,1158 @@
++/*
++ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
++ * Author: Jacek Anaszewski <j.anaszewski@samsung.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/i2c.h>
++#include <linux/irq.h>
++#include <linux/mutex.h>
++#include <linux/slab.h>
++#include <linux/module.h>
++#include <linux/interrupt.h>
++#include <linux/regulator/consumer.h>
++#include <linux/iio/iio.h>
++#include <linux/iio/sysfs.h>
++#include <linux/iio/events.h>
++#include <linux/iio/trigger.h>
++#include <linux/iio/buffer.h>
++#include <linux/iio/trigger_consumer.h>
++#include <linux/iio/triggered_buffer.h>
++
++#define GP2A_I2C_NAME "gp2ap002a00f"
++
++/* Registers */
++#define OP_REG                        0x00 /* Basic operations */
++#define ALS_REG                       0x01 /* ALS related settings */
++#define PS_REG                        0x02 /* PS related settings */
++#define LED_REG                       0x03 /* LED reg */
++#define TL_L_REG              0x04 /* ALS: Threshold low LSB */
++#define TL_H_REG              0x05 /* ALS: Threshold low MSB */
++#define TH_L_REG              0x06 /* ALS: Threshold high LSB */
++#define TH_H_REG              0x07 /* ALS: Threshold high MSB */
++#define PL_L_REG              0x08 /* PS: Threshold low LSB */
++#define PL_H_REG              0x09 /* PS: Threshold low MSB */
++#define PH_L_REG              0x0a /* PS: Threshold high LSB */
++#define PH_H_REG              0x0b /* PS: Threshold high MSB */
++#define D0_L_REG              0x0c /* ALS result: Clear/Illuminance LSB */
++#define D0_H_REG              0x0d /* ALS result: Clear/Illuminance MSB */
++#define D1_L_REG              0x0e /* ALS result: IR LSB */
++#define D1_H_REG              0x0f /* ALS result: IR LSB */
++#define D2_L_REG              0x10 /* PS result LSB */
++#define D2_H_REG              0x11 /* PS result MSB */
++#define REGS_NUM              0x12 /* Number of registers */
++
++/* OP_REG bits */
++#define OP3_MASK              0x80 /* Software shutdown */
++#define OP3_SHUTDOWN          0x00
++#define OP3_OPERATION         0x80
++#define OP2_MASK              0x40 /* Auto shutdown/Continuous operation  */
++#define OP2_AUTO_SHUTDOWN     0x00
++#define OP2_CONT_OPERATION    0x40
++#define OP_MASK                       0x30 /* Operating mode selection  */
++#define OP_ALS_AND_PS         0x00
++#define OP_ALS                        0x10
++#define OP_PS                 0x20
++#define OP_DEBUG              0x30
++#define PROX_MASK             0x08 /* PS: detection/non-detection  */
++#define PROX_NON_DETECT               0x00
++#define PROX_DETECT           0x08
++#define FLAG_P                        0x04 /* PS: interrupt result  */
++#define FLAG_A                        0x02 /* ALS: interrupt result  */
++#define TYPE_MASK             0x01 /* Output data type selection */
++#define TYPE_MANUAL_CALC      0x00
++#define TYPE_AUTO_CALC                0x01
++
++/* ALS_REG bits */
++#define PRST_MASK             0xc0 /* Number of measurement cycles */
++#define PRST_ONCE             0x00
++#define PRST_4_CYCLES         0x40
++#define PRST_8_CYCLES         0x80
++#define PRST_16_CYCLES                0xc0
++#define RES_A_MASK            0x38 /* ALS: Resolution (0.39ms - 800ms) */
++#define RES_A_800ms           0x00
++#define RES_A_400ms           0x08
++#define RES_A_200ms           0x10
++#define RES_A_100ms           0x18
++#define RES_A_25ms            0x20
++#define RES_A_6_25ms          0x28
++#define RES_A_1_56ms          0x30
++#define RES_A_0_39ms          0x38
++#define RANGE_A_MASK          0x07 /* ALS: Max measurable range (x1 - x128) */
++#define RANGE_A_x1            0x00
++#define RANGE_A_x2            0x01
++#define RANGE_A_x4            0x02
++#define RANGE_A_x8            0x03
++#define RANGE_A_x16           0x04
++#define RANGE_A_x32           0x05
++#define RANGE_A_x64           0x06
++#define RANGE_A_x128          0x07
++
++/* PS_REG bits */
++#define ALC_MASK              0x80 /* Auto light cancel */
++#define ALC_ON                        0x80
++#define ALC_OFF                       0x00
++#define INTTYPE_MASK          0x40 /* Interrupt type setting */
++#define INTTYPE_LEVEL         0x00
++#define INTTYPE_PULSE         0x40
++#define RES_P_MASK            0x38 /* PS: Resolution (0.39ms - 800ms)  */
++#define RES_P_800ms_x2                0x00
++#define RES_P_400ms_x2                0x08
++#define RES_P_200ms_x2                0x10
++#define RES_P_100ms_x2                0x18
++#define RES_P_25ms_x2         0x20
++#define RES_P_6_25ms_x2               0x28
++#define RES_P_1_56ms_x2               0x30
++#define RES_P_0_39ms_x2               0x38
++#define RANGE_P_MASK          0x07 /* PS: Max measurable range (x1 - x128) */
++#define RANGE_P_x1            0x00
++#define RANGE_P_x2            0x01
++#define RANGE_P_x4            0x02
++#define RANGE_P_x8            0x03
++#define RANGE_P_x16           0x04
++#define RANGE_P_x32           0x05
++#define RANGE_P_x64           0x06
++#define RANGE_P_x128          0x07
++
++/* LED reg bits */
++#define INTVAL_MASK           0xc0 /* Intermittent operating */
++#define INTVAL_0              0x00
++#define INTVAL_4              0x40
++#define INTVAL_8              0x80
++#define INTVAL_16             0xc0
++#define IS_MASK                       0x30 /* ILED drive peak current setting  */
++#define IS_13_8mA             0x00
++#define IS_27_5mA             0x10
++#define IS_55mA                       0x20
++#define IS_110mA              0x30
++#define PIN_MASK              0x0c /* INT terminal setting */
++#define PIN_ALS_OR_PS         0x00
++#define PIN_ALS                       0x04
++#define PIN_PS                        0x08
++#define PIN_PS_DETECT         0x0c
++#define FREQ_MASK             0x02 /* LED modulation frequency */
++#define FREQ_327_5kHz         0x00
++#define FREQ_81_8kHz          0x02
++#define RST                   0x01 /* Software reset */
++
++#define SCAN_MODE_LIGHT_CLEAR 0
++#define SCAN_MODE_LIGHT_IR    1
++#define SCAN_MODE_PROXIMITY   2
++#define CHAN_TIMESTAMP                3
++
++#define GP2AP002A00F_DATA_READY_TIMEOUT ((1000*HZ)/1000)
++
++#define GP2AP002A00F_DATA_REG(chan) (D0_L_REG + (chan) * 2)
++
++#define GP2AP002A00F_SUBTRACT_MODE    0
++#define GP2AP002A00F_ADD_MODE         1
++
++#define GP2AP002A00F_MAX_CHANNELS     3
++
++enum gp2ap002a00f_opmode {
++      GP2AP002A00F_OPMODE_READ_RAW_CLEAR,
++      GP2AP002A00F_OPMODE_READ_RAW_IR,
++      GP2AP002A00F_OPMODE_READ_RAW_PROXIMITY,
++      GP2AP002A00F_OPMODE_ALS,
++      GP2AP002A00F_OPMODE_PS,
++      GP2AP002A00F_OPMODE_ALS_AND_PS,
++      GP2AP002A00F_OPMODE_PROX_DETECT,
++      GP2AP002A00F_OPMODE_SHUTDOWN,
++};
++
++enum gp2ap002a00f_cmd {
++      GP2AP002A00F_CMD_READ_RAW_CLEAR,
++      GP2AP002A00F_CMD_READ_RAW_IR,
++      GP2AP002A00F_CMD_READ_RAW_PROXIMITY,
++      GP2AP002A00F_CMD_TRIGGER_CLEAR_EN,
++      GP2AP002A00F_CMD_TRIGGER_CLEAR_DIS,
++      GP2AP002A00F_CMD_TRIGGER_IR_EN,
++      GP2AP002A00F_CMD_TRIGGER_IR_DIS,
++      GP2AP002A00F_CMD_TRIGGER_PROX_EN,
++      GP2AP002A00F_CMD_TRIGGER_PROX_DIS,
++      GP2AP002A00F_CMD_ALS_HIGH_EV_EN,
++      GP2AP002A00F_CMD_ALS_HIGH_EV_DIS,
++      GP2AP002A00F_CMD_ALS_LOW_EV_EN,
++      GP2AP002A00F_CMD_ALS_LOW_EV_DIS,
++      GP2AP002A00F_CMD_PROX_EV_EN,
++      GP2AP002A00F_CMD_PROX_EV_DIS,
++};
++
++enum gp2ap002a00f_flags {
++      GP2AP002A00F_FLAG_ALS_CLEAR_TRIGGER,
++      GP2AP002A00F_FLAG_ALS_IR_TRIGGER,
++      GP2AP002A00F_FLAG_PS_TRIGGER,
++      GP2AP002A00F_FLAG_PS_RISING_EVENT,
++      GP2AP002A00F_FLAG_ALS_RISING_EVENT,
++      GP2AP002A00F_FLAG_ALS_FALLING_EVENT,
++      GP2AP002A00F_FLAG_DATA_READY,
++};
++
++struct gp2ap002a00f_data {
++      const struct gp2ap002a00f_platform_data *pdata;
++      struct i2c_client *client;
++      struct mutex lock;
++      char *buffer;
++      u8 reg_cache[REGS_NUM];
++      struct regulator *vled_reg;
++      unsigned long flags;
++      enum gp2ap002a00f_opmode cur_opmode;
++      wait_queue_head_t data_ready_queue;
++};
++
++static unsigned long gp2ap002a00f_available_scan_masks[] = {
++      0x01,
++      0x02,
++      0x04,
++};
++
++static int gp2ap002a00f_set_operation_mode(struct gp2ap002a00f_data *data,
++                                      enum gp2ap002a00f_opmode op)
++{
++      u8 prev_ctrl_regs[4];
++      int err;
++
++      prev_ctrl_regs[OP_REG] = data->reg_cache[OP_REG];
++      prev_ctrl_regs[ALS_REG] = data->reg_cache[ALS_REG];
++      prev_ctrl_regs[PS_REG] = data->reg_cache[PS_REG];
++      prev_ctrl_regs[LED_REG] = data->reg_cache[LED_REG];
++
++      data->reg_cache[OP_REG] &= ~(OP_MASK | OP2_MASK | OP3_MASK
++                                   | TYPE_MASK);
++      data->reg_cache[ALS_REG] &= ~PRST_MASK;
++      data->reg_cache[LED_REG] &= ~PIN_MASK;
++
++      switch (op) {
++      case GP2AP002A00F_OPMODE_READ_RAW_CLEAR:
++      case GP2AP002A00F_OPMODE_READ_RAW_IR:
++              data->reg_cache[OP_REG] |= (OP_ALS | OP2_AUTO_SHUTDOWN
++                                         | OP3_OPERATION | TYPE_MANUAL_CALC);
++              data->reg_cache[ALS_REG] |= PRST_ONCE;
++              data->reg_cache[LED_REG] |= PIN_ALS;
++              break;
++      case GP2AP002A00F_OPMODE_READ_RAW_PROXIMITY:
++              data->reg_cache[OP_REG] |= (OP_PS | OP2_AUTO_SHUTDOWN
++                                         | OP3_OPERATION | TYPE_MANUAL_CALC);
++              data->reg_cache[ALS_REG] |= PRST_ONCE;
++              data->reg_cache[LED_REG] |= PIN_PS;
++              break;
++      case GP2AP002A00F_OPMODE_PROX_DETECT:
++              data->reg_cache[OP_REG] |= (OP_PS | OP2_CONT_OPERATION
++                                         | OP3_OPERATION | TYPE_MANUAL_CALC);
++              data->reg_cache[ALS_REG] |= PRST_4_CYCLES;
++              data->reg_cache[LED_REG] |= PIN_PS_DETECT;
++              break;
++      case GP2AP002A00F_OPMODE_ALS:
++              data->reg_cache[OP_REG] |= (OP_ALS | OP2_CONT_OPERATION
++                                         | OP3_OPERATION | TYPE_MANUAL_CALC);
++              data->reg_cache[ALS_REG] |= PRST_ONCE;
++              data->reg_cache[LED_REG] |= PIN_ALS;
++              break;
++      case GP2AP002A00F_OPMODE_PS:
++              data->reg_cache[OP_REG] |= (OP_PS | OP2_CONT_OPERATION
++                                         | OP3_OPERATION | TYPE_MANUAL_CALC);
++              data->reg_cache[ALS_REG] |= PRST_4_CYCLES;
++              data->reg_cache[LED_REG] |= PIN_PS;
++              break;
++      case GP2AP002A00F_OPMODE_ALS_AND_PS:
++              data->reg_cache[OP_REG] |= (OP_ALS_AND_PS | OP2_CONT_OPERATION
++                                         | OP3_OPERATION | TYPE_MANUAL_CALC);
++              data->reg_cache[ALS_REG] |= PRST_4_CYCLES;
++              data->reg_cache[LED_REG] |= PIN_ALS_OR_PS;
++              break;
++      case GP2AP002A00F_OPMODE_SHUTDOWN:
++              /*
++               * Bring back last OP state to avoid sending shutdown
++               * command twice due to spurious op mode transition.
++               */
++              data->reg_cache[OP_REG] = prev_ctrl_regs[OP_REG]
++                                      & OP_MASK;
++              break;
++      }
++
++      /*
++       * Shutdown the device if the operation being executed entails
++       * mode transition.
++       */
++      if ((data->reg_cache[OP_REG] & OP_MASK) !=
++          (prev_ctrl_regs[OP_REG] & OP_MASK)) {
++              /* set shutdown mode */
++              err = i2c_smbus_write_byte_data(data->client, OP_REG, 0);
++              if (err < 0)
++                      goto error_ret;
++      }
++
++      err = i2c_smbus_write_i2c_block_data(data->client, ALS_REG, 3,
++                                              &data->reg_cache[ALS_REG]);
++      if (err < 0)
++              goto error_ret;
++
++      /* Set OP_REG and apply operation mode (power on / off) */
++      err = i2c_smbus_write_byte_data(data->client, OP_REG,
++                                              data->reg_cache[OP_REG]);
++      if (err < 0)
++              goto error_ret;
++
++      data->cur_opmode = op;
++
++      return 0;
++
++error_ret:
++      data->reg_cache[OP_REG] = prev_ctrl_regs[OP_REG];
++      data->reg_cache[ALS_REG] = prev_ctrl_regs[ALS_REG];
++      data->reg_cache[PS_REG] = prev_ctrl_regs[PS_REG];
++      data->reg_cache[LED_REG] = prev_ctrl_regs[LED_REG];
++
++      return err;
++}
++
++static bool gp2ap002a00f_als_enabled(struct gp2ap002a00f_data *data)
++{
++      return test_bit(GP2AP002A00F_FLAG_ALS_CLEAR_TRIGGER,
++                                                      &data->flags) ||
++             test_bit(GP2AP002A00F_FLAG_ALS_IR_TRIGGER,
++                                                      &data->flags) ||
++             test_bit(GP2AP002A00F_FLAG_ALS_RISING_EVENT,
++                                                      &data->flags) ||
++             test_bit(GP2AP002A00F_FLAG_ALS_FALLING_EVENT,
++                                                      &data->flags);
++}
++
++static int gp2ap002a00f_alter_opmode(struct gp2ap002a00f_data *data,
++                      enum gp2ap002a00f_opmode diff_mode, int add_sub)
++{
++      enum gp2ap002a00f_opmode new_mode;
++      int err;
++
++      if (diff_mode != GP2AP002A00F_OPMODE_ALS &&
++          diff_mode != GP2AP002A00F_OPMODE_PS)
++              return -EINVAL;
++
++      if (add_sub == GP2AP002A00F_ADD_MODE) {
++              if (data->cur_opmode == GP2AP002A00F_OPMODE_SHUTDOWN)
++                      new_mode =  diff_mode;
++              else
++                      new_mode = GP2AP002A00F_OPMODE_ALS_AND_PS;
++      } else {
++              if (data->cur_opmode == GP2AP002A00F_OPMODE_ALS_AND_PS)
++                      new_mode =  diff_mode;
++              else
++                      new_mode = GP2AP002A00F_OPMODE_SHUTDOWN;
++      }
++
++      err = gp2ap002a00f_set_operation_mode(data, new_mode);
++
++      return err;
++}
++
++static int gp2ap002a00f_exec_cmd(struct gp2ap002a00f_data *data,
++                                      enum gp2ap002a00f_cmd cmd)
++{
++      const u8 thresh_off_buf[2] = {0x00, 0x00};
++      int err = 0;
++
++      switch (cmd) {
++      case GP2AP002A00F_CMD_READ_RAW_CLEAR:
++              if (data->cur_opmode != GP2AP002A00F_OPMODE_SHUTDOWN)
++                      return -EBUSY;
++              err = gp2ap002a00f_set_operation_mode(data,
++                                      GP2AP002A00F_CMD_READ_RAW_CLEAR);
++              break;
++      case GP2AP002A00F_CMD_READ_RAW_IR:
++              if (data->cur_opmode != GP2AP002A00F_OPMODE_SHUTDOWN)
++                      return -EBUSY;
++              err = gp2ap002a00f_set_operation_mode(data,
++                                      GP2AP002A00F_CMD_READ_RAW_IR);
++              break;
++      case GP2AP002A00F_CMD_READ_RAW_PROXIMITY:
++              if (data->cur_opmode != GP2AP002A00F_OPMODE_SHUTDOWN)
++                      return -EBUSY;
++              err = gp2ap002a00f_set_operation_mode(data,
++                                      GP2AP002A00F_CMD_READ_RAW_PROXIMITY);
++              break;
++      case GP2AP002A00F_CMD_TRIGGER_CLEAR_EN:
++              if (data->cur_opmode == GP2AP002A00F_OPMODE_PROX_DETECT)
++                      return -EBUSY;
++              if (!gp2ap002a00f_als_enabled(data))
++                      err = gp2ap002a00f_alter_opmode(data,
++                                              GP2AP002A00F_OPMODE_ALS,
++                                              GP2AP002A00F_ADD_MODE);
++              set_bit(GP2AP002A00F_FLAG_ALS_CLEAR_TRIGGER, &data->flags);
++              break;
++      case GP2AP002A00F_CMD_TRIGGER_CLEAR_DIS:
++              clear_bit(GP2AP002A00F_FLAG_ALS_CLEAR_TRIGGER, &data->flags);
++              if (gp2ap002a00f_als_enabled(data))
++                      break;
++              err = gp2ap002a00f_alter_opmode(data,
++                                              GP2AP002A00F_OPMODE_ALS,
++                                              GP2AP002A00F_SUBTRACT_MODE);
++              break;
++      case GP2AP002A00F_CMD_TRIGGER_IR_EN:
++              if (data->cur_opmode == GP2AP002A00F_OPMODE_PROX_DETECT)
++                      return -EBUSY;
++              if (!gp2ap002a00f_als_enabled(data))
++                      err = gp2ap002a00f_alter_opmode(data,
++                                              GP2AP002A00F_OPMODE_ALS,
++                                              GP2AP002A00F_ADD_MODE);
++              set_bit(GP2AP002A00F_FLAG_ALS_IR_TRIGGER, &data->flags);
++              break;
++      case GP2AP002A00F_CMD_TRIGGER_IR_DIS:
++              clear_bit(GP2AP002A00F_FLAG_ALS_IR_TRIGGER, &data->flags);
++              if (gp2ap002a00f_als_enabled(data))
++                      break;
++              err = gp2ap002a00f_alter_opmode(data,
++                                              GP2AP002A00F_OPMODE_ALS,
++                                              GP2AP002A00F_SUBTRACT_MODE);
++              break;
++      case GP2AP002A00F_CMD_TRIGGER_PROX_EN:
++              set_bit(GP2AP002A00F_FLAG_PS_TRIGGER, &data->flags);
++              /*
++               * Don't change opmode if in PROX_DETECT, as
++               * it is compatible with PS mode.
++               */
++              if (data->cur_opmode == GP2AP002A00F_OPMODE_PROX_DETECT)
++                      break;
++              err = gp2ap002a00f_alter_opmode(data,
++                                              GP2AP002A00F_OPMODE_PS,
++                                              GP2AP002A00F_ADD_MODE);
++              break;
++      case GP2AP002A00F_CMD_TRIGGER_PROX_DIS:
++              clear_bit(GP2AP002A00F_FLAG_PS_TRIGGER, &data->flags);
++              if (test_bit(GP2AP002A00F_FLAG_PS_RISING_EVENT, &data->flags))
++                      break;
++              err = gp2ap002a00f_alter_opmode(data,
++                                              GP2AP002A00F_OPMODE_PS,
++                                              GP2AP002A00F_SUBTRACT_MODE);
++              break;
++      case GP2AP002A00F_CMD_ALS_HIGH_EV_EN:
++              if (data->cur_opmode == GP2AP002A00F_OPMODE_PROX_DETECT)
++                      return -EBUSY;
++              if (!gp2ap002a00f_als_enabled(data)) {
++                      err = gp2ap002a00f_alter_opmode(data,
++                                              GP2AP002A00F_OPMODE_ALS,
++                                              GP2AP002A00F_ADD_MODE);
++                      if (err < 0)
++                              return err;
++              }
++              set_bit(GP2AP002A00F_FLAG_ALS_RISING_EVENT, &data->flags);
++              err = i2c_smbus_write_i2c_block_data(data->client, TH_L_REG, 2,
++                                              &data->reg_cache[TH_L_REG]);
++              break;
++      case GP2AP002A00F_CMD_ALS_HIGH_EV_DIS:
++              clear_bit(GP2AP002A00F_FLAG_ALS_RISING_EVENT, &data->flags);
++              if (!gp2ap002a00f_als_enabled(data)) {
++                      err = gp2ap002a00f_alter_opmode(data,
++                                              GP2AP002A00F_OPMODE_ALS,
++                                              GP2AP002A00F_SUBTRACT_MODE);
++                      if (err < 0)
++                              return err;
++              }
++              err = i2c_smbus_write_i2c_block_data(data->client, TH_L_REG, 2,
++                                              thresh_off_buf);
++              break;
++      case GP2AP002A00F_CMD_ALS_LOW_EV_EN:
++              if (data->cur_opmode == GP2AP002A00F_OPMODE_PROX_DETECT)
++                      return -EBUSY;
++              if (!gp2ap002a00f_als_enabled(data)) {
++                      err = gp2ap002a00f_alter_opmode(data,
++                                              GP2AP002A00F_OPMODE_ALS,
++                                              GP2AP002A00F_ADD_MODE);
++                      if (err < 0)
++                              return err;
++              }
++              set_bit(GP2AP002A00F_FLAG_ALS_FALLING_EVENT, &data->flags);
++              err = i2c_smbus_write_i2c_block_data(data->client, TL_L_REG, 2,
++                                              &data->reg_cache[TL_L_REG]);
++              break;
++      case GP2AP002A00F_CMD_ALS_LOW_EV_DIS:
++              clear_bit(GP2AP002A00F_FLAG_ALS_FALLING_EVENT, &data->flags);
++              if (!gp2ap002a00f_als_enabled(data)) {
++                      err = gp2ap002a00f_alter_opmode(data,
++                                              GP2AP002A00F_OPMODE_ALS,
++                                              GP2AP002A00F_SUBTRACT_MODE);
++                      if (err < 0)
++                              return err;
++              }
++              err = i2c_smbus_write_i2c_block_data(data->client, TL_L_REG, 2,
++                                              thresh_off_buf);
++              break;
++      case GP2AP002A00F_CMD_PROX_EV_EN:
++              if (gp2ap002a00f_als_enabled(data))
++                      return -EBUSY;
++              set_bit(GP2AP002A00F_FLAG_PS_RISING_EVENT, &data->flags);
++              err = gp2ap002a00f_set_operation_mode(data,
++                                      GP2AP002A00F_OPMODE_PROX_DETECT);
++              if (err < 0)
++                      return err;
++              err = i2c_smbus_write_i2c_block_data(data->client, PH_L_REG, 2,
++                                              &data->reg_cache[PH_L_REG]);
++              break;
++      case GP2AP002A00F_CMD_PROX_EV_DIS:
++              clear_bit(GP2AP002A00F_FLAG_PS_RISING_EVENT, &data->flags);
++              if (test_bit(GP2AP002A00F_FLAG_PS_TRIGGER, &data->flags))
++                      err = gp2ap002a00f_set_operation_mode(data,
++                                      GP2AP002A00F_OPMODE_PS);
++              else
++                      err = gp2ap002a00f_set_operation_mode(data,
++                                      GP2AP002A00F_OPMODE_SHUTDOWN);
++              if (err < 0)
++                      return err;
++              err = i2c_smbus_write_i2c_block_data(data->client, PH_L_REG, 2,
++                                              thresh_off_buf);
++              break;
++      }
++
++      return err;
++}
++
++static int gp2ap002a00f_get_reg_cache_word(struct gp2ap002a00f_data *data,
++                                      u8 reg_addr)
++{
++      return (data->reg_cache[reg_addr + 1] << 8) |
++              data->reg_cache[reg_addr];
++}
++
++/* Returns 0 if the end of conversion interrupt occured or -ETIME otherwise */
++static int wait_conversion_complete_interrupt(struct gp2ap002a00f_data *data)
++{
++      int ret;
++
++      ret = wait_event_timeout(data->data_ready_queue,
++                               test_bit(GP2AP002A00F_FLAG_DATA_READY,
++                                        &data->flags),
++                               GP2AP002A00F_DATA_READY_TIMEOUT);
++      clear_bit(GP2AP002A00F_FLAG_DATA_READY, &data->flags);
++
++      return ret > 0 ? 0 : -ETIME;
++}
++
++static int gp2ap002a00f_read_output(struct gp2ap002a00f_data *data,
++                                      u8 output_reg, int *val)
++{
++      int err = -EINVAL;
++
++      err = wait_conversion_complete_interrupt(data);
++      if (err < 0)
++              dev_dbg(&data->client->dev, "data ready timeout\n");
++
++      err = i2c_smbus_read_i2c_block_data(data->client, output_reg, 2,
++                                              &data->reg_cache[output_reg]);
++      if (err < 0)
++              return err;
++
++      *val = gp2ap002a00f_get_reg_cache_word(data, output_reg);
++
++      return err;
++}
++
++static irqreturn_t gp2ap002a00f_event_handler(int irq, void *data)
++{
++      struct iio_dev *indio_dev = data;
++      struct gp2ap002a00f_data *lgt = iio_priv(indio_dev);
++      u8 op_reg_val, op_reg_flags;
++      int output_val, ret;
++
++      /* Read interrupt flags */
++      ret = i2c_smbus_read_i2c_block_data(lgt->client, OP_REG, 1,
++                                              &op_reg_val);
++      if (ret < 0)
++              goto done;
++
++      op_reg_flags = op_reg_val & (FLAG_A | FLAG_P | PROX_DETECT);
++
++      /* Clear interrupt flags */
++      op_reg_val &= (~FLAG_A & ~FLAG_P & ~PROX_DETECT);
++      ret = i2c_smbus_write_i2c_block_data(lgt->client, OP_REG, 1,
++                                              &op_reg_val);
++      if (ret < 0)
++              goto done;
++
++      if (lgt->cur_opmode == GP2AP002A00F_OPMODE_READ_RAW_CLEAR ||
++          lgt->cur_opmode == GP2AP002A00F_OPMODE_READ_RAW_IR ||
++          lgt->cur_opmode == GP2AP002A00F_OPMODE_READ_RAW_PROXIMITY) {
++              set_bit(GP2AP002A00F_FLAG_DATA_READY, &lgt->flags);
++              wake_up(&lgt->data_ready_queue);
++              goto done;
++      }
++
++      if ((test_bit(GP2AP002A00F_FLAG_ALS_RISING_EVENT, &lgt->flags) ||
++          test_bit(GP2AP002A00F_FLAG_ALS_FALLING_EVENT, &lgt->flags)) &&
++          (op_reg_flags & FLAG_A)) {
++              /*
++               * We need to read output value to distinguish
++               * between high and low threshold event.
++               */
++              ret = i2c_smbus_read_i2c_block_data(lgt->client, D0_L_REG, 2,
++                                              &lgt->reg_cache[D0_L_REG]);
++              if (ret < 0)
++                      goto done;
++
++              output_val = gp2ap002a00f_get_reg_cache_word(lgt, D0_L_REG);
++
++              if (output_val > gp2ap002a00f_get_reg_cache_word(lgt,
++                                                               TH_L_REG))
++                      iio_push_event(indio_dev,
++                                     IIO_MOD_EVENT_CODE(
++                                              IIO_LIGHT,
++                                              SCAN_MODE_LIGHT_CLEAR,
++                                              IIO_MOD_LIGHT_CLEAR,
++                                              IIO_EV_TYPE_THRESH,
++                                              IIO_EV_DIR_RISING),
++                                     iio_get_time_ns());
++              else if (output_val < gp2ap002a00f_get_reg_cache_word(lgt,
++                                                                  TL_L_REG))
++                      iio_push_event(indio_dev,
++                                     IIO_MOD_EVENT_CODE(
++                                              IIO_LIGHT,
++                                              SCAN_MODE_LIGHT_CLEAR,
++                                              IIO_MOD_LIGHT_CLEAR,
++                                              IIO_EV_TYPE_THRESH,
++                                              IIO_EV_DIR_FALLING),
++                                     iio_get_time_ns());
++      }
++
++      if (test_bit(GP2AP002A00F_FLAG_PS_RISING_EVENT, &lgt->flags) &&
++              (op_reg_flags & FLAG_P)) {
++              iio_push_event(indio_dev,
++                             IIO_UNMOD_EVENT_CODE(
++                                      IIO_PROXIMITY,
++                                      SCAN_MODE_PROXIMITY,
++                                      IIO_EV_TYPE_THRESH,
++                                      IIO_EV_DIR_RISING),
++                             iio_get_time_ns());
++      }
++
++done:
++      return IRQ_HANDLED;
++}
++
++static irqreturn_t gp2ap002a00f_trigger_handler(int irq, void *data)
++{
++      struct iio_poll_func *pf = data;
++      struct iio_dev *indio_dev = pf->indio_dev;
++      struct gp2ap002a00f_data *lgt = iio_priv(indio_dev);
++      s64 time_ns;
++      size_t d_size = 0;
++      int i, ret;
++
++      for_each_set_bit(i, indio_dev->active_scan_mask,
++              indio_dev->masklength) {
++              ret = i2c_smbus_read_i2c_block_data(lgt->client,
++                              GP2AP002A00F_DATA_REG(i), 2,
++                              &lgt->buffer[d_size]);
++              if (ret < 0)
++                      goto done;
++              d_size += 2;
++      }
++
++      if (indio_dev->scan_timestamp)
++              d_size += sizeof(s64);
++
++      lgt->buffer = kmalloc(d_size, GFP_KERNEL);
++      if (lgt->buffer == NULL)
++              goto done;
++
++      time_ns = iio_get_time_ns();
++
++      if (indio_dev->scan_timestamp)
++              memcpy(lgt->buffer + d_size - sizeof(s64), &time_ns,
++                                                      sizeof(time_ns));
++
++      iio_push_to_buffers(indio_dev, lgt->buffer);
++
++      kfree(lgt->buffer);
++done:
++      iio_trigger_notify_done(indio_dev->trig);
++
++      return IRQ_HANDLED;
++}
++
++static int gp2ap002a00f_setup(struct gp2ap002a00f_data *data)
++{
++      int err = 0;
++
++      data->reg_cache[OP_REG] = OP3_SHUTDOWN;
++      data->reg_cache[LED_REG] = INTVAL_0 | IS_110mA | FREQ_327_5kHz;
++      data->reg_cache[ALS_REG] = RES_A_25ms | RANGE_A_x8;
++      data->reg_cache[PS_REG] = ALC_ON | INTTYPE_LEVEL | RES_P_1_56ms_x2
++                                | RANGE_P_x4;
++
++      err = i2c_smbus_write_i2c_block_data(data->client, OP_REG, REGS_NUM,
++                                              &data->reg_cache[OP_REG]);
++
++      return err;
++}
++
++static u8 get_reg_by_event_code(u64 event_code)
++{
++      int chan_type = IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code);
++
++      if (chan_type == IIO_PROXIMITY) {
++              /*
++               * Only IIO_EV_DIR_RISING direction for the IIO_PROXIMITY
++               * event is supported by the driver.
++               */
++              return PH_L_REG;
++      } else if (chan_type == IIO_LIGHT) {
++              if (IIO_EVENT_CODE_EXTRACT_DIR(event_code)
++                                      == IIO_EV_DIR_RISING)
++                      return TH_L_REG;
++              else
++                      return TL_L_REG;
++      } else {
++              return -EINVAL;
++      }
++
++      return 0;
++}
++
++static int gp2ap002a00f_write_event_val(struct iio_dev *indio_dev,
++                                      u64 event_code, int val)
++{
++      struct gp2ap002a00f_data *data = iio_priv(indio_dev);
++      bool event_en = false;
++      int thresh_reg_l, err = 0;
++
++      mutex_lock(&data->lock);
++
++      thresh_reg_l = get_reg_by_event_code(event_code);
++
++      if (thresh_reg_l > PH_L_REG) {
++              err = -EINVAL;
++              goto error_ret;
++      }
++
++      data->reg_cache[thresh_reg_l] = val & 0xff;
++      data->reg_cache[thresh_reg_l + 1] = val >> 8;
++
++      switch (thresh_reg_l) {
++      case TH_L_REG:
++              if (test_bit(GP2AP002A00F_FLAG_ALS_RISING_EVENT,
++                                                      &data->flags))
++                      event_en = true;
++              break;
++      case TL_L_REG:
++              if (test_bit(GP2AP002A00F_FLAG_ALS_FALLING_EVENT,
++                                                      &data->flags))
++                      event_en = true;
++              break;
++      case PH_L_REG:
++              if (test_bit(GP2AP002A00F_FLAG_PS_RISING_EVENT,
++                                                      &data->flags))
++                      event_en = true;
++              break;
++      }
++
++      if (event_en)
++              err = i2c_smbus_write_i2c_block_data(data->client,
++                                      thresh_reg_l, 2,
++                                      &data->reg_cache[thresh_reg_l]);
++error_ret:
++      mutex_unlock(&data->lock);
++
++      return err;
++}
++
++static int gp2ap002a00f_read_event_val(struct iio_dev *indio_dev,
++                                      u64 event_code, int *val)
++{
++      struct gp2ap002a00f_data *data = iio_priv(indio_dev);
++      int thresh_reg_l;
++
++      mutex_lock(&data->lock);
++
++      thresh_reg_l = get_reg_by_event_code(event_code);
++
++      *val = gp2ap002a00f_get_reg_cache_word(data, thresh_reg_l);
++
++      mutex_unlock(&data->lock);
++
++      return 0;
++}
++
++static int gp2ap002a00f_write_event_config(struct iio_dev *indio_dev,
++                                      u64 event_code, int state)
++{
++      struct gp2ap002a00f_data *data = iio_priv(indio_dev);
++      enum gp2ap002a00f_cmd cmd;
++      int chan_type = IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code);
++      int err;
++
++      mutex_lock(&data->lock);
++
++      if (chan_type == IIO_PROXIMITY) {
++              cmd = state ? GP2AP002A00F_CMD_PROX_EV_EN :
++                            GP2AP002A00F_CMD_PROX_EV_DIS;
++              err = gp2ap002a00f_exec_cmd(data, cmd);
++      } else if (chan_type == IIO_LIGHT) {
++              if (IIO_EVENT_CODE_EXTRACT_DIR(event_code)
++                                      == IIO_EV_DIR_RISING) {
++                      cmd = state ? GP2AP002A00F_CMD_ALS_HIGH_EV_EN :
++                                    GP2AP002A00F_CMD_ALS_HIGH_EV_DIS;
++                      err = gp2ap002a00f_exec_cmd(data, cmd);
++              } else {
++                      cmd = state ? GP2AP002A00F_CMD_ALS_LOW_EV_EN :
++                                    GP2AP002A00F_CMD_ALS_LOW_EV_DIS;
++                      err = gp2ap002a00f_exec_cmd(data, cmd);
++              }
++      } else {
++              return -EINVAL;
++      }
++
++      mutex_unlock(&data->lock);
++
++      return err;
++}
++
++static int gp2ap002a00f_read_event_config(struct iio_dev *indio_dev,
++                                      u64 event_code)
++{
++      struct gp2ap002a00f_data *data = iio_priv(indio_dev);
++      int chan_type = IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code);
++      int event_en;
++
++      mutex_lock(&data->lock);
++
++      if (chan_type == IIO_PROXIMITY) {
++              event_en = test_bit(GP2AP002A00F_FLAG_PS_RISING_EVENT,
++                                                              &data->flags);
++      } else if (chan_type == IIO_LIGHT) {
++              if (IIO_EVENT_CODE_EXTRACT_DIR(event_code)
++                                      == IIO_EV_DIR_RISING)
++                      event_en = test_bit(GP2AP002A00F_FLAG_ALS_RISING_EVENT,
++                                                              &data->flags);
++              else
++                      event_en = test_bit(GP2AP002A00F_FLAG_ALS_FALLING_EVENT,
++                                                              &data->flags);
++      } else {
++              return -EINVAL;
++      }
++
++      mutex_unlock(&data->lock);
++
++      return event_en;
++}
++
++static int gp2ap002a00f_read_channel(struct gp2ap002a00f_data *data,
++                              struct iio_chan_spec const *chan, int *val)
++{
++      enum gp2ap002a00f_cmd cmd;
++      int err;
++
++      switch (chan->scan_index) {
++      case SCAN_MODE_LIGHT_CLEAR:
++              cmd = GP2AP002A00F_CMD_READ_RAW_CLEAR;
++              break;
++      case SCAN_MODE_LIGHT_IR:
++              cmd = GP2AP002A00F_CMD_READ_RAW_IR;
++              break;
++      case SCAN_MODE_PROXIMITY:
++              cmd = GP2AP002A00F_CMD_READ_RAW_PROXIMITY;
++              break;
++      }
++
++      err = gp2ap002a00f_exec_cmd(data, cmd);
++      if (err < 0) {
++              dev_err(&data->client->dev, "gp2ap002a00f_exec_cmd failed\n");
++              goto error_ret;
++      }
++
++      err = gp2ap002a00f_read_output(data, chan->address, val);
++      if (err < 0)
++              dev_err(&data->client->dev, "gp2ap002a00f_read_output failed\n");
++
++      data->cur_opmode = GP2AP002A00F_OPMODE_SHUTDOWN;
++
++error_ret:
++      return err;
++}
++
++static int gp2ap002a00f_read_raw(struct iio_dev *indio_dev,
++                         struct iio_chan_spec const *chan,
++                         int *val, int *val2,
++                         long mask)
++{
++      struct gp2ap002a00f_data *data = iio_priv(indio_dev);
++      int err = -EINVAL;
++
++      mutex_lock(&data->lock);
++
++      switch (mask) {
++      case IIO_CHAN_INFO_RAW:
++              if (iio_buffer_enabled(indio_dev)) {
++                      err = -EBUSY;
++                      goto error_ret;
++              }
++              err = gp2ap002a00f_read_channel(data, chan, val);
++              break;
++      }
++
++error_ret:
++      mutex_unlock(&data->lock);
++
++      return err < 0 ? err : IIO_VAL_INT;
++}
++
++static const struct iio_chan_spec gp2ap002a00f_channels[] = {
++      {
++              .type = IIO_LIGHT,
++              .channel2 = IIO_MOD_LIGHT_CLEAR,
++              .modified = 1,
++              .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++              .scan_type = {
++                      .sign = 'u',
++                      .realbits = 16,
++                      .shift = 0,
++                      .storagebits = 16,
++                      .endianness = IIO_LE,
++              },
++              .scan_index = SCAN_MODE_LIGHT_CLEAR,
++              .address = D0_L_REG,
++              .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH,
++                                       IIO_EV_DIR_RISING) |
++                            IIO_EV_BIT(IIO_EV_TYPE_THRESH,
++                                       IIO_EV_DIR_FALLING),
++      },
++      {
++              .type = IIO_LIGHT,
++              .channel2 = IIO_MOD_LIGHT_IR,
++              .modified = 1,
++              .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++              .scan_type = {
++                      .sign = 'u',
++                      .realbits = 16,
++                      .shift = 0,
++                      .storagebits = 16,
++                      .endianness = IIO_LE,
++              },
++              .scan_index = SCAN_MODE_LIGHT_IR,
++              .address = D1_L_REG,
++      },
++      {
++              .type = IIO_PROXIMITY,
++              .modified = 0,
++              .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++              .scan_type = {
++                      .sign = 'u',
++                      .realbits = 16,
++                      .shift = 0,
++                      .storagebits = 16,
++                      .endianness = IIO_LE,
++              },
++              .scan_index = SCAN_MODE_PROXIMITY,
++              .address = D2_L_REG,
++              .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH,
++                                       IIO_EV_DIR_RISING),
++      },
++      IIO_CHAN_SOFT_TIMESTAMP(CHAN_TIMESTAMP),
++};
++
++static const struct iio_info gp2ap002a00f_info = {
++      .read_raw = &gp2ap002a00f_read_raw,
++      .read_event_value = &gp2ap002a00f_read_event_val,
++      .read_event_config = &gp2ap002a00f_read_event_config,
++      .write_event_value = &gp2ap002a00f_write_event_val,
++      .write_event_config = &gp2ap002a00f_write_event_config,
++      .driver_module = THIS_MODULE,
++};
++
++static int gp2ap002a00f_buffer_preenable(struct iio_dev *indio_dev)
++{
++      struct gp2ap002a00f_data *data = iio_priv(indio_dev);
++      int i, err = 0;
++
++      mutex_lock(&data->lock);
++
++      /* Enable triggers according to the scan_mask */
++      for_each_set_bit(i, indio_dev->active_scan_mask,
++              indio_dev->masklength) {
++              switch (i) {
++              case SCAN_MODE_LIGHT_CLEAR:
++                      err = gp2ap002a00f_exec_cmd(data,
++                                      GP2AP002A00F_CMD_TRIGGER_CLEAR_EN);
++                      if (err < 0)
++                              goto error_ret;
++                      break;
++              case SCAN_MODE_LIGHT_IR:
++                      err = gp2ap002a00f_exec_cmd(data,
++                                      GP2AP002A00F_CMD_TRIGGER_IR_EN);
++                      if (err < 0)
++                              goto error_ret;
++                      break;
++              case SCAN_MODE_PROXIMITY:
++                      err = gp2ap002a00f_exec_cmd(data,
++                                      GP2AP002A00F_CMD_TRIGGER_PROX_EN);
++                      if (err < 0)
++                              goto error_ret;
++                      break;
++              }
++
++      }
++
++      err = iio_sw_buffer_preenable(indio_dev);
++
++error_ret:
++      mutex_unlock(&data->lock);
++
++      return err;
++}
++
++static int gp2ap002a00f_buffer_predisable(struct iio_dev *indio_dev)
++{
++      struct gp2ap002a00f_data *data = iio_priv(indio_dev);
++      int err;
++
++      clear_bit(GP2AP002A00F_FLAG_ALS_CLEAR_TRIGGER, &data->flags);
++      clear_bit(GP2AP002A00F_FLAG_ALS_IR_TRIGGER, &data->flags);
++      clear_bit(GP2AP002A00F_FLAG_PS_TRIGGER, &data->flags);
++
++      err = gp2ap002a00f_exec_cmd(data, GP2AP002A00F_CMD_TRIGGER_CLEAR_DIS);
++      if (err < 0)
++              goto error_ret;
++
++      err = gp2ap002a00f_exec_cmd(data, GP2AP002A00F_CMD_TRIGGER_IR_DIS);
++      if (err < 0)
++              goto error_ret;
++
++      err = gp2ap002a00f_exec_cmd(data, GP2AP002A00F_CMD_TRIGGER_PROX_DIS);
++      if (err < 0)
++              goto error_ret;
++
++      err = iio_triggered_buffer_predisable(indio_dev);
++      if (err < 0)
++              goto error_ret;
++
++error_ret:
++      return err;
++}
++
++static const struct iio_buffer_setup_ops gp2ap002a00f_buffer_setup_ops = {
++      .preenable = &gp2ap002a00f_buffer_preenable,
++      .postenable = &iio_triggered_buffer_postenable,
++      .predisable = &gp2ap002a00f_buffer_predisable,
++};
++
++static int gp2ap002a00f_probe(struct i2c_client *client,
++                              const struct i2c_device_id *id)
++{
++      struct gp2ap002a00f_data *data;
++      struct iio_dev *indio_dev;
++      int err;
++
++      pr_info("gp2ap002a00f probe\n");
++
++      /* Register with IIO */
++      indio_dev = iio_device_alloc(sizeof(*data));
++      if (indio_dev == NULL) {
++              err = -ENOMEM;
++              goto error_alloc;
++      }
++
++      data = iio_priv(indio_dev);
++
++      data->vled_reg = devm_regulator_get(&client->dev, "vled");
++      if (IS_ERR(data->vled_reg)) {
++              err = PTR_ERR(data->vled_reg);
++              goto error_regulator_get;
++      }
++
++      err = regulator_enable(data->vled_reg);
++      if (err)
++              goto error_free_data;
++
++      i2c_set_clientdata(client, indio_dev);
++
++      data->client = client;
++      data->cur_opmode = GP2AP002A00F_OPMODE_SHUTDOWN;
++
++      init_waitqueue_head(&data->data_ready_queue);
++
++      err = gp2ap002a00f_setup(data);
++      if (err < 0)
++              goto error_free_data;
++
++      mutex_init(&data->lock);
++      indio_dev->dev.parent = &client->dev;
++      indio_dev->channels = gp2ap002a00f_channels;
++      indio_dev->num_channels = ARRAY_SIZE(gp2ap002a00f_channels);
++      indio_dev->info = &gp2ap002a00f_info;
++      indio_dev->name = id->name;
++      indio_dev->modes = INDIO_DIRECT_MODE;
++      indio_dev->available_scan_masks = gp2ap002a00f_available_scan_masks;
++
++      err = iio_triggered_buffer_setup(indio_dev, NULL,
++              &gp2ap002a00f_trigger_handler, &gp2ap002a00f_buffer_setup_ops);
++
++      err = devm_request_threaded_irq(&client->dev, client->irq,
++                                 &gp2ap002a00f_event_handler,
++                                 NULL,
++                                 IRQF_TRIGGER_FALLING,
++                                 "gp2ap002a00f_event",
++                                 indio_dev);
++      if (err < 0)
++              goto error_uninit_buffer;
++
++      err = iio_device_register(indio_dev);
++      if (err < 0)
++              goto error_uninit_buffer;
++
++      return 0;
++
++error_uninit_buffer:
++      iio_triggered_buffer_cleanup(indio_dev);
++error_free_data:
++      regulator_disable(data->vled_reg);
++error_regulator_get:
++      iio_device_free(indio_dev);
++error_alloc:
++      return err;
++}
++
++static int gp2ap002a00f_remove(struct i2c_client *client)
++{
++      struct iio_dev *indio_dev = i2c_get_clientdata(client);
++      struct gp2ap002a00f_data *data = iio_priv(indio_dev);
++
++      iio_device_unregister(indio_dev);
++      iio_triggered_buffer_cleanup(indio_dev);
++      regulator_disable(data->vled_reg);
++
++      iio_device_free(indio_dev);
++
++      return 0;
++}
++
++static const struct i2c_device_id gp2ap002a00f_id[] = {
++      { GP2A_I2C_NAME, 0 },
++      { }
++};
++
++MODULE_DEVICE_TABLE(i2c, gp2ap002a00f_id);
++
++#ifdef CONFIG_OF
++static const struct of_device_id gp2ap002a00f_of_match[] = {
++      { .compatible = "sharp,gp2ap002a00f" },
++      { .compatible = "gp2ap002a00f" },
++      { }
++};
++#endif
++
++static struct i2c_driver gp2ap002a00f_driver = {
++      .driver = {
++              .name   = GP2A_I2C_NAME,
++              .of_match_table = of_match_ptr(gp2ap002a00f_of_match),
++              .owner  = THIS_MODULE,
++      },
++      .probe          = gp2ap002a00f_probe,
++      .remove         = gp2ap002a00f_remove,
++      .id_table       = gp2ap002a00f_id,
++};
++
++module_i2c_driver(gp2ap002a00f_driver);
++
++MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
++MODULE_DESCRIPTION("Sharp GP2AP002A00F I2C Proximity/Opto sensor driver");
++MODULE_LICENSE("GPL v2");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0269-ARM-dts-Add-gp2ap002a00f-device-node-for-PQ-M0-board.patch b/patches.tizen/0269-ARM-dts-Add-gp2ap002a00f-device-node-for-PQ-M0-board.patch
new file mode 100644 (file)
index 0000000..06768fd
--- /dev/null
@@ -0,0 +1,61 @@
+From af4bb72c104a8c86fae02dfa1847c861987e2333 Mon Sep 17 00:00:00 2001
+From: Jacek Anaszewski <j.anaszewski@samsung.com>
+Date: Fri, 14 Jun 2013 17:23:52 +0200
+Subject: [PATCH 0269/1302] ARM: dts: Add gp2ap002a00f device node for PQ/M0
+ board
+
+This patch adds gp2ap002a00f device node for PQ/M0 board.
+
+Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 26 ++++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index d274e36..d32fe16 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -197,6 +197,23 @@
+               };
+       };
++      i2c-gpio-2 {
++              compatible = "i2c-gpio";
++              gpios = <&gpk1 1 0>, <&gpk2 2 0>;
++              i2c-gpio,delay-us = <2>;
++              #address-cells = <1>;
++              #size-cells = <0>;
++              status = "okay";
++
++              gp2ap002a00f@39 {
++                      compatible = "gp2ap002a00f";
++                      reg = <0x39>;
++                      interrupt-parent = <&gpx0>;
++                      interrupts = <2 0>;
++                      vled-supply = <&ps_als_reg>;
++              };
++      };
++
+       i2c_0: i2c@13860000 {
+               samsung,i2c-sda-delay = <100>;
+               samsung,i2c-slave-addr = <0x10>;
+@@ -715,6 +732,15 @@
+               regulator-always-on;
+       };
++      ps_als_reg: voltage-regulator@6 {
++              compatible = "regulator-fixed";
++              regulator-name = "LED_A_3.0V";
++              regulator-min-microvolt = <3000000>;
++              regulator-max-microvolt = <3000000>;
++              gpio = <&gpj0 5 0>;
++              enable-active-high;
++      };
++
+       fimd0_lcd: panel {
+               compatible = "samsung,s6e8aa0";
+               reset-gpio = <&gpy4 5 0>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0270-nfc-pn544-i2c-Add-DT-bindings.patch b/patches.tizen/0270-nfc-pn544-i2c-Add-DT-bindings.patch
new file mode 100644 (file)
index 0000000..bb9211e
--- /dev/null
@@ -0,0 +1,218 @@
+From 8fdb6a62277cbb635eac8b153d7ffa0e783d8d0b Mon Sep 17 00:00:00 2001
+From: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Date: Tue, 4 Jun 2013 13:24:43 +0200
+Subject: [PATCH 0270/1302] nfc: pn544-i2c: Add DT bindings
+
+This patch adds device tree support for nxp pn544-i2c nfc controller.
+
+Signed-off-by: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/nfc/pn544/i2c.c             | 130 ++++++++++++++++++++++++++++++------
+ include/linux/platform_data/pn544.h |   3 +-
+ 2 files changed, 111 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/nfc/pn544/i2c.c b/drivers/nfc/pn544/i2c.c
+index 8cf64c1..5edcb18 100644
+--- a/drivers/nfc/pn544/i2c.c
++++ b/drivers/nfc/pn544/i2c.c
+@@ -25,6 +25,8 @@
+ #include <linux/miscdevice.h>
+ #include <linux/interrupt.h>
+ #include <linux/delay.h>
++#include <linux/of.h>
++#include <linux/of_gpio.h>
+ #include <linux/platform_data/pn544.h>
+@@ -46,6 +48,13 @@
+ #define PN544_HCI_I2C_LLC_MAX_SIZE    (PN544_HCI_I2C_LLC_LEN_CRC + 1 + \
+                                        PN544_HCI_I2C_LLC_MAX_PAYLOAD)
++#ifdef CONFIG_OF
++static struct of_device_id pn544_hci_dt_match[] = {
++      { .compatible = "nxp,pn544-hci-i2c" },
++      {},
++};
++#endif
++
+ static struct i2c_device_id pn544_hci_i2c_id_table[] = {
+       {"pn544", 0},
+       {}
+@@ -361,6 +370,89 @@ static struct nfc_phy_ops i2c_phy_ops = {
+       .disable = pn544_hci_i2c_disable,
+ };
++static int pn544_hci_i2c_parse_pdata(
++              struct i2c_client *client,
++              struct pn544_nfc_platform_data *pdata,
++              struct pn544_i2c_phy *phy)
++{
++      int r;
++
++      if (pdata == NULL)
++              return -EINVAL;
++
++      if (pdata->request_resources == NULL) {
++              dev_err(&client->dev, "request_resources() missing\n");
++              return -EINVAL;
++      }
++
++      r = pdata->request_resources(client);
++      if (r) {
++              dev_err(&client->dev, "Cannot get platform resources\n");
++              return r;
++      }
++
++      phy->gpio_en = pdata->get_gpio(NFC_GPIO_ENABLE);
++      phy->gpio_fw = pdata->get_gpio(NFC_GPIO_FW_RESET);
++      phy->gpio_irq = pdata->get_gpio(NFC_GPIO_IRQ);
++
++      return 0;
++}
++
++#ifdef CONFIG_OF
++static const char * const pn544_hci_i2c_gpio_names[] = {
++      "nfc_gpio_enable",
++      "nfc_gpio_fw_reset",
++      "nfc_gpio_irq"
++};
++
++static int pn544_hci_i2c_parse_dt(struct i2c_client *client,
++              struct pn544_i2c_phy *phy)
++{
++      struct device_node *np = client->dev.of_node;
++      unsigned long flags = 0;
++      enum of_gpio_flags of_flags;
++      int gpio, err, i;
++
++      if (!np)
++              return -EINVAL;
++
++      for (i = 0; i < NFC_GPIO_COUNT; i++) {
++              gpio = of_get_gpio_flags(np, i, &of_flags);
++              flags = of_flags ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
++              switch (i) {
++              case NFC_GPIO_ENABLE:
++                      phy->gpio_en = gpio;
++                      break;
++              case NFC_GPIO_FW_RESET:
++                      phy->gpio_fw = gpio;
++                      break;
++              case NFC_GPIO_IRQ:
++                      phy->gpio_irq = gpio;
++                      break;
++              default:
++                      break;
++              }
++
++              if (gpio > 0)
++                      err = devm_gpio_request_one(&client->dev, gpio, flags,
++                              pn544_hci_i2c_gpio_names[i]);
++              else {
++                      dev_err(&client->dev, "%s no platform data\n",
++                              pn544_hci_i2c_gpio_names[i]);
++                      return -ENODEV;
++              }
++      }
++
++      return 0;
++}
++#else
++static static pn544_hci_i2c_parse_dt(struct i2c_client *client,
++              struct pn544_i2c_phy *phy)
++{
++      return -EINVAL;
++}
++#endif
++
+ static int pn544_hci_i2c_probe(struct i2c_client *client,
+                              const struct i2c_device_id *id)
+ {
+@@ -388,26 +480,17 @@ static int pn544_hci_i2c_probe(struct i2c_client *client,
+       i2c_set_clientdata(client, phy);
+       pdata = client->dev.platform_data;
+-      if (pdata == NULL) {
+-              dev_err(&client->dev, "No platform data\n");
+-              return -EINVAL;
+-      }
+-      if (pdata->request_resources == NULL) {
+-              dev_err(&client->dev, "request_resources() missing\n");
+-              return -EINVAL;
+-      }
++      if (pdata)
++              r = pn544_hci_i2c_parse_pdata(client, pdata, phy);
++      else
++              r = pn544_hci_i2c_parse_dt(client, phy);
+-      r = pdata->request_resources(client);
+-      if (r) {
+-              dev_err(&client->dev, "Cannot get platform resources\n");
+-              return r;
++      if (r < 0) {
++              dev_err(&client->dev, "No platform data\n");
++              goto err;
+       }
+-      phy->gpio_en = pdata->get_gpio(NFC_GPIO_ENABLE);
+-      phy->gpio_fw = pdata->get_gpio(NFC_GPIO_FW_RESET);
+-      phy->gpio_irq = pdata->get_gpio(NFC_GPIO_IRQ);
+-
+       pn544_hci_i2c_platform_init(phy);
+       r = request_threaded_irq(client->irq, NULL, pn544_hci_i2c_irq_thread_fn,
+@@ -430,9 +513,11 @@ err_hci:
+       free_irq(client->irq, phy);
+ err_rti:
+-      if (pdata->free_resources != NULL)
+-              pdata->free_resources();
+-
++      if (pdata) {
++              if (pdata->free_resources)
++                      pdata->free_resources();
++      }
++err:
+       return r;
+ }
+@@ -449,8 +534,10 @@ static int pn544_hci_i2c_remove(struct i2c_client *client)
+               pn544_hci_i2c_disable(phy);
+       free_irq(client->irq, phy);
+-      if (pdata->free_resources)
+-              pdata->free_resources();
++      if (pdata) {
++              if (pdata->free_resources)
++                      pdata->free_resources();
++      }
+       return 0;
+ }
+@@ -458,6 +545,7 @@ static int pn544_hci_i2c_remove(struct i2c_client *client)
+ static struct i2c_driver pn544_hci_i2c_driver = {
+       .driver = {
+                  .name = PN544_HCI_I2C_DRIVER_NAME,
++                 .of_match_table = of_match_ptr(pn544_hci_dt_match),
+                 },
+       .probe = pn544_hci_i2c_probe,
+       .id_table = pn544_hci_i2c_id_table,
+diff --git a/include/linux/platform_data/pn544.h b/include/linux/platform_data/pn544.h
+index 713bfd7..7f66370 100644
+--- a/include/linux/platform_data/pn544.h
++++ b/include/linux/platform_data/pn544.h
+@@ -28,7 +28,8 @@
+ enum {
+       NFC_GPIO_ENABLE,
+       NFC_GPIO_FW_RESET,
+-      NFC_GPIO_IRQ
++      NFC_GPIO_IRQ,
++      NFC_GPIO_COUNT
+ };
+ /* board config */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0271-nfc-pn544-i2c-Remove-unused-gpio_irq.patch b/patches.tizen/0271-nfc-pn544-i2c-Remove-unused-gpio_irq.patch
new file mode 100644 (file)
index 0000000..c448a85
--- /dev/null
@@ -0,0 +1,69 @@
+From 36ace92903aeaa17c927d5763fef8b33e51c43c1 Mon Sep 17 00:00:00 2001
+From: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Date: Thu, 13 Jun 2013 15:06:33 +0200
+Subject: [PATCH 0271/1302] nfc: pn544-i2c: Remove unused gpio_irq
+
+This patch removes unused gpio irq pin from driver.
+
+Signed-off-by: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/nfc/pn544/i2c.c             | 8 +-------
+ include/linux/platform_data/pn544.h | 1 -
+ 2 files changed, 1 insertion(+), 8 deletions(-)
+
+diff --git a/drivers/nfc/pn544/i2c.c b/drivers/nfc/pn544/i2c.c
+index 5edcb18..8a848c2 100644
+--- a/drivers/nfc/pn544/i2c.c
++++ b/drivers/nfc/pn544/i2c.c
+@@ -69,7 +69,6 @@ struct pn544_i2c_phy {
+       struct nfc_hci_dev *hdev;
+       unsigned int gpio_en;
+-      unsigned int gpio_irq;
+       unsigned int gpio_fw;
+       unsigned int en_polarity;
+@@ -393,7 +392,6 @@ static int pn544_hci_i2c_parse_pdata(
+       phy->gpio_en = pdata->get_gpio(NFC_GPIO_ENABLE);
+       phy->gpio_fw = pdata->get_gpio(NFC_GPIO_FW_RESET);
+-      phy->gpio_irq = pdata->get_gpio(NFC_GPIO_IRQ);
+       return 0;
+ }
+@@ -401,8 +399,7 @@ static int pn544_hci_i2c_parse_pdata(
+ #ifdef CONFIG_OF
+ static const char * const pn544_hci_i2c_gpio_names[] = {
+       "nfc_gpio_enable",
+-      "nfc_gpio_fw_reset",
+-      "nfc_gpio_irq"
++      "nfc_gpio_fw_reset"
+ };
+ static int pn544_hci_i2c_parse_dt(struct i2c_client *client,
+@@ -426,9 +423,6 @@ static int pn544_hci_i2c_parse_dt(struct i2c_client *client,
+               case NFC_GPIO_FW_RESET:
+                       phy->gpio_fw = gpio;
+                       break;
+-              case NFC_GPIO_IRQ:
+-                      phy->gpio_irq = gpio;
+-                      break;
+               default:
+                       break;
+               }
+diff --git a/include/linux/platform_data/pn544.h b/include/linux/platform_data/pn544.h
+index 7f66370..76fc0d5 100644
+--- a/include/linux/platform_data/pn544.h
++++ b/include/linux/platform_data/pn544.h
+@@ -28,7 +28,6 @@
+ enum {
+       NFC_GPIO_ENABLE,
+       NFC_GPIO_FW_RESET,
+-      NFC_GPIO_IRQ,
+       NFC_GPIO_COUNT
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0272-nfc-pn544-i2c-Fix-pn544_hci_i2c_write-resend-cmd.patch b/patches.tizen/0272-nfc-pn544-i2c-Fix-pn544_hci_i2c_write-resend-cmd.patch
new file mode 100644 (file)
index 0000000..ebff573
--- /dev/null
@@ -0,0 +1,30 @@
+From 3041318391f663c135214e207f73c82856b2f26b Mon Sep 17 00:00:00 2001
+From: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Date: Thu, 13 Jun 2013 15:42:22 +0200
+Subject: [PATCH 0272/1302] nfc: pn544-i2c: Fix pn544_hci_i2c_write() resend
+ cmd
+
+Driver should always try resend cmd after failed i2c_master_send.
+
+Signed-off-by: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/nfc/pn544/i2c.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/nfc/pn544/i2c.c b/drivers/nfc/pn544/i2c.c
+index 8a848c2..8545623 100644
+--- a/drivers/nfc/pn544/i2c.c
++++ b/drivers/nfc/pn544/i2c.c
+@@ -206,7 +206,7 @@ static int pn544_hci_i2c_write(void *phy_id, struct sk_buff *skb)
+       r = i2c_master_send(client, skb->data, skb->len);
+-      if (r == -EREMOTEIO) {  /* Retry, chip was in standby */
++      if (r < 0) {    /* Retry, chip was in standby */
+               usleep_range(6000, 10000);
+               r = i2c_master_send(client, skb->data, skb->len);
+       }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0273-ARM-dts-Add-nfc-node-for-PQ-board.patch b/patches.tizen/0273-ARM-dts-Add-nfc-node-for-PQ-board.patch
new file mode 100644 (file)
index 0000000..f9083b0
--- /dev/null
@@ -0,0 +1,45 @@
+From 4d115eb80d785b5a90dd168f39d97cff16c154a3 Mon Sep 17 00:00:00 2001
+From: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Date: Thu, 13 Jun 2013 13:23:48 +0200
+Subject: [PATCH 0273/1302] ARM: dts: Add nfc node for PQ board
+
+This patch adds nxp pn544-hci nfc controller node.
+
+Signed-off-by: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index d32fe16..c5ed477 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -341,6 +341,24 @@
+               };
+       };
++      i2c@138B0000 {
++              samsung,i2c-sda-delay = <100>;
++              samsung,i2c-slave-addr = <0x10>;
++              samsung,i2c-max-bus-freq = <100000>;
++              pinctrl-0 = <&i2c5_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              pn544@2b {
++                      compatible = "nxp,pn544-hci-i2c";
++                      reg = <0x2b>;
++                      interrupt-parent = <&gpx1>;
++                      interrupts = <7 1>;
++                      gpios = <&gpl2 6 0>,    /* GPIO_ENABLE */
++                              <&gpl2 7 0>;    /* GPIO_FW_RESET */
++              };
++      };
++
+       i2c@138D0000 {
+               samsung,i2c-sda-delay = <100>;
+               samsung,i2c-slave-addr = <0x10>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0274-tizen_defconfig-update.patch b/patches.tizen/0274-tizen_defconfig-update.patch
new file mode 100644 (file)
index 0000000..c775d23
--- /dev/null
@@ -0,0 +1,136 @@
+From baf3f5eede2697f20644ac917617b76456742945 Mon Sep 17 00:00:00 2001
+From: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Date: Tue, 28 May 2013 09:03:43 +0200
+Subject: [PATCH 0274/1302] tizen_defconfig update
+
+This patch enables:
+ - NFC subsystem
+ - NCI protocol
+ - NFC HCI implementation
+ - SHDLC link layer for HCI NFC drivers
+ - NFC PN544 driver support
+ - GP2AP002A00F light/priximity sensor
+ - LSM330DLC sensor IIO driver
+ - buffer support within IIO
+
+Signed-off-by: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_defconfig | 42 +++++++++++++++++++++++++++++++---------
+ 1 file changed, 33 insertions(+), 9 deletions(-)
+
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index 8b4dc03..0ab7ac0 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -1013,7 +1013,18 @@ CONFIG_RFKILL_LEDS=y
+ # CONFIG_NET_9P is not set
+ # CONFIG_CAIF is not set
+ # CONFIG_CEPH_LIB is not set
+-# CONFIG_NFC is not set
++CONFIG_NFC=y
++CONFIG_NFC_NCI=y
++CONFIG_NFC_HCI=y
++CONFIG_NFC_SHDLC=y
++
++#
++# Near Field Communication (NFC) devices
++#
++# CONFIG_NFC_PN533 is not set
++CONFIG_NFC_PN544=y
++CONFIG_NFC_PN544_I2C=y
++# CONFIG_NFC_MICROREAD is not set
+ CONFIG_HAVE_BPF_JIT=y
+ #
+@@ -2499,10 +2510,6 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+ #
+ CONFIG_LEDS_TRIGGER_TRANSIENT=y
+ # CONFIG_LEDS_TRIGGER_CAMERA is not set
+-CONFIG_SENSORS_CORE=y
+-CONFIG_SENSORS_AK8975_=y
+-CONFIG_SENSORS_LSM330DLC=y
+-CONFIG_SENSORS_LPS331=y
+ # CONFIG_ACCESSIBILITY is not set
+ # CONFIG_EDAC is not set
+ CONFIG_RTC_LIB=y
+@@ -2651,6 +2658,7 @@ CONFIG_STAGING=y
+ # CONFIG_ADIS16220 is not set
+ # CONFIG_ADIS16240 is not set
+ # CONFIG_LIS3L02DQ is not set
++# CONFIG_SCA3000 is not set
+ #
+ # Analog to digital converters
+@@ -2730,6 +2738,9 @@ CONFIG_STAGING=y
+ #
+ # Triggers - standalone
+ #
++# CONFIG_IIO_PERIODIC_RTC_TRIGGER is not set
++# CONFIG_IIO_GPIO_TRIGGER is not set
++# CONFIG_IIO_SYSFS_TRIGGER is not set
+ # CONFIG_IIO_SIMPLE_DUMMY is not set
+ # CONFIG_ZSMALLOC is not set
+ # CONFIG_USB_ENESTORAGE is not set
+@@ -2796,14 +2807,20 @@ CONFIG_EXYNOS_IOMMU=y
+ # CONFIG_EXTCON is not set
+ # CONFIG_MEMORY is not set
+ CONFIG_IIO=y
+-# CONFIG_IIO_BUFFER is not set
+-# CONFIG_IIO_TRIGGER is not set
++CONFIG_IIO_BUFFER=y
++# CONFIG_IIO_BUFFER_CB is not set
++CONFIG_IIO_KFIFO_BUF=y
++CONFIG_IIO_TRIGGERED_BUFFER=y
++CONFIG_IIO_TRIGGER=y
++CONFIG_IIO_CONSUMERS_PER_TRIGGER=2
+ #
+ # Accelerometers
+ #
+ # CONFIG_KXSD9 is not set
+-# CONFIG_IIO_ST_ACCEL_3AXIS is not set
++CONFIG_IIO_ST_ACCEL_3AXIS=y
++CONFIG_IIO_ST_ACCEL_I2C_3AXIS=y
++CONFIG_IIO_ST_ACCEL_SPI_3AXIS=y
+ #
+ # Analog to digital converters
+@@ -2827,10 +2844,14 @@ CONFIG_IIO=y
+ #
+ # Barometer sensors
+ #
++CONFIG_SENSORS_LPS331=y
+ #
+ # Hid Sensor IIO Common
+ #
++CONFIG_IIO_ST_SENSORS_I2C=y
++CONFIG_IIO_ST_SENSORS_SPI=y
++CONFIG_IIO_ST_SENSORS_CORE=y
+ #
+ # Digital to analog converters
+@@ -2870,7 +2891,9 @@ CONFIG_IIO=y
+ # CONFIG_ADIS16080 is not set
+ # CONFIG_ADIS16136 is not set
+ # CONFIG_ADXRS450 is not set
+-# CONFIG_IIO_ST_GYRO_3AXIS is not set
++CONFIG_IIO_ST_GYRO_3AXIS=y
++CONFIG_IIO_ST_GYRO_I2C_3AXIS=y
++CONFIG_IIO_ST_GYRO_SPI_3AXIS=y
+ # CONFIG_ITG3200 is not set
+ #
+@@ -2886,6 +2909,7 @@ CONFIG_IIO=y
+ # CONFIG_ADJD_S311 is not set
+ # CONFIG_SENSORS_TSL2563 is not set
+ # CONFIG_VCNL4000 is not set
++CONFIG_GP2AP002A00F=y
+ #
+ # Magnetometer sensors
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0275-media-exynos4-is-Drop-drvdata-handling-in-fimc-lite-.patch b/patches.tizen/0275-media-exynos4-is-Drop-drvdata-handling-in-fimc-lite-.patch
new file mode 100644 (file)
index 0000000..efbc8f1
--- /dev/null
@@ -0,0 +1,49 @@
+From dff991e4aa5e579bbbf5dee5d44652a92f187f09 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Tue, 11 Jun 2013 10:44:38 -0300
+Subject: [PATCH 0275/1302] [media] exynos4-is: Drop drvdata handling in
+ fimc-lite for non-dt platforms
+
+The FIMC-LITE IP block is available only on platforms instantiated
+from device tree.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-lite.c | 3 ---
+ drivers/media/platform/exynos4-is/fimc-lite.h | 3 ---
+ 2 files changed, 6 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
+index 3f76f8a..00c525c 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite.c
++++ b/drivers/media/platform/exynos4-is/fimc-lite.c
+@@ -1449,9 +1449,6 @@ static int fimc_lite_probe(struct platform_device *pdev)
+               if (of_id)
+                       drv_data = (struct flite_drvdata *)of_id->data;
+               fimc->index = of_alias_get_id(dev->of_node, "fimc-lite");
+-      } else {
+-              drv_data = fimc_lite_get_drvdata(pdev);
+-              fimc->index = pdev->id;
+       }
+       if (!drv_data || fimc->index < 0 || fimc->index >= FIMC_LITE_MAX_DEVS)
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite.h b/drivers/media/platform/exynos4-is/fimc-lite.h
+index c7aa084..4b10684 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite.h
++++ b/drivers/media/platform/exynos4-is/fimc-lite.h
+@@ -56,9 +56,6 @@ struct flite_drvdata {
+       unsigned short out_hor_offs_align;
+ };
+-#define fimc_lite_get_drvdata(_pdev) \
+-      ((struct flite_drvdata *) platform_get_device_id(_pdev)->driver_data)
+-
+ struct fimc_lite_events {
+       unsigned int data_overflow;
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0276-media-exynos4-is-Add-Exynos5250-SoC-support-to-fimc-.patch b/patches.tizen/0276-media-exynos4-is-Add-Exynos5250-SoC-support-to-fimc-.patch
new file mode 100644 (file)
index 0000000..2564f57
--- /dev/null
@@ -0,0 +1,369 @@
+From 80673331acd79fbf8e0bf19b19c5bd3126513958 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 14 Jun 2013 12:38:15 -0300
+Subject: [PATCH 0276/1302] [media] exynos4-is: Add Exynos5250 SoC support to
+ fimc-lite driver
+
+This patch adds support for the Exynos5250 SoC variant of the FIMC-LITE
+IP. A 'compatible' string is added for Exynos5250 compatible devices
+and the capture DMA handling is reworked to use the FLITE_REG_CIFCNTSEQ
+register, masking output DMA buffer address slots. The frame interrupt
+is enabled so there are now 2 interrupts per frame. This likely can be
+optimized in future by using any status registers that allow to figure
+out what the last and the currently written frame buffer is. It would
+also be more reliable in cases where there are high interrupt service
+latencies.
+
+Signed-off-by: Shaik Ameer Basha <shaik.ameer@samsung.com>
+Signed-off-by: Arun Kumar K <arun.kk@samsung.com>
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/media/exynos-fimc-lite.txt |  6 ++-
+ drivers/media/platform/exynos4-is/fimc-lite-reg.c  | 53 ++++++++++++++++++++--
+ drivers/media/platform/exynos4-is/fimc-lite-reg.h  | 10 +++-
+ drivers/media/platform/exynos4-is/fimc-lite.c      | 50 +++++++++++++++++---
+ drivers/media/platform/exynos4-is/fimc-lite.h      | 22 ++++++++-
+ 5 files changed, 125 insertions(+), 16 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt b/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt
+index de9f6b7..0bf6fb7 100644
+--- a/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt
++++ b/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt
+@@ -2,8 +2,10 @@ Exynos4x12/Exynos5 SoC series camera host interface (FIMC-LITE)
+ Required properties:
+-- compatible  : should be "samsung,exynos4212-fimc-lite" for Exynos4212 and
+-                Exynos4412 SoCs;
++- compatible  : should be one of:
++                "samsung,exynos4212-fimc-lite" for Exynos4212/4412 SoCs,
++                "samsung,exynos5250-fimc-lite" for Exynos5250 compatible
++                 devices;
+ - reg         : physical base address and size of the device memory mapped
+                 registers;
+ - interrupts  : should contain FIMC-LITE interrupt;
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite-reg.c b/drivers/media/platform/exynos4-is/fimc-lite-reg.c
+index eb4f763..72a343e3b 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite-reg.c
++++ b/drivers/media/platform/exynos4-is/fimc-lite-reg.c
+@@ -2,15 +2,16 @@
+  * Register interface file for EXYNOS FIMC-LITE (camera interface) driver
+  *
+  * Copyright (C) 2012 Samsung Electronics Co., Ltd.
+- * Sylwester Nawrocki <s.nawrocki@samsung.com>
++ * Author: Sylwester Nawrocki <s.nawrocki@samsung.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/io.h>
++#include <linux/bitops.h>
+ #include <linux/delay.h>
++#include <linux/io.h>
+ #include <media/s5p_fimc.h>
+ #include "fimc-lite-reg.h"
+@@ -68,7 +69,8 @@ void flite_hw_set_interrupt_mask(struct fimc_lite *dev)
+       if (atomic_read(&dev->out_path) == FIMC_IO_DMA) {
+               intsrc = FLITE_REG_CIGCTRL_IRQ_OVFEN |
+                        FLITE_REG_CIGCTRL_IRQ_LASTEN |
+-                       FLITE_REG_CIGCTRL_IRQ_STARTEN;
++                       FLITE_REG_CIGCTRL_IRQ_STARTEN |
++                       FLITE_REG_CIGCTRL_IRQ_ENDEN;
+       } else {
+               /* An output to the FIMC-IS */
+               intsrc = FLITE_REG_CIGCTRL_IRQ_OVFEN |
+@@ -215,6 +217,18 @@ void flite_hw_set_camera_bus(struct fimc_lite *dev,
+       flite_hw_set_camera_port(dev, si->mux_id);
+ }
++static void flite_hw_set_pack12(struct fimc_lite *dev, int on)
++{
++      u32 cfg = readl(dev->regs + FLITE_REG_CIODMAFMT);
++
++      cfg &= ~FLITE_REG_CIODMAFMT_PACK12;
++
++      if (on)
++              cfg |= FLITE_REG_CIODMAFMT_PACK12;
++
++      writel(cfg, dev->regs + FLITE_REG_CIODMAFMT);
++}
++
+ static void flite_hw_set_out_order(struct fimc_lite *dev, struct flite_frame *f)
+ {
+       static const u32 pixcode[4][2] = {
+@@ -250,6 +264,38 @@ void flite_hw_set_dma_window(struct fimc_lite *dev, struct flite_frame *f)
+       writel(cfg, dev->regs + FLITE_REG_CIOOFF);
+ }
++void flite_hw_set_dma_buffer(struct fimc_lite *dev, struct flite_buffer *buf)
++{
++      unsigned int index;
++      u32 cfg;
++
++      if (dev->dd->max_dma_bufs == 1)
++              index = 0;
++      else
++              index = buf->index;
++
++      if (index == 0)
++              writel(buf->paddr, dev->regs + FLITE_REG_CIOSA);
++      else
++              writel(buf->paddr, dev->regs + FLITE_REG_CIOSAN(index - 1));
++
++      cfg = readl(dev->regs + FLITE_REG_CIFCNTSEQ);
++      cfg |= BIT(index);
++      writel(cfg, dev->regs + FLITE_REG_CIFCNTSEQ);
++}
++
++void flite_hw_mask_dma_buffer(struct fimc_lite *dev, u32 index)
++{
++      u32 cfg;
++
++      if (dev->dd->max_dma_bufs == 1)
++              index = 0;
++
++      cfg = readl(dev->regs + FLITE_REG_CIFCNTSEQ);
++      cfg &= ~BIT(index);
++      writel(cfg, dev->regs + FLITE_REG_CIFCNTSEQ);
++}
++
+ /* Enable/disable output DMA, set output pixel size and offsets (composition) */
+ void flite_hw_set_output_dma(struct fimc_lite *dev, struct flite_frame *f,
+                            bool enable)
+@@ -267,6 +313,7 @@ void flite_hw_set_output_dma(struct fimc_lite *dev, struct flite_frame *f,
+       flite_hw_set_out_order(dev, f);
+       flite_hw_set_dma_window(dev, f);
++      flite_hw_set_pack12(dev, 0);
+ }
+ void flite_hw_dump_regs(struct fimc_lite *dev, const char *label)
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite-reg.h b/drivers/media/platform/exynos4-is/fimc-lite-reg.h
+index 3903839..10a7d7b 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite-reg.h
++++ b/drivers/media/platform/exynos4-is/fimc-lite-reg.h
+@@ -120,6 +120,9 @@
+ /* b0: 1 - camera B, 0 - camera A */
+ #define FLITE_REG_CIGENERAL_CAM_B             (1 << 0)
++#define FLITE_REG_CIFCNTSEQ                   0x100
++#define FLITE_REG_CIOSAN(x)                   (0x200 + (4 * (x)))
++
+ /* ----------------------------------------------------------------------------
+  * Function declarations
+  */
+@@ -142,9 +145,12 @@ void flite_hw_set_output_dma(struct fimc_lite *dev, struct flite_frame *f,
+ void flite_hw_set_dma_window(struct fimc_lite *dev, struct flite_frame *f);
+ void flite_hw_set_test_pattern(struct fimc_lite *dev, bool on);
+ void flite_hw_dump_regs(struct fimc_lite *dev, const char *label);
++void flite_hw_set_dma_buffer(struct fimc_lite *dev, struct flite_buffer *buf);
++void flite_hw_mask_dma_buffer(struct fimc_lite *dev, u32 index);
+-static inline void flite_hw_set_output_addr(struct fimc_lite *dev, u32 paddr)
++static inline void flite_hw_set_dma_buf_mask(struct fimc_lite *dev, u32 mask)
+ {
+-      writel(paddr, dev->regs + FLITE_REG_CIOSA);
++      writel(mask, dev->regs + FLITE_REG_CIFCNTSEQ);
+ }
++
+ #endif /* FIMC_LITE_REG_H */
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
+index 00c525c..07767c8 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite.c
++++ b/drivers/media/platform/exynos4-is/fimc-lite.c
+@@ -153,6 +153,7 @@ static int fimc_lite_hw_init(struct fimc_lite *fimc, bool isp_output)
+       flite_hw_set_camera_bus(fimc, si);
+       flite_hw_set_source_format(fimc, &fimc->inp_frame);
+       flite_hw_set_window_offset(fimc, &fimc->inp_frame);
++      flite_hw_set_dma_buf_mask(fimc, 0);
+       flite_hw_set_output_dma(fimc, &fimc->out_frame, !isp_output);
+       flite_hw_set_interrupt_mask(fimc);
+       flite_hw_set_test_pattern(fimc, fimc->test_pattern->val);
+@@ -276,19 +277,23 @@ static irqreturn_t flite_irq_handler(int irq, void *priv)
+       if ((intsrc & FLITE_REG_CISTATUS_IRQ_SRC_FRMSTART) &&
+           test_bit(ST_FLITE_RUN, &fimc->state) &&
+-          !list_empty(&fimc->active_buf_q) &&
+           !list_empty(&fimc->pending_buf_q)) {
++              vbuf = fimc_lite_pending_queue_pop(fimc);
++              flite_hw_set_dma_buffer(fimc, vbuf);
++              fimc_lite_active_queue_add(fimc, vbuf);
++      }
++
++      if ((intsrc & FLITE_REG_CISTATUS_IRQ_SRC_FRMEND) &&
++          test_bit(ST_FLITE_RUN, &fimc->state) &&
++          !list_empty(&fimc->active_buf_q)) {
+               vbuf = fimc_lite_active_queue_pop(fimc);
+               ktime_get_ts(&ts);
+               tv = &vbuf->vb.v4l2_buf.timestamp;
+               tv->tv_sec = ts.tv_sec;
+               tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
+               vbuf->vb.v4l2_buf.sequence = fimc->frame_count++;
++              flite_hw_mask_dma_buffer(fimc, vbuf->index);
+               vb2_buffer_done(&vbuf->vb, VB2_BUF_STATE_DONE);
+-
+-              vbuf = fimc_lite_pending_queue_pop(fimc);
+-              flite_hw_set_output_addr(fimc, vbuf->paddr);
+-              fimc_lite_active_queue_add(fimc, vbuf);
+       }
+       if (test_bit(ST_FLITE_CONFIG, &fimc->state))
+@@ -307,10 +312,16 @@ done:
+ static int start_streaming(struct vb2_queue *q, unsigned int count)
+ {
+       struct fimc_lite *fimc = q->drv_priv;
++      unsigned long flags;
+       int ret;
++      spin_lock_irqsave(&fimc->slock, flags);
++
++      fimc->buf_index = 0;
+       fimc->frame_count = 0;
++      spin_unlock_irqrestore(&fimc->slock, flags);
++
+       ret = fimc_lite_hw_init(fimc, false);
+       if (ret) {
+               fimc_lite_reinit(fimc, false);
+@@ -412,10 +423,14 @@ static void buffer_queue(struct vb2_buffer *vb)
+       spin_lock_irqsave(&fimc->slock, flags);
+       buf->paddr = vb2_dma_contig_plane_dma_addr(vb, 0);
++      buf->index = fimc->buf_index++;
++      if (fimc->buf_index >= fimc->reqbufs_count)
++              fimc->buf_index = 0;
++
+       if (!test_bit(ST_FLITE_SUSPENDED, &fimc->state) &&
+           !test_bit(ST_FLITE_STREAM, &fimc->state) &&
+           list_empty(&fimc->active_buf_q)) {
+-              flite_hw_set_output_addr(fimc, buf->paddr);
++              flite_hw_set_dma_buffer(fimc, buf);
+               fimc_lite_active_queue_add(fimc, buf);
+       } else {
+               fimc_lite_pending_queue_add(fimc, buf);
+@@ -1451,8 +1466,12 @@ static int fimc_lite_probe(struct platform_device *pdev)
+               fimc->index = of_alias_get_id(dev->of_node, "fimc-lite");
+       }
+-      if (!drv_data || fimc->index < 0 || fimc->index >= FIMC_LITE_MAX_DEVS)
++      if (!drv_data || fimc->index >= drv_data->num_instances ||
++                                              fimc->index < 0) {
++              dev_err(dev, "Wrong %s node alias\n",
++                                      dev->of_node->full_name);
+               return -EINVAL;
++      }
+       fimc->dd = drv_data;
+       fimc->pdev = pdev;
+@@ -1609,6 +1628,19 @@ static struct flite_drvdata fimc_lite_drvdata_exynos4 = {
+       .out_width_align        = 8,
+       .win_hor_offs_align     = 2,
+       .out_hor_offs_align     = 8,
++      .max_dma_bufs           = 1,
++      .num_instances          = 2,
++};
++
++/* EXYNOS5250 */
++static struct flite_drvdata fimc_lite_drvdata_exynos5 = {
++      .max_width              = 8192,
++      .max_height             = 8192,
++      .out_width_align        = 8,
++      .win_hor_offs_align     = 2,
++      .out_hor_offs_align     = 8,
++      .max_dma_bufs           = 32,
++      .num_instances          = 3,
+ };
+ static const struct of_device_id flite_of_match[] = {
+@@ -1616,6 +1648,10 @@ static const struct of_device_id flite_of_match[] = {
+               .compatible = "samsung,exynos4212-fimc-lite",
+               .data = &fimc_lite_drvdata_exynos4,
+       },
++      {
++              .compatible = "samsung,exynos5250-fimc-lite",
++              .data = &fimc_lite_drvdata_exynos5,
++      },
+       { /* sentinel */ },
+ };
+ MODULE_DEVICE_TABLE(of, flite_of_match);
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite.h b/drivers/media/platform/exynos4-is/fimc-lite.h
+index 4b10684..c98f3da 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite.h
++++ b/drivers/media/platform/exynos4-is/fimc-lite.h
+@@ -27,7 +27,7 @@
+ #define FIMC_LITE_DRV_NAME    "exynos-fimc-lite"
+ #define FLITE_CLK_NAME                "flite"
+-#define FIMC_LITE_MAX_DEVS    2
++#define FIMC_LITE_MAX_DEVS    3
+ #define FLITE_REQ_BUFS_MIN    2
+ /* Bit index definitions for struct fimc_lite::state */
+@@ -48,12 +48,26 @@ enum {
+ #define FLITE_SD_PAD_SOURCE_ISP       2
+ #define FLITE_SD_PADS_NUM     3
++/**
++ * struct flite_drvdata - FIMC-LITE IP variant data structure
++ * @max_width: maximum camera interface input width in pixels
++ * @max_height: maximum camera interface input height in pixels
++ * @out_width_align: minimum output width alignment in pixels
++ * @win_hor_offs_align: minimum camera interface crop window horizontal
++ *                    offset alignment in pixels
++ * @out_hor_offs_align: minimum output DMA compose rectangle horizontal
++ *                    offset alignment in pixels
++ * @max_dma_bufs: number of output DMA buffer start address registers
++ * @num_instances: total number of FIMC-LITE IP instances available
++ */
+ struct flite_drvdata {
+       unsigned short max_width;
+       unsigned short max_height;
+       unsigned short out_width_align;
+       unsigned short win_hor_offs_align;
+       unsigned short out_hor_offs_align;
++      unsigned short max_dma_bufs;
++      unsigned short num_instances;
+ };
+ struct fimc_lite_events {
+@@ -80,12 +94,14 @@ struct flite_frame {
+  * struct flite_buffer - video buffer structure
+  * @vb:    vb2 buffer
+  * @list:  list head for the buffers queue
+- * @paddr: precalculated physical address
++ * @paddr: DMA buffer start address
++ * @index: DMA start address register's index
+  */
+ struct flite_buffer {
+       struct vb2_buffer vb;
+       struct list_head list;
+       dma_addr_t paddr;
++      unsigned short index;
+ };
+ /**
+@@ -119,6 +135,7 @@ struct flite_buffer {
+  * @pending_buf_q: pending buffers queue head
+  * @active_buf_q: the queue head of buffers scheduled in hardware
+  * @vb_queue: vb2 buffers queue
++ * @buf_index: helps to keep track of the DMA start address register index
+  * @active_buf_count: number of video buffers scheduled in hardware
+  * @frame_count: the captured frames counter
+  * @reqbufs_count: the number of buffers requested with REQBUFS ioctl
+@@ -155,6 +172,7 @@ struct fimc_lite {
+       struct list_head        pending_buf_q;
+       struct list_head        active_buf_q;
+       struct vb2_queue        vb_queue;
++      unsigned short          buf_index;
+       unsigned int            frame_count;
+       unsigned int            reqbufs_count;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0277-media-exynos4-is-Add-support-for-Exynos5250-MIPI-CSI.patch b/patches.tizen/0277-media-exynos4-is-Add-support-for-Exynos5250-MIPI-CSI.patch
new file mode 100644 (file)
index 0000000..be84cec
--- /dev/null
@@ -0,0 +1,204 @@
+From e7c81d3f56036eab0594ceca87088871203cdc51 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 31 May 2013 10:38:23 -0300
+Subject: [PATCH 0277/1302] [media] exynos4-is: Add support for Exynos5250
+ MIPI-CSIS
+
+Add compatible property for the Exynos5250 and enable the frame start
+and frame end interrupts. These interrupts are needed for the Exynos5
+FIMC-IS firmware. The driver enables those interrupt only where available,
+depending on the 'compatible' property. This can be optimized further,
+by exposing some API at the subdev driver, so the host driver can enable
+extra interrupts only for the image processing chains involving FIMC-IS.
+
+Signed-off-by: Shaik Ameer Basha <shaik.ameer@samsung.com>
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../bindings/media/samsung-mipi-csis.txt           |  4 +-
+ drivers/media/platform/exynos4-is/mipi-csis.c      | 67 ++++++++++++++++++----
+ 2 files changed, 58 insertions(+), 13 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/media/samsung-mipi-csis.txt b/Documentation/devicetree/bindings/media/samsung-mipi-csis.txt
+index 5f8e28e..be45f0b 100644
+--- a/Documentation/devicetree/bindings/media/samsung-mipi-csis.txt
++++ b/Documentation/devicetree/bindings/media/samsung-mipi-csis.txt
+@@ -5,8 +5,8 @@ Required properties:
+ - compatible    : "samsung,s5pv210-csis" for S5PV210 (S5PC110),
+                   "samsung,exynos4210-csis" for Exynos4210 (S5PC210),
+-                  "samsung,exynos4212-csis" for Exynos4212/Exynos4412
+-                  SoC series;
++                  "samsung,exynos4212-csis" for Exynos4212/Exynos4412,
++                  "samsung,exynos5250-csis" for Exynos5250;
+ - reg           : offset and length of the register set for the device;
+ - interrupts      : should contain MIPI CSIS interrupt; the format of the
+                   interrupt specifier depends on the interrupt controller;
+diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
+index ae99803..0fe80e3 100644
+--- a/drivers/media/platform/exynos4-is/mipi-csis.c
++++ b/drivers/media/platform/exynos4-is/mipi-csis.c
+@@ -1,8 +1,8 @@
+ /*
+- * Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver
++ * Samsung S5P/EXYNOS SoC series MIPI-CSI receiver driver
+  *
+- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd.
+- * Sylwester Nawrocki <s.nawrocki@samsung.com>
++ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd.
++ * Author: Sylwester Nawrocki <s.nawrocki@samsung.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
+@@ -66,11 +66,12 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)");
+ /* Interrupt mask */
+ #define S5PCSIS_INTMSK                        0x10
+-#define S5PCSIS_INTMSK_EN_ALL         0xf000103f
+ #define S5PCSIS_INTMSK_EVEN_BEFORE    (1 << 31)
+ #define S5PCSIS_INTMSK_EVEN_AFTER     (1 << 30)
+ #define S5PCSIS_INTMSK_ODD_BEFORE     (1 << 29)
+ #define S5PCSIS_INTMSK_ODD_AFTER      (1 << 28)
++#define S5PCSIS_INTMSK_FRAME_START    (1 << 27)
++#define S5PCSIS_INTMSK_FRAME_END      (1 << 26)
+ #define S5PCSIS_INTMSK_ERR_SOT_HS     (1 << 12)
+ #define S5PCSIS_INTMSK_ERR_LOST_FS    (1 << 5)
+ #define S5PCSIS_INTMSK_ERR_LOST_FE    (1 << 4)
+@@ -78,6 +79,8 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)");
+ #define S5PCSIS_INTMSK_ERR_ECC                (1 << 2)
+ #define S5PCSIS_INTMSK_ERR_CRC                (1 << 1)
+ #define S5PCSIS_INTMSK_ERR_UNKNOWN    (1 << 0)
++#define S5PCSIS_INTMSK_EXYNOS4_EN_ALL 0xf000103f
++#define S5PCSIS_INTMSK_EXYNOS5_EN_ALL 0xfc00103f
+ /* Interrupt source */
+ #define S5PCSIS_INTSRC                        0x14
+@@ -88,6 +91,8 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)");
+ #define S5PCSIS_INTSRC_ODD_AFTER      (1 << 28)
+ #define S5PCSIS_INTSRC_ODD            (0x3 << 28)
+ #define S5PCSIS_INTSRC_NON_IMAGE_DATA (0xff << 28)
++#define S5PCSIS_INTSRC_FRAME_START    (1 << 27)
++#define S5PCSIS_INTSRC_FRAME_END      (1 << 26)
+ #define S5PCSIS_INTSRC_ERR_SOT_HS     (0xf << 12)
+ #define S5PCSIS_INTSRC_ERR_LOST_FS    (1 << 5)
+ #define S5PCSIS_INTSRC_ERR_LOST_FE    (1 << 4)
+@@ -155,6 +160,9 @@ static const struct s5pcsis_event s5pcsis_events[] = {
+       { S5PCSIS_INTSRC_EVEN_AFTER,    "Non-image data after even frame" },
+       { S5PCSIS_INTSRC_ODD_BEFORE,    "Non-image data before odd frame" },
+       { S5PCSIS_INTSRC_ODD_AFTER,     "Non-image data after odd frame" },
++      /* Frame start/end */
++      { S5PCSIS_INTSRC_FRAME_START,   "Frame Start" },
++      { S5PCSIS_INTSRC_FRAME_END,     "Frame End" },
+ };
+ #define S5PCSIS_NUM_EVENTS ARRAY_SIZE(s5pcsis_events)
+@@ -163,6 +171,11 @@ struct csis_pktbuf {
+       unsigned int len;
+ };
++struct csis_drvdata {
++      /* Mask of all used interrupts in S5PCSIS_INTMSK register */
++      u32 interrupt_mask;
++};
++
+ /**
+  * struct csis_state - the driver's internal state data structure
+  * @lock: mutex serializing the subdev and power management operations,
+@@ -175,6 +188,7 @@ struct csis_pktbuf {
+  * @supplies: CSIS regulator supplies
+  * @clock: CSIS clocks
+  * @irq: requested s5p-mipi-csis irq number
++ * @interrupt_mask: interrupt mask of the all used interrupts
+  * @flags: the state variable for power and streaming control
+  * @clock_frequency: device bus clock frequency
+  * @hs_settle: HS-RX settle time
+@@ -197,6 +211,7 @@ struct csis_state {
+       struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES];
+       struct clk *clock[NUM_CSIS_CLOCKS];
+       int irq;
++      u32 interrupt_mask;
+       u32 flags;
+       u32 clk_frequency;
+@@ -278,9 +293,10 @@ static const struct csis_pix_format *find_csis_format(
+ static void s5pcsis_enable_interrupts(struct csis_state *state, bool on)
+ {
+       u32 val = s5pcsis_read(state, S5PCSIS_INTMSK);
+-
+-      val = on ? val | S5PCSIS_INTMSK_EN_ALL :
+-                 val & ~S5PCSIS_INTMSK_EN_ALL;
++      if (on)
++              val |= state->interrupt_mask;
++      else
++              val &= ~state->interrupt_mask;
+       s5pcsis_write(state, S5PCSIS_INTMSK, val);
+ }
+@@ -803,8 +819,12 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
+ #define s5pcsis_parse_dt(pdev, state) (-ENOSYS)
+ #endif
++static const struct of_device_id s5pcsis_of_match[];
++
+ static int s5pcsis_probe(struct platform_device *pdev)
+ {
++      const struct of_device_id *of_id;
++      const struct csis_drvdata *drv_data;
+       struct device *dev = &pdev->dev;
+       struct resource *mem_res;
+       struct csis_state *state;
+@@ -819,10 +839,19 @@ static int s5pcsis_probe(struct platform_device *pdev)
+       spin_lock_init(&state->slock);
+       state->pdev = pdev;
+-      if (dev->of_node)
++      if (dev->of_node) {
++              of_id = of_match_node(s5pcsis_of_match, dev->of_node);
++              if (WARN_ON(of_id == NULL))
++                      return -EINVAL;
++
++              drv_data = of_id->data;
++              state->interrupt_mask = drv_data->interrupt_mask;
++
+               ret = s5pcsis_parse_dt(pdev, state);
+-      else
++      } else {
+               ret = s5pcsis_get_platform_data(pdev, state);
++      }
++
+       if (ret < 0)
+               return ret;
+@@ -1018,9 +1047,25 @@ static const struct dev_pm_ops s5pcsis_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(s5pcsis_suspend, s5pcsis_resume)
+ };
++static const struct csis_drvdata exynos4_csis_drvdata = {
++      .interrupt_mask = S5PCSIS_INTMSK_EXYNOS4_EN_ALL,
++};
++
++static const struct csis_drvdata exynos5_csis_drvdata = {
++      .interrupt_mask = S5PCSIS_INTMSK_EXYNOS5_EN_ALL,
++};
++
+ static const struct of_device_id s5pcsis_of_match[] = {
+-      { .compatible = "samsung,s5pv210-csis" },
+-      { .compatible = "samsung,exynos4210-csis" },
++      {
++              .compatible = "samsung,s5pv210-csis",
++              .data = &exynos4_csis_drvdata,
++      }, {
++              .compatible = "samsung,exynos4210-csis",
++              .data = &exynos4_csis_drvdata,
++      }, {
++              .compatible = "samsung,exynos5250-csis",
++              .data = &exynos5_csis_drvdata,
++      },
+       { /* sentinel */ },
+ };
+ MODULE_DEVICE_TABLE(of, s5pcsis_of_match);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0278-media-exynos4-is-Change-fimc-is-firmware-file-names.patch b/patches.tizen/0278-media-exynos4-is-Change-fimc-is-firmware-file-names.patch
new file mode 100644 (file)
index 0000000..83b9ebb
--- /dev/null
@@ -0,0 +1,40 @@
+From 0fa401d69da1bee519518833d4cf1eebccf25bac Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 31 May 2013 10:36:19 -0300
+Subject: [PATCH 0278/1302] [media] exynos4-is: Change fimc-is firmware file
+ names
+
+This patch changes the firmware file names of the FIMC-IS subsystem.
+It is needed since there are different firmwares used across various
+SoC series, e.g. Exynos4 and Exynos5.
+Also the sensor specific "setfile" name is changed, to account for
+it depends on an image sensor and is also specific to the FIMC-IS
+and the SoC.
+This is a change for a driver merged in 3.10.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-is.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-is.h b/drivers/media/platform/exynos4-is/fimc-is.h
+index 08fa518..61bb012 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is.h
++++ b/drivers/media/platform/exynos4-is/fimc-is.h
+@@ -33,8 +33,8 @@
+ #define FIMC_IS_DRV_NAME              "exynos4-fimc-is"
+-#define FIMC_IS_FW_FILENAME           "fimc_is_fw.bin"
+-#define FIMC_IS_SETFILE_6A3           "setfile.bin"
++#define FIMC_IS_FW_FILENAME           "exynos4_fimc_is_fw.bin"
++#define FIMC_IS_SETFILE_6A3           "exynos4_s5k6a3_setfile.bin"
+ #define FIMC_IS_FW_LOAD_TIMEOUT               1000 /* ms */
+ #define FIMC_IS_POWER_ON_TIMEOUT      1000 /* us */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0279-media-exynos4-is-Fix-format-propagation-on-FIMC-LITE.patch b/patches.tizen/0279-media-exynos4-is-Fix-format-propagation-on-FIMC-LITE.patch
new file mode 100644 (file)
index 0000000..2e95aa9
--- /dev/null
@@ -0,0 +1,165 @@
+From 26fae0983185746e0a2e5441ed542717909c3b92 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 20 Jun 2013 10:57:47 -0300
+Subject: [PATCH 0279/1302] [media] exynos4-is: Fix format propagation on
+ FIMC-LITE.n subdevs
+
+FIMC-LITE subdevs have one sink pad and two source pads on which the image
+formats are always same. This patch implements missing format propagation
+from the sink pad to the source pads, to allow user space to negotiate TRY
+format on whole media pipeline involving FIMC-LITE.n subdevs. The subdev
+try_fmt helper is simplified.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-lite.c | 92 +++++++++++++++++----------
+ 1 file changed, 59 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
+index 07767c8..993bd79 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite.c
++++ b/drivers/media/platform/exynos4-is/fimc-lite.c
+@@ -560,37 +560,51 @@ static const struct v4l2_file_operations fimc_lite_fops = {
+  * Format and crop negotiation helpers
+  */
+-static const struct fimc_fmt *fimc_lite_try_format(struct fimc_lite *fimc,
+-                                      u32 *width, u32 *height,
+-                                      u32 *code, u32 *fourcc, int pad)
++static const struct fimc_fmt *fimc_lite_subdev_try_fmt(struct fimc_lite *fimc,
++                                      struct v4l2_subdev_fh *fh,
++                                      struct v4l2_subdev_format *format)
+ {
+       struct flite_drvdata *dd = fimc->dd;
+-      const struct fimc_fmt *fmt;
+-      unsigned int flags = 0;
++      struct v4l2_mbus_framefmt *mf = &format->format;
++      const struct fimc_fmt *fmt = NULL;
++
++      if (format->pad == FLITE_SD_PAD_SINK) {
++              v4l_bound_align_image(&mf->width, 8, dd->max_width,
++                              ffs(dd->out_width_align) - 1,
++                              &mf->height, 0, dd->max_height, 0, 0);
+-      if (pad == FLITE_SD_PAD_SINK) {
+-              v4l_bound_align_image(width, 8, dd->max_width,
+-                                    ffs(dd->out_width_align) - 1,
+-                                    height, 0, dd->max_height, 0, 0);
++              fmt = fimc_lite_find_format(NULL, &mf->code, 0, 0);
++              if (WARN_ON(!fmt))
++                      return NULL;
++
++              mf->code = fmt->mbus_code;
+       } else {
+-              v4l_bound_align_image(width, 8, fimc->inp_frame.rect.width,
+-                                    ffs(dd->out_width_align) - 1,
+-                                    height, 0, fimc->inp_frame.rect.height,
+-                                    0, 0);
+-              flags = fimc->inp_frame.fmt->flags;
+-      }
++              struct flite_frame *sink = &fimc->inp_frame;
++              struct v4l2_mbus_framefmt *sink_fmt;
++              struct v4l2_rect *rect;
+-      fmt = fimc_lite_find_format(fourcc, code, flags, 0);
+-      if (WARN_ON(!fmt))
+-              return NULL;
++              if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
++                      sink_fmt = v4l2_subdev_get_try_format(fh,
++                                              FLITE_SD_PAD_SINK);
+-      if (code)
+-              *code = fmt->mbus_code;
+-      if (fourcc)
+-              *fourcc = fmt->fourcc;
++                      mf->code = sink_fmt->code;
++
++                      rect = v4l2_subdev_get_try_crop(fh,
++                                              FLITE_SD_PAD_SINK);
++              } else {
++                      mf->code = sink->fmt->mbus_code;
++                      rect = &sink->rect;
++              }
++
++              /* Allow changing format only on sink pad */
++              mf->width = rect->width;
++              mf->height = rect->height;
++      }
+-      v4l2_dbg(1, debug, &fimc->subdev, "code: 0x%x, %dx%d\n",
+-               code ? *code : 0, *width, *height);
++      mf->field = V4L2_FIELD_NONE;
++
++      v4l2_dbg(1, debug, &fimc->subdev, "code: %#x (%d), %dx%d\n",
++               mf->code, mf->colorspace, mf->width, mf->height);
+       return fmt;
+ }
+@@ -1035,6 +1049,15 @@ static int fimc_lite_subdev_enum_mbus_code(struct v4l2_subdev *sd,
+       return 0;
+ }
++static struct v4l2_mbus_framefmt *__fimc_lite_subdev_get_try_fmt(
++                      struct v4l2_subdev_fh *fh, unsigned int pad)
++{
++      if (pad != FLITE_SD_PAD_SINK)
++              pad = FLITE_SD_PAD_SOURCE_DMA;
++
++      return v4l2_subdev_get_try_format(fh, pad);
++}
++
+ static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd,
+                                   struct v4l2_subdev_fh *fh,
+                                   struct v4l2_subdev_format *fmt)
+@@ -1044,7 +1067,7 @@ static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd,
+       struct flite_frame *f = &fimc->inp_frame;
+       if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+-              mf = v4l2_subdev_get_try_format(fh, fmt->pad);
++              mf = __fimc_lite_subdev_get_try_fmt(fh, fmt->pad);
+               fmt->format = *mf;
+               return 0;
+       }
+@@ -1090,12 +1113,20 @@ static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd,
+               return -EBUSY;
+       }
+-      ffmt = fimc_lite_try_format(fimc, &mf->width, &mf->height,
+-                                  &mf->code, NULL, fmt->pad);
++      ffmt = fimc_lite_subdev_try_fmt(fimc, fh, fmt);
+       if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+-              mf = v4l2_subdev_get_try_format(fh, fmt->pad);
++              struct v4l2_mbus_framefmt *src_fmt;
++
++              mf = __fimc_lite_subdev_get_try_fmt(fh, fmt->pad);
+               *mf = fmt->format;
++
++              if (fmt->pad == FLITE_SD_PAD_SINK) {
++                      unsigned int pad = FLITE_SD_PAD_SOURCE_DMA;
++                      src_fmt = __fimc_lite_subdev_get_try_fmt(fh, pad);
++                      *src_fmt = *mf;
++              }
++
+               mutex_unlock(&fimc->lock);
+               return 0;
+       }
+@@ -1113,11 +1144,6 @@ static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd,
+               source->rect = sink->rect;
+               source->f_width = mf->width;
+               source->f_height = mf->height;
+-      } else {
+-              /* Allow changing format only on sink pad */
+-              mf->code = sink->fmt->mbus_code;
+-              mf->width = sink->rect.width;
+-              mf->height = sink->rect.height;
+       }
+       mutex_unlock(&fimc->lock);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0280-media-exynos4-is-Set-valid-initial-format-at-FIMC-LI.patch b/patches.tizen/0280-media-exynos4-is-Set-valid-initial-format-at-FIMC-LI.patch
new file mode 100644 (file)
index 0000000..6134995
--- /dev/null
@@ -0,0 +1,85 @@
+From 8e771ab2a0651a646094bc946a2ae4009f143201 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Tue, 18 Jun 2013 08:00:42 -0300
+Subject: [PATCH 0280/1302] [media] exynos4-is: Set valid initial format at
+ FIMC-LITE
+
+Ensure the image resolution and crop rectangle on the FIMC-LITE.n
+subdevs and fimc-lite.n.capture video nodes is properly configured
+upon the driver's initialization.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-lite.c | 23 ++++++++++++++++++++---
+ drivers/media/platform/exynos4-is/fimc-lite.h |  2 ++
+ 2 files changed, 22 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
+index 993bd79..4fa2e05 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite.c
++++ b/drivers/media/platform/exynos4-is/fimc-lite.c
+@@ -1281,9 +1281,6 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
+       int ret;
+       memset(vfd, 0, sizeof(*vfd));
+-
+-      fimc->inp_frame.fmt = &fimc_lite_formats[0];
+-      fimc->out_frame.fmt = &fimc_lite_formats[0];
+       atomic_set(&fimc->out_path, FIMC_IO_DMA);
+       snprintf(vfd->name, sizeof(vfd->name), "fimc-lite.%d.capture",
+@@ -1399,6 +1396,23 @@ static const struct v4l2_ctrl_config fimc_lite_ctrl = {
+       .step   = 1,
+ };
++static void fimc_lite_set_default_config(struct fimc_lite *fimc)
++{
++      struct flite_frame *sink = &fimc->inp_frame;
++      struct flite_frame *source = &fimc->out_frame;
++
++      sink->fmt = &fimc_lite_formats[0];
++      sink->f_width = FLITE_DEFAULT_WIDTH;
++      sink->f_height = FLITE_DEFAULT_HEIGHT;
++
++      sink->rect.width = FLITE_DEFAULT_WIDTH;
++      sink->rect.height = FLITE_DEFAULT_HEIGHT;
++      sink->rect.left = 0;
++      sink->rect.top = 0;
++
++      *source = *sink;
++}
++
+ static int fimc_lite_create_capture_subdev(struct fimc_lite *fimc)
+ {
+       struct v4l2_ctrl_handler *handler = &fimc->ctrl_handler;
+@@ -1544,8 +1558,11 @@ static int fimc_lite_probe(struct platform_device *pdev)
+               ret = PTR_ERR(fimc->alloc_ctx);
+               goto err_pm;
+       }
++
+       pm_runtime_put(dev);
++      fimc_lite_set_default_config(fimc);
++
+       dev_dbg(dev, "FIMC-LITE.%d registered successfully\n",
+               fimc->index);
+       return 0;
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite.h b/drivers/media/platform/exynos4-is/fimc-lite.h
+index c98f3da..7428b2d 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite.h
++++ b/drivers/media/platform/exynos4-is/fimc-lite.h
+@@ -29,6 +29,8 @@
+ #define FLITE_CLK_NAME                "flite"
+ #define FIMC_LITE_MAX_DEVS    3
+ #define FLITE_REQ_BUFS_MIN    2
++#define FLITE_DEFAULT_WIDTH   640
++#define FLITE_DEFAULT_HEIGHT  480
+ /* Bit index definitions for struct fimc_lite::state */
+ enum {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0281-media-exynos4-is-Fix-format-propagation-on-FIMC-IS-I.patch b/patches.tizen/0281-media-exynos4-is-Fix-format-propagation-on-FIMC-IS-I.patch
new file mode 100644 (file)
index 0000000..e646406
--- /dev/null
@@ -0,0 +1,184 @@
+From 3822ef87c381f2919b60acdc3fe150e185bc0d0a Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Tue, 18 Jun 2013 13:42:30 -0300
+Subject: [PATCH 0281/1302] [media] exynos4-is: Fix format propagation on
+ FIMC-IS-ISP subdev
+
+Ensure TRY formats are propagated from the sink pad to the source pads
+of the FIMC-IS-ISP subdev and the TRY and ACTIVE formats are separated.
+
+[mchehab@redhat.com: Whitespace cleanup]
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungin.park@samsung.com>
+
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-isp.c | 92 +++++++++++++++++++---------
+ drivers/media/platform/exynos4-is/fimc-isp.h |  3 +-
+ 2 files changed, 66 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c
+index ecb82a9..f859b3c 100644
+--- a/drivers/media/platform/exynos4-is/fimc-isp.c
++++ b/drivers/media/platform/exynos4-is/fimc-isp.c
+@@ -128,31 +128,28 @@ static int fimc_isp_subdev_get_fmt(struct v4l2_subdev *sd,
+                                  struct v4l2_subdev_format *fmt)
+ {
+       struct fimc_isp *isp = v4l2_get_subdevdata(sd);
+-      struct fimc_is *is = fimc_isp_to_is(isp);
+       struct v4l2_mbus_framefmt *mf = &fmt->format;
+-      struct v4l2_mbus_framefmt cur_fmt;
+       if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+-              mf = v4l2_subdev_get_try_format(fh, fmt->pad);
+-              fmt->format = *mf;
++              *mf = *v4l2_subdev_get_try_format(fh, fmt->pad);
+               return 0;
+       }
+       mf->colorspace = V4L2_COLORSPACE_SRGB;
+       mutex_lock(&isp->subdev_lock);
+-      __is_get_frame_size(is, &cur_fmt);
+       if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
+-              /* full camera input frame size */
+-              mf->width = cur_fmt.width + FIMC_ISP_CAC_MARGIN_WIDTH;
+-              mf->height = cur_fmt.height + FIMC_ISP_CAC_MARGIN_HEIGHT;
+-              mf->code = V4L2_MBUS_FMT_SGRBG10_1X10;
++              /* ISP OTF input image format */
++              *mf = isp->sink_fmt;
+       } else {
+-              /* crop size */
+-              mf->width = cur_fmt.width;
+-              mf->height = cur_fmt.height;
+-              mf->code = V4L2_MBUS_FMT_YUV10_1X30;
++              /* ISP OTF output image format */
++              *mf = isp->src_fmt;
++
++              if (fmt->pad == FIMC_ISP_SD_PAD_SRC_FIFO) {
++                      mf->colorspace = V4L2_COLORSPACE_JPEG;
++                      mf->code = V4L2_MBUS_FMT_YUV10_1X30;
++              }
+       }
+       mutex_unlock(&isp->subdev_lock);
+@@ -164,21 +161,37 @@ static int fimc_isp_subdev_get_fmt(struct v4l2_subdev *sd,
+ }
+ static void __isp_subdev_try_format(struct fimc_isp *isp,
+-                                 struct v4l2_subdev_format *fmt)
++                                  struct v4l2_subdev_fh *fh,
++                                  struct v4l2_subdev_format *fmt)
+ {
+       struct v4l2_mbus_framefmt *mf = &fmt->format;
++      struct v4l2_mbus_framefmt *format;
++
++      mf->colorspace = V4L2_COLORSPACE_SRGB;
+       if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
+               v4l_bound_align_image(&mf->width, FIMC_ISP_SINK_WIDTH_MIN,
+                               FIMC_ISP_SINK_WIDTH_MAX, 0,
+                               &mf->height, FIMC_ISP_SINK_HEIGHT_MIN,
+                               FIMC_ISP_SINK_HEIGHT_MAX, 0, 0);
+-              isp->subdev_fmt = *mf;
++              mf->code = V4L2_MBUS_FMT_SGRBG10_1X10;
+       } else {
++              if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
++                      format = v4l2_subdev_get_try_format(fh,
++                                              FIMC_ISP_SD_PAD_SINK);
++              else
++                      format = &isp->sink_fmt;
++
+               /* Allow changing format only on sink pad */
+-              mf->width = isp->subdev_fmt.width - FIMC_ISP_CAC_MARGIN_WIDTH;
+-              mf->height = isp->subdev_fmt.height - FIMC_ISP_CAC_MARGIN_HEIGHT;
+-              mf->code = isp->subdev_fmt.code;
++              mf->width = format->width - FIMC_ISP_CAC_MARGIN_WIDTH;
++              mf->height = format->height - FIMC_ISP_CAC_MARGIN_HEIGHT;
++
++              if (fmt->pad == FIMC_ISP_SD_PAD_SRC_FIFO) {
++                      mf->code = V4L2_MBUS_FMT_YUV10_1X30;
++                      mf->colorspace = V4L2_COLORSPACE_JPEG;
++              } else {
++                      mf->code = format->code;
++              }
+       }
+ }
+@@ -194,24 +207,47 @@ static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd,
+       isp_dbg(1, sd, "%s: pad%d: code: 0x%x, %dx%d\n",
+                __func__, fmt->pad, mf->code, mf->width, mf->height);
+-      mf->colorspace = V4L2_COLORSPACE_SRGB;
+-
+       mutex_lock(&isp->subdev_lock);
+-      __isp_subdev_try_format(isp, fmt);
++      __isp_subdev_try_format(isp, fh, fmt);
+       if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+               mf = v4l2_subdev_get_try_format(fh, fmt->pad);
+               *mf = fmt->format;
+-              mutex_unlock(&isp->subdev_lock);
+-              return 0;
++
++              /* Propagate format to the source pads */
++              if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
++                      struct v4l2_subdev_format format = *fmt;
++                      unsigned int pad;
++
++                      for (pad = FIMC_ISP_SD_PAD_SRC_FIFO;
++                                      pad < FIMC_ISP_SD_PADS_NUM; pad++) {
++                              format.pad = pad;
++                              __isp_subdev_try_format(isp, fh, &format);
++                              mf = v4l2_subdev_get_try_format(fh, pad);
++                              *mf = format.format;
++                      }
++              }
++      } else {
++              if (sd->entity.stream_count == 0) {
++                      if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
++                              struct v4l2_subdev_format format = *fmt;
++
++                              isp->sink_fmt = *mf;
++
++                              format.pad = FIMC_ISP_SD_PAD_SRC_DMA;
++                              __isp_subdev_try_format(isp, fh, &format);
++
++                              isp->src_fmt = format.format;
++                              __is_set_frame_size(is, &isp->src_fmt);
++                      } else {
++                              isp->src_fmt = *mf;
++                      }
++              } else {
++                      ret = -EBUSY;
++              }
+       }
+-      if (sd->entity.stream_count == 0)
+-              __is_set_frame_size(is, mf);
+-      else
+-              ret = -EBUSY;
+       mutex_unlock(&isp->subdev_lock);
+-
+       return ret;
+ }
+diff --git a/drivers/media/platform/exynos4-is/fimc-isp.h b/drivers/media/platform/exynos4-is/fimc-isp.h
+index 756063e..03bf95a 100644
+--- a/drivers/media/platform/exynos4-is/fimc-isp.h
++++ b/drivers/media/platform/exynos4-is/fimc-isp.h
+@@ -145,7 +145,8 @@ struct fimc_isp {
+       struct vb2_alloc_ctx            *alloc_ctx;
+       struct v4l2_subdev              subdev;
+       struct media_pad                subdev_pads[FIMC_ISP_SD_PADS_NUM];
+-      struct v4l2_mbus_framefmt       subdev_fmt;
++      struct v4l2_mbus_framefmt       src_fmt;
++      struct v4l2_mbus_framefmt       sink_fmt;
+       struct v4l2_ctrl                *test_pattern;
+       struct fimc_isp_ctrls           ctrls;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0282-media-exynos4-is-Set-valid-initial-format-on-FIMC-IS.patch b/patches.tizen/0282-media-exynos4-is-Set-valid-initial-format-on-FIMC-IS.patch
new file mode 100644 (file)
index 0000000..6dfd774
--- /dev/null
@@ -0,0 +1,56 @@
+From cd2759370248c1b1271ac261f588ff44e62a665b Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Tue, 18 Jun 2013 14:50:50 -0300
+Subject: [PATCH 0282/1302] [media] exynos4-is: Set valid initial format on
+ FIMC-IS-ISP subdev pads
+
+Ensure there is a valid initial resolution and pixel format set
+at the FIMC-IS-ISP subdev pads.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-isp.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c
+index f859b3c..cf520a7 100644
+--- a/drivers/media/platform/exynos4-is/fimc-isp.c
++++ b/drivers/media/platform/exynos4-is/fimc-isp.c
+@@ -645,6 +645,22 @@ static const struct v4l2_ctrl_ops fimc_isp_ctrl_ops = {
+       .s_ctrl = fimc_is_s_ctrl,
+ };
++static void __isp_subdev_set_default_format(struct fimc_isp *isp)
++{
++      struct fimc_is *is = fimc_isp_to_is(isp);
++
++      isp->sink_fmt.width = DEFAULT_PREVIEW_STILL_WIDTH +
++                              FIMC_ISP_CAC_MARGIN_WIDTH;
++      isp->sink_fmt.height = DEFAULT_PREVIEW_STILL_HEIGHT +
++                              FIMC_ISP_CAC_MARGIN_HEIGHT;
++      isp->sink_fmt.code = V4L2_MBUS_FMT_SGRBG10_1X10;
++
++      isp->src_fmt.width = DEFAULT_PREVIEW_STILL_WIDTH;
++      isp->src_fmt.height = DEFAULT_PREVIEW_STILL_HEIGHT;
++      isp->src_fmt.code = V4L2_MBUS_FMT_SGRBG10_1X10;
++      __is_set_frame_size(is, &isp->src_fmt);
++}
++
+ int fimc_isp_subdev_create(struct fimc_isp *isp)
+ {
+       const struct v4l2_ctrl_ops *ops = &fimc_isp_ctrl_ops;
+@@ -725,6 +741,8 @@ int fimc_isp_subdev_create(struct fimc_isp *isp)
+       sd->entity.ops = &fimc_is_subdev_media_ops;
+       v4l2_set_subdevdata(sd, isp);
++      __isp_subdev_set_default_format(isp);
++
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0283-media-exynos4-is-Set-valid-initial-format-on-FIMC.n-.patch b/patches.tizen/0283-media-exynos4-is-Set-valid-initial-format-on-FIMC.n-.patch
new file mode 100644 (file)
index 0000000..bfb433d
--- /dev/null
@@ -0,0 +1,77 @@
+From 85aee2ab3692fc345b0c8866e9b5c6e819680fdc Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Tue, 18 Jun 2013 14:56:11 -0300
+Subject: [PATCH 0283/1302] [media] exynos4-is: Set valid initial format on
+ FIMC.n subdevs
+
+Ensure there are valid initial image formats on the FIMC.n subdev pads.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-capture.c | 19 +++++++++++++++++--
+ drivers/media/platform/exynos4-is/fimc-core.h    |  2 ++
+ 2 files changed, 19 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
+index 2b045b6..fb27ff7 100644
+--- a/drivers/media/platform/exynos4-is/fimc-capture.c
++++ b/drivers/media/platform/exynos4-is/fimc-capture.c
+@@ -1722,8 +1722,8 @@ static int fimc_capture_set_default_format(struct fimc_dev *fimc)
+       struct v4l2_format fmt = {
+               .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+               .fmt.pix_mp = {
+-                      .width          = 640,
+-                      .height         = 480,
++                      .width          = FIMC_DEFAULT_WIDTH,
++                      .height         = FIMC_DEFAULT_HEIGHT,
+                       .pixelformat    = V4L2_PIX_FMT_YUYV,
+                       .field          = V4L2_FIELD_NONE,
+                       .colorspace     = V4L2_COLORSPACE_JPEG,
+@@ -1741,6 +1741,7 @@ static int fimc_register_capture_device(struct fimc_dev *fimc,
+       struct vb2_queue *q = &fimc->vid_cap.vbq;
+       struct fimc_ctx *ctx;
+       struct fimc_vid_cap *vid_cap;
++      struct fimc_fmt *fmt;
+       int ret = -ENOMEM;
+       ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+@@ -1788,6 +1789,20 @@ static int fimc_register_capture_device(struct fimc_dev *fimc,
+       if (ret)
+               goto err_free_ctx;
++      /* Default format configuration */
++      fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0);
++      vid_cap->ci_fmt.width = FIMC_DEFAULT_WIDTH;
++      vid_cap->ci_fmt.height = FIMC_DEFAULT_HEIGHT;
++      vid_cap->ci_fmt.code = fmt->mbus_code;
++
++      ctx->s_frame.width = FIMC_DEFAULT_WIDTH;
++      ctx->s_frame.height = FIMC_DEFAULT_HEIGHT;
++      ctx->s_frame.fmt = fmt;
++
++      fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_WRITEBACK, 0);
++      vid_cap->wb_fmt = vid_cap->ci_fmt;
++      vid_cap->wb_fmt.code = fmt->mbus_code;
++
+       vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK;
+       ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad, 0);
+       if (ret)
+diff --git a/drivers/media/platform/exynos4-is/fimc-core.h b/drivers/media/platform/exynos4-is/fimc-core.h
+index 0f25ce0..65c8ce7 100644
+--- a/drivers/media/platform/exynos4-is/fimc-core.h
++++ b/drivers/media/platform/exynos4-is/fimc-core.h
+@@ -47,6 +47,8 @@
+ #define FIMC_DEF_MIN_SIZE     16
+ #define FIMC_DEF_HEIGHT_ALIGN 2
+ #define FIMC_DEF_HOR_OFFS_ALIGN       1
++#define FIMC_DEFAULT_WIDTH    640
++#define FIMC_DEFAULT_HEIGHT   480
+ /* indices to the clocks array */
+ enum {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0284-media-exynos4-is-Correct-colorspace-handling-at-FIMC.patch b/patches.tizen/0284-media-exynos4-is-Correct-colorspace-handling-at-FIMC.patch
new file mode 100644 (file)
index 0000000..018fec7
--- /dev/null
@@ -0,0 +1,160 @@
+From a82be5fcfab96218f2eb0dfcc01b6e8bd10a8c0d Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 20 Jun 2013 10:49:09 -0300
+Subject: [PATCH 0284/1302] [media] exynos4-is: Correct colorspace handling at
+ FIMC-LITE
+
+Ensure the colorspace is properly adjusted by the driver for YUV
+and Bayer image formats. The subdev try_fmt helper is simplified.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-lite.c | 17 +++++++++++++----
+ include/media/s5p_fimc.h                      |  2 ++
+ 2 files changed, 15 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
+index 4fa2e05..08fbfed 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite.c
++++ b/drivers/media/platform/exynos4-is/fimc-lite.c
+@@ -44,6 +44,7 @@ static const struct fimc_fmt fimc_lite_formats[] = {
+       {
+               .name           = "YUV 4:2:2 packed, YCbYCr",
+               .fourcc         = V4L2_PIX_FMT_YUYV,
++              .colorspace     = V4L2_COLORSPACE_JPEG,
+               .depth          = { 16 },
+               .color          = FIMC_FMT_YCBYCR422,
+               .memplanes      = 1,
+@@ -52,6 +53,7 @@ static const struct fimc_fmt fimc_lite_formats[] = {
+       }, {
+               .name           = "YUV 4:2:2 packed, CbYCrY",
+               .fourcc         = V4L2_PIX_FMT_UYVY,
++              .colorspace     = V4L2_COLORSPACE_JPEG,
+               .depth          = { 16 },
+               .color          = FIMC_FMT_CBYCRY422,
+               .memplanes      = 1,
+@@ -60,6 +62,7 @@ static const struct fimc_fmt fimc_lite_formats[] = {
+       }, {
+               .name           = "YUV 4:2:2 packed, CrYCbY",
+               .fourcc         = V4L2_PIX_FMT_VYUY,
++              .colorspace     = V4L2_COLORSPACE_JPEG,
+               .depth          = { 16 },
+               .color          = FIMC_FMT_CRYCBY422,
+               .memplanes      = 1,
+@@ -68,6 +71,7 @@ static const struct fimc_fmt fimc_lite_formats[] = {
+       }, {
+               .name           = "YUV 4:2:2 packed, YCrYCb",
+               .fourcc         = V4L2_PIX_FMT_YVYU,
++              .colorspace     = V4L2_COLORSPACE_JPEG,
+               .depth          = { 16 },
+               .color          = FIMC_FMT_YCRYCB422,
+               .memplanes      = 1,
+@@ -76,6 +80,7 @@ static const struct fimc_fmt fimc_lite_formats[] = {
+       }, {
+               .name           = "RAW8 (GRBG)",
+               .fourcc         = V4L2_PIX_FMT_SGRBG8,
++              .colorspace     = V4L2_COLORSPACE_SRGB,
+               .depth          = { 8 },
+               .color          = FIMC_FMT_RAW8,
+               .memplanes      = 1,
+@@ -84,6 +89,7 @@ static const struct fimc_fmt fimc_lite_formats[] = {
+       }, {
+               .name           = "RAW10 (GRBG)",
+               .fourcc         = V4L2_PIX_FMT_SGRBG10,
++              .colorspace     = V4L2_COLORSPACE_SRGB,
+               .depth          = { 10 },
+               .color          = FIMC_FMT_RAW10,
+               .memplanes      = 1,
+@@ -92,6 +98,7 @@ static const struct fimc_fmt fimc_lite_formats[] = {
+       }, {
+               .name           = "RAW12 (GRBG)",
+               .fourcc         = V4L2_PIX_FMT_SGRBG12,
++              .colorspace     = V4L2_COLORSPACE_SRGB,
+               .depth          = { 12 },
+               .color          = FIMC_FMT_RAW12,
+               .memplanes      = 1,
+@@ -577,6 +584,7 @@ static const struct fimc_fmt *fimc_lite_subdev_try_fmt(struct fimc_lite *fimc,
+               if (WARN_ON(!fmt))
+                       return NULL;
++              mf->colorspace = fmt->colorspace;
+               mf->code = fmt->mbus_code;
+       } else {
+               struct flite_frame *sink = &fimc->inp_frame;
+@@ -588,11 +596,13 @@ static const struct fimc_fmt *fimc_lite_subdev_try_fmt(struct fimc_lite *fimc,
+                                               FLITE_SD_PAD_SINK);
+                       mf->code = sink_fmt->code;
++                      mf->colorspace = sink_fmt->colorspace;
+                       rect = v4l2_subdev_get_try_crop(fh,
+                                               FLITE_SD_PAD_SINK);
+               } else {
+                       mf->code = sink->fmt->mbus_code;
++                      mf->colorspace = sink->fmt->colorspace;
+                       rect = &sink->rect;
+               }
+@@ -696,7 +706,7 @@ static int fimc_lite_g_fmt_mplane(struct file *file, void *fh,
+       pixm->width = frame->f_width;
+       pixm->height = frame->f_height;
+       pixm->field = V4L2_FIELD_NONE;
+-      pixm->colorspace = V4L2_COLORSPACE_JPEG;
++      pixm->colorspace = fmt->colorspace;
+       return 0;
+ }
+@@ -739,7 +749,7 @@ static int fimc_lite_try_fmt(struct fimc_lite *fimc,
+                                               fmt->depth[0]) / 8;
+       pixm->num_planes = fmt->memplanes;
+       pixm->pixelformat = fmt->fourcc;
+-      pixm->colorspace = V4L2_COLORSPACE_JPEG;
++      pixm->colorspace = fmt->colorspace;
+       pixm->field = V4L2_FIELD_NONE;
+       return 0;
+ }
+@@ -1071,9 +1081,9 @@ static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd,
+               fmt->format = *mf;
+               return 0;
+       }
+-      mf->colorspace = V4L2_COLORSPACE_JPEG;
+       mutex_lock(&fimc->lock);
++      mf->colorspace = f->fmt->colorspace;
+       mf->code = f->fmt->mbus_code;
+       if (fmt->pad == FLITE_SD_PAD_SINK) {
+@@ -1102,7 +1112,6 @@ static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd,
+       v4l2_dbg(1, debug, sd, "pad%d: code: 0x%x, %dx%d\n",
+                fmt->pad, mf->code, mf->width, mf->height);
+-      mf->colorspace = V4L2_COLORSPACE_JPEG;
+       mutex_lock(&fimc->lock);
+       if ((atomic_read(&fimc->out_path) == FIMC_IO_ISP &&
+diff --git a/include/media/s5p_fimc.h b/include/media/s5p_fimc.h
+index 0afadb6..b975c28 100644
+--- a/include/media/s5p_fimc.h
++++ b/include/media/s5p_fimc.h
+@@ -116,6 +116,7 @@ struct s5p_platform_fimc {
+  * @color: the driver's private color format id
+  * @memplanes: number of physically non-contiguous data planes
+  * @colplanes: number of physically contiguous data planes
++ * @colorspace: v4l2 colorspace (V4L2_COLORSPACE_*)
+  * @depth: per plane driver's private 'number of bits per pixel'
+  * @mdataplanes: bitmask indicating meta data plane(s), (1 << plane_no)
+  * @flags: flags indicating which operation mode format applies to
+@@ -127,6 +128,7 @@ struct fimc_fmt {
+       u32     color;
+       u16     memplanes;
+       u16     colplanes;
++      u8      colorspace;
+       u8      depth[FIMC_MAX_PLANES];
+       u16     mdataplanes;
+       u16     flags;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0285-exynos4-is-Add-the-FIMC-IS-ISP-capture-DMA-driver.patch b/patches.tizen/0285-exynos4-is-Add-the-FIMC-IS-ISP-capture-DMA-driver.patch
new file mode 100644 (file)
index 0000000..dde284e
--- /dev/null
@@ -0,0 +1,1063 @@
+From eeaa446c3ae9d8a401fb7dbe903344202d07bff8 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 31 May 2013 13:08:24 +0200
+Subject: [PATCH 0285/1302] exynos4-is: Add the FIMC-IS ISP capture DMA driver
+
+Add a video capture node for the FIMC-IS ISP IP block. The Exynos4x12
+FIMC-IS ISP IP block has 2 DMA interfaces that allow to capture raw
+Bayer and YUV data to memory.  Currently only the DMA2 output is and
+raw Bayer data capture is supported.
+
+exynos4-is: Fix ISP DMA capture start/stop sequence
+
+Ensure we wait until FIMC-IS executes a command, otherwise a division by
+zero exception is thrown in the interrupt handler due to buf_count being
+set to 0.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/Kconfig          |   9 +
+ drivers/media/platform/exynos4-is/Makefile         |   4 +
+ drivers/media/platform/exynos4-is/fimc-is-param.h  |   5 +
+ drivers/media/platform/exynos4-is/fimc-is-regs.c   |  14 +
+ drivers/media/platform/exynos4-is/fimc-is-regs.h   |   1 +
+ drivers/media/platform/exynos4-is/fimc-is.c        |   3 +
+ drivers/media/platform/exynos4-is/fimc-is.h        |   5 +
+ drivers/media/platform/exynos4-is/fimc-isp-video.c | 660 +++++++++++++++++++++
+ drivers/media/platform/exynos4-is/fimc-isp-video.h |  44 ++
+ drivers/media/platform/exynos4-is/fimc-isp.c       |  29 +-
+ drivers/media/platform/exynos4-is/fimc-isp.h       |  27 +-
+ drivers/media/platform/exynos4-is/media-dev.c      |  23 +-
+ 12 files changed, 816 insertions(+), 8 deletions(-)
+ create mode 100644 drivers/media/platform/exynos4-is/fimc-isp-video.c
+ create mode 100644 drivers/media/platform/exynos4-is/fimc-isp-video.h
+
+diff --git a/drivers/media/platform/exynos4-is/Kconfig b/drivers/media/platform/exynos4-is/Kconfig
+index c622532..d2c670c 100644
+--- a/drivers/media/platform/exynos4-is/Kconfig
++++ b/drivers/media/platform/exynos4-is/Kconfig
+@@ -63,4 +63,13 @@ config VIDEO_EXYNOS4_FIMC_IS
+         To compile this driver as a module, choose M here: the
+         module will be called exynos4-fimc-is.
++config VIDEO_EXYNOS4_ISP_DMA_CAPTURE
++      bool "EXYNOS4x12 FIMC-IS ISP Direct DMA capture support"
++      depends on VIDEO_EXYNOS4_FIMC_IS
++      select VIDEO_EXYNOS4_IS_COMMON
++      default y
++        help
++        This option enables an additional video device node exposing a V4L2
++        video capture interface for the FIMC-IS ISP raw (Bayer) capture DMA.
++
+ endif # VIDEO_SAMSUNG_EXYNOS4_IS
+diff --git a/drivers/media/platform/exynos4-is/Makefile b/drivers/media/platform/exynos4-is/Makefile
+index c2ff29b..eed1b18 100644
+--- a/drivers/media/platform/exynos4-is/Makefile
++++ b/drivers/media/platform/exynos4-is/Makefile
+@@ -6,6 +6,10 @@ exynos4-is-common-objs := common.o
+ exynos-fimc-is-objs := fimc-is.o fimc-isp.o fimc-is-sensor.o fimc-is-regs.o
+ exynos-fimc-is-objs += fimc-is-param.o fimc-is-errno.o fimc-is-i2c.o
++ifeq ($(CONFIG_VIDEO_EXYNOS4_ISP_DMA_CAPTURE),y)
++exynos-fimc-is-objs += fimc-isp-video.o
++endif
++
+ obj-$(CONFIG_VIDEO_S5P_MIPI_CSIS)     += s5p-csis.o
+ obj-$(CONFIG_VIDEO_EXYNOS_FIMC_LITE)  += exynos-fimc-lite.o
+ obj-$(CONFIG_VIDEO_EXYNOS4_FIMC_IS)   += exynos-fimc-is.o
+diff --git a/drivers/media/platform/exynos4-is/fimc-is-param.h b/drivers/media/platform/exynos4-is/fimc-is-param.h
+index f9358c2..8e31f76 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is-param.h
++++ b/drivers/media/platform/exynos4-is/fimc-is-param.h
+@@ -911,6 +911,10 @@ struct is_region {
+       u32 shared[MAX_SHARED_COUNT];
+ } __packed;
++/* Offset to the ISP DMA2 output buffer address array. */
++#define DMA2_OUTPUT_ADDR_ARRAY_OFFS \
++      (offsetof(struct is_region, shared) + 32 * sizeof(u32))
++
+ struct is_debug_frame_descriptor {
+       u32 sensor_frame_time;
+       u32 sensor_exposure_time;
+@@ -988,6 +992,7 @@ struct sensor_open_extended {
+ struct fimc_is;
+ int fimc_is_hw_get_sensor_max_framerate(struct fimc_is *is);
++int __fimc_is_hw_update_param(struct fimc_is *is, u32 offset);
+ void fimc_is_set_initial_params(struct fimc_is *is);
+ unsigned int __get_pending_param_count(struct fimc_is *is);
+diff --git a/drivers/media/platform/exynos4-is/fimc-is-regs.c b/drivers/media/platform/exynos4-is/fimc-is-regs.c
+index 63c68ec..19d3eae 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is-regs.c
++++ b/drivers/media/platform/exynos4-is/fimc-is-regs.c
+@@ -129,6 +129,20 @@ int fimc_is_hw_get_params(struct fimc_is *is, unsigned int num_args)
+       return 0;
+ }
++void fimc_is_hw_set_isp_buf_mask(struct fimc_is *is, unsigned int mask)
++{
++      if (hweight32(mask) == 1) {
++              dev_err(&is->pdev->dev, "%s(): not enough buffers (mask %#x)\n",
++                                                      __func__, mask);
++              return;
++      }
++
++      if (mcuctl_read(is, MCUCTL_REG_ISSR(23)) != 0)
++              dev_dbg(&is->pdev->dev, "non-zero DMA buffer mask\n");
++
++      mcuctl_write(mask, is, MCUCTL_REG_ISSR(23));
++}
++
+ void fimc_is_hw_set_sensor_num(struct fimc_is *is)
+ {
+       pr_debug("setting sensor index to: %d\n", is->sensor_index);
+diff --git a/drivers/media/platform/exynos4-is/fimc-is-regs.h b/drivers/media/platform/exynos4-is/fimc-is-regs.h
+index 5fa2fda..ab73957 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is-regs.h
++++ b/drivers/media/platform/exynos4-is/fimc-is-regs.h
+@@ -148,6 +148,7 @@ void fimc_is_hw_set_intgr0_gd0(struct fimc_is *is);
+ int fimc_is_hw_wait_intsr0_intsd0(struct fimc_is *is);
+ int fimc_is_hw_wait_intmsr0_intmsd0(struct fimc_is *is);
+ void fimc_is_hw_set_sensor_num(struct fimc_is *is);
++void fimc_is_hw_set_isp_buf_mask(struct fimc_is *is, unsigned int mask);
+ void fimc_is_hw_stream_on(struct fimc_is *is);
+ void fimc_is_hw_stream_off(struct fimc_is *is);
+ int fimc_is_hw_set_param(struct fimc_is *is);
+diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c
+index 967f6a9..37dac12 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is.c
++++ b/drivers/media/platform/exynos4-is/fimc-is.c
+@@ -190,6 +190,9 @@ static int fimc_is_register_subdevs(struct fimc_is *is)
+       if (ret < 0)
+               return ret;
++      /* Initialize memory allocator context for the ISP DMA. */
++      is->isp.alloc_ctx = is->alloc_ctx;
++
+       for_each_compatible_node(adapter, NULL, FIMC_IS_I2C_COMPATIBLE) {
+               if (!of_find_device_by_node(adapter)) {
+                       of_node_put(adapter);
+diff --git a/drivers/media/platform/exynos4-is/fimc-is.h b/drivers/media/platform/exynos4-is/fimc-is.h
+index 61bb012..1a97e09 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is.h
++++ b/drivers/media/platform/exynos4-is/fimc-is.h
+@@ -292,6 +292,11 @@ static inline struct fimc_is *fimc_isp_to_is(struct fimc_isp *isp)
+       return container_of(isp, struct fimc_is, isp);
+ }
++static inline struct chain_config *__get_curr_is_config(struct fimc_is *is)
++{
++      return &is->config[is->config_index];
++}
++
+ static inline void fimc_is_mem_barrier(void)
+ {
+       mb();
+diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c
+new file mode 100644
+index 0000000..f28160c
+--- /dev/null
++++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c
+@@ -0,0 +1,660 @@
++/*
++ * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
++ *
++ * FIMC-IS ISP video input and video output DMA interface driver
++ *
++ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
++ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
++ *
++ * The hardware handling code derived from a driver written by
++ * Younghwan Joo <yhwan.joo@samsung.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/bitops.h>
++#include <linux/device.h>
++#include <linux/delay.h>
++#include <linux/errno.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/printk.h>
++#include <linux/pm_runtime.h>
++#include <linux/slab.h>
++#include <linux/videodev2.h>
++
++#include <media/v4l2-device.h>
++#include <media/v4l2-ioctl.h>
++#include <media/videobuf2-core.h>
++#include <media/videobuf2-dma-contig.h>
++#include <media/s5p_fimc.h>
++
++#include "common.h"
++#include "media-dev.h"
++#include "fimc-is.h"
++#include "fimc-isp-video.h"
++#include "fimc-is-param.h"
++
++static int isp_video_capture_queue_setup(struct vb2_queue *vq,
++                      const struct v4l2_format *pfmt,
++                      unsigned int *num_buffers, unsigned int *num_planes,
++                      unsigned int sizes[], void *allocators[])
++{
++      struct fimc_isp *isp = vb2_get_drv_priv(vq);
++      struct v4l2_pix_format_mplane *vid_fmt = &isp->video_capture.pixfmt;
++      const struct v4l2_pix_format_mplane *pixm = NULL;
++      const struct fimc_fmt *fmt;
++      unsigned int wh, i;
++
++      if (pfmt) {
++              pixm = &pfmt->fmt.pix_mp;
++              fmt = fimc_isp_find_format(&pixm->pixelformat, NULL, -1);
++              wh = pixm->width * pixm->height;
++      } else {
++              fmt = isp->video_capture.format;
++              wh = vid_fmt->width * vid_fmt->height;
++      }
++
++      if (fmt == NULL)
++              return -EINVAL;
++
++      *num_buffers = clamp_t(u32, *num_buffers, FIMC_ISP_REQ_BUFS_MIN,
++                                              FIMC_ISP_REQ_BUFS_MAX);
++      *num_planes = fmt->memplanes;
++
++      for (i = 0; i < fmt->memplanes; i++) {
++              unsigned int size = (wh * fmt->depth[i]) / 8;
++              if (pixm)
++                      sizes[i] = max(size, pixm->plane_fmt[i].sizeimage);
++              else
++                      sizes[i] = size;
++              allocators[i] = isp->alloc_ctx;
++      }
++
++      return 0;
++}
++
++static inline struct param_dma_output *__get_isp_dma2(struct fimc_is *is)
++{
++      return &__get_curr_is_config(is)->isp.dma2_output;
++}
++
++static int isp_video_capture_start_streaming(struct vb2_queue *q,
++                                              unsigned int count)
++{
++      struct fimc_isp *isp = vb2_get_drv_priv(q);
++      struct fimc_is *is = fimc_isp_to_is(isp);
++      struct param_dma_output *dma = __get_isp_dma2(is);
++      struct fimc_is_video *video = &isp->video_capture;
++      int ret;
++
++      if (!test_bit(ST_ISP_VID_CAP_BUF_PREP, &isp->state) ||
++          test_bit(ST_ISP_VID_CAP_STREAMING, &isp->state))
++              return 0;
++
++
++      dma->cmd = DMA_OUTPUT_COMMAND_ENABLE;
++      dma->notify_dma_done = DMA_OUTPUT_NOTIFY_DMA_DONE_ENABLE;
++      dma->buffer_address = is->is_dma_p_region +
++                              DMA2_OUTPUT_ADDR_ARRAY_OFFS;
++      dma->buffer_number = video->reqbufs_count;
++      dma->dma_out_mask = video->buf_mask;
++
++      isp_dbg(2, &video->ve.vdev,
++              "buf_count: %d, planes: %d, dma addr table: %#x\n",
++              video->buf_count, video->format->memplanes,
++              dma->buffer_address);
++
++      fimc_is_mem_barrier();
++
++      fimc_is_set_param_bit(is, PARAM_ISP_DMA2_OUTPUT);
++      __fimc_is_hw_update_param(is, PARAM_ISP_DMA2_OUTPUT);
++
++      ret = fimc_is_itf_s_param(is, false);
++      if (ret < 0)
++              return ret;
++
++      ret = fimc_pipeline_call(&video->ve, set_stream, 1);
++      if (ret < 0)
++              return ret;
++
++      set_bit(ST_ISP_VID_CAP_STREAMING, &isp->state);
++      return ret;
++}
++
++static int isp_video_capture_stop_streaming(struct vb2_queue *q)
++{
++      struct fimc_isp *isp = vb2_get_drv_priv(q);
++      struct fimc_is *is = fimc_isp_to_is(isp);
++      struct param_dma_output *dma = __get_isp_dma2(is);
++      int ret;
++
++      ret = fimc_pipeline_call(&isp->video_capture.ve, set_stream, 0);
++      if (ret < 0)
++              return ret;
++
++      dma->cmd = DMA_OUTPUT_COMMAND_DISABLE;
++      dma->notify_dma_done = DMA_OUTPUT_NOTIFY_DMA_DONE_DISABLE;
++      dma->buffer_number = 0;
++      dma->buffer_address = 0;
++      dma->dma_out_mask = 0;
++
++      fimc_is_set_param_bit(is, PARAM_ISP_DMA2_OUTPUT);
++      __fimc_is_hw_update_param(is, PARAM_ISP_DMA2_OUTPUT);
++
++      ret = fimc_is_itf_s_param(is, false);
++      if (ret < 0)
++              dev_warn(&is->pdev->dev, "%s: DMA stop failed\n", __func__);
++
++      fimc_is_hw_set_isp_buf_mask(is, 0);
++
++      clear_bit(ST_ISP_VID_CAP_BUF_PREP, &isp->state);
++      clear_bit(ST_ISP_VID_CAP_STREAMING, &isp->state);
++
++      isp->video_capture.buf_count = 0;
++      return 0;
++}
++
++static int isp_video_capture_buffer_prepare(struct vb2_buffer *vb)
++{
++      struct fimc_isp *isp = vb2_get_drv_priv(vb->vb2_queue);
++      struct fimc_is_video *video = &isp->video_capture;
++      int i;
++
++      if (video->format == NULL)
++              return -EINVAL;
++
++      for (i = 0; i < video->format->memplanes; i++) {
++              unsigned long size = video->pixfmt.plane_fmt[i].sizeimage;
++
++              if (vb2_plane_size(vb, i) < size) {
++                      v4l2_err(&video->ve.vdev,
++                               "User buffer too small (%ld < %ld)\n",
++                               vb2_plane_size(vb, i), size);
++                      return -EINVAL;
++              }
++              vb2_set_plane_payload(vb, i, size);
++      }
++
++      /* Check if we get one of the already known buffers. */
++      if (test_bit(ST_ISP_VID_CAP_BUF_PREP, &isp->state)) {
++              dma_addr_t dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
++              int i;
++
++              for (i = 0; i < video->buf_count; i++)
++                      if (video->buffers[i]->dma_addr[0] == dma_addr)
++                              return 0;
++              return -ENXIO;
++      }
++
++      return 0;
++}
++
++static void isp_video_capture_buffer_queue(struct vb2_buffer *vb)
++{
++      struct fimc_isp *isp = vb2_get_drv_priv(vb->vb2_queue);
++      struct fimc_is_video *video = &isp->video_capture;
++      struct fimc_is *is = fimc_isp_to_is(isp);
++      struct isp_video_buf *ivb = to_isp_video_buf(vb);
++      unsigned long flags;
++      unsigned int i;
++
++      if (test_bit(ST_ISP_VID_CAP_BUF_PREP, &isp->state)) {
++              spin_lock_irqsave(&is->slock, flags);
++              video->buf_mask |= BIT(ivb->index);
++              spin_unlock_irqrestore(&is->slock, flags);
++      } else {
++              unsigned int num_planes = video->format->memplanes;
++
++              ivb->index = video->buf_count;
++              video->buffers[ivb->index] = ivb;
++
++              for (i = 0; i < num_planes; i++) {
++                      int buf_index = ivb->index * num_planes + i;
++
++                      ivb->dma_addr[i] = vb2_dma_contig_plane_dma_addr(vb, i);
++                      is->is_p_region->shared[32 + buf_index] =
++                                                      ivb->dma_addr[i];
++
++                      isp_dbg(2, &video->ve.vdev,
++                              "dma_buf %d (%d/%d/%d) addr: %#x\n",
++                              buf_index, ivb->index, i, vb->v4l2_buf.index,
++                              ivb->dma_addr[i]);
++              }
++
++              if (++video->buf_count < video->reqbufs_count)
++                      return;
++
++              video->buf_mask = (1UL << video->buf_count) - 1;
++              set_bit(ST_ISP_VID_CAP_BUF_PREP, &isp->state);
++      }
++
++      if (!test_bit(ST_ISP_VID_CAP_STREAMING, &isp->state))
++              isp_video_capture_start_streaming(vb->vb2_queue, 0);
++}
++
++/*
++ * FIMC-IS ISP input and output DMA interface interrupt handler.
++ * Locking: called with is->slock spinlock held.
++ */
++void fimc_isp_video_irq_handler(struct fimc_is *is)
++{
++      struct fimc_is_video *video = &is->isp.video_capture;
++      struct vb2_buffer *vb;
++      int buf_index;
++
++      /* TODO: Ensure the DMA is really stopped in stop_streaming callback */
++      if (!test_bit(ST_ISP_VID_CAP_STREAMING, &is->isp.state))
++              return;
++
++      buf_index = (is->i2h_cmd.args[1] - 1) % video->buf_count;
++      vb = &video->buffers[buf_index]->vb;
++
++      v4l2_get_timestamp(&vb->v4l2_buf.timestamp);
++      vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
++
++      video->buf_mask &= ~BIT(buf_index);
++      fimc_is_hw_set_isp_buf_mask(is, video->buf_mask);
++}
++
++static const struct vb2_ops isp_video_capture_qops = {
++      .queue_setup     = isp_video_capture_queue_setup,
++      .buf_prepare     = isp_video_capture_buffer_prepare,
++      .buf_queue       = isp_video_capture_buffer_queue,
++      .wait_prepare    = vb2_ops_wait_prepare,
++      .wait_finish     = vb2_ops_wait_finish,
++      .start_streaming = isp_video_capture_start_streaming,
++      .stop_streaming  = isp_video_capture_stop_streaming,
++};
++
++static int isp_video_open(struct file *file)
++{
++      struct fimc_isp *isp = video_drvdata(file);
++      struct exynos_video_entity *ve = &isp->video_capture.ve;
++      struct media_entity *me = &ve->vdev.entity;
++      int ret;
++
++      if (mutex_lock_interruptible(&isp->video_lock))
++              return -ERESTARTSYS;
++
++      ret = v4l2_fh_open(file);
++      if (ret < 0)
++              goto unlock;
++
++      ret = pm_runtime_get_sync(&isp->pdev->dev);
++      if (ret < 0)
++              goto rel_fh;
++
++      if (v4l2_fh_is_singular_file(file)) {
++              mutex_lock(&me->parent->graph_mutex);
++
++              ret = fimc_pipeline_call(ve, open, me, true);
++
++              /* Mark the video pipeline as in use. */
++              if (ret == 0)
++                      me->use_count++;
++
++              mutex_unlock(&me->parent->graph_mutex);
++      }
++      if (!ret)
++              goto unlock;
++rel_fh:
++      v4l2_fh_release(file);
++unlock:
++      mutex_unlock(&isp->video_lock);
++      return ret;
++}
++
++static int isp_video_release(struct file *file)
++{
++      struct fimc_isp *isp = video_drvdata(file);
++      struct fimc_is_video *ivc = &isp->video_capture;
++      struct media_entity *entity = &ivc->ve.vdev.entity;
++      struct media_device *mdev = entity->parent;
++      int ret = 0;
++
++      mutex_lock(&isp->video_lock);
++
++      if (v4l2_fh_is_singular_file(file) && ivc->streaming) {
++              media_entity_pipeline_stop(entity);
++              ivc->streaming = 0;
++      }
++
++      vb2_fop_release(file);
++
++      if (v4l2_fh_is_singular_file(file)) {
++              fimc_pipeline_call(&ivc->ve, close);
++
++              mutex_lock(&mdev->graph_mutex);
++              entity->use_count--;
++              mutex_unlock(&mdev->graph_mutex);
++      }
++
++      pm_runtime_put(&isp->pdev->dev);
++      mutex_unlock(&isp->video_lock);
++
++      return ret;
++}
++
++static const struct v4l2_file_operations isp_video_fops = {
++      .owner          = THIS_MODULE,
++      .open           = isp_video_open,
++      .release        = isp_video_release,
++      .poll           = vb2_fop_poll,
++      .unlocked_ioctl = video_ioctl2,
++      .mmap           = vb2_fop_mmap,
++};
++
++/*
++ * Video node ioctl operations
++ */
++static int isp_video_querycap(struct file *file, void *priv,
++                                      struct v4l2_capability *cap)
++{
++      struct fimc_isp *isp = video_drvdata(file);
++
++      __fimc_vidioc_querycap(&isp->pdev->dev, cap, V4L2_CAP_STREAMING);
++      return 0;
++}
++
++static int isp_video_enum_fmt_mplane(struct file *file, void *priv,
++                                      struct v4l2_fmtdesc *f)
++{
++      const struct fimc_fmt *fmt;
++
++      if (f->index >= FIMC_ISP_NUM_FORMATS)
++              return -EINVAL;
++
++      fmt = fimc_isp_find_format(NULL, NULL, f->index);
++      if (WARN_ON(fmt == NULL))
++              return -EINVAL;
++
++      strlcpy(f->description, fmt->name, sizeof(f->description));
++      f->pixelformat = fmt->fourcc;
++
++      return 0;
++}
++
++static int isp_video_g_fmt_mplane(struct file *file, void *fh,
++                                      struct v4l2_format *f)
++{
++      struct fimc_isp *isp = video_drvdata(file);
++
++      f->fmt.pix_mp = isp->video_capture.pixfmt;
++      return 0;
++}
++
++static void __isp_video_try_fmt(struct fimc_isp *isp,
++                              struct v4l2_pix_format_mplane *pixm,
++                              const struct fimc_fmt **fmt)
++{
++      *fmt = fimc_isp_find_format(&pixm->pixelformat, NULL, 2);
++
++      pixm->colorspace = V4L2_COLORSPACE_SRGB;
++      pixm->field = V4L2_FIELD_NONE;
++      pixm->num_planes = (*fmt)->memplanes;
++      pixm->pixelformat = (*fmt)->fourcc;
++      /*
++       * TODO: double check with the docmentation these width/height
++       * constraints are correct.
++       */
++      v4l_bound_align_image(&pixm->width, FIMC_ISP_SOURCE_WIDTH_MIN,
++                            FIMC_ISP_SOURCE_WIDTH_MAX, 3,
++                            &pixm->height, FIMC_ISP_SOURCE_HEIGHT_MIN,
++                            FIMC_ISP_SOURCE_HEIGHT_MAX, 0, 0);
++}
++
++static int isp_video_try_fmt_mplane(struct file *file, void *fh,
++                                      struct v4l2_format *f)
++{
++      struct fimc_isp *isp = video_drvdata(file);
++
++      __isp_video_try_fmt(isp, &f->fmt.pix_mp, NULL);
++      return 0;
++}
++
++static int isp_video_s_fmt_mplane(struct file *file, void *priv,
++                                      struct v4l2_format *f)
++{
++      struct fimc_isp *isp = video_drvdata(file);
++      struct fimc_is *is = fimc_isp_to_is(isp);
++      struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
++      const struct fimc_fmt *ifmt = NULL;
++      struct param_dma_output *dma = __get_isp_dma2(is);
++
++      __isp_video_try_fmt(isp, pixm, &ifmt);
++
++      if (WARN_ON(ifmt == NULL))
++              return -EINVAL;
++
++      dma->format = DMA_OUTPUT_FORMAT_BAYER;
++      dma->order = DMA_OUTPUT_ORDER_GB_BG;
++      dma->plane = ifmt->memplanes;
++      dma->bitwidth = ifmt->depth[0];
++      dma->width = pixm->width;
++      dma->height = pixm->height;
++
++      fimc_is_mem_barrier();
++
++      isp->video_capture.format = ifmt;
++      isp->video_capture.pixfmt = *pixm;
++
++      return 0;
++}
++
++/*
++ * Check for source/sink format differences at each link.
++ * Return 0 if the formats match or -EPIPE otherwise.
++ */
++static int isp_video_pipeline_validate(struct fimc_isp *isp)
++{
++      struct v4l2_subdev *sd = &isp->subdev;
++      struct v4l2_subdev_format sink_fmt, src_fmt;
++      struct media_pad *pad;
++      int ret;
++
++      while (1) {
++              /* Retrieve format at the sink pad */
++              pad = &sd->entity.pads[0];
++              if (!(pad->flags & MEDIA_PAD_FL_SINK))
++                      break;
++              sink_fmt.pad = pad->index;
++              sink_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
++              ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sink_fmt);
++              if (ret < 0 && ret != -ENOIOCTLCMD)
++                      return -EPIPE;
++
++              /* Retrieve format at the source pad */
++              pad = media_entity_remote_pad(pad);
++              if (pad == NULL ||
++                  media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
++                      break;
++
++              sd = media_entity_to_v4l2_subdev(pad->entity);
++              src_fmt.pad = pad->index;
++              src_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
++              ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &src_fmt);
++              if (ret < 0 && ret != -ENOIOCTLCMD)
++                      return -EPIPE;
++
++              if (src_fmt.format.width != sink_fmt.format.width ||
++                  src_fmt.format.height != sink_fmt.format.height ||
++                  src_fmt.format.code != sink_fmt.format.code)
++                      return -EPIPE;
++      }
++
++      return 0;
++}
++
++static int isp_video_streamon(struct file *file, void *priv,
++                                    enum v4l2_buf_type type)
++{
++      struct fimc_isp *isp = video_drvdata(file);
++      struct exynos_video_entity *ve = &isp->video_capture.ve;
++      struct media_entity *me = &ve->vdev.entity;
++      int ret;
++
++      ret = media_entity_pipeline_start(me, &ve->pipe->mp);
++      if (ret < 0)
++              return ret;
++
++      ret = isp_video_pipeline_validate(isp);
++      if (ret < 0)
++              goto p_stop;
++
++      ret = vb2_ioctl_streamon(file, priv, type);
++      if (ret < 0)
++              goto p_stop;
++
++      isp->video_capture.streaming = 1;
++      return 0;
++p_stop:
++      media_entity_pipeline_stop(me);
++      return ret;
++}
++
++static int isp_video_streamoff(struct file *file, void *priv,
++                                      enum v4l2_buf_type type)
++{
++      struct fimc_isp *isp = video_drvdata(file);
++      struct fimc_is_video *video = &isp->video_capture;
++      int ret;
++
++      ret = vb2_ioctl_streamoff(file, priv, type);
++      if (ret < 0)
++              return ret;
++
++      media_entity_pipeline_stop(&video->ve.vdev.entity);
++      video->streaming = 0;
++      return 0;
++}
++
++static int isp_video_reqbufs(struct file *file, void *priv,
++                              struct v4l2_requestbuffers *rb)
++{
++      struct fimc_isp *isp = video_drvdata(file);
++      int ret;
++
++      ret = vb2_ioctl_reqbufs(file, priv, rb);
++      if (ret < 0)
++              return ret;
++
++      if (rb->count && rb->count < FIMC_ISP_REQ_BUFS_MIN) {
++              rb->count = 0;
++              vb2_ioctl_reqbufs(file, priv, rb);
++              ret = -ENOMEM;
++      }
++
++      isp->video_capture.reqbufs_count = rb->count;
++      return ret;
++}
++
++static const struct v4l2_ioctl_ops isp_video_ioctl_ops = {
++      .vidioc_querycap                = isp_video_querycap,
++      .vidioc_enum_fmt_vid_cap_mplane = isp_video_enum_fmt_mplane,
++      .vidioc_try_fmt_vid_cap_mplane  = isp_video_try_fmt_mplane,
++      .vidioc_s_fmt_vid_cap_mplane    = isp_video_s_fmt_mplane,
++      .vidioc_g_fmt_vid_cap_mplane    = isp_video_g_fmt_mplane,
++      .vidioc_reqbufs                 = isp_video_reqbufs,
++      .vidioc_querybuf                = vb2_ioctl_querybuf,
++      .vidioc_prepare_buf             = vb2_ioctl_prepare_buf,
++      .vidioc_create_bufs             = vb2_ioctl_create_bufs,
++      .vidioc_qbuf                    = vb2_ioctl_qbuf,
++      .vidioc_dqbuf                   = vb2_ioctl_dqbuf,
++      .vidioc_streamon                = isp_video_streamon,
++      .vidioc_streamoff               = isp_video_streamoff,
++};
++
++int fimc_isp_video_device_register(struct fimc_isp *isp,
++                                 struct v4l2_device *v4l2_dev,
++                                 enum v4l2_buf_type type)
++{
++      struct vb2_queue *q = &isp->video_capture.vb_queue;
++      struct fimc_is_video *iv;
++      struct video_device *vdev;
++      int ret;
++
++      if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
++              iv = &isp->video_capture;
++      else
++              return -ENOSYS;
++
++      mutex_init(&isp->video_lock);
++      INIT_LIST_HEAD(&iv->pending_buf_q);
++      INIT_LIST_HEAD(&iv->active_buf_q);
++      iv->format = fimc_isp_find_format(NULL, NULL, 0);
++      iv->pixfmt.width = IS_DEFAULT_WIDTH;
++      iv->pixfmt.height = IS_DEFAULT_HEIGHT;
++      iv->pixfmt.pixelformat = iv->format->fourcc;
++      iv->pixfmt.colorspace = V4L2_COLORSPACE_SRGB;
++      iv->reqbufs_count = 0;
++
++      memset(q, 0, sizeof(*q));
++      q->type = type;
++      q->io_modes = VB2_MMAP | VB2_USERPTR;
++      q->ops = &isp_video_capture_qops;
++      q->mem_ops = &vb2_dma_contig_memops;
++      q->buf_struct_size = sizeof(struct isp_video_buf);
++      q->drv_priv = isp;
++      q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
++      q->lock = &isp->video_lock;
++
++      ret = vb2_queue_init(q);
++      if (ret < 0)
++              return ret;
++
++      vdev = &iv->ve.vdev;
++      memset(vdev, 0, sizeof(*vdev));
++      snprintf(vdev->name, sizeof(vdev->name), "fimc-is-isp.%s",
++                      type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ?
++                      "capture" : "output");
++      vdev->queue = q;
++      vdev->fops = &isp_video_fops;
++      vdev->ioctl_ops = &isp_video_ioctl_ops;
++      vdev->v4l2_dev = v4l2_dev;
++      vdev->minor = -1;
++      vdev->release = video_device_release_empty;
++      vdev->lock = &isp->video_lock;
++
++      iv->pad.flags = MEDIA_PAD_FL_SINK;
++      ret = media_entity_init(&vdev->entity, 1, &iv->pad, 0);
++      if (ret < 0)
++              return ret;
++
++      video_set_drvdata(vdev, isp);
++
++      ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
++      if (ret < 0) {
++              media_entity_cleanup(&vdev->entity);
++              return ret;
++      }
++
++      v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n",
++                vdev->name, video_device_node_name(vdev));
++
++      return 0;
++}
++
++void fimc_isp_video_device_unregister(struct fimc_isp *isp,
++                                    enum v4l2_buf_type type)
++{
++      struct exynos_video_entity *ve;
++
++      if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
++              ve = &isp->video_capture.ve;
++      else
++              return;
++
++      mutex_lock(&isp->video_lock);
++
++      if (video_is_registered(&ve->vdev)) {
++              video_unregister_device(&ve->vdev);
++              media_entity_cleanup(&ve->vdev.entity);
++              ve->pipe = NULL;
++      }
++
++      mutex_unlock(&isp->video_lock);
++}
+diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.h b/drivers/media/platform/exynos4-is/fimc-isp-video.h
+new file mode 100644
+index 0000000..98c6626
+--- /dev/null
++++ b/drivers/media/platform/exynos4-is/fimc-isp-video.h
+@@ -0,0 +1,44 @@
++/*
++ * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
++ *
++ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
++ * Sylwester Nawrocki <s.nawrocki@samsung.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 FIMC_ISP_VIDEO__
++#define FIMC_ISP_VIDEO__
++
++#include <media/videobuf2-core.h>
++#include "fimc-isp.h"
++
++#ifdef CONFIG_VIDEO_EXYNOS4_ISP_DMA_CAPTURE
++int fimc_isp_video_device_register(struct fimc_isp *isp,
++                              struct v4l2_device *v4l2_dev,
++                              enum v4l2_buf_type type);
++
++void fimc_isp_video_device_unregister(struct fimc_isp *isp,
++                              enum v4l2_buf_type type);
++
++void fimc_isp_video_irq_handler(struct fimc_is *is);
++#else
++static inline void fimc_isp_video_irq_handler(struct fimc_is *is)
++{
++}
++
++static inline int fimc_isp_video_device_register(struct fimc_isp *isp,
++                                              struct v4l2_device *v4l2_dev,
++                                              enum v4l2_buf_type type)
++{
++      return 0;
++}
++
++void fimc_isp_video_device_unregister(struct fimc_isp *isp,
++                              enum v4l2_buf_type type)
++{
++}
++#endif /* !CONFIG_VIDEO_EXYNOS4_ISP_DMA_CAPTURE */
++
++#endif /* FIMC_ISP_VIDEO__ */
+diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c
+index cf520a7..077993c 100644
+--- a/drivers/media/platform/exynos4-is/fimc-isp.c
++++ b/drivers/media/platform/exynos4-is/fimc-isp.c
+@@ -25,6 +25,7 @@
+ #include <media/v4l2-device.h>
+ #include "media-dev.h"
++#include "fimc-isp-video.h"
+ #include "fimc-is-command.h"
+ #include "fimc-is-param.h"
+ #include "fimc-is-regs.h"
+@@ -93,8 +94,8 @@ void fimc_isp_irq_handler(struct fimc_is *is)
+       is->i2h_cmd.args[1] = mcuctl_read(is, MCUCTL_REG_ISSR(21));
+       fimc_is_fw_clear_irq1(is, FIMC_IS_INT_FRAME_DONE_ISP);
++      fimc_isp_video_irq_handler(is);
+-      /* TODO: Complete ISP DMA interrupt handler */
+       wake_up(&is->irq_queue);
+ }
+@@ -388,7 +389,33 @@ static int fimc_isp_subdev_open(struct v4l2_subdev *sd,
+       return 0;
+ }
++static int fimc_isp_subdev_registered(struct v4l2_subdev *sd)
++{
++      struct fimc_isp *isp = v4l2_get_subdevdata(sd);
++      int ret;
++
++      /* Use pipeline object allocated by the media device. */
++      isp->video_capture.ve.pipe = v4l2_get_subdev_hostdata(sd);
++
++      ret = fimc_isp_video_device_register(isp, sd->v4l2_dev,
++                      V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
++      if (ret < 0)
++              isp->video_capture.ve.pipe = NULL;
++
++      return ret;
++}
++
++static void fimc_isp_subdev_unregistered(struct v4l2_subdev *sd)
++{
++      struct fimc_isp *isp = v4l2_get_subdevdata(sd);
++
++      fimc_isp_video_device_unregister(isp,
++                      V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
++}
++
+ static const struct v4l2_subdev_internal_ops fimc_is_subdev_internal_ops = {
++      .registered = fimc_isp_subdev_registered,
++      .unregistered = fimc_isp_subdev_unregistered,
+       .open = fimc_isp_subdev_open,
+ };
+diff --git a/drivers/media/platform/exynos4-is/fimc-isp.h b/drivers/media/platform/exynos4-is/fimc-isp.h
+index 03bf95a..4dc55a1 100644
+--- a/drivers/media/platform/exynos4-is/fimc-isp.h
++++ b/drivers/media/platform/exynos4-is/fimc-isp.h
+@@ -35,17 +35,18 @@ extern int fimc_isp_debug;
+ #define FIMC_ISP_SINK_WIDTH_MIN               (16 + 8)
+ #define FIMC_ISP_SINK_HEIGHT_MIN      (12 + 8)
+ #define FIMC_ISP_SOURCE_WIDTH_MIN     8
+-#define FIMC_ISP_SOURC_HEIGHT_MIN     8
++#define FIMC_ISP_SOURCE_HEIGHT_MIN    8
+ #define FIMC_ISP_CAC_MARGIN_WIDTH     16
+ #define FIMC_ISP_CAC_MARGIN_HEIGHT    12
+ #define FIMC_ISP_SINK_WIDTH_MAX               (4000 - 16)
+ #define FIMC_ISP_SINK_HEIGHT_MAX      (4000 + 12)
+ #define FIMC_ISP_SOURCE_WIDTH_MAX     4000
+-#define FIMC_ISP_SOURC_HEIGHT_MAX     4000
++#define FIMC_ISP_SOURCE_HEIGHT_MAX    4000
+ #define FIMC_ISP_NUM_FORMATS          3
+ #define FIMC_ISP_REQ_BUFS_MIN         2
++#define FIMC_ISP_REQ_BUFS_MAX         32
+ #define FIMC_ISP_SD_PAD_SINK          0
+ #define FIMC_ISP_SD_PAD_SRC_FIFO      1
+@@ -100,6 +101,16 @@ struct fimc_isp_ctrls {
+       struct v4l2_ctrl *colorfx;
+ };
++struct isp_video_buf {
++      struct vb2_buffer vb;
++      dma_addr_t dma_addr[FIMC_ISP_MAX_PLANES];
++      unsigned int index;
++};
++
++#define to_isp_video_buf(_b) container_of(_b, struct isp_video_buf, vb)
++
++#define FIMC_ISP_MAX_BUFS     4
++
+ /**
+  * struct fimc_is_video - fimc-is video device structure
+  * @vdev: video_device structure
+@@ -114,18 +125,26 @@ struct fimc_isp_ctrls {
+  * @format: current pixel format
+  */
+ struct fimc_is_video {
+-      struct video_device     vdev;
++      struct exynos_video_entity ve;
+       enum v4l2_buf_type      type;
+       struct media_pad        pad;
+       struct list_head        pending_buf_q;
+       struct list_head        active_buf_q;
+       struct vb2_queue        vb_queue;
+-      unsigned int            frame_count;
+       unsigned int            reqbufs_count;
++      unsigned int            buf_count;
++      unsigned int            buf_mask;
++      unsigned int            frame_count;
+       int                     streaming;
++      struct isp_video_buf    *buffers[FIMC_ISP_MAX_BUFS];
+       const struct fimc_fmt   *format;
++      struct v4l2_pix_format_mplane pixfmt;
+ };
++/* struct fimc_isp:state bit definitions */
++#define ST_ISP_VID_CAP_BUF_PREP               0
++#define ST_ISP_VID_CAP_STREAMING      1
++
+ /**
+  * struct fimc_isp - FIMC-IS ISP data structure
+  * @pdev: pointer to FIMC-IS platform device
+diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
+index 91f21e2..d1a1ff6 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.c
++++ b/drivers/media/platform/exynos4-is/media-dev.c
+@@ -732,8 +732,16 @@ static int register_csis_entity(struct fimc_md *fmd,
+ static int register_fimc_is_entity(struct fimc_md *fmd, struct fimc_is *is)
+ {
+       struct v4l2_subdev *sd = &is->isp.subdev;
++      struct exynos_media_pipeline *ep;
+       int ret;
++      /* Allocate pipeline object for the ISP capture video node. */
++      ep = fimc_md_pipeline_create(fmd);
++      if (!ep)
++              return -ENOMEM;
++
++      v4l2_set_subdev_hostdata(sd, ep);
++
+       ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
+       if (ret) {
+               v4l2_err(&fmd->v4l2_dev,
+@@ -1005,16 +1013,17 @@ static int __fimc_md_create_flite_source_links(struct fimc_md *fmd)
+ /* Create FIMC-IS links */
+ static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd)
+ {
++      struct fimc_isp *isp = &fmd->fimc_is->isp;
+       struct media_entity *source, *sink;
+       int i, ret;
+-      source = &fmd->fimc_is->isp.subdev.entity;
++      source = &isp->subdev.entity;
+       for (i = 0; i < FIMC_MAX_DEVS; i++) {
+               if (fmd->fimc[i] == NULL)
+                       continue;
+-              /* Link from IS-ISP subdev to FIMC */
++              /* Link from FIMC-IS-ISP subdev to FIMC */
+               sink = &fmd->fimc[i]->vid_cap.subdev.entity;
+               ret = media_entity_create_link(source, FIMC_ISP_SD_PAD_SRC_FIFO,
+                                              sink, FIMC_SD_PAD_SINK_FIFO, 0);
+@@ -1022,7 +1031,15 @@ static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd)
+                       return ret;
+       }
+-      return ret;
++      /* Link from FIMC-IS-ISP subdev to fimc-is-isp.capture video node */
++      sink = &isp->video_capture.ve.vdev.entity;
++
++      /* Skip this link if the fimc-is-isp video node driver isn't built-in */
++      if (sink->num_pads == 0)
++              return 0;
++
++      return media_entity_create_link(source, FIMC_ISP_SD_PAD_SRC_DMA,
++                                      sink, 0, 0);
+ }
+ /**
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0286-ARM-dts-Add-MIPI-PHY-node-to-exynos4.dtsi.patch b/patches.tizen/0286-ARM-dts-Add-MIPI-PHY-node-to-exynos4.dtsi.patch
new file mode 100644 (file)
index 0000000..ed73c54
--- /dev/null
@@ -0,0 +1,60 @@
+From 553013e754ed1aeaa38328609014053c2e539ba4 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 4 Apr 2013 13:23:27 +0200
+Subject: [PATCH 0286/1302] ARM: dts: Add MIPI PHY node to exynos4.dtsi
+
+Add PHY provider node for the MIPI CSIS and MIPI DSIM PHYs.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index a18cba6..2f2a5f4 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -120,12 +120,20 @@
+               reg = <0x10010000 0x400>;
+       };
++      mipi_phy: video-phy@10020710 {
++              compatible = "samsung,s5pv210-mipi-video-phy";
++              reg = <0x10020710 8>;
++              #phy-cells = <1>;
++      };
++
+       dsi_0: dsi@11C80000 {
+               compatible = "samsung,exynos4210-mipi-dsi";
+               reg = <0x11C80000 0x10000>;
+               interrupts = <0 79 0>;
+               samsung,phy-type = <0>;
+               samsung,power-domain = <&pd_lcd0>;
++              phys = <&mipi_phy 1>;
++              phy-names = "dsim";
+               clocks = <&clock 286>, <&clock 143>;
+               clock-names = "bus_clk", "pll_clk";
+               status = "disabled";
+@@ -204,6 +212,8 @@
+                       interrupts = <0 78 0>;
+                       bus-width = <4>;
+                       samsung,power-domain = <&pd_cam>;
++                      phys = <&mipi_phy 0>;
++                      phy-names = "csis";
+                       status = "disabled";
+               };
+@@ -213,6 +223,8 @@
+                       interrupts = <0 80 0>;
+                       bus-width = <2>;
+                       samsung,power-domain = <&pd_cam>;
++                      phys = <&mipi_phy 2>;
++                      phy-names = "csis";
+                       status = "disabled";
+               };
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0287-drivers-phy-add-generic-PHY-framework.patch b/patches.tizen/0287-drivers-phy-add-generic-PHY-framework.patch
new file mode 100644 (file)
index 0000000..32ae982
--- /dev/null
@@ -0,0 +1,1220 @@
+From 4c64b2c45a37c5b85ea7abc43fa65c99bb9fdbbe Mon Sep 17 00:00:00 2001
+From: Kishon Vijay Abraham I <kishon@ti.com>
+Date: Wed, 26 Jun 2013 15:27:45 +0530
+Subject: [PATCH 0287/1302] drivers: phy: add generic PHY framework
+
+The PHY framework provides a set of APIs for the PHY drivers to
+create/destroy a PHY and APIs for the PHY users to obtain a reference to the
+PHY with or without using phandle. For dt-boot, the PHY drivers should
+also register *PHY provider* with the framework.
+
+PHY drivers should create the PHY by passing id and ops like init, exit,
+power_on and power_off. This framework is also pm runtime enabled.
+
+The documentation for the generic PHY framework is added in
+Documentation/phy.txt and the documentation for dt binding can be found at
+Documentation/devicetree/bindings/phy/phy-bindings.txt
+
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+Tested-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/phy/phy-bindings.txt       |  66 +++
+ Documentation/phy.txt                              | 129 +++++
+ MAINTAINERS                                        |   7 +
+ drivers/Kconfig                                    |   2 +
+ drivers/Makefile                                   |   2 +
+ drivers/phy/Kconfig                                |  13 +
+ drivers/phy/Makefile                               |   5 +
+ drivers/phy/phy-core.c                             | 544 +++++++++++++++++++++
+ include/linux/phy/phy.h                            | 344 +++++++++++++
+ 9 files changed, 1112 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/phy/phy-bindings.txt
+ create mode 100644 Documentation/phy.txt
+ create mode 100644 drivers/phy/Kconfig
+ create mode 100644 drivers/phy/Makefile
+ create mode 100644 drivers/phy/phy-core.c
+ create mode 100644 include/linux/phy/phy.h
+
+diff --git a/Documentation/devicetree/bindings/phy/phy-bindings.txt b/Documentation/devicetree/bindings/phy/phy-bindings.txt
+new file mode 100644
+index 0000000..8ae844f
+--- /dev/null
++++ b/Documentation/devicetree/bindings/phy/phy-bindings.txt
+@@ -0,0 +1,66 @@
++This document explains only the device tree data binding. For general
++information about PHY subsystem refer to Documentation/phy.txt
++
++PHY device node
++===============
++
++Required Properties:
++#phy-cells:   Number of cells in a PHY specifier;  The meaning of all those
++              cells is defined by the binding for the phy node. The PHY
++              provider can use the values in cells to find the appropriate
++              PHY.
++
++For example:
++
++phys: phy {
++    compatible = "xxx";
++    reg = <...>;
++    .
++    .
++    #phy-cells = <1>;
++    .
++    .
++};
++
++That node describes an IP block (PHY provider) that implements 2 different PHYs.
++In order to differentiate between these 2 PHYs, an additonal specifier should be
++given while trying to get a reference to it.
++
++PHY user node
++=============
++
++Required Properties:
++phys : the phandle for the PHY device (used by the PHY subsystem)
++phy-names : the names of the PHY corresponding to the PHYs present in the
++          *phys* phandle
++
++Example 1:
++usb1: usb_otg_ss@xxx {
++    compatible = "xxx";
++    reg = <xxx>;
++    .
++    .
++    phys = <&usb2_phy>, <&usb3_phy>;
++    phy-names = "usb2phy", "usb3phy";
++    .
++    .
++};
++
++This node represents a controller that uses two PHYs, one for usb2 and one for
++usb3.
++
++Example 2:
++usb2: usb_otg_ss@xxx {
++    compatible = "xxx";
++    reg = <xxx>;
++    .
++    .
++    phys = <&phys 1>;
++    phy-names = "usbphy";
++    .
++    .
++};
++
++This node represents a controller that uses one of the PHYs of the PHY provider
++device defined previously. Note that the phy handle has an additional specifier
++"1" to differentiate between the two PHYs.
+diff --git a/Documentation/phy.txt b/Documentation/phy.txt
+new file mode 100644
+index 0000000..05f8fda
+--- /dev/null
++++ b/Documentation/phy.txt
+@@ -0,0 +1,129 @@
++                          PHY SUBSYSTEM
++                Kishon Vijay Abraham I <kishon@ti.com>
++
++This document explains the Generic PHY Framework along with the APIs provided,
++and how-to-use.
++
++1. Introduction
++
++*PHY* is the abbreviation for physical layer. It is used to connect a device
++to the physical medium e.g., the USB controller has a PHY to provide functions
++such as serialization, de-serialization, encoding, decoding and is responsible
++for obtaining the required data transmission rate. Note that some USB
++controllers have PHY functionality embedded into it and others use an external
++PHY. Other peripherals that use PHY include Wireless LAN, Ethernet,
++SATA etc.
++
++The intention of creating this framework is to bring the PHY drivers spread
++all over the Linux kernel to drivers/phy to increase code re-use and for
++better code maintainability.
++
++This framework will be of use only to devices that use external PHY (PHY
++functionality is not embedded within the controller).
++
++2. Registering/Unregistering the PHY provider
++
++PHY provider refers to an entity that implements one or more PHY instances.
++For the simple case where the PHY provider implements only a single instance of
++the PHY, the framework provides its own implementation of of_xlate in
++of_phy_simple_xlate. If the PHY provider implements multiple instances, it
++should provide its own implementation of of_xlate. of_xlate is used only for
++dt boot case.
++
++struct phy_provider *__of_phy_provider_register(struct device *dev,
++      struct module *owner, struct phy * (*of_xlate)(struct device *dev,
++      struct of_phandle_args *args));
++struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
++      struct module *owner, struct phy * (*of_xlate)(struct device *dev,
++      struct of_phandle_args *args))
++
++__of_phy_provider_register and __devm_of_phy_provider_register can be used to
++register the phy_provider and it takes device, owner and of_xlate as
++arguments. For the dt boot case, all PHY providers should use one of the above
++2 APIs to register the PHY provider.
++
++void devm_of_phy_provider_unregister(struct device *dev,
++      struct phy_provider *phy_provider);
++void of_phy_provider_unregister(struct phy_provider *phy_provider);
++
++devm_of_phy_provider_unregister and of_phy_provider_unregister can be used to
++unregister the PHY.
++
++3. Creating the PHY
++
++The PHY driver should create the PHY in order for other peripheral controllers
++to make use of it. The PHY framework provides 2 APIs to create the PHY.
++
++struct phy *phy_create(struct device *dev, u8 id, const struct phy_ops *ops,
++      const char *label);
++extern struct phy *devm_phy_create(struct device *dev, u8 id,
++        const struct phy_ops *ops, const char *label);
++
++The PHY drivers can use one of the above 2 APIs to create the PHY by passing
++the device pointer, id, phy ops, label and a driver data.
++phy_ops is a set of function pointers for performing PHY operations such as
++init, exit, power_on and power_off. *label* is mandatory for non-dt boot case
++and it should be unique as well.
++
++Inorder to dereference the private data (in phy_ops), the phy provider driver
++can use phy_set_drvdata() after creating the PHY and use phy_get_drvdata() in
++phy_ops to get back the private data.
++
++4. Getting a reference to the PHY
++
++Before the controller can make use of the PHY, it has to get a reference to
++it. This framework provides the following APIs to get a reference to the PHY.
++
++struct phy *phy_get(struct device *dev, const char *string);
++struct phy *devm_phy_get(struct device *dev, const char *string);
++
++phy_get and devm_phy_get can be used to get the PHY. In the case of dt boot,
++the string arguments should contain the phy name as given in the dt data and
++in the case of non-dt boot, it should contain the label of the PHY.
++The only difference between the two APIs is that devm_phy_get associates the
++device with the PHY using devres on successful PHY get. On driver detach,
++release function is invoked on the the devres data and devres data is freed.
++
++5. Releasing a reference to the PHY
++
++When the controller no longer needs the PHY, it has to release the reference
++to the PHY it has obtained using the APIs mentioned in the above section. The
++PHY framework provides 2 APIs to release a reference to the PHY.
++
++void phy_put(struct phy *phy);
++void devm_phy_put(struct device *dev, struct phy *phy);
++
++Both these APIs are used to release a reference to the PHY and devm_phy_put
++destroys the devres associated with this PHY.
++
++6. Destroying the PHY
++
++When the driver that created the PHY is unloaded, it should destroy the PHY it
++created using one of the following 2 APIs.
++
++void phy_destroy(struct phy *phy);
++void devm_phy_destroy(struct device *dev, struct phy *phy);
++
++Both these APIs destroy the PHY and devm_phy_destroy destroys the devres
++associated with this PHY.
++
++7. PM Runtime
++
++This subsystem is pm runtime enabled. So while creating the PHY,
++pm_runtime_enable of the phy device created by this subsystem is called and
++while destroying the PHY, pm_runtime_disable is called. Note that the phy
++device created by this subsystem will be a child of the device that calls
++phy_create (PHY provider device).
++
++So pm_runtime_get_sync of the phy_device created by this subsystem will invoke
++pm_runtime_get_sync of PHY provider device because of parent-child relationship.
++It should also be noted that phy_power_on and phy_power_off performs
++phy_pm_runtime_get_sync and phy_pm_runtime_put respectively.
++There are exported APIs like phy_pm_runtime_get, phy_pm_runtime_get_sync,
++phy_pm_runtime_put, phy_pm_runtime_put_sync, phy_pm_runtime_allow and
++phy_pm_runtime_forbid for performing PM operations.
++
++8. DeviceTree Binding
++
++The documentation for PHY dt binding can be found @
++Documentation/devicetree/bindings/phy/phy-bindings.txt
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 0775741..761de43 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -3536,6 +3536,13 @@ S:      Maintained
+ F:    include/asm-generic
+ F:    include/uapi/asm-generic
++GENERIC PHY FRAMEWORK
++M:    Kishon Vijay Abraham I <kishon@ti.com>
++L:    linux-kernel@vger.kernel.org
++S:    Supported
++F:    drivers/phy/
++F:    include/linux/phy/
++
+ GENERIC UIO DRIVER FOR PCI DEVICES
+ M:    "Michael S. Tsirkin" <mst@redhat.com>
+ L:    kvm@vger.kernel.org
+diff --git a/drivers/Kconfig b/drivers/Kconfig
+index 9953a42..2943fb6 100644
+--- a/drivers/Kconfig
++++ b/drivers/Kconfig
+@@ -166,4 +166,6 @@ source "drivers/ipack/Kconfig"
+ source "drivers/reset/Kconfig"
++source "drivers/phy/Kconfig"
++
+ endmenu
+diff --git a/drivers/Makefile b/drivers/Makefile
+index 130abc1..46c99a1 100644
+--- a/drivers/Makefile
++++ b/drivers/Makefile
+@@ -8,6 +8,8 @@
+ obj-y                         += irqchip/
+ obj-y                         += bus/
++obj-$(CONFIG_GENERIC_PHY)     += phy/
++
+ # GPIO must come after pinctrl as gpios may need to mux pins etc
+ obj-y                         += pinctrl/
+ obj-y                         += gpio/
+diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
+new file mode 100644
+index 0000000..5f85909
+--- /dev/null
++++ b/drivers/phy/Kconfig
+@@ -0,0 +1,13 @@
++#
++# PHY
++#
++
++menuconfig GENERIC_PHY
++      tristate "PHY Subsystem"
++      help
++        Generic PHY support.
++
++        This framework is designed to provide a generic interface for PHY
++        devices present in the kernel. This layer will have the generic
++        API by which phy drivers can create PHY using the phy framework and
++        phy users can obtain reference to the PHY.
+diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
+new file mode 100644
+index 0000000..9e9560f
+--- /dev/null
++++ b/drivers/phy/Makefile
+@@ -0,0 +1,5 @@
++#
++# Makefile for the phy drivers.
++#
++
++obj-$(CONFIG_GENERIC_PHY)     += phy-core.o
+diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
+new file mode 100644
+index 0000000..6c75dc3
+--- /dev/null
++++ b/drivers/phy/phy-core.c
+@@ -0,0 +1,544 @@
++/*
++ * phy-core.c  --  Generic Phy framework.
++ *
++ * Copyright (C) 2013 Texas Instruments
++ *
++ * Author: Kishon Vijay Abraham I <kishon@ti.com>
++ *
++ * This program is free software; you can redistribute  it and/or modify it
++ * under  the terms of  the GNU General  Public License as published by the
++ * Free Software Foundation;  either version 2 of the  License, or (at your
++ * option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
++ */
++
++#include <linux/kernel.h>
++#include <linux/export.h>
++#include <linux/module.h>
++#include <linux/err.h>
++#include <linux/device.h>
++#include <linux/slab.h>
++#include <linux/of.h>
++#include <linux/phy/phy.h>
++#include <linux/pm_runtime.h>
++
++static struct class *phy_class;
++static DEFINE_MUTEX(phy_provider_mutex);
++static LIST_HEAD(phy_provider_list);
++
++static void devm_phy_release(struct device *dev, void *res)
++{
++      struct phy *phy = *(struct phy **)res;
++
++      phy_put(phy);
++}
++
++static void devm_phy_provider_release(struct device *dev, void *res)
++{
++      struct phy_provider *phy_provider = *(struct phy_provider **)res;
++
++      of_phy_provider_unregister(phy_provider);
++}
++
++static void devm_phy_consume(struct device *dev, void *res)
++{
++      struct phy *phy = *(struct phy **)res;
++
++      phy_destroy(phy);
++}
++
++static int devm_phy_match(struct device *dev, void *res, void *match_data)
++{
++      return res == match_data;
++}
++
++static struct phy *phy_lookup(const char *phy_name)
++{
++      struct phy *phy;
++      struct device *dev;
++      struct class_dev_iter iter;
++
++      class_dev_iter_init(&iter, phy_class, NULL, NULL);
++      while ((dev = class_dev_iter_next(&iter))) {
++              phy = to_phy(dev);
++              if (strcmp(phy->label, phy_name))
++                      continue;
++
++              class_dev_iter_exit(&iter);
++              return phy;
++      }
++
++      class_dev_iter_exit(&iter);
++      return ERR_PTR(-ENODEV);
++}
++
++static struct phy_provider *of_phy_provider_lookup(struct device_node *node)
++{
++      struct phy_provider *phy_provider;
++
++      list_for_each_entry(phy_provider, &phy_provider_list, list) {
++              if (phy_provider->dev->of_node == node)
++                      return phy_provider;
++      }
++
++      return ERR_PTR(-EPROBE_DEFER);
++}
++
++/**
++ * of_phy_get() - lookup and obtain a reference to a phy by phandle
++ * @dev: device that requests this phy
++ * @index: the index of the phy
++ *
++ * Returns the phy associated with the given phandle value,
++ * after getting a refcount to it or -ENODEV if there is no such phy or
++ * -EPROBE_DEFER if there is a phandle to the phy, but the device is
++ * not yet loaded. This function uses of_xlate call back function provided
++ * while registering the phy_provider to find the phy instance.
++ */
++static struct phy *of_phy_get(struct device *dev, int index)
++{
++      int ret;
++      struct phy_provider *phy_provider;
++      struct phy *phy = NULL;
++      struct of_phandle_args args;
++
++      ret = of_parse_phandle_with_args(dev->of_node, "phys", "#phy-cells",
++              index, &args);
++      if (ret) {
++              dev_dbg(dev, "failed to get phy in %s node\n",
++                      dev->of_node->full_name);
++              return ERR_PTR(-ENODEV);
++      }
++
++      mutex_lock(&phy_provider_mutex);
++      phy_provider = of_phy_provider_lookup(args.np);
++      if (IS_ERR(phy_provider) || !try_module_get(phy_provider->owner)) {
++              phy = ERR_PTR(-EPROBE_DEFER);
++              goto err0;
++      }
++
++      phy = phy_provider->of_xlate(phy_provider->dev, &args);
++      module_put(phy_provider->owner);
++
++err0:
++      mutex_unlock(&phy_provider_mutex);
++      of_node_put(args.np);
++
++      return phy;
++}
++
++/**
++ * phy_put() - release the PHY
++ * @phy: the phy returned by phy_get()
++ *
++ * Releases a refcount the caller received from phy_get().
++ */
++void phy_put(struct phy *phy)
++{
++      if (IS_ERR(phy))
++              return;
++
++      module_put(phy->ops->owner);
++      put_device(&phy->dev);
++}
++EXPORT_SYMBOL_GPL(phy_put);
++
++/**
++ * devm_phy_put() - release the PHY
++ * @dev: device that wants to release this phy
++ * @phy: the phy returned by devm_phy_get()
++ *
++ * destroys the devres associated with this phy and invokes phy_put
++ * to release the phy.
++ */
++void devm_phy_put(struct device *dev, struct phy *phy)
++{
++      int r;
++
++      r = devres_destroy(dev, devm_phy_release, devm_phy_match, phy);
++      dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n");
++}
++EXPORT_SYMBOL_GPL(devm_phy_put);
++
++/**
++ * of_phy_simple_xlate() - returns the phy instance from phy provider
++ * @dev: the PHY provider device
++ * @args: of_phandle_args (not used here)
++ *
++ * Intended to be used by phy provider for the common case where #phy-cells is
++ * 0. For other cases where #phy-cells is greater than '0', the phy provider
++ * should provide a custom of_xlate function that reads the *args* and returns
++ * the appropriate phy.
++ */
++struct phy *of_phy_simple_xlate(struct device *dev, struct of_phandle_args
++      *args)
++{
++      struct phy *phy;
++      struct class_dev_iter iter;
++      struct device_node *node = dev->of_node;
++
++      class_dev_iter_init(&iter, phy_class, NULL, NULL);
++      while ((dev = class_dev_iter_next(&iter))) {
++              phy = to_phy(dev);
++              if (node != phy->dev.of_node)
++                      continue;
++
++              class_dev_iter_exit(&iter);
++              return phy;
++      }
++
++      class_dev_iter_exit(&iter);
++      return ERR_PTR(-ENODEV);
++}
++EXPORT_SYMBOL_GPL(of_phy_simple_xlate);
++
++/**
++ * phy_get() - lookup and obtain a reference to a phy.
++ * @dev: device that requests this phy
++ * @string: the phy name as given in the dt data or phy device name
++ * for non-dt case
++ *
++ * Returns the phy driver, after getting a refcount to it; or
++ * -ENODEV if there is no such phy.  The caller is responsible for
++ * calling phy_put() to release that count.
++ */
++struct phy *phy_get(struct device *dev, const char *string)
++{
++      int index = 0;
++      struct phy *phy = NULL;
++
++      if (string == NULL) {
++              dev_WARN(dev, "missing string\n");
++              return ERR_PTR(-EINVAL);
++      }
++
++      if (dev->of_node) {
++              index = of_property_match_string(dev->of_node, "phy-names",
++                      string);
++              phy = of_phy_get(dev, index);
++              if (IS_ERR(phy)) {
++                      dev_WARN(dev, "unable to find phy\n");
++                      return phy;
++              }
++      } else {
++              phy = phy_lookup(string);
++              if (IS_ERR(phy)) {
++                      dev_WARN(dev, "unable to find phy\n");
++                      return phy;
++              }
++      }
++
++      if (!try_module_get(phy->ops->owner))
++              return ERR_PTR(-EPROBE_DEFER);
++
++      get_device(&phy->dev);
++
++      return phy;
++}
++EXPORT_SYMBOL_GPL(phy_get);
++
++/**
++ * devm_phy_get() - lookup and obtain a reference to a phy.
++ * @dev: device that requests this phy
++ * @string: the phy name as given in the dt data or phy device name
++ * for non-dt case
++ *
++ * Gets the phy using phy_get(), and associates a device with it using
++ * devres. On driver detach, release function is invoked on the devres data,
++ * then, devres data is freed.
++ */
++struct phy *devm_phy_get(struct device *dev, const char *string)
++{
++      struct phy **ptr, *phy;
++
++      ptr = devres_alloc(devm_phy_release, sizeof(*ptr), GFP_KERNEL);
++      if (!ptr)
++              return ERR_PTR(-ENOMEM);
++
++      phy = phy_get(dev, string);
++      if (!IS_ERR(phy)) {
++              *ptr = phy;
++              devres_add(dev, ptr);
++      } else {
++              devres_free(ptr);
++      }
++
++      return phy;
++}
++EXPORT_SYMBOL_GPL(devm_phy_get);
++
++/**
++ * phy_create() - create a new phy
++ * @dev: device that is creating the new phy
++ * @id: id of the phy
++ * @ops: function pointers for performing phy operations
++ * @label: label given to the phy
++ *
++ * Called to create a phy using phy framework.
++ */
++struct phy *phy_create(struct device *dev, u8 id, const struct phy_ops *ops,
++      const char *label)
++{
++      int ret;
++      struct phy *phy;
++
++      if (!dev) {
++              dev_WARN(dev, "no device provided for PHY\n");
++              ret = -EINVAL;
++              goto err0;
++      }
++
++      phy = kzalloc(sizeof(*phy), GFP_KERNEL);
++      if (!phy) {
++              ret = -ENOMEM;
++              goto err0;
++      }
++
++      device_initialize(&phy->dev);
++      mutex_init(&phy->mutex);
++
++      phy->dev.class = phy_class;
++      phy->dev.parent = dev;
++      phy->dev.of_node = dev->of_node;
++      phy->id = id;
++      phy->ops = ops;
++      phy->label = kstrdup(label, GFP_KERNEL);
++
++      ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
++      if (ret)
++              goto err1;
++
++      ret = device_add(&phy->dev);
++      if (ret)
++              goto err1;
++
++      if (pm_runtime_enabled(dev)) {
++              pm_runtime_enable(&phy->dev);
++              pm_runtime_no_callbacks(&phy->dev);
++      }
++
++      return phy;
++
++err1:
++      put_device(&phy->dev);
++      kfree(phy->label);
++      kfree(phy);
++
++err0:
++      return ERR_PTR(ret);
++}
++EXPORT_SYMBOL_GPL(phy_create);
++
++/**
++ * devm_phy_create() - create a new phy
++ * @dev: device that is creating the new phy
++ * @id: id of the phy
++ * @ops: function pointers for performing phy operations
++ * @label: label given to the phy
++ *
++ * Creates a new PHY device adding it to the PHY class.
++ * While at that, it also associates the device with the phy using devres.
++ * On driver detach, release function is invoked on the devres data,
++ * then, devres data is freed.
++ */
++struct phy *devm_phy_create(struct device *dev, u8 id,
++      const struct phy_ops *ops, const char *label)
++{
++      struct phy **ptr, *phy;
++
++      ptr = devres_alloc(devm_phy_consume, sizeof(*ptr), GFP_KERNEL);
++      if (!ptr)
++              return ERR_PTR(-ENOMEM);
++
++      phy = phy_create(dev, id, ops, label);
++      if (!IS_ERR(phy)) {
++              *ptr = phy;
++              devres_add(dev, ptr);
++      } else {
++              devres_free(ptr);
++      }
++
++      return phy;
++}
++EXPORT_SYMBOL_GPL(devm_phy_create);
++
++/**
++ * phy_destroy() - destroy the phy
++ * @phy: the phy to be destroyed
++ *
++ * Called to destroy the phy.
++ */
++void phy_destroy(struct phy *phy)
++{
++      pm_runtime_disable(&phy->dev);
++      device_unregister(&phy->dev);
++}
++EXPORT_SYMBOL_GPL(phy_destroy);
++
++/**
++ * devm_phy_destroy() - destroy the PHY
++ * @dev: device that wants to release this phy
++ * @phy: the phy returned by devm_phy_get()
++ *
++ * destroys the devres associated with this phy and invokes phy_destroy
++ * to destroy the phy.
++ */
++void devm_phy_destroy(struct device *dev, struct phy *phy)
++{
++      int r;
++
++      r = devres_destroy(dev, devm_phy_consume, devm_phy_match, phy);
++      dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n");
++}
++EXPORT_SYMBOL_GPL(devm_phy_destroy);
++
++/**
++ * __of_phy_provider_register() - create/register phy provider with the framework
++ * @dev: struct device of the phy provider
++ * @owner: the module owner containing of_xlate
++ * @of_xlate: function pointer to obtain phy instance from phy provider
++ *
++ * Creates struct phy_provider from dev and of_xlate function pointer.
++ * This is used in the case of dt boot for finding the phy instance from
++ * phy provider.
++ */
++struct phy_provider *__of_phy_provider_register(struct device *dev,
++      struct module *owner, struct phy * (*of_xlate)(struct device *dev,
++      struct of_phandle_args *args))
++{
++      struct phy_provider *phy_provider;
++
++      phy_provider = kzalloc(sizeof(*phy_provider), GFP_KERNEL);
++      if (!phy_provider)
++              return ERR_PTR(-ENOMEM);
++
++      phy_provider->dev = dev;
++      phy_provider->owner = owner;
++      phy_provider->of_xlate = of_xlate;
++
++      mutex_lock(&phy_provider_mutex);
++      list_add_tail(&phy_provider->list, &phy_provider_list);
++      mutex_unlock(&phy_provider_mutex);
++
++      return phy_provider;
++}
++EXPORT_SYMBOL_GPL(__of_phy_provider_register);
++
++/**
++ * __devm_of_phy_provider_register() - create/register phy provider with the
++ * framework
++ * @dev: struct device of the phy provider
++ * @owner: the module owner containing of_xlate
++ * @of_xlate: function pointer to obtain phy instance from phy provider
++ *
++ * Creates struct phy_provider from dev and of_xlate function pointer.
++ * This is used in the case of dt boot for finding the phy instance from
++ * phy provider. While at that, it also associates the device with the
++ * phy provider using devres. On driver detach, release function is invoked
++ * on the devres data, then, devres data is freed.
++ */
++struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
++      struct module *owner, struct phy * (*of_xlate)(struct device *dev,
++      struct of_phandle_args *args))
++{
++      struct phy_provider **ptr, *phy_provider;
++
++      ptr = devres_alloc(devm_phy_provider_release, sizeof(*ptr), GFP_KERNEL);
++      if (!ptr)
++              return ERR_PTR(-ENOMEM);
++
++      phy_provider = __of_phy_provider_register(dev, owner, of_xlate);
++      if (!IS_ERR(phy_provider)) {
++              *ptr = phy_provider;
++              devres_add(dev, ptr);
++      } else {
++              devres_free(ptr);
++      }
++
++      return phy_provider;
++}
++EXPORT_SYMBOL_GPL(__devm_of_phy_provider_register);
++
++/**
++ * of_phy_provider_unregister() - unregister phy provider from the framework
++ * @phy_provider: phy provider returned by of_phy_provider_register()
++ *
++ * Removes the phy_provider created using of_phy_provider_register().
++ */
++void of_phy_provider_unregister(struct phy_provider *phy_provider)
++{
++      if (IS_ERR(phy_provider))
++              return;
++
++      mutex_lock(&phy_provider_mutex);
++      list_del(&phy_provider->list);
++      kfree(phy_provider);
++      mutex_unlock(&phy_provider_mutex);
++}
++EXPORT_SYMBOL_GPL(of_phy_provider_unregister);
++
++/**
++ * devm_of_phy_provider_unregister() - remove phy provider from the framework
++ * @dev: struct device of the phy provider
++ *
++ * destroys the devres associated with this phy provider and invokes
++ * of_phy_provider_unregister to unregister the phy provider.
++ */
++void devm_of_phy_provider_unregister(struct device *dev,
++      struct phy_provider *phy_provider) {
++      int r;
++
++      r = devres_destroy(dev, devm_phy_provider_release, devm_phy_match,
++              phy_provider);
++      dev_WARN_ONCE(dev, r, "couldn't find PHY provider device resource\n");
++}
++EXPORT_SYMBOL_GPL(devm_of_phy_provider_unregister);
++
++/**
++ * phy_release() - release the phy
++ * @dev: the dev member within phy
++ *
++ * When the last reference to the device is removed, it is called
++ * from the embedded kobject as release method.
++ */
++static void phy_release(struct device *dev)
++{
++      struct phy *phy;
++
++      phy = to_phy(dev);
++      dev_vdbg(dev, "releasing '%s'\n", dev_name(dev));
++      kfree(phy->label);
++      kfree(phy);
++}
++
++static int __init phy_core_init(void)
++{
++      phy_class = class_create(THIS_MODULE, "phy");
++      if (IS_ERR(phy_class)) {
++              pr_err("failed to create phy class --> %ld\n",
++                      PTR_ERR(phy_class));
++              return PTR_ERR(phy_class);
++      }
++
++      phy_class->dev_release = phy_release;
++
++      return 0;
++}
++module_init(phy_core_init);
++
++static void __exit phy_core_exit(void)
++{
++      class_destroy(phy_class);
++}
++module_exit(phy_core_exit);
++
++MODULE_DESCRIPTION("Generic PHY Framework");
++MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
++MODULE_LICENSE("GPL v2");
+diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
+new file mode 100644
+index 0000000..9351a16
+--- /dev/null
++++ b/include/linux/phy/phy.h
+@@ -0,0 +1,344 @@
++/*
++ * phy.h -- generic phy header file
++ *
++ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * Author: Kishon Vijay Abraham I <kishon@ti.com>
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#ifndef __DRIVERS_PHY_H
++#define __DRIVERS_PHY_H
++
++#include <linux/err.h>
++#include <linux/of.h>
++#include <linux/device.h>
++#include <linux/pm_runtime.h>
++
++struct phy;
++
++/**
++ * struct phy_ops - set of function pointers for performing phy operations
++ * @init: operation to be performed for initializing phy
++ * @exit: operation to be performed while exiting
++ * @power_on: powering on the phy
++ * @power_off: powering off the phy
++ * @owner: the module owner containing the ops
++ */
++struct phy_ops {
++      int     (*init)(struct phy *phy);
++      int     (*exit)(struct phy *phy);
++      int     (*power_on)(struct phy *phy);
++      int     (*power_off)(struct phy *phy);
++      struct module *owner;
++};
++
++/**
++ * struct phy - represents the phy device
++ * @dev: phy device
++ * @id: id of the phy
++ * @ops: function pointers for performing phy operations
++ * @label: label given to the phy
++ * @mutex: mutex to protect phy_ops
++ * @init_count: used to protect when the PHY is used by multiple consumers
++ * @power_count: used to protect when the PHY is used by multiple consumers
++ */
++struct phy {
++      struct device           dev;
++      int                     id;
++      const struct phy_ops    *ops;
++      const char              *label;
++      struct mutex            mutex;
++      int                     init_count;
++      int                     power_count;
++};
++
++/**
++ * struct phy_provider - represents the phy provider
++ * @dev: phy provider device
++ * @owner: the module owner having of_xlate
++ * @of_xlate: function pointer to obtain phy instance from phy pointer
++ * @list: to maintain a linked list of PHY providers
++ */
++struct phy_provider {
++      struct device           *dev;
++      struct module           *owner;
++      struct list_head        list;
++      struct phy * (*of_xlate)(struct device *dev,
++              struct of_phandle_args *args);
++};
++
++#define       to_phy(dev)     (container_of((dev), struct phy, dev))
++
++#define       of_phy_provider_register(dev, xlate)    \
++      __of_phy_provider_register((dev), THIS_MODULE, (xlate))
++
++#define       devm_of_phy_provider_register(dev, xlate)       \
++      __of_phy_provider_register((dev), THIS_MODULE, (xlate))
++
++static inline void phy_set_drvdata(struct phy *phy, void *data)
++{
++      dev_set_drvdata(&phy->dev, data);
++}
++
++static inline void *phy_get_drvdata(struct phy *phy)
++{
++      return dev_get_drvdata(&phy->dev);
++}
++
++#if IS_ENABLED(CONFIG_GENERIC_PHY)
++extern struct phy *phy_get(struct device *dev, const char *string);
++extern struct phy *devm_phy_get(struct device *dev, const char *string);
++extern void phy_put(struct phy *phy);
++extern void devm_phy_put(struct device *dev, struct phy *phy);
++extern struct phy *of_phy_simple_xlate(struct device *dev,
++      struct of_phandle_args *args);
++extern struct phy *phy_create(struct device *dev, u8 id,
++      const struct phy_ops *ops, const char *label);
++extern struct phy *devm_phy_create(struct device *dev, u8 id,
++      const struct phy_ops *ops, const char *label);
++extern void phy_destroy(struct phy *phy);
++extern void devm_phy_destroy(struct device *dev, struct phy *phy);
++extern struct phy_provider *__of_phy_provider_register(struct device *dev,
++      struct module *owner, struct phy * (*of_xlate)(struct device *dev,
++      struct of_phandle_args *args));
++extern struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
++      struct module *owner, struct phy * (*of_xlate)(struct device *dev,
++      struct of_phandle_args *args));
++extern void of_phy_provider_unregister(struct phy_provider *phy_provider);
++extern void devm_of_phy_provider_unregister(struct device *dev,
++      struct phy_provider *phy_provider);
++#else
++static inline struct phy *phy_get(struct device *dev, const char *string)
++{
++      return ERR_PTR(-ENOSYS);
++}
++
++static inline struct phy *devm_phy_get(struct device *dev, const char *string)
++{
++      return ERR_PTR(-ENOSYS);
++}
++
++static inline void phy_put(struct phy *phy)
++{
++}
++
++static inline void devm_phy_put(struct device *dev, struct phy *phy)
++{
++}
++
++static inline struct phy *of_phy_simple_xlate(struct device *dev,
++      struct of_phandle_args *args)
++{
++      return ERR_PTR(-ENOSYS);
++}
++
++static inline struct phy *phy_create(struct device *dev, u8 id,
++      const struct phy_ops *ops, const char *label)
++{
++      return ERR_PTR(-ENOSYS);
++}
++
++static inline struct phy *devm_phy_create(struct device *dev, u8 id,
++      const struct phy_ops *ops, const char *label)
++{
++      return ERR_PTR(-ENOSYS);
++}
++
++static inline void phy_destroy(struct phy *phy)
++{
++}
++
++static inline void devm_phy_destroy(struct device *dev, struct phy *phy)
++{
++}
++
++static inline struct phy_provider *__of_phy_provider_register(
++      struct device *dev, struct module *owner, struct phy * (*of_xlate)(
++      struct device *dev, struct of_phandle_args *args))
++{
++      return ERR_PTR(-ENOSYS);
++}
++
++static inline struct phy_provider *__devm_of_phy_provider_register(struct device
++      *dev, struct module *owner, struct phy * (*of_xlate)(struct device *dev,
++      struct of_phandle_args *args))
++{
++      return ERR_PTR(-ENOSYS);
++}
++
++static inline void of_phy_provider_unregister(struct phy_provider *phy_provider)
++{
++}
++
++static inline void devm_of_phy_provider_unregister(struct device *dev,
++      struct phy_provider *phy_provider)
++{
++}
++#endif
++
++static inline int phy_pm_runtime_get(struct phy *phy)
++{
++      if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
++              return -EINVAL;
++
++      if (!pm_runtime_enabled(&phy->dev))
++              return -ENOTSUPP;
++
++      return pm_runtime_get(&phy->dev);
++}
++
++static inline int phy_pm_runtime_get_sync(struct phy *phy)
++{
++      if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
++              return -EINVAL;
++
++      if (!pm_runtime_enabled(&phy->dev))
++              return -ENOTSUPP;
++
++      return pm_runtime_get_sync(&phy->dev);
++}
++
++static inline int phy_pm_runtime_put(struct phy *phy)
++{
++      if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
++              return -EINVAL;
++
++      if (!pm_runtime_enabled(&phy->dev))
++              return -ENOTSUPP;
++
++      return pm_runtime_put(&phy->dev);
++}
++
++static inline int phy_pm_runtime_put_sync(struct phy *phy)
++{
++      if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
++              return -EINVAL;
++
++      if (!pm_runtime_enabled(&phy->dev))
++              return -ENOTSUPP;
++
++      return pm_runtime_put_sync(&phy->dev);
++}
++
++static inline void phy_pm_runtime_allow(struct phy *phy)
++{
++      if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
++              return;
++
++      if (!pm_runtime_enabled(&phy->dev))
++              return;
++
++      pm_runtime_allow(&phy->dev);
++}
++
++static inline void phy_pm_runtime_forbid(struct phy *phy)
++{
++      if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
++              return;
++
++      if (!pm_runtime_enabled(&phy->dev))
++              return;
++
++      pm_runtime_forbid(&phy->dev);
++}
++
++static inline int phy_init(struct phy *phy)
++{
++      int ret;
++
++      ret = phy_pm_runtime_get_sync(phy);
++      if (ret < 0 && ret != -ENOTSUPP)
++              return ret;
++
++      mutex_lock(&phy->mutex);
++      if (phy->init_count++ == 0 && phy->ops->init) {
++              ret = phy->ops->init(phy);
++              if (ret < 0) {
++                      dev_err(&phy->dev, "phy init failed --> %d\n", ret);
++                      goto out;
++              }
++      }
++
++out:
++      mutex_unlock(&phy->mutex);
++      phy_pm_runtime_put(phy);
++      return ret;
++}
++
++static inline int phy_exit(struct phy *phy)
++{
++      int ret;
++
++      ret = phy_pm_runtime_get_sync(phy);
++      if (ret < 0 && ret != -ENOTSUPP)
++              return ret;
++
++      mutex_lock(&phy->mutex);
++      if (--phy->init_count == 0 && phy->ops->exit) {
++              ret = phy->ops->exit(phy);
++              if (ret < 0) {
++                      dev_err(&phy->dev, "phy exit failed --> %d\n", ret);
++                      goto out;
++              }
++      }
++
++out:
++      mutex_unlock(&phy->mutex);
++      phy_pm_runtime_put(phy);
++      return ret;
++}
++
++static inline int phy_power_on(struct phy *phy)
++{
++      int ret = -ENOTSUPP;
++
++      ret = phy_pm_runtime_get_sync(phy);
++      if (ret < 0 && ret != -ENOTSUPP)
++              return ret;
++
++      mutex_lock(&phy->mutex);
++      if (phy->power_count++ == 0 && phy->ops->power_on) {
++              ret = phy->ops->power_on(phy);
++              if (ret < 0) {
++                      dev_err(&phy->dev, "phy poweron failed --> %d\n", ret);
++                      goto out;
++              }
++      }
++
++out:
++      mutex_unlock(&phy->mutex);
++
++      return ret;
++}
++
++static inline int phy_power_off(struct phy *phy)
++{
++      int ret = -ENOTSUPP;
++
++      mutex_lock(&phy->mutex);
++      if (--phy->power_count == 0 && phy->ops->power_off) {
++              ret =  phy->ops->power_off(phy);
++              if (ret < 0) {
++                      dev_err(&phy->dev, "phy poweroff failed --> %d\n", ret);
++                      goto out;
++              }
++      }
++
++out:
++      mutex_unlock(&phy->mutex);
++      phy_pm_runtime_put(phy);
++
++      return ret;
++}
++
++#endif /* __DRIVERS_PHY_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0288-phy-Add-driver-for-Exynos-MIPI-CSIS-DSIM-DPHYs.patch b/patches.tizen/0288-phy-Add-driver-for-Exynos-MIPI-CSIS-DSIM-DPHYs.patch
new file mode 100644 (file)
index 0000000..9d345a1
--- /dev/null
@@ -0,0 +1,255 @@
+From 8217a32bdf31227eca9453ee90caa558123d276e Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 13 Jun 2013 11:16:30 +0200
+Subject: [PATCH 0288/1302] phy: Add driver for Exynos MIPI CSIS/DSIM DPHYs
+
+Add a PHY provider driver for the Samsung S5P/Exynos SoC MIPI CSI-2
+receiver and MIPI DSI transmitter DPHYs.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Felipe Balbi <balbi@ti.com>
+---
+Changes since v3:
+ - replaced spin_(un)lock_irq_{save,restore} with spin_{lock,unlock}.
+ - DT binding file renamed to samsung-phy.txt, so it can be used for
+   other PHYs as well,
+ - removed <linux/delay.h> inclusion,
+ - added missing spin_lock_init().
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/phy/samsung-phy.txt        |  14 ++
+ drivers/phy/Kconfig                                |   9 ++
+ drivers/phy/Makefile                               |   3 +-
+ drivers/phy/phy-exynos-mipi-video.c                | 169 +++++++++++++++++++++
+ 4 files changed, 194 insertions(+), 1 deletion(-)
+ create mode 100644 Documentation/devicetree/bindings/phy/samsung-phy.txt
+ create mode 100644 drivers/phy/phy-exynos-mipi-video.c
+
+diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt
+new file mode 100644
+index 0000000..5ff208c
+--- /dev/null
++++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt
+@@ -0,0 +1,14 @@
++Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY
++-------------------------------------------------
++
++Required properties:
++- compatible : should be "samsung,s5pv210-mipi-video-phy";
++- reg : offset and length of the MIPI DPHY register set;
++- #phy-cells : from the generic phy bindings, must be 1;
++
++For "samsung,s5pv210-mipi-video-phy" compatible PHYs the second cell in
++the PHY specifier identifies the PHY and its meaning is as follows:
++  0 - MIPI CSIS 0,
++  1 - MIPI DSIM 0,
++  2 - MIPI CSIS 1,
++  3 - MIPI DSIM 1.
+diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
+index 5f85909..6f446d0 100644
+--- a/drivers/phy/Kconfig
++++ b/drivers/phy/Kconfig
+@@ -11,3 +11,12 @@ menuconfig GENERIC_PHY
+         devices present in the kernel. This layer will have the generic
+         API by which phy drivers can create PHY using the phy framework and
+         phy users can obtain reference to the PHY.
++
++if GENERIC_PHY
++
++config PHY_EXYNOS_MIPI_VIDEO
++      tristate "S5P/EXYNOS SoC series MIPI CSI-2/DSI PHY driver"
++      help
++        Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung
++        S5P and EXYNOS SoCs.
++endif
+diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
+index 9e9560f..71d8841 100644
+--- a/drivers/phy/Makefile
++++ b/drivers/phy/Makefile
+@@ -2,4 +2,5 @@
+ # Makefile for the phy drivers.
+ #
+-obj-$(CONFIG_GENERIC_PHY)     += phy-core.o
++obj-$(CONFIG_GENERIC_PHY)             += phy-core.o
++obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO)   += phy-exynos-mipi-video.o
+diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/phy-exynos-mipi-video.c
+new file mode 100644
+index 0000000..7e7fcd7
+--- /dev/null
++++ b/drivers/phy/phy-exynos-mipi-video.c
+@@ -0,0 +1,169 @@
++/*
++ * Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY driver
++ *
++ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
++ * Author: Sylwester Nawrocki <s.nawrocki@samsung.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/io.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/phy/phy.h>
++#include <linux/platform_device.h>
++#include <linux/spinlock.h>
++
++/* MIPI_PHYn_CONTROL register offset: n = 0..1 */
++#define EXYNOS_MIPI_PHY_CONTROL(n)    ((n) * 4)
++#define EXYNOS_MIPI_PHY_ENABLE                (1 << 0)
++#define EXYNOS_MIPI_PHY_SRESETN               (1 << 1)
++#define EXYNOS_MIPI_PHY_MRESETN               (1 << 2)
++#define EXYNOS_MIPI_PHY_RESET_MASK    (3 << 1)
++
++enum exynos_mipi_phy_id {
++      EXYNOS_MIPI_PHY_ID_CSIS0,
++      EXYNOS_MIPI_PHY_ID_DSIM0,
++      EXYNOS_MIPI_PHY_ID_CSIS1,
++      EXYNOS_MIPI_PHY_ID_DSIM1,
++      EXYNOS_MIPI_PHYS_NUM
++};
++
++#define IS_EXYNOS_MIPI_DSIM_PHY_ID(id) \
++      ((id) == EXYNOS_MIPI_PHY_ID_DSIM0 || (id) == EXYNOS_MIPI_PHY_ID_DSIM0)
++
++struct exynos_mipi_video_phy {
++      spinlock_t slock;
++      struct phy *phys[EXYNOS_MIPI_PHYS_NUM];
++      void __iomem *regs;
++};
++
++static int __set_phy_state(struct exynos_mipi_video_phy *state,
++                      enum exynos_mipi_phy_id id, unsigned int on)
++{
++      void __iomem *addr;
++      u32 reg, reset;
++
++      addr = state->regs + EXYNOS_MIPI_PHY_CONTROL(id / 2);
++
++      if (IS_EXYNOS_MIPI_DSIM_PHY_ID(id))
++              reset = EXYNOS_MIPI_PHY_MRESETN;
++      else
++              reset = EXYNOS_MIPI_PHY_SRESETN;
++
++      spin_lock(&state->slock);
++      reg = readl(addr);
++      if (on)
++              reg |= reset;
++      else
++              reg &= ~reset;
++      writel(reg, addr);
++
++      /* Clear ENABLE bit only if MRESETN, SRESETN bits are not set. */
++      if (on)
++              reg |= EXYNOS_MIPI_PHY_ENABLE;
++      else if (!(reg & EXYNOS_MIPI_PHY_RESET_MASK))
++              reg &= ~EXYNOS_MIPI_PHY_ENABLE;
++
++      writel(reg, addr);
++      spin_unlock(&state->slock);
++      return 0;
++}
++
++static int exynos_mipi_video_phy_power_on(struct phy *phy)
++{
++      struct exynos_mipi_video_phy *state = phy_get_drvdata(phy);
++      return __set_phy_state(state, phy->id, 1);
++}
++
++static int exynos_mipi_video_phy_power_off(struct phy *phy)
++{
++      struct exynos_mipi_video_phy *state = phy_get_drvdata(phy);
++      return __set_phy_state(state, phy->id, 0);
++}
++
++static struct phy *exynos_mipi_video_phy_xlate(struct device *dev,
++                                      struct of_phandle_args *args)
++{
++      struct exynos_mipi_video_phy *state = dev_get_drvdata(dev);
++
++      if (WARN_ON(args->args[0] > EXYNOS_MIPI_PHYS_NUM))
++              return ERR_PTR(-ENODEV);
++
++      return state->phys[args->args[0]];
++}
++
++static struct phy_ops exynos_mipi_video_phy_ops = {
++      .power_on       = exynos_mipi_video_phy_power_on,
++      .power_off      = exynos_mipi_video_phy_power_off,
++      .owner          = THIS_MODULE,
++};
++
++static int exynos_mipi_video_phy_probe(struct platform_device *pdev)
++{
++      struct exynos_mipi_video_phy *state;
++      struct device *dev = &pdev->dev;
++      struct resource *res;
++      struct phy_provider *phy_provider;
++      int i;
++
++      state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
++      if (!state)
++              return -ENOMEM;
++
++      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++
++      state->regs = devm_ioremap_resource(dev, res);
++      if (IS_ERR(state->regs))
++              return PTR_ERR(state->regs);
++
++      dev_set_drvdata(dev, state);
++      spin_lock_init(&state->slock);
++
++      phy_provider = devm_of_phy_provider_register(dev,
++                                      exynos_mipi_video_phy_xlate);
++      if (IS_ERR(phy_provider))
++              return PTR_ERR(phy_provider);
++
++      for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) {
++              char label[8];
++
++              snprintf(label, sizeof(label), "%s.%d",
++                              IS_EXYNOS_MIPI_DSIM_PHY_ID(i) ?
++                              "dsim" : "csis", i / 2);
++
++              state->phys[i] = devm_phy_create(dev, i,
++                              &exynos_mipi_video_phy_ops, label);
++              if (IS_ERR(state->phys[i])) {
++                      dev_err(dev, "failed to create PHY %s\n", label);
++                      return PTR_ERR(state->phys[i]);
++              }
++              phy_set_drvdata(state->phys[i], state);
++      }
++
++      return 0;
++}
++
++static const struct of_device_id exynos_mipi_video_phy_of_match[] = {
++      { .compatible = "samsung,s5pv210-mipi-video-phy" },
++      { },
++};
++MODULE_DEVICE_TABLE(of, exynos_mipi_video_phy_of_match);
++
++static struct platform_driver exynos_mipi_video_phy_driver = {
++      .probe  = exynos_mipi_video_phy_probe,
++      .driver = {
++              .of_match_table = exynos_mipi_video_phy_of_match,
++              .name  = "exynos-mipi-video-phy",
++              .owner = THIS_MODULE,
++      }
++};
++module_platform_driver(exynos_mipi_video_phy_driver);
++
++MODULE_DESCRIPTION("Samsung S5P/EXYNOS SoC MIPI CSI-2/DSI PHY driver");
++MODULE_LICENSE("GPL v2");
++MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0289-video-exynos_mipi_dsim-Use-the-generic-PHY-driver.patch b/patches.tizen/0289-video-exynos_mipi_dsim-Use-the-generic-PHY-driver.patch
new file mode 100644 (file)
index 0000000..bca9a07
--- /dev/null
@@ -0,0 +1,125 @@
+From 00fa61eaa4f44e01ea8745cf23fbb7debd0a9378 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 28 Jun 2013 11:21:25 +0200
+Subject: [PATCH 0289/1302] video: exynos_mipi_dsim: Use the generic PHY driver
+
+Use the generic PHY API instead of the platform callback to control
+the MIPI DSIM DPHY. The 'phy_label' field is added to the platform
+data structure to allow PHY lookup on non-dt platforms.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Felipe Balbi <balbi@ti.com>
+Acked-by: Donghwa Lee <dh09.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/video/exynos/exynos_mipi_dsi.c | 19 ++++++++++---------
+ include/video/exynos_mipi_dsim.h       |  6 ++++--
+ 2 files changed, 14 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/video/exynos/exynos_mipi_dsi.c b/drivers/video/exynos/exynos_mipi_dsi.c
+index 32e5406..248e444 100644
+--- a/drivers/video/exynos/exynos_mipi_dsi.c
++++ b/drivers/video/exynos/exynos_mipi_dsi.c
+@@ -30,6 +30,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/kthread.h>
+ #include <linux/notifier.h>
++#include <linux/phy/phy.h>
+ #include <linux/regulator/consumer.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/err.h>
+@@ -156,8 +157,7 @@ static int exynos_mipi_dsi_blank_mode(struct mipi_dsim_device *dsim, int power)
+               exynos_mipi_regulator_enable(dsim);
+               /* enable MIPI-DSI PHY. */
+-              if (dsim->pd->phy_enable)
+-                      dsim->pd->phy_enable(pdev, true);
++              phy_power_on(dsim->phy);
+               clk_enable(dsim->clock);
+@@ -373,6 +373,10 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
+               return ret;
+       }
++      dsim->phy = devm_phy_get(&pdev->dev, dsim_pd->phy_label);
++      if (IS_ERR(dsim->phy))
++              return PTR_ERR(dsim->phy);
++
+       dsim->clock = devm_clk_get(&pdev->dev, "dsim0");
+       if (IS_ERR(dsim->clock)) {
+               dev_err(&pdev->dev, "failed to get dsim clock source\n");
+@@ -439,8 +443,7 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
+       exynos_mipi_regulator_enable(dsim);
+       /* enable MIPI-DSI PHY. */
+-      if (dsim->pd->phy_enable)
+-              dsim->pd->phy_enable(pdev, true);
++      phy_power_on(dsim->phy);
+       exynos_mipi_update_cfg(dsim);
+@@ -504,9 +507,8 @@ static int exynos_mipi_dsi_suspend(struct device *dev)
+       if (client_drv && client_drv->suspend)
+               client_drv->suspend(client_dev);
+-      /* enable MIPI-DSI PHY. */
+-      if (dsim->pd->phy_enable)
+-              dsim->pd->phy_enable(pdev, false);
++      /* disable MIPI-DSI PHY. */
++      phy_power_off(dsim->phy);
+       clk_disable(dsim->clock);
+@@ -536,8 +538,7 @@ static int exynos_mipi_dsi_resume(struct device *dev)
+       exynos_mipi_regulator_enable(dsim);
+       /* enable MIPI-DSI PHY. */
+-      if (dsim->pd->phy_enable)
+-              dsim->pd->phy_enable(pdev, true);
++      phy_power_on(dsim->phy);
+       clk_enable(dsim->clock);
+diff --git a/include/video/exynos_mipi_dsim.h b/include/video/exynos_mipi_dsim.h
+index c6b1bf5..6843385 100644
+--- a/include/video/exynos_mipi_dsim.h
++++ b/include/video/exynos_mipi_dsim.h
+@@ -216,6 +216,7 @@ struct mipi_dsim_config {
+  *    automatically.
+  * @e_clk_src: select byte clock source.
+  * @pd: pointer to MIPI-DSI driver platform data.
++ * @phy: pointer to the generic PHY
+  */
+ struct mipi_dsim_device {
+       struct device                   *dev;
+@@ -236,6 +237,7 @@ struct mipi_dsim_device {
+       bool                            suspended;
+       struct mipi_dsim_platform_data  *pd;
++      struct phy                      *phy;
+ };
+ /*
+@@ -248,7 +250,7 @@ struct mipi_dsim_device {
+  * @enabled: indicate whether mipi controller got enabled or not.
+  * @lcd_panel_info: pointer for lcd panel specific structure.
+  *    this structure specifies width, height, timing and polarity and so on.
+- * @phy_enable: pointer to a callback controlling D-PHY enable/reset
++ * @phy_label: the generic PHY label
+  */
+ struct mipi_dsim_platform_data {
+       char                            lcd_panel_name[PANEL_NAME_SIZE];
+@@ -257,7 +259,7 @@ struct mipi_dsim_platform_data {
+       unsigned int                    enabled;
+       void                            *lcd_panel_info;
+-      int (*phy_enable)(struct platform_device *pdev, bool on);
++      const char                      *phy_label;
+ };
+ /*
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0290-media-exynos4-is-Use-the-generic-MIPI-CSIS-PHY-drive.patch b/patches.tizen/0290-media-exynos4-is-Use-the-generic-MIPI-CSIS-PHY-drive.patch
new file mode 100644 (file)
index 0000000..0159abc
--- /dev/null
@@ -0,0 +1,128 @@
+From fe3536f4d4e9a1b159598e31aded9fb51b063b10 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 4 Apr 2013 14:15:04 +0200
+Subject: [PATCH 0290/1302] [media] exynos4-is: Use the generic MIPI CSIS PHY
+ driver
+
+Use the generic PHY API instead of the platform callback to control
+the MIPI CSIS DPHY. The 'phy_label' field is added to the platform
+data structure to allow PHY lookup on non-dt platforms
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Felipe Balbi <balbi@ti.com>
+Acked-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/mipi-csis.c | 16 +++++++++++++---
+ include/linux/platform_data/mipi-csis.h       | 11 ++---------
+ 2 files changed, 15 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
+index 0fe80e3..c26442d 100644
+--- a/drivers/media/platform/exynos4-is/mipi-csis.c
++++ b/drivers/media/platform/exynos4-is/mipi-csis.c
+@@ -20,6 +20,7 @@
+ #include <linux/memory.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
++#include <linux/phy/phy.h>
+ #include <linux/platform_data/mipi-csis.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_runtime.h>
+@@ -184,6 +185,7 @@ struct csis_drvdata {
+  * @sd: v4l2_subdev associated with CSIS device instance
+  * @index: the hardware instance index
+  * @pdev: CSIS platform device
++ * @phy: pointer to the CSIS generic PHY
+  * @regs: mmaped I/O registers memory
+  * @supplies: CSIS regulator supplies
+  * @clock: CSIS clocks
+@@ -207,6 +209,8 @@ struct csis_state {
+       struct v4l2_subdev sd;
+       u8 index;
+       struct platform_device *pdev;
++      struct phy *phy;
++      const char *phy_label;
+       void __iomem *regs;
+       struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES];
+       struct clk *clock[NUM_CSIS_CLOCKS];
+@@ -774,6 +778,7 @@ static int s5pcsis_get_platform_data(struct platform_device *pdev,
+       state->index = max(0, pdev->id);
+       state->max_num_lanes = state->index ? CSIS1_MAX_LANES :
+                                             CSIS0_MAX_LANES;
++      state->phy_label = pdata->phy_label;
+       return 0;
+ }
+@@ -811,8 +816,9 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
+                                       "samsung,csis-wclk");
+       state->num_lanes = endpoint.bus.mipi_csi2.num_data_lanes;
+-
+       of_node_put(node);
++
++      state->phy_label = "csis";
+       return 0;
+ }
+ #else
+@@ -861,6 +867,10 @@ static int s5pcsis_probe(struct platform_device *pdev)
+               return -EINVAL;
+       }
++      state->phy = devm_phy_get(dev, state->phy_label);
++      if (IS_ERR(state->phy))
++              return PTR_ERR(state->phy);
++
+       mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       state->regs = devm_ioremap_resource(dev, mem_res);
+       if (IS_ERR(state->regs))
+@@ -946,7 +956,7 @@ static int s5pcsis_pm_suspend(struct device *dev, bool runtime)
+       mutex_lock(&state->lock);
+       if (state->flags & ST_POWERED) {
+               s5pcsis_stop_stream(state);
+-              ret = s5p_csis_phy_enable(state->index, false);
++              ret = phy_power_off(state->phy);
+               if (ret)
+                       goto unlock;
+               ret = regulator_bulk_disable(CSIS_NUM_SUPPLIES,
+@@ -982,7 +992,7 @@ static int s5pcsis_pm_resume(struct device *dev, bool runtime)
+                                           state->supplies);
+               if (ret)
+                       goto unlock;
+-              ret = s5p_csis_phy_enable(state->index, true);
++              ret = phy_power_on(state->phy);
+               if (!ret) {
+                       state->flags |= ST_POWERED;
+               } else {
+diff --git a/include/linux/platform_data/mipi-csis.h b/include/linux/platform_data/mipi-csis.h
+index bf34e17..9214317 100644
+--- a/include/linux/platform_data/mipi-csis.h
++++ b/include/linux/platform_data/mipi-csis.h
+@@ -17,21 +17,14 @@
+  * @wclk_source: CSI wrapper clock selection: 0 - bus clock, 1 - ext. SCLK_CAM
+  * @lanes:       number of data lanes used
+  * @hs_settle:   HS-RX settle time
++ * @phy_label:         the generic PHY label
+  */
+ struct s5p_platform_mipi_csis {
+       unsigned long clk_rate;
+       u8 wclk_source;
+       u8 lanes;
+       u8 hs_settle;
++      const char *phy_label;
+ };
+-/**
+- * s5p_csis_phy_enable - global MIPI-CSI receiver D-PHY control
+- * @id:     MIPI-CSIS harware instance index (0...1)
+- * @on:     true to enable D-PHY and deassert its reset
+- *          false to disable D-PHY
+- * @return: 0 on success, or negative error code on failure
+- */
+-int s5p_csis_phy_enable(int id, bool on);
+-
+ #endif /* __PLAT_SAMSUNG_MIPI_CSIS_H_ */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0291-ARM-Samsung-Remove-the-MIPI-PHY-setup-code.patch b/patches.tizen/0291-ARM-Samsung-Remove-the-MIPI-PHY-setup-code.patch
new file mode 100644 (file)
index 0000000..ef851d0
--- /dev/null
@@ -0,0 +1,154 @@
+From 5c6a6f3eec73d98beb5fc6bbc6764d6874f6a614 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 28 Jun 2013 11:24:47 +0200
+Subject: [PATCH 0291/1302] ARM: Samsung: Remove the MIPI PHY setup code
+
+Generic PHY drivers are used to handle the MIPI CSIS and MIPI DSIM
+DPHYs so we can remove now unused code at arch/arm/plat-samsung.
+In case there is any board file for S5PV210 platforms using MIPI
+CSIS/DSIM (not any upstream currently) it should use the generic
+PHY API to bind the PHYs to respective PHY consumer drivers and
+a platform device for the PHY provider should be defined.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Felipe Balbi <balbi@ti.com>
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/mach-exynos/include/mach/regs-pmu.h    |  5 ---
+ arch/arm/mach-s5pv210/include/mach/regs-clock.h |  4 --
+ arch/arm/plat-samsung/Kconfig                   |  5 ---
+ arch/arm/plat-samsung/Makefile                  |  1 -
+ arch/arm/plat-samsung/setup-mipiphy.c           | 60 -------------------------
+ 5 files changed, 75 deletions(-)
+ delete mode 100644 arch/arm/plat-samsung/setup-mipiphy.c
+
+diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu.h b/arch/arm/mach-exynos/include/mach/regs-pmu.h
+index cf40b86..3820e39 100644
+--- a/arch/arm/mach-exynos/include/mach/regs-pmu.h
++++ b/arch/arm/mach-exynos/include/mach/regs-pmu.h
+@@ -44,11 +44,6 @@
+ #define S5P_DAC_PHY_CONTROL                   S5P_PMUREG(0x070C)
+ #define S5P_DAC_PHY_ENABLE                    (1 << 0)
+-#define S5P_MIPI_DPHY_CONTROL(n)              S5P_PMUREG(0x0710 + (n) * 4)
+-#define S5P_MIPI_DPHY_ENABLE                  (1 << 0)
+-#define S5P_MIPI_DPHY_SRESETN                 (1 << 1)
+-#define S5P_MIPI_DPHY_MRESETN                 (1 << 2)
+-
+ #define S5P_INFORM0                           S5P_PMUREG(0x0800)
+ #define S5P_INFORM1                           S5P_PMUREG(0x0804)
+ #define S5P_INFORM2                           S5P_PMUREG(0x0808)
+diff --git a/arch/arm/mach-s5pv210/include/mach/regs-clock.h b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
+index 032de66..e345584 100644
+--- a/arch/arm/mach-s5pv210/include/mach/regs-clock.h
++++ b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
+@@ -147,10 +147,6 @@
+ #define S5P_HDMI_PHY_CONTROL  S5P_CLKREG(0xE804)
+ #define S5P_USB_PHY_CONTROL   S5P_CLKREG(0xE80C)
+ #define S5P_DAC_PHY_CONTROL   S5P_CLKREG(0xE810)
+-#define S5P_MIPI_DPHY_CONTROL(x) S5P_CLKREG(0xE814)
+-#define S5P_MIPI_DPHY_ENABLE  (1 << 0)
+-#define S5P_MIPI_DPHY_SRESETN (1 << 1)
+-#define S5P_MIPI_DPHY_MRESETN (1 << 2)
+ #define S5P_INFORM0           S5P_CLKREG(0xF000)
+ #define S5P_INFORM1           S5P_CLKREG(0xF004)
+diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
+index a072524..0498729 100644
+--- a/arch/arm/plat-samsung/Kconfig
++++ b/arch/arm/plat-samsung/Kconfig
+@@ -396,11 +396,6 @@ config S3C24XX_PWM
+         Support for exporting the PWM timer blocks via the pwm device
+         system
+-config S5P_SETUP_MIPIPHY
+-      bool
+-      help
+-        Compile in common setup code for MIPI-CSIS and MIPI-DSIM devices
+-
+ config S3C_SETUP_CAMIF
+       bool
+       help
+diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
+index a23c460..5a15fae 100644
+--- a/arch/arm/plat-samsung/Makefile
++++ b/arch/arm/plat-samsung/Makefile
+@@ -41,7 +41,6 @@ obj-$(CONFIG_S5P_DEV_UART)   += s5p-dev-uart.o
+ obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT)   += dev-backlight.o
+ obj-$(CONFIG_S3C_SETUP_CAMIF) += setup-camif.o
+-obj-$(CONFIG_S5P_SETUP_MIPIPHY)       += setup-mipiphy.o
+ # DMA support
+diff --git a/arch/arm/plat-samsung/setup-mipiphy.c b/arch/arm/plat-samsung/setup-mipiphy.c
+deleted file mode 100644
+index 66df315..0000000
+--- a/arch/arm/plat-samsung/setup-mipiphy.c
++++ /dev/null
+@@ -1,60 +0,0 @@
+-/*
+- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+- *
+- * S5P - Helper functions for MIPI-CSIS and MIPI-DSIM D-PHY control
+- *
+- * 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/export.h>
+-#include <linux/kernel.h>
+-#include <linux/platform_device.h>
+-#include <linux/io.h>
+-#include <linux/spinlock.h>
+-#include <mach/regs-clock.h>
+-
+-static int __s5p_mipi_phy_control(int id, bool on, u32 reset)
+-{
+-      static DEFINE_SPINLOCK(lock);
+-      void __iomem *addr;
+-      unsigned long flags;
+-      u32 cfg;
+-
+-      id = max(0, id);
+-      if (id > 1)
+-              return -EINVAL;
+-
+-      addr = S5P_MIPI_DPHY_CONTROL(id);
+-
+-      spin_lock_irqsave(&lock, flags);
+-
+-      cfg = __raw_readl(addr);
+-      cfg = on ? (cfg | reset) : (cfg & ~reset);
+-      __raw_writel(cfg, addr);
+-
+-      if (on) {
+-              cfg |= S5P_MIPI_DPHY_ENABLE;
+-      } else if (!(cfg & (S5P_MIPI_DPHY_SRESETN |
+-                          S5P_MIPI_DPHY_MRESETN) & ~reset)) {
+-              cfg &= ~S5P_MIPI_DPHY_ENABLE;
+-      }
+-
+-      __raw_writel(cfg, addr);
+-      spin_unlock_irqrestore(&lock, flags);
+-
+-      return 0;
+-}
+-
+-int s5p_csis_phy_enable(int id, bool on)
+-{
+-      return __s5p_mipi_phy_control(id, on, S5P_MIPI_DPHY_SRESETN);
+-}
+-EXPORT_SYMBOL(s5p_csis_phy_enable);
+-
+-int s5p_dsim_phy_enable(struct platform_device *pdev, bool on)
+-{
+-      return __s5p_mipi_phy_control(pdev->id, on, S5P_MIPI_DPHY_MRESETN);
+-}
+-EXPORT_SYMBOL(s5p_dsim_phy_enable);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0292-video-exynos_dsi-Use-generic-PHY-driver.patch b/patches.tizen/0292-video-exynos_dsi-Use-generic-PHY-driver.patch
new file mode 100644 (file)
index 0000000..4c23a20
--- /dev/null
@@ -0,0 +1,150 @@
+From 5b001c3db677377ac29af48892ecaffab7336db4 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 4 Apr 2013 14:13:51 +0200
+Subject: [PATCH 0292/1302] video: exynos_dsi: Use generic PHY driver
+
+Use the generic PHY API instead of the platform callback to control
+the MIPI DSIM DPHY.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/video/display/source-exynos_dsi.c | 36 ++++++++++---------------------
+ include/video/exynos_dsi.h                |  5 -----
+ 2 files changed, 11 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/video/display/source-exynos_dsi.c b/drivers/video/display/source-exynos_dsi.c
+index d7094f4..d36162f 100644
+--- a/drivers/video/display/source-exynos_dsi.c
++++ b/drivers/video/display/source-exynos_dsi.c
+@@ -24,6 +24,7 @@
+ #include <linux/mm.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
++#include <linux/phy/phy.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/regulator/consumer.h>
+@@ -219,6 +220,7 @@ struct exynos_dsi {
+       bool enabled;
+       struct platform_device *pdev;
++      struct phy *phy;
+       struct device *dev;
+       struct resource *res;
+       struct clk *pll_clk;
+@@ -816,6 +818,7 @@ again:
+ static bool exynos_dsi_transfer_finish(struct exynos_dsi *dsi)
+ {
++      static unsigned long j;
+       struct exynos_dsi_transfer *xfer;
+       unsigned long flags;
+       bool start = true;
+@@ -824,7 +827,8 @@ static bool exynos_dsi_transfer_finish(struct exynos_dsi *dsi)
+       if (list_empty(&dsi->transfer_list)) {
+               spin_unlock_irqrestore(&dsi->transfer_lock, flags);
+-              dev_warn(dsi->dev, "unexpected TX/RX interrupt\n");
++              if (printk_timed_ratelimit(&j, 500))
++                      dev_warn(dsi->dev, "unexpected TX/RX interrupt\n");
+               return false;
+       }
+@@ -996,8 +1000,7 @@ static int exynos_dsi_enable(struct video_source *src)
+       clk_prepare_enable(dsi->bus_clk);
+       clk_prepare_enable(dsi->pll_clk);
+-      if (dsi->pd->phy_enable)
+-              dsi->pd->phy_enable(dsi->pdev, true);
++      phy_power_on(dsi->phy);
+       exynos_dsi_reset(dsi);
+       exynos_dsi_init_link(dsi);
+@@ -1022,8 +1025,7 @@ static int exynos_dsi_disable(struct video_source *src)
+       exynos_dsi_disable_clock(dsi);
+-      if (dsi->pd->phy_enable)
+-              dsi->pd->phy_enable(dsi->pdev, false);
++      phy_power_off(dsi->phy);
+       clk_disable_unprepare(dsi->pll_clk);
+       clk_disable_unprepare(dsi->bus_clk);
+@@ -1104,12 +1106,6 @@ static const struct dsi_video_source_ops exynos_dsi_ops = {
+  * Device Tree
+  */
+-static int (* const of_phy_enables[])(struct platform_device *, bool) = {
+-#ifdef CONFIG_S5P_SETUP_MIPIPHY
+-      [0] = s5p_dsim_phy_enable,
+-#endif
+-};
+-
+ static struct exynos_dsi_platform_data *exynos_dsi_parse_dt(
+                                               struct platform_device *pdev)
+ {
+@@ -1117,7 +1113,6 @@ static struct exynos_dsi_platform_data *exynos_dsi_parse_dt(
+       struct exynos_dsi_platform_data *dsi_pd;
+       struct device *dev = &pdev->dev;
+       const __be32 *prop_data;
+-      u32 val;
+       dsi_pd = kzalloc(sizeof(*dsi_pd), GFP_KERNEL);
+       if (!dsi_pd) {
+@@ -1125,19 +1120,6 @@ static struct exynos_dsi_platform_data *exynos_dsi_parse_dt(
+               return NULL;
+       }
+-      prop_data = of_get_property(node, "samsung,phy-type", NULL);
+-      if (!prop_data) {
+-              dev_err(dev, "failed to get phy-type property\n");
+-              goto err_free_pd;
+-      }
+-
+-      val = be32_to_cpu(*prop_data);
+-      if (val >= ARRAY_SIZE(of_phy_enables) || !of_phy_enables[val]) {
+-              dev_err(dev, "Invalid phy-type %u\n", val);
+-              goto err_free_pd;
+-      }
+-      dsi_pd->phy_enable = of_phy_enables[val];
+-
+       prop_data = of_get_property(node, "samsung,pll-stable-time", NULL);
+       if (!prop_data) {
+               dev_err(dev, "failed to get pll-stable-time property\n");
+@@ -1259,6 +1241,10 @@ static int exynos_dsi_probe(struct platform_device *pdev)
+               return -ENOMEM;
+       }
++      dsi->phy = devm_phy_get(&pdev->dev, "dsim");
++      if (IS_ERR(dsi->phy))
++              return PTR_ERR(dsi->phy);
++
+       platform_set_drvdata(pdev, dsi);
+       dsi->irq = platform_get_irq(pdev, 0);
+diff --git a/include/video/exynos_dsi.h b/include/video/exynos_dsi.h
+index 95e1568..5c062c7 100644
+--- a/include/video/exynos_dsi.h
++++ b/include/video/exynos_dsi.h
+@@ -25,9 +25,6 @@
+  */
+ struct exynos_dsi_platform_data {
+       unsigned int enabled;
+-
+-      int (*phy_enable)(struct platform_device *pdev, bool on);
+-
+       unsigned int pll_stable_time;
+       unsigned long pll_clk_rate;
+       unsigned long esc_clk_rate;
+@@ -36,6 +33,4 @@ struct exynos_dsi_platform_data {
+       unsigned short rx_timeout;
+ };
+-int s5p_dsim_phy_enable(struct platform_device *pdev, bool on);
+-
+ #endif /* _EXYNOS_MIPI_DSIM_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0293-tizen_defconfig-update.patch b/patches.tizen/0293-tizen_defconfig-update.patch
new file mode 100644 (file)
index 0000000..327cdda
--- /dev/null
@@ -0,0 +1,37 @@
+From 87a8fe90fe846fd90e8b3e3c76e27d43bbd17ef9 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 21 Jun 2013 14:07:07 +0200
+Subject: [PATCH 0293/1302] tizen_defconfig update
+
+Enable MIPI CSI-2/DSIM PHY driver and geenric PHY framework.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_defconfig | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index 0ab7ac0..fd97c41 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -318,7 +318,6 @@ CONFIG_S3C_GPIO_TRACK=y
+ CONFIG_S3C_ADC=y
+ CONFIG_S5P_DEV_MFC=y
+ CONFIG_S3C24XX_PWM=y
+-CONFIG_S5P_SETUP_MIPIPHY=y
+ CONFIG_SAMSUNG_DMADEV=y
+ #
+@@ -2923,6 +2922,8 @@ CONFIG_ARM_GIC=y
+ CONFIG_GIC_NON_BANKED=y
+ # CONFIG_IPACK_BUS is not set
+ # CONFIG_RESET_CONTROLLER is not set
++CONFIG_GENERIC_PHY=y
++CONFIG_PHY_EXYNOS_MIPI_DSIM_CSIS=y
+ #
+ # File systems
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0294-clk-honor-CLK_GET_RATE_NOCACHE-in-clk_set_rate.patch b/patches.tizen/0294-clk-honor-CLK_GET_RATE_NOCACHE-in-clk_set_rate.patch
new file mode 100644 (file)
index 0000000..5dbc4f3
--- /dev/null
@@ -0,0 +1,32 @@
+From 1ade7d7b023532f12986667b933d8a085cda5a30 Mon Sep 17 00:00:00 2001
+From: Peter De Schrijver <pdeschrijver@nvidia.com>
+Date: Wed, 5 Jun 2013 18:06:36 +0300
+Subject: [PATCH 0294/1302] clk: honor CLK_GET_RATE_NOCACHE in clk_set_rate
+
+clk_set_rate() uses clk->rate directly. This causes problems if the clock
+is marked as CLK_GET_RATE_NOCACHE. Hence call clk_get_rate() to get the
+current rate.
+
+Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>
+Signed-off-by: Mike Turquette <mturquette@linaro.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/clk.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
+index 8d790a8..5b39cda 100644
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -1219,7 +1219,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
+       clk_prepare_lock();
+       /* bail early if nothing to do */
+-      if (rate == clk->rate)
++      if (rate == clk_get_rate(clk))
+               goto out;
+       if ((clk->flags & CLK_SET_RATE_GATE) && clk->prepare_count) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0295-ARM-dts-Add-missing-I2C-controller-node-alias-for-GP.patch b/patches.tizen/0295-ARM-dts-Add-missing-I2C-controller-node-alias-for-GP.patch
new file mode 100644 (file)
index 0000000..66f9525
--- /dev/null
@@ -0,0 +1,39 @@
+From 50b01f59c5c2805d6153463a6c8c0a0694edfd1e Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Mon, 24 Jun 2013 18:56:55 +0200
+Subject: [PATCH 0295/1302] ARM: dts: Add missing I2C controller node alias for
+ GP2AP020A00F sensor
+
+Without this alias probing of the I2C0 adapter was failing as the
+'i2c-gpio-2' i2c-gpio adapter was getting I2C bus id 0 assigned to it.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index c5ed477..85b3b7e 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -24,6 +24,7 @@
+               i2c9 = &i2c_lps331ap;
+               i2c10 = &i2c_if_pmic;
+               i2c11 = &i2c_fuel;
++              i2c12 = &i2c_gp2ap020a00f;
+       };
+       memory {
+@@ -197,7 +198,7 @@
+               };
+       };
+-      i2c-gpio-2 {
++      i2c_gp2ap020a00f: i2c-gpio-2 {
+               compatible = "i2c-gpio";
+               gpios = <&gpk1 1 0>, <&gpk2 2 0>;
+               i2c-gpio,delay-us = <2>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0296-mmc-sdhci-s3c-revert-fix-missing-clock-for-gpio-card.patch b/patches.tizen/0296-mmc-sdhci-s3c-revert-fix-missing-clock-for-gpio-card.patch
new file mode 100644 (file)
index 0000000..5ec9f16
--- /dev/null
@@ -0,0 +1,50 @@
+From 65c167ddae2d43d2f9e24d5dfeb045b7604c5caa Mon Sep 17 00:00:00 2001
+From: Jaehoon Chung <jh80.chung@samsung.com>
+Date: Tue, 25 Jun 2013 10:27:53 +0900
+Subject: [PATCH 0296/1302] mmc: sdhci-s3c: revert "fix missing clock for gpio
+ card-detect"
+
+It's produced the clk-disable counting warning.
+(the pair is not right)
+
+Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mmc/host/sdhci-s3c.c | 9 ---------
+ 1 file changed, 9 deletions(-)
+
+diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
+index c6f6246..504f5c3 100644
+--- a/drivers/mmc/host/sdhci-s3c.c
++++ b/drivers/mmc/host/sdhci-s3c.c
+@@ -370,27 +370,18 @@ static struct sdhci_ops sdhci_s3c_ops = {
+ static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
+ {
+       struct sdhci_host *host = platform_get_drvdata(dev);
+-#ifdef CONFIG_PM_RUNTIME
+-      struct sdhci_s3c *sc = sdhci_priv(host);
+-#endif
+       unsigned long flags;
+       if (host) {
+               spin_lock_irqsave(&host->lock, flags);
+               if (state) {
+                       dev_dbg(&dev->dev, "card inserted.\n");
+-#ifdef CONFIG_PM_RUNTIME
+-                      clk_prepare_enable(sc->clk_io);
+-#endif
+                       host->flags &= ~SDHCI_DEVICE_DEAD;
+                       host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
+               } else {
+                       dev_dbg(&dev->dev, "card removed.\n");
+                       host->flags |= SDHCI_DEVICE_DEAD;
+                       host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
+-#ifdef CONFIG_PM_RUNTIME
+-                      clk_disable_unprepare(sc->clk_io);
+-#endif
+               }
+               tasklet_schedule(&host->card_tasklet);
+               spin_unlock_irqrestore(&host->lock, flags);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0297-ARM-dts-Remove-redundant-sysreg-node-from-exynos4.dt.patch b/patches.tizen/0297-ARM-dts-Remove-redundant-sysreg-node-from-exynos4.dt.patch
new file mode 100644 (file)
index 0000000..af55117
--- /dev/null
@@ -0,0 +1,34 @@
+From 07cdf3292ef20771bf6b9c3f640a6cf6758d4ec2 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Tue, 25 Jun 2013 20:23:35 +0200
+Subject: [PATCH 0297/1302] ARM: dts: Remove redundant sysreg node from
+ exynos4.dtsi
+
+Remove the incorrect sysreg node, which is likely in this file
+due to wrong merge conflict resolution.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi | 5 -----
+ 1 file changed, 5 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index 2f2a5f4..7620fce 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -115,11 +115,6 @@
+               arm,tag-latency = <1 1 0>;
+       };
+-      sys_reg: sysreg {
+-              compatible = "exynos4-sysreg", "syscon";
+-              reg = <0x10010000 0x400>;
+-      };
+-
+       mipi_phy: video-phy@10020710 {
+               compatible = "samsung,s5pv210-mipi-video-phy";
+               reg = <0x10020710 8>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0298-mmc-sdhci-s3c-remove-the-duplicated-calling-sequence.patch b/patches.tizen/0298-mmc-sdhci-s3c-remove-the-duplicated-calling-sequence.patch
new file mode 100644 (file)
index 0000000..66d2213
--- /dev/null
@@ -0,0 +1,60 @@
+From 0689006d342df007b5b38eda3fc9a5712d833241 Mon Sep 17 00:00:00 2001
+From: Jaehoon Chung <jh80.chung@samsung.com>
+Date: Thu, 27 Jun 2013 11:29:47 +0900
+Subject: [PATCH 0298/1302] mmc: sdhci-s3c: remove the duplicated calling
+ sequence
+
+Didn't need to call the sdhci_s3c_notify_change in
+setup_card_detect_gpio()
+
+Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mmc/host/sdhci-s3c.c | 27 +++++++++++++--------------
+ 1 file changed, 13 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
+index 504f5c3..1b6485f 100644
+--- a/drivers/mmc/host/sdhci-s3c.c
++++ b/drivers/mmc/host/sdhci-s3c.c
+@@ -402,24 +402,23 @@ static void sdhci_s3c_setup_card_detect_gpio(struct sdhci_s3c *sc)
+ {
+       struct s3c_sdhci_platdata *pdata = sc->pdata;
+       struct device *dev = &sc->pdev->dev;
++      int ret = 0;
+       if (devm_gpio_request(dev, pdata->ext_cd_gpio, "SDHCI EXT CD") == 0) {
+               sc->ext_cd_gpio = pdata->ext_cd_gpio;
+               sc->ext_cd_irq = gpio_to_irq(pdata->ext_cd_gpio);
+-              if (sc->ext_cd_irq &&
+-                  request_threaded_irq(sc->ext_cd_irq, NULL,
+-                                       sdhci_s3c_gpio_card_detect_thread,
+-                                       IRQF_TRIGGER_RISING |
+-                                       IRQF_TRIGGER_FALLING |
+-                                       IRQF_ONESHOT,
+-                                       dev_name(dev), sc) == 0) {
+-                      int status = gpio_get_value(sc->ext_cd_gpio);
+-                      if (pdata->ext_cd_gpio_invert)
+-                              status = !status;
+-                      sdhci_s3c_notify_change(sc->pdev, status);
+-              } else {
+-                      dev_warn(dev, "cannot request irq for card detect\n");
+-                      sc->ext_cd_irq = 0;
++              if (sc->ext_cd_irq) {
++                      ret = request_threaded_irq(sc->ext_cd_irq, NULL,
++                                      sdhci_s3c_gpio_card_detect_thread,
++                                      IRQF_TRIGGER_RISING |
++                                      IRQF_TRIGGER_FALLING |
++                                      IRQF_ONESHOT,
++                                      dev_name(dev), sc);
++                      if (ret) {
++                              dev_warn(dev,
++                                      "cannot request irq for card detect\n");
++                              sc->ext_cd_irq = 0;
++                      }
+               }
+       } else {
+               dev_err(dev, "cannot request gpio for card detect\n");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0299-exynos4-is-Handle-suspend-resume-of-fimc-is-i2c-corr.patch b/patches.tizen/0299-exynos4-is-Handle-suspend-resume-of-fimc-is-i2c-corr.patch
new file mode 100644 (file)
index 0000000..8072390
--- /dev/null
@@ -0,0 +1,77 @@
+From 7eab02689586a62d1f7cfffbb95f1224bb0a489d Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 26 Jun 2013 15:37:14 +0200
+Subject: [PATCH 0299/1302] exynos4-is: Handle suspend/resume of fimc-is-i2c
+ correctly
+
+If the same callbacks are used for runtime and system suspend/resume,
+clocks can get disabled twice, which can lead to negative reference
+counts and kernel warnings.
+
+This patch splits suspend/resume callbacks into separate runtime and
+system-wide functions, so clock gating is done correctly.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-is-i2c.c | 33 ++++++++++++++++++++++---
+ 1 file changed, 29 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-is-i2c.c b/drivers/media/platform/exynos4-is/fimc-is-i2c.c
+index 617a798..6bc481a 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is-i2c.c
++++ b/drivers/media/platform/exynos4-is/fimc-is-i2c.c
+@@ -83,21 +83,46 @@ static int fimc_is_i2c_remove(struct platform_device *pdev)
+       return 0;
+ }
+-static int fimc_is_i2c_suspend(struct device *dev)
++#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP)
++static int fimc_is_i2c_runtime_suspend(struct device *dev)
+ {
+       struct fimc_is_i2c *isp_i2c = dev_get_drvdata(dev);
++
+       clk_disable_unprepare(isp_i2c->clock);
+       return 0;
+ }
+-static int fimc_is_i2c_resume(struct device *dev)
++static int fimc_is_i2c_runtime_resume(struct device *dev)
+ {
+       struct fimc_is_i2c *isp_i2c = dev_get_drvdata(dev);
++
+       return clk_prepare_enable(isp_i2c->clock);
+ }
++#endif
+-static UNIVERSAL_DEV_PM_OPS(fimc_is_i2c_pm_ops, fimc_is_i2c_suspend,
+-                   fimc_is_i2c_resume, NULL);
++#ifdef CONFIG_PM_SLEEP
++static int fimc_is_i2c_suspend(struct device *dev)
++{
++      if (pm_runtime_suspended(dev))
++              return 0;
++
++      return fimc_is_i2c_runtime_suspend(dev);
++}
++
++static int fimc_is_i2c_resume(struct device *dev)
++{
++      if (pm_runtime_suspended(dev))
++              return 0;
++
++      return fimc_is_i2c_runtime_resume(dev);
++}
++#endif
++
++static struct dev_pm_ops fimc_is_i2c_pm_ops = {
++      SET_RUNTIME_PM_OPS(fimc_is_i2c_runtime_suspend,
++                                      fimc_is_i2c_runtime_resume, NULL)
++      SET_SYSTEM_SLEEP_PM_OPS(fimc_is_i2c_suspend, fimc_is_i2c_resume)
++};
+ static const struct of_device_id fimc_is_i2c_of_match[] = {
+       { .compatible = FIMC_IS_I2C_COMPATIBLE },
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0300-exynos4-is-Ungate-uart-clocks-on-system-suspend.patch b/patches.tizen/0300-exynos4-is-Ungate-uart-clocks-on-system-suspend.patch
new file mode 100644 (file)
index 0000000..51cdb96
--- /dev/null
@@ -0,0 +1,78 @@
+From 9f8ea90494a724e8a2cb93b25cad03d801ff42c1 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 26 Jun 2013 15:42:14 +0200
+Subject: [PATCH 0300/1302] exynos4-is: Ungate uart clocks on system suspend
+
+Due to hardware requirements, several ISP clocks must be enabled when
+suspending the system. This patch adds ungating to suspend and
+gating to resume callbacks to keep such clocks ungated.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-is.c | 22 ++++++++++++++++++++++
+ drivers/media/platform/exynos4-is/fimc-is.h |  3 ++-
+ 2 files changed, 24 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c
+index 37dac12..0b641b5 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is.c
++++ b/drivers/media/platform/exynos4-is/fimc-is.c
+@@ -905,17 +905,39 @@ static int fimc_is_runtime_suspend(struct device *dev)
+ static int fimc_is_resume(struct device *dev)
+ {
+       /* TODO: */
++      struct fimc_is *is = dev_get_drvdata(dev);
++      int i;
++
++      for (i = ISS_GATE_CLKS_SUSPEND; i < ISS_GATE_CLKS_MAX; i++)
++              if (!IS_ERR(is->clocks[i]))
++                      clk_disable_unprepare(is->clocks[i]);
++
+       return 0;
+ }
+ static int fimc_is_suspend(struct device *dev)
+ {
+       struct fimc_is *is = dev_get_drvdata(dev);
++      int i, ret;
+       /* TODO: */
+       if (test_bit(IS_ST_A5_PWR_ON, &is->state))
+               return -EBUSY;
++      for (i = ISS_GATE_CLKS_SUSPEND; i < ISS_GATE_CLKS_MAX; i++) {
++              if (IS_ERR(is->clocks[i]))
++                      continue;
++
++              ret = clk_prepare_enable(is->clocks[i]);
++              if (ret < 0) {
++                      dev_err(&is->pdev->dev, "clock %s enable failed\n",
++                                                      fimc_is_clocks[i]);
++                      for (--i; i >= ISS_GATE_CLKS_SUSPEND; i--)
++                              clk_disable_unprepare(is->clocks[i]);
++                      return ret;
++              }
++      }
++
+       return 0;
+ }
+ #endif /* CONFIG_PM_SLEEP */
+diff --git a/drivers/media/platform/exynos4-is/fimc-is.h b/drivers/media/platform/exynos4-is/fimc-is.h
+index 1a97e09..fc6d1130 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is.h
++++ b/drivers/media/platform/exynos4-is/fimc-is.h
+@@ -77,7 +77,8 @@ enum {
+       ISS_CLK_DRC,
+       ISS_CLK_FD,
+       ISS_CLK_MCUISP,
+-      ISS_CLK_UART,
++      ISS_GATE_CLKS_SUSPEND,
++      ISS_CLK_UART = ISS_GATE_CLKS_SUSPEND,
+       ISS_GATE_CLKS_MAX,
+       ISS_CLK_ISP_DIV0 = ISS_GATE_CLKS_MAX,
+       ISS_CLK_ISP_DIV1,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0301-ARM-dts-exynos4210-origen-Add-device-nodes-for-USB-g.patch b/patches.tizen/0301-ARM-dts-exynos4210-origen-Add-device-nodes-for-USB-g.patch
new file mode 100644 (file)
index 0000000..5046a13
--- /dev/null
@@ -0,0 +1,41 @@
+From 10deeacad18b598b6fa8e72e8e3a96514924348c Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 7 Mar 2013 15:36:40 +0100
+Subject: [PATCH 0301/1302] ARM: dts: exynos4210-origen: Add device nodes for
+ USB gadget
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-origen.dts | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts
+index ab598e9..700ddea 100644
+--- a/arch/arm/boot/dts/exynos4210-origen.dts
++++ b/arch/arm/boot/dts/exynos4210-origen.dts
+@@ -164,4 +164,21 @@
+                       clock-frequency = <24000000>;
+               };
+       };
++
++      vusb_reg: voltage-regulator-1 {
++              compatible = "regulator-fixed";
++              regulator-name = "VUSB_DUMMY";
++              regulator-min-microvolt = <3300000>;
++              regulator-max-microvolt = <3300000>;
++      };
++
++      usbphy@125B0000 {
++              status = "okay";
++      };
++
++      hsotg@12480000 {
++              status = "okay";
++              vusb_d-supply = <&vusb_reg>;
++              vusb_a-supply = <&vusb_reg>;
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0302-ARM-dts-exynos4-Add-node-for-EHCI.patch b/patches.tizen/0302-ARM-dts-exynos4-Add-node-for-EHCI.patch
new file mode 100644 (file)
index 0000000..18e9147
--- /dev/null
@@ -0,0 +1,34 @@
+From 7c303812b35c01487d77ce4beaac91fdbee78e9a Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 8 Mar 2013 18:12:43 +0100
+Subject: [PATCH 0302/1302] ARM: dts: exynos4: Add node for EHCI
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index 7620fce..d8525ec 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -500,6 +500,15 @@
+               status = "disabled";
+       };
++      ehci@12580000 {
++              compatible = "samsung,exynos-ehci";
++              reg = <0x12580000 0x20000>;
++              interrupts = <0 70 0>;
++              clocks = <&clock 304>;
++              clock-names = "usbhost";
++              status = "disabled";
++      };
++
+       i2s0: i2s@03830000 {
+               compatible = "samsung,i2s-v5";
+               reg = <0x03830000 0x100>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0303-HACK-ARM-dts-exynos4412-slp_pq-Keep-HSIC-regulators-.patch b/patches.tizen/0303-HACK-ARM-dts-exynos4412-slp_pq-Keep-HSIC-regulators-.patch
new file mode 100644 (file)
index 0000000..5021f15
--- /dev/null
@@ -0,0 +1,38 @@
+From e178f59e60e820ba195ee959e3bf3a0d27623fa7 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 8 Mar 2013 18:13:08 +0100
+Subject: [PATCH 0303/1302] [HACK] ARM: dts: exynos4412-slp_pq: Keep HSIC
+ regulators always on
+
+This is needed because the s5p-ehci driver does not control voltage
+regulators.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 85b3b7e..b7783cb 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -487,6 +487,7 @@
+                                       regulator-name = "VHSIC_1.0V";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
+                               };
+                               ldo16_reg: ldo@16 {
+@@ -494,6 +495,7 @@
+                                       regulator-name = "VHSIC_1.8V";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
+                               };
+                               ldo17_reg: ldo@17 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0304-ARM-dts-exynos4412-slp_pq-Enable-EHCI-controller.patch b/patches.tizen/0304-ARM-dts-exynos4412-slp_pq-Enable-EHCI-controller.patch
new file mode 100644 (file)
index 0000000..f17c012
--- /dev/null
@@ -0,0 +1,29 @@
+From 812a96a3c3b916301c7ae11020e9db75c315c3fc Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 8 Mar 2013 18:13:58 +0100
+Subject: [PATCH 0304/1302] ARM: dts: exynos4412-slp_pq: Enable EHCI controller
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index b7783cb..a9df9c6 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -831,6 +831,10 @@
+               vusb_a-supply = <&ldo12_reg>;
+       };
++      ehci@12580000 {
++              status = "okay";
++      };
++
+       spi_1: spi@13930000 {
+               pinctrl-names = "default";
+               pinctrl-0 = <&spi1_bus>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0305-ARM-dts-exynos4x12-Extend-usbphy-reg-property-to-cov.patch b/patches.tizen/0305-ARM-dts-exynos4x12-Extend-usbphy-reg-property-to-cov.patch
new file mode 100644 (file)
index 0000000..2ef84f7
--- /dev/null
@@ -0,0 +1,28 @@
+From 646f42ecfd19a10e2b13580b916546e74860d522 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 8 Mar 2013 18:14:17 +0100
+Subject: [PATCH 0305/1302] ARM: dts: exynos4x12: Extend usbphy reg property to
+ cover HSIC registers
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index be4adc2..b336bd5 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -194,7 +194,7 @@
+               status = "disabled";
+               usbphy-sys {
+-                      reg = <0x10020704 0x8>, <0x1001021C 0x4>;
++                      reg = <0x10020704 0x0c>;
+               };
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0306-ARM-DTS-exynos4210-origen-Add-MAX8997-node-entry.patch b/patches.tizen/0306-ARM-DTS-exynos4210-origen-Add-MAX8997-node-entry.patch
new file mode 100644 (file)
index 0000000..370c4cd
--- /dev/null
@@ -0,0 +1,176 @@
+From 1dfbd451cc08d6668fbb9b8a7db9c6450be29abc Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 13 Mar 2013 20:07:50 +0100
+Subject: [PATCH 0306/1302] ARM: DTS: exynos4210-origen: Add MAX8997 node entry
+
+The node entry is added as per documentation and legacy board file.
+
+Signed-off-by: Tushar Behera <tushar.behera@linaro.org>
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-origen.dts | 150 ++++++++++++++++++++++++++++++++
+ 1 file changed, 150 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts
+index 700ddea..c28a4ad 100644
+--- a/arch/arm/boot/dts/exynos4210-origen.dts
++++ b/arch/arm/boot/dts/exynos4210-origen.dts
+@@ -181,4 +181,154 @@
+               vusb_d-supply = <&vusb_reg>;
+               vusb_a-supply = <&vusb_reg>;
+       };
++
++      i2c@13860000 {
++              #address-cells = <1>;
++              #size-cells = <0>;
++              samsung,i2c-sda-delay = <100>;
++              samsung,i2c-max-bus-freq = <100000>;
++              pinctrl-0 = <&i2c0_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              max8997_pmic@66 {
++                      compatible = "maxim,max8997-pmic";
++                      reg = <0x66>;
++                      interrupt-parent = <&gpx0>;
++                      interrupts = <4 0>, <3 0>;
++
++                      max8997,pmic-ignore-gpiodvs-side-effect;
++                      max8997,pmic-buck125-default-dvs-idx = <0>;
++                      max8997,pmic-buck125-dvs-gpios = <&gpx0 0 0>,
++                                                       <&gpx0 1 0>,
++                                                       <&gpx0 2 0>;
++                      max8997,pmic-buck1-dvs-voltage = <1350000>, <1300000>,
++                                                       <1250000>, <1200000>,
++                                                       <1150000>, <1100000>,
++                                                       <1000000>, <950000>;
++                      max8997,pmic-buck2-dvs-voltage = <1100000>, <1100000>,
++                                                       <1100000>, <1100000>,
++                                                       <1000000>, <1000000>,
++                                                       <1000000>, <1000000>;
++                      max8997,pmic-buck5-dvs-voltage = <1200000>, <1200000>,
++                                                       <1200000>, <1200000>,
++                                                       <1200000>, <1200000>,
++                                                       <1200000>, <1200000>;
++
++                      regulators {
++                              ldo1_reg: LDO1 {
++                                      regulator-name = "VDD_ABB_3.3V";
++                                      regulator-min-microvolt = <3300000>;
++                                      regulator-max-microvolt = <3300000>;
++                              };
++
++                              ldo2_reg: LDO2 {
++                                      regulator-name = "VDD_ALIVE_1.1V";
++                                      regulator-min-microvolt = <1100000>;
++                                      regulator-max-microvolt = <1100000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo3_reg: LDO3 {
++                                      regulator-name = "VMIPI_1.1V";
++                                      regulator-min-microvolt = <1100000>;
++                                      regulator-max-microvolt = <1100000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo4_reg: LDO4 {
++                                      regulator-name = "VDD_RTC_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo6_reg: LDO6 {
++                                      regulator-name = "VMIPI_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo7_reg: LDO7 {
++                                      regulator-name = "VDD_AUD_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo8_reg: LDO8 {
++                                      regulator-name = "VADC_3.3V";
++                                      regulator-min-microvolt = <3300000>;
++                                      regulator-max-microvolt = <3300000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo9_reg: LDO9 {
++                                      regulator-name = "DVDD_SWB_2.8V";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo10_reg: LDO10 {
++                                      regulator-name = "VDD_PLL_1.1V";
++                                      regulator-min-microvolt = <1100000>;
++                                      regulator-max-microvolt = <1100000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo11_reg: LDO11 {
++                                      regulator-name = "VDD_AUD_3V";
++                                      regulator-min-microvolt = <3000000>;
++                                      regulator-max-microvolt = <3000000>;
++                              };
++
++                              ldo14_reg: LDO14 {
++                                      regulator-name = "AVDD18_SWB_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo17_reg: LDO17 {
++                                      regulator-name = "VDD_SWB_3.3V";
++                                      regulator-min-microvolt = <3300000>;
++                                      regulator-max-microvolt = <3300000>;
++                                      regulator-always-on;
++                              };
++
++                              buck1_reg: BUCK1 {
++                                      regulator-name = "vdd_arm";
++                                      regulator-min-microvolt = <950000>;
++                                      regulator-max-microvolt = <1350000>;
++                                      regulator-always-on;
++                                      regulator-boot-on;
++                              };
++
++                              buck2_reg: BUCK2 {
++                                      regulator-name = "vdd_int";
++                                      regulator-min-microvolt = <900000>;
++                                      regulator-max-microvolt = <1100000>;
++                                      regulator-always-on;
++                                      regulator-boot-on;
++                              };
++
++                              buck5_reg: BUCK5 {
++                                      regulator-name = "VDDQ_M1M2_1.2V";
++                                      regulator-min-microvolt = <1200000>;
++                                      regulator-max-microvolt = <1200000>;
++                                      regulator-always-on;
++                              };
++
++                              buck7_reg: BUCK7 {
++                                      regulator-name = "VDD_LCD_3.3V";
++                                      regulator-min-microvolt = <3300000>;
++                                      regulator-max-microvolt = <3300000>;
++                                      regulator-boot-on;
++                              };
++                      };
++              };
++      };
++
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0307-ARM-dts-exynos4210-origen-Add-device-node-for-ehci-c.patch b/patches.tizen/0307-ARM-dts-exynos4210-origen-Add-device-node-for-ehci-c.patch
new file mode 100644 (file)
index 0000000..226b379
--- /dev/null
@@ -0,0 +1,33 @@
+From ced71a514af10c9b71f219401d254ad93e6e1642 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 13 Mar 2013 20:09:01 +0100
+Subject: [PATCH 0307/1302] ARM: dts: exynos4210-origen: Add device node for
+ ehci controller
+
+This patch adds device tree node for ehci controller used on
+exynos4210-origen board.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-origen.dts | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts
+index c28a4ad..341717b 100644
+--- a/arch/arm/boot/dts/exynos4210-origen.dts
++++ b/arch/arm/boot/dts/exynos4210-origen.dts
+@@ -182,6 +182,10 @@
+               vusb_a-supply = <&vusb_reg>;
+       };
++      ehci@12580000 {
++              status = "okay";
++      };
++
+       i2c@13860000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0308-ARM-dts-exynos4210-origen-Use-real-regulators-for-US.patch b/patches.tizen/0308-ARM-dts-exynos4210-origen-Use-real-regulators-for-US.patch
new file mode 100644 (file)
index 0000000..d1e59c5
--- /dev/null
@@ -0,0 +1,43 @@
+From 3ced7a2eecc1352aafb23bba0a29af739bc40bf9 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 13 Mar 2013 20:03:15 +0100
+Subject: [PATCH 0308/1302] ARM: dts: exynos4210-origen: Use real regulators
+ for USB OTG
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-origen.dts | 11 ++---------
+ 1 file changed, 2 insertions(+), 9 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts
+index 341717b..95bb61f 100644
+--- a/arch/arm/boot/dts/exynos4210-origen.dts
++++ b/arch/arm/boot/dts/exynos4210-origen.dts
+@@ -165,21 +165,14 @@
+               };
+       };
+-      vusb_reg: voltage-regulator-1 {
+-              compatible = "regulator-fixed";
+-              regulator-name = "VUSB_DUMMY";
+-              regulator-min-microvolt = <3300000>;
+-              regulator-max-microvolt = <3300000>;
+-      };
+-
+       usbphy@125B0000 {
+               status = "okay";
+       };
+       hsotg@12480000 {
+               status = "okay";
+-              vusb_d-supply = <&vusb_reg>;
+-              vusb_a-supply = <&vusb_reg>;
++              vusb_d-supply = <&ldo8_reg>;
++              vusb_a-supply = <&ldo3_reg>;
+       };
+       ehci@12580000 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0309-usb-ehci-s5p-Create-EHCI-OHCI-power-control-sysfs.patch b/patches.tizen/0309-usb-ehci-s5p-Create-EHCI-OHCI-power-control-sysfs.patch
new file mode 100644 (file)
index 0000000..06e44f7
--- /dev/null
@@ -0,0 +1,207 @@
+From 004a5931f7402852bdcff955d9ca4bbdd78446b9 Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Tue, 2 Jul 2013 16:14:01 +0200
+Subject: [PATCH 0309/1302] usb: ehci-s5p: Create EHCI & OHCI power control
+ sysfs
+
+This patch enable EHCI & OHCI power control function using sysfs
+
+This control ehci port power and initialize kernel resources.
+EHCI power off: echo 0 > /sys/devices/platform/s5p-ehci/ehci_power
+EHCI power on: echo 1 > /sys/devices/platform/s5p-ehci/ehci_power
+
+OHCI power off: echo 0 > /sys/devices/platform/s5p-ohci/ohci_power
+OHCI power on: echo 1 > /sys/devices/platform/s5p-ohci/ohci_power
+
+Change-Id: I51f99fa5759cd5041b1e70cf7309047aac2232e5
+Signed-off-by: Yulgon Kim <yulgon.kim@samsung.com>
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/host/ehci-s5p.c | 119 ++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 99 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
+index 379037f..30c8f44 100644
+--- a/drivers/usb/host/ehci-s5p.c
++++ b/drivers/usb/host/ehci-s5p.c
+@@ -45,6 +45,7 @@ static struct hc_driver __read_mostly s5p_ehci_hc_driver;
+ struct s5p_ehci_hcd {
+       struct clk *clk;
++      int power_on;
+       struct usb_phy *phy;
+       struct usb_otg *otg;
+       struct s5p_ehci_platdata *pdata;
+@@ -52,6 +53,93 @@ struct s5p_ehci_hcd {
+ #define to_s5p_ehci(hcd)      (struct s5p_ehci_hcd *)(hcd_to_ehci(hcd)->priv)
++static void s5p_ehci_phy_enable(struct s5p_ehci_hcd *s5p_ehci,
++                                              struct platform_device *pdev)
++{
++      if (s5p_ehci->phy)
++              usb_phy_init(s5p_ehci->phy);
++      else if (s5p_ehci->pdata->phy_init)
++              s5p_ehci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
++}
++
++static void s5p_ehci_phy_disable(struct s5p_ehci_hcd *s5p_ehci,
++                                               struct platform_device *pdev)
++{
++      if (s5p_ehci->phy)
++              usb_phy_shutdown(s5p_ehci->phy);
++      else if (s5p_ehci->pdata->phy_exit)
++              s5p_ehci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
++}
++
++static ssize_t show_ehci_power(struct device *dev,
++                             struct device_attribute *attr,
++                             char *buf)
++{
++      struct platform_device *pdev = to_platform_device(dev);
++      struct usb_hcd *hcd = platform_get_drvdata(pdev);
++      struct s5p_ehci_hcd *s5p_ehci = to_s5p_ehci(hcd);
++
++      return sprintf(buf, "EHCI Power %s\n", (s5p_ehci->power_on) ? "on" : "off");
++}
++
++static ssize_t store_ehci_power(struct device *dev,
++                              struct device_attribute *attr,
++                              const char *buf, size_t count)
++{
++      struct platform_device *pdev = to_platform_device(dev);
++      struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
++      struct usb_hcd *hcd = platform_get_drvdata(pdev);
++      struct s5p_ehci_hcd *s5p_ehci = to_s5p_ehci(hcd);
++      int power_on;
++      int irq;
++      int retval;
++
++      if (sscanf(buf, "%d", &power_on) != 1)
++              return -EINVAL;
++
++      device_lock(dev);
++      if (!power_on && s5p_ehci->power_on) {
++              printk(KERN_DEBUG "%s: EHCI turns off\n", __func__);
++              s5p_ehci->power_on = 0;
++              usb_remove_hcd(hcd);
++
++              s5p_ehci_phy_disable(s5p_ehci, pdev);
++      } else if (power_on) {
++              printk(KERN_DEBUG "%s: EHCI turns on\n", __func__);
++              if (s5p_ehci->power_on) {
++                      usb_remove_hcd(hcd);
++              }
++
++              s5p_ehci_phy_enable(s5p_ehci, pdev);
++
++              irq = platform_get_irq(pdev, 0);
++              retval = usb_add_hcd(hcd, irq,
++                              IRQF_DISABLED | IRQF_SHARED);
++              if (retval < 0) {
++                      dev_err(dev, "Power On Fail\n");
++                      goto exit;
++              }
++
++              s5p_ehci->power_on = 1;
++      }
++exit:
++      device_unlock(dev);
++      return count;
++}
++static DEVICE_ATTR(ehci_power, 0664, show_ehci_power, store_ehci_power);
++
++static inline int create_ehci_sys_file(struct ehci_hcd *ehci)
++{
++      return device_create_file(ehci_to_hcd(ehci)->self.controller,
++                      &dev_attr_ehci_power);
++}
++
++static inline void remove_ehci_sys_file(struct ehci_hcd *ehci)
++{
++      device_remove_file(ehci_to_hcd(ehci)->self.controller,
++                      &dev_attr_ehci_power);
++}
++
+ static void s5p_setup_vbus_gpio(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+@@ -154,10 +242,7 @@ static int s5p_ehci_probe(struct platform_device *pdev)
+       if (s5p_ehci->otg)
+               s5p_ehci->otg->set_host(s5p_ehci->otg, &hcd->self);
+-      if (s5p_ehci->phy)
+-              usb_phy_init(s5p_ehci->phy);
+-      else if (s5p_ehci->pdata->phy_init)
+-              s5p_ehci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
++      s5p_ehci_phy_enable(s5p_ehci, pdev);
+       ehci = hcd_to_ehci(hcd);
+       ehci->caps = hcd->regs;
+@@ -173,13 +258,14 @@ static int s5p_ehci_probe(struct platform_device *pdev)
+       platform_set_drvdata(pdev, hcd);
++      create_ehci_sys_file(ehci);
++      s5p_ehci->power_on = 1;
++
+       return 0;
+ fail_add_hcd:
+-      if (s5p_ehci->phy)
+-              usb_phy_shutdown(s5p_ehci->phy);
+-      else if (s5p_ehci->pdata->phy_exit)
+-              s5p_ehci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
++      s5p_ehci_phy_disable(s5p_ehci, pdev);
++
+ fail_io:
+       clk_disable_unprepare(s5p_ehci->clk);
+ fail_clk:
+@@ -192,15 +278,14 @@ static int s5p_ehci_remove(struct platform_device *pdev)
+       struct usb_hcd *hcd = platform_get_drvdata(pdev);
+       struct s5p_ehci_hcd *s5p_ehci = to_s5p_ehci(hcd);
++      s5p_ehci->power_on = 0;
++      remove_ehci_sys_file(hcd_to_ehci(hcd));
+       usb_remove_hcd(hcd);
+       if (s5p_ehci->otg)
+               s5p_ehci->otg->set_host(s5p_ehci->otg, &hcd->self);
+-      if (s5p_ehci->phy)
+-              usb_phy_shutdown(s5p_ehci->phy);
+-      else if (s5p_ehci->pdata->phy_exit)
+-              s5p_ehci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
++      s5p_ehci_phy_disable(s5p_ehci, pdev);
+       clk_disable_unprepare(s5p_ehci->clk);
+@@ -232,10 +317,7 @@ static int s5p_ehci_suspend(struct device *dev)
+       if (s5p_ehci->otg)
+               s5p_ehci->otg->set_host(s5p_ehci->otg, &hcd->self);
+-      if (s5p_ehci->phy)
+-              usb_phy_shutdown(s5p_ehci->phy);
+-      else if (s5p_ehci->pdata->phy_exit)
+-              s5p_ehci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
++      s5p_ehci_phy_disable(s5p_ehci, pdev);
+       clk_disable_unprepare(s5p_ehci->clk);
+@@ -253,10 +335,7 @@ static int s5p_ehci_resume(struct device *dev)
+       if (s5p_ehci->otg)
+               s5p_ehci->otg->set_host(s5p_ehci->otg, &hcd->self);
+-      if (s5p_ehci->phy)
+-              usb_phy_init(s5p_ehci->phy);
+-      else if (s5p_ehci->pdata->phy_init)
+-              s5p_ehci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
++      s5p_ehci_phy_enable(s5p_ehci, pdev);
+       /* DMA burst Enable */
+       writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs));
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0310-usb-ehci-s5p-Fix-device-tree-compatible-string-for-e.patch b/patches.tizen/0310-usb-ehci-s5p-Fix-device-tree-compatible-string-for-e.patch
new file mode 100644 (file)
index 0000000..e63fc5b
--- /dev/null
@@ -0,0 +1,32 @@
+From c098620b3b13eea9e696e7bd73472361841e0747 Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Tue, 2 Jul 2013 16:14:29 +0200
+Subject: [PATCH 0310/1302] usb: ehci-s5p: Fix device tree compatible string
+ for ehci-s5p.c
+
+Change device tree compatible string to a more generic one covering whole
+Exynos SoC family.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/host/ehci-s5p.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
+index 30c8f44..708b5b4 100644
+--- a/drivers/usb/host/ehci-s5p.c
++++ b/drivers/usb/host/ehci-s5p.c
+@@ -355,7 +355,7 @@ static const struct dev_pm_ops s5p_ehci_pm_ops = {
+ #ifdef CONFIG_OF
+ static const struct of_device_id exynos_ehci_match[] = {
+-      { .compatible = "samsung,exynos4210-ehci" },
++      { .compatible = "samsung,exynos-ehci" },
+       {},
+ };
+ MODULE_DEVICE_TABLE(of, exynos_ehci_match);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0311-ARM-dts-Enable-ehci-for-exynos4412-redwood.dts.patch b/patches.tizen/0311-ARM-dts-Enable-ehci-for-exynos4412-redwood.dts.patch
new file mode 100644 (file)
index 0000000..e32d97d
--- /dev/null
@@ -0,0 +1,29 @@
+From 0ded303dba76f72dcbc36cb2d4147be7eb0debb6 Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Tue, 2 Jul 2013 15:51:39 +0200
+Subject: [PATCH 0311/1302] ARM: dts: Enable ehci for exynos4412-redwood.dts
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-redwood.dts | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-redwood.dts b/arch/arm/boot/dts/exynos4412-redwood.dts
+index 74b70a9..828376b 100644
+--- a/arch/arm/boot/dts/exynos4412-redwood.dts
++++ b/arch/arm/boot/dts/exynos4412-redwood.dts
+@@ -726,4 +726,9 @@
+               status = "okay";
+       };
++      ehci@12580000 {
++              status = "okay";
++      };
++
++
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0312-usb-s3c-hsotg-Changing-MAC-interface-to-8-bit.patch b/patches.tizen/0312-usb-s3c-hsotg-Changing-MAC-interface-to-8-bit.patch
new file mode 100644 (file)
index 0000000..d626db6
--- /dev/null
@@ -0,0 +1,55 @@
+From c9c649b384431e66e91d6e5ab73b42fce81c9afb Mon Sep 17 00:00:00 2001
+From: Praveen Paneri <p.paneri@samsung.com>
+Date: Tue, 2 Jul 2013 16:12:16 +0200
+Subject: [PATCH 0312/1302] usb: s3c-hsotg: Changing MAC interface to 8 bit
+
+This patch changes UTMI+ PHY interface of udc core from 16bit to
+8bit. Although the manual says that only 16 bit is supported. This
+solves the problem of EHCI and Device not working together.
+
+Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/s3c-hsotg.c | 6 +++---
+ drivers/usb/gadget/s3c-hsotg.h | 1 +
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
+index 8fd9681..5c8fe2d 100644
+--- a/drivers/usb/gadget/s3c-hsotg.c
++++ b/drivers/usb/gadget/s3c-hsotg.c
+@@ -2214,8 +2214,8 @@ static void s3c_hsotg_core_init(struct s3c_hsotg *hsotg)
+        */
+       /* set the PLL on, remove the HNP/SRP and set the PHY */
+-      writel(GUSBCFG_PHYIf16 | GUSBCFG_TOutCal(7) |
+-             (0x5 << 10), hsotg->regs + GUSBCFG);
++      writel(GUSBCFG_PHYIf8 | GUSBCFG_TOutCal(7) |
++             (0x9 << 10), hsotg->regs + GUSBCFG);
+       s3c_hsotg_init_fifo(hsotg);
+@@ -2883,7 +2883,7 @@ static void s3c_hsotg_init(struct s3c_hsotg *hsotg)
+       s3c_hsotg_init_fifo(hsotg);
+       /* set the PLL on, remove the HNP/SRP and set the PHY */
+-      writel(GUSBCFG_PHYIf16 | GUSBCFG_TOutCal(7) | (0x5 << 10),
++      writel(GUSBCFG_PHYIf8 | GUSBCFG_TOutCal(7) | (0x9 << 10),
+              hsotg->regs + GUSBCFG);
+       writel(using_dma(hsotg) ? GAHBCFG_DMAEn : 0x0,
+diff --git a/drivers/usb/gadget/s3c-hsotg.h b/drivers/usb/gadget/s3c-hsotg.h
+index d650b12..3848263 100644
+--- a/drivers/usb/gadget/s3c-hsotg.h
++++ b/drivers/usb/gadget/s3c-hsotg.h
+@@ -55,6 +55,7 @@
+ #define GUSBCFG_HNPCap                                (1 << 9)
+ #define GUSBCFG_SRPCap                                (1 << 8)
+ #define GUSBCFG_PHYIf16                       (1 << 3)
++#define GUSBCFG_PHYIf8                        (0 << 3)
+ #define GUSBCFG_TOutCal_MASK                  (0x7 << 0)
+ #define GUSBCFG_TOutCal_SHIFT                 (0)
+ #define GUSBCFG_TOutCal_LIMIT                 (0x7)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0313-usb-ehci-s5p-Add-support-for-HSIC-to-the-Exynos-4x12.patch b/patches.tizen/0313-usb-ehci-s5p-Add-support-for-HSIC-to-the-Exynos-4x12.patch
new file mode 100644 (file)
index 0000000..b3cdd0c
--- /dev/null
@@ -0,0 +1,166 @@
+From ec87e984343becb83f6853f7a620b53ca714932c Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Tue, 2 Jul 2013 16:14:44 +0200
+Subject: [PATCH 0313/1302] usb: ehci-s5p: Add support for HSIC to the Exynos
+ 4x12 SoC family
+
+Add support for HSIC to the Exynos 4x12 SoC family.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/phy/phy-samsung-usb.h  | 16 +++++++++++++-
+ drivers/usb/phy/phy-samsung-usb2.c | 44 ++++++++++++++++++++++++++++++++------
+ 2 files changed, 53 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/usb/phy/phy-samsung-usb.h b/drivers/usb/phy/phy-samsung-usb.h
+index 585d12f..3614a0f 100644
+--- a/drivers/usb/phy/phy-samsung-usb.h
++++ b/drivers/usb/phy/phy-samsung-usb.h
+@@ -28,6 +28,11 @@
+ #define PHYPWR_FORCE_SUSPEND                  (0x1 << 1)
+ /* For Exynos4 */
+ #define PHYPWR_NORMAL_MASK_PHY0                       (0x39 << 0)
++#define PHYPWR_NORMAL_MASK_PHY1                       (0x7 << 6)
++#define PHYPWR_NORMAL_MASK_HSIC0_4210         (0x3 << 9)
++#define PHYPWR_NORMAL_MASK_HSIC1_4210         (0x3 << 11)
++#define PHYPWR_NORMAL_MASK_HSIC0_4X12         (0x7 << 9)
++#define PHYPWR_NORMAL_MASK_HSIC1_4X12         (0x7 << 12)
+ #define PHYPWR_SLEEP_PHY0                     (0x1 << 5)
+ #define SAMSUNG_PHYCLK                                (0x04)
+@@ -46,6 +51,13 @@
+ #define RSTCON_PHYLINK_SWRST                  (0x1 << 2)
+ #define RSTCON_HLINK_SWRST                    (0x1 << 1)
+ #define RSTCON_SWRST                          (0x1 << 0)
++/* This following values will also reset some fields marked as "reserved"
++   The question is... was it intentional?                                 */
++#define RSTCON_SWRST_HOST_4X12                        (0xff << 3)
++#define RSTCON_SWRST_HOST_4210                        (0x7f << 3)
++
++#define EXYNOS4_PHY1CON                               (0x34)
++#define PHY1CON_FPENABLEN                     (0x1 << 0)
+ /* EXYNOS5 */
+ #define EXYNOS5_PHY_HOST_CTRL0                        (0x00)
+@@ -233,7 +245,9 @@
+ #define KHZ (1000)
+ #endif
+-#define EXYNOS_USBHOST_PHY_CTRL_OFFSET                (0x4)
++#define EXYNOS5_USBHOST_PHY_CTRL_OFFSET               (0x4)
++#define EXYNOS4x12_HSIC1_PHY_CTRL_OFFSET      (0x4)
++#define EXYNOS4x12_HSIC2_PHY_CTRL_OFFSET      (0x8)
+ #define S3C64XX_USBPHY_ENABLE                 (0x1 << 16)
+ #define EXYNOS_USBPHY_ENABLE                  (0x1 << 0)
+ #define EXYNOS_USB20PHY_CFG_HOST_LINK         (0x1 << 0)
+diff --git a/drivers/usb/phy/phy-samsung-usb2.c b/drivers/usb/phy/phy-samsung-usb2.c
+index 03180c0..cebf34b 100644
+--- a/drivers/usb/phy/phy-samsung-usb2.c
++++ b/drivers/usb/phy/phy-samsung-usb2.c
+@@ -68,6 +68,7 @@ static void samsung_exynos5_usb2phy_enable(struct samsung_usbphy *sphy)
+        * the last consumer to disable it.
+        */
++
+       atomic_inc(&sphy->phy_usage);
+       if (exynos5_phyhost_is_on(regs)) {
+@@ -164,22 +165,41 @@ static void samsung_usb2phy_enable(struct samsung_usbphy *sphy)
+       u32 phypwr;
+       u32 phyclk;
+       u32 rstcon;
++      u32 rstbits;
+       /* set clock frequency for PLL */
+       phyclk = sphy->ref_clk_freq;
+       phypwr = readl(regs + SAMSUNG_PHYPWR);
+       rstcon = readl(regs + SAMSUNG_RSTCON);
++      rstbits = 0;
+       switch (sphy->drv_data->cpu_type) {
+       case TYPE_S3C64XX:
+               phyclk &= ~PHYCLK_COMMON_ON_N;
+               phypwr &= ~PHYPWR_NORMAL_MASK;
+-              rstcon |= RSTCON_SWRST;
++              rstbits = RSTCON_SWRST;
+               break;
+       case TYPE_EXYNOS4210:
+-      case TYPE_EXYNOS4X12:
+               phypwr &= ~PHYPWR_NORMAL_MASK_PHY0;
+-              rstcon |= RSTCON_SWRST;
++              rstbits = RSTCON_SWRST;
++              break;
++      case TYPE_EXYNOS4X12:
++              if (sphy->phy_type == USB_PHY_TYPE_HOST) {
++                      phypwr &= ~PHYPWR_NORMAL_MASK_PHY1;
++                      phypwr &= ~PHYPWR_NORMAL_MASK_HSIC0_4X12;
++                      phypwr &= ~PHYPWR_NORMAL_MASK_HSIC1_4X12;
++                      rstbits = RSTCON_SWRST_HOST_4X12;
++                      /* The following register (0x125b0034) is not documented
++                       * for Exynos4412, however it is documented for S5PC210.
++                       * There is means that is should not be used, but hey,
++                       * who knows? */
++                      writel(PHY1CON_FPENABLEN, regs + EXYNOS4_PHY1CON);
++              } else {
++                      phypwr &= ~PHYPWR_NORMAL_MASK_PHY0;
++                      rstbits |= RSTCON_SWRST;
++              }
++              break;
++
+       default:
+               break;
+       }
+@@ -188,9 +208,11 @@ static void samsung_usb2phy_enable(struct samsung_usbphy *sphy)
+       /* Configure PHY0 for normal operation*/
+       writel(phypwr, regs + SAMSUNG_PHYPWR);
+       /* reset all ports of PHY and Link */
++      /* Keep track of which bits are reset with rstbits. */
++      rstcon |= rstbits;
+       writel(rstcon, regs + SAMSUNG_RSTCON);
+       udelay(10);
+-      rstcon &= ~RSTCON_SWRST;
++      rstcon &= ~rstbits;
+       writel(rstcon, regs + SAMSUNG_RSTCON);
+ }
+@@ -241,8 +263,17 @@ static void samsung_usb2phy_disable(struct samsung_usbphy *sphy)
+               phypwr |= PHYPWR_NORMAL_MASK;
+               break;
+       case TYPE_EXYNOS4210:
+-      case TYPE_EXYNOS4X12:
+               phypwr |= PHYPWR_NORMAL_MASK_PHY0;
++              break;
++      case TYPE_EXYNOS4X12:
++              if (sphy->phy_type == USB_PHY_TYPE_HOST) {
++                      phypwr |= PHYPWR_NORMAL_MASK_PHY1;
++                      phypwr |= PHYPWR_NORMAL_MASK_HSIC0_4X12;
++                      phypwr |= PHYPWR_NORMAL_MASK_HSIC1_4X12;
++              } else {
++                      phypwr |= PHYPWR_NORMAL_MASK_PHY0;
++              }
++              break;
+       default:
+               break;
+       }
+@@ -457,6 +488,7 @@ static const struct samsung_usbphy_drvdata usb2phy_exynos4x12 = {
+       .cpu_type               = TYPE_EXYNOS4X12,
+       .devphy_en_mask         = EXYNOS_USBPHY_ENABLE,
+       .hostphy_en_mask        = EXYNOS_USBPHY_ENABLE,
++      .hostphy_reg_offset     = EXYNOS4x12_HSIC1_PHY_CTRL_OFFSET,
+       .rate_to_clksel         = samsung_usbphy_rate_to_clksel_4x12,
+       .set_isolation          = samsung_usbphy_set_isolation_4210,
+       .phy_enable             = samsung_usb2phy_enable,
+@@ -466,7 +498,7 @@ static const struct samsung_usbphy_drvdata usb2phy_exynos4x12 = {
+ static struct samsung_usbphy_drvdata usb2phy_exynos5 = {
+       .cpu_type               = TYPE_EXYNOS5250,
+       .hostphy_en_mask        = EXYNOS_USBPHY_ENABLE,
+-      .hostphy_reg_offset     = EXYNOS_USBHOST_PHY_CTRL_OFFSET,
++      .hostphy_reg_offset     = EXYNOS5_USBHOST_PHY_CTRL_OFFSET,
+       .rate_to_clksel         = samsung_usbphy_rate_to_clksel_4x12,
+       .set_isolation          = samsung_usbphy_set_isolation_4210,
+       .phy_enable             = samsung_exynos5_usb2phy_enable,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0314-modem_if-Add-modem_if-driver-files.patch b/patches.tizen/0314-modem_if-Add-modem_if-driver-files.patch
new file mode 100644 (file)
index 0000000..9e5bf2d
--- /dev/null
@@ -0,0 +1,21839 @@
+From 2446af4fe7b0fca802645d632b56ec30b3698cef Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Wed, 22 May 2013 14:34:06 +0200
+Subject: [PATCH 0314/1302] modem_if: Add modem_if driver files
+
+All files were taken from exynos3.4 kernel.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/misc/modem_if/Kconfig                      |   89 +
+ drivers/misc/modem_if/Makefile                     |   24 +
+ drivers/misc/modem_if/lte_modem_bootloader.c       |  313 +++
+ drivers/misc/modem_if/modem_link_device_c2c.c      |   61 +
+ drivers/misc/modem_if/modem_link_device_c2c.h      |  216 ++
+ drivers/misc/modem_if/modem_link_device_dpram.c    | 2111 ++++++++++++++++++++
+ drivers/misc/modem_if/modem_link_device_dpram.h    |  252 +++
+ .../misc/modem_if/modem_link_device_dpram_ext_op.c | 1306 ++++++++++++
+ drivers/misc/modem_if/modem_link_device_hsic.c     | 1654 +++++++++++++++
+ drivers/misc/modem_if/modem_link_device_hsic.h     |  155 ++
+ drivers/misc/modem_if/modem_link_device_memory.h   |  501 +++++
+ drivers/misc/modem_if/modem_link_device_mipi.c     | 1418 +++++++++++++
+ drivers/misc/modem_if/modem_link_device_mipi.h     |  158 ++
+ drivers/misc/modem_if/modem_link_device_pld.c      | 1618 +++++++++++++++
+ drivers/misc/modem_if/modem_link_device_pld.h      |  231 +++
+ .../misc/modem_if/modem_link_device_pld_ext_op.c   |  556 ++++++
+ drivers/misc/modem_if/modem_link_device_usb.c      | 1027 ++++++++++
+ drivers/misc/modem_if/modem_link_device_usb.h      |  132 ++
+ drivers/misc/modem_if/modem_link_pm_usb.c          |  417 ++++
+ drivers/misc/modem_if/modem_link_pm_usb.h          |   65 +
+ .../misc/modem_if/modem_modemctl_device_cbp71.c    |  233 +++
+ .../misc/modem_if/modem_modemctl_device_cbp72.c    |  273 +++
+ .../misc/modem_if/modem_modemctl_device_cmc221.c   |  317 +++
+ .../misc/modem_if/modem_modemctl_device_esc6270.c  |  348 ++++
+ .../misc/modem_if/modem_modemctl_device_mdm6600.c  |  801 ++++++++
+ .../misc/modem_if/modem_modemctl_device_xmm6260.c  |  303 +++
+ .../misc/modem_if/modem_modemctl_device_xmm6262.c  |  261 +++
+ .../misc/modem_if/modem_net_flowcontrol_device.c   |  117 ++
+ drivers/misc/modem_if/modem_prj.h                  |  725 +++++++
+ drivers/misc/modem_if/modem_sim_slot_switch.c      |   92 +
+ drivers/misc/modem_if/modem_utils.c                | 1227 ++++++++++++
+ drivers/misc/modem_if/modem_utils.h                |  315 +++
+ drivers/misc/modem_if/modem_variation.h            |  168 ++
+ drivers/misc/modem_if/sipc4_io_device.c            | 1668 ++++++++++++++++
+ drivers/misc/modem_if/sipc4_modem.c                |  371 ++++
+ drivers/misc/modem_if/sipc5_io_device.c            | 1620 +++++++++++++++
+ drivers/misc/modem_if/sipc5_modem.c                |  384 ++++
+ 37 files changed, 21527 insertions(+)
+ create mode 100644 drivers/misc/modem_if/Kconfig
+ create mode 100644 drivers/misc/modem_if/Makefile
+ create mode 100644 drivers/misc/modem_if/lte_modem_bootloader.c
+ create mode 100644 drivers/misc/modem_if/modem_link_device_c2c.c
+ create mode 100644 drivers/misc/modem_if/modem_link_device_c2c.h
+ create mode 100644 drivers/misc/modem_if/modem_link_device_dpram.c
+ create mode 100644 drivers/misc/modem_if/modem_link_device_dpram.h
+ create mode 100644 drivers/misc/modem_if/modem_link_device_dpram_ext_op.c
+ create mode 100644 drivers/misc/modem_if/modem_link_device_hsic.c
+ create mode 100644 drivers/misc/modem_if/modem_link_device_hsic.h
+ create mode 100644 drivers/misc/modem_if/modem_link_device_memory.h
+ create mode 100644 drivers/misc/modem_if/modem_link_device_mipi.c
+ create mode 100644 drivers/misc/modem_if/modem_link_device_mipi.h
+ create mode 100644 drivers/misc/modem_if/modem_link_device_pld.c
+ create mode 100644 drivers/misc/modem_if/modem_link_device_pld.h
+ create mode 100644 drivers/misc/modem_if/modem_link_device_pld_ext_op.c
+ create mode 100644 drivers/misc/modem_if/modem_link_device_usb.c
+ create mode 100644 drivers/misc/modem_if/modem_link_device_usb.h
+ create mode 100644 drivers/misc/modem_if/modem_link_pm_usb.c
+ create mode 100644 drivers/misc/modem_if/modem_link_pm_usb.h
+ create mode 100644 drivers/misc/modem_if/modem_modemctl_device_cbp71.c
+ create mode 100644 drivers/misc/modem_if/modem_modemctl_device_cbp72.c
+ create mode 100644 drivers/misc/modem_if/modem_modemctl_device_cmc221.c
+ create mode 100644 drivers/misc/modem_if/modem_modemctl_device_esc6270.c
+ create mode 100644 drivers/misc/modem_if/modem_modemctl_device_mdm6600.c
+ create mode 100644 drivers/misc/modem_if/modem_modemctl_device_xmm6260.c
+ create mode 100644 drivers/misc/modem_if/modem_modemctl_device_xmm6262.c
+ create mode 100644 drivers/misc/modem_if/modem_net_flowcontrol_device.c
+ create mode 100644 drivers/misc/modem_if/modem_prj.h
+ create mode 100644 drivers/misc/modem_if/modem_sim_slot_switch.c
+ create mode 100644 drivers/misc/modem_if/modem_utils.c
+ create mode 100644 drivers/misc/modem_if/modem_utils.h
+ create mode 100644 drivers/misc/modem_if/modem_variation.h
+ create mode 100644 drivers/misc/modem_if/sipc4_io_device.c
+ create mode 100644 drivers/misc/modem_if/sipc4_modem.c
+ create mode 100644 drivers/misc/modem_if/sipc5_io_device.c
+ create mode 100644 drivers/misc/modem_if/sipc5_modem.c
+
+diff --git a/drivers/misc/modem_if/Kconfig b/drivers/misc/modem_if/Kconfig
+new file mode 100644
+index 0000000..234de2f
+--- /dev/null
++++ b/drivers/misc/modem_if/Kconfig
+@@ -0,0 +1,89 @@
++menuconfig SEC_MODEM
++      bool "Samsung Mobile Modem Interface"
++      default n
++      ---help---
++        Samsung Modem Interface Driver.
++
++config UMTS_MODEM_XMM6260
++      bool "modem chip : IMC XMM6260"
++      depends on SEC_MODEM
++      default n
++
++config UMTS_MODEM_XMM6262
++      bool "modem chip : IMC XMM6262"
++      depends on SEC_MODEM
++      default n
++
++config CDMA_MODEM_CBP71
++      bool "modem chip : VIA CBP7.1"
++      depends on SEC_MODEM
++      default n
++
++config CDMA_MODEM_CBP72
++      bool "modem chip : VIA CBP7.2"
++      depends on SEC_MODEM
++      default n
++
++config LTE_MODEM_CMC221
++      bool "modem chip : SEC CMC221"
++      depends on SEC_MODEM
++      default n
++
++config CDMA_MODEM_MDM6600
++      bool "modem chip : QC MDM6600"
++      depends on SEC_MODEM
++      default n
++
++config GSM_MODEM_ESC6270
++      bool "modem chip : QC ESC6270"
++      depends on SEC_MODEM
++      default n
++
++config LINK_DEVICE_MIPI
++      bool "modem driver link device MIPI-HSI"
++      depends on SEC_MODEM
++      default n
++
++config LINK_DEVICE_DPRAM
++      bool "modem driver link device DPRAM"
++      depends on SEC_MODEM
++      default n
++
++config LINK_DEVICE_PLD
++      bool "modem driver link device PLD"
++      depends on SEC_MODEM
++      default n
++config LINK_DEVICE_USB
++      bool "modem driver link device USB"
++      depends on SEC_MODEM
++      default n
++
++config LINK_DEVICE_HSIC
++      bool "modem driver link device HSIC"
++      depends on SEC_MODEM
++      default n
++
++config LINK_DEVICE_C2C
++      bool "modem driver link device C2C"
++      depends on SEC_MODEM
++      default n
++
++config IPC_CMC22x_OLD_RFS
++      bool "IPC: CMC22x ancient RFS"
++      depends on SEC_MODEM
++      default n
++
++config SIPC_VER_5
++      bool "IPC: Samsung IPC 5.0"
++      depends on SEC_MODEM
++      default n
++
++config SIM_DETECT
++      bool "SIM_DETECT pin"
++      depends on SEC_MODEM
++      default n
++
++config SIM_SLOT_SWITCH
++      bool "SIM_SLOT_SWITCH"
++      depends on SEC_MODEM
++      default n
+diff --git a/drivers/misc/modem_if/Makefile b/drivers/misc/modem_if/Makefile
+new file mode 100644
+index 0000000..9bedbe1
+--- /dev/null
++++ b/drivers/misc/modem_if/Makefile
+@@ -0,0 +1,24 @@
++# Makefile of modem_if
++
++EXTRA_CFLAGS += -Idrivers/misc/modem_if
++
++obj-y += sipc5_modem.o sipc5_io_device.o
++obj-y += sipc4_modem.o sipc4_io_device.o
++obj-y += modem_net_flowcontrol_device.o modem_utils.o
++
++obj-$(CONFIG_UMTS_MODEM_XMM6260) += modem_modemctl_device_xmm6260.o
++obj-$(CONFIG_UMTS_MODEM_XMM6262) += modem_modemctl_device_xmm6262.o
++obj-$(CONFIG_CDMA_MODEM_CBP71) += modem_modemctl_device_cbp71.o
++obj-$(CONFIG_CDMA_MODEM_CBP72) += modem_modemctl_device_cbp72.o
++obj-$(CONFIG_LTE_MODEM_CMC221) += modem_modemctl_device_cmc221.o lte_modem_bootloader.o
++obj-$(CONFIG_CDMA_MODEM_MDM6600) += modem_modemctl_device_mdm6600.o
++obj-$(CONFIG_GSM_MODEM_ESC6270) += modem_modemctl_device_esc6270.o
++
++obj-$(CONFIG_LINK_DEVICE_MIPI) += modem_link_device_mipi.o
++obj-$(CONFIG_LINK_DEVICE_DPRAM) += modem_link_device_dpram.o modem_link_device_dpram_ext_op.o
++obj-$(CONFIG_LINK_DEVICE_PLD) += modem_link_device_pld.o modem_link_device_pld_ext_op.o
++obj-$(CONFIG_LINK_DEVICE_USB) += modem_link_device_usb.o modem_link_pm_usb.o
++obj-$(CONFIG_LINK_DEVICE_HSIC) += modem_link_device_hsic.o
++obj-$(CONFIG_LINK_DEVICE_C2C) += modem_link_device_c2c.o
++
++obj-$(CONFIG_SIM_SLOT_SWITCH)  += modem_sim_slot_switch.o
+diff --git a/drivers/misc/modem_if/lte_modem_bootloader.c b/drivers/misc/modem_if/lte_modem_bootloader.c
+new file mode 100644
+index 0000000..f259aae
+--- /dev/null
++++ b/drivers/misc/modem_if/lte_modem_bootloader.c
+@@ -0,0 +1,313 @@
++/* Lte modem bootloader support for Samsung Tuna Board.
++ *
++ * Copyright (C) 2011 Google, Inc.
++ * Copyright (C) 2011 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/interrupt.h>
++#include <linux/platform_device.h>
++#include <linux/miscdevice.h>
++
++#include <linux/uaccess.h>
++#include <linux/fs.h>
++#include <linux/wait.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/mutex.h>
++#include <linux/irq.h>
++#include <linux/gpio.h>
++#include <linux/wakelock.h>
++#include <linux/delay.h>
++#include <linux/spi/spi.h>
++
++#include <linux/platform_data/modem.h>
++#include <linux/platform_data/lte_modem_bootloader.h>
++
++#define LEN_XMIT_DELEY        100
++
++#ifdef AIRPLAIN_MODE_TEST
++int lte_airplain_mode;
++#endif
++
++enum xmit_bootloader_status {
++      XMIT_BOOT_READY = 0,
++      XMIT_LOADER_READY,
++};
++
++struct lte_modem_bootloader {
++      struct spi_device *spi_dev;
++      struct miscdevice dev;
++
++      struct mutex lock;
++
++      unsigned int gpio_lte2ap_status;
++      enum xmit_bootloader_status xmit_status;
++};
++#define to_loader(misc)       container_of(misc, struct lte_modem_bootloader, dev);
++
++static inline
++int spi_xmit(struct lte_modem_bootloader *loader,
++              const unsigned char val)
++{
++      unsigned char buf[1];
++      int ret;
++      struct spi_message msg;
++
++      struct spi_transfer xfer = {
++              .len = 1,
++              .tx_buf = buf,
++      };
++
++      buf[0] = val;
++
++      spi_message_init(&msg);
++      spi_message_add_tail(&xfer, &msg);
++
++      ret = spi_sync(loader->spi_dev, &msg);
++
++      if (ret < 0)
++              mif_err("error %d\n", ret);
++
++      return ret;
++}
++
++static
++int bootloader_write(struct lte_modem_bootloader *loader,
++              const char *addr, const int len)
++{
++      int i;
++      int ret = 0;
++      unsigned char lenbuf[4];
++
++      if (loader->xmit_status == XMIT_LOADER_READY) {
++              memcpy(lenbuf, &len, ARRAY_SIZE(lenbuf));
++              for (i = 0 ; i < ARRAY_SIZE(lenbuf) ; i++) {
++                      ret = spi_xmit(loader, lenbuf[i]);
++                      if (ret < 0)
++                              return ret;
++              }
++              msleep(LEN_XMIT_DELEY);
++      }
++
++      for (i = 0 ; i < len ; i++) {
++              ret = spi_xmit(loader, addr[i]);
++              if (ret < 0)
++                      return ret;
++      }
++
++      return 0;
++}
++
++
++static
++int bootloader_open(struct inode *inode, struct file *flip)
++{
++      struct lte_modem_bootloader *loader = to_loader(flip->private_data);
++      flip->private_data = loader;
++
++      return 0;
++}
++
++static
++long bootloader_ioctl(struct file *flip,
++              unsigned int cmd, unsigned long arg)
++{
++      int ret = 0;
++      int status;
++      struct lte_modem_bootloader_param param;
++      struct lte_modem_bootloader *loader = flip->private_data;
++
++      mutex_lock(&loader->lock);
++      switch (cmd) {
++      case IOCTL_LTE_MODEM_XMIT_BOOT:
++
++              ret = copy_from_user(&param, (const void __user *)arg,
++                                              sizeof(param));
++              if (ret) {
++                      mif_err("can not copy userdata\n");
++                      ret = -EFAULT;
++                      goto exit_err;
++              }
++
++              dev_info(&loader->spi_dev->dev,
++                              "IOCTL_LTE_MODEM_XMIT_BOOT - bin size: %d\n",
++                              param.len);
++
++              ret = bootloader_write(loader, param.buf, param.len);
++              if (ret < 0)
++                      mif_err("failed to xmit boot bin\n");
++              else {
++                      if (loader->xmit_status == XMIT_BOOT_READY)
++                              loader->xmit_status = XMIT_LOADER_READY;
++              else
++                              loader->xmit_status = XMIT_BOOT_READY;
++              }
++
++              break;
++      case IOCTL_LTE_MODEM_LTE2AP_STATUS:
++              status = gpio_get_value(loader->gpio_lte2ap_status);
++              mif_debug("LTE2AP status :%d\n", status);
++              ret = copy_to_user((unsigned int *)arg, &status,
++                              sizeof(status));
++
++              break;
++#ifdef AIRPLAIN_MODE_TEST
++      case IOCTL_LTE_MODEM_AIRPLAIN_ON:
++              lte_airplain_mode = 1;
++              mif_info("IOCTL_LTE_MODEM LPM_ON\n");
++              break;
++      case IOCTL_LTE_MODEM_AIRPLAIN_OFF:
++              mif_info("IOCTL_LTE_MODEM LPM_OFF\n");
++              lte_airplain_mode = 0;
++              break;
++#endif
++      default:
++              mif_err("ioctl cmd error\n");
++              ret = -ENOIOCTLCMD;
++
++              break;
++      }
++      mutex_unlock(&loader->lock);
++
++exit_err:
++      return ret;
++}
++
++static const struct file_operations lte_modem_bootloader_fops = {
++      .owner = THIS_MODULE,
++      .open = bootloader_open,
++      .unlocked_ioctl = bootloader_ioctl,
++};
++
++static
++int bootloader_gpio_setup(struct lte_modem_bootloader *loader)
++{
++      if (!loader->gpio_lte2ap_status)
++              return -EINVAL;
++
++      gpio_request(loader->gpio_lte2ap_status, "GPIO_LTE2AP_STATUS");
++      gpio_direction_input(loader->gpio_lte2ap_status);
++
++      return 0;
++}
++
++static
++int __devinit lte_modem_bootloader_probe(struct spi_device *spi)
++{
++      int ret;
++
++      struct lte_modem_bootloader *loader;
++      struct lte_modem_bootloader_platform_data *pdata;
++
++      loader = kzalloc(sizeof(*loader), GFP_KERNEL);
++      if (!loader) {
++              mif_err("failed to allocate for lte_modem_bootloader\n");
++              ret = -ENOMEM;
++              goto err_alloc;
++      }
++      mutex_init(&loader->lock);
++
++      spi->bits_per_word = 8;
++
++      if (spi_setup(spi)) {
++              mif_err("failed to setup spi for lte_modem_bootloader\n");
++              ret = -EINVAL;
++              goto err_setup;
++      }
++
++      loader->spi_dev = spi;
++
++      if (!spi->dev.platform_data) {
++              mif_err("failed to get platform data for lte_modem_bootloader\n");
++              ret = -EINVAL;
++              goto err_setup;
++      }
++      pdata = (struct lte_modem_bootloader_platform_data *)
++                      spi->dev.platform_data;
++      loader->gpio_lte2ap_status = pdata->gpio_lte2ap_status;
++
++      ret = bootloader_gpio_setup(loader);
++      if (ret) {
++              mif_err("failed to set gpio for lte_modem_boot_loader\n");
++              goto err_setup;
++      }
++
++      loader->gpio_lte2ap_status = pdata->gpio_lte2ap_status;
++      loader->xmit_status = XMIT_BOOT_READY;
++
++      spi_set_drvdata(spi, loader);
++
++      loader->dev.minor = MISC_DYNAMIC_MINOR;
++      loader->dev.name = "lte_spi";
++      loader->dev.fops = &lte_modem_bootloader_fops;
++      ret = misc_register(&loader->dev);
++      if (ret) {
++              mif_err("failed to register misc dev for lte_modem_bootloader\n");
++              goto err_setup;
++      }
++      mif_info("lte_modem_bootloader successfully probed\n");
++#ifdef AIRPLAIN_MODE_TEST
++      lte_airplain_mode = 0;
++#endif
++      return 0;
++
++err_setup:
++      mutex_destroy(&loader->lock);
++      kfree(loader);
++
++err_alloc:
++
++      return ret;
++}
++
++static
++int __devexit lte_modem_bootloader_remove(struct spi_device *spi)
++{
++      struct lte_modem_bootloader *loader = spi_get_drvdata(spi);
++
++      misc_deregister(&loader->dev);
++      mutex_destroy(&loader->lock);
++      kfree(loader);
++
++      return 0;
++}
++
++static
++struct spi_driver lte_modem_bootloader_driver = {
++      .driver = {
++              .name = "lte_modem_spi",
++              .bus = &spi_bus_type,
++              .owner = THIS_MODULE,
++      },
++      .probe = lte_modem_bootloader_probe,
++      .remove = __devexit_p(lte_modem_bootloader_remove),
++};
++
++static
++int __init lte_modem_bootloader_init(void)
++{
++      return spi_register_driver(&lte_modem_bootloader_driver);
++}
++
++static
++void __exit lte_modem_bootloader_exit(void)
++{
++      spi_unregister_driver(&lte_modem_bootloader_driver);
++}
++
++module_init(lte_modem_bootloader_init);
++module_exit(lte_modem_bootloader_exit);
++
++MODULE_DESCRIPTION("LTE Modem Bootloader driver");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/misc/modem_if/modem_link_device_c2c.c b/drivers/misc/modem_if/modem_link_device_c2c.c
+new file mode 100644
+index 0000000..acbaadf
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_link_device_c2c.c
+@@ -0,0 +1,61 @@
++/* /linux/drivers/new_modem_if/link_dev_c2c.c
++ *
++ * Copyright (C) 2010 Google, Inc.
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <linux/init.h>
++#include <linux/irq.h>
++#include <linux/gpio.h>
++#include <linux/interrupt.h>
++#include <linux/timer.h>
++#include <linux/wakelock.h>
++#include <linux/delay.h>
++#include <linux/wait.h>
++#include <linux/sched.h>
++#include <linux/vmalloc.h>
++#include <linux/proc_fs.h>
++#include <linux/if_arp.h>
++#include <linux/platform_device.h>
++
++#include <linux/platform_data/modem.h>
++#include <linux/platform_data/c2c.h>
++#include "modem_prj.h"
++#include "modem_link_device_c2c.h"
++
++struct link_device *c2c_create_link_device(struct platform_device *pdev)
++{
++      struct c2c_link_device *dpld;
++      struct link_device *ld;
++      struct modem_data *pdata;
++
++      pdata = pdev->dev.platform_data;
++
++      dpld = kzalloc(sizeof(struct c2c_link_device), GFP_KERNEL);
++      if (!dpld) {
++              mif_err("dpld == NULL\n");
++              return NULL;
++      }
++
++      wake_lock_init(&dpld->c2c_wake_lock, WAKE_LOCK_SUSPEND, "c2c_wakelock");
++      wake_lock(&dpld->c2c_wake_lock);
++
++      ld = &dpld->ld;
++      dpld->pdata = pdata;
++
++      ld->name = "c2c";
++
++      mif_info("%s is created!!!\n", dpld->ld.name);
++
++      return ld;
++}
+diff --git a/drivers/misc/modem_if/modem_link_device_c2c.h b/drivers/misc/modem_if/modem_link_device_c2c.h
+new file mode 100644
+index 0000000..7ec9aa6
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_link_device_c2c.h
+@@ -0,0 +1,216 @@
++/*
++ * Copyright (C) 2010 Google, Inc.
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.        See the
++ * GNU General Public License for more details.
++ *
++ */
++#include <linux/wakelock.h>
++
++#ifndef __MODEM_LINK_DEVICE_C2C_H__
++#define __MODEM_LINK_DEVICE_C2C_H__
++
++#define DPRAM_ERR_MSG_LEN             128
++#define DPRAM_ERR_DEVICE              "c2cerr"
++
++#define MAX_IDX                               2
++
++#define DPRAM_BASE_PTR                        0x4000000
++
++#define DPRAM_START_ADDRESS           0
++#define DPRAM_MAGIC_CODE_ADDRESS      DPRAM_START_ADDRESS
++#define DPRAM_GOTA_MAGIC_CODE_SIZE            0x4
++#define DPRAM_PDA2PHONE_FORMATTED_START_ADDRESS       \
++      (DPRAM_START_ADDRESS + DPRAM_GOTA_MAGIC_CODE_SIZE)
++#define BSP_DPRAM_BASE_SIZE           0x1ff8
++#define DPRAM_END_OF_ADDRESS          (BSP_DPRAM_BASE_SIZE - 1)
++#define DPRAM_INTERRUPT_SIZE          0x2
++#define DPRAM_PDA2PHONE_INTERRUPT_ADDRESS     \
++      (DPRAM_START_ADDRESS + BSP_DPRAM_BASE_SIZE -  DPRAM_INTERRUPT_SIZE*2)
++#define DPRAM_PHONE2PDA_INTERRUPT_ADDRESS     \
++      (DPRAM_START_ADDRESS + BSP_DPRAM_BASE_SIZE)
++#define DPRAM_BUFFER_SIZE                     \
++      (DPRAM_PHONE2PDA_INTERRUPT_ADDRESS -\
++      DPRAM_PDA2PHONE_FORMATTED_START_ADDRESS)
++#define DPRAM_INDEX_SIZE              0x2
++
++#define MAGIC_DMDL                    0x4445444C
++#define MAGIC_UMDL                    0x4445444D
++
++#define DPRAM_PACKET_DATA_SIZE                0x3f00
++#define DPRAM_PACKET_HEADER_SIZE      0x7
++
++#define INT_GOTA_MASK_VALID           0xA000
++#define INT_DPRAM_DUMP_MASK_VALID             0xA000
++#define MASK_CMD_RECEIVE_READY_NOTIFICATION   0xA100
++#define MASK_CMD_DOWNLOAD_START_REQUEST               0xA200
++#define MASK_CMD_DOWNLOAD_START_RESPONSE      0xA301
++#define MASK_CMD_IMAGE_SEND_REQUEST           0xA400
++#define MASK_CMD_IMAGE_SEND_RESPONSE          0xA500
++#define MASK_CMD_SEND_DONE_REQUEST            0xA600
++#define MASK_CMD_SEND_DONE_RESPONSE           0xA701
++#define MASK_CMD_STATUS_UPDATE_NOTIFICATION   0xA800
++#define MASK_CMD_UPDATE_DONE_NOTIFICATION     0xA900
++#define MASK_CMD_EFS_CLEAR_RESPONSE           0xAB00
++#define MASK_CMD_ALARM_BOOT_OK                        0xAC00
++#define MASK_CMD_ALARM_BOOT_FAIL              0xAD00
++
++#define WRITEIMG_HEADER_SIZE                  8
++#define WRITEIMG_TAIL_SIZE                    4
++#define WRITEIMG_BODY_SIZE                    \
++      (DPRAM_BUFFER_SIZE - WRITEIMG_HEADER_SIZE - WRITEIMG_TAIL_SIZE)
++
++#define DPDN_DEFAULT_WRITE_LEN                        WRITEIMG_BODY_SIZE
++#define CMD_DL_START_REQ                      0x9200
++#define CMD_IMG_SEND_REQ                      0x9400
++#define CMD_DL_SEND_DONE_REQ                  0x9600
++
++#define CMD_UL_START_REQ              0x9200
++#define CMD_UL_START_READY            0x9400
++#define CMD_UL_SEND_RESP              0x9601
++#define CMD_UL_SEND_DONE_RESP         0x9801
++#define CMD_UL_SEND_REQ                       0xA500
++#define CMD_UL_START_RESPONSE         0xA301
++#define CMD_UL_SEND_DONE_REQ          0xA700
++#define CMD_RECEIVE_READY_NOTIFICATION        0xA100
++
++#define MASK_CMD_RESULT_FAIL          0x0002
++#define MASK_CMD_RESULT_SUCCESS               0x0001
++
++#define START_INDEX                   0x007F
++#define END_INDEX                     0x007E
++
++#define CMD_IMG_SEND_REQ              0x9400
++
++#define CRC_TAB_SIZE                  256
++#define CRC_16_L_SEED                 0xFFFF
++
++struct c2c_device {
++      /* DPRAM memory addresses */
++      u16             *in_head_addr;
++      u16             *in_tail_addr;
++      u8              *in_buff_addr;
++      unsigned long   in_buff_size;
++
++      u16             *out_head_addr;
++      u16             *out_tail_addr;
++      u8              *out_buff_addr;
++      unsigned long   out_buff_size;
++
++      unsigned long   in_head_saved;
++      unsigned long   in_tail_saved;
++      unsigned long   out_head_saved;
++      unsigned long   out_tail_saved;
++
++      u16             mask_req_ack;
++      u16             mask_res_ack;
++      u16             mask_send;
++};
++
++struct memory_region {
++      u8 *control;
++      u8 *fmt_out;
++      u8 *raw_out;
++      u8 *fmt_in;
++      u8 *raw_in;
++      u8 *mbx;
++};
++
++struct UldDataHeader {
++      u8 bop;
++      u16 total_frame;
++      u16 curr_frame;
++      u16 len;
++};
++
++struct c2c_link_device {
++      struct link_device ld;
++
++      struct modem_data *pdata;
++
++      /*only c2c*/
++      struct wake_lock c2c_wake_lock;
++      atomic_t raw_txq_req_ack_rcvd;
++      atomic_t fmt_txq_req_ack_rcvd;
++      u8 net_stop_flag;
++      int phone_sync;
++      u8 phone_status;
++
++       struct work_struct xmit_work_struct;
++
++      struct workqueue_struct *gota_wq;
++      struct work_struct gota_cmd_work;
++
++      struct c2c_device dev_map[MAX_IDX];
++
++      struct wake_lock dumplock;
++
++      u8 c2c_read_data[131072];
++
++      int c2c_init_cmd_wait_condition;
++      wait_queue_head_t c2c_init_cmd_wait_q;
++
++      int modem_pif_init_wait_condition;
++      wait_queue_head_t modem_pif_init_done_wait_q;
++
++      struct completion gota_download_start_complete;
++
++      int gota_send_done_cmd_wait_condition;
++      wait_queue_head_t gota_send_done_cmd_wait_q;
++
++      int gota_update_done_cmd_wait_condition;
++      wait_queue_head_t gota_update_done_cmd_wait_q;
++
++      int upload_send_req_wait_condition;
++      wait_queue_head_t upload_send_req_wait_q;
++
++      int upload_send_done_wait_condition;
++      wait_queue_head_t upload_send_done_wait_q;
++
++      int upload_start_req_wait_condition;
++      wait_queue_head_t upload_start_req_wait_q;
++
++      int upload_packet_start_condition;
++      wait_queue_head_t upload_packet_start_wait_q;
++
++      u16 gota_irq_handler_cmd;
++
++      u16 c2c_dump_handler_cmd;
++
++      int dump_region_number;
++
++      unsigned int is_c2c_err ;
++
++      int c2c_dump_start;
++      int gota_start;
++
++      char c2c_err_buf[DPRAM_ERR_MSG_LEN];
++
++      struct fasync_struct *c2c_err_async_q;
++
++      void (*clear_interrupt)(struct c2c_link_device *);
++
++      struct memory_region m_region;
++
++      unsigned long  fmt_out_buff_size;
++      unsigned long  raw_out_buff_size;
++      unsigned long  fmt_in_buff_size;
++      unsigned long  raw_in_buff_size;
++
++      struct delayed_work delayed_tx;
++      struct sk_buff *delayed_skb;
++      u8 delayed_count;
++};
++
++/* converts from struct link_device* to struct xxx_link_device* */
++#define to_c2c_link_device(linkdev) \
++                      container_of(linkdev, struct c2c_link_device, ld)
++
++#endif
+diff --git a/drivers/misc/modem_if/modem_link_device_dpram.c b/drivers/misc/modem_if/modem_link_device_dpram.c
+new file mode 100644
+index 0000000..ea0b21e
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_link_device_dpram.c
+@@ -0,0 +1,2111 @@
++/*
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <linux/irq.h>
++#include <linux/gpio.h>
++#include <linux/time.h>
++#include <linux/interrupt.h>
++#include <linux/timer.h>
++#include <linux/wakelock.h>
++#include <linux/delay.h>
++#include <linux/wait.h>
++#include <linux/sched.h>
++#include <linux/vmalloc.h>
++#include <linux/if_arp.h>
++#include <linux/platform_device.h>
++#include <linux/kallsyms.h>
++#include <linux/platform_data/modem.h>
++
++#include "modem_prj.h"
++#include "modem_link_device_dpram.h"
++#include "modem_utils.h"
++
++/*
++** Function prototypes for basic DPRAM operations
++*/
++static inline void clear_intr(struct dpram_link_device *dpld);
++static inline u16 recv_intr(struct dpram_link_device *dpld);
++static inline void send_intr(struct dpram_link_device *dpld, u16 mask);
++
++static inline u16 get_magic(struct dpram_link_device *dpld);
++static inline void set_magic(struct dpram_link_device *dpld, u16 val);
++static inline u16 get_access(struct dpram_link_device *dpld);
++static inline void set_access(struct dpram_link_device *dpld, u16 val);
++
++static inline u32 get_tx_head(struct dpram_link_device *dpld, int id);
++static inline u32 get_tx_tail(struct dpram_link_device *dpld, int id);
++static inline void set_tx_head(struct dpram_link_device *dpld, int id, u32 in);
++static inline void set_tx_tail(struct dpram_link_device *dpld, int id, u32 out);
++static inline u8 *get_tx_buff(struct dpram_link_device *dpld, int id);
++static inline u32 get_tx_buff_size(struct dpram_link_device *dpld, int id);
++
++static inline u32 get_rx_head(struct dpram_link_device *dpld, int id);
++static inline u32 get_rx_tail(struct dpram_link_device *dpld, int id);
++static inline void set_rx_head(struct dpram_link_device *dpld, int id, u32 in);
++static inline void set_rx_tail(struct dpram_link_device *dpld, int id, u32 out);
++static inline u8 *get_rx_buff(struct dpram_link_device *dpld, int id);
++static inline u32 get_rx_buff_size(struct dpram_link_device *dpld, int id);
++
++static inline u16 get_mask_req_ack(struct dpram_link_device *dpld, int id);
++static inline u16 get_mask_res_ack(struct dpram_link_device *dpld, int id);
++static inline u16 get_mask_send(struct dpram_link_device *dpld, int id);
++
++static inline void reset_tx_circ(struct dpram_link_device *dpld, int dev);
++static inline void reset_rx_circ(struct dpram_link_device *dpld, int dev);
++
++static int trigger_force_cp_crash(struct dpram_link_device *dpld);
++
++#ifndef CONFIG_SAMSUNG_PRODUCT_SHIP
++static inline void log_dpram_status(struct dpram_link_device *dpld, char *str)
++{
++      struct utc_time utc;
++
++      get_utc_time(&utc);
++
++      pr_info("%s%s: %s: [%02d:%02d:%02d.%03d] "
++              "ACC{%X %d} FMT{TI:%u TO:%u RI:%u RO:%u} "
++              "RAW{TI:%u TO:%u RI:%u RO:%u} INTR{0x%X}\n",
++              LOG_TAG, dpld->ld.mc->name, str,
++              utc.hour, utc.min, utc.sec, utc.msec,
++              get_magic(dpld), get_access(dpld),
++              get_tx_head(dpld, IPC_FMT), get_tx_tail(dpld, IPC_FMT),
++              get_rx_head(dpld, IPC_FMT), get_rx_tail(dpld, IPC_FMT),
++              get_tx_head(dpld, IPC_RAW), get_tx_tail(dpld, IPC_RAW),
++              get_rx_head(dpld, IPC_RAW), get_rx_tail(dpld, IPC_RAW),
++              recv_intr(dpld));
++}
++
++static void pr_trace(struct dpram_link_device *dpld, int dev,
++                      struct timespec *ts, u8 *buff, u32 rcvd)
++{
++      struct link_device *ld = &dpld->ld;
++      struct utc_time utc;
++
++      ts2utc(ts, &utc);
++
++      pr_info("%s[%d-%02d-%02d %02d:%02d:%02d.%03d] %s trace (%s)\n",
++              LOG_TAG, utc.year, utc.mon, utc.day, utc.hour, utc.min, utc.sec,
++              utc.msec, get_dev_name(dev), ld->name);
++
++      mif_print_dump(buff, rcvd, 4);
++
++      return;
++}
++
++static void save_dpram_dump_work(struct work_struct *work)
++{
++      struct dpram_link_device *dpld;
++      struct link_device *ld;
++      struct trace_queue *trq;
++      struct trace_data *trd;
++      struct file *fp;
++      struct timespec *ts;
++      u8 *dump;
++      int rcvd;
++      char *path;
++      struct utc_time utc;
++
++      dpld = container_of(work, struct dpram_link_device, dump_dwork.work);
++      ld = &dpld->ld;
++      trq = &dpld->dump_list;
++      path = dpld->dump_path;
++
++      while (1) {
++              trd = trq_get_data_slot(trq);
++              if (!trd)
++                      break;
++
++              ts = &trd->ts;
++              dump = trd->data;
++              rcvd = trd->size;
++
++              ts2utc(ts, &utc);
++              snprintf(path, MIF_MAX_PATH_LEN,
++                      "%s/%s_dump_%d%02d%02d-%02d%02d%02d",
++                      MIF_LOG_DIR, ld->name, utc.year, utc.mon, utc.day,
++                      utc.hour, utc.min, utc.sec);
++
++              fp = mif_open_file(path);
++              if (fp) {
++                      mif_save_file(fp, dump, rcvd);
++                      mif_close_file(fp);
++              } else {
++                      mif_err("%s: ERR! %s open fail\n", ld->name, path);
++                      mif_print_dump(dump, rcvd, 16);
++              }
++
++              kfree(dump);
++      }
++}
++
++static void save_dpram_dump(struct dpram_link_device *dpld)
++{
++      struct link_device *ld = &dpld->ld;
++      struct trace_data *trd;
++      u8 *buff;
++      struct timespec ts;
++
++      buff = kzalloc(dpld->size, GFP_ATOMIC);
++      if (!buff) {
++              mif_err("%s: ERR! kzalloc fail\n", ld->name);
++              return;
++      }
++
++      getnstimeofday(&ts);
++
++      memcpy(buff, dpld->base, dpld->size);
++
++      trd = trq_get_free_slot(&dpld->dump_list);
++      if (!trd) {
++              mif_err("%s: ERR! trq_get_free_slot fail\n", ld->name);
++              mif_print_dump(buff, dpld->size, 16);
++              kfree(buff);
++              return;
++      }
++
++      memcpy(&trd->ts, &ts, sizeof(struct timespec));
++      trd->data = buff;
++      trd->size = dpld->size;
++
++      queue_delayed_work(system_nrt_wq, &dpld->dump_dwork, 0);
++}
++
++static void save_ipc_trace_work(struct work_struct *work)
++{
++      struct dpram_link_device *dpld;
++      struct link_device *ld;
++      struct trace_queue *trq;
++      struct trace_data *trd;
++      struct file *fp;
++      struct timespec *ts;
++      int dev;
++      u8 *dump;
++      int rcvd;
++      u8 *buff;
++      char *path;
++      struct utc_time utc;
++
++      dpld = container_of(work, struct dpram_link_device, trace_dwork.work);
++      ld = &dpld->ld;
++      trq = &dpld->trace_list;
++      path = dpld->trace_path;
++
++      buff = kzalloc(dpld->size << 3, GFP_KERNEL);
++      if (!buff) {
++              while (1) {
++                      trd = trq_get_data_slot(trq);
++                      if (!trd)
++                              break;
++
++                      ts = &trd->ts;
++                      dev = trd->dev;
++                      dump = trd->data;
++                      rcvd = trd->size;
++                      pr_trace(dpld, dev, ts, dump, rcvd);
++
++                      kfree(dump);
++              }
++              return;
++      }
++
++      while (1) {
++              trd = trq_get_data_slot(trq);
++              if (!trd)
++                      break;
++
++              ts = &trd->ts;
++              dev = trd->dev;
++              dump = trd->data;
++              rcvd = trd->size;
++
++              ts2utc(ts, &utc);
++              snprintf(path, MIF_MAX_PATH_LEN,
++                      "%s/%s_%s_%d%02d%02d-%02d%02d%02d",
++                      MIF_LOG_DIR, ld->name, get_dev_name(dev),
++                      utc.year, utc.mon, utc.day, utc.hour, utc.min, utc.sec);
++
++              fp = mif_open_file(path);
++              if (fp) {
++                      int len;
++
++                      snprintf(buff, MIF_MAX_PATH_LEN,
++                              "[%d-%02d-%02d %02d:%02d:%02d.%03d]\n",
++                              utc.year, utc.mon, utc.day, utc.hour, utc.min,
++                              utc.sec, utc.msec);
++                      len = strlen(buff);
++                      mif_dump2format4(dump, rcvd, (buff + len), NULL);
++                      strcat(buff, "\n");
++                      len = strlen(buff);
++
++                      mif_save_file(fp, buff, len);
++
++                      memset(buff, 0, len);
++                      mif_close_file(fp);
++              } else {
++                      mif_err("%s: %s open fail\n", ld->name, path);
++                      pr_trace(dpld, dev, ts, dump, rcvd);
++              }
++
++              kfree(dump);
++      }
++
++      kfree(buff);
++}
++
++static void print_ipc_trace(struct dpram_link_device *dpld, int dev,
++                      u8 __iomem *src, u32 qsize, u32 in, u32 out, u32 rcvd)
++{
++      u8 *buff = dpld->buff;
++      struct timespec ts;
++
++      getnstimeofday(&ts);
++
++      memset(buff, 0, dpld->size);
++      circ_read(buff, src, qsize, out, rcvd);
++
++      pr_trace(dpld, dev, &ts, buff, rcvd);
++}
++
++static void save_ipc_trace(struct dpram_link_device *dpld, int dev,
++                      u8 __iomem *src, u32 qsize, u32 in, u32 out, u32 rcvd)
++{
++      struct link_device *ld = &dpld->ld;
++      struct trace_data *trd;
++      u8 *buff;
++      struct timespec ts;
++
++      buff = kzalloc(rcvd, GFP_ATOMIC);
++      if (!buff) {
++              mif_err("%s: %s: ERR! kzalloc fail\n",
++                      ld->name, get_dev_name(dev));
++              print_ipc_trace(dpld, dev, src, qsize, in, out, rcvd);
++              return;
++      }
++
++      getnstimeofday(&ts);
++
++      circ_read(buff, src, qsize, out, rcvd);
++
++      trd = trq_get_free_slot(&dpld->trace_list);
++      if (!trd) {
++              mif_err("%s: %s: ERR! trq_get_free_slot fail\n",
++                      ld->name, get_dev_name(dev));
++              pr_trace(dpld, dev, &ts, buff, rcvd);
++              kfree(buff);
++              return;
++      }
++
++      memcpy(&trd->ts, &ts, sizeof(struct timespec));
++      trd->dev = dev;
++      trd->data = buff;
++      trd->size = rcvd;
++
++      queue_delayed_work(system_nrt_wq, &dpld->trace_dwork, 0);
++}
++#endif
++
++static void set_dpram_map(struct dpram_link_device *dpld,
++                      struct mif_irq_map *map)
++{
++      map->magic = get_magic(dpld);
++      map->access = get_access(dpld);
++
++      map->fmt_tx_in = get_tx_head(dpld, IPC_FMT);
++      map->fmt_tx_out = get_tx_tail(dpld, IPC_FMT);
++      map->fmt_rx_in = get_rx_head(dpld, IPC_FMT);
++      map->fmt_rx_out = get_rx_tail(dpld, IPC_FMT);
++      map->raw_tx_in = get_tx_head(dpld, IPC_RAW);
++      map->raw_tx_out = get_tx_tail(dpld, IPC_RAW);
++      map->raw_rx_in = get_rx_head(dpld, IPC_RAW);
++      map->raw_rx_out = get_rx_tail(dpld, IPC_RAW);
++
++      map->cp2ap = recv_intr(dpld);
++}
++
++/*
++** DPRAM operations
++*/
++static int register_isr(unsigned irq, irqreturn_t (*isr)(int, void*),
++                              unsigned long flag, const char *name,
++                              struct dpram_link_device *dpld)
++{
++      int ret;
++
++      ret = request_irq(irq, isr, flag, name, dpld);
++      if (ret) {
++              mif_info("%s: ERR! request_irq fail (err %d)\n", name, ret);
++              return ret;
++      }
++
++      ret = enable_irq_wake(irq);
++      if (ret)
++              mif_info("%s: ERR! enable_irq_wake fail (err %d)\n", name, ret);
++
++      mif_info("%s (#%d) handler registered\n", name, irq);
++
++      return 0;
++}
++
++static inline void clear_intr(struct dpram_link_device *dpld)
++{
++      if (likely(dpld->need_intr_clear))
++              dpld->ext_op->clear_intr(dpld);
++}
++
++static inline u16 recv_intr(struct dpram_link_device *dpld)
++{
++      return ioread16(dpld->mbx2ap);
++}
++
++static inline void send_intr(struct dpram_link_device *dpld, u16 mask)
++{
++      iowrite16(mask, dpld->mbx2cp);
++}
++
++static inline u16 get_magic(struct dpram_link_device *dpld)
++{
++      return ioread16(dpld->magic);
++}
++
++static inline void set_magic(struct dpram_link_device *dpld, u16 val)
++{
++      iowrite16(val, dpld->magic);
++}
++
++static inline u16 get_access(struct dpram_link_device *dpld)
++{
++      return ioread16(dpld->access);
++}
++
++static inline void set_access(struct dpram_link_device *dpld, u16 val)
++{
++      iowrite16(val, dpld->access);
++}
++
++static inline u32 get_tx_head(struct dpram_link_device *dpld, int id)
++{
++      return ioread16(dpld->dev[id]->txq.head);
++}
++
++static inline u32 get_tx_tail(struct dpram_link_device *dpld, int id)
++{
++      return ioread16(dpld->dev[id]->txq.tail);
++}
++
++static inline void set_tx_head(struct dpram_link_device *dpld, int id, u32 in)
++{
++      int cnt = 0;
++      u32 val = 0;
++
++      iowrite16((u16)in, dpld->dev[id]->txq.head);
++
++      while (1) {
++              /* Check head value written */
++              val = ioread16(dpld->dev[id]->txq.head);
++              if (likely(val == in))
++                      return;
++
++              cnt++;
++              mif_err("ERR: %s txq.head(%d) != in(%d), count %d\n",
++                      get_dev_name(id), val, in, cnt);
++              if (cnt >= MAX_RETRY_CNT)
++                      break;
++
++              /* Write head value again */
++              udelay(100);
++              iowrite16((u16)in, dpld->dev[id]->txq.head);
++      }
++
++      trigger_force_cp_crash(dpld);
++}
++
++static inline void set_tx_tail(struct dpram_link_device *dpld, int id, u32 out)
++{
++      int cnt = 0;
++      u32 val = 0;
++
++      iowrite16((u16)out, dpld->dev[id]->txq.tail);
++
++      while (1) {
++              /* Check tail value written */
++              val = ioread16(dpld->dev[id]->txq.tail);
++              if (likely(val == out))
++                      return;
++
++              cnt++;
++              mif_err("ERR: %s txq.tail(%d) != out(%d), count %d\n",
++                      get_dev_name(id), val, out, cnt);
++              if (cnt >= MAX_RETRY_CNT)
++                      break;
++
++              /* Write tail value again */
++              udelay(100);
++              iowrite16((u16)out, dpld->dev[id]->txq.tail);
++      }
++
++      trigger_force_cp_crash(dpld);
++}
++
++static inline u8 *get_tx_buff(struct dpram_link_device *dpld, int id)
++{
++      return dpld->dev[id]->txq.buff;
++}
++
++static inline u32 get_tx_buff_size(struct dpram_link_device *dpld, int id)
++{
++      return dpld->dev[id]->txq.size;
++}
++
++static inline u32 get_rx_head(struct dpram_link_device *dpld, int id)
++{
++      return ioread16(dpld->dev[id]->rxq.head);
++}
++
++static inline u32 get_rx_tail(struct dpram_link_device *dpld, int id)
++{
++      return ioread16(dpld->dev[id]->rxq.tail);
++}
++
++static inline void set_rx_head(struct dpram_link_device *dpld, int id, u32 in)
++{
++      int cnt = 0;
++      u32 val = 0;
++
++      iowrite16((u16)in, dpld->dev[id]->rxq.head);
++
++      while (1) {
++              /* Check head value written */
++              val = ioread16(dpld->dev[id]->rxq.head);
++              if (val == in)
++                      return;
++
++              cnt++;
++              mif_err("ERR: %s rxq.head(%d) != in(%d), count %d\n",
++                      get_dev_name(id), val, in, cnt);
++              if (cnt >= MAX_RETRY_CNT)
++                      break;
++
++              /* Write head value again */
++              udelay(100);
++              iowrite16((u16)in, dpld->dev[id]->rxq.head);
++      }
++
++      trigger_force_cp_crash(dpld);
++}
++
++static inline void set_rx_tail(struct dpram_link_device *dpld, int id, u32 out)
++{
++      int cnt = 0;
++      u32 val = 0;
++
++      iowrite16((u16)out, dpld->dev[id]->rxq.tail);
++
++      while (1) {
++              /* Check tail value written */
++              val = ioread16(dpld->dev[id]->rxq.tail);
++              if (val == out)
++                      return;
++
++              cnt++;
++              mif_err("ERR: %s rxq.tail(%d) != out(%d), count %d\n",
++                      get_dev_name(id), val, out, cnt);
++              if (cnt >= MAX_RETRY_CNT)
++                      break;
++
++              /* Write tail value again */
++              udelay(100);
++              iowrite16((u16)out, dpld->dev[id]->rxq.tail);
++      }
++
++      trigger_force_cp_crash(dpld);
++}
++
++static inline u8 *get_rx_buff(struct dpram_link_device *dpld, int id)
++{
++      return dpld->dev[id]->rxq.buff;
++}
++
++static inline u32 get_rx_buff_size(struct dpram_link_device *dpld, int id)
++{
++      return dpld->dev[id]->rxq.size;
++}
++
++static inline u16 get_mask_req_ack(struct dpram_link_device *dpld, int id)
++{
++      return dpld->dev[id]->mask_req_ack;
++}
++
++static inline u16 get_mask_res_ack(struct dpram_link_device *dpld, int id)
++{
++      return dpld->dev[id]->mask_res_ack;
++}
++
++static inline u16 get_mask_send(struct dpram_link_device *dpld, int id)
++{
++      return dpld->dev[id]->mask_send;
++}
++
++/* Get free space in the TXQ as well as in & out pointers */
++static int get_txq_space(struct dpram_link_device *dpld, int dev, u32 qsize,
++                      u32 *in, u32 *out)
++{
++      struct link_device *ld = &dpld->ld;
++      int cnt = 0;
++      u32 head;
++      u32 tail;
++      int space;
++
++      while (1) {
++              head = get_tx_head(dpld, dev);
++              tail = get_tx_tail(dpld, dev);
++
++              space = circ_get_space(qsize, head, tail);
++              mif_debug("%s: %s_TXQ qsize[%u] in[%u] out[%u] space[%u]\n",
++                      ld->name, get_dev_name(dev), qsize, head, tail, space);
++
++              if (circ_valid(qsize, head, tail)) {
++                      *in = head;
++                      *out = tail;
++                      return space;
++              }
++
++              cnt++;
++              mif_err("%s: ERR! <%pf> "
++                      "%s_TXQ invalid (size:%d in:%d out:%d), count %d\n",
++                      ld->name, __builtin_return_address(0),
++                      get_dev_name(dev), qsize, head, tail, cnt);
++              if (cnt >= MAX_RETRY_CNT)
++                      break;
++
++              udelay(100);
++      }
++
++      *in = 0;
++      *out = 0;
++      return -EINVAL;
++}
++
++/* Get data size in the RXQ as well as in & out pointers */
++static int get_rxq_rcvd(struct dpram_link_device *dpld, int dev, u32 qsize,
++                      u32 *in, u32 *out)
++{
++      struct link_device *ld = &dpld->ld;
++      int cnt = 0;
++      u32 head;
++      u32 tail;
++      u32 rcvd;
++
++      while (1) {
++              head = get_rx_head(dpld, dev);
++              tail = get_rx_tail(dpld, dev);
++              if (head == tail) {
++                      *in = head;
++                      *out = tail;
++                      return 0;
++              }
++
++              rcvd = circ_get_usage(qsize, head, tail);
++              mif_debug("%s: %s_RXQ qsize[%u] in[%u] out[%u] rcvd[%u]\n",
++                      ld->name, get_dev_name(dev), qsize, head, tail, rcvd);
++
++              if (circ_valid(qsize, head, tail)) {
++                      *in = head;
++                      *out = tail;
++                      return rcvd;
++              }
++
++              cnt++;
++              mif_err("%s: ERR! <%pf> "
++                      "%s_RXQ invalid (size:%d in:%d out:%d), count %d\n",
++                      ld->name, __builtin_return_address(0),
++                      get_dev_name(dev), qsize, head, tail, cnt);
++              if (cnt >= MAX_RETRY_CNT)
++                      break;
++
++              udelay(100);
++      }
++
++      *in = 0;
++      *out = 0;
++      return -EINVAL;
++}
++
++static inline void reset_tx_circ(struct dpram_link_device *dpld, int dev)
++{
++      set_tx_head(dpld, dev, 0);
++      set_tx_tail(dpld, dev, 0);
++      if (dev == IPC_FMT)
++              trigger_force_cp_crash(dpld);
++}
++
++static inline void reset_rx_circ(struct dpram_link_device *dpld, int dev)
++{
++#ifndef CONFIG_SAMSUNG_PRODUCT_SHIP
++      trigger_force_cp_crash(dpld);
++#else
++      set_rx_tail(dpld, dev, get_rx_head(dpld, dev));
++      if (dev == IPC_FMT)
++              trigger_force_cp_crash(dpld);
++#endif
++}
++
++/*
++** CAUTION : dpram_allow_sleep() MUST be invoked after dpram_wake_up() success
++*/
++static inline bool dpram_can_sleep(struct dpram_link_device *dpld)
++{
++      return dpld->need_wake_up;
++}
++
++static int dpram_wake_up(struct dpram_link_device *dpld)
++{
++      struct link_device *ld = &dpld->ld;
++
++      if (unlikely(!dpram_can_sleep(dpld)))
++              return 0;
++
++      if (dpld->ext_op->wakeup(dpld) < 0) {
++              mif_err("%s: ERR! <%pf> DPRAM wakeup fail once\n",
++                      ld->name, __builtin_return_address(0));
++
++              dpld->ext_op->sleep(dpld);
++
++              udelay(10);
++
++              if (dpld->ext_op->wakeup(dpld) < 0) {
++                      mif_err("%s: ERR! <%pf> DPRAM wakeup fail twice\n",
++                              ld->name, __builtin_return_address(0));
++                      return -EACCES;
++              }
++      }
++
++      atomic_inc(&dpld->accessing);
++      return 0;
++}
++
++static void dpram_allow_sleep(struct dpram_link_device *dpld)
++{
++      struct link_device *ld = &dpld->ld;
++
++      if (unlikely(!dpram_can_sleep(dpld)))
++              return;
++
++      if (atomic_dec_return(&dpld->accessing) <= 0) {
++              dpld->ext_op->sleep(dpld);
++              atomic_set(&dpld->accessing, 0);
++              mif_debug("%s: DPRAM sleep possible\n", ld->name);
++      }
++}
++
++static int check_access(struct dpram_link_device *dpld)
++{
++      struct link_device *ld = &dpld->ld;
++      int i;
++      u16 magic = get_magic(dpld);
++      u16 access = get_access(dpld);
++
++      if (likely(magic == DPRAM_MAGIC_CODE && access == 1))
++              return 0;
++
++      for (i = 1; i <= 100; i++) {
++              mif_info("%s: ERR! magic:%X access:%X -> retry:%d\n",
++                      ld->name, magic, access, i);
++              udelay(100);
++
++              magic = get_magic(dpld);
++              access = get_access(dpld);
++              if (likely(magic == DPRAM_MAGIC_CODE && access == 1))
++                      return 0;
++      }
++
++      mif_info("%s: !CRISIS! magic:%X access:%X\n", ld->name, magic, access);
++      return -EACCES;
++}
++
++static bool ipc_active(struct dpram_link_device *dpld)
++{
++      struct link_device *ld = &dpld->ld;
++
++      /* Check DPRAM mode */
++      if (ld->mode != LINK_MODE_IPC) {
++              mif_info("%s: <%pf> ld->mode != LINK_MODE_IPC\n",
++                      ld->name, __builtin_return_address(0));
++              return false;
++      }
++
++      if (check_access(dpld) < 0) {
++              mif_info("%s: ERR! <%pf> check_access fail\n",
++                      ld->name, __builtin_return_address(0));
++              return false;
++      }
++
++      return true;
++}
++
++static void dpram_ipc_write(struct dpram_link_device *dpld, int dev, u32 qsize,
++                      u32 in, u32 out, struct sk_buff *skb)
++{
++      struct link_device *ld = &dpld->ld;
++      u8 __iomem *buff = get_tx_buff(dpld, dev);
++      u8 *src = skb->data;
++      u32 len = skb->len;
++      u32 inp;
++      struct mif_irq_map map;
++
++      circ_write(buff, src, qsize, in, len);
++
++      /* update new in pointer */
++      inp = in + len;
++      if (inp >= qsize)
++              inp -= qsize;
++      set_tx_head(dpld, dev, inp);
++
++      if (dev == IPC_FMT) {
++#ifndef CONFIG_SAMSUNG_PRODUCT_SHIP
++              char tag[MIF_MAX_STR_LEN];
++              snprintf(tag, MIF_MAX_STR_LEN, "%s: MIF2CP", ld->mc->name);
++              pr_ipc(tag, src, (len > 20 ? 20 : len));
++              log_dpram_status(dpld, "MIF2CP");
++#endif
++              set_dpram_map(dpld, &map);
++              mif_irq_log(ld->mc->msd, map, "ipc_write", sizeof("ipc_write"));
++              mif_ipc_log(MIF_IPC_AP2CP, ld->mc->msd, skb->data, skb->len);
++      }
++
++#if 1
++      if (ld->aligned && memcmp16_to_io((buff + in), src, 4)) {
++              mif_err("%s: memcmp16_to_io fail\n", ld->name);
++              trigger_force_cp_crash(dpld);
++      }
++#endif
++}
++
++static int dpram_ipc_tx(struct dpram_link_device *dpld, int dev)
++{
++      struct link_device *ld = &dpld->ld;
++      struct sk_buff_head *txq = ld->skb_txq[dev];
++      struct sk_buff *skb;
++      unsigned long int flags;
++      u32 qsize = get_tx_buff_size(dpld, dev);
++      u32 in;
++      u32 out;
++      int space;
++      int copied = 0;
++
++      spin_lock_irqsave(&dpld->tx_lock[dev], flags);
++
++      while (1) {
++              space = get_txq_space(dpld, dev, qsize, &in, &out);
++              if (unlikely(space < 0)) {
++                      spin_unlock_irqrestore(&dpld->tx_lock[dev], flags);
++                      reset_tx_circ(dpld, dev);
++                      return space;
++              }
++
++              skb = skb_dequeue(txq);
++              if (unlikely(!skb))
++                      break;
++
++              if (unlikely(space < skb->len)) {
++                      atomic_set(&dpld->res_required[dev], 1);
++                      skb_queue_head(txq, skb);
++                      spin_unlock_irqrestore(&dpld->tx_lock[dev], flags);
++                      mif_info("%s: %s "
++                              "qsize[%u] in[%u] out[%u] free[%u] < len[%u]\n",
++                              ld->name, get_dev_name(dev),
++                              qsize, in, out, space, skb->len);
++                      return -ENOSPC;
++              }
++
++              /* TX if there is enough room in the queue */
++              dpram_ipc_write(dpld, dev, qsize, in, out, skb);
++              copied += skb->len;
++              dev_kfree_skb_any(skb);
++      }
++
++      spin_unlock_irqrestore(&dpld->tx_lock[dev], flags);
++
++      return copied;
++}
++
++static int dpram_wait_for_res_ack(struct dpram_link_device *dpld, int dev)
++{
++      struct link_device *ld = &dpld->ld;
++      struct completion *cmpl = &dpld->res_ack_cmpl[dev];
++      unsigned long timeout = RES_ACK_WAIT_TIMEOUT;
++      int ret;
++      u16 mask;
++
++      mask = get_mask_req_ack(dpld, dev);
++      mif_info("%s: Send REQ_ACK 0x%04X\n", ld->name, mask);
++      send_intr(dpld, INT_NON_CMD(mask));
++
++      ret = wait_for_completion_interruptible_timeout(cmpl, timeout);
++      /* ret == 0 on timeout, ret < 0 if interrupted */
++      if (ret == 0) {
++              mif_err("%s: %s: TIMEOUT\n", ld->name, get_dev_name(dev));
++              queue_delayed_work(ld->tx_wq, ld->tx_dwork[dev], 0);
++      } else if (ret < 0) {
++              mif_err("%s: %s: interrupted (ret %d)\n",
++                      ld->name, get_dev_name(dev), ret);
++      }
++
++      return ret;
++}
++
++static int dpram_process_res_ack(struct dpram_link_device *dpld, int dev)
++{
++      struct link_device *ld = &dpld->ld;
++      int ret;
++      u16 mask;
++
++      ret = dpram_ipc_tx(dpld, dev);
++      if (ret < 0) {
++              if (ret == -ENOSPC) {
++                      /* dpld->res_required[dev] is set in dpram_ipc_tx() */
++                      queue_delayed_work(ld->tx_wq, ld->tx_dwork[dev], 0);
++              } else {
++                      mif_err("%s: ERR! ipc_tx fail (%d)\n", ld->name, ret);
++              }
++      } else {
++              if (ret > 0) {
++                      mask = get_mask_send(dpld, dev);
++                      send_intr(dpld, INT_NON_CMD(mask));
++                      mif_debug("%s: send intr 0x%04X\n", ld->name, mask);
++              }
++              atomic_set(&dpld->res_required[dev], 0);
++      }
++
++      return ret;
++}
++
++static void dpram_fmt_tx_work(struct work_struct *work)
++{
++      struct link_device *ld;
++      struct dpram_link_device *dpld;
++      int ret;
++
++      ld = container_of(work, struct link_device, fmt_tx_dwork.work);
++      dpld = to_dpram_link_device(ld);
++
++      ret = dpram_wait_for_res_ack(dpld, IPC_FMT);
++      /* ret == 0 on timeout, ret < 0 if interrupted */
++      if (ret <= 0)
++              return;
++
++      ret = dpram_process_res_ack(dpld, IPC_FMT);
++}
++
++static void dpram_raw_tx_work(struct work_struct *work)
++{
++      struct link_device *ld;
++      struct dpram_link_device *dpld;
++      int ret;
++
++      ld = container_of(work, struct link_device, raw_tx_dwork.work);
++      dpld = to_dpram_link_device(ld);
++
++      ret = dpram_wait_for_res_ack(dpld, IPC_RAW);
++      /* ret == 0 on timeout, ret < 0 if interrupted */
++      if (ret <= 0)
++              return;
++
++      ret = dpram_process_res_ack(dpld, IPC_RAW);
++      if (ret > 0)
++              mif_netif_wake(ld);
++}
++
++static void dpram_rfs_tx_work(struct work_struct *work)
++{
++      struct link_device *ld;
++      struct dpram_link_device *dpld;
++      int ret;
++
++      ld = container_of(work, struct link_device, rfs_tx_dwork.work);
++      dpld = to_dpram_link_device(ld);
++
++      ret = dpram_wait_for_res_ack(dpld, IPC_RFS);
++      /* ret == 0 on timeout, ret < 0 if interrupted */
++      if (ret <= 0)
++              return;
++
++      ret = dpram_process_res_ack(dpld, IPC_RFS);
++}
++
++static void dpram_ipc_rx_task(unsigned long data)
++{
++      struct dpram_link_device *dpld = (struct dpram_link_device *)data;
++      struct link_device *ld = &dpld->ld;
++      struct io_device *iod;
++      struct mif_rxb *rxb;
++      unsigned qlen;
++      int i;
++
++      for (i = 0; i < ld->max_ipc_dev; i++) {
++              iod = dpld->iod[i];
++              qlen = rxbq_size(&dpld->rxbq[i]);
++              while (qlen > 0) {
++                      rxb = rxbq_get_data_rxb(&dpld->rxbq[i]);
++                      iod->recv(iod, ld, rxb->data, rxb->len);
++                      rxb_clear(rxb);
++                      qlen--;
++              }
++      }
++}
++
++/*
++  ret < 0  : error
++  ret == 0 : no data
++  ret > 0  : valid data
++*/
++static int dpram_recv_ipc_with_rxb(struct dpram_link_device *dpld, int dev)
++{
++      struct link_device *ld = &dpld->ld;
++      struct mif_rxb *rxb;
++      u8 __iomem *src = get_rx_buff(dpld, dev);
++      u32 qsize = get_rx_buff_size(dpld, dev);
++      u32 in;
++      u32 out;
++      u32 rcvd;
++      struct mif_irq_map map;
++
++      rcvd = get_rxq_rcvd(dpld, dev, qsize, &in, &out);
++      if (rcvd <= 0)
++              return rcvd;
++
++      if (dev == IPC_FMT) {
++              set_dpram_map(dpld, &map);
++              mif_irq_log(ld->mc->msd, map, "ipc_recv", sizeof("ipc_recv"));
++      }
++
++      /* Allocate an rxb */
++      rxb = rxbq_get_free_rxb(&dpld->rxbq[dev]);
++      if (!rxb) {
++              mif_info("%s: ERR! %s rxbq_get_free_rxb fail\n",
++                      ld->name, get_dev_name(dev));
++              return -ENOMEM;
++      }
++
++      /* Read data from each DPRAM buffer */
++      circ_read(rxb_put(rxb, rcvd), src, qsize, out, rcvd);
++
++      /* Update tail (out) pointer */
++      set_rx_tail(dpld, dev, in);
++
++      return rcvd;
++}
++
++/*
++  ret < 0  : error
++  ret == 0 : no data
++  ret > 0  : valid data
++*/
++static int dpram_recv_ipc_with_skb(struct dpram_link_device *dpld, int dev)
++{
++      struct link_device *ld = &dpld->ld;
++      struct io_device *iod = dpld->iod[dev];
++      struct sk_buff *skb;
++      u8 __iomem *src = get_rx_buff(dpld, dev);
++      u32 qsize = get_rx_buff_size(dpld, dev);
++      u32 in;
++      u32 out;
++      u32 rcvd;
++      int rest;
++      u8 *frm;
++      u8 *dst;
++      unsigned int len;
++      unsigned int pad;
++      unsigned int tot;
++      struct mif_irq_map map;
++
++      rcvd = get_rxq_rcvd(dpld, dev, qsize, &in, &out);
++      if (rcvd <= 0)
++              return rcvd;
++
++      if (dev == IPC_FMT) {
++#ifndef CONFIG_SAMSUNG_PRODUCT_SHIP
++              log_dpram_status(dpld, "CP2MIF");
++#endif
++              set_dpram_map(dpld, &map);
++              mif_irq_log(ld->mc->msd, map, "ipc_recv", sizeof("ipc_recv"));
++      }
++
++      rest = rcvd;
++      while (rest > 0) {
++              /* Calculate the start of an SIPC5 frame */
++              frm = src + out;
++
++              /* Check the SIPC5 frame */
++              len = sipc5_check_frame_in_dev(ld, dev, frm, rest);
++              if (len <= 0) {
++#ifndef CONFIG_SAMSUNG_PRODUCT_SHIP
++                      u32 tail = get_rx_tail(dpld, dev);
++                      log_dpram_status(dpld, "CP2MIF");
++                      save_ipc_trace(dpld, dev, src, qsize, in, tail, rcvd);
++                      save_dpram_dump(dpld);
++#endif
++                      return -EBADMSG;
++              }
++
++              /* Calculate total length with padding in DPRAM */
++              pad = sipc5_calc_padding_size(len);
++              tot = len + pad;
++
++              /* Allocate an skb */
++              skb = dev_alloc_skb(tot);
++              if (!skb) {
++                      mif_err("%s: ERR! %s dev_alloc_skb fail\n",
++                              ld->name, get_dev_name(dev));
++                      return -ENOMEM;
++              }
++
++              /* Read data from each DPRAM buffer */
++              dst = skb_put(skb, tot);
++              circ_read(dst, src, qsize, out, tot);
++              skb_trim(skb, len);
++#if 1
++              if (ld->aligned && memcmp16_to_io((src + out), dst, 4)) {
++                      mif_err("%s: memcmp16_to_io fail\n", ld->name);
++                      trigger_force_cp_crash(dpld);
++              }
++#endif
++#ifndef CONFIG_SAMSUNG_PRODUCT_SHIP
++              if (unlikely(dev == IPC_FMT)) {
++                      char str[MIF_MAX_STR_LEN];
++                      snprintf(str, MIF_MAX_STR_LEN, "%s: CP2MIF",
++                              ld->mc->name);
++                      pr_ipc(str, skb->data, (skb->len > 20 ? 20 : skb->len));
++              }
++#endif
++
++              /* Pass the IPC frame to IOD */
++              iod->recv_skb(iod, ld, skb);
++
++              /* Calculate new 'out' pointer */
++              rest -= tot;
++              out += tot;
++              if (out >= qsize)
++                      out -= qsize;
++      }
++
++      /* Update tail (out) pointer */
++      set_rx_tail(dpld, dev, in);
++
++      return rcvd;
++}
++
++static void non_command_handler(struct dpram_link_device *dpld, u16 intr)
++{
++      struct link_device *ld = &dpld->ld;
++      int i = 0;
++      int ret = 0;
++      u16 mask = 0;
++
++      if (!ipc_active(dpld))
++              return;
++
++      /* Read data from DPRAM */
++      for (i = 0; i < ld->max_ipc_dev; i++) {
++              if (dpld->use_skb)
++                      ret = dpram_recv_ipc_with_skb(dpld, i);
++              else
++                      ret = dpram_recv_ipc_with_rxb(dpld, i);
++              if (ret < 0)
++                      reset_rx_circ(dpld, i);
++
++              /* Check and process REQ_ACK (at this time, in == out) */
++              if (intr & get_mask_req_ack(dpld, i)) {
++                      mif_debug("%s: send %s_RES_ACK\n",
++                              ld->name, get_dev_name(i));
++                      mask |= get_mask_res_ack(dpld, i);
++              }
++      }
++
++      if (!dpld->use_skb) {
++              /* Schedule soft IRQ for RX */
++              tasklet_hi_schedule(&dpld->rx_tsk);
++      }
++
++      if (mask) {
++              send_intr(dpld, INT_NON_CMD(mask));
++              mif_debug("%s: send intr 0x%04X\n", ld->name, mask);
++      }
++
++      if (intr && INT_MASK_RES_ACK_SET) {
++              if (intr && INT_MASK_RES_ACK_R)
++                      complete_all(&dpld->res_ack_cmpl[IPC_RAW]);
++              else if (intr && INT_MASK_RES_ACK_F)
++                      complete_all(&dpld->res_ack_cmpl[IPC_FMT]);
++              else
++                      complete_all(&dpld->res_ack_cmpl[IPC_RFS]);
++      }
++}
++
++static void handle_cp_crash(struct dpram_link_device *dpld)
++{
++      struct link_device *ld = &dpld->ld;
++      struct io_device *iod;
++      int i;
++
++      mif_netif_stop(ld);
++
++      for (i = 0; i < ld->max_ipc_dev; i++) {
++              mif_info("%s: purging %s_skb_txq\n", ld->name, get_dev_name(i));
++              skb_queue_purge(ld->skb_txq[i]);
++      }
++
++      iod = link_get_iod_with_format(ld, IPC_FMT);
++      iod->modem_state_changed(iod, STATE_CRASH_EXIT);
++
++      iod = link_get_iod_with_format(ld, IPC_BOOT);
++      iod->modem_state_changed(iod, STATE_CRASH_EXIT);
++}
++
++static void handle_no_crash_ack(unsigned long arg)
++{
++      struct dpram_link_device *dpld = (struct dpram_link_device *)arg;
++      struct link_device *ld = &dpld->ld;
++
++      mif_err("%s: ERR! No CRASH_EXIT ACK from CP\n", ld->mc->name);
++
++      if (!wake_lock_active(&dpld->wlock))
++              wake_lock(&dpld->wlock);
++
++      handle_cp_crash(dpld);
++}
++
++static int trigger_force_cp_crash(struct dpram_link_device *dpld)
++{
++      struct link_device *ld = &dpld->ld;
++
++      if (ld->mode == LINK_MODE_ULOAD) {
++              mif_err("%s: CP crash is already in progress\n", ld->mc->name);
++              return 0;
++      }
++
++      disable_irq_nosync(dpld->irq);
++
++      ld->mode = LINK_MODE_ULOAD;
++      mif_err("%s: called by %pf\n", ld->name, __builtin_return_address(0));
++
++      dpram_wake_up(dpld);
++#ifndef CONFIG_SAMSUNG_PRODUCT_SHIP
++      save_dpram_dump(dpld);
++#endif
++
++      enable_irq(dpld->irq);
++
++      send_intr(dpld, INT_CMD(INT_CMD_CRASH_EXIT));
++
++      mif_add_timer(&dpld->crash_ack_timer, FORCE_CRASH_ACK_TIMEOUT,
++                      handle_no_crash_ack, (unsigned long)dpld);
++
++      return 0;
++}
++
++static int dpram_init_ipc(struct dpram_link_device *dpld)
++{
++      struct link_device *ld = &dpld->ld;
++      int i;
++
++      if (ld->mode == LINK_MODE_IPC &&
++          get_magic(dpld) == DPRAM_MAGIC_CODE &&
++          get_access(dpld) == 1)
++              mif_info("%s: IPC already initialized\n", ld->name);
++
++      /* Clear pointers in every circular queue */
++      for (i = 0; i < ld->max_ipc_dev; i++) {
++              set_tx_head(dpld, i, 0);
++              set_tx_tail(dpld, i, 0);
++              set_rx_head(dpld, i, 0);
++              set_rx_tail(dpld, i, 0);
++      }
++
++      /* Initialize variables for efficient TX/RX processing */
++      for (i = 0; i < ld->max_ipc_dev; i++)
++              dpld->iod[i] = link_get_iod_with_format(ld, i);
++      dpld->iod[IPC_RAW] = link_get_iod_with_format(ld, IPC_MULTI_RAW);
++
++      if (dpld->iod[IPC_RAW]->recv_skb)
++              dpld->use_skb = true;
++
++      for (i = 0; i < ld->max_ipc_dev; i++) {
++              spin_lock_init(&dpld->tx_lock[i]);
++              atomic_set(&dpld->res_required[i], 0);
++      }
++
++      /* Enable IPC */
++      atomic_set(&dpld->accessing, 0);
++
++      set_magic(dpld, DPRAM_MAGIC_CODE);
++      set_access(dpld, 1);
++      if (get_magic(dpld) != DPRAM_MAGIC_CODE || get_access(dpld) != 1)
++              return -EACCES;
++
++      ld->mode = LINK_MODE_IPC;
++
++      if (wake_lock_active(&dpld->wlock))
++              wake_unlock(&dpld->wlock);
++
++      return 0;
++}
++
++static void cmd_req_active_handler(struct dpram_link_device *dpld)
++{
++      send_intr(dpld, INT_CMD(INT_CMD_RES_ACTIVE));
++}
++
++static void cmd_crash_reset_handler(struct dpram_link_device *dpld)
++{
++      struct link_device *ld = &dpld->ld;
++      struct io_device *iod = NULL;
++
++      ld->mode = LINK_MODE_ULOAD;
++
++      if (!wake_lock_active(&dpld->wlock))
++              wake_lock(&dpld->wlock);
++
++      mif_err("%s: Recv 0xC7 (CRASH_RESET)\n", ld->name);
++
++      iod = link_get_iod_with_format(ld, IPC_FMT);
++      iod->modem_state_changed(iod, STATE_CRASH_RESET);
++
++      iod = link_get_iod_with_format(ld, IPC_BOOT);
++      iod->modem_state_changed(iod, STATE_CRASH_RESET);
++}
++
++static void cmd_crash_exit_handler(struct dpram_link_device *dpld)
++{
++      struct link_device *ld = &dpld->ld;
++
++      ld->mode = LINK_MODE_ULOAD;
++
++      if (!wake_lock_active(&dpld->wlock))
++              wake_lock(&dpld->wlock);
++
++      del_timer(&dpld->crash_ack_timer);
++
++      dpram_wake_up(dpld);
++#ifndef CONFIG_SAMSUNG_PRODUCT_SHIP
++      save_dpram_dump(dpld);
++#endif
++
++      if (dpld->ext_op && dpld->ext_op->crash_log)
++              dpld->ext_op->crash_log(dpld);
++
++      mif_err("%s: Recv 0xC9 (CRASH_EXIT)\n", ld->name);
++
++      handle_cp_crash(dpld);
++}
++
++static void cmd_phone_start_handler(struct dpram_link_device *dpld)
++{
++      struct link_device *ld = &dpld->ld;
++      struct io_device *iod = NULL;
++
++      mif_info("%s: Recv 0xC8 (CP_START)\n", ld->name);
++
++      dpram_init_ipc(dpld);
++
++      iod = link_get_iod_with_format(ld, IPC_FMT);
++      if (!iod) {
++              mif_info("%s: ERR! no iod\n", ld->name);
++              return;
++      }
++
++      if (dpld->ext_op && dpld->ext_op->cp_start_handler)
++              dpld->ext_op->cp_start_handler(dpld);
++
++      if (ld->mc->phone_state != STATE_ONLINE) {
++              mif_info("%s: phone_state: %d -> ONLINE\n",
++                      ld->name, ld->mc->phone_state);
++              iod->modem_state_changed(iod, STATE_ONLINE);
++      }
++
++      mif_info("%s: Send 0xC2 (INIT_END)\n", ld->name);
++      send_intr(dpld, INT_CMD(INT_CMD_INIT_END));
++}
++
++static void command_handler(struct dpram_link_device *dpld, u16 cmd)
++{
++      struct link_device *ld = &dpld->ld;
++
++      switch (INT_CMD_MASK(cmd)) {
++      case INT_CMD_REQ_ACTIVE:
++              cmd_req_active_handler(dpld);
++              break;
++
++      case INT_CMD_CRASH_RESET:
++              dpld->init_status = DPRAM_INIT_STATE_NONE;
++              cmd_crash_reset_handler(dpld);
++              break;
++
++      case INT_CMD_CRASH_EXIT:
++              dpld->init_status = DPRAM_INIT_STATE_NONE;
++              cmd_crash_exit_handler(dpld);
++              break;
++
++      case INT_CMD_PHONE_START:
++              dpld->init_status = DPRAM_INIT_STATE_READY;
++              cmd_phone_start_handler(dpld);
++              complete_all(&dpld->dpram_init_cmd);
++              break;
++
++      case INT_CMD_NV_REBUILDING:
++              mif_info("%s: NV_REBUILDING\n", ld->name);
++              break;
++
++      case INT_CMD_PIF_INIT_DONE:
++              complete_all(&dpld->modem_pif_init_done);
++              break;
++
++      case INT_CMD_SILENT_NV_REBUILDING:
++              mif_info("%s: SILENT_NV_REBUILDING\n", ld->name);
++              break;
++
++      case INT_CMD_NORMAL_PWR_OFF:
++              /*ToDo:*/
++              /*kernel_sec_set_cp_ack()*/;
++              break;
++
++      case INT_CMD_REQ_TIME_SYNC:
++      case INT_CMD_CP_DEEP_SLEEP:
++      case INT_CMD_EMER_DOWN:
++              break;
++
++      default:
++              mif_info("%s: unknown command 0x%04X\n", ld->name, cmd);
++      }
++}
++
++static void ext_command_handler(struct dpram_link_device *dpld, u16 cmd)
++{
++      struct link_device *ld = &dpld->ld;
++      u16 resp;
++
++      switch (EXT_CMD_MASK(cmd)) {
++      case EXT_CMD_SET_SPEED_LOW:
++              if (dpld->dpctl->setup_speed) {
++                      dpld->dpctl->setup_speed(DPRAM_SPEED_LOW);
++                      resp = INT_EXT_CMD(EXT_CMD_SET_SPEED_LOW);
++                      send_intr(dpld, resp);
++              }
++              break;
++
++      case EXT_CMD_SET_SPEED_MID:
++              if (dpld->dpctl->setup_speed) {
++                      dpld->dpctl->setup_speed(DPRAM_SPEED_MID);
++                      resp = INT_EXT_CMD(EXT_CMD_SET_SPEED_MID);
++                      send_intr(dpld, resp);
++              }
++              break;
++
++      case EXT_CMD_SET_SPEED_HIGH:
++              if (dpld->dpctl->setup_speed) {
++                      dpld->dpctl->setup_speed(DPRAM_SPEED_HIGH);
++                      resp = INT_EXT_CMD(EXT_CMD_SET_SPEED_HIGH);
++                      send_intr(dpld, resp);
++              }
++              break;
++
++      default:
++              mif_info("%s: unknown command 0x%04X\n", ld->name, cmd);
++              break;
++      }
++}
++
++static void udl_command_handler(struct dpram_link_device *dpld, u16 cmd)
++{
++      struct link_device *ld = &dpld->ld;
++
++      if (cmd & UDL_RESULT_FAIL) {
++              mif_info("%s: ERR! Command failed: %04x\n", ld->name, cmd);
++              return;
++      }
++
++      switch (UDL_CMD_MASK(cmd)) {
++      case UDL_CMD_RECV_READY:
++              mif_debug("%s: Send CP-->AP RECEIVE_READY\n", ld->name);
++              send_intr(dpld, CMD_IMG_START_REQ);
++              break;
++      default:
++              complete_all(&dpld->udl_cmd_complete);
++      }
++}
++
++static inline void dpram_ipc_rx(struct dpram_link_device *dpld, u16 intr)
++{
++      if (unlikely(INT_CMD_VALID(intr)))
++              command_handler(dpld, intr);
++      else
++              non_command_handler(dpld, intr);
++}
++
++static inline void dpram_intr_handler(struct dpram_link_device *dpld, u16 intr)
++{
++      char *name = dpld->ld.name;
++
++      if (unlikely(intr == INT_POWERSAFE_FAIL)) {
++              mif_info("%s: intr == INT_POWERSAFE_FAIL\n", name);
++              return;
++      }
++
++      if (unlikely(EXT_UDL_CMD(intr))) {
++              if (likely(EXT_INT_VALID(intr))) {
++                      if (UDL_CMD_VALID(intr))
++                              udl_command_handler(dpld, intr);
++                      else if (EXT_CMD_VALID(intr))
++                              ext_command_handler(dpld, intr);
++                      else
++                              mif_info("%s: ERR! invalid intr 0x%04X\n",
++                                      name, intr);
++              } else {
++                      mif_info("%s: ERR! invalid intr 0x%04X\n", name, intr);
++              }
++              return;
++      }
++
++      if (likely(INT_VALID(intr)))
++              dpram_ipc_rx(dpld, intr);
++      else
++              mif_info("%s: ERR! invalid intr 0x%04X\n", name, intr);
++}
++
++static irqreturn_t ap_idpram_irq_handler(int irq, void *data)
++{
++      struct dpram_link_device *dpld = (struct dpram_link_device *)data;
++      struct link_device *ld = (struct link_device *)&dpld->ld;
++      u16 int2ap = recv_intr(dpld);
++
++      if (unlikely(ld->mode == LINK_MODE_OFFLINE))
++              return IRQ_HANDLED;
++
++      dpram_intr_handler(dpld, int2ap);
++
++      return IRQ_HANDLED;
++}
++
++static irqreturn_t cp_idpram_irq_handler(int irq, void *data)
++{
++      struct dpram_link_device *dpld = (struct dpram_link_device *)data;
++      struct link_device *ld = (struct link_device *)&dpld->ld;
++      u16 int2ap;
++
++      if (unlikely(ld->mode == LINK_MODE_OFFLINE))
++              return IRQ_HANDLED;
++
++      if (dpram_wake_up(dpld) < 0) {
++              trigger_force_cp_crash(dpld);
++              return IRQ_HANDLED;
++      }
++
++      int2ap = recv_intr(dpld);
++
++      dpram_intr_handler(dpld, int2ap);
++
++      clear_intr(dpld);
++
++      dpram_allow_sleep(dpld);
++
++      return IRQ_HANDLED;
++}
++
++static irqreturn_t ext_dpram_irq_handler(int irq, void *data)
++{
++      struct dpram_link_device *dpld = (struct dpram_link_device *)data;
++      struct link_device *ld = (struct link_device *)&dpld->ld;
++      u16 int2ap = recv_intr(dpld);
++
++      if (unlikely(ld->mode == LINK_MODE_OFFLINE))
++              return IRQ_HANDLED;
++
++      dpram_intr_handler(dpld, int2ap);
++
++      return IRQ_HANDLED;
++}
++
++static void dpram_send_ipc(struct link_device *ld, int dev,
++                      struct io_device *iod, struct sk_buff *skb)
++{
++      struct dpram_link_device *dpld = to_dpram_link_device(ld);
++      struct sk_buff_head *txq = ld->skb_txq[dev];
++      int ret;
++      u16 mask;
++
++      if (unlikely(txq->qlen >= MAX_SKB_TXQ_DEPTH)) {
++              mif_err("%s: %s txq->qlen %d >= %d\n", ld->name,
++                      get_dev_name(dev), txq->qlen, MAX_SKB_TXQ_DEPTH);
++              if (iod->io_typ == IODEV_NET || iod->format == IPC_MULTI_RAW) {
++                      dev_kfree_skb_any(skb);
++                      return;
++              }
++      }
++
++      skb_queue_tail(txq, skb);
++
++      if (dpram_wake_up(dpld) < 0) {
++              trigger_force_cp_crash(dpld);
++              return;
++      }
++
++      if (!ipc_active(dpld)) {
++              mif_info("%s: IPC is NOT active\n", ld->name);
++              goto exit;
++      }
++
++      if (atomic_read(&dpld->res_required[dev]) > 0) {
++              mif_info("%s: %s_TXQ is full\n", ld->name, get_dev_name(dev));
++              goto exit;
++      }
++
++      ret = dpram_ipc_tx(dpld, dev);
++      if (ret > 0) {
++              mask = get_mask_send(dpld, dev);
++              send_intr(dpld, INT_NON_CMD(mask));
++      } else if (ret == -ENOSPC) {
++              /*
++              ** dpld->res_required[dev] is set in dpram_ipc_tx()
++              */
++              if (dev == IPC_RAW)
++                      mif_netif_stop(ld);
++              queue_delayed_work(ld->tx_wq, ld->tx_dwork[dev], 0);
++      } else {
++              mif_info("%s: dpram_ipc_tx fail (err %d)\n", ld->name, ret);
++      }
++
++exit:
++      dpram_allow_sleep(dpld);
++}
++
++static int dpram_send_cp_binary(struct link_device *ld, struct sk_buff *skb)
++{
++      struct dpram_link_device *dpld = to_dpram_link_device(ld);
++
++      if (dpld->ext_op && dpld->ext_op->download_binary)
++              return dpld->ext_op->download_binary(dpld, skb);
++      else
++              return -ENODEV;
++}
++
++static int dpram_send(struct link_device *ld, struct io_device *iod,
++              struct sk_buff *skb)
++{
++      enum dev_format dev = iod->format;
++      int len = skb->len;
++
++      switch (dev) {
++      case IPC_FMT:
++      case IPC_RAW:
++      case IPC_RFS:
++              if (likely(ld->mode == LINK_MODE_IPC)) {
++                      dpram_send_ipc(ld, dev, iod, skb);
++              } else {
++                      mif_info("%s: ld->mode != LINK_MODE_IPC\n", ld->name);
++                      dev_kfree_skb_any(skb);
++              }
++              return len;
++
++      case IPC_BOOT:
++              return dpram_send_cp_binary(ld, skb);
++
++      default:
++              mif_info("%s: ERR! no TXQ for %s\n", ld->name, iod->name);
++              dev_kfree_skb_any(skb);
++              return -ENODEV;
++      }
++}
++
++static int dpram_force_dump(struct link_device *ld, struct io_device *iod)
++{
++      struct dpram_link_device *dpld = to_dpram_link_device(ld);
++      trigger_force_cp_crash(dpld);
++      return 0;
++}
++
++static int dpram_dump_start(struct link_device *ld, struct io_device *iod)
++{
++      struct dpram_link_device *dpld = to_dpram_link_device(ld);
++
++      if (dpld->ext_op && dpld->ext_op->dump_start)
++              return dpld->ext_op->dump_start(dpld);
++      else
++              return -ENODEV;
++}
++
++static int dpram_dump_update(struct link_device *ld, struct io_device *iod,
++              unsigned long arg)
++{
++      struct dpram_link_device *dpld = to_dpram_link_device(ld);
++
++      if (dpld->ext_op && dpld->ext_op->dump_update)
++              return dpld->ext_op->dump_update(dpld, (void *)arg);
++      else
++              return -ENODEV;
++}
++
++static int dpram_ioctl(struct link_device *ld, struct io_device *iod,
++              unsigned int cmd, unsigned long arg)
++{
++      struct dpram_link_device *dpld = to_dpram_link_device(ld);
++      int err = 0;
++
++      mif_info("%s: cmd 0x%08X\n", ld->name, cmd);
++
++      switch (cmd) {
++      case IOCTL_DPRAM_INIT_STATUS:
++              mif_debug("%s: get dpram init status\n", ld->name);
++              return dpld->init_status;
++
++      default:
++              if (dpld->ext_ioctl) {
++                      err = dpld->ext_ioctl(dpld, iod, cmd, arg);
++              } else {
++                      mif_err("%s: ERR! invalid cmd 0x%08X\n", ld->name, cmd);
++                      err = -EINVAL;
++              }
++
++              break;
++      }
++
++      return err;
++}
++
++static void dpram_dump_memory(struct link_device *ld, char *buff)
++{
++      struct dpram_link_device *dpld = to_dpram_link_device(ld);
++      dpram_wake_up(dpld);
++      memcpy(buff, dpld->base, dpld->size);
++      dpram_allow_sleep(dpld);
++}
++
++static void dpram_remap_std_16k_region(struct dpram_link_device *dpld)
++{
++      struct dpram_ipc_16k_map *dpram_map;
++      struct dpram_ipc_device *dev;
++
++      dpram_map = (struct dpram_ipc_16k_map *)dpld->base;
++
++      /* magic code and access enable fields */
++      dpld->ipc_map.magic = (u16 __iomem *)&dpram_map->magic;
++      dpld->ipc_map.access = (u16 __iomem *)&dpram_map->access;
++
++      /* FMT */
++      dev = &dpld->ipc_map.dev[IPC_FMT];
++
++      strcpy(dev->name, "FMT");
++      dev->id = IPC_FMT;
++
++      dev->txq.head = (u16 __iomem *)&dpram_map->fmt_tx_head;
++      dev->txq.tail = (u16 __iomem *)&dpram_map->fmt_tx_tail;
++      dev->txq.buff = (u8 __iomem *)&dpram_map->fmt_tx_buff[0];
++      dev->txq.size = DP_16K_FMT_TX_BUFF_SZ;
++
++      dev->rxq.head = (u16 __iomem *)&dpram_map->fmt_rx_head;
++      dev->rxq.tail = (u16 __iomem *)&dpram_map->fmt_rx_tail;
++      dev->rxq.buff = (u8 __iomem *)&dpram_map->fmt_rx_buff[0];
++      dev->rxq.size = DP_16K_FMT_RX_BUFF_SZ;
++
++      dev->mask_req_ack = INT_MASK_REQ_ACK_F;
++      dev->mask_res_ack = INT_MASK_RES_ACK_F;
++      dev->mask_send    = INT_MASK_SEND_F;
++
++      /* RAW */
++      dev = &dpld->ipc_map.dev[IPC_RAW];
++
++      strcpy(dev->name, "RAW");
++      dev->id = IPC_RAW;
++
++      dev->txq.head = (u16 __iomem *)&dpram_map->raw_tx_head;
++      dev->txq.tail = (u16 __iomem *)&dpram_map->raw_tx_tail;
++      dev->txq.buff = (u8 __iomem *)&dpram_map->raw_tx_buff[0];
++      dev->txq.size = DP_16K_RAW_TX_BUFF_SZ;
++
++      dev->rxq.head = (u16 __iomem *)&dpram_map->raw_rx_head;
++      dev->rxq.tail = (u16 __iomem *)&dpram_map->raw_rx_tail;
++      dev->rxq.buff = (u8 __iomem *)&dpram_map->raw_rx_buff[0];
++      dev->rxq.size = DP_16K_RAW_RX_BUFF_SZ;
++
++      dev->mask_req_ack = INT_MASK_REQ_ACK_R;
++      dev->mask_res_ack = INT_MASK_RES_ACK_R;
++      dev->mask_send    = INT_MASK_SEND_R;
++
++      /* interrupt ports */
++      dpld->ipc_map.mbx_cp2ap = (u16 __iomem *)&dpram_map->mbx_cp2ap;
++      dpld->ipc_map.mbx_ap2cp = (u16 __iomem *)&dpram_map->mbx_ap2cp;
++}
++
++static int dpram_table_init(struct dpram_link_device *dpld)
++{
++      struct link_device *ld = &dpld->ld;
++      u8 __iomem *dp_base;
++      int i;
++
++      if (!dpld->base) {
++              mif_info("%s: ERR! dpld->base == NULL\n", ld->name);
++              return -EINVAL;
++      }
++      dp_base = dpld->base;
++
++      /* Map for booting */
++      if (dpld->ext_op && dpld->ext_op->init_boot_map) {
++              dpld->ext_op->init_boot_map(dpld);
++      } else {
++              dpld->bt_map.magic = (u32 *)(dp_base);
++              dpld->bt_map.buff = (u8 *)(dp_base + DP_BOOT_BUFF_OFFSET);
++              dpld->bt_map.size = dpld->size - 8;
++      }
++
++      /* Map for download (FOTA, UDL, etc.) */
++      if (dpld->ext_op && dpld->ext_op->init_dl_map) {
++              dpld->ext_op->init_dl_map(dpld);
++      } else {
++              dpld->dl_map.magic = (u32 *)(dp_base);
++              dpld->dl_map.buff = (u8 *)(dp_base + DP_DLOAD_BUFF_OFFSET);
++      }
++
++      /* Map for upload mode */
++      if (dpld->ext_op && dpld->ext_op->init_ul_map) {
++              dpld->ext_op->init_ul_map(dpld);
++      } else {
++              dpld->ul_map.magic = (u32 *)(dp_base);
++              dpld->ul_map.buff = (u8 *)(dp_base + DP_ULOAD_BUFF_OFFSET);
++      }
++
++      /* Map for IPC */
++      if (dpld->ext_op && dpld->ext_op->init_ipc_map) {
++              dpld->ext_op->init_ipc_map(dpld);
++      } else if (dpld->dpctl->ipc_map) {
++              memcpy(&dpld->ipc_map, dpld->dpctl->ipc_map,
++                      sizeof(struct dpram_ipc_map));
++      } else {
++              if (dpld->size == DPRAM_SIZE_16KB)
++                      dpram_remap_std_16k_region(dpld);
++              else
++                      return -EINVAL;
++      }
++
++      dpld->magic = dpld->ipc_map.magic;
++      dpld->access = dpld->ipc_map.access;
++      for (i = 0; i < ld->max_ipc_dev; i++)
++              dpld->dev[i] = &dpld->ipc_map.dev[i];
++      dpld->mbx2ap = dpld->ipc_map.mbx_cp2ap;
++      dpld->mbx2cp = dpld->ipc_map.mbx_ap2cp;
++
++      return 0;
++}
++
++static void dpram_setup_common_op(struct dpram_link_device *dpld)
++{
++      dpld->recv_intr = recv_intr;
++      dpld->send_intr = send_intr;
++      dpld->get_magic = get_magic;
++      dpld->set_magic = set_magic;
++      dpld->get_access = get_access;
++      dpld->set_access = set_access;
++      dpld->get_tx_head = get_tx_head;
++      dpld->get_tx_tail = get_tx_tail;
++      dpld->set_tx_head = set_tx_head;
++      dpld->set_tx_tail = set_tx_tail;
++      dpld->get_tx_buff = get_tx_buff;
++      dpld->get_tx_buff_size = get_tx_buff_size;
++      dpld->get_rx_head = get_rx_head;
++      dpld->get_rx_tail = get_rx_tail;
++      dpld->set_rx_head = set_rx_head;
++      dpld->set_rx_tail = set_rx_tail;
++      dpld->get_rx_buff = get_rx_buff;
++      dpld->get_rx_buff_size = get_rx_buff_size;
++      dpld->get_mask_req_ack = get_mask_req_ack;
++      dpld->get_mask_res_ack = get_mask_res_ack;
++      dpld->get_mask_send = get_mask_send;
++      dpld->ipc_rx_handler = dpram_intr_handler;
++}
++
++static int dpram_link_init(struct link_device *ld, struct io_device *iod)
++{
++      return 0;
++}
++
++static void dpram_link_terminate(struct link_device *ld, struct io_device *iod)
++{
++      if (iod->format == IPC_FMT && ld->mode == LINK_MODE_IPC) {
++              if (!atomic_read(&iod->opened)) {
++                      ld->mode = LINK_MODE_OFFLINE;
++                      mif_err("%s: %s: link mode is changed: IPC->OFFLINE\n",
++                              iod->name, ld->name);
++              }
++      }
++
++      return;
++}
++
++struct link_device *dpram_create_link_device(struct platform_device *pdev)
++{
++      struct dpram_link_device *dpld = NULL;
++      struct link_device *ld = NULL;
++      struct modem_data *modem = NULL;
++      struct modemlink_dpram_control *dpctl = NULL;
++      struct resource *res = NULL;
++      resource_size_t res_size;
++      unsigned long task_data;
++      int ret = 0;
++      int i = 0;
++      int bsize;
++      int qsize;
++
++      /*
++      ** Alloc an instance of the DPRAM link device structure
++      */
++      dpld = kzalloc(sizeof(struct dpram_link_device), GFP_KERNEL);
++      if (!dpld) {
++              mif_err("ERR! kzalloc dpld fail\n");
++              goto err;
++      }
++      ld = &dpld->ld;
++
++      /*
++      ** Get the modem (platform) data
++      */
++      modem = (struct modem_data *)pdev->dev.platform_data;
++      if (!modem) {
++              mif_err("ERR! modem == NULL\n");
++              goto err;
++      }
++      mif_info("modem = %s\n", modem->name);
++      mif_info("link device = %s\n", modem->link_name);
++
++      /*
++      ** Retrieve modem data and DPRAM control data from the modem data
++      */
++      ld->mdm_data = modem;
++      ld->name = modem->link_name;
++      ld->ipc_version = modem->ipc_version;
++
++      if (!modem->dpram_ctl) {
++              mif_err("ERR! modem->dpram_ctl == NULL\n");
++              goto err;
++      }
++      dpctl = modem->dpram_ctl;
++
++      dpld->dpctl = dpctl;
++      dpld->type = dpctl->dp_type;
++
++      if (ld->ipc_version < SIPC_VER_50) {
++              if (!dpctl->max_ipc_dev) {
++                      mif_err("%s: ERR! no max_ipc_dev\n", ld->name);
++                      goto err;
++              }
++
++              ld->aligned = dpctl->aligned;
++              ld->max_ipc_dev = dpctl->max_ipc_dev;
++      } else {
++              ld->aligned = 1;
++              ld->max_ipc_dev = MAX_SIPC5_DEV;
++      }
++
++      /*
++      ** Set attributes as a link device
++      */
++      ld->init_comm = dpram_link_init;
++      ld->terminate_comm = dpram_link_terminate;
++      ld->send = dpram_send;
++      ld->force_dump = dpram_force_dump;
++      ld->dump_start = dpram_dump_start;
++      ld->dump_update = dpram_dump_update;
++      ld->ioctl = dpram_ioctl;
++
++      INIT_LIST_HEAD(&ld->list);
++
++      skb_queue_head_init(&ld->sk_fmt_tx_q);
++      skb_queue_head_init(&ld->sk_raw_tx_q);
++      skb_queue_head_init(&ld->sk_rfs_tx_q);
++      ld->skb_txq[IPC_FMT] = &ld->sk_fmt_tx_q;
++      ld->skb_txq[IPC_RAW] = &ld->sk_raw_tx_q;
++      ld->skb_txq[IPC_RFS] = &ld->sk_rfs_tx_q;
++
++      /*
++      ** Set up function pointers
++      */
++      dpram_setup_common_op(dpld);
++      dpld->dpram_dump = dpram_dump_memory;
++      dpld->ext_op = dpram_get_ext_op(modem->modem_type);
++      if (dpld->ext_op && dpld->ext_op->ioctl)
++              dpld->ext_ioctl = dpld->ext_op->ioctl;
++      if (dpld->ext_op && dpld->ext_op->wakeup && dpld->ext_op->sleep)
++              dpld->need_wake_up = true;
++      if (dpld->ext_op && dpld->ext_op->clear_intr)
++              dpld->need_intr_clear = true;
++
++      /*
++      ** Retrieve DPRAM resource
++      */
++      if (!dpctl->dp_base) {
++              res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
++                                              STR_DPRAM_BASE);
++              if (!res) {
++                      mif_err("%s: ERR! no DPRAM resource\n", ld->name);
++                      goto err;
++              }
++              res_size = resource_size(res);
++
++              dpctl->dp_base = ioremap_nocache(res->start, res_size);
++              if (!dpctl->dp_base) {
++                      mif_err("%s: ERR! ioremap_nocache for BASE fail\n",
++                              ld->name);
++                      goto err;
++              }
++              dpctl->dp_size = res_size;
++      }
++      dpld->base = dpctl->dp_base;
++      dpld->size = dpctl->dp_size;
++
++      mif_info("%s: type %d, aligned %d, base 0x%08X, size %d\n",
++              ld->name, dpld->type, ld->aligned, (int)dpld->base, dpld->size);
++
++      /*
++      ** Retrieve DPRAM SFR resource if exists
++      */
++      res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
++                                      STR_DPRAM_SFR_BASE);
++      if (res) {
++              res_size = resource_size(res);
++              dpld->sfr_base = ioremap_nocache(res->start, res_size);
++              if (!dpld->sfr_base) {
++                      mif_err("%s: ERR! ioremap_nocache for SFR fail\n",
++                              ld->name);
++                      goto err;
++              }
++      }
++
++      /* Initialize DPRAM map (physical map -> logical map) */
++      ret = dpram_table_init(dpld);
++      if (ret < 0) {
++              mif_err("%s: ERR! dpram_table_init fail (err %d)\n",
++                      ld->name, ret);
++              goto err;
++      }
++
++      /* Disable IPC */
++      set_magic(dpld, 0);
++      set_access(dpld, 0);
++      dpld->init_status = DPRAM_INIT_STATE_NONE;
++
++      /* Initialize locks, completions, and bottom halves */
++      snprintf(dpld->wlock_name, MIF_MAX_NAME_LEN, "%s_wlock", ld->name);
++      wake_lock_init(&dpld->wlock, WAKE_LOCK_SUSPEND, dpld->wlock_name);
++
++      init_completion(&dpld->dpram_init_cmd);
++      init_completion(&dpld->modem_pif_init_done);
++      init_completion(&dpld->udl_start_complete);
++      init_completion(&dpld->udl_cmd_complete);
++      init_completion(&dpld->crash_start_complete);
++      init_completion(&dpld->crash_recv_done);
++      for (i = 0; i < ld->max_ipc_dev; i++)
++              init_completion(&dpld->res_ack_cmpl[i]);
++
++      task_data = (unsigned long)dpld;
++      tasklet_init(&dpld->rx_tsk, dpram_ipc_rx_task, task_data);
++
++      ld->tx_wq = create_singlethread_workqueue("dpram_tx_wq");
++      if (!ld->tx_wq) {
++              mif_err("%s: ERR! fail to create tx_wq\n", ld->name);
++              goto err;
++      }
++      INIT_DELAYED_WORK(&ld->fmt_tx_dwork, dpram_fmt_tx_work);
++      INIT_DELAYED_WORK(&ld->raw_tx_dwork, dpram_raw_tx_work);
++      INIT_DELAYED_WORK(&ld->rfs_tx_dwork, dpram_rfs_tx_work);
++      ld->tx_dwork[IPC_FMT] = &ld->fmt_tx_dwork;
++      ld->tx_dwork[IPC_RAW] = &ld->raw_tx_dwork;
++      ld->tx_dwork[IPC_RFS] = &ld->rfs_tx_dwork;
++
++#ifndef CONFIG_SAMSUNG_PRODUCT_SHIP
++      INIT_DELAYED_WORK(&dpld->dump_dwork, save_dpram_dump_work);
++      INIT_DELAYED_WORK(&dpld->trace_dwork, save_ipc_trace_work);
++      spin_lock_init(&dpld->dump_list.lock);
++      spin_lock_init(&dpld->trace_list.lock);
++#endif
++
++      /* Prepare RXB queue */
++      qsize = DPRAM_MAX_RXBQ_SIZE;
++      for (i = 0; i < ld->max_ipc_dev; i++) {
++              bsize = rxbq_get_page_size(get_rx_buff_size(dpld, i));
++              dpld->rxbq[i].size = qsize;
++              dpld->rxbq[i].in = 0;
++              dpld->rxbq[i].out = 0;
++              dpld->rxbq[i].rxb = rxbq_create_pool(bsize, qsize);
++              if (!dpld->rxbq[i].rxb) {
++                      mif_err("%s: ERR! %s rxbq_create_pool fail\n",
++                              ld->name, get_dev_name(i));
++                      goto err;
++              }
++              mif_info("%s: %s rxbq_pool created (bsize:%d, qsize:%d)\n",
++                      ld->name, get_dev_name(i), bsize, qsize);
++      }
++
++      /* Prepare a multi-purpose miscellaneous buffer */
++      dpld->buff = kzalloc(dpld->size, GFP_KERNEL);
++      if (!dpld->buff) {
++              mif_err("%s: ERR! kzalloc dpld->buff fail\n", ld->name);
++              goto err;
++      }
++
++      /*
++      ** Retrieve DPRAM IRQ GPIO#, IRQ#, and IRQ flags
++      */
++      dpld->gpio_dpram_int = modem->gpio_dpram_int;
++
++      if (dpctl->dpram_irq) {
++              dpld->irq = dpctl->dpram_irq;
++      } else {
++              dpld->irq = platform_get_irq_byname(pdev, STR_DPRAM_IRQ);
++              if (dpld->irq < 0) {
++                      mif_err("%s: ERR! no DPRAM IRQ resource\n", ld->name);
++                      goto err;
++              }
++      }
++
++      if (dpctl->dpram_irq_flags)
++              dpld->irq_flags = dpctl->dpram_irq_flags;
++      else
++              dpld->irq_flags = (IRQF_NO_SUSPEND | IRQF_TRIGGER_LOW);
++
++      /*
++      ** Register DPRAM interrupt handler
++      */
++      snprintf(dpld->irq_name, MIF_MAX_NAME_LEN, "%s_irq", ld->name);
++      if (dpld->ext_op && dpld->ext_op->irq_handler)
++              dpld->irq_handler = dpld->ext_op->irq_handler;
++      else if (dpld->type == CP_IDPRAM)
++              dpld->irq_handler = cp_idpram_irq_handler;
++      else if (dpld->type == AP_IDPRAM)
++              dpld->irq_handler = ap_idpram_irq_handler;
++      else
++              dpld->irq_handler = ext_dpram_irq_handler;
++
++      ret = register_isr(dpld->irq, dpld->irq_handler, dpld->irq_flags,
++                              dpld->irq_name, dpld);
++      if (ret)
++              goto err;
++
++      return ld;
++
++err:
++      if (dpld) {
++              if (dpld->buff)
++                      kfree(dpld->buff);
++              kfree(dpld);
++      }
++
++      return NULL;
++}
++
+diff --git a/drivers/misc/modem_if/modem_link_device_dpram.h b/drivers/misc/modem_if/modem_link_device_dpram.h
+new file mode 100644
+index 0000000..8706fd0
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_link_device_dpram.h
+@@ -0,0 +1,252 @@
++/*
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++#ifndef __MODEM_LINK_DEVICE_DPRAM_H__
++#define __MODEM_LINK_DEVICE_DPRAM_H__
++
++#include "modem_link_device_memory.h"
++
++/*
++      magic_code +
++      access_enable +
++      fmt_tx_head + fmt_tx_tail + fmt_tx_buff +
++      raw_tx_head + raw_tx_tail + raw_tx_buff +
++      fmt_rx_head + fmt_rx_tail + fmt_rx_buff +
++      raw_rx_head + raw_rx_tail + raw_rx_buff +
++      mbx_cp2ap +
++      mbx_ap2cp
++ =    2 +
++      2 +
++      2 + 2 + 1336 +
++      2 + 2 + 4564 +
++      2 + 2 + 1336 +
++      2 + 2 + 9124 +
++      2 +
++      2
++ =    16384
++*/
++#define DP_16K_FMT_TX_BUFF_SZ 1336
++#define DP_16K_RAW_TX_BUFF_SZ 4564
++#define DP_16K_FMT_RX_BUFF_SZ 1336
++#define DP_16K_RAW_RX_BUFF_SZ 9124
++
++struct dpram_ipc_16k_map {
++      u16 magic;
++      u16 access;
++
++      u16 fmt_tx_head;
++      u16 fmt_tx_tail;
++      u8  fmt_tx_buff[DP_16K_FMT_TX_BUFF_SZ];
++
++      u16 raw_tx_head;
++      u16 raw_tx_tail;
++      u8  raw_tx_buff[DP_16K_RAW_TX_BUFF_SZ];
++
++      u16 fmt_rx_head;
++      u16 fmt_rx_tail;
++      u8  fmt_rx_buff[DP_16K_FMT_RX_BUFF_SZ];
++
++      u16 raw_rx_head;
++      u16 raw_rx_tail;
++      u8  raw_rx_buff[DP_16K_RAW_RX_BUFF_SZ];
++
++      u16 mbx_cp2ap;
++      u16 mbx_ap2cp;
++};
++
++struct dpram_sfr {
++      u16 __iomem *int2cp;
++      u16 __iomem *int2ap;
++      u16 __iomem *clr_int2ap;
++      u16 __iomem *reset;
++      u16 __iomem *msg2cp;
++      u16 __iomem *msg2ap;
++};
++
++struct dpram_ext_op;
++
++struct dpram_link_device {
++      struct link_device ld;
++
++      /* DPRAM address and size */
++      enum dpram_type type;   /* DPRAM type                   */
++      u8 __iomem *base;       /* Virtual address of DPRAM     */
++      u32 size;               /* DPRAM size                   */
++
++      /* Whether or not this DPRAM can go asleep */
++      bool need_wake_up;
++
++      /* Whether or not this DPRAM needs interrupt clearing */
++      bool need_intr_clear;
++
++      /* DPRAM SFR */
++      u8 __iomem *sfr_base;   /* Virtual address of SFR       */
++      struct dpram_sfr sfr;
++
++      /* DPRAM IRQ GPIO# */
++      unsigned gpio_dpram_int;
++
++      /* DPRAM IRQ from CP */
++      int irq;
++      unsigned long irq_flags;
++      char irq_name[MIF_MAX_NAME_LEN];
++
++      /* Link to DPRAM control functions dependent on each platform */
++      struct modemlink_dpram_control *dpctl;
++
++      /* Physical configuration -> logical configuration */
++      union {
++              struct dpram_boot_map bt_map;
++              struct qc_dpram_boot_map qc_bt_map;
++      };
++
++      struct dpram_dload_map dl_map;
++      struct dpram_uload_map ul_map;
++
++      /* IPC device map */
++      struct dpram_ipc_map ipc_map;
++
++      /* Pointers (aliases) to IPC device map */
++      u16 __iomem *magic;
++      u16 __iomem *access;
++      struct dpram_ipc_device *dev[MAX_IPC_DEV];
++      u16 __iomem *mbx2ap;
++      u16 __iomem *mbx2cp;
++
++      /* Wakelock for DPRAM device */
++      struct wake_lock wlock;
++      char wlock_name[MIF_MAX_NAME_LEN];
++
++      /* For booting */
++      unsigned boot_start_complete;
++      struct completion dpram_init_cmd;
++      struct completion modem_pif_init_done;
++
++      /* For UDL */
++      struct tasklet_struct ul_tsk;
++      struct tasklet_struct dl_tsk;
++      struct completion udl_start_complete;
++      struct completion udl_cmd_complete;
++      struct dpram_udl_check udl_check;
++      struct dpram_udl_param udl_param;
++
++      /* For CP crash dump */
++      struct timer_list crash_ack_timer;
++      struct completion crash_start_complete;
++      struct completion crash_recv_done;
++      struct timer_list crash_timer;
++      int crash_rcvd;         /* Count of CP crash dump packets received */
++
++      /* For locking TX process */
++      spinlock_t tx_lock[MAX_IPC_DEV];
++
++      /* For TX under DPRAM flow control */
++      struct completion res_ack_cmpl[MAX_IPC_DEV];
++
++      /* For efficient RX process */
++      struct tasklet_struct rx_tsk;
++      struct mif_rxb_queue rxbq[MAX_IPC_DEV];
++      struct io_device *iod[MAX_IPC_DEV];
++      bool use_skb;
++
++      /* For retransmission after buffer full state */
++      atomic_t res_required[MAX_IPC_DEV];
++
++      /* For wake-up/sleep control */
++      atomic_t accessing;
++
++      /* Multi-purpose miscellaneous buffer */
++      u8 *buff;
++
++      /* DPRAM IPC initialization status */
++      int init_status;
++
++      /* Alias to device-specific IOCTL function */
++      int (*ext_ioctl)(struct dpram_link_device *dpld, struct io_device *iod,
++                      unsigned int cmd, unsigned long arg);
++
++      /* Alias to DPRAM IRQ handler */
++      irqreturn_t (*irq_handler)(int irq, void *data);
++
++      /* For DPRAM dump */
++      u8 *dump_buff;
++      char dump_path[MIF_MAX_PATH_LEN];
++      char trace_path[MIF_MAX_PATH_LEN];
++      struct trace_queue dump_list;
++      struct trace_queue trace_list;
++      struct delayed_work dump_dwork;
++      struct delayed_work trace_dwork;
++      void (*dpram_dump)(struct link_device *ld, char *buff);
++
++      /* Common operations for each DPRAM */
++      u16 (*recv_intr)(struct dpram_link_device *dpld);
++      void (*send_intr)(struct dpram_link_device *dpld, u16 mask);
++      u16 (*get_magic)(struct dpram_link_device *dpld);
++      void (*set_magic)(struct dpram_link_device *dpld, u16 value);
++      u16 (*get_access)(struct dpram_link_device *dpld);
++      void (*set_access)(struct dpram_link_device *dpld, u16 value);
++      u32 (*get_tx_head)(struct dpram_link_device *dpld, int id);
++      u32 (*get_tx_tail)(struct dpram_link_device *dpld, int id);
++      void (*set_tx_head)(struct dpram_link_device *dpld, int id, u32 head);
++      void (*set_tx_tail)(struct dpram_link_device *dpld, int id, u32 tail);
++      u8 *(*get_tx_buff)(struct dpram_link_device *dpld, int id);
++      u32 (*get_tx_buff_size)(struct dpram_link_device *dpld, int id);
++      u32 (*get_rx_head)(struct dpram_link_device *dpld, int id);
++      u32 (*get_rx_tail)(struct dpram_link_device *dpld, int id);
++      void (*set_rx_head)(struct dpram_link_device *dpld, int id, u32 head);
++      void (*set_rx_tail)(struct dpram_link_device *dpld, int id, u32 tail);
++      u8 *(*get_rx_buff)(struct dpram_link_device *dpld, int id);
++      u32 (*get_rx_buff_size)(struct dpram_link_device *dpld, int id);
++      u16 (*get_mask_req_ack)(struct dpram_link_device *dpld, int id);
++      u16 (*get_mask_res_ack)(struct dpram_link_device *dpld, int id);
++      u16 (*get_mask_send)(struct dpram_link_device *dpld, int id);
++      void (*ipc_rx_handler)(struct dpram_link_device *dpld, u16 int2ap);
++
++      /* Extended operations for various modems */
++      struct dpram_ext_op *ext_op;
++};
++
++/* converts from struct link_device* to struct xxx_link_device* */
++#define to_dpram_link_device(linkdev) \
++              container_of(linkdev, struct dpram_link_device, ld)
++
++struct dpram_ext_op {
++      int exist;
++
++      void (*init_boot_map)(struct dpram_link_device *dpld);
++      void (*init_dl_map)(struct dpram_link_device *dpld);
++      void (*init_ul_map)(struct dpram_link_device *dpld);
++      void (*init_ipc_map)(struct dpram_link_device *dpld);
++
++      int (*download_binary)(struct dpram_link_device *dpld,
++                      struct sk_buff *skb);
++
++      void (*cp_start_handler)(struct dpram_link_device *dpld);
++
++      void (*crash_log)(struct dpram_link_device *dpld);
++      int (*dump_start)(struct dpram_link_device *dpld);
++      int (*dump_update)(struct dpram_link_device *dpld, void *arg);
++
++      int (*ioctl)(struct dpram_link_device *dpld, struct io_device *iod,
++                      unsigned int cmd, unsigned long arg);
++
++      irqreturn_t (*irq_handler)(int irq, void *data);
++      void (*clear_intr)(struct dpram_link_device *dpld);
++
++      int (*wakeup)(struct dpram_link_device *dpld);
++      void (*sleep)(struct dpram_link_device *dpld);
++};
++
++struct dpram_ext_op *dpram_get_ext_op(enum modem_t modem);
++
++#endif
+diff --git a/drivers/misc/modem_if/modem_link_device_dpram_ext_op.c b/drivers/misc/modem_if/modem_link_device_dpram_ext_op.c
+new file mode 100644
+index 0000000..83f2cc3
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_link_device_dpram_ext_op.c
+@@ -0,0 +1,1306 @@
++/*
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <linux/irq.h>
++#include <linux/gpio.h>
++#include <linux/time.h>
++#include <linux/interrupt.h>
++#include <linux/timer.h>
++#include <linux/wakelock.h>
++#include <linux/delay.h>
++#include <linux/wait.h>
++#include <linux/sched.h>
++#include <linux/vmalloc.h>
++#include <linux/if_arp.h>
++#include <linux/platform_device.h>
++#include <linux/kallsyms.h>
++#include <linux/platform_data/modem.h>
++
++#include "modem_prj.h"
++#include "modem_link_device_dpram.h"
++#include "modem_utils.h"
++
++#if defined(CONFIG_LTE_MODEM_CMC221)
++/*
++** For host (flashless) booting via DPRAM
++*/
++#define CMC22x_AP_BOOT_DOWN_DONE      0x54329876
++#define CMC22x_CP_REQ_MAIN_BIN                0xA5A5A5A5
++#define CMC22x_CP_REQ_NV_DATA         0x5A5A5A5A
++#define CMC22x_CP_DUMP_MAGIC          0xDEADDEAD
++
++#define CMC22x_HOST_DOWN_START                0x1234
++#define CMC22x_HOST_DOWN_END          0x4321
++#define CMC22x_REG_NV_DOWN_END                0xABCD
++#define CMC22x_CAL_NV_DOWN_END                0xDCBA
++
++#define CMC22x_1ST_BUFF_READY         0xAAAA
++#define CMC22x_2ND_BUFF_READY         0xBBBB
++#define CMC22x_1ST_BUFF_FULL          0x1111
++#define CMC22x_2ND_BUFF_FULL          0x2222
++
++#define CMC22x_CP_RECV_NV_END         0x8888
++#define CMC22x_CP_CAL_OK              0x4F4B
++#define CMC22x_CP_CAL_BAD             0x4552
++#define CMC22x_CP_DUMP_END            0xFADE
++
++#define CMC22x_DUMP_BUFF_SIZE         8192    /* 8 KB */
++#endif
++
++#if defined(CONFIG_CDMA_MODEM_CBP72)
++static void cbp72_init_boot_map(struct dpram_link_device *dpld)
++{
++      struct dpram_boot_map *bt_map = &dpld->bt_map;
++
++      bt_map->magic = (u32 *)dpld->base;
++      bt_map->buff = (u8 *)(dpld->base + DP_BOOT_BUFF_OFFSET);
++      bt_map->size = dpld->size - 4;
++}
++
++static void cbp72_init_dl_map(struct dpram_link_device *dpld)
++{
++      dpld->dl_map.magic = (u32 *)dpld->base;
++      dpld->dl_map.buff = (u8 *)(dpld->base + DP_DLOAD_BUFF_OFFSET);
++}
++
++static int _cbp72_edpram_wait_resp(struct dpram_link_device *dpld, u32 resp)
++{
++      struct link_device *ld = &dpld->ld;
++      int ret;
++      int int2cp;
++
++      ret = wait_for_completion_interruptible_timeout(
++                      &dpld->udl_cmd_complete, UDL_TIMEOUT);
++      if (!ret) {
++              mif_info("%s: ERR! No UDL_CMD_RESP!!!\n", ld->name);
++              return -ENXIO;
++      }
++
++      int2cp = dpld->recv_intr(dpld);
++      mif_debug("%s: int2cp = 0x%x\n", ld->name, int2cp);
++      if (resp == int2cp || int2cp == 0xA700)
++              return int2cp;
++      else
++              return -EINVAL;
++}
++
++static int _cbp72_edpram_download_bin(struct dpram_link_device *dpld,
++                      struct sk_buff *skb)
++{
++      struct link_device *ld = &dpld->ld;
++      struct dpram_boot_frame *bf = (struct dpram_boot_frame *)skb->data;
++      u8 __iomem *buff = dpld->bt_map.buff;
++      int err = 0;
++
++      if (bf->len > dpld->bt_map.size) {
++              mif_info("%s: ERR! Out of DPRAM boundary\n", ld->name);
++              err = -EINVAL;
++              goto exit;
++      }
++
++      if (bf->len)
++              memcpy(buff, bf->data, bf->len);
++
++      init_completion(&dpld->udl_cmd_complete);
++
++      if (bf->req)
++              dpld->send_intr(dpld, (u16)bf->req);
++
++      if (bf->resp) {
++              err = _cbp72_edpram_wait_resp(dpld, bf->resp);
++              if (err < 0) {
++                      mif_info("%s: ERR! wait_response fail (%d)\n",
++                              ld->name, err);
++                      goto exit;
++              } else if (err == bf->resp) {
++                      err = skb->len;
++              }
++      }
++
++exit:
++      dev_kfree_skb_any(skb);
++      return err;
++}
++
++static int cbp72_download_binary(struct dpram_link_device *dpld,
++                      struct sk_buff *skb)
++{
++      if (dpld->type == EXT_DPRAM)
++              return _cbp72_edpram_download_bin(dpld, skb);
++      else
++              return -ENODEV;
++}
++
++static int cbp72_dump_start(struct dpram_link_device *dpld)
++{
++      struct link_device *ld = &dpld->ld;
++      u8 *dest = dpld->ul_map.buff;
++      int ret;
++
++      ld->mode = LINK_MODE_ULOAD;
++
++      ret = del_timer(&dpld->crash_timer);
++      wake_lock(&dpld->wlock);
++
++      iowrite32(DP_MAGIC_UMDL, dpld->ul_map.magic);
++
++      iowrite8((u8)START_FLAG, dest + 0);
++      iowrite8((u8)0x1, dest + 1);
++      iowrite8((u8)0x1, dest + 2);
++      iowrite8((u8)0x0, dest + 3);
++      iowrite8((u8)END_FLAG, dest + 4);
++
++      init_completion(&dpld->crash_start_complete);
++
++      return 0;
++}
++
++static int _cbp72_edpram_upload(struct dpram_link_device *dpld,
++              struct dpram_dump_arg *dump, unsigned char __user *target)
++{
++      struct link_device *ld = &dpld->ld;
++      struct ul_header header;
++      u8 *dest = NULL;
++      u8 *buff = NULL;
++      u16 plen = 0;
++      int err = 0;
++      int ret = 0;
++      int buff_size = 0;
++
++      mif_debug("\n");
++
++      init_completion(&dpld->udl_cmd_complete);
++
++      mif_debug("%s: req %x, resp %x", ld->name, dump->req, dump->resp);
++
++      if (dump->req)
++              dpld->send_intr(dpld, (u16)dump->req);
++
++      if (dump->resp) {
++              err = _cbp72_edpram_wait_resp(dpld, dump->resp);
++              if (err < 0) {
++                      mif_info("%s: ERR! wait_response fail (%d)\n",
++                              ld->name, err);
++                      goto exit;
++              }
++      }
++
++      if (dump->cmd)
++              return err;
++
++      dest = (u8 *)dpld->ul_map.buff;
++
++      header.bop = *(u8 *)(dest);
++      header.total_frame = *(u16 *)(dest + 1);
++      header.curr_frame = *(u16 *)(dest + 3);
++      header.len = *(u16 *)(dest + 5);
++
++      mif_debug("%s: total frame:%d, current frame:%d, data len:%d\n",
++              ld->name, header.total_frame, header.curr_frame, header.len);
++
++      plen = min_t(u16, header.len, DP_DEFAULT_DUMP_LEN);
++
++      buff = vmalloc(DP_DEFAULT_DUMP_LEN);
++      if (!buff) {
++              err = -ENOMEM;
++              goto exit;
++      }
++
++      memcpy(buff, dest + sizeof(struct ul_header), plen);
++      ret = copy_to_user(dump->buff, buff, plen);
++      if (ret < 0) {
++              mif_info("%s: ERR! dump copy_to_user fail\n", ld->name);
++              err = -EIO;
++              goto exit;
++      }
++      buff_size = plen;
++
++      ret = copy_to_user(target + 4, &buff_size, sizeof(int));
++      if (ret < 0) {
++              mif_info("%s: ERR! size copy_to_user fail\n", ld->name);
++              err = -EIO;
++              goto exit;
++      }
++
++      vfree(buff);
++      return err;
++
++exit:
++      if (buff)
++              vfree(buff);
++      iowrite32(0, dpld->ul_map.magic);
++      wake_unlock(&dpld->wlock);
++      return err;
++}
++
++static int cbp72_dump_update(struct dpram_link_device *dpld, void *arg)
++{
++      struct link_device *ld = &dpld->ld;
++      struct dpram_dump_arg dump;
++      int ret;
++
++      ret = copy_from_user(&dump, (void __user *)arg, sizeof(dump));
++      if (ret  < 0) {
++              mif_info("%s: ERR! copy_from_user fail\n", ld->name);
++              return ret;
++      }
++
++      return _cbp72_edpram_upload(dpld, &dump, (unsigned char __user *)arg);
++}
++
++static int cbp72_set_dl_magic(struct link_device *ld, struct io_device *iod)
++{
++      struct dpram_link_device *dpld = to_dpram_link_device(ld);
++
++      ld->mode = LINK_MODE_DLOAD;
++
++      iowrite32(DP_MAGIC_DMDL, dpld->dl_map.magic);
++
++      return 0;
++}
++
++static int cbp72_ioctl(struct dpram_link_device *dpld, struct io_device *iod,
++              unsigned int cmd, unsigned long arg)
++{
++      struct link_device *ld = &dpld->ld;
++      int err = 0;
++
++      switch (cmd) {
++      case IOCTL_MODEM_DL_START:
++              err = cbp72_set_dl_magic(ld, iod);
++              if (err < 0)
++                      mif_err("%s: ERR! set_dl_magic fail\n", ld->name);
++              break;
++
++      default:
++              mif_err("%s: ERR! invalid cmd 0x%08X\n", ld->name, cmd);
++              err = -EINVAL;
++              break;
++      }
++
++      return err;
++}
++#endif
++
++#if defined(CONFIG_LTE_MODEM_CMC221)
++/* For CMC221 SFR for IDPRAM */
++#define CMC_INT2CP_REG                0x10    /* Interrupt to CP            */
++#define CMC_INT2AP_REG                0x50
++#define CMC_CLR_INT_REG               0x28    /* Clear Interrupt to AP      */
++#define CMC_RESET_REG         0x3C
++#define CMC_PUT_REG           0x40    /* AP->CP reg for hostbooting */
++#define CMC_GET_REG           0x50    /* CP->AP reg for hostbooting */
++
++static void cmc221_init_boot_map(struct dpram_link_device *dpld)
++{
++      struct dpram_boot_map *bt_map = &dpld->bt_map;
++
++      bt_map->buff = dpld->base;
++      bt_map->size = dpld->size;
++      bt_map->req = (u32 *)(dpld->base + DP_BOOT_REQ_OFFSET);
++      bt_map->resp = (u32 *)(dpld->base + DP_BOOT_RESP_OFFSET);
++}
++
++static void cmc221_init_dl_map(struct dpram_link_device *dpld)
++{
++      dpld->dl_map.magic = (u32 *)dpld->base;
++      dpld->dl_map.buff = (u8 *)dpld->base;
++}
++
++static void cmc221_init_ul_map(struct dpram_link_device *dpld)
++{
++      dpld->ul_map.magic = (u32 *)dpld->base;
++      dpld->ul_map.buff = (u8 *)dpld->base;
++}
++
++static void cmc221_init_ipc_map(struct dpram_link_device *dpld)
++{
++      struct dpram_ipc_16k_map *dpram_map;
++      struct dpram_ipc_device *dev;
++      u8 __iomem *sfr_base = dpld->sfr_base;
++
++      dpram_map = (struct dpram_ipc_16k_map *)dpld->base;
++
++      /* Magic code and access enable fields */
++      dpld->ipc_map.magic = (u16 __iomem *)&dpram_map->magic;
++      dpld->ipc_map.access = (u16 __iomem *)&dpram_map->access;
++
++      /* FMT */
++      dev = &dpld->ipc_map.dev[IPC_FMT];
++
++      strcpy(dev->name, "FMT");
++      dev->id = IPC_FMT;
++
++      dev->txq.head = (u16 __iomem *)&dpram_map->fmt_tx_head;
++      dev->txq.tail = (u16 __iomem *)&dpram_map->fmt_tx_tail;
++      dev->txq.buff = (u8 __iomem *)&dpram_map->fmt_tx_buff[0];
++      dev->txq.size = DP_16K_FMT_TX_BUFF_SZ;
++
++      dev->rxq.head = (u16 __iomem *)&dpram_map->fmt_rx_head;
++      dev->rxq.tail = (u16 __iomem *)&dpram_map->fmt_rx_tail;
++      dev->rxq.buff = (u8 __iomem *)&dpram_map->fmt_rx_buff[0];
++      dev->rxq.size = DP_16K_FMT_RX_BUFF_SZ;
++
++      dev->mask_req_ack = INT_MASK_REQ_ACK_F;
++      dev->mask_res_ack = INT_MASK_RES_ACK_F;
++      dev->mask_send    = INT_MASK_SEND_F;
++
++      /* RAW */
++      dev = &dpld->ipc_map.dev[IPC_RAW];
++
++      strcpy(dev->name, "RAW");
++      dev->id = IPC_RAW;
++
++      dev->txq.head = (u16 __iomem *)&dpram_map->raw_tx_head;
++      dev->txq.tail = (u16 __iomem *)&dpram_map->raw_tx_tail;
++      dev->txq.buff = (u8 __iomem *)&dpram_map->raw_tx_buff[0];
++      dev->txq.size = DP_16K_RAW_TX_BUFF_SZ;
++
++      dev->rxq.head = (u16 __iomem *)&dpram_map->raw_rx_head;
++      dev->rxq.tail = (u16 __iomem *)&dpram_map->raw_rx_tail;
++      dev->rxq.buff = (u8 __iomem *)&dpram_map->raw_rx_buff[0];
++      dev->rxq.size = DP_16K_RAW_RX_BUFF_SZ;
++
++      dev->mask_req_ack = INT_MASK_REQ_ACK_R;
++      dev->mask_res_ack = INT_MASK_RES_ACK_R;
++      dev->mask_send    = INT_MASK_SEND_R;
++
++      /* SFR */
++      dpld->sfr.int2cp = (u16 __iomem *)(sfr_base + CMC_INT2CP_REG);
++      dpld->sfr.int2ap = (u16 __iomem *)(sfr_base + CMC_INT2AP_REG);
++      dpld->sfr.clr_int2ap = (u16 __iomem *)(sfr_base + CMC_CLR_INT_REG);
++      dpld->sfr.reset = (u16 __iomem *)(sfr_base + CMC_RESET_REG);
++      dpld->sfr.msg2cp = (u16 __iomem *)(sfr_base + CMC_PUT_REG);
++      dpld->sfr.msg2ap = (u16 __iomem *)(sfr_base + CMC_GET_REG);
++
++      /* Interrupt ports */
++      dpld->ipc_map.mbx_cp2ap = dpld->sfr.int2ap;
++      dpld->ipc_map.mbx_ap2cp = dpld->sfr.int2cp;
++}
++
++static inline void cmc221_idpram_reset(struct dpram_link_device *dpld)
++{
++      iowrite16(1, dpld->sfr.reset);
++}
++
++static inline u16 cmc221_idpram_recv_msg(struct dpram_link_device *dpld)
++{
++      return ioread16(dpld->sfr.msg2ap);
++}
++
++static inline void cmc221_idpram_send_msg(struct dpram_link_device *dpld,
++                                      u16 msg)
++{
++      iowrite16(msg, dpld->sfr.msg2cp);
++}
++
++static int _cmc221_idpram_wait_resp(struct dpram_link_device *dpld, u32 resp)
++{
++      struct link_device *ld = &dpld->ld;
++      int count = 50000;
++      u32 rcvd = 0;
++
++      if (resp == CMC22x_CP_REQ_NV_DATA) {
++              while (1) {
++                      rcvd = ioread32(dpld->bt_map.resp);
++                      if (rcvd == resp)
++                              break;
++
++                      rcvd = cmc221_idpram_recv_msg(dpld);
++                      if (rcvd == 0x9999) {
++                              mif_info("%s: Invalid resp 0x%04X\n",
++                                      ld->name, rcvd);
++                              panic("CP Crash ... BAD CRC in CP");
++                      }
++
++                      if (count-- < 0) {
++                              mif_info("%s: Invalid resp 0x%08X\n",
++                                      ld->name, rcvd);
++                              return -EAGAIN;
++                      }
++
++                      udelay(100);
++              }
++      } else {
++              while (1) {
++                      rcvd = cmc221_idpram_recv_msg(dpld);
++
++                      if (rcvd == resp)
++                              break;
++
++                      if (resp == CMC22x_CP_RECV_NV_END &&
++                          rcvd == CMC22x_CP_CAL_BAD) {
++                              mif_info("%s: CMC22x_CP_CAL_BAD\n", ld->name);
++                              break;
++                      }
++
++                      if (count-- < 0) {
++                              mif_info("%s: Invalid resp 0x%04X\n",
++                                      ld->name, rcvd);
++                              return -EAGAIN;
++                      }
++
++                      udelay(100);
++              }
++      }
++
++      return rcvd;
++}
++
++static int _cmc221_idpram_send_boot(struct dpram_link_device *dpld, void *arg)
++{
++      struct link_device *ld = &dpld->ld;
++      u8 __iomem *bt_buff = dpld->bt_map.buff;
++      struct dpram_boot_img cp_img;
++      u8 *img_buff = NULL;
++      int err = 0;
++      int cnt = 0;
++
++      ld->mode = LINK_MODE_BOOT;
++
++      dpld->dpctl->setup_speed(DPRAM_SPEED_LOW);
++
++      /* Test memory... After testing, memory is cleared. */
++      if (mif_test_dpram(ld->name, bt_buff, dpld->bt_map.size) < 0) {
++              mif_info("%s: ERR! mif_test_dpram fail!\n", ld->name);
++              ld->mode = LINK_MODE_OFFLINE;
++              return -EIO;
++      }
++
++      memset(&cp_img, 0, sizeof(struct dpram_boot_img));
++
++      /* Get information about the boot image */
++      err = copy_from_user(&cp_img, arg, sizeof(cp_img));
++      mif_info("%s: CP image addr = 0x%08X, size = %d\n",
++              ld->name, (int)cp_img.addr, cp_img.size);
++
++      /* Alloc a buffer for the boot image */
++      img_buff = kzalloc(dpld->bt_map.size, GFP_KERNEL);
++      if (!img_buff) {
++              mif_info("%s: ERR! kzalloc fail\n", ld->name);
++              ld->mode = LINK_MODE_OFFLINE;
++              return -ENOMEM;
++      }
++
++      /* Copy boot image from the user space to the image buffer */
++      err = copy_from_user(img_buff, cp_img.addr, cp_img.size);
++
++      /* Copy boot image to DPRAM and verify it */
++      memcpy(bt_buff, img_buff, cp_img.size);
++      if (memcmp16_to_io(bt_buff, img_buff, cp_img.size)) {
++              mif_info("%s: ERR! Boot may be broken!!!\n", ld->name);
++              goto err;
++      }
++
++      cmc221_idpram_reset(dpld);
++      usleep_range(1000, 2000);
++
++      if (cp_img.mode == HOST_BOOT_MODE_NORMAL) {
++              mif_info("%s: HOST_BOOT_MODE_NORMAL\n", ld->name);
++              mif_info("%s: Send req 0x%08X\n", ld->name, cp_img.req);
++              iowrite32(cp_img.req, dpld->bt_map.req);
++
++              /* Wait for cp_img.resp for up to 2 seconds */
++              mif_info("%s: Wait resp 0x%08X\n", ld->name, cp_img.resp);
++              while (ioread32(dpld->bt_map.resp) != cp_img.resp) {
++                      cnt++;
++                      usleep_range(1000, 2000);
++
++                      if (cnt > 1000) {
++                              mif_info("%s: ERR! Invalid resp 0x%08X\n",
++                                      ld->name, ioread32(dpld->bt_map.resp));
++                              goto err;
++                      }
++              }
++      } else {
++              mif_info("%s: HOST_BOOT_MODE_DUMP\n", ld->name);
++      }
++
++      kfree(img_buff);
++
++      mif_info("%s: Send BOOT done\n", ld->name);
++
++      dpld->dpctl->setup_speed(DPRAM_SPEED_HIGH);
++
++      return 0;
++
++err:
++      ld->mode = LINK_MODE_OFFLINE;
++      kfree(img_buff);
++
++      mif_info("%s: ERR! Boot send fail!!!\n", ld->name);
++      return -EIO;
++}
++
++static int cmc221_download_boot(struct dpram_link_device *dpld, void *arg)
++{
++      if (dpld->type == CP_IDPRAM)
++              return _cmc221_idpram_send_boot(dpld, arg);
++      else
++              return -ENODEV;
++}
++
++static int _cmc221_idpram_download_bin(struct dpram_link_device *dpld,
++                      struct sk_buff *skb)
++{
++      int err = 0;
++      int ret = 0;
++      struct link_device *ld = &dpld->ld;
++      struct dpram_boot_frame *bf = (struct dpram_boot_frame *)skb->data;
++      u8 __iomem *buff = (dpld->bt_map.buff + bf->offset);
++
++      if ((bf->offset + bf->len) > dpld->bt_map.size) {
++              mif_info("%s: ERR! Out of DPRAM boundary\n", ld->name);
++              err = -EINVAL;
++              goto exit;
++      }
++
++      if (bf->len)
++              memcpy(buff, bf->data, bf->len);
++
++      if (bf->req)
++              cmc221_idpram_send_msg(dpld, (u16)bf->req);
++
++      if (bf->resp) {
++              err = _cmc221_idpram_wait_resp(dpld, bf->resp);
++              if (err < 0)
++                      mif_info("%s: ERR! wait_response fail (err %d)\n",
++                              ld->name, err);
++      }
++
++      if (bf->req == CMC22x_CAL_NV_DOWN_END)
++              mif_info("%s: CMC22x_CAL_NV_DOWN_END\n", ld->name);
++
++exit:
++      if (err < 0)
++              ret = err;
++      else
++              ret = skb->len;
++
++      dev_kfree_skb_any(skb);
++
++      return ret;
++}
++
++static int cmc221_download_binary(struct dpram_link_device *dpld,
++                      struct sk_buff *skb)
++{
++      if (dpld->type == CP_IDPRAM)
++              return _cmc221_idpram_download_bin(dpld, skb);
++      else
++              return -ENODEV;
++}
++
++static int cmc221_dump_start(struct dpram_link_device *dpld)
++{
++      struct link_device *ld = &dpld->ld;
++      int ret;
++
++      ld->mode = LINK_MODE_ULOAD;
++
++      ret = del_timer(&dpld->crash_timer);
++      wake_lock(&dpld->wlock);
++
++      dpld->crash_rcvd = 0;
++      iowrite32(CMC22x_CP_DUMP_MAGIC, dpld->ul_map.magic);
++
++      init_completion(&dpld->crash_start_complete);
++
++      return 0;
++}
++
++static void _cmc221_idpram_wait_dump(unsigned long arg)
++{
++      struct dpram_link_device *dpld = (struct dpram_link_device *)arg;
++      u16 msg;
++
++      msg = cmc221_idpram_recv_msg(dpld);
++      if (msg == CMC22x_CP_DUMP_END) {
++              complete_all(&dpld->crash_recv_done);
++              return;
++      }
++
++      if (((dpld->crash_rcvd & 0x1) == 0) && (msg == CMC22x_1ST_BUFF_FULL)) {
++              complete_all(&dpld->crash_recv_done);
++              return;
++      }
++
++      if (((dpld->crash_rcvd & 0x1) == 1) && (msg == CMC22x_2ND_BUFF_FULL)) {
++              complete_all(&dpld->crash_recv_done);
++              return;
++      }
++
++      mif_add_timer(&dpld->crash_timer, DUMP_WAIT_TIMEOUT,
++              _cmc221_idpram_wait_dump, (unsigned long)dpld);
++}
++
++static int _cmc221_idpram_upload(struct dpram_link_device *dpld,
++              struct dpram_dump_arg *dumparg)
++{
++      struct link_device *ld = &dpld->ld;
++      int ret;
++      u8 __iomem *src;
++      int buff_size = CMC22x_DUMP_BUFF_SIZE;
++
++      if ((dpld->crash_rcvd & 0x1) == 0)
++              cmc221_idpram_send_msg(dpld, CMC22x_1ST_BUFF_READY);
++      else
++              cmc221_idpram_send_msg(dpld, CMC22x_2ND_BUFF_READY);
++
++      init_completion(&dpld->crash_recv_done);
++
++      mif_add_timer(&dpld->crash_timer, DUMP_WAIT_TIMEOUT,
++              _cmc221_idpram_wait_dump, (unsigned long)dpld);
++
++      ret = wait_for_completion_interruptible_timeout(
++                      &dpld->crash_recv_done, DUMP_TIMEOUT);
++      if (!ret) {
++              mif_info("%s: ERR! CP didn't send dump data!!!\n", ld->name);
++              goto err_out;
++      }
++
++      if (cmc221_idpram_recv_msg(dpld) == CMC22x_CP_DUMP_END) {
++              mif_info("%s: CMC22x_CP_DUMP_END\n", ld->name);
++              return 0;
++      }
++
++      if ((dpld->crash_rcvd & 0x1) == 0)
++              src = dpld->ul_map.buff;
++      else
++              src = dpld->ul_map.buff + CMC22x_DUMP_BUFF_SIZE;
++
++      memcpy(dpld->buff, src, buff_size);
++
++      ret = copy_to_user(dumparg->buff, dpld->buff, buff_size);
++      if (ret < 0) {
++              mif_info("%s: ERR! copy_to_user fail\n", ld->name);
++              goto err_out;
++      }
++
++      dpld->crash_rcvd++;
++      return buff_size;
++
++err_out:
++      return -EIO;
++}
++
++static int cmc221_dump_update(struct dpram_link_device *dpld, void *arg)
++{
++      struct link_device *ld = &dpld->ld;
++      struct dpram_dump_arg dump;
++      int ret;
++
++      ret = copy_from_user(&dump, (void __user *)arg, sizeof(dump));
++      if (ret  < 0) {
++              mif_info("%s: ERR! copy_from_user fail\n", ld->name);
++              return ret;
++      }
++
++      return _cmc221_idpram_upload(dpld, &dump);
++}
++
++static int cmc221_ioctl(struct dpram_link_device *dpld, struct io_device *iod,
++              unsigned int cmd, unsigned long arg)
++{
++      struct link_device *ld = &dpld->ld;
++      int err = 0;
++
++      switch (cmd) {
++      case IOCTL_DPRAM_SEND_BOOT:
++              err = cmc221_download_boot(dpld, (void *)arg);
++              if (err < 0)
++                      mif_info("%s: ERR! download_boot fail\n", ld->name);
++              break;
++
++      default:
++              mif_err("%s: ERR! invalid cmd 0x%08X\n", ld->name, cmd);
++              err = -EINVAL;
++              break;
++      }
++
++      return err;
++}
++
++static void cmc221_idpram_clr_int2ap(struct dpram_link_device *dpld)
++{
++      iowrite16(0xFFFF, dpld->sfr.clr_int2ap);
++}
++
++static int cmc221_idpram_wakeup(struct dpram_link_device *dpld)
++{
++      struct link_device *ld = &dpld->ld;
++      struct modem_data *mdm_data = ld->mdm_data;
++      int cnt = 0;
++
++      gpio_set_value(mdm_data->gpio_dpram_wakeup, 1);
++
++      while (!gpio_get_value(mdm_data->gpio_dpram_status)) {
++              if (cnt++ > 10) {
++                      if (in_irq())
++                              mif_err("ERR! gpio_dpram_status == 0 in IRQ\n");
++                      else
++                              mif_err("ERR! gpio_dpram_status == 0\n");
++                      return -EACCES;
++              }
++
++              mif_info("gpio_dpram_status == 0 (cnt %d)\n", cnt);
++              if (in_interrupt())
++                      udelay(1000);
++              else
++                      usleep_range(1000, 2000);
++      }
++
++      return 0;
++}
++
++static void cmc221_idpram_sleep(struct dpram_link_device *dpld)
++{
++      struct link_device *ld = &dpld->ld;
++      gpio_set_value(ld->mdm_data->gpio_dpram_wakeup, 0);
++}
++#endif
++
++#if defined(CONFIG_CDMA_MODEM_MDM6600) || defined(CONFIG_GSM_MODEM_ESC6270)
++enum qc_dload_tag {
++      QC_DLOAD_TAG_NONE = 0,
++      QC_DLOAD_TAG_BIN,
++      QC_DLOAD_TAG_NV,
++      QC_DLOAD_TAG_MAX
++};
++
++static void qc_dload_task(unsigned long data);
++
++static void qc_init_boot_map(struct dpram_link_device *dpld)
++{
++      struct qc_dpram_boot_map *qbt_map = &dpld->qc_bt_map;
++      struct modemlink_dpram_control *dpctl = dpld->dpctl;
++
++      qbt_map->buff = dpld->base;
++      qbt_map->frame_size = (u16 *)(dpld->base + dpctl->boot_size_offset);
++      qbt_map->tag = (u16 *)(dpld->base + dpctl->boot_tag_offset);
++      qbt_map->count = (u16 *)(dpld->base + dpctl->boot_count_offset);
++
++      tasklet_init(&dpld->dl_tsk, qc_dload_task, (unsigned long)dpld);
++}
++
++static int qc_prepare_download(struct dpram_link_device *dpld)
++{
++      int retval = 0;
++      int count = 0;
++
++      while (1) {
++              if (dpld->udl_check.copy_start) {
++                      dpld->udl_check.copy_start = 0;
++                      break;
++              }
++
++              usleep_range(10000, 11000);
++
++              count++;
++              if (count > 200) {
++                      mif_err("ERR! count %d\n", count);
++                      return -1;
++              }
++      }
++
++      return retval;
++}
++
++static void _qc_do_download(struct dpram_link_device *dpld,
++                      struct dpram_udl_param *param)
++{
++      struct qc_dpram_boot_map *qbt_map = &dpld->qc_bt_map;
++
++      if (param->size <= dpld->dpctl->max_boot_frame_size) {
++              memcpy(qbt_map->buff, param->addr, param->size);
++              iowrite16(param->size, qbt_map->frame_size);
++              iowrite16(param->tag, qbt_map->tag);
++              iowrite16(param->count, qbt_map->count);
++              dpld->send_intr(dpld, 0xDB12);
++      } else {
++              mif_info("param->size %d\n", param->size);
++      }
++}
++
++static int _qc_download(struct dpram_link_device *dpld, void *arg,
++                      enum qc_dload_tag tag)
++{
++      int retval = 0;
++      int count = 0;
++      int cnt_limit;
++      unsigned char *img;
++      struct dpram_udl_param param;
++
++      retval = copy_from_user((void *)&param, (void *)arg, sizeof(param));
++      if (retval < 0) {
++              mif_err("ERR! copy_from_user fail\n");
++              return -1;
++      }
++
++      img = vmalloc(param.size);
++      if (!img) {
++              mif_err("ERR! vmalloc fail\n");
++              return -1;
++      }
++      memset(img, 0, param.size);
++      memcpy(img, param.addr, param.size);
++
++      dpld->udl_check.total_size = param.size;
++      dpld->udl_check.rest_size = param.size;
++      dpld->udl_check.send_size = 0;
++      dpld->udl_check.copy_complete = 0;
++
++      dpld->udl_param.addr = img;
++      dpld->udl_param.size = dpld->dpctl->max_boot_frame_size;
++      if (tag == QC_DLOAD_TAG_NV)
++              dpld->udl_param.count = 1;
++      else
++              dpld->udl_param.count = param.count;
++      dpld->udl_param.tag = tag;
++
++      if (dpld->udl_check.rest_size < dpld->dpctl->max_boot_frame_size)
++              dpld->udl_param.size = dpld->udl_check.rest_size;
++
++      /* Download image (binary or NV) */
++      _qc_do_download(dpld, &dpld->udl_param);
++
++      /* Wait for completion
++      */
++      if (tag == QC_DLOAD_TAG_NV)
++              cnt_limit = 200;
++      else
++              cnt_limit = 1000;
++
++      while (1) {
++              if (dpld->udl_check.copy_complete) {
++                      dpld->udl_check.copy_complete = 0;
++                      retval = 0;
++                      break;
++              }
++
++              usleep_range(10000, 11000);
++
++              count++;
++              if (count > cnt_limit) {
++                      dpld->udl_check.total_size = 0;
++                      dpld->udl_check.rest_size = 0;
++                      mif_err("ERR! count %d\n", count);
++                      retval = -1;
++                      break;
++              }
++      }
++
++      vfree(img);
++
++      return retval;
++}
++
++static int qc_download_binary(struct dpram_link_device *dpld, void *arg)
++{
++      return _qc_download(dpld, arg, QC_DLOAD_TAG_BIN);
++}
++
++static int qc_download_nv(struct dpram_link_device *dpld, void *arg)
++{
++      return _qc_download(dpld, arg, QC_DLOAD_TAG_NV);
++}
++
++static void qc_dload_task(unsigned long data)
++{
++      struct dpram_link_device *dpld = (struct dpram_link_device *)data;
++
++      dpld->udl_check.send_size += dpld->udl_param.size;
++      dpld->udl_check.rest_size -= dpld->udl_param.size;
++
++      dpld->udl_param.addr += dpld->udl_param.size;
++
++      if (dpld->udl_check.send_size >= dpld->udl_check.total_size) {
++              dpld->udl_check.copy_complete = 1;
++              dpld->udl_param.tag = 0;
++              return;
++      }
++
++      if (dpld->udl_check.rest_size < dpld->dpctl->max_boot_frame_size)
++              dpld->udl_param.size = dpld->udl_check.rest_size;
++
++      dpld->udl_param.count += 1;
++
++      _qc_do_download(dpld, &dpld->udl_param);
++}
++
++static void qc_dload_cmd_handler(struct dpram_link_device *dpld, u16 cmd)
++{
++      switch (cmd) {
++      case 0x1234:
++              dpld->udl_check.copy_start = 1;
++              break;
++
++      case 0xDBAB:
++              if (dpld->udl_check.total_size)
++                      tasklet_schedule(&dpld->dl_tsk);
++              break;
++
++      case 0xABCD:
++              dpld->udl_check.boot_complete = 1;
++              break;
++
++      default:
++              mif_err("ERR! unknown command 0x%04X\n", cmd);
++      }
++}
++
++static int qc_boot_start(struct dpram_link_device *dpld)
++{
++      u16 mask = 0;
++      int count = 0;
++
++      /* Send interrupt -> '0x4567' */
++      mask = 0x4567;
++      dpld->send_intr(dpld, mask);
++
++      while (1) {
++              if (dpld->udl_check.boot_complete) {
++                      dpld->udl_check.boot_complete = 0;
++                      break;
++              }
++
++              usleep_range(10000, 11000);
++
++              count++;
++              if (count > 200) {
++                      mif_err("ERR! count %d\n", count);
++                      return -1;
++              }
++      }
++
++      return 0;
++}
++
++static int qc_boot_post_process(struct dpram_link_device *dpld)
++{
++      int count = 0;
++
++      while (1) {
++              if (dpld->boot_start_complete) {
++                      dpld->boot_start_complete = 0;
++                      break;
++              }
++
++              usleep_range(10000, 11000);
++
++              count++;
++              if (count > 200) {
++                      mif_err("ERR! count %d\n", count);
++                      return -1;
++              }
++      }
++
++      return 0;
++}
++
++static void qc_start_handler(struct dpram_link_device *dpld)
++{
++      /*
++       * INT_MASK_VALID | INT_MASK_CMD | INT_MASK_CP_AIRPLANE_BOOT |
++       * INT_MASK_CP_AP_ANDROID | INT_MASK_CMD_INIT_END
++       */
++      u16 mask = (0x0080 | 0x0040 | 0x1000 | 0x0100 | 0x0002);
++
++      dpld->boot_start_complete = 1;
++
++      /* Send INIT_END code to CP */
++      mif_info("send 0x%04X (INIT_END)\n", mask);
++
++      dpld->send_intr(dpld, mask);
++}
++
++static void qc_crash_log(struct dpram_link_device *dpld)
++{
++      struct link_device *ld = &dpld->ld;
++      static unsigned char buf[151];
++      u8 __iomem *data = NULL;
++
++      data = dpld->get_rx_buff(dpld, IPC_FMT);
++      memcpy(buf, data, (sizeof(buf) - 1));
++
++      mif_info("PHONE ERR MSG\t| %s Crash\n", ld->mdm_data->name);
++      mif_info("PHONE ERR MSG\t| %s\n", buf);
++}
++
++static int _qc_data_upload(struct dpram_link_device *dpld,
++                      struct dpram_udl_param *param)
++{
++      struct qc_dpram_boot_map *qbt_map = &dpld->qc_bt_map;
++      int retval = 0;
++      u16 intval = 0;
++      int count = 0;
++
++      while (1) {
++              if (!gpio_get_value(dpld->gpio_dpram_int)) {
++                      intval = dpld->recv_intr(dpld);
++                      if (intval == 0xDBAB) {
++                              break;
++                      } else {
++                              mif_err("intr 0x%08x\n", intval);
++                              return -1;
++                      }
++              }
++
++              usleep_range(1000, 2000);
++
++              count++;
++              if (count > 200) {
++                      mif_err("<%s:%d>\n", __func__, __LINE__);
++                      return -1;
++              }
++      }
++
++      param->size = ioread16(qbt_map->frame_size);
++      memcpy(param->addr, qbt_map->buff, param->size);
++      param->tag = ioread16(qbt_map->tag);
++      param->count = ioread16(qbt_map->count);
++
++      dpld->send_intr(dpld, 0xDB12);
++
++      return retval;
++}
++
++static int qc_uload_step1(struct dpram_link_device *dpld)
++{
++      int retval = 0;
++      int count = 0;
++      u16 intval = 0;
++      u16 mask = 0;
++
++      mif_info("+---------------------------------------------+\n");
++      mif_info("|            UPLOAD PHONE SDRAM               |\n");
++      mif_info("+---------------------------------------------+\n");
++
++      while (1) {
++              if (!gpio_get_value(dpld->gpio_dpram_int)) {
++                      intval = dpld->recv_intr(dpld);
++                      mif_info("intr 0x%04x\n", intval);
++                      if (intval == 0x1234) {
++                              break;
++                      } else {
++                              mif_info("ERR! invalid intr\n");
++                              return -1;
++                      }
++              }
++
++              usleep_range(1000, 2000);
++
++              count++;
++              if (count > 200) {
++                      intval = dpld->recv_intr(dpld);
++                      mif_info("count %d, intr 0x%04x\n", count, intval);
++                      if (intval == 0x1234)
++                              break;
++                      return -1;
++              }
++      }
++
++      mask = 0xDEAD;
++      dpld->send_intr(dpld, mask);
++
++      return retval;
++}
++
++static int qc_uload_step2(struct dpram_link_device *dpld, void *arg)
++{
++      int retval = 0;
++      struct dpram_udl_param param;
++
++      retval = copy_from_user((void *)&param, (void *)arg, sizeof(param));
++      if (retval < 0) {
++              mif_err("ERR! copy_from_user fail (err %d)\n", retval);
++              return -1;
++      }
++
++      retval = _qc_data_upload(dpld, &param);
++      if (retval < 0) {
++              mif_err("ERR! _qc_data_upload fail (err %d)\n", retval);
++              return -1;
++      }
++
++      if (!(param.count % 500))
++              mif_info("param->count = %d\n", param.count);
++
++      if (param.tag == 4) {
++              enable_irq(dpld->irq);
++              mif_info("param->tag = %d\n", param.tag);
++      }
++
++      retval = copy_to_user((unsigned long *)arg, &param, sizeof(param));
++      if (retval < 0) {
++              mif_err("ERR! copy_to_user fail (err %d)\n", retval);
++              return -1;
++      }
++
++      return retval;
++}
++
++static int qc_ioctl(struct dpram_link_device *dpld, struct io_device *iod,
++              unsigned int cmd, unsigned long arg)
++{
++      struct link_device *ld = &dpld->ld;
++      int err = 0;
++
++      switch (cmd) {
++      case IOCTL_DPRAM_PHONE_POWON:
++              err = qc_prepare_download(dpld);
++              if (err < 0)
++                      mif_info("%s: ERR! prepare_download fail\n", ld->name);
++              break;
++
++      case IOCTL_DPRAM_PHONEIMG_LOAD:
++              err = qc_download_binary(dpld, (void *)arg);
++              if (err < 0)
++                      mif_info("%s: ERR! download_binary fail\n", ld->name);
++              break;
++
++      case IOCTL_DPRAM_NVDATA_LOAD:
++              err = qc_download_nv(dpld, (void *)arg);
++              if (err < 0)
++                      mif_info("%s: ERR! download_nv fail\n", ld->name);
++              break;
++
++      case IOCTL_DPRAM_PHONE_BOOTSTART:
++              err = qc_boot_start(dpld);
++              if (err < 0) {
++                      mif_info("%s: ERR! boot_start fail\n", ld->name);
++                      break;
++              }
++
++              err = qc_boot_post_process(dpld);
++              if (err < 0)
++                      mif_info("%s: ERR! boot_post_process fail\n", ld->name);
++
++              break;
++
++      case IOCTL_DPRAM_PHONE_UPLOAD_STEP1:
++              disable_irq_nosync(dpld->irq);
++              err = qc_uload_step1(dpld);
++              if (err < 0) {
++                      enable_irq(dpld->irq);
++                      mif_info("%s: ERR! upload_step1 fail\n", ld->name);
++              }
++              break;
++
++      case IOCTL_DPRAM_PHONE_UPLOAD_STEP2:
++              err = qc_uload_step2(dpld, (void *)arg);
++              if (err < 0) {
++                      enable_irq(dpld->irq);
++                      mif_info("%s: ERR! upload_step2 fail\n", ld->name);
++              }
++              break;
++
++      default:
++              mif_err("%s: ERR! invalid cmd 0x%08X\n", ld->name, cmd);
++              err = -EINVAL;
++              break;
++      }
++
++      return err;
++}
++
++static irqreturn_t qc_dpram_irq_handler(int irq, void *data)
++{
++      struct dpram_link_device *dpld = (struct dpram_link_device *)data;
++      struct link_device *ld = (struct link_device *)&dpld->ld;
++      u16 int2ap = 0;
++
++      if (unlikely(ld->mode == LINK_MODE_OFFLINE))
++              return IRQ_HANDLED;
++
++      int2ap = dpld->recv_intr(dpld);
++
++      if (int2ap == INT_POWERSAFE_FAIL) {
++              mif_info("%s: int2ap == INT_POWERSAFE_FAIL\n", ld->name);
++              goto exit;
++      }
++
++      if (int2ap == 0x1234 || int2ap == 0xDBAB || int2ap == 0xABCD) {
++              qc_dload_cmd_handler(dpld, int2ap);
++              goto exit;
++      }
++
++      if (likely(INT_VALID(int2ap)))
++              dpld->ipc_rx_handler(dpld, int2ap);
++      else
++              mif_info("%s: ERR! invalid intr 0x%04X\n", ld->name, int2ap);
++
++exit:
++      return IRQ_HANDLED;
++}
++#endif
++
++static struct dpram_ext_op ext_op_set[] = {
++#ifdef CONFIG_CDMA_MODEM_CBP72
++      [VIA_CBP72] = {
++              .exist = 1,
++              .init_boot_map = cbp72_init_boot_map,
++              .init_dl_map = cbp72_init_dl_map,
++              .download_binary = cbp72_download_binary,
++              .dump_start = cbp72_dump_start,
++              .dump_update = cbp72_dump_update,
++              .ioctl = cbp72_ioctl,
++      },
++#endif
++#ifdef CONFIG_LTE_MODEM_CMC221
++      [SEC_CMC221] = {
++              .exist = 1,
++              .init_boot_map = cmc221_init_boot_map,
++              .init_dl_map = cmc221_init_dl_map,
++              .init_ul_map = cmc221_init_ul_map,
++              .init_ipc_map = cmc221_init_ipc_map,
++              .download_binary = cmc221_download_binary,
++              .dump_start = cmc221_dump_start,
++              .dump_update = cmc221_dump_update,
++              .ioctl = cmc221_ioctl,
++              .clear_intr = cmc221_idpram_clr_int2ap,
++              .wakeup = cmc221_idpram_wakeup,
++              .sleep = cmc221_idpram_sleep,
++      },
++#endif
++#if defined(CONFIG_CDMA_MODEM_MDM6600)
++      [QC_MDM6600] = {
++              .exist = 1,
++              .init_boot_map = qc_init_boot_map,
++              .cp_start_handler = qc_start_handler,
++              .crash_log = qc_crash_log,
++              .ioctl = qc_ioctl,
++              .irq_handler = qc_dpram_irq_handler,
++      },
++#endif
++#if defined(CONFIG_GSM_MODEM_ESC6270)
++      [QC_ESC6270] = {
++              .exist = 1,
++              .init_boot_map = qc_init_boot_map,
++              .cp_start_handler = qc_start_handler,
++              .crash_log = qc_crash_log,
++              .ioctl = qc_ioctl,
++              .irq_handler = qc_dpram_irq_handler,
++      },
++#endif
++};
++
++struct dpram_ext_op *dpram_get_ext_op(enum modem_t modem)
++{
++      if (ext_op_set[modem].exist)
++              return &ext_op_set[modem];
++      else
++              return NULL;
++}
++
+diff --git a/drivers/misc/modem_if/modem_link_device_hsic.c b/drivers/misc/modem_if/modem_link_device_hsic.c
+new file mode 100644
+index 0000000..bb8066a
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_link_device_hsic.c
+@@ -0,0 +1,1654 @@
++/* /linux/drivers/new_modem_if/link_dev_usb.c
++ *
++ * Copyright (C) 2010 Google, Inc.
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/device.h>
++#include <linux/sched.h>
++#include <linux/irq.h>
++#include <linux/poll.h>
++#include <linux/gpio.h>
++#include <linux/if_arp.h>
++#include <linux/usb.h>
++#include <linux/usb/cdc.h>
++#include <linux/pm_runtime.h>
++#include <linux/cdev.h>
++#include <linux/platform_device.h>
++#ifdef CONFIG_HAS_WAKELOCK
++#include <linux/wakelock.h>
++#endif
++#include <linux/suspend.h>
++#include <linux/version.h>
++
++#include <linux/platform_data/modem.h>
++#include "modem_prj.h"
++#include "modem_link_device_hsic.h"
++#include "modem_utils.h"
++
++static struct modem_ctl *if_usb_get_modemctl(struct link_pm_data *pm_data);
++static int link_pm_runtime_get_active(struct link_pm_data *pm_data);
++static int usb_tx_urb_with_skb(struct usb_device *usbdev, struct sk_buff *skb,
++                                      struct if_usb_devdata *pipe_data);
++#ifdef FOR_TEGRA
++#define ehci_vendor_txfilltuning tegra_ehci_txfilltuning
++#else
++#define ehci_vendor_txfilltuning()
++#endif
++static void usb_rx_complete(struct urb *urb);
++
++static int start_ipc(struct link_device *ld, struct io_device *iod)
++{
++      struct sk_buff *skb;
++      char data[1] = {'a'};
++      int err;
++      struct usb_link_device *usb_ld = to_usb_link_device(ld);
++      struct link_pm_data *pm_data = usb_ld->link_pm_data;
++      struct device *dev = &usb_ld->usbdev->dev;
++      struct if_usb_devdata *pipe_data = &usb_ld->devdata[IF_USB_FMT_EP];
++
++      if (!usb_ld->if_usb_connected) {
++              mif_err("HSIC not connected, skip start ipc\n");
++              err = -ENODEV;
++              goto exit;
++      }
++
++retry:
++      if (ld->mc->phone_state != STATE_ONLINE) {
++              mif_err("MODEM is not online, skip start ipc\n");
++              err = -ENODEV;
++              goto exit;
++      }
++
++      /* check usb runtime pm first */
++      if (dev->power.runtime_status != RPM_ACTIVE) {
++              if (!pm_data->resume_requested) {
++                      mif_debug("QW PM\n");
++                      INIT_COMPLETION(pm_data->active_done);
++                      queue_delayed_work(pm_data->wq,
++                                      &pm_data->link_pm_work, 0);
++              }
++              mif_debug("Wait pm\n");
++              err = wait_for_completion_timeout(&pm_data->active_done,
++                                                      msecs_to_jiffies(500));
++              /* timeout or -ERESTARTSYS */
++              if (err <= 0)
++                      goto retry;
++      }
++
++      pm_runtime_get_sync(dev);
++
++      mif_err("send 'a'\n");
++
++      skb = alloc_skb(16, GFP_ATOMIC);
++      if (unlikely(!skb)) {
++              pm_runtime_put(dev);
++              return -ENOMEM;
++      }
++      memcpy(skb_put(skb, 1), data, 1);
++      skbpriv(skb)->iod = iod;
++      skbpriv(skb)->ld = ld;
++
++      if (!usb_ld->if_usb_connected || !usb_ld->usbdev)
++              return -ENODEV;
++
++      usb_mark_last_busy(usb_ld->usbdev);
++      err = usb_tx_urb_with_skb(usb_ld->usbdev, skb, pipe_data);
++      if (err < 0) {
++              mif_err("usb_tx_urb fail\n");
++              dev_kfree_skb_any(skb);
++      }
++
++      pm_runtime_put(dev);
++exit:
++      return err;
++}
++
++static void stop_ipc(struct link_device *ld)
++{
++      ld->com_state = COM_NONE;
++}
++
++static int usb_init_communication(struct link_device *ld,
++                      struct io_device *iod)
++{
++      struct task_struct *task = get_current();
++      char str[TASK_COMM_LEN];
++
++      mif_info("%d:%s\n", task->pid, get_task_comm(str, task));
++
++      /* Send IPC Start ASCII 'a' */
++      if (iod->id == 0x1)
++              return start_ipc(ld, iod);
++
++      return 0;
++}
++
++static void usb_terminate_communication(struct link_device *ld,
++                      struct io_device *iod)
++{
++      if (iod->id != 0x1 || iod->format != IPC_FMT)
++              return;
++
++      if (iod->mc->phone_state == STATE_CRASH_RESET ||
++                      iod->mc->phone_state == STATE_CRASH_EXIT)
++              stop_ipc(ld);
++}
++
++static int usb_rx_submit(struct usb_link_device *usb_ld,
++                                      struct if_usb_devdata *pipe_data,
++                                      gfp_t gfp_flags)
++{
++      int ret;
++      struct urb *urb;
++
++      if (pipe_data->disconnected)
++              return -ENOENT;
++
++      ehci_vendor_txfilltuning();
++
++      urb = pipe_data->urb;
++
++      urb->transfer_flags = 0;
++      usb_fill_bulk_urb(urb, pipe_data->usbdev,
++                              pipe_data->rx_pipe, pipe_data->rx_buf,
++                              pipe_data->rx_buf_size, usb_rx_complete,
++                              (void *)pipe_data);
++
++      if (pipe_data->disconnected)
++              return -ENOENT;
++
++      usb_mark_last_busy(usb_ld->usbdev);
++      ret = usb_submit_urb(urb, gfp_flags);
++      if (ret)
++              mif_err("submit urb fail with ret (%d)\n", ret);
++
++      return ret;
++}
++
++static void usb_rx_retry_work(struct work_struct *work)
++{
++      int ret = 0;
++      struct usb_link_device *usb_ld =
++              container_of(work, struct usb_link_device, rx_retry_work.work);
++      struct urb *urb = usb_ld->retry_urb;
++      struct if_usb_devdata *pipe_data = urb->context;
++      struct io_device *iod;
++      int iod_format;
++
++      if (!usb_ld->if_usb_connected || !usb_ld->usbdev)
++              return;
++
++      if (usb_ld->usbdev)
++              usb_mark_last_busy(usb_ld->usbdev);
++      switch (pipe_data->format) {
++      case IF_USB_FMT_EP:
++              if (usb_ld->if_usb_is_main) {
++                      pr_urb("IPC-RX, retry", urb);
++                      iod_format = IPC_FMT;
++              } else {
++                      iod_format = IPC_BOOT;
++              }
++              break;
++      case IF_USB_RAW_EP:
++              iod_format = IPC_MULTI_RAW;
++              break;
++      case IF_USB_RFS_EP:
++              iod_format = IPC_RFS;
++              pr_urb("RFS-RX, retry", urb);
++              break;
++      case IF_USB_CMD_EP:
++              iod_format = IPC_CMD;
++              break;
++      default:
++              iod_format = -1;
++              break;
++      }
++
++      iod = link_get_iod_with_format(&usb_ld->ld, iod_format);
++      if (iod) {
++              ret = iod->recv(iod, &usb_ld->ld, (char *)urb->transfer_buffer,
++                      urb->actual_length);
++              if (ret == -ENOMEM) {
++                      /* TODO: check the retry count */
++                      /* retry the delay work after 20ms and resubit*/
++                      mif_err("ENOMEM, +retry 20ms\n");
++                      if (usb_ld->usbdev)
++                              usb_mark_last_busy(usb_ld->usbdev);
++                      usb_ld->retry_urb = urb;
++                      if (usb_ld->rx_retry_cnt++ < 10)
++                              queue_delayed_work(usb_ld->ld.tx_wq,
++                                      &usb_ld->rx_retry_work, 10);
++                      return;
++              }
++              if (ret < 0)
++                      mif_err("io device recv error (%d)\n", ret);
++              usb_ld->rx_retry_cnt = 0;
++      }
++
++      if (usb_ld->usbdev)
++              usb_mark_last_busy(usb_ld->usbdev);
++      usb_rx_submit(usb_ld, pipe_data, GFP_ATOMIC);
++}
++
++
++static void usb_rx_complete(struct urb *urb)
++{
++      struct if_usb_devdata *pipe_data = urb->context;
++      struct usb_link_device *usb_ld = pipe_data->usb_ld;
++      struct io_device *iod;
++      int iod_format;
++      int ret;
++
++      if (usb_ld->usbdev)
++              usb_mark_last_busy(usb_ld->usbdev);
++
++      switch (urb->status) {
++      case -ENOENT:
++              /* case for 'link pm suspended but rx data had remained' */
++              mif_debug("urb->status = -ENOENT\n");
++      case 0:
++              if (!urb->actual_length) {
++                      mif_debug("urb has zero length!\n");
++                      goto rx_submit;
++              }
++
++              usb_ld->link_pm_data->rx_cnt++;
++              /* call iod recv */
++              /* how we can distinguish boot ch with fmt ch ?? */
++              switch (pipe_data->format) {
++              case IF_USB_FMT_EP:
++                      if (usb_ld->if_usb_is_main) {
++                              pr_urb("IPC-RX", urb);
++                              iod_format = IPC_FMT;
++                      } else {
++                              iod_format = IPC_BOOT;
++                      }
++                      break;
++              case IF_USB_RAW_EP:
++                      iod_format = IPC_MULTI_RAW;
++                      break;
++              case IF_USB_RFS_EP:
++                      iod_format = IPC_RFS;
++                      break;
++              case IF_USB_CMD_EP:
++                      iod_format = IPC_CMD;
++                      break;
++              default:
++                      iod_format = -1;
++                      break;
++              }
++
++              /* flow control CMD by CP, not use io device */
++              if (unlikely(iod_format == IPC_CMD)) {
++                      ret = link_rx_flowctl_cmd(&usb_ld->ld,
++                                      (char *)urb->transfer_buffer,
++                                      urb->actual_length);
++                      if (ret < 0)
++                              mif_err("no multi raw device (%d)\n", ret);
++                      goto rx_submit;
++              }
++
++              iod = link_get_iod_with_format(&usb_ld->ld, iod_format);
++              if (iod) {
++                      ret = iod->recv(iod,
++                                      &usb_ld->ld,
++                                      (char *)urb->transfer_buffer,
++                                      urb->actual_length);
++                      if (ret == -ENOMEM) {
++                              /* retry the delay work and resubit*/
++                              mif_err("ENOMEM, retry\n");
++                              if (usb_ld->usbdev)
++                                      usb_mark_last_busy(usb_ld->usbdev);
++                              usb_ld->retry_urb = urb;
++                              queue_delayed_work(usb_ld->ld.tx_wq,
++                                      &usb_ld->rx_retry_work, 0);
++                              return;
++                      }
++                      if (ret < 0)
++                              mif_err("io device recv error (%d)\n", ret);
++              }
++rx_submit:
++              if (urb->status == 0) {
++                      if (usb_ld->usbdev)
++                              usb_mark_last_busy(usb_ld->usbdev);
++                      usb_rx_submit(usb_ld, pipe_data, GFP_ATOMIC);
++              }
++              break;
++      default:
++              mif_err("urb err status = %d\n", urb->status);
++              break;
++      }
++}
++
++static int usb_send(struct link_device *ld, struct io_device *iod,
++                      struct sk_buff *skb)
++{
++      struct sk_buff_head *txq;
++      size_t tx_size;
++      struct usb_link_device *usb_ld = to_usb_link_device(ld);
++      struct link_pm_data *pm_data = usb_ld->link_pm_data;
++
++      switch (iod->format) {
++      case IPC_RAW:
++              txq = &ld->sk_raw_tx_q;
++
++              if (unlikely(ld->raw_tx_suspended)) {
++                      /* Unlike misc_write, vnet_xmit is in interrupt.
++                       * Despite call netif_stop_queue on CMD_SUSPEND,
++                       * packets can be reached here.
++                       */
++                      if (in_irq()) {
++                              mif_err("raw tx is suspended, "
++                                              "drop packet. size=%d",
++                                              skb->len);
++                              return -EBUSY;
++                      }
++
++                      mif_err("wait RESUME CMD...\n");
++                      INIT_COMPLETION(ld->raw_tx_resumed_by_cp);
++                      wait_for_completion(&ld->raw_tx_resumed_by_cp);
++                      mif_err("resumed done.\n");
++              }
++              break;
++      case IPC_BOOT:
++      case IPC_FMT:
++      case IPC_RFS:
++      default:
++              txq = &ld->sk_fmt_tx_q;
++              break;
++      }
++      /* store the tx size before run the tx_delayed_work*/
++      tx_size = skb->len;
++
++      /* drop packet, when link is not online */
++      if (ld->com_state == COM_BOOT && iod->format != IPC_BOOT) {
++              mif_err("%s: drop packet, size=%d, com_state=%d\n",
++                              iod->name, skb->len, ld->com_state);
++              dev_kfree_skb_any(skb);
++              return 0;
++      }
++
++      /* en queue skb data */
++      skb_queue_tail(txq, skb);
++      /* Hold wake_lock for getting schedule the tx_work */
++#ifdef CONFIG_HAS_WAKELOCK
++      wake_lock(&pm_data->tx_async_wake);
++#else
++      pm_stay_awake(pm_data->miscdev.this_device);
++#endif
++
++      if (!work_pending(&ld->tx_delayed_work.work))
++              queue_delayed_work(ld->tx_wq, &ld->tx_delayed_work, 0);
++
++      return tx_size;
++}
++
++static void usb_tx_complete(struct urb *urb)
++{
++      struct sk_buff *skb = urb->context;
++      struct io_device *iod = skbpriv(skb)->iod;
++      struct link_device *ld = skbpriv(skb)->ld;
++      struct usb_link_device *usb_ld = to_usb_link_device(ld);
++
++      switch (urb->status) {
++      case 0:
++              break;
++      case -ENOENT:
++      case -ECONNRESET:
++      case -ESHUTDOWN:
++      default:
++              if (iod->format != IPC_BOOT)
++                      mif_info("TX error (%d)\n", urb->status);
++      }
++
++      dev_kfree_skb_any(skb);
++      if (urb->dev && usb_ld->if_usb_connected)
++              usb_mark_last_busy(urb->dev);
++      usb_free_urb(urb);
++}
++
++/* Even if usb_tx_urb_with_skb is failed, does not release the skb to retry */
++static int usb_tx_urb_with_skb(struct usb_device *usbdev, struct sk_buff *skb,
++                                      struct if_usb_devdata *pipe_data)
++{
++      int ret;
++      struct urb *urb;
++
++      if (pipe_data->disconnected)
++              return -ENOENT;
++
++      urb = usb_alloc_urb(0, GFP_KERNEL);
++      if (!urb) {
++              mif_err("alloc urb error\n");
++              return -ENOMEM;
++      }
++
++      urb->transfer_flags = URB_ZERO_PACKET;
++      usb_fill_bulk_urb(urb, pipe_data->usbdev, pipe_data->tx_pipe, skb->data,
++                      skb->len, usb_tx_complete, (void *)skb);
++
++      usb_mark_last_busy(usbdev);
++      ret = usb_submit_urb(urb, GFP_KERNEL);
++      if (ret < 0) {
++              mif_err("usb_submit_urb with ret(%d)\n", ret);
++              usb_free_urb(urb);
++              return ret;
++      }
++      return 0;
++}
++
++
++static int _usb_tx_work(struct sk_buff *skb)
++{
++      struct sk_buff_head *txq;
++      struct io_device *iod = skbpriv(skb)->iod;
++      struct link_device *ld = skbpriv(skb)->ld;
++      struct usb_link_device *usb_ld = to_usb_link_device(ld);
++      struct if_usb_devdata *pipe_data;
++
++      switch (iod->format) {
++      case IPC_BOOT:
++      case IPC_FMT:
++              /* boot device uses same intf with fmt*/
++              pipe_data = &usb_ld->devdata[IF_USB_FMT_EP];
++              txq = &ld->sk_fmt_tx_q;
++              break;
++      case IPC_RAW:
++              pipe_data = &usb_ld->devdata[IF_USB_RAW_EP];
++              txq = &ld->sk_raw_tx_q;
++              break;
++      case IPC_RFS:
++              pipe_data = &usb_ld->devdata[IF_USB_RFS_EP];
++              txq = &ld->sk_fmt_tx_q;
++              break;
++      default:
++              /* wrong packet, drop it */
++              pipe_data =  NULL;
++              txq = NULL;
++              break;
++      }
++
++      if (!pipe_data)
++              return -ENOENT;
++
++      if (iod->format == IPC_FMT && usb_ld->if_usb_is_main)
++              pr_skb("IPC-TX", skb);
++
++      if (iod->format == IPC_RAW)
++              mif_debug("TX[RAW]\n");
++
++      return usb_tx_urb_with_skb(usb_ld->usbdev, skb, pipe_data);
++}
++
++
++static void usb_tx_work(struct work_struct *work)
++{
++      int ret = 0;
++      struct link_device *ld =
++              container_of(work, struct link_device, tx_delayed_work.work);
++      struct usb_link_device *usb_ld = to_usb_link_device(ld);
++      struct sk_buff *skb;
++      struct link_pm_data *pm_data = usb_ld->link_pm_data;
++
++      if (!usb_ld->usbdev) {
++              mif_info("usbdev is invalid\n");
++              return;
++      }
++
++      pm_data->tx_cnt++;
++
++      while (ld->sk_fmt_tx_q.qlen || ld->sk_raw_tx_q.qlen) {
++              /* request and check usb runtime pm first */
++              ret = link_pm_runtime_get_active(pm_data);
++              if (ret < 0) {
++                      if (ret == -ENODEV) {
++                              mif_err("link not avail, retry reconnect.\n");
++                              goto exit;
++                      }
++                      goto retry_tx_work;
++              }
++
++              /* If AP try to tx when interface disconnect->reconnect probe,
++               * usbdev was created but one of interface channel device are
++               * probing, _usb_tx_work return to -ENOENT then runtime usage
++               * count allways positive and never enter to L2
++               */
++              if (!usb_ld->if_usb_connected) {
++                      mif_info("link is available, but if  was not readey\n");
++                      goto retry_tx_work;
++              }
++              pm_runtime_get_sync(&usb_ld->usbdev->dev);
++
++              ret = 0;
++              /* send skb from fmt_txq and raw_txq,*/
++              /* one by one for fair flow control */
++              skb = skb_dequeue(&ld->sk_fmt_tx_q);
++              if (skb)
++                      ret = _usb_tx_work(skb);
++
++              if (ret) {
++                      mif_err("usb_tx_urb_with_skb for fmt_q %d\n", ret);
++                      skb_queue_head(&ld->sk_fmt_tx_q, skb);
++
++                      if (ret == -ENODEV || ret == -ENOENT)
++                              goto exit;
++
++                      /* tx fail and usbdev alived, retry tx work */
++                      pm_runtime_put(&usb_ld->usbdev->dev);
++                      goto retry_tx_work;
++              }
++
++              skb = skb_dequeue(&ld->sk_raw_tx_q);
++              if (skb)
++                      ret = _usb_tx_work(skb);
++
++              if (ret) {
++                      mif_err("usb_tx_urb_with_skb for raw_q %d\n", ret);
++                      skb_queue_head(&ld->sk_raw_tx_q, skb);
++
++                      if (ret == -ENODEV || ret == -ENOENT)
++                              goto exit;
++
++                      pm_runtime_put(&usb_ld->usbdev->dev);
++                      goto retry_tx_work;
++              }
++
++              pm_runtime_put(&usb_ld->usbdev->dev);
++      }
++#ifdef CONFIG_HAS_WAKELOCK
++      wake_unlock(&pm_data->tx_async_wake);
++#else
++      pm_relax(pm_data->miscdev.this_device);
++#endif
++exit:
++      return;
++
++retry_tx_work:
++      queue_delayed_work(ld->tx_wq, &ld->tx_delayed_work,
++              msecs_to_jiffies(20));
++      return;
++}
++
++/*
++#ifdef CONFIG_LINK_PM
++*/
++
++static int link_pm_runtime_get_active(struct link_pm_data *pm_data)
++{
++      int ret;
++      struct usb_link_device *usb_ld = pm_data->usb_ld;
++      struct device *dev = &usb_ld->usbdev->dev;
++
++      if (!usb_ld->if_usb_connected || usb_ld->ld.com_state == COM_NONE)
++              return -ENODEV;
++
++      if (pm_data->dpm_suspending) {
++              mif_err("Kernel in suspending try get_active later\n");
++              /* during dpm_suspending..
++               * if AP get tx data, wake up. */
++#ifdef CONFIG_HAS_WAKELOCK
++              wake_lock(&pm_data->l2_wake);
++#else
++              pm_stay_awake(pm_data->miscdev.this_device);
++#endif
++              return -EAGAIN;
++      }
++
++      if (dev->power.runtime_status == RPM_ACTIVE) {
++              pm_data->resume_retry_cnt = 0;
++              return 0;
++      }
++
++      if (!pm_data->resume_requested) {
++              mif_debug("QW PM\n");
++              queue_delayed_work(pm_data->wq, &pm_data->link_pm_work, 0);
++      }
++      mif_debug("Wait pm\n");
++      INIT_COMPLETION(pm_data->active_done);
++      ret = wait_for_completion_timeout(&pm_data->active_done,
++                                              msecs_to_jiffies(500));
++
++      /* If usb link was disconnected while waiting ACTIVE State, usb device
++       * was removed, usb_ld->usbdev->dev is invalid and below
++       * dev->power.runtime_status is also invalid address.
++       * It will be occured LPA L3 -> AP iniated L0 -> disconnect -> link
++       * timeout
++       */
++      if (!usb_ld->if_usb_connected || usb_ld->ld.com_state == COM_NONE) {
++              mif_info("link disconnected after timed-out\n");
++              return -ENODEV;
++      }
++
++      if (dev->power.runtime_status != RPM_ACTIVE) {
++              mif_info("link_active (%d) retry\n",
++                                              dev->power.runtime_status);
++              return -EAGAIN;
++      }
++      mif_debug("link_active success(%d)\n", ret);
++      return 0;
++}
++
++static void link_pm_runtime_start(struct work_struct *work)
++{
++      struct link_pm_data *pm_data =
++              container_of(work, struct link_pm_data, link_pm_start.work);
++      struct usb_device *usbdev = pm_data->usb_ld->usbdev;
++      struct device *dev, *hdev;
++      struct link_device *ld = &pm_data->usb_ld->ld;
++
++      if (!pm_data->usb_ld->if_usb_connected
++              || pm_data->usb_ld->ld.com_state == COM_NONE) {
++              mif_debug("disconnect status, ignore\n");
++              return;
++      }
++
++      dev = &pm_data->usb_ld->usbdev->dev;
++
++      /* wait interface driver resumming */
++      if (dev->power.runtime_status == RPM_SUSPENDED) {
++              mif_info("suspended yet, delayed work\n");
++              queue_delayed_work(pm_data->wq, &pm_data->link_pm_start,
++                      msecs_to_jiffies(20));
++              return;
++      }
++
++      if (pm_data->usb_ld->usbdev && dev->parent) {
++              mif_info("rpm_status: %d\n",
++                      dev->power.runtime_status);
++              pm_runtime_set_autosuspend_delay(dev, 200);
++              hdev = usbdev->bus->root_hub->dev.parent;
++              mif_info("EHCI runtime %s, %s\n", dev_driver_string(hdev),
++                      dev_name(hdev));
++              pm_runtime_allow(dev);
++              pm_runtime_allow(hdev);/*ehci*/
++              pm_data->link_pm_active = true;
++              pm_data->resume_requested = false;
++              pm_data->link_reconnect_cnt = 5;
++              pm_data->resume_retry_cnt = 0;
++
++              /* retry prvious link tx q */
++              queue_delayed_work(ld->tx_wq, &ld->tx_delayed_work, 0);
++      }
++}
++
++static void link_pm_force_cp_dump(struct link_pm_data *pm_data)
++{
++      struct modem_ctl *mc = if_usb_get_modemctl(pm_data);
++
++      mif_err("Set modem crash ap_dump_int by %pF\n",
++              __builtin_return_address(0));
++
++      if (mc->gpio_ap_dump_int) {
++              if (gpio_get_value(mc->gpio_ap_dump_int)) {
++                      gpio_set_value(mc->gpio_ap_dump_int, 0);
++                      msleep(20);
++              }
++              gpio_set_value(mc->gpio_ap_dump_int, 1);
++              msleep(20);
++              mif_err("AP_DUMP_INT(%d)\n",
++                      gpio_get_value(mc->gpio_ap_dump_int));
++              gpio_set_value(mc->gpio_ap_dump_int, 0);
++      }
++}
++
++static void link_pm_change_modem_state(struct link_pm_data *pm_data,
++                                              enum modem_state state)
++{
++      struct modem_ctl *mc = if_usb_get_modemctl(pm_data);
++
++      if (!mc->iod || pm_data->usb_ld->ld.com_state != COM_ONLINE)
++              return;
++
++      mif_err("set modem state %d by %pF\n", state,
++              __builtin_return_address(0));
++      mc->iod->modem_state_changed(mc->iod, state);
++      mc->bootd->modem_state_changed(mc->bootd, state);
++}
++
++static void link_pm_reconnect_work(struct work_struct *work)
++{
++      struct link_pm_data *pm_data =
++              container_of(work, struct link_pm_data,
++                                      link_reconnect_work.work);
++      struct modem_ctl *mc = if_usb_get_modemctl(pm_data);
++
++      if (!mc || pm_data->usb_ld->if_usb_connected)
++              return;
++
++      if (pm_data->usb_ld->ld.com_state != COM_ONLINE)
++              return;
++
++      if (pm_data->link_reconnect_cnt--) {
++              if (mc->phone_state == STATE_ONLINE &&
++                                              !pm_data->link_reconnect())
++                      /* try reconnect and check */
++                      schedule_delayed_work(&pm_data->link_reconnect_work,
++                                                      msecs_to_jiffies(500));
++              else    /* under cp crash or reset, just return */
++                      return;
++      } else {
++              /* try to recover cp */
++              mif_err("recover connection: silent reset\n");
++              link_pm_change_modem_state(pm_data, STATE_CRASH_RESET);
++      }
++}
++
++static inline int link_pm_slave_wake(struct link_pm_data *pm_data)
++{
++      int spin = 20;
++
++      /* when slave device is in sleep, wake up slave cpu first */
++      if (gpio_get_value(pm_data->gpio_link_hostwake)
++                              != HOSTWAKE_TRIGLEVEL) {
++              if (gpio_get_value(pm_data->gpio_link_slavewake)) {
++                      gpio_set_value(pm_data->gpio_link_slavewake, 0);
++                      mif_info("gpio [SWK] set [0]\n");
++                      mdelay(5);
++              }
++              gpio_set_value(pm_data->gpio_link_slavewake, 1);
++              mif_info("gpio [SWK] set [1]\n");
++              mdelay(5);
++
++              /* wait host wake signal*/
++              while (spin-- && gpio_get_value(pm_data->gpio_link_hostwake) !=
++                                                      HOSTWAKE_TRIGLEVEL)
++                      mdelay(5);
++      }
++      return spin;
++}
++
++static void link_pm_runtime_work(struct work_struct *work)
++{
++      int ret;
++      struct link_pm_data *pm_data =
++              container_of(work, struct link_pm_data, link_pm_work.work);
++      struct device *dev = &pm_data->usb_ld->usbdev->dev;
++
++      if (!pm_data->usb_ld->if_usb_connected || pm_data->dpm_suspending)
++              return;
++
++      if (pm_data->usb_ld->ld.com_state == COM_NONE)
++              return;
++
++      mif_debug("for dev 0x%p : current %d\n", dev,
++                                      dev->power.runtime_status);
++
++      switch (dev->power.runtime_status) {
++      case RPM_ACTIVE:
++              pm_data->resume_retry_cnt = 0;
++              pm_data->resume_requested = false;
++              complete(&pm_data->active_done);
++
++              return;
++      case RPM_SUSPENDED:
++              if (pm_data->resume_requested)
++                      break;
++              pm_data->resume_requested = true;
++#ifdef CONFIG_HAS_WAKELOCK
++              wake_lock(&pm_data->rpm_wake);
++#else
++              pm_stay_awake(pm_data->miscdev.this_device);
++#endif
++              ret = link_pm_slave_wake(pm_data);
++              if (ret < 0) {
++                      mif_err("slave wake fail\n");
++#ifdef CONFIG_HAS_WAKELOCK
++                      wake_unlock(&pm_data->rpm_wake);
++#else
++                      pm_relax(pm_data->miscdev.this_device);
++#endif
++                      break;
++              }
++
++              if (!pm_data->usb_ld->if_usb_connected) {
++#ifdef CONFIG_HAS_WAKELOCK
++                      wake_unlock(&pm_data->rpm_wake);
++#else
++                      pm_relax(pm_data->miscdev.this_device);
++#endif
++                      return;
++              }
++
++              ret = pm_runtime_resume(dev);
++              if (ret < 0) {
++                      mif_err("resume error(%d)\n", ret);
++                      if (!pm_data->usb_ld->if_usb_connected) {
++#ifdef CONFIG_HAS_WAKELOCK
++                              wake_unlock(&pm_data->rpm_wake);
++#else
++                              pm_relax(pm_data->miscdev.this_device);
++#endif
++                              return;
++                      }
++                      /* force to go runtime idle before retry resume */
++                      if (dev->power.timer_expires == 0 &&
++                                              !dev->power.request_pending) {
++                              mif_debug("run time idle\n");
++                              pm_runtime_idle(dev);
++                      }
++              }
++#ifdef CONFIG_HAS_WAKELOCK
++              wake_unlock(&pm_data->rpm_wake);
++#else
++              pm_relax(pm_data->miscdev.this_device);
++#endif
++              break;
++      case RPM_SUSPENDING:
++              /* Checking the usb_runtime_suspend running time.*/
++              mif_info("rpm_states=%d", dev->power.runtime_status);
++              msleep(20);
++              break;
++      default:
++              break;
++      }
++      pm_data->resume_requested = false;
++
++      /* check until runtime_status goes to active */
++      /* attemp 10 times, or re-establish modem-link */
++      /* if pm_runtime_resume run properly, rpm status must be in ACTIVE */
++      if (dev->power.runtime_status == RPM_ACTIVE) {
++              pm_data->resume_retry_cnt = 0;
++              complete(&pm_data->active_done);
++      } else if (pm_data->resume_retry_cnt++ > 10) {
++              mif_err("runtime_status(%d), retry_cnt(%d)\n",
++                      dev->power.runtime_status, pm_data->resume_retry_cnt);
++              link_pm_change_modem_state(pm_data, STATE_CRASH_RESET);
++      } else
++              queue_delayed_work(pm_data->wq, &pm_data->link_pm_work,
++                                                      msecs_to_jiffies(20));
++}
++
++static irqreturn_t link_pm_irq_handler(int irq, void *data)
++{
++      int value;
++      struct link_pm_data *pm_data = data;
++
++#if defined(CONFIG_SLP)
++      pm_wakeup_event(pm_data->miscdev.this_device, 0);
++#endif
++
++      if (!pm_data->link_pm_active)
++              return IRQ_HANDLED;
++
++      /* host wake up HIGH */
++      /*
++              resume usb runtime pm start
++      */
++      /* host wake up LOW */
++      /*
++              slave usb enumeration end,
++              host can send usb packet after
++              runtime pm status changes to ACTIVE
++      */
++      value = gpio_get_value(pm_data->gpio_link_hostwake);
++      mif_info("gpio [HWK] get [%d]\n", value);
++
++      /*
++      * igonore host wakeup interrupt at suspending kernel
++      */
++      if (pm_data->dpm_suspending) {
++              mif_info("ignore request by suspending\n");
++              /* Ignore HWK but AP got to L2 by suspending fail */
++#ifdef CONFIG_HAS_WAKELOCK
++              wake_lock(&pm_data->l2_wake);
++#else
++              pm_stay_awake(pm_data->miscdev.this_device);
++#endif
++              return IRQ_HANDLED;
++      }
++
++      if (value == HOSTWAKE_TRIGLEVEL) {
++              /* move to slave wake function */
++              /* runtime pm goes to active */
++              /*
++              if (gpio_get_value(pm_data->gpio_link_active)) {
++                      mif_err("gpio [H ACTV : %d] set 1\n",
++                              gpio_get_value(pm_data->gpio_link_active));
++                      gpio_set_value(pm_data->gpio_link_active, 1);
++              }
++              */
++              queue_delayed_work(pm_data->wq, &pm_data->link_pm_work, 0);
++      } else {
++              /* notification of enumeration process from slave device
++               * But it does not mean whole connection is in resume, so do not
++               * notify resume completion here.
++
++              if (pm_data->link_pm_active && !pm_data->active_done.done)
++                      complete(&pm_data->active_done);
++              */
++              /* clear slave cpu wake up pin */
++              gpio_set_value(pm_data->gpio_link_slavewake, 0);
++              mif_debug("gpio [SWK] set [0]\n");
++      }
++      return IRQ_HANDLED;
++}
++
++static long link_pm_ioctl(struct file *file, unsigned int cmd,
++                                              unsigned long arg)
++{
++      int value;
++      struct link_pm_data *pm_data = file->private_data;
++      struct modem_ctl *mc = if_usb_get_modemctl(pm_data);
++
++      mif_info("%x\n", cmd);
++
++      switch (cmd) {
++      case IOCTL_LINK_CONTROL_ENABLE:
++              if (copy_from_user(&value, (const void __user *)arg,
++                                                      sizeof(int)))
++                      return -EFAULT;
++              if (pm_data->link_ldo_enable)
++                      pm_data->link_ldo_enable(!!value);
++              if (pm_data->gpio_link_enable)
++                      gpio_set_value(pm_data->gpio_link_enable, value);
++              break;
++      case IOCTL_LINK_CONTROL_ACTIVE:
++              if (copy_from_user(&value, (const void __user *)arg,
++                                                      sizeof(int)))
++                      return -EFAULT;
++              gpio_set_value(pm_data->gpio_link_active, value);
++              break;
++      case IOCTL_LINK_GET_HOSTWAKE:
++              return !gpio_get_value(pm_data->gpio_link_hostwake);
++      case IOCTL_LINK_CONNECTED:
++              return pm_data->usb_ld->if_usb_connected;
++      case IOCTL_LINK_SET_BIAS_CLEAR:
++              if (copy_from_user(&value, (const void __user *)arg,
++                                                      sizeof(int)))
++                      return -EFAULT;
++              if (value) {
++                      gpio_direction_output(pm_data->gpio_link_slavewake, 0);
++                      gpio_direction_output(pm_data->gpio_link_hostwake, 0);
++              } else {
++                      gpio_direction_output(pm_data->gpio_link_slavewake, 0);
++                      gpio_direction_input(pm_data->gpio_link_hostwake);
++                      irq_set_irq_type(pm_data->irq_link_hostwake,
++                              IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING);
++              }
++      case IOCTL_LINK_GET_PHONEACTIVE:
++              return gpio_get_value(mc->gpio_phone_active);
++      default:
++              break;
++      }
++
++      return 0;
++}
++
++static int link_pm_open(struct inode *inode, struct file *file)
++{
++      struct link_pm_data *pm_data =
++              (struct link_pm_data *)file->private_data;
++      file->private_data = (void *)pm_data;
++      return 0;
++}
++
++static int link_pm_release(struct inode *inode, struct file *file)
++{
++      file->private_data = NULL;
++      return 0;
++}
++
++static const struct file_operations link_pm_fops = {
++      .owner = THIS_MODULE,
++      .open = link_pm_open,
++      .release = link_pm_release,
++      .unlocked_ioctl = link_pm_ioctl,
++};
++
++static int link_pm_notifier_event(struct notifier_block *this,
++                              unsigned long event, void *ptr)
++{
++      struct link_pm_data *pm_data =
++                      container_of(this, struct link_pm_data, pm_notifier);
++#ifdef CONFIG_UMTS_MODEM_XMM6262
++      struct modem_ctl *mc = if_usb_get_modemctl(pm_data);
++#endif
++
++      switch (event) {
++      case PM_SUSPEND_PREPARE:
++#ifdef CONFIG_HIBERNATION
++      case PM_HIBERNATION_PREPARE:
++      case PM_RESTORE_PREPARE:
++#endif
++              pm_data->dpm_suspending = true;
++#ifdef CONFIG_UMTS_MODEM_XMM6262
++              /* set PDA Active High if previous state was LPA */
++              if (!gpio_get_value(pm_data->gpio_link_active)) {
++                      mif_info("PDA active High to LPA suspend spot\n");
++                      gpio_set_value(mc->gpio_pda_active, 1);
++              }
++#endif
++              mif_debug("dpm suspending set to true\n");
++              return NOTIFY_OK;
++      case PM_POST_SUSPEND:
++#ifdef CONFIG_HIBERNATION
++      case PM_POST_HIBERNATION:
++      case PM_POST_RESTORE:
++#endif
++              pm_data->dpm_suspending = false;
++              if (gpio_get_value(pm_data->gpio_link_hostwake)
++                      == HOSTWAKE_TRIGLEVEL) {
++                      queue_delayed_work(pm_data->wq, &pm_data->link_pm_work,
++                              0);
++                      mif_info("post resume\n");
++              }
++#ifdef CONFIG_UMTS_MODEM_XMM6262
++              /* LPA to Kernel suspend and User Freezing task fail resume,
++              restore to LPA GPIO states. */
++              if (!gpio_get_value(pm_data->gpio_link_active)) {
++                      mif_info("PDA active low to LPA GPIO state\n");
++                      gpio_set_value(mc->gpio_pda_active, 0);
++              }
++#endif
++              mif_debug("dpm suspending set to false\n");
++              return NOTIFY_OK;
++      }
++      return NOTIFY_DONE;
++}
++
++static struct modem_ctl *if_usb_get_modemctl(struct link_pm_data *pm_data)
++{
++      struct io_device *iod;
++
++      iod = link_get_iod_with_format(&pm_data->usb_ld->ld, IPC_FMT);
++      if (!iod) {
++              mif_err("no iodevice for modem control\n");
++              return NULL;
++      }
++
++      return iod->mc;
++}
++
++static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
++{
++      struct if_usb_devdata *devdata = usb_get_intfdata(intf);
++      struct link_pm_data *pm_data = devdata->usb_ld->link_pm_data;
++      if (!devdata->disconnected && devdata->state == STATE_RESUMED) {
++              usb_kill_urb(devdata->urb);
++              devdata->state = STATE_SUSPENDED;
++      }
++
++      devdata->usb_ld->suspended++;
++
++      if (devdata->usb_ld->suspended == LINKPM_DEV_NUM) {
++              mif_debug("[if_usb_suspended]\n");
++#ifdef CONFIG_HAS_WAKELOCK
++              wake_lock_timeout(&pm_data->l2_wake, msecs_to_jiffies(50));
++#else
++              pm_wakeup_event(pm_data->miscdev.this_device, 50);
++#endif
++              /* XMM6262 Host wakeup toggle recovery */
++              if (!pm_data->rx_cnt && !pm_data->tx_cnt) {
++                      if (pm_data->ipc_debug_cnt++ > 10) {
++                              mif_err("No TX/RX after resume 10times\n");
++                              link_pm_change_modem_state(pm_data,
++                                      STATE_CRASH_RESET);
++                      }
++              } else {
++                      pm_data->ipc_debug_cnt = 0;
++                      pm_data->rx_cnt = 0;
++                      pm_data->tx_cnt = 0;
++              }
++      }
++      return 0;
++}
++
++static int if_usb_resume(struct usb_interface *intf)
++{
++      int ret;
++      struct if_usb_devdata *devdata = usb_get_intfdata(intf);
++      struct link_pm_data *pm_data = devdata->usb_ld->link_pm_data;
++
++      if (!devdata->disconnected && devdata->state == STATE_SUSPENDED) {
++              ret = usb_rx_submit(devdata->usb_ld, devdata, GFP_ATOMIC);
++              if (ret < 0) {
++                      mif_err("usb_rx_submit error with (%d)\n", ret);
++                      return ret;
++              }
++              devdata->state = STATE_RESUMED;
++      }
++
++      /* For debugging -  nomal case, never reach below... */
++      if (pm_data->resume_retry_cnt > 5) {
++              mif_err("retry_cnt=%d, rpm_status=%d",
++                      pm_data->resume_retry_cnt,
++                      devdata->usb_ld->usbdev->dev.power.runtime_status);
++              pm_data->resume_retry_cnt = 0;
++      }
++
++      devdata->usb_ld->suspended--;
++      if (!devdata->usb_ld->suspended) {
++              mif_debug("[if_usb_resumed]\n");
++#ifdef CONFIG_HAS_WAKELOCK
++              wake_lock(&pm_data->l2_wake);
++#else
++              pm_stay_awake(pm_data->miscdev.this_device);
++#endif
++      }
++
++      return 0;
++}
++
++static int if_usb_reset_resume(struct usb_interface *intf)
++{
++      int ret;
++      struct if_usb_devdata *devdata = usb_get_intfdata(intf);
++      struct link_pm_data *pm_data = devdata->usb_ld->link_pm_data;
++
++      ret = if_usb_resume(intf);
++      pm_data->ipc_debug_cnt = 0;
++      /*
++       * for runtime suspend, kick runtime pm at L3 -> L0 reset resume
++      */
++      if (!devdata->usb_ld->suspended)
++              queue_delayed_work(pm_data->wq, &pm_data->link_pm_start, 0);
++      return ret;
++}
++
++static void if_usb_disconnect(struct usb_interface *intf)
++{
++      struct if_usb_devdata *devdata = usb_get_intfdata(intf);
++      struct link_pm_data *pm_data = devdata->usb_ld->link_pm_data;
++      struct device *dev, *hdev;
++      struct link_device *ld = &devdata->usb_ld->ld;
++
++      mif_info("\n");
++
++      if (devdata->disconnected)
++              return;
++
++      devdata->usb_ld->if_usb_connected = 0;
++
++      usb_driver_release_interface(to_usb_driver(intf->dev.driver), intf);
++
++      usb_kill_urb(devdata->urb);
++
++      hdev = devdata->usbdev->bus->root_hub->dev.parent;
++      pm_runtime_forbid(hdev); /*ehci*/
++
++      mif_info("put dev 0x%p\n", devdata->usbdev);
++      usb_put_dev(devdata->usbdev);
++
++      devdata->data_intf = NULL;
++      devdata->usbdev = NULL;
++      /* if possible, merge below 2 variables */
++      devdata->disconnected = 1;
++      devdata->state = STATE_SUSPENDED;
++      pm_data->ipc_debug_cnt = 0;
++
++      devdata->usb_ld->suspended = 0;
++#ifdef CONFIG_HAS_WAKELOCK
++      wake_lock(&pm_data->boot_wake);
++#else
++      pm_stay_awake(pm_data->miscdev.this_device);
++#endif
++      usb_set_intfdata(intf, NULL);
++
++      /* cancel runtime start delayed works */
++      cancel_delayed_work_sync(&pm_data->link_pm_start);
++      cancel_delayed_work_sync(&ld->tx_delayed_work);
++
++      /* if reconnect function exist , try reconnect without reset modem
++       * reconnect function checks modem is under crash or not, so we don't
++       * need check crash state here. reconnect work checks and determine
++       * further works
++       */
++      if (!pm_data->link_reconnect)
++              return;
++
++      if (devdata->usb_ld->ld.com_state != COM_ONLINE) {
++              cancel_delayed_work(&pm_data->link_reconnect_work);
++              return;
++      } else {
++              if (pm_data->ehci_reg_dump)
++                      pm_data->ehci_reg_dump(hdev);
++              schedule_delayed_work(&pm_data->link_reconnect_work,
++                                                      msecs_to_jiffies(500));
++      }
++      return;
++}
++
++static int if_usb_set_pipe(struct usb_link_device *usb_ld,
++                      const struct usb_host_interface *desc, int pipe)
++{
++      if (pipe < 0 || pipe >= IF_USB_DEVNUM_MAX) {
++              mif_err("undefined endpoint, exceed max\n");
++              return -EINVAL;
++      }
++
++      mif_info("set %d\n", pipe);
++
++      if ((usb_pipein(desc->endpoint[0].desc.bEndpointAddress)) &&
++          (usb_pipeout(desc->endpoint[1].desc.bEndpointAddress))) {
++              usb_ld->devdata[pipe].rx_pipe = usb_rcvbulkpipe(usb_ld->usbdev,
++                              desc->endpoint[0].desc.bEndpointAddress);
++              usb_ld->devdata[pipe].tx_pipe = usb_sndbulkpipe(usb_ld->usbdev,
++                              desc->endpoint[1].desc.bEndpointAddress);
++      } else if ((usb_pipeout(desc->endpoint[0].desc.bEndpointAddress)) &&
++                 (usb_pipein(desc->endpoint[1].desc.bEndpointAddress))) {
++              usb_ld->devdata[pipe].rx_pipe = usb_rcvbulkpipe(usb_ld->usbdev,
++                              desc->endpoint[1].desc.bEndpointAddress);
++              usb_ld->devdata[pipe].tx_pipe = usb_sndbulkpipe(usb_ld->usbdev,
++                              desc->endpoint[0].desc.bEndpointAddress);
++      } else {
++              mif_err("undefined endpoint\n");
++              return -EINVAL;
++      }
++
++      return 0;
++}
++
++static int __devinit if_usb_probe(struct usb_interface *intf,
++                                      const struct usb_device_id *id)
++{
++      int err;
++      int pipe;
++      const struct usb_cdc_union_desc *union_hdr;
++      const struct usb_host_interface *data_desc;
++      unsigned char *buf = intf->altsetting->extra;
++      int buflen = intf->altsetting->extralen;
++      struct usb_interface *data_intf;
++      struct usb_device *usbdev = interface_to_usbdev(intf);
++      struct usb_driver *usbdrv = to_usb_driver(intf->dev.driver);
++      struct usb_id_info *info = (struct usb_id_info *)id->driver_info;
++      struct usb_link_device *usb_ld = info->usb_ld;
++
++      mif_info("usbdev = 0x%p\n", usbdev);
++
++      pr_debug("%s: Class=%d, SubClass=%d, Protocol=%d\n", __func__,
++              intf->altsetting->desc.bInterfaceClass,
++              intf->altsetting->desc.bInterfaceSubClass,
++              intf->altsetting->desc.bInterfaceProtocol);
++
++      /* if usb disconnected, AP try to reconnect 5 times.
++       * but because if_sub_connected is configured
++       * at the end of if_usb_probe, there was a chance
++       * that swk will be called again during enumeration.
++       * so.. cancel reconnect work_queue in this case. */
++      if (usb_ld->ld.com_state == COM_ONLINE)
++              cancel_delayed_work(&usb_ld->link_pm_data->link_reconnect_work);
++
++      usb_ld->usbdev = usbdev;
++      pm_runtime_forbid(&usbdev->dev);
++      usb_ld->link_pm_data->link_pm_active = false;
++      usb_ld->link_pm_data->dpm_suspending = false;
++      usb_ld->link_pm_data->ipc_debug_cnt = 0;
++      usb_ld->if_usb_is_main = (info->intf_id != BOOT_DOWN);
++
++      union_hdr = NULL;
++      /* for WMC-ACM compatibility, WMC-ACM use an end-point for control msg*/
++      if (intf->altsetting->desc.bInterfaceSubClass != USB_CDC_SUBCLASS_ACM) {
++              mif_err("ignore Non ACM end-point\n");
++              return -EINVAL;
++      }
++
++      if (!buflen) {
++              if (intf->cur_altsetting->endpoint->extralen &&
++                                  intf->cur_altsetting->endpoint->extra) {
++                      buflen = intf->cur_altsetting->endpoint->extralen;
++                      buf = intf->cur_altsetting->endpoint->extra;
++              } else {
++                      mif_err("Zero len descriptor reference\n");
++                      return -EINVAL;
++              }
++      }
++
++      while (buflen > 0) {
++              if (buf[1] == USB_DT_CS_INTERFACE) {
++                      switch (buf[2]) {
++                      case USB_CDC_UNION_TYPE:
++                              if (union_hdr)
++                                      break;
++                              union_hdr = (struct usb_cdc_union_desc *)buf;
++                              break;
++                      default:
++                              break;
++                      }
++              }
++              buf += buf[0];
++              buflen -= buf[0];
++      }
++
++      if (!union_hdr) {
++              mif_err("USB CDC is not union type\n");
++              return -EINVAL;
++      }
++
++      data_intf = usb_ifnum_to_if(usbdev, union_hdr->bSlaveInterface0);
++      if (!data_intf) {
++              mif_err("data_inferface is NULL\n");
++              return -ENODEV;
++      }
++
++      data_desc = data_intf->altsetting;
++      if (!data_desc) {
++              mif_err("data_desc is NULL\n");
++              return -ENODEV;
++      }
++
++      switch (info->intf_id) {
++      case BOOT_DOWN:
++              pipe = IF_USB_BOOT_EP;
++              usb_ld->ld.com_state = COM_BOOT;
++              /* purge previous boot fmt/raw tx q
++               clear all tx q*/
++              skb_queue_purge(&usb_ld->ld.sk_fmt_tx_q);
++              skb_queue_purge(&usb_ld->ld.sk_raw_tx_q);
++              break;
++      case IPC_CHANNEL:
++              pipe = intf->altsetting->desc.bInterfaceNumber / 2;
++              usb_ld->ld.com_state = COM_ONLINE;
++              break;
++      default:
++              pipe = -1;
++              break;
++      }
++
++      if (if_usb_set_pipe(usb_ld, data_desc, pipe) < 0)
++              return -EINVAL;
++
++      usb_ld->devdata[pipe].usbdev = usb_get_dev(usbdev);
++      mif_info("devdata usbdev = 0x%p\n",
++              usb_ld->devdata[pipe].usbdev);
++      usb_ld->devdata[pipe].usb_ld = usb_ld;
++      usb_ld->devdata[pipe].data_intf = data_intf;
++      usb_ld->devdata[pipe].format = pipe;
++      usb_ld->devdata[pipe].disconnected = 0;
++      usb_ld->devdata[pipe].state = STATE_RESUMED;
++
++      usb_ld->suspended = 0;
++
++      err = usb_driver_claim_interface(usbdrv, data_intf,
++              (void *)&usb_ld->devdata[pipe]);
++      if (err < 0) {
++              mif_err("usb_driver_claim() failed\n");
++              return err;
++      }
++
++      pm_suspend_ignore_children(&usbdev->dev, true);
++
++      usb_set_intfdata(intf, (void *)&usb_ld->devdata[pipe]);
++
++      /* rx start for this endpoint */
++      usb_rx_submit(usb_ld, &usb_ld->devdata[pipe], GFP_KERNEL);
++
++      if (info->intf_id == IPC_CHANNEL &&
++              !work_pending(&usb_ld->link_pm_data->link_pm_start.work)) {
++                      queue_delayed_work(usb_ld->link_pm_data->wq,
++                                      &usb_ld->link_pm_data->link_pm_start,
++                                      msecs_to_jiffies(500));
++#ifdef CONFIG_HAS_WAKELOCK
++                      wake_lock(&usb_ld->link_pm_data->l2_wake);
++                      wake_unlock(&usb_ld->link_pm_data->boot_wake);
++#else
++                      pm_stay_awake
++                              (usb_ld->link_pm_data->miscdev.this_device);
++#endif
++      }
++
++      /* HSIC main comm channel has been established */
++      if (pipe == IF_USB_CMD_EP)
++              link_pm_change_modem_state(usb_ld->link_pm_data, STATE_ONLINE);
++
++      if (pipe == IF_USB_CMD_EP || info->intf_id == BOOT_DOWN)
++              usb_ld->if_usb_connected = 1;
++
++      mif_info("successfully done\n");
++
++      return 0;
++}
++
++static void if_usb_free_pipe_data(struct usb_link_device *usb_ld)
++{
++      int i;
++      for (i = 0; i < IF_USB_DEVNUM_MAX; i++) {
++              kfree(usb_ld->devdata[i].rx_buf);
++              usb_kill_urb(usb_ld->devdata[i].urb);
++      }
++}
++
++static struct usb_id_info hsic_boot_down_info = {
++      .intf_id = BOOT_DOWN,
++};
++static struct usb_id_info hsic_channel_info = {
++      .intf_id = IPC_CHANNEL,
++};
++
++static struct usb_device_id if_usb_ids[] = {
++      {USB_DEVICE_AND_INTERFACE_INFO(IMC_BOOT_VID, IMC_BOOT_PID,
++              USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, USB_CDC_PROTO_NONE),
++      .driver_info = (unsigned long)&hsic_boot_down_info,},
++      {USB_DEVICE_AND_INTERFACE_INFO(IMC_MAIN_VID, IMC_MAIN_PID,
++              USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, 1),
++      .driver_info = (unsigned long)&hsic_channel_info,},
++      {USB_DEVICE(STE_BOOT_VID, STE_BOOT_PID),
++      .driver_info = (unsigned long)&hsic_boot_down_info,},
++      {USB_DEVICE(STE_MAIN_VID, STE_MAIN_PID),
++      .driver_info = (unsigned long)&hsic_channel_info,},
++      {}
++};
++MODULE_DEVICE_TABLE(usb, if_usb_ids);
++
++static struct usb_driver if_usb_driver = {
++      .name =         "cdc_modem",
++      .probe =                if_usb_probe,
++      .disconnect =   if_usb_disconnect,
++      .id_table =     if_usb_ids,
++      .suspend =      if_usb_suspend,
++      .resume =       if_usb_resume,
++      .reset_resume = if_usb_reset_resume,
++      .supports_autosuspend = 1,
++};
++
++static int if_usb_init(struct link_device *ld)
++{
++      int ret;
++      int i;
++      struct usb_link_device *usb_ld = to_usb_link_device(ld);
++      struct if_usb_devdata *pipe_data;
++      struct usb_id_info *id_info;
++
++      /* to connect usb link device with usb interface driver */
++      for (i = 0; i < ARRAY_SIZE(if_usb_ids); i++) {
++              id_info = (struct usb_id_info *)if_usb_ids[i].driver_info;
++              if (id_info)
++                      id_info->usb_ld = usb_ld;
++      }
++
++      ret = usb_register(&if_usb_driver);
++      if (ret) {
++              mif_err("usb_register_driver() fail : %d\n", ret);
++              return ret;
++      }
++
++      /* allocate rx buffer for usb receive */
++      for (i = 0; i < IF_USB_DEVNUM_MAX; i++) {
++              pipe_data = &usb_ld->devdata[i];
++              pipe_data->format = i;
++              pipe_data->rx_buf_size = 16 * 1024;
++
++              pipe_data->rx_buf = kmalloc(pipe_data->rx_buf_size,
++                                              GFP_DMA | GFP_KERNEL);
++              if (!pipe_data->rx_buf) {
++                      if_usb_free_pipe_data(usb_ld);
++                      ret = -ENOMEM;
++                      break;
++              }
++
++              pipe_data->urb = usb_alloc_urb(0, GFP_KERNEL);
++              if (!pipe_data->urb) {
++                      mif_err("alloc urb fail\n");
++                      if_usb_free_pipe_data(usb_ld);
++                      return -ENOMEM;
++              }
++      }
++
++      mif_info("if_usb_init() done : %d, usb_ld (0x%p)\n",
++                                                              ret, usb_ld);
++      return ret;
++}
++
++static int usb_link_pm_init(struct usb_link_device *usb_ld, void *data)
++{
++      int r;
++      struct platform_device *pdev = (struct platform_device *)data;
++      struct modem_data *pdata =
++                      (struct modem_data *)pdev->dev.platform_data;
++      struct modemlink_pm_data *pm_pdata;
++      struct link_pm_data *pm_data =
++                      kzalloc(sizeof(struct link_pm_data), GFP_KERNEL);
++
++      if (!pdata || !pdata->link_pm_data) {
++              mif_err("platform data is NULL\n");
++              return -EINVAL;
++      }
++      pm_pdata = pdata->link_pm_data;
++
++      if (!pm_data) {
++              mif_err("link_pm_data is NULL\n");
++              return -ENOMEM;
++      }
++
++      /* get link pm data from modemcontrol's platform data */
++      pm_data->gpio_link_active = pm_pdata->gpio_link_active;
++      pm_data->gpio_link_enable = pm_pdata->gpio_link_enable;
++      pm_data->gpio_link_hostwake = pm_pdata->gpio_link_hostwake;
++      pm_data->gpio_link_slavewake = pm_pdata->gpio_link_slavewake;
++      pm_data->irq_link_hostwake = gpio_to_irq(pm_data->gpio_link_hostwake);
++      pm_data->link_ldo_enable = pm_pdata->link_ldo_enable;
++      pm_data->link_reconnect = pm_pdata->link_reconnect;
++      pm_data->ehci_reg_dump = pm_pdata->ehci_reg_dump;
++
++      pm_data->usb_ld = usb_ld;
++      pm_data->link_pm_active = false;
++      pm_data->ipc_debug_cnt = 0;
++      usb_ld->link_pm_data = pm_data;
++
++      pm_data->miscdev.minor = MISC_DYNAMIC_MINOR;
++      pm_data->miscdev.name = "link_pm";
++      pm_data->miscdev.fops = &link_pm_fops;
++
++      r = misc_register(&pm_data->miscdev);
++      if (r < 0) {
++              mif_err("fail to register pm device(%d)\n", r);
++              goto err_misc_register;
++      }
++
++      r = request_irq(pm_data->irq_link_hostwake, link_pm_irq_handler,
++              IRQF_NO_SUSPEND | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
++              "hostwake", (void *)pm_data);
++      if (r) {
++              mif_err("fail to request irq(%d)\n", r);
++              goto err_request_irq;
++      }
++
++      r = enable_irq_wake(pm_data->irq_link_hostwake);
++      if (r) {
++              mif_err("failed to enable_irq_wake:%d\n", r);
++              goto err_set_wake_irq;
++      }
++
++      /* create work queue & init work for runtime pm */
++      pm_data->wq = create_singlethread_workqueue("linkpmd");
++      if (!pm_data->wq) {
++              mif_err("fail to create wq\n");
++              goto err_create_wq;
++      }
++
++      pm_data->pm_notifier.notifier_call = link_pm_notifier_event;
++      register_pm_notifier(&pm_data->pm_notifier);
++
++      init_completion(&pm_data->active_done);
++      INIT_DELAYED_WORK(&pm_data->link_pm_work, link_pm_runtime_work);
++      INIT_DELAYED_WORK(&pm_data->link_pm_start, link_pm_runtime_start);
++      INIT_DELAYED_WORK(&pm_data->link_reconnect_work,
++                                              link_pm_reconnect_work);
++#ifdef CONFIG_HAS_WAKELOCK
++      wake_lock_init(&pm_data->l2_wake, WAKE_LOCK_SUSPEND, "l2_hsic");
++      wake_lock_init(&pm_data->boot_wake, WAKE_LOCK_SUSPEND, "boot_hsic");
++      wake_lock_init(&pm_data->rpm_wake, WAKE_LOCK_SUSPEND, "rpm_hsic");
++      wake_lock_init(&pm_data->tx_async_wake, WAKE_LOCK_SUSPEND, "tx_hsic");
++#else
++      device_init_wakeup(pm_data->miscdev.this_device, true);
++#endif
++
++      return 0;
++
++err_create_wq:
++      disable_irq_wake(pm_data->irq_link_hostwake);
++err_set_wake_irq:
++      free_irq(pm_data->irq_link_hostwake, (void *)pm_data);
++err_request_irq:
++      misc_deregister(&pm_data->miscdev);
++err_misc_register:
++      kfree(pm_data);
++      return r;
++}
++
++struct link_device *hsic_create_link_device(void *data)
++{
++      int ret;
++      struct usb_link_device *usb_ld;
++      struct link_device *ld;
++
++      usb_ld = kzalloc(sizeof(struct usb_link_device), GFP_KERNEL);
++      if (!usb_ld)
++              return NULL;
++
++      INIT_LIST_HEAD(&usb_ld->ld.list);
++      skb_queue_head_init(&usb_ld->ld.sk_fmt_tx_q);
++      skb_queue_head_init(&usb_ld->ld.sk_raw_tx_q);
++
++      ld = &usb_ld->ld;
++
++      ld->name = "usb";
++      ld->init_comm = usb_init_communication;
++      ld->terminate_comm = usb_terminate_communication;
++      ld->send = usb_send;
++      ld->com_state = COM_NONE;
++      ld->raw_tx_suspended = false;
++      init_completion(&ld->raw_tx_resumed_by_cp);
++
++      ld->tx_wq = create_singlethread_workqueue("usb_tx_wq");
++      if (!ld->tx_wq) {
++              mif_err("fail to create work Q.\n");
++              goto err;
++      }
++
++      INIT_DELAYED_WORK(&ld->tx_delayed_work, usb_tx_work);
++      INIT_DELAYED_WORK(&usb_ld->rx_retry_work, usb_rx_retry_work);
++      usb_ld->rx_retry_cnt = 0;
++
++      /* create link pm device */
++      ret = usb_link_pm_init(usb_ld, data);
++      if (ret)
++              goto err;
++
++      ret = if_usb_init(ld);
++      if (ret)
++              goto err;
++
++      mif_info("%s : create_link_device DONE\n", usb_ld->ld.name);
++      return (void *)ld;
++err:
++      kfree(usb_ld);
++      return NULL;
++}
++
++static void __exit if_usb_exit(void)
++{
++      usb_deregister(&if_usb_driver);
++}
+diff --git a/drivers/misc/modem_if/modem_link_device_hsic.h b/drivers/misc/modem_if/modem_link_device_hsic.h
+new file mode 100644
+index 0000000..604b067
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_link_device_hsic.h
+@@ -0,0 +1,155 @@
++/*
++ * Copyright (C) 2010 Google, Inc.
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#ifndef __MODEM_LINK_DEVICE_USB_H__
++#define __MODEM_LINK_DEVICE_USB_H__
++
++
++enum {
++      IF_USB_BOOT_EP = 0,
++      IF_USB_FMT_EP = 0,
++      IF_USB_RAW_EP,
++      IF_USB_RFS_EP,
++      IF_USB_CMD_EP,
++      IF_USB_DEVNUM_MAX,
++};
++
++/* each pipe has 2 ep for in/out */
++#define LINKPM_DEV_NUM        (IF_USB_DEVNUM_MAX * 2)
++/******************/
++/* xmm6260 specific */
++
++#define IOCTL_LINK_CONTROL_ENABLE     _IO('o', 0x30)
++#define IOCTL_LINK_CONTROL_ACTIVE     _IO('o', 0x31)
++#define IOCTL_LINK_GET_HOSTWAKE               _IO('o', 0x32)
++#define IOCTL_LINK_CONNECTED          _IO('o', 0x33)
++#define IOCTL_LINK_SET_BIAS_CLEAR     _IO('o', 0x34)
++#define IOCTL_LINK_GET_PHONEACTIVE    _IO('o', 0x35)
++
++/* VID,PID for IMC - XMM6260, XMM6262*/
++#define IMC_BOOT_VID          0x058b
++#define IMC_BOOT_PID          0x0041
++#define IMC_MAIN_VID          0x1519
++#define IMC_MAIN_PID          0x0020
++/* VID,PID for STE - M7400 */
++#define STE_BOOT_VID          0x04cc
++#define STE_BOOT_PID          0x7400
++#define STE_MAIN_VID          0x04cc
++#define STE_MAIN_PID          0x2333
++
++enum {
++      BOOT_DOWN = 0,
++      IPC_CHANNEL
++};
++
++enum ch_state {
++      STATE_SUSPENDED,
++      STATE_RESUMED,
++};
++
++#define HOSTWAKE_TRIGLEVEL    0
++/******************/
++
++struct link_pm_info {
++      struct usb_link_device *usb_ld;
++};
++
++struct usb_id_info {
++      int intf_id;
++      struct usb_link_device *usb_ld;
++};
++
++struct link_pm_data {
++      struct miscdevice miscdev;
++      struct usb_link_device *usb_ld;
++      unsigned irq_link_hostwake;
++      int (*link_ldo_enable)(bool);
++      unsigned gpio_link_enable;
++      unsigned gpio_link_active;
++      unsigned gpio_link_hostwake;
++      unsigned gpio_link_slavewake;
++      int (*link_reconnect)(void);
++      int link_reconnect_cnt;
++
++      struct workqueue_struct *wq;
++      struct completion active_done;
++      struct delayed_work link_pm_work;
++      struct delayed_work link_pm_start;
++      struct delayed_work link_reconnect_work;
++      bool resume_requested;
++      bool link_pm_active;
++      int resume_retry_cnt;
++
++      struct wake_lock l2_wake;
++      struct wake_lock boot_wake;
++      struct wake_lock rpm_wake;
++      struct wake_lock tx_async_wake;
++      struct notifier_block pm_notifier;
++      bool dpm_suspending;
++
++      /* Host wakeup toggle debugging */
++      unsigned ipc_debug_cnt;
++      unsigned long tx_cnt;
++      unsigned long rx_cnt;
++
++      void (*ehci_reg_dump)(struct device *);
++};
++
++struct if_usb_devdata {
++      struct usb_interface *data_intf;
++      struct usb_link_device *usb_ld;
++      struct usb_device *usbdev;
++      unsigned int tx_pipe;
++      unsigned int rx_pipe;
++      u8 disconnected;
++
++      int format;
++      struct urb *urb;
++      void *rx_buf;
++      unsigned int rx_buf_size;
++      enum ch_state state;
++};
++
++struct usb_link_device {
++      /*COMMON LINK DEVICE*/
++      struct link_device ld;
++
++      /*USB SPECIFIC LINK DEVICE*/
++      struct usb_device       *usbdev;
++      struct if_usb_devdata   devdata[IF_USB_DEVNUM_MAX];
++      unsigned int            dev_count;
++      unsigned int            suspended;
++      int if_usb_connected;
++
++      bool if_usb_is_main; /* boot,down(false) or main(true) */
++
++      /* LINK PM DEVICE DATA */
++      struct link_pm_data *link_pm_data;
++
++      /*RX retry work by -ENOMEM*/
++      struct delayed_work rx_retry_work;
++      struct urb *retry_urb;
++      unsigned rx_retry_cnt;
++};
++/* converts from struct link_device* to struct xxx_link_device* */
++#define to_usb_link_device(linkdev) \
++                      container_of(linkdev, struct usb_link_device, ld)
++
++
++#ifdef FOR_TEGRA
++extern void tegra_ehci_txfilltuning(void);
++#endif
++
++#endif
+diff --git a/drivers/misc/modem_if/modem_link_device_memory.h b/drivers/misc/modem_if/modem_link_device_memory.h
+new file mode 100644
+index 0000000..9ea01a7
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_link_device_memory.h
+@@ -0,0 +1,501 @@
++/*
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++#ifndef __MODEM_LINK_DEVICE_MEMORY_H__
++#define __MODEM_LINK_DEVICE_MEMORY_H__
++
++#include <linux/spinlock.h>
++#include <linux/wakelock.h>
++#include <linux/workqueue.h>
++#include <linux/timer.h>
++#include <linux/platform_data/modem.h>
++
++#include "modem_prj.h"
++
++#define DPRAM_MAGIC_CODE      0xAA
++
++/* interrupt masks.*/
++#define INT_MASK_VALID                0x0080
++#define INT_MASK_CMD          0x0040
++#define INT_VALID(x)          ((x) & INT_MASK_VALID)
++#define INT_CMD_VALID(x)      ((x) & INT_MASK_CMD)
++#define INT_NON_CMD(x)                (INT_MASK_VALID | (x))
++#define INT_CMD(x)            (INT_MASK_VALID | INT_MASK_CMD | (x))
++
++#define EXT_UDL_MASK          0xF000
++#define EXT_UDL_CMD(x)                ((x) & EXT_UDL_MASK)
++#define EXT_INT_VALID_MASK    0x8000
++#define EXT_CMD_VALID_MASK    0x4000
++#define UDL_CMD_VALID_MASK    0x2000
++#define EXT_INT_VALID(x)      ((x) & EXT_INT_VALID_MASK)
++#define EXT_CMD_VALID(x)      ((x) & EXT_CMD_VALID_MASK)
++#define UDL_CMD_VALID(x)      ((x) & UDL_CMD_VALID_MASK)
++#define INT_EXT_CMD(x)                (EXT_INT_VALID_MASK | EXT_CMD_VALID_MASK | (x))
++
++#define EXT_CMD_MASK(x)               ((x) & 0x0FFF)
++#define EXT_CMD_SET_SPEED_LOW 0x0011
++#define EXT_CMD_SET_SPEED_MID 0x0012
++#define EXT_CMD_SET_SPEED_HIGH        0x0013
++
++#define UDL_RESULT_SUCCESS    0x1
++#define UDL_RESULT_FAIL               0x2
++
++#define UDL_CMD_MASK(x)               (((x) >> 8) & 0xF)
++#define UDL_CMD_RECV_READY    0x1
++#define UDL_CMD_DL_START_REQ  0x2
++#define UDL_CMD_DL_START_RESP 0x3
++#define UDL_CMD_IMAGE_SEND_REQ        0x4
++#define UDL_CMD_SEND_DONE_RESP        0x5
++#define UDL_CMD_SEND_DONE_REQ 0x6
++#define UDL_CMD_UPDATE_DONE   0x7
++#define UDL_CMD_STATUS_UPDATE 0x8
++#define UDL_CMD_IMAGE_SEND_RESP       0x9
++#define UDL_CMD_EFS_CLEAR_RESP        0xB
++#define UDL_CMD_ALARM_BOOT_OK 0xC
++#define UDL_CMD_ALARM_BOOT_FAIL       0xD
++
++#define CMD_IMG_START_REQ     0x9200
++#define CMD_IMG_SEND_REQ      0x9400
++#define CMD_DL_SEND_DONE_REQ  0x9600
++#define CMD_UL_RECV_RESP      0x9601
++#define CMD_UL_RECV_DONE_RESP 0x9801
++
++/* special interrupt cmd indicating modem boot failure. */
++#define INT_POWERSAFE_FAIL    0xDEAD
++
++#define INT_MASK_REQ_ACK_F    0x0020
++#define INT_MASK_REQ_ACK_R    0x0010
++#define INT_MASK_RES_ACK_F    0x0008
++#define INT_MASK_RES_ACK_R    0x0004
++#define INT_MASK_SEND_F               0x0002
++#define INT_MASK_SEND_R               0x0001
++
++#define INT_MASK_REQ_ACK_RFS  0x0400 /* Request RES_ACK_RFS           */
++#define INT_MASK_RES_ACK_RFS  0x0200 /* Response of REQ_ACK_RFS       */
++#define INT_MASK_SEND_RFS     0x0100 /* Indicate sending RFS data     */
++
++#define INT_MASK_RES_ACK_SET \
++      (INT_MASK_RES_ACK_F | INT_MASK_RES_ACK_R | INT_MASK_RES_ACK_RFS)
++
++#define INT_MASK_SEND_SET \
++      (INT_MASK_SEND_F | INT_MASK_SEND_R | INT_MASK_SEND_RFS)
++
++#define INT_CMD_MASK(x)               ((x) & 0xF)
++#define INT_CMD_INIT_START    0x1
++#define INT_CMD_INIT_END      0x2
++#define INT_CMD_REQ_ACTIVE    0x3
++#define INT_CMD_RES_ACTIVE    0x4
++#define INT_CMD_REQ_TIME_SYNC 0x5
++#define INT_CMD_CRASH_RESET   0x7
++#define INT_CMD_PHONE_START   0x8
++#define INT_CMD_ERR_DISPLAY   0x9
++#define INT_CMD_CRASH_EXIT    0x9
++#define INT_CMD_CP_DEEP_SLEEP 0xA
++#define INT_CMD_NV_REBUILDING 0xB
++#define INT_CMD_EMER_DOWN     0xC
++#define INT_CMD_PIF_INIT_DONE 0xD
++#define INT_CMD_SILENT_NV_REBUILDING  0xE
++#define INT_CMD_NORMAL_PWR_OFF        0xF
++
++#define START_FLAG            0x7F
++#define END_FLAG              0x7E
++
++#define DP_MAGIC_DMDL         0x4445444C
++#define DP_MAGIC_UMDL         0x4445444D
++#define DP_DPRAM_SIZE         0x4000
++#define DP_DEFAULT_WRITE_LEN  8168
++#define DP_DEFAULT_DUMP_LEN   16128
++#define DP_DUMP_HEADER_SIZE   7
++
++#define UDL_TIMEOUT           (50 * HZ)
++#define UDL_SEND_TIMEOUT      (200 * HZ)
++#define FORCE_CRASH_ACK_TIMEOUT       (5 * HZ)
++#define DUMP_TIMEOUT          (30 * HZ)
++#define DUMP_START_TIMEOUT    (100 * HZ)
++#define DUMP_WAIT_TIMEOUT     (HZ >> 10)      /* 1/1024 second */
++#define RES_ACK_WAIT_TIMEOUT  (HZ >> 8)       /* 1/256 second */
++
++#ifndef CONFIG_SAMSUNG_PRODUCT_SHIP
++#define MAX_RETRY_CNT 1
++#else
++#define MAX_RETRY_CNT 3
++#endif
++
++#define MAX_SKB_TXQ_DEPTH     1024
++
++enum host_boot_mode {
++      HOST_BOOT_MODE_NORMAL,
++      HOST_BOOT_MODE_DUMP,
++};
++
++enum dpram_init_status {
++      DPRAM_INIT_STATE_NONE,
++      DPRAM_INIT_STATE_READY,
++};
++
++struct dpram_boot_img {
++      char *addr;
++      int size;
++      enum host_boot_mode mode;
++      unsigned req;
++      unsigned resp;
++};
++
++#define MAX_PAYLOAD_SIZE 0x2000
++struct dpram_boot_frame {
++      unsigned req;           /* AP->CP request               */
++      unsigned resp;          /* response expected by AP      */
++      ssize_t len;            /* data size in the buffer      */
++      unsigned offset;        /* offset to write into DPRAM   */
++      char data[MAX_PAYLOAD_SIZE];
++};
++
++/* buffer type for modem image */
++struct dpram_dump_arg {
++      char *buff;             /* pointer to the buffer        */
++      int buff_size;          /* buffer size                  */
++      unsigned req;           /* AP->CP request               */
++      unsigned resp;          /* CP->AP response              */
++      bool cmd;               /* AP->CP command               */
++};
++
++struct dpram_boot_map {
++      u32 __iomem *magic;
++      u8  __iomem *buff;
++      u32 __iomem *req;
++      u32 __iomem *resp;
++      u32          size;
++};
++
++struct qc_dpram_boot_map {
++      u8 __iomem *buff;
++      u16 __iomem *frame_size;
++      u16 __iomem *tag;
++      u16 __iomem *count;
++};
++
++struct dpram_dload_map {
++      u32 __iomem *magic;
++      u8  __iomem *buff;
++};
++
++struct dpram_uload_map {
++      u32 __iomem *magic;
++      u8  __iomem *buff;
++};
++
++struct ul_header {
++      u8  bop;
++      u16 total_frame;
++      u16 curr_frame;
++      u16 len;
++} __packed;
++
++struct dpram_udl_param {
++      unsigned char *addr;
++      unsigned int size;
++      unsigned int count;
++      unsigned int tag;
++};
++
++struct dpram_udl_check {
++      unsigned int total_size;
++      unsigned int rest_size;
++      unsigned int send_size;
++      unsigned int copy_start;
++      unsigned int copy_complete;
++      unsigned int boot_complete;
++};
++
++#define DP_BOOT_BUFF_OFFSET   4
++#define DP_DLOAD_BUFF_OFFSET  4
++#define DP_ULOAD_BUFF_OFFSET  4
++#define DP_BOOT_REQ_OFFSET    0
++#define DP_BOOT_RESP_OFFSET   8
++
++static inline bool circ_valid(u32 qsize, u32 in, u32 out)
++{
++      if (in >= qsize)
++              return false;
++
++      if (out >= qsize)
++              return false;
++
++      return true;
++}
++
++static inline int circ_get_space(int qsize, int in, int out)
++{
++      return (in < out) ? (out - in - 1) : (qsize + out - in - 1);
++}
++
++static inline int circ_get_usage(int qsize, int in, int out)
++{
++      return (in >= out) ? (in - out) : (qsize - out + in);
++}
++
++/**
++ * circ_read
++ * @dst: pointer to the destination buffer
++ * @src: pointer to the start of the circular queue
++ * @qsize: size of the circular queue
++ * @out: offset to read
++ * @len: length of data to be read
++ *
++ * Should be invoked after checking data length
++ */
++static inline void circ_read(u8 *dst, u8 *src, u32 qsize, u32 out, u32 len)
++{
++      unsigned len1;
++
++      if ((out + len) <= qsize) {
++              /* ----- (out)         (in) ----- */
++              /* -----   7f 00 00 7e      ----- */
++              memcpy(dst, (src + out), len);
++      } else {
++              /*       (in) ----------- (out)   */
++              /* 00 7e      -----------   7f 00 */
++
++              /* 1) data start (out) ~ buffer end */
++              len1 = qsize - out;
++              memcpy(dst, (src + out), len1);
++
++              /* 2) buffer start ~ data end (in?) */
++              memcpy((dst + len1), src, (len - len1));
++      }
++}
++
++/**
++ * circ_write
++ * @dst: pointer to the start of the circular queue
++ * @src: pointer to the source
++ * @qsize: size of the circular queue
++ * @in: offset to write
++ * @len: length of data to be written
++ *
++ * Should be invoked after checking free space
++ */
++static inline void circ_write(u8 *dst, u8 *src, u32 qsize, u32 in, u32 len)
++{
++      u32 space;
++
++      if ((in + len) < qsize) {
++              /*       (in) ----------- (out)   */
++              /* 00 7e      -----------   7f 00 */
++              memcpy((dst + in), src, len);
++      } else {
++              /* ----- (out)         (in) ----- */
++              /* -----   7f 00 00 7e      ----- */
++
++              /* 1) space start (in) ~ buffer end */
++              space = qsize - in;
++              memcpy((dst + in), src, ((len > space) ? space : len));
++
++              /* 2) buffer start ~ data end */
++              if (len > space)
++                      memcpy(dst, (src + space), (len - space));
++      }
++}
++
++#if 1
++#define DPRAM_MAX_RXBQ_SIZE   256
++
++struct mif_rxb {
++      u8 *buff;
++      unsigned size;
++
++      u8 *data;
++      unsigned len;
++};
++
++struct mif_rxb_queue {
++      int size;
++      int in;
++      int out;
++      struct mif_rxb *rxb;
++};
++
++/*
++** RXB (DPRAM RX buffer) functions
++*/
++static inline struct mif_rxb *rxbq_create_pool(unsigned size, int count)
++{
++      struct mif_rxb *rxb;
++      u8 *buff;
++      int i;
++
++      rxb = kzalloc(sizeof(struct mif_rxb) * count, GFP_KERNEL);
++      if (!rxb) {
++              mif_info("ERR! kzalloc rxb fail\n");
++              return NULL;
++      }
++
++      buff = kzalloc((size * count), GFP_KERNEL|GFP_DMA);
++      if (!buff) {
++              mif_info("ERR! kzalloc buff fail\n");
++              kfree(rxb);
++              return NULL;
++      }
++
++      for (i = 0; i < count; i++) {
++              rxb[i].buff = buff;
++              rxb[i].size = size;
++              buff += size;
++      }
++
++      return rxb;
++}
++
++static inline unsigned rxbq_get_page_size(unsigned len)
++{
++      return ((len + PAGE_SIZE - 1) >> PAGE_SHIFT) << PAGE_SHIFT;
++}
++
++static inline bool rxbq_empty(struct mif_rxb_queue *rxbq)
++{
++      return (rxbq->in == rxbq->out) ? true : false;
++}
++
++static inline int rxbq_free_size(struct mif_rxb_queue *rxbq)
++{
++      int in = rxbq->in;
++      int out = rxbq->out;
++      int qsize = rxbq->size;
++      return (in < out) ? (out - in - 1) : (qsize + out - in - 1);
++}
++
++static inline struct mif_rxb *rxbq_get_free_rxb(struct mif_rxb_queue *rxbq)
++{
++      struct mif_rxb *rxb = NULL;
++
++      if (likely(rxbq_free_size(rxbq) > 0)) {
++              rxb = &rxbq->rxb[rxbq->in];
++              rxbq->in++;
++              if (rxbq->in >= rxbq->size)
++                      rxbq->in -= rxbq->size;
++              rxb->data = rxb->buff;
++      }
++
++      return rxb;
++}
++
++static inline int rxbq_size(struct mif_rxb_queue *rxbq)
++{
++      int in = rxbq->in;
++      int out = rxbq->out;
++      int qsize = rxbq->size;
++      return (in >= out) ? (in - out) : (qsize - out + in);
++}
++
++static inline struct mif_rxb *rxbq_get_data_rxb(struct mif_rxb_queue *rxbq)
++{
++      struct mif_rxb *rxb = NULL;
++
++      if (likely(!rxbq_empty(rxbq))) {
++              rxb = &rxbq->rxb[rxbq->out];
++              rxbq->out++;
++              if (rxbq->out >= rxbq->size)
++                      rxbq->out -= rxbq->size;
++      }
++
++      return rxb;
++}
++
++static inline u8 *rxb_put(struct mif_rxb *rxb, unsigned len)
++{
++      rxb->len = len;
++      return rxb->data;
++}
++
++static inline void rxb_clear(struct mif_rxb *rxb)
++{
++      rxb->data = NULL;
++      rxb->len = 0;
++}
++#endif
++
++#ifndef CONFIG_SAMSUNG_PRODUCT_SHIP
++#define MAX_TRACE_SIZE        1024
++
++struct trace_data {
++      struct timespec ts;
++      enum dev_format dev;
++      u8 *data;
++      int size;
++};
++
++struct trace_queue {
++      spinlock_t lock;
++      int in;
++      int out;
++      struct trace_data trd[MAX_TRACE_SIZE];
++};
++
++static inline struct trace_data *trq_get_free_slot(struct trace_queue *trq)
++{
++      int in = trq->in;
++      int out = trq->out;
++      int qsize = MAX_TRACE_SIZE;
++      struct trace_data *trd = NULL;
++      unsigned long int flags;
++
++      spin_lock_irqsave(&trq->lock, flags);
++
++      if (circ_get_space(qsize, in, out) < 1) {
++              spin_unlock_irqrestore(&trq->lock, flags);
++              return NULL;
++      }
++
++      trd = &trq->trd[in];
++
++      in++;
++      if (in == qsize)
++              trq->in = 0;
++      else
++              trq->in = in;
++
++      spin_unlock_irqrestore(&trq->lock, flags);
++
++      return trd;
++}
++
++static inline struct trace_data *trq_get_data_slot(struct trace_queue *trq)
++{
++      int in = trq->in;
++      int out = trq->out;
++      int qsize = MAX_TRACE_SIZE;
++      struct trace_data *trd = NULL;
++      unsigned long int flags;
++
++      spin_lock_irqsave(&trq->lock, flags);
++
++      if (circ_get_usage(qsize, in, out) < 1) {
++              spin_unlock_irqrestore(&trq->lock, flags);
++              return NULL;
++      }
++
++      trd = &trq->trd[out];
++
++      out++;
++      if (out == qsize)
++              trq->out = 0;
++      else
++              trq->out = out;
++
++      spin_unlock_irqrestore(&trq->lock, flags);
++
++      return trd;
++}
++#endif
++
++#endif
+diff --git a/drivers/misc/modem_if/modem_link_device_mipi.c b/drivers/misc/modem_if/modem_link_device_mipi.c
+new file mode 100644
+index 0000000..f2804e9
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_link_device_mipi.c
+@@ -0,0 +1,1418 @@
++/* /linux/drivers/new_modem_if/link_dev_mipi.c
++ *
++ * Copyright (C) 2010 Google, Inc.
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/device.h>
++#include <linux/sched.h>
++#include <linux/irq.h>
++#include <linux/poll.h>
++#include <linux/gpio.h>
++#include <linux/if_arp.h>
++#include <linux/wakelock.h>
++#include <linux/semaphore.h>
++#include <linux/hsi_driver_if.h>
++
++#include <linux/platform_data/modem.h>
++#include "modem_prj.h"
++#include "modem_link_device_mipi.h"
++#include "modem_utils.h"
++
++static int mipi_hsi_init_communication(struct link_device *ld,
++                      struct io_device *iod)
++{
++      struct mipi_link_device *mipi_ld = to_mipi_link_device(ld);
++
++      switch (iod->format) {
++      case IPC_FMT:
++              return hsi_init_handshake(mipi_ld, HSI_INIT_MODE_NORMAL);
++
++      case IPC_BOOT:
++              return hsi_init_handshake(mipi_ld,
++                                      HSI_INIT_MODE_FLASHLESS_BOOT);
++
++      case IPC_RAMDUMP:
++              return hsi_init_handshake(mipi_ld,
++                                      HSI_INIT_MODE_CP_RAMDUMP);
++
++      case IPC_RFS:
++      case IPC_RAW:
++      default:
++              return 0;
++      }
++}
++
++static void mipi_hsi_terminate_communication(
++                      struct link_device *ld, struct io_device *iod)
++{
++      struct mipi_link_device *mipi_ld = to_mipi_link_device(ld);
++
++      switch (iod->format) {
++      case IPC_BOOT:
++              if (&mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].opened)
++                      if_hsi_close_channel(&mipi_ld->hsi_channles[
++                                      HSI_FLASHLESS_CHANNEL]);
++              break;
++
++      case IPC_RAMDUMP:
++              if (&mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].opened)
++                      if_hsi_close_channel(&mipi_ld->hsi_channles[
++                                      HSI_CP_RAMDUMP_CHANNEL]);
++              break;
++
++      case IPC_FMT:
++      case IPC_RFS:
++      case IPC_RAW:
++      default:
++              break;
++      }
++}
++
++static int mipi_hsi_send(struct link_device *ld, struct io_device *iod,
++                      struct sk_buff *skb)
++{
++      int ret;
++      struct mipi_link_device *mipi_ld = to_mipi_link_device(ld);
++
++      struct sk_buff_head *txq;
++
++      switch (iod->format) {
++      case IPC_RAW:
++              txq = &ld->sk_raw_tx_q;
++              break;
++
++      case IPC_RAMDUMP:
++              ret = if_hsi_write(&mipi_ld->hsi_channles[
++                                      HSI_CP_RAMDUMP_CHANNEL],
++                                      (u32 *)skb->data, skb->len);
++              if (ret < 0) {
++                      mif_err("[MIPI-HSI] write fail : %d\n", ret);
++                      dev_kfree_skb_any(skb);
++                      return ret;
++              } else
++                      mif_debug("[MIPI-HSI] write Done\n");
++              dev_kfree_skb_any(skb);
++              return ret;
++
++      case IPC_BOOT:
++              ret = if_hsi_write(&mipi_ld->hsi_channles[
++                                      HSI_FLASHLESS_CHANNEL],
++                                      (u32 *)skb->data, skb->len);
++              if (ret < 0) {
++                      mif_err("[MIPI-HSI] write fail : %d\n", ret);
++                      dev_kfree_skb_any(skb);
++                      return ret;
++              } else
++                      mif_debug("[MIPI-HSI] write Done\n");
++              dev_kfree_skb_any(skb);
++              return ret;
++
++      case IPC_FMT:
++      case IPC_RFS:
++      default:
++              txq = &ld->sk_fmt_tx_q;
++              break;
++      }
++
++      /* save io device */
++      skbpriv(skb)->iod = iod;
++      /* en queue skb data */
++      skb_queue_tail(txq, skb);
++
++      queue_work(ld->tx_wq, &ld->tx_work);
++      return skb->len;
++}
++
++static void mipi_hsi_tx_work(struct work_struct *work)
++{
++      int ret;
++      struct link_device *ld = container_of(work, struct link_device,
++                              tx_work);
++      struct mipi_link_device *mipi_ld = to_mipi_link_device(ld);
++      struct io_device *iod;
++      struct sk_buff *fmt_skb;
++      struct sk_buff *raw_skb;
++      int send_channel = 0;
++
++      while (ld->sk_fmt_tx_q.qlen || ld->sk_raw_tx_q.qlen) {
++              mif_debug("[MIPI-HSI] fmt qlen : %d, raw qlen:%d\n",
++                              ld->sk_fmt_tx_q.qlen, ld->sk_raw_tx_q.qlen);
++
++              fmt_skb = skb_dequeue(&ld->sk_fmt_tx_q);
++              if (fmt_skb) {
++                      iod = skbpriv(fmt_skb)->iod;
++
++                      mif_debug("[MIPI-HSI] dequeue. fmt qlen : %d\n",
++                                              ld->sk_fmt_tx_q.qlen);
++
++                      if (ld->com_state != COM_ONLINE) {
++                              mif_err("[MIPI-HSI] CP not ready\n");
++                              skb_queue_head(&ld->sk_fmt_tx_q, fmt_skb);
++                              return;
++                      }
++
++                      switch (iod->format) {
++                      case IPC_FMT:
++                              send_channel = HSI_FMT_CHANNEL;
++                              break;
++
++                      case IPC_RFS:
++                              send_channel = HSI_RFS_CHANNEL;
++                              break;
++
++                      case IPC_BOOT:
++                              send_channel = HSI_FLASHLESS_CHANNEL;
++                              break;
++
++                      case IPC_RAMDUMP:
++                              send_channel = HSI_CP_RAMDUMP_CHANNEL;
++                              break;
++
++                      default:
++                              break;
++                      }
++                      ret = if_hsi_protocol_send(mipi_ld, send_channel,
++                                      (u32 *)fmt_skb->data, fmt_skb->len);
++                      if (ret < 0) {
++                              /* TODO: Re Enqueue */
++                              mif_err("[MIPI-HSI] write fail : %d\n", ret);
++                      }  else
++                              mif_debug("[MIPI-HSI] write Done\n");
++
++                      dev_kfree_skb_any(fmt_skb);
++              }
++
++              raw_skb = skb_dequeue(&ld->sk_raw_tx_q);
++              if (raw_skb) {
++                      if (ld->com_state != COM_ONLINE) {
++                              mif_err("[MIPI-HSI] RAW CP not ready\n");
++                              skb_queue_head(&ld->sk_raw_tx_q, raw_skb);
++                              return;
++                      }
++
++                      mif_debug("[MIPI-HSI] dequeue. raw qlen:%d\n",
++                                              ld->sk_raw_tx_q.qlen);
++
++                      ret = if_hsi_protocol_send(mipi_ld, HSI_RAW_CHANNEL,
++                                      (u32 *)raw_skb->data, raw_skb->len);
++                      if (ret < 0) {
++                              /* TODO: Re Enqueue */
++                              mif_err("[MIPI-HSI] write fail : %d\n", ret);
++                      }  else
++                              mif_debug("[MIPI-HSI] write Done\n");
++
++                      dev_kfree_skb_any(raw_skb);
++              }
++      }
++}
++
++static int __devinit if_hsi_probe(struct hsi_device *dev);
++static struct hsi_device_driver if_hsi_driver = {
++      .ctrl_mask = ANY_HSI_CONTROLLER,
++      .probe = if_hsi_probe,
++      .driver = {
++              .name = "if_hsi_driver"
++      },
++};
++
++static int if_hsi_set_wakeline(struct if_hsi_channel *channel,
++                      unsigned int state)
++{
++      int ret;
++
++      spin_lock_bh(&channel->acwake_lock);
++      if (channel->acwake == state) {
++              spin_unlock_bh(&channel->acwake_lock);
++              return 0;
++      }
++
++      ret = hsi_ioctl(channel->dev, state ?
++              HSI_IOCTL_ACWAKE_UP : HSI_IOCTL_ACWAKE_DOWN, NULL);
++      if (ret) {
++              mif_err("[MIPI-HSI] ACWAKE(%d) setting fail : %d\n", state,
++                                      ret);
++              /* duplicate operation */
++              if (ret == -EPERM)
++                      channel->acwake = state;
++              spin_unlock_bh(&channel->acwake_lock);
++              return ret;
++      }
++
++      channel->acwake = state;
++      spin_unlock_bh(&channel->acwake_lock);
++
++      mif_debug("[MIPI-HSI] ACWAKE_%d(%d)\n", channel->channel_id, state);
++      return 0;
++}
++
++static void if_hsi_acwake_down_func(unsigned long data)
++{
++      int i;
++      struct if_hsi_channel *channel;
++      struct mipi_link_device *mipi_ld = (struct mipi_link_device *)data;
++
++      mif_debug("[MIPI-HSI]\n");
++
++      for (i = 0; i < HSI_NUM_OF_USE_CHANNELS; i++) {
++              channel = &mipi_ld->hsi_channles[i];
++
++              if ((channel->send_step == STEP_IDLE) &&
++                      (channel->recv_step == STEP_IDLE)) {
++                      if_hsi_set_wakeline(channel, 0);
++              } else {
++                      mod_timer(&mipi_ld->hsi_acwake_down_timer, jiffies +
++                                      HSI_ACWAKE_DOWN_TIMEOUT);
++                      mif_debug("[MIPI-HSI] mod_timer done(%d)\n",
++                                      HSI_ACWAKE_DOWN_TIMEOUT);
++                      return;
++              }
++      }
++}
++
++static int if_hsi_open_channel(struct if_hsi_channel *channel)
++{
++      int ret;
++
++      if (channel->opened) {
++              mif_debug("[MIPI-HSI] channel %d is already opened\n",
++                                      channel->channel_id);
++              return 0;
++      }
++
++      ret = hsi_open(channel->dev);
++      if (ret) {
++              mif_err("[MIPI-HSI] hsi_open fail : %d\n", ret);
++              return ret;
++      }
++      channel->opened = 1;
++
++      channel->send_step = STEP_IDLE;
++      channel->recv_step = STEP_IDLE;
++
++      mif_debug("[MIPI-HSI] hsi_open Done : %d\n", channel->channel_id);
++      return 0;
++}
++
++static int if_hsi_close_channel(struct if_hsi_channel *channel)
++{
++      unsigned long int flags;
++
++      if (!channel->opened) {
++              mif_debug("[MIPI-HSI] channel %d is already closed\n",
++                                      channel->channel_id);
++              return 0;
++      }
++
++      if_hsi_set_wakeline(channel, 0);
++      hsi_write_cancel(channel->dev);
++      hsi_read_cancel(channel->dev);
++
++      spin_lock_irqsave(&channel->tx_state_lock, flags);
++      channel->tx_state &= ~HSI_CHANNEL_TX_STATE_WRITING;
++      spin_unlock_irqrestore(&channel->tx_state_lock, flags);
++      spin_lock_irqsave(&channel->rx_state_lock, flags);
++      channel->rx_state &= ~HSI_CHANNEL_RX_STATE_READING;
++      spin_unlock_irqrestore(&channel->rx_state_lock, flags);
++
++      hsi_close(channel->dev);
++      channel->opened = 0;
++
++      channel->send_step = STEP_CLOSED;
++      channel->recv_step = STEP_CLOSED;
++
++      mif_debug("[MIPI-HSI] hsi_close Done : %d\n", channel->channel_id);
++      return 0;
++}
++
++static void mipi_hsi_start_work(struct work_struct *work)
++{
++      int ret;
++      u32 start_cmd = 0xC2;
++      struct mipi_link_device *mipi_ld =
++                      container_of(work, struct mipi_link_device,
++                                              start_work.work);
++
++      ret = if_hsi_protocol_send(mipi_ld, HSI_CMD_CHANNEL, &start_cmd, 1);
++      if (ret < 0) {
++              /* TODO: Re Enqueue */
++              mif_err("[MIPI-HSI] First write fail : %d\n", ret);
++      }  else {
++              mif_debug("[MIPI-HSI] First write Done : %d\n", ret);
++              mipi_ld->ld.com_state = COM_ONLINE;
++      }
++}
++
++static int hsi_init_handshake(struct mipi_link_device *mipi_ld, int mode)
++{
++      int ret;
++      int i;
++      struct hst_ctx tx_config;
++      struct hsr_ctx rx_config;
++
++      switch (mode) {
++      case HSI_INIT_MODE_NORMAL:
++              if (timer_pending(&mipi_ld->hsi_acwake_down_timer))
++                      del_timer(&mipi_ld->hsi_acwake_down_timer);
++
++              for (i = 0; i < HSI_NUM_OF_USE_CHANNELS; i++) {
++                      if (mipi_ld->hsi_channles[i].opened) {
++                              hsi_write_cancel(mipi_ld->hsi_channles[i].dev);
++                              hsi_read_cancel(mipi_ld->hsi_channles[i].dev);
++                      } else {
++                              ret = if_hsi_open_channel(
++                                              &mipi_ld->hsi_channles[i]);
++                              if (ret)
++                                      return ret;
++                      }
++
++                      hsi_ioctl(mipi_ld->hsi_channles[i].dev,
++                                              HSI_IOCTL_GET_TX, &tx_config);
++                      tx_config.mode = 2;
++                      tx_config.divisor = 0; /* Speed : 96MHz */
++                      tx_config.channels = HSI_MAX_CHANNELS;
++                      hsi_ioctl(mipi_ld->hsi_channles[i].dev,
++                                              HSI_IOCTL_SET_TX, &tx_config);
++
++                      hsi_ioctl(mipi_ld->hsi_channles[i].dev,
++                                              HSI_IOCTL_GET_RX, &rx_config);
++                      rx_config.mode = 2;
++                      rx_config.divisor = 0; /* Speed : 96MHz */
++                      rx_config.channels = HSI_MAX_CHANNELS;
++                      hsi_ioctl(mipi_ld->hsi_channles[i].dev,
++                                              HSI_IOCTL_SET_RX, &rx_config);
++                      mif_debug("[MIPI-HSI] Set TX/RX MIPI-HSI\n");
++
++                      hsi_ioctl(mipi_ld->hsi_channles[i].dev,
++                              HSI_IOCTL_SET_ACREADY_NORMAL, NULL);
++                      mif_debug("[MIPI-HSI] ACREADY_NORMAL\n");
++              }
++
++              if (mipi_ld->ld.com_state != COM_ONLINE)
++                      mipi_ld->ld.com_state = COM_HANDSHAKE;
++
++              ret = hsi_read(mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL].dev,
++                      mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL].rx_data,
++                                      1);
++              if (ret)
++                      mif_err("[MIPI-HSI] hsi_read fail : %d\n", ret);
++
++              if (mipi_ld->ld.com_state != COM_ONLINE)
++                      schedule_delayed_work(&mipi_ld->start_work, 3 * HZ);
++
++              mif_debug("[MIPI-HSI] hsi_init_handshake Done : MODE_NORMAL\n");
++              return 0;
++
++      case HSI_INIT_MODE_FLASHLESS_BOOT:
++              mipi_ld->ld.com_state = COM_BOOT;
++
++              if (mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].opened) {
++                      hsi_write_cancel(mipi_ld->hsi_channles[
++                                      HSI_FLASHLESS_CHANNEL].dev);
++                      hsi_read_cancel(mipi_ld->hsi_channles[
++                                      HSI_FLASHLESS_CHANNEL].dev);
++              } else {
++                      ret = if_hsi_open_channel(
++                              &mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL]);
++                      if (ret)
++                              return ret;
++              }
++
++              hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev,
++                                      HSI_IOCTL_GET_TX, &tx_config);
++              tx_config.mode = 2;
++              tx_config.divisor = 0; /* Speed : 96MHz */
++              tx_config.channels = 1;
++              hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev,
++                                      HSI_IOCTL_SET_TX, &tx_config);
++
++              hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev,
++                                      HSI_IOCTL_GET_RX, &rx_config);
++              rx_config.mode = 2;
++              rx_config.divisor = 0; /* Speed : 96MHz */
++              rx_config.channels = 1;
++              hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev,
++                                      HSI_IOCTL_SET_RX, &rx_config);
++              mif_debug("[MIPI-HSI] Set TX/RX MIPI-HSI\n");
++
++              if (!wake_lock_active(&mipi_ld->wlock)) {
++                      wake_lock(&mipi_ld->wlock);
++                      mif_debug("[MIPI-HSI] wake_lock\n");
++              }
++
++              if_hsi_set_wakeline(
++                      &mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL], 1);
++
++              ret = hsi_read(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev,
++                      mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].rx_data,
++                                      HSI_FLASHBOOT_ACK_LEN / 4);
++              if (ret)
++                      mif_err("[MIPI-HSI] hsi_read fail : %d\n", ret);
++
++              hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev,
++                      HSI_IOCTL_SET_ACREADY_NORMAL, NULL);
++
++              mif_debug("[MIPI-HSI] hsi_init_handshake Done : FLASHLESS_BOOT\n");
++              return 0;
++
++      case HSI_INIT_MODE_CP_RAMDUMP:
++              mipi_ld->ld.com_state = COM_CRASH;
++
++              if (mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].opened) {
++                      hsi_write_cancel(mipi_ld->hsi_channles[
++                                      HSI_CP_RAMDUMP_CHANNEL].dev);
++                      hsi_read_cancel(mipi_ld->hsi_channles[
++                                      HSI_CP_RAMDUMP_CHANNEL].dev);
++              } else {
++                      ret = if_hsi_open_channel(
++                              &mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL]);
++                      if (ret)
++                              return ret;
++              }
++
++              hsi_ioctl(mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].dev,
++                                      HSI_IOCTL_GET_TX, &tx_config);
++              tx_config.mode = 2;
++              tx_config.divisor = 0; /* Speed : 96MHz */
++              tx_config.channels = 1;
++              hsi_ioctl(mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].dev,
++                                      HSI_IOCTL_SET_TX, &tx_config);
++
++              hsi_ioctl(mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].dev,
++                                      HSI_IOCTL_GET_RX, &rx_config);
++              rx_config.mode = 2;
++              rx_config.divisor = 0; /* Speed : 96MHz */
++              rx_config.channels = 1;
++              hsi_ioctl(mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].dev,
++                                      HSI_IOCTL_SET_RX, &rx_config);
++              mif_debug("[MIPI-HSI] Set TX/RX MIPI-HSI\n");
++
++              if (!wake_lock_active(&mipi_ld->wlock)) {
++                      wake_lock(&mipi_ld->wlock);
++                      mif_debug("[MIPI-HSI] wake_lock\n");
++              }
++
++              if_hsi_set_wakeline(
++                      &mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL], 1);
++
++              ret = hsi_read(
++                      mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].dev,
++                      mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].rx_data,
++                                      DUMP_ERR_INFO_SIZE);
++              if (ret)
++                      mif_err("[MIPI-HSI] hsi_read fail : %d\n", ret);
++
++              hsi_ioctl(mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].dev,
++                      HSI_IOCTL_SET_ACREADY_NORMAL, NULL);
++
++              mif_debug("[MIPI-HSI] hsi_init_handshake Done : RAMDUMP\n");
++              return 0;
++
++      default:
++              return -EINVAL;
++      }
++}
++
++static u32 if_hsi_create_cmd(u32 cmd_type, int ch, void *arg)
++{
++      u32 cmd = 0;
++      unsigned int size = 0;
++
++      switch (cmd_type) {
++      case HSI_LL_MSG_BREAK:
++              return 0;
++
++      case HSI_LL_MSG_CONN_CLOSED:
++              cmd =  ((HSI_LL_MSG_CONN_CLOSED & 0x0000000F) << 28)
++                                      |((ch & 0x000000FF) << 24);
++              return cmd;
++
++      case HSI_LL_MSG_ACK:
++              size = *(unsigned int *)arg;
++
++              cmd = ((HSI_LL_MSG_ACK & 0x0000000F) << 28)
++                      |((ch & 0x000000FF) << 24) | ((size & 0x00FFFFFF));
++              return cmd;
++
++      case HSI_LL_MSG_NAK:
++              cmd = ((HSI_LL_MSG_NAK & 0x0000000F) << 28)
++                                      |((ch & 0x000000FF) << 24);
++              return cmd;
++
++      case HSI_LL_MSG_OPEN_CONN_OCTET:
++              size = *(unsigned int *)arg;
++
++              cmd = ((HSI_LL_MSG_OPEN_CONN_OCTET & 0x0000000F)
++                              << 28) | ((ch & 0x000000FF) << 24)
++                                      | ((size & 0x00FFFFFF));
++              return cmd;
++
++      case HSI_LL_MSG_OPEN_CONN:
++      case HSI_LL_MSG_CONF_RATE:
++      case HSI_LL_MSG_CANCEL_CONN:
++      case HSI_LL_MSG_CONN_READY:
++      case HSI_LL_MSG_ECHO:
++      case HSI_LL_MSG_INFO_REQ:
++      case HSI_LL_MSG_INFO:
++      case HSI_LL_MSG_CONFIGURE:
++      case HSI_LL_MSG_ALLOCATE_CH:
++      case HSI_LL_MSG_RELEASE_CH:
++      case HSI_LL_MSG_INVALID:
++      default:
++              mif_err("[MIPI-HSI] ERROR... CMD Not supported : %08x\n",
++                                      cmd_type);
++              return -EINVAL;
++      }
++}
++
++static void if_hsi_cmd_work(struct work_struct *work)
++{
++      int ret;
++      unsigned long int flags;
++      struct mipi_link_device *mipi_ld =
++                      container_of(work, struct mipi_link_device, cmd_work);
++      struct if_hsi_channel *channel =
++                      &mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL];
++      struct if_hsi_command *hsi_cmd;
++
++      mif_debug("[MIPI-HSI] cmd_work\n");
++
++      do {
++              spin_lock_irqsave(&mipi_ld->list_cmd_lock, flags);
++              if (!list_empty(&mipi_ld->list_of_hsi_cmd)) {
++                      hsi_cmd = list_entry(mipi_ld->list_of_hsi_cmd.next,
++                                      struct if_hsi_command, list);
++                      list_del(&hsi_cmd->list);
++                      spin_unlock_irqrestore(&mipi_ld->list_cmd_lock, flags);
++
++                      channel->send_step = STEP_TX;
++                      if_hsi_set_wakeline(channel, 1);
++                      mod_timer(&mipi_ld->hsi_acwake_down_timer, jiffies +
++                                      HSI_ACWAKE_DOWN_TIMEOUT);
++              } else {
++                      spin_unlock_irqrestore(&mipi_ld->list_cmd_lock, flags);
++                      channel->send_step = STEP_IDLE;
++                      break;
++              }
++              mif_debug("[MIPI-HSI] take command : %08x\n", hsi_cmd->command);
++
++              ret = if_hsi_write(channel, &hsi_cmd->command, 4);
++              if (ret < 0) {
++                      mif_err("[MIPI-HSI] write command fail : %d\n", ret);
++                      if_hsi_set_wakeline(channel, 0);
++                      channel->send_step = STEP_IDLE;
++                      return;
++              }
++              mif_debug("[MIPI-HSI] SEND CMD : %08x\n", hsi_cmd->command);
++
++              kfree(hsi_cmd);
++      } while (true);
++}
++
++static int if_hsi_send_command(struct mipi_link_device *mipi_ld,
++                      u32 cmd_type, int ch, u32 param)
++{
++      unsigned long int flags;
++      struct if_hsi_command *hsi_cmd;
++
++      hsi_cmd = kmalloc(sizeof(struct if_hsi_command), GFP_ATOMIC);
++      if (!hsi_cmd) {
++              mif_err("[MIPI-HSI] hsi_cmd kmalloc fail\n");
++              return -ENOMEM;
++      }
++      INIT_LIST_HEAD(&hsi_cmd->list);
++
++      hsi_cmd->command = if_hsi_create_cmd(cmd_type, ch, &param);
++      mif_debug("[MIPI-HSI] made command : %08x\n", hsi_cmd->command);
++
++      spin_lock_irqsave(&mipi_ld->list_cmd_lock, flags);
++      list_add_tail(&hsi_cmd->list, &mipi_ld->list_of_hsi_cmd);
++      spin_unlock_irqrestore(&mipi_ld->list_cmd_lock, flags);
++
++      mif_debug("[MIPI-HSI] queue_work : cmd_work\n");
++      queue_work(mipi_ld->mipi_wq, &mipi_ld->cmd_work);
++
++      return 0;
++}
++
++static int if_hsi_decode_cmd(u32 *cmd_data, u32 *cmd, u32 *ch,
++                      u32 *param)
++{
++      u32 data = *cmd_data;
++      u8 lrc_cal, lrc_act;
++      u8 val1, val2, val3;
++
++      *cmd = ((data & 0xF0000000) >> 28);
++      switch (*cmd) {
++      case HSI_LL_MSG_BREAK:
++              mif_err("[MIPI-HSI] Command MSG_BREAK Received\n");
++              return -1;
++
++      case HSI_LL_MSG_OPEN_CONN:
++              *ch = ((data & 0x0F000000) >> 24);
++              *param = ((data & 0x00FFFF00) >> 8);
++              val1 = ((data & 0xFF000000) >> 24);
++              val2 = ((data & 0x00FF0000) >> 16);
++              val3 = ((data & 0x0000FF00) >>  8);
++              lrc_act = (data & 0x000000FF);
++              lrc_cal = val1 ^ val2 ^ val3;
++
++              if (lrc_cal != lrc_act) {
++                      mif_err("[MIPI-HSI] CAL is broken\n");
++                      return -1;
++              }
++              return 0;
++
++      case HSI_LL_MSG_CONN_READY:
++      case HSI_LL_MSG_CONN_CLOSED:
++      case HSI_LL_MSG_CANCEL_CONN:
++      case HSI_LL_MSG_NAK:
++              *ch = ((data & 0x0F000000) >> 24);
++              return 0;
++
++      case HSI_LL_MSG_ACK:
++              *ch = ((data & 0x0F000000) >> 24);
++              *param = (data & 0x00FFFFFF);
++              return 0;
++
++      case HSI_LL_MSG_CONF_RATE:
++              *ch = ((data & 0x0F000000) >> 24);
++              *param = ((data & 0x0F000000) >> 24);
++              return 0;
++
++      case HSI_LL_MSG_OPEN_CONN_OCTET:
++              *ch = ((data & 0x0F000000) >> 24);
++              *param = (data & 0x00FFFFFF);
++              return 0;
++
++      case HSI_LL_MSG_ECHO:
++      case HSI_LL_MSG_INFO_REQ:
++      case HSI_LL_MSG_INFO:
++      case HSI_LL_MSG_CONFIGURE:
++      case HSI_LL_MSG_ALLOCATE_CH:
++      case HSI_LL_MSG_RELEASE_CH:
++      case HSI_LL_MSG_INVALID:
++      default:
++              mif_err("[MIPI-HSI] Invalid command received : %08x\n", *cmd);
++              *cmd = HSI_LL_MSG_INVALID;
++              *ch  = HSI_LL_INVALID_CHANNEL;
++              return -1;
++      }
++      return 0;
++}
++
++static int if_hsi_rx_cmd_handle(struct mipi_link_device *mipi_ld, u32 cmd,
++                      u32 ch, u32 param)
++{
++      int ret;
++      struct if_hsi_channel *channel = &mipi_ld->hsi_channles[ch];
++
++      mif_debug("[MIPI-HSI] if_hsi_rx_cmd_handle cmd=0x%x, ch=%d, param=%d\n",
++                              cmd, ch, param);
++
++      switch (cmd) {
++      case HSI_LL_MSG_OPEN_CONN_OCTET:
++              switch (channel->recv_step) {
++              case STEP_IDLE:
++                      channel->recv_step = STEP_TO_ACK;
++
++                      if (!wake_lock_active(&mipi_ld->wlock)) {
++                              wake_lock(&mipi_ld->wlock);
++                              mif_debug("[MIPI-HSI] wake_lock\n");
++                      }
++
++                      if_hsi_set_wakeline(channel, 1);
++                      mod_timer(&mipi_ld->hsi_acwake_down_timer, jiffies +
++                                              HSI_ACWAKE_DOWN_TIMEOUT);
++                      mif_debug("[MIPI-HSI] mod_timer done(%d)\n",
++                                              HSI_ACWAKE_DOWN_TIMEOUT);
++
++                      ret = if_hsi_send_command(mipi_ld, HSI_LL_MSG_ACK, ch,
++                                              param);
++                      if (ret) {
++                              mif_err("[MIPI-HSI] if_hsi_send_command fail : %d\n",
++                                                      ret);
++                              return ret;
++                      }
++
++                      channel->packet_size = param;
++                      channel->recv_step = STEP_RX;
++                      if (param % 4)
++                              param += (4 - (param % 4));
++                      channel->rx_count = param;
++                      ret = hsi_read(channel->dev, channel->rx_data,
++                                              channel->rx_count / 4);
++                      if (ret) {
++                              mif_err("[MIPI-HSI] hsi_read fail : %d\n", ret);
++                              return ret;
++                      }
++                      return 0;
++
++              case STEP_NOT_READY:
++                      ret = if_hsi_send_command(mipi_ld, HSI_LL_MSG_NAK, ch,
++                                              param);
++                      if (ret) {
++                              mif_err("[MIPI-HSI] if_hsi_send_command fail : %d\n",
++                                                      ret);
++                              return ret;
++                      }
++                      return 0;
++
++              default:
++                      mif_err("[MIPI-HSI] wrong state : %08x, recv_step : %d\n",
++                                              cmd, channel->recv_step);
++                      return -1;
++              }
++
++      case HSI_LL_MSG_ACK:
++      case HSI_LL_MSG_NAK:
++              switch (channel->send_step) {
++              case STEP_WAIT_FOR_ACK:
++              case STEP_SEND_OPEN_CONN:
++                      if (cmd == HSI_LL_MSG_ACK) {
++                              channel->send_step = STEP_TX;
++                              channel->got_nack = 0;
++                              mif_debug("[MIPI-HSI] got ack\n");
++                      } else {
++                              channel->send_step = STEP_WAIT_FOR_ACK;
++                              channel->got_nack = 1;
++                              mif_debug("[MIPI-HSI] got nack\n");
++                      }
++
++                      up(&channel->ack_done_sem);
++                      return 0;
++
++              default:
++                      mif_err("[MIPI-HSI] wrong state : %08x\n", cmd);
++                      return -1;
++              }
++
++      case HSI_LL_MSG_CONN_CLOSED:
++              switch (channel->send_step) {
++              case STEP_TX:
++              case STEP_WAIT_FOR_CONN_CLOSED:
++                      mif_debug("[MIPI-HSI] got close\n");
++
++                      channel->send_step = STEP_IDLE;
++                      up(&channel->close_conn_done_sem);
++                      return 0;
++
++              default:
++                      mif_err("[MIPI-HSI] wrong state : %08x\n", cmd);
++                      return -1;
++              }
++
++      case HSI_LL_MSG_OPEN_CONN:
++      case HSI_LL_MSG_ECHO:
++      case HSI_LL_MSG_CANCEL_CONN:
++      case HSI_LL_MSG_CONF_RATE:
++      default:
++              mif_err("[MIPI-HSI] ERROR... CMD Not supported : %08x\n", cmd);
++              return -EINVAL;
++      }
++}
++
++static int if_hsi_protocol_send(struct mipi_link_device *mipi_ld, int ch,
++                      u32 *data, unsigned int len)
++{
++      int ret;
++      int retry_count = 0;
++      int ack_timeout_cnt = 0;
++      struct io_device *iod;
++      struct if_hsi_channel *channel = &mipi_ld->hsi_channles[ch];
++
++      if (channel->send_step != STEP_IDLE) {
++              mif_err("[MIPI-HSI] send step is not IDLE : %d\n",
++                                      channel->send_step);
++              return -EBUSY;
++      }
++      channel->send_step = STEP_SEND_OPEN_CONN;
++
++      if (!wake_lock_active(&mipi_ld->wlock)) {
++              wake_lock(&mipi_ld->wlock);
++              mif_debug("[MIPI-HSI] wake_lock\n");
++      }
++
++      if_hsi_set_wakeline(channel, 1);
++      mod_timer(&mipi_ld->hsi_acwake_down_timer, jiffies +
++                                      HSI_ACWAKE_DOWN_TIMEOUT);
++      mif_debug("[MIPI-HSI] mod_timer done(%d)\n",
++                              HSI_ACWAKE_DOWN_TIMEOUT);
++
++retry_send:
++
++      ret = if_hsi_send_command(mipi_ld, HSI_LL_MSG_OPEN_CONN_OCTET, ch,
++                              len);
++      if (ret) {
++              mif_err("[MIPI-HSI] if_hsi_send_command fail : %d\n", ret);
++              if_hsi_set_wakeline(channel, 0);
++              channel->send_step = STEP_IDLE;
++              return -1;
++      }
++
++      channel->send_step = STEP_WAIT_FOR_ACK;
++
++      if (down_timeout(&channel->ack_done_sem, HSI_ACK_DONE_TIMEOUT) < 0) {
++              mif_err("[MIPI-HSI] ch=%d, ack_done timeout\n",
++                                      channel->channel_id);
++
++              if_hsi_set_wakeline(channel, 0);
++
++              if (mipi_ld->ld.com_state == COM_ONLINE) {
++                      ack_timeout_cnt++;
++                      if (ack_timeout_cnt < 10) {
++                              if_hsi_set_wakeline(channel, 1);
++                              mif_err("[MIPI-HSI] ch=%d, retry send open. cnt : %d\n",
++                                      channel->channel_id, ack_timeout_cnt);
++                              goto retry_send;
++                      }
++
++                      /* try to recover cp */
++                      iod = link_get_iod_with_format(&mipi_ld->ld, IPC_FMT);
++                      if (iod)
++                              iod->modem_state_changed(iod,
++                                              STATE_CRASH_RESET);
++              }
++
++              channel->send_step = STEP_IDLE;
++              return -ETIMEDOUT;
++      }
++      mif_debug("[MIPI-HSI] ch=%d, got ack_done=%d\n", channel->channel_id,
++                              channel->got_nack);
++
++      if (channel->got_nack && (retry_count < 10)) {
++              mif_debug("[MIPI-HSI] ch=%d, got nack=%d retry=%d\n",
++                              channel->channel_id, channel->got_nack,
++                              retry_count);
++              retry_count++;
++              msleep_interruptible(1);
++              goto retry_send;
++      }
++      retry_count = 0;
++
++      channel->send_step = STEP_TX;
++
++      ret = if_hsi_write(channel, data, len);
++      if (ret < 0) {
++              mif_err("[MIPI-HSI] if_hsi_write fail : %d\n", ret);
++              if_hsi_set_wakeline(channel, 0);
++              channel->send_step = STEP_IDLE;
++              return ret;
++      }
++      mif_debug("[MIPI-HSI] SEND DATA : %08x(%d)\n", *data, len);
++
++      mif_debug("%08x %08x %08x %08x %08x %08x %08x %08x\n",
++              *channel->tx_data, *(channel->tx_data + 1),
++              *(channel->tx_data + 2), *(channel->tx_data + 3),
++              *(channel->tx_data + 4), *(channel->tx_data + 5),
++              *(channel->tx_data + 6), *(channel->tx_data + 7));
++
++      channel->send_step = STEP_WAIT_FOR_CONN_CLOSED;
++      if (down_timeout(&channel->close_conn_done_sem,
++                              HSI_CLOSE_CONN_DONE_TIMEOUT) < 0) {
++              mif_err("[MIPI-HSI] ch=%d, close conn timeout\n",
++                                      channel->channel_id);
++              if_hsi_set_wakeline(channel, 0);
++              channel->send_step = STEP_IDLE;
++              return -ETIMEDOUT;
++      }
++      mif_debug("[MIPI-HSI] ch=%d, got close_conn_done\n",
++                              channel->channel_id);
++
++      channel->send_step = STEP_IDLE;
++
++      mif_debug("[MIPI-HSI] write protocol Done : %d\n", channel->tx_count);
++      return channel->tx_count;
++}
++
++static int if_hsi_write(struct if_hsi_channel *channel, u32 *data,
++                      unsigned int size)
++{
++      int ret;
++      unsigned long int flags;
++
++      spin_lock_irqsave(&channel->tx_state_lock, flags);
++      if (channel->tx_state & HSI_CHANNEL_TX_STATE_WRITING) {
++              spin_unlock_irqrestore(&channel->tx_state_lock, flags);
++              return -EBUSY;
++      }
++      channel->tx_state |= HSI_CHANNEL_TX_STATE_WRITING;
++      spin_unlock_irqrestore(&channel->tx_state_lock, flags);
++
++      channel->tx_data = data;
++      if (size % 4)
++              size += (4 - (size % 4));
++      channel->tx_count = size;
++
++      mif_debug("[MIPI-HSI] submit write data : 0x%x(%d)\n",
++                              *(u32 *)channel->tx_data, channel->tx_count);
++      ret = hsi_write(channel->dev, channel->tx_data, channel->tx_count / 4);
++      if (ret) {
++              mif_err("[MIPI-HSI] ch=%d, hsi_write fail : %d\n",
++                                      channel->channel_id, ret);
++
++              spin_lock_irqsave(&channel->tx_state_lock, flags);
++              channel->tx_state &= ~HSI_CHANNEL_TX_STATE_WRITING;
++              spin_unlock_irqrestore(&channel->tx_state_lock, flags);
++
++              return ret;
++      }
++
++      if (down_timeout(&channel->write_done_sem,
++                              HSI_WRITE_DONE_TIMEOUT) < 0) {
++              mif_err("[MIPI-HSI] ch=%d, hsi_write_done timeout : %d\n",
++                                      channel->channel_id, size);
++
++              mif_err("[MIPI-HSI] data : %08x %08x %08x %08x %08x ...\n",
++                      *channel->tx_data, *(channel->tx_data + 1),
++                      *(channel->tx_data + 2), *(channel->tx_data + 3),
++                      *(channel->tx_data + 4));
++
++              hsi_write_cancel(channel->dev);
++
++              spin_lock_irqsave(&channel->tx_state_lock, flags);
++              channel->tx_state &= ~HSI_CHANNEL_TX_STATE_WRITING;
++              spin_unlock_irqrestore(&channel->tx_state_lock, flags);
++
++              return -ETIMEDOUT;
++      }
++
++      if (channel->tx_count != size)
++              mif_err("[MIPI-HSI] ch:%d,write_done fail,write_size:%d,origin_size:%d\n",
++                              channel->channel_id, channel->tx_count, size);
++
++      mif_debug("[MIPI-HSI] len:%d, id:%d, data : %08x %08x %08x %08x %08x ...\n",
++              channel->tx_count, channel->channel_id, *channel->tx_data,
++              *(channel->tx_data + 1), *(channel->tx_data + 2),
++              *(channel->tx_data + 3), *(channel->tx_data + 4));
++
++      return channel->tx_count;
++}
++
++static void if_hsi_write_done(struct hsi_device *dev, unsigned int size)
++{
++      unsigned long int flags;
++      struct mipi_link_device *mipi_ld =
++                      (struct mipi_link_device *)if_hsi_driver.priv_data;
++      struct if_hsi_channel *channel = &mipi_ld->hsi_channles[dev->n_ch];
++
++      mif_debug("[MIPI-HSI] got write data : 0x%x(%d)\n",
++                              *(u32 *)channel->tx_data, size);
++
++      spin_lock_irqsave(&channel->tx_state_lock, flags);
++      channel->tx_state &= ~HSI_CHANNEL_TX_STATE_WRITING;
++      spin_unlock_irqrestore(&channel->tx_state_lock, flags);
++
++      mif_debug("%08x %08x %08x %08x %08x %08x %08x %08x\n",
++                      *channel->tx_data, *(channel->tx_data + 1),
++                      *(channel->tx_data + 2), *(channel->tx_data + 3),
++                      *(channel->tx_data + 4), *(channel->tx_data + 5),
++                      *(channel->tx_data + 6), *(channel->tx_data + 7));
++
++      channel->tx_count = 4 * size;
++      up(&channel->write_done_sem);
++}
++
++static void if_hsi_read_done(struct hsi_device *dev, unsigned int size)
++{
++      int ret;
++      unsigned long int flags;
++      u32 cmd = 0, ch = 0, param = 0;
++      struct mipi_link_device *mipi_ld =
++                      (struct mipi_link_device *)if_hsi_driver.priv_data;
++      struct if_hsi_channel *channel = &mipi_ld->hsi_channles[dev->n_ch];
++      struct io_device *iod;
++      enum dev_format format_type = 0;
++
++      mif_debug("[MIPI-HSI] got read data : 0x%x(%d)\n",
++                              *(u32 *)channel->rx_data, size);
++
++      spin_lock_irqsave(&channel->rx_state_lock, flags);
++      channel->rx_state &= ~HSI_CHANNEL_RX_STATE_READING;
++      spin_unlock_irqrestore(&channel->rx_state_lock, flags);
++
++      channel->rx_count = 4 * size;
++
++      switch (channel->channel_id) {
++      case HSI_CONTROL_CHANNEL:
++              switch (mipi_ld->ld.com_state) {
++              case COM_HANDSHAKE:
++              case COM_ONLINE:
++                      mif_debug("[MIPI-HSI] RECV CMD : %08x\n",
++                                              *channel->rx_data);
++
++                      if (channel->rx_count != 4) {
++                              mif_err("[MIPI-HSI] wrong command len : %d\n",
++                                      channel->rx_count);
++                              return;
++                      }
++
++                      ret = if_hsi_decode_cmd(channel->rx_data, &cmd, &ch,
++                                              &param);
++                      if (ret)
++                              mif_err("[MIPI-HSI] decode_cmd fail=%d, "
++                                              "cmd=%x\n", ret, cmd);
++                      else {
++                              mif_debug("[MIPI-HSI] decode_cmd : %08x\n",
++                                              cmd);
++                              ret = if_hsi_rx_cmd_handle(mipi_ld, cmd, ch,
++                                                      param);
++                              if (ret)
++                                      mif_err("[MIPI-HSI] handle cmd "
++                                                      "cmd=%x\n", cmd);
++                      }
++
++                      ret = hsi_read(channel->dev, channel->rx_data, 1);
++                      if (ret)
++                              mif_err("[MIPI-HSI] hsi_read fail : %d\n", ret);
++
++                      return;
++
++              case COM_BOOT:
++                      mif_debug("[MIPI-HSI] receive data : 0x%x(%d)\n",
++                                      *channel->rx_data, channel->rx_count);
++
++                      iod = link_get_iod_with_format(&mipi_ld->ld, IPC_BOOT);
++                      if (iod) {
++                              channel->packet_size = *channel->rx_data;
++                              mif_debug("[MIPI-HSI] flashless packet size : "
++                                              "%d\n", channel->packet_size);
++
++                              ret = iod->recv(iod,
++                                              &mipi_ld->ld,
++                                              (char *)channel->rx_data + 4,
++                                              HSI_FLASHBOOT_ACK_LEN - 4);
++                              if (ret < 0)
++                                      mif_err("[MIPI-HSI] recv call "
++                                                      "fail : %d\n", ret);
++                      }
++
++                      ret = hsi_read(channel->dev, channel->rx_data,
++                                              HSI_FLASHBOOT_ACK_LEN / 4);
++                      if (ret)
++                              mif_err("[MIPI-HSI] hsi_read fail : %d\n", ret);
++                      return;
++
++              case COM_CRASH:
++                      mif_debug("[MIPI-HSI] receive data : 0x%x(%d)\n",
++                                      *channel->rx_data, channel->rx_count);
++
++                      iod = link_get_iod_with_format(&mipi_ld->ld,
++                                                              IPC_RAMDUMP);
++                      if (iod) {
++                              channel->packet_size = *channel->rx_data;
++                              mif_debug("[MIPI-HSI] ramdump packet size : "
++                                              "%d\n", channel->packet_size);
++
++                              ret = iod->recv(iod,
++                                              &mipi_ld->ld,
++                                              (char *)channel->rx_data + 4,
++                                              channel->packet_size);
++                              if (ret < 0)
++                                      mif_err("[MIPI-HSI] recv call "
++                                                      "fail : %d\n", ret);
++                      }
++
++                      ret = hsi_read(channel->dev, channel->rx_data,
++                                              DUMP_PACKET_SIZE);
++                      if (ret)
++                              mif_err("[MIPI-HSI] hsi_read fail : %d\n", ret);
++                      return;
++
++              case COM_NONE:
++              default:
++                      mif_err("[MIPI-HSI] receive data in wrong state : 0x%x(%d)\n",
++                                      *channel->rx_data, channel->rx_count);
++                      return;
++              }
++              break;
++
++      case HSI_FMT_CHANNEL:
++              mif_debug("[MIPI-HSI] iodevice format : IPC_FMT\n");
++              format_type = IPC_FMT;
++              break;
++      case HSI_RAW_CHANNEL:
++              mif_debug("[MIPI-HSI] iodevice format : IPC_MULTI_RAW\n");
++              format_type = IPC_MULTI_RAW;
++              break;
++      case HSI_RFS_CHANNEL:
++              mif_debug("[MIPI-HSI] iodevice format : IPC_RFS\n");
++              format_type = IPC_RFS;
++              break;
++
++      case HSI_CMD_CHANNEL:
++              mif_debug("[MIPI-HSI] receive command data : 0x%x\n",
++                                      *channel->rx_data);
++
++              ch = channel->channel_id;
++              param = 0;
++              ret = if_hsi_send_command(mipi_ld, HSI_LL_MSG_CONN_CLOSED,
++                                      ch, param);
++              if (ret)
++                      mif_err("[MIPI-HSI] send_cmd fail=%d\n", ret);
++
++              channel->recv_step = STEP_IDLE;
++              return;
++
++      default:
++              return;
++      }
++
++      iod = link_get_iod_with_format(&mipi_ld->ld, format_type);
++      if (iod) {
++              mif_debug("[MIPI-HSI] iodevice format : %d\n", iod->format);
++
++              channel->recv_step = STEP_NOT_READY;
++
++              mif_debug("[MIPI-HSI] RECV DATA : %08x(%d)-%d\n",
++                              *channel->rx_data, channel->packet_size,
++                              iod->format);
++
++              mif_debug("%08x %08x %08x %08x %08x %08x %08x %08x\n",
++                      *channel->rx_data, *(channel->rx_data + 1),
++                      *(channel->rx_data + 2), *(channel->rx_data + 3),
++                      *(channel->rx_data + 4), *(channel->rx_data + 5),
++                      *(channel->rx_data + 6), *(channel->rx_data + 7));
++
++              ret = iod->recv(iod, &mipi_ld->ld,
++                              (char *)channel->rx_data, channel->packet_size);
++              if (ret < 0)
++                      mif_err("[MIPI-HSI] recv call fail : %d\n", ret);
++
++              ch = channel->channel_id;
++              param = 0;
++              ret = if_hsi_send_command(mipi_ld,
++                              HSI_LL_MSG_CONN_CLOSED, ch, param);
++              if (ret)
++                      mif_err("[MIPI-HSI] send_cmd fail=%d\n", ret);
++
++              channel->recv_step = STEP_IDLE;
++      }
++}
++
++static void if_hsi_port_event(struct hsi_device *dev, unsigned int event,
++                      void *arg)
++{
++      int acwake_level = 1;
++      struct mipi_link_device *mipi_ld =
++                      (struct mipi_link_device *)if_hsi_driver.priv_data;
++
++      switch (event) {
++      case HSI_EVENT_BREAK_DETECTED:
++              mif_err("[MIPI-HSI] HSI_EVENT_BREAK_DETECTED\n");
++              return;
++
++      case HSI_EVENT_HSR_DATAAVAILABLE:
++              mif_err("[MIPI-HSI] HSI_EVENT_HSR_DATAAVAILABLE\n");
++              return;
++
++      case HSI_EVENT_CAWAKE_UP:
++              if (dev->n_ch == HSI_CONTROL_CHANNEL) {
++                      if (!wake_lock_active(&mipi_ld->wlock)) {
++                              wake_lock(&mipi_ld->wlock);
++                              mif_debug("[MIPI-HSI] wake_lock\n");
++                      }
++                      mif_debug("[MIPI-HSI] CAWAKE_%d(1)\n", dev->n_ch);
++              }
++              return;
++
++      case HSI_EVENT_CAWAKE_DOWN:
++              if (dev->n_ch == HSI_CONTROL_CHANNEL)
++                      mif_debug("[MIPI-HSI] CAWAKE_%d(0)\n", dev->n_ch);
++
++              if ((dev->n_ch == HSI_CONTROL_CHANNEL) &&
++                      mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL].opened) {
++                      hsi_ioctl(
++                      mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL].dev,
++                      HSI_IOCTL_GET_ACWAKE, &acwake_level);
++
++                      mif_debug("[MIPI-HSI] GET_ACWAKE. Ch : %d, level : %d\n",
++                                      dev->n_ch, acwake_level);
++
++                      if (!acwake_level) {
++                              wake_unlock(&mipi_ld->wlock);
++                              mif_debug("[MIPI-HSI] wake_unlock\n");
++                      }
++              }
++              return;
++
++      case HSI_EVENT_ERROR:
++              mif_err("[MIPI-HSI] HSI_EVENT_ERROR\n");
++              return;
++
++      default:
++              mif_err("[MIPI-HSI] Unknown Event : %d\n", event);
++              return;
++      }
++}
++
++static int __devinit if_hsi_probe(struct hsi_device *dev)
++{
++      int port = 0;
++      unsigned long *address;
++      struct mipi_link_device *mipi_ld =
++                      (struct mipi_link_device *)if_hsi_driver.priv_data;
++
++      for (port = 0; port < HSI_MAX_PORTS; port++) {
++              if (if_hsi_driver.ch_mask[port])
++                      break;
++      }
++      address = (unsigned long *)&if_hsi_driver.ch_mask[port];
++
++      if (test_bit(dev->n_ch, address) && (dev->n_p == port)) {
++              /* Register callback func */
++              hsi_set_write_cb(dev, if_hsi_write_done);
++              hsi_set_read_cb(dev, if_hsi_read_done);
++              hsi_set_port_event_cb(dev, if_hsi_port_event);
++
++              /* Init device data */
++              mipi_ld->hsi_channles[dev->n_ch].dev = dev;
++              mipi_ld->hsi_channles[dev->n_ch].tx_count = 0;
++              mipi_ld->hsi_channles[dev->n_ch].rx_count = 0;
++              mipi_ld->hsi_channles[dev->n_ch].tx_state = 0;
++              mipi_ld->hsi_channles[dev->n_ch].rx_state = 0;
++              mipi_ld->hsi_channles[dev->n_ch].packet_size = 0;
++              mipi_ld->hsi_channles[dev->n_ch].acwake = 0;
++              mipi_ld->hsi_channles[dev->n_ch].send_step = STEP_UNDEF;
++              mipi_ld->hsi_channles[dev->n_ch].recv_step = STEP_UNDEF;
++              spin_lock_init(&mipi_ld->hsi_channles[dev->n_ch].tx_state_lock);
++              spin_lock_init(&mipi_ld->hsi_channles[dev->n_ch].rx_state_lock);
++              spin_lock_init(&mipi_ld->hsi_channles[dev->n_ch].acwake_lock);
++              sema_init(&mipi_ld->hsi_channles[dev->n_ch].write_done_sem,
++                        0);
++              sema_init(&mipi_ld->hsi_channles[dev->n_ch].ack_done_sem,
++                        0);
++              sema_init(&mipi_ld->hsi_channles[dev->n_ch].close_conn_done_sem,
++                        0);
++      }
++
++      mif_debug("[MIPI-HSI] if_hsi_probe() done. ch : %d\n", dev->n_ch);
++      return 0;
++}
++
++static int if_hsi_init(struct link_device *ld)
++{
++      int ret;
++      int i = 0;
++      struct mipi_link_device *mipi_ld = to_mipi_link_device(ld);
++
++      for (i = 0; i < HSI_MAX_PORTS; i++)
++              if_hsi_driver.ch_mask[i] = 0;
++
++      for (i = 0; i < HSI_MAX_CHANNELS; i++) {
++              mipi_ld->hsi_channles[i].dev = NULL;
++              mipi_ld->hsi_channles[i].opened = 0;
++              mipi_ld->hsi_channles[i].channel_id = i;
++      }
++      if_hsi_driver.ch_mask[0] = CHANNEL_MASK;
++
++      /* TODO - need to get priv data (request to TI) */
++      if_hsi_driver.priv_data = (void *)mipi_ld;
++      ret = hsi_register_driver(&if_hsi_driver);
++      if (ret) {
++              mif_err("[MIPI-HSI] hsi_register_driver() fail : %d\n", ret);
++              return ret;
++      }
++
++      mipi_ld->mipi_wq = create_singlethread_workqueue("mipi_cmd_wq");
++      if (!mipi_ld->mipi_wq) {
++              mif_err("[MIPI-HSI] fail to create work Q.\n");
++              return -ENOMEM;
++      }
++      INIT_WORK(&mipi_ld->cmd_work, if_hsi_cmd_work);
++      INIT_DELAYED_WORK(&mipi_ld->start_work, mipi_hsi_start_work);
++
++      setup_timer(&mipi_ld->hsi_acwake_down_timer, if_hsi_acwake_down_func,
++                              (unsigned long)mipi_ld);
++
++      /* TODO - allocate rx buff */
++      mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL].rx_data =
++                              kmalloc(64 * 1024, GFP_DMA | GFP_ATOMIC);
++      if (!mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL].rx_data) {
++              mif_err("[MIPI-HSI] alloc HSI_CONTROL_CHANNEL rx_data fail\n");
++              return -ENOMEM;
++      }
++      mipi_ld->hsi_channles[HSI_FMT_CHANNEL].rx_data =
++                              kmalloc(256 * 1024, GFP_DMA | GFP_ATOMIC);
++      if (!mipi_ld->hsi_channles[HSI_FMT_CHANNEL].rx_data) {
++              mif_err("[MIPI-HSI] alloc HSI_FMT_CHANNEL rx_data fail\n");
++              return -ENOMEM;
++      }
++      mipi_ld->hsi_channles[HSI_RAW_CHANNEL].rx_data =
++                              kmalloc(256 * 1024, GFP_DMA | GFP_ATOMIC);
++      if (!mipi_ld->hsi_channles[HSI_RAW_CHANNEL].rx_data) {
++              mif_err("[MIPI-HSI] alloc HSI_RAW_CHANNEL rx_data fail\n");
++              return -ENOMEM;
++      }
++      mipi_ld->hsi_channles[HSI_RFS_CHANNEL].rx_data =
++                              kmalloc(256 * 1024, GFP_DMA | GFP_ATOMIC);
++      if (!mipi_ld->hsi_channles[HSI_RFS_CHANNEL].rx_data) {
++              mif_err("[MIPI-HSI] alloc HSI_RFS_CHANNEL rx_data fail\n");
++              return -ENOMEM;
++      }
++      mipi_ld->hsi_channles[HSI_CMD_CHANNEL].rx_data =
++                              kmalloc(256 * 1024, GFP_DMA | GFP_ATOMIC);
++      if (!mipi_ld->hsi_channles[HSI_CMD_CHANNEL].rx_data) {
++              mif_err("[MIPI-HSI] alloc HSI_CMD_CHANNEL rx_data fail\n");
++              return -ENOMEM;
++      }
++
++      return 0;
++}
++
++struct link_device *mipi_create_link_device(struct platform_device *pdev)
++{
++      int ret;
++      struct mipi_link_device *mipi_ld;
++      struct link_device *ld;
++
++      /* for dpram int */
++      /* struct modem_data *pdata = pdev->dev.platform_data; */
++
++      mipi_ld = kzalloc(sizeof(struct mipi_link_device), GFP_KERNEL);
++      if (!mipi_ld)
++              return NULL;
++
++      INIT_LIST_HEAD(&mipi_ld->list_of_hsi_cmd);
++      spin_lock_init(&mipi_ld->list_cmd_lock);
++      skb_queue_head_init(&mipi_ld->ld.sk_fmt_tx_q);
++      skb_queue_head_init(&mipi_ld->ld.sk_raw_tx_q);
++
++      wake_lock_init(&mipi_ld->wlock, WAKE_LOCK_SUSPEND, "mipi_link");
++
++      ld = &mipi_ld->ld;
++
++      ld->name = "mipi_hsi";
++      ld->init_comm = mipi_hsi_init_communication;
++      ld->terminate_comm = mipi_hsi_terminate_communication;
++      ld->send = mipi_hsi_send;
++      ld->com_state = COM_NONE;
++
++      /* for dpram int */
++      /* ld->irq = gpio_to_irq(pdata->gpio); s*/
++
++      ld->tx_wq = create_singlethread_workqueue("mipi_tx_wq");
++      if (!ld->tx_wq) {
++              mif_err("[MIPI-HSI] fail to create work Q.\n");
++              return NULL;
++      }
++      INIT_WORK(&ld->tx_work, mipi_hsi_tx_work);
++
++      ret = if_hsi_init(ld);
++      if (ret)
++              return NULL;
++
++      return ld;
++}
+diff --git a/drivers/misc/modem_if/modem_link_device_mipi.h b/drivers/misc/modem_if/modem_link_device_mipi.h
+new file mode 100644
+index 0000000..8ca4968
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_link_device_mipi.h
+@@ -0,0 +1,158 @@
++/*
++ * Copyright (C) 2010 Google, Inc.
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#ifndef __MODEM_LINK_DEVICE_MIPI_H__
++#define __MODEM_LINK_DEVICE_MIPI_H__
++
++
++#define HSI_MAX_CHANNELS      16
++#define CHANNEL_MASK  0xFF
++
++#define HSI_CHANNEL_TX_STATE_UNAVAIL  (1 << 0)
++#define HSI_CHANNEL_TX_STATE_WRITING  (1 << 1)
++#define HSI_CHANNEL_RX_STATE_UNAVAIL  (1 << 0)
++#define HSI_CHANNEL_RX_STATE_READING  (1 << 1)
++
++#define HSI_WRITE_DONE_TIMEOUT        (HZ)
++#define HSI_READ_DONE_TIMEOUT (HZ)
++#define HSI_ACK_DONE_TIMEOUT  (HZ)
++#define HSI_CLOSE_CONN_DONE_TIMEOUT   (HZ)
++#define HSI_ACWAKE_DOWN_TIMEOUT       (HZ / 2)
++
++#define HSI_CONTROL_CHANNEL   0
++#define HSI_FLASHLESS_CHANNEL 0
++#define HSI_CP_RAMDUMP_CHANNEL        0
++#define HSI_FMT_CHANNEL       1
++#define HSI_RAW_CHANNEL       2
++#define HSI_RFS_CHANNEL       3
++#define HSI_CMD_CHANNEL       4
++#define HSI_NUM_OF_USE_CHANNELS       5
++
++#define HSI_LL_INVALID_CHANNEL        0xFF
++
++#define HSI_FLASHBOOT_ACK_LEN 16
++#define DUMP_PACKET_SIZE      12289 /* 48K + 4 length, word unit */
++#define DUMP_ERR_INFO_SIZE    39 /* 150 bytes + 4 length , word unit */
++
++enum {
++      HSI_LL_MSG_BREAK, /* 0x0 */
++      HSI_LL_MSG_ECHO,
++      HSI_LL_MSG_INFO_REQ,
++      HSI_LL_MSG_INFO,
++      HSI_LL_MSG_CONFIGURE,
++      HSI_LL_MSG_ALLOCATE_CH,
++      HSI_LL_MSG_RELEASE_CH,
++      HSI_LL_MSG_OPEN_CONN,
++      HSI_LL_MSG_CONN_READY,
++      HSI_LL_MSG_CONN_CLOSED, /* 0x9 */
++      HSI_LL_MSG_CANCEL_CONN,
++      HSI_LL_MSG_ACK, /* 0xB */
++      HSI_LL_MSG_NAK, /* 0xC */
++      HSI_LL_MSG_CONF_RATE,
++      HSI_LL_MSG_OPEN_CONN_OCTET, /* 0xE */
++      HSI_LL_MSG_INVALID = 0xFF,
++};
++
++enum {
++      STEP_UNDEF,
++      STEP_CLOSED,
++      STEP_NOT_READY,
++      STEP_IDLE,
++      STEP_ERROR,
++      STEP_SEND_OPEN_CONN,
++      STEP_SEND_ACK,
++      STEP_WAIT_FOR_ACK,
++      STEP_TO_ACK,
++      STEP_SEND_NACK,
++      STEP_GET_NACK,
++      STEP_SEND_CONN_READY,
++      STEP_WAIT_FOR_CONN_READY,
++      STEP_SEND_CONF_RATE,
++      STEP_WAIT_FOR_CONF_ACK,
++      STEP_TX,
++      STEP_RX,
++      STEP_SEND_CONN_CLOSED,
++      STEP_WAIT_FOR_CONN_CLOSED,
++      STEP_SEND_BREAK,
++};
++
++
++struct if_hsi_channel {
++      struct hsi_device *dev;
++      unsigned int channel_id;
++
++      u32 *tx_data;
++      unsigned int tx_count;
++      u32 *rx_data;
++      unsigned int rx_count;
++      unsigned int packet_size;
++
++      unsigned int tx_state;
++      unsigned int rx_state;
++      spinlock_t tx_state_lock;
++      spinlock_t rx_state_lock;
++
++      unsigned int send_step;
++      unsigned int recv_step;
++
++      unsigned int got_nack;
++      unsigned int acwake;
++      spinlock_t acwake_lock;
++
++      struct semaphore write_done_sem;
++      struct semaphore ack_done_sem;
++      struct semaphore close_conn_done_sem;
++
++      unsigned int opened;
++};
++
++struct if_hsi_command {
++      u32 command;
++      struct list_head list;
++};
++
++struct mipi_link_device {
++      struct link_device ld;
++
++      /* mipi specific link data */
++      struct if_hsi_channel hsi_channles[HSI_MAX_CHANNELS];
++      struct list_head list_of_hsi_cmd;
++      spinlock_t list_cmd_lock;
++
++      struct workqueue_struct *mipi_wq;
++      struct work_struct cmd_work;
++      struct delayed_work start_work;
++
++      struct wake_lock wlock;
++      struct timer_list hsi_acwake_down_timer;
++};
++/* converts from struct link_device* to struct xxx_link_device* */
++#define to_mipi_link_device(linkdev) \
++                      container_of(linkdev, struct mipi_link_device, ld)
++
++
++enum {
++      HSI_INIT_MODE_NORMAL,
++      HSI_INIT_MODE_FLASHLESS_BOOT,
++      HSI_INIT_MODE_CP_RAMDUMP,
++};
++static int hsi_init_handshake(struct mipi_link_device *mipi_ld, int mode);
++static int if_hsi_write(struct if_hsi_channel *channel, u32 *data,
++                      unsigned int size);
++static int if_hsi_protocol_send(struct mipi_link_device *mipi_ld, int ch,
++                      u32 *data, unsigned int len);
++static int if_hsi_close_channel(struct if_hsi_channel *channel);
++
++#endif
+diff --git a/drivers/misc/modem_if/modem_link_device_pld.c b/drivers/misc/modem_if/modem_link_device_pld.c
+new file mode 100644
+index 0000000..23d4627
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_link_device_pld.c
+@@ -0,0 +1,1618 @@
++/*
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <linux/irq.h>
++#include <linux/gpio.h>
++#include <linux/time.h>
++#include <linux/interrupt.h>
++#include <linux/timer.h>
++#include <linux/wakelock.h>
++#include <linux/delay.h>
++#include <linux/wait.h>
++#include <linux/sched.h>
++#include <linux/vmalloc.h>
++#include <linux/if_arp.h>
++#include <linux/platform_device.h>
++#include <linux/kallsyms.h>
++#include <linux/platform_data/modem.h>
++
++#include "modem_prj.h"
++#include "modem_link_device_pld.h"
++#include "modem_utils.h"
++
++
++/*
++** Function prototypes for basic DPRAM operations
++*/
++static inline void clear_intr(struct pld_link_device *pld);
++static inline u16 recv_intr(struct pld_link_device *pld);
++static inline void send_intr(struct pld_link_device *pld, u16 mask);
++
++static inline u16 get_magic(struct pld_link_device *pld);
++static inline void set_magic(struct pld_link_device *pld, u16 val);
++static inline u16 get_access(struct pld_link_device *pld);
++static inline void set_access(struct pld_link_device *pld, u16 val);
++
++static inline u32 get_tx_head(struct pld_link_device *pld, int id);
++static inline u32 get_tx_tail(struct pld_link_device *pld, int id);
++static inline void set_tx_head(struct pld_link_device *pld, int id, u32 in);
++static inline void set_tx_tail(struct pld_link_device *pld, int id, u32 out);
++static inline u8 *get_tx_buff(struct pld_link_device *pld, int id);
++static inline u32 get_tx_buff_size(struct pld_link_device *pld, int id);
++
++static inline u32 get_rx_head(struct pld_link_device *pld, int id);
++static inline u32 get_rx_tail(struct pld_link_device *pld, int id);
++static inline void set_rx_head(struct pld_link_device *pld, int id, u32 in);
++static inline void set_rx_tail(struct pld_link_device *pld, int id, u32 out);
++static inline u8 *get_rx_buff(struct pld_link_device *pld, int id);
++static inline u32 get_rx_buff_size(struct pld_link_device *pld, int id);
++
++static inline u16 get_mask_req_ack(struct pld_link_device *pld, int id);
++static inline u16 get_mask_res_ack(struct pld_link_device *pld, int id);
++static inline u16 get_mask_send(struct pld_link_device *pld, int id);
++
++static void handle_cp_crash(struct pld_link_device *pld);
++static int trigger_force_cp_crash(struct pld_link_device *pld);
++
++/*
++** Functions for debugging
++*/
++static void set_dpram_map(struct pld_link_device *pld,
++                      struct mif_irq_map *map)
++{
++      map->magic = get_magic(pld);
++      map->access = get_access(pld);
++
++      map->fmt_tx_in = get_tx_head(pld, IPC_FMT);
++      map->fmt_tx_out = get_tx_tail(pld, IPC_FMT);
++      map->fmt_rx_in = get_rx_head(pld, IPC_FMT);
++      map->fmt_rx_out = get_rx_tail(pld, IPC_FMT);
++      map->raw_tx_in = get_tx_head(pld, IPC_RAW);
++      map->raw_tx_out = get_tx_tail(pld, IPC_RAW);
++      map->raw_rx_in = get_rx_head(pld, IPC_RAW);
++      map->raw_rx_out = get_rx_tail(pld, IPC_RAW);
++
++      map->cp2ap = recv_intr(pld);
++}
++
++/*
++** DPRAM operations
++*/
++static int pld_register_isr(unsigned irq, irqreturn_t (*isr)(int, void*),
++                              unsigned long flag, const char *name,
++                              struct pld_link_device *pld)
++{
++      int ret = 0;
++
++      ret = request_irq(irq, isr, flag, name, pld);
++      if (ret) {
++              mif_info("%s: ERR! request_irq fail (err %d)\n", name, ret);
++              return ret;
++      }
++
++      ret = enable_irq_wake(irq);
++      if (ret)
++              mif_info("%s: ERR! enable_irq_wake fail (err %d)\n", name, ret);
++
++      mif_info("%s (#%d) handler registered\n", name, irq);
++
++      return 0;
++}
++
++static inline void clear_intr(struct pld_link_device *pld)
++{
++      if (pld->ext_op && pld->ext_op->clear_intr)
++              pld->ext_op->clear_intr(pld);
++}
++
++static inline u16 recv_intr(struct pld_link_device *pld)
++{
++      u16 val1 = 0, val2 = 0, cnt = 3;
++      unsigned long int flags;
++
++      spin_lock_irqsave(&pld->pld_lock, flags);
++
++      do {
++              /* Check head value written */
++              iowrite16(PLD_ADDR_MASK(&pld->mbx2ap[0]),
++                              pld->address_buffer);
++              val1 =  ioread16(pld->base);
++
++              iowrite16(PLD_ADDR_MASK(&pld->mbx2ap[0]),
++                              pld->address_buffer);
++              val2 =  ioread16(pld->base);
++
++              if (likely(val1 == val2))       {
++                      spin_unlock_irqrestore(&pld->pld_lock, flags);
++                      return val1;
++              }
++
++              mif_err("ERR: intr1(%d) != intr1(%d)\n", val1, val2);
++
++      } while (cnt--);
++
++      spin_unlock_irqrestore(&pld->pld_lock, flags);
++
++      return val1;
++}
++
++static inline void send_intr(struct pld_link_device *pld, u16 mask)
++{
++      int cnt = 3;
++      u32 val = 0;
++      unsigned long int flags;
++
++      spin_lock_irqsave(&pld->pld_lock, flags);
++
++      iowrite16(PLD_ADDR_MASK(&pld->mbx2cp[0]),
++                              pld->address_buffer);
++      iowrite16((u16)mask, pld->base);
++
++      do {
++              /* Check head value written */
++              iowrite16(PLD_ADDR_MASK(&pld->mbx2cp[0]),
++                                      pld->address_buffer);
++              val =  ioread16(pld->base);
++
++              if (likely(val == mask))        {
++                      spin_unlock_irqrestore(&pld->pld_lock, flags);
++                      return;
++              }
++
++              mif_err("ERR: intr1(%d) != intr2(%d)\n", val, mask);
++              udelay(100);
++
++              /* Write head value again */
++              iowrite16(PLD_ADDR_MASK(&pld->mbx2cp[0]),
++                                      pld->address_buffer);
++              iowrite16((u16)mask, pld->base);
++      } while (cnt--);
++
++      spin_unlock_irqrestore(&pld->pld_lock, flags);
++
++      return;
++}
++
++static inline u16 get_magic(struct pld_link_device *pld)
++{
++      u16 val1 = 0, val2 = 0, cnt = 3;
++      unsigned long int flags;
++
++      spin_lock_irqsave(&pld->pld_lock, flags);
++
++      do {
++              /* Check head value written */
++              iowrite16(PLD_ADDR_MASK(&pld->magic_ap2cp[0]),
++                              pld->address_buffer);
++              val1 =  ioread16(pld->base);
++
++              iowrite16(PLD_ADDR_MASK(&pld->magic_ap2cp[0]),
++                              pld->address_buffer);
++              val2 =  ioread16(pld->base);
++
++              if (likely(val1 == val2))       {
++                      spin_unlock_irqrestore(&pld->pld_lock, flags);
++                      return val1;
++              }
++
++              mif_err("ERR: txq.head(%d) != in(%d)\n", val1, val2);
++              udelay(100);
++
++      } while (cnt--);
++
++      spin_unlock_irqrestore(&pld->pld_lock, flags);
++      return val1;
++
++}
++
++static inline void set_magic(struct pld_link_device *pld, u16 in)
++{
++      int cnt = 3;
++      u32 val = 0;
++      unsigned long int flags;
++
++      spin_lock_irqsave(&pld->pld_lock, flags);
++
++      iowrite16(PLD_ADDR_MASK(&pld->magic_ap2cp[0]),
++                              pld->address_buffer);
++      iowrite16((u16)in, pld->base);
++
++      do {
++              /* Check head value written */
++              iowrite16(PLD_ADDR_MASK(&pld->magic_ap2cp[0]),
++                                      pld->address_buffer);
++              val =  ioread16(pld->base);
++
++              if (likely(val == in))  {
++                      spin_unlock_irqrestore(&pld->pld_lock, flags);
++                      return;
++              }
++
++              mif_err("ERR: magic1(%d) != magic2(%d)\n", val, in);
++              udelay(100);
++
++              /* Write head value again */
++              iowrite16(PLD_ADDR_MASK(&pld->magic_ap2cp[0]),
++                                      pld->address_buffer);
++              iowrite16((u16)in, pld->base);
++      } while (cnt--);
++
++      spin_unlock_irqrestore(&pld->pld_lock, flags);
++      return;
++}
++
++static inline u16 get_access(struct pld_link_device *pld)
++{
++      u16 val1 = 0, val2 = 0, cnt = 3;
++      unsigned long int flags;
++
++      spin_lock_irqsave(&pld->pld_lock, flags);
++
++      do {
++              /* Check head value written */
++              iowrite16(PLD_ADDR_MASK(&pld->access_ap2cp[0]),
++                              pld->address_buffer);
++              val1 =  ioread16(pld->base);
++
++              iowrite16(PLD_ADDR_MASK(&pld->access_ap2cp[0]),
++                              pld->address_buffer);
++              val2 =  ioread16(pld->base);
++
++              if (likely(val1 == val2))       {
++                      spin_unlock_irqrestore(&pld->pld_lock, flags);
++                      return val1;
++              }
++
++              mif_err("ERR: access1(%d) != access2(%d)\n", val1, val2);
++              udelay(100);
++
++      } while (cnt--);
++
++      spin_unlock_irqrestore(&pld->pld_lock, flags);
++      return val1;
++
++}
++
++static inline void set_access(struct pld_link_device *pld, u16 in)
++{
++      int cnt = 3;
++      u32 val = 0;
++      unsigned long int flags;
++
++      iowrite16(PLD_ADDR_MASK(&pld->access_ap2cp[0]),
++                              pld->address_buffer);
++      iowrite16((u16)in, pld->base);
++
++      spin_lock_irqsave(&pld->pld_lock, flags);
++
++      do {
++              /* Check head value written */
++              iowrite16(PLD_ADDR_MASK(&pld->access_ap2cp[0]),
++                                      pld->address_buffer);
++              val =  ioread16(pld->base);
++
++              if (likely(val == in))  {
++                      spin_unlock_irqrestore(&pld->pld_lock, flags);
++                      return;
++              }
++
++              mif_err("ERR: access(%d) != access(%d)\n", val, in);
++              udelay(100);
++
++              /* Write head value again */
++              iowrite16(PLD_ADDR_MASK(&pld->access_ap2cp[0]),
++                                      pld->address_buffer);
++              iowrite16((u16)in, pld->base);
++      } while (cnt--);
++
++      spin_unlock_irqrestore(&pld->pld_lock, flags);
++      return;
++}
++
++static inline u32 get_tx_head(struct pld_link_device *pld, int id)
++{
++      u16 val1 = 0, val2 = 0, cnt = 3;
++      unsigned long int flags;
++
++      spin_lock_irqsave(&pld->pld_lock, flags);
++
++      do {
++              /* Check head value written */
++              iowrite16(PLD_ADDR_MASK(&(pld->dev[id]->txq.head)[0]),
++                              pld->address_buffer);
++              val1 =  ioread16(pld->base);
++
++              iowrite16(PLD_ADDR_MASK(&(pld->dev[id]->txq.head)[0]),
++                              pld->address_buffer);
++              val2 =  ioread16(pld->base);
++
++              if (likely(val1 == val2))       {
++                      spin_unlock_irqrestore(&pld->pld_lock, flags);
++                      return val1;
++              }
++
++              mif_err("ERR: %s txq.head(%d) != in(%d)\n",
++                      get_dev_name(id), val1, val2);
++              udelay(100);
++
++      } while (cnt--);
++
++      spin_unlock_irqrestore(&pld->pld_lock, flags);
++      return val1;
++}
++
++static inline u32 get_tx_tail(struct pld_link_device *pld, int id)
++{
++      u16 val1 = 0, val2 = 0, cnt = 3;
++      unsigned long int flags;
++
++      spin_lock_irqsave(&pld->pld_lock, flags);
++
++      do {
++              /* Check head value written */
++              iowrite16(PLD_ADDR_MASK(&(pld->dev[id]->txq.tail)[0]),
++                                      pld->address_buffer);
++              val1 =  ioread16(pld->base);
++
++              iowrite16(PLD_ADDR_MASK(&(pld->dev[id]->txq.tail)[0]),
++                                      pld->address_buffer);
++              val2 =  ioread16(pld->base);
++
++              if (likely(val1 == val2))       {
++                      spin_unlock_irqrestore(&pld->pld_lock, flags);
++                      return val1;
++              }
++
++              mif_err("ERR: %s txq.tail(%d) != in(%d)\n",
++                      get_dev_name(id), val1, val2);
++              udelay(100);
++
++      } while (cnt--);
++
++      spin_unlock_irqrestore(&pld->pld_lock, flags);
++      return val1;
++}
++
++static inline void set_tx_head(struct pld_link_device *pld, int id, u32 in)
++{
++      int cnt = 3;
++      u32 val = 0;
++      unsigned long int flags;
++
++      spin_lock_irqsave(&pld->pld_lock, flags);
++
++      iowrite16(PLD_ADDR_MASK(&(pld->dev[id]->txq.head)[0]),
++                              pld->address_buffer);
++      iowrite16((u16)in, pld->base);
++
++      do {
++              /* Check head value written */
++              iowrite16(PLD_ADDR_MASK(&(pld->dev[id]->txq.head)[0]),
++                                      pld->address_buffer);
++              val =  ioread16(pld->base);
++
++              if (likely(val == in))  {
++                      spin_unlock_irqrestore(&pld->pld_lock, flags);
++                      return;
++              }
++
++              mif_err("ERR: %s txq.head(%d) != in(%d)\n",
++                      get_dev_name(id), val, in);
++              udelay(100);
++
++              /* Write head value again */
++              iowrite16(PLD_ADDR_MASK(&(pld->dev[id]->txq.head)[0]),
++                                      pld->address_buffer);
++              iowrite16((u16)in, pld->base);
++      } while (cnt--);
++
++      spin_unlock_irqrestore(&pld->pld_lock, flags);
++      return;
++}
++
++static inline void set_tx_tail(struct pld_link_device *pld, int id, u32 out)
++{
++      return;
++}
++
++static inline u8 *get_tx_buff(struct pld_link_device *pld, int id)
++{
++      return pld->dev[id]->txq.buff;
++}
++
++static inline u32 get_tx_buff_size(struct pld_link_device *pld, int id)
++{
++      return pld->dev[id]->txq.size;
++}
++
++static inline u32 get_rx_head(struct pld_link_device *pld, int id)
++{
++      u16 val1 = 0, val2 = 0, cnt = 3;
++      unsigned long int flags;
++
++      spin_lock_irqsave(&pld->pld_lock, flags);
++
++      do {
++              /* Check head value written */
++              iowrite16(PLD_ADDR_MASK(&(pld->dev[id]->rxq.head)[0]),
++                                      pld->address_buffer);
++              val1 =  ioread16(pld->base);
++
++              iowrite16(PLD_ADDR_MASK(&(pld->dev[id]->rxq.head)[0]),
++                                      pld->address_buffer);
++              val2 =  ioread16(pld->base);
++
++              if (likely(val1 == val2))       {
++                      spin_unlock_irqrestore(&pld->pld_lock, flags);
++                      return val1;
++              }
++
++              mif_err("ERR: %s rxq.head(%d) != in(%d)\n",
++                      get_dev_name(id), val1, val2);
++              udelay(100);
++
++      } while (cnt--);
++
++      spin_unlock_irqrestore(&pld->pld_lock, flags);
++      return val1;
++}
++
++static inline u32 get_rx_tail(struct pld_link_device *pld, int id)
++{
++      u16 val1 = 0, val2 = 0, cnt = 3;
++      unsigned long int flags;
++
++      spin_lock_irqsave(&pld->pld_lock, flags);
++
++      do {
++              /* Check head value written */
++              iowrite16(PLD_ADDR_MASK(&(pld->dev[id]->rxq.tail)[0]),
++                                      pld->address_buffer);
++              val1 =  ioread16(pld->base);
++
++              iowrite16(PLD_ADDR_MASK(&(pld->dev[id]->rxq.tail)[0]),
++                                      pld->address_buffer);
++              val2 =  ioread16(pld->base);
++
++              if (likely(val1 == val2))       {
++                      spin_unlock_irqrestore(&pld->pld_lock, flags);
++                      return val1;
++              }
++
++              mif_err("ERR: %s rxq.tail(%d) != in(%d)\n",
++              get_dev_name(id), val1, val2);
++              udelay(100);
++
++      } while (cnt--);
++
++      spin_unlock_irqrestore(&pld->pld_lock, flags);
++      return val1;
++}
++
++static inline void set_rx_head(struct pld_link_device *pld, int id, u32 in)
++{
++      return;
++}
++
++static inline void set_rx_tail(struct pld_link_device *pld, int id, u32 out)
++{
++      int cnt = 3;
++      u32 val = 0;
++      unsigned long int flags;
++
++      spin_lock_irqsave(&pld->pld_lock, flags);
++
++      iowrite16(PLD_ADDR_MASK(&(pld->dev[id]->rxq.tail)[0]),
++                              pld->address_buffer);
++      iowrite16((u16)out, pld->base);
++
++      do {
++              /* Check tail value written */
++              iowrite16(PLD_ADDR_MASK(&(pld->dev[id]->rxq.tail)[0]),
++                                      pld->address_buffer);
++              val =  ioread16(pld->base);
++
++              if (val == out) {
++                      spin_unlock_irqrestore(&pld->pld_lock, flags);
++                      return;
++              }
++
++              mif_err("ERR: %s rxq.tail(%d) != out(%d)\n",
++                      get_dev_name(id), val, out);
++              udelay(100);
++
++              /* Write tail value again */
++              iowrite16(PLD_ADDR_MASK(&(pld->dev[id]->rxq.tail)[0]),
++                                      pld->address_buffer);
++              iowrite16((u16)out, pld->base);
++      } while (cnt--);
++
++      spin_unlock_irqrestore(&pld->pld_lock, flags);
++      return;
++}
++
++static inline u8 *get_rx_buff(struct pld_link_device *pld, int id)
++{
++      return pld->dev[id]->rxq.buff;
++}
++
++static inline u32 get_rx_buff_size(struct pld_link_device *pld, int id)
++{
++      return pld->dev[id]->rxq.size;
++}
++
++static inline u16 get_mask_req_ack(struct pld_link_device *pld, int id)
++{
++      return pld->dev[id]->mask_req_ack;
++}
++
++static inline u16 get_mask_res_ack(struct pld_link_device *pld, int id)
++{
++      return pld->dev[id]->mask_res_ack;
++}
++
++static inline u16 get_mask_send(struct pld_link_device *pld, int id)
++{
++      return pld->dev[id]->mask_send;
++}
++
++/* Get free space in the TXQ as well as in & out pointers */
++static inline int get_txq_space(struct pld_link_device *pld, int dev, u32 qsize,
++              u32 *in, u32 *out)
++{
++      struct link_device *ld = &pld->ld;
++      int cnt = 3;
++      u32 head;
++      u32 tail;
++      int space;
++
++      do {
++              head = get_tx_head(pld, dev);
++              tail = get_tx_tail(pld, dev);
++
++              space = (head < tail) ? (tail - head - 1) :
++                      (qsize + tail - head - 1);
++              mif_debug("%s: %s_TXQ qsize[%u] in[%u] out[%u] space[%u]\n",
++                      ld->name, get_dev_name(dev), qsize, head, tail, space);
++
++              if (circ_valid(qsize, head, tail)) {
++                      *in = head;
++                      *out = tail;
++                      return space;
++              }
++
++              mif_info("%s: CAUTION! <%pf> "
++                      "%s_TXQ invalid (size:%d in:%d out:%d)\n",
++                      ld->name, __builtin_return_address(0),
++                      get_dev_name(dev), qsize, head, tail);
++
++              udelay(100);
++      } while (cnt--);
++
++      *in = 0;
++      *out = 0;
++      return -EINVAL;
++}
++
++static void reset_tx_circ(struct pld_link_device *pld, int dev)
++{
++      set_tx_head(pld, dev, 0);
++      set_tx_tail(pld, dev, 0);
++      if (dev == IPC_FMT)
++              trigger_force_cp_crash(pld);
++}
++
++/* Get data size in the RXQ as well as in & out pointers */
++static inline int get_rxq_rcvd(struct pld_link_device *pld, int dev, u32 qsize,
++              u32 *in, u32 *out)
++{
++      struct link_device *ld = &pld->ld;
++      int cnt = 3;
++      u32 head;
++      u32 tail;
++      u32 rcvd;
++
++      do {
++              head = get_rx_head(pld, dev);
++              tail = get_rx_tail(pld, dev);
++              if (head == tail) {
++                      *in = head;
++                      *out = tail;
++                      return 0;
++              }
++
++              rcvd = (head > tail) ? (head - tail) : (qsize - tail + head);
++              mif_info("%s: %s_RXQ qsize[%u] in[%u] out[%u] rcvd[%u]\n",
++                      ld->name, get_dev_name(dev), qsize, head, tail, rcvd);
++
++              if (circ_valid(qsize, head, tail)) {
++                      *in = head;
++                      *out = tail;
++                      return rcvd;
++              }
++
++              mif_info("%s: CAUTION! <%pf> "
++                      "%s_RXQ invalid (size:%d in:%d out:%d)\n",
++                      ld->name, __builtin_return_address(0),
++                      get_dev_name(dev), qsize, head, tail);
++
++              udelay(100);
++      } while (cnt--);
++
++      *in = 0;
++      *out = 0;
++      return -EINVAL;
++}
++
++static void reset_rx_circ(struct pld_link_device *pld, int dev)
++{
++      set_rx_head(pld, dev, 0);
++      set_rx_tail(pld, dev, 0);
++      if (dev == IPC_FMT)
++              trigger_force_cp_crash(pld);
++}
++
++static int check_access(struct pld_link_device *pld)
++{
++      struct link_device *ld = &pld->ld;
++      int i;
++      u16 magic = get_magic(pld);
++      u16 access = get_access(pld);
++
++      if (likely(magic == DPRAM_MAGIC_CODE && access == 1))
++              return 0;
++
++      for (i = 1; i <= 100; i++) {
++              mif_info("%s: ERR! magic:%X access:%X -> retry:%d\n",
++                      ld->name, magic, access, i);
++              udelay(100);
++
++              magic = get_magic(pld);
++              access = get_access(pld);
++              if (likely(magic == DPRAM_MAGIC_CODE && access == 1))
++                      return 0;
++      }
++
++      mif_info("%s: !CRISIS! magic:%X access:%X\n", ld->name, magic, access);
++      return -EACCES;
++}
++
++static bool ipc_active(struct pld_link_device *pld)
++{
++      struct link_device *ld = &pld->ld;
++
++      /* Check DPRAM mode */
++      if (ld->mode != LINK_MODE_IPC) {
++              mif_info("%s: <%pf> ld->mode != LINK_MODE_IPC\n",
++                      ld->name, __builtin_return_address(0));
++              return false;
++      }
++
++      if (check_access(pld) < 0) {
++              mif_info("%s: ERR! <%pf> check_access fail\n",
++                      ld->name, __builtin_return_address(0));
++              return false;
++      }
++
++      return true;
++}
++
++static void pld_ipc_write(struct pld_link_device *pld, int dev,
++              u32 qsize, u32 in, u32 out, struct sk_buff *skb)
++{
++      struct link_device *ld = &pld->ld;
++      u8 __iomem *buff = get_tx_buff(pld, dev);
++      u8 *src = skb->data;
++      u32 len = skb->len;
++      u32 inp;
++      struct mif_irq_map map;
++
++      if (in < out) {
++              /* +++++++++ in ---------- out ++++++++++ */
++              iowrite16(PLD_ADDR_MASK(&(buff+in)[0]), pld->address_buffer);
++              memcpy(pld->base, src, len);
++      } else {
++              /* ------ out +++++++++++ in ------------ */
++              u32 space = qsize - in;
++
++              /* 1) in -> buffer end */
++              iowrite16(PLD_ADDR_MASK(&(buff+in)[0]), pld->address_buffer);
++              memcpy(pld->base, src, ((len > space) ? space : len));
++
++              if (len > space)        {
++                      iowrite16(PLD_ADDR_MASK(&buff[0]),
++                                              pld->address_buffer);
++                      memcpy(pld->base, (src+space), (len-space));
++              }
++      }
++
++      /* update new in pointer */
++      inp = in + len;
++      if (inp >= qsize)
++              inp -= qsize;
++      set_tx_head(pld, dev, inp);
++
++      if (dev == IPC_FMT) {
++              set_dpram_map(pld, &map);
++              mif_irq_log(ld->mc->msd, map, "ipc_write", sizeof("ipc_write"));
++              mif_ipc_log(MIF_IPC_AP2CP, ld->mc->msd, skb->data, skb->len);
++      }
++}
++
++static int pld_try_ipc_tx(struct pld_link_device *pld, int dev)
++{
++      struct link_device *ld = &pld->ld;
++      struct sk_buff_head *txq = ld->skb_txq[dev];
++      struct sk_buff *skb;
++      unsigned long int flags;
++      u32 qsize = get_tx_buff_size(pld, dev);
++      u32 in;
++      u32 out;
++      int space;
++      int copied = 0;
++
++      spin_lock_irqsave(&pld->tx_rx_lock, flags);
++
++      while (1) {
++              space = get_txq_space(pld, dev, qsize, &in, &out);
++              if (unlikely(space < 0)) {
++                      spin_unlock_irqrestore(&pld->tx_rx_lock, flags);
++                      reset_tx_circ(pld, dev);
++                      return space;
++              }
++
++              skb = skb_dequeue(txq);
++              if (unlikely(!skb))
++                      break;
++
++              if (unlikely(space < skb->len)) {
++                      atomic_set(&pld->res_required[dev], 1);
++                      skb_queue_head(txq, skb);
++                      spin_unlock_irqrestore(&pld->tx_rx_lock, flags);
++                      mif_info("%s: %s "
++                              "qsize[%u] in[%u] out[%u] free[%u] < len[%u]\n",
++                              ld->name, get_dev_name(dev),
++                              qsize, in, out, space, skb->len);
++                      return -ENOSPC;
++              }
++
++              /* TX if there is enough room in the queue */
++              pld_ipc_write(pld, dev, qsize, in, out, skb);
++              copied += skb->len;
++              dev_kfree_skb_any(skb);
++      }
++
++      spin_unlock_irqrestore(&pld->tx_rx_lock, flags);
++
++      return copied;
++}
++
++static void pld_ipc_rx_task(unsigned long data)
++{
++      struct pld_link_device *pld = (struct pld_link_device *)data;
++      struct link_device *ld = &pld->ld;
++      struct io_device *iod;
++      struct mif_rxb *rxb;
++      unsigned qlen;
++      int i;
++
++      for (i = 0; i < ld->max_ipc_dev; i++) {
++              iod = pld->iod[i];
++              qlen = rxbq_size(&pld->rxbq[i]);
++              while (qlen > 0) {
++                      rxb = rxbq_get_data_rxb(&pld->rxbq[i]);
++                      iod->recv(iod, ld, rxb->data, rxb->len);
++                      rxb_clear(rxb);
++                      qlen--;
++              }
++      }
++}
++
++static void pld_ipc_read(struct pld_link_device *pld, int dev, u8 *dst,
++      u8 __iomem *src, u32 out, u32 len, u32 qsize)
++{
++      u8 *ori_det = dst;
++
++      if ((out + len) <= qsize) {
++              /* ----- (out)         (in) ----- */
++              /* -----   7f 00 00 7e      ----- */
++              iowrite16(PLD_ADDR_MASK(&(src+out)[0]), pld->address_buffer);
++              memcpy(dst, pld->base, len);
++      } else {
++              /*       (in) ----------- (out)   */
++              /* 00 7e      -----------   7f 00 */
++              unsigned len1 = qsize - out;
++
++              /* 1) out -> buffer end */
++              iowrite16(PLD_ADDR_MASK(&(src+out)[0]), pld->address_buffer);
++              memcpy(dst, pld->base, len1);
++
++              /* 2) buffer start -> in */
++              dst += len1;
++              iowrite16(PLD_ADDR_MASK(&src[0]), pld->address_buffer);
++              memcpy(dst, pld->base, (len - len1));
++      }
++
++      if (pld->ld.mode == LINK_MODE_IPC && ori_det[0] != 0x7F)        {
++              mif_info("ipc read error!! in[%d], out[%d]\n",
++                                      get_rx_head(pld, dev),
++                                      get_rx_tail(pld, dev));
++      }
++
++}
++
++/*
++  ret < 0  : error
++  ret == 0 : no data
++  ret > 0  : valid data
++*/
++static int pld_ipc_recv_data_with_rxb(struct pld_link_device *pld, int dev)
++{
++      struct link_device *ld = &pld->ld;
++      struct mif_rxb *rxb;
++      u8 __iomem *src = get_rx_buff(pld, dev);
++      u32 qsize = get_rx_buff_size(pld, dev);
++      u32 in;
++      u32 out;
++      u32 rcvd;
++      struct mif_irq_map map;
++      unsigned long int flags;
++
++      spin_lock_irqsave(&pld->tx_rx_lock, flags);
++
++      rcvd = get_rxq_rcvd(pld, dev, qsize, &in, &out);
++      if (rcvd <= 0)  {
++              spin_unlock_irqrestore(&pld->tx_rx_lock, flags);
++              return rcvd;
++      }
++
++      if (dev == IPC_FMT) {
++              set_dpram_map(pld, &map);
++              mif_irq_log(ld->mc->msd, map, "ipc_recv", sizeof("ipc_recv"));
++      }
++
++      /* Allocate an rxb */
++      rxb = rxbq_get_free_rxb(&pld->rxbq[dev]);
++      if (!rxb) {
++              mif_info("%s: ERR! %s rxbq_get_free_rxb fail\n",
++                      ld->name, get_dev_name(dev));
++              spin_unlock_irqrestore(&pld->tx_rx_lock, flags);
++              return -ENOMEM;
++      }
++
++      /* Read data from each DPRAM buffer */
++      pld_ipc_read(pld, dev, rxb_put(rxb, rcvd), src, out, rcvd, qsize);
++
++      /* Calculate and set new out */
++      out += rcvd;
++      if (out >= qsize)
++              out -= qsize;
++      set_rx_tail(pld, dev, out);
++
++      spin_unlock_irqrestore(&pld->tx_rx_lock, flags);
++      return rcvd;
++}
++
++static void non_command_handler(struct pld_link_device *pld, u16 non_cmd)
++{
++      struct link_device *ld = &pld->ld;
++      int i = 0;
++      int ret = 0;
++      u16 mask = 0;
++
++      if (!ipc_active(pld))
++              return;
++
++      /* Read data from DPRAM */
++      for (i = 0; i < ld->max_ipc_dev; i++) {
++              ret = pld_ipc_recv_data_with_rxb(pld, i);
++              if (ret < 0)
++                      reset_rx_circ(pld, i);
++
++              /* Check and process REQ_ACK (at this time, in == out) */
++              if (non_cmd & get_mask_req_ack(pld, i)) {
++                      mif_debug("%s: send %s_RES_ACK\n",
++                              ld->name, get_dev_name(i));
++                      mask |= get_mask_res_ack(pld, i);
++              }
++      }
++
++      /* Schedule soft IRQ for RX */
++      tasklet_hi_schedule(&pld->rx_tsk);
++
++      /* Try TX via DPRAM */
++      for (i = 0; i < ld->max_ipc_dev; i++) {
++              if (atomic_read(&pld->res_required[i]) > 0) {
++                      ret = pld_try_ipc_tx(pld, i);
++                      if (ret > 0) {
++                              atomic_set(&pld->res_required[i], 0);
++                              mask |= get_mask_send(pld, i);
++                      } else if (ret == -ENOSPC) {
++                              mask |= get_mask_req_ack(pld, i);
++                      }
++              }
++      }
++
++      if (mask) {
++              send_intr(pld, INT_NON_CMD(mask));
++              mif_debug("%s: send intr 0x%04X\n", ld->name, mask);
++      }
++}
++
++static void handle_cp_crash(struct pld_link_device *pld)
++{
++      struct link_device *ld = &pld->ld;
++      struct io_device *iod;
++      int i;
++
++      for (i = 0; i < ld->max_ipc_dev; i++) {
++              mif_info("%s: purging %s_skb_txq\b", ld->name, get_dev_name(i));
++              skb_queue_purge(ld->skb_txq[i]);
++      }
++
++      iod = link_get_iod_with_format(ld, IPC_FMT);
++      iod->modem_state_changed(iod, STATE_CRASH_EXIT);
++
++      iod = link_get_iod_with_format(ld, IPC_BOOT);
++      iod->modem_state_changed(iod, STATE_CRASH_EXIT);
++
++      iod = link_get_iod_with_channel(ld, RMNET0_CH_ID);
++      if (iod)
++              iodevs_for_each(iod->msd, iodev_netif_stop, 0);
++}
++
++static void handle_no_crash_ack(unsigned long arg)
++{
++      struct pld_link_device *pld = (struct pld_link_device *)arg;
++      struct link_device *ld = &pld->ld;
++
++      mif_err("%s: ERR! No CRASH_EXIT ACK from CP\n", ld->mc->name);
++
++      if (!wake_lock_active(&pld->wlock))
++              wake_lock(&pld->wlock);
++
++      handle_cp_crash(pld);
++}
++
++static int trigger_force_cp_crash(struct pld_link_device *pld)
++{
++      struct link_device *ld = &pld->ld;
++
++      if (ld->mode == LINK_MODE_ULOAD) {
++              mif_err("%s: CP crash is already in progress\n", ld->mc->name);
++              return 0;
++      }
++
++      ld->mode = LINK_MODE_ULOAD;
++      mif_err("%s: called by %pf\n", ld->name, __builtin_return_address(0));
++
++      send_intr(pld, INT_CMD(INT_CMD_CRASH_EXIT));
++
++      mif_add_timer(&pld->crash_ack_timer, FORCE_CRASH_ACK_TIMEOUT,
++                      handle_no_crash_ack, (unsigned long)pld);
++
++      return 0;
++}
++
++static int pld_init_ipc(struct pld_link_device *pld)
++{
++      struct link_device *ld = &pld->ld;
++      int i;
++
++      if (ld->mode == LINK_MODE_IPC &&
++          get_magic(pld) == DPRAM_MAGIC_CODE &&
++          get_access(pld) == 1)
++              mif_info("%s: IPC already initialized\n", ld->name);
++
++      /* Clear pointers in every circular queue */
++      for (i = 0; i < ld->max_ipc_dev; i++) {
++              set_tx_head(pld, i, 0);
++              set_tx_tail(pld, i, 0);
++              set_rx_head(pld, i, 0);
++              set_rx_tail(pld, i, 0);
++      }
++
++      /* Initialize variables for efficient TX/RX processing */
++      for (i = 0; i < ld->max_ipc_dev; i++)
++              pld->iod[i] = link_get_iod_with_format(ld, i);
++      pld->iod[IPC_RAW] = link_get_iod_with_format(ld, IPC_MULTI_RAW);
++
++      for (i = 0; i < ld->max_ipc_dev; i++)
++              atomic_set(&pld->res_required[i], 0);
++
++      spin_lock_init(&pld->tx_rx_lock);
++
++      /* Enable IPC */
++      atomic_set(&pld->accessing, 0);
++
++      set_magic(pld, DPRAM_MAGIC_CODE);
++      set_access(pld, 1);
++      if (get_magic(pld) != DPRAM_MAGIC_CODE || get_access(pld) != 1)
++              return -EACCES;
++
++      ld->mode = LINK_MODE_IPC;
++
++      if (wake_lock_active(&pld->wlock))
++              wake_unlock(&pld->wlock);
++
++      return 0;
++}
++
++static void cmd_req_active_handler(struct pld_link_device *pld)
++{
++      send_intr(pld, INT_CMD(INT_CMD_RES_ACTIVE));
++}
++
++static void cmd_crash_reset_handler(struct pld_link_device *pld)
++{
++      struct link_device *ld = &pld->ld;
++      struct io_device *iod = NULL;
++
++      ld->mode = LINK_MODE_ULOAD;
++
++      if (!wake_lock_active(&pld->wlock))
++              wake_lock(&pld->wlock);
++
++      mif_err("%s: Recv 0xC7 (CRASH_RESET)\n", ld->name);
++
++      iod = link_get_iod_with_format(ld, IPC_FMT);
++      iod->modem_state_changed(iod, STATE_CRASH_RESET);
++
++      iod = link_get_iod_with_format(ld, IPC_BOOT);
++      iod->modem_state_changed(iod, STATE_CRASH_RESET);
++}
++
++static void cmd_crash_exit_handler(struct pld_link_device *pld)
++{
++      struct link_device *ld = &pld->ld;
++
++      ld->mode = LINK_MODE_ULOAD;
++
++      if (!wake_lock_active(&pld->wlock))
++              wake_lock(&pld->wlock);
++
++      mif_err("%s: Recv 0xC9 (CRASH_EXIT)\n", ld->name);
++
++      del_timer(&pld->crash_ack_timer);
++
++      if (pld->ext_op && pld->ext_op->crash_log)
++              pld->ext_op->crash_log(pld);
++
++      handle_cp_crash(pld);
++}
++
++static void cmd_phone_start_handler(struct pld_link_device *pld)
++{
++      struct link_device *ld = &pld->ld;
++      struct io_device *iod = NULL;
++
++      mif_info("%s: Recv 0xC8 (CP_START)\n", ld->name);
++
++      pld_init_ipc(pld);
++
++      iod = link_get_iod_with_format(ld, IPC_FMT);
++      if (!iod) {
++              mif_info("%s: ERR! no iod\n", ld->name);
++              return;
++      }
++
++      if (pld->ext_op && pld->ext_op->cp_start_handler)
++              pld->ext_op->cp_start_handler(pld);
++
++      if (ld->mc->phone_state != STATE_ONLINE) {
++              mif_info("%s: phone_state: %d -> ONLINE\n",
++                      ld->name, ld->mc->phone_state);
++              iod->modem_state_changed(iod, STATE_ONLINE);
++      }
++
++      mif_info("%s: Send 0xC2 (INIT_END)\n", ld->name);
++      send_intr(pld, INT_CMD(INT_CMD_INIT_END));
++}
++
++static void command_handler(struct pld_link_device *pld, u16 cmd)
++{
++      struct link_device *ld = &pld->ld;
++
++      switch (INT_CMD_MASK(cmd)) {
++      case INT_CMD_REQ_ACTIVE:
++              cmd_req_active_handler(pld);
++              break;
++
++      case INT_CMD_CRASH_RESET:
++              pld->init_status = DPRAM_INIT_STATE_NONE;
++              cmd_crash_reset_handler(pld);
++              break;
++
++      case INT_CMD_CRASH_EXIT:
++              pld->init_status = DPRAM_INIT_STATE_NONE;
++              cmd_crash_exit_handler(pld);
++              break;
++
++      case INT_CMD_PHONE_START:
++              pld->init_status = DPRAM_INIT_STATE_READY;
++              cmd_phone_start_handler(pld);
++              complete_all(&pld->dpram_init_cmd);
++              break;
++
++      case INT_CMD_NV_REBUILDING:
++              mif_info("%s: NV_REBUILDING\n", ld->name);
++              break;
++
++      case INT_CMD_PIF_INIT_DONE:
++              complete_all(&pld->modem_pif_init_done);
++              break;
++
++      case INT_CMD_SILENT_NV_REBUILDING:
++              mif_info("%s: SILENT_NV_REBUILDING\n", ld->name);
++              break;
++
++      case INT_CMD_NORMAL_PWR_OFF:
++              /*ToDo:*/
++              /*kernel_sec_set_cp_ack()*/;
++              break;
++
++      case INT_CMD_REQ_TIME_SYNC:
++      case INT_CMD_CP_DEEP_SLEEP:
++      case INT_CMD_EMER_DOWN:
++              break;
++
++      default:
++              mif_info("%s: unknown command 0x%04X\n", ld->name, cmd);
++      }
++}
++
++static irqreturn_t pld_irq_handler(int irq, void *data)
++{
++      struct pld_link_device *pld = (struct pld_link_device *)data;
++      struct link_device *ld = (struct link_device *)&pld->ld;
++      u16 int2ap = 0;
++
++      if (unlikely(ld->mode == LINK_MODE_OFFLINE))
++              return IRQ_HANDLED;
++
++      int2ap = recv_intr(pld);
++
++      if (unlikely(int2ap == INT_POWERSAFE_FAIL)) {
++              mif_info("%s: int2ap == INT_POWERSAFE_FAIL\n", ld->name);
++              goto exit;
++      } else if (int2ap == 0x1234 || int2ap == 0xDBAB || int2ap == 0xABCD) {
++              if (pld->ext_op && pld->ext_op->dload_cmd_handler) {
++                      pld->ext_op->dload_cmd_handler(pld, int2ap);
++                      goto exit;
++              }
++      }
++
++      if (likely(INT_VALID(int2ap))) {
++              if (unlikely(INT_CMD_VALID(int2ap)))
++                      command_handler(pld, int2ap);
++              else
++                      non_command_handler(pld, int2ap);
++      } else {
++              mif_info("%s: ERR! invalid intr 0x%04X\n",
++                      ld->name, int2ap);
++      }
++
++exit:
++      clear_intr(pld);
++      return IRQ_HANDLED;
++}
++
++static void pld_send_ipc(struct link_device *ld, int dev,
++                      struct io_device *iod, struct sk_buff *skb)
++{
++      struct pld_link_device *pld = to_pld_link_device(ld);
++      struct sk_buff_head *txq = ld->skb_txq[dev];
++      int ret;
++      u16 mask;
++
++      skb_queue_tail(txq, skb);
++      if (txq->qlen > 1024) {
++              mif_debug("%s: %s txq->qlen %d > 1024\n",
++                      ld->name, get_dev_name(dev), txq->qlen);
++      }
++
++      if (!ipc_active(pld))
++              goto exit;
++
++      if (atomic_read(&pld->res_required[dev]) > 0) {
++              mif_debug("%s: %s_TXQ is full\n", ld->name, get_dev_name(dev));
++              goto exit;
++      }
++
++      ret = pld_try_ipc_tx(pld, dev);
++      if (ret > 0) {
++              mask = get_mask_send(pld, dev);
++              send_intr(pld, INT_NON_CMD(mask));
++      } else if (ret == -ENOSPC) {
++              mask = get_mask_req_ack(pld, dev);
++              send_intr(pld, INT_NON_CMD(mask));
++              mif_info("%s: Send REQ_ACK 0x%04X\n", ld->name, mask);
++      } else {
++              mif_info("%s: pld_try_ipc_tx fail (err %d)\n", ld->name, ret);
++      }
++
++exit:
++      return;
++}
++
++static int pld_send(struct link_device *ld, struct io_device *iod,
++              struct sk_buff *skb)
++{
++      enum dev_format dev = iod->format;
++      int len = skb->len;
++
++      switch (dev) {
++      case IPC_FMT:
++      case IPC_RAW:
++      case IPC_RFS:
++              if (likely(ld->mode == LINK_MODE_IPC)) {
++                      pld_send_ipc(ld, dev, iod, skb);
++              } else {
++                      mif_info("%s: ld->mode != LINK_MODE_IPC\n", ld->name);
++                      dev_kfree_skb_any(skb);
++              }
++              return len;
++
++      default:
++              mif_info("%s: ERR! no TXQ for %s\n", ld->name, iod->name);
++              dev_kfree_skb_any(skb);
++              return -ENODEV;
++      }
++}
++
++static int pld_force_dump(struct link_device *ld, struct io_device *iod)
++{
++      struct pld_link_device *pld = to_pld_link_device(ld);
++      trigger_force_cp_crash(pld);
++      return 0;
++}
++
++static int pld_dump_start(struct link_device *ld, struct io_device *iod)
++{
++      struct pld_link_device *pld = to_pld_link_device(ld);
++
++      if (pld->ext_op && pld->ext_op->dump_start)
++              return pld->ext_op->dump_start(pld);
++      else
++              return -ENODEV;
++}
++
++static int pld_dump_update(struct link_device *ld, struct io_device *iod,
++              unsigned long arg)
++{
++      struct pld_link_device *pld = to_pld_link_device(ld);
++
++      if (pld->ext_op && pld->ext_op->dump_update)
++              return pld->ext_op->dump_update(pld, (void *)arg);
++      else
++              return -ENODEV;
++}
++
++static int pld_ioctl(struct link_device *ld, struct io_device *iod,
++              unsigned int cmd, unsigned long arg)
++{
++      struct pld_link_device *pld = to_pld_link_device(ld);
++      int err = 0;
++
++/*
++      mif_info("%s: cmd 0x%08X\n", ld->name, cmd);
++*/
++
++      switch (cmd) {
++      case IOCTL_DPRAM_INIT_STATUS:
++              mif_debug("%s: get dpram init status\n", ld->name);
++              return pld->init_status;
++
++      default:
++              if (pld->ext_ioctl) {
++                      err = pld->ext_ioctl(pld, iod, cmd, arg);
++              } else {
++                      mif_err("%s: ERR! invalid cmd 0x%08X\n", ld->name, cmd);
++                      err = -EINVAL;
++              }
++
++              break;
++      }
++
++      return err;
++}
++
++static int pld_table_init(struct pld_link_device *pld)
++{
++      struct link_device *ld = &pld->ld;
++      u8 __iomem *dp_base;
++      int i;
++
++      if (!pld->base) {
++              mif_info("%s: ERR! pld->base == NULL\n", ld->name);
++              return -EINVAL;
++      }
++      dp_base = pld->base;
++
++      /* Map for IPC */
++      if (pld->dpctl->ipc_map) {
++              memcpy(&pld->ipc_map, pld->dpctl->ipc_map,
++                      sizeof(struct dpram_ipc_map));
++      }
++
++      pld->magic_ap2cp = pld->ipc_map.magic_ap2cp;
++      pld->access_ap2cp = pld->ipc_map.access_ap2cp;
++
++      pld->magic_cp2ap = pld->ipc_map.magic_cp2ap;
++      pld->access_cp2ap = pld->ipc_map.access_cp2ap;
++
++      pld->address_buffer = pld->ipc_map.address_buffer;
++
++      for (i = 0; i < ld->max_ipc_dev; i++)
++              pld->dev[i] = &pld->ipc_map.dev[i];
++      pld->mbx2ap = pld->ipc_map.mbx_cp2ap;
++      pld->mbx2cp = pld->ipc_map.mbx_ap2cp;
++
++      /* Map for booting */
++      if (pld->ext_op && pld->ext_op->init_boot_map) {
++              pld->ext_op->init_boot_map(pld);
++      } else {
++              pld->bt_map.magic = (u32 *)(dp_base);
++              pld->bt_map.buff = (u8 *)(dp_base + DP_BOOT_BUFF_OFFSET);
++              pld->bt_map.size = pld->size - 8;
++      }
++
++      /* Map for download (FOTA, UDL, etc.) */
++      if (pld->ext_op && pld->ext_op->init_dl_map) {
++              pld->ext_op->init_dl_map(pld);
++      } else {
++              pld->dl_map.magic = (u32 *)(dp_base);
++              pld->dl_map.buff = (u8 *)(dp_base + DP_DLOAD_BUFF_OFFSET);
++      }
++
++      /* Map for upload mode */
++      if (pld->ext_op && pld->ext_op->init_ul_map) {
++              pld->ext_op->init_ul_map(pld);
++      } else {
++              pld->ul_map.magic = (u32 *)(dp_base);
++              pld->ul_map.buff = (u8 *)(dp_base + DP_ULOAD_BUFF_OFFSET);
++      }
++
++      return 0;
++}
++
++static void pld_setup_common_op(struct pld_link_device *pld)
++{
++      pld->clear_intr = clear_intr;
++      pld->recv_intr = recv_intr;
++      pld->send_intr = send_intr;
++      pld->get_magic = get_magic;
++      pld->set_magic = set_magic;
++      pld->get_access = get_access;
++      pld->set_access = set_access;
++      pld->get_tx_head = get_tx_head;
++      pld->get_tx_tail = get_tx_tail;
++      pld->set_tx_head = set_tx_head;
++      pld->set_tx_tail = set_tx_tail;
++      pld->get_tx_buff = get_tx_buff;
++      pld->get_tx_buff_size = get_tx_buff_size;
++      pld->get_rx_head = get_rx_head;
++      pld->get_rx_tail = get_rx_tail;
++      pld->set_rx_head = set_rx_head;
++      pld->set_rx_tail = set_rx_tail;
++      pld->get_rx_buff = get_rx_buff;
++      pld->get_rx_buff_size = get_rx_buff_size;
++      pld->get_mask_req_ack = get_mask_req_ack;
++      pld->get_mask_res_ack = get_mask_res_ack;
++      pld->get_mask_send = get_mask_send;
++}
++
++static int pld_link_init(struct link_device *ld, struct io_device *iod)
++{
++      return 0;
++}
++
++static void pld_link_terminate(struct link_device *ld, struct io_device *iod)
++{
++      return;
++}
++
++struct link_device *pld_create_link_device(struct platform_device *pdev)
++{
++      struct modem_data *mdm_data = NULL;
++      struct pld_link_device *pld = NULL;
++      struct link_device *ld = NULL;
++      struct resource *res = NULL;
++      resource_size_t res_size;
++      struct modemlink_dpram_control *dpctl = NULL;
++      unsigned long task_data;
++      int ret = 0;
++      int i = 0;
++      int bsize;
++      int qsize;
++
++      /* Get the platform data */
++      mdm_data = (struct modem_data *)pdev->dev.platform_data;
++      if (!mdm_data) {
++              mif_info("ERR! mdm_data == NULL\n");
++              goto err;
++      }
++      mif_info("modem = %s\n", mdm_data->name);
++      mif_info("link device = %s\n", mdm_data->link_name);
++
++      if (!mdm_data->dpram_ctl) {
++              mif_info("ERR! mdm_data->dpram_ctl == NULL\n");
++              goto err;
++      }
++      dpctl = mdm_data->dpram_ctl;
++
++      /* Alloc DPRAM link device structure */
++      pld = kzalloc(sizeof(struct pld_link_device), GFP_KERNEL);
++      if (!pld) {
++              mif_info("ERR! kzalloc pld fail\n");
++              goto err;
++      }
++      ld = &pld->ld;
++
++      /* Retrieve modem data and DPRAM control data from the modem data */
++      ld->mdm_data = mdm_data;
++      ld->name = mdm_data->link_name;
++      ld->ipc_version = mdm_data->ipc_version;
++
++      /* Retrieve the most basic data for IPC from the modem data */
++      pld->dpctl = dpctl;
++      pld->type = dpctl->dp_type;
++
++      if (mdm_data->ipc_version < SIPC_VER_50) {
++              if (!dpctl->max_ipc_dev) {
++                      mif_info("ERR! no max_ipc_dev\n");
++                      goto err;
++              }
++
++              ld->aligned = dpctl->aligned;
++              ld->max_ipc_dev = dpctl->max_ipc_dev;
++      } else {
++              ld->aligned = 1;
++              ld->max_ipc_dev = MAX_SIPC5_DEV;
++      }
++
++      /* Set attributes as a link device */
++      ld->init_comm = pld_link_init;
++      ld->terminate_comm = pld_link_terminate;
++      ld->send = pld_send;
++      ld->force_dump = pld_force_dump;
++      ld->dump_start = pld_dump_start;
++      ld->dump_update = pld_dump_update;
++      ld->ioctl = pld_ioctl;
++
++      INIT_LIST_HEAD(&ld->list);
++
++      skb_queue_head_init(&ld->sk_fmt_tx_q);
++      skb_queue_head_init(&ld->sk_raw_tx_q);
++      skb_queue_head_init(&ld->sk_rfs_tx_q);
++      ld->skb_txq[IPC_FMT] = &ld->sk_fmt_tx_q;
++      ld->skb_txq[IPC_RAW] = &ld->sk_raw_tx_q;
++      ld->skb_txq[IPC_RFS] = &ld->sk_rfs_tx_q;
++
++      /* Set up function pointers */
++      pld_setup_common_op(pld);
++      pld->ext_op = pld_get_ext_op(mdm_data->modem_type);
++      if (pld->ext_op && pld->ext_op->ioctl)
++              pld->ext_ioctl = pld->ext_op->ioctl;
++
++      /* Retrieve DPRAM resource */
++      if (!dpctl->dp_base) {
++              res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++              if (!res) {
++                      mif_info("%s: ERR! platform_get_resource fail\n",
++                              ld->name);
++                      goto err;
++              }
++              res_size = resource_size(res);
++
++              dpctl->dp_base = ioremap_nocache(res->start, res_size);
++              dpctl->dp_size = res_size;
++      }
++      pld->base = dpctl->dp_base;
++      pld->size = dpctl->dp_size;
++
++      mif_info("%s: type %d, aligned %d, base 0x%08X, size %d\n",
++              ld->name, pld->type, ld->aligned, (int)pld->base, pld->size);
++
++      /* Initialize DPRAM map (physical map -> logical map) */
++      ret = pld_table_init(pld);
++      if (ret < 0) {
++              mif_info("%s: ERR! pld_table_init fail (err %d)\n",
++                      ld->name, ret);
++              goto err;
++      }
++
++      spin_lock_init(&pld->pld_lock);
++
++      /* Disable IPC */
++      set_magic(pld, 0);
++      set_access(pld, 0);
++
++      pld->init_status = DPRAM_INIT_STATE_NONE;
++
++      /* Initialize locks, completions, and bottom halves */
++      snprintf(pld->wlock_name, MIF_MAX_NAME_LEN, "%s_wlock", ld->name);
++      wake_lock_init(&pld->wlock, WAKE_LOCK_SUSPEND, pld->wlock_name);
++
++      init_completion(&pld->dpram_init_cmd);
++      init_completion(&pld->modem_pif_init_done);
++      init_completion(&pld->udl_start_complete);
++      init_completion(&pld->udl_cmd_complete);
++      init_completion(&pld->crash_start_complete);
++      init_completion(&pld->crash_recv_done);
++
++      task_data = (unsigned long)pld;
++      tasklet_init(&pld->rx_tsk, pld_ipc_rx_task, task_data);
++
++      /* Prepare RXB queue */
++      qsize = DPRAM_MAX_RXBQ_SIZE;
++      for (i = 0; i < ld->max_ipc_dev; i++) {
++              bsize = rxbq_get_page_size(get_rx_buff_size(pld, i));
++              pld->rxbq[i].size = qsize;
++              pld->rxbq[i].in = 0;
++              pld->rxbq[i].out = 0;
++              pld->rxbq[i].rxb = rxbq_create_pool(bsize, qsize);
++              if (!pld->rxbq[i].rxb) {
++                      mif_info("%s: ERR! %s rxbq_create_pool fail\n",
++                              ld->name, get_dev_name(i));
++                      goto err;
++              }
++              mif_info("%s: %s rxbq_pool created (bsize:%d, qsize:%d)\n",
++                      ld->name, get_dev_name(i), bsize, qsize);
++      }
++
++      /* Prepare a multi-purpose miscellaneous buffer */
++      pld->buff = kzalloc(pld->size, GFP_KERNEL);
++      if (!pld->buff) {
++              mif_info("%s: ERR! kzalloc pld->buff fail\n", ld->name);
++              goto err;
++      }
++
++      /* Retrieve DPRAM IRQ GPIO# */
++      pld->gpio_dpram_int = mdm_data->gpio_dpram_int;
++
++      /* Retrieve DPRAM IRQ# */
++      if (!dpctl->dpram_irq) {
++              dpctl->dpram_irq = platform_get_irq_byname(pdev, "dpram_irq");
++              if (dpctl->dpram_irq < 0) {
++                      mif_info("%s: ERR! platform_get_irq_byname fail\n",
++                              ld->name);
++                      goto err;
++              }
++      }
++      pld->irq = dpctl->dpram_irq;
++
++      /* Retrieve DPRAM IRQ flags */
++      if (!dpctl->dpram_irq_flags)
++              dpctl->dpram_irq_flags = (IRQF_NO_SUSPEND | IRQF_TRIGGER_LOW);
++      pld->irq_flags = dpctl->dpram_irq_flags;
++
++      /* Register DPRAM interrupt handler */
++      snprintf(pld->irq_name, MIF_MAX_NAME_LEN, "%s_irq", ld->name);
++      ret = pld_register_isr(pld->irq, pld_irq_handler, pld->irq_flags,
++                              pld->irq_name, pld);
++      if (ret)
++              goto err;
++
++      return ld;
++
++err:
++      if (pld) {
++              kfree(pld->buff);
++              kfree(pld);
++      }
++
++      return NULL;
++}
++
+diff --git a/drivers/misc/modem_if/modem_link_device_pld.h b/drivers/misc/modem_if/modem_link_device_pld.h
+new file mode 100644
+index 0000000..89c44b2
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_link_device_pld.h
+@@ -0,0 +1,231 @@
++/*
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++#ifndef __MODEM_LINK_DEVICE_PLD_H__
++#define __MODEM_LINK_DEVICE_PLD_H__
++
++#include "modem_link_device_memory.h"
++
++#define PLD_ADDR_MASK(x)      (0x00003FFF & (unsigned long)(x))
++
++/*
++      mbx_ap2cp +                     0x0
++      magic_code +
++      access_enable +
++      padding +
++      mbx_cp2ap +                     0x1000
++      magic_code +
++      access_enable +
++      padding +
++      fmt_tx_head + fmt_tx_tail + fmt_tx_buff +               0x2000
++      raw_tx_head + raw_tx_tail + raw_tx_buff +
++      fmt_rx_head + fmt_rx_tail + fmt_rx_buff +               0x3000
++      raw_rx_head + raw_rx_tail + raw_rx_buff +
++  =   2 +
++      4094 +
++      2 +
++      4094 +
++      2 +
++      2 +
++      2 + 2 + 1020 +
++      2 + 2 + 3064 +
++      2 + 2 + 1020 +
++      2 + 2 + 3064
++ */
++
++#define PLD_FMT_TX_BUFF_SZ    1024
++#define PLD_RAW_TX_BUFF_SZ    3072
++#define PLD_FMT_RX_BUFF_SZ    1024
++#define PLD_RAW_RX_BUFF_SZ    3072
++
++#define MAX_MSM_EDPRAM_IPC_DEV        2       /* FMT, RAW */
++
++struct pld_ipc_map {
++      u16 mbx_ap2cp;
++      u16 magic_ap2cp;
++      u16 access_ap2cp;
++      u16 fmt_tx_head;
++      u16 raw_tx_head;
++      u16 fmt_rx_tail;
++      u16 raw_rx_tail;
++      u16 temp1;
++      u8 padding1[4080];
++
++      u16 mbx_cp2ap;
++      u16 magic_cp2ap;
++      u16 access_cp2ap;
++      u16 fmt_tx_tail;
++      u16 raw_tx_tail;
++      u16 fmt_rx_head;
++      u16 raw_rx_head;
++      u16 temp2;
++      u8 padding2[4080];
++
++      u8 fmt_tx_buff[PLD_FMT_TX_BUFF_SZ];
++      u8 raw_tx_buff[PLD_RAW_TX_BUFF_SZ];
++      u8 fmt_rx_buff[PLD_RAW_TX_BUFF_SZ];
++      u8 raw_rx_buff[PLD_RAW_RX_BUFF_SZ];
++
++      u8 padding3[16384];
++
++      u16 address_buffer;
++};
++
++struct pld_ext_op;
++
++struct pld_link_device {
++      struct link_device ld;
++
++      /* DPRAM address and size */
++      enum dpram_type type;   /* DPRAM type                   */
++      u8 __iomem *base;       /* DPRAM base virtual address   */
++      u32 size;               /* DPRAM size                   */
++
++      /* DPRAM IRQ GPIO# */
++      unsigned gpio_dpram_int;
++
++      /* DPRAM IRQ from CP */
++      int irq;
++      unsigned long irq_flags;
++      char irq_name[MIF_MAX_NAME_LEN];
++
++      /* Link to DPRAM control functions dependent on each platform */
++      struct modemlink_dpram_control *dpctl;
++
++      /* Physical configuration -> logical configuration */
++      union {
++              struct dpram_boot_map bt_map;
++              struct qc_dpram_boot_map qc_bt_map;
++      };
++
++      struct dpram_dload_map dl_map;
++      struct dpram_uload_map ul_map;
++
++      /* IPC device map */
++      struct dpram_ipc_map ipc_map;
++
++      /* Pointers (aliases) to IPC device map */
++      u16 __iomem *magic_ap2cp;
++      u16 __iomem *access_ap2cp;
++      u16 __iomem *magic_cp2ap;
++      u16 __iomem *access_cp2ap;
++      u16 __iomem *address_buffer;
++
++      struct dpram_ipc_device *dev[MAX_IPC_DEV];
++      u16 __iomem *mbx2ap;
++      u16 __iomem *mbx2cp;
++
++      /* Wakelock for DPRAM device */
++      struct wake_lock wlock;
++      char wlock_name[MIF_MAX_NAME_LEN];
++
++      /* For booting */
++      unsigned boot_start_complete;
++      struct completion dpram_init_cmd;
++      struct completion modem_pif_init_done;
++
++      /* For UDL */
++      struct tasklet_struct ul_tsk;
++      struct tasklet_struct dl_tsk;
++      struct completion udl_start_complete;
++      struct completion udl_cmd_complete;
++      struct dpram_udl_check udl_check;
++      struct dpram_udl_param udl_param;
++
++      /* For CP crash dump */
++      struct timer_list crash_ack_timer;
++      struct completion crash_start_complete;
++      struct completion crash_recv_done;
++      struct timer_list crash_timer;
++      int crash_rcvd;         /* Count of CP crash dump packets received */
++
++      /* For locking TX process */
++      spinlock_t tx_rx_lock;
++      spinlock_t pld_lock;
++
++      /* For efficient RX process */
++      struct tasklet_struct rx_tsk;
++      struct mif_rxb_queue rxbq[MAX_IPC_DEV];
++      struct io_device *iod[MAX_IPC_DEV];
++
++      /* For retransmission after buffer full state */
++      atomic_t res_required[MAX_IPC_DEV];
++
++      /* For wake-up/sleep control */
++      atomic_t accessing;
++
++      /* Multi-purpose miscellaneous buffer */
++      u8 *buff;
++
++      /* PLD IPC initialization status */
++      int init_status;
++
++      /* Alias to device-specific IOCTL function */
++      int (*ext_ioctl)(struct pld_link_device *pld, struct io_device *iod,
++                      unsigned int cmd, unsigned long arg);
++
++      /* Common operations for each DPRAM */
++      void (*clear_intr)(struct pld_link_device *pld);
++      u16 (*recv_intr)(struct pld_link_device *pld);
++      void (*send_intr)(struct pld_link_device *pld, u16 mask);
++      u16 (*get_magic)(struct pld_link_device *pld);
++      void (*set_magic)(struct pld_link_device *pld, u16 value);
++      u16 (*get_access)(struct pld_link_device *pld);
++      void (*set_access)(struct pld_link_device *pld, u16 value);
++      u32 (*get_tx_head)(struct pld_link_device *pld, int id);
++      u32 (*get_tx_tail)(struct pld_link_device *pld, int id);
++      void (*set_tx_head)(struct pld_link_device *pld, int id, u32 head);
++      void (*set_tx_tail)(struct pld_link_device *pld, int id, u32 tail);
++      u8 *(*get_tx_buff)(struct pld_link_device *pld, int id);
++      u32 (*get_tx_buff_size)(struct pld_link_device *pld, int id);
++      u32 (*get_rx_head)(struct pld_link_device *pld, int id);
++      u32 (*get_rx_tail)(struct pld_link_device *pld, int id);
++      void (*set_rx_head)(struct pld_link_device *pld, int id, u32 head);
++      void (*set_rx_tail)(struct pld_link_device *pld, int id, u32 tail);
++      u8 *(*get_rx_buff)(struct pld_link_device *pld, int id);
++      u32 (*get_rx_buff_size)(struct pld_link_device *pld, int id);
++      u16 (*get_mask_req_ack)(struct pld_link_device *pld, int id);
++      u16 (*get_mask_res_ack)(struct pld_link_device *pld, int id);
++      u16 (*get_mask_send)(struct pld_link_device *pld, int id);
++
++      /* Extended operations for various modems */
++      struct pld_ext_op *ext_op;
++};
++
++/* converts from struct link_device* to struct xxx_link_device* */
++#define to_pld_link_device(linkdev) \
++              container_of(linkdev, struct pld_link_device, ld)
++
++struct pld_ext_op {
++      int exist;
++
++      void (*init_boot_map)(struct pld_link_device *pld);
++      void (*init_dl_map)(struct pld_link_device *pld);
++      void (*init_ul_map)(struct pld_link_device *pld);
++
++      void (*dload_cmd_handler)(struct pld_link_device *pld, u16 cmd);
++
++      void (*cp_start_handler)(struct pld_link_device *pld);
++
++      void (*crash_log)(struct pld_link_device *pld);
++      int (*dump_start)(struct pld_link_device *pld);
++      int (*dump_update)(struct pld_link_device *pld, void *arg);
++
++      int (*ioctl)(struct pld_link_device *pld, struct io_device *iod,
++              unsigned int cmd, unsigned long arg);
++
++      void (*clear_intr)(struct pld_link_device *pld);
++};
++
++struct pld_ext_op *pld_get_ext_op(enum modem_t modem);
++#endif
+diff --git a/drivers/misc/modem_if/modem_link_device_pld_ext_op.c b/drivers/misc/modem_if/modem_link_device_pld_ext_op.c
+new file mode 100644
+index 0000000..4f2df8f
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_link_device_pld_ext_op.c
+@@ -0,0 +1,556 @@
++/*
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <linux/irq.h>
++#include <linux/gpio.h>
++#include <linux/time.h>
++#include <linux/interrupt.h>
++#include <linux/timer.h>
++#include <linux/wakelock.h>
++#include <linux/delay.h>
++#include <linux/wait.h>
++#include <linux/sched.h>
++#include <linux/vmalloc.h>
++#include <linux/if_arp.h>
++#include <linux/platform_device.h>
++#include <linux/kallsyms.h>
++#include <linux/platform_data/modem.h>
++
++#include "modem_prj.h"
++#include "modem_link_device_pld.h"
++#include "modem_utils.h"
++
++#if defined(CONFIG_CDMA_MODEM_MDM6600) || defined(CONFIG_GSM_MODEM_ESC6270)
++enum qc_dload_tag {
++      QC_DLOAD_TAG_NONE = 0,
++      QC_DLOAD_TAG_BIN,
++      QC_DLOAD_TAG_NV,
++      QC_DLOAD_TAG_MAX
++};
++
++static void qc_dload_task(unsigned long data);
++
++static void qc_init_boot_map(struct pld_link_device *pld)
++{
++      struct qc_dpram_boot_map *qbt_map = &pld->qc_bt_map;
++      struct modemlink_dpram_control *dpctl = pld->dpctl;
++
++      qbt_map->buff = pld->dev[0]->txq.buff;
++      qbt_map->frame_size = (u16 *)(pld->base + dpctl->boot_size_offset);
++      qbt_map->tag = (u16 *)(pld->base + dpctl->boot_tag_offset);
++      qbt_map->count = (u16 *)(pld->base + dpctl->boot_count_offset);
++
++      tasklet_init(&pld->dl_tsk, qc_dload_task, (unsigned long)pld);
++}
++
++static void qc_dload_map(struct pld_link_device *pld, u8 is_upload)
++{
++      struct qc_dpram_boot_map *qbt_map = &pld->qc_bt_map;
++      struct modemlink_dpram_control *dpctl = pld->dpctl;
++      unsigned int upload_offset = 0;
++
++      if (is_upload == 1)     {
++              upload_offset = 0x1000;
++              qbt_map->buff = pld->dev[0]->rxq.buff;
++      }       else {
++              upload_offset = 0;
++              qbt_map->buff = pld->dev[0]->txq.buff;
++      }
++
++      qbt_map->frame_size = (u16 *)(pld->base +
++                      dpctl->boot_size_offset + upload_offset);
++      qbt_map->tag = (u16 *)(pld->base +
++                      dpctl->boot_tag_offset + upload_offset);
++      qbt_map->count = (u16 *)(pld->base +
++                      dpctl->boot_count_offset + upload_offset);
++
++}
++
++static int qc_prepare_download(struct pld_link_device *pld)
++{
++      int retval = 0;
++      int count = 0;
++
++      qc_dload_map(pld, 0);
++
++      while (1) {
++              if (pld->udl_check.copy_start) {
++                      pld->udl_check.copy_start = 0;
++                      break;
++              }
++
++              usleep_range(10000, 11000);
++
++              count++;
++              if (count > 1000) {
++                      mif_err("ERR! count %d\n", count);
++                      return -1;
++              }
++      }
++
++      return retval;
++}
++
++static void _qc_do_download(struct pld_link_device *pld,
++                      struct dpram_udl_param *param)
++{
++      struct qc_dpram_boot_map *qbt_map = &pld->qc_bt_map;
++
++      if (param->size <= pld->dpctl->max_boot_frame_size) {
++              iowrite16(PLD_ADDR_MASK(&qbt_map->buff[0]),
++                                      pld->address_buffer);
++              memcpy(pld->base, param->addr, param->size);
++
++              iowrite16(PLD_ADDR_MASK(&qbt_map->frame_size[0]),
++                                      pld->address_buffer);
++              iowrite16(param->size, pld->base);
++
++              iowrite16(PLD_ADDR_MASK(&qbt_map->tag[0]),
++                                      pld->address_buffer);
++              iowrite16(param->tag, pld->base);
++
++              iowrite16(PLD_ADDR_MASK(&qbt_map->count[0]),
++                                      pld->address_buffer);
++              iowrite16(param->count, pld->base);
++
++              pld->send_intr(pld, 0xDB12);
++      } else {
++              mif_info("param->size %d\n", param->size);
++      }
++}
++
++static int _qc_download(struct pld_link_device *pld, void *arg,
++                      enum qc_dload_tag tag)
++{
++      int retval = 0;
++      int count = 0;
++      int cnt_limit;
++      unsigned char *img;
++      struct dpram_udl_param param;
++
++      retval = copy_from_user((void *)&param, (void *)arg, sizeof(param));
++      if (retval < 0) {
++              mif_err("ERR! copy_from_user fail\n");
++              return -1;
++      }
++
++      img = vmalloc(param.size);
++      if (!img) {
++              mif_err("ERR! vmalloc fail\n");
++              return -1;
++      }
++      memset(img, 0, param.size);
++      memcpy(img, param.addr, param.size);
++
++      pld->udl_check.total_size = param.size;
++      pld->udl_check.rest_size = param.size;
++      pld->udl_check.send_size = 0;
++      pld->udl_check.copy_complete = 0;
++
++      pld->udl_param.addr = img;
++      pld->udl_param.size = pld->dpctl->max_boot_frame_size;
++      if (tag == QC_DLOAD_TAG_NV)
++              pld->udl_param.count = 1;
++      else
++              pld->udl_param.count = param.count;
++      pld->udl_param.tag = tag;
++
++      if (pld->udl_check.rest_size < pld->dpctl->max_boot_frame_size)
++              pld->udl_param.size = pld->udl_check.rest_size;
++
++      /* Download image (binary or NV) */
++      _qc_do_download(pld, &pld->udl_param);
++
++      /* Wait for completion
++      */
++      if (tag == QC_DLOAD_TAG_NV)
++              cnt_limit = 200;
++      else
++              cnt_limit = 1000;
++
++      while (1) {
++              if (pld->udl_check.copy_complete) {
++                      pld->udl_check.copy_complete = 0;
++                      retval = 0;
++                      break;
++              }
++
++              usleep_range(10000, 11000);
++
++              count++;
++              if (count > cnt_limit) {
++                      mif_err("ERR! count %d\n", count);
++                      retval = -1;
++                      break;
++              }
++      }
++
++      vfree(img);
++
++      return retval;
++}
++
++static int qc_download_bin(struct pld_link_device *pld, void *arg)
++{
++      return _qc_download(pld, arg, QC_DLOAD_TAG_BIN);
++}
++
++static int qc_download_nv(struct pld_link_device *pld, void *arg)
++{
++      return _qc_download(pld, arg, QC_DLOAD_TAG_NV);
++}
++
++static void qc_dload_task(unsigned long data)
++{
++      struct pld_link_device *pld = (struct pld_link_device *)data;
++
++      pld->udl_check.send_size += pld->udl_param.size;
++      pld->udl_check.rest_size -= pld->udl_param.size;
++
++      pld->udl_param.addr += pld->udl_param.size;
++
++      if (pld->udl_check.send_size >= pld->udl_check.total_size) {
++              pld->udl_check.copy_complete = 1;
++              pld->udl_param.tag = 0;
++              return;
++      }
++
++      if (pld->udl_check.rest_size < pld->dpctl->max_boot_frame_size)
++              pld->udl_param.size = pld->udl_check.rest_size;
++
++      pld->udl_param.count += 1;
++
++      _qc_do_download(pld, &pld->udl_param);
++}
++
++static void qc_dload_cmd_handler(struct pld_link_device *pld, u16 cmd)
++{
++      switch (cmd) {
++      case 0x1234:
++              pld->udl_check.copy_start = 1;
++              break;
++
++      case 0xDBAB:
++              tasklet_schedule(&pld->dl_tsk);
++              break;
++
++      case 0xABCD:
++              mif_info("[%s] booting Start\n", pld->ld.name);
++              pld->udl_check.boot_complete = 1;
++              break;
++
++      default:
++              mif_err("ERR! unknown command 0x%04X\n", cmd);
++      }
++}
++
++static int qc_boot_start(struct pld_link_device *pld)
++{
++      u16 mask = 0;
++      int count = 0;
++
++      /* Send interrupt -> '0x4567' */
++      mask = 0x4567;
++      pld->send_intr(pld, mask);
++
++      while (1) {
++              if (pld->udl_check.boot_complete) {
++                      pld->udl_check.boot_complete = 0;
++                      break;
++              }
++
++              usleep_range(10000, 11000);
++
++              count++;
++              if (count > 200) {
++                      mif_err("ERR! count %d\n", count);
++                      return -1;
++              }
++      }
++
++      return 0;
++}
++
++static int qc_boot_post_process(struct pld_link_device *pld)
++{
++      int count = 0;
++
++      while (1) {
++              if (pld->boot_start_complete) {
++                      pld->boot_start_complete = 0;
++                      break;
++              }
++
++              usleep_range(10000, 11000);
++
++              count++;
++              if (count > 200) {
++                      mif_err("ERR! count %d\n", count);
++                      return -1;
++              }
++      }
++
++      return 0;
++}
++
++static void qc_start_handler(struct pld_link_device *pld)
++{
++      /*
++       * INT_MASK_VALID | INT_MASK_CMD | INT_MASK_CP_AIRPLANE_BOOT |
++       * INT_MASK_CP_AP_ANDROID | INT_MASK_CMD_INIT_END
++       */
++      u16 mask = (0x0080 | 0x0040 | 0x1000 | 0x0100 | 0x0002);
++
++      pld->boot_start_complete = 1;
++
++      /* Send INIT_END code to CP */
++      mif_info("send 0x%04X (INIT_END)\n", mask);
++
++      pld->send_intr(pld, mask);
++}
++
++static void qc_crash_log(struct pld_link_device *pld)
++{
++      struct link_device *ld = &pld->ld;
++      static unsigned char buf[151];
++      u8 __iomem *data = NULL;
++
++      data = pld->get_rx_buff(pld, IPC_FMT);
++      memcpy(buf, data, (sizeof(buf) - 1));
++
++      mif_info("PHONE ERR MSG\t| %s Crash\n", ld->mdm_data->name);
++      mif_info("PHONE ERR MSG\t| %s\n", buf);
++}
++
++static int _qc_data_upload(struct pld_link_device *pld,
++                      struct dpram_udl_param *param)
++{
++      struct qc_dpram_boot_map *qbt_map = &pld->qc_bt_map;
++      int retval = 0;
++      u16 intval = 0;
++      int count = 0;
++
++      while (1) {
++              if (!gpio_get_value(pld->gpio_dpram_int)) {
++                      intval = pld->recv_intr(pld);
++                      if (intval == 0xDBAB) {
++                              break;
++                      } else {
++                              mif_err("intr 0x%08x\n", intval);
++                              return -1;
++                      }
++              }
++
++              usleep_range(1000, 2000);
++
++              count++;
++              if (count > 200) {
++                      mif_err("<%s:%d>\n", __func__, __LINE__);
++                      return -1;
++              }
++      }
++
++      iowrite16(PLD_ADDR_MASK(&qbt_map->frame_size[0]),
++                              pld->address_buffer);
++      param->size = ioread16(pld->base);
++
++      iowrite16(PLD_ADDR_MASK(&qbt_map->tag[0]),
++                              pld->address_buffer);
++      param->tag = ioread16(pld->base);
++
++      iowrite16(PLD_ADDR_MASK(&qbt_map->count[0]),
++                              pld->address_buffer);
++      param->count = ioread16(pld->base);
++
++      iowrite16(PLD_ADDR_MASK(&qbt_map->buff[0]),
++                              pld->address_buffer);
++      memcpy(param->addr, pld->base, param->size);
++
++      pld->send_intr(pld, 0xDB12);
++
++      return retval;
++}
++
++static int qc_uload_step1(struct pld_link_device *pld)
++{
++      int retval = 0;
++      int count = 0;
++      u16 intval = 0;
++      u16 mask = 0;
++
++      qc_dload_map(pld, 1);
++
++      mif_info("+---------------------------------------------+\n");
++      mif_info("|            UPLOAD PHONE SDRAM               |\n");
++      mif_info("+---------------------------------------------+\n");
++
++      while (1) {
++              if (!gpio_get_value(pld->gpio_dpram_int)) {
++                      intval = pld->recv_intr(pld);
++                      mif_info("intr 0x%04x\n", intval);
++                      if (intval == 0x1234) {
++                              break;
++                      } else {
++                              mif_info("ERR! invalid intr\n");
++                              return -1;
++                      }
++              }
++
++              usleep_range(1000, 2000);
++
++              count++;
++              if (count > 200) {
++                      intval = pld->recv_intr(pld);
++                      mif_info("count %d, intr 0x%04x\n", count, intval);
++                      if (intval == 0x1234)
++                              break;
++                      return -1;
++              }
++      }
++
++      mask = 0xDEAD;
++      pld->send_intr(pld, mask);
++
++      return retval;
++}
++
++static int qc_uload_step2(struct pld_link_device *pld, void *arg)
++{
++      int retval = 0;
++      struct dpram_udl_param param;
++
++      retval = copy_from_user((void *)&param, (void *)arg, sizeof(param));
++      if (retval < 0) {
++              mif_err("ERR! copy_from_user fail (err %d)\n", retval);
++              return -1;
++      }
++
++      retval = _qc_data_upload(pld, &param);
++      if (retval < 0) {
++              mif_err("ERR! _qc_data_upload fail (err %d)\n", retval);
++              return -1;
++      }
++
++      if (!(param.count % 500))
++              mif_info("param->count = %d\n", param.count);
++
++      if (param.tag == 4) {
++              enable_irq(pld->irq);
++              mif_info("param->tag = %d\n", param.tag);
++      }
++
++      retval = copy_to_user((unsigned long *)arg, &param, sizeof(param));
++      if (retval < 0) {
++              mif_err("ERR! copy_to_user fail (err %d)\n", retval);
++              return -1;
++      }
++
++      return retval;
++}
++
++static int qc_ioctl(struct pld_link_device *pld, struct io_device *iod,
++              unsigned int cmd, unsigned long arg)
++{
++      struct link_device *ld = &pld->ld;
++      int err = 0;
++
++      switch (cmd) {
++      case IOCTL_DPRAM_PHONE_POWON:
++              err = qc_prepare_download(pld);
++              if (err < 0)
++                      mif_info("%s: ERR! prepare_download fail\n", ld->name);
++              break;
++
++      case IOCTL_DPRAM_PHONEIMG_LOAD:
++              err = qc_download_bin(pld, (void *)arg);
++              if (err < 0)
++                      mif_info("%s: ERR! download_bin fail\n", ld->name);
++              break;
++
++      case IOCTL_DPRAM_NVDATA_LOAD:
++              err = qc_download_nv(pld, (void *)arg);
++              if (err < 0)
++                      mif_info("%s: ERR! download_nv fail\n", ld->name);
++              break;
++
++      case IOCTL_DPRAM_PHONE_BOOTSTART:
++              err = qc_boot_start(pld);
++              if (err < 0) {
++                      mif_info("%s: ERR! boot_start fail\n", ld->name);
++                      break;
++              }
++
++              err = qc_boot_post_process(pld);
++              if (err < 0)
++                      mif_info("%s: ERR! boot_post_process fail\n", ld->name);
++
++              break;
++
++      case IOCTL_DPRAM_PHONE_UPLOAD_STEP1:
++              disable_irq_nosync(pld->irq);
++              err = qc_uload_step1(pld);
++              if (err < 0) {
++                      enable_irq(pld->irq);
++                      mif_info("%s: ERR! upload_step1 fail\n", ld->name);
++              }
++              break;
++
++      case IOCTL_DPRAM_PHONE_UPLOAD_STEP2:
++              err = qc_uload_step2(pld, (void *)arg);
++              if (err < 0) {
++                      enable_irq(pld->irq);
++                      mif_info("%s: ERR! upload_step2 fail\n", ld->name);
++              }
++              break;
++
++      default:
++              mif_err("%s: ERR! invalid cmd 0x%08X\n", ld->name, cmd);
++              err = -EINVAL;
++              break;
++      }
++
++      return err;
++}
++#endif
++
++static struct pld_ext_op ext_op_set[] = {
++#if defined(CONFIG_CDMA_MODEM_MDM6600)
++      [QC_MDM6600] = {
++              .exist = 1,
++              .init_boot_map = qc_init_boot_map,
++              .dload_cmd_handler = qc_dload_cmd_handler,
++              .cp_start_handler = qc_start_handler,
++              .crash_log = qc_crash_log,
++              .ioctl = qc_ioctl,
++      },
++#endif
++#if defined(CONFIG_GSM_MODEM_ESC6270)
++      [QC_ESC6270] = {
++              .exist = 1,
++              .init_boot_map = qc_init_boot_map,
++              .dload_cmd_handler = qc_dload_cmd_handler,
++              .cp_start_handler = qc_start_handler,
++              .crash_log = qc_crash_log,
++              .ioctl = qc_ioctl,
++      },
++#endif
++};
++
++struct pld_ext_op *pld_get_ext_op(enum modem_t modem)
++{
++      if (ext_op_set[modem].exist)
++              return &ext_op_set[modem];
++      else
++              return NULL;
++}
+diff --git a/drivers/misc/modem_if/modem_link_device_usb.c b/drivers/misc/modem_if/modem_link_device_usb.c
+new file mode 100644
+index 0000000..5b7c98b
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_link_device_usb.c
+@@ -0,0 +1,1027 @@
++/*
++ * Copyright (C) 2010 Google, Inc.
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#define DEBUG
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/device.h>
++#include <linux/sched.h>
++#include <linux/irq.h>
++#include <linux/poll.h>
++#include <linux/gpio.h>
++#include <linux/if_arp.h>
++#include <linux/platform_device.h>
++#include <linux/suspend.h>
++
++#include <linux/platform_data/modem.h>
++#include "modem_prj.h"
++#include "modem_link_device_usb.h"
++#include "modem_utils.h"
++#include "modem_link_pm_usb.h"
++
++#include <mach/regs-gpio.h>
++
++#define URB_COUNT     4
++
++static int usb_tx_urb_with_skb(struct usb_link_device *usb_ld,
++              struct sk_buff *skb, struct if_usb_devdata *pipe_data);
++
++static void
++usb_free_urbs(struct usb_link_device *usb_ld, struct if_usb_devdata *pipe)
++{
++      struct usb_device *usbdev = usb_ld->usbdev;
++      struct urb *urb;
++
++      while ((urb = usb_get_from_anchor(&pipe->urbs))) {
++              usb_poison_urb(urb);
++              usb_free_coherent(usbdev, pipe->rx_buf_size,
++                              urb->transfer_buffer, urb->transfer_dma);
++              urb->transfer_buffer = NULL;
++              usb_put_urb(urb);
++              usb_free_urb(urb);
++      }
++}
++
++static int start_ipc(struct link_device *ld, struct io_device *iod)
++{
++      struct sk_buff *skb;
++      char data[1] = {'a'};
++      int err;
++      struct usb_link_device *usb_ld = to_usb_link_device(ld);
++      struct if_usb_devdata *pipe_data = &usb_ld->devdata[IF_USB_FMT_EP];
++
++      if (has_hub(usb_ld) && usb_ld->link_pm_data->hub_handshake_done) {
++              mif_err("Already send start ipc, skip start ipc\n");
++              err = 0;
++              goto exit;
++      }
++
++      if (!usb_ld->if_usb_connected) {
++              mif_err("HSIC/USB not connected, skip start ipc\n");
++              err = -ENODEV;
++              goto exit;
++      }
++
++      if (has_hub(usb_ld) &&
++              usb_ld->if_usb_initstates == INIT_IPC_START_DONE) {
++              mif_debug("Already IPC started\n");
++              err = 0;
++              goto exit;
++      }
++
++      mif_info("send 'a'\n");
++
++      skb = alloc_skb(16, GFP_ATOMIC);
++      if (unlikely(!skb))
++              return -ENOMEM;
++      memcpy(skb_put(skb, 1), data, 1);
++
++      skbpriv(skb)->iod = iod;
++      skbpriv(skb)->ld = &usb_ld->ld;
++      err = usb_tx_urb_with_skb(usb_ld, skb, pipe_data);
++      if (err < 0) {
++              mif_err("usb_tx_urb fail\n");
++              goto exit;
++      }
++      usb_ld->link_pm_data->hub_handshake_done = true;
++      usb_ld->if_usb_initstates = INIT_IPC_START_DONE;
++exit:
++      return err;
++}
++
++static int usb_init_communication(struct link_device *ld,
++                      struct io_device *iod)
++{
++      int err = 0;
++      switch (iod->format) {
++      case IPC_BOOT:
++              ld->com_state = COM_BOOT;
++              skb_queue_purge(&ld->sk_fmt_tx_q);
++              break;
++
++      case IPC_RAMDUMP:
++              ld->com_state = COM_CRASH;
++              break;
++
++      case IPC_FMT:
++              err = start_ipc(ld, iod);
++              break;
++
++      case IPC_RFS:
++      case IPC_RAW:
++
++      default:
++              ld->com_state = COM_ONLINE;
++              break;
++      }
++
++      mif_debug("com_state = %d\n", ld->com_state);
++      return err;
++}
++
++static void usb_terminate_communication(
++                      struct link_device *ld, struct io_device *iod)
++{
++      mif_debug("com_state = %d\n", ld->com_state);
++}
++
++static int usb_rx_submit(struct if_usb_devdata *pipe, struct urb *urb,
++      gfp_t gfp_flags)
++{
++      int ret;
++
++      usb_anchor_urb(urb, &pipe->reading);
++      ret = usb_submit_urb(urb, gfp_flags);
++      if (ret) {
++              usb_unanchor_urb(urb);
++              usb_anchor_urb(urb, &pipe->urbs);
++              mif_err("submit urb fail with ret (%d)\n", ret);
++      }
++
++      usb_mark_last_busy(urb->dev);
++      return ret;
++}
++
++static void usb_rx_complete(struct urb *urb)
++{
++      struct if_usb_devdata *pipe_data = urb->context;
++      struct usb_link_device *usb_ld = usb_get_intfdata(pipe_data->data_intf);
++      struct io_device *iod;
++      int iod_format = IPC_FMT;
++      int ret;
++
++      usb_mark_last_busy(urb->dev);
++
++      switch (urb->status) {
++      case 0:
++      case -ENOENT:
++              if (!urb->actual_length)
++                      goto re_submit;
++              /* call iod recv */
++              /* how we can distinguish boot ch with fmt ch ?? */
++              switch (pipe_data->format) {
++              case IF_USB_FMT_EP:
++                      iod_format = IPC_FMT;
++                      pr_buffer("rx", (char *)urb->transfer_buffer,
++                                      (size_t)urb->actual_length, 16);
++                      break;
++              case IF_USB_RAW_EP:
++                      iod_format = IPC_MULTI_RAW;
++                      break;
++              case IF_USB_RFS_EP:
++                      iod_format = IPC_RFS;
++                      break;
++              default:
++                      break;
++              }
++
++              /* during boot stage fmt end point */
++              /* shared with boot io device */
++              /* when we use fmt device only, at boot and ipc exchange
++                      it can be reduced to 1 device */
++              if (iod_format == IPC_FMT &&
++                      usb_ld->ld.com_state == COM_BOOT)
++                      iod_format = IPC_BOOT;
++              if (iod_format == IPC_FMT &&
++                      usb_ld->ld.com_state == COM_CRASH)
++                      iod_format = IPC_RAMDUMP;
++
++              iod = link_get_iod_with_format(&usb_ld->ld, iod_format);
++              if (iod) {
++                      ret = iod->recv(iod,
++                                      &usb_ld->ld,
++                                      (char *)urb->transfer_buffer,
++                                      urb->actual_length);
++                      if (ret < 0)
++                              mif_err("io device recv error :%d\n", ret);
++              }
++re_submit:
++              if (urb->status || atomic_read(&usb_ld->suspend_count))
++                      break;
++
++              usb_mark_last_busy(urb->dev);
++              usb_rx_submit(pipe_data, urb, GFP_ATOMIC);
++              return;
++      case -ESHUTDOWN:
++      case -EPROTO:
++              break;
++      case -EOVERFLOW:
++              mif_err("RX overflow\n");
++              break;
++      default:
++              mif_err("RX complete Status (%d)\n", urb->status);
++              break;
++      }
++
++      usb_anchor_urb(urb, &pipe_data->urbs);
++}
++
++static int usb_send(struct link_device *ld, struct io_device *iod,
++                      struct sk_buff *skb)
++{
++      struct sk_buff_head *txq;
++      size_t tx_size;
++
++      if (iod->format == IPC_RAW)
++              txq = &ld->sk_raw_tx_q;
++      else
++              txq = &ld->sk_fmt_tx_q;
++
++      /* store the tx size before run the tx_delayed_work*/
++      tx_size = skb->len;
++
++      /* en queue skb data */
++      skb_queue_tail(txq, skb);
++
++      queue_delayed_work(ld->tx_wq, &ld->tx_delayed_work, 0);
++
++      return tx_size;
++}
++
++static void usb_tx_complete(struct urb *urb)
++{
++      int ret = 0;
++      struct sk_buff *skb = urb->context;
++
++      switch (urb->status) {
++      case 0:
++              break;
++      default:
++              mif_err("TX error (%d)\n", urb->status);
++      }
++
++      usb_mark_last_busy(urb->dev);
++      ret = pm_runtime_put_autosuspend(&urb->dev->dev);
++      if (ret < 0 && ret != -EAGAIN)
++              mif_debug("pm_runtime_put_autosuspend failed: %d\n", ret);
++      usb_free_urb(urb);
++      dev_kfree_skb_any(skb);
++}
++
++static void if_usb_force_disconnect(struct work_struct *work)
++{
++      struct usb_link_device *usb_ld =
++              container_of(work, struct usb_link_device, disconnect_work);
++      struct usb_device *udev = usb_ld->usbdev;
++
++      /* if already disconnected before run this workqueue */
++      if (!udev || !(&udev->dev) || !usb_ld->if_usb_connected)
++              return;
++
++      /* disconnect udev's parent if usb hub used */
++      if (has_hub(usb_ld))
++              udev = udev->parent;
++
++      pm_runtime_get_sync(&udev->dev);
++      if (udev->state != USB_STATE_NOTATTACHED) {
++              usb_force_disconnect(udev);
++              mif_info("force disconnect\n");
++      }
++      pm_runtime_put_autosuspend(&udev->dev);
++}
++
++static void
++usb_change_modem_state(struct usb_link_device *usb_ld, enum modem_state state)
++{
++      struct io_device *iod;
++
++      iod = link_get_iod_with_format(&usb_ld->ld, IPC_FMT);
++      if (iod)
++              iod->modem_state_changed(iod, state);
++}
++
++static int usb_tx_urb_with_skb(struct usb_link_device *usb_ld,
++              struct sk_buff *skb, struct if_usb_devdata *pipe_data)
++{
++      int ret, cnt = 0;
++      struct urb *urb;
++      struct usb_device *usbdev = usb_ld->usbdev;
++      unsigned long flags;
++
++      if (!usbdev || (usbdev->state == USB_STATE_NOTATTACHED) ||
++                      usb_ld->host_wake_timeout_flag)
++              return -ENODEV;
++
++      pm_runtime_get_noresume(&usbdev->dev);
++
++      if (usbdev->dev.power.runtime_status == RPM_SUSPENDED ||
++              usbdev->dev.power.runtime_status == RPM_SUSPENDING) {
++              usb_ld->resume_status = AP_INITIATED_RESUME;
++              SET_SLAVE_WAKEUP(usb_ld->pdata, 1);
++
++              while (!wait_event_interruptible_timeout(usb_ld->l2_wait,
++                              usbdev->dev.power.runtime_status == RPM_ACTIVE
++                              || pipe_data->disconnected,
++                              HOST_WAKEUP_TIMEOUT_JIFFIES)) {
++
++                      if (cnt == MAX_RETRY) {
++                              mif_err("host wakeup timeout !!\n");
++                              SET_SLAVE_WAKEUP(usb_ld->pdata, 0);
++                              pm_runtime_put_autosuspend(&usbdev->dev);
++                              schedule_work(&usb_ld->disconnect_work);
++                              usb_ld->host_wake_timeout_flag = 1;
++                              return -1;
++                      }
++                      mif_err("host wakeup timeout ! retry..\n");
++                      SET_SLAVE_WAKEUP(usb_ld->pdata, 0);
++                      udelay(100);
++                      SET_SLAVE_WAKEUP(usb_ld->pdata, 1);
++                      cnt++;
++              }
++
++              if (pipe_data->disconnected) {
++                      SET_SLAVE_WAKEUP(usb_ld->pdata, 0);
++                      pm_runtime_put_autosuspend(&usbdev->dev);
++                      return -ENODEV;
++              }
++
++              mif_debug("wait_q done (runtime_status=%d)\n",
++                              usbdev->dev.power.runtime_status);
++      }
++
++      urb = usb_alloc_urb(0, GFP_KERNEL);
++      if (!urb) {
++              mif_err("alloc urb error\n");
++              if (pm_runtime_put_autosuspend(&usbdev->dev) < 0)
++                      mif_debug("pm_runtime_put_autosuspend fail\n");
++              return -ENOMEM;
++      }
++
++      urb->transfer_flags = URB_ZERO_PACKET;
++      usb_fill_bulk_urb(urb, usbdev, pipe_data->tx_pipe, skb->data,
++                      skb->len, usb_tx_complete, (void *)skb);
++
++      spin_lock_irqsave(&usb_ld->lock, flags);
++      if (atomic_read(&usb_ld->suspend_count)) {
++              /* transmission will be done in resume */
++              usb_anchor_urb(urb, &usb_ld->deferred);
++              usb_put_urb(urb);
++              mif_debug("anchor urb (0x%p)\n", urb);
++              spin_unlock_irqrestore(&usb_ld->lock, flags);
++              return 0;
++      }
++      spin_unlock_irqrestore(&usb_ld->lock, flags);
++
++      ret = usb_submit_urb(urb, GFP_KERNEL);
++      if (ret < 0) {
++              mif_err("usb_submit_urb with ret(%d)\n", ret);
++              if (pm_runtime_put_autosuspend(&usbdev->dev) < 0)
++                      mif_debug("pm_runtime_put_autosuspend fail\n");
++      }
++      return ret;
++}
++
++static void usb_tx_work(struct work_struct *work)
++{
++      int ret = 0;
++      struct link_device *ld =
++              container_of(work, struct link_device, tx_delayed_work.work);
++      struct usb_link_device *usb_ld = to_usb_link_device(ld);
++      struct io_device *iod;
++      struct sk_buff *skb;
++      struct if_usb_devdata *pipe_data;
++      struct link_pm_data *pm_data = usb_ld->link_pm_data;
++
++      /*TODO: check the PHONE ACTIVE STATES */
++      /* because tx data wait until hub on with wait_for_complettion, it
++       should queue to single_threaded work queue */
++      if (!link_pm_set_active(usb_ld))
++              return;
++
++      while (ld->sk_fmt_tx_q.qlen || ld->sk_raw_tx_q.qlen) {
++              /* send skb from fmt_txq and raw_txq,
++               * one by one for fair flow control */
++              skb = skb_dequeue(&ld->sk_fmt_tx_q);
++              if (skb) {
++                      iod = skbpriv(skb)->iod;
++                      switch (iod->format) {
++                      case IPC_BOOT:
++                      case IPC_RAMDUMP:
++                      case IPC_FMT:
++                              /* boot device uses same intf with fmt*/
++                              pipe_data = &usb_ld->devdata[IF_USB_FMT_EP];
++                              break;
++                      case IPC_RFS:
++                              pipe_data = &usb_ld->devdata[IF_USB_RFS_EP];
++                              break;
++                      default:
++                              /* wrong packet for fmt tx q , drop it */
++                              dev_kfree_skb_any(skb);
++                              continue;
++                      }
++
++                      ret = usb_tx_urb_with_skb(usb_ld, skb, pipe_data);
++                      if (ret < 0) {
++                              mif_err("usb_tx_urb_with_skb, ret(%d)\n",
++                                      ret);
++                              skb_queue_head(&ld->sk_fmt_tx_q, skb);
++                              return;
++                      }
++              }
++
++              skb = skb_dequeue(&ld->sk_raw_tx_q);
++              if (skb) {
++                      pipe_data = &usb_ld->devdata[IF_USB_RAW_EP];
++                      ret = usb_tx_urb_with_skb(usb_ld, skb, pipe_data);
++                      if (ret < 0) {
++                              mif_err("usb_tx_urb_with_skb "
++                                              "for raw, ret(%d)\n",
++                                              ret);
++                              skb_queue_head(&ld->sk_raw_tx_q, skb);
++                              return;
++                      }
++              }
++      }
++}
++
++static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
++{
++      struct usb_link_device *usb_ld = usb_get_intfdata(intf);
++      struct link_pm_data *pm_data = usb_ld->link_pm_data;
++      int i;
++
++      if (atomic_inc_return(&usb_ld->suspend_count) == IF_USB_DEVNUM_MAX) {
++              mif_debug("L2\n");
++
++              for (i = 0; i < IF_USB_DEVNUM_MAX; i++)
++                      usb_kill_anchored_urbs(&usb_ld->devdata[i].reading);
++
++              if (pm_data->freq_unlock)
++                      pm_data->freq_unlock(&usb_ld->usbdev->dev);
++
++              wake_unlock(&usb_ld->susplock);
++      }
++
++      return 0;
++}
++
++static void runtime_pm_work(struct work_struct *work)
++{
++      struct usb_link_device *usb_ld = container_of(work,
++              struct usb_link_device, runtime_pm_work.work);
++      int ret;
++
++      ret = pm_request_autosuspend(&usb_ld->usbdev->dev);
++
++      if (ret == -EAGAIN || ret == 1)
++              queue_delayed_work(system_nrt_wq, &usb_ld->runtime_pm_work,
++                                                      msecs_to_jiffies(50));
++}
++
++static void post_resume_work(struct work_struct *work)
++{
++      struct usb_link_device *usb_ld = container_of(work,
++                      struct usb_link_device, post_resume_work.work);
++      struct link_pm_data *pm_data = usb_ld->link_pm_data;
++      struct usb_device *udev = usb_ld->usbdev;
++
++      /* if already disconnected before run this workqueue */
++      if (!udev || !(&udev->dev) || !usb_ld->if_usb_connected)
++              return;
++
++      /* lock cpu/bus frequency when L2->L0 */
++      if (pm_data->freq_lock)
++              pm_data->freq_lock(&udev->dev);
++}
++
++static void wait_enumeration_work(struct work_struct *work)
++{
++      struct usb_link_device *usb_ld = container_of(work,
++              struct usb_link_device, wait_enumeration.work);
++      if (usb_ld->if_usb_connected == 0) {
++              mif_err("USB disconnected and not enumerated for long time\n");
++              usb_change_modem_state(usb_ld, STATE_CRASH_EXIT);
++      }
++}
++
++static int if_usb_resume(struct usb_interface *intf)
++{
++      int i, ret;
++      struct sk_buff *skb;
++      struct usb_link_device *usb_ld = usb_get_intfdata(intf);
++      struct if_usb_devdata *pipe;
++      struct urb *urb;
++
++      spin_lock_irq(&usb_ld->lock);
++      if (!atomic_dec_return(&usb_ld->suspend_count)) {
++              spin_unlock_irq(&usb_ld->lock);
++
++              mif_debug("\n");
++              wake_lock(&usb_ld->susplock);
++
++              /* HACK: Runtime pm does not allow requesting autosuspend from
++               * resume callback, delayed it after resume */
++              queue_delayed_work(system_nrt_wq, &usb_ld->runtime_pm_work,
++                                                      msecs_to_jiffies(50));
++
++              for (i = 0; i < IF_USB_DEVNUM_MAX; i++) {
++                      pipe = &usb_ld->devdata[i];
++                      while ((urb = usb_get_from_anchor(&pipe->urbs))) {
++                              ret = usb_rx_submit(pipe, urb, GFP_KERNEL);
++                              if (ret < 0) {
++                                      usb_put_urb(urb);
++                                      mif_err(
++                                      "usb_rx_submit error with (%d)\n",
++                                              ret);
++                                      return ret;
++                              }
++                              usb_put_urb(urb);
++                      }
++              }
++
++              while ((urb = usb_get_from_anchor(&usb_ld->deferred))) {
++                      mif_debug("got urb (0x%p) from anchor & resubmit\n",
++                                      urb);
++                      ret = usb_submit_urb(urb, GFP_KERNEL);
++                      if (ret < 0) {
++                              mif_err("resubmit failed\n");
++                              skb = urb->context;
++                              dev_kfree_skb_any(skb);
++                              usb_free_urb(urb);
++                              ret = pm_runtime_put_autosuspend(
++                                              &usb_ld->usbdev->dev);
++                              if (ret < 0 && ret != -EAGAIN)
++                                      mif_debug("pm_runtime_put_autosuspend "
++                                                      "failed: %d\n", ret);
++                      }
++              }
++              SET_SLAVE_WAKEUP(usb_ld->pdata, 1);
++              udelay(100);
++              SET_SLAVE_WAKEUP(usb_ld->pdata, 0);
++
++              /* if_usb_resume() is atomic. post_resume_work is
++               * a kind of bottom halves
++               */
++              queue_delayed_work(system_nrt_wq, &usb_ld->post_resume_work, 0);
++
++              return 0;
++      }
++
++      spin_unlock_irq(&usb_ld->lock);
++      return 0;
++}
++
++static int if_usb_reset_resume(struct usb_interface *intf)
++{
++      int ret;
++
++      mif_debug("\n");
++      ret = if_usb_resume(intf);
++      return ret;
++}
++
++static struct usb_device_id if_usb_ids[] = {
++      { USB_DEVICE(0x04e8, 0x6999), /* CMC221 LTE Modem */
++      /*.driver_info = 0,*/
++      },
++      { } /* terminating entry */
++};
++MODULE_DEVICE_TABLE(usb, if_usb_ids);
++
++static struct usb_driver if_usb_driver;
++static void if_usb_disconnect(struct usb_interface *intf)
++{
++      struct usb_link_device *usb_ld  = usb_get_intfdata(intf);
++      struct usb_device *usbdev = usb_ld->usbdev;
++      struct link_pm_data *pm_data = usb_ld->link_pm_data;
++      int dev_id = intf->altsetting->desc.bInterfaceNumber;
++      struct if_usb_devdata *pipe_data = &usb_ld->devdata[dev_id];
++
++
++      usb_set_intfdata(intf, NULL);
++
++      pipe_data->disconnected = 1;
++      smp_wmb();
++
++      wake_up(&usb_ld->l2_wait);
++
++      usb_ld->if_usb_connected = 0;
++      usb_ld->flow_suspend = 1;
++
++      dev_dbg(&usbdev->dev, "%s\n", __func__);
++      usb_ld->dev_count--;
++      usb_driver_release_interface(&if_usb_driver, pipe_data->data_intf);
++
++      usb_kill_anchored_urbs(&pipe_data->reading);
++      usb_free_urbs(usb_ld, pipe_data);
++
++      if (usb_ld->dev_count == 0) {
++              cancel_delayed_work_sync(&usb_ld->runtime_pm_work);
++              cancel_delayed_work_sync(&usb_ld->post_resume_work);
++              cancel_delayed_work_sync(&usb_ld->ld.tx_delayed_work);
++              usb_put_dev(usbdev);
++              usb_ld->usbdev = NULL;
++              pm_runtime_forbid(pm_data->root_hub);
++      }
++}
++
++static int __devinit if_usb_probe(struct usb_interface *intf,
++                                      const struct usb_device_id *id)
++{
++      struct usb_host_interface *data_desc;
++      struct usb_link_device *usb_ld =
++                      (struct usb_link_device *)id->driver_info;
++      struct link_device *ld = &usb_ld->ld;
++      struct usb_interface *data_intf;
++      struct usb_device *usbdev = interface_to_usbdev(intf);
++      struct device *dev, *ehci_dev, *root_hub;
++      struct if_usb_devdata *pipe;
++      struct urb *urb;
++      int i;
++      int j;
++      int dev_id;
++      int err;
++
++      /* To detect usb device order probed */
++      dev_id = intf->cur_altsetting->desc.bInterfaceNumber;
++
++      if (dev_id >= IF_USB_DEVNUM_MAX) {
++              dev_err(&intf->dev, "Device id %d cannot support\n",
++                                                              dev_id);
++              return -EINVAL;
++      }
++
++      if (!usb_ld) {
++              dev_err(&intf->dev,
++              "if_usb device doesn't be allocated\n");
++              err = ENOMEM;
++              goto out;
++      }
++
++      mif_info("probe dev_id=%d usb_device_id(0x%p), usb_ld (0x%p)\n",
++                              dev_id, id, usb_ld);
++
++      usb_ld->usbdev = usbdev;
++      usb_get_dev(usbdev);
++
++      for (i = 0; i < IF_USB_DEVNUM_MAX; i++) {
++              data_intf = usb_ifnum_to_if(usbdev, i);
++
++              /* remap endpoint of RAW to no.1 for LTE modem */
++              if (i == 0)
++                      pipe = &usb_ld->devdata[1];
++              else if (i == 1)
++                      pipe = &usb_ld->devdata[0];
++              else
++                      pipe = &usb_ld->devdata[i];
++
++              pipe->disconnected = 0;
++              pipe->data_intf = data_intf;
++              data_desc = data_intf->cur_altsetting;
++
++              /* Endpoints */
++              if (usb_pipein(data_desc->endpoint[0].desc.bEndpointAddress)) {
++                      pipe->rx_pipe = usb_rcvbulkpipe(usbdev,
++                              data_desc->endpoint[0].desc.bEndpointAddress);
++                      pipe->tx_pipe = usb_sndbulkpipe(usbdev,
++                              data_desc->endpoint[1].desc.bEndpointAddress);
++                      pipe->rx_buf_size = 1024*4;
++              } else {
++                      pipe->rx_pipe = usb_rcvbulkpipe(usbdev,
++                              data_desc->endpoint[1].desc.bEndpointAddress);
++                      pipe->tx_pipe = usb_sndbulkpipe(usbdev,
++                              data_desc->endpoint[0].desc.bEndpointAddress);
++                      pipe->rx_buf_size = 1024*4;
++              }
++
++              if (i == 0) {
++                      dev_info(&usbdev->dev, "USB IF USB device found\n");
++              } else {
++                      err = usb_driver_claim_interface(&if_usb_driver,
++                                      data_intf, usb_ld);
++                      if (err < 0) {
++                              mif_err("failed to cliam usb interface\n");
++                              goto out;
++                      }
++              }
++
++              usb_set_intfdata(data_intf, usb_ld);
++              usb_ld->dev_count++;
++              pm_suspend_ignore_children(&data_intf->dev, true);
++
++              for (j = 0; j < URB_COUNT; j++) {
++                      urb = usb_alloc_urb(0, GFP_KERNEL);
++                      if (!urb) {
++                              mif_err("alloc urb fail\n");
++                              err = -ENOMEM;
++                              goto out2;
++                      }
++
++                      urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
++                      urb->transfer_buffer = usb_alloc_coherent(usbdev,
++                              pipe->rx_buf_size, GFP_KERNEL,
++                              &urb->transfer_dma);
++                      if (!urb->transfer_buffer) {
++                              mif_err(
++                              "Failed to allocate transfer buffer\n");
++                              usb_free_urb(urb);
++                              err = -ENOMEM;
++                              goto out2;
++                      }
++
++                      usb_fill_bulk_urb(urb, usbdev, pipe->rx_pipe,
++                              urb->transfer_buffer, pipe->rx_buf_size,
++                              usb_rx_complete, pipe);
++                      usb_anchor_urb(urb, &pipe->urbs);
++              }
++      }
++
++      /* temporary call reset_resume */
++      atomic_set(&usb_ld->suspend_count, 1);
++      if_usb_reset_resume(data_intf);
++      atomic_set(&usb_ld->suspend_count, 0);
++
++      SET_HOST_ACTIVE(usb_ld->pdata, 1);
++      usb_ld->host_wake_timeout_flag = 0;
++
++      if (gpio_get_value(usb_ld->pdata->gpio_phone_active)) {
++              struct link_pm_data *pm_data = usb_ld->link_pm_data;
++              int delay = pm_data->autosuspend_delay_ms ?:
++                              DEFAULT_AUTOSUSPEND_DELAY_MS;
++              pm_runtime_set_autosuspend_delay(&usbdev->dev, delay);
++              dev = &usbdev->dev;
++              if (dev->parent) {
++                      dev_dbg(&usbdev->dev, "if_usb Runtime PM Start!!\n");
++                      usb_enable_autosuspend(usb_ld->usbdev);
++                      /* s5p-ehci runtime pm allow - usb phy suspend mode */
++                      root_hub = &usbdev->bus->root_hub->dev;
++                      ehci_dev = root_hub->parent;
++                      mif_debug("ehci device = %s, %s\n",
++                                      dev_driver_string(ehci_dev),
++                                      dev_name(ehci_dev));
++                      pm_runtime_allow(ehci_dev);
++
++                      if (!pm_data->autosuspend)
++                              pm_runtime_forbid(dev);
++
++                      if (has_hub(usb_ld))
++                              link_pm_preactive(pm_data);
++
++                      pm_data->root_hub = root_hub;
++              }
++
++              usb_ld->flow_suspend = 0;
++              /* Queue work if skbs were pending before a disconnect/probe */
++              if (ld->sk_fmt_tx_q.qlen || ld->sk_raw_tx_q.qlen)
++                      queue_delayed_work(ld->tx_wq, &ld->tx_delayed_work, 0);
++
++              usb_ld->if_usb_connected = 1;
++              /*USB3503*/
++              mif_debug("hub active complete\n");
++
++              usb_change_modem_state(usb_ld, STATE_ONLINE);
++      } else {
++              usb_change_modem_state(usb_ld, STATE_LOADER_DONE);
++      }
++
++      /* check dynamic switching gpio received
++       * before usb enumeration is completed
++       */
++      if (ld->mc->need_switch_to_usb) {
++              ld->mc->need_switch_to_usb = false;
++              rawdevs_set_tx_link(ld->msd, LINKDEV_USB);
++      }
++
++      return 0;
++
++out2:
++      usb_ld->dev_count--;
++      for (i = 0; i < IF_USB_DEVNUM_MAX; i++)
++              usb_free_urbs(usb_ld, &usb_ld->devdata[i]);
++out:
++      usb_set_intfdata(intf, NULL);
++      return err;
++}
++
++irqreturn_t usb_resume_irq(int irq, void *data)
++{
++      int ret;
++      struct usb_link_device *usb_ld = data;
++      int hwup;
++      static int wake_status = -1;
++      struct device *dev;
++
++      hwup = gpio_get_value(usb_ld->pdata->gpio_host_wakeup);
++      if (hwup == wake_status) {
++              mif_err("Received spurious wake irq: %d", hwup);
++              return IRQ_HANDLED;
++      }
++      wake_status = hwup;
++
++      irq_set_irq_type(irq, hwup ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH);
++      /*
++       * exynos BSP has problem when using level interrupt.
++       * If we change irq type from interrupt handler,
++       * we can get level interrupt twice.
++       * this is temporary solution until SYS.LSI resolve this problem.
++       */
++      __raw_writel(eint_irq_to_bit(irq), S5P_EINT_PEND(EINT_REG_NR(irq)));
++      wake_lock_timeout(&usb_ld->gpiolock, 100);
++
++      mif_err("< H-WUP %d\n", hwup);
++
++      if (!link_pm_is_connected(usb_ld))
++              return IRQ_HANDLED;
++
++      if (hwup) {
++              dev = &usb_ld->usbdev->dev;
++              mif_info("runtime status=%d\n",
++                              dev->power.runtime_status);
++
++              /* if usb3503 was on, usb_if was resumed by probe */
++              if (has_hub(usb_ld) &&
++                              (dev->power.runtime_status == RPM_ACTIVE ||
++                              dev->power.runtime_status == RPM_RESUMING))
++                      return IRQ_HANDLED;
++
++              device_lock(dev);
++              if (dev->power.is_prepared || dev->power.is_suspended) {
++                      pm_runtime_get_noresume(dev);
++                      ret = 0;
++              } else {
++                      ret = pm_runtime_get_sync(dev);
++              }
++              device_unlock(dev);
++              if (ret < 0) {
++                      mif_err("pm_runtime_get fail (%d)\n", ret);
++                      return IRQ_HANDLED;
++              }
++      } else {
++              if (usb_ld->resume_status == AP_INITIATED_RESUME)
++                      wake_up(&usb_ld->l2_wait);
++              usb_ld->resume_status = CP_INITIATED_RESUME;
++              pm_runtime_mark_last_busy(&usb_ld->usbdev->dev);
++              pm_runtime_put_autosuspend(&usb_ld->usbdev->dev);
++      }
++
++      return IRQ_HANDLED;
++}
++
++static int if_usb_init(struct usb_link_device *usb_ld)
++{
++      int ret;
++      int i;
++      struct if_usb_devdata *pipe;
++
++      /* give it to probe, or global variable needed */
++      if_usb_ids[0].driver_info = (unsigned long)usb_ld;
++
++      for (i = 0; i < IF_USB_DEVNUM_MAX; i++) {
++              pipe = &usb_ld->devdata[i];
++              pipe->format = i;
++              pipe->disconnected = 1;
++              init_usb_anchor(&pipe->urbs);
++              init_usb_anchor(&pipe->reading);
++      }
++
++      init_waitqueue_head(&usb_ld->l2_wait);
++      init_usb_anchor(&usb_ld->deferred);
++
++      ret = usb_register(&if_usb_driver);
++      if (ret) {
++              mif_err("usb_register_driver() fail : %d\n", ret);
++              return ret;
++      }
++
++      return 0;
++}
++
++struct link_device *usb_create_link_device(void *data)
++{
++      int ret;
++      struct modem_data *pdata;
++      struct platform_device *pdev = (struct platform_device *)data;
++      struct usb_link_device *usb_ld = NULL;
++      struct link_device *ld = NULL;
++
++      pdata = pdev->dev.platform_data;
++
++      usb_ld = kzalloc(sizeof(struct usb_link_device), GFP_KERNEL);
++      if (!usb_ld)
++              goto err;
++
++      INIT_LIST_HEAD(&usb_ld->ld.list);
++      skb_queue_head_init(&usb_ld->ld.sk_fmt_tx_q);
++      skb_queue_head_init(&usb_ld->ld.sk_raw_tx_q);
++      spin_lock_init(&usb_ld->lock);
++
++      ld = &usb_ld->ld;
++      usb_ld->pdata = pdata;
++
++      ld->name = "usb";
++      ld->init_comm = usb_init_communication;
++      ld->terminate_comm = usb_terminate_communication;
++      ld->send = usb_send;
++      ld->com_state = COM_NONE;
++
++      /*ld->tx_wq = create_singlethread_workqueue("usb_tx_wq");*/
++      ld->tx_wq = alloc_workqueue("usb_tx_wq",
++              WQ_HIGHPRI | WQ_UNBOUND | WQ_RESCUER, 1);
++
++      if (!ld->tx_wq) {
++              mif_err("fail to create work Q.\n");
++              goto err;
++      }
++
++      usb_ld->pdata->irq_host_wakeup = platform_get_irq(pdev, 1);
++      wake_lock_init(&usb_ld->gpiolock, WAKE_LOCK_SUSPEND,
++              "modem_usb_gpio_wake");
++      wake_lock_init(&usb_ld->susplock, WAKE_LOCK_SUSPEND,
++              "modem_usb_suspend_block");
++
++      INIT_DELAYED_WORK(&ld->tx_delayed_work, usb_tx_work);
++      INIT_DELAYED_WORK(&usb_ld->runtime_pm_work, runtime_pm_work);
++      INIT_DELAYED_WORK(&usb_ld->post_resume_work, post_resume_work);
++      INIT_DELAYED_WORK(&usb_ld->wait_enumeration, wait_enumeration_work);
++      INIT_WORK(&usb_ld->disconnect_work, if_usb_force_disconnect);
++
++      /* create link pm device */
++      ret = link_pm_init(usb_ld, data);
++      if (ret)
++              goto err;
++
++      ret = if_usb_init(usb_ld);
++      if (ret)
++              goto err;
++
++      return ld;
++err:
++      if (ld && ld->tx_wq)
++              destroy_workqueue(ld->tx_wq);
++
++      kfree(usb_ld);
++
++      return NULL;
++}
++
++static struct usb_driver if_usb_driver = {
++      .name =         "if_usb_driver",
++      .probe =        if_usb_probe,
++      .disconnect =   if_usb_disconnect,
++      .id_table =     if_usb_ids,
++      .suspend =      if_usb_suspend,
++      .resume =       if_usb_resume,
++      .reset_resume = if_usb_reset_resume,
++      .supports_autosuspend = 1,
++};
++
++static void __exit if_usb_exit(void)
++{
++      usb_deregister(&if_usb_driver);
++}
++
++bool usb_is_enumerated(struct modem_shared *msd)
++{
++      struct link_device *ld = find_linkdev(msd, LINKDEV_USB);
++      if (ld)
++              return to_usb_link_device(ld)->usbdev != NULL;
++      else
++              return false;
++}
++
++
++/* lte specific functions */
++
++static int lte_wake_resume(struct device *pdev)
++{
++      struct modem_data *pdata = pdev->platform_data;
++      int val;
++
++      val = gpio_get_value(pdata->gpio_host_wakeup);
++      if (!val) {
++              mif_debug("> S-WUP 1\n");
++              gpio_set_value(pdata->gpio_slave_wakeup, 1);
++      }
++
++      return 0;
++}
++
++static const struct dev_pm_ops lte_wake_pm_ops = {
++      .resume     = lte_wake_resume,
++};
++
++static struct platform_driver lte_wake_driver = {
++      .driver = {
++              .name = "modem_lte_wake",
++              .pm   = &lte_wake_pm_ops,
++      },
++};
++
++static int __init lte_wake_init(void)
++{
++      return platform_driver_register(&lte_wake_driver);
++}
++module_init(lte_wake_init);
+diff --git a/drivers/misc/modem_if/modem_link_device_usb.h b/drivers/misc/modem_if/modem_link_device_usb.h
+new file mode 100644
+index 0000000..8233fd1
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_link_device_usb.h
+@@ -0,0 +1,132 @@
++/*
++ * Copyright (C) 2010 Google, Inc.
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#ifndef __MODEM_LINK_DEVICE_USB_H__
++#define __MODEM_LINK_DEVICE_USB_H__
++
++#include <linux/usb.h>
++#include <linux/wakelock.h>
++
++#define IF_USB_DEVNUM_MAX     3
++
++#define IF_USB_FMT_EP         0
++#define IF_USB_RAW_EP         1
++#define IF_USB_RFS_EP         2
++
++#define DEFAULT_AUTOSUSPEND_DELAY_MS          500
++#define HOST_WAKEUP_TIMEOUT_JIFFIES           msecs_to_jiffies(500)
++#define WAIT_ENUMURATION_TIMEOUT_JIFFIES      msecs_to_jiffies(15000)
++#define MAX_RETRY     30
++
++#define IOCTL_LINK_CONTROL_ENABLE     _IO('o', 0x30)
++#define IOCTL_LINK_CONTROL_ACTIVE     _IO('o', 0x31)
++#define IOCTL_LINK_GET_HOSTWAKE               _IO('o', 0x32)
++#define IOCTL_LINK_CONNECTED          _IO('o', 0x33)
++#define IOCTL_LINK_SET_BIAS_CLEAR     _IO('o', 0x34)
++
++#define IOCTL_LINK_PORT_ON            _IO('o', 0x35)
++#define IOCTL_LINK_PORT_OFF           _IO('o', 0x36)
++
++enum RESUME_STATUS {
++      CP_INITIATED_RESUME,
++      AP_INITIATED_RESUME,
++};
++
++enum IPC_INIT_STATUS {
++      INIT_IPC_NOT_READY,
++      INIT_IPC_START_DONE,    /* send 'a' done */
++};
++
++enum hub_status {
++      HUB_STATE_OFF,          /* usb3503 0ff*/
++      HUB_STATE_RESUMMING,    /* usb3503 on, but enummerattion was not yet*/
++      HUB_STATE_ACTIVE,       /* hub and CMC221 enumerate */
++};
++
++struct if_usb_devdata {
++      struct usb_interface *data_intf;
++      unsigned int tx_pipe;
++      unsigned int rx_pipe;
++      u8 disconnected;
++
++      int format;
++      struct usb_anchor urbs;
++      struct usb_anchor reading;
++      unsigned int rx_buf_size;
++};
++
++struct usb_link_device {
++      /*COMMON LINK DEVICE*/
++      struct link_device ld;
++
++      struct modem_data *pdata;
++
++      /*USB SPECIFIC LINK DEVICE*/
++      struct usb_device       *usbdev;
++      struct if_usb_devdata   devdata[IF_USB_DEVNUM_MAX];
++      struct delayed_work     runtime_pm_work;
++      struct delayed_work     post_resume_work;
++      struct delayed_work     wait_enumeration;
++      struct work_struct      disconnect_work;
++
++      struct wake_lock        gpiolock;
++      struct wake_lock        susplock;
++
++      unsigned int            dev_count;
++      unsigned int            suspended;
++      atomic_t                suspend_count;
++      enum RESUME_STATUS      resume_status;
++      int if_usb_connected;
++      int if_usb_initstates;
++      int flow_suspend;
++      int host_wake_timeout_flag;
++
++      unsigned gpio_slave_wakeup;
++      unsigned gpio_host_wakeup;
++      unsigned gpio_host_active;
++      int irq_host_wakeup;
++      struct delayed_work dwork;
++      struct work_struct resume_work;
++      int cpcrash_flag;
++      wait_queue_head_t l2_wait;
++
++      spinlock_t              lock;
++      struct usb_anchor       deferred;
++
++      /* LINK PM DEVICE DATA */
++      struct link_pm_data *link_pm_data;
++};
++/* converts from struct link_device* to struct xxx_link_device* */
++#define to_usb_link_device(linkdev) \
++                      container_of(linkdev, struct usb_link_device, ld)
++
++#define SET_SLAVE_WAKEUP(_pdata, _value)                      \
++do {                                                          \
++      gpio_set_value(_pdata->gpio_slave_wakeup, _value);      \
++      mif_debug("> S-WUP %s\n", _value ? "1" : "0");  \
++} while (0)
++
++#define SET_HOST_ACTIVE(_pdata, _value)                       \
++do {                                                          \
++      gpio_set_value(_pdata->gpio_host_active, _value);       \
++      mif_debug("> H-ACT %s\n", _value ? "1" : "0");  \
++} while (0)
++
++#define has_hub(usb_ld) ((usb_ld)->link_pm_data->has_usbhub)
++
++irqreturn_t usb_resume_irq(int irq, void *data);
++bool usb_is_enumerated(struct modem_shared *msd);
++
++#endif
+diff --git a/drivers/misc/modem_if/modem_link_pm_usb.c b/drivers/misc/modem_if/modem_link_pm_usb.c
+new file mode 100644
+index 0000000..1b2614e
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_link_pm_usb.c
+@@ -0,0 +1,417 @@
++/*
++ * Copyright (C) 2012 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#define DEBUG
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/device.h>
++#include <linux/sched.h>
++#include <linux/irq.h>
++#include <linux/poll.h>
++#include <linux/gpio.h>
++#include <linux/if_arp.h>
++#include <linux/platform_device.h>
++#include <linux/suspend.h>
++
++#include "modem_link_pm_usb.h"
++
++static inline void start_hub_work(struct link_pm_data *pm_data, int delay)
++{
++      if (pm_data->hub_work_running == false) {
++              pm_data->hub_work_running = true;
++              wake_lock(&pm_data->hub_lock);
++              mif_debug("link_pm_hub_work is started\n");
++      }
++
++      schedule_delayed_work(&pm_data->link_pm_hub, msecs_to_jiffies(delay));
++}
++
++static inline void end_hub_work(struct link_pm_data *pm_data)
++{
++      wake_unlock(&pm_data->hub_lock);
++      pm_data->hub_work_running = false;
++      mif_debug("link_pm_hub_work is done\n");
++}
++
++bool link_pm_is_connected(struct usb_link_device *usb_ld)
++{
++      if (has_hub(usb_ld)) {
++              struct link_pm_data *pm_data = usb_ld->link_pm_data;
++              if (pm_data->hub_init_lock)
++                      return false;
++
++              if (pm_data->hub_status == HUB_STATE_OFF) {
++                      if (pm_data->hub_work_running == false)
++                              start_hub_work(pm_data, 0);
++                      return false;
++              }
++      }
++
++      if (!usb_ld->if_usb_connected) {
++              mif_err("mif: if not connected\n");
++              return false;
++      }
++
++      return true;
++}
++
++void link_pm_preactive(struct link_pm_data *pm_data)
++{
++      if (pm_data->root_hub) {
++              mif_info("pre-active\n");
++              pm_data->hub_on_retry_cnt = 0;
++              complete(&pm_data->hub_active);
++              pm_runtime_put_sync(pm_data->root_hub);
++      }
++
++      pm_data->hub_status = HUB_STATE_ACTIVE;
++}
++
++static void link_pm_hub_work(struct work_struct *work)
++{
++      int err;
++      struct link_pm_data *pm_data =
++              container_of(work, struct link_pm_data, link_pm_hub.work);
++
++      if (pm_data->hub_status == HUB_STATE_ACTIVE) {
++              end_hub_work(pm_data);
++              return;
++      }
++
++      if (!pm_data->port_enable) {
++              mif_err("mif: hub power func not assinged\n");
++              end_hub_work(pm_data);
++              return;
++      }
++
++      /* If kernel if suspend, wait the ehci resume */
++      if (pm_data->dpm_suspending) {
++              mif_info("dpm_suspending\n");
++              start_hub_work(pm_data, 500);
++              return;
++      }
++
++      switch (pm_data->hub_status) {
++      case HUB_STATE_OFF:
++              pm_data->hub_status = HUB_STATE_RESUMMING;
++              mif_trace("hub off->on\n");
++
++              /* skip 1st time before first probe */
++              if (pm_data->root_hub)
++                      pm_runtime_get_sync(pm_data->root_hub);
++              err = pm_data->port_enable(2, 1);
++              if (err < 0) {
++                      mif_err("hub on fail err=%d\n", err);
++                      err = pm_data->port_enable(2, 0);
++                      if (err < 0)
++                              mif_err("hub off fail err=%d\n", err);
++                      pm_data->hub_status = HUB_STATE_OFF;
++                      if (pm_data->root_hub)
++                              pm_runtime_put_sync(pm_data->root_hub);
++                      end_hub_work(pm_data);
++              } else {
++                      /* resume root hub */
++                      start_hub_work(pm_data, 100);
++              }
++              break;
++      case HUB_STATE_RESUMMING:
++              if (pm_data->hub_on_retry_cnt++ > 50) {
++                      pm_data->hub_on_retry_cnt = 0;
++                      pm_data->hub_status = HUB_STATE_OFF;
++                      if (pm_data->root_hub)
++                              pm_runtime_put_sync(pm_data->root_hub);
++                      end_hub_work(pm_data);
++              } else {
++                      mif_info("hub resumming: %d\n",
++                                      pm_data->hub_on_retry_cnt);
++                      start_hub_work(pm_data, 200);
++              }
++              break;
++      }
++exit:
++      return;
++}
++
++static int link_pm_hub_standby(void *args)
++{
++      struct link_pm_data *pm_data = args;
++      struct usb_link_device *usb_ld = pm_data->usb_ld;
++      int err = 0;
++
++      if (!pm_data->port_enable) {
++              mif_err("port power func not assinged\n");
++              return -ENODEV;
++      }
++
++      err = pm_data->port_enable(2, 0);
++      if (err < 0)
++              mif_err("hub off fail err=%d\n", err);
++
++      pm_data->hub_status = HUB_STATE_OFF;
++
++      /* this function is atomic.
++       * make force disconnect in workqueue..
++       */
++      if (pm_data->usb_ld->if_usb_connected)
++              schedule_work(&usb_ld->disconnect_work);
++
++      return err;
++}
++
++bool link_pm_set_active(struct usb_link_device *usb_ld)
++{
++      int ret;
++      struct link_pm_data *pm_data = usb_ld->link_pm_data;
++
++      if (has_hub(usb_ld)) {
++              if (pm_data->hub_status != HUB_STATE_ACTIVE) {
++                      INIT_COMPLETION(pm_data->hub_active);
++                      SET_SLAVE_WAKEUP(usb_ld->pdata, 1);
++                      ret = wait_for_completion_timeout(&pm_data->hub_active,
++                              msecs_to_jiffies(2000));
++                      if (!ret) { /*timeout*/
++                              mif_err("hub on timeout - retry\n");
++                              SET_SLAVE_WAKEUP(usb_ld->pdata, 0);
++                              queue_delayed_work(usb_ld->ld.tx_wq,
++                                              &usb_ld->ld.tx_delayed_work, 0);
++                              return false;
++                      }
++              }
++      } else {
++              /* TODO do something */
++      }
++      return true;
++}
++
++static long link_pm_ioctl(struct file *file, unsigned int cmd,
++                                              unsigned long arg)
++{
++      int value, err = 0;
++      struct link_pm_data *pm_data = file->private_data;
++      struct usb_link_device *usb_ld = pm_data->usb_ld;
++
++      mif_info("cmd: 0x%08x\n", cmd);
++
++      switch (cmd) {
++      case IOCTL_LINK_CONTROL_ACTIVE:
++              if (copy_from_user(&value, (const void __user *)arg,
++                                                      sizeof(int)))
++                      return -EFAULT;
++              gpio_set_value(pm_data->gpio_link_active, value);
++              break;
++      case IOCTL_LINK_GET_HOSTWAKE:
++              return !gpio_get_value(pm_data->gpio_link_hostwake);
++      case IOCTL_LINK_CONNECTED:
++              return usb_ld->if_usb_connected;
++      case IOCTL_LINK_PORT_ON:
++              /* ignore cp host wakeup irq, set the hub_init_lock when AP try
++               CP off and release hub_init_lock when CP boot done */
++              pm_data->hub_init_lock = 0;
++              if (pm_data->root_hub)
++                      pm_runtime_get_sync(pm_data->root_hub);
++              if (pm_data->port_enable) {
++                      err = pm_data->port_enable(2, 1);
++                      if (err < 0) {
++                              mif_err("hub on fail err=%d\n", err);
++                              goto exit;
++                      }
++                      pm_data->hub_status = HUB_STATE_RESUMMING;
++              }
++              break;
++      case IOCTL_LINK_PORT_OFF:
++              err = link_pm_hub_standby(pm_data);
++              if (err < 0) {
++                      mif_err("usb3503 active fail\n");
++                      goto exit;
++              }
++              pm_data->hub_init_lock = 1;
++              pm_data->hub_handshake_done = 0;
++              break;
++      default:
++              break;
++      }
++exit:
++      return err;
++}
++
++static ssize_t show_autosuspend(struct device *dev,
++              struct device_attribute *attr, char *buf)
++{
++      char *p = buf;
++      struct miscdevice *miscdev = dev_get_drvdata(dev);
++      struct link_pm_data *pm_data = container_of(miscdev,
++                      struct link_pm_data, miscdev);
++      struct usb_link_device *usb_ld = pm_data->usb_ld;
++
++      p += sprintf(buf, "%s\n", pm_data->autosuspend ? "on" : "off");
++
++      return p - buf;
++}
++
++static ssize_t store_autosuspend(struct device *dev,
++              struct device_attribute *attr, const char *buf, size_t count)
++{
++      struct miscdevice *miscdev = dev_get_drvdata(dev);
++      struct link_pm_data *pm_data = container_of(miscdev,
++                      struct link_pm_data, miscdev);
++      struct usb_link_device *usb_ld = pm_data->usb_ld;
++      struct task_struct *task = get_current();
++      char taskname[TASK_COMM_LEN];
++
++      mif_info("autosuspend: %s: %s(%d)'\n",
++                      buf, get_task_comm(taskname, task), task->pid);
++
++      if (!strncmp(buf, "on", 2)) {
++              pm_data->autosuspend = true;
++              if (usb_ld->usbdev)
++                      pm_runtime_allow(&usb_ld->usbdev->dev);
++      } else if (!strncmp(buf, "off", 3)) {
++              pm_data->autosuspend = false;
++              if (usb_ld->usbdev)
++                      pm_runtime_forbid(&usb_ld->usbdev->dev);
++      }
++
++      return count;
++}
++
++static struct device_attribute attr_autosuspend =
++              __ATTR(autosuspend, S_IRUGO | S_IWUSR,
++              show_autosuspend, store_autosuspend);
++
++static int link_pm_open(struct inode *inode, struct file *file)
++{
++      struct link_pm_data *pm_data =
++              (struct link_pm_data *)file->private_data;
++      file->private_data = (void *)pm_data;
++      return 0;
++}
++
++static int link_pm_release(struct inode *inode, struct file *file)
++{
++      file->private_data = NULL;
++      return 0;
++}
++
++static const struct file_operations link_pm_fops = {
++      .owner = THIS_MODULE,
++      .open = link_pm_open,
++      .release = link_pm_release,
++      .unlocked_ioctl = link_pm_ioctl,
++};
++
++static int link_pm_notifier_event(struct notifier_block *this,
++                              unsigned long event, void *ptr)
++{
++      struct link_pm_data *pm_data =
++                      container_of(this, struct link_pm_data, pm_notifier);
++      struct usb_link_device *usb_ld = pm_data->usb_ld;
++
++      switch (event) {
++      case PM_SUSPEND_PREPARE:
++              pm_data->dpm_suspending = true;
++              if (has_hub(usb_ld))
++                      link_pm_hub_standby(pm_data);
++              return NOTIFY_OK;
++      case PM_POST_SUSPEND:
++              pm_data->dpm_suspending = false;
++              return NOTIFY_OK;
++      }
++      return NOTIFY_DONE;
++}
++
++int link_pm_init(struct usb_link_device *usb_ld, void *data)
++{
++      int err;
++      int irq;
++      struct platform_device *pdev = (struct platform_device *)data;
++      struct modem_data *pdata =
++                      (struct modem_data *)pdev->dev.platform_data;
++      struct modemlink_pm_data *pm_pdata = pdata->link_pm_data;
++      struct link_pm_data *pm_data =
++                      kzalloc(sizeof(struct link_pm_data), GFP_KERNEL);
++      if (!pm_data) {
++              mif_err("link_pm_data is NULL\n");
++              return -ENOMEM;
++      }
++      /* get link pm data from modemcontrol's platform data */
++      pm_data->gpio_link_active = pm_pdata->gpio_link_active;
++      pm_data->gpio_link_hostwake = pm_pdata->gpio_link_hostwake;
++      pm_data->gpio_link_slavewake = pm_pdata->gpio_link_slavewake;
++      pm_data->link_reconnect = pm_pdata->link_reconnect;
++      pm_data->port_enable = pm_pdata->port_enable;
++      pm_data->freq_lock = pm_pdata->freq_lock;
++      pm_data->freq_unlock = pm_pdata->freq_unlock;
++      pm_data->autosuspend_delay_ms = pm_pdata->autosuspend_delay_ms;
++      pm_data->autosuspend = true;
++
++      pm_data->usb_ld = usb_ld;
++      usb_ld->link_pm_data = pm_data;
++
++      pm_data->miscdev.minor = MISC_DYNAMIC_MINOR;
++      pm_data->miscdev.name = "link_pm";
++      pm_data->miscdev.fops = &link_pm_fops;
++
++      err = misc_register(&pm_data->miscdev);
++      if (err < 0) {
++              mif_err("fail to register pm device(%d)\n", err);
++              goto err_misc_register;
++      }
++
++      err = device_create_file(pm_data->miscdev.this_device,
++                      &attr_autosuspend);
++      if (err) {
++              mif_err("fail to create file: autosuspend: %d\n", err);
++              goto err_create_file;
++      }
++
++      pm_data->hub_init_lock = 1;
++      irq = gpio_to_irq(usb_ld->pdata->gpio_host_wakeup);
++      err = request_threaded_irq(irq, NULL, usb_resume_irq,
++              IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "modem_usb_wake", usb_ld);
++      if (err) {
++              mif_err("Failed to allocate an interrupt(%d)\n", irq);
++              goto err_request_irq;
++      }
++      enable_irq_wake(irq);
++
++      pm_data->has_usbhub = pm_pdata->has_usbhub;
++
++      if (has_hub(usb_ld)) {
++              init_completion(&pm_data->hub_active);
++              pm_data->hub_status = HUB_STATE_OFF;
++              pm_data->hub_handshake_done = 0;
++              pm_data->root_hub = NULL;
++
++              pm_pdata->hub_standby = link_pm_hub_standby;
++              pm_pdata->hub_pm_data = pm_data;
++
++              wake_lock_init(&pm_data->hub_lock, WAKE_LOCK_SUSPEND,
++                              "modem_hub_enum_lock");
++              INIT_DELAYED_WORK(&pm_data->link_pm_hub, link_pm_hub_work);
++              pm_data->hub_work_running = false;
++      }
++
++      pm_data->pm_notifier.notifier_call = link_pm_notifier_event;
++      register_pm_notifier(&pm_data->pm_notifier);
++
++      return 0;
++
++err_request_irq:
++err_create_file:
++      misc_deregister(&pm_data->miscdev);
++err_misc_register:
++      kfree(pm_data);
++      return err;
++}
+diff --git a/drivers/misc/modem_if/modem_link_pm_usb.h b/drivers/misc/modem_if/modem_link_pm_usb.h
+new file mode 100644
+index 0000000..d26af76
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_link_pm_usb.h
+@@ -0,0 +1,65 @@
++/*
++ * Copyright (C) 2012 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#ifndef __MODEM_LINK_PM_USB_H__
++#define __MODEM_LINK_PM_USB_H__
++
++#include <linux/platform_data/modem.h>
++#include "modem_prj.h"
++#include "modem_link_device_usb.h"
++
++struct link_pm_data {
++      struct miscdevice miscdev;
++      struct usb_link_device *usb_ld;
++      unsigned gpio_link_active;
++      unsigned gpio_link_hostwake;
++      unsigned gpio_link_slavewake;
++      int (*link_reconnect)(void);
++      int link_reconnect_cnt;
++
++      struct workqueue_struct *wq;
++      struct completion active_done;
++
++/*USB3503*/
++      struct completion hub_active;
++      int hub_status;
++      bool has_usbhub;
++      /* ignore hub on by host wakeup irq before cp power on*/
++      int hub_init_lock;
++      /* C1 stay disconnect status after send 'a', skip 'a' next enumeration*/
++      int hub_handshake_done;
++      struct wake_lock hub_lock;
++      struct delayed_work link_pm_hub;
++      bool hub_work_running;
++      int hub_on_retry_cnt;
++      struct device *root_hub;
++
++      struct notifier_block pm_notifier;
++      bool dpm_suspending;
++
++      int (*port_enable)(int, int);
++
++      int (*freq_lock)(struct device *dev);
++      int (*freq_unlock)(struct device *dev);
++
++      int autosuspend_delay_ms; /* if zero, the default value is used */
++      bool autosuspend;
++};
++
++bool link_pm_set_active(struct usb_link_device *usb_ld);
++bool link_pm_is_connected(struct usb_link_device *usb_ld);
++void link_pm_preactive(struct link_pm_data *pm_data);
++int link_pm_init(struct usb_link_device *usb_ld, void *data);
++
++#endif
+diff --git a/drivers/misc/modem_if/modem_modemctl_device_cbp71.c b/drivers/misc/modem_if/modem_modemctl_device_cbp71.c
+new file mode 100644
+index 0000000..28f2ce7
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_modemctl_device_cbp71.c
+@@ -0,0 +1,233 @@
++/* /linux/drivers/misc/modem_if/modem_modemctl_device_cbp7.1.c
++ *
++ * Copyright (C) 2010 Google, Inc.
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <linux/init.h>
++
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/gpio.h>
++#include <linux/delay.h>
++#include <linux/wait.h>
++#include <linux/sched.h>
++
++#include <linux/platform_data/modem.h>
++#include "modem_prj.h"
++#include "modem_link_device_dpram.h"
++
++#define PIF_TIMEOUT           (180 * HZ)
++#define DPRAM_INIT_TIMEOUT    (15 * HZ)
++
++static int cbp71_on(struct modem_ctl *mc)
++{
++      int RetVal = 0;
++      int dpram_init_RetVal = 0;
++      struct link_device *ld = get_current_link(mc->iod);
++      struct dpram_link_device *dpram_ld = to_dpram_link_device(ld);
++
++      mif_info("cbp71_on()\n");
++
++      if (!mc->gpio_cp_off || !mc->gpio_cp_reset) {
++              mif_err("no gpio data\n");
++              return -ENXIO;
++      }
++      gpio_set_value(mc->gpio_cp_reset, 0);
++      msleep(600);
++      gpio_set_value(mc->gpio_cp_reset, 1);
++      msleep(100);
++      gpio_set_value(mc->gpio_cp_off, 0);
++      msleep(300);
++
++      gpio_set_value(mc->gpio_pda_active, 1);
++
++      mc->iod->modem_state_changed(mc->iod, STATE_BOOTING);
++
++      /* Wait here until the PHONE is up.
++      * Waiting as the this called from IOCTL->UM thread */
++      mif_debug("power control waiting for INT_MASK_CMD_PIF_INIT_DONE\n");
++
++      /* 1HZ = 1 clock tick, 100 default */
++      dpram_ld->clear_interrupt(dpram_ld);
++
++      dpram_init_RetVal =
++              wait_event_interruptible_timeout(
++              dpram_ld->dpram_init_cmd_wait_q,
++                                      dpram_ld->dpram_init_cmd_wait_condition,
++                                      DPRAM_INIT_TIMEOUT);
++
++      if (!dpram_init_RetVal) {
++              /*RetVal will be 0 on timeout, non zero if interrupted */
++              mif_err("INIT_START cmd was not arrived.\n");
++              mif_err("init_cmd_wait_condition is 0 and wait timeout happend\n");
++              return -ENXIO;
++      }
++
++      RetVal = wait_event_interruptible_timeout(
++              dpram_ld->modem_pif_init_done_wait_q,
++                                      dpram_ld->modem_pif_init_wait_condition,
++                                      PIF_TIMEOUT);
++
++      if (!RetVal) {
++              /*RetVal will be 0 on timeout, non zero if interrupted */
++              mif_err("PIF init failed\n");
++              mif_err("pif_init_wait_condition is 0 and wait timeout happend\n");
++              return -ENXIO;
++      }
++
++      mif_debug("complete cbp71_on\n");
++
++      mc->iod->modem_state_changed(mc->iod, STATE_ONLINE);
++
++      return 0;
++}
++
++static int cbp71_off(struct modem_ctl *mc)
++{
++      mif_debug("cbp71_off()\n");
++
++      if (!mc->gpio_cp_off || !mc->gpio_cp_reset) {
++              mif_err("no gpio data\n");
++              return -ENXIO;
++      }
++
++      mif_err("Phone power Off. - do nothing\n");
++
++      mc->iod->modem_state_changed(mc->iod, STATE_OFFLINE);
++
++      return 0;
++}
++
++static int cbp71_reset(struct modem_ctl *mc)
++{
++      int ret = 0;
++
++      mif_debug("cbp71_reset()\n");
++
++      ret = cbp71_off(mc);
++      if (ret)
++              return -ENXIO;
++
++      msleep(100);
++
++      ret = cbp71_on(mc);
++      if (ret)
++              return -ENXIO;
++
++      return 0;
++}
++
++static int cbp71_boot_on(struct modem_ctl *mc)
++{
++      mif_debug("cbp71_boot_on()\n");
++
++      if (!mc->gpio_cp_reset) {
++              mif_err("no gpio data\n");
++              return -ENXIO;
++      }
++      gpio_set_value(mc->gpio_cp_reset, 0);
++      msleep(600);
++      gpio_set_value(mc->gpio_cp_reset, 1);
++
++      mc->iod->modem_state_changed(mc->iod, STATE_BOOTING);
++
++      return 0;
++}
++
++static int cbp71_boot_off(struct modem_ctl *mc)
++{
++      mif_debug("cbp71_boot_off()\n");
++      return 0;
++}
++
++static irqreturn_t phone_active_irq_handler(int irq, void *_mc)
++{
++      int phone_reset = 0;
++      int phone_active_value = 0;
++      int phone_state = 0;
++      struct modem_ctl *mc = (struct modem_ctl *)_mc;
++
++      if (!mc->gpio_cp_reset || !mc->gpio_phone_active) {
++              mif_err("no gpio data\n");
++              return IRQ_HANDLED;
++      }
++
++      phone_reset = gpio_get_value(mc->gpio_cp_reset);
++      phone_active_value = gpio_get_value(mc->gpio_phone_active);
++
++      if (phone_reset && phone_active_value)
++              phone_state = STATE_ONLINE;
++      else if (phone_reset && !phone_active_value)
++              phone_state = STATE_CRASH_EXIT;
++      else
++              phone_state = STATE_OFFLINE;
++
++      if (mc->iod && mc->iod->modem_state_changed)
++              mc->iod->modem_state_changed(mc->iod, phone_state);
++
++      if (phone_active_value)
++              irq_set_irq_type(mc->irq_phone_active, IRQ_TYPE_LEVEL_LOW);
++      else
++              irq_set_irq_type(mc->irq_phone_active, IRQ_TYPE_LEVEL_HIGH);
++
++      mif_info("phone_active_irq_handler : phone_state=%d\n", phone_state);
++
++      return IRQ_HANDLED;
++}
++
++static void cbp71_get_ops(struct modem_ctl *mc)
++{
++      mc->ops.modem_on = cbp71_on;
++      mc->ops.modem_off = cbp71_off;
++      mc->ops.modem_reset = cbp71_reset;
++      mc->ops.modem_boot_on = cbp71_boot_on;
++      mc->ops.modem_boot_off = cbp71_boot_off;
++}
++
++int cbp71_init_modemctl_device(struct modem_ctl *mc,
++                      struct modem_data *pdata)
++{
++      int ret = 0;
++      struct platform_device *pdev;
++
++      mc->gpio_cp_on = pdata->gpio_cp_on;
++      mc->gpio_reset_req_n = pdata->gpio_reset_req_n;
++      mc->gpio_cp_reset = pdata->gpio_cp_reset;
++      mc->gpio_pda_active = pdata->gpio_pda_active;
++      mc->gpio_phone_active = pdata->gpio_phone_active;
++      mc->gpio_cp_dump_int = pdata->gpio_cp_dump_int;
++      mc->gpio_flm_uart_sel = pdata->gpio_flm_uart_sel;
++      mc->gpio_cp_warm_reset = pdata->gpio_cp_warm_reset;
++      mc->gpio_cp_off = pdata->gpio_cp_off;
++
++      pdev = to_platform_device(mc->dev);
++      mc->irq_phone_active = platform_get_irq(pdev, 0);
++
++      cbp71_get_ops(mc);
++
++      /*TODO: check*/
++      ret = request_irq(mc->irq_phone_active, phone_active_irq_handler,
++                      IRQF_TRIGGER_HIGH, "phone_active", mc);
++      if (ret) {
++              mif_err("failed to irq_phone_active request_irq: %d\n"
++                      , ret);
++              return ret;
++      }
++
++      ret = enable_irq_wake(mc->irq_phone_active);
++      if (ret)
++              mif_err("failed to enable_irq_wake:%d\n", ret);
++
++      return ret;
++}
+diff --git a/drivers/misc/modem_if/modem_modemctl_device_cbp72.c b/drivers/misc/modem_if/modem_modemctl_device_cbp72.c
+new file mode 100644
+index 0000000..2617be8
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_modemctl_device_cbp72.c
+@@ -0,0 +1,273 @@
++/* /linux/drivers/misc/modem_if/modem_modemctl_device_cbp7.1.c
++ *
++ * Copyright (C) 2010 Google, Inc.
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <linux/init.h>
++
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/gpio.h>
++#include <linux/delay.h>
++#include <linux/wait.h>
++#include <linux/sched.h>
++#include <linux/platform_device.h>
++
++#include <linux/platform_data/modem.h>
++#include "modem_prj.h"
++#include "modem_link_device_dpram.h"
++
++#define PIF_TIMEOUT           (180 * HZ)
++#define DPRAM_INIT_TIMEOUT    (30 * HZ)
++
++
++static irqreturn_t phone_active_handler(int irq, void *arg)
++{
++      struct modem_ctl *mc = (struct modem_ctl *)arg;
++      int phone_reset = gpio_get_value(mc->gpio_cp_reset);
++      int phone_active = gpio_get_value(mc->gpio_phone_active);
++      int phone_state = mc->phone_state;
++
++      mif_info("state = %d, phone_reset = %d, phone_active = %d\n",
++              phone_state, phone_reset, phone_active);
++
++      if (phone_reset && phone_active) {
++              if (mc->phone_state == STATE_BOOTING) {
++                      phone_state = STATE_ONLINE;
++                      mc->bootd->modem_state_changed(mc->bootd, phone_state);
++              }
++      } else if (phone_reset && !phone_active) {
++              if (mc->phone_state == STATE_ONLINE) {
++                      phone_state = STATE_CRASH_EXIT;
++                      mc->bootd->modem_state_changed(mc->bootd, phone_state);
++              }
++      } else {
++              phone_state = STATE_OFFLINE;
++              if (mc->bootd && mc->bootd->modem_state_changed)
++                      mc->bootd->modem_state_changed(mc->bootd, phone_state);
++      }
++
++      if (phone_active)
++              irq_set_irq_type(mc->irq_phone_active, IRQ_TYPE_LEVEL_LOW);
++      else
++              irq_set_irq_type(mc->irq_phone_active, IRQ_TYPE_LEVEL_HIGH);
++
++      mif_info("phone_state = %d\n", phone_state);
++
++      return IRQ_HANDLED;
++}
++
++static int cbp72_on(struct modem_ctl *mc)
++{
++      mif_info("start!!!\n");
++
++      /* prevent sleep during bootloader downloading */
++      if (!wake_lock_active(&mc->mc_wake_lock))
++              wake_lock(&mc->mc_wake_lock);
++
++      gpio_set_value(mc->gpio_cp_on, 0);
++      if (mc->gpio_cp_off)
++              gpio_set_value(mc->gpio_cp_off, 1);
++      gpio_set_value(mc->gpio_cp_reset, 0);
++
++      msleep(500);
++
++      gpio_set_value(mc->gpio_cp_on, 1);
++      if (mc->gpio_cp_off)
++              gpio_set_value(mc->gpio_cp_off, 0);
++
++      msleep(100);
++
++      gpio_set_value(mc->gpio_cp_reset, 1);
++
++      msleep(300);
++
++      gpio_set_value(mc->gpio_pda_active, 1);
++
++      mc->bootd->modem_state_changed(mc->bootd, STATE_BOOTING);
++
++      mif_info("complete!!!\n");
++
++      return 0;
++}
++
++static int cbp72_off(struct modem_ctl *mc)
++{
++      mif_info("cbp72_off()\n");
++
++      if (!mc->gpio_cp_off || !mc->gpio_cp_reset) {
++              mif_err("no gpio data\n");
++              return -ENXIO;
++      }
++
++      gpio_set_value(mc->gpio_cp_reset, 0);
++      gpio_set_value(mc->gpio_cp_on, 0);
++      gpio_set_value(mc->gpio_cp_off, 1);
++
++      mc->bootd->modem_state_changed(mc->bootd, STATE_OFFLINE);
++
++      return 0;
++}
++
++static int cbp72_reset(struct modem_ctl *mc)
++{
++      int ret = 0;
++
++      mif_debug("cbp72_reset()\n");
++
++      ret = cbp72_off(mc);
++      if (ret)
++              return -ENXIO;
++
++      msleep(100);
++
++      ret = cbp72_on(mc);
++      if (ret)
++              return -ENXIO;
++
++      return 0;
++}
++
++static int cbp72_boot_on(struct modem_ctl *mc)
++{
++      mif_info("\n");
++
++      if (!mc->gpio_cp_reset) {
++              mif_err("no gpio data\n");
++              return -ENXIO;
++      }
++
++      gpio_set_value(mc->gpio_cp_reset, 0);
++
++      msleep(600);
++
++      gpio_set_value(mc->gpio_cp_reset, 1);
++
++      mc->bootd->modem_state_changed(mc->bootd, STATE_BOOTING);
++
++      return 0;
++}
++
++static int cbp72_boot_off(struct modem_ctl *mc)
++{
++      int ret;
++      struct link_device *ld = get_current_link(mc->bootd);
++      struct dpram_link_device *dpld = to_dpram_link_device(ld);
++      mif_debug("\n");
++      /* Wait here until the PHONE is up.
++       * Waiting as the this called from IOCTL->UM thread */
++      mif_info("Waiting for INT_CMD_PHONE_START\n");
++      ret = wait_for_completion_interruptible_timeout(
++                      &dpld->dpram_init_cmd, DPRAM_INIT_TIMEOUT);
++      if (!ret) {
++              /* ret == 0 on timeout, ret < 0 if interrupted */
++              mif_err("Timeout!!! (PHONE_START was not arrived.)\n");
++              return -ENXIO;
++      }
++
++      mif_info("Waiting for INT_CMD_PIF_INIT_DONE\n");
++      ret = wait_for_completion_interruptible_timeout(
++                      &dpld->modem_pif_init_done, PIF_TIMEOUT);
++      if (!ret) {
++              mif_err("Timeout!!! (PIF_INIT_DONE was not arrived.)\n");
++              return -ENXIO;
++      }
++      mc->bootd->modem_state_changed(mc->bootd, STATE_ONLINE);
++
++      wake_unlock(&mc->mc_wake_lock);
++
++      return 0;
++}
++
++static int cbp72_force_crash_exit(struct modem_ctl *mc)
++{
++      struct link_device *ld = get_current_link(mc->bootd);
++
++      mif_err("device = %s\n", mc->bootd->name);
++
++      /* Make DUMP start */
++      ld->force_dump(ld, mc->bootd);
++
++      msleep_interruptible(1000);
++
++      mc->bootd->modem_state_changed(mc->bootd, STATE_CRASH_EXIT);
++
++      return 0;
++}
++
++static void cbp72_get_ops(struct modem_ctl *mc)
++{
++      mc->ops.modem_on = cbp72_on;
++      mc->ops.modem_off = cbp72_off;
++      mc->ops.modem_reset = cbp72_reset;
++      mc->ops.modem_boot_on = cbp72_boot_on;
++      mc->ops.modem_boot_off = cbp72_boot_off;
++      mc->ops.modem_force_crash_exit = cbp72_force_crash_exit;
++}
++
++int cbp72_init_modemctl_device(struct modem_ctl *mc, struct modem_data *pdata)
++{
++      int ret = 0;
++      int irq = 0;
++      unsigned long flag = 0;
++      struct platform_device *pdev = NULL;
++
++      mc->gpio_cp_on         = pdata->gpio_cp_on;
++      mc->gpio_cp_off        = pdata->gpio_cp_off;
++      mc->gpio_reset_req_n   = pdata->gpio_reset_req_n;
++      mc->gpio_cp_reset      = pdata->gpio_cp_reset;
++      mc->gpio_pda_active    = pdata->gpio_pda_active;
++      mc->gpio_phone_active  = pdata->gpio_phone_active;
++      mc->gpio_cp_dump_int   = pdata->gpio_cp_dump_int;
++      mc->gpio_flm_uart_sel  = pdata->gpio_flm_uart_sel;
++      mc->gpio_cp_warm_reset = pdata->gpio_cp_warm_reset;
++
++      if (!mc->gpio_cp_on || !mc->gpio_cp_reset || !mc->gpio_phone_active) {
++              mif_err("no GPIO data\n");
++              return -ENXIO;
++      }
++
++      gpio_set_value(mc->gpio_cp_reset, 0);
++      if (mc->gpio_cp_off)
++              gpio_set_value(mc->gpio_cp_off, 1);
++      gpio_set_value(mc->gpio_cp_on, 0);
++
++      cbp72_get_ops(mc);
++
++      pdev = to_platform_device(mc->dev);
++      mc->irq_phone_active = platform_get_irq_byname(pdev, "cp_active_irq");
++      if (!mc->irq_phone_active) {
++              mif_err("get irq fail\n");
++              return -1;
++      }
++
++      irq = mc->irq_phone_active;
++      mif_info("PHONE_ACTIVE IRQ# = %d\n", irq);
++
++      flag = IRQF_TRIGGER_HIGH;
++      ret = request_irq(irq, phone_active_handler, flag, "cbp_active", mc);
++      if (ret) {
++              mif_err("request_irq fail (%d)\n", ret);
++              return ret;
++      }
++
++      wake_lock_init(&mc->mc_wake_lock, WAKE_LOCK_SUSPEND, "cbp72_wake_lock");
++
++      ret = enable_irq_wake(irq);
++      if (ret)
++              mif_err("enable_irq_wake fail (%d)\n", ret);
++
++      return 0;
++}
++
+diff --git a/drivers/misc/modem_if/modem_modemctl_device_cmc221.c b/drivers/misc/modem_if/modem_modemctl_device_cmc221.c
+new file mode 100644
+index 0000000..eddc91a
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_modemctl_device_cmc221.c
+@@ -0,0 +1,317 @@
++/* /linux/drivers/misc/modem_if/modem_modemctl_device_cmc221.c
++ *
++ * Copyright (C) 2010 Google, Inc.
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++#include <linux/init.h>
++
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/gpio.h>
++#include <linux/delay.h>
++#include <linux/platform_device.h>
++
++#include <linux/platform_data/modem.h>
++#include "modem_prj.h"
++#include "modem_link_device_usb.h"
++#include "modem_link_device_dpram.h"
++#include "modem_utils.h"
++
++#define PIF_TIMEOUT           (180 * HZ)
++#define DPRAM_INIT_TIMEOUT    (30 * HZ)
++
++static void mc_state_fsm(struct modem_ctl *mc)
++{
++      struct link_device *ld = get_current_link(mc->iod);
++      int cp_on = gpio_get_value(mc->gpio_cp_on);
++      int cp_reset  = gpio_get_value(mc->gpio_cp_reset);
++      int cp_active = gpio_get_value(mc->gpio_phone_active);
++      int old_state = mc->phone_state;
++      int new_state = mc->phone_state;
++
++      mif_err("%s: old_state:%d cp_on:%d cp_reset:%d cp_active:%d\n",
++              mc->name, old_state, cp_on, cp_reset, cp_active);
++
++      if (!cp_active) {
++              if (!cp_on) {
++                      gpio_set_value(mc->gpio_cp_reset, 0);
++                      new_state = STATE_OFFLINE;
++                      ld->mode = LINK_MODE_OFFLINE;
++                      mif_err("%s: new_state = PHONE_PWR_OFF\n", mc->name);
++              } else if (old_state == STATE_ONLINE) {
++                      new_state = STATE_CRASH_EXIT;
++                      mif_err("%s: new_state = CRASH_EXIT\n", mc->name);
++              } else {
++                      mif_err("%s: Don't care!!!\n", mc->name);
++              }
++      }
++
++      if (old_state != new_state) {
++              mc->bootd->modem_state_changed(mc->bootd, new_state);
++              mc->iod->modem_state_changed(mc->iod, new_state);
++      }
++}
++
++static irqreturn_t phone_active_handler(int irq, void *arg)
++{
++      struct modem_ctl *mc = (struct modem_ctl *)arg;
++      int cp_reset  = gpio_get_value(mc->gpio_cp_reset);
++
++      if (cp_reset)
++              mc_state_fsm(mc);
++
++      return IRQ_HANDLED;
++}
++
++/* TX dynamic switching between DPRAM and USB in one modem */
++static irqreturn_t dynamic_switching_handler(int irq, void *arg)
++{
++      struct modem_ctl *mc = (struct modem_ctl *)arg;
++      int txpath = gpio_get_value(mc->gpio_dynamic_switching);
++      bool enumerated = usb_is_enumerated(mc->msd);
++
++      mif_err("txpath=%d, enumeration=%d\n", txpath, enumerated);
++
++      /* do not switch to USB, when USB is not enumerated. */
++      if (!enumerated && txpath) {
++              mc->need_switch_to_usb = true;
++              return IRQ_HANDLED;
++      }
++
++      mc->need_switch_to_usb = false;
++      rawdevs_set_tx_link(mc->msd, txpath ? LINKDEV_USB : LINKDEV_DPRAM);
++
++      return IRQ_HANDLED;
++}
++
++static int cmc221_on(struct modem_ctl *mc)
++{
++      struct link_device *ld = get_current_link(mc->iod);
++
++      if (!wake_lock_active(&mc->mc_wake_lock))
++              wake_lock(&mc->mc_wake_lock);
++      set_sromc_access(true);
++
++      mc->phone_state = STATE_OFFLINE;
++      ld->mode = LINK_MODE_OFFLINE;
++
++      mif_err("%s\n", mc->name);
++
++      disable_irq_nosync(mc->irq_phone_active);
++
++      gpio_set_value(mc->gpio_cp_on, 0);
++      msleep(100);
++
++      gpio_set_value(mc->gpio_cp_reset, 0);
++      msleep(500);
++
++      gpio_set_value(mc->gpio_cp_on, 1);
++      msleep(100);
++
++      gpio_set_value(mc->gpio_cp_reset, 1);
++
++      return 0;
++}
++
++static int cmc221_off(struct modem_ctl *mc)
++{
++      int cp_on = gpio_get_value(mc->gpio_cp_on);
++
++      mif_err("%s\n", mc->name);
++
++      if (mc->phone_state == STATE_OFFLINE || cp_on == 0)
++              return 0;
++
++      if (!wake_lock_active(&mc->mc_wake_lock))
++              wake_lock(&mc->mc_wake_lock);
++      set_sromc_access(true);
++
++      gpio_set_value(mc->gpio_cp_on, 0);
++
++      return 0;
++}
++
++static int cmc221_force_crash_exit(struct modem_ctl *mc)
++{
++      struct link_device *ld = get_current_link(mc->bootd);
++
++      mif_err("%s\n", mc->name);
++
++      /* Make DUMP start */
++      ld->force_dump(ld, mc->bootd);
++
++      return 0;
++}
++
++static int cmc221_dump_reset(struct modem_ctl *mc)
++{
++      mif_err("%s\n", mc->name);
++
++      if (!wake_lock_active(&mc->mc_wake_lock))
++              wake_lock(&mc->mc_wake_lock);
++      set_sromc_access(true);
++
++      gpio_set_value(mc->gpio_host_active, 0);
++      gpio_set_value(mc->gpio_cp_reset, 0);
++
++      udelay(200);
++
++      gpio_set_value(mc->gpio_cp_reset, 1);
++
++      msleep(300);
++
++      return 0;
++}
++
++static int cmc221_reset(struct modem_ctl *mc)
++{
++      mif_err("%s\n", mc->name);
++
++      if (cmc221_off(mc))
++              return -ENXIO;
++
++      msleep(100);
++
++      if (cmc221_on(mc))
++              return -ENXIO;
++
++      return 0;
++}
++
++static int cmc221_boot_on(struct modem_ctl *mc)
++{
++      mif_err("%s\n", mc->name);
++
++      gpio_set_value(mc->gpio_pda_active, 1);
++
++      mc->bootd->modem_state_changed(mc->bootd, STATE_BOOTING);
++      mc->iod->modem_state_changed(mc->iod, STATE_BOOTING);
++
++      return 0;
++}
++
++static int cmc221_boot_off(struct modem_ctl *mc)
++{
++      int ret;
++      struct link_device *ld = get_current_link(mc->bootd);
++      struct dpram_link_device *dpld = to_dpram_link_device(ld);
++
++      mif_err("%s\n", mc->name);
++
++      ret = wait_for_completion_interruptible_timeout(&dpld->dpram_init_cmd,
++                      DPRAM_INIT_TIMEOUT);
++      if (!ret) {
++              /* ret == 0 on timeout, ret < 0 if interrupted */
++              mif_err("%s: ERR! timeout (CP_START not arrived)\n", mc->name);
++              return -ENXIO;
++      }
++
++      enable_irq(mc->irq_phone_active);
++
++      return 0;
++}
++
++static int cmc221_boot_done(struct modem_ctl *mc)
++{
++      mif_err("%s\n", mc->name);
++
++      set_sromc_access(false);
++      if (wake_lock_active(&mc->mc_wake_lock))
++              wake_unlock(&mc->mc_wake_lock);
++
++      return 0;
++}
++
++static void cmc221_get_ops(struct modem_ctl *mc)
++{
++      mc->ops.modem_on = cmc221_on;
++      mc->ops.modem_off = cmc221_off;
++      mc->ops.modem_reset = cmc221_reset;
++      mc->ops.modem_boot_on = cmc221_boot_on;
++      mc->ops.modem_boot_off = cmc221_boot_off;
++      mc->ops.modem_boot_done = cmc221_boot_done;
++      mc->ops.modem_force_crash_exit = cmc221_force_crash_exit;
++      mc->ops.modem_dump_reset = cmc221_dump_reset;
++}
++
++int cmc221_init_modemctl_device(struct modem_ctl *mc, struct modem_data *pdata)
++{
++      int ret = 0;
++      int irq = 0;
++      unsigned long flag = 0;
++      struct platform_device *pdev = NULL;
++
++      mc->gpio_cp_on        = pdata->gpio_cp_on;
++      mc->gpio_cp_reset     = pdata->gpio_cp_reset;
++      mc->gpio_phone_active = pdata->gpio_phone_active;
++      mc->gpio_pda_active   = pdata->gpio_pda_active;
++#if 0 /*TODO: check the GPIO map*/
++      mc->gpio_cp_dump_int  = pdata->gpio_cp_dump_int;
++      mc->gpio_flm_uart_sel = pdata->gpio_flm_uart_sel;
++      mc->gpio_slave_wakeup = pdata->gpio_slave_wakeup;
++      mc->gpio_host_active  = pdata->gpio_host_active;
++      mc->gpio_host_wakeup  = pdata->gpio_host_wakeup;
++#endif
++      mc->gpio_dynamic_switching = pdata->gpio_dynamic_switching;
++      mc->need_switch_to_usb = false;
++
++      if (!mc->gpio_cp_on || !mc->gpio_cp_reset || !mc->gpio_phone_active) {
++              mif_err("%s: ERR! no GPIO data\n", mc->name);
++              return -ENXIO;
++      }
++
++      gpio_set_value(mc->gpio_cp_reset, 0);
++      gpio_set_value(mc->gpio_cp_on, 0);
++
++      cmc221_get_ops(mc);
++      dev_set_drvdata(mc->dev, mc);
++
++      pdev = to_platform_device(mc->dev);
++      mc->irq_phone_active = platform_get_irq_byname(pdev, STR_CP_ACTIVE_IRQ);
++      if (!mc->irq_phone_active) {
++              mif_err("%s: ERR! get cp_active_irq fail\n", mc->name);
++              return -1;
++      }
++      mif_err("%s: PHONE_ACTIVE IRQ# = %d\n", mc->name, mc->irq_phone_active);
++
++      wake_lock_init(&mc->mc_wake_lock, WAKE_LOCK_SUSPEND, "cmc_wake_lock");
++
++      flag = IRQF_TRIGGER_FALLING | IRQF_NO_SUSPEND;
++      irq = mc->irq_phone_active;
++      ret = request_irq(irq, phone_active_handler, flag, "cmc_active", mc);
++      if (ret) {
++              mif_err("%s: ERR! request_irq(#%d) fail (err %d)\n",
++                      mc->name, irq, ret);
++              return ret;
++      }
++      ret = enable_irq_wake(irq);
++      if (ret) {
++              mif_err("%s: WARNING! enable_irq_wake(#%d) fail (err %d)\n",
++                      mc->name, irq, ret);
++      }
++
++      flag = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_NO_SUSPEND;
++      if (mc->gpio_dynamic_switching) {
++              irq = gpio_to_irq(mc->gpio_dynamic_switching);
++              mif_err("%s: DYNAMIC_SWITCH IRQ# = %d\n", mc->name, irq);
++              ret = request_irq(irq, dynamic_switching_handler, flag,
++                              "dynamic_switching", mc);
++              if (ret) {
++                      mif_err("%s: ERR! request_irq(#%d) fail (err %d)\n",
++                              mc->name, irq, ret);
++                      return ret;
++              }
++      }
++
++      return 0;
++}
+diff --git a/drivers/misc/modem_if/modem_modemctl_device_esc6270.c b/drivers/misc/modem_if/modem_modemctl_device_esc6270.c
+new file mode 100644
+index 0000000..f35e4cc
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_modemctl_device_esc6270.c
+@@ -0,0 +1,348 @@
++/* /linux/drivers/misc/modem_if/modem_modemctl_device_esc6270.c
++ *
++ * Copyright (C) 2010 Google, Inc.
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <linux/init.h>
++
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/gpio.h>
++#include <linux/delay.h>
++#include <linux/wait.h>
++#include <linux/sched.h>
++#include <linux/platform_device.h>
++
++#include <linux/platform_data/modem.h>
++#include "modem_prj.h"
++#include <linux/regulator/consumer.h>
++
++#include <plat/gpio-cfg.h>
++
++#if defined(CONFIG_LINK_DEVICE_DPRAM)
++#include "modem_link_device_dpram.h"
++#elif defined(CONFIG_LINK_DEVICE_PLD)
++#include "modem_link_device_pld.h"
++#endif
++
++#if defined(CONFIG_LINK_DEVICE_DPRAM) || defined(CONFIG_LINK_DEVICE_PLD)
++#include <linux/mfd/max77693.h>
++
++#define PIF_TIMEOUT           (180 * HZ)
++#define DPRAM_INIT_TIMEOUT    (30 * HZ)
++
++static int esc6270_on(struct modem_ctl *mc)
++{
++      int ret;
++      struct link_device *ld = get_current_link(mc->iod);
++
++      pr_info("[MODEM_IF:ESC] <%s> start!!!\n", __func__);
++
++      if (!mc->gpio_cp_reset) {
++              pr_err("[MODEM_IF:ESC] no gpio data\n");
++              return -ENXIO;
++      }
++
++      if (mc->gpio_reset_req_n)
++              gpio_set_value(mc->gpio_reset_req_n, 1);
++
++      gpio_set_value(mc->gpio_cp_reset, 1);
++      msleep(30);
++
++      gpio_set_value(mc->gpio_cp_on, 1);
++      msleep(500);
++
++      gpio_set_value(mc->gpio_cp_on, 0);
++      msleep(500);
++
++      gpio_set_value(mc->gpio_pda_active, 1);
++
++      mc->iod->modem_state_changed(mc->iod, STATE_BOOTING);
++      ld->mode = LINK_MODE_BOOT;
++
++      return 0;
++}
++
++static int esc6270_off(struct modem_ctl *mc)
++{
++      pr_info("[MODEM_IF:ESC] esc6270_off()\n");
++
++#if 1
++      if (!mc->gpio_cp_reset) {
++              pr_err("[MODEM_IF:ESC] no gpio data\n");
++              return -ENXIO;
++      }
++
++      gpio_set_value(mc->gpio_cp_reset, 0);
++      gpio_set_value(mc->gpio_cp_on, 0);
++#endif
++
++      mc->iod->modem_state_changed(mc->iod, STATE_OFFLINE);
++
++      return 0;
++}
++
++static int esc6270_reset(struct modem_ctl *mc)
++{
++      int ret = 0;
++
++      pr_debug("[MODEM_IF:ESC] esc6270_reset()\n");
++
++      ret = esc6270_off(mc);
++      if (ret)
++              return -ENXIO;
++
++      msleep(100);
++
++      ret = esc6270_on(mc);
++      if (ret)
++              return -ENXIO;
++
++      return 0;
++}
++
++int esc6270_boot_on(struct modem_ctl *mc)
++{
++      struct link_device *ld = get_current_link(mc->iod);
++
++      pr_info("[MODEM_IF:ESC] <%s>\n", __func__);
++
++      /* Need to init uart byt gpio_flm_uart_sel GPIO */
++      if (!mc->gpio_cp_reset || !mc->gpio_flm_uart_sel) {
++              pr_err("[MODEM_IF:ESC] no gpio data\n");
++              return -ENXIO;
++      }
++      gpio_set_value(mc->gpio_flm_uart_sel, 1);
++
++      pr_info("  - ESC_PHONE_ON : %d, ESC_RESET_N : %d\n",
++                      gpio_get_value(mc->gpio_cp_on),
++                      gpio_get_value(mc->gpio_cp_reset));
++
++      gpio_set_value(mc->gpio_cp_on, 0);
++      gpio_direction_output(mc->gpio_cp_reset, 0);
++      msleep(100);
++
++      gpio_direction_output(mc->gpio_cp_on, 1);
++      msleep(44);
++
++      pr_info("  - ESC_PHONE_ON : %d, ESC_RESET_N : %d\n",
++                      gpio_get_value(mc->gpio_cp_on),
++                      gpio_get_value(mc->gpio_cp_reset));
++
++      gpio_direction_input(mc->gpio_cp_reset);
++      msleep(600);
++      gpio_direction_output(mc->gpio_cp_on, 0);
++
++      msleep(20);
++      pr_info("  - ESC_PHONE_ON : %d, ESC_RESET_N : %d\n",
++                      gpio_get_value(mc->gpio_cp_on),
++                      gpio_get_value(mc->gpio_cp_reset));
++
++      mc->iod->modem_state_changed(mc->iod, STATE_BOOTING);
++      ld->mode = LINK_MODE_BOOT;
++
++      return 0;
++}
++
++static int esc6270_boot_off(struct modem_ctl *mc)
++{
++      pr_info("[MODEM_IF:ESC] <%s>\n", __func__);
++
++      if (!mc->gpio_flm_uart_sel) {
++              pr_err("[MODEM_IF:ESC] no gpio data\n");
++              return -ENXIO;
++      }
++
++      gpio_set_value(mc->gpio_flm_uart_sel, 0);
++
++      mc->iod->modem_state_changed(mc->iod, STATE_OFFLINE);
++
++      return 0;
++}
++
++static int esc6270_active_count;
++
++static irqreturn_t phone_active_irq_handler(int irq, void *arg)
++{
++      struct modem_ctl *mc = (struct modem_ctl *)arg;
++      int phone_reset = 0;
++      int phone_active = 0;
++      int phone_state = 0;
++      int cp_dump_int = 0;
++
++      if (!mc->gpio_cp_reset ||
++              !mc->gpio_phone_active) { /* || !mc->gpio_cp_dump_int) { */
++              pr_err("[MODEM_IF:ESC] no gpio data\n");
++              return IRQ_HANDLED;
++      }
++
++      phone_reset = gpio_get_value(mc->gpio_cp_reset);
++      phone_active = gpio_get_value(mc->gpio_phone_active);
++      cp_dump_int = gpio_get_value(mc->gpio_cp_dump_int);
++
++      pr_info("[MODEM_IF:ESC] <%s> phone_reset=%d, phone_active=%d, cp_dump_int=%d\n",
++              __func__, phone_reset, phone_active, cp_dump_int);
++
++      if (phone_reset && phone_active) {
++              phone_state = STATE_ONLINE;
++              if (mc->iod && mc->iod->modem_state_changed)
++                      mc->iod->modem_state_changed(mc->iod, phone_state);
++      } else if (phone_reset && !phone_active) {
++              if (mc->phone_state == STATE_ONLINE) {
++                      phone_state = STATE_CRASH_EXIT;
++                      if (mc->iod && mc->iod->modem_state_changed)
++                              mc->iod->modem_state_changed(mc->iod,
++                                                           phone_state);
++              }
++      } else {
++              phone_state = STATE_OFFLINE;
++              if (mc->iod && mc->iod->modem_state_changed)
++                      mc->iod->modem_state_changed(mc->iod, phone_state);
++      }
++
++      if (phone_active)
++              irq_set_irq_type(mc->irq_phone_active, IRQ_TYPE_LEVEL_LOW);
++      else
++              irq_set_irq_type(mc->irq_phone_active, IRQ_TYPE_LEVEL_HIGH);
++
++      pr_info("[MODEM_IF::ESC] <%s> phone_state = %d\n",
++                      __func__, phone_state);
++
++      return IRQ_HANDLED;
++}
++
++#if defined(CONFIG_SIM_DETECT)
++#if defined(CONFIG_MACH_GRANDE)
++static void sim_detect_work(struct work_struct *work)
++{
++      struct modem_ctl *mc =
++              container_of(work, struct modem_ctl, sim_det_dwork.work);
++
++      pr_info("[MODEM_IF:ESC] <%s> gpio_sim_detect = %d\n",
++              __func__, gpio_get_value(mc->gpio_sim_detect));
++
++      if (mc->iod && mc->iod->sim_state_changed)
++              mc->iod->sim_state_changed(mc->iod,
++              !gpio_get_value(mc->gpio_sim_detect));
++}
++#endif
++static irqreturn_t sim_detect_irq_handler(int irq, void *_mc)
++{
++      struct modem_ctl *mc = (struct modem_ctl *)_mc;
++
++      pr_info("[MODEM_IF:ESC] <%s> gpio_sim_detect = %d\n",
++              __func__, gpio_get_value(mc->gpio_sim_detect));
++
++#if defined(CONFIG_MACH_GRANDE)
++      schedule_delayed_work(&mc->sim_det_dwork, msecs_to_jiffies(400));
++#else
++      if (mc->iod && mc->iod->sim_state_changed)
++              mc->iod->sim_state_changed(mc->iod,
++              !gpio_get_value(mc->gpio_sim_detect));
++#endif
++      return IRQ_HANDLED;
++}
++#endif
++
++static void esc6270_get_ops(struct modem_ctl *mc)
++{
++      mc->ops.modem_on = esc6270_on;
++      mc->ops.modem_off = esc6270_off;
++      mc->ops.modem_reset = esc6270_reset;
++      mc->ops.modem_boot_on = esc6270_boot_on;
++      mc->ops.modem_boot_off = esc6270_boot_off;
++}
++
++int esc6270_init_modemctl_device(struct modem_ctl *mc, struct modem_data *pdata)
++{
++      int ret = 0;
++      struct platform_device *pdev;
++
++      mc->gpio_cp_on = pdata->gpio_cp_on;
++      mc->gpio_reset_req_n = pdata->gpio_reset_req_n;
++      mc->gpio_cp_reset = pdata->gpio_cp_reset;
++      mc->gpio_pda_active = pdata->gpio_pda_active;
++      mc->gpio_phone_active = pdata->gpio_phone_active;
++      mc->gpio_cp_dump_int = pdata->gpio_cp_dump_int;
++      mc->gpio_flm_uart_sel = pdata->gpio_flm_uart_sel;
++      mc->gpio_cp_warm_reset = pdata->gpio_cp_warm_reset;
++      mc->gpio_sim_detect = pdata->gpio_sim_detect;
++
++      gpio_set_value(mc->gpio_cp_reset, 0);
++      gpio_set_value(mc->gpio_cp_on, 0);
++
++      pdev = to_platform_device(mc->dev);
++      mc->irq_phone_active = platform_get_irq_byname(pdev, "cp_active_irq");
++      pr_info("[MODEM_IF:ESC] <%s> PHONE_ACTIVE IRQ# = %d\n",
++              __func__, mc->irq_phone_active);
++
++      esc6270_get_ops(mc);
++
++      if (mc->irq_phone_active) {
++              ret = request_irq(mc->irq_phone_active,
++                                phone_active_irq_handler,
++                                IRQF_TRIGGER_HIGH,
++                                "esc_active",
++                                mc);
++              if (ret) {
++                      pr_err("[MODEM_IF:ESC] <%s> failed to request_irq IRQ# %d (err=%d)\n",
++                              __func__, mc->irq_phone_active, ret);
++                      return ret;
++              }
++
++              ret = enable_irq_wake(mc->irq_phone_active);
++              if (ret) {
++                      pr_err("[MODEM_IF:ESC] %s: failed to enable_irq_wake IRQ# %d (err=%d)\n",
++                              __func__, mc->irq_phone_active, ret);
++                      free_irq(mc->irq_phone_active, mc);
++                      return ret;
++              }
++      }
++
++#if defined(CONFIG_SIM_DETECT)
++#if defined(CONFIG_MACH_GRANDE)
++      INIT_DELAYED_WORK(&mc->sim_det_dwork, sim_detect_work);
++#endif
++      mc->irq_sim_detect = platform_get_irq_byname(pdev, "sim_irq");
++      pr_info("[MODEM_IF:ESC] <%s> SIM_DECTCT IRQ# = %d\n",
++              __func__, mc->irq_sim_detect);
++
++      if (mc->irq_sim_detect) {
++              ret = request_irq(mc->irq_sim_detect, sim_detect_irq_handler,
++                      IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
++                      "esc_sim_detect", mc);
++              if (ret) {
++                      mif_err("failed to request_irq: %d\n", ret);
++                              mc->sim_state.online = false;
++                              mc->sim_state.changed = false;
++                      return ret;
++              }
++
++              ret = enable_irq_wake(mc->irq_sim_detect);
++              if (ret) {
++                      mif_err("failed to enable_irq_wake: %d\n", ret);
++                      free_irq(mc->irq_sim_detect, mc);
++                      mc->sim_state.online = false;
++                      mc->sim_state.changed = false;
++                      return ret;
++              }
++
++              /* initialize sim_state => insert: gpio=0, remove: gpio=1 */
++              mc->sim_state.online = !gpio_get_value(mc->gpio_sim_detect);
++      }
++#endif
++
++      return ret;
++}
++#endif
+diff --git a/drivers/misc/modem_if/modem_modemctl_device_mdm6600.c b/drivers/misc/modem_if/modem_modemctl_device_mdm6600.c
+new file mode 100644
+index 0000000..129f790
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_modemctl_device_mdm6600.c
+@@ -0,0 +1,801 @@
++/* /linux/drivers/misc/modem_if/modem_modemctl_device_mdm6600.c
++ *
++ * Copyright (C) 2010 Google, Inc.
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <linux/init.h>
++
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/gpio.h>
++#include <linux/delay.h>
++#include <linux/wait.h>
++#include <linux/sched.h>
++#include <linux/platform_device.h>
++
++#include <linux/platform_data/modem.h>
++#include "modem_prj.h"
++#include <linux/regulator/consumer.h>
++
++#include <plat/gpio-cfg.h>
++
++#if defined(CONFIG_MACH_M0_CTC)
++#include <linux/mfd/max77693.h>
++#endif
++
++#if defined(CONFIG_MACH_U1_KOR_LGT)
++#include <linux/mfd/max8997.h>
++
++static int mdm6600_on(struct modem_ctl *mc)
++{
++      pr_info("[MODEM_IF] mdm6600_on()\n");
++
++      if (!mc->gpio_cp_reset || !mc->gpio_cp_reset_msm || !mc->gpio_cp_on) {
++              pr_err("[MODEM_IF] no gpio data\n");
++              return -ENXIO;
++      }
++
++      gpio_set_value(mc->gpio_pda_active, 0);
++      gpio_set_value(mc->gpio_cp_reset, 1);
++      gpio_set_value(mc->gpio_cp_reset_msm, 1);
++      msleep(30);
++      gpio_set_value(mc->gpio_cp_on, 1);
++      msleep(300);
++      gpio_set_value(mc->gpio_cp_on, 0);
++      msleep(500);
++
++      gpio_set_value(mc->gpio_pda_active, 1);
++
++      mc->iod->modem_state_changed(mc->iod, STATE_BOOTING);
++
++      return 0;
++}
++
++static int mdm6600_off(struct modem_ctl *mc)
++{
++      pr_info("[MODEM_IF] mdm6600_off()\n");
++
++      if (!mc->gpio_cp_reset || !mc->gpio_cp_reset_msm || !mc->gpio_cp_on) {
++              pr_err("[MODEM_IF] no gpio data\n");
++              return -ENXIO;
++      }
++
++      gpio_set_value(mc->gpio_cp_on, 0);
++      gpio_set_value(mc->gpio_cp_reset, 0);
++      gpio_set_value(mc->gpio_cp_reset_msm, 0);
++
++      mc->iod->modem_state_changed(mc->iod, STATE_OFFLINE);
++
++      return 0;
++}
++
++static int mdm6600_reset(struct modem_ctl *mc)
++{
++      int ret;
++
++      pr_info("[MODEM_IF] mdm6600_reset()\n");
++
++      if (!mc->gpio_cp_reset || !mc->gpio_cp_reset_msm || !mc->gpio_cp_on) {
++              pr_err("[MODEM_IF] no gpio data\n");
++              return -ENXIO;
++      }
++
++      if (system_rev >= 0x05) {
++              dev_err(mc->dev, "[%s] system_rev: %d\n", __func__, system_rev);
++
++              gpio_set_value(mc->gpio_cp_reset_msm, 0);
++              msleep(100);    /* no spec, confirm later exactly how much time
++                                 needed to initialize CP with RESET_PMU_N */
++              gpio_set_value(mc->gpio_cp_reset_msm, 1);
++              msleep(40);     /* > 37.2 + 2 msec */
++      } else {
++              dev_err(mc->dev, "[%s] system_rev: %d\n", __func__, system_rev);
++
++              gpio_set_value(mc->gpio_cp_reset, 0);
++              msleep(500);    /* no spec, confirm later exactly how much time
++                                 needed to initialize CP with RESET_PMU_N */
++              gpio_set_value(mc->gpio_cp_reset, 1);
++              msleep(40);     /* > 37.2 + 2 msec */
++      }
++
++      return 0;
++}
++
++static int mdm6600_boot_on(struct modem_ctl *mc)
++{
++      pr_info("[MODEM_IF] mdm6600_boot_on()\n");
++
++      if (!mc->gpio_boot_sw_sel) {
++              pr_err("[MODEM_IF] no gpio data\n");
++              return -ENXIO;
++      }
++
++      if (mc->vbus_on)
++              mc->vbus_on();
++
++      if (mc->gpio_boot_sw_sel)
++              gpio_set_value(mc->gpio_boot_sw_sel, 0);
++      mc->usb_boot = true;
++
++      return 0;
++}
++
++static int mdm6600_boot_off(struct modem_ctl *mc)
++{
++      pr_info("[MODEM_IF] mdm6600_boot_off()\n");
++
++      if (!mc->gpio_boot_sw_sel) {
++              pr_err("[MODEM_IF] no gpio data\n");
++              return -ENXIO;
++      }
++
++      if (mc->vbus_off)
++              mc->vbus_off();
++
++      if (mc->gpio_boot_sw_sel)
++              gpio_set_value(mc->gpio_boot_sw_sel, 1);
++      mc->usb_boot = false;
++
++      return 0;
++}
++
++static int count;
++
++static irqreturn_t phone_active_irq_handler(int irq, void *_mc)
++{
++      int phone_reset = 0;
++      int phone_active_value = 0;
++      int cp_dump_value = 0;
++      int phone_state = 0;
++      struct modem_ctl *mc = (struct modem_ctl *)_mc;
++
++      if (!mc->gpio_cp_reset || !mc->gpio_phone_active
++/*|| !mc->gpio_cp_dump_int */) {
++              pr_err("[MODEM_IF] no gpio data\n");
++              return IRQ_HANDLED;
++      }
++
++      phone_reset = gpio_get_value(mc->gpio_cp_reset);
++      phone_active_value = gpio_get_value(mc->gpio_phone_active);
++
++      pr_info("[MODEM_IF] PA EVENT : reset =%d, pa=%d, cp_dump=%d\n",
++              phone_reset, phone_active_value, cp_dump_value);
++
++      if (phone_reset && phone_active_value) {
++              phone_state = STATE_ONLINE;
++              if (mc->iod && mc->iod->modem_state_changed)
++                      mc->iod->modem_state_changed(mc->iod, phone_state);
++      } else if (phone_reset && !phone_active_value) {
++              if (count == 1) {
++                      phone_state = STATE_CRASH_EXIT;
++                      if (mc->iod) {
++                              ld = get_current_link(mc->iod);
++                              if (ld->terminate_comm)
++                                      ld->terminate_comm(ld, mc->iod);
++                      }
++                      if (mc->iod && mc->iod->modem_state_changed)
++                              mc->iod->modem_state_changed
++                                  (mc->iod, phone_state);
++                      count = 0;
++              } else {
++                      count++;
++              }
++      } else {
++              phone_state = STATE_OFFLINE;
++              if (mc->iod && mc->iod->modem_state_changed)
++                      mc->iod->modem_state_changed(mc->iod, phone_state);
++      }
++
++      pr_info("phone_active_irq_handler : phone_state=%d\n", phone_state);
++
++      return IRQ_HANDLED;
++}
++
++static void mdm6600_get_ops(struct modem_ctl *mc)
++{
++      mc->ops.modem_on = mdm6600_on;
++      mc->ops.modem_off = mdm6600_off;
++      mc->ops.modem_reset = mdm6600_reset;
++      mc->ops.modem_boot_on = mdm6600_boot_on;
++      mc->ops.modem_boot_off = mdm6600_boot_off;
++}
++
++int mdm6600_init_modemctl_device(struct modem_ctl *mc, struct modem_data *pdata)
++{
++      int ret;
++      struct platform_device *pdev;
++
++      mc->gpio_cp_on = pdata->gpio_cp_on;
++      mc->gpio_cp_reset = pdata->gpio_cp_reset;
++      mc->gpio_pda_active = pdata->gpio_pda_active;
++      mc->gpio_phone_active = pdata->gpio_phone_active;
++      mc->gpio_cp_reset_msm = pdata->gpio_cp_reset_msm;
++      mc->gpio_boot_sw_sel = pdata->gpio_boot_sw_sel;
++
++      mc->vbus_on = pdata->vbus_on;
++      mc->vbus_off = pdata->vbus_off;
++
++      pdev = to_platform_device(mc->dev);
++      mc->irq_phone_active = platform_get_irq_byname(pdev, "cp_active_irq");
++      pr_info("[MODEM_IF] <%s> PHONE_ACTIVE IRQ# = %d\n",
++              __func__, mc->irq_phone_active);
++
++      mdm6600_get_ops(mc);
++
++      ret = request_irq(mc->irq_phone_active, phone_active_irq_handler,
++                        IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
++                        "phone_active", mc);
++      if (ret) {
++              pr_err("[MODEM_IF] %s: failed to request_irq:%d\n",
++                     __func__, ret);
++              goto err_request_irq;
++      }
++
++      ret = enable_irq_wake(mc->irq_phone_active);
++      if (ret) {
++              pr_err("[MODEM_IF] %s: failed to enable_irq_wake:%d\n",
++                     __func__, ret);
++              goto err_set_wake_irq;
++      }
++
++      return ret;
++
++ err_set_wake_irq:
++      free_irq(mc->irq_phone_active, mc);
++ err_request_irq:
++      return ret;
++}
++#endif                                /* CONFIG_MACH_U1_KOR_LGT */
++
++#if defined(CONFIG_MACH_M0_CTC) || defined(CONFIG_MACH_T0_CHN_CTC)
++
++#if defined(CONFIG_LINK_DEVICE_DPRAM)
++#include "modem_link_device_dpram.h"
++#elif defined(CONFIG_LINK_DEVICE_PLD)
++#include "modem_link_device_pld.h"
++#endif
++
++#define PIF_TIMEOUT           (180 * HZ)
++#define DPRAM_INIT_TIMEOUT    (30 * HZ)
++
++#if defined(CONFIG_MACH_M0_DUOSCTC) || defined(CONFIG_MACH_M0_GRANDECTC) || \
++      defined(CONFIG_MACH_T0_CHN_CTC)
++static void mdm6600_vbus_on(void)
++{
++      struct regulator *regulator;
++
++      pr_info("[MSM] <%s>\n", __func__);
++
++#if defined(CONFIG_MACH_T0_CHN_CTC)
++      if (system_rev == 4)
++              regulator = regulator_get(NULL, "vcc_1.8v_lcd");
++      else
++              regulator = regulator_get(NULL, "vcc_1.8v_usb");
++#else
++      regulator = regulator_get(NULL, "vusbhub_osc_1.8v");
++#endif
++      if (IS_ERR(regulator)) {
++              pr_err("[MSM] error getting regulator_get <%s>\n", __func__);
++              return ;
++      }
++      regulator_enable(regulator);
++      regulator_put(regulator);
++
++      pr_info("[MSM] <%s> enable\n", __func__);
++}
++
++static void mdm6600_vbus_off(void)
++{
++      struct regulator *regulator;
++
++      pr_info("[MSM] <%s>\n", __func__);
++
++#if defined(CONFIG_MACH_T0_CHN_CTC)
++      if (system_rev == 4)
++              regulator = regulator_get(NULL, "vcc_1.8v_lcd");
++      else
++              regulator = regulator_get(NULL, "vcc_1.8v_usb");
++#else
++      regulator = regulator_get(NULL, "vusbhub_osc_1.8v");
++#endif
++      if (IS_ERR(regulator)) {
++              pr_err("[MSM] error getting regulator_get <%s>\n", __func__);
++              return ;
++      }
++      regulator_disable(regulator);
++      regulator_put(regulator);
++
++      pr_info("[MSM] <%s> disable\n", __func__);
++}
++#endif
++
++static int mdm6600_on(struct modem_ctl *mc)
++{
++      struct link_device *ld = get_current_link(mc->iod);
++
++      pr_info("[MSM] <%s>\n", __func__);
++
++      if (!mc->gpio_reset_req_n || !mc->gpio_cp_reset
++          || !mc->gpio_cp_on || !mc->gpio_pda_active) {
++              pr_err("[MSM] no gpio data\n");
++              return -ENXIO;
++      }
++
++      gpio_set_value(mc->gpio_pda_active, 0);
++
++      gpio_set_value(mc->gpio_cp_on, 1);
++      msleep(500);
++
++      gpio_set_value(mc->gpio_reset_req_n, 1);
++      msleep(50);
++
++      gpio_set_value(mc->gpio_cp_reset, 1);
++      msleep(50);
++
++      gpio_set_value(mc->gpio_cp_on, 0);
++      msleep(500);
++
++      gpio_set_value(mc->gpio_pda_active, 1);
++
++      mc->iod->modem_state_changed(mc->iod, STATE_BOOTING);
++      ld->mode = LINK_MODE_BOOT;
++
++      return 0;
++}
++
++static int mdm6600_off(struct modem_ctl *mc)
++{
++      pr_info("[MSM] <%s>\n", __func__);
++
++      if (!mc->gpio_cp_reset || !mc->gpio_cp_on) {
++              pr_err("[MSM] no gpio data\n");
++              return -ENXIO;
++      }
++
++      gpio_set_value(mc->gpio_cp_reset, 0);
++      gpio_set_value(mc->gpio_reset_req_n, 0);
++      gpio_set_value(mc->gpio_cp_on, 0);
++
++      msleep(200);
++
++      mc->iod->modem_state_changed(mc->iod, STATE_OFFLINE);
++
++      return 0;
++}
++
++static int mdm6600_reset(struct modem_ctl *mc)
++{
++      int ret = 0;
++      struct link_device *ld = get_current_link(mc->iod);
++
++      pr_info("[MSM] <%s>\n", __func__);
++
++      if (!mc->gpio_reset_req_n || !mc->gpio_cp_reset
++          || !mc->gpio_cp_on || !mc->gpio_pda_active) {
++              pr_err("[MSM] no gpio data\n");
++              return -ENXIO;
++      }
++
++      gpio_set_value(mc->gpio_cp_reset, 0);
++      gpio_set_value(mc->gpio_reset_req_n, 0);
++      gpio_set_value(mc->gpio_cp_on, 0);
++
++      msleep(100);
++
++      gpio_set_value(mc->gpio_cp_on, 1);
++      msleep(300);
++
++      gpio_set_value(mc->gpio_reset_req_n, 1);
++      msleep(50);
++
++      gpio_set_value(mc->gpio_cp_reset, 1);
++      msleep(50);
++
++      gpio_set_value(mc->gpio_cp_on, 0);
++      msleep(100);
++
++      gpio_set_value(mc->gpio_pda_active, 1);
++
++      mc->iod->modem_state_changed(mc->iod, STATE_BOOTING);
++      ld->mode = LINK_MODE_BOOT;
++
++      return 0;
++}
++
++static int mdm6600_boot_on(struct modem_ctl *mc)
++{
++      struct regulator *regulator;
++
++      pr_info("[MSM] <%s>\n", __func__);
++
++      if (!mc->gpio_flm_uart_sel) {
++              pr_err("[MSM] no gpio data\n");
++              return -ENXIO;
++      }
++
++#if defined(CONFIG_MACH_M0_DUOSCTC) || defined(CONFIG_MACH_T0_CHN_CTC)
++      mdm6600_vbus_on();
++#elif defined(CONFIG_MACH_M0_GRANDECTC)
++      if (system_rev >= 14)
++              mdm6600_vbus_on();
++#endif
++
++      pr_info("[MSM] <%s> %s\n", __func__, "USB_BOOT_EN initializing");
++      if (system_rev < 11) {
++
++              gpio_direction_output(GPIO_USB_BOOT_EN, 0);
++              s3c_gpio_setpull(GPIO_USB_BOOT_EN, S3C_GPIO_PULL_NONE);
++              gpio_set_value(GPIO_USB_BOOT_EN, 0);
++
++              gpio_direction_output(GPIO_BOOT_SW_SEL, 0);
++              s3c_gpio_setpull(GPIO_BOOT_SW_SEL, S3C_GPIO_PULL_NONE);
++              gpio_set_value(GPIO_BOOT_SW_SEL, 0);
++
++              msleep(100);
++
++              gpio_direction_output(GPIO_USB_BOOT_EN, 1);
++              gpio_set_value(GPIO_USB_BOOT_EN, 1);
++
++              pr_info("[MSM] <%s> USB_BOOT_EN:[%d]\n", __func__,
++                      gpio_get_value(GPIO_USB_BOOT_EN));
++
++              gpio_direction_output(GPIO_BOOT_SW_SEL, 1);
++              gpio_set_value(GPIO_BOOT_SW_SEL, 1);
++
++              pr_info("[MSM] <%s> BOOT_SW_SEL : [%d]\n", __func__,
++                      gpio_get_value(GPIO_BOOT_SW_SEL));
++      } else if (system_rev == 11) {
++              gpio_direction_output(GPIO_USB_BOOT_EN, 0);
++              s3c_gpio_setpull(GPIO_USB_BOOT_EN, S3C_GPIO_PULL_NONE);
++              gpio_set_value(GPIO_USB_BOOT_EN, 0);
++
++              gpio_direction_output(GPIO_USB_BOOT_EN_REV06, 0);
++              s3c_gpio_setpull(GPIO_USB_BOOT_EN_REV06, S3C_GPIO_PULL_NONE);
++              gpio_set_value(GPIO_USB_BOOT_EN_REV06, 0);
++
++              msleep(100);
++
++              gpio_direction_output(GPIO_USB_BOOT_EN, 1);
++              gpio_set_value(GPIO_USB_BOOT_EN, 1);
++
++              pr_info("[MSM] <%s> USB_BOOT_EN:[%d]\n", __func__,
++                      gpio_get_value(GPIO_USB_BOOT_EN));
++
++              gpio_direction_output(GPIO_USB_BOOT_EN_REV06, 1);
++              gpio_set_value(GPIO_USB_BOOT_EN_REV06, 1);
++
++              pr_info("[MSM(%d)] <%s> USB_BOOT_EN:[%d]\n", system_rev,
++                      __func__, gpio_get_value(GPIO_USB_BOOT_EN_REV06));
++
++              gpio_direction_output(GPIO_BOOT_SW_SEL, 0);
++              s3c_gpio_setpull(GPIO_BOOT_SW_SEL, S3C_GPIO_PULL_NONE);
++              gpio_set_value(GPIO_BOOT_SW_SEL, 0);
++
++              gpio_direction_output(GPIO_BOOT_SW_SEL_REV06, 0);
++              s3c_gpio_setpull(GPIO_BOOT_SW_SEL_REV06, S3C_GPIO_PULL_NONE);
++              gpio_set_value(GPIO_BOOT_SW_SEL_REV06, 0);
++
++              msleep(100);
++
++              gpio_direction_output(GPIO_BOOT_SW_SEL, 1);
++              gpio_set_value(GPIO_BOOT_SW_SEL, 1);
++
++              pr_info("[MSM] <%s> BOOT_SW_SEL : [%d]\n", __func__,
++                      gpio_get_value(GPIO_BOOT_SW_SEL));
++
++              gpio_direction_output(GPIO_BOOT_SW_SEL_REV06, 1);
++              gpio_set_value(GPIO_BOOT_SW_SEL_REV06, 1);
++
++              pr_info("[MSM(%d)] <%s> BOOT_SW_SEL : [%d]\n", system_rev,
++                      __func__, gpio_get_value(GPIO_BOOT_SW_SEL_REV06));
++
++      } else {        /* system_rev>11 */
++              gpio_direction_output(GPIO_USB_BOOT_EN_REV06, 0);
++              s3c_gpio_setpull(GPIO_USB_BOOT_EN_REV06, S3C_GPIO_PULL_NONE);
++              gpio_set_value(GPIO_USB_BOOT_EN_REV06, 0);
++
++              gpio_direction_output(GPIO_BOOT_SW_SEL_REV06, 0);
++              s3c_gpio_setpull(GPIO_BOOT_SW_SEL_REV06, S3C_GPIO_PULL_NONE);
++              gpio_set_value(GPIO_BOOT_SW_SEL_REV06, 0);
++
++              msleep(100);
++
++              gpio_direction_output(GPIO_USB_BOOT_EN_REV06, 1);
++              gpio_set_value(GPIO_USB_BOOT_EN_REV06, 1);
++
++              pr_info("[MSM] <%s> USB_BOOT_EN:[%d]\n", __func__,
++                      gpio_get_value(GPIO_USB_BOOT_EN_REV06));
++
++              gpio_direction_output(GPIO_BOOT_SW_SEL_REV06, 1);
++              gpio_set_value(GPIO_BOOT_SW_SEL_REV06, 1);
++
++      pr_info("[MSM] <%s> BOOT_SW_SEL : [%d]\n", __func__,
++                      gpio_get_value(GPIO_BOOT_SW_SEL_REV06));
++
++      }
++
++      mc->iod->modem_state_changed(mc->iod, STATE_BOOTING);
++
++      return 0;
++}
++
++static int mdm6600_boot_off(struct modem_ctl *mc)
++{
++      pr_info("[MSM] <%s>\n", __func__);
++
++      if (!mc->gpio_flm_uart_sel
++#if defined(CONFIG_MACH_M0_CTC)
++              || !mc->gpio_flm_uart_sel_rev06
++#endif
++      ) {
++              pr_err("[MSM] no gpio data\n");
++              return -ENXIO;
++      }
++
++#if defined(CONFIG_MACH_M0_DUOSCTC) || defined(CONFIG_MACH_T0_CHN_CTC)
++      mdm6600_vbus_off();
++#elif defined(CONFIG_MACH_M0_GRANDECTC)
++      if (system_rev >= 14)
++              mdm6600_vbus_off();
++#endif
++
++      if (system_rev < 11) {
++              gpio_direction_output(GPIO_USB_BOOT_EN, 0);
++              s3c_gpio_setpull(GPIO_USB_BOOT_EN, S3C_GPIO_PULL_NONE);
++              gpio_set_value(GPIO_USB_BOOT_EN, 0);
++              gpio_direction_output(GPIO_BOOT_SW_SEL, 0);
++              s3c_gpio_setpull(GPIO_BOOT_SW_SEL, S3C_GPIO_PULL_NONE);
++              gpio_set_value(GPIO_BOOT_SW_SEL, 0);
++
++      } else if (system_rev == 11) {
++              gpio_direction_output(GPIO_USB_BOOT_EN, 0);
++              s3c_gpio_setpull(GPIO_USB_BOOT_EN, S3C_GPIO_PULL_NONE);
++              gpio_set_value(GPIO_USB_BOOT_EN, 0);
++
++              gpio_direction_output(GPIO_BOOT_SW_SEL, 0);
++              s3c_gpio_setpull(GPIO_BOOT_SW_SEL, S3C_GPIO_PULL_NONE);
++              gpio_set_value(GPIO_BOOT_SW_SEL, 0);
++
++#if defined(CONFIG_MACH_M0_CTC)
++              gpio_direction_output(GPIO_USB_BOOT_EN_REV06, 0);
++              s3c_gpio_setpull(GPIO_USB_BOOT_EN_REV06, S3C_GPIO_PULL_NONE);
++              gpio_set_value(GPIO_USB_BOOT_EN_REV06, 0);
++
++              gpio_direction_output(GPIO_BOOT_SW_SEL_REV06, 0);
++              s3c_gpio_setpull(GPIO_BOOT_SW_SEL_REV06, S3C_GPIO_PULL_NONE);
++              gpio_set_value(GPIO_BOOT_SW_SEL_REV06, 0);
++#endif
++
++      } else {        /* system_rev>11 */
++#if defined(CONFIG_MACH_M0_CTC)
++              gpio_direction_output(GPIO_USB_BOOT_EN_REV06, 0);
++              s3c_gpio_setpull(GPIO_USB_BOOT_EN_REV06, S3C_GPIO_PULL_NONE);
++              gpio_set_value(GPIO_USB_BOOT_EN_REV06, 0);
++
++              gpio_direction_output(GPIO_BOOT_SW_SEL_REV06, 0);
++              s3c_gpio_setpull(GPIO_BOOT_SW_SEL_REV06, S3C_GPIO_PULL_NONE);
++              gpio_set_value(GPIO_BOOT_SW_SEL_REV06, 0);
++#endif
++      }
++
++#if defined(CONFIG_MACH_M0_CTC)
++      if (max7693_muic_cp_usb_state()) {
++              msleep(30);
++              gpio_direction_output(GPIO_USB_BOOT_EN, 1);
++              s3c_gpio_setpull(GPIO_USB_BOOT_EN, S3C_GPIO_PULL_NONE);
++              gpio_set_value(GPIO_USB_BOOT_EN, 1);
++              gpio_direction_output(GPIO_USB_BOOT_EN_REV06, 1);
++              s3c_gpio_setpull(GPIO_USB_BOOT_EN_REV06, S3C_GPIO_PULL_NONE);
++              gpio_set_value(GPIO_USB_BOOT_EN_REV06, 1);
++      }
++#endif
++
++      gpio_set_value(GPIO_BOOT_SW_SEL, 0);
++
++      return 0;
++}
++
++
++static int mdm6600_force_crash_exit(struct modem_ctl *mc)
++{
++      pr_info("[MSM] <%s>\n", __func__);
++
++      if (!mc->gpio_cp_reset || !mc->gpio_cp_on) {
++              pr_err("[MSM] no gpio data\n");
++              return -ENXIO;
++      }
++
++      s3c_gpio_cfgpin(mc->gpio_cp_dump_int, S3C_GPIO_OUTPUT);
++      gpio_direction_output(mc->gpio_cp_dump_int, 1);
++
++      gpio_set_value(mc->gpio_cp_reset, 0);
++      gpio_set_value(mc->gpio_cp_on, 0);
++      gpio_set_value(mc->gpio_cp_reset, 1);
++
++      return 0;
++}
++
++static irqreturn_t phone_active_irq_handler(int irq, void *arg)
++{
++      struct modem_ctl *mc = (struct modem_ctl *)arg;
++      int phone_reset = 0;
++      int phone_active = 0;
++      int phone_state = 0;
++      int cp_dump_int = 0;
++
++      if (!mc->gpio_cp_reset ||
++              !mc->gpio_phone_active || !mc->gpio_cp_dump_int) {
++              pr_err("[MSM] no gpio data\n");
++              return IRQ_HANDLED;
++      }
++
++      phone_reset = gpio_get_value(mc->gpio_cp_reset);
++      phone_active = gpio_get_value(mc->gpio_phone_active);
++      cp_dump_int = gpio_get_value(mc->gpio_cp_dump_int);
++
++      pr_info("[MSM] <%s> phone_reset=%d, phone_active=%d, cp_dump_int=%d\n",
++              __func__, phone_reset, phone_active, cp_dump_int);
++
++      if (phone_reset && phone_active) {
++              phone_state = STATE_ONLINE;
++              if (mc->iod && mc->iod->modem_state_changed)
++                      mc->iod->modem_state_changed(mc->iod, phone_state);
++      } else if (phone_reset && !phone_active) {
++              if (mc->phone_state == STATE_ONLINE) {
++                      phone_state = STATE_CRASH_EXIT;
++
++                      if (mc->iod && mc->iod->modem_state_changed)
++                              mc->iod->modem_state_changed(mc->iod,
++                                                           phone_state);
++              }
++      } else {
++              phone_state = STATE_OFFLINE;
++              if (mc->iod && mc->iod->modem_state_changed)
++                      mc->iod->modem_state_changed(mc->iod, phone_state);
++      }
++
++      if (phone_active)
++              irq_set_irq_type(mc->irq_phone_active, IRQ_TYPE_LEVEL_LOW);
++      else
++              irq_set_irq_type(mc->irq_phone_active, IRQ_TYPE_LEVEL_HIGH);
++
++      pr_info("[MSM] <%s> phone_state = %d\n", __func__, phone_state);
++
++      return IRQ_HANDLED;
++}
++
++#if defined(CONFIG_SIM_DETECT)
++#if defined(CONFIG_MACH_GRANDE)
++static void sim_detect_work(struct work_struct *work)
++{
++      struct modem_ctl *mc =
++              container_of(work, struct modem_ctl, sim_det_dwork.work);
++
++      pr_info("[MSM] <%s> gpio_sim_detect = %d\n",
++              __func__, gpio_get_value(mc->gpio_sim_detect));
++
++      if (mc->iod && mc->iod->sim_state_changed)
++              mc->iod->sim_state_changed(mc->iod,
++              !gpio_get_value(mc->gpio_sim_detect));
++}
++#endif
++static irqreturn_t sim_detect_irq_handler(int irq, void *_mc)
++{
++      struct modem_ctl *mc = (struct modem_ctl *)_mc;
++
++      pr_info("[MSM] <%s> gpio_sim_detect = %d\n",
++              __func__, gpio_get_value(mc->gpio_sim_detect));
++
++#if defined(CONFIG_MACH_GRANDE)
++      schedule_delayed_work(&mc->sim_det_dwork, msecs_to_jiffies(400));
++#else
++      if (mc->iod && mc->iod->sim_state_changed)
++              mc->iod->sim_state_changed(mc->iod,
++              !gpio_get_value(mc->gpio_sim_detect));
++#endif
++      return IRQ_HANDLED;
++}
++#endif
++
++static void mdm6600_get_ops(struct modem_ctl *mc)
++{
++      mc->ops.modem_on = mdm6600_on;
++      mc->ops.modem_off = mdm6600_off;
++      mc->ops.modem_reset = mdm6600_reset;
++      mc->ops.modem_boot_on = mdm6600_boot_on;
++      mc->ops.modem_boot_off = mdm6600_boot_off;
++      mc->ops.modem_force_crash_exit = mdm6600_force_crash_exit;
++}
++
++int mdm6600_init_modemctl_device(struct modem_ctl *mc, struct modem_data *pdata)
++{
++      int ret = 0;
++      struct platform_device *pdev;
++
++      mc->gpio_cp_on = pdata->gpio_cp_on;
++      mc->gpio_reset_req_n = pdata->gpio_reset_req_n;
++      mc->gpio_cp_reset = pdata->gpio_cp_reset;
++      mc->gpio_pda_active = pdata->gpio_pda_active;
++      mc->gpio_phone_active = pdata->gpio_phone_active;
++      mc->gpio_cp_dump_int = pdata->gpio_cp_dump_int;
++      mc->gpio_flm_uart_sel = pdata->gpio_flm_uart_sel;
++#if defined(CONFIG_MACH_M0_CTC)
++      mc->gpio_flm_uart_sel_rev06 = pdata->gpio_flm_uart_sel_rev06;
++#endif
++      mc->gpio_cp_warm_reset = pdata->gpio_cp_warm_reset;
++      mc->gpio_sim_detect = pdata->gpio_sim_detect;
++
++      gpio_set_value(mc->gpio_cp_reset, 0);
++      gpio_set_value(mc->gpio_cp_on, 0);
++
++      pdev = to_platform_device(mc->dev);
++      mc->irq_phone_active = platform_get_irq_byname(pdev, "cp_active_irq");
++      pr_info("[MSM] <%s> PHONE_ACTIVE IRQ# = %d\n",
++              __func__, mc->irq_phone_active);
++
++      mdm6600_get_ops(mc);
++
++      ret = request_irq(mc->irq_phone_active,
++                        phone_active_irq_handler,
++                        IRQF_TRIGGER_HIGH, "msm_active", mc);
++      if (ret) {
++              pr_err("[MSM] <%s> failed to request_irq IRQ# %d (err=%d)\n",
++                     __func__, mc->irq_phone_active, ret);
++              return ret;
++      }
++
++      ret = enable_irq_wake(mc->irq_phone_active);
++      if (ret) {
++              pr_err("[MSM] %s: failed to enable_irq_wake IRQ# %d (err=%d)\n",
++                     __func__, mc->irq_phone_active, ret);
++              free_irq(mc->irq_phone_active, mc);
++              return ret;
++      }
++
++#if defined(CONFIG_SIM_DETECT)
++#if defined(CONFIG_MACH_GRANDE)
++      INIT_DELAYED_WORK(&mc->sim_det_dwork, sim_detect_work);
++#endif
++      mc->irq_sim_detect = platform_get_irq_byname(pdev, "sim_irq");
++      pr_info("[MSM] <%s> SIM_DECTCT IRQ# = %d\n",
++              __func__, mc->irq_sim_detect);
++
++      if (mc->irq_sim_detect) {
++              ret = request_irq(mc->irq_sim_detect, sim_detect_irq_handler,
++                      IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
++                      "msm_sim_detect", mc);
++              if (ret) {
++                      mif_err("[MSM] failed to request_irq: %d\n", ret);
++                      mc->sim_state.online = false;
++                      mc->sim_state.changed = false;
++                      return ret;
++              }
++
++              ret = enable_irq_wake(mc->irq_sim_detect);
++              if (ret) {
++                      mif_err("[MSM] failed to enable_irq_wake: %d\n", ret);
++                      free_irq(mc->irq_sim_detect, mc);
++                      mc->sim_state.online = false;
++                      mc->sim_state.changed = false;
++                      return ret;
++              }
++
++              /* initialize sim_state => insert: gpio=0, remove: gpio=1 */
++              mc->sim_state.online = !gpio_get_value(mc->gpio_sim_detect);
++      }
++#endif
++
++      return ret;
++}
++#endif
+diff --git a/drivers/misc/modem_if/modem_modemctl_device_xmm6260.c b/drivers/misc/modem_if/modem_modemctl_device_xmm6260.c
+new file mode 100644
+index 0000000..c2d5067
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_modemctl_device_xmm6260.c
+@@ -0,0 +1,303 @@
++/* /linux/drivers/misc/modem_if/modem_modemctl_device_xmm6260.c
++ *
++ * Copyright (C) 2010 Google, Inc.
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.        See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <linux/init.h>
++
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/gpio.h>
++#include <linux/delay.h>
++#include <linux/platform_device.h>
++
++#include <linux/platform_data/modem.h>
++#include "modem_prj.h"
++
++static int xmm6260_on(struct modem_ctl *mc)
++{
++      mif_info("xmm6260_on()\n");
++
++      if (!mc->gpio_cp_reset || !mc->gpio_cp_on || !mc->gpio_reset_req_n) {
++              mif_err("no gpio data\n");
++              return -ENXIO;
++      }
++
++      if (mc->gpio_revers_bias_clear)
++              mc->gpio_revers_bias_clear();
++
++
++      gpio_set_value(mc->gpio_cp_on, 0);
++      gpio_set_value(mc->gpio_cp_reset, 0);
++      udelay(160);
++      gpio_set_value(mc->gpio_pda_active, 0);
++      msleep(500); /* must be >500ms for CP can boot up under -20 degrees */
++      gpio_set_value(mc->gpio_cp_reset, 1);
++      udelay(160);
++      gpio_set_value(mc->gpio_reset_req_n, 1);
++      udelay(160);
++      gpio_set_value(mc->gpio_cp_on, 1);
++      udelay(60);
++      gpio_set_value(mc->gpio_cp_on, 0);
++      msleep(20);
++
++      if (mc->gpio_revers_bias_restore)
++              mc->gpio_revers_bias_restore();
++
++
++      gpio_set_value(mc->gpio_pda_active, 1);
++
++      mc->phone_state = STATE_BOOTING;
++
++      return 0;
++
++}
++
++static int xmm6260_off(struct modem_ctl *mc)
++{
++      mif_info("xmm6260_off()\n");
++
++      if (!mc->gpio_cp_reset || !mc->gpio_cp_on) {
++              mif_err("no gpio data\n");
++              return -ENXIO;
++      }
++
++      gpio_set_value(mc->gpio_cp_on, 0);
++      gpio_set_value(mc->gpio_cp_reset, 0);
++
++      mc->phone_state = STATE_OFFLINE;
++
++      return 0;
++}
++
++
++static int xmm6260_reset(struct modem_ctl *mc)
++{
++
++      mif_info("xmm6260_reset()\n");
++
++      if (!mc->gpio_cp_reset || !mc->gpio_reset_req_n)
++              return -ENXIO;
++
++      if (mc->gpio_revers_bias_clear)
++              mc->gpio_revers_bias_clear();
++
++      gpio_set_value(mc->gpio_cp_reset, 0);
++      gpio_set_value(mc->gpio_reset_req_n, 0);
++
++      mc->phone_state = STATE_OFFLINE;
++
++      msleep(20);
++
++      gpio_set_value(mc->gpio_cp_reset, 1);
++/* TODO: check the reset timming with C2C connection */
++      udelay(160);
++
++      gpio_set_value(mc->gpio_reset_req_n, 1);
++      udelay(100);
++
++      gpio_set_value(mc->gpio_cp_on, 1);
++      udelay(60);
++      gpio_set_value(mc->gpio_cp_on, 0);
++      msleep(20);
++
++      if (mc->gpio_revers_bias_restore)
++              mc->gpio_revers_bias_restore();
++
++      mc->phone_state = STATE_BOOTING;
++
++      return 0;
++}
++
++static int xmm6260_boot_on(struct modem_ctl *mc)
++{
++      mif_info("xmm6260_boot_on()\n");
++
++      if (!mc->gpio_flm_uart_sel) {
++              mif_err("no gpio data\n");
++              return -ENXIO;
++      }
++
++      gpio_set_value(mc->gpio_flm_uart_sel, 0);
++
++      return 0;
++}
++
++static int xmm6260_boot_off(struct modem_ctl *mc)
++{
++      mif_info("xmm6260_boot_off()\n");
++
++      if (!mc->gpio_flm_uart_sel) {
++              mif_err("no gpio data\n");
++              return -ENXIO;
++      }
++
++      gpio_set_value(mc->gpio_flm_uart_sel, 1);
++
++      return 0;
++}
++
++static irqreturn_t phone_active_irq_handler(int irq, void *_mc)
++{
++      int phone_reset = 0;
++      int phone_active_value = 0;
++      int cp_dump_value = 0;
++      int phone_state = 0;
++      struct modem_ctl *mc = (struct modem_ctl *)_mc;
++      struct link_device *ld;
++
++      disable_irq_nosync(mc->irq_phone_active);
++
++      if (!mc->gpio_cp_reset || !mc->gpio_phone_active ||
++                      !mc->gpio_cp_dump_int) {
++              mif_err("no gpio data\n");
++              return IRQ_HANDLED;
++      }
++
++      phone_reset = gpio_get_value(mc->gpio_cp_reset);
++      phone_active_value = gpio_get_value(mc->gpio_phone_active);
++      cp_dump_value = gpio_get_value(mc->gpio_cp_dump_int);
++
++      mif_info("PA EVENT : reset =%d, pa=%d, cp_dump=%d\n",
++                              phone_reset, phone_active_value, cp_dump_value);
++
++      if (phone_reset && phone_active_value)
++              phone_state = STATE_BOOTING;
++      else if (phone_reset && !phone_active_value) {
++              if (mc->phone_state == STATE_BOOTING)
++                      goto set_type;
++              if (cp_dump_value)
++                      phone_state = STATE_CRASH_EXIT;
++              else
++                      phone_state = STATE_CRASH_RESET;
++              if (mc->iod) {
++                      ld = get_current_link(mc->iod);
++                      if (ld->terminate_comm)
++                              ld->terminate_comm(ld, mc->iod);
++              }
++      } else
++              phone_state = STATE_OFFLINE;
++
++      if (mc->iod && mc->iod->modem_state_changed)
++              mc->iod->modem_state_changed(mc->iod, phone_state);
++
++      if (mc->bootd && mc->bootd->modem_state_changed)
++              mc->bootd->modem_state_changed(mc->bootd, phone_state);
++
++set_type:
++      if (phone_active_value)
++              irq_set_irq_type(mc->irq_phone_active, IRQ_TYPE_LEVEL_LOW);
++      else
++              irq_set_irq_type(mc->irq_phone_active, IRQ_TYPE_LEVEL_HIGH);
++      enable_irq(mc->irq_phone_active);
++
++      return IRQ_HANDLED;
++}
++
++static irqreturn_t sim_detect_irq_handler(int irq, void *_mc)
++{
++      struct modem_ctl *mc = (struct modem_ctl *)_mc;
++
++      if (mc->iod && mc->iod->sim_state_changed)
++              mc->iod->sim_state_changed(mc->iod,
++                              !gpio_get_value(mc->gpio_sim_detect));
++
++      return IRQ_HANDLED;
++}
++
++static void xmm6260_get_ops(struct modem_ctl *mc)
++{
++      mc->ops.modem_on = xmm6260_on;
++      mc->ops.modem_off = xmm6260_off;
++      mc->ops.modem_reset = xmm6260_reset;
++      mc->ops.modem_boot_on = xmm6260_boot_on;
++      mc->ops.modem_boot_off = xmm6260_boot_off;
++}
++
++int xmm6260_init_modemctl_device(struct modem_ctl *mc,
++                      struct modem_data *pdata)
++{
++      int ret;
++      struct platform_device *pdev;
++
++      mc->gpio_cp_on = pdata->gpio_cp_on;
++      mc->gpio_reset_req_n = pdata->gpio_reset_req_n;
++      mc->gpio_cp_reset = pdata->gpio_cp_reset;
++      mc->gpio_pda_active = pdata->gpio_pda_active;
++      mc->gpio_phone_active = pdata->gpio_phone_active;
++      mc->gpio_cp_dump_int = pdata->gpio_cp_dump_int;
++      mc->gpio_flm_uart_sel = pdata->gpio_flm_uart_sel;
++      mc->gpio_cp_warm_reset = pdata->gpio_cp_warm_reset;
++      mc->gpio_revers_bias_clear = pdata->gpio_revers_bias_clear;
++      mc->gpio_revers_bias_restore = pdata->gpio_revers_bias_restore;
++      mc->gpio_sim_detect = pdata->gpio_sim_detect;
++
++      pdev = to_platform_device(mc->dev);
++      /* mc->irq_phone_active = platform_get_irq(pdev, 0); */
++      mc->irq_phone_active = gpio_to_irq(mc->gpio_phone_active);
++
++      if (mc->gpio_sim_detect)
++              mc->irq_sim_detect = gpio_to_irq(mc->gpio_sim_detect);
++
++      xmm6260_get_ops(mc);
++
++      /* initialize phone active */
++      ret = request_irq(mc->irq_phone_active, phone_active_irq_handler,
++                              IRQF_NO_SUSPEND | IRQF_TRIGGER_HIGH,
++                              "phone_active", mc);
++      if (ret) {
++              mif_err("failed to request_irq:%d\n", ret);
++              goto err_phone_active_request_irq;
++      }
++
++      ret = enable_irq_wake(mc->irq_phone_active);
++      if (ret) {
++              mif_err("failed to enable_irq_wake:%d\n", ret);
++              goto err_phone_active_set_wake_irq;
++      }
++
++      /* initialize sim_state if gpio_sim_detect exists */
++      mc->sim_state.online = false;
++      mc->sim_state.changed = false;
++      if (mc->gpio_sim_detect) {
++              ret = request_irq(mc->irq_sim_detect, sim_detect_irq_handler,
++                              IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
++                              "sim_detect", mc);
++              if (ret) {
++                      mif_err("failed to request_irq: %d\n", ret);
++                      goto err_sim_detect_request_irq;
++              }
++
++              ret = enable_irq_wake(mc->irq_sim_detect);
++              if (ret) {
++                      mif_err("failed to enable_irq_wake: %d\n", ret);
++                      goto err_sim_detect_set_wake_irq;
++              }
++
++              /* initialize sim_state => insert: gpio=0, remove: gpio=1 */
++              mc->sim_state.online = !gpio_get_value(mc->gpio_sim_detect);
++      }
++
++      return ret;
++
++err_sim_detect_set_wake_irq:
++      free_irq(mc->irq_sim_detect, mc);
++err_sim_detect_request_irq:
++      mc->sim_state.online = false;
++      mc->sim_state.changed = false;
++err_phone_active_set_wake_irq:
++      free_irq(mc->irq_phone_active, mc);
++err_phone_active_request_irq:
++      return ret;
++}
+diff --git a/drivers/misc/modem_if/modem_modemctl_device_xmm6262.c b/drivers/misc/modem_if/modem_modemctl_device_xmm6262.c
+new file mode 100644
+index 0000000..e400046
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_modemctl_device_xmm6262.c
+@@ -0,0 +1,261 @@
++/* /linux/drivers/misc/modem_if/modem_modemctl_device_xmm6262.c
++ *
++ * Copyright (C) 2010 Google, Inc.
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#define DEBUG
++
++#include <linux/init.h>
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/gpio.h>
++#include <linux/delay.h>
++#include <linux/platform_device.h>
++#include <linux/cma.h>
++#include <plat/devs.h>
++#include <linux/platform_data/modem.h>
++#include "modem_prj.h"
++
++static int xmm6262_on(struct modem_ctl *mc)
++{
++      mif_info("\n");
++
++      if (!mc->gpio_cp_reset || !mc->gpio_cp_on || !mc->gpio_reset_req_n) {
++              mif_err("no gpio data\n");
++              return -ENXIO;
++      }
++
++      if (mc->gpio_revers_bias_clear)
++              mc->gpio_revers_bias_clear();
++
++      /* TODO */
++      gpio_set_value(mc->gpio_reset_req_n, 0);
++      gpio_set_value(mc->gpio_cp_on, 0);
++      gpio_set_value(mc->gpio_cp_reset, 0);
++      msleep(100);
++      gpio_set_value(mc->gpio_cp_reset, 1);
++      /* If XMM6262 was connected with C2C, AP wait 50ms to BB Reset*/
++      msleep(50);
++      gpio_set_value(mc->gpio_reset_req_n, 1);
++
++      gpio_set_value(mc->gpio_cp_on, 1);
++      udelay(60);
++      gpio_set_value(mc->gpio_cp_on, 0);
++      msleep(20);
++      if (mc->gpio_revers_bias_restore)
++              mc->gpio_revers_bias_restore();
++      gpio_set_value(mc->gpio_pda_active, 1);
++
++      mc->phone_state = STATE_BOOTING;
++
++      return 0;
++}
++
++static int xmm6262_off(struct modem_ctl *mc)
++{
++      mif_info("\n");
++
++      if (!mc->gpio_cp_reset || !mc->gpio_cp_on) {
++              mif_err("no gpio data\n");
++              return -ENXIO;
++      }
++
++      gpio_set_value(mc->gpio_cp_on, 0);
++      gpio_set_value(mc->gpio_cp_reset, 0);
++
++      return 0;
++}
++
++static int xmm6262_reset(struct modem_ctl *mc)
++{
++      mif_info("\n");
++
++      if (!mc->gpio_cp_reset || !mc->gpio_reset_req_n)
++              return -ENXIO;
++
++      if (mc->gpio_revers_bias_clear)
++              mc->gpio_revers_bias_clear();
++
++      gpio_set_value(mc->gpio_cp_reset, 0);
++      gpio_set_value(mc->gpio_reset_req_n, 0);
++
++      mc->phone_state = STATE_OFFLINE;
++
++      msleep(20);
++
++      gpio_set_value(mc->gpio_cp_reset, 1);
++      /* TODO: check the reset timming with C2C connection */
++      udelay(160);
++
++      gpio_set_value(mc->gpio_reset_req_n, 1);
++      udelay(100);
++
++      gpio_set_value(mc->gpio_cp_on, 1);
++      udelay(60);
++      gpio_set_value(mc->gpio_cp_on, 0);
++      msleep(20);
++
++      if (mc->gpio_revers_bias_restore)
++              mc->gpio_revers_bias_restore();
++
++      mc->phone_state = STATE_BOOTING;
++
++      return 0;
++}
++
++static irqreturn_t phone_active_irq_handler(int irq, void *_mc)
++{
++      int phone_reset = 0;
++      int phone_active_value = 0;
++      int cp_dump_value = 0;
++      int phone_state = 0;
++      struct modem_ctl *mc = (struct modem_ctl *)_mc;
++
++      disable_irq_nosync(mc->irq_phone_active);
++
++      if (!mc->gpio_cp_reset || !mc->gpio_phone_active ||
++                      !mc->gpio_cp_dump_int) {
++              mif_err("no gpio data\n");
++              return IRQ_HANDLED;
++      }
++
++      phone_reset = gpio_get_value(mc->gpio_cp_reset);
++      phone_active_value = gpio_get_value(mc->gpio_phone_active);
++      cp_dump_value = gpio_get_value(mc->gpio_cp_dump_int);
++
++      mif_info("PA EVENT : reset =%d, pa=%d, cp_dump=%d\n",
++                              phone_reset, phone_active_value, cp_dump_value);
++
++      if (phone_reset && phone_active_value)
++              phone_state = STATE_BOOTING;
++      else if (phone_reset && !phone_active_value) {
++              if (cp_dump_value)
++                      phone_state = STATE_CRASH_EXIT;
++              else
++                      phone_state = STATE_CRASH_RESET;
++      } else
++              phone_state = STATE_OFFLINE;
++
++      if (mc->iod && mc->iod->modem_state_changed)
++              mc->iod->modem_state_changed(mc->iod, phone_state);
++
++      if (mc->bootd && mc->bootd->modem_state_changed)
++              mc->bootd->modem_state_changed(mc->bootd, phone_state);
++
++      if (phone_active_value)
++              irq_set_irq_type(mc->irq_phone_active, IRQ_TYPE_LEVEL_LOW);
++      else
++              irq_set_irq_type(mc->irq_phone_active, IRQ_TYPE_LEVEL_HIGH);
++      enable_irq(mc->irq_phone_active);
++
++      return IRQ_HANDLED;
++}
++
++static irqreturn_t sim_detect_irq_handler(int irq, void *_mc)
++{
++      struct modem_ctl *mc = (struct modem_ctl *)_mc;
++
++      if (mc->iod && mc->iod->sim_state_changed)
++              mc->iod->sim_state_changed(mc->iod,
++                      gpio_get_value(mc->gpio_sim_detect) == mc->sim_polarity
++                      );
++
++      return IRQ_HANDLED;
++}
++
++static void xmm6262_get_ops(struct modem_ctl *mc)
++{
++      mc->ops.modem_on = xmm6262_on;
++      mc->ops.modem_off = xmm6262_off;
++      mc->ops.modem_reset = xmm6262_reset;
++}
++
++int xmm6262_init_modemctl_device(struct modem_ctl *mc,
++                      struct modem_data *pdata)
++{
++      int ret = 0;
++      struct platform_device *pdev;
++
++      mc->gpio_reset_req_n = pdata->gpio_reset_req_n;
++      mc->gpio_cp_on = pdata->gpio_cp_on;
++      mc->gpio_cp_reset = pdata->gpio_cp_reset;
++      mc->gpio_pda_active = pdata->gpio_pda_active;
++      mc->gpio_phone_active = pdata->gpio_phone_active;
++      mc->gpio_cp_dump_int = pdata->gpio_cp_dump_int;
++      mc->gpio_ap_dump_int = pdata->gpio_ap_dump_int;
++      mc->gpio_flm_uart_sel = pdata->gpio_flm_uart_sel;
++      mc->gpio_cp_warm_reset = pdata->gpio_cp_warm_reset;
++      mc->gpio_sim_detect = pdata->gpio_sim_detect;
++      mc->sim_polarity = pdata->sim_polarity;
++
++      mc->gpio_revers_bias_clear = pdata->gpio_revers_bias_clear;
++      mc->gpio_revers_bias_restore = pdata->gpio_revers_bias_restore;
++
++      pdev = to_platform_device(mc->dev);
++      mc->irq_phone_active = gpio_to_irq(mc->gpio_phone_active);
++
++      if (mc->gpio_sim_detect)
++              mc->irq_sim_detect = gpio_to_irq(mc->gpio_sim_detect);
++
++      xmm6262_get_ops(mc);
++
++      ret = request_irq(mc->irq_phone_active, phone_active_irq_handler,
++                              IRQF_NO_SUSPEND | IRQF_TRIGGER_HIGH,
++                              "phone_active", mc);
++      if (ret) {
++              mif_err("failed to request_irq:%d\n", ret);
++              goto err_phone_active_request_irq;
++      }
++
++      ret = enable_irq_wake(mc->irq_phone_active);
++      if (ret) {
++              mif_err("failed to enable_irq_wake:%d\n", ret);
++              goto err_phone_active_set_wake_irq;
++      }
++
++      /* initialize sim_state if gpio_sim_detect exists */
++      mc->sim_state.online = false;
++      mc->sim_state.changed = false;
++      if (mc->gpio_sim_detect) {
++              ret = request_irq(mc->irq_sim_detect, sim_detect_irq_handler,
++                              IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
++                              "sim_detect", mc);
++              if (ret) {
++                      mif_err("failed to request_irq: %d\n", ret);
++                      goto err_sim_detect_request_irq;
++              }
++
++              ret = enable_irq_wake(mc->irq_sim_detect);
++              if (ret) {
++                      mif_err("failed to enable_irq_wake: %d\n", ret);
++                      goto err_sim_detect_set_wake_irq;
++              }
++
++              /* initialize sim_state => insert: gpio=0, remove: gpio=1 */
++              mc->sim_state.online =
++                      gpio_get_value(mc->gpio_sim_detect) == mc->sim_polarity;
++      }
++
++      return ret;
++
++err_sim_detect_set_wake_irq:
++      free_irq(mc->irq_sim_detect, mc);
++err_sim_detect_request_irq:
++      mc->sim_state.online = false;
++      mc->sim_state.changed = false;
++err_phone_active_set_wake_irq:
++      free_irq(mc->irq_phone_active, mc);
++err_phone_active_request_irq:
++      return ret;
++}
+diff --git a/drivers/misc/modem_if/modem_net_flowcontrol_device.c b/drivers/misc/modem_if/modem_net_flowcontrol_device.c
+new file mode 100644
+index 0000000..164f471
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_net_flowcontrol_device.c
+@@ -0,0 +1,117 @@
++/* /linux/drivers/misc/modem_if/modem_net_flowcontrol_device.c
++ *
++ * Copyright (C) 2011 Google, Inc.
++ * Copyright (C) 2011 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/fs.h>
++#include <linux/errno.h>
++#include <linux/types.h>
++#include <linux/fcntl.h>
++#include <linux/sched.h>
++#include <linux/netdevice.h>
++#include <linux/if_arp.h>
++#include <linux/platform_data/modem.h>
++#include <linux/module.h>
++
++#include "modem_prj.h"
++
++
++#define NET_FLOWCONTROL_DEV_NAME_LEN 8
++
++static int modem_net_flowcontrol_device_open(
++                      struct inode *inode, struct file *filp)
++{
++      return 0;
++}
++
++static int modem_net_flowcontrol_device_release(
++                      struct inode *inode, struct file *filp)
++{
++      return 0;
++}
++
++static long modem_net_flowcontrol_device_ioctl(
++                      struct file *filp, unsigned int cmd, unsigned long arg)
++{
++      struct net *this_net;
++      struct net_device *ndev;
++      char dev_name[NET_FLOWCONTROL_DEV_NAME_LEN];
++      u8 chan;
++
++      if (copy_from_user(&chan, (void __user *)arg, sizeof(char)))
++              return -EFAULT;
++
++      if (chan > 15)
++              return -ENODEV;
++
++      snprintf(dev_name, NET_FLOWCONTROL_DEV_NAME_LEN, "rmnet%d", (int)chan);
++      this_net = get_net_ns_by_pid(current->pid);
++      ndev = __dev_get_by_name(this_net, dev_name);
++      if (ndev == NULL) {
++              mif_err("device = %s not exist\n", dev_name);
++              return -ENODEV;
++      }
++
++      switch (cmd) {
++      case IOCTL_MODEM_NET_SUSPEND:
++              netif_stop_queue(ndev);
++              mif_info("NET SUSPEND(%s)\n", dev_name);
++              break;
++      case IOCTL_MODEM_NET_RESUME:
++              netif_wake_queue(ndev);
++              mif_info("NET RESUME(%s)\n", dev_name);
++              break;
++      default:
++              return -EINVAL;
++      }
++      return 0;
++}
++
++static const struct file_operations modem_net_flowcontrol_device_fops = {
++      .owner = THIS_MODULE,
++      .open = modem_net_flowcontrol_device_open,
++      .release = modem_net_flowcontrol_device_release,
++      .unlocked_ioctl = modem_net_flowcontrol_device_ioctl,
++};
++
++static int __init modem_net_flowcontrol_device_init(void)
++{
++      int ret = 0;
++      struct io_device *net_flowcontrol_dev;
++
++      net_flowcontrol_dev = kzalloc(sizeof(struct io_device), GFP_KERNEL);
++      if (!net_flowcontrol_dev) {
++              mif_err("net_flowcontrol_dev io device memory alloc fail\n");
++              return -ENOMEM;
++      }
++
++      net_flowcontrol_dev->miscdev.minor = MISC_DYNAMIC_MINOR;
++      net_flowcontrol_dev->miscdev.name = "modem_br";
++      net_flowcontrol_dev->miscdev.fops = &modem_net_flowcontrol_device_fops;
++
++      ret = misc_register(&net_flowcontrol_dev->miscdev);
++      if (ret) {
++              mif_err("failed to register misc br device : %s\n",
++                      net_flowcontrol_dev->miscdev.name);
++              kfree(net_flowcontrol_dev);
++      }
++
++      return ret;
++}
++
++module_init(modem_net_flowcontrol_device_init);
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("Samsung Modem IF Net Flowcontrol Driver");
+diff --git a/drivers/misc/modem_if/modem_prj.h b/drivers/misc/modem_if/modem_prj.h
+new file mode 100644
+index 0000000..4780bef
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_prj.h
+@@ -0,0 +1,725 @@
++/*
++ * Copyright (C) 2010 Google, Inc.
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#ifndef __MODEM_PRJ_H__
++#define __MODEM_PRJ_H__
++
++#include <linux/wait.h>
++#include <linux/miscdevice.h>
++#include <linux/skbuff.h>
++#include <linux/completion.h>
++#include <linux/wakelock.h>
++#include <linux/rbtree.h>
++#include <linux/spinlock.h>
++#include <linux/types.h>
++
++#define MAX_CPINFO_SIZE               512
++
++#define MAX_LINK_DEVTYPE      3
++
++#define MAX_FMT_DEVS  10
++#define MAX_RAW_DEVS  32
++#define MAX_RFS_DEVS  10
++#define MAX_NUM_IO_DEV        (MAX_FMT_DEVS + MAX_RAW_DEVS + MAX_RFS_DEVS)
++
++#define IOCTL_MODEM_ON                        _IO('o', 0x19)
++#define IOCTL_MODEM_OFF                       _IO('o', 0x20)
++#define IOCTL_MODEM_RESET             _IO('o', 0x21)
++#define IOCTL_MODEM_BOOT_ON           _IO('o', 0x22)
++#define IOCTL_MODEM_BOOT_OFF          _IO('o', 0x23)
++#define IOCTL_MODEM_BOOT_DONE         _IO('o', 0x24)
++
++#define IOCTL_MODEM_PROTOCOL_SUSPEND  _IO('o', 0x25)
++#define IOCTL_MODEM_PROTOCOL_RESUME   _IO('o', 0x26)
++
++#define IOCTL_MODEM_STATUS            _IO('o', 0x27)
++#define IOCTL_MODEM_DL_START          _IO('o', 0x28)
++#define IOCTL_MODEM_FW_UPDATE         _IO('o', 0x29)
++
++#define IOCTL_MODEM_NET_SUSPEND               _IO('o', 0x30)
++#define IOCTL_MODEM_NET_RESUME                _IO('o', 0x31)
++
++#define IOCTL_MODEM_DUMP_START                _IO('o', 0x32)
++#define IOCTL_MODEM_DUMP_UPDATE               _IO('o', 0x33)
++#define IOCTL_MODEM_FORCE_CRASH_EXIT  _IO('o', 0x34)
++#define IOCTL_MODEM_CP_UPLOAD         _IO('o', 0x35)
++#define IOCTL_MODEM_DUMP_RESET                _IO('o', 0x36)
++
++#define IOCTL_DPRAM_SEND_BOOT         _IO('o', 0x40)
++#define IOCTL_DPRAM_INIT_STATUS               _IO('o', 0x43)
++
++/* ioctl command definitions. */
++#define IOCTL_DPRAM_PHONE_POWON               _IO('o', 0xd0)
++#define IOCTL_DPRAM_PHONEIMG_LOAD     _IO('o', 0xd1)
++#define IOCTL_DPRAM_NVDATA_LOAD               _IO('o', 0xd2)
++#define IOCTL_DPRAM_PHONE_BOOTSTART   _IO('o', 0xd3)
++
++#define IOCTL_DPRAM_PHONE_UPLOAD_STEP1        _IO('o', 0xde)
++#define IOCTL_DPRAM_PHONE_UPLOAD_STEP2        _IO('o', 0xdf)
++
++/* ioctl command for IPC Logger */
++#define IOCTL_MIF_LOG_DUMP            _IO('o', 0x51)
++#define IOCTL_MIF_DPRAM_DUMP          _IO('o', 0x52)
++
++/* modem status */
++#define MODEM_OFF             0
++#define MODEM_CRASHED         1
++#define MODEM_RAMDUMP         2
++#define MODEM_POWER_ON                3
++#define MODEM_BOOTING_NORMAL  4
++#define MODEM_BOOTING_RAMDUMP 5
++#define MODEM_DUMPING         6
++#define MODEM_RUNNING         7
++
++#define HDLC_HEADER_MAX_SIZE  6 /* fmt 3, raw 6, rfs 6 */
++
++#define PSD_DATA_CHID_BEGIN   0x2A
++#define PSD_DATA_CHID_END     0x38
++
++#define PS_DATA_CH_0          10
++#define PS_DATA_CH_LAST               24
++#define RMNET0_CH_ID          PS_DATA_CH_0
++
++#define IP6VERSION            6
++
++#define SOURCE_MAC_ADDR               {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}
++
++/* IP loopback */
++#define CP2AP_LOOPBACK_CHANNEL        30      /* CP -> AP -> CP */
++#define DATA_LOOPBACK_CHANNEL 31      /* AP -> CP -> AP */
++
++/* Debugging features */
++#define MIF_LOG_DIR           "/sdcard/log"
++#define MIF_MAX_PATH_LEN      256
++#define MIF_MAX_NAME_LEN      64
++#define MIF_MAX_STR_LEN               32
++
++/* Does modem ctl structure will use state ? or status defined below ?*/
++enum modem_state {
++      STATE_OFFLINE,
++      STATE_CRASH_RESET, /* silent reset */
++      STATE_CRASH_EXIT, /* cp ramdump */
++      STATE_BOOTING,
++      STATE_ONLINE,
++      STATE_NV_REBUILDING, /* <= rebuilding start */
++      STATE_LOADER_DONE,
++      STATE_SIM_ATTACH,
++      STATE_SIM_DETACH,
++};
++
++enum com_state {
++      COM_NONE,
++      COM_ONLINE,
++      COM_HANDSHAKE,
++      COM_BOOT,
++      COM_CRASH,
++};
++
++enum link_mode {
++      LINK_MODE_OFFLINE = 0,
++      LINK_MODE_BOOT,
++      LINK_MODE_IPC,
++      LINK_MODE_DLOAD,
++      LINK_MODE_ULOAD,
++};
++
++struct sim_state {
++      bool online;    /* SIM is online? */
++      bool changed;   /* online is changed? */
++};
++
++#define HDLC_START            0x7F
++#define HDLC_END              0x7E
++#define SIZE_OF_HDLC_START    1
++#define SIZE_OF_HDLC_END      1
++#define MAX_LINK_PADDING_SIZE 3
++
++struct header_data {
++      char hdr[HDLC_HEADER_MAX_SIZE];
++      unsigned len;
++      unsigned frag_len;
++      char start; /*hdlc start header 0x7F*/
++};
++
++struct fmt_hdr {
++      u16 len;
++      u8 control;
++} __packed;
++
++struct raw_hdr {
++      u32 len;
++      u8 channel;
++      u8 control;
++} __packed;
++
++struct rfs_hdr {
++      u32 len;
++      u8 cmd;
++      u8 id;
++} __packed;
++
++struct sipc_fmt_hdr {
++      u16 len;
++      u8  msg_seq;
++      u8  ack_seq;
++      u8  main_cmd;
++      u8  sub_cmd;
++      u8  cmd_type;
++} __packed;
++
++#define SIPC5_START_MASK      0b11111000
++#define SIPC5_CONFIG_MASK     0b00000111
++#define SIPC5_EXT_FIELD_MASK  0b00000011
++
++#define SIPC5_PADDING_EXIST   0b00000100
++#define SIPC5_EXT_FIELD_EXIST 0b00000010
++#define SIPC5_CTL_FIELD_EXIST 0b00000001
++
++#define SIPC5_MAX_HEADER_SIZE 6
++#define SIPC5_HEADER_SIZE_WITH_EXT_LEN        6
++#define SIPC5_HEADER_SIZE_WITH_CTL_FLD        5
++#define SIPC5_MIN_HEADER_SIZE 4
++#define SIPC5_CONFIG_SIZE     1
++#define SIPC5_CH_ID_SIZE      1
++
++#define SIPC5_CONFIG_OFFSET   0
++#define SIPC5_CH_ID_OFFSET    1
++#define SIPC5_LEN_OFFSET      2
++#define SIPC5_CTL_OFFSET      4
++
++#define SIPC5_CH_ID_RAW_0     0
++#define SIPC5_CH_ID_PDP_0     10
++#define SIPC5_CH_ID_PDP_LAST  24
++#define SIPC5_CH_ID_FMT_0     235
++#define SIPC5_CH_ID_RFS_0     245
++#define SIPC5_CH_ID_MAX               255
++
++/* If iod->id is 0, do not need to store to `iodevs_tree_fmt' in SIPC4 */
++#define sipc4_is_not_reserved_channel(ch) ((ch) != 0)
++
++/* Channel 0, 5, 6, 27, 255 are reserved in SIPC5.
++ * see SIPC5 spec: 2.2.2 Channel Identification (Ch ID) Field.
++ * They do not need to store in `iodevs_tree_fmt'
++ */
++#define sipc5_is_not_reserved_channel(ch) \
++      ((ch) != 0 && (ch) != 5 && (ch) != 6 && (ch) != 27 && (ch) != 255)
++
++struct sipc5_link_hdr {
++      u8 cfg;
++      u8 ch;
++      u16 len;
++      union {
++              u8 ctl;
++              u16 ext_len;
++      };
++} __packed;
++
++struct sipc5_frame_data {
++      /* Config octet */
++      u8 config;
++
++      /* Channel ID */
++      u8 ch_id;
++
++      /* Control for multiple FMT frame */
++      u8 control;
++
++      /* Frame configuration set by header analysis */
++      bool padding;
++      bool ctl_fld;
++      bool ext_len;
++
++      /* Frame length calculated from the length fields */
++      unsigned len;
++
++      /* The length of link layer header */
++      unsigned hdr_len;
++
++      /* The length of received header */
++      unsigned hdr_rcvd;
++
++      /* The length of data payload */
++      unsigned data_len;
++
++      /* The length of received data */
++      unsigned data_rcvd;
++
++      /* Header buffer */
++      u8 hdr[SIPC5_MAX_HEADER_SIZE];
++};
++
++struct vnet {
++      struct io_device *iod;
++};
++
++/* for fragmented data from link devices */
++struct fragmented_data {
++      struct sk_buff *skb_recv;
++      struct header_data h_data;
++      struct sipc5_frame_data f_data;
++      /* page alloc fail retry*/
++      unsigned realloc_offset;
++};
++#define fragdata(iod, ld) (&(iod)->fragments[(ld)->link_type])
++
++/** struct skbuff_priv - private data of struct sk_buff
++ * this is matched to char cb[48] of struct sk_buff
++ */
++struct skbuff_private {
++      struct io_device *iod;
++      struct link_device *ld;
++      struct io_device *real_iod; /* for rx multipdp */
++      u8 ch_id;
++      u8 control;
++} __packed;
++
++static inline struct skbuff_private *skbpriv(struct sk_buff *skb)
++{
++      BUILD_BUG_ON(sizeof(struct skbuff_private) > sizeof(skb->cb));
++      return (struct skbuff_private *)&skb->cb;
++}
++
++struct io_device {
++      /* rb_tree node for an io device */
++      struct rb_node node_chan;
++      struct rb_node node_fmt;
++
++      /* Name of the IO device */
++      char *name;
++
++      atomic_t opened;
++
++      /* Wait queue for the IO device */
++      wait_queue_head_t wq;
++
++      /* Misc and net device structures for the IO device */
++      struct miscdevice  miscdev;
++      struct net_device *ndev;
++
++      /* ID and Format for channel on the link */
++      unsigned id;
++      enum modem_link link_types;
++      enum dev_format format;
++      enum modem_io io_typ;
++      enum modem_network net_typ;
++
++      bool use_handover;      /* handover 2+ link devices */
++
++      /* SIPC version */
++      enum sipc_ver ipc_version;
++
++      /* Rx queue of sk_buff */
++      struct sk_buff_head sk_rx_q;
++
++      /*
++      ** work for each io device, when delayed work needed
++      ** use this for private io device rx action
++      */
++      struct delayed_work rx_work;
++
++      struct fragmented_data fragments[LINKDEV_MAX];
++
++      /* for multi-frame */
++      struct sk_buff *skb[128];
++
++      /* called from linkdevice when a packet arrives for this iodevice */
++      int (*recv)(struct io_device *iod, struct link_device *ld,
++                                      const char *data, unsigned int len);
++      int (*recv_skb)(struct io_device *iod, struct link_device *ld,
++                                      struct sk_buff *skb);
++
++      /* inform the IO device that the modem is now online or offline or
++       * crashing or whatever...
++       */
++      void (*modem_state_changed)(struct io_device *iod, enum modem_state);
++
++      /* inform the IO device that the SIM is not inserting or removing */
++      void (*sim_state_changed)(struct io_device *iod, bool sim_online);
++
++      struct modem_ctl *mc;
++      struct modem_shared *msd;
++
++      struct wake_lock wakelock;
++      long waketime;
++
++      /* DO NOT use __current_link directly
++       * you MUST use skbpriv(skb)->ld in mc, link, etc..
++       */
++      struct link_device *__current_link;
++};
++#define to_io_device(misc) container_of(misc, struct io_device, miscdev)
++
++/* get_current_link, set_current_link don't need to use locks.
++ * In ARM, set_current_link and get_current_link are compiled to
++ * each one instruction (str, ldr) as atomic_set, atomic_read.
++ * And, the order of set_current_link and get_current_link is not important.
++ */
++#define get_current_link(iod) ((iod)->__current_link)
++#define set_current_link(iod, ld) ((iod)->__current_link = (ld))
++
++struct link_device {
++      struct list_head  list;
++      char *name;
++
++      enum modem_link link_type;
++      unsigned aligned;
++
++      /* Maximum IPC device = the last IPC device (e.g. IPC_RFS) + 1 */
++      int max_ipc_dev;
++
++      /* SIPC version */
++      enum sipc_ver ipc_version;
++
++      /* Modem data */
++      struct modem_data *mdm_data;
++
++      /* Modem control */
++      struct modem_ctl *mc;
++
++      /* Modem shared data */
++      struct modem_shared *msd;
++
++      /* Operation mode of the link device */
++      enum link_mode mode;
++
++      struct io_device *fmt_iods[4];
++
++      /* TX queue of socket buffers */
++      struct sk_buff_head sk_fmt_tx_q;
++      struct sk_buff_head sk_raw_tx_q;
++      struct sk_buff_head sk_rfs_tx_q;
++
++      struct sk_buff_head *skb_txq[MAX_IPC_DEV];
++
++      bool raw_tx_suspended; /* for misc dev */
++      struct completion raw_tx_resumed_by_cp;
++
++      struct workqueue_struct *tx_wq;
++      struct work_struct tx_work;
++      struct delayed_work tx_delayed_work;
++
++      struct delayed_work *tx_dwork[MAX_IPC_DEV];
++      struct delayed_work fmt_tx_dwork;
++      struct delayed_work raw_tx_dwork;
++      struct delayed_work rfs_tx_dwork;
++
++      struct workqueue_struct *rx_wq;
++      struct work_struct rx_work;
++      struct delayed_work rx_delayed_work;
++
++      enum com_state com_state;
++
++      /* init communication - setting link driver */
++      int (*init_comm)(struct link_device *ld, struct io_device *iod);
++
++      /* terminate communication */
++      void (*terminate_comm)(struct link_device *ld, struct io_device *iod);
++
++      /* called by an io_device when it has a packet to send over link
++       * - the io device is passed so the link device can look at id and
++       *   format fields to determine how to route/format the packet
++       */
++      int (*send)(struct link_device *ld, struct io_device *iod,
++                      struct sk_buff *skb);
++
++      int (*udl_start)(struct link_device *ld, struct io_device *iod);
++
++      int (*force_dump)(struct link_device *ld, struct io_device *iod);
++
++      int (*dump_start)(struct link_device *ld, struct io_device *iod);
++
++      int (*modem_update)(struct link_device *ld, struct io_device *iod,
++                      unsigned long arg);
++
++      int (*dump_update)(struct link_device *ld, struct io_device *iod,
++                      unsigned long arg);
++
++      int (*ioctl)(struct link_device *ld, struct io_device *iod,
++                      unsigned cmd, unsigned long _arg);
++};
++
++/** rx_alloc_skb - allocate an skbuff and set skb's iod, ld
++ * @length:   length to allocate
++ * @iod:      struct io_device *
++ * @ld:               struct link_device *
++ *
++ * %NULL is returned if there is no free memory.
++ */
++static inline struct sk_buff *rx_alloc_skb(unsigned int length,
++              struct io_device *iod, struct link_device *ld)
++{
++      struct sk_buff *skb;
++
++      if (iod->format == IPC_MULTI_RAW || iod->format == IPC_RAW)
++              skb = dev_alloc_skb(length);
++      else
++              skb = alloc_skb(length, GFP_ATOMIC);
++
++      if (likely(skb)) {
++              skbpriv(skb)->iod = iod;
++              skbpriv(skb)->ld = ld;
++      }
++      return skb;
++}
++
++struct modemctl_ops {
++      int (*modem_on) (struct modem_ctl *);
++      int (*modem_off) (struct modem_ctl *);
++      int (*modem_reset) (struct modem_ctl *);
++      int (*modem_boot_on) (struct modem_ctl *);
++      int (*modem_boot_off) (struct modem_ctl *);
++      int (*modem_boot_done) (struct modem_ctl *);
++      int (*modem_force_crash_exit) (struct modem_ctl *);
++      int (*modem_dump_reset) (struct modem_ctl *);
++};
++
++/* for IPC Logger */
++struct mif_storage {
++      char *addr;
++      unsigned int cnt;
++};
++
++/* modem_shared - shared data for all io/link devices and a modem ctl
++ * msd : mc : iod : ld = 1 : 1 : M : N
++ */
++struct modem_shared {
++      /* list of link devices */
++      struct list_head link_dev_list;
++
++      /* rb_tree root of io devices. */
++      struct rb_root iodevs_tree_chan; /* group by channel */
++      struct rb_root iodevs_tree_fmt; /* group by dev_format */
++
++      /* for IPC Logger */
++      struct mif_storage storage;
++      spinlock_t lock;
++
++      /* loopbacked IP address
++       * default is 0.0.0.0 (disabled)
++       * after you setted this, you can use IP packet loopback using this IP.
++       * exam: echo 1.2.3.4 > /sys/devices/virtual/misc/umts_multipdp/loopback
++       */
++      __be32 loopback_ipaddr;
++};
++
++struct modem_ctl {
++      struct device *dev;
++      char *name;
++      struct modem_data *mdm_data;
++
++      struct modem_shared *msd;
++
++      enum modem_state phone_state;
++      struct sim_state sim_state;
++
++      unsigned gpio_cp_on;
++      unsigned gpio_reset_req_n;
++      unsigned gpio_cp_reset;
++      unsigned gpio_pda_active;
++      unsigned gpio_phone_active;
++      unsigned gpio_cp_dump_int;
++      unsigned gpio_ap_dump_int;
++      unsigned gpio_flm_uart_sel;
++#if defined(CONFIG_MACH_M0_CTC)
++      unsigned gpio_flm_uart_sel_rev06;
++#endif
++      unsigned gpio_cp_warm_reset;
++      unsigned gpio_cp_off;
++      unsigned gpio_sim_detect;
++      unsigned gpio_dynamic_switching;
++
++      int irq_phone_active;
++      int irq_sim_detect;
++
++#ifdef CONFIG_LTE_MODEM_CMC221
++      const struct attribute_group *group;
++      unsigned gpio_slave_wakeup;
++      unsigned gpio_host_wakeup;
++      unsigned gpio_host_active;
++      int      irq_host_wakeup;
++
++      struct delayed_work dwork;
++#endif /*CONFIG_LTE_MODEM_CMC221*/
++#if defined(CONFIG_MACH_GRANDE)
++      struct delayed_work sim_det_dwork;
++#endif /* For checking sim detect pin */
++      struct work_struct work;
++
++#if defined(CONFIG_MACH_U1_KOR_LGT)
++      unsigned gpio_cp_reset_msm;
++      unsigned gpio_boot_sw_sel;
++      void (*vbus_on)(void);
++      void (*vbus_off)(void);
++      bool usb_boot;
++#endif
++
++      struct modemctl_ops ops;
++      struct io_device *iod;
++      struct io_device *bootd;
++
++      /* Wakelock for modem_ctl */
++      struct wake_lock mc_wake_lock;
++
++      void (*gpio_revers_bias_clear)(void);
++      void (*gpio_revers_bias_restore)(void);
++
++      bool need_switch_to_usb;
++      bool sim_polarity;
++};
++
++int sipc4_init_io_device(struct io_device *iod);
++int sipc5_init_io_device(struct io_device *iod);
++
++/**
++ * get_dev_name
++ * @dev: IPC device (enum dev_format)
++ *
++ * Returns IPC device name as a string.
++ *
++ */
++static const inline char *get_dev_name(int dev)
++{
++      if (dev == IPC_FMT)
++              return "FMT";
++      else if (dev == IPC_RAW)
++              return "RAW";
++      else if (dev == IPC_RFS)
++              return "RFS";
++      else if (dev == IPC_BOOT)
++              return "BOOT";
++      else if (dev == IPC_RAMDUMP)
++              return "DUMP";
++      else
++              return "NONE";
++}
++
++/**
++ * sipc5_start_valid
++ * @cfg: configuration field of an SIPC5 link frame
++ *
++ * Returns TRUE if the start (configuration field) of an SIPC5 link frame
++ * is valid or returns FALSE if it is not valid.
++ *
++ */
++static inline int sipc5_start_valid(u8 cfg)
++{
++      return (cfg & SIPC5_START_MASK) == SIPC5_START_MASK;
++}
++
++/**
++ * sipc5_get_hdr_len
++ * @cfg: configuration field of an SIPC5 link frame
++ *
++ * Returns the length of SIPC5 link layer header in an SIPC5 link frame
++ *
++ */
++static inline unsigned sipc5_get_hdr_len(u8 cfg)
++{
++      if (cfg & SIPC5_EXT_FIELD_EXIST) {
++              if (cfg & SIPC5_CTL_FIELD_EXIST)
++                      return SIPC5_HEADER_SIZE_WITH_CTL_FLD;
++              else
++                      return SIPC5_HEADER_SIZE_WITH_EXT_LEN;
++      } else {
++              return SIPC5_MIN_HEADER_SIZE;
++      }
++}
++
++/**
++ * sipc5_get_ch_id
++ * @frm: pointer to an SIPC5 frame
++ *
++ * Returns the channel ID in an SIPC5 link frame
++ *
++ */
++static inline u8 sipc5_get_ch_id(u8 *frm)
++{
++      return *(frm + SIPC5_CH_ID_OFFSET);
++}
++
++/**
++ * sipc5_get_frame_sz16
++ * @frm: pointer to an SIPC5 link frame
++ *
++ * Returns the length of an SIPC5 link frame without the extended length field
++ *
++ */
++static inline unsigned sipc5_get_frame_sz16(u8 *frm)
++{
++      return *((u16 *)(frm + SIPC5_LEN_OFFSET));
++}
++
++/**
++ * sipc5_get_frame_sz32
++ * @frm: pointer to an SIPC5 frame
++ *
++ * Returns the length of an SIPC5 link frame with the extended length field
++ *
++ */
++static inline unsigned sipc5_get_frame_sz32(u8 *frm)
++{
++      return *((u32 *)(frm + SIPC5_LEN_OFFSET));
++}
++
++/**
++ * sipc5_calc_padding_size
++ * @len: length of an SIPC5 link frame
++ *
++ * Returns the padding size for an SIPC5 link frame
++ *
++ */
++static inline unsigned sipc5_calc_padding_size(unsigned len)
++{
++      unsigned residue = len & 0x3;
++      return residue ? (4 - residue) : 0;
++}
++
++/**
++ * sipc5_check_frame_in_dev
++ * @ld: pointer to the link device structure
++ * @dev: IPC device (enum dev_format)
++ * @frm: pointer to the start of an SIPC5 frame
++ * @rest: size of the rest data in the device buffer including this frame
++ *
++ * Returns
++ *  < 0  : error
++ *  == 0 : no data
++ *  > 0  : valid data
++ *
++ */
++static inline int sipc5_check_frame_in_dev(struct link_device *ld, int dev,
++                      u8 *frm, int rest)
++{
++      unsigned int len;
++
++      if (unlikely(!sipc5_start_valid(frm[0]))) {
++              mif_err("%s: ERR! %s invalid start 0x%02X\n",
++                      ld->name, get_dev_name(dev), frm[0]);
++              return -EBADMSG;
++      }
++
++      len = sipc5_get_frame_sz16(frm);
++      if (unlikely(len > rest)) {
++              mif_err("%s: ERR! %s len %d > rest %d\n",
++                      ld->name, get_dev_name(dev), len, rest);
++              return -EBADMSG;
++      }
++
++      return len;
++}
++
++extern void set_sromc_access(bool access);
++
++#endif
+diff --git a/drivers/misc/modem_if/modem_sim_slot_switch.c b/drivers/misc/modem_if/modem_sim_slot_switch.c
+new file mode 100644
+index 0000000..1dd4c67
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_sim_slot_switch.c
+@@ -0,0 +1,92 @@
++#include <linux/i2c.h>
++#include <linux/gpio.h>
++#include <linux/delay.h>
++#include <linux/err.h>
++
++#include <plat/gpio-cfg.h>
++
++#include <mach/gpio.h>
++
++extern struct class *sec_class;
++struct device *slot_switch_dev;
++
++static ssize_t get_slot_switch(struct device *dev, struct device_attribute *attr, char *buf)
++{
++      int value;
++
++      //return '0' slot path is '||', return '1' slot path is 'X'
++      value = gpio_get_value(GPIO_UIM_SIM_SEL);
++      printk("Current Slot is %x\n", value);
++
++      return sprintf(buf, "%d\n", value);
++}
++
++static ssize_t set_slot_switch(struct device *dev, struct device_attribute *attr,   const char *buf, size_t size)
++{
++      int value;
++
++      sscanf(buf, "%d", &value);
++
++      switch(value) {
++              case 0:
++                      gpio_set_value(GPIO_UIM_SIM_SEL, 0);
++                      printk("set slot switch to %x\n", gpio_get_value(GPIO_UIM_SIM_SEL));
++                      break;
++              case 1:
++                      gpio_set_value(GPIO_UIM_SIM_SEL, 1);
++                      printk("set slot switch to %x\n", gpio_get_value(GPIO_UIM_SIM_SEL));
++                      break;
++              default:
++                      printk("Enter 0 or 1!!\n");
++      }
++
++      return size;
++}
++
++static DEVICE_ATTR(slot_sel, S_IRUGO |S_IWUGO | S_IRUSR | S_IWUSR, get_slot_switch, set_slot_switch);
++
++static int __init slot_switch_manager_init(void)
++{
++      int ret = 0;
++      int err = 0;
++
++      printk("slot_switch_manager_init\n");
++
++    //initailize uim_sim_switch gpio
++      err = gpio_request(GPIO_UIM_SIM_SEL, "PDA_ACTIVE");
++      if (err) {
++              pr_err("fail to request gpio %s, gpio %d, errno %d\n",
++                                      "PDA_ACTIVE", GPIO_UIM_SIM_SEL, err);
++      } else {
++              gpio_direction_output(GPIO_UIM_SIM_SEL, 1);
++              s3c_gpio_setpull(GPIO_UIM_SIM_SEL, S3C_GPIO_PULL_NONE);
++#if defined(CONFIG_MACH_T0_CHN_CTC)
++              gpio_set_value(GPIO_UIM_SIM_SEL, 1);
++#else
++              gpio_set_value(GPIO_UIM_SIM_SEL, 0);
++#endif
++      }
++
++      //initailize slot switch device
++      slot_switch_dev = device_create(sec_class,
++                                    NULL, 0, NULL, "slot_switch");
++      if (IS_ERR(slot_switch_dev))
++              pr_err("Failed to create device(switch)!\n");
++
++      if (device_create_file(slot_switch_dev, &dev_attr_slot_sel) < 0)
++              pr_err("Failed to create device file(%s)!\n",
++                                      dev_attr_slot_sel.attr.name);
++
++      return ret;
++}
++
++static void __exit slot_switch_manager_exit(void)
++{
++}
++
++module_init(slot_switch_manager_init);
++module_exit(slot_switch_manager_exit);
++
++MODULE_AUTHOR("SAMSUNG ELECTRONICS CO., LTD");
++MODULE_DESCRIPTION("Slot Switch");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/misc/modem_if/modem_utils.c b/drivers/misc/modem_if/modem_utils.c
+new file mode 100644
+index 0000000..a2def11
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_utils.c
+@@ -0,0 +1,1227 @@
++/*
++ * Copyright (C) 2011 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/interrupt.h>
++#include <linux/miscdevice.h>
++#include <linux/netdevice.h>
++#include <linux/skbuff.h>
++#include <linux/ip.h>
++#include <net/ip.h>
++#include <linux/tcp.h>
++#include <linux/udp.h>
++#include <linux/rtc.h>
++#include <linux/time.h>
++
++#include <linux/uaccess.h>
++#include <linux/fs.h>
++#include <linux/io.h>
++#include <linux/wait.h>
++#include <linux/time.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/mutex.h>
++#include <linux/irq.h>
++#include <linux/gpio.h>
++#include <linux/delay.h>
++#include <linux/wakelock.h>
++
++#include <linux/platform_data/modem.h>
++#include "modem_prj.h"
++#include "modem_variation.h"
++#include "modem_utils.h"
++
++#define CMD_SUSPEND   ((unsigned short)(0x00CA))
++#define CMD_RESUME    ((unsigned short)(0x00CB))
++
++#define TX_SEPARATOR  "mif: >>>>>>>>>> Outgoing packet "
++#define RX_SEPARATOR  "mif: Incoming packet <<<<<<<<<<"
++#define LINE_SEPARATOR        \
++      "mif: ------------------------------------------------------------"
++#define LINE_BUFF_SIZE        80
++
++static const char *hex = "0123456789abcdef";
++
++void ts2utc(struct timespec *ts, struct utc_time *utc)
++{
++      struct tm tm;
++
++      time_to_tm((ts->tv_sec - (sys_tz.tz_minuteswest * 60)), 0, &tm);
++      utc->year = 1900 + tm.tm_year;
++      utc->mon = 1 + tm.tm_mon;
++      utc->day = tm.tm_mday;
++      utc->hour = tm.tm_hour;
++      utc->min = tm.tm_min;
++      utc->sec = tm.tm_sec;
++      utc->msec = (ts->tv_nsec > 0) ? (ts->tv_nsec / 1000000) : 0;
++}
++
++void get_utc_time(struct utc_time *utc)
++{
++      struct timespec ts;
++      getnstimeofday(&ts);
++      ts2utc(&ts, utc);
++}
++
++#ifdef CONFIG_LINK_DEVICE_DPRAM
++#include "modem_link_device_dpram.h"
++int mif_dump_dpram(struct io_device *iod)
++{
++      struct link_device *ld = get_current_link(iod);
++      struct dpram_link_device *dpld = to_dpram_link_device(ld);
++      u32 size = dpld->size;
++      unsigned long read_len = 0;
++      struct sk_buff *skb;
++      char *buff;
++
++      buff = kzalloc(size, GFP_ATOMIC);
++      if (!buff) {
++              mif_err("ERR! kzalloc fail\n");
++              return -ENOMEM;
++      } else {
++              dpld->dpram_dump(ld, buff);
++      }
++
++      while (read_len < size) {
++              skb = alloc_skb(MAX_IPC_SKB_SIZE, GFP_ATOMIC);
++              if (!skb) {
++                      mif_err("ERR! alloc_skb fail\n");
++                      kfree(buff);
++                      return -ENOMEM;
++              }
++              memcpy(skb_put(skb, MAX_IPC_SKB_SIZE),
++                      buff + read_len, MAX_IPC_SKB_SIZE);
++              skb_queue_tail(&iod->sk_rx_q, skb);
++              read_len += MAX_IPC_SKB_SIZE;
++              wake_up(&iod->wq);
++      }
++      kfree(buff);
++      return 0;
++}
++#endif
++
++int mif_dump_log(struct modem_shared *msd, struct io_device *iod)
++{
++      struct sk_buff *skb;
++      unsigned long read_len = 0;
++      unsigned long int flags;
++
++      spin_lock_irqsave(&msd->lock, flags);
++      while (read_len < MAX_MIF_BUFF_SIZE) {
++              skb = alloc_skb(MAX_IPC_SKB_SIZE, GFP_ATOMIC);
++              if (!skb) {
++                      mif_err("ERR! alloc_skb fail\n");
++                      spin_unlock_irqrestore(&msd->lock, flags);
++                      return -ENOMEM;
++              }
++              memcpy(skb_put(skb, MAX_IPC_SKB_SIZE),
++                      msd->storage.addr + read_len, MAX_IPC_SKB_SIZE);
++              skb_queue_tail(&iod->sk_rx_q, skb);
++              read_len += MAX_IPC_SKB_SIZE;
++              wake_up(&iod->wq);
++      }
++      spin_unlock_irqrestore(&msd->lock, flags);
++      return 0;
++}
++
++static unsigned long long get_kernel_time(void)
++{
++      int this_cpu;
++      unsigned long flags;
++      unsigned long long time;
++
++      preempt_disable();
++      raw_local_irq_save(flags);
++
++      this_cpu = smp_processor_id();
++      time = cpu_clock(this_cpu);
++
++      preempt_enable();
++      raw_local_irq_restore(flags);
++
++      return time;
++}
++
++void mif_ipc_log(enum mif_log_id id,
++      struct modem_shared *msd, const char *data, size_t len)
++{
++      struct mif_ipc_block *block;
++      unsigned long int flags;
++
++      spin_lock_irqsave(&msd->lock, flags);
++
++      block = (struct mif_ipc_block *)
++              (msd->storage.addr + (MAX_LOG_SIZE * msd->storage.cnt));
++      msd->storage.cnt = ((msd->storage.cnt + 1) < MAX_LOG_CNT) ?
++              msd->storage.cnt + 1 : 0;
++
++      spin_unlock_irqrestore(&msd->lock, flags);
++
++      block->id = id;
++      block->time = get_kernel_time();
++      block->len = (len > MAX_IPC_LOG_SIZE) ? MAX_IPC_LOG_SIZE : len;
++      memcpy(block->buff, data, block->len);
++}
++
++void _mif_irq_log(enum mif_log_id id, struct modem_shared *msd,
++      struct mif_irq_map map, const char *data, size_t len)
++{
++      struct mif_irq_block *block;
++      unsigned long int flags;
++
++      spin_lock_irqsave(&msd->lock, flags);
++
++      block = (struct mif_irq_block *)
++              (msd->storage.addr + (MAX_LOG_SIZE * msd->storage.cnt));
++      msd->storage.cnt = ((msd->storage.cnt + 1) < MAX_LOG_CNT) ?
++              msd->storage.cnt + 1 : 0;
++
++      spin_unlock_irqrestore(&msd->lock, flags);
++
++      block->id = id;
++      block->time = get_kernel_time();
++      memcpy(&(block->map), &map, sizeof(struct mif_irq_map));
++      if (data)
++              memcpy(block->buff, data,
++                      (len > MAX_IRQ_LOG_SIZE) ? MAX_IRQ_LOG_SIZE : len);
++}
++
++void _mif_com_log(enum mif_log_id id,
++      struct modem_shared *msd, const char *format, ...)
++{
++      struct mif_common_block *block;
++      unsigned long int flags;
++      va_list args;
++      int ret;
++
++      spin_lock_irqsave(&msd->lock, flags);
++
++      block = (struct mif_common_block *)
++              (msd->storage.addr + (MAX_LOG_SIZE * msd->storage.cnt));
++      msd->storage.cnt = ((msd->storage.cnt + 1) < MAX_LOG_CNT) ?
++              msd->storage.cnt + 1 : 0;
++
++      spin_unlock_irqrestore(&msd->lock, flags);
++
++      block->id = id;
++      block->time = get_kernel_time();
++
++      va_start(args, format);
++      ret = vsnprintf(block->buff, MAX_COM_LOG_SIZE, format, args);
++      va_end(args);
++}
++
++void _mif_time_log(enum mif_log_id id, struct modem_shared *msd,
++      struct timespec epoch, const char *data, size_t len)
++{
++      struct mif_time_block *block;
++      unsigned long int flags;
++
++      spin_lock_irqsave(&msd->lock, flags);
++
++      block = (struct mif_time_block *)
++              (msd->storage.addr + (MAX_LOG_SIZE * msd->storage.cnt));
++      msd->storage.cnt = ((msd->storage.cnt + 1) < MAX_LOG_CNT) ?
++              msd->storage.cnt + 1 : 0;
++
++      spin_unlock_irqrestore(&msd->lock, flags);
++
++      block->id = id;
++      block->time = get_kernel_time();
++      memcpy(&block->epoch, &epoch, sizeof(struct timespec));
++
++      if (data)
++              memcpy(block->buff, data,
++                      (len > MAX_IRQ_LOG_SIZE) ? MAX_IRQ_LOG_SIZE : len);
++}
++
++/* dump2hex
++ * dump data to hex as fast as possible.
++ * the length of @buff must be greater than "@len * 3"
++ * it need 3 bytes per one data byte to print.
++ */
++static inline int dump2hex(char *buff, const char *data, size_t len)
++{
++      char *dest = buff;
++      int i;
++
++      for (i = 0; i < len; i++) {
++              *dest++ = hex[(data[i] >> 4) & 0xf];
++              *dest++ = hex[data[i] & 0xf];
++              *dest++ = ' ';
++      }
++      if (likely(len > 0))
++              dest--; /* last space will be overwrited with null */
++
++      *dest = '\0';
++
++      return dest - buff;
++}
++
++void pr_ipc(const char *tag, const char *data, size_t len)
++{
++      struct utc_time utc;
++      unsigned char str[128];
++
++      get_utc_time(&utc);
++      dump2hex(str, data, (len > 32 ? 32 : len));
++      pr_info("%s: %s: [%02d:%02d:%02d.%03d] %s\n",
++              MIF_TAG, tag, utc.hour, utc.min, utc.sec, utc.msec, str);
++}
++
++/* print buffer as hex string */
++int pr_buffer(const char *tag, const char *data, size_t data_len,
++                                                      size_t max_len)
++{
++      size_t len = min(data_len, max_len);
++      unsigned char str[len ? len * 3 : 1]; /* 1 <= sizeof <= max_len*3 */
++      dump2hex(str, data, len);
++
++      /* don't change this printk to mif_debug for print this as level7 */
++      return printk(KERN_INFO "%s: %s(%u): %s%s\n", MIF_TAG, tag, data_len,
++                      str, (len == data_len) ? "" : " ...");
++}
++
++/* flow control CM from CP, it use in serial devices */
++int link_rx_flowctl_cmd(struct link_device *ld, const char *data, size_t len)
++{
++      struct modem_shared *msd = ld->msd;
++      unsigned short *cmd, *end = (unsigned short *)(data + len);
++
++      mif_debug("flow control cmd: size=%d\n", len);
++
++      for (cmd = (unsigned short *)data; cmd < end; cmd++) {
++              switch (*cmd) {
++              case CMD_SUSPEND:
++                      iodevs_for_each(msd, iodev_netif_stop, 0);
++                      ld->raw_tx_suspended = true;
++                      mif_info("flowctl CMD_SUSPEND(%04X)\n", *cmd);
++                      break;
++
++              case CMD_RESUME:
++                      iodevs_for_each(msd, iodev_netif_wake, 0);
++                      ld->raw_tx_suspended = false;
++                      complete_all(&ld->raw_tx_resumed_by_cp);
++                      mif_info("flowctl CMD_RESUME(%04X)\n", *cmd);
++                      break;
++
++              default:
++                      mif_err("flowctl BACMD: %04X\n", *cmd);
++                      break;
++              }
++      }
++
++      return 0;
++}
++
++struct io_device *get_iod_with_channel(struct modem_shared *msd,
++                                      unsigned channel)
++{
++      struct rb_node *n = msd->iodevs_tree_chan.rb_node;
++      struct io_device *iodev;
++      while (n) {
++              iodev = rb_entry(n, struct io_device, node_chan);
++              if (channel < iodev->id)
++                      n = n->rb_left;
++              else if (channel > iodev->id)
++                      n = n->rb_right;
++              else
++                      return iodev;
++      }
++      return NULL;
++}
++
++struct io_device *get_iod_with_format(struct modem_shared *msd,
++                      enum dev_format format)
++{
++      struct rb_node *n = msd->iodevs_tree_fmt.rb_node;
++      struct io_device *iodev;
++      while (n) {
++              iodev = rb_entry(n, struct io_device, node_fmt);
++              if (format < iodev->format)
++                      n = n->rb_left;
++              else if (format > iodev->format)
++                      n = n->rb_right;
++              else
++                      return iodev;
++      }
++      return NULL;
++}
++
++struct io_device *insert_iod_with_channel(struct modem_shared *msd,
++              unsigned channel, struct io_device *iod)
++{
++      struct rb_node **p = &msd->iodevs_tree_chan.rb_node;
++      struct rb_node *parent = NULL;
++      struct io_device *iodev;
++      while (*p) {
++              parent = *p;
++              iodev = rb_entry(parent, struct io_device, node_chan);
++              if (channel < iodev->id)
++                      p = &(*p)->rb_left;
++              else if (channel > iodev->id)
++                      p = &(*p)->rb_right;
++              else
++                      return iodev;
++      }
++      rb_link_node(&iod->node_chan, parent, p);
++      rb_insert_color(&iod->node_chan, &msd->iodevs_tree_chan);
++      return NULL;
++}
++
++struct io_device *insert_iod_with_format(struct modem_shared *msd,
++              enum dev_format format, struct io_device *iod)
++{
++      struct rb_node **p = &msd->iodevs_tree_fmt.rb_node;
++      struct rb_node *parent = NULL;
++      struct io_device *iodev;
++      while (*p) {
++              parent = *p;
++              iodev = rb_entry(parent, struct io_device, node_fmt);
++              if (format < iodev->format)
++                      p = &(*p)->rb_left;
++              else if (format > iodev->format)
++                      p = &(*p)->rb_right;
++              else
++                      return iodev;
++      }
++      rb_link_node(&iod->node_fmt, parent, p);
++      rb_insert_color(&iod->node_fmt, &msd->iodevs_tree_fmt);
++      return NULL;
++}
++
++void iodevs_for_each(struct modem_shared *msd, action_fn action, void *args)
++{
++      struct io_device *iod;
++      struct rb_node *node = rb_first(&msd->iodevs_tree_chan);
++      for (; node; node = rb_next(node)) {
++              iod = rb_entry(node, struct io_device, node_chan);
++              action(iod, args);
++      }
++}
++
++void iodev_netif_wake(struct io_device *iod, void *args)
++{
++      if (iod->io_typ == IODEV_NET && iod->ndev) {
++              netif_wake_queue(iod->ndev);
++              mif_info("%s\n", iod->name);
++      }
++}
++
++void iodev_netif_stop(struct io_device *iod, void *args)
++{
++      if (iod->io_typ == IODEV_NET && iod->ndev) {
++              netif_stop_queue(iod->ndev);
++              mif_info("%s\n", iod->name);
++      }
++}
++
++static void iodev_set_tx_link(struct io_device *iod, void *args)
++{
++      struct link_device *ld = (struct link_device *)args;
++      if (iod->format == IPC_RAW && IS_CONNECTED(iod, ld)) {
++              set_current_link(iod, ld);
++              mif_err("%s -> %s\n", iod->name, ld->name);
++      }
++}
++
++void rawdevs_set_tx_link(struct modem_shared *msd, enum modem_link link_type)
++{
++      struct link_device *ld = find_linkdev(msd, link_type);
++      if (ld)
++              iodevs_for_each(msd, iodev_set_tx_link, ld);
++}
++
++void mif_netif_stop(struct link_device *ld)
++{
++      struct io_device *iod;
++
++      if (ld->ipc_version < SIPC_VER_50)
++              iod = link_get_iod_with_channel(ld, 0x20 | RMNET0_CH_ID);
++      else
++              iod = link_get_iod_with_channel(ld, RMNET0_CH_ID);
++
++      if (iod)
++              iodevs_for_each(iod->msd, iodev_netif_stop, 0);
++}
++
++void mif_netif_wake(struct link_device *ld)
++{
++      struct io_device *iod;
++
++      if (ld->ipc_version < SIPC_VER_50)
++              iod = link_get_iod_with_channel(ld, 0x20 | RMNET0_CH_ID);
++      else
++              iod = link_get_iod_with_channel(ld, RMNET0_CH_ID);
++
++      if (iod)
++              iodevs_for_each(iod->msd, iodev_netif_wake, 0);
++}
++
++/**
++ * ipv4str_to_be32 - ipv4 string to be32 (big endian 32bits integer)
++ * @return: return zero when errors occurred
++ */
++__be32 ipv4str_to_be32(const char *ipv4str, size_t count)
++{
++      unsigned char ip[4];
++      char ipstr[16]; /* == strlen("xxx.xxx.xxx.xxx") + 1 */
++      char *next = ipstr;
++      char *p;
++      int i;
++
++      strncpy(ipstr, ipv4str, ARRAY_SIZE(ipstr));
++
++      for (i = 0; i < 4; i++) {
++              p = strsep(&next, ".");
++              if (kstrtou8(p, 10, &ip[i]) < 0)
++                      return 0; /* == 0.0.0.0 */
++      }
++
++      return *((__be32 *)ip);
++}
++
++void mif_add_timer(struct timer_list *timer, unsigned long expire,
++              void (*function)(unsigned long), unsigned long data)
++{
++      if (timer_pending(timer))
++              return;
++
++      init_timer(timer);
++      timer->expires = get_jiffies_64() + expire;
++      timer->function = function;
++      timer->data = data;
++      add_timer(timer);
++}
++
++void mif_print_data(const char *buff, int len)
++{
++      int words = len >> 4;
++      int residue = len - (words << 4);
++      int i;
++      char *b;
++      char last[80];
++      char tb[8];
++
++      /* Make the last line, if ((len % 16) > 0) */
++      if (residue > 0) {
++              memset(last, 0, sizeof(last));
++              memset(tb, 0, sizeof(tb));
++              b = (char *)buff + (words << 4);
++
++              sprintf(last, "%04X: ", (words << 4));
++              for (i = 0; i < residue; i++) {
++                      sprintf(tb, "%02x ", b[i]);
++                      strcat(last, tb);
++                      if ((i & 0x3) == 0x3) {
++                              sprintf(tb, " ");
++                              strcat(last, tb);
++                      }
++              }
++      }
++
++      for (i = 0; i < words; i++) {
++              b = (char *)buff + (i << 4);
++              mif_err("%04X: "
++                      "%02x %02x %02x %02x  %02x %02x %02x %02x  "
++                      "%02x %02x %02x %02x  %02x %02x %02x %02x\n",
++                      (i << 4),
++                      b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7],
++                      b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]);
++      }
++
++      /* Print the last line */
++      if (residue > 0)
++              mif_err("%s\n", last);
++}
++
++void mif_dump2format16(const char *data, int len, char *buff, char *tag)
++{
++      char *d;
++      int i;
++      int words = len >> 4;
++      int residue = len - (words << 4);
++      char line[LINE_BUFF_SIZE];
++      char tb[8];
++
++      for (i = 0; i < words; i++) {
++              memset(line, 0, LINE_BUFF_SIZE);
++              d = (char *)data + (i << 4);
++
++              if (tag)
++                      sprintf(line, "%s%04X| "
++                              "%02x %02x %02x %02x  "
++                              "%02x %02x %02x %02x  "
++                              "%02x %02x %02x %02x  "
++                              "%02x %02x %02x %02x\n",
++                              tag, (i << 4),
++                              d[0], d[1], d[2], d[3],
++                              d[4], d[5], d[6], d[7],
++                              d[8], d[9], d[10], d[11],
++                              d[12], d[13], d[14], d[15]);
++              else
++                      sprintf(line, "%04X| "
++                              "%02x %02x %02x %02x  "
++                              "%02x %02x %02x %02x  "
++                              "%02x %02x %02x %02x  "
++                              "%02x %02x %02x %02x\n",
++                              (i << 4),
++                              d[0], d[1], d[2], d[3],
++                              d[4], d[5], d[6], d[7],
++                              d[8], d[9], d[10], d[11],
++                              d[12], d[13], d[14], d[15]);
++
++              strcat(buff, line);
++      }
++
++      /* Make the last line, if (len % 16) > 0 */
++      if (residue > 0) {
++              memset(line, 0, LINE_BUFF_SIZE);
++              memset(tb, 0, sizeof(tb));
++              d = (char *)data + (words << 4);
++
++              if (tag)
++                      sprintf(line, "%s%04X|", tag, (words << 4));
++              else
++                      sprintf(line, "%04X|", (words << 4));
++
++              for (i = 0; i < residue; i++) {
++                      sprintf(tb, " %02x", d[i]);
++                      strcat(line, tb);
++                      if ((i & 0x3) == 0x3) {
++                              sprintf(tb, " ");
++                              strcat(line, tb);
++                      }
++              }
++              strcat(line, "\n");
++
++              strcat(buff, line);
++      }
++}
++
++void mif_dump2format4(const char *data, int len, char *buff, char *tag)
++{
++      char *d;
++      int i;
++      int words = len >> 2;
++      int residue = len - (words << 2);
++      char line[LINE_BUFF_SIZE];
++      char tb[8];
++
++      for (i = 0; i < words; i++) {
++              memset(line, 0, LINE_BUFF_SIZE);
++              d = (char *)data + (i << 2);
++
++              if (tag)
++                      sprintf(line, "%s%04X| %02x %02x %02x %02x\n",
++                              tag, (i << 2), d[0], d[1], d[2], d[3]);
++              else
++                      sprintf(line, "%04X| %02x %02x %02x %02x\n",
++                              (i << 2), d[0], d[1], d[2], d[3]);
++
++              strcat(buff, line);
++      }
++
++      /* Make the last line, if (len % 4) > 0 */
++      if (residue > 0) {
++              memset(line, 0, LINE_BUFF_SIZE);
++              memset(tb, 0, sizeof(tb));
++              d = (char *)data + (words << 2);
++
++              if (tag)
++                      sprintf(line, "%s%04X|", tag, (words << 2));
++              else
++                      sprintf(line, "%04X|", (words << 2));
++
++              for (i = 0; i < residue; i++) {
++                      sprintf(tb, " %02x", d[i]);
++                      strcat(line, tb);
++              }
++              strcat(line, "\n");
++
++              strcat(buff, line);
++      }
++}
++
++void mif_print_dump(const char *data, int len, int width)
++{
++      char *buff;
++
++      buff = kzalloc(len << 3, GFP_ATOMIC);
++      if (!buff) {
++              mif_err("ERR! kzalloc fail\n");
++              return;
++      }
++
++      if (width == 16)
++              mif_dump2format16(data, len, buff, LOG_TAG);
++      else
++              mif_dump2format4(data, len, buff, LOG_TAG);
++
++      pr_info("%s", buff);
++
++      kfree(buff);
++}
++
++void print_sipc4_hdlc_fmt_frame(const u8 *psrc)
++{
++      u8 *frm;                        /* HDLC Frame   */
++      struct fmt_hdr *hh;             /* HDLC Header  */
++      struct sipc_fmt_hdr *fh;        /* IPC Header   */
++      u16 hh_len = sizeof(struct fmt_hdr);
++      u16 fh_len = sizeof(struct sipc_fmt_hdr);
++      u8 *data;
++      int dlen;
++
++      /* Actual HDLC header starts from after START flag (0x7F) */
++      frm = (u8 *)(psrc + 1);
++
++      /* Point HDLC header and IPC header */
++      hh = (struct fmt_hdr *)(frm);
++      fh = (struct sipc_fmt_hdr *)(frm + hh_len);
++
++      /* Point IPC data */
++      data = frm + (hh_len + fh_len);
++      dlen = hh->len - (hh_len + fh_len);
++
++      mif_err("--------------------HDLC & FMT HEADER----------------------\n");
++
++      mif_err("HDLC: length %d, control 0x%02x\n", hh->len, hh->control);
++
++      mif_err("(M)0x%02X, (S)0x%02X, (T)0x%02X, mseq %d, aseq %d, len %d\n",
++              fh->main_cmd, fh->sub_cmd, fh->cmd_type,
++              fh->msg_seq, fh->ack_seq, fh->len);
++
++      mif_err("-----------------------IPC FMT DATA------------------------\n");
++
++      if (dlen > 0) {
++              if (dlen > 64)
++                      dlen = 64;
++              mif_print_data(data, dlen);
++      }
++
++      mif_err("-----------------------------------------------------------\n");
++}
++
++void print_sipc4_fmt_frame(const u8 *psrc)
++{
++      struct sipc_fmt_hdr *fh = (struct sipc_fmt_hdr *)psrc;
++      u16 fh_len = sizeof(struct sipc_fmt_hdr);
++      u8 *data;
++      int dlen;
++
++      /* Point IPC data */
++      data = (u8 *)(psrc + fh_len);
++      dlen = fh->len - fh_len;
++
++      mif_err("----------------------IPC FMT HEADER-----------------------\n");
++
++      mif_err("(M)0x%02X, (S)0x%02X, (T)0x%02X, mseq:%d, aseq:%d, len:%d\n",
++              fh->main_cmd, fh->sub_cmd, fh->cmd_type,
++              fh->msg_seq, fh->ack_seq, fh->len);
++
++      mif_err("-----------------------IPC FMT DATA------------------------\n");
++
++      if (dlen > 0)
++              mif_print_data(data, dlen);
++
++      mif_err("-----------------------------------------------------------\n");
++}
++
++void print_sipc5_link_fmt_frame(const u8 *psrc)
++{
++      u8 *lf;                         /* Link Frame   */
++      struct sipc5_link_hdr *lh;      /* Link Header  */
++      struct sipc_fmt_hdr *fh;        /* IPC Header   */
++      u16 lh_len;
++      u16 fh_len;
++      u8 *data;
++      int dlen;
++
++      lf = (u8 *)psrc;
++
++      /* Point HDLC header and IPC header */
++      lh = (struct sipc5_link_hdr *)lf;
++      if (lh->cfg & SIPC5_CTL_FIELD_EXIST)
++              lh_len = SIPC5_HEADER_SIZE_WITH_CTL_FLD;
++      else
++              lh_len = SIPC5_MIN_HEADER_SIZE;
++      fh = (struct sipc_fmt_hdr *)(lf + lh_len);
++      fh_len = sizeof(struct sipc_fmt_hdr);
++
++      /* Point IPC data */
++      data = lf + (lh_len + fh_len);
++      dlen = lh->len - (lh_len + fh_len);
++
++      mif_err("--------------------LINK & FMT HEADER----------------------\n");
++
++      mif_err("LINK: cfg 0x%02X, ch %d, len %d\n", lh->cfg, lh->ch, lh->len);
++
++      mif_err("(M)0x%02X, (S)0x%02X, (T)0x%02X, mseq:%d, aseq:%d, len:%d\n",
++              fh->main_cmd, fh->sub_cmd, fh->cmd_type,
++              fh->msg_seq, fh->ack_seq, fh->len);
++
++      mif_err("-----------------------IPC FMT DATA------------------------\n");
++
++      if (dlen > 0) {
++              if (dlen > 64)
++                      dlen = 64;
++              mif_print_data(data, dlen);
++      }
++
++      mif_err("-----------------------------------------------------------\n");
++}
++
++static void strcat_tcp_header(char *buff, u8 *pkt)
++{
++      struct tcphdr *tcph = (struct tcphdr *)pkt;
++      int eol;
++      char line[LINE_BUFF_SIZE];
++      char flag_str[32];
++
++/*-------------------------------------------------------------------------
++
++                              TCP Header Format
++
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |          Source Port          |       Destination Port        |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |                        Sequence Number                        |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |                    Acknowledgment Number                      |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |  Data |       |C|E|U|A|P|R|S|F|                               |
++      | Offset| Rsvd  |W|C|R|C|S|S|Y|I|            Window             |
++      |       |       |R|E|G|K|H|T|N|N|                               |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |           Checksum            |         Urgent Pointer        |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |                    Options                    |    Padding    |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |                             data                              |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++
++-------------------------------------------------------------------------*/
++
++      memset(line, 0, LINE_BUFF_SIZE);
++      snprintf(line, LINE_BUFF_SIZE,
++              "%s: TCP:: Src.Port %u, Dst.Port %u\n",
++              MIF_TAG, ntohs(tcph->source), ntohs(tcph->dest));
++      strcat(buff, line);
++
++      memset(line, 0, LINE_BUFF_SIZE);
++      snprintf(line, LINE_BUFF_SIZE,
++              "%s: TCP:: SEQ 0x%08X(%u), ACK 0x%08X(%u)\n",
++              MIF_TAG, ntohs(tcph->seq), ntohs(tcph->seq),
++              ntohs(tcph->ack_seq), ntohs(tcph->ack_seq));
++      strcat(buff, line);
++
++      memset(line, 0, LINE_BUFF_SIZE);
++      memset(flag_str, 0, sizeof(flag_str));
++      if (tcph->cwr)
++              strcat(flag_str, "CWR ");
++      if (tcph->ece)
++              strcat(flag_str, "ECE");
++      if (tcph->urg)
++              strcat(flag_str, "URG ");
++      if (tcph->ack)
++              strcat(flag_str, "ACK ");
++      if (tcph->psh)
++              strcat(flag_str, "PSH ");
++      if (tcph->rst)
++              strcat(flag_str, "RST ");
++      if (tcph->syn)
++              strcat(flag_str, "SYN ");
++      if (tcph->fin)
++              strcat(flag_str, "FIN ");
++      eol = strlen(flag_str) - 1;
++      if (eol > 0)
++              flag_str[eol] = 0;
++      snprintf(line, LINE_BUFF_SIZE, "%s: TCP:: Flags {%s}\n",
++              MIF_TAG, flag_str);
++      strcat(buff, line);
++
++      memset(line, 0, LINE_BUFF_SIZE);
++      snprintf(line, LINE_BUFF_SIZE,
++              "%s: TCP:: Window %u, Checksum 0x%04X, Urgent %u\n", MIF_TAG,
++              ntohs(tcph->window), ntohs(tcph->check), ntohs(tcph->urg_ptr));
++      strcat(buff, line);
++}
++
++static void strcat_udp_header(char *buff, u8 *pkt)
++{
++      struct udphdr *udph = (struct udphdr *)pkt;
++      char line[LINE_BUFF_SIZE];
++
++/*-------------------------------------------------------------------------
++
++                              UDP Header Format
++
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |          Source Port          |       Destination Port        |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |            Length             |           Checksum            |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |                             data                              |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++
++-------------------------------------------------------------------------*/
++
++      memset(line, 0, LINE_BUFF_SIZE);
++      snprintf(line, LINE_BUFF_SIZE,
++              "%s: UDP:: Src.Port %u, Dst.Port %u\n",
++              MIF_TAG, ntohs(udph->source), ntohs(udph->dest));
++      strcat(buff, line);
++
++      memset(line, 0, LINE_BUFF_SIZE);
++      snprintf(line, LINE_BUFF_SIZE,
++              "%s: UDP:: Length %u, Checksum 0x%04X\n",
++              MIF_TAG, ntohs(udph->len), ntohs(udph->check));
++      strcat(buff, line);
++
++      if (ntohs(udph->dest) == 53) {
++              memset(line, 0, LINE_BUFF_SIZE);
++              snprintf(line, LINE_BUFF_SIZE, "%s: UDP:: DNS query!!!\n",
++                      MIF_TAG);
++              strcat(buff, line);
++      }
++
++      if (ntohs(udph->source) == 53) {
++              memset(line, 0, LINE_BUFF_SIZE);
++              snprintf(line, LINE_BUFF_SIZE, "%s: UDP:: DNS response!!!\n",
++                      MIF_TAG);
++              strcat(buff, line);
++      }
++}
++
++void print_ip4_packet(const u8 *ip_pkt, bool tx)
++{
++      char *buff;
++      struct iphdr *iph = (struct iphdr *)ip_pkt;
++      u8 *pkt = (u8 *)ip_pkt + (iph->ihl << 2);
++      u16 flags = (ntohs(iph->frag_off) & 0xE000);
++      u16 frag_off = (ntohs(iph->frag_off) & 0x1FFF);
++      int eol;
++      char line[LINE_BUFF_SIZE];
++      char flag_str[16];
++
++/*---------------------------------------------------------------------------
++                              IPv4 Header Format
++
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |Version|  IHL  |Type of Service|          Total Length         |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |         Identification        |C|D|M|     Fragment Offset     |
++      |                               |E|F|F|                         |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |  Time to Live |    Protocol   |         Header Checksum       |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |                       Source Address                          |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |                    Destination Address                        |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |                    Options                    |    Padding    |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++
++      IHL - Header Length
++      Flags - Consist of 3 bits
++              The 1st bit is "Congestion" bit.
++              The 2nd bit is "Dont Fragment" bit.
++              The 3rd bit is "More Fragments" bit.
++
++---------------------------------------------------------------------------*/
++
++      if (iph->version != 4)
++              return;
++
++      buff = kzalloc(4096, GFP_ATOMIC);
++      if (!buff)
++              return;
++
++
++      memset(line, 0, LINE_BUFF_SIZE);
++      if (tx)
++              snprintf(line, LINE_BUFF_SIZE, "\n%s\n", TX_SEPARATOR);
++      else
++              snprintf(line, LINE_BUFF_SIZE, "\n%s\n", RX_SEPARATOR);
++      strcat(buff, line);
++
++      memset(line, 0, LINE_BUFF_SIZE);
++      snprintf(line, LINE_BUFF_SIZE, "%s\n", LINE_SEPARATOR);
++      strcat(buff, line);
++
++      memset(line, 0, LINE_BUFF_SIZE);
++      snprintf(line, LINE_BUFF_SIZE,
++              "%s: IP4:: Version %u, Header Length %u, TOS %u, Length %u\n",
++              MIF_TAG, iph->version, (iph->ihl << 2), iph->tos,
++              ntohs(iph->tot_len));
++      strcat(buff, line);
++
++      memset(line, 0, LINE_BUFF_SIZE);
++      snprintf(line, LINE_BUFF_SIZE, "%s: IP4:: ID %u, Fragment Offset %u\n",
++              MIF_TAG, ntohs(iph->id), frag_off);
++      strcat(buff, line);
++
++      memset(line, 0, LINE_BUFF_SIZE);
++      memset(flag_str, 0, sizeof(flag_str));
++      if (flags & IP_CE)
++              strcat(flag_str, "CE ");
++      if (flags & IP_DF)
++              strcat(flag_str, "DF ");
++      if (flags & IP_MF)
++              strcat(flag_str, "MF ");
++      eol = strlen(flag_str) - 1;
++      if (eol > 0)
++              flag_str[eol] = 0;
++      snprintf(line, LINE_BUFF_SIZE, "%s: IP4:: Flags {%s}\n",
++              MIF_TAG, flag_str);
++      strcat(buff, line);
++
++      memset(line, 0, LINE_BUFF_SIZE);
++      snprintf(line, LINE_BUFF_SIZE,
++              "%s: IP4:: TTL %u, Protocol %u, Header Checksum 0x%04X\n",
++              MIF_TAG, iph->ttl, iph->protocol, ntohs(iph->check));
++      strcat(buff, line);
++
++      memset(line, 0, LINE_BUFF_SIZE);
++      snprintf(line, LINE_BUFF_SIZE,
++              "%s: IP4:: Src.IP %u.%u.%u.%u, Dst.IP %u.%u.%u.%u\n",
++              MIF_TAG, ip_pkt[12], ip_pkt[13], ip_pkt[14], ip_pkt[15],
++              ip_pkt[16], ip_pkt[17], ip_pkt[18], ip_pkt[19]);
++      strcat(buff, line);
++
++      switch (iph->protocol) {
++      case 6: /* TCP */
++              strcat_tcp_header(buff, pkt);
++              break;
++
++      case 17: /* UDP */
++              strcat_udp_header(buff, pkt);
++              break;
++
++      default:
++              break;
++      }
++
++      memset(line, 0, LINE_BUFF_SIZE);
++      snprintf(line, LINE_BUFF_SIZE, "%s\n", LINE_SEPARATOR);
++      strcat(buff, line);
++
++      pr_info("%s", buff);
++
++      kfree(buff);
++}
++
++bool is_dns_packet(const u8 *ip_pkt)
++{
++      struct iphdr *iph = (struct iphdr *)ip_pkt;
++      struct udphdr *udph = (struct udphdr *)(ip_pkt + (iph->ihl << 2));
++
++      /* If this packet is not a UDP packet, return here. */
++      if (iph->protocol != 17)
++              return false;
++
++      if (ntohs(udph->dest) == 53 || ntohs(udph->source) == 53)
++              return true;
++      else
++              return false;
++}
++
++bool is_syn_packet(const u8 *ip_pkt)
++{
++      struct iphdr *iph = (struct iphdr *)ip_pkt;
++      struct tcphdr *tcph = (struct tcphdr *)(ip_pkt + (iph->ihl << 2));
++
++      /* If this packet is not a TCP packet, return here. */
++      if (iph->protocol != 6)
++              return false;
++
++      if (tcph->syn || tcph->fin)
++              return true;
++      else
++              return false;
++}
++
++int memcmp16_to_io(const void __iomem *to, void *from, int size)
++{
++      u16 *d = (u16 *)to;
++      u16 *s = (u16 *)from;
++      int count = size >> 1;
++      int diff = 0;
++      int i;
++      u16 d1;
++      u16 s1;
++
++      for (i = 0; i < count; i++) {
++              d1 = ioread16(d);
++              s1 = *s;
++              if (d1 != s1) {
++                      diff++;
++                      mif_err("ERR! [%d] d:0x%04X != s:0x%04X\n", i, d1, s1);
++              }
++              d++;
++              s++;
++      }
++
++      return diff;
++}
++
++int mif_test_dpram(char *dp_name, u8 __iomem *start, u32 size)
++{
++      u8 __iomem *dst;
++      int i;
++      u16 val;
++
++      mif_info("%s: start = 0x%p, size = %d\n", dp_name, start, size);
++
++      dst = start;
++      for (i = 0; i < (size >> 1); i++) {
++              iowrite16((i & 0xFFFF), dst);
++              dst += 2;
++      }
++
++      dst = start;
++      for (i = 0; i < (size >> 1); i++) {
++              val = ioread16(dst);
++              if (val != (i & 0xFFFF)) {
++                      mif_info("%s: ERR! dst[%d] 0x%04X != 0x%04X\n",
++                              dp_name, i, val, (i & 0xFFFF));
++                      return -EINVAL;
++              }
++              dst += 2;
++      }
++
++      dst = start;
++      for (i = 0; i < (size >> 1); i++) {
++              iowrite16(0x00FF, dst);
++              dst += 2;
++      }
++
++      dst = start;
++      for (i = 0; i < (size >> 1); i++) {
++              val = ioread16(dst);
++              if (val != 0x00FF) {
++                      mif_info("%s: ERR! dst[%d] 0x%04X != 0x00FF\n",
++                              dp_name, i, val);
++                      return -EINVAL;
++              }
++              dst += 2;
++      }
++
++      dst = start;
++      for (i = 0; i < (size >> 1); i++) {
++              iowrite16(0x0FF0, dst);
++              dst += 2;
++      }
++
++      dst = start;
++      for (i = 0; i < (size >> 1); i++) {
++              val = ioread16(dst);
++              if (val != 0x0FF0) {
++                      mif_info("%s: ERR! dst[%d] 0x%04X != 0x0FF0\n",
++                              dp_name, i, val);
++                      return -EINVAL;
++              }
++              dst += 2;
++      }
++
++      dst = start;
++      for (i = 0; i < (size >> 1); i++) {
++              iowrite16(0xFF00, dst);
++              dst += 2;
++      }
++
++      dst = start;
++      for (i = 0; i < (size >> 1); i++) {
++              val = ioread16(dst);
++              if (val != 0xFF00) {
++                      mif_info("%s: ERR! dst[%d] 0x%04X != 0xFF00\n",
++                              dp_name, i, val);
++                      return -EINVAL;
++              }
++              dst += 2;
++      }
++
++      dst = start;
++      for (i = 0; i < (size >> 1); i++) {
++              iowrite16(0, dst);
++              dst += 2;
++      }
++
++      dst = start;
++      for (i = 0; i < (size >> 1); i++) {
++              val = ioread16(dst);
++              if (val != 0) {
++                      mif_info("%s: ERR! dst[%d] 0x%04X != 0\n",
++                              dp_name, i, val);
++                      return -EINVAL;
++              }
++              dst += 2;
++      }
++
++      mif_info("%s: PASS!!!\n", dp_name);
++      return 0;
++}
++
++struct file *mif_open_file(const char *path)
++{
++      struct file *fp;
++      mm_segment_t old_fs;
++
++      old_fs = get_fs();
++      set_fs(get_ds());
++
++      fp = filp_open(path, O_RDWR|O_CREAT|O_APPEND, 0666);
++
++      set_fs(old_fs);
++
++      if (IS_ERR(fp))
++              return NULL;
++
++      return fp;
++}
++
++void mif_save_file(struct file *fp, const char *buff, size_t size)
++{
++      int ret;
++      mm_segment_t old_fs;
++
++      old_fs = get_fs();
++      set_fs(get_ds());
++
++      ret = fp->f_op->write(fp, buff, size, &fp->f_pos);
++      if (ret < 0)
++              mif_err("ERR! write fail\n");
++
++      set_fs(old_fs);
++}
++
++void mif_close_file(struct file *fp)
++{
++      mm_segment_t old_fs;
++
++      old_fs = get_fs();
++      set_fs(get_ds());
++
++      filp_close(fp, NULL);
++
++      set_fs(old_fs);
++}
++
+diff --git a/drivers/misc/modem_if/modem_utils.h b/drivers/misc/modem_if/modem_utils.h
+new file mode 100644
+index 0000000..219e059
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_utils.h
+@@ -0,0 +1,315 @@
++/*
++ * Copyright (C) 2011 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#ifndef __MODEM_UTILS_H__
++#define __MODEM_UTILS_H__
++
++#include <linux/rbtree.h>
++
++#define IS_CONNECTED(iod, ld) ((iod)->link_types & LINKTYPE((ld)->link_type))
++
++#define MAX_MIF_BUFF_SIZE 0x80000 /* 512kb */
++#define MAX_MIF_SEPA_SIZE 32
++#define MIF_SEPARATOR "IPC_LOGGER(VER1.1)"
++#define MIF_SEPARATOR_DPRAM "DPRAM_LOGGER(VER1.1)"
++#define MAX_IPC_SKB_SIZE 4096
++#define MAX_LOG_SIZE 64
++
++#define MIF_TAG       "mif"
++
++#define MAX_LOG_CNT (MAX_MIF_BUFF_SIZE / MAX_LOG_SIZE)
++#define MIF_ID_SIZE sizeof(enum mif_log_id)
++
++#define MAX_IPC_LOG_SIZE \
++      (MAX_LOG_SIZE - sizeof(enum mif_log_id) \
++       - sizeof(unsigned long long) - sizeof(size_t))
++#define MAX_IRQ_LOG_SIZE \
++      (MAX_LOG_SIZE - sizeof(enum mif_log_id) \
++       - sizeof(unsigned long long) - sizeof(struct mif_irq_map))
++#define MAX_COM_LOG_SIZE \
++      (MAX_LOG_SIZE - sizeof(enum mif_log_id) \
++       - sizeof(unsigned long long))
++#define MAX_TIM_LOG_SIZE \
++      (MAX_LOG_SIZE - sizeof(enum mif_log_id) \
++       - sizeof(unsigned long long) - sizeof(struct timespec))
++
++enum mif_log_id {
++      MIF_IPC_RL2AP = 1,
++      MIF_IPC_AP2CP,
++      MIF_IPC_CP2AP,
++      MIF_IPC_AP2RL,
++      MIF_IRQ,
++      MIF_COM,
++      MIF_TIME
++};
++
++struct mif_irq_map {
++      u16 magic;
++      u16 access;
++
++      u16 fmt_tx_in;
++      u16 fmt_tx_out;
++      u16 fmt_rx_in;
++      u16 fmt_rx_out;
++
++      u16 raw_tx_in;
++      u16 raw_tx_out;
++      u16 raw_rx_in;
++      u16 raw_rx_out;
++
++      u16 cp2ap;
++};
++
++struct mif_ipc_block {
++      enum mif_log_id id;
++      unsigned long long time;
++      size_t len;
++      char buff[MAX_IPC_LOG_SIZE];
++};
++
++struct mif_irq_block {
++      enum mif_log_id id;
++      unsigned long long time;
++      struct mif_irq_map map;
++      char buff[MAX_IRQ_LOG_SIZE];
++};
++
++struct mif_common_block {
++      enum mif_log_id id;
++      unsigned long long time;
++      char buff[MAX_COM_LOG_SIZE];
++};
++
++struct mif_time_block {
++      enum mif_log_id id;
++      unsigned long long time;
++      struct timespec epoch;
++      char buff[MAX_TIM_LOG_SIZE];
++};
++
++struct utc_time {
++      u16 year;
++      u8 mon:4,
++         day:4;
++      u8 hour;
++      u8 min;
++      u8 sec;
++      u16 msec;
++} __packed;
++
++void ts2utc(struct timespec *ts, struct utc_time *utc);
++void get_utc_time(struct utc_time *utc);
++
++int mif_dump_dpram(struct io_device *);
++int mif_dump_log(struct modem_shared *, struct io_device *);
++
++#define mif_irq_log(msd, map, data, len) \
++      _mif_irq_log(MIF_IRQ, msd, map, data, len)
++#define mif_com_log(msd, format, ...) \
++      _mif_com_log(MIF_COM, msd, pr_fmt(format), ##__VA_ARGS__)
++#define mif_time_log(msd, epoch, data, len) \
++      _mif_time_log(MIF_TIME, msd, epoch, data, len)
++
++void mif_ipc_log(enum mif_log_id,
++      struct modem_shared *, const char *, size_t);
++void _mif_irq_log(enum mif_log_id,
++      struct modem_shared *, struct mif_irq_map, const char *, size_t);
++void _mif_com_log(enum mif_log_id,
++      struct modem_shared *, const char *, ...);
++void _mif_time_log(enum mif_log_id,
++      struct modem_shared *, struct timespec, const char *, size_t);
++
++/** find_linkdev - find a link device
++ * @msd:      struct modem_shared *
++ */
++static inline struct link_device *find_linkdev(struct modem_shared *msd,
++              enum modem_link link_type)
++{
++      struct link_device *ld;
++      list_for_each_entry(ld, &msd->link_dev_list, list) {
++              if (ld->link_type == link_type)
++                      return ld;
++      }
++      return NULL;
++}
++
++/** countbits - count number of 1 bits as fastest way
++ * @n: number
++ */
++static inline unsigned int countbits(unsigned int n)
++{
++      unsigned int i;
++      for (i = 0; n != 0; i++)
++              n &= (n - 1);
++      return i;
++}
++
++/* print IPC message as hex string with UTC time */
++void pr_ipc(const char *tag, const char *data, size_t len);
++
++/* print buffer as hex string */
++int pr_buffer(const char *tag, const char *data, size_t data_len,
++                                                      size_t max_len);
++
++/* print a sk_buff as hex string */
++#define pr_skb(tag, skb) \
++      pr_buffer(tag, (char *)((skb)->data), (size_t)((skb)->len), (size_t)16)
++
++/* print a urb as hex string */
++#define pr_urb(tag, urb) \
++      pr_buffer(tag, (char *)((urb)->transfer_buffer), \
++                      (size_t)((urb)->actual_length), (size_t)16)
++
++/* Stop/wake all TX queues in network interfaces */
++void mif_netif_stop(struct link_device *ld);
++void mif_netif_wake(struct link_device *ld);
++
++/* flow control CMD from CP, it use in serial devices */
++int link_rx_flowctl_cmd(struct link_device *ld, const char *data, size_t len);
++
++/* get iod from tree functions */
++
++struct io_device *get_iod_with_format(struct modem_shared *msd,
++                                      enum dev_format format);
++struct io_device *get_iod_with_channel(struct modem_shared *msd,
++                                      unsigned channel);
++
++static inline struct io_device *link_get_iod_with_format(
++                      struct link_device *ld, enum dev_format format)
++{
++      struct io_device *iod = get_iod_with_format(ld->msd, format);
++      return (iod && IS_CONNECTED(iod, ld)) ? iod : NULL;
++}
++
++static inline struct io_device *link_get_iod_with_channel(
++                      struct link_device *ld, unsigned channel)
++{
++      struct io_device *iod = get_iod_with_channel(ld->msd, channel);
++      return (iod && IS_CONNECTED(iod, ld)) ? iod : NULL;
++}
++
++/* insert iod to tree functions */
++struct io_device *insert_iod_with_format(struct modem_shared *msd,
++                      enum dev_format format, struct io_device *iod);
++struct io_device *insert_iod_with_channel(struct modem_shared *msd,
++                      unsigned channel, struct io_device *iod);
++
++/* iodev for each */
++typedef void (*action_fn)(struct io_device *iod, void *args);
++void iodevs_for_each(struct modem_shared *msd, action_fn action, void *args);
++
++/* netif wake/stop queue of iod */
++void iodev_netif_wake(struct io_device *iod, void *args);
++void iodev_netif_stop(struct io_device *iod, void *args);
++
++/* change tx_link of raw devices */
++void rawdevs_set_tx_link(struct modem_shared *msd, enum modem_link link_type);
++
++__be32 ipv4str_to_be32(const char *ipv4str, size_t count);
++
++void mif_add_timer(struct timer_list *timer, unsigned long expire,
++              void (*function)(unsigned long), unsigned long data);
++
++/* debug helper functions for sipc4, sipc5 */
++void mif_print_data(const char *buff, int len);
++void mif_dump2format16(const char *data, int len, char *buff, char *tag);
++void mif_dump2format4(const char *data, int len, char *buff, char *tag);
++void mif_print_dump(const char *data, int len, int width);
++void print_sipc4_hdlc_fmt_frame(const u8 *psrc);
++void print_sipc4_fmt_frame(const u8 *psrc);
++void print_sipc5_link_fmt_frame(const u8 *psrc);
++
++/*---------------------------------------------------------------------------
++
++                              IPv4 Header Format
++
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |Version|  IHL  |Type of Service|          Total Length         |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |         Identification        |C|D|M|     Fragment Offset     |
++      |                               |E|F|F|                         |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |  Time to Live |    Protocol   |         Header Checksum       |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |                       Source Address                          |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |                    Destination Address                        |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |                    Options                    |    Padding    |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++
++      IHL - Header Length
++      Flags - Consist of 3 bits
++              The 1st bit is "Congestion" bit.
++              The 2nd bit is "Dont Fragment" bit.
++              The 3rd bit is "More Fragments" bit.
++
++---------------------------------------------------------------------------*/
++#define IPV4_HDR_SIZE 20
++
++/*-------------------------------------------------------------------------
++
++                              TCP Header Format
++
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |          Source Port          |       Destination Port        |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |                        Sequence Number                        |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |                    Acknowledgment Number                      |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |  Data |       |C|E|U|A|P|R|S|F|                               |
++      | Offset| Rsvd  |W|C|R|C|S|S|Y|I|            Window             |
++      |       |       |R|E|G|K|H|T|N|N|                               |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |           Checksum            |         Urgent Pointer        |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |                    Options                    |    Padding    |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |                             data                              |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++
++-------------------------------------------------------------------------*/
++#define TCP_HDR_SIZE  20
++
++/*-------------------------------------------------------------------------
++
++                              UDP Header Format
++
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |          Source Port          |       Destination Port        |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |            Length             |           Checksum            |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++      |                             data                              |
++      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++
++-------------------------------------------------------------------------*/
++#define UDP_HDR_SIZE  8
++
++void print_ip4_packet(const u8 *ip_pkt, bool tx);
++bool is_dns_packet(const u8 *ip_pkt);
++bool is_syn_packet(const u8 *ip_pkt);
++
++int memcmp16_to_io(const void __iomem *to, void *from, int size);
++int mif_test_dpram(char *dp_name, u8 __iomem *start, u32 size);
++struct file *mif_open_file(const char *path);
++void mif_save_file(struct file *fp, const char *buff, size_t size);
++void mif_close_file(struct file *fp);
++
++#endif/*__MODEM_UTILS_H__*/
+diff --git a/drivers/misc/modem_if/modem_variation.h b/drivers/misc/modem_if/modem_variation.h
+new file mode 100644
+index 0000000..2865f7b
+--- /dev/null
++++ b/drivers/misc/modem_if/modem_variation.h
+@@ -0,0 +1,168 @@
++/*
++ * Copyright (C) 2010 Google, Inc.
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#ifndef __MODEM_VARIATION_H__
++#define __MODEM_VARIATION_H__
++
++#include <linux/platform_data/modem.h>
++
++#define DECLARE_MODEM_INIT(type)      \
++      int type ## _init_modemctl_device(struct modem_ctl *mc, \
++                              struct modem_data *pdata)
++#define DECLARE_MODEM_INIT_DUMMY(type)        \
++      static DECLARE_MODEM_INIT(type) { return 0; }
++
++#define DECLARE_LINK_INIT(type)       \
++              struct link_device *type ## _create_link_device(        \
++              struct platform_device *pdev)
++#define DECLARE_LINK_INIT_DUMMY(type) \
++      static DECLARE_LINK_INIT(type) { return NULL; }
++
++#define MODEM_INIT_CALL(type) type ## _init_modemctl_device
++#define LINK_INIT_CALL(type)  type ## _create_link_device
++
++/* add declaration of modem & link type */
++/* modem device support */
++DECLARE_MODEM_INIT_DUMMY(dummy)
++
++#ifdef CONFIG_UMTS_MODEM_XMM6260
++DECLARE_MODEM_INIT(xmm6260);
++#else
++DECLARE_MODEM_INIT_DUMMY(xmm6260)
++#endif
++
++#ifdef CONFIG_UMTS_MODEM_XMM6262
++DECLARE_MODEM_INIT(xmm6262);
++#else
++DECLARE_MODEM_INIT_DUMMY(xmm6262)
++#endif
++
++#ifdef CONFIG_CDMA_MODEM_CBP71
++DECLARE_MODEM_INIT(cbp71);
++#else
++DECLARE_MODEM_INIT_DUMMY(cbp71)
++#endif
++
++#ifdef CONFIG_CDMA_MODEM_CBP72
++DECLARE_MODEM_INIT(cbp72);
++#else
++DECLARE_MODEM_INIT_DUMMY(cbp72)
++#endif
++
++#ifdef CONFIG_LTE_MODEM_CMC221
++DECLARE_MODEM_INIT(cmc221);
++#else
++DECLARE_MODEM_INIT_DUMMY(cmc221)
++#endif
++
++#ifdef CONFIG_CDMA_MODEM_MDM6600
++DECLARE_MODEM_INIT(mdm6600);
++#else
++DECLARE_MODEM_INIT_DUMMY(mdm6600)
++#endif
++
++#ifdef CONFIG_GSM_MODEM_ESC6270
++DECLARE_MODEM_INIT(esc6270);
++#else
++DECLARE_MODEM_INIT_DUMMY(esc6270)
++#endif
++
++/* link device support */
++DECLARE_LINK_INIT_DUMMY(undefined)
++
++#ifdef CONFIG_LINK_DEVICE_MIPI
++DECLARE_LINK_INIT(mipi);
++#else
++DECLARE_LINK_INIT_DUMMY(mipi)
++#endif
++
++#ifdef CONFIG_LINK_DEVICE_DPRAM
++DECLARE_LINK_INIT(dpram);
++#else
++DECLARE_LINK_INIT_DUMMY(dpram)
++#endif
++
++#ifdef CONFIG_LINK_DEVICE_PLD
++DECLARE_LINK_INIT(pld);
++#else
++DECLARE_LINK_INIT_DUMMY(pld)
++#endif
++
++#ifdef CONFIG_LINK_DEVICE_SPI
++DECLARE_LINK_INIT(spi);
++#else
++DECLARE_LINK_INIT_DUMMY(spi)
++#endif
++
++#ifdef CONFIG_LINK_DEVICE_USB
++DECLARE_LINK_INIT(usb);
++#else
++DECLARE_LINK_INIT_DUMMY(usb)
++#endif
++
++#ifdef CONFIG_LINK_DEVICE_HSIC
++DECLARE_LINK_INIT(hsic);
++#else
++DECLARE_LINK_INIT_DUMMY(hsic)
++#endif
++
++#ifdef CONFIG_LINK_DEVICE_C2C
++DECLARE_LINK_INIT(c2c);
++#else
++DECLARE_LINK_INIT_DUMMY(c2c)
++#endif
++
++typedef int (*modem_init_call)(struct modem_ctl *, struct modem_data *);
++static modem_init_call modem_init_func[] = {
++      MODEM_INIT_CALL(xmm6260),
++      MODEM_INIT_CALL(xmm6262),
++      MODEM_INIT_CALL(cbp71),
++      MODEM_INIT_CALL(cbp72),
++      MODEM_INIT_CALL(cmc221),
++      MODEM_INIT_CALL(mdm6600),
++      MODEM_INIT_CALL(esc6270),
++      MODEM_INIT_CALL(dummy),
++};
++
++typedef struct link_device *(*link_init_call)(struct platform_device *);
++static link_init_call link_init_func[] = {
++      LINK_INIT_CALL(undefined),
++      LINK_INIT_CALL(mipi),
++      LINK_INIT_CALL(dpram),
++      LINK_INIT_CALL(spi),
++      LINK_INIT_CALL(usb),
++      LINK_INIT_CALL(hsic),
++      LINK_INIT_CALL(c2c),
++      LINK_INIT_CALL(pld),
++};
++
++static int call_modem_init_func(struct modem_ctl *mc, struct modem_data *pdata)
++{
++      if (modem_init_func[pdata->modem_type])
++              return modem_init_func[pdata->modem_type](mc, pdata);
++      else
++              return -ENOTSUPP;
++}
++
++static struct link_device *call_link_init_func(struct platform_device *pdev,
++                      enum modem_link link_type)
++{
++      if (link_init_func[link_type])
++              return link_init_func[link_type](pdev);
++      else
++              return NULL;
++}
++
++#endif
+diff --git a/drivers/misc/modem_if/sipc4_io_device.c b/drivers/misc/modem_if/sipc4_io_device.c
+new file mode 100644
+index 0000000..56b9afd
+--- /dev/null
++++ b/drivers/misc/modem_if/sipc4_io_device.c
+@@ -0,0 +1,1668 @@
++/* /linux/drivers/misc/modem_if/modem_io_device.c
++ *
++ * Copyright (C) 2010 Google, Inc.
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/fs.h>
++#include <linux/poll.h>
++#include <linux/irq.h>
++#include <linux/gpio.h>
++#include <linux/if_arp.h>
++#include <linux/ip.h>
++#include <linux/if_ether.h>
++#include <linux/etherdevice.h>
++#include <linux/device.h>
++#include <linux/module.h>
++
++#include <linux/platform_data/modem.h>
++#ifdef CONFIG_LINK_DEVICE_C2C
++#include <linux/platform_data/c2c.h>
++#endif
++#include "modem_prj.h"
++#include "modem_utils.h"
++
++/*
++ * MAX_RXDATA_SIZE is used at making skb, when it called with page size
++ * it need more bytes to allocate itself (Ex, cache byte, shared info,
++ * padding...)
++ * So, give restriction to allocation size below 1 page to prevent
++ * big pages broken.
++ */
++#define MAX_RXDATA_SIZE               0x0E00  /* 4 * 1024 - 512 */
++#define MAX_MULTI_FMT_SIZE    0x4000  /* 16 * 1024 */
++
++static const char hdlc_start[1] = { HDLC_START };
++static const char hdlc_end[1] = { HDLC_END };
++
++static int rx_iodev_skb(struct sk_buff *skb);
++
++static ssize_t show_waketime(struct device *dev,
++              struct device_attribute *attr, char *buf)
++{
++      unsigned int msec;
++      char *p = buf;
++      struct miscdevice *miscdev = dev_get_drvdata(dev);
++      struct io_device *iod = container_of(miscdev, struct io_device,
++                      miscdev);
++
++      msec = jiffies_to_msecs(iod->waketime);
++
++      p += sprintf(buf, "raw waketime : %ums\n", msec);
++
++      return p - buf;
++}
++
++static ssize_t store_waketime(struct device *dev,
++              struct device_attribute *attr, const char *buf, size_t count)
++{
++      unsigned long msec;
++      int ret;
++      struct miscdevice *miscdev = dev_get_drvdata(dev);
++      struct io_device *iod = container_of(miscdev, struct io_device,
++                      miscdev);
++
++      ret = strict_strtoul(buf, 10, &msec);
++      if (ret)
++              return count;
++
++      iod->waketime = msecs_to_jiffies(msec);
++
++      return count;
++}
++
++static struct device_attribute attr_waketime =
++      __ATTR(waketime, S_IRUGO | S_IWUSR, show_waketime, store_waketime);
++
++static ssize_t show_loopback(struct device *dev,
++              struct device_attribute *attr, char *buf)
++{
++      struct miscdevice *miscdev = dev_get_drvdata(dev);
++      struct modem_shared *msd =
++              container_of(miscdev, struct io_device, miscdev)->msd;
++      unsigned char *ip = (unsigned char *)&msd->loopback_ipaddr;
++      char *p = buf;
++
++      p += sprintf(buf, "%u.%u.%u.%u\n", ip[0], ip[1], ip[2], ip[3]);
++
++      return p - buf;
++}
++
++static ssize_t store_loopback(struct device *dev,
++              struct device_attribute *attr, const char *buf, size_t count)
++{
++      struct miscdevice *miscdev = dev_get_drvdata(dev);
++      struct modem_shared *msd =
++              container_of(miscdev, struct io_device, miscdev)->msd;
++
++      msd->loopback_ipaddr = ipv4str_to_be32(buf, count);
++
++      return count;
++}
++
++static struct device_attribute attr_loopback =
++      __ATTR(loopback, S_IRUGO | S_IWUSR, show_loopback, store_loopback);
++
++static int get_header_size(struct io_device *iod)
++{
++      switch (iod->format) {
++      case IPC_FMT:
++              return sizeof(struct fmt_hdr);
++
++      case IPC_RAW:
++      case IPC_MULTI_RAW:
++              return sizeof(struct raw_hdr);
++
++      case IPC_RFS:
++              return sizeof(struct rfs_hdr);
++
++      case IPC_BOOT:
++              /* minimum size for transaction align */
++              return 4;
++
++      case IPC_RAMDUMP:
++      default:
++              return 0;
++      }
++}
++
++static int get_hdlc_size(struct io_device *iod, char *buf)
++{
++      struct fmt_hdr *fmt_header;
++      struct raw_hdr *raw_header;
++      struct rfs_hdr *rfs_header;
++
++      mif_debug("buf : %02x %02x %02x (%d)\n", *buf, *(buf + 1),
++                              *(buf + 2), __LINE__);
++
++      switch (iod->format) {
++      case IPC_FMT:
++              fmt_header = (struct fmt_hdr *)buf;
++              if (iod->mc->mdm_data->ipc_version == SIPC_VER_42)
++                      return fmt_header->len & 0x3FFF;
++              else
++                      return fmt_header->len;
++      case IPC_RAW:
++      case IPC_MULTI_RAW:
++              raw_header = (struct raw_hdr *)buf;
++              return raw_header->len;
++      case IPC_RFS:
++              rfs_header = (struct rfs_hdr *)buf;
++              return rfs_header->len;
++      default:
++              break;
++      }
++      return 0;
++}
++
++static void *get_header(struct io_device *iod, size_t count,
++                      char *frame_header_buf)
++{
++      struct fmt_hdr *fmt_h;
++      struct raw_hdr *raw_h;
++      struct rfs_hdr *rfs_h;
++
++      switch (iod->format) {
++      case IPC_FMT:
++              fmt_h = (struct fmt_hdr *)frame_header_buf;
++
++              fmt_h->len = count + sizeof(struct fmt_hdr);
++              fmt_h->control = 0;
++
++              return (void *)frame_header_buf;
++
++      case IPC_RAW:
++      case IPC_MULTI_RAW:
++              raw_h = (struct raw_hdr *)frame_header_buf;
++
++              raw_h->len = count + sizeof(struct raw_hdr);
++              raw_h->channel = iod->id & 0x1F;
++              raw_h->control = 0;
++
++              return (void *)frame_header_buf;
++
++      case IPC_RFS:
++              rfs_h = (struct rfs_hdr *)frame_header_buf;
++
++              rfs_h->len = count + sizeof(struct raw_hdr);
++              rfs_h->id = iod->id;
++
++              return (void *)frame_header_buf;
++
++      default:
++              return 0;
++      }
++}
++
++static inline int calc_padding_size(struct io_device *iod,
++      struct link_device *ld, unsigned len)
++{
++      if (ld->aligned)
++              return (4 - (len & 0x3)) & 0x3;
++      else
++              return 0;
++}
++
++static inline int rx_hdlc_head_start_check(char *buf)
++{
++      /* check hdlc head and return size of start byte */
++      return (buf[0] == HDLC_START) ? SIZE_OF_HDLC_START : -EBADMSG;
++}
++
++static inline int rx_hdlc_tail_check(char *buf)
++{
++      /* check hdlc tail and return size of tail byte */
++      return (buf[0] == HDLC_END) ? SIZE_OF_HDLC_END : -EBADMSG;
++}
++
++/* remove hdlc header and store IPC header */
++static int rx_hdlc_head_check(struct io_device *iod, struct link_device *ld,
++                                              char *buf, unsigned rest)
++{
++      struct header_data *hdr = &fragdata(iod, ld)->h_data;
++      int head_size = get_header_size(iod);
++      int done_len = 0;
++      int len = 0;
++
++      /* first frame, remove start header 7F */
++      if (!hdr->start) {
++              len = rx_hdlc_head_start_check(buf);
++              if (len < 0) {
++                      mif_err("Wrong HDLC start: 0x%x\n", *buf);
++                      return len; /*Wrong hdlc start*/
++              }
++
++              mif_debug("check len : %d, rest : %d (%d)\n", len,
++                                      rest, __LINE__);
++
++              /* set the start flag of current packet */
++              hdr->start = HDLC_START;
++              hdr->len = 0;
++
++              /* debug print */
++              switch (iod->format) {
++              case IPC_FMT:
++              case IPC_RAW:
++              case IPC_MULTI_RAW:
++              case IPC_RFS:
++                      /* TODO: print buf...  */
++                      break;
++
++              case IPC_CMD:
++              case IPC_BOOT:
++              case IPC_RAMDUMP:
++              default:
++                      break;
++              }
++
++              buf += len;
++              done_len += len;
++              rest -= len; /* rest, call by value */
++      }
++
++      mif_debug("check len : %d, rest : %d (%d)\n",
++                      len, rest, __LINE__);
++
++      /* store the HDLC header to iod priv */
++      if (hdr->len < head_size) {
++              len = min(rest, head_size - hdr->len);
++              memcpy(hdr->hdr + hdr->len, buf, len);
++              hdr->len += len;
++              done_len += len;
++      }
++
++      mif_debug("check done_len : %d, rest : %d (%d)\n", done_len,
++                              rest, __LINE__);
++      return done_len;
++}
++
++/* alloc skb and copy data to skb */
++static int rx_hdlc_data_check(struct io_device *iod, struct link_device *ld,
++                                              char *buf, unsigned rest)
++{
++      struct header_data *hdr = &fragdata(iod, ld)->h_data;
++      struct sk_buff *skb = fragdata(iod, ld)->skb_recv;
++      int head_size = get_header_size(iod);
++      int data_size = get_hdlc_size(iod, hdr->hdr) - head_size;
++      int alloc_size;
++      int len = 0;
++      int done_len = 0;
++      int rest_len = data_size - hdr->frag_len;
++      int continue_len = fragdata(iod, ld)->realloc_offset;
++
++      mif_debug("head_size : %d, data_size : %d (%d)\n", head_size,
++                              data_size, __LINE__);
++
++      if (continue_len) {
++              /* check the HDLC header*/
++              if (rx_hdlc_head_start_check(buf) == SIZE_OF_HDLC_START) {
++                      rest_len -= (head_size + SIZE_OF_HDLC_START);
++                      continue_len += (head_size + SIZE_OF_HDLC_START);
++              }
++
++              buf += continue_len;
++              rest -= continue_len;
++              done_len += continue_len;
++              fragdata(iod, ld)->realloc_offset = 0;
++
++              mif_debug("realloc_offset = %d\n", continue_len);
++      }
++
++      /* first payload data - alloc skb */
++      if (!skb) {
++              /* make skb data size under MAX_RXDATA_SIZE */
++              alloc_size = min(data_size, MAX_RXDATA_SIZE);
++              alloc_size = min(alloc_size, rest_len);
++
++              /* exceptional case for RFS channel
++               * make skb for header info first
++               */
++              if (iod->format == IPC_RFS && !hdr->frag_len) {
++                      skb = rx_alloc_skb(head_size, iod, ld);
++                      if (unlikely(!skb))
++                              return -ENOMEM;
++                      memcpy(skb_put(skb, head_size), hdr->hdr, head_size);
++                      rx_iodev_skb(skb);
++              }
++
++              /* allocate first packet for data, when its size exceed
++               * MAX_RXDATA_SIZE, this packet will split to
++               * multiple packets
++               */
++              skb = rx_alloc_skb(alloc_size, iod, ld);
++              if (unlikely(!skb)) {
++                      fragdata(iod, ld)->realloc_offset = continue_len;
++                      return -ENOMEM;
++              }
++              fragdata(iod, ld)->skb_recv = skb;
++      }
++
++      while (rest) {
++              /* copy length cannot exceed rest_len */
++              len = min_t(int, rest_len, rest);
++              /* copy length should be under skb tailroom size */
++              len = min(len, skb_tailroom(skb));
++              /* when skb tailroom is bigger than MAX_RXDATA_SIZE
++               * restrict its size to MAX_RXDATA_SIZE just for convinience */
++              len = min(len, MAX_RXDATA_SIZE);
++
++              /* copy bytes to skb */
++              memcpy(skb_put(skb, len), buf, len);
++
++              /* adjusting variables */
++              buf += len;
++              rest -= len;
++              done_len += len;
++              rest_len -= len;
++              hdr->frag_len += len;
++
++              /* check if it is final for this packet sequence */
++              if (!rest_len || !rest)
++                      break;
++
++              /* more bytes are remain for this packet sequence
++               * pass fully loaded skb to rx queue
++               * and allocate another skb for continues data recv chain
++               */
++              rx_iodev_skb(skb);
++              fragdata(iod, ld)->skb_recv =  NULL;
++
++              alloc_size = min(rest_len, MAX_RXDATA_SIZE);
++
++              skb = rx_alloc_skb(alloc_size, iod, ld);
++              if (unlikely(!skb)) {
++                      fragdata(iod, ld)->realloc_offset = done_len;
++                      return -ENOMEM;
++              }
++              fragdata(iod, ld)->skb_recv = skb;
++      }
++
++      mif_debug("rest : %d, alloc_size : %d , len : %d (%d)\n",
++                              rest, alloc_size, skb->len, __LINE__);
++
++      return done_len;
++}
++
++static int rx_multi_fmt_frame(struct sk_buff *rx_skb)
++{
++      struct io_device *iod = skbpriv(rx_skb)->iod;
++      struct link_device *ld = skbpriv(rx_skb)->ld;
++      struct fmt_hdr *fh =
++              (struct fmt_hdr *)fragdata(iod, ld)->h_data.hdr;
++      unsigned int id = fh->control & 0x7F;
++      struct sk_buff *skb = iod->skb[id];
++      unsigned char *data = fragdata(iod, ld)->skb_recv->data;
++      unsigned int rcvd = fragdata(iod, ld)->skb_recv->len;
++
++      if (!skb) {
++              /* If there has been no multiple frame with this ID */
++              if (!(fh->control & 0x80)) {
++                      /* It is a single frame because the "more" bit is 0. */
++#if 0
++                      mif_err("\n<%s> Rx FMT frame (len %d)\n",
++                              iod->name, rcvd);
++                      print_sipc4_fmt_frame(data);
++                      mif_err("\n");
++#endif
++                      skb_queue_tail(&iod->sk_rx_q,
++                                      fragdata(iod, ld)->skb_recv);
++                      mif_debug("wake up wq of %s\n", iod->name);
++                      wake_up(&iod->wq);
++                      return 0;
++              } else {
++                      struct fmt_hdr *fh = NULL;
++                      skb = rx_alloc_skb(MAX_MULTI_FMT_SIZE, iod, ld);
++                      if (!skb) {
++                              mif_err("<%d> alloc_skb fail\n",
++                                      __LINE__);
++                              return -ENOMEM;
++                      }
++                      iod->skb[id] = skb;
++
++                      fh = (struct fmt_hdr *)data;
++                      mif_info("Start multi-frame (ID %d, len %d)",
++                              id, fh->len);
++              }
++      }
++
++      /* Start multi-frame processing */
++
++      memcpy(skb_put(skb, rcvd), data, rcvd);
++      dev_kfree_skb_any(fragdata(iod, ld)->skb_recv);
++
++      if (fh->control & 0x80) {
++              /* The last frame has not arrived yet. */
++              mif_info("Receiving (ID %d, %d bytes)\n",
++                      id, skb->len);
++      } else {
++              /* It is the last frame because the "more" bit is 0. */
++              mif_info("The Last (ID %d, %d bytes received)\n",
++                      id, skb->len);
++#if 0
++              mif_err("\n<%s> Rx FMT frame (len %d)\n",
++                      iod->name, skb->len);
++              print_sipc4_fmt_frame(skb->data);
++              mif_err("\n");
++#endif
++              skb_queue_tail(&iod->sk_rx_q, skb);
++              iod->skb[id] = NULL;
++              mif_info("wake up wq of %s\n", iod->name);
++              wake_up(&iod->wq);
++      }
++
++      return 0;
++}
++
++static int rx_multi_fmt_frame_sipc42(struct sk_buff *rx_skb)
++{
++      struct io_device *iod = skbpriv(rx_skb)->iod;
++      struct link_device *ld = skbpriv(rx_skb)->ld;
++      struct fmt_hdr *fh =
++              (struct fmt_hdr *)fragdata(iod, ld)->h_data.hdr;
++      unsigned int    id = fh->control & 0x7F;
++      struct sk_buff *skb = iod->skb[id];
++      unsigned char  *data = fragdata(iod, ld)->skb_recv->data;
++      unsigned int    rcvd = fragdata(iod, ld)->skb_recv->len;
++
++      u8 ch;
++      struct io_device *real_iod = NULL;
++
++      ch = (fh->len & 0xC000) >> 14;
++      fh->len = fh->len & 0x3FFF;
++      real_iod = ld->fmt_iods[ch];
++      if (!real_iod) {
++              mif_err("wrong channel %d\n", ch);
++              return -1;
++      }
++      skbpriv(rx_skb)->real_iod = real_iod;
++
++      if (!skb) {
++              /* If there has been no multiple frame with this ID */
++              if (!(fh->control & 0x80)) {
++                      /* It is a single frame because the "more" bit is 0. */
++#if 0
++                      mif_err("\n<%s> Rx FMT frame (len %d)\n",
++                              iod->name, rcvd);
++                      print_sipc4_fmt_frame(data);
++                      mif_err("\n");
++#endif
++                      skb_queue_tail(&real_iod->sk_rx_q,
++                                      fragdata(iod, ld)->skb_recv);
++                      mif_debug("wake up wq of %s\n", iod->name);
++                      wake_up(&real_iod->wq);
++                      return 0;
++              } else {
++                      struct fmt_hdr *fh = NULL;
++                      skb = rx_alloc_skb(MAX_MULTI_FMT_SIZE, real_iod, ld);
++                      if (!skb) {
++                              mif_err("alloc_skb fail\n");
++                              return -ENOMEM;
++                      }
++                      real_iod->skb[id] = skb;
++
++                      fh = (struct fmt_hdr *)data;
++                      mif_err("Start multi-frame (ID %d, len %d)",
++                              id, fh->len);
++              }
++      }
++
++      /* Start multi-frame processing */
++
++      memcpy(skb_put(skb, rcvd), data, rcvd);
++      dev_kfree_skb_any(fragdata(real_iod, ld)->skb_recv);
++
++      if (fh->control & 0x80) {
++              /* The last frame has not arrived yet. */
++              mif_err("Receiving (ID %d, %d bytes)\n",
++                      id, skb->len);
++      } else {
++              /* It is the last frame because the "more" bit is 0. */
++              mif_err("The Last (ID %d, %d bytes received)\n",
++                      id, skb->len);
++#if 0
++              mif_err("\n<%s> Rx FMT frame (len %d)\n",
++                      iod->name, skb->len);
++              print_sipc4_fmt_frame(skb->data);
++              mif_err("\n");
++#endif
++              skb_queue_tail(&real_iod->sk_rx_q, skb);
++              real_iod->skb[id] = NULL;
++              mif_info("wake up wq of %s\n", real_iod->name);
++              wake_up(&real_iod->wq);
++      }
++
++      return 0;
++}
++
++static int rx_iodev_skb_raw(struct sk_buff *skb)
++{
++      int err = 0;
++      struct io_device *iod = skbpriv(skb)->real_iod;
++      struct net_device *ndev = NULL;
++      struct iphdr *ip_header = NULL;
++      struct ethhdr *ehdr = NULL;
++      const char source[ETH_ALEN] = SOURCE_MAC_ADDR;
++
++      /* check the real_iod is open? */
++      /*
++      if (atomic_read(&iod->opened) == 0) {
++              mif_err("<%s> is not opened.\n",
++                      iod->name);
++              pr_skb("drop packet", skb);
++              return -ENOENT;
++      }
++      */
++
++      switch (iod->io_typ) {
++      case IODEV_MISC:
++              mif_debug("<%s> sk_rx_q.qlen = %d\n",
++                      iod->name, iod->sk_rx_q.qlen);
++              skb_queue_tail(&iod->sk_rx_q, skb);
++              wake_up(&iod->wq);
++              return 0;
++
++      case IODEV_NET:
++              ndev = iod->ndev;
++              if (!ndev) {
++                      mif_err("<%s> ndev == NULL",
++                              iod->name);
++                      return -EINVAL;
++              }
++
++              skb->dev = ndev;
++              ndev->stats.rx_packets++;
++              ndev->stats.rx_bytes += skb->len;
++
++              /* check the version of IP */
++              ip_header = (struct iphdr *)skb->data;
++              if (ip_header->version == IP6VERSION)
++                      skb->protocol = htons(ETH_P_IPV6);
++              else
++                      skb->protocol = htons(ETH_P_IP);
++
++              if (iod->use_handover) {
++                      skb_push(skb, sizeof(struct ethhdr));
++                      ehdr = (void *)skb->data;
++                      memcpy(ehdr->h_dest, ndev->dev_addr, ETH_ALEN);
++                      memcpy(ehdr->h_source, source, ETH_ALEN);
++                      ehdr->h_proto = skb->protocol;
++                      skb->ip_summed = CHECKSUM_UNNECESSARY;
++                      skb_reset_mac_header(skb);
++
++                      skb_pull(skb, sizeof(struct ethhdr));
++              }
++
++              if (in_irq())
++                      err = netif_rx(skb);
++              else
++                      err = netif_rx_ni(skb);
++
++              if (err != NET_RX_SUCCESS)
++                      dev_err(&ndev->dev, "rx error: %d\n", err);
++
++              return err;
++
++      default:
++              mif_err("wrong io_type : %d\n", iod->io_typ);
++              return -EINVAL;
++      }
++}
++
++static void rx_iodev_work(struct work_struct *work)
++{
++      int ret = 0;
++      struct sk_buff *skb = NULL;
++      struct io_device *iod = container_of(work, struct io_device,
++                              rx_work.work);
++
++      while ((skb = skb_dequeue(&iod->sk_rx_q)) != NULL) {
++              ret = rx_iodev_skb_raw(skb);
++              if (ret < 0) {
++                      mif_err("<%s> rx_iodev_skb_raw err = %d",
++                              iod->name, ret);
++                      dev_kfree_skb_any(skb);
++              } else if (ret == NET_RX_DROP) {
++                      mif_err("<%s> ret == NET_RX_DROP\n",
++                              iod->name);
++                      schedule_delayed_work(&iod->rx_work,
++                                              msecs_to_jiffies(100));
++                      break;
++              }
++      }
++}
++
++static int rx_multipdp(struct sk_buff *skb)
++{
++      u8 ch;
++      struct io_device *iod = skbpriv(skb)->iod;
++      struct link_device *ld = skbpriv(skb)->ld;
++      struct raw_hdr *raw_header =
++              (struct raw_hdr *)fragdata(iod, ld)->h_data.hdr;
++      struct io_device *real_iod = NULL;
++
++      ch = raw_header->channel;
++      if (ch == DATA_LOOPBACK_CHANNEL && ld->msd->loopback_ipaddr)
++              ch = RMNET0_CH_ID;
++
++      real_iod = link_get_iod_with_channel(ld, 0x20 | ch);
++      if (!real_iod) {
++              mif_err("wrong channel %d\n", ch);
++              return -1;
++      }
++
++      skbpriv(skb)->real_iod = real_iod;
++      skb_queue_tail(&iod->sk_rx_q, skb);
++      mif_debug("sk_rx_qlen:%d\n", iod->sk_rx_q.qlen);
++
++      schedule_delayed_work(&iod->rx_work, 0);
++      return 0;
++}
++
++/* de-mux function draft */
++static int rx_iodev_skb(struct sk_buff *skb)
++{
++      struct io_device *iod = skbpriv(skb)->iod;
++
++      switch (iod->format) {
++      case IPC_MULTI_RAW:
++              return rx_multipdp(skb);
++
++      case IPC_FMT:
++              if (iod->mc->mdm_data->ipc_version == SIPC_VER_42)
++                      return rx_multi_fmt_frame_sipc42(skb);
++              else
++                      return rx_multi_fmt_frame(skb);
++
++      case IPC_RFS:
++      default:
++              skb_queue_tail(&iod->sk_rx_q, skb);
++              mif_debug("wake up wq of %s\n", iod->name);
++              wake_up(&iod->wq);
++              return 0;
++      }
++}
++
++static int rx_hdlc_packet(struct io_device *iod, struct link_device *ld,
++              const char *data, unsigned recv_size)
++{
++      int rest = (int)recv_size;
++      char *buf = (char *)data;
++      int err = 0;
++      int len = 0;
++      unsigned rcvd = 0;
++
++      if (rest <= 0)
++              goto exit;
++
++      mif_debug("RX_SIZE = %d, ld: %s\n", rest, ld->name);
++
++      if (fragdata(iod, ld)->h_data.frag_len) {
++              /*
++                If the fragdata(iod, ld)->h_data.frag_len field is
++                not zero, there is a HDLC frame that is waiting for more data
++                or HDLC_END in the skb (fragdata(iod, ld)->skb_recv).
++                In this case, rx_hdlc_head_check() must be skipped.
++              */
++              goto data_check;
++      }
++
++next_frame:
++      err = len = rx_hdlc_head_check(iod, ld, buf, rest);
++      if (err < 0)
++              goto exit;
++      mif_debug("check len : %d, rest : %d (%d)\n", len, rest,
++                              __LINE__);
++
++      buf += len;
++      rest -= len;
++      if (rest <= 0)
++              goto exit;
++
++data_check:
++      /*
++        If the return value of rx_hdlc_data_check() is zero, there remains
++        only HDLC_END that will be received.
++      */
++      err = len = rx_hdlc_data_check(iod, ld, buf, rest);
++      if (err < 0)
++              goto exit;
++      mif_debug("check len : %d, rest : %d (%d)\n", len, rest,
++                              __LINE__);
++
++      buf += len;
++      rest -= len;
++
++      if (!rest && fragdata(iod, ld)->h_data.frag_len) {
++              /*
++                Data is being received and more data or HDLC_END does not
++                arrive yet, but there is no more data in the buffer. More
++                data may come within the next frame from the link device.
++              */
++              return 0;
++      } else if (rest <= 0)
++              goto exit;
++
++      /* At this point, one HDLC frame except HDLC_END has been received. */
++
++      err = len = rx_hdlc_tail_check(buf);
++      if (err < 0) {
++              mif_err("Wrong HDLC end: 0x%02X\n", *buf);
++              goto exit;
++      }
++      mif_debug("check len : %d, rest : %d (%d)\n", len, rest,
++                              __LINE__);
++      buf += len;
++      rest -= len;
++
++      /* At this point, one complete HDLC frame has been received. */
++
++      /*
++        The padding size is applied for the next HDLC frame. Zero will be
++        returned by calc_padding_size() if the link device does not require
++        4-byte aligned access.
++      */
++      rcvd = get_hdlc_size(iod, fragdata(iod, ld)->h_data.hdr) +
++             (SIZE_OF_HDLC_START + SIZE_OF_HDLC_END);
++      len = calc_padding_size(iod, ld, rcvd);
++      buf += len;
++      rest -= len;
++      if (rest < 0)
++              goto exit;
++
++      err = rx_iodev_skb(fragdata(iod, ld)->skb_recv);
++      if (err < 0)
++              goto exit;
++
++      /* initialize header & skb */
++      fragdata(iod, ld)->skb_recv = NULL;
++      memset(&fragdata(iod, ld)->h_data, 0x00,
++                      sizeof(struct header_data));
++      fragdata(iod, ld)->realloc_offset = 0;
++
++      if (rest)
++              goto next_frame;
++
++exit:
++      /* free buffers. mipi-hsi re-use recv buf */
++
++      if (rest < 0)
++              err = -ERANGE;
++
++      if (err == -ENOMEM) {
++              if (!(fragdata(iod, ld)->h_data.frag_len))
++                      memset(&fragdata(iod, ld)->h_data, 0x00,
++                              sizeof(struct header_data));
++              return err;
++      }
++
++      if (err < 0 && fragdata(iod, ld)->skb_recv) {
++              dev_kfree_skb_any(fragdata(iod, ld)->skb_recv);
++              fragdata(iod, ld)->skb_recv = NULL;
++
++              /* clear headers */
++              memset(&fragdata(iod, ld)->h_data, 0x00,
++                              sizeof(struct header_data));
++              fragdata(iod, ld)->realloc_offset = 0;
++      }
++
++      return err;
++}
++
++static int rx_rfs_packet(struct io_device *iod, struct link_device *ld,
++                                      const char *data, unsigned size)
++{
++      int err = 0;
++      int pad = 0;
++      int rcvd = 0;
++      struct sk_buff *skb;
++
++      if (data[0] != HDLC_START) {
++              mif_err("Dropping RFS packet ... "
++                     "size = %d, start = %02X %02X %02X %02X\n",
++                      size,
++                      data[0], data[1], data[2], data[3]);
++              return -EINVAL;
++      }
++
++      if (data[size-1] != HDLC_END) {
++              for (pad = 1; pad < 4; pad++)
++                      if (data[(size-1)-pad] == HDLC_END)
++                              break;
++
++              if (pad >= 4) {
++                      char *b = (char *)data;
++                      unsigned sz = size;
++                      mif_err("size %d, No END_FLAG!!!\n", size);
++                      mif_err("end = %02X %02X %02X %02X\n",
++                              b[sz-4], b[sz-3], b[sz-2], b[sz-1]);
++                      return -EINVAL;
++              } else {
++                      mif_info("padding = %d\n", pad);
++              }
++      }
++
++      skb = rx_alloc_skb(size, iod, ld);
++      if (unlikely(!skb)) {
++              mif_err("alloc_skb fail\n");
++              return -ENOMEM;
++      }
++
++      /* copy the RFS haeder to skb->data */
++      rcvd = size - sizeof(hdlc_start) - sizeof(hdlc_end) - pad;
++      memcpy(skb_put(skb, rcvd), ((char *)data + sizeof(hdlc_start)), rcvd);
++
++      fragdata(iod, ld)->skb_recv = skb;
++      err = rx_iodev_skb(fragdata(iod, ld)->skb_recv);
++
++      return err;
++}
++
++/* called from link device when a packet arrives for this io device */
++static int io_dev_recv_data_from_link_dev(struct io_device *iod,
++              struct link_device *ld, const char *data, unsigned int len)
++{
++      struct sk_buff *skb;
++      int err;
++      unsigned int alloc_size, rest_len;
++      char *cur;
++
++
++      /* check the iod(except IODEV_DUMMY) is open?
++       * if the iod is MULTIPDP, check this data on rx_iodev_skb_raw()
++       * because, we cannot know the channel no in here.
++       */
++      /*
++      if (iod->io_typ != IODEV_DUMMY && atomic_read(&iod->opened) == 0) {
++              mif_err("<%s> is not opened.\n", iod->name);
++              pr_buffer("drop packet", data, len, 16u);
++              return -ENOENT;
++      }
++      */
++
++      switch (iod->format) {
++      case IPC_RFS:
++#ifdef CONFIG_IPC_CMC22x_OLD_RFS
++              err = rx_rfs_packet(iod, ld, data, len);
++              return err;
++#endif
++
++      case IPC_FMT:
++      case IPC_RAW:
++      case IPC_MULTI_RAW:
++              if (iod->waketime)
++#ifdef CONFIG_HAS_WAKELOCK
++                      wake_lock_timeout(&iod->wakelock, iod->waketime);
++#else
++                      pm_wakeup_event(iod->miscdev.this_device,
++                              jiffies_to_msecs(iod->waketime));
++#endif
++              err = rx_hdlc_packet(iod, ld, data, len);
++              if (err < 0)
++                      mif_err("fail process HDLC frame\n");
++              return err;
++
++      case IPC_CMD:
++              /* TODO- handle flow control command from CP */
++              return 0;
++
++      case IPC_BOOT:
++      case IPC_RAMDUMP:
++              /* save packet to sk_buff */
++              skb = rx_alloc_skb(len, iod, ld);
++              if (skb) {
++                      mif_debug("boot len : %d\n", len);
++
++                      memcpy(skb_put(skb, len), data, len);
++                      skb_queue_tail(&iod->sk_rx_q, skb);
++                      mif_debug("skb len : %d\n", skb->len);
++
++                      wake_up(&iod->wq);
++                      return len;
++              }
++              /* 32KB page alloc fail case, alloc 3.5K a page.. */
++              mif_info("(%d)page fail, alloc fragment pages\n", len);
++
++              rest_len = len;
++              cur = (char *)data;
++              while (rest_len) {
++                      alloc_size = min_t(unsigned int, MAX_RXDATA_SIZE,
++                              rest_len);
++                      skb = rx_alloc_skb(alloc_size, iod, ld);
++                      if (!skb) {
++                              mif_err("fail alloc skb (%d)\n", __LINE__);
++                              return -ENOMEM;
++                      }
++                      mif_debug("boot len : %d\n", alloc_size);
++
++                      memcpy(skb_put(skb, alloc_size), cur, alloc_size);
++                      skb_queue_tail(&iod->sk_rx_q, skb);
++                      mif_debug("skb len : %d\n", skb->len);
++
++                      rest_len -= alloc_size;
++                      cur += alloc_size;
++              }
++              wake_up(&iod->wq);
++              return len;
++
++      default:
++              return -EINVAL;
++      }
++}
++
++/* inform the IO device that the modem is now online or offline or
++ * crashing or whatever...
++ */
++static void io_dev_modem_state_changed(struct io_device *iod,
++                      enum modem_state state)
++{
++      iod->mc->phone_state = state;
++      mif_err("modem state changed. (iod: %s, state: %d)\n",
++              iod->name, state);
++
++      if ((state == STATE_CRASH_RESET) || (state == STATE_CRASH_EXIT)
++              || (state == STATE_NV_REBUILDING))
++              wake_up(&iod->wq);
++}
++
++/**
++ * io_dev_sim_state_changed
++ * @iod:      IPC's io_device
++ * @sim_online: SIM is online?
++ */
++static void io_dev_sim_state_changed(struct io_device *iod, bool sim_online)
++{
++      if (atomic_read(&iod->opened) == 0) {
++              mif_err("iod is not opened: %s\n",
++                              iod->name);
++      } else if (iod->mc->sim_state.online == sim_online) {
++              mif_err("sim state not changed.\n");
++      } else {
++              iod->mc->sim_state.online = sim_online;
++              iod->mc->sim_state.changed = true;
++#ifdef CONFIG_HAS_WAKELOCK
++              wake_lock_timeout(&iod->mc->bootd->wakelock,
++                                              iod->mc->bootd->waketime);
++#else
++              pm_wakeup_event(iod->mc->bootd->miscdev.this_device,
++                      jiffies_to_msecs(iod->mc->bootd->waketime));
++#endif
++              mif_err("sim state changed. (iod: %s, state: "
++                              "[online=%d, changed=%d])\n",
++                              iod->name, iod->mc->sim_state.online,
++                              iod->mc->sim_state.changed);
++              wake_up(&iod->wq);
++      }
++}
++
++static int misc_open(struct inode *inode, struct file *filp)
++{
++      struct io_device *iod = to_io_device(filp->private_data);
++      struct modem_shared *msd = iod->msd;
++      struct link_device *ld;
++      int ret;
++      filp->private_data = (void *)iod;
++
++      mif_err("iod = %s\n", iod->name);
++      atomic_inc(&iod->opened);
++
++      list_for_each_entry(ld, &msd->link_dev_list, list) {
++              if (IS_CONNECTED(iod, ld) && ld->init_comm) {
++                      ret = ld->init_comm(ld, iod);
++                      if (ret < 0) {
++                              mif_err("%s: init_comm error: %d\n",
++                                              ld->name, ret);
++                              return ret;
++                      }
++              }
++      }
++
++      return 0;
++}
++
++static int misc_release(struct inode *inode, struct file *filp)
++{
++      struct io_device *iod = (struct io_device *)filp->private_data;
++      struct modem_shared *msd = iod->msd;
++      struct link_device *ld;
++
++      mif_err("iod = %s\n", iod->name);
++      atomic_dec(&iod->opened);
++      skb_queue_purge(&iod->sk_rx_q);
++
++      list_for_each_entry(ld, &msd->link_dev_list, list) {
++              if (IS_CONNECTED(iod, ld) && ld->terminate_comm)
++                      ld->terminate_comm(ld, iod);
++      }
++
++      return 0;
++}
++
++static unsigned int misc_poll(struct file *filp, struct poll_table_struct *wait)
++{
++      struct io_device *iod = (struct io_device *)filp->private_data;
++
++      poll_wait(filp, &iod->wq, wait);
++
++      if ((!skb_queue_empty(&iod->sk_rx_q)) &&
++          (iod->mc->phone_state != STATE_OFFLINE)) {
++              return POLLIN | POLLRDNORM;
++      } else if ((iod->mc->phone_state == STATE_CRASH_RESET) ||
++                      (iod->mc->phone_state == STATE_CRASH_EXIT) ||
++                      (iod->mc->phone_state == STATE_NV_REBUILDING) ||
++                      (iod->mc->sim_state.changed)) {
++              if (iod->format == IPC_RAW) {
++                      msleep(20);
++                      return 0;
++              }
++              return POLLHUP;
++      } else {
++              return 0;
++      }
++}
++
++static long misc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
++{
++      int p_state;
++      struct io_device *iod = (struct io_device *)filp->private_data;
++      struct link_device *ld = get_current_link(iod);
++      char cpinfo_buf[530] = "CP Crash ";
++      unsigned long size;
++      int ret;
++      char str[TASK_COMM_LEN];
++
++      mif_debug("cmd = 0x%x\n", cmd);
++
++      switch (cmd) {
++      case IOCTL_MODEM_ON:
++              mif_debug("misc_ioctl : IOCTL_MODEM_ON\n");
++              return iod->mc->ops.modem_on(iod->mc);
++
++      case IOCTL_MODEM_OFF:
++              mif_debug("misc_ioctl : IOCTL_MODEM_OFF\n");
++              return iod->mc->ops.modem_off(iod->mc);
++
++      case IOCTL_MODEM_RESET:
++              mif_debug("misc_ioctl : IOCTL_MODEM_RESET\n");
++              return iod->mc->ops.modem_reset(iod->mc);
++
++      case IOCTL_MODEM_BOOT_ON:
++              mif_debug("misc_ioctl : IOCTL_MODEM_BOOT_ON\n");
++              return iod->mc->ops.modem_boot_on(iod->mc);
++
++      case IOCTL_MODEM_BOOT_OFF:
++              mif_debug("misc_ioctl : IOCTL_MODEM_BOOT_OFF\n");
++              return iod->mc->ops.modem_boot_off(iod->mc);
++
++      /* TODO - will remove this command after ril updated */
++      case IOCTL_MODEM_BOOT_DONE:
++              mif_debug("misc_ioctl : IOCTL_MODEM_BOOT_DONE\n");
++              return 0;
++
++      case IOCTL_MODEM_STATUS:
++              mif_debug("misc_ioctl : IOCTL_MODEM_STATUS\n");
++
++              p_state = iod->mc->phone_state;
++              if ((p_state == STATE_CRASH_RESET) ||
++                  (p_state == STATE_CRASH_EXIT)) {
++                      mif_err("<%s> send err state : %d\n",
++                              iod->name, p_state);
++              } else if (iod->mc->sim_state.changed &&
++                      !strcmp(get_task_comm(str, get_current()), "rild")) {
++                      int s_state = iod->mc->sim_state.online ?
++                                      STATE_SIM_ATTACH : STATE_SIM_DETACH;
++                      iod->mc->sim_state.changed = false;
++
++                      mif_info("SIM states (%d) to %s\n", s_state, str);
++                      return s_state;
++              } else if (p_state == STATE_NV_REBUILDING) {
++                      mif_info("send nv rebuild state : %d\n",
++                              p_state);
++                      iod->mc->phone_state = STATE_ONLINE;
++              }
++              return p_state;
++
++      case IOCTL_MODEM_PROTOCOL_SUSPEND:
++              mif_info("misc_ioctl : IOCTL_MODEM_PROTOCOL_SUSPEND\n");
++
++              if (iod->format != IPC_MULTI_RAW)
++                      return -EINVAL;
++
++              iodevs_for_each(iod->msd, iodev_netif_stop, 0);
++              return 0;
++
++      case IOCTL_MODEM_PROTOCOL_RESUME:
++              mif_info("misc_ioctl : IOCTL_MODEM_PROTOCOL_RESUME\n");
++
++              if (iod->format != IPC_MULTI_RAW)
++                      return -EINVAL;
++
++              iodevs_for_each(iod->msd, iodev_netif_wake, 0);
++              return 0;
++
++      case IOCTL_MODEM_DUMP_START:
++              mif_err("misc_ioctl : IOCTL_MODEM_DUMP_START\n");
++              return ld->dump_start(ld, iod);
++
++      case IOCTL_MODEM_DUMP_UPDATE:
++              mif_debug("misc_ioctl : IOCTL_MODEM_DUMP_UPDATE\n");
++              return ld->dump_update(ld, iod, arg);
++
++      case IOCTL_MODEM_FORCE_CRASH_EXIT:
++              mif_debug("misc_ioctl : IOCTL_MODEM_FORCE_CRASH_EXIT\n");
++              if (iod->mc->ops.modem_force_crash_exit)
++                      return iod->mc->ops.modem_force_crash_exit(iod->mc);
++              return -EINVAL;
++
++      case IOCTL_MODEM_CP_UPLOAD:
++              mif_err("misc_ioctl : IOCTL_MODEM_CP_UPLOAD\n");
++              if (copy_from_user(cpinfo_buf + strlen(cpinfo_buf),
++                      (void __user *)arg, MAX_CPINFO_SIZE) != 0)
++                      panic("CP Crash");
++              else
++                      panic(cpinfo_buf);
++              return 0;
++
++      case IOCTL_MODEM_DUMP_RESET:
++              mif_err("misc_ioctl : IOCTL_MODEM_DUMP_RESET\n");
++              return iod->mc->ops.modem_dump_reset(iod->mc);
++
++      case IOCTL_MIF_LOG_DUMP:
++              size = MAX_MIF_BUFF_SIZE;
++              ret = copy_to_user((void __user *)arg, &size,
++                      sizeof(unsigned long));
++              if (ret < 0)
++                      return -EFAULT;
++
++              mif_dump_log(iod->mc->msd, iod);
++              return 0;
++
++      case IOCTL_MIF_DPRAM_DUMP:
++#ifdef CONFIG_LINK_DEVICE_DPRAM
++              if (iod->mc->mdm_data->link_types & LINKTYPE(LINKDEV_DPRAM)) {
++                      size = iod->mc->mdm_data->dpram_ctl->dp_size;
++                      ret = copy_to_user((void __user *)arg, &size,
++                              sizeof(unsigned long));
++                      if (ret < 0)
++                              return -EFAULT;
++                      mif_dump_dpram(iod);
++                      return 0;
++              }
++#endif
++              return -EINVAL;
++
++      default:
++               /* If you need to handle the ioctl for specific link device,
++                * then assign the link ioctl handler to ld->ioctl
++                * It will be call for specific link ioctl */
++              if (ld->ioctl)
++                      return ld->ioctl(ld, iod, cmd, arg);
++
++              mif_err("misc_ioctl : ioctl 0x%X is not defined.\n", cmd);
++              return -EINVAL;
++      }
++      return 0;
++}
++
++static ssize_t misc_write(struct file *filp, const char __user *buf,
++                      size_t count, loff_t *ppos)
++{
++      struct io_device *iod = (struct io_device *)filp->private_data;
++      struct link_device *ld = get_current_link(iod);
++      int frame_len = 0;
++      char frame_header_buf[sizeof(struct raw_hdr)];
++      struct sk_buff *skb;
++      int err;
++      size_t tx_size;
++
++      /* TODO - check here flow control for only raw data */
++
++      frame_len = SIZE_OF_HDLC_START +
++                  get_header_size(iod) +
++                  count +
++                  SIZE_OF_HDLC_END;
++      if (ld->aligned)
++              frame_len += MAX_LINK_PADDING_SIZE;
++
++      skb = alloc_skb(frame_len, GFP_KERNEL);
++      if (!skb) {
++              mif_err("fail alloc skb (%d)\n", __LINE__);
++              return -ENOMEM;
++      }
++
++      switch (iod->format) {
++      case IPC_BOOT:
++      case IPC_RAMDUMP:
++              if (copy_from_user(skb_put(skb, count), buf, count) != 0) {
++                      dev_kfree_skb_any(skb);
++                      return -EFAULT;
++              }
++              break;
++
++      case IPC_RFS:
++              memcpy(skb_put(skb, SIZE_OF_HDLC_START), hdlc_start,
++                              SIZE_OF_HDLC_START);
++              if (copy_from_user(skb_put(skb, count), buf, count) != 0) {
++                      dev_kfree_skb_any(skb);
++                      return -EFAULT;
++              }
++              memcpy(skb_put(skb, SIZE_OF_HDLC_END), hdlc_end,
++                                      SIZE_OF_HDLC_END);
++              break;
++
++      default:
++              memcpy(skb_put(skb, SIZE_OF_HDLC_START), hdlc_start,
++                              SIZE_OF_HDLC_START);
++              memcpy(skb_put(skb, get_header_size(iod)),
++                      get_header(iod, count, frame_header_buf),
++                      get_header_size(iod));
++              if (copy_from_user(skb_put(skb, count), buf, count) != 0) {
++                      dev_kfree_skb_any(skb);
++                      return -EFAULT;
++              }
++              memcpy(skb_put(skb, SIZE_OF_HDLC_END), hdlc_end,
++                                      SIZE_OF_HDLC_END);
++              break;
++      }
++
++      skb_put(skb, calc_padding_size(iod, ld, skb->len));
++
++#if 0
++      if (iod->format == IPC_FMT) {
++              mif_err("\n<%s> Tx HDLC FMT frame (len %d)\n",
++                      iod->name, skb->len);
++              print_sipc4_hdlc_fmt_frame(skb->data);
++              mif_err("\n");
++      }
++#endif
++#if 0
++      if (iod->format == IPC_RAW) {
++              mif_err("\n<%s> Tx HDLC RAW frame (len %d)\n",
++                      iod->name, skb->len);
++              mif_print_data(skb->data, (skb->len < 64 ? skb->len : 64));
++              mif_err("\n");
++      }
++#endif
++#if 0
++      if (iod->format == IPC_RFS) {
++              mif_err("\n<%s> Tx HDLC RFS frame (len %d)\n",
++                      iod->name, skb->len);
++              mif_print_data(skb->data, (skb->len < 64 ? skb->len : 64));
++              mif_err("\n");
++      }
++#endif
++
++      /* send data with sk_buff, link device will put sk_buff
++       * into the specific sk_buff_q and run work-q to send data
++       */
++      tx_size = skb->len;
++
++      skbpriv(skb)->iod = iod;
++      skbpriv(skb)->ld = ld;
++
++      err = ld->send(ld, iod, skb);
++      if (err < 0) {
++              dev_kfree_skb_any(skb);
++              return err;
++      }
++
++      if (err != tx_size)
++              mif_err("WARNNING: wrong tx size: %s, format=%d "
++                      "count=%d, tx_size=%d, return_size=%d",
++                      iod->name, iod->format, count, tx_size, err);
++
++      /* Temporaly enable t he RFS log for debugging IPC RX pedding issue */
++      if (iod->format == IPC_RFS)
++              mif_info("write rfs size = %d\n", count);
++
++      return count;
++}
++
++static ssize_t misc_read(struct file *filp, char *buf, size_t count,
++                      loff_t *f_pos)
++{
++      struct io_device *iod = (struct io_device *)filp->private_data;
++      struct sk_buff *skb = NULL;
++      int pktsize = 0;
++      unsigned int rest_len, copy_len;
++      char *cur = buf;
++
++      skb = skb_dequeue(&iod->sk_rx_q);
++      if (!skb) {
++              mif_err("<%s> no data from sk_rx_q\n", iod->name);
++              return 0;
++      }
++      mif_debug("<%s> skb->len : %d\n", iod->name, skb->len);
++
++      if (iod->format == IPC_BOOT) {
++              pktsize = rest_len = count;
++              while (rest_len) {
++                      if (skb->len > rest_len) {
++                              /* BOOT device receviced rx data as serial
++                                stream, return data by User requested size */
++                              mif_err("skb->len %d > count %d\n", skb->len,
++                                      rest_len);
++                              pr_skb("BOOT-wRX", skb);
++                              if (copy_to_user(cur, skb->data, rest_len)
++                                                                      != 0) {
++                                      dev_kfree_skb_any(skb);
++                                      return -EFAULT;
++                              }
++                              cur += rest_len;
++                              skb_pull(skb, rest_len);
++                              if (skb->len) {
++                                      mif_info("queue-head, skb->len = %d\n",
++                                              skb->len);
++                                      skb_queue_head(&iod->sk_rx_q, skb);
++                              }
++                              mif_debug("return %u\n", rest_len);
++                              return rest_len;
++                      }
++
++                      copy_len = min(rest_len, skb->len);
++                      if (copy_to_user(cur, skb->data, copy_len) != 0) {
++                              dev_kfree_skb_any(skb);
++                              return -EFAULT;
++                      }
++                      cur += skb->len;
++                      dev_kfree_skb_any(skb);
++                      rest_len -= copy_len;
++
++                      if (!rest_len)
++                              break;
++
++                      skb = skb_dequeue(&iod->sk_rx_q);
++                      if (!skb) {
++                              mif_err("<%s> %d / %d sk_rx_q\n", iod->name,
++                                      (count - rest_len), count);
++                              return count - rest_len;
++                      }
++              }
++      } else {
++              if (skb->len > count) {
++                      mif_err("<%s> skb->len %d > count %d\n", iod->name,
++                              skb->len, count);
++                      dev_kfree_skb_any(skb);
++                      return -EFAULT;
++              }
++              pktsize = skb->len;
++              if (copy_to_user(buf, skb->data, pktsize) != 0) {
++                      dev_kfree_skb_any(skb);
++                      return -EFAULT;
++              }
++              if (iod->format == IPC_FMT)
++                      mif_debug("copied %d bytes to user\n", pktsize);
++
++              dev_kfree_skb_any(skb);
++      }
++      return pktsize;
++}
++
++#ifdef CONFIG_LINK_DEVICE_C2C
++static int misc_mmap(struct file *filp, struct vm_area_struct *vma)
++{
++      int r = 0;
++      unsigned long size = 0;
++      unsigned long pfn = 0;
++      unsigned long offset = 0;
++      struct io_device *iod = (struct io_device *)filp->private_data;
++
++      if (!vma)
++              return -EFAULT;
++
++      size = vma->vm_end - vma->vm_start;
++      offset = vma->vm_pgoff << PAGE_SHIFT;
++      if (offset + size > (C2C_CP_RGN_SIZE + C2C_SH_RGN_SIZE)) {
++              mif_err("offset + size > C2C_CP_RGN_SIZE\n");
++              return -EINVAL;
++      }
++
++      /* Set the noncacheable property to the region */
++      vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
++      vma->vm_flags |= VM_RESERVED | VM_IO;
++
++      pfn = __phys_to_pfn(C2C_CP_RGN_ADDR + offset);
++      r = remap_pfn_range(vma, vma->vm_start, pfn, size, vma->vm_page_prot);
++      if (r) {
++              mif_err("Failed in remap_pfn_range()!!!\n");
++              return -EAGAIN;
++      }
++
++      mif_err("VA = 0x%08lx, offset = 0x%lx, size = %lu\n",
++              vma->vm_start, offset, size);
++
++      return 0;
++}
++#endif
++
++static const struct file_operations misc_io_fops = {
++      .owner = THIS_MODULE,
++      .open = misc_open,
++      .release = misc_release,
++      .poll = misc_poll,
++      .unlocked_ioctl = misc_ioctl,
++      .write = misc_write,
++      .read = misc_read,
++#ifdef CONFIG_LINK_DEVICE_C2C
++      .mmap = misc_mmap,
++#endif
++};
++
++static int vnet_open(struct net_device *ndev)
++{
++      struct vnet *vnet = netdev_priv(ndev);
++      netif_start_queue(ndev);
++      atomic_inc(&vnet->iod->opened);
++      return 0;
++}
++
++static int vnet_stop(struct net_device *ndev)
++{
++      struct vnet *vnet = netdev_priv(ndev);
++      atomic_dec(&vnet->iod->opened);
++      netif_stop_queue(ndev);
++      return 0;
++}
++
++static int vnet_xmit(struct sk_buff *skb, struct net_device *ndev)
++{
++      int ret = 0;
++      int headroom = 0;
++      int tailroom = 0;
++      struct sk_buff *skb_new = NULL;
++      struct vnet *vnet = netdev_priv(ndev);
++      struct io_device *iod = vnet->iod;
++      struct link_device *ld = get_current_link(iod);
++      struct raw_hdr hd;
++      struct iphdr *ip_header = NULL;
++
++      /* When use `handover' with Network Bridge,
++       * user -> TCP/IP(kernel) -> bridge device -> TCP/IP(kernel) -> this.
++       *
++       * We remove the one ethernet header of skb before using skb->len,
++       * because the skb has two ethernet headers.
++       */
++      if (iod->use_handover) {
++              if (iod->id >= PSD_DATA_CHID_BEGIN &&
++                      iod->id <= PSD_DATA_CHID_END)
++                      skb_pull(skb, sizeof(struct ethhdr));
++      }
++
++      /* ip loop-back */
++      ip_header = (struct iphdr *)skb->data;
++      if (iod->msd->loopback_ipaddr &&
++              ip_header->daddr == iod->msd->loopback_ipaddr) {
++              swap(ip_header->saddr, ip_header->daddr);
++              hd.channel = DATA_LOOPBACK_CHANNEL;
++      } else {
++              hd.channel = iod->id & 0x1F;
++      }
++      hd.len = skb->len + sizeof(hd);
++      hd.control = 0;
++
++      headroom = sizeof(hd) + sizeof(hdlc_start);
++      tailroom = sizeof(hdlc_end);
++      if (ld->aligned)
++              tailroom += MAX_LINK_PADDING_SIZE;
++      if (skb_headroom(skb) < headroom || skb_tailroom(skb) < tailroom) {
++              skb_new = skb_copy_expand(skb, headroom, tailroom, GFP_ATOMIC);
++              /* skb_copy_expand success or not, free old skb from caller */
++              dev_kfree_skb_any(skb);
++              if (!skb_new)
++                      return -ENOMEM;
++      } else
++              skb_new = skb;
++
++      memcpy(skb_push(skb_new, sizeof(hd)), &hd, sizeof(hd));
++      memcpy(skb_push(skb_new, sizeof(hdlc_start)), hdlc_start,
++                              sizeof(hdlc_start));
++      memcpy(skb_put(skb_new, sizeof(hdlc_end)), hdlc_end, sizeof(hdlc_end));
++      skb_put(skb_new, calc_padding_size(iod, ld,  skb_new->len));
++
++      skbpriv(skb_new)->iod = iod;
++      skbpriv(skb_new)->ld = ld;
++
++      ret = ld->send(ld, iod, skb_new);
++      if (ret < 0) {
++              netif_stop_queue(ndev);
++              dev_kfree_skb_any(skb_new);
++              return NETDEV_TX_BUSY;
++      }
++
++      ndev->stats.tx_packets++;
++      ndev->stats.tx_bytes += skb->len;
++
++      return NETDEV_TX_OK;
++}
++
++static struct net_device_ops vnet_ops = {
++      .ndo_open = vnet_open,
++      .ndo_stop = vnet_stop,
++      .ndo_start_xmit = vnet_xmit,
++};
++
++static void vnet_setup(struct net_device *ndev)
++{
++      ndev->netdev_ops = &vnet_ops;
++      ndev->type = ARPHRD_PPP;
++      ndev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
++      ndev->addr_len = 0;
++      ndev->hard_header_len = 0;
++      ndev->tx_queue_len = 1000;
++      ndev->mtu = ETH_DATA_LEN;
++      ndev->watchdog_timeo = 5 * HZ;
++}
++
++static void vnet_setup_ether(struct net_device *ndev)
++{
++      ndev->netdev_ops = &vnet_ops;
++      ndev->type = ARPHRD_ETHER;
++      ndev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST | IFF_SLAVE;
++      ndev->addr_len = ETH_ALEN;
++      random_ether_addr(ndev->dev_addr);
++      ndev->hard_header_len = 0;
++      ndev->tx_queue_len = 1000;
++      ndev->mtu = ETH_DATA_LEN;
++      ndev->watchdog_timeo = 5 * HZ;
++}
++
++int sipc4_init_io_device(struct io_device *iod)
++{
++      int ret = 0;
++      struct vnet *vnet;
++
++      /* Get modem state from modem control device */
++      iod->modem_state_changed = io_dev_modem_state_changed;
++
++      iod->sim_state_changed = io_dev_sim_state_changed;
++
++      /* Get data from link device */
++      iod->recv = io_dev_recv_data_from_link_dev;
++
++      /* Register misc or net device */
++      switch (iod->io_typ) {
++      case IODEV_MISC:
++              init_waitqueue_head(&iod->wq);
++              skb_queue_head_init(&iod->sk_rx_q);
++              INIT_DELAYED_WORK(&iod->rx_work, rx_iodev_work);
++
++              iod->miscdev.minor = MISC_DYNAMIC_MINOR;
++              iod->miscdev.name = iod->name;
++              iod->miscdev.fops = &misc_io_fops;
++
++              ret = misc_register(&iod->miscdev);
++              if (ret)
++                      mif_err("failed to register misc io device : %s\n",
++                                              iod->name);
++
++              break;
++
++      case IODEV_NET:
++              skb_queue_head_init(&iod->sk_rx_q);
++              if (iod->use_handover)
++                      iod->ndev = alloc_netdev(0, iod->name,
++                                              vnet_setup_ether);
++              else
++                      iod->ndev = alloc_netdev(0, iod->name, vnet_setup);
++
++              if (!iod->ndev) {
++                      mif_err("failed to alloc netdev\n");
++                      return -ENOMEM;
++              }
++
++              ret = register_netdev(iod->ndev);
++              if (ret)
++                      free_netdev(iod->ndev);
++
++              mif_debug("(iod:0x%p)\n", iod);
++              vnet = netdev_priv(iod->ndev);
++              mif_debug("(vnet:0x%p)\n", vnet);
++              vnet->iod = iod;
++
++              break;
++
++      case IODEV_DUMMY:
++              skb_queue_head_init(&iod->sk_rx_q);
++              INIT_DELAYED_WORK(&iod->rx_work, rx_iodev_work);
++
++              iod->miscdev.minor = MISC_DYNAMIC_MINOR;
++              iod->miscdev.name = iod->name;
++              iod->miscdev.fops = &misc_io_fops;
++
++              ret = misc_register(&iod->miscdev);
++              if (ret)
++                      mif_err("failed to register misc io device : %s\n",
++                                              iod->name);
++              ret = device_create_file(iod->miscdev.this_device,
++                              &attr_waketime);
++              if (ret)
++                      mif_err("failed to create `waketime' file : %s\n",
++                                      iod->name);
++              ret = device_create_file(iod->miscdev.this_device,
++                              &attr_loopback);
++              if (ret)
++                      mif_err("failed to create `loopback file' : %s\n",
++                                      iod->name);
++              break;
++
++      default:
++              mif_err("wrong io_type : %d\n", iod->io_typ);
++              return -EINVAL;
++      }
++
++      mif_debug("%s(%d) : init_io_device() done : %d\n",
++                              iod->name, iod->io_typ, ret);
++      return ret;
++}
++
+diff --git a/drivers/misc/modem_if/sipc4_modem.c b/drivers/misc/modem_if/sipc4_modem.c
+new file mode 100644
+index 0000000..58b3faf
+--- /dev/null
++++ b/drivers/misc/modem_if/sipc4_modem.c
+@@ -0,0 +1,371 @@
++/* linux/drivers/modem/modem.c
++ *
++ * Copyright (C) 2010 Google, Inc.
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/interrupt.h>
++#include <linux/platform_device.h>
++#include <linux/miscdevice.h>
++
++#include <linux/uaccess.h>
++#include <linux/fs.h>
++#include <linux/io.h>
++#include <linux/wait.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/mutex.h>
++#include <linux/irq.h>
++#include <linux/gpio.h>
++#include <linux/delay.h>
++#ifdef CONFIG_HAS_WAKELOCK
++#include <linux/wakelock.h>
++#endif
++
++#include <linux/platform_data/modem.h>
++#include "modem_prj.h"
++#include "modem_variation.h"
++#include "modem_utils.h"
++
++#define FMT_WAKE_TIME   (HZ/2)
++#define RFS_WAKE_TIME   (HZ*3)
++#define RAW_WAKE_TIME   (HZ*6)
++
++static struct modem_shared *create_modem_shared_data(void)
++{
++      struct modem_shared *msd;
++
++      msd = kzalloc(sizeof(struct modem_shared), GFP_KERNEL);
++      if (!msd)
++              return NULL;
++
++      /* initialize link device list */
++      INIT_LIST_HEAD(&msd->link_dev_list);
++
++      /* initialize tree of io devices */
++      msd->iodevs_tree_chan = RB_ROOT;
++      msd->iodevs_tree_fmt = RB_ROOT;
++
++      msd->storage.cnt = 0;
++      msd->storage.addr =
++              kzalloc(MAX_MIF_BUFF_SIZE + MAX_MIF_SEPA_SIZE, GFP_KERNEL);
++      if (!msd->storage.addr) {
++              mif_err("IPC logger buff alloc failed!!\n");
++              return NULL;
++      }
++      memset(msd->storage.addr, 0, MAX_MIF_BUFF_SIZE);
++      memcpy(msd->storage.addr, MIF_SEPARATOR, MAX_MIF_SEPA_SIZE);
++      msd->storage.addr += MAX_MIF_SEPA_SIZE;
++      spin_lock_init(&msd->lock);
++
++      return msd;
++}
++
++static struct modem_ctl *create_modemctl_device(struct platform_device *pdev,
++              struct modem_shared *msd)
++{
++      int ret = 0;
++      struct modem_data *pdata;
++      struct modem_ctl *modemctl;
++      struct device *dev = &pdev->dev;
++
++      /* create modem control device */
++      modemctl = kzalloc(sizeof(struct modem_ctl), GFP_KERNEL);
++      if (!modemctl)
++              return NULL;
++
++      modemctl->msd = msd;
++      modemctl->dev = dev;
++      modemctl->phone_state = STATE_OFFLINE;
++
++      pdata = pdev->dev.platform_data;
++      modemctl->mdm_data = pdata;
++      modemctl->name = pdata->name;
++
++      /* init modemctl device for getting modemctl operations */
++      ret = call_modem_init_func(modemctl, pdata);
++      if (ret) {
++              kfree(modemctl);
++              return NULL;
++      }
++
++      mif_info("%s is created!!!\n", pdata->name);
++
++      return modemctl;
++}
++
++static struct io_device *create_io_device(struct modem_io_t *io_t,
++              struct modem_shared *msd, struct modem_ctl *modemctl,
++              struct modem_data *pdata)
++{
++      int ret = 0;
++      struct io_device *iod = NULL;
++
++      iod = kzalloc(sizeof(struct io_device), GFP_KERNEL);
++      if (!iod) {
++              mif_err("iod == NULL\n");
++              return NULL;
++      }
++
++      rb_init_node(&iod->node_chan);
++      rb_init_node(&iod->node_fmt);
++
++      iod->name = io_t->name;
++      iod->id = io_t->id;
++      iod->format = io_t->format;
++      iod->io_typ = io_t->io_type;
++      iod->link_types = io_t->links;
++      iod->net_typ = pdata->modem_net;
++      iod->use_handover = pdata->use_handover;
++      iod->ipc_version = pdata->ipc_version;
++      atomic_set(&iod->opened, 0);
++
++      /* link between io device and modem control */
++      iod->mc = modemctl;
++      if (iod->format == IPC_FMT)
++              modemctl->iod = iod;
++      if (iod->format == IPC_BOOT) {
++              modemctl->bootd = iod;
++              mif_info("Bood device = %s\n", iod->name);
++      }
++
++      /* link between io device and modem shared */
++      iod->msd = msd;
++
++      /* add iod to rb_tree */
++      if (iod->format != IPC_RAW)
++              insert_iod_with_format(msd, iod->format, iod);
++
++      if (sipc4_is_not_reserved_channel(iod->id))
++              insert_iod_with_channel(msd, iod->id, iod);
++
++      /* register misc device or net device */
++      ret = sipc4_init_io_device(iod);
++      if (ret) {
++              kfree(iod);
++              mif_err("sipc4_init_io_device fail (%d)\n", ret);
++              return NULL;
++      }
++
++      mif_debug("%s is created!!!\n", iod->name);
++      return iod;
++}
++
++static int attach_devices(struct io_device *iod, enum modem_link tx_link)
++{
++      struct modem_shared *msd = iod->msd;
++      struct link_device *ld;
++
++      /* find link type for this io device */
++      list_for_each_entry(ld, &msd->link_dev_list, list) {
++              if (IS_CONNECTED(iod, ld)) {
++                      /* The count 1 bits of iod->link_types is count
++                       * of link devices of this iod.
++                       * If use one link device,
++                       * or, 2+ link devices and this link is tx_link,
++                       * set iod's link device with ld
++                       */
++                      if ((countbits(iod->link_types) <= 1) ||
++                                      (tx_link == ld->link_type)) {
++                              mif_debug("set %s->%s\n", iod->name, ld->name);
++
++                              set_current_link(iod, ld);
++
++                              if (iod->ipc_version == SIPC_VER_42) {
++                                      if (iod->format == IPC_FMT) {
++                                              int ch = iod->id & 0x03;
++                                              ld->fmt_iods[ch] = iod;
++                                      }
++                              }
++                      }
++              }
++      }
++
++      /* if use rx dynamic switch, set tx_link at modem_io_t of
++       * board-*-modems.c
++       */
++      if (!get_current_link(iod)) {
++              mif_err("%s->link == NULL\n", iod->name);
++              BUG();
++      }
++
++      switch (iod->format) {
++      case IPC_FMT:
++#ifdef CONFIG_HAS_WAKELOCK
++              wake_lock_init(&iod->wakelock, WAKE_LOCK_SUSPEND, iod->name);
++#else
++              device_init_wakeup(iod->miscdev.this_device, true);
++#endif
++              iod->waketime = FMT_WAKE_TIME;
++              break;
++
++      case IPC_RFS:
++#ifdef CONFIG_HAS_WAKELOCK
++              wake_lock_init(&iod->wakelock, WAKE_LOCK_SUSPEND, iod->name);
++#else
++              device_init_wakeup(iod->miscdev.this_device, true);
++#endif
++              iod->waketime = RFS_WAKE_TIME;
++              break;
++
++      case IPC_MULTI_RAW:
++#ifdef CONFIG_HAS_WAKELOCK
++              wake_lock_init(&iod->wakelock, WAKE_LOCK_SUSPEND, iod->name);
++#else
++              device_init_wakeup(iod->miscdev.this_device, true);
++#endif
++              iod->waketime = RAW_WAKE_TIME;
++              break;
++      case IPC_BOOT:
++#ifdef CONFIG_HAS_WAKELOCK
++              wake_lock_init(&iod->wakelock, WAKE_LOCK_SUSPEND, iod->name);
++#else
++              device_init_wakeup(iod->miscdev.this_device, true);
++#endif
++              iod->waketime = 3 * HZ;
++      default:
++              break;
++      }
++
++      return 0;
++}
++
++static int __devinit modem_probe(struct platform_device *pdev)
++{
++      int i;
++      struct modem_data *pdata = pdev->dev.platform_data;
++      struct modem_shared *msd = NULL;
++      struct modem_ctl *modemctl = NULL;
++      struct io_device *iod[pdata->num_iodevs];
++      struct link_device *ld;
++
++      mif_err("%s\n", pdev->name);
++      memset(iod, 0, sizeof(iod));
++
++      msd = create_modem_shared_data();
++      if (!msd) {
++              mif_err("msd == NULL\n");
++              goto err_free_modemctl;
++      }
++
++      modemctl = create_modemctl_device(pdev, msd);
++      if (!modemctl) {
++              mif_err("modemctl == NULL\n");
++              goto err_free_modemctl;
++      }
++
++      /* create link device */
++      /* support multi-link device */
++      for (i = 0; i < LINKDEV_MAX ; i++) {
++              /* find matching link type */
++              if (pdata->link_types & LINKTYPE(i)) {
++                      ld = call_link_init_func(pdev, i);
++                      if (!ld)
++                              goto err_free_modemctl;
++
++                      mif_err("link created: %s\n", ld->name);
++                      ld->link_type = i;
++                      ld->mc = modemctl;
++                      ld->msd = msd;
++                      list_add(&ld->list, &msd->link_dev_list);
++              }
++      }
++
++      /* create io deivces and connect to modemctl device */
++      for (i = 0; i < pdata->num_iodevs; i++) {
++              iod[i] = create_io_device(&pdata->iodevs[i], msd, modemctl,
++                              pdata);
++              if (!iod[i]) {
++                      mif_err("iod[%d] == NULL\n", i);
++                      goto err_free_modemctl;
++              }
++
++              attach_devices(iod[i], pdata->iodevs[i].tx_link);
++      }
++
++      platform_set_drvdata(pdev, modemctl);
++
++      mif_info("Complete!!!\n");
++      return 0;
++
++err_free_modemctl:
++      for (i = 0; i < pdata->num_iodevs; i++)
++              if (iod[i] != NULL)
++                      kfree(iod[i]);
++
++      if (modemctl != NULL)
++              kfree(modemctl);
++
++      if (msd != NULL)
++              kfree(msd);
++
++      return -ENOMEM;
++}
++
++static void modem_shutdown(struct platform_device *pdev)
++{
++      struct device *dev = &pdev->dev;
++      struct modem_ctl *mc = dev_get_drvdata(dev);
++      mc->ops.modem_off(mc);
++      mc->phone_state = STATE_OFFLINE;
++}
++
++static int modem_suspend(struct device *pdev)
++{
++#ifndef CONFIG_LINK_DEVICE_HSIC
++      struct modem_ctl *mc = dev_get_drvdata(pdev);
++
++      if (mc->gpio_pda_active)
++              gpio_set_value(mc->gpio_pda_active, 0);
++#endif
++
++      return 0;
++}
++
++static int modem_resume(struct device *pdev)
++{
++#ifndef CONFIG_LINK_DEVICE_HSIC
++      struct modem_ctl *mc = dev_get_drvdata(pdev);
++
++      if (mc->gpio_pda_active)
++              gpio_set_value(mc->gpio_pda_active, 1);
++#endif
++
++      return 0;
++}
++
++static const struct dev_pm_ops modem_pm_ops = {
++      .suspend    = modem_suspend,
++      .resume     = modem_resume,
++};
++
++static struct platform_driver modem_driver = {
++      .probe = modem_probe,
++      .shutdown = modem_shutdown,
++      .driver = {
++              .name = "modem_if",
++              .pm   = &modem_pm_ops,
++      },
++};
++
++static int __init modem_init(void)
++{
++      return platform_driver_register(&modem_driver);
++}
++
++module_init(modem_init);
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("Samsung Modem Interface Driver");
+diff --git a/drivers/misc/modem_if/sipc5_io_device.c b/drivers/misc/modem_if/sipc5_io_device.c
+new file mode 100644
+index 0000000..9e22e9c
+--- /dev/null
++++ b/drivers/misc/modem_if/sipc5_io_device.c
+@@ -0,0 +1,1620 @@
++/* /linux/drivers/misc/modem_if/sipc5_io_device.c
++ *
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/fs.h>
++#include <linux/poll.h>
++#include <linux/irq.h>
++#include <linux/gpio.h>
++#include <linux/if_arp.h>
++#include <linux/ip.h>
++#include <linux/if_ether.h>
++#include <linux/etherdevice.h>
++#include <linux/device.h>
++#include <linux/module.h>
++
++#include <linux/platform_data/modem.h>
++#ifdef CONFIG_LINK_DEVICE_C2C
++#include <linux/platform_data/c2c.h>
++#endif
++#include "modem_prj.h"
++#include "modem_utils.h"
++
++static ssize_t show_waketime(struct device *dev,
++              struct device_attribute *attr, char *buf)
++{
++      unsigned int msec;
++      char *p = buf;
++      struct miscdevice *miscdev = dev_get_drvdata(dev);
++      struct io_device *iod = container_of(miscdev, struct io_device,
++                      miscdev);
++
++      msec = jiffies_to_msecs(iod->waketime);
++
++      p += sprintf(buf, "raw waketime : %ums\n", msec);
++
++      return p - buf;
++}
++
++static ssize_t store_waketime(struct device *dev,
++              struct device_attribute *attr, const char *buf, size_t count)
++{
++      unsigned long msec;
++      int ret;
++      struct miscdevice *miscdev = dev_get_drvdata(dev);
++      struct io_device *iod = container_of(miscdev, struct io_device,
++                      miscdev);
++
++      ret = strict_strtoul(buf, 10, &msec);
++      if (ret)
++              return count;
++
++      iod->waketime = msecs_to_jiffies(msec);
++
++      return count;
++}
++
++static struct device_attribute attr_waketime =
++      __ATTR(waketime, S_IRUGO | S_IWUSR, show_waketime, store_waketime);
++
++static ssize_t show_loopback(struct device *dev,
++              struct device_attribute *attr, char *buf)
++{
++      struct miscdevice *miscdev = dev_get_drvdata(dev);
++      struct modem_shared *msd =
++              container_of(miscdev, struct io_device, miscdev)->msd;
++      unsigned char *ip = (unsigned char *)&msd->loopback_ipaddr;
++      char *p = buf;
++
++      p += sprintf(buf, "%u.%u.%u.%u\n", ip[0], ip[1], ip[2], ip[3]);
++
++      return p - buf;
++}
++
++static ssize_t store_loopback(struct device *dev,
++              struct device_attribute *attr, const char *buf, size_t count)
++{
++      struct miscdevice *miscdev = dev_get_drvdata(dev);
++      struct modem_shared *msd =
++              container_of(miscdev, struct io_device, miscdev)->msd;
++
++      msd->loopback_ipaddr = ipv4str_to_be32(buf, count);
++
++      return count;
++}
++
++static struct device_attribute attr_loopback =
++      __ATTR(loopback, S_IRUGO | S_IWUSR, show_loopback, store_loopback);
++
++static void iodev_showtxlink(struct io_device *iod, void *args)
++{
++      char **p = (char **)args;
++      struct link_device *ld = get_current_link(iod);
++
++      if (iod->io_typ == IODEV_NET && IS_CONNECTED(iod, ld))
++              *p += sprintf(*p, "%s: %s\n", iod->name, ld->name);
++}
++
++static ssize_t show_txlink(struct device *dev,
++              struct device_attribute *attr, char *buf)
++{
++      struct miscdevice *miscdev = dev_get_drvdata(dev);
++      struct modem_shared *msd =
++              container_of(miscdev, struct io_device, miscdev)->msd;
++      char *p = buf;
++
++      iodevs_for_each(msd, iodev_showtxlink, &p);
++
++      return p - buf;
++}
++
++static ssize_t store_txlink(struct device *dev,
++              struct device_attribute *attr, const char *buf, size_t count)
++{
++      /* don't change without gpio dynamic switching */
++      return -EINVAL;
++}
++
++static struct device_attribute attr_txlink =
++      __ATTR(txlink, S_IRUGO | S_IWUSR, show_txlink, store_txlink);
++
++/**
++ * rx_check_frame_cfg
++ * @cfg: configuration field of a link layer header
++ * @frm: pointer to the sipc5_frame_data buffer
++ *
++ * 1) Checks whether or not an extended field exists
++ * 2) Calculates the length of a link layer header
++ *
++ * Returns the size of a link layer header
++ *
++ * Must be invoked only when the configuration field of the link layer header
++ * is validated with sipc5_start_valid() function
++ */
++static int rx_check_frame_cfg(u8 cfg, struct sipc5_frame_data *frm)
++{
++      frm->config = cfg;
++
++      if (likely(cfg & SIPC5_PADDING_EXIST))
++              frm->padding = true;
++
++      if (unlikely(cfg & SIPC5_EXT_FIELD_EXIST)) {
++              if (cfg & SIPC5_CTL_FIELD_EXIST) {
++                      frm->ctl_fld = true;
++                      frm->hdr_len = SIPC5_HEADER_SIZE_WITH_CTL_FLD;
++              } else {
++                      frm->ext_len = true;
++                      frm->hdr_len = SIPC5_HEADER_SIZE_WITH_EXT_LEN;
++              }
++      } else {
++              frm->hdr_len = SIPC5_MIN_HEADER_SIZE;
++      }
++
++      return frm->hdr_len;
++}
++
++/**
++ * rx_build_meta_data
++ * @ld: pointer to the link device
++ * @frm: pointer to the sipc5_frame_data buffer
++ *
++ * Fills each field of sipc5_frame_data from a link layer header
++ * 1) Extracts the channel ID
++ * 2) Calculates the length of a link layer frame
++ * 3) Extracts a control field if exists
++ * 4) Calculates the length of an IPC message packet in the link layer frame
++ *
++ */
++static void rx_build_meta_data(struct link_device *ld,
++              struct sipc5_frame_data *frm)
++{
++      u16 *sz16 = (u16 *)(frm->hdr + SIPC5_LEN_OFFSET);
++      u32 *sz32 = (u32 *)(frm->hdr + SIPC5_LEN_OFFSET);
++
++      frm->ch_id = frm->hdr[SIPC5_CH_ID_OFFSET];
++
++      if (unlikely(frm->ext_len))
++              frm->len = *sz32;
++      else
++              frm->len = *sz16;
++
++      if (unlikely(frm->ctl_fld))
++              frm->control = frm->hdr[SIPC5_CTL_OFFSET];
++
++      frm->data_len = frm->len - frm->hdr_len;
++
++      mif_debug("%s: FRM ch:%d len:%d ctl:%02X data.len:%d\n",
++              ld->name, frm->ch_id, frm->len, frm->control, frm->data_len);
++}
++
++/**
++ * tx_build_link_header
++ * @frm: pointer to the sipc5_frame_data buffer
++ * @iod: pointer to the IO device
++ * @ld: pointer to the link device
++ * @count: length of the data to be transmitted
++ *
++ * Builds the meta data for an SIPC5 frame and the link layer header of it
++ * Returns the link layer header length for an SIPC5 frame or 0 for other frame
++ */
++static unsigned tx_build_link_header(struct sipc5_frame_data *frm,
++              struct io_device *iod, struct link_device *ld, ssize_t count)
++{
++      u8 *buff = frm->hdr;
++      u16 *sz16 = (u16 *)(buff + SIPC5_LEN_OFFSET);
++      u32 *sz32 = (u32 *)(buff + SIPC5_LEN_OFFSET);
++
++      memset(frm, 0, sizeof(struct sipc5_frame_data));
++
++      if (iod->format == IPC_CMD ||
++          iod->format == IPC_BOOT ||
++          iod->format == IPC_RAMDUMP) {
++              frm->len = count;
++              return 0;
++      }
++
++      frm->config = SIPC5_START_MASK;
++
++      if (iod->format == IPC_FMT && count > 2048) {
++              frm->ctl_fld = true;
++              frm->config |= SIPC5_EXT_FIELD_EXIST;
++              frm->config |= SIPC5_CTL_FIELD_EXIST;
++      }
++
++      if (iod->id >= SIPC5_CH_ID_RFS_0 && count > 0xFFFF) {
++              frm->ext_len = true;
++              frm->config |= SIPC5_EXT_FIELD_EXIST;
++      }
++
++      if (ld->aligned)
++              frm->config |= SIPC5_PADDING_EXIST;
++
++      frm->ch_id = iod->id;
++
++      frm->hdr_len = sipc5_get_hdr_len(frm->config);
++      frm->data_len = count;
++      frm->len = frm->hdr_len + frm->data_len;
++
++      buff[SIPC5_CONFIG_OFFSET] = frm->config;
++      buff[SIPC5_CH_ID_OFFSET] = frm->ch_id;
++
++      if (unlikely(frm->ext_len))
++              *sz32 = (u32)frm->len;
++      else
++              *sz16 = (u16)frm->len;
++
++      if (unlikely(frm->ctl_fld))
++              buff[SIPC5_CTL_OFFSET] = frm->control;
++
++      return frm->hdr_len;
++}
++
++static int rx_fmt_frame(struct sk_buff *skb)
++{
++      struct io_device *iod = skbpriv(skb)->iod;
++      struct link_device *ld = skbpriv(skb)->ld;
++      struct sk_buff_head *rxq = &iod->sk_rx_q;
++      struct sipc_fmt_hdr *fh;
++      struct sk_buff *rx_skb;
++      u8 ctrl = skbpriv(skb)->control;
++      unsigned id = ctrl & 0x7F;
++
++      if (iod->skb[id] == NULL) {
++              /*
++              ** There has been no multiple frame with this ID.
++              */
++              if ((ctrl & 0x80) == 0) {
++                      /*
++                      ** It is a single frame because the "more" bit is 0.
++                      */
++                      skb_queue_tail(rxq, skb);
++                      if (unlikely(rxq->qlen > 2048)) {
++                              struct sk_buff *victim;
++                              mif_info("%s: WARNING! rxq->qlen %d > 2048\n",
++                                      iod->name, rxq->qlen);
++                              victim = skb_dequeue(rxq);
++                              dev_kfree_skb_any(victim);
++                      } else {
++                              mif_debug("%s: rxq->qlen = %d\n",
++                                      iod->name, rxq->qlen);
++                      }
++
++                      wake_up(&iod->wq);
++                      return 0;
++              }
++
++              /*
++              ** The start of multiple frames
++              */
++              fh = (struct sipc_fmt_hdr *)skb->data;
++              mif_debug("%s: start multi-frame (ID:%d len:%d)\n",
++                      iod->name, id, fh->len);
++
++              rx_skb = rx_alloc_skb(fh->len, iod, ld);
++              if (!rx_skb) {
++                      mif_info("%s: ERR! rx_alloc_skb fail\n", iod->name);
++                      return -ENOMEM;
++              }
++
++              iod->skb[id] = rx_skb;
++      } else {
++              rx_skb = iod->skb[id];
++      }
++
++      /*
++      ** Start multi-frame processing
++      */
++      memcpy(skb_put(rx_skb, skb->len), skb->data, skb->len);
++      dev_kfree_skb_any(skb);
++
++      if (ctrl & 0x80) {
++              /* The last frame has not arrived yet. */
++              mif_debug("%s: recv multi-frame (ID:%d rcvd:%d)\n",
++                      iod->name, id, rx_skb->len);
++      } else {
++              /* It is the last frame because the "more" bit is 0. */
++              mif_debug("%s: end multi-frame (ID:%d rcvd:%d)\n",
++                      iod->name, id, rx_skb->len);
++              skb_queue_tail(rxq, rx_skb);
++              if (unlikely(rxq->qlen > 2048)) {
++                      struct sk_buff *victim;
++                      mif_info("%s: WARNING! rxq->qlen %d > 2048\n",
++                              iod->name, rxq->qlen);
++                      victim = skb_dequeue(rxq);
++                      dev_kfree_skb_any(victim);
++              } else {
++                      mif_debug("%s: rxq->qlen = %d\n", iod->name, rxq->qlen);
++              }
++
++              iod->skb[id] = NULL;
++              wake_up(&iod->wq);
++      }
++
++      return 0;
++}
++
++static int rx_rfs_frame(struct sk_buff *skb)
++{
++      struct io_device *iod = skbpriv(skb)->iod;
++      struct sk_buff_head *rxq = &iod->sk_rx_q;
++
++      skb_queue_tail(rxq, skb);
++      if (unlikely(rxq->qlen > 2048)) {
++              struct sk_buff *victim;
++              mif_debug("%s: rxq->qlen %d > 2048\n", iod->name, rxq->qlen);
++              victim = skb_dequeue(rxq);
++              dev_kfree_skb_any(victim);
++      } else {
++              mif_debug("%s: rxq->qlen %d\n", iod->name, rxq->qlen);
++      }
++
++      wake_up(&iod->wq);
++
++      return 0;
++}
++
++static int rx_loopback(struct sk_buff *skb)
++{
++      struct io_device *iod = skbpriv(skb)->iod;
++      struct link_device *ld = get_current_link(iod);
++      struct sipc5_frame_data frm;
++      unsigned headroom;
++      unsigned tailroom = 0;
++      int ret;
++
++      headroom = tx_build_link_header(&frm, iod, ld, skb->len);
++
++      if (ld->aligned)
++              tailroom = sipc5_calc_padding_size(headroom + skb->len);
++
++      /* We need not to expand skb in here. dev_alloc_skb (in rx_alloc_skb)
++       * already alloc 32bytes padding in headroom. 32bytes are enough.
++       */
++
++      /* store IPC link header to start of skb
++       * this is skb_push not skb_put. different with misc_write.
++       */
++      memcpy(skb_push(skb, headroom), frm.hdr, headroom);
++
++      /* store padding */
++      if (tailroom)
++              skb_put(skb, tailroom);
++
++      /* forward */
++      ret = ld->send(ld, iod, skb);
++      if (ret < 0)
++              mif_err("%s->%s: ld->send fail: %d\n", iod->name,
++                              ld->name, ret);
++      return ret;
++}
++
++static int rx_raw_misc(struct sk_buff *skb)
++{
++      struct io_device *iod = skbpriv(skb)->iod; /* same with real_iod */
++      struct sk_buff_head *rxq = &iod->sk_rx_q;
++
++      skb_queue_tail(rxq, skb);
++      if (unlikely(rxq->qlen > 2048)) {
++              struct sk_buff *victim;
++              mif_debug("%s: rxq->qlen %d > 2048\n", iod->name, rxq->qlen);
++              victim = skb_dequeue(rxq);
++              dev_kfree_skb_any(victim);
++      } else {
++              mif_debug("%s: rxq->qlen %d\n", iod->name, rxq->qlen);
++      }
++
++      wake_up(&iod->wq);
++
++      return 0;
++}
++
++static int rx_multi_pdp(struct sk_buff *skb)
++{
++      struct io_device *iod = skbpriv(skb)->iod; /* same with real_iod */
++      struct net_device *ndev;
++      struct iphdr *iphdr;
++      struct ethhdr *ehdr;
++      int ret;
++      const char source[ETH_ALEN] = SOURCE_MAC_ADDR;
++
++      ndev = iod->ndev;
++      if (!ndev) {
++              mif_info("%s: ERR! no iod->ndev\n", iod->name);
++              return -ENODEV;
++      }
++
++      skb->dev = ndev;
++      ndev->stats.rx_packets++;
++      ndev->stats.rx_bytes += skb->len;
++
++      /* check the version of IP */
++      iphdr = (struct iphdr *)skb->data;
++      if (iphdr->version == IP6VERSION)
++              skb->protocol = htons(ETH_P_IPV6);
++      else
++              skb->protocol = htons(ETH_P_IP);
++
++      if (iod->use_handover) {
++              skb_push(skb, sizeof(struct ethhdr));
++              ehdr = (void *)skb->data;
++              memcpy(ehdr->h_dest, ndev->dev_addr, ETH_ALEN);
++              memcpy(ehdr->h_source, source, ETH_ALEN);
++              ehdr->h_proto = skb->protocol;
++              skb->ip_summed = CHECKSUM_UNNECESSARY;
++              skb_reset_mac_header(skb);
++
++              skb_pull(skb, sizeof(struct ethhdr));
++      }
++
++      if (in_interrupt())
++              ret = netif_rx(skb);
++      else
++              ret = netif_rx_ni(skb);
++
++      if (ret != NET_RX_SUCCESS)
++              mif_info("%s: ERR! netif_rx fail (err %d)\n", iod->name, ret);
++
++      return ret;
++}
++
++static int rx_demux(struct link_device *ld, struct sk_buff *skb)
++{
++      struct io_device *iod = NULL;
++      char *link = ld->name;
++      u8 ch = skbpriv(skb)->ch_id;
++
++      if (unlikely(ch == SIPC5_CH_ID_MAX || ch == 0)) {
++              mif_info("%s: ERR! invalid ch# %d\n", link, ch);
++              return -ENODEV;
++      }
++
++      /* IP loopback */
++      if (ch == DATA_LOOPBACK_CHANNEL && ld->msd->loopback_ipaddr)
++              ch = RMNET0_CH_ID;
++
++      iod = link_get_iod_with_channel(ld, ch);
++      if (unlikely(!iod)) {
++              mif_info("%s: ERR! no iod for ch# %d\n", link, ch);
++              return -ENODEV;
++      }
++
++      skbpriv(skb)->ld = ld;
++      skbpriv(skb)->iod = iod;
++      skbpriv(skb)->real_iod = iod;
++
++      /* don't care about CP2AP_LOOPBACK_CHANNEL is opened */
++      if (unlikely(iod->id == CP2AP_LOOPBACK_CHANNEL))
++              return rx_loopback(skb);
++
++      if (atomic_read(&iod->opened) <= 0) {
++              mif_info("%s: ERR! %s is not opened\n", link, iod->name);
++              return -ENODEV;
++      }
++
++      if (ch >= SIPC5_CH_ID_RFS_0)
++              return rx_rfs_frame(skb);
++      else if (ch >= SIPC5_CH_ID_FMT_0)
++              return rx_fmt_frame(skb);
++      else if (iod->io_typ == IODEV_MISC)
++              return rx_raw_misc(skb);
++      else
++              return rx_multi_pdp(skb);
++}
++
++/* Check and store link layer header, then alloc an skb */
++static int rx_header_from_serial(struct io_device *iod, struct link_device *ld,
++              u8 *buff, unsigned size, struct sipc5_frame_data *frm)
++{
++      char *link = ld->name;
++      struct sk_buff *skb;
++      int len;
++      u8 cfg = buff[0];
++
++      mif_debug("%s: size %d\n", link, size);
++
++      if (!frm->config) {
++              if (unlikely(!sipc5_start_valid(cfg))) {
++                      mif_info("%s: ERR! wrong start (0x%02x)\n", link, cfg);
++                      return -EBADMSG;
++              }
++              rx_check_frame_cfg(cfg, frm);
++
++              /* Copy the link layer header to the header buffer */
++              len = min(frm->hdr_len, size);
++              memcpy(frm->hdr, buff, len);
++      } else {
++              /* Copy the link layer header to the header buffer */
++              len = min((frm->hdr_len - frm->hdr_rcvd), size);
++              memcpy((frm->hdr + frm->hdr_rcvd), buff, len);
++      }
++
++      frm->hdr_rcvd += len;
++
++      mif_debug("%s: FRM hdr_len:%d, hdr_rcvd:%d\n",
++              link, frm->hdr_len, frm->hdr_rcvd);
++
++      if (frm->hdr_rcvd >= frm->hdr_len) {
++              rx_build_meta_data(ld, frm);
++              skb = rx_alloc_skb(frm->data_len, iod, ld);
++              fragdata(iod, ld)->skb_recv = skb;
++              skbpriv(skb)->ch_id = frm->ch_id;
++              skbpriv(skb)->control = frm->control;
++      }
++
++      return len;
++}
++
++/* copy data to skb */
++static int rx_payload_from_serial(struct io_device *iod, struct link_device *ld,
++              u8 *buff, unsigned size, struct sipc5_frame_data *frm)
++{
++      struct sk_buff *skb = fragdata(iod, ld)->skb_recv;
++      char *link = ld->name;
++      unsigned rest = frm->data_len - frm->data_rcvd;
++      unsigned len;
++
++      /* rest == (frm->data_len - frm->data_rcvd) == tailroom of skb */
++      rest = frm->data_len - frm->data_rcvd;
++      mif_debug("%s: FRM data.len:%d data.rcvd:%d rest:%d size:%d\n",
++              link, frm->data_len, frm->data_rcvd, rest, size);
++
++      /* If there is no skb, data must be dropped. */
++      len = min(rest, size);
++      if (skb)
++              memcpy(skb_put(skb, len), buff, len);
++
++      frm->data_rcvd += len;
++
++      mif_debug("%s: FRM data_len:%d, data_rcvd:%d\n",
++              link, frm->data_len, frm->data_rcvd);
++
++      return len;
++}
++
++static int rx_frame_from_serial(struct io_device *iod, struct link_device *ld,
++              const char *data, unsigned size)
++{
++      struct sipc5_frame_data *frm = &fragdata(iod, ld)->f_data;
++      struct sk_buff *skb;
++      char *link = ld->name;
++      u8 *buff = (u8 *)data;
++      int rest = (int)size;
++      int err = 0;
++      int done = 0;
++
++      mif_debug("%s: size = %d\n", link, size);
++
++      if (frm->hdr_rcvd >= frm->hdr_len && frm->data_rcvd < frm->data_len) {
++              /*
++              ** There is an skb that is waiting for more SIPC5 data.
++              ** In this case, rx_header_from_serial() must be skipped.
++              */
++              mif_debug("%s: FRM data.len:%d data.rcvd:%d -> recv_data\n",
++                      link, frm->data_len, frm->data_rcvd);
++              goto recv_data;
++      }
++
++next_frame:
++      /* Receive and analyze header, then prepare an akb */
++      err = done = rx_header_from_serial(iod, ld, buff, rest, frm);
++      if (err < 0)
++              goto err_exit;
++
++      buff += done;
++      rest -= done;
++      mif_debug("%s: rx_header() -> done:%d rest:%d\n", link, done, rest);
++      if (rest < 0)
++              goto err_range;
++
++      if (rest == 0)
++              return size;
++
++recv_data:
++      err = 0;
++
++      mif_debug("%s: done:%d rest:%d -> rx_payload()\n", link, done, rest);
++
++      done = rx_payload_from_serial(iod, ld, buff, rest, frm);
++      buff += done;
++      rest -= done;
++
++      mif_debug("%s: rx_payload() -> done:%d rest:%d\n", link, done, rest);
++
++      if (rest == 0 && frm->data_rcvd < frm->data_len) {
++              /*
++                Data is being received and more data will come within the next
++                frame from the link device.
++              */
++              return size;
++      }
++
++      /* At this point, one complete link layer frame has been received. */
++
++      /* A padding size is applied to access the next IPC frame. */
++      if (frm->padding) {
++              done = sipc5_calc_padding_size(frm->len);
++              if (done > rest) {
++                      mif_info("%s: ERR! padding %d > rest %d\n",
++                              link, done, rest);
++                      goto err_exit;
++              }
++
++              buff += done;
++              rest -= done;
++
++              mif_debug("%s: padding:%d -> rest:%d\n", link, done, rest);
++
++              if (rest < 0)
++                      goto err_range;
++
++      }
++
++      skb = fragdata(iod, ld)->skb_recv;
++      if (likely(skb)) {
++              mif_debug("%s: len:%d -> rx_demux()\n", link, skb->len);
++              err = rx_demux(ld, skb);
++              if (err < 0)
++                      dev_kfree_skb_any(skb);
++      } else {
++              mif_debug("%s: len:%d -> drop\n", link, skb->len);
++      }
++
++      /* initialize the skb_recv and the frame_data buffer */
++      fragdata(iod, ld)->skb_recv = NULL;
++      memset(frm, 0, sizeof(struct sipc5_frame_data));
++
++      if (rest > 0)
++              goto next_frame;
++
++      if (rest <= 0)
++              return size;
++
++err_exit:
++      if (fragdata(iod, ld)->skb_recv &&
++          frm->hdr_rcvd >= frm->hdr_len && frm->data_rcvd >= frm->data_len) {
++              dev_kfree_skb_any(fragdata(iod, ld)->skb_recv);
++              memset(frm, 0, sizeof(struct sipc5_frame_data));
++              fragdata(iod, ld)->skb_recv = NULL;
++              mif_info("%s: ERR! clear frag\n", link);
++      }
++      return err;
++
++err_range:
++      mif_info("%s: ERR! size:%d vs. rest:%d\n", link, size, rest);
++      return size;
++}
++
++/**
++ * rx_header_from_mem
++ * @ld: pointer to the link device
++ * @buff: pointer to the frame
++ * @rest: size of the frame
++ * @frm: pointer to the sipc5_frame_data buffer
++ *
++ * 1) Verifies a link layer header configuration of a frame
++ * 2) Stores the link layer header to the header buffer
++ * 3) Builds and stores the meta data of the frame into a meta data buffer
++ * 4) Verifies the length of the frame
++ *
++ * Returns SIPC5 header length
++ */
++static int rx_header_from_mem(struct link_device *ld, u8 *buff, unsigned rest,
++              struct sipc5_frame_data *frm)
++{
++      char *link = ld->name;
++      u8 cfg = buff[0];
++
++      /* Verify link layer header configuration */
++      if (unlikely(!sipc5_start_valid(cfg))) {
++              mif_info("%s: ERR! wrong start (0x%02x)\n", link, cfg);
++              return -EBADMSG;
++      }
++      rx_check_frame_cfg(cfg, frm);
++
++      /* Store the link layer header to the header buffer */
++      memcpy(frm->hdr, buff, frm->hdr_len);
++      frm->hdr_rcvd = frm->hdr_len;
++
++      /* Build and store the meta data of this frame */
++      rx_build_meta_data(ld, frm);
++
++      /* Verify frame length */
++      if (unlikely(frm->len > rest)) {
++              mif_info("%s: ERR! frame length %d > rest %d\n",
++                      link, frm->len, rest);
++              return -EBADMSG;
++      }
++
++      return frm->hdr_rcvd;
++}
++
++/* copy data to skb */
++static int rx_payload_from_mem(struct sk_buff *skb, u8 *buff, unsigned len)
++{
++      /* If there is no skb, data must be dropped. */
++      if (skb)
++              memcpy(skb_put(skb, len), buff, len);
++      return len;
++}
++
++static int rx_frame_from_mem(struct io_device *iod, struct link_device *ld,
++              const char *data, unsigned size)
++{
++      struct sipc5_frame_data *frm = &fragdata(iod, ld)->f_data;
++      struct sk_buff *skb;
++      char *link = ld->name;
++      u8 *buff = (u8 *)data;
++      int rest = (int)size;
++      int len;
++      int done;
++
++      mif_debug("%s: size = %d\n", link, size);
++
++      while (rest > 0) {
++              /* Initialize the frame data buffer */
++              memset(frm, 0, sizeof(struct sipc5_frame_data));
++              skb = NULL;
++
++              /* Receive and analyze link layer header */
++              done = rx_header_from_mem(ld, buff, rest, frm);
++              if (unlikely(done < 0))
++                      return -EBADMSG;
++
++              /* Verify rest size */
++              rest -= done;
++              if (rest < 0) {
++                      mif_info("%s: ERR! rx_header -> rest %d\n", link, rest);
++                      return -ERANGE;
++              }
++
++              /* Move buff pointer to the payload */
++              buff += done;
++
++              /* Prepare an akb */
++              len = frm->data_len;
++              skb = rx_alloc_skb(len, iod, ld);
++
++              /* Store channel ID and control fields to the CB of the skb */
++              skbpriv(skb)->ch_id = frm->ch_id;
++              skbpriv(skb)->control = frm->control;
++
++              /* Receive payload */
++              mif_debug("%s: done:%d rest:%d len:%d -> rx_payload()\n",
++                      link, done, rest, len);
++              done = rx_payload_from_mem(skb, buff, len);
++              rest -= done;
++              if (rest < 0) {
++                      mif_info("%s: ERR! rx_payload() -> rest %d\n",
++                              link, rest);
++                      if (skb)
++                              dev_kfree_skb_any(skb);
++                      return -ERANGE;
++              }
++              buff += done;
++
++              /* A padding size is applied to access the next IPC frame. */
++              if (frm->padding) {
++                      done = sipc5_calc_padding_size(frm->len);
++                      if (done > rest) {
++                              mif_info("%s: ERR! padding %d > rest %d\n",
++                                      link, done, rest);
++                              if (skb)
++                                      dev_kfree_skb_any(skb);
++                              return -ERANGE;
++                      }
++                      buff += done;
++                      rest -= done;
++              }
++
++              if (likely(skb)) {
++                      mif_debug("%s: len:%d -> rx_demux()\n", link, skb->len);
++                      if (rx_demux(ld, skb) < 0)
++                              dev_kfree_skb_any(skb);
++              } else {
++                      mif_debug("%s: len:%d -> drop\n", link, skb->len);
++              }
++      }
++
++      return 0;
++}
++
++/* called from link device when a packet arrives for this io device */
++static int io_dev_recv_data_from_link_dev(struct io_device *iod,
++              struct link_device *ld, const char *data, unsigned int len)
++{
++      struct sk_buff_head *rxq = &iod->sk_rx_q;
++      struct sk_buff *skb;
++      char *link = ld->name;
++      int err;
++
++      if (!data) {
++              mif_info("%s: ERR! !data\n", link);
++              return -EINVAL;
++      }
++
++      if (len <= 0) {
++              mif_info("%s: ERR! len %d <= 0\n", link, len);
++              return -EINVAL;
++      }
++
++      switch (iod->format) {
++      case IPC_FMT:
++      case IPC_RAW:
++      case IPC_RFS:
++      case IPC_MULTI_RAW:
++              if (iod->waketime)
++                      wake_lock_timeout(&iod->wakelock, iod->waketime);
++
++              if (ld->link_type == LINKDEV_DPRAM && ld->aligned)
++                      err = rx_frame_from_mem(iod, ld, data, len);
++              else
++                      err = rx_frame_from_serial(iod, ld, data, len);
++
++              if (err < 0)
++                      mif_info("%s: ERR! rx_frame_from_link fail (err %d)\n",
++                              link, err);
++
++              return err;
++
++      case IPC_CMD:
++      case IPC_BOOT:
++      case IPC_RAMDUMP:
++              /* save packet to sk_buff */
++              skb = rx_alloc_skb(len, iod, ld);
++              if (!skb) {
++                      mif_info("%s: ERR! rx_alloc_skb fail\n", link);
++                      return -ENOMEM;
++              }
++
++              mif_debug("%s: len:%d -> iod:%s\n", link, len, iod->name);
++
++              memcpy(skb_put(skb, len), data, len);
++              skb_queue_tail(rxq, skb);
++              if (unlikely(rxq->qlen > 2048)) {
++                      struct sk_buff *victim;
++                      mif_info("%s: ERR! rxq->qlen %d > 2048\n",
++                              iod->name, rxq->qlen);
++                      victim = skb_dequeue(rxq);
++                      dev_kfree_skb_any(victim);
++              }
++              wake_up(&iod->wq);
++
++              return len;
++
++      default:
++              mif_info("%s: ERR! unknown format %d\n", link, iod->format);
++              return -EINVAL;
++      }
++}
++
++static int rx_frame_from_skb(struct io_device *iod, struct link_device *ld,
++              struct sk_buff *skb)
++{
++      struct sipc5_frame_data *frm = &fragdata(iod, ld)->f_data;
++      u8 cfg = skb->data[0];
++
++      /* Initialize the frame data buffer */
++      memset(frm, 0, sizeof(struct sipc5_frame_data));
++
++      /*
++      ** The start of a link layer header has already been checked in the
++      ** link device.
++      */
++
++      /* Analyze the configuration of the link layer header */
++      rx_check_frame_cfg(cfg, frm);
++
++      /* Store the link layer header to the header buffer */
++      memcpy(frm->hdr, skb->data, frm->hdr_len);
++      frm->hdr_rcvd = frm->hdr_len;
++
++      /* Build and store the meta data of this frame */
++      rx_build_meta_data(ld, frm);
++
++      /*
++      ** The length of the frame has already been checked in the link device.
++      */
++
++      /* Trim the link layer header off the frame */
++      skb_pull(skb, frm->hdr_len);
++
++      /* Store channel ID and control fields to the CB of the skb */
++      skbpriv(skb)->ch_id = frm->ch_id;
++      skbpriv(skb)->control = frm->control;
++
++      /* Demux the frame */
++      if (rx_demux(ld, skb) < 0) {
++              mif_err("%s: ERR! rx_demux fail\n", ld->name);
++              return -EINVAL;
++      }
++
++      return 0;
++}
++
++/* called from link device when a packet arrives for this io device */
++static int io_dev_recv_skb_from_link_dev(struct io_device *iod,
++              struct link_device *ld, struct sk_buff *skb)
++{
++      char *link = ld->name;
++      enum dev_format dev = iod->format;
++      int err;
++
++      switch (dev) {
++      case IPC_FMT:
++      case IPC_RAW:
++      case IPC_RFS:
++      case IPC_MULTI_RAW:
++              if (iod->waketime)
++                      wake_lock_timeout(&iod->wakelock, iod->waketime);
++
++              err = rx_frame_from_skb(iod, ld, skb);
++              if (err < 0) {
++                      dev_kfree_skb_any(skb);
++                      mif_info("%s: ERR! rx_frame_from_skb fail (err %d)\n",
++                              link, err);
++              }
++
++              return err;
++
++      default:
++              mif_info("%s: ERR! unknown device %d\n", link, dev);
++              return -EINVAL;
++      }
++}
++
++/* inform the IO device that the modem is now online or offline or
++ * crashing or whatever...
++ */
++static void io_dev_modem_state_changed(struct io_device *iod,
++                      enum modem_state state)
++{
++      mif_info("%s: %s state changed (state %d)\n",
++              iod->name, iod->mc->name, state);
++
++      iod->mc->phone_state = state;
++
++      if (state == STATE_CRASH_RESET || state == STATE_CRASH_EXIT ||
++          state == STATE_NV_REBUILDING)
++              wake_up(&iod->wq);
++}
++
++/**
++ * io_dev_sim_state_changed
++ * @iod:      IPC's io_device
++ * @sim_online: SIM is online?
++ */
++static void io_dev_sim_state_changed(struct io_device *iod, bool sim_online)
++{
++      if (atomic_read(&iod->opened) == 0) {
++              mif_info("%s: ERR! not opened\n", iod->name);
++      } else if (iod->mc->sim_state.online == sim_online) {
++              mif_info("%s: SIM state not changed\n", iod->name);
++      } else {
++              iod->mc->sim_state.online = sim_online;
++              iod->mc->sim_state.changed = true;
++              mif_info("%s: SIM state changed {online %d, changed %d}\n",
++                      iod->name, iod->mc->sim_state.online,
++                      iod->mc->sim_state.changed);
++              wake_up(&iod->wq);
++      }
++}
++
++static void iodev_dump_status(struct io_device *iod, void *args)
++{
++      if (iod->format == IPC_RAW && iod->io_typ == IODEV_NET) {
++              struct link_device *ld = get_current_link(iod);
++              mif_com_log(iod->mc->msd, "%s: %s\n", iod->name, ld->name);
++      }
++}
++
++static int misc_open(struct inode *inode, struct file *filp)
++{
++      struct io_device *iod = to_io_device(filp->private_data);
++      struct modem_shared *msd = iod->msd;
++      struct link_device *ld;
++      int ret;
++      filp->private_data = (void *)iod;
++
++      atomic_inc(&iod->opened);
++
++      list_for_each_entry(ld, &msd->link_dev_list, list) {
++              if (IS_CONNECTED(iod, ld) && ld->init_comm) {
++                      ret = ld->init_comm(ld, iod);
++                      if (ret < 0) {
++                              mif_info("%s: init_comm fail(%d)\n",
++                                      ld->name, ret);
++                              return ret;
++                      }
++              }
++      }
++
++      mif_err("%s (opened %d)\n", iod->name, atomic_read(&iod->opened));
++
++      return 0;
++}
++
++static int misc_release(struct inode *inode, struct file *filp)
++{
++      struct io_device *iod = (struct io_device *)filp->private_data;
++      struct modem_shared *msd = iod->msd;
++      struct link_device *ld;
++
++      atomic_dec(&iod->opened);
++      skb_queue_purge(&iod->sk_rx_q);
++
++      list_for_each_entry(ld, &msd->link_dev_list, list) {
++              if (IS_CONNECTED(iod, ld) && ld->terminate_comm)
++                      ld->terminate_comm(ld, iod);
++      }
++
++      mif_err("%s (opened %d)\n", iod->name, atomic_read(&iod->opened));
++
++      return 0;
++}
++
++static unsigned int misc_poll(struct file *filp, struct poll_table_struct *wait)
++{
++      struct io_device *iod = (struct io_device *)filp->private_data;
++
++      poll_wait(filp, &iod->wq, wait);
++
++      if (!skb_queue_empty(&iod->sk_rx_q) &&
++          iod->mc->phone_state != STATE_OFFLINE) {
++              return POLLIN | POLLRDNORM;
++      } else if ((iod->mc->phone_state == STATE_CRASH_RESET) ||
++                 (iod->mc->phone_state == STATE_CRASH_EXIT) ||
++                 (iod->mc->phone_state == STATE_NV_REBUILDING) ||
++                 (iod->mc->sim_state.changed)) {
++              if (iod->format == IPC_RAW) {
++                      msleep(20);
++                      return 0;
++              }
++              return POLLHUP;
++      } else {
++              return 0;
++      }
++}
++
++static long misc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
++{
++      int p_state;
++      struct io_device *iod = (struct io_device *)filp->private_data;
++      struct link_device *ld = get_current_link(iod);
++      char cpinfo_buf[530] = "CP Crash ";
++      unsigned long size;
++      int ret;
++
++      switch (cmd) {
++      case IOCTL_MODEM_ON:
++              mif_info("%s: IOCTL_MODEM_ON\n", iod->name);
++              return iod->mc->ops.modem_on(iod->mc);
++
++      case IOCTL_MODEM_OFF:
++              mif_info("%s: IOCTL_MODEM_OFF\n", iod->name);
++              return iod->mc->ops.modem_off(iod->mc);
++
++      case IOCTL_MODEM_RESET:
++              mif_info("%s: IOCTL_MODEM_RESET\n", iod->name);
++              return iod->mc->ops.modem_reset(iod->mc);
++
++      case IOCTL_MODEM_BOOT_ON:
++              mif_info("%s: IOCTL_MODEM_BOOT_ON\n", iod->name);
++              return iod->mc->ops.modem_boot_on(iod->mc);
++
++      case IOCTL_MODEM_BOOT_OFF:
++              mif_info("%s: IOCTL_MODEM_BOOT_OFF\n", iod->name);
++              return iod->mc->ops.modem_boot_off(iod->mc);
++
++      case IOCTL_MODEM_BOOT_DONE:
++              mif_err("%s: IOCTL_MODEM_BOOT_DONE\n", iod->name);
++              if (iod->mc->ops.modem_boot_done)
++                      return iod->mc->ops.modem_boot_done(iod->mc);
++              else
++                      return 0;
++
++      case IOCTL_MODEM_STATUS:
++              mif_debug("%s: IOCTL_MODEM_STATUS\n", iod->name);
++
++              p_state = iod->mc->phone_state;
++              if ((p_state == STATE_CRASH_RESET) ||
++                  (p_state == STATE_CRASH_EXIT)) {
++                      mif_info("%s: IOCTL_MODEM_STATUS (state %d)\n",
++                              iod->name, p_state);
++              } else if (iod->mc->sim_state.changed) {
++                      int s_state = iod->mc->sim_state.online ?
++                                      STATE_SIM_ATTACH : STATE_SIM_DETACH;
++                      iod->mc->sim_state.changed = false;
++                      return s_state;
++              } else if (p_state == STATE_NV_REBUILDING) {
++                      mif_info("%s: IOCTL_MODEM_STATUS (state %d)\n",
++                              iod->name, p_state);
++                      iod->mc->phone_state = STATE_ONLINE;
++              }
++              return p_state;
++
++      case IOCTL_MODEM_PROTOCOL_SUSPEND:
++              mif_debug("%s: IOCTL_MODEM_PROTOCOL_SUSPEND\n",
++                      iod->name);
++
++              if (iod->format != IPC_MULTI_RAW)
++                      return -EINVAL;
++
++              iodevs_for_each(iod->msd, iodev_netif_stop, 0);
++              return 0;
++
++      case IOCTL_MODEM_PROTOCOL_RESUME:
++              mif_info("%s: IOCTL_MODEM_PROTOCOL_RESUME\n",
++                      iod->name);
++
++              if (iod->format != IPC_MULTI_RAW)
++                      return -EINVAL;
++
++              iodevs_for_each(iod->msd, iodev_netif_wake, 0);
++              return 0;
++
++      case IOCTL_MODEM_DUMP_START:
++              mif_info("%s: IOCTL_MODEM_DUMP_START\n", iod->name);
++              return ld->dump_start(ld, iod);
++
++      case IOCTL_MODEM_DUMP_UPDATE:
++              mif_debug("%s: IOCTL_MODEM_DUMP_UPDATE\n", iod->name);
++              return ld->dump_update(ld, iod, arg);
++
++      case IOCTL_MODEM_FORCE_CRASH_EXIT:
++              mif_info("%s: IOCTL_MODEM_FORCE_CRASH_EXIT\n", iod->name);
++              if (iod->mc->ops.modem_force_crash_exit)
++                      return iod->mc->ops.modem_force_crash_exit(iod->mc);
++              return -EINVAL;
++
++      case IOCTL_MODEM_CP_UPLOAD:
++              mif_info("%s: IOCTL_MODEM_CP_UPLOAD\n", iod->name);
++              if (copy_from_user(cpinfo_buf + strlen(cpinfo_buf),
++                      (void __user *)arg, MAX_CPINFO_SIZE) != 0)
++                      return -EFAULT;
++              panic(cpinfo_buf);
++              return 0;
++
++      case IOCTL_MODEM_DUMP_RESET:
++              mif_info("%s: IOCTL_MODEM_DUMP_RESET\n", iod->name);
++              return iod->mc->ops.modem_dump_reset(iod->mc);
++
++      case IOCTL_MIF_LOG_DUMP:
++              iodevs_for_each(iod->msd, iodev_dump_status, 0);
++              size = MAX_MIF_BUFF_SIZE;
++              ret = copy_to_user((void __user *)arg, &size,
++                      sizeof(unsigned long));
++              if (ret < 0)
++                      return -EFAULT;
++
++              mif_dump_log(iod->mc->msd, iod);
++              return 0;
++
++      case IOCTL_MIF_DPRAM_DUMP:
++#ifdef CONFIG_LINK_DEVICE_DPRAM
++              if (iod->mc->mdm_data->link_types & LINKTYPE(LINKDEV_DPRAM)) {
++                      size = iod->mc->mdm_data->dpram_ctl->dp_size;
++                      ret = copy_to_user((void __user *)arg, &size,
++                              sizeof(unsigned long));
++                      if (ret < 0)
++                              return -EFAULT;
++                      mif_dump_dpram(iod);
++                      return 0;
++              }
++#endif
++              return -EINVAL;
++
++      default:
++               /* If you need to handle the ioctl for specific link device,
++                * then assign the link ioctl handler to ld->ioctl
++                * It will be call for specific link ioctl */
++              if (ld->ioctl)
++                      return ld->ioctl(ld, iod, cmd, arg);
++
++              mif_info("%s: ERR! cmd 0x%X not defined.\n", iod->name, cmd);
++              return -EINVAL;
++      }
++      return 0;
++}
++
++static ssize_t misc_write(struct file *filp, const char __user *data,
++                      size_t count, loff_t *fpos)
++{
++      struct io_device *iod = (struct io_device *)filp->private_data;
++      struct link_device *ld = get_current_link(iod);
++      struct sk_buff *skb;
++      int ret;
++      unsigned headroom = 0;
++      unsigned tailroom = 0;
++      size_t tx_size;
++      struct sipc5_frame_data frm;
++
++      if (iod->format <= IPC_RFS && iod->id == 0)
++              return -EINVAL;
++
++      headroom = tx_build_link_header(&frm, iod, ld, count);
++
++      if (ld->aligned)
++              tailroom = sipc5_calc_padding_size(headroom + count);
++
++      tx_size = headroom + count + tailroom;
++
++      skb = alloc_skb(tx_size, GFP_KERNEL);
++      if (!skb) {
++              mif_info("%s: ERR! alloc_skb fail (tx_size:%d)\n",
++                      iod->name, tx_size);
++              return -ENOMEM;
++      }
++
++      /* store IPC link header*/
++      memcpy(skb_put(skb, headroom), frm.hdr, headroom);
++
++      /* store IPC message */
++      if (copy_from_user(skb_put(skb, count), data, count) != 0) {
++              if (skb)
++                      dev_kfree_skb_any(skb);
++              return -EFAULT;
++      }
++
++      if (iod->format == IPC_FMT) {
++              struct timespec epoch;
++              u8 *msg = (skb->data + headroom);
++#ifndef CONFIG_SAMSUNG_PRODUCT_SHIP
++              char str[MIF_MAX_STR_LEN];
++              snprintf(str, MIF_MAX_STR_LEN, "%s: RL2MIF", iod->mc->name);
++              pr_ipc(str, msg, (count > 16 ? 16 : count));
++#endif
++              getnstimeofday(&epoch);
++              mif_time_log(iod->mc->msd, epoch, NULL, 0);
++              mif_ipc_log(MIF_IPC_RL2AP, iod->mc->msd, msg, count);
++      }
++
++      /* store padding */
++      if (tailroom)
++              skb_put(skb, tailroom);
++
++      /* send data with sk_buff, link device will put sk_buff
++       * into the specific sk_buff_q and run work-q to send data
++       */
++      skbpriv(skb)->iod = iod;
++      skbpriv(skb)->ld = ld;
++
++      ret = ld->send(ld, iod, skb);
++      if (ret < 0) {
++              mif_info("%s: ERR! ld->send fail (err %d)\n", iod->name, ret);
++              return ret;
++      }
++
++      if (ret != tx_size)
++              mif_info("%s: wrong tx size (count:%d tx_size:%d ret:%d)\n",
++                      iod->name, count, tx_size, ret);
++
++      return count;
++}
++
++static ssize_t misc_read(struct file *filp, char *buf, size_t count,
++                      loff_t *fpos)
++{
++      struct io_device *iod = (struct io_device *)filp->private_data;
++      struct sk_buff_head *rxq = &iod->sk_rx_q;
++      struct sk_buff *skb;
++      int copied = 0;
++
++      skb = skb_dequeue(rxq);
++      if (!skb) {
++              mif_info("%s: ERR! no data in rxq\n", iod->name);
++              return 0;
++      }
++
++      if (iod->format == IPC_FMT) {
++              struct timespec epoch;
++#ifndef CONFIG_SAMSUNG_PRODUCT_SHIP
++              char str[MIF_MAX_STR_LEN];
++              snprintf(str, MIF_MAX_STR_LEN, "%s: MIF2RL", iod->mc->name);
++              pr_ipc(str, skb->data, (skb->len > 16 ? 16 : skb->len));
++#endif
++              getnstimeofday(&epoch);
++              mif_time_log(iod->mc->msd, epoch, NULL, 0);
++              mif_ipc_log(MIF_IPC_AP2RL, iod->mc->msd, skb->data, skb->len);
++      }
++
++      copied = skb->len > count ? count : skb->len;
++
++      if (copy_to_user(buf, skb->data, copied)) {
++              mif_info("%s: ERR! copy_to_user fail\n", iod->name);
++              dev_kfree_skb_any(skb);
++              return -EFAULT;
++      }
++
++      mif_debug("%s: data:%d copied:%d qlen:%d\n",
++              iod->name, skb->len, copied, rxq->qlen);
++
++      if (skb->len > count) {
++              skb_pull(skb, count);
++              skb_queue_head(rxq, skb);
++      } else {
++              dev_kfree_skb_any(skb);
++      }
++
++      return copied;
++}
++
++#ifdef CONFIG_LINK_DEVICE_C2C
++static int misc_mmap(struct file *filp, struct vm_area_struct *vma)
++{
++      int r = 0;
++      unsigned long size = 0;
++      unsigned long pfn = 0;
++      unsigned long offset = 0;
++      struct io_device *iod = (struct io_device *)filp->private_data;
++
++      if (!vma)
++              return -EFAULT;
++
++      size = vma->vm_end - vma->vm_start;
++      offset = vma->vm_pgoff << PAGE_SHIFT;
++      if (offset + size > (C2C_CP_RGN_SIZE + C2C_SH_RGN_SIZE)) {
++              mif_info("ERR: offset + size > C2C_CP_RGN_SIZE\n");
++              return -EINVAL;
++      }
++
++      /* Set the noncacheable property to the region */
++      vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
++      vma->vm_flags |= VM_RESERVED | VM_IO;
++
++      pfn = __phys_to_pfn(C2C_CP_RGN_ADDR + offset);
++      r = remap_pfn_range(vma, vma->vm_start, pfn, size, vma->vm_page_prot);
++      if (r) {
++              mif_info("ERR: Failed in remap_pfn_range()!!!\n");
++              return -EAGAIN;
++      }
++
++      mif_info("%s: VA = 0x%08lx, offset = 0x%lx, size = %lu\n",
++              iod->name, vma->vm_start, offset, size);
++
++      return 0;
++}
++#endif
++
++static const struct file_operations misc_io_fops = {
++      .owner = THIS_MODULE,
++      .open = misc_open,
++      .release = misc_release,
++      .poll = misc_poll,
++      .unlocked_ioctl = misc_ioctl,
++      .write = misc_write,
++      .read = misc_read,
++#ifdef CONFIG_LINK_DEVICE_C2C
++      .mmap = misc_mmap,
++#endif
++};
++
++static int vnet_open(struct net_device *ndev)
++{
++      struct vnet *vnet = netdev_priv(ndev);
++
++      mif_err("%s\n", vnet->iod->name);
++
++      netif_start_queue(ndev);
++      atomic_inc(&vnet->iod->opened);
++      return 0;
++}
++
++static int vnet_stop(struct net_device *ndev)
++{
++      struct vnet *vnet = netdev_priv(ndev);
++
++      mif_err("%s\n", vnet->iod->name);
++
++      atomic_dec(&vnet->iod->opened);
++      netif_stop_queue(ndev);
++      skb_queue_purge(&vnet->iod->sk_rx_q);
++      return 0;
++}
++
++static int vnet_xmit(struct sk_buff *skb, struct net_device *ndev)
++{
++      struct vnet *vnet = netdev_priv(ndev);
++      struct io_device *iod = vnet->iod;
++      struct link_device *ld = get_current_link(iod);
++      struct sk_buff *skb_new;
++      int ret;
++      unsigned headroom = 0;
++      unsigned tailroom = 0;
++      unsigned long tx_bytes = skb->len;
++      struct iphdr *ip_header = NULL;
++      struct sipc5_frame_data frm;
++
++      /* When use `handover' with Network Bridge,
++       * user -> bridge device(rmnet0) -> real rmnet(xxxx_rmnet0) -> here.
++       * bridge device is ethernet device unlike xxxx_rmnet(net device).
++       * We remove the an ethernet header of skb before using skb->len,
++       * because bridge device added an ethernet header to skb.
++       */
++      if (iod->use_handover) {
++              if (iod->id >= PS_DATA_CH_0 && iod->id <= PS_DATA_CH_LAST)
++                      skb_pull(skb, sizeof(struct ethhdr));
++      }
++
++      headroom = tx_build_link_header(&frm, iod, ld, skb->len);
++
++      /* ip loop-back */
++      ip_header = (struct iphdr *)skb->data;
++      if (iod->msd->loopback_ipaddr &&
++              ip_header->daddr == iod->msd->loopback_ipaddr) {
++              swap(ip_header->saddr, ip_header->daddr);
++              frm.ch_id = DATA_LOOPBACK_CHANNEL;
++              frm.hdr[SIPC5_CH_ID_OFFSET] = DATA_LOOPBACK_CHANNEL;
++      }
++
++      if (ld->aligned)
++              tailroom = sipc5_calc_padding_size(frm.len);
++
++      if (skb_headroom(skb) < headroom || skb_tailroom(skb) < tailroom) {
++              mif_debug("%s: skb_copy_expand needed\n", iod->name);
++              skb_new = skb_copy_expand(skb, headroom, tailroom, GFP_ATOMIC);
++              /* skb_copy_expand success or not, free old skb from caller */
++              dev_kfree_skb_any(skb);
++              if (!skb_new) {
++                      mif_info("%s: ERR! skb_copy_expand fail\n", iod->name);
++                      return NETDEV_TX_BUSY;
++              }
++      } else {
++              skb_new = skb;
++      }
++
++      memcpy(skb_push(skb_new, headroom), frm.hdr, headroom);
++      if (tailroom)
++              skb_put(skb_new, tailroom);
++
++      skbpriv(skb_new)->iod = iod;
++      skbpriv(skb_new)->ld = ld;
++
++      ret = ld->send(ld, iod, skb_new);
++      if (ret < 0) {
++              netif_stop_queue(ndev);
++              mif_info("%s: ERR! ld->send fail (err %d)\n", iod->name, ret);
++              return NETDEV_TX_BUSY;
++      }
++
++      ndev->stats.tx_packets++;
++      ndev->stats.tx_bytes += tx_bytes;
++
++      return NETDEV_TX_OK;
++}
++
++static struct net_device_ops vnet_ops = {
++      .ndo_open = vnet_open,
++      .ndo_stop = vnet_stop,
++      .ndo_start_xmit = vnet_xmit,
++};
++
++static void vnet_setup(struct net_device *ndev)
++{
++      ndev->netdev_ops = &vnet_ops;
++      ndev->type = ARPHRD_PPP;
++      ndev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
++      ndev->addr_len = 0;
++      ndev->hard_header_len = 0;
++      ndev->tx_queue_len = 1000;
++      ndev->mtu = ETH_DATA_LEN;
++      ndev->watchdog_timeo = 5 * HZ;
++}
++
++static void vnet_setup_ether(struct net_device *ndev)
++{
++      ndev->netdev_ops = &vnet_ops;
++      ndev->type = ARPHRD_ETHER;
++      ndev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST | IFF_SLAVE;
++      ndev->addr_len = ETH_ALEN;
++      random_ether_addr(ndev->dev_addr);
++      ndev->hard_header_len = 0;
++      ndev->tx_queue_len = 1000;
++      ndev->mtu = ETH_DATA_LEN;
++      ndev->watchdog_timeo = 5 * HZ;
++}
++
++int sipc5_init_io_device(struct io_device *iod)
++{
++      int ret = 0;
++      struct vnet *vnet;
++
++      /* Get modem state from modem control device */
++      iod->modem_state_changed = io_dev_modem_state_changed;
++
++      iod->sim_state_changed = io_dev_sim_state_changed;
++
++      /* Get data from link device */
++      mif_debug("%s: SIPC version = %d\n", iod->name, iod->ipc_version);
++      iod->recv = io_dev_recv_data_from_link_dev;
++      iod->recv_skb = io_dev_recv_skb_from_link_dev;
++
++      /* Register misc or net device */
++      switch (iod->io_typ) {
++      case IODEV_MISC:
++              init_waitqueue_head(&iod->wq);
++              skb_queue_head_init(&iod->sk_rx_q);
++
++              iod->miscdev.minor = MISC_DYNAMIC_MINOR;
++              iod->miscdev.name = iod->name;
++              iod->miscdev.fops = &misc_io_fops;
++
++              ret = misc_register(&iod->miscdev);
++              if (ret)
++                      mif_info("%s: ERR! misc_register failed\n", iod->name);
++
++              break;
++
++      case IODEV_NET:
++              skb_queue_head_init(&iod->sk_rx_q);
++              if (iod->use_handover)
++                      iod->ndev = alloc_netdev(0, iod->name,
++                                              vnet_setup_ether);
++              else
++                      iod->ndev = alloc_netdev(0, iod->name, vnet_setup);
++
++              if (!iod->ndev) {
++                      mif_info("%s: ERR! alloc_netdev fail\n", iod->name);
++                      return -ENOMEM;
++              }
++
++              ret = register_netdev(iod->ndev);
++              if (ret) {
++                      mif_info("%s: ERR! register_netdev fail\n", iod->name);
++                      free_netdev(iod->ndev);
++              }
++
++              mif_debug("iod 0x%p\n", iod);
++              vnet = netdev_priv(iod->ndev);
++              mif_debug("vnet 0x%p\n", vnet);
++              vnet->iod = iod;
++
++              break;
++
++      case IODEV_DUMMY:
++              skb_queue_head_init(&iod->sk_rx_q);
++
++              iod->miscdev.minor = MISC_DYNAMIC_MINOR;
++              iod->miscdev.name = iod->name;
++              iod->miscdev.fops = &misc_io_fops;
++
++              ret = misc_register(&iod->miscdev);
++              if (ret)
++                      mif_info("%s: ERR! misc_register fail\n", iod->name);
++              ret = device_create_file(iod->miscdev.this_device,
++                                      &attr_waketime);
++              if (ret)
++                      mif_info("%s: ERR! device_create_file fail\n",
++                              iod->name);
++              ret = device_create_file(iod->miscdev.this_device,
++                              &attr_loopback);
++              if (ret)
++                      mif_err("failed to create `loopback file' : %s\n",
++                                      iod->name);
++              ret = device_create_file(iod->miscdev.this_device,
++                              &attr_txlink);
++              if (ret)
++                      mif_err("failed to create `txlink file' : %s\n",
++                                      iod->name);
++              break;
++
++      default:
++              mif_info("%s: ERR! wrong io_type %d\n", iod->name, iod->io_typ);
++              return -EINVAL;
++      }
++
++      return ret;
++}
++
+diff --git a/drivers/misc/modem_if/sipc5_modem.c b/drivers/misc/modem_if/sipc5_modem.c
+new file mode 100644
+index 0000000..9898751
+--- /dev/null
++++ b/drivers/misc/modem_if/sipc5_modem.c
+@@ -0,0 +1,384 @@
++/* linux/drivers/modem/modem.c
++ *
++ * Copyright (C) 2010 Google, Inc.
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/interrupt.h>
++#include <linux/platform_device.h>
++#include <linux/miscdevice.h>
++#include <linux/if_arp.h>
++
++#include <linux/uaccess.h>
++#include <linux/fs.h>
++#include <linux/io.h>
++#include <linux/wait.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/mutex.h>
++#include <linux/irq.h>
++#include <linux/gpio.h>
++#include <linux/delay.h>
++#include <linux/wakelock.h>
++
++#include <linux/platform_data/modem.h>
++#include "modem_prj.h"
++#include "modem_variation.h"
++#include "modem_utils.h"
++
++#define FMT_WAKE_TIME   (HZ/2)
++#define RAW_WAKE_TIME   (HZ*6)
++
++static struct modem_shared *create_modem_shared_data(void)
++{
++      struct modem_shared *msd;
++      int size = MAX_MIF_BUFF_SIZE;
++
++      msd = kzalloc(sizeof(struct modem_shared), GFP_KERNEL);
++      if (!msd)
++              return NULL;
++
++      /* initialize link device list */
++      INIT_LIST_HEAD(&msd->link_dev_list);
++
++      /* initialize tree of io devices */
++      msd->iodevs_tree_chan = RB_ROOT;
++      msd->iodevs_tree_fmt = RB_ROOT;
++
++      msd->storage.cnt = 0;
++      msd->storage.addr = kzalloc(MAX_MIF_BUFF_SIZE +
++              (MAX_MIF_SEPA_SIZE * 2), GFP_KERNEL);
++      if (!msd->storage.addr) {
++              mif_err("IPC logger buff alloc failed!!\n");
++              return NULL;
++      }
++      memset(msd->storage.addr, 0, size + (MAX_MIF_SEPA_SIZE * 2));
++      memcpy(msd->storage.addr, MIF_SEPARATOR, MAX_MIF_SEPA_SIZE);
++      msd->storage.addr += MAX_MIF_SEPA_SIZE;
++      memcpy(msd->storage.addr, &size, MAX_MIF_SEPA_SIZE);
++      msd->storage.addr += MAX_MIF_SEPA_SIZE;
++      spin_lock_init(&msd->lock);
++
++      return msd;
++}
++
++static struct modem_ctl *create_modemctl_device(struct platform_device *pdev,
++              struct modem_shared *msd)
++{
++      int ret = 0;
++      struct modem_data *pdata;
++      struct modem_ctl *modemctl;
++      struct device *dev = &pdev->dev;
++
++      /* create modem control device */
++      modemctl = kzalloc(sizeof(struct modem_ctl), GFP_KERNEL);
++      if (!modemctl)
++              return NULL;
++
++      modemctl->msd = msd;
++      modemctl->dev = dev;
++      modemctl->phone_state = STATE_OFFLINE;
++
++      pdata = pdev->dev.platform_data;
++      modemctl->mdm_data = pdata;
++      modemctl->name = pdata->name;
++
++      /* init modemctl device for getting modemctl operations */
++      ret = call_modem_init_func(modemctl, pdata);
++      if (ret) {
++              kfree(modemctl);
++              return NULL;
++      }
++
++      mif_info("%s is created!!!\n", pdata->name);
++
++      return modemctl;
++}
++
++static struct io_device *create_io_device(struct modem_io_t *io_t,
++              struct modem_shared *msd, struct modem_ctl *modemctl,
++              struct modem_data *pdata)
++{
++      int ret = 0;
++      struct io_device *iod = NULL;
++
++      iod = kzalloc(sizeof(struct io_device), GFP_KERNEL);
++      if (!iod) {
++              mif_err("iod == NULL\n");
++              return NULL;
++      }
++
++      rb_init_node(&iod->node_chan);
++      rb_init_node(&iod->node_fmt);
++
++      iod->name = io_t->name;
++      iod->id = io_t->id;
++      iod->format = io_t->format;
++      iod->io_typ = io_t->io_type;
++      iod->link_types = io_t->links;
++      iod->net_typ = pdata->modem_net;
++      iod->use_handover = pdata->use_handover;
++      iod->ipc_version = pdata->ipc_version;
++      atomic_set(&iod->opened, 0);
++
++      /* link between io device and modem control */
++      iod->mc = modemctl;
++      if (iod->format == IPC_FMT)
++              modemctl->iod = iod;
++      if (iod->format == IPC_BOOT) {
++              modemctl->bootd = iod;
++              mif_info("Bood device = %s\n", iod->name);
++      }
++
++      /* link between io device and modem shared */
++      iod->msd = msd;
++
++      /* add iod to rb_tree */
++      if (iod->format != IPC_RAW)
++              insert_iod_with_format(msd, iod->format, iod);
++
++      if (sipc5_is_not_reserved_channel(iod->id))
++              insert_iod_with_channel(msd, iod->id, iod);
++
++      /* register misc device or net device */
++      ret = sipc5_init_io_device(iod);
++      if (ret) {
++              kfree(iod);
++              mif_err("sipc5_init_io_device fail (%d)\n", ret);
++              return NULL;
++      }
++
++      mif_debug("%s is created!!!\n", iod->name);
++      return iod;
++}
++
++static int attach_devices(struct io_device *iod, enum modem_link tx_link)
++{
++      struct modem_shared *msd = iod->msd;
++      struct link_device *ld;
++      unsigned ch;
++
++      /* find link type for this io device */
++      list_for_each_entry(ld, &msd->link_dev_list, list) {
++              if (IS_CONNECTED(iod, ld)) {
++                      /* The count 1 bits of iod->link_types is count
++                       * of link devices of this iod.
++                       * If use one link device,
++                       * or, 2+ link devices and this link is tx_link,
++                       * set iod's link device with ld
++                       */
++                      if ((countbits(iod->link_types) <= 1) ||
++                                      (tx_link == ld->link_type)) {
++                              mif_debug("set %s->%s\n", iod->name, ld->name);
++                              set_current_link(iod, ld);
++                      }
++              }
++      }
++
++      /* if use rx dynamic switch, set tx_link at modem_io_t of
++       * board-*-modems.c
++       */
++      if (!get_current_link(iod)) {
++              mif_err("%s->link == NULL\n", iod->name);
++              BUG();
++      }
++
++      switch (iod->format) {
++      case IPC_FMT:
++              wake_lock_init(&iod->wakelock, WAKE_LOCK_SUSPEND, iod->name);
++              iod->waketime = FMT_WAKE_TIME;
++              break;
++
++      case IPC_RAW:
++              wake_lock_init(&iod->wakelock, WAKE_LOCK_SUSPEND, iod->name);
++              iod->waketime = RAW_WAKE_TIME;
++              break;
++
++      case IPC_RFS:
++              wake_lock_init(&iod->wakelock, WAKE_LOCK_SUSPEND, iod->name);
++              iod->waketime = RAW_WAKE_TIME;
++              break;
++
++      case IPC_MULTI_RAW:
++              wake_lock_init(&iod->wakelock, WAKE_LOCK_SUSPEND, iod->name);
++              iod->waketime = RAW_WAKE_TIME;
++              break;
++
++      case IPC_BOOT:
++              wake_lock_init(&iod->wakelock, WAKE_LOCK_SUSPEND, iod->name);
++              iod->waketime = RAW_WAKE_TIME;
++              break;
++
++      default:
++              break;
++      }
++
++      return 0;
++}
++
++static int __devinit modem_probe(struct platform_device *pdev)
++{
++      int i;
++      struct modem_data *pdata = pdev->dev.platform_data;
++      struct modem_shared *msd = NULL;
++      struct modem_ctl *modemctl = NULL;
++      struct io_device *iod[pdata->num_iodevs];
++      struct link_device *ld;
++
++      mif_err("%s\n", pdev->name);
++      memset(iod, 0, sizeof(iod));
++
++      msd = create_modem_shared_data();
++      if (!msd) {
++              mif_err("msd == NULL\n");
++              goto err_free_modemctl;
++      }
++
++      modemctl = create_modemctl_device(pdev, msd);
++      if (!modemctl) {
++              mif_err("modemctl == NULL\n");
++              goto err_free_modemctl;
++      }
++
++      /* create link device */
++      /* support multi-link device */
++      for (i = 0; i < LINKDEV_MAX ; i++) {
++              /* find matching link type */
++              if (pdata->link_types & LINKTYPE(i)) {
++                      ld = call_link_init_func(pdev, i);
++                      if (!ld)
++                              goto err_free_modemctl;
++
++                      mif_err("link created: %s\n", ld->name);
++                      ld->link_type = i;
++                      ld->mc = modemctl;
++                      ld->msd = msd;
++                      list_add(&ld->list, &msd->link_dev_list);
++              }
++      }
++
++      /* create io deivces and connect to modemctl device */
++      for (i = 0; i < pdata->num_iodevs; i++) {
++              iod[i] = create_io_device(&pdata->iodevs[i], msd, modemctl,
++                              pdata);
++              if (!iod[i]) {
++                      mif_err("iod[%d] == NULL\n", i);
++                      goto err_free_modemctl;
++              }
++
++              attach_devices(iod[i], pdata->iodevs[i].tx_link);
++      }
++
++      platform_set_drvdata(pdev, modemctl);
++
++      mif_err("Complete!!!\n");
++
++      return 0;
++
++err_free_modemctl:
++      for (i = 0; i < pdata->num_iodevs; i++)
++              if (iod[i] != NULL)
++                      kfree(iod[i]);
++
++      if (modemctl != NULL)
++              kfree(modemctl);
++
++      if (msd != NULL)
++              kfree(msd);
++
++      return -ENOMEM;
++}
++
++static void modem_shutdown(struct platform_device *pdev)
++{
++      struct device *dev = &pdev->dev;
++      struct modem_ctl *mc = dev_get_drvdata(dev);
++      struct utc_time utc;
++
++      mc->ops.modem_off(mc);
++      mc->phone_state = STATE_OFFLINE;
++
++      get_utc_time(&utc);
++      mif_info("%s: at [%02d:%02d:%02d.%03d]\n",
++              mc->name, utc.hour, utc.min, utc.sec, utc.msec);
++}
++
++static int modem_suspend(struct device *pdev)
++{
++#ifndef CONFIG_SAMSUNG_PRODUCT_SHIP
++      struct utc_time utc;
++#endif
++
++#ifndef CONFIG_LINK_DEVICE_HSIC
++      struct modem_ctl *mc = dev_get_drvdata(pdev);
++
++      if (mc->gpio_pda_active) {
++              gpio_set_value(mc->gpio_pda_active, 0);
++#ifndef CONFIG_SAMSUNG_PRODUCT_SHIP
++              get_utc_time(&utc);
++              mif_info("%s: at [%02d:%02d:%02d.%03d]\n",
++                      mc->name, utc.hour, utc.min, utc.sec, utc.msec);
++#endif
++      }
++#endif
++
++      return 0;
++}
++
++static int modem_resume(struct device *pdev)
++{
++#ifndef CONFIG_SAMSUNG_PRODUCT_SHIP
++      struct utc_time utc;
++#endif
++
++#ifndef CONFIG_LINK_DEVICE_HSIC
++      struct modem_ctl *mc = dev_get_drvdata(pdev);
++
++      if (mc->gpio_pda_active) {
++              gpio_set_value(mc->gpio_pda_active, 1);
++#ifndef CONFIG_SAMSUNG_PRODUCT_SHIP
++              get_utc_time(&utc);
++              mif_info("%s: at [%02d:%02d:%02d.%03d]\n",
++                      mc->name, utc.hour, utc.min, utc.sec, utc.msec);
++#endif
++      }
++#endif
++
++      return 0;
++}
++
++static const struct dev_pm_ops modem_pm_ops = {
++      .suspend = modem_suspend,
++      .resume = modem_resume,
++};
++
++static struct platform_driver modem_driver = {
++      .probe = modem_probe,
++      .shutdown = modem_shutdown,
++      .driver = {
++              .name = "mif_sipc5",
++              .pm = &modem_pm_ops,
++      },
++};
++
++static int __init modem_init(void)
++{
++      return platform_driver_register(&modem_driver);
++}
++
++module_init(modem_init);
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("Samsung Modem Interface Driver");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0315-modem_if-Remove-linux-cma.h-use.patch b/patches.tizen/0315-modem_if-Remove-linux-cma.h-use.patch
new file mode 100644 (file)
index 0000000..323cec4
--- /dev/null
@@ -0,0 +1,30 @@
+From 38f9fdfc49f9cb6e6d62e10cfb00b3326ab0f2c5 Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Tue, 21 May 2013 17:32:17 +0200
+Subject: [PATCH 0315/1302] modem_if: Remove linux/cma.h use
+
+Remove linux/cma.h from modem_modemctl_device_xmm6262.c
+It wasn't used anyway and was included for linux/rbtree.h only.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/misc/modem_if/modem_modemctl_device_xmm6262.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/misc/modem_if/modem_modemctl_device_xmm6262.c b/drivers/misc/modem_if/modem_modemctl_device_xmm6262.c
+index e400046..311836c 100644
+--- a/drivers/misc/modem_if/modem_modemctl_device_xmm6262.c
++++ b/drivers/misc/modem_if/modem_modemctl_device_xmm6262.c
+@@ -22,7 +22,6 @@
+ #include <linux/gpio.h>
+ #include <linux/delay.h>
+ #include <linux/platform_device.h>
+-#include <linux/cma.h>
+ #include <plat/devs.h>
+ #include <linux/platform_data/modem.h>
+ #include "modem_prj.h"
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0316-modem_if-Add-modem.h-to-include-linux-platform_data.patch b/patches.tizen/0316-modem_if-Add-modem.h-to-include-linux-platform_data.patch
new file mode 100644 (file)
index 0000000..90bcde1
--- /dev/null
@@ -0,0 +1,355 @@
+From 85d24760a443e69db2163519c62af463d6253d94 Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Wed, 22 May 2013 14:31:10 +0200
+Subject: [PATCH 0316/1302] modem_if: Add modem.h to
+ include/linux/platform_data
+
+This file is needed by modem_if driver.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/platform_data/modem.h | 330 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 330 insertions(+)
+ create mode 100644 include/linux/platform_data/modem.h
+
+diff --git a/include/linux/platform_data/modem.h b/include/linux/platform_data/modem.h
+new file mode 100644
+index 0000000..8a83ed0
+--- /dev/null
++++ b/include/linux/platform_data/modem.h
+@@ -0,0 +1,330 @@
++/*
++ * Copyright (C) 2010 Google, Inc.
++ * Copyright (C) 2010 Samsung Electronics.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#ifndef __MODEM_IF_H__
++#define __MODEM_IF_H__
++
++enum modem_t {
++      IMC_XMM6260,
++      IMC_XMM6262,
++      VIA_CBP71,
++      VIA_CBP72,
++      SEC_CMC221,
++      QC_MDM6600,
++      QC_ESC6270,
++      DUMMY,
++      MAX_MODEM_TYPE
++};
++
++enum dev_format {
++      IPC_FMT,
++      IPC_RAW,
++      IPC_RFS,
++      IPC_CMD,
++      IPC_BOOT,
++      IPC_MULTI_RAW,
++      IPC_RAMDUMP,
++      MAX_DEV_FORMAT,
++};
++#define MAX_IPC_DEV   (IPC_RFS + 1)   /* FMT, RAW, RFS */
++#define MAX_SIPC5_DEV (IPC_RAW + 1)   /* FMT, RAW */
++
++enum modem_io {
++      IODEV_MISC,
++      IODEV_NET,
++      IODEV_DUMMY,
++};
++
++enum modem_link {
++      LINKDEV_UNDEFINED,
++      LINKDEV_MIPI,
++      LINKDEV_DPRAM,
++      LINKDEV_SPI,
++      LINKDEV_USB,
++      LINKDEV_HSIC,
++      LINKDEV_C2C,
++      LINKDEV_PLD,
++      LINKDEV_MAX,
++};
++#define LINKTYPE(modem_link) (1u << (modem_link))
++
++enum modem_network {
++      UMTS_NETWORK,
++      CDMA_NETWORK,
++      LTE_NETWORK,
++};
++
++enum sipc_ver {
++      NO_SIPC_VER = 0,
++      SIPC_VER_40 = 40,
++      SIPC_VER_41 = 41,
++      SIPC_VER_42 = 42,
++      SIPC_VER_50 = 50,
++      MAX_SIPC_VER,
++};
++
++/**
++ * struct modem_io_t - declaration for io_device
++ * @name:     device name
++ * @id:               for SIPC4, contains format & channel information
++ *            (id & 11100000b)>>5 = format  (eg, 0=FMT, 1=RAW, 2=RFS)
++ *            (id & 00011111b)    = channel (valid only if format is RAW)
++ *            for SIPC5, contains only 8-bit channel ID
++ * @format:   device format
++ * @io_type:  type of this io_device
++ * @links:    list of link_devices to use this io_device
++ *            for example, if you want to use DPRAM and USB in an io_device.
++ *            .links = LINKTYPE(LINKDEV_DPRAM) | LINKTYPE(LINKDEV_USB)
++ * @tx_link:  when you use 2+ link_devices, set the link for TX.
++ *            If define multiple link_devices in @links,
++ *            you can receive data from them. But, cannot send data to all.
++ *            TX is only one link_device.
++ * @app:      the name of the application that will use this IO device
++ *
++ * This structure is used in board-*-modem.c
++ */
++struct modem_io_t {
++      char *name;
++      int   id;
++      enum dev_format format;
++      enum modem_io io_type;
++      enum modem_link links;
++      enum modem_link tx_link;
++      char *app;
++};
++
++struct modemlink_pm_data {
++      char *name;
++      /* link power contol 2 types : pin & regulator control */
++      int (*link_ldo_enable)(bool);
++      unsigned gpio_link_enable;
++      unsigned gpio_link_active;
++      unsigned gpio_link_hostwake;
++      unsigned gpio_link_slavewake;
++      int (*link_reconnect)(void);
++
++      /* usb hub only */
++      int (*port_enable)(int, int);
++      int (*hub_standby)(void *);
++      void *hub_pm_data;
++      bool has_usbhub;
++
++      /* cpu/bus frequency lock */
++      atomic_t freqlock;
++      int (*freq_lock)(struct device *dev);
++      int (*freq_unlock)(struct device *dev);
++
++      int autosuspend_delay_ms; /* if zero, the default value is used */
++      void (*ehci_reg_dump)(struct device *);
++};
++
++struct modemlink_pm_link_activectl {
++      int gpio_initialized;
++      int gpio_request_host_active;
++};
++
++#define RES_CP_ACTIVE_IRQ_ID  0
++#define RES_DPRAM_MEM_ID      1
++#define RES_DPRAM_IRQ_ID      2
++#define RES_DPRAM_SFR_ID      3
++
++#define STR_CP_ACTIVE_IRQ     "cp_active_irq"
++#define STR_DPRAM_BASE                "dpram_base"
++#define STR_DPRAM_IRQ         "dpram_irq"
++#define STR_DPRAM_SFR_BASE    "dpram_sfr_base"
++
++enum dpram_type {
++      EXT_DPRAM,
++      AP_IDPRAM,
++      CP_IDPRAM,
++      SHM_DPRAM,
++      MAX_DPRAM_TYPE
++};
++
++#define DPRAM_SIZE_8KB                0x02000
++#define DPRAM_SIZE_16KB               0x04000
++#define DPRAM_SIZE_32KB               0x08000
++#define DPRAM_SIZE_64KB               0x10000
++#define DPRAM_SIZE_128KB      0x20000
++
++enum dpram_speed {
++      DPRAM_SPEED_LOW,
++      DPRAM_SPEED_MID,
++      DPRAM_SPEED_HIGH,
++      MAX_DPRAM_SPEED
++};
++
++struct dpram_circ {
++      u16 __iomem *head;
++      u16 __iomem *tail;
++      u8  __iomem *buff;
++      u32          size;
++};
++
++struct dpram_ipc_device {
++      char name[16];
++      int  id;
++
++      struct dpram_circ txq;
++      struct dpram_circ rxq;
++
++      u16 mask_req_ack;
++      u16 mask_res_ack;
++      u16 mask_send;
++};
++
++struct dpram_ipc_map {
++#if defined(CONFIG_LINK_DEVICE_PLD)
++      u16 __iomem *mbx_ap2cp;
++      u16 __iomem *magic_ap2cp;
++      u16 __iomem *access_ap2cp;
++
++      u16 __iomem *mbx_cp2ap;
++      u16 __iomem *magic_cp2ap;
++      u16 __iomem *access_cp2ap;
++
++      struct dpram_ipc_device dev[MAX_IPC_DEV];
++
++      u16 __iomem *address_buffer;
++#else
++      u16 __iomem *magic;
++      u16 __iomem *access;
++
++      struct dpram_ipc_device dev[MAX_IPC_DEV];
++
++      u16 __iomem *mbx_cp2ap;
++      u16 __iomem *mbx_ap2cp;
++#endif
++};
++
++struct modemlink_dpram_control {
++      enum dpram_type dp_type;        /* DPRAM type */
++      int aligned;                    /* Aligned access is required */
++      bool disabled;                  /* Disabled during phone booting */
++      u8 __iomem *dp_base;
++      u32 dp_size;
++
++      int dpram_irq;
++      unsigned long dpram_irq_flags;
++
++      int max_ipc_dev;
++      struct dpram_ipc_map *ipc_map;
++
++      unsigned boot_size_offset;
++      unsigned boot_tag_offset;
++      unsigned boot_count_offset;
++      unsigned max_boot_frame_size;
++
++      void (*setup_speed)(enum dpram_speed);
++};
++
++/* platform data */
++struct modem_data {
++      char *name;
++
++      unsigned gpio_cp_on;
++      unsigned gpio_cp_off;
++      unsigned gpio_reset_req_n;
++      unsigned gpio_cp_reset;
++      unsigned gpio_pda_active;
++      unsigned gpio_phone_active;
++      unsigned gpio_cp_dump_int;
++      unsigned gpio_ap_dump_int;
++      unsigned gpio_flm_uart_sel;
++#if defined(CONFIG_MACH_M0_CTC)
++      unsigned gpio_flm_uart_sel_rev06;
++      unsigned gpio_host_wakeup;
++#endif
++      unsigned gpio_cp_warm_reset;
++      unsigned gpio_sim_detect;
++      unsigned gpio_dpram_int;
++
++#ifdef CONFIG_LINK_DEVICE_PLD
++      unsigned gpio_fpga1_creset;
++      unsigned gpio_fpga1_cdone;
++      unsigned gpio_fpga1_rst_n;
++      unsigned gpio_fpga1_cs_n;
++
++      unsigned gpio_fpga2_creset;
++      unsigned gpio_fpga2_cdone;
++      unsigned gpio_fpga2_rst_n;
++      unsigned gpio_fpga2_cs_n;
++#endif
++
++#ifdef CONFIG_LTE_MODEM_CMC221
++      unsigned gpio_dpram_status;
++      unsigned gpio_dpram_wakeup;
++      unsigned gpio_slave_wakeup;
++      unsigned gpio_host_active;
++      unsigned gpio_host_wakeup;
++      int      irq_host_wakeup;
++#endif
++#ifdef CONFIG_MACH_U1_KOR_LGT
++      unsigned gpio_cp_reset_msm;
++      unsigned gpio_boot_sw_sel;
++      void (*vbus_on)(void);
++      void (*vbus_off)(void);
++      struct regulator *cp_vbus;
++#endif
++#ifdef CONFIG_SEC_MODEM_IRON_TD
++      unsigned gpio_cp_uart_sel;
++#endif
++      /* Switch with 2 links in a modem */
++      unsigned gpio_dynamic_switching;
++
++      /* Modem component */
++      enum modem_network  modem_net;
++      enum modem_t        modem_type;
++      enum modem_link     link_types;
++      char               *link_name;
++
++      /* Link to DPRAM control functions dependent on each platform */
++      struct modemlink_dpram_control *dpram_ctl;
++
++      /* SIPC version */
++      enum sipc_ver ipc_version;
++
++      /* Information of IO devices */
++      unsigned            num_iodevs;
++      struct modem_io_t  *iodevs;
++
++      /* Modem link PM support */
++      struct modemlink_pm_data *link_pm_data;
++
++      void (*gpio_revers_bias_clear)(void);
++      void (*gpio_revers_bias_restore)(void);
++
++      /* Handover with 2+ modems */
++      bool use_handover;
++
++      /* Debugging option */
++      bool use_mif_log;
++      /* SIM Detect polarity */
++      bool sim_polarity;
++};
++
++#define LOG_TAG "mif: "
++
++#define mif_err(fmt, ...) \
++      pr_err(LOG_TAG "%s: " pr_fmt(fmt), __func__, ##__VA_ARGS__)
++#define mif_debug(fmt, ...) \
++      pr_debug(LOG_TAG "%s: " pr_fmt(fmt), __func__, ##__VA_ARGS__)
++#define mif_info(fmt, ...) \
++      pr_info(LOG_TAG "%s: " pr_fmt(fmt), __func__, ##__VA_ARGS__)
++#define mif_trace(fmt, ...) \
++      printk(KERN_DEBUG "mif: %s: %d: called(%pF): " fmt, \
++              __func__, __LINE__, __builtin_return_address(0), ##__VA_ARGS__)
++
++#endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0317-modem_if-Modification-of-the-modem-driver-to-compile.patch b/patches.tizen/0317-modem_if-Modification-of-the-modem-driver-to-compile.patch
new file mode 100644 (file)
index 0000000..e1ef6a3
--- /dev/null
@@ -0,0 +1,120 @@
+From b91c85372c805dc7308fd0609369155407637de7 Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Tue, 21 May 2013 18:54:09 +0200
+Subject: [PATCH 0317/1302] modem_if: Modification of the modem driver to
+ compile on the 3.8 kernel
+
+The modem_if driver code was taken from 3.0 kernel and did not compile
+on 3.8. These changes are necessary to make the driver work.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/misc/modem_if/modem_link_device_hsic.c       | 4 ++--
+ drivers/misc/modem_if/modem_net_flowcontrol_device.c | 4 ++--
+ drivers/misc/modem_if/sipc4_modem.c                  | 7 ++++---
+ drivers/misc/modem_if/sipc5_modem.c                  | 7 ++++---
+ 4 files changed, 12 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/misc/modem_if/modem_link_device_hsic.c b/drivers/misc/modem_if/modem_link_device_hsic.c
+index bb8066a..81c732e 100644
+--- a/drivers/misc/modem_if/modem_link_device_hsic.c
++++ b/drivers/misc/modem_if/modem_link_device_hsic.c
+@@ -1251,7 +1251,7 @@ static int if_usb_set_pipe(struct usb_link_device *usb_ld,
+       return 0;
+ }
+-static int __devinit if_usb_probe(struct usb_interface *intf,
++static int if_usb_probe(struct usb_interface *intf,
+                                       const struct usb_device_id *id)
+ {
+       int err;
+@@ -1444,7 +1444,7 @@ MODULE_DEVICE_TABLE(usb, if_usb_ids);
+ static struct usb_driver if_usb_driver = {
+       .name =         "cdc_modem",
+-      .probe =                if_usb_probe,
++      .probe =        if_usb_probe,
+       .disconnect =   if_usb_disconnect,
+       .id_table =     if_usb_ids,
+       .suspend =      if_usb_suspend,
+diff --git a/drivers/misc/modem_if/modem_net_flowcontrol_device.c b/drivers/misc/modem_if/modem_net_flowcontrol_device.c
+index 164f471..4e8b314 100644
+--- a/drivers/misc/modem_if/modem_net_flowcontrol_device.c
++++ b/drivers/misc/modem_if/modem_net_flowcontrol_device.c
+@@ -113,5 +113,5 @@ static int __init modem_net_flowcontrol_device_init(void)
+ module_init(modem_net_flowcontrol_device_init);
+-MODULE_LICENSE("GPL");
+-MODULE_DESCRIPTION("Samsung Modem IF Net Flowcontrol Driver");
++//MODULE_LICENSE("GPL");
++//MODULE_DESCRIPTION("Samsung Modem IF Net Flowcontrol Driver");
+diff --git a/drivers/misc/modem_if/sipc4_modem.c b/drivers/misc/modem_if/sipc4_modem.c
+index 58b3faf..65d9444 100644
+--- a/drivers/misc/modem_if/sipc4_modem.c
++++ b/drivers/misc/modem_if/sipc4_modem.c
+@@ -33,6 +33,7 @@
+ #ifdef CONFIG_HAS_WAKELOCK
+ #include <linux/wakelock.h>
+ #endif
++#include <linux/rbtree.h>
+ #include <linux/platform_data/modem.h>
+ #include "modem_prj.h"
+@@ -119,8 +120,8 @@ static struct io_device *create_io_device(struct modem_io_t *io_t,
+               return NULL;
+       }
+-      rb_init_node(&iod->node_chan);
+-      rb_init_node(&iod->node_fmt);
++      RB_CLEAR_NODE(&iod->node_chan);
++      RB_CLEAR_NODE(&iod->node_fmt);
+       iod->name = io_t->name;
+       iod->id = io_t->id;
+@@ -242,7 +243,7 @@ static int attach_devices(struct io_device *iod, enum modem_link tx_link)
+       return 0;
+ }
+-static int __devinit modem_probe(struct platform_device *pdev)
++static int modem_probe(struct platform_device *pdev)
+ {
+       int i;
+       struct modem_data *pdata = pdev->dev.platform_data;
+diff --git a/drivers/misc/modem_if/sipc5_modem.c b/drivers/misc/modem_if/sipc5_modem.c
+index 9898751..ccfad5f 100644
+--- a/drivers/misc/modem_if/sipc5_modem.c
++++ b/drivers/misc/modem_if/sipc5_modem.c
+@@ -32,6 +32,7 @@
+ #include <linux/gpio.h>
+ #include <linux/delay.h>
+ #include <linux/wakelock.h>
++#include <linux/rbtree.h>
+ #include <linux/platform_data/modem.h>
+ #include "modem_prj.h"
+@@ -120,8 +121,8 @@ static struct io_device *create_io_device(struct modem_io_t *io_t,
+               return NULL;
+       }
+-      rb_init_node(&iod->node_chan);
+-      rb_init_node(&iod->node_fmt);
++      RB_CLEAR_NODE(&iod->node_chan);
++      RB_CLEAR_NODE(&iod->node_fmt);
+       iod->name = io_t->name;
+       iod->id = io_t->id;
+@@ -228,7 +229,7 @@ static int attach_devices(struct io_device *iod, enum modem_link tx_link)
+       return 0;
+ }
+-static int __devinit modem_probe(struct platform_device *pdev)
++static int modem_probe(struct platform_device *pdev)
+ {
+       int i;
+       struct modem_data *pdata = pdev->dev.platform_data;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0318-modem_if-device_tree-Add-modem_if-to-exynos4412-slp_.patch b/patches.tizen/0318-modem_if-device_tree-Add-modem_if-to-exynos4412-slp_.patch
new file mode 100644 (file)
index 0000000..942f2ea
--- /dev/null
@@ -0,0 +1,69 @@
+From 16907b2942fc12f4630e56a60943d752bee28dae Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Wed, 22 May 2013 15:46:21 +0200
+Subject: [PATCH 0318/1302] modem_if: device_tree: Add modem_if to
+ exynos4412-slp_pq.dts
+
+Add modem_if to the device tree of slp_pq board.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 42 +++++++++++++++++++++++++++++++++
+ 1 file changed, 42 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index a9df9c6..4695393 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -993,4 +993,46 @@
+               vdd_arm-supply = <&buck2_reg>;
+               status = "okay";
+       };
++
++      modem_if {
++              compatible = "samsung,modem_if";
++              reset-req-gpio = <&gpm3 3 0>;
++              cp-on-gpio = <&gpl2 5 0>;
++              cp-reset-gpio = <&gpx3 2 0>;
++              pda-active-gpio = <&gpf1 6 0>;
++
++              phone-active-gpio = <&gpx1 6 0>;
++              cp-dump-int-gpio = <&gpx1 2 0>;
++
++              ap-dump-int-gpio = <0>;
++              flm_uart_sel = <0>;
++              cp_warm_reset = <0>;
++              sim_detect = <0>;
++
++              link-slavewake-gpio = <&gpx1 0 0>;
++              link-hostwake-gpio = <&gpx1 1 0>;
++              link-active-gpio = <&gpf1 1 0>;
++              link-enable-gpio = <0>;
++
++              modem-type = "xmm6262";
++              link-type = "hsic";
++              modem-net = "umts";
++              use-handover = <0>;
++
++              pinctrl-names = "default", "active";
++              pinctrl-0 = <&modem_state_off>;
++              pinctrl-1 = <&modem_state_active>;
++      };
++
++};
++
++&pinctrl_1 {
++      modem_state_active: modem-state-active {
++              samsung,pins = "gpx1-6", "gpx1-1", "gpx1-2";
++              samsung,pin-pud = <0>;
++      };
++      modem_state_off: modem-state-off {
++              samsung,pins = "gpx1-6", "gpx1-1", "gpx1-2";
++              samsung,pin-pud = <1>;
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0319-modem_if-Move-code-from-board-m0-modems.c-to-the-mod.patch b/patches.tizen/0319-modem_if-Move-code-from-board-m0-modems.c-to-the-mod.patch
new file mode 100644 (file)
index 0000000..095915c
--- /dev/null
@@ -0,0 +1,307 @@
+From 3cb34081f257d37c3a6452896b194628b7c460a0 Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Wed, 22 May 2013 16:26:37 +0200
+Subject: [PATCH 0319/1302] modem_if: Move code from board-m0-modems.c to the
+ modem driver
+
+Move modem related code from the board file to the modem driver.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/misc/modem_if/sipc4_modem.c | 241 +++++++++++++++++++++++++++++++++++-
+ 1 file changed, 239 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/misc/modem_if/sipc4_modem.c b/drivers/misc/modem_if/sipc4_modem.c
+index 65d9444..30560e0 100644
+--- a/drivers/misc/modem_if/sipc4_modem.c
++++ b/drivers/misc/modem_if/sipc4_modem.c
+@@ -34,6 +34,8 @@
+ #include <linux/wakelock.h>
+ #endif
+ #include <linux/rbtree.h>
++#include <linux/of.h>
++#include <linux/of_gpio.h>
+ #include <linux/platform_data/modem.h>
+ #include "modem_prj.h"
+@@ -44,6 +46,100 @@
+ #define RFS_WAKE_TIME   (HZ*3)
+ #define RAW_WAKE_TIME   (HZ*6)
++
++/* umts target platform data */
++static struct modem_io_t umts_io_devices[] = {
++      [0] = {
++              .name = "umts_ipc0",
++              .id = 0x1,
++              .format = IPC_FMT,
++              .io_type = IODEV_MISC,
++              .links = LINKTYPE(LINKDEV_HSIC),
++      },
++      [1] = {
++              .name = "umts_rfs0",
++              .id = 0x41,
++              .format = IPC_RFS,
++              .io_type = IODEV_MISC,
++              .links = LINKTYPE(LINKDEV_HSIC),
++      },
++      [2] = {
++              .name = "umts_boot0",
++              .id = 0x0,
++              .format = IPC_BOOT,
++              .io_type = IODEV_MISC,
++              .links = LINKTYPE(LINKDEV_HSIC),
++      },
++      [3] = {
++              .name = "multipdp",
++              .id = 0x1,
++              .format = IPC_MULTI_RAW,
++              .io_type = IODEV_DUMMY,
++              .links = LINKTYPE(LINKDEV_HSIC),
++      },
++      [4] = {
++#ifdef CONFIG_SLP
++              .name = "pdp0",
++#else
++              .name = "rmnet0",
++#endif
++              .id = 0x2A,
++              .format = IPC_RAW,
++              .io_type = IODEV_NET,
++              .links = LINKTYPE(LINKDEV_HSIC),
++      },
++      [5] = {
++#ifdef CONFIG_SLP
++              .name = "pdp1",
++#else
++              .name = "rmnet1",
++#endif
++              .id = 0x2B,
++              .format = IPC_RAW,
++              .io_type = IODEV_NET,
++              .links = LINKTYPE(LINKDEV_HSIC),
++      },
++      [6] = {
++#ifdef CONFIG_SLP
++              .name = "pdp2",
++#else
++              .name = "rmnet2",
++#endif
++              .id = 0x2C,
++              .format = IPC_RAW,
++              .io_type = IODEV_NET,
++              .links = LINKTYPE(LINKDEV_HSIC),
++      },
++      [7] = {
++              .name = "umts_router",
++              .id = 0x39,
++              .format = IPC_RAW,
++              .io_type = IODEV_MISC,
++              .links = LINKTYPE(LINKDEV_HSIC),
++      },
++      [8] = {
++              .name = "umts_csd",
++              .id = 0x21,
++              .format = IPC_RAW,
++              .io_type = IODEV_MISC,
++              .links = LINKTYPE(LINKDEV_HSIC),
++      },
++      [9] = {
++              .name = "umts_ramdump0",
++              .id = 0x0,
++              .format = IPC_RAMDUMP,
++              .io_type = IODEV_MISC,
++              .links = LINKTYPE(LINKDEV_HSIC),
++      },
++      [10] = {
++              .name = "umts_loopback0",
++              .id = 0x3f,
++              .format = IPC_RAW,
++              .io_type = IODEV_MISC,
++              .links = LINKTYPE(LINKDEV_HSIC),
++      },
++};
++
+ static struct modem_shared *create_modem_shared_data(void)
+ {
+       struct modem_shared *msd;
+@@ -243,13 +339,131 @@ static int attach_devices(struct io_device *iod, enum modem_link tx_link)
+       return 0;
+ }
++static struct modem_data *modem_parse_dt(struct platform_device *pdev, struct device_node *np)
++{
++      struct modem_data *mc;
++      int err = 0;
++
++      mc = kzalloc(sizeof(struct modem_data), GFP_KERNEL);
++      if (!mc) {
++              mif_err("Insufficent memory to allocate struct modem_data\n");
++              err = -ENOMEM;
++              goto dt_parse_err;
++      }
++
++      mc->link_pm_data = kzalloc(sizeof(struct modemlink_pm_data), GFP_KERNEL);
++      if (!mc->link_pm_data) {
++              mif_err("Insufficent memory to allocate struct modem_data\n");
++              err = -ENOMEM;
++              goto dt_parse_err;
++      }
++
++      mc->gpio_reset_req_n = of_get_named_gpio(np, "reset-req-gpio", 0);
++      if (!gpio_is_valid(mc->gpio_reset_req_n)) {
++              mif_err("failed to get reset-req gpio\n");
++              err = -EINVAL;
++              goto dt_parse_err;
++      }
++
++      mc->gpio_cp_on = of_get_named_gpio(np, "cp-on-gpio", 0);
++      if (!gpio_is_valid(mc->gpio_cp_on)) {
++              mif_err("failed to get cp-on gpio\n");
++              err = -EINVAL;
++              goto dt_parse_err;
++      }
++
++      mc->gpio_cp_reset = of_get_named_gpio(np, "cp-reset-gpio", 0);
++      if (!gpio_is_valid(mc->gpio_cp_reset)) {
++              mif_err("failed to get cp-reset gpio\n");
++              err = -EINVAL;
++              goto dt_parse_err;
++      }
++
++      mc->gpio_pda_active = of_get_named_gpio(np, "pda-active-gpio", 0);
++      if (!gpio_is_valid(mc->gpio_pda_active)) {
++              mif_err("failed to get pda-active gpio\n");
++              err = -EINVAL;
++              goto dt_parse_err;
++      }
++
++      mc->gpio_phone_active = of_get_named_gpio(np, "phone-active-gpio", 0);
++      if (!gpio_is_valid(mc->gpio_phone_active)) {
++              mif_err("failed to get phone-active gpio\n");
++              err = -EINVAL;
++              goto dt_parse_err;
++      }
++
++      mc->gpio_cp_dump_int = of_get_named_gpio(np, "cp-dump-int-gpio", 0);
++      if (!gpio_is_valid(mc->gpio_cp_dump_int)) {
++              mif_err("failed to get cp-dump-int gpio\n");
++              err = -EINVAL;
++              goto dt_parse_err;
++      }
++
++      mc->link_pm_data->gpio_link_slavewake = of_get_named_gpio(np,
++                                              "link-slavewake-gpio", 0);
++      if (!gpio_is_valid(mc->link_pm_data->gpio_link_slavewake)) {
++              mif_err("failed to get link-slavewak gpio\n");
++              err = -EINVAL;
++              goto dt_parse_err;
++      }
++
++      mc->link_pm_data->gpio_link_hostwake = of_get_named_gpio(np,
++                                              "link-hostwake-gpio", 0);
++      if (!gpio_is_valid(mc->link_pm_data->gpio_link_hostwake)) {
++              mif_err("failed to get link-hostwake gpio\n");
++              err = -EINVAL;
++              goto dt_parse_err;
++      }
++
++      mc->link_pm_data->gpio_link_active = of_get_named_gpio(np, "link-active-gpio", 0);
++      if (!gpio_is_valid(mc->link_pm_data->gpio_link_active)) {
++              mif_err("failed to get link-active gpio\n");
++              err = -EINVAL;
++              goto dt_parse_err;
++      }
++
++      mc->link_pm_data->gpio_link_enable = of_get_named_gpio(np, "link-enable-gpio", 0);
++
++      /* link enable is optional */
++/*    if (!gpio_is_valid(mc->link_pm_data->gpio_link_enable)) {
++              mif_err("failed to get link-enable gpio\n");
++              return ERR_PTR(-EINVAL);
++      }*/
++
++      mc->link_pm_data->gpio_link_enable = 0;
++
++      devm_gpio_request(&pdev->dev, mc->gpio_reset_req_n, "gpio_reset_req_n");
++      devm_gpio_request(&pdev->dev, mc->gpio_cp_on, "gpio_cp_on");
++      devm_gpio_request(&pdev->dev, mc->gpio_cp_reset, "gpio_cp_reset");
++      devm_gpio_request(&pdev->dev, mc->gpio_pda_active, "gpio_pda_active");
++      devm_gpio_request(&pdev->dev, mc->gpio_phone_active, "gpio_phone_active");
++      devm_gpio_request(&pdev->dev, mc->gpio_cp_dump_int, "gpio_cp_dump_int");
++      devm_gpio_request(&pdev->dev, mc->link_pm_data->gpio_link_slavewake, "gpio_link_slavewake");
++      devm_gpio_request(&pdev->dev, mc->link_pm_data->gpio_link_hostwake, "gpio_link_hostwake");
++      devm_gpio_request(&pdev->dev, mc->link_pm_data->gpio_link_active, "gpio_link_active");
++      devm_gpio_request(&pdev->dev, mc->link_pm_data->gpio_link_enable, "gpio_link_enable");
++
++      platform_set_drvdata(pdev, mc);
++
++      return mc;
++
++dt_parse_err:
++      if (mc && mc->link_pm_data)
++              free(mc->link_pm_data);
++      if (mc)
++              free(mc);
++
++      return ERR_PTR(err);
++}
++
+ static int modem_probe(struct platform_device *pdev)
+ {
+-      int i;
++      int i, ret;
+       struct modem_data *pdata = pdev->dev.platform_data;
+       struct modem_shared *msd = NULL;
+       struct modem_ctl *modemctl = NULL;
+-      struct io_device *iod[pdata->num_iodevs];
++      struct io_device *iod[ARRAY_SIZE(umts_io_devices)];
+       struct link_device *ld;
+       mif_err("%s\n", pdev->name);
+@@ -261,6 +475,22 @@ static int modem_probe(struct platform_device *pdev)
+               goto err_free_modemctl;
+       }
++
++      pdata = modem_parse_dt(pdev, pdev->dev.of_node);
++      if (IS_ERR(pdata)) {
++              mif_err("Failed to parse device tree\n");
++              kfree(msd);
++              return -ENOMEM;
++      }
++
++      pdev->dev.platform_data = pdata;
++
++      pdata->num_iodevs = ARRAY_SIZE(umts_io_devices);
++      pdata->iodevs = umts_io_devices;
++      pdata->modem_type = 1;
++      pdata->name = "xmm6262";
++      pdata->link_types = LINKTYPE(LINKDEV_HSIC);
++
+       modemctl = create_modemctl_device(pdev, msd);
+       if (!modemctl) {
+               mif_err("modemctl == NULL\n");
+@@ -352,10 +582,17 @@ static const struct dev_pm_ops modem_pm_ops = {
+       .resume     = modem_resume,
+ };
++static const struct of_device_id modem_of_match[] = {
++      { .compatible = "samsung,modem_if" },
++      {},
++};
++MODULE_DEVICE_TABLE(of, modem_of_match);
++
+ static struct platform_driver modem_driver = {
+       .probe = modem_probe,
+       .shutdown = modem_shutdown,
+       .driver = {
++              .of_match_table = modem_of_match,
+               .name = "modem_if",
+               .pm   = &modem_pm_ops,
+       },
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0320-modem_if-Comment-out-enable_wake_irq-in-modem-driver.patch b/patches.tizen/0320-modem_if-Comment-out-enable_wake_irq-in-modem-driver.patch
new file mode 100644 (file)
index 0000000..b7f3a33
--- /dev/null
@@ -0,0 +1,57 @@
+From f781eecb531f56df35d8f5c8c9ad6d4be91a3442 Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Thu, 23 May 2013 11:33:17 +0200
+Subject: [PATCH 0320/1302] modem_if: Comment out enable_wake_irq in modem
+ drivers (HSIC, xmm6262)
+
+Enabling the interrupt caused problem with the modem.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/misc/modem_if/modem_link_device_hsic.c        | 4 ++--
+ drivers/misc/modem_if/modem_modemctl_device_xmm6262.c | 5 +++--
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/misc/modem_if/modem_link_device_hsic.c b/drivers/misc/modem_if/modem_link_device_hsic.c
+index 81c732e..dd4f749 100644
+--- a/drivers/misc/modem_if/modem_link_device_hsic.c
++++ b/drivers/misc/modem_if/modem_link_device_hsic.c
+@@ -1555,11 +1555,11 @@ static int usb_link_pm_init(struct usb_link_device *usb_ld, void *data)
+               goto err_request_irq;
+       }
+-      r = enable_irq_wake(pm_data->irq_link_hostwake);
++/*    r = enable_irq_wake(pm_data->irq_link_hostwake);
+       if (r) {
+               mif_err("failed to enable_irq_wake:%d\n", r);
+               goto err_set_wake_irq;
+-      }
++      }*/
+       /* create work queue & init work for runtime pm */
+       pm_data->wq = create_singlethread_workqueue("linkpmd");
+diff --git a/drivers/misc/modem_if/modem_modemctl_device_xmm6262.c b/drivers/misc/modem_if/modem_modemctl_device_xmm6262.c
+index 311836c..015a873 100644
+--- a/drivers/misc/modem_if/modem_modemctl_device_xmm6262.c
++++ b/drivers/misc/modem_if/modem_modemctl_device_xmm6262.c
+@@ -217,12 +217,13 @@ int xmm6262_init_modemctl_device(struct modem_ctl *mc,
+               goto err_phone_active_request_irq;
+       }
+-      ret = enable_irq_wake(mc->irq_phone_active);
++/* not needed for suspend/resume */
++/*    ret = enable_irq_wake(mc->irq_phone_active);
+       if (ret) {
+               mif_err("failed to enable_irq_wake:%d\n", ret);
+               goto err_phone_active_set_wake_irq;
+       }
+-
++*/
+       /* initialize sim_state if gpio_sim_detect exists */
+       mc->sim_state.online = false;
+       mc->sim_state.changed = false;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0321-usb-ehci-s5p-Add-s5p_ehci_configurate-needed-by-mode.patch b/patches.tizen/0321-usb-ehci-s5p-Add-s5p_ehci_configurate-needed-by-mode.patch
new file mode 100644 (file)
index 0000000..fbd52e2
--- /dev/null
@@ -0,0 +1,70 @@
+From e0b569d0b9decca781c91e06777cee474c216f23 Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Tue, 2 Jul 2013 16:18:22 +0200
+Subject: [PATCH 0321/1302] usb: ehci-s5p: Add s5p_ehci_configurate, needed by
+ modem_if
+
+s5p_ehci_configurate function configures the data transfer for HSIC modem.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/host/ehci-s5p.c | 27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
+index 708b5b4..e7d26d6 100644
+--- a/drivers/usb/host/ehci-s5p.c
++++ b/drivers/usb/host/ehci-s5p.c
+@@ -39,6 +39,9 @@
+ #define EHCI_INSNREG00_ENABLE_DMA_BURST       \
+       (EHCI_INSNREG00_ENA_INCR16 | EHCI_INSNREG00_ENA_INCR8 | \
+        EHCI_INSNREG00_ENA_INCR4 | EHCI_INSNREG00_ENA_INCRX_ALIGN)
++#define INSNREG00(base)                         (base + 0x90)
++#define ENA_DMA_INCR                            (0xF << 22)
++#define OHCI_SUSP_LGCY                          (1 << 20)
+ static const char hcd_name[] = "ehci-s5p";
+ static struct hc_driver __read_mostly s5p_ehci_hc_driver;
+@@ -82,6 +85,28 @@ static ssize_t show_ehci_power(struct device *dev,
+       return sprintf(buf, "EHCI Power %s\n", (s5p_ehci->power_on) ? "on" : "off");
+ }
++static int s5p_ehci_configurate(struct usb_hcd *hcd)
++{
++      int delay_count = 0;
++
++      /* This is for waiting phy before ehci configuration */
++      do {
++              if (readl(hcd->regs))
++                      break;
++              udelay(1);
++              ++delay_count;
++      } while (delay_count < 200);
++      if (delay_count)
++              dev_info(hcd->self.controller, "phy delay count = %d\n",
++                      delay_count);
++
++      /* DMA burst Enable, set utmi suspend_on_n */
++      writel(readl(INSNREG00(hcd->regs)) | ENA_DMA_INCR | OHCI_SUSP_LGCY,
++              INSNREG00(hcd->regs));
++      return 0;
++}
++
++
+ static ssize_t store_ehci_power(struct device *dev,
+                               struct device_attribute *attr,
+                               const char *buf, size_t count)
+@@ -111,6 +136,8 @@ static ssize_t store_ehci_power(struct device *dev,
+               }
+               s5p_ehci_phy_enable(s5p_ehci, pdev);
++                      
++              s5p_ehci_configurate(hcd);
+               irq = platform_get_irq(pdev, 0);
+               retval = usb_add_hcd(hcd, irq,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0322-modem_if-Move-code-from-board-m0-modems.c-to-the-xmm.patch b/patches.tizen/0322-modem_if-Move-code-from-board-m0-modems.c-to-the-xmm.patch
new file mode 100644 (file)
index 0000000..8b2e05a
--- /dev/null
@@ -0,0 +1,148 @@
+From bb1e1af90d80cc0e56a92cb94c791c0f91dc2eff Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Thu, 23 May 2013 11:51:54 +0200
+Subject: [PATCH 0322/1302] modem_if: Move code from board-m0-modems.c to the
+ xmm6262 driver
+
+Moved code from the board file to the driver of the xmm6262 chip. Also
+handling of sim card detection has been commented out.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../misc/modem_if/modem_modemctl_device_xmm6262.c  | 70 +++++++++++++++++++---
+ drivers/misc/modem_if/sipc4_modem.c                |  4 +-
+ 2 files changed, 64 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/misc/modem_if/modem_modemctl_device_xmm6262.c b/drivers/misc/modem_if/modem_modemctl_device_xmm6262.c
+index 015a873..0956906 100644
+--- a/drivers/misc/modem_if/modem_modemctl_device_xmm6262.c
++++ b/drivers/misc/modem_if/modem_modemctl_device_xmm6262.c
+@@ -23,9 +23,52 @@
+ #include <linux/delay.h>
+ #include <linux/platform_device.h>
+ #include <plat/devs.h>
++#include <plat/gpio-cfg.h>
+ #include <linux/platform_data/modem.h>
+ #include "modem_prj.h"
++static void xmm_gpio_revers_bias_clear(struct modem_ctl *mc)
++{
++      gpio_direction_output(mc->gpio_pda_active, 0);
++      gpio_direction_output(mc->gpio_phone_active, 0);
++      gpio_direction_output(mc->gpio_cp_dump_int, 0);
++      gpio_direction_output(mc->mdm_data->link_pm_data->gpio_link_active, 0);
++      gpio_direction_output(mc->mdm_data->link_pm_data->gpio_link_hostwake, 0);
++      gpio_direction_output(mc->mdm_data->link_pm_data->gpio_link_slavewake, 0);
++
++      gpio_direction_output(mc->gpio_reset_req_n, 0); /* added by K */
++      gpio_direction_output(mc->gpio_cp_on, 0); /* added by K */
++      gpio_direction_output(mc->gpio_cp_reset, 0); /* added by K */
++
++/*
++      if (umts_modem_data.gpio_sim_detect)
++              gpio_direction_output(umts_modem_data.gpio_sim_detect, 0);
++*/
++
++      msleep(20);
++}
++
++static void xmm_gpio_revers_bias_restore(struct modem_ctl *mc)
++{
++/*
++      unsigned gpio_sim_detect = umts_modem_data.gpio_sim_detect;
++*/
++
++      s3c_gpio_cfgpin(mc->gpio_phone_active, S3C_GPIO_SFN(0xF));
++      s3c_gpio_cfgpin(mc->mdm_data->link_pm_data->gpio_link_hostwake,
++              S3C_GPIO_SFN(0xF));
++      gpio_direction_input(mc->gpio_cp_dump_int);
++
++/*    if (gpio_sim_detect) {
++              gpio_direction_input(gpio_sim_detect);
++              s3c_gpio_cfgpin(gpio_sim_detect, S3C_GPIO_SFN(0xF));
++              s3c_gpio_setpull(gpio_sim_detect, S3C_GPIO_PULL_NONE);
++              irq_set_irq_type(gpio_to_irq(gpio_sim_detect),
++                              IRQ_TYPE_EDGE_BOTH);
++              enable_irq_wake(gpio_to_irq(gpio_sim_detect));
++      } */
++}
++
+ static int xmm6262_on(struct modem_ctl *mc)
+ {
+       mif_info("\n");
+@@ -35,8 +78,7 @@ static int xmm6262_on(struct modem_ctl *mc)
+               return -ENXIO;
+       }
+-      if (mc->gpio_revers_bias_clear)
+-              mc->gpio_revers_bias_clear();
++      xmm_gpio_revers_bias_clear(mc);
+       /* TODO */
+       gpio_set_value(mc->gpio_reset_req_n, 0);
+@@ -52,8 +94,9 @@ static int xmm6262_on(struct modem_ctl *mc)
+       udelay(60);
+       gpio_set_value(mc->gpio_cp_on, 0);
+       msleep(20);
+-      if (mc->gpio_revers_bias_restore)
+-              mc->gpio_revers_bias_restore();
++
++      xmm_gpio_revers_bias_restore(mc);
++
+       gpio_set_value(mc->gpio_pda_active, 1);
+       mc->phone_state = STATE_BOOTING;
+@@ -83,8 +126,7 @@ static int xmm6262_reset(struct modem_ctl *mc)
+       if (!mc->gpio_cp_reset || !mc->gpio_reset_req_n)
+               return -ENXIO;
+-      if (mc->gpio_revers_bias_clear)
+-              mc->gpio_revers_bias_clear();
++      xmm_gpio_revers_bias_clear(mc);
+       gpio_set_value(mc->gpio_cp_reset, 0);
+       gpio_set_value(mc->gpio_reset_req_n, 0);
+@@ -105,8 +147,20 @@ static int xmm6262_reset(struct modem_ctl *mc)
+       gpio_set_value(mc->gpio_cp_on, 0);
+       msleep(20);
+-      if (mc->gpio_revers_bias_restore)
+-              mc->gpio_revers_bias_restore();
++      xmm_gpio_revers_bias_restore(mc);
++
++/* vvv added by Kamil */
++      gpio_direction_input(mc->mdm_data->link_pm_data->gpio_link_hostwake);
++      gpio_direction_input(mc->gpio_phone_active);
++      gpio_direction_input(mc->gpio_cp_dump_int);
++
++      gpio_set_value(mc->gpio_pda_active, 1);
++
++      msleep(10);
++
++      gpio_set_value(mc->mdm_data->link_pm_data->gpio_link_active, 1);
++      gpio_set_value(mc->mdm_data->link_pm_data->gpio_link_slavewake, 1);
++/* ^^^ added by Kamil */
+       mc->phone_state = STATE_BOOTING;
+diff --git a/drivers/misc/modem_if/sipc4_modem.c b/drivers/misc/modem_if/sipc4_modem.c
+index 30560e0..3f22f6a 100644
+--- a/drivers/misc/modem_if/sipc4_modem.c
++++ b/drivers/misc/modem_if/sipc4_modem.c
+@@ -450,9 +450,9 @@ static struct modem_data *modem_parse_dt(struct platform_device *pdev, struct de
+ dt_parse_err:
+       if (mc && mc->link_pm_data)
+-              free(mc->link_pm_data);
++              kfree(mc->link_pm_data);
+       if (mc)
+-              free(mc);
++              kfree(mc);
+       return ERR_PTR(err);
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0323-modem_if-ifdef-wake_lock-support-in-the-modem-driver.patch b/patches.tizen/0323-modem_if-ifdef-wake_lock-support-in-the-modem-driver.patch
new file mode 100644 (file)
index 0000000..13309a7
--- /dev/null
@@ -0,0 +1,153 @@
+From ca76117bf238273c6b4c2e3aa64192a87528461b Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Tue, 21 May 2013 16:54:10 +0200
+Subject: [PATCH 0323/1302] modem_if: ifdef wake_lock support in the modem
+ driver
+
+Wake_locks are not supported outside of Android so it is essential to
+make their use optional.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/misc/modem_if/modem_link_device_hsic.h | 2 ++
+ drivers/misc/modem_if/modem_prj.h              | 8 ++++++++
+ drivers/misc/modem_if/modem_utils.c            | 2 ++
+ drivers/misc/modem_if/sipc5_io_device.c        | 4 ++++
+ drivers/misc/modem_if/sipc5_modem.c            | 4 ++++
+ 5 files changed, 20 insertions(+)
+
+diff --git a/drivers/misc/modem_if/modem_link_device_hsic.h b/drivers/misc/modem_if/modem_link_device_hsic.h
+index 604b067..50a6485 100644
+--- a/drivers/misc/modem_if/modem_link_device_hsic.h
++++ b/drivers/misc/modem_if/modem_link_device_hsic.h
+@@ -92,10 +92,12 @@ struct link_pm_data {
+       bool link_pm_active;
+       int resume_retry_cnt;
++#ifdef CONFIG_HAS_WAKELOCK
+       struct wake_lock l2_wake;
+       struct wake_lock boot_wake;
+       struct wake_lock rpm_wake;
+       struct wake_lock tx_async_wake;
++#endif
+       struct notifier_block pm_notifier;
+       bool dpm_suspending;
+diff --git a/drivers/misc/modem_if/modem_prj.h b/drivers/misc/modem_if/modem_prj.h
+index 4780bef..d7ab484 100644
+--- a/drivers/misc/modem_if/modem_prj.h
++++ b/drivers/misc/modem_if/modem_prj.h
+@@ -20,7 +20,9 @@
+ #include <linux/miscdevice.h>
+ #include <linux/skbuff.h>
+ #include <linux/completion.h>
++#ifdef CONFIG_HAS_WAKELOCK
+ #include <linux/wakelock.h>
++#endif
+ #include <linux/rbtree.h>
+ #include <linux/spinlock.h>
+ #include <linux/types.h>
+@@ -351,7 +353,9 @@ struct io_device {
+       struct modem_ctl *mc;
+       struct modem_shared *msd;
++#ifdef CONFIG_HAS_WAKELOCK
+       struct wake_lock wakelock;
++#endif
+       long waketime;
+       /* DO NOT use __current_link directly
+@@ -554,6 +558,8 @@ struct modem_ctl {
+ #endif /*CONFIG_LTE_MODEM_CMC221*/
+ #if defined(CONFIG_MACH_GRANDE)
+       struct delayed_work sim_det_dwork;
++#ifdef CONFIG_HAS_WAKELOCK
++#endif
+ #endif /* For checking sim detect pin */
+       struct work_struct work;
+@@ -570,7 +576,9 @@ struct modem_ctl {
+       struct io_device *bootd;
+       /* Wakelock for modem_ctl */
++#ifdef CONFIG_HAS_WAKELOCK
+       struct wake_lock mc_wake_lock;
++#endif
+       void (*gpio_revers_bias_clear)(void);
+       void (*gpio_revers_bias_restore)(void);
+diff --git a/drivers/misc/modem_if/modem_utils.c b/drivers/misc/modem_if/modem_utils.c
+index a2def11..229e93f 100644
+--- a/drivers/misc/modem_if/modem_utils.c
++++ b/drivers/misc/modem_if/modem_utils.c
+@@ -37,7 +37,9 @@
+ #include <linux/irq.h>
+ #include <linux/gpio.h>
+ #include <linux/delay.h>
++#ifdef CONFIG_HAS_WAKELOCK
+ #include <linux/wakelock.h>
++#endif
+ #include <linux/platform_data/modem.h>
+ #include "modem_prj.h"
+diff --git a/drivers/misc/modem_if/sipc5_io_device.c b/drivers/misc/modem_if/sipc5_io_device.c
+index 9e22e9c..636e191 100644
+--- a/drivers/misc/modem_if/sipc5_io_device.c
++++ b/drivers/misc/modem_if/sipc5_io_device.c
+@@ -855,8 +855,10 @@ static int io_dev_recv_data_from_link_dev(struct io_device *iod,
+       case IPC_RAW:
+       case IPC_RFS:
+       case IPC_MULTI_RAW:
++#ifdef CONFIG_HAS_WAKELOCK
+               if (iod->waketime)
+                       wake_lock_timeout(&iod->wakelock, iod->waketime);
++#endif
+               if (ld->link_type == LINKDEV_DPRAM && ld->aligned)
+                       err = rx_frame_from_mem(iod, ld, data, len);
+@@ -957,8 +959,10 @@ static int io_dev_recv_skb_from_link_dev(struct io_device *iod,
+       case IPC_RAW:
+       case IPC_RFS:
+       case IPC_MULTI_RAW:
++#ifdef CONFIG_HAS_WAKELOCK
+               if (iod->waketime)
+                       wake_lock_timeout(&iod->wakelock, iod->waketime);
++#endif
+               err = rx_frame_from_skb(iod, ld, skb);
+               if (err < 0) {
+diff --git a/drivers/misc/modem_if/sipc5_modem.c b/drivers/misc/modem_if/sipc5_modem.c
+index ccfad5f..f7662df 100644
+--- a/drivers/misc/modem_if/sipc5_modem.c
++++ b/drivers/misc/modem_if/sipc5_modem.c
+@@ -31,7 +31,9 @@
+ #include <linux/irq.h>
+ #include <linux/gpio.h>
+ #include <linux/delay.h>
++#ifdef CONFIG_HAS_WAKELOCK
+ #include <linux/wakelock.h>
++#endif
+ #include <linux/rbtree.h>
+ #include <linux/platform_data/modem.h>
+@@ -196,6 +198,7 @@ static int attach_devices(struct io_device *iod, enum modem_link tx_link)
+               BUG();
+       }
++#ifdef CONFIG_HAS_WAKELOCK
+       switch (iod->format) {
+       case IPC_FMT:
+               wake_lock_init(&iod->wakelock, WAKE_LOCK_SUSPEND, iod->name);
+@@ -225,6 +228,7 @@ static int attach_devices(struct io_device *iod, enum modem_link tx_link)
+       default:
+               break;
+       }
++#endif
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0324-modem_if-Change-net-device-name-choice-mechanism.patch b/patches.tizen/0324-modem_if-Change-net-device-name-choice-mechanism.patch
new file mode 100644 (file)
index 0000000..7205942
--- /dev/null
@@ -0,0 +1,68 @@
+From 7f6f05e8e496b8cd2f420e03c96ea46b00425447 Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Tue, 2 Jul 2013 15:53:32 +0200
+Subject: [PATCH 0324/1302] modem_if: Change net device name choice mechanism
+
+CONFIG_SLP is no longer used hence new method of net device names was
+implemented.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/misc/modem_if/sipc4_modem.c | 20 +++++---------------
+ 1 file changed, 5 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/misc/modem_if/sipc4_modem.c b/drivers/misc/modem_if/sipc4_modem.c
+index 3f22f6a..c4cd872 100644
+--- a/drivers/misc/modem_if/sipc4_modem.c
++++ b/drivers/misc/modem_if/sipc4_modem.c
+@@ -46,6 +46,8 @@
+ #define RFS_WAKE_TIME   (HZ*3)
+ #define RAW_WAKE_TIME   (HZ*6)
++/* pdp for SLP, rmnet for others */
++#define NET_DEVICE_NAME(n) "pdp"#n
+ /* umts target platform data */
+ static struct modem_io_t umts_io_devices[] = {
+@@ -78,33 +80,21 @@ static struct modem_io_t umts_io_devices[] = {
+               .links = LINKTYPE(LINKDEV_HSIC),
+       },
+       [4] = {
+-#ifdef CONFIG_SLP
+-              .name = "pdp0",
+-#else
+-              .name = "rmnet0",
+-#endif
++              .name = NET_DEVICE_NAME(0),
+               .id = 0x2A,
+               .format = IPC_RAW,
+               .io_type = IODEV_NET,
+               .links = LINKTYPE(LINKDEV_HSIC),
+       },
+       [5] = {
+-#ifdef CONFIG_SLP
+-              .name = "pdp1",
+-#else
+-              .name = "rmnet1",
+-#endif
++              .name = NET_DEVICE_NAME(1) ,
+               .id = 0x2B,
+               .format = IPC_RAW,
+               .io_type = IODEV_NET,
+               .links = LINKTYPE(LINKDEV_HSIC),
+       },
+       [6] = {
+-#ifdef CONFIG_SLP
+-              .name = "pdp2",
+-#else
+-              .name = "rmnet2",
+-#endif
++              .name = NET_DEVICE_NAME(2),
+               .id = 0x2C,
+               .format = IPC_RAW,
+               .io_type = IODEV_NET,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0325-modem_if-Add-modem-drivers-to-Kconfig-and-Makefile.patch b/patches.tizen/0325-modem_if-Add-modem-drivers-to-Kconfig-and-Makefile.patch
new file mode 100644 (file)
index 0000000..62bd7a7
--- /dev/null
@@ -0,0 +1,38 @@
+From 1e4b4a64bc2b22783068b96fff8ec0fca41887fb Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Thu, 23 May 2013 12:03:23 +0200
+Subject: [PATCH 0325/1302] modem_if: Add modem drivers to Kconfig and Makefile
+
+Add modem_if to Kconfig and Makefile to enable compilation.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/misc/Kconfig  | 1 +
+ drivers/misc/Makefile | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
+index 378b0f3..0341677 100644
+--- a/drivers/misc/Kconfig
++++ b/drivers/misc/Kconfig
+@@ -540,5 +540,6 @@ source "drivers/misc/lis3lv02d/Kconfig"
+ source "drivers/misc/carma/Kconfig"
+ source "drivers/misc/altera-stapl/Kconfig"
+ source "drivers/misc/mei/Kconfig"
++source "drivers/misc/modem_if/Kconfig"
+ source "drivers/misc/vmw_vmci/Kconfig"
+ endmenu
+diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
+index 0cadf27..97e46bb 100644
+--- a/drivers/misc/Makefile
++++ b/drivers/misc/Makefile
+@@ -54,3 +54,4 @@ obj-$(CONFIG_VMWARE_VMCI)    += vmw_vmci/
+ obj-$(CONFIG_LATTICE_ECP3_CONFIG)     += lattice-ecp3-config.o
+ obj-$(CONFIG_SLP_GLOBAL_LOCK) += slp_global_lock.o
+ obj-$(CONFIG_SRAM)            += sram.o
++obj-$(CONFIG_SEC_MODEM)               += modem_if/
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0326-ARM-dts-exynos4412-redwood-Add-device-nodes-for-mode.patch b/patches.tizen/0326-ARM-dts-exynos4412-redwood-Add-device-nodes-for-mode.patch
new file mode 100644 (file)
index 0000000..f8b11da
--- /dev/null
@@ -0,0 +1,84 @@
+From 59826af7b21be29e142799b7e4bd67f62ad9912a Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Tue, 2 Jul 2013 17:24:10 +0200
+Subject: [PATCH 0326/1302] ARM: dts: exynos4412-redwood: Add device nodes for
+ modem_if
+
+Add device nodes for modem_if, also set HSIC regulator to always on.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-redwood.dts | 43 ++++++++++++++++++++++++++++++++
+ 1 file changed, 43 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-redwood.dts b/arch/arm/boot/dts/exynos4412-redwood.dts
+index 828376b..ccb5b9b 100644
+--- a/arch/arm/boot/dts/exynos4412-redwood.dts
++++ b/arch/arm/boot/dts/exynos4412-redwood.dts
+@@ -365,6 +365,7 @@
+                                       regulator-name = "VHSIC_1.0V";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
+                               };
+                               ldo16_reg: ldo@16 {
+@@ -372,6 +373,7 @@
+                                       regulator-name = "VHSIC_1.8V";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
+                               };
+                               ldo17_reg: ldo@17 {
+@@ -731,4 +733,45 @@
+       };
++      modem_if {
++              compatible = "samsung,modem_if";
++              reset-req-gpio = <&gpm3 3 0>;
++              cp-on-gpio = <&gpl2 5 0>;
++              cp-reset-gpio = <&gpx3 2 0>;
++              pda-active-gpio = <&gpf1 6 0>;
++
++              phone-active-gpio = <&gpx1 6 0>;
++              cp-dump-int-gpio = <&gpx1 2 0>;
++
++              ap-dump-int-gpio = <0>;
++              flm_uart_sel = <0>;
++              cp_warm_reset = <0>;
++              sim_detect = <0>;
++
++              link-slavewake-gpio = <&gpx1 0 0>;
++              link-hostwake-gpio = <&gpx1 1 0>;
++              link-active-gpio = <&gpf1 1 0>;
++              link-enable-gpio = <0>;
++
++              modem-type = "xmm6262";
++              link-type = "hsic";
++              modem-net = "umts";
++              use-handover = <0>;
++
++              pinctrl-names = "default", "active";
++              pinctrl-0 = <&modem_state_off>;
++              pinctrl-1 = <&modem_state_active>;
++      };
++
++};
++
++&pinctrl_1 {
++      modem_state_active: modem-state-active {
++              samsung,pins = "gpx1-6", "gpx1-1", "gpx1-2";
++              samsung,pin-pud = <0>;
++      };
++      modem_state_off: modem-state-off {
++              samsung,pins = "gpx1-6", "gpx1-1", "gpx1-2";
++              samsung,pin-pud = <1>;
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0327-tizen_defconfig-update.patch b/patches.tizen/0327-tizen_defconfig-update.patch
new file mode 100644 (file)
index 0000000..1c7636a
--- /dev/null
@@ -0,0 +1,90 @@
+From 3e53b1257c9e87e348167cf7e963ad5702cf5a43 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 3 Jul 2013 18:18:13 +0200
+Subject: [PATCH 0327/1302] tizen_defconfig update
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_defconfig | 30 ++++++++++++++++++++++++------
+ 1 file changed, 24 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index fd97c41..453ca9f 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -1,6 +1,6 @@
+ #
+ # Automatically generated file; DO NOT EDIT.
+-# Linux/arm 3.10.0-rc5 Kernel Configuration
++# Linux/arm 3.10.0 Kernel Configuration
+ #
+ CONFIG_ARM=y
+ CONFIG_ARM_HAS_SG_CHAIN=y
+@@ -552,10 +552,7 @@ CONFIG_ARM_EXYNOS4210_CPUFREQ=y
+ CONFIG_ARM_EXYNOS4X12_CPUFREQ=y
+ # CONFIG_ARM_EXYNOS5250_CPUFREQ is not set
+ # CONFIG_ARM_KIRKWOOD_CPUFREQ is not set
+-CONFIG_CPU_IDLE=y
+-# CONFIG_CPU_IDLE_MULTIPLE_DRIVERS is not set
+-CONFIG_CPU_IDLE_GOV_LADDER=y
+-CONFIG_CPU_IDLE_GOV_MENU=y
++# CONFIG_CPU_IDLE is not set
+ # CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
+ #
+@@ -1153,6 +1150,24 @@ CONFIG_SLP_GLOBAL_LOCK=y
+ # Altera FPGA firmware download module
+ #
+ # CONFIG_ALTERA_STAPL is not set
++CONFIG_SEC_MODEM=y
++CONFIG_UMTS_MODEM_XMM6260=y
++CONFIG_UMTS_MODEM_XMM6262=y
++# CONFIG_CDMA_MODEM_CBP71 is not set
++# CONFIG_CDMA_MODEM_CBP72 is not set
++# CONFIG_LTE_MODEM_CMC221 is not set
++# CONFIG_CDMA_MODEM_MDM6600 is not set
++# CONFIG_GSM_MODEM_ESC6270 is not set
++# CONFIG_LINK_DEVICE_MIPI is not set
++# CONFIG_LINK_DEVICE_DPRAM is not set
++# CONFIG_LINK_DEVICE_PLD is not set
++# CONFIG_LINK_DEVICE_USB is not set
++CONFIG_LINK_DEVICE_HSIC=y
++# CONFIG_LINK_DEVICE_C2C is not set
++# CONFIG_IPC_CMC22x_OLD_RFS is not set
++CONFIG_SIPC_VER_5=y
++# CONFIG_SIM_DETECT is not set
++# CONFIG_SIM_SLOT_SWITCH is not set
+ #
+ # SCSI device support
+@@ -1887,6 +1902,7 @@ CONFIG_VIDEO_S5P_FIMC=y
+ CONFIG_VIDEO_S5P_MIPI_CSIS=y
+ CONFIG_VIDEO_EXYNOS_FIMC_LITE=y
+ CONFIG_VIDEO_EXYNOS4_FIMC_IS=y
++# CONFIG_VIDEO_EXYNOS4_ISP_DMA_CAPTURE is not set
+ # CONFIG_VIDEO_SAMSUNG_S5P_TV is not set
+ CONFIG_V4L_MEM2MEM_DRIVERS=y
+ # CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set
+@@ -2786,7 +2802,9 @@ CONFIG_COMMON_CLK_MAX77686=y
+ # Hardware Spinlock drivers
+ #
+ CONFIG_CLKSRC_OF=y
++CONFIG_CLKSRC_MMIO=y
+ CONFIG_CLKSRC_EXYNOS_MCT=y
++CONFIG_CLKSRC_SAMSUNG_PWM=y
+ # CONFIG_MAILBOX is not set
+ CONFIG_IOMMU_API=y
+ CONFIG_IOMMU_SUPPORT=y
+@@ -2923,7 +2941,7 @@ CONFIG_GIC_NON_BANKED=y
+ # CONFIG_IPACK_BUS is not set
+ # CONFIG_RESET_CONTROLLER is not set
+ CONFIG_GENERIC_PHY=y
+-CONFIG_PHY_EXYNOS_MIPI_DSIM_CSIS=y
++CONFIG_PHY_EXYNOS_MIPI_VIDEO=y
+ #
+ # File systems
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0328-clk-samsung-exynos4-Do-not-disable-ISP-bus-clocks.patch b/patches.tizen/0328-clk-samsung-exynos4-Do-not-disable-ISP-bus-clocks.patch
new file mode 100644 (file)
index 0000000..5c8c169
--- /dev/null
@@ -0,0 +1,41 @@
+From 784754340a972b44e9835c74e8466f865392785d Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 24 Apr 2013 19:02:54 +0200
+Subject: [PATCH 0328/1302] clk: samsung: exynos4: Do not disable ISP bus
+ clocks
+
+Some ISP bus clocks must be kept enabled when entering sleep mode,
+otherwise the system hangs. This patch adds CLK_IGNORE_UNUSED flags to
+those clocks to keep them ungated when FIMC IS driver is not present.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/samsung/clk-exynos4.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
+index 9994b8d..adb1352 100644
+--- a/drivers/clk/samsung/clk-exynos4.c
++++ b/drivers/clk/samsung/clk-exynos4.c
+@@ -847,13 +847,13 @@ struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = {
+                       E4X12_GATE_IP_PERIR, 16, 0, 0, "keypad"),
+       GATE(tmu_apbif, "tmu_apbif", "aclk100", E4X12_GATE_IP_PERIR, 17, 0, 0),
+       GATE(sclk_pwm_isp, "sclk_pwm_isp", "div_pwm_isp",
+-                      E4X12_SRC_MASK_ISP, 0, CLK_SET_RATE_PARENT, 0),
++                      E4X12_SRC_MASK_ISP, 0, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0),
+       GATE(sclk_spi0_isp, "sclk_spi0_isp", "div_spi0_isp_pre",
+-                      E4X12_SRC_MASK_ISP, 4, CLK_SET_RATE_PARENT, 0),
++                      E4X12_SRC_MASK_ISP, 4, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0),
+       GATE(sclk_spi1_isp, "sclk_spi1_isp", "div_spi1_isp_pre",
+-                      E4X12_SRC_MASK_ISP, 8, CLK_SET_RATE_PARENT, 0),
++                      E4X12_SRC_MASK_ISP, 8, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0),
+       GATE(sclk_uart_isp, "sclk_uart_isp", "div_uart_isp",
+-                      E4X12_SRC_MASK_ISP, 12, CLK_SET_RATE_PARENT, 0),
++                      E4X12_SRC_MASK_ISP, 12, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0),
+       GATE(pwm_isp_sclk, "pwm_isp_sclk", "sclk_pwm_isp",
+                       E4X12_GATE_IP_ISP, 0, 0, 0),
+       GATE(spi0_isp_sclk, "spi0_isp_sclk", "sclk_spi0_isp",
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0329-ARM-EXYNOS-pm-Move-call-to-flush_cache_all-before-ou.patch b/patches.tizen/0329-ARM-EXYNOS-pm-Move-call-to-flush_cache_all-before-ou.patch
new file mode 100644 (file)
index 0000000..3e4ee14
--- /dev/null
@@ -0,0 +1,42 @@
+From 7550167acf82df605ec9f0c0ad575a4630a60087 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 26 Jun 2013 19:04:13 +0200
+Subject: [PATCH 0329/1302] ARM: EXYNOS: pm: Move call to flush_cache_all()
+ before outer_flush_all()
+
+Flushing L1 cache might cause data to be stored to L2 cache, so it is
+more reasonable to flush L1 cache first and only then L2 cache.
+
+This patch moves call to flush_cache_all() in exynos_cpu_suspend()
+before outer_flush_all() to make sure that all data are flushed
+correctly. In addition flushing is enabled for all Exynos SoCs to
+prevent any data loss.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/mach-exynos/pm.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
+index e3faaa81..83c4999 100644
+--- a/arch/arm/mach-exynos/pm.c
++++ b/arch/arm/mach-exynos/pm.c
+@@ -82,13 +82,11 @@ static unsigned int save_arm_register[2];
+ static int exynos_cpu_suspend(unsigned long arg)
+ {
++      flush_cache_all();
+ #ifdef CONFIG_CACHE_L2X0
+       outer_flush_all();
+ #endif
+-      if (soc_is_exynos5250())
+-              flush_cache_all();
+-
+       /* issue the standby signal into the pm unit. */
+       cpu_do_idle();
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0330-ARM-EXYNOS-Add-support-for-firmware-assisted-suspend.patch b/patches.tizen/0330-ARM-EXYNOS-Add-support-for-firmware-assisted-suspend.patch
new file mode 100644 (file)
index 0000000..fa13e11
--- /dev/null
@@ -0,0 +1,135 @@
+From ae053e0f8ffeb64f36bf220eb5d54cef4b734543 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 21 Mar 2013 18:48:45 +0100
+Subject: [PATCH 0330/1302] ARM: EXYNOS: Add support for firmware-assisted
+ suspend/resume
+
+This patch adds firmware ops related to system suspend/resume that
+allows suspend/resume of systems with secure firmware.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/include/asm/firmware.h | 12 ++++++++++++
+ arch/arm/mach-exynos/firmware.c | 28 ++++++++++++++++++++++++++++
+ arch/arm/mach-exynos/pm.c       |  9 +++++++--
+ 3 files changed, 47 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/include/asm/firmware.h b/arch/arm/include/asm/firmware.h
+index 1563130..f459d25 100644
+--- a/arch/arm/include/asm/firmware.h
++++ b/arch/arm/include/asm/firmware.h
+@@ -37,6 +37,18 @@ struct firmware_ops {
+        * Initializes L2 cache
+        */
+       int (*l2x0_init)(void);
++      /*
++       * Suspends the system
++       */
++      int (*suspend)(unsigned long resume_addr);
++      /*
++       * Acknowledges system resume
++       */
++      int (*resume)(void);
++      /*
++       * Restores coprocessor 15 registers
++       */
++      int (*c15resume)(u32 *regs);
+ };
+ /* Global pointer for current firmware_ops structure, can't be NULL. */
+diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
+index da5fb26..3f98bf7 100644
+--- a/arch/arm/mach-exynos/firmware.c
++++ b/arch/arm/mach-exynos/firmware.c
+@@ -20,6 +20,8 @@
+ #include "smc.h"
++#define EXYNOS_SLEEP_MAGIC    0x00000BAD
++
+ static int exynos_do_idle(void)
+ {
+       exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
+@@ -47,11 +49,37 @@ static int exynos_l2x0_init(void)
+       return 0;
+ }
++static int exynos_suspend(unsigned long resume_addr)
++{
++      writel(EXYNOS_SLEEP_MAGIC, S5P_VA_SYSRAM_NS + 0xC);
++      writel(resume_addr, S5P_VA_SYSRAM_NS + 0x8);
++      exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
++
++      return 0;
++}
++
++static int exynos_resume(void)
++{
++      writel(0, S5P_VA_SYSRAM_NS + 0xC);
++
++      return 0;
++}
++
++static int exynos_c15resume(u32 *regs)
++{
++      exynos_smc(SMC_CMD_C15RESUME, regs[0], regs[1], 0);
++
++      return 0;
++}
++
+ static const struct firmware_ops exynos_firmware_ops = {
+       .do_idle                = exynos_do_idle,
+       .set_cpu_boot_addr      = exynos_set_cpu_boot_addr,
+       .cpu_boot               = exynos_cpu_boot,
+       .l2x0_init      = exynos_l2x0_init,
++      .suspend        = exynos_suspend,
++      .resume         = exynos_resume,
++      .c15resume      = exynos_c15resume,
+ };
+ void __init exynos_firmware_init(void)
+diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
+index 83c4999..e195e3e 100644
+--- a/arch/arm/mach-exynos/pm.c
++++ b/arch/arm/mach-exynos/pm.c
+@@ -36,6 +36,7 @@
+ #include <mach/pm-core.h>
+ #include "common.h"
++#include "smc.h"
+ static struct sleep_save exynos4_set_clksrc[] = {
+       { .reg = EXYNOS4_CLKSRC_MASK_TOP                , .val = 0x00000001, },
+@@ -88,7 +89,8 @@ static int exynos_cpu_suspend(unsigned long arg)
+ #endif
+       /* issue the standby signal into the pm unit. */
+-      cpu_do_idle();
++      if (call_firmware_op(suspend, virt_to_phys(s3c_cpu_resume)) == -ENOSYS)
++              cpu_do_idle();
+       pr_info("Failed to suspend the system\n");
+       return 1; /* Aborting suspend */
+@@ -286,7 +288,9 @@ static void exynos_pm_resume(void)
+               /* No need to perform below restore code */
+               goto early_wakeup;
+       }
+-      if (!soc_is_exynos5250()) {
++      if (!soc_is_exynos5250()
++          && call_firmware_op(c15resume, save_arm_register) == -ENOSYS)
++      {
+               /* Restore Power control register */
+               tmp = save_arm_register[0];
+               asm volatile ("mcr p15, 0, %0, c15, c0, 0"
+@@ -328,6 +332,7 @@ early_wakeup:
+       /* Clear SLEEP mode set in INFORM1 */
+       __raw_writel(0x0, S5P_INFORM1);
++      call_firmware_op(resume);
+       return;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0331-pinctrl-samsung-Parse-pin-groups-before-calling-pinc.patch b/patches.tizen/0331-pinctrl-samsung-Parse-pin-groups-before-calling-pinc.patch
new file mode 100644 (file)
index 0000000..77ce8a1
--- /dev/null
@@ -0,0 +1,50 @@
+From 2705a24ab66bb227748f162920e74cc8c1a0d1af Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 27 Jun 2013 17:41:48 +0200
+Subject: [PATCH 0331/1302] pinctrl: samsung: Parse pin groups before calling
+ pinctrl_register()
+
+Calling pinctrl_register() means that the driver is fully initialized
+and might accept pinmux/pinconf requests, so pin groups must be parsed
+before.
+
+This patch fixes this problem by moving device tree parsing
+before call to pinctrl_register().
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/pinctrl/pinctrl-samsung.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
+index 63ac22e..4f0c048 100644
+--- a/drivers/pinctrl/pinctrl-samsung.c
++++ b/drivers/pinctrl/pinctrl-samsung.c
+@@ -767,6 +767,10 @@ static int samsung_pinctrl_register(struct platform_device *pdev,
+               }
+       }
++      ret = samsung_pinctrl_parse_dt(pdev, drvdata);
++      if (ret)
++              return ret;
++
+       drvdata->pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, drvdata);
+       if (!drvdata->pctl_dev) {
+               dev_err(&pdev->dev, "could not register pinctrl driver\n");
+@@ -784,12 +788,6 @@ static int samsung_pinctrl_register(struct platform_device *pdev,
+               pinctrl_add_gpio_range(drvdata->pctl_dev, &pin_bank->grange);
+       }
+-      ret = samsung_pinctrl_parse_dt(pdev, drvdata);
+-      if (ret) {
+-              pinctrl_unregister(drvdata->pctl_dev);
+-              return ret;
+-      }
+-
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0332-ARM-dts-exynos4412-slp_pq-Add-sleep-mode-pin-configu.patch b/patches.tizen/0332-ARM-dts-exynos4412-slp_pq-Add-sleep-mode-pin-configu.patch
new file mode 100644 (file)
index 0000000..041c2b6
--- /dev/null
@@ -0,0 +1,190 @@
+From 0efe4843734456ccbf8db22331851185753fab20 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 11 Apr 2013 16:52:42 +0200
+Subject: [PATCH 0332/1302] ARM: dts: exynos4412-slp_pq: Add sleep mode pin
+ configuration
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 164 ++++++++++++++++++++++++++++++++
+ 1 file changed, 164 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 4695393..b91b1e3 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -15,6 +15,170 @@
+ /dts-v1/;
+ /include/ "exynos4412.dtsi"
++&pinctrl_0 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&pdn_group_low_0>,
++                      <&pdn_group_high_0>,
++                      <&pdn_group_in_nopull_0>,
++                      <&pdn_group_in_down_0>,
++                      <&pdn_group_in_up_0>,
++                      <&pdn_group_prev_0>;
++
++      pdn_group_low_0: pdn-group-low {
++              samsung,pins = "gpa0-1";
++              samsung,pin-con-pdn = <0>;
++              samsung,pin-pud-pdn = <0>;
++      };
++
++      pdn_group_high_0: pdn-group-high {
++              samsung,pins = "gpf3-4";
++              samsung,pin-con-pdn = <1>;
++              samsung,pin-pud-pdn = <0>;
++      };
++
++      pdn_group_in_nopull_0: pdn-group-in-nopull {
++              samsung,pins = "gpa0-0", "gpa0-2", "gpa0-4", "gpb-0",
++                              "gpb-1", "gpb-2", "gpb-3", "gpc1-0",
++                              "gpc1-2", "gpc1-3", "gpc1-4", "gpd0-2",
++                              "gpd0-3", "gpd1-2", "gpd1-3", "gpf0-0",
++                              "gpf0-1", "gpf0-4", "gpf0-6", "gpf1-4",
++                              "gpf1-5", "gpf2-6", "gpf2-7", "gpf3-0";
++              samsung,pin-con-pdn = <2>;
++              samsung,pin-pud-pdn = <0>;
++      };
++
++      pdn_group_in_down_0: pdn-group-in-down {
++              samsung,pins = "gpa0-5", "gpa0-6", "gpa1-0", "gpa1-1",
++                              "gpa1-2", "gpa1-3", "gpa1-4", "gpa1-5",
++                              "gpb-4", "gpb-6", "gpb-7", "gpc0-0",
++                              "gpc0-1", "gpc0-2", "gpc0-3", "gpc0-4",
++                              "gpd0-0", "gpd0-1", "gpd1-0", "gpd1-1",
++                              "gpf0-2", "gpf0-3", "gpf0-5", "gpf0-7",
++                              "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3",
++                              "gpf1-6", "gpf2-1", "gpf2-2", "gpf2-3",
++                              "gpf2-4", "gpf2-5", "gpf3-5", "gpj0-3",
++                              "gpj0-6", "gpj0-7", "gpj1-0", "gpj1-3",
++                              "gpj1-4";
++              samsung,pin-con-pdn = <2>;
++              samsung,pin-pud-pdn = <1>;
++      };
++
++      pdn_group_in_up_0: pdn-group-in-up {
++              samsung,pins = "gpa0-3", "gpa0-7", "gpb-5";
++              samsung,pin-con-pdn = <2>;
++              samsung,pin-pud-pdn = <2>;
++      };
++
++      pdn_group_prev_0: pdn-group-prev {
++              samsung,pins = "gpc1-1", "gpf1-7", "gpf2-0", "gpf3-1",
++                              "gpf3-2", "gpf3-3", "gpj0-0", "gpj0-1",
++                              "gpj0-2", "gpj0-4", "gpj0-5", "gpj1-1",
++                              "gpj1-2";
++              samsung,pin-con-pdn = <3>;
++              samsung,pin-pud-pdn = <0>;
++      };
++};
++
++&pinctrl_1 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&pdn_group_low_1>,
++                      <&pdn_group_high_1>,
++                      <&pdn_group_in_nopull_1>,
++                      <&pdn_group_in_down_1>,
++                      <&pdn_group_prev_1>;
++
++      pdn_group_low_1: pdn-group-low {
++              samsung,pins = "gpk3-0", "gpk0-2";
++              samsung,pin-con-pdn = <0>;
++              samsung,pin-pud-pdn = <0>;
++      };
++
++      pdn_group_high_1: pdn-group-high {
++              samsung,pins = "gpm3-3";
++              samsung,pin-con-pdn = <1>;
++              samsung,pin-pud-pdn = <0>;
++      };
++
++      pdn_group_in_nopull_1: pdn-group-in-nopull {
++              samsung,pins = "gpk3-1", "gpk3-3", "gpk3-4", "gpk3-5",
++                              "gpk3-6", "gpy2-2", "gpy2-3", "gpy2-4",
++                              "gpy2-5", "gpm1-2", "gpm1-3", "gpm1-4",
++                              "gpm1-5", "gpm2-0", "gpm2-1";
++              samsung,pin-con-pdn = <2>;
++              samsung,pin-pud-pdn = <0>;
++      };
++
++      pdn_group_in_down_1: pdn-group-in-down {
++              samsung,pins = "gpk1-0", "gpk1-1", "gpk1-2", "gpk2-0",
++                              "gpk2-1", "gpk2-2", "gpk2-3", "gpk2-4",
++                              "gpk2-5", "gpk2-6", "gpk3-2", "gpl0-0",
++                              "gpl0-1", "gpl0-2", "gpl0-3", "gpl1-0",
++                              "gpl1-1", "gpl2-0", "gpl2-1", "gpl2-2",
++                              "gpl2-3", "gpl2-4", "gpl2-5", "gpl2-7",
++                              "gpm0-0", "gpm0-1", "gpm0-2", "gpm0-3",
++                              "gpm0-4", "gpm0-5", "gpm0-6", "gpm0-7",
++                              "gpm1-0", "gpm1-1", "gpm1-6", "gpm2-2",
++                              "gpm2-3", "gpm2-4", "gpm3-4", "gpm3-5",
++                              "gpm3-6", "gpm3-7", "gpm4-0", "gpm4-1",
++                              "gpm4-2", "gpm4-3", "gpm4-4", "gpm4-5",
++                              "gpm4-6", "gpm4-7", "gpy0-0", "gpy0-1",
++                              "gpy0-2", "gpy0-3", "gpy0-4", "gpy0-5",
++                              "gpy1-0", "gpy1-1", "gpy1-2", "gpy1-3",
++                              "gpy2-1", "gpy3-0", "gpy3-1", "gpy3-2",
++                              "gpy3-3", "gpy3-4", "gpy3-5", "gpy3-6",
++                              "gpy3-7", "gpy4-0", "gpy4-1", "gpy4-2",
++                              "gpy4-3", "gpy4-4", "gpy4-5", "gpy4-6",
++                              "gpy4-7", "gpy5-0", "gpy5-1", "gpy5-2",
++                              "gpy5-3", "gpy5-4", "gpy5-5", "gpy5-6",
++                              "gpy5-7", "gpy6-0", "gpy6-1", "gpy6-2",
++                              "gpy6-3", "gpy6-4", "gpy6-5", "gpy6-6",
++                              "gpy6-7";
++              samsung,pin-con-pdn = <2>;
++              samsung,pin-pud-pdn = <1>;
++      };
++
++      pdn_group_prev_1: pdn-group-prev {
++              samsung,pins = "gpk0-0", "gpk0-1", "gpk0-3", "gpk0-4",
++                              "gpk0-5", "gpk0-6", "gpk1-3", "gpk1-4",
++                              "gpk1-5", "gpk1-6", "gpl0-4", "gpl0-6",
++                              "gpl2-6", "gpy2-0", "gpm3-0", "gpm3-1",
++                              "gpm3-2";
++              samsung,pin-con-pdn = <3>;
++              samsung,pin-pud-pdn = <0>;
++      };
++};
++
++&pinctrl_2 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&pdn_group_in_down_2>;
++
++      pdn_group_in_down_2: pdn-group-in-down {
++              samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
++                              "gpz-4", "gpz-5", "gpz-6";
++              samsung,pin-con-pdn = <2>;
++              samsung,pin-pud-pdn = <1>;
++      };
++};
++
++&pinctrl_3 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&pdn_group_in_down_3>;
++
++      pdn_group_in_down_3: pdn-group-in-down {
++              samsung,pins = "gpv0-0", "gpv0-1", "gpv0-2", "gpv0-3",
++                              "gpv0-4", "gpv0-5", "gpv0-6", "gpv0-7",
++                              "gpv1-0", "gpv1-1", "gpv1-2", "gpv1-3",
++                              "gpv1-4", "gpv1-5", "gpv1-6", "gpv1-7",
++                              "gpv2-0", "gpv2-1", "gpv2-2", "gpv2-3",
++                              "gpv2-4", "gpv2-5", "gpv2-6", "gpv2-7",
++                              "gpv3-0", "gpv3-1", "gpv3-2", "gpv3-3",
++                              "gpv3-4", "gpv3-5", "gpv3-6", "gpv3-7",
++                              "gpv4-0";
++              samsung,pin-con-pdn = <2>;
++              samsung,pin-pud-pdn = <1>;
++      };
++};
++
+ / {
+       model = "Samsung SLP PQ based on Exynos4412";
+       compatible = "samsung,slp_pq", "samsung,exynos4412";
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0333-regulator-Handle-suspend-and-resume-of-regulators.patch b/patches.tizen/0333-regulator-Handle-suspend-and-resume-of-regulators.patch
new file mode 100644 (file)
index 0000000..54b4700
--- /dev/null
@@ -0,0 +1,60 @@
+From 3612c4874088158e07376048d0f680b2f1cf69ee Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 24 Apr 2013 18:58:06 +0200
+Subject: [PATCH 0333/1302] regulator: Handle suspend and resume of regulators
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/regulator/core.c | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index 815d6df..1ab233b 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -3946,6 +3946,32 @@ static const struct file_operations supply_map_fops = {
+ #endif
+ };
++static int regulator_pm_notify(struct notifier_block *nb,
++                                              unsigned long event, void *ptr)
++{
++      int ret;
++
++      switch (event) {
++      case PM_SUSPEND_PREPARE:
++              ret = regulator_suspend_prepare(PM_SUSPEND_MEM);
++              break;
++      case PM_HIBERNATION_PREPARE:
++              ret = regulator_suspend_prepare(PM_SUSPEND_MAX);
++              break;
++      case PM_POST_SUSPEND:
++      case PM_POST_HIBERNATION:
++              ret = regulator_suspend_finish();
++              break;
++      default:
++              return NOTIFY_DONE;
++      }
++
++      if (ret)
++              return NOTIFY_BAD;
++
++      return NOTIFY_OK;
++}
++
+ static int __init regulator_init(void)
+ {
+       int ret;
+@@ -3961,6 +3987,8 @@ static int __init regulator_init(void)
+       regulator_dummy_init();
++      pm_notifier(regulator_pm_notify, 0);
++
+       return ret;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0334-regulator-of-Parse-regulator-state-in-mem-mode-from-.patch b/patches.tizen/0334-regulator-of-Parse-regulator-state-in-mem-mode-from-.patch
new file mode 100644 (file)
index 0000000..3c99b08
--- /dev/null
@@ -0,0 +1,46 @@
+From 66a65cb6865d14a4f4e7f2e8f7a8c1c06bc31472 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 24 Apr 2013 19:01:42 +0200
+Subject: [PATCH 0334/1302] regulator: of: Parse regulator state in mem mode
+ from DT
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/regulator/of_regulator.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
+index 66ca769..cf2d6bf 100644
+--- a/drivers/regulator/of_regulator.c
++++ b/drivers/regulator/of_regulator.c
+@@ -64,6 +64,26 @@ static void of_get_regulation_constraints(struct device_node *np,
+       ramp_delay = of_get_property(np, "regulator-ramp-delay", NULL);
+       if (ramp_delay)
+               constraints->ramp_delay = be32_to_cpu(*ramp_delay);
++
++      if (of_find_property(np, "regulator-mem-fast", NULL)) {
++              constraints->state_mem.enabled = true;
++              constraints->state_mem.mode = REGULATOR_MODE_FAST;
++      }
++
++      if (of_find_property(np, "regulator-mem-on", NULL)) {
++              constraints->state_mem.enabled = true;
++              constraints->state_mem.mode = REGULATOR_MODE_NORMAL;
++      }
++
++      if (of_find_property(np, "regulator-mem-idle", NULL)) {
++              constraints->state_mem.disabled = true;
++              constraints->state_mem.mode = REGULATOR_MODE_IDLE;
++      }
++
++      if (of_find_property(np, "regulator-mem-off", NULL)) {
++              constraints->state_mem.disabled = true;
++              constraints->state_mem.mode = REGULATOR_MODE_STANDBY;
++      }
+ }
+ /**
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0335-regulator-max77686-Add-set_suspend_enable-callback-f.patch b/patches.tizen/0335-regulator-max77686-Add-set_suspend_enable-callback-f.patch
new file mode 100644 (file)
index 0000000..c515ce6
--- /dev/null
@@ -0,0 +1,58 @@
+From a5567732ac7785e34b534564b2328a3d978d68ee Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 25 Apr 2013 15:47:59 +0200
+Subject: [PATCH 0335/1302] regulator: max77686: Add set_suspend_enable
+ callback for buck regulators
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/regulator/max77686.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c
+index 20935b1..0b55f55 100644
+--- a/drivers/regulator/max77686.c
++++ b/drivers/regulator/max77686.c
+@@ -91,6 +91,22 @@ static int max77686_buck_set_suspend_disable(struct regulator_dev *rdev)
+       return 0;
+ }
++static int max77686_buck_set_suspend_enable(struct regulator_dev *rdev)
++{
++      unsigned int val;
++      struct max77686_data *max77686 = rdev_get_drvdata(rdev);
++
++      if (rdev->desc->id == MAX77686_BUCK1)
++              val = MAX77686_OPMODE_MASK;
++      else
++              val = MAX77686_OPMODE_MASK << MAX77686_OPMODE_BUCK234_SHIFT;
++
++      max77686->opmode[rdev->desc->id] = val;
++      return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
++                                rdev->desc->enable_mask,
++                                val);
++}
++
+ /* Some LDOs supports [LPM/Normal]ON mode during suspend state */
+ static int max77686_set_suspend_mode(struct regulator_dev *rdev,
+                                    unsigned int mode)
+@@ -226,6 +242,7 @@ static struct regulator_ops max77686_buck1_ops = {
+       .set_voltage_sel        = regulator_set_voltage_sel_regmap,
+       .set_voltage_time_sel   = regulator_set_voltage_time_sel,
+       .set_suspend_disable    = max77686_buck_set_suspend_disable,
++      .set_suspend_enable     = max77686_buck_set_suspend_enable,
+ };
+ static struct regulator_ops max77686_buck_dvs_ops = {
+@@ -239,6 +256,7 @@ static struct regulator_ops max77686_buck_dvs_ops = {
+       .set_voltage_time_sel   = regulator_set_voltage_time_sel,
+       .set_ramp_delay         = max77686_set_ramp_delay,
+       .set_suspend_disable    = max77686_buck_set_suspend_disable,
++      .set_suspend_enable     = max77686_buck_set_suspend_enable,
+ };
+ #define regulator_desc_ldo(num)               {                               \
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0336-regulator-max77686-Fix-suspend-mode-settings-of-regu.patch b/patches.tizen/0336-regulator-max77686-Fix-suspend-mode-settings-of-regu.patch
new file mode 100644 (file)
index 0000000..2806e30
--- /dev/null
@@ -0,0 +1,183 @@
+From b52bacf45f724d30044c9a80ca915365810f38f5 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Tue, 30 Apr 2013 17:38:19 +0200
+Subject: [PATCH 0336/1302] regulator: max77686: Fix suspend-mode settings of
+ regulators
+
+LDO20, LDO21, LDO22, BUCK8 and BUCK9 regulators provide external pins
+for enable control in addition to I2C control, which is usually used to
+control regulator states in suspend.
+
+BUCK5-BUCK7 do not provide any suspend-mode control.
+
+This patch modifies the driver to account for these factors, making it
+program sleep mode states of regulators correctly.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+
+Conflicts:
+       drivers/regulator/max77686.c
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/regulator/max77686.c | 99 +++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 89 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c
+index 0b55f55..3b9b342 100644
+--- a/drivers/regulator/max77686.c
++++ b/drivers/regulator/max77686.c
+@@ -113,13 +113,38 @@ static int max77686_set_suspend_mode(struct regulator_dev *rdev,
+ {
+       struct max77686_data *max77686 = rdev_get_drvdata(rdev);
+       unsigned int val;
+-      int ret, id = rdev_get_id(rdev);
+-      /* BUCK[5-9] doesn't support this feature */
+-      if (id >= MAX77686_BUCK5)
+-              return 0;
++      switch (mode) {
++      case REGULATOR_MODE_IDLE:                       /* ON in LP Mode */
++              val = 0x2 << MAX77686_OPMODE_SHIFT;
++              break;
++      case REGULATOR_MODE_NORMAL:                     /* ON in Normal Mode */
++              val = 0x3 << MAX77686_OPMODE_SHIFT;
++              break;
++      default:
++              pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n",
++                      rdev->desc->name, mode);
++              return -EINVAL;
++      }
++
++      max77686->opmode[rdev->desc->id] = val;
++      return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
++                                rdev->desc->enable_mask,
++                                val);
++}
++
++/* Some LDOs supports [LPM/Normal]ON mode during suspend state */
++static int max77686_ldo_en_set_suspend_mode(struct regulator_dev *rdev,
++                                   unsigned int mode)
++{
++      struct max77686_data *max77686 = rdev_get_drvdata(rdev);
++      unsigned int val;
++      int ret, id = rdev_get_id(rdev);
+       switch (mode) {
++      case REGULATOR_MODE_STANDBY:            /* OFF when ENLDOx low */
++              val = 0x0 << MAX77686_OPMODE_SHIFT;
++              break;
+       case REGULATOR_MODE_IDLE:                       /* ON in LP Mode */
+               val = 0x2 << MAX77686_OPMODE_SHIFT;
+               break;
+@@ -220,6 +245,18 @@ static struct regulator_ops max77686_ops = {
+       .set_suspend_mode       = max77686_set_suspend_mode,
+ };
++static struct regulator_ops max77686_ldo_en_ops = {
++      .list_voltage           = regulator_list_voltage_linear,
++      .map_voltage            = regulator_map_voltage_linear,
++      .is_enabled             = regulator_is_enabled_regmap,
++      .enable                 = max77686_enable,
++      .disable                = regulator_disable_regmap,
++      .get_voltage_sel        = regulator_get_voltage_sel_regmap,
++      .set_voltage_sel        = regulator_set_voltage_sel_regmap,
++      .set_voltage_time_sel   = regulator_set_voltage_time_sel,
++      .set_suspend_mode       = max77686_ldo_en_set_suspend_mode,
++};
++
+ static struct regulator_ops max77686_ldo_ops = {
+       .list_voltage           = regulator_list_voltage_linear,
+       .map_voltage            = regulator_map_voltage_linear,
+@@ -259,6 +296,17 @@ static struct regulator_ops max77686_buck_dvs_ops = {
+       .set_suspend_enable     = max77686_buck_set_suspend_enable,
+ };
++static struct regulator_ops max77686_buck_ops = {
++      .list_voltage           = regulator_list_voltage_linear,
++      .map_voltage            = regulator_map_voltage_linear,
++      .is_enabled             = regulator_is_enabled_regmap,
++      .enable                 = max77686_enable,
++      .disable                = regulator_disable_regmap,
++      .get_voltage_sel        = regulator_get_voltage_sel_regmap,
++      .set_voltage_sel        = regulator_set_voltage_sel_regmap,
++      .set_voltage_time_sel   = regulator_set_voltage_time_sel,
++};
++
+ #define regulator_desc_ldo(num)               {                               \
+       .name           = "LDO"#num,                                    \
+       .id             = MAX77686_LDO##num,                            \
+@@ -275,6 +323,22 @@ static struct regulator_ops max77686_buck_dvs_ops = {
+       .enable_mask    = MAX77686_OPMODE_MASK                          \
+                       << MAX77686_OPMODE_SHIFT,                       \
+ }
++#define regulator_desc_ldo_en(num)            {                               \
++      .name           = "LDO"#num,                                    \
++      .id             = MAX77686_LDO##num,                            \
++      .ops            = &max77686_ldo_en_ops,                         \
++      .type           = REGULATOR_VOLTAGE,                            \
++      .owner          = THIS_MODULE,                                  \
++      .min_uV         = MAX77686_LDO_MINUV,                           \
++      .uV_step        = MAX77686_LDO_UVSTEP,                          \
++      .ramp_delay     = MAX77686_RAMP_DELAY,                          \
++      .n_voltages     = MAX77686_VSEL_MASK + 1,                       \
++      .vsel_reg       = MAX77686_REG_LDO1CTRL1 + num - 1,             \
++      .vsel_mask      = MAX77686_VSEL_MASK,                           \
++      .enable_reg     = MAX77686_REG_LDO1CTRL1 + num - 1,             \
++      .enable_mask    = MAX77686_OPMODE_MASK                          \
++                      << MAX77686_OPMODE_SHIFT,                       \
++}
+ #define regulator_desc_lpm_ldo(num)   {                               \
+       .name           = "LDO"#num,                                    \
+       .id             = MAX77686_LDO##num,                            \
+@@ -326,7 +390,22 @@ static struct regulator_ops max77686_buck_dvs_ops = {
+ #define regulator_desc_buck(num)              {                       \
+       .name           = "BUCK"#num,                                   \
+       .id             = MAX77686_BUCK##num,                           \
+-      .ops            = &max77686_ops,                                \
++      .ops            = &max77686_buck_ops,                           \
++      .type           = REGULATOR_VOLTAGE,                            \
++      .owner          = THIS_MODULE,                                  \
++      .min_uV         = MAX77686_BUCK_MINUV,                          \
++      .uV_step        = MAX77686_BUCK_UVSTEP,                         \
++      .ramp_delay     = MAX77686_RAMP_DELAY,                          \
++      .n_voltages     = MAX77686_VSEL_MASK + 1,                       \
++      .vsel_reg       = MAX77686_REG_BUCK5OUT + (num - 5) * 2,        \
++      .vsel_mask      = MAX77686_VSEL_MASK,                           \
++      .enable_reg     = MAX77686_REG_BUCK5CTRL + (num - 5) * 2,       \
++      .enable_mask    = MAX77686_OPMODE_MASK,                         \
++}
++#define regulator_desc_buck89(num)            {                       \
++      .name           = "BUCK"#num,                                   \
++      .id             = MAX77686_BUCK##num,                           \
++      .ops            = &max77686_buck1_ops,                          \
+       .type           = REGULATOR_VOLTAGE,                            \
+       .owner          = THIS_MODULE,                                  \
+       .min_uV         = MAX77686_BUCK_MINUV,                          \
+@@ -390,9 +469,9 @@ static struct regulator_desc regulators[] = {
+       regulator_desc_ldo(17),
+       regulator_desc_ldo(18),
+       regulator_desc_ldo(19),
+-      regulator_desc_ldo(20),
+-      regulator_desc_ldo(21),
+-      regulator_desc_ldo(22),
++      regulator_desc_ldo_en(20),
++      regulator_desc_ldo_en(21),
++      regulator_desc_ldo_en(22),
+       regulator_desc_ldo(23),
+       regulator_desc_ldo(24),
+       regulator_desc_ldo(25),
+@@ -404,8 +483,8 @@ static struct regulator_desc regulators[] = {
+       regulator_desc_buck(5),
+       regulator_desc_buck(6),
+       regulator_desc_buck(7),
+-      regulator_desc_buck(8),
+-      regulator_desc_buck(9),
++      regulator_desc_buck89(8),
++      regulator_desc_buck89(9),
+ };
+ #ifdef CONFIG_OF
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0337-ARM-dts-exynos4412-slp_pq-Add-regulator-states-in-me.patch b/patches.tizen/0337-ARM-dts-exynos4412-slp_pq-Add-regulator-states-in-me.patch
new file mode 100644 (file)
index 0000000..040b16b
--- /dev/null
@@ -0,0 +1,283 @@
+From 51f7e3ecf704a52daadcb87da4af7e9b94709b93 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 24 Apr 2013 19:02:29 +0200
+Subject: [PATCH 0337/1302] ARM: dts: exynos4412-slp_pq: Add regulator states
+ in mem mode
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 33 +++++++++++++++++++++++++++++++++
+ 1 file changed, 33 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index b91b1e3..ec50285 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -545,6 +545,7 @@
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
++                                      regulator-mem-on;
+                               };
+                               ldo2_reg: ldo@2 {
+@@ -553,6 +554,7 @@
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+                                       regulator-always-on;
++                                      regulator-mem-on;
+                               };
+                               ldo3_reg: ldo@3 {
+@@ -561,6 +563,7 @@
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
++                                      regulator-mem-on;
+                               };
+                               ldo4_reg: ldo@4 {
+@@ -569,6 +572,7 @@
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                                       regulator-always-on;
++                                      regulator-mem-on;
+                               };
+                               ldo5_reg: ldo@5 {
+@@ -577,6 +581,7 @@
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
++                                      regulator-mem-on;
+                               };
+                               ldo6_reg: ldo@6 {
+@@ -585,6 +590,7 @@
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
++                                      regulator-mem-on;
+                               };
+                               ldo7_reg: ldo@7 {
+@@ -593,6 +599,7 @@
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
++                                      regulator-mem-on;
+                               };
+                               ldo8_reg: ldo@8 {
+@@ -600,6 +607,7 @@
+                                       regulator-name = "VMIPI_1.0V";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
++                                      regulator-mem-off;
+                               };
+                               ldo9_reg: ldo@9 {
+@@ -607,6 +615,7 @@
+                                       regulator-name = "CAM_ISP_MIPI_1.2V";
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
++                                      regulator-mem-idle;
+                               };
+                               ldo10_reg: ldo@10 {
+@@ -614,6 +623,7 @@
+                                       regulator-name = "VMIPI_1.8V";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
++                                      regulator-mem-off;
+                               };
+                               ldo11_reg: ldo@11 {
+@@ -622,6 +632,7 @@
+                                       regulator-min-microvolt = <1950000>;
+                                       regulator-max-microvolt = <1950000>;
+                                       regulator-always-on;
++                                      regulator-mem-off;
+                               };
+                               ldo12_reg: ldo@12 {
+@@ -629,6 +640,7 @@
+                                       regulator-name = "VUOTG_3.0V";
+                                       regulator-min-microvolt = <3000000>;
+                                       regulator-max-microvolt = <3000000>;
++                                      regulator-mem-off;
+                               };
+                               ldo13_reg: ldo@13 {
+@@ -636,6 +648,7 @@
+                                       regulator-name = "NFC_AVDD_1.8V";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
++                                      regulator-mem-idle;
+                               };
+                               ldo14_reg: ldo@14 {
+@@ -644,6 +657,7 @@
+                                       regulator-min-microvolt = <1950000>;
+                                       regulator-max-microvolt = <1950000>;
+                                       regulator-always-on;
++                                      regulator-mem-off;
+                               };
+                               ldo15_reg: ldo@15 {
+@@ -652,6 +666,7 @@
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
++                                      regulator-mem-off;
+                               };
+                               ldo16_reg: ldo@16 {
+@@ -660,6 +675,7 @@
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
++                                      regulator-mem-off;
+                               };
+                               ldo17_reg: ldo@17 {
+@@ -667,6 +683,7 @@
+                                       regulator-name = "CAM_SENSOR_CORE_1.2V";
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
++                                      regulator-mem-idle;
+                               };
+                               ldo18_reg: ldo@18 {
+@@ -674,6 +691,7 @@
+                                       regulator-name = "CAM_ISP_SEN_IO_1.8V";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
++                                      regulator-mem-idle;
+                               };
+                               ldo19_reg: ldo@19 {
+@@ -681,6 +699,7 @@
+                                       regulator-name = "VT_CAM_1.8V";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
++                                      regulator-mem-idle;
+                               };
+                               ldo20_reg: ldo@20 {
+@@ -688,6 +707,7 @@
+                                       regulator-name = "VDDQ_PRE_1.8V";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
++                                      regulator-mem-idle;
+                               };
+                               ldo21_reg: ldo@21 {
+@@ -695,6 +715,7 @@
+                                       regulator-name = "VTF_2.8V";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
++                                      regulator-mem-idle;
+                               };
+                               ldo22_reg: ldo@22 {
+@@ -703,6 +724,7 @@
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                                       regulator-always-on;
++                                      regulator-mem-off;
+                               };
+                               ldo23_reg: ldo@23 {
+@@ -710,6 +732,7 @@
+                                       regulator-name = "TSP_AVDD_3.3V";
+                                       regulator-min-microvolt = <3300000>;
+                                       regulator-max-microvolt = <3300000>;
++                                      regulator-mem-idle;
+                               };
+                               ldo24_reg: ldo@24 {
+@@ -717,6 +740,7 @@
+                                       regulator-name = "TSP_VDD_1.8V";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
++                                      regulator-mem-idle;
+                               };
+                               ldo25_reg: ldo@25 {
+@@ -724,6 +748,7 @@
+                                       regulator-name = "LCD_VCC_3.3V";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
++                                      regulator-mem-idle;
+                               };
+                               ldo26_reg: ldo@26 {
+@@ -731,6 +756,7 @@
+                                       regulator-name = "MOTOR_VCC_3.0V";
+                                       regulator-min-microvolt = <3000000>;
+                                       regulator-max-microvolt = <3000000>;
++                                      regulator-mem-idle;
+                               };
+                               buck1_reg: buck@1 {
+@@ -740,6 +766,7 @@
+                                       regulator-max-microvolt = <1100000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
++                                      regulator-mem-off;
+                               };
+                               buck2_reg: buck@2 {
+@@ -749,6 +776,7 @@
+                                       regulator-max-microvolt = <1500000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
++                                      regulator-mem-off;
+                               };
+                               buck3_reg: buck@3 {
+@@ -758,6 +786,7 @@
+                                       regulator-max-microvolt = <1150000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
++                                      regulator-mem-off;
+                               };
+                               buck4_reg: buck@4 {
+@@ -766,6 +795,7 @@
+                                       regulator-min-microvolt = <850000>;
+                                       regulator-max-microvolt = <1150000>;
+                                       regulator-boot-on;
++                                      regulator-mem-off;
+                               };
+                               buck5_reg: buck@5 {
+@@ -783,6 +813,7 @@
+                                       regulator-max-microvolt = <1350000>;
+                                       regulator-always-on;
+                               };
++
+                               buck7_reg: buck@7 {
+                                       regulator-compatible = "BUCK7";
+                                       regulator-name = "VCC_SUB_2.0V";
+@@ -797,6 +828,7 @@
+                                       regulator-min-microvolt = <2850000>;
+                                       regulator-max-microvolt = <2850000>;
+                                       regulator-always-on;
++                                      regulator-mem-off;
+                               };
+                               buck9_reg: buck@9 {
+@@ -804,6 +836,7 @@
+                                       regulator-name = "CAM_ISP_CORE_1.2V";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1200000>;
++                                      regulator-mem-off;
+                               };
+                       };
+               };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0338-clocksource-exynos_mct-Register-sched_clock.patch b/patches.tizen/0338-clocksource-exynos_mct-Register-sched_clock.patch
new file mode 100644 (file)
index 0000000..dac8f8d
--- /dev/null
@@ -0,0 +1,52 @@
+From 2ae0363b0323b68e7ffb22e6e028962169d7aca8 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 8 May 2013 12:02:43 +0200
+Subject: [PATCH 0338/1302] clocksource: exynos_mct: Register sched_clock
+
+This patch adds sched_clock registration to Exynos MCT driver to
+improve scheduler precision by providing a high resolution clock source
+for scheduling purposes.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+
+Conflicts:
+       drivers/clocksource/exynos_mct.c
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clocksource/exynos_mct.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
+index 662fcc0..9c2f9ab 100644
+--- a/drivers/clocksource/exynos_mct.c
++++ b/drivers/clocksource/exynos_mct.c
+@@ -25,6 +25,7 @@
+ #include <linux/clocksource.h>
+ #include <asm/localtimer.h>
++#include <asm/sched_clock.h>
+ #include <asm/mach/time.h>
+ #define EXYNOS4_MCTREG(x)             (x)
+@@ -190,10 +191,17 @@ struct clocksource mct_frc = {
+       .resume         = exynos4_frc_resume,
+ };
++static u32 notrace exynos4_mct_read_sched_clock(void)
++{
++      return __raw_readl(reg_base + EXYNOS4_MCT_G_CNT_L);
++}
++
+ static void __init exynos4_clocksource_init(void)
+ {
+       exynos4_mct_frc_start(0, 0);
++      setup_sched_clock(exynos4_mct_read_sched_clock, 32, clk_rate);
++
+       if (clocksource_register_hz(&mct_frc, clk_rate))
+               panic("%s: can't register clocksource\n", mct_frc.name);
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0339-tty-serial-samsung-Remove-useless-checks-in-suspend-.patch b/patches.tizen/0339-tty-serial-samsung-Remove-useless-checks-in-suspend-.patch
new file mode 100644 (file)
index 0000000..3b0a803
--- /dev/null
@@ -0,0 +1,75 @@
+From fd312d212145a18638622d590ae8697ad4f74919 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 8 May 2013 18:30:30 +0200
+Subject: [PATCH 0339/1302] tty: serial: samsung: Remove useless checks in
+ suspend/resume callbacks
+
+Since uart_port struct exists through whole driver lifetime, there is no
+need to check if it is non-NULL in suspend/resume callbacks.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/tty/serial/samsung.c | 31 +++++++++++++------------------
+ 1 file changed, 13 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
+index 0c8a9fa..12bb5d8 100644
+--- a/drivers/tty/serial/samsung.c
++++ b/drivers/tty/serial/samsung.c
+@@ -1307,8 +1307,7 @@ static int s3c24xx_serial_suspend(struct device *dev)
+ {
+       struct uart_port *port = s3c24xx_dev_to_port(dev);
+-      if (port)
+-              uart_suspend_port(&s3c24xx_uart_drv, port);
++      uart_suspend_port(&s3c24xx_uart_drv, port);
+       return 0;
+ }
+@@ -1318,13 +1317,11 @@ static int s3c24xx_serial_resume(struct device *dev)
+       struct uart_port *port = s3c24xx_dev_to_port(dev);
+       struct s3c24xx_uart_port *ourport = to_ourport(port);
+-      if (port) {
+-              clk_prepare_enable(ourport->clk);
+-              s3c24xx_serial_resetport(port, s3c24xx_port_to_cfg(port));
+-              clk_disable_unprepare(ourport->clk);
++      clk_prepare_enable(ourport->clk);
++      s3c24xx_serial_resetport(port, s3c24xx_port_to_cfg(port));
++      clk_disable_unprepare(ourport->clk);
+-              uart_resume_port(&s3c24xx_uart_drv, port);
+-      }
++      uart_resume_port(&s3c24xx_uart_drv, port);
+       return 0;
+ }
+@@ -1333,16 +1330,14 @@ static int s3c24xx_serial_resume_noirq(struct device *dev)
+ {
+       struct uart_port *port = s3c24xx_dev_to_port(dev);
+-      if (port) {
+-              /* restore IRQ mask */
+-              if (s3c24xx_serial_has_interrupt_mask(port)) {
+-                      unsigned int uintm = 0xf;
+-                      if (tx_enabled(port))
+-                              uintm &= ~S3C64XX_UINTM_TXD_MSK;
+-                      if (rx_enabled(port))
+-                              uintm &= ~S3C64XX_UINTM_RXD_MSK;
+-                      wr_regl(port, S3C64XX_UINTM, uintm);
+-              }
++      /* restore IRQ mask */
++      if (s3c24xx_serial_has_interrupt_mask(port)) {
++              unsigned int uintm = 0xf;
++              if (tx_enabled(port))
++                      uintm &= ~S3C64XX_UINTM_TXD_MSK;
++              if (rx_enabled(port))
++                      uintm &= ~S3C64XX_UINTM_RXD_MSK;
++              wr_regl(port, S3C64XX_UINTM, uintm);
+       }
+       return 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0340-ARM-firmware-Add-L2X0-resume-operation.patch b/patches.tizen/0340-ARM-firmware-Add-L2X0-resume-operation.patch
new file mode 100644 (file)
index 0000000..efe1b5d
--- /dev/null
@@ -0,0 +1,29 @@
+From 087205970a3cb1b0856a52a702094bd85d716b42 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 5 Jun 2013 17:38:17 +0200
+Subject: [PATCH 0340/1302] ARM: firmware: Add L2X0 resume operation
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/include/asm/firmware.h | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm/include/asm/firmware.h b/arch/arm/include/asm/firmware.h
+index f459d25..1ee7523 100644
+--- a/arch/arm/include/asm/firmware.h
++++ b/arch/arm/include/asm/firmware.h
+@@ -38,6 +38,10 @@ struct firmware_ops {
+        */
+       int (*l2x0_init)(void);
+       /*
++       * Restores state of L2 cache after power down
++       */
++      int (*l2x0_resume)(void);
++      /*
+        * Suspends the system
+        */
+       int (*suspend)(unsigned long resume_addr);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0341-ARM-EXYNOS-firmware-Implement-l2x0_resume-operation.patch b/patches.tizen/0341-ARM-EXYNOS-firmware-Implement-l2x0_resume-operation.patch
new file mode 100644 (file)
index 0000000..32ee415
--- /dev/null
@@ -0,0 +1,53 @@
+From 325da1189ff8c8da69704ccec9f573c268300ef2 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 5 Jun 2013 17:38:51 +0200
+Subject: [PATCH 0341/1302] ARM: EXYNOS: firmware: Implement l2x0_resume
+ operation
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/mach-exynos/firmware.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
+index 3f98bf7..bce0b97 100644
+--- a/arch/arm/mach-exynos/firmware.c
++++ b/arch/arm/mach-exynos/firmware.c
+@@ -15,6 +15,7 @@
+ #include <linux/of_address.h>
+ #include <asm/firmware.h>
++#include <asm/hardware/cache-l2x0.h>
+ #include <mach/map.h>
+@@ -49,6 +50,17 @@ static int exynos_l2x0_init(void)
+       return 0;
+ }
++static int exynos_l2x0_resume(void)
++{
++      exynos_smc(SMC_CMD_L2X0SETUP1, l2x0_saved_regs.tag_latency,
++                 l2x0_saved_regs.data_latency, l2x0_saved_regs.prefetch_ctrl);
++      exynos_smc(SMC_CMD_L2X0SETUP2, 0x3, 0x7C470001, 0xC200FFFF);
++      exynos_smc(SMC_CMD_L2X0INVALL, 0, 0, 0);
++      exynos_smc(SMC_CMD_L2X0CTRL, 1, 0, 0);
++
++      return 0;
++}
++
+ static int exynos_suspend(unsigned long resume_addr)
+ {
+       writel(EXYNOS_SLEEP_MAGIC, S5P_VA_SYSRAM_NS + 0xC);
+@@ -77,6 +89,7 @@ static const struct firmware_ops exynos_firmware_ops = {
+       .set_cpu_boot_addr      = exynos_set_cpu_boot_addr,
+       .cpu_boot               = exynos_cpu_boot,
+       .l2x0_init      = exynos_l2x0_init,
++      .l2x0_resume    = exynos_l2x0_resume,
+       .suspend        = exynos_suspend,
+       .resume         = exynos_resume,
+       .c15resume      = exynos_c15resume,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0342-ARM-EXYNOS-Move-L2X0-cache-resume-to-SoC-PM-code.patch b/patches.tizen/0342-ARM-EXYNOS-Move-L2X0-cache-resume-to-SoC-PM-code.patch
new file mode 100644 (file)
index 0000000..7352f5e
--- /dev/null
@@ -0,0 +1,134 @@
+From b9bc6744377a2962e77f08daa4d6cf3cf86d1ed6 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 5 Jun 2013 17:39:33 +0200
+Subject: [PATCH 0342/1302] ARM: EXYNOS: Move L2X0 cache resume to SoC PM code
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/mach-exynos/common.c     |  5 -----
+ arch/arm/mach-exynos/common.h     |  1 -
+ arch/arm/mach-exynos/pm.c         |  4 +++-
+ arch/arm/plat-samsung/s5p-sleep.S | 43 ---------------------------------------
+ 4 files changed, 3 insertions(+), 50 deletions(-)
+
+diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
+index 02fb4a1..a8b62e4 100644
+--- a/arch/arm/mach-exynos/common.c
++++ b/arch/arm/mach-exynos/common.c
+@@ -567,8 +567,6 @@ static int __init exynos4_l2x0_cache_init(void)
+               ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK);
+               if (ret)
+                       return ret;
+-              l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs);
+-              clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long));
+               return 0;
+       }
+@@ -586,8 +584,6 @@ static int __init exynos4_l2x0_cache_init(void)
+               l2x0_saved_regs.pwr_ctrl =
+                       (L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN);
+-              l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs);
+-
+               __raw_writel(l2x0_saved_regs.tag_latency,
+                               S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL);
+               __raw_writel(l2x0_saved_regs.data_latency,
+@@ -601,7 +597,6 @@ static int __init exynos4_l2x0_cache_init(void)
+               __raw_writel(l2x0_saved_regs.pwr_ctrl,
+                               S5P_VA_L2CC + L2X0_POWER_CTRL);
+-              clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long));
+               clean_dcache_area(&l2x0_saved_regs, sizeof(struct l2x0_regs));
+       }
+diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
+index 11fc1e2..eeed0c5 100644
+--- a/arch/arm/mach-exynos/common.h
++++ b/arch/arm/mach-exynos/common.h
+@@ -91,7 +91,6 @@ enum sys_powerdown {
+       NUM_SYS_POWERDOWN,
+ };
+-extern unsigned long l2x0_regs_phys;
+ struct exynos_pmu_conf {
+       void __iomem *reg;
+       unsigned int val[NUM_SYS_POWERDOWN];
+diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
+index e195e3e..e46ac76 100644
+--- a/arch/arm/mach-exynos/pm.c
++++ b/arch/arm/mach-exynos/pm.c
+@@ -272,7 +272,9 @@ static int exynos_pm_suspend(void)
+ static void exynos_pm_resume(void)
+ {
+       unsigned long tmp;
+-
++#ifdef CONFIG_CACHE_L2X0
++      outer_resume();
++#endif
+       /*
+        * If PMU failed while entering sleep mode, WFI will be
+        * ignored by PMU and then exiting cpu_do_idle().
+diff --git a/arch/arm/plat-samsung/s5p-sleep.S b/arch/arm/plat-samsung/s5p-sleep.S
+index a030e73..16a0701 100644
+--- a/arch/arm/plat-samsung/s5p-sleep.S
++++ b/arch/arm/plat-samsung/s5p-sleep.S
+@@ -25,17 +25,6 @@
+ #include <asm/asm-offsets.h>
+ #include <asm/hardware/cache-l2x0.h>
+-#define CPU_MASK      0xff0ffff0
+-#define CPU_CORTEX_A9 0x410fc090
+-
+-/*
+- *     The following code is located into the .data section. This is to
+- *     allow l2x0_regs_phys to be accessed with a relative load while we
+- *     can't rely on any MMU translation. We could have put l2x0_regs_phys
+- *     in the .text section as well, but some setups might insist on it to
+- *     be truly read-only. (Reference from: arch/arm/kernel/sleep.S)
+- */
+-      .data
+       .align
+       /*
+@@ -53,37 +42,5 @@
+        */
+ ENTRY(s3c_cpu_resume)
+-#ifdef CONFIG_CACHE_L2X0
+-      mrc     p15, 0, r0, c0, c0, 0
+-      ldr     r1, =CPU_MASK
+-      and     r0, r0, r1
+-      ldr     r1, =CPU_CORTEX_A9
+-      cmp     r0, r1
+-      bne     resume_l2on
+-      adr     r0, l2x0_regs_phys
+-      ldr     r0, [r0]
+-      ldr     r1, [r0, #L2X0_R_PHY_BASE]
+-      ldr     r2, [r1, #L2X0_CTRL]
+-      tst     r2, #0x1
+-      bne     resume_l2on
+-      ldr     r2, [r0, #L2X0_R_AUX_CTRL]
+-      str     r2, [r1, #L2X0_AUX_CTRL]
+-      ldr     r2, [r0, #L2X0_R_TAG_LATENCY]
+-      str     r2, [r1, #L2X0_TAG_LATENCY_CTRL]
+-      ldr     r2, [r0, #L2X0_R_DATA_LATENCY]
+-      str     r2, [r1, #L2X0_DATA_LATENCY_CTRL]
+-      ldr     r2, [r0, #L2X0_R_PREFETCH_CTRL]
+-      str     r2, [r1, #L2X0_PREFETCH_CTRL]
+-      ldr     r2, [r0, #L2X0_R_PWR_CTRL]
+-      str     r2, [r1, #L2X0_POWER_CTRL]
+-      mov     r2, #1
+-      str     r2, [r1, #L2X0_CTRL]
+-resume_l2on:
+-#endif
+       b       cpu_resume
+ ENDPROC(s3c_cpu_resume)
+-#ifdef CONFIG_CACHE_L2X0
+-      .globl l2x0_regs_phys
+-l2x0_regs_phys:
+-      .long   0
+-#endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0343-ARM-EXYNOS-pm-Add-support-for-firmware-based-L2X0-re.patch b/patches.tizen/0343-ARM-EXYNOS-pm-Add-support-for-firmware-based-L2X0-re.patch
new file mode 100644 (file)
index 0000000..e0892ec
--- /dev/null
@@ -0,0 +1,37 @@
+From bc020f7885f58b656b584902fe59cde2eb24a7ab Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 5 Jun 2013 17:40:11 +0200
+Subject: [PATCH 0343/1302] ARM: EXYNOS: pm: Add support for firmware-based
+ L2X0 resume
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/mach-exynos/pm.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
+index e46ac76..d5bac0d 100644
+--- a/arch/arm/mach-exynos/pm.c
++++ b/arch/arm/mach-exynos/pm.c
+@@ -21,6 +21,7 @@
+ #include <linux/clk.h>
+ #include <asm/cacheflush.h>
++#include <asm/firmware.h>
+ #include <asm/hardware/cache-l2x0.h>
+ #include <asm/smp_scu.h>
+@@ -273,7 +274,8 @@ static void exynos_pm_resume(void)
+ {
+       unsigned long tmp;
+ #ifdef CONFIG_CACHE_L2X0
+-      outer_resume();
++      if (call_firmware_op(l2x0_resume) < 0)
++              outer_resume();
+ #endif
+       /*
+        * If PMU failed while entering sleep mode, WFI will be
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0344-ARM-EXYNOS-firmware-Surround-l2x0-ops-with-an-ifdef.patch b/patches.tizen/0344-ARM-EXYNOS-firmware-Surround-l2x0-ops-with-an-ifdef.patch
new file mode 100644 (file)
index 0000000..0505717
--- /dev/null
@@ -0,0 +1,46 @@
+From 8e82301bfa5d5e79b45c9b51bd661bde3e89c6cb Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 5 Jun 2013 17:53:37 +0200
+Subject: [PATCH 0344/1302] ARM: EXYNOS: firmware: Surround l2x0 ops with an
+ ifdef
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/mach-exynos/firmware.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
+index bce0b97..e224ae1 100644
+--- a/arch/arm/mach-exynos/firmware.c
++++ b/arch/arm/mach-exynos/firmware.c
+@@ -43,6 +43,7 @@ static int exynos_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
+       return 0;
+ }
++#ifdef CONFIG_CACHE_L2X0
+ static int exynos_l2x0_init(void)
+ {
+       exynos_smc(SMC_CMD_L2X0INVALL, 0, 0, 0);
+@@ -60,6 +61,7 @@ static int exynos_l2x0_resume(void)
+       return 0;
+ }
++#endif
+ static int exynos_suspend(unsigned long resume_addr)
+ {
+@@ -88,8 +90,10 @@ static const struct firmware_ops exynos_firmware_ops = {
+       .do_idle                = exynos_do_idle,
+       .set_cpu_boot_addr      = exynos_set_cpu_boot_addr,
+       .cpu_boot               = exynos_cpu_boot,
++#ifdef CONFIG_CACHE_L2X0
+       .l2x0_init      = exynos_l2x0_init,
+       .l2x0_resume    = exynos_l2x0_resume,
++#endif
+       .suspend        = exynos_suspend,
+       .resume         = exynos_resume,
+       .c15resume      = exynos_c15resume,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0345-charger_manager-Workaround-for-supporting-platform-d.patch b/patches.tizen/0345-charger_manager-Workaround-for-supporting-platform-d.patch
new file mode 100644 (file)
index 0000000..d264d04
--- /dev/null
@@ -0,0 +1,166 @@
+From 18a4007e37d870959b877153e0e10cd7d6a9f5a7 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Mon, 10 Jun 2013 16:01:24 +0900
+Subject: [PATCH 0345/1302] charger_manager: Workaround for supporting platform
+ data without DT parsing.
+
+All data will be move into DT later.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/power/charger-manager.c | 115 +++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 114 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c
+index 98de1dd..3264fd8 100644
+--- a/drivers/power/charger-manager.c
++++ b/drivers/power/charger-manager.c
+@@ -23,6 +23,7 @@
+ #include <linux/power/charger-manager.h>
+ #include <linux/regulator/consumer.h>
+ #include <linux/sysfs.h>
++#include <linux/of.h>
+ static const char * const default_event_names[] = {
+       [CM_EVENT_UNKNOWN] = "Unknown",
+@@ -1451,9 +1452,118 @@ err:
+       return ret;
+ }
++/*
++ * Charger driver platform data
++ * To do : Should be transferred to DT.
++ */
++
++static int thermistor_ck(int *mC)
++{
++      return 0;
++}
++
++static char *charger_stats[] = {
++#if defined(CONFIG_CHARGER_MAX77693)
++      "max77693-charger",
++#endif
++      NULL,
++};
++
++#define BATT_CHARGING_SOURCE_TA               2
++#define BATT_CHARGING_SOURCE_USB      3
++#define BATT_CHARGING_SOURCE_SLOW_TA  4
++#define BATT_CHARGING_SOURCE_FAST_TA  5
++#define BATT_CHARGING_SOURCE_MHL_TA   6
++
++struct charger_cable charger_cable_vinchg1[] = {
++      {
++              .extcon_name    = "max77693-muic",
++              .name           = "USB",
++              .min_uA         = 475000,
++              .max_uA         = 475000 + 25000,
++      }, {
++              .extcon_name    = "max77693-muic",
++              .name           = "TA",
++              .min_uA         = 650000,
++              .max_uA         = 650000 + 25000,
++      }, {
++              .extcon_name    = "max77693-muic",
++              .name           = "Slow-charger",
++              .min_uA         = 650000,
++              .max_uA         = 650000 + 25000,
++      }, {
++              .extcon_name    = "max77693-muic",
++              .name           = "Fast-charger",
++              .min_uA         = 650000,
++              .max_uA         = 650000 + 25000,
++      }, {
++              .extcon_name    = "max77693-muic",
++              .name           = "MHL",
++              .min_uA         = 475000,
++              .max_uA         = 475000 + 25000,
++      },
++};
++static struct charger_regulator regulators[] = {
++      {
++              .regulator_name = "vinchg1",
++              .cables         = charger_cable_vinchg1,
++              .num_cables     = ARRAY_SIZE(charger_cable_vinchg1),
++      },
++};
++
++static struct charger_desc cm_drv_data = {
++      .psy_name               = "battery",
++      .polling_mode           = CM_POLL_EXTERNAL_POWER_ONLY,
++      .polling_interval_ms    = 30000,
++      .fullbatt_vchkdrop_ms   = 30000,
++      .fullbatt_vchkdrop_uV   = 150000,
++      .fullbatt_uV            = 4200000,
++      .fullbatt_soc           = 100,
++      .fullbatt_full_capacity = 0,
++
++      .battery_present        = CM_CHARGER_STAT,
++      .psy_charger_stat       = charger_stats,
++      .num_charger_regulators = 1,
++      .psy_fuel_gauge         = "max170xx_battery",
++      .charger_regulators     = regulators,
++      .num_charger_regulators = ARRAY_SIZE(regulators),
++
++      .temperature_out_of_range       = thermistor_ck,
++      .measure_battery_temp   = true,
++
++      .charging_max_duration_ms       = (6 * 60 * 60 * 1000),  /* 6hr */
++      .discharging_max_duration_ms    = (1.5 * 60 * 60 * 1000),/* 1.5hr */
++};
++
++#ifdef CONFIG_OF
++static struct of_device_id charger_manager_match[] = {
++      {
++              .compatible = "charger-manager",
++              .data   = (void *)&cm_drv_data,
++      },
++      {},
++};
++#endif
++
++static inline struct charger_desc *cm_get_drv_data(
++                              struct platform_device *pdev)
++{
++#ifdef CONFIG_OF
++      if (pdev->dev.of_node) {
++              const struct of_device_id *match;
++              match = of_match_node(charger_manager_match,
++                                      pdev->dev.of_node);
++              if (!match)
++                      return NULL;
++              return (struct charger_desc *)match->data;
++      }
++#endif
++      return (struct charger_desc *)dev_get_platdata(&pdev->dev);
++}
++
+ static int charger_manager_probe(struct platform_device *pdev)
+ {
+-      struct charger_desc *desc = dev_get_platdata(&pdev->dev);
++      struct charger_desc *desc;
+       struct charger_manager *cm;
+       int ret = 0, i = 0;
+       int j = 0;
+@@ -1470,6 +1580,8 @@ static int charger_manager_probe(struct platform_device *pdev)
+               }
+       }
++      desc = cm_get_drv_data(pdev);
++
+       if (!desc) {
+               dev_err(&pdev->dev, "No platform data (desc) found.\n");
+               ret = -ENODEV;
+@@ -1861,6 +1973,7 @@ static struct platform_driver charger_manager_driver = {
+               .name = "charger-manager",
+               .owner = THIS_MODULE,
+               .pm = &charger_manager_pm,
++              .of_match_table = charger_manager_match,
+       },
+       .probe = charger_manager_probe,
+       .remove = charger_manager_remove,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0346-power-charger-manager-regulator_get-never-returns-NU.patch b/patches.tizen/0346-power-charger-manager-regulator_get-never-returns-NU.patch
new file mode 100644 (file)
index 0000000..e48a9dd
--- /dev/null
@@ -0,0 +1,37 @@
+From bf929decc5d2e46337fa7b1a5e427c92834a3924 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Tue, 16 Jul 2013 17:19:13 +0900
+Subject: [PATCH 0346/1302] power: charger-manager: regulator_get() never
+ returns NULL.
+
+This patch fixes return value checking of regulator_get() in charger-manager
+driver. The API, regulator_get(), returns ERR_PTR() when it fails to get
+regulator with given name, not NULL.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/power/charger-manager.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c
+index 3264fd8..4092bd8 100644
+--- a/drivers/power/charger-manager.c
++++ b/drivers/power/charger-manager.c
+@@ -1243,11 +1243,10 @@ static int charger_manager_register_extcon(struct charger_manager *cm)
+               charger->consumer = regulator_get(cm->dev,
+                                       charger->regulator_name);
+-              if (charger->consumer == NULL) {
++              if (IS_ERR(charger->consumer)) {
+                       dev_err(cm->dev, "Cannot find charger(%s)n",
+                                       charger->regulator_name);
+-                      ret = -EINVAL;
+-                      goto err;
++                      return PTR_ERR(charger->consumer);
+               }
+               charger->cm = cm;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0347-power-charger-manager-Fix-a-bug-when-it-unregisters-.patch b/patches.tizen/0347-power-charger-manager-Fix-a-bug-when-it-unregisters-.patch
new file mode 100644 (file)
index 0000000..657472b
--- /dev/null
@@ -0,0 +1,38 @@
+From 3c898d2db18fd37887c70d0882af65e9d15d9d28 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Tue, 16 Jul 2013 17:22:29 +0900
+Subject: [PATCH 0347/1302] power: charger-manager: Fix a bug when it
+ unregisters notifier block of extcon.
+
+This patch prevents NULL pointer error cauesed by unregistering unregistered
+exton notifier block. At the probing time of charger manager, it tries to
+remove extcon notifier block when it fails to initialize them. It has to be
+applied for only registered one. Otherwise, it'd make kernel panic. To make it
+work right, it checks extcon_specific_cable_nb's extcon_dev node. If extcon
+cable notifier block was registered successfully, it has proper extcon_dev
+pointer if not so it has NULL pointer.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/power/charger-manager.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c
+index 4092bd8..7946b8a 100644
+--- a/drivers/power/charger-manager.c
++++ b/drivers/power/charger-manager.c
+@@ -1800,7 +1800,9 @@ err_reg_extcon:
+               charger = &desc->charger_regulators[i];
+               for (j = 0; j < charger->num_cables; j++) {
+                       struct charger_cable *cable = &charger->cables[j];
+-                      extcon_unregister_interest(&cable->extcon_dev);
++                      /* Remove notifier block if only edev exists */
++                      if (cable->extcon_dev.edev)
++                              extcon_unregister_interest(&cable->extcon_dev);
+               }
+               regulator_put(desc->charger_regulators[i].consumer);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0348-ARM-config-Update-tizen_defconfig.patch b/patches.tizen/0348-ARM-config-Update-tizen_defconfig.patch
new file mode 100644 (file)
index 0000000..89ff991
--- /dev/null
@@ -0,0 +1,46 @@
+From 5ae0850e45834a22b34d102c788bbc76ae8410fc Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Tue, 16 Jul 2013 17:56:59 +0900
+Subject: [PATCH 0348/1302] ARM: config: Update tizen_defconfig.
+
+Enable CONFIG_CHARGER_MANAGER, CONFIG_EXTCON
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_defconfig | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index 453ca9f..6aaec32 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -1722,7 +1722,7 @@ CONFIG_BATTERY_MAX17042=y
+ # CONFIG_CHARGER_MAX8903 is not set
+ # CONFIG_CHARGER_LP8727 is not set
+ # CONFIG_CHARGER_GPIO is not set
+-# CONFIG_CHARGER_MANAGER is not set
++CONFIG_CHARGER_MANAGER=y
+ CONFIG_CHARGER_MAX8997=y
+ CONFIG_CHARGER_MAX77693=y
+ # CONFIG_CHARGER_BQ2415X is not set
+@@ -2821,7 +2821,15 @@ CONFIG_EXYNOS_IOMMU=y
+ # Rpmsg drivers
+ #
+ # CONFIG_PM_DEVFREQ is not set
+-# CONFIG_EXTCON is not set
++CONFIG_EXTCON=y
++
++#
++# Extcon Device Drivers
++#
++CONFIG_EXTCON_GPIO=y
++CONFIG_EXTCON_ADC_JACK=y
++CONFIG_EXTCON_MAX77693=y
++CONFIG_EXTCON_MAX8997=y
+ # CONFIG_MEMORY is not set
+ CONFIG_IIO=y
+ CONFIG_IIO_BUFFER=y
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0349-ARM-DTS-update-device-tree-for-for-charger_manager.patch b/patches.tizen/0349-ARM-DTS-update-device-tree-for-for-charger_manager.patch
new file mode 100644 (file)
index 0000000..4fd0013
--- /dev/null
@@ -0,0 +1,53 @@
+From 17f8de659695026ecd2f2cbc9da9665e20dd32ed Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Tue, 16 Jul 2013 17:58:14 +0900
+Subject: [PATCH 0349/1302] ARM: DTS: update device tree for for
+ charger_manager.
+
+Set supply regulator for charger manager.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index ec50285..ab09bd2 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -858,16 +858,16 @@
+                       reg = <0x66>;
+                       regulators {
+-                              esafeout@1 {
++                              esafeout1_reg: esafeout@1 {
+                                       regulator-compatible = "ESAFEOUT1";
+                                       regulator-name = "ESAFEOUT1";
+                                       regulator-boot-on;
+                               };
+-                              esafeout@2 {
++                              esafeout2_reg: esafeout@2 {
+                                       regulator-compatible = "ESAFEOUT2";
+                                       regulator-name = "ESAFEOUT2";
+                               };
+-                              charger@0 {
++                              charger_reg: charger@0 {
+                                       regulator-compatible = "CHARGER";
+                                       regulator-name = "CHARGER";
+                                       regulator-min-microamp = <60000>;
+@@ -1221,6 +1221,11 @@
+               pinctrl-1 = <&modem_state_active>;
+       };
++      charger {
++              compatible = "charger-manager";
++              status = "okay";
++              vinchg1-supply = <&charger_reg>;
++      };
+ };
+ &pinctrl_1 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0350-arch-Make-__mutex_fastpath_lock_retval-return-whethe.patch b/patches.tizen/0350-arch-Make-__mutex_fastpath_lock_retval-return-whethe.patch
new file mode 100644 (file)
index 0000000..4d46e62
--- /dev/null
@@ -0,0 +1,315 @@
+From 89281e7aafd408556ced76de0e2b3fd5c5d78dd7 Mon Sep 17 00:00:00 2001
+From: Maarten Lankhorst <maarten.lankhorst@canonical.com>
+Date: Thu, 20 Jun 2013 13:31:05 +0200
+Subject: [PATCH 0350/1302] arch: Make __mutex_fastpath_lock_retval return
+ whether fastpath succeeded or not
+
+This will allow me to call functions that have multiple
+arguments if fastpath fails. This is required to support ticket
+mutexes, because they need to be able to pass an extra argument
+to the fail function.
+
+Originally I duplicated the functions, by adding
+__mutex_fastpath_lock_retval_arg. This ended up being just a
+duplication of the existing function, so a way to test if
+fastpath was called ended up being better.
+
+This also cleaned up the reservation mutex patch some by being
+able to call an atomic_set instead of atomic_xchg, and making it
+easier to detect if the wrong unlock function was previously
+used.
+
+Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
+Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: dri-devel@lists.freedesktop.org
+Cc: linaro-mm-sig@lists.linaro.org
+Cc: robclark@gmail.com
+Cc: rostedt@goodmis.org
+Cc: daniel@ffwll.ch
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Link: http://lkml.kernel.org/r/20130620113105.4001.83929.stgit@patser
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/ia64/include/asm/mutex.h    | 10 ++++------
+ arch/powerpc/include/asm/mutex.h | 10 ++++------
+ arch/sh/include/asm/mutex-llsc.h |  4 ++--
+ arch/x86/include/asm/mutex_32.h  | 11 ++++-------
+ arch/x86/include/asm/mutex_64.h  | 11 ++++-------
+ include/asm-generic/mutex-dec.h  | 10 ++++------
+ include/asm-generic/mutex-null.h |  2 +-
+ include/asm-generic/mutex-xchg.h | 10 ++++------
+ kernel/mutex.c                   | 32 ++++++++++++++------------------
+ 9 files changed, 41 insertions(+), 59 deletions(-)
+
+diff --git a/arch/ia64/include/asm/mutex.h b/arch/ia64/include/asm/mutex.h
+index bed73a6..f41e66d 100644
+--- a/arch/ia64/include/asm/mutex.h
++++ b/arch/ia64/include/asm/mutex.h
+@@ -29,17 +29,15 @@ __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
+  *  __mutex_fastpath_lock_retval - try to take the lock by moving the count
+  *                                 from 1 to a 0 value
+  *  @count: pointer of type atomic_t
+- *  @fail_fn: function to call if the original value was not 1
+  *
+- * Change the count from 1 to a value lower than 1, and call <fail_fn> if
+- * it wasn't 1 originally. This function returns 0 if the fastpath succeeds,
+- * or anything the slow path function returns.
++ * Change the count from 1 to a value lower than 1. This function returns 0
++ * if the fastpath succeeds, or -1 otherwise.
+  */
+ static inline int
+-__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
++__mutex_fastpath_lock_retval(atomic_t *count)
+ {
+       if (unlikely(ia64_fetchadd4_acq(count, -1) != 1))
+-              return fail_fn(count);
++              return -1;
+       return 0;
+ }
+diff --git a/arch/powerpc/include/asm/mutex.h b/arch/powerpc/include/asm/mutex.h
+index 5399f7e..127ab23 100644
+--- a/arch/powerpc/include/asm/mutex.h
++++ b/arch/powerpc/include/asm/mutex.h
+@@ -82,17 +82,15 @@ __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
+  *  __mutex_fastpath_lock_retval - try to take the lock by moving the count
+  *                                 from 1 to a 0 value
+  *  @count: pointer of type atomic_t
+- *  @fail_fn: function to call if the original value was not 1
+  *
+- * Change the count from 1 to a value lower than 1, and call <fail_fn> if
+- * it wasn't 1 originally. This function returns 0 if the fastpath succeeds,
+- * or anything the slow path function returns.
++ * Change the count from 1 to a value lower than 1. This function returns 0
++ * if the fastpath succeeds, or -1 otherwise.
+  */
+ static inline int
+-__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
++__mutex_fastpath_lock_retval(atomic_t *count)
+ {
+       if (unlikely(__mutex_dec_return_lock(count) < 0))
+-              return fail_fn(count);
++              return -1;
+       return 0;
+ }
+diff --git a/arch/sh/include/asm/mutex-llsc.h b/arch/sh/include/asm/mutex-llsc.h
+index 090358a..dad29b6 100644
+--- a/arch/sh/include/asm/mutex-llsc.h
++++ b/arch/sh/include/asm/mutex-llsc.h
+@@ -37,7 +37,7 @@ __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
+ }
+ static inline int
+-__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
++__mutex_fastpath_lock_retval(atomic_t *count)
+ {
+       int __done, __res;
+@@ -51,7 +51,7 @@ __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
+               : "t");
+       if (unlikely(!__done || __res != 0))
+-              __res = fail_fn(count);
++              __res = -1;
+       return __res;
+ }
+diff --git a/arch/x86/include/asm/mutex_32.h b/arch/x86/include/asm/mutex_32.h
+index 03f90c8..0208c3c 100644
+--- a/arch/x86/include/asm/mutex_32.h
++++ b/arch/x86/include/asm/mutex_32.h
+@@ -42,17 +42,14 @@ do {                                                               \
+  *  __mutex_fastpath_lock_retval - try to take the lock by moving the count
+  *                                 from 1 to a 0 value
+  *  @count: pointer of type atomic_t
+- *  @fail_fn: function to call if the original value was not 1
+  *
+- * Change the count from 1 to a value lower than 1, and call <fail_fn> if it
+- * wasn't 1 originally. This function returns 0 if the fastpath succeeds,
+- * or anything the slow path function returns
++ * Change the count from 1 to a value lower than 1. This function returns 0
++ * if the fastpath succeeds, or -1 otherwise.
+  */
+-static inline int __mutex_fastpath_lock_retval(atomic_t *count,
+-                                             int (*fail_fn)(atomic_t *))
++static inline int __mutex_fastpath_lock_retval(atomic_t *count)
+ {
+       if (unlikely(atomic_dec_return(count) < 0))
+-              return fail_fn(count);
++              return -1;
+       else
+               return 0;
+ }
+diff --git a/arch/x86/include/asm/mutex_64.h b/arch/x86/include/asm/mutex_64.h
+index 68a87b0..2c543ff 100644
+--- a/arch/x86/include/asm/mutex_64.h
++++ b/arch/x86/include/asm/mutex_64.h
+@@ -37,17 +37,14 @@ do {                                                               \
+  *  __mutex_fastpath_lock_retval - try to take the lock by moving the count
+  *                                 from 1 to a 0 value
+  *  @count: pointer of type atomic_t
+- *  @fail_fn: function to call if the original value was not 1
+  *
+- * Change the count from 1 to a value lower than 1, and call <fail_fn> if
+- * it wasn't 1 originally. This function returns 0 if the fastpath succeeds,
+- * or anything the slow path function returns
++ * Change the count from 1 to a value lower than 1. This function returns 0
++ * if the fastpath succeeds, or -1 otherwise.
+  */
+-static inline int __mutex_fastpath_lock_retval(atomic_t *count,
+-                                             int (*fail_fn)(atomic_t *))
++static inline int __mutex_fastpath_lock_retval(atomic_t *count)
+ {
+       if (unlikely(atomic_dec_return(count) < 0))
+-              return fail_fn(count);
++              return -1;
+       else
+               return 0;
+ }
+diff --git a/include/asm-generic/mutex-dec.h b/include/asm-generic/mutex-dec.h
+index f104af7..d4f9fb4 100644
+--- a/include/asm-generic/mutex-dec.h
++++ b/include/asm-generic/mutex-dec.h
+@@ -28,17 +28,15 @@ __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
+  *  __mutex_fastpath_lock_retval - try to take the lock by moving the count
+  *                                 from 1 to a 0 value
+  *  @count: pointer of type atomic_t
+- *  @fail_fn: function to call if the original value was not 1
+  *
+- * Change the count from 1 to a value lower than 1, and call <fail_fn> if
+- * it wasn't 1 originally. This function returns 0 if the fastpath succeeds,
+- * or anything the slow path function returns.
++ * Change the count from 1 to a value lower than 1. This function returns 0
++ * if the fastpath succeeds, or -1 otherwise.
+  */
+ static inline int
+-__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
++__mutex_fastpath_lock_retval(atomic_t *count)
+ {
+       if (unlikely(atomic_dec_return(count) < 0))
+-              return fail_fn(count);
++              return -1;
+       return 0;
+ }
+diff --git a/include/asm-generic/mutex-null.h b/include/asm-generic/mutex-null.h
+index e1bbbc7..61069ed 100644
+--- a/include/asm-generic/mutex-null.h
++++ b/include/asm-generic/mutex-null.h
+@@ -11,7 +11,7 @@
+ #define _ASM_GENERIC_MUTEX_NULL_H
+ #define __mutex_fastpath_lock(count, fail_fn)         fail_fn(count)
+-#define __mutex_fastpath_lock_retval(count, fail_fn)  fail_fn(count)
++#define __mutex_fastpath_lock_retval(count)           (-1)
+ #define __mutex_fastpath_unlock(count, fail_fn)               fail_fn(count)
+ #define __mutex_fastpath_trylock(count, fail_fn)      fail_fn(count)
+ #define __mutex_slowpath_needs_to_unlock()            1
+diff --git a/include/asm-generic/mutex-xchg.h b/include/asm-generic/mutex-xchg.h
+index c04e0db..f169ec0 100644
+--- a/include/asm-generic/mutex-xchg.h
++++ b/include/asm-generic/mutex-xchg.h
+@@ -39,18 +39,16 @@ __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
+  *  __mutex_fastpath_lock_retval - try to take the lock by moving the count
+  *                                 from 1 to a 0 value
+  *  @count: pointer of type atomic_t
+- *  @fail_fn: function to call if the original value was not 1
+  *
+- * Change the count from 1 to a value lower than 1, and call <fail_fn> if it
+- * wasn't 1 originally. This function returns 0 if the fastpath succeeds,
+- * or anything the slow path function returns
++ * Change the count from 1 to a value lower than 1. This function returns 0
++ * if the fastpath succeeds, or -1 otherwise.
+  */
+ static inline int
+-__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
++__mutex_fastpath_lock_retval(atomic_t *count)
+ {
+       if (unlikely(atomic_xchg(count, 0) != 1))
+               if (likely(atomic_xchg(count, -1) != 1))
+-                      return fail_fn(count);
++                      return -1;
+       return 0;
+ }
+diff --git a/kernel/mutex.c b/kernel/mutex.c
+index ad53a66..42f8dda 100644
+--- a/kernel/mutex.c
++++ b/kernel/mutex.c
+@@ -494,10 +494,10 @@ __mutex_unlock_slowpath(atomic_t *lock_count)
+  * mutex_lock_interruptible() and mutex_trylock().
+  */
+ static noinline int __sched
+-__mutex_lock_killable_slowpath(atomic_t *lock_count);
++__mutex_lock_killable_slowpath(struct mutex *lock);
+ static noinline int __sched
+-__mutex_lock_interruptible_slowpath(atomic_t *lock_count);
++__mutex_lock_interruptible_slowpath(struct mutex *lock);
+ /**
+  * mutex_lock_interruptible - acquire the mutex, interruptible
+@@ -515,12 +515,12 @@ int __sched mutex_lock_interruptible(struct mutex *lock)
+       int ret;
+       might_sleep();
+-      ret =  __mutex_fastpath_lock_retval
+-                      (&lock->count, __mutex_lock_interruptible_slowpath);
+-      if (!ret)
++      ret =  __mutex_fastpath_lock_retval(&lock->count);
++      if (likely(!ret)) {
+               mutex_set_owner(lock);
+-
+-      return ret;
++              return 0;
++      } else
++              return __mutex_lock_interruptible_slowpath(lock);
+ }
+ EXPORT_SYMBOL(mutex_lock_interruptible);
+@@ -530,12 +530,12 @@ int __sched mutex_lock_killable(struct mutex *lock)
+       int ret;
+       might_sleep();
+-      ret = __mutex_fastpath_lock_retval
+-                      (&lock->count, __mutex_lock_killable_slowpath);
+-      if (!ret)
++      ret = __mutex_fastpath_lock_retval(&lock->count);
++      if (likely(!ret)) {
+               mutex_set_owner(lock);
+-
+-      return ret;
++              return 0;
++      } else
++              return __mutex_lock_killable_slowpath(lock);
+ }
+ EXPORT_SYMBOL(mutex_lock_killable);
+@@ -548,18 +548,14 @@ __mutex_lock_slowpath(atomic_t *lock_count)
+ }
+ static noinline int __sched
+-__mutex_lock_killable_slowpath(atomic_t *lock_count)
++__mutex_lock_killable_slowpath(struct mutex *lock)
+ {
+-      struct mutex *lock = container_of(lock_count, struct mutex, count);
+-
+       return __mutex_lock_common(lock, TASK_KILLABLE, 0, NULL, _RET_IP_);
+ }
+ static noinline int __sched
+-__mutex_lock_interruptible_slowpath(atomic_t *lock_count)
++__mutex_lock_interruptible_slowpath(struct mutex *lock)
+ {
+-      struct mutex *lock = container_of(lock_count, struct mutex, count);
+-
+       return __mutex_lock_common(lock, TASK_INTERRUPTIBLE, 0, NULL, _RET_IP_);
+ }
+ #endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0351-mutex-Add-support-for-wound-wait-style-locks.patch b/patches.tizen/0351-mutex-Add-support-for-wound-wait-style-locks.patch
new file mode 100644 (file)
index 0000000..9bd8fb7
--- /dev/null
@@ -0,0 +1,1268 @@
+From d9fa3ba2d9ada2c9443ee16dc20af485df14a46e Mon Sep 17 00:00:00 2001
+From: Maarten Lankhorst <maarten.lankhorst@canonical.com>
+Date: Mon, 24 Jun 2013 10:30:04 +0200
+Subject: [PATCH 0351/1302] mutex: Add support for wound/wait style locks
+
+Wound/wait mutexes are used when other multiple lock
+acquisitions of a similar type can be done in an arbitrary
+order. The deadlock handling used here is called wait/wound in
+the RDBMS literature: The older tasks waits until it can acquire
+the contended lock. The younger tasks needs to back off and drop
+all the locks it is currently holding, i.e. the younger task is
+wounded.
+
+For full documentation please read Documentation/ww-mutex-design.txt.
+
+References: https://lwn.net/Articles/548909/
+Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
+Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Acked-by: Rob Clark <robdclark@gmail.com>
+Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: dri-devel@lists.freedesktop.org
+Cc: linaro-mm-sig@lists.linaro.org
+Cc: rostedt@goodmis.org
+Cc: daniel@ffwll.ch
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Link: http://lkml.kernel.org/r/51C8038C.9000106@canonical.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/ww-mutex-design.txt | 344 ++++++++++++++++++++++++++++++++++++
+ include/linux/mutex-debug.h       |   1 +
+ include/linux/mutex.h             | 355 +++++++++++++++++++++++++++++++++++++-
+ kernel/mutex.c                    | 318 ++++++++++++++++++++++++++++++++--
+ lib/debug_locks.c                 |   2 +
+ 5 files changed, 1003 insertions(+), 17 deletions(-)
+ create mode 100644 Documentation/ww-mutex-design.txt
+
+diff --git a/Documentation/ww-mutex-design.txt b/Documentation/ww-mutex-design.txt
+new file mode 100644
+index 0000000..8a112dc
+--- /dev/null
++++ b/Documentation/ww-mutex-design.txt
+@@ -0,0 +1,344 @@
++Wait/Wound Deadlock-Proof Mutex Design
++======================================
++
++Please read mutex-design.txt first, as it applies to wait/wound mutexes too.
++
++Motivation for WW-Mutexes
++-------------------------
++
++GPU's do operations that commonly involve many buffers.  Those buffers
++can be shared across contexts/processes, exist in different memory
++domains (for example VRAM vs system memory), and so on.  And with
++PRIME / dmabuf, they can even be shared across devices.  So there are
++a handful of situations where the driver needs to wait for buffers to
++become ready.  If you think about this in terms of waiting on a buffer
++mutex for it to become available, this presents a problem because
++there is no way to guarantee that buffers appear in a execbuf/batch in
++the same order in all contexts.  That is directly under control of
++userspace, and a result of the sequence of GL calls that an application
++makes.        Which results in the potential for deadlock.  The problem gets
++more complex when you consider that the kernel may need to migrate the
++buffer(s) into VRAM before the GPU operates on the buffer(s), which
++may in turn require evicting some other buffers (and you don't want to
++evict other buffers which are already queued up to the GPU), but for a
++simplified understanding of the problem you can ignore this.
++
++The algorithm that the TTM graphics subsystem came up with for dealing with
++this problem is quite simple.  For each group of buffers (execbuf) that need
++to be locked, the caller would be assigned a unique reservation id/ticket,
++from a global counter.  In case of deadlock while locking all the buffers
++associated with a execbuf, the one with the lowest reservation ticket (i.e.
++the oldest task) wins, and the one with the higher reservation id (i.e. the
++younger task) unlocks all of the buffers that it has already locked, and then
++tries again.
++
++In the RDBMS literature this deadlock handling approach is called wait/wound:
++The older tasks waits until it can acquire the contended lock. The younger tasks
++needs to back off and drop all the locks it is currently holding, i.e. the
++younger task is wounded.
++
++Concepts
++--------
++
++Compared to normal mutexes two additional concepts/objects show up in the lock
++interface for w/w mutexes:
++
++Acquire context: To ensure eventual forward progress it is important the a task
++trying to acquire locks doesn't grab a new reservation id, but keeps the one it
++acquired when starting the lock acquisition. This ticket is stored in the
++acquire context. Furthermore the acquire context keeps track of debugging state
++to catch w/w mutex interface abuse.
++
++W/w class: In contrast to normal mutexes the lock class needs to be explicit for
++w/w mutexes, since it is required to initialize the acquire context.
++
++Furthermore there are three different class of w/w lock acquire functions:
++
++* Normal lock acquisition with a context, using ww_mutex_lock.
++
++* Slowpath lock acquisition on the contending lock, used by the wounded task
++  after having dropped all already acquired locks. These functions have the
++  _slow postfix.
++
++  From a simple semantics point-of-view the _slow functions are not strictly
++  required, since simply calling the normal ww_mutex_lock functions on the
++  contending lock (after having dropped all other already acquired locks) will
++  work correctly. After all if no other ww mutex has been acquired yet there's
++  no deadlock potential and hence the ww_mutex_lock call will block and not
++  prematurely return -EDEADLK. The advantage of the _slow functions is in
++  interface safety:
++  - ww_mutex_lock has a __must_check int return type, whereas ww_mutex_lock_slow
++    has a void return type. Note that since ww mutex code needs loops/retries
++    anyway the __must_check doesn't result in spurious warnings, even though the
++    very first lock operation can never fail.
++  - When full debugging is enabled ww_mutex_lock_slow checks that all acquired
++    ww mutex have been released (preventing deadlocks) and makes sure that we
++    block on the contending lock (preventing spinning through the -EDEADLK
++    slowpath until the contended lock can be acquired).
++
++* Functions to only acquire a single w/w mutex, which results in the exact same
++  semantics as a normal mutex. This is done by calling ww_mutex_lock with a NULL
++  context.
++
++  Again this is not strictly required. But often you only want to acquire a
++  single lock in which case it's pointless to set up an acquire context (and so
++  better to avoid grabbing a deadlock avoidance ticket).
++
++Of course, all the usual variants for handling wake-ups due to signals are also
++provided.
++
++Usage
++-----
++
++Three different ways to acquire locks within the same w/w class. Common
++definitions for methods #1 and #2:
++
++static DEFINE_WW_CLASS(ww_class);
++
++struct obj {
++      struct ww_mutex lock;
++      /* obj data */
++};
++
++struct obj_entry {
++      struct list_head head;
++      struct obj *obj;
++};
++
++Method 1, using a list in execbuf->buffers that's not allowed to be reordered.
++This is useful if a list of required objects is already tracked somewhere.
++Furthermore the lock helper can use propagate the -EALREADY return code back to
++the caller as a signal that an object is twice on the list. This is useful if
++the list is constructed from userspace input and the ABI requires userspace to
++not have duplicate entries (e.g. for a gpu commandbuffer submission ioctl).
++
++int lock_objs(struct list_head *list, struct ww_acquire_ctx *ctx)
++{
++      struct obj *res_obj = NULL;
++      struct obj_entry *contended_entry = NULL;
++      struct obj_entry *entry;
++
++      ww_acquire_init(ctx, &ww_class);
++
++retry:
++      list_for_each_entry (entry, list, head) {
++              if (entry->obj == res_obj) {
++                      res_obj = NULL;
++                      continue;
++              }
++              ret = ww_mutex_lock(&entry->obj->lock, ctx);
++              if (ret < 0) {
++                      contended_entry = entry;
++                      goto err;
++              }
++      }
++
++      ww_acquire_done(ctx);
++      return 0;
++
++err:
++      list_for_each_entry_continue_reverse (entry, list, head)
++              ww_mutex_unlock(&entry->obj->lock);
++
++      if (res_obj)
++              ww_mutex_unlock(&res_obj->lock);
++
++      if (ret == -EDEADLK) {
++              /* we lost out in a seqno race, lock and retry.. */
++              ww_mutex_lock_slow(&contended_entry->obj->lock, ctx);
++              res_obj = contended_entry->obj;
++              goto retry;
++      }
++      ww_acquire_fini(ctx);
++
++      return ret;
++}
++
++Method 2, using a list in execbuf->buffers that can be reordered. Same semantics
++of duplicate entry detection using -EALREADY as method 1 above. But the
++list-reordering allows for a bit more idiomatic code.
++
++int lock_objs(struct list_head *list, struct ww_acquire_ctx *ctx)
++{
++      struct obj_entry *entry, *entry2;
++
++      ww_acquire_init(ctx, &ww_class);
++
++      list_for_each_entry (entry, list, head) {
++              ret = ww_mutex_lock(&entry->obj->lock, ctx);
++              if (ret < 0) {
++                      entry2 = entry;
++
++                      list_for_each_entry_continue_reverse (entry2, list, head)
++                              ww_mutex_unlock(&entry2->obj->lock);
++
++                      if (ret != -EDEADLK) {
++                              ww_acquire_fini(ctx);
++                              return ret;
++                      }
++
++                      /* we lost out in a seqno race, lock and retry.. */
++                      ww_mutex_lock_slow(&entry->obj->lock, ctx);
++
++                      /*
++                       * Move buf to head of the list, this will point
++                       * buf->next to the first unlocked entry,
++                       * restarting the for loop.
++                       */
++                      list_del(&entry->head);
++                      list_add(&entry->head, list);
++              }
++      }
++
++      ww_acquire_done(ctx);
++      return 0;
++}
++
++Unlocking works the same way for both methods #1 and #2:
++
++void unlock_objs(struct list_head *list, struct ww_acquire_ctx *ctx)
++{
++      struct obj_entry *entry;
++
++      list_for_each_entry (entry, list, head)
++              ww_mutex_unlock(&entry->obj->lock);
++
++      ww_acquire_fini(ctx);
++}
++
++Method 3 is useful if the list of objects is constructed ad-hoc and not upfront,
++e.g. when adjusting edges in a graph where each node has its own ww_mutex lock,
++and edges can only be changed when holding the locks of all involved nodes. w/w
++mutexes are a natural fit for such a case for two reasons:
++- They can handle lock-acquisition in any order which allows us to start walking
++  a graph from a starting point and then iteratively discovering new edges and
++  locking down the nodes those edges connect to.
++- Due to the -EALREADY return code signalling that a given objects is already
++  held there's no need for additional book-keeping to break cycles in the graph
++  or keep track off which looks are already held (when using more than one node
++  as a starting point).
++
++Note that this approach differs in two important ways from the above methods:
++- Since the list of objects is dynamically constructed (and might very well be
++  different when retrying due to hitting the -EDEADLK wound condition) there's
++  no need to keep any object on a persistent list when it's not locked. We can
++  therefore move the list_head into the object itself.
++- On the other hand the dynamic object list construction also means that the -EALREADY return
++  code can't be propagated.
++
++Note also that methods #1 and #2 and method #3 can be combined, e.g. to first lock a
++list of starting nodes (passed in from userspace) using one of the above
++methods. And then lock any additional objects affected by the operations using
++method #3 below. The backoff/retry procedure will be a bit more involved, since
++when the dynamic locking step hits -EDEADLK we also need to unlock all the
++objects acquired with the fixed list. But the w/w mutex debug checks will catch
++any interface misuse for these cases.
++
++Also, method 3 can't fail the lock acquisition step since it doesn't return
++-EALREADY. Of course this would be different when using the _interruptible
++variants, but that's outside of the scope of these examples here.
++
++struct obj {
++      struct ww_mutex ww_mutex;
++      struct list_head locked_list;
++};
++
++static DEFINE_WW_CLASS(ww_class);
++
++void __unlock_objs(struct list_head *list)
++{
++      struct obj *entry, *temp;
++
++      list_for_each_entry_safe (entry, temp, list, locked_list) {
++              /* need to do that before unlocking, since only the current lock holder is
++              allowed to use object */
++              list_del(&entry->locked_list);
++              ww_mutex_unlock(entry->ww_mutex)
++      }
++}
++
++void lock_objs(struct list_head *list, struct ww_acquire_ctx *ctx)
++{
++      struct obj *obj;
++
++      ww_acquire_init(ctx, &ww_class);
++
++retry:
++      /* re-init loop start state */
++      loop {
++              /* magic code which walks over a graph and decides which objects
++               * to lock */
++
++              ret = ww_mutex_lock(obj->ww_mutex, ctx);
++              if (ret == -EALREADY) {
++                      /* we have that one already, get to the next object */
++                      continue;
++              }
++              if (ret == -EDEADLK) {
++                      __unlock_objs(list);
++
++                      ww_mutex_lock_slow(obj, ctx);
++                      list_add(&entry->locked_list, list);
++                      goto retry;
++              }
++
++              /* locked a new object, add it to the list */
++              list_add_tail(&entry->locked_list, list);
++      }
++
++      ww_acquire_done(ctx);
++      return 0;
++}
++
++void unlock_objs(struct list_head *list, struct ww_acquire_ctx *ctx)
++{
++      __unlock_objs(list);
++      ww_acquire_fini(ctx);
++}
++
++Method 4: Only lock one single objects. In that case deadlock detection and
++prevention is obviously overkill, since with grabbing just one lock you can't
++produce a deadlock within just one class. To simplify this case the w/w mutex
++api can be used with a NULL context.
++
++Implementation Details
++----------------------
++
++Design:
++  ww_mutex currently encapsulates a struct mutex, this means no extra overhead for
++  normal mutex locks, which are far more common. As such there is only a small
++  increase in code size if wait/wound mutexes are not used.
++
++  In general, not much contention is expected. The locks are typically used to
++  serialize access to resources for devices. The only way to make wakeups
++  smarter would be at the cost of adding a field to struct mutex_waiter. This
++  would add overhead to all cases where normal mutexes are used, and
++  ww_mutexes are generally less performance sensitive.
++
++Lockdep:
++  Special care has been taken to warn for as many cases of api abuse
++  as possible. Some common api abuses will be caught with
++  CONFIG_DEBUG_MUTEXES, but CONFIG_PROVE_LOCKING is recommended.
++
++  Some of the errors which will be warned about:
++   - Forgetting to call ww_acquire_fini or ww_acquire_init.
++   - Attempting to lock more mutexes after ww_acquire_done.
++   - Attempting to lock the wrong mutex after -EDEADLK and
++     unlocking all mutexes.
++   - Attempting to lock the right mutex after -EDEADLK,
++     before unlocking all mutexes.
++
++   - Calling ww_mutex_lock_slow before -EDEADLK was returned.
++
++   - Unlocking mutexes with the wrong unlock function.
++   - Calling one of the ww_acquire_* twice on the same context.
++   - Using a different ww_class for the mutex than for the ww_acquire_ctx.
++   - Normal lockdep errors that can result in deadlocks.
++
++  Some of the lockdep errors that can result in deadlocks:
++   - Calling ww_acquire_init to initialize a second ww_acquire_ctx before
++     having called ww_acquire_fini on the first.
++   - 'normal' deadlocks that can occur.
++
++FIXME: Update this section once we have the TASK_DEADLOCK task state flag magic
++implemented.
+diff --git a/include/linux/mutex-debug.h b/include/linux/mutex-debug.h
+index 731d77d..4ac8b19 100644
+--- a/include/linux/mutex-debug.h
++++ b/include/linux/mutex-debug.h
+@@ -3,6 +3,7 @@
+ #include <linux/linkage.h>
+ #include <linux/lockdep.h>
++#include <linux/debug_locks.h>
+ /*
+  * Mutexes - debugging helpers:
+diff --git a/include/linux/mutex.h b/include/linux/mutex.h
+index 433da8a..a56b0cc 100644
+--- a/include/linux/mutex.h
++++ b/include/linux/mutex.h
+@@ -10,6 +10,7 @@
+ #ifndef __LINUX_MUTEX_H
+ #define __LINUX_MUTEX_H
++#include <asm/current.h>
+ #include <linux/list.h>
+ #include <linux/spinlock_types.h>
+ #include <linux/linkage.h>
+@@ -77,6 +78,36 @@ struct mutex_waiter {
+ #endif
+ };
++struct ww_class {
++      atomic_long_t stamp;
++      struct lock_class_key acquire_key;
++      struct lock_class_key mutex_key;
++      const char *acquire_name;
++      const char *mutex_name;
++};
++
++struct ww_acquire_ctx {
++      struct task_struct *task;
++      unsigned long stamp;
++      unsigned acquired;
++#ifdef CONFIG_DEBUG_MUTEXES
++      unsigned done_acquire;
++      struct ww_class *ww_class;
++      struct ww_mutex *contending_lock;
++#endif
++#ifdef CONFIG_DEBUG_LOCK_ALLOC
++      struct lockdep_map dep_map;
++#endif
++};
++
++struct ww_mutex {
++      struct mutex base;
++      struct ww_acquire_ctx *ctx;
++#ifdef CONFIG_DEBUG_MUTEXES
++      struct ww_class *ww_class;
++#endif
++};
++
+ #ifdef CONFIG_DEBUG_MUTEXES
+ # include <linux/mutex-debug.h>
+ #else
+@@ -101,8 +132,11 @@ static inline void mutex_destroy(struct mutex *lock) {}
+ #ifdef CONFIG_DEBUG_LOCK_ALLOC
+ # define __DEP_MAP_MUTEX_INITIALIZER(lockname) \
+               , .dep_map = { .name = #lockname }
++# define __WW_CLASS_MUTEX_INITIALIZER(lockname, ww_class) \
++              , .ww_class = &ww_class
+ #else
+ # define __DEP_MAP_MUTEX_INITIALIZER(lockname)
++# define __WW_CLASS_MUTEX_INITIALIZER(lockname, ww_class)
+ #endif
+ #define __MUTEX_INITIALIZER(lockname) \
+@@ -112,13 +146,49 @@ static inline void mutex_destroy(struct mutex *lock) {}
+               __DEBUG_MUTEX_INITIALIZER(lockname) \
+               __DEP_MAP_MUTEX_INITIALIZER(lockname) }
++#define __WW_CLASS_INITIALIZER(ww_class) \
++              { .stamp = ATOMIC_LONG_INIT(0) \
++              , .acquire_name = #ww_class "_acquire" \
++              , .mutex_name = #ww_class "_mutex" }
++
++#define __WW_MUTEX_INITIALIZER(lockname, class) \
++              { .base = { \__MUTEX_INITIALIZER(lockname) } \
++              __WW_CLASS_MUTEX_INITIALIZER(lockname, class) }
++
+ #define DEFINE_MUTEX(mutexname) \
+       struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
++#define DEFINE_WW_CLASS(classname) \
++      struct ww_class classname = __WW_CLASS_INITIALIZER(classname)
++
++#define DEFINE_WW_MUTEX(mutexname, ww_class) \
++      struct ww_mutex mutexname = __WW_MUTEX_INITIALIZER(mutexname, ww_class)
++
++
+ extern void __mutex_init(struct mutex *lock, const char *name,
+                        struct lock_class_key *key);
+ /**
++ * ww_mutex_init - initialize the w/w mutex
++ * @lock: the mutex to be initialized
++ * @ww_class: the w/w class the mutex should belong to
++ *
++ * Initialize the w/w mutex to unlocked state and associate it with the given
++ * class.
++ *
++ * It is not allowed to initialize an already locked mutex.
++ */
++static inline void ww_mutex_init(struct ww_mutex *lock,
++                               struct ww_class *ww_class)
++{
++      __mutex_init(&lock->base, ww_class->mutex_name, &ww_class->mutex_key);
++      lock->ctx = NULL;
++#ifdef CONFIG_DEBUG_MUTEXES
++      lock->ww_class = ww_class;
++#endif
++}
++
++/**
+  * mutex_is_locked - is the mutex locked
+  * @lock: the mutex to be queried
+  *
+@@ -136,6 +206,7 @@ static inline int mutex_is_locked(struct mutex *lock)
+ #ifdef CONFIG_DEBUG_LOCK_ALLOC
+ extern void mutex_lock_nested(struct mutex *lock, unsigned int subclass);
+ extern void _mutex_lock_nest_lock(struct mutex *lock, struct lockdep_map *nest_lock);
++
+ extern int __must_check mutex_lock_interruptible_nested(struct mutex *lock,
+                                       unsigned int subclass);
+ extern int __must_check mutex_lock_killable_nested(struct mutex *lock,
+@@ -147,7 +218,7 @@ extern int __must_check mutex_lock_killable_nested(struct mutex *lock,
+ #define mutex_lock_nest_lock(lock, nest_lock)                         \
+ do {                                                                  \
+-      typecheck(struct lockdep_map *, &(nest_lock)->dep_map);         \
++      typecheck(struct lockdep_map *, &(nest_lock)->dep_map); \
+       _mutex_lock_nest_lock(lock, &(nest_lock)->dep_map);             \
+ } while (0)
+@@ -170,6 +241,288 @@ extern int __must_check mutex_lock_killable(struct mutex *lock);
+  */
+ extern int mutex_trylock(struct mutex *lock);
+ extern void mutex_unlock(struct mutex *lock);
++
++/**
++ * ww_acquire_init - initialize a w/w acquire context
++ * @ctx: w/w acquire context to initialize
++ * @ww_class: w/w class of the context
++ *
++ * Initializes an context to acquire multiple mutexes of the given w/w class.
++ *
++ * Context-based w/w mutex acquiring can be done in any order whatsoever within
++ * a given lock class. Deadlocks will be detected and handled with the
++ * wait/wound logic.
++ *
++ * Mixing of context-based w/w mutex acquiring and single w/w mutex locking can
++ * result in undetected deadlocks and is so forbidden. Mixing different contexts
++ * for the same w/w class when acquiring mutexes can also result in undetected
++ * deadlocks, and is hence also forbidden. Both types of abuse will be caught by
++ * enabling CONFIG_PROVE_LOCKING.
++ *
++ * Nesting of acquire contexts for _different_ w/w classes is possible, subject
++ * to the usual locking rules between different lock classes.
++ *
++ * An acquire context must be released with ww_acquire_fini by the same task
++ * before the memory is freed. It is recommended to allocate the context itself
++ * on the stack.
++ */
++static inline void ww_acquire_init(struct ww_acquire_ctx *ctx,
++                                 struct ww_class *ww_class)
++{
++      ctx->task = current;
++      ctx->stamp = atomic_long_inc_return(&ww_class->stamp);
++      ctx->acquired = 0;
++#ifdef CONFIG_DEBUG_MUTEXES
++      ctx->ww_class = ww_class;
++      ctx->done_acquire = 0;
++      ctx->contending_lock = NULL;
++#endif
++#ifdef CONFIG_DEBUG_LOCK_ALLOC
++      debug_check_no_locks_freed((void *)ctx, sizeof(*ctx));
++      lockdep_init_map(&ctx->dep_map, ww_class->acquire_name,
++                       &ww_class->acquire_key, 0);
++      mutex_acquire(&ctx->dep_map, 0, 0, _RET_IP_);
++#endif
++}
++
++/**
++ * ww_acquire_done - marks the end of the acquire phase
++ * @ctx: the acquire context
++ *
++ * Marks the end of the acquire phase, any further w/w mutex lock calls using
++ * this context are forbidden.
++ *
++ * Calling this function is optional, it is just useful to document w/w mutex
++ * code and clearly designated the acquire phase from actually using the locked
++ * data structures.
++ */
++static inline void ww_acquire_done(struct ww_acquire_ctx *ctx)
++{
++#ifdef CONFIG_DEBUG_MUTEXES
++      lockdep_assert_held(ctx);
++
++      DEBUG_LOCKS_WARN_ON(ctx->done_acquire);
++      ctx->done_acquire = 1;
++#endif
++}
++
++/**
++ * ww_acquire_fini - releases a w/w acquire context
++ * @ctx: the acquire context to free
++ *
++ * Releases a w/w acquire context. This must be called _after_ all acquired w/w
++ * mutexes have been released with ww_mutex_unlock.
++ */
++static inline void ww_acquire_fini(struct ww_acquire_ctx *ctx)
++{
++#ifdef CONFIG_DEBUG_MUTEXES
++      mutex_release(&ctx->dep_map, 0, _THIS_IP_);
++
++      DEBUG_LOCKS_WARN_ON(ctx->acquired);
++      if (!config_enabled(CONFIG_PROVE_LOCKING))
++              /*
++               * lockdep will normally handle this,
++               * but fail without anyway
++               */
++              ctx->done_acquire = 1;
++
++      if (!config_enabled(CONFIG_DEBUG_LOCK_ALLOC))
++              /* ensure ww_acquire_fini will still fail if called twice */
++              ctx->acquired = ~0U;
++#endif
++}
++
++extern int __must_check __ww_mutex_lock(struct ww_mutex *lock,
++                                      struct ww_acquire_ctx *ctx);
++extern int __must_check __ww_mutex_lock_interruptible(struct ww_mutex *lock,
++                                                    struct ww_acquire_ctx *ctx);
++
++/**
++ * ww_mutex_lock - acquire the w/w mutex
++ * @lock: the mutex to be acquired
++ * @ctx: w/w acquire context, or NULL to acquire only a single lock.
++ *
++ * Lock the w/w mutex exclusively for this task.
++ *
++ * Deadlocks within a given w/w class of locks are detected and handled with the
++ * wait/wound algorithm. If the lock isn't immediately avaiable this function
++ * will either sleep until it is (wait case). Or it selects the current context
++ * for backing off by returning -EDEADLK (wound case). Trying to acquire the
++ * same lock with the same context twice is also detected and signalled by
++ * returning -EALREADY. Returns 0 if the mutex was successfully acquired.
++ *
++ * In the wound case the caller must release all currently held w/w mutexes for
++ * the given context and then wait for this contending lock to be available by
++ * calling ww_mutex_lock_slow. Alternatively callers can opt to not acquire this
++ * lock and proceed with trying to acquire further w/w mutexes (e.g. when
++ * scanning through lru lists trying to free resources).
++ *
++ * The mutex must later on be released by the same task that
++ * acquired it. The task may not exit without first unlocking the mutex. Also,
++ * kernel memory where the mutex resides must not be freed with the mutex still
++ * locked. The mutex must first be initialized (or statically defined) before it
++ * can be locked. memset()-ing the mutex to 0 is not allowed. The mutex must be
++ * of the same w/w lock class as was used to initialize the acquire context.
++ *
++ * A mutex acquired with this function must be released with ww_mutex_unlock.
++ */
++static inline int ww_mutex_lock(struct ww_mutex *lock, struct ww_acquire_ctx *ctx)
++{
++      if (ctx)
++              return __ww_mutex_lock(lock, ctx);
++      else {
++              mutex_lock(&lock->base);
++              return 0;
++      }
++}
++
++/**
++ * ww_mutex_lock_interruptible - acquire the w/w mutex, interruptible
++ * @lock: the mutex to be acquired
++ * @ctx: w/w acquire context
++ *
++ * Lock the w/w mutex exclusively for this task.
++ *
++ * Deadlocks within a given w/w class of locks are detected and handled with the
++ * wait/wound algorithm. If the lock isn't immediately avaiable this function
++ * will either sleep until it is (wait case). Or it selects the current context
++ * for backing off by returning -EDEADLK (wound case). Trying to acquire the
++ * same lock with the same context twice is also detected and signalled by
++ * returning -EALREADY. Returns 0 if the mutex was successfully acquired. If a
++ * signal arrives while waiting for the lock then this function returns -EINTR.
++ *
++ * In the wound case the caller must release all currently held w/w mutexes for
++ * the given context and then wait for this contending lock to be available by
++ * calling ww_mutex_lock_slow_interruptible. Alternatively callers can opt to
++ * not acquire this lock and proceed with trying to acquire further w/w mutexes
++ * (e.g. when scanning through lru lists trying to free resources).
++ *
++ * The mutex must later on be released by the same task that
++ * acquired it. The task may not exit without first unlocking the mutex. Also,
++ * kernel memory where the mutex resides must not be freed with the mutex still
++ * locked. The mutex must first be initialized (or statically defined) before it
++ * can be locked. memset()-ing the mutex to 0 is not allowed. The mutex must be
++ * of the same w/w lock class as was used to initialize the acquire context.
++ *
++ * A mutex acquired with this function must be released with ww_mutex_unlock.
++ */
++static inline int __must_check ww_mutex_lock_interruptible(struct ww_mutex *lock,
++                                                         struct ww_acquire_ctx *ctx)
++{
++      if (ctx)
++              return __ww_mutex_lock_interruptible(lock, ctx);
++      else
++              return mutex_lock_interruptible(&lock->base);
++}
++
++/**
++ * ww_mutex_lock_slow - slowpath acquiring of the w/w mutex
++ * @lock: the mutex to be acquired
++ * @ctx: w/w acquire context
++ *
++ * Acquires a w/w mutex with the given context after a wound case. This function
++ * will sleep until the lock becomes available.
++ *
++ * The caller must have released all w/w mutexes already acquired with the
++ * context and then call this function on the contended lock.
++ *
++ * Afterwards the caller may continue to (re)acquire the other w/w mutexes it
++ * needs with ww_mutex_lock. Note that the -EALREADY return code from
++ * ww_mutex_lock can be used to avoid locking this contended mutex twice.
++ *
++ * It is forbidden to call this function with any other w/w mutexes associated
++ * with the context held. It is forbidden to call this on anything else than the
++ * contending mutex.
++ *
++ * Note that the slowpath lock acquiring can also be done by calling
++ * ww_mutex_lock directly. This function here is simply to help w/w mutex
++ * locking code readability by clearly denoting the slowpath.
++ */
++static inline void
++ww_mutex_lock_slow(struct ww_mutex *lock, struct ww_acquire_ctx *ctx)
++{
++      int ret;
++#ifdef CONFIG_DEBUG_MUTEXES
++      DEBUG_LOCKS_WARN_ON(!ctx->contending_lock);
++#endif
++      ret = ww_mutex_lock(lock, ctx);
++      (void)ret;
++}
++
++/**
++ * ww_mutex_lock_slow_interruptible - slowpath acquiring of the w/w mutex,
++ *                                  interruptible
++ * @lock: the mutex to be acquired
++ * @ctx: w/w acquire context
++ *
++ * Acquires a w/w mutex with the given context after a wound case. This function
++ * will sleep until the lock becomes available and returns 0 when the lock has
++ * been acquired. If a signal arrives while waiting for the lock then this
++ * function returns -EINTR.
++ *
++ * The caller must have released all w/w mutexes already acquired with the
++ * context and then call this function on the contended lock.
++ *
++ * Afterwards the caller may continue to (re)acquire the other w/w mutexes it
++ * needs with ww_mutex_lock. Note that the -EALREADY return code from
++ * ww_mutex_lock can be used to avoid locking this contended mutex twice.
++ *
++ * It is forbidden to call this function with any other w/w mutexes associated
++ * with the given context held. It is forbidden to call this on anything else
++ * than the contending mutex.
++ *
++ * Note that the slowpath lock acquiring can also be done by calling
++ * ww_mutex_lock_interruptible directly. This function here is simply to help
++ * w/w mutex locking code readability by clearly denoting the slowpath.
++ */
++static inline int __must_check
++ww_mutex_lock_slow_interruptible(struct ww_mutex *lock,
++                               struct ww_acquire_ctx *ctx)
++{
++#ifdef CONFIG_DEBUG_MUTEXES
++      DEBUG_LOCKS_WARN_ON(!ctx->contending_lock);
++#endif
++      return ww_mutex_lock_interruptible(lock, ctx);
++}
++
++extern void ww_mutex_unlock(struct ww_mutex *lock);
++
++/**
++ * ww_mutex_trylock - tries to acquire the w/w mutex without acquire context
++ * @lock: mutex to lock
++ *
++ * Trylocks a mutex without acquire context, so no deadlock detection is
++ * possible. Returns 1 if the mutex has been acquired successfully, 0 otherwise.
++ */
++static inline int __must_check ww_mutex_trylock(struct ww_mutex *lock)
++{
++      return mutex_trylock(&lock->base);
++}
++
++/***
++ * ww_mutex_destroy - mark a w/w mutex unusable
++ * @lock: the mutex to be destroyed
++ *
++ * This function marks the mutex uninitialized, and any subsequent
++ * use of the mutex is forbidden. The mutex must not be locked when
++ * this function is called.
++ */
++static inline void ww_mutex_destroy(struct ww_mutex *lock)
++{
++      mutex_destroy(&lock->base);
++}
++
++/**
++ * ww_mutex_is_locked - is the w/w mutex locked
++ * @lock: the mutex to be queried
++ *
++ * Returns 1 if the mutex is locked, 0 if unlocked.
++ */
++static inline bool ww_mutex_is_locked(struct ww_mutex *lock)
++{
++      return mutex_is_locked(&lock->base);
++}
++
+ extern int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock);
+ #ifndef CONFIG_HAVE_ARCH_MUTEX_CPU_RELAX
+diff --git a/kernel/mutex.c b/kernel/mutex.c
+index 42f8dda..fc801aa 100644
+--- a/kernel/mutex.c
++++ b/kernel/mutex.c
+@@ -254,16 +254,165 @@ void __sched mutex_unlock(struct mutex *lock)
+ EXPORT_SYMBOL(mutex_unlock);
++/**
++ * ww_mutex_unlock - release the w/w mutex
++ * @lock: the mutex to be released
++ *
++ * Unlock a mutex that has been locked by this task previously with any of the
++ * ww_mutex_lock* functions (with or without an acquire context). It is
++ * forbidden to release the locks after releasing the acquire context.
++ *
++ * This function must not be used in interrupt context. Unlocking
++ * of a unlocked mutex is not allowed.
++ */
++void __sched ww_mutex_unlock(struct ww_mutex *lock)
++{
++      /*
++       * The unlocking fastpath is the 0->1 transition from 'locked'
++       * into 'unlocked' state:
++       */
++      if (lock->ctx) {
++#ifdef CONFIG_DEBUG_MUTEXES
++              DEBUG_LOCKS_WARN_ON(!lock->ctx->acquired);
++#endif
++              if (lock->ctx->acquired > 0)
++                      lock->ctx->acquired--;
++              lock->ctx = NULL;
++      }
++
++#ifndef CONFIG_DEBUG_MUTEXES
++      /*
++       * When debugging is enabled we must not clear the owner before time,
++       * the slow path will always be taken, and that clears the owner field
++       * after verifying that it was indeed current.
++       */
++      mutex_clear_owner(&lock->base);
++#endif
++      __mutex_fastpath_unlock(&lock->base.count, __mutex_unlock_slowpath);
++}
++EXPORT_SYMBOL(ww_mutex_unlock);
++
++static inline int __sched
++__mutex_lock_check_stamp(struct mutex *lock, struct ww_acquire_ctx *ctx)
++{
++      struct ww_mutex *ww = container_of(lock, struct ww_mutex, base);
++      struct ww_acquire_ctx *hold_ctx = ACCESS_ONCE(ww->ctx);
++
++      if (!hold_ctx)
++              return 0;
++
++      if (unlikely(ctx == hold_ctx))
++              return -EALREADY;
++
++      if (ctx->stamp - hold_ctx->stamp <= LONG_MAX &&
++          (ctx->stamp != hold_ctx->stamp || ctx > hold_ctx)) {
++#ifdef CONFIG_DEBUG_MUTEXES
++              DEBUG_LOCKS_WARN_ON(ctx->contending_lock);
++              ctx->contending_lock = ww;
++#endif
++              return -EDEADLK;
++      }
++
++      return 0;
++}
++
++static __always_inline void ww_mutex_lock_acquired(struct ww_mutex *ww,
++                                                 struct ww_acquire_ctx *ww_ctx)
++{
++#ifdef CONFIG_DEBUG_MUTEXES
++      /*
++       * If this WARN_ON triggers, you used ww_mutex_lock to acquire,
++       * but released with a normal mutex_unlock in this call.
++       *
++       * This should never happen, always use ww_mutex_unlock.
++       */
++      DEBUG_LOCKS_WARN_ON(ww->ctx);
++
++      /*
++       * Not quite done after calling ww_acquire_done() ?
++       */
++      DEBUG_LOCKS_WARN_ON(ww_ctx->done_acquire);
++
++      if (ww_ctx->contending_lock) {
++              /*
++               * After -EDEADLK you tried to
++               * acquire a different ww_mutex? Bad!
++               */
++              DEBUG_LOCKS_WARN_ON(ww_ctx->contending_lock != ww);
++
++              /*
++               * You called ww_mutex_lock after receiving -EDEADLK,
++               * but 'forgot' to unlock everything else first?
++               */
++              DEBUG_LOCKS_WARN_ON(ww_ctx->acquired > 0);
++              ww_ctx->contending_lock = NULL;
++      }
++
++      /*
++       * Naughty, using a different class will lead to undefined behavior!
++       */
++      DEBUG_LOCKS_WARN_ON(ww_ctx->ww_class != ww->ww_class);
++#endif
++      ww_ctx->acquired++;
++}
++
++/*
++ * after acquiring lock with fastpath or when we lost out in contested
++ * slowpath, set ctx and wake up any waiters so they can recheck.
++ *
++ * This function is never called when CONFIG_DEBUG_LOCK_ALLOC is set,
++ * as the fastpath and opportunistic spinning are disabled in that case.
++ */
++static __always_inline void
++ww_mutex_set_context_fastpath(struct ww_mutex *lock,
++                             struct ww_acquire_ctx *ctx)
++{
++      unsigned long flags;
++      struct mutex_waiter *cur;
++
++      ww_mutex_lock_acquired(lock, ctx);
++
++      lock->ctx = ctx;
++
++      /*
++       * The lock->ctx update should be visible on all cores before
++       * the atomic read is done, otherwise contended waiters might be
++       * missed. The contended waiters will either see ww_ctx == NULL
++       * and keep spinning, or it will acquire wait_lock, add itself
++       * to waiter list and sleep.
++       */
++      smp_mb(); /* ^^^ */
++
++      /*
++       * Check if lock is contended, if not there is nobody to wake up
++       */
++      if (likely(atomic_read(&lock->base.count) == 0))
++              return;
++
++      /*
++       * Uh oh, we raced in fastpath, wake up everyone in this case,
++       * so they can see the new lock->ctx.
++       */
++      spin_lock_mutex(&lock->base.wait_lock, flags);
++      list_for_each_entry(cur, &lock->base.wait_list, list) {
++              debug_mutex_wake_waiter(&lock->base, cur);
++              wake_up_process(cur->task);
++      }
++      spin_unlock_mutex(&lock->base.wait_lock, flags);
++}
++
+ /*
+  * Lock a mutex (possibly interruptible), slowpath:
+  */
+-static inline int __sched
++static __always_inline int __sched
+ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass,
+-                  struct lockdep_map *nest_lock, unsigned long ip)
++                  struct lockdep_map *nest_lock, unsigned long ip,
++                  struct ww_acquire_ctx *ww_ctx)
+ {
+       struct task_struct *task = current;
+       struct mutex_waiter waiter;
+       unsigned long flags;
++      int ret;
+       preempt_disable();
+       mutex_acquire_nest(&lock->dep_map, subclass, 0, nest_lock, ip);
+@@ -298,6 +447,22 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass,
+               struct task_struct *owner;
+               struct mspin_node  node;
++              if (!__builtin_constant_p(ww_ctx == NULL) && ww_ctx->acquired > 0) {
++                      struct ww_mutex *ww;
++
++                      ww = container_of(lock, struct ww_mutex, base);
++                      /*
++                       * If ww->ctx is set the contents are undefined, only
++                       * by acquiring wait_lock there is a guarantee that
++                       * they are not invalid when reading.
++                       *
++                       * As such, when deadlock detection needs to be
++                       * performed the optimistic spinning cannot be done.
++                       */
++                      if (ACCESS_ONCE(ww->ctx))
++                              break;
++              }
++
+               /*
+                * If there's an owner, wait for it to either
+                * release the lock or go to sleep.
+@@ -312,6 +477,13 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass,
+               if ((atomic_read(&lock->count) == 1) &&
+                   (atomic_cmpxchg(&lock->count, 1, 0) == 1)) {
+                       lock_acquired(&lock->dep_map, ip);
++                      if (!__builtin_constant_p(ww_ctx == NULL)) {
++                              struct ww_mutex *ww;
++                              ww = container_of(lock, struct ww_mutex, base);
++
++                              ww_mutex_set_context_fastpath(ww, ww_ctx);
++                      }
++
+                       mutex_set_owner(lock);
+                       mspin_unlock(MLOCK(lock), &node);
+                       preempt_enable();
+@@ -371,15 +543,16 @@ slowpath:
+                * TASK_UNINTERRUPTIBLE case.)
+                */
+               if (unlikely(signal_pending_state(state, task))) {
+-                      mutex_remove_waiter(lock, &waiter,
+-                                          task_thread_info(task));
+-                      mutex_release(&lock->dep_map, 1, ip);
+-                      spin_unlock_mutex(&lock->wait_lock, flags);
++                      ret = -EINTR;
++                      goto err;
++              }
+-                      debug_mutex_free_waiter(&waiter);
+-                      preempt_enable();
+-                      return -EINTR;
++              if (!__builtin_constant_p(ww_ctx == NULL) && ww_ctx->acquired > 0) {
++                      ret = __mutex_lock_check_stamp(lock, ww_ctx);
++                      if (ret)
++                              goto err;
+               }
++
+               __set_task_state(task, state);
+               /* didn't get the lock, go to sleep: */
+@@ -394,6 +567,30 @@ done:
+       mutex_remove_waiter(lock, &waiter, current_thread_info());
+       mutex_set_owner(lock);
++      if (!__builtin_constant_p(ww_ctx == NULL)) {
++              struct ww_mutex *ww = container_of(lock,
++                                                    struct ww_mutex,
++                                                    base);
++              struct mutex_waiter *cur;
++
++              /*
++               * This branch gets optimized out for the common case,
++               * and is only important for ww_mutex_lock.
++               */
++
++              ww_mutex_lock_acquired(ww, ww_ctx);
++              ww->ctx = ww_ctx;
++
++              /*
++               * Give any possible sleeping processes the chance to wake up,
++               * so they can recheck if they have to back off.
++               */
++              list_for_each_entry(cur, &lock->wait_list, list) {
++                      debug_mutex_wake_waiter(lock, cur);
++                      wake_up_process(cur->task);
++              }
++      }
++
+       /* set it to 0 if there are no waiters left: */
+       if (likely(list_empty(&lock->wait_list)))
+               atomic_set(&lock->count, 0);
+@@ -404,6 +601,14 @@ done:
+       preempt_enable();
+       return 0;
++
++err:
++      mutex_remove_waiter(lock, &waiter, task_thread_info(task));
++      spin_unlock_mutex(&lock->wait_lock, flags);
++      debug_mutex_free_waiter(&waiter);
++      mutex_release(&lock->dep_map, 1, ip);
++      preempt_enable();
++      return ret;
+ }
+ #ifdef CONFIG_DEBUG_LOCK_ALLOC
+@@ -411,7 +616,8 @@ void __sched
+ mutex_lock_nested(struct mutex *lock, unsigned int subclass)
+ {
+       might_sleep();
+-      __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, subclass, NULL, _RET_IP_);
++      __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE,
++                          subclass, NULL, _RET_IP_, NULL);
+ }
+ EXPORT_SYMBOL_GPL(mutex_lock_nested);
+@@ -420,7 +626,8 @@ void __sched
+ _mutex_lock_nest_lock(struct mutex *lock, struct lockdep_map *nest)
+ {
+       might_sleep();
+-      __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, 0, nest, _RET_IP_);
++      __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE,
++                          0, nest, _RET_IP_, NULL);
+ }
+ EXPORT_SYMBOL_GPL(_mutex_lock_nest_lock);
+@@ -429,7 +636,8 @@ int __sched
+ mutex_lock_killable_nested(struct mutex *lock, unsigned int subclass)
+ {
+       might_sleep();
+-      return __mutex_lock_common(lock, TASK_KILLABLE, subclass, NULL, _RET_IP_);
++      return __mutex_lock_common(lock, TASK_KILLABLE,
++                                 subclass, NULL, _RET_IP_, NULL);
+ }
+ EXPORT_SYMBOL_GPL(mutex_lock_killable_nested);
+@@ -438,10 +646,30 @@ mutex_lock_interruptible_nested(struct mutex *lock, unsigned int subclass)
+ {
+       might_sleep();
+       return __mutex_lock_common(lock, TASK_INTERRUPTIBLE,
+-                                 subclass, NULL, _RET_IP_);
++                                 subclass, NULL, _RET_IP_, NULL);
+ }
+ EXPORT_SYMBOL_GPL(mutex_lock_interruptible_nested);
++
++
++int __sched
++__ww_mutex_lock(struct ww_mutex *lock, struct ww_acquire_ctx *ctx)
++{
++      might_sleep();
++      return __mutex_lock_common(&lock->base, TASK_UNINTERRUPTIBLE,
++                                 0, &ctx->dep_map, _RET_IP_, ctx);
++}
++EXPORT_SYMBOL_GPL(__ww_mutex_lock);
++
++int __sched
++__ww_mutex_lock_interruptible(struct ww_mutex *lock, struct ww_acquire_ctx *ctx)
++{
++      might_sleep();
++      return __mutex_lock_common(&lock->base, TASK_INTERRUPTIBLE,
++                                 0, &ctx->dep_map, _RET_IP_, ctx);
++}
++EXPORT_SYMBOL_GPL(__ww_mutex_lock_interruptible);
++
+ #endif
+ /*
+@@ -544,20 +772,39 @@ __mutex_lock_slowpath(atomic_t *lock_count)
+ {
+       struct mutex *lock = container_of(lock_count, struct mutex, count);
+-      __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, 0, NULL, _RET_IP_);
++      __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, 0,
++                          NULL, _RET_IP_, NULL);
+ }
+ static noinline int __sched
+ __mutex_lock_killable_slowpath(struct mutex *lock)
+ {
+-      return __mutex_lock_common(lock, TASK_KILLABLE, 0, NULL, _RET_IP_);
++      return __mutex_lock_common(lock, TASK_KILLABLE, 0,
++                                 NULL, _RET_IP_, NULL);
+ }
+ static noinline int __sched
+ __mutex_lock_interruptible_slowpath(struct mutex *lock)
+ {
+-      return __mutex_lock_common(lock, TASK_INTERRUPTIBLE, 0, NULL, _RET_IP_);
++      return __mutex_lock_common(lock, TASK_INTERRUPTIBLE, 0,
++                                 NULL, _RET_IP_, NULL);
++}
++
++static noinline int __sched
++__ww_mutex_lock_slowpath(struct ww_mutex *lock, struct ww_acquire_ctx *ctx)
++{
++      return __mutex_lock_common(&lock->base, TASK_UNINTERRUPTIBLE, 0,
++                                 NULL, _RET_IP_, ctx);
+ }
++
++static noinline int __sched
++__ww_mutex_lock_interruptible_slowpath(struct ww_mutex *lock,
++                                          struct ww_acquire_ctx *ctx)
++{
++      return __mutex_lock_common(&lock->base, TASK_INTERRUPTIBLE, 0,
++                                 NULL, _RET_IP_, ctx);
++}
++
+ #endif
+ /*
+@@ -613,6 +860,45 @@ int __sched mutex_trylock(struct mutex *lock)
+ }
+ EXPORT_SYMBOL(mutex_trylock);
++#ifndef CONFIG_DEBUG_LOCK_ALLOC
++int __sched
++__ww_mutex_lock(struct ww_mutex *lock, struct ww_acquire_ctx *ctx)
++{
++      int ret;
++
++      might_sleep();
++
++      ret = __mutex_fastpath_lock_retval(&lock->base.count);
++
++      if (likely(!ret)) {
++              ww_mutex_set_context_fastpath(lock, ctx);
++              mutex_set_owner(&lock->base);
++      } else
++              ret = __ww_mutex_lock_slowpath(lock, ctx);
++      return ret;
++}
++EXPORT_SYMBOL(__ww_mutex_lock);
++
++int __sched
++__ww_mutex_lock_interruptible(struct ww_mutex *lock, struct ww_acquire_ctx *ctx)
++{
++      int ret;
++
++      might_sleep();
++
++      ret = __mutex_fastpath_lock_retval(&lock->base.count);
++
++      if (likely(!ret)) {
++              ww_mutex_set_context_fastpath(lock, ctx);
++              mutex_set_owner(&lock->base);
++      } else
++              ret = __ww_mutex_lock_interruptible_slowpath(lock, ctx);
++      return ret;
++}
++EXPORT_SYMBOL(__ww_mutex_lock_interruptible);
++
++#endif
++
+ /**
+  * atomic_dec_and_mutex_lock - return holding mutex if we dec to 0
+  * @cnt: the atomic which we are to dec
+diff --git a/lib/debug_locks.c b/lib/debug_locks.c
+index f2fa60c..96c4c63 100644
+--- a/lib/debug_locks.c
++++ b/lib/debug_locks.c
+@@ -30,6 +30,7 @@ EXPORT_SYMBOL_GPL(debug_locks);
+  * a locking bug is detected.
+  */
+ int debug_locks_silent;
++EXPORT_SYMBOL_GPL(debug_locks_silent);
+ /*
+  * Generic 'turn off all lock debugging' function:
+@@ -44,3 +45,4 @@ int debug_locks_off(void)
+       }
+       return 0;
+ }
++EXPORT_SYMBOL_GPL(debug_locks_off);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0352-mutex-Add-w-w-mutex-slowpath-debugging.patch b/patches.tizen/0352-mutex-Add-w-w-mutex-slowpath-debugging.patch
new file mode 100644 (file)
index 0000000..d4c9c7c
--- /dev/null
@@ -0,0 +1,178 @@
+From 402f7156db51b0a21e71659c23219369808e4bda Mon Sep 17 00:00:00 2001
+From: Daniel Vetter <daniel.vetter@ffwll.ch>
+Date: Thu, 20 Jun 2013 13:31:17 +0200
+Subject: [PATCH 0352/1302] mutex: Add w/w mutex slowpath debugging
+
+Injects EDEADLK conditions at pseudo-random interval, with
+exponential backoff up to UINT_MAX (to ensure that every lock
+operation still completes in a reasonable time).
+
+This way we can test the wound slowpath even for ww mutex users
+where contention is never expected, and the ww deadlock
+avoidance algorithm is only needed for correctness against
+malicious userspace. An example would be protecting kernel
+modesetting properties, which thanks to single-threaded X isn't
+really expected to contend, ever.
+
+I've looked into using the CONFIG_FAULT_INJECTION
+infrastructure, but decided against it for two reasons:
+
+- EDEADLK handling is mandatory for ww mutex users and should
+  never affect the outcome of a syscall. This is in contrast to -ENOMEM
+  injection. So fine configurability isn't required.
+
+- The fault injection framework only allows to set a simple
+  probability for failure. Now the probability that a ww mutex acquire
+  stage with N locks will never complete (due to too many injected
+  EDEADLK backoffs) is zero. But the expected number of ww_mutex_lock
+  operations for the completely uncontended case would be O(exp(N)).
+  The per-acuiqire ctx exponential backoff solution choosen here only
+  results in O(log N) overhead due to injection and so O(log N * N)
+  lock operations. This way we can fail with high probability (and so
+  have good test coverage even for fancy backoff and lock acquisition
+  paths) without running into patalogical cases.
+
+Note that EDEADLK will only ever be injected when we managed to
+acquire the lock. This prevents any behaviour changes for users
+which rely on the EALREADY semantics.
+
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
+Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: dri-devel@lists.freedesktop.org
+Cc: linaro-mm-sig@lists.linaro.org
+Cc: rostedt@goodmis.org
+Cc: daniel@ffwll.ch
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Link: http://lkml.kernel.org/r/20130620113117.4001.21681.stgit@patser
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/mutex.h |  8 ++++++++
+ kernel/mutex.c        | 44 +++++++++++++++++++++++++++++++++++++++++---
+ lib/Kconfig.debug     | 13 +++++++++++++
+ 3 files changed, 62 insertions(+), 3 deletions(-)
+
+diff --git a/include/linux/mutex.h b/include/linux/mutex.h
+index a56b0cc..3793ed7 100644
+--- a/include/linux/mutex.h
++++ b/include/linux/mutex.h
+@@ -98,6 +98,10 @@ struct ww_acquire_ctx {
+ #ifdef CONFIG_DEBUG_LOCK_ALLOC
+       struct lockdep_map dep_map;
+ #endif
++#ifdef CONFIG_DEBUG_WW_MUTEX_SLOWPATH
++      unsigned deadlock_inject_interval;
++      unsigned deadlock_inject_countdown;
++#endif
+ };
+ struct ww_mutex {
+@@ -283,6 +287,10 @@ static inline void ww_acquire_init(struct ww_acquire_ctx *ctx,
+                        &ww_class->acquire_key, 0);
+       mutex_acquire(&ctx->dep_map, 0, 0, _RET_IP_);
+ #endif
++#ifdef CONFIG_DEBUG_WW_MUTEX_SLOWPATH
++      ctx->deadlock_inject_interval = 1;
++      ctx->deadlock_inject_countdown = ctx->stamp & 0xf;
++#endif
+ }
+ /**
+diff --git a/kernel/mutex.c b/kernel/mutex.c
+index fc801aa..e581ada 100644
+--- a/kernel/mutex.c
++++ b/kernel/mutex.c
+@@ -651,22 +651,60 @@ mutex_lock_interruptible_nested(struct mutex *lock, unsigned int subclass)
+ EXPORT_SYMBOL_GPL(mutex_lock_interruptible_nested);
++static inline int
++ww_mutex_deadlock_injection(struct ww_mutex *lock, struct ww_acquire_ctx *ctx)
++{
++#ifdef CONFIG_DEBUG_WW_MUTEX_SLOWPATH
++      unsigned tmp;
++
++      if (ctx->deadlock_inject_countdown-- == 0) {
++              tmp = ctx->deadlock_inject_interval;
++              if (tmp > UINT_MAX/4)
++                      tmp = UINT_MAX;
++              else
++                      tmp = tmp*2 + tmp + tmp/2;
++
++              ctx->deadlock_inject_interval = tmp;
++              ctx->deadlock_inject_countdown = tmp;
++              ctx->contending_lock = lock;
++
++              ww_mutex_unlock(lock);
++
++              return -EDEADLK;
++      }
++#endif
++
++      return 0;
++}
+ int __sched
+ __ww_mutex_lock(struct ww_mutex *lock, struct ww_acquire_ctx *ctx)
+ {
++      int ret;
++
+       might_sleep();
+-      return __mutex_lock_common(&lock->base, TASK_UNINTERRUPTIBLE,
++      ret =  __mutex_lock_common(&lock->base, TASK_UNINTERRUPTIBLE,
+                                  0, &ctx->dep_map, _RET_IP_, ctx);
++      if (!ret && ctx->acquired > 0)
++              return ww_mutex_deadlock_injection(lock, ctx);
++
++      return ret;
+ }
+ EXPORT_SYMBOL_GPL(__ww_mutex_lock);
+ int __sched
+ __ww_mutex_lock_interruptible(struct ww_mutex *lock, struct ww_acquire_ctx *ctx)
+ {
++      int ret;
++
+       might_sleep();
+-      return __mutex_lock_common(&lock->base, TASK_INTERRUPTIBLE,
+-                                 0, &ctx->dep_map, _RET_IP_, ctx);
++      ret = __mutex_lock_common(&lock->base, TASK_INTERRUPTIBLE,
++                                0, &ctx->dep_map, _RET_IP_, ctx);
++
++      if (!ret && ctx->acquired > 0)
++              return ww_mutex_deadlock_injection(lock, ctx);
++
++      return ret;
+ }
+ EXPORT_SYMBOL_GPL(__ww_mutex_lock_interruptible);
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index 74fdc5c..13b8c1c 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -547,6 +547,19 @@ config DEBUG_MUTEXES
+        This feature allows mutex semantics violations to be detected and
+        reported.
++config DEBUG_WW_MUTEX_SLOWPATH
++      bool "Wait/wound mutex debugging: Slowpath testing"
++      depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
++      select DEBUG_LOCK_ALLOC
++      select DEBUG_SPINLOCK
++      select DEBUG_MUTEXES
++      help
++       This feature enables slowpath testing for w/w mutex users by
++       injecting additional -EDEADLK wound/backoff cases. Together with
++       the full mutex checks enabled with (CONFIG_PROVE_LOCKING) this
++       will test all possible w/w mutex interface abuse with the
++       exception of simply not acquiring all the required locks.
++
+ config DEBUG_LOCK_ALLOC
+       bool "Lock debugging: detect incorrect freeing of live locks"
+       depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0353-dmabuf-sync-add-buffer-synchronization-framework.patch b/patches.tizen/0353-dmabuf-sync-add-buffer-synchronization-framework.patch
new file mode 100644 (file)
index 0000000..74a759b
--- /dev/null
@@ -0,0 +1,1443 @@
+From a2baf3c043ccd2ec94f953719de4d68acca6d7c6 Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Wed, 17 Jul 2013 14:40:48 +0900
+Subject: [PATCH 0353/1302] dmabuf-sync: add buffer synchronization framework
+
+This patch adds a buffer synchronization framework based on DMA BUF[1]
+and and based on ww-mutexes[2] for lock mechanism.
+
+The purpose of this framework is to provide not only buffer access control
+to CPU and DMA but also easy-to-use interfaces for device drivers and
+user application. This framework can be used for all dma devices using
+system memory as dma buffer, especially for most ARM based SoCs.
+
+Changelog v5:
+- Rmove a dependence on reservation_object: the reservation_object is used
+  to hook up to ttm and dma-buf for easy sharing of reservations across
+  devices. However, the dmabuf sync can be used for all dma devices; v4l2
+  and drm based drivers, so doesn't need the reservation_object anymore.
+  With regared to this, it adds 'void *sync' to dma_buf structure.
+- All patches are rebased on mainline, Linux v3.10.
+
+Changelog v4:
+- Add user side interface for buffer synchronization mechanism and update
+  descriptions related to the user side interface.
+
+Changelog v3:
+- remove cache operation relevant codes and update document file.
+
+Changelog v2:
+- use atomic_add_unless to avoid potential bug.
+- add a macro for checking valid access type.
+- code clean.
+
+The mechanism of this framework has the following steps,
+    1. Register dmabufs to a sync object - A task gets a new sync object and
+    can add one or more dmabufs that the task wants to access.
+    This registering should be performed when a device context or an event
+    context such as a page flip event is created or before CPU accesses a shared
+    buffer.
+
+       dma_buf_sync_get(a sync object, a dmabuf);
+
+    2. Lock a sync object - A task tries to lock all dmabufs added in its own
+    sync object. Basically, the lock mechanism uses ww-mutex[1] to avoid dead
+    lock issue and for race condition between CPU and CPU, CPU and DMA, and DMA
+    and DMA. Taking a lock means that others cannot access all locked dmabufs
+    until the task that locked the corresponding dmabufs, unlocks all the locked
+    dmabufs.
+    This locking should be performed before DMA or CPU accesses these dmabufs.
+
+       dma_buf_sync_lock(a sync object);
+
+    3. Unlock a sync object - The task unlocks all dmabufs added in its own sync
+    object. The unlock means that the DMA or CPU accesses to the dmabufs have
+    been completed so that others may access them.
+    This unlocking should be performed after DMA or CPU has completed accesses
+    to the dmabufs.
+
+       dma_buf_sync_unlock(a sync object);
+
+    4. Unregister one or all dmabufs from a sync object - A task unregisters
+    the given dmabufs from the sync object. This means that the task dosen't
+    want to lock the dmabufs.
+    The unregistering should be performed after DMA or CPU has completed
+    accesses to the dmabufs or when dma_buf_sync_lock() is failed.
+
+       dma_buf_sync_put(a sync object, a dmabuf);
+       dma_buf_sync_put_all(a sync object);
+
+    The described steps may be summarized as:
+       get -> lock -> CPU or DMA access to a buffer/s -> unlock -> put
+
+This framework includes the following two features.
+    1. read (shared) and write (exclusive) locks - A task is required to declare
+    the access type when the task tries to register a dmabuf;
+    READ, WRITE, READ DMA, or WRITE DMA.
+
+    The below is example codes,
+       struct dmabuf_sync *sync;
+
+       sync = dmabuf_sync_init(NULL, "test sync");
+
+       dmabuf_sync_get(sync, dmabuf, DMA_BUF_ACCESS_R);
+       ...
+
+       And the below can be used as access types:
+               DMA_BUF_ACCESS_R - CPU will access a buffer for read.
+               DMA_BUF_ACCESS_W - CPU will access a buffer for read or write.
+               DMA_BUF_ACCESS_DMA_R - DMA will access a buffer for read
+               DMA_BUF_ACCESS_DMA_W - DMA will access a buffer for read or
+                                       write.
+
+    2. Mandatory resource releasing - a task cannot hold a lock indefinitely.
+    A task may never try to unlock a buffer after taking a lock to the buffer.
+    In this case, a timer handler to the corresponding sync object is called
+    in five (default) seconds and then the timed-out buffer is unlocked by work
+    queue handler to avoid lockups and to enforce resources of the buffer.
+
+The below is how to use interfaces for device driver:
+       1. Allocate and Initialize a sync object:
+               struct dmabuf_sync *sync;
+
+               sync = dmabuf_sync_init(NULL, "test sync");
+               ...
+
+       2. Add a dmabuf to the sync object when setting up dma buffer relevant
+          registers:
+               dmabuf_sync_get(sync, dmabuf, DMA_BUF_ACCESS_READ);
+               ...
+
+       3. Lock all dmabufs of the sync object before DMA or CPU accesses
+          the dmabufs:
+               dmabuf_sync_lock(sync);
+               ...
+
+       4. Now CPU or DMA can access all dmabufs locked in step 3.
+
+       5. Unlock all dmabufs added in a sync object after DMA or CPU access
+          to these dmabufs is completed:
+               dmabuf_sync_unlock(sync);
+
+          And call the following functions to release all resources,
+               dmabuf_sync_put_all(sync);
+               dmabuf_sync_fini(sync);
+
+       You can refer to actual example codes:
+               "drm/exynos: add dmabuf sync support for g2d driver" and
+               "drm/exynos: add dmabuf sync support for kms framework" from
+               https://git.kernel.org/cgit/linux/kernel/git/daeinki/
+               drm-exynos.git/log/?h=dmabuf-sync
+
+And this framework includes fcntl system call[3] as interfaces exported
+to user. As you know, user sees a buffer object as a dma-buf file descriptor.
+So fcntl() call with the file descriptor means to lock some buffer region being
+managed by the dma-buf object.
+
+The below is how to use interfaces for user application:
+       struct flock filelock;
+
+       1. Lock a dma buf:
+               filelock.l_type = F_WRLCK or F_RDLCK;
+
+               /* lock entire region to the dma buf. */
+               filelock.lwhence = SEEK_CUR;
+               filelock.l_start = 0;
+               filelock.l_len = 0;
+
+               fcntl(dmabuf fd, F_SETLKW or F_SETLK, &filelock);
+               ...
+               CPU access to the dma buf
+
+       2. Unlock a dma buf:
+               filelock.l_type = F_UNLCK;
+
+               fcntl(dmabuf fd, F_SETLKW or F_SETLK, &filelock);
+
+               close(dmabuf fd) call would also unlock the dma buf. And for more
+               detail, please refer to [3]
+
+References:
+[1] http://lwn.net/Articles/470339/
+[2] https://patchwork.kernel.org/patch/2625361/
+[3] http://linux.die.net/man/2/fcntl
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/dma-buf-sync.txt | 290 ++++++++++++++++++
+ drivers/base/Kconfig           |   7 +
+ drivers/base/Makefile          |   1 +
+ drivers/base/dma-buf.c         |   4 +
+ drivers/base/dmabuf-sync.c     | 674 +++++++++++++++++++++++++++++++++++++++++
+ include/linux/dma-buf.h        |  16 +
+ include/linux/dmabuf-sync.h    | 178 +++++++++++
+ 7 files changed, 1170 insertions(+)
+ create mode 100644 Documentation/dma-buf-sync.txt
+ create mode 100644 drivers/base/dmabuf-sync.c
+ create mode 100644 include/linux/dmabuf-sync.h
+
+diff --git a/Documentation/dma-buf-sync.txt b/Documentation/dma-buf-sync.txt
+new file mode 100644
+index 0000000..4427759
+--- /dev/null
++++ b/Documentation/dma-buf-sync.txt
+@@ -0,0 +1,290 @@
++                    DMA Buffer Synchronization Framework
++                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++
++                                  Inki Dae
++                      <inki dot dae at samsung dot com>
++                          <daeinki at gmail dot com>
++
++This document is a guide for device-driver writers describing the DMA buffer
++synchronization API. This document also describes how to use the API to
++use buffer synchronization mechanism between DMA and DMA, CPU and DMA, and
++CPU and CPU.
++
++The DMA Buffer synchronization API provides buffer synchronization mechanism;
++i.e., buffer access control to CPU and DMA, and easy-to-use interfaces for
++device drivers and user application. And this API can be used for all dma
++devices using system memory as dma buffer, especially for most ARM based SoCs.
++
++
++Motivation
++----------
++
++Buffer synchronization issue between DMA and DMA:
++      Sharing a buffer, a device cannot be aware of when the other device
++      will access the shared buffer: a device may access a buffer containing
++      wrong data if the device accesses the shared buffer while another
++      device is still accessing the shared buffer.
++      Therefore, a user process should have waited for the completion of DMA
++      access by another device before a device tries to access the shared
++      buffer.
++
++Buffer synchronization issue between CPU and DMA:
++      A user process should consider that when having to send a buffer, filled
++      by CPU, to a device driver for the device driver to access the buffer as
++      a input buffer while CPU and DMA are sharing the buffer.
++      This means that the user process needs to understand how the device
++      driver is worked. Hence, the conventional mechanism not only makes
++      user application complicated but also incurs performance overhead.
++
++Buffer synchronization issue between CPU and CPU:
++      In case that two processes share one buffer; shared with DMA also,
++      they may need some mechanism to allow process B to access the shared
++      buffer after the completion of CPU access by process A.
++      Therefore, process B should have waited for the completion of CPU access
++      by process A using the mechanism before trying to access the shared
++      buffer.
++
++What is the best way to solve these buffer synchronization issues?
++      We may need a common object that a device driver and a user process
++      notify the common object of when they try to access a shared buffer.
++      That way we could decide when we have to allow or not to allow for CPU
++      or DMA to access the shared buffer through the common object.
++      If so, what could become the common object? Right, that's a dma-buf[1].
++      Now we have already been using the dma-buf to share one buffer with
++      other drivers.
++
++How we can utilize multi threads for more performance?
++      DMA and CPU works individually. So CPU could perform other works while
++      DMA are performing some works, and vise versa.
++      However, in the conventional way, that is not easy to do so because
++      DMA operation is depend on CPU operation, and vice versa.
++
++      Conventional way:
++        User                                     Kernel
++        ---------------------------------------------------------------------
++        CPU writes something to src
++        send the src to driver------------------------->
++                                                 update DMA register
++        request DMA start(1)--------------------------->
++                                                 DMA start
++                <---------completion signal(2)----------
++        CPU accesses dst
++
++        (1) Request DMA start after the CPU access to src buffer is completed.
++        (2) Access dst buffer after DMA access to the dst buffer is completed.
++
++On the other hand, if there is something to control buffer access between CPU
++and DMA? The below shows that:
++
++        User(thread a)          User(thread b)            Kernel
++        ---------------------------------------------------------------------
++        send a src to driver---------------------------------->
++                                                          update DMA register
++        lock the src
++                                request DMA start(1)---------->
++        CPU acccess to src
++        unlock the src                                    lock src and dst
++                                                          DMA start
++                <-------------completion signal(2)-------------
++        lock dst                                          DMA completion
++        CPU access to dst                                 unlock src and dst
++        unlock DST
++
++        (1) Try to start DMA operation while CPU is accessing the src buffer.
++        (2) Try CPU access to dst buffer while DMA is accessing the dst buffer.
++
++      In the same way, we could reduce hand shaking overhead between
++      two processes when those processes need to share a shared buffer.
++      There may be other cases that we could reduce overhead as well.
++
++
++Basic concept
++-------------
++
++The mechanism of this framework has the following steps,
++    1. Register dmabufs to a sync object - A task gets a new sync object and
++    can add one or more dmabufs that the task wants to access.
++    This registering should be performed when a device context or an event
++    context such as a page flip event is created or before CPU accesses a shared
++    buffer.
++
++      dma_buf_sync_get(a sync object, a dmabuf);
++
++    2. Lock a sync object - A task tries to lock all dmabufs added in its own
++    sync object. Basically, the lock mechanism uses ww-mutexes[2] to avoid dead
++    lock issue and for race condition between CPU and CPU, CPU and DMA, and DMA
++    and DMA. Taking a lock means that others cannot access all locked dmabufs
++    until the task that locked the corresponding dmabufs, unlocks all the locked
++    dmabufs.
++    This locking should be performed before DMA or CPU accesses these dmabufs.
++
++      dma_buf_sync_lock(a sync object);
++
++    3. Unlock a sync object - The task unlocks all dmabufs added in its own sync
++    object. The unlock means that the DMA or CPU accesses to the dmabufs have
++    been completed so that others may access them.
++    This unlocking should be performed after DMA or CPU has completed accesses
++    to the dmabufs.
++
++      dma_buf_sync_unlock(a sync object);
++
++    4. Unregister one or all dmabufs from a sync object - A task unregisters
++    the given dmabufs from the sync object. This means that the task dosen't
++    want to lock the dmabufs.
++    The unregistering should be performed after DMA or CPU has completed
++    accesses to the dmabufs or when dma_buf_sync_lock() is failed.
++
++      dma_buf_sync_put(a sync object, a dmabuf);
++      dma_buf_sync_put_all(a sync object);
++
++    The described steps may be summarized as:
++      get -> lock -> CPU or DMA access to a buffer/s -> unlock -> put
++
++This framework includes the following two features.
++    1. read (shared) and write (exclusive) locks - A task is required to declare
++    the access type when the task tries to register a dmabuf;
++    READ, WRITE, READ DMA, or WRITE DMA.
++
++    The below is example codes,
++      struct dmabuf_sync *sync;
++
++      sync = dmabuf_sync_init(NULL, "test sync");
++
++      dmabuf_sync_get(sync, dmabuf, DMA_BUF_ACCESS_R);
++      ...
++
++    2. Mandatory resource releasing - a task cannot hold a lock indefinitely.
++    A task may never try to unlock a buffer after taking a lock to the buffer.
++    In this case, a timer handler to the corresponding sync object is called
++    in five (default) seconds and then the timed-out buffer is unlocked by work
++    queue handler to avoid lockups and to enforce resources of the buffer.
++
++
++Access types
++------------
++
++DMA_BUF_ACCESS_R - CPU will access a buffer for read.
++DMA_BUF_ACCESS_W - CPU will access a buffer for read or write.
++DMA_BUF_ACCESS_DMA_R - DMA will access a buffer for read
++DMA_BUF_ACCESS_DMA_W - DMA will access a buffer for read or write.
++
++
++Generic user interfaces
++-----------------------
++
++And this framework includes fcntl system call[3] as interfaces exported
++to user. As you know, user sees a buffer object as a dma-buf file descriptor.
++So fcntl() call with the file descriptor means to lock some buffer region being
++managed by the dma-buf object.
++
++
++API set
++-------
++
++bool is_dmabuf_sync_supported(void)
++      - Check if dmabuf sync is supported or not.
++
++struct dmabuf_sync *dmabuf_sync_init(void *priv, const char *name)
++      - Allocate and initialize a new sync object. The caller can get a new
++      sync object for buffer synchronization. priv is used to set caller's
++      private data and name is the name of sync object.
++
++void dmabuf_sync_fini(struct dmabuf_sync *sync)
++      - Release all resources to the sync object.
++
++int dmabuf_sync_get(struct dmabuf_sync *sync, void *sync_buf,
++                      unsigned int type)
++      - Get dmabuf sync object. Internally, this function allocates
++      a dmabuf_sync object and adds a given dmabuf to it, and also takes
++      a reference to the dmabuf. The caller can tie up multiple dmabufs
++      into one sync object by calling this function several times.
++
++void dmabuf_sync_put(struct dmabuf_sync *sync, struct dma_buf *dmabuf)
++      - Put dmabuf sync object to a given dmabuf. Internally, this function
++      removes a given dmabuf from a sync object and remove the sync object.
++      At this time, the dmabuf is putted.
++
++void dmabuf_sync_put_all(struct dmabuf_sync *sync)
++      - Put dmabuf sync object to dmabufs. Internally, this function removes
++      all dmabufs from a sync object and remove the sync object.
++      At this time, all dmabufs are putted.
++
++int dmabuf_sync_lock(struct dmabuf_sync *sync)
++      - Lock all dmabufs added in a sync object. The caller should call this
++      function prior to CPU or DMA access to the dmabufs so that others can
++      not access the dmabufs. Internally, this function avoids dead lock
++      issue with ww-mutexes.
++
++int dmabuf_sync_single_lock(struct dma_buf *dmabuf)
++      - Lock a dmabuf. The caller should call this
++      function prior to CPU or DMA access to the dmabuf so that others can
++      not access the dmabuf.
++
++int dmabuf_sync_unlock(struct dmabuf_sync *sync)
++      - Unlock all dmabufs added in a sync object. The caller should call
++      this function after CPU or DMA access to the dmabufs is completed so
++      that others can access the dmabufs.
++
++void dmabuf_sync_single_unlock(struct dma_buf *dmabuf)
++      - Unlock a dmabuf. The caller should call this function after CPU or
++      DMA access to the dmabuf is completed so that others can access
++      the dmabuf.
++
++
++Tutorial for device driver
++--------------------------
++
++1. Allocate and Initialize a sync object:
++      struct dmabuf_sync *sync;
++
++      sync = dmabuf_sync_init(NULL, "test sync");
++      ...
++
++2. Add a dmabuf to the sync object when setting up dma buffer relevant registers:
++      dmabuf_sync_get(sync, dmabuf, DMA_BUF_ACCESS_READ);
++      ...
++
++3. Lock all dmabufs of the sync object before DMA or CPU accesses the dmabufs:
++      dmabuf_sync_lock(sync);
++      ...
++
++4. Now CPU or DMA can access all dmabufs locked in step 3.
++
++5. Unlock all dmabufs added in a sync object after DMA or CPU access to these
++   dmabufs is completed:
++      dmabuf_sync_unlock(sync);
++
++   And call the following functions to release all resources,
++      dmabuf_sync_put_all(sync);
++      dmabuf_sync_fini(sync);
++
++
++Tutorial for user application
++-----------------------------
++      struct flock filelock;
++
++1. Lock a dma buf:
++      filelock.l_type = F_WRLCK or F_RDLCK;
++
++      /* lock entire region to the dma buf. */
++      filelock.lwhence = SEEK_CUR;
++      filelock.l_start = 0;
++      filelock.l_len = 0;
++
++      fcntl(dmabuf fd, F_SETLKW or F_SETLK, &filelock);
++      ...
++      CPU access to the dma buf
++
++2. Unlock a dma buf:
++      filelock.l_type = F_UNLCK;
++
++      fcntl(dmabuf fd, F_SETLKW or F_SETLK, &filelock);
++
++      close(dmabuf fd) call would also unlock the dma buf. And for more
++      detail, please refer to [3]
++
++
++References:
++[1] http://lwn.net/Articles/470339/
++[2] https://patchwork.kernel.org/patch/2625361/
++[3] http://linux.die.net/man/2/fcntl
+diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
+index 07abd9d..eb89421 100644
+--- a/drivers/base/Kconfig
++++ b/drivers/base/Kconfig
+@@ -202,6 +202,13 @@ config DMA_SHARED_BUFFER
+         APIs extension; the file's descriptor can then be passed on to other
+         driver.
++config DMABUF_SYNC
++      bool "DMABUF Synchronization Framework"
++      depends on DMA_SHARED_BUFFER
++      help
++        This option enables dmabuf sync framework for buffer synchronization between
++        DMA and DMA, CPU and DMA, and CPU and CPU.
++
+ config CMA
+       bool "Contiguous Memory Allocator"
+       depends on HAVE_DMA_CONTIGUOUS && HAVE_MEMBLOCK
+diff --git a/drivers/base/Makefile b/drivers/base/Makefile
+index 4e22ce3..548d434 100644
+--- a/drivers/base/Makefile
++++ b/drivers/base/Makefile
+@@ -11,6 +11,7 @@ obj-y                        += power/
+ obj-$(CONFIG_HAS_DMA) += dma-mapping.o
+ obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o
+ obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf.o
++obj-$(CONFIG_DMABUF_SYNC) += dmabuf-sync.o
+ obj-$(CONFIG_ISA)     += isa.o
+ obj-$(CONFIG_FW_LOADER)       += firmware_class.o
+ obj-$(CONFIG_NUMA)    += node.o
+diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
+index 08fe897..9a26981 100644
+--- a/drivers/base/dma-buf.c
++++ b/drivers/base/dma-buf.c
+@@ -29,6 +29,7 @@
+ #include <linux/export.h>
+ #include <linux/debugfs.h>
+ #include <linux/seq_file.h>
++#include <linux/dmabuf-sync.h>
+ static inline int is_dma_buf_file(struct file *);
+@@ -56,6 +57,8 @@ static int dma_buf_release(struct inode *inode, struct file *file)
+       list_del(&dmabuf->list_node);
+       mutex_unlock(&db_list.lock);
++      dmabuf_sync_reservation_fini(dmabuf);
++
+       kfree(dmabuf);
+       return 0;
+ }
+@@ -134,6 +137,7 @@ struct dma_buf *dma_buf_export_named(void *priv, const struct dma_buf_ops *ops,
+       file = anon_inode_getfile("dmabuf", &dma_buf_fops, dmabuf, flags);
++      dmabuf_sync_reservation_init(dmabuf);
+       dmabuf->file = file;
+       mutex_init(&dmabuf->lock);
+diff --git a/drivers/base/dmabuf-sync.c b/drivers/base/dmabuf-sync.c
+new file mode 100644
+index 0000000..0b83111
+--- /dev/null
++++ b/drivers/base/dmabuf-sync.c
+@@ -0,0 +1,674 @@
++/*
++ * Copyright (C) 2013 Samsung Electronics Co.Ltd
++ * Authors:
++ *    Inki Dae <inki.dae@samsung.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/module.h>
++#include <linux/slab.h>
++#include <linux/debugfs.h>
++#include <linux/uaccess.h>
++
++#include <linux/dmabuf-sync.h>
++
++#define MAX_SYNC_TIMEOUT      5 /* Second. */
++
++int dmabuf_sync_enabled = 1;
++
++MODULE_PARM_DESC(enabled, "Check if dmabuf sync is supported or not");
++module_param_named(enabled, dmabuf_sync_enabled, int, 0444);
++
++DEFINE_WW_CLASS(dmabuf_sync_ww_class);
++EXPORT_SYMBOL(dmabuf_sync_ww_class);
++
++static void dmabuf_sync_timeout_worker(struct work_struct *work)
++{
++      struct dmabuf_sync *sync = container_of(work, struct dmabuf_sync, work);
++      struct dmabuf_sync_object *sobj;
++
++      mutex_lock(&sync->lock);
++
++      list_for_each_entry(sobj, &sync->syncs, head) {
++              if (WARN_ON(!sobj->robj))
++                      continue;
++
++              mutex_lock(&sobj->robj->lock);
++
++              printk(KERN_WARNING "%s: timeout = 0x%x [type = %d, " \
++                                      "refcnt = %d, locked = %d]\n",
++                                      sync->name, (u32)sobj->dmabuf,
++                                      sobj->access_type,
++                                      atomic_read(&sobj->robj->shared_cnt),
++                                      sobj->robj->locked);
++
++              /* unlock only valid sync object. */
++              if (!sobj->robj->locked) {
++                      mutex_unlock(&sobj->robj->lock);
++                      continue;
++              }
++
++              if (sobj->robj->shared &&
++                  atomic_add_unless(&sobj->robj->shared_cnt, -1, 1)) {
++                      mutex_unlock(&sobj->robj->lock);
++                      continue;
++              }
++
++              mutex_unlock(&sobj->robj->lock);
++
++              ww_mutex_unlock(&sobj->robj->sync_lock);
++
++              mutex_lock(&sobj->robj->lock);
++
++              if (sobj->access_type & DMA_BUF_ACCESS_R)
++                      printk(KERN_WARNING "%s: r-unlocked = 0x%x\n",
++                                      sync->name, (u32)sobj->dmabuf);
++              else
++                      printk(KERN_WARNING "%s: w-unlocked = 0x%x\n",
++                                      sync->name, (u32)sobj->dmabuf);
++
++              mutex_unlock(&sobj->robj->lock);
++      }
++
++      sync->status = 0;
++      mutex_unlock(&sync->lock);
++
++      dmabuf_sync_put_all(sync);
++      dmabuf_sync_fini(sync);
++}
++
++static void dmabuf_sync_lock_timeout(unsigned long arg)
++{
++      struct dmabuf_sync *sync = (struct dmabuf_sync *)arg;
++
++      schedule_work(&sync->work);
++}
++
++static int dmabuf_sync_lock_objs(struct dmabuf_sync *sync,
++                                      struct ww_acquire_ctx *ctx)
++{
++      struct dmabuf_sync_object *contended_sobj = NULL;
++      struct dmabuf_sync_object *res_sobj = NULL;
++      struct dmabuf_sync_object *sobj = NULL;
++      int ret;
++
++      if (ctx)
++              ww_acquire_init(ctx, &dmabuf_sync_ww_class);
++
++retry:
++      list_for_each_entry(sobj, &sync->syncs, head) {
++              if (WARN_ON(!sobj->robj))
++                      continue;
++
++              mutex_lock(&sobj->robj->lock);
++
++              /* Don't lock in case of read and read. */
++              if (sobj->robj->accessed_type & DMA_BUF_ACCESS_R &&
++                  sobj->access_type & DMA_BUF_ACCESS_R) {
++                      atomic_inc(&sobj->robj->shared_cnt);
++                      sobj->robj->shared = true;
++                      mutex_unlock(&sobj->robj->lock);
++                      continue;
++              }
++
++              if (sobj == res_sobj) {
++                      res_sobj = NULL;
++                      mutex_unlock(&sobj->robj->lock);
++                      continue;
++              }
++
++              mutex_unlock(&sobj->robj->lock);
++
++              ret = ww_mutex_lock(&sobj->robj->sync_lock, ctx);
++              if (ret < 0) {
++                      contended_sobj = sobj;
++
++                      if (ret == -EDEADLK)
++                              printk(KERN_WARNING"%s: deadlock = 0x%x\n",
++                                      sync->name, (u32)sobj->dmabuf);
++                      goto err;
++              }
++
++              mutex_lock(&sobj->robj->lock);
++              sobj->robj->locked = true;
++
++              mutex_unlock(&sobj->robj->lock);
++      }
++
++      if (ctx)
++              ww_acquire_done(ctx);
++
++      init_timer(&sync->timer);
++
++      sync->timer.data = (unsigned long)sync;
++      sync->timer.function = dmabuf_sync_lock_timeout;
++      sync->timer.expires = jiffies + (HZ * MAX_SYNC_TIMEOUT);
++
++      add_timer(&sync->timer);
++
++      return 0;
++
++err:
++      list_for_each_entry_continue_reverse(sobj, &sync->syncs, head) {
++              mutex_lock(&sobj->robj->lock);
++
++              /* Don't need to unlock in case of read and read. */
++              if (atomic_add_unless(&sobj->robj->shared_cnt, -1, 1)) {
++                      mutex_unlock(&sobj->robj->lock);
++                      continue;
++              }
++
++              ww_mutex_unlock(&sobj->robj->sync_lock);
++              sobj->robj->locked = false;
++
++              mutex_unlock(&sobj->robj->lock);
++      }
++
++      if (res_sobj) {
++              mutex_lock(&res_sobj->robj->lock);
++
++              if (!atomic_add_unless(&res_sobj->robj->shared_cnt, -1, 1)) {
++                      ww_mutex_unlock(&res_sobj->robj->sync_lock);
++                      res_sobj->robj->locked = false;
++              }
++
++              mutex_unlock(&res_sobj->robj->lock);
++      }
++
++      if (ret == -EDEADLK) {
++              ww_mutex_lock_slow(&contended_sobj->robj->sync_lock, ctx);
++              res_sobj = contended_sobj;
++
++              goto retry;
++      }
++
++      if (ctx)
++              ww_acquire_fini(ctx);
++
++      return ret;
++}
++
++static void dmabuf_sync_unlock_objs(struct dmabuf_sync *sync,
++                                      struct ww_acquire_ctx *ctx)
++{
++      struct dmabuf_sync_object *sobj;
++
++      if (list_empty(&sync->syncs))
++              return;
++
++      mutex_lock(&sync->lock);
++
++      list_for_each_entry(sobj, &sync->syncs, head) {
++              mutex_lock(&sobj->robj->lock);
++
++              if (sobj->robj->shared) {
++                      if (atomic_add_unless(&sobj->robj->shared_cnt, -1,
++                                              1)) {
++                              mutex_unlock(&sobj->robj->lock);
++                              continue;
++                      }
++
++                      mutex_unlock(&sobj->robj->lock);
++
++                      ww_mutex_unlock(&sobj->robj->sync_lock);
++
++                      mutex_lock(&sobj->robj->lock);
++                      sobj->robj->shared = false;
++                      sobj->robj->locked = false;
++              } else {
++                      mutex_unlock(&sobj->robj->lock);
++
++                      ww_mutex_unlock(&sobj->robj->sync_lock);
++
++                      mutex_lock(&sobj->robj->lock);
++                      sobj->robj->locked = false;
++              }
++
++              mutex_unlock(&sobj->robj->lock);
++      }
++
++      mutex_unlock(&sync->lock);
++
++      if (ctx)
++              ww_acquire_fini(ctx);
++
++      del_timer(&sync->timer);
++}
++
++/**
++ * is_dmabuf_sync_supported - Check if dmabuf sync is supported or not.
++ */
++bool is_dmabuf_sync_supported(void)
++{
++      return dmabuf_sync_enabled == 1;
++}
++EXPORT_SYMBOL(is_dmabuf_sync_supported);
++
++/**
++ * dmabuf_sync_init - Allocate and initialize a dmabuf sync.
++ *
++ * @priv: A device private data.
++ * @name: A sync object name.
++ *
++ * This function should be called when a device context or an event
++ * context such as a page flip event is created. And the created
++ * dmabuf_sync object should be set to the context.
++ * The caller can get a new sync object for buffer synchronization
++ * through this function.
++ */
++struct dmabuf_sync *dmabuf_sync_init(void *priv, const char *name)
++{
++      struct dmabuf_sync *sync;
++
++      sync = kzalloc(sizeof(*sync), GFP_KERNEL);
++      if (!sync)
++              return ERR_PTR(-ENOMEM);
++
++      strncpy(sync->name, name, ARRAY_SIZE(sync->name) - 1);
++
++      sync->priv = priv;
++      INIT_LIST_HEAD(&sync->syncs);
++      mutex_init(&sync->lock);
++      INIT_WORK(&sync->work, dmabuf_sync_timeout_worker);
++
++      return sync;
++}
++EXPORT_SYMBOL(dmabuf_sync_init);
++
++/**
++ * dmabuf_sync_fini - Release a given dmabuf sync.
++ *
++ * @sync: An object to dmabuf_sync structure.
++ *
++ * This function should be called if some operation is failed after
++ * dmabuf_sync_init call to release relevant resources, and after
++ * dmabuf_sync_unlock function is called.
++ */
++void dmabuf_sync_fini(struct dmabuf_sync *sync)
++{
++      if (WARN_ON(!sync))
++              return;
++
++      kfree(sync);
++}
++EXPORT_SYMBOL(dmabuf_sync_fini);
++
++/*
++ * dmabuf_sync_get_obj - Add a given object to syncs list.
++ *
++ * @sync: An object to dmabuf_sync structure.
++ * @dmabuf: An object to dma_buf structure.
++ * @type: A access type to a dma buf.
++ *    The DMA_BUF_ACCESS_R means that this dmabuf could be accessed by
++ *    others for read access. On the other hand, the DMA_BUF_ACCESS_W
++ *    means that this dmabuf couldn't be accessed by others but would be
++ *    accessed by caller's dma exclusively. And the DMA_BUF_ACCESS_DMA can be
++ *    combined.
++ *
++ * This function creates and initializes a new dmabuf sync object and it adds
++ * the dmabuf sync object to syncs list to track and manage all dmabufs.
++ */
++static int dmabuf_sync_get_obj(struct dmabuf_sync *sync, struct dma_buf *dmabuf,
++                                      unsigned int type)
++{
++      struct dmabuf_sync_object *sobj;
++
++      if (!dmabuf->sync) {
++              WARN_ON(1);
++              return -EFAULT;
++      }
++
++      if (!IS_VALID_DMA_BUF_ACCESS_TYPE(type))
++              return -EINVAL;
++
++      if ((type & DMA_BUF_ACCESS_RW) == DMA_BUF_ACCESS_RW)
++              type &= ~DMA_BUF_ACCESS_R;
++
++      sobj = kzalloc(sizeof(*sobj), GFP_KERNEL);
++      if (!sobj) {
++              WARN_ON(1);
++              return -ENOMEM;
++      }
++
++      sobj->dmabuf = dmabuf;
++      sobj->robj = dmabuf->sync;
++
++      mutex_lock(&sync->lock);
++      list_add_tail(&sobj->head, &sync->syncs);
++      mutex_unlock(&sync->lock);
++
++      get_dma_buf(dmabuf);
++
++      mutex_lock(&sobj->robj->lock);
++      sobj->access_type = type;
++      mutex_unlock(&sobj->robj->lock);
++
++      return 0;
++}
++
++/*
++ * dmabuf_sync_put_obj - Release a given sync object.
++ *
++ * @sync: An object to dmabuf_sync structure.
++ *
++ * This function should be called if some operation is failed after
++ * dmabuf_sync_get_obj call to release a given sync object.
++ */
++static void dmabuf_sync_put_obj(struct dmabuf_sync *sync,
++                                      struct dma_buf *dmabuf)
++{
++      struct dmabuf_sync_object *sobj;
++
++      mutex_lock(&sync->lock);
++
++      list_for_each_entry(sobj, &sync->syncs, head) {
++              if (sobj->dmabuf != dmabuf)
++                      continue;
++
++              dma_buf_put(sobj->dmabuf);
++
++              list_del_init(&sobj->head);
++              kfree(sobj);
++              break;
++      }
++
++      if (list_empty(&sync->syncs))
++              sync->status = 0;
++
++      mutex_unlock(&sync->lock);
++}
++
++/*
++ * dmabuf_sync_put_objs - Release all sync objects of dmabuf_sync.
++ *
++ * @sync: An object to dmabuf_sync structure.
++ *
++ * This function should be called if some operation is failed after
++ * dmabuf_sync_get_obj call to release all sync objects.
++ */
++static void dmabuf_sync_put_objs(struct dmabuf_sync *sync)
++{
++      struct dmabuf_sync_object *sobj, *next;
++
++      mutex_lock(&sync->lock);
++
++      list_for_each_entry_safe(sobj, next, &sync->syncs, head) {
++              dma_buf_put(sobj->dmabuf);
++
++              list_del_init(&sobj->head);
++              kfree(sobj);
++      }
++
++      mutex_unlock(&sync->lock);
++
++      sync->status = 0;
++}
++
++/**
++ * dmabuf_sync_lock - lock all dmabufs added to syncs list.
++ *
++ * @sync: An object to dmabuf_sync structure.
++ *
++ * The caller should call this function prior to CPU or DMA access to
++ * the dmabufs so that others can not access the dmabufs.
++ * Internally, this function avoids dead lock issue with ww-mutex.
++ */
++int dmabuf_sync_lock(struct dmabuf_sync *sync)
++{
++      int ret;
++
++      if (!sync) {
++              WARN_ON(1);
++              return -EFAULT;
++      }
++
++      if (list_empty(&sync->syncs))
++              return -EINVAL;
++
++      if (sync->status != DMABUF_SYNC_GOT)
++              return -EINVAL;
++
++      ret = dmabuf_sync_lock_objs(sync, &sync->ctx);
++      if (ret < 0) {
++              WARN_ON(1);
++              return ret;
++      }
++
++      sync->status = DMABUF_SYNC_LOCKED;
++
++      return ret;
++}
++EXPORT_SYMBOL(dmabuf_sync_lock);
++
++/**
++ * dmabuf_sync_unlock - unlock all objects added to syncs list.
++ *
++ * @sync: An object to dmabuf_sync structure.
++ *
++ * The caller should call this function after CPU or DMA access to
++ * the dmabufs is completed so that others can access the dmabufs.
++ */
++int dmabuf_sync_unlock(struct dmabuf_sync *sync)
++{
++      if (!sync) {
++              WARN_ON(1);
++              return -EFAULT;
++      }
++
++      /* If current dmabuf sync object wasn't reserved then just return. */
++      if (sync->status != DMABUF_SYNC_LOCKED)
++              return -EAGAIN;
++
++      dmabuf_sync_unlock_objs(sync, &sync->ctx);
++
++      return 0;
++}
++EXPORT_SYMBOL(dmabuf_sync_unlock);
++
++/**
++ * dmabuf_sync_single_lock - lock a dma buf.
++ *
++ * @dmabuf: A dma buf object that tries to lock.
++ * @type: A access type to a dma buf.
++ *    The DMA_BUF_ACCESS_R means that this dmabuf could be accessed by
++ *    others for read access. On the other hand, the DMA_BUF_ACCESS_W
++ *    means that this dmabuf couldn't be accessed by others but would be
++ *    accessed by caller's dma exclusively. And the DMA_BUF_ACCESS_DMA can
++ *    be combined with other.
++ * @wait: Indicate whether caller is blocked or not.
++ *    true means that caller will be blocked, and false means that this
++ *    function will return -EAGAIN if this caller can't take the lock
++ *    right now.
++ *
++ * The caller should call this function prior to CPU or DMA access to the dmabuf
++ * so that others cannot access the dmabuf.
++ */
++int dmabuf_sync_single_lock(struct dma_buf *dmabuf, unsigned int type,
++                              bool wait)
++{
++      struct dmabuf_sync_reservation *robj;
++
++      if (!dmabuf->sync) {
++              WARN_ON(1);
++              return -EFAULT;
++      }
++
++      if (!IS_VALID_DMA_BUF_ACCESS_TYPE(type)) {
++              WARN_ON(1);
++              return -EINVAL;
++      }
++
++      get_dma_buf(dmabuf);
++      robj = dmabuf->sync;
++
++      mutex_lock(&robj->lock);
++
++      /* Don't lock in case of read and read. */
++      if (robj->accessed_type & DMA_BUF_ACCESS_R && type & DMA_BUF_ACCESS_R) {
++              atomic_inc(&robj->shared_cnt);
++              robj->shared = true;
++              mutex_unlock(&robj->lock);
++              return 0;
++      }
++
++      /*
++       * In case of F_SETLK, just return -EAGAIN if this dmabuf has already
++       * been locked.
++       */
++      if (!wait && robj->locked) {
++              mutex_unlock(&robj->lock);
++              dma_buf_put(dmabuf);
++              return -EAGAIN;
++      }
++
++      mutex_unlock(&robj->lock);
++
++      mutex_lock(&robj->sync_lock.base);
++
++      mutex_lock(&robj->lock);
++      robj->locked = true;
++      mutex_unlock(&robj->lock);
++
++      return 0;
++}
++EXPORT_SYMBOL(dmabuf_sync_single_lock);
++
++/**
++ * dmabuf_sync_single_unlock - unlock a dma buf.
++ *
++ * @dmabuf: A dma buf object that tries to unlock.
++ *
++ * The caller should call this function after CPU or DMA access to
++ * the dmabuf is completed so that others can access the dmabuf.
++ */
++void dmabuf_sync_single_unlock(struct dma_buf *dmabuf)
++{
++      struct dmabuf_sync_reservation *robj;
++
++      if (!dmabuf->sync) {
++              WARN_ON(1);
++              return;
++      }
++
++      robj = dmabuf->sync;
++
++      mutex_lock(&robj->lock);
++
++      if (robj->shared) {
++              if (atomic_add_unless(&robj->shared_cnt, -1 , 1)) {
++                      mutex_unlock(&robj->lock);
++                      return;
++              }
++
++              robj->shared = false;
++      }
++
++      mutex_unlock(&robj->lock);
++
++      mutex_unlock(&robj->sync_lock.base);
++
++      mutex_lock(&robj->lock);
++      robj->locked = false;
++      mutex_unlock(&robj->lock);
++
++      dma_buf_put(dmabuf);
++
++      return;
++}
++EXPORT_SYMBOL(dmabuf_sync_single_unlock);
++
++/**
++ * dmabuf_sync_get - Get dmabuf sync object.
++ *
++ * @sync: An object to dmabuf_sync structure.
++ * @sync_buf: A dmabuf object to be synchronized with others.
++ * @type: A access type to a dma buf.
++ *    The DMA_BUF_ACCESS_R means that this dmabuf could be accessed by
++ *    others for read access. On the other hand, the DMA_BUF_ACCESS_W
++ *    means that this dmabuf couldn't be accessed by others but would be
++ *    accessed by caller's dma exclusively. And the DMA_BUF_ACCESS_DMA can
++ *    be combined with other.
++ *
++ * This function should be called after dmabuf_sync_init function is called.
++ * The caller can tie up multiple dmabufs into one sync object by calling this
++ * function several times. Internally, this function allocates
++ * a dmabuf_sync_object and adds a given dmabuf to it, and also takes
++ * a reference to a dmabuf.
++ */
++int dmabuf_sync_get(struct dmabuf_sync *sync, void *sync_buf, unsigned int type)
++{
++      int ret;
++
++      if (!sync || !sync_buf) {
++              WARN_ON(1);
++              return -EFAULT;
++      }
++
++      ret = dmabuf_sync_get_obj(sync, sync_buf, type);
++      if (ret < 0) {
++              WARN_ON(1);
++              return ret;
++      }
++
++      sync->status = DMABUF_SYNC_GOT;
++
++      return 0;
++}
++EXPORT_SYMBOL(dmabuf_sync_get);
++
++/**
++ * dmabuf_sync_put - Put dmabuf sync object to a given dmabuf.
++ *
++ * @sync: An object to dmabuf_sync structure.
++ * @dmabuf: An dmabuf object.
++ *
++ * This function should be called if some operation is failed after
++ * dmabuf_sync_get function is called to release the dmabuf, or
++ * dmabuf_sync_unlock function is called. Internally, this function
++ * removes a given dmabuf from a sync object and remove the sync object.
++ * At this time, the dmabuf is putted.
++ */
++void dmabuf_sync_put(struct dmabuf_sync *sync, struct dma_buf *dmabuf)
++{
++      if (!sync || !dmabuf) {
++              WARN_ON(1);
++              return;
++      }
++
++      if (list_empty(&sync->syncs))
++              return;
++
++      dmabuf_sync_put_obj(sync, dmabuf);
++}
++EXPORT_SYMBOL(dmabuf_sync_put);
++
++/**
++ * dmabuf_sync_put_all - Put dmabuf sync object to dmabufs.
++ *
++ * @sync: An object to dmabuf_sync structure.
++ *
++ * This function should be called if some operation is failed after
++ * dmabuf_sync_get function is called to release all sync objects, or
++ * dmabuf_sync_unlock function is called. Internally, this function
++ * removes dmabufs from a sync object and remove the sync object.
++ * At this time, all dmabufs are putted.
++ */
++void dmabuf_sync_put_all(struct dmabuf_sync *sync)
++{
++      if (!sync) {
++              WARN_ON(1);
++              return;
++      }
++
++      if (list_empty(&sync->syncs))
++              return;
++
++      dmabuf_sync_put_objs(sync);
++}
++EXPORT_SYMBOL(dmabuf_sync_put_all);
+diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
+index dfac5ed..0109673 100644
+--- a/include/linux/dma-buf.h
++++ b/include/linux/dma-buf.h
+@@ -115,6 +115,7 @@ struct dma_buf_ops {
+  * @exp_name: name of the exporter; useful for debugging.
+  * @list_node: node for dma_buf accounting and debugging.
+  * @priv: exporter specific private data for this buffer object.
++ * @sync: sync object linked to this dma-buf
+  */
+ struct dma_buf {
+       size_t size;
+@@ -128,6 +129,7 @@ struct dma_buf {
+       const char *exp_name;
+       struct list_head list_node;
+       void *priv;
++      void *sync;
+ };
+ /**
+@@ -148,6 +150,20 @@ struct dma_buf_attachment {
+       void *priv;
+ };
++#define       DMA_BUF_ACCESS_R        0x1
++#define DMA_BUF_ACCESS_W      0x2
++#define DMA_BUF_ACCESS_DMA    0x4
++#define DMA_BUF_ACCESS_RW     (DMA_BUF_ACCESS_R | DMA_BUF_ACCESS_W)
++#define DMA_BUF_ACCESS_DMA_R  (DMA_BUF_ACCESS_R | DMA_BUF_ACCESS_DMA)
++#define DMA_BUF_ACCESS_DMA_W  (DMA_BUF_ACCESS_W | DMA_BUF_ACCESS_DMA)
++#define DMA_BUF_ACCESS_DMA_RW (DMA_BUF_ACCESS_DMA_R | DMA_BUF_ACCESS_DMA_W)
++#define IS_VALID_DMA_BUF_ACCESS_TYPE(t)       (t == DMA_BUF_ACCESS_R || \
++                                       t == DMA_BUF_ACCESS_W || \
++                                       t == DMA_BUF_ACCESS_DMA_R || \
++                                       t == DMA_BUF_ACCESS_DMA_W || \
++                                       t == DMA_BUF_ACCESS_RW || \
++                                       t == DMA_BUF_ACCESS_DMA_RW)
++
+ /**
+  * get_dma_buf - convenience wrapper for get_file.
+  * @dmabuf:   [in]    pointer to dma_buf
+diff --git a/include/linux/dmabuf-sync.h b/include/linux/dmabuf-sync.h
+new file mode 100644
+index 0000000..2502ad6
+--- /dev/null
++++ b/include/linux/dmabuf-sync.h
+@@ -0,0 +1,178 @@
++/*
++ * Copyright (C) 2013 Samsung Electronics Co.Ltd
++ * Authors:
++ *    Inki Dae <inki.dae@samsung.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/mutex.h>
++#include <linux/sched.h>
++#include <linux/dma-buf.h>
++
++enum dmabuf_sync_status {
++      DMABUF_SYNC_GOT         = 1,
++      DMABUF_SYNC_LOCKED,
++};
++
++struct dmabuf_sync_reservation {
++      struct ww_mutex         sync_lock;
++      struct mutex            lock;
++      atomic_t                shared_cnt;
++      unsigned int            accessed_type;
++      unsigned int            shared;
++      unsigned int            locked;
++};
++
++/*
++ * A structure for dmabuf_sync_object.
++ *
++ * @head: A list head to be added to syncs list.
++ * @robj: A reservation_object object.
++ * @dma_buf: A dma_buf object.
++ * @access_type: Indicate how a current task tries to access
++ *    a given buffer.
++ */
++struct dmabuf_sync_object {
++      struct list_head                head;
++      struct dmabuf_sync_reservation  *robj;
++      struct dma_buf                  *dmabuf;
++      unsigned int                    access_type;
++};
++
++/*
++ * A structure for dmabuf_sync.
++ *
++ * @syncs: A list head to sync object and this is global to system.
++ * @list: A list entry used as committed list node
++ * @lock: A mutex lock to current sync object.
++ * @ctx: A current context for ww mutex.
++ * @work: A work struct to release resources at timeout.
++ * @priv: A private data.
++ * @name: A string to dmabuf sync owner.
++ * @timer: A timer list to avoid lockup and release resources.
++ * @status: Indicate current status (DMABUF_SYNC_GOT or DMABUF_SYNC_LOCKED).
++ */
++struct dmabuf_sync {
++      struct list_head        syncs;
++      struct list_head        list;
++      struct mutex            lock;
++      struct ww_acquire_ctx   ctx;
++      struct work_struct      work;
++      void                    *priv;
++      char                    name[64];
++      struct timer_list       timer;
++      unsigned int            status;
++};
++
++#ifdef CONFIG_DMABUF_SYNC
++
++extern struct ww_class dmabuf_sync_ww_class;
++
++static inline void dmabuf_sync_reservation_init(struct dma_buf *dmabuf)
++{
++      struct dmabuf_sync_reservation *obj;
++
++      obj = kzalloc(sizeof(*obj), GFP_KERNEL);
++      if (!obj)
++              return;
++
++      dmabuf->sync = obj;
++
++      ww_mutex_init(&obj->sync_lock, &dmabuf_sync_ww_class);
++
++      mutex_init(&obj->lock);
++      atomic_set(&obj->shared_cnt, 1);
++}
++
++static inline void dmabuf_sync_reservation_fini(struct dma_buf *dmabuf)
++{
++      struct dmabuf_sync_reservation *obj;
++
++      if (!dmabuf->sync)
++              return;
++
++      obj = dmabuf->sync;
++
++      ww_mutex_destroy(&obj->sync_lock);
++
++      kfree(obj);
++}
++
++extern bool is_dmabuf_sync_supported(void);
++
++extern struct dmabuf_sync *dmabuf_sync_init(void *priv, const char *name);
++
++extern void dmabuf_sync_fini(struct dmabuf_sync *sync);
++
++extern int dmabuf_sync_lock(struct dmabuf_sync *sync);
++
++extern int dmabuf_sync_unlock(struct dmabuf_sync *sync);
++
++int dmabuf_sync_single_lock(struct dma_buf *dmabuf, unsigned int type,
++                              bool wait);
++
++void dmabuf_sync_single_unlock(struct dma_buf *dmabuf);
++
++extern int dmabuf_sync_get(struct dmabuf_sync *sync, void *sync_buf,
++                              unsigned int type);
++
++extern void dmabuf_sync_put(struct dmabuf_sync *sync, struct dma_buf *dmabuf);
++
++extern void dmabuf_sync_put_all(struct dmabuf_sync *sync);
++
++#else
++
++static inline void dmabuf_sync_reservation_init(struct dma_buf *dmabuf) { }
++
++static inline void dmabuf_sync_reservation_fini(struct dma_buf *dmabuf) { }
++
++static inline bool is_dmabuf_sync_supported(void) { return false; }
++
++static inline struct dmabuf_sync *dmabuf_sync_init(void *priv,
++                                      const char *names)
++{
++      return ERR_PTR(0);
++}
++
++static inline void dmabuf_sync_fini(struct dmabuf_sync *sync) { }
++
++static inline int dmabuf_sync_lock(struct dmabuf_sync *sync)
++{
++      return 0;
++}
++
++static inline int dmabuf_sync_unlock(struct dmabuf_sync *sync)
++{
++      return 0;
++}
++
++static inline int dmabuf_sync_single_lock(struct dma_buf *dmabuf,
++                                              unsigned int type,
++                                              bool wait)
++{
++      return 0;
++}
++
++static inline void dmabuf_sync_single_unlock(struct dma_buf *dmabuf)
++{
++      return;
++}
++
++static inline int dmabuf_sync_get(struct dmabuf_sync *sync,
++                                      void *sync_buf,
++                                      unsigned int type)
++{
++      return 0;
++}
++
++static inline void dmabuf_sync_put(struct dmabuf_sync *sync,
++                                      struct dma_buf *dmabuf) { }
++
++static inline void dmabuf_sync_put_all(struct dmabuf_sync *sync) { }
++
++#endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0354-dmabuf-sync-add-cache-operation-feature.patch b/patches.tizen/0354-dmabuf-sync-add-cache-operation-feature.patch
new file mode 100644 (file)
index 0000000..3a303cc
--- /dev/null
@@ -0,0 +1,130 @@
+From 8608a8ae127e9e8d262aaf93290db3477bc330d2 Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Wed, 17 Jul 2013 14:43:43 +0900
+Subject: [PATCH 0354/1302] dmabuf-sync: add cache operation feature
+
+With this patch, all cache operations will be done in kernel side
+instead of user side.
+
+P.S. basically, not only user shouldn't need to request cache operation
+to kernel but also kernel should't need such things. However, we would
+have performance overhead by unnecessary cache operations if we conform
+with mainline style: cache sync just before memory ownership moves from
+CPU to DMA, and just after memory ownership moves from DMA to CPU.
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/base/dmabuf-sync.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 75 insertions(+)
+
+diff --git a/drivers/base/dmabuf-sync.c b/drivers/base/dmabuf-sync.c
+index 0b83111..a4b8a50 100644
+--- a/drivers/base/dmabuf-sync.c
++++ b/drivers/base/dmabuf-sync.c
+@@ -22,6 +22,15 @@
+ int dmabuf_sync_enabled = 1;
++#define NEED_BEGIN_CPU_ACCESS(old, new_type)  \
++                      ((old->accessed_type & DMA_BUF_ACCESS_DMA_W) == \
++                        DMA_BUF_ACCESS_DMA_W && new_type == DMA_BUF_ACCESS_R)
++
++#define NEED_END_CPU_ACCESS(old, new_type)    \
++                      (((old->accessed_type == DMA_BUF_ACCESS_W) || \
++                       (old->accessed_type == DMA_BUF_ACCESS_RW)) && \
++                       new_type & DMA_BUF_ACCESS_DMA)
++
+ MODULE_PARM_DESC(enabled, "Check if dmabuf sync is supported or not");
+ module_param_named(enabled, dmabuf_sync_enabled, int, 0444);
+@@ -83,6 +92,68 @@ static void dmabuf_sync_timeout_worker(struct work_struct *work)
+       dmabuf_sync_fini(sync);
+ }
++static void dmabuf_sync_cache_ops(struct dmabuf_sync *sync)
++{
++      struct dmabuf_sync_object *sobj;
++
++      mutex_lock(&sync->lock);
++
++      list_for_each_entry(sobj, &sync->syncs, head) {
++              struct dma_buf *dmabuf;
++
++              dmabuf = sobj->dmabuf;
++              if (WARN_ON(!dmabuf || !sobj->robj))
++                      continue;
++
++              mutex_lock(&sobj->robj->lock);
++
++              /* first time access. */
++              if (!sobj->robj->accessed_type)
++                      goto out;
++
++              if (NEED_END_CPU_ACCESS(sobj->robj, sobj->access_type))
++                      /* cache clean */
++                      dma_buf_end_cpu_access(dmabuf, 0, dmabuf->size,
++                                                      DMA_TO_DEVICE);
++              else if (NEED_BEGIN_CPU_ACCESS(sobj->robj, sobj->access_type))
++                      /* cache invalidate */
++                      dma_buf_begin_cpu_access(dmabuf, 0, dmabuf->size,
++                                                      DMA_FROM_DEVICE);
++
++out:
++              /* Update access type to new one. */
++              sobj->robj->accessed_type = sobj->access_type;
++              mutex_unlock(&sobj->robj->lock);
++      }
++
++      mutex_unlock(&sync->lock);
++}
++
++static void dmabuf_sync_single_cache_ops(struct dma_buf *dmabuf,
++                                              unsigned int access_type)
++{
++      struct dmabuf_sync_reservation *robj;
++
++      robj = dmabuf->sync;
++
++      /* first time access. */
++      if (!robj->accessed_type)
++              goto out;
++
++      if (NEED_END_CPU_ACCESS(robj, access_type))
++              /* cache clean */
++              dma_buf_end_cpu_access(dmabuf, 0, dmabuf->size,
++                                              DMA_TO_DEVICE);
++      else if (NEED_BEGIN_CPU_ACCESS(robj, access_type))
++              /* cache invalidate */
++              dma_buf_begin_cpu_access(dmabuf, 0, dmabuf->size,
++                                              DMA_FROM_DEVICE);
++
++out:
++              /* Update access type to new one. */
++              robj->accessed_type = access_type;
++}
++
+ static void dmabuf_sync_lock_timeout(unsigned long arg)
+ {
+       struct dmabuf_sync *sync = (struct dmabuf_sync *)arg;
+@@ -442,6 +513,8 @@ int dmabuf_sync_lock(struct dmabuf_sync *sync)
+       sync->status = DMABUF_SYNC_LOCKED;
++      dmabuf_sync_cache_ops(sync);
++
+       return ret;
+ }
+ EXPORT_SYMBOL(dmabuf_sync_lock);
+@@ -533,6 +606,8 @@ int dmabuf_sync_single_lock(struct dma_buf *dmabuf, unsigned int type,
+       mutex_lock(&robj->lock);
+       robj->locked = true;
++
++      dmabuf_sync_single_cache_ops(dmabuf, type);
+       mutex_unlock(&robj->lock);
+       return 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0355-dma-buf-add-lock-callback-for-fcntl-system-call.patch b/patches.tizen/0355-dma-buf-add-lock-callback-for-fcntl-system-call.patch
new file mode 100644 (file)
index 0000000..46d07eb
--- /dev/null
@@ -0,0 +1,68 @@
+From 5a25eeb1650459a280ef145e753c204ebaee9863 Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Fri, 12 Jul 2013 14:01:02 +0900
+Subject: [PATCH 0355/1302] dma-buf: add lock callback for fcntl system call.
+
+This patch adds lock callback to dma buf file operations,
+and this callback will be called by fcntl system call.
+
+With this patch, fcntl system call can be used for buffer
+synchronization between CPU and CPU, and CPU and DMA in user mode.
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/base/dma-buf.c | 33 +++++++++++++++++++++++++++++++++
+ 1 file changed, 33 insertions(+)
+
+diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
+index 9a26981..e1b8583 100644
+--- a/drivers/base/dma-buf.c
++++ b/drivers/base/dma-buf.c
+@@ -80,9 +80,42 @@ static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma)
+       return dmabuf->ops->mmap(dmabuf, vma);
+ }
++static int dma_buf_lock(struct file *file, int cmd, struct file_lock *fl)
++{
++      struct dma_buf *dmabuf;
++      unsigned int type;
++      bool wait = false;
++
++      if (!is_dma_buf_file(file))
++              return -EINVAL;
++
++      dmabuf = file->private_data;
++
++      if ((fl->fl_type & F_UNLCK) == F_UNLCK) {
++              dmabuf_sync_single_unlock(dmabuf);
++              return 0;
++      }
++
++      /* convert flock type to dmabuf sync type. */
++      if ((fl->fl_type & F_WRLCK) == F_WRLCK)
++              type = DMA_BUF_ACCESS_W;
++      else if ((fl->fl_type & F_RDLCK) == F_RDLCK)
++              type = DMA_BUF_ACCESS_R;
++      else
++              return -EINVAL;
++
++      if (fl->fl_flags & FL_SLEEP)
++              wait = true;
++
++      /* TODO. the locking to certain region should also be considered. */
++
++      return dmabuf_sync_single_lock(dmabuf, type, wait);
++}
++
+ static const struct file_operations dma_buf_fops = {
+       .release        = dma_buf_release,
+       .mmap           = dma_buf_mmap_internal,
++      .lock           = dma_buf_lock,
+ };
+ /*
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0356-drm-exynos-export-a-gem-into-dmabuf-fd-with-O_RDWR.patch b/patches.tizen/0356-drm-exynos-export-a-gem-into-dmabuf-fd-with-O_RDWR.patch
new file mode 100644 (file)
index 0000000..9b3bc6a
--- /dev/null
@@ -0,0 +1,30 @@
+From 47404a3b962d6c53fc2fad5a9869740ba1b67b7d Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Wed, 17 Jul 2013 15:29:38 +0900
+Subject: [PATCH 0356/1302] drm/exynos: export a gem into dmabuf fd with O_RDWR
+
+user process needs read/write permissions when the user process tires
+buffer lock with a exported dmabuf fd through fcntl system call.
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_dmabuf.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
+index ff7f2a8..f26861e 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
+@@ -205,6 +205,8 @@ struct dma_buf *exynos_dmabuf_prime_export(struct drm_device *drm_dev,
+ {
+       struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj);
++      flags |= O_RDWR;
++
+       return dma_buf_export(exynos_gem_obj, &exynos_dmabuf_ops,
+                               exynos_gem_obj->base.size, flags);
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0357-drm-exynos-add-cache-operation-backend-callbacks.patch b/patches.tizen/0357-drm-exynos-add-cache-operation-backend-callbacks.patch
new file mode 100644 (file)
index 0000000..03d2f7e
--- /dev/null
@@ -0,0 +1,66 @@
+From 1e9c0a66d23e3bcc60bd30530301dddcead984a4 Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Wed, 17 Jul 2013 20:41:15 +0900
+Subject: [PATCH 0357/1302] drm/exynos: add cache operation backend callbacks
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_dmabuf.c | 34 ++++++++++++++++++++++++++++++
+ 1 file changed, 34 insertions(+)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
+index f26861e..99ff8dc 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
+@@ -129,6 +129,38 @@ static void exynos_gem_unmap_dma_buf(struct dma_buf_attachment *attach,
+       /* Nothing to do. */
+ }
++static int exynos_gem_begin_cpu_access(struct dma_buf *dmabuf, size_t start,
++                                      size_t len, enum dma_data_direction dir)
++{
++      struct exynos_drm_gem_obj *exynos_gem_obj = dmabuf->priv;
++      struct exynos_drm_gem_buf *buf = exynos_gem_obj->buffer;
++      struct drm_device *drm_dev = exynos_gem_obj->base.dev;
++
++      if (dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, &buf->dma_attrs))
++              return 0;
++
++      /* TODO. need to optimize cache operation. */
++      dma_sync_sg_for_cpu(drm_dev->dev, buf->sgt->sgl, buf->sgt->orig_nents,
++                              dir);
++
++      return 0;
++}
++
++static void exynos_gem_end_cpu_access(struct dma_buf *dmabuf, size_t start,
++                                      size_t len, enum dma_data_direction dir)
++{
++      struct exynos_drm_gem_obj *exynos_gem_obj = dmabuf->priv;
++      struct exynos_drm_gem_buf *buf = exynos_gem_obj->buffer;
++      struct drm_device *drm_dev = exynos_gem_obj->base.dev;
++
++      if (dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, &buf->dma_attrs))
++              return;
++
++      /* TODO. need to optimize cache operation. */
++      dma_sync_sg_for_device(drm_dev->dev, buf->sgt->sgl, buf->sgt->orig_nents,
++                              dir);
++}
++
+ static void exynos_dmabuf_release(struct dma_buf *dmabuf)
+ {
+       struct exynos_drm_gem_obj *exynos_gem_obj = dmabuf->priv;
+@@ -192,6 +224,8 @@ static struct dma_buf_ops exynos_dmabuf_ops = {
+       .detach                 = exynos_gem_detach_dma_buf,
+       .map_dma_buf            = exynos_gem_map_dma_buf,
+       .unmap_dma_buf          = exynos_gem_unmap_dma_buf,
++      .begin_cpu_access       = exynos_gem_begin_cpu_access,
++      .end_cpu_access         = exynos_gem_end_cpu_access,
+       .kmap                   = exynos_gem_dmabuf_kmap,
+       .kmap_atomic            = exynos_gem_dmabuf_kmap_atomic,
+       .kunmap                 = exynos_gem_dmabuf_kunmap,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0358-perf-tools-Fix-bug-in-isupper-and-islower.patch b/patches.tizen/0358-perf-tools-Fix-bug-in-isupper-and-islower.patch
new file mode 100644 (file)
index 0000000..b6e2080
--- /dev/null
@@ -0,0 +1,39 @@
+From 13ac119034246d7b52a8edea3f6762575af170ce Mon Sep 17 00:00:00 2001
+From: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
+Date: Fri, 29 Mar 2013 12:14:43 -0700
+Subject: [PATCH 0358/1302] perf tools: Fix bug in isupper() and islower()
+
+One of the reasons 'perf test' is failing on Power appears to be due to
+a bug in isupper().
+
+isupper(c) and islower(c) should be checking 'c' against the mask 0x20.
+Instead they are checking sane_ctype[c] which causes isupper() to be
+true for lower case letters.
+
+Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
+Acked-by: Namhyung Kim <namhyung@kernel.org>
+Link: http://lkml.kernel.org/r/20130329192950.GA9312@us.ibm.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/util/util.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
+index a45710b..7a484c9 100644
+--- a/tools/perf/util/util.h
++++ b/tools/perf/util/util.h
+@@ -221,8 +221,8 @@ extern unsigned char sane_ctype[256];
+ #define isalpha(x) sane_istest(x,GIT_ALPHA)
+ #define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT)
+ #define isprint(x) sane_istest(x,GIT_PRINT)
+-#define islower(x) (sane_istest(x,GIT_ALPHA) && sane_istest(x,0x20))
+-#define isupper(x) (sane_istest(x,GIT_ALPHA) && !sane_istest(x,0x20))
++#define islower(x) (sane_istest(x,GIT_ALPHA) && (x & 0x20))
++#define isupper(x) (sane_istest(x,GIT_ALPHA) && !(x & 0x20))
+ #define tolower(x) sane_case((unsigned char)(x), 0x20)
+ #define toupper(x) sane_case((unsigned char)(x), 0)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0359-perf-hists-Fix-an-invalid-memory-free-on-he-branch_i.patch b/patches.tizen/0359-perf-hists-Fix-an-invalid-memory-free-on-he-branch_i.patch
new file mode 100644 (file)
index 0000000..1f752d0
--- /dev/null
@@ -0,0 +1,104 @@
+From 2079511d18769ffb4c68070889713f922001c487 Mon Sep 17 00:00:00 2001
+From: Namhyung Kim <namhyung.kim@lge.com>
+Date: Mon, 1 Apr 2013 20:35:17 +0900
+Subject: [PATCH 0359/1302] perf hists: Fix an invalid memory free on
+ he->branch_info
+
+The branch info was allocated for the whole stack and passed matching
+hist entry for each level during processing samples.  Thus when a hist
+entry tries to free its branch info like in hists__collapse_insert_entry
+it'll face following error.
+
+  *** glibc detected *** perf: munmap_chunk(): invalid pointer: 0x00000000014e9d20 ***
+  ======= Backtrace: =========
+  /lib64/libc.so.6[0x387d47ae16]
+  perf[0x4923bd]
+  perf(cmd_report+0xd68)[0x432a08]
+  perf[0x41a663]
+  perf(main+0x58f)[0x419eaf]
+  /lib64/libc.so.6(__libc_start_main+0xf5)[0x387d421735]
+  perf[0x419f95]
+
+Fix it by allocating and copying branch info for each new hist entry.
+
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1364816125-12212-2-git-send-email-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/builtin-report.c |  9 ++++++---
+ tools/perf/util/hist.c      | 14 ++++++++++++++
+ 2 files changed, 20 insertions(+), 3 deletions(-)
+
+diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
+index bd0ca81..d9f2de3 100644
+--- a/tools/perf/builtin-report.c
++++ b/tools/perf/builtin-report.c
+@@ -187,6 +187,9 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,
+       for (i = 0; i < sample->branch_stack->nr; i++) {
+               if (rep->hide_unresolved && !(bi[i].from.sym && bi[i].to.sym))
+                       continue;
++
++              err = -ENOMEM;
++
+               /*
+                * The report shows the percentage of total branches captured
+                * and not events sampled. Thus we use a pseudo period of 1.
+@@ -195,7 +198,6 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,
+                               &bi[i], 1, 1);
+               if (he) {
+                       struct annotation *notes;
+-                      err = -ENOMEM;
+                       bx = he->branch_info;
+                       if (bx->from.sym && use_browser == 1 && sort__has_sym) {
+                               notes = symbol__annotation(bx->from.sym);
+@@ -226,11 +228,12 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,
+                       }
+                       evsel->hists.stats.total_period += 1;
+                       hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);
+-                      err = 0;
+               } else
+-                      return -ENOMEM;
++                      goto out;
+       }
++      err = 0;
+ out:
++      free(bi);
+       return err;
+ }
+diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
+index 6b32721..9438d57 100644
+--- a/tools/perf/util/hist.c
++++ b/tools/perf/util/hist.c
+@@ -292,6 +292,20 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template)
+                       he->ms.map->referenced = true;
+               if (he->branch_info) {
++                      /*
++                       * This branch info is (a part of) allocated from
++                       * machine__resolve_bstack() and will be freed after
++                       * adding new entries.  So we need to save a copy.
++                       */
++                      he->branch_info = malloc(sizeof(*he->branch_info));
++                      if (he->branch_info == NULL) {
++                              free(he);
++                              return NULL;
++                      }
++
++                      memcpy(he->branch_info, template->branch_info,
++                             sizeof(*he->branch_info));
++
+                       if (he->branch_info->from.map)
+                               he->branch_info->from.map->referenced = true;
+                       if (he->branch_info->to.map)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0360-perf-hists-Free-unused-mem-info-of-a-matched-hist-en.patch b/patches.tizen/0360-perf-hists-Free-unused-mem-info-of-a-matched-hist-en.patch
new file mode 100644 (file)
index 0000000..db64b17
--- /dev/null
@@ -0,0 +1,43 @@
+From 52a921319f09b9de8df8cb08f71a31329da76bf7 Mon Sep 17 00:00:00 2001
+From: Namhyung Kim <namhyung.kim@lge.com>
+Date: Mon, 1 Apr 2013 20:35:18 +0900
+Subject: [PATCH 0360/1302] perf hists: Free unused mem info of a matched hist
+ entry
+
+The mem info is shared between matched entries so one should be freed.
+
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1364816125-12212-3-git-send-email-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/util/hist.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
+index 9438d57..514fc04 100644
+--- a/tools/perf/util/hist.c
++++ b/tools/perf/util/hist.c
+@@ -374,6 +374,12 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
+               if (!cmp) {
+                       he_stat__add_period(&he->stat, period, weight);
++                      /*
++                       * This mem info was allocated from machine__resolve_mem
++                       * and will not be used anymore.
++                       */
++                      free(entry->mem_info);
++
+                       /* If the map of an existing hist_entry has
+                        * become out-of-date due to an exec() or
+                        * similar, update it.  Otherwise we will
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0361-perf-report-Fix-alignment-of-symbol-column-when-v-is.patch b/patches.tizen/0361-perf-report-Fix-alignment-of-symbol-column-when-v-is.patch
new file mode 100644 (file)
index 0000000..9aedde0
--- /dev/null
@@ -0,0 +1,113 @@
+From 8612a48cbddc0cdacb67436d8503fd044e8ed8f3 Mon Sep 17 00:00:00 2001
+From: Namhyung Kim <namhyung.kim@lge.com>
+Date: Mon, 1 Apr 2013 20:35:19 +0900
+Subject: [PATCH 0361/1302] perf report: Fix alignment of symbol column when -v
+ is given
+
+When -v option is given, the symbol sort key prints its address also but
+it wasn't properly aligned since hists__calc_col_len() misses the
+additional part.  Also it missed 2 spaces for 0x prefix when printing.
+
+  $ perf report --stdio -v -s sym
+  # Samples: 133  of event 'cycles'
+  # Event count (approx.): 50536717
+  #
+  # Overhead                          Symbol
+  # ........  ..............................
+  #
+      12.20%  0xffffffff81384c50 v [k] intel_idle
+       7.62%  0xffffffff8170976a v [k] ftrace_caller
+       7.02%  0x2d986d         B [.] 0x00000000002d986d
+
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1364816125-12212-4-git-send-email-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/util/hist.c | 26 +++++++++++++++-----------
+ tools/perf/util/sort.c |  2 +-
+ 2 files changed, 16 insertions(+), 12 deletions(-)
+
+diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
+index 514fc04..72b4eec 100644
+--- a/tools/perf/util/hist.c
++++ b/tools/perf/util/hist.c
+@@ -70,9 +70,17 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
+       int symlen;
+       u16 len;
+-      if (h->ms.sym)
+-              hists__new_col_len(hists, HISTC_SYMBOL, h->ms.sym->namelen + 4);
+-      else {
++      /*
++       * +4 accounts for '[x] ' priv level info
++       * +2 accounts for 0x prefix on raw addresses
++       * +3 accounts for ' y ' symtab origin info
++       */
++      if (h->ms.sym) {
++              symlen = h->ms.sym->namelen + 4;
++              if (verbose)
++                      symlen += BITS_PER_LONG / 4 + 2 + 3;
++              hists__new_col_len(hists, HISTC_SYMBOL, symlen);
++      } else {
+               symlen = unresolved_col_width + 4 + 2;
+               hists__new_col_len(hists, HISTC_SYMBOL, symlen);
+               hists__set_unres_dso_col_len(hists, HISTC_DSO);
+@@ -91,12 +99,10 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
+               hists__new_col_len(hists, HISTC_PARENT, h->parent->namelen);
+       if (h->branch_info) {
+-              /*
+-               * +4 accounts for '[x] ' priv level info
+-               * +2 account of 0x prefix on raw addresses
+-               */
+               if (h->branch_info->from.sym) {
+                       symlen = (int)h->branch_info->from.sym->namelen + 4;
++                      if (verbose)
++                              symlen += BITS_PER_LONG / 4 + 2 + 3;
+                       hists__new_col_len(hists, HISTC_SYMBOL_FROM, symlen);
+                       symlen = dso__name_len(h->branch_info->from.map->dso);
+@@ -109,6 +115,8 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
+               if (h->branch_info->to.sym) {
+                       symlen = (int)h->branch_info->to.sym->namelen + 4;
++                      if (verbose)
++                              symlen += BITS_PER_LONG / 4 + 2 + 3;
+                       hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen);
+                       symlen = dso__name_len(h->branch_info->to.map->dso);
+@@ -121,10 +129,6 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
+       }
+       if (h->mem_info) {
+-              /*
+-               * +4 accounts for '[x] ' priv level info
+-               * +2 account of 0x prefix on raw addresses
+-               */
+               if (h->mem_info->daddr.sym) {
+                       symlen = (int)h->mem_info->daddr.sym->namelen + 4
+                              + unresolved_col_width + 2;
+diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
+index 5f52d49..16d5e38 100644
+--- a/tools/perf/util/sort.c
++++ b/tools/perf/util/sort.c
+@@ -194,7 +194,7 @@ static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym,
+       if (verbose) {
+               char o = map ? dso__symtab_origin(map->dso) : '!';
+               ret += repsep_snprintf(bf, size, "%-#*llx %c ",
+-                                     BITS_PER_LONG / 4, ip, o);
++                                     BITS_PER_LONG / 4 + 2, ip, o);
+       }
+       ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", level);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0362-perf-sort-Introduce-sort__mode-variable.patch b/patches.tizen/0362-perf-sort-Introduce-sort__mode-variable.patch
new file mode 100644 (file)
index 0000000..a9d8331
--- /dev/null
@@ -0,0 +1,183 @@
+From 6b071c52b5333899ef3e83bff210c47c1622414c Mon Sep 17 00:00:00 2001
+From: Namhyung Kim <namhyung.kim@lge.com>
+Date: Mon, 1 Apr 2013 20:35:20 +0900
+Subject: [PATCH 0362/1302] perf sort: Introduce sort__mode variable
+
+It's used for determining current sort mode which can be one of
+NORMAL, BRANCH and new MEMORY.
+
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1364816125-12212-5-git-send-email-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/builtin-report.c    | 23 +++++++++++++----------
+ tools/perf/ui/browsers/hists.c |  4 ++--
+ tools/perf/util/sort.c         |  4 ++--
+ tools/perf/util/sort.h         |  8 +++++++-
+ 4 files changed, 24 insertions(+), 15 deletions(-)
+
+diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
+index d9f2de3..c877982 100644
+--- a/tools/perf/builtin-report.c
++++ b/tools/perf/builtin-report.c
+@@ -311,7 +311,7 @@ static int process_sample_event(struct perf_tool *tool,
+       if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap))
+               return 0;
+-      if (sort__branch_mode == 1) {
++      if (sort__mode == SORT_MODE__BRANCH) {
+               if (perf_report__add_branch_hist_entry(tool, &al, sample,
+                                                      evsel, machine)) {
+                       pr_debug("problem adding lbr entry, skipping event\n");
+@@ -387,7 +387,7 @@ static int perf_report__setup_sample_type(struct perf_report *rep)
+                       }
+       }
+-      if (sort__branch_mode == 1) {
++      if (sort__mode == SORT_MODE__BRANCH) {
+               if (!self->fd_pipe &&
+                   !(sample_type & PERF_SAMPLE_BRANCH_STACK)) {
+                       ui__error("Selected -b but no branch data. "
+@@ -694,7 +694,9 @@ static int
+ parse_branch_mode(const struct option *opt __maybe_unused,
+                 const char *str __maybe_unused, int unset)
+ {
+-      sort__branch_mode = !unset;
++      int *branch_mode = opt->value;
++
++      *branch_mode = !unset;
+       return 0;
+ }
+@@ -703,6 +705,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
+       struct perf_session *session;
+       struct stat st;
+       bool has_br_stack = false;
++      int branch_mode = -1;
+       int ret = -1;
+       char callchain_default_opt[] = "fractal,0.5,callee";
+       const char * const report_usage[] = {
+@@ -799,7 +802,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
+                   "Show a column with the sum of periods"),
+       OPT_BOOLEAN(0, "group", &symbol_conf.event_group,
+                   "Show event group information together"),
+-      OPT_CALLBACK_NOOPT('b', "branch-stack", &sort__branch_mode, "",
++      OPT_CALLBACK_NOOPT('b', "branch-stack", &branch_mode, "",
+                   "use branch records for histogram filling", parse_branch_mode),
+       OPT_STRING(0, "objdump", &objdump_path, "path",
+                  "objdump binary to use for disassembly and annotations"),
+@@ -849,11 +852,11 @@ repeat:
+       has_br_stack = perf_header__has_feat(&session->header,
+                                            HEADER_BRANCH_STACK);
+-      if (sort__branch_mode == -1 && has_br_stack)
+-              sort__branch_mode = 1;
++      if (branch_mode == -1 && has_br_stack)
++              sort__mode = SORT_MODE__BRANCH;
+-      /* sort__branch_mode could be 0 if --no-branch-stack */
+-      if (sort__branch_mode == 1) {
++      /* sort__mode could be NORMAL if --no-branch-stack */
++      if (sort__mode == SORT_MODE__BRANCH) {
+               /*
+                * if no sort_order is provided, then specify
+                * branch-mode specific order
+@@ -864,7 +867,7 @@ repeat:
+       }
+       if (report.mem_mode) {
+-              if (sort__branch_mode == 1) {
++              if (sort__mode == SORT_MODE__BRANCH) {
+                       fprintf(stderr, "branch and mem mode incompatible\n");
+                       goto error;
+               }
+@@ -934,7 +937,7 @@ repeat:
+       sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", stdout);
+-      if (sort__branch_mode == 1) {
++      if (sort__mode == SORT_MODE__BRANCH) {
+               sort_entry__setup_elide(&sort_dso_from, symbol_conf.dso_from_list, "dso_from", stdout);
+               sort_entry__setup_elide(&sort_dso_to, symbol_conf.dso_to_list, "dso_to", stdout);
+               sort_entry__setup_elide(&sort_sym_from, symbol_conf.sym_from_list, "sym_from", stdout);
+diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
+index d88a2d0..cad8e37 100644
+--- a/tools/perf/ui/browsers/hists.c
++++ b/tools/perf/ui/browsers/hists.c
+@@ -1155,7 +1155,7 @@ static struct hist_browser *hist_browser__new(struct hists *hists)
+               browser->b.refresh = hist_browser__refresh;
+               browser->b.seek = ui_browser__hists_seek;
+               browser->b.use_navkeypressed = true;
+-              if (sort__branch_mode == 1)
++              if (sort__mode == SORT_MODE__BRANCH)
+                       browser->has_symbols = sort_sym_from.list.next != NULL;
+               else
+                       browser->has_symbols = sort_sym.list.next != NULL;
+@@ -1488,7 +1488,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
+               if (!browser->has_symbols)
+                       goto add_exit_option;
+-              if (sort__branch_mode == 1) {
++              if (sort__mode == SORT_MODE__BRANCH) {
+                       bi = browser->he_selection->branch_info;
+                       if (browser->selection != NULL &&
+                           bi &&
+diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
+index 16d5e38..a6ddad4 100644
+--- a/tools/perf/util/sort.c
++++ b/tools/perf/util/sort.c
+@@ -9,7 +9,7 @@ const char     *sort_order = default_sort_order;
+ int           sort__need_collapse = 0;
+ int           sort__has_parent = 0;
+ int           sort__has_sym = 0;
+-int           sort__branch_mode = -1; /* -1 = means not set */
++enum sort_mode        sort__mode = SORT_MODE__NORMAL;
+ enum sort_type        sort__first_dimension;
+@@ -943,7 +943,7 @@ int sort_dimension__add(const char *tok)
+               if (strncasecmp(tok, sd->name, strlen(tok)))
+                       continue;
+-              if (sort__branch_mode != 1)
++              if (sort__mode != SORT_MODE__BRANCH)
+                       return -EINVAL;
+               if (sd->entry == &sort_sym_from || sd->entry == &sort_sym_to)
+diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
+index f24bdf6..39ff4b8 100644
+--- a/tools/perf/util/sort.h
++++ b/tools/perf/util/sort.h
+@@ -32,7 +32,7 @@ extern const char default_sort_order[];
+ extern int sort__need_collapse;
+ extern int sort__has_parent;
+ extern int sort__has_sym;
+-extern int sort__branch_mode;
++extern enum sort_mode sort__mode;
+ extern struct sort_entry sort_comm;
+ extern struct sort_entry sort_dso;
+ extern struct sort_entry sort_sym;
+@@ -123,6 +123,12 @@ static inline void hist_entry__add_pair(struct hist_entry *he,
+       list_add_tail(&he->pairs.head, &pair->pairs.node);
+ }
++enum sort_mode {
++      SORT_MODE__NORMAL,
++      SORT_MODE__BRANCH,
++      SORT_MODE__MEMORY,
++};
++
+ enum sort_type {
+       /* common sort keys */
+       SORT_PID,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0363-perf-sort-Factor-out-common-code-in-sort_dimension__.patch b/patches.tizen/0363-perf-sort-Factor-out-common-code-in-sort_dimension__.patch
new file mode 100644 (file)
index 0000000..3d13b06
--- /dev/null
@@ -0,0 +1,93 @@
+From f9b220e65cb859b5456637dc9fbe7302b56df750 Mon Sep 17 00:00:00 2001
+From: Namhyung Kim <namhyung.kim@lge.com>
+Date: Wed, 3 Apr 2013 21:26:10 +0900
+Subject: [PATCH 0363/1302] perf sort: Factor out common code in
+ sort_dimension__add()
+
+Let's remove duplicate code.
+
+Suggested-by: Jiri Olsa <jolsa@redhat.com>
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1364991979-3008-2-git-send-email-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/util/sort.c | 41 +++++++++++++++++------------------------
+ 1 file changed, 17 insertions(+), 24 deletions(-)
+
+diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
+index a6ddad4..a997955 100644
+--- a/tools/perf/util/sort.c
++++ b/tools/perf/util/sort.c
+@@ -895,6 +895,21 @@ static struct sort_dimension bstack_sort_dimensions[] = {
+ #undef DIM
++static void __sort_dimension__add(struct sort_dimension *sd, enum sort_type idx)
++{
++      if (sd->taken)
++              return;
++
++      if (sd->entry->se_collapse)
++              sort__need_collapse = 1;
++
++      if (list_empty(&hist_entry__sort_list))
++              sort__first_dimension = idx;
++
++      list_add_tail(&sd->entry->list, &hist_entry__sort_list);
++      sd->taken = 1;
++}
++
+ int sort_dimension__add(const char *tok)
+ {
+       unsigned int i;
+@@ -922,18 +937,7 @@ int sort_dimension__add(const char *tok)
+                       sort__has_sym = 1;
+               }
+-              if (sd->taken)
+-                      return 0;
+-
+-              if (sd->entry->se_collapse)
+-                      sort__need_collapse = 1;
+-
+-              if (list_empty(&hist_entry__sort_list))
+-                      sort__first_dimension = i;
+-
+-              list_add_tail(&sd->entry->list, &hist_entry__sort_list);
+-              sd->taken = 1;
+-
++              __sort_dimension__add(sd, i);
+               return 0;
+       }
+@@ -949,18 +953,7 @@ int sort_dimension__add(const char *tok)
+               if (sd->entry == &sort_sym_from || sd->entry == &sort_sym_to)
+                       sort__has_sym = 1;
+-              if (sd->taken)
+-                      return 0;
+-
+-              if (sd->entry->se_collapse)
+-                      sort__need_collapse = 1;
+-
+-              if (list_empty(&hist_entry__sort_list))
+-                      sort__first_dimension = i + __SORT_BRANCH_STACK;
+-
+-              list_add_tail(&sd->entry->list, &hist_entry__sort_list);
+-              sd->taken = 1;
+-
++              __sort_dimension__add(sd, i + __SORT_BRANCH_STACK);
+               return 0;
+       }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0364-perf-sort-Separate-out-memory-specific-sort-keys.patch b/patches.tizen/0364-perf-sort-Separate-out-memory-specific-sort-keys.patch
new file mode 100644 (file)
index 0000000..4fb292d
--- /dev/null
@@ -0,0 +1,145 @@
+From a7e5a4be8c0f5da7833c8e88ab558674bc4e83c3 Mon Sep 17 00:00:00 2001
+From: Namhyung Kim <namhyung.kim@lge.com>
+Date: Wed, 3 Apr 2013 21:26:11 +0900
+Subject: [PATCH 0364/1302] perf sort: Separate out memory-specific sort keys
+
+Since they're used only for perf mem, separate out them to a different
+dimension so that normal user cannot access them by any chance.
+
+For global/local weights, I'm not entirely sure to place them into the
+memory dimension.  But it's the only user at this time.
+
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1364991979-3008-3-git-send-email-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/builtin-report.c |  2 ++
+ tools/perf/util/sort.c      | 39 +++++++++++++++++++++++++++++++--------
+ tools/perf/util/sort.h      | 19 +++++++++++--------
+ 3 files changed, 44 insertions(+), 16 deletions(-)
+
+diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
+index c877982..669405c 100644
+--- a/tools/perf/builtin-report.c
++++ b/tools/perf/builtin-report.c
+@@ -871,6 +871,8 @@ repeat:
+                       fprintf(stderr, "branch and mem mode incompatible\n");
+                       goto error;
+               }
++              sort__mode = SORT_MODE__MEMORY;
++
+               /*
+                * if no sort_order is provided, then specify
+                * branch-mode specific order
+diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
+index a997955..1dbf169 100644
+--- a/tools/perf/util/sort.c
++++ b/tools/perf/util/sort.c
+@@ -871,14 +871,6 @@ static struct sort_dimension common_sort_dimensions[] = {
+       DIM(SORT_PARENT, "parent", sort_parent),
+       DIM(SORT_CPU, "cpu", sort_cpu),
+       DIM(SORT_SRCLINE, "srcline", sort_srcline),
+-      DIM(SORT_LOCAL_WEIGHT, "local_weight", sort_local_weight),
+-      DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight),
+-      DIM(SORT_MEM_DADDR_SYMBOL, "symbol_daddr", sort_mem_daddr_sym),
+-      DIM(SORT_MEM_DADDR_DSO, "dso_daddr", sort_mem_daddr_dso),
+-      DIM(SORT_MEM_LOCKED, "locked", sort_mem_locked),
+-      DIM(SORT_MEM_TLB, "tlb", sort_mem_tlb),
+-      DIM(SORT_MEM_LVL, "mem", sort_mem_lvl),
+-      DIM(SORT_MEM_SNOOP, "snoop", sort_mem_snoop),
+ };
+ #undef DIM
+@@ -895,6 +887,21 @@ static struct sort_dimension bstack_sort_dimensions[] = {
+ #undef DIM
++#define DIM(d, n, func) [d - __SORT_MEMORY_MODE] = { .name = n, .entry = &(func) }
++
++static struct sort_dimension memory_sort_dimensions[] = {
++      DIM(SORT_LOCAL_WEIGHT, "local_weight", sort_local_weight),
++      DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight),
++      DIM(SORT_MEM_DADDR_SYMBOL, "symbol_daddr", sort_mem_daddr_sym),
++      DIM(SORT_MEM_DADDR_DSO, "dso_daddr", sort_mem_daddr_dso),
++      DIM(SORT_MEM_LOCKED, "locked", sort_mem_locked),
++      DIM(SORT_MEM_TLB, "tlb", sort_mem_tlb),
++      DIM(SORT_MEM_LVL, "mem", sort_mem_lvl),
++      DIM(SORT_MEM_SNOOP, "snoop", sort_mem_snoop),
++};
++
++#undef DIM
++
+ static void __sort_dimension__add(struct sort_dimension *sd, enum sort_type idx)
+ {
+       if (sd->taken)
+@@ -957,6 +964,22 @@ int sort_dimension__add(const char *tok)
+               return 0;
+       }
++      for (i = 0; i < ARRAY_SIZE(memory_sort_dimensions); i++) {
++              struct sort_dimension *sd = &memory_sort_dimensions[i];
++
++              if (strncasecmp(tok, sd->name, strlen(tok)))
++                      continue;
++
++              if (sort__mode != SORT_MODE__MEMORY)
++                      return -EINVAL;
++
++              if (sd->entry == &sort_mem_daddr_sym)
++                      sort__has_sym = 1;
++
++              __sort_dimension__add(sd, i + __SORT_MEMORY_MODE);
++              return 0;
++      }
++
+       return -ESRCH;
+ }
+diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
+index 39ff4b8..0232d47 100644
+--- a/tools/perf/util/sort.h
++++ b/tools/perf/util/sort.h
+@@ -138,14 +138,6 @@ enum sort_type {
+       SORT_PARENT,
+       SORT_CPU,
+       SORT_SRCLINE,
+-      SORT_LOCAL_WEIGHT,
+-      SORT_GLOBAL_WEIGHT,
+-      SORT_MEM_DADDR_SYMBOL,
+-      SORT_MEM_DADDR_DSO,
+-      SORT_MEM_LOCKED,
+-      SORT_MEM_TLB,
+-      SORT_MEM_LVL,
+-      SORT_MEM_SNOOP,
+       /* branch stack specific sort keys */
+       __SORT_BRANCH_STACK,
+@@ -154,6 +146,17 @@ enum sort_type {
+       SORT_SYM_FROM,
+       SORT_SYM_TO,
+       SORT_MISPREDICT,
++
++      /* memory mode specific sort keys */
++      __SORT_MEMORY_MODE,
++      SORT_LOCAL_WEIGHT = __SORT_MEMORY_MODE,
++      SORT_GLOBAL_WEIGHT,
++      SORT_MEM_DADDR_SYMBOL,
++      SORT_MEM_DADDR_DSO,
++      SORT_MEM_LOCKED,
++      SORT_MEM_TLB,
++      SORT_MEM_LVL,
++      SORT_MEM_SNOOP,
+ };
+ /*
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0365-perf-sort-Consolidate-sort_entry__setup_elide.patch b/patches.tizen/0365-perf-sort-Consolidate-sort_entry__setup_elide.patch
new file mode 100644 (file)
index 0000000..92fd1ea
--- /dev/null
@@ -0,0 +1,170 @@
+From fdf3b645c2f7f53d63bf09cb96ccf477eec595a2 Mon Sep 17 00:00:00 2001
+From: Namhyung Kim <namhyung.kim@lge.com>
+Date: Wed, 3 Apr 2013 21:26:19 +0900
+Subject: [PATCH 0365/1302] perf sort: Consolidate sort_entry__setup_elide()
+
+The same code was duplicate to places, factor them out to common
+sort__setup_elide().
+
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1364991979-3008-11-git-send-email-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/builtin-diff.c   |  4 +---
+ tools/perf/builtin-report.c | 20 +-------------------
+ tools/perf/builtin-top.c    |  4 +---
+ tools/perf/util/sort.c      | 45 +++++++++++++++++++++++++++++++++++++++++++--
+ tools/perf/util/sort.h      |  3 +--
+ 5 files changed, 47 insertions(+), 29 deletions(-)
+
+diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
+index 2d0462d..cabbea5 100644
+--- a/tools/perf/builtin-diff.c
++++ b/tools/perf/builtin-diff.c
+@@ -611,9 +611,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused)
+       setup_pager();
+-      sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso", NULL);
+-      sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", NULL);
+-      sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, "symbol", NULL);
++      sort__setup_elide(NULL);
+       return __cmd_diff();
+ }
+diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
+index 669405c..d45bf9b 100644
+--- a/tools/perf/builtin-report.c
++++ b/tools/perf/builtin-report.c
+@@ -937,25 +937,7 @@ repeat:
+               report.symbol_filter_str = argv[0];
+       }
+-      sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", stdout);
+-
+-      if (sort__mode == SORT_MODE__BRANCH) {
+-              sort_entry__setup_elide(&sort_dso_from, symbol_conf.dso_from_list, "dso_from", stdout);
+-              sort_entry__setup_elide(&sort_dso_to, symbol_conf.dso_to_list, "dso_to", stdout);
+-              sort_entry__setup_elide(&sort_sym_from, symbol_conf.sym_from_list, "sym_from", stdout);
+-              sort_entry__setup_elide(&sort_sym_to, symbol_conf.sym_to_list, "sym_to", stdout);
+-      } else {
+-              if (report.mem_mode) {
+-                      sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "symbol_daddr", stdout);
+-                      sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso_daddr", stdout);
+-                      sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "mem", stdout);
+-                      sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "local_weight", stdout);
+-                      sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "tlb", stdout);
+-                      sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "snoop", stdout);
+-              }
+-              sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso", stdout);
+-              sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, "symbol", stdout);
+-      }
++      sort__setup_elide(stdout);
+       ret = __cmd_report(&report);
+       if (ret == K_SWITCH_INPUT_DATA) {
+diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
+index 67bdb9f..2eb272d 100644
+--- a/tools/perf/builtin-top.c
++++ b/tools/perf/builtin-top.c
+@@ -1200,9 +1200,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
+       if (symbol__init() < 0)
+               return -1;
+-      sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso", stdout);
+-      sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", stdout);
+-      sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, "symbol", stdout);
++      sort__setup_elide(stdout);
+       /*
+        * Avoid annotation data structures overhead when symbols aren't on the
+diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
+index 1dbf169..701ab1d 100644
+--- a/tools/perf/util/sort.c
++++ b/tools/perf/util/sort.c
+@@ -1,5 +1,6 @@
+ #include "sort.h"
+ #include "hist.h"
++#include "symbol.h"
+ regex_t               parent_regex;
+ const char    default_parent_pattern[] = "^sys_|^do_page_fault";
+@@ -1009,8 +1010,9 @@ int setup_sorting(void)
+       return ret;
+ }
+-void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list,
+-                           const char *list_name, FILE *fp)
++static void sort_entry__setup_elide(struct sort_entry *self,
++                                  struct strlist *list,
++                                  const char *list_name, FILE *fp)
+ {
+       if (list && strlist__nr_entries(list) == 1) {
+               if (fp != NULL)
+@@ -1019,3 +1021,42 @@ void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list,
+               self->elide = true;
+       }
+ }
++
++void sort__setup_elide(FILE *output)
++{
++      sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
++                              "dso", output);
++      sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list,
++                              "comm", output);
++      sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list,
++                              "symbol", output);
++
++      if (sort__mode == SORT_MODE__BRANCH) {
++              sort_entry__setup_elide(&sort_dso_from,
++                                      symbol_conf.dso_from_list,
++                                      "dso_from", output);
++              sort_entry__setup_elide(&sort_dso_to,
++                                      symbol_conf.dso_to_list,
++                                      "dso_to", output);
++              sort_entry__setup_elide(&sort_sym_from,
++                                      symbol_conf.sym_from_list,
++                                      "sym_from", output);
++              sort_entry__setup_elide(&sort_sym_to,
++                                      symbol_conf.sym_to_list,
++                                      "sym_to", output);
++      } else if (sort__mode == SORT_MODE__MEMORY) {
++              sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
++                                      "symbol_daddr", output);
++              sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
++                                      "dso_daddr", output);
++              sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
++                                      "mem", output);
++              sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
++                                      "local_weight", output);
++              sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
++                                      "tlb", output);
++              sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
++                                      "snoop", output);
++      }
++
++}
+diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
+index 0232d47..51f1b5a 100644
+--- a/tools/perf/util/sort.h
++++ b/tools/perf/util/sort.h
+@@ -181,7 +181,6 @@ extern struct list_head hist_entry__sort_list;
+ int setup_sorting(void);
+ extern int sort_dimension__add(const char *);
+-void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list,
+-                           const char *list_name, FILE *fp);
++void sort__setup_elide(FILE *fp);
+ #endif        /* __PERF_SORT_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0366-perf-archive-Fix-typo-on-Documentation.patch b/patches.tizen/0366-perf-archive-Fix-typo-on-Documentation.patch
new file mode 100644 (file)
index 0000000..3b55b91
--- /dev/null
@@ -0,0 +1,39 @@
+From e2aae3f2332d3a79a5db0f0ec2bcfb0cc57f507a Mon Sep 17 00:00:00 2001
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+Date: Thu, 4 Apr 2013 12:41:22 -0300
+Subject: [PATCH 0366/1302] perf archive: Fix typo on Documentation
+
+It is analysis, not analisys.
+
+Reported-by: William Cohen <wcohen@redhat.com>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Mike Galbraith <efault@gmx.de>
+Cc: Namhyung Kim <namhyung@gmail.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/n/tip-s7476m0irq0naxkzd9iekbr3@git.kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Documentation/perf-archive.txt | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/Documentation/perf-archive.txt b/tools/perf/Documentation/perf-archive.txt
+index fae174d..5032a14 100644
+--- a/tools/perf/Documentation/perf-archive.txt
++++ b/tools/perf/Documentation/perf-archive.txt
+@@ -13,7 +13,7 @@ SYNOPSIS
+ DESCRIPTION
+ -----------
+ This command runs runs perf-buildid-list --with-hits, and collects the files
+-with the buildids found so that analisys of perf.data contents can be possible
++with the buildids found so that analysis of perf.data contents can be possible
+ on another machine.
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0367-perf-sort-Reorder-HISTC_SRCLINE-index.patch b/patches.tizen/0367-perf-sort-Reorder-HISTC_SRCLINE-index.patch
new file mode 100644 (file)
index 0000000..22e896e
--- /dev/null
@@ -0,0 +1,44 @@
+From 4c197e285922926fb418f9619be87d36743b6ba3 Mon Sep 17 00:00:00 2001
+From: Namhyung Kim <namhyung.kim@lge.com>
+Date: Fri, 5 Apr 2013 10:26:31 +0900
+Subject: [PATCH 0367/1302] perf sort: Reorder HISTC_SRCLINE index
+
+It's in common sort dimension so it'd be more natural to place it with
+other common column index.
+
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1365125198-8334-2-git-send-email-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/util/hist.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
+index 14c2fe2..6be88dc 100644
+--- a/tools/perf/util/hist.h
++++ b/tools/perf/util/hist.h
+@@ -43,12 +43,12 @@ enum hist_column {
+       HISTC_COMM,
+       HISTC_PARENT,
+       HISTC_CPU,
++      HISTC_SRCLINE,
+       HISTC_MISPREDICT,
+       HISTC_SYMBOL_FROM,
+       HISTC_SYMBOL_TO,
+       HISTC_DSO_FROM,
+       HISTC_DSO_TO,
+-      HISTC_SRCLINE,
+       HISTC_LOCAL_WEIGHT,
+       HISTC_GLOBAL_WEIGHT,
+       HISTC_MEM_DADDR_SYMBOL,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0368-perf-sort-Cleanup-sort__has_sym-setting.patch b/patches.tizen/0368-perf-sort-Cleanup-sort__has_sym-setting.patch
new file mode 100644 (file)
index 0000000..cadd74e
--- /dev/null
@@ -0,0 +1,43 @@
+From 14d978e63143e6b86ce5a45e87b0b7d4860ffb69 Mon Sep 17 00:00:00 2001
+From: Namhyung Kim <namhyung.kim@lge.com>
+Date: Fri, 5 Apr 2013 10:26:36 +0900
+Subject: [PATCH 0368/1302] perf sort: Cleanup sort__has_sym setting
+
+The sort__has_sym variable is set only if a symbol-related sort key was
+added.  Since branch stack and memory sort dimensions are separated, it
+doesn't need to be checked from common dimension.
+
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1365125198-8334-7-git-send-email-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/util/sort.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
+index 701ab1d..313a5a7 100644
+--- a/tools/perf/util/sort.c
++++ b/tools/perf/util/sort.c
+@@ -938,10 +938,7 @@ int sort_dimension__add(const char *tok)
+                               return -EINVAL;
+                       }
+                       sort__has_parent = 1;
+-              } else if (sd->entry == &sort_sym ||
+-                         sd->entry == &sort_sym_from ||
+-                         sd->entry == &sort_sym_to ||
+-                         sd->entry == &sort_mem_daddr_sym) {
++              } else if (sd->entry == &sort_sym) {
+                       sort__has_sym = 1;
+               }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0369-perf-top-Use-sort__has_sym.patch b/patches.tizen/0369-perf-top-Use-sort__has_sym.patch
new file mode 100644 (file)
index 0000000..d47ddb7
--- /dev/null
@@ -0,0 +1,76 @@
+From 2b010f2391a75eb5689bf7deab35af373c0ee31f Mon Sep 17 00:00:00 2001
+From: Namhyung Kim <namhyung.kim@lge.com>
+Date: Fri, 5 Apr 2013 10:26:37 +0900
+Subject: [PATCH 0369/1302] perf top: Use sort__has_sym
+
+perf top had a similar variable sort_has_symbols for the same purpose.
+
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1365125198-8334-8-git-send-email-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/builtin-top.c | 12 +++---------
+ tools/perf/util/top.h    |  1 -
+ 2 files changed, 3 insertions(+), 10 deletions(-)
+
+diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
+index 2eb272d..df9e06a 100644
+--- a/tools/perf/builtin-top.c
++++ b/tools/perf/builtin-top.c
+@@ -794,7 +794,7 @@ static void perf_event__process_sample(struct perf_tool *tool,
+                               return;
+               }
+-              if (top->sort_has_symbols)
++              if (sort__has_sym)
+                       perf_top__record_precise_ip(top, he, evsel->idx, ip);
+       }
+@@ -912,9 +912,9 @@ out_err:
+       return -1;
+ }
+-static int perf_top__setup_sample_type(struct perf_top *top)
++static int perf_top__setup_sample_type(struct perf_top *top __maybe_unused)
+ {
+-      if (!top->sort_has_symbols) {
++      if (!sort__has_sym) {
+               if (symbol_conf.use_callchain) {
+                       ui__error("Selected -g but \"sym\" not present in --sort/-s.");
+                       return -EINVAL;
+@@ -1202,12 +1202,6 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
+       sort__setup_elide(stdout);
+-      /*
+-       * Avoid annotation data structures overhead when symbols aren't on the
+-       * sort list.
+-       */
+-      top.sort_has_symbols = sort_sym.list.next != NULL;
+-
+       get_term_dimensions(&top.winsize);
+       if (top.print_entries == 0) {
+               struct sigaction act = {
+diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h
+index 7ebf357..f0a8625 100644
+--- a/tools/perf/util/top.h
++++ b/tools/perf/util/top.h
+@@ -26,7 +26,6 @@ struct perf_top {
+       int                print_entries, count_filter, delay_secs;
+       bool               hide_kernel_symbols, hide_user_symbols, zero;
+       bool               use_tui, use_stdio;
+-      bool               sort_has_symbols;
+       bool               kptr_restrict_warned;
+       bool               vmlinux_warned;
+       bool               dump_symtab;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0370-perf-hists-browser-Use-sort__has_sym.patch b/patches.tizen/0370-perf-hists-browser-Use-sort__has_sym.patch
new file mode 100644 (file)
index 0000000..e7ebd48
--- /dev/null
@@ -0,0 +1,67 @@
+From 95d57c480be9b15000d571e4e77e297d7e6b5e41 Mon Sep 17 00:00:00 2001
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+Date: Fri, 26 Apr 2013 14:28:46 -0300
+Subject: [PATCH 0370/1302] perf hists browser: Use sort__has_sym
+
+The TUI hist browser had a similar variable has_symbols for the same
+purpose.  Let's get rid of the duplication.
+
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1365125198-8334-9-git-send-email-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/ui/browsers/hists.c | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
+index cad8e37..a4268ca 100644
+--- a/tools/perf/ui/browsers/hists.c
++++ b/tools/perf/ui/browsers/hists.c
+@@ -25,7 +25,6 @@ struct hist_browser {
+       struct map_symbol   *selection;
+       int                  print_seq;
+       bool                 show_dso;
+-      bool                 has_symbols;
+ };
+ extern void hist_browser__init_hpp(void);
+@@ -1155,10 +1154,6 @@ static struct hist_browser *hist_browser__new(struct hists *hists)
+               browser->b.refresh = hist_browser__refresh;
+               browser->b.seek = ui_browser__hists_seek;
+               browser->b.use_navkeypressed = true;
+-              if (sort__mode == SORT_MODE__BRANCH)
+-                      browser->has_symbols = sort_sym_from.list.next != NULL;
+-              else
+-                      browser->has_symbols = sort_sym.list.next != NULL;
+       }
+       return browser;
+@@ -1386,7 +1381,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
+                        */
+                       goto out_free_stack;
+               case 'a':
+-                      if (!browser->has_symbols) {
++                      if (!sort__has_sym) {
+                               ui_browser__warning(&browser->b, delay_secs * 2,
+                       "Annotation is only available for symbolic views, "
+                       "include \"sym*\" in --sort to use it.");
+@@ -1485,7 +1480,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
+                       continue;
+               }
+-              if (!browser->has_symbols)
++              if (!sort__has_sym)
+                       goto add_exit_option;
+               if (sort__mode == SORT_MODE__BRANCH) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0371-perf-tools-Fix-tab-vs-spaces-issue-in-Makefile-ifdef.patch b/patches.tizen/0371-perf-tools-Fix-tab-vs-spaces-issue-in-Makefile-ifdef.patch
new file mode 100644 (file)
index 0000000..0ed8bb9
--- /dev/null
@@ -0,0 +1,58 @@
+From 0647ddf4f77a7188d88c1fbaa04f207f0ffd9f7c Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Wed, 24 Apr 2013 11:37:29 +0200
+Subject: [PATCH 0371/1302] perf tools: Fix tab vs spaces issue in Makefile
+ ifdef/endif
+
+Unmatched spaces/tabs Makefile indentation could make the
+Makefile fails. While the tabed line could be considered
+sometimes as follow up for rule command, the mixed space
+tab meses up with makefile if conditions.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1366796273-4780-3-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Makefile | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/tools/perf/Makefile b/tools/perf/Makefile
+index b0f164b..c8fb0fd 100644
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -90,7 +90,7 @@ endif
+ # Treat warnings as errors unless directed not to
+ ifneq ($(WERROR),0)
+-      CFLAGS_WERROR := -Werror
++  CFLAGS_WERROR := -Werror
+ endif
+ ifeq ("$(origin DEBUG)", "command line")
+@@ -819,10 +819,10 @@ endif
+ ifdef NO_DEMANGLE
+       BASIC_CFLAGS += -DNO_DEMANGLE
+ else
+-        ifdef HAVE_CPLUS_DEMANGLE
++      ifdef HAVE_CPLUS_DEMANGLE
+               EXTLIBS += -liberty
+               BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
+-        else
++      else
+               FLAGS_BFD=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -DPACKAGE='perf' -lbfd
+               has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD),libbfd)
+               ifeq ($(has_bfd),y)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0372-perf-tests-Fix-compile-errors-in-bp_signal-files.patch b/patches.tizen/0372-perf-tests-Fix-compile-errors-in-bp_signal-files.patch
new file mode 100644 (file)
index 0000000..e694532
--- /dev/null
@@ -0,0 +1,58 @@
+From 7be9ebfd16952dce645c49825ae40bd1a20591b8 Mon Sep 17 00:00:00 2001
+From: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
+Date: Fri, 26 Apr 2013 10:17:56 -0700
+Subject: [PATCH 0372/1302] perf tests: Fix compile errors in bp_signal files
+
+When building on powerpc,  we get compile errors in bp_signal.c and
+bp_signal_overflow.c due to __u64 and '%llx'.
+
+Powerpc, needs __SANE_USERSPACE_TYPES__ to be defined so we pick up
+<asm-generic/int-ll64.h> and define __u64 as unsigned long long.
+
+Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Link: http://lkml.kernel.org/r/20130426173320.GA7029@us.ibm.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/tests/bp_signal.c          | 6 ++++++
+ tools/perf/tests/bp_signal_overflow.c | 6 ++++++
+ 2 files changed, 12 insertions(+)
+
+diff --git a/tools/perf/tests/bp_signal.c b/tools/perf/tests/bp_signal.c
+index 68daa28..aba0954 100644
+--- a/tools/perf/tests/bp_signal.c
++++ b/tools/perf/tests/bp_signal.c
+@@ -4,6 +4,12 @@
+  * (git://github.com/deater/perf_event_tests)
+  */
++/*
++ * Powerpc needs __SANE_USERSPACE_TYPES__ before <linux/types.h> to select
++ * 'int-ll64.h' and avoid compile warnings when printing __u64 with %llu.
++ */
++#define __SANE_USERSPACE_TYPES__
++
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <unistd.h>
+diff --git a/tools/perf/tests/bp_signal_overflow.c b/tools/perf/tests/bp_signal_overflow.c
+index fe7ed28..44ac821 100644
+--- a/tools/perf/tests/bp_signal_overflow.c
++++ b/tools/perf/tests/bp_signal_overflow.c
+@@ -3,6 +3,12 @@
+  * perf_event_tests (git://github.com/deater/perf_event_tests)
+  */
++/*
++ * Powerpc needs __SANE_USERSPACE_TYPES__ before <linux/types.h> to select
++ * 'int-ll64.h' and avoid compile warnings when printing __u64 with %llu.
++ */
++#define __SANE_USERSPACE_TYPES__
++
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <unistd.h>
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0373-perf-record-handle-death-by-SIGTERM.patch b/patches.tizen/0373-perf-record-handle-death-by-SIGTERM.patch
new file mode 100644 (file)
index 0000000..ef48456
--- /dev/null
@@ -0,0 +1,59 @@
+From 5f2bea012df00029789a8029eda739b193d05579 Mon Sep 17 00:00:00 2001
+From: David Ahern <dsahern@gmail.com>
+Date: Mon, 6 May 2013 12:24:23 -0600
+Subject: [PATCH 0373/1302] perf record: handle death by SIGTERM
+
+Perf data files cannot be processed until the header is updated which is
+done via an on_exit handler.
+
+If perf is killed due to a SIGTERM it does not run the on_exit hooks
+leaving the perf.data file in a random state which perf-report will
+happily spin on trying to read.
+
+As noted by Mike an easy reproducer is:
+
+perf record -a -g & sleep 1; killall perf
+
+Fix by catching SIGTERM like it does SIGINT.
+
+Also need to remove the kill which was added via commit f7b7c26e.
+
+Acked-by: Stephane Eranian <eranian@google.com>
+Signed-off-by: David Ahern <dsahern@gmail.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Mike Galbraith <efault@gmx.de>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1367864663-1309-1-git-send-email-dsahern@gmail.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/builtin-record.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
+index cdf58ec..fff985c 100644
+--- a/tools/perf/builtin-record.c
++++ b/tools/perf/builtin-record.c
+@@ -198,7 +198,6 @@ static void perf_record__sig_exit(int exit_status __maybe_unused, void *arg)
+               return;
+       signal(signr, SIG_DFL);
+-      kill(getpid(), signr);
+ }
+ static bool perf_evlist__equal(struct perf_evlist *evlist,
+@@ -404,6 +403,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
+       signal(SIGCHLD, sig_handler);
+       signal(SIGINT, sig_handler);
+       signal(SIGUSR1, sig_handler);
++      signal(SIGTERM, sig_handler);
+       if (!output_name) {
+               if (!fstat(STDOUT_FILENO, &st) && S_ISFIFO(st.st_mode))
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0374-perf-top-Fix-E-option-behavior.patch b/patches.tizen/0374-perf-top-Fix-E-option-behavior.patch
new file mode 100644 (file)
index 0000000..ba88b75
--- /dev/null
@@ -0,0 +1,84 @@
+From 81f9d9f6e2131074bfa895d5b43c8b3e79a4ca33 Mon Sep 17 00:00:00 2001
+From: Namhyung Kim <namhyung.kim@lge.com>
+Date: Tue, 14 May 2013 11:08:59 +0900
+Subject: [PATCH 0374/1302] perf top: Fix -E option behavior
+
+The -E/--entries option controls how many lines to be printed on stdio
+output but it doesn't work as it should be:
+
+If -E option is specified, print that many lines regardless of current
+window size, if not automatically adjust number of lines printed to fit
+into the window size.
+
+Reported-by: Minchan Kim <minchan@kernel.org>
+Tested-by: Jiri Olsa <jolsa@redhat.com>
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1368497347-9628-2-git-send-email-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/builtin-top.c | 17 +++++------------
+ 1 file changed, 5 insertions(+), 12 deletions(-)
+
+diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
+index df9e06a..81adcaf 100644
+--- a/tools/perf/builtin-top.c
++++ b/tools/perf/builtin-top.c
+@@ -70,10 +70,11 @@
+ static volatile int done;
++#define HEADER_LINE_NR  5
++
+ static void perf_top__update_print_entries(struct perf_top *top)
+ {
+-      if (top->print_entries > 9)
+-              top->print_entries -= 9;
++      top->print_entries = top->winsize.ws_row - HEADER_LINE_NR;
+ }
+ static void perf_top__sig_winch(int sig __maybe_unused,
+@@ -82,13 +83,6 @@ static void perf_top__sig_winch(int sig __maybe_unused,
+       struct perf_top *top = arg;
+       get_term_dimensions(&top->winsize);
+-      if (!top->print_entries
+-          || (top->print_entries+4) > top->winsize.ws_row) {
+-              top->print_entries = top->winsize.ws_row;
+-      } else {
+-              top->print_entries += 4;
+-              top->winsize.ws_row = top->print_entries;
+-      }
+       perf_top__update_print_entries(top);
+ }
+@@ -296,10 +290,10 @@ static void perf_top__print_sym_table(struct perf_top *top)
+                                     top->hide_user_symbols,
+                                     top->hide_kernel_symbols);
+       hists__output_recalc_col_len(&top->sym_evsel->hists,
+-                                   top->winsize.ws_row - 3);
++                                   top->print_entries - printed);
+       putchar('\n');
+       hists__fprintf(&top->sym_evsel->hists, false,
+-                     top->winsize.ws_row - 4 - printed, win_width, stdout);
++                     top->print_entries - printed, win_width, stdout);
+ }
+ static void prompt_integer(int *target, const char *msg)
+@@ -477,7 +471,6 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c)
+                               perf_top__sig_winch(SIGWINCH, NULL, top);
+                               sigaction(SIGWINCH, &act, NULL);
+                       } else {
+-                              perf_top__sig_winch(SIGWINCH, NULL, top);
+                               signal(SIGWINCH, SIG_DFL);
+                       }
+                       break;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0375-perf-top-Fix-percent-output-when-no-samples-collecte.patch b/patches.tizen/0375-perf-top-Fix-percent-output-when-no-samples-collecte.patch
new file mode 100644 (file)
index 0000000..3dbd4cb
--- /dev/null
@@ -0,0 +1,69 @@
+From fc0914141006b72785cbc64b299f074abc837278 Mon Sep 17 00:00:00 2001
+From: Namhyung Kim <namhyung.kim@lge.com>
+Date: Tue, 14 May 2013 11:09:00 +0900
+Subject: [PATCH 0375/1302] perf top: Fix percent output when no samples
+ collected
+
+If there's no sample, kernel and exact percent output at the header
+looked like "-nan%".
+
+Tested-by: Jiri Olsa <jolsa@redhat.com>
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1368497347-9628-3-git-send-email-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/util/top.c | 23 +++++++++++++++++------
+ 1 file changed, 17 insertions(+), 6 deletions(-)
+
+diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c
+index 54d37a4..f857b51 100644
+--- a/tools/perf/util/top.c
++++ b/tools/perf/util/top.c
+@@ -23,20 +23,31 @@
+ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size)
+ {
+-      float samples_per_sec = top->samples / top->delay_secs;
+-      float ksamples_per_sec = top->kernel_samples / top->delay_secs;
+-      float esamples_percent = (100.0 * top->exact_samples) / top->samples;
++      float samples_per_sec;
++      float ksamples_per_sec;
++      float esamples_percent;
+       struct perf_record_opts *opts = &top->record_opts;
+       struct perf_target *target = &opts->target;
+       size_t ret = 0;
++      if (top->samples) {
++              samples_per_sec = top->samples / top->delay_secs;
++              ksamples_per_sec = top->kernel_samples / top->delay_secs;
++              esamples_percent = (100.0 * top->exact_samples) / top->samples;
++      } else {
++              samples_per_sec = ksamples_per_sec = esamples_percent = 0.0;
++      }
++
+       if (!perf_guest) {
++              float ksamples_percent = 0.0;
++
++              if (samples_per_sec)
++                      ksamples_percent = (100.0 * ksamples_per_sec) /
++                                                      samples_per_sec;
+               ret = SNPRINTF(bf, size,
+                              "   PerfTop:%8.0f irqs/sec  kernel:%4.1f%%"
+                              "  exact: %4.1f%% [", samples_per_sec,
+-                             100.0 - (100.0 * ((samples_per_sec - ksamples_per_sec) /
+-                                      samples_per_sec)),
+-                              esamples_percent);
++                             ksamples_percent, esamples_percent);
+       } else {
+               float us_samples_per_sec = top->us_samples / top->delay_secs;
+               float guest_kernel_samples_per_sec = top->guest_kernel_samples / top->delay_secs;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0376-perf-top-Get-rid-of-_threaded-functions.patch b/patches.tizen/0376-perf-top-Get-rid-of-_threaded-functions.patch
new file mode 100644 (file)
index 0000000..a8714e6
--- /dev/null
@@ -0,0 +1,207 @@
+From 3abde2f43249bcb75e09b68852a15445d0ebb241 Mon Sep 17 00:00:00 2001
+From: Namhyung Kim <namhyung.kim@lge.com>
+Date: Tue, 14 May 2013 11:09:01 +0900
+Subject: [PATCH 0376/1302] perf top: Get rid of *_threaded() functions
+
+Those _threaded() functions are needed to make hist tree handling
+thread-safe, but AFAICS the only thing it does is forcing it to use
+the intermediate 'collapsed' tree.
+
+This can be acheived by setting sort__need_collapse to 1 in cmd_top() so
+no need to keep those _threaded() variants.
+
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Acked-by: Jiri Olsa <jolsa@redhat.com>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1368497347-9628-4-git-send-email-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/builtin-top.c | 23 +++++++++++++----------
+ tools/perf/util/hist.c   | 44 ++++++--------------------------------------
+ tools/perf/util/hist.h   |  4 ----
+ 3 files changed, 19 insertions(+), 52 deletions(-)
+
+diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
+index 81adcaf..5cd41ec 100644
+--- a/tools/perf/builtin-top.c
++++ b/tools/perf/builtin-top.c
+@@ -284,11 +284,11 @@ static void perf_top__print_sym_table(struct perf_top *top)
+               return;
+       }
+-      hists__collapse_resort_threaded(&top->sym_evsel->hists);
+-      hists__output_resort_threaded(&top->sym_evsel->hists);
+-      hists__decay_entries_threaded(&top->sym_evsel->hists,
+-                                    top->hide_user_symbols,
+-                                    top->hide_kernel_symbols);
++      hists__collapse_resort(&top->sym_evsel->hists);
++      hists__output_resort(&top->sym_evsel->hists);
++      hists__decay_entries(&top->sym_evsel->hists,
++                           top->hide_user_symbols,
++                           top->hide_kernel_symbols);
+       hists__output_recalc_col_len(&top->sym_evsel->hists,
+                                    top->print_entries - printed);
+       putchar('\n');
+@@ -549,11 +549,11 @@ static void perf_top__sort_new_samples(void *arg)
+       if (t->evlist->selected != NULL)
+               t->sym_evsel = t->evlist->selected;
+-      hists__collapse_resort_threaded(&t->sym_evsel->hists);
+-      hists__output_resort_threaded(&t->sym_evsel->hists);
+-      hists__decay_entries_threaded(&t->sym_evsel->hists,
+-                                    t->hide_user_symbols,
+-                                    t->hide_kernel_symbols);
++      hists__collapse_resort(&t->sym_evsel->hists);
++      hists__output_resort(&t->sym_evsel->hists);
++      hists__decay_entries(&t->sym_evsel->hists,
++                           t->hide_user_symbols,
++                           t->hide_kernel_symbols);
+ }
+ static void *display_thread_tui(void *arg)
+@@ -1126,6 +1126,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
+       if (setup_sorting() < 0)
+               usage_with_options(top_usage, options);
++      /* display thread wants entries to be collapsed in a different tree */
++      sort__need_collapse = 1;
++
+       if (top.use_stdio)
+               use_browser = 0;
+       else if (top.use_tui)
+diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
+index 72b4eec..7e0fa62 100644
+--- a/tools/perf/util/hist.c
++++ b/tools/perf/util/hist.c
+@@ -240,8 +240,7 @@ static bool hists__decay_entry(struct hists *hists, struct hist_entry *he)
+       return he->stat.period == 0;
+ }
+-static void __hists__decay_entries(struct hists *hists, bool zap_user,
+-                                 bool zap_kernel, bool threaded)
++void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel)
+ {
+       struct rb_node *next = rb_first(&hists->entries);
+       struct hist_entry *n;
+@@ -260,7 +259,7 @@ static void __hists__decay_entries(struct hists *hists, bool zap_user,
+                   !n->used) {
+                       rb_erase(&n->rb_node, &hists->entries);
+-                      if (sort__need_collapse || threaded)
++                      if (sort__need_collapse)
+                               rb_erase(&n->rb_node_in, &hists->entries_collapsed);
+                       hist_entry__free(n);
+@@ -269,17 +268,6 @@ static void __hists__decay_entries(struct hists *hists, bool zap_user,
+       }
+ }
+-void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel)
+-{
+-      return __hists__decay_entries(hists, zap_user, zap_kernel, false);
+-}
+-
+-void hists__decay_entries_threaded(struct hists *hists,
+-                                 bool zap_user, bool zap_kernel)
+-{
+-      return __hists__decay_entries(hists, zap_user, zap_kernel, true);
+-}
+-
+ /*
+  * histogram, sorted on item, collects periods
+  */
+@@ -613,13 +601,13 @@ static void hists__apply_filters(struct hists *hists, struct hist_entry *he)
+       hists__filter_entry_by_symbol(hists, he);
+ }
+-static void __hists__collapse_resort(struct hists *hists, bool threaded)
++void hists__collapse_resort(struct hists *hists)
+ {
+       struct rb_root *root;
+       struct rb_node *next;
+       struct hist_entry *n;
+-      if (!sort__need_collapse && !threaded)
++      if (!sort__need_collapse)
+               return;
+       root = hists__get_rotate_entries_in(hists);
+@@ -641,16 +629,6 @@ static void __hists__collapse_resort(struct hists *hists, bool threaded)
+       }
+ }
+-void hists__collapse_resort(struct hists *hists)
+-{
+-      return __hists__collapse_resort(hists, false);
+-}
+-
+-void hists__collapse_resort_threaded(struct hists *hists)
+-{
+-      return __hists__collapse_resort(hists, true);
+-}
+-
+ /*
+  * reverse the map, sort on period.
+  */
+@@ -737,7 +715,7 @@ static void __hists__insert_output_entry(struct rb_root *entries,
+       rb_insert_color(&he->rb_node, entries);
+ }
+-static void __hists__output_resort(struct hists *hists, bool threaded)
++void hists__output_resort(struct hists *hists)
+ {
+       struct rb_root *root;
+       struct rb_node *next;
+@@ -746,7 +724,7 @@ static void __hists__output_resort(struct hists *hists, bool threaded)
+       min_callchain_hits = hists->stats.total_period * (callchain_param.min_percent / 100);
+-      if (sort__need_collapse || threaded)
++      if (sort__need_collapse)
+               root = &hists->entries_collapsed;
+       else
+               root = hists->entries_in;
+@@ -767,16 +745,6 @@ static void __hists__output_resort(struct hists *hists, bool threaded)
+       }
+ }
+-void hists__output_resort(struct hists *hists)
+-{
+-      return __hists__output_resort(hists, false);
+-}
+-
+-void hists__output_resort_threaded(struct hists *hists)
+-{
+-      return __hists__output_resort(hists, true);
+-}
+-
+ static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h,
+                                      enum hist_filter filter)
+ {
+diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
+index 6be88dc..bd81d79 100644
+--- a/tools/perf/util/hist.h
++++ b/tools/perf/util/hist.h
+@@ -104,13 +104,9 @@ struct hist_entry *__hists__add_mem_entry(struct hists *self,
+                                         u64 weight);
+ void hists__output_resort(struct hists *self);
+-void hists__output_resort_threaded(struct hists *hists);
+ void hists__collapse_resort(struct hists *self);
+-void hists__collapse_resort_threaded(struct hists *hists);
+ void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel);
+-void hists__decay_entries_threaded(struct hists *hists, bool zap_user,
+-                                 bool zap_kernel);
+ void hists__output_recalc_col_len(struct hists *hists, int max_rows);
+ void hists__inc_nr_entries(struct hists *hists, struct hist_entry *h);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0377-perf-hists-Move-locking-to-its-call-sites.patch b/patches.tizen/0377-perf-hists-Move-locking-to-its-call-sites.patch
new file mode 100644 (file)
index 0000000..58c64d2
--- /dev/null
@@ -0,0 +1,127 @@
+From 2b9307c3382e7768fcf8ecb23ba3b5a86c689c17 Mon Sep 17 00:00:00 2001
+From: Namhyung Kim <namhyung.kim@lge.com>
+Date: Tue, 14 May 2013 11:09:02 +0900
+Subject: [PATCH 0377/1302] perf hists: Move locking to its call-sites
+
+It's a preparation patch to eliminate unneeded locking in the perf
+report path.
+
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Acked-by: Jiri Olsa <jolsa@redhat.com>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1368497347-9628-5-git-send-email-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/builtin-report.c | 26 ++++++++++++++------------
+ tools/perf/builtin-top.c    |  3 +++
+ tools/perf/util/hist.c      |  6 +-----
+ 3 files changed, 18 insertions(+), 17 deletions(-)
+
+diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
+index d45bf9b..63febd2 100644
+--- a/tools/perf/builtin-report.c
++++ b/tools/perf/builtin-report.c
+@@ -297,6 +297,7 @@ static int process_sample_event(struct perf_tool *tool,
+ {
+       struct perf_report *rep = container_of(tool, struct perf_report, tool);
+       struct addr_location al;
++      int ret;
+       if (perf_event__preprocess_sample(event, machine, &al, sample,
+                                         rep->annotate_init) < 0) {
+@@ -311,28 +312,29 @@ static int process_sample_event(struct perf_tool *tool,
+       if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap))
+               return 0;
++      pthread_mutex_lock(&evsel->hists.lock);
++
+       if (sort__mode == SORT_MODE__BRANCH) {
+-              if (perf_report__add_branch_hist_entry(tool, &al, sample,
+-                                                     evsel, machine)) {
++              ret = perf_report__add_branch_hist_entry(tool, &al, sample,
++                                                       evsel, machine);
++              if (ret < 0)
+                       pr_debug("problem adding lbr entry, skipping event\n");
+-                      return -1;
+-              }
+       } else if (rep->mem_mode == 1) {
+-              if (perf_report__add_mem_hist_entry(tool, &al, sample,
+-                                                  evsel, machine, event)) {
++              ret = perf_report__add_mem_hist_entry(tool, &al, sample,
++                                                    evsel, machine, event);
++              if (ret < 0)
+                       pr_debug("problem adding mem entry, skipping event\n");
+-                      return -1;
+-              }
+       } else {
+               if (al.map != NULL)
+                       al.map->dso->hit = 1;
+-              if (perf_evsel__add_hist_entry(evsel, &al, sample, machine)) {
++              ret = perf_evsel__add_hist_entry(evsel, &al, sample, machine);
++              if (ret < 0)
+                       pr_debug("problem incrementing symbol period, skipping event\n");
+-                      return -1;
+-              }
+       }
+-      return 0;
++      pthread_mutex_unlock(&evsel->hists.lock);
++
++      return ret;
+ }
+ static int process_read_event(struct perf_tool *tool,
+diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
+index 5cd41ec..c2c9734 100644
+--- a/tools/perf/builtin-top.c
++++ b/tools/perf/builtin-top.c
+@@ -245,8 +245,11 @@ static struct hist_entry *perf_evsel__add_hist_entry(struct perf_evsel *evsel,
+ {
+       struct hist_entry *he;
++      pthread_mutex_lock(&evsel->hists.lock);
+       he = __hists__add_entry(&evsel->hists, al, NULL, sample->period,
+                               sample->weight);
++      pthread_mutex_unlock(&evsel->hists.lock);
++
+       if (he == NULL)
+               return NULL;
+diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
+index 7e0fa62..b11a6cf 100644
+--- a/tools/perf/util/hist.c
++++ b/tools/perf/util/hist.c
+@@ -347,8 +347,6 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
+       struct hist_entry *he;
+       int cmp;
+-      pthread_mutex_lock(&hists->lock);
+-
+       p = &hists->entries_in->rb_node;
+       while (*p != NULL) {
+@@ -394,14 +392,12 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
+       he = hist_entry__new(entry);
+       if (!he)
+-              goto out_unlock;
++              return NULL;
+       rb_link_node(&he->rb_node_in, parent, p);
+       rb_insert_color(&he->rb_node_in, hists->entries_in);
+ out:
+       hist_entry__add_cpumode_period(he, al->cpumode, period);
+-out_unlock:
+-      pthread_mutex_unlock(&hists->lock);
+       return he;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0378-perf-report-Don-t-bother-locking-when-adding-hist-en.patch b/patches.tizen/0378-perf-report-Don-t-bother-locking-when-adding-hist-en.patch
new file mode 100644 (file)
index 0000000..4c6e0ee
--- /dev/null
@@ -0,0 +1,66 @@
+From 726f8bccc24d44d4b21ecaadd802103057751c11 Mon Sep 17 00:00:00 2001
+From: Namhyung Kim <namhyung.kim@lge.com>
+Date: Tue, 14 May 2013 11:09:03 +0900
+Subject: [PATCH 0378/1302] perf report: Don't bother locking when adding hist
+ entries
+
+The 'perf report'command is single-threaded, so no need to grab a lock.
+
+Although the fast path of pthread_mutex_[un]lock() is very fast, there's
+a ~3% gain by eliminating it when we have huge sample data.
+
+  $ perf record -a -F 100000 -o perf.data.bench -- perf bench sched all
+  $ perf record -e cycles:upp -o perf.data.before -- \
+  > perf report -i perf.data.bench --stdio > /dev/null
+  ... apply this patch ...
+  $ perf record -e cycles:upp -o perf.data.after -- \
+  > perf report -i perf.data.bench --stdio > /dev/null
+  $ perf diff perf.data.{before,after} | grep pthread
+             +0.02%  libpthread-2.15.so  [.] _pthread_cleanup_push_defer
+             +0.02%  libpthread-2.15.so  [.] _pthread_cleanup_pop_restore
+     0.05%   -0.05%  perf                [.] pthread_mutex_unlock@plt
+     0.05%   -0.05%  perf                [.] pthread_mutex_lock@plt
+     1.01%   -1.01%  libpthread-2.15.so  [.] pthread_mutex_lock
+     1.68%   -1.68%  libpthread-2.15.so  [.] __pthread_mutex_unlock_usercnt
+     0.05%   -0.05%  libpthread-2.15.so  [.] pthread_mutex_unlock
+
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Acked-by: Jiri Olsa <jolsa@redhat.com>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1368497347-9628-6-git-send-email-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/builtin-report.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
+index 63febd2..0f0cf24 100644
+--- a/tools/perf/builtin-report.c
++++ b/tools/perf/builtin-report.c
+@@ -312,8 +312,6 @@ static int process_sample_event(struct perf_tool *tool,
+       if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap))
+               return 0;
+-      pthread_mutex_lock(&evsel->hists.lock);
+-
+       if (sort__mode == SORT_MODE__BRANCH) {
+               ret = perf_report__add_branch_hist_entry(tool, &al, sample,
+                                                        evsel, machine);
+@@ -332,8 +330,6 @@ static int process_sample_event(struct perf_tool *tool,
+               if (ret < 0)
+                       pr_debug("problem incrementing symbol period, skipping event\n");
+       }
+-      pthread_mutex_unlock(&evsel->hists.lock);
+-
+       return ret;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0379-perf-report-Add-percent-limit-option.patch b/patches.tizen/0379-perf-report-Add-percent-limit-option.patch
new file mode 100644 (file)
index 0000000..41391ef
--- /dev/null
@@ -0,0 +1,515 @@
+From f84ea0d49234a403ed6b7530614f473f4fd1896e Mon Sep 17 00:00:00 2001
+From: Namhyung Kim <namhyung.kim@lge.com>
+Date: Tue, 14 May 2013 11:09:04 +0900
+Subject: [PATCH 0379/1302] perf report: Add --percent-limit option
+
+The --percent-limit option is for not showing small overhead entries in
+the output.  Maybe we want to set a certain default value like 0.1.
+
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Acked-by: Pekka Enberg <penberg@kernel.org>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1368497347-9628-7-git-send-email-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Documentation/perf-report.txt |  4 ++
+ tools/perf/builtin-diff.c                |  2 +-
+ tools/perf/builtin-report.c              | 21 +++++++--
+ tools/perf/builtin-top.c                 |  4 +-
+ tools/perf/ui/browsers/hists.c           | 79 +++++++++++++++++++++++++++-----
+ tools/perf/ui/gtk/hists.c                | 13 ++++--
+ tools/perf/ui/stdio/hist.c               |  7 ++-
+ tools/perf/util/hist.h                   | 10 ++--
+ 8 files changed, 115 insertions(+), 25 deletions(-)
+
+diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
+index 7d5f4f3..66dab74 100644
+--- a/tools/perf/Documentation/perf-report.txt
++++ b/tools/perf/Documentation/perf-report.txt
+@@ -210,6 +210,10 @@ OPTIONS
+       Demangle symbol names to human readable form. It's enabled by default,
+       disable with --no-demangle.
++--percent-limit::
++      Do not show entries which have an overhead under that percent.
++      (Default: 0).
++
+ SEE ALSO
+ --------
+ linkperf:perf-stat[1], linkperf:perf-annotate[1]
+diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
+index cabbea5..a9d63c1 100644
+--- a/tools/perf/builtin-diff.c
++++ b/tools/perf/builtin-diff.c
+@@ -457,7 +457,7 @@ static void hists__process(struct hists *old, struct hists *new)
+               hists__output_resort(new);
+       }
+-      hists__fprintf(new, true, 0, 0, stdout);
++      hists__fprintf(new, true, 0, 0, 0, stdout);
+ }
+ static int __cmd_diff(void)
+diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
+index 0f0cf24..0a4979b 100644
+--- a/tools/perf/builtin-report.c
++++ b/tools/perf/builtin-report.c
+@@ -52,6 +52,7 @@ struct perf_report {
+       symbol_filter_t         annotate_init;
+       const char              *cpu_list;
+       const char              *symbol_filter_str;
++      float                   min_percent;
+       DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
+ };
+@@ -456,7 +457,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
+                       continue;
+               hists__fprintf_nr_sample_events(rep, hists, evname, stdout);
+-              hists__fprintf(hists, true, 0, 0, stdout);
++              hists__fprintf(hists, true, 0, 0, rep->min_percent, stdout);
+               fprintf(stdout, "\n\n");
+       }
+@@ -575,8 +576,8 @@ static int __cmd_report(struct perf_report *rep)
+       if (use_browser > 0) {
+               if (use_browser == 1) {
+                       ret = perf_evlist__tui_browse_hists(session->evlist,
+-                                                      help,
+-                                                      NULL,
++                                                      help, NULL,
++                                                      rep->min_percent,
+                                                       &session->header.env);
+                       /*
+                        * Usually "ret" is the last pressed key, and we only
+@@ -587,7 +588,7 @@ static int __cmd_report(struct perf_report *rep)
+               } else if (use_browser == 2) {
+                       perf_evlist__gtk_browse_hists(session->evlist, help,
+-                                                    NULL);
++                                                    NULL, rep->min_percent);
+               }
+       } else
+               perf_evlist__tty_browse_hists(session->evlist, rep, help);
+@@ -698,6 +699,16 @@ parse_branch_mode(const struct option *opt __maybe_unused,
+       return 0;
+ }
++static int
++parse_percent_limit(const struct option *opt, const char *str,
++                  int unset __maybe_unused)
++{
++      struct perf_report *rep = opt->value;
++
++      rep->min_percent = strtof(str, NULL);
++      return 0;
++}
++
+ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
+ {
+       struct perf_session *session;
+@@ -807,6 +818,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
+       OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
+                   "Disable symbol demangling"),
+       OPT_BOOLEAN(0, "mem-mode", &report.mem_mode, "mem access profile"),
++      OPT_CALLBACK(0, "percent-limit", &report, "percent",
++                   "Don't show entries under that percent", parse_percent_limit),
+       OPT_END()
+       };
+diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
+index c2c9734..19fe25f 100644
+--- a/tools/perf/builtin-top.c
++++ b/tools/perf/builtin-top.c
+@@ -296,7 +296,7 @@ static void perf_top__print_sym_table(struct perf_top *top)
+                                    top->print_entries - printed);
+       putchar('\n');
+       hists__fprintf(&top->sym_evsel->hists, false,
+-                     top->print_entries - printed, win_width, stdout);
++                     top->print_entries - printed, win_width, 0, stdout);
+ }
+ static void prompt_integer(int *target, const char *msg)
+@@ -580,7 +580,7 @@ static void *display_thread_tui(void *arg)
+       list_for_each_entry(pos, &top->evlist->entries, node)
+               pos->hists.uid_filter_str = top->record_opts.target.uid_str;
+-      perf_evlist__tui_browse_hists(top->evlist, help, &hbt,
++      perf_evlist__tui_browse_hists(top->evlist, help, &hbt, 0,
+                                     &top->session->header.env);
+       done = 1;
+diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
+index a4268ca..9dfde61 100644
+--- a/tools/perf/ui/browsers/hists.c
++++ b/tools/perf/ui/browsers/hists.c
+@@ -25,6 +25,8 @@ struct hist_browser {
+       struct map_symbol   *selection;
+       int                  print_seq;
+       bool                 show_dso;
++      float                min_pcnt;
++      u64                  nr_pcnt_entries;
+ };
+ extern void hist_browser__init_hpp(void);
+@@ -317,6 +319,8 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
+       browser->b.entries = &browser->hists->entries;
+       browser->b.nr_entries = browser->hists->nr_entries;
++      if (browser->min_pcnt)
++              browser->b.nr_entries = browser->nr_pcnt_entries;
+       hist_browser__refresh_dimensions(browser);
+       hists__browser_title(browser->hists, title, sizeof(title), ev_name);
+@@ -795,10 +799,15 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser)
+       for (nd = browser->top; nd; nd = rb_next(nd)) {
+               struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
++              float percent = h->stat.period * 100.0 /
++                                      hb->hists->stats.total_period;
+               if (h->filtered)
+                       continue;
++              if (percent < hb->min_pcnt)
++                      continue;
++
+               row += hist_browser__show_entry(hb, h, row);
+               if (row == browser->height)
+                       break;
+@@ -807,10 +816,18 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser)
+       return row;
+ }
+-static struct rb_node *hists__filter_entries(struct rb_node *nd)
++static struct rb_node *hists__filter_entries(struct rb_node *nd,
++                                           struct hists *hists,
++                                           float min_pcnt)
+ {
+       while (nd != NULL) {
+               struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
++              float percent = h->stat.period * 100.0 /
++                                      hists->stats.total_period;
++
++              if (percent < min_pcnt)
++                      return NULL;
++
+               if (!h->filtered)
+                       return nd;
+@@ -820,11 +837,16 @@ static struct rb_node *hists__filter_entries(struct rb_node *nd)
+       return NULL;
+ }
+-static struct rb_node *hists__filter_prev_entries(struct rb_node *nd)
++static struct rb_node *hists__filter_prev_entries(struct rb_node *nd,
++                                                struct hists *hists,
++                                                float min_pcnt)
+ {
+       while (nd != NULL) {
+               struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
+-              if (!h->filtered)
++              float percent = h->stat.period * 100.0 /
++                                      hists->stats.total_period;
++
++              if (!h->filtered && percent >= min_pcnt)
+                       return nd;
+               nd = rb_prev(nd);
+@@ -839,6 +861,9 @@ static void ui_browser__hists_seek(struct ui_browser *browser,
+       struct hist_entry *h;
+       struct rb_node *nd;
+       bool first = true;
++      struct hist_browser *hb;
++
++      hb = container_of(browser, struct hist_browser, b);
+       if (browser->nr_entries == 0)
+               return;
+@@ -847,13 +872,15 @@ static void ui_browser__hists_seek(struct ui_browser *browser,
+       switch (whence) {
+       case SEEK_SET:
+-              nd = hists__filter_entries(rb_first(browser->entries));
++              nd = hists__filter_entries(rb_first(browser->entries),
++                                         hb->hists, hb->min_pcnt);
+               break;
+       case SEEK_CUR:
+               nd = browser->top;
+               goto do_offset;
+       case SEEK_END:
+-              nd = hists__filter_prev_entries(rb_last(browser->entries));
++              nd = hists__filter_prev_entries(rb_last(browser->entries),
++                                              hb->hists, hb->min_pcnt);
+               first = false;
+               break;
+       default:
+@@ -896,7 +923,8 @@ do_offset:
+                                       break;
+                               }
+                       }
+-                      nd = hists__filter_entries(rb_next(nd));
++                      nd = hists__filter_entries(rb_next(nd), hb->hists,
++                                                 hb->min_pcnt);
+                       if (nd == NULL)
+                               break;
+                       --offset;
+@@ -929,7 +957,8 @@ do_offset:
+                               }
+                       }
+-                      nd = hists__filter_prev_entries(rb_prev(nd));
++                      nd = hists__filter_prev_entries(rb_prev(nd), hb->hists,
++                                                      hb->min_pcnt);
+                       if (nd == NULL)
+                               break;
+                       ++offset;
+@@ -1098,14 +1127,17 @@ static int hist_browser__fprintf_entry(struct hist_browser *browser,
+ static int hist_browser__fprintf(struct hist_browser *browser, FILE *fp)
+ {
+-      struct rb_node *nd = hists__filter_entries(rb_first(browser->b.entries));
++      struct rb_node *nd = hists__filter_entries(rb_first(browser->b.entries),
++                                                 browser->hists,
++                                                 browser->min_pcnt);
+       int printed = 0;
+       while (nd) {
+               struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
+               printed += hist_browser__fprintf_entry(browser, h, fp);
+-              nd = hists__filter_entries(rb_next(nd));
++              nd = hists__filter_entries(rb_next(nd), browser->hists,
++                                         browser->min_pcnt);
+       }
+       return printed;
+@@ -1324,11 +1356,25 @@ close_file_and_continue:
+       return ret;
+ }
++static void hist_browser__update_pcnt_entries(struct hist_browser *hb)
++{
++      u64 nr_entries = 0;
++      struct rb_node *nd = rb_first(&hb->hists->entries);
++
++      while (nd) {
++              nr_entries++;
++              nd = hists__filter_entries(rb_next(nd), hb->hists,
++                                         hb->min_pcnt);
++      }
++
++      hb->nr_pcnt_entries = nr_entries;
++}
+ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
+                                   const char *helpline, const char *ev_name,
+                                   bool left_exits,
+                                   struct hist_browser_timer *hbt,
++                                  float min_pcnt,
+                                   struct perf_session_env *env)
+ {
+       struct hists *hists = &evsel->hists;
+@@ -1345,6 +1391,11 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
+       if (browser == NULL)
+               return -1;
++      if (min_pcnt) {
++              browser->min_pcnt = min_pcnt;
++              hist_browser__update_pcnt_entries(browser);
++      }
++
+       fstack = pstack__new(2);
+       if (fstack == NULL)
+               goto out;
+@@ -1684,6 +1735,7 @@ struct perf_evsel_menu {
+       struct ui_browser b;
+       struct perf_evsel *selection;
+       bool lost_events, lost_events_warned;
++      float min_pcnt;
+       struct perf_session_env *env;
+ };
+@@ -1777,6 +1829,7 @@ browse_hists:
+                       ev_name = perf_evsel__name(pos);
+                       key = perf_evsel__hists_browse(pos, nr_events, help,
+                                                      ev_name, true, hbt,
++                                                     menu->min_pcnt,
+                                                      menu->env);
+                       ui_browser__show_title(&menu->b, title);
+                       switch (key) {
+@@ -1838,6 +1891,7 @@ static bool filter_group_entries(struct ui_browser *self __maybe_unused,
+ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
+                                          int nr_entries, const char *help,
+                                          struct hist_browser_timer *hbt,
++                                         float min_pcnt,
+                                          struct perf_session_env *env)
+ {
+       struct perf_evsel *pos;
+@@ -1851,6 +1905,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
+                       .nr_entries = nr_entries,
+                       .priv       = evlist,
+               },
++              .min_pcnt = min_pcnt,
+               .env = env,
+       };
+@@ -1869,6 +1924,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
+ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
+                                 struct hist_browser_timer *hbt,
++                                float min_pcnt,
+                                 struct perf_session_env *env)
+ {
+       int nr_entries = evlist->nr_entries;
+@@ -1880,7 +1936,8 @@ single_entry:
+               const char *ev_name = perf_evsel__name(first);
+               return perf_evsel__hists_browse(first, nr_entries, help,
+-                                              ev_name, false, hbt, env);
++                                              ev_name, false, hbt, min_pcnt,
++                                              env);
+       }
+       if (symbol_conf.event_group) {
+@@ -1896,5 +1953,5 @@ single_entry:
+       }
+       return __perf_evlist__tui_browse_hists(evlist, nr_entries, help,
+-                                             hbt, env);
++                                             hbt, min_pcnt, env);
+ }
+diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c
+index 6f259b3..9708dd5 100644
+--- a/tools/perf/ui/gtk/hists.c
++++ b/tools/perf/ui/gtk/hists.c
+@@ -124,7 +124,8 @@ void perf_gtk__init_hpp(void)
+                               perf_gtk__hpp_color_overhead_guest_us;
+ }
+-static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists)
++static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists,
++                               float min_pcnt)
+ {
+       struct perf_hpp_fmt *fmt;
+       GType col_types[MAX_COLUMNS];
+@@ -189,10 +190,15 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists)
+       for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
+               struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
+               GtkTreeIter iter;
++              float percent = h->stat.period * 100.0 /
++                                      hists->stats.total_period;
+               if (h->filtered)
+                       continue;
++              if (percent < min_pcnt)
++                      continue;
++
+               gtk_list_store_append(store, &iter);
+               col_idx = 0;
+@@ -222,7 +228,8 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists)
+ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist,
+                                 const char *help,
+-                                struct hist_browser_timer *hbt __maybe_unused)
++                                struct hist_browser_timer *hbt __maybe_unused,
++                                float min_pcnt)
+ {
+       struct perf_evsel *pos;
+       GtkWidget *vbox;
+@@ -286,7 +293,7 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist,
+                                                       GTK_POLICY_AUTOMATIC,
+                                                       GTK_POLICY_AUTOMATIC);
+-              perf_gtk__show_hists(scrolled_window, hists);
++              perf_gtk__show_hists(scrolled_window, hists, min_pcnt);
+               tab_label = gtk_label_new(evname);
+diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
+index ff1f60c..ae7a754 100644
+--- a/tools/perf/ui/stdio/hist.c
++++ b/tools/perf/ui/stdio/hist.c
+@@ -334,7 +334,7 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size,
+ }
+ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
+-                    int max_cols, FILE *fp)
++                    int max_cols, float min_pcnt, FILE *fp)
+ {
+       struct perf_hpp_fmt *fmt;
+       struct sort_entry *se;
+@@ -440,10 +440,15 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
+ print_entries:
+       for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
+               struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
++              float percent = h->stat.period * 100.0 /
++                                      hists->stats.total_period;
+               if (h->filtered)
+                       continue;
++              if (percent < min_pcnt)
++                      continue;
++
+               ret += hist_entry__fprintf(h, max_cols, hists, fp);
+               if (max_rows && ++nr_rows >= max_rows)
+diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
+index bd81d79..2d3790f 100644
+--- a/tools/perf/util/hist.h
++++ b/tools/perf/util/hist.h
+@@ -115,7 +115,7 @@ void events_stats__inc(struct events_stats *stats, u32 type);
+ size_t events_stats__fprintf(struct events_stats *stats, FILE *fp);
+ size_t hists__fprintf(struct hists *self, bool show_header, int max_rows,
+-                    int max_cols, FILE *fp);
++                    int max_cols, float min_pcnt, FILE *fp);
+ int hist_entry__inc_addr_samples(struct hist_entry *self, int evidx, u64 addr);
+ int hist_entry__annotate(struct hist_entry *self, size_t privsize);
+@@ -195,6 +195,7 @@ int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel,
+ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
+                                 struct hist_browser_timer *hbt,
++                                float min_pcnt,
+                                 struct perf_session_env *env);
+ int script_browse(const char *script_opt);
+ #else
+@@ -202,6 +203,7 @@ static inline
+ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused,
+                                 const char *help __maybe_unused,
+                                 struct hist_browser_timer *hbt __maybe_unused,
++                                float min_pcnt __maybe_unused,
+                                 struct perf_session_env *env __maybe_unused)
+ {
+       return 0;
+@@ -229,12 +231,14 @@ static inline int script_browse(const char *script_opt __maybe_unused)
+ #ifdef GTK2_SUPPORT
+ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help,
+-                                struct hist_browser_timer *hbt __maybe_unused);
++                                struct hist_browser_timer *hbt __maybe_unused,
++                                float min_pcnt);
+ #else
+ static inline
+ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist __maybe_unused,
+                                 const char *help __maybe_unused,
+-                                struct hist_browser_timer *hbt __maybe_unused)
++                                struct hist_browser_timer *hbt __maybe_unused,
++                                float min_pcnt __maybe_unused)
+ {
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0380-perf-top-Add-percent-limit-option.patch b/patches.tizen/0380-perf-top-Add-percent-limit-option.patch
new file mode 100644 (file)
index 0000000..0a1c841
--- /dev/null
@@ -0,0 +1,148 @@
+From 3f135a55c4d13e895ad812e76c8b9e9848e6d763 Mon Sep 17 00:00:00 2001
+From: Namhyung Kim <namhyung.kim@lge.com>
+Date: Tue, 14 May 2013 11:09:05 +0900
+Subject: [PATCH 0380/1302] perf top: Add --percent-limit option
+
+The --percent-limit option is for not showing small overhead entries in
+the output.
+
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Acked-by: Pekka Enberg <penberg@kernel.org>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1368497347-9628-8-git-send-email-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Documentation/perf-top.txt |  4 ++++
+ tools/perf/builtin-top.c              | 17 +++++++++++++++--
+ tools/perf/ui/browsers/hists.c        | 16 ++++++++++++++--
+ tools/perf/util/top.h                 |  1 +
+ 4 files changed, 34 insertions(+), 4 deletions(-)
+
+diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt
+index 9f1a2fe54..7fdd190 100644
+--- a/tools/perf/Documentation/perf-top.txt
++++ b/tools/perf/Documentation/perf-top.txt
+@@ -155,6 +155,10 @@ Default is to monitor all CPUS.
+       Default: fractal,0.5,callee.
++--percent-limit::
++      Do not show entries which have an overhead under that percent.
++      (Default: 0).
++
+ INTERACTIVE PROMPTING KEYS
+ --------------------------
+diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
+index 19fe25f..f036af9 100644
+--- a/tools/perf/builtin-top.c
++++ b/tools/perf/builtin-top.c
+@@ -296,7 +296,8 @@ static void perf_top__print_sym_table(struct perf_top *top)
+                                    top->print_entries - printed);
+       putchar('\n');
+       hists__fprintf(&top->sym_evsel->hists, false,
+-                     top->print_entries - printed, win_width, 0, stdout);
++                     top->print_entries - printed, win_width,
++                     top->min_percent, stdout);
+ }
+ static void prompt_integer(int *target, const char *msg)
+@@ -580,7 +581,7 @@ static void *display_thread_tui(void *arg)
+       list_for_each_entry(pos, &top->evlist->entries, node)
+               pos->hists.uid_filter_str = top->record_opts.target.uid_str;
+-      perf_evlist__tui_browse_hists(top->evlist, help, &hbt, 0,
++      perf_evlist__tui_browse_hists(top->evlist, help, &hbt, top->min_percent,
+                                     &top->session->header.env);
+       done = 1;
+@@ -1021,6 +1022,16 @@ parse_callchain_opt(const struct option *opt, const char *arg, int unset)
+       return record_parse_callchain_opt(opt, arg, unset);
+ }
++static int
++parse_percent_limit(const struct option *opt, const char *arg,
++                  int unset __maybe_unused)
++{
++      struct perf_top *top = opt->value;
++
++      top->min_percent = strtof(arg, NULL);
++      return 0;
++}
++
+ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
+ {
+       int status;
+@@ -1106,6 +1117,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
+       OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style",
+                  "Specify disassembler style (e.g. -M intel for intel syntax)"),
+       OPT_STRING('u', "uid", &target->uid_str, "user", "user to profile"),
++      OPT_CALLBACK(0, "percent-limit", &top, "percent",
++                   "Don't show entries under that percent", parse_percent_limit),
+       OPT_END()
+       };
+       const char * const top_usage[] = {
+diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
+index 9dfde61..fc0bd38 100644
+--- a/tools/perf/ui/browsers/hists.c
++++ b/tools/perf/ui/browsers/hists.c
+@@ -310,6 +310,8 @@ static void ui_browser__warn_lost_events(struct ui_browser *browser)
+               "Or reduce the sampling frequency.");
+ }
++static void hist_browser__update_pcnt_entries(struct hist_browser *hb);
++
+ static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
+                            struct hist_browser_timer *hbt)
+ {
+@@ -333,9 +335,18 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
+               key = ui_browser__run(&browser->b, delay_secs);
+               switch (key) {
+-              case K_TIMER:
++              case K_TIMER: {
++                      u64 nr_entries;
+                       hbt->timer(hbt->arg);
+-                      ui_browser__update_nr_entries(&browser->b, browser->hists->nr_entries);
++
++                      if (browser->min_pcnt) {
++                              hist_browser__update_pcnt_entries(browser);
++                              nr_entries = browser->nr_pcnt_entries;
++                      } else {
++                              nr_entries = browser->hists->nr_entries;
++                      }
++
++                      ui_browser__update_nr_entries(&browser->b, nr_entries);
+                       if (browser->hists->stats.nr_lost_warned !=
+                           browser->hists->stats.nr_events[PERF_RECORD_LOST]) {
+@@ -347,6 +358,7 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
+                       hists__browser_title(browser->hists, title, sizeof(title), ev_name);
+                       ui_browser__show_title(&browser->b, title);
+                       continue;
++              }
+               case 'D': { /* Debug */
+                       static int seq;
+                       struct hist_entry *h = rb_entry(browser->b.top,
+diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h
+index f0a8625..df46be9 100644
+--- a/tools/perf/util/top.h
++++ b/tools/perf/util/top.h
+@@ -36,6 +36,7 @@ struct perf_top {
+       int                realtime_prio;
+       int                sym_pcnt_filter;
+       const char         *sym_filter;
++      float              min_percent;
+ };
+ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0381-perf-report-Add-report.percent-limit-config-variable.patch b/patches.tizen/0381-perf-report-Add-report.percent-limit-config-variable.patch
new file mode 100644 (file)
index 0000000..c642486
--- /dev/null
@@ -0,0 +1,58 @@
+From 4eb822588353c7fb151657b99875d3232f340f46 Mon Sep 17 00:00:00 2001
+From: Namhyung Kim <namhyung.kim@lge.com>
+Date: Tue, 14 May 2013 11:09:06 +0900
+Subject: [PATCH 0381/1302] perf report: Add report.percent-limit config
+ variable
+
+Now an user can set a default value of --percent-limit option into the
+perfconfig file.
+
+  $ cat ~/.perfconfig
+  [report]
+  percent-limit = 0.1
+
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Acked-by: Pekka Enberg <penberg@kernel.org>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Pekka Enberg <penberg@kernel.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1368497347-9628-9-git-send-email-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/builtin-report.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
+index 0a4979b..ca98d34 100644
+--- a/tools/perf/builtin-report.c
++++ b/tools/perf/builtin-report.c
+@@ -62,6 +62,11 @@ static int perf_report_config(const char *var, const char *value, void *cb)
+               symbol_conf.event_group = perf_config_bool(var, value);
+               return 0;
+       }
++      if (!strcmp(var, "report.percent-limit")) {
++              struct perf_report *rep = cb;
++              rep->min_percent = strtof(value, NULL);
++              return 0;
++      }
+       return perf_default_config(var, value, cb);
+ }
+@@ -823,7 +828,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
+       OPT_END()
+       };
+-      perf_config(perf_report_config, NULL);
++      perf_config(perf_report_config, &report);
+       argc = parse_options(argc, argv, options, report_usage, 0);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0382-perf-diff-Use-internal-rb-tree-for-hists__precompute.patch b/patches.tizen/0382-perf-diff-Use-internal-rb-tree-for-hists__precompute.patch
new file mode 100644 (file)
index 0000000..686bf59
--- /dev/null
@@ -0,0 +1,61 @@
+From 85717fe0ffaccf19d838a54ca127c361079add68 Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Thu, 13 Dec 2012 14:08:59 +0100
+Subject: [PATCH 0382/1302] perf diff: Use internal rb tree for
+ hists__precompute
+
+There's missing change for hists__precompute to iterate either
+entries_collapsed or entries_in tree. The change was initiated
+for hists_compute_resort function in commit:
+
+  66f97ed perf diff: Use internal rb tree for compute resort
+
+but was missing for hists__precompute function changes.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Link: http://lkml.kernel.org/r/1355404152-16523-2-git-send-email-jolsa@redhat.com
+[ committer note: Reduce patch size, no functional change ]
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/builtin-diff.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
+index a9d63c1..da8f8eb 100644
+--- a/tools/perf/builtin-diff.c
++++ b/tools/perf/builtin-diff.c
+@@ -323,13 +323,20 @@ static void hists__baseline_only(struct hists *hists)
+ static void hists__precompute(struct hists *hists)
+ {
+-      struct rb_node *next = rb_first(&hists->entries);
++      struct rb_root *root;
++      struct rb_node *next;
++
++      if (sort__need_collapse)
++              root = &hists->entries_collapsed;
++      else
++              root = hists->entries_in;
++      next = rb_first(root);
+       while (next != NULL) {
+-              struct hist_entry *he = rb_entry(next, struct hist_entry, rb_node);
++              struct hist_entry *he = rb_entry(next, struct hist_entry, rb_node_in);
+               struct hist_entry *pair = hist_entry__next_pair(he);
+-              next = rb_next(&he->rb_node);
++              next = rb_next(&he->rb_node_in);
+               if (!pair)
+                       continue;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0383-perf-hists-Rename-hist_entry__add_pair-arguments.patch b/patches.tizen/0383-perf-hists-Rename-hist_entry__add_pair-arguments.patch
new file mode 100644 (file)
index 0000000..53f7d46
--- /dev/null
@@ -0,0 +1,47 @@
+From be81cef05213009625c1e9dfa1fc4aac43d501b6 Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Thu, 13 Dec 2012 14:09:00 +0100
+Subject: [PATCH 0383/1302] perf hists: Rename hist_entry__add_pair arguments
+
+The current logic is to attach pair to the leader hist_entry.
+
+Arguments of hist_entry__add_pair function were placed the other way
+round.. driving me crazy.
+
+I.e. list_add_tail expects (new_node, head).
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Link: http://lkml.kernel.org/r/1355404152-16523-3-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/util/sort.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
+index 51f1b5a..45ac84c 100644
+--- a/tools/perf/util/sort.h
++++ b/tools/perf/util/sort.h
+@@ -117,10 +117,10 @@ static inline struct hist_entry *hist_entry__next_pair(struct hist_entry *he)
+       return NULL;
+ }
+-static inline void hist_entry__add_pair(struct hist_entry *he,
+-                                      struct hist_entry *pair)
++static inline void hist_entry__add_pair(struct hist_entry *pair,
++                                      struct hist_entry *he)
+ {
+-      list_add_tail(&he->pairs.head, &pair->pairs.node);
++      list_add_tail(&pair->pairs.node, &he->pairs.head);
+ }
+ enum sort_mode {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0384-perf-test-Fix-typo.patch b/patches.tizen/0384-perf-test-Fix-typo.patch
new file mode 100644 (file)
index 0000000..ece7acc
--- /dev/null
@@ -0,0 +1,37 @@
+From e9bde59790d0cd2f705c3bd98c89e4854dde79a9 Mon Sep 17 00:00:00 2001
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+Date: Thu, 23 May 2013 12:08:38 +0200
+Subject: [PATCH 0384/1302] perf test: Fix typo
+
+Its 'multiple', not 'mutliple', noticed while preparing a talk for
+Linuxtag'13.
+
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Mike Galbraith <efault@gmx.de>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/n/tip-dzy9nl1ku7a5umddvdic4ibl@git.kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/tests/builtin-test.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
+index 0918ada..35b45f1466 100644
+--- a/tools/perf/tests/builtin-test.c
++++ b/tools/perf/tests/builtin-test.c
+@@ -70,7 +70,7 @@ static struct test {
+               .func = test__attr,
+       },
+       {
+-              .desc = "Test matching and linking mutliple hists",
++              .desc = "Test matching and linking multiple hists",
+               .func = test__hists_link,
+       },
+       {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0385-perf-evsel-Fix-printing-of-perf_event_paranoid-messa.patch b/patches.tizen/0385-perf-evsel-Fix-printing-of-perf_event_paranoid-messa.patch
new file mode 100644 (file)
index 0000000..519f8d8
--- /dev/null
@@ -0,0 +1,43 @@
+From 2d6ee96ad06884ae2ca215e3b658c4dfbd91369b Mon Sep 17 00:00:00 2001
+From: David Ahern <dsahern@gmail.com>
+Date: Sat, 25 May 2013 17:54:00 -0600
+Subject: [PATCH 0385/1302] perf evsel: Fix printing of perf_event_paranoid
+ message
+
+message is currently shown as:
+
+  Error:
+  You may not have permission to collect %sstats.
+  Consider tweaking /proc/sys/kernel/perf_event_paranoid:
+
+Note the %sstats. With patch this becomes:
+
+  Error:
+  You may not have permission to collect stats.
+  Consider tweaking /proc/sys/kernel/perf_event_paranoid:
+
+Signed-off-by: David Ahern <dsahern@gmail.com>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Link: http://lkml.kernel.org/r/1369526040-1368-1-git-send-email-dsahern@gmail.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/util/evsel.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
+index 07b1a3a..63b6f8c 100644
+--- a/tools/perf/util/evsel.c
++++ b/tools/perf/util/evsel.c
+@@ -1514,7 +1514,7 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel,
+       switch (err) {
+       case EPERM:
+       case EACCES:
+-              return scnprintf(msg, size, "%s",
++              return scnprintf(msg, size,
+                "You may not have permission to collect %sstats.\n"
+                "Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n"
+                " -1 - Not paranoid at all\n"
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0386-perf-kvm-Handle-realloc-failures.patch b/patches.tizen/0386-perf-kvm-Handle-realloc-failures.patch
new file mode 100644 (file)
index 0000000..1e547ae
--- /dev/null
@@ -0,0 +1,49 @@
+From e316c2a99cb0e10fae216ab616559294142bc641 Mon Sep 17 00:00:00 2001
+From: David Ahern <dsahern@gmail.com>
+Date: Sat, 25 May 2013 18:24:46 -0600
+Subject: [PATCH 0386/1302] perf kvm: Handle realloc failures
+
+Save previous pointer and free on failure.
+
+Signed-off-by: David Ahern <dsahern@gmail.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Runzhen Wang <runzhen@linux.vnet.ibm.com>
+Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
+Link: http://lkml.kernel.org/r/1369527896-3650-7-git-send-email-dsahern@gmail.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/builtin-kvm.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
+index 533501e..24b78ae 100644
+--- a/tools/perf/builtin-kvm.c
++++ b/tools/perf/builtin-kvm.c
+@@ -328,6 +328,7 @@ static int kvm_events_hash_fn(u64 key)
+ static bool kvm_event_expand(struct kvm_event *event, int vcpu_id)
+ {
+       int old_max_vcpu = event->max_vcpu;
++      void *prev;
+       if (vcpu_id < event->max_vcpu)
+               return true;
+@@ -335,9 +336,11 @@ static bool kvm_event_expand(struct kvm_event *event, int vcpu_id)
+       while (event->max_vcpu <= vcpu_id)
+               event->max_vcpu += DEFAULT_VCPU_NUM;
++      prev = event->vcpu;
+       event->vcpu = realloc(event->vcpu,
+                             event->max_vcpu * sizeof(*event->vcpu));
+       if (!event->vcpu) {
++              free(prev);
+               pr_err("Not enough memory\n");
+               return false;
+       }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0387-perf-stats-Fix-divide-by-0-in-variance.patch b/patches.tizen/0387-perf-stats-Fix-divide-by-0-in-variance.patch
new file mode 100644 (file)
index 0000000..71b8f23
--- /dev/null
@@ -0,0 +1,40 @@
+From 5a1bf75048a47ec0330c77a9e6fd8553480a3ca1 Mon Sep 17 00:00:00 2001
+From: David Ahern <dsahern@gmail.com>
+Date: Sat, 25 May 2013 18:24:48 -0600
+Subject: [PATCH 0387/1302] perf stats: Fix divide by 0 in variance
+
+Number of samples needs to be greater 1 to have a variance.
+
+Fixes nan% in perf-kvm-live output.
+
+Signed-off-by: David Ahern <dsahern@gmail.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Runzhen Wang <runzhen@linux.vnet.ibm.com>
+Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
+Link: http://lkml.kernel.org/r/1369527896-3650-9-git-send-email-dsahern@gmail.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/util/stat.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
+index 2374212..7c59c28 100644
+--- a/tools/perf/util/stat.c
++++ b/tools/perf/util/stat.c
+@@ -37,7 +37,7 @@ double stddev_stats(struct stats *stats)
+ {
+       double variance, variance_mean;
+-      if (!stats->n)
++      if (stats->n < 2)
+               return 0.0;
+       variance = stats->M2 / (stats->n - 1);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0388-perf-tools-Save-parent-pid-in-thread-struct.patch b/patches.tizen/0388-perf-tools-Save-parent-pid-in-thread-struct.patch
new file mode 100644 (file)
index 0000000..1d2a100
--- /dev/null
@@ -0,0 +1,59 @@
+From 94e048e1e7c0100d229793e0c34bb42ec18d4d9a Mon Sep 17 00:00:00 2001
+From: David Ahern <dsahern@gmail.com>
+Date: Sat, 25 May 2013 22:47:10 -0600
+Subject: [PATCH 0388/1302] perf  tools: Save parent pid in thread struct
+
+Information is available, so why not save it in case some command wants
+to use it.
+
+Signed-off-by: David Ahern <dsahern@gmail.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369543631-5106-1-git-send-email-dsahern@gmail.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/util/thread.c | 4 ++++
+ tools/perf/util/thread.h | 1 +
+ 2 files changed, 5 insertions(+)
+
+diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
+index 632e40e..40399cb 100644
+--- a/tools/perf/util/thread.c
++++ b/tools/perf/util/thread.c
+@@ -14,6 +14,7 @@ struct thread *thread__new(pid_t pid)
+       if (self != NULL) {
+               map_groups__init(&self->mg);
+               self->pid = pid;
++              self->ppid = -1;
+               self->comm = malloc(32);
+               if (self->comm)
+                       snprintf(self->comm, 32, ":%d", self->pid);
+@@ -82,5 +83,8 @@ int thread__fork(struct thread *self, struct thread *parent)
+       for (i = 0; i < MAP__NR_TYPES; ++i)
+               if (map_groups__clone(&self->mg, &parent->mg, i) < 0)
+                       return -ENOMEM;
++
++      self->ppid = parent->pid;
++
+       return 0;
+ }
+diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
+index 5ad2664..eeb7ac6 100644
+--- a/tools/perf/util/thread.h
++++ b/tools/perf/util/thread.h
+@@ -13,6 +13,7 @@ struct thread {
+       };
+       struct map_groups       mg;
+       pid_t                   pid;
++      pid_t                   ppid;
+       char                    shortname[3];
+       bool                    comm_set;
+       char                    *comm;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0389-perf-tools-Add-automated-make-test-suite.patch b/patches.tizen/0389-perf-tools-Add-automated-make-test-suite.patch
new file mode 100644 (file)
index 0000000..30c5332
--- /dev/null
@@ -0,0 +1,203 @@
+From ae4c6bc77dd6195b060d53ded22d967a217bb39f Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Fri, 29 Mar 2013 16:11:02 +0100
+Subject: [PATCH 0389/1302] perf tools: Add automated make test suite
+
+Adding automated test for testing the build process.
+
+To run it you need to be in perf directory or specify one with PERF
+variable. It's also possible to specify optional Makefile to test via MK
+variable.
+
+Whole suite is executed twice, the second time with O=/tmp/xxx option
+added.
+
+To run the whole suite:
+  $ make -f tests/make
+  - make_pure: cd . && make -f Makefile
+    test: test -x ./perf
+  - make_clean_all: cd . && make -f Makefile clean all
+    test: test -x ./perf
+  - make_python_perf_so: cd . && make -f Makefile python/perf.so
+    test: test -f ./python/perf.so
+  - make_debug: cd . && make -f Makefile DEBUG=1
+    test: test -x ./perf
+  - make_no_libperl: cd . && make -f Makefile NO_LIBPERL=1
+    test: test -x ./perf
+
+You see command line for 'make_pure' test right away, and the output is
+stored into 'make_pure' file.
+
+To run simple test:
+  $ make -f tests/make make_debug
+  - make_debug: cd . && make -f Makefile DEBUG=1
+    test: test -x ./perf
+
+At this moment tests checks for successfull build and for existence of
+several built files. Additional after-build checks could be added.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369398928-9809-2-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/tests/make | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 138 insertions(+)
+ create mode 100644 tools/perf/tests/make
+
+diff --git a/tools/perf/tests/make b/tools/perf/tests/make
+new file mode 100644
+index 0000000..c441a28
+--- /dev/null
++++ b/tools/perf/tests/make
+@@ -0,0 +1,138 @@
++PERF := .
++MK   := Makefile
++
++# standard single make variable specified
++make_clean_all      := clean all
++make_python_perf_so := python/perf.so
++make_debug          := DEBUG=1
++make_no_libperl     := NO_LIBPERL=1
++make_no_libpython   := NO_LIBPYTHON=1
++make_no_scripts     := NO_LIBPYTHON=1 NO_LIBPERL=1
++make_no_newt        := NO_NEWT=1
++make_no_slang       := NO_SLANG=1
++make_no_gtk2        := NO_GTK2=1
++make_no_ui          := NO_NEWT=1 NO_SLANG=1 NO_GTK2=1
++make_no_demangle    := NO_DEMANGLE=1
++make_no_libelf      := NO_LIBELF=1
++make_no_libunwind   := NO_LIBUNWIND=1
++make_no_backtrace   := NO_BACKTRACE=1
++make_no_libnuma     := NO_LIBNUMA=1
++make_no_libaudit    := NO_LIBAUDIT=1
++make_no_libbionic   := NO_LIBBIONIC=1
++make_tags           := tags
++make_cscope         := cscope
++make_help           := help
++make_doc            := doc
++make_perf_o         := perf.o
++make_util_map_o     := util/map.o
++
++# all the NO_* variable combined
++make_minimal        := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1
++make_minimal        += NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1
++make_minimal        += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1
++
++# $(run) contains all available tests
++run := make_pure
++run += make_clean_all
++run += make_python_perf_so
++run += make_debug
++run += make_no_libperl
++run += make_no_libpython
++run += make_no_scripts
++run += make_no_newt
++run += make_no_slang
++run += make_no_gtk2
++run += make_no_ui
++run += make_no_demangle
++run += make_no_libelf
++run += make_no_libunwind
++run += make_no_backtrace
++run += make_no_libnuma
++run += make_no_libaudit
++run += make_no_libbionic
++run += make_tags
++run += make_cscope
++run += make_help
++run += make_doc
++run += make_perf_o
++run += make_util_map_o
++run += make_minimal
++
++# $(run_O) contains same portion of $(run) tests with '_O' attached
++# to distinguish O=... tests
++run_O := $(addsuffix _O,$(run))
++
++# disable some tests for O=...
++run_O := $(filter-out make_python_perf_so_O,$(run_O))
++
++# define test for each compile as 'test_NAME' variable
++# with the test itself as a value
++test_make_tags   = test -f tags
++test_make_cscope = test -f cscope.out
++
++test_make_tags_O   := $(test_make_tags)
++test_make_cscope_O := $(test_make_cscope)
++
++test_ok          := true
++test_make_help   := $(test_ok)
++test_make_doc    := $(test_ok)
++test_make_help_O := $(test_ok)
++test_make_doc_O  := $(test_ok)
++
++test_make_python_perf_so := test -f $(PERF)/python/perf.so
++
++test_make_perf_o     := test -f $(PERF)/perf.o
++test_make_util_map_o := test -f $(PERF)/util/map.o
++
++# Kbuild tests only
++#test_make_python_perf_so_O := test -f $$TMP/tools/perf/python/perf.so
++#test_make_perf_o_O         := test -f $$TMP/tools/perf/perf.o
++#test_make_util_map_o_O     := test -f $$TMP/tools/perf/util/map.o
++
++test_make_perf_o_O     := true
++test_make_util_map_o_O := true
++
++test_default = test -x $(PERF)/perf
++test = $(if $(test_$1),$(test_$1),$(test_default))
++
++test_default_O = test -x $$TMP/perf
++test_O = $(if $(test_$1),$(test_$1),$(test_default_O))
++
++all:
++
++ifdef DEBUG
++d := $(info run   $(run))
++d := $(info run_O $(run_O))
++endif
++
++MAKEFLAGS := --no-print-directory
++
++clean := @(cd $(PERF); make -s -f $(MK) clean >/dev/null)
++
++$(run):
++      $(call clean)
++      @cmd="cd $(PERF) && make -f $(MK) $($@)"; \
++      echo "- $@: $$cmd" && echo $$cmd > $@ && \
++      ( eval $$cmd ) >> $@ 2>&1; \
++      echo "  test: $(call test,$@)"; \
++      $(call test,$@) && \
++      rm -f $@
++
++$(run_O):
++      $(call clean)
++      @TMP=$$(mktemp -d); \
++      cmd="cd $(PERF) && make -f $(MK) $($(patsubst %_O,%,$@)) O=$$TMP"; \
++      echo "- $@: $$cmd" && echo $$cmd > $@ && \
++      ( eval $$cmd ) >> $@ 2>&1 && \
++      echo "  test: $(call test_O,$@)"; \
++      $(call test_O,$@) && \
++      rm -f $@ && \
++      rm -rf $$TMP
++
++all: $(run) $(run_O)
++      @echo OK
++
++out: $(run_O)
++      @echo OK
++
++.PHONY: all $(run) $(run_O) clean
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0390-perf-tools-Move-arch-check-into-config-Makefile.patch b/patches.tizen/0390-perf-tools-Move-arch-check-into-config-Makefile.patch
new file mode 100644 (file)
index 0000000..733fb1c
--- /dev/null
@@ -0,0 +1,141 @@
+From 5efcb7ace067db78ca3bd3fc6304aff53d6aab00 Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Fri, 15 Mar 2013 16:28:49 +0100
+Subject: [PATCH 0390/1302] perf tools: Move arch check into config/Makefile
+
+Moving arch check into config/Makefile.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369398928-9809-3-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Makefile        | 43 ++++++++++++++-----------------------------
+ tools/perf/config/Makefile | 34 ++++++++++++++++++++++++++++++++++
+ 2 files changed, 48 insertions(+), 29 deletions(-)
+ create mode 100644 tools/perf/config/Makefile
+
+diff --git a/tools/perf/Makefile b/tools/perf/Makefile
+index c8fb0fd..a4abdaf 100644
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -55,37 +55,23 @@ include config/utilities.mak
+ $(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
+       @$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
+-uname_M := $(shell uname -m 2>/dev/null || echo not)
+-
+-ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
+-                                -e s/arm.*/arm/ -e s/sa110/arm/ \
+-                                -e s/s390x/s390/ -e s/parisc64/parisc/ \
+-                                -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
+-                                -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ )
+-NO_PERF_REGS := 1
+-
+ CC = $(CROSS_COMPILE)gcc
+ AR = $(CROSS_COMPILE)ar
+-# Additional ARCH settings for x86
+-ifeq ($(ARCH),i386)
+-      override ARCH := x86
+-      NO_PERF_REGS := 0
+-      LIBUNWIND_LIBS = -lunwind -lunwind-x86
++# include config/Makefile by default and rule out
++# non-config cases
++config := 1
++
++NON_CONFIG_TARGETS := clean TAGS tags cscope help
++
++ifdef MAKECMDGOALS
++ifeq ($(filter-out $(NON_CONFIG_TARGETS),$(MAKECMDGOALS)),)
++  config := 0
+ endif
+-ifeq ($(ARCH),x86_64)
+-      override ARCH := x86
+-      IS_X86_64 := 0
+-      ifeq (, $(findstring m32,$(EXTRA_CFLAGS)))
+-              IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -x c - | tail -n 1)
+-      endif
+-      ifeq (${IS_X86_64}, 1)
+-              RAW_ARCH := x86_64
+-              ARCH_CFLAGS := -DARCH_X86_64
+-              ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S
+-      endif
+-      NO_PERF_REGS := 0
+-      LIBUNWIND_LIBS = -lunwind -lunwind-x86_64
++endif
++
++ifeq ($(config),1)
++include config/Makefile
+ endif
+ # Treat warnings as errors unless directed not to
+@@ -208,7 +194,7 @@ ifneq ($(OUTPUT),)
+ #$(info Determined 'OUTPUT' to be $(OUTPUT))
+ endif
+-BASIC_CFLAGS = \
++BASIC_CFLAGS += \
+       -Iutil/include \
+       -Iarch/$(ARCH)/include \
+       $(if $(objtree),-I$(objtree)/arch/$(ARCH)/include/generated/uapi) \
+@@ -857,7 +843,6 @@ ifeq ($(NO_PERF_REGS),0)
+       ifeq ($(ARCH),x86)
+               LIB_H += arch/x86/include/perf_regs.h
+       endif
+-      BASIC_CFLAGS += -DHAVE_PERF_REGS
+ endif
+ ifndef NO_STRLCPY
+diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
+new file mode 100644
+index 0000000..fe317c2
+--- /dev/null
++++ b/tools/perf/config/Makefile
+@@ -0,0 +1,34 @@
++uname_M := $(shell uname -m 2>/dev/null || echo not)
++
++ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
++                                -e s/arm.*/arm/ -e s/sa110/arm/ \
++                                -e s/s390x/s390/ -e s/parisc64/parisc/ \
++                                -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
++                                -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ )
++NO_PERF_REGS := 1
++
++# Additional ARCH settings for x86
++ifeq ($(ARCH),i386)
++      override ARCH := x86
++      NO_PERF_REGS := 0
++      LIBUNWIND_LIBS = -lunwind -lunwind-x86
++endif
++
++ifeq ($(ARCH),x86_64)
++      override ARCH := x86
++      IS_X86_64 := 0
++      ifeq (, $(findstring m32,$(EXTRA_CFLAGS)))
++              IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -x c - | tail -n 1)
++      endif
++      ifeq (${IS_X86_64}, 1)
++              RAW_ARCH := x86_64
++              ARCH_CFLAGS := -DARCH_X86_64
++              ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S
++      endif
++      NO_PERF_REGS := 0
++      LIBUNWIND_LIBS = -lunwind -lunwind-x86_64
++endif
++
++ifeq ($(NO_PERF_REGS),0)
++        BASIC_CFLAGS += -DHAVE_PERF_REGS
++endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0391-perf-tools-Move-programs-check-into-config-Makefile.patch b/patches.tizen/0391-perf-tools-Move-programs-check-into-config-Makefile.patch
new file mode 100644 (file)
index 0000000..56444b3
--- /dev/null
@@ -0,0 +1,103 @@
+From f8966e1fe511405df6c4d7a830246ab232ba1a80 Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Mon, 25 Mar 2013 00:32:01 +0100
+Subject: [PATCH 0391/1302] perf tools: Move programs check into
+ config/Makefile
+
+Moving programs check into config/Makefile.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369398928-9809-4-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Makefile        | 24 ++++++++----------------
+ tools/perf/config/Makefile | 10 ++++++++++
+ 2 files changed, 18 insertions(+), 16 deletions(-)
+
+diff --git a/tools/perf/Makefile b/tools/perf/Makefile
+index a4abdaf..2a75476 100644
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -58,6 +58,14 @@ $(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
+ CC = $(CROSS_COMPILE)gcc
+ AR = $(CROSS_COMPILE)ar
++RM      = rm -f
++MKDIR   = mkdir
++FIND    = find
++INSTALL = install
++FLEX    = flex
++BISON   = bison
++STRIP  ?= strip
++
+ # include config/Makefile by default and rule out
+ # non-config cases
+ config := 1
+@@ -100,7 +108,6 @@ CFLAGS = -fno-omit-frame-pointer -ggdb3 -funwind-tables -Wall -Wextra -std=gnu99
+ EXTLIBS = -lpthread -lrt -lelf -lm
+ ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
+ ALL_LDFLAGS = $(LDFLAGS)
+-STRIP ?= strip
+ # Among the variables below, these:
+ #   perfexecdir
+@@ -137,13 +144,6 @@ lib = lib
+ export prefix bindir sharedir sysconfdir
+-RM = rm -f
+-MKDIR = mkdir
+-FIND = find
+-INSTALL = install
+-FLEX = flex
+-BISON= bison
+-
+ # sparse is architecture-neutral, which means that we need to tell it
+ # explicitly what architecture to check for. Fix this up for yours..
+ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
+@@ -152,14 +152,6 @@ ifneq ($(MAKECMDGOALS),clean)
+ ifneq ($(MAKECMDGOALS),tags)
+ -include config/feature-tests.mak
+-ifeq ($(call get-executable,$(FLEX)),)
+-      dummy := $(error Error: $(FLEX) is missing on this system, please install it)
+-endif
+-
+-ifeq ($(call get-executable,$(BISON)),)
+-      dummy := $(error Error: $(BISON) is missing on this system, please install it)
+-endif
+-
+ ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y)
+       CFLAGS := $(CFLAGS) -fstack-protector-all
+ endif
+diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
+index fe317c2..04bf8ac 100644
+--- a/tools/perf/config/Makefile
++++ b/tools/perf/config/Makefile
+@@ -32,3 +32,13 @@ endif
+ ifeq ($(NO_PERF_REGS),0)
+         BASIC_CFLAGS += -DHAVE_PERF_REGS
+ endif
++
++-include config/feature-tests.mak
++
++ifeq ($(call get-executable,$(FLEX)),)
++      dummy := $(error Error: $(FLEX) is missing on this system, please install it)
++endif
++
++ifeq ($(call get-executable,$(BISON)),)
++      dummy := $(error Error: $(BISON) is missing on this system, please install it)
++endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0392-perf-tools-Move-compiler-and-linker-flags-check-into.patch b/patches.tizen/0392-perf-tools-Move-compiler-and-linker-flags-check-into.patch
new file mode 100644 (file)
index 0000000..1b25db4
--- /dev/null
@@ -0,0 +1,263 @@
+From af9c434e147677607bfa3349c8f5f4b60267557b Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Mon, 25 Mar 2013 00:40:48 +0100
+Subject: [PATCH 0392/1302] perf tools: Move compiler and linker flags check
+ into config/Makefile
+
+Moving compiler and linker flags check into config/Makefile.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369398928-9809-5-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Makefile        | 110 ++++++++-------------------------------------
+ tools/perf/config/Makefile |  66 +++++++++++++++++++++++++++
+ 2 files changed, 85 insertions(+), 91 deletions(-)
+
+diff --git a/tools/perf/Makefile b/tools/perf/Makefile
+index 2a75476..aa6f933 100644
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -52,6 +52,20 @@ include config/utilities.mak
+ #
+ # Define NO_LIBNUMA if you do not want numa perf benchmark
++ifeq ($(srctree),)
++srctree := $(patsubst %/,%,$(dir $(shell pwd)))
++srctree := $(patsubst %/,%,$(dir $(srctree)))
++#$(info Determined 'srctree' to be $(srctree))
++endif
++
++ifneq ($(objtree),)
++#$(info Determined 'objtree' to be $(objtree))
++endif
++
++ifneq ($(OUTPUT),)
++#$(info Determined 'OUTPUT' to be $(OUTPUT))
++endif
++
+ $(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
+       @$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
+@@ -66,6 +80,9 @@ FLEX    = flex
+ BISON   = bison
+ STRIP  ?= strip
++LK_DIR = ../lib/lk/
++TRACE_EVENT_DIR = ../lib/traceevent/
++
+ # include config/Makefile by default and rule out
+ # non-config cases
+ config := 1
+@@ -82,33 +99,10 @@ ifeq ($(config),1)
+ include config/Makefile
+ endif
+-# Treat warnings as errors unless directed not to
+-ifneq ($(WERROR),0)
+-  CFLAGS_WERROR := -Werror
+-endif
+-
+-ifeq ("$(origin DEBUG)", "command line")
+-  PERF_DEBUG = $(DEBUG)
+-endif
+-ifndef PERF_DEBUG
+-  CFLAGS_OPTIMIZE = -O6
+-endif
+-
+-ifdef PARSER_DEBUG
+-      PARSER_DEBUG_BISON  := -t
+-      PARSER_DEBUG_FLEX   := -d
+-      PARSER_DEBUG_CFLAGS := -DPARSER_DEBUG
+-endif
+-
+ ifdef NO_NEWT
+       NO_SLANG=1
+ endif
+-CFLAGS = -fno-omit-frame-pointer -ggdb3 -funwind-tables -Wall -Wextra -std=gnu99 $(CFLAGS_WERROR) $(CFLAGS_OPTIMIZE) $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) $(PARSER_DEBUG_CFLAGS)
+-EXTLIBS = -lpthread -lrt -lelf -lm
+-ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
+-ALL_LDFLAGS = $(LDFLAGS)
+-
+ # Among the variables below, these:
+ #   perfexecdir
+ #   template_dir
+@@ -148,71 +142,6 @@ export prefix bindir sharedir sysconfdir
+ # explicitly what architecture to check for. Fix this up for yours..
+ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
+-ifneq ($(MAKECMDGOALS),clean)
+-ifneq ($(MAKECMDGOALS),tags)
+--include config/feature-tests.mak
+-
+-ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y)
+-      CFLAGS := $(CFLAGS) -fstack-protector-all
+-endif
+-
+-ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wstack-protector,-Wstack-protector),y)
+-       CFLAGS := $(CFLAGS) -Wstack-protector
+-endif
+-
+-ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wvolatile-register-var,-Wvolatile-register-var),y)
+-       CFLAGS := $(CFLAGS) -Wvolatile-register-var
+-endif
+-
+-ifndef PERF_DEBUG
+-      ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -D_FORTIFY_SOURCE=2,-D_FORTIFY_SOURCE=2),y)
+-              CFLAGS := $(CFLAGS) -D_FORTIFY_SOURCE=2
+-      endif
+-endif
+-
+-### --- END CONFIGURATION SECTION ---
+-
+-ifeq ($(srctree),)
+-srctree := $(patsubst %/,%,$(dir $(shell pwd)))
+-srctree := $(patsubst %/,%,$(dir $(srctree)))
+-#$(info Determined 'srctree' to be $(srctree))
+-endif
+-
+-ifneq ($(objtree),)
+-#$(info Determined 'objtree' to be $(objtree))
+-endif
+-
+-ifneq ($(OUTPUT),)
+-#$(info Determined 'OUTPUT' to be $(OUTPUT))
+-endif
+-
+-BASIC_CFLAGS += \
+-      -Iutil/include \
+-      -Iarch/$(ARCH)/include \
+-      $(if $(objtree),-I$(objtree)/arch/$(ARCH)/include/generated/uapi) \
+-      -I$(srctree)/arch/$(ARCH)/include/uapi \
+-      -I$(srctree)/arch/$(ARCH)/include \
+-      $(if $(objtree),-I$(objtree)/include/generated/uapi) \
+-      -I$(srctree)/include/uapi \
+-      -I$(srctree)/include \
+-      -I$(OUTPUT)util \
+-      -Iutil \
+-      -I. \
+-      -I$(TRACE_EVENT_DIR) \
+-      -I../lib/ \
+-      -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
+-
+-BASIC_LDFLAGS =
+-
+-ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS),bionic),y)
+-      BIONIC := 1
+-      EXTLIBS := $(filter-out -lrt,$(EXTLIBS))
+-      EXTLIBS := $(filter-out -lpthread,$(EXTLIBS))
+-      BASIC_CFLAGS += -I.
+-endif
+-endif # MAKECMDGOALS != tags
+-endif # MAKECMDGOALS != clean
+-
+ # Guard against environment variables
+ BUILTIN_OBJS =
+ LIB_H =
+@@ -225,9 +154,6 @@ SCRIPT_SH += perf-archive.sh
+ grep-libs = $(filter -l%,$(1))
+ strip-libs = $(filter-out -l%,$(1))
+-LK_DIR = ../lib/lk/
+-TRACE_EVENT_DIR = ../lib/traceevent/
+-
+ LK_PATH=$(LK_DIR)
+ ifneq ($(OUTPUT),)
+@@ -541,6 +467,8 @@ PERFLIBS = $(LIB_FILE) $(LIBLK) $(LIBTRACEEVENT)
+ ifneq ($(MAKECMDGOALS),clean)
+ ifneq ($(MAKECMDGOALS),tags)
++-include config/feature-tests.mak
++
+ # We choose to avoid "if .. else if .. else .. endif endif"
+ # because maintaining the nesting to match is a pain.  If
+ # we had "elif" things would have been much nicer...
+diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
+index 04bf8ac..8acbcfe 100644
+--- a/tools/perf/config/Makefile
++++ b/tools/perf/config/Makefile
+@@ -42,3 +42,69 @@ endif
+ ifeq ($(call get-executable,$(BISON)),)
+       dummy := $(error Error: $(BISON) is missing on this system, please install it)
+ endif
++
++# Treat warnings as errors unless directed not to
++ifneq ($(WERROR),0)
++      CFLAGS_WERROR := -Werror
++endif
++
++ifeq ("$(origin DEBUG)", "command line")
++      PERF_DEBUG = $(DEBUG)
++endif
++ifndef PERF_DEBUG
++      CFLAGS_OPTIMIZE = -O6
++endif
++
++ifdef PARSER_DEBUG
++      PARSER_DEBUG_BISON  := -t
++      PARSER_DEBUG_FLEX   := -d
++      PARSER_DEBUG_CFLAGS := -DPARSER_DEBUG
++endif
++
++CFLAGS = -fno-omit-frame-pointer -ggdb3 -funwind-tables -Wall -Wextra -std=gnu99 $(CFLAGS_WERROR) $(CFLAGS_OPTIMIZE) $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) $(PARSER_DEBUG_CFLAGS)
++EXTLIBS = -lpthread -lrt -lelf -lm
++ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
++ALL_LDFLAGS = $(LDFLAGS)
++
++ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y)
++      CFLAGS := $(CFLAGS) -fstack-protector-all
++endif
++
++ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wstack-protector,-Wstack-protector),y)
++      CFLAGS := $(CFLAGS) -Wstack-protector
++endif
++
++ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wvolatile-register-var,-Wvolatile-register-var),y)
++      CFLAGS := $(CFLAGS) -Wvolatile-register-var
++endif
++
++ifndef PERF_DEBUG
++      ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -D_FORTIFY_SOURCE=2,-D_FORTIFY_SOURCE=2),y)
++              CFLAGS := $(CFLAGS) -D_FORTIFY_SOURCE=2
++      endif
++endif
++
++BASIC_CFLAGS += \
++      -Iutil/include \
++      -Iarch/$(ARCH)/include \
++      $(if $(objtree),-I$(objtree)/arch/$(ARCH)/include/generated/uapi) \
++      -I$(srctree)/arch/$(ARCH)/include/uapi \
++      -I$(srctree)/arch/$(ARCH)/include \
++      $(if $(objtree),-I$(objtree)/include/generated/uapi) \
++      -I$(srctree)/include/uapi \
++      -I$(srctree)/include \
++      -I$(OUTPUT)util \
++      -Iutil \
++      -I. \
++      -I$(TRACE_EVENT_DIR) \
++      -I../lib/ \
++      -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
++
++BASIC_LDFLAGS =
++
++ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS),bionic),y)
++      BIONIC := 1
++      EXTLIBS := $(filter-out -lrt,$(EXTLIBS))
++      EXTLIBS := $(filter-out -lpthread,$(EXTLIBS))
++      BASIC_CFLAGS += -I.
++endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0393-perf-tools-Move-libelf-check-config-into-config-Make.patch b/patches.tizen/0393-perf-tools-Move-libelf-check-config-into-config-Make.patch
new file mode 100644 (file)
index 0000000..1aaf86e
--- /dev/null
@@ -0,0 +1,148 @@
+From 6200c9c382391d590b25ac79c5d2783fe222b54b Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Mon, 25 Mar 2013 00:45:08 +0100
+Subject: [PATCH 0393/1302] perf tools: Move libelf check config into
+ config/Makefile
+
+Moving libelf check config into config/Makefile.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369398928-9809-6-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Makefile        | 46 ---------------------------------------------
+ tools/perf/config/Makefile | 47 ++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 47 insertions(+), 46 deletions(-)
+
+diff --git a/tools/perf/Makefile b/tools/perf/Makefile
+index aa6f933..a174c68 100644
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -473,45 +473,6 @@ ifneq ($(MAKECMDGOALS),tags)
+ # because maintaining the nesting to match is a pain.  If
+ # we had "elif" things would have been much nicer...
+-ifdef NO_LIBELF
+-      NO_DWARF := 1
+-      NO_DEMANGLE := 1
+-      NO_LIBUNWIND := 1
+-else
+-FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
+-ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF),libelf),y)
+-      FLAGS_GLIBC=$(ALL_CFLAGS) $(ALL_LDFLAGS)
+-      ifeq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC),glibc),y)
+-              LIBC_SUPPORT := 1
+-      endif
+-      ifeq ($(BIONIC),1)
+-              LIBC_SUPPORT := 1
+-      endif
+-      ifeq ($(LIBC_SUPPORT),1)
+-              msg := $(warning No libelf found, disables 'probe' tool, please install elfutils-libelf-devel/libelf-dev);
+-
+-              NO_LIBELF := 1
+-              NO_DWARF := 1
+-              NO_DEMANGLE := 1
+-      else
+-              msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
+-      endif
+-else
+-      # for linking with debug library, run like:
+-      # make DEBUG=1 LIBDW_DIR=/opt/libdw/
+-      ifdef LIBDW_DIR
+-              LIBDW_CFLAGS  := -I$(LIBDW_DIR)/include
+-              LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib
+-      endif
+-
+-      FLAGS_DWARF=$(ALL_CFLAGS) $(LIBDW_CFLAGS) -ldw -lelf $(LIBDW_LDFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
+-      ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF),libdw),y)
+-              msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
+-              NO_DWARF := 1
+-      endif # Dwarf support
+-endif # SOURCE_LIBELF
+-endif # NO_LIBELF
+-
+ # There's only x86 (both 32 and 64) support for CFI unwind so far
+ ifneq ($(ARCH),x86)
+       NO_LIBUNWIND := 1
+@@ -553,13 +514,6 @@ BUILTIN_OBJS := $(filter-out $(OUTPUT)builtin-probe.o,$(BUILTIN_OBJS))
+ LIB_OBJS += $(OUTPUT)util/symbol-minimal.o
+ else # NO_LIBELF
+-BASIC_CFLAGS += -DLIBELF_SUPPORT
+-
+-FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
+-ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
+-      BASIC_CFLAGS += -DLIBELF_MMAP
+-endif
+-
+ ifndef NO_DWARF
+ ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
+       msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled);
+diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
+index 8acbcfe..17614b1 100644
+--- a/tools/perf/config/Makefile
++++ b/tools/perf/config/Makefile
+@@ -108,3 +108,50 @@ ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS),bionic),y)
+       EXTLIBS := $(filter-out -lpthread,$(EXTLIBS))
+       BASIC_CFLAGS += -I.
+ endif
++
++ifdef NO_LIBELF
++      NO_DWARF := 1
++      NO_DEMANGLE := 1
++      NO_LIBUNWIND := 1
++else
++FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
++ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF),libelf),y)
++      FLAGS_GLIBC=$(ALL_CFLAGS) $(ALL_LDFLAGS)
++      ifeq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC),glibc),y)
++              LIBC_SUPPORT := 1
++      endif
++      ifeq ($(BIONIC),1)
++              LIBC_SUPPORT := 1
++      endif
++      ifeq ($(LIBC_SUPPORT),1)
++              msg := $(warning No libelf found, disables 'probe' tool, please install elfutils-libelf-devel/libelf-dev);
++
++              NO_LIBELF := 1
++              NO_DWARF := 1
++              NO_DEMANGLE := 1
++      else
++              msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
++      endif
++else
++      # for linking with debug library, run like:
++      # make DEBUG=1 LIBDW_DIR=/opt/libdw/
++      ifdef LIBDW_DIR
++              LIBDW_CFLAGS  := -I$(LIBDW_DIR)/include
++              LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib
++      endif
++
++      FLAGS_DWARF=$(ALL_CFLAGS) $(LIBDW_CFLAGS) -ldw -lelf $(LIBDW_LDFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
++      ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF),libdw),y)
++              msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
++              NO_DWARF := 1
++      endif # Dwarf support
++endif # SOURCE_LIBELF
++endif # NO_LIBELF
++
++ifndef NO_LIBELF
++BASIC_CFLAGS += -DLIBELF_SUPPORT
++FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
++ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
++      BASIC_CFLAGS += -DLIBELF_MMAP
++endif
++endif # NO_LIBELF
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0394-perf-tools-Move-libdw-check-config-into-config-Makef.patch b/patches.tizen/0394-perf-tools-Move-libdw-check-config-into-config-Makef.patch
new file mode 100644 (file)
index 0000000..4e0d00c
--- /dev/null
@@ -0,0 +1,73 @@
+From fffd1e59e047c73928a3a96699007598a0ce5729 Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Mon, 25 Mar 2013 00:48:14 +0100
+Subject: [PATCH 0394/1302] perf tools: Move libdw check config into
+ config/Makefile
+
+Moving libdw check config into config/Makefile.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369398928-9809-7-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Makefile        |  7 -------
+ tools/perf/config/Makefile | 15 +++++++++++++++
+ 2 files changed, 15 insertions(+), 7 deletions(-)
+
+diff --git a/tools/perf/Makefile b/tools/perf/Makefile
+index a174c68..51fac31 100644
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -515,15 +515,8 @@ LIB_OBJS += $(OUTPUT)util/symbol-minimal.o
+ else # NO_LIBELF
+ ifndef NO_DWARF
+-ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
+-      msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled);
+-else
+-      BASIC_CFLAGS := -DDWARF_SUPPORT $(LIBDW_CFLAGS) $(BASIC_CFLAGS)
+-      BASIC_LDFLAGS := $(LIBDW_LDFLAGS) $(BASIC_LDFLAGS)
+-      EXTLIBS += -lelf -ldw
+       LIB_OBJS += $(OUTPUT)util/probe-finder.o
+       LIB_OBJS += $(OUTPUT)util/dwarf-aux.o
+-endif # PERF_HAVE_DWARF_REGS
+ endif # NO_DWARF
+ endif # NO_LIBELF
+diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
+index 17614b1..71e737c 100644
+--- a/tools/perf/config/Makefile
++++ b/tools/perf/config/Makefile
+@@ -154,4 +154,19 @@ FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
+ ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
+       BASIC_CFLAGS += -DLIBELF_MMAP
+ endif
++
++# include ARCH specific config
++-include arch/$(ARCH)/Makefile
++
++ifndef NO_DWARF
++ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
++      msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled);
++      NO_DWARF := 1
++else
++      BASIC_CFLAGS := -DDWARF_SUPPORT $(LIBDW_CFLAGS) $(BASIC_CFLAGS)
++      BASIC_LDFLAGS := $(LIBDW_LDFLAGS) $(BASIC_LDFLAGS)
++      EXTLIBS += -lelf -ldw
++endif # PERF_HAVE_DWARF_REGS
++endif # NO_DWARF
++
+ endif # NO_LIBELF
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0395-perf-tools-Move-libunwind-check-config-into-config-M.patch b/patches.tizen/0395-perf-tools-Move-libunwind-check-config-into-config-M.patch
new file mode 100644 (file)
index 0000000..fa19d74
--- /dev/null
@@ -0,0 +1,106 @@
+From b1968f743682082a682d005d9c5430011baa4bc5 Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Mon, 25 Mar 2013 00:53:03 +0100
+Subject: [PATCH 0395/1302] perf tools: Move libunwind check config into
+ config/Makefile
+
+Moving libunwind check config into config/Makefile.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369398928-9809-8-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Makefile        | 24 ------------------------
+ tools/perf/config/Makefile | 27 +++++++++++++++++++++++++++
+ 2 files changed, 27 insertions(+), 24 deletions(-)
+
+diff --git a/tools/perf/Makefile b/tools/perf/Makefile
+index 51fac31..7dc6615 100644
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -473,26 +473,6 @@ ifneq ($(MAKECMDGOALS),tags)
+ # because maintaining the nesting to match is a pain.  If
+ # we had "elif" things would have been much nicer...
+-# There's only x86 (both 32 and 64) support for CFI unwind so far
+-ifneq ($(ARCH),x86)
+-      NO_LIBUNWIND := 1
+-endif
+-
+-ifndef NO_LIBUNWIND
+-# for linking with debug library, run like:
+-# make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/
+-ifdef LIBUNWIND_DIR
+-      LIBUNWIND_CFLAGS  := -I$(LIBUNWIND_DIR)/include
+-      LIBUNWIND_LDFLAGS := -L$(LIBUNWIND_DIR)/lib
+-endif
+-
+-FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(ALL_CFLAGS) $(LIBUNWIND_LDFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS)
+-ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND),libunwind),y)
+-      msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99);
+-      NO_LIBUNWIND := 1
+-endif # Libunwind support
+-endif # NO_LIBUNWIND
+-
+ -include arch/$(ARCH)/Makefile
+ ifneq ($(OUTPUT),)
+@@ -521,10 +501,6 @@ endif # NO_DWARF
+ endif # NO_LIBELF
+ ifndef NO_LIBUNWIND
+-      BASIC_CFLAGS += -DLIBUNWIND_SUPPORT
+-      EXTLIBS += $(LIBUNWIND_LIBS)
+-      BASIC_CFLAGS := $(LIBUNWIND_CFLAGS) $(BASIC_CFLAGS)
+-      BASIC_LDFLAGS := $(LIBUNWIND_LDFLAGS) $(BASIC_LDFLAGS)
+       LIB_OBJS += $(OUTPUT)util/unwind.o
+ endif
+diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
+index 71e737c..438574b 100644
+--- a/tools/perf/config/Makefile
++++ b/tools/perf/config/Makefile
+@@ -170,3 +170,30 @@ endif # PERF_HAVE_DWARF_REGS
+ endif # NO_DWARF
+ endif # NO_LIBELF
++
++# There's only x86 (both 32 and 64) support for CFI unwind so far
++ifneq ($(ARCH),x86)
++      NO_LIBUNWIND := 1
++endif
++
++ifndef NO_LIBUNWIND
++# for linking with debug library, run like:
++# make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/
++ifdef LIBUNWIND_DIR
++      LIBUNWIND_CFLAGS  := -I$(LIBUNWIND_DIR)/include
++      LIBUNWIND_LDFLAGS := -L$(LIBUNWIND_DIR)/lib
++endif
++
++FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(ALL_CFLAGS) $(LIBUNWIND_LDFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS)
++ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND),libunwind),y)
++      msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99);
++      NO_LIBUNWIND := 1
++endif # Libunwind support
++endif # NO_LIBUNWIND
++
++ifndef NO_LIBUNWIND
++      BASIC_CFLAGS += -DLIBUNWIND_SUPPORT
++      EXTLIBS += $(LIBUNWIND_LIBS)
++      BASIC_CFLAGS := $(LIBUNWIND_CFLAGS) $(BASIC_CFLAGS)
++      BASIC_LDFLAGS := $(LIBUNWIND_LDFLAGS) $(BASIC_LDFLAGS)
++endif # NO_LIBUNWIND
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0396-perf-tools-Move-libaudit-check-config-into-config-Ma.patch b/patches.tizen/0396-perf-tools-Move-libaudit-check-config-into-config-Ma.patch
new file mode 100644 (file)
index 0000000..00d1d62
--- /dev/null
@@ -0,0 +1,68 @@
+From ba02ac84ec664b7fdfb40243d32fd5fc4dd1ee23 Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Mon, 25 Mar 2013 00:54:36 +0100
+Subject: [PATCH 0396/1302] perf tools: Move libaudit check config into
+ config/Makefile
+
+Moving libaudit check config into config/Makefile.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369398928-9809-9-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Makefile        |  9 +--------
+ tools/perf/config/Makefile | 11 +++++++++++
+ 2 files changed, 12 insertions(+), 8 deletions(-)
+
+diff --git a/tools/perf/Makefile b/tools/perf/Makefile
+index 7dc6615..57d39ed 100644
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -505,14 +505,7 @@ ifndef NO_LIBUNWIND
+ endif
+ ifndef NO_LIBAUDIT
+-      FLAGS_LIBAUDIT = $(ALL_CFLAGS) $(ALL_LDFLAGS) -laudit
+-      ifneq ($(call try-cc,$(SOURCE_LIBAUDIT),$(FLAGS_LIBAUDIT),libaudit),y)
+-              msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev);
+-      else
+-              BASIC_CFLAGS += -DLIBAUDIT_SUPPORT
+-              BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
+-              EXTLIBS += -laudit
+-      endif
++      BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
+ endif
+ ifndef NO_SLANG
+diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
+index 438574b..02e58ff 100644
+--- a/tools/perf/config/Makefile
++++ b/tools/perf/config/Makefile
+@@ -197,3 +197,14 @@ ifndef NO_LIBUNWIND
+       BASIC_CFLAGS := $(LIBUNWIND_CFLAGS) $(BASIC_CFLAGS)
+       BASIC_LDFLAGS := $(LIBUNWIND_LDFLAGS) $(BASIC_LDFLAGS)
+ endif # NO_LIBUNWIND
++
++ifndef NO_LIBAUDIT
++      FLAGS_LIBAUDIT = $(ALL_CFLAGS) $(ALL_LDFLAGS) -laudit
++      ifneq ($(call try-cc,$(SOURCE_LIBAUDIT),$(FLAGS_LIBAUDIT),libaudit),y)
++              msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev);
++              NO_LIBAUDIT := 1
++      else
++              BASIC_CFLAGS += -DLIBAUDIT_SUPPORT
++              EXTLIBS += -laudit
++      endif
++endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0397-perf-tools-Move-slang-check-config-into-config-Makef.patch b/patches.tizen/0397-perf-tools-Move-slang-check-config-into-config-Makef.patch
new file mode 100644 (file)
index 0000000..c4d45a4
--- /dev/null
@@ -0,0 +1,111 @@
+From e69e33b1c4d3297d1ae012b7dc784a902092a1ef Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Mon, 25 Mar 2013 00:56:08 +0100
+Subject: [PATCH 0397/1302] perf tools: Move slang check config into
+ config/Makefile
+
+Moving slang check config into config/Makefile.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369398928-9809-10-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Makefile        | 39 +++++++++++++--------------------------
+ tools/perf/config/Makefile | 17 +++++++++++++++++
+ 2 files changed, 30 insertions(+), 26 deletions(-)
+
+diff --git a/tools/perf/Makefile b/tools/perf/Makefile
+index 57d39ed..f0c23ce 100644
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -99,10 +99,6 @@ ifeq ($(config),1)
+ include config/Makefile
+ endif
+-ifdef NO_NEWT
+-      NO_SLANG=1
+-endif
+-
+ # Among the variables below, these:
+ #   perfexecdir
+ #   template_dir
+@@ -509,28 +505,19 @@ ifndef NO_LIBAUDIT
+ endif
+ ifndef NO_SLANG
+-      FLAGS_SLANG=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -I/usr/include/slang -lslang
+-      ifneq ($(call try-cc,$(SOURCE_SLANG),$(FLAGS_SLANG),libslang),y)
+-              msg := $(warning slang not found, disables TUI support. Please install slang-devel or libslang-dev);
+-      else
+-              # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h
+-              BASIC_CFLAGS += -I/usr/include/slang
+-              BASIC_CFLAGS += -DSLANG_SUPPORT
+-              EXTLIBS += -lslang
+-              LIB_OBJS += $(OUTPUT)ui/browser.o
+-              LIB_OBJS += $(OUTPUT)ui/browsers/annotate.o
+-              LIB_OBJS += $(OUTPUT)ui/browsers/hists.o
+-              LIB_OBJS += $(OUTPUT)ui/browsers/map.o
+-              LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o
+-              LIB_OBJS += $(OUTPUT)ui/tui/setup.o
+-              LIB_OBJS += $(OUTPUT)ui/tui/util.o
+-              LIB_OBJS += $(OUTPUT)ui/tui/helpline.o
+-              LIB_OBJS += $(OUTPUT)ui/tui/progress.o
+-              LIB_H += ui/browser.h
+-              LIB_H += ui/browsers/map.h
+-              LIB_H += ui/keysyms.h
+-              LIB_H += ui/libslang.h
+-      endif
++      LIB_OBJS += $(OUTPUT)ui/browser.o
++      LIB_OBJS += $(OUTPUT)ui/browsers/annotate.o
++      LIB_OBJS += $(OUTPUT)ui/browsers/hists.o
++      LIB_OBJS += $(OUTPUT)ui/browsers/map.o
++      LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o
++      LIB_OBJS += $(OUTPUT)ui/tui/setup.o
++      LIB_OBJS += $(OUTPUT)ui/tui/util.o
++      LIB_OBJS += $(OUTPUT)ui/tui/helpline.o
++      LIB_OBJS += $(OUTPUT)ui/tui/progress.o
++      LIB_H += ui/browser.h
++      LIB_H += ui/browsers/map.h
++      LIB_H += ui/keysyms.h
++      LIB_H += ui/libslang.h
+ endif
+ ifndef NO_GTK2
+diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
+index 02e58ff..06634be 100644
+--- a/tools/perf/config/Makefile
++++ b/tools/perf/config/Makefile
+@@ -208,3 +208,20 @@ ifndef NO_LIBAUDIT
+               EXTLIBS += -laudit
+       endif
+ endif
++
++ifdef NO_NEWT
++      NO_SLANG=1
++endif
++
++ifndef NO_SLANG
++      FLAGS_SLANG=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -I/usr/include/slang -lslang
++      ifneq ($(call try-cc,$(SOURCE_SLANG),$(FLAGS_SLANG),libslang),y)
++              msg := $(warning slang not found, disables TUI support. Please install slang-devel or libslang-dev);
++              NO_SLANG := 1
++      else
++              # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h
++              BASIC_CFLAGS += -I/usr/include/slang
++              BASIC_CFLAGS += -DSLANG_SUPPORT
++              EXTLIBS += -lslang
++      endif
++endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0398-perf-tools-Move-gtk2-check-config-into-config-Makefi.patch b/patches.tizen/0398-perf-tools-Move-gtk2-check-config-into-config-Makefi.patch
new file mode 100644 (file)
index 0000000..86696ee
--- /dev/null
@@ -0,0 +1,88 @@
+From 0d9364dd1db659e3ed5240f9af985dc65cbbd93a Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Mon, 18 Mar 2013 00:09:24 +0100
+Subject: [PATCH 0398/1302] perf tools: Move gtk2 check config into
+ config/Makefile
+
+Moving gtk2 check config into config/Makefile.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369398928-9809-11-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Makefile        | 25 +++++++------------------
+ tools/perf/config/Makefile | 15 +++++++++++++++
+ 2 files changed, 22 insertions(+), 18 deletions(-)
+
+diff --git a/tools/perf/Makefile b/tools/perf/Makefile
+index f0c23ce..8e59a4d 100644
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -521,24 +521,13 @@ ifndef NO_SLANG
+ endif
+ ifndef NO_GTK2
+-      FLAGS_GTK2=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
+-      ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2),gtk2),y)
+-              msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev);
+-      else
+-              ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2),-DHAVE_GTK_INFO_BAR),y)
+-                      BASIC_CFLAGS += -DHAVE_GTK_INFO_BAR
+-              endif
+-              BASIC_CFLAGS += -DGTK2_SUPPORT
+-              BASIC_CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null)
+-              EXTLIBS += $(shell pkg-config --libs gtk+-2.0 2>/dev/null)
+-              LIB_OBJS += $(OUTPUT)ui/gtk/browser.o
+-              LIB_OBJS += $(OUTPUT)ui/gtk/hists.o
+-              LIB_OBJS += $(OUTPUT)ui/gtk/setup.o
+-              LIB_OBJS += $(OUTPUT)ui/gtk/util.o
+-              LIB_OBJS += $(OUTPUT)ui/gtk/helpline.o
+-              LIB_OBJS += $(OUTPUT)ui/gtk/progress.o
+-              LIB_OBJS += $(OUTPUT)ui/gtk/annotate.o
+-      endif
++      LIB_OBJS += $(OUTPUT)ui/gtk/browser.o
++      LIB_OBJS += $(OUTPUT)ui/gtk/hists.o
++      LIB_OBJS += $(OUTPUT)ui/gtk/setup.o
++      LIB_OBJS += $(OUTPUT)ui/gtk/util.o
++      LIB_OBJS += $(OUTPUT)ui/gtk/helpline.o
++      LIB_OBJS += $(OUTPUT)ui/gtk/progress.o
++      LIB_OBJS += $(OUTPUT)ui/gtk/annotate.o
+ endif
+ ifdef NO_LIBPERL
+diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
+index 06634be..8cf0958 100644
+--- a/tools/perf/config/Makefile
++++ b/tools/perf/config/Makefile
+@@ -225,3 +225,18 @@ ifndef NO_SLANG
+               EXTLIBS += -lslang
+       endif
+ endif
++
++ifndef NO_GTK2
++      FLAGS_GTK2=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
++      ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2),gtk2),y)
++              msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev);
++              NO_GTK2 := 1
++      else
++              ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2),-DHAVE_GTK_INFO_BAR),y)
++                      BASIC_CFLAGS += -DHAVE_GTK_INFO_BAR
++              endif
++              BASIC_CFLAGS += -DGTK2_SUPPORT
++              BASIC_CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null)
++              EXTLIBS += $(shell pkg-config --libs gtk+-2.0 2>/dev/null)
++      endif
++endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0399-perf-tools-Move-libperl-check-config-into-config-Mak.patch b/patches.tizen/0399-perf-tools-Move-libperl-check-config-into-config-Mak.patch
new file mode 100644 (file)
index 0000000..b9f421c
--- /dev/null
@@ -0,0 +1,89 @@
+From f67af54c64883825d17164a8e0cd1511d8e912be Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Mon, 18 Mar 2013 00:19:44 +0100
+Subject: [PATCH 0399/1302] perf tools: Move libperl check config into
+ config/Makefile
+
+Moving libperl check config into config/Makefile.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369398928-9809-12-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Makefile        | 20 +++-----------------
+ tools/perf/config/Makefile | 21 +++++++++++++++++++++
+ 2 files changed, 24 insertions(+), 17 deletions(-)
+
+diff --git a/tools/perf/Makefile b/tools/perf/Makefile
+index 8e59a4d..f856bb5 100644
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -530,23 +530,9 @@ ifndef NO_GTK2
+       LIB_OBJS += $(OUTPUT)ui/gtk/annotate.o
+ endif
+-ifdef NO_LIBPERL
+-      BASIC_CFLAGS += -DNO_LIBPERL
+-else
+-       PERL_EMBED_LDOPTS = $(shell perl -MExtUtils::Embed -e ldopts 2>/dev/null)
+-       PERL_EMBED_LDFLAGS = $(call strip-libs,$(PERL_EMBED_LDOPTS))
+-       PERL_EMBED_LIBADD = $(call grep-libs,$(PERL_EMBED_LDOPTS))
+-      PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null`
+-      FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS)
+-
+-      ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED),perl),y)
+-              BASIC_CFLAGS += -DNO_LIBPERL
+-      else
+-               ALL_LDFLAGS += $(PERL_EMBED_LDFLAGS)
+-               EXTLIBS += $(PERL_EMBED_LIBADD)
+-              LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-perl.o
+-              LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o
+-      endif
++ifndef NO_LIBPERL
++      LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-perl.o
++      LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o
+ endif
+ disable-python = $(eval $(disable-python_code))
+diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
+index 8cf0958..a42c7b8 100644
+--- a/tools/perf/config/Makefile
++++ b/tools/perf/config/Makefile
+@@ -240,3 +240,24 @@ ifndef NO_GTK2
+               EXTLIBS += $(shell pkg-config --libs gtk+-2.0 2>/dev/null)
+       endif
+ endif
++
++grep-libs  = $(filter -l%,$(1))
++strip-libs = $(filter-out -l%,$(1))
++
++ifdef NO_LIBPERL
++      BASIC_CFLAGS += -DNO_LIBPERL
++else
++      PERL_EMBED_LDOPTS = $(shell perl -MExtUtils::Embed -e ldopts 2>/dev/null)
++      PERL_EMBED_LDFLAGS = $(call strip-libs,$(PERL_EMBED_LDOPTS))
++      PERL_EMBED_LIBADD = $(call grep-libs,$(PERL_EMBED_LDOPTS))
++      PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null`
++      FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS)
++
++      ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED),perl),y)
++              BASIC_CFLAGS += -DNO_LIBPERL
++              NO_LIBPERL := 1
++      else
++              ALL_LDFLAGS += $(PERL_EMBED_LDFLAGS)
++              EXTLIBS += $(PERL_EMBED_LIBADD)
++      endif
++endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0400-perf-tools-Move-libpython-check-config-into-config-M.patch b/patches.tizen/0400-perf-tools-Move-libpython-check-config-into-config-M.patch
new file mode 100644 (file)
index 0000000..9ce4d2d
--- /dev/null
@@ -0,0 +1,186 @@
+From 704c06b80388ba85528c345b8b0d192bac81d61a Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Mon, 18 Mar 2013 00:35:32 +0100
+Subject: [PATCH 0400/1302] perf tools: Move libpython check config into
+ config/Makefile
+
+Moving libpython check config into config/Makefile.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369398928-9809-13-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Makefile        | 68 ++--------------------------------------------
+ tools/perf/config/Makefile | 63 ++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 66 insertions(+), 65 deletions(-)
+
+diff --git a/tools/perf/Makefile b/tools/perf/Makefile
+index f856bb5..061de65 100644
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -196,8 +196,6 @@ SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH))
+ #
+ PROGRAMS += $(OUTPUT)perf
+-LANG_BINDINGS =
+-
+ # what 'all' will build and 'install' will install, in perfexecdir
+ ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS)
+@@ -535,69 +533,9 @@ ifndef NO_LIBPERL
+       LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o
+ endif
+-disable-python = $(eval $(disable-python_code))
+-define disable-python_code
+-  BASIC_CFLAGS += -DNO_LIBPYTHON
+-  $(if $(1),$(warning No $(1) was found))
+-  $(warning Python support will not be built)
+-endef
+-
+-override PYTHON := \
+-  $(call get-executable-or-default,PYTHON,python)
+-
+-ifndef PYTHON
+-  $(call disable-python,python interpreter)
+-else
+-
+-  PYTHON_WORD := $(call shell-wordify,$(PYTHON))
+-
+-  ifdef NO_LIBPYTHON
+-    $(call disable-python)
+-  else
+-
+-    override PYTHON_CONFIG := \
+-      $(call get-executable-or-default,PYTHON_CONFIG,$(PYTHON)-config)
+-
+-    ifndef PYTHON_CONFIG
+-      $(call disable-python,python-config tool)
+-    else
+-
+-      PYTHON_CONFIG_SQ := $(call shell-sq,$(PYTHON_CONFIG))
+-
+-      PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null)
+-      PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS))
+-      PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS))
+-      PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null)
+-      FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS)
+-
+-      ifneq ($(call try-cc,$(SOURCE_PYTHON_EMBED),$(FLAGS_PYTHON_EMBED),python),y)
+-        $(call disable-python,Python.h (for Python 2.x))
+-      else
+-
+-        ifneq ($(call try-cc,$(SOURCE_PYTHON_VERSION),$(FLAGS_PYTHON_EMBED),python version),y)
+-          $(warning Python 3 is not yet supported; please set)
+-          $(warning PYTHON and/or PYTHON_CONFIG appropriately.)
+-          $(warning If you also have Python 2 installed, then)
+-          $(warning try something like:)
+-          $(warning $(and ,))
+-          $(warning $(and ,)  make PYTHON=python2)
+-          $(warning $(and ,))
+-          $(warning Otherwise, disable Python support entirely:)
+-          $(warning $(and ,))
+-          $(warning $(and ,)  make NO_LIBPYTHON=1)
+-          $(warning $(and ,))
+-          $(error   $(and ,))
+-        else
+-          ALL_LDFLAGS += $(PYTHON_EMBED_LDFLAGS)
+-          EXTLIBS += $(PYTHON_EMBED_LIBADD)
+-          LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o
+-          LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o
+-          LANG_BINDINGS += $(OUTPUT)python/perf.so
+-        endif
+-
+-      endif
+-    endif
+-  endif
++ifndef NO_LIBPYTHON
++      LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o
++      LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o
+ endif
+ ifdef NO_DEMANGLE
+diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
+index a42c7b8..b9b1465 100644
+--- a/tools/perf/config/Makefile
++++ b/tools/perf/config/Makefile
+@@ -261,3 +261,66 @@ else
+               EXTLIBS += $(PERL_EMBED_LIBADD)
+       endif
+ endif
++
++disable-python = $(eval $(disable-python_code))
++define disable-python_code
++  BASIC_CFLAGS += -DNO_LIBPYTHON
++  $(if $(1),$(warning No $(1) was found))
++  $(warning Python support will not be built)
++  NO_LIBPYTHON := 1
++endef
++
++override PYTHON := \
++  $(call get-executable-or-default,PYTHON,python)
++
++ifndef PYTHON
++  $(call disable-python,python interpreter)
++else
++
++  PYTHON_WORD := $(call shell-wordify,$(PYTHON))
++
++  ifdef NO_LIBPYTHON
++    $(call disable-python)
++  else
++
++    override PYTHON_CONFIG := \
++      $(call get-executable-or-default,PYTHON_CONFIG,$(PYTHON)-config)
++
++    ifndef PYTHON_CONFIG
++      $(call disable-python,python-config tool)
++    else
++
++      PYTHON_CONFIG_SQ := $(call shell-sq,$(PYTHON_CONFIG))
++
++      PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null)
++      PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS))
++      PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS))
++      PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null)
++      FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS)
++
++      ifneq ($(call try-cc,$(SOURCE_PYTHON_EMBED),$(FLAGS_PYTHON_EMBED),python),y)
++        $(call disable-python,Python.h (for Python 2.x))
++      else
++
++        ifneq ($(call try-cc,$(SOURCE_PYTHON_VERSION),$(FLAGS_PYTHON_EMBED),python version),y)
++          $(warning Python 3 is not yet supported; please set)
++          $(warning PYTHON and/or PYTHON_CONFIG appropriately.)
++          $(warning If you also have Python 2 installed, then)
++          $(warning try something like:)
++          $(warning $(and ,))
++          $(warning $(and ,)  make PYTHON=python2)
++          $(warning $(and ,))
++          $(warning Otherwise, disable Python support entirely:)
++          $(warning $(and ,))
++          $(warning $(and ,)  make NO_LIBPYTHON=1)
++          $(warning $(and ,))
++          $(error   $(and ,))
++        else
++          ALL_LDFLAGS += $(PYTHON_EMBED_LDFLAGS)
++          EXTLIBS += $(PYTHON_EMBED_LIBADD)
++          LANG_BINDINGS += $(OUTPUT)python/perf.so
++        endif
++      endif
++    endif
++  endif
++endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0401-perf-tools-Move-libbfd-check-config-into-config-Make.patch b/patches.tizen/0401-perf-tools-Move-libbfd-check-config-into-config-Make.patch
new file mode 100644 (file)
index 0000000..f61b35f
--- /dev/null
@@ -0,0 +1,122 @@
+From 5718250f069b7519c3a83a0584f7f2229122a44e Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Mon, 18 Mar 2013 00:38:16 +0100
+Subject: [PATCH 0401/1302] perf tools: Move libbfd check config into
+ config/Makefile
+
+Moving libbfd check config into config/Makefile.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369398928-9809-14-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Makefile        | 37 -------------------------------------
+ tools/perf/config/Makefile | 37 +++++++++++++++++++++++++++++++++++++
+ 2 files changed, 37 insertions(+), 37 deletions(-)
+
+diff --git a/tools/perf/Makefile b/tools/perf/Makefile
+index 061de65..e4d99c4 100644
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -538,43 +538,6 @@ ifndef NO_LIBPYTHON
+       LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o
+ endif
+-ifdef NO_DEMANGLE
+-      BASIC_CFLAGS += -DNO_DEMANGLE
+-else
+-      ifdef HAVE_CPLUS_DEMANGLE
+-              EXTLIBS += -liberty
+-              BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
+-      else
+-              FLAGS_BFD=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -DPACKAGE='perf' -lbfd
+-              has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD),libbfd)
+-              ifeq ($(has_bfd),y)
+-                      EXTLIBS += -lbfd
+-              else
+-                      FLAGS_BFD_IBERTY=$(FLAGS_BFD) -liberty
+-                      has_bfd_iberty := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY),liberty)
+-                      ifeq ($(has_bfd_iberty),y)
+-                              EXTLIBS += -lbfd -liberty
+-                      else
+-                              FLAGS_BFD_IBERTY_Z=$(FLAGS_BFD_IBERTY) -lz
+-                              has_bfd_iberty_z := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY_Z),libz)
+-                              ifeq ($(has_bfd_iberty_z),y)
+-                                      EXTLIBS += -lbfd -liberty -lz
+-                              else
+-                                      FLAGS_CPLUS_DEMANGLE=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -liberty
+-                                      has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE),demangle)
+-                                      ifeq ($(has_cplus_demangle),y)
+-                                              EXTLIBS += -liberty
+-                                              BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
+-                                      else
+-                                              msg := $(warning No bfd.h/libbfd found, install binutils-dev[el]/zlib-static to gain symbol demangling)
+-                                              BASIC_CFLAGS += -DNO_DEMANGLE
+-                                      endif
+-                              endif
+-                      endif
+-              endif
+-      endif
+-endif
+-
+ ifeq ($(NO_PERF_REGS),0)
+       ifeq ($(ARCH),x86)
+               LIB_H += arch/x86/include/perf_regs.h
+diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
+index b9b1465..317dafe 100644
+--- a/tools/perf/config/Makefile
++++ b/tools/perf/config/Makefile
+@@ -324,3 +324,40 @@ else
+     endif
+   endif
+ endif
++
++ifdef NO_DEMANGLE
++      BASIC_CFLAGS += -DNO_DEMANGLE
++else
++      ifdef HAVE_CPLUS_DEMANGLE
++              EXTLIBS += -liberty
++              BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
++      else
++              FLAGS_BFD=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -DPACKAGE='perf' -lbfd
++              has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD),libbfd)
++              ifeq ($(has_bfd),y)
++                      EXTLIBS += -lbfd
++              else
++                      FLAGS_BFD_IBERTY=$(FLAGS_BFD) -liberty
++                      has_bfd_iberty := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY),liberty)
++                      ifeq ($(has_bfd_iberty),y)
++                              EXTLIBS += -lbfd -liberty
++                      else
++                              FLAGS_BFD_IBERTY_Z=$(FLAGS_BFD_IBERTY) -lz
++                              has_bfd_iberty_z := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY_Z),libz)
++                              ifeq ($(has_bfd_iberty_z),y)
++                                      EXTLIBS += -lbfd -liberty -lz
++                              else
++                                      FLAGS_CPLUS_DEMANGLE=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -liberty
++                                      has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE),demangle)
++                                      ifeq ($(has_cplus_demangle),y)
++                                              EXTLIBS += -liberty
++                                              BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
++                                      else
++                                              msg := $(warning No bfd.h/libbfd found, install binutils-dev[el]/zlib-static to gain symbol demangling)
++                                              BASIC_CFLAGS += -DNO_DEMANGLE
++                                      endif
++                              endif
++                      endif
++              endif
++      endif
++endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0402-perf-tools-Move-stdlib-check-config-into-config-Make.patch b/patches.tizen/0402-perf-tools-Move-stdlib-check-config-into-config-Make.patch
new file mode 100644 (file)
index 0000000..0be7a89
--- /dev/null
@@ -0,0 +1,84 @@
+From 4d1eec6de3dbfa04b2ba57a5777f6b53512f20c6 Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Mon, 18 Mar 2013 00:41:04 +0100
+Subject: [PATCH 0402/1302] perf tools: Move stdlib check config into
+ config/Makefile
+
+Moving stdlib check config into config/Makefile.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369398928-9809-15-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Makefile        | 18 ------------------
+ tools/perf/config/Makefile | 18 ++++++++++++++++++
+ 2 files changed, 18 insertions(+), 18 deletions(-)
+
+diff --git a/tools/perf/Makefile b/tools/perf/Makefile
+index e4d99c4..9276576 100644
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -544,24 +544,6 @@ ifeq ($(NO_PERF_REGS),0)
+       endif
+ endif
+-ifndef NO_STRLCPY
+-      ifeq ($(call try-cc,$(SOURCE_STRLCPY),,-DHAVE_STRLCPY),y)
+-              BASIC_CFLAGS += -DHAVE_STRLCPY
+-      endif
+-endif
+-
+-ifndef NO_ON_EXIT
+-      ifeq ($(call try-cc,$(SOURCE_ON_EXIT),,-DHAVE_ON_EXIT),y)
+-              BASIC_CFLAGS += -DHAVE_ON_EXIT
+-      endif
+-endif
+-
+-ifndef NO_BACKTRACE
+-       ifeq ($(call try-cc,$(SOURCE_BACKTRACE),,-DBACKTRACE_SUPPORT),y)
+-               BASIC_CFLAGS += -DBACKTRACE_SUPPORT
+-       endif
+-endif
+-
+ ifndef NO_LIBNUMA
+       FLAGS_LIBNUMA = $(ALL_CFLAGS) $(ALL_LDFLAGS) -lnuma
+       ifneq ($(call try-cc,$(SOURCE_LIBNUMA),$(FLAGS_LIBNUMA),libnuma),y)
+diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
+index 317dafe..8c0e43f 100644
+--- a/tools/perf/config/Makefile
++++ b/tools/perf/config/Makefile
+@@ -361,3 +361,21 @@ else
+               endif
+       endif
+ endif
++
++ifndef NO_STRLCPY
++      ifeq ($(call try-cc,$(SOURCE_STRLCPY),,-DHAVE_STRLCPY),y)
++              BASIC_CFLAGS += -DHAVE_STRLCPY
++      endif
++endif
++
++ifndef NO_ON_EXIT
++      ifeq ($(call try-cc,$(SOURCE_ON_EXIT),,-DHAVE_ON_EXIT),y)
++              BASIC_CFLAGS += -DHAVE_ON_EXIT
++      endif
++endif
++
++ifndef NO_BACKTRACE
++       ifeq ($(call try-cc,$(SOURCE_BACKTRACE),,-DBACKTRACE_SUPPORT),y)
++              BASIC_CFLAGS += -DBACKTRACE_SUPPORT
++       endif
++endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0403-perf-tools-Move-libnuma-check-config-into-config-Mak.patch b/patches.tizen/0403-perf-tools-Move-libnuma-check-config-into-config-Mak.patch
new file mode 100644 (file)
index 0000000..cb765c5
--- /dev/null
@@ -0,0 +1,68 @@
+From 8023188d747f89f7cc13fd2c2c19442d1a8e5cc8 Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Mon, 18 Mar 2013 00:45:27 +0100
+Subject: [PATCH 0403/1302] perf tools: Move libnuma check config into
+ config/Makefile
+
+Moving libnuma check config into config/Makefile
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369398928-9809-16-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Makefile        |  9 +--------
+ tools/perf/config/Makefile | 11 +++++++++++
+ 2 files changed, 12 insertions(+), 8 deletions(-)
+
+diff --git a/tools/perf/Makefile b/tools/perf/Makefile
+index 9276576..11525ac 100644
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -545,14 +545,7 @@ ifeq ($(NO_PERF_REGS),0)
+ endif
+ ifndef NO_LIBNUMA
+-      FLAGS_LIBNUMA = $(ALL_CFLAGS) $(ALL_LDFLAGS) -lnuma
+-      ifneq ($(call try-cc,$(SOURCE_LIBNUMA),$(FLAGS_LIBNUMA),libnuma),y)
+-              msg := $(warning No numa.h found, disables 'perf bench numa mem' benchmark, please install numa-libs-devel or libnuma-dev);
+-      else
+-              BASIC_CFLAGS += -DLIBNUMA_SUPPORT
+-              BUILTIN_OBJS += $(OUTPUT)bench/numa.o
+-              EXTLIBS += -lnuma
+-      endif
++      BUILTIN_OBJS += $(OUTPUT)bench/numa.o
+ endif
+ ifdef ASCIIDOC8
+diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
+index 8c0e43f..124c344 100644
+--- a/tools/perf/config/Makefile
++++ b/tools/perf/config/Makefile
+@@ -379,3 +379,14 @@ ifndef NO_BACKTRACE
+               BASIC_CFLAGS += -DBACKTRACE_SUPPORT
+        endif
+ endif
++
++ifndef NO_LIBNUMA
++      FLAGS_LIBNUMA = $(ALL_CFLAGS) $(ALL_LDFLAGS) -lnuma
++      ifneq ($(call try-cc,$(SOURCE_LIBNUMA),$(FLAGS_LIBNUMA),libnuma),y)
++              msg := $(warning No numa.h found, disables 'perf bench numa mem' benchmark, please install numa-libs-devel or libnuma-dev);
++              NO_LIBNUMA := 1
++      else
++              BASIC_CFLAGS += -DLIBNUMA_SUPPORT
++              EXTLIBS += -lnuma
++      endif
++endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0404-perf-tools-Move-paths-config-into-config-Makefile.patch b/patches.tizen/0404-perf-tools-Move-paths-config-into-config-Makefile.patch
new file mode 100644 (file)
index 0000000..6e7bea0
--- /dev/null
@@ -0,0 +1,178 @@
+From 6cb5dd2f7ffaf38af7ce2f4c8e761888ca5b0894 Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Mon, 18 Mar 2013 00:56:01 +0100
+Subject: [PATCH 0404/1302] perf tools: Move paths config into config/Makefile
+
+Moving paths config into config/Makefile.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369398928-9809-17-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Makefile        | 58 ----------------------------------------------
+ tools/perf/config/Makefile | 52 +++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 52 insertions(+), 58 deletions(-)
+
+diff --git a/tools/perf/Makefile b/tools/perf/Makefile
+index 11525ac..240bf88 100644
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -99,39 +99,6 @@ ifeq ($(config),1)
+ include config/Makefile
+ endif
+-# Among the variables below, these:
+-#   perfexecdir
+-#   template_dir
+-#   mandir
+-#   infodir
+-#   htmldir
+-#   ETC_PERFCONFIG (but not sysconfdir)
+-# can be specified as a relative path some/where/else;
+-# this is interpreted as relative to $(prefix) and "perf" at
+-# runtime figures out where they are based on the path to the executable.
+-# This can help installing the suite in a relocatable way.
+-
+-# Make the path relative to DESTDIR, not to prefix
+-ifndef DESTDIR
+-prefix = $(HOME)
+-endif
+-bindir_relative = bin
+-bindir = $(prefix)/$(bindir_relative)
+-mandir = share/man
+-infodir = share/info
+-perfexecdir = libexec/perf-core
+-sharedir = $(prefix)/share
+-template_dir = share/perf-core/templates
+-htmldir = share/doc/perf-doc
+-ifeq ($(prefix),/usr)
+-sysconfdir = /etc
+-ETC_PERFCONFIG = $(sysconfdir)/perfconfig
+-else
+-sysconfdir = $(prefix)/etc
+-ETC_PERFCONFIG = etc/perfconfig
+-endif
+-lib = lib
+-
+ export prefix bindir sharedir sysconfdir
+ # sparse is architecture-neutral, which means that we need to tell it
+@@ -555,23 +522,6 @@ endif
+ endif # MAKECMDGOALS != tags
+ endif # MAKECMDGOALS != clean
+-# Shell quote (do not use $(call) to accommodate ancient setups);
+-
+-ETC_PERFCONFIG_SQ = $(subst ','\'',$(ETC_PERFCONFIG))
+-
+-DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
+-bindir_SQ = $(subst ','\'',$(bindir))
+-bindir_relative_SQ = $(subst ','\'',$(bindir_relative))
+-mandir_SQ = $(subst ','\'',$(mandir))
+-infodir_SQ = $(subst ','\'',$(infodir))
+-perfexecdir_SQ = $(subst ','\'',$(perfexecdir))
+-template_dir_SQ = $(subst ','\'',$(template_dir))
+-htmldir_SQ = $(subst ','\'',$(htmldir))
+-prefix_SQ = $(subst ','\'',$(prefix))
+-sysconfdir_SQ = $(subst ','\'',$(sysconfdir))
+-
+-SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
+-
+ LIBS = -Wl,--whole-archive $(PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group
+ ALL_CFLAGS += $(BASIC_CFLAGS)
+@@ -580,7 +530,6 @@ ALL_LDFLAGS += $(BASIC_LDFLAGS)
+ export INSTALL SHELL_PATH
+-
+ ### Build rules
+ SHELL = $(SHELL_PATH)
+@@ -822,13 +771,6 @@ check: $(OUTPUT)common-cmds.h
+ ### Installation rules
+-ifneq ($(filter /%,$(firstword $(perfexecdir))),)
+-perfexec_instdir = $(perfexecdir)
+-else
+-perfexec_instdir = $(prefix)/$(perfexecdir)
+-endif
+-perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir))
+-
+ install-bin: all
+       $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
+       $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'
+diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
+index 124c344..506c479 100644
+--- a/tools/perf/config/Makefile
++++ b/tools/perf/config/Makefile
+@@ -390,3 +390,55 @@ ifndef NO_LIBNUMA
+               EXTLIBS += -lnuma
+       endif
+ endif
++
++# Among the variables below, these:
++#   perfexecdir
++#   template_dir
++#   mandir
++#   infodir
++#   htmldir
++#   ETC_PERFCONFIG (but not sysconfdir)
++# can be specified as a relative path some/where/else;
++# this is interpreted as relative to $(prefix) and "perf" at
++# runtime figures out where they are based on the path to the executable.
++# This can help installing the suite in a relocatable way.
++
++# Make the path relative to DESTDIR, not to prefix
++ifndef DESTDIR
++prefix = $(HOME)
++endif
++bindir_relative = bin
++bindir = $(prefix)/$(bindir_relative)
++mandir = share/man
++infodir = share/info
++perfexecdir = libexec/perf-core
++sharedir = $(prefix)/share
++template_dir = share/perf-core/templates
++htmldir = share/doc/perf-doc
++ifeq ($(prefix),/usr)
++sysconfdir = /etc
++ETC_PERFCONFIG = $(sysconfdir)/perfconfig
++else
++sysconfdir = $(prefix)/etc
++ETC_PERFCONFIG = etc/perfconfig
++endif
++lib = lib
++
++# Shell quote (do not use $(call) to accommodate ancient setups);
++ETC_PERFCONFIG_SQ = $(subst ','\'',$(ETC_PERFCONFIG))
++DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
++bindir_SQ = $(subst ','\'',$(bindir))
++mandir_SQ = $(subst ','\'',$(mandir))
++infodir_SQ = $(subst ','\'',$(infodir))
++perfexecdir_SQ = $(subst ','\'',$(perfexecdir))
++template_dir_SQ = $(subst ','\'',$(template_dir))
++htmldir_SQ = $(subst ','\'',$(htmldir))
++prefix_SQ = $(subst ','\'',$(prefix))
++sysconfdir_SQ = $(subst ','\'',$(sysconfdir))
++
++ifneq ($(filter /%,$(firstword $(perfexecdir))),)
++perfexec_instdir = $(perfexecdir)
++else
++perfexec_instdir = $(prefix)/$(perfexecdir)
++endif
++perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir))
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0405-perf-tools-Final-touches-for-CHK-config-move.patch b/patches.tizen/0405-perf-tools-Final-touches-for-CHK-config-move.patch
new file mode 100644 (file)
index 0000000..88d601a
--- /dev/null
@@ -0,0 +1,56 @@
+From abdef5f5459ba1ff35e276175d9bd8348e1aba76 Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Mon, 18 Mar 2013 22:04:35 +0100
+Subject: [PATCH 0405/1302] perf tools: Final touches for CHK config move
+
+Removing no longer needed ifdefs.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369398928-9809-18-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Makefile | 11 -----------
+ 1 file changed, 11 deletions(-)
+
+diff --git a/tools/perf/Makefile b/tools/perf/Makefile
+index 240bf88..74fdd2b 100644
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -422,14 +422,6 @@ BUILTIN_OBJS += $(OUTPUT)builtin-mem.o
+ PERFLIBS = $(LIB_FILE) $(LIBLK) $(LIBTRACEEVENT)
+-#
+-# Platform specific tweaks
+-#
+-ifneq ($(MAKECMDGOALS),clean)
+-ifneq ($(MAKECMDGOALS),tags)
+-
+--include config/feature-tests.mak
+-
+ # We choose to avoid "if .. else if .. else .. endif endif"
+ # because maintaining the nesting to match is a pain.  If
+ # we had "elif" things would have been much nicer...
+@@ -519,9 +511,6 @@ ifdef ASCIIDOC8
+       export ASCIIDOC8
+ endif
+-endif # MAKECMDGOALS != tags
+-endif # MAKECMDGOALS != clean
+-
+ LIBS = -Wl,--whole-archive $(PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group
+ ALL_CFLAGS += $(BASIC_CFLAGS)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0406-perf-tests-Fix-attr-test-for-record-d-option.patch b/patches.tizen/0406-perf-tests-Fix-attr-test-for-record-d-option.patch
new file mode 100644 (file)
index 0000000..ab50f5d
--- /dev/null
@@ -0,0 +1,41 @@
+From 2d12b16cd370476c7380b6430c4b2f4674d63558 Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Fri, 24 May 2013 13:16:37 +0200
+Subject: [PATCH 0406/1302] perf tests: Fix attr test for record -d option
+
+The sample type for '-d' option is changed, because of the memory
+profiling patches from Stephane. The '-d' now adds PERF_SAMPLE_DATA_SRC
+sample_type.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369394201-20044-2-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/tests/attr/test-record-data | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/tools/perf/tests/attr/test-record-data b/tools/perf/tests/attr/test-record-data
+index 6627c3e..716e143 100644
+--- a/tools/perf/tests/attr/test-record-data
++++ b/tools/perf/tests/attr/test-record-data
+@@ -4,5 +4,8 @@ args    = -d kill >/dev/null 2>&1
+ [event:base-record]
+ sample_period=4000
+-sample_type=271
++
++# sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_TIME |
++# PERF_SAMPLE_ADDR | PERF_SAMPLE_PERIOD | PERF_SAMPLE_DATA_SRC
++sample_type=33039
+ mmap_data=1
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0407-perf-tests-Fix-exclude_guest-exclude_host-checking-f.patch b/patches.tizen/0407-perf-tests-Fix-exclude_guest-exclude_host-checking-f.patch
new file mode 100644 (file)
index 0000000..4d0a965
--- /dev/null
@@ -0,0 +1,62 @@
+From cab3f2d7ff4b4fae8c3262a0f259fb6089a0928b Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Fri, 24 May 2013 13:16:38 +0200
+Subject: [PATCH 0407/1302] perf tests: Fix exclude_guest|exclude_host checking
+ for attr tests
+
+We have a one of the event open fallback case in __perf_evsel__open
+where we zero exclude_guest|exclude_host fields.
+
+This means there's no way for attr tests to find out what's the right
+value for those fields, so we need to check for both 0 and 1. Luckily we
+still have other event parsing tests for those fields.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369394201-20044-3-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/tests/attr/base-record | 4 ++--
+ tools/perf/tests/attr/base-stat   | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/tools/perf/tests/attr/base-record b/tools/perf/tests/attr/base-record
+index b4fc835..e9bd639 100644
+--- a/tools/perf/tests/attr/base-record
++++ b/tools/perf/tests/attr/base-record
+@@ -27,8 +27,8 @@ watermark=0
+ precise_ip=0
+ mmap_data=0
+ sample_id_all=1
+-exclude_host=0
+-exclude_guest=1
++exclude_host=0|1
++exclude_guest=0|1
+ exclude_callchain_kernel=0
+ exclude_callchain_user=0
+ wakeup_events=0
+diff --git a/tools/perf/tests/attr/base-stat b/tools/perf/tests/attr/base-stat
+index 748ee94..91cd48b 100644
+--- a/tools/perf/tests/attr/base-stat
++++ b/tools/perf/tests/attr/base-stat
+@@ -27,8 +27,8 @@ watermark=0
+ precise_ip=0
+ mmap_data=0
+ sample_id_all=0
+-exclude_host=0
+-exclude_guest=1
++exclude_host=0|1
++exclude_guest=0|1
+ exclude_callchain_kernel=0
+ exclude_callchain_user=0
+ wakeup_events=0
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0408-perf-tools-Remove-frozen-from-perf_header-struct.patch b/patches.tizen/0408-perf-tools-Remove-frozen-from-perf_header-struct.patch
new file mode 100644 (file)
index 0000000..bc90106
--- /dev/null
@@ -0,0 +1,58 @@
+From 39c35c78b1c15e19e076222aae0ab76467dbdcbd Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Fri, 24 May 2013 13:16:39 +0200
+Subject: [PATCH 0408/1302] perf tools: Remove frozen from perf_header struct
+
+Removing frozen from perf_header struct as it's no longer used.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369394201-20044-4-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/util/header.c | 2 --
+ tools/perf/util/header.h | 1 -
+ 2 files changed, 3 deletions(-)
+
+diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
+index 326068a..738d3b8 100644
+--- a/tools/perf/util/header.c
++++ b/tools/perf/util/header.c
+@@ -2391,7 +2391,6 @@ out_err_write:
+       }
+       lseek(fd, header->data_offset + header->data_size, SEEK_SET);
+-      header->frozen = 1;
+       return 0;
+ }
+@@ -2871,7 +2870,6 @@ int perf_session__read_header(struct perf_session *session, int fd)
+                                                  session->pevent))
+               goto out_delete_evlist;
+-      header->frozen = 1;
+       return 0;
+ out_errno:
+       return -errno;
+diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
+index c9fc55c..16a3e83 100644
+--- a/tools/perf/util/header.h
++++ b/tools/perf/util/header.h
+@@ -84,7 +84,6 @@ struct perf_session_env {
+ };
+ struct perf_header {
+-      int                     frozen;
+       bool                    needs_swap;
+       s64                     attr_offset;
+       u64                     data_offset;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0409-perf-tools-Remove-cwdlen-from-struct-perf_session.patch b/patches.tizen/0409-perf-tools-Remove-cwdlen-from-struct-perf_session.patch
new file mode 100644 (file)
index 0000000..319ccb2
--- /dev/null
@@ -0,0 +1,37 @@
+From 2264cadbe97a468e52151cbc935a69986fdda990 Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Fri, 24 May 2013 13:16:41 +0200
+Subject: [PATCH 0409/1302] perf tools: Remove cwdlen from struct perf_session
+
+Removing cwdlen from struct perf_session as it's no longer used.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369394201-20044-6-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/util/session.h | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
+index 6b51d47a..f3b235e 100644
+--- a/tools/perf/util/session.h
++++ b/tools/perf/util/session.h
+@@ -37,7 +37,6 @@ struct perf_session {
+       int                     fd;
+       bool                    fd_pipe;
+       bool                    repipe;
+-      int                     cwdlen;
+       char                    *cwd;
+       struct ordered_samples  ordered_samples;
+       char                    filename[1];
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0410-tools-lib-lk-Respect-CROSS_COMPILE.patch b/patches.tizen/0410-tools-lib-lk-Respect-CROSS_COMPILE.patch
new file mode 100644 (file)
index 0000000..f649586
--- /dev/null
@@ -0,0 +1,34 @@
+From 312c8b226c5371dd789c1a9315b4de4a331cc4ca Mon Sep 17 00:00:00 2001
+From: Rabin Vincent <rabin@rab.in>
+Date: Fri, 17 May 2013 22:27:44 +0200
+Subject: [PATCH 0410/1302] tools lib lk: Respect CROSS_COMPILE
+
+Make lk use CROSS_COMPILE, in order to be able to cross compile perf
+again.
+
+Signed-off-by: Rabin Vincent <rabin@rab.in>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Borislav Petkov <bp@suse.de>
+Link: http://lkml.kernel.org/r/1368822464-4887-1-git-send-email-rabin@rab.in
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/lib/lk/Makefile | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/tools/lib/lk/Makefile b/tools/lib/lk/Makefile
+index 926cbf3..2c5a197 100644
+--- a/tools/lib/lk/Makefile
++++ b/tools/lib/lk/Makefile
+@@ -1,5 +1,8 @@
+ include ../../scripts/Makefile.include
++CC = $(CROSS_COMPILE)gcc
++AR = $(CROSS_COMPILE)ar
++
+ # guard against environment variables
+ LIB_H=
+ LIB_OBJS=
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0411-perf-Power7-Make-CPI-stack-events-available-in-sysfs.patch b/patches.tizen/0411-perf-Power7-Make-CPI-stack-events-available-in-sysfs.patch
new file mode 100644 (file)
index 0000000..85122c5
--- /dev/null
@@ -0,0 +1,125 @@
+From 6ea808d70edbdf4430f4a18fd55472c9e390f32b Mon Sep 17 00:00:00 2001
+From: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
+Date: Sat, 6 Apr 2013 08:48:26 -0700
+Subject: [PATCH 0411/1302] perf: Power7: Make CPI stack events available in
+ sysfs
+
+A set of Power7 events are often used for Cycles Per Instruction (CPI) stack
+analysis. Make these events available in sysfs (/sys/devices/cpu/events/) so
+they can be identified using their symbolic names:
+
+       perf stat -e 'cpu/PM_CMPLU_STALL_DCACHE_MISS/' /bin/ls
+
+Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
+Acked-by: Paul Mackerras <paulus@samba.org>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: linuxppc-dev@ozlabs.org
+Link: http://lkml.kernel.org/r/20130406164803.GA408@us.ibm.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/powerpc/perf/power7-pmu.c | 73 ++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 73 insertions(+)
+
+diff --git a/arch/powerpc/perf/power7-pmu.c b/arch/powerpc/perf/power7-pmu.c
+index 3c475d6..13c3f0e 100644
+--- a/arch/powerpc/perf/power7-pmu.c
++++ b/arch/powerpc/perf/power7-pmu.c
+@@ -62,6 +62,29 @@
+ #define       PME_PM_BRU_FIN                  0x10068
+ #define       PME_PM_BRU_MPRED                0x400f6
++#define PME_PM_CMPLU_STALL_FXU                        0x20014
++#define PME_PM_CMPLU_STALL_DIV                        0x40014
++#define PME_PM_CMPLU_STALL_SCALAR             0x40012
++#define PME_PM_CMPLU_STALL_SCALAR_LONG                0x20018
++#define PME_PM_CMPLU_STALL_VECTOR             0x2001c
++#define PME_PM_CMPLU_STALL_VECTOR_LONG                0x4004a
++#define PME_PM_CMPLU_STALL_LSU                        0x20012
++#define PME_PM_CMPLU_STALL_REJECT             0x40016
++#define PME_PM_CMPLU_STALL_ERAT_MISS          0x40018
++#define PME_PM_CMPLU_STALL_DCACHE_MISS                0x20016
++#define PME_PM_CMPLU_STALL_STORE              0x2004a
++#define PME_PM_CMPLU_STALL_THRD                       0x1001c
++#define PME_PM_CMPLU_STALL_IFU                        0x4004c
++#define PME_PM_CMPLU_STALL_BRU                        0x4004e
++#define PME_PM_GCT_NOSLOT_IC_MISS             0x2001a
++#define PME_PM_GCT_NOSLOT_BR_MPRED            0x4001a
++#define PME_PM_GCT_NOSLOT_BR_MPRED_IC_MISS    0x4001c
++#define PME_PM_GRP_CMPL                               0x30004
++#define PME_PM_1PLUS_PPC_CMPL                 0x100f2
++#define PME_PM_CMPLU_STALL_DFU                        0x2003c
++#define PME_PM_RUN_CYC                                0x200f4
++#define PME_PM_RUN_INST_CMPL                  0x400fa
++
+ /*
+  * Layout of constraint bits:
+  * 6666555555555544444444443333333333222222222211111111110000000000
+@@ -393,6 +416,31 @@ POWER_EVENT_ATTR(LD_MISS_L1,                      LD_MISS_L1);
+ POWER_EVENT_ATTR(BRU_FIN,                     BRU_FIN)
+ POWER_EVENT_ATTR(BRU_MPRED,                   BRU_MPRED);
++POWER_EVENT_ATTR(CMPLU_STALL_FXU,             CMPLU_STALL_FXU);
++POWER_EVENT_ATTR(CMPLU_STALL_DIV,             CMPLU_STALL_DIV);
++POWER_EVENT_ATTR(CMPLU_STALL_SCALAR,          CMPLU_STALL_SCALAR);
++POWER_EVENT_ATTR(CMPLU_STALL_SCALAR_LONG,     CMPLU_STALL_SCALAR_LONG);
++POWER_EVENT_ATTR(CMPLU_STALL_VECTOR,          CMPLU_STALL_VECTOR);
++POWER_EVENT_ATTR(CMPLU_STALL_VECTOR_LONG,     CMPLU_STALL_VECTOR_LONG);
++POWER_EVENT_ATTR(CMPLU_STALL_LSU,             CMPLU_STALL_LSU);
++POWER_EVENT_ATTR(CMPLU_STALL_REJECT,          CMPLU_STALL_REJECT);
++
++POWER_EVENT_ATTR(CMPLU_STALL_ERAT_MISS,               CMPLU_STALL_ERAT_MISS);
++POWER_EVENT_ATTR(CMPLU_STALL_DCACHE_MISS,     CMPLU_STALL_DCACHE_MISS);
++POWER_EVENT_ATTR(CMPLU_STALL_STORE,           CMPLU_STALL_STORE);
++POWER_EVENT_ATTR(CMPLU_STALL_THRD,            CMPLU_STALL_THRD);
++POWER_EVENT_ATTR(CMPLU_STALL_IFU,             CMPLU_STALL_IFU);
++POWER_EVENT_ATTR(CMPLU_STALL_BRU,             CMPLU_STALL_BRU);
++POWER_EVENT_ATTR(GCT_NOSLOT_IC_MISS,          GCT_NOSLOT_IC_MISS);
++
++POWER_EVENT_ATTR(GCT_NOSLOT_BR_MPRED,         GCT_NOSLOT_BR_MPRED);
++POWER_EVENT_ATTR(GCT_NOSLOT_BR_MPRED_IC_MISS, GCT_NOSLOT_BR_MPRED_IC_MISS);
++POWER_EVENT_ATTR(GRP_CMPL,                    GRP_CMPL);
++POWER_EVENT_ATTR(1PLUS_PPC_CMPL,              1PLUS_PPC_CMPL);
++POWER_EVENT_ATTR(CMPLU_STALL_DFU,             CMPLU_STALL_DFU);
++POWER_EVENT_ATTR(RUN_CYC,                     RUN_CYC);
++POWER_EVENT_ATTR(RUN_INST_CMPL,                       RUN_INST_CMPL);
++
+ static struct attribute *power7_events_attr[] = {
+       GENERIC_EVENT_PTR(CYC),
+       GENERIC_EVENT_PTR(GCT_NOSLOT_CYC),
+@@ -411,6 +459,31 @@ static struct attribute *power7_events_attr[] = {
+       POWER_EVENT_PTR(LD_MISS_L1),
+       POWER_EVENT_PTR(BRU_FIN),
+       POWER_EVENT_PTR(BRU_MPRED),
++
++      POWER_EVENT_PTR(CMPLU_STALL_FXU),
++      POWER_EVENT_PTR(CMPLU_STALL_DIV),
++      POWER_EVENT_PTR(CMPLU_STALL_SCALAR),
++      POWER_EVENT_PTR(CMPLU_STALL_SCALAR_LONG),
++      POWER_EVENT_PTR(CMPLU_STALL_VECTOR),
++      POWER_EVENT_PTR(CMPLU_STALL_VECTOR_LONG),
++      POWER_EVENT_PTR(CMPLU_STALL_LSU),
++      POWER_EVENT_PTR(CMPLU_STALL_REJECT),
++
++      POWER_EVENT_PTR(CMPLU_STALL_ERAT_MISS),
++      POWER_EVENT_PTR(CMPLU_STALL_DCACHE_MISS),
++      POWER_EVENT_PTR(CMPLU_STALL_STORE),
++      POWER_EVENT_PTR(CMPLU_STALL_THRD),
++      POWER_EVENT_PTR(CMPLU_STALL_IFU),
++      POWER_EVENT_PTR(CMPLU_STALL_BRU),
++      POWER_EVENT_PTR(GCT_NOSLOT_IC_MISS),
++      POWER_EVENT_PTR(GCT_NOSLOT_BR_MPRED),
++
++      POWER_EVENT_PTR(GCT_NOSLOT_BR_MPRED_IC_MISS),
++      POWER_EVENT_PTR(GRP_CMPL),
++      POWER_EVENT_PTR(1PLUS_PPC_CMPL),
++      POWER_EVENT_PTR(CMPLU_STALL_DFU),
++      POWER_EVENT_PTR(RUN_CYC),
++      POWER_EVENT_PTR(RUN_INST_CMPL),
+       NULL
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0412-perf-Power7-Update-testing-ABI-to-list-CPI-stack-eve.patch b/patches.tizen/0412-perf-Power7-Update-testing-ABI-to-list-CPI-stack-eve.patch
new file mode 100644 (file)
index 0000000..120314d
--- /dev/null
@@ -0,0 +1,71 @@
+From b7b61ae303eb858237bce086f4cb75ce6f9a27c4 Mon Sep 17 00:00:00 2001
+From: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
+Date: Sat, 6 Apr 2013 09:52:05 -0700
+Subject: [PATCH 0412/1302] perf: Power7 Update testing ABI to list CPI-stack
+ events
+
+Following patch added several Power7 events into /sys/devices/cpu/events.
+Document those events in the testing ABI.
+
+       https://lists.ozlabs.org/pipermail/linuxppc-dev/2013-April/105167.html
+
+Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: linuxppc-dev@ozlabs.org
+Link: http://lkml.kernel.org/r/20130406170623.GA900@us.ibm.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../testing/sysfs-bus-event_source-devices-events  | 32 ++++++++++++++++++----
+ 1 file changed, 27 insertions(+), 5 deletions(-)
+
+diff --git a/Documentation/ABI/testing/sysfs-bus-event_source-devices-events b/Documentation/ABI/testing/sysfs-bus-event_source-devices-events
+index 0adeb52..8b25ffb 100644
+--- a/Documentation/ABI/testing/sysfs-bus-event_source-devices-events
++++ b/Documentation/ABI/testing/sysfs-bus-event_source-devices-events
+@@ -27,14 +27,36 @@ Description:       Generic performance monitoring events
+               "basename".
+-What:                 /sys/devices/cpu/events/PM_LD_MISS_L1
+-              /sys/devices/cpu/events/PM_LD_REF_L1
+-              /sys/devices/cpu/events/PM_CYC
++What:                 /sys/devices/cpu/events/PM_1PLUS_PPC_CMPL
+               /sys/devices/cpu/events/PM_BRU_FIN
+-              /sys/devices/cpu/events/PM_GCT_NOSLOT_CYC
+               /sys/devices/cpu/events/PM_BRU_MPRED
+-              /sys/devices/cpu/events/PM_INST_CMPL
+               /sys/devices/cpu/events/PM_CMPLU_STALL
++              /sys/devices/cpu/events/PM_CMPLU_STALL_BRU
++              /sys/devices/cpu/events/PM_CMPLU_STALL_DCACHE_MISS
++              /sys/devices/cpu/events/PM_CMPLU_STALL_DFU
++              /sys/devices/cpu/events/PM_CMPLU_STALL_DIV
++              /sys/devices/cpu/events/PM_CMPLU_STALL_ERAT_MISS
++              /sys/devices/cpu/events/PM_CMPLU_STALL_FXU
++              /sys/devices/cpu/events/PM_CMPLU_STALL_IFU
++              /sys/devices/cpu/events/PM_CMPLU_STALL_LSU
++              /sys/devices/cpu/events/PM_CMPLU_STALL_REJECT
++              /sys/devices/cpu/events/PM_CMPLU_STALL_SCALAR
++              /sys/devices/cpu/events/PM_CMPLU_STALL_SCALAR_LONG
++              /sys/devices/cpu/events/PM_CMPLU_STALL_STORE
++              /sys/devices/cpu/events/PM_CMPLU_STALL_THRD
++              /sys/devices/cpu/events/PM_CMPLU_STALL_VECTOR
++              /sys/devices/cpu/events/PM_CMPLU_STALL_VECTOR_LONG
++              /sys/devices/cpu/events/PM_CYC
++              /sys/devices/cpu/events/PM_GCT_NOSLOT_BR_MPRED
++              /sys/devices/cpu/events/PM_GCT_NOSLOT_BR_MPRED_IC_MISS
++              /sys/devices/cpu/events/PM_GCT_NOSLOT_CYC
++              /sys/devices/cpu/events/PM_GCT_NOSLOT_IC_MISS
++              /sys/devices/cpu/events/PM_GRP_CMPL
++              /sys/devices/cpu/events/PM_INST_CMPL
++              /sys/devices/cpu/events/PM_LD_MISS_L1
++              /sys/devices/cpu/events/PM_LD_REF_L1
++              /sys/devices/cpu/events/PM_RUN_CYC
++              /sys/devices/cpu/events/PM_RUN_INST_CMPL
+ Date:         2013/01/08
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0413-perf-Expand-definition-of-sysfs-format-attribute.patch b/patches.tizen/0413-perf-Expand-definition-of-sysfs-format-attribute.patch
new file mode 100644 (file)
index 0000000..da1fe23
--- /dev/null
@@ -0,0 +1,56 @@
+From de9708f736dbd8b336f4f723b2fad2fe4ff03b61 Mon Sep 17 00:00:00 2001
+From: Michael Ellerman <michael@ellerman.id.au>
+Date: Fri, 10 May 2013 17:33:00 +0200
+Subject: [PATCH 0413/1302] perf: Expand definition of sysfs format attribute
+
+Make it explicit that the format attributes may define overlapping bit
+ranges. Unfortunately this was left unspecified originally, and all the
+examples show non-overlapping ranges. I don't believe this is an ABI
+change, as we are defining something that was previously undefined, but
+others may disagree.
+
+The POWER8 PMU would like to define overlapping ranges, as bit ranges in
+the event code have different meanings for certain events. It will also
+allow us to define an overarching "event" field, that encompasses all
+others.
+
+As far as I can see perf is comfortable with this change, however I am
+not sure if there are any other users of the interface.
+
+Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
+Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1368199980-20283-1-git-send-email-jolsa@redhat.com
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/ABI/testing/sysfs-bus-event_source-devices-format | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/Documentation/ABI/testing/sysfs-bus-event_source-devices-format b/Documentation/ABI/testing/sysfs-bus-event_source-devices-format
+index 079afc7..77f47ff 100644
+--- a/Documentation/ABI/testing/sysfs-bus-event_source-devices-format
++++ b/Documentation/ABI/testing/sysfs-bus-event_source-devices-format
+@@ -9,6 +9,12 @@ Description:
+               we want to export, so that userspace can deal with sane
+               name/value pairs.
++              Userspace must be prepared for the possibility that attributes
++              define overlapping bit ranges. For example:
++                      attr1 = 'config:0-23'
++                      attr2 = 'config:0-7'
++                      attr3 = 'config:12-35'
++
+               Example: 'config1:1,6-10,44'
+               Defines contents of attribute that occupies bits 1,6-10,44 of
+               perf_event_attr::config1.
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0414-perf-evlist-Reset-SIGTERM-handler-in-workload-child-.patch b/patches.tizen/0414-perf-evlist-Reset-SIGTERM-handler-in-workload-child-.patch
new file mode 100644 (file)
index 0000000..ef307a7
--- /dev/null
@@ -0,0 +1,49 @@
+From cc38e17ec4d4f39fe23709f0e979a2c932f7a22b Mon Sep 17 00:00:00 2001
+From: David Ahern <dsahern@gmail.com>
+Date: Sat, 25 May 2013 17:50:39 -0600
+Subject: [PATCH 0414/1302] perf evlist: Reset SIGTERM handler in workload
+ child process
+
+Jiri reported hanging perf tests on latest acme's perf/core and bisected
+it to 87f303a9f:
+
+[jolsa@krava2 perf]$ cat /proc/sys/kernel/perf_event_paranoid
+1
+[jolsa@krava2 perf]$ ./perf record -C 0 kill
+Error:
+You may not have permission to collect %sstats.
+Consider tweaking /proc/sys/kernel/perf_event_paranoid:
+ -1 - Not paranoid at all
+  0 - Disallow raw tracepoint access for unpriv
+  1 - Disallow cpu events for unpriv
+  2 - Disallow kernel profiling for unpriv
+
+Need to let default handling kickin for workload process.
+
+Reported-by: Jiri Olsa <jolsa@redhat.com>
+Signed-off-by: David Ahern <dsahern@gmail.com>
+Acked-by: Jiri Olsa <jolsa@redhat.com>
+Tested-by: Jiri Olsa <jolsa@redhat.com>
+Link: http://lkml.kernel.org/r/1369525839-1261-1-git-send-email-dsahern@gmail.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/util/evlist.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
+index f7c7278..99b43dd 100644
+--- a/tools/perf/util/evlist.c
++++ b/tools/perf/util/evlist.c
+@@ -776,6 +776,8 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist,
+               if (pipe_output)
+                       dup2(2, 1);
++              signal(SIGTERM, SIG_DFL);
++
+               close(child_ready_pipe[0]);
+               close(go_pipe[1]);
+               fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0415-perf-tools-Merge-all-CFLAGS-make-variable-into-CFLAG.patch b/patches.tizen/0415-perf-tools-Merge-all-CFLAGS-make-variable-into-CFLAG.patch
new file mode 100644 (file)
index 0000000..45db1e5
--- /dev/null
@@ -0,0 +1,542 @@
+From f96f8e447e7df63b80ae87abcfedc25cae6441d6 Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Thu, 21 Mar 2013 11:30:54 +0100
+Subject: [PATCH 0415/1302] perf tools: Merge all *CFLAGS* make variable into
+ CFLAGS
+
+Merging all *CFLAGS* make variable into CFLAGS to eliminate all special
+*_CFLAGS_* variables and make the setup clear.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369398928-9809-19-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Makefile        |  64 ++++++++++++++--------------
+ tools/perf/config/Makefile | 104 ++++++++++++++++++++++++---------------------
+ tools/perf/util/setup.py   |   5 ++-
+ 3 files changed, 89 insertions(+), 84 deletions(-)
+
+diff --git a/tools/perf/Makefile b/tools/perf/Makefile
+index 74fdd2b..58275f2 100644
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -148,7 +148,7 @@ PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources)
+ PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBTRACEEVENT)
+ $(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS)
+-      $(QUIET_GEN)CFLAGS='$(BASIC_CFLAGS)' $(PYTHON_WORD) util/setup.py \
++      $(QUIET_GEN)CFLAGS='$(CFLAGS)' $(PYTHON_WORD) util/setup.py \
+         --quiet build_ext; \
+       mkdir -p $(OUTPUT)python && \
+       cp $(PYTHON_EXTBUILD_LIB)perf.so $(OUTPUT)python/
+@@ -429,7 +429,7 @@ PERFLIBS = $(LIB_FILE) $(LIBLK) $(LIBTRACEEVENT)
+ -include arch/$(ARCH)/Makefile
+ ifneq ($(OUTPUT),)
+-      BASIC_CFLAGS += -I$(OUTPUT)
++      CFLAGS += -I$(OUTPUT)
+ endif
+ ifdef NO_LIBELF
+@@ -513,8 +513,6 @@ endif
+ LIBS = -Wl,--whole-archive $(PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group
+-ALL_CFLAGS += $(BASIC_CFLAGS)
+-ALL_CFLAGS += $(ARCH_CFLAGS)
+ ALL_LDFLAGS += $(BASIC_LDFLAGS)
+ export INSTALL SHELL_PATH
+@@ -536,20 +534,20 @@ strip: $(PROGRAMS) $(OUTPUT)perf
+ $(OUTPUT)perf.o: perf.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -include $(OUTPUT)PERF-VERSION-FILE \
+               '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
+-              $(ALL_CFLAGS) -c $(filter %.c,$^) -o $@
++              $(CFLAGS) -c $(filter %.c,$^) -o $@
+ $(OUTPUT)perf: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS)
+-      $(QUIET_LINK)$(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) $(OUTPUT)perf.o \
++      $(QUIET_LINK)$(CC) $(CFLAGS) $(ALL_LDFLAGS) $(OUTPUT)perf.o \
+                $(BUILTIN_OBJS) $(LIBS) -o $@
+ $(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
+-      $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
++      $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
+               '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
+               '-DPERF_MAN_PATH="$(mandir_SQ)"' \
+               '-DPERF_INFO_PATH="$(infodir_SQ)"' $<
+ $(OUTPUT)builtin-timechart.o: builtin-timechart.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
+-      $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
++      $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
+               '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
+               '-DPERF_MAN_PATH="$(mandir_SQ)"' \
+               '-DPERF_INFO_PATH="$(infodir_SQ)"' $<
+@@ -574,77 +572,77 @@ $(OUTPUT)perf.o perf.spec \
+ # over the general rule for .o
+ $(OUTPUT)util/%-flex.o: $(OUTPUT)util/%-flex.c $(OUTPUT)PERF-CFLAGS
+-      $(QUIET_CC)$(CC) -o $@ -c -Iutil/ $(ALL_CFLAGS) -w $<
++      $(QUIET_CC)$(CC) -o $@ -c -Iutil/ $(CFLAGS) -w $<
+ $(OUTPUT)util/%-bison.o: $(OUTPUT)util/%-bison.c $(OUTPUT)PERF-CFLAGS
+-      $(QUIET_CC)$(CC) -o $@ -c -Iutil/ $(ALL_CFLAGS) -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -w $<
++      $(QUIET_CC)$(CC) -o $@ -c -Iutil/ $(CFLAGS) -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -w $<
+ $(OUTPUT)%.o: %.c $(OUTPUT)PERF-CFLAGS
+-      $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $<
++      $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $<
+ $(OUTPUT)%.i: %.c $(OUTPUT)PERF-CFLAGS
+-      $(QUIET_CC)$(CC) -o $@ -E $(ALL_CFLAGS) $<
++      $(QUIET_CC)$(CC) -o $@ -E $(CFLAGS) $<
+ $(OUTPUT)%.s: %.c $(OUTPUT)PERF-CFLAGS
+-      $(QUIET_CC)$(CC) -o $@ -S $(ALL_CFLAGS) $<
++      $(QUIET_CC)$(CC) -o $@ -S $(CFLAGS) $<
+ $(OUTPUT)%.o: %.S
+-      $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $<
++      $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $<
+ $(OUTPUT)%.s: %.S
+-      $(QUIET_CC)$(CC) -o $@ -E $(ALL_CFLAGS) $<
++      $(QUIET_CC)$(CC) -o $@ -E $(CFLAGS) $<
+ $(OUTPUT)util/exec_cmd.o: util/exec_cmd.c $(OUTPUT)PERF-CFLAGS
+-      $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
++      $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
+               '-DPERF_EXEC_PATH="$(perfexecdir_SQ)"' \
+               '-DPREFIX="$(prefix_SQ)"' \
+               $<
+ $(OUTPUT)tests/attr.o: tests/attr.c $(OUTPUT)PERF-CFLAGS
+-      $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
++      $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
+               '-DBINDIR="$(bindir_SQ)"' -DPYTHON='"$(PYTHON_WORD)"' \
+               $<
+ $(OUTPUT)tests/python-use.o: tests/python-use.c $(OUTPUT)PERF-CFLAGS
+-      $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
++      $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
+               -DPYTHONPATH='"$(OUTPUT)python"' \
+               -DPYTHON='"$(PYTHON_WORD)"' \
+               $<
+ $(OUTPUT)util/config.o: util/config.c $(OUTPUT)PERF-CFLAGS
+-      $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
++      $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
+ $(OUTPUT)ui/browser.o: ui/browser.c $(OUTPUT)PERF-CFLAGS
+-      $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
++      $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
+ $(OUTPUT)ui/browsers/annotate.o: ui/browsers/annotate.c $(OUTPUT)PERF-CFLAGS
+-      $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
++      $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
+ $(OUTPUT)ui/browsers/hists.o: ui/browsers/hists.c $(OUTPUT)PERF-CFLAGS
+-      $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
++      $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
+ $(OUTPUT)ui/browsers/map.o: ui/browsers/map.c $(OUTPUT)PERF-CFLAGS
+-      $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
++      $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
+ $(OUTPUT)ui/browsers/scripts.o: ui/browsers/scripts.c $(OUTPUT)PERF-CFLAGS
+-      $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
++      $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
+ $(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
+-      $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
++      $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
+ $(OUTPUT)util/parse-events.o: util/parse-events.c $(OUTPUT)PERF-CFLAGS
+-      $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -Wno-redundant-decls $<
++      $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-redundant-decls $<
+ $(OUTPUT)util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c $(OUTPUT)PERF-CFLAGS
+-      $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
++      $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
+ $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS
+-      $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
++      $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
+ $(OUTPUT)util/scripting-engines/trace-event-python.o: util/scripting-engines/trace-event-python.c $(OUTPUT)PERF-CFLAGS
+-      $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
++      $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
+ $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o: scripts/python/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS
+-      $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
++      $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
+ $(OUTPUT)perf-%: %.o $(PERFLIBS)
+-      $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
++      $(QUIET_LINK)$(CC) $(CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
+ $(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
+ $(patsubst perf-%,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
+@@ -731,7 +729,7 @@ cscope:
+       $(FIND) . -name '*.[hcS]' -print | xargs cscope -b
+ ### Detect prefix changes
+-TRACK_CFLAGS = $(subst ','\'',$(ALL_CFLAGS)):\
++TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):\
+              $(bindir_SQ):$(perfexecdir_SQ):$(template_dir_SQ):$(prefix_SQ)
+ $(OUTPUT)PERF-CFLAGS: .FORCE-PERF-CFLAGS
+@@ -752,7 +750,7 @@ check: $(OUTPUT)common-cmds.h
+       then \
+               for i in *.c */*.c; \
+               do \
+-                      sparse $(ALL_CFLAGS) $(SPARSE_FLAGS) $$i || exit; \
++                      sparse $(CFLAGS) $(SPARSE_FLAGS) $$i || exit; \
+               done; \
+       else \
+               exit 1; \
+diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
+index 506c479..a53d2b3 100644
+--- a/tools/perf/config/Makefile
++++ b/tools/perf/config/Makefile
+@@ -6,6 +6,7 @@ ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
+                                 -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
+                                 -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ )
+ NO_PERF_REGS := 1
++CFLAGS := $(EXTRA_CFLAGS) $(EXTRA_WARNINGS)
+ # Additional ARCH settings for x86
+ ifeq ($(ARCH),i386)
+@@ -17,12 +18,12 @@ endif
+ ifeq ($(ARCH),x86_64)
+       override ARCH := x86
+       IS_X86_64 := 0
+-      ifeq (, $(findstring m32,$(EXTRA_CFLAGS)))
++      ifeq (, $(findstring m32,$(CFLAGS)))
+               IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -x c - | tail -n 1)
+       endif
+       ifeq (${IS_X86_64}, 1)
+               RAW_ARCH := x86_64
+-              ARCH_CFLAGS := -DARCH_X86_64
++              CFLAGS += -DARCH_X86_64
+               ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S
+       endif
+       NO_PERF_REGS := 0
+@@ -30,7 +31,7 @@ ifeq ($(ARCH),x86_64)
+ endif
+ ifeq ($(NO_PERF_REGS),0)
+-        BASIC_CFLAGS += -DHAVE_PERF_REGS
++        CFLAGS += -DHAVE_PERF_REGS
+ endif
+ -include config/feature-tests.mak
+@@ -45,46 +46,52 @@ endif
+ # Treat warnings as errors unless directed not to
+ ifneq ($(WERROR),0)
+-      CFLAGS_WERROR := -Werror
++      CFLAGS += -Werror
+ endif
+ ifeq ("$(origin DEBUG)", "command line")
+       PERF_DEBUG = $(DEBUG)
+ endif
+ ifndef PERF_DEBUG
+-      CFLAGS_OPTIMIZE = -O6
++      CFLAGS += -O6
+ endif
+ ifdef PARSER_DEBUG
+-      PARSER_DEBUG_BISON  := -t
+-      PARSER_DEBUG_FLEX   := -d
+-      PARSER_DEBUG_CFLAGS := -DPARSER_DEBUG
++      PARSER_DEBUG_BISON := -t
++      PARSER_DEBUG_FLEX  := -d
++      CFLAGS             += -DPARSER_DEBUG
+ endif
+-CFLAGS = -fno-omit-frame-pointer -ggdb3 -funwind-tables -Wall -Wextra -std=gnu99 $(CFLAGS_WERROR) $(CFLAGS_OPTIMIZE) $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) $(PARSER_DEBUG_CFLAGS)
++CFLAGS += \
++      -fno-omit-frame-pointer \
++      -ggdb3 \
++      -funwind-tables \
++      -Wall \
++      -Wextra \
++      -std=gnu99
++
+ EXTLIBS = -lpthread -lrt -lelf -lm
+-ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
+ ALL_LDFLAGS = $(LDFLAGS)
+ ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y)
+-      CFLAGS := $(CFLAGS) -fstack-protector-all
++      CFLAGS += -fstack-protector-all
+ endif
+ ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wstack-protector,-Wstack-protector),y)
+-      CFLAGS := $(CFLAGS) -Wstack-protector
++      CFLAGS += -Wstack-protector
+ endif
+ ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wvolatile-register-var,-Wvolatile-register-var),y)
+-      CFLAGS := $(CFLAGS) -Wvolatile-register-var
++      CFLAGS += -Wvolatile-register-var
+ endif
+ ifndef PERF_DEBUG
+       ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -D_FORTIFY_SOURCE=2,-D_FORTIFY_SOURCE=2),y)
+-              CFLAGS := $(CFLAGS) -D_FORTIFY_SOURCE=2
++              CFLAGS += -D_FORTIFY_SOURCE=2
+       endif
+ endif
+-BASIC_CFLAGS += \
++CFLAGS += \
+       -Iutil/include \
+       -Iarch/$(ARCH)/include \
+       $(if $(objtree),-I$(objtree)/arch/$(ARCH)/include/generated/uapi) \
+@@ -106,7 +113,6 @@ ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS),bionic),y)
+       BIONIC := 1
+       EXTLIBS := $(filter-out -lrt,$(EXTLIBS))
+       EXTLIBS := $(filter-out -lpthread,$(EXTLIBS))
+-      BASIC_CFLAGS += -I.
+ endif
+ ifdef NO_LIBELF
+@@ -114,9 +120,9 @@ ifdef NO_LIBELF
+       NO_DEMANGLE := 1
+       NO_LIBUNWIND := 1
+ else
+-FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
++FLAGS_LIBELF=$(CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
+ ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF),libelf),y)
+-      FLAGS_GLIBC=$(ALL_CFLAGS) $(ALL_LDFLAGS)
++      FLAGS_GLIBC=$(CFLAGS) $(ALL_LDFLAGS)
+       ifeq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC),glibc),y)
+               LIBC_SUPPORT := 1
+       endif
+@@ -140,7 +146,7 @@ else
+               LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib
+       endif
+-      FLAGS_DWARF=$(ALL_CFLAGS) $(LIBDW_CFLAGS) -ldw -lelf $(LIBDW_LDFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
++      FLAGS_DWARF=$(CFLAGS) $(LIBDW_CFLAGS) -ldw -lelf $(LIBDW_LDFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
+       ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF),libdw),y)
+               msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
+               NO_DWARF := 1
+@@ -149,10 +155,10 @@ endif # SOURCE_LIBELF
+ endif # NO_LIBELF
+ ifndef NO_LIBELF
+-BASIC_CFLAGS += -DLIBELF_SUPPORT
+-FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
++CFLAGS += -DLIBELF_SUPPORT
++FLAGS_LIBELF=$(CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
+ ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
+-      BASIC_CFLAGS += -DLIBELF_MMAP
++      CFLAGS += -DLIBELF_MMAP
+ endif
+ # include ARCH specific config
+@@ -163,7 +169,7 @@ ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
+       msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled);
+       NO_DWARF := 1
+ else
+-      BASIC_CFLAGS := -DDWARF_SUPPORT $(LIBDW_CFLAGS) $(BASIC_CFLAGS)
++      CFLAGS += -DDWARF_SUPPORT $(LIBDW_CFLAGS)
+       BASIC_LDFLAGS := $(LIBDW_LDFLAGS) $(BASIC_LDFLAGS)
+       EXTLIBS += -lelf -ldw
+ endif # PERF_HAVE_DWARF_REGS
+@@ -184,7 +190,7 @@ ifdef LIBUNWIND_DIR
+       LIBUNWIND_LDFLAGS := -L$(LIBUNWIND_DIR)/lib
+ endif
+-FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(ALL_CFLAGS) $(LIBUNWIND_LDFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS)
++FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(CFLAGS) $(LIBUNWIND_LDFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS)
+ ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND),libunwind),y)
+       msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99);
+       NO_LIBUNWIND := 1
+@@ -192,19 +198,19 @@ endif # Libunwind support
+ endif # NO_LIBUNWIND
+ ifndef NO_LIBUNWIND
+-      BASIC_CFLAGS += -DLIBUNWIND_SUPPORT
++      CFLAGS += -DLIBUNWIND_SUPPORT
+       EXTLIBS += $(LIBUNWIND_LIBS)
+-      BASIC_CFLAGS := $(LIBUNWIND_CFLAGS) $(BASIC_CFLAGS)
++      CFLAGS += $(LIBUNWIND_CFLAGS)
+       BASIC_LDFLAGS := $(LIBUNWIND_LDFLAGS) $(BASIC_LDFLAGS)
+ endif # NO_LIBUNWIND
+ ifndef NO_LIBAUDIT
+-      FLAGS_LIBAUDIT = $(ALL_CFLAGS) $(ALL_LDFLAGS) -laudit
++      FLAGS_LIBAUDIT = $(CFLAGS) $(ALL_LDFLAGS) -laudit
+       ifneq ($(call try-cc,$(SOURCE_LIBAUDIT),$(FLAGS_LIBAUDIT),libaudit),y)
+               msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev);
+               NO_LIBAUDIT := 1
+       else
+-              BASIC_CFLAGS += -DLIBAUDIT_SUPPORT
++              CFLAGS += -DLIBAUDIT_SUPPORT
+               EXTLIBS += -laudit
+       endif
+ endif
+@@ -214,29 +220,29 @@ ifdef NO_NEWT
+ endif
+ ifndef NO_SLANG
+-      FLAGS_SLANG=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -I/usr/include/slang -lslang
++      FLAGS_SLANG=$(CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -I/usr/include/slang -lslang
+       ifneq ($(call try-cc,$(SOURCE_SLANG),$(FLAGS_SLANG),libslang),y)
+               msg := $(warning slang not found, disables TUI support. Please install slang-devel or libslang-dev);
+               NO_SLANG := 1
+       else
+               # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h
+-              BASIC_CFLAGS += -I/usr/include/slang
+-              BASIC_CFLAGS += -DSLANG_SUPPORT
++              CFLAGS += -I/usr/include/slang
++              CFLAGS += -DSLANG_SUPPORT
+               EXTLIBS += -lslang
+       endif
+ endif
+ ifndef NO_GTK2
+-      FLAGS_GTK2=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
++      FLAGS_GTK2=$(CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
+       ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2),gtk2),y)
+               msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev);
+               NO_GTK2 := 1
+       else
+               ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2),-DHAVE_GTK_INFO_BAR),y)
+-                      BASIC_CFLAGS += -DHAVE_GTK_INFO_BAR
++                      CFLAGS += -DHAVE_GTK_INFO_BAR
+               endif
+-              BASIC_CFLAGS += -DGTK2_SUPPORT
+-              BASIC_CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null)
++              CFLAGS += -DGTK2_SUPPORT
++              CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null)
+               EXTLIBS += $(shell pkg-config --libs gtk+-2.0 2>/dev/null)
+       endif
+ endif
+@@ -245,7 +251,7 @@ grep-libs  = $(filter -l%,$(1))
+ strip-libs = $(filter-out -l%,$(1))
+ ifdef NO_LIBPERL
+-      BASIC_CFLAGS += -DNO_LIBPERL
++      CFLAGS += -DNO_LIBPERL
+ else
+       PERL_EMBED_LDOPTS = $(shell perl -MExtUtils::Embed -e ldopts 2>/dev/null)
+       PERL_EMBED_LDFLAGS = $(call strip-libs,$(PERL_EMBED_LDOPTS))
+@@ -254,7 +260,7 @@ else
+       FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS)
+       ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED),perl),y)
+-              BASIC_CFLAGS += -DNO_LIBPERL
++              CFLAGS += -DNO_LIBPERL
+               NO_LIBPERL := 1
+       else
+               ALL_LDFLAGS += $(PERL_EMBED_LDFLAGS)
+@@ -264,7 +270,7 @@ endif
+ disable-python = $(eval $(disable-python_code))
+ define disable-python_code
+-  BASIC_CFLAGS += -DNO_LIBPYTHON
++  CFLAGS += -DNO_LIBPYTHON
+   $(if $(1),$(warning No $(1) was found))
+   $(warning Python support will not be built)
+   NO_LIBPYTHON := 1
+@@ -326,13 +332,13 @@ else
+ endif
+ ifdef NO_DEMANGLE
+-      BASIC_CFLAGS += -DNO_DEMANGLE
++      CFLAGS += -DNO_DEMANGLE
+ else
+       ifdef HAVE_CPLUS_DEMANGLE
+               EXTLIBS += -liberty
+-              BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
++              CFLAGS += -DHAVE_CPLUS_DEMANGLE
+       else
+-              FLAGS_BFD=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -DPACKAGE='perf' -lbfd
++              FLAGS_BFD=$(CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -DPACKAGE='perf' -lbfd
+               has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD),libbfd)
+               ifeq ($(has_bfd),y)
+                       EXTLIBS += -lbfd
+@@ -347,14 +353,14 @@ else
+                               ifeq ($(has_bfd_iberty_z),y)
+                                       EXTLIBS += -lbfd -liberty -lz
+                               else
+-                                      FLAGS_CPLUS_DEMANGLE=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -liberty
++                                      FLAGS_CPLUS_DEMANGLE=$(CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -liberty
+                                       has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE),demangle)
+                                       ifeq ($(has_cplus_demangle),y)
+                                               EXTLIBS += -liberty
+-                                              BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
++                                              CFLAGS += -DHAVE_CPLUS_DEMANGLE
+                                       else
+                                               msg := $(warning No bfd.h/libbfd found, install binutils-dev[el]/zlib-static to gain symbol demangling)
+-                                              BASIC_CFLAGS += -DNO_DEMANGLE
++                                              CFLAGS += -DNO_DEMANGLE
+                                       endif
+                               endif
+                       endif
+@@ -364,29 +370,29 @@ endif
+ ifndef NO_STRLCPY
+       ifeq ($(call try-cc,$(SOURCE_STRLCPY),,-DHAVE_STRLCPY),y)
+-              BASIC_CFLAGS += -DHAVE_STRLCPY
++              CFLAGS += -DHAVE_STRLCPY
+       endif
+ endif
+ ifndef NO_ON_EXIT
+       ifeq ($(call try-cc,$(SOURCE_ON_EXIT),,-DHAVE_ON_EXIT),y)
+-              BASIC_CFLAGS += -DHAVE_ON_EXIT
++              CFLAGS += -DHAVE_ON_EXIT
+       endif
+ endif
+ ifndef NO_BACKTRACE
+        ifeq ($(call try-cc,$(SOURCE_BACKTRACE),,-DBACKTRACE_SUPPORT),y)
+-              BASIC_CFLAGS += -DBACKTRACE_SUPPORT
++              CFLAGS += -DBACKTRACE_SUPPORT
+        endif
+ endif
+ ifndef NO_LIBNUMA
+-      FLAGS_LIBNUMA = $(ALL_CFLAGS) $(ALL_LDFLAGS) -lnuma
++      FLAGS_LIBNUMA = $(CFLAGS) $(ALL_LDFLAGS) -lnuma
+       ifneq ($(call try-cc,$(SOURCE_LIBNUMA),$(FLAGS_LIBNUMA),libnuma),y)
+               msg := $(warning No numa.h found, disables 'perf bench numa mem' benchmark, please install numa-libs-devel or libnuma-dev);
+               NO_LIBNUMA := 1
+       else
+-              BASIC_CFLAGS += -DLIBNUMA_SUPPORT
++              CFLAGS += -DLIBNUMA_SUPPORT
+               EXTLIBS += -lnuma
+       endif
+ endif
+diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py
+index 6b0ed32..58ea5ca 100644
+--- a/tools/perf/util/setup.py
++++ b/tools/perf/util/setup.py
+@@ -18,8 +18,9 @@ class install_lib(_install_lib):
+         self.build_dir = build_lib
+-cflags = ['-fno-strict-aliasing', '-Wno-write-strings']
+-cflags += getenv('CFLAGS', '').split()
++cflags = getenv('CFLAGS', '').split()
++# switch off several checks (need to be at the end of cflags list)
++cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter' ]
+ build_lib = getenv('PYTHON_EXTBUILD_LIB')
+ build_tmp = getenv('PYTHON_EXTBUILD_TMP')
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0416-perf-tools-Merge-all-LDFLAGS-make-variable-into-LDFL.patch b/patches.tizen/0416-perf-tools-Merge-all-LDFLAGS-make-variable-into-LDFL.patch
new file mode 100644 (file)
index 0000000..302d393
--- /dev/null
@@ -0,0 +1,221 @@
+From 768aa4ea81d6155888b81e240b5a57e7192f84ec Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Thu, 21 Mar 2013 11:41:05 +0100
+Subject: [PATCH 0416/1302] perf tools: Merge all *LDFLAGS* make variable into
+ LDFLAGS
+
+Merging all *LDFLAGS* make variable into LDFLAGS to eliminate all
+special *LDFLAGS* variables and make the setup clear.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369398928-9809-20-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Makefile        |  6 ++----
+ tools/perf/config/Makefile | 41 +++++++++++++++++++++++------------------
+ 2 files changed, 25 insertions(+), 22 deletions(-)
+
+diff --git a/tools/perf/Makefile b/tools/perf/Makefile
+index 58275f2..1a3557c 100644
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -513,8 +513,6 @@ endif
+ LIBS = -Wl,--whole-archive $(PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group
+-ALL_LDFLAGS += $(BASIC_LDFLAGS)
+-
+ export INSTALL SHELL_PATH
+ ### Build rules
+@@ -537,7 +535,7 @@ $(OUTPUT)perf.o: perf.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
+               $(CFLAGS) -c $(filter %.c,$^) -o $@
+ $(OUTPUT)perf: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS)
+-      $(QUIET_LINK)$(CC) $(CFLAGS) $(ALL_LDFLAGS) $(OUTPUT)perf.o \
++      $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(OUTPUT)perf.o \
+                $(BUILTIN_OBJS) $(LIBS) -o $@
+ $(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
+@@ -642,7 +640,7 @@ $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o: scripts/python/Perf-Trace-Uti
+       $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
+ $(OUTPUT)perf-%: %.o $(PERFLIBS)
+-      $(QUIET_LINK)$(CC) $(CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
++      $(QUIET_LINK)$(CC) $(CFLAGS) -o $@ $(LDFLAGS) $(filter %.o,$^) $(LIBS)
+ $(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
+ $(patsubst perf-%,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
+diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
+index a53d2b3..c6e4902 100644
+--- a/tools/perf/config/Makefile
++++ b/tools/perf/config/Makefile
+@@ -71,7 +71,6 @@ CFLAGS += \
+       -std=gnu99
+ EXTLIBS = -lpthread -lrt -lelf -lm
+-ALL_LDFLAGS = $(LDFLAGS)
+ ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y)
+       CFLAGS += -fstack-protector-all
+@@ -107,8 +106,6 @@ CFLAGS += \
+       -I../lib/ \
+       -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
+-BASIC_LDFLAGS =
+-
+ ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS),bionic),y)
+       BIONIC := 1
+       EXTLIBS := $(filter-out -lrt,$(EXTLIBS))
+@@ -120,9 +117,9 @@ ifdef NO_LIBELF
+       NO_DEMANGLE := 1
+       NO_LIBUNWIND := 1
+ else
+-FLAGS_LIBELF=$(CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
++FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS)
+ ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF),libelf),y)
+-      FLAGS_GLIBC=$(CFLAGS) $(ALL_LDFLAGS)
++      FLAGS_GLIBC=$(CFLAGS) $(LDFLAGS)
+       ifeq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC),glibc),y)
+               LIBC_SUPPORT := 1
+       endif
+@@ -146,7 +143,7 @@ else
+               LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib
+       endif
+-      FLAGS_DWARF=$(CFLAGS) $(LIBDW_CFLAGS) -ldw -lelf $(LIBDW_LDFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
++      FLAGS_DWARF=$(CFLAGS) $(LIBDW_CFLAGS) -ldw -lelf $(LIBDW_LDFLAGS) $(LDFLAGS) $(EXTLIBS)
+       ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF),libdw),y)
+               msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
+               NO_DWARF := 1
+@@ -156,7 +153,7 @@ endif # NO_LIBELF
+ ifndef NO_LIBELF
+ CFLAGS += -DLIBELF_SUPPORT
+-FLAGS_LIBELF=$(CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
++FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS)
+ ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
+       CFLAGS += -DLIBELF_MMAP
+ endif
+@@ -170,13 +167,21 @@ ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
+       NO_DWARF := 1
+ else
+       CFLAGS += -DDWARF_SUPPORT $(LIBDW_CFLAGS)
+-      BASIC_LDFLAGS := $(LIBDW_LDFLAGS) $(BASIC_LDFLAGS)
++      LDFLAGS += $(LIBDW_LDFLAGS)
+       EXTLIBS += -lelf -ldw
+ endif # PERF_HAVE_DWARF_REGS
+ endif # NO_DWARF
+ endif # NO_LIBELF
++ifndef NO_LIBELF
++CFLAGS += -DLIBELF_SUPPORT
++FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS)
++ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
++      CFLAGS += -DLIBELF_MMAP
++endif # try-cc
++endif # NO_LIBELF
++
+ # There's only x86 (both 32 and 64) support for CFI unwind so far
+ ifneq ($(ARCH),x86)
+       NO_LIBUNWIND := 1
+@@ -190,7 +195,7 @@ ifdef LIBUNWIND_DIR
+       LIBUNWIND_LDFLAGS := -L$(LIBUNWIND_DIR)/lib
+ endif
+-FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(CFLAGS) $(LIBUNWIND_LDFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS)
++FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(CFLAGS) $(LIBUNWIND_LDFLAGS) $(LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS)
+ ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND),libunwind),y)
+       msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99);
+       NO_LIBUNWIND := 1
+@@ -201,11 +206,11 @@ ifndef NO_LIBUNWIND
+       CFLAGS += -DLIBUNWIND_SUPPORT
+       EXTLIBS += $(LIBUNWIND_LIBS)
+       CFLAGS += $(LIBUNWIND_CFLAGS)
+-      BASIC_LDFLAGS := $(LIBUNWIND_LDFLAGS) $(BASIC_LDFLAGS)
++      LDFLAGS += $(LIBUNWIND_LDFLAGS)
+ endif # NO_LIBUNWIND
+ ifndef NO_LIBAUDIT
+-      FLAGS_LIBAUDIT = $(CFLAGS) $(ALL_LDFLAGS) -laudit
++      FLAGS_LIBAUDIT = $(CFLAGS) $(LDFLAGS) -laudit
+       ifneq ($(call try-cc,$(SOURCE_LIBAUDIT),$(FLAGS_LIBAUDIT),libaudit),y)
+               msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev);
+               NO_LIBAUDIT := 1
+@@ -220,7 +225,7 @@ ifdef NO_NEWT
+ endif
+ ifndef NO_SLANG
+-      FLAGS_SLANG=$(CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -I/usr/include/slang -lslang
++      FLAGS_SLANG=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -I/usr/include/slang -lslang
+       ifneq ($(call try-cc,$(SOURCE_SLANG),$(FLAGS_SLANG),libslang),y)
+               msg := $(warning slang not found, disables TUI support. Please install slang-devel or libslang-dev);
+               NO_SLANG := 1
+@@ -233,7 +238,7 @@ ifndef NO_SLANG
+ endif
+ ifndef NO_GTK2
+-      FLAGS_GTK2=$(CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
++      FLAGS_GTK2=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
+       ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2),gtk2),y)
+               msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev);
+               NO_GTK2 := 1
+@@ -263,7 +268,7 @@ else
+               CFLAGS += -DNO_LIBPERL
+               NO_LIBPERL := 1
+       else
+-              ALL_LDFLAGS += $(PERL_EMBED_LDFLAGS)
++              LDFLAGS += $(PERL_EMBED_LDFLAGS)
+               EXTLIBS += $(PERL_EMBED_LIBADD)
+       endif
+ endif
+@@ -322,7 +327,7 @@ else
+           $(warning $(and ,))
+           $(error   $(and ,))
+         else
+-          ALL_LDFLAGS += $(PYTHON_EMBED_LDFLAGS)
++          LDFLAGS += $(PYTHON_EMBED_LDFLAGS)
+           EXTLIBS += $(PYTHON_EMBED_LIBADD)
+           LANG_BINDINGS += $(OUTPUT)python/perf.so
+         endif
+@@ -338,7 +343,7 @@ else
+               EXTLIBS += -liberty
+               CFLAGS += -DHAVE_CPLUS_DEMANGLE
+       else
+-              FLAGS_BFD=$(CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -DPACKAGE='perf' -lbfd
++              FLAGS_BFD=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -DPACKAGE='perf' -lbfd
+               has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD),libbfd)
+               ifeq ($(has_bfd),y)
+                       EXTLIBS += -lbfd
+@@ -353,7 +358,7 @@ else
+                               ifeq ($(has_bfd_iberty_z),y)
+                                       EXTLIBS += -lbfd -liberty -lz
+                               else
+-                                      FLAGS_CPLUS_DEMANGLE=$(CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -liberty
++                                      FLAGS_CPLUS_DEMANGLE=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -liberty
+                                       has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE),demangle)
+                                       ifeq ($(has_cplus_demangle),y)
+                                               EXTLIBS += -liberty
+@@ -387,7 +392,7 @@ ifndef NO_BACKTRACE
+ endif
+ ifndef NO_LIBNUMA
+-      FLAGS_LIBNUMA = $(CFLAGS) $(ALL_LDFLAGS) -lnuma
++      FLAGS_LIBNUMA = $(CFLAGS) $(LDFLAGS) -lnuma
+       ifneq ($(call try-cc,$(SOURCE_LIBNUMA),$(FLAGS_LIBNUMA),libnuma),y)
+               msg := $(warning No numa.h found, disables 'perf bench numa mem' benchmark, please install numa-libs-devel or libnuma-dev);
+               NO_LIBNUMA := 1
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0417-perf-tools-Switch-to-full-path-C-include-directories.patch b/patches.tizen/0417-perf-tools-Switch-to-full-path-C-include-directories.patch
new file mode 100644 (file)
index 0000000..d1e8050
--- /dev/null
@@ -0,0 +1,131 @@
+From 2fa9ec50d14edc66e912dd26003bb885e1cea48e Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Fri, 24 May 2013 14:35:23 +0200
+Subject: [PATCH 0417/1302] perf tools: Switch to full path C include
+ directories
+
+Switching to full path C include directories, to make the includes
+clear. Plus little include cleanup.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369398928-9809-21-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Makefile        |  4 ++--
+ tools/perf/config/Makefile | 49 ++++++++++++++++++++++++++++++++++------------
+ 2 files changed, 39 insertions(+), 14 deletions(-)
+
+diff --git a/tools/perf/Makefile b/tools/perf/Makefile
+index 1a3557c..4275ddc 100644
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -80,8 +80,8 @@ FLEX    = flex
+ BISON   = bison
+ STRIP  ?= strip
+-LK_DIR = ../lib/lk/
+-TRACE_EVENT_DIR = ../lib/traceevent/
++LK_DIR          = $(srctree)/tools/lib/lk/
++TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/
+ # include config/Makefile by default and rule out
+ # non-config cases
+diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
+index c6e4902..8762209 100644
+--- a/tools/perf/config/Makefile
++++ b/tools/perf/config/Makefile
+@@ -34,7 +34,23 @@ ifeq ($(NO_PERF_REGS),0)
+         CFLAGS += -DHAVE_PERF_REGS
+ endif
+--include config/feature-tests.mak
++ifeq ($(src-perf),)
++src-perf := $(srctree)/tools/perf
++endif
++
++ifeq ($(obj-perf),)
++obj-perf := $(objtree)
++endif
++
++ifneq ($(obj-perf),)
++obj-perf := $(abspath $(obj-perf))/
++endif
++
++# include ARCH specific config
++-include $(src-perf)/arch/$(ARCH)/Makefile
++
++include $(src-perf)/config/feature-tests.mak
++include $(src-perf)/config/utilities.mak
+ ifeq ($(call get-executable,$(FLEX)),)
+       dummy := $(error Error: $(FLEX) is missing on this system, please install it)
+@@ -91,19 +107,28 @@ ifndef PERF_DEBUG
+ endif
+ CFLAGS += \
+-      -Iutil/include \
+-      -Iarch/$(ARCH)/include \
+-      $(if $(objtree),-I$(objtree)/arch/$(ARCH)/include/generated/uapi) \
++      -I$(src-perf)/util/include \
++      -I$(src-perf)/arch/$(ARCH)/include \
+       -I$(srctree)/arch/$(ARCH)/include/uapi \
+       -I$(srctree)/arch/$(ARCH)/include \
+-      $(if $(objtree),-I$(objtree)/include/generated/uapi) \
+       -I$(srctree)/include/uapi \
+-      -I$(srctree)/include \
+-      -I$(OUTPUT)util \
+-      -Iutil \
+-      -I. \
++      -I$(srctree)/include
++
++# $(obj-perf)      for generated common-cmds.h
++# $(obj-perf)/util for generated bison/flex headers
++ifneq ($(OUTPUT),)
++CFLAGS += \
++      -I$(obj-perf)/util \
++      -I$(obj-perf)
++endif
++
++CFLAGS += \
++      -I$(src-perf)/util \
++      -I$(src-perf) \
+       -I$(TRACE_EVENT_DIR) \
+-      -I../lib/ \
++      -I$(srctree)/tools/lib/
++
++CFLAGS += \
+       -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
+ ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS),bionic),y)
+@@ -159,7 +184,7 @@ ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
+ endif
+ # include ARCH specific config
+--include arch/$(ARCH)/Makefile
++-include $(src-perf)/arch/$(ARCH)/Makefile
+ ifndef NO_DWARF
+ ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
+@@ -329,7 +354,7 @@ else
+         else
+           LDFLAGS += $(PYTHON_EMBED_LDFLAGS)
+           EXTLIBS += $(PYTHON_EMBED_LIBADD)
+-          LANG_BINDINGS += $(OUTPUT)python/perf.so
++          LANG_BINDINGS += $(obj-perf)python/perf.so
+         endif
+       endif
+     endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0418-perf-tools-Add-NO_BIONIC-variable-to-confiure-bionic.patch b/patches.tizen/0418-perf-tools-Add-NO_BIONIC-variable-to-confiure-bionic.patch
new file mode 100644 (file)
index 0000000..729078b
--- /dev/null
@@ -0,0 +1,63 @@
+From bfa6cd5d8d6792677f1dc2e3cf6081ceee40311c Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Fri, 24 May 2013 14:35:24 +0200
+Subject: [PATCH 0418/1302] perf tools: Add NO_BIONIC variable to confiure
+ bionic setup
+
+Adding NO_BIONIC variable to confiure bionic setup
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369398928-9809-22-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Makefile        | 4 ++++
+ tools/perf/config/Makefile | 2 ++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/tools/perf/Makefile b/tools/perf/Makefile
+index 4275ddc..8f50afe 100644
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -51,6 +51,10 @@ include config/utilities.mak
+ # Define NO_BACKTRACE if you do not want stack backtrace debug feature
+ #
+ # Define NO_LIBNUMA if you do not want numa perf benchmark
++#
++# Define NO_LIBAUDIT if you do not want libaudit support
++#
++# Define NO_LIBBIONIC if you do not want bionic support
+ ifeq ($(srctree),)
+ srctree := $(patsubst %/,%,$(dir $(shell pwd)))
+diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
+index 8762209..cc464f1 100644
+--- a/tools/perf/config/Makefile
++++ b/tools/perf/config/Makefile
+@@ -131,11 +131,13 @@ CFLAGS += \
+ CFLAGS += \
+       -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
++ifndef NO_BIONIC
+ ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS),bionic),y)
+       BIONIC := 1
+       EXTLIBS := $(filter-out -lrt,$(EXTLIBS))
+       EXTLIBS := $(filter-out -lpthread,$(EXTLIBS))
+ endif
++endif # NO_BIONIC
+ ifdef NO_LIBELF
+       NO_DWARF := 1
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0419-perf-tools-Replace-tabs-with-spaces-for-all-non-comm.patch b/patches.tizen/0419-perf-tools-Replace-tabs-with-spaces-for-all-non-comm.patch
new file mode 100644 (file)
index 0000000..00993b0
--- /dev/null
@@ -0,0 +1,737 @@
+From 5b3f18b8425232bfea9a951c8385b1300e2f661f Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Mon, 15 Apr 2013 04:06:58 +0200
+Subject: [PATCH 0419/1302] perf tools: Replace tabs with spaces for all
+ non-commands statements
+
+Replacing tabs with spaces for all non-commands statements
+in 'Makefile' and 'config/Makefile' files.
+
+Suggested-by: Sam Ravnborg <sam@ravnborg.org>
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369398928-9809-23-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Makefile        |  80 ++++-----
+ tools/perf/config/Makefile | 396 ++++++++++++++++++++++-----------------------
+ 2 files changed, 238 insertions(+), 238 deletions(-)
+
+diff --git a/tools/perf/Makefile b/tools/perf/Makefile
+index 8f50afe..ac52598 100644
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -124,14 +124,14 @@ strip-libs = $(filter-out -l%,$(1))
+ LK_PATH=$(LK_DIR)
+ ifneq ($(OUTPUT),)
+-      TE_PATH=$(OUTPUT)
++  TE_PATH=$(OUTPUT)
+ ifneq ($(subdir),)
+-      LK_PATH=$(OUTPUT)$(LK_DIR)
++  LK_PATH=$(OUTPUT)$(LK_DIR)
+ else
+-      LK_PATH=$(OUTPUT)
++  LK_PATH=$(OUTPUT)
+ endif
+ else
+-      TE_PATH=$(TRACE_EVENT_DIR)
++  TE_PATH=$(TRACE_EVENT_DIR)
+ endif
+ LIBTRACEEVENT = $(TE_PATH)libtraceevent.a
+@@ -175,10 +175,10 @@ OTHER_PROGRAMS = $(OUTPUT)perf
+ # Set paths to tools early so that they can be used for version tests.
+ ifndef SHELL_PATH
+-      SHELL_PATH = /bin/sh
++  SHELL_PATH = /bin/sh
+ endif
+ ifndef PERL_PATH
+-      PERL_PATH = /usr/bin/perl
++  PERL_PATH = /usr/bin/perl
+ endif
+ export PERL_PATH
+@@ -433,7 +433,7 @@ PERFLIBS = $(LIB_FILE) $(LIBLK) $(LIBTRACEEVENT)
+ -include arch/$(ARCH)/Makefile
+ ifneq ($(OUTPUT),)
+-      CFLAGS += -I$(OUTPUT)
++  CFLAGS += -I$(OUTPUT)
+ endif
+ ifdef NO_LIBELF
+@@ -452,67 +452,67 @@ LIB_OBJS += $(OUTPUT)util/symbol-minimal.o
+ else # NO_LIBELF
+ ifndef NO_DWARF
+-      LIB_OBJS += $(OUTPUT)util/probe-finder.o
+-      LIB_OBJS += $(OUTPUT)util/dwarf-aux.o
++  LIB_OBJS += $(OUTPUT)util/probe-finder.o
++  LIB_OBJS += $(OUTPUT)util/dwarf-aux.o
+ endif # NO_DWARF
+ endif # NO_LIBELF
+ ifndef NO_LIBUNWIND
+-      LIB_OBJS += $(OUTPUT)util/unwind.o
++  LIB_OBJS += $(OUTPUT)util/unwind.o
+ endif
+ ifndef NO_LIBAUDIT
+-      BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
++  BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
+ endif
+ ifndef NO_SLANG
+-      LIB_OBJS += $(OUTPUT)ui/browser.o
+-      LIB_OBJS += $(OUTPUT)ui/browsers/annotate.o
+-      LIB_OBJS += $(OUTPUT)ui/browsers/hists.o
+-      LIB_OBJS += $(OUTPUT)ui/browsers/map.o
+-      LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o
+-      LIB_OBJS += $(OUTPUT)ui/tui/setup.o
+-      LIB_OBJS += $(OUTPUT)ui/tui/util.o
+-      LIB_OBJS += $(OUTPUT)ui/tui/helpline.o
+-      LIB_OBJS += $(OUTPUT)ui/tui/progress.o
+-      LIB_H += ui/browser.h
+-      LIB_H += ui/browsers/map.h
+-      LIB_H += ui/keysyms.h
+-      LIB_H += ui/libslang.h
++  LIB_OBJS += $(OUTPUT)ui/browser.o
++  LIB_OBJS += $(OUTPUT)ui/browsers/annotate.o
++  LIB_OBJS += $(OUTPUT)ui/browsers/hists.o
++  LIB_OBJS += $(OUTPUT)ui/browsers/map.o
++  LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o
++  LIB_OBJS += $(OUTPUT)ui/tui/setup.o
++  LIB_OBJS += $(OUTPUT)ui/tui/util.o
++  LIB_OBJS += $(OUTPUT)ui/tui/helpline.o
++  LIB_OBJS += $(OUTPUT)ui/tui/progress.o
++  LIB_H += ui/browser.h
++  LIB_H += ui/browsers/map.h
++  LIB_H += ui/keysyms.h
++  LIB_H += ui/libslang.h
+ endif
+ ifndef NO_GTK2
+-      LIB_OBJS += $(OUTPUT)ui/gtk/browser.o
+-      LIB_OBJS += $(OUTPUT)ui/gtk/hists.o
+-      LIB_OBJS += $(OUTPUT)ui/gtk/setup.o
+-      LIB_OBJS += $(OUTPUT)ui/gtk/util.o
+-      LIB_OBJS += $(OUTPUT)ui/gtk/helpline.o
+-      LIB_OBJS += $(OUTPUT)ui/gtk/progress.o
+-      LIB_OBJS += $(OUTPUT)ui/gtk/annotate.o
++  LIB_OBJS += $(OUTPUT)ui/gtk/browser.o
++  LIB_OBJS += $(OUTPUT)ui/gtk/hists.o
++  LIB_OBJS += $(OUTPUT)ui/gtk/setup.o
++  LIB_OBJS += $(OUTPUT)ui/gtk/util.o
++  LIB_OBJS += $(OUTPUT)ui/gtk/helpline.o
++  LIB_OBJS += $(OUTPUT)ui/gtk/progress.o
++  LIB_OBJS += $(OUTPUT)ui/gtk/annotate.o
+ endif
+ ifndef NO_LIBPERL
+-      LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-perl.o
+-      LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o
++  LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-perl.o
++  LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o
+ endif
+ ifndef NO_LIBPYTHON
+-      LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o
+-      LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o
++  LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o
++  LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o
+ endif
+ ifeq ($(NO_PERF_REGS),0)
+-      ifeq ($(ARCH),x86)
+-              LIB_H += arch/x86/include/perf_regs.h
+-      endif
++  ifeq ($(ARCH),x86)
++    LIB_H += arch/x86/include/perf_regs.h
++  endif
+ endif
+ ifndef NO_LIBNUMA
+-      BUILTIN_OBJS += $(OUTPUT)bench/numa.o
++  BUILTIN_OBJS += $(OUTPUT)bench/numa.o
+ endif
+ ifdef ASCIIDOC8
+-      export ASCIIDOC8
++  export ASCIIDOC8
+ endif
+ LIBS = -Wl,--whole-archive $(PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group
+diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
+index cc464f1..9765993 100644
+--- a/tools/perf/config/Makefile
++++ b/tools/perf/config/Makefile
+@@ -1,37 +1,37 @@
+ uname_M := $(shell uname -m 2>/dev/null || echo not)
+ ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
+-                                -e s/arm.*/arm/ -e s/sa110/arm/ \
+-                                -e s/s390x/s390/ -e s/parisc64/parisc/ \
+-                                -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
+-                                -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ )
++                                  -e s/arm.*/arm/ -e s/sa110/arm/ \
++                                  -e s/s390x/s390/ -e s/parisc64/parisc/ \
++                                  -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
++                                  -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ )
+ NO_PERF_REGS := 1
+ CFLAGS := $(EXTRA_CFLAGS) $(EXTRA_WARNINGS)
+ # Additional ARCH settings for x86
+ ifeq ($(ARCH),i386)
+-      override ARCH := x86
+-      NO_PERF_REGS := 0
+-      LIBUNWIND_LIBS = -lunwind -lunwind-x86
++  override ARCH := x86
++  NO_PERF_REGS := 0
++  LIBUNWIND_LIBS = -lunwind -lunwind-x86
+ endif
+ ifeq ($(ARCH),x86_64)
+-      override ARCH := x86
+-      IS_X86_64 := 0
+-      ifeq (, $(findstring m32,$(CFLAGS)))
+-              IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -x c - | tail -n 1)
+-      endif
+-      ifeq (${IS_X86_64}, 1)
+-              RAW_ARCH := x86_64
+-              CFLAGS += -DARCH_X86_64
+-              ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S
+-      endif
+-      NO_PERF_REGS := 0
+-      LIBUNWIND_LIBS = -lunwind -lunwind-x86_64
++  override ARCH := x86
++  IS_X86_64 := 0
++  ifeq (, $(findstring m32,$(CFLAGS)))
++    IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -x c - | tail -n 1)
++  endif
++  ifeq (${IS_X86_64}, 1)
++    RAW_ARCH := x86_64
++    CFLAGS += -DARCH_X86_64
++    ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S
++  endif
++  NO_PERF_REGS := 0
++  LIBUNWIND_LIBS = -lunwind -lunwind-x86_64
+ endif
+ ifeq ($(NO_PERF_REGS),0)
+-        CFLAGS += -DHAVE_PERF_REGS
++  CFLAGS += -DHAVE_PERF_REGS
+ endif
+ ifeq ($(src-perf),)
+@@ -53,128 +53,128 @@ include $(src-perf)/config/feature-tests.mak
+ include $(src-perf)/config/utilities.mak
+ ifeq ($(call get-executable,$(FLEX)),)
+-      dummy := $(error Error: $(FLEX) is missing on this system, please install it)
++  dummy := $(error Error: $(FLEX) is missing on this system, please install it)
+ endif
+ ifeq ($(call get-executable,$(BISON)),)
+-      dummy := $(error Error: $(BISON) is missing on this system, please install it)
++  dummy := $(error Error: $(BISON) is missing on this system, please install it)
+ endif
+ # Treat warnings as errors unless directed not to
+ ifneq ($(WERROR),0)
+-      CFLAGS += -Werror
++  CFLAGS += -Werror
+ endif
+ ifeq ("$(origin DEBUG)", "command line")
+-      PERF_DEBUG = $(DEBUG)
++  PERF_DEBUG = $(DEBUG)
+ endif
+ ifndef PERF_DEBUG
+-      CFLAGS += -O6
++  CFLAGS += -O6
+ endif
+ ifdef PARSER_DEBUG
+-      PARSER_DEBUG_BISON := -t
+-      PARSER_DEBUG_FLEX  := -d
+-      CFLAGS             += -DPARSER_DEBUG
++  PARSER_DEBUG_BISON := -t
++  PARSER_DEBUG_FLEX  := -d
++  CFLAGS             += -DPARSER_DEBUG
+ endif
+ CFLAGS += \
+-      -fno-omit-frame-pointer \
+-      -ggdb3 \
+-      -funwind-tables \
+-      -Wall \
+-      -Wextra \
+-      -std=gnu99
++  -fno-omit-frame-pointer \
++  -ggdb3 \
++  -funwind-tables \
++  -Wall \
++  -Wextra \
++  -std=gnu99
+ EXTLIBS = -lpthread -lrt -lelf -lm
+ ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y)
+-      CFLAGS += -fstack-protector-all
++  CFLAGS += -fstack-protector-all
+ endif
+ ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wstack-protector,-Wstack-protector),y)
+-      CFLAGS += -Wstack-protector
++  CFLAGS += -Wstack-protector
+ endif
+ ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wvolatile-register-var,-Wvolatile-register-var),y)
+-      CFLAGS += -Wvolatile-register-var
++  CFLAGS += -Wvolatile-register-var
+ endif
+ ifndef PERF_DEBUG
+-      ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -D_FORTIFY_SOURCE=2,-D_FORTIFY_SOURCE=2),y)
+-              CFLAGS += -D_FORTIFY_SOURCE=2
+-      endif
++  ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -D_FORTIFY_SOURCE=2,-D_FORTIFY_SOURCE=2),y)
++    CFLAGS += -D_FORTIFY_SOURCE=2
++  endif
+ endif
+ CFLAGS += \
+-      -I$(src-perf)/util/include \
+-      -I$(src-perf)/arch/$(ARCH)/include \
+-      -I$(srctree)/arch/$(ARCH)/include/uapi \
+-      -I$(srctree)/arch/$(ARCH)/include \
+-      -I$(srctree)/include/uapi \
+-      -I$(srctree)/include
++  -I$(src-perf)/util/include \
++  -I$(src-perf)/arch/$(ARCH)/include \
++  -I$(srctree)/arch/$(ARCH)/include/uapi \
++  -I$(srctree)/arch/$(ARCH)/include \
++  -I$(srctree)/include/uapi \
++  -I$(srctree)/include
+ # $(obj-perf)      for generated common-cmds.h
+ # $(obj-perf)/util for generated bison/flex headers
+ ifneq ($(OUTPUT),)
+ CFLAGS += \
+-      -I$(obj-perf)/util \
+-      -I$(obj-perf)
++  -I$(obj-perf)/util \
++  -I$(obj-perf)
+ endif
+ CFLAGS += \
+-      -I$(src-perf)/util \
+-      -I$(src-perf) \
+-      -I$(TRACE_EVENT_DIR) \
+-      -I$(srctree)/tools/lib/
++  -I$(src-perf)/util \
++  -I$(src-perf) \
++  -I$(TRACE_EVENT_DIR) \
++  -I$(srctree)/tools/lib/
+ CFLAGS += \
+-      -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
++  -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
+ ifndef NO_BIONIC
+ ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS),bionic),y)
+-      BIONIC := 1
+-      EXTLIBS := $(filter-out -lrt,$(EXTLIBS))
+-      EXTLIBS := $(filter-out -lpthread,$(EXTLIBS))
++  BIONIC := 1
++  EXTLIBS := $(filter-out -lrt,$(EXTLIBS))
++  EXTLIBS := $(filter-out -lpthread,$(EXTLIBS))
+ endif
+ endif # NO_BIONIC
+ ifdef NO_LIBELF
+-      NO_DWARF := 1
+-      NO_DEMANGLE := 1
+-      NO_LIBUNWIND := 1
++  NO_DWARF := 1
++  NO_DEMANGLE := 1
++  NO_LIBUNWIND := 1
+ else
+ FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS)
+ ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF),libelf),y)
+-      FLAGS_GLIBC=$(CFLAGS) $(LDFLAGS)
+-      ifeq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC),glibc),y)
+-              LIBC_SUPPORT := 1
+-      endif
+-      ifeq ($(BIONIC),1)
+-              LIBC_SUPPORT := 1
+-      endif
+-      ifeq ($(LIBC_SUPPORT),1)
+-              msg := $(warning No libelf found, disables 'probe' tool, please install elfutils-libelf-devel/libelf-dev);
+-
+-              NO_LIBELF := 1
+-              NO_DWARF := 1
+-              NO_DEMANGLE := 1
+-      else
+-              msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
+-      endif
++  FLAGS_GLIBC=$(CFLAGS) $(LDFLAGS)
++  ifeq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC),glibc),y)
++    LIBC_SUPPORT := 1
++  endif
++  ifeq ($(BIONIC),1)
++    LIBC_SUPPORT := 1
++  endif
++  ifeq ($(LIBC_SUPPORT),1)
++    msg := $(warning No libelf found, disables 'probe' tool, please install elfutils-libelf-devel/libelf-dev);
++
++    NO_LIBELF := 1
++    NO_DWARF := 1
++    NO_DEMANGLE := 1
++  else
++    msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
++  endif
+ else
+-      # for linking with debug library, run like:
+-      # make DEBUG=1 LIBDW_DIR=/opt/libdw/
+-      ifdef LIBDW_DIR
+-              LIBDW_CFLAGS  := -I$(LIBDW_DIR)/include
+-              LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib
+-      endif
+-
+-      FLAGS_DWARF=$(CFLAGS) $(LIBDW_CFLAGS) -ldw -lelf $(LIBDW_LDFLAGS) $(LDFLAGS) $(EXTLIBS)
+-      ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF),libdw),y)
+-              msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
+-              NO_DWARF := 1
+-      endif # Dwarf support
++  # for linking with debug library, run like:
++  # make DEBUG=1 LIBDW_DIR=/opt/libdw/
++  ifdef LIBDW_DIR
++    LIBDW_CFLAGS  := -I$(LIBDW_DIR)/include
++    LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib
++  endif
++
++  FLAGS_DWARF=$(CFLAGS) $(LIBDW_CFLAGS) -ldw -lelf $(LIBDW_LDFLAGS) $(LDFLAGS) $(EXTLIBS)
++  ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF),libdw),y)
++    msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
++    NO_DWARF := 1
++  endif # Dwarf support
+ endif # SOURCE_LIBELF
+ endif # NO_LIBELF
+@@ -182,7 +182,7 @@ ifndef NO_LIBELF
+ CFLAGS += -DLIBELF_SUPPORT
+ FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS)
+ ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
+-      CFLAGS += -DLIBELF_MMAP
++  CFLAGS += -DLIBELF_MMAP
+ endif
+ # include ARCH specific config
+@@ -190,12 +190,12 @@ endif
+ ifndef NO_DWARF
+ ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
+-      msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled);
+-      NO_DWARF := 1
++  msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled);
++  NO_DWARF := 1
+ else
+-      CFLAGS += -DDWARF_SUPPORT $(LIBDW_CFLAGS)
+-      LDFLAGS += $(LIBDW_LDFLAGS)
+-      EXTLIBS += -lelf -ldw
++  CFLAGS += -DDWARF_SUPPORT $(LIBDW_CFLAGS)
++  LDFLAGS += $(LIBDW_LDFLAGS)
++  EXTLIBS += -lelf -ldw
+ endif # PERF_HAVE_DWARF_REGS
+ endif # NO_DWARF
+@@ -205,99 +205,99 @@ ifndef NO_LIBELF
+ CFLAGS += -DLIBELF_SUPPORT
+ FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS)
+ ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
+-      CFLAGS += -DLIBELF_MMAP
++  CFLAGS += -DLIBELF_MMAP
+ endif # try-cc
+ endif # NO_LIBELF
+ # There's only x86 (both 32 and 64) support for CFI unwind so far
+ ifneq ($(ARCH),x86)
+-      NO_LIBUNWIND := 1
++  NO_LIBUNWIND := 1
+ endif
+ ifndef NO_LIBUNWIND
+ # for linking with debug library, run like:
+ # make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/
+ ifdef LIBUNWIND_DIR
+-      LIBUNWIND_CFLAGS  := -I$(LIBUNWIND_DIR)/include
+-      LIBUNWIND_LDFLAGS := -L$(LIBUNWIND_DIR)/lib
++  LIBUNWIND_CFLAGS  := -I$(LIBUNWIND_DIR)/include
++  LIBUNWIND_LDFLAGS := -L$(LIBUNWIND_DIR)/lib
+ endif
+ FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(CFLAGS) $(LIBUNWIND_LDFLAGS) $(LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS)
+ ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND),libunwind),y)
+-      msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99);
+-      NO_LIBUNWIND := 1
++  msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99);
++  NO_LIBUNWIND := 1
+ endif # Libunwind support
+ endif # NO_LIBUNWIND
+ ifndef NO_LIBUNWIND
+-      CFLAGS += -DLIBUNWIND_SUPPORT
+-      EXTLIBS += $(LIBUNWIND_LIBS)
+-      CFLAGS += $(LIBUNWIND_CFLAGS)
+-      LDFLAGS += $(LIBUNWIND_LDFLAGS)
++  CFLAGS += -DLIBUNWIND_SUPPORT
++  EXTLIBS += $(LIBUNWIND_LIBS)
++  CFLAGS += $(LIBUNWIND_CFLAGS)
++  LDFLAGS += $(LIBUNWIND_LDFLAGS)
+ endif # NO_LIBUNWIND
+ ifndef NO_LIBAUDIT
+-      FLAGS_LIBAUDIT = $(CFLAGS) $(LDFLAGS) -laudit
+-      ifneq ($(call try-cc,$(SOURCE_LIBAUDIT),$(FLAGS_LIBAUDIT),libaudit),y)
+-              msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev);
+-              NO_LIBAUDIT := 1
+-      else
+-              CFLAGS += -DLIBAUDIT_SUPPORT
+-              EXTLIBS += -laudit
+-      endif
++  FLAGS_LIBAUDIT = $(CFLAGS) $(LDFLAGS) -laudit
++  ifneq ($(call try-cc,$(SOURCE_LIBAUDIT),$(FLAGS_LIBAUDIT),libaudit),y)
++    msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev);
++    NO_LIBAUDIT := 1
++  else
++    CFLAGS += -DLIBAUDIT_SUPPORT
++    EXTLIBS += -laudit
++  endif
+ endif
+ ifdef NO_NEWT
+-      NO_SLANG=1
++  NO_SLANG=1
+ endif
+ ifndef NO_SLANG
+-      FLAGS_SLANG=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -I/usr/include/slang -lslang
+-      ifneq ($(call try-cc,$(SOURCE_SLANG),$(FLAGS_SLANG),libslang),y)
+-              msg := $(warning slang not found, disables TUI support. Please install slang-devel or libslang-dev);
+-              NO_SLANG := 1
+-      else
+-              # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h
+-              CFLAGS += -I/usr/include/slang
+-              CFLAGS += -DSLANG_SUPPORT
+-              EXTLIBS += -lslang
+-      endif
++  FLAGS_SLANG=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -I/usr/include/slang -lslang
++  ifneq ($(call try-cc,$(SOURCE_SLANG),$(FLAGS_SLANG),libslang),y)
++    msg := $(warning slang not found, disables TUI support. Please install slang-devel or libslang-dev);
++    NO_SLANG := 1
++  else
++    # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h
++    CFLAGS += -I/usr/include/slang
++    CFLAGS += -DSLANG_SUPPORT
++    EXTLIBS += -lslang
++  endif
+ endif
+ ifndef NO_GTK2
+-      FLAGS_GTK2=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
+-      ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2),gtk2),y)
+-              msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev);
+-              NO_GTK2 := 1
+-      else
+-              ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2),-DHAVE_GTK_INFO_BAR),y)
+-                      CFLAGS += -DHAVE_GTK_INFO_BAR
+-              endif
+-              CFLAGS += -DGTK2_SUPPORT
+-              CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null)
+-              EXTLIBS += $(shell pkg-config --libs gtk+-2.0 2>/dev/null)
+-      endif
++  FLAGS_GTK2=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
++  ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2),gtk2),y)
++    msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev);
++    NO_GTK2 := 1
++  else
++    ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2),-DHAVE_GTK_INFO_BAR),y)
++      CFLAGS += -DHAVE_GTK_INFO_BAR
++    endif
++    CFLAGS += -DGTK2_SUPPORT
++    CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null)
++    EXTLIBS += $(shell pkg-config --libs gtk+-2.0 2>/dev/null)
++  endif
+ endif
+ grep-libs  = $(filter -l%,$(1))
+ strip-libs = $(filter-out -l%,$(1))
+ ifdef NO_LIBPERL
+-      CFLAGS += -DNO_LIBPERL
++  CFLAGS += -DNO_LIBPERL
+ else
+-      PERL_EMBED_LDOPTS = $(shell perl -MExtUtils::Embed -e ldopts 2>/dev/null)
+-      PERL_EMBED_LDFLAGS = $(call strip-libs,$(PERL_EMBED_LDOPTS))
+-      PERL_EMBED_LIBADD = $(call grep-libs,$(PERL_EMBED_LDOPTS))
+-      PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null`
+-      FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS)
+-
+-      ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED),perl),y)
+-              CFLAGS += -DNO_LIBPERL
+-              NO_LIBPERL := 1
+-      else
+-              LDFLAGS += $(PERL_EMBED_LDFLAGS)
+-              EXTLIBS += $(PERL_EMBED_LIBADD)
+-      endif
++  PERL_EMBED_LDOPTS = $(shell perl -MExtUtils::Embed -e ldopts 2>/dev/null)
++  PERL_EMBED_LDFLAGS = $(call strip-libs,$(PERL_EMBED_LDOPTS))
++  PERL_EMBED_LIBADD = $(call grep-libs,$(PERL_EMBED_LDOPTS))
++  PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null`
++  FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS)
++
++  ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED),perl),y)
++    CFLAGS += -DNO_LIBPERL
++    NO_LIBPERL := 1
++  else
++    LDFLAGS += $(PERL_EMBED_LDFLAGS)
++    EXTLIBS += $(PERL_EMBED_LIBADD)
++  endif
+ endif
+ disable-python = $(eval $(disable-python_code))
+@@ -364,69 +364,69 @@ else
+ endif
+ ifdef NO_DEMANGLE
+-      CFLAGS += -DNO_DEMANGLE
++  CFLAGS += -DNO_DEMANGLE
+ else
+-      ifdef HAVE_CPLUS_DEMANGLE
+-              EXTLIBS += -liberty
+-              CFLAGS += -DHAVE_CPLUS_DEMANGLE
+-      else
+-              FLAGS_BFD=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -DPACKAGE='perf' -lbfd
+-              has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD),libbfd)
+-              ifeq ($(has_bfd),y)
+-                      EXTLIBS += -lbfd
+-              else
+-                      FLAGS_BFD_IBERTY=$(FLAGS_BFD) -liberty
+-                      has_bfd_iberty := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY),liberty)
+-                      ifeq ($(has_bfd_iberty),y)
+-                              EXTLIBS += -lbfd -liberty
+-                      else
+-                              FLAGS_BFD_IBERTY_Z=$(FLAGS_BFD_IBERTY) -lz
+-                              has_bfd_iberty_z := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY_Z),libz)
+-                              ifeq ($(has_bfd_iberty_z),y)
+-                                      EXTLIBS += -lbfd -liberty -lz
+-                              else
+-                                      FLAGS_CPLUS_DEMANGLE=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -liberty
+-                                      has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE),demangle)
+-                                      ifeq ($(has_cplus_demangle),y)
+-                                              EXTLIBS += -liberty
+-                                              CFLAGS += -DHAVE_CPLUS_DEMANGLE
+-                                      else
+-                                              msg := $(warning No bfd.h/libbfd found, install binutils-dev[el]/zlib-static to gain symbol demangling)
+-                                              CFLAGS += -DNO_DEMANGLE
+-                                      endif
+-                              endif
+-                      endif
+-              endif
+-      endif
++  ifdef HAVE_CPLUS_DEMANGLE
++    EXTLIBS += -liberty
++    CFLAGS += -DHAVE_CPLUS_DEMANGLE
++  else
++    FLAGS_BFD=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -DPACKAGE='perf' -lbfd
++    has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD),libbfd)
++    ifeq ($(has_bfd),y)
++      EXTLIBS += -lbfd
++    else
++      FLAGS_BFD_IBERTY=$(FLAGS_BFD) -liberty
++      has_bfd_iberty := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY),liberty)
++      ifeq ($(has_bfd_iberty),y)
++        EXTLIBS += -lbfd -liberty
++      else
++        FLAGS_BFD_IBERTY_Z=$(FLAGS_BFD_IBERTY) -lz
++        has_bfd_iberty_z := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY_Z),libz)
++        ifeq ($(has_bfd_iberty_z),y)
++          EXTLIBS += -lbfd -liberty -lz
++        else
++          FLAGS_CPLUS_DEMANGLE=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -liberty
++          has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE),demangle)
++          ifeq ($(has_cplus_demangle),y)
++            EXTLIBS += -liberty
++            CFLAGS += -DHAVE_CPLUS_DEMANGLE
++          else
++            msg := $(warning No bfd.h/libbfd found, install binutils-dev[el]/zlib-static to gain symbol demangling)
++            CFLAGS += -DNO_DEMANGLE
++          endif
++        endif
++      endif
++    endif
++  endif
+ endif
+ ifndef NO_STRLCPY
+-      ifeq ($(call try-cc,$(SOURCE_STRLCPY),,-DHAVE_STRLCPY),y)
+-              CFLAGS += -DHAVE_STRLCPY
+-      endif
++  ifeq ($(call try-cc,$(SOURCE_STRLCPY),,-DHAVE_STRLCPY),y)
++    CFLAGS += -DHAVE_STRLCPY
++  endif
+ endif
+ ifndef NO_ON_EXIT
+-      ifeq ($(call try-cc,$(SOURCE_ON_EXIT),,-DHAVE_ON_EXIT),y)
+-              CFLAGS += -DHAVE_ON_EXIT
+-      endif
++  ifeq ($(call try-cc,$(SOURCE_ON_EXIT),,-DHAVE_ON_EXIT),y)
++    CFLAGS += -DHAVE_ON_EXIT
++  endif
+ endif
+ ifndef NO_BACKTRACE
+-       ifeq ($(call try-cc,$(SOURCE_BACKTRACE),,-DBACKTRACE_SUPPORT),y)
+-              CFLAGS += -DBACKTRACE_SUPPORT
+-       endif
++  ifeq ($(call try-cc,$(SOURCE_BACKTRACE),,-DBACKTRACE_SUPPORT),y)
++    CFLAGS += -DBACKTRACE_SUPPORT
++  endif
+ endif
+ ifndef NO_LIBNUMA
+-      FLAGS_LIBNUMA = $(CFLAGS) $(LDFLAGS) -lnuma
+-      ifneq ($(call try-cc,$(SOURCE_LIBNUMA),$(FLAGS_LIBNUMA),libnuma),y)
+-              msg := $(warning No numa.h found, disables 'perf bench numa mem' benchmark, please install numa-libs-devel or libnuma-dev);
+-              NO_LIBNUMA := 1
+-      else
+-              CFLAGS += -DLIBNUMA_SUPPORT
+-              EXTLIBS += -lnuma
+-      endif
++  FLAGS_LIBNUMA = $(CFLAGS) $(LDFLAGS) -lnuma
++  ifneq ($(call try-cc,$(SOURCE_LIBNUMA),$(FLAGS_LIBNUMA),libnuma),y)
++    msg := $(warning No numa.h found, disables 'perf bench numa mem' benchmark, please install numa-libs-devel or libnuma-dev);
++    NO_LIBNUMA := 1
++  else
++    CFLAGS += -DLIBNUMA_SUPPORT
++    EXTLIBS += -lnuma
++  endif
+ endif
+ # Among the variables below, these:
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0420-perf-tools-Replace-multiple-line-assignment-with-mul.patch b/patches.tizen/0420-perf-tools-Replace-multiple-line-assignment-with-mul.patch
new file mode 100644 (file)
index 0000000..633705d
--- /dev/null
@@ -0,0 +1,97 @@
+From a885198bbb009bc89783d3d9889757ed130cd9b8 Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Mon, 15 Apr 2013 04:32:28 +0200
+Subject: [PATCH 0420/1302] perf tools: Replace multiple line assignment with
+ multiple statements
+
+Replacing multiple line assignment with multiple statements.
+
+Suggested-by: Sam Ravnborg <sam@ravnborg.org>
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369398928-9809-24-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/config/Makefile | 43 +++++++++++++++++++------------------------
+ 1 file changed, 19 insertions(+), 24 deletions(-)
+
+diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
+index 9765993..f139dcd 100644
+--- a/tools/perf/config/Makefile
++++ b/tools/perf/config/Makefile
+@@ -78,13 +78,12 @@ ifdef PARSER_DEBUG
+   CFLAGS             += -DPARSER_DEBUG
+ endif
+-CFLAGS += \
+-  -fno-omit-frame-pointer \
+-  -ggdb3 \
+-  -funwind-tables \
+-  -Wall \
+-  -Wextra \
+-  -std=gnu99
++CFLAGS += -fno-omit-frame-pointer
++CFLAGS += -ggdb3
++CFLAGS += -funwind-tables
++CFLAGS += -Wall
++CFLAGS += -Wextra
++CFLAGS += -std=gnu99
+ EXTLIBS = -lpthread -lrt -lelf -lm
+@@ -106,30 +105,26 @@ ifndef PERF_DEBUG
+   endif
+ endif
+-CFLAGS += \
+-  -I$(src-perf)/util/include \
+-  -I$(src-perf)/arch/$(ARCH)/include \
+-  -I$(srctree)/arch/$(ARCH)/include/uapi \
+-  -I$(srctree)/arch/$(ARCH)/include \
+-  -I$(srctree)/include/uapi \
+-  -I$(srctree)/include
++CFLAGS += -I$(src-perf)/util/include
++CFLAGS += -I$(src-perf)/arch/$(ARCH)/include
++CFLAGS += -I$(srctree)/arch/$(ARCH)/include/uapi
++CFLAGS += -I$(srctree)/arch/$(ARCH)/include
++CFLAGS += -I$(srctree)/include/uapi
++CFLAGS += -I$(srctree)/include
+ # $(obj-perf)      for generated common-cmds.h
+ # $(obj-perf)/util for generated bison/flex headers
+ ifneq ($(OUTPUT),)
+-CFLAGS += \
+-  -I$(obj-perf)/util \
+-  -I$(obj-perf)
++CFLAGS += -I$(obj-perf)/util
++CFLAGS += -I$(obj-perf)
+ endif
+-CFLAGS += \
+-  -I$(src-perf)/util \
+-  -I$(src-perf) \
+-  -I$(TRACE_EVENT_DIR) \
+-  -I$(srctree)/tools/lib/
++CFLAGS += -I$(src-perf)/util
++CFLAGS += -I$(src-perf)
++CFLAGS += -I$(TRACE_EVENT_DIR)
++CFLAGS += -I$(srctree)/tools/lib/
+-CFLAGS += \
+-  -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
++CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
+ ifndef NO_BIONIC
+ ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS),bionic),y)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0421-perf-tools-Remove-Makefile-STRIP-assignment.patch b/patches.tizen/0421-perf-tools-Remove-Makefile-STRIP-assignment.patch
new file mode 100644 (file)
index 0000000..6efd197
--- /dev/null
@@ -0,0 +1,43 @@
+From 8b8e8119e0303559b0a9d2f98509bc2025cee101 Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Mon, 15 Apr 2013 04:49:43 +0200
+Subject: [PATCH 0421/1302] perf tools: Remove '?=' Makefile STRIP assignment
+
+No need to use '?=' assignment for STRIP variable, the standard
+'=' does the same job without creating confusion.
+
+Suggested-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Stephane Eranian <eranian@google.com>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Link: http://lkml.kernel.org/r/1369398928-9809-25-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/Makefile b/tools/perf/Makefile
+index ac52598..b5f5c6d 100644
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -82,7 +82,7 @@ FIND    = find
+ INSTALL = install
+ FLEX    = flex
+ BISON   = bison
+-STRIP  ?= strip
++STRIP   = strip
+ LK_DIR          = $(srctree)/tools/lib/lk/
+ TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0422-perf-tools-Add-missing-liblk.a-dependency-for-python.patch b/patches.tizen/0422-perf-tools-Add-missing-liblk.a-dependency-for-python.patch
new file mode 100644 (file)
index 0000000..49ba5c2
--- /dev/null
@@ -0,0 +1,41 @@
+From 368633d7d4671798ce27bcfe15094f581f4b4d0a Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@redhat.com>
+Date: Mon, 15 Apr 2013 05:54:14 +0200
+Subject: [PATCH 0422/1302] perf tools: Add missing liblk.a dependency for
+ python/perf.so
+
+Adding missing liblk.a dependency for python/perf.so.
+
+Signed-off-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lkml.kernel.org/r/1369398928-9809-26-git-send-email-jolsa@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ tools/perf/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/Makefile b/tools/perf/Makefile
+index b5f5c6d..203cb0e 100644
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -149,7 +149,7 @@ export PYTHON_EXTBUILD_LIB PYTHON_EXTBUILD_TMP
+ python-clean := rm -rf $(PYTHON_EXTBUILD) $(OUTPUT)python/perf.so
+ PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources)
+-PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBTRACEEVENT)
++PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBTRACEEVENT) $(LIBLK)
+ $(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS)
+       $(QUIET_GEN)CFLAGS='$(CFLAGS)' $(PYTHON_WORD) util/setup.py \
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0423-dts-arm-add-arm-pmu-node-for-exynos4412.patch b/patches.tizen/0423-dts-arm-add-arm-pmu-node-for-exynos4412.patch
new file mode 100644 (file)
index 0000000..d6e38e3
--- /dev/null
@@ -0,0 +1,34 @@
+From f1666327c6bd87414d9f47ef80fb677e1a46f381 Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Fri, 19 Jul 2013 16:18:56 +0900
+Subject: [PATCH 0423/1302] dts: arm: add arm-pmu node for exynos4412
+
+This patch enables arm-pmu node of exynos4412. It has 4 cpus. Thus, it also
+has 4 performance counter.
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412.dtsi | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412.dtsi b/arch/arm/boot/dts/exynos4412.dtsi
+index 270b389..2f4ca6f 100644
+--- a/arch/arm/boot/dts/exynos4412.dtsi
++++ b/arch/arm/boot/dts/exynos4412.dtsi
+@@ -35,6 +35,12 @@
+                            <0 107 0>, <0 108 0>, <0 48 0>, <0 42 0>;
+       };
++      pmu {
++              compatible = "arm,cortex-a9-pmu";
++              interrupt-parent = <&combiner>;
++              interrupts = <2 2>, <3 2>, <18 2>, <19 2>;
++      };
++
+       mct@10050000 {
+               compatible = "samsung,exynos4412-mct";
+               reg = <0x10050000 0x800>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0424-clk-samsung-fix-section-mismatch-from-audio-subsyste.patch b/patches.tizen/0424-clk-samsung-fix-section-mismatch-from-audio-subsyste.patch
new file mode 100644 (file)
index 0000000..f800859
--- /dev/null
@@ -0,0 +1,31 @@
+From 4bcf3189adf1666c00592bc767e19e2708920716 Mon Sep 17 00:00:00 2001
+From: Seung-Woo Kim <sw0312.kim@samsung.com>
+Date: Fri, 19 Jul 2013 16:41:44 +0900
+Subject: [PATCH 0424/1302] clk: samsung: fix section mismatch from audio
+ subsystem clocks
+
+The init function should have __init flag to match reference
+sections.
+
+Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/samsung/clk-exynos4-audss.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/samsung/clk-exynos4-audss.c b/drivers/clk/samsung/clk-exynos4-audss.c
+index 978c5de..4522d00 100644
+--- a/drivers/clk/samsung/clk-exynos4-audss.c
++++ b/drivers/clk/samsung/clk-exynos4-audss.c
+@@ -77,7 +77,7 @@ static struct of_device_id audss_of_match[] __initdata = {
+ static DEFINE_SPINLOCK(audss_clk_lock);
+-static int samsung_audss_clk_init(void)
++static int __init samsung_audss_clk_init(void)
+ {
+       struct device_node *node;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0425-max77693_charger-fix-section-mismatch.patch b/patches.tizen/0425-max77693_charger-fix-section-mismatch.patch
new file mode 100644 (file)
index 0000000..3de8e3d
--- /dev/null
@@ -0,0 +1,31 @@
+From 63a8f9bbe7db445b98e7ef82b24324b18239c754 Mon Sep 17 00:00:00 2001
+From: Seung-Woo Kim <sw0312.kim@samsung.com>
+Date: Fri, 19 Jul 2013 16:45:57 +0900
+Subject: [PATCH 0425/1302] max77693_charger: fix section mismatch
+
+max77693_charger_of_match with __initconst flag is referenced from
+max77693_charger_driver which is non init data and this causes
+section mismatch. So flag __initconst is removed.
+
+Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/power/max77693_charger.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/power/max77693_charger.c b/drivers/power/max77693_charger.c
+index 340aec0..71e94c1 100644
+--- a/drivers/power/max77693_charger.c
++++ b/drivers/power/max77693_charger.c
+@@ -654,7 +654,7 @@ static SIMPLE_DEV_PM_OPS(max77693_charger_pm_ops, max77693_charger_suspend,
+                       max77693_charger_resume);
+ #ifdef CONFIG_OF
+-static struct of_device_id max77693_charger_of_match[] __initconst = {
++static struct of_device_id max77693_charger_of_match[] = {
+       { .compatible = "samsung,max77693-charger", },
+       { },
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0426-cpufreq-exynos-fix-section-mismatch.patch b/patches.tizen/0426-cpufreq-exynos-fix-section-mismatch.patch
new file mode 100644 (file)
index 0000000..b2a678d
--- /dev/null
@@ -0,0 +1,38 @@
+From 88c3ee832e3ba6a96d5c83988fdeffbf3150d017 Mon Sep 17 00:00:00 2001
+From: Seung-Woo Kim <sw0312.kim@samsung.com>
+Date: Fri, 19 Jul 2013 16:52:29 +0900
+Subject: [PATCH 0426/1302] cpufreq: exynos: fix section mismatch
+
+Non init data, exynos_cpufreq_driver references init data,
+exynos_cpufreq_probe and exynos_cpufreq_of_match, and this causes
+section mismatch.
+
+Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/exynos-cpufreq.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c
+index 3197d88..d748ada 100644
+--- a/drivers/cpufreq/exynos-cpufreq.c
++++ b/drivers/cpufreq/exynos-cpufreq.c
+@@ -351,13 +351,13 @@ struct cpufreq_frequency_table *exynos_of_parse_freq_table(
+ }
+ #ifdef CONFIG_OF
+-static struct of_device_id exynos_cpufreq_of_match[] __initconst = {
++static struct of_device_id exynos_cpufreq_of_match[] = {
+       { .compatible = "samsung,exynos-cpufreq", },
+       { },
+ };
+ #endif
+-static int __init exynos_cpufreq_probe(struct platform_device *pdev)
++static int exynos_cpufreq_probe(struct platform_device *pdev)
+ {
+       int ret = -EINVAL;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0427-dmabuf-sync-fix-sync-lock-to-multiple-read.patch b/patches.tizen/0427-dmabuf-sync-fix-sync-lock-to-multiple-read.patch
new file mode 100644 (file)
index 0000000..beb39e1
--- /dev/null
@@ -0,0 +1,131 @@
+From a0bd381663b3141c3b5cc739b80d374328b16a2f Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Mon, 22 Jul 2013 12:42:35 +0900
+Subject: [PATCH 0427/1302] dmabuf-sync: fix sync lock to multiple read
+
+This patch fixes the issue that a sync object is unlocked
+when shared_cnt is bigger than 1 and sobj->access_type is write.
+
+the below number means shared_cnt and three sync objects share
+one buffer,
+                       r       r       r       w
+when write locked      1       2       3       3 <- blocked
+when read unlocked             2
+when read unlocked     1
+when read unlocked                             1 <- waked up
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/base/dmabuf-sync.c  | 43 +++++++++++++------------------------------
+ include/linux/dmabuf-sync.h |  1 -
+ 2 files changed, 13 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/base/dmabuf-sync.c b/drivers/base/dmabuf-sync.c
+index a4b8a50..14c0c6f 100644
+--- a/drivers/base/dmabuf-sync.c
++++ b/drivers/base/dmabuf-sync.c
+@@ -63,8 +63,7 @@ static void dmabuf_sync_timeout_worker(struct work_struct *work)
+                       continue;
+               }
+-              if (sobj->robj->shared &&
+-                  atomic_add_unless(&sobj->robj->shared_cnt, -1, 1)) {
++              if (atomic_add_unless(&sobj->robj->shared_cnt, -1, 1)) {
+                       mutex_unlock(&sobj->robj->lock);
+                       continue;
+               }
+@@ -74,6 +73,7 @@ static void dmabuf_sync_timeout_worker(struct work_struct *work)
+               ww_mutex_unlock(&sobj->robj->sync_lock);
+               mutex_lock(&sobj->robj->lock);
++              sobj->robj->locked = false;
+               if (sobj->access_type & DMA_BUF_ACCESS_R)
+                       printk(KERN_WARNING "%s: r-unlocked = 0x%x\n",
+@@ -183,7 +183,6 @@ retry:
+               if (sobj->robj->accessed_type & DMA_BUF_ACCESS_R &&
+                   sobj->access_type & DMA_BUF_ACCESS_R) {
+                       atomic_inc(&sobj->robj->shared_cnt);
+-                      sobj->robj->shared = true;
+                       mutex_unlock(&sobj->robj->lock);
+                       continue;
+               }
+@@ -278,29 +277,17 @@ static void dmabuf_sync_unlock_objs(struct dmabuf_sync *sync,
+       list_for_each_entry(sobj, &sync->syncs, head) {
+               mutex_lock(&sobj->robj->lock);
+-              if (sobj->robj->shared) {
+-                      if (atomic_add_unless(&sobj->robj->shared_cnt, -1,
+-                                              1)) {
+-                              mutex_unlock(&sobj->robj->lock);
+-                              continue;
+-                      }
+-
+-                      mutex_unlock(&sobj->robj->lock);
+-
+-                      ww_mutex_unlock(&sobj->robj->sync_lock);
+-
+-                      mutex_lock(&sobj->robj->lock);
+-                      sobj->robj->shared = false;
+-                      sobj->robj->locked = false;
+-              } else {
++              if (atomic_add_unless(&sobj->robj->shared_cnt, -1, 1)) {
+                       mutex_unlock(&sobj->robj->lock);
++                      continue;
++              }
+-                      ww_mutex_unlock(&sobj->robj->sync_lock);
++              mutex_unlock(&sobj->robj->lock);
+-                      mutex_lock(&sobj->robj->lock);
+-                      sobj->robj->locked = false;
+-              }
++              ww_mutex_unlock(&sobj->robj->sync_lock);
++              mutex_lock(&sobj->robj->lock);
++              sobj->robj->locked = false;
+               mutex_unlock(&sobj->robj->lock);
+       }
+@@ -585,7 +572,6 @@ int dmabuf_sync_single_lock(struct dma_buf *dmabuf, unsigned int type,
+       /* Don't lock in case of read and read. */
+       if (robj->accessed_type & DMA_BUF_ACCESS_R && type & DMA_BUF_ACCESS_R) {
+               atomic_inc(&robj->shared_cnt);
+-              robj->shared = true;
+               mutex_unlock(&robj->lock);
+               return 0;
+       }
+@@ -635,13 +621,10 @@ void dmabuf_sync_single_unlock(struct dma_buf *dmabuf)
+       mutex_lock(&robj->lock);
+-      if (robj->shared) {
+-              if (atomic_add_unless(&robj->shared_cnt, -1 , 1)) {
+-                      mutex_unlock(&robj->lock);
+-                      return;
+-              }
+-
+-              robj->shared = false;
++      if (atomic_add_unless(&robj->shared_cnt, -1 , 1)) {
++              mutex_unlock(&robj->lock);
++              dma_buf_put(dmabuf);
++              return;
+       }
+       mutex_unlock(&robj->lock);
+diff --git a/include/linux/dmabuf-sync.h b/include/linux/dmabuf-sync.h
+index 2502ad6..963ba99 100644
+--- a/include/linux/dmabuf-sync.h
++++ b/include/linux/dmabuf-sync.h
+@@ -24,7 +24,6 @@ struct dmabuf_sync_reservation {
+       struct mutex            lock;
+       atomic_t                shared_cnt;
+       unsigned int            accessed_type;
+-      unsigned int            shared;
+       unsigned int            locked;
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0428-dmabuf-sync-remove-unnecessary-the-use-of-mutex-lock.patch b/patches.tizen/0428-dmabuf-sync-remove-unnecessary-the-use-of-mutex-lock.patch
new file mode 100644 (file)
index 0000000..8eb042c
--- /dev/null
@@ -0,0 +1,42 @@
+From 4c5424e2cf8c623b2682679b362a418d37ba6a76 Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Mon, 22 Jul 2013 12:47:39 +0900
+Subject: [PATCH 0428/1302] dmabuf-sync: remove unnecessary the use of mutex
+ lock.
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/base/dmabuf-sync.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/base/dmabuf-sync.c b/drivers/base/dmabuf-sync.c
+index 14c0c6f..fdf3bce 100644
+--- a/drivers/base/dmabuf-sync.c
++++ b/drivers/base/dmabuf-sync.c
+@@ -394,19 +394,16 @@ static int dmabuf_sync_get_obj(struct dmabuf_sync *sync, struct dma_buf *dmabuf,
+               return -ENOMEM;
+       }
++      get_dma_buf(dmabuf);
++
+       sobj->dmabuf = dmabuf;
+       sobj->robj = dmabuf->sync;
++      sobj->access_type = type;
+       mutex_lock(&sync->lock);
+       list_add_tail(&sobj->head, &sync->syncs);
+       mutex_unlock(&sync->lock);
+-      get_dma_buf(dmabuf);
+-
+-      mutex_lock(&sobj->robj->lock);
+-      sobj->access_type = type;
+-      mutex_unlock(&sobj->robj->lock);
+-
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0429-dmabuf-sync-add-private-backend-callbacks.patch b/patches.tizen/0429-dmabuf-sync-add-private-backend-callbacks.patch
new file mode 100644 (file)
index 0000000..6563d32
--- /dev/null
@@ -0,0 +1,117 @@
+From 31f5922a1b8094cdad94336b87178765165b0a35 Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Mon, 22 Jul 2013 12:52:01 +0900
+Subject: [PATCH 0429/1302] dmabuf-sync: add private backend callbacks
+
+This ops has just a free callback to release resource for each
+device driver. free callback will be called when device driver's
+sync object is freed. So device drivers should implement this callback
+so that their own contexts can be cleaned up regarding sync object.
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/base/dmabuf-sync.c  |  8 +++++++-
+ include/linux/dmabuf-sync.h | 32 ++++++++++++++++++++------------
+ 2 files changed, 27 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/base/dmabuf-sync.c b/drivers/base/dmabuf-sync.c
+index fdf3bce..abfd8e3 100644
+--- a/drivers/base/dmabuf-sync.c
++++ b/drivers/base/dmabuf-sync.c
+@@ -320,7 +320,9 @@ EXPORT_SYMBOL(is_dmabuf_sync_supported);
+  * The caller can get a new sync object for buffer synchronization
+  * through this function.
+  */
+-struct dmabuf_sync *dmabuf_sync_init(void *priv, const char *name)
++struct dmabuf_sync *dmabuf_sync_init(const char *name,
++                                      struct dmabuf_sync_priv_ops *ops,
++                                      void *priv)
+ {
+       struct dmabuf_sync *sync;
+@@ -330,6 +332,7 @@ struct dmabuf_sync *dmabuf_sync_init(void *priv, const char *name)
+       strncpy(sync->name, name, ARRAY_SIZE(sync->name) - 1);
++      sync->ops = ops;
+       sync->priv = priv;
+       INIT_LIST_HEAD(&sync->syncs);
+       mutex_init(&sync->lock);
+@@ -353,6 +356,9 @@ void dmabuf_sync_fini(struct dmabuf_sync *sync)
+       if (WARN_ON(!sync))
+               return;
++      if (sync->ops && sync->ops->free)
++              sync->ops->free(sync->priv);
++
+       kfree(sync);
+ }
+ EXPORT_SYMBOL(dmabuf_sync_fini);
+diff --git a/include/linux/dmabuf-sync.h b/include/linux/dmabuf-sync.h
+index 963ba99..d4dcf4f 100644
+--- a/include/linux/dmabuf-sync.h
++++ b/include/linux/dmabuf-sync.h
+@@ -43,6 +43,10 @@ struct dmabuf_sync_object {
+       unsigned int                    access_type;
+ };
++struct dmabuf_sync_priv_ops {
++      void (*free)(void *priv);
++};
++
+ /*
+  * A structure for dmabuf_sync.
+  *
+@@ -57,15 +61,16 @@ struct dmabuf_sync_object {
+  * @status: Indicate current status (DMABUF_SYNC_GOT or DMABUF_SYNC_LOCKED).
+  */
+ struct dmabuf_sync {
+-      struct list_head        syncs;
+-      struct list_head        list;
+-      struct mutex            lock;
+-      struct ww_acquire_ctx   ctx;
+-      struct work_struct      work;
+-      void                    *priv;
+-      char                    name[64];
+-      struct timer_list       timer;
+-      unsigned int            status;
++      struct list_head                syncs;
++      struct list_head                list;
++      struct mutex                    lock;
++      struct ww_acquire_ctx           ctx;
++      struct work_struct              work;
++      void                            *priv;
++      struct dmabuf_sync_priv_ops     *ops;
++      char                            name[64];
++      struct timer_list               timer;
++      unsigned int                    status;
+ };
+ #ifdef CONFIG_DMABUF_SYNC
+@@ -104,7 +109,9 @@ static inline void dmabuf_sync_reservation_fini(struct dma_buf *dmabuf)
+ extern bool is_dmabuf_sync_supported(void);
+-extern struct dmabuf_sync *dmabuf_sync_init(void *priv, const char *name);
++extern struct dmabuf_sync *dmabuf_sync_init(const char *name,
++                                      struct dmabuf_sync_priv_ops *ops,
++                                      void *priv);
+ extern void dmabuf_sync_fini(struct dmabuf_sync *sync);
+@@ -132,8 +139,9 @@ static inline void dmabuf_sync_reservation_fini(struct dma_buf *dmabuf) { }
+ static inline bool is_dmabuf_sync_supported(void) { return false; }
+-static inline struct dmabuf_sync *dmabuf_sync_init(void *priv,
+-                                      const char *names)
++static inline  struct dmabuf_sync *dmabuf_sync_init(const char *name,
++                                      struct dmabuf_sync_priv_ops *ops,
++                                      void *priv)
+ {
+       return ERR_PTR(0);
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0430-drm-exynos-fix-module-build-error.patch b/patches.tizen/0430-drm-exynos-fix-module-build-error.patch
new file mode 100644 (file)
index 0000000..1a6e1cb
--- /dev/null
@@ -0,0 +1,68 @@
+From 873194bdec78086cadc49779b1199046a7211541 Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Mon, 22 Jul 2013 19:57:05 +0900
+Subject: [PATCH 0430/1302] drm/exynos: fix module build error
+
+Exynos drm drivers don't need to export device tables because
+all devices of Exynos drm include in one SoC so they cannot be
+plugged in.
+
+P.S. we need to create MODULE_DEVICE_TABLE in case of enabling
+the linux-hotplug system to load the driver automatically when
+the device is plugged in.
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_fimd.c    | 2 --
+ drivers/gpu/drm/exynos/exynos_drm_g2d.c     | 1 -
+ drivers/gpu/drm/exynos/exynos_drm_rotator.c | 1 -
+ 3 files changed, 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+index e8465f5..5c68289 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+@@ -117,7 +117,6 @@ static const struct of_device_id fimd_driver_dt_match[] = {
+         .data = &exynos5_fimd_driver_data },
+       {},
+ };
+-MODULE_DEVICE_TABLE(of, fimd_driver_dt_match);
+ #endif
+ static inline struct fimd_driver_data *drm_fimd_get_driver_data(
+@@ -1120,7 +1119,6 @@ static struct platform_device_id fimd_driver_ids[] = {
+       },
+       {},
+ };
+-MODULE_DEVICE_TABLE(platform, fimd_driver_ids);
+ static const struct dev_pm_ops fimd_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(fimd_suspend, fimd_resume)
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+index 7a6e310..310fbe8 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+@@ -1526,7 +1526,6 @@ static const struct of_device_id exynos_g2d_match[] = {
+       { .compatible = "samsung,exynos5250-g2d" },
+       {},
+ };
+-MODULE_DEVICE_TABLE(of, exynos_g2d_match);
+ #endif
+ struct platform_driver g2d_driver = {
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
+index 039e23a..3d38a91 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_rotator.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
+@@ -645,7 +645,6 @@ static const struct of_device_id exynos_rotator_match[] = {
+       },
+       {},
+ };
+-MODULE_DEVICE_TABLE(of, exynos_rotator_match);
+ static int rotator_parse_dt_tbl(struct device_node *np, struct rot_limit *rlim)
+ {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0431-ARM-dts-exynos4412-slp_pq-add-fimd-iommu-related-pro.patch b/patches.tizen/0431-ARM-dts-exynos4412-slp_pq-add-fimd-iommu-related-pro.patch
new file mode 100644 (file)
index 0000000..3a487bf
--- /dev/null
@@ -0,0 +1,28 @@
+From b0f23dd65ec947fcf7a83b5c1cf866949ba72a0f Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Tue, 23 Jul 2013 17:26:35 +0900
+Subject: [PATCH 0431/1302] ARM: dts: exynos4412-slp_pq: add fimd iommu related
+ properties
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index ab09bd2..44f1c3a 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -1015,6 +1015,8 @@
+       };
+       sysmmu-fimd0 {
++              clock-names = "sysmmu";
++              clocks = <&clock 287>;
+               mmu-master = <&fimd>;
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0432-ARM-configs-update-tizen_defconfig.patch b/patches.tizen/0432-ARM-configs-update-tizen_defconfig.patch
new file mode 100644 (file)
index 0000000..7399a8b
--- /dev/null
@@ -0,0 +1,87 @@
+From 692d66f6975d2b5c4d29d5b5402b5d38a68d564c Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Tue, 23 Jul 2013 18:00:16 +0900
+Subject: [PATCH 0432/1302] ARM: configs: update tizen_defconfig
+
+Enabling exynos drm iommu support and disabling DRM based
+IPP drivers. IPP drivers don't support IOMMU yet.
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_defconfig | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index 6aaec32..8a54a1b 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -183,6 +183,7 @@ CONFIG_HAVE_DMA_ATTRS=y
+ CONFIG_HAVE_DMA_CONTIGUOUS=y
+ CONFIG_USE_GENERIC_SMP_HELPERS=y
+ CONFIG_GENERIC_SMP_IDLE_THREAD=y
++CONFIG_GENERIC_IDLE_POLL_SETUP=y
+ CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+ CONFIG_HAVE_CLK=y
+ CONFIG_HAVE_DMA_API_DEBUG=y
+@@ -191,6 +192,7 @@ CONFIG_HAVE_ARCH_JUMP_LABEL=y
+ CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+ CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+ CONFIG_HAVE_CONTEXT_TRACKING=y
++CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+ CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+ CONFIG_MODULES_USE_ELF_REL=y
+ CONFIG_CLONE_BACKWARDS=y
+@@ -420,6 +422,7 @@ CONFIG_MULTI_IRQ_HANDLER=y
+ # CONFIG_ARM_ERRATA_742230 is not set
+ # CONFIG_ARM_ERRATA_742231 is not set
+ # CONFIG_PL310_ERRATA_588369 is not set
++# CONFIG_ARM_ERRATA_643719 is not set
+ # CONFIG_ARM_ERRATA_720789 is not set
+ # CONFIG_PL310_ERRATA_727915 is not set
+ CONFIG_ARM_ERRATA_743622=y
+@@ -1049,6 +1052,7 @@ CONFIG_REGMAP_SPI=y
+ CONFIG_REGMAP_MMIO=y
+ CONFIG_REGMAP_IRQ=y
+ CONFIG_DMA_SHARED_BUFFER=y
++# CONFIG_DMABUF_SYNC is not set
+ CONFIG_CMA=y
+ CONFIG_CMA_DEBUG=y
+@@ -1719,6 +1723,7 @@ CONFIG_POWER_SUPPLY=y
+ CONFIG_BATTERY_MAX17040=y
+ CONFIG_BATTERY_MAX17042=y
+ # CONFIG_BATTERY_S3C_ADC is not set
++# CONFIG_CHARGER_ISP1704 is not set
+ # CONFIG_CHARGER_MAX8903 is not set
+ # CONFIG_CHARGER_LP8727 is not set
+ # CONFIG_CHARGER_GPIO is not set
+@@ -2069,15 +2074,13 @@ CONFIG_DRM_KMS_HELPER=y
+ # CONFIG_DRM_I2C_SIL164 is not set
+ # CONFIG_DRM_I2C_NXP_TDA998X is not set
+ CONFIG_DRM_EXYNOS=y
+-# CONFIG_DRM_EXYNOS_IOMMU is not set
++CONFIG_DRM_EXYNOS_IOMMU=y
+ CONFIG_DRM_EXYNOS_DMABUF=y
+ CONFIG_DRM_EXYNOS_FIMD=y
+ # CONFIG_DRM_EXYNOS_HDMI is not set
+ CONFIG_DRM_EXYNOS_VIDI=y
+ CONFIG_DRM_EXYNOS_G2D=y
+-CONFIG_DRM_EXYNOS_IPP=y
+-CONFIG_DRM_EXYNOS_FIMC=y
+-CONFIG_DRM_EXYNOS_ROTATOR=y
++# CONFIG_DRM_EXYNOS_IPP is not set
+ # CONFIG_DRM_UDL is not set
+ # CONFIG_DRM_TILCDC is not set
+ # CONFIG_VGASTATE is not set
+@@ -3147,6 +3150,7 @@ CONFIG_HAVE_DEBUG_KMEMLEAK=y
+ # CONFIG_RT_MUTEX_TESTER is not set
+ # CONFIG_DEBUG_SPINLOCK is not set
+ # CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
+ # CONFIG_DEBUG_LOCK_ALLOC is not set
+ # CONFIG_PROVE_LOCKING is not set
+ # CONFIG_LOCK_STAT is not set
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0433-drm-exynos-consider-common-clock-framework-to-g2d-dr.patch b/patches.tizen/0433-drm-exynos-consider-common-clock-framework-to-g2d-dr.patch
new file mode 100644 (file)
index 0000000..d0f21c6
--- /dev/null
@@ -0,0 +1,40 @@
+From 3a2b9e1a30d68b966e4ebb27c63589c83530624f Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Wed, 24 Jul 2013 13:40:12 +0900
+Subject: [PATCH 0433/1302] drm/exynos: consider common clock framework to g2d
+ driver.
+
+This patch just changes clk_enable/disable to
+clk_prepare_enable/clk_disable_unprepare.
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_g2d.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+index 310fbe8..3925e44 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+@@ -812,7 +812,7 @@ static void g2d_dma_start(struct g2d_data *g2d,
+                                               struct g2d_cmdlist_node, list);
+       pm_runtime_get_sync(g2d->dev);
+-      clk_enable(g2d->gate_clk);
++      clk_prepare_enable(g2d->gate_clk);
+       writel_relaxed(node->dma_addr, g2d->regs + G2D_DMA_SFR_BASE_ADDR);
+       writel_relaxed(G2D_DMA_START, g2d->regs + G2D_DMA_COMMAND);
+@@ -865,7 +865,7 @@ static void g2d_runqueue_worker(struct work_struct *work)
+                                           runqueue_work);
+       mutex_lock(&g2d->runqueue_mutex);
+-      clk_disable(g2d->gate_clk);
++      clk_disable_unprepare(g2d->gate_clk);
+       pm_runtime_put_sync(g2d->dev);
+       complete(&g2d->runqueue_node->complete);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0434-ARM-dts-exynos4412-slp_pq-add-device-node-for-g2d-io.patch b/patches.tizen/0434-ARM-dts-exynos4412-slp_pq-add-device-node-for-g2d-io.patch
new file mode 100644 (file)
index 0000000..6a2f9c3
--- /dev/null
@@ -0,0 +1,57 @@
+From 178bfa57cc7f1efbe5f796a9048a349981b45da1 Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Wed, 24 Jul 2013 13:41:34 +0900
+Subject: [PATCH 0434/1302] ARM: dts: exynos4412-slp_pq: add device node for
+ g2d iommu
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 10 ++++++++++
+ arch/arm/boot/dts/exynos4x12.dtsi       |  2 +-
+ 2 files changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 44f1c3a..9007770 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -1010,6 +1010,10 @@
+               status = "okay";
+       };
++      g2d@10800000 {
++              status = "okay";
++      };
++
+       vidi {
+               compatible = "samsung,exynos-drm-vidi";
+       };
+@@ -1020,6 +1024,12 @@
+               mmu-master = <&fimd>;
+       };
++      sysmmu-g2d {
++              clock-names = "sysmmu";
++              clocks = <&clock 280>;
++              mmu-master = <&g2d>;
++      };
++
+       usbphy@125B0000 {
+               status = "okay";
+       };
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index b336bd5..da3b793 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -98,7 +98,7 @@
+               interrupts = <0 72 0>;
+       };
+-      g2d@10800000 {
++      g2d: g2d@10800000 {
+               compatible = "samsung,exynos4212-g2d";
+               reg = <0x10800000 0x1000>;
+               interrupts = <0 89 0>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0435-mmc-dw_mmc-fix-error-return-code-in-dw_mci_probe.patch b/patches.tizen/0435-mmc-dw_mmc-fix-error-return-code-in-dw_mci_probe.patch
new file mode 100644 (file)
index 0000000..9b44c8b
--- /dev/null
@@ -0,0 +1,36 @@
+From 4e7e9ad941af42a8cb7caff4c9756513309d04c8 Mon Sep 17 00:00:00 2001
+From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
+Date: Fri, 19 Apr 2013 09:25:45 +0800
+Subject: [PATCH 0435/1302] mmc: dw_mmc: fix error return code in
+ dw_mci_probe()
+
+Fix to return -ENOMEM in alloc workqueue error case instead
+of 0, as done elsewhere in this function.
+
+Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
+Acked-by: Seungwon Jeon <tgih.jun@samsung.com>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mmc/host/dw_mmc.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
+index bc3a1bc..0652690 100644
+--- a/drivers/mmc/host/dw_mmc.c
++++ b/drivers/mmc/host/dw_mmc.c
+@@ -2321,8 +2321,10 @@ int dw_mci_probe(struct dw_mci *host)
+       tasklet_init(&host->tasklet, dw_mci_tasklet_func, (unsigned long)host);
+       host->card_workqueue = alloc_workqueue("dw-mci-card",
+                       WQ_MEM_RECLAIM | WQ_NON_REENTRANT, 1);
+-      if (!host->card_workqueue)
++      if (!host->card_workqueue) {
++              ret = -ENOMEM;
+               goto err_dmaunmap;
++      }
+       INIT_WORK(&host->card_work, dw_mci_work_routine_card);
+       ret = devm_request_irq(host->dev, host->irq, dw_mci_interrupt,
+                              host->irq_flags, "dw-mci", host);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0436-mmc-dw_mmc-clear-IDSTS-register-when-initialize-IDMA.patch b/patches.tizen/0436-mmc-dw_mmc-clear-IDSTS-register-when-initialize-IDMA.patch
new file mode 100644 (file)
index 0000000..251cd10
--- /dev/null
@@ -0,0 +1,45 @@
+From 356b0529db5f17e6716c23b3d17c108a2775171b Mon Sep 17 00:00:00 2001
+From: Joonyoung Shim <jy0922.shim@samsung.com>
+Date: Fri, 26 Apr 2013 15:35:22 +0900
+Subject: [PATCH 0436/1302] mmc: dw_mmc: clear IDSTS register when initialize
+ IDMAC
+
+If pending interrupt for IDMAC exists when initialize IDMAC, it will
+call interrupt handler unnecessarily.
+
+Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
+Acked-by: Seungwon Jeon <tgih.jun@samsung.com>
+Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mmc/host/dw_mmc.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
+index 0652690..b10e5e1 100644
+--- a/drivers/mmc/host/dw_mmc.c
++++ b/drivers/mmc/host/dw_mmc.c
+@@ -51,6 +51,11 @@
+ #define DW_MCI_DMA_THRESHOLD  16
+ #ifdef CONFIG_MMC_DW_IDMAC
++#define IDMAC_INT_CLR         (SDMMC_IDMAC_INT_AI | SDMMC_IDMAC_INT_NI | \
++                               SDMMC_IDMAC_INT_CES | SDMMC_IDMAC_INT_DU | \
++                               SDMMC_IDMAC_INT_FBE | SDMMC_IDMAC_INT_RI | \
++                               SDMMC_IDMAC_INT_TI)
++
+ struct idmac_desc {
+       u32             des0;   /* Control Descriptor */
+ #define IDMAC_DES0_DIC        BIT(1)
+@@ -433,6 +438,7 @@ static int dw_mci_idmac_init(struct dw_mci *host)
+       mci_writel(host, BMOD, SDMMC_IDMAC_SWRESET);
+       /* Mask out interrupts - get Tx & Rx complete only */
++      mci_writel(host, IDSTS, IDMAC_INT_CLR);
+       mci_writel(host, IDINTEN, SDMMC_IDMAC_INT_NI | SDMMC_IDMAC_INT_RI |
+                  SDMMC_IDMAC_INT_TI);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0437-mmc-dw_mmc-change-the-macro-name-from-DTO-to-DRTO.patch b/patches.tizen/0437-mmc-dw_mmc-change-the-macro-name-from-DTO-to-DRTO.patch
new file mode 100644 (file)
index 0000000..9499c34
--- /dev/null
@@ -0,0 +1,58 @@
+From 25f874d38d3982a440dbe93819da785554fc26ec Mon Sep 17 00:00:00 2001
+From: Jaehoon Chung <jh80.chung@samsung.com>
+Date: Mon, 27 May 2013 13:47:57 +0900
+Subject: [PATCH 0437/1302] mmc: dw_mmc: change the macro name from DTO to DRTO
+
+At Interrupt status register, Bit9 is Data Read Timeout.
+But we used macro name as the DTO. It could be confused with the
+Data Transfer Over(DTO)-Bit[3].
+It's clearly that is changed the DRTO instead of DTO.
+
+Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
+Reviewed-by: James Hogan <james.hogan@imgtec.com>
+Acked-by: Seungwon Jeon <tgih.jun@samsung.com>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mmc/host/dw_mmc.c | 4 ++--
+ drivers/mmc/host/dw_mmc.h | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
+index b10e5e1..7dca5e9 100644
+--- a/drivers/mmc/host/dw_mmc.c
++++ b/drivers/mmc/host/dw_mmc.c
+@@ -39,7 +39,7 @@
+ #include "dw_mmc.h"
+ /* Common flag combinations */
+-#define DW_MCI_DATA_ERROR_FLAGS       (SDMMC_INT_DTO | SDMMC_INT_DCRC | \
++#define DW_MCI_DATA_ERROR_FLAGS       (SDMMC_INT_DRTO | SDMMC_INT_DCRC | \
+                                SDMMC_INT_HTO | SDMMC_INT_SBE  | \
+                                SDMMC_INT_EBE)
+ #define DW_MCI_CMD_ERROR_FLAGS        (SDMMC_INT_RTO | SDMMC_INT_RCRC | \
+@@ -1093,7 +1093,7 @@ static void dw_mci_tasklet_func(unsigned long priv)
+                       status = host->data_status;
+                       if (status & DW_MCI_DATA_ERROR_FLAGS) {
+-                              if (status & SDMMC_INT_DTO) {
++                              if (status & SDMMC_INT_DRTO) {
+                                       data->error = -ETIMEDOUT;
+                               } else if (status & SDMMC_INT_DCRC) {
+                                       data->error = -EILSEQ;
+diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
+index 0b74189..2f52c87 100644
+--- a/drivers/mmc/host/dw_mmc.h
++++ b/drivers/mmc/host/dw_mmc.h
+@@ -98,7 +98,7 @@
+ #define SDMMC_INT_HLE                 BIT(12)
+ #define SDMMC_INT_FRUN                        BIT(11)
+ #define SDMMC_INT_HTO                 BIT(10)
+-#define SDMMC_INT_DTO                 BIT(9)
++#define SDMMC_INT_DRTO                        BIT(9)
+ #define SDMMC_INT_RTO                 BIT(8)
+ #define SDMMC_INT_DCRC                        BIT(7)
+ #define SDMMC_INT_RCRC                        BIT(6)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0438-mmc-dw_mmc-Handle-late-vmmc-regulators-with-EPROBE_D.patch b/patches.tizen/0438-mmc-dw_mmc-Handle-late-vmmc-regulators-with-EPROBE_D.patch
new file mode 100644 (file)
index 0000000..4943802
--- /dev/null
@@ -0,0 +1,112 @@
+From 301f8ceba8ac5a1917c56765e70c6827c2bce5c6 Mon Sep 17 00:00:00 2001
+From: Doug Anderson <dianders@chromium.org>
+Date: Fri, 7 Jun 2013 10:28:29 -0700
+Subject: [PATCH 0438/1302] mmc: dw_mmc: Handle late vmmc regulators with
+ EPROBE_DEFER
+
+It is possible to specify a regulator that should be turned on when
+dw_mmc is probed.  At the moment dw_mmc will fail to use the regulator
+properly if the regulator probes after dw_mmc.  Fix this problem by
+honoring EPROBE_DEFER.
+
+At the same time move the regulator code out of the slot init code.
+We only specify one regulator for the whole device and other parts of
+the code (like suspend/resume) assume that the regulator has only been
+enabled once.
+
+Signed-off-by: Doug Anderson <dianders@chromium.org>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/mmc/synopsis-dw-mshc.txt   |  4 +++
+ drivers/mmc/host/dw_mmc.c                          | 34 +++++++++++++---------
+ 2 files changed, 24 insertions(+), 14 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt
+index 726fd21..d5cc94e 100644
+--- a/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt
++++ b/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt
+@@ -55,6 +55,9 @@ Optional properties:
+ * broken-cd: as documented in mmc core bindings.
++* vmmc-supply: The phandle to the regulator to use for vmmc.  If this is
++  specified we'll defer probe until we can find this regulator.
++
+ Aliases:
+ - All the MSHC controller nodes should be represented in the aliases node using
+@@ -79,6 +82,7 @@ board specific portions as listed below.
+               broken-cd;
+               fifo-depth = <0x80>;
+               card-detect-delay = <200>;
++              vmmc-supply = <&buck8>;
+               slot@0 {
+                       reg = <0>;
+diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
+index 7dca5e9..957f5d7 100644
+--- a/drivers/mmc/host/dw_mmc.c
++++ b/drivers/mmc/host/dw_mmc.c
+@@ -1991,19 +1991,6 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
+ #endif /* CONFIG_MMC_DW_IDMAC */
+       }
+-      host->vmmc = devm_regulator_get(mmc_dev(mmc), "vmmc");
+-      if (IS_ERR(host->vmmc)) {
+-              pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc));
+-              host->vmmc = NULL;
+-      } else {
+-              ret = regulator_enable(host->vmmc);
+-              if (ret) {
+-                      dev_err(host->dev,
+-                              "failed to enable regulator: %d\n", ret);
+-                      goto err_setup_bus;
+-              }
+-      }
+-
+       if (dw_mci_get_cd(mmc))
+               set_bit(DW_MMC_CARD_PRESENT, &slot->flags);
+       else
+@@ -2235,11 +2222,29 @@ int dw_mci_probe(struct dw_mci *host)
+               }
+       }
++      host->vmmc = devm_regulator_get(host->dev, "vmmc");
++      if (IS_ERR(host->vmmc)) {
++              ret = PTR_ERR(host->vmmc);
++              if (ret == -EPROBE_DEFER)
++                      goto err_clk_ciu;
++
++              dev_info(host->dev, "no vmmc regulator found: %d\n", ret);
++              host->vmmc = NULL;
++      } else {
++              ret = regulator_enable(host->vmmc);
++              if (ret) {
++                      if (ret != -EPROBE_DEFER)
++                              dev_err(host->dev,
++                                      "regulator_enable fail: %d\n", ret);
++                      goto err_clk_ciu;
++              }
++      }
++
+       if (!host->bus_hz) {
+               dev_err(host->dev,
+                       "Platform data must supply bus speed\n");
+               ret = -ENODEV;
+-              goto err_clk_ciu;
++              goto err_regulator;
+       }
+       host->quirks = host->pdata->quirks;
+@@ -2386,6 +2391,7 @@ err_dmaunmap:
+       if (host->use_dma && host->dma_ops->exit)
+               host->dma_ops->exit(host);
++err_regulator:
+       if (host->vmmc)
+               regulator_disable(host->vmmc);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0439-mmc-dw_mmc-Add-the-ability-to-set-the-ciu-clock-freq.patch b/patches.tizen/0439-mmc-dw_mmc-Add-the-ability-to-set-the-ciu-clock-freq.patch
new file mode 100644 (file)
index 0000000..42a5fc0
--- /dev/null
@@ -0,0 +1,113 @@
+From 9fe621e95bea01096a5b99468a47ea039344c5c4 Mon Sep 17 00:00:00 2001
+From: Doug Anderson <dianders@chromium.org>
+Date: Fri, 7 Jun 2013 10:28:30 -0700
+Subject: [PATCH 0439/1302] mmc: dw_mmc: Add the ability to set the ciu clock
+ frequency
+
+As of now we rely on code outside of the driver to set the ciu clock
+frequency.  There's no reason to do that.  Add support for setting up
+the clock in the driver during probe.
+
+Signed-off-by: Doug Anderson <dianders@chromium.org>
+Acked-by: Jaehoon Chung <jh80.chung@samsung.com>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/mmc/synopsis-dw-mshc.txt        | 16 ++++++++++++++++
+ drivers/mmc/host/dw_mmc.c                               | 17 +++++++++++++----
+ 2 files changed, 29 insertions(+), 4 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt
+index d5cc94e..dd31b00 100644
+--- a/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt
++++ b/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt
+@@ -39,6 +39,19 @@ Required Properties:
+ Optional properties:
++* clocks: from common clock binding: handle to biu and ciu clocks for the
++  bus interface unit clock and the card interface unit clock.
++
++* clock-names: from common clock binding: Shall be "biu" and "ciu".
++  If the biu clock is missing we'll simply skip enabling it.  If the
++  ciu clock is missing we'll just assume that the clock is running at
++  clock-frequency.  It is an error to omit both the ciu clock and the
++  clock-frequency.
++
++* clock-frequency: should be the frequency (in Hz) of the ciu clock.  If this
++  is specified and the ciu clock is specified then we'll try to set the ciu
++  clock to this at probe time.
++
+ * num-slots: specifies the number of slots supported by the controller.
+   The number of physical slots actually used could be equal or less than the
+   value specified by num-slots. If this property is not specified, the value
+@@ -70,6 +83,8 @@ board specific portions as listed below.
+       dwmmc0@12200000 {
+               compatible = "snps,dw-mshc";
++              clocks = <&clock 351>, <&clock 132>;
++              clock-names = "biu", "ciu";
+               reg = <0x12200000 0x1000>;
+               interrupts = <0 75 0>;
+               #address-cells = <1>;
+@@ -77,6 +92,7 @@ board specific portions as listed below.
+       };
+       dwmmc0@12200000 {
++              clock-frequency = <400000000>;
+               num-slots = <1>;
+               supports-highspeed;
+               broken-cd;
+diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
+index 957f5d7..ee5f167 100644
+--- a/drivers/mmc/host/dw_mmc.c
++++ b/drivers/mmc/host/dw_mmc.c
+@@ -2117,6 +2117,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
+       struct device_node *np = dev->of_node;
+       const struct dw_mci_drv_data *drv_data = host->drv_data;
+       int idx, ret;
++      u32 clock_frequency;
+       pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+       if (!pdata) {
+@@ -2143,6 +2144,9 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
+       of_property_read_u32(np, "card-detect-delay", &pdata->detect_delay_ms);
++      if (!of_property_read_u32(np, "clock-frequency", &clock_frequency))
++              pdata->bus_hz = clock_frequency;
++
+       if (drv_data && drv_data->parse_dt) {
+               ret = drv_data->parse_dt(host);
+               if (ret)
+@@ -2200,18 +2204,23 @@ int dw_mci_probe(struct dw_mci *host)
+       host->ciu_clk = devm_clk_get(host->dev, "ciu");
+       if (IS_ERR(host->ciu_clk)) {
+               dev_dbg(host->dev, "ciu clock not available\n");
++              host->bus_hz = host->pdata->bus_hz;
+       } else {
+               ret = clk_prepare_enable(host->ciu_clk);
+               if (ret) {
+                       dev_err(host->dev, "failed to enable ciu clock\n");
+                       goto err_clk_biu;
+               }
+-      }
+-      if (IS_ERR(host->ciu_clk))
+-              host->bus_hz = host->pdata->bus_hz;
+-      else
++              if (host->pdata->bus_hz) {
++                      ret = clk_set_rate(host->ciu_clk, host->pdata->bus_hz);
++                      if (ret)
++                              dev_warn(host->dev,
++                                       "Unable to set bus rate to %ul\n",
++                                       host->pdata->bus_hz);
++              }
+               host->bus_hz = clk_get_rate(host->ciu_clk);
++      }
+       if (drv_data && drv_data->setup_clock) {
+               ret = drv_data->setup_clock(host);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0440-ARM-dts-enable-dw-mmc-controlle-instead-of-sdhci-con.patch b/patches.tizen/0440-ARM-dts-enable-dw-mmc-controlle-instead-of-sdhci-con.patch
new file mode 100644 (file)
index 0000000..fe6e3eb
--- /dev/null
@@ -0,0 +1,52 @@
+From f7ee1cbbdc3f7b15b6b0944bfd65f9363cedc801 Mon Sep 17 00:00:00 2001
+From: Jaehoon Chung <jh80.chung@samsung.com>
+Date: Wed, 24 Jul 2013 14:45:33 +0900
+Subject: [PATCH 0440/1302] ARM: dts: enable dw-mmc controlle instead of sdhci
+ controller
+
+Using dw-mmc controller.
+
+Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 21 +++++++++++++++++----
+ 1 file changed, 17 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 9007770..fbcf7b3 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -254,13 +254,26 @@
+               enable-active-high;
+       };
+-      sdhci_emmc: sdhci@12510000 {
+-              bus-width = <8>;
++      mshc@12550000 {
++              num-slots = <1>;
++              supports-highspeed;
++              broken-cd;
+               non-removable;
+-              pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus8>;
+-              pinctrl-names = "default";
++              fifo-depth = <0x80>;
++              card-detect-delay = <200>;
+               vmmc-supply = <&vemmc_reg>;
++              clock-frequency = <400000000>;
++              samsung,dw-mshc-ciu-div = <0>;
++              samsung,dw-mshc-sdr-timing = <2 3>;
++              samsung,dw-mshc-ddr-timing = <1 2>;
++              pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>;
++              pinctrl-names = "default";
+               status = "okay";
++
++              slot@0 {
++                      reg = <0>;
++                      bus-width = <8>;
++              };
+       };
+       sdhci_sd: sdhci@12530000 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0441-ARM-dts-updated-the-dwmmc-device-tree-for-clk-name.patch b/patches.tizen/0441-ARM-dts-updated-the-dwmmc-device-tree-for-clk-name.patch
new file mode 100644 (file)
index 0000000..41a9fcd
--- /dev/null
@@ -0,0 +1,30 @@
+From cbd87a0e8de7a62309a68e194203dcf525680c77 Mon Sep 17 00:00:00 2001
+From: Jaehoon Chung <jh80.chung@samsung.com>
+Date: Wed, 3 Jul 2013 15:19:29 +0900
+Subject: [PATCH 0441/1302] ARM: dts: updated the dwmmc device tree for clk
+ name
+
+To get clk for dwmmc, added the clk-name.
+
+Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index fbcf7b3..20a5c86 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -261,6 +261,8 @@
+               non-removable;
+               fifo-depth = <0x80>;
+               card-detect-delay = <200>;
++              clocks = <&clock 351>, <&clock 132>;
++              clock-name = "biu", "ciu";
+               vmmc-supply = <&vemmc_reg>;
+               clock-frequency = <400000000>;
+               samsung,dw-mshc-ciu-div = <0>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0442-clock-clk-exynos4-set-the-CLK_SET_RATE_PARENT-for-mm.patch b/patches.tizen/0442-clock-clk-exynos4-set-the-CLK_SET_RATE_PARENT-for-mm.patch
new file mode 100644 (file)
index 0000000..4e9879a
--- /dev/null
@@ -0,0 +1,38 @@
+From a9caf2743da97298d75e0d1234f7a21d91f532e6 Mon Sep 17 00:00:00 2001
+From: Jaehoon Chung <jh80.chung@samsung.com>
+Date: Wed, 24 Jul 2013 14:11:08 +0900
+Subject: [PATCH 0442/1302] clock: clk-exynos4: set the CLK_SET_RATE_PARENT for
+ mmc4
+
+mmc4_clk set to CLK_SET_PARENT with DIV_F().
+
+Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/samsung/clk-exynos4.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
+index adb1352..f8ff509 100644
+--- a/drivers/clk/samsung/clk-exynos4.c
++++ b/drivers/clk/samsung/clk-exynos4.c
+@@ -525,7 +525,6 @@ struct samsung_div_clock exynos4_div_clks[] __initdata = {
+       DIV(sclk_i2s1, "sclk_i2s1", "sclk_audio1", DIV_PERIL5, 0, 6),
+       DIV(sclk_i2s2, "sclk_i2s2", "sclk_audio2", DIV_PERIL5, 8, 6),
+       DIV(none, "div_mmc4", "mout_mmc4", DIV_FSYS3, 0, 4),
+-      DIV(none, "div_mmc_pre4", "div_mmc4", DIV_FSYS3, 8, 8),
+       DIV(none, "div_uart0", "mout_uart0", DIV_PERIL0, 0, 4),
+       DIV(none, "div_uart1", "mout_uart1", DIV_PERIL0, 4, 4),
+       DIV(none, "div_uart2", "mout_uart2", DIV_PERIL0, 8, 4),
+@@ -552,6 +551,8 @@ struct samsung_div_clock exynos4_div_clks[] __initdata = {
+                       CLK_SET_RATE_PARENT, 0),
+       DIV_F(none, "div_mmc_pre3", "div_mmc3", DIV_FSYS2, 24, 8,
+                       CLK_SET_RATE_PARENT, 0),
++      DIV_F(none, "div_mmc_pre4", "div_mmc4", DIV_FSYS3, 8, 8,
++                      CLK_SET_RATE_PARENT, 0),
+ };
+ /* list of divider clocks supported in exynos4210 soc */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0443-ARM-tizen_defconfig-enable-the-exynos-dw-mmc.patch b/patches.tizen/0443-ARM-tizen_defconfig-enable-the-exynos-dw-mmc.patch
new file mode 100644 (file)
index 0000000..a0f4b57
--- /dev/null
@@ -0,0 +1,29 @@
+From 4137c290f462f96daf1ad52a9dc61b7a6322c68e Mon Sep 17 00:00:00 2001
+From: Jaehoon Chung <jh80.chung@samsung.com>
+Date: Wed, 24 Jul 2013 14:47:31 +0900
+Subject: [PATCH 0443/1302] ARM: tizen_defconfig: enable the exynos dw-mmc
+
+For using dw_mmc-exynos, updated the tizen_defconfig
+
+Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_defconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index 8a54a1b..0b55856 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -2479,7 +2479,7 @@ CONFIG_MMC_SDHCI_S3C=y
+ CONFIG_MMC_DW=y
+ CONFIG_MMC_DW_IDMAC=y
+ CONFIG_MMC_DW_PLTFM=y
+-# CONFIG_MMC_DW_EXYNOS is not set
++CONFIG_MMC_DW_EXYNOS=y
+ # CONFIG_MMC_VUB300 is not set
+ # CONFIG_MMC_USHC is not set
+ # CONFIG_MEMSTICK is not set
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0444-drm-exynos-add-runtime-pm-interfaces-to-g2d-driver.patch b/patches.tizen/0444-drm-exynos-add-runtime-pm-interfaces-to-g2d-driver.patch
new file mode 100644 (file)
index 0000000..14de065
--- /dev/null
@@ -0,0 +1,79 @@
+From e3d059525a1d07d56db55c1db624c631b4baa277 Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Wed, 24 Jul 2013 15:28:57 +0900
+Subject: [PATCH 0444/1302] drm/exynos: add runtime pm interfaces to g2d driver
+
+This patch makes g2d power domain and clock to be controlled
+with runtime pm interfaces instead of controlling them
+respectively.
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_g2d.c | 35 +++++++++++++++++++++++++++++----
+ 1 file changed, 31 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+index 3925e44..115940b 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+@@ -810,9 +810,11 @@ static void g2d_dma_start(struct g2d_data *g2d,
+       struct g2d_cmdlist_node *node =
+                               list_first_entry(&runqueue_node->run_cmdlist,
+                                               struct g2d_cmdlist_node, list);
++      int ret;
+-      pm_runtime_get_sync(g2d->dev);
+-      clk_prepare_enable(g2d->gate_clk);
++      ret = pm_runtime_get_sync(g2d->dev);
++      if (ret < 0)
++              return;
+       writel_relaxed(node->dma_addr, g2d->regs + G2D_DMA_SFR_BASE_ADDR);
+       writel_relaxed(G2D_DMA_START, g2d->regs + G2D_DMA_COMMAND);
+@@ -865,7 +867,6 @@ static void g2d_runqueue_worker(struct work_struct *work)
+                                           runqueue_work);
+       mutex_lock(&g2d->runqueue_mutex);
+-      clk_disable_unprepare(g2d->gate_clk);
+       pm_runtime_put_sync(g2d->dev);
+       complete(&g2d->runqueue_node->complete);
+@@ -1518,7 +1519,33 @@ static int g2d_resume(struct device *dev)
+ }
+ #endif
+-static SIMPLE_DEV_PM_OPS(g2d_pm_ops, g2d_suspend, g2d_resume);
++#ifdef CONFIG_PM_RUNTIME
++static int g2d_runtime_suspend(struct device *dev)
++{
++      struct g2d_data *g2d = dev_get_drvdata(dev);
++
++      clk_disable_unprepare(g2d->gate_clk);
++
++      return 0;
++}
++
++static int g2d_runtime_resume(struct device *dev)
++{
++      struct g2d_data *g2d = dev_get_drvdata(dev);
++      int ret;
++
++      ret = clk_prepare_enable(g2d->gate_clk);
++      if (ret < 0)
++              dev_warn(dev, "failed to enable clock.\n");
++
++      return ret;
++}
++#endif
++
++static const struct dev_pm_ops g2d_pm_ops = {
++      SET_SYSTEM_SLEEP_PM_OPS(g2d_suspend, g2d_resume)
++      SET_RUNTIME_PM_OPS(g2d_runtime_suspend, g2d_runtime_resume, NULL)
++};
+ #ifdef CONFIG_OF
+ static const struct of_device_id exynos_g2d_match[] = {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0445-extcon-max77693-Fix-bug-related-to-MAX77693-irq-when.patch b/patches.tizen/0445-extcon-max77693-Fix-bug-related-to-MAX77693-irq-when.patch
new file mode 100644 (file)
index 0000000..9197b7d
--- /dev/null
@@ -0,0 +1,44 @@
+From b64315125400f4eec9f74f7536acca3e8eeca720 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Tue, 18 Jun 2013 15:01:37 +0900
+Subject: [PATCH 0445/1302] extcon: max77693: Fix bug related to MAX77693 irq
+ when set ADC debounce time
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/extcon/extcon-max77693.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c
+index b56bdaa..2f1e3f1 100644
+--- a/drivers/extcon/extcon-max77693.c
++++ b/drivers/extcon/extcon-max77693.c
+@@ -285,6 +285,14 @@ static int max77693_muic_set_path(struct max77693_muic_info *info,
+       int ret = 0;
+       u8 ctrl1, ctrl2 = 0;
++      /* Set open state to path before changing hw path */
++      ret = max77693_update_reg(info->max77693->regmap_muic,
++              MAX77693_MUIC_REG_CTRL1, CONTROL1_SW_OPEN, COMP_SW_MASK);
++      if (ret < 0) {
++              dev_err(info->dev, "failed to update MUIC register\n");
++              return ret;
++      }
++
+       if (attached)
+               ctrl1 = val;
+       else
+@@ -1246,7 +1254,7 @@ static int max77693_muic_probe(struct platform_device *pdev)
+       }
+       /* Set initial path for UART */
+-       max77693_muic_set_path(info, info->path_uart, true);
++      max77693_muic_set_path(info, info->path_uart, true);
+       /* Check revision number of MUIC device*/
+       ret = max77693_read_reg(info->max77693->regmap_muic,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0446-ARM-dts-exynos4412-redwood-Add-i2c-node-for-MAX77693.patch b/patches.tizen/0446-ARM-dts-exynos4412-redwood-Add-i2c-node-for-MAX77693.patch
new file mode 100644 (file)
index 0000000..9c9e6bf
--- /dev/null
@@ -0,0 +1,72 @@
+From 481536aa1e35399bd44b1ef8de265c1c41f17c96 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Mon, 17 Jun 2013 17:21:21 +0900
+Subject: [PATCH 0446/1302] ARM: dts: exynos4412-redwood: Add i2c node for
+ MAX77693
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-redwood.dts | 46 ++++++++++++++++++++++++++++++++
+ 1 file changed, 46 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-redwood.dts b/arch/arm/boot/dts/exynos4412-redwood.dts
+index ccb5b9b..e3ef5fe 100644
+--- a/arch/arm/boot/dts/exynos4412-redwood.dts
++++ b/arch/arm/boot/dts/exynos4412-redwood.dts
+@@ -523,6 +523,52 @@
+               };
+       };
++      i2c_if_pmic: i2c@0 {
++              compatible = "i2c-gpio";
++              gpios = <&gpm2 0 0
++                       &gpm2 1 0
++                      >;
++              #address-cells = <1>;
++              #size-cells = <0>;
++
++              max77693@66 {
++                      compatible = "maxim,max77693";
++                      interrupt-parent = <&gpx1>;
++                      interrupts = <5 2>;
++                      wakeup = <1>;
++                      reg = <0x66>;
++
++                      regulators {
++                              esafeout@1 {
++                                      regulator-compatible = "ESAFEOUT1";
++                                      regulator-name = "ESAFEOUT1";
++                                      regulator-boot-on;
++                              };
++                              esafeout@2 {
++                                      regulator-compatible = "ESAFEOUT2";
++                                      regulator-name = "ESAFEOUT2";
++                              };
++                              charger@0 {
++                                      regulator-compatible = "CHARGER";
++                                      regulator-name = "CHARGER";
++                                      regulator-min-microamp = <60000>;
++                                      regulator-max-microamp = <2580000>;
++                                      regulator-boot-on;
++                              };
++                      };
++                      muic_regs {
++                              intmask@1 {
++                                      addr = <0x7>;
++                                      data = <0x9>;
++                              };
++                              intmask@2 {
++                                      addr = <0x8>;
++                                      data = <0x1>;
++                              };
++                      };
++              };
++      };
++
+       lcd_vdd_reg: voltage-regulator@1 {
+               compatible = "regulator-fixed";
+               regulator-name = "LCD_VDD_5.0V";
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0447-ARM-tizen_defconfig-enable-unsafe-resume-config.patch b/patches.tizen/0447-ARM-tizen_defconfig-enable-unsafe-resume-config.patch
new file mode 100644 (file)
index 0000000..839089a
--- /dev/null
@@ -0,0 +1,37 @@
+From cc56ecb378bfda66c491968d0973bdfcb4af4c3a Mon Sep 17 00:00:00 2001
+From: Jaehoon Chung <jh80.chung@samsung.com>
+Date: Thu, 25 Jul 2013 13:45:27 +0900
+Subject: [PATCH 0447/1302] ARM: tizen_defconfig: enable unsafe resume config
+
+Enabled the unsafe rsume configuration
+
+Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_defconfig | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index 0b55856..7bc6e6e 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -535,6 +535,7 @@ CONFIG_CPU_FREQ=y
+ CONFIG_CPU_FREQ_TABLE=y
+ CONFIG_CPU_FREQ_GOV_COMMON=y
+ CONFIG_CPU_FREQ_STAT=y
++CONFIG_NR_CPU_LOAD_STORAGE=10
+ # CONFIG_CPU_FREQ_STAT_DETAILS is not set
+ # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+ # CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+@@ -2454,7 +2455,7 @@ CONFIG_USB_ETH_RNDIS=y
+ # CONFIG_USB_G_WEBCAM is not set
+ CONFIG_MMC=y
+ # CONFIG_MMC_DEBUG is not set
+-# CONFIG_MMC_UNSAFE_RESUME is not set
++CONFIG_MMC_UNSAFE_RESUME=y
+ # CONFIG_MMC_CLKGATE is not set
+ #
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0448-mmc-Makefile-change-the-init-sequence-for-indexing-m.patch b/patches.tizen/0448-mmc-Makefile-change-the-init-sequence-for-indexing-m.patch
new file mode 100644 (file)
index 0000000..531ab84
--- /dev/null
@@ -0,0 +1,43 @@
+From 8322d45502bb7b6ddd7194de96b072d093a2731e Mon Sep 17 00:00:00 2001
+From: Jaehoon Chung <jh80.chung@samsung.com>
+Date: Thu, 25 Jul 2013 20:12:08 +0900
+Subject: [PATCH 0448/1302] mmc: Makefile: change the init sequence for
+ indexing mmcblkX
+
+To ensure mmcblk0 for eMMC, must call the dwmmc before calling sdhci.
+
+Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mmc/host/Makefile | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
+index cd32280..a1e7bdd 100644
+--- a/drivers/mmc/host/Makefile
++++ b/drivers/mmc/host/Makefile
+@@ -6,6 +6,10 @@ obj-$(CONFIG_MMC_ARMMMCI)     += mmci.o
+ obj-$(CONFIG_MMC_PXA)         += pxamci.o
+ obj-$(CONFIG_MMC_MXC)         += mxcmmc.o
+ obj-$(CONFIG_MMC_MXS)         += mxs-mmc.o
++obj-$(CONFIG_MMC_DW)          += dw_mmc.o
++obj-$(CONFIG_MMC_DW_PLTFM)    += dw_mmc-pltfm.o
++obj-$(CONFIG_MMC_DW_EXYNOS)   += dw_mmc-exynos.o
++obj-$(CONFIG_MMC_DW_PCI)      += dw_mmc-pci.o
+ obj-$(CONFIG_MMC_SDHCI)               += sdhci.o
+ obj-$(CONFIG_MMC_SDHCI_PCI)   += sdhci-pci.o
+ obj-$(subst m,y,$(CONFIG_MMC_SDHCI_PCI))      += sdhci-pci-data.o
+@@ -39,10 +43,6 @@ obj-$(CONFIG_MMC_SDHI)              += sh_mobile_sdhi.o
+ obj-$(CONFIG_MMC_CB710)               += cb710-mmc.o
+ obj-$(CONFIG_MMC_VIA_SDMMC)   += via-sdmmc.o
+ obj-$(CONFIG_SDH_BFIN)                += bfin_sdh.o
+-obj-$(CONFIG_MMC_DW)          += dw_mmc.o
+-obj-$(CONFIG_MMC_DW_PLTFM)    += dw_mmc-pltfm.o
+-obj-$(CONFIG_MMC_DW_EXYNOS)   += dw_mmc-exynos.o
+-obj-$(CONFIG_MMC_DW_PCI)      += dw_mmc-pci.o
+ obj-$(CONFIG_MMC_SH_MMCIF)    += sh_mmcif.o
+ obj-$(CONFIG_MMC_JZ4740)      += jz4740_mmc.o
+ obj-$(CONFIG_MMC_VUB300)      += vub300.o
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0449-ARM-dts-exynos4412-m0-update-gpio-keys-configuration.patch b/patches.tizen/0449-ARM-dts-exynos4412-m0-update-gpio-keys-configuration.patch
new file mode 100644 (file)
index 0000000..8df689b
--- /dev/null
@@ -0,0 +1,71 @@
+From 109287e2dbfdd152bcda94dbde5c1972d3c6071c Mon Sep 17 00:00:00 2001
+From: Beomho Seo <beomho.seo@samsung.com>
+Date: Fri, 26 Jul 2013 17:01:52 +0900
+Subject: [PATCH 0449/1302] ARM: dts:exynos4412-m0: update gpio-keys
+ configuration
+
+       add gpio-keys configuration for support M0 board
+       supported gpio-keys are volume up, volume down, power and ok key
+
+Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-m0.dts | 42 +++++++++++++++++++++++++++++++++++++
+ 1 file changed, 42 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-m0.dts b/arch/arm/boot/dts/exynos4412-m0.dts
+index 8e75628..3a43790 100644
+--- a/arch/arm/boot/dts/exynos4412-m0.dts
++++ b/arch/arm/boot/dts/exynos4412-m0.dts
+@@ -29,6 +29,48 @@
+               };
+       };
++      gpio-keys@0 {
++              compatible = "gpio-keys";
++
++              key@114 {
++                      interrupt-parent = <&gpx3>;
++                      interrupts = <3 0>;
++                      gpios = <&gpx3 3 1>;
++                      linux,code = <114>;
++                      label = "volume down";
++                      debounce-interval = <10>;
++              };
++
++              key@115 {
++                      interrupt-parent = <&gpx2>;
++                      interrupts = <2 0>;
++                      gpios = <&gpx2 2 1>;
++                      linux,code = <115>;
++                      label = "volume up";
++                      debounce-interval = <10>;
++              };
++
++              key@116 {
++                      interrupt-parent = <&gpx2>;
++                      interrupts = <7 0>;
++                      gpios = <&gpx2 7 1>;
++                      linux,code = <116>;
++                      label = "power";
++                      debounce-interval = <10>;
++                      gpio-key,wakeup;
++              };
++
++              key@139 {
++                      interrupt-parent = <&gpx0>;
++                      interrupts = <1 0>;
++                      gpios = <&gpx0 1 1>;
++                      linux,code = <139>;
++                      label = "ok";
++                      debounce-interval = <10>;
++                      gpio-key,wakeup;
++              };
++      };
++
+       camera {
+               status = "okay";
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0450-f2fs-fix-inconsistency-of-block-count-during-recover.patch b/patches.tizen/0450-f2fs-fix-inconsistency-of-block-count-during-recover.patch
new file mode 100644 (file)
index 0000000..062d389
--- /dev/null
@@ -0,0 +1,62 @@
+From 219f5ba1323bd4507fb98f1a41b941777e3a17e3 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Tue, 14 May 2013 15:47:43 +0900
+Subject: [PATCH 0450/1302] f2fs: fix inconsistency of block count during
+ recovery
+
+Currently f2fs recovers the dentry of fsynced files.
+When power-off-recovery is conducted, this newly recovered inode should increase
+node block count as well as inode block count.
+
+This patch resolves this inconsistency that results in:
+
+1. create a file
+2. write data
+3. fsync
+4. reboot without sync
+5. mount and recover the file
+6. node block count is 1 and inode block count is 2
+ : fall into the inconsistent state
+7. unlink the file
+ : trigger the following BUG_ON
+
+------------[ cut here ]------------
+kernel BUG at /home/zeus/f2fs_test/src/fs/f2fs/f2fs.h:716!
+Call Trace:
+ [<ffffffffa0344100>] ? get_node_page+0x50/0x1a0 [f2fs]
+ [<ffffffffa0344bfc>] remove_inode_page+0x8c/0x100 [f2fs]
+ [<ffffffffa03380f0>] ? f2fs_evict_inode+0x180/0x2d0 [f2fs]
+ [<ffffffffa033812e>] f2fs_evict_inode+0x1be/0x2d0 [f2fs]
+ [<ffffffff811c7a67>] evict+0xa7/0x1a0
+ [<ffffffff811c82b5>] iput+0x105/0x190
+ [<ffffffff811c2b30>] d_kill+0xe0/0x120
+ [<ffffffff811c2c57>] dput+0xe7/0x1e0
+ [<ffffffff811acc3d>] __fput+0x19d/0x2d0
+ [<ffffffff811acd7e>] ____fput+0xe/0x10
+ [<ffffffff81070645>] task_work_run+0xb5/0xe0
+ [<ffffffff81002941>] do_notify_resume+0x71/0xb0
+ [<ffffffff8175f14a>] int_signal+0x12/0x17
+
+Reported-and-Tested-by: Chris Fries <C.Fries@motorola.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/node.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
+index 3df43b4..9641534 100644
+--- a/fs/f2fs/node.c
++++ b/fs/f2fs/node.c
+@@ -1492,6 +1492,8 @@ int recover_inode_page(struct f2fs_sb_info *sbi, struct page *page)
+       new_ni = old_ni;
+       new_ni.ino = ino;
++      if (!inc_valid_node_count(sbi, NULL, 1))
++              WARN_ON(1);
+       set_node_addr(sbi, &new_ni, NEW_ADDR);
+       inc_valid_inode_count(sbi);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0451-f2fs-fix-the-inconsistent-state-of-data-pages.patch b/patches.tizen/0451-f2fs-fix-the-inconsistent-state-of-data-pages.patch
new file mode 100644 (file)
index 0000000..f267295
--- /dev/null
@@ -0,0 +1,67 @@
+From 7cc0d9601bcc503e981bb2541ecba6ac6163b0fa Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Mon, 13 May 2013 08:38:35 +0900
+Subject: [PATCH 0451/1302] f2fs: fix the inconsistent state of data pages
+
+In get_lock_data_page, if there is a data race between get_dnode_of_data for
+node and grab_cache_page for data, f2fs is able to face with the following
+BUG_ON(dn.data_blkaddr == NEW_ADDR).
+
+kernel BUG at /home/zeus/f2fs_test/src/fs/f2fs/data.c:251!
+ [<ffffffffa044966c>] get_lock_data_page+0x1ec/0x210 [f2fs]
+Call Trace:
+ [<ffffffffa043b089>] f2fs_readdir+0x89/0x210 [f2fs]
+ [<ffffffff811a0920>] ? fillonedir+0x100/0x100
+ [<ffffffff811a0920>] ? fillonedir+0x100/0x100
+ [<ffffffff811a07f8>] vfs_readdir+0xb8/0xe0
+ [<ffffffff811a0b4f>] sys_getdents+0x8f/0x110
+ [<ffffffff816d7999>] system_call_fastpath+0x16/0x1b
+
+This bug is able to be occurred when the block address of the data block is
+changed after f2fs_put_dnode().
+In order to avoid that, this patch fixes the lock order of node and data
+blocks in which the node block lock is covered by the data block lock.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/data.c | 17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 91ff93b..05fb5c6 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -233,18 +233,23 @@ struct page *get_lock_data_page(struct inode *inode, pgoff_t index)
+       struct page *page;
+       int err;
++repeat:
++      page = grab_cache_page(mapping, index);
++      if (!page)
++              return ERR_PTR(-ENOMEM);
++
+       set_new_dnode(&dn, inode, NULL, NULL, 0);
+       err = get_dnode_of_data(&dn, index, LOOKUP_NODE);
+-      if (err)
++      if (err) {
++              f2fs_put_page(page, 1);
+               return ERR_PTR(err);
++      }
+       f2fs_put_dnode(&dn);
+-      if (dn.data_blkaddr == NULL_ADDR)
++      if (dn.data_blkaddr == NULL_ADDR) {
++              f2fs_put_page(page, 1);
+               return ERR_PTR(-ENOENT);
+-repeat:
+-      page = grab_cache_page(mapping, index);
+-      if (!page)
+-              return ERR_PTR(-ENOMEM);
++      }
+       if (PageUptodate(page))
+               return page;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0452-f2fs-remove-redundant-assignment.patch b/patches.tizen/0452-f2fs-remove-redundant-assignment.patch
new file mode 100644 (file)
index 0000000..82d3cc7
--- /dev/null
@@ -0,0 +1,41 @@
+From 45dd13e314e3af709aeeb3594083eecc07fb41a5 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Wed, 15 May 2013 10:49:13 +0900
+Subject: [PATCH 0452/1302] f2fs: remove redundant assignment
+
+We don't need to assign a value redundantly.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/recovery.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
+index 60c8a50..2941987 100644
+--- a/fs/f2fs/recovery.c
++++ b/fs/f2fs/recovery.c
+@@ -126,7 +126,6 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head)
+               entry = get_fsync_inode(head, ino_of_node(page));
+               if (entry) {
+-                      entry->blkaddr = blkaddr;
+                       if (IS_INODE(page) && is_dent_dnode(page))
+                               set_inode_flag(F2FS_I(entry->inode),
+                                                       FI_INC_LINK);
+@@ -150,10 +149,10 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head)
+                               kmem_cache_free(fsync_entry_slab, entry);
+                               goto unlock_out;
+                       }
+-
+                       list_add_tail(&entry->list, head);
+-                      entry->blkaddr = blkaddr;
+               }
++              entry->blkaddr = blkaddr;
++
+               if (IS_INODE(page)) {
+                       err = recover_inode(entry->inode, page);
+                       if (err == -ENOENT) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0453-f2fs-fix-por_doing-variable-coverage.patch b/patches.tizen/0453-f2fs-fix-por_doing-variable-coverage.patch
new file mode 100644 (file)
index 0000000..0e90b0c
--- /dev/null
@@ -0,0 +1,46 @@
+From ca4a851ade5923ec4234dcfeb20e0ed0ec4b63e4 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Wed, 15 May 2013 16:12:18 +0900
+Subject: [PATCH 0453/1302] f2fs: fix por_doing variable coverage
+
+The reason of using sbi->por_doing is to alleviate data writes during the
+recovery.
+The find_fsync_dnodes() produces some dirty dentry pages, so we should
+cover it too with sbi->por_doing.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/recovery.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
+index 2941987..4d89514 100644
+--- a/fs/f2fs/recovery.c
++++ b/fs/f2fs/recovery.c
+@@ -381,6 +381,7 @@ int recover_fsync_data(struct f2fs_sb_info *sbi)
+       INIT_LIST_HEAD(&inode_list);
+       /* step #1: find fsynced inode numbers */
++      sbi->por_doing = 1;
+       err = find_fsync_dnodes(sbi, &inode_list);
+       if (err)
+               goto out;
+@@ -389,13 +390,12 @@ int recover_fsync_data(struct f2fs_sb_info *sbi)
+               goto out;
+       /* step #2: recover data */
+-      sbi->por_doing = 1;
+       err = recover_data(sbi, &inode_list, CURSEG_WARM_NODE);
+-      sbi->por_doing = 0;
+       BUG_ON(!list_empty(&inode_list));
+ out:
+       destroy_fsync_dnodes(sbi, &inode_list);
+       kmem_cache_destroy(fsync_entry_slab);
++      sbi->por_doing = 0;
+       write_checkpoint(sbi, false);
+       return err;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0454-f2fs-fix-BUG_ON-during-f2fs_evict_inode-dir.patch b/patches.tizen/0454-f2fs-fix-BUG_ON-during-f2fs_evict_inode-dir.patch
new file mode 100644 (file)
index 0000000..24921f3
--- /dev/null
@@ -0,0 +1,138 @@
+From e5db02b4bb0fb7fa923c28afd7d5cdc6c80f9dca Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Wed, 15 May 2013 16:40:02 +0900
+Subject: [PATCH 0454/1302] f2fs: fix BUG_ON during f2fs_evict_inode(dir)
+
+During the dentry recovery routine, recover_inode() triggers __f2fs_add_link
+with its directory inode.
+
+In the following scenario, a bug is captured.
+ 1. dir = f2fs_iget(pino)
+ 2. __f2fs_add_link(dir, name)
+ 3. iput(dir)
+  -> f2fs_evict_inode() faces with BUG_ON(atomic_read(fi->dirty_dents))
+
+Kernel BUG at ffffffffa01c0676 [verbose debug info unavailable]
+[<ffffffffa01c0676>] f2fs_evict_inode+0x276/0x300 [f2fs]
+Call Trace:
+ [<ffffffff8118ea00>] evict+0xb0/0x1b0
+ [<ffffffff8118f1c5>] iput+0x105/0x190
+ [<ffffffffa01d2dac>] recover_fsync_data+0x3bc/0x1070 [f2fs]
+ [<ffffffff81692e8a>] ? io_schedule+0xaa/0xd0
+ [<ffffffff81690acb>] ? __wait_on_bit_lock+0x7b/0xc0
+ [<ffffffff8111a0e7>] ? __lock_page+0x67/0x70
+ [<ffffffff81165e21>] ? kmem_cache_alloc+0x31/0x140
+ [<ffffffff8118a502>] ? __d_instantiate+0x92/0xf0
+ [<ffffffff812a949b>] ? security_d_instantiate+0x1b/0x30
+ [<ffffffff8118a5b4>] ? d_instantiate+0x54/0x70
+
+This means that we should flush all the dentry pages between iget and iput().
+But, during the recovery routine, it is unallowed due to consistency, so we
+have to wait the whole recovery process.
+And then, write_checkpoint flushes all the dirty dentry blocks, and nicely we
+can put the stale dir inodes from the dirty_dir_inode_list.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/checkpoint.c | 23 +++++++++++++++++++++++
+ fs/f2fs/f2fs.h       |  2 ++
+ fs/f2fs/recovery.c   | 14 +++++++++-----
+ 3 files changed, 34 insertions(+), 5 deletions(-)
+
+diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
+index b1de01d..3d11449 100644
+--- a/fs/f2fs/checkpoint.c
++++ b/fs/f2fs/checkpoint.c
+@@ -514,6 +514,29 @@ void remove_dirty_dir_inode(struct inode *inode)
+       }
+ out:
+       spin_unlock(&sbi->dir_inode_lock);
++
++      /* Only from the recovery routine */
++      if (is_inode_flag_set(F2FS_I(inode), FI_DELAY_IPUT))
++              iput(inode);
++}
++
++struct inode *check_dirty_dir_inode(struct f2fs_sb_info *sbi, nid_t ino)
++{
++      struct list_head *head = &sbi->dir_inode_list;
++      struct list_head *this;
++      struct inode *inode = NULL;
++
++      spin_lock(&sbi->dir_inode_lock);
++      list_for_each(this, head) {
++              struct dir_inode_entry *entry;
++              entry = list_entry(this, struct dir_inode_entry, list);
++              if (entry->inode->i_ino == ino) {
++                      inode = entry->inode;
++                      break;
++              }
++      }
++      spin_unlock(&sbi->dir_inode_lock);
++      return inode;
+ }
+ void sync_dirty_dir_inodes(struct f2fs_sb_info *sbi)
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 20aab02..ef6cac8 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -846,6 +846,7 @@ enum {
+       FI_INC_LINK,            /* need to increment i_nlink */
+       FI_ACL_MODE,            /* indicate acl mode */
+       FI_NO_ALLOC,            /* should not allocate any blocks */
++      FI_DELAY_IPUT,          /* used for the recovery */
+ };
+ static inline void set_inode_flag(struct f2fs_inode_info *fi, int flag)
+@@ -1012,6 +1013,7 @@ int recover_orphan_inodes(struct f2fs_sb_info *);
+ int get_valid_checkpoint(struct f2fs_sb_info *);
+ void set_dirty_dir_page(struct inode *, struct page *);
+ void remove_dirty_dir_inode(struct inode *);
++struct inode *check_dirty_dir_inode(struct f2fs_sb_info *, nid_t);
+ void sync_dirty_dir_inodes(struct f2fs_sb_info *);
+ void write_checkpoint(struct f2fs_sb_info *, bool);
+ void init_orphan_info(struct f2fs_sb_info *);
+diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
+index 4d89514..23f5803 100644
+--- a/fs/f2fs/recovery.c
++++ b/fs/f2fs/recovery.c
+@@ -42,6 +42,7 @@ static int recover_dentry(struct page *ipage, struct inode *inode)
+ {
+       struct f2fs_node *raw_node = (struct f2fs_node *)kmap(ipage);
+       struct f2fs_inode *raw_inode = &(raw_node->i);
++      nid_t pino = le32_to_cpu(raw_inode->i_pino);
+       struct qstr name;
+       struct f2fs_dir_entry *de;
+       struct page *page;
+@@ -51,10 +52,14 @@ static int recover_dentry(struct page *ipage, struct inode *inode)
+       if (!is_dent_dnode(ipage))
+               goto out;
+-      dir = f2fs_iget(inode->i_sb, le32_to_cpu(raw_inode->i_pino));
+-      if (IS_ERR(dir)) {
+-              err = PTR_ERR(dir);
+-              goto out;
++      dir = check_dirty_dir_inode(F2FS_SB(inode->i_sb), pino);
++      if (!dir) {
++              dir = f2fs_iget(inode->i_sb, pino);
++              if (IS_ERR(dir)) {
++                      err = PTR_ERR(dir);
++                      goto out;
++              }
++              set_inode_flag(F2FS_I(dir), FI_DELAY_IPUT);
+       }
+       name.len = le32_to_cpu(raw_inode->i_namelen);
+@@ -67,7 +72,6 @@ static int recover_dentry(struct page *ipage, struct inode *inode)
+       } else {
+               err = __f2fs_add_link(dir, &name, inode);
+       }
+-      iput(dir);
+ out:
+       kunmap(ipage);
+       return err;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0455-f2fs-remove-unnecessary-por_doing-check.patch b/patches.tizen/0455-f2fs-remove-unnecessary-por_doing-check.patch
new file mode 100644 (file)
index 0000000..8e12cc0
--- /dev/null
@@ -0,0 +1,30 @@
+From 6e7ce510acc1afe0fe7dc9f1aa17f90c432621a5 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Thu, 16 May 2013 08:57:43 +0900
+Subject: [PATCH 0455/1302] f2fs: remove unnecessary por_doing check
+
+This por_doing check is totally not related to the recovery process.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/namei.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
+index 47abc97..729b285 100644
+--- a/fs/f2fs/namei.c
++++ b/fs/f2fs/namei.c
+@@ -149,8 +149,7 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
+       alloc_nid_done(sbi, ino);
+-      if (!sbi->por_doing)
+-              d_instantiate(dentry, inode);
++      d_instantiate(dentry, inode);
+       unlock_new_inode(inode);
+       return 0;
+ out:
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0456-f2fs-skip-get_node_page-if-locked-node-page-is-passe.patch b/patches.tizen/0456-f2fs-skip-get_node_page-if-locked-node-page-is-passe.patch
new file mode 100644 (file)
index 0000000..8444d82
--- /dev/null
@@ -0,0 +1,40 @@
+From 914ff1f579d4c9a64d60a1661803bf6c25a4a7a4 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Mon, 20 May 2013 09:42:28 +0900
+Subject: [PATCH 0456/1302] f2fs: skip get_node_page if locked node page is
+ passed
+
+If get_dnode_of_data gets a locked node page, let's skip redundant
+get_node_page calls.
+This is for the futher enhancement.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/node.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
+index 9641534..f63f0a4 100644
+--- a/fs/f2fs/node.c
++++ b/fs/f2fs/node.c
+@@ -408,10 +408,13 @@ int get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode)
+       level = get_node_path(index, offset, noffset);
+       nids[0] = dn->inode->i_ino;
+-      npage[0] = get_node_page(sbi, nids[0]);
+-      if (IS_ERR(npage[0]))
+-              return PTR_ERR(npage[0]);
++      npage[0] = dn->inode_page;
++      if (!npage[0]) {
++              npage[0] = get_node_page(sbi, nids[0]);
++              if (IS_ERR(npage[0]))
++                      return PTR_ERR(npage[0]);
++      }
+       parent = npage[0];
+       if (level != 0)
+               nids[1] = get_nid(parent, offset[0], true);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0457-f2fs-change-get_new_data_page-to-pass-a-locked-node-.patch b/patches.tizen/0457-f2fs-change-get_new_data_page-to-pass-a-locked-node-.patch
new file mode 100644 (file)
index 0000000..7da0127
--- /dev/null
@@ -0,0 +1,107 @@
+From 58f7ddc948d21423312f6038263039165512c5a5 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Mon, 20 May 2013 09:55:50 +0900
+Subject: [PATCH 0457/1302] f2fs: change get_new_data_page to pass a locked
+ node page
+
+This patch is for passing a locked node page to get_dnode_of_data.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/data.c | 12 +++++++-----
+ fs/f2fs/dir.c  |  4 ++--
+ fs/f2fs/f2fs.h |  2 +-
+ fs/f2fs/file.c |  2 +-
+ 4 files changed, 11 insertions(+), 9 deletions(-)
+
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 05fb5c6..af74549 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -280,8 +280,8 @@ repeat:
+  * Also, caller should grab and release a mutex by calling mutex_lock_op() and
+  * mutex_unlock_op().
+  */
+-struct page *get_new_data_page(struct inode *inode, pgoff_t index,
+-                                              bool new_i_size)
++struct page *get_new_data_page(struct inode *inode,
++              struct page *npage, pgoff_t index, bool new_i_size)
+ {
+       struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
+       struct address_space *mapping = inode->i_mapping;
+@@ -289,18 +289,20 @@ struct page *get_new_data_page(struct inode *inode, pgoff_t index,
+       struct dnode_of_data dn;
+       int err;
+-      set_new_dnode(&dn, inode, NULL, NULL, 0);
++      set_new_dnode(&dn, inode, npage, npage, 0);
+       err = get_dnode_of_data(&dn, index, ALLOC_NODE);
+       if (err)
+               return ERR_PTR(err);
+       if (dn.data_blkaddr == NULL_ADDR) {
+               if (reserve_new_block(&dn)) {
+-                      f2fs_put_dnode(&dn);
++                      if (!npage)
++                              f2fs_put_dnode(&dn);
+                       return ERR_PTR(-ENOSPC);
+               }
+       }
+-      f2fs_put_dnode(&dn);
++      if (!npage)
++              f2fs_put_dnode(&dn);
+ repeat:
+       page = grab_cache_page(mapping, index);
+       if (!page)
+diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
+index 1ac6b93..7db6e58 100644
+--- a/fs/f2fs/dir.c
++++ b/fs/f2fs/dir.c
+@@ -287,7 +287,7 @@ static int make_empty_dir(struct inode *inode, struct inode *parent)
+       struct f2fs_dir_entry *de;
+       void *kaddr;
+-      dentry_page = get_new_data_page(inode, 0, true);
++      dentry_page = get_new_data_page(inode, NULL, 0, true);
+       if (IS_ERR(dentry_page))
+               return PTR_ERR(dentry_page);
+@@ -448,7 +448,7 @@ start:
+       bidx = dir_block_index(level, (le32_to_cpu(dentry_hash) % nbucket));
+       for (block = bidx; block <= (bidx + nblock - 1); block++) {
+-              dentry_page = get_new_data_page(dir, block, true);
++              dentry_page = get_new_data_page(dir, NULL, block, true);
+               if (IS_ERR(dentry_page))
+                       return PTR_ERR(dentry_page);
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index ef6cac8..cbae2b6 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -1027,7 +1027,7 @@ int reserve_new_block(struct dnode_of_data *);
+ void update_extent_cache(block_t, struct dnode_of_data *);
+ struct page *find_data_page(struct inode *, pgoff_t, bool);
+ struct page *get_lock_data_page(struct inode *, pgoff_t);
+-struct page *get_new_data_page(struct inode *, pgoff_t, bool);
++struct page *get_new_data_page(struct inode *, struct page *, pgoff_t, bool);
+ int f2fs_readpage(struct f2fs_sb_info *, struct page *, block_t, int);
+ int do_write_data_page(struct page *);
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 1cae864..b8e34db 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -387,7 +387,7 @@ static void fill_zero(struct inode *inode, pgoff_t index,
+       f2fs_balance_fs(sbi);
+       ilock = mutex_lock_op(sbi);
+-      page = get_new_data_page(inode, index, false);
++      page = get_new_data_page(inode, NULL, index, false);
+       mutex_unlock_op(sbi, ilock);
+       if (!IS_ERR(page)) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0458-f2fs-update-inode-page-after-creation.patch b/patches.tizen/0458-f2fs-update-inode-page-after-creation.patch
new file mode 100644 (file)
index 0000000..b8bc63e
--- /dev/null
@@ -0,0 +1,256 @@
+From 5eb8b0eeb5f7d51ae8dffdf84ad77fd68aa32c30 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Mon, 20 May 2013 10:10:29 +0900
+Subject: [PATCH 0458/1302] f2fs: update inode page after creation
+
+I found a bug when testing power-off-recovery as follows.
+
+[Bug Scenario]
+1. create a file
+2. fsync the file
+3. reboot w/o any sync
+4. try to recover the file
+ - found its fsync mark
+ - found its dentry mark
+   : try to recover its dentry
+    - get its file name
+    - get its parent inode number
+     : here we got zero value
+
+The reason why we get the wrong parent inode number is that we didn't
+synchronize the inode page with its newly created inode information perfectly.
+
+Especially, previous f2fs stores fi->i_pino and writes it to the cached
+node page in a wrong order, which incurs the zero-valued i_pino during the
+recovery.
+
+So, this patch modifies the creation flow to fix the synchronization order of
+inode page with its inode.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/data.c |  1 +
+ fs/f2fs/dir.c  | 85 +++++++++++++++++++++++++++++++---------------------------
+ fs/f2fs/f2fs.h |  3 +--
+ fs/f2fs/node.c | 12 +++------
+ 4 files changed, 51 insertions(+), 50 deletions(-)
+
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index af74549..c320f7f 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -279,6 +279,7 @@ repeat:
+  *
+  * Also, caller should grab and release a mutex by calling mutex_lock_op() and
+  * mutex_unlock_op().
++ * Note that, npage is set only by make_empty_dir.
+  */
+ struct page *get_new_data_page(struct inode *inode,
+               struct page *npage, pgoff_t index, bool new_i_size)
+diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
+index 7db6e58..fc1dacf 100644
+--- a/fs/f2fs/dir.c
++++ b/fs/f2fs/dir.c
+@@ -264,15 +264,10 @@ void f2fs_set_link(struct inode *dir, struct f2fs_dir_entry *de,
+       f2fs_put_page(page, 1);
+ }
+-void init_dent_inode(const struct qstr *name, struct page *ipage)
++static void init_dent_inode(const struct qstr *name, struct page *ipage)
+ {
+       struct f2fs_node *rn;
+-      if (IS_ERR(ipage))
+-              return;
+-
+-      wait_on_page_writeback(ipage);
+-
+       /* copy name info. to this inode page */
+       rn = (struct f2fs_node *)page_address(ipage);
+       rn->i.i_namelen = cpu_to_le32(name->len);
+@@ -280,14 +275,15 @@ void init_dent_inode(const struct qstr *name, struct page *ipage)
+       set_page_dirty(ipage);
+ }
+-static int make_empty_dir(struct inode *inode, struct inode *parent)
++static int make_empty_dir(struct inode *inode,
++              struct inode *parent, struct page *page)
+ {
+       struct page *dentry_page;
+       struct f2fs_dentry_block *dentry_blk;
+       struct f2fs_dir_entry *de;
+       void *kaddr;
+-      dentry_page = get_new_data_page(inode, NULL, 0, true);
++      dentry_page = get_new_data_page(inode, page, 0, true);
+       if (IS_ERR(dentry_page))
+               return PTR_ERR(dentry_page);
+@@ -317,42 +313,47 @@ static int make_empty_dir(struct inode *inode, struct inode *parent)
+       return 0;
+ }
+-static int init_inode_metadata(struct inode *inode,
++static struct page *init_inode_metadata(struct inode *inode,
+               struct inode *dir, const struct qstr *name)
+ {
++      struct page *page;
++      int err;
++
+       if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE)) {
+-              int err;
+-              err = new_inode_page(inode, name);
+-              if (err)
+-                      return err;
++              page = new_inode_page(inode, name);
++              if (IS_ERR(page))
++                      return page;
+               if (S_ISDIR(inode->i_mode)) {
+-                      err = make_empty_dir(inode, dir);
+-                      if (err) {
+-                              remove_inode_page(inode);
+-                              return err;
+-                      }
++                      err = make_empty_dir(inode, dir, page);
++                      if (err)
++                              goto error;
+               }
+               err = f2fs_init_acl(inode, dir);
+-              if (err) {
+-                      remove_inode_page(inode);
+-                      return err;
+-              }
++              if (err)
++                      goto error;
++
++              wait_on_page_writeback(page);
+       } else {
+-              struct page *ipage;
+-              ipage = get_node_page(F2FS_SB(dir->i_sb), inode->i_ino);
+-              if (IS_ERR(ipage))
+-                      return PTR_ERR(ipage);
+-              set_cold_node(inode, ipage);
+-              init_dent_inode(name, ipage);
+-              f2fs_put_page(ipage, 1);
++              page = get_node_page(F2FS_SB(dir->i_sb), inode->i_ino);
++              if (IS_ERR(page))
++                      return page;
++
++              wait_on_page_writeback(page);
++              set_cold_node(inode, page);
+       }
+-      if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK)) {
++
++      init_dent_inode(name, page);
++
++      if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK))
+               inc_nlink(inode);
+-              update_inode_page(inode);
+-      }
+-      return 0;
++      return page;
++
++error:
++      f2fs_put_page(page, 1);
++      remove_inode_page(inode);
++      return ERR_PTR(err);
+ }
+ static void update_parent_metadata(struct inode *dir, struct inode *inode,
+@@ -423,6 +424,7 @@ int __f2fs_add_link(struct inode *dir, const struct qstr *name, struct inode *in
+       struct page *dentry_page = NULL;
+       struct f2fs_dentry_block *dentry_blk = NULL;
+       int slots = GET_DENTRY_SLOTS(namelen);
++      struct page *page;
+       int err = 0;
+       int i;
+@@ -465,12 +467,13 @@ start:
+       ++level;
+       goto start;
+ add_dentry:
+-      err = init_inode_metadata(inode, dir, name);
+-      if (err)
+-              goto fail;
+-
+       wait_on_page_writeback(dentry_page);
++      page = init_inode_metadata(inode, dir, name);
++      if (IS_ERR(page)) {
++              err = PTR_ERR(page);
++              goto fail;
++      }
+       de = &dentry_blk->dentry[bit_pos];
+       de->hash_code = dentry_hash;
+       de->name_len = cpu_to_le16(namelen);
+@@ -481,10 +484,12 @@ add_dentry:
+               test_and_set_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap);
+       set_page_dirty(dentry_page);
+-      update_parent_metadata(dir, inode, current_depth);
+-
+-      /* update parent inode number before releasing dentry page */
++      /* we don't need to mark_inode_dirty now */
+       F2FS_I(inode)->i_pino = dir->i_ino;
++      update_inode(inode, page);
++      f2fs_put_page(page, 1);
++
++      update_parent_metadata(dir, inode, current_depth);
+ fail:
+       kunmap(dentry_page);
+       f2fs_put_page(dentry_page, 1);
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index cbae2b6..9360a03 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -914,7 +914,6 @@ struct f2fs_dir_entry *f2fs_parent_dir(struct inode *, struct page **);
+ ino_t f2fs_inode_by_name(struct inode *, struct qstr *);
+ void f2fs_set_link(struct inode *, struct f2fs_dir_entry *,
+                               struct page *, struct inode *);
+-void init_dent_inode(const struct qstr *, struct page *);
+ int __f2fs_add_link(struct inode *, const struct qstr *, struct inode *);
+ void f2fs_delete_entry(struct f2fs_dir_entry *, struct page *, struct inode *);
+ int f2fs_make_empty(struct inode *, struct inode *);
+@@ -949,7 +948,7 @@ void get_node_info(struct f2fs_sb_info *, nid_t, struct node_info *);
+ int get_dnode_of_data(struct dnode_of_data *, pgoff_t, int);
+ int truncate_inode_blocks(struct inode *, pgoff_t);
+ int remove_inode_page(struct inode *);
+-int new_inode_page(struct inode *, const struct qstr *);
++struct page *new_inode_page(struct inode *, const struct qstr *);
+ struct page *new_node_page(struct dnode_of_data *, unsigned int);
+ void ra_node_page(struct f2fs_sb_info *, nid_t);
+ struct page *get_node_page(struct f2fs_sb_info *, pgoff_t);
+diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
+index f63f0a4..b41482d 100644
+--- a/fs/f2fs/node.c
++++ b/fs/f2fs/node.c
+@@ -806,19 +806,15 @@ int remove_inode_page(struct inode *inode)
+       return 0;
+ }
+-int new_inode_page(struct inode *inode, const struct qstr *name)
++struct page *new_inode_page(struct inode *inode, const struct qstr *name)
+ {
+-      struct page *page;
+       struct dnode_of_data dn;
+       /* allocate inode page for new inode */
+       set_new_dnode(&dn, inode, NULL, NULL, inode->i_ino);
+-      page = new_node_page(&dn, 0);
+-      init_dent_inode(name, page);
+-      if (IS_ERR(page))
+-              return PTR_ERR(page);
+-      f2fs_put_page(page, 1);
+-      return 0;
++
++      /* caller should f2fs_put_page(page, 1); */
++      return new_node_page(&dn, 0);
+ }
+ struct page *new_node_page(struct dnode_of_data *dn, unsigned int ofs)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0459-f2fs-add-debug-msgs-in-the-recovery-routine.patch b/patches.tizen/0459-f2fs-add-debug-msgs-in-the-recovery-routine.patch
new file mode 100644 (file)
index 0000000..2f339d2
--- /dev/null
@@ -0,0 +1,161 @@
+From 3d475c568c54b6cf9cb6f436b7c7633b9e8a16ea Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Thu, 16 May 2013 15:04:49 +0900
+Subject: [PATCH 0459/1302] f2fs: add debug msgs in the recovery routine
+
+This patch adds some trivial debugging messages in the recovery process.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/node.c     |  1 -
+ fs/f2fs/recovery.c | 44 +++++++++++++++++++++++++-------------------
+ 2 files changed, 25 insertions(+), 20 deletions(-)
+
+diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
+index b41482d..5a59780 100644
+--- a/fs/f2fs/node.c
++++ b/fs/f2fs/node.c
+@@ -1495,7 +1495,6 @@ int recover_inode_page(struct f2fs_sb_info *sbi, struct page *page)
+               WARN_ON(1);
+       set_node_addr(sbi, &new_ni, NEW_ADDR);
+       inc_valid_inode_count(sbi);
+-
+       f2fs_put_page(ipage, 1);
+       return 0;
+ }
+diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
+index 23f5803..6ad4e53 100644
+--- a/fs/f2fs/recovery.c
++++ b/fs/f2fs/recovery.c
+@@ -49,9 +49,6 @@ static int recover_dentry(struct page *ipage, struct inode *inode)
+       struct inode *dir;
+       int err = 0;
+-      if (!is_dent_dnode(ipage))
+-              goto out;
+-
+       dir = check_dirty_dir_inode(F2FS_SB(inode->i_sb), pino);
+       if (!dir) {
+               dir = f2fs_iget(inode->i_sb, pino);
+@@ -73,6 +70,9 @@ static int recover_dentry(struct page *ipage, struct inode *inode)
+               err = __f2fs_add_link(dir, &name, inode);
+       }
+ out:
++      f2fs_msg(inode->i_sb, KERN_NOTICE, "recover_inode and its dentry: "
++                      "ino = %x, name = %s, dir = %lx, err = %d",
++                      ino_of_node(ipage), raw_inode->i_name, dir->i_ino, err);
+       kunmap(ipage);
+       return err;
+ }
+@@ -83,6 +83,9 @@ static int recover_inode(struct inode *inode, struct page *node_page)
+       struct f2fs_node *raw_node = (struct f2fs_node *)kaddr;
+       struct f2fs_inode *raw_inode = &(raw_node->i);
++      if (!IS_INODE(node_page))
++              return 0;
++
+       inode->i_mode = le16_to_cpu(raw_inode->i_mode);
+       i_size_write(inode, le64_to_cpu(raw_inode->i_size));
+       inode->i_atime.tv_sec = le64_to_cpu(raw_inode->i_mtime);
+@@ -92,7 +95,12 @@ static int recover_inode(struct inode *inode, struct page *node_page)
+       inode->i_ctime.tv_nsec = le32_to_cpu(raw_inode->i_ctime_nsec);
+       inode->i_mtime.tv_nsec = le32_to_cpu(raw_inode->i_mtime_nsec);
+-      return recover_dentry(node_page, inode);
++      if (is_dent_dnode(node_page))
++              return recover_dentry(node_page, inode);
++
++      f2fs_msg(inode->i_sb, KERN_NOTICE, "recover_inode: ino = %x, name = %s",
++                      ino_of_node(node_page), raw_inode->i_name);
++      return 0;
+ }
+ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head)
+@@ -123,7 +131,7 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head)
+               lock_page(page);
+               if (cp_ver != cpver_of_node(page))
+-                      goto unlock_out;
++                      break;
+               if (!is_fsync_dnode(page))
+                       goto next;
+@@ -137,40 +145,33 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head)
+                       if (IS_INODE(page) && is_dent_dnode(page)) {
+                               err = recover_inode_page(sbi, page);
+                               if (err)
+-                                      goto unlock_out;
++                                      break;
+                       }
+                       /* add this fsync inode to the list */
+                       entry = kmem_cache_alloc(fsync_entry_slab, GFP_NOFS);
+                       if (!entry) {
+                               err = -ENOMEM;
+-                              goto unlock_out;
++                              break;
+                       }
+                       entry->inode = f2fs_iget(sbi->sb, ino_of_node(page));
+                       if (IS_ERR(entry->inode)) {
+                               err = PTR_ERR(entry->inode);
+                               kmem_cache_free(fsync_entry_slab, entry);
+-                              goto unlock_out;
++                              break;
+                       }
+                       list_add_tail(&entry->list, head);
+               }
+               entry->blkaddr = blkaddr;
+-              if (IS_INODE(page)) {
+-                      err = recover_inode(entry->inode, page);
+-                      if (err == -ENOENT) {
+-                              goto next;
+-                      } else if (err) {
+-                              err = -EINVAL;
+-                              goto unlock_out;
+-                      }
+-              }
++              err = recover_inode(entry->inode, page);
++              if (err && err != -ENOENT)
++                      break;
+ next:
+               /* check next segment */
+               blkaddr = next_blkaddr_of_node(page);
+       }
+-unlock_out:
+       unlock_page(page);
+ out:
+       __free_pages(page, 0);
+@@ -248,7 +249,7 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
+       struct dnode_of_data dn;
+       struct f2fs_summary sum;
+       struct node_info ni;
+-      int err = 0;
++      int err = 0, recovered = 0;
+       int ilock;
+       start = start_bidx_of_node(ofs_of_node(page));
+@@ -293,6 +294,7 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
+                       /* write dummy data page */
+                       recover_data_page(sbi, NULL, &sum, src, dest);
+                       update_extent_cache(dest, &dn);
++                      recovered++;
+               }
+               dn.ofs_in_node++;
+       }
+@@ -310,6 +312,10 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
+       recover_node_page(sbi, dn.node_page, &sum, &ni, blkaddr);
+       f2fs_put_dnode(&dn);
+       mutex_unlock_op(sbi, ilock);
++
++      f2fs_msg(sbi->sb, KERN_NOTICE, "recover_data: ino = %lx, "
++                      "recovered_data = %d blocks",
++                      inode->i_ino, recovered);
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0460-f2fs-lockdep-annotate-mutex_lock_all.patch b/patches.tizen/0460-f2fs-lockdep-annotate-mutex_lock_all.patch
new file mode 100644 (file)
index 0000000..934387d
--- /dev/null
@@ -0,0 +1,48 @@
+From ef0aa12a74bc491e448b527aba6748a48b58003c Mon Sep 17 00:00:00 2001
+From: Peter Zijlstra <peterz@infradead.org>
+Date: Thu, 16 May 2013 20:03:12 +0200
+Subject: [PATCH 0460/1302] f2fs, lockdep: annotate mutex_lock_all()
+
+Majianpeng reported a lockdep splat for f2fs. It turns out mutex_lock_all()
+acquires an array of locks (in global/local lock style).
+
+Any such operation is always serialized using cp_mutex, therefore there is no
+fs_lock[] lock-order issue; tell lockdep about this using the
+mutex_lock_nest_lock() primitive.
+
+Reported-by: majianpeng <majianpeng@gmail.com>
+Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/f2fs.h | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 9360a03..9182b27 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -495,9 +495,17 @@ static inline void clear_ckpt_flags(struct f2fs_checkpoint *cp, unsigned int f)
+ static inline void mutex_lock_all(struct f2fs_sb_info *sbi)
+ {
+-      int i = 0;
+-      for (; i < NR_GLOBAL_LOCKS; i++)
+-              mutex_lock(&sbi->fs_lock[i]);
++      int i;
++
++      for (i = 0; i < NR_GLOBAL_LOCKS; i++) {
++              /*
++               * This is the only time we take multiple fs_lock[]
++               * instances; the order is immaterial since we
++               * always hold cp_mutex, which serializes multiple
++               * such operations.
++               */
++              mutex_lock_nest_lock(&sbi->fs_lock[i], &sbi->cp_mutex);
++      }
+ }
+ static inline void mutex_unlock_all(struct f2fs_sb_info *sbi)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0461-f2fs-remove-unecessary-variable-and-code.patch b/patches.tizen/0461-f2fs-remove-unecessary-variable-and-code.patch
new file mode 100644 (file)
index 0000000..f863549
--- /dev/null
@@ -0,0 +1,85 @@
+From a276ebaa824f79ae7a766afc47d3b298783d5f5c Mon Sep 17 00:00:00 2001
+From: Haicheng Li <haicheng.li@linux.intel.com>
+Date: Tue, 14 May 2013 18:20:28 +0800
+Subject: [PATCH 0461/1302] f2fs: remove unecessary variable and code
+
+Code cleanup without behavior changed.
+
+Signed-off-by: Haicheng Li <haicheng.li@linux.intel.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/segment.c | 18 ++++++++----------
+ 1 file changed, 8 insertions(+), 10 deletions(-)
+
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index d8e84e4..3a0d027 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -126,17 +126,16 @@ void locate_dirty_segment(struct f2fs_sb_info *sbi, unsigned int segno)
+ static void set_prefree_as_free_segments(struct f2fs_sb_info *sbi)
+ {
+       struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
+-      unsigned int segno, offset = 0;
++      unsigned int segno = -1;
+       unsigned int total_segs = TOTAL_SEGS(sbi);
+       mutex_lock(&dirty_i->seglist_lock);
+       while (1) {
+               segno = find_next_bit(dirty_i->dirty_segmap[PRE], total_segs,
+-                              offset);
++                              segno + 1);
+               if (segno >= total_segs)
+                       break;
+               __set_test_and_free(sbi, segno);
+-              offset = segno + 1;
+       }
+       mutex_unlock(&dirty_i->seglist_lock);
+ }
+@@ -144,17 +143,16 @@ static void set_prefree_as_free_segments(struct f2fs_sb_info *sbi)
+ void clear_prefree_segments(struct f2fs_sb_info *sbi)
+ {
+       struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
+-      unsigned int segno, offset = 0;
++      unsigned int segno = -1;
+       unsigned int total_segs = TOTAL_SEGS(sbi);
+       mutex_lock(&dirty_i->seglist_lock);
+       while (1) {
+               segno = find_next_bit(dirty_i->dirty_segmap[PRE], total_segs,
+-                              offset);
++                              segno + 1);
+               if (segno >= total_segs)
+                       break;
+-              offset = segno + 1;
+               if (test_and_clear_bit(segno, dirty_i->dirty_segmap[PRE]))
+                       dirty_i->nr_dirty[PRE]--;
+@@ -364,11 +362,11 @@ next:
+ static int is_next_segment_free(struct f2fs_sb_info *sbi, int type)
+ {
+       struct curseg_info *curseg = CURSEG_I(sbi, type);
+-      unsigned int segno = curseg->segno;
++      unsigned int segno = curseg->segno + 1;
+       struct free_segmap_info *free_i = FREE_I(sbi);
+-      if (segno + 1 < TOTAL_SEGS(sbi) && (segno + 1) % sbi->segs_per_sec)
+-              return !test_bit(segno + 1, free_i->free_segmap);
++      if (segno < TOTAL_SEGS(sbi) && segno % sbi->segs_per_sec)
++              return !test_bit(segno, free_i->free_segmap);
+       return 0;
+ }
+@@ -495,7 +493,7 @@ static void new_curseg(struct f2fs_sb_info *sbi, int type, bool new_sec)
+       int dir = ALLOC_LEFT;
+       write_sum_page(sbi, curseg->sum_blk,
+-                              GET_SUM_BLOCK(sbi, curseg->segno));
++                              GET_SUM_BLOCK(sbi, segno));
+       if (type == CURSEG_WARM_DATA || type == CURSEG_COLD_DATA)
+               dir = ALLOC_RIGHT;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0462-f2fs-use-list_for_each_entry-rather-than-list_for_ea.patch b/patches.tizen/0462-f2fs-use-list_for_each_entry-rather-than-list_for_ea.patch
new file mode 100644 (file)
index 0000000..a649d0a
--- /dev/null
@@ -0,0 +1,40 @@
+From ddec1a2d04337ee6a49c88d08ee925e62e33e7d0 Mon Sep 17 00:00:00 2001
+From: majianpeng <majianpeng@gmail.com>
+Date: Tue, 14 May 2013 20:06:46 +0800
+Subject: [PATCH 0462/1302] f2fs: use list_for_each_entry rather than
+ list_for_each_entry_safe
+
+We can do this, since now we use a global mutex, f2fs_stat_mutex to protect its
+list operations.
+
+Signed-off-by: Jianpeng Ma <majianpeng@gmail.com>
+[Jaegeuk Kim: add description]
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/debug.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
+index 8d99437..0d6c6aa 100644
+--- a/fs/f2fs/debug.c
++++ b/fs/f2fs/debug.c
+@@ -175,12 +175,12 @@ get_cache:
+ static int stat_show(struct seq_file *s, void *v)
+ {
+-      struct f2fs_stat_info *si, *next;
++      struct f2fs_stat_info *si;
+       int i = 0;
+       int j;
+       mutex_lock(&f2fs_stat_mutex);
+-      list_for_each_entry_safe(si, next, &f2fs_stat_list, stat_list) {
++      list_for_each_entry(si, &f2fs_stat_list, stat_list) {
+               char devname[BDEVNAME_SIZE];
+               update_general_status(si->sbi);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0463-f2fs-reorganize-f2fs_vm_page_mkwrite.patch b/patches.tizen/0463-f2fs-reorganize-f2fs_vm_page_mkwrite.patch
new file mode 100644 (file)
index 0000000..d1603a1
--- /dev/null
@@ -0,0 +1,61 @@
+From 9740939def029d768f496a6ee671895461005316 Mon Sep 17 00:00:00 2001
+From: Namjae Jeon <namjae.jeon@samsung.com>
+Date: Sun, 28 Apr 2013 09:04:18 +0900
+Subject: [PATCH 0463/1302] f2fs: reorganize f2fs_vm_page_mkwrite
+
+Few things can be changed in the default mkwrite function
+1) Make file_update_time at the start before acquiring any lock
+2) the condition page_offset(page) >= i_size_read(inode) should be
+ changed to page_offset(page) > i_size_read
+3) Move wait_on_page_writeback.
+
+Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
+Signed-off-by: Amit Sahrawat <a.sahrawat@samsung.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/file.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index b8e34db..9937ba1 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -63,9 +63,10 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,
+       f2fs_put_dnode(&dn);
+       mutex_unlock_op(sbi, ilock);
++      file_update_time(vma->vm_file);
+       lock_page(page);
+       if (page->mapping != inode->i_mapping ||
+-                      page_offset(page) >= i_size_read(inode) ||
++                      page_offset(page) > i_size_read(inode) ||
+                       !PageUptodate(page)) {
+               unlock_page(page);
+               err = -EFAULT;
+@@ -76,10 +77,7 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,
+        * check to see if the page is mapped already (no holes)
+        */
+       if (PageMappedToDisk(page))
+-              goto out;
+-
+-      /* fill the page */
+-      wait_on_page_writeback(page);
++              goto mapped;
+       /* page is wholly or partially inside EOF */
+       if (((page->index + 1) << PAGE_CACHE_SHIFT) > i_size_read(inode)) {
+@@ -90,7 +88,9 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,
+       set_page_dirty(page);
+       SetPageUptodate(page);
+-      file_update_time(vma->vm_file);
++mapped:
++      /* fill the page */
++      wait_on_page_writeback(page);
+ out:
+       sb_end_pagefault(inode->i_sb);
+       return block_page_mkwrite_return(err);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0464-f2fs-remove-unnecessary-kmap-kunmap-operations.patch b/patches.tizen/0464-f2fs-remove-unnecessary-kmap-kunmap-operations.patch
new file mode 100644 (file)
index 0000000..fc645f8
--- /dev/null
@@ -0,0 +1,53 @@
+From 4fafa5b703ad5a4c7fd2893c066e6397eebe7f37 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Mon, 20 May 2013 10:23:40 +0900
+Subject: [PATCH 0464/1302] f2fs: remove unnecessary kmap/kunmap operations
+
+The allocated page used by the recovery is not on HIGHMEM, so that we don't
+need to use kmap/kunmap.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/recovery.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
+index 6ad4e53..f91ff0f 100644
+--- a/fs/f2fs/recovery.c
++++ b/fs/f2fs/recovery.c
+@@ -40,11 +40,11 @@ static struct fsync_inode_entry *get_fsync_inode(struct list_head *head,
+ static int recover_dentry(struct page *ipage, struct inode *inode)
+ {
+-      struct f2fs_node *raw_node = (struct f2fs_node *)kmap(ipage);
++      void *kaddr = page_address(ipage);
++      struct f2fs_node *raw_node = (struct f2fs_node *)kaddr;
+       struct f2fs_inode *raw_inode = &(raw_node->i);
+       nid_t pino = le32_to_cpu(raw_inode->i_pino);
+       struct qstr name;
+-      struct f2fs_dir_entry *de;
+       struct page *page;
+       struct inode *dir;
+       int err = 0;
+@@ -62,8 +62,7 @@ static int recover_dentry(struct page *ipage, struct inode *inode)
+       name.len = le32_to_cpu(raw_inode->i_namelen);
+       name.name = raw_inode->i_name;
+-      de = f2fs_find_entry(dir, &name, &page);
+-      if (de) {
++      if (f2fs_find_entry(dir, &name, &page)) {
+               kunmap(page);
+               f2fs_put_page(page, 0);
+       } else {
+@@ -73,7 +72,6 @@ out:
+       f2fs_msg(inode->i_sb, KERN_NOTICE, "recover_inode and its dentry: "
+                       "ino = %x, name = %s, dir = %lx, err = %d",
+                       ino_of_node(ipage), raw_inode->i_name, dir->i_ino, err);
+-      kunmap(ipage);
+       return err;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0465-f2fs-fix-to-unlock-page-before-exit.patch b/patches.tizen/0465-f2fs-fix-to-unlock-page-before-exit.patch
new file mode 100644 (file)
index 0000000..39e6cea
--- /dev/null
@@ -0,0 +1,46 @@
+From 48ebb04bd0d4033662eb7295593bcfc2efd897c8 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Mon, 20 May 2013 10:26:09 +0900
+Subject: [PATCH 0465/1302] f2fs: fix to unlock page before exit
+
+If we got an error after lock_page, we should unlock it before exit.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/recovery.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
+index f91ff0f..3a4b51c 100644
+--- a/fs/f2fs/recovery.c
++++ b/fs/f2fs/recovery.c
+@@ -347,7 +347,7 @@ static int recover_data(struct f2fs_sb_info *sbi,
+               lock_page(page);
+               if (cp_ver != cpver_of_node(page))
+-                      goto unlock_out;
++                      break;
+               entry = get_fsync_inode(head, ino_of_node(page));
+               if (!entry)
+@@ -355,7 +355,7 @@ static int recover_data(struct f2fs_sb_info *sbi,
+               err = do_recover_data(sbi, entry->inode, page, blkaddr);
+               if (err)
+-                      goto out;
++                      break;
+               if (entry->blkaddr == blkaddr) {
+                       iput(entry->inode);
+@@ -366,7 +366,6 @@ next:
+               /* check next segment */
+               blkaddr = next_blkaddr_of_node(page);
+       }
+-unlock_out:
+       unlock_page(page);
+ out:
+       __free_pages(page, 0);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0466-f2fs-don-t-do-checkpoint-if-error-is-occurred.patch b/patches.tizen/0466-f2fs-don-t-do-checkpoint-if-error-is-occurred.patch
new file mode 100644 (file)
index 0000000..ebcbb5d
--- /dev/null
@@ -0,0 +1,31 @@
+From 1316dd44da075e49e4ce9580573a48e94ca96803 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Mon, 20 May 2013 14:48:49 +0900
+Subject: [PATCH 0466/1302] f2fs: don't do checkpoint if error is occurred
+
+If we met an error during the dentry recovery, we should not conduct checkpoint.
+Otherwise, some errorneous dentry blocks overwrites the existing blocks that
+contain the remaining recovery information.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/recovery.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
+index 3a4b51c..5148d90 100644
+--- a/fs/f2fs/recovery.c
++++ b/fs/f2fs/recovery.c
+@@ -403,6 +403,7 @@ out:
+       destroy_fsync_dnodes(sbi, &inode_list);
+       kmem_cache_destroy(fsync_entry_slab);
+       sbi->por_doing = 0;
+-      write_checkpoint(sbi, false);
++      if (!err)
++              write_checkpoint(sbi, false);
+       return err;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0467-f2fs-avoid-RECLAIM_FS-ON-W-deadlock.patch b/patches.tizen/0467-f2fs-avoid-RECLAIM_FS-ON-W-deadlock.patch
new file mode 100644 (file)
index 0000000..eecfa56
--- /dev/null
@@ -0,0 +1,78 @@
+From a52b0254a775a852a430b20af268df828b322a34 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Mon, 20 May 2013 16:15:22 +0900
+Subject: [PATCH 0467/1302] f2fs: avoid RECLAIM_FS-ON-W: deadlock
+
+This patch tries to avoid the following deadlock condition of which the reclaim
+path can trigger f2fs_balance_fs again.
+
+=================================
+[ INFO: inconsistent lock state ]
+---------------------------------
+inconsistent {RECLAIM_FS-ON-W} -> {IN-RECLAIM_FS-W} usage.
+kswapd0/41 [HC0[0]:SC0[0]:HE1:SE1] takes:
+ (&sbi->gc_mutex){+.+.?.}, at: f2fs_balance_fs+0xe6/0x100 [f2fs]
+{RECLAIM_FS-ON-W} state was registered at:
+  [<ffffffff810aa5a9>] mark_held_locks+0xb9/0x140
+  [<ffffffff810aae85>] lockdep_trace_alloc+0x85/0xf0
+  [<ffffffff8113ab2c>] __alloc_pages_nodemask+0x7c/0x9b0
+  [<ffffffff81175aa8>] alloc_pages_current+0xb8/0x180
+  [<ffffffff811319cf>] __page_cache_alloc+0xaf/0xd0
+  [<ffffffff8113225c>] find_or_create_page+0x4c/0xb0
+  [<ffffffffa021359e>] find_data_page+0x14e/0x210 [f2fs]
+  [<ffffffffa021161b>] f2fs_gc+0x9eb/0xd90 [f2fs]
+  [<ffffffffa0218fae>] f2fs_balance_fs+0xee/0x100 [f2fs]
+  [<ffffffffa020848c>] f2fs_setattr+0x6c/0x200 [f2fs]
+  [<ffffffff811ae51b>] notify_change+0x1db/0x3a0
+  [<ffffffff8118fbd0>] do_truncate+0x60/0xa0
+  [<ffffffff8118fd95>] vfs_truncate+0x185/0x1b0
+  [<ffffffff8118fe1c>] do_sys_truncate+0x5c/0xa0
+  [<ffffffff8118ffee>] SyS_truncate+0xe/0x10
+  [<ffffffff816e2b42>] system_call_fastpath+0x16/0x1b
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/data.c  | 4 ++--
+ fs/f2fs/inode.c | 3 +--
+ 2 files changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index c320f7f..1644fff 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -199,7 +199,7 @@ struct page *find_data_page(struct inode *inode, pgoff_t index, bool sync)
+       if (dn.data_blkaddr == NEW_ADDR)
+               return ERR_PTR(-EINVAL);
+-      page = grab_cache_page(mapping, index);
++      page = grab_cache_page_write_begin(mapping, index, AOP_FLAG_NOFS);
+       if (!page)
+               return ERR_PTR(-ENOMEM);
+@@ -234,7 +234,7 @@ struct page *get_lock_data_page(struct inode *inode, pgoff_t index)
+       int err;
+ repeat:
+-      page = grab_cache_page(mapping, index);
++      page = grab_cache_page_write_begin(mapping, index, AOP_FLAG_NOFS);
+       if (!page)
+               return ERR_PTR(-ENOMEM);
+diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
+index 91ac7f9..a18946e 100644
+--- a/fs/f2fs/inode.c
++++ b/fs/f2fs/inode.c
+@@ -130,8 +130,7 @@ make_now:
+               inode->i_op = &f2fs_dir_inode_operations;
+               inode->i_fop = &f2fs_dir_operations;
+               inode->i_mapping->a_ops = &f2fs_dblock_aops;
+-              mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER_MOVABLE |
+-                              __GFP_ZERO);
++              mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_ZERO);
+       } else if (S_ISLNK(inode->i_mode)) {
+               inode->i_op = &f2fs_symlink_inode_operations;
+               inode->i_mapping->a_ops = &f2fs_dblock_aops;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0468-f2fs-add-f2fs_readonly.patch b/patches.tizen/0468-f2fs-add-f2fs_readonly.patch
new file mode 100644 (file)
index 0000000..c5fa9de
--- /dev/null
@@ -0,0 +1,60 @@
+From 712db383c407195396a242082e76b92c046468b7 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Mon, 20 May 2013 20:28:47 +0900
+Subject: [PATCH 0468/1302] f2fs: add f2fs_readonly()
+
+Introduce a simple macro function for readability.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/f2fs.h  | 5 +++++
+ fs/f2fs/file.c  | 2 +-
+ fs/f2fs/super.c | 2 +-
+ 3 files changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 9182b27..6594ce1 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -887,6 +887,11 @@ static inline int cond_clear_inode_flag(struct f2fs_inode_info *fi, int flag)
+       return 0;
+ }
++static inline int f2fs_readonly(struct super_block *sb)
++{
++      return sb->s_flags & MS_RDONLY;
++}
++
+ /*
+  * file.c
+  */
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 9937ba1..316bcfe 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -114,7 +114,7 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
+               .for_reclaim = 0,
+       };
+-      if (inode->i_sb->s_flags & MS_RDONLY)
++      if (f2fs_readonly(inode->i_sb))
+               return 0;
+       trace_f2fs_sync_file_enter(inode);
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 8555f7d..3ac305d 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -170,7 +170,7 @@ static int f2fs_freeze(struct super_block *sb)
+ {
+       int err;
+-      if (sb->s_flags & MS_RDONLY)
++      if (f2fs_readonly(sb))
+               return 0;
+       err = f2fs_sync_fs(sb, 1);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0469-f2fs-fix-wrong-condition-check.patch b/patches.tizen/0469-f2fs-fix-wrong-condition-check.patch
new file mode 100644 (file)
index 0000000..e434851
--- /dev/null
@@ -0,0 +1,43 @@
+From b435b2df80435a620dcaaf627e0c4d082014caa2 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Tue, 21 May 2013 10:17:56 +0900
+Subject: [PATCH 0469/1302] f2fs: fix wrong condition check
+
+While an orphan inode has zero link_count, f2fs_gc is able to select the inode
+for foreground gc.
+
+- f2fs_gc
+ - do_garbage_collect
+   - gc_data_segment
+     : f2fs_iget is failed
+     : get_valid_blocks() != 0, so that retry
+--> here we got the infinite loop.
+
+This patch resolved this issue.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/inode.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
+index a18946e..b44a4c1 100644
+--- a/fs/f2fs/inode.c
++++ b/fs/f2fs/inode.c
+@@ -109,12 +109,6 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino)
+       ret = do_read_inode(inode);
+       if (ret)
+               goto bad_inode;
+-
+-      if (!sbi->por_doing && inode->i_nlink == 0) {
+-              ret = -ENOENT;
+-              goto bad_inode;
+-      }
+-
+ make_now:
+       if (ino == F2FS_NODE_INO(sbi)) {
+               inode->i_mapping->a_ops = &f2fs_node_aops;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0470-f2fs-reuse-the-locked-dnode-page-and-its-inode.patch b/patches.tizen/0470-f2fs-reuse-the-locked-dnode-page-and-its-inode.patch
new file mode 100644 (file)
index 0000000..fe5db76
--- /dev/null
@@ -0,0 +1,142 @@
+From aac25773cfc5684f932848bfe25d05de6e236e99 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Wed, 22 May 2013 08:02:02 +0900
+Subject: [PATCH 0470/1302] f2fs: reuse the locked dnode page and its inode
+
+This patch fixes the following deadlock bug during the recovery.
+
+INFO: task mount:1322 blocked for more than 120 seconds.
+"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+mount           D ffffffff81125870     0  1322   1266 0x00000000
+ ffff8801207e39d8 0000000000000046 ffff88012ab1dee0 0000000000000046
+ ffff8801207e3a08 ffff880115903f40 ffff8801207e3fd8 ffff8801207e3fd8
+ ffff8801207e3fd8 ffff880115903f40 ffff8801207e39d8 ffff88012fc94520
+Call Trace:
+[<ffffffff81125870>] ? __lock_page+0x70/0x70
+[<ffffffff816a92d9>] schedule+0x29/0x70
+[<ffffffff816a93af>] io_schedule+0x8f/0xd0
+[<ffffffff8112587e>] sleep_on_page+0xe/0x20
+[<ffffffff816a649a>] __wait_on_bit_lock+0x5a/0xc0
+[<ffffffff81125867>] __lock_page+0x67/0x70
+[<ffffffff8106c7b0>] ? autoremove_wake_function+0x40/0x40
+[<ffffffff81126857>] find_lock_page+0x67/0x80
+[<ffffffff8112698f>] find_or_create_page+0x3f/0xb0
+[<ffffffffa03901a8>] ? sync_inode_page+0xa8/0xd0 [f2fs]
+[<ffffffffa038fdf7>] get_node_page+0x67/0x180 [f2fs]
+[<ffffffffa039818b>] recover_fsync_data+0xacb/0xff0 [f2fs]
+[<ffffffff816aaa1e>] ? _raw_spin_unlock+0x3e/0x40
+[<ffffffffa0389634>] f2fs_fill_super+0x7d4/0x850 [f2fs]
+[<ffffffff81184cf9>] mount_bdev+0x1c9/0x210
+[<ffffffffa0388e60>] ? validate_superblock+0x180/0x180 [f2fs]
+[<ffffffffa0387635>] f2fs_mount+0x15/0x20 [f2fs]
+[<ffffffff81185a13>] mount_fs+0x43/0x1b0
+[<ffffffff81145ba0>] ? __alloc_percpu+0x10/0x20
+[<ffffffff811a0796>] vfs_kern_mount+0x76/0x120
+[<ffffffff811a2cb7>] do_mount+0x237/0xa10
+[<ffffffff81140b9b>] ? strndup_user+0x5b/0x80
+[<ffffffff811a3520>] SyS_mount+0x90/0xe0
+[<ffffffff816b3502>] system_call_fastpath+0x16/0x1b
+
+The bug is triggered when check_index_in_prev_nodes tries to get the direct
+node page by calling get_node_page.
+At this point, if the direct node page is already locked by get_dnode_of_data,
+its caller, we got a deadlock condition.
+
+This patch adds additional condition check for the reuse of locked direct node
+pages prior to the get_node_page call.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/f2fs.h     |  1 +
+ fs/f2fs/file.c     |  2 +-
+ fs/f2fs/recovery.c | 26 +++++++++++++++++++++-----
+ 3 files changed, 23 insertions(+), 6 deletions(-)
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 6594ce1..7b05029 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -900,6 +900,7 @@ void truncate_data_blocks(struct dnode_of_data *);
+ void f2fs_truncate(struct inode *);
+ int f2fs_setattr(struct dentry *, struct iattr *);
+ int truncate_hole(struct inode *, pgoff_t, pgoff_t);
++int truncate_data_blocks_range(struct dnode_of_data *, int);
+ long f2fs_ioctl(struct file *, unsigned int, unsigned long);
+ long f2fs_compat_ioctl(struct file *, unsigned int, unsigned long);
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 316bcfe..deefd25 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -168,7 +168,7 @@ static int f2fs_file_mmap(struct file *file, struct vm_area_struct *vma)
+       return 0;
+ }
+-static int truncate_data_blocks_range(struct dnode_of_data *dn, int count)
++int truncate_data_blocks_range(struct dnode_of_data *dn, int count)
+ {
+       int nr_free = 0, ofs = dn->ofs_in_node;
+       struct f2fs_sb_info *sbi = F2FS_SB(dn->inode->i_sb);
+diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
+index 5148d90..eceb665 100644
+--- a/fs/f2fs/recovery.c
++++ b/fs/f2fs/recovery.c
+@@ -189,14 +189,14 @@ static void destroy_fsync_dnodes(struct f2fs_sb_info *sbi,
+ }
+ static void check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
+-                                              block_t blkaddr)
++                      block_t blkaddr, struct dnode_of_data *dn)
+ {
+       struct seg_entry *sentry;
+       unsigned int segno = GET_SEGNO(sbi, blkaddr);
+       unsigned short blkoff = GET_SEGOFF_FROM_SEG0(sbi, blkaddr) &
+                                       (sbi->blocks_per_seg - 1);
+       struct f2fs_summary sum;
+-      nid_t ino;
++      nid_t ino, nid;
+       void *kaddr;
+       struct inode *inode;
+       struct page *node_page;
+@@ -224,10 +224,26 @@ static void check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
+               f2fs_put_page(sum_page, 1);
+       }
++      /* Use the locked dnode page and inode */
++      nid = le32_to_cpu(sum.nid);
++      if (dn->inode->i_ino == nid) {
++              struct dnode_of_data tdn = *dn;
++              tdn.nid = nid;
++              tdn.node_page = dn->inode_page;
++              tdn.ofs_in_node = sum.ofs_in_node;
++              truncate_data_blocks_range(&tdn, 1);
++              return;
++      } else if (dn->nid == nid) {
++              struct dnode_of_data tdn = *dn;
++              tdn.ofs_in_node = sum.ofs_in_node;
++              truncate_data_blocks_range(&tdn, 1);
++              return;
++      }
++
+       /* Get the node page */
+-      node_page = get_node_page(sbi, le32_to_cpu(sum.nid));
++      node_page = get_node_page(sbi, nid);
+       bidx = start_bidx_of_node(ofs_of_node(node_page)) +
+-                              le16_to_cpu(sum.ofs_in_node);
++                                      le16_to_cpu(sum.ofs_in_node);
+       ino = ino_of_node(node_page);
+       f2fs_put_page(node_page, 1);
+@@ -285,7 +301,7 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
+                       }
+                       /* Check the previous node page having this index */
+-                      check_index_in_prev_nodes(sbi, dest);
++                      check_index_in_prev_nodes(sbi, dest, &dn);
+                       set_summary(&sum, dn.nid, dn.ofs_in_node, ni.version);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0471-f2fs-fix-to-handle-do_recover_data-errors.patch b/patches.tizen/0471-f2fs-fix-to-handle-do_recover_data-errors.patch
new file mode 100644 (file)
index 0000000..12664e1
--- /dev/null
@@ -0,0 +1,102 @@
+From 74d9680934438f7f040e1bee413cfb064602fc9d Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Wed, 22 May 2013 08:20:01 +0900
+Subject: [PATCH 0471/1302] f2fs: fix to handle do_recover_data errors
+
+This patch adds error handling codes of check_index_in_prev_nodes and its
+caller, do_recover_data.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/recovery.c | 24 +++++++++++++++---------
+ 1 file changed, 15 insertions(+), 9 deletions(-)
+
+diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
+index eceb665..dcd8e86 100644
+--- a/fs/f2fs/recovery.c
++++ b/fs/f2fs/recovery.c
+@@ -188,7 +188,7 @@ static void destroy_fsync_dnodes(struct f2fs_sb_info *sbi,
+       }
+ }
+-static void check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
++static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
+                       block_t blkaddr, struct dnode_of_data *dn)
+ {
+       struct seg_entry *sentry;
+@@ -205,7 +205,7 @@ static void check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
+       sentry = get_seg_entry(sbi, segno);
+       if (!f2fs_test_bit(blkoff, sentry->cur_valid_map))
+-              return;
++              return 0;
+       /* Get the previous summary */
+       for (i = CURSEG_WARM_DATA; i <= CURSEG_COLD_DATA; i++) {
+@@ -232,16 +232,18 @@ static void check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
+               tdn.node_page = dn->inode_page;
+               tdn.ofs_in_node = sum.ofs_in_node;
+               truncate_data_blocks_range(&tdn, 1);
+-              return;
++              return 0;
+       } else if (dn->nid == nid) {
+               struct dnode_of_data tdn = *dn;
+               tdn.ofs_in_node = sum.ofs_in_node;
+               truncate_data_blocks_range(&tdn, 1);
+-              return;
++              return 0;
+       }
+       /* Get the node page */
+       node_page = get_node_page(sbi, nid);
++      if (IS_ERR(node_page))
++              return PTR_ERR(node_page);
+       bidx = start_bidx_of_node(ofs_of_node(node_page)) +
+                                       le16_to_cpu(sum.ofs_in_node);
+       ino = ino_of_node(node_page);
+@@ -250,10 +252,11 @@ static void check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
+       /* Deallocate previous index in the node page */
+       inode = f2fs_iget(sbi->sb, ino);
+       if (IS_ERR(inode))
+-              return;
++              return PTR_ERR(inode);
+       truncate_hole(inode, bidx, bidx + 1);
+       iput(inode);
++      return 0;
+ }
+ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
+@@ -301,7 +304,9 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
+                       }
+                       /* Check the previous node page having this index */
+-                      check_index_in_prev_nodes(sbi, dest, &dn);
++                      err = check_index_in_prev_nodes(sbi, dest, &dn);
++                      if (err)
++                              goto err;
+                       set_summary(&sum, dn.nid, dn.ofs_in_node, ni.version);
+@@ -324,13 +329,14 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
+       set_page_dirty(dn.node_page);
+       recover_node_page(sbi, dn.node_page, &sum, &ni, blkaddr);
++err:
+       f2fs_put_dnode(&dn);
+       mutex_unlock_op(sbi, ilock);
+       f2fs_msg(sbi->sb, KERN_NOTICE, "recover_data: ino = %lx, "
+-                      "recovered_data = %d blocks",
+-                      inode->i_ino, recovered);
+-      return 0;
++                      "recovered_data = %d blocks, err = %d",
++                      inode->i_ino, recovered, err);
++      return err;
+ }
+ static int recover_data(struct f2fs_sb_info *sbi,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0472-f2fs-should-not-make_bad_inode-on-f2fs_link-failure.patch b/patches.tizen/0472-f2fs-should-not-make_bad_inode-on-f2fs_link-failure.patch
new file mode 100644 (file)
index 0000000..d650f64
--- /dev/null
@@ -0,0 +1,30 @@
+From 58bc2774e7db195c31bad4b1607cbba0fb0969de Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Wed, 22 May 2013 12:03:47 +0900
+Subject: [PATCH 0472/1302] f2fs: should not make_bad_inode on f2fs_link
+ failure
+
+If -ENOSPC is met during f2fs_link, we should not make the inode as bad.
+The inode is still alive.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/namei.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
+index 729b285..71aa305 100644
+--- a/fs/f2fs/namei.c
++++ b/fs/f2fs/namei.c
+@@ -191,7 +191,6 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir,
+       return 0;
+ out:
+       clear_inode_flag(F2FS_I(inode), FI_INC_LINK);
+-      make_bad_inode(inode);
+       iput(inode);
+       return err;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0473-f2fs-use-ihold.patch b/patches.tizen/0473-f2fs-use-ihold.patch
new file mode 100644 (file)
index 0000000..096fe43
--- /dev/null
@@ -0,0 +1,37 @@
+From a161550af3f8226c6e52b3b37591d8f65840c2d8 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Wed, 22 May 2013 12:06:26 +0900
+Subject: [PATCH 0473/1302] f2fs: use ihold
+
+Use the following helper function committed by Al.
+
+commit 7de9c6ee3ecffd99e1628e81a5ea5468f7581a1f
+Author: Al Viro <viro@zeniv.linux.org.uk>
+Date:   Sat Oct 23 11:11:40 2010 -0400
+
+    new helper: ihold()
+
+...
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/namei.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
+index 71aa305..efe0a12 100644
+--- a/fs/f2fs/namei.c
++++ b/fs/f2fs/namei.c
+@@ -172,7 +172,7 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir,
+       f2fs_balance_fs(sbi);
+       inode->i_ctime = CURRENT_TIME;
+-      atomic_inc(&inode->i_count);
++      ihold(inode);
+       set_inode_flag(F2FS_I(inode), FI_INC_LINK);
+       ilock = mutex_lock_op(sbi);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0474-f2fs-dereferencing-an-ERR_PTR.patch b/patches.tizen/0474-f2fs-dereferencing-an-ERR_PTR.patch
new file mode 100644 (file)
index 0000000..892f714
--- /dev/null
@@ -0,0 +1,31 @@
+From a57261e93ebeee86c81cbbec095533aeb399317f Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Thu, 23 May 2013 13:02:13 +0300
+Subject: [PATCH 0474/1302] f2fs: dereferencing an ERR_PTR
+
+There is an error path where "dir" is an ERR_PTR.
+
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/recovery.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
+index dcd8e86..0dd2ce1 100644
+--- a/fs/f2fs/recovery.c
++++ b/fs/f2fs/recovery.c
+@@ -71,7 +71,8 @@ static int recover_dentry(struct page *ipage, struct inode *inode)
+ out:
+       f2fs_msg(inode->i_sb, KERN_NOTICE, "recover_inode and its dentry: "
+                       "ino = %x, name = %s, dir = %lx, err = %d",
+-                      ino_of_node(ipage), raw_inode->i_name, dir->i_ino, err);
++                      ino_of_node(ipage), raw_inode->i_name,
++                      IS_ERR(dir) ? 0 : dir->i_ino, err);
+       return err;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0475-f2fs-align-data-types-between-on-disk-and-in-memory-.patch b/patches.tizen/0475-f2fs-align-data-types-between-on-disk-and-in-memory-.patch
new file mode 100644 (file)
index 0000000..d937bf6
--- /dev/null
@@ -0,0 +1,53 @@
+From 7113d965a18984957c557bca43d264b6faafbe98 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Fri, 24 May 2013 12:41:04 +0900
+Subject: [PATCH 0475/1302] f2fs: align data types between on-disk and
+ in-memory block addresses
+
+The on-disk block address is defined as __le32, but in-memory block address,
+block_t, does as u64.
+
+Let's synchronize them to 32 bits.
+
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/f2fs.h          | 5 ++++-
+ include/linux/f2fs_fs.h | 4 ++--
+ 2 files changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 7b05029..92fd4e9 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -37,7 +37,10 @@
+               typecheck(unsigned long long, b) &&                     \
+               ((long long)((a) - (b)) > 0))
+-typedef u64 block_t;
++typedef u32 block_t;  /*
++                       * should not change u32, since it is the on-disk block
++                       * address format, __le32.
++                       */
+ typedef u32 nid_t;
+ struct f2fs_mount_info {
+diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
+index df6fab8..383d5e3 100644
+--- a/include/linux/f2fs_fs.h
++++ b/include/linux/f2fs_fs.h
+@@ -20,8 +20,8 @@
+ #define F2FS_BLKSIZE                  4096    /* support only 4KB block */
+ #define F2FS_MAX_EXTENSION            64      /* # of extension entries */
+-#define NULL_ADDR             0x0U
+-#define NEW_ADDR              -1U
++#define NULL_ADDR             ((block_t)0)    /* used as block_t addresses */
++#define NEW_ADDR              ((block_t)-1)   /* used as block_t addresses */
+ #define F2FS_ROOT_INO(sbi)    (sbi->root_ino_num)
+ #define F2FS_NODE_INO(sbi)    (sbi->node_ino_num)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0476-f2fs-push-some-variables-to-debug-part.patch b/patches.tizen/0476-f2fs-push-some-variables-to-debug-part.patch
new file mode 100644 (file)
index 0000000..f87f250
--- /dev/null
@@ -0,0 +1,151 @@
+From 8dca816663ff4c3021054ecc3838edb48bc6e814 Mon Sep 17 00:00:00 2001
+From: Namjae Jeon <namjae.jeon@samsung.com>
+Date: Thu, 23 May 2013 22:57:53 +0900
+Subject: [PATCH 0476/1302] f2fs: push some variables to debug part
+
+Some, counters are needed only for the statistical information
+while debugging.
+So, those can be controlled using CONFIG_F2FS_STAT_FS,
+pushing the usage for few variables under this flag.
+
+Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
+Signed-off-by: Amit Sahrawat <a.sahrawat@samsung.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/checkpoint.c | 4 ++++
+ fs/f2fs/data.c       | 6 ++++++
+ fs/f2fs/f2fs.h       | 6 ++++--
+ fs/f2fs/gc.c         | 2 ++
+ fs/f2fs/segment.c    | 5 +++++
+ 5 files changed, 21 insertions(+), 2 deletions(-)
+
+diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
+index 3d11449..01ddc91 100644
+--- a/fs/f2fs/checkpoint.c
++++ b/fs/f2fs/checkpoint.c
+@@ -478,7 +478,9 @@ retry:
+               }
+       }
+       list_add_tail(&new->list, head);
++#ifdef CONFIG_F2FS_STAT_FS
+       sbi->n_dirty_dirs++;
++#endif
+       BUG_ON(!S_ISDIR(inode->i_mode));
+ out:
+@@ -508,7 +510,9 @@ void remove_dirty_dir_inode(struct inode *inode)
+               if (entry->inode == inode) {
+                       list_del(&entry->list);
+                       kmem_cache_free(inode_entry_slab, entry);
++#ifdef CONFIG_F2FS_STAT_FS
+                       sbi->n_dirty_dirs--;
++#endif
+                       break;
+               }
+       }
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 1644fff..93917e3 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -68,7 +68,9 @@ static int check_extent_cache(struct inode *inode, pgoff_t pgofs,
+                                       struct buffer_head *bh_result)
+ {
+       struct f2fs_inode_info *fi = F2FS_I(inode);
++#ifdef CONFIG_F2FS_STAT_FS
+       struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
++#endif
+       pgoff_t start_fofs, end_fofs;
+       block_t start_blkaddr;
+@@ -78,7 +80,9 @@ static int check_extent_cache(struct inode *inode, pgoff_t pgofs,
+               return 0;
+       }
++#ifdef CONFIG_F2FS_STAT_FS
+       sbi->total_hit_ext++;
++#endif
+       start_fofs = fi->ext.fofs;
+       end_fofs = fi->ext.fofs + fi->ext.len - 1;
+       start_blkaddr = fi->ext.blk_addr;
+@@ -96,7 +100,9 @@ static int check_extent_cache(struct inode *inode, pgoff_t pgofs,
+               else
+                       bh_result->b_size = UINT_MAX;
++#ifdef CONFIG_F2FS_STAT_FS
+               sbi->read_hit_ext++;
++#endif
+               read_unlock(&fi->ext.ext_lock);
+               return 1;
+       }
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 92fd4e9..40b137a 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -372,7 +372,6 @@ struct f2fs_sb_info {
+       /* for directory inode management */
+       struct list_head dir_inode_list;        /* dir inode list */
+       spinlock_t dir_inode_lock;              /* for dir inode list lock */
+-      unsigned int n_dirty_dirs;              /* # of dir inodes */
+       /* basic file system units */
+       unsigned int log_sectors_per_block;     /* log2 sectors per block */
+@@ -409,12 +408,15 @@ struct f2fs_sb_info {
+        * for stat information.
+        * one is for the LFS mode, and the other is for the SSR mode.
+        */
++#ifdef CONFIG_F2FS_STAT_FS
+       struct f2fs_stat_info *stat_info;       /* FS status information */
+       unsigned int segment_count[2];          /* # of allocated segments */
+       unsigned int block_count[2];            /* # of allocated blocks */
+-      unsigned int last_victim[2];            /* last victim segment # */
+       int total_hit_ext, read_hit_ext;        /* extent cache hit ratio */
+       int bg_gc;                              /* background gc calls */
++      unsigned int n_dirty_dirs;              /* # of dir inodes */
++#endif
++      unsigned int last_victim[2];            /* last victim segment # */
+       spinlock_t stat_lock;                   /* lock for stat operations */
+ };
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index 1496159..25b083c 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -76,7 +76,9 @@ static int gc_thread_func(void *data)
+               else
+                       wait_ms = increase_sleep_time(wait_ms);
++#ifdef CONFIG_F2FS_STAT_FS
+               sbi->bg_gc++;
++#endif
+               /* if return value is not zero, no victim was selected */
+               if (f2fs_gc(sbi))
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index 3a0d027..be668ff 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -610,7 +610,10 @@ static void allocate_segment_by_default(struct f2fs_sb_info *sbi,
+       else
+               new_curseg(sbi, type, false);
+ out:
++#ifdef CONFIG_F2FS_STAT_FS
+       sbi->segment_count[curseg->alloc_type]++;
++#endif
++      return;
+ }
+ void allocate_new_segments(struct f2fs_sb_info *sbi)
+@@ -846,7 +849,9 @@ static void do_write_page(struct f2fs_sb_info *sbi, struct page *page,
+       mutex_lock(&sit_i->sentry_lock);
+       __refresh_next_blkoff(sbi, curseg);
++#ifdef CONFIG_F2FS_STAT_FS
+       sbi->block_count[curseg->alloc_type]++;
++#endif
+       /*
+        * SIT information should be updated before segment allocation,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0477-f2fs-remove-unneeded-initializations-in-f2fs_parent_.patch b/patches.tizen/0477-f2fs-remove-unneeded-initializations-in-f2fs_parent_.patch
new file mode 100644 (file)
index 0000000..b94f8de
--- /dev/null
@@ -0,0 +1,38 @@
+From f6933a41935444478bc470f0060276ca604da32a Mon Sep 17 00:00:00 2001
+From: Namjae Jeon <namjae.jeon@samsung.com>
+Date: Thu, 23 May 2013 22:58:07 +0900
+Subject: [PATCH 0477/1302] f2fs: remove unneeded initializations in
+ f2fs_parent_dir
+
+There is no need to initialize few pointers in f2fs_parent_dir
+as the values are not checked and instead directly initialized
+values are used.
+
+Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
+Signed-off-by: Amit Sahrawat <a.sahrawat@samsung.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/dir.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
+index fc1dacf..b278bfb 100644
+--- a/fs/f2fs/dir.c
++++ b/fs/f2fs/dir.c
+@@ -215,9 +215,9 @@ struct f2fs_dir_entry *f2fs_find_entry(struct inode *dir,
+ struct f2fs_dir_entry *f2fs_parent_dir(struct inode *dir, struct page **p)
+ {
+-      struct page *page = NULL;
+-      struct f2fs_dir_entry *de = NULL;
+-      struct f2fs_dentry_block *dentry_blk = NULL;
++      struct page *page;
++      struct f2fs_dir_entry *de;
++      struct f2fs_dentry_block *dentry_blk;
+       page = get_lock_data_page(dir, 0);
+       if (IS_ERR(page))
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0478-f2fs-optimize-several-routines-in-node.h.patch b/patches.tizen/0478-f2fs-optimize-several-routines-in-node.h.patch
new file mode 100644 (file)
index 0000000..c074a6f
--- /dev/null
@@ -0,0 +1,127 @@
+From 99cc237dcbfa6cca4f104ac2b6b254094ba0c8fe Mon Sep 17 00:00:00 2001
+From: Namjae Jeon <namjae.jeon@samsung.com>
+Date: Thu, 23 May 2013 22:58:40 +0900
+Subject: [PATCH 0478/1302] f2fs: optimize several routines in node.h
+
+There are various functions with common code which could be separated
+out to make common routines. So, made new routines and in order to
+retain the same call path and no major changes, written some macros
+to access those routines.
+
+Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
+Signed-off-by: Amit Sahrawat <a.sahrawat@samsung.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/node.h | 67 +++++++++++++++++-----------------------------------------
+ 1 file changed, 19 insertions(+), 48 deletions(-)
+
+diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h
+index 0a2d72f..a503661 100644
+--- a/fs/f2fs/node.h
++++ b/fs/f2fs/node.h
+@@ -275,25 +275,20 @@ static inline nid_t get_nid(struct page *p, int off, bool i)
+  *  - Mark cold node blocks in their node footer
+  *  - Mark cold data pages in page cache
+  */
+-static inline int is_cold_file(struct inode *inode)
++static inline int is_file(struct inode *inode, int type)
+ {
+-      return F2FS_I(inode)->i_advise & FADVISE_COLD_BIT;
++      return F2FS_I(inode)->i_advise & type;
+ }
+-static inline void set_cold_file(struct inode *inode)
++static inline void set_file(struct inode *inode, int type)
+ {
+-      F2FS_I(inode)->i_advise |= FADVISE_COLD_BIT;
++      F2FS_I(inode)->i_advise |= type;
+ }
+-static inline int is_cp_file(struct inode *inode)
+-{
+-      return F2FS_I(inode)->i_advise & FADVISE_CP_BIT;
+-}
+-
+-static inline void set_cp_file(struct inode *inode)
+-{
+-      F2FS_I(inode)->i_advise |= FADVISE_CP_BIT;
+-}
++#define is_cold_file(inode)   is_file(inode, FADVISE_COLD_BIT)
++#define is_cp_file(inode)     is_file(inode, FADVISE_CP_BIT)
++#define set_cold_file(inode)  set_file(inode, FADVISE_COLD_BIT)
++#define set_cp_file(inode)    set_file(inode, FADVISE_CP_BIT)
+ static inline int is_cold_data(struct page *page)
+ {
+@@ -310,29 +305,16 @@ static inline void clear_cold_data(struct page *page)
+       ClearPageChecked(page);
+ }
+-static inline int is_cold_node(struct page *page)
++static inline int is_node(struct page *page, int type)
+ {
+       void *kaddr = page_address(page);
+       struct f2fs_node *rn = (struct f2fs_node *)kaddr;
+-      unsigned int flag = le32_to_cpu(rn->footer.flag);
+-      return flag & (0x1 << COLD_BIT_SHIFT);
++      return le32_to_cpu(rn->footer.flag) & (1 << type);
+ }
+-static inline unsigned char is_fsync_dnode(struct page *page)
+-{
+-      void *kaddr = page_address(page);
+-      struct f2fs_node *rn = (struct f2fs_node *)kaddr;
+-      unsigned int flag = le32_to_cpu(rn->footer.flag);
+-      return flag & (0x1 << FSYNC_BIT_SHIFT);
+-}
+-
+-static inline unsigned char is_dent_dnode(struct page *page)
+-{
+-      void *kaddr = page_address(page);
+-      struct f2fs_node *rn = (struct f2fs_node *)kaddr;
+-      unsigned int flag = le32_to_cpu(rn->footer.flag);
+-      return flag & (0x1 << DENT_BIT_SHIFT);
+-}
++#define is_cold_node(page)    is_node(page, COLD_BIT_SHIFT)
++#define is_fsync_dnode(page)  is_node(page, FSYNC_BIT_SHIFT)
++#define is_dent_dnode(page)   is_node(page, DENT_BIT_SHIFT)
+ static inline void set_cold_node(struct inode *inode, struct page *page)
+ {
+@@ -346,26 +328,15 @@ static inline void set_cold_node(struct inode *inode, struct page *page)
+       rn->footer.flag = cpu_to_le32(flag);
+ }
+-static inline void set_fsync_mark(struct page *page, int mark)
+-{
+-      void *kaddr = page_address(page);
+-      struct f2fs_node *rn = (struct f2fs_node *)kaddr;
+-      unsigned int flag = le32_to_cpu(rn->footer.flag);
+-      if (mark)
+-              flag |= (0x1 << FSYNC_BIT_SHIFT);
+-      else
+-              flag &= ~(0x1 << FSYNC_BIT_SHIFT);
+-      rn->footer.flag = cpu_to_le32(flag);
+-}
+-
+-static inline void set_dentry_mark(struct page *page, int mark)
++static inline void set_mark(struct page *page, int mark, int type)
+ {
+-      void *kaddr = page_address(page);
+-      struct f2fs_node *rn = (struct f2fs_node *)kaddr;
++      struct f2fs_node *rn = (struct f2fs_node *)page_address(page);
+       unsigned int flag = le32_to_cpu(rn->footer.flag);
+       if (mark)
+-              flag |= (0x1 << DENT_BIT_SHIFT);
++              flag |= (0x1 << type);
+       else
+-              flag &= ~(0x1 << DENT_BIT_SHIFT);
++              flag &= ~(0x1 << type);
+       rn->footer.flag = cpu_to_le32(flag);
+ }
++#define set_dentry_mark(page, mark)   set_mark(page, mark, DENT_BIT_SHIFT)
++#define set_fsync_mark(page, mark)    set_mark(page, mark, FSYNC_BIT_SHIFT)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0479-f2fs-return-proper-error-from-start_gc_thread.patch b/patches.tizen/0479-f2fs-return-proper-error-from-start_gc_thread.patch
new file mode 100644 (file)
index 0000000..a1b5333
--- /dev/null
@@ -0,0 +1,57 @@
+From 8f13d691c5fbd6e37ac89f3f3df9521ec6b53458 Mon Sep 17 00:00:00 2001
+From: Namjae Jeon <namjae.jeon@samsung.com>
+Date: Sun, 26 May 2013 11:05:32 +0900
+Subject: [PATCH 0479/1302] f2fs: return proper error from start_gc_thread
+
+when there is an error from kthread_run, then return proper error
+rather than returning -ENOMEM.
+
+Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
+Signed-off-by: Amit Sahrawat <a.sahrawat@samsung.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/gc.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index 25b083c..ddc2c67 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -91,23 +91,28 @@ int start_gc_thread(struct f2fs_sb_info *sbi)
+ {
+       struct f2fs_gc_kthread *gc_th;
+       dev_t dev = sbi->sb->s_bdev->bd_dev;
++      int err = 0;
+       if (!test_opt(sbi, BG_GC))
+-              return 0;
++              goto out;
+       gc_th = kmalloc(sizeof(struct f2fs_gc_kthread), GFP_KERNEL);
+-      if (!gc_th)
+-              return -ENOMEM;
++      if (!gc_th) {
++              err = -ENOMEM;
++              goto out;
++      }
+       sbi->gc_thread = gc_th;
+       init_waitqueue_head(&sbi->gc_thread->gc_wait_queue_head);
+       sbi->gc_thread->f2fs_gc_task = kthread_run(gc_thread_func, sbi,
+                       "f2fs_gc-%u:%u", MAJOR(dev), MINOR(dev));
+       if (IS_ERR(gc_th->f2fs_gc_task)) {
++              err = PTR_ERR(gc_th->f2fs_gc_task);
+               kfree(gc_th);
+               sbi->gc_thread = NULL;
+-              return -ENOMEM;
+       }
+-      return 0;
++
++out:
++      return err;
+ }
+ void stop_gc_thread(struct f2fs_sb_info *sbi)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0480-f2fs-iput-only-if-whole-data-blocks-are-flushed.patch b/patches.tizen/0480-f2fs-iput-only-if-whole-data-blocks-are-flushed.patch
new file mode 100644 (file)
index 0000000..5c4560b
--- /dev/null
@@ -0,0 +1,43 @@
+From 7729117496e64b356ecdb03d5f3fd832ba033ebc Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Mon, 27 May 2013 10:32:01 +0900
+Subject: [PATCH 0480/1302] f2fs: iput only if whole data blocks are flushed
+
+If there remains some unwritten blocks from the recovery, we should not call
+iput on that directory inode.
+Otherwise, we can loose some dentry blocks after the recovery.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/checkpoint.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
+index 01ddc91..0d3701d 100644
+--- a/fs/f2fs/checkpoint.c
++++ b/fs/f2fs/checkpoint.c
+@@ -501,8 +501,10 @@ void remove_dirty_dir_inode(struct inode *inode)
+               return;
+       spin_lock(&sbi->dir_inode_lock);
+-      if (atomic_read(&F2FS_I(inode)->dirty_dents))
+-              goto out;
++      if (atomic_read(&F2FS_I(inode)->dirty_dents)) {
++              spin_unlock(&sbi->dir_inode_lock);
++              return;
++      }
+       list_for_each(this, head) {
+               struct dir_inode_entry *entry;
+@@ -516,7 +518,6 @@ void remove_dirty_dir_inode(struct inode *inode)
+                       break;
+               }
+       }
+-out:
+       spin_unlock(&sbi->dir_inode_lock);
+       /* Only from the recovery routine */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0481-f2fs-fix-dentry-recovery-routine.patch b/patches.tizen/0481-f2fs-fix-dentry-recovery-routine.patch
new file mode 100644 (file)
index 0000000..4037271
--- /dev/null
@@ -0,0 +1,76 @@
+From cd8ee4bddbe85ddc9fb9fbdb682c35725600ae45 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Tue, 28 May 2013 09:19:22 +0900
+Subject: [PATCH 0481/1302] f2fs: fix dentry recovery routine
+
+The error scenario is:
+1. create /a
+(1.a link /a /b)
+2. sync
+3. unlinke /a
+4. create /a
+5. fsync /a
+6. Sudden power-off
+
+When the f2fs recovers the fsynced dentry, /a, we discover an exsiting dentry at
+f2fs_find_entry() in recover_dentry().
+
+In such the case, we should unlink the existing dentry and its inode
+and then recover newly created dentry.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/recovery.c | 24 +++++++++++++++++++-----
+ 1 file changed, 19 insertions(+), 5 deletions(-)
+
+diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
+index 0dd2ce1..539ca32 100644
+--- a/fs/f2fs/recovery.c
++++ b/fs/f2fs/recovery.c
+@@ -44,9 +44,10 @@ static int recover_dentry(struct page *ipage, struct inode *inode)
+       struct f2fs_node *raw_node = (struct f2fs_node *)kaddr;
+       struct f2fs_inode *raw_inode = &(raw_node->i);
+       nid_t pino = le32_to_cpu(raw_inode->i_pino);
++      struct f2fs_dir_entry *de;
+       struct qstr name;
+       struct page *page;
+-      struct inode *dir;
++      struct inode *dir, *einode;
+       int err = 0;
+       dir = check_dirty_dir_inode(F2FS_SB(inode->i_sb), pino);
+@@ -61,13 +62,26 @@ static int recover_dentry(struct page *ipage, struct inode *inode)
+       name.len = le32_to_cpu(raw_inode->i_namelen);
+       name.name = raw_inode->i_name;
+-
+-      if (f2fs_find_entry(dir, &name, &page)) {
++retry:
++      de = f2fs_find_entry(dir, &name, &page);
++      if (de && inode->i_ino == le32_to_cpu(de->ino)) {
+               kunmap(page);
+               f2fs_put_page(page, 0);
+-      } else {
+-              err = __f2fs_add_link(dir, &name, inode);
++              goto out;
++      }
++      if (de) {
++              einode = f2fs_iget(inode->i_sb, le32_to_cpu(de->ino));
++              if (IS_ERR(einode)) {
++                      WARN_ON(1);
++                      if (PTR_ERR(einode) == -ENOENT)
++                              err = -EEXIST;
++                      goto out;
++              }
++              f2fs_delete_entry(de, page, einode);
++              iput(einode);
++              goto retry;
+       }
++      err = __f2fs_add_link(dir, &name, inode);
+ out:
+       f2fs_msg(inode->i_sb, KERN_NOTICE, "recover_inode and its dentry: "
+                       "ino = %x, name = %s, dir = %lx, err = %d",
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0482-f2fs-fix-incorrect-iputs-during-the-dentry-recovery.patch b/patches.tizen/0482-f2fs-fix-incorrect-iputs-during-the-dentry-recovery.patch
new file mode 100644 (file)
index 0000000..0b2a59e
--- /dev/null
@@ -0,0 +1,46 @@
+From 2b750e7584485402b3a52faacf3a6d24c87978c1 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Tue, 28 May 2013 09:59:27 +0900
+Subject: [PATCH 0482/1302] f2fs: fix incorrect iputs during the dentry
+ recovery
+
+- iget/iput flow in the dentry recovery process
+
+1. *dir* = f2fs_iget
+2. set FI_DELAY_IPUT to *dir*
+3. add *dir* to the dirty_dir_list
+                  - __f2fs_add_link
+                    - recover_dentry)
+4. iput *dir* by remove_dirty_dir_inode
+                  - sync_dirty_dir_inodes
+                    - write_chekcpoint
+
+If *dir*'s i_count is not 1 (i.e., root dir), remove_dirty_dir_inode is called
+later and then iput is triggered again due to the FI_DELAY_IPUT flag.
+So, let's unset the flag properly once iput is triggered.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/checkpoint.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
+index 0d3701d..6f56e57 100644
+--- a/fs/f2fs/checkpoint.c
++++ b/fs/f2fs/checkpoint.c
+@@ -521,8 +521,10 @@ void remove_dirty_dir_inode(struct inode *inode)
+       spin_unlock(&sbi->dir_inode_lock);
+       /* Only from the recovery routine */
+-      if (is_inode_flag_set(F2FS_I(inode), FI_DELAY_IPUT))
++      if (is_inode_flag_set(F2FS_I(inode), FI_DELAY_IPUT)) {
++              clear_inode_flag(F2FS_I(inode), FI_DELAY_IPUT);
+               iput(inode);
++      }
+ }
+ struct inode *check_dirty_dir_inode(struct f2fs_sb_info *sbi, nid_t ino)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0483-f2fs-cover-cp_file-information-with-ilock.patch b/patches.tizen/0483-f2fs-cover-cp_file-information-with-ilock.patch
new file mode 100644 (file)
index 0000000..722fff6
--- /dev/null
@@ -0,0 +1,58 @@
+From 9c2320b1e750ee48a9c356f5c8fbe2e0af877a47 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Tue, 28 May 2013 12:25:47 +0900
+Subject: [PATCH 0483/1302] f2fs: cover cp_file information with ilock
+
+If a file is linked with other files, it should be checkpointed at every fsync
+calls.
+For this, we use set_cp_file() with FADVISE_CP_BIT, but previously we didn't
+cover the flag by the global lock.
+This patch fixes that the inode page stores this correctly.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/dir.c   | 8 +++++++-
+ fs/f2fs/namei.c | 6 ------
+ 2 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
+index b278bfb..67e2d13 100644
+--- a/fs/f2fs/dir.c
++++ b/fs/f2fs/dir.c
+@@ -346,8 +346,14 @@ static struct page *init_inode_metadata(struct inode *inode,
+       init_dent_inode(name, page);
+-      if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK))
++      /*
++       * This file should be checkpointed during fsync.
++       * We lost i_pino from now on.
++       */
++      if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK)) {
++              set_cp_file(inode);
+               inc_nlink(inode);
++      }
+       return page;
+ error:
+diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
+index efe0a12..1fe1502 100644
+--- a/fs/f2fs/namei.c
++++ b/fs/f2fs/namei.c
+@@ -181,12 +181,6 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir,
+       if (err)
+               goto out;
+-      /*
+-       * This file should be checkpointed during fsync.
+-       * We lost i_pino from now on.
+-       */
+-      set_cp_file(inode);
+-
+       d_instantiate(dentry, inode);
+       return 0;
+ out:
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0484-f2fs-handle-errors-from-get_node_page-calls.patch b/patches.tizen/0484-f2fs-handle-errors-from-get_node_page-calls.patch
new file mode 100644 (file)
index 0000000..49eb204
--- /dev/null
@@ -0,0 +1,40 @@
+From b9c3637e0a67966cd51745630ee3431f30b8dbfb Mon Sep 17 00:00:00 2001
+From: Jason Hrycay <jhrycay@gmail.com>
+Date: Fri, 31 May 2013 12:45:11 -0500
+Subject: [PATCH 0484/1302] f2fs: handle errors from get_node_page calls
+
+Add check for error pointers returned from get_node_page in order to
+avoid dereferencing a bad address on the next use.
+
+Signed-off-by: Jason Hrycay <jason.hrycay@motorola.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/xattr.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
+index 0b02dce..ae61f35 100644
+--- a/fs/f2fs/xattr.c
++++ b/fs/f2fs/xattr.c
+@@ -218,6 +218,8 @@ int f2fs_getxattr(struct inode *inode, int name_index, const char *name,
+               return -ENODATA;
+       page = get_node_page(sbi, fi->i_xattr_nid);
++      if (IS_ERR(page))
++              return PTR_ERR(page);
+       base_addr = page_address(page);
+       list_for_each_xattr(entry, base_addr) {
+@@ -268,6 +270,8 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
+               return 0;
+       page = get_node_page(sbi, fi->i_xattr_nid);
++      if (IS_ERR(page))
++              return PTR_ERR(page);
+       base_addr = page_address(page);
+       list_for_each_xattr(entry, base_addr) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0485-f2fs-reorganise-the-function-get_victim_by_default.patch b/patches.tizen/0485-f2fs-reorganise-the-function-get_victim_by_default.patch
new file mode 100644 (file)
index 0000000..980d5fa
--- /dev/null
@@ -0,0 +1,85 @@
+From af4e695dc737165087afacd02a48442630ad62b6 Mon Sep 17 00:00:00 2001
+From: Namjae Jeon <namjae.jeon@samsung.com>
+Date: Sat, 1 Jun 2013 16:20:26 +0900
+Subject: [PATCH 0485/1302] f2fs: reorganise the function get_victim_by_default
+
+Fix the function get_victim_by_default, where it checks
+for the condition  that p.min_segno != NULL_SEGNO as
+shown:
+
+if (p.min_segno != NULL_SEGNO)
+           goto got_it;
+
+and if above condition is true then
+
+got_it:
+        if (p.min_segno != NULL_SEGNO) {
+
+So this condition is being checked twice. Hence move the goto
+statement after the if condition so that duplication of condition
+check is avoided.
+
+Also this function makes a call to get_max_cost() to compute
+the max cost based on the f2fs_sbi_info and victim policy. Since
+get_max_cost depends on on three parameters of victim_sel_policy
+=> alloc_mode, gc_mode & ofs_unit, once this victim policy is
+initialised, these value will not change till the execution
+time of get_victim_by_default() & also f2fs_sbi_info structure
+parameters will not change.
+
+Hence making calls to get_max_cost() in while loop does not seems to
+be a good point. Instead we can call it once in begining and store
+the results in local variable, which later can serve our purpose
+for comparing the cost with max cost inside the while loop.
+
+Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
+Signed-off-by: Pankaj Kumar <pankaj.km@samsung.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/gc.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index ddc2c67..3a9df36 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -241,14 +241,14 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi,
+ {
+       struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
+       struct victim_sel_policy p;
+-      unsigned int secno;
++      unsigned int secno, max_cost;
+       int nsearched = 0;
+       p.alloc_mode = alloc_mode;
+       select_policy(sbi, gc_type, type, &p);
+       p.min_segno = NULL_SEGNO;
+-      p.min_cost = get_max_cost(sbi, &p);
++      p.min_cost = max_cost = get_max_cost(sbi, &p);
+       mutex_lock(&dirty_i->seglist_lock);
+@@ -287,7 +287,7 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi,
+                       p.min_cost = cost;
+               }
+-              if (cost == get_max_cost(sbi, &p))
++              if (cost == max_cost)
+                       continue;
+               if (nsearched++ >= MAX_VICTIM_SEARCH) {
+@@ -295,8 +295,8 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi,
+                       break;
+               }
+       }
+-got_it:
+       if (p.min_segno != NULL_SEGNO) {
++got_it:
+               if (p.alloc_mode == LFS) {
+                       secno = GET_SECNO(sbi, p.min_segno);
+                       if (gc_type == FG_GC)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0486-f2fs-fix-iget-iput-of-dir-during-recovery.patch b/patches.tizen/0486-f2fs-fix-iget-iput-of-dir-during-recovery.patch
new file mode 100644 (file)
index 0000000..b0f9662
--- /dev/null
@@ -0,0 +1,137 @@
+From 7bd3679f773018ee41177ed43e1f043d94ead3b0 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Wed, 5 Jun 2013 17:42:45 +0900
+Subject: [PATCH 0486/1302] f2fs: fix iget/iput of dir during recovery
+
+It is possible that iput is skipped after iget during the recovery.
+
+In recover_dentry(),
+ dir = f2fs_iget();
+ ...
+ if (de && inode->i_ino == le32_to_cpu(de->ino))
+       goto out;
+
+In this case, this dir is not able to be added in dirty_dir_inode_list.
+The actual linking is done only when set_page_dirty() is called.
+
+So let's add this newly got inode into the list explicitly, and put it at the
+end of the recovery routine.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/checkpoint.c | 55 +++++++++++++++++++++++++++++++++++++---------------
+ fs/f2fs/f2fs.h       |  1 +
+ fs/f2fs/recovery.c   |  1 +
+ 3 files changed, 41 insertions(+), 16 deletions(-)
+
+diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
+index 6f56e57..9a77509 100644
+--- a/fs/f2fs/checkpoint.c
++++ b/fs/f2fs/checkpoint.c
+@@ -450,13 +450,30 @@ fail_no_cp:
+       return -EINVAL;
+ }
+-void set_dirty_dir_page(struct inode *inode, struct page *page)
++static int __add_dirty_inode(struct inode *inode, struct dir_inode_entry *new)
+ {
+       struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
+       struct list_head *head = &sbi->dir_inode_list;
+-      struct dir_inode_entry *new;
+       struct list_head *this;
++      list_for_each(this, head) {
++              struct dir_inode_entry *entry;
++              entry = list_entry(this, struct dir_inode_entry, list);
++              if (entry->inode == inode)
++                      return -EEXIST;
++      }
++      list_add_tail(&new->list, head);
++#ifdef CONFIG_F2FS_STAT_FS
++      sbi->n_dirty_dirs++;
++#endif
++      return 0;
++}
++
++void set_dirty_dir_page(struct inode *inode, struct page *page)
++{
++      struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
++      struct dir_inode_entry *new;
++
+       if (!S_ISDIR(inode->i_mode))
+               return;
+ retry:
+@@ -469,25 +486,31 @@ retry:
+       INIT_LIST_HEAD(&new->list);
+       spin_lock(&sbi->dir_inode_lock);
+-      list_for_each(this, head) {
+-              struct dir_inode_entry *entry;
+-              entry = list_entry(this, struct dir_inode_entry, list);
+-              if (entry->inode == inode) {
+-                      kmem_cache_free(inode_entry_slab, new);
+-                      goto out;
+-              }
+-      }
+-      list_add_tail(&new->list, head);
+-#ifdef CONFIG_F2FS_STAT_FS
+-      sbi->n_dirty_dirs++;
+-#endif
++      if (__add_dirty_inode(inode, new))
++              kmem_cache_free(inode_entry_slab, new);
+-      BUG_ON(!S_ISDIR(inode->i_mode));
+-out:
+       inc_page_count(sbi, F2FS_DIRTY_DENTS);
+       inode_inc_dirty_dents(inode);
+       SetPagePrivate(page);
++      spin_unlock(&sbi->dir_inode_lock);
++}
++
++void add_dirty_dir_inode(struct inode *inode)
++{
++      struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
++      struct dir_inode_entry *new;
++retry:
++      new = kmem_cache_alloc(inode_entry_slab, GFP_NOFS);
++      if (!new) {
++              cond_resched();
++              goto retry;
++      }
++      new->inode = inode;
++      INIT_LIST_HEAD(&new->list);
++      spin_lock(&sbi->dir_inode_lock);
++      if (__add_dirty_inode(inode, new))
++              kmem_cache_free(inode_entry_slab, new);
+       spin_unlock(&sbi->dir_inode_lock);
+ }
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 40b137a..d6e63da 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -1030,6 +1030,7 @@ void remove_orphan_inode(struct f2fs_sb_info *, nid_t);
+ int recover_orphan_inodes(struct f2fs_sb_info *);
+ int get_valid_checkpoint(struct f2fs_sb_info *);
+ void set_dirty_dir_page(struct inode *, struct page *);
++void add_dirty_dir_inode(struct inode *);
+ void remove_dirty_dir_inode(struct inode *);
+ struct inode *check_dirty_dir_inode(struct f2fs_sb_info *, nid_t);
+ void sync_dirty_dir_inodes(struct f2fs_sb_info *);
+diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
+index 539ca32..ddde14f 100644
+--- a/fs/f2fs/recovery.c
++++ b/fs/f2fs/recovery.c
+@@ -58,6 +58,7 @@ static int recover_dentry(struct page *ipage, struct inode *inode)
+                       goto out;
+               }
+               set_inode_flag(F2FS_I(dir), FI_DELAY_IPUT);
++              add_dirty_dir_inode(dir);
+       }
+       name.len = le32_to_cpu(raw_inode->i_namelen);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0487-f2fs-support-xattr-security-labels.patch b/patches.tizen/0487-f2fs-support-xattr-security-labels.patch
new file mode 100644 (file)
index 0000000..86efd19
--- /dev/null
@@ -0,0 +1,349 @@
+From 5d80c5766a2767d8f58cfafb8d5bee676d21e8cf Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Mon, 3 Jun 2013 19:46:19 +0900
+Subject: [PATCH 0487/1302] f2fs: support xattr security labels
+
+This patch adds the support of security labels for f2fs, which will be used
+by Linus Security Models (LSMs).
+
+Quote from http://en.wikipedia.org/wiki/Linux_Security_Modules:
+"Linux Security Modules (LSM) is a framework that allows the Linux kernel to
+support a variety of computer security models while avoiding favoritism toward
+any single security implementation. The framework is licensed under the terms of
+the GNU General Public License and is standard part of the Linux kernel since
+Linux 2.6. AppArmor, SELinux, Smack and TOMOYO Linux are the currently accepted
+modules in the official kernel.".
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/Kconfig | 12 +++++++++++
+ fs/f2fs/acl.c   |  2 +-
+ fs/f2fs/dir.c   |  5 +++++
+ fs/f2fs/f2fs.h  |  2 +-
+ fs/f2fs/node.c  | 12 +++++++----
+ fs/f2fs/xattr.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
+ fs/f2fs/xattr.h | 24 ++++++++++++++--------
+ 7 files changed, 100 insertions(+), 21 deletions(-)
+
+diff --git a/fs/f2fs/Kconfig b/fs/f2fs/Kconfig
+index fd27e7e..e06e099 100644
+--- a/fs/f2fs/Kconfig
++++ b/fs/f2fs/Kconfig
+@@ -51,3 +51,15 @@ config F2FS_FS_POSIX_ACL
+         Linux website <http://acl.bestbits.at/>.
+         If you don't know what Access Control Lists are, say N
++
++config F2FS_FS_SECURITY
++      bool "F2FS Security Labels"
++      depends on F2FS_FS_XATTR
++      help
++        Security labels provide an access control facility to support Linux
++        Security Models (LSMs) accepted by AppArmor, SELinux, Smack and TOMOYO
++        Linux. This option enables an extended attribute handler for file
++        security labels in the f2fs filesystem, so that it requires enabling
++        the extended attribute support in advance.
++
++        If you are not using a security module, say N.
+diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c
+index 44abc2f..b7826ec 100644
+--- a/fs/f2fs/acl.c
++++ b/fs/f2fs/acl.c
+@@ -250,7 +250,7 @@ static int f2fs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
+               }
+       }
+-      error = f2fs_setxattr(inode, name_index, "", value, size);
++      error = f2fs_setxattr(inode, name_index, "", value, size, NULL);
+       kfree(value);
+       if (!error)
+diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
+index 67e2d13..eaea5b5 100644
+--- a/fs/f2fs/dir.c
++++ b/fs/f2fs/dir.c
+@@ -13,6 +13,7 @@
+ #include "f2fs.h"
+ #include "node.h"
+ #include "acl.h"
++#include "xattr.h"
+ static unsigned long dir_blocks(struct inode *inode)
+ {
+@@ -334,6 +335,10 @@ static struct page *init_inode_metadata(struct inode *inode,
+               if (err)
+                       goto error;
++              err = f2fs_init_security(inode, dir, name, page);
++              if (err)
++                      goto error;
++
+               wait_on_page_writeback(page);
+       } else {
+               page = get_node_page(F2FS_SB(dir->i_sb), inode->i_ino);
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index d6e63da..4f2c209 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -968,7 +968,7 @@ int get_dnode_of_data(struct dnode_of_data *, pgoff_t, int);
+ int truncate_inode_blocks(struct inode *, pgoff_t);
+ int remove_inode_page(struct inode *);
+ struct page *new_inode_page(struct inode *, const struct qstr *);
+-struct page *new_node_page(struct dnode_of_data *, unsigned int);
++struct page *new_node_page(struct dnode_of_data *, unsigned int, struct page *);
+ void ra_node_page(struct f2fs_sb_info *, nid_t);
+ struct page *get_node_page(struct f2fs_sb_info *, pgoff_t);
+ struct page *get_node_page_ra(struct page *, int);
+diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
+index 5a59780..b02440c 100644
+--- a/fs/f2fs/node.c
++++ b/fs/f2fs/node.c
+@@ -433,7 +433,7 @@ int get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode)
+                       }
+                       dn->nid = nids[i];
+-                      npage[i] = new_node_page(dn, noffset[i]);
++                      npage[i] = new_node_page(dn, noffset[i], NULL);
+                       if (IS_ERR(npage[i])) {
+                               alloc_nid_failed(sbi, nids[i]);
+                               err = PTR_ERR(npage[i]);
+@@ -814,10 +814,11 @@ struct page *new_inode_page(struct inode *inode, const struct qstr *name)
+       set_new_dnode(&dn, inode, NULL, NULL, inode->i_ino);
+       /* caller should f2fs_put_page(page, 1); */
+-      return new_node_page(&dn, 0);
++      return new_node_page(&dn, 0, NULL);
+ }
+-struct page *new_node_page(struct dnode_of_data *dn, unsigned int ofs)
++struct page *new_node_page(struct dnode_of_data *dn,
++                              unsigned int ofs, struct page *ipage)
+ {
+       struct f2fs_sb_info *sbi = F2FS_SB(dn->inode->i_sb);
+       struct address_space *mapping = sbi->node_inode->i_mapping;
+@@ -850,7 +851,10 @@ struct page *new_node_page(struct dnode_of_data *dn, unsigned int ofs)
+       set_cold_node(dn->inode, page);
+       dn->node_page = page;
+-      sync_inode_page(dn);
++      if (ipage)
++              update_inode(dn->inode, ipage);
++      else
++              sync_inode_page(dn);
+       set_page_dirty(page);
+       if (ofs == 0)
+               inc_valid_inode_count(sbi);
+diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
+index ae61f35..3ab07ec 100644
+--- a/fs/f2fs/xattr.c
++++ b/fs/f2fs/xattr.c
+@@ -20,6 +20,7 @@
+  */
+ #include <linux/rwsem.h>
+ #include <linux/f2fs_fs.h>
++#include <linux/security.h>
+ #include "f2fs.h"
+ #include "xattr.h"
+@@ -43,6 +44,10 @@ static size_t f2fs_xattr_generic_list(struct dentry *dentry, char *list,
+               prefix = XATTR_TRUSTED_PREFIX;
+               prefix_len = XATTR_TRUSTED_PREFIX_LEN;
+               break;
++      case F2FS_XATTR_INDEX_SECURITY:
++              prefix = XATTR_SECURITY_PREFIX;
++              prefix_len = XATTR_SECURITY_PREFIX_LEN;
++              break;
+       default:
+               return -EINVAL;
+       }
+@@ -50,7 +55,7 @@ static size_t f2fs_xattr_generic_list(struct dentry *dentry, char *list,
+       total_len = prefix_len + name_len + 1;
+       if (list && total_len <= list_size) {
+               memcpy(list, prefix, prefix_len);
+-              memcpy(list+prefix_len, name, name_len);
++              memcpy(list + prefix_len, name, name_len);
+               list[prefix_len + name_len] = '\0';
+       }
+       return total_len;
+@@ -70,13 +75,14 @@ static int f2fs_xattr_generic_get(struct dentry *dentry, const char *name,
+               if (!capable(CAP_SYS_ADMIN))
+                       return -EPERM;
+               break;
++      case F2FS_XATTR_INDEX_SECURITY:
++              break;
+       default:
+               return -EINVAL;
+       }
+       if (strcmp(name, "") == 0)
+               return -EINVAL;
+-      return f2fs_getxattr(dentry->d_inode, type, name,
+-                      buffer, size);
++      return f2fs_getxattr(dentry->d_inode, type, name, buffer, size);
+ }
+ static int f2fs_xattr_generic_set(struct dentry *dentry, const char *name,
+@@ -93,13 +99,15 @@ static int f2fs_xattr_generic_set(struct dentry *dentry, const char *name,
+               if (!capable(CAP_SYS_ADMIN))
+                       return -EPERM;
+               break;
++      case F2FS_XATTR_INDEX_SECURITY:
++              break;
+       default:
+               return -EINVAL;
+       }
+       if (strcmp(name, "") == 0)
+               return -EINVAL;
+-      return f2fs_setxattr(dentry->d_inode, type, name, value, size);
++      return f2fs_setxattr(dentry->d_inode, type, name, value, size, NULL);
+ }
+ static size_t f2fs_xattr_advise_list(struct dentry *dentry, char *list,
+@@ -145,6 +153,31 @@ static int f2fs_xattr_advise_set(struct dentry *dentry, const char *name,
+       return 0;
+ }
++#ifdef CONFIG_F2FS_FS_SECURITY
++static int f2fs_initxattrs(struct inode *inode, const struct xattr *xattr_array,
++              void *page)
++{
++      const struct xattr *xattr;
++      int err = 0;
++
++      for (xattr = xattr_array; xattr->name != NULL; xattr++) {
++              err = f2fs_setxattr(inode, F2FS_XATTR_INDEX_SECURITY,
++                              xattr->name, xattr->value,
++                              xattr->value_len, (struct page *)page);
++              if (err < 0)
++                      break;
++      }
++      return err;
++}
++
++int f2fs_init_security(struct inode *inode, struct inode *dir,
++                              const struct qstr *qstr, struct page *ipage)
++{
++      return security_inode_init_security(inode, dir, qstr,
++                              &f2fs_initxattrs, ipage);
++}
++#endif
++
+ const struct xattr_handler f2fs_xattr_user_handler = {
+       .prefix = XATTR_USER_PREFIX,
+       .flags  = F2FS_XATTR_INDEX_USER,
+@@ -169,6 +202,14 @@ const struct xattr_handler f2fs_xattr_advise_handler = {
+       .set    = f2fs_xattr_advise_set,
+ };
++const struct xattr_handler f2fs_xattr_security_handler = {
++      .prefix = XATTR_SECURITY_PREFIX,
++      .flags  = F2FS_XATTR_INDEX_SECURITY,
++      .list   = f2fs_xattr_generic_list,
++      .get    = f2fs_xattr_generic_get,
++      .set    = f2fs_xattr_generic_set,
++};
++
+ static const struct xattr_handler *f2fs_xattr_handler_map[] = {
+       [F2FS_XATTR_INDEX_USER] = &f2fs_xattr_user_handler,
+ #ifdef CONFIG_F2FS_FS_POSIX_ACL
+@@ -176,6 +217,9 @@ static const struct xattr_handler *f2fs_xattr_handler_map[] = {
+       [F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT] = &f2fs_xattr_acl_default_handler,
+ #endif
+       [F2FS_XATTR_INDEX_TRUSTED] = &f2fs_xattr_trusted_handler,
++#ifdef CONFIG_F2FS_FS_SECURITY
++      [F2FS_XATTR_INDEX_SECURITY] = &f2fs_xattr_security_handler,
++#endif
+       [F2FS_XATTR_INDEX_ADVISE] = &f2fs_xattr_advise_handler,
+ };
+@@ -186,6 +230,9 @@ const struct xattr_handler *f2fs_xattr_handlers[] = {
+       &f2fs_xattr_acl_default_handler,
+ #endif
+       &f2fs_xattr_trusted_handler,
++#ifdef CONFIG_F2FS_FS_SECURITY
++      &f2fs_xattr_security_handler,
++#endif
+       &f2fs_xattr_advise_handler,
+       NULL,
+ };
+@@ -300,7 +347,7 @@ cleanup:
+ }
+ int f2fs_setxattr(struct inode *inode, int name_index, const char *name,
+-                                      const void *value, size_t value_len)
++                      const void *value, size_t value_len, struct page *ipage)
+ {
+       struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
+       struct f2fs_inode_info *fi = F2FS_I(inode);
+@@ -339,7 +386,7 @@ int f2fs_setxattr(struct inode *inode, int name_index, const char *name,
+               set_new_dnode(&dn, inode, NULL, NULL, fi->i_xattr_nid);
+               mark_inode_dirty(inode);
+-              page = new_node_page(&dn, XATTR_NODE_OFFSET);
++              page = new_node_page(&dn, XATTR_NODE_OFFSET, ipage);
+               if (IS_ERR(page)) {
+                       alloc_nid_failed(sbi, fi->i_xattr_nid);
+                       fi->i_xattr_nid = 0;
+@@ -439,7 +486,10 @@ int f2fs_setxattr(struct inode *inode, int name_index, const char *name,
+               inode->i_ctime = CURRENT_TIME;
+               clear_inode_flag(fi, FI_ACL_MODE);
+       }
+-      update_inode_page(inode);
++      if (ipage)
++              update_inode(inode, ipage);
++      else
++              update_inode_page(inode);
+       mutex_unlock_op(sbi, ilock);
+       return 0;
+diff --git a/fs/f2fs/xattr.h b/fs/f2fs/xattr.h
+index 49c9558..3c0817b 100644
+--- a/fs/f2fs/xattr.h
++++ b/fs/f2fs/xattr.h
+@@ -112,21 +112,19 @@ extern const struct xattr_handler f2fs_xattr_trusted_handler;
+ extern const struct xattr_handler f2fs_xattr_acl_access_handler;
+ extern const struct xattr_handler f2fs_xattr_acl_default_handler;
+ extern const struct xattr_handler f2fs_xattr_advise_handler;
++extern const struct xattr_handler f2fs_xattr_security_handler;
+ extern const struct xattr_handler *f2fs_xattr_handlers[];
+-extern int f2fs_setxattr(struct inode *inode, int name_index, const char *name,
+-              const void *value, size_t value_len);
+-extern int f2fs_getxattr(struct inode *inode, int name_index, const char *name,
+-              void *buffer, size_t buffer_size);
+-extern ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer,
+-              size_t buffer_size);
+-
++extern int f2fs_setxattr(struct inode *, int, const char *,
++                              const void *, size_t, struct page *);
++extern int f2fs_getxattr(struct inode *, int, const char *, void *, size_t);
++extern ssize_t f2fs_listxattr(struct dentry *, char *, size_t);
+ #else
+ #define f2fs_xattr_handlers   NULL
+ static inline int f2fs_setxattr(struct inode *inode, int name_index,
+-      const char *name, const void *value, size_t value_len)
++              const char *name, const void *value, size_t value_len)
+ {
+       return -EOPNOTSUPP;
+ }
+@@ -142,4 +140,14 @@ static inline ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer,
+ }
+ #endif
++#ifdef CONFIG_F2FS_FS_SECURITY
++extern int f2fs_init_security(struct inode *, struct inode *,
++                              const struct qstr *, struct page *);
++#else
++static inline int f2fs_init_security(struct inode *inode, struct inode *dir,
++                              const struct qstr *qstr, struct page *ipage)
++{
++      return 0;
++}
++#endif
+ #endif /* __F2FS_XATTR_H__ */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0488-f2fs-set-sb-s_fs_info-before-calling-parse_options.patch b/patches.tizen/0488-f2fs-set-sb-s_fs_info-before-calling-parse_options.patch
new file mode 100644 (file)
index 0000000..9f7dad9
--- /dev/null
@@ -0,0 +1,61 @@
+From bd85aa9f6c709ded4a1b454e603a67e8eec72830 Mon Sep 17 00:00:00 2001
+From: Gu Zheng <guz.fnst@cn.fujitsu.com>
+Date: Fri, 7 Jun 2013 14:16:53 +0800
+Subject: [PATCH 0488/1302] f2fs: set sb->s_fs_info before calling
+ parse_options()
+
+In f2fs_fill_super(), set sb->s_fs_info before calling parse_options(), then we can get
+f2fs_sb_info via F2FS_SB(sb) in parse_options().
+So that the second argument "sbi" of func parse_options() is no longer needed.
+
+Signed-off-by: Gu Zheng <guz.fnst@cn.fujitsu.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/super.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 3ac305d..4fdcdff 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -303,9 +303,9 @@ static const struct export_operations f2fs_export_ops = {
+       .get_parent = f2fs_get_parent,
+ };
+-static int parse_options(struct super_block *sb, struct f2fs_sb_info *sbi,
+-                              char *options)
++static int parse_options(struct super_block *sb, char *options)
+ {
++      struct f2fs_sb_info *sbi = F2FS_SB(sb);
+       substring_t args[MAX_OPT_ARGS];
+       char *p;
+       int arg = 0;
+@@ -541,6 +541,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
+               if (err)
+                       goto free_sb_buf;
+       }
++      sb->s_fs_info = sbi;
+       /* init some FS parameters */
+       sbi->active_logs = NR_CURSEG_TYPE;
+@@ -553,7 +554,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
+       set_opt(sbi, POSIX_ACL);
+ #endif
+       /* parse mount options */
+-      err = parse_options(sb, sbi, (char *)data);
++      err = parse_options(sb, (char *)data);
+       if (err)
+               goto free_sb_buf;
+@@ -565,7 +566,6 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
+       sb->s_xattr = f2fs_xattr_handlers;
+       sb->s_export_op = &f2fs_export_ops;
+       sb->s_magic = F2FS_SUPER_MAGIC;
+-      sb->s_fs_info = sbi;
+       sb->s_time_gran = 1;
+       sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
+               (test_opt(sbi, POSIX_ACL) ? MS_POSIXACL : 0);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0489-f2fs-fix-i_blocks-translation-on-various-types-of-fi.patch b/patches.tizen/0489-f2fs-fix-i_blocks-translation-on-various-types-of-fi.patch
new file mode 100644 (file)
index 0000000..b9cdd2a
--- /dev/null
@@ -0,0 +1,78 @@
+From 30e853f528c57c3a727c664df4ad5dd1eaa388a4 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Fri, 7 Jun 2013 16:33:07 +0900
+Subject: [PATCH 0489/1302] f2fs: fix i_blocks translation on various types of
+ files
+
+Basically an inode manages the number of allocated blocks with inode->i_blocks
+which is represented in a unit of sectors, not file system blocks.
+But, f2fs has used i_blocks in a unit of file system blocks, and f2fs_getattr
+translates it to the number of sectors when fstat is called.
+
+However, previously f2fs_file_inode_operations only has this, so this patch adds
+it to all the types of inode_operations.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/f2fs.h  | 1 +
+ fs/f2fs/file.c  | 2 +-
+ fs/f2fs/namei.c | 3 +++
+ 3 files changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 4f2c209..c344a4d 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -903,6 +903,7 @@ static inline int f2fs_readonly(struct super_block *sb)
+ int f2fs_sync_file(struct file *, loff_t, loff_t, int);
+ void truncate_data_blocks(struct dnode_of_data *);
+ void f2fs_truncate(struct inode *);
++int f2fs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+ int f2fs_setattr(struct dentry *, struct iattr *);
+ int truncate_hole(struct inode *, pgoff_t, pgoff_t);
+ int truncate_data_blocks_range(struct dnode_of_data *, int);
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index deefd25..8d2fce9 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -291,7 +291,7 @@ void f2fs_truncate(struct inode *inode)
+       }
+ }
+-static int f2fs_getattr(struct vfsmount *mnt,
++int f2fs_getattr(struct vfsmount *mnt,
+                        struct dentry *dentry, struct kstat *stat)
+ {
+       struct inode *inode = dentry->d_inode;
+diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
+index 1fe1502..810444e 100644
+--- a/fs/f2fs/namei.c
++++ b/fs/f2fs/namei.c
+@@ -490,6 +490,7 @@ const struct inode_operations f2fs_dir_inode_operations = {
+       .rmdir          = f2fs_rmdir,
+       .mknod          = f2fs_mknod,
+       .rename         = f2fs_rename,
++      .getattr        = f2fs_getattr,
+       .setattr        = f2fs_setattr,
+       .get_acl        = f2fs_get_acl,
+ #ifdef CONFIG_F2FS_FS_XATTR
+@@ -504,6 +505,7 @@ const struct inode_operations f2fs_symlink_inode_operations = {
+       .readlink       = generic_readlink,
+       .follow_link    = page_follow_link_light,
+       .put_link       = page_put_link,
++      .getattr        = f2fs_getattr,
+       .setattr        = f2fs_setattr,
+ #ifdef CONFIG_F2FS_FS_XATTR
+       .setxattr       = generic_setxattr,
+@@ -514,6 +516,7 @@ const struct inode_operations f2fs_symlink_inode_operations = {
+ };
+ const struct inode_operations f2fs_special_inode_operations = {
++      .getattr        = f2fs_getattr,
+       .setattr        = f2fs_setattr,
+       .get_acl        = f2fs_get_acl,
+ #ifdef CONFIG_F2FS_FS_XATTR
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0490-f2fs-sync-dir-i_size-with-its-block-allocation.patch b/patches.tizen/0490-f2fs-sync-dir-i_size-with-its-block-allocation.patch
new file mode 100644 (file)
index 0000000..8913ff9
--- /dev/null
@@ -0,0 +1,104 @@
+From a3e031050b714757b6beb15f50033b4099e559bf Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Fri, 7 Jun 2013 22:08:23 +0900
+Subject: [PATCH 0490/1302] f2fs: sync dir->i_size with its block allocation
+
+If new dentry block is allocated and its i_size is updated, we should update
+its inode block together in order to sync i_size and its block allocation.
+Otherwise, we can loose additional dentry block due to the unconsistent i_size.
+
+Errorneous Scenario
+-------------------
+
+In the recovery routine,
+ - recovery_dentry
+ | - __f2fs_add_link
+ | | - get_new_data_page
+ | | | - i_size_write(new_i_size)
+ | | | - mark_inode_dirty_sync(dir)
+ | | - update_parent_metadata
+ | | | - mark_inode_dirty(dir)
+ |
+ - write_checkpoint
+   - sync_dirty_dir_inodes
+     - filemap_flush(dentry_blocks)
+       - f2fs_write_data_page
+         - skip to write the last dentry block due to index < i_size
+
+In the above flow, new_i_size is not updated to its inode block so that the
+last dentry block will be lost accordingly.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/data.c | 2 ++
+ fs/f2fs/dir.c  | 9 ++++-----
+ fs/f2fs/f2fs.h | 1 +
+ 3 files changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 93917e3..5b145fc 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -339,6 +339,8 @@ repeat:
+       if (new_i_size &&
+               i_size_read(inode) < ((index + 1) << PAGE_CACHE_SHIFT)) {
+               i_size_write(inode, ((index + 1) << PAGE_CACHE_SHIFT));
++              /* Only the directory inode sets new_i_size */
++              set_inode_flag(F2FS_I(inode), FI_UPDATE_DIR);
+               mark_inode_dirty_sync(inode);
+       }
+       return page;
+diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
+index eaea5b5..69ca049 100644
+--- a/fs/f2fs/dir.c
++++ b/fs/f2fs/dir.c
+@@ -370,22 +370,20 @@ error:
+ static void update_parent_metadata(struct inode *dir, struct inode *inode,
+                                               unsigned int current_depth)
+ {
+-      bool need_dir_update = false;
+-
+       if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE)) {
+               if (S_ISDIR(inode->i_mode)) {
+                       inc_nlink(dir);
+-                      need_dir_update = true;
++                      set_inode_flag(F2FS_I(dir), FI_UPDATE_DIR);
+               }
+               clear_inode_flag(F2FS_I(inode), FI_NEW_INODE);
+       }
+       dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+       if (F2FS_I(dir)->i_current_depth != current_depth) {
+               F2FS_I(dir)->i_current_depth = current_depth;
+-              need_dir_update = true;
++              set_inode_flag(F2FS_I(dir), FI_UPDATE_DIR);
+       }
+-      if (need_dir_update)
++      if (is_inode_flag_set(F2FS_I(dir), FI_UPDATE_DIR))
+               update_inode_page(dir);
+       else
+               mark_inode_dirty(dir);
+@@ -502,6 +500,7 @@ add_dentry:
+       update_parent_metadata(dir, inode, current_depth);
+ fail:
++      clear_inode_flag(F2FS_I(dir), FI_UPDATE_DIR);
+       kunmap(dentry_page);
+       f2fs_put_page(dentry_page, 1);
+       return err;
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index c344a4d..27edf59 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -859,6 +859,7 @@ enum {
+       FI_INC_LINK,            /* need to increment i_nlink */
+       FI_ACL_MODE,            /* indicate acl mode */
+       FI_NO_ALLOC,            /* should not allocate any blocks */
++      FI_UPDATE_DIR,          /* should update inode block for consistency */
+       FI_DELAY_IPUT,          /* used for the recovery */
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0491-f2fs-use-the-F2FS-specific-flags-in-f2fs_ioctl.patch b/patches.tizen/0491-f2fs-use-the-F2FS-specific-flags-in-f2fs_ioctl.patch
new file mode 100644 (file)
index 0000000..4526d2b
--- /dev/null
@@ -0,0 +1,37 @@
+From c2dfda645ffe25cc855739b509783415bc22ca66 Mon Sep 17 00:00:00 2001
+From: Namjae Jeon <namjae.jeon@samsung.com>
+Date: Sat, 8 Jun 2013 21:25:28 +0900
+Subject: [PATCH 0491/1302] f2fs: use the F2FS specific flags in f2fs_ioctl()
+
+In f2fs_ioctl() function, it is using generic flags.
+Since F2FS specific flags are defined. So lets use
+those flags.
+
+Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
+Signed-off-by: Pankaj Kumar <pankaj.km@samsung.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/file.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 8d2fce9..85b665d 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -575,10 +575,10 @@ long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+       int ret;
+       switch (cmd) {
+-      case FS_IOC_GETFLAGS:
++      case F2FS_IOC_GETFLAGS:
+               flags = fi->i_flags & FS_FL_USER_VISIBLE;
+               return put_user(flags, (int __user *) arg);
+-      case FS_IOC_SETFLAGS:
++      case F2FS_IOC_SETFLAGS:
+       {
+               unsigned int oldflags;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0492-f2fs-optimise-the-truncate_data_blocks_range-range.patch b/patches.tizen/0492-f2fs-optimise-the-truncate_data_blocks_range-range.patch
new file mode 100644 (file)
index 0000000..09cb56d
--- /dev/null
@@ -0,0 +1,51 @@
+From 41cd8ded7bd1ee1117fff161e6f7431ed514ed34 Mon Sep 17 00:00:00 2001
+From: Namjae Jeon <namjae.jeon@samsung.com>
+Date: Sat, 8 Jun 2013 21:25:40 +0900
+Subject: [PATCH 0492/1302] f2fs: optimise the truncate_data_blocks_range()
+ range
+
+The function truncate_data_blocks_range() decrements the valid
+block count of inode via dec_valid_block_count(). Since this
+function updates the i_blocks field of inode, we can update this
+field once we have calculated total the number of blocks
+to be freed.
+
+Therefore we can decrement valid blocks outside of the for loop.
+
+       if (nr_free) {
++              dec_valid_block_count(sbi, dn->inode, nr_free);
+               set_page_dirty(dn->node_page);
+               sync_inode_page(dn);
+       }
+
+'nr_free' tells the total number of blocks freed. So, we can
+just directly pass this value to dec_valid_block_count() and update
+the i_blocks.
+
+Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
+Signed-off-by: Pankaj Kumar <pankaj.km@samsung.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/file.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 85b665d..2f649b8 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -185,10 +185,10 @@ int truncate_data_blocks_range(struct dnode_of_data *dn, int count)
+               update_extent_cache(NULL_ADDR, dn);
+               invalidate_blocks(sbi, blkaddr);
+-              dec_valid_block_count(sbi, dn->inode, 1);
+               nr_free++;
+       }
+       if (nr_free) {
++              dec_valid_block_count(sbi, dn->inode, nr_free);
+               set_page_dirty(dn->node_page);
+               sync_inode_page(dn);
+       }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0493-f2fs-avoid-freqeunt-write_inode-calls.patch b/patches.tizen/0493-f2fs-avoid-freqeunt-write_inode-calls.patch
new file mode 100644 (file)
index 0000000..e97593c
--- /dev/null
@@ -0,0 +1,96 @@
+From f447b34c9af60ca5f0a0586a51107794a9dbb6c5 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Mon, 10 Jun 2013 09:17:01 +0900
+Subject: [PATCH 0493/1302] f2fs: avoid freqeunt write_inode calls
+
+If update_inode is called, we don't need to do write_inode.
+So, let's use a *dirty* flag for each inode.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/f2fs.h  |  1 +
+ fs/f2fs/file.c  |  1 +
+ fs/f2fs/inode.c |  4 ++++
+ fs/f2fs/super.c | 12 ++++++++++++
+ 4 files changed, 18 insertions(+)
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 27edf59..a05aa65 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -856,6 +856,7 @@ static inline int f2fs_clear_bit(unsigned int nr, char *addr)
+ /* used for f2fs_inode_info->flags */
+ enum {
+       FI_NEW_INODE,           /* indicate newly allocated inode */
++      FI_DIRTY_INODE,         /* indicate inode is dirty or not */
+       FI_INC_LINK,            /* need to increment i_nlink */
+       FI_ACL_MODE,            /* indicate acl mode */
+       FI_NO_ALLOC,            /* should not allocate any blocks */
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 2f649b8..fda226f 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -147,6 +147,7 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
+       } else {
+               /* if there is no written node page, write its inode page */
+               while (!sync_node_pages(sbi, inode->i_ino, &wbc)) {
++                      mark_inode_dirty_sync(inode);
+                       ret = f2fs_write_inode(inode, NULL);
+                       if (ret)
+                               goto out;
+diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
+index b44a4c1..2b2d45d1 100644
+--- a/fs/f2fs/inode.c
++++ b/fs/f2fs/inode.c
+@@ -192,6 +192,7 @@ void update_inode(struct inode *inode, struct page *node_page)
+       set_cold_node(inode, node_page);
+       set_page_dirty(node_page);
++      clear_inode_flag(F2FS_I(inode), FI_DIRTY_INODE);
+ }
+ int update_inode_page(struct inode *inode)
+@@ -217,6 +218,9 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc)
+                       inode->i_ino == F2FS_META_INO(sbi))
+               return 0;
++      if (!is_inode_flag_set(F2FS_I(inode), FI_DIRTY_INODE))
++              return 0;
++
+       if (wbc)
+               f2fs_balance_fs(sbi);
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 4fdcdff..ba56549 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -112,6 +112,17 @@ static int f2fs_drop_inode(struct inode *inode)
+       return generic_drop_inode(inode);
+ }
++/*
++ * f2fs_dirty_inode() is called from __mark_inode_dirty()
++ *
++ * We should call set_dirty_inode to write the dirty inode through write_inode.
++ */
++static void f2fs_dirty_inode(struct inode *inode, int flags)
++{
++      set_inode_flag(F2FS_I(inode), FI_DIRTY_INODE);
++      return;
++}
++
+ static void f2fs_i_callback(struct rcu_head *head)
+ {
+       struct inode *inode = container_of(head, struct inode, i_rcu);
+@@ -249,6 +260,7 @@ static struct super_operations f2fs_sops = {
+       .drop_inode     = f2fs_drop_inode,
+       .destroy_inode  = f2fs_destroy_inode,
+       .write_inode    = f2fs_write_inode,
++      .dirty_inode    = f2fs_dirty_inode,
+       .show_options   = f2fs_show_options,
+       .evict_inode    = f2fs_evict_inode,
+       .put_super      = f2fs_put_super,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0494-f2fs-remove-unnecessary-parameter-offset-from-__add_.patch b/patches.tizen/0494-f2fs-remove-unnecessary-parameter-offset-from-__add_.patch
new file mode 100644 (file)
index 0000000..0ab759c
--- /dev/null
@@ -0,0 +1,63 @@
+From 3f264acb2e6e95d39a45b6e2ee08c4e56c543b68 Mon Sep 17 00:00:00 2001
+From: Haicheng Li <haicheng.li@linux.intel.com>
+Date: Thu, 13 Jun 2013 16:59:27 +0800
+Subject: [PATCH 0494/1302] f2fs: remove unnecessary parameter "offset" from
+ __add_sum_entry()
+
+We can get the value directly from pointer "curseg".
+
+Signed-off-by: Haicheng Li <haicheng.li@linux.intel.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/segment.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index be668ff..77f31c0 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -255,11 +255,11 @@ void invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr)
+  * This function should be resided under the curseg_mutex lock
+  */
+ static void __add_sum_entry(struct f2fs_sb_info *sbi, int type,
+-              struct f2fs_summary *sum, unsigned short offset)
++                                      struct f2fs_summary *sum)
+ {
+       struct curseg_info *curseg = CURSEG_I(sbi, type);
+       void *addr = curseg->sum_blk;
+-      addr += offset * sizeof(struct f2fs_summary);
++      addr += curseg->next_blkoff * sizeof(struct f2fs_summary);
+       memcpy(addr, sum, sizeof(struct f2fs_summary));
+       return;
+ }
+@@ -845,7 +845,7 @@ static void do_write_page(struct f2fs_sb_info *sbi, struct page *page,
+        * because, this function updates a summary entry in the
+        * current summary block.
+        */
+-      __add_sum_entry(sbi, type, sum, curseg->next_blkoff);
++      __add_sum_entry(sbi, type, sum);
+       mutex_lock(&sit_i->sentry_lock);
+       __refresh_next_blkoff(sbi, curseg);
+@@ -946,7 +946,7 @@ void recover_data_page(struct f2fs_sb_info *sbi,
+       curseg->next_blkoff = GET_SEGOFF_FROM_SEG0(sbi, new_blkaddr) &
+                                       (sbi->blocks_per_seg - 1);
+-      __add_sum_entry(sbi, type, sum, curseg->next_blkoff);
++      __add_sum_entry(sbi, type, sum);
+       refresh_sit_entry(sbi, old_blkaddr, new_blkaddr);
+@@ -983,7 +983,7 @@ void rewrite_node_page(struct f2fs_sb_info *sbi,
+       }
+       curseg->next_blkoff = GET_SEGOFF_FROM_SEG0(sbi, new_blkaddr) &
+                                       (sbi->blocks_per_seg - 1);
+-      __add_sum_entry(sbi, type, sum, curseg->next_blkoff);
++      __add_sum_entry(sbi, type, sum);
+       /* change the current log to the next block addr in advance */
+       if (next_segno != segno) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0495-f2fs-make-locate_dirty_segment-as-static.patch b/patches.tizen/0495-f2fs-make-locate_dirty_segment-as-static.patch
new file mode 100644 (file)
index 0000000..a954919
--- /dev/null
@@ -0,0 +1,43 @@
+From 3731947b62373829a4960c0584a44b33a066f366 Mon Sep 17 00:00:00 2001
+From: Haicheng Li <haicheng.li@linux.intel.com>
+Date: Thu, 13 Jun 2013 16:59:28 +0800
+Subject: [PATCH 0495/1302] f2fs: make locate_dirty_segment() as static
+
+It's used only locally and could be static.
+
+Signed-off-by: Haicheng Li <haicheng.li@linux.intel.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/f2fs.h    | 1 -
+ fs/f2fs/segment.c | 2 +-
+ 2 files changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index a05aa65..3e7cb33 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -996,7 +996,6 @@ void destroy_node_manager_caches(void);
+  */
+ void f2fs_balance_fs(struct f2fs_sb_info *);
+ void invalidate_blocks(struct f2fs_sb_info *, block_t);
+-void locate_dirty_segment(struct f2fs_sb_info *, unsigned int);
+ void clear_prefree_segments(struct f2fs_sb_info *);
+ int npages_for_summary_flush(struct f2fs_sb_info *);
+ void allocate_new_segments(struct f2fs_sb_info *);
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index 77f31c0..b15debc 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -94,7 +94,7 @@ static void __remove_dirty_segment(struct f2fs_sb_info *sbi, unsigned int segno,
+  * Adding dirty entry into seglist is not critical operation.
+  * If a given segment is one of current working segments, it won't be added.
+  */
+-void locate_dirty_segment(struct f2fs_sb_info *sbi, unsigned int segno)
++static void locate_dirty_segment(struct f2fs_sb_info *sbi, unsigned int segno)
+ {
+       struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
+       unsigned short valid_blocks;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0496-f2fs-optimize-do_write_data_page.patch b/patches.tizen/0496-f2fs-optimize-do_write_data_page.patch
new file mode 100644 (file)
index 0000000..1a534d2
--- /dev/null
@@ -0,0 +1,34 @@
+From 5542ff2f81d7e05908e1a87f9e5ee9b6e0698b27 Mon Sep 17 00:00:00 2001
+From: Haicheng Li <haicheng.li@linux.intel.com>
+Date: Thu, 13 Jun 2013 16:59:29 +0800
+Subject: [PATCH 0496/1302] f2fs: optimize do_write_data_page()
+
+Since "need_inplace_update() == true" is a very rare case, using unlikely()
+to give compiler a chance to optimize the code.
+
+Signed-off-by: Haicheng Li <haicheng.li@linux.intel.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/data.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 5b145fc..6d4a743 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -497,8 +497,9 @@ int do_write_data_page(struct page *page)
+        * If current allocation needs SSR,
+        * it had better in-place writes for updated data.
+        */
+-      if (old_blk_addr != NEW_ADDR && !is_cold_data(page) &&
+-                              need_inplace_update(inode)) {
++      if (unlikely(old_blk_addr != NEW_ADDR &&
++                      !is_cold_data(page) &&
++                      need_inplace_update(inode))) {
+               rewrite_data_page(F2FS_SB(inode->i_sb), page,
+                                               old_blk_addr);
+       } else {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0497-f2fs-recover-wrong-pino-after-checkpoint-during-fsyn.patch b/patches.tizen/0497-f2fs-recover-wrong-pino-after-checkpoint-during-fsyn.patch
new file mode 100644 (file)
index 0000000..8b74e45
--- /dev/null
@@ -0,0 +1,162 @@
+From fff2d2220bbf0c26a9fba81efcf57bc967c58207 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Fri, 14 Jun 2013 08:52:35 +0900
+Subject: [PATCH 0497/1302] f2fs: recover wrong pino after checkpoint during
+ fsync
+
+If a file is linked, f2fs loose its parent inode number so that fsync calls
+for the linked file should do checkpoint all the time.
+But, if we can recover its parent inode number after the checkpoint, we can
+adjust roll-forward mechanism for the further fsync calls, which is able to
+improve the fsync performance significatly.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/dir.c     |  2 +-
+ fs/f2fs/f2fs.h    |  2 +-
+ fs/f2fs/file.c    | 31 ++++++++++++++++++++++++++++++-
+ fs/f2fs/namei.c   |  2 +-
+ fs/f2fs/node.h    | 15 +++++++++++----
+ fs/f2fs/segment.c |  2 +-
+ 6 files changed, 45 insertions(+), 9 deletions(-)
+
+diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
+index 69ca049..4f21452 100644
+--- a/fs/f2fs/dir.c
++++ b/fs/f2fs/dir.c
+@@ -356,7 +356,7 @@ static struct page *init_inode_metadata(struct inode *inode,
+        * We lost i_pino from now on.
+        */
+       if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK)) {
+-              set_cp_file(inode);
++              file_lost_pino(inode);
+               inc_nlink(inode);
+       }
+       return page;
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 3e7cb33..863a5e91 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -151,7 +151,7 @@ struct extent_info {
+  * i_advise uses FADVISE_XXX_BIT. We can add additional hints later.
+  */
+ #define FADVISE_COLD_BIT      0x01
+-#define FADVISE_CP_BIT                0x02
++#define FADVISE_LOST_PINO_BIT 0x02
+ struct f2fs_inode_info {
+       struct inode vfs_inode;         /* serve a vfs inode */
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index fda226f..d2d2b7d 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -102,6 +102,24 @@ static const struct vm_operations_struct f2fs_file_vm_ops = {
+       .remap_pages    = generic_file_remap_pages,
+ };
++static int get_parent_ino(struct inode *inode, nid_t *pino)
++{
++      struct dentry *dentry;
++
++      inode = igrab(inode);
++      dentry = d_find_any_alias(inode);
++      iput(inode);
++      if (!dentry)
++              return 0;
++
++      inode = igrab(dentry->d_parent->d_inode);
++      dput(dentry);
++
++      *pino = inode->i_ino;
++      iput(inode);
++      return 1;
++}
++
+ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
+ {
+       struct inode *inode = file->f_mapping->host;
+@@ -134,7 +152,7 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
+       if (!S_ISREG(inode->i_mode) || inode->i_nlink != 1)
+               need_cp = true;
+-      else if (is_cp_file(inode))
++      else if (file_wrong_pino(inode))
+               need_cp = true;
+       else if (!space_for_roll_forward(sbi))
+               need_cp = true;
+@@ -142,8 +160,19 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
+               need_cp = true;
+       if (need_cp) {
++              nid_t pino;
++
+               /* all the dirty node pages should be flushed for POR */
+               ret = f2fs_sync_fs(inode->i_sb, 1);
++              if (file_wrong_pino(inode) && inode->i_nlink == 1 &&
++                                      get_parent_ino(inode, &pino)) {
++                      F2FS_I(inode)->i_pino = pino;
++                      file_got_pino(inode);
++                      mark_inode_dirty_sync(inode);
++                      ret = f2fs_write_inode(inode, NULL);
++                      if (ret)
++                              goto out;
++              }
+       } else {
+               /* if there is no written node page, write its inode page */
+               while (!sync_node_pages(sbi, inode->i_ino, &wbc)) {
+diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
+index 810444e..64c0716 100644
+--- a/fs/f2fs/namei.c
++++ b/fs/f2fs/namei.c
+@@ -112,7 +112,7 @@ static inline void set_cold_files(struct f2fs_sb_info *sbi, struct inode *inode,
+       int count = le32_to_cpu(sbi->raw_super->extension_count);
+       for (i = 0; i < count; i++) {
+               if (is_multimedia_file(name, extlist[i])) {
+-                      set_cold_file(inode);
++                      file_set_cold(inode);
+                       break;
+               }
+       }
+diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h
+index a503661..c65fb4f 100644
+--- a/fs/f2fs/node.h
++++ b/fs/f2fs/node.h
+@@ -285,10 +285,17 @@ static inline void set_file(struct inode *inode, int type)
+       F2FS_I(inode)->i_advise |= type;
+ }
+-#define is_cold_file(inode)   is_file(inode, FADVISE_COLD_BIT)
+-#define is_cp_file(inode)     is_file(inode, FADVISE_CP_BIT)
+-#define set_cold_file(inode)  set_file(inode, FADVISE_COLD_BIT)
+-#define set_cp_file(inode)    set_file(inode, FADVISE_CP_BIT)
++static inline void clear_file(struct inode *inode, int type)
++{
++      F2FS_I(inode)->i_advise &= ~type;
++}
++
++#define file_is_cold(inode)   is_file(inode, FADVISE_COLD_BIT)
++#define file_wrong_pino(inode)        is_file(inode, FADVISE_LOST_PINO_BIT)
++#define file_set_cold(inode)  set_file(inode, FADVISE_COLD_BIT)
++#define file_lost_pino(inode) set_file(inode, FADVISE_LOST_PINO_BIT)
++#define file_clear_cold(inode)        clear_file(inode, FADVISE_COLD_BIT)
++#define file_got_pino(inode)  clear_file(inode, FADVISE_LOST_PINO_BIT)
+ static inline int is_cold_data(struct page *page)
+ {
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index b15debc..0e1a60a 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -796,7 +796,7 @@ static int __get_segment_type_6(struct page *page, enum page_type p_type)
+               if (S_ISDIR(inode->i_mode))
+                       return CURSEG_HOT_DATA;
+-              else if (is_cold_data(page) || is_cold_file(inode))
++              else if (is_cold_data(page) || file_is_cold(inode))
+                       return CURSEG_COLD_DATA;
+               else
+                       return CURSEG_WARM_DATA;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0498-f2fs-add-remount_fs-callback-support.patch b/patches.tizen/0498-f2fs-add-remount_fs-callback-support.patch
new file mode 100644 (file)
index 0000000..d432c67
--- /dev/null
@@ -0,0 +1,361 @@
+From 396cc9e0651840e51ece7dcbc26fb7fc8fe3d47b Mon Sep 17 00:00:00 2001
+From: Namjae Jeon <namjae.jeon@samsung.com>
+Date: Sun, 16 Jun 2013 09:48:48 +0900
+Subject: [PATCH 0498/1302] f2fs: add remount_fs callback support
+
+Add the f2fs_remount function call which will be used
+during the filesystem remounting. This function
+will help us to change the mount options specific to
+f2fs.
+
+Also modify the f2fs background_gc mount option, which
+will allow the user to dynamically trun on/off the
+garbage collection in f2fs based on the background_gc
+value. If background_gc=on, Garbage collection will
+be turned off & if background_gc=off, Garbage collection
+will be truned on.
+
+By default the garbage collection is on in f2fs.
+
+Change Log:
+v2: Incorporated the review comments by Gu Zheng.
+    Removing the restore part for VFS flags
+    Updating comments with proper flag conditions
+    Display GC background option as ON/OFF
+    Revised conditions to stop GC in case of remount
+
+v1: Initial changes for adding remount_fs callback
+support.
+
+Cc: Gu Zheng <guz.fnst@cn.fujitsu.com>
+Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
+Signed-off-by: Pankaj Kumar <pankaj.km@samsung.com>
+Reviewed-by: Gu Zheng <guz.fnst@cn.fujitsu.com>
+[Jaegeuk Kim: change /** with /* for the coding style]
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/filesystems/f2fs.txt |   9 +-
+ fs/f2fs/super.c                    | 235 ++++++++++++++++++++++++-------------
+ 2 files changed, 160 insertions(+), 84 deletions(-)
+
+diff --git a/Documentation/filesystems/f2fs.txt b/Documentation/filesystems/f2fs.txt
+index bd3c56c..b91e2f2 100644
+--- a/Documentation/filesystems/f2fs.txt
++++ b/Documentation/filesystems/f2fs.txt
+@@ -98,8 +98,13 @@ Cleaning Overhead
+ MOUNT OPTIONS
+ ================================================================================
+-background_gc_off      Turn off cleaning operations, namely garbage collection,
+-                     triggered in background when I/O subsystem is idle.
++background_gc=%s       Turn on/off cleaning operations, namely garbage
++                       collection, triggered in background when I/O subsystem is
++                       idle. If background_gc=on, it will turn on the garbage
++                       collection and if background_gc=off, garbage collection
++                       will be truned off.
++                       Default value for this option is on. So garbage
++                       collection is on by default.
+ disable_roll_forward   Disable the roll-forward recovery routine
+ discard                Issue discard/TRIM commands when a segment is cleaned.
+ no_heap                Disable heap-style segment allocation which finds free
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index ba56549..75c7dc3 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -34,7 +34,7 @@
+ static struct kmem_cache *f2fs_inode_cachep;
+ enum {
+-      Opt_gc_background_off,
++      Opt_gc_background,
+       Opt_disable_roll_forward,
+       Opt_discard,
+       Opt_noheap,
+@@ -46,7 +46,7 @@ enum {
+ };
+ static match_table_t f2fs_tokens = {
+-      {Opt_gc_background_off, "background_gc_off"},
++      {Opt_gc_background, "background_gc=%s"},
+       {Opt_disable_roll_forward, "disable_roll_forward"},
+       {Opt_discard, "discard"},
+       {Opt_noheap, "no_heap"},
+@@ -76,6 +76,91 @@ static void init_once(void *foo)
+       inode_init_once(&fi->vfs_inode);
+ }
++static int parse_options(struct super_block *sb, char *options)
++{
++      struct f2fs_sb_info *sbi = F2FS_SB(sb);
++      substring_t args[MAX_OPT_ARGS];
++      char *p, *name;
++      int arg = 0;
++
++      if (!options)
++              return 0;
++
++      while ((p = strsep(&options, ",")) != NULL) {
++              int token;
++              if (!*p)
++                      continue;
++              /*
++               * Initialize args struct so we know whether arg was
++               * found; some options take optional arguments.
++               */
++              args[0].to = args[0].from = NULL;
++              token = match_token(p, f2fs_tokens, args);
++
++              switch (token) {
++              case Opt_gc_background:
++                      name = match_strdup(&args[0]);
++
++                      if (!name)
++                              return -ENOMEM;
++                      if (!strncmp(name, "on", 2))
++                              set_opt(sbi, BG_GC);
++                      else if (!strncmp(name, "off", 3))
++                              clear_opt(sbi, BG_GC);
++                      else {
++                              kfree(name);
++                              return -EINVAL;
++                      }
++                      kfree(name);
++                      break;
++              case Opt_disable_roll_forward:
++                      set_opt(sbi, DISABLE_ROLL_FORWARD);
++                      break;
++              case Opt_discard:
++                      set_opt(sbi, DISCARD);
++                      break;
++              case Opt_noheap:
++                      set_opt(sbi, NOHEAP);
++                      break;
++#ifdef CONFIG_F2FS_FS_XATTR
++              case Opt_nouser_xattr:
++                      clear_opt(sbi, XATTR_USER);
++                      break;
++#else
++              case Opt_nouser_xattr:
++                      f2fs_msg(sb, KERN_INFO,
++                              "nouser_xattr options not supported");
++                      break;
++#endif
++#ifdef CONFIG_F2FS_FS_POSIX_ACL
++              case Opt_noacl:
++                      clear_opt(sbi, POSIX_ACL);
++                      break;
++#else
++              case Opt_noacl:
++                      f2fs_msg(sb, KERN_INFO, "noacl options not supported");
++                      break;
++#endif
++              case Opt_active_logs:
++                      if (args->from && match_int(args, &arg))
++                              return -EINVAL;
++                      if (arg != 2 && arg != 4 && arg != NR_CURSEG_TYPE)
++                              return -EINVAL;
++                      sbi->active_logs = arg;
++                      break;
++              case Opt_disable_ext_identify:
++                      set_opt(sbi, DISABLE_EXT_IDENTIFY);
++                      break;
++              default:
++                      f2fs_msg(sb, KERN_ERR,
++                              "Unrecognized mount option \"%s\" or missing value",
++                              p);
++                      return -EINVAL;
++              }
++      }
++      return 0;
++}
++
+ static struct inode *f2fs_alloc_inode(struct super_block *sb)
+ {
+       struct f2fs_inode_info *fi;
+@@ -225,10 +310,10 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
+ {
+       struct f2fs_sb_info *sbi = F2FS_SB(root->d_sb);
+-      if (test_opt(sbi, BG_GC))
+-              seq_puts(seq, ",background_gc_on");
++      if (!(root->d_sb->s_flags & MS_RDONLY) && test_opt(sbi, BG_GC))
++              seq_printf(seq, ",background_gc=%s", "on");
+       else
+-              seq_puts(seq, ",background_gc_off");
++              seq_printf(seq, ",background_gc=%s", "off");
+       if (test_opt(sbi, DISABLE_ROLL_FORWARD))
+               seq_puts(seq, ",disable_roll_forward");
+       if (test_opt(sbi, DISCARD))
+@@ -255,6 +340,58 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
+       return 0;
+ }
++static int f2fs_remount(struct super_block *sb, int *flags, char *data)
++{
++      struct f2fs_sb_info *sbi = F2FS_SB(sb);
++      struct f2fs_mount_info org_mount_opt;
++      int err, active_logs;
++
++      /*
++       * Save the old mount options in case we
++       * need to restore them.
++       */
++      org_mount_opt = sbi->mount_opt;
++      active_logs = sbi->active_logs;
++
++      /* parse mount options */
++      err = parse_options(sb, data);
++      if (err)
++              goto restore_opts;
++
++      /*
++       * Previous and new state of filesystem is RO,
++       * so no point in checking GC conditions.
++       */
++      if ((sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY))
++              goto skip;
++
++      /*
++       * We stop the GC thread if FS is mounted as RO
++       * or if background_gc = off is passed in mount
++       * option. Also sync the filesystem.
++       */
++      if ((*flags & MS_RDONLY) || !test_opt(sbi, BG_GC)) {
++              if (sbi->gc_thread) {
++                      stop_gc_thread(sbi);
++                      f2fs_sync_fs(sb, 1);
++              }
++      } else if (test_opt(sbi, BG_GC) && !sbi->gc_thread) {
++              err = start_gc_thread(sbi);
++              if (err)
++                      goto restore_opts;
++      }
++skip:
++      /* Update the POSIXACL Flag */
++       sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
++              (test_opt(sbi, POSIX_ACL) ? MS_POSIXACL : 0);
++      return 0;
++
++restore_opts:
++      sbi->mount_opt = org_mount_opt;
++      sbi->active_logs = active_logs;
++      return err;
++}
++
+ static struct super_operations f2fs_sops = {
+       .alloc_inode    = f2fs_alloc_inode,
+       .drop_inode     = f2fs_drop_inode,
+@@ -268,6 +405,7 @@ static struct super_operations f2fs_sops = {
+       .freeze_fs      = f2fs_freeze,
+       .unfreeze_fs    = f2fs_unfreeze,
+       .statfs         = f2fs_statfs,
++      .remount_fs     = f2fs_remount,
+ };
+ static struct inode *f2fs_nfs_get_inode(struct super_block *sb,
+@@ -315,79 +453,6 @@ static const struct export_operations f2fs_export_ops = {
+       .get_parent = f2fs_get_parent,
+ };
+-static int parse_options(struct super_block *sb, char *options)
+-{
+-      struct f2fs_sb_info *sbi = F2FS_SB(sb);
+-      substring_t args[MAX_OPT_ARGS];
+-      char *p;
+-      int arg = 0;
+-
+-      if (!options)
+-              return 0;
+-
+-      while ((p = strsep(&options, ",")) != NULL) {
+-              int token;
+-              if (!*p)
+-                      continue;
+-              /*
+-               * Initialize args struct so we know whether arg was
+-               * found; some options take optional arguments.
+-               */
+-              args[0].to = args[0].from = NULL;
+-              token = match_token(p, f2fs_tokens, args);
+-
+-              switch (token) {
+-              case Opt_gc_background_off:
+-                      clear_opt(sbi, BG_GC);
+-                      break;
+-              case Opt_disable_roll_forward:
+-                      set_opt(sbi, DISABLE_ROLL_FORWARD);
+-                      break;
+-              case Opt_discard:
+-                      set_opt(sbi, DISCARD);
+-                      break;
+-              case Opt_noheap:
+-                      set_opt(sbi, NOHEAP);
+-                      break;
+-#ifdef CONFIG_F2FS_FS_XATTR
+-              case Opt_nouser_xattr:
+-                      clear_opt(sbi, XATTR_USER);
+-                      break;
+-#else
+-              case Opt_nouser_xattr:
+-                      f2fs_msg(sb, KERN_INFO,
+-                              "nouser_xattr options not supported");
+-                      break;
+-#endif
+-#ifdef CONFIG_F2FS_FS_POSIX_ACL
+-              case Opt_noacl:
+-                      clear_opt(sbi, POSIX_ACL);
+-                      break;
+-#else
+-              case Opt_noacl:
+-                      f2fs_msg(sb, KERN_INFO, "noacl options not supported");
+-                      break;
+-#endif
+-              case Opt_active_logs:
+-                      if (args->from && match_int(args, &arg))
+-                              return -EINVAL;
+-                      if (arg != 2 && arg != 4 && arg != NR_CURSEG_TYPE)
+-                              return -EINVAL;
+-                      sbi->active_logs = arg;
+-                      break;
+-              case Opt_disable_ext_identify:
+-                      set_opt(sbi, DISABLE_EXT_IDENTIFY);
+-                      break;
+-              default:
+-                      f2fs_msg(sb, KERN_ERR,
+-                              "Unrecognized mount option \"%s\" or missing value",
+-                              p);
+-                      return -EINVAL;
+-              }
+-      }
+-      return 0;
+-}
+-
+ static loff_t max_file_size(unsigned bits)
+ {
+       loff_t result = ADDRS_PER_INODE;
+@@ -686,10 +751,16 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
+                               "Cannot recover all fsync data errno=%ld", err);
+       }
+-      /* After POR, we can run background GC thread */
+-      err = start_gc_thread(sbi);
+-      if (err)
+-              goto fail;
++      /*
++       * If filesystem is not mounted as read-only then
++       * do start the gc_thread.
++       */
++      if (!(sb->s_flags & MS_RDONLY)) {
++              /* After POR, we can run background GC thread.*/
++              err = start_gc_thread(sbi);
++              if (err)
++                      goto fail;
++      }
+       err = f2fs_build_stats(sbi);
+       if (err)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0499-f2fs-fix-crc-endian-conversion.patch b/patches.tizen/0499-f2fs-fix-crc-endian-conversion.patch
new file mode 100644 (file)
index 0000000..ffaffb0
--- /dev/null
@@ -0,0 +1,107 @@
+From 9fbeed233d8d58add454d60527a2e9e7d675b986 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Wed, 19 Jun 2013 20:47:19 +0900
+Subject: [PATCH 0499/1302] f2fs: fix crc endian conversion
+
+While calculating CRC for the checkpoint block, we use __u32, but when storing
+the crc value to the disk, we use __le32.
+
+Let's fix the inconsistency.
+
+Reported-and-Tested-by: Oded Gabbay <ogabbay@advaoptical.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/checkpoint.c | 12 ++++++------
+ fs/f2fs/f2fs.h       | 19 +++++++++++++++----
+ 2 files changed, 21 insertions(+), 10 deletions(-)
+
+diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
+index 9a77509..66a6b85 100644
+--- a/fs/f2fs/checkpoint.c
++++ b/fs/f2fs/checkpoint.c
+@@ -357,8 +357,8 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi,
+       unsigned long blk_size = sbi->blocksize;
+       struct f2fs_checkpoint *cp_block;
+       unsigned long long cur_version = 0, pre_version = 0;
+-      unsigned int crc = 0;
+       size_t crc_offset;
++      __u32 crc = 0;
+       /* Read the 1st cp block in this CP pack */
+       cp_page_1 = get_meta_page(sbi, cp_addr);
+@@ -369,7 +369,7 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi,
+       if (crc_offset >= blk_size)
+               goto invalid_cp1;
+-      crc = *(unsigned int *)((unsigned char *)cp_block + crc_offset);
++      crc = le32_to_cpu(*((__u32 *)((unsigned char *)cp_block + crc_offset)));
+       if (!f2fs_crc_valid(crc, cp_block, crc_offset))
+               goto invalid_cp1;
+@@ -384,7 +384,7 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi,
+       if (crc_offset >= blk_size)
+               goto invalid_cp2;
+-      crc = *(unsigned int *)((unsigned char *)cp_block + crc_offset);
++      crc = le32_to_cpu(*((__u32 *)((unsigned char *)cp_block + crc_offset)));
+       if (!f2fs_crc_valid(crc, cp_block, crc_offset))
+               goto invalid_cp2;
+@@ -648,7 +648,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
+       block_t start_blk;
+       struct page *cp_page;
+       unsigned int data_sum_blocks, orphan_blocks;
+-      unsigned int crc32 = 0;
++      __u32 crc32 = 0;
+       void *kaddr;
+       int i;
+@@ -717,8 +717,8 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
+       get_nat_bitmap(sbi, __bitmap_ptr(sbi, NAT_BITMAP));
+       crc32 = f2fs_crc32(ckpt, le32_to_cpu(ckpt->checksum_offset));
+-      *(__le32 *)((unsigned char *)ckpt +
+-                              le32_to_cpu(ckpt->checksum_offset))
++      *((__le32 *)((unsigned char *)ckpt +
++                              le32_to_cpu(ckpt->checksum_offset)))
+                               = cpu_to_le32(crc32);
+       start_blk = __start_cp_addr(sbi);
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 863a5e91..467d42d 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -47,14 +47,25 @@ struct f2fs_mount_info {
+       unsigned int    opt;
+ };
+-static inline __u32 f2fs_crc32(void *buff, size_t len)
++#define CRCPOLY_LE 0xedb88320
++
++static inline __u32 f2fs_crc32(void *buf, size_t len)
+ {
+-      return crc32_le(F2FS_SUPER_MAGIC, buff, len);
++      unsigned char *p = (unsigned char *)buf;
++      __u32 crc = F2FS_SUPER_MAGIC;
++      int i;
++
++      while (len--) {
++              crc ^= *p++;
++              for (i = 0; i < 8; i++)
++                      crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
++      }
++      return crc;
+ }
+-static inline bool f2fs_crc_valid(__u32 blk_crc, void *buff, size_t buff_size)
++static inline bool f2fs_crc_valid(__u32 blk_crc, void *buf, size_t buf_size)
+ {
+-      return f2fs_crc32(buff, buff_size) == blk_crc;
++      return f2fs_crc32(buf, buf_size) == blk_crc;
+ }
+ /*
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0500-f2fs-fix-an-endian-conversion-bug-detected-by-sparse.patch b/patches.tizen/0500-f2fs-fix-an-endian-conversion-bug-detected-by-sparse.patch
new file mode 100644 (file)
index 0000000..74c4d8e
--- /dev/null
@@ -0,0 +1,48 @@
+From c12dc39ae3e9926b3b803e7c0a0fc6a7e36ff931 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Mon, 24 Jun 2013 07:47:23 +0900
+Subject: [PATCH 0500/1302] f2fs: fix an endian conversion bug detected by
+ sparse
+
+This patch should fix the following bug reported by kbuild test robot.
+
+fs/f2fs/recovery.c:233:33: sparse: incorrect type in assignment
+(different base types)
+
+parse warnings: (new ones prefixed by >>)
+
+>> recovery.c:233: sparse: incorrect type in assignment (different base types)
+   recovery.c:233:    expected unsigned int [unsigned] [assigned] ofs_in_node
+   recovery.c:233:    got restricted __le16 [assigned] [usertype] ofs_in_node
+>> recovery.c:238: sparse: incorrect type in assignment (different base types)
+   recovery.c:238:    expected unsigned int [unsigned] ofs_in_node
+   recovery.c:238:    got restricted __le16 [assigned] [usertype] ofs_in_node
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/recovery.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
+index ddde14f..9db8239 100644
+--- a/fs/f2fs/recovery.c
++++ b/fs/f2fs/recovery.c
+@@ -246,12 +246,12 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
+               struct dnode_of_data tdn = *dn;
+               tdn.nid = nid;
+               tdn.node_page = dn->inode_page;
+-              tdn.ofs_in_node = sum.ofs_in_node;
++              tdn.ofs_in_node = le16_to_cpu(sum.ofs_in_node);
+               truncate_data_blocks_range(&tdn, 1);
+               return 0;
+       } else if (dn->nid == nid) {
+               struct dnode_of_data tdn = *dn;
+-              tdn.ofs_in_node = sum.ofs_in_node;
++              tdn.ofs_in_node = le16_to_cpu(sum.ofs_in_node);
+               truncate_data_blocks_range(&tdn, 1);
+               return 0;
+       }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0501-f2fs-optimize-the-init_dirty_segmap-function.patch b/patches.tizen/0501-f2fs-optimize-the-init_dirty_segmap-function.patch
new file mode 100644 (file)
index 0000000..1aa5103
--- /dev/null
@@ -0,0 +1,51 @@
+From 7c940b24209d5f3382e1b28c44df6dbedf78ef07 Mon Sep 17 00:00:00 2001
+From: Namjae Jeon <namjae.jeon@samsung.com>
+Date: Sun, 16 Jun 2013 09:49:11 +0900
+Subject: [PATCH 0501/1302] f2fs: optimize the init_dirty_segmap function
+
+Optimize the while loop condition
+
+Since this condition will always be true and while loop will
+be terminated by the following condition in code:
+
+if (segno >= TOTAL_SEGS(sbi))
+    break;
+Hence we can replace the while loop condition with while(1)
+instead of always checking for segno to be less than Total segs.
+
+Also we do not need to use TOTAL_SEGS() everytime. We can store
+this value in a local variable since this value is constant.
+
+Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
+Signed-off-by: Pankaj Kumar <pankaj.km@samsung.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/segment.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index 0e1a60a..3ac4d29 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -1582,13 +1582,13 @@ static void init_dirty_segmap(struct f2fs_sb_info *sbi)
+ {
+       struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
+       struct free_segmap_info *free_i = FREE_I(sbi);
+-      unsigned int segno = 0, offset = 0;
++      unsigned int segno = 0, offset = 0, total_segs = TOTAL_SEGS(sbi);
+       unsigned short valid_blocks;
+-      while (segno < TOTAL_SEGS(sbi)) {
++      while (1) {
+               /* find dirty segment based on free segmap */
+-              segno = find_next_inuse(free_i, TOTAL_SEGS(sbi), offset);
+-              if (segno >= TOTAL_SEGS(sbi))
++              segno = find_next_inuse(free_i, total_segs, offset);
++              if (segno >= total_segs)
+                       break;
+               offset = segno + 1;
+               valid_blocks = get_valid_blocks(sbi, segno, 0);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0502-f2fs-code-cleanup-and-simplify-in-func-find-add-_gc_.patch b/patches.tizen/0502-f2fs-code-cleanup-and-simplify-in-func-find-add-_gc_.patch
new file mode 100644 (file)
index 0000000..214a149
--- /dev/null
@@ -0,0 +1,59 @@
+From 704ef6be4a6ba81f79448f95b0143f6cf96623cd Mon Sep 17 00:00:00 2001
+From: Gu Zheng <guz.fnst@cn.fujitsu.com>
+Date: Thu, 20 Jun 2013 17:52:39 +0800
+Subject: [PATCH 0502/1302] f2fs: code cleanup and simplify in func
+ {find/add}_gc_inode
+
+This patch simplifies list operations in find_gc_inode and add_gc_inode.
+Just simple code cleanup.
+
+Signed-off-by: Gu Zheng <guz.fnst@cn.fujitsu.com>
+[Jaegeuk Kim: add description]
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/gc.c | 17 +++++------------
+ 1 file changed, 5 insertions(+), 12 deletions(-)
+
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index 3a9df36..35f9b1a 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -321,28 +321,21 @@ static const struct victim_selection default_v_ops = {
+ static struct inode *find_gc_inode(nid_t ino, struct list_head *ilist)
+ {
+-      struct list_head *this;
+       struct inode_entry *ie;
+-      list_for_each(this, ilist) {
+-              ie = list_entry(this, struct inode_entry, list);
++      list_for_each_entry(ie, ilist, list)
+               if (ie->inode->i_ino == ino)
+                       return ie->inode;
+-      }
+       return NULL;
+ }
+ static void add_gc_inode(struct inode *inode, struct list_head *ilist)
+ {
+-      struct list_head *this;
+-      struct inode_entry *new_ie, *ie;
++      struct inode_entry *new_ie;
+-      list_for_each(this, ilist) {
+-              ie = list_entry(this, struct inode_entry, list);
+-              if (ie->inode == inode) {
+-                      iput(inode);
+-                      return;
+-              }
++      if (inode == find_gc_inode(inode->i_ino, ilist)) {
++              iput(inode);
++              return;
+       }
+ repeat:
+       new_ie = kmem_cache_alloc(winode_slab, GFP_NOFS);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0503-f2fs-remove-reusing-any-prefree-segments.patch b/patches.tizen/0503-f2fs-remove-reusing-any-prefree-segments.patch
new file mode 100644 (file)
index 0000000..0882943
--- /dev/null
@@ -0,0 +1,125 @@
+From a2b68b087a3b1a5d861f1b7d1d3deebd063341c1 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Thu, 27 Jun 2013 09:59:40 +0900
+Subject: [PATCH 0503/1302] f2fs: remove reusing any prefree segments
+
+This patch removes check_prefree_segments initially designed to enhance the
+performance by narrowing the range of LBA usage across the whole block device.
+
+When allocating a new segment, previous f2fs tries to find proper prefree
+segments, and then, if finds a segment, it reuses the segment for further
+data or node block allocation.
+
+However, I found that this was totally wrong approach since the prefree segments
+have several data or node blocks that will be used by the roll-forward mechanism
+operated after sudden-power-off.
+
+Let's assume the following scenario.
+
+/* write 8MB with fsync */
+for (i = 0; i < 2048; i++) {
+       offset = i * 4096;
+       write(fd, offset, 4KB);
+       fsync(fd);
+}
+
+In this case, naive segment allocation sequence will be like:
+ data segment: x, x+1, x+2, x+3
+ node segment: y, y+1, y+2, y+3.
+
+But, if we can reuse prefree segments, the sequence can be like:
+ data segment: x, x+1, y, y+1
+ node segment: y, y+1, y+2, y+3.
+Because, y, y+1, and y+2 became prefree segments one by one, and those are
+reused by data allocation.
+
+After conducting this workload, we should consider how to recover the latest
+inode with its data.
+If we reuse the prefree segments such as y or y+1, we lost the old node blocks
+so that f2fs even cannot start roll-forward recovery.
+
+Therefore, I suggest that we should remove reusing prefree segments.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/segment.c | 56 +------------------------------------------------------
+ 1 file changed, 1 insertion(+), 55 deletions(-)
+
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index 3ac4d29..a86d125 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -309,56 +309,6 @@ static void write_sum_page(struct f2fs_sb_info *sbi,
+       f2fs_put_page(page, 1);
+ }
+-static unsigned int check_prefree_segments(struct f2fs_sb_info *sbi, int type)
+-{
+-      struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
+-      unsigned long *prefree_segmap = dirty_i->dirty_segmap[PRE];
+-      unsigned int segno;
+-      unsigned int ofs = 0;
+-
+-      /*
+-       * If there is not enough reserved sections,
+-       * we should not reuse prefree segments.
+-       */
+-      if (has_not_enough_free_secs(sbi, 0))
+-              return NULL_SEGNO;
+-
+-      /*
+-       * NODE page should not reuse prefree segment,
+-       * since those information is used for SPOR.
+-       */
+-      if (IS_NODESEG(type))
+-              return NULL_SEGNO;
+-next:
+-      segno = find_next_bit(prefree_segmap, TOTAL_SEGS(sbi), ofs);
+-      ofs += sbi->segs_per_sec;
+-
+-      if (segno < TOTAL_SEGS(sbi)) {
+-              int i;
+-
+-              /* skip intermediate segments in a section */
+-              if (segno % sbi->segs_per_sec)
+-                      goto next;
+-
+-              /* skip if the section is currently used */
+-              if (sec_usage_check(sbi, GET_SECNO(sbi, segno)))
+-                      goto next;
+-
+-              /* skip if whole section is not prefree */
+-              for (i = 1; i < sbi->segs_per_sec; i++)
+-                      if (!test_bit(segno + i, prefree_segmap))
+-                              goto next;
+-
+-              /* skip if whole section was not free at the last checkpoint */
+-              for (i = 0; i < sbi->segs_per_sec; i++)
+-                      if (get_seg_entry(sbi, segno + i)->ckpt_valid_blocks)
+-                              goto next;
+-
+-              return segno;
+-      }
+-      return NULL_SEGNO;
+-}
+-
+ static int is_next_segment_free(struct f2fs_sb_info *sbi, int type)
+ {
+       struct curseg_info *curseg = CURSEG_I(sbi, type);
+@@ -597,11 +547,7 @@ static void allocate_segment_by_default(struct f2fs_sb_info *sbi,
+               goto out;
+       }
+-      curseg->next_segno = check_prefree_segments(sbi, type);
+-
+-      if (curseg->next_segno != NULL_SEGNO)
+-              change_curseg(sbi, type, false);
+-      else if (type == CURSEG_WARM_NODE)
++      if (type == CURSEG_WARM_NODE)
+               new_curseg(sbi, type, false);
+       else if (curseg->alloc_type == LFS && is_next_segment_free(sbi, type))
+               new_curseg(sbi, type, false);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0504-f2fs-remove-the-unused-argument-sbi-of-func-destroy_.patch b/patches.tizen/0504-f2fs-remove-the-unused-argument-sbi-of-func-destroy_.patch
new file mode 100644 (file)
index 0000000..34bde85
--- /dev/null
@@ -0,0 +1,42 @@
+From 7c5e53eb8ab07d0fd58cc7d1dc0cb5d768341bcf Mon Sep 17 00:00:00 2001
+From: Gu Zheng <guz.fnst@cn.fujitsu.com>
+Date: Thu, 27 Jun 2013 09:28:54 +0800
+Subject: [PATCH 0504/1302] f2fs: remove the unused argument "sbi" of func
+ destroy_fsync_dnodes()
+
+As destroy_fsync_dnodes() is a simple list-cleanup func, so delete the unused
+and unrelated f2fs_sb_info argument of it.
+
+Signed-off-by: Gu Zheng <guz.fnst@cn.fujitsu.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/recovery.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
+index 9db8239..d56d951 100644
+--- a/fs/f2fs/recovery.c
++++ b/fs/f2fs/recovery.c
+@@ -192,8 +192,7 @@ out:
+       return err;
+ }
+-static void destroy_fsync_dnodes(struct f2fs_sb_info *sbi,
+-                                      struct list_head *head)
++static void destroy_fsync_dnodes(struct list_head *head)
+ {
+       struct fsync_inode_entry *entry, *tmp;
+@@ -438,7 +437,7 @@ int recover_fsync_data(struct f2fs_sb_info *sbi)
+       err = recover_data(sbi, &inode_list, CURSEG_WARM_NODE);
+       BUG_ON(!list_empty(&inode_list));
+ out:
+-      destroy_fsync_dnodes(sbi, &inode_list);
++      destroy_fsync_dnodes(&inode_list);
+       kmem_cache_destroy(fsync_entry_slab);
+       sbi->por_doing = 0;
+       if (!err)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0505-f2fs-fix-to-recover-i_size-from-roll-forward.patch b/patches.tizen/0505-f2fs-fix-to-recover-i_size-from-roll-forward.patch
new file mode 100644 (file)
index 0000000..653e75b
--- /dev/null
@@ -0,0 +1,66 @@
+From 95343ae0fa57314b14d5386af6e561b63e942753 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Thu, 27 Jun 2013 13:04:08 +0900
+Subject: [PATCH 0505/1302] f2fs: fix to recover i_size from roll-forward
+
+If user requests many data writes and fsync together, the last updated i_size
+should be stored to the inode block consistently.
+
+But, previous write_end just marks the inode as dirty and doesn't update its
+metadata into its inode block.
+After that, fsync just writes the inode block with newly updated data index
+excluding inode metadata updates.
+
+So, this patch introduces write_end in which updates inode block too when the
+i_size is changed.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/data.c | 23 ++++++++++++++++++++++-
+ 1 file changed, 22 insertions(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 6d4a743..e88f46f 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -701,6 +701,27 @@ err:
+       return err;
+ }
++static int f2fs_write_end(struct file *file,
++                      struct address_space *mapping,
++                      loff_t pos, unsigned len, unsigned copied,
++                      struct page *page, void *fsdata)
++{
++      struct inode *inode = page->mapping->host;
++
++      SetPageUptodate(page);
++      set_page_dirty(page);
++
++      if (pos + copied > i_size_read(inode)) {
++              i_size_write(inode, pos + copied);
++              mark_inode_dirty(inode);
++              update_inode_page(inode);
++      }
++
++      unlock_page(page);
++      page_cache_release(page);
++      return copied;
++}
++
+ static ssize_t f2fs_direct_IO(int rw, struct kiocb *iocb,
+               const struct iovec *iov, loff_t offset, unsigned long nr_segs)
+ {
+@@ -757,7 +778,7 @@ const struct address_space_operations f2fs_dblock_aops = {
+       .writepage      = f2fs_write_data_page,
+       .writepages     = f2fs_write_data_pages,
+       .write_begin    = f2fs_write_begin,
+-      .write_end      = nobh_write_end,
++      .write_end      = f2fs_write_end,
+       .set_page_dirty = f2fs_set_data_page_dirty,
+       .invalidatepage = f2fs_invalidate_data_page,
+       .releasepage    = f2fs_release_data_page,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0506-ARM-dts-Add-dts-file-for-exynos4412-redwoodlte-board.patch b/patches.tizen/0506-ARM-dts-Add-dts-file-for-exynos4412-redwoodlte-board.patch
new file mode 100644 (file)
index 0000000..5c9f2cc
--- /dev/null
@@ -0,0 +1,742 @@
+From e078c0f8a8438e8469f9119793b93617f5f750f2 Mon Sep 17 00:00:00 2001
+From: Donghwa Lee <dh09.lee@samsung.com>
+Date: Thu, 1 Aug 2013 11:29:06 +0900
+Subject: [PATCH 0506/1302] ARM: dts: Add dts file for exynos4412-redwoodlte
+ board
+
+This patch adds a basic dts file for REDWOOD-LTE board based on Exynos 4412
+SoC.
+
+Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/Makefile                  |   1 +
+ arch/arm/boot/dts/exynos4412-redwoodlte.dts | 704 ++++++++++++++++++++++++++++
+ 2 files changed, 705 insertions(+)
+ create mode 100644 arch/arm/boot/dts/exynos4412-redwoodlte.dts
+
+diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
+index 00fe583..aa7eb34 100644
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -53,6 +53,7 @@ dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \
+       exynos4412-m0.dtb \
+       exynos4412-odroidx.dtb \
+       exynos4412-redwood.dtb \
++      exynos4412-redwoodlte.dtb \
+       exynos4412-smdk4412.dtb \
+       exynos4412-slp_pq.dtb \
+       exynos4412-origen.dtb \
+diff --git a/arch/arm/boot/dts/exynos4412-redwoodlte.dts b/arch/arm/boot/dts/exynos4412-redwoodlte.dts
+new file mode 100644
+index 0000000..86fa455
+--- /dev/null
++++ b/arch/arm/boot/dts/exynos4412-redwoodlte.dts
+@@ -0,0 +1,704 @@
++/*
++ * Samsung's Exynos4412 based  board device tree source
++ *
++ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
++ *            http://www.samsung.com
++ *
++ * Device tree source file for Samsung's Redwood board which is based on
++ * Samsung's Exynos4412 SoC.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++*/
++
++/dts-v1/;
++/include/ "exynos4412.dtsi"
++
++/ {
++      model = "Samsung Redwood based on Exynos4412";
++      compatible = "samsung,redwood", "samsung,exynos4412";
++
++      memory {
++              reg =  <0x40000000 0x10000000
++                      0x50000000 0x10000000
++                      0x60000000 0x10000000
++                      0x70000000 0x10000000>;
++
++              reserved-memory {
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      contig_mem: region@71000000 {
++                              compatible = "linux,contiguous-memory-region";
++                              reg = <0x71000000 0x0c000000>;
++                              linux,default-contiguous-region;
++                      };
++
++                      fimc_mem: region@70000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x70000000 0x1000000>;
++                      };
++
++                      mfc_l_mem: mfc_l_region@43000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x43000000 0x1000000>;
++                      };
++
++                      mfc_r_mem: mfc_r_region@51000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x51000000 0x1000000>;
++                      };
++              };
++      };
++
++      chosen {
++              bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rootwait earlyprintk panic=5";
++      };
++
++      firmware@0204F000 {
++              compatible = "samsung,secure-firmware";
++              reg = <0x0204F000 0x1000>;
++      };
++
++      fixed-rate-clocks {
++              xxti {
++                      compatible = "samsung,clock-xxti", "fixed-clock";
++                      clock-frequency = <0>;
++              };
++
++              xusbxti {
++                      compatible = "samsung,clock-xusbxti", "fixed-clock";
++                      clock-frequency = <24000000>;
++              };
++      };
++
++      vemmc_reg: voltage-regulator@0 {
++              compatible = "regulator-fixed";
++              regulator-name = "VMEM_VDD_2.8V";
++              regulator-min-microvolt = <2800000>;
++              regulator-max-microvolt = <2800000>;
++              gpio = <&gpk0 2 0>;
++              enable-active-high;
++      };
++
++      sdhci_emmc: sdhci@12510000 {
++              bus-width = <8>;
++              non-removable;
++              pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus8>;
++              pinctrl-names = "default";
++              vmmc-supply = <&vemmc_reg>;
++              status = "okay";
++      };
++
++      serial@13800000 {
++              status = "okay";
++      };
++
++      serial@13810000 {
++              status = "okay";
++      };
++
++      serial@13820000 {
++              status = "okay";
++      };
++
++      serial@13830000 {
++              status = "okay";
++      };
++
++      gpio-keys@0 {
++              compatible = "gpio-keys";
++
++              key@114 {
++                      interrupt-parent = <&gpj1>;
++                      interrupts = <2 0>;
++                      gpios = <&gpj1 2 1>;
++                      linux,code = <114>;
++                      label = "volume down";
++                      debounce-interval = <10>;
++              };
++
++              key@115 {
++                      interrupt-parent = <&gpj1>;
++                      interrupts = <1 0>;
++                      gpios = <&gpj1 1 1>;
++                      linux,code = <115>;
++                      label = "volume up";
++                      debounce-interval = <10>;
++              };
++
++              key@116 {
++                      interrupt-parent = <&gpx2>;
++                      interrupts = <7 0>;
++                      gpios = <&gpx2 7 1>;
++                      linux,code = <116>;
++                      label = "power";
++                      debounce-interval = <10>;
++                      gpio-key,wakeup;
++              };
++
++              key@139 {
++                      interrupt-parent = <&gpx0>;
++                      interrupts = <1 0>;
++                      gpios = <&gpx0 1 1>;
++                      linux,code = <139>;
++                      label = "menu";
++                      debounce-interval = <10>;
++                      gpio-key,wakeup;
++              };
++      };
++
++      i2c_0: i2c@13860000 {
++              samsung,i2c-sda-delay = <100>;
++              samsung,i2c-slave-addr = <0x10>;
++              samsung,i2c-max-bus-freq = <400000>;
++              pinctrl-0 = <&i2c0_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              s5c73m3@3c {
++                      compatible = "samsung,s5c73m3";
++                      reg = <0x3c>;
++                      gpios = <&gpm0 1 1>, /* ISP_STANDBY */
++                              <&gpf1 3 1>; /* ISP_RESET */
++                      vdd-int-supply = <&buck9_reg>;
++                      vddio-cis-supply = <&ldo9_reg>;
++                      vdda-supply = <&ldo17_reg>;
++                      vddio-host-supply = <&ldo18_reg>;
++                      vdd-af-supply = <&cam_af_reg>;
++                      vdd-reg-supply = <&cam_io_reg>;
++                      clock-frequency = <24000000>;
++
++                      port {
++                              s5c73m3_ep: endpoint {
++                                      remote-endpoint = <&csis0_ep>;
++                              };
++                      };
++              };
++      };
++
++      i2c@13870000 {
++              samsung,i2c-sda-delay = <100>;
++              samsung,i2c-slave-addr = <0x10>;
++              samsung,i2c-max-bus-freq = <400000>;
++              pinctrl-0 = <&i2c1_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              lsm330dlc_gyro@6b {
++                      compatible = "st,lsm330dlc-gyro";
++                      reg = <0x6b>;
++                      irq-map-policy = <1>;
++                      interrupt-controller;
++                      #interrups-cells = <2>;
++                      interrupt-parent = <&lsm330dlc_gyro_map>;
++                      interrupts= <1 0>;
++
++                      lsm330dlc_gyro_map: lsm330dlc-gyro-map {
++                              compatible = "samsung,lsm330dlc-gyro-map";
++                              #interrupt-cells = <2>;
++                              #address-cells = <0>;
++                              #size-cells = <0>;
++                              interrupt-map = <0x1 0 &gpf0 3 0>;
++                      };
++              };
++
++              lsm330dlc_accel@19 {
++                      compatible = "st,lsm330dlc-accel";
++                      reg = <0x19>;
++                      irq-map-policy = <2>;
++                      interrupt-controller;
++                      #interrups-cells = <2>;
++                      interrupt-parent = <&lsm330dlc_accel_map>;
++                      interrupts= <1 0>;
++
++                      lsm330dlc_accel_map: lsm330dlc-accel-map {
++                              compatible = "samsung,lsm330dlc-accel-map";
++                              #interrupt-cells = <2>;
++                              #address-cells = <0>;
++                              #size-cells = <0>;
++                              interrupt-map = <0x1 0 &gpx0 0 0>;
++                      };
++              };
++      };
++
++      i2c@13890000 {
++              samsung,i2c-sda-delay = <100>;
++              samsung,i2c-slave-addr = <0x10>;
++              samsung,i2c-max-bus-freq = <400000>;
++              pinctrl-0 = <&i2c3_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              mms114-touchscreen@48 {
++                      compatible = "melfas,mms114";
++                      reg = <0x48>;
++                      interrupt-parent = <&gpm2>;
++                      interrupts = <3 2>;
++                      x-size = <720>;
++                      y-size = <1280>;
++                      avdd-supply = <&ldo23_reg>;
++                      vdd-supply = <&ldo24_reg>;
++              };
++      };
++
++      i2c@138D0000 {
++              samsung,i2c-sda-delay = <100>;
++              samsung,i2c-slave-addr = <0x10>;
++              samsung,i2c-max-bus-freq = <100000>;
++              pinctrl-0 = <&i2c7_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              max77686_pmic@09 {
++                      compatible = "maxim,max77686";
++                      interrupt-parent = <&gpx0>;
++                      interrupts = <7 0>;
++                      reg = <0x09>;
++
++                      voltage-regulators {
++                              ldo1_reg: ldo@1 {
++                                      regulator-compatible = "LDO1";
++                                      regulator-name = "VALIVE_1.0V_AP";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo2_reg: ldo@2 {
++                                      regulator-compatible = "LDO2";
++                                      regulator-name = "VM1M2_1.2V_AP";
++                                      regulator-min-microvolt = <1200000>;
++                                      regulator-max-microvolt = <1200000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo3_reg: ldo@3 {
++                                      regulator-compatible = "LDO3";
++                                      regulator-name = "VCC_1.8V_AP";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo4_reg: ldo@4 {
++                                      regulator-compatible = "LDO4";
++                                      regulator-name = "VCC_2.8V_AP";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo5_reg: ldo@5 {
++                                      regulator-compatible = "LDO5";
++                                      regulator-name = "VCC_1.8V_IO";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo6_reg: ldo@6 {
++                                      regulator-compatible = "LDO6";
++                                      regulator-name = "VMPLL_1.0V_AP";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo7_reg: ldo@7 {
++                                      regulator-compatible = "LDO7";
++                                      regulator-name = "VPLL_1.0V_AP";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo8_reg: ldo@8 {
++                                      regulator-compatible = "LDO8";
++                                      regulator-name = "VMIPI_1.0V";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                              };
++
++                              ldo9_reg: ldo@9 {
++                                      regulator-compatible = "LDO9";
++                                      regulator-name = "CAM_ISP_MIPI_1.2V";
++                                      regulator-min-microvolt = <1200000>;
++                                      regulator-max-microvolt = <1200000>;
++                              };
++
++                              ldo10_reg: ldo@10 {
++                                      regulator-compatible = "LDO10";
++                                      regulator-name = "VMIPI_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                              };
++
++                              ldo11_reg: ldo@11 {
++                                      regulator-compatible = "LDO11";
++                                      regulator-name = "VABB1_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo12_reg: ldo@12 {
++                                      regulator-compatible = "LDO12";
++                                      regulator-name = "VUOTG_3.0V";
++                                      regulator-min-microvolt = <3000000>;
++                                      regulator-max-microvolt = <3000000>;
++                              };
++
++                              ldo13_reg: ldo@13 {
++                                      regulator-compatible = "LDO13";
++                                      regulator-name = "NFC_AVDD_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                              };
++
++                              ldo14_reg: ldo@14 {
++                                      regulator-compatible = "LDO14";
++                                      regulator-name = "VABB2_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo15_reg: ldo@15 {
++                                      regulator-compatible = "LDO15";
++                                      regulator-name = "VHSIC_1.0V";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo16_reg: ldo@16 {
++                                      regulator-compatible = "LDO16";
++                                      regulator-name = "VHSIC_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo17_reg: ldo@17 {
++                                      regulator-compatible = "LDO17";
++                                      regulator-name = "CAM_SENSOR_CORE_1.2V";
++                                      regulator-min-microvolt = <1200000>;
++                                      regulator-max-microvolt = <1200000>;
++                              };
++
++                              ldo18_reg: ldo@18 {
++                                      regulator-compatible = "LDO18";
++                                      regulator-name = "CAM_ISP_SENSOR_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                              };
++
++                              ldo19_reg: ldo@19 {
++                                      regulator-compatible = "LDO19";
++                                      regulator-name = "VT_CAM_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                              };
++
++                              ldo20_reg: ldo@20 {
++                                      regulator-compatible = "LDO20";
++                                      regulator-name = "VDDQ_PRE_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                              };
++
++                              ldo21_reg: ldo@21 {
++                                      regulator-compatible = "LDO21";
++                                      regulator-name = "VTF_2.8V";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
++                              };
++
++                              ldo22_reg: ldo@22 {
++                                      regulator-compatible = "LDO22";
++                                      regulator-name = "VMEM_VDD_2.8V";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo23_reg: ldo@23 {
++                                      regulator-compatible = "LDO23";
++                                      regulator-name = "TSP_AVDD_3.3V";
++                                      regulator-min-microvolt = <3300000>;
++                                      regulator-max-microvolt = <3300000>;
++                              };
++
++                              ldo24_reg: ldo@24 {
++                                      regulator-compatible = "LDO24";
++                                      regulator-name = "VDD_1.8V_TSP";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                              };
++
++                              ldo25_reg: ldo@25 {
++                                      regulator-compatible = "LDO25";
++                                      regulator-name = "LED_A_2.8V";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
++                              };
++
++                              ldo26_reg: ldo@26 {
++                                      regulator-compatible = "LDO26";
++                                      regulator-name = "MOTOR_VCC_3.0V";
++                                      regulator-min-microvolt = <3000000>;
++                                      regulator-max-microvolt = <3000000>;
++                              };
++
++                              buck1_reg: buck@1 {
++                                      regulator-compatible = "BUCK1";
++                                      regulator-name = "vdd_mif";
++                                      regulator-min-microvolt = <850000>;
++                                      regulator-max-microvolt = <1100000>;
++                                      regulator-always-on;
++                                      regulator-boot-on;
++                              };
++
++                              buck2_reg: buck@2 {
++                                      regulator-compatible = "BUCK2";
++                                      regulator-name = "vdd_arm";
++                                      regulator-min-microvolt = <850000>;
++                                      regulator-max-microvolt = <1500000>;
++                                      regulator-always-on;
++                                      regulator-boot-on;
++                              };
++
++                              buck3_reg: buck@3 {
++                                      regulator-compatible = "BUCK3";
++                                      regulator-name = "vdd_int";
++                                      regulator-min-microvolt = <850000>;
++                                      regulator-max-microvolt = <1150000>;
++                                      regulator-always-on;
++                                      regulator-boot-on;
++                              };
++
++                              buck4_reg: buck@4 {
++                                      regulator-compatible = "BUCK4";
++                                      regulator-name = "vdd_g3d";
++                                      regulator-min-microvolt = <850000>;
++                                      regulator-max-microvolt = <1150000>;
++                                      regulator-boot-on;
++                              };
++
++                              buck5_reg: buck@5 {
++                                      regulator-compatible = "BUCK5";
++                                      regulator-name = "VMEM_1.2V_AP";
++                                      regulator-min-microvolt = <1200000>;
++                                      regulator-max-microvolt = <1200000>;
++                                      regulator-always-on;
++                              };
++
++                              buck6_reg: buck@6 {
++                                      regulator-compatible = "BUCK6";
++                                      regulator-name = "VCC_SUB_1.35V";
++                                      regulator-min-microvolt = <1350000>;
++                                      regulator-max-microvolt = <1350000>;
++                                      regulator-always-on;
++                              };
++                              buck7_reg: buck@7 {
++                                      regulator-compatible = "BUCK7";
++                                      regulator-name = "VCC_SUB_2.0V";
++                                      regulator-min-microvolt = <2000000>;
++                                      regulator-max-microvolt = <2000000>;
++                                      regulator-always-on;
++                              };
++
++                              buck8_reg: buck@8 {
++                                      regulator-compatible = "BUCK8";
++                                      regulator-name = "VMEM_VDDF_3.0V";
++                                      regulator-min-microvolt = <2850000>;
++                                      regulator-max-microvolt = <2850000>;
++                                      regulator-always-on;
++                              };
++
++                              buck9_reg: buck@9 {
++                                      regulator-compatible = "BUCK9";
++                                      regulator-name = "CAM_ISP_CORE_1.2V";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1200000>;
++                              };
++                      };
++              };
++      };
++
++      i2c_if_pmic: i2c@0 {
++              compatible = "i2c-gpio";
++              gpios = <&gpm2 0 0
++                       &gpm2 1 0
++                      >;
++              #address-cells = <1>;
++              #size-cells = <0>;
++      };
++
++      lcd_vdd_reg: voltage-regulator@1 {
++              compatible = "regulator-fixed";
++              regulator-name = "LCD_VDD_5.0V";
++              regulator-min-microvolt = <5000000>;
++              regulator-max-microvolt = <5000000>;
++              gpio = <&gpm0 0 0>;
++              enable-active-high;
++      };
++
++      cam_af_reg: voltage-regulator@2 {
++              compatible = "regulator-fixed";
++              regulator-name = "CAM_AF";
++              regulator-min-microvolt = <2800000>;
++              regulator-max-microvolt = <2800000>;
++              gpio = <&gpm0 4 0>;
++              enable-active-high;
++      };
++
++      cam_io_reg: voltage-regulator@3 {
++              compatible = "regulator-fixed";
++              regulator-name = "CAM_SENSOR_A";
++              regulator-min-microvolt = <2800000>;
++              regulator-max-microvolt = <2800000>;
++              gpio = <&gpm0 2 0>;
++              enable-active-high;
++      };
++
++      cam_isp_core_reg: voltage-regulator@4 {
++              compatible = "regulator-fixed";
++              regulator-name = "CAM_ISP_CORE_1.2V_EN";
++              regulator-min-microvolt = <1200000>;
++              regulator-max-microvolt = <1200000>;
++              gpio = <&gpm0 3 0>;
++              enable-active-high;
++              regulator-always-on;
++      };
++
++      vidi {
++              compatible = "samsung,exynos-drm-vidi";
++      };
++
++      sysmmu-fimd0 {
++              clock-names = "sysmmu";
++              clocks = <&clock 287>;
++              mmu-master = <&fimd>;
++      };
++
++      sysmmu-g2d {
++              clock-names = "sysmmu";
++              clocks = <&clock 280>;
++              mmu-master = <&g2d>;
++      };
++
++      usbphy@125B0000 {
++              status = "okay";
++      };
++
++      hsotg@12480000 {
++              status = "okay";
++              vusb_d-supply = <&ldo15_reg>;
++              vusb_a-supply = <&ldo12_reg>;
++      };
++
++      spi_1: spi@13930000 {
++              pinctrl-names = "default";
++              pinctrl-0 = <&spi1_bus>;
++              status = "okay";
++
++              s5c73m3_spi: s5c73m3 {
++                      compatible = "samsung,s5c73m3";
++                      spi-max-frequency = <50000000>;
++                      reg = <0>;
++                      controller-data {
++                              cs-gpio = <&gpb 5 0>;
++                              samsung,spi-feedback-delay = <2>;
++                      };
++              };
++      };
++
++      g2d@10800000 {
++              status = "okay";
++      };
++
++      rotator: rotator@12810000 {
++              status = "okay";
++      };
++
++      camera {
++              status = "okay";
++
++              pinctrl-names = "default";
++              pinctrl-0 = <&cam_port_a_clk_active>;
++
++              fimc_0: fimc@11800000 {
++                      clock-frequency = <176000000>;
++                      status = "okay";
++              };
++
++              fimc_1: fimc@11810000 {
++                      clock-frequency = <176000000>;
++                      status = "okay";
++              };
++
++              fimc_2: fimc@11820000 {
++                      clock-frequency = <176000000>;
++                      status = "okay";
++              };
++
++              fimc_3: fimc@11830000 {
++                      clock-frequency = <176000000>;
++                      status = "okay";
++              };
++
++              csis_0: csis@11880000 {
++                      status = "okay";
++                      vddcore-supply = <&ldo8_reg>;
++                      vddio-supply = <&ldo10_reg>;
++                      clock-frequency = <160000000>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++
++                      /* Camera C (3) MIPI CSI-2 (CSIS0) */
++                      port@3 {
++                              reg = <3>;
++                              csis0_ep: endpoint {
++                                      remote-endpoint = <&s5c73m3_ep>;
++                                      data-lanes = <1 2 3 4>;
++                                      samsung,csis-hs-settle = <12>;
++                              };
++                      };
++              };
++      };
++
++      mfc: codec@13400000 {
++              status = "okay";
++
++              memport@0 {
++                      memory-region = <&mfc_l_mem>;
++              };
++
++              memport@1 {
++                      memory-region = <&mfc_r_mem>;
++              };
++      };
++
++      gpu@13000000 {
++              status = "okay";
++              vdd_g3d-supply = <&buck4_reg>;
++      };
++
++      cpufreq {
++              status = "okay";
++              overclocking = "okay";
++              max_overclocking_freq = <1500000>;
++      };
++
++      tmu@100C0000 {
++              vdd_ts-supply = <&ldo10_reg>;
++              status = "okay";
++      };
++
++      ehci@12580000 {
++              status = "okay";
++      };
++};
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0507-f2fs-recover-date-requested-by-fdatasync.patch b/patches.tizen/0507-f2fs-recover-date-requested-by-fdatasync.patch
new file mode 100644 (file)
index 0000000..67dfcb8
--- /dev/null
@@ -0,0 +1,40 @@
+From 64ac3deeec4782902618a6568f4e4914ba0f89f6 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Wed, 3 Jul 2013 10:55:52 +0900
+Subject: [PATCH 0507/1302] f2fs: recover date requested by fdatasync
+
+In order to support SQLite that uses fdatasync instead of fsync, we should
+guarantee the data requested by fdatasync can be recovered after sudden-power-
+off.
+
+So, let's remove the fdatasync condition in f2fs_sync_file.
+Otherwise, we can restore the data after sudden-power-off due to nonexistence
+of any fsync mark'ed node blocks.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/file.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index d2d2b7d..157a635 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -147,9 +147,10 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
+       mutex_lock(&inode->i_mutex);
+-      if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
+-              goto out;
+-
++      /*
++       * Both of fdatasync() and fsync() are able to be recovered from
++       * sudden-power-off.
++       */
+       if (!S_ISREG(inode->i_mode) || inode->i_nlink != 1)
+               need_cp = true;
+       else if (file_wrong_pino(inode))
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0508-f2fs-add-description-for-fsck.f2fs-and-dump.f2fs.patch b/patches.tizen/0508-f2fs-add-description-for-fsck.f2fs-and-dump.f2fs.patch
new file mode 100644 (file)
index 0000000..bfd29f8
--- /dev/null
@@ -0,0 +1,86 @@
+From 0f3f7643a7e8bab7f0d901e9a43b2491dd80be09 Mon Sep 17 00:00:00 2001
+From: Changman Lee <cm224.lee@samsung.com>
+Date: Thu, 4 Jul 2013 17:12:47 +0900
+Subject: [PATCH 0508/1302] f2fs: add description for fsck.f2fs and dump.f2fs
+
+This patch adds some description on fsck.f2fs and dump.f2fs which is
+recently merged into f2fs-tools.
+
+Signed-off-by: Changman Lee <cm224.lee@samsung.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/filesystems/f2fs.txt | 43 ++++++++++++++++++++++++++++++++++----
+ 1 file changed, 39 insertions(+), 4 deletions(-)
+
+diff --git a/Documentation/filesystems/f2fs.txt b/Documentation/filesystems/f2fs.txt
+index b91e2f2..0500c19 100644
+--- a/Documentation/filesystems/f2fs.txt
++++ b/Documentation/filesystems/f2fs.txt
+@@ -18,8 +18,8 @@ according to its internal geometry or flash memory management scheme, namely FTL
+ F2FS and its tools support various parameters not only for configuring on-disk
+ layout, but also for selecting allocation and cleaning algorithms.
+-The file system formatting tool, "mkfs.f2fs", is available from the following
+-git tree:
++The following git tree provides the file system formatting tool (mkfs.f2fs),
++a consistency checking tool (fsck.f2fs), and a debugging tool (dump.f2fs).
+ >> git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs-tools.git
+ For reporting bugs and sending patches, please use the following mailing list:
+@@ -149,8 +149,12 @@ USAGE
+  # mkfs.f2fs -l label /dev/block_device
+  # mount -t f2fs /dev/block_device /mnt/f2fs
+-Format options
+---------------
++mkfs.f2fs
++---------
++The mkfs.f2fs is for the use of formatting a partition as the f2fs filesystem,
++which builds a basic on-disk layout.
++
++The options consist of:
+ -l [label]   : Give a volume label, up to 512 unicode name.
+ -a [0 or 1]  : Split start location of each area for heap-based allocation.
+                1 is set by default, which performs this.
+@@ -164,6 +168,37 @@ Format options
+ -t [0 or 1]  : Disable discard command or not.
+                1 is set by default, which conducts discard.
++fsck.f2fs
++---------
++The fsck.f2fs is a tool to check the consistency of an f2fs-formatted
++partition, which examines whether the filesystem metadata and user-made data
++are cross-referenced correctly or not.
++Note that, initial version of the tool does not fix any inconsistency.
++
++The options consist of:
++  -d debug level [default:0]
++
++dump.f2fs
++---------
++The dump.f2fs shows the information of specific inode and dumps SSA and SIT to
++file. Each file is dump_ssa and dump_sit.
++
++The dump.f2fs is used to debug on-disk data structures of the f2fs filesystem.
++It shows on-disk inode information reconized by a given inode number, and is
++able to dump all the SSA and SIT entries into predefined files, ./dump_ssa and
++./dump_sit respectively.
++
++The options consist of:
++  -d debug level [default:0]
++  -i inode no (hex)
++  -s [SIT dump segno from #1~#2 (decimal), for all 0~-1]
++  -a [SSA dump segno from #1~#2 (decimal), for all 0~-1]
++
++Examples:
++# dump.f2fs -i [ino] /dev/sdx
++# dump.f2fs -s 0~-1 /dev/sdx (SIT dump)
++# dump.f2fs -a 0~-1 /dev/sdx (SSA dump)
++
+ ================================================================================
+ DESIGN
+ ================================================================================
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0509-f2fs-add-proc-entry-to-monitor-current-usage-of-segm.patch b/patches.tizen/0509-f2fs-add-proc-entry-to-monitor-current-usage-of-segm.patch
new file mode 100644 (file)
index 0000000..39c6095
--- /dev/null
@@ -0,0 +1,129 @@
+From f0ad478976d102744a56addb8fdc7ba316c3fc93 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Fri, 28 Jun 2013 12:47:01 +0900
+Subject: [PATCH 0509/1302] f2fs: add proc entry to monitor current usage of
+ segments
+
+You can monitor valid block counts of whole segments in:
+  /proc/fs/f2fs/sdb1/segment_info.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/f2fs.h  |  1 +
+ fs/f2fs/super.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 47 insertions(+)
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 467d42d..c7620b9 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -350,6 +350,7 @@ enum page_type {
+ struct f2fs_sb_info {
+       struct super_block *sb;                 /* pointer to VFS super block */
++      struct proc_dir_entry *s_proc;          /* proc entry */
+       struct buffer_head *raw_super_buf;      /* buffer head of raw sb */
+       struct f2fs_super_block *raw_super;     /* raw super block pointer */
+       int s_dirty;                            /* dirty flag for checkpoint */
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 75c7dc3..70dbb31 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -18,6 +18,7 @@
+ #include <linux/parser.h>
+ #include <linux/mount.h>
+ #include <linux/seq_file.h>
++#include <linux/proc_fs.h>
+ #include <linux/random.h>
+ #include <linux/exportfs.h>
+ #include <linux/blkdev.h>
+@@ -31,6 +32,7 @@
+ #define CREATE_TRACE_POINTS
+ #include <trace/events/f2fs.h>
++static struct proc_dir_entry *f2fs_proc_root;
+ static struct kmem_cache *f2fs_inode_cachep;
+ enum {
+@@ -223,6 +225,11 @@ static void f2fs_put_super(struct super_block *sb)
+ {
+       struct f2fs_sb_info *sbi = F2FS_SB(sb);
++      if (sbi->s_proc) {
++              remove_proc_entry("segment_info", sbi->s_proc);
++              remove_proc_entry(sb->s_id, f2fs_proc_root);
++      }
++
+       f2fs_destroy_stats(sbi);
+       stop_gc_thread(sbi);
+@@ -340,6 +347,36 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
+       return 0;
+ }
++static int segment_info_seq_show(struct seq_file *seq, void *offset)
++{
++      struct super_block *sb = seq->private;
++      struct f2fs_sb_info *sbi = F2FS_SB(sb);
++      unsigned int total_segs = le32_to_cpu(sbi->raw_super->segment_count_main);
++      int i;
++
++      for (i = 0; i < total_segs; i++) {
++              seq_printf(seq, "%u", get_valid_blocks(sbi, i, 1));
++              if (i != 0 && (i % 10) == 0)
++                      seq_puts(seq, "\n");
++              else
++                      seq_puts(seq, " ");
++      }
++      return 0;
++}
++
++static int segment_info_open_fs(struct inode *inode, struct file *file)
++{
++      return single_open(file, segment_info_seq_show, PDE_DATA(inode));
++}
++
++static const struct file_operations f2fs_seq_segment_info_fops = {
++      .owner = THIS_MODULE,
++      .open = segment_info_open_fs,
++      .read = seq_read,
++      .llseek = seq_lseek,
++      .release = single_release,
++};
++
+ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
+ {
+       struct f2fs_sb_info *sbi = F2FS_SB(sb);
+@@ -766,6 +803,13 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
+       if (err)
+               goto fail;
++      if (f2fs_proc_root)
++              sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root);
++
++      if (sbi->s_proc)
++              proc_create_data("segment_info", S_IRUGO, sbi->s_proc,
++                               &f2fs_seq_segment_info_fops, sb);
++
+       if (test_opt(sbi, DISCARD)) {
+               struct request_queue *q = bdev_get_queue(sb->s_bdev);
+               if (!blk_queue_discard(q))
+@@ -852,12 +896,14 @@ static int __init init_f2fs_fs(void)
+       if (err)
+               goto fail;
+       f2fs_create_root_stats();
++      f2fs_proc_root = proc_mkdir("fs/f2fs", NULL);
+ fail:
+       return err;
+ }
+ static void __exit exit_f2fs_fs(void)
+ {
++      remove_proc_entry("fs/f2fs", NULL);
+       f2fs_destroy_root_stats();
+       unregister_filesystem(&f2fs_fs_type);
+       destroy_checkpoint_caches();
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0510-f2fs-add-a-help-func-F2FS_STAT-to-get-the-f2fs_stat_.patch b/patches.tizen/0510-f2fs-add-a-help-func-F2FS_STAT-to-get-the-f2fs_stat_.patch
new file mode 100644 (file)
index 0000000..6d8d985
--- /dev/null
@@ -0,0 +1,127 @@
+From 86fff8187ef3c2abc63a00d1409c79187493bc0a Mon Sep 17 00:00:00 2001
+From: Gu Zheng <guz.fnst@cn.fujitsu.com>
+Date: Fri, 12 Jul 2013 14:47:11 +0800
+Subject: [PATCH 0510/1302] f2fs: add a help func F2FS_STAT() to get the
+ f2fs_stat_info
+
+Add a help func F2FS_STAT() to get the f2fs_stat_info.
+
+Signed-off-by: Gu Zheng <guz.fnst@cn.fujitsu.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/debug.c | 16 ++++++++--------
+ fs/f2fs/f2fs.h  | 11 ++++++++---
+ 2 files changed, 16 insertions(+), 11 deletions(-)
+
+diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
+index 0d6c6aa..fd12b7f 100644
+--- a/fs/f2fs/debug.c
++++ b/fs/f2fs/debug.c
+@@ -29,7 +29,7 @@ static DEFINE_MUTEX(f2fs_stat_mutex);
+ static void update_general_status(struct f2fs_sb_info *sbi)
+ {
+-      struct f2fs_stat_info *si = sbi->stat_info;
++      struct f2fs_stat_info *si = F2FS_STAT(sbi);
+       int i;
+       /* valid check of the segment numbers */
+@@ -83,7 +83,7 @@ static void update_general_status(struct f2fs_sb_info *sbi)
+  */
+ static void update_sit_info(struct f2fs_sb_info *sbi)
+ {
+-      struct f2fs_stat_info *si = sbi->stat_info;
++      struct f2fs_stat_info *si = F2FS_STAT(sbi);
+       unsigned int blks_per_sec, hblks_per_sec, total_vblocks, bimodal, dist;
+       struct sit_info *sit_i = SIT_I(sbi);
+       unsigned int segno, vblocks;
+@@ -118,7 +118,7 @@ static void update_sit_info(struct f2fs_sb_info *sbi)
+  */
+ static void update_mem_info(struct f2fs_sb_info *sbi)
+ {
+-      struct f2fs_stat_info *si = sbi->stat_info;
++      struct f2fs_stat_info *si = F2FS_STAT(sbi);
+       unsigned npages;
+       if (si->base_mem)
+@@ -305,11 +305,10 @@ int f2fs_build_stats(struct f2fs_sb_info *sbi)
+       struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
+       struct f2fs_stat_info *si;
+-      sbi->stat_info = kzalloc(sizeof(struct f2fs_stat_info), GFP_KERNEL);
+-      if (!sbi->stat_info)
++      si = kzalloc(sizeof(struct f2fs_stat_info), GFP_KERNEL);
++      if (!si)
+               return -ENOMEM;
+-      si = sbi->stat_info;
+       si->all_area_segs = le32_to_cpu(raw_super->segment_count);
+       si->sit_area_segs = le32_to_cpu(raw_super->segment_count_sit);
+       si->nat_area_segs = le32_to_cpu(raw_super->segment_count_nat);
+@@ -319,6 +318,7 @@ int f2fs_build_stats(struct f2fs_sb_info *sbi)
+       si->main_area_zones = si->main_area_sections /
+                               le32_to_cpu(raw_super->secs_per_zone);
+       si->sbi = sbi;
++      sbi->stat_info = si;
+       mutex_lock(&f2fs_stat_mutex);
+       list_add_tail(&si->stat_list, &f2fs_stat_list);
+@@ -329,13 +329,13 @@ int f2fs_build_stats(struct f2fs_sb_info *sbi)
+ void f2fs_destroy_stats(struct f2fs_sb_info *sbi)
+ {
+-      struct f2fs_stat_info *si = sbi->stat_info;
++      struct f2fs_stat_info *si = F2FS_STAT(sbi);
+       mutex_lock(&f2fs_stat_mutex);
+       list_del(&si->stat_list);
+       mutex_unlock(&f2fs_stat_mutex);
+-      kfree(sbi->stat_info);
++      kfree(si);
+ }
+ void __init f2fs_create_root_stats(void)
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index c7620b9..0a352b6 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -1113,11 +1113,16 @@ struct f2fs_stat_info {
+       unsigned base_mem, cache_mem;
+ };
++static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi)
++{
++      return (struct f2fs_stat_info*)sbi->stat_info;
++}
++
+ #define stat_inc_call_count(si)       ((si)->call_count++)
+ #define stat_inc_seg_count(sbi, type)                                 \
+       do {                                                            \
+-              struct f2fs_stat_info *si = sbi->stat_info;             \
++              struct f2fs_stat_info *si = F2FS_STAT(sbi);             \
+               (si)->tot_segs++;                                       \
+               if (type == SUM_TYPE_DATA)                              \
+                       si->data_segs++;                                \
+@@ -1130,14 +1135,14 @@ struct f2fs_stat_info {
+ #define stat_inc_data_blk_count(sbi, blks)                            \
+       do {                                                            \
+-              struct f2fs_stat_info *si = sbi->stat_info;             \
++              struct f2fs_stat_info *si = F2FS_STAT(sbi);             \
+               stat_inc_tot_blk_count(si, blks);                       \
+               si->data_blks += (blks);                                \
+       } while (0)
+ #define stat_inc_node_blk_count(sbi, blks)                            \
+       do {                                                            \
+-              struct f2fs_stat_info *si = sbi->stat_info;             \
++              struct f2fs_stat_info *si = F2FS_STAT(sbi);             \
+               stat_inc_tot_blk_count(si, blks);                       \
+               si->node_blks += (blks);                                \
+       } while (0)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0511-f2fs-introduce-help-function-F2FS_NODE.patch b/patches.tizen/0511-f2fs-introduce-help-function-F2FS_NODE.patch
new file mode 100644 (file)
index 0000000..628da57
--- /dev/null
@@ -0,0 +1,313 @@
+From 67c57f7e0f91ae82ea5a8e3d8435badcf8395817 Mon Sep 17 00:00:00 2001
+From: Gu Zheng <guz.fnst@cn.fujitsu.com>
+Date: Mon, 15 Jul 2013 17:57:38 +0800
+Subject: [PATCH 0511/1302] f2fs: introduce help function F2FS_NODE()
+
+Introduce help function F2FS_NODE() to simplify the conversion of node_page to
+f2fs_node.
+
+Signed-off-by: Gu Zheng <guz.fnst@cn.fujitsu.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/data.c     |  2 +-
+ fs/f2fs/dir.c      |  2 +-
+ fs/f2fs/f2fs.h     |  9 +++++++--
+ fs/f2fs/file.c     |  2 +-
+ fs/f2fs/inode.c    |  4 ++--
+ fs/f2fs/node.c     | 10 +++++-----
+ fs/f2fs/node.h     | 40 ++++++++++++++++------------------------
+ fs/f2fs/recovery.c |  6 ++----
+ 8 files changed, 35 insertions(+), 40 deletions(-)
+
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index e88f46f..dc21f9e 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -39,7 +39,7 @@ static void __set_data_blkaddr(struct dnode_of_data *dn, block_t new_addr)
+       wait_on_page_writeback(node_page);
+-      rn = (struct f2fs_node *)page_address(node_page);
++      rn = F2FS_NODE(node_page);
+       /* Get physical address of data block */
+       addr_array = blkaddr_in_node(rn);
+diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
+index 4f21452..a151f0f 100644
+--- a/fs/f2fs/dir.c
++++ b/fs/f2fs/dir.c
+@@ -270,7 +270,7 @@ static void init_dent_inode(const struct qstr *name, struct page *ipage)
+       struct f2fs_node *rn;
+       /* copy name info. to this inode page */
+-      rn = (struct f2fs_node *)page_address(ipage);
++      rn = F2FS_NODE(ipage);
+       rn->i.i_namelen = cpu_to_le32(name->len);
+       memcpy(rn->i.i_name, name->name, name->len);
+       set_page_dirty(ipage);
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 0a352b6..2dfd584 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -455,6 +455,11 @@ static inline struct f2fs_checkpoint *F2FS_CKPT(struct f2fs_sb_info *sbi)
+       return (struct f2fs_checkpoint *)(sbi->ckpt);
+ }
++static inline struct f2fs_node *F2FS_NODE(struct page *page)
++{
++      return (struct f2fs_node *)page_address(page);
++}
++
+ static inline struct f2fs_nm_info *NM_I(struct f2fs_sb_info *sbi)
+ {
+       return (struct f2fs_nm_info *)(sbi->nm_info);
+@@ -813,7 +818,7 @@ static inline struct kmem_cache *f2fs_kmem_cache_create(const char *name,
+ static inline bool IS_INODE(struct page *page)
+ {
+-      struct f2fs_node *p = (struct f2fs_node *)page_address(page);
++      struct f2fs_node *p = F2FS_NODE(page);
+       return RAW_IS_INODE(p);
+ }
+@@ -827,7 +832,7 @@ static inline block_t datablock_addr(struct page *node_page,
+ {
+       struct f2fs_node *raw_node;
+       __le32 *addr_array;
+-      raw_node = (struct f2fs_node *)page_address(node_page);
++      raw_node = F2FS_NODE(node_page);
+       addr_array = blkaddr_in_node(raw_node);
+       return le32_to_cpu(addr_array[offset]);
+ }
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 157a635..65ca3b3 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -206,7 +206,7 @@ int truncate_data_blocks_range(struct dnode_of_data *dn, int count)
+       struct f2fs_node *raw_node;
+       __le32 *addr;
+-      raw_node = page_address(dn->node_page);
++      raw_node = F2FS_NODE(dn->node_page);
+       addr = blkaddr_in_node(raw_node) + ofs;
+       for ( ; count > 0; count--, addr++, dn->ofs_in_node++) {
+diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
+index 2b2d45d1..debf743 100644
+--- a/fs/f2fs/inode.c
++++ b/fs/f2fs/inode.c
+@@ -56,7 +56,7 @@ static int do_read_inode(struct inode *inode)
+       if (IS_ERR(node_page))
+               return PTR_ERR(node_page);
+-      rn = page_address(node_page);
++      rn = F2FS_NODE(node_page);
+       ri = &(rn->i);
+       inode->i_mode = le16_to_cpu(ri->i_mode);
+@@ -153,7 +153,7 @@ void update_inode(struct inode *inode, struct page *node_page)
+       wait_on_page_writeback(node_page);
+-      rn = page_address(node_page);
++      rn = F2FS_NODE(node_page);
+       ri = &(rn->i);
+       ri->i_mode = cpu_to_le16(inode->i_mode);
+diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
+index b02440c..e1fa84a 100644
+--- a/fs/f2fs/node.c
++++ b/fs/f2fs/node.c
+@@ -565,7 +565,7 @@ static int truncate_nodes(struct dnode_of_data *dn, unsigned int nofs,
+               return PTR_ERR(page);
+       }
+-      rn = (struct f2fs_node *)page_address(page);
++      rn = F2FS_NODE(page);
+       if (depth < 3) {
+               for (i = ofs; i < NIDS_PER_BLOCK; i++, freed++) {
+                       child_nid = le32_to_cpu(rn->in.nid[i]);
+@@ -698,7 +698,7 @@ restart:
+       set_new_dnode(&dn, inode, page, NULL, 0);
+       unlock_page(page);
+-      rn = page_address(page);
++      rn = F2FS_NODE(page);
+       switch (level) {
+       case 0:
+       case 1:
+@@ -1483,8 +1483,8 @@ int recover_inode_page(struct f2fs_sb_info *sbi, struct page *page)
+       SetPageUptodate(ipage);
+       fill_node_footer(ipage, ino, ino, 0, true);
+-      src = (struct f2fs_node *)page_address(page);
+-      dst = (struct f2fs_node *)page_address(ipage);
++      src = F2FS_NODE(page);
++      dst = F2FS_NODE(ipage);
+       memcpy(dst, src, (unsigned long)&src->i.i_ext - (unsigned long)&src->i);
+       dst->i.i_size = 0;
+@@ -1534,7 +1534,7 @@ int restore_node_summary(struct f2fs_sb_info *sbi,
+                       goto out;
+               lock_page(page);
+-              rn = (struct f2fs_node *)page_address(page);
++              rn = F2FS_NODE(page);
+               sum_entry->nid = rn->footer.nid;
+               sum_entry->version = 0;
+               sum_entry->ofs_in_node = 0;
+diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h
+index c65fb4f..87349c4 100644
+--- a/fs/f2fs/node.h
++++ b/fs/f2fs/node.h
+@@ -155,8 +155,7 @@ static inline void set_to_next_nat(struct f2fs_nm_info *nm_i, nid_t start_nid)
+ static inline void fill_node_footer(struct page *page, nid_t nid,
+                               nid_t ino, unsigned int ofs, bool reset)
+ {
+-      void *kaddr = page_address(page);
+-      struct f2fs_node *rn = (struct f2fs_node *)kaddr;
++      struct f2fs_node *rn = F2FS_NODE(page);
+       if (reset)
+               memset(rn, 0, sizeof(*rn));
+       rn->footer.nid = cpu_to_le32(nid);
+@@ -166,10 +165,8 @@ static inline void fill_node_footer(struct page *page, nid_t nid,
+ static inline void copy_node_footer(struct page *dst, struct page *src)
+ {
+-      void *src_addr = page_address(src);
+-      void *dst_addr = page_address(dst);
+-      struct f2fs_node *src_rn = (struct f2fs_node *)src_addr;
+-      struct f2fs_node *dst_rn = (struct f2fs_node *)dst_addr;
++      struct f2fs_node *src_rn = F2FS_NODE(src);
++      struct f2fs_node *dst_rn = F2FS_NODE(dst);
+       memcpy(&dst_rn->footer, &src_rn->footer, sizeof(struct node_footer));
+ }
+@@ -177,45 +174,40 @@ static inline void fill_node_footer_blkaddr(struct page *page, block_t blkaddr)
+ {
+       struct f2fs_sb_info *sbi = F2FS_SB(page->mapping->host->i_sb);
+       struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
+-      void *kaddr = page_address(page);
+-      struct f2fs_node *rn = (struct f2fs_node *)kaddr;
++      struct f2fs_node *rn = F2FS_NODE(page);
++
+       rn->footer.cp_ver = ckpt->checkpoint_ver;
+       rn->footer.next_blkaddr = cpu_to_le32(blkaddr);
+ }
+ static inline nid_t ino_of_node(struct page *node_page)
+ {
+-      void *kaddr = page_address(node_page);
+-      struct f2fs_node *rn = (struct f2fs_node *)kaddr;
++      struct f2fs_node *rn = F2FS_NODE(node_page);
+       return le32_to_cpu(rn->footer.ino);
+ }
+ static inline nid_t nid_of_node(struct page *node_page)
+ {
+-      void *kaddr = page_address(node_page);
+-      struct f2fs_node *rn = (struct f2fs_node *)kaddr;
++      struct f2fs_node *rn = F2FS_NODE(node_page);
+       return le32_to_cpu(rn->footer.nid);
+ }
+ static inline unsigned int ofs_of_node(struct page *node_page)
+ {
+-      void *kaddr = page_address(node_page);
+-      struct f2fs_node *rn = (struct f2fs_node *)kaddr;
++      struct f2fs_node *rn = F2FS_NODE(node_page);
+       unsigned flag = le32_to_cpu(rn->footer.flag);
+       return flag >> OFFSET_BIT_SHIFT;
+ }
+ static inline unsigned long long cpver_of_node(struct page *node_page)
+ {
+-      void *kaddr = page_address(node_page);
+-      struct f2fs_node *rn = (struct f2fs_node *)kaddr;
++      struct f2fs_node *rn = F2FS_NODE(node_page);
+       return le64_to_cpu(rn->footer.cp_ver);
+ }
+ static inline block_t next_blkaddr_of_node(struct page *node_page)
+ {
+-      void *kaddr = page_address(node_page);
+-      struct f2fs_node *rn = (struct f2fs_node *)kaddr;
++      struct f2fs_node *rn = F2FS_NODE(node_page);
+       return le32_to_cpu(rn->footer.next_blkaddr);
+ }
+@@ -250,7 +242,7 @@ static inline bool IS_DNODE(struct page *node_page)
+ static inline void set_nid(struct page *p, int off, nid_t nid, bool i)
+ {
+-      struct f2fs_node *rn = (struct f2fs_node *)page_address(p);
++      struct f2fs_node *rn = F2FS_NODE(p);
+       wait_on_page_writeback(p);
+@@ -263,7 +255,8 @@ static inline void set_nid(struct page *p, int off, nid_t nid, bool i)
+ static inline nid_t get_nid(struct page *p, int off, bool i)
+ {
+-      struct f2fs_node *rn = (struct f2fs_node *)page_address(p);
++      struct f2fs_node *rn = F2FS_NODE(p);
++
+       if (i)
+               return le32_to_cpu(rn->i.i_nid[off - NODE_DIR1_BLOCK]);
+       return le32_to_cpu(rn->in.nid[off]);
+@@ -314,8 +307,7 @@ static inline void clear_cold_data(struct page *page)
+ static inline int is_node(struct page *page, int type)
+ {
+-      void *kaddr = page_address(page);
+-      struct f2fs_node *rn = (struct f2fs_node *)kaddr;
++      struct f2fs_node *rn = F2FS_NODE(page);
+       return le32_to_cpu(rn->footer.flag) & (1 << type);
+ }
+@@ -325,7 +317,7 @@ static inline int is_node(struct page *page, int type)
+ static inline void set_cold_node(struct inode *inode, struct page *page)
+ {
+-      struct f2fs_node *rn = (struct f2fs_node *)page_address(page);
++      struct f2fs_node *rn = F2FS_NODE(page);
+       unsigned int flag = le32_to_cpu(rn->footer.flag);
+       if (S_ISDIR(inode->i_mode))
+@@ -337,7 +329,7 @@ static inline void set_cold_node(struct inode *inode, struct page *page)
+ static inline void set_mark(struct page *page, int mark, int type)
+ {
+-      struct f2fs_node *rn = (struct f2fs_node *)page_address(page);
++      struct f2fs_node *rn = F2FS_NODE(page);
+       unsigned int flag = le32_to_cpu(rn->footer.flag);
+       if (mark)
+               flag |= (0x1 << type);
+diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
+index d56d951..639eb34 100644
+--- a/fs/f2fs/recovery.c
++++ b/fs/f2fs/recovery.c
+@@ -40,8 +40,7 @@ static struct fsync_inode_entry *get_fsync_inode(struct list_head *head,
+ static int recover_dentry(struct page *ipage, struct inode *inode)
+ {
+-      void *kaddr = page_address(ipage);
+-      struct f2fs_node *raw_node = (struct f2fs_node *)kaddr;
++      struct f2fs_node *raw_node = F2FS_NODE(ipage);
+       struct f2fs_inode *raw_inode = &(raw_node->i);
+       nid_t pino = le32_to_cpu(raw_inode->i_pino);
+       struct f2fs_dir_entry *de;
+@@ -93,8 +92,7 @@ out:
+ static int recover_inode(struct inode *inode, struct page *node_page)
+ {
+-      void *kaddr = page_address(node_page);
+-      struct f2fs_node *raw_node = (struct f2fs_node *)kaddr;
++      struct f2fs_node *raw_node = F2FS_NODE(node_page);
+       struct f2fs_inode *raw_inode = &(raw_node->i);
+       if (!IS_INODE(node_page))
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0512-f2fs-update-file-name-in-the-inode-block-during-f2fs.patch b/patches.tizen/0512-f2fs-update-file-name-in-the-inode-block-during-f2fs.patch
new file mode 100644 (file)
index 0000000..cdd00fb
--- /dev/null
@@ -0,0 +1,85 @@
+From 9c6800136cd4ad62b537340edfd5210f4bb8d197 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Thu, 18 Jul 2013 18:02:31 +0900
+Subject: [PATCH 0512/1302] f2fs: update file name in the inode block during
+ f2fs_rename
+
+The error is reproducible by:
+0. mkfs.f2fs /dev/sdb1 & mount
+1. touch test1
+2. touch test2
+3. mv test1 test2
+4. umount
+5. dumpt.f2fs -i 4 /dev/sdb1
+
+After this, when we retrieve the inode->i_name of test2 by dump.f2fs, we get
+test1 instead of test2.
+This is because f2fs didn't update the file name during the f2fs_rename.
+
+So, this patch fixes that.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/dir.c   | 15 +++++++++++++++
+ fs/f2fs/f2fs.h  |  1 +
+ fs/f2fs/namei.c |  5 +++++
+ 3 files changed, 21 insertions(+)
+
+diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
+index a151f0f..4d96362 100644
+--- a/fs/f2fs/dir.c
++++ b/fs/f2fs/dir.c
+@@ -276,6 +276,21 @@ static void init_dent_inode(const struct qstr *name, struct page *ipage)
+       set_page_dirty(ipage);
+ }
++int update_dent_inode(struct inode *inode, const struct qstr *name)
++{
++      struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
++      struct page *page;
++
++      page = get_node_page(sbi, inode->i_ino);
++      if (IS_ERR(page))
++              return PTR_ERR(page);
++
++      init_dent_inode(name, page);
++      f2fs_put_page(page, 1);
++
++      return 0;
++}
++
+ static int make_empty_dir(struct inode *inode,
+               struct inode *parent, struct page *page)
+ {
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 2dfd584..a6858c7 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -953,6 +953,7 @@ struct f2fs_dir_entry *f2fs_parent_dir(struct inode *, struct page **);
+ ino_t f2fs_inode_by_name(struct inode *, struct qstr *);
+ void f2fs_set_link(struct inode *, struct f2fs_dir_entry *,
+                               struct page *, struct inode *);
++int update_dent_inode(struct inode *, const struct qstr *);
+ int __f2fs_add_link(struct inode *, const struct qstr *, struct inode *);
+ void f2fs_delete_entry(struct f2fs_dir_entry *, struct page *, struct inode *);
+ int f2fs_make_empty(struct inode *, struct inode *);
+diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
+index 64c0716..3297278 100644
+--- a/fs/f2fs/namei.c
++++ b/fs/f2fs/namei.c
+@@ -427,6 +427,11 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
+               if (!new_entry)
+                       goto out_dir;
++              if (update_dent_inode(old_inode, &new_dentry->d_name)) {
++                      f2fs_put_page(new_page, 1);
++                      goto out_dir;
++              }
++
+               f2fs_set_link(new_dir, new_entry, new_page, old_inode);
+               new_inode->i_ctime = CURRENT_TIME;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0513-f2fs-fix-i_name-during-f2fs_sync_file.patch b/patches.tizen/0513-f2fs-fix-i_name-during-f2fs_sync_file.patch
new file mode 100644 (file)
index 0000000..73b476e
--- /dev/null
@@ -0,0 +1,48 @@
+From 80b6c76099b2b0b94eeb82493d99efa69c834614 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Mon, 22 Jul 2013 22:12:56 +0900
+Subject: [PATCH 0513/1302] f2fs: fix i_name during f2fs_sync_file
+
+As similar as the i_pino fix, i_name also should be fixed when i_nlink is 1.
+
+The errorneous scenario is like this.
+
+1. touch test1
+2. link test1 test2
+3. unlink test2
+4. fsync test1
+
+After this, i_name should be test1.
+
+CC: Al Viro <viro@ZenIV.linux.org.uk>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/file.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 65ca3b3..c2deb27 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -112,11 +112,13 @@ static int get_parent_ino(struct inode *inode, nid_t *pino)
+       if (!dentry)
+               return 0;
+-      inode = igrab(dentry->d_parent->d_inode);
+-      dput(dentry);
++      if (update_dent_inode(inode, &dentry->d_name)) {
++              dput(dentry);
++              return 0;
++      }
+-      *pino = inode->i_ino;
+-      iput(inode);
++      *pino = parent_ino(dentry);
++      dput(dentry);
+       return 1;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0514-f2fs-use-seq_puts-seq_putc-rather-than-seq_printf-wh.patch b/patches.tizen/0514-f2fs-use-seq_puts-seq_putc-rather-than-seq_printf-wh.patch
new file mode 100644 (file)
index 0000000..5c0e2ac
--- /dev/null
@@ -0,0 +1,54 @@
+From baf7a99e1282281f4ce49b86f9dcd88f8c2baf3a Mon Sep 17 00:00:00 2001
+From: Gu Zheng <guz.fnst@cn.fujitsu.com>
+Date: Mon, 22 Jul 2013 16:33:32 +0800
+Subject: [PATCH 0514/1302] f2fs: use seq_puts()/seq_putc() rather than
+ seq_printf() where possible
+
+For string without format specifiers, using seq_puts()/seq_putc()
+instead of seq_printf().
+
+Signed-off-by: Gu Zheng <guz.fnst@cn.fujitsu.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/debug.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
+index fd12b7f..a84b0a8 100644
+--- a/fs/f2fs/debug.c
++++ b/fs/f2fs/debug.c
+@@ -253,21 +253,21 @@ static int stat_show(struct seq_file *s, void *v)
+                          si->nats, NM_WOUT_THRESHOLD);
+               seq_printf(s, "  - SITs: %5d\n  - free_nids: %5d\n",
+                          si->sits, si->fnids);
+-              seq_printf(s, "\nDistribution of User Blocks:");
+-              seq_printf(s, " [ valid | invalid | free ]\n");
+-              seq_printf(s, "  [");
++              seq_puts(s, "\nDistribution of User Blocks:");
++              seq_puts(s, " [ valid | invalid | free ]\n");
++              seq_puts(s, "  [");
+               for (j = 0; j < si->util_valid; j++)
+-                      seq_printf(s, "-");
+-              seq_printf(s, "|");
++                      seq_putc(s, '-');
++              seq_putc(s, '|');
+               for (j = 0; j < si->util_invalid; j++)
+-                      seq_printf(s, "-");
+-              seq_printf(s, "|");
++                      seq_putc(s, '-');
++              seq_putc(s, '|');
+               for (j = 0; j < si->util_free; j++)
+-                      seq_printf(s, "-");
+-              seq_printf(s, "]\n\n");
++                      seq_putc(s, '-');
++              seq_puts(s, "]\n\n");
+               seq_printf(s, "SSR: %u blocks in %u segments\n",
+                          si->block_count[SSR], si->segment_count[SSR]);
+               seq_printf(s, "LFS: %u blocks in %u segments\n",
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0515-f2fs-use-list_for_each-rather-than-list_for_each_saf.patch b/patches.tizen/0515-f2fs-use-list_for_each-rather-than-list_for_each_saf.patch
new file mode 100644 (file)
index 0000000..e656609
--- /dev/null
@@ -0,0 +1,39 @@
+From 036c5088f828edbc7871b4e1ff78e7561b20348f Mon Sep 17 00:00:00 2001
+From: Gu Zheng <guz.fnst@cn.fujitsu.com>
+Date: Fri, 19 Jul 2013 16:24:06 +0800
+Subject: [PATCH 0515/1302] f2fs: use list_for_each rather than
+ list_for_each_safe, in remove_orphan_inode()
+
+As we remove the target single node, so list_for_each is enought, in order to
+clean up, we use list_for_each_entry instead.
+
+Signed-off-by: Gu Zheng <guz.fnst@cn.fujitsu.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/checkpoint.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
+index 66a6b85..fe91773 100644
+--- a/fs/f2fs/checkpoint.c
++++ b/fs/f2fs/checkpoint.c
+@@ -237,13 +237,12 @@ out:
+ void remove_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
+ {
+-      struct list_head *this, *next, *head;
++      struct list_head *head;
+       struct orphan_inode_entry *orphan;
+       mutex_lock(&sbi->orphan_inode_mutex);
+       head = &sbi->orphan_inode_list;
+-      list_for_each_safe(this, next, head) {
+-              orphan = list_entry(this, struct orphan_inode_entry, list);
++      list_for_each_entry(orphan, head, list) {
+               if (orphan->ino == ino) {
+                       list_del(&orphan->list);
+                       kmem_cache_free(orphan_entry_slab, orphan);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0516-f2fs-move-bio_private-allocation-out-of-f2fs_bio_all.patch b/patches.tizen/0516-f2fs-move-bio_private-allocation-out-of-f2fs_bio_all.patch
new file mode 100644 (file)
index 0000000..081fcde
--- /dev/null
@@ -0,0 +1,77 @@
+From 68bec2f9295cbbd3623fc52942fb07e2759f535e Mon Sep 17 00:00:00 2001
+From: Gu Zheng <guz.fnst@cn.fujitsu.com>
+Date: Thu, 25 Jul 2013 11:30:01 +0800
+Subject: [PATCH 0516/1302] f2fs: move bio_private allocation out of
+ f2fs_bio_alloc()
+
+bio->bi_private is not always needed. As in the reading data path,
+end_read_io does not need bio_private for further using, so moving
+bio_private allocation out of f2fs_bio_alloc(). Alloc it in the
+submit_write_page(), and ignore it in the f2fs_readpage().
+
+Signed-off-by: Gu Zheng <guz.fnst@cn.fujitsu.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/data.c    |  1 -
+ fs/f2fs/segment.c | 19 +++++++++++--------
+ 2 files changed, 11 insertions(+), 9 deletions(-)
+
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index dc21f9e..317ef26 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -365,7 +365,6 @@ static void read_end_io(struct bio *bio, int err)
+               }
+               unlock_page(page);
+       } while (bvec >= bio->bi_io_vec);
+-      kfree(bio->bi_private);
+       bio_put(bio);
+ }
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index a86d125..9b74ae2 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -611,18 +611,12 @@ static void f2fs_end_io_write(struct bio *bio, int err)
+ struct bio *f2fs_bio_alloc(struct block_device *bdev, int npages)
+ {
+       struct bio *bio;
+-      struct bio_private *priv;
+-retry:
+-      priv = kmalloc(sizeof(struct bio_private), GFP_NOFS);
+-      if (!priv) {
+-              cond_resched();
+-              goto retry;
+-      }
+       /* No failure on bio allocation */
+       bio = bio_alloc(GFP_NOIO, npages);
+       bio->bi_bdev = bdev;
+-      bio->bi_private = priv;
++      bio->bi_private = NULL;
++
+       return bio;
+ }
+@@ -681,8 +675,17 @@ static void submit_write_page(struct f2fs_sb_info *sbi, struct page *page,
+               do_submit_bio(sbi, type, false);
+ alloc_new:
+       if (sbi->bio[type] == NULL) {
++              struct bio_private *priv;
++retry:
++              priv = kmalloc(sizeof(struct bio_private), GFP_NOFS);
++              if (!priv) {
++                      cond_resched();
++                      goto retry;
++              }
++
+               sbi->bio[type] = f2fs_bio_alloc(bdev, max_hw_blocks(sbi));
+               sbi->bio[type]->bi_sector = SECTOR_FROM_BLOCK(sbi, blk_addr);
++              sbi->bio[type]->bi_private = priv;
+               /*
+                * The end_io will be assigned at the sumbission phase.
+                * Until then, let bio_add_page() merge consecutive IOs as much
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0517-f2fs-fix-handling-orphan-inodes.patch b/patches.tizen/0517-f2fs-fix-handling-orphan-inodes.patch
new file mode 100644 (file)
index 0000000..01eaf95
--- /dev/null
@@ -0,0 +1,165 @@
+From 99d07ec7f4d6f77f5eeb4507243432d6df72c067 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Date: Tue, 30 Jul 2013 11:36:53 +0900
+Subject: [PATCH 0517/1302] f2fs: fix handling orphan inodes
+
+This patch fixes mishandling of the sbi->n_orphans variable.
+
+If users request lots of f2fs_unlink(), check_orphan_space() could be contended.
+In such the case, sbi->n_orphans can be read incorrectly so that f2fs_unlink()
+would fall into the wrong state which results in the failure of
+add_orphan_inode().
+
+So, let's increment sbi->n_orphans virtually prior to the actual orphan inode
+stuffs. After that, let's release sbi->n_orphans by calling release_orphan_inode
+or remove_orphan_inode.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/f2fs/checkpoint.c | 13 ++++++++++---
+ fs/f2fs/dir.c        |  2 ++
+ fs/f2fs/f2fs.h       |  3 ++-
+ fs/f2fs/namei.c      | 19 ++++++++++++++-----
+ 4 files changed, 28 insertions(+), 9 deletions(-)
+
+diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
+index fe91773..c5a5c39 100644
+--- a/fs/f2fs/checkpoint.c
++++ b/fs/f2fs/checkpoint.c
+@@ -182,7 +182,7 @@ const struct address_space_operations f2fs_meta_aops = {
+       .set_page_dirty = f2fs_set_meta_page_dirty,
+ };
+-int check_orphan_space(struct f2fs_sb_info *sbi)
++int acquire_orphan_inode(struct f2fs_sb_info *sbi)
+ {
+       unsigned int max_orphans;
+       int err = 0;
+@@ -197,10 +197,19 @@ int check_orphan_space(struct f2fs_sb_info *sbi)
+       mutex_lock(&sbi->orphan_inode_mutex);
+       if (sbi->n_orphans >= max_orphans)
+               err = -ENOSPC;
++      else
++              sbi->n_orphans++;
+       mutex_unlock(&sbi->orphan_inode_mutex);
+       return err;
+ }
++void release_orphan_inode(struct f2fs_sb_info *sbi)
++{
++      mutex_lock(&sbi->orphan_inode_mutex);
++      sbi->n_orphans--;
++      mutex_unlock(&sbi->orphan_inode_mutex);
++}
++
+ void add_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
+ {
+       struct list_head *head, *this;
+@@ -229,8 +238,6 @@ retry:
+               list_add(&new->list, this->prev);
+       else
+               list_add_tail(&new->list, head);
+-
+-      sbi->n_orphans++;
+ out:
+       mutex_unlock(&sbi->orphan_inode_mutex);
+ }
+diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
+index 4d96362..ecf0fde 100644
+--- a/fs/f2fs/dir.c
++++ b/fs/f2fs/dir.c
+@@ -572,6 +572,8 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
+               if (inode->i_nlink == 0)
+                       add_orphan_inode(sbi, inode->i_ino);
++              else
++                      release_orphan_inode(sbi);
+       }
+       if (bit_pos == NR_DENTRY_IN_BLOCK) {
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index a6858c7..78777cd 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -1044,7 +1044,8 @@ void destroy_segment_manager(struct f2fs_sb_info *);
+ struct page *grab_meta_page(struct f2fs_sb_info *, pgoff_t);
+ struct page *get_meta_page(struct f2fs_sb_info *, pgoff_t);
+ long sync_meta_pages(struct f2fs_sb_info *, enum page_type, long);
+-int check_orphan_space(struct f2fs_sb_info *);
++int acquire_orphan_inode(struct f2fs_sb_info *);
++void release_orphan_inode(struct f2fs_sb_info *);
+ void add_orphan_inode(struct f2fs_sb_info *, nid_t);
+ void remove_orphan_inode(struct f2fs_sb_info *, nid_t);
+ int recover_orphan_inodes(struct f2fs_sb_info *);
+diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
+index 3297278..4e47518 100644
+--- a/fs/f2fs/namei.c
++++ b/fs/f2fs/namei.c
+@@ -239,7 +239,7 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry)
+       if (!de)
+               goto fail;
+-      err = check_orphan_space(sbi);
++      err = acquire_orphan_inode(sbi);
+       if (err) {
+               kunmap(page);
+               f2fs_put_page(page, 0);
+@@ -393,7 +393,7 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
+       struct inode *old_inode = old_dentry->d_inode;
+       struct inode *new_inode = new_dentry->d_inode;
+       struct page *old_dir_page;
+-      struct page *old_page;
++      struct page *old_page, *new_page;
+       struct f2fs_dir_entry *old_dir_entry = NULL;
+       struct f2fs_dir_entry *old_entry;
+       struct f2fs_dir_entry *new_entry;
+@@ -415,7 +415,6 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
+       ilock = mutex_lock_op(sbi);
+       if (new_inode) {
+-              struct page *new_page;
+               err = -ENOTEMPTY;
+               if (old_dir_entry && !f2fs_empty_dir(new_inode))
+@@ -427,9 +426,13 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
+               if (!new_entry)
+                       goto out_dir;
++              err = acquire_orphan_inode(sbi);
++              if (err)
++                      goto put_out_dir;
++
+               if (update_dent_inode(old_inode, &new_dentry->d_name)) {
+-                      f2fs_put_page(new_page, 1);
+-                      goto out_dir;
++                      release_orphan_inode(sbi);
++                      goto put_out_dir;
+               }
+               f2fs_set_link(new_dir, new_entry, new_page, old_inode);
+@@ -438,8 +441,12 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
+               if (old_dir_entry)
+                       drop_nlink(new_inode);
+               drop_nlink(new_inode);
++
+               if (!new_inode->i_nlink)
+                       add_orphan_inode(sbi, new_inode->i_ino);
++              else
++                      release_orphan_inode(sbi);
++
+               update_inode_page(new_inode);
+       } else {
+               err = f2fs_add_link(new_dentry, old_inode);
+@@ -472,6 +479,8 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
+       mutex_unlock_op(sbi, ilock);
+       return 0;
++put_out_dir:
++      f2fs_put_page(new_page, 1);
+ out_dir:
+       if (old_dir_entry) {
+               kunmap(old_dir_page);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0518-mmc-dw_mmc-add-the-specified-capabilities2-of-the-co.patch b/patches.tizen/0518-mmc-dw_mmc-add-the-specified-capabilities2-of-the-co.patch
new file mode 100644 (file)
index 0000000..eb1e3d3
--- /dev/null
@@ -0,0 +1,52 @@
+From 19e7236a5f3561f74d13bc1272b212f9cd16d22f Mon Sep 17 00:00:00 2001
+From: Jaehoon Chung <jh80.chung@samsung.com>
+Date: Thu, 1 Aug 2013 22:37:29 +0900
+Subject: [PATCH 0518/1302] mmc: dw_mmc: add the specified capabilities2 of the
+ controller
+
+Add the capabilities2 of controller to use *_CAP2_*
+
+Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mmc/host/dw_mmc.c | 3 +++
+ drivers/mmc/host/dw_mmc.h | 2 ++
+ 2 files changed, 5 insertions(+)
+
+diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
+index ee5f167..564c9fb 100644
+--- a/drivers/mmc/host/dw_mmc.c
++++ b/drivers/mmc/host/dw_mmc.c
+@@ -1951,6 +1951,9 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
+       if (host->pdata->caps2)
+               mmc->caps2 = host->pdata->caps2;
++      if (drv_data && drv_data->caps2)
++              mmc->caps2 |= drv_data->caps2[ctrl_id];
++
+       if (host->pdata->get_bus_wd)
+               bus_width = host->pdata->get_bus_wd(slot->id);
+       else if (host->dev->of_node)
+diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
+index 2f52c87..90e2bab 100644
+--- a/drivers/mmc/host/dw_mmc.h
++++ b/drivers/mmc/host/dw_mmc.h
+@@ -185,6 +185,7 @@ extern int dw_mci_resume(struct dw_mci *host);
+ /**
+  * dw_mci driver data - dw-mshc implementation specific driver data.
+  * @caps: mmc subsystem specified capabilities of the controller(s).
++ * @caps2: mmc subsystem specified capabilities2 of the controller(s).
+  * @init: early implementation specific initialization.
+  * @setup_clock: implementation specific clock configuration.
+  * @prepare_command: handle CMD register extensions.
+@@ -197,6 +198,7 @@ extern int dw_mci_resume(struct dw_mci *host);
+  */
+ struct dw_mci_drv_data {
+       unsigned long   *caps;
++      unsigned long   *caps2;
+       int             (*init)(struct dw_mci *host);
+       int             (*setup_clock)(struct dw_mci *host);
+       void            (*prepare_command)(struct dw_mci *host, u32 *cmdr);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0519-mmc-dw_mmc-exynos-supporte-the-packed-command.patch b/patches.tizen/0519-mmc-dw_mmc-exynos-supporte-the-packed-command.patch
new file mode 100644 (file)
index 0000000..60f6513
--- /dev/null
@@ -0,0 +1,34 @@
+From 5a80faf7024655a942e7d45f56e5937936f72657 Mon Sep 17 00:00:00 2001
+From: Jaehoon Chung <jh80.chung@samsung.com>
+Date: Thu, 1 Aug 2013 22:39:50 +0900
+Subject: [PATCH 0519/1302] mmc: dw_mmc-exynos: supporte the packed command
+
+To increase the performance, use the packed command
+
+Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mmc/host/dw_mmc-exynos.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c
+index f013e7e..1d0291b 100644
+--- a/drivers/mmc/host/dw_mmc-exynos.c
++++ b/drivers/mmc/host/dw_mmc-exynos.c
+@@ -161,8 +161,13 @@ static unsigned long exynos_dwmmc_caps[4] = {
+       MMC_CAP_CMD23,
+ };
++static unsigned long exynos_dwmmc_caps2[4] = {
++      MMC_CAP2_PACKED_CMD,
++};
++
+ static const struct dw_mci_drv_data exynos_drv_data = {
+       .caps                   = exynos_dwmmc_caps,
++      .caps2                  = exynos_dwmmc_caps2,
+       .init                   = dw_mci_exynos_priv_init,
+       .setup_clock            = dw_mci_exynos_setup_clock,
+       .prepare_command        = dw_mci_exynos_prepare_command,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0520-DT-support-l5f31188-panel.patch b/patches.tizen/0520-DT-support-l5f31188-panel.patch
new file mode 100644 (file)
index 0000000..7726f0a
--- /dev/null
@@ -0,0 +1,803 @@
+From b69d765492aba2f8c58acc25cf34956dc0a0f584 Mon Sep 17 00:00:00 2001
+From: Hyungwon Hwang <human.hwang@samsung.com>
+Date: Fri, 2 Aug 2013 17:09:48 +0900
+Subject: [PATCH 0520/1302] DT: support l5f31188 panel
+
+Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-redwoodlte.dts |  55 +++
+ arch/arm/configs/tizen_defconfig            |   1 +
+ drivers/video/display/Kconfig               |   5 +
+ drivers/video/display/Makefile              |   1 +
+ drivers/video/display/panel-l5f31188.c      | 674 ++++++++++++++++++++++++++++
+ 5 files changed, 736 insertions(+)
+ create mode 100644 drivers/video/display/panel-l5f31188.c
+
+diff --git a/arch/arm/boot/dts/exynos4412-redwoodlte.dts b/arch/arm/boot/dts/exynos4412-redwoodlte.dts
+index 86fa455..a846ea9 100644
+--- a/arch/arm/boot/dts/exynos4412-redwoodlte.dts
++++ b/arch/arm/boot/dts/exynos4412-redwoodlte.dts
+@@ -574,6 +574,61 @@
+               regulator-always-on;
+       };
++      fimd0_lcd: panel {
++              compatible = "samsung,l5f31188";
++              width = <720>;
++              height = <1280>;
++              reset-gpio = <&gpf2 1 0>;
++              reset-delay1 = <15>;
++              reset-delay2 = <180>;
++              power-on-delay = <120>;
++              power-off-delay1 = <100>;
++              power-off-delay2 = <200>;
++              vdd-supply = <&ldo25_reg>;
++              vddi-supply = <&ldo5_reg>;
++              video-source = <&dsi_0>;
++              samsung,panel-width-mm = <59>; /* FIXME */
++              samsung,panel-height-mm = <105>; /* FIXME */
++
++              display-timings {
++                      native-mode = <&timing0>;
++
++                      timing0: timing-0 {
++                              clock-frequency = <0>;
++                              hactive = <720>;
++                              vactive = <1280>;
++                              hfront-porch = <81>;
++                              hback-porch = <81>;
++                              hsync-len = <27>;
++                              vfront-porch = <11>;
++                              vback-porch = <4>;
++                              vsync-len = <2>;
++                      };
++              };
++      };
++
++      dsi_0: dsi@11C80000 {
++              samsung,pll-stable-time = <500>;
++              samsung,stop-holding-count = <0x7ff>;
++              samsung,bta-timeout = <0xff>;
++              samsung,rx-timeout = <0xffff>;
++              samsung,pll-clk-freq = <24000000>;
++              samsung,cmd-allow = <0xf>;
++              vdd11-supply = <&ldo8_reg>;
++              vdd18-supply = <&ldo10_reg>;
++              status = "okay";
++      };
++
++      fimd@11c00000 {
++              samsung,fimd-display = <&fimd0_lcd>;
++              samsung,fimd-vidout-rgb;
++              samsung,fimd-inv-vclk;
++              samsung,fimd-frame-rate = <60>;
++              samsung,default-window = <3>;
++              samsung,fimd-win-bpp = <32>;
++              status = "okay";
++      };
++
+       vidi {
+               compatible = "samsung,exynos-drm-vidi";
+       };
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index 7bc6e6e..481ffe7 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -2149,6 +2149,7 @@ CONFIG_BACKLIGHT_GENERIC=y
+ CONFIG_DISPLAY_CORE=y
+ CONFIG_DISPLAY_PANEL_S6D6AA1=y
+ CONFIG_DISPLAY_PANEL_S6E8AA0=y
++CONFIG_DISPLAY_PANEL_L5F31188=y
+ CONFIG_DISPLAY_SOURCE_EXYNOS_DSI=y
+ #
+diff --git a/drivers/video/display/Kconfig b/drivers/video/display/Kconfig
+index 49f6dab..f0ab8d2 100644
+--- a/drivers/video/display/Kconfig
++++ b/drivers/video/display/Kconfig
+@@ -13,6 +13,11 @@ config DISPLAY_PANEL_S6E8AA0
+       tristate "S6E8AA0 DSI video mode panel"
+       select OF_VIDEOMODE
++config DISPLAY_PANEL_L5F31188
++      tristate "L5F31188 DSI video mode panel"
++      depends on OF
++      select VIDEOMODE_HELPERS
++
+ config DISPLAY_SOURCE_EXYNOS_DSI
+       tristate "Samsung SoC MIPI DSI Master"
+diff --git a/drivers/video/display/Makefile b/drivers/video/display/Makefile
+index 55ab711..4cfab97 100644
+--- a/drivers/video/display/Makefile
++++ b/drivers/video/display/Makefile
+@@ -1,4 +1,5 @@
+ obj-$(CONFIG_DISPLAY_CORE) += display-core.o
+ obj-$(CONFIG_DISPLAY_PANEL_S6D6AA1) += panel-s6d6aa1.o
+ obj-$(CONFIG_DISPLAY_PANEL_S6E8AA0) += panel-s6e8aa0.o
++obj-$(CONFIG_DISPLAY_PANEL_L5F31188) += panel-l5f31188.o
+ obj-$(CONFIG_DISPLAY_SOURCE_EXYNOS_DSI) += source-exynos_dsi.o
+diff --git a/drivers/video/display/panel-l5f31188.c b/drivers/video/display/panel-l5f31188.c
+new file mode 100644
+index 0000000..4330a68
+--- /dev/null
++++ b/drivers/video/display/panel-l5f31188.c
+@@ -0,0 +1,674 @@
++/*
++ * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved.
++ * Hyungwon Hwang <human.hwang@samsung.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/gpio.h>
++#include <linux/of_gpio.h>
++#include <linux/delay.h>
++#include <linux/lcd.h>
++#include <linux/fb.h>
++#include <linux/platform_device.h>
++#include <linux/regulator/consumer.h>
++
++#include <video/display.h>
++#include <video/mipi_display.h>
++#include <video/videomode.h>
++#include <video/of_videomode.h>
++
++#define NUM_REGULATOR_CONSUMERS       2
++
++#define MIN_BRIGHTNESS                (0)
++#define MAX_BRIGHTNESS                (255)
++
++#define SCAN_FROM_LEFT_TO_RIGHT 0
++#define SCAN_FROM_RIGHT_TO_LEFT 1
++#define SCAN_FROM_TOP_TO_BOTTOM 0
++#define SCAN_FROM_BOTTOM_TO_TOP 1
++
++#define to_panel(p)   container_of(p, struct l5f31188, entity)
++
++enum cabc_mode {
++      CABC_OFF,
++      USER_INTERFACE_IMAGE,
++      STILL_PICTURE,
++      MOVING_IMAGE
++};
++
++struct l5f31188_platform_data {
++      unsigned long width;            /* Panel width in mm */
++      unsigned long height;           /* Panel height in mm */
++      struct videomode mode;
++
++      /* time needed while resetting */
++      unsigned int reset_delay1;
++
++      /* time needed after reset */
++      unsigned int reset_delay2;
++
++      /* stable time needing to become panel power on. */
++      unsigned int power_on_delay;
++
++      /* time needed after display off */
++      unsigned int power_off_delay1;
++
++      /* time needed after sleep off */
++      unsigned int power_off_delay2;
++};
++
++struct l5f31188 {
++      struct display_entity entity;
++      struct device *dev;
++
++      struct l5f31188_platform_data *pdata;
++      struct backlight_device *bd;
++      struct regulator_bulk_data regs[NUM_REGULATOR_CONSUMERS];
++
++      unsigned int power;
++      enum cabc_mode cabc_mode;
++
++      unsigned int reset_gpio;
++};
++
++static void l5f31188_delay(unsigned int msecs)
++{
++      /* refer from documentation/timers/timers-howto.txt */
++      if (msecs < 20)
++              usleep_range(msecs * 1000, (msecs + 1) * 1000);
++      else
++              msleep(msecs);
++}
++
++static void l5f31188_sleep_in(struct video_source *source)
++{
++
++      const unsigned char data_to_send[] = {
++              0x10, 0x00
++      };
++      dsi_dcs_write(source, 0,
++                      data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void l5f31188_sleep_out(struct video_source *source)
++{
++      const unsigned char data_to_send[] = {
++              0x11, 0x00
++      };
++      dsi_dcs_write(source, 0,
++                      data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void l5f31188_set_gamma(struct video_source *source)
++{
++      const unsigned char data_to_send[] = {
++              0x26, 0x00
++      };
++      dsi_dcs_write(source, 0,
++                      data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void l5f31188_display_off(struct video_source *source)
++{
++      const unsigned char data_to_send[] = {
++              0x28, 0x00
++      };
++      dsi_dcs_write(source, 0,
++                      data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void l5f31188_display_on(struct video_source *source)
++{
++      const unsigned char data_to_send[] = {
++              0x29, 0x00
++      };
++      dsi_dcs_write(source, 0,
++                      data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void l5f31188_ctl_memory_access(struct video_source *source,
++              int h_direction, int v_direction)
++{
++      const unsigned char data_to_send[] = {
++              0x36, ((h_direction & 0x1) << 1) | (v_direction & 0x1)
++      };
++      dsi_dcs_write(source, 0,
++                      data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void l5f31188_set_pixel_format(struct video_source *source)
++{
++      const unsigned char data_to_send[] = {
++              0x3A, 0x70
++      };
++      dsi_dcs_write(source, 0,
++                      data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void l5f31188_write_disbv(struct video_source *source,
++              unsigned int brightness)
++{
++      const unsigned char data_to_send[] = {
++              0x51, brightness
++      };
++      dsi_dcs_write(source, 0,
++                      data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void l5f31188_write_ctrld(struct video_source *source)
++{
++      const unsigned char data_to_send[] = {
++              0x53, 0x2C
++      };
++      dsi_dcs_write(source, 0,
++                      data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void l5f31188_write_cabc(struct video_source *source,
++              enum cabc_mode cabc_mode)
++{
++      const unsigned char data_to_send[] = {
++              0x55, cabc_mode
++      };
++      dsi_dcs_write(source, 0,
++                      data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void l5f31188_write_cabcmb(struct video_source *source,
++              unsigned int min_brightness)
++{
++      const unsigned char data_to_send[] = {
++              0x5E, min_brightness
++      };
++      dsi_dcs_write(source, 0,
++                      data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void l5f31188_set_extension(struct video_source *source)
++{
++      const unsigned char data_to_send[] = {
++              0xB9, 0xFF, 0x83, 0x94
++      };
++
++      dsi_dcs_write(source, 0,
++                      data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void l5f31188_set_dgc_lut(struct video_source *source)
++{
++      const unsigned char data_to_send[] = {
++              0xC1, 0x01, 0x00, 0x04, 0x0E, 0x18, 0x1E,
++              0x26, 0x2F, 0x36, 0x3E, 0x47, 0x4E, 0x56,
++              0x5D, 0x65, 0x6D, 0x75, 0x7D, 0x84, 0x8C,
++              0x94, 0x9C, 0xA4, 0xAD, 0xB5, 0xBD, 0xC5,
++              0xCC, 0xD4, 0xDE, 0xE5, 0xEE, 0xF7, 0xFF,
++              0x3F, 0x9A, 0xCE, 0xD4, 0x21, 0xA1, 0x26,
++              0x54, 0x00, 0x00, 0x04, 0x0E, 0x19, 0x1F,
++              0x27, 0x30, 0x37, 0x40, 0x48, 0x50, 0x58,
++              0x60, 0x67, 0x6F, 0x77, 0x7F, 0x87, 0x8F,
++              0x97, 0x9F, 0xA7, 0xB0, 0xB8, 0xC0, 0xC8,
++              0xCE, 0xD8, 0xE0, 0xE7, 0xF0, 0xF7, 0xFF,
++              0x3C, 0xEB, 0xFD, 0x2F, 0x66, 0xA8, 0x2C,
++              0x46, 0x00, 0x00, 0x04, 0x0E, 0x18, 0x1E,
++              0x26, 0x30, 0x38, 0x41, 0x4A, 0x52, 0x5A,
++              0x62, 0x6B, 0x73, 0x7B, 0x83, 0x8C, 0x94,
++              0x9C, 0xA5, 0xAD, 0xB6, 0xBD, 0xC5, 0xCC,
++              0xD4, 0xDD, 0xE3, 0xEB, 0xF2, 0xF9, 0xFF,
++              0x3F, 0xA4, 0x8A, 0x8F, 0xC7, 0x33, 0xF5,
++              0xE9, 0x00
++      };
++      dsi_dcs_write(source, 0,
++                      data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void l5f31188_set_tcon(struct video_source *source)
++{
++      const unsigned char data_to_send[] = {
++              0xC7, 0x00, 0x20
++      };
++      dsi_dcs_write(source, 0,
++                      data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void l5f31188_set_ptba(struct video_source *source)
++{
++      const unsigned char data_to_send[] = {
++              0xBF, 0x06, 0x10
++      };
++      dsi_dcs_write(source, 0,
++                      data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static void l5f31188_set_eco(struct video_source *source)
++{
++      const unsigned char data_to_send[] = {
++              0xC6, 0x0C
++      };
++      dsi_dcs_write(source, 0,
++                      data_to_send, ARRAY_SIZE(data_to_send));
++}
++
++static int l5f31188_get_brightness(struct backlight_device *bd)
++{
++      return bd->props.brightness;
++}
++
++
++static int l5f31188_set_brightness(struct backlight_device *bd)
++{
++      int brightness = bd->props.brightness;
++      struct l5f31188 *panel = bl_get_data(bd);
++      enum display_entity_state state;
++      int ret;
++
++      if (bd->props.power == FB_BLANK_POWERDOWN
++                      || bd->props.state & BL_CORE_SUSPENDED)
++              state = DISPLAY_ENTITY_STATE_OFF;
++      else if (bd->props.power != FB_BLANK_UNBLANK)
++              state = DISPLAY_ENTITY_STATE_STANDBY;
++      else
++              state = DISPLAY_ENTITY_STATE_ON;
++
++      if (panel->power == FB_BLANK_POWERDOWN) {
++              dev_err(panel->dev,
++                              "panel off: brightness set failed.\n");
++              return -EINVAL;
++      }
++
++      if (brightness < 0 || brightness > bd->props.max_brightness) {
++              dev_err(panel->dev, "panel brightness should be 0 to %d.\n",
++                              MAX_BRIGHTNESS);
++              return -EINVAL;
++      }
++
++      ret = display_entity_set_state(&panel->entity, state);
++      if (ret)
++              return ret;
++
++      if (state == DISPLAY_ENTITY_STATE_OFF)
++              return 0;
++
++      l5f31188_write_disbv(panel->entity.source, brightness);
++
++      return 0;
++}
++
++static const struct backlight_ops l5f31188_backlight_ops = {
++      .get_brightness = l5f31188_get_brightness,
++      .update_status = l5f31188_set_brightness,
++};
++
++static void l5f31188_set_sequence(struct l5f31188 *panel)
++{
++      int brightness = panel->bd->props.brightness;
++      struct video_source *source = panel->entity.source;
++
++      l5f31188_set_extension(source);
++      l5f31188_set_dgc_lut(source);
++
++      l5f31188_set_eco(source);
++      l5f31188_set_tcon(source);
++      l5f31188_set_ptba(source);
++      l5f31188_set_gamma(source);
++      l5f31188_ctl_memory_access(source, SCAN_FROM_LEFT_TO_RIGHT,
++                      SCAN_FROM_TOP_TO_BOTTOM);
++      l5f31188_set_pixel_format(source);
++      l5f31188_write_disbv(source, brightness);
++      l5f31188_write_ctrld(source);
++      l5f31188_write_cabc(source, 0x0);
++      l5f31188_write_cabcmb(source, 0x0);
++
++      l5f31188_sleep_out(source);
++      l5f31188_delay(panel->pdata->power_on_delay);
++      l5f31188_display_on(source);
++
++      dev_info(panel->dev, "%s:done.\n", __func__);
++}
++
++#ifdef CONFIG_OF
++static int l5f31188_reset(struct device *dev)
++{
++      struct l5f31188 *panel = dev_get_drvdata(dev);
++
++      gpio_set_value(panel->reset_gpio, 0);
++      l5f31188_delay(panel->pdata->reset_delay1);
++      gpio_set_value(panel->reset_gpio, 1);
++      l5f31188_delay(panel->pdata->reset_delay2);
++
++      return 0;
++}
++
++static struct l5f31188_platform_data *l5f31188_parse_dt(struct l5f31188 *panel)
++{
++      struct device_node *node = panel->dev->of_node;
++      struct l5f31188_platform_data *data;
++      const __be32 *prop_data;
++
++      data = devm_kzalloc(panel->dev, sizeof(*data), GFP_KERNEL);
++      if (!data) {
++              dev_err(panel->dev, "failed to allocate platform data.\n");
++              return NULL;
++      }
++
++      if (of_get_videomode(node, &data->mode, 0)) {
++              dev_err(panel->dev, "failed to read video mode from DT\n");
++              return NULL;
++      }
++
++      panel->reset_gpio = of_get_named_gpio(node, "reset-gpio", 0);
++      if (panel->reset_gpio < 0)
++              return NULL;
++
++      prop_data = of_get_property(node, "width", NULL);
++      if (!prop_data)
++              return NULL;
++      data->width = be32_to_cpu(*prop_data);
++
++      prop_data = of_get_property(node, "height", NULL);
++      if (!prop_data)
++              return NULL;
++      data->height = be32_to_cpu(*prop_data);
++
++      prop_data = of_get_property(node, "reset-delay1", NULL);
++      if (!prop_data)
++              return NULL;
++      data->reset_delay1 = be32_to_cpu(*prop_data);
++
++      prop_data = of_get_property(node, "reset-delay2", NULL);
++      if (!prop_data)
++              return NULL;
++      data->reset_delay2 = be32_to_cpu(*prop_data);
++
++      prop_data = of_get_property(node, "power-on-delay", NULL);
++      if (!prop_data)
++              return NULL;
++      data->power_on_delay = be32_to_cpu(*prop_data);
++
++      prop_data = of_get_property(node, "power-off-delay1", NULL);
++      if (!prop_data)
++              return NULL;
++      data->power_off_delay1 = be32_to_cpu(*prop_data);
++
++      prop_data = of_get_property(node, "power-off-delay2", NULL);
++      if (!prop_data)
++              return NULL;
++      data->power_off_delay2 = be32_to_cpu(*prop_data);
++
++      prop_data = of_get_property(node, "vdd-supply", NULL);
++      if (!prop_data)
++              return NULL;
++
++      return data;
++}
++
++static struct of_device_id l5f31188_of_match[] = {
++      { .compatible = "samsung,l5f31188" },
++      { }
++};
++
++MODULE_DEVICE_TABLE(of, l5f31188_of_match);
++#else
++static struct l5f31188_platform_data *l5f31188_parse_dt(struct l5f31188 *panel)
++{
++      return NULL;
++}
++#endif
++
++static const struct display_entity_interface_params l5f31188_params = {
++      .type = DISPLAY_ENTITY_INTERFACE_DSI,
++      .p.dsi = {
++              .format = DSI_FMT_RGB888,
++              .mode = DSI_MODE_VIDEO | DSI_MODE_VIDEO_BURST
++                      | DSI_MODE_VIDEO_HFP | DSI_MODE_VIDEO_HBP
++                      | DSI_MODE_VIDEO_HSA | DSI_MODE_EOT_PACKET
++                      | DSI_MODE_VSYNC_FLUSH,
++              .data_lanes = 0xf,
++              .hs_clk_freq = 500000000,
++              .esc_clk_freq = 10000000,
++      },
++};
++
++static void l5f31188_power_on(struct l5f31188 *panel)
++{
++      struct video_source *src = panel->entity.source;
++      int ret;
++
++      ret = regulator_bulk_enable(NUM_REGULATOR_CONSUMERS,
++                      panel->regs);
++      if (ret != 0) {
++              dev_err(panel->dev, "failed to enable regulators (%d)\n", ret);
++              return;
++      }
++
++      /* panel reset */
++      l5f31188_reset(panel->dev);
++
++      src->ops.dsi->enable(src);
++
++      l5f31188_set_sequence(panel);
++
++      return;
++}
++
++static void l5f31188_power_off(struct l5f31188 *panel)
++{
++      struct video_source *src = panel->entity.source;
++
++      l5f31188_display_off(src);
++      l5f31188_delay(panel->pdata->power_off_delay1);
++      l5f31188_sleep_in(src);
++      l5f31188_delay(panel->pdata->power_off_delay2);
++
++      src->ops.dsi->disable(src);
++
++      regulator_bulk_disable(NUM_REGULATOR_CONSUMERS,
++                      panel->regs);
++}
++
++static int l5f31188_set_state(struct display_entity *entity,
++              enum display_entity_state state)
++{
++      struct l5f31188 *panel = to_panel(entity);
++      struct video_source *src = panel->entity.source;
++
++      switch (state) {
++      case DISPLAY_ENTITY_STATE_OFF:
++              if (entity->state == DISPLAY_ENTITY_STATE_ON)
++                      src->common_ops->set_stream(src,
++                                      DISPLAY_ENTITY_STREAM_STOPPED);
++
++              l5f31188_power_off(panel);
++              break;
++      case DISPLAY_ENTITY_STATE_ON:
++              if (entity->state == DISPLAY_ENTITY_STATE_OFF)
++                      l5f31188_power_on(panel);
++
++              src->common_ops->set_stream(src,
++                              DISPLAY_ENTITY_STREAM_CONTINUOUS);
++              break;
++      default:
++              break;
++      }
++
++      return 0;
++}
++
++static int l5f31188_get_modes(struct display_entity *entity,
++              const struct videomode **modes)
++{
++      struct l5f31188 *panel = to_panel(entity);
++
++      *modes = &panel->pdata->mode;
++      return 1;
++}
++
++static int l5f31188_get_size(struct display_entity *entity,
++              unsigned int *width, unsigned int *height)
++{
++      struct l5f31188 *panel = to_panel(entity);
++
++      *width = panel->pdata->width;
++      *height = panel->pdata->height;
++      return 0;
++}
++
++static int l5f31188_get_params(struct display_entity *entity,
++              struct display_entity_interface_params *params)
++{
++      *params = l5f31188_params;
++      return 0;
++}
++
++static const struct display_entity_control_ops l5f31188_control_ops = {
++      .set_state = l5f31188_set_state,
++      .get_modes = l5f31188_get_modes,
++      .get_size = l5f31188_get_size,
++      .get_params = l5f31188_get_params,
++};
++
++static void l5f31188_release(struct display_entity *entity)
++{
++      struct l5f31188 *panel = to_panel(entity);
++
++      backlight_device_unregister(panel->bd);
++      regulator_bulk_free(NUM_REGULATOR_CONSUMERS, panel->regs);
++      kfree(panel);
++}
++
++static int l5f31188_probe(struct platform_device *pdev)
++{
++      struct l5f31188 *panel;
++      int ret;
++
++      panel = kzalloc(sizeof(struct l5f31188), GFP_KERNEL);
++      if (!panel) {
++              dev_err(&pdev->dev,
++                              "failed to allocate l5f31188 structure.\n");
++              return -ENOMEM;
++      }
++
++      panel->dev = &pdev->dev;
++      panel->pdata = 
++              (struct l5f31188_platform_data *)pdev->dev.platform_data;
++
++      if (!panel->pdata) {
++              panel->pdata = l5f31188_parse_dt(panel);
++              if (!panel->pdata) {
++                      dev_err(&pdev->dev, "failed to find platform data\n");
++                      return -ENODEV;
++              }
++      }
++
++      panel->regs[0].supply = "vddi";
++      panel->regs[1].supply = "vdd";
++
++      ret = regulator_bulk_get(&pdev->dev, NUM_REGULATOR_CONSUMERS,
++                      panel->regs);
++      if (ret != 0) {
++              dev_err(panel->dev, "failed to get regulators (%d)\n", ret);
++              goto err_regulator_bulk_get;
++      }
++
++      panel->bd = backlight_device_register("l5f31188_bd", &pdev->dev, panel,
++                      &l5f31188_backlight_ops, NULL);
++      if (IS_ERR(panel->bd)) {
++              dev_err(&pdev->dev, "failed to register backlight ops.\n");
++              ret = PTR_ERR(panel->bd);
++              goto err_backlight_register;
++      }
++
++      panel->cabc_mode = CABC_OFF;
++      panel->bd->props.max_brightness = MAX_BRIGHTNESS;
++      panel->bd->props.brightness = MAX_BRIGHTNESS;
++
++      panel->entity.of_node = pdev->dev.of_node;
++      panel->entity.dev = &pdev->dev;
++      panel->entity.release = l5f31188_release;
++      panel->entity.ops = &l5f31188_control_ops;
++
++      platform_set_drvdata(pdev, panel);
++
++      ret = display_entity_register(&panel->entity);
++      if (ret < 0)
++              goto err_display_register;
++
++      display_entity_set_state(&panel->entity, DISPLAY_ENTITY_STATE_ON);
++
++      dev_dbg(&pdev->dev, "probed l5f31188 panel driver.\n");
++
++
++      return 0;
++
++err_display_register:
++      backlight_device_unregister(panel->bd);
++err_backlight_register:
++      regulator_bulk_free(NUM_REGULATOR_CONSUMERS, panel->regs);
++err_regulator_bulk_get:
++      kfree(panel);
++
++      return ret;
++}
++
++static int l5f31188_remove(struct platform_device *pdev)
++{
++      struct l5f31188 *panel = platform_get_drvdata(pdev);
++
++      platform_set_drvdata(pdev, NULL);
++      display_entity_unregister(&panel->entity);
++
++      return 0;
++}
++
++static int l5f31188_suspend(struct device *dev)
++{
++      struct l5f31188 *panel = dev_get_drvdata(dev);
++
++      if (panel->power != FB_BLANK_UNBLANK)
++              return 0;
++
++      return display_entity_set_state(&panel->entity,
++                      DISPLAY_ENTITY_STATE_OFF);
++}
++
++static int l5f31188_resume(struct device *dev)
++{
++      struct l5f31188 *panel = dev_get_drvdata(dev);
++
++      if (panel->power != FB_BLANK_UNBLANK)
++              return 0;
++
++      return display_entity_set_state(&panel->entity,
++                      DISPLAY_ENTITY_STATE_ON);
++}
++
++static const struct dev_pm_ops l5f31188_pm_ops = {
++      SET_SYSTEM_SLEEP_PM_OPS(l5f31188_suspend, l5f31188_resume)
++};
++
++static struct platform_driver l5f31188_driver = {
++      .probe = l5f31188_probe,
++      .remove = l5f31188_remove,
++      .driver = {
++              .name = "panel_l5f31188",
++              .owner = THIS_MODULE,
++              .of_match_table = of_match_ptr(l5f31188_of_match),
++              .pm = &l5f31188_pm_ops,
++      }
++};
++
++module_platform_driver(l5f31188_driver);
++
++MODULE_AUTHOR("Hyungwon Hwang<human.hwang@samsung.com>");
++MODULE_DESCRIPTION("MIPI-DSI based l5f31188 TFT-LCD Panel Driver");
++MODULE_LICENSE("GPL");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0521-ARM-dts-remove-repeated-code-and-bug-fix.patch b/patches.tizen/0521-ARM-dts-remove-repeated-code-and-bug-fix.patch
new file mode 100644 (file)
index 0000000..96e16fb
--- /dev/null
@@ -0,0 +1,750 @@
+From 6424055431eb12477269206e22f048828ee4fd6d Mon Sep 17 00:00:00 2001
+From: Donghwa Lee <dh09.lee@samsung.com>
+Date: Wed, 7 Aug 2013 14:07:29 +0900
+Subject: [PATCH 0521/1302] ARM: dts: remove repeated code and bug fix
+
+This patch removes already defined dts code and include "exynos4412-slp_pq.dts".
+And it is fixed gpio key interrupts.
+
+Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-redwood.dts | 661 +------------------------------
+ 1 file changed, 3 insertions(+), 658 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-redwood.dts b/arch/arm/boot/dts/exynos4412-redwood.dts
+index e3ef5fe..e6f50c9 100644
+--- a/arch/arm/boot/dts/exynos4412-redwood.dts
++++ b/arch/arm/boot/dts/exynos4412-redwood.dts
+@@ -12,71 +12,16 @@
+  * published by the Free Software Foundation.
+ */
+-/dts-v1/;
+-/include/ "exynos4412.dtsi"
++/include/ "exynos4412-slp_pq.dts"
+ / {
+       model = "Samsung Redwood based on Exynos4412";
+       compatible = "samsung,redwood", "samsung,exynos4412";
+-      memory {
+-              reg =  <0x40000000 0x10000000
+-                      0x50000000 0x10000000
+-                      0x60000000 0x10000000
+-                      0x70000000 0x10000000>;
+-
+-              reserved-memory {
+-                      #address-cells = <1>;
+-                      #size-cells = <1>;
+-
+-                      contig_mem: region@71000000 {
+-                              compatible = "linux,contiguous-memory-region";
+-                              reg = <0x71000000 0x0c000000>;
+-                              linux,default-contiguous-region;
+-                      };
+-
+-                      mfc_l_mem: mfc_l_region@43000000 {
+-                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
+-                              reg = <0x43000000 0x1000000>;
+-                      };
+-
+-                      mfc_r_mem: mfc_r_region@51000000 {
+-                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
+-                              reg = <0x51000000 0x1000000>;
+-                      };
+-              };
+-      };
+-
+       chosen {
+               bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rootwait earlyprintk panic=5";
+       };
+-      firmware@0204F000 {
+-              compatible = "samsung,secure-firmware";
+-              reg = <0x0204F000 0x1000>;
+-      };
+-
+-      fixed-rate-clocks {
+-              xxti {
+-                      compatible = "samsung,clock-xxti", "fixed-clock";
+-                      clock-frequency = <0>;
+-              };
+-
+-              xusbxti {
+-                      compatible = "samsung,clock-xusbxti", "fixed-clock";
+-                      clock-frequency = <24000000>;
+-              };
+-      };
+-
+-      vemmc_reg: voltage-regulator@0 {
+-              compatible = "regulator-fixed";
+-              regulator-name = "VMEM_VDD_2.8V";
+-              regulator-min-microvolt = <2800000>;
+-              regulator-max-microvolt = <2800000>;
+-              gpio = <&gpk0 2 0>;
+-              enable-active-high;
+-      };
+-
+       sdhci_emmc: sdhci@12510000 {
+               bus-width = <8>;
+               non-removable;
+@@ -86,29 +31,13 @@
+               status = "okay";
+       };
+-      serial@13800000 {
+-              status = "okay";
+-      };
+-
+-      serial@13810000 {
+-              status = "okay";
+-      };
+-
+-      serial@13820000 {
+-              status = "okay";
+-      };
+-
+-      serial@13830000 {
+-              status = "okay";
+-      };
+-
+       gpio-keys@0 {
+               compatible = "gpio-keys";
+               key@114 {
+                       interrupt-parent = <&gpj1>;
+                       interrupts = <2 0>;
+-                      gpios = <&gpj1 2 1>;
++                      gpios = <&gpx3 3 1>;
+                       linux,code = <114>;
+                       label = "volume down";
+                       debounce-interval = <10>;
+@@ -117,7 +46,7 @@
+               key@115 {
+                       interrupt-parent = <&gpj1>;
+                       interrupts = <1 0>;
+-                      gpios = <&gpj1 1 1>;
++                      gpios = <&gpx2 2 1>;
+                       linux,code = <115>;
+                       label = "volume up";
+                       debounce-interval = <10>;
+@@ -144,431 +73,6 @@
+               };
+       };
+-      i2c_0: i2c@13860000 {
+-              samsung,i2c-sda-delay = <100>;
+-              samsung,i2c-slave-addr = <0x10>;
+-              samsung,i2c-max-bus-freq = <400000>;
+-              pinctrl-0 = <&i2c0_bus>;
+-              pinctrl-names = "default";
+-              status = "okay";
+-
+-              s5c73m3@3c {
+-                      compatible = "samsung,s5c73m3";
+-                      reg = <0x3c>;
+-                      gpios = <&gpm0 1 1>, /* ISP_STANDBY */
+-                              <&gpf1 3 1>; /* ISP_RESET */
+-                      vdd-int-supply = <&buck9_reg>;
+-                      vddio-cis-supply = <&ldo9_reg>;
+-                      vdda-supply = <&ldo17_reg>;
+-                      vddio-host-supply = <&ldo18_reg>;
+-                      vdd-af-supply = <&cam_af_reg>;
+-                      vdd-reg-supply = <&cam_io_reg>;
+-                      clock-frequency = <24000000>;
+-
+-                      port {
+-                              s5c73m3_ep: endpoint {
+-                                      remote-endpoint = <&csis0_ep>;
+-                              };
+-                      };
+-              };
+-      };
+-
+-      i2c@13870000 {
+-              samsung,i2c-sda-delay = <100>;
+-              samsung,i2c-slave-addr = <0x10>;
+-              samsung,i2c-max-bus-freq = <400000>;
+-              pinctrl-0 = <&i2c1_bus>;
+-              pinctrl-names = "default";
+-              status = "okay";
+-
+-              lsm330dlc_gyro@6b {
+-                      compatible = "st,lsm330dlc-gyro";
+-                      reg = <0x6b>;
+-                      irq-map-policy = <1>;
+-                      interrupt-controller;
+-                      #interrups-cells = <2>;
+-                      interrupt-parent = <&lsm330dlc_gyro_map>;
+-                      interrupts= <1 0>;
+-
+-                      lsm330dlc_gyro_map: lsm330dlc-gyro-map {
+-                              compatible = "samsung,lsm330dlc-gyro-map";
+-                              #interrupt-cells = <2>;
+-                              #address-cells = <0>;
+-                              #size-cells = <0>;
+-                              interrupt-map = <0x1 0 &gpf0 3 0>;
+-                      };
+-              };
+-
+-              lsm330dlc_accel@19 {
+-                      compatible = "st,lsm330dlc-accel";
+-                      reg = <0x19>;
+-                      irq-map-policy = <2>;
+-                      interrupt-controller;
+-                      #interrups-cells = <2>;
+-                      interrupt-parent = <&lsm330dlc_accel_map>;
+-                      interrupts= <1 0>;
+-
+-                      lsm330dlc_accel_map: lsm330dlc-accel-map {
+-                              compatible = "samsung,lsm330dlc-accel-map";
+-                              #interrupt-cells = <2>;
+-                              #address-cells = <0>;
+-                              #size-cells = <0>;
+-                              interrupt-map = <0x1 0 &gpx0 0 0>;
+-                      };
+-              };
+-      };
+-
+-      i2c@13890000 {
+-              samsung,i2c-sda-delay = <100>;
+-              samsung,i2c-slave-addr = <0x10>;
+-              samsung,i2c-max-bus-freq = <400000>;
+-              pinctrl-0 = <&i2c3_bus>;
+-              pinctrl-names = "default";
+-              status = "okay";
+-
+-              mms114-touchscreen@48 {
+-                      compatible = "melfas,mms114";
+-                      reg = <0x48>;
+-                      interrupt-parent = <&gpm2>;
+-                      interrupts = <3 2>;
+-                      x-size = <720>;
+-                      y-size = <1280>;
+-                      avdd-supply = <&ldo23_reg>;
+-                      vdd-supply = <&ldo24_reg>;
+-              };
+-      };
+-
+-      i2c@138D0000 {
+-              samsung,i2c-sda-delay = <100>;
+-              samsung,i2c-slave-addr = <0x10>;
+-              samsung,i2c-max-bus-freq = <100000>;
+-              pinctrl-0 = <&i2c7_bus>;
+-              pinctrl-names = "default";
+-              status = "okay";
+-
+-              max77686_pmic@09 {
+-                      compatible = "maxim,max77686";
+-                      interrupt-parent = <&gpx0>;
+-                      interrupts = <7 0>;
+-                      reg = <0x09>;
+-
+-                      voltage-regulators {
+-                              ldo1_reg: ldo@1 {
+-                                      regulator-compatible = "LDO1";
+-                                      regulator-name = "VALIVE_1.0V_AP";
+-                                      regulator-min-microvolt = <1000000>;
+-                                      regulator-max-microvolt = <1000000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo2_reg: ldo@2 {
+-                                      regulator-compatible = "LDO2";
+-                                      regulator-name = "VM1M2_1.2V_AP";
+-                                      regulator-min-microvolt = <1200000>;
+-                                      regulator-max-microvolt = <1200000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo3_reg: ldo@3 {
+-                                      regulator-compatible = "LDO3";
+-                                      regulator-name = "VCC_1.8V_AP";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo4_reg: ldo@4 {
+-                                      regulator-compatible = "LDO4";
+-                                      regulator-name = "VCC_2.8V_AP";
+-                                      regulator-min-microvolt = <2800000>;
+-                                      regulator-max-microvolt = <2800000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo5_reg: ldo@5 {
+-                                      regulator-compatible = "LDO5";
+-                                      regulator-name = "VCC_1.8V_IO";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo6_reg: ldo@6 {
+-                                      regulator-compatible = "LDO6";
+-                                      regulator-name = "VMPLL_1.0V_AP";
+-                                      regulator-min-microvolt = <1000000>;
+-                                      regulator-max-microvolt = <1000000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo7_reg: ldo@7 {
+-                                      regulator-compatible = "LDO7";
+-                                      regulator-name = "VPLL_1.0V_AP";
+-                                      regulator-min-microvolt = <1000000>;
+-                                      regulator-max-microvolt = <1000000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo8_reg: ldo@8 {
+-                                      regulator-compatible = "LDO8";
+-                                      regulator-name = "VMIPI_1.0V";
+-                                      regulator-min-microvolt = <1000000>;
+-                                      regulator-max-microvolt = <1000000>;
+-                              };
+-
+-                              ldo9_reg: ldo@9 {
+-                                      regulator-compatible = "LDO9";
+-                                      regulator-name = "CAM_ISP_MIPI_1.2V";
+-                                      regulator-min-microvolt = <1200000>;
+-                                      regulator-max-microvolt = <1200000>;
+-                              };
+-
+-                              ldo10_reg: ldo@10 {
+-                                      regulator-compatible = "LDO10";
+-                                      regulator-name = "VMIPI_1.8V";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                              };
+-
+-                              ldo11_reg: ldo@11 {
+-                                      regulator-compatible = "LDO11";
+-                                      regulator-name = "VABB1_1.8V";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo12_reg: ldo@12 {
+-                                      regulator-compatible = "LDO12";
+-                                      regulator-name = "VUOTG_3.0V";
+-                                      regulator-min-microvolt = <3000000>;
+-                                      regulator-max-microvolt = <3000000>;
+-                              };
+-
+-                              ldo13_reg: ldo@13 {
+-                                      regulator-compatible = "LDO13";
+-                                      regulator-name = "NFC_AVDD_1.8V";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                              };
+-
+-                              ldo14_reg: ldo@14 {
+-                                      regulator-compatible = "LDO14";
+-                                      regulator-name = "VABB2_1.8V";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo15_reg: ldo@15 {
+-                                      regulator-compatible = "LDO15";
+-                                      regulator-name = "VHSIC_1.0V";
+-                                      regulator-min-microvolt = <1000000>;
+-                                      regulator-max-microvolt = <1000000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo16_reg: ldo@16 {
+-                                      regulator-compatible = "LDO16";
+-                                      regulator-name = "VHSIC_1.8V";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo17_reg: ldo@17 {
+-                                      regulator-compatible = "LDO17";
+-                                      regulator-name = "CAM_SENSOR_CORE_1.2V";
+-                                      regulator-min-microvolt = <1200000>;
+-                                      regulator-max-microvolt = <1200000>;
+-                              };
+-
+-                              ldo18_reg: ldo@18 {
+-                                      regulator-compatible = "LDO18";
+-                                      regulator-name = "CAM_ISP_SENSOR_1.8V";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                              };
+-
+-                              ldo19_reg: ldo@19 {
+-                                      regulator-compatible = "LDO19";
+-                                      regulator-name = "VT_CAM_1.8V";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                              };
+-
+-                              ldo20_reg: ldo@20 {
+-                                      regulator-compatible = "LDO20";
+-                                      regulator-name = "VDDQ_PRE_1.8V";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                              };
+-
+-                              ldo21_reg: ldo@21 {
+-                                      regulator-compatible = "LDO21";
+-                                      regulator-name = "VTF_2.8V";
+-                                      regulator-min-microvolt = <2800000>;
+-                                      regulator-max-microvolt = <2800000>;
+-                              };
+-
+-                              ldo22_reg: ldo@22 {
+-                                      regulator-compatible = "LDO22";
+-                                      regulator-name = "VMEM_VDD_2.8V";
+-                                      regulator-min-microvolt = <2800000>;
+-                                      regulator-max-microvolt = <2800000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo23_reg: ldo@23 {
+-                                      regulator-compatible = "LDO23";
+-                                      regulator-name = "TSP_AVDD_3.3V";
+-                                      regulator-min-microvolt = <3300000>;
+-                                      regulator-max-microvolt = <3300000>;
+-                              };
+-
+-                              ldo24_reg: ldo@24 {
+-                                      regulator-compatible = "LDO24";
+-                                      regulator-name = "VDD_1.8V_TSP";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                              };
+-
+-                              ldo25_reg: ldo@25 {
+-                                      regulator-compatible = "LDO25";
+-                                      regulator-name = "LED_A_2.8V";
+-                                      regulator-min-microvolt = <2800000>;
+-                                      regulator-max-microvolt = <2800000>;
+-                              };
+-
+-                              ldo26_reg: ldo@26 {
+-                                      regulator-compatible = "LDO26";
+-                                      regulator-name = "MOTOR_VCC_3.0V";
+-                                      regulator-min-microvolt = <3000000>;
+-                                      regulator-max-microvolt = <3000000>;
+-                              };
+-
+-                              buck1_reg: buck@1 {
+-                                      regulator-compatible = "BUCK1";
+-                                      regulator-name = "vdd_mif";
+-                                      regulator-min-microvolt = <850000>;
+-                                      regulator-max-microvolt = <1100000>;
+-                                      regulator-always-on;
+-                                      regulator-boot-on;
+-                              };
+-
+-                              buck2_reg: buck@2 {
+-                                      regulator-compatible = "BUCK2";
+-                                      regulator-name = "vdd_arm";
+-                                      regulator-min-microvolt = <850000>;
+-                                      regulator-max-microvolt = <1500000>;
+-                                      regulator-always-on;
+-                                      regulator-boot-on;
+-                              };
+-
+-                              buck3_reg: buck@3 {
+-                                      regulator-compatible = "BUCK3";
+-                                      regulator-name = "vdd_int";
+-                                      regulator-min-microvolt = <850000>;
+-                                      regulator-max-microvolt = <1150000>;
+-                                      regulator-always-on;
+-                                      regulator-boot-on;
+-                              };
+-
+-                              buck4_reg: buck@4 {
+-                                      regulator-compatible = "BUCK4";
+-                                      regulator-name = "vdd_g3d";
+-                                      regulator-min-microvolt = <850000>;
+-                                      regulator-max-microvolt = <1150000>;
+-                                      regulator-boot-on;
+-                              };
+-
+-                              buck5_reg: buck@5 {
+-                                      regulator-compatible = "BUCK5";
+-                                      regulator-name = "VMEM_1.2V_AP";
+-                                      regulator-min-microvolt = <1200000>;
+-                                      regulator-max-microvolt = <1200000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              buck6_reg: buck@6 {
+-                                      regulator-compatible = "BUCK6";
+-                                      regulator-name = "VCC_SUB_1.35V";
+-                                      regulator-min-microvolt = <1350000>;
+-                                      regulator-max-microvolt = <1350000>;
+-                                      regulator-always-on;
+-                              };
+-                              buck7_reg: buck@7 {
+-                                      regulator-compatible = "BUCK7";
+-                                      regulator-name = "VCC_SUB_2.0V";
+-                                      regulator-min-microvolt = <2000000>;
+-                                      regulator-max-microvolt = <2000000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              buck8_reg: buck@8 {
+-                                      regulator-compatible = "BUCK8";
+-                                      regulator-name = "VMEM_VDDF_3.0V";
+-                                      regulator-min-microvolt = <2850000>;
+-                                      regulator-max-microvolt = <2850000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              buck9_reg: buck@9 {
+-                                      regulator-compatible = "BUCK9";
+-                                      regulator-name = "CAM_ISP_CORE_1.2V";
+-                                      regulator-min-microvolt = <1000000>;
+-                                      regulator-max-microvolt = <1200000>;
+-                              };
+-                      };
+-              };
+-      };
+-
+-      i2c_if_pmic: i2c@0 {
+-              compatible = "i2c-gpio";
+-              gpios = <&gpm2 0 0
+-                       &gpm2 1 0
+-                      >;
+-              #address-cells = <1>;
+-              #size-cells = <0>;
+-
+-              max77693@66 {
+-                      compatible = "maxim,max77693";
+-                      interrupt-parent = <&gpx1>;
+-                      interrupts = <5 2>;
+-                      wakeup = <1>;
+-                      reg = <0x66>;
+-
+-                      regulators {
+-                              esafeout@1 {
+-                                      regulator-compatible = "ESAFEOUT1";
+-                                      regulator-name = "ESAFEOUT1";
+-                                      regulator-boot-on;
+-                              };
+-                              esafeout@2 {
+-                                      regulator-compatible = "ESAFEOUT2";
+-                                      regulator-name = "ESAFEOUT2";
+-                              };
+-                              charger@0 {
+-                                      regulator-compatible = "CHARGER";
+-                                      regulator-name = "CHARGER";
+-                                      regulator-min-microamp = <60000>;
+-                                      regulator-max-microamp = <2580000>;
+-                                      regulator-boot-on;
+-                              };
+-                      };
+-                      muic_regs {
+-                              intmask@1 {
+-                                      addr = <0x7>;
+-                                      data = <0x9>;
+-                              };
+-                              intmask@2 {
+-                                      addr = <0x8>;
+-                                      data = <0x1>;
+-                              };
+-                      };
+-              };
+-      };
+-
+       lcd_vdd_reg: voltage-regulator@1 {
+               compatible = "regulator-fixed";
+               regulator-name = "LCD_VDD_5.0V";
+@@ -578,34 +82,6 @@
+               enable-active-high;
+       };
+-      cam_af_reg: voltage-regulator@2 {
+-              compatible = "regulator-fixed";
+-              regulator-name = "CAM_AF";
+-              regulator-min-microvolt = <2800000>;
+-              regulator-max-microvolt = <2800000>;
+-              gpio = <&gpm0 4 0>;
+-              enable-active-high;
+-      };
+-
+-      cam_io_reg: voltage-regulator@3 {
+-              compatible = "regulator-fixed";
+-              regulator-name = "CAM_SENSOR_A";
+-              regulator-min-microvolt = <2800000>;
+-              regulator-max-microvolt = <2800000>;
+-              gpio = <&gpm0 2 0>;
+-              enable-active-high;
+-      };
+-
+-      cam_isp_core_reg: voltage-regulator@4 {
+-              compatible = "regulator-fixed";
+-              regulator-name = "CAM_ISP_CORE_1.2V_EN";
+-              regulator-min-microvolt = <1200000>;
+-              regulator-max-microvolt = <1200000>;
+-              gpio = <&gpm0 3 0>;
+-              enable-active-high;
+-              regulator-always-on;
+-      };
+-
+       fimd0_lcd: panel {
+               compatible = "samsung,s6d6aa1";
+               reset-gpio = <&gpf2 1 0>;
+@@ -658,111 +134,10 @@
+               status = "okay";
+       };
+-      vidi {
+-              compatible = "samsung,exynos-drm-vidi";
+-      };
+-
+-      sysmmu-fimd0 {
+-              mmu-master = <&fimd>;
+-      };
+-
+-      usbphy@125B0000 {
+-              status = "okay";
+-      };
+-
+-      hsotg@12480000 {
+-              status = "okay";
+-              vusb_d-supply = <&ldo15_reg>;
+-              vusb_a-supply = <&ldo12_reg>;
+-      };
+-
+-      spi_1: spi@13930000 {
+-              pinctrl-names = "default";
+-              pinctrl-0 = <&spi1_bus>;
+-              status = "okay";
+-
+-              s5c73m3_spi: s5c73m3 {
+-                      compatible = "samsung,s5c73m3";
+-                      spi-max-frequency = <50000000>;
+-                      reg = <0>;
+-                      controller-data {
+-                              cs-gpio = <&gpb 5 0>;
+-                              samsung,spi-feedback-delay = <2>;
+-                      };
+-              };
+-      };
+-
+-      g2d@10800000 {
+-              status = "okay";
+-      };
+-
+       rotator: rotator@12810000 {
+               status = "okay";
+       };
+-      camera {
+-              status = "okay";
+-
+-              pinctrl-names = "default";
+-              pinctrl-0 = <&cam_port_a_clk_active>;
+-
+-              fimc_0: fimc@11800000 {
+-                      clock-frequency = <176000000>;
+-                      status = "okay";
+-              };
+-
+-              fimc_1: fimc@11810000 {
+-                      clock-frequency = <176000000>;
+-                      status = "okay";
+-              };
+-
+-              fimc_2: fimc@11820000 {
+-                      clock-frequency = <176000000>;
+-                      status = "okay";
+-              };
+-
+-              fimc_3: fimc@11830000 {
+-                      clock-frequency = <176000000>;
+-                      status = "okay";
+-              };
+-
+-              csis_0: csis@11880000 {
+-                      status = "okay";
+-                      vddcore-supply = <&ldo8_reg>;
+-                      vddio-supply = <&ldo10_reg>;
+-                      clock-frequency = <160000000>;
+-                      #address-cells = <1>;
+-                      #size-cells = <0>;
+-
+-                      /* Camera C (3) MIPI CSI-2 (CSIS0) */
+-                      port@3 {
+-                              reg = <3>;
+-                              csis0_ep: endpoint {
+-                                      remote-endpoint = <&s5c73m3_ep>;
+-                                      data-lanes = <1 2 3 4>;
+-                                      samsung,csis-hs-settle = <12>;
+-                              };
+-                      };
+-              };
+-      };
+-
+-      mfc: codec@13400000 {
+-              status = "okay";
+-
+-              memport@0 {
+-                      memory-region = <&mfc_l_mem>;
+-              };
+-
+-              memport@1 {
+-                      memory-region = <&mfc_r_mem>;
+-              };
+-      };
+-
+-      gpu@13000000 {
+-              status = "okay";
+-              vdd_g3d-supply = <&buck4_reg>;
+-      };
+-
+       cpufreq {
+               status = "okay";
+               overclocking = "okay";
+@@ -779,36 +154,6 @@
+       };
+-      modem_if {
+-              compatible = "samsung,modem_if";
+-              reset-req-gpio = <&gpm3 3 0>;
+-              cp-on-gpio = <&gpl2 5 0>;
+-              cp-reset-gpio = <&gpx3 2 0>;
+-              pda-active-gpio = <&gpf1 6 0>;
+-
+-              phone-active-gpio = <&gpx1 6 0>;
+-              cp-dump-int-gpio = <&gpx1 2 0>;
+-
+-              ap-dump-int-gpio = <0>;
+-              flm_uart_sel = <0>;
+-              cp_warm_reset = <0>;
+-              sim_detect = <0>;
+-
+-              link-slavewake-gpio = <&gpx1 0 0>;
+-              link-hostwake-gpio = <&gpx1 1 0>;
+-              link-active-gpio = <&gpf1 1 0>;
+-              link-enable-gpio = <0>;
+-
+-              modem-type = "xmm6262";
+-              link-type = "hsic";
+-              modem-net = "umts";
+-              use-handover = <0>;
+-
+-              pinctrl-names = "default", "active";
+-              pinctrl-0 = <&modem_state_off>;
+-              pinctrl-1 = <&modem_state_active>;
+-      };
+-
+ };
+ &pinctrl_1 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0522-video-display-panel-s6d6aa1-remove-useless-function.patch b/patches.tizen/0522-video-display-panel-s6d6aa1-remove-useless-function.patch
new file mode 100644 (file)
index 0000000..4150547
--- /dev/null
@@ -0,0 +1,63 @@
+From 797340ec41e91170ef1a5b1106944843acc3b564 Mon Sep 17 00:00:00 2001
+From: Donghwa Lee <dh09.lee@samsung.com>
+Date: Wed, 7 Aug 2013 14:20:08 +0900
+Subject: [PATCH 0522/1302] video: display: panel-s6d6aa1: remove useless
+ function.
+
+There is no usage for s6d6aa1_read_id().
+
+Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/video/display/panel-s6d6aa1.c | 22 ----------------------
+ 1 file changed, 22 deletions(-)
+
+diff --git a/drivers/video/display/panel-s6d6aa1.c b/drivers/video/display/panel-s6d6aa1.c
+index 6f6080c..d48f926 100644
+--- a/drivers/video/display/panel-s6d6aa1.c
++++ b/drivers/video/display/panel-s6d6aa1.c
+@@ -128,16 +128,6 @@ static void s6d6aa1_apply_level_2_key(struct s6d6aa1 *lcd)
+               data_to_send, ARRAY_SIZE(data_to_send));
+ }
+-static void s6d6aa1_read_id(struct s6d6aa1 *lcd, u8 *mtp_id)
+-{
+-      dsi_dcs_read(lcd->entity.source, 0,
+-                      0xDA, &mtp_id[0], 1);
+-      dsi_dcs_read(lcd->entity.source, 0,
+-                      0xDB, &mtp_id[1], 1);
+-      dsi_dcs_read(lcd->entity.source, 0,
+-                      0xDC, &mtp_id[2], 1);
+-}
+-
+ static void s6d6aa1_write_ddb(struct s6d6aa1 *lcd)
+ {
+       const unsigned char data_to_send[] = {
+@@ -427,24 +417,12 @@ static const struct backlight_ops s6d6aa1_backlight_ops = {
+ static int s6d6aa1_check_mtp(struct s6d6aa1 *lcd)
+ {
+-      u8 mtp_id[3] = {0, };
+-
+       s6d6aa1_apply_level_1_key(lcd);
+       s6d6aa1_apply_level_2_key(lcd);
+-      s6d6aa1_read_id(lcd, mtp_id);
+-      if (mtp_id[0] == 0x00) {
+-              dev_err(lcd->dev, "read id failed\n");
+-              return -EIO;
+-      }
+-
+       s6d6aa1_register_access_dis_1(lcd);
+       s6d6aa1_register_access_dis_2(lcd);
+-      lcd->ver = mtp_id[1];
+-      dev_info(lcd->dev, "Read ID : 0x%2x, 0x%2x, 0x%2x\n",
+-              mtp_id[0], mtp_id[1], mtp_id[2]);
+-
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0523-ARM-dts-redwood-correct-gpio_key-interrupt-control.patch b/patches.tizen/0523-ARM-dts-redwood-correct-gpio_key-interrupt-control.patch
new file mode 100644 (file)
index 0000000..7df2e23
--- /dev/null
@@ -0,0 +1,41 @@
+From 0b06e781372d4de9367dffa6ea8d1371ba365cec Mon Sep 17 00:00:00 2001
+From: Donghwa Lee <dh09.lee@samsung.com>
+Date: Wed, 7 Aug 2013 16:49:08 +0900
+Subject: [PATCH 0523/1302] ARM: dts: redwood: correct gpio_key interrupt
+ control
+
+Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-redwood.dts | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-redwood.dts b/arch/arm/boot/dts/exynos4412-redwood.dts
+index e6f50c9..b24caa8 100644
+--- a/arch/arm/boot/dts/exynos4412-redwood.dts
++++ b/arch/arm/boot/dts/exynos4412-redwood.dts
+@@ -35,8 +35,8 @@
+               compatible = "gpio-keys";
+               key@114 {
+-                      interrupt-parent = <&gpj1>;
+-                      interrupts = <2 0>;
++                      interrupt-parent = <&gpx3>;
++                      interrupts = <3 0>;
+                       gpios = <&gpx3 3 1>;
+                       linux,code = <114>;
+                       label = "volume down";
+@@ -44,8 +44,8 @@
+               };
+               key@115 {
+-                      interrupt-parent = <&gpj1>;
+-                      interrupts = <1 0>;
++                      interrupt-parent = <&gpx2>;
++                      interrupts = <2 0>;
+                       gpios = <&gpx2 2 1>;
+                       linux,code = <115>;
+                       label = "volume up";
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0524-clk-exynos4-Add-additional-G2D-clocks.patch b/patches.tizen/0524-clk-exynos4-Add-additional-G2D-clocks.patch
new file mode 100644 (file)
index 0000000..288859b
--- /dev/null
@@ -0,0 +1,90 @@
+From f72d2a64e4e227df0df809cae524b41a2ea2418d Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Mon, 10 Jun 2013 17:49:41 +0900
+Subject: [PATCH 0524/1302] clk: exynos4: Add additional G2D clocks
+
+Add G2D clocks for Exynos4x12 SoC and sclk_fimg2d required by G2D
+IP.
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Cc: Thomas Abraham <thomas.abraham@linaro.org>
+Acked-by: Mike Turquette <mturquette@linaro.org>
+Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/devicetree/bindings/clock/exynos4-clock.txt | 3 ++-
+ drivers/clk/samsung/clk-exynos4.c                         | 9 +++++++--
+ 2 files changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/clock/exynos4-clock.txt b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
+index 76feb47..d7a4bc9 100644
+--- a/Documentation/devicetree/bindings/clock/exynos4-clock.txt
++++ b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
+@@ -103,6 +103,7 @@ Exynos4 SoC and this is specified where applicable.
+   sclk_spi0_isp       174     Exynos4x12
+   sclk_spi1_isp       175     Exynos4x12
+   sclk_uart_isp       176     Exynos4x12
++  sclk_fimg2d         177
+             [Peripheral Clock Gates]
+@@ -130,7 +131,7 @@ Exynos4 SoC and this is specified where applicable.
+   smmu_mfcl           274
+   smmu_mfcr           275
+   g3d                 276
+-  g2d                 277     Exynos4210
++  g2d                 277
+   rotator             278     Exynos4210
+   mdma                279     Exynos4210
+   smmu_g2d            280     Exynos4210
+diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
+index f8ff509..ee932d4 100644
+--- a/drivers/clk/samsung/clk-exynos4.c
++++ b/drivers/clk/samsung/clk-exynos4.c
+@@ -154,7 +154,7 @@ enum exynos4_clks {
+       sclk_audio1, sclk_audio2, sclk_spdif, sclk_spi0, sclk_spi1, sclk_spi2,
+       sclk_slimbus, sclk_fimd1, sclk_mipi1, sclk_pcm1, sclk_pcm2, sclk_i2s1,
+       sclk_i2s2, sclk_mipihsi, sclk_mfc, sclk_pcm0, sclk_g3d, sclk_pwm_isp,
+-      sclk_spi0_isp, sclk_spi1_isp, sclk_uart_isp,
++      sclk_spi0_isp, sclk_spi1_isp, sclk_uart_isp, sclk_fimg2d,
+       /* gate clocks */
+       fimc0 = 256, fimc1, fimc2, fimc3, csis0, csis1, jpeg, smmu_fimc0,
+@@ -489,6 +489,9 @@ struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = {
+       MUX(none, "mout_spi0_isp", group1_p4x12, E4X12_SRC_ISP, 4, 4),
+       MUX(none, "mout_spi1_isp", group1_p4x12, E4X12_SRC_ISP, 8, 4),
+       MUX(none, "mout_uart_isp", group1_p4x12, E4X12_SRC_ISP, 12, 4),
++      MUX(none, "mout_g2d0", sclk_ampll_p4210, SRC_DMC, 20, 1),
++      MUX(none, "mout_g2d1", sclk_evpll_p, SRC_DMC, 24, 1),
++      MUX(none, "mout_g2d", mout_g2d_p, SRC_DMC, 28, 1),
+ };
+ /* list of divider clocks supported in all exynos4 soc's */
+@@ -558,7 +561,7 @@ struct samsung_div_clock exynos4_div_clks[] __initdata = {
+ /* list of divider clocks supported in exynos4210 soc */
+ struct samsung_div_clock exynos4210_div_clks[] __initdata = {
+       DIV(aclk200, "aclk200", "mout_aclk200", DIV_TOP, 0, 3),
+-      DIV(none, "div_g2d", "mout_g2d", DIV_IMAGE, 0, 4),
++      DIV(sclk_fimg2d, "sclk_fimg2d", "mout_g2d", DIV_IMAGE, 0, 4),
+       DIV(none, "div_fimd1", "mout_fimd1", E4210_DIV_LCD1, 0, 4),
+       DIV(none, "div_mipi1", "mout_mipi1", E4210_DIV_LCD1, 16, 4),
+       DIV(none, "div_sata", "mout_sata", DIV_FSYS0, 20, 4),
+@@ -592,6 +595,7 @@ struct samsung_div_clock exynos4x12_div_clks[] __initdata = {
+                                               4, 3, CLK_GET_RATE_NOCACHE, 0),
+       DIV_F(div_mcuisp1, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1,
+                                               8, 3, CLK_GET_RATE_NOCACHE, 0),
++      DIV(sclk_fimg2d, "sclk_fimg2d", "mout_g2d", DIV_DMC1, 0, 4),
+ };
+ /* list of gate clocks supported in all exynos4 soc's */
+@@ -917,6 +921,7 @@ struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = {
+                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+       GATE(spi1_isp, "spi1_isp", "aclk200", E4X12_GATE_ISP1, 13,
+                       CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
++      GATE(g2d, "g2d", "aclk200", GATE_IP_DMC, 23, 0, 0),
+ };
+ static struct of_device_id exynos4_clkout_ids[] __initdata = {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0525-dmabuf-sync-add-select-system-call-support.patch b/patches.tizen/0525-dmabuf-sync-add-select-system-call-support.patch
new file mode 100644 (file)
index 0000000..f65cc2f
--- /dev/null
@@ -0,0 +1,166 @@
+From a091524f9feef9d49cefeafabe6951cc96a72be6 Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Fri, 9 Aug 2013 15:38:34 +0900
+Subject: [PATCH 0525/1302] dmabuf-sync: add select system call support.
+
+This patch implements select system call for DMA BUF module
+and adds related codes to dmabuf sync framework.
+
+The purpose of this feature is to wait for the completion of DMA
+or CPU access to a dmabuf without that caller locks the dmabuf
+again after the completion.
+
+This feature is useful when caller wants to be aware of the completion
+of DMA access to a shared dmabuf, and the caller doesn't use interfaces
+for the DMA device driver.
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/base/dma-buf.c      | 48 +++++++++++++++++++++++++++++++++++++++++++++
+ drivers/base/dmabuf-sync.c  | 18 +++++++++++++++++
+ include/linux/dmabuf-sync.h |  5 +++++
+ 3 files changed, 71 insertions(+)
+
+diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
+index e1b8583..53ade7b 100644
+--- a/drivers/base/dma-buf.c
++++ b/drivers/base/dma-buf.c
+@@ -29,6 +29,7 @@
+ #include <linux/export.h>
+ #include <linux/debugfs.h>
+ #include <linux/seq_file.h>
++#include <linux/poll.h>
+ #include <linux/dmabuf-sync.h>
+ static inline int is_dma_buf_file(struct file *);
+@@ -80,6 +81,52 @@ static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma)
+       return dmabuf->ops->mmap(dmabuf, vma);
+ }
++static unsigned int dma_buf_poll(struct file *filp,
++                                      struct poll_table_struct *poll)
++{
++      struct dma_buf *dmabuf;
++      struct dmabuf_sync_reservation *robj;
++      int ret = 0;
++
++      if (!is_dma_buf_file(filp))
++              return POLLERR;
++
++      dmabuf = filp->private_data;
++      if (!dmabuf || !dmabuf->sync)
++              return POLLERR;
++
++      robj = dmabuf->sync;
++
++      mutex_lock(&robj->lock);
++
++      robj->polled = true;
++
++      /*
++       * CPU or DMA access to this buffer has been completed, and
++       * the blocked task has been waked up. Return poll event
++       * so that the task can get out of select().
++       */
++      if (robj->poll_event) {
++              robj->poll_event = false;
++              mutex_unlock(&robj->lock);
++              return POLLIN | POLLOUT;
++      }
++
++      /*
++       * There is no anyone accessing this buffer so just return POLLERR.
++       */
++      if (!robj->locked) {
++              mutex_unlock(&robj->lock);
++              return POLLERR;
++      }
++
++      poll_wait(filp, &robj->poll_wait, poll);
++
++      mutex_unlock(&robj->lock);
++
++      return ret;
++}
++
+ static int dma_buf_lock(struct file *file, int cmd, struct file_lock *fl)
+ {
+       struct dma_buf *dmabuf;
+@@ -115,6 +162,7 @@ static int dma_buf_lock(struct file *file, int cmd, struct file_lock *fl)
+ static const struct file_operations dma_buf_fops = {
+       .release        = dma_buf_release,
+       .mmap           = dma_buf_mmap_internal,
++      .poll           = dma_buf_poll,
+       .lock           = dma_buf_lock,
+ };
+diff --git a/drivers/base/dmabuf-sync.c b/drivers/base/dmabuf-sync.c
+index abfd8e3..dab5b32 100644
+--- a/drivers/base/dmabuf-sync.c
++++ b/drivers/base/dmabuf-sync.c
+@@ -63,6 +63,12 @@ static void dmabuf_sync_timeout_worker(struct work_struct *work)
+                       continue;
+               }
++              if (sobj->robj->polled) {
++                      sobj->robj->poll_event = true;
++                      sobj->robj->polled = false;
++                      wake_up_interruptible(&sobj->robj->poll_wait);
++              }
++
+               if (atomic_add_unless(&sobj->robj->shared_cnt, -1, 1)) {
+                       mutex_unlock(&sobj->robj->lock);
+                       continue;
+@@ -277,6 +283,12 @@ static void dmabuf_sync_unlock_objs(struct dmabuf_sync *sync,
+       list_for_each_entry(sobj, &sync->syncs, head) {
+               mutex_lock(&sobj->robj->lock);
++              if (sobj->robj->polled) {
++                      sobj->robj->poll_event = true;
++                      sobj->robj->polled = false;
++                      wake_up_interruptible(&sobj->robj->poll_wait);
++              }
++
+               if (atomic_add_unless(&sobj->robj->shared_cnt, -1, 1)) {
+                       mutex_unlock(&sobj->robj->lock);
+                       continue;
+@@ -624,6 +636,12 @@ void dmabuf_sync_single_unlock(struct dma_buf *dmabuf)
+       mutex_lock(&robj->lock);
++      if (robj->polled) {
++              robj->poll_event = true;
++              robj->polled = false;
++              wake_up_interruptible(&robj->poll_wait);
++      }
++
+       if (atomic_add_unless(&robj->shared_cnt, -1 , 1)) {
+               mutex_unlock(&robj->lock);
+               dma_buf_put(dmabuf);
+diff --git a/include/linux/dmabuf-sync.h b/include/linux/dmabuf-sync.h
+index d4dcf4f..9a3afc4 100644
+--- a/include/linux/dmabuf-sync.h
++++ b/include/linux/dmabuf-sync.h
+@@ -22,6 +22,9 @@ enum dmabuf_sync_status {
+ struct dmabuf_sync_reservation {
+       struct ww_mutex         sync_lock;
+       struct mutex            lock;
++      wait_queue_head_t       poll_wait;
++      unsigned int            poll_event;
++      unsigned int            polled;
+       atomic_t                shared_cnt;
+       unsigned int            accessed_type;
+       unsigned int            locked;
+@@ -91,6 +94,8 @@ static inline void dmabuf_sync_reservation_init(struct dma_buf *dmabuf)
+       mutex_init(&obj->lock);
+       atomic_set(&obj->shared_cnt, 1);
++
++      init_waitqueue_head(&obj->poll_wait);
+ }
+ static inline void dmabuf_sync_reservation_fini(struct dma_buf *dmabuf)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0526-ARM-tizen_defconfig-enable-mcs_touchkey-config.patch b/patches.tizen/0526-ARM-tizen_defconfig-enable-mcs_touchkey-config.patch
new file mode 100644 (file)
index 0000000..353fa8a
--- /dev/null
@@ -0,0 +1,28 @@
+From 6bd3967d3eccabb347db6b3508ee3d7a1e5c30ab Mon Sep 17 00:00:00 2001
+From: Beomho Seo <beomho.seo@samsung.com>
+Date: Mon, 12 Aug 2013 21:49:36 +0900
+Subject: [PATCH 0526/1302] ARM: tizen_defconfig: enable mcs_touchkey config 
+ enable mcs_touchkey configuration
+
+Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_defconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index 481ffe7..e36edb1 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -1426,7 +1426,7 @@ CONFIG_KEYBOARD_GPIO=y
+ # CONFIG_KEYBOARD_LM8323 is not set
+ # CONFIG_KEYBOARD_LM8333 is not set
+ # CONFIG_KEYBOARD_MAX7359 is not set
+-# CONFIG_KEYBOARD_MCS is not set
++CONFIG_KEYBOARD_MCS=y
+ # CONFIG_KEYBOARD_MPR121 is not set
+ # CONFIG_KEYBOARD_NEWTON is not set
+ # CONFIG_KEYBOARD_OPENCORES is not set
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0527-TRATS2-dts-exynos4412-m0.dts-Add-mcs-touchkey-node.patch b/patches.tizen/0527-TRATS2-dts-exynos4412-m0.dts-Add-mcs-touchkey-node.patch
new file mode 100644 (file)
index 0000000..e2a0acc
--- /dev/null
@@ -0,0 +1,80 @@
+From 0a0f199b3d77d5ee6eab665e03504cdc654aabbd Mon Sep 17 00:00:00 2001
+From: Beomho Seo <beomho.seo@samsung.com>
+Date: Mon, 12 Aug 2013 21:51:45 +0900
+Subject: [PATCH 0527/1302] TRATS2: dts: exynos4412-m0.dts: Add mcs-touchkey
+ node  Support melfas 2 touchkey device for TRATS2 board       Adds also the
+ binding documentation file
+
+Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/input/mcs-touchkey.txt     | 26 ++++++++++++++++++++++
+ arch/arm/boot/dts/exynos4412-m0.dts                | 19 ++++++++++++++++
+ 2 files changed, 45 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/input/mcs-touchkey.txt
+
+diff --git a/Documentation/devicetree/bindings/input/mcs-touchkey.txt b/Documentation/devicetree/bindings/input/mcs-touchkey.txt
+new file mode 100644
+index 0000000..5454541
+--- /dev/null
++++ b/Documentation/devicetree/bindings/input/mcs-touchkey.txt
+@@ -0,0 +1,26 @@
++* mcs_touchkey MELFAS MCS5000/5080 controller
++
++Required properties:
++- compatible: must be "mcs5000_touchkey" or "mcs5080_touchkey"
++- reg : I2C address of the chip
++- interrupts: interrupt to which the chop is connected
++- key_maxval: size of keycode table
++- interrupts: interrupt to which the chip is connected
++- code: key code for this device
++
++Example:
++
++      i2c_touch_key: i2c-gpio-0 {
++             /* ... */
++
++             touch_key@20 {
++                     compatible = "mcs5080_touchkey";
++                     reg = <0x20>;
++                     interrupt-patrent = <gpj0>;
++                     key_maxval = <2>;
++                     linux, code = <0x0000009e
++                                    0x000000a9>;
++             };
++
++             /* ... */
++      };
+diff --git a/arch/arm/boot/dts/exynos4412-m0.dts b/arch/arm/boot/dts/exynos4412-m0.dts
+index 3a43790..fbefee6 100644
+--- a/arch/arm/boot/dts/exynos4412-m0.dts
++++ b/arch/arm/boot/dts/exynos4412-m0.dts
+@@ -71,6 +71,25 @@
+               };
+       };
++      i2c_touch_key: i2c-gpio-3 {
++              compatible = "i2c-gpio";
++              gpios = <&gpl0 2 0>, <&gpl0 1 0>;
++              i2c-gpio,delay-us = <2>;
++              #address-cells = <1>;
++              #size-cells = <0>;
++              status = "okay";
++
++              touch_key@20 {
++                      compatible = "mcs5080_touchkey";
++                      reg = <0x20>;
++                      interrupt-parent = <&gpj0>;
++                      interrupts = <3 0>;
++                      key_maxval = <2>;
++                      linux,code = <0x0000009e        /* KEY_BACK */
++                                    0x000000a9>;      /* KEY_MENU */
++              };
++      };
++
+       camera {
+               status = "okay";
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0528-Input-mcs_touchkey-Add-parse-DT-function-from-device.patch b/patches.tizen/0528-Input-mcs_touchkey-Add-parse-DT-function-from-device.patch
new file mode 100644 (file)
index 0000000..fe5485c
--- /dev/null
@@ -0,0 +1,135 @@
+From a4febffb33f29999ccaeff69ad3ba88fcfedbcaf Mon Sep 17 00:00:00 2001
+From: Beomho Seo <beomho.seo@samsung.com>
+Date: Mon, 12 Aug 2013 22:04:13 +0900
+Subject: [PATCH 0528/1302] Input: mcs_touchkey: Add parse DT function from
+ device tree   Add parse DT function for support mcs touchkey driver
+
+Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/input/keyboard/mcs_touchkey.c | 76 ++++++++++++++++++++++++++++++++---
+ 1 file changed, 71 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/input/keyboard/mcs_touchkey.c b/drivers/input/keyboard/mcs_touchkey.c
+index 7c236f9..9668d3e 100644
+--- a/drivers/input/keyboard/mcs_touchkey.c
++++ b/drivers/input/keyboard/mcs_touchkey.c
+@@ -20,6 +20,8 @@
+ #include <linux/irq.h>
+ #include <linux/slab.h>
+ #include <linux/pm.h>
++#include <linux/of_platform.h>
++#include <linux/of_gpio.h>
+ /* MCS5000 Touchkey */
+ #define MCS5000_TOUCHKEY_STATUS               0x04
+@@ -97,6 +99,60 @@ static irqreturn_t mcs_touchkey_interrupt(int irq, void *dev_id)
+       return IRQ_HANDLED;
+ }
++#ifdef CONFIG_OF
++static struct mcs_platform_data *mcs_touchkey_parse_dt(struct device *dev)
++{
++      struct mcs_platform_data *pdata;
++      struct device_node *np = dev->of_node;
++      unsigned int keymap[2];
++      unsigned int len;
++      int i = 0;
++      const __be32 *prop;
++
++      pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
++      if (!pdata) {
++              dev_err(dev, "Failed to allocate platform data\n");
++              return ERR_PTR(-ENOMEM);
++      }
++
++      prop = of_get_property(np, "linux,code", &len);
++      if (!prop) {
++              dev_err(dev, "Failed to get code\n");
++              return ERR_PTR(-EINVAL);
++      }
++
++      if (len % sizeof(u32)) {
++              dev_err(dev, "Malformed keycode property\n");
++              return ERR_PTR(-EINVAL);
++      }
++
++      pdata->keymap_size = len / sizeof(u32);
++
++      if (of_property_read_u32(np, "key_maxval", &pdata->key_maxval)) {
++              dev_err(dev, "Failed to get key max value data\n");
++              return ERR_PTR(-EINVAL);
++      }
++
++      if (pdata->keymap_size > pdata->key_maxval) {
++              dev_err(dev, "Key map size overflow\n");
++              return ERR_PTR(-EINVAL);
++      }
++
++      for (i = 0; i < pdata->keymap_size; i++) {
++              u32 code = be32_to_cpup(prop + i);
++              keymap[i] = MCS_KEY_MAP(i, code);
++      }
++      pdata->keymap = keymap;
++      return pdata;
++}
++#else
++static inline struct mcs_platform_data *mcs_touchkey_parse_dt
++                                              (struct device *dev)
++{
++      return NULL;
++}
++#endif
++
+ static int mcs_touchkey_probe(struct i2c_client *client,
+               const struct i2c_device_id *id)
+ {
+@@ -108,10 +164,14 @@ static int mcs_touchkey_probe(struct i2c_client *client,
+       int error;
+       int i;
+-      pdata = client->dev.platform_data;
+-      if (!pdata) {
+-              dev_err(&client->dev, "no platform data defined\n");
+-              return -EINVAL;
++      if (&client->dev.of_node)
++              pdata = mcs_touchkey_parse_dt(&client->dev);
++      else
++              pdata = client->dev.platform_data;
++
++      if (IS_ERR(pdata)) {
++              dev_err(&client->dev, "Failed to get platform data\n");
++              return PTR_ERR(pdata);
+       }
+       data = kzalloc(sizeof(struct mcs_touchkey_data) +
+@@ -148,7 +208,7 @@ static int mcs_touchkey_probe(struct i2c_client *client,
+       }
+       dev_info(&client->dev, "Firmware version: %d\n", fw_ver);
+-      input_dev->name = "MELPAS MCS Touchkey";
++      input_dev->name = "MELFAS MCS Touchkey";
+       input_dev->id.bustype = BUS_I2C;
+       input_dev->dev.parent = &client->dev;
+       input_dev->evbit[0] = BIT_MASK(EV_KEY);
+@@ -263,11 +323,17 @@ static const struct i2c_device_id mcs_touchkey_id[] = {
+ };
+ MODULE_DEVICE_TABLE(i2c, mcs_touchkey_id);
++static struct of_device_id mcs_touchkey_dt_match[] = {
++      { .compatible = "mcs5000_touchkey", },
++      { .compatible = "mcs5080_touchkey", },
++};
++
+ static struct i2c_driver mcs_touchkey_driver = {
+       .driver = {
+               .name   = "mcs_touchkey",
+               .owner  = THIS_MODULE,
+               .pm     = &mcs_touchkey_pm_ops,
++              .of_match_table = of_match_ptr(mcs_touchkey_dt_match),
+       },
+       .probe          = mcs_touchkey_probe,
+       .remove         = mcs_touchkey_remove,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0529-debugfs-add-get-set-for-atomic-types.patch b/patches.tizen/0529-debugfs-add-get-set-for-atomic-types.patch
new file mode 100644 (file)
index 0000000..53aa8cd
--- /dev/null
@@ -0,0 +1,132 @@
+From 5c9bf1f913ea0907d5bf9de647882fdb5c513c9c Mon Sep 17 00:00:00 2001
+From: Seth Jennings <sjenning@linux.vnet.ibm.com>
+Date: Mon, 3 Jun 2013 15:33:02 -0500
+Subject: [PATCH 0529/1302] debugfs: add get/set for atomic types
+
+debugfs currently lack the ability to create attributes
+that set/get atomic_t values.
+
+This patch adds support for this through a new
+debugfs_create_atomic_t() function.
+
+Signed-off-by: Seth Jennings <sjenning@linux.vnet.ibm.com>
+Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Mel Gorman <mgorman@suse.de>
+Acked-by: Rik van Riel <riel@redhat.com>
+Acked-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/debugfs/file.c       | 42 ++++++++++++++++++++++++++++++++++++++++++
+ include/linux/debugfs.h |  2 ++
+ lib/fault-inject.c      | 21 ---------------------
+ 3 files changed, 44 insertions(+), 21 deletions(-)
+
+diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
+index c5ca6ae..ff64bcd 100644
+--- a/fs/debugfs/file.c
++++ b/fs/debugfs/file.c
+@@ -21,6 +21,7 @@
+ #include <linux/debugfs.h>
+ #include <linux/io.h>
+ #include <linux/slab.h>
++#include <linux/atomic.h>
+ static ssize_t default_read_file(struct file *file, char __user *buf,
+                                size_t count, loff_t *ppos)
+@@ -403,6 +404,47 @@ struct dentry *debugfs_create_size_t(const char *name, umode_t mode,
+ }
+ EXPORT_SYMBOL_GPL(debugfs_create_size_t);
++static int debugfs_atomic_t_set(void *data, u64 val)
++{
++      atomic_set((atomic_t *)data, val);
++      return 0;
++}
++static int debugfs_atomic_t_get(void *data, u64 *val)
++{
++      *val = atomic_read((atomic_t *)data);
++      return 0;
++}
++DEFINE_SIMPLE_ATTRIBUTE(fops_atomic_t, debugfs_atomic_t_get,
++                      debugfs_atomic_t_set, "%lld\n");
++DEFINE_SIMPLE_ATTRIBUTE(fops_atomic_t_ro, debugfs_atomic_t_get, NULL, "%lld\n");
++DEFINE_SIMPLE_ATTRIBUTE(fops_atomic_t_wo, NULL, debugfs_atomic_t_set, "%lld\n");
++
++/**
++ * debugfs_create_atomic_t - create a debugfs file that is used to read and
++ * write an atomic_t value
++ * @name: a pointer to a string containing the name of the file to create.
++ * @mode: the permission that the file should have
++ * @parent: a pointer to the parent dentry for this file.  This should be a
++ *          directory dentry if set.  If this parameter is %NULL, then the
++ *          file will be created in the root of the debugfs filesystem.
++ * @value: a pointer to the variable that the file should read to and write
++ *         from.
++ */
++struct dentry *debugfs_create_atomic_t(const char *name, umode_t mode,
++                               struct dentry *parent, atomic_t *value)
++{
++      /* if there are no write bits set, make read only */
++      if (!(mode & S_IWUGO))
++              return debugfs_create_file(name, mode, parent, value,
++                                      &fops_atomic_t_ro);
++      /* if there are no read bits set, make write only */
++      if (!(mode & S_IRUGO))
++              return debugfs_create_file(name, mode, parent, value,
++                                      &fops_atomic_t_wo);
++
++      return debugfs_create_file(name, mode, parent, value, &fops_atomic_t);
++}
++EXPORT_SYMBOL_GPL(debugfs_create_atomic_t);
+ static ssize_t read_file_bool(struct file *file, char __user *user_buf,
+                             size_t count, loff_t *ppos)
+diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h
+index 63f2465..d68b4ea 100644
+--- a/include/linux/debugfs.h
++++ b/include/linux/debugfs.h
+@@ -79,6 +79,8 @@ struct dentry *debugfs_create_x64(const char *name, umode_t mode,
+                                 struct dentry *parent, u64 *value);
+ struct dentry *debugfs_create_size_t(const char *name, umode_t mode,
+                                    struct dentry *parent, size_t *value);
++struct dentry *debugfs_create_atomic_t(const char *name, umode_t mode,
++                                   struct dentry *parent, atomic_t *value);
+ struct dentry *debugfs_create_bool(const char *name, umode_t mode,
+                                 struct dentry *parent, u32 *value);
+diff --git a/lib/fault-inject.c b/lib/fault-inject.c
+index c5c7a76..d7d501e 100644
+--- a/lib/fault-inject.c
++++ b/lib/fault-inject.c
+@@ -182,27 +182,6 @@ static struct dentry *debugfs_create_stacktrace_depth(
+ #endif /* CONFIG_FAULT_INJECTION_STACKTRACE_FILTER */
+-static int debugfs_atomic_t_set(void *data, u64 val)
+-{
+-      atomic_set((atomic_t *)data, val);
+-      return 0;
+-}
+-
+-static int debugfs_atomic_t_get(void *data, u64 *val)
+-{
+-      *val = atomic_read((atomic_t *)data);
+-      return 0;
+-}
+-
+-DEFINE_SIMPLE_ATTRIBUTE(fops_atomic_t, debugfs_atomic_t_get,
+-                      debugfs_atomic_t_set, "%lld\n");
+-
+-static struct dentry *debugfs_create_atomic_t(const char *name, umode_t mode,
+-                              struct dentry *parent, atomic_t *value)
+-{
+-      return debugfs_create_file(name, mode, parent, value, &fops_atomic_t);
+-}
+-
+ struct dentry *fault_create_debugfs_attr(const char *name,
+                       struct dentry *parent, struct fault_attr *attr)
+ {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0530-zbud-add-to-mm.patch b/patches.tizen/0530-zbud-add-to-mm.patch
new file mode 100644 (file)
index 0000000..06651a2
--- /dev/null
@@ -0,0 +1,660 @@
+From 5e527277e53cf2176189ad2288c1258763927fff Mon Sep 17 00:00:00 2001
+From: Seth Jennings <sjenning@linux.vnet.ibm.com>
+Date: Wed, 10 Jul 2013 16:04:55 -0700
+Subject: [PATCH 0530/1302] zbud: add to mm/
+
+zbud is an special purpose allocator for storing compressed pages.  It
+is designed to store up to two compressed pages per physical page.
+While this design limits storage density, it has simple and
+deterministic reclaim properties that make it preferable to a higher
+density approach when reclaim will be used.
+
+zbud works by storing compressed pages, or "zpages", together in pairs
+in a single memory page called a "zbud page".  The first buddy is "left
+justifed" at the beginning of the zbud page, and the last buddy is
+"right justified" at the end of the zbud page.  The benefit is that if
+either buddy is freed, the freed buddy space, coalesced with whatever
+slack space that existed between the buddies, results in the largest
+possible free region within the zbud page.
+
+zbud also provides an attractive lower bound on density.  The ratio of
+zpages to zbud pages can not be less than 1.  This ensures that zbud can
+never "do harm" by using more pages to store zpages than the
+uncompressed zpages would have used on their own.
+
+This implementation is a rewrite of the zbud allocator internally used
+by zcache in the driver/staging tree.  The rewrite was necessary to
+remove some of the zcache specific elements that were ingrained
+throughout and provide a generic allocation interface that can later be
+used by zsmalloc and others.
+
+This patch adds zbud to mm/ for later use by zswap.
+
+Signed-off-by: Seth Jennings <sjenning@linux.vnet.ibm.com>
+Acked-by: Rik van Riel <riel@redhat.com>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Nitin Gupta <ngupta@vflare.org>
+Cc: Minchan Kim <minchan@kernel.org>
+Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Cc: Dan Magenheimer <dan.magenheimer@oracle.com>
+Cc: Robert Jennings <rcj@linux.vnet.ibm.com>
+Cc: Jenifer Hopper <jhopper@us.ibm.com>
+Cc: Mel Gorman <mgorman@suse.de>
+Cc: Johannes Weiner <jweiner@redhat.com>
+Cc: Larry Woodman <lwoodman@redhat.com>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Cc: Dave Hansen <dave@sr71.net>
+Cc: Joe Perches <joe@perches.com>
+Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
+Cc: Cody P Schafer <cody@linux.vnet.ibm.com>
+Cc: Hugh Dickens <hughd@google.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Bob Liu <bob.liu@oracle.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+
+Conflicts:
+
+       mm/Kconfig
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/zbud.h |  22 +++
+ mm/Kconfig           |  10 +
+ mm/Makefile          |   1 +
+ mm/zbud.c            | 527 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 560 insertions(+)
+ create mode 100644 include/linux/zbud.h
+ create mode 100644 mm/zbud.c
+
+diff --git a/include/linux/zbud.h b/include/linux/zbud.h
+new file mode 100644
+index 0000000..2571a5c
+--- /dev/null
++++ b/include/linux/zbud.h
+@@ -0,0 +1,22 @@
++#ifndef _ZBUD_H_
++#define _ZBUD_H_
++
++#include <linux/types.h>
++
++struct zbud_pool;
++
++struct zbud_ops {
++      int (*evict)(struct zbud_pool *pool, unsigned long handle);
++};
++
++struct zbud_pool *zbud_create_pool(gfp_t gfp, struct zbud_ops *ops);
++void zbud_destroy_pool(struct zbud_pool *pool);
++int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
++      unsigned long *handle);
++void zbud_free(struct zbud_pool *pool, unsigned long handle);
++int zbud_reclaim_page(struct zbud_pool *pool, unsigned int retries);
++void *zbud_map(struct zbud_pool *pool, unsigned long handle);
++void zbud_unmap(struct zbud_pool *pool, unsigned long handle);
++u64 zbud_get_pool_size(struct zbud_pool *pool);
++
++#endif /* _ZBUD_H_ */
+diff --git a/mm/Kconfig b/mm/Kconfig
+index e742d06..3367ac3 100644
+--- a/mm/Kconfig
++++ b/mm/Kconfig
+@@ -477,3 +477,13 @@ config FRONTSWAP
+         and swap data is stored as normal on the matching swap device.
+         If unsure, say Y to enable frontswap.
++
++config ZBUD
++      tristate
++      default n
++      help
++        A special purpose allocator for storing compressed pages.
++        It is designed to store up to two compressed pages per physical
++        page.  While this design limits storage density, it has simple and
++        deterministic reclaim properties that make it preferable to a higher
++        density approach when reclaim will be used.
+diff --git a/mm/Makefile b/mm/Makefile
+index 72c5acb..95f0197 100644
+--- a/mm/Makefile
++++ b/mm/Makefile
+@@ -58,3 +58,4 @@ obj-$(CONFIG_DEBUG_KMEMLEAK) += kmemleak.o
+ obj-$(CONFIG_DEBUG_KMEMLEAK_TEST) += kmemleak-test.o
+ obj-$(CONFIG_CLEANCACHE) += cleancache.o
+ obj-$(CONFIG_MEMORY_ISOLATION) += page_isolation.o
++obj-$(CONFIG_ZBUD)    += zbud.o
+diff --git a/mm/zbud.c b/mm/zbud.c
+new file mode 100644
+index 0000000..9bb4710
+--- /dev/null
++++ b/mm/zbud.c
+@@ -0,0 +1,527 @@
++/*
++ * zbud.c
++ *
++ * Copyright (C) 2013, Seth Jennings, IBM
++ *
++ * Concepts based on zcache internal zbud allocator by Dan Magenheimer.
++ *
++ * zbud is an special purpose allocator for storing compressed pages.  Contrary
++ * to what its name may suggest, zbud is not a buddy allocator, but rather an
++ * allocator that "buddies" two compressed pages together in a single memory
++ * page.
++ *
++ * While this design limits storage density, it has simple and deterministic
++ * reclaim properties that make it preferable to a higher density approach when
++ * reclaim will be used.
++ *
++ * zbud works by storing compressed pages, or "zpages", together in pairs in a
++ * single memory page called a "zbud page".  The first buddy is "left
++ * justifed" at the beginning of the zbud page, and the last buddy is "right
++ * justified" at the end of the zbud page.  The benefit is that if either
++ * buddy is freed, the freed buddy space, coalesced with whatever slack space
++ * that existed between the buddies, results in the largest possible free region
++ * within the zbud page.
++ *
++ * zbud also provides an attractive lower bound on density. The ratio of zpages
++ * to zbud pages can not be less than 1.  This ensures that zbud can never "do
++ * harm" by using more pages to store zpages than the uncompressed zpages would
++ * have used on their own.
++ *
++ * zbud pages are divided into "chunks".  The size of the chunks is fixed at
++ * compile time and determined by NCHUNKS_ORDER below.  Dividing zbud pages
++ * into chunks allows organizing unbuddied zbud pages into a manageable number
++ * of unbuddied lists according to the number of free chunks available in the
++ * zbud page.
++ *
++ * The zbud API differs from that of conventional allocators in that the
++ * allocation function, zbud_alloc(), returns an opaque handle to the user,
++ * not a dereferenceable pointer.  The user must map the handle using
++ * zbud_map() in order to get a usable pointer by which to access the
++ * allocation data and unmap the handle with zbud_unmap() when operations
++ * on the allocation data are complete.
++ */
++
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/atomic.h>
++#include <linux/list.h>
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/preempt.h>
++#include <linux/slab.h>
++#include <linux/spinlock.h>
++#include <linux/zbud.h>
++
++/*****************
++ * Structures
++*****************/
++/*
++ * NCHUNKS_ORDER determines the internal allocation granularity, effectively
++ * adjusting internal fragmentation.  It also determines the number of
++ * freelists maintained in each pool. NCHUNKS_ORDER of 6 means that the
++ * allocation granularity will be in chunks of size PAGE_SIZE/64, and there
++ * will be 64 freelists per pool.
++ */
++#define NCHUNKS_ORDER 6
++
++#define CHUNK_SHIFT   (PAGE_SHIFT - NCHUNKS_ORDER)
++#define CHUNK_SIZE    (1 << CHUNK_SHIFT)
++#define NCHUNKS               (PAGE_SIZE >> CHUNK_SHIFT)
++#define ZHDR_SIZE_ALIGNED CHUNK_SIZE
++
++/**
++ * struct zbud_pool - stores metadata for each zbud pool
++ * @lock:     protects all pool fields and first|last_chunk fields of any
++ *            zbud page in the pool
++ * @unbuddied:        array of lists tracking zbud pages that only contain one buddy;
++ *            the lists each zbud page is added to depends on the size of
++ *            its free region.
++ * @buddied:  list tracking the zbud pages that contain two buddies;
++ *            these zbud pages are full
++ * @lru:      list tracking the zbud pages in LRU order by most recently
++ *            added buddy.
++ * @pages_nr: number of zbud pages in the pool.
++ * @ops:      pointer to a structure of user defined operations specified at
++ *            pool creation time.
++ *
++ * This structure is allocated at pool creation time and maintains metadata
++ * pertaining to a particular zbud pool.
++ */
++struct zbud_pool {
++      spinlock_t lock;
++      struct list_head unbuddied[NCHUNKS];
++      struct list_head buddied;
++      struct list_head lru;
++      u64 pages_nr;
++      struct zbud_ops *ops;
++};
++
++/*
++ * struct zbud_header - zbud page metadata occupying the first chunk of each
++ *                    zbud page.
++ * @buddy:    links the zbud page into the unbuddied/buddied lists in the pool
++ * @lru:      links the zbud page into the lru list in the pool
++ * @first_chunks:     the size of the first buddy in chunks, 0 if free
++ * @last_chunks:      the size of the last buddy in chunks, 0 if free
++ */
++struct zbud_header {
++      struct list_head buddy;
++      struct list_head lru;
++      unsigned int first_chunks;
++      unsigned int last_chunks;
++      bool under_reclaim;
++};
++
++/*****************
++ * Helpers
++*****************/
++/* Just to make the code easier to read */
++enum buddy {
++      FIRST,
++      LAST
++};
++
++/* Converts an allocation size in bytes to size in zbud chunks */
++static int size_to_chunks(int size)
++{
++      return (size + CHUNK_SIZE - 1) >> CHUNK_SHIFT;
++}
++
++#define for_each_unbuddied_list(_iter, _begin) \
++      for ((_iter) = (_begin); (_iter) < NCHUNKS; (_iter)++)
++
++/* Initializes the zbud header of a newly allocated zbud page */
++static struct zbud_header *init_zbud_page(struct page *page)
++{
++      struct zbud_header *zhdr = page_address(page);
++      zhdr->first_chunks = 0;
++      zhdr->last_chunks = 0;
++      INIT_LIST_HEAD(&zhdr->buddy);
++      INIT_LIST_HEAD(&zhdr->lru);
++      zhdr->under_reclaim = 0;
++      return zhdr;
++}
++
++/* Resets the struct page fields and frees the page */
++static void free_zbud_page(struct zbud_header *zhdr)
++{
++      __free_page(virt_to_page(zhdr));
++}
++
++/*
++ * Encodes the handle of a particular buddy within a zbud page
++ * Pool lock should be held as this function accesses first|last_chunks
++ */
++static unsigned long encode_handle(struct zbud_header *zhdr, enum buddy bud)
++{
++      unsigned long handle;
++
++      /*
++       * For now, the encoded handle is actually just the pointer to the data
++       * but this might not always be the case.  A little information hiding.
++       * Add CHUNK_SIZE to the handle if it is the first allocation to jump
++       * over the zbud header in the first chunk.
++       */
++      handle = (unsigned long)zhdr;
++      if (bud == FIRST)
++              /* skip over zbud header */
++              handle += ZHDR_SIZE_ALIGNED;
++      else /* bud == LAST */
++              handle += PAGE_SIZE - (zhdr->last_chunks  << CHUNK_SHIFT);
++      return handle;
++}
++
++/* Returns the zbud page where a given handle is stored */
++static struct zbud_header *handle_to_zbud_header(unsigned long handle)
++{
++      return (struct zbud_header *)(handle & PAGE_MASK);
++}
++
++/* Returns the number of free chunks in a zbud page */
++static int num_free_chunks(struct zbud_header *zhdr)
++{
++      /*
++       * Rather than branch for different situations, just use the fact that
++       * free buddies have a length of zero to simplify everything. -1 at the
++       * end for the zbud header.
++       */
++      return NCHUNKS - zhdr->first_chunks - zhdr->last_chunks - 1;
++}
++
++/*****************
++ * API Functions
++*****************/
++/**
++ * zbud_create_pool() - create a new zbud pool
++ * @gfp:      gfp flags when allocating the zbud pool structure
++ * @ops:      user-defined operations for the zbud pool
++ *
++ * Return: pointer to the new zbud pool or NULL if the metadata allocation
++ * failed.
++ */
++struct zbud_pool *zbud_create_pool(gfp_t gfp, struct zbud_ops *ops)
++{
++      struct zbud_pool *pool;
++      int i;
++
++      pool = kmalloc(sizeof(struct zbud_pool), gfp);
++      if (!pool)
++              return NULL;
++      spin_lock_init(&pool->lock);
++      for_each_unbuddied_list(i, 0)
++              INIT_LIST_HEAD(&pool->unbuddied[i]);
++      INIT_LIST_HEAD(&pool->buddied);
++      INIT_LIST_HEAD(&pool->lru);
++      pool->pages_nr = 0;
++      pool->ops = ops;
++      return pool;
++}
++
++/**
++ * zbud_destroy_pool() - destroys an existing zbud pool
++ * @pool:     the zbud pool to be destroyed
++ *
++ * The pool should be emptied before this function is called.
++ */
++void zbud_destroy_pool(struct zbud_pool *pool)
++{
++      kfree(pool);
++}
++
++/**
++ * zbud_alloc() - allocates a region of a given size
++ * @pool:     zbud pool from which to allocate
++ * @size:     size in bytes of the desired allocation
++ * @gfp:      gfp flags used if the pool needs to grow
++ * @handle:   handle of the new allocation
++ *
++ * This function will attempt to find a free region in the pool large enough to
++ * satisfy the allocation request.  A search of the unbuddied lists is
++ * performed first. If no suitable free region is found, then a new page is
++ * allocated and added to the pool to satisfy the request.
++ *
++ * gfp should not set __GFP_HIGHMEM as highmem pages cannot be used
++ * as zbud pool pages.
++ *
++ * Return: 0 if success and handle is set, otherwise -EINVAL is the size or
++ * gfp arguments are invalid or -ENOMEM if the pool was unable to allocate
++ * a new page.
++ */
++int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
++                      unsigned long *handle)
++{
++      int chunks, i, freechunks;
++      struct zbud_header *zhdr = NULL;
++      enum buddy bud;
++      struct page *page;
++
++      if (size <= 0 || gfp & __GFP_HIGHMEM)
++              return -EINVAL;
++      if (size > PAGE_SIZE - ZHDR_SIZE_ALIGNED)
++              return -ENOSPC;
++      chunks = size_to_chunks(size);
++      spin_lock(&pool->lock);
++
++      /* First, try to find an unbuddied zbud page. */
++      zhdr = NULL;
++      for_each_unbuddied_list(i, chunks) {
++              if (!list_empty(&pool->unbuddied[i])) {
++                      zhdr = list_first_entry(&pool->unbuddied[i],
++                                      struct zbud_header, buddy);
++                      list_del(&zhdr->buddy);
++                      if (zhdr->first_chunks == 0)
++                              bud = FIRST;
++                      else
++                              bud = LAST;
++                      goto found;
++              }
++      }
++
++      /* Couldn't find unbuddied zbud page, create new one */
++      spin_unlock(&pool->lock);
++      page = alloc_page(gfp);
++      if (!page)
++              return -ENOMEM;
++      spin_lock(&pool->lock);
++      pool->pages_nr++;
++      zhdr = init_zbud_page(page);
++      bud = FIRST;
++
++found:
++      if (bud == FIRST)
++              zhdr->first_chunks = chunks;
++      else
++              zhdr->last_chunks = chunks;
++
++      if (zhdr->first_chunks == 0 || zhdr->last_chunks == 0) {
++              /* Add to unbuddied list */
++              freechunks = num_free_chunks(zhdr);
++              list_add(&zhdr->buddy, &pool->unbuddied[freechunks]);
++      } else {
++              /* Add to buddied list */
++              list_add(&zhdr->buddy, &pool->buddied);
++      }
++
++      /* Add/move zbud page to beginning of LRU */
++      if (!list_empty(&zhdr->lru))
++              list_del(&zhdr->lru);
++      list_add(&zhdr->lru, &pool->lru);
++
++      *handle = encode_handle(zhdr, bud);
++      spin_unlock(&pool->lock);
++
++      return 0;
++}
++
++/**
++ * zbud_free() - frees the allocation associated with the given handle
++ * @pool:     pool in which the allocation resided
++ * @handle:   handle associated with the allocation returned by zbud_alloc()
++ *
++ * In the case that the zbud page in which the allocation resides is under
++ * reclaim, as indicated by the PG_reclaim flag being set, this function
++ * only sets the first|last_chunks to 0.  The page is actually freed
++ * once both buddies are evicted (see zbud_reclaim_page() below).
++ */
++void zbud_free(struct zbud_pool *pool, unsigned long handle)
++{
++      struct zbud_header *zhdr;
++      int freechunks;
++
++      spin_lock(&pool->lock);
++      zhdr = handle_to_zbud_header(handle);
++
++      /* If first buddy, handle will be page aligned */
++      if ((handle - ZHDR_SIZE_ALIGNED) & ~PAGE_MASK)
++              zhdr->last_chunks = 0;
++      else
++              zhdr->first_chunks = 0;
++
++      if (zhdr->under_reclaim) {
++              /* zbud page is under reclaim, reclaim will free */
++              spin_unlock(&pool->lock);
++              return;
++      }
++
++      /* Remove from existing buddy list */
++      list_del(&zhdr->buddy);
++
++      if (zhdr->first_chunks == 0 && zhdr->last_chunks == 0) {
++              /* zbud page is empty, free */
++              list_del(&zhdr->lru);
++              free_zbud_page(zhdr);
++              pool->pages_nr--;
++      } else {
++              /* Add to unbuddied list */
++              freechunks = num_free_chunks(zhdr);
++              list_add(&zhdr->buddy, &pool->unbuddied[freechunks]);
++      }
++
++      spin_unlock(&pool->lock);
++}
++
++#define list_tail_entry(ptr, type, member) \
++      list_entry((ptr)->prev, type, member)
++
++/**
++ * zbud_reclaim_page() - evicts allocations from a pool page and frees it
++ * @pool:     pool from which a page will attempt to be evicted
++ * @retires:  number of pages on the LRU list for which eviction will
++ *            be attempted before failing
++ *
++ * zbud reclaim is different from normal system reclaim in that the reclaim is
++ * done from the bottom, up.  This is because only the bottom layer, zbud, has
++ * information on how the allocations are organized within each zbud page. This
++ * has the potential to create interesting locking situations between zbud and
++ * the user, however.
++ *
++ * To avoid these, this is how zbud_reclaim_page() should be called:
++
++ * The user detects a page should be reclaimed and calls zbud_reclaim_page().
++ * zbud_reclaim_page() will remove a zbud page from the pool LRU list and call
++ * the user-defined eviction handler with the pool and handle as arguments.
++ *
++ * If the handle can not be evicted, the eviction handler should return
++ * non-zero. zbud_reclaim_page() will add the zbud page back to the
++ * appropriate list and try the next zbud page on the LRU up to
++ * a user defined number of retries.
++ *
++ * If the handle is successfully evicted, the eviction handler should
++ * return 0 _and_ should have called zbud_free() on the handle. zbud_free()
++ * contains logic to delay freeing the page if the page is under reclaim,
++ * as indicated by the setting of the PG_reclaim flag on the underlying page.
++ *
++ * If all buddies in the zbud page are successfully evicted, then the
++ * zbud page can be freed.
++ *
++ * Returns: 0 if page is successfully freed, otherwise -EINVAL if there are
++ * no pages to evict or an eviction handler is not registered, -EAGAIN if
++ * the retry limit was hit.
++ */
++int zbud_reclaim_page(struct zbud_pool *pool, unsigned int retries)
++{
++      int i, ret, freechunks;
++      struct zbud_header *zhdr;
++      unsigned long first_handle = 0, last_handle = 0;
++
++      spin_lock(&pool->lock);
++      if (!pool->ops || !pool->ops->evict || list_empty(&pool->lru) ||
++                      retries == 0) {
++              spin_unlock(&pool->lock);
++              return -EINVAL;
++      }
++      for (i = 0; i < retries; i++) {
++              zhdr = list_tail_entry(&pool->lru, struct zbud_header, lru);
++              list_del(&zhdr->lru);
++              list_del(&zhdr->buddy);
++              /* Protect zbud page against free */
++              zhdr->under_reclaim = true;
++              /*
++               * We need encode the handles before unlocking, since we can
++               * race with free that will set (first|last)_chunks to 0
++               */
++              first_handle = 0;
++              last_handle = 0;
++              if (zhdr->first_chunks)
++                      first_handle = encode_handle(zhdr, FIRST);
++              if (zhdr->last_chunks)
++                      last_handle = encode_handle(zhdr, LAST);
++              spin_unlock(&pool->lock);
++
++              /* Issue the eviction callback(s) */
++              if (first_handle) {
++                      ret = pool->ops->evict(pool, first_handle);
++                      if (ret)
++                              goto next;
++              }
++              if (last_handle) {
++                      ret = pool->ops->evict(pool, last_handle);
++                      if (ret)
++                              goto next;
++              }
++next:
++              spin_lock(&pool->lock);
++              zhdr->under_reclaim = false;
++              if (zhdr->first_chunks == 0 && zhdr->last_chunks == 0) {
++                      /*
++                       * Both buddies are now free, free the zbud page and
++                       * return success.
++                       */
++                      free_zbud_page(zhdr);
++                      pool->pages_nr--;
++                      spin_unlock(&pool->lock);
++                      return 0;
++              } else if (zhdr->first_chunks == 0 ||
++                              zhdr->last_chunks == 0) {
++                      /* add to unbuddied list */
++                      freechunks = num_free_chunks(zhdr);
++                      list_add(&zhdr->buddy, &pool->unbuddied[freechunks]);
++              } else {
++                      /* add to buddied list */
++                      list_add(&zhdr->buddy, &pool->buddied);
++              }
++
++              /* add to beginning of LRU */
++              list_add(&zhdr->lru, &pool->lru);
++      }
++      spin_unlock(&pool->lock);
++      return -EAGAIN;
++}
++
++/**
++ * zbud_map() - maps the allocation associated with the given handle
++ * @pool:     pool in which the allocation resides
++ * @handle:   handle associated with the allocation to be mapped
++ *
++ * While trivial for zbud, the mapping functions for others allocators
++ * implementing this allocation API could have more complex information encoded
++ * in the handle and could create temporary mappings to make the data
++ * accessible to the user.
++ *
++ * Returns: a pointer to the mapped allocation
++ */
++void *zbud_map(struct zbud_pool *pool, unsigned long handle)
++{
++      return (void *)(handle);
++}
++
++/**
++ * zbud_unmap() - maps the allocation associated with the given handle
++ * @pool:     pool in which the allocation resides
++ * @handle:   handle associated with the allocation to be unmapped
++ */
++void zbud_unmap(struct zbud_pool *pool, unsigned long handle)
++{
++}
++
++/**
++ * zbud_get_pool_size() - gets the zbud pool size in pages
++ * @pool:     pool whose size is being queried
++ *
++ * Returns: size in pages of the given pool.  The pool lock need not be
++ * taken to access pages_nr.
++ */
++u64 zbud_get_pool_size(struct zbud_pool *pool)
++{
++      return pool->pages_nr;
++}
++
++static int __init init_zbud(void)
++{
++      /* Make sure the zbud header will fit in one chunk */
++      BUILD_BUG_ON(sizeof(struct zbud_header) > ZHDR_SIZE_ALIGNED);
++      pr_info("loaded\n");
++      return 0;
++}
++
++static void __exit exit_zbud(void)
++{
++      pr_info("unloaded\n");
++}
++
++module_init(init_zbud);
++module_exit(exit_zbud);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Seth Jennings <sjenning@linux.vnet.ibm.com>");
++MODULE_DESCRIPTION("Buddy Allocator for Compressed Pages");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0531-zswap-add-to-mm.patch b/patches.tizen/0531-zswap-add-to-mm.patch
new file mode 100644 (file)
index 0000000..0dcbc4f
--- /dev/null
@@ -0,0 +1,1047 @@
+From 4c7064dd6b3ff9d0519c9aa9a8853c98f40b9d2c Mon Sep 17 00:00:00 2001
+From: Seth Jennings <sjenning@linux.vnet.ibm.com>
+Date: Wed, 10 Jul 2013 16:05:03 -0700
+Subject: [PATCH 0531/1302] zswap: add to mm/
+
+zswap is a thin backend for frontswap that takes pages that are in the
+process of being swapped out and attempts to compress them and store
+them in a RAM-based memory pool.  This can result in a significant I/O
+reduction on the swap device and, in the case where decompressing from
+RAM is faster than reading from the swap device, can also improve
+workload performance.
+
+It also has support for evicting swap pages that are currently
+compressed in zswap to the swap device on an LRU(ish) basis.  This
+functionality makes zswap a true cache in that, once the cache is full,
+the oldest pages can be moved out of zswap to the swap device so newer
+pages can be compressed and stored in zswap.
+
+This patch adds the zswap driver to mm/
+
+Signed-off-by: Seth Jennings <sjenning@linux.vnet.ibm.com>
+Acked-by: Rik van Riel <riel@redhat.com>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Nitin Gupta <ngupta@vflare.org>
+Cc: Minchan Kim <minchan@kernel.org>
+Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Cc: Dan Magenheimer <dan.magenheimer@oracle.com>
+Cc: Robert Jennings <rcj@linux.vnet.ibm.com>
+Cc: Jenifer Hopper <jhopper@us.ibm.com>
+Cc: Mel Gorman <mgorman@suse.de>
+Cc: Johannes Weiner <jweiner@redhat.com>
+Cc: Larry Woodman <lwoodman@redhat.com>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Cc: Dave Hansen <dave@sr71.net>
+Cc: Joe Perches <joe@perches.com>
+Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
+Cc: Cody P Schafer <cody@linux.vnet.ibm.com>
+Cc: Hugh Dickens <hughd@google.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Fengguang Wu <fengguang.wu@intel.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+
+Conflicts:
+
+       mm/Kconfig
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ mm/Kconfig  |  20 ++
+ mm/Makefile |   1 +
+ mm/zswap.c  | 943 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 964 insertions(+)
+ create mode 100644 mm/zswap.c
+
+diff --git a/mm/Kconfig b/mm/Kconfig
+index 3367ac3..01cd56e 100644
+--- a/mm/Kconfig
++++ b/mm/Kconfig
+@@ -487,3 +487,23 @@ config ZBUD
+         page.  While this design limits storage density, it has simple and
+         deterministic reclaim properties that make it preferable to a higher
+         density approach when reclaim will be used.
++
++config ZSWAP
++      bool "Compressed cache for swap pages (EXPERIMENTAL)"
++      depends on FRONTSWAP && CRYPTO=y
++      select CRYPTO_LZO
++      select ZBUD
++      default n
++      help
++        A lightweight compressed cache for swap pages.  It takes
++        pages that are in the process of being swapped out and attempts to
++        compress them into a dynamically allocated RAM-based memory pool.
++        This can result in a significant I/O reduction on swap device and,
++        in the case where decompressing from RAM is faster that swap device
++        reads, can also improve workload performance.
++
++        This is marked experimental because it is a new feature (as of
++        v3.11) that interacts heavily with memory reclaim.  While these
++        interactions don't cause any known issues on simple memory setups,
++        they have not be fully explored on the large set of potential
++        configurations and workloads that exist.
+diff --git a/mm/Makefile b/mm/Makefile
+index 95f0197..f008033 100644
+--- a/mm/Makefile
++++ b/mm/Makefile
+@@ -32,6 +32,7 @@ obj-$(CONFIG_HAVE_MEMBLOCK) += memblock.o
+ obj-$(CONFIG_BOUNCE)  += bounce.o
+ obj-$(CONFIG_SWAP)    += page_io.o swap_state.o swapfile.o
+ obj-$(CONFIG_FRONTSWAP)       += frontswap.o
++obj-$(CONFIG_ZSWAP)   += zswap.o
+ obj-$(CONFIG_HAS_DMA) += dmapool.o
+ obj-$(CONFIG_HUGETLBFS)       += hugetlb.o
+ obj-$(CONFIG_NUMA)    += mempolicy.o
+diff --git a/mm/zswap.c b/mm/zswap.c
+new file mode 100644
+index 0000000..deda2b6
+--- /dev/null
++++ b/mm/zswap.c
+@@ -0,0 +1,943 @@
++/*
++ * zswap.c - zswap driver file
++ *
++ * zswap is a backend for frontswap that takes pages that are in the process
++ * of being swapped out and attempts to compress and store them in a
++ * RAM-based memory pool.  This can result in a significant I/O reduction on
++ * the swap device and, in the case where decompressing from RAM is faster
++ * than reading from the swap device, can also improve workload performance.
++ *
++ * Copyright (C) 2012  Seth Jennings <sjenning@linux.vnet.ibm.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++*/
++
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/module.h>
++#include <linux/cpu.h>
++#include <linux/highmem.h>
++#include <linux/slab.h>
++#include <linux/spinlock.h>
++#include <linux/types.h>
++#include <linux/atomic.h>
++#include <linux/frontswap.h>
++#include <linux/rbtree.h>
++#include <linux/swap.h>
++#include <linux/crypto.h>
++#include <linux/mempool.h>
++#include <linux/zbud.h>
++
++#include <linux/mm_types.h>
++#include <linux/page-flags.h>
++#include <linux/swapops.h>
++#include <linux/writeback.h>
++#include <linux/pagemap.h>
++
++/*********************************
++* statistics
++**********************************/
++/* Number of memory pages used by the compressed pool */
++static u64 zswap_pool_pages;
++/* The number of compressed pages currently stored in zswap */
++static atomic_t zswap_stored_pages = ATOMIC_INIT(0);
++
++/*
++ * The statistics below are not protected from concurrent access for
++ * performance reasons so they may not be a 100% accurate.  However,
++ * they do provide useful information on roughly how many times a
++ * certain event is occurring.
++*/
++
++/* Pool limit was hit (see zswap_max_pool_percent) */
++static u64 zswap_pool_limit_hit;
++/* Pages written back when pool limit was reached */
++static u64 zswap_written_back_pages;
++/* Store failed due to a reclaim failure after pool limit was reached */
++static u64 zswap_reject_reclaim_fail;
++/* Compressed page was too big for the allocator to (optimally) store */
++static u64 zswap_reject_compress_poor;
++/* Store failed because underlying allocator could not get memory */
++static u64 zswap_reject_alloc_fail;
++/* Store failed because the entry metadata could not be allocated (rare) */
++static u64 zswap_reject_kmemcache_fail;
++/* Duplicate store was encountered (rare) */
++static u64 zswap_duplicate_entry;
++
++/*********************************
++* tunables
++**********************************/
++/* Enable/disable zswap (disabled by default, fixed at boot for now) */
++static bool zswap_enabled __read_mostly;
++module_param_named(enabled, zswap_enabled, bool, 0);
++
++/* Compressor to be used by zswap (fixed at boot for now) */
++#define ZSWAP_COMPRESSOR_DEFAULT "lzo"
++static char *zswap_compressor = ZSWAP_COMPRESSOR_DEFAULT;
++module_param_named(compressor, zswap_compressor, charp, 0);
++
++/* The maximum percentage of memory that the compressed pool can occupy */
++static unsigned int zswap_max_pool_percent = 20;
++module_param_named(max_pool_percent,
++                      zswap_max_pool_percent, uint, 0644);
++
++/*********************************
++* compression functions
++**********************************/
++/* per-cpu compression transforms */
++static struct crypto_comp * __percpu *zswap_comp_pcpu_tfms;
++
++enum comp_op {
++      ZSWAP_COMPOP_COMPRESS,
++      ZSWAP_COMPOP_DECOMPRESS
++};
++
++static int zswap_comp_op(enum comp_op op, const u8 *src, unsigned int slen,
++                              u8 *dst, unsigned int *dlen)
++{
++      struct crypto_comp *tfm;
++      int ret;
++
++      tfm = *per_cpu_ptr(zswap_comp_pcpu_tfms, get_cpu());
++      switch (op) {
++      case ZSWAP_COMPOP_COMPRESS:
++              ret = crypto_comp_compress(tfm, src, slen, dst, dlen);
++              break;
++      case ZSWAP_COMPOP_DECOMPRESS:
++              ret = crypto_comp_decompress(tfm, src, slen, dst, dlen);
++              break;
++      default:
++              ret = -EINVAL;
++      }
++
++      put_cpu();
++      return ret;
++}
++
++static int __init zswap_comp_init(void)
++{
++      if (!crypto_has_comp(zswap_compressor, 0, 0)) {
++              pr_info("%s compressor not available\n", zswap_compressor);
++              /* fall back to default compressor */
++              zswap_compressor = ZSWAP_COMPRESSOR_DEFAULT;
++              if (!crypto_has_comp(zswap_compressor, 0, 0))
++                      /* can't even load the default compressor */
++                      return -ENODEV;
++      }
++      pr_info("using %s compressor\n", zswap_compressor);
++
++      /* alloc percpu transforms */
++      zswap_comp_pcpu_tfms = alloc_percpu(struct crypto_comp *);
++      if (!zswap_comp_pcpu_tfms)
++              return -ENOMEM;
++      return 0;
++}
++
++static void zswap_comp_exit(void)
++{
++      /* free percpu transforms */
++      if (zswap_comp_pcpu_tfms)
++              free_percpu(zswap_comp_pcpu_tfms);
++}
++
++/*********************************
++* data structures
++**********************************/
++/*
++ * struct zswap_entry
++ *
++ * This structure contains the metadata for tracking a single compressed
++ * page within zswap.
++ *
++ * rbnode - links the entry into red-black tree for the appropriate swap type
++ * refcount - the number of outstanding reference to the entry. This is needed
++ *            to protect against premature freeing of the entry by code
++ *            concurent calls to load, invalidate, and writeback.  The lock
++ *            for the zswap_tree structure that contains the entry must
++ *            be held while changing the refcount.  Since the lock must
++ *            be held, there is no reason to also make refcount atomic.
++ * offset - the swap offset for the entry.  Index into the red-black tree.
++ * handle - zsmalloc allocation handle that stores the compressed page data
++ * length - the length in bytes of the compressed page data.  Needed during
++ *           decompression
++ */
++struct zswap_entry {
++      struct rb_node rbnode;
++      pgoff_t offset;
++      int refcount;
++      unsigned int length;
++      unsigned long handle;
++};
++
++struct zswap_header {
++      swp_entry_t swpentry;
++};
++
++/*
++ * The tree lock in the zswap_tree struct protects a few things:
++ * - the rbtree
++ * - the refcount field of each entry in the tree
++ */
++struct zswap_tree {
++      struct rb_root rbroot;
++      spinlock_t lock;
++      struct zbud_pool *pool;
++};
++
++static struct zswap_tree *zswap_trees[MAX_SWAPFILES];
++
++/*********************************
++* zswap entry functions
++**********************************/
++static struct kmem_cache *zswap_entry_cache;
++
++static int zswap_entry_cache_create(void)
++{
++      zswap_entry_cache = KMEM_CACHE(zswap_entry, 0);
++      return (zswap_entry_cache == NULL);
++}
++
++static void zswap_entry_cache_destory(void)
++{
++      kmem_cache_destroy(zswap_entry_cache);
++}
++
++static struct zswap_entry *zswap_entry_cache_alloc(gfp_t gfp)
++{
++      struct zswap_entry *entry;
++      entry = kmem_cache_alloc(zswap_entry_cache, gfp);
++      if (!entry)
++              return NULL;
++      entry->refcount = 1;
++      return entry;
++}
++
++static void zswap_entry_cache_free(struct zswap_entry *entry)
++{
++      kmem_cache_free(zswap_entry_cache, entry);
++}
++
++/* caller must hold the tree lock */
++static void zswap_entry_get(struct zswap_entry *entry)
++{
++      entry->refcount++;
++}
++
++/* caller must hold the tree lock */
++static int zswap_entry_put(struct zswap_entry *entry)
++{
++      entry->refcount--;
++      return entry->refcount;
++}
++
++/*********************************
++* rbtree functions
++**********************************/
++static struct zswap_entry *zswap_rb_search(struct rb_root *root, pgoff_t offset)
++{
++      struct rb_node *node = root->rb_node;
++      struct zswap_entry *entry;
++
++      while (node) {
++              entry = rb_entry(node, struct zswap_entry, rbnode);
++              if (entry->offset > offset)
++                      node = node->rb_left;
++              else if (entry->offset < offset)
++                      node = node->rb_right;
++              else
++                      return entry;
++      }
++      return NULL;
++}
++
++/*
++ * In the case that a entry with the same offset is found, a pointer to
++ * the existing entry is stored in dupentry and the function returns -EEXIST
++ */
++static int zswap_rb_insert(struct rb_root *root, struct zswap_entry *entry,
++                      struct zswap_entry **dupentry)
++{
++      struct rb_node **link = &root->rb_node, *parent = NULL;
++      struct zswap_entry *myentry;
++
++      while (*link) {
++              parent = *link;
++              myentry = rb_entry(parent, struct zswap_entry, rbnode);
++              if (myentry->offset > entry->offset)
++                      link = &(*link)->rb_left;
++              else if (myentry->offset < entry->offset)
++                      link = &(*link)->rb_right;
++              else {
++                      *dupentry = myentry;
++                      return -EEXIST;
++              }
++      }
++      rb_link_node(&entry->rbnode, parent, link);
++      rb_insert_color(&entry->rbnode, root);
++      return 0;
++}
++
++/*********************************
++* per-cpu code
++**********************************/
++static DEFINE_PER_CPU(u8 *, zswap_dstmem);
++
++static int __zswap_cpu_notifier(unsigned long action, unsigned long cpu)
++{
++      struct crypto_comp *tfm;
++      u8 *dst;
++
++      switch (action) {
++      case CPU_UP_PREPARE:
++              tfm = crypto_alloc_comp(zswap_compressor, 0, 0);
++              if (IS_ERR(tfm)) {
++                      pr_err("can't allocate compressor transform\n");
++                      return NOTIFY_BAD;
++              }
++              *per_cpu_ptr(zswap_comp_pcpu_tfms, cpu) = tfm;
++              dst = kmalloc(PAGE_SIZE * 2, GFP_KERNEL);
++              if (!dst) {
++                      pr_err("can't allocate compressor buffer\n");
++                      crypto_free_comp(tfm);
++                      *per_cpu_ptr(zswap_comp_pcpu_tfms, cpu) = NULL;
++                      return NOTIFY_BAD;
++              }
++              per_cpu(zswap_dstmem, cpu) = dst;
++              break;
++      case CPU_DEAD:
++      case CPU_UP_CANCELED:
++              tfm = *per_cpu_ptr(zswap_comp_pcpu_tfms, cpu);
++              if (tfm) {
++                      crypto_free_comp(tfm);
++                      *per_cpu_ptr(zswap_comp_pcpu_tfms, cpu) = NULL;
++              }
++              dst = per_cpu(zswap_dstmem, cpu);
++              kfree(dst);
++              per_cpu(zswap_dstmem, cpu) = NULL;
++              break;
++      default:
++              break;
++      }
++      return NOTIFY_OK;
++}
++
++static int zswap_cpu_notifier(struct notifier_block *nb,
++                              unsigned long action, void *pcpu)
++{
++      unsigned long cpu = (unsigned long)pcpu;
++      return __zswap_cpu_notifier(action, cpu);
++}
++
++static struct notifier_block zswap_cpu_notifier_block = {
++      .notifier_call = zswap_cpu_notifier
++};
++
++static int zswap_cpu_init(void)
++{
++      unsigned long cpu;
++
++      get_online_cpus();
++      for_each_online_cpu(cpu)
++              if (__zswap_cpu_notifier(CPU_UP_PREPARE, cpu) != NOTIFY_OK)
++                      goto cleanup;
++      register_cpu_notifier(&zswap_cpu_notifier_block);
++      put_online_cpus();
++      return 0;
++
++cleanup:
++      for_each_online_cpu(cpu)
++              __zswap_cpu_notifier(CPU_UP_CANCELED, cpu);
++      put_online_cpus();
++      return -ENOMEM;
++}
++
++/*********************************
++* helpers
++**********************************/
++static bool zswap_is_full(void)
++{
++      return (totalram_pages * zswap_max_pool_percent / 100 <
++              zswap_pool_pages);
++}
++
++/*
++ * Carries out the common pattern of freeing and entry's zsmalloc allocation,
++ * freeing the entry itself, and decrementing the number of stored pages.
++ */
++static void zswap_free_entry(struct zswap_tree *tree, struct zswap_entry *entry)
++{
++      zbud_free(tree->pool, entry->handle);
++      zswap_entry_cache_free(entry);
++      atomic_dec(&zswap_stored_pages);
++      zswap_pool_pages = zbud_get_pool_size(tree->pool);
++}
++
++/*********************************
++* writeback code
++**********************************/
++/* return enum for zswap_get_swap_cache_page */
++enum zswap_get_swap_ret {
++      ZSWAP_SWAPCACHE_NEW,
++      ZSWAP_SWAPCACHE_EXIST,
++      ZSWAP_SWAPCACHE_NOMEM
++};
++
++/*
++ * zswap_get_swap_cache_page
++ *
++ * This is an adaption of read_swap_cache_async()
++ *
++ * This function tries to find a page with the given swap entry
++ * in the swapper_space address space (the swap cache).  If the page
++ * is found, it is returned in retpage.  Otherwise, a page is allocated,
++ * added to the swap cache, and returned in retpage.
++ *
++ * If success, the swap cache page is returned in retpage
++ * Returns 0 if page was already in the swap cache, page is not locked
++ * Returns 1 if the new page needs to be populated, page is locked
++ * Returns <0 on error
++ */
++static int zswap_get_swap_cache_page(swp_entry_t entry,
++                              struct page **retpage)
++{
++      struct page *found_page, *new_page = NULL;
++      struct address_space *swapper_space = &swapper_spaces[swp_type(entry)];
++      int err;
++
++      *retpage = NULL;
++      do {
++              /*
++               * First check the swap cache.  Since this is normally
++               * called after lookup_swap_cache() failed, re-calling
++               * that would confuse statistics.
++               */
++              found_page = find_get_page(swapper_space, entry.val);
++              if (found_page)
++                      break;
++
++              /*
++               * Get a new page to read into from swap.
++               */
++              if (!new_page) {
++                      new_page = alloc_page(GFP_KERNEL);
++                      if (!new_page)
++                              break; /* Out of memory */
++              }
++
++              /*
++               * call radix_tree_preload() while we can wait.
++               */
++              err = radix_tree_preload(GFP_KERNEL);
++              if (err)
++                      break;
++
++              /*
++               * Swap entry may have been freed since our caller observed it.
++               */
++              err = swapcache_prepare(entry);
++              if (err == -EEXIST) { /* seems racy */
++                      radix_tree_preload_end();
++                      continue;
++              }
++              if (err) { /* swp entry is obsolete ? */
++                      radix_tree_preload_end();
++                      break;
++              }
++
++              /* May fail (-ENOMEM) if radix-tree node allocation failed. */
++              __set_page_locked(new_page);
++              SetPageSwapBacked(new_page);
++              err = __add_to_swap_cache(new_page, entry);
++              if (likely(!err)) {
++                      radix_tree_preload_end();
++                      lru_cache_add_anon(new_page);
++                      *retpage = new_page;
++                      return ZSWAP_SWAPCACHE_NEW;
++              }
++              radix_tree_preload_end();
++              ClearPageSwapBacked(new_page);
++              __clear_page_locked(new_page);
++              /*
++               * add_to_swap_cache() doesn't return -EEXIST, so we can safely
++               * clear SWAP_HAS_CACHE flag.
++               */
++              swapcache_free(entry, NULL);
++      } while (err != -ENOMEM);
++
++      if (new_page)
++              page_cache_release(new_page);
++      if (!found_page)
++              return ZSWAP_SWAPCACHE_NOMEM;
++      *retpage = found_page;
++      return ZSWAP_SWAPCACHE_EXIST;
++}
++
++/*
++ * Attempts to free an entry by adding a page to the swap cache,
++ * decompressing the entry data into the page, and issuing a
++ * bio write to write the page back to the swap device.
++ *
++ * This can be thought of as a "resumed writeback" of the page
++ * to the swap device.  We are basically resuming the same swap
++ * writeback path that was intercepted with the frontswap_store()
++ * in the first place.  After the page has been decompressed into
++ * the swap cache, the compressed version stored by zswap can be
++ * freed.
++ */
++static int zswap_writeback_entry(struct zbud_pool *pool, unsigned long handle)
++{
++      struct zswap_header *zhdr;
++      swp_entry_t swpentry;
++      struct zswap_tree *tree;
++      pgoff_t offset;
++      struct zswap_entry *entry;
++      struct page *page;
++      u8 *src, *dst;
++      unsigned int dlen;
++      int ret, refcount;
++      struct writeback_control wbc = {
++              .sync_mode = WB_SYNC_NONE,
++      };
++
++      /* extract swpentry from data */
++      zhdr = zbud_map(pool, handle);
++      swpentry = zhdr->swpentry; /* here */
++      zbud_unmap(pool, handle);
++      tree = zswap_trees[swp_type(swpentry)];
++      offset = swp_offset(swpentry);
++      BUG_ON(pool != tree->pool);
++
++      /* find and ref zswap entry */
++      spin_lock(&tree->lock);
++      entry = zswap_rb_search(&tree->rbroot, offset);
++      if (!entry) {
++              /* entry was invalidated */
++              spin_unlock(&tree->lock);
++              return 0;
++      }
++      zswap_entry_get(entry);
++      spin_unlock(&tree->lock);
++      BUG_ON(offset != entry->offset);
++
++      /* try to allocate swap cache page */
++      switch (zswap_get_swap_cache_page(swpentry, &page)) {
++      case ZSWAP_SWAPCACHE_NOMEM: /* no memory */
++              ret = -ENOMEM;
++              goto fail;
++
++      case ZSWAP_SWAPCACHE_EXIST: /* page is unlocked */
++              /* page is already in the swap cache, ignore for now */
++              page_cache_release(page);
++              ret = -EEXIST;
++              goto fail;
++
++      case ZSWAP_SWAPCACHE_NEW: /* page is locked */
++              /* decompress */
++              dlen = PAGE_SIZE;
++              src = (u8 *)zbud_map(tree->pool, entry->handle) +
++                      sizeof(struct zswap_header);
++              dst = kmap_atomic(page);
++              ret = zswap_comp_op(ZSWAP_COMPOP_DECOMPRESS, src,
++                              entry->length, dst, &dlen);
++              kunmap_atomic(dst);
++              zbud_unmap(tree->pool, entry->handle);
++              BUG_ON(ret);
++              BUG_ON(dlen != PAGE_SIZE);
++
++              /* page is up to date */
++              SetPageUptodate(page);
++      }
++
++      /* start writeback */
++      __swap_writepage(page, &wbc, end_swap_bio_write);
++      page_cache_release(page);
++      zswap_written_back_pages++;
++
++      spin_lock(&tree->lock);
++
++      /* drop local reference */
++      zswap_entry_put(entry);
++      /* drop the initial reference from entry creation */
++      refcount = zswap_entry_put(entry);
++
++      /*
++       * There are three possible values for refcount here:
++       * (1) refcount is 1, load is in progress, unlink from rbtree,
++       *     load will free
++       * (2) refcount is 0, (normal case) entry is valid,
++       *     remove from rbtree and free entry
++       * (3) refcount is -1, invalidate happened during writeback,
++       *     free entry
++       */
++      if (refcount >= 0) {
++              /* no invalidate yet, remove from rbtree */
++              rb_erase(&entry->rbnode, &tree->rbroot);
++      }
++      spin_unlock(&tree->lock);
++      if (refcount <= 0) {
++              /* free the entry */
++              zswap_free_entry(tree, entry);
++              return 0;
++      }
++      return -EAGAIN;
++
++fail:
++      spin_lock(&tree->lock);
++      zswap_entry_put(entry);
++      spin_unlock(&tree->lock);
++      return ret;
++}
++
++/*********************************
++* frontswap hooks
++**********************************/
++/* attempts to compress and store an single page */
++static int zswap_frontswap_store(unsigned type, pgoff_t offset,
++                              struct page *page)
++{
++      struct zswap_tree *tree = zswap_trees[type];
++      struct zswap_entry *entry, *dupentry;
++      int ret;
++      unsigned int dlen = PAGE_SIZE, len;
++      unsigned long handle;
++      char *buf;
++      u8 *src, *dst;
++      struct zswap_header *zhdr;
++
++      if (!tree) {
++              ret = -ENODEV;
++              goto reject;
++      }
++
++      /* reclaim space if needed */
++      if (zswap_is_full()) {
++              zswap_pool_limit_hit++;
++              if (zbud_reclaim_page(tree->pool, 8)) {
++                      zswap_reject_reclaim_fail++;
++                      ret = -ENOMEM;
++                      goto reject;
++              }
++      }
++
++      /* allocate entry */
++      entry = zswap_entry_cache_alloc(GFP_KERNEL);
++      if (!entry) {
++              zswap_reject_kmemcache_fail++;
++              ret = -ENOMEM;
++              goto reject;
++      }
++
++      /* compress */
++      dst = get_cpu_var(zswap_dstmem);
++      src = kmap_atomic(page);
++      ret = zswap_comp_op(ZSWAP_COMPOP_COMPRESS, src, PAGE_SIZE, dst, &dlen);
++      kunmap_atomic(src);
++      if (ret) {
++              ret = -EINVAL;
++              goto freepage;
++      }
++
++      /* store */
++      len = dlen + sizeof(struct zswap_header);
++      ret = zbud_alloc(tree->pool, len, __GFP_NORETRY | __GFP_NOWARN,
++              &handle);
++      if (ret == -ENOSPC) {
++              zswap_reject_compress_poor++;
++              goto freepage;
++      }
++      if (ret) {
++              zswap_reject_alloc_fail++;
++              goto freepage;
++      }
++      zhdr = zbud_map(tree->pool, handle);
++      zhdr->swpentry = swp_entry(type, offset);
++      buf = (u8 *)(zhdr + 1);
++      memcpy(buf, dst, dlen);
++      zbud_unmap(tree->pool, handle);
++      put_cpu_var(zswap_dstmem);
++
++      /* populate entry */
++      entry->offset = offset;
++      entry->handle = handle;
++      entry->length = dlen;
++
++      /* map */
++      spin_lock(&tree->lock);
++      do {
++              ret = zswap_rb_insert(&tree->rbroot, entry, &dupentry);
++              if (ret == -EEXIST) {
++                      zswap_duplicate_entry++;
++                      /* remove from rbtree */
++                      rb_erase(&dupentry->rbnode, &tree->rbroot);
++                      if (!zswap_entry_put(dupentry)) {
++                              /* free */
++                              zswap_free_entry(tree, dupentry);
++                      }
++              }
++      } while (ret == -EEXIST);
++      spin_unlock(&tree->lock);
++
++      /* update stats */
++      atomic_inc(&zswap_stored_pages);
++      zswap_pool_pages = zbud_get_pool_size(tree->pool);
++
++      return 0;
++
++freepage:
++      put_cpu_var(zswap_dstmem);
++      zswap_entry_cache_free(entry);
++reject:
++      return ret;
++}
++
++/*
++ * returns 0 if the page was successfully decompressed
++ * return -1 on entry not found or error
++*/
++static int zswap_frontswap_load(unsigned type, pgoff_t offset,
++                              struct page *page)
++{
++      struct zswap_tree *tree = zswap_trees[type];
++      struct zswap_entry *entry;
++      u8 *src, *dst;
++      unsigned int dlen;
++      int refcount, ret;
++
++      /* find */
++      spin_lock(&tree->lock);
++      entry = zswap_rb_search(&tree->rbroot, offset);
++      if (!entry) {
++              /* entry was written back */
++              spin_unlock(&tree->lock);
++              return -1;
++      }
++      zswap_entry_get(entry);
++      spin_unlock(&tree->lock);
++
++      /* decompress */
++      dlen = PAGE_SIZE;
++      src = (u8 *)zbud_map(tree->pool, entry->handle) +
++                      sizeof(struct zswap_header);
++      dst = kmap_atomic(page);
++      ret = zswap_comp_op(ZSWAP_COMPOP_DECOMPRESS, src, entry->length,
++              dst, &dlen);
++      kunmap_atomic(dst);
++      zbud_unmap(tree->pool, entry->handle);
++      BUG_ON(ret);
++
++      spin_lock(&tree->lock);
++      refcount = zswap_entry_put(entry);
++      if (likely(refcount)) {
++              spin_unlock(&tree->lock);
++              return 0;
++      }
++      spin_unlock(&tree->lock);
++
++      /*
++       * We don't have to unlink from the rbtree because
++       * zswap_writeback_entry() or zswap_frontswap_invalidate page()
++       * has already done this for us if we are the last reference.
++       */
++      /* free */
++
++      zswap_free_entry(tree, entry);
++
++      return 0;
++}
++
++/* frees an entry in zswap */
++static void zswap_frontswap_invalidate_page(unsigned type, pgoff_t offset)
++{
++      struct zswap_tree *tree = zswap_trees[type];
++      struct zswap_entry *entry;
++      int refcount;
++
++      /* find */
++      spin_lock(&tree->lock);
++      entry = zswap_rb_search(&tree->rbroot, offset);
++      if (!entry) {
++              /* entry was written back */
++              spin_unlock(&tree->lock);
++              return;
++      }
++
++      /* remove from rbtree */
++      rb_erase(&entry->rbnode, &tree->rbroot);
++
++      /* drop the initial reference from entry creation */
++      refcount = zswap_entry_put(entry);
++
++      spin_unlock(&tree->lock);
++
++      if (refcount) {
++              /* writeback in progress, writeback will free */
++              return;
++      }
++
++      /* free */
++      zswap_free_entry(tree, entry);
++}
++
++/* frees all zswap entries for the given swap type */
++static void zswap_frontswap_invalidate_area(unsigned type)
++{
++      struct zswap_tree *tree = zswap_trees[type];
++      struct rb_node *node;
++      struct zswap_entry *entry;
++
++      if (!tree)
++              return;
++
++      /* walk the tree and free everything */
++      spin_lock(&tree->lock);
++      /*
++       * TODO: Even though this code should not be executed because
++       * the try_to_unuse() in swapoff should have emptied the tree,
++       * it is very wasteful to rebalance the tree after every
++       * removal when we are freeing the whole tree.
++       *
++       * If post-order traversal code is ever added to the rbtree
++       * implementation, it should be used here.
++       */
++      while ((node = rb_first(&tree->rbroot))) {
++              entry = rb_entry(node, struct zswap_entry, rbnode);
++              rb_erase(&entry->rbnode, &tree->rbroot);
++              zbud_free(tree->pool, entry->handle);
++              zswap_entry_cache_free(entry);
++              atomic_dec(&zswap_stored_pages);
++      }
++      tree->rbroot = RB_ROOT;
++      spin_unlock(&tree->lock);
++}
++
++static struct zbud_ops zswap_zbud_ops = {
++      .evict = zswap_writeback_entry
++};
++
++static void zswap_frontswap_init(unsigned type)
++{
++      struct zswap_tree *tree;
++
++      tree = kzalloc(sizeof(struct zswap_tree), GFP_KERNEL);
++      if (!tree)
++              goto err;
++      tree->pool = zbud_create_pool(GFP_KERNEL, &zswap_zbud_ops);
++      if (!tree->pool)
++              goto freetree;
++      tree->rbroot = RB_ROOT;
++      spin_lock_init(&tree->lock);
++      zswap_trees[type] = tree;
++      return;
++
++freetree:
++      kfree(tree);
++err:
++      pr_err("alloc failed, zswap disabled for swap type %d\n", type);
++}
++
++static struct frontswap_ops zswap_frontswap_ops = {
++      .store = zswap_frontswap_store,
++      .load = zswap_frontswap_load,
++      .invalidate_page = zswap_frontswap_invalidate_page,
++      .invalidate_area = zswap_frontswap_invalidate_area,
++      .init = zswap_frontswap_init
++};
++
++/*********************************
++* debugfs functions
++**********************************/
++#ifdef CONFIG_DEBUG_FS
++#include <linux/debugfs.h>
++
++static struct dentry *zswap_debugfs_root;
++
++static int __init zswap_debugfs_init(void)
++{
++      if (!debugfs_initialized())
++              return -ENODEV;
++
++      zswap_debugfs_root = debugfs_create_dir("zswap", NULL);
++      if (!zswap_debugfs_root)
++              return -ENOMEM;
++
++      debugfs_create_u64("pool_limit_hit", S_IRUGO,
++                      zswap_debugfs_root, &zswap_pool_limit_hit);
++      debugfs_create_u64("reject_reclaim_fail", S_IRUGO,
++                      zswap_debugfs_root, &zswap_reject_reclaim_fail);
++      debugfs_create_u64("reject_alloc_fail", S_IRUGO,
++                      zswap_debugfs_root, &zswap_reject_alloc_fail);
++      debugfs_create_u64("reject_kmemcache_fail", S_IRUGO,
++                      zswap_debugfs_root, &zswap_reject_kmemcache_fail);
++      debugfs_create_u64("reject_compress_poor", S_IRUGO,
++                      zswap_debugfs_root, &zswap_reject_compress_poor);
++      debugfs_create_u64("written_back_pages", S_IRUGO,
++                      zswap_debugfs_root, &zswap_written_back_pages);
++      debugfs_create_u64("duplicate_entry", S_IRUGO,
++                      zswap_debugfs_root, &zswap_duplicate_entry);
++      debugfs_create_u64("pool_pages", S_IRUGO,
++                      zswap_debugfs_root, &zswap_pool_pages);
++      debugfs_create_atomic_t("stored_pages", S_IRUGO,
++                      zswap_debugfs_root, &zswap_stored_pages);
++
++      return 0;
++}
++
++static void __exit zswap_debugfs_exit(void)
++{
++      debugfs_remove_recursive(zswap_debugfs_root);
++}
++#else
++static int __init zswap_debugfs_init(void)
++{
++      return 0;
++}
++
++static void __exit zswap_debugfs_exit(void) { }
++#endif
++
++/*********************************
++* module init and exit
++**********************************/
++static int __init init_zswap(void)
++{
++      if (!zswap_enabled)
++              return 0;
++
++      pr_info("loading zswap\n");
++      if (zswap_entry_cache_create()) {
++              pr_err("entry cache creation failed\n");
++              goto error;
++      }
++      if (zswap_comp_init()) {
++              pr_err("compressor initialization failed\n");
++              goto compfail;
++      }
++      if (zswap_cpu_init()) {
++              pr_err("per-cpu initialization failed\n");
++              goto pcpufail;
++      }
++      frontswap_register_ops(&zswap_frontswap_ops);
++      if (zswap_debugfs_init())
++              pr_warn("debugfs initialization failed\n");
++      return 0;
++pcpufail:
++      zswap_comp_exit();
++compfail:
++      zswap_entry_cache_destory();
++error:
++      return -ENOMEM;
++}
++/* must be late so crypto has time to come up */
++late_initcall(init_zswap);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Seth Jennings <sjenning@linux.vnet.ibm.com>");
++MODULE_DESCRIPTION("Compressed cache for swap pages");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0532-zswap-add-documentation.patch b/patches.tizen/0532-zswap-add-documentation.patch
new file mode 100644 (file)
index 0000000..49e0541
--- /dev/null
@@ -0,0 +1,111 @@
+From d9a41319bdc99fc746a2804854f4c3c515d13c2e Mon Sep 17 00:00:00 2001
+From: Seth Jennings <sjenning@linux.vnet.ibm.com>
+Date: Wed, 10 Jul 2013 16:05:05 -0700
+Subject: [PATCH 0532/1302] zswap: add documentation
+
+Add the documentation file for the zswap functionality
+
+Signed-off-by: Seth Jennings <sjenning@linux.vnet.ibm.com>
+Acked-by: Rik van Riel <riel@redhat.com>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Nitin Gupta <ngupta@vflare.org>
+Cc: Minchan Kim <minchan@kernel.org>
+Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Cc: Dan Magenheimer <dan.magenheimer@oracle.com>
+Cc: Robert Jennings <rcj@linux.vnet.ibm.com>
+Cc: Jenifer Hopper <jhopper@us.ibm.com>
+Cc: Mel Gorman <mgorman@suse.de>
+Cc: Johannes Weiner <jweiner@redhat.com>
+Cc: Larry Woodman <lwoodman@redhat.com>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Cc: Dave Hansen <dave@sr71.net>
+Cc: Joe Perches <joe@perches.com>
+Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
+Cc: Cody P Schafer <cody@linux.vnet.ibm.com>
+Cc: Hugh Dickens <hughd@google.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/vm/zswap.txt | 68 ++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 68 insertions(+)
+ create mode 100644 Documentation/vm/zswap.txt
+
+diff --git a/Documentation/vm/zswap.txt b/Documentation/vm/zswap.txt
+new file mode 100644
+index 0000000..7e492d8
+--- /dev/null
++++ b/Documentation/vm/zswap.txt
+@@ -0,0 +1,68 @@
++Overview:
++
++Zswap is a lightweight compressed cache for swap pages. It takes pages that are
++in the process of being swapped out and attempts to compress them into a
++dynamically allocated RAM-based memory pool.  zswap basically trades CPU cycles
++for potentially reduced swap I/O.  This trade-off can also result in a
++significant performance improvement if reads from the compressed cache are
++faster than reads from a swap device.
++
++NOTE: Zswap is a new feature as of v3.11 and interacts heavily with memory
++reclaim.  This interaction has not be fully explored on the large set of
++potential configurations and workloads that exist.  For this reason, zswap
++is a work in progress and should be considered experimental.
++
++Some potential benefits:
++* Desktop/laptop users with limited RAM capacities can mitigate the
++    performance impact of swapping.
++* Overcommitted guests that share a common I/O resource can
++    dramatically reduce their swap I/O pressure, avoiding heavy handed I/O
++    throttling by the hypervisor. This allows more work to get done with less
++    impact to the guest workload and guests sharing the I/O subsystem
++* Users with SSDs as swap devices can extend the life of the device by
++    drastically reducing life-shortening writes.
++
++Zswap evicts pages from compressed cache on an LRU basis to the backing swap
++device when the compressed pool reaches it size limit.  This requirement had
++been identified in prior community discussions.
++
++To enabled zswap, the "enabled" attribute must be set to 1 at boot time.  e.g.
++zswap.enabled=1
++
++Design:
++
++Zswap receives pages for compression through the Frontswap API and is able to
++evict pages from its own compressed pool on an LRU basis and write them back to
++the backing swap device in the case that the compressed pool is full.
++
++Zswap makes use of zbud for the managing the compressed memory pool.  Each
++allocation in zbud is not directly accessible by address.  Rather, a handle is
++return by the allocation routine and that handle must be mapped before being
++accessed.  The compressed memory pool grows on demand and shrinks as compressed
++pages are freed.  The pool is not preallocated.
++
++When a swap page is passed from frontswap to zswap, zswap maintains a mapping
++of the swap entry, a combination of the swap type and swap offset, to the zbud
++handle that references that compressed swap page.  This mapping is achieved
++with a red-black tree per swap type.  The swap offset is the search key for the
++tree nodes.
++
++During a page fault on a PTE that is a swap entry, frontswap calls the zswap
++load function to decompress the page into the page allocated by the page fault
++handler.
++
++Once there are no PTEs referencing a swap page stored in zswap (i.e. the count
++in the swap_map goes to 0) the swap code calls the zswap invalidate function,
++via frontswap, to free the compressed entry.
++
++Zswap seeks to be simple in its policies.  Sysfs attributes allow for one user
++controlled policies:
++* max_pool_percent - The maximum percentage of memory that the compressed
++    pool can occupy.
++
++Zswap allows the compressor to be selected at kernel boot time by setting the
++“compressor” attribute.  The default compressor is lzo.  e.g.
++zswap.compressor=deflate
++
++A debugfs interface is provided for various statistic about pool size, number
++of pages stored, and various counters for the reasons pages are rejected.
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0533-dma-buf-return-POLLIN-POLLOUT-instead-of-POLLERR.patch b/patches.tizen/0533-dma-buf-return-POLLIN-POLLOUT-instead-of-POLLERR.patch
new file mode 100644 (file)
index 0000000..05db4a0
--- /dev/null
@@ -0,0 +1,36 @@
+From 441dba5b258fa05e375d623f598a073ab40f253c Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Tue, 13 Aug 2013 13:47:57 +0900
+Subject: [PATCH 0533/1302] dma-buf: return POLLIN | POLLOUT instead of POLLERR
+
+It's not error if a dmabuf wasn't locked when select is called but
+rather that means there is no anyone accessing the dmabuf so return
+POLLIN | POLLOUT.
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/base/dma-buf.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
+index 53ade7b..e2e35ed 100644
+--- a/drivers/base/dma-buf.c
++++ b/drivers/base/dma-buf.c
+@@ -113,11 +113,11 @@ static unsigned int dma_buf_poll(struct file *filp,
+       }
+       /*
+-       * There is no anyone accessing this buffer so just return POLLERR.
++       * There is no anyone accessing this buffer so just return.
+        */
+       if (!robj->locked) {
+               mutex_unlock(&robj->lock);
+-              return POLLERR;
++              return POLLIN | POLLOUT;
+       }
+       poll_wait(filp, &robj->poll_wait, poll);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0534-iio-add-proximity-light-sensor-cm36651-driver-to-Kco.patch b/patches.tizen/0534-iio-add-proximity-light-sensor-cm36651-driver-to-Kco.patch
new file mode 100644 (file)
index 0000000..2dcdb80
--- /dev/null
@@ -0,0 +1,47 @@
+From cebcc7fbebf6255c8df5764109f290fa39330175 Mon Sep 17 00:00:00 2001
+From: Beomho Seo <beomho.seo@samsung.com>
+Date: Wed, 14 Aug 2013 11:54:56 +0900
+Subject: [PATCH 0534/1302] iio:add proximity/light sensor cm36651 driver to
+ Kconfig and Makefile - Add cm36651 proximity/light sensor to Kconfig to
+ enable compilation - Add cm36651 proximity/light sensor to Makefile to enable
+ compilation
+
+Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iio/light/Kconfig  | 11 +++++++++++
+ drivers/iio/light/Makefile |  1 +
+ 2 files changed, 12 insertions(+)
+
+diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
+index 176ef6d..ad1d60a 100644
+--- a/drivers/iio/light/Kconfig
++++ b/drivers/iio/light/Kconfig
+@@ -75,4 +75,15 @@ config HID_SENSOR_ALS
+         Say yes here to build support for the HID SENSOR
+         Ambient light sensor.
++config CM36651
++      depends on I2C
++      tristate "CM36651 driver"
++      default n
++      help
++        Sya Y here if you use cm36651.
++        This option enables proximity & RGB sensor using
++        Capella cm36651 device driver.
++
++        Say N here if you do not use cm36651.
++
+ endmenu
+diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile
+index 9621b18..53bf410 100644
+--- a/drivers/iio/light/Makefile
++++ b/drivers/iio/light/Makefile
+@@ -8,3 +8,4 @@ obj-$(CONFIG_SENSORS_TSL2563)  += tsl2563.o
+ obj-$(CONFIG_VCNL4000)                += vcnl4000.o
+ obj-$(CONFIG_HID_SENSOR_ALS)  += hid-sensor-als.o
+ obj-$(CONFIG_GP2AP002A00F)    += gp2ap002a00f.o
++obj-$(CONFIG_CM36651)         += cm36651.o
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0535-ARM-tizen_defconfig-add-cm36651-proxmity-light-senso.patch b/patches.tizen/0535-ARM-tizen_defconfig-add-cm36651-proxmity-light-senso.patch
new file mode 100644 (file)
index 0000000..d611be6
--- /dev/null
@@ -0,0 +1,31 @@
+From 8660c77e087e90f612b42ef53e95d39cebbe447d Mon Sep 17 00:00:00 2001
+From: Beomho Seo <beomho.seo@samsung.com>
+Date: Wed, 14 Aug 2013 11:56:48 +0900
+Subject: [PATCH 0535/1302] ARM: tizen_defconfig: add cm36651 proxmity/light
+ sensor config - Add cm36651 proximity/light sensor configuration - Disable
+ gp2ap002a00f proximity/light sensor configuration
+
+Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_defconfig | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index e36edb1..dbee6bd 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -2939,7 +2939,9 @@ CONFIG_IIO_ST_GYRO_SPI_3AXIS=y
+ # CONFIG_ADJD_S311 is not set
+ # CONFIG_SENSORS_TSL2563 is not set
+ # CONFIG_VCNL4000 is not set
+-CONFIG_GP2AP002A00F=y
++#CONFIG_GP2AP002A00F is not set
++CONFIG_CM36651=y
++
+ #
+ # Magnetometer sensors
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0536-TRATS2-dts-exynos4412-m0.dts-Add-cm36651-proximity-l.patch b/patches.tizen/0536-TRATS2-dts-exynos4412-m0.dts-Add-cm36651-proximity-l.patch
new file mode 100644 (file)
index 0000000..30c5bc0
--- /dev/null
@@ -0,0 +1,76 @@
+From 611aca94d901b25476d065a8d402c9722b2709d0 Mon Sep 17 00:00:00 2001
+From: Beomho Seo <beomho.seo@samsung.com>
+Date: Wed, 14 Aug 2013 12:01:53 +0900
+Subject: [PATCH 0536/1302] TRATS2: dts: exynos4412-m0.dts: Add cm36651
+ proximity/light sensor node - Support cm36651 proximity/light sensor device
+ for TRATS2 board - Add also the binding documentation file
+
+Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/iio/light/cm36651.txt      | 24 ++++++++++++++++++++++
+ arch/arm/boot/dts/exynos4412-m0.dts                | 17 +++++++++++++++
+ 2 files changed, 41 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/iio/light/cm36651.txt
+
+diff --git a/Documentation/devicetree/bindings/iio/light/cm36651.txt b/Documentation/devicetree/bindings/iio/light/cm36651.txt
+new file mode 100644
+index 0000000..975296f
+--- /dev/null
++++ b/Documentation/devicetree/bindings/iio/light/cm36651.txt
+@@ -0,0 +1,24 @@
++* CAPELLA CM36651 I2C Proximity sensor with Color sensor
++
++Required properties:
++- compatible: must be "capella,cm36651" or "cm36651"
++- reg: the I2C address of light sensor
++- interrupts: interrupt to which the chip is connected
++- vled-suppled: regulator for the sensor device, refere to
++              Documentation/devicetree/bindings/regulator/regulator.txt
++
++Example:
++
++      i2c_cm36651: i2c-gpio-2 {
++              /* ... */
++
++              cm36651@18 {
++                      compatible = "cm36651";
++                      reg = <0x18>;
++                      interrupt-parent = <&gpx0>;
++                      interrupts = <2 0>;
++                      vled-supply = <&ps_als_reg>;
++              };
++
++              /* ... */
++      };
+diff --git a/arch/arm/boot/dts/exynos4412-m0.dts b/arch/arm/boot/dts/exynos4412-m0.dts
+index fbefee6..12c7078 100644
+--- a/arch/arm/boot/dts/exynos4412-m0.dts
++++ b/arch/arm/boot/dts/exynos4412-m0.dts
+@@ -90,6 +90,23 @@
+               };
+       };
++      i2c_cm36651: i2c-gpio-2 {
++              compatible = "i2c-gpio";
++              gpios = <&gpf0 0 0>, <&gpf0 1 0>;
++              i2c-gpio,delay-us = <2>;
++              #address-cells = <1>;
++              #size-cells = <0>;
++              status = "okay";
++
++              cm36651@18 {
++                      compatible = "cm36651";
++                      reg = <0x18>;
++                      interrupt-parent = <&gpx0>;
++                      interrupts = <2 0>;
++                      vled-supply = <&ps_als_reg>;
++              };
++      };
++
+       camera {
+               status = "okay";
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0537-iio-add-proximity-light-sensor-cm36651-driver.patch b/patches.tizen/0537-iio-add-proximity-light-sensor-cm36651-driver.patch
new file mode 100644 (file)
index 0000000..d752293
--- /dev/null
@@ -0,0 +1,670 @@
+From 0c85546b320459ab6062366b2800b5d04efbea9b Mon Sep 17 00:00:00 2001
+From: Beomho Seo <beomho.seo@samsung.com>
+Date: Wed, 14 Aug 2013 13:04:49 +0900
+Subject: [PATCH 0537/1302] iio: add proximity/light sensor cm36651 driver -
+ Add proximity/light sensor cm36651 driver using iio subsystem
+
+Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iio/light/cm36651.c | 648 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 648 insertions(+)
+ create mode 100644 drivers/iio/light/cm36651.c
+
+diff --git a/drivers/iio/light/cm36651.c b/drivers/iio/light/cm36651.c
+new file mode 100644
+index 0000000..92a837b
+--- /dev/null
++++ b/drivers/iio/light/cm36651.c
+@@ -0,0 +1,648 @@
++/*
++ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
++ *
++ * This program is free software; you can redistribute  it and/or modify it
++ * under  the terms of  the GNU General  Public License as published by the
++ * Free Software Foundation;  either version 2 of the  License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/i2c.h>
++#include <linux/mutex.h>
++#include <linux/module.h>
++#include <linux/interrupt.h>
++#include <linux/regulator/consumer.h>
++#include <linux/iio/iio.h>
++#include <linux/iio/sysfs.h>
++#include <linux/iio/events.h>
++
++#define       CM36651_VENDOR          "CAPELLA"
++#define       CHIP_ID                 "CM36651"
++
++#define I2C_M_WR      0 /* for i2c Write */
++#define I2c_M_RD      1 /* for i2c Read */
++
++/* slave addresses */
++#define CM36651_ALS   0x30 /* 7bits : 0x18 */
++#define CM36651_PS    0x32 /* 7bits : 0x19 */
++
++/* Ambient light sensor */
++#define CS_CONF1      0x00
++#define CS_CONF2      0x01
++#define CS_CONF3      0x06
++
++#define RED           0x00
++#define GREEN         0x01
++#define BLUE          0x02
++#define WHITE         0x03
++
++/* Proximity sensor */
++#define PS_CONF1      0x00
++#define PS_THD                0x01
++#define PS_CANC               0x02
++#define PS_CONF2      0x03
++
++#define ALS_REG_NUM   3
++#define PS_REG_NUM    4
++#define ALS_CHANNEL_NUM       4
++#define INITIAL_THD   0x09
++#define SCAN_MODE_LIGHT       0
++#define SCAN_MODE_PROX        1
++
++enum {
++      LIGHT_EN,
++      PROXIMITY_EN,
++      PROXIMITY_EV_EN,
++};
++
++enum cm36651_cmd {
++      READ_RAW_LIGHT,
++      READ_RAW_PROXIMITY,
++      PROX_EV_EN,
++      PROX_EV_DIS,
++};
++
++enum {
++      CLOSE_PROXIMITY,
++      FAR_PROXIMITY,
++};
++
++/* register settings */
++static u8 als_reg_setting[ALS_REG_NUM][2] = {
++      {0x00, 0x04},   /* CS_CONF1 */
++      {0x01, 0x08},   /* CS_CONF2 */
++      {0x06, 0x00}    /* CS_CONF3 */
++};
++
++static u8 ps_reg_setting[PS_REG_NUM][2] = {
++      {0x00, 0x3C},   /* PS_CONF1 */
++      {0x01, 0x09},   /* PS_THD */
++      {0x02, 0x00},   /* PS_CANC */
++      {0x03, 0x13},   /* PS_CONF2 */
++};
++
++struct cm36651_data {
++      const struct cm36651_platform_data *pdata;
++      struct i2c_client *client;
++      struct mutex lock;
++      struct regulator *vled_reg;
++      unsigned long flags;
++      wait_queue_head_t data_ready_queue;
++      u8 temp;
++      u16 color[4];
++};
++
++int cm36651_i2c_read_byte(struct cm36651_data *cm36651, u8 addr, u8 *val)
++{
++      int ret = 0;
++      struct i2c_msg msg[1];
++      struct i2c_client *client = cm36651->client;
++
++      if ((client == NULL) || (!client->adapter))
++              return -ENODEV;
++
++      /* send slave address & command */
++      msg->addr = addr >> 1;
++      msg->flags = I2C_M_RD;
++      msg->len = 1;
++      msg->buf = val;
++
++      ret = i2c_transfer(client->adapter, msg, 1);
++      if (ret != 1) {
++              dev_err(&client->dev, "i2c transfer error ret=%d\n", ret);
++              ret = -EIO;
++      }
++
++      return 0;
++}
++
++int cm36651_i2c_read_word(struct cm36651_data *cm36651, u8 addr,
++                                                      u8 command, u16 *val)
++{
++      int ret = 0;
++      struct i2c_client *client = cm36651->client;
++      struct i2c_msg msg[2];
++      unsigned char data[2] = {0,};
++      u16 value = 0;
++
++      if ((client == NULL) || (!client->adapter))
++              return -ENODEV;
++
++      /* send slave address & command */
++      msg[0].addr = addr >> 1;
++      msg[0].flags = I2C_M_WR;
++      msg[0].len = 1;
++      msg[0].buf = &command;
++
++      /* read word data */
++      msg[1].addr = addr >> 1;
++      msg[1].flags = I2C_M_RD;
++      msg[1].len = 2;
++      msg[1].buf = data;
++
++      ret = i2c_transfer(client->adapter, msg, 2);
++      if (ret != 2) {
++              dev_err(&client->dev, "i2c transfer error ret=%d\n", ret);
++              ret = -EIO;
++      }
++      value = (u16)data[1];
++      *val = (value << 8) | (u16)data[0];
++
++      return 0;
++}
++
++int cm36651_i2c_write_byte(struct cm36651_data *cm36651, u8 addr,
++                                                       u8 command, u8 val)
++{
++      int ret = 0;
++      struct i2c_client *client = cm36651->client;
++      struct i2c_msg msg[1];
++      unsigned char data[2];
++
++      if ((client == NULL) || (!client->adapter))
++              return -ENODEV;
++
++      data[0] = command;
++      data[1] = val;
++
++      /* send slave address & command */
++      msg->addr = addr >> 1;
++      msg->flags = I2C_M_WR;
++      msg->len = 2;
++      msg->buf = data;
++
++      ret = i2c_transfer(client->adapter, msg, 1);
++      if (ret != 1) {
++              dev_err(&client->dev, "i2c transfer error ret=%d\n", ret);
++              ret = -EIO;
++      }
++
++      return 0;
++}
++
++static int cm36651_setup_reg(struct cm36651_data *cm36651)
++{
++      struct i2c_client *client = cm36651->client;
++      int ret = 0, i = 0;
++      u8 tmp = 0;
++
++      /* ALS initialization */
++      for (i = 0; i < ALS_REG_NUM; i++) {
++              ret = cm36651_i2c_write_byte(cm36651, CM36651_ALS,
++                      als_reg_setting[i][0], als_reg_setting[i][1]);
++              if (ret < 0)
++                      goto err_setup_reg;
++      }
++
++      /* PS initialization */
++      for (i = 0; i < PS_REG_NUM; i++) {
++              ret = cm36651_i2c_write_byte(cm36651, CM36651_PS,
++                      ps_reg_setting[i][0], ps_reg_setting[i][1]);
++              if (ret < 0)
++                      goto err_setup_reg;
++      }
++
++      /* printing the inital proximity value with no contact */
++      ret = cm36651_i2c_read_byte(cm36651, CM36651_PS, &tmp);
++      if (ret < 0)
++              goto err_setup_reg;
++
++      dev_dbg(&client->dev, "initial proximity value = %d\n", tmp);
++
++      /* turn off */
++      cm36651_i2c_write_byte(cm36651, CM36651_ALS, CS_CONF1, 0x01);
++      cm36651_i2c_write_byte(cm36651, CM36651_PS, PS_CONF1, 0x01);
++
++      return 0;
++
++err_setup_reg:
++      dev_err(&client->dev, "cm36651 register failed. %d\n", ret);
++      return ret;
++}
++
++static ssize_t cm36651_vendor_show(struct device *dev,
++              struct device_attribute *attr, char *buf)
++{
++      return sprintf(buf, "%s\n", CM36651_VENDOR);
++}
++
++static ssize_t proximity_thresh_show(struct device *dev,
++              struct device_attribute *attr, char *buf)
++{
++      return sprintf(buf, "prox_threshold = %d\n", ps_reg_setting[1][1]);
++}
++
++static ssize_t proximity_thresh_store(struct device *dev,
++              struct device_attribute *attr, const char *buf, size_t size)
++{
++      struct iio_dev *dev_info = dev_to_iio_dev(dev);
++      struct cm36651_data *cm36651 = iio_priv(dev_info);
++      struct i2c_client *client = cm36651->client;
++      u8 thresh_value = INITIAL_THD;
++      int ret = 0;
++
++      ret = kstrtou8(buf, 10, &thresh_value);
++      if (ret < 0)
++              dev_err(dev, "kstrtoint failed\n");
++
++      ps_reg_setting[1][1] = thresh_value;
++      ret = cm36651_i2c_write_byte(cm36651, CM36651_PS,
++                      PS_THD, ps_reg_setting[1][1]);
++      if (ret < 0) {
++              dev_err(dev, "PS reg is failed. %d\n", ret);
++              return ret;
++      }
++      dev_info(&client->dev, "new threshold = 0x%x\n", ps_reg_setting[1][1]);
++      msleep(150);
++
++      return size;
++}
++
++static int cm36651_read_output(struct cm36651_data *cm36651,
++                                              u8 address, int *val)
++{
++      struct i2c_client *client = cm36651->client;
++      int i = 0, ret = -EINVAL;
++      u8 prox_val;
++
++      switch (address) {
++      case CM36651_ALS:
++              for (i = 0; i < ALS_CHANNEL_NUM; i++) {
++                      ret = cm36651_i2c_read_word(cm36651, address,
++                                                      i, &cm36651->color[i]);
++                      if (ret < 0)
++                              goto read_err;
++              }
++
++              dev_info(&client->dev, "%d, %d, %d, %d\n",
++                      cm36651->color[0]+1, cm36651->color[1]+1,
++                      cm36651->color[2]+1, cm36651->color[3]+1);
++              break;
++      case CM36651_PS:
++              ret = cm36651_i2c_read_byte(cm36651, address, &prox_val);
++              if (ret < 0)
++                      goto read_err;
++
++              dev_info(&client->dev, "%d\n", prox_val);
++              break;
++      }
++
++      ret = cm36651_i2c_write_byte(cm36651, address, 0x00, 0x01);
++      if (ret < 0)
++              goto write_err;
++
++      return ret;
++
++read_err:
++      dev_err(&client->dev, "fail to read sensor value");
++      return ret;
++write_err:
++      dev_err(&client->dev, "fail to write register value");
++      return ret;
++}
++
++static irqreturn_t cm36651_irq_handler(int irq, void *data)
++{
++      struct iio_dev *indio_dev = data;
++      struct cm36651_data *cm36651 = iio_priv(indio_dev);
++      struct i2c_client *client = cm36651->client;
++      int ev_dir, val, ret;
++      u64 ev_code;
++
++      ret =  cm36651_i2c_read_byte(cm36651, CM36651_PS, &cm36651->temp);
++      if (ret < 0) {
++              dev_err(&client->dev, "read data is failed. %d\n", ret);
++              return ret;
++      }
++
++      if (cm36651->temp < ps_reg_setting[1][1]) {
++              ev_dir = IIO_EV_DIR_RISING;
++              val = FAR_PROXIMITY;
++      } else {
++              ev_dir = IIO_EV_DIR_FALLING;
++              val = CLOSE_PROXIMITY;
++      }
++
++      ev_code = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, READ_RAW_PROXIMITY,
++                                              IIO_EV_TYPE_THRESH, ev_dir);
++
++      iio_push_event(indio_dev, ev_code, iio_get_time_ns());
++      cm36651_i2c_read_byte(cm36651, CM36651_PS, &cm36651->temp);
++      dev_info(&client->dev, "val: %d, ps_data: %d(close:0, far:1)\n",
++                                                      val, cm36651->temp);
++
++      return IRQ_HANDLED;
++}
++
++static int cm36651_set_operation_mode(struct cm36651_data *cm36651,
++                                              enum cm36651_cmd cmd)
++{
++      struct i2c_client *client = cm36651->client;
++      int ret = 0;
++      int i;
++
++      switch (cmd) {
++      case READ_RAW_LIGHT:
++              ret = cm36651_i2c_write_byte(cm36651, CM36651_ALS,
++                                                      CS_CONF1, 0x04);
++              break;
++      case READ_RAW_PROXIMITY:
++              ret = cm36651_i2c_write_byte(cm36651, CM36651_PS,
++                                                      PS_CONF1, 0x3C);
++              break;
++      case PROX_EV_EN:
++              if (test_bit(PROXIMITY_EV_EN, &cm36651->flags)) {
++                      dev_err(&client->dev, "Aleady enable state\n");
++                      return -EINVAL;
++              }
++              set_bit(PROXIMITY_EV_EN, &cm36651->flags);
++
++              /* enable setting */
++              for (i = 0; i < 4; i++) {
++                      cm36651_i2c_write_byte(cm36651, CM36651_PS,
++                              ps_reg_setting[i][0], ps_reg_setting[i][1]);
++              }
++              enable_irq(client->irq);
++              break;
++      case PROX_EV_DIS:
++              if (!test_bit(PROXIMITY_EV_EN, &cm36651->flags)) {
++                      dev_err(&client->dev, "Aleady disable state\n");
++                      return -EINVAL;
++              }
++              clear_bit(PROXIMITY_EV_EN, &cm36651->flags);
++              disable_irq(client->irq);
++
++              /* disable setting */
++              cm36651_i2c_write_byte(cm36651, CM36651_PS, PS_CONF1, 0x01);
++              break;
++      }
++      return ret;
++}
++
++static int cm36651_read_channel(struct cm36651_data *cm36651,
++                              struct iio_chan_spec const *chan, int *val)
++{
++      struct i2c_client *client = cm36651->client;
++      enum cm36651_cmd cmd = 0;
++      int ret;
++
++      switch (chan->scan_index) {
++      case SCAN_MODE_LIGHT:
++              cmd = READ_RAW_LIGHT;
++              break;
++      case SCAN_MODE_PROX:
++              cmd = READ_RAW_PROXIMITY;
++              break;
++      }
++
++      ret = cm36651_set_operation_mode(cm36651, cmd);
++      if (ret < 0) {
++              dev_err(&client->dev, "cm36651 set operation mode failed\n");
++              return ret;
++      }
++
++      msleep(50);
++      ret = cm36651_read_output(cm36651, chan->address, val);
++      if (ret < 0) {
++              dev_err(&client->dev, "cm36651 read output failed\n");
++              return ret;
++      }
++
++      return 0;
++}
++
++static int cm36651_read_raw(struct iio_dev *indio_dev,
++                          struct iio_chan_spec const *chan,
++                          int *val, int *val2, long mask)
++{
++      struct cm36651_data *cm36651 = iio_priv(indio_dev);
++      int ret = -EINVAL;
++
++      mutex_lock(&cm36651->lock);
++
++      switch (mask) {
++      case IIO_CHAN_INFO_RAW:
++              ret = cm36651_read_channel(cm36651, chan, val);
++              break;
++      }
++      mutex_unlock(&cm36651->lock);
++
++      return ret;
++}
++
++static int cm36651_read_event_val(struct iio_dev *indio_dev,
++                                      u64 event_code, int *val)
++{
++      struct cm36651_data *cm36651 = iio_priv(indio_dev);
++      int chan_type = IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code);
++      int event_type = IIO_EVENT_CODE_EXTRACT_TYPE(event_code);
++
++      if (event_type != IIO_EV_TYPE_THRESH || chan_type != IIO_PROXIMITY)
++              return -EINVAL;
++
++      *val = cm36651->temp;
++      return 0;
++}
++
++static int cm36651_write_event_config(struct iio_dev *indio_dev,
++                                      u64 event_code, int state)
++{
++      struct cm36651_data *cm36651 = iio_priv(indio_dev);
++      enum cm36651_cmd cmd;
++      int chan_type = IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code);
++      int ret = -EINVAL;
++
++      mutex_lock(&cm36651->lock);
++
++      if (chan_type == IIO_PROXIMITY) {
++              cmd = state ? PROX_EV_EN : PROX_EV_DIS;
++              ret = cm36651_set_operation_mode(cm36651, cmd);
++      }
++
++      mutex_unlock(&cm36651->lock);
++
++      return ret;
++}
++
++static int cm36651_read_event_config(struct iio_dev *indio_dev, u64 event_code)
++{
++      struct cm36651_data *cm36651 = iio_priv(indio_dev);
++      int chan_type = IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code);
++      int event_en = -EINVAL;
++
++      mutex_lock(&cm36651->lock);
++
++      if (chan_type == IIO_PROXIMITY)
++              event_en = test_bit(PROXIMITY_EV_EN, &cm36651->flags);
++
++      mutex_unlock(&cm36651->lock);
++
++      return event_en;
++}
++
++static IIO_DEVICE_ATTR(vendor, 0644, cm36651_vendor_show, NULL, 0);
++static IIO_DEVICE_ATTR(prox_thresh, 0644, proximity_thresh_show,
++                                      proximity_thresh_store, 1);
++
++static struct attribute *cm36651_attributes[] = {
++      &iio_dev_attr_vendor.dev_attr.attr,
++      &iio_dev_attr_prox_thresh.dev_attr.attr,
++      NULL
++};
++
++static struct attribute_group cm36651_attribute_group = {
++      .attrs = cm36651_attributes,
++};
++
++static const struct iio_chan_spec cm36651_channels[] = {
++      {
++              .type = IIO_LIGHT,
++              .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++              .scan_type = {
++                      .sign = 'u',
++                      .realbits = 16,
++                      .shift = 0,
++                      .storagebits = 16,
++              },
++              .address = CM36651_ALS,
++              .scan_index = SCAN_MODE_LIGHT
++      },
++      {
++              .type = IIO_PROXIMITY,
++              .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++              .scan_type = {
++                      .sign = 'u',
++                      .realbits = 8,
++                      .shift = 0,
++                      .storagebits = 8,
++              },
++              .address = CM36651_PS,
++              .scan_index = SCAN_MODE_PROX,
++              .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER)
++      },
++};
++
++static const struct iio_info cm36651_info = {
++      .driver_module = THIS_MODULE,
++      .read_raw = &cm36651_read_raw,
++      .read_event_value = &cm36651_read_event_val,
++      .read_event_config = &cm36651_read_event_config,
++      .write_event_config = &cm36651_write_event_config,
++      .attrs = &cm36651_attribute_group,
++};
++
++static int cm36651_probe(struct i2c_client *client,
++                           const struct i2c_device_id *id)
++{
++      struct cm36651_data *cm36651;
++      struct iio_dev *indio_dev;
++      unsigned long irqflag;
++      int ret;
++
++      dev_info(&client->dev, "cm36651 light/proxymity sensor probe\n");
++
++      indio_dev = iio_device_alloc(sizeof(*cm36651));
++      if (indio_dev == NULL) {
++              ret = -ENOMEM;
++              goto error_ret;
++      }
++
++      cm36651 = iio_priv(indio_dev);
++
++      cm36651->vled_reg = devm_regulator_get(&client->dev, "vled");
++      if (IS_ERR(cm36651->vled_reg)) {
++              dev_err(&client->dev, "failed to get regulator vled\n");
++              ret =  PTR_ERR(cm36651->vled_reg);
++              return ret;
++      }
++
++      ret = regulator_enable(cm36651->vled_reg);
++      if (ret) {
++              dev_err(&client->dev, "faile to enable regulator\n");
++              goto error_put_reg;
++      }
++
++      i2c_set_clientdata(client, indio_dev);
++
++      cm36651->client = client;
++      init_waitqueue_head(&cm36651->data_ready_queue);
++
++      ret = cm36651_setup_reg(cm36651);
++
++      mutex_init(&cm36651->lock);
++      indio_dev->dev.parent = &client->dev;
++      indio_dev->channels = cm36651_channels;
++      indio_dev->num_channels = ARRAY_SIZE(cm36651_channels);
++      indio_dev->info = &cm36651_info;
++      indio_dev->name = id->name;
++      indio_dev->modes = INDIO_DIRECT_MODE;
++
++      irqflag = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
++      ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
++              &cm36651_irq_handler, irqflag, "proximity_int", indio_dev);
++      if (ret) {
++              dev_err(&client->dev, "failed to request irq\n");
++              goto error_ret;
++      }
++
++      disable_irq(client->irq);
++
++      ret = iio_device_register(indio_dev);
++      if (ret)
++              goto exit_free_iio;
++
++      return 0;
++
++error_ret:
++      return ret;
++error_put_reg:
++      regulator_put(cm36651->vled_reg);
++      return ret;
++exit_free_iio:
++      iio_device_free(indio_dev);
++      return ret;
++}
++
++static int cm36651_remove(struct i2c_client *client)
++{
++      struct iio_dev *indio_dev = i2c_get_clientdata(client);
++      struct cm36651_data *cm36651 = iio_priv(indio_dev);
++
++      iio_device_unregister(indio_dev);
++      regulator_disable(cm36651->vled_reg);
++
++      iio_device_free(indio_dev);
++
++      return 0;
++}
++
++static const struct i2c_device_id cm36651_id[] = {
++      {"cm36651", 0},
++      {}
++};
++
++MODULE_DEVICE_TABLE(i2c, cm36651_id);
++
++static const struct of_device_id cm36651_of_match[] = {
++      { .compatible = "capella,cm36651" },
++      { .compatible = "cm36651"},
++      { }
++};
++
++static struct i2c_driver cm36651_driver = {
++      .driver = {
++              .name   = "cm36651",
++              .of_match_table = of_match_ptr(cm36651_of_match),
++              .owner  = THIS_MODULE,
++      },
++      .probe          = cm36651_probe,
++      .remove         = cm36651_remove,
++      .id_table       = cm36651_id,
++};
++
++module_i2c_driver(cm36651_driver);
++
++MODULE_AUTHOR("Samsung Electronics");
++MODULE_DESCRIPTION("Light/Proximity Sensor device driver for cm36651");
++MODULE_LICENSE("GPL v2");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0538-drm-exynos-Add-missing-includes.patch b/patches.tizen/0538-drm-exynos-Add-missing-includes.patch
new file mode 100644 (file)
index 0000000..feaf65a
--- /dev/null
@@ -0,0 +1,148 @@
+From f526e2e46a0e12c89626730989afe7a16864893e Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@linaro.org>
+Date: Tue, 13 Aug 2013 00:46:40 +0100
+Subject: [PATCH 0538/1302] drm/exynos: Add missing includes
+
+Ensure that all externally accessed functions are correctly prototyped
+when defined in each file by making sure the headers with the protoypes
+are included in the file with the definition.
+
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_connector.c | 1 +
+ drivers/gpu/drm/exynos/exynos_drm_crtc.c      | 1 +
+ drivers/gpu/drm/exynos/exynos_drm_dmabuf.c    | 1 +
+ drivers/gpu/drm/exynos/exynos_drm_fbdev.c     | 1 +
+ drivers/gpu/drm/exynos/exynos_drm_fimc.c      | 1 +
+ drivers/gpu/drm/exynos/exynos_drm_g2d.c       | 1 +
+ drivers/gpu/drm/exynos/exynos_drm_gsc.c       | 1 +
+ drivers/gpu/drm/exynos/exynos_drm_plane.c     | 1 +
+ drivers/gpu/drm/exynos/exynos_drm_rotator.c   | 1 +
+ drivers/gpu/drm/exynos/exynos_drm_vidi.c      | 1 +
+ 10 files changed, 10 insertions(+)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c
+index e5c1a01..902e0be 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_connector.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c
+@@ -17,6 +17,7 @@
+ #include <drm/exynos_drm.h>
+ #include "exynos_drm_drv.h"
+ #include "exynos_drm_encoder.h"
++#include "exynos_drm_connector.h"
+ #define to_exynos_connector(x)        container_of(x, struct exynos_drm_connector,\
+                               drm_connector)
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+index c200e4d..9bafae7 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+@@ -15,6 +15,7 @@
+ #include <drm/drmP.h>
+ #include <drm/drm_crtc_helper.h>
++#include "exynos_drm_crtc.h"
+ #include "exynos_drm_drv.h"
+ #include "exynos_drm_encoder.h"
+ #include "exynos_drm_plane.h"
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
+index 99ff8dc..0fe74e1 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
+@@ -11,6 +11,7 @@
+ #include <drm/drmP.h>
+ #include <drm/exynos_drm.h>
++#include "exynos_drm_dmabuf.h"
+ #include "exynos_drm_drv.h"
+ #include "exynos_drm_gem.h"
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+index 8f007aa..45b6cb3 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+@@ -19,6 +19,7 @@
+ #include "exynos_drm_drv.h"
+ #include "exynos_drm_fb.h"
++#include "exynos_drm_fbdev.h"
+ #include "exynos_drm_gem.h"
+ #include "exynos_drm_iommu.h"
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+index 4a1616a..a83e664 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+@@ -22,6 +22,7 @@
+ #include <drm/drmP.h>
+ #include <drm/exynos_drm.h>
+ #include "regs-fimc.h"
++#include "exynos_drm_drv.h"
+ #include "exynos_drm_ipp.h"
+ #include "exynos_drm_fimc.h"
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+index 115940b..ae81551 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+@@ -24,6 +24,7 @@
+ #include <drm/drmP.h>
+ #include <drm/exynos_drm.h>
+ #include "exynos_drm_drv.h"
++#include "exynos_drm_g2d.h"
+ #include "exynos_drm_gem.h"
+ #include "exynos_drm_iommu.h"
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
+index 762f40d..4683251 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
+@@ -21,6 +21,7 @@
+ #include <drm/drmP.h>
+ #include <drm/exynos_drm.h>
+ #include "regs-gsc.h"
++#include "exynos_drm_drv.h"
+ #include "exynos_drm_ipp.h"
+ #include "exynos_drm_gsc.h"
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
+index 83efc66..63ebeeb 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
+@@ -16,6 +16,7 @@
+ #include "exynos_drm_encoder.h"
+ #include "exynos_drm_fb.h"
+ #include "exynos_drm_gem.h"
++#include "exynos_drm_plane.h"
+ #define to_exynos_plane(x)    container_of(x, struct exynos_plane, base)
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
+index 3d38a91..185306e 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_rotator.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
+@@ -22,6 +22,7 @@
+ #include <drm/exynos_drm.h>
+ #include "regs-rotator.h"
+ #include "exynos_drm.h"
++#include "exynos_drm_drv.h"
+ #include "exynos_drm_ipp.h"
+ /*
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+index 3b2aa26..bb73949 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+@@ -24,6 +24,7 @@
+ #include "exynos_drm_drv.h"
+ #include "exynos_drm_crtc.h"
+ #include "exynos_drm_encoder.h"
++#include "exynos_drm_vidi.h"
+ /* vidi has totally three virtual windows. */
+ #define WINDOWS_NR            3
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0539-drm-exynos-Remove-module.h-header-inclusion.patch b/patches.tizen/0539-drm-exynos-Remove-module.h-header-inclusion.patch
new file mode 100644 (file)
index 0000000..a8b9b5e
--- /dev/null
@@ -0,0 +1,173 @@
+From f6f6fb0b434a3c6f385e6681b159761bac779726 Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Fri, 26 Jul 2013 13:29:19 +0530
+Subject: [PATCH 0539/1302] drm/exynos: Remove module.h header inclusion
+
+Remove module.h header file inclusion from files since they do
+not use/refer to any code from that file.
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_ddc.c         | 1 -
+ drivers/gpu/drm/exynos/exynos_drm_fimc.c    | 1 -
+ drivers/gpu/drm/exynos/exynos_drm_fimd.c    | 1 -
+ drivers/gpu/drm/exynos/exynos_drm_g2d.c     | 1 -
+ drivers/gpu/drm/exynos/exynos_drm_gsc.c     | 1 -
+ drivers/gpu/drm/exynos/exynos_drm_hdmi.c    | 1 -
+ drivers/gpu/drm/exynos/exynos_drm_ipp.c     | 1 -
+ drivers/gpu/drm/exynos/exynos_drm_rotator.c | 1 -
+ drivers/gpu/drm/exynos/exynos_drm_vidi.c    | 1 -
+ drivers/gpu/drm/exynos/exynos_hdmi.c        | 1 -
+ drivers/gpu/drm/exynos/exynos_hdmiphy.c     | 1 -
+ drivers/gpu/drm/exynos/exynos_mixer.c       | 1 -
+ 12 files changed, 12 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_ddc.c b/drivers/gpu/drm/exynos/exynos_ddc.c
+index 4e9b5ba..ee9b889 100644
+--- a/drivers/gpu/drm/exynos/exynos_ddc.c
++++ b/drivers/gpu/drm/exynos/exynos_ddc.c
+@@ -15,7 +15,6 @@
+ #include <linux/kernel.h>
+ #include <linux/i2c.h>
+-#include <linux/module.h>
+ #include "exynos_drm_drv.h"
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+index a83e664..087f5bb 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+@@ -12,7 +12,6 @@
+  *
+  */
+ #include <linux/kernel.h>
+-#include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/regmap.h>
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+index 5c68289..2622369 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+@@ -14,7 +14,6 @@
+ #include <drm/drmP.h>
+ #include <linux/kernel.h>
+-#include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/clk.h>
+ #include <linux/of_device.h>
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+index ae81551..222950d 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+@@ -8,7 +8,6 @@
+  */
+ #include <linux/kernel.h>
+-#include <linux/module.h>
+ #include <linux/clk.h>
+ #include <linux/err.h>
+ #include <linux/interrupt.h>
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
+index 4683251..862a55b 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
+@@ -12,7 +12,6 @@
+  *
+  */
+ #include <linux/kernel.h>
+-#include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/clk.h>
+ #include <linux/pm_runtime.h>
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
+index 437fb94..d0bca57 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
+@@ -15,7 +15,6 @@
+ #include <linux/kernel.h>
+ #include <linux/wait.h>
+-#include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_runtime.h>
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+index be1e884..df1e874 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+@@ -12,7 +12,6 @@
+  *
+  */
+ #include <linux/kernel.h>
+-#include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/types.h>
+ #include <linux/clk.h>
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
+index 185306e..f7ee022 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_rotator.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
+@@ -10,7 +10,6 @@
+  */
+ #include <linux/kernel.h>
+-#include <linux/module.h>
+ #include <linux/err.h>
+ #include <linux/interrupt.h>
+ #include <linux/io.h>
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+index bb73949..ebe332b 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+@@ -13,7 +13,6 @@
+ #include <drm/drmP.h>
+ #include <linux/kernel.h>
+-#include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <drm/exynos_drm.h>
+diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
+index fd1426d..0432ede 100644
+--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
++++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
+@@ -24,7 +24,6 @@
+ #include <linux/spinlock.h>
+ #include <linux/wait.h>
+ #include <linux/i2c.h>
+-#include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/interrupt.h>
+ #include <linux/irq.h>
+diff --git a/drivers/gpu/drm/exynos/exynos_hdmiphy.c b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
+index ea49d13..10a2848 100644
+--- a/drivers/gpu/drm/exynos/exynos_hdmiphy.c
++++ b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
+@@ -15,7 +15,6 @@
+ #include <linux/kernel.h>
+ #include <linux/i2c.h>
+-#include <linux/module.h>
+ #include "exynos_drm_drv.h"
+ #include "exynos_hdmi.h"
+diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
+index 7c197d38..b9cf88f 100644
+--- a/drivers/gpu/drm/exynos/exynos_mixer.c
++++ b/drivers/gpu/drm/exynos/exynos_mixer.c
+@@ -23,7 +23,6 @@
+ #include <linux/spinlock.h>
+ #include <linux/wait.h>
+ #include <linux/i2c.h>
+-#include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/interrupt.h>
+ #include <linux/irq.h>
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0540-drm-exynos-Add-missing-of.h-header-include.patch b/patches.tizen/0540-drm-exynos-Add-missing-of.h-header-include.patch
new file mode 100644 (file)
index 0000000..6e4d6d9
--- /dev/null
@@ -0,0 +1,95 @@
+From 5ccfab2a31bb421ca5d2ef029717702c73f479b5 Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Wed, 14 Aug 2013 16:38:01 +0530
+Subject: [PATCH 0540/1302] drm/exynos: Add missing of.h header include
+
+Add of.h explicitly for of_* APIs.
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_ddc.c      | 2 +-
+ drivers/gpu/drm/exynos/exynos_drm_fimc.c | 1 +
+ drivers/gpu/drm/exynos/exynos_drm_fimd.c | 1 +
+ drivers/gpu/drm/exynos/exynos_hdmi.c     | 1 +
+ drivers/gpu/drm/exynos/exynos_hdmiphy.c  | 1 +
+ drivers/gpu/drm/exynos/exynos_mixer.c    | 1 +
+ 6 files changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_ddc.c b/drivers/gpu/drm/exynos/exynos_ddc.c
+index ee9b889..45f28f7 100644
+--- a/drivers/gpu/drm/exynos/exynos_ddc.c
++++ b/drivers/gpu/drm/exynos/exynos_ddc.c
+@@ -15,7 +15,7 @@
+ #include <linux/kernel.h>
+ #include <linux/i2c.h>
+-
++#include <linux/of.h>
+ #include "exynos_drm_drv.h"
+ #include "exynos_hdmi.h"
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+index 087f5bb..fc62c81 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+@@ -17,6 +17,7 @@
+ #include <linux/regmap.h>
+ #include <linux/clk.h>
+ #include <linux/pm_runtime.h>
++#include <linux/of.h>
+ #include <drm/drmP.h>
+ #include <drm/exynos_drm.h>
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+index 2622369..0e602e3 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+@@ -16,6 +16,7 @@
+ #include <linux/kernel.h>
+ #include <linux/platform_device.h>
+ #include <linux/clk.h>
++#include <linux/of.h>
+ #include <linux/of_device.h>
+ #include <linux/pm_runtime.h>
+diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
+index 0432ede..3f5460e 100644
+--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
++++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
+@@ -32,6 +32,7 @@
+ #include <linux/clk.h>
+ #include <linux/regulator/consumer.h>
+ #include <linux/io.h>
++#include <linux/of.h>
+ #include <linux/of_gpio.h>
+ #include <drm/exynos_drm.h>
+diff --git a/drivers/gpu/drm/exynos/exynos_hdmiphy.c b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
+index 10a2848..0113471 100644
+--- a/drivers/gpu/drm/exynos/exynos_hdmiphy.c
++++ b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
+@@ -15,6 +15,7 @@
+ #include <linux/kernel.h>
+ #include <linux/i2c.h>
++#include <linux/of.h>
+ #include "exynos_drm_drv.h"
+ #include "exynos_hdmi.h"
+diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
+index b9cf88f..9cf165e 100644
+--- a/drivers/gpu/drm/exynos/exynos_mixer.c
++++ b/drivers/gpu/drm/exynos/exynos_mixer.c
+@@ -30,6 +30,7 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/clk.h>
+ #include <linux/regulator/consumer.h>
++#include <linux/of.h>
+ #include <drm/exynos_drm.h>
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0541-drm-exynos-Remove-redundant-error-messages.patch b/patches.tizen/0541-drm-exynos-Remove-redundant-error-messages.patch
new file mode 100644 (file)
index 0000000..2272cad
--- /dev/null
@@ -0,0 +1,495 @@
+From fed5c7af7fa06d8733b95e3867bd51a0988fe0ad Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Tue, 20 Aug 2013 17:11:26 +0900
+Subject: [PATCH 0541/1302] drm/exynos: Remove redundant error messages
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_buf.c       |  4 +---
+ drivers/gpu/drm/exynos/exynos_drm_connector.c |  4 +---
+ drivers/gpu/drm/exynos/exynos_drm_crtc.c      |  4 +---
+ drivers/gpu/drm/exynos/exynos_drm_dmabuf.c    |  1 -
+ drivers/gpu/drm/exynos/exynos_drm_drv.c       |  4 +---
+ drivers/gpu/drm/exynos/exynos_drm_encoder.c   |  4 +---
+ drivers/gpu/drm/exynos/exynos_drm_fb.c        |  8 ++------
+ drivers/gpu/drm/exynos/exynos_drm_fbdev.c     |  4 +---
+ drivers/gpu/drm/exynos/exynos_drm_fimc.c      |  4 +---
+ drivers/gpu/drm/exynos/exynos_drm_fimd.c      |  4 +---
+ drivers/gpu/drm/exynos/exynos_drm_g2d.c       | 15 +++------------
+ drivers/gpu/drm/exynos/exynos_drm_gem.c       |  4 +---
+ drivers/gpu/drm/exynos/exynos_drm_gsc.c       |  4 +---
+ drivers/gpu/drm/exynos/exynos_drm_hdmi.c      |  4 +---
+ drivers/gpu/drm/exynos/exynos_drm_ipp.c       | 22 +++++-----------------
+ drivers/gpu/drm/exynos/exynos_drm_plane.c     |  4 +---
+ drivers/gpu/drm/exynos/exynos_drm_rotator.c   |  8 ++------
+ drivers/gpu/drm/exynos/exynos_hdmi.c          | 16 ++++------------
+ drivers/gpu/drm/exynos/exynos_mixer.c         |  8 ++------
+ 19 files changed, 30 insertions(+), 96 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c b/drivers/gpu/drm/exynos/exynos_drm_buf.c
+index 57affae..cd3c49c 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_buf.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c
+@@ -155,10 +155,8 @@ struct exynos_drm_gem_buf *exynos_drm_init_buf(struct drm_device *dev,
+       DRM_DEBUG_KMS("desired size = 0x%x\n", size);
+       buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
+-      if (!buffer) {
+-              DRM_ERROR("failed to allocate exynos_drm_gem_buf.\n");
++      if (!buffer)
+               return NULL;
+-      }
+       buffer->size = size;
+       return buffer;
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c
+index 902e0be..f729f16 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_connector.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c
+@@ -326,10 +326,8 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
+       DRM_DEBUG_KMS("%s\n", __FILE__);
+       exynos_connector = kzalloc(sizeof(*exynos_connector), GFP_KERNEL);
+-      if (!exynos_connector) {
+-              DRM_ERROR("failed to allocate connector\n");
++      if (!exynos_connector)
+               return NULL;
+-      }
+       connector = &exynos_connector->drm_connector;
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+index 9bafae7..1de357a 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+@@ -347,10 +347,8 @@ int exynos_drm_crtc_create(struct drm_device *dev, unsigned int nr)
+       DRM_DEBUG_KMS("%s\n", __FILE__);
+       exynos_crtc = kzalloc(sizeof(*exynos_crtc), GFP_KERNEL);
+-      if (!exynos_crtc) {
+-              DRM_ERROR("failed to allocate exynos crtc\n");
++      if (!exynos_crtc)
+               return -ENOMEM;
+-      }
+       exynos_crtc->pipe = nr;
+       exynos_crtc->dpms = DRM_MODE_DPMS_OFF;
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
+index 0fe74e1..4b750ce 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
+@@ -290,7 +290,6 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev,
+       buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
+       if (!buffer) {
+-              DRM_ERROR("failed to allocate exynos_drm_gem_buf.\n");
+               ret = -ENOMEM;
+               goto err_unmap_attach;
+       }
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
+index ba6d995..1a07ff6 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
+@@ -49,10 +49,8 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
+       DRM_DEBUG_DRIVER("%s\n", __FILE__);
+       private = kzalloc(sizeof(struct exynos_drm_private), GFP_KERNEL);
+-      if (!private) {
+-              DRM_ERROR("failed to allocate private\n");
++      if (!private)
+               return -ENOMEM;
+-      }
+       INIT_LIST_HEAD(&private->pageflip_event_list);
+       dev->dev_private = (void *)private;
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+index c63721f..4296d8f 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+@@ -338,10 +338,8 @@ exynos_drm_encoder_create(struct drm_device *dev,
+               return NULL;
+       exynos_encoder = kzalloc(sizeof(*exynos_encoder), GFP_KERNEL);
+-      if (!exynos_encoder) {
+-              DRM_ERROR("failed to allocate encoder\n");
++      if (!exynos_encoder)
+               return NULL;
+-      }
+       exynos_encoder->dpms = DRM_MODE_DPMS_OFF;
+       exynos_encoder->manager = manager;
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c
+index 0e04f4e..e2a1a1f 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
+@@ -162,10 +162,8 @@ exynos_drm_framebuffer_init(struct drm_device *dev,
+       }
+       exynos_fb = kzalloc(sizeof(*exynos_fb), GFP_KERNEL);
+-      if (!exynos_fb) {
+-              DRM_ERROR("failed to allocate exynos drm framebuffer\n");
++      if (!exynos_fb)
+               return ERR_PTR(-ENOMEM);
+-      }
+       drm_helper_mode_fill_fb_struct(&exynos_fb->fb, mode_cmd);
+       exynos_fb->exynos_gem_obj[0] = exynos_gem_obj;
+@@ -228,10 +226,8 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
+       DRM_DEBUG_KMS("%s\n", __FILE__);
+       exynos_fb = kzalloc(sizeof(*exynos_fb), GFP_KERNEL);
+-      if (!exynos_fb) {
+-              DRM_ERROR("failed to allocate exynos drm framebuffer\n");
++      if (!exynos_fb)
+               return ERR_PTR(-ENOMEM);
+-      }
+       obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]);
+       if (!obj) {
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+index 45b6cb3..d677aee 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+@@ -245,10 +245,8 @@ int exynos_drm_fbdev_init(struct drm_device *dev)
+               return 0;
+       fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL);
+-      if (!fbdev) {
+-              DRM_ERROR("failed to allocate drm fbdev.\n");
++      if (!fbdev)
+               return -ENOMEM;
+-      }
+       private->fb_helper = helper = &fbdev->drm_fb_helper;
+       helper->funcs = &exynos_drm_fb_helper_funcs;
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+index fc62c81..4efe9a7 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+@@ -1361,10 +1361,8 @@ static int fimc_init_prop_list(struct exynos_drm_ippdrv *ippdrv)
+       DRM_DEBUG_KMS("%s\n", __func__);
+       prop_list = devm_kzalloc(ippdrv->dev, sizeof(*prop_list), GFP_KERNEL);
+-      if (!prop_list) {
+-              DRM_ERROR("failed to alloc property list.\n");
++      if (!prop_list)
+               return -ENOMEM;
+-      }
+       prop_list->version = 1;
+       prop_list->writeback = 1;
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+index 0e602e3..304c3cb 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+@@ -920,10 +920,8 @@ static int fimd_probe(struct platform_device *pdev)
+                       display_np = dev->of_node;
+               pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+-              if (!pdata) {
+-                      DRM_ERROR("memory allocation for pdata failed\n");
++              if (!pdata)
+                       return -ENOMEM;
+-              }
+               ret = of_get_fb_videomode(display_np,
+                               &pdata->panel.timing, OF_USE_NATIVE_MODE);
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+index 222950d..1eb2a2a 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+@@ -450,10 +450,8 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev,
+       }
+       g2d_userptr = kzalloc(sizeof(*g2d_userptr), GFP_KERNEL);
+-      if (!g2d_userptr) {
+-              DRM_ERROR("failed to allocate g2d_userptr.\n");
++      if (!g2d_userptr)
+               return ERR_PTR(-ENOMEM);
+-      }
+       atomic_set(&g2d_userptr->refcount, 1);
+@@ -503,7 +501,6 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev,
+       sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
+       if (!sgt) {
+-              DRM_ERROR("failed to allocate sg table.\n");
+               ret = -ENOMEM;
+               goto err_free_userptr;
+       }
+@@ -1091,8 +1088,6 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data,
+               e = kzalloc(sizeof(*node->event), GFP_KERNEL);
+               if (!e) {
+-                      dev_err(dev, "failed to allocate event\n");
+-
+                       spin_lock_irqsave(&drm_dev->event_lock, flags);
+                       file->event_space += sizeof(e->event);
+                       spin_unlock_irqrestore(&drm_dev->event_lock, flags);
+@@ -1322,10 +1317,8 @@ static int g2d_open(struct drm_device *drm_dev, struct device *dev,
+       struct exynos_drm_g2d_private *g2d_priv;
+       g2d_priv = kzalloc(sizeof(*g2d_priv), GFP_KERNEL);
+-      if (!g2d_priv) {
+-              dev_err(dev, "failed to allocate g2d private data\n");
++      if (!g2d_priv)
+               return -ENOMEM;
+-      }
+       g2d_priv->dev = dev;
+       file_priv->g2d_priv = g2d_priv;
+@@ -1381,10 +1374,8 @@ static int g2d_probe(struct platform_device *pdev)
+       int ret;
+       g2d = devm_kzalloc(dev, sizeof(*g2d), GFP_KERNEL);
+-      if (!g2d) {
+-              dev_err(dev, "failed to allocate driver data\n");
++      if (!g2d)
+               return -ENOMEM;
+-      }
+       g2d->runqueue_slab = kmem_cache_create("g2d_runqueue_slab",
+                       sizeof(struct g2d_runqueue_node), 0, 0, NULL);
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
+index cf4543f..8633ba4 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
+@@ -193,10 +193,8 @@ struct exynos_drm_gem_obj *exynos_drm_gem_init(struct drm_device *dev,
+       int ret;
+       exynos_gem_obj = kzalloc(sizeof(*exynos_gem_obj), GFP_KERNEL);
+-      if (!exynos_gem_obj) {
+-              DRM_ERROR("failed to allocate exynos gem object\n");
++      if (!exynos_gem_obj)
+               return NULL;
+-      }
+       exynos_gem_obj->size = size;
+       obj = &exynos_gem_obj->base;
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
+index 862a55b..b9ec6d7 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
+@@ -1353,10 +1353,8 @@ static int gsc_init_prop_list(struct exynos_drm_ippdrv *ippdrv)
+       DRM_DEBUG_KMS("%s\n", __func__);
+       prop_list = devm_kzalloc(ippdrv->dev, sizeof(*prop_list), GFP_KERNEL);
+-      if (!prop_list) {
+-              DRM_ERROR("failed to alloc property list.\n");
++      if (!prop_list)
+               return -ENOMEM;
+-      }
+       prop_list->version = 1;
+       prop_list->writeback = 1;
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
+index d0bca57..81b860c 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
+@@ -442,10 +442,8 @@ static int exynos_drm_hdmi_probe(struct platform_device *pdev)
+       DRM_DEBUG_KMS("%s\n", __FILE__);
+       ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
+-      if (!ctx) {
+-              DRM_LOG_KMS("failed to alloc common hdmi context.\n");
++      if (!ctx)
+               return -ENOMEM;
+-      }
+       subdrv = &ctx->subdrv;
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+index df1e874..1b3b59c 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+@@ -420,10 +420,8 @@ static struct drm_exynos_ipp_cmd_work *ipp_create_cmd_work(void)
+       DRM_DEBUG_KMS("%s\n", __func__);
+       cmd_work = kzalloc(sizeof(*cmd_work), GFP_KERNEL);
+-      if (!cmd_work) {
+-              DRM_ERROR("failed to alloc cmd_work.\n");
++      if (!cmd_work)
+               return ERR_PTR(-ENOMEM);
+-      }
+       INIT_WORK((struct work_struct *)cmd_work, ipp_sched_cmd);
+@@ -437,10 +435,8 @@ static struct drm_exynos_ipp_event_work *ipp_create_event_work(void)
+       DRM_DEBUG_KMS("%s\n", __func__);
+       event_work = kzalloc(sizeof(*event_work), GFP_KERNEL);
+-      if (!event_work) {
+-              DRM_ERROR("failed to alloc event_work.\n");
++      if (!event_work)
+               return ERR_PTR(-ENOMEM);
+-      }
+       INIT_WORK((struct work_struct *)event_work, ipp_sched_event);
+@@ -498,10 +494,8 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
+       /* allocate command node */
+       c_node = kzalloc(sizeof(*c_node), GFP_KERNEL);
+-      if (!c_node) {
+-              DRM_ERROR("failed to allocate map node.\n");
++      if (!c_node)
+               return -ENOMEM;
+-      }
+       /* create property id */
+       ret = ipp_create_id(&ctx->prop_idr, &ctx->prop_lock, c_node,
+@@ -718,10 +712,8 @@ static struct drm_exynos_ipp_mem_node
+       mutex_lock(&c_node->mem_lock);
+       m_node = kzalloc(sizeof(*m_node), GFP_KERNEL);
+-      if (!m_node) {
+-              DRM_ERROR("failed to allocate queue node.\n");
++      if (!m_node)
+               goto err_unlock;
+-      }
+       /* clear base address for error handling */
+       memset(&buf_info, 0x0, sizeof(buf_info));
+@@ -827,9 +819,7 @@ static int ipp_get_event(struct drm_device *drm_dev,
+               qbuf->ops_id, qbuf->buf_id);
+       e = kzalloc(sizeof(*e), GFP_KERNEL);
+-
+       if (!e) {
+-              DRM_ERROR("failed to allocate event.\n");
+               spin_lock_irqsave(&drm_dev->event_lock, flags);
+               file->event_space += sizeof(e->event);
+               spin_unlock_irqrestore(&drm_dev->event_lock, flags);
+@@ -1836,10 +1826,8 @@ static int ipp_subdrv_open(struct drm_device *drm_dev, struct device *dev,
+       DRM_DEBUG_KMS("%s\n", __func__);
+       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+-      if (!priv) {
+-              DRM_ERROR("failed to allocate priv.\n");
++      if (!priv)
+               return -ENOMEM;
+-      }
+       priv->dev = dev;
+       file_priv->ipp_priv = priv;
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
+index 63ebeeb..55f8d97 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
+@@ -281,10 +281,8 @@ struct drm_plane *exynos_plane_init(struct drm_device *dev,
+       DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+       exynos_plane = kzalloc(sizeof(struct exynos_plane), GFP_KERNEL);
+-      if (!exynos_plane) {
+-              DRM_ERROR("failed to allocate plane\n");
++      if (!exynos_plane)
+               return NULL;
+-      }
+       err = drm_plane_init(dev, &exynos_plane->base, possible_crtcs,
+                             &exynos_plane_funcs, formats, ARRAY_SIZE(formats),
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
+index f7ee022..97b60df 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_rotator.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
+@@ -474,10 +474,8 @@ static int rotator_init_prop_list(struct exynos_drm_ippdrv *ippdrv)
+       DRM_DEBUG_KMS("%s\n", __func__);
+       prop_list = devm_kzalloc(ippdrv->dev, sizeof(*prop_list), GFP_KERNEL);
+-      if (!prop_list) {
+-              DRM_ERROR("failed to alloc property list.\n");
++      if (!prop_list)
+               return -ENOMEM;
+-      }
+       prop_list->version = 1;
+       prop_list->flip = (1 << EXYNOS_DRM_FLIP_VERTICAL) |
+@@ -717,10 +715,8 @@ static int rotator_probe(struct platform_device *pdev)
+       }
+       rot = devm_kzalloc(dev, sizeof(*rot), GFP_KERNEL);
+-      if (!rot) {
+-              dev_err(dev, "failed to allocate rot\n");
++      if (!rot)
+               return -ENOMEM;
+-      }
+       ret = rotator_parse_dt(dev, rot);
+       if (ret) {
+diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
+index 3f5460e..299bf6e 100644
+--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
++++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
+@@ -1836,10 +1836,8 @@ static int hdmi_resources_init(struct hdmi_context *hdata)
+       res->regul_bulk = devm_kzalloc(dev, ARRAY_SIZE(supply) *
+               sizeof(res->regul_bulk[0]), GFP_KERNEL);
+-      if (!res->regul_bulk) {
+-              DRM_ERROR("failed to get memory for regulators\n");
++      if (!res->regul_bulk)
+               goto fail;
+-      }
+       for (i = 0; i < ARRAY_SIZE(supply); ++i) {
+               res->regul_bulk[i].supply = supply[i];
+               res->regul_bulk[i].consumer = NULL;
+@@ -1881,10 +1879,8 @@ static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
+       u32 value;
+       pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
+-      if (!pd) {
+-              DRM_ERROR("memory allocation for pdata failed\n");
++      if (!pd)
+               goto err_data;
+-      }
+       if (!of_find_property(np, "hpd-gpio", &value)) {
+               DRM_ERROR("no hpd gpio property found\n");
+@@ -1963,17 +1959,13 @@ static int hdmi_probe(struct platform_device *pdev)
+       drm_hdmi_ctx = devm_kzalloc(dev, sizeof(*drm_hdmi_ctx),
+                                                               GFP_KERNEL);
+-      if (!drm_hdmi_ctx) {
+-              DRM_ERROR("failed to allocate common hdmi context.\n");
++      if (!drm_hdmi_ctx)
+               return -ENOMEM;
+-      }
+       hdata = devm_kzalloc(dev, sizeof(struct hdmi_context),
+                                                               GFP_KERNEL);
+-      if (!hdata) {
+-              DRM_ERROR("out of memory\n");
++      if (!hdata)
+               return -ENOMEM;
+-      }
+       mutex_init(&hdata->hdmi_mutex);
+diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
+index 9cf165e..7bd57b5 100644
+--- a/drivers/gpu/drm/exynos/exynos_mixer.c
++++ b/drivers/gpu/drm/exynos/exynos_mixer.c
+@@ -1171,16 +1171,12 @@ static int mixer_probe(struct platform_device *pdev)
+       drm_hdmi_ctx = devm_kzalloc(dev, sizeof(*drm_hdmi_ctx),
+                                                               GFP_KERNEL);
+-      if (!drm_hdmi_ctx) {
+-              DRM_ERROR("failed to allocate common hdmi context.\n");
++      if (!drm_hdmi_ctx)
+               return -ENOMEM;
+-      }
+       ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
+-      if (!ctx) {
+-              DRM_ERROR("failed to alloc mixer context.\n");
++      if (!ctx)
+               return -ENOMEM;
+-      }
+       mutex_init(&ctx->mixer_mutex);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0542-drm-exynos-Add-NULL-pointer-check.patch b/patches.tizen/0542-drm-exynos-Add-NULL-pointer-check.patch
new file mode 100644 (file)
index 0000000..ec238f4
--- /dev/null
@@ -0,0 +1,49 @@
+From b12c64d7bb8c224b34b099967c862e5bac649064 Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Wed, 14 Aug 2013 16:38:03 +0530
+Subject: [PATCH 0542/1302] drm/exynos: Add NULL pointer check
+
+devm_kzalloc can fail. Hence check the pointer to avoid NULL pointer
+dereferencing.
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_iommu.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_iommu.c b/drivers/gpu/drm/exynos/exynos_drm_iommu.c
+index 3799d5c..fb8db03 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_iommu.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_iommu.c
+@@ -47,10 +47,16 @@ int drm_create_iommu_mapping(struct drm_device *drm_dev)
+       dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms),
+                                       GFP_KERNEL);
++      if (!dev->dma_parms)
++              goto error;
++
+       dma_set_max_seg_size(dev, 0xffffffffu);
+       dev->archdata.mapping = mapping;
+       return 0;
++error:
++      arm_iommu_release_mapping(mapping);
++      return -ENOMEM;
+ }
+ /*
+@@ -91,6 +97,9 @@ int drm_iommu_attach_device(struct drm_device *drm_dev,
+       subdrv_dev->dma_parms = devm_kzalloc(subdrv_dev,
+                                       sizeof(*subdrv_dev->dma_parms),
+                                       GFP_KERNEL);
++      if (!subdrv_dev->dma_parms)
++              return -ENOMEM;
++
+       dma_set_max_seg_size(subdrv_dev, 0xffffffffu);
+       ret = arm_iommu_attach_device(subdrv_dev, dev->archdata.mapping);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0543-drm-exynos-fix-fimd-pixel-format-setting.patch b/patches.tizen/0543-drm-exynos-fix-fimd-pixel-format-setting.patch
new file mode 100644 (file)
index 0000000..db9b058
--- /dev/null
@@ -0,0 +1,94 @@
+From cdb479a692ae9b60d3313215ec0c0cf10e1bf8d8 Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Tue, 20 Aug 2013 13:51:02 +0900
+Subject: [PATCH 0543/1302] drm/exynos: fix fimd pixel format setting
+
+This patch fixes wrong pixel format setting.
+
+A pixel format is decided according to bpp and depth, or user-requested
+format but fimd driver considered only bpp value to decide a proper pixel
+format. So this patch makes a proper pixel format to be set according
+to drm_framebuffer's pixel_format which is set by addfb with bpp and
+depth, or addfb2 with user-requested format.
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_fimd.c | 34 ++++++++++++--------------------
+ 1 file changed, 13 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+index 304c3cb..1324b37 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+@@ -81,6 +81,7 @@ struct fimd_win_data {
+       unsigned int            fb_width;
+       unsigned int            fb_height;
+       unsigned int            bpp;
++      unsigned int            pixel_format;
+       dma_addr_t              dma_addr;
+       unsigned int            buf_offsize;
+       unsigned int            line_size;      /* bytes */
+@@ -398,6 +399,7 @@ static void fimd_win_mode_set(struct device *dev,
+       win_data->fb_height = overlay->fb_height;
+       win_data->dma_addr = overlay->dma_addr[0] + offset;
+       win_data->bpp = overlay->bpp;
++      win_data->pixel_format = overlay->pixel_format;
+       win_data->buf_offsize = (overlay->fb_width - overlay->crtc_width) *
+                               (overlay->bpp >> 3);
+       win_data->line_size = overlay->crtc_width * (overlay->bpp >> 3);
+@@ -421,39 +423,29 @@ static void fimd_win_set_pixfmt(struct device *dev, unsigned int win)
+       val = WINCONx_ENWIN;
+-      switch (win_data->bpp) {
+-      case 1:
+-              val |= WINCON0_BPPMODE_1BPP;
+-              val |= WINCONx_BITSWP;
+-              val |= WINCONx_BURSTLEN_4WORD;
+-              break;
+-      case 2:
+-              val |= WINCON0_BPPMODE_2BPP;
+-              val |= WINCONx_BITSWP;
+-              val |= WINCONx_BURSTLEN_8WORD;
+-              break;
+-      case 4:
+-              val |= WINCON0_BPPMODE_4BPP;
+-              val |= WINCONx_BITSWP;
+-              val |= WINCONx_BURSTLEN_8WORD;
+-              break;
+-      case 8:
++      switch (win_data->pixel_format) {
++      case DRM_FORMAT_C8:
+               val |= WINCON0_BPPMODE_8BPP_PALETTE;
+               val |= WINCONx_BURSTLEN_8WORD;
+               val |= WINCONx_BYTSWP;
+               break;
+-      case 16:
++      case DRM_FORMAT_XRGB1555:
++              val |= WINCON0_BPPMODE_16BPP_1555;
++              val |= WINCONx_HAWSWP;
++              val |= WINCONx_BURSTLEN_16WORD;
++              break;
++      case DRM_FORMAT_RGB565:
+               val |= WINCON0_BPPMODE_16BPP_565;
+               val |= WINCONx_HAWSWP;
+               val |= WINCONx_BURSTLEN_16WORD;
+               break;
+-      case 24:
++      case DRM_FORMAT_XRGB8888:
+               val |= WINCON0_BPPMODE_24BPP_888;
+               val |= WINCONx_WSWP;
+               val |= WINCONx_BURSTLEN_16WORD;
+               break;
+-      case 32:
+-              val |= WINCON1_BPPMODE_28BPP_A4888
++      case DRM_FORMAT_ARGB8888:
++              val |= WINCON1_BPPMODE_25BPP_A1888
+                       | WINCON1_BLD_PIX | WINCON1_ALPHA_SEL;
+               val |= WINCONx_WSWP;
+               val |= WINCONx_BURSTLEN_16WORD;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0544-drm-exynos-fix-WINDOWS_NR-checking-to-vidi-driver.patch b/patches.tizen/0544-drm-exynos-fix-WINDOWS_NR-checking-to-vidi-driver.patch
new file mode 100644 (file)
index 0000000..cf9e953
--- /dev/null
@@ -0,0 +1,49 @@
+From 9059c9d772c69bd74a053ad44df9dc8a315ee911 Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Tue, 28 May 2013 16:01:21 +0900
+Subject: [PATCH 0544/1302] drm/exynos: fix WINDOWS_NR checking to vidi driver
+
+This patch just checks if win_data array range is valid
+or not correctly.
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_vidi.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+index ebe332b..3d3ecea 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+@@ -289,7 +289,7 @@ static void vidi_win_mode_set(struct device *dev,
+       if (win == DEFAULT_ZPOS)
+               win = ctx->default_win;
+-      if (win < 0 || win > WINDOWS_NR)
++      if (win < 0 || win >= WINDOWS_NR)
+               return;
+       offset = overlay->fb_x * (overlay->bpp >> 3);
+@@ -339,7 +339,7 @@ static void vidi_win_commit(struct device *dev, int zpos)
+       if (win == DEFAULT_ZPOS)
+               win = ctx->default_win;
+-      if (win < 0 || win > WINDOWS_NR)
++      if (win < 0 || win >= WINDOWS_NR)
+               return;
+       win_data = &ctx->win_data[win];
+@@ -363,7 +363,7 @@ static void vidi_win_disable(struct device *dev, int zpos)
+       if (win == DEFAULT_ZPOS)
+               win = ctx->default_win;
+-      if (win < 0 || win > WINDOWS_NR)
++      if (win < 0 || win >= WINDOWS_NR)
+               return;
+       win_data = &ctx->win_data[win];
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0545-drm-exynos-remove-ignoring-return-value-warning-in-h.patch b/patches.tizen/0545-drm-exynos-remove-ignoring-return-value-warning-in-h.patch
new file mode 100644 (file)
index 0000000..0ea5e9c
--- /dev/null
@@ -0,0 +1,37 @@
+From 9b08772e3ac9aeef9327e2823bb7dfbbe636a557 Mon Sep 17 00:00:00 2001
+From: Seung-Woo Kim <sw0312.kim@samsung.com>
+Date: Wed, 5 Jun 2013 14:34:38 +0900
+Subject: [PATCH 0545/1302] drm/exynos: remove ignoring return value warning in
+ hdmi
+
+The definition of regulator_bulk_enable is fixed with __must_check
+and this causes following build warning.
+warning: ignoring return value of 'regulator_bulk_enable',
+declared with attribute warn_unused_result
+This patch fixes to check return value of the function.
+
+Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_hdmi.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
+index 299bf6e..030b863 100644
+--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
++++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
+@@ -1699,7 +1699,9 @@ static void hdmi_poweron(struct hdmi_context *hdata)
+       mutex_unlock(&hdata->hdmi_mutex);
+-      regulator_bulk_enable(res->regul_count, res->regul_bulk);
++      if (regulator_bulk_enable(res->regul_count, res->regul_bulk))
++              DRM_DEBUG_KMS("failed to enable regulator bulk\n");
++
+       clk_enable(res->hdmiphy);
+       clk_enable(res->hdmi);
+       clk_enable(res->sclk_hdmi);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0546-drm-exynos-Remove-redundant-use-of-of_match_ptr-macr.patch b/patches.tizen/0546-drm-exynos-Remove-redundant-use-of-of_match_ptr-macr.patch
new file mode 100644 (file)
index 0000000..7197593
--- /dev/null
@@ -0,0 +1,33 @@
+From 9abc28917ccdf9dc31deb6c07ccfff25d47f3b02 Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Wed, 5 Jun 2013 16:00:23 +0900
+Subject: [PATCH 0546/1302] drm/exynos: Remove redundant use of of_match_ptr
+ macro
+
+'mixer_match_types' is always compiled in. Hence of_match_ptr is not
+necessary.
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_mixer.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
+index 7bd57b5..4a4ff8b 100644
+--- a/drivers/gpu/drm/exynos/exynos_mixer.c
++++ b/drivers/gpu/drm/exynos/exynos_mixer.c
+@@ -1182,8 +1182,7 @@ static int mixer_probe(struct platform_device *pdev)
+       if (dev->of_node) {
+               const struct of_device_id *match;
+-              match = of_match_node(of_match_ptr(mixer_match_types),
+-                                                        dev->of_node);
++              match = of_match_node(mixer_match_types, dev->of_node);
+               drv = (struct mixer_drv_data *)match->data;
+       } else {
+               drv = (struct mixer_drv_data *)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0547-drm-exynos-do-not-use-mode_set_base-function-directl.patch b/patches.tizen/0547-drm-exynos-do-not-use-mode_set_base-function-directl.patch
new file mode 100644 (file)
index 0000000..ca762eb
--- /dev/null
@@ -0,0 +1,58 @@
+From 1b8cbe5d224f5c9cd6d5c98c37217fa8f9aa032e Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Tue, 20 Aug 2013 17:16:29 +0900
+Subject: [PATCH 0547/1302] drm/exynos: do not use mode_set_base function
+ directly
+
+This patch adds exynos_drm_crtc_mode_set_commit function
+to update mode data and it makes page flip call this function
+instead of calling exynos_drm_crtc_mode_set_base function directly.
+
+exynos_drm_crtc_mode_set_base function is called by drm subsystem
+as a callback so we don't have to call this function directly.
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_crtc.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+index 1de357a..3c0c338a 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+@@ -140,7 +140,7 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
+       return 0;
+ }
+-static int exynos_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
++static int exynos_drm_crtc_mode_set_commit(struct drm_crtc *crtc, int x, int y,
+                                         struct drm_framebuffer *old_fb)
+ {
+       struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
+@@ -176,6 +176,12 @@ static void exynos_drm_crtc_load_lut(struct drm_crtc *crtc)
+       /* drm framework doesn't check NULL */
+ }
++static int exynos_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
++                                        struct drm_framebuffer *old_fb)
++{
++      return exynos_drm_crtc_mode_set_commit(crtc, x, y, old_fb);
++}
++
+ static void exynos_drm_crtc_disable(struct drm_crtc *crtc)
+ {
+       struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
+@@ -238,7 +244,7 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
+               spin_unlock_irq(&dev->event_lock);
+               crtc->fb = fb;
+-              ret = exynos_drm_crtc_mode_set_base(crtc, crtc->x, crtc->y,
++              ret = exynos_drm_crtc_mode_set_commit(crtc, crtc->x, crtc->y,
+                                                   NULL);
+               if (ret) {
+                       crtc->fb = old_fb;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0548-drm-exynos-fimd-Hold-pointer-to-driver-data-in-conte.patch b/patches.tizen/0548-drm-exynos-fimd-Hold-pointer-to-driver-data-in-conte.patch
new file mode 100644 (file)
index 0000000..f3e5186
--- /dev/null
@@ -0,0 +1,53 @@
+From 342b6bde57dbaa4ec8dbf5d76882037089c00e15 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <tomasz.figa@gmail.com>
+Date: Wed, 1 May 2013 21:02:26 +0200
+Subject: [PATCH 0548/1302] drm/exynos: fimd: Hold pointer to driver data in
+ context struct
+
+This patch adds pointer to driver data to fimd_context structure, to
+remove the need to call drm_fimd_get_driver_data() each time access to
+driver data is necessary.
+
+Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
+Acked-by: Joonyoung Shim <jy0922.shim@samsung.com>
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_fimd.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+index 1324b37..cfadd1c 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+@@ -108,6 +108,7 @@ struct fimd_context {
+       atomic_t                        wait_vsync_event;
+       struct exynos_drm_panel_info *panel;
++      struct fimd_driver_data *driver_data;
+ };
+ #ifdef CONFIG_OF
+@@ -239,10 +240,9 @@ static void fimd_commit(struct device *dev)
+       struct exynos_drm_panel_info *panel = ctx->panel;
+       struct fb_videomode *timing = &panel->timing;
+       struct fimd_driver_data *driver_data;
+-      struct platform_device *pdev = to_platform_device(dev);
+       u32 val;
+-      driver_data = drm_fimd_get_driver_data(pdev);
++      driver_data = ctx->driver_data;
+       if (ctx->suspended)
+               return;
+@@ -978,6 +978,7 @@ static int fimd_probe(struct platform_device *pdev)
+               return ret;
+       }
++      ctx->driver_data = drm_fimd_get_driver_data(pdev);
+       ctx->vidcon0 = pdata->vidcon0;
+       ctx->vidcon1 = pdata->vidcon1;
+       ctx->default_win = pdata->default_win;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0549-drm-exynos-fimd-Add-support-for-FIMD-versions-withou.patch b/patches.tizen/0549-drm-exynos-fimd-Add-support-for-FIMD-versions-withou.patch
new file mode 100644 (file)
index 0000000..fdaf32f
--- /dev/null
@@ -0,0 +1,169 @@
+From 6a2d343d1762c0af532aa13b39c4f66963f8ac19 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <tomasz.figa@gmail.com>
+Date: Wed, 1 May 2013 21:02:27 +0200
+Subject: [PATCH 0549/1302] drm/exynos: fimd: Add support for FIMD versions
+ without SHADOWCON register
+
+Some platforms that can be supported with this driver have PRTCON
+register instead of SHADOWCON, which requires slightly different
+handling.
+
+This patch factors out all register shadow control code from the driver
+and adds a function to control register shadowing appropriately,
+depending on driver data.
+
+Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
+Acked-by: Joonyoung Shim <jy0922.shim@samsung.com>
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_fimd.c | 69 +++++++++++++++++++++++---------
+ 1 file changed, 49 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+index cfadd1c..c2614a3 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+@@ -63,14 +63,18 @@
+ struct fimd_driver_data {
+       unsigned int timing_base;
++
++      unsigned int has_shadowcon:1;
+ };
+ static struct fimd_driver_data exynos4_fimd_driver_data = {
+       .timing_base = 0x0,
++      .has_shadowcon = 1,
+ };
+ static struct fimd_driver_data exynos5_fimd_driver_data = {
+       .timing_base = 0x20000,
++      .has_shadowcon = 1,
+ };
+ struct fimd_win_data {
+@@ -480,6 +484,33 @@ static void fimd_win_set_colkey(struct device *dev, unsigned int win)
+       writel(keycon1, ctx->regs + WKEYCON1_BASE(win));
+ }
++/**
++ * shadow_protect_win() - disable updating values from shadow registers at vsync
++ *
++ * @win: window to protect registers for
++ * @protect: 1 to protect (disable updates)
++ */
++static void fimd_shadow_protect_win(struct fimd_context *ctx,
++                                                      int win, bool protect)
++{
++      u32 reg, bits, val;
++
++      if (ctx->driver_data->has_shadowcon) {
++              reg = SHADOWCON;
++              bits = SHADOWCON_WINx_PROTECT(win);
++      } else {
++              reg = PRTCON;
++              bits = PRTCON_PROTECT;
++      }
++
++      val = readl(ctx->regs + reg);
++      if (protect)
++              val |= bits;
++      else
++              val &= ~bits;
++      writel(val, ctx->regs + reg);
++}
++
+ static void fimd_win_commit(struct device *dev, int zpos)
+ {
+       struct fimd_context *ctx = get_fimd_context(dev);
+@@ -503,7 +534,7 @@ static void fimd_win_commit(struct device *dev, int zpos)
+       win_data = &ctx->win_data[win];
+       /*
+-       * SHADOWCON register is used for enabling timing.
++       * SHADOWCON/PRTCON register is used for enabling timing.
+        *
+        * for example, once only width value of a register is set,
+        * if the dma is started then fimd hardware could malfunction so
+@@ -513,9 +544,7 @@ static void fimd_win_commit(struct device *dev, int zpos)
+        */
+       /* protect windows */
+-      val = readl(ctx->regs + SHADOWCON);
+-      val |= SHADOWCON_WINx_PROTECT(win);
+-      writel(val, ctx->regs + SHADOWCON);
++      fimd_shadow_protect_win(ctx, win, true);
+       /* buffer start address */
+       val = (unsigned long)win_data->dma_addr;
+@@ -593,10 +622,13 @@ static void fimd_win_commit(struct device *dev, int zpos)
+       writel(val, ctx->regs + WINCON(win));
+       /* Enable DMA channel and unprotect windows */
+-      val = readl(ctx->regs + SHADOWCON);
+-      val |= SHADOWCON_CHx_ENABLE(win);
+-      val &= ~SHADOWCON_WINx_PROTECT(win);
+-      writel(val, ctx->regs + SHADOWCON);
++      fimd_shadow_protect_win(ctx, win, false);
++
++      if (ctx->driver_data->has_shadowcon) {
++              val = readl(ctx->regs + SHADOWCON);
++              val |= SHADOWCON_CHx_ENABLE(win);
++              writel(val, ctx->regs + SHADOWCON);
++      }
+       win_data->enabled = true;
+ }
+@@ -625,9 +657,7 @@ static void fimd_win_disable(struct device *dev, int zpos)
+       }
+       /* protect windows */
+-      val = readl(ctx->regs + SHADOWCON);
+-      val |= SHADOWCON_WINx_PROTECT(win);
+-      writel(val, ctx->regs + SHADOWCON);
++      fimd_shadow_protect_win(ctx, win, true);
+       /* wincon */
+       val = readl(ctx->regs + WINCON(win));
+@@ -635,10 +665,13 @@ static void fimd_win_disable(struct device *dev, int zpos)
+       writel(val, ctx->regs + WINCON(win));
+       /* unprotect windows */
+-      val = readl(ctx->regs + SHADOWCON);
+-      val &= ~SHADOWCON_CHx_ENABLE(win);
+-      val &= ~SHADOWCON_WINx_PROTECT(win);
+-      writel(val, ctx->regs + SHADOWCON);
++      if (ctx->driver_data->has_shadowcon) {
++              val = readl(ctx->regs + SHADOWCON);
++              val &= ~SHADOWCON_CHx_ENABLE(win);
++              writel(val, ctx->regs + SHADOWCON);
++      }
++
++      fimd_shadow_protect_win(ctx, win, false);
+       win_data->enabled = false;
+ }
+@@ -795,8 +828,6 @@ static int fimd_calc_clkdiv(struct fimd_context *ctx,
+ static void fimd_clear_win(struct fimd_context *ctx, int win)
+ {
+-      u32 val;
+-
+       DRM_DEBUG_KMS("%s\n", __FILE__);
+       writel(0, ctx->regs + WINCON(win));
+@@ -807,9 +838,7 @@ static void fimd_clear_win(struct fimd_context *ctx, int win)
+       if (win == 1 || win == 2)
+               writel(0, ctx->regs + VIDOSD_D(win));
+-      val = readl(ctx->regs + SHADOWCON);
+-      val &= ~SHADOWCON_WINx_PROTECT(win);
+-      writel(val, ctx->regs + SHADOWCON);
++      fimd_shadow_protect_win(ctx, win, false);
+ }
+ static int fimd_clock(struct fimd_context *ctx, bool enable)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0550-drm-exynos-fimd-Add-support-for-FIMD-variants-with-c.patch b/patches.tizen/0550-drm-exynos-fimd-Add-support-for-FIMD-variants-with-c.patch
new file mode 100644 (file)
index 0000000..fb32149
--- /dev/null
@@ -0,0 +1,49 @@
+From a4e5ee1b638b22db25787e794a8bf5c6a5cb3aff Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <tomasz.figa@gmail.com>
+Date: Wed, 1 May 2013 21:02:28 +0200
+Subject: [PATCH 0550/1302] drm/exynos: fimd: Add support for FIMD variants
+ with clock selection
+
+Some platforms that can be supported this driver has additional clock
+source selection bits in VIDCON0 register that allows to select which
+clock should be used to drive the pixel clock: bus clock or special
+clock.
+
+Since this driver assumes that special clock always drives the pixel
+clock, this patch sets the selection bitfield to use the special clock.
+
+Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
+Acked-by: Joonyoung Shim <jy0922.shim@samsung.com>
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_fimd.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+index c2614a3..ba99bd7 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+@@ -65,6 +65,7 @@ struct fimd_driver_data {
+       unsigned int timing_base;
+       unsigned int has_shadowcon:1;
++      unsigned int has_clksel:1;
+ };
+ static struct fimd_driver_data exynos4_fimd_driver_data = {
+@@ -278,6 +279,11 @@ static void fimd_commit(struct device *dev)
+       val = ctx->vidcon0;
+       val &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR);
++      if (ctx->driver_data->has_clksel) {
++              val &= ~VIDCON0_CLKSEL_MASK;
++              val |= VIDCON0_CLKSEL_LCD;
++      }
++
+       if (ctx->clkdiv > 1)
+               val |= VIDCON0_CLKVAL_F(ctx->clkdiv - 1) | VIDCON0_CLKDIR;
+       else
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0551-drm-exynos-fimd-Add-support-for-S3C64xx-SoCs.patch b/patches.tizen/0551-drm-exynos-fimd-Add-support-for-S3C64xx-SoCs.patch
new file mode 100644 (file)
index 0000000..7170dbf
--- /dev/null
@@ -0,0 +1,57 @@
+From 210b453602dd0e472213bd4e7872839a8c2422ba Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <tomasz.figa@gmail.com>
+Date: Wed, 1 May 2013 21:02:29 +0200
+Subject: [PATCH 0551/1302] drm/exynos: fimd: Add support for S3C64xx SoCs
+
+The FIMD block present on S3C6400/S3C6410 SoCs is compatible with this
+driver, so it can be supported by it as well.
+
+This patch adds appropriate device IDs and driver data to enable this
+driver for S3C64xx SoCs.
+
+Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
+Acked-by: Joonyoung Shim <jy0922.shim@samsung.com>
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_fimd.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+index ba99bd7..a8203b3 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+@@ -68,6 +68,11 @@ struct fimd_driver_data {
+       unsigned int has_clksel:1;
+ };
++static struct fimd_driver_data s3c64xx_fimd_driver_data = {
++      .timing_base = 0x0,
++      .has_clksel = 1,
++};
++
+ static struct fimd_driver_data exynos4_fimd_driver_data = {
+       .timing_base = 0x0,
+       .has_shadowcon = 1,
+@@ -118,6 +123,8 @@ struct fimd_context {
+ #ifdef CONFIG_OF
+ static const struct of_device_id fimd_driver_dt_match[] = {
++      { .compatible = "samsung,s3c6400-fimd",
++        .data = &s3c64xx_fimd_driver_data },
+       { .compatible = "samsung,exynos4210-fimd",
+         .data = &exynos4_fimd_driver_data },
+       { .compatible = "samsung,exynos5250-fimd",
+@@ -1137,6 +1144,9 @@ static int fimd_runtime_resume(struct device *dev)
+ static struct platform_device_id fimd_driver_ids[] = {
+       {
++              .name           = "s3c64xx-fb",
++              .driver_data    = (unsigned long)&s3c64xx_fimd_driver_data,
++      }, {
+               .name           = "exynos4-fb",
+               .driver_data    = (unsigned long)&exynos4_fimd_driver_data,
+       }, {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0552-drm-exynos-hdmi-use-drm_display_mode-to-check-the-su.patch b/patches.tizen/0552-drm-exynos-hdmi-use-drm_display_mode-to-check-the-su.patch
new file mode 100644 (file)
index 0000000..48068bb
--- /dev/null
@@ -0,0 +1,381 @@
+From 8e2872f79190da8e85948ad414ef3688e4d72a12 Mon Sep 17 00:00:00 2001
+From: Rahul Sharma <rahul.sharma@samsung.com>
+Date: Mon, 10 Jun 2013 14:50:00 +0530
+Subject: [PATCH 0552/1302] drm/exynos: hdmi: use drm_display_mode to check the
+ supported modes
+
+This patch renames check_timing to check_mode and removes the
+unnecessary conversion of drm_display_mode to/from fb_videomode in
+the hdmi driver.
+
+v4:
+1) Changed the commit message to add information related to renaming
+the callbacks to check_mode.
+2) Changed debug message to print 1/0 for interlace mode.
+
+v3:
+1) Replaced check_timing callbacks with check_mode.
+2) Change the type of second parameter of check_mode callback from void
+pointer paramenter to struct drm_display_mode pointer.
+
+v2:
+1) Removed convert_to_video_timing().
+2) Corrected DRM_DEBUG_KMS to print the resolution properly.
+
+Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_connector.c | 38 ++-------------------------
+ drivers/gpu/drm/exynos/exynos_drm_drv.h       |  4 +--
+ drivers/gpu/drm/exynos/exynos_drm_fimd.c      |  4 +--
+ drivers/gpu/drm/exynos/exynos_drm_hdmi.c      | 17 ++++++------
+ drivers/gpu/drm/exynos/exynos_drm_hdmi.h      |  6 ++---
+ drivers/gpu/drm/exynos/exynos_drm_vidi.c      |  4 +--
+ drivers/gpu/drm/exynos/exynos_hdmi.c          | 29 ++++++++++----------
+ drivers/gpu/drm/exynos/exynos_mixer.c         | 15 +++++------
+ 8 files changed, 41 insertions(+), 76 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c
+index f729f16..ce52d85 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_connector.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c
+@@ -59,37 +59,6 @@ convert_to_display_mode(struct drm_display_mode *mode,
+               mode->flags |= DRM_MODE_FLAG_DBLSCAN;
+ }
+-/* convert drm_display_mode to exynos_video_timings */
+-static inline void
+-convert_to_video_timing(struct fb_videomode *timing,
+-                      struct drm_display_mode *mode)
+-{
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+-      memset(timing, 0, sizeof(*timing));
+-
+-      timing->pixclock = mode->clock * 1000;
+-      timing->refresh = drm_mode_vrefresh(mode);
+-
+-      timing->xres = mode->hdisplay;
+-      timing->right_margin = mode->hsync_start - mode->hdisplay;
+-      timing->hsync_len = mode->hsync_end - mode->hsync_start;
+-      timing->left_margin = mode->htotal - mode->hsync_end;
+-
+-      timing->yres = mode->vdisplay;
+-      timing->lower_margin = mode->vsync_start - mode->vdisplay;
+-      timing->vsync_len = mode->vsync_end - mode->vsync_start;
+-      timing->upper_margin = mode->vtotal - mode->vsync_end;
+-
+-      if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+-              timing->vmode = FB_VMODE_INTERLACED;
+-      else
+-              timing->vmode = FB_VMODE_NONINTERLACED;
+-
+-      if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
+-              timing->vmode |= FB_VMODE_DOUBLE;
+-}
+-
+ static int exynos_drm_connector_get_modes(struct drm_connector *connector)
+ {
+       struct exynos_drm_connector *exynos_connector =
+@@ -169,15 +138,12 @@ static int exynos_drm_connector_mode_valid(struct drm_connector *connector,
+                                       to_exynos_connector(connector);
+       struct exynos_drm_manager *manager = exynos_connector->manager;
+       struct exynos_drm_display_ops *display_ops = manager->display_ops;
+-      struct fb_videomode timing;
+       int ret = MODE_BAD;
+       DRM_DEBUG_KMS("%s\n", __FILE__);
+-      convert_to_video_timing(&timing, mode);
+-
+-      if (display_ops && display_ops->check_timing)
+-              if (!display_ops->check_timing(manager->dev, (void *)&timing))
++      if (display_ops && display_ops->check_mode)
++              if (!display_ops->check_mode(manager->dev, mode))
+                       ret = MODE_OK;
+       return ret;
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
+index 680a7c1..eaa1966 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
++++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
+@@ -142,7 +142,7 @@ struct exynos_drm_overlay {
+  * @is_connected: check for that display is connected or not.
+  * @get_edid: get edid modes from display driver.
+  * @get_panel: get panel object from display driver.
+- * @check_timing: check if timing is valid or not.
++ * @check_mode: check if mode is valid or not.
+  * @power_on: display device on or off.
+  */
+ struct exynos_drm_display_ops {
+@@ -151,7 +151,7 @@ struct exynos_drm_display_ops {
+       struct edid *(*get_edid)(struct device *dev,
+                       struct drm_connector *connector);
+       void *(*get_panel)(struct device *dev);
+-      int (*check_timing)(struct device *dev, void *timing);
++      int (*check_mode)(struct device *dev, struct drm_display_mode *mode);
+       int (*power_on)(struct device *dev, int mode);
+ };
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+index a8203b3..80f5ec5 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+@@ -166,7 +166,7 @@ static void *fimd_get_panel(struct device *dev)
+       return ctx->panel;
+ }
+-static int fimd_check_timing(struct device *dev, void *timing)
++static int fimd_check_mode(struct device *dev, struct drm_display_mode *mode)
+ {
+       DRM_DEBUG_KMS("%s\n", __FILE__);
+@@ -188,7 +188,7 @@ static struct exynos_drm_display_ops fimd_display_ops = {
+       .type = EXYNOS_DISPLAY_TYPE_LCD,
+       .is_connected = fimd_display_is_connected,
+       .get_panel = fimd_get_panel,
+-      .check_timing = fimd_check_timing,
++      .check_mode = fimd_check_mode,
+       .power_on = fimd_display_power_on,
+ };
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
+index 81b860c..1be4f64 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
+@@ -126,7 +126,8 @@ static struct edid *drm_hdmi_get_edid(struct device *dev,
+       return NULL;
+ }
+-static int drm_hdmi_check_timing(struct device *dev, void *timing)
++static int drm_hdmi_check_mode(struct device *dev,
++              struct drm_display_mode *mode)
+ {
+       struct drm_hdmi_context *ctx = to_context(dev);
+       int ret = 0;
+@@ -138,14 +139,14 @@ static int drm_hdmi_check_timing(struct device *dev, void *timing)
+       * If any of the two fails, return mode as BAD.
+       */
+-      if (mixer_ops && mixer_ops->check_timing)
+-              ret = mixer_ops->check_timing(ctx->mixer_ctx->ctx, timing);
++      if (mixer_ops && mixer_ops->check_mode)
++              ret = mixer_ops->check_mode(ctx->mixer_ctx->ctx, mode);
+       if (ret)
+               return ret;
+-      if (hdmi_ops && hdmi_ops->check_timing)
+-              return hdmi_ops->check_timing(ctx->hdmi_ctx->ctx, timing);
++      if (hdmi_ops && hdmi_ops->check_mode)
++              return hdmi_ops->check_mode(ctx->hdmi_ctx->ctx, mode);
+       return 0;
+ }
+@@ -166,7 +167,7 @@ static struct exynos_drm_display_ops drm_hdmi_display_ops = {
+       .type = EXYNOS_DISPLAY_TYPE_HDMI,
+       .is_connected = drm_hdmi_is_connected,
+       .get_edid = drm_hdmi_get_edid,
+-      .check_timing = drm_hdmi_check_timing,
++      .check_mode = drm_hdmi_check_mode,
+       .power_on = drm_hdmi_power_on,
+ };
+@@ -217,7 +218,7 @@ static void drm_hdmi_mode_fixup(struct device *subdrv_dev,
+       drm_mode_set_crtcinfo(adjusted_mode, 0);
+-      mode_ok = drm_hdmi_check_timing(subdrv_dev, adjusted_mode);
++      mode_ok = drm_hdmi_check_mode(subdrv_dev, adjusted_mode);
+       /* just return if user desired mode exists. */
+       if (mode_ok == 0)
+@@ -228,7 +229,7 @@ static void drm_hdmi_mode_fixup(struct device *subdrv_dev,
+        * to adjusted_mode.
+        */
+       list_for_each_entry(m, &connector->modes, head) {
+-              mode_ok = drm_hdmi_check_timing(subdrv_dev, m);
++              mode_ok = drm_hdmi_check_mode(subdrv_dev, m);
+               if (mode_ok == 0) {
+                       struct drm_mode_object base;
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
+index 6b70944..724cab1 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
++++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
+@@ -32,11 +32,11 @@ struct exynos_hdmi_ops {
+       bool (*is_connected)(void *ctx);
+       struct edid *(*get_edid)(void *ctx,
+                       struct drm_connector *connector);
+-      int (*check_timing)(void *ctx, struct fb_videomode *timing);
++      int (*check_mode)(void *ctx, struct drm_display_mode *mode);
+       int (*power_on)(void *ctx, int mode);
+       /* manager */
+-      void (*mode_set)(void *ctx, void *mode);
++      void (*mode_set)(void *ctx, struct drm_display_mode *mode);
+       void (*get_max_resol)(void *ctx, unsigned int *width,
+                               unsigned int *height);
+       void (*commit)(void *ctx);
+@@ -57,7 +57,7 @@ struct exynos_mixer_ops {
+       void (*win_disable)(void *ctx, int zpos);
+       /* display */
+-      int (*check_timing)(void *ctx, struct fb_videomode *timing);
++      int (*check_mode)(void *ctx, struct drm_display_mode *mode);
+ };
+ void exynos_hdmi_drv_attach(struct exynos_drm_hdmi_context *ctx);
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+index 3d3ecea..5197eda 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+@@ -142,7 +142,7 @@ static void *vidi_get_panel(struct device *dev)
+       return NULL;
+ }
+-static int vidi_check_timing(struct device *dev, void *timing)
++static int vidi_check_mode(struct device *dev, struct drm_display_mode *mode)
+ {
+       DRM_DEBUG_KMS("%s\n", __FILE__);
+@@ -165,7 +165,7 @@ static struct exynos_drm_display_ops vidi_display_ops = {
+       .is_connected = vidi_display_is_connected,
+       .get_edid = vidi_get_edid,
+       .get_panel = vidi_get_panel,
+-      .check_timing = vidi_check_timing,
++      .check_mode = vidi_check_mode,
+       .power_on = vidi_display_power_on,
+ };
+diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
+index 030b863..e5d8dae 100644
+--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
++++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
+@@ -796,18 +796,17 @@ static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
+       return -EINVAL;
+ }
+-static int hdmi_check_timing(void *ctx, struct fb_videomode *timing)
++static int hdmi_check_mode(void *ctx, struct drm_display_mode *mode)
+ {
+       struct hdmi_context *hdata = ctx;
+       int ret;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+-      DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", timing->xres,
+-                      timing->yres, timing->refresh,
+-                      timing->vmode);
++      DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
++              mode->hdisplay, mode->vdisplay, mode->vrefresh,
++              (mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
++              false, mode->clock * 1000);
+-      ret = hdmi_find_phy_conf(hdata, timing->pixclock);
++      ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
+       if (ret < 0)
+               return ret;
+       return 0;
+@@ -1042,7 +1041,7 @@ static void hdmi_conf_init(struct hdmi_context *hdata)
+       }
+ }
+-static void hdmi_v13_timing_apply(struct hdmi_context *hdata)
++static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
+ {
+       const struct hdmi_tg_regs *tg = &hdata->mode_conf.conf.v13_conf.tg;
+       const struct hdmi_v13_core_regs *core =
+@@ -1131,7 +1130,7 @@ static void hdmi_v13_timing_apply(struct hdmi_context *hdata)
+               hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
+ }
+-static void hdmi_v14_timing_apply(struct hdmi_context *hdata)
++static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
+ {
+       const struct hdmi_tg_regs *tg = &hdata->mode_conf.conf.v14_conf.tg;
+       const struct hdmi_v14_core_regs *core =
+@@ -1298,12 +1297,12 @@ static void hdmi_v14_timing_apply(struct hdmi_context *hdata)
+               hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
+ }
+-static void hdmi_timing_apply(struct hdmi_context *hdata)
++static void hdmi_mode_apply(struct hdmi_context *hdata)
+ {
+       if (hdata->type == HDMI_TYPE13)
+-              hdmi_v13_timing_apply(hdata);
++              hdmi_v13_mode_apply(hdata);
+       else
+-              hdmi_v14_timing_apply(hdata);
++              hdmi_v14_mode_apply(hdata);
+ }
+ static void hdmiphy_conf_reset(struct hdmi_context *hdata)
+@@ -1423,7 +1422,7 @@ static void hdmi_conf_apply(struct hdmi_context *hdata)
+       hdmi_audio_init(hdata);
+       /* setting core registers */
+-      hdmi_timing_apply(hdata);
++      hdmi_mode_apply(hdata);
+       hdmi_audio_control(hdata, true);
+       hdmi_regs_dump(hdata, "start");
+@@ -1642,7 +1641,7 @@ static void hdmi_v14_mode_set(struct hdmi_context *hdata,
+       hdmi_set_reg(tg->tg_3d, 1, 0x0);
+ }
+-static void hdmi_mode_set(void *ctx, void *mode)
++static void hdmi_mode_set(void *ctx, struct drm_display_mode *mode)
+ {
+       struct hdmi_context *hdata = ctx;
+       struct drm_display_mode *m = mode;
+@@ -1767,7 +1766,7 @@ static struct exynos_hdmi_ops hdmi_ops = {
+       /* display */
+       .is_connected   = hdmi_is_connected,
+       .get_edid       = hdmi_get_edid,
+-      .check_timing   = hdmi_check_timing,
++      .check_mode     = hdmi_check_mode,
+       /* manager */
+       .mode_set       = hdmi_mode_set,
+diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
+index 4a4ff8b..d0a8afb 100644
+--- a/drivers/gpu/drm/exynos/exynos_mixer.c
++++ b/drivers/gpu/drm/exynos/exynos_mixer.c
+@@ -820,17 +820,16 @@ static void mixer_win_disable(void *ctx, int win)
+       mixer_ctx->win_data[win].enabled = false;
+ }
+-static int mixer_check_timing(void *ctx, struct fb_videomode *timing)
++static int mixer_check_mode(void *ctx, struct drm_display_mode *mode)
+ {
+       u32 w, h;
+-      w = timing->xres;
+-      h = timing->yres;
++      w = mode->hdisplay;
++      h = mode->vdisplay;
+-      DRM_DEBUG_KMS("%s : xres=%d, yres=%d, refresh=%d, intl=%d\n",
+-              __func__, timing->xres, timing->yres,
+-              timing->refresh, (timing->vmode &
+-              FB_VMODE_INTERLACED) ? true : false);
++      DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d\n",
++              mode->hdisplay, mode->vdisplay, mode->vrefresh,
++              (mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
+       if ((w >= 464 && w <= 720 && h >= 261 && h <= 576) ||
+               (w >= 1024 && w <= 1280 && h >= 576 && h <= 720) ||
+@@ -978,7 +977,7 @@ static struct exynos_mixer_ops mixer_ops = {
+       .win_disable            = mixer_win_disable,
+       /* display */
+-      .check_timing           = mixer_check_timing,
++      .check_mode             = mixer_check_mode,
+ };
+ static irqreturn_t mixer_irq_handler(int irq, void *arg)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0553-drm-exynos-Remove-tracking-log-functions.patch b/patches.tizen/0553-drm-exynos-Remove-tracking-log-functions.patch
new file mode 100644 (file)
index 0000000..a059866
--- /dev/null
@@ -0,0 +1,2118 @@
+From fac9f70da1fc2b62545aa91a245eac53791fa910 Mon Sep 17 00:00:00 2001
+From: YoungJun Cho <yj44.cho@samsung.com>
+Date: Tue, 20 Aug 2013 17:18:40 +0900
+Subject: [PATCH 0553/1302] drm/exynos: Remove tracking log functions
+
+This patch removes tracking log functions which were used to debug
+in the early development stage and are not so important as were.
+So remove them for code clean up.
+
+Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
+Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_buf.c       |  7 ----
+ drivers/gpu/drm/exynos/exynos_drm_connector.c | 13 -------
+ drivers/gpu/drm/exynos/exynos_drm_core.c      | 12 -------
+ drivers/gpu/drm/exynos/exynos_drm_crtc.c      | 28 ---------------
+ drivers/gpu/drm/exynos/exynos_drm_dmabuf.c    |  6 ----
+ drivers/gpu/drm/exynos/exynos_drm_drv.c       | 20 -----------
+ drivers/gpu/drm/exynos/exynos_drm_encoder.c   | 28 +--------------
+ drivers/gpu/drm/exynos/exynos_drm_fb.c        | 10 ------
+ drivers/gpu/drm/exynos/exynos_drm_fbdev.c     |  8 -----
+ drivers/gpu/drm/exynos/exynos_drm_fimc.c      | 16 ---------
+ drivers/gpu/drm/exynos/exynos_drm_fimd.c      | 46 +-----------------------
+ drivers/gpu/drm/exynos/exynos_drm_gem.c       | 23 ------------
+ drivers/gpu/drm/exynos/exynos_drm_gsc.c       | 12 +------
+ drivers/gpu/drm/exynos/exynos_drm_hdmi.c      | 42 ----------------------
+ drivers/gpu/drm/exynos/exynos_drm_ipp.c       | 52 ---------------------------
+ drivers/gpu/drm/exynos/exynos_drm_plane.c     | 16 ---------
+ drivers/gpu/drm/exynos/exynos_drm_rotator.c   | 12 -------
+ drivers/gpu/drm/exynos/exynos_drm_vidi.c      | 40 +--------------------
+ drivers/gpu/drm/exynos/exynos_hdmi.c          | 30 ----------------
+ drivers/gpu/drm/exynos/exynos_mixer.c         | 20 -----------
+ 20 files changed, 4 insertions(+), 437 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c b/drivers/gpu/drm/exynos/exynos_drm_buf.c
+index cd3c49c..ed5c694 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_buf.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c
+@@ -24,8 +24,6 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
+       enum dma_attr attr;
+       unsigned int nr_pages;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (buf->dma_addr) {
+               DRM_DEBUG_KMS("already allocated.\n");
+               return 0;
+@@ -119,8 +117,6 @@ err_free_attrs:
+ static void lowlevel_buffer_deallocate(struct drm_device *dev,
+               unsigned int flags, struct exynos_drm_gem_buf *buf)
+ {
+-      DRM_DEBUG_KMS("%s.\n", __FILE__);
+-
+       if (!buf->dma_addr) {
+               DRM_DEBUG_KMS("dma_addr is invalid.\n");
+               return;
+@@ -151,7 +147,6 @@ struct exynos_drm_gem_buf *exynos_drm_init_buf(struct drm_device *dev,
+ {
+       struct exynos_drm_gem_buf *buffer;
+-      DRM_DEBUG_KMS("%s.\n", __FILE__);
+       DRM_DEBUG_KMS("desired size = 0x%x\n", size);
+       buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
+@@ -165,8 +160,6 @@ struct exynos_drm_gem_buf *exynos_drm_init_buf(struct drm_device *dev,
+ void exynos_drm_fini_buf(struct drm_device *dev,
+                               struct exynos_drm_gem_buf *buffer)
+ {
+-      DRM_DEBUG_KMS("%s.\n", __FILE__);
+-
+       if (!buffer) {
+               DRM_DEBUG_KMS("buffer is null.\n");
+               return;
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c
+index ce52d85..964d553 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_connector.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c
+@@ -35,7 +35,6 @@ convert_to_display_mode(struct drm_display_mode *mode,
+                       struct exynos_drm_panel_info *panel)
+ {
+       struct fb_videomode *timing = &panel->timing;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+       mode->clock = timing->pixclock / 1000;
+       mode->vrefresh = timing->refresh;
+@@ -69,8 +68,6 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector)
+       unsigned int count = 0;
+       int ret;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (!display_ops) {
+               DRM_DEBUG_KMS("display_ops is null.\n");
+               return 0;
+@@ -157,8 +154,6 @@ struct drm_encoder *exynos_drm_best_encoder(struct drm_connector *connector)
+       struct drm_mode_object *obj;
+       struct drm_encoder *encoder;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       obj = drm_mode_object_find(dev, exynos_connector->encoder_id,
+                                  DRM_MODE_OBJECT_ENCODER);
+       if (!obj) {
+@@ -201,8 +196,6 @@ void exynos_drm_display_power(struct drm_connector *connector, int mode)
+ static void exynos_drm_connector_dpms(struct drm_connector *connector,
+                                       int mode)
+ {
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /*
+        * in case that drm_crtc_helper_set_mode() is called,
+        * encoder/crtc->funcs->dpms() will be just returned
+@@ -249,8 +242,6 @@ exynos_drm_connector_detect(struct drm_connector *connector, bool force)
+                                       manager->display_ops;
+       enum drm_connector_status status = connector_status_disconnected;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (display_ops && display_ops->is_connected) {
+               if (display_ops->is_connected(manager->dev))
+                       status = connector_status_connected;
+@@ -266,8 +257,6 @@ static void exynos_drm_connector_destroy(struct drm_connector *connector)
+       struct exynos_drm_connector *exynos_connector =
+               to_exynos_connector(connector);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       drm_sysfs_connector_remove(connector);
+       drm_connector_cleanup(connector);
+       kfree(exynos_connector);
+@@ -289,8 +278,6 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
+       int type;
+       int err;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       exynos_connector = kzalloc(sizeof(*exynos_connector), GFP_KERNEL);
+       if (!exynos_connector)
+               return NULL;
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c
+index 4667c9f..1bef6dc 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_core.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_core.c
+@@ -27,8 +27,6 @@ static int exynos_drm_create_enc_conn(struct drm_device *dev,
+       struct drm_connector *connector;
+       int ret;
+-      DRM_DEBUG_DRIVER("%s\n", __FILE__);
+-
+       subdrv->manager->dev = subdrv->dev;
+       /* create and initialize a encoder for this sub driver. */
+@@ -102,8 +100,6 @@ static int exynos_drm_subdrv_probe(struct drm_device *dev,
+ static void exynos_drm_subdrv_remove(struct drm_device *dev,
+                                     struct exynos_drm_subdrv *subdrv)
+ {
+-      DRM_DEBUG_DRIVER("%s\n", __FILE__);
+-
+       if (subdrv->remove)
+               subdrv->remove(dev, subdrv->dev);
+ }
+@@ -114,8 +110,6 @@ int exynos_drm_device_register(struct drm_device *dev)
+       unsigned int fine_cnt = 0;
+       int err;
+-      DRM_DEBUG_DRIVER("%s\n", __FILE__);
+-
+       if (!dev)
+               return -EINVAL;
+@@ -158,8 +152,6 @@ int exynos_drm_device_unregister(struct drm_device *dev)
+ {
+       struct exynos_drm_subdrv *subdrv;
+-      DRM_DEBUG_DRIVER("%s\n", __FILE__);
+-
+       if (!dev) {
+               WARN(1, "Unexpected drm device unregister!\n");
+               return -EINVAL;
+@@ -176,8 +168,6 @@ EXPORT_SYMBOL_GPL(exynos_drm_device_unregister);
+ int exynos_drm_subdrv_register(struct exynos_drm_subdrv *subdrv)
+ {
+-      DRM_DEBUG_DRIVER("%s\n", __FILE__);
+-
+       if (!subdrv)
+               return -EINVAL;
+@@ -189,8 +179,6 @@ EXPORT_SYMBOL_GPL(exynos_drm_subdrv_register);
+ int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *subdrv)
+ {
+-      DRM_DEBUG_DRIVER("%s\n", __FILE__);
+-
+       if (!subdrv)
+               return -EINVAL;
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+index 3c0c338a..311a36e 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+@@ -77,8 +77,6 @@ static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
+ static void exynos_drm_crtc_prepare(struct drm_crtc *crtc)
+ {
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /* drm framework doesn't check NULL. */
+ }
+@@ -86,8 +84,6 @@ static void exynos_drm_crtc_commit(struct drm_crtc *crtc)
+ {
+       struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
+       exynos_plane_commit(exynos_crtc->plane);
+       exynos_plane_dpms(exynos_crtc->plane, DRM_MODE_DPMS_ON);
+@@ -98,8 +94,6 @@ exynos_drm_crtc_mode_fixup(struct drm_crtc *crtc,
+                           const struct drm_display_mode *mode,
+                           struct drm_display_mode *adjusted_mode)
+ {
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /* drm framework doesn't check NULL */
+       return true;
+ }
+@@ -116,8 +110,6 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
+       int pipe = exynos_crtc->pipe;
+       int ret;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /*
+        * copy the mode data adjusted by mode_fixup() into crtc->mode
+        * so that hardware can be seet to proper mode.
+@@ -149,8 +141,6 @@ static int exynos_drm_crtc_mode_set_commit(struct drm_crtc *crtc, int x, int y,
+       unsigned int crtc_h;
+       int ret;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /* when framebuffer changing is requested, crtc's dpms should be on */
+       if (exynos_crtc->dpms > DRM_MODE_DPMS_ON) {
+               DRM_ERROR("failed framebuffer changing request.\n");
+@@ -186,8 +176,6 @@ static void exynos_drm_crtc_disable(struct drm_crtc *crtc)
+ {
+       struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       exynos_plane_dpms(exynos_crtc->plane, DRM_MODE_DPMS_OFF);
+       exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+ }
+@@ -213,8 +201,6 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
+       struct drm_framebuffer *old_fb = crtc->fb;
+       int ret = -EINVAL;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /* when the page flip is requested, crtc's dpms should be on */
+       if (exynos_crtc->dpms > DRM_MODE_DPMS_ON) {
+               DRM_ERROR("failed page flip request.\n");
+@@ -267,8 +253,6 @@ static void exynos_drm_crtc_destroy(struct drm_crtc *crtc)
+       struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
+       struct exynos_drm_private *private = crtc->dev->dev_private;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       private->crtc[exynos_crtc->pipe] = NULL;
+       drm_crtc_cleanup(crtc);
+@@ -283,8 +267,6 @@ static int exynos_drm_crtc_set_property(struct drm_crtc *crtc,
+       struct exynos_drm_private *dev_priv = dev->dev_private;
+       struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       if (property == dev_priv->crtc_mode_property) {
+               enum exynos_crtc_mode mode = val;
+@@ -329,8 +311,6 @@ static void exynos_drm_crtc_attach_mode_property(struct drm_crtc *crtc)
+       struct exynos_drm_private *dev_priv = dev->dev_private;
+       struct drm_property *prop;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       prop = dev_priv->crtc_mode_property;
+       if (!prop) {
+               prop = drm_property_create_enum(dev, 0, "mode", mode_names,
+@@ -350,8 +330,6 @@ int exynos_drm_crtc_create(struct drm_device *dev, unsigned int nr)
+       struct exynos_drm_private *private = dev->dev_private;
+       struct drm_crtc *crtc;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       exynos_crtc = kzalloc(sizeof(*exynos_crtc), GFP_KERNEL);
+       if (!exynos_crtc)
+               return -ENOMEM;
+@@ -384,8 +362,6 @@ int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int crtc)
+       struct exynos_drm_crtc *exynos_crtc =
+               to_exynos_crtc(private->crtc[crtc]);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (exynos_crtc->dpms != DRM_MODE_DPMS_ON)
+               return -EPERM;
+@@ -401,8 +377,6 @@ void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int crtc)
+       struct exynos_drm_crtc *exynos_crtc =
+               to_exynos_crtc(private->crtc[crtc]);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (exynos_crtc->dpms != DRM_MODE_DPMS_ON)
+               return;
+@@ -418,8 +392,6 @@ void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int crtc)
+       struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(drm_crtc);
+       unsigned long flags;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       spin_lock_irqsave(&dev->event_lock, flags);
+       list_for_each_entry_safe(e, t, &dev_priv->pageflip_event_list,
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
+index 4b750ce..4e2ab46 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
+@@ -72,8 +72,6 @@ static struct sg_table *
+       unsigned int i;
+       int nents, ret;
+-      DRM_DEBUG_PRIME("%s\n", __FILE__);
+-
+       /* just return current sgt if already requested. */
+       if (exynos_attach->dir == dir && exynos_attach->is_mapped)
+               return &exynos_attach->sgt;
+@@ -166,8 +164,6 @@ static void exynos_dmabuf_release(struct dma_buf *dmabuf)
+ {
+       struct exynos_drm_gem_obj *exynos_gem_obj = dmabuf->priv;
+-      DRM_DEBUG_PRIME("%s\n", __FILE__);
+-
+       /*
+        * exynos_dmabuf_release() call means that file object's
+        * f_count is 0 and it calls drm_gem_object_handle_unreference()
+@@ -256,8 +252,6 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev,
+       struct exynos_drm_gem_buf *buffer;
+       int ret;
+-      DRM_DEBUG_PRIME("%s\n", __FILE__);
+-
+       /* is this one of own objects? */
+       if (dma_buf->ops == &exynos_dmabuf_ops) {
+               struct drm_gem_object *obj;
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
+index 1a07ff6..d5da1ea 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
+@@ -46,8 +46,6 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
+       int ret;
+       int nr;
+-      DRM_DEBUG_DRIVER("%s\n", __FILE__);
+-
+       private = kzalloc(sizeof(struct exynos_drm_private), GFP_KERNEL);
+       if (!private)
+               return -ENOMEM;
+@@ -138,8 +136,6 @@ err_crtc:
+ static int exynos_drm_unload(struct drm_device *dev)
+ {
+-      DRM_DEBUG_DRIVER("%s\n", __FILE__);
+-
+       exynos_drm_fbdev_fini(dev);
+       exynos_drm_device_unregister(dev);
+       drm_vblank_cleanup(dev);
+@@ -158,8 +154,6 @@ static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
+ {
+       struct drm_exynos_file_private *file_priv;
+-      DRM_DEBUG_DRIVER("%s\n", __FILE__);
+-
+       file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
+       if (!file_priv)
+               return -ENOMEM;
+@@ -176,8 +170,6 @@ static void exynos_drm_preclose(struct drm_device *dev,
+       struct drm_pending_vblank_event *e, *t;
+       unsigned long flags;
+-      DRM_DEBUG_DRIVER("%s\n", __FILE__);
+-
+       /* release events of current file */
+       spin_lock_irqsave(&dev->event_lock, flags);
+       list_for_each_entry_safe(e, t, &private->pageflip_event_list,
+@@ -194,8 +186,6 @@ static void exynos_drm_preclose(struct drm_device *dev,
+ static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
+ {
+-      DRM_DEBUG_DRIVER("%s\n", __FILE__);
+-
+       if (!file->driver_priv)
+               return;
+@@ -205,8 +195,6 @@ static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
+ static void exynos_drm_lastclose(struct drm_device *dev)
+ {
+-      DRM_DEBUG_DRIVER("%s\n", __FILE__);
+-
+       exynos_drm_fbdev_restore_mode(dev);
+ }
+@@ -290,8 +278,6 @@ static struct drm_driver exynos_drm_driver = {
+ static int exynos_drm_platform_probe(struct platform_device *pdev)
+ {
+-      DRM_DEBUG_DRIVER("%s\n", __FILE__);
+-
+       pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+       exynos_drm_driver.num_ioctls = DRM_ARRAY_SIZE(exynos_ioctls);
+@@ -300,8 +286,6 @@ static int exynos_drm_platform_probe(struct platform_device *pdev)
+ static int exynos_drm_platform_remove(struct platform_device *pdev)
+ {
+-      DRM_DEBUG_DRIVER("%s\n", __FILE__);
+-
+       drm_platform_exit(&exynos_drm_driver, pdev);
+       return 0;
+@@ -320,8 +304,6 @@ static int __init exynos_drm_init(void)
+ {
+       int ret;
+-      DRM_DEBUG_DRIVER("%s\n", __FILE__);
+-
+ #ifdef CONFIG_DRM_EXYNOS_FIMD
+       ret = platform_driver_register(&fimd_driver);
+       if (ret < 0)
+@@ -453,8 +435,6 @@ out_fimd:
+ static void __exit exynos_drm_exit(void)
+ {
+-      DRM_DEBUG_DRIVER("%s\n", __FILE__);
+-
+       platform_device_unregister(exynos_drm_pdev);
+       platform_driver_unregister(&exynos_drm_platform_driver);
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+index 4296d8f..06f1b2a 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+@@ -61,7 +61,7 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode)
+       struct exynos_drm_manager_ops *manager_ops = manager->ops;
+       struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
+-      DRM_DEBUG_KMS("%s, encoder dpms: %d\n", __FILE__, mode);
++      DRM_DEBUG_KMS("encoder dpms: %d\n", mode);
+       if (exynos_encoder->dpms == mode) {
+               DRM_DEBUG_KMS("desired dpms mode is same as previous one.\n");
+@@ -104,8 +104,6 @@ exynos_drm_encoder_mode_fixup(struct drm_encoder *encoder,
+       struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
+       struct exynos_drm_manager_ops *manager_ops = manager->ops;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+               if (connector->encoder == encoder)
+                       if (manager_ops && manager_ops->mode_fixup)
+@@ -155,8 +153,6 @@ static void exynos_drm_encoder_mode_set(struct drm_encoder *encoder,
+       struct exynos_drm_manager *manager;
+       struct exynos_drm_manager_ops *manager_ops;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+               if (connector->encoder == encoder) {
+                       struct exynos_drm_encoder *exynos_encoder;
+@@ -189,8 +185,6 @@ static void exynos_drm_encoder_mode_set(struct drm_encoder *encoder,
+ static void exynos_drm_encoder_prepare(struct drm_encoder *encoder)
+ {
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /* drm framework doesn't check NULL. */
+ }
+@@ -200,8 +194,6 @@ static void exynos_drm_encoder_commit(struct drm_encoder *encoder)
+       struct exynos_drm_manager *manager = exynos_encoder->manager;
+       struct exynos_drm_manager_ops *manager_ops = manager->ops;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (manager_ops && manager_ops->commit)
+               manager_ops->commit(manager->dev);
+@@ -274,8 +266,6 @@ static void exynos_drm_encoder_destroy(struct drm_encoder *encoder)
+       struct exynos_drm_encoder *exynos_encoder =
+               to_exynos_encoder(encoder);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       exynos_encoder->manager->pipe = -1;
+       drm_encoder_cleanup(encoder);
+@@ -315,8 +305,6 @@ void exynos_drm_encoder_setup(struct drm_device *dev)
+ {
+       struct drm_encoder *encoder;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
+               encoder->possible_clones = exynos_drm_encoder_clones(encoder);
+ }
+@@ -329,8 +317,6 @@ exynos_drm_encoder_create(struct drm_device *dev,
+       struct drm_encoder *encoder;
+       struct exynos_drm_encoder *exynos_encoder;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (!manager || !possible_crtcs)
+               return NULL;
+@@ -425,8 +411,6 @@ void exynos_drm_encoder_crtc_dpms(struct drm_encoder *encoder, void *data)
+       struct exynos_drm_manager_ops *manager_ops = manager->ops;
+       int mode = *(int *)data;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (manager_ops && manager_ops->dpms)
+               manager_ops->dpms(manager->dev, mode);
+@@ -447,8 +431,6 @@ void exynos_drm_encoder_crtc_pipe(struct drm_encoder *encoder, void *data)
+               to_exynos_encoder(encoder)->manager;
+       int pipe = *(int *)data;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /*
+        * when crtc is detached from encoder, this pipe is used
+        * to select manager operation
+@@ -463,8 +445,6 @@ void exynos_drm_encoder_plane_mode_set(struct drm_encoder *encoder, void *data)
+       struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
+       struct exynos_drm_overlay *overlay = data;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (overlay_ops && overlay_ops->mode_set)
+               overlay_ops->mode_set(manager->dev, overlay);
+ }
+@@ -476,8 +456,6 @@ void exynos_drm_encoder_plane_commit(struct drm_encoder *encoder, void *data)
+       struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
+       int zpos = DEFAULT_ZPOS;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (data)
+               zpos = *(int *)data;
+@@ -492,8 +470,6 @@ void exynos_drm_encoder_plane_enable(struct drm_encoder *encoder, void *data)
+       struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
+       int zpos = DEFAULT_ZPOS;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (data)
+               zpos = *(int *)data;
+@@ -508,8 +484,6 @@ void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data)
+       struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
+       int zpos = DEFAULT_ZPOS;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (data)
+               zpos = *(int *)data;
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c
+index e2a1a1f..ea39e0e 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
+@@ -70,8 +70,6 @@ static void exynos_drm_fb_destroy(struct drm_framebuffer *fb)
+       struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
+       unsigned int i;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /* make sure that overlay data are updated before relesing fb. */
+       exynos_drm_encoder_complete_scanout(fb);
+@@ -97,8 +95,6 @@ static int exynos_drm_fb_create_handle(struct drm_framebuffer *fb,
+ {
+       struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /* This fb should have only one gem object. */
+       if (WARN_ON(exynos_fb->buf_cnt != 1))
+               return -EINVAL;
+@@ -112,8 +108,6 @@ static int exynos_drm_fb_dirty(struct drm_framebuffer *fb,
+                               unsigned color, struct drm_clip_rect *clips,
+                               unsigned num_clips)
+ {
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /* TODO */
+       return 0;
+@@ -223,8 +217,6 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
+       struct exynos_drm_fb *exynos_fb;
+       int i, ret;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       exynos_fb = kzalloc(sizeof(*exynos_fb), GFP_KERNEL);
+       if (!exynos_fb)
+               return ERR_PTR(-ENOMEM);
+@@ -289,8 +281,6 @@ struct exynos_drm_gem_buf *exynos_drm_fb_buffer(struct drm_framebuffer *fb,
+       struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
+       struct exynos_drm_gem_buf *buffer;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (index >= MAX_FB_BUFFER)
+               return NULL;
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+index d677aee..b5f9a71 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+@@ -44,8 +44,6 @@ static int exynos_drm_fb_mmap(struct fb_info *info,
+       unsigned long vm_size;
+       int ret;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
+       vm_size = vma->vm_end - vma->vm_start;
+@@ -85,8 +83,6 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
+       unsigned int size = fb->width * fb->height * (fb->bits_per_pixel >> 3);
+       unsigned long offset;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth);
+       drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height);
+@@ -149,8 +145,6 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
+       unsigned long size;
+       int ret;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d\n",
+                       sizes->surface_width, sizes->surface_height,
+                       sizes->surface_bpp);
+@@ -239,8 +233,6 @@ int exynos_drm_fbdev_init(struct drm_device *dev)
+       unsigned int num_crtc;
+       int ret;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (!dev->mode_config.num_crtc || !dev->mode_config.num_connector)
+               return 0;
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+index 4efe9a7..99d35b8 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+@@ -176,8 +176,6 @@ static void fimc_sw_reset(struct fimc_context *ctx)
+ {
+       u32 cfg;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       /* stop dma operation */
+       cfg = fimc_read(EXYNOS_CISTATUS);
+       if (EXYNOS_CISTATUS_GET_ENVID_STATUS(cfg)) {
+@@ -211,8 +209,6 @@ static void fimc_sw_reset(struct fimc_context *ctx)
+ static int fimc_set_camblk_fimd0_wb(struct fimc_context *ctx)
+ {
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       return regmap_update_bits(ctx->sysreg, SYSREG_CAMERA_BLK,
+                                 SYSREG_FIMD0WB_DEST_MASK,
+                                 ctx->id << SYSREG_FIMD0WB_DEST_SHIFT);
+@@ -320,8 +316,6 @@ static void fimc_clear_irq(struct fimc_context *ctx)
+ {
+       u32 cfg;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       cfg = fimc_read(EXYNOS_CIGCTRL);
+       cfg |= EXYNOS_CIGCTRL_IRQ_CLR;
+       fimc_write(cfg, EXYNOS_CIGCTRL);
+@@ -381,8 +375,6 @@ static int fimc_get_buf_id(struct fimc_context *ctx)
+       u32 cfg;
+       int frame_cnt, buf_id;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       cfg = fimc_read(EXYNOS_CISTATUS2);
+       frame_cnt = EXYNOS_CISTATUS2_GET_FRAMECOUNT_BEFORE(cfg);
+@@ -1358,8 +1350,6 @@ static int fimc_init_prop_list(struct exynos_drm_ippdrv *ippdrv)
+ {
+       struct drm_exynos_ipp_prop_list *prop_list;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       prop_list = devm_kzalloc(ippdrv->dev, sizeof(*prop_list), GFP_KERNEL);
+       if (!prop_list)
+               return -ENOMEM;
+@@ -1418,8 +1408,6 @@ static int fimc_ippdrv_check_property(struct device *dev,
+       bool swap;
+       int i;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       for_each_ipp_ops(i) {
+               if ((i == EXYNOS_DRM_OPS_SRC) &&
+                       (property->cmd == IPP_CMD_WB))
+@@ -1525,8 +1513,6 @@ static void fimc_clear_addr(struct fimc_context *ctx)
+ {
+       int i;
+-      DRM_DEBUG_KMS("%s:\n", __func__);
+-
+       for (i = 0; i < FIMC_MAX_SRC; i++) {
+               fimc_write(0, EXYNOS_CIIYSA(i));
+               fimc_write(0, EXYNOS_CIICBSA(i));
+@@ -1544,8 +1530,6 @@ static int fimc_ippdrv_reset(struct device *dev)
+ {
+       struct fimc_context *ctx = get_fimc_context(dev);
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       /* reset h/w block */
+       fimc_sw_reset(ctx);
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+index 80f5ec5..a0b88a2 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+@@ -150,8 +150,6 @@ static inline struct fimd_driver_data *drm_fimd_get_driver_data(
+ static bool fimd_display_is_connected(struct device *dev)
+ {
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /* TODO. */
+       return true;
+@@ -161,15 +159,11 @@ static void *fimd_get_panel(struct device *dev)
+ {
+       struct fimd_context *ctx = get_fimd_context(dev);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       return ctx->panel;
+ }
+ static int fimd_check_mode(struct device *dev, struct drm_display_mode *mode)
+ {
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /* TODO. */
+       return 0;
+@@ -177,8 +171,6 @@ static int fimd_check_mode(struct device *dev, struct drm_display_mode *mode)
+ static int fimd_display_power_on(struct device *dev, int mode)
+ {
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /* TODO */
+       return 0;
+@@ -196,7 +188,7 @@ static void fimd_dpms(struct device *subdrv_dev, int mode)
+ {
+       struct fimd_context *ctx = get_fimd_context(subdrv_dev);
+-      DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode);
++      DRM_DEBUG_KMS("%d\n", mode);
+       mutex_lock(&ctx->lock);
+@@ -234,8 +226,6 @@ static void fimd_apply(struct device *subdrv_dev)
+       struct fimd_win_data *win_data;
+       int i;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       for (i = 0; i < WINDOWS_NR; i++) {
+               win_data = &ctx->win_data[i];
+               if (win_data->enabled && (ovl_ops && ovl_ops->commit))
+@@ -258,8 +248,6 @@ static void fimd_commit(struct device *dev)
+       if (ctx->suspended)
+               return;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /* setup polarity values from machine code. */
+       writel(ctx->vidcon1, ctx->regs + driver_data->timing_base + VIDCON1);
+@@ -309,8 +297,6 @@ static int fimd_enable_vblank(struct device *dev)
+       struct fimd_context *ctx = get_fimd_context(dev);
+       u32 val;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (ctx->suspended)
+               return -EPERM;
+@@ -336,8 +322,6 @@ static void fimd_disable_vblank(struct device *dev)
+       struct fimd_context *ctx = get_fimd_context(dev);
+       u32 val;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (ctx->suspended)
+               return;
+@@ -387,8 +371,6 @@ static void fimd_win_mode_set(struct device *dev,
+       int win;
+       unsigned long offset;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (!overlay) {
+               dev_err(dev, "overlay is NULL\n");
+               return;
+@@ -436,8 +418,6 @@ static void fimd_win_set_pixfmt(struct device *dev, unsigned int win)
+       struct fimd_win_data *win_data = &ctx->win_data[win];
+       unsigned long val;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       val = WINCONx_ENWIN;
+       switch (win_data->pixel_format) {
+@@ -486,8 +466,6 @@ static void fimd_win_set_colkey(struct device *dev, unsigned int win)
+       struct fimd_context *ctx = get_fimd_context(dev);
+       unsigned int keycon0 = 0, keycon1 = 0;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       keycon0 = ~(WxKEYCON0_KEYBL_EN | WxKEYCON0_KEYEN_F |
+                       WxKEYCON0_DIRCON) | WxKEYCON0_COMPKEY(0);
+@@ -533,8 +511,6 @@ static void fimd_win_commit(struct device *dev, int zpos)
+       unsigned int last_x;
+       unsigned int last_y;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (ctx->suspended)
+               return;
+@@ -653,8 +629,6 @@ static void fimd_win_disable(struct device *dev, int zpos)
+       int win = zpos;
+       u32 val;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (win == DEFAULT_ZPOS)
+               win = ctx->default_win;
+@@ -756,8 +730,6 @@ static void fimd_clear_channel(struct device *dev)
+ static int fimd_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
+ {
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /*
+        * enable drm irq mode.
+        * - with irq_enabled = 1, we can use the vblank feature.
+@@ -789,8 +761,6 @@ static int fimd_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
+ static void fimd_subdrv_remove(struct drm_device *drm_dev, struct device *dev)
+ {
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /* detach this sub driver from iommu mapping if supported. */
+       if (is_drm_iommu_supported(drm_dev))
+               drm_iommu_detach_device(drm_dev, dev);
+@@ -805,8 +775,6 @@ static int fimd_calc_clkdiv(struct fimd_context *ctx,
+       u32 best_framerate = 0;
+       u32 framerate;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       retrace = timing->left_margin + timing->hsync_len +
+                               timing->right_margin + timing->xres;
+       retrace *= timing->upper_margin + timing->vsync_len +
+@@ -841,8 +809,6 @@ static int fimd_calc_clkdiv(struct fimd_context *ctx,
+ static void fimd_clear_win(struct fimd_context *ctx, int win)
+ {
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       writel(0, ctx->regs + WINCON(win));
+       writel(0, ctx->regs + VIDOSD_A(win));
+       writel(0, ctx->regs + VIDOSD_B(win));
+@@ -856,8 +822,6 @@ static void fimd_clear_win(struct fimd_context *ctx, int win)
+ static int fimd_clock(struct fimd_context *ctx, bool enable)
+ {
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (enable) {
+               int ret;
+@@ -943,8 +907,6 @@ static int fimd_probe(struct platform_device *pdev)
+       int win;
+       int ret = -EINVAL;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (dev->of_node) {
+               struct device_node *display_np;
+@@ -1061,8 +1023,6 @@ static int fimd_remove(struct platform_device *pdev)
+       struct device *dev = &pdev->dev;
+       struct fimd_context *ctx = platform_get_drvdata(pdev);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       exynos_drm_subdrv_unregister(&ctx->subdrv);
+       if (ctx->suspended)
+@@ -1127,8 +1087,6 @@ static int fimd_runtime_suspend(struct device *dev)
+ {
+       struct fimd_context *ctx = get_fimd_context(dev);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       return fimd_activate(ctx, false);
+ }
+@@ -1136,8 +1094,6 @@ static int fimd_runtime_resume(struct device *dev)
+ {
+       struct fimd_context *ctx = get_fimd_context(dev);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       return fimd_activate(ctx, true);
+ }
+ #endif
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
+index 8633ba4..5b6f6e2 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
+@@ -132,8 +132,6 @@ void exynos_drm_gem_destroy(struct exynos_drm_gem_obj *exynos_gem_obj)
+       struct drm_gem_object *obj;
+       struct exynos_drm_gem_buf *buf;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       obj = &exynos_gem_obj->base;
+       buf = exynos_gem_obj->buffer;
+@@ -225,7 +223,6 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
+       }
+       size = roundup_gem_size(size, flags);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+       ret = check_gem_flags(flags);
+       if (ret)
+@@ -266,8 +263,6 @@ int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data,
+       struct exynos_drm_gem_obj *exynos_gem_obj;
+       int ret;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       exynos_gem_obj = exynos_drm_gem_create(dev, args->flags, args->size);
+       if (IS_ERR(exynos_gem_obj))
+               return PTR_ERR(exynos_gem_obj);
+@@ -329,8 +324,6 @@ int exynos_drm_gem_map_offset_ioctl(struct drm_device *dev, void *data,
+ {
+       struct drm_exynos_gem_map_off *args = data;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       DRM_DEBUG_KMS("handle = 0x%x, offset = 0x%lx\n",
+                       args->handle, (unsigned long)args->offset);
+@@ -369,8 +362,6 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp,
+       unsigned long vm_size;
+       int ret;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
+       vma->vm_private_data = obj;
+       vma->vm_ops = drm_dev->driver->gem_vm_ops;
+@@ -429,8 +420,6 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data,
+       struct drm_gem_object *obj;
+       unsigned int addr;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (!(dev->driver->driver_features & DRIVER_GEM)) {
+               DRM_ERROR("does not support GEM.\n");
+               return -ENODEV;
+@@ -641,8 +630,6 @@ void exynos_gem_unmap_sgt_from_dma(struct drm_device *drm_dev,
+ int exynos_drm_gem_init_object(struct drm_gem_object *obj)
+ {
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       return 0;
+ }
+@@ -651,8 +638,6 @@ void exynos_drm_gem_free_object(struct drm_gem_object *obj)
+       struct exynos_drm_gem_obj *exynos_gem_obj;
+       struct exynos_drm_gem_buf *buf;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       exynos_gem_obj = to_exynos_gem_obj(obj);
+       buf = exynos_gem_obj->buffer;
+@@ -669,8 +654,6 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv,
+       struct exynos_drm_gem_obj *exynos_gem_obj;
+       int ret;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /*
+        * alocate memory to be used for framebuffer.
+        * - this callback would be called by user application
+@@ -702,8 +685,6 @@ int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv,
+       struct drm_gem_object *obj;
+       int ret = 0;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       mutex_lock(&dev->struct_mutex);
+       /*
+@@ -741,8 +722,6 @@ int exynos_drm_gem_dumb_destroy(struct drm_file *file_priv,
+ {
+       int ret;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /*
+        * obj->refcount and obj->handle_count are decreased and
+        * if both them are 0 then exynos_drm_gem_free_object()
+@@ -786,8 +765,6 @@ int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
+       struct drm_gem_object *obj;
+       int ret;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /* set vm_area_struct. */
+       ret = drm_gem_mmap(filp, vma);
+       if (ret < 0) {
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
+index b9ec6d7..c9bc0a5 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
+@@ -400,8 +400,6 @@ static int gsc_sw_reset(struct gsc_context *ctx)
+       u32 cfg;
+       int count = GSC_RESET_TIMEOUT;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       /* s/w reset */
+       cfg = (GSC_SW_RESET_SRESET);
+       gsc_write(cfg, GSC_SW_RESET);
+@@ -441,8 +439,6 @@ static void gsc_set_gscblk_fimd_wb(struct gsc_context *ctx, bool enable)
+ {
+       u32 gscblk_cfg;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       gscblk_cfg = readl(SYSREG_GSCBLK_CFG1);
+       if (enable)
+@@ -1350,8 +1346,6 @@ static int gsc_init_prop_list(struct exynos_drm_ippdrv *ippdrv)
+ {
+       struct drm_exynos_ipp_prop_list *prop_list;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       prop_list = devm_kzalloc(ippdrv->dev, sizeof(*prop_list), GFP_KERNEL);
+       if (!prop_list)
+               return -ENOMEM;
+@@ -1409,8 +1403,6 @@ static int gsc_ippdrv_check_property(struct device *dev,
+       bool swap;
+       int i;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       for_each_ipp_ops(i) {
+               if ((i == EXYNOS_DRM_OPS_SRC) &&
+                       (property->cmd == IPP_CMD_WB))
+@@ -1519,8 +1511,6 @@ static int gsc_ippdrv_reset(struct device *dev)
+       struct gsc_scaler *sc = &ctx->sc;
+       int ret;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       /* reset h/w block */
+       ret = gsc_sw_reset(ctx);
+       if (ret < 0) {
+@@ -1805,7 +1795,7 @@ static int gsc_runtime_resume(struct device *dev)
+ {
+       struct gsc_context *ctx = get_gsc_context(dev);
+-      DRM_DEBUG_KMS("%s:id[%d]\n", __FILE__, ctx->id);
++      DRM_DEBUG_KMS("id[%d]\n", ctx->id);
+       return  gsc_clk_ctrl(ctx, true);
+ }
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
+index 1be4f64..d7c23e2 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
+@@ -87,16 +87,12 @@ void exynos_mixer_drv_attach(struct exynos_drm_hdmi_context *ctx)
+ void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops)
+ {
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (ops)
+               hdmi_ops = ops;
+ }
+ void exynos_mixer_ops_register(struct exynos_mixer_ops *ops)
+ {
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (ops)
+               mixer_ops = ops;
+ }
+@@ -105,8 +101,6 @@ static bool drm_hdmi_is_connected(struct device *dev)
+ {
+       struct drm_hdmi_context *ctx = to_context(dev);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (hdmi_ops && hdmi_ops->is_connected)
+               return hdmi_ops->is_connected(ctx->hdmi_ctx->ctx);
+@@ -118,8 +112,6 @@ static struct edid *drm_hdmi_get_edid(struct device *dev,
+ {
+       struct drm_hdmi_context *ctx = to_context(dev);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (hdmi_ops && hdmi_ops->get_edid)
+               return hdmi_ops->get_edid(ctx->hdmi_ctx->ctx, connector);
+@@ -132,8 +124,6 @@ static int drm_hdmi_check_mode(struct device *dev,
+       struct drm_hdmi_context *ctx = to_context(dev);
+       int ret = 0;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /*
+       * Both, mixer and hdmi should be able to handle the requested mode.
+       * If any of the two fails, return mode as BAD.
+@@ -155,8 +145,6 @@ static int drm_hdmi_power_on(struct device *dev, int mode)
+ {
+       struct drm_hdmi_context *ctx = to_context(dev);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (hdmi_ops && hdmi_ops->power_on)
+               return hdmi_ops->power_on(ctx->hdmi_ctx->ctx, mode);
+@@ -177,8 +165,6 @@ static int drm_hdmi_enable_vblank(struct device *subdrv_dev)
+       struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
+       struct exynos_drm_manager *manager = subdrv->manager;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (mixer_ops && mixer_ops->enable_vblank)
+               return mixer_ops->enable_vblank(ctx->mixer_ctx->ctx,
+                                               manager->pipe);
+@@ -190,8 +176,6 @@ static void drm_hdmi_disable_vblank(struct device *subdrv_dev)
+ {
+       struct drm_hdmi_context *ctx = to_context(subdrv_dev);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (mixer_ops && mixer_ops->disable_vblank)
+               return mixer_ops->disable_vblank(ctx->mixer_ctx->ctx);
+ }
+@@ -200,8 +184,6 @@ static void drm_hdmi_wait_for_vblank(struct device *subdrv_dev)
+ {
+       struct drm_hdmi_context *ctx = to_context(subdrv_dev);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (mixer_ops && mixer_ops->wait_for_vblank)
+               mixer_ops->wait_for_vblank(ctx->mixer_ctx->ctx);
+ }
+@@ -214,8 +196,6 @@ static void drm_hdmi_mode_fixup(struct device *subdrv_dev,
+       struct drm_display_mode *m;
+       int mode_ok;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       drm_mode_set_crtcinfo(adjusted_mode, 0);
+       mode_ok = drm_hdmi_check_mode(subdrv_dev, adjusted_mode);
+@@ -256,8 +236,6 @@ static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode)
+ {
+       struct drm_hdmi_context *ctx = to_context(subdrv_dev);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (hdmi_ops && hdmi_ops->mode_set)
+               hdmi_ops->mode_set(ctx->hdmi_ctx->ctx, mode);
+ }
+@@ -267,8 +245,6 @@ static void drm_hdmi_get_max_resol(struct device *subdrv_dev,
+ {
+       struct drm_hdmi_context *ctx = to_context(subdrv_dev);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (hdmi_ops && hdmi_ops->get_max_resol)
+               hdmi_ops->get_max_resol(ctx->hdmi_ctx->ctx, width, height);
+ }
+@@ -277,8 +253,6 @@ static void drm_hdmi_commit(struct device *subdrv_dev)
+ {
+       struct drm_hdmi_context *ctx = to_context(subdrv_dev);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (hdmi_ops && hdmi_ops->commit)
+               hdmi_ops->commit(ctx->hdmi_ctx->ctx);
+ }
+@@ -287,8 +261,6 @@ static void drm_hdmi_dpms(struct device *subdrv_dev, int mode)
+ {
+       struct drm_hdmi_context *ctx = to_context(subdrv_dev);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (mixer_ops && mixer_ops->dpms)
+               mixer_ops->dpms(ctx->mixer_ctx->ctx, mode);
+@@ -301,8 +273,6 @@ static void drm_hdmi_apply(struct device *subdrv_dev)
+       struct drm_hdmi_context *ctx = to_context(subdrv_dev);
+       int i;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       for (i = 0; i < MIXER_WIN_NR; i++) {
+               if (!ctx->enabled[i])
+                       continue;
+@@ -331,8 +301,6 @@ static void drm_mixer_mode_set(struct device *subdrv_dev,
+ {
+       struct drm_hdmi_context *ctx = to_context(subdrv_dev);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (mixer_ops && mixer_ops->win_mode_set)
+               mixer_ops->win_mode_set(ctx->mixer_ctx->ctx, overlay);
+ }
+@@ -342,8 +310,6 @@ static void drm_mixer_commit(struct device *subdrv_dev, int zpos)
+       struct drm_hdmi_context *ctx = to_context(subdrv_dev);
+       int win = (zpos == DEFAULT_ZPOS) ? MIXER_DEFAULT_WIN : zpos;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (win < 0 || win > MIXER_WIN_NR) {
+               DRM_ERROR("mixer window[%d] is wrong\n", win);
+               return;
+@@ -360,8 +326,6 @@ static void drm_mixer_disable(struct device *subdrv_dev, int zpos)
+       struct drm_hdmi_context *ctx = to_context(subdrv_dev);
+       int win = (zpos == DEFAULT_ZPOS) ? MIXER_DEFAULT_WIN : zpos;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (win < 0 || win > MIXER_WIN_NR) {
+               DRM_ERROR("mixer window[%d] is wrong\n", win);
+               return;
+@@ -392,8 +356,6 @@ static int hdmi_subdrv_probe(struct drm_device *drm_dev,
+       struct exynos_drm_subdrv *subdrv = to_subdrv(dev);
+       struct drm_hdmi_context *ctx;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (!hdmi_ctx) {
+               DRM_ERROR("hdmi context not initialized.\n");
+               return -EFAULT;
+@@ -440,8 +402,6 @@ static int exynos_drm_hdmi_probe(struct platform_device *pdev)
+       struct exynos_drm_subdrv *subdrv;
+       struct drm_hdmi_context *ctx;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
+       if (!ctx)
+               return -ENOMEM;
+@@ -464,8 +424,6 @@ static int exynos_drm_hdmi_remove(struct platform_device *pdev)
+ {
+       struct drm_hdmi_context *ctx = platform_get_drvdata(pdev);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       exynos_drm_subdrv_unregister(&ctx->subdrv);
+       return 0;
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+index 1b3b59c..4cd2b40 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+@@ -130,8 +130,6 @@ void exynos_platform_device_ipp_unregister(void)
+ int exynos_drm_ippdrv_register(struct exynos_drm_ippdrv *ippdrv)
+ {
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       if (!ippdrv)
+               return -EINVAL;
+@@ -144,8 +142,6 @@ int exynos_drm_ippdrv_register(struct exynos_drm_ippdrv *ippdrv)
+ int exynos_drm_ippdrv_unregister(struct exynos_drm_ippdrv *ippdrv)
+ {
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       if (!ippdrv)
+               return -EINVAL;
+@@ -161,8 +157,6 @@ static int ipp_create_id(struct idr *id_idr, struct mutex *lock, void *obj,
+ {
+       int ret;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       /* do the allocation under our mutexlock */
+       mutex_lock(lock);
+       ret = idr_alloc(id_idr, obj, 1, 0, GFP_KERNEL);
+@@ -319,8 +313,6 @@ int exynos_drm_ipp_get_property(struct drm_device *drm_dev, void *data,
+       struct exynos_drm_ippdrv *ippdrv;
+       int count = 0;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       if (!ctx) {
+               DRM_ERROR("invalid context.\n");
+               return -EINVAL;
+@@ -417,8 +409,6 @@ static struct drm_exynos_ipp_cmd_work *ipp_create_cmd_work(void)
+ {
+       struct drm_exynos_ipp_cmd_work *cmd_work;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       cmd_work = kzalloc(sizeof(*cmd_work), GFP_KERNEL);
+       if (!cmd_work)
+               return ERR_PTR(-ENOMEM);
+@@ -432,8 +422,6 @@ static struct drm_exynos_ipp_event_work *ipp_create_event_work(void)
+ {
+       struct drm_exynos_ipp_event_work *event_work;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       event_work = kzalloc(sizeof(*event_work), GFP_KERNEL);
+       if (!event_work)
+               return ERR_PTR(-ENOMEM);
+@@ -455,8 +443,6 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
+       struct drm_exynos_ipp_cmd_node *c_node;
+       int ret, i;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       if (!ctx) {
+               DRM_ERROR("invalid context.\n");
+               return -EINVAL;
+@@ -562,8 +548,6 @@ err_clear:
+ static void ipp_clean_cmd_node(struct drm_exynos_ipp_cmd_node *c_node)
+ {
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       /* delete list */
+       list_del(&c_node->list);
+@@ -586,8 +570,6 @@ static int ipp_check_mem_list(struct drm_exynos_ipp_cmd_node *c_node)
+       struct list_head *head;
+       int ret, i, count[EXYNOS_DRM_OPS_MAX] = { 0, };
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       mutex_lock(&c_node->mem_lock);
+       for_each_ipp_ops(i) {
+@@ -707,8 +689,6 @@ static struct drm_exynos_ipp_mem_node
+       void *addr;
+       int i;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       mutex_lock(&c_node->mem_lock);
+       m_node = kzalloc(sizeof(*m_node), GFP_KERNEL);
+@@ -846,8 +826,6 @@ static void ipp_put_event(struct drm_exynos_ipp_cmd_node *c_node,
+       struct drm_exynos_ipp_send_event *e, *te;
+       int count = 0;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       if (list_empty(&c_node->event_list)) {
+               DRM_DEBUG_KMS("%s:event_list is empty.\n", __func__);
+               return;
+@@ -901,8 +879,6 @@ static int ipp_queue_buf_with_run(struct device *dev,
+       struct exynos_drm_ipp_ops *ops;
+       int ret;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       ippdrv = ipp_find_drv_by_handle(qbuf->prop_id);
+       if (IS_ERR(ippdrv)) {
+               DRM_ERROR("failed to get ipp driver.\n");
+@@ -953,8 +929,6 @@ static void ipp_clean_queue_buf(struct drm_device *drm_dev,
+ {
+       struct drm_exynos_ipp_mem_node *m_node, *tm_node;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       if (!list_empty(&c_node->mem_list[qbuf->ops_id])) {
+               /* delete list */
+               list_for_each_entry_safe(m_node, tm_node,
+@@ -978,8 +952,6 @@ int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data,
+       struct drm_exynos_ipp_mem_node *m_node;
+       int ret;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       if (!qbuf) {
+               DRM_ERROR("invalid buf parameter.\n");
+               return -EINVAL;
+@@ -1064,8 +1036,6 @@ err_clean_node:
+ static bool exynos_drm_ipp_check_valid(struct device *dev,
+               enum drm_exynos_ipp_ctrl ctrl, enum drm_exynos_ipp_state state)
+ {
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       if (ctrl != IPP_CTRL_PLAY) {
+               if (pm_runtime_suspended(dev)) {
+                       DRM_ERROR("pm:runtime_suspended.\n");
+@@ -1115,8 +1085,6 @@ int exynos_drm_ipp_cmd_ctrl(struct drm_device *drm_dev, void *data,
+       struct drm_exynos_ipp_cmd_work *cmd_work;
+       struct drm_exynos_ipp_cmd_node *c_node;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       if (!ctx) {
+               DRM_ERROR("invalid context.\n");
+               return -EINVAL;
+@@ -1480,8 +1448,6 @@ void ipp_sched_cmd(struct work_struct *work)
+       struct drm_exynos_ipp_property *property;
+       int ret;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       ippdrv = cmd_work->ippdrv;
+       if (!ippdrv) {
+               DRM_ERROR("invalid ippdrv list.\n");
+@@ -1748,8 +1714,6 @@ static int ipp_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
+       struct exynos_drm_ippdrv *ippdrv;
+       int ret, count = 0;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       /* get ipp driver entry */
+       list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) {
+               ippdrv->drm_dev = drm_dev;
+@@ -1805,8 +1769,6 @@ static void ipp_subdrv_remove(struct drm_device *drm_dev, struct device *dev)
+ {
+       struct exynos_drm_ippdrv *ippdrv;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       /* get ipp driver entry */
+       list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) {
+               if (is_drm_iommu_supported(drm_dev))
+@@ -1823,8 +1785,6 @@ static int ipp_subdrv_open(struct drm_device *drm_dev, struct device *dev,
+       struct drm_exynos_file_private *file_priv = file->driver_priv;
+       struct exynos_drm_ipp_private *priv;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+@@ -1900,8 +1860,6 @@ static int ipp_probe(struct platform_device *pdev)
+       if (!ctx)
+               return -ENOMEM;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       mutex_init(&ctx->ipp_lock);
+       mutex_init(&ctx->prop_lock);
+@@ -1965,8 +1923,6 @@ static int ipp_remove(struct platform_device *pdev)
+ {
+       struct ipp_context *ctx = platform_get_drvdata(pdev);
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       /* unregister sub driver */
+       exynos_drm_subdrv_unregister(&ctx->subdrv);
+@@ -1996,8 +1952,6 @@ static int ipp_suspend(struct device *dev)
+ {
+       struct ipp_context *ctx = get_ipp_context(dev);
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       if (pm_runtime_suspended(dev))
+               return 0;
+@@ -2008,8 +1962,6 @@ static int ipp_resume(struct device *dev)
+ {
+       struct ipp_context *ctx = get_ipp_context(dev);
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       if (!pm_runtime_suspended(dev))
+               return ipp_power_ctrl(ctx, true);
+@@ -2022,8 +1974,6 @@ static int ipp_runtime_suspend(struct device *dev)
+ {
+       struct ipp_context *ctx = get_ipp_context(dev);
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       return ipp_power_ctrl(ctx, false);
+ }
+@@ -2031,8 +1981,6 @@ static int ipp_runtime_resume(struct device *dev)
+ {
+       struct ipp_context *ctx = get_ipp_context(dev);
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       return ipp_power_ctrl(ctx, true);
+ }
+ #endif
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
+index 55f8d97..fcb0652 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
+@@ -82,8 +82,6 @@ int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
+       int nr;
+       int i;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       nr = exynos_drm_fb_get_buf_cnt(fb);
+       for (i = 0; i < nr; i++) {
+               struct exynos_drm_gem_buf *buffer = exynos_drm_fb_buffer(fb, i);
+@@ -160,8 +158,6 @@ void exynos_plane_dpms(struct drm_plane *plane, int mode)
+       struct exynos_plane *exynos_plane = to_exynos_plane(plane);
+       struct exynos_drm_overlay *overlay = &exynos_plane->overlay;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       if (mode == DRM_MODE_DPMS_ON) {
+               if (exynos_plane->enabled)
+                       return;
+@@ -190,8 +186,6 @@ exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
+ {
+       int ret;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       ret = exynos_plane_mode_set(plane, crtc, fb, crtc_x, crtc_y,
+                       crtc_w, crtc_h, src_x >> 16, src_y >> 16,
+                       src_w >> 16, src_h >> 16);
+@@ -208,8 +202,6 @@ exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
+ static int exynos_disable_plane(struct drm_plane *plane)
+ {
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       exynos_plane_dpms(plane, DRM_MODE_DPMS_OFF);
+       return 0;
+@@ -219,8 +211,6 @@ static void exynos_plane_destroy(struct drm_plane *plane)
+ {
+       struct exynos_plane *exynos_plane = to_exynos_plane(plane);
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       exynos_disable_plane(plane);
+       drm_plane_cleanup(plane);
+       kfree(exynos_plane);
+@@ -234,8 +224,6 @@ static int exynos_plane_set_property(struct drm_plane *plane,
+       struct exynos_plane *exynos_plane = to_exynos_plane(plane);
+       struct exynos_drm_private *dev_priv = dev->dev_private;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       if (property == dev_priv->plane_zpos_property) {
+               exynos_plane->overlay.zpos = val;
+               return 0;
+@@ -257,8 +245,6 @@ static void exynos_plane_attach_zpos_property(struct drm_plane *plane)
+       struct exynos_drm_private *dev_priv = dev->dev_private;
+       struct drm_property *prop;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       prop = dev_priv->plane_zpos_property;
+       if (!prop) {
+               prop = drm_property_create_range(dev, 0, "zpos", 0,
+@@ -278,8 +264,6 @@ struct drm_plane *exynos_plane_init(struct drm_device *dev,
+       struct exynos_plane *exynos_plane;
+       int err;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       exynos_plane = kzalloc(sizeof(struct exynos_plane), GFP_KERNEL);
+       if (!exynos_plane)
+               return NULL;
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
+index 97b60df..375e36a 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_rotator.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
+@@ -471,8 +471,6 @@ static int rotator_init_prop_list(struct exynos_drm_ippdrv *ippdrv)
+ {
+       struct drm_exynos_ipp_prop_list *prop_list;
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       prop_list = devm_kzalloc(ippdrv->dev, sizeof(*prop_list), GFP_KERNEL);
+       if (!prop_list)
+               return -ENOMEM;
+@@ -797,8 +795,6 @@ static int rotator_remove(struct platform_device *pdev)
+ static int rotator_clk_crtl(struct rot_context *rot, bool enable)
+ {
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       if (enable) {
+               clk_enable(rot->clock);
+               rot->suspended = false;
+@@ -816,8 +812,6 @@ static int rotator_suspend(struct device *dev)
+ {
+       struct rot_context *rot = dev_get_drvdata(dev);
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       if (pm_runtime_suspended(dev))
+               return 0;
+@@ -828,8 +822,6 @@ static int rotator_resume(struct device *dev)
+ {
+       struct rot_context *rot = dev_get_drvdata(dev);
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       if (!pm_runtime_suspended(dev))
+               return rotator_clk_crtl(rot, true);
+@@ -842,8 +834,6 @@ static int rotator_runtime_suspend(struct device *dev)
+ {
+       struct rot_context *rot = dev_get_drvdata(dev);
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       return  rotator_clk_crtl(rot, false);
+ }
+@@ -851,8 +841,6 @@ static int rotator_runtime_resume(struct device *dev)
+ {
+       struct rot_context *rot = dev_get_drvdata(dev);
+-      DRM_DEBUG_KMS("%s\n", __func__);
+-
+       return  rotator_clk_crtl(rot, true);
+ }
+ #endif
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+index 5197eda..eb052e7 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+@@ -96,8 +96,6 @@ static bool vidi_display_is_connected(struct device *dev)
+ {
+       struct vidi_context *ctx = get_vidi_context(dev);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /*
+        * connection request would come from user side
+        * to do hotplug through specific ioctl.
+@@ -112,8 +110,6 @@ static struct edid *vidi_get_edid(struct device *dev,
+       struct edid *edid;
+       int edid_len;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /*
+        * the edid data comes from user side and it would be set
+        * to ctx->raw_edid through specific ioctl.
+@@ -135,8 +131,6 @@ static struct edid *vidi_get_edid(struct device *dev,
+ static void *vidi_get_panel(struct device *dev)
+ {
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /* TODO. */
+       return NULL;
+@@ -144,8 +138,6 @@ static void *vidi_get_panel(struct device *dev)
+ static int vidi_check_mode(struct device *dev, struct drm_display_mode *mode)
+ {
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /* TODO. */
+       return 0;
+@@ -153,8 +145,6 @@ static int vidi_check_mode(struct device *dev, struct drm_display_mode *mode)
+ static int vidi_display_power_on(struct device *dev, int mode)
+ {
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /* TODO */
+       return 0;
+@@ -173,7 +163,7 @@ static void vidi_dpms(struct device *subdrv_dev, int mode)
+ {
+       struct vidi_context *ctx = get_vidi_context(subdrv_dev);
+-      DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode);
++      DRM_DEBUG_KMS("%d\n", mode);
+       mutex_lock(&ctx->lock);
+@@ -203,8 +193,6 @@ static void vidi_apply(struct device *subdrv_dev)
+       struct vidi_win_data *win_data;
+       int i;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       for (i = 0; i < WINDOWS_NR; i++) {
+               win_data = &ctx->win_data[i];
+               if (win_data->enabled && (ovl_ops && ovl_ops->commit))
+@@ -219,8 +207,6 @@ static void vidi_commit(struct device *dev)
+ {
+       struct vidi_context *ctx = get_vidi_context(dev);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (ctx->suspended)
+               return;
+ }
+@@ -229,8 +215,6 @@ static int vidi_enable_vblank(struct device *dev)
+ {
+       struct vidi_context *ctx = get_vidi_context(dev);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (ctx->suspended)
+               return -EPERM;
+@@ -253,8 +237,6 @@ static void vidi_disable_vblank(struct device *dev)
+ {
+       struct vidi_context *ctx = get_vidi_context(dev);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (ctx->suspended)
+               return;
+@@ -278,8 +260,6 @@ static void vidi_win_mode_set(struct device *dev,
+       int win;
+       unsigned long offset;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (!overlay) {
+               dev_err(dev, "overlay is NULL\n");
+               return;
+@@ -331,8 +311,6 @@ static void vidi_win_commit(struct device *dev, int zpos)
+       struct vidi_win_data *win_data;
+       int win = zpos;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (ctx->suspended)
+               return;
+@@ -358,8 +336,6 @@ static void vidi_win_disable(struct device *dev, int zpos)
+       struct vidi_win_data *win_data;
+       int win = zpos;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (win == DEFAULT_ZPOS)
+               win = ctx->default_win;
+@@ -414,8 +390,6 @@ static void vidi_fake_vblank_handler(struct work_struct *work)
+ static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
+ {
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /*
+        * enable drm irq mode.
+        * - with irq_enabled = 1, we can use the vblank feature.
+@@ -438,8 +412,6 @@ static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
+ static void vidi_subdrv_remove(struct drm_device *drm_dev, struct device *dev)
+ {
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       /* TODO. */
+ }
+@@ -448,8 +420,6 @@ static int vidi_power_on(struct vidi_context *ctx, bool enable)
+       struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
+       struct device *dev = subdrv->dev;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (enable != false && enable != true)
+               return -EINVAL;
+@@ -490,8 +460,6 @@ static int vidi_store_connection(struct device *dev,
+       struct vidi_context *ctx = get_vidi_context(dev);
+       int ret;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       ret = kstrtoint(buf, 0, &ctx->connected);
+       if (ret)
+               return ret;
+@@ -529,8 +497,6 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
+       struct drm_exynos_vidi_connection *vidi = data;
+       int edid_len;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       if (!vidi) {
+               DRM_DEBUG_KMS("user data for vidi is null.\n");
+               return -EINVAL;
+@@ -599,8 +565,6 @@ static int vidi_probe(struct platform_device *pdev)
+       struct exynos_drm_subdrv *subdrv;
+       int ret;
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
+       if (!ctx)
+               return -ENOMEM;
+@@ -632,8 +596,6 @@ static int vidi_remove(struct platform_device *pdev)
+ {
+       struct vidi_context *ctx = platform_get_drvdata(pdev);
+-      DRM_DEBUG_KMS("%s\n", __FILE__);
+-
+       exynos_drm_subdrv_unregister(&ctx->subdrv);
+       if (ctx->raw_edid != (struct edid *)fake_edid_info) {
+diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
+index e5d8dae..05b24f9 100644
+--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
++++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
+@@ -689,8 +689,6 @@ static void hdmi_reg_infoframe(struct hdmi_context *hdata,
+       u32 mod;
+       u32 vic;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       mod = hdmi_reg_read(hdata, HDMI_MODE_SEL);
+       if (hdata->dvi_mode) {
+               hdmi_reg_writeb(hdata, HDMI_VSI_CON,
+@@ -755,8 +753,6 @@ static struct edid *hdmi_get_edid(void *ctx, struct drm_connector *connector)
+       struct edid *raw_edid;
+       struct hdmi_context *hdata = ctx;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       if (!hdata->ddc_port)
+               return ERR_PTR(-ENODEV);
+@@ -777,8 +773,6 @@ static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
+       const struct hdmiphy_config *confs;
+       int count, i;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       if (hdata->type == HDMI_TYPE13) {
+               confs = hdmiphy_v13_configs;
+               count = ARRAY_SIZE(hdmiphy_v13_configs);
+@@ -1335,8 +1329,6 @@ static void hdmiphy_conf_reset(struct hdmi_context *hdata)
+ static void hdmiphy_poweron(struct hdmi_context *hdata)
+ {
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       if (hdata->type == HDMI_TYPE14)
+               hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0,
+                       HDMI_PHY_POWER_OFF_EN);
+@@ -1344,8 +1336,6 @@ static void hdmiphy_poweron(struct hdmi_context *hdata)
+ static void hdmiphy_poweroff(struct hdmi_context *hdata)
+ {
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       if (hdata->type == HDMI_TYPE14)
+               hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0,
+                       HDMI_PHY_POWER_OFF_EN);
+@@ -1409,8 +1399,6 @@ static void hdmiphy_conf_apply(struct hdmi_context *hdata)
+ static void hdmi_conf_apply(struct hdmi_context *hdata)
+ {
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       hdmiphy_conf_reset(hdata);
+       hdmiphy_conf_apply(hdata);
+@@ -1660,8 +1648,6 @@ static void hdmi_mode_set(void *ctx, struct drm_display_mode *mode)
+ static void hdmi_get_max_resol(void *ctx, unsigned int *width,
+                                       unsigned int *height)
+ {
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       *width = MAX_WIDTH;
+       *height = MAX_HEIGHT;
+ }
+@@ -1670,8 +1656,6 @@ static void hdmi_commit(void *ctx)
+ {
+       struct hdmi_context *hdata = ctx;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       mutex_lock(&hdata->hdmi_mutex);
+       if (!hdata->powered) {
+               mutex_unlock(&hdata->hdmi_mutex);
+@@ -1686,8 +1670,6 @@ static void hdmi_poweron(struct hdmi_context *hdata)
+ {
+       struct hdmi_resources *res = &hdata->res;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       mutex_lock(&hdata->hdmi_mutex);
+       if (hdata->powered) {
+               mutex_unlock(&hdata->hdmi_mutex);
+@@ -1712,8 +1694,6 @@ static void hdmi_poweroff(struct hdmi_context *hdata)
+ {
+       struct hdmi_resources *res = &hdata->res;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       mutex_lock(&hdata->hdmi_mutex);
+       if (!hdata->powered)
+               goto out;
+@@ -1941,8 +1921,6 @@ static int hdmi_probe(struct platform_device *pdev)
+       struct resource *res;
+       int ret;
+-      DRM_DEBUG_KMS("[%d]\n", __LINE__);
+-
+       if (dev->of_node) {
+               pdata = drm_hdmi_dt_parse_pdata(dev);
+               if (IS_ERR(pdata)) {
+@@ -2064,8 +2042,6 @@ static int hdmi_remove(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       pm_runtime_disable(dev);
+       /* hdmiphy i2c driver */
+@@ -2082,8 +2058,6 @@ static int hdmi_suspend(struct device *dev)
+       struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
+       struct hdmi_context *hdata = ctx->ctx;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       disable_irq(hdata->irq);
+       hdata->hpd = false;
+@@ -2105,8 +2079,6 @@ static int hdmi_resume(struct device *dev)
+       struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
+       struct hdmi_context *hdata = ctx->ctx;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       hdata->hpd = gpio_get_value(hdata->hpd_gpio);
+       enable_irq(hdata->irq);
+@@ -2127,7 +2099,6 @@ static int hdmi_runtime_suspend(struct device *dev)
+ {
+       struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
+       struct hdmi_context *hdata = ctx->ctx;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+       hdmi_poweroff(hdata);
+@@ -2138,7 +2109,6 @@ static int hdmi_runtime_resume(struct device *dev)
+ {
+       struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
+       struct hdmi_context *hdata = ctx->ctx;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+       hdmi_poweron(hdata);
+diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
+index d0a8afb..7b41942 100644
+--- a/drivers/gpu/drm/exynos/exynos_mixer.c
++++ b/drivers/gpu/drm/exynos/exynos_mixer.c
+@@ -696,8 +696,6 @@ static int mixer_enable_vblank(void *ctx, int pipe)
+       struct mixer_context *mixer_ctx = ctx;
+       struct mixer_resources *res = &mixer_ctx->mixer_res;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       mixer_ctx->pipe = pipe;
+       /* enable vsync interrupt */
+@@ -712,8 +710,6 @@ static void mixer_disable_vblank(void *ctx)
+       struct mixer_context *mixer_ctx = ctx;
+       struct mixer_resources *res = &mixer_ctx->mixer_res;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       /* disable vsync interrupt */
+       mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
+ }
+@@ -725,8 +721,6 @@ static void mixer_win_mode_set(void *ctx,
+       struct hdmi_win_data *win_data;
+       int win;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       if (!overlay) {
+               DRM_ERROR("overlay is NULL\n");
+               return;
+@@ -890,8 +884,6 @@ static void mixer_poweron(struct mixer_context *ctx)
+ {
+       struct mixer_resources *res = &ctx->mixer_res;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       mutex_lock(&ctx->mixer_mutex);
+       if (ctx->powered) {
+               mutex_unlock(&ctx->mixer_mutex);
+@@ -916,8 +908,6 @@ static void mixer_poweroff(struct mixer_context *ctx)
+ {
+       struct mixer_resources *res = &ctx->mixer_res;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       mutex_lock(&ctx->mixer_mutex);
+       if (!ctx->powered)
+               goto out;
+@@ -944,8 +934,6 @@ static void mixer_dpms(void *ctx, int mode)
+ {
+       struct mixer_context *mixer_ctx = ctx;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       switch (mode) {
+       case DRM_MODE_DPMS_ON:
+               if (pm_runtime_suspended(mixer_ctx->dev))
+@@ -1245,8 +1233,6 @@ static int mixer_suspend(struct device *dev)
+       struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
+       struct mixer_context *ctx = drm_hdmi_ctx->ctx;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       if (pm_runtime_suspended(dev)) {
+               DRM_DEBUG_KMS("%s : Already suspended\n", __func__);
+               return 0;
+@@ -1262,8 +1248,6 @@ static int mixer_resume(struct device *dev)
+       struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
+       struct mixer_context *ctx = drm_hdmi_ctx->ctx;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       if (!pm_runtime_suspended(dev)) {
+               DRM_DEBUG_KMS("%s : Already resumed\n", __func__);
+               return 0;
+@@ -1281,8 +1265,6 @@ static int mixer_runtime_suspend(struct device *dev)
+       struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
+       struct mixer_context *ctx = drm_hdmi_ctx->ctx;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       mixer_poweroff(ctx);
+       return 0;
+@@ -1293,8 +1275,6 @@ static int mixer_runtime_resume(struct device *dev)
+       struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
+       struct mixer_context *ctx = drm_hdmi_ctx->ctx;
+-      DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+-
+       mixer_poweron(ctx);
+       return 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0554-drm-exynos-check-a-pixel-format-to-a-particular-wind.patch b/patches.tizen/0554-drm-exynos-check-a-pixel-format-to-a-particular-wind.patch
new file mode 100644 (file)
index 0000000..04e8067
--- /dev/null
@@ -0,0 +1,55 @@
+From b80e9fcd3c7b3e10cec5b177b9f11a312cb4960c Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Tue, 20 Aug 2013 14:28:56 +0900
+Subject: [PATCH 0554/1302] drm/exynos: check a pixel format to a particular
+ window layer
+
+This patch checks if a requested window supports alpha channel or not.
+
+In case of s3c64xx, window 0 doesn't support alpha channel so if
+the request pixel format is ARGB8888 then change it to XRGB8888.
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_fimd.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+index a0b88a2..8aec342 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+@@ -66,11 +66,13 @@ struct fimd_driver_data {
+       unsigned int has_shadowcon:1;
+       unsigned int has_clksel:1;
++      unsigned int has_limited_fmt:1;
+ };
+ static struct fimd_driver_data s3c64xx_fimd_driver_data = {
+       .timing_base = 0x0,
+       .has_clksel = 1,
++      .has_limited_fmt = 1,
+ };
+ static struct fimd_driver_data exynos4_fimd_driver_data = {
+@@ -420,6 +422,15 @@ static void fimd_win_set_pixfmt(struct device *dev, unsigned int win)
+       val = WINCONx_ENWIN;
++      /*
++       * In case of s3c64xx, window 0 doesn't support alpha channel.
++       * So the request format is ARGB8888 then change it to XRGB8888.
++       */
++      if (ctx->driver_data->has_limited_fmt && !win) {
++              if (win_data->pixel_format == DRM_FORMAT_ARGB8888)
++                      win_data->pixel_format = DRM_FORMAT_XRGB8888;
++      }
++
+       switch (win_data->pixel_format) {
+       case DRM_FORMAT_C8:
+               val |= WINCON0_BPPMODE_8BPP_PALETTE;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0555-drm-exynos-use-drm_calloc_large-when-allocates-point.patch b/patches.tizen/0555-drm-exynos-use-drm_calloc_large-when-allocates-point.patch
new file mode 100644 (file)
index 0000000..54eb221
--- /dev/null
@@ -0,0 +1,95 @@
+From 9a067752114cfd0886bada6a48f48d852f9c3979 Mon Sep 17 00:00:00 2001
+From: YoungJun Cho <yj44.cho@samsung.com>
+Date: Wed, 3 Jul 2013 17:09:19 +0900
+Subject: [PATCH 0555/1302] drm/exynos: use drm_calloc_large when allocates
+ pointer array
+
+If the type of object is pointer array, the drm_calloc_large() is
+more suitable than kzalloc() for its allocation function. And uses
+drm_free_large() instead of kfree() also.
+
+Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
+Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_buf.c | 9 ++++-----
+ drivers/gpu/drm/exynos/exynos_drm_g2d.c | 6 +++---
+ 2 files changed, 7 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c b/drivers/gpu/drm/exynos/exynos_drm_buf.c
+index ed5c694..01c8e33 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_buf.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c
+@@ -57,8 +57,7 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
+               dma_addr_t start_addr;
+               unsigned int i = 0;
+-              buf->pages = kzalloc(sizeof(struct page) * nr_pages,
+-                                      GFP_KERNEL);
++              buf->pages = drm_calloc_large(nr_pages, sizeof(struct page));
+               if (!buf->pages) {
+                       DRM_ERROR("failed to allocate pages.\n");
+                       return -ENOMEM;
+@@ -69,7 +68,7 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
+                                       &buf->dma_attrs);
+               if (!buf->kvaddr) {
+                       DRM_ERROR("failed to allocate buffer.\n");
+-                      kfree(buf->pages);
++                      drm_free_large(buf->pages);
+                       return -ENOMEM;
+               }
+@@ -109,7 +108,7 @@ err_free_attrs:
+       buf->dma_addr = (dma_addr_t)NULL;
+       if (!is_drm_iommu_supported(dev))
+-              kfree(buf->pages);
++              drm_free_large(buf->pages);
+       return ret;
+ }
+@@ -134,7 +133,7 @@ static void lowlevel_buffer_deallocate(struct drm_device *dev,
+       if (!is_drm_iommu_supported(dev)) {
+               dma_free_attrs(dev->dev, buf->size, buf->kvaddr,
+                               (dma_addr_t)buf->dma_addr, &buf->dma_attrs);
+-              kfree(buf->pages);
++              drm_free_large(buf->pages);
+       } else
+               dma_free_attrs(dev->dev, buf->size, buf->pages,
+                               (dma_addr_t)buf->dma_addr, &buf->dma_attrs);
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+index 1eb2a2a..8e8678d 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+@@ -390,7 +390,7 @@ out:
+       kfree(g2d_userptr->sgt);
+       g2d_userptr->sgt = NULL;
+-      kfree(g2d_userptr->pages);
++      drm_free_large(g2d_userptr->pages);
+       g2d_userptr->pages = NULL;
+       kfree(g2d_userptr);
+       g2d_userptr = NULL;
+@@ -461,7 +461,7 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev,
+       npages = (end - start) >> PAGE_SHIFT;
+       g2d_userptr->npages = npages;
+-      pages = kzalloc(npages * sizeof(struct page *), GFP_KERNEL);
++      pages = drm_calloc_large(npages, sizeof(struct page *));
+       if (!pages) {
+               DRM_ERROR("failed to allocate pages.\n");
+               kfree(g2d_userptr);
+@@ -551,7 +551,7 @@ err_put_vma:
+       exynos_gem_put_vma(g2d_userptr->vma);
+ err_free_pages:
+-      kfree(pages);
++      drm_free_large(pages);
+       kfree(g2d_userptr);
+       pages = NULL;
+       g2d_userptr = NULL;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0556-drm-exynos-remove-duplicated-error-routine-and-unnec.patch b/patches.tizen/0556-drm-exynos-remove-duplicated-error-routine-and-unnec.patch
new file mode 100644 (file)
index 0000000..297bb79
--- /dev/null
@@ -0,0 +1,97 @@
+From 816e3e21edfcb47fa25fb8b09e0e2889737132c0 Mon Sep 17 00:00:00 2001
+From: Seung-Woo Kim <sw0312.kim@samsung.com>
+Date: Wed, 3 Jul 2013 17:09:21 +0900
+Subject: [PATCH 0556/1302] drm/exynos: remove duplicated error routine and
+ unnecessary assign
+
+There were duplicated error handling routines during allocating
+pages in lowlevel_buffer_allocate() and g2d_userptr_get_dma_addr().
+Also unnecessary NULL assignments for variable used not any more
+are removed from g2d_userptr_get_dma_addr() and
+g2d_userptr_put_dma_addr().
+
+Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
+Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_buf.c |  6 +++---
+ drivers/gpu/drm/exynos/exynos_drm_g2d.c | 12 ++++--------
+ 2 files changed, 7 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c b/drivers/gpu/drm/exynos/exynos_drm_buf.c
+index 01c8e33..774bd48 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_buf.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c
+@@ -68,8 +68,8 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
+                                       &buf->dma_attrs);
+               if (!buf->kvaddr) {
+                       DRM_ERROR("failed to allocate buffer.\n");
+-                      drm_free_large(buf->pages);
+-                      return -ENOMEM;
++                      ret = -ENOMEM;
++                      goto err_free;
+               }
+               start_addr = buf->dma_addr;
+@@ -106,7 +106,7 @@ err_free_attrs:
+       dma_free_attrs(dev->dev, buf->size, buf->pages,
+                       (dma_addr_t)buf->dma_addr, &buf->dma_attrs);
+       buf->dma_addr = (dma_addr_t)NULL;
+-
++err_free:
+       if (!is_drm_iommu_supported(dev))
+               drm_free_large(buf->pages);
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+index 8e8678d..ce28fc9 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+@@ -388,12 +388,9 @@ out:
+       sg_free_table(g2d_userptr->sgt);
+       kfree(g2d_userptr->sgt);
+-      g2d_userptr->sgt = NULL;
+       drm_free_large(g2d_userptr->pages);
+-      g2d_userptr->pages = NULL;
+       kfree(g2d_userptr);
+-      g2d_userptr = NULL;
+ }
+ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev,
+@@ -464,8 +461,8 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev,
+       pages = drm_calloc_large(npages, sizeof(struct page *));
+       if (!pages) {
+               DRM_ERROR("failed to allocate pages.\n");
+-              kfree(g2d_userptr);
+-              return ERR_PTR(-ENOMEM);
++              ret = -ENOMEM;
++              goto err_free;
+       }
+       vma = find_vma(current->mm, userptr);
+@@ -540,7 +537,6 @@ err_sg_free_table:
+ err_free_sgt:
+       kfree(sgt);
+-      sgt = NULL;
+ err_free_userptr:
+       exynos_gem_put_pages_to_userptr(g2d_userptr->pages,
+@@ -552,9 +548,9 @@ err_put_vma:
+ err_free_pages:
+       drm_free_large(pages);
++
++err_free:
+       kfree(g2d_userptr);
+-      pages = NULL;
+-      g2d_userptr = NULL;
+       return ERR_PTR(ret);
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0557-drm-exynos-add-exynos_drm_gem_get_dmabuf-function.patch b/patches.tizen/0557-drm-exynos-add-exynos_drm_gem_get_dmabuf-function.patch
new file mode 100644 (file)
index 0000000..935a5e2
--- /dev/null
@@ -0,0 +1,58 @@
+From 6963fe02645521e655611cef9d914b55c848a464 Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Tue, 20 Aug 2013 17:35:43 +0900
+Subject: [PATCH 0557/1302] drm/exynos: add exynos_drm_gem_get_dmabuf function
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_gem.c | 17 +++++++++++++++++
+ drivers/gpu/drm/exynos/exynos_drm_gem.h |  4 ++++
+ 2 files changed, 21 insertions(+)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
+index 5b6f6e2..55289cd 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
+@@ -319,6 +319,23 @@ void exynos_drm_gem_put_dma_addr(struct drm_device *dev,
+       drm_gem_object_unreference_unlocked(obj);
+ }
++void *exynos_drm_gem_get_dmabuf(struct drm_device *dev,
++                                      unsigned int gem_handle,
++                                      struct drm_file *filp)
++{
++      struct drm_gem_object *obj;
++
++      obj = drm_gem_object_lookup(dev, filp, gem_handle);
++      if (!obj) {
++              DRM_ERROR("failed to lookup gem object.\n");
++              return ERR_PTR(-EINVAL);
++      }
++
++      drm_gem_object_unreference_unlocked(obj);
++
++      return obj->export_dma_buf;
++}
++
+ int exynos_drm_gem_map_offset_ioctl(struct drm_device *dev, void *data,
+                                   struct drm_file *file_priv)
+ {
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h
+index 468766b..78a0833 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
++++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
+@@ -111,6 +111,10 @@ void exynos_drm_gem_put_dma_addr(struct drm_device *dev,
+                                       unsigned int gem_handle,
+                                       struct drm_file *filp);
++void *exynos_drm_gem_get_dmabuf(struct drm_device *dev,
++                                      unsigned int gem_handle,
++                                      struct drm_file *filp);
++
+ /* get buffer offset to map to user space. */
+ int exynos_drm_gem_map_offset_ioctl(struct drm_device *dev, void *data,
+                                   struct drm_file *file_priv);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0558-drm-exynos-add-dmabuf-sync-support-for-g2d-driver.patch b/patches.tizen/0558-drm-exynos-add-dmabuf-sync-support-for-g2d-driver.patch
new file mode 100644 (file)
index 0000000..f41ba0c
--- /dev/null
@@ -0,0 +1,162 @@
+From 20ee1b334280c453dff5b9e3d84a1d6b8829b407 Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Tue, 20 Aug 2013 17:39:12 +0900
+Subject: [PATCH 0558/1302] drm/exynos: add dmabuf sync support for g2d driver
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_g2d.c | 84 ++++++++++++++++++++++++++++++++-
+ 1 file changed, 82 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+index ce28fc9..90432d3 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+@@ -19,6 +19,7 @@
+ #include <linux/dma-mapping.h>
+ #include <linux/dma-attrs.h>
+ #include <linux/of.h>
++#include <linux/dmabuf-sync.h>
+ #include <drm/drmP.h>
+ #include <drm/exynos_drm.h>
+@@ -205,6 +206,7 @@ struct g2d_cmdlist_node {
+       struct g2d_buf_info     buf_info;
+       struct drm_exynos_pending_g2d_event     *event;
++      struct dmabuf_sync      *sync;
+ };
+ struct g2d_runqueue_node {
+@@ -245,6 +247,20 @@ struct g2d_data {
+       unsigned long                   max_pool;
+ };
++static void g2d_dmabuf_sync_free(void *priv)
++{
++      struct g2d_cmdlist_node *node = priv;
++
++      if (!node)
++              return;
++
++      node->sync = NULL;
++}
++
++static struct dmabuf_sync_priv_ops dmabuf_sync_ops = {
++      .free   = g2d_dmabuf_sync_free,
++};
++
+ static int g2d_init_cmdlist(struct g2d_data *g2d)
+ {
+       struct device *dev = g2d->dev;
+@@ -684,6 +700,12 @@ static int g2d_map_cmdlist_gem(struct g2d_data *g2d,
+       int ret;
+       int i;
++      if (is_dmabuf_sync_supported()) {
++              node->sync = dmabuf_sync_init("g2d", &dmabuf_sync_ops, node);
++              if (IS_ERR(node->sync))
++                      node->sync = NULL;
++      }
++
+       for (i = 0; i < buf_info->map_nr; i++) {
+               struct g2d_buf_desc *buf_desc;
+               enum g2d_reg_type reg_type;
+@@ -706,7 +728,30 @@ static int g2d_map_cmdlist_gem(struct g2d_data *g2d,
+               if (buf_info->types[reg_type] == BUF_TYPE_GEM) {
+                       unsigned long size;
++                      unsigned int type;
++                      void *dma_buf = NULL;
++
++                      if (!node->sync)
++                              goto out_dmabuf_sync;
++
++                      dma_buf = exynos_drm_gem_get_dmabuf(drm_dev, handle,
++                                                              file);
++                      if (!dma_buf)
++                              goto out_dmabuf_sync;
++
++                      if (reg_type == REG_TYPE_DST_PLANE2 ||
++                                      reg_type == REG_TYPE_DST)
++                              type = DMA_BUF_ACCESS_DMA_W;
++                      else
++                              type = DMA_BUF_ACCESS_DMA_R;
++
++                      ret = dmabuf_sync_get(node->sync, dma_buf, type);
++                      if (ret < 0) {
++                              WARN_ON(1);
++                              dmabuf_sync_put_all(node->sync);
++                      }
++out_dmabuf_sync:
+                       size = exynos_drm_gem_get_size(drm_dev, handle, file);
+                       if (!size) {
+                               ret = -EFAULT;
+@@ -756,9 +801,19 @@ static int g2d_map_cmdlist_gem(struct g2d_data *g2d,
+               buf_info->handles[reg_type] = handle;
+       }
+-      return 0;
++      if (node->sync) {
++              if (list_empty(&node->sync->syncs))
++                      dmabuf_sync_fini(node->sync);
++      }
++
++      return ret;
+ err:
++      if (node->sync) {
++              dmabuf_sync_put_all(node->sync);
++              dmabuf_sync_fini(node->sync);
++      }
++
+       buf_info->map_nr = i;
+       return ret;
+ }
+@@ -805,6 +860,17 @@ static void g2d_dma_start(struct g2d_data *g2d,
+                                               struct g2d_cmdlist_node, list);
+       int ret;
++      if (node->sync) {
++              int ret;
++
++              ret = dmabuf_sync_lock(node->sync);
++              if (ret < 0) {
++                      WARN_ON(1);
++                      dmabuf_sync_put_all(node->sync);
++                      dmabuf_sync_fini(node->sync);
++              }
++      }
++
+       ret = pm_runtime_get_sync(g2d->dev);
+       if (ret < 0)
+               return;
+@@ -839,8 +905,22 @@ static void g2d_free_runqueue_node(struct g2d_data *g2d,
+        * commands in run_cmdlist have been completed so unmap all gem
+        * objects in each command node so that they are unreferenced.
+        */
+-      list_for_each_entry(node, &runqueue_node->run_cmdlist, list)
++      list_for_each_entry(node, &runqueue_node->run_cmdlist, list) {
++              if (node->sync) {
++                      int ret;
++
++                      ret = dmabuf_sync_unlock(node->sync);
++                      if (ret < 0) {
++                              WARN_ON(1);
++                              /* TODO */
++                      }
++
++                      dmabuf_sync_put_all(node->sync);
++                      dmabuf_sync_fini(node->sync);
++              }
++
+               g2d_unmap_cmdlist_gem(g2d, node, runqueue_node->filp);
++      }
+       list_splice_tail_init(&runqueue_node->run_cmdlist, &g2d->free_cmdlist);
+       mutex_unlock(&g2d->cmdlist_mutex);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0559-vt-disable-console-blank.patch b/patches.tizen/0559-vt-disable-console-blank.patch
new file mode 100644 (file)
index 0000000..7d2857d
--- /dev/null
@@ -0,0 +1,27 @@
+From 8a883198eb085fb5998ffd3a15b7674d4d536117 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Tue, 28 Feb 2012 10:31:19 +0100
+Subject: [PATCH 0559/1302] vt: disable console blank
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/tty/vt/vt.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
+index 740202d..fa02563 100644
+--- a/drivers/tty/vt/vt.c
++++ b/drivers/tty/vt/vt.c
+@@ -176,7 +176,7 @@ int console_blanked;
+ static int vesa_blank_mode; /* 0:none 1:suspendV 2:suspendH 3:powerdown */
+ static int vesa_off_interval;
+-static int blankinterval = 10*60;
++static int blankinterval = 0;
+ core_param(consoleblank, blankinterval, int, 0444);
+ static DECLARE_WORK(console_work, console_callback);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0560-mfd-max8998-Add-irq-domain-support.patch b/patches.tizen/0560-mfd-max8998-Add-irq-domain-support.patch
new file mode 100644 (file)
index 0000000..3dc5d66
--- /dev/null
@@ -0,0 +1,233 @@
+From 2afb23963557685a0f96b0d9bc8ac14bff25e12e Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Mon, 24 Jun 2013 14:39:52 +0200
+Subject: [PATCH 0560/1302] mfd: max8998: Add irq domain support
+
+This patch adds irq domain support for max8998 interrupts.
+
+To keep both non-DT and DT worlds happy, simple domain is used, which is
+linear when no explicit IRQ base is specified and legacy, with static
+mapping, otherwise.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mfd/Kconfig                 |  1 +
+ drivers/mfd/max8998-irq.c           | 65 +++++++++++++++++++++++--------------
+ drivers/rtc/rtc-max8998.c           | 12 ++++++-
+ include/linux/mfd/max8998-private.h |  5 ++-
+ include/linux/mfd/max8998.h         |  2 +-
+ 5 files changed, 57 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
+index d54e985..503a1b5 100644
+--- a/drivers/mfd/Kconfig
++++ b/drivers/mfd/Kconfig
+@@ -342,6 +342,7 @@ config MFD_MAX8998
+       bool "Maxim Semiconductor MAX8998/National LP3974 PMIC Support"
+       depends on I2C=y && GENERIC_HARDIRQS
+       select MFD_CORE
++      select IRQ_DOMAIN
+       help
+         Say yes here to support for Maxim Semiconductor MAX8998 and
+         National Semiconductor LP3974. This is a Power Management IC.
+diff --git a/drivers/mfd/max8998-irq.c b/drivers/mfd/max8998-irq.c
+index 5919710..c469477 100644
+--- a/drivers/mfd/max8998-irq.c
++++ b/drivers/mfd/max8998-irq.c
+@@ -14,6 +14,7 @@
+ #include <linux/device.h>
+ #include <linux/interrupt.h>
+ #include <linux/irq.h>
++#include <linux/irqdomain.h>
+ #include <linux/mfd/max8998-private.h>
+ struct max8998_irq_data {
+@@ -99,7 +100,8 @@ static struct max8998_irq_data max8998_irqs[] = {
+ static inline struct max8998_irq_data *
+ irq_to_max8998_irq(struct max8998_dev *max8998, int irq)
+ {
+-      return &max8998_irqs[irq - max8998->irq_base];
++      struct irq_data *data = irq_get_irq_data(irq);
++      return &max8998_irqs[data->hwirq];
+ }
+ static void max8998_irq_lock(struct irq_data *data)
+@@ -176,8 +178,14 @@ static irqreturn_t max8998_irq_thread(int irq, void *data)
+       /* Report */
+       for (i = 0; i < MAX8998_IRQ_NR; i++) {
+-              if (irq_reg[max8998_irqs[i].reg - 1] & max8998_irqs[i].mask)
+-                      handle_nested_irq(max8998->irq_base + i);
++              if (irq_reg[max8998_irqs[i].reg - 1] & max8998_irqs[i].mask) {
++                      irq = irq_find_mapping(max8998->irq_domain, i);
++                      if (WARN_ON(!irq)) {
++                              disable_irq_nosync(max8998->irq);
++                              return IRQ_NONE;
++                      }
++                      handle_nested_irq(irq);
++              }
+       }
+       return IRQ_HANDLED;
+@@ -185,27 +193,40 @@ static irqreturn_t max8998_irq_thread(int irq, void *data)
+ int max8998_irq_resume(struct max8998_dev *max8998)
+ {
+-      if (max8998->irq && max8998->irq_base)
+-              max8998_irq_thread(max8998->irq_base, max8998);
++      if (max8998->irq && max8998->irq_domain)
++              max8998_irq_thread(max8998->irq, max8998);
++      return 0;
++}
++
++static int max8998_irq_domain_map(struct irq_domain *d, unsigned int irq,
++                                      irq_hw_number_t hw)
++{
++      struct max8997_dev *max8998 = d->host_data;
++
++      irq_set_chip_data(irq, max8998);
++      irq_set_chip_and_handler(irq, &max8998_irq_chip, handle_edge_irq);
++      irq_set_nested_thread(irq, 1);
++#ifdef CONFIG_ARM
++      set_irq_flags(irq, IRQF_VALID);
++#else
++      irq_set_noprobe(irq);
++#endif
+       return 0;
+ }
++static struct irq_domain_ops max8998_irq_domain_ops = {
++      .map = max8998_irq_domain_map,
++};
++
+ int max8998_irq_init(struct max8998_dev *max8998)
+ {
+       int i;
+-      int cur_irq;
+       int ret;
++      struct irq_domain *domain;
+       if (!max8998->irq) {
+               dev_warn(max8998->dev,
+                        "No interrupt specified, no interrupts\n");
+-              max8998->irq_base = 0;
+-              return 0;
+-      }
+-
+-      if (!max8998->irq_base) {
+-              dev_err(max8998->dev,
+-                      "No interrupt base specified, no interrupts\n");
+               return 0;
+       }
+@@ -221,19 +242,13 @@ int max8998_irq_init(struct max8998_dev *max8998)
+       max8998_write_reg(max8998->i2c, MAX8998_REG_STATUSM1, 0xff);
+       max8998_write_reg(max8998->i2c, MAX8998_REG_STATUSM2, 0xff);
+-      /* register with genirq */
+-      for (i = 0; i < MAX8998_IRQ_NR; i++) {
+-              cur_irq = i + max8998->irq_base;
+-              irq_set_chip_data(cur_irq, max8998);
+-              irq_set_chip_and_handler(cur_irq, &max8998_irq_chip,
+-                                       handle_edge_irq);
+-              irq_set_nested_thread(cur_irq, 1);
+-#ifdef CONFIG_ARM
+-              set_irq_flags(cur_irq, IRQF_VALID);
+-#else
+-              irq_set_noprobe(cur_irq);
+-#endif
++      domain = irq_domain_add_simple(NULL, MAX8998_IRQ_NR,
++                      max8998->irq_base, &max8998_irq_domain_ops, max8998);
++      if (!domain) {
++              dev_err(max8998->dev, "could not create irq domain\n");
++              return -ENODEV;
+       }
++      max8998->irq_domain = domain;
+       ret = request_threaded_irq(max8998->irq, NULL, max8998_irq_thread,
+                                  IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+diff --git a/drivers/rtc/rtc-max8998.c b/drivers/rtc/rtc-max8998.c
+index d5af7ba..46f2301 100644
+--- a/drivers/rtc/rtc-max8998.c
++++ b/drivers/rtc/rtc-max8998.c
+@@ -16,6 +16,7 @@
+ #include <linux/i2c.h>
+ #include <linux/slab.h>
+ #include <linux/bcd.h>
++#include <linux/irqdomain.h>
+ #include <linux/rtc.h>
+ #include <linux/platform_device.h>
+ #include <linux/mfd/max8998.h>
+@@ -264,7 +265,6 @@ static int max8998_rtc_probe(struct platform_device *pdev)
+       info->dev = &pdev->dev;
+       info->max8998 = max8998;
+       info->rtc = max8998->rtc;
+-      info->irq = max8998->irq_base + MAX8998_IRQ_ALARM0;
+       platform_set_drvdata(pdev, info);
+@@ -277,6 +277,15 @@ static int max8998_rtc_probe(struct platform_device *pdev)
+               goto out_rtc;
+       }
++      if (!max8998->irq_domain)
++              goto no_irq;
++
++      info->irq = irq_create_mapping(max8998->irq_domain, MAX8998_IRQ_ALARM0);
++      if (!info->irq) {
++              dev_warn(&pdev->dev, "Failed to map alarm IRQ\n");
++              goto no_irq;
++      }
++
+       ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL,
+                               max8998_rtc_alarm_irq, 0, "rtc-alarm0", info);
+@@ -284,6 +293,7 @@ static int max8998_rtc_probe(struct platform_device *pdev)
+               dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
+                       info->irq, ret);
++no_irq:
+       dev_info(&pdev->dev, "RTC CHIP NAME: %s\n", pdev->id_entry->name);
+       if (pdata && pdata->rtc_delay) {
+               info->lp3974_bug_workaround = true;
+diff --git a/include/linux/mfd/max8998-private.h b/include/linux/mfd/max8998-private.h
+index effa5d3..bfb48b6 100644
+--- a/include/linux/mfd/max8998-private.h
++++ b/include/linux/mfd/max8998-private.h
+@@ -132,6 +132,8 @@ enum {
+ #define MAX8998_ENRAMP                  (1 << 4)
++struct irq_domain;
++
+ /**
+  * struct max8998_dev - max8998 master device for sub-drivers
+  * @dev: master device of the chip (can be used to access platform data)
+@@ -153,7 +155,8 @@ struct max8998_dev {
+       struct mutex iolock;
+       struct mutex irqlock;
+-      int irq_base;
++      unsigned int irq_base;
++      struct irq_domain *irq_domain;
+       int irq;
+       int ono;
+       u8 irq_masks_cur[MAX8998_NUM_IRQ_REGS];
+diff --git a/include/linux/mfd/max8998.h b/include/linux/mfd/max8998.h
+index 6823548..7547118 100644
+--- a/include/linux/mfd/max8998.h
++++ b/include/linux/mfd/max8998.h
+@@ -100,7 +100,7 @@ struct max8998_regulator_data {
+ struct max8998_platform_data {
+       struct max8998_regulator_data   *regulators;
+       int                             num_regulators;
+-      int                             irq_base;
++      unsigned int                    irq_base;
+       int                             ono;
+       bool                            buck_voltage_lock;
+       int                             buck1_voltage1;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0561-regulator-max8998-Use-arrays-for-specifying-voltages.patch b/patches.tizen/0561-regulator-max8998-Use-arrays-for-specifying-voltages.patch
new file mode 100644 (file)
index 0000000..0bfb6c2
--- /dev/null
@@ -0,0 +1,244 @@
+From 2f58ddf0b16be3f2feee44b0d171e18cd6808d75 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Mon, 24 Jun 2013 14:39:53 +0200
+Subject: [PATCH 0561/1302] regulator: max8998: Use arrays for specifying
+ voltages in platform data
+
+This patch modifies the platform data of max8998 to use arrays for
+specifying predefined voltages of buck1 and buck2 instead of separate
+field for each voltage.
+
+This allows to simplify the code a bit and will help in adding support
+for Device Tree, which will be introduced in further patch.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Acked-by: Mark Brown <broonie@linaro.org>
+Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/mach-exynos/mach-universal_c210.c |  8 +--
+ arch/arm/mach-s5pv210/mach-aquila.c        |  8 +--
+ arch/arm/mach-s5pv210/mach-goni.c          |  8 +--
+ drivers/regulator/max8998.c                | 96 +++++++++---------------------
+ include/linux/mfd/max8998.h                | 16 ++---
+ 5 files changed, 39 insertions(+), 97 deletions(-)
+
+diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c
+index 74ddb2b..f912444 100644
+--- a/arch/arm/mach-exynos/mach-universal_c210.c
++++ b/arch/arm/mach-exynos/mach-universal_c210.c
+@@ -540,15 +540,11 @@ static struct max8998_regulator_data lp3974_regulators[] = {
+ static struct max8998_platform_data universal_lp3974_pdata = {
+       .num_regulators         = ARRAY_SIZE(lp3974_regulators),
+       .regulators             = lp3974_regulators,
+-      .buck1_voltage1         = 1100000,      /* INT */
+-      .buck1_voltage2         = 1000000,
+-      .buck1_voltage3         = 1100000,
+-      .buck1_voltage4         = 1000000,
++      .buck1_voltage          = { 1100000, 1000000, 1100000, 1000000 },
+       .buck1_set1             = EXYNOS4_GPX0(5),
+       .buck1_set2             = EXYNOS4_GPX0(6),
+-      .buck2_voltage1         = 1200000,      /* G3D */
+-      .buck2_voltage2         = 1100000,
+       .buck1_default_idx      = 0,
++      .buck2_voltage          = { 1200000, 1100000 },
+       .buck2_set3             = EXYNOS4_GPE2(0),
+       .buck2_default_idx      = 0,
+       .wakeup                 = true,
+diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
+index ed2b854..ad40ab0 100644
+--- a/arch/arm/mach-s5pv210/mach-aquila.c
++++ b/arch/arm/mach-s5pv210/mach-aquila.c
+@@ -377,12 +377,8 @@ static struct max8998_platform_data aquila_max8998_pdata = {
+       .buck1_set1     = S5PV210_GPH0(3),
+       .buck1_set2     = S5PV210_GPH0(4),
+       .buck2_set3     = S5PV210_GPH0(5),
+-      .buck1_voltage1 = 1200000,
+-      .buck1_voltage2 = 1200000,
+-      .buck1_voltage3 = 1200000,
+-      .buck1_voltage4 = 1200000,
+-      .buck2_voltage1 = 1200000,
+-      .buck2_voltage2 = 1200000,
++      .buck1_voltage  = { 1200000, 1200000, 1200000, 1200000 },
++      .buck2_voltage  = { 1200000, 1200000 },
+ };
+ #endif
+diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
+index 30b24ad..e5cd9fb 100644
+--- a/arch/arm/mach-s5pv210/mach-goni.c
++++ b/arch/arm/mach-s5pv210/mach-goni.c
+@@ -580,12 +580,8 @@ static struct max8998_platform_data goni_max8998_pdata = {
+       .buck1_set1     = S5PV210_GPH0(3),
+       .buck1_set2     = S5PV210_GPH0(4),
+       .buck2_set3     = S5PV210_GPH0(5),
+-      .buck1_voltage1 = 1200000,
+-      .buck1_voltage2 = 1200000,
+-      .buck1_voltage3 = 1200000,
+-      .buck1_voltage4 = 1200000,
+-      .buck2_voltage1 = 1200000,
+-      .buck2_voltage2 = 1200000,
++      .buck1_voltage  = { 1200000, 1200000, 1200000, 1200000 },
++      .buck2_voltage  = { 1200000, 1200000 },
+ };
+ #endif
+diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c
+index a57a1b1..8c45b93 100644
+--- a/drivers/regulator/max8998.c
++++ b/drivers/regulator/max8998.c
+@@ -630,6 +630,7 @@ static int max8998_pmic_probe(struct platform_device *pdev)
+       struct max8998_data *max8998;
+       struct i2c_client *i2c;
+       int i, ret, size;
++      unsigned int v;
+       if (!pdata) {
+               dev_err(pdev->dev.parent, "No platform init data supplied\n");
+@@ -688,53 +689,21 @@ static int max8998_pmic_probe(struct platform_device *pdev)
+               gpio_request(pdata->buck1_set2, "MAX8998 BUCK1_SET2");
+               gpio_direction_output(pdata->buck1_set2,
+                                     (max8998->buck1_idx >> 1) & 0x1);
+-              /* Set predefined value for BUCK1 register 1 */
+-              i = 0;
+-              while (buck12_voltage_map_desc.min +
+-                     buck12_voltage_map_desc.step*i
+-                     < pdata->buck1_voltage1)
+-                      i++;
+-              max8998->buck1_vol[0] = i;
+-              ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE1, i);
+-              if (ret)
+-                      goto err_out;
+-
+-              /* Set predefined value for BUCK1 register 2 */
+-              i = 0;
+-              while (buck12_voltage_map_desc.min +
+-                     buck12_voltage_map_desc.step*i
+-                     < pdata->buck1_voltage2)
+-                      i++;
+-
+-              max8998->buck1_vol[1] = i;
+-              ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE2, i);
+-              if (ret)
+-                      goto err_out;
+-
+-              /* Set predefined value for BUCK1 register 3 */
+-              i = 0;
+-              while (buck12_voltage_map_desc.min +
+-                     buck12_voltage_map_desc.step*i
+-                     < pdata->buck1_voltage3)
+-                      i++;
+-
+-              max8998->buck1_vol[2] = i;
+-              ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE3, i);
+-              if (ret)
+-                      goto err_out;
+-
+-              /* Set predefined value for BUCK1 register 4 */
+-              i = 0;
+-              while (buck12_voltage_map_desc.min +
+-                     buck12_voltage_map_desc.step*i
+-                     < pdata->buck1_voltage4)
+-                      i++;
+-
+-              max8998->buck1_vol[3] = i;
+-              ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE4, i);
+-              if (ret)
+-                      goto err_out;
++              /* Set predefined values for BUCK1 registers */
++              for (v = 0; v < ARRAY_SIZE(pdata->buck1_voltage); ++v) {
++                      i = 0;
++                      while (buck12_voltage_map_desc.min +
++                             buck12_voltage_map_desc.step*i
++                             < pdata->buck1_voltage[v])
++                              i++;
++
++                      max8998->buck1_vol[v] = i;
++                      ret = max8998_write_reg(i2c,
++                                      MAX8998_REG_BUCK1_VOLTAGE1 + v, i);
++                      if (ret)
++                              goto err_out;
++              }
+       }
+       if (gpio_is_valid(pdata->buck2_set3)) {
+@@ -750,27 +719,20 @@ static int max8998_pmic_probe(struct platform_device *pdev)
+               gpio_direction_output(pdata->buck2_set3,
+                                     max8998->buck2_idx & 0x1);
+-              /* BUCK2 register 1 */
+-              i = 0;
+-              while (buck12_voltage_map_desc.min +
+-                     buck12_voltage_map_desc.step*i
+-                     < pdata->buck2_voltage1)
+-                      i++;
+-              max8998->buck2_vol[0] = i;
+-              ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE1, i);
+-              if (ret)
+-                      goto err_out;
+-
+-              /* BUCK2 register 2 */
+-              i = 0;
+-              while (buck12_voltage_map_desc.min +
+-                     buck12_voltage_map_desc.step*i
+-                     < pdata->buck2_voltage2)
+-                      i++;
+-              max8998->buck2_vol[1] = i;
+-              ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE2, i);
+-              if (ret)
+-                      goto err_out;
++              /* Set predefined values for BUCK2 registers */
++              for (v = 0; v < ARRAY_SIZE(pdata->buck2_voltage); ++v) {
++                      i = 0;
++                      while (buck12_voltage_map_desc.min +
++                             buck12_voltage_map_desc.step*i
++                             < pdata->buck2_voltage[v])
++                              i++;
++
++                      max8998->buck2_vol[v] = i;
++                      ret = max8998_write_reg(i2c,
++                                      MAX8998_REG_BUCK2_VOLTAGE1 + v, i);
++                      if (ret)
++                              goto err_out;
++              }
+       }
+       for (i = 0; i < pdata->num_regulators; i++) {
+diff --git a/include/linux/mfd/max8998.h b/include/linux/mfd/max8998.h
+index 7547118..ca56bb0 100644
+--- a/include/linux/mfd/max8998.h
++++ b/include/linux/mfd/max8998.h
+@@ -73,12 +73,8 @@ struct max8998_regulator_data {
+  * @buck_voltage_lock: Do NOT change the values of the following six
+  *   registers set by buck?_voltage?. The voltage of BUCK1/2 cannot
+  *   be other than the preset values.
+- * @buck1_voltage1: BUCK1 DVS mode 1 voltage register
+- * @buck1_voltage2: BUCK1 DVS mode 2 voltage register
+- * @buck1_voltage3: BUCK1 DVS mode 3 voltage register
+- * @buck1_voltage4: BUCK1 DVS mode 4 voltage register
+- * @buck2_voltage1: BUCK2 DVS mode 1 voltage register
+- * @buck2_voltage2: BUCK2 DVS mode 2 voltage register
++ * @buck1_voltage: BUCK1 DVS mode 1 voltage registers
++ * @buck2_voltage: BUCK2 DVS mode 2 voltage registers
+  * @buck1_set1: BUCK1 gpio pin 1 to set output voltage
+  * @buck1_set2: BUCK1 gpio pin 2 to set output voltage
+  * @buck1_default_idx: Default for BUCK1 gpio pin 1, 2
+@@ -103,12 +99,8 @@ struct max8998_platform_data {
+       unsigned int                    irq_base;
+       int                             ono;
+       bool                            buck_voltage_lock;
+-      int                             buck1_voltage1;
+-      int                             buck1_voltage2;
+-      int                             buck1_voltage3;
+-      int                             buck1_voltage4;
+-      int                             buck2_voltage1;
+-      int                             buck2_voltage2;
++      int                             buck1_voltage[4];
++      int                             buck2_voltage[2];
+       int                             buck1_set1;
+       int                             buck1_set2;
+       int                             buck1_default_idx;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0562-mfd-max8998-Add-support-for-Device-Tree.patch b/patches.tizen/0562-mfd-max8998-Add-support-for-Device-Tree.patch
new file mode 100644 (file)
index 0000000..3ee096e
--- /dev/null
@@ -0,0 +1,501 @@
+From 47838977ef505228a8a1152184af7ae29f4dbc5b Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Tue, 25 Jun 2013 16:08:10 +0200
+Subject: [PATCH 0562/1302] mfd: max8998: Add support for Device Tree
+
+This patch adds Device Tree support to max8998 driver.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Acked-by: Mark Brown <broonie@linaro.org>
+Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/devicetree/bindings/mfd/max8998.txt | 119 ++++++++++++++++++++
+ drivers/mfd/max8998.c                             |  67 ++++++++++-
+ drivers/regulator/max8998.c                       | 131 +++++++++++++++++++++-
+ drivers/rtc/rtc-max8998.c                         |   2 +-
+ include/linux/mfd/max8998-private.h               |   2 +
+ include/linux/mfd/max8998.h                       |   2 +
+ 6 files changed, 316 insertions(+), 7 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/mfd/max8998.txt
+
+diff --git a/Documentation/devicetree/bindings/mfd/max8998.txt b/Documentation/devicetree/bindings/mfd/max8998.txt
+new file mode 100644
+index 0000000..23a3650
+--- /dev/null
++++ b/Documentation/devicetree/bindings/mfd/max8998.txt
+@@ -0,0 +1,119 @@
++* Maxim MAX8998, National/TI LP3974 multi-function device
++
++The Maxim MAX8998 is a multi-function device which includes voltage/current
++regulators, real time clock, battery charging controller and several
++other sub-blocks. It is interfaced using an I2C interface. Each sub-block
++is addressed by the host system using different i2c slave address.
++
++PMIC sub-block
++--------------
++
++The PMIC sub-block contains a number of voltage and current regulators,
++with controllable parameters and dynamic voltage scaling capability.
++In addition, it includes a real time clock and battery charging controller
++as well. It is accessible at I2C address 0x66.
++
++Required properties:
++- compatible: Should be one of the following:
++    - "maxim,max8998" for Maxim MAX8998
++    - "national,lp3974" or "ti,lp3974" for National/TI LP3974.
++- reg: Specifies the i2c slave address of the pmic block. It should be 0x66.
++
++Optional properties:
++- interrupt-parent: Specifies the phandle of the interrupt controller to which
++  the interrupts from MAX8998 are routed to.
++- interrupts: Interrupt specifiers for two interrupt sources.
++  - First interrupt specifier is for main interrupt.
++  - Second interrupt specifier is for power-on/-off interrupt.
++- max8998,pmic-buck1-dvs-gpios: GPIO specifiers for two host gpios used
++  for buck 1 dvs. The format of the gpio specifier depends on the gpio
++  controller.
++- max8998,pmic-buck2-dvs-gpio: GPIO specifier for host gpio used
++  for buck 2 dvs. The format of the gpio specifier depends on the gpio
++  controller.
++- max8998,pmic-buck1-default-dvs-idx: Default voltage setting selected from
++  the possible 4 options selectable by the dvs gpios. The value of this
++  property should be 0, 1, 2 or 3. If not specified or out of range,
++  a default value of 0 is taken.
++- max8998,pmic-buck2-default-dvs-idx: Default voltage setting selected from
++  the possible 2 options selectable by the dvs gpios. The value of this
++  property should be 0 or 1. If not specified or out of range, a default
++  value of 0 is taken.
++- max8998,pmic-buck-voltage-lock: If present, disallows changing of
++  preprogrammed buck dvfs voltages.
++
++Additional properties required if max8998,pmic-buck1-dvs-gpios is defined:
++- max8998,pmic-buck1-dvs-voltage: An array of 4 voltage values in microvolts
++  for buck1 regulator that can be selected using dvs gpio.
++
++Additional properties required if max8998,pmic-buck2-dvs-gpio is defined:
++- max8998,pmic-buck2-dvs-voltage: An array of 2 voltage values in microvolts
++  for buck2 regulator that can be selected using dvs gpio.
++
++Regulators: All the regulators of MAX8998 to be instantiated shall be
++listed in a child node named 'regulators'. Each regulator is represented
++by a child node of the 'regulators' node.
++
++      regulator-name {
++              /* standard regulator bindings here */
++      };
++
++Following regulators of the MAX8998 PMIC block are supported. Note that
++the 'n' in regulator name, as in LDOn or BUCKn, represents the LDO or BUCK
++number as described in MAX8998 datasheet.
++
++      - LDOn
++                - valid values for n are 2 to 17
++                - Example: LDO2, LDO10, LDO17
++      - BUCKn
++                - valid values for n are 1 to 4.
++                - Example: BUCK1, BUCK2, BUCK3, BUCK4
++
++      - ENVICHG: Battery Charging Current Monitor Output. This is a fixed
++                 voltage type regulator
++
++      - ESAFEOUT1: (ldo19)
++      - ESAFEOUT2: (ld020)
++
++Standard regulator bindings are used inside regulator subnodes. Check
++  Documentation/devicetree/bindings/regulator/regulator.txt
++for more details.
++
++Example:
++
++      pmic@66 {
++              compatible = "maxim,max8998-pmic";
++              reg = <0x66>;
++              interrupt-parent = <&wakeup_eint>;
++              interrupts = <4 0>, <3 0>;
++
++              /* Buck 1 DVS settings */
++              max8998,pmic-buck1-default-dvs-idx = <0>;
++              max8998,pmic-buck1-dvs-gpios = <&gpx0 0 1 0 0>, /* SET1 */
++                                             <&gpx0 1 1 0 0>; /* SET2 */
++              max8998,pmic-buck1-dvs-voltage = <1350000>, <1300000>,
++                                               <1000000>, <950000>;
++
++              /* Buck 2 DVS settings */
++              max8998,pmic-buck2-default-dvs-idx = <0>;
++              max8998,pmic-buck2-dvs-gpio = <&gpx0 0 3 0 0>; /* SET3 */
++              max8998,pmic-buck2-dvs-voltage = <1350000>, <1300000>;
++
++              /* Regulators to instantiate */
++              regulators {
++                      ldo2_reg: LDO2 {
++                              regulator-name = "VDD_ALIVE_1.1V";
++                              regulator-min-microvolt = <1100000>;
++                              regulator-max-microvolt = <1100000>;
++                              regulator-always-on;
++                      };
++
++                      buck1_reg: BUCK1 {
++                              regulator-name = "VDD_ARM_1.2V";
++                              regulator-min-microvolt = <950000>;
++                              regulator-max-microvolt = <1350000>;
++                              regulator-always-on;
++                              regulator-boot-on;
++                      };
++              };
++      };
+diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c
+index d7218cc..21af51a 100644
+--- a/drivers/mfd/max8998.c
++++ b/drivers/mfd/max8998.c
+@@ -20,12 +20,15 @@
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+  */
++#include <linux/err.h>
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
+ #include <linux/init.h>
+ #include <linux/slab.h>
+ #include <linux/i2c.h>
+ #include <linux/interrupt.h>
++#include <linux/of.h>
++#include <linux/of_irq.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/mutex.h>
+ #include <linux/mfd/core.h>
+@@ -128,6 +131,56 @@ int max8998_update_reg(struct i2c_client *i2c, u8 reg, u8 val, u8 mask)
+ }
+ EXPORT_SYMBOL(max8998_update_reg);
++#ifdef CONFIG_OF
++static struct of_device_id max8998_dt_match[] = {
++      { .compatible = "maxim,max8998", .data = (void *)TYPE_MAX8998 },
++      { .compatible = "national,lp3974", .data = (void *)TYPE_LP3974 },
++      { .compatible = "ti,lp3974", .data = (void *)TYPE_LP3974 },
++      {},
++};
++MODULE_DEVICE_TABLE(of, max8998_dt_match);
++#endif
++
++/*
++ * Only the common platform data elements for max8998 are parsed here from the
++ * device tree. Other sub-modules of max8998 such as pmic, rtc and others have
++ * to parse their own platform data elements from device tree.
++ *
++ * The max8998 platform data structure is instantiated here and the drivers for
++ * the sub-modules need not instantiate another instance while parsing their
++ * platform data.
++ */
++static struct max8998_platform_data *max8998_i2c_parse_dt_pdata(
++                                                      struct device *dev)
++{
++      struct max8998_platform_data *pd;
++
++      pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
++      if (!pd)
++              return ERR_PTR(-ENOMEM);
++
++      pd->ono = irq_of_parse_and_map(dev->of_node, 1);
++
++      /*
++       * ToDo: the 'wakeup' member in the platform data is more of a linux
++       * specfic information. Hence, there is no binding for that yet and
++       * not parsed here.
++       */
++      return pd;
++}
++
++static inline int max8998_i2c_get_driver_data(struct i2c_client *i2c,
++                                              const struct i2c_device_id *id)
++{
++      if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node) {
++              const struct of_device_id *match;
++              match = of_match_node(max8998_dt_match, i2c->dev.of_node);
++              return (int)match->data;
++      }
++
++      return (int)id->driver_data;
++}
++
+ static int max8998_i2c_probe(struct i2c_client *i2c,
+                           const struct i2c_device_id *id)
+ {
+@@ -139,11 +192,20 @@ static int max8998_i2c_probe(struct i2c_client *i2c,
+       if (max8998 == NULL)
+               return -ENOMEM;
++      if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node) {
++              pdata = max8998_i2c_parse_dt_pdata(&i2c->dev);
++              if (IS_ERR(pdata)) {
++                      ret = PTR_ERR(pdata);
++                      goto err;
++              }
++      }
++
+       i2c_set_clientdata(i2c, max8998);
+       max8998->dev = &i2c->dev;
+       max8998->i2c = i2c;
+       max8998->irq = i2c->irq;
+-      max8998->type = id->driver_data;
++      max8998->type = max8998_i2c_get_driver_data(i2c, id);
++      max8998->pdata = pdata;
+       if (pdata) {
+               max8998->ono = pdata->ono;
+               max8998->irq_base = pdata->irq_base;
+@@ -158,7 +220,7 @@ static int max8998_i2c_probe(struct i2c_client *i2c,
+       pm_runtime_set_active(max8998->dev);
+-      switch (id->driver_data) {
++      switch (max8998->type) {
+       case TYPE_LP3974:
+               ret = mfd_add_devices(max8998->dev, -1,
+                                     lp3974_devs, ARRAY_SIZE(lp3974_devs),
+@@ -314,6 +376,7 @@ static struct i2c_driver max8998_i2c_driver = {
+                  .name = "max8998",
+                  .owner = THIS_MODULE,
+                  .pm = &max8998_pm,
++                 .of_match_table = of_match_ptr(max8998_dt_match),
+       },
+       .probe = max8998_i2c_probe,
+       .remove = max8998_i2c_remove,
+diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c
+index 8c45b93..a4c53b2 100644
+--- a/drivers/regulator/max8998.c
++++ b/drivers/regulator/max8998.c
+@@ -28,8 +28,11 @@
+ #include <linux/slab.h>
+ #include <linux/interrupt.h>
+ #include <linux/mutex.h>
++#include <linux/of.h>
++#include <linux/of_gpio.h>
+ #include <linux/platform_device.h>
+ #include <linux/regulator/driver.h>
++#include <linux/regulator/of_regulator.h>
+ #include <linux/mfd/max8998.h>
+ #include <linux/mfd/max8998-private.h>
+@@ -589,13 +592,13 @@ static struct regulator_desc regulators[] = {
+               .type           = REGULATOR_VOLTAGE,
+               .owner          = THIS_MODULE,
+       }, {
+-              .name           = "EN32KHz AP",
++              .name           = "EN32KHz-AP",
+               .id             = MAX8998_EN32KHZ_AP,
+               .ops            = &max8998_others_ops,
+               .type           = REGULATOR_VOLTAGE,
+               .owner          = THIS_MODULE,
+       }, {
+-              .name           = "EN32KHz CP",
++              .name           = "EN32KHz-CP",
+               .id             = MAX8998_EN32KHZ_CP,
+               .ops            = &max8998_others_ops,
+               .type           = REGULATOR_VOLTAGE,
+@@ -621,10 +624,122 @@ static struct regulator_desc regulators[] = {
+       }
+ };
++static int max8998_pmic_dt_parse_dvs_gpio(struct max8998_dev *iodev,
++                      struct max8998_platform_data *pdata,
++                      struct device_node *pmic_np)
++{
++      int gpio;
++
++      gpio = of_get_named_gpio(pmic_np, "max8998,pmic-buck1-dvs-gpios", 0);
++      if (!gpio_is_valid(gpio)) {
++              dev_err(iodev->dev, "invalid buck1 gpio[0]: %d\n", gpio);
++              return -EINVAL;
++      }
++      pdata->buck1_set1 = gpio;
++
++      gpio = of_get_named_gpio(pmic_np, "max8998,pmic-buck1-dvs-gpios", 1);
++      if (!gpio_is_valid(gpio)) {
++              dev_err(iodev->dev, "invalid buck1 gpio[1]: %d\n", gpio);
++              return -EINVAL;
++      }
++      pdata->buck1_set2 = gpio;
++
++      gpio = of_get_named_gpio(pmic_np, "max8998,pmic-buck2-dvs-gpio", 0);
++      if (!gpio_is_valid(gpio)) {
++              dev_err(iodev->dev, "invalid buck 2 gpio: %d\n", gpio);
++              return -EINVAL;
++      }
++      pdata->buck2_set3 = gpio;
++
++      return 0;
++}
++
++static int max8998_pmic_dt_parse_pdata(struct max8998_dev *iodev,
++                                      struct max8998_platform_data *pdata)
++{
++      struct device_node *pmic_np = iodev->dev->of_node;
++      struct device_node *regulators_np, *reg_np;
++      struct max8998_regulator_data *rdata;
++      unsigned int i;
++      int ret;
++
++      regulators_np = of_get_child_by_name(pmic_np, "regulators");
++      if (!regulators_np) {
++              dev_err(iodev->dev, "could not find regulators sub-node\n");
++              return -EINVAL;
++      }
++
++      /* count the number of regulators to be supported in pmic */
++      pdata->num_regulators = of_get_child_count(regulators_np);
++
++      rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) *
++                              pdata->num_regulators, GFP_KERNEL);
++      if (!rdata)
++              return -ENOMEM;
++
++      pdata->regulators = rdata;
++      for (i = 0; i < ARRAY_SIZE(regulators); ++i) {
++              reg_np = of_get_child_by_name(regulators_np,
++                                                      regulators[i].name);
++              if (!reg_np)
++                      continue;
++
++              rdata->id = regulators[i].id;
++              rdata->initdata = of_get_regulator_init_data(
++                                                      iodev->dev, reg_np);
++              rdata->reg_node = reg_np;
++              ++rdata;
++      }
++      pdata->num_regulators = rdata - pdata->regulators;
++
++      ret = max8998_pmic_dt_parse_dvs_gpio(iodev, pdata, pmic_np);
++      if (ret)
++              return -EINVAL;
++
++      if (of_find_property(pmic_np, "max8998,pmic-buck-voltage-lock", NULL))
++              pdata->buck_voltage_lock = true;
++
++      ret = of_property_read_u32(pmic_np,
++                                      "max8998,pmic-buck1-default-dvs-idx",
++                                      &pdata->buck1_default_idx);
++      if (!ret && pdata->buck1_default_idx >= 4) {
++              pdata->buck1_default_idx = 0;
++              dev_warn(iodev->dev, "invalid value for default dvs index, using 0 instead\n");
++      }
++
++      ret = of_property_read_u32(pmic_np,
++                                      "max8998,pmic-buck2-default-dvs-idx",
++                                      &pdata->buck2_default_idx);
++      if (!ret && pdata->buck2_default_idx >= 2) {
++              pdata->buck2_default_idx = 0;
++              dev_warn(iodev->dev, "invalid value for default dvs index, using 0 instead\n");
++      }
++
++      ret = of_property_read_u32_array(pmic_np,
++                                      "max8998,pmic-buck1-dvs-voltage",
++                                      pdata->buck1_voltage,
++                                      ARRAY_SIZE(pdata->buck1_voltage));
++      if (ret) {
++              dev_err(iodev->dev, "buck1 voltages not specified\n");
++              return -EINVAL;
++      }
++
++      ret = of_property_read_u32_array(pmic_np,
++                                      "max8998,pmic-buck2-dvs-voltage",
++                                      pdata->buck2_voltage,
++                                      ARRAY_SIZE(pdata->buck2_voltage));
++      if (ret) {
++              dev_err(iodev->dev, "buck2 voltages not specified\n");
++              return -EINVAL;
++      }
++
++      return 0;
++}
++
+ static int max8998_pmic_probe(struct platform_device *pdev)
+ {
+       struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent);
+-      struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev);
++      struct max8998_platform_data *pdata = iodev->pdata;
+       struct regulator_config config = { };
+       struct regulator_dev **rdev;
+       struct max8998_data *max8998;
+@@ -637,6 +752,12 @@ static int max8998_pmic_probe(struct platform_device *pdev)
+               return -ENODEV;
+       }
++      if (IS_ENABLED(CONFIG_OF) && iodev->dev->of_node) {
++              ret = max8998_pmic_dt_parse_pdata(iodev, pdata);
++              if (ret)
++                      return ret;
++      }
++
+       max8998 = devm_kzalloc(&pdev->dev, sizeof(struct max8998_data),
+                              GFP_KERNEL);
+       if (!max8998)
+@@ -750,13 +871,15 @@ static int max8998_pmic_probe(struct platform_device *pdev)
+               }
+               config.dev = max8998->dev;
++              config.of_node = pdata->regulators[i].reg_node;
+               config.init_data = pdata->regulators[i].initdata;
+               config.driver_data = max8998;
+               rdev[i] = regulator_register(&regulators[index], &config);
+               if (IS_ERR(rdev[i])) {
+                       ret = PTR_ERR(rdev[i]);
+-                      dev_err(max8998->dev, "regulator init failed\n");
++                      dev_err(max8998->dev, "regulator %s init failed (%d)\n",
++                                              regulators[index].name, ret);
+                       rdev[i] = NULL;
+                       goto err;
+               }
+diff --git a/drivers/rtc/rtc-max8998.c b/drivers/rtc/rtc-max8998.c
+index 46f2301..042a873 100644
+--- a/drivers/rtc/rtc-max8998.c
++++ b/drivers/rtc/rtc-max8998.c
+@@ -253,7 +253,7 @@ static const struct rtc_class_ops max8998_rtc_ops = {
+ static int max8998_rtc_probe(struct platform_device *pdev)
+ {
+       struct max8998_dev *max8998 = dev_get_drvdata(pdev->dev.parent);
+-      struct max8998_platform_data *pdata = dev_get_platdata(max8998->dev);
++      struct max8998_platform_data *pdata = max8998->pdata;
+       struct max8998_rtc_info *info;
+       int ret;
+diff --git a/include/linux/mfd/max8998-private.h b/include/linux/mfd/max8998-private.h
+index bfb48b6..84844e0 100644
+--- a/include/linux/mfd/max8998-private.h
++++ b/include/linux/mfd/max8998-private.h
+@@ -137,6 +137,7 @@ struct irq_domain;
+ /**
+  * struct max8998_dev - max8998 master device for sub-drivers
+  * @dev: master device of the chip (can be used to access platform data)
++ * @pdata: platform data for the driver and subdrivers
+  * @i2c: i2c client private data for regulator
+  * @rtc: i2c client private data for rtc
+  * @iolock: mutex for serializing io access
+@@ -150,6 +151,7 @@ struct irq_domain;
+  */
+ struct max8998_dev {
+       struct device *dev;
++      struct max8998_platform_data *pdata;
+       struct i2c_client *i2c;
+       struct i2c_client *rtc;
+       struct mutex iolock;
+diff --git a/include/linux/mfd/max8998.h b/include/linux/mfd/max8998.h
+index ca56bb0..e3956a6 100644
+--- a/include/linux/mfd/max8998.h
++++ b/include/linux/mfd/max8998.h
+@@ -58,10 +58,12 @@ enum {
+  * max8998_regulator_data - regulator data
+  * @id: regulator id
+  * @initdata: regulator init data (contraints, supplies, ...)
++ * @reg_node: DT node of regulator (unused on non-DT platforms)
+  */
+ struct max8998_regulator_data {
+       int                             id;
+       struct regulator_init_data      *initdata;
++      struct device_node              *reg_node;
+ };
+ /**
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0563-dts-universal-c210-board.patch b/patches.tizen/0563-dts-universal-c210-board.patch
new file mode 100644 (file)
index 0000000..4720a3e
--- /dev/null
@@ -0,0 +1,263 @@
+From 475119f26d5fc6d987acba52d0a64034f18202dc Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Tue, 20 Aug 2013 11:12:27 +0200
+Subject: [PATCH 0563/1302] dts: universal c210 board
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-pinctrl.dtsi       | 96 +++++++++++++++++++++++++
+ arch/arm/boot/dts/exynos4210-universal_c210.dts | 93 ++++++++++++++++++++++++
+ 2 files changed, 189 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
+index 00a1221..82ba2f5 100644
+--- a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
++++ b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
+@@ -330,6 +330,102 @@
+                       samsung,pin-pud = <3>;
+                       samsung,pin-drv = <0>;
+               };
++
++              pwm0_out: pwm0-out {
++                      samsung,pins = "gpd0-0";
++                      samsung,pin-function = <2>;
++                      samsung,pin-pud = <0>;
++                      samsung,pin-drv = <0>;
++              };
++
++              pwm1_out: pwm1-out {
++                      samsung,pins = "gpd0-1";
++                      samsung,pin-function = <2>;
++                      samsung,pin-pud = <0>;
++                      samsung,pin-drv = <0>;
++              };
++
++              pwm2_out: pwm2-out {
++                      samsung,pins = "gpd0-2";
++                      samsung,pin-function = <2>;
++                      samsung,pin-pud = <0>;
++                      samsung,pin-drv = <0>;
++              };
++
++              pwm3_out: pwm3-out {
++                      samsung,pins = "gpd0-3";
++                      samsung,pin-function = <2>;
++                      samsung,pin-pud = <0>;
++                      samsung,pin-drv = <0>;
++              };
++
++              lcd_ctrl: lcd-ctrl {
++                      samsung,pins = "gpd0-0", "gpd0-1";
++                      samsung,pin-function = <3>;
++                      samsung,pin-pud = <0>;
++                      samsung,pin-drv = <0>;
++              };
++
++              lcd_sync: lcd-sync {
++                      samsung,pins = "gpf0-0", "gpf0-1";
++                      samsung,pin-function = <2>;
++                      samsung,pin-pud = <0>;
++                      samsung,pin-drv = <0>;
++              };
++
++              lcd_en: lcd-en {
++                      samsung,pins = "gpe3-4";
++                      samsung,pin-function = <2>;
++                      samsung,pin-pud = <0>;
++                      samsung,pin-drv = <0>;
++              };
++
++              lcd_clk: lcd-clk {
++                      samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3";
++                      samsung,pin-function = <2>;
++                      samsung,pin-pud = <0>;
++                      samsung,pin-drv = <0>;
++              };
++
++              lcd_data16: lcd-data-width16 {
++                      samsung,pins = "gpf0-7", "gpf1-0", "gpf1-1", "gpf1-2",
++                                      "gpf1-3", "gpf1-6", "gpf1-7", "gpf2-0",
++                                      "gpf2-1", "gpf2-2", "gpf2-3", "gpf2-7",
++                                      "gpf3-0", "gpf3-1", "gpf3-2", "gpf3-3";
++                      samsung,pin-function = <2>;
++                      samsung,pin-pud = <0>;
++                      samsung,pin-drv = <0>;
++              };
++
++              lcd_data18: lcd-data-width18 {
++                      samsung,pins = "gpf0-6", "gpf0-7", "gpf1-0", "gpf1-1",
++                                      "gpf1-2", "gpf1-3", "gpf1-6", "gpf1-7",
++                                      "gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3",
++                                      "gpf2-6", "gpf2-7", "gpf3-0", "gpf3-1",
++                                      "gpf3-2", "gpf3-3";
++                      samsung,pin-function = <2>;
++                      samsung,pin-pud = <0>;
++                      samsung,pin-drv = <0>;
++              };
++
++              lcd_data24: lcd-data-width24 {
++                      samsung,pins = "gpf0-4", "gpf0-5", "gpf0-6", "gpf0-7",
++                                      "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3",
++                                      "gpf1-4", "gpf1-5", "gpf1-6", "gpf1-7",
++                                      "gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3",
++                                      "gpf2-4", "gpf2-5", "gpf2-6", "gpf2-7",
++                                      "gpf3-0", "gpf3-1", "gpf3-2", "gpf3-3";
++                      samsung,pin-function = <2>;
++                      samsung,pin-pud = <0>;
++                      samsung,pin-drv = <0>;
++              };
++
++              lcd_ldi: lcd-ldi {
++                      samsung,pins = "gpf3-4";
++                      samsung,pin-function = <2>;
++                      samsung,pin-pud = <0>;
++                      samsung,pin-drv = <0>;
++              };
+       };
+       pinctrl@11000000 {
+diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts
+index 345cdb5..2c91861 100644
+--- a/arch/arm/boot/dts/exynos4210-universal_c210.dts
++++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts
+@@ -22,6 +22,27 @@
+       memory {
+               reg =  <0x40000000 0x10000000
+                       0x50000000 0x10000000>;
++
++              reserved-memory {
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      contig_mem: region@0 {
++                              compatible = "linux,contiguous-memory-region";
++                              reg = <0x0 0x4000000>;
++                              linux,default-contiguous-region;
++                      };
++
++                      mfc_l_mem: mfc_l_region@43000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x43000000 0x1000000>;
++                      };
++
++                      mfc_r_mem: mfc_r_region@51000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x51000000 0x1000000>;
++                      };
++              };
+       };
+       chosen {
+@@ -53,6 +74,12 @@
+               enable-active-high;
+       };
++      hsotg@12480000 {
++              vusb_d-supply = <&ldo3_reg>;
++              vusb_a-supply = <&ldo8_reg>;
++              status = "okay";
++      };
++
+       sdhci_emmc: sdhci@12510000 {
+               bus-width = <8>;
+               non-removable;
+@@ -62,6 +89,10 @@
+               status = "okay";
+       };
++      usbphy@125B0000 {
++              status = "okay";
++      };
++
+       serial@13800000 {
+               status = "okay";
+       };
+@@ -225,6 +256,7 @@
+                                       regulator-name = "VLCD+VMIPI_1.8V";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
+                               };
+                               ldo8_reg: LDO8 {
+@@ -288,6 +320,7 @@
+                                       regulator-name = "VCC_3.0V_LCD";
+                                       regulator-min-microvolt = <3000000>;
+                                       regulator-max-microvolt = <3000000>;
++                                      regulator-always-on;
+                               };
+                               buck1_reg: BUCK1 {
+@@ -345,8 +378,68 @@
+               };
+       };
++      fimd: fimd@11c00000 {
++              pinctrl-names = "default";
++              pinctrl-0 = <&lcd_clk>, <&lcd_data24>;
++              status = "okay";
++
++              display-timings {
++                      native-mode = <&timing0>;
++                      timing0: timing {
++                              clock-frequency = <24000000>;
++                              hactive = <480>;
++                              vactive = <800>;
++                              hfront-porch = <16>;
++                              hback-porch = <16>;
++                              hsync-len = <2>;
++                              vback-porch = <2>;
++                              vfront-porch = <28>;
++                              vsync-len = <1>;
++                              vsync-active = <0>;
++                              hsync-active = <0>;
++                              de-active = <0>;
++                              pixelclk-active = <0>;
++                      };
++              };
++      };
++
+       pwm@139D0000 {
+               compatible = "samsung,s5p6440-pwm";
+               status = "okay";
+       };
++
++      camera {
++              status = "okay";
++
++              pinctrl-names = "default";
++              pinctrl-0 = <&cam_port_a_clk_off>;
++
++              fimc_0: fimc@11800000 {
++                      status = "okay";
++              };
++
++              fimc_1: fimc@11810000 {
++                      status = "okay";
++              };
++
++              fimc_2: fimc@11820000 {
++                      status = "okay";
++              };
++
++              fimc_3: fimc@11830000 {
++                      status = "okay";
++              };
++      };
++
++      codec@13400000 {
++              status = "okay";
++
++              memport@0 {
++                      memory-region = <&mfc_l_mem>;
++              };
++
++              memport@1 {
++                      memory-region = <&mfc_r_mem>;
++              };
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0564-drm-exynos-fimd-disable-windows-before-registering-d.patch b/patches.tizen/0564-drm-exynos-fimd-disable-windows-before-registering-d.patch
new file mode 100644 (file)
index 0000000..b5b89f4
--- /dev/null
@@ -0,0 +1,36 @@
+From 6402dc41098e3f8482f76d961f63b33cc28a6063 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Thu, 8 Aug 2013 11:24:33 +0200
+Subject: [PATCH 0564/1302] drm/exynos: fimd: disable windows before
+ registering driver
+
+Bootloader might enable some windows, so ensure that all windows are
+disabled before registering to the system. This solves IOMMU fault during
+registration if bootloader enabled some FIMD windows.
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_fimd.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+index 8aec342..ec060cb 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+@@ -1021,8 +1021,11 @@ static int fimd_probe(struct platform_device *pdev)
+       DRM_DEBUG_KMS("pixel clock = %d, clkdiv = %d\n",
+                       panel->timing.pixclock, ctx->clkdiv);
+-      for (win = 0; win < WINDOWS_NR; win++)
++      for (win = 0; win < WINDOWS_NR; win++) {
+               fimd_clear_win(ctx, win);
++              fimd_win_disable(dev, win);
++      }
++      fimd_wait_for_vblank(dev);
+       exynos_drm_subdrv_register(subdrv);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0565-drm-exynos-simplify-and-unify-subdrivers-registratio.patch b/patches.tizen/0565-drm-exynos-simplify-and-unify-subdrivers-registratio.patch
new file mode 100644 (file)
index 0000000..20d56d2
--- /dev/null
@@ -0,0 +1,232 @@
+From 9cfb7fe6bc6b2e4f33936f7e8c127bff703e03b6 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Tue, 20 Aug 2013 15:30:29 +0200
+Subject: [PATCH 0565/1302] drm/exynos: simplify and unify subdrivers
+ registration
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_drv.c | 157 ++++++++------------------------
+ 1 file changed, 37 insertions(+), 120 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
+index d5da1ea..c659fc3 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
+@@ -300,75 +300,58 @@ static struct platform_driver exynos_drm_platform_driver = {
+       },
+ };
+-static int __init exynos_drm_init(void)
+-{
+-      int ret;
++static struct platform_driver *exynos_drm_subdrivers[] = {
+ #ifdef CONFIG_DRM_EXYNOS_FIMD
+-      ret = platform_driver_register(&fimd_driver);
+-      if (ret < 0)
+-              goto out_fimd;
++      &fimd_driver,
+ #endif
+-
+ #ifdef CONFIG_DRM_EXYNOS_HDMI
+-      ret = platform_driver_register(&hdmi_driver);
+-      if (ret < 0)
+-              goto out_hdmi;
+-      ret = platform_driver_register(&mixer_driver);
+-      if (ret < 0)
+-              goto out_mixer;
+-      ret = platform_driver_register(&exynos_drm_common_hdmi_driver);
+-      if (ret < 0)
+-              goto out_common_hdmi;
+-
+-      ret = exynos_platform_device_hdmi_register();
+-      if (ret < 0)
+-              goto out_common_hdmi_dev;
++      &hdmi_driver,
++      &mixer_driver,
++      &exynos_drm_common_hdmi_driver,
+ #endif
+-
+ #ifdef CONFIG_DRM_EXYNOS_VIDI
+-      ret = platform_driver_register(&vidi_driver);
+-      if (ret < 0)
+-              goto out_vidi;
++      &vidi_driver,
+ #endif
+-
+ #ifdef CONFIG_DRM_EXYNOS_G2D
+-      ret = platform_driver_register(&g2d_driver);
+-      if (ret < 0)
+-              goto out_g2d;
++      &g2d_driver,
+ #endif
+-
+ #ifdef CONFIG_DRM_EXYNOS_FIMC
+-      ret = platform_driver_register(&fimc_driver);
+-      if (ret < 0)
+-              goto out_fimc;
++      &fimc_driver,
+ #endif
+-
+ #ifdef CONFIG_DRM_EXYNOS_ROTATOR
+-      ret = platform_driver_register(&rotator_driver);
+-      if (ret < 0)
+-              goto out_rotator;
++      &rotator_driver,
+ #endif
+-
+ #ifdef CONFIG_DRM_EXYNOS_GSC
+-      ret = platform_driver_register(&gsc_driver);
+-      if (ret < 0)
+-              goto out_gsc;
++      &gsc_driver,
+ #endif
+-
+ #ifdef CONFIG_DRM_EXYNOS_IPP
+-      ret = platform_driver_register(&ipp_driver);
++      &ipp_driver,
++#endif
++      &exynos_drm_platform_driver,
++};
++
++static int __init exynos_drm_init(void)
++{
++      int ret, i = 0;
++
++#ifdef CONFIG_DRM_EXYNOS_HDMI
++      ret = exynos_platform_device_hdmi_register();
+       if (ret < 0)
+-              goto out_ipp;
++              goto out_hdmi;
++#endif
++#ifdef CONFIG_DRM_EXYNOS_IPP
+       ret = exynos_platform_device_ipp_register();
+       if (ret < 0)
+-              goto out_ipp_dev;
++              goto out_ipp;
+ #endif
+-      ret = platform_driver_register(&exynos_drm_platform_driver);
+-      if (ret < 0)
+-              goto out_drm;
++      for (i=0; i < ARRAY_SIZE(exynos_drm_subdrivers); i++) {
++              ret = platform_driver_register(exynos_drm_subdrivers[i]);
++              if (ret < 0)
++                      goto out;
++      }
+       exynos_drm_pdev = platform_device_register_simple("exynos-drm", -1,
+                               NULL, 0);
+@@ -380,99 +363,33 @@ static int __init exynos_drm_init(void)
+       return 0;
+ out:
+-      platform_driver_unregister(&exynos_drm_platform_driver);
++      while (--i > 0)
++              platform_driver_unregister(exynos_drm_subdrivers[i]);
+-out_drm:
+ #ifdef CONFIG_DRM_EXYNOS_IPP
+-      exynos_platform_device_ipp_unregister();
+-out_ipp_dev:
+-      platform_driver_unregister(&ipp_driver);
+ out_ipp:
+-#endif
+-
+-#ifdef CONFIG_DRM_EXYNOS_GSC
+-      platform_driver_unregister(&gsc_driver);
+-out_gsc:
+-#endif
+-
+-#ifdef CONFIG_DRM_EXYNOS_ROTATOR
+-      platform_driver_unregister(&rotator_driver);
+-out_rotator:
+-#endif
+-
+-#ifdef CONFIG_DRM_EXYNOS_FIMC
+-      platform_driver_unregister(&fimc_driver);
+-out_fimc:
+-#endif
+-
+-#ifdef CONFIG_DRM_EXYNOS_G2D
+-      platform_driver_unregister(&g2d_driver);
+-out_g2d:
+-#endif
+-
+-#ifdef CONFIG_DRM_EXYNOS_VIDI
+-      platform_driver_unregister(&vidi_driver);
+-out_vidi:
++      exynos_platform_device_ipp_unregister();
+ #endif
+ #ifdef CONFIG_DRM_EXYNOS_HDMI
+-      exynos_platform_device_hdmi_unregister();
+-out_common_hdmi_dev:
+-      platform_driver_unregister(&exynos_drm_common_hdmi_driver);
+-out_common_hdmi:
+-      platform_driver_unregister(&mixer_driver);
+-out_mixer:
+-      platform_driver_unregister(&hdmi_driver);
+ out_hdmi:
+-#endif
+-
+-#ifdef CONFIG_DRM_EXYNOS_FIMD
+-      platform_driver_unregister(&fimd_driver);
+-out_fimd:
++      exynos_platform_device_hdmi_unregister();
+ #endif
+       return ret;
+ }
+ static void __exit exynos_drm_exit(void)
+ {
++      int i;
++      for (i=0; i < ARRAY_SIZE(exynos_drm_subdrivers); i++)
++              platform_driver_unregister(exynos_drm_subdrivers[i]);
+       platform_device_unregister(exynos_drm_pdev);
+-      platform_driver_unregister(&exynos_drm_platform_driver);
+-
+ #ifdef CONFIG_DRM_EXYNOS_IPP
+       exynos_platform_device_ipp_unregister();
+-      platform_driver_unregister(&ipp_driver);
+-#endif
+-
+-#ifdef CONFIG_DRM_EXYNOS_GSC
+-      platform_driver_unregister(&gsc_driver);
+-#endif
+-
+-#ifdef CONFIG_DRM_EXYNOS_ROTATOR
+-      platform_driver_unregister(&rotator_driver);
+-#endif
+-
+-#ifdef CONFIG_DRM_EXYNOS_FIMC
+-      platform_driver_unregister(&fimc_driver);
+ #endif
+-
+-#ifdef CONFIG_DRM_EXYNOS_G2D
+-      platform_driver_unregister(&g2d_driver);
+-#endif
+-
+ #ifdef CONFIG_DRM_EXYNOS_HDMI
+       exynos_platform_device_hdmi_unregister();
+-      platform_driver_unregister(&exynos_drm_common_hdmi_driver);
+-      platform_driver_unregister(&mixer_driver);
+-      platform_driver_unregister(&hdmi_driver);
+-#endif
+-
+-#ifdef CONFIG_DRM_EXYNOS_VIDI
+-      platform_driver_unregister(&vidi_driver);
+-#endif
+-
+-#ifdef CONFIG_DRM_EXYNOS_FIMD
+-      platform_driver_unregister(&fimd_driver);
+ #endif
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0566-drm-exynos-add-support-for-separate-iommu-mapping-ma.patch b/patches.tizen/0566-drm-exynos-add-support-for-separate-iommu-mapping-ma.patch
new file mode 100644 (file)
index 0000000..9ddec62
--- /dev/null
@@ -0,0 +1,218 @@
+From c635b8277c5315efc24e4f63b5330ad3b40d03f9 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Thu, 8 Aug 2013 11:18:32 +0200
+Subject: [PATCH 0566/1302] drm/exynos: add support for separate iommu mapping
+ management by drm driver
+
+This patch adds support for a single, shared iommu domain (mapping and
+address space) management for all Exynos DRM subdrivers. The registered
+high priority notifier ensures that IOMMU driver will not create default
+domains for all devices which will be handled by Exynos DRM subdrivers.
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/Makefile                |  1 +
+ drivers/gpu/drm/exynos/exynos_drm_drv.c        |  8 +++
+ drivers/gpu/drm/exynos/exynos_drm_iommu.h      | 10 ++--
+ drivers/gpu/drm/exynos/exynos_drm_iommu_init.c | 69 ++++++++++++++++++++++++++
+ drivers/gpu/drm/exynos/exynos_drm_iommu_init.h | 30 +++++++++++
+ 5 files changed, 114 insertions(+), 4 deletions(-)
+ create mode 100644 drivers/gpu/drm/exynos/exynos_drm_iommu_init.c
+ create mode 100644 drivers/gpu/drm/exynos/exynos_drm_iommu_init.h
+
+diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
+index 639b49e..a7c34f5 100644
+--- a/drivers/gpu/drm/exynos/Makefile
++++ b/drivers/gpu/drm/exynos/Makefile
+@@ -9,6 +9,7 @@ exynosdrm-y := exynos_drm_drv.o exynos_drm_encoder.o exynos_drm_connector.o \
+               exynos_drm_plane.o
+ exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o
++exynosdrm-$(CONFIG_ARM_DMA_USE_IOMMU) += exynos_drm_iommu_init.o
+ exynosdrm-$(CONFIG_DRM_EXYNOS_DMABUF) += exynos_drm_dmabuf.o
+ exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD)   += exynos_drm_fimd.o
+ exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI)   += exynos_hdmi.o exynos_mixer.o \
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
+index c659fc3..f727f98 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
+@@ -28,6 +28,7 @@
+ #include "exynos_drm_g2d.h"
+ #include "exynos_drm_ipp.h"
+ #include "exynos_drm_iommu.h"
++#include "exynos_drm_iommu_init.h"
+ #define DRIVER_NAME   "exynos"
+ #define DRIVER_DESC   "Samsung SoC DRM"
+@@ -335,6 +336,11 @@ static int __init exynos_drm_init(void)
+ {
+       int ret, i = 0;
++      ret = exynos_drm_iommu_register(exynos_drm_subdrivers,
++                                      ARRAY_SIZE(exynos_drm_subdrivers));
++      if (ret < 0)
++              return ret;
++
+ #ifdef CONFIG_DRM_EXYNOS_HDMI
+       ret = exynos_platform_device_hdmi_register();
+       if (ret < 0)
+@@ -375,6 +381,7 @@ out_ipp:
+ out_hdmi:
+       exynos_platform_device_hdmi_unregister();
+ #endif
++      exynos_drm_iommu_unregister();
+       return ret;
+ }
+@@ -391,6 +398,7 @@ static void __exit exynos_drm_exit(void)
+ #ifdef CONFIG_DRM_EXYNOS_HDMI
+       exynos_platform_device_hdmi_unregister();
+ #endif
++      exynos_drm_iommu_unregister();
+ }
+ module_init(exynos_drm_init);
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_iommu.h b/drivers/gpu/drm/exynos/exynos_drm_iommu.h
+index 598e60f..9f6a24e 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_iommu.h
++++ b/drivers/gpu/drm/exynos/exynos_drm_iommu.h
+@@ -12,6 +12,8 @@
+ #ifndef _EXYNOS_DRM_IOMMU_H_
+ #define _EXYNOS_DRM_IOMMU_H_
++#include "exynos_drm_iommu_init.h"
++
+ #define EXYNOS_DEV_ADDR_START 0x20000000
+ #define EXYNOS_DEV_ADDR_SIZE  0x40000000
+ #define EXYNOS_DEV_ADDR_ORDER 0x0
+@@ -32,11 +34,11 @@ static inline bool is_drm_iommu_supported(struct drm_device *drm_dev)
+ {
+ #ifdef CONFIG_ARM_DMA_USE_IOMMU
+       struct device *dev = drm_dev->dev;
+-
+-      return dev->archdata.mapping ? true : false;
+-#else
+-      return false;
++      if (dev->archdata.mapping &&
++          dev->archdata.mapping != EXYNOS_DRM_INITIAL_MAPPING_VAL)
++              return true;
+ #endif
++      return false;
+ }
+ #else
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_iommu_init.c b/drivers/gpu/drm/exynos/exynos_drm_iommu_init.c
+new file mode 100644
+index 0000000..3022a0c
+--- /dev/null
++++ b/drivers/gpu/drm/exynos/exynos_drm_iommu_init.c
+@@ -0,0 +1,69 @@
++/* exynos_drm_iommu_init.c
++ *
++ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
++ *
++ * This program is free software; you can redistribute  it and/or modify it
++ * under  the terms of  the GNU General  Public License as published by the
++ * Free Software Foundation;  either version 2 of the  License, or (at your
++ * option) any later version.
++ */
++
++#include <drmP.h>
++#include <drm/exynos_drm.h>
++
++#include <linux/dma-mapping.h>
++#include <linux/iommu.h>
++#include <linux/kref.h>
++
++#include <asm/dma-iommu.h>
++
++#include "exynos_drm_drv.h"
++#include "exynos_drm_iommu_init.h"
++
++static struct platform_driver **exynos_drm_subdrivers;
++static int exynos_drm_subdrivers_count;
++
++static int exynos_iommu_hook_driver(struct notifier_block *nb,
++                                           unsigned long val, void *p)
++{
++      struct device *dev = p;
++      int i;
++
++      switch (val) {
++      case BUS_NOTIFY_BIND_DRIVER:
++              for (i=0; i < exynos_drm_subdrivers_count; i++) {
++                      if (dev->driver == &exynos_drm_subdrivers[i]->driver) {
++                              dev->archdata.mapping = EXYNOS_DRM_INITIAL_MAPPING_VAL;
++                              break;
++                      }
++              }
++              break;
++
++      case BUS_NOTIFY_UNBOUND_DRIVER:
++      case BUS_NOTIFY_BIND_FAILED:
++              for (i=0; i < exynos_drm_subdrivers_count; i++) {
++                      if (dev->driver == &exynos_drm_subdrivers[i]->driver) {
++                              dev->archdata.mapping = NULL;
++                              break;
++                      }
++              }
++      }
++      return 0;
++}
++
++static struct notifier_block exynos_drm_iommu_notifier = {
++      .notifier_call = &exynos_iommu_hook_driver,
++      .priority = 100,
++};
++
++int exynos_drm_iommu_register(struct platform_driver **drivers, int count)
++{
++      exynos_drm_subdrivers = drivers;
++      exynos_drm_subdrivers_count = count;
++      return bus_register_notifier(&platform_bus_type, &exynos_drm_iommu_notifier);
++}
++
++int exynos_drm_iommu_unregister(void)
++{
++      return bus_register_notifier(&platform_bus_type, &exynos_drm_iommu_notifier);
++}
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_iommu_init.h b/drivers/gpu/drm/exynos/exynos_drm_iommu_init.h
+new file mode 100644
+index 0000000..b7a416e
+--- /dev/null
++++ b/drivers/gpu/drm/exynos/exynos_drm_iommu_init.h
+@@ -0,0 +1,30 @@
++/* exynos_drm_iommu_init.h
++ *
++ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
++ *
++ * This program is free software; you can redistribute  it and/or modify it
++ * under  the terms of  the GNU General  Public License as published by the
++ * Free Software Foundation;  either version 2 of the  License, or (at your
++ * option) any later version.
++ */
++
++#ifndef _EXYNOS_DRM_IOMMU_INIT_H_
++#define _EXYNOS_DRM_IOMMU_INIT_H_
++
++#define EXYNOS_DRM_INITIAL_MAPPING_VAL        ERR_PTR(-EAGAIN)
++
++#ifdef CONFIG_ARM_DMA_USE_IOMMU
++int exynos_drm_iommu_register(struct platform_driver **drivers, int count);
++int exynos_drm_iommu_unregister(void);
++#else
++static inline int exynos_drm_iommu_register(struct platform_driver **drivers, int count)
++{
++      return 0;
++}
++static inline int exynos_drm_iommu_unregister(void)
++{
++      return 0;
++}
++#endif
++
++#endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0567-iommu-exynos-remove-support-for-combined-sysmmu-cont.patch b/patches.tizen/0567-iommu-exynos-remove-support-for-combined-sysmmu-cont.patch
new file mode 100644 (file)
index 0000000..19e6996
--- /dev/null
@@ -0,0 +1,361 @@
+From 209fb53701ea19da014853314e8eae1ddcc498b5 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Wed, 7 Aug 2013 09:27:52 +0200
+Subject: [PATCH 0567/1302] iommu/exynos: remove support for combined sysmmu
+ controllers
+
+This patch removes support for combined SYSMMU controllers, which can be
+handled by defining separate device nodes for each controller. This
+significantly simplifies the code.
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iommu/exynos-iommu.c | 193 +++++++++++++++++--------------------------
+ 1 file changed, 74 insertions(+), 119 deletions(-)
+
+diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
+index 6eed6d6..b46c3fe 100644
+--- a/drivers/iommu/exynos-iommu.c
++++ b/drivers/iommu/exynos-iommu.c
+@@ -183,7 +183,6 @@ struct sysmmu_drvdata {
+       struct list_head node; /* entry of exynos_iommu_domain.clients */
+       struct device *sysmmu;  /* System MMU's device descriptor */
+       struct device *master;  /* Owner of system MMU */
+-      int nsfrs;
+       struct clk *clk;
+       struct clk *clk_master;
+       int activations;
+@@ -191,7 +190,7 @@ struct sysmmu_drvdata {
+       struct iommu_domain *domain;
+       bool runtime_active;
+       unsigned long pgtable;
+-      void __iomem *sfrbases[0];
++      void __iomem *sfrbase;
+ };
+ static bool set_sysmmu_active(struct sysmmu_drvdata *data)
+@@ -214,11 +213,11 @@ static bool is_sysmmu_active(struct sysmmu_drvdata *data)
+ }
+ static unsigned int __sysmmu_version(struct sysmmu_drvdata *data,
+-                                   int idx, unsigned int *minor)
++                                   unsigned int *minor)
+ {
+       unsigned long major;
+-      major = readl(data->sfrbases[idx] + REG_MMU_VERSION);
++      major = readl(data->sfrbase + REG_MMU_VERSION);
+       if (minor)
+               *minor = MMU_MIN_VER(major);
+@@ -282,7 +281,6 @@ void exynos_sysmmu_set_prefbuf(struct device *dev,
+ {
+       struct sysmmu_drvdata *data = dev_get_drvdata(dev->archdata.iommu);
+       unsigned long flags;
+-      int i;
+       BUG_ON((base0 + size0) <= base0);
+       BUG_ON((size1 > 0) && ((base1 + size1) <= base1));
+@@ -292,31 +290,31 @@ void exynos_sysmmu_set_prefbuf(struct device *dev,
+               goto finish;
+       clk_enable(data->clk_master);
+-      for (i = 0; i < data->nsfrs; i++) {
+-              if ((readl(data->sfrbases[i] + REG_MMU_VERSION) >> 28) == 3) {
+-                      if (!sysmmu_block(data->sfrbases[i]))
+-                              continue;
+-
+-                      if (size1 == 0) {
+-                              if (size0 <= SZ_128K) {
+-                                      base1 = base0;
+-                                      size1 = size0;
+-                              } else {
+-                                      size1 = size0 -
+-                                              ALIGN(size0 / 2, SZ_64K);
+-                                      size0 = size0 - size1;
+-                                      base1 = base0 + size0;
+-                              }
++
++      if ((readl(data->sfrbase + REG_MMU_VERSION) >> 28) == 3) {
++              if (!sysmmu_block(data->sfrbase))
++                      goto skip;
++
++              if (size1 == 0) {
++                      if (size0 <= SZ_128K) {
++                              base1 = base0;
++                              size1 = size0;
++                      } else {
++                              size1 = size0 -
++                                      ALIGN(size0 / 2, SZ_64K);
++                              size0 = size0 - size1;
++                              base1 = base0 + size0;
+                       }
++              }
+-                      __sysmmu_set_prefbuf(
+-                                      data->sfrbases[i], base0, size0, 0);
+-                      __sysmmu_set_prefbuf(
+-                                      data->sfrbases[i], base1, size1, 1);
++              __sysmmu_set_prefbuf(
++                              data->sfrbase, base0, size0, 0);
++              __sysmmu_set_prefbuf(
++                              data->sfrbase, base1, size1, 1);
+-                      sysmmu_unblock(data->sfrbases[i]);
+-              }
++              sysmmu_unblock(data->sfrbase);
+       }
++skip:
+       clk_disable(data->clk_master);
+ finish:
+       spin_unlock_irqrestore(&data->lock, flags);
+@@ -354,53 +352,41 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
+       struct exynos_iommu_client *client = NULL;
+       enum exynos_sysmmu_inttype itype;
+       unsigned long addr = -1;
+-      int i, ret = -ENOSYS;
++      int ret = -ENOSYS;
+       if (data->master)
+               client = data->master->archdata.iommu;
+       WARN_ON(!is_sysmmu_active(data));
+-      for (i = 0; i < data->nsfrs; i++) {
+-              struct resource *irqres;
+-              irqres = platform_get_resource(to_platform_device(data->sysmmu),
+-                                              IORESOURCE_IRQ, i);
+-              if (irqres && ((int)irqres->start == irq))
+-                      break;
+-      }
+-
+       if (client)
+               spin_lock(&client->lock);
+       spin_lock(&data->lock);
+-      if (i == data->nsfrs) {
++      itype = (enum exynos_sysmmu_inttype)
++              __ffs(__raw_readl(data->sfrbase + REG_INT_STATUS));
++      if (WARN_ON(!((itype >= 0) && (itype < SYSMMU_FAULT_UNKNOWN))))
+               itype = SYSMMU_FAULT_UNKNOWN;
+-      } else {
+-              itype = (enum exynos_sysmmu_inttype)
+-                      __ffs(__raw_readl(data->sfrbases[i] + REG_INT_STATUS));
+-              if (WARN_ON(!((itype >= 0) && (itype < SYSMMU_FAULT_UNKNOWN))))
+-                      itype = SYSMMU_FAULT_UNKNOWN;
+-              else
+-                      addr = __raw_readl(
+-                              data->sfrbases[i] + fault_reg_offset[itype]);
+-      }
++      else
++              addr = __raw_readl(
++                      data->sfrbase + fault_reg_offset[itype]);
+       if (data->domain)
+               ret = report_iommu_fault(data->domain, data->master,
+                               addr, itype);
+       if (!ret && (itype != SYSMMU_FAULT_UNKNOWN))
+-              __raw_writel(1 << itype, data->sfrbases[i] + REG_INT_CLEAR);
++              __raw_writel(1 << itype, data->sfrbase + REG_INT_CLEAR);
+       else {
+               unsigned long ba = data->pgtable;
+               if (itype != SYSMMU_FAULT_UNKNOWN)
+-                      ba = __raw_readl(data->sfrbases[i] + REG_PT_BASE_ADDR);
++                      ba = __raw_readl(data->sfrbase + REG_PT_BASE_ADDR);
+               show_fault_information(dev_name(data->sysmmu),
+                                       itype, ba, addr);
+       }
+       if (itype != SYSMMU_FAULT_UNKNOWN)
+-              sysmmu_unblock(data->sfrbases[i]);
++              sysmmu_unblock(data->sfrbase);
+       spin_unlock(&data->lock);
+       if (client)
+@@ -411,14 +397,10 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
+ static void __sysmmu_disable_nocount(struct sysmmu_drvdata *data)
+ {
+-      int i;
+-
+       clk_enable(data->clk_master);
+-      for (i = 0; i < data->nsfrs; i++) {
+-              __raw_writel(CTRL_DISABLE,
+-                              data->sfrbases[i] + REG_MMU_CTRL);
+-              __raw_writel(0, data->sfrbases[i] + REG_MMU_CFG);
+-      }
++
++      __raw_writel(CTRL_DISABLE, data->sfrbase + REG_MMU_CTRL);
++      __raw_writel(0, data->sfrbase + REG_MMU_CFG);
+       clk_disable(data->clk);
+       clk_disable(data->clk_master);
+@@ -452,12 +434,12 @@ static bool __sysmmu_disable(struct sysmmu_drvdata *data)
+ }
+-static void __sysmmu_init_config(struct sysmmu_drvdata *data, int idx)
++static void __sysmmu_init_config(struct sysmmu_drvdata *data)
+ {
+       unsigned long cfg = CFG_LRU | CFG_QOS(15);
+       int maj, min = 0;
+-      maj = __sysmmu_version(data, idx, &min);
++      maj = __sysmmu_version(data, &min);
+       if (maj == 3) {
+               if (min > 1) {
+                       cfg |= CFG_FLPDCACHE;
+@@ -465,25 +447,22 @@ static void __sysmmu_init_config(struct sysmmu_drvdata *data, int idx)
+               }
+       }
+-      __raw_writel(cfg, data->sfrbases[idx] + REG_MMU_CFG);
++      __raw_writel(cfg, data->sfrbase + REG_MMU_CFG);
+ }
+ static void __sysmmu_enable_nocount(struct sysmmu_drvdata *data)
+ {
+-      int i;
+-
+       clk_enable(data->clk_master);
+       clk_enable(data->clk);
+-      for (i = 0; i < data->nsfrs; i++) {
+-              __raw_writel(CTRL_BLOCK, data->sfrbases[i] + REG_MMU_CTRL);
++      __raw_writel(CTRL_BLOCK, data->sfrbase + REG_MMU_CTRL);
+-              __sysmmu_init_config(data, i);
++      __sysmmu_init_config(data);
+-              __sysmmu_set_ptbase(data->sfrbases[i], data->pgtable);
++      __sysmmu_set_ptbase(data->sfrbase, data->pgtable);
++
++      __raw_writel(CTRL_ENABLE, data->sfrbase + REG_MMU_CTRL);
+-              __raw_writel(CTRL_ENABLE, data->sfrbases[i] + REG_MMU_CTRL);
+-      }
+       clk_disable(data->clk_master);
+ }
+@@ -604,11 +583,8 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, unsigned long iova)
+               spin_lock_irqsave(&data->lock, flags);
+               if (is_sysmmu_active(data) && data->runtime_active) {
+-                      int i;
+                       clk_enable(data->clk_master);
+-                      for (i = 0; i < data->nsfrs; i++)
+-                              __sysmmu_tlb_invalidate_entry(
+-                                              data->sfrbases[i], iova);
++                      __sysmmu_tlb_invalidate_entry(data->sfrbase, iova);
+                       clk_disable(data->clk_master);
+               } else {
+                       dev_dbg(dev,
+@@ -633,16 +609,12 @@ void exynos_sysmmu_tlb_invalidate(struct device *dev)
+               spin_lock_irqsave(&data->lock, flags);
+               if (is_sysmmu_active(data) &&
+                               data->runtime_active) {
+-                      int i;
+-                      for (i = 0; i < data->nsfrs; i++) {
+-                              clk_enable(data->clk_master);
+-                              if (sysmmu_block(data->sfrbases[i])) {
+-                                      __sysmmu_tlb_invalidate(
+-                                                      data->sfrbases[i]);
+-                                      sysmmu_unblock(data->sfrbases[i]);
+-                              }
+-                              clk_disable(data->clk_master);
++                      clk_enable(data->clk_master);
++                      if (sysmmu_block(data->sfrbase)) {
++                              __sysmmu_tlb_invalidate(data->sfrbase);
++                              sysmmu_unblock(data->sfrbase);
+                       }
++                      clk_disable(data->clk_master);
+               } else {
+                       dev_dbg(dev, "disabled. Skipping TLB invalidation\n");
+               }
+@@ -652,58 +624,41 @@ void exynos_sysmmu_tlb_invalidate(struct device *dev)
+ static int __init exynos_sysmmu_probe(struct platform_device *pdev)
+ {
+-      int i, ret;
++      int ret;
+       struct device *dev = &pdev->dev;
+       struct sysmmu_drvdata *data;
++      struct resource *res;
++      int irq;
+-      if (pdev->num_resources == 0) {
+-              dev_err(dev, "No System MMU resource defined\n");
+-              return -ENODEV;
+-      }
+-
+-      data = devm_kzalloc(dev,
+-                      sizeof(*data) +
+-                      sizeof(*data->sfrbases) * (pdev->num_resources / 2),
+-                      GFP_KERNEL);
++      data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+       if (!data) {
+               dev_err(dev, "Not enough memory for initialization\n");
+               return -ENOMEM;
+       }
+-      data->nsfrs = pdev->num_resources / 2;
+-
+-      for (i = 0; i < data->nsfrs; i++) {
+-              struct resource *res;
+-
+-              res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+-              if (!res) {
+-                      dev_err(dev, "Unable to find IOMEM region\n");
+-                      return -ENOENT;
+-              }
+-
+-              data->sfrbases[i] = devm_request_and_ioremap(dev, res);
+-              if (!data->sfrbases[i]) {
+-                      dev_err(dev, "Unable to map IOMEM @ %#x\n", res->start);
+-                      return -EBUSY;
+-              }
++      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      if (!res) {
++              dev_err(dev, "Unable to find IOMEM region\n");
++              return -ENOENT;
+       }
+-      for (i = 0; i < data->nsfrs; i++) {
+-              int irq;
++      data->sfrbase = devm_request_and_ioremap(dev, res);
++      if (!data->sfrbase) {
++              dev_err(dev, "Unable to map IOMEM @ %#x\n", res->start);
++              return -EBUSY;
++      }
+-              irq = platform_get_irq(pdev, i);
+-              if (irq <= 0) {
+-                      dev_err(dev, "Unable to find IRQ resource\n");
+-                      return -ENOENT;
+-              }
++      irq = platform_get_irq(pdev, 0);
++      if (irq <= 0) {
++      dev_err(dev, "Unable to find IRQ resource\n");
++              return -ENOENT;
++      }
+-              ret = devm_request_irq(dev, irq, exynos_sysmmu_irq,
+-                                      0, dev_name(dev), data);
+-              if (ret) {
+-                      dev_err(dev, "Unable to register handler to irq %d\n",
+-                              irq);
+-                      return ret;
+-              }
++      ret = devm_request_irq(dev, irq, exynos_sysmmu_irq, 0, dev_name(dev),
++                             data);
++      if (ret) {
++              dev_err(dev, "Unable to register handler to irq %d\n", irq);
++              return ret;
+       }
+       pm_runtime_enable(dev);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0568-iommu-exynos-remove-support-for-multiple-sysmmu-s-pe.patch b/patches.tizen/0568-iommu-exynos-remove-support-for-multiple-sysmmu-s-pe.patch
new file mode 100644 (file)
index 0000000..82787ef
--- /dev/null
@@ -0,0 +1,542 @@
+From f823fc366547752113e22d22ac2cb670d6d1aa37 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Wed, 7 Aug 2013 09:31:05 +0200
+Subject: [PATCH 0568/1302] iommu/exynos: remove support for multiple sysmmu's
+ per single device
+
+Combined SYSMMU's has been removed, so there is no point to support
+more than one SYSMMU controller per single client device. This patch
+removes support for it and simplifies the code of the SYSMMU driver.
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iommu/exynos-iommu.c | 310 ++++++++++++++-----------------------------
+ 1 file changed, 100 insertions(+), 210 deletions(-)
+
+diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
+index b46c3fe..1af5496 100644
+--- a/drivers/iommu/exynos-iommu.c
++++ b/drivers/iommu/exynos-iommu.c
+@@ -163,14 +163,6 @@ static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
+       "UNKNOWN FAULT"
+ };
+-struct exynos_iommu_client {
+-      struct list_head node;  /* entry of exynos_iommu_domain.clients */
+-      struct device *dev;
+-      spinlock_t lock;
+-      int num_sysmmu;
+-      struct device *sysmmu[0];
+-};
+-
+ struct exynos_iommu_domain {
+       struct list_head clients; /* list of sysmmu_drvdata.node */
+       unsigned long *pgtable; /* lv1 page table, 16KB */
+@@ -349,18 +341,12 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
+ {
+       /* SYSMMU is in blocked when interrupt occurred. */
+       struct sysmmu_drvdata *data = dev_id;
+-      struct exynos_iommu_client *client = NULL;
+       enum exynos_sysmmu_inttype itype;
+       unsigned long addr = -1;
+       int ret = -ENOSYS;
+-      if (data->master)
+-              client = data->master->archdata.iommu;
+-
+       WARN_ON(!is_sysmmu_active(data));
+-      if (client)
+-              spin_lock(&client->lock);
+       spin_lock(&data->lock);
+       itype = (enum exynos_sysmmu_inttype)
+@@ -389,8 +375,6 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
+               sysmmu_unblock(data->sfrbase);
+       spin_unlock(&data->lock);
+-      if (client)
+-              spin_unlock(&client->lock);
+       return IRQ_HANDLED;
+ }
+@@ -505,30 +489,17 @@ static int __exynos_sysmmu_enable(struct device *dev, unsigned long pgtable,
+                                 struct iommu_domain *domain)
+ {
+       int ret = 0;
+-      unsigned long flags;
+-      struct exynos_iommu_client *client = dev->archdata.iommu;
+-      int i;
++      struct device *sysmmu = dev->archdata.iommu;
++      struct sysmmu_drvdata *data;
+-      if (WARN_ON(!client))
++      if (WARN_ON(!sysmmu))
+               return -ENODEV;
+-      spin_lock_irqsave(&client->lock, flags);
+-
+-      for (i = 0; i < client->num_sysmmu; i++) {
+-              struct sysmmu_drvdata *data =
+-                              dev_get_drvdata(client->sysmmu[i]);
+-              ret = __sysmmu_enable(data, pgtable, domain);
+-              if (ret < 0) {
+-                      int j;
+-                      for (j = 0; j < i; j++)
+-                              __sysmmu_disable(data);
+-                      break;
+-              } else {
+-                      data->master = dev;
+-              }
+-      }
++      data = dev_get_drvdata(sysmmu);
+-      spin_unlock_irqrestore(&client->lock, flags);
++      ret = __sysmmu_enable(data, pgtable, domain);
++      if (ret >= 0)
++              data->master = dev;
+       return ret;
+ }
+@@ -546,80 +517,63 @@ int exynos_sysmmu_enable(struct device *dev, unsigned long pgtable)
+ static bool exynos_sysmmu_disable(struct device *dev)
+ {
+-      unsigned long flags;
++      struct device *sysmmu = dev->archdata.iommu;
++      struct sysmmu_drvdata *data;
+       bool disabled = true;
+-      struct exynos_iommu_client *client = dev->archdata.iommu;
+-      int i;
+-      if (WARN_ON(!client))
+-              return true;
+-
+-      spin_lock_irqsave(&client->lock, flags);
++      if (WARN_ON(!sysmmu))
++              return -ENODEV;
+-      /* Every call to __sysmmu_disable() must return same result */
+-      for (i = 0; i < client->num_sysmmu; i++) {
+-              struct sysmmu_drvdata *data =
+-                              dev_get_drvdata(client->sysmmu[i]);
+-              disabled = __sysmmu_disable(data);
+-              if (disabled)
+-                      data->master = NULL;
+-      }
++      data = dev_get_drvdata(sysmmu);
+-      spin_unlock_irqrestore(&client->lock, flags);
++      disabled = __sysmmu_disable(data);
++      if (disabled)
++              data->master = NULL;
+       return disabled;
+ }
+ static void sysmmu_tlb_invalidate_entry(struct device *dev, unsigned long iova)
+ {
+-      struct exynos_iommu_client *client = dev->archdata.iommu;
+-      int i;
++      struct device *sysmmu = dev->archdata.iommu;
++      struct sysmmu_drvdata *data;
++      unsigned long flags;
+-      for (i = 0; i < client->num_sysmmu; i++) {
+-              unsigned long flags;
+-              struct sysmmu_drvdata *data;
+-
+-              data = dev_get_drvdata(client->sysmmu[i]);
+-
+-              spin_lock_irqsave(&data->lock, flags);
+-              if (is_sysmmu_active(data) && data->runtime_active) {
+-                      clk_enable(data->clk_master);
+-                      __sysmmu_tlb_invalidate_entry(data->sfrbase, iova);
+-                      clk_disable(data->clk_master);
+-              } else {
+-                      dev_dbg(dev,
+-                              "disabled. Skipping TLB invalidation @ %#lx\n",
+-                              iova);
+-              }
+-              spin_unlock_irqrestore(&data->lock, flags);
++      data = dev_get_drvdata(sysmmu);
++
++      spin_lock_irqsave(&data->lock, flags);
++      if (is_sysmmu_active(data) && data->runtime_active) {
++              clk_enable(data->clk_master);
++              __sysmmu_tlb_invalidate_entry(data->sfrbase, iova);
++              clk_disable(data->clk_master);
++      } else {
++              dev_dbg(dev,
++                      "disabled. Skipping TLB invalidation @ %#lx\n", iova);
+       }
++      spin_unlock_irqrestore(&data->lock, flags);
+ }
+ void exynos_sysmmu_tlb_invalidate(struct device *dev)
+ {
+-      struct exynos_iommu_client *client = dev->archdata.iommu;
+-      int i;
++      struct device *sysmmu = dev->archdata.iommu;
++      struct sysmmu_drvdata *data;
++      unsigned long flags;
+-      for (i = 0; i < client->num_sysmmu; i++) {
+-              unsigned long flags;
+-              struct sysmmu_drvdata *data;
++      data = dev_get_drvdata(sysmmu);
+-              data = dev_get_drvdata(client->sysmmu[i]);
++      spin_lock_irqsave(&data->lock, flags);
+-              spin_lock_irqsave(&data->lock, flags);
+-              if (is_sysmmu_active(data) &&
+-                              data->runtime_active) {
+-                      clk_enable(data->clk_master);
+-                      if (sysmmu_block(data->sfrbase)) {
+-                              __sysmmu_tlb_invalidate(data->sfrbase);
+-                              sysmmu_unblock(data->sfrbase);
+-                      }
+-                      clk_disable(data->clk_master);
+-              } else {
+-                      dev_dbg(dev, "disabled. Skipping TLB invalidation\n");
++      if (is_sysmmu_active(data) && data->runtime_active) {
++              clk_enable(data->clk_master);
++              if (sysmmu_block(data->sfrbase)) {
++                      __sysmmu_tlb_invalidate(data->sfrbase);
++                      sysmmu_unblock(data->sfrbase);
+               }
+-              spin_unlock_irqrestore(&data->lock, flags);
++              clk_disable(data->clk_master);
++      } else {
++              dev_dbg(dev, "disabled. Skipping TLB invalidation\n");
+       }
++      spin_unlock_irqrestore(&data->lock, flags);
+ }
+ static int __init exynos_sysmmu_probe(struct platform_device *pdev)
+@@ -792,7 +746,7 @@ err_pgtable:
+ static void exynos_iommu_domain_destroy(struct iommu_domain *domain)
+ {
+       struct exynos_iommu_domain *priv = domain->priv;
+-      struct exynos_iommu_client *client;
++      struct sysmmu_drvdata *data;
+       unsigned long flags;
+       int i;
+@@ -800,8 +754,8 @@ static void exynos_iommu_domain_destroy(struct iommu_domain *domain)
+       spin_lock_irqsave(&priv->lock, flags);
+-      list_for_each_entry(client, &priv->clients, node) {
+-              while (!exynos_sysmmu_disable(client->dev))
++      list_for_each_entry(data, &priv->clients, node) {
++              while (!exynos_sysmmu_disable(data->master))
+                       ; /* until System MMU is actually disabled */
+       }
+@@ -824,8 +778,8 @@ static void exynos_iommu_domain_destroy(struct iommu_domain *domain)
+ static int exynos_iommu_attach_device(struct iommu_domain *domain,
+                                  struct device *dev)
+ {
+-      struct exynos_iommu_client *client = dev->archdata.iommu;
+       struct exynos_iommu_domain *priv = domain->priv;
++      struct sysmmu_drvdata *data = dev_get_drvdata(dev->archdata.iommu);
+       unsigned long flags;
+       int ret;
+@@ -833,7 +787,7 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
+       ret = __exynos_sysmmu_enable(dev, __pa(priv->pgtable), domain);
+       if (ret == 0)
+-              list_add_tail(&client->node, &priv->clients);
++              list_add_tail(&data->node, &priv->clients);
+       spin_unlock_irqrestore(&priv->lock, flags);
+@@ -852,23 +806,23 @@ static int exynos_iommu_attach_device(struct iommu_domain *domain,
+ static void exynos_iommu_detach_device(struct iommu_domain *domain,
+                                   struct device *dev)
+ {
+-      struct exynos_iommu_client *client = NULL;
+       struct exynos_iommu_domain *priv = domain->priv;
++      struct sysmmu_drvdata *data;
+       unsigned long flags;
+       spin_lock_irqsave(&priv->lock, flags);
+-      list_for_each_entry(client, &priv->clients, node) {
+-              if (client == dev->archdata.iommu) {
++      list_for_each_entry(data, &priv->clients, node) {
++              if (data->sysmmu == dev->archdata.iommu) {
+                       if (exynos_sysmmu_disable(dev))
+-                              list_del_init(&client->node);
++                              list_del_init(&data->node);
+                       break;
+               }
+       }
+       spin_unlock_irqrestore(&priv->lock, flags);
+-      if (client == dev->archdata.iommu)
++      if (data->sysmmu == dev->archdata.iommu)
+               dev_dbg(dev, "%s: Detached IOMMU with pgtable %#lx\n",
+                                       __func__, __pa(priv->pgtable));
+       else
+@@ -994,7 +948,7 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain,
+                                              unsigned long iova, size_t size)
+ {
+       struct exynos_iommu_domain *priv = domain->priv;
+-      struct exynos_iommu_client *client;
++      struct sysmmu_drvdata *data;
+       unsigned long flags;
+       unsigned long *ent;
+       size_t err_pgsize;
+@@ -1055,8 +1009,8 @@ done:
+       spin_unlock_irqrestore(&priv->pgtablelock, flags);
+       spin_lock_irqsave(&priv->lock, flags);
+-      list_for_each_entry(client, &priv->clients, node)
+-              sysmmu_tlb_invalidate_entry(client->dev, iova);
++      list_for_each_entry(data, &priv->clients, node)
++              sysmmu_tlb_invalidate_entry(data->master, iova);
+       spin_unlock_irqrestore(&priv->lock, flags);
+       return size;
+@@ -1139,50 +1093,32 @@ subsys_initcall(exynos_iommu_init);
+ #ifdef CONFIG_PM_SLEEP
+ static int sysmmu_pm_genpd_suspend(struct device *dev)
+ {
+-      struct exynos_iommu_client *client = dev->archdata.iommu;
+-      int ret = 0;
+-      int i;
+-
+-      for (i = 0; i < client->num_sysmmu; i++) {
+-              ret = pm_generic_suspend(client->sysmmu[i]);
+-              if (ret)
+-                      break;
+-      }
+-
+-      if (!ret)
+-              ret = pm_generic_suspend(dev);
++      struct sysmmu_drvdata *data = dev_get_drvdata(dev->archdata.iommu);
++      int ret;
+-      if (ret) {
+-              int j;
++      ret = pm_generic_suspend(data->sysmmu);
++      if (ret)
++              return ret;
+-              for (j = 0; j < i; j++)
+-                      pm_generic_resume(client->sysmmu[j]);
+-      }
++      ret = pm_generic_suspend(dev);
++      if (ret)
++              pm_generic_resume(data->sysmmu);
+       return ret;
+ }
+ static int sysmmu_pm_genpd_resume(struct device *dev)
+ {
+-      struct exynos_iommu_client *client = dev->archdata.iommu;
++      struct sysmmu_drvdata *data = dev_get_drvdata(dev->archdata.iommu);
+       int ret = 0;
+-      int i;
+-      for (i = 0; i < client->num_sysmmu; i++) {
+-              ret = pm_generic_resume(client->sysmmu[i]);
+-              if (ret)
+-                      break;
+-      }
+-
+-      if (!ret)
+-              ret = pm_generic_resume(dev);
+-
+-      if (ret) {
+-              int j;
++      ret = pm_generic_resume(data->sysmmu);
++      if (ret)
++              return ret;
+-              for (j = 0; j < i; j++)
+-                      pm_generic_suspend(client->sysmmu[j]);
+-      }
++      ret = pm_generic_resume(dev);
++      if (ret)
++              pm_generic_suspend(data->sysmmu);
+       return ret;
+ }
+@@ -1215,9 +1151,8 @@ static void sysmmu_save_state(struct device *sysmmu)
+ static int sysmmu_pm_genpd_save_state(struct device *dev)
+ {
+-      struct exynos_iommu_client *client = dev->archdata.iommu;
++      struct sysmmu_drvdata *data = dev_get_drvdata(dev->archdata.iommu);
+       int (*cb)(struct device *__dev);
+-      int i;
+       if (dev->type && dev->type->pm)
+               cb = dev->type->pm->runtime_suspend;
+@@ -1239,17 +1174,15 @@ static int sysmmu_pm_genpd_save_state(struct device *dev)
+                       return ret;
+       }
+-      for (i = 0; i < client->num_sysmmu; i++)
+-              sysmmu_save_state(client->sysmmu[i]);
++      sysmmu_save_state(data->sysmmu);
+       return 0;
+ }
+ static int sysmmu_pm_genpd_restore_state(struct device *dev)
+ {
+-      struct exynos_iommu_client *client = dev->archdata.iommu;
++      struct sysmmu_drvdata *data = dev_get_drvdata(dev->archdata.iommu);
+       int (*cb)(struct device *__dev);
+-      int i;
+       if (dev->type && dev->type->pm)
+               cb = dev->type->pm->runtime_resume;
+@@ -1263,15 +1196,13 @@ static int sysmmu_pm_genpd_restore_state(struct device *dev)
+       if (!cb && dev->driver && dev->driver->pm)
+               cb = dev->driver->pm->runtime_resume;
+-      for (i = 0; i < client->num_sysmmu; i++)
+-              sysmmu_restore_state(client->sysmmu[i]);
++      sysmmu_restore_state(data->sysmmu);
+       if (cb) {
+               int ret;
+               ret = cb(dev);
+               if (ret) {
+-                      for (i = 0; i < client->num_sysmmu; i++)
+-                              sysmmu_save_state(client->sysmmu[i]);
++                      sysmmu_save_state(data->sysmmu);
+                       return ret;
+               }
+       }
+@@ -1302,83 +1233,45 @@ static int sysmmu_hook_driver_register(struct notifier_block *nb,
+       switch (val) {
+       case BUS_NOTIFY_BIND_DRIVER:
+       {
+-              int i = 0;
+-              int size = 0;
++              struct platform_device *sysmmu;
++              struct device_node *np;
+               const __be32 *phandle;
+-              struct exynos_iommu_client *client;
++              int ret;
+-              phandle = of_get_property(dev->of_node, "iommu", &size);
++              phandle = of_get_property(dev->of_node, "iommu", NULL);
+               if (!phandle)
+                       break;
+-              size = size / sizeof(*phandle); /* number of elements */
+-
+-              client = devm_kzalloc(dev, sizeof(*client) * size, GFP_KERNEL);
+-              if (!client) {
+-                      dev_err(dev, "No Memory for exynos_iommu_client\n");
+-                      return -ENOMEM;
+-              }
+-
+-              client->num_sysmmu = size;
+-              client->dev = dev;
+-              INIT_LIST_HEAD(&client->node);
+-              spin_lock_init(&client->lock);
+-
+-              for (i = 0; i < size; i++) {
+-                      struct device_node *np;
+-                      struct platform_device *sysmmu;
+-
+-                      /* this always success: see above of_find_property() */
+-                      np = of_parse_phandle(dev->of_node, "iommu", i);
+-
+-                      sysmmu = of_find_device_by_node(np);
+-                      if (!sysmmu) {
+-                              dev_err(dev,
+-                                      "sysmmu node '%s' is not found\n",
+-                                      np->name);
+-                              break;
+-                      }
+-
+-                      client->sysmmu[i] = &sysmmu->dev;
+-              }
+-
+-              if (i < size) {
+-                      while (--i >= 0)
+-                              of_node_put(client->sysmmu[i]->of_node);
+-                      devm_kfree(dev, client);
+-                      return -ENODEV;
++              /* this always success: see above of_find_property() */
++              np = of_parse_phandle(dev->of_node, "iommu", 0);
++              sysmmu = of_find_device_by_node(np);
++              if (!sysmmu) {
++                      dev_err(dev, "sysmmu node '%s' is not found\n",
++                              np->name);
++                              return -ENODEV;
+               }
+-              i = pm_genpd_add_callbacks(dev, &sysmmu_devpm_ops, NULL);
+-              if (i && (i != -ENOSYS)) {
++              ret = pm_genpd_add_callbacks(dev, &sysmmu_devpm_ops, NULL);
++              if (ret && (ret != -ENOSYS)) {
+                       dev_err(dev,
+                               "Failed to register 'dev_pm_ops' for iommu\n");
+-                      devm_kfree(dev, client);
+-                      return i;
++                      return ret;
+               }
+-              dev->archdata.iommu = client;
++              dev->archdata.iommu = &sysmmu->dev;
+               break;
+       }
+       case BUS_NOTIFY_BOUND_DRIVER:
+       {
+-              struct exynos_iommu_client *client = dev->archdata.iommu;
+-              if (dev->archdata.iommu &&
+-                              (!pm_runtime_enabled(dev) ||
+-                                       IS_ERR(dev_to_genpd(dev)))) {
+-                      int i;
+-                      for (i = 0; i < client->num_sysmmu; i++) {
+-                              struct sysmmu_drvdata *data;
+-                              pm_runtime_disable(client->sysmmu[i]);
+-                              data = dev_get_drvdata(client->sysmmu[i]);
+-                              if (!data)
+-                                      continue;
+-                              data->runtime_active =
+-                                      !pm_runtime_enabled(data->sysmmu);
+-                              if (data->runtime_active &&
+-                                              is_sysmmu_active(data))
+-                                      __sysmmu_enable_nocount(data);
+-                      }
++              if (dev->archdata.iommu && (!pm_runtime_enabled(dev) ||
++                                         IS_ERR(dev_to_genpd(dev)))) {
++                      struct sysmmu_drvdata *data;
++                      data = dev_get_drvdata(dev->archdata.iommu);
++                      pm_runtime_disable(data->sysmmu);
++                      data->runtime_active = !pm_runtime_enabled(data->sysmmu);
++                      if (data->runtime_active && is_sysmmu_active(data))
++                              __sysmmu_enable_nocount(data);
++
+               }
+               break;
+       }
+@@ -1386,9 +1279,6 @@ static int sysmmu_hook_driver_register(struct notifier_block *nb,
+       {
+               if (dev->archdata.iommu) {
+                       __pm_genpd_remove_callbacks(dev, false);
+-
+-                      devm_kfree(dev, dev->archdata.iommu);
+-
+                       dev->archdata.iommu = NULL;
+               }
+               break;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0569-iommu-exynos-simplify-some-functions.patch b/patches.tizen/0569-iommu-exynos-simplify-some-functions.patch
new file mode 100644 (file)
index 0000000..a1a95b0
--- /dev/null
@@ -0,0 +1,93 @@
+From 33cc03857e3394ac791f1c0b44537167cd84c845 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Wed, 7 Aug 2013 09:33:26 +0200
+Subject: [PATCH 0569/1302] iommu/exynos: simplify some functions
+
+Some functions are now called directly with all data structures available
+at caller, so simplify them and remove code extracting private structures.
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iommu/exynos-iommu.c | 27 ++++++++-------------------
+ 1 file changed, 8 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
+index 1af5496..8b0471d 100644
+--- a/drivers/iommu/exynos-iommu.c
++++ b/drivers/iommu/exynos-iommu.c
+@@ -515,39 +515,28 @@ int exynos_sysmmu_enable(struct device *dev, unsigned long pgtable)
+       return ret;
+ }
+-static bool exynos_sysmmu_disable(struct device *dev)
++static bool exynos_sysmmu_disable(struct sysmmu_drvdata *data)
+ {
+-      struct device *sysmmu = dev->archdata.iommu;
+-      struct sysmmu_drvdata *data;
+-      bool disabled = true;
+-
+-      if (WARN_ON(!sysmmu))
+-              return -ENODEV;
++      bool disabled = __sysmmu_disable(data);
+-      data = dev_get_drvdata(sysmmu);
+-
+-      disabled = __sysmmu_disable(data);
+       if (disabled)
+               data->master = NULL;
+       return disabled;
+ }
+-static void sysmmu_tlb_invalidate_entry(struct device *dev, unsigned long iova)
++static void sysmmu_tlb_invalidate_entry(struct sysmmu_drvdata *data,
++                                      unsigned long iova)
+ {
+-      struct device *sysmmu = dev->archdata.iommu;
+-      struct sysmmu_drvdata *data;
+       unsigned long flags;
+-      data = dev_get_drvdata(sysmmu);
+-
+       spin_lock_irqsave(&data->lock, flags);
+       if (is_sysmmu_active(data) && data->runtime_active) {
+               clk_enable(data->clk_master);
+               __sysmmu_tlb_invalidate_entry(data->sfrbase, iova);
+               clk_disable(data->clk_master);
+       } else {
+-              dev_dbg(dev,
++              dev_dbg(data->master,
+                       "disabled. Skipping TLB invalidation @ %#lx\n", iova);
+       }
+       spin_unlock_irqrestore(&data->lock, flags);
+@@ -755,7 +744,7 @@ static void exynos_iommu_domain_destroy(struct iommu_domain *domain)
+       spin_lock_irqsave(&priv->lock, flags);
+       list_for_each_entry(data, &priv->clients, node) {
+-              while (!exynos_sysmmu_disable(data->master))
++              while (!exynos_sysmmu_disable(data))
+                       ; /* until System MMU is actually disabled */
+       }
+@@ -814,7 +803,7 @@ static void exynos_iommu_detach_device(struct iommu_domain *domain,
+       list_for_each_entry(data, &priv->clients, node) {
+               if (data->sysmmu == dev->archdata.iommu) {
+-                      if (exynos_sysmmu_disable(dev))
++                      if (exynos_sysmmu_disable(data))
+                               list_del_init(&data->node);
+                       break;
+               }
+@@ -1010,7 +999,7 @@ done:
+       spin_lock_irqsave(&priv->lock, flags);
+       list_for_each_entry(data, &priv->clients, node)
+-              sysmmu_tlb_invalidate_entry(data->master, iova);
++              sysmmu_tlb_invalidate_entry(data, iova);
+       spin_unlock_irqrestore(&priv->lock, flags);
+       return size;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0570-iommu-exynos-register-iommu-aware-dma-ops-for-client.patch b/patches.tizen/0570-iommu-exynos-register-iommu-aware-dma-ops-for-client.patch
new file mode 100644 (file)
index 0000000..207565b
--- /dev/null
@@ -0,0 +1,179 @@
+From b4a1619bd9d41d66d464dff56b4e8f4a8043aefb Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Wed, 7 Aug 2013 11:00:13 +0200
+Subject: [PATCH 0570/1302] iommu/exynos: register iommu-aware dma ops for
+ client devices
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iommu/Kconfig        |  1 +
+ drivers/iommu/exynos-iommu.c | 89 ++++++++++++++++++++++++++++++--------------
+ 2 files changed, 62 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
+index d45f3c9..e48798d 100644
+--- a/drivers/iommu/Kconfig
++++ b/drivers/iommu/Kconfig
+@@ -170,6 +170,7 @@ config EXYNOS_IOMMU
+       bool "Exynos IOMMU Support"
+       depends on ARCH_EXYNOS
+       select IOMMU_API
++      select ARM_DMA_USE_IOMMU
+       default n
+       help
+         Support for the IOMMU(System MMU) of Samsung Exynos application
+diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
+index 8b0471d..01d1c62 100644
+--- a/drivers/iommu/exynos-iommu.c
++++ b/drivers/iommu/exynos-iommu.c
+@@ -19,6 +19,7 @@
+ #include <linux/slab.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/clk.h>
++#include <linux/dma-mapping.h>
+ #include <linux/err.h>
+ #include <linux/mm.h>
+ #include <linux/iommu.h>
+@@ -31,6 +32,7 @@
+ #include <linux/pm_domain.h>
+ #include <linux/notifier.h>
++#include <asm/dma-iommu.h>
+ #include <asm/cacheflush.h>
+ #include <asm/pgtable.h>
+@@ -1053,31 +1055,6 @@ static struct iommu_ops exynos_iommu_ops = {
+       .pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE,
+ };
+-static int __init exynos_iommu_init(void)
+-{
+-      int ret;
+-
+-      lv2table_kmem_cache = kmem_cache_create("exynos-iommu-lv2table",
+-                              LV2TABLE_SIZE, LV2TABLE_SIZE, 0, NULL);
+-      if (!lv2table_kmem_cache) {
+-              pr_err("%s: Failed to create kmem cache\n", __func__);
+-              return -ENOMEM;
+-      }
+-
+-      ret = platform_driver_register(&exynos_sysmmu_driver);
+-
+-      if (ret == 0)
+-              ret = bus_set_iommu(&platform_bus_type, &exynos_iommu_ops);
+-
+-      if (ret) {
+-              pr_err("%s: Failed to register exynos-iommu driver.\n",
+-                                                              __func__);
+-              kmem_cache_destroy(lv2table_kmem_cache);
+-      }
+-
+-      return ret;
+-}
+-subsys_initcall(exynos_iommu_init);
+ #ifdef CONFIG_PM_SLEEP
+ static int sysmmu_pm_genpd_suspend(struct device *dev)
+@@ -1213,6 +1190,31 @@ struct gpd_dev_ops sysmmu_devpm_ops = {
+ };
+ #endif /* CONFIG_PM_GENERIC_DOMAINS */
++
++static int exynos_create_default_iommu_mapping(struct device *dev)
++{
++      struct dma_iommu_mapping *mapping;
++      dma_addr_t base = 0x20000000;
++      unsigned int size = SZ_128M;
++      int order = 4;
++
++      mapping = arm_iommu_create_mapping(&platform_bus_type, base, size, order);
++      if (!mapping)
++              return -ENOMEM;
++      dev->dma_parms = kzalloc(sizeof(*dev->dma_parms), GFP_KERNEL);
++      dma_set_max_seg_size(dev, 0xffffffffu);
++      arm_iommu_attach_device(dev, mapping);
++      return 0;
++}
++
++static int exynos_remove_iommu_mapping(struct device *dev)
++{
++      struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
++      arm_iommu_detach_device(dev);
++      arm_iommu_release_mapping(mapping);
++      return 0;
++}
++
+ static int sysmmu_hook_driver_register(struct notifier_block *nb,
+                                       unsigned long val,
+                                       void *p)
+@@ -1239,6 +1241,8 @@ static int sysmmu_hook_driver_register(struct notifier_block *nb,
+                               np->name);
+                               return -ENODEV;
+               }
++              dev_info(dev, "attaching sysmmu controller %s\n",
++                       dev_name(&sysmmu->dev));
+               ret = pm_genpd_add_callbacks(dev, &sysmmu_devpm_ops, NULL);
+               if (ret && (ret != -ENOSYS)) {
+@@ -1248,6 +1252,9 @@ static int sysmmu_hook_driver_register(struct notifier_block *nb,
+               }
+               dev->archdata.iommu = &sysmmu->dev;
++
++              if (!to_dma_iommu_mapping(dev))
++                      exynos_create_default_iommu_mapping(dev);
+               break;
+       }
+       case BUS_NOTIFY_BOUND_DRIVER:
+@@ -1265,9 +1272,12 @@ static int sysmmu_hook_driver_register(struct notifier_block *nb,
+               break;
+       }
+       case BUS_NOTIFY_UNBOUND_DRIVER:
++      case BUS_NOTIFY_BIND_FAILED:
+       {
+               if (dev->archdata.iommu) {
+                       __pm_genpd_remove_callbacks(dev, false);
++                      if (to_dma_iommu_mapping(dev))
++                              exynos_remove_iommu_mapping(dev);
+                       dev->archdata.iommu = NULL;
+               }
+               break;
+@@ -1281,8 +1291,31 @@ static struct notifier_block sysmmu_notifier = {
+       .notifier_call = &sysmmu_hook_driver_register,
+ };
+-static int __init exynos_iommu_prepare(void)
++static int __init exynos_iommu_init(void)
+ {
+-      return bus_register_notifier(&platform_bus_type, &sysmmu_notifier);
++      int ret;
++
++      lv2table_kmem_cache = kmem_cache_create("exynos-iommu-lv2table",
++                              LV2TABLE_SIZE, LV2TABLE_SIZE, 0, NULL);
++      if (!lv2table_kmem_cache) {
++              pr_err("%s: Failed to create kmem cache\n", __func__);
++              return -ENOMEM;
++      }
++
++      ret = platform_driver_register(&exynos_sysmmu_driver);
++      if (ret == 0) {
++              ret = bus_set_iommu(&platform_bus_type, &exynos_iommu_ops);
++              if (ret == 0)
++                      ret = bus_register_notifier(&platform_bus_type,
++                                                  &sysmmu_notifier);
++      }
++
++      if (ret) {
++              pr_err("%s: Failed to register exynos-iommu driver.\n",
++                                                              __func__);
++              kmem_cache_destroy(lv2table_kmem_cache);
++      }
++
++      return ret;
+ }
+-arch_initcall(exynos_iommu_prepare);
++arch_initcall(exynos_iommu_init);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0571-iommu-exynos-add-dummy-driver-for-enabling-runtime-p.patch b/patches.tizen/0571-iommu-exynos-add-dummy-driver-for-enabling-runtime-p.patch
new file mode 100644 (file)
index 0000000..de1fdfa
--- /dev/null
@@ -0,0 +1,57 @@
+From e22b78a24fb729fc970326e55843376852339885 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Wed, 7 Aug 2013 11:03:17 +0200
+Subject: [PATCH 0571/1302] iommu/exynos: add dummy driver for enabling runtime
+ pm for mem port devices
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iommu/exynos-iommu.c | 34 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 34 insertions(+)
+
+diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
+index 01d1c62..76f423d 100644
+--- a/drivers/iommu/exynos-iommu.c
++++ b/drivers/iommu/exynos-iommu.c
+@@ -1319,3 +1319,37 @@ static int __init exynos_iommu_init(void)
+       return ret;
+ }
+ arch_initcall(exynos_iommu_init);
++
++/*
++ * Dummy driver to enable runtime power management for memport
++ * devices, which required for correct Exynos SYSMMU operation.
++ * Must be registered before drivers, which will use memport nodes.
++ */
++static int __init exynos_memport_probe(struct platform_device *pdev)
++{
++      struct device *dev = &pdev->dev;
++      pm_runtime_enable(dev);
++      return 0;
++}
++
++#ifdef CONFIG_OF
++static struct of_device_id memport_of_match[] __initconst = {
++      { .compatible   = "samsung,memport", },
++      { },
++};
++#endif
++
++static struct platform_driver exynos_memport_driver __refdata = {
++      .probe  = exynos_memport_probe,
++      .driver = {
++              .owner          = THIS_MODULE,
++              .name           = "exynos-memport",
++              .of_match_table = of_match_ptr(memport_of_match),
++      }
++};
++
++static int __init exynos_memport_init(void)
++{
++      return platform_driver_register(&exynos_memport_driver);
++}
++subsys_initcall(exynos_memport_init);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0572-ARM-Exynos4-add-clocks-for-SYSMMU-controller-and-ena.patch b/patches.tizen/0572-ARM-Exynos4-add-clocks-for-SYSMMU-controller-and-ena.patch
new file mode 100644 (file)
index 0000000..c1196c2
--- /dev/null
@@ -0,0 +1,250 @@
+From 26575327fa3616dbc6576aa746bf705ca1006250 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Wed, 21 Aug 2013 13:24:22 +0200
+Subject: [PATCH 0572/1302] ARM: Exynos4: add clocks for SYSMMU controller and
+ enable IOMMU support
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi    | 49 ++++++++++++++++++++++-----------------
+ arch/arm/boot/dts/exynos4x12.dtsi | 21 +++++++++++------
+ 2 files changed, 42 insertions(+), 28 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index d8525ec..cd2725a 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -172,6 +172,7 @@
+                       samsung,power-domain = <&pd_cam>;
+                       samsung,sysreg = <&sys_reg>;
+                       status = "disabled";
++                      iommu = <&sysmmu_fimc0>;
+               };
+               fimc_1: fimc@11810000 {
+@@ -181,6 +182,7 @@
+                       samsung,power-domain = <&pd_cam>;
+                       samsung,sysreg = <&sys_reg>;
+                       status = "disabled";
++                      iommu = <&sysmmu_fimc1>;
+               };
+               fimc_2: fimc@11820000 {
+@@ -190,6 +192,7 @@
+                       samsung,power-domain = <&pd_cam>;
+                       samsung,sysreg = <&sys_reg>;
+                       status = "disabled";
++                      iommu = <&sysmmu_fimc2>;
+               };
+               fimc_3: fimc@11830000 {
+@@ -199,6 +202,7 @@
+                       samsung,power-domain = <&pd_cam>;
+                       samsung,sysreg = <&sys_reg>;
+                       status = "disabled";
++                      iommu = <&sysmmu_fimc3>;
+               };
+               csis_0: csis@11880000 {
+@@ -297,16 +301,19 @@
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+-              iommu = <&sysmmu_mfc_l>, <&sysmmu_mfc_r>;
+               mfc_l: memport@0 {
+                       compatible = "samsung,memport";
+                       reg = <0>;
++                      iommu = <&sysmmu_mfc_l>;
++                      samsung,power-domain = <&pd_mfc>;
+               };
+               mfc_r: memport@1 {
+                       compatible = "samsung,memport";
+                       reg = <1>;
++                      iommu = <&sysmmu_mfc_r>;
++                      samsung,power-domain = <&pd_mfc>;
+               };
+       };
+@@ -605,8 +612,8 @@
+               interrupt-parent = <&combiner>;
+               interrupt-names = "sysmmu-mfc-l";
+               interrupts = <5 5>;
+-              clock-names = "sysmmu";
+-              clocks = <&clock 274>;
++              clock-names = "sysmmu", "master";
++              clocks = <&clock 274>, <&clock 273>;
+               samsung,power-domain = <&pd_mfc>;
+               status = "ok";
+       };
+@@ -617,8 +624,8 @@
+               interrupt-parent = <&combiner>;
+               interrupt-names = "sysmmu-mfc-r";
+               interrupts = <5 6>;
+-              clock-names = "sysmmu";
+-              clocks = <&clock 275>;
++              clock-names = "sysmmu", "master";
++              clocks = <&clock 275>, <&clock 273>;
+               samsung,power-domain = <&pd_mfc>;
+               status = "ok";
+       };
+@@ -629,8 +636,8 @@
+               interrupt-parent = <&combiner>;
+               interrupt-names = "sysmmu-tv";
+               interrupts = <5 4>;
+-              clock-names = "sysmmu";
+-              clocks = <&clock 272>;
++              clock-names = "sysmmu", "master";
++              clocks = <&clock 272>, <&clock 269>;
+               samsung,power-domain = <&pd_tv>;
+               status = "ok";
+       };
+@@ -641,8 +648,8 @@
+               interrupt-parent = <&combiner>;
+               interrupt-names = "sysmmu-fimc0";
+               interrupts = <4 2>;
+-              clock-names = "sysmmu";
+-              clocks = <&clock 263>;
++              clock-names = "sysmmu", "master";
++              clocks = <&clock 263>, <&clock 256>;
+               samsung,power-domain = <&pd_cam>;
+               status = "ok";
+       };
+@@ -653,8 +660,8 @@
+               interrupt-parent = <&combiner>;
+               interrupt-names = "sysmmu-fimc1";
+               interrupts = <4 3>;
+-              clock-names = "sysmmu";
+-              clocks = <&clock 264>;
++              clock-names = "sysmmu", "master";
++              clocks = <&clock 264>, <&clock 257>;
+               samsung,power-domain = <&pd_cam>;
+               status = "ok";
+       };
+@@ -665,8 +672,8 @@
+               interrupt-parent = <&combiner>;
+               interrupt-names = "sysmmu-fimc2";
+               interrupts = <4 4>;
+-              clock-names = "sysmmu";
+-              clocks = <&clock 265>;
++              clock-names = "sysmmu", "master";
++              clocks = <&clock 265>, <&clock 258>;
+               samsung,power-domain = <&pd_cam>;
+               status = "ok";
+       };
+@@ -677,8 +684,8 @@
+               interrupt-parent = <&combiner>;
+               interrupt-names = "sysmmu-fimc3";
+               interrupts = <4 5>;
+-              clock-names = "sysmmu";
+-              clocks = <&clock 266>;
++              clock-names = "sysmmu", "master";
++              clocks = <&clock 266>, <&clock 259>;
+               samsung,power-domain = <&pd_cam>;
+               status = "ok";
+       };
+@@ -689,8 +696,8 @@
+               interrupt-parent = <&combiner>;
+               interrupt-names = "sysmmu-jpeg";
+               interrupts = <4 6>;
+-              clock-names = "sysmmu";
+-              clocks = <&clock 267>;
++              clock-names = "sysmmu", "master";
++              clocks = <&clock 267>, <&clock 262>;
+               samsung,power-domain = <&pd_cam>;
+               status = "ok";
+       };
+@@ -701,8 +708,8 @@
+               interrupt-parent = <&combiner>;
+               interrupt-names = "sysmmu-rotator";
+               interrupts = <5 0>;
+-              clock-names = "sysmmu";
+-              clocks = <&clock 281>;
++              clock-names = "sysmmu", "master";
++              clocks = <&clock 281>, <&clock 278>;
+               samsung,power-domain = <&pd_lcd0>;
+               status = "ok";
+       };
+@@ -713,8 +720,8 @@
+               interrupt-parent = <&combiner>;
+               interrupt-names = "sysmmu-fimd0";
+               interrupts = <5 2>;
+-              clock-names = "sysmmu";
+-              clocks = <&clock 287>;
++              clock-names = "sysmmu", "master";
++              clocks = <&clock 287>, <&clock 283>;
+               samsung,power-domain = <&pd_lcd0>;
+               status = "ok";
+       };
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index da3b793..a0d85c3 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -102,8 +102,10 @@
+               compatible = "samsung,exynos4212-g2d";
+               reg = <0x10800000 0x1000>;
+               interrupts = <0 89 0>;
+-              clocks = <&clock 277>;
+-              clock-names = "fimg2d";
++              clocks = <&clock 177>, <&clock 277>;
++              clock-names = "sclk_fimg2d", "fimg2d";
++              samsung,power-domain = <&pd_lcd0>;
++              iommu = <&sysmmu_g2d>;
+               status = "disabled";
+       };
+@@ -113,7 +115,8 @@
+               interrupt-parent = <&combiner>;
+               interrupt-names = "sysmmu-g2d";
+               interrupts = <4 7>;
+-              clock-names = "sysmmu";
++              clocks = <&clock 280>, <&clock 277>;
++              clock-names = "sysmmu", "master";
+               status = "ok";
+       };
+@@ -167,8 +170,9 @@
+               interrupt-parent = <&combiner>;
+               interrupt-names = "sysmmu-fimc_lite0";
+               interrupts = <16 0>;
+-              clock-names = "sysmmu";
+-              clocks = <&clock 366>;
++              clock-names = "sysmmu", "master";
++              clocks = <&clock 366>, <&clock 353>;
++              samsung,power-domain = <&pd_isp>;
+               status = "ok";
+       };
+@@ -178,8 +182,9 @@
+               interrupt-parent = <&combiner>;
+               interrupt-names = "sysmmu-fimc_lite1";
+               interrupts = <16 1>;
+-              clock-names = "sysmmu";
+-              clocks = <&clock 365>;
++              clock-names = "sysmmu", "master";
++              clocks = <&clock 365>, <&clock 354>;
++              samsung,power-domain = <&pd_isp>;
+               status = "ok";
+       };
+@@ -264,6 +269,7 @@
+                       clocks = <&clock 353>;
+                       clock-names = "flite";
+                       status = "disabled";
++                      iommu = <&sysmmu_fimc_lite0>;
+               };
+               fimc_lite_1: fimc-lite@123A0000 {
+@@ -274,6 +280,7 @@
+                       clocks = <&clock 354>;
+                       clock-names = "flite";
+                       status = "disabled";
++                      iommu = <&sysmmu_fimc_lite1>;
+               };
+               fimc_is: fimc-is@12000000 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0573-ARM-Exynos4-dts-disable-CMA-support-for-MFC-obsolete.patch b/patches.tizen/0573-ARM-Exynos4-dts-disable-CMA-support-for-MFC-obsolete.patch
new file mode 100644 (file)
index 0000000..e76cdf5
--- /dev/null
@@ -0,0 +1,33 @@
+From 344cab44ad2a138f7bbdbdfe00e59203f223eeea Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Wed, 21 Aug 2013 13:24:50 +0200
+Subject: [PATCH 0573/1302] ARM: Exynos4: dts: disable CMA support for MFC
+ (obsoleted by IOMMU support)
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 20a5c86..4ef6363 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -215,11 +215,13 @@
+                       mfc_l_mem: mfc_l_region@43000000 {
+                               compatible = "linux,contiguous-memory-region", "reserved-memory-region";
+                               reg = <0x43000000 0x1000000>;
++                              status = "disabled";
+                       };
+                       mfc_r_mem: mfc_r_region@51000000 {
+                               compatible = "linux,contiguous-memory-region", "reserved-memory-region";
+                               reg = <0x51000000 0x1000000>;
++                              status = "disabled";
+                       };
+               };
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0574-ARM-dts-Add-missing-aliases-for-I2C-bus-controllers-.patch b/patches.tizen/0574-ARM-dts-Add-missing-aliases-for-I2C-bus-controllers-.patch
new file mode 100644 (file)
index 0000000..af5e300
--- /dev/null
@@ -0,0 +1,40 @@
+From 68b626c695df4dd054a40b1b9ffa71b55c912279 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 21 Aug 2013 15:28:44 +0200
+Subject: [PATCH 0574/1302] ARM: dts: Add missing aliases for I2C bus
+ controllers in exynos4412-m0.dts
+
+When an I2C bus controller is added without a corresponding entry in
+the aliases node the I2C core uses firs available number as the bus ID
+which may be one of already reserved IDs for other controllers. E.g.
+0...7 are reserved for hardware I2C bus controllers I2C0.I2C7.
+Missing aliases were causing I2C0 bus adapter initialization to fail
+due to bus ID 0 being assigned to one of the i2c-gpio controllers.
+
+Fix this regression by adding corresponding node aliases.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-m0.dts | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-m0.dts b/arch/arm/boot/dts/exynos4412-m0.dts
+index 12c7078..ba9168b 100644
+--- a/arch/arm/boot/dts/exynos4412-m0.dts
++++ b/arch/arm/boot/dts/exynos4412-m0.dts
+@@ -18,7 +18,10 @@
+       model = "Samsung M0 based on Exynos4412";
+       compatible = "samsung,m0", "samsung,exynos4412";
+-      /* Nothing to override here yet. */
++      aliases {
++              i2c20 = &i2c_touch_key;
++              i2c21 = &i2c_cm36651;
++      };
+       pinctrl@11400000 {
+               vt_cam_id: vt-cam-id {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0575-exynos4-is-Fix-compressed-format-setting-in-fimc-cap.patch b/patches.tizen/0575-exynos4-is-Fix-compressed-format-setting-in-fimc-cap.patch
new file mode 100644 (file)
index 0000000..e7cb5fc
--- /dev/null
@@ -0,0 +1,30 @@
+From 7996ab62fbfcbfca981801fba0a85d620ea0c033 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 22 Aug 2013 17:49:18 +0200
+Subject: [PATCH 0575/1302] exynos4-is: Fix compressed format setting in
+ fimc-capture
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-capture.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
+index fb27ff7..e946ba3 100644
+--- a/drivers/media/platform/exynos4-is/fimc-capture.c
++++ b/drivers/media/platform/exynos4-is/fimc-capture.c
+@@ -991,8 +991,8 @@ static int __video_try_or_set_format(struct fimc_dev *fimc,
+               sensor = __fimc_md_get_subdev(ve->pipe, IDX_SENSOR);
+               if (sensor)
+-                      fimc_get_sensor_frame_desc(sensor, pix->plane_fmt,
+-                                                 (*out_fmt)->memplanes, try);
++                      ret = fimc_get_sensor_frame_desc(sensor, pix->plane_fmt,
++                                                 (*out_fmt)->memplanes, true);
+               else
+                       ret = -EPIPE;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0576-s5c73m3-Set-default-data-plane-lengths-for-interleav.patch b/patches.tizen/0576-s5c73m3-Set-default-data-plane-lengths-for-interleav.patch
new file mode 100644 (file)
index 0000000..73902dd
--- /dev/null
@@ -0,0 +1,30 @@
+From ef1d8921b43b3826686fd4e6c1b0b88b2fca250f Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 22 Aug 2013 17:50:41 +0200
+Subject: [PATCH 0576/1302] s5c73m3: Set default data plane lengths for
+ interleaved data
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/s5c73m3/s5c73m3-core.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+index b79e100..1ff7509 100644
+--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
++++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+@@ -1699,6 +1699,10 @@ static int s5c73m3_probe(struct i2c_client *client,
+       state->i2c_client = client;
++      /* Initialize data plane lengths for the interleaved image data. */
++      state->frame_desc.entry[0].length = 10 * SZ_1M;
++      state->frame_desc.entry[1].length = S5C73M3_EMBEDDED_DATA_MAXLEN;
++
+       v4l2_info(sd, "%s: completed succesfully\n", __func__);
+       return 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0577-brcmfmac-Add-generic-platform-support.patch b/patches.tizen/0577-brcmfmac-Add-generic-platform-support.patch
new file mode 100644 (file)
index 0000000..a423a12
--- /dev/null
@@ -0,0 +1,188 @@
+From 978bc9523622248271e4007330ae1a0eee6e0254 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 23 May 2013 13:28:09 +0200
+Subject: [PATCH 0577/1302] brcmfmac: Add generic platform support
+
+This patch adds basic support for generic platforms that do not require
+special platform data.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../bindings/net/wireless/brcm,bcm43xx-fmac.txt    | 41 ++++++++++++
+ .../net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 78 ++++++++++++++++++++++
+ 2 files changed, 119 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt
+
+diff --git a/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt b/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt
+new file mode 100644
+index 0000000..57ca99c
+--- /dev/null
++++ b/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt
+@@ -0,0 +1,41 @@
++Broadcom BCM43xx-series FullMAC WLAN network adapter
++
++Required properties:
++- compatible: should be one of following:
++  - "brcm,bcm43143" - for BCM43134 chip,
++  - "brcm,bcm4324" - for BCM4324 chip,
++  - "brcm,bcm4329" - for BCM4329 chip,
++  - "brcm,bcm4330" - for BCM4330 chip,
++  - "brcm,bcm4334" - for BCM4334 chip,
++  - "brcm,bcm4335" - for BCM4335 chip.
++- wlan-supply: regulator used to control power of WLAN block of the chip.
++
++Optional properties:
++- interrupt-parent: interrupt controller to which the out-of-bound interrupt
++    signal of the chip (usually WL_HOST_WAKE pin) is connected.
++- interrupts: interrupt specifier of the out-of-bound interrupt in format
++    specific to interrupt controller specifiedy by interrupt-parent property.
++- clock-names: Should contain one clock entry - "32khz", which is the external
++    32768 Hz clock used by the chip.
++- clocks: Clock specifiers given in the same order as specified in clock-names
++    property.
++
++Example:
++
++      wlan_reg: voltage-regulator {
++              compatible = "regulator-fixed";
++              regulator-name = "WL_REG_ON";
++              regulator-min-microvolt = <1800000>;
++              regulator-max-microvolt = <1800000>;
++              gpio = <&gpj0 0 0>;
++              enable-active-high;
++      };
++
++      wlan {
++              compatible = "brcm,bcm4334";
++              wlan-supply = <&wlan_reg>;
++              interrupt-parent = <&gpx2>;
++              interrupts = <5 4>;
++              clocks = <&max77686 2>;
++              clock-names = "32khz";
++      };
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+index 0f6eb2b..61c6e67 100644
+--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+@@ -16,17 +16,20 @@
+ #include <linux/types.h>
+ #include <linux/netdevice.h>
++#include <linux/clk-provider.h>
+ #include <linux/mmc/sdio.h>
+ #include <linux/mmc/core.h>
+ #include <linux/mmc/sdio_func.h>
+ #include <linux/mmc/sdio_ids.h>
+ #include <linux/mmc/card.h>
++#include <linux/of.h>
+ #include <linux/suspend.h>
+ #include <linux/errno.h>
+ #include <linux/sched.h>      /* request_irq() */
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/platform_data/brcmfmac-sdio.h>
++#include <linux/regulator/consumer.h>
+ #include <net/cfg80211.h>
+ #include <defs.h>
+@@ -573,11 +576,73 @@ static struct sdio_driver brcmf_sdmmc_driver = {
+ #endif        /* CONFIG_PM_SLEEP */
+ };
++static struct regulator *brcmf_regulator;
++static struct clk *brcmf_clock;
++
++static void brcmf_generic_power_on(void)
++{
++      if (regulator_enable(brcmf_regulator) < 0)
++              pr_warn("%s: failed to enable regulator\n", __func__);
++      if (!IS_ERR(brcmf_clock))
++              clk_prepare_enable(brcmf_clock);
++}
++
++static void brcmf_generic_power_off(void)
++{
++      if (!IS_ERR(brcmf_clock))
++              clk_disable_unprepare(brcmf_clock);
++      regulator_disable(brcmf_regulator);
++}
++
++static void brcmf_generic_reset(void)
++{
++      brcmf_generic_power_off();
++      msleep(10);
++      brcmf_generic_power_on();
++}
++
++static struct brcmfmac_sdio_platform_data *brcmf_generic_pdata(
++                                              struct platform_device *pdev)
++{
++      struct brcmfmac_sdio_platform_data *pdata;
++      struct resource *res;
++
++      pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
++      if (!pdata)
++              return pdata;
++
++      brcmf_regulator = devm_regulator_get(&pdev->dev, "wlan");
++      if (IS_ERR(brcmf_regulator))
++              return NULL;
++
++      brcmf_clock = devm_clk_get(&pdev->dev, "32khz");
++      if (IS_ERR(brcmf_clock))
++              dev_warn(&pdev->dev, "no 32khz clock provided, assuming always on\n");
++
++      res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
++      if (res) {
++              pdata->oob_irq_supported = true;
++              pdata->oob_irq_nr = res->start;
++              pdata->oob_irq_flags = res->flags;
++      }
++
++      pdata->power_on = brcmf_generic_power_on;
++      pdata->power_off = brcmf_generic_power_off;
++      pdata->reset = brcmf_generic_reset;
++
++      return pdata;
++}
++
+ static int brcmf_sdio_pd_probe(struct platform_device *pdev)
+ {
+       brcmf_dbg(SDIO, "Enter\n");
+       brcmfmac_sdio_pdata = pdev->dev.platform_data;
++      if (!brcmfmac_sdio_pdata)
++              brcmfmac_sdio_pdata = brcmf_generic_pdata(pdev);
++
++      if (!brcmfmac_sdio_pdata)
++              return -EINVAL;
+       if (brcmfmac_sdio_pdata->power_on)
+               brcmfmac_sdio_pdata->power_on();
+@@ -597,9 +662,22 @@ static int brcmf_sdio_pd_remove(struct platform_device *pdev)
+       return 0;
+ }
++#ifdef CONFIG_OF
++static struct of_device_id brcmf_sdio_pd_of_match[] = {
++      { .compatible = "brcm,bcm43143", },
++      { .compatible = "brcm,bcm4324", },
++      { .compatible = "brcm,bcm4329", },
++      { .compatible = "brcm,bcm4330", },
++      { .compatible = "brcm,bcm4334", },
++      { .compatible = "brcm,bcm4335", },
++      { /* sentinel */ }
++};
++#endif
++
+ static struct platform_driver brcmf_sdio_pd = {
+       .remove         = brcmf_sdio_pd_remove,
+       .driver         = {
++              .of_match_table = of_match_ptr(brcmf_sdio_pd_of_match),
+               .name   = BRCMFMAC_SDIO_PDATA_NAME
+       }
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0578-clk-max77686-Correct-callback-used-for-checking-cloc.patch b/patches.tizen/0578-clk-max77686-Correct-callback-used-for-checking-cloc.patch
new file mode 100644 (file)
index 0000000..976413c
--- /dev/null
@@ -0,0 +1,42 @@
+From e570c098af68b5ced3abd717bf98328a9dc9e6aa Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 23 Aug 2013 17:24:29 +0200
+Subject: [PATCH 0578/1302] clk: max77686: Correct callback used for checking
+ clock status
+
+Changing status of clock gates in max77686 requires i2c transfers, which
+can sleep, so this is done in prepare and unprepare callbacks. Due to
+this, checking whether whether the clock is ungated must be done
+in is_prepared() callback as well, for consistency.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/clk-max77686.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/clk-max77686.c b/drivers/clk/clk-max77686.c
+index 9f57bc3..e39d463 100644
+--- a/drivers/clk/clk-max77686.c
++++ b/drivers/clk/clk-max77686.c
+@@ -66,7 +66,7 @@ static void max77686_clk_unprepare(struct clk_hw *hw)
+               MAX77686_REG_32KHZ, max77686->mask, ~max77686->mask);
+ }
+-static int max77686_clk_is_enabled(struct clk_hw *hw)
++static int max77686_clk_is_prepared(struct clk_hw *hw)
+ {
+       struct max77686_clk *max77686 = to_max77686_clk(hw);
+       int ret;
+@@ -84,7 +84,7 @@ static int max77686_clk_is_enabled(struct clk_hw *hw)
+ static struct clk_ops max77686_clk_ops = {
+       .prepare        = max77686_clk_prepare,
+       .unprepare      = max77686_clk_unprepare,
+-      .is_enabled     = max77686_clk_is_enabled,
++      .is_prepared    = max77686_clk_is_prepared,
+ };
+ static struct clk_init_data max77686_clks_init[MAX77686_CLKS_NUM] = {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0579-clk-max77686-Provide-.recalc_rate-operation.patch b/patches.tizen/0579-clk-max77686-Provide-.recalc_rate-operation.patch
new file mode 100644 (file)
index 0000000..95404bf
--- /dev/null
@@ -0,0 +1,39 @@
+From 5073000c844c00cf1f69939701a8729c7d58a712 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 23 Aug 2013 18:28:17 +0200
+Subject: [PATCH 0579/1302] clk: max77686: Provide .recalc_rate() operation
+
+It is usually nice to know frequency of a clock, so this patch adds a
+.recalc_rate() callback returning rates of provided clocks.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/clk-max77686.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/clk/clk-max77686.c b/drivers/clk/clk-max77686.c
+index e39d463..e40ecdb 100644
+--- a/drivers/clk/clk-max77686.c
++++ b/drivers/clk/clk-max77686.c
+@@ -81,10 +81,17 @@ static int max77686_clk_is_prepared(struct clk_hw *hw)
+       return val & max77686->mask;
+ }
++static unsigned long max77686_recalc_rate(struct clk_hw *hw,
++                                        unsigned long parent_rate)
++{
++      return 32768;
++}
++
+ static struct clk_ops max77686_clk_ops = {
+       .prepare        = max77686_clk_prepare,
+       .unprepare      = max77686_clk_unprepare,
+       .is_prepared    = max77686_clk_is_prepared,
++      .recalc_rate    = max77686_recalc_rate,
+ };
+ static struct clk_init_data max77686_clks_init[MAX77686_CLKS_NUM] = {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0580-mfd-max77686-Enable-register-cache.patch b/patches.tizen/0580-mfd-max77686-Enable-register-cache.patch
new file mode 100644 (file)
index 0000000..c1e90f1
--- /dev/null
@@ -0,0 +1,50 @@
+From e580fd18f56242cc81c2bc1b7837adf64ba87315 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 23 Aug 2013 18:41:27 +0200
+Subject: [PATCH 0580/1302] mfd: max77686: Enable register cache
+
+This patch enables flat register cache for max77686 PMIC register to
+speed up operations like getting regulator voltage or clock status.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mfd/max77686.c | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c
+index 91c81cd..195ac96 100644
+--- a/drivers/mfd/max77686.c
++++ b/drivers/mfd/max77686.c
+@@ -39,9 +39,28 @@ static struct mfd_cell max77686_devs[] = {
+       { .name = "max77686-rtc", },
+ };
++static bool max77686_volatile(struct device *dev, unsigned int reg)
++{
++      switch (reg) {
++      case MAX77686_REG_INTSRC:
++      case MAX77686_REG_INT1:
++      case MAX77686_REG_INT2:
++      case MAX77686_REG_STATUS1:
++      case MAX77686_REG_STATUS2:
++      case MAX77686_REG_PWRON:
++              return true;
++      default:
++              return false;
++      }
++}
++
+ static struct regmap_config max77686_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
++      .max_register = MAX77686_REG_PMIC_END,
++      .cache_type = REGCACHE_FLAT,
++      .volatile_reg = max77686_volatile,
++      .num_reg_defaults_raw = MAX77686_REG_PMIC_END,
+ };
+ #ifdef CONFIG_OF
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0581-clk-max77686-Refactor-successful-exit-of-probe-funct.patch b/patches.tizen/0581-clk-max77686-Refactor-successful-exit-of-probe-funct.patch
new file mode 100644 (file)
index 0000000..42bd254
--- /dev/null
@@ -0,0 +1,40 @@
+From 86ef77d763c32579731a041c6f838f80dbb45a40 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 23 Aug 2013 18:56:31 +0200
+Subject: [PATCH 0581/1302] clk: max77686: Refactor successful exit of probe
+ function
+
+The function can simply return 0, without jumping to a separate label,
+which does exactly the same. This patch does not introduce any
+functional change, just a clean-up.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/clk-max77686.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/clk/clk-max77686.c b/drivers/clk/clk-max77686.c
+index e40ecdb..5d78460 100644
+--- a/drivers/clk/clk-max77686.c
++++ b/drivers/clk/clk-max77686.c
+@@ -178,7 +178,7 @@ static int max77686_clk_probe(struct platform_device *pdev)
+       platform_set_drvdata(pdev, max77686_clks);
+-      goto out;
++      return 0;
+ err_clk_pmic:
+       clkdev_drop(max77686_clks[MAX77686_CLK_CP]->lookup);
+@@ -187,7 +187,6 @@ err_clk_cp:
+       clkdev_drop(max77686_clks[MAX77686_CLK_AP]->lookup);
+       kfree(max77686_clks[MAX77686_CLK_AP]->hw.clk);
+ err_clk_ap:
+-out:
+       return ret;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0582-clk-max77686-Make-max77686_clk_register-return-struc.patch b/patches.tizen/0582-clk-max77686-Make-max77686_clk_register-return-struc.patch
new file mode 100644 (file)
index 0000000..092a199
--- /dev/null
@@ -0,0 +1,74 @@
+From 01c520d31adda98d287f7e5a1ba24e0dd5f0ee42 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 23 Aug 2013 18:59:40 +0200
+Subject: [PATCH 0582/1302] clk: max77686: Make max77686_clk_register() return
+ struct clk *
+
+As a preparation for further patches, this patch modifies the clock
+registration helper function to return a pointer to the newly registered
+clock. No functional change is done to the driver.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/clk-max77686.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/clk/clk-max77686.c b/drivers/clk/clk-max77686.c
+index 5d78460..2e6ba0e 100644
+--- a/drivers/clk/clk-max77686.c
++++ b/drivers/clk/clk-max77686.c
+@@ -112,27 +112,26 @@ static struct clk_init_data max77686_clks_init[MAX77686_CLKS_NUM] = {
+       },
+ };
+-static int max77686_clk_register(struct device *dev,
++static struct clk *max77686_clk_register(struct device *dev,
+                               struct max77686_clk *max77686)
+ {
+       struct clk *clk;
+       struct clk_hw *hw = &max77686->hw;
+       clk = clk_register(dev, hw);
+-
+       if (IS_ERR(clk))
+-              return -ENOMEM;
++              return clk;
+       max77686->lookup = kzalloc(sizeof(struct clk_lookup), GFP_KERNEL);
+       if (!max77686->lookup)
+-              return -ENOMEM;
++              return ERR_PTR(-ENOMEM);
+       max77686->lookup->con_id = hw->init->name;
+       max77686->lookup->clk = clk;
+       clkdev_add(max77686->lookup);
+-      return 0;
++      return clk;
+ }
+ static int max77686_clk_probe(struct platform_device *pdev)
+@@ -154,12 +153,16 @@ static int max77686_clk_probe(struct platform_device *pdev)
+       }
+       for (i = 0; i < MAX77686_CLKS_NUM; i++) {
++              struct clk *clk;
++
+               max77686_clks[i]->iodev = iodev;
+               max77686_clks[i]->mask = 1 << i;
+               max77686_clks[i]->hw.init = &max77686_clks_init[i];
+-              ret = max77686_clk_register(&pdev->dev, max77686_clks[i]);
+-              if (ret) {
++              clk = max77686_clk_register(&pdev->dev, max77686_clks[i]);
++              if (IS_ERR(clk)) {
++                      ret = PTR_ERR(clk);
++
+                       switch (i) {
+                       case MAX77686_CLK_AP:
+                               dev_err(&pdev->dev, "Fail to register CLK_AP\n");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0583-clk-max77686-Fix-clean-up-in-error-and-remove-paths.patch b/patches.tizen/0583-clk-max77686-Fix-clean-up-in-error-and-remove-paths.patch
new file mode 100644 (file)
index 0000000..7aab5c2
--- /dev/null
@@ -0,0 +1,76 @@
+From 2fc60f58fe4f5d48d61430b37f61ed9f1ffc55de Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 23 Aug 2013 19:03:47 +0200
+Subject: [PATCH 0583/1302] clk: max77686: Fix clean-up in error and remove
+ paths
+
+This patch fixes invalid kfree() and adds missing call to clk_unregister()
+in error and remove paths in max77686_clk_probe(). While at it, error
+handling is also cleaned up.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/clk-max77686.c | 32 ++++++++++----------------------
+ 1 file changed, 10 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/clk/clk-max77686.c b/drivers/clk/clk-max77686.c
+index 2e6ba0e..81b3680 100644
+--- a/drivers/clk/clk-max77686.c
++++ b/drivers/clk/clk-max77686.c
+@@ -162,20 +162,9 @@ static int max77686_clk_probe(struct platform_device *pdev)
+               clk = max77686_clk_register(&pdev->dev, max77686_clks[i]);
+               if (IS_ERR(clk)) {
+                       ret = PTR_ERR(clk);
+-
+-                      switch (i) {
+-                      case MAX77686_CLK_AP:
+-                              dev_err(&pdev->dev, "Fail to register CLK_AP\n");
+-                              goto err_clk_ap;
+-                              break;
+-                      case MAX77686_CLK_CP:
+-                              dev_err(&pdev->dev, "Fail to register CLK_CP\n");
+-                              goto err_clk_cp;
+-                              break;
+-                      case MAX77686_CLK_PMIC:
+-                              dev_err(&pdev->dev, "Fail to register CLK_PMIC\n");
+-                              goto err_clk_pmic;
+-                      }
++                      dev_err(&pdev->dev, "failed to register %s\n",
++                              max77686_clks[i]->hw.init->name);
++                      goto err_clocks;
+               }
+       }
+@@ -183,13 +172,12 @@ static int max77686_clk_probe(struct platform_device *pdev)
+       return 0;
+-err_clk_pmic:
+-      clkdev_drop(max77686_clks[MAX77686_CLK_CP]->lookup);
+-      kfree(max77686_clks[MAX77686_CLK_CP]->hw.clk);
+-err_clk_cp:
+-      clkdev_drop(max77686_clks[MAX77686_CLK_AP]->lookup);
+-      kfree(max77686_clks[MAX77686_CLK_AP]->hw.clk);
+-err_clk_ap:
++err_clocks:
++      for (--i; i >= 0; --i) {
++              clkdev_drop(max77686_clks[i]->lookup);
++              clk_unregister(max77686_clks[i]->hw.clk);
++      }
++
+       return ret;
+ }
+@@ -200,7 +188,7 @@ static int max77686_clk_remove(struct platform_device *pdev)
+       for (i = 0; i < MAX77686_CLKS_NUM; i++) {
+               clkdev_drop(max77686_clks[i]->lookup);
+-              kfree(max77686_clks[i]->hw.clk);
++              clk_unregister(max77686_clks[i]->hw.clk);
+       }
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0584-clk-max77686-Refactor-driver-data-handling.patch b/patches.tizen/0584-clk-max77686-Refactor-driver-data-handling.patch
new file mode 100644 (file)
index 0000000..fcb144c
--- /dev/null
@@ -0,0 +1,85 @@
+From 35d7dccc74184bdead550e6633636504539a0105 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 23 Aug 2013 19:09:41 +0200
+Subject: [PATCH 0584/1302] clk: max77686: Refactor driver data handling
+
+As a prerequisite for further patch adding OF clock provider support to
+the driver, this patch changes the driver to store an array of struct
+clk * as driver data.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/clk-max77686.c | 26 ++++++++++++++------------
+ 1 file changed, 14 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/clk/clk-max77686.c b/drivers/clk/clk-max77686.c
+index 81b3680..3cf38dc 100644
+--- a/drivers/clk/clk-max77686.c
++++ b/drivers/clk/clk-max77686.c
+@@ -137,12 +137,13 @@ static struct clk *max77686_clk_register(struct device *dev,
+ static int max77686_clk_probe(struct platform_device *pdev)
+ {
+       struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent);
+-      struct max77686_clk **max77686_clks;
++      struct max77686_clk *max77686_clks[MAX77686_CLKS_NUM];
++      struct clk **clocks;
+       int i, ret;
+-      max77686_clks = devm_kzalloc(&pdev->dev, sizeof(struct max77686_clk *)
++      clocks = devm_kzalloc(&pdev->dev, sizeof(struct clk *)
+                                       * MAX77686_CLKS_NUM, GFP_KERNEL);
+-      if (!max77686_clks)
++      if (!clocks)
+               return -ENOMEM;
+       for (i = 0; i < MAX77686_CLKS_NUM; i++) {
+@@ -153,22 +154,20 @@ static int max77686_clk_probe(struct platform_device *pdev)
+       }
+       for (i = 0; i < MAX77686_CLKS_NUM; i++) {
+-              struct clk *clk;
+-
+               max77686_clks[i]->iodev = iodev;
+               max77686_clks[i]->mask = 1 << i;
+               max77686_clks[i]->hw.init = &max77686_clks_init[i];
+-              clk = max77686_clk_register(&pdev->dev, max77686_clks[i]);
+-              if (IS_ERR(clk)) {
+-                      ret = PTR_ERR(clk);
++              clocks[i] = max77686_clk_register(&pdev->dev, max77686_clks[i]);
++              if (IS_ERR(clocks[i])) {
++                      ret = PTR_ERR(clocks[i]);
+                       dev_err(&pdev->dev, "failed to register %s\n",
+                               max77686_clks[i]->hw.init->name);
+                       goto err_clocks;
+               }
+       }
+-      platform_set_drvdata(pdev, max77686_clks);
++      platform_set_drvdata(pdev, clocks);
+       return 0;
+@@ -183,12 +182,15 @@ err_clocks:
+ static int max77686_clk_remove(struct platform_device *pdev)
+ {
+-      struct max77686_clk **max77686_clks = platform_get_drvdata(pdev);
++      struct clk **clocks = platform_get_drvdata(pdev);
+       int i;
+       for (i = 0; i < MAX77686_CLKS_NUM; i++) {
+-              clkdev_drop(max77686_clks[i]->lookup);
+-              clk_unregister(max77686_clks[i]->hw.clk);
++              struct clk_hw *hw = __clk_get_hw(clocks[i]);
++              struct max77686_clk *max77686 = to_max77686_clk(hw);
++
++              clkdev_drop(max77686->lookup);
++              clk_unregister(clocks[i]);
+       }
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0585-clk-max77686-Register-OF-clock-provider.patch b/patches.tizen/0585-clk-max77686-Register-OF-clock-provider.patch
new file mode 100644 (file)
index 0000000..7278c5e
--- /dev/null
@@ -0,0 +1,125 @@
+From 8aaa90b911f5a554f4ea1ed18ce55338acb1d717 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Fri, 23 Aug 2013 19:22:21 +0200
+Subject: [PATCH 0585/1302] clk: max77686: Register OF clock provider
+
+If max77686 chip is instantiated from device tree, it is desirable to
+have an OF clock provider to allow device tree based look-up of clocks.
+This patch adds OF clock provider registration to the clk-max77686
+driver.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/clock/maxim,max77686.txt   | 38 ++++++++++++++++++++++
+ Documentation/devicetree/bindings/mfd/max77686.txt |  3 ++
+ drivers/clk/clk-max77686.c                         | 24 ++++++++++++++
+ 3 files changed, 65 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/clock/maxim,max77686.txt
+
+diff --git a/Documentation/devicetree/bindings/clock/maxim,max77686.txt b/Documentation/devicetree/bindings/clock/maxim,max77686.txt
+new file mode 100644
+index 0000000..96ce71b
+--- /dev/null
++++ b/Documentation/devicetree/bindings/clock/maxim,max77686.txt
+@@ -0,0 +1,38 @@
++Binding for Maxim MAX77686 32k clock generator block
++
++This is a part of device tree bindings of MAX77686 multi-function device.
++More information can be found in bindings/mfd/max77686.txt file.
++
++The MAX77686 contains three 32.768khz clock outputs that can be controlled
++(gated/ungated) over I2C.
++
++Following properties should be presend in main device node of the MFD chip.
++
++Required properties:
++- #clock-cells: simple one-cell clock specifier format is used, where the
++  only cell is used as an index of the clock inside the provider. Following
++  indices are allowed:
++    - 0: 32khz_ap clock,
++    - 1: 32khz_cp clock,
++    - 2: 32khz_pmic clock.
++
++Example: Node of the MFD chip
++
++      max77686: max77686@09 {
++              compatible = "maxim,max77686";
++              interrupt-parent = <&wakeup_eint>;
++              interrupts = <26 0>;
++              reg = <0x09>;
++              #clock-cells = <1>;
++
++              /* ... */
++      };
++
++Example: Clock consumer node
++
++      foo@0 {
++              compatible = "bar,foo";
++              /* ... */
++              clock-names = "my-clock";
++              clocks = <&max77686 2>;
++      };
+diff --git a/Documentation/devicetree/bindings/mfd/max77686.txt b/Documentation/devicetree/bindings/mfd/max77686.txt
+index c6a3469..678f3cf 100644
+--- a/Documentation/devicetree/bindings/mfd/max77686.txt
++++ b/Documentation/devicetree/bindings/mfd/max77686.txt
+@@ -7,6 +7,9 @@ different i2c slave address,presently for which we are statically creating i2c
+ client while probing.This document describes the binding for mfd device and
+ PMIC submodule.
++Binding for the built-in 32k clock generator block is defined separately
++in bindings/clk/maxim,max77686.txt file.
++
+ Required properties:
+ - compatible : Must be "maxim,max77686";
+ - reg : Specifies the i2c slave address of PMIC block.
+diff --git a/drivers/clk/clk-max77686.c b/drivers/clk/clk-max77686.c
+index 3cf38dc..3d7e8dd 100644
+--- a/drivers/clk/clk-max77686.c
++++ b/drivers/clk/clk-max77686.c
+@@ -169,6 +169,26 @@ static int max77686_clk_probe(struct platform_device *pdev)
+       platform_set_drvdata(pdev, clocks);
++      if (iodev->dev->of_node) {
++              struct clk_onecell_data *of_data;
++
++              of_data = devm_kzalloc(&pdev->dev,
++                                      sizeof(*of_data), GFP_KERNEL);
++              if (!of_data) {
++                      ret = -ENOMEM;
++                      goto err_clocks;
++              }
++
++              of_data->clks = clocks;
++              of_data->clk_num = MAX77686_CLKS_NUM;
++              ret = of_clk_add_provider(iodev->dev->of_node,
++                                      of_clk_src_onecell_get, of_data);
++              if (ret) {
++                      dev_err(&pdev->dev, "failed to register OF clock provider\n");
++                      goto err_clocks;
++              }
++      }
++
+       return 0;
+ err_clocks:
+@@ -182,9 +202,13 @@ err_clocks:
+ static int max77686_clk_remove(struct platform_device *pdev)
+ {
++      struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent);
+       struct clk **clocks = platform_get_drvdata(pdev);
+       int i;
++      if (iodev->dev->of_node)
++              of_clk_del_provider(iodev->dev->of_node);
++
+       for (i = 0; i < MAX77686_CLKS_NUM; i++) {
+               struct clk_hw *hw = __clk_get_hw(clocks[i]);
+               struct max77686_clk *max77686 = to_max77686_clk(hw);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0586-of-irq-Pass-trigger-type-in-IRQ-resource-flags.patch b/patches.tizen/0586-of-irq-Pass-trigger-type-in-IRQ-resource-flags.patch
new file mode 100644 (file)
index 0000000..804196f
--- /dev/null
@@ -0,0 +1,46 @@
+From 943c6cbe71b4ed6efd3f89313f6eb5bc535e9e55 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <tomasz.figa@gmail.com>
+Date: Sun, 21 Apr 2013 01:56:00 +0200
+Subject: [PATCH 0586/1302] of: irq: Pass trigger type in IRQ resource flags
+
+Some drivers might rely on availability of trigger flags in IRQ
+resource, for example to configure the hardware for particular interrupt
+type. However current code creating IRQ resources from data in device
+tree does not configure trigger flags in resulting resources.
+
+This patch tries to solve the problem, based on the fact that
+irq_of_parse_and_map() configures the trigger based on DT interrupt
+specifier and IRQD_TRIGGER_* flags are consistent with IORESOURCE_IRQ_*,
+and we can get correct trigger flags by calling irqd_get_trigger_type()
+after mapping the interrupt.
+
+Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/of/irq.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/of/irq.c b/drivers/of/irq.c
+index a3c1c5a..79a7a26 100644
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -355,6 +355,16 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
+               r->start = r->end = irq;
+               r->flags = IORESOURCE_IRQ;
+               r->name = name ? name : dev->full_name;
++
++              /*
++               * Some drivers might rely on availability of trigger flags
++               * in IRQ resource. Since irq_of_parse_and_map() configures the
++               * trigger based on interrupt specifier and IRQD_TRIGGER_*
++               * flags are consistent with IORESOURCE_IRQ_*, we can get
++               * trigger type that was just set and pass it through resource
++               * flags as well.
++               */
++              r->flags |= irqd_get_trigger_type(irq_get_irq_data(irq));
+       }
+       return irq;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0587-ARM-dts-exynos4412-slp_pq-Allow-using-max77686-as-cl.patch b/patches.tizen/0587-ARM-dts-exynos4412-slp_pq-Allow-using-max77686-as-cl.patch
new file mode 100644 (file)
index 0000000..09ee69c
--- /dev/null
@@ -0,0 +1,36 @@
+From c926c8e20805a214869167574ce13df3afb7c38b Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Mon, 26 Aug 2013 17:01:04 +0200
+Subject: [PATCH 0587/1302] ARM: dts: exynos4412-slp_pq: Allow using max77686
+ as clock provider
+
+This patch adds #clock-cells property and label to the node of max77686
+to enable using it as a clock provider.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 4ef6363..add9306 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -549,11 +549,12 @@
+               pinctrl-names = "default";
+               status = "okay";
+-              max77686_pmic@09 {
++              max77686: max77686_pmic@09 {
+                       compatible = "maxim,max77686";
+                       interrupt-parent = <&gpx0>;
+                       interrupts = <7 0>;
+                       reg = <0x09>;
++                      #clock-cells = <1>;
+                       voltage-regulators {
+                               ldo1_reg: ldo@1 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0588-ARM-dts-exynos4412-slp_pq-Enable-WLAN-chip.patch b/patches.tizen/0588-ARM-dts-exynos4412-slp_pq-Enable-WLAN-chip.patch
new file mode 100644 (file)
index 0000000..5819f37
--- /dev/null
@@ -0,0 +1,73 @@
+From d86e95e588f18ff9f44278cc511e801341c0dd68 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Mon, 26 Aug 2013 17:08:10 +0200
+Subject: [PATCH 0588/1302] ARM: dts: exynos4412-slp_pq: Enable WLAN chip
+
+This patch adds required device tree nodes to enable support for BCM4334
+WLAN chip present on SLP PQ based boards.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 40 +++++++++++++++++++++++++++++++++
+ 1 file changed, 40 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index add9306..7a82690 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -1256,6 +1256,41 @@
+               status = "okay";
+               vinchg1-supply = <&charger_reg>;
+       };
++
++      fixed-regulators {
++              compatible = "simple-bus";
++              #address-cells = <1>;
++              #size-cells = <0>;
++
++              wlan_reg: voltage-regulator@7 {
++                      compatible = "regulator-fixed";
++                      reg = <7>;
++                      regulator-name = "WL_REG_ON";
++                      regulator-min-microvolt = <1800000>;
++                      regulator-max-microvolt = <1800000>;
++                      gpio = <&gpj0 0 0>;
++                      enable-active-high;
++              };
++      };
++
++      wlan {
++              compatible = "brcm,bcm4334";
++              wlan-supply = <&wlan_reg>;
++              interrupt-parent = <&gpx2>;
++              interrupts = <5 4>;
++              clocks = <&max77686 2>;
++              clock-names = "32khz";
++              pinctrl-names = "default";
++              pinctrl-0 = <&wlan_int>;
++      };
++
++      sdhci@12540000 {
++              bus-width = <4>;
++              broken-cd;
++              pinctrl-0 = <&sd3_clk &sd3_cmd &sd3_bus4>;
++              pinctrl-names = "default";
++              status = "okay";
++      };
+ };
+ &pinctrl_1 {
+@@ -1267,4 +1302,9 @@
+               samsung,pins = "gpx1-6", "gpx1-1", "gpx1-2";
+               samsung,pin-pud = <1>;
+       };
++
++      wlan_int: wlan-irq {
++              samsung,pins = "gpx2-5";
++              samsung,pin-pud = <1>;
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0589-s5p-jpeg-Add-initial-device-tree-support-for-S5PV210.patch b/patches.tizen/0589-s5p-jpeg-Add-initial-device-tree-support-for-S5PV210.patch
new file mode 100644 (file)
index 0000000..1c095b0
--- /dev/null
@@ -0,0 +1,78 @@
+From 2481bf1ccce6e14cb0939ffd51a3312d0394786b Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
+Date: Sun, 18 Aug 2013 19:14:27 +0000
+Subject: [PATCH 0589/1302] s5p-jpeg: Add initial device tree support for
+ S5PV210/Exynos4210 SoCs
+
+This patch enables the JPEG codec on S5PV210 and Exynos4210 SoCs. There are
+some differences in newer versions of the JPEG codec IP on SoCs like Exynos4x12
+and Exynos5 series and support for them will be added in subsequent patches.
+
+Cc: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Acked-by: Stephen Warren <swarren@nvidia.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/media/exynos-jpeg-codec.txt          | 11 +++++++++++
+ drivers/media/platform/s5p-jpeg/jpeg-core.c                  | 12 +++++++++++-
+ 2 files changed, 22 insertions(+), 1 deletion(-)
+ create mode 100644 Documentation/devicetree/bindings/media/exynos-jpeg-codec.txt
+
+diff --git a/Documentation/devicetree/bindings/media/exynos-jpeg-codec.txt b/Documentation/devicetree/bindings/media/exynos-jpeg-codec.txt
+new file mode 100644
+index 0000000..937b755
+--- /dev/null
++++ b/Documentation/devicetree/bindings/media/exynos-jpeg-codec.txt
+@@ -0,0 +1,11 @@
++Samsung S5P/EXYNOS SoC series JPEG codec
++
++Required properties:
++
++- compatible  : should be one of:
++                "samsung,s5pv210-jpeg", "samsung,exynos4210-jpeg";
++- reg         : address and length of the JPEG codec IP register set;
++- interrupts  : specifies the JPEG codec IP interrupt;
++- clocks      : should contain the JPEG codec IP gate clock specifier, from the
++                common clock bindings;
++- clock-names : should contain "jpeg" entry.
+diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c
+index 15d2396..88c5beb 100644
+--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
++++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
+@@ -17,6 +17,7 @@
+ #include <linux/io.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
++#include <linux/of.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/slab.h>
+@@ -1513,10 +1514,20 @@ static const struct dev_pm_ops s5p_jpeg_pm_ops = {
+       .runtime_resume  = s5p_jpeg_runtime_resume,
+ };
++#ifdef CONFIG_OF
++static const struct of_device_id s5p_jpeg_of_match[] = {
++      { .compatible = "samsung,s5pv210-jpeg" },
++      { .compatible = "samsung,exynos4210-jpeg" },
++      { /* sentinel */ },
++};
++MODULE_DEVICE_TABLE(of, s5p_jpeg_of_match);
++#endif
++
+ static struct platform_driver s5p_jpeg_driver = {
+       .probe = s5p_jpeg_probe,
+       .remove = s5p_jpeg_remove,
+       .driver = {
++              .of_match_table = of_match_ptr(s5p_jpeg_of_match),
+               .owner = THIS_MODULE,
+               .name = S5P_JPEG_M2M_NAME,
+               .pm = &s5p_jpeg_pm_ops,
+@@ -1528,4 +1539,3 @@ module_platform_driver(s5p_jpeg_driver);
+ MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzej.p@samsung.com>");
+ MODULE_DESCRIPTION("Samsung JPEG codec driver");
+ MODULE_LICENSE("GPL");
+-
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0590-ARM-dts-exynos4412-slp_pq-always-turn-on-ESAFEOUT1.patch b/patches.tizen/0590-ARM-dts-exynos4412-slp_pq-always-turn-on-ESAFEOUT1.patch
new file mode 100644 (file)
index 0000000..f8e2e78
--- /dev/null
@@ -0,0 +1,33 @@
+From 1b4c39a6c58a18bba523be996b80022c4d08ced6 Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Thu, 29 Aug 2013 21:38:41 +0900
+Subject: [PATCH 0590/1302] ARM: dts: exynos4412-slp_pq: always turn on
+ ESAFEOUT1
+
+This patch is only WIP(work-in-progress) patch. Max77693's ESAFEOUT1 is used
+for AP-USB VBUS. To enable USB for AP, it should be turned on always or when
+a cable is connected. Extcon driver can detect the cable status, so ESAFEOUT1
+can be brought up by the extcon. Until supporting it, we should turn ESAFEOUT1
+on boot time.
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 7a82690..729e3c2 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -879,6 +879,7 @@
+                               esafeout1_reg: esafeout@1 {
+                                       regulator-compatible = "ESAFEOUT1";
+                                       regulator-name = "ESAFEOUT1";
++                                      regulator-always-on;
+                                       regulator-boot-on;
+                               };
+                               esafeout2_reg: esafeout@2 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0591-dmabuf-sync-update-it-to-patch-v8.patch b/patches.tizen/0591-dmabuf-sync-update-it-to-patch-v8.patch
new file mode 100644 (file)
index 0000000..83a05a0
--- /dev/null
@@ -0,0 +1,1209 @@
+From f3dce49058a1c4650cafabf425c03bbaa8369ae1 Mon Sep 17 00:00:00 2001
+From: Inki Dae <inki.dae@samsung.com>
+Date: Fri, 30 Aug 2013 15:56:59 +0900
+Subject: [PATCH 0591/1302] dmabuf-sync: update it to patch v8
+
+- Consider the write-and-then-read ordering.
+  The ordering issue means that a task don't take a lock to the dmabuf
+  so this task would be stalled even though this task requested a lock
+  to the dmabuf between other task unlocked and tries to lock the dmabuf
+  again. For this, it addes a wait event mechanism using only generic
+  APIs, wait_event_timeout and wake_up functions.
+
+  The below is how to handle the ordering issue using this mechanism:
+  1. Check if there is a sync object added prior to current task's one.
+  2. If exists, it unlocks the dmabuf so that other task can take a lock
+     to the dmabuf first.
+  3. Wait for the wake up event from other task: current task will be
+     waked up when other task unlocks the dmabuf.
+  4. Take a lock to the dmabuf again.
+- Update Document
+- Code cleanups.
+
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/dma-buf-sync.txt          | 100 +++----
+ drivers/base/dmabuf-sync.c              | 502 +++++++++++++++++++++++++-------
+ drivers/gpu/drm/exynos/exynos_drm_g2d.c |   2 +-
+ include/linux/dmabuf-sync.h             |  93 +++++-
+ 4 files changed, 518 insertions(+), 179 deletions(-)
+
+diff --git a/Documentation/dma-buf-sync.txt b/Documentation/dma-buf-sync.txt
+index 4427759..5945c8a 100644
+--- a/Documentation/dma-buf-sync.txt
++++ b/Documentation/dma-buf-sync.txt
+@@ -53,50 +53,6 @@ What is the best way to solve these buffer synchronization issues?
+       Now we have already been using the dma-buf to share one buffer with
+       other drivers.
+-How we can utilize multi threads for more performance?
+-      DMA and CPU works individually. So CPU could perform other works while
+-      DMA are performing some works, and vise versa.
+-      However, in the conventional way, that is not easy to do so because
+-      DMA operation is depend on CPU operation, and vice versa.
+-
+-      Conventional way:
+-        User                                     Kernel
+-        ---------------------------------------------------------------------
+-        CPU writes something to src
+-        send the src to driver------------------------->
+-                                                 update DMA register
+-        request DMA start(1)--------------------------->
+-                                                 DMA start
+-                <---------completion signal(2)----------
+-        CPU accesses dst
+-
+-        (1) Request DMA start after the CPU access to src buffer is completed.
+-        (2) Access dst buffer after DMA access to the dst buffer is completed.
+-
+-On the other hand, if there is something to control buffer access between CPU
+-and DMA? The below shows that:
+-
+-        User(thread a)          User(thread b)            Kernel
+-        ---------------------------------------------------------------------
+-        send a src to driver---------------------------------->
+-                                                          update DMA register
+-        lock the src
+-                                request DMA start(1)---------->
+-        CPU acccess to src
+-        unlock the src                                    lock src and dst
+-                                                          DMA start
+-                <-------------completion signal(2)-------------
+-        lock dst                                          DMA completion
+-        CPU access to dst                                 unlock src and dst
+-        unlock DST
+-
+-        (1) Try to start DMA operation while CPU is accessing the src buffer.
+-        (2) Try CPU access to dst buffer while DMA is accessing the dst buffer.
+-
+-      In the same way, we could reduce hand shaking overhead between
+-      two processes when those processes need to share a shared buffer.
+-      There may be other cases that we could reduce overhead as well.
+-
+ Basic concept
+ -------------
+@@ -172,10 +128,12 @@ DMA_BUF_ACCESS_DMA_W - DMA will access a buffer for read or write.
+ Generic user interfaces
+ -----------------------
+-And this framework includes fcntl system call[3] as interfaces exported
+-to user. As you know, user sees a buffer object as a dma-buf file descriptor.
+-So fcntl() call with the file descriptor means to lock some buffer region being
+-managed by the dma-buf object.
++And this framework includes fcntl[3] and select system calls as interfaces
++exported to user. As you know, user sees a buffer object as a dma-buf file
++descriptor. fcntl() call with the file descriptor means to lock some buffer
++region being managed by the dma-buf object. And select call with the file
++descriptor means to poll the completion event of CPU or DMA access to
++the dma-buf.
+ API set
+@@ -184,10 +142,14 @@ API set
+ bool is_dmabuf_sync_supported(void)
+       - Check if dmabuf sync is supported or not.
+-struct dmabuf_sync *dmabuf_sync_init(void *priv, const char *name)
++struct dmabuf_sync *dmabuf_sync_init(const char *name,
++                                      struct dmabuf_sync_priv_ops *ops,
++                                      void priv*)
+       - Allocate and initialize a new sync object. The caller can get a new
+-      sync object for buffer synchronization. priv is used to set caller's
+-      private data and name is the name of sync object.
++      sync object for buffer synchronization. ops is used for device driver
++      to clean up its own sync object. For this, each device driver should
++      implement a free callback. priv is used for device driver to get its
++      device context when free callback is called.
+ void dmabuf_sync_fini(struct dmabuf_sync *sync)
+       - Release all resources to the sync object.
+@@ -235,9 +197,25 @@ Tutorial for device driver
+ --------------------------
+ 1. Allocate and Initialize a sync object:
++      static void xxx_dmabuf_sync_free(void *priv)
++      {
++              struct xxx_context *ctx = priv;
++
++              if (!ctx)
++                      return;
++
++              ctx->sync = NULL;
++      }
++      ...
++
++      static struct dmabuf_sync_priv_ops driver_specific_ops = {
++              .free = xxx_dmabuf_sync_free,
++      };
++      ...
++
+       struct dmabuf_sync *sync;
+-      sync = dmabuf_sync_init(NULL, "test sync");
++      sync = dmabuf_sync_init("test sync", &driver_specific_ops, ctx);
+       ...
+ 2. Add a dmabuf to the sync object when setting up dma buffer relevant registers:
+@@ -261,6 +239,8 @@ Tutorial for device driver
+ Tutorial for user application
+ -----------------------------
++fcntl system call:
++
+       struct flock filelock;
+ 1. Lock a dma buf:
+@@ -284,6 +264,22 @@ Tutorial for user application
+       detail, please refer to [3]
++select system call:
++
++      fd_set wdfs or rdfs;
++
++      FD_ZERO(&wdfs or &rdfs);
++      FD_SET(fd, &wdfs or &rdfs);
++
++      select(fd + 1, &rdfs, NULL, NULL, NULL);
++              or
++      select(fd + 1, NULL, &wdfs, NULL, NULL);
++
++      Every time select system call is called, a caller will wait for
++      the completion of DMA or CPU access to a shared buffer if there
++      is someone accessing the shared buffer. If no anyone then select
++      system call will be returned at once.
++
+ References:
+ [1] http://lwn.net/Articles/470339/
+ [2] https://patchwork.kernel.org/patch/2625361/
+diff --git a/drivers/base/dmabuf-sync.c b/drivers/base/dmabuf-sync.c
+index dab5b32..288aaff 100644
+--- a/drivers/base/dmabuf-sync.c
++++ b/drivers/base/dmabuf-sync.c
+@@ -18,9 +18,8 @@
+ #include <linux/dmabuf-sync.h>
+-#define MAX_SYNC_TIMEOUT      5 /* Second. */
+-
+-int dmabuf_sync_enabled = 1;
++#define MAX_SYNC_TIMEOUT      5       /* Second. */
++#define MAX_WAIT_TIMEOUT      2000    /* Millisecond. */
+ #define NEED_BEGIN_CPU_ACCESS(old, new_type)  \
+                       ((old->accessed_type & DMA_BUF_ACCESS_DMA_W) == \
+@@ -31,11 +30,31 @@ int dmabuf_sync_enabled = 1;
+                        (old->accessed_type == DMA_BUF_ACCESS_RW)) && \
+                        new_type & DMA_BUF_ACCESS_DMA)
++#define WAKE_UP_SYNC_OBJ(obj) {                                               \
++              if (obj->waiting) {                                     \
++                      obj->waiting = false;                           \
++                      wake_up(&obj->wq);                              \
++              }                                                       \
++      }
++
++#define DEL_OBJ_FROM_RSV(obj, rsv) {                                  \
++              struct dmabuf_sync_object *e, *n;                       \
++                                                                      \
++              list_for_each_entry_safe(e, n, &rsv->syncs, r_head) {   \
++                      if (e == obj && !e->task) {                     \
++                              list_del_init(&e->r_head);              \
++                              break;                                  \
++                      }                                               \
++              }                                                       \
++      }
++
++int dmabuf_sync_enabled = 1;
++
+ MODULE_PARM_DESC(enabled, "Check if dmabuf sync is supported or not");
+ module_param_named(enabled, dmabuf_sync_enabled, int, 0444);
+ DEFINE_WW_CLASS(dmabuf_sync_ww_class);
+-EXPORT_SYMBOL(dmabuf_sync_ww_class);
++EXPORT_SYMBOL_GPL(dmabuf_sync_ww_class);
+ static void dmabuf_sync_timeout_worker(struct work_struct *work)
+ {
+@@ -45,50 +64,61 @@ static void dmabuf_sync_timeout_worker(struct work_struct *work)
+       mutex_lock(&sync->lock);
+       list_for_each_entry(sobj, &sync->syncs, head) {
+-              if (WARN_ON(!sobj->robj))
+-                      continue;
++              struct dmabuf_sync_reservation *rsvp = sobj->robj;
+-              mutex_lock(&sobj->robj->lock);
++              mutex_lock(&rsvp->lock);
+-              printk(KERN_WARNING "%s: timeout = 0x%x [type = %d, " \
++              pr_warn("%s: timeout = 0x%p [type = %d:%d, "
+                                       "refcnt = %d, locked = %d]\n",
+-                                      sync->name, (u32)sobj->dmabuf,
++                                      sync->name, sobj->dmabuf,
++                                      rsvp->accessed_type,
+                                       sobj->access_type,
+-                                      atomic_read(&sobj->robj->shared_cnt),
+-                                      sobj->robj->locked);
++                                      atomic_read(&rsvp->shared_cnt),
++                                      rsvp->locked);
+-              /* unlock only valid sync object. */
+-              if (!sobj->robj->locked) {
+-                      mutex_unlock(&sobj->robj->lock);
+-                      continue;
++              if (rsvp->polled) {
++                      rsvp->poll_event = true;
++                      rsvp->polled = false;
++                      wake_up_interruptible(&rsvp->poll_wait);
+               }
+-              if (sobj->robj->polled) {
+-                      sobj->robj->poll_event = true;
+-                      sobj->robj->polled = false;
+-                      wake_up_interruptible(&sobj->robj->poll_wait);
+-              }
++              /*
++               * Wake up a task blocked by dmabuf_sync_wait_prev_objs().
++               *
++               * If sobj->waiting is true, the task is waiting for the wake
++               * up event so wake up the task if a given time period is
++               * elapsed and current task is timed out.
++               */
++              WAKE_UP_SYNC_OBJ(sobj);
+-              if (atomic_add_unless(&sobj->robj->shared_cnt, -1, 1)) {
+-                      mutex_unlock(&sobj->robj->lock);
++              /* Delete a sync object from reservation object of dmabuf. */
++              DEL_OBJ_FROM_RSV(sobj, rsvp);
++
++              if (atomic_add_unless(&rsvp->shared_cnt, -1, 1)) {
++                      mutex_unlock(&rsvp->lock);
+                       continue;
+               }
+-              mutex_unlock(&sobj->robj->lock);
++              /* unlock only valid sync object. */
++              if (!rsvp->locked) {
++                      mutex_unlock(&rsvp->lock);
++                      continue;
++              }
+-              ww_mutex_unlock(&sobj->robj->sync_lock);
++              mutex_unlock(&rsvp->lock);
++              ww_mutex_unlock(&rsvp->sync_lock);
+-              mutex_lock(&sobj->robj->lock);
+-              sobj->robj->locked = false;
++              mutex_lock(&rsvp->lock);
++              rsvp->locked = false;
+               if (sobj->access_type & DMA_BUF_ACCESS_R)
+-                      printk(KERN_WARNING "%s: r-unlocked = 0x%x\n",
+-                                      sync->name, (u32)sobj->dmabuf);
++                      pr_warn("%s: r-unlocked = 0x%p\n",
++                                      sync->name, sobj->dmabuf);
+               else
+-                      printk(KERN_WARNING "%s: w-unlocked = 0x%x\n",
+-                                      sync->name, (u32)sobj->dmabuf);
++                      pr_warn("%s: w-unlocked = 0x%p\n",
++                                      sync->name, sobj->dmabuf);
+-              mutex_unlock(&sobj->robj->lock);
++              mutex_unlock(&rsvp->lock);
+       }
+       sync->status = 0;
+@@ -167,6 +197,99 @@ static void dmabuf_sync_lock_timeout(unsigned long arg)
+       schedule_work(&sync->work);
+ }
++static void dmabuf_sync_wait_prev_objs(struct dmabuf_sync_object *sobj,
++                                      struct dmabuf_sync_reservation *rsvp,
++                                      struct ww_acquire_ctx *ctx)
++{
++      mutex_lock(&rsvp->lock);
++
++      /*
++       * This function handles the write-and-then-read ordering issue.
++       *
++       * The ordering issue:
++       * There is a case that a task don't take a lock to a dmabuf so
++       * this task would be stalled even though this task requested a lock
++       * to the dmabuf between other task unlocked and tries to lock
++       * the dmabuf again.
++       *
++       * How to handle the ordering issue:
++       * 1. Check if there is a sync object added prior to current task's one.
++       * 2. If exists, it unlocks the dmabuf so that other task can take
++       *      a lock to the dmabuf first.
++       * 3. Wait for the wake up event from other task: current task will be
++       *      waked up when other task unlocks the dmabuf.
++       * 4. Take a lock to the dmabuf again.
++       */
++      if (!list_empty(&rsvp->syncs)) {
++              struct dmabuf_sync_object *r_sobj, *next;
++
++              list_for_each_entry_safe(r_sobj, next, &rsvp->syncs,
++                                      r_head) {
++                      long timeout;
++
++                      /*
++                       * Find a sync object added to rsvp->syncs by other task
++                       * before current task tries to lock the dmabuf again.
++                       * If sobj == r_sobj, it means that there is no any task
++                       * that added its own sync object to rsvp->syncs so out
++                       * of this loop.
++                       */
++                      if (sobj == r_sobj)
++                              break;
++
++                      /*
++                       * Unlock the dmabuf if there is a sync object added
++                       * to rsvp->syncs so that other task can take a lock
++                       * first.
++                       */
++                      if (rsvp->locked) {
++                              ww_mutex_unlock(&rsvp->sync_lock);
++                              rsvp->locked = false;
++                      }
++
++                      r_sobj->waiting = true;
++
++                      atomic_inc(&r_sobj->refcnt);
++                      mutex_unlock(&rsvp->lock);
++
++                      /* Wait for the wake up event from other task. */
++                      timeout = wait_event_timeout(r_sobj->wq,
++                                      !r_sobj->waiting,
++                                      msecs_to_jiffies(MAX_WAIT_TIMEOUT));
++                      if (!timeout) {
++                              r_sobj->waiting = false;
++                              pr_warn("wait event timeout: sobj = 0x%p\n",
++                                              r_sobj);
++
++                              /*
++                               * A sync object from fcntl system call has no
++                               * timeout handler so delete ane free r_sobj
++                               * once timeout here without checking refcnt.
++                               */
++                              if (r_sobj->task) {
++                                      pr_warn("delete: user sobj = 0x%p\n",
++                                                      r_sobj);
++                                      list_del_init(&r_sobj->r_head);
++                                      kfree(r_sobj);
++                              }
++                      }
++
++                      if (!atomic_add_unless(&r_sobj->refcnt, -1, 1))
++                              kfree(r_sobj);
++
++                      /*
++                       * Other task unlocked the dmabuf so take a lock again.
++                       */
++                      ww_mutex_lock(&rsvp->sync_lock, ctx);
++
++                      mutex_lock(&rsvp->lock);
++                      rsvp->locked = true;
++              }
++      }
++
++      mutex_unlock(&rsvp->lock);
++}
++
+ static int dmabuf_sync_lock_objs(struct dmabuf_sync *sync,
+                                       struct ww_acquire_ctx *ctx)
+ {
+@@ -180,41 +303,58 @@ static int dmabuf_sync_lock_objs(struct dmabuf_sync *sync,
+ retry:
+       list_for_each_entry(sobj, &sync->syncs, head) {
+-              if (WARN_ON(!sobj->robj))
++              struct dmabuf_sync_reservation *rsvp = sobj->robj;
++
++              if (WARN_ON(!rsvp))
+                       continue;
+-              mutex_lock(&sobj->robj->lock);
++              mutex_lock(&rsvp->lock);
++
++              /*
++               * Add a sync object to reservation object of dmabuf
++               * to handle the write-and-then-read ordering issue.
++               *
++               * For more details, see dmabuf_sync_wait_prev_objs function.
++               */
++              list_add_tail(&sobj->r_head, &rsvp->syncs);
+               /* Don't lock in case of read and read. */
+-              if (sobj->robj->accessed_type & DMA_BUF_ACCESS_R &&
++              if (rsvp->accessed_type & DMA_BUF_ACCESS_R &&
+                   sobj->access_type & DMA_BUF_ACCESS_R) {
+-                      atomic_inc(&sobj->robj->shared_cnt);
+-                      mutex_unlock(&sobj->robj->lock);
++                      atomic_inc(&rsvp->shared_cnt);
++                      mutex_unlock(&rsvp->lock);
+                       continue;
+               }
+               if (sobj == res_sobj) {
+                       res_sobj = NULL;
+-                      mutex_unlock(&sobj->robj->lock);
++                      mutex_unlock(&rsvp->lock);
+                       continue;
+               }
+-              mutex_unlock(&sobj->robj->lock);
++              mutex_unlock(&rsvp->lock);
+-              ret = ww_mutex_lock(&sobj->robj->sync_lock, ctx);
++              ret = ww_mutex_lock(&rsvp->sync_lock, ctx);
+               if (ret < 0) {
+                       contended_sobj = sobj;
+                       if (ret == -EDEADLK)
+-                              printk(KERN_WARNING"%s: deadlock = 0x%x\n",
+-                                      sync->name, (u32)sobj->dmabuf);
++                              pr_warn("%s: deadlock = 0x%p\n",
++                                      sync->name, sobj->dmabuf);
+                       goto err;
+               }
+-              mutex_lock(&sobj->robj->lock);
+-              sobj->robj->locked = true;
+-
+-              mutex_unlock(&sobj->robj->lock);
++              mutex_lock(&rsvp->lock);
++              rsvp->locked = true;
++              mutex_unlock(&rsvp->lock);
++
++              /*
++               * Check if there is a sync object added to reservation object
++               * of dmabuf before current task takes a lock to the dmabuf.
++               * And ithen wait for the for the wake up event from other task
++               * if exists.
++               */
++              dmabuf_sync_wait_prev_objs(sobj, rsvp, ctx);
+       }
+       if (ctx)
+@@ -232,29 +372,52 @@ retry:
+ err:
+       list_for_each_entry_continue_reverse(sobj, &sync->syncs, head) {
+-              mutex_lock(&sobj->robj->lock);
++              struct dmabuf_sync_reservation *rsvp = sobj->robj;
++
++              mutex_lock(&rsvp->lock);
+               /* Don't need to unlock in case of read and read. */
+-              if (atomic_add_unless(&sobj->robj->shared_cnt, -1, 1)) {
+-                      mutex_unlock(&sobj->robj->lock);
++              if (atomic_add_unless(&rsvp->shared_cnt, -1, 1)) {
++                      mutex_unlock(&rsvp->lock);
+                       continue;
+               }
+-              ww_mutex_unlock(&sobj->robj->sync_lock);
+-              sobj->robj->locked = false;
++              /*
++               * Delete a sync object from reservation object of dmabuf.
++               *
++               * The sync object was added to reservation object of dmabuf
++               * just before ww_mutex_lock() is called.
++               */
++              DEL_OBJ_FROM_RSV(sobj, rsvp);
++              mutex_unlock(&rsvp->lock);
+-              mutex_unlock(&sobj->robj->lock);
++              ww_mutex_unlock(&rsvp->sync_lock);
++
++              mutex_lock(&rsvp->lock);
++              rsvp->locked = false;
++              mutex_unlock(&rsvp->lock);
+       }
+       if (res_sobj) {
+-              mutex_lock(&res_sobj->robj->lock);
++              struct dmabuf_sync_reservation *rsvp = res_sobj->robj;
+-              if (!atomic_add_unless(&res_sobj->robj->shared_cnt, -1, 1)) {
+-                      ww_mutex_unlock(&res_sobj->robj->sync_lock);
+-                      res_sobj->robj->locked = false;
++              mutex_lock(&rsvp->lock);
++
++              if (!atomic_add_unless(&rsvp->shared_cnt, -1, 1)) {
++                      /*
++                       * Delete a sync object from reservation object
++                       * of dmabuf.
++                       */
++                      DEL_OBJ_FROM_RSV(sobj, rsvp);
++                      mutex_unlock(&rsvp->lock);
++
++                      ww_mutex_unlock(&rsvp->sync_lock);
++
++                      mutex_lock(&rsvp->lock);
++                      rsvp->locked = false;
+               }
+-              mutex_unlock(&res_sobj->robj->lock);
++              mutex_unlock(&rsvp->lock);
+       }
+       if (ret == -EDEADLK) {
+@@ -281,26 +444,40 @@ static void dmabuf_sync_unlock_objs(struct dmabuf_sync *sync,
+       mutex_lock(&sync->lock);
+       list_for_each_entry(sobj, &sync->syncs, head) {
+-              mutex_lock(&sobj->robj->lock);
++              struct dmabuf_sync_reservation *rsvp = sobj->robj;
+-              if (sobj->robj->polled) {
+-                      sobj->robj->poll_event = true;
+-                      sobj->robj->polled = false;
+-                      wake_up_interruptible(&sobj->robj->poll_wait);
++              mutex_lock(&rsvp->lock);
++
++              if (rsvp->polled) {
++                      rsvp->poll_event = true;
++                      rsvp->polled = false;
++                      wake_up_interruptible(&rsvp->poll_wait);
+               }
+-              if (atomic_add_unless(&sobj->robj->shared_cnt, -1, 1)) {
+-                      mutex_unlock(&sobj->robj->lock);
++              /*
++               * Wake up a task blocked by dmabuf_sync_wait_prev_objs().
++               *
++               * If sobj->waiting is true, the task is waiting for wake_up
++               * call. So wake up the task if a given time period was
++               * elapsed so current task was timed out.
++               */
++              WAKE_UP_SYNC_OBJ(sobj);
++
++              /* Delete a sync object from reservation object of dmabuf. */
++              DEL_OBJ_FROM_RSV(sobj, rsvp);
++
++              if (atomic_add_unless(&rsvp->shared_cnt, -1, 1)) {
++                      mutex_unlock(&rsvp->lock);
+                       continue;
+               }
+-              mutex_unlock(&sobj->robj->lock);
++              mutex_unlock(&rsvp->lock);
+-              ww_mutex_unlock(&sobj->robj->sync_lock);
++              ww_mutex_unlock(&rsvp->sync_lock);
+-              mutex_lock(&sobj->robj->lock);
+-              sobj->robj->locked = false;
+-              mutex_unlock(&sobj->robj->lock);
++              mutex_lock(&rsvp->lock);
++              rsvp->locked = false;
++              mutex_unlock(&rsvp->lock);
+       }
+       mutex_unlock(&sync->lock);
+@@ -312,13 +489,13 @@ static void dmabuf_sync_unlock_objs(struct dmabuf_sync *sync,
+ }
+ /**
+- * is_dmabuf_sync_supported - Check if dmabuf sync is supported or not.
++ * dmabuf_sync_is_supported - Check if dmabuf sync is supported or not.
+  */
+-bool is_dmabuf_sync_supported(void)
++bool dmabuf_sync_is_supported(void)
+ {
+       return dmabuf_sync_enabled == 1;
+ }
+-EXPORT_SYMBOL(is_dmabuf_sync_supported);
++EXPORT_SYMBOL_GPL(dmabuf_sync_is_supported);
+ /**
+  * dmabuf_sync_init - Allocate and initialize a dmabuf sync.
+@@ -342,7 +519,7 @@ struct dmabuf_sync *dmabuf_sync_init(const char *name,
+       if (!sync)
+               return ERR_PTR(-ENOMEM);
+-      strncpy(sync->name, name, ARRAY_SIZE(sync->name) - 1);
++      strncpy(sync->name, name, DMABUF_SYNC_NAME_SIZE);
+       sync->ops = ops;
+       sync->priv = priv;
+@@ -352,7 +529,7 @@ struct dmabuf_sync *dmabuf_sync_init(const char *name,
+       return sync;
+ }
+-EXPORT_SYMBOL(dmabuf_sync_init);
++EXPORT_SYMBOL_GPL(dmabuf_sync_init);
+ /**
+  * dmabuf_sync_fini - Release a given dmabuf sync.
+@@ -365,18 +542,47 @@ EXPORT_SYMBOL(dmabuf_sync_init);
+  */
+ void dmabuf_sync_fini(struct dmabuf_sync *sync)
+ {
++      struct dmabuf_sync_object *sobj;
++
+       if (WARN_ON(!sync))
+               return;
++      if (list_empty(&sync->syncs))
++              goto free_sync;
++
++      list_for_each_entry(sobj, &sync->syncs, head) {
++              struct dmabuf_sync_reservation *rsvp = sobj->robj;
++
++              mutex_lock(&rsvp->lock);
++
++              if (rsvp->locked) {
++                      mutex_unlock(&rsvp->lock);
++                      ww_mutex_unlock(&rsvp->sync_lock);
++
++                      mutex_lock(&rsvp->lock);
++                      rsvp->locked = false;
++              }
++
++              mutex_unlock(&rsvp->lock);
++      }
++
++      /*
++       * If !list_empty(&sync->syncs) then it means that dmabuf_sync_put()
++       * or dmabuf_sync_put_all() was never called. So unreference all
++       * dmabuf objects added to sync->syncs, and remove them from the syncs.
++       */
++      dmabuf_sync_put_all(sync);
++
++free_sync:
+       if (sync->ops && sync->ops->free)
+               sync->ops->free(sync->priv);
+       kfree(sync);
+ }
+-EXPORT_SYMBOL(dmabuf_sync_fini);
++EXPORT_SYMBOL_GPL(dmabuf_sync_fini);
+ /*
+- * dmabuf_sync_get_obj - Add a given object to syncs list.
++ * dmabuf_sync_get_obj - Add a given object to sync's list.
+  *
+  * @sync: An object to dmabuf_sync structure.
+  * @dmabuf: An object to dma_buf structure.
+@@ -395,10 +601,8 @@ static int dmabuf_sync_get_obj(struct dmabuf_sync *sync, struct dma_buf *dmabuf,
+ {
+       struct dmabuf_sync_object *sobj;
+-      if (!dmabuf->sync) {
+-              WARN_ON(1);
++      if (!dmabuf->sync)
+               return -EFAULT;
+-      }
+       if (!IS_VALID_DMA_BUF_ACCESS_TYPE(type))
+               return -EINVAL;
+@@ -407,16 +611,16 @@ static int dmabuf_sync_get_obj(struct dmabuf_sync *sync, struct dma_buf *dmabuf,
+               type &= ~DMA_BUF_ACCESS_R;
+       sobj = kzalloc(sizeof(*sobj), GFP_KERNEL);
+-      if (!sobj) {
+-              WARN_ON(1);
++      if (!sobj)
+               return -ENOMEM;
+-      }
+       get_dma_buf(dmabuf);
+       sobj->dmabuf = dmabuf;
+       sobj->robj = dmabuf->sync;
+       sobj->access_type = type;
++      atomic_set(&sobj->refcnt, 1);
++      init_waitqueue_head(&sobj->wq);
+       mutex_lock(&sync->lock);
+       list_add_tail(&sobj->head, &sync->syncs);
+@@ -430,7 +634,7 @@ static int dmabuf_sync_get_obj(struct dmabuf_sync *sync, struct dma_buf *dmabuf,
+  *
+  * @sync: An object to dmabuf_sync structure.
+  *
+- * This function should be called if some operation is failed after
++ * This function should be called if some operation failed after
+  * dmabuf_sync_get_obj call to release a given sync object.
+  */
+ static void dmabuf_sync_put_obj(struct dmabuf_sync *sync,
+@@ -447,7 +651,9 @@ static void dmabuf_sync_put_obj(struct dmabuf_sync *sync,
+               dma_buf_put(sobj->dmabuf);
+               list_del_init(&sobj->head);
+-              kfree(sobj);
++
++              if (!atomic_add_unless(&sobj->refcnt, -1, 1))
++                      kfree(sobj);
+               break;
+       }
+@@ -462,7 +668,7 @@ static void dmabuf_sync_put_obj(struct dmabuf_sync *sync,
+  *
+  * @sync: An object to dmabuf_sync structure.
+  *
+- * This function should be called if some operation is failed after
++ * This function should be called if some operation failed after
+  * dmabuf_sync_get_obj call to release all sync objects.
+  */
+ static void dmabuf_sync_put_objs(struct dmabuf_sync *sync)
+@@ -475,7 +681,9 @@ static void dmabuf_sync_put_objs(struct dmabuf_sync *sync)
+               dma_buf_put(sobj->dmabuf);
+               list_del_init(&sobj->head);
+-              kfree(sobj);
++
++              if (!atomic_add_unless(&sobj->refcnt, -1, 1))
++                      kfree(sobj);
+       }
+       mutex_unlock(&sync->lock);
+@@ -496,10 +704,8 @@ int dmabuf_sync_lock(struct dmabuf_sync *sync)
+ {
+       int ret;
+-      if (!sync) {
+-              WARN_ON(1);
++      if (!sync)
+               return -EFAULT;
+-      }
+       if (list_empty(&sync->syncs))
+               return -EINVAL;
+@@ -508,10 +714,8 @@ int dmabuf_sync_lock(struct dmabuf_sync *sync)
+               return -EINVAL;
+       ret = dmabuf_sync_lock_objs(sync, &sync->ctx);
+-      if (ret < 0) {
+-              WARN_ON(1);
++      if (ret < 0)
+               return ret;
+-      }
+       sync->status = DMABUF_SYNC_LOCKED;
+@@ -519,7 +723,7 @@ int dmabuf_sync_lock(struct dmabuf_sync *sync)
+       return ret;
+ }
+-EXPORT_SYMBOL(dmabuf_sync_lock);
++EXPORT_SYMBOL_GPL(dmabuf_sync_lock);
+ /**
+  * dmabuf_sync_unlock - unlock all objects added to syncs list.
+@@ -531,10 +735,8 @@ EXPORT_SYMBOL(dmabuf_sync_lock);
+  */
+ int dmabuf_sync_unlock(struct dmabuf_sync *sync)
+ {
+-      if (!sync) {
+-              WARN_ON(1);
++      if (!sync)
+               return -EFAULT;
+-      }
+       /* If current dmabuf sync object wasn't reserved then just return. */
+       if (sync->status != DMABUF_SYNC_LOCKED)
+@@ -544,7 +746,7 @@ int dmabuf_sync_unlock(struct dmabuf_sync *sync)
+       return 0;
+ }
+-EXPORT_SYMBOL(dmabuf_sync_unlock);
++EXPORT_SYMBOL_GPL(dmabuf_sync_unlock);
+ /**
+  * dmabuf_sync_single_lock - lock a dma buf.
+@@ -568,22 +770,36 @@ int dmabuf_sync_single_lock(struct dma_buf *dmabuf, unsigned int type,
+                               bool wait)
+ {
+       struct dmabuf_sync_reservation *robj;
++      struct dmabuf_sync_object *sobj;
+-      if (!dmabuf->sync) {
+-              WARN_ON(1);
++      if (!dmabuf->sync)
+               return -EFAULT;
+-      }
+-      if (!IS_VALID_DMA_BUF_ACCESS_TYPE(type)) {
+-              WARN_ON(1);
++      if (!IS_VALID_DMA_BUF_ACCESS_TYPE(type))
+               return -EINVAL;
+-      }
+       get_dma_buf(dmabuf);
+       robj = dmabuf->sync;
++      sobj = kzalloc(sizeof(*sobj), GFP_KERNEL);
++      if (!sobj) {
++              dma_buf_put(dmabuf);
++              return -ENOMEM;
++      }
++
++      sobj->dmabuf = dmabuf;
++      sobj->task = (unsigned long)current;
++      atomic_set(&sobj->refcnt, 1);
++      init_waitqueue_head(&sobj->wq);
++
+       mutex_lock(&robj->lock);
++      /*
++       * Add a sync object to reservation object of dmabuf to handle
++       * the write-and-then-read ordering issue.
++       */
++      list_add_tail(&sobj->r_head, &robj->syncs);
++
+       /* Don't lock in case of read and read. */
+       if (robj->accessed_type & DMA_BUF_ACCESS_R && type & DMA_BUF_ACCESS_R) {
+               atomic_inc(&robj->shared_cnt);
+@@ -596,24 +812,36 @@ int dmabuf_sync_single_lock(struct dma_buf *dmabuf, unsigned int type,
+        * been locked.
+        */
+       if (!wait && robj->locked) {
++              list_del_init(&sobj->r_head);
+               mutex_unlock(&robj->lock);
++              kfree(sobj);
+               dma_buf_put(dmabuf);
+               return -EAGAIN;
+       }
+       mutex_unlock(&robj->lock);
++      /* Unlocked by dmabuf_sync_single_unlock or dmabuf_sync_unlock. */
+       mutex_lock(&robj->sync_lock.base);
+       mutex_lock(&robj->lock);
+       robj->locked = true;
++      mutex_unlock(&robj->lock);
++
++      /*
++       * Check if there is a sync object added to reservation object of
++       * dmabuf before current task takes a lock to the dmabuf, and wait
++       * for the for the wake up event from other task if exists.
++       */
++      dmabuf_sync_wait_prev_objs(sobj, robj, NULL);
++      mutex_lock(&robj->lock);
+       dmabuf_sync_single_cache_ops(dmabuf, type);
+       mutex_unlock(&robj->lock);
+       return 0;
+ }
+-EXPORT_SYMBOL(dmabuf_sync_single_lock);
++EXPORT_SYMBOL_GPL(dmabuf_sync_single_lock);
+ /**
+  * dmabuf_sync_single_unlock - unlock a dma buf.
+@@ -626,6 +854,7 @@ EXPORT_SYMBOL(dmabuf_sync_single_lock);
+ void dmabuf_sync_single_unlock(struct dma_buf *dmabuf)
+ {
+       struct dmabuf_sync_reservation *robj;
++      struct dmabuf_sync_object *sobj, *next;
+       if (!dmabuf->sync) {
+               WARN_ON(1);
+@@ -642,6 +871,57 @@ void dmabuf_sync_single_unlock(struct dma_buf *dmabuf)
+               wake_up_interruptible(&robj->poll_wait);
+       }
++      /*
++       * Wake up a blocked task/tasks by dmabuf_sync_wait_prev_objs()
++       * with two steps.
++       *
++       * 1. Wake up a task waiting for the wake up event to a sync object
++       *      of same task, and remove the sync object from reservation
++       *      object of dmabuf, and then go to out: requested by same task.
++       * 2. Wait up a task waiting for the wake up event to a sync object
++       *      of other task, and remove the sync object if not existed
++       *      at step 1: requested by other task.
++       *
++       * The reason, we have to handle it with the above two steps,
++       * is that fcntl system call is called with a file descriptor so
++       * kernel side cannot be aware of which sync object of robj->syncs
++       * should be waked up and deleted at this function.
++       * So for this, we use the above two steps to find a sync object
++       * to be waked up.
++       */
++      list_for_each_entry_safe(sobj, next, &robj->syncs, r_head) {
++              if (sobj->task == (unsigned long)current) {
++                      /*
++                       * Wake up a task blocked by
++                       * dmabuf_sync_wait_prev_objs().
++                       */
++                      WAKE_UP_SYNC_OBJ(sobj);
++
++                      list_del_init(&sobj->r_head);
++
++                      if (!atomic_add_unless(&sobj->refcnt, -1, 1))
++                              kfree(sobj);
++                      goto out;
++              }
++      }
++
++      list_for_each_entry_safe(sobj, next, &robj->syncs, r_head) {
++              if (sobj->task) {
++                      /*
++                       * Wake up a task blocked by
++                       * dmabuf_sync_wait_prev_objs().
++                       */
++                      WAKE_UP_SYNC_OBJ(sobj);
++
++                      list_del_init(&sobj->r_head);
++
++                      if (!atomic_add_unless(&sobj->refcnt, -1, 1))
++                              kfree(sobj);
++                      break;
++              }
++      }
++
++out:
+       if (atomic_add_unless(&robj->shared_cnt, -1 , 1)) {
+               mutex_unlock(&robj->lock);
+               dma_buf_put(dmabuf);
+@@ -660,7 +940,7 @@ void dmabuf_sync_single_unlock(struct dma_buf *dmabuf)
+       return;
+ }
+-EXPORT_SYMBOL(dmabuf_sync_single_unlock);
++EXPORT_SYMBOL_GPL(dmabuf_sync_single_unlock);
+ /**
+  * dmabuf_sync_get - Get dmabuf sync object.
+@@ -684,22 +964,18 @@ int dmabuf_sync_get(struct dmabuf_sync *sync, void *sync_buf, unsigned int type)
+ {
+       int ret;
+-      if (!sync || !sync_buf) {
+-              WARN_ON(1);
++      if (!sync || !sync_buf)
+               return -EFAULT;
+-      }
+       ret = dmabuf_sync_get_obj(sync, sync_buf, type);
+-      if (ret < 0) {
+-              WARN_ON(1);
++      if (ret < 0)
+               return ret;
+-      }
+       sync->status = DMABUF_SYNC_GOT;
+       return 0;
+ }
+-EXPORT_SYMBOL(dmabuf_sync_get);
++EXPORT_SYMBOL_GPL(dmabuf_sync_get);
+ /**
+  * dmabuf_sync_put - Put dmabuf sync object to a given dmabuf.
+@@ -725,7 +1001,7 @@ void dmabuf_sync_put(struct dmabuf_sync *sync, struct dma_buf *dmabuf)
+       dmabuf_sync_put_obj(sync, dmabuf);
+ }
+-EXPORT_SYMBOL(dmabuf_sync_put);
++EXPORT_SYMBOL_GPL(dmabuf_sync_put);
+ /**
+  * dmabuf_sync_put_all - Put dmabuf sync object to dmabufs.
+@@ -750,4 +1026,4 @@ void dmabuf_sync_put_all(struct dmabuf_sync *sync)
+       dmabuf_sync_put_objs(sync);
+ }
+-EXPORT_SYMBOL(dmabuf_sync_put_all);
++EXPORT_SYMBOL_GPL(dmabuf_sync_put_all);
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+index 90432d3..f438e80 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+@@ -700,7 +700,7 @@ static int g2d_map_cmdlist_gem(struct g2d_data *g2d,
+       int ret;
+       int i;
+-      if (is_dmabuf_sync_supported()) {
++      if (dmabuf_sync_is_supported()) {
+               node->sync = dmabuf_sync_init("g2d", &dmabuf_sync_ops, node);
+               if (IS_ERR(node->sync))
+                       node->sync = NULL;
+diff --git a/include/linux/dmabuf-sync.h b/include/linux/dmabuf-sync.h
+index 9a3afc4..6577af8 100644
+--- a/include/linux/dmabuf-sync.h
++++ b/include/linux/dmabuf-sync.h
+@@ -14,12 +14,58 @@
+ #include <linux/sched.h>
+ #include <linux/dma-buf.h>
++#define DMABUF_SYNC_NAME_SIZE 64
++
++/*
++ * Status to a dmabuf_sync object.
++ *
++ * @DMABUF_SYNC_GOT: Indicate that one more dmabuf objects have been added
++ *                    to a sync's list.
++ * @DMABUF_SYNC_LOCKED: Indicate that all dmabuf objects in a sync's list
++ *                    have been locked.
++ */
+ enum dmabuf_sync_status {
+       DMABUF_SYNC_GOT         = 1,
+       DMABUF_SYNC_LOCKED,
+ };
++/*
++ * A structure for dmabuf_sync_reservation.
++ *
++ * @syncs: A list head to sync object and this is global to system.
++ *    This contains sync objects of tasks that requested a lock
++ *    to this dmabuf.
++ * @sync_lock: This provides read or write lock to a dmabuf.
++ *    Except in the below cases, a task will be blocked if the task
++ *    tries to lock a dmabuf for CPU or DMA access when other task
++ *    already locked the dmabuf.
++ *
++ *    Before          After
++ *    --------------------------
++ *    CPU read        CPU read
++ *    CPU read        DMA read
++ *    DMA read        CPU read
++ *    DMA read        DMA read
++ *
++ * @lock: Protecting a dmabuf_sync_reservation object.
++ * @poll_wait: A wait queue object to poll a dmabuf object.
++ * @poll_event: Indicate whether a dmabuf object - being polled -
++ *    was unlocked or not. If true, a blocked task will be out
++ *    of select system call.
++ * @poll: Indicate whether the polling to a dmabuf object was requested
++ *    or not by userspace.
++ * @shared_cnt: Shared count to a dmabuf object.
++ * @accessed_type: Indicate how and who a dmabuf object was accessed by.
++ *    One of the below types could be set.
++ *    DMA_BUF_ACCESS_R -> CPU access for read.
++ *    DMA_BUF_ACCRSS_W -> CPU access for write.
++ *    DMA_BUF_ACCESS_R | DMA_BUF_ACCESS_DMA -> DMA access for read.
++ *    DMA_BUF_ACCESS_W | DMA_BUF_ACCESS_DMA -> DMA access for write.
++ * @locked: Indicate whether a dmabuf object has been locked or not.
++ *
++ */
+ struct dmabuf_sync_reservation {
++      struct list_head        syncs;
+       struct ww_mutex         sync_lock;
+       struct mutex            lock;
+       wait_queue_head_t       poll_wait;
+@@ -33,17 +79,36 @@ struct dmabuf_sync_reservation {
+ /*
+  * A structure for dmabuf_sync_object.
+  *
+- * @head: A list head to be added to syncs list.
++ * @head: A list head to be added to dmabuf_sync's syncs.
++ * @r_head: A list head to be added to dmabuf_sync_reservation's syncs.
+  * @robj: A reservation_object object.
+  * @dma_buf: A dma_buf object.
++ * @task: An address value to current task.
++ *    This is used to indicate who is a owner of a sync object.
++ * @wq: A wait queue head.
++ *    This is used to guarantee that a task can take a lock to a dmabuf
++ *    if the task requested a lock to the dmabuf prior to other task.
++ *    For more details, see dmabuf_sync_wait_prev_objs function.
++ * @refcnt: A reference count to a sync object.
+  * @access_type: Indicate how a current task tries to access
+- *    a given buffer.
++ *    a given buffer, and one of the below types could be set.
++ *    DMA_BUF_ACCESS_R -> CPU access for read.
++ *    DMA_BUF_ACCRSS_W -> CPU access for write.
++ *    DMA_BUF_ACCESS_R | DMA_BUF_ACCESS_DMA -> DMA access for read.
++ *    DMA_BUF_ACCESS_W | DMA_BUF_ACCESS_DMA -> DMA access for write.
++ * @waiting: Indicate whether current task is waiting for the wake up event
++ *    from other task or not.
+  */
+ struct dmabuf_sync_object {
+       struct list_head                head;
++      struct list_head                r_head;
+       struct dmabuf_sync_reservation  *robj;
+       struct dma_buf                  *dmabuf;
++      unsigned long                   task;
++      wait_queue_head_t               wq;
++      atomic_t                        refcnt;
+       unsigned int                    access_type;
++      unsigned int                    waiting;
+ };
+ struct dmabuf_sync_priv_ops {
+@@ -54,8 +119,9 @@ struct dmabuf_sync_priv_ops {
+  * A structure for dmabuf_sync.
+  *
+  * @syncs: A list head to sync object and this is global to system.
++ *    This contains sync objects of dmabuf_sync owner.
+  * @list: A list entry used as committed list node
+- * @lock: A mutex lock to current sync object.
++ * @lock: Protecting a dmabuf_sync object.
+  * @ctx: A current context for ww mutex.
+  * @work: A work struct to release resources at timeout.
+  * @priv: A private data.
+@@ -71,7 +137,7 @@ struct dmabuf_sync {
+       struct work_struct              work;
+       void                            *priv;
+       struct dmabuf_sync_priv_ops     *ops;
+-      char                            name[64];
++      char                            name[DMABUF_SYNC_NAME_SIZE];
+       struct timer_list               timer;
+       unsigned int                    status;
+ };
+@@ -94,6 +160,7 @@ static inline void dmabuf_sync_reservation_init(struct dma_buf *dmabuf)
+       mutex_init(&obj->lock);
+       atomic_set(&obj->shared_cnt, 1);
++      INIT_LIST_HEAD(&obj->syncs);
+       init_waitqueue_head(&obj->poll_wait);
+ }
+@@ -112,29 +179,29 @@ static inline void dmabuf_sync_reservation_fini(struct dma_buf *dmabuf)
+       kfree(obj);
+ }
+-extern bool is_dmabuf_sync_supported(void);
++bool dmabuf_sync_is_supported(void);
+-extern struct dmabuf_sync *dmabuf_sync_init(const char *name,
++struct dmabuf_sync *dmabuf_sync_init(const char *name,
+                                       struct dmabuf_sync_priv_ops *ops,
+                                       void *priv);
+-extern void dmabuf_sync_fini(struct dmabuf_sync *sync);
++void dmabuf_sync_fini(struct dmabuf_sync *sync);
+-extern int dmabuf_sync_lock(struct dmabuf_sync *sync);
++int dmabuf_sync_lock(struct dmabuf_sync *sync);
+-extern int dmabuf_sync_unlock(struct dmabuf_sync *sync);
++int dmabuf_sync_unlock(struct dmabuf_sync *sync);
+ int dmabuf_sync_single_lock(struct dma_buf *dmabuf, unsigned int type,
+                               bool wait);
+ void dmabuf_sync_single_unlock(struct dma_buf *dmabuf);
+-extern int dmabuf_sync_get(struct dmabuf_sync *sync, void *sync_buf,
++int dmabuf_sync_get(struct dmabuf_sync *sync, void *sync_buf,
+                               unsigned int type);
+-extern void dmabuf_sync_put(struct dmabuf_sync *sync, struct dma_buf *dmabuf);
++void dmabuf_sync_put(struct dmabuf_sync *sync, struct dma_buf *dmabuf);
+-extern void dmabuf_sync_put_all(struct dmabuf_sync *sync);
++void dmabuf_sync_put_all(struct dmabuf_sync *sync);
+ #else
+@@ -142,7 +209,7 @@ static inline void dmabuf_sync_reservation_init(struct dma_buf *dmabuf) { }
+ static inline void dmabuf_sync_reservation_fini(struct dma_buf *dmabuf) { }
+-static inline bool is_dmabuf_sync_supported(void) { return false; }
++static inline bool dmabuf_sync_is_supported(void) { return false; }
+ static inline  struct dmabuf_sync *dmabuf_sync_init(const char *name,
+                                       struct dmabuf_sync_priv_ops *ops,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0592-usb-phy-samsung-do-not-check-otg-host-to-clear-it.patch b/patches.tizen/0592-usb-phy-samsung-do-not-check-otg-host-to-clear-it.patch
new file mode 100644 (file)
index 0000000..71c425b
--- /dev/null
@@ -0,0 +1,32 @@
+From e63ca49f324d4fe8eeada1b30a1618daf9162fa9 Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Fri, 30 Aug 2013 20:46:07 +0900
+Subject: [PATCH 0592/1302] usb: phy: samsung: do not check otg->host to clear
+ it
+
+This patch can clear otg->host variable to select a host and a device mode on
+runtime. Before initializing the phy, it should specify which mode will be used.
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/phy/phy-samsung-usb2.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/usb/phy/phy-samsung-usb2.c b/drivers/usb/phy/phy-samsung-usb2.c
+index cebf34b..b29e0ce 100644
+--- a/drivers/usb/phy/phy-samsung-usb2.c
++++ b/drivers/usb/phy/phy-samsung-usb2.c
+@@ -37,8 +37,7 @@ static int samsung_usbphy_set_host(struct usb_otg *otg, struct usb_bus *host)
+       if (!otg)
+               return -ENODEV;
+-      if (!otg->host)
+-              otg->host = host;
++      otg->host = host;
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0593-usb-ehci-s5p-specify-host-mode-to-phy-driver.patch b/patches.tizen/0593-usb-ehci-s5p-specify-host-mode-to-phy-driver.patch
new file mode 100644 (file)
index 0000000..009f3ab
--- /dev/null
@@ -0,0 +1,65 @@
+From 8e838837783fee2d39ba9dc259a19bd9d5546db5 Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Fri, 30 Aug 2013 20:56:11 +0900
+Subject: [PATCH 0593/1302] usb: ehci-s5p: specify host mode to phy driver
+
+In otg mode, we can use it both host and device mode. Before initializing phy
+driver, we should specify which mode will be used for it.
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/host/ehci-s5p.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
+index e7d26d6..671de95 100644
+--- a/drivers/usb/host/ehci-s5p.c
++++ b/drivers/usb/host/ehci-s5p.c
+@@ -51,6 +51,7 @@ struct s5p_ehci_hcd {
+       int power_on;
+       struct usb_phy *phy;
+       struct usb_otg *otg;
++      struct usb_bus *host;
+       struct s5p_ehci_platdata *pdata;
+ };
+@@ -59,8 +60,11 @@ struct s5p_ehci_hcd {
+ static void s5p_ehci_phy_enable(struct s5p_ehci_hcd *s5p_ehci,
+                                               struct platform_device *pdev)
+ {
+-      if (s5p_ehci->phy)
++      if (s5p_ehci->phy) {
++              if (s5p_ehci->otg)
++                      otg_set_host(s5p_ehci->otg, s5p_ehci->host);
+               usb_phy_init(s5p_ehci->phy);
++      }
+       else if (s5p_ehci->pdata->phy_init)
+               s5p_ehci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
+ }
+@@ -68,8 +72,11 @@ static void s5p_ehci_phy_enable(struct s5p_ehci_hcd *s5p_ehci,
+ static void s5p_ehci_phy_disable(struct s5p_ehci_hcd *s5p_ehci,
+                                                struct platform_device *pdev)
+ {
+-      if (s5p_ehci->phy)
++      if (s5p_ehci->phy) {
++              if (s5p_ehci->otg)
++                      otg_set_host(s5p_ehci->otg, NULL);
+               usb_phy_shutdown(s5p_ehci->phy);
++      }
+       else if (s5p_ehci->pdata->phy_exit)
+               s5p_ehci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
+ }
+@@ -266,8 +273,7 @@ static int s5p_ehci_probe(struct platform_device *pdev)
+               goto fail_io;
+       }
+-      if (s5p_ehci->otg)
+-              s5p_ehci->otg->set_host(s5p_ehci->otg, &hcd->self);
++      s5p_ehci->host = &hcd->self;
+       s5p_ehci_phy_enable(s5p_ehci, pdev);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0594-usb-gadget-s3c-hsotg-specify-device-mode-before-init.patch b/patches.tizen/0594-usb-gadget-s3c-hsotg-specify-device-mode-before-init.patch
new file mode 100644 (file)
index 0000000..bccdb6f
--- /dev/null
@@ -0,0 +1,47 @@
+From bd6429a2f6f79d5d493726872d601efe6fdd9980 Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Fri, 30 Aug 2013 20:58:55 +0900
+Subject: [PATCH 0594/1302] usb: gadget: s3c-hsotg: specify device mode before
+ initializing phy
+
+The otg module can be used both host and device mode. According to the boot
+sequence, device mode will be initialized first and host mode will be
+initialized later. Thus, the phy always remained in the host mode.
+To address this problem, we should clear the 'host' value before initializing
+the phy driver.
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/s3c-hsotg.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
+index 5c8fe2d..5fc87ce 100644
+--- a/drivers/usb/gadget/s3c-hsotg.c
++++ b/drivers/usb/gadget/s3c-hsotg.c
+@@ -34,6 +34,7 @@
+ #include <linux/usb/ch9.h>
+ #include <linux/usb/gadget.h>
+ #include <linux/usb/phy.h>
++#include <linux/usb/otg.h>
+ #include <linux/platform_data/s3c-hsotg.h>
+ #include <mach/map.h>
+@@ -2824,8 +2825,12 @@ static void s3c_hsotg_phy_enable(struct s3c_hsotg *hsotg)
+       dev_dbg(hsotg->dev, "pdev 0x%p\n", pdev);
+-      if (hsotg->phy)
++      if (hsotg->phy) {
++              struct usb_otg *otg = hsotg->phy->otg;
++              if (otg && otg->set_host)
++                      otg->set_host(otg, NULL);
+               usb_phy_init(hsotg->phy);
++      }
+       else if (hsotg->plat->phy_init)
+               hsotg->plat->phy_init(pdev, hsotg->plat->phy_type);
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0595-ARM-dts-exynos4x12-add-usb-sysreg-node.patch b/patches.tizen/0595-ARM-dts-exynos4x12-add-usb-sysreg-node.patch
new file mode 100644 (file)
index 0000000..f3630e7
--- /dev/null
@@ -0,0 +1,29 @@
+From 40a9496c5c3d8161be2e53362c7091ecab298d14 Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Fri, 30 Aug 2013 21:08:25 +0900
+Subject: [PATCH 0595/1302] ARM: dts: exynos4x12: add usb sysreg node
+
+The exynos4x12 can control usb mode by sysreg register.
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index a0d85c3..6c1c5eb 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -199,7 +199,7 @@
+               status = "disabled";
+               usbphy-sys {
+-                      reg = <0x10020704 0x0c>;
++                      reg = <0x10020704 0x0c>, <0x1001021C 0x04>;
+               };
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0596-Revert-drm-exynos-add-dt-binding-documentation-for-r.patch b/patches.tizen/0596-Revert-drm-exynos-add-dt-binding-documentation-for-r.patch
new file mode 100644 (file)
index 0000000..44beedd
--- /dev/null
@@ -0,0 +1,58 @@
+From 0119a9732641d68c5c85bd222766202dce1b87f2 Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Mon, 2 Sep 2013 13:23:29 +0900
+Subject: [PATCH 0596/1302] Revert "drm/exynos: add dt-binding documentation
+ for rotator"
+
+This reverts commit 5e842af0339fda92b300bf95be9886aff776f80c.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../bindings/drm/exynos/samsung-rotator.txt        | 35 ----------------------
+ 1 file changed, 35 deletions(-)
+ delete mode 100644 Documentation/devicetree/bindings/drm/exynos/samsung-rotator.txt
+
+diff --git a/Documentation/devicetree/bindings/drm/exynos/samsung-rotator.txt b/Documentation/devicetree/bindings/drm/exynos/samsung-rotator.txt
+deleted file mode 100644
+index 6b1d704..0000000
+--- a/Documentation/devicetree/bindings/drm/exynos/samsung-rotator.txt
++++ /dev/null
+@@ -1,35 +0,0 @@
+-* Samsung Image Rotator
+-
+-Required properties:
+-  - compatible : value should be the "samsung,exynos4210".
+-  - reg : Physical base address of the IP registers and length of memory
+-        mapped region.
+-  - interrupts : interrupt number to the CPU.
+-  - clocks : clock number of exynos4 rotator clock.
+-  - clocks : clock name of rotator
+-  - status : "okay" or "disabled"
+-  - limit table for image formats : min_w/min_h/max_w/max_h for min/max of image
+-
+-Example:
+-      rotator: rotator@12810000 {
+-              compatible = "samsung,exynos4210-rotator";
+-              reg = <0x12810000 0x1000>;
+-              interrupts = <0 83 0>;
+-              clocks = <&clock 278>;
+-              clock-names = "rotator";
+-              status = "disabled";
+-              ycbcr420_2p {
+-                      min_w = <32>;
+-                      min_h = <32>;
+-                      max_w = <32768>;
+-                      max_h = <32768>;
+-                      align = <3>;
+-              };
+-              rgb888 {
+-                      min_w = <8>;
+-                      min_h = <8>;
+-                      max_w = <8192>;
+-                      max_h = <8192>;
+-                      align = <2>;
+-              };
+-      };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0597-Revert-ARM-dts-add-a-rotator-node-for-exynos4.patch b/patches.tizen/0597-Revert-ARM-dts-add-a-rotator-node-for-exynos4.patch
new file mode 100644 (file)
index 0000000..1f5ccf8
--- /dev/null
@@ -0,0 +1,49 @@
+From d3325c63fb75b487ea5c12cee52ced35ddcf6382 Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Mon, 2 Sep 2013 13:23:56 +0900
+Subject: [PATCH 0597/1302] Revert "ARM: dts: add a rotator node for exynos4"
+
+This reverts commit 75a691b2420a63580d452561c55284f1720ed947.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi | 23 -----------------------
+ 1 file changed, 23 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index cd2725a..e084b26 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -134,29 +134,6 @@
+               status = "disabled";
+       };
+-      rotator: rotator@12810000 {
+-              compatible = "samsung,exynos4210-rotator";
+-              reg = <0x12810000 0x1000>;
+-              interrupts = <0 83 0>;
+-              clocks = <&clock 278>;
+-              clock-names = "rotator";
+-              status = "disabled";
+-              ycbcr420_2p {
+-                      min_w = <32>;
+-                      min_h = <32>;
+-                      max_w = <32768>;
+-                      max_h = <32768>;
+-                      align = <3>;
+-              };
+-              rgb888 {
+-                      min_w = <8>;
+-                      min_h = <8>;
+-                      max_w = <8192>;
+-                      max_h = <8192>;
+-                      align = <2>;
+-              };
+-      };
+-
+       camera {
+               compatible = "samsung,fimc", "simple-bus";
+               status = "disabled";
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0598-Revert-drm-exynos-add-device-tree-support-for-rotato.patch b/patches.tizen/0598-Revert-drm-exynos-add-device-tree-support-for-rotato.patch
new file mode 100644 (file)
index 0000000..4849b56
--- /dev/null
@@ -0,0 +1,183 @@
+From f9eaad0228613f35c0e425e9ff1b130d9888c7bc Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Mon, 2 Sep 2013 13:25:41 +0900
+Subject: [PATCH 0598/1302] Revert "drm/exynos: add device tree support for
+ rotator"
+
+This reverts commit 4306d0e1427f477853d555fc08f4ec5dc370f01f.
+
+Conflicts:
+
+       drivers/gpu/drm/exynos/exynos_drm_rotator.c
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_rotator.c | 109 ++++++++--------------------
+ 1 file changed, 30 insertions(+), 79 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
+index 375e36a..d5fed49 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_rotator.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
+@@ -96,7 +96,7 @@ struct rot_context {
+       struct resource *regs_res;
+       void __iomem    *regs;
+       struct clk      *clock;
+-      struct rot_limit_table  limit_tbl;
++      struct rot_limit_table  *limit_tbl;
+       int     irq;
+       int     cur_buf_id[EXYNOS_DRM_OPS_MAX];
+       bool    suspended;
+@@ -167,7 +167,7 @@ static irqreturn_t rotator_irq_handler(int irq, void *arg)
+ static void rotator_align_size(struct rot_context *rot, u32 fmt, u32 *hsize,
+               u32 *vsize)
+ {
+-      struct rot_limit_table *limit_tbl = &rot->limit_tbl;
++      struct rot_limit_table *limit_tbl = rot->limit_tbl;
+       struct rot_limit *limit;
+       u32 mask, val;
+@@ -635,71 +635,6 @@ static int rotator_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd)
+       return 0;
+ }
+-static const struct of_device_id exynos_rotator_match[] = {
+-      {
+-              .compatible = "samsung,exynos4210-rotator",
+-      },
+-      {},
+-};
+-
+-static int rotator_parse_dt_tbl(struct device_node *np, struct rot_limit *rlim)
+-{
+-      int ret;
+-
+-      ret = of_property_read_u32(np, "min_w", &rlim->min_w);
+-      if (ret)
+-              return ret;
+-
+-      ret = of_property_read_u32(np, "min_h", &rlim->min_h);
+-      if (ret)
+-              return ret;
+-
+-      ret = of_property_read_u32(np, "max_w", &rlim->max_w);
+-      if (ret)
+-              return ret;
+-
+-      ret = of_property_read_u32(np, "max_h", &rlim->max_h);
+-      if (ret)
+-              return ret;
+-
+-      ret = of_property_read_u32(np, "align", &rlim->align);
+-      if (ret)
+-              return ret;
+-
+-      return 0;
+-}
+-
+-static int rotator_parse_dt(struct device *dev, struct rot_context *rot)
+-{
+-      struct device_node *ycbcr_node, *rgb888_node;
+-      int ret;
+-
+-      ycbcr_node = of_get_child_by_name(dev->of_node, "ycbcr420_2p");
+-      if (!ycbcr_node) {
+-              dev_err(dev, "can't find ycbcr420_2p node\n");
+-              return -ENODEV;
+-      }
+-
+-      rgb888_node = of_get_child_by_name(dev->of_node, "rgb888");
+-      if (!rgb888_node) {
+-              dev_err(dev, "can't find rgb888 node\n");
+-              return -ENODEV;
+-      }
+-
+-      ret = rotator_parse_dt_tbl(ycbcr_node, &rot->limit_tbl.ycbcr420_2p);
+-      if (ret) {
+-              dev_err(dev, "failed to parse ycbcr420 data\n");
+-              return ret;
+-      }
+-      ret = rotator_parse_dt_tbl(rgb888_node, &rot->limit_tbl.rgb888);
+-      if (ret) {
+-              dev_err(dev, "failed to parse rgb888 data\n");
+-              return ret;
+-      }
+-
+-      return 0;
+-}
+-
+ static int rotator_probe(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+@@ -707,21 +642,12 @@ static int rotator_probe(struct platform_device *pdev)
+       struct exynos_drm_ippdrv *ippdrv;
+       int ret;
+-      if (!dev->of_node) {
+-              dev_err(dev, "Cannot find device tree node\n");
+-              return -ENODEV;
+-      }
+-
+       rot = devm_kzalloc(dev, sizeof(*rot), GFP_KERNEL);
+       if (!rot)
+               return -ENOMEM;
+-      ret = rotator_parse_dt(dev, rot);
+-      if (ret) {
+-              dev_err(dev, "failed parse dt info\n");
+-              devm_kfree(dev, rot);
+-              return ret;
+-      }
++      rot->limit_tbl = (struct rot_limit_table *)
++                              platform_get_device_id(pdev)->driver_data;
+       rot->regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       rot->regs = devm_ioremap_resource(dev, rot->regs_res);
+@@ -793,6 +719,31 @@ static int rotator_remove(struct platform_device *pdev)
+       return 0;
+ }
++static struct rot_limit_table rot_limit_tbl = {
++      .ycbcr420_2p = {
++              .min_w = 32,
++              .min_h = 32,
++              .max_w = SZ_32K,
++              .max_h = SZ_32K,
++              .align = 3,
++      },
++      .rgb888 = {
++              .min_w = 8,
++              .min_h = 8,
++              .max_w = SZ_8K,
++              .max_h = SZ_8K,
++              .align = 2,
++      },
++};
++
++static struct platform_device_id rotator_driver_ids[] = {
++      {
++              .name           = "exynos-rot",
++              .driver_data    = (unsigned long)&rot_limit_tbl,
++      },
++      {},
++};
++
+ static int rotator_clk_crtl(struct rot_context *rot, bool enable)
+ {
+       if (enable) {
+@@ -854,10 +805,10 @@ static const struct dev_pm_ops rotator_pm_ops = {
+ struct platform_driver rotator_driver = {
+       .probe          = rotator_probe,
+       .remove         = rotator_remove,
++      .id_table       = rotator_driver_ids,
+       .driver         = {
+               .name   = "exynos-rot",
+               .owner  = THIS_MODULE,
+               .pm     = &rotator_pm_ops,
+-              .of_match_table = of_match_ptr(exynos_rotator_match),
+       },
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0599-drm-exynos-add-device-tree-support-for-rotator.patch b/patches.tizen/0599-drm-exynos-add-device-tree-support-for-rotator.patch
new file mode 100644 (file)
index 0000000..40bb1e0
--- /dev/null
@@ -0,0 +1,208 @@
+From 26f593da2d1f40efd44859c91bfa51a21369ddc8 Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Mon, 12 Aug 2013 22:44:42 +0900
+Subject: [PATCH 0599/1302] drm/exynos: add device tree support for rotator
+
+The exynos4 platform is only dt-based since 3.10, we should convert driver data
+and ids to dt-based parsing methods. The rotator driver has a limit table to get
+size limit of input picture. Each SoCs has slightly different limit value
+compared with any others.
+For example, exynos4210's max_size of RGB888 is 16k x 16k. But, others have
+8k x 8k. Another example the exynos5250 should have multiple of 2 pixel size
+for its X/Y axis. Thus, we should keep different tables for each of them.
+This patch also includes desciptions of each nodes for the rotator and specifies
+a example how to bind it.
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Cc: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/gpu/samsung-rotator.txt    |  27 ++++++
+ drivers/gpu/drm/exynos/exynos_drm_rotator.c        | 108 +++++++++++++++------
+ 2 files changed, 107 insertions(+), 28 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/gpu/samsung-rotator.txt
+
+diff --git a/Documentation/devicetree/bindings/gpu/samsung-rotator.txt b/Documentation/devicetree/bindings/gpu/samsung-rotator.txt
+new file mode 100644
+index 0000000..82cd1ed
+--- /dev/null
++++ b/Documentation/devicetree/bindings/gpu/samsung-rotator.txt
+@@ -0,0 +1,27 @@
++* Samsung Image Rotator
++
++Required properties:
++  - compatible : value should be one of the following:
++      (a) "samsung,exynos4210-rotator" for Rotator IP in Exynos4210
++      (b) "samsung,exynos4212-rotator" for Rotator IP in Exynos4212/4412
++      (c) "samsung,exynos5250-rotator" for Rotator IP in Exynos5250
++
++  - reg : Physical base address of the IP registers and length of memory
++        mapped region.
++
++  - interrupts : Interrupt specifier for rotator interrupt, according to format
++               specific to interrupt parent.
++
++  - clocks : Clock specifier for rotator clock, according to generic clock
++           bindings. (See Documentation/devicetree/bindings/clock/exynos*.txt)
++
++  - clock-names : Names of clocks. For exynos rotator, it should be "rotator".
++
++Example:
++      rotator@12810000 {
++              compatible = "samsung,exynos4210-rotator";
++              reg = <0x12810000 0x1000>;
++              interrupts = <0 83 0>;
++              clocks = <&clock 278>;
++              clock-names = "rotator";
++      };
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
+index d5fed49..d9bacd2 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_rotator.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
+@@ -635,19 +635,96 @@ static int rotator_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd)
+       return 0;
+ }
++static struct rot_limit_table rot_limit_tbl_4210 = {
++      .ycbcr420_2p = {
++              .min_w = 32,
++              .min_h = 32,
++              .max_w = SZ_64K,
++              .max_h = SZ_64K,
++              .align = 3,
++      },
++      .rgb888 = {
++              .min_w = 8,
++              .min_h = 8,
++              .max_w = SZ_16K,
++              .max_h = SZ_16K,
++              .align = 2,
++      },
++};
++
++static struct rot_limit_table rot_limit_tbl_4x12 = {
++      .ycbcr420_2p = {
++              .min_w = 32,
++              .min_h = 32,
++              .max_w = SZ_32K,
++              .max_h = SZ_32K,
++              .align = 3,
++      },
++      .rgb888 = {
++              .min_w = 8,
++              .min_h = 8,
++              .max_w = SZ_8K,
++              .max_h = SZ_8K,
++              .align = 2,
++      },
++};
++
++static struct rot_limit_table rot_limit_tbl_5250 = {
++      .ycbcr420_2p = {
++              .min_w = 32,
++              .min_h = 32,
++              .max_w = SZ_32K,
++              .max_h = SZ_32K,
++              .align = 3,
++      },
++      .rgb888 = {
++              .min_w = 8,
++              .min_h = 8,
++              .max_w = SZ_8K,
++              .max_h = SZ_8K,
++              .align = 1,
++      },
++};
++
++static const struct of_device_id exynos_rotator_match[] = {
++      {
++              .compatible = "samsung,exynos4210-rotator",
++              .data = &rot_limit_tbl_4210,
++      },
++      {
++              .compatible = "samsung,exynos4212-rotator",
++              .data = &rot_limit_tbl_4x12,
++      },
++      {
++              .compatible = "samsung,exynos5250-rotator",
++              .data = &rot_limit_tbl_5250,
++      },
++      {},
++};
++
+ static int rotator_probe(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+       struct rot_context *rot;
+       struct exynos_drm_ippdrv *ippdrv;
++      const struct of_device_id *match;
+       int ret;
++      if (!dev->of_node) {
++              dev_err(dev, "cannot find of_node.\n");
++              return -ENODEV;
++      }
++
+       rot = devm_kzalloc(dev, sizeof(*rot), GFP_KERNEL);
+       if (!rot)
+               return -ENOMEM;
+-      rot->limit_tbl = (struct rot_limit_table *)
+-                              platform_get_device_id(pdev)->driver_data;
++      match = of_match_node(exynos_rotator_match, dev->of_node);
++      if (!match) {
++              dev_err(dev, "failed to match node\n");
++              return -ENODEV;
++      }
++      rot->limit_tbl = (struct rot_limit_table *)match->data;
+       rot->regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       rot->regs = devm_ioremap_resource(dev, rot->regs_res);
+@@ -719,31 +796,6 @@ static int rotator_remove(struct platform_device *pdev)
+       return 0;
+ }
+-static struct rot_limit_table rot_limit_tbl = {
+-      .ycbcr420_2p = {
+-              .min_w = 32,
+-              .min_h = 32,
+-              .max_w = SZ_32K,
+-              .max_h = SZ_32K,
+-              .align = 3,
+-      },
+-      .rgb888 = {
+-              .min_w = 8,
+-              .min_h = 8,
+-              .max_w = SZ_8K,
+-              .max_h = SZ_8K,
+-              .align = 2,
+-      },
+-};
+-
+-static struct platform_device_id rotator_driver_ids[] = {
+-      {
+-              .name           = "exynos-rot",
+-              .driver_data    = (unsigned long)&rot_limit_tbl,
+-      },
+-      {},
+-};
+-
+ static int rotator_clk_crtl(struct rot_context *rot, bool enable)
+ {
+       if (enable) {
+@@ -805,10 +857,10 @@ static const struct dev_pm_ops rotator_pm_ops = {
+ struct platform_driver rotator_driver = {
+       .probe          = rotator_probe,
+       .remove         = rotator_remove,
+-      .id_table       = rotator_driver_ids,
+       .driver         = {
+               .name   = "exynos-rot",
+               .owner  = THIS_MODULE,
+               .pm     = &rotator_pm_ops,
++              .of_match_table = exynos_rotator_match,
+       },
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0600-ARM-dts-Add-rotator-node-for-exynos4210.patch b/patches.tizen/0600-ARM-dts-Add-rotator-node-for-exynos4210.patch
new file mode 100644 (file)
index 0000000..06529ac
--- /dev/null
@@ -0,0 +1,40 @@
+From ed6076ad1d1c1959bc632e4ee7969a128454f739 Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Mon, 12 Aug 2013 22:49:16 +0900
+Subject: [PATCH 0600/1302] ARM: dts: Add rotator node for exynos4210
+
+This patch adds a rotator node for exynos4210. The exynos4210 has different
+limitation of image size compared with later chips.
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Cc: Thomas Abraham <thomas.abraham@linaro.org>
+Cc: Kukjin Kim <kgene.kim@samsung.com>
+Cc: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index e084b26..e3e47a1 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -268,6 +268,14 @@
+               status = "disabled";
+       };
++      rotator@12810000 {
++              compatible = "samsung,exynos4210-rotator";
++              reg = <0x12810000 0x1000>;
++              interrupts = <0 83 0>;
++              clocks = <&clock 278>;
++              clock-names = "rotator";
++      };
++
+       mfc: codec@13400000 {
+               compatible = "samsung,mfc-v5";
+               reg = <0x13400000 0x10000>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0601-ARM-dts-Add-rotator-node-for-exynos4x12.patch b/patches.tizen/0601-ARM-dts-Add-rotator-node-for-exynos4x12.patch
new file mode 100644 (file)
index 0000000..48dfb3b
--- /dev/null
@@ -0,0 +1,35 @@
+From fd20e132f43824be4f17bf89a66b5df9d60a16d4 Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Mon, 12 Aug 2013 22:49:53 +0900
+Subject: [PATCH 0601/1302] ARM: dts: Add rotator node for exynos4x12
+
+This patch adds a rotator node for exynos4212 and 4412. These have different
+limitation of image size compared with the exynos4210. So, we should define
+new compatible to distinguish it from the exynos4210.
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Cc: Thomas Abraham <thomas.abraham@linaro.org>
+Cc: Kukjin Kim <kgene.kim@samsung.com>
+Cc: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12.dtsi | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index 6c1c5eb..7c11261 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -357,4 +357,8 @@
+               clock-names = "tmu_apbif";
+               status = "disabled";
+       };
++
++      rotator@12810000 {
++              compatible = "samsung,exynos4212-rotator";
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0602-ARM-dts-Add-rotator-node-for-exynos5250.patch b/patches.tizen/0602-ARM-dts-Add-rotator-node-for-exynos5250.patch
new file mode 100644 (file)
index 0000000..2454d52
--- /dev/null
@@ -0,0 +1,41 @@
+From f9dab37467eb7d84572d836d9664e30e49a1c35d Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Mon, 12 Aug 2013 22:50:22 +0900
+Subject: [PATCH 0602/1302] ARM: dts: Add rotator node for exynos5250
+
+This patch adds a rotator node for exynos5250. It has different align value of
+image size compared with any other chips. So, we should define new compatible
+for the exynos5250.
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Cc: Thomas Abraham <thomas.abraham@linaro.org>
+Cc: Kukjin Kim <kgene.kim@samsung.com>
+Cc: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos5250.dtsi | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
+index c49d73e..236de09 100644
+--- a/arch/arm/boot/dts/exynos5250.dtsi
++++ b/arch/arm/boot/dts/exynos5250.dtsi
+@@ -588,6 +588,14 @@
+               };
+       };
++      rotator@11C00000 {
++              compatible = "samsung,exynos5250-rotator";
++              reg = <0x11C00000 0x1000>;
++              interrupts = <0 84 0>;
++              clocks = <&clock 269>;
++              clock-names = "rotator";
++      };
++
+       gsc_0:  gsc@0x13e00000 {
+               compatible = "samsung,exynos5-gsc";
+               reg = <0x13e00000 0x1000>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0603-ARM-dts-exynos4x12-specify-iommu-node-for-rotator.patch b/patches.tizen/0603-ARM-dts-exynos4x12-specify-iommu-node-for-rotator.patch
new file mode 100644 (file)
index 0000000..cdc0b85
--- /dev/null
@@ -0,0 +1,27 @@
+From 5b06c10c070d637d2ffd1d5ed783048b25a99c0a Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Mon, 2 Sep 2013 14:53:27 +0900
+Subject: [PATCH 0603/1302] ARM: dts: exynos4x12: specify iommu node for
+ rotator
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index e3e47a1..aa7fb0b 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -274,6 +274,7 @@
+               interrupts = <0 83 0>;
+               clocks = <&clock 278>;
+               clock-names = "rotator";
++              iommu = <&sysmmu_rotator>;
+       };
+       mfc: codec@13400000 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0604-Revert-ARM-dts-exynos4x12-add-usb-sysreg-node.patch b/patches.tizen/0604-Revert-ARM-dts-exynos4x12-add-usb-sysreg-node.patch
new file mode 100644 (file)
index 0000000..0c02225
--- /dev/null
@@ -0,0 +1,28 @@
+From 641461333d3c6c23561257354bdd6248014a3214 Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Mon, 2 Sep 2013 15:37:11 +0900
+Subject: [PATCH 0604/1302] Revert "ARM: dts: exynos4x12: add usb sysreg node"
+
+This reverts commit 4c3885e75920886c5a4f9dd206bc2774eb345ed0.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index 7c11261..77241e1 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -199,7 +199,7 @@
+               status = "disabled";
+               usbphy-sys {
+-                      reg = <0x10020704 0x0c>, <0x1001021C 0x04>;
++                      reg = <0x10020704 0x0c>;
+               };
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0605-usb-gadget-u_ether-convert-into-module.patch b/patches.tizen/0605-usb-gadget-u_ether-convert-into-module.patch
new file mode 100644 (file)
index 0000000..e40d5e3
--- /dev/null
@@ -0,0 +1,603 @@
+From dd66ad0a046b89e20f69f5635175321da57bccb7 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 23 May 2013 09:22:03 +0200
+Subject: [PATCH 0605/1302] usb: gadget: u_ether: convert into module
+
+u_ether.c has been #include'd by all gadgets which implement
+USB Ethernet functions. In order to add configfs support,
+the f_ecm.c, f_eem.c, f_ncm.c, f_subset.c, f_rndis.c need to be
+converted into modules and must not be #include'd. Consequently,
+the u_ether.c needs to be a module too, in a manner similar
+to u_serial.c. The resulting module should not take any parameters,
+so they are pushed to the current users of it, that is ether.c,
+g_ffs.c, multi.c, ncm.c, nokia.c.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig   | 10 ++++++++++
+ drivers/usb/gadget/Makefile  |  1 +
+ drivers/usb/gadget/cdc2.c    | 10 ++++++----
+ drivers/usb/gadget/ether.c   | 14 ++++++++------
+ drivers/usb/gadget/g_ffs.c   | 13 ++++++++-----
+ drivers/usb/gadget/multi.c   | 13 ++++++++-----
+ drivers/usb/gadget/ncm.c     | 10 ++++++----
+ drivers/usb/gadget/nokia.c   | 11 +++++++----
+ drivers/usb/gadget/u_ether.c | 38 ++++++++++++++++++--------------------
+ drivers/usb/gadget/u_ether.h | 30 ++++++++++++++++++++++++++----
+ 10 files changed, 98 insertions(+), 52 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index cefb5d6..751b472 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -507,6 +507,9 @@ config USB_F_SS_LB
+ config USB_U_SERIAL
+       tristate
++config USB_U_ETHER
++      tristate
++
+ config USB_F_SERIAL
+       tristate
+@@ -603,6 +606,7 @@ config USB_ETH
+       tristate "Ethernet Gadget (with CDC Ethernet support)"
+       depends on NET
+       select USB_LIBCOMPOSITE
++      select USB_U_ETHER
+       select CRC32
+       help
+         This driver implements Ethernet style communication, in one of
+@@ -675,6 +679,7 @@ config USB_G_NCM
+       tristate "Network Control Model (NCM) support"
+       depends on NET
+       select USB_LIBCOMPOSITE
++      select USB_U_ETHER
+       select CRC32
+       help
+         This driver implements USB CDC NCM subclass standard. NCM is
+@@ -718,6 +723,7 @@ config USB_FUNCTIONFS
+ config USB_FUNCTIONFS_ETH
+       bool "Include configuration with CDC ECM (Ethernet)"
+       depends on USB_FUNCTIONFS && NET
++      select USB_U_ETHER
+       help
+         Include a configuration with CDC ECM function (Ethernet) and the
+         Function Filesystem.
+@@ -725,6 +731,7 @@ config USB_FUNCTIONFS_ETH
+ config USB_FUNCTIONFS_RNDIS
+       bool "Include configuration with RNDIS (Ethernet)"
+       depends on USB_FUNCTIONFS && NET
++      select USB_U_ETHER
+       help
+         Include a configuration with RNDIS function (Ethernet) and the Filesystem.
+@@ -825,6 +832,7 @@ config USB_CDC_COMPOSITE
+       depends on NET
+       select USB_LIBCOMPOSITE
+       select USB_U_SERIAL
++      select USB_U_ETHER
+       select USB_F_ACM
+       help
+         This driver provides two functions in one configuration:
+@@ -842,6 +850,7 @@ config USB_G_NOKIA
+       depends on PHONET
+       select USB_LIBCOMPOSITE
+       select USB_U_SERIAL
++      select USB_U_ETHER
+       select USB_F_ACM
+       help
+         The Nokia composite gadget provides support for acm, obex
+@@ -869,6 +878,7 @@ config USB_G_MULTI
+       select USB_G_MULTI_CDC if !USB_G_MULTI_RNDIS
+       select USB_LIBCOMPOSITE
+       select USB_U_SERIAL
++      select USB_U_ETHER
+       select USB_F_ACM
+       help
+         The Multifunction Composite Gadget provides Ethernet (RNDIS
+diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
+index 6afd166..b6c2bf7 100644
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -45,6 +45,7 @@ usb_f_serial-y                       := f_serial.o
+ obj-$(CONFIG_USB_F_SERIAL)    += usb_f_serial.o
+ usb_f_obex-y                  := f_obex.o
+ obj-$(CONFIG_USB_F_OBEX)      += usb_f_obex.o
++obj-$(CONFIG_USB_U_ETHER)     += u_ether.o
+ #
+ # USB gadget drivers
+diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c
+index 2c52551..bffa997 100644
+--- a/drivers/usb/gadget/cdc2.c
++++ b/drivers/usb/gadget/cdc2.c
+@@ -35,6 +35,8 @@
+ /*-------------------------------------------------------------------------*/
+ USB_GADGET_COMPOSITE_OPTIONS();
++USB_ETHERNET_MODULE_PARAMETERS();
++
+ /*
+  * Kbuild is not very cooperative with respect to linking separately
+  * compiled library objects into one module.  So for now we won't use
+@@ -43,7 +45,6 @@ USB_GADGET_COMPOSITE_OPTIONS();
+  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+  */
+ #include "f_ecm.c"
+-#include "u_ether.c"
+ /*-------------------------------------------------------------------------*/
+@@ -102,7 +103,7 @@ static struct usb_gadget_strings *dev_strings[] = {
+       NULL,
+ };
+-static u8 hostaddr[ETH_ALEN];
++static u8 host_mac[ETH_ALEN];
+ static struct eth_dev *the_dev;
+ /*-------------------------------------------------------------------------*/
+ static struct usb_function *f_acm;
+@@ -120,7 +121,7 @@ static int __init cdc_do_config(struct usb_configuration *c)
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+-      status = ecm_bind_config(c, hostaddr, the_dev);
++      status = ecm_bind_config(c, host_mac, the_dev);
+       if (status < 0)
+               return status;
+@@ -166,7 +167,8 @@ static int __init cdc_bind(struct usb_composite_dev *cdev)
+       }
+       /* set up network link layer */
+-      the_dev = gether_setup(cdev->gadget, hostaddr);
++      the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, host_mac,
++                             qmult);
+       if (IS_ERR(the_dev))
+               return PTR_ERR(the_dev);
+diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
+index 56c8eca..75418c7 100644
+--- a/drivers/usb/gadget/ether.c
++++ b/drivers/usb/gadget/ether.c
+@@ -107,11 +107,12 @@ static inline bool has_rndis(void)
+ #include "rndis.c"
+ #endif
+ #include "f_eem.c"
+-#include "u_ether.c"
+ /*-------------------------------------------------------------------------*/
+ USB_GADGET_COMPOSITE_OPTIONS();
++USB_ETHERNET_MODULE_PARAMETERS();
++
+ /* DO NOT REUSE THESE IDs with a protocol-incompatible driver!!  Ever!!
+  * Instead:  allocate your own, using normal USB-IF procedures.
+  */
+@@ -206,7 +207,7 @@ static struct usb_gadget_strings *dev_strings[] = {
+       NULL,
+ };
+-static u8 hostaddr[ETH_ALEN];
++static u8 host_mac[ETH_ALEN];
+ static struct eth_dev *the_dev;
+ /*-------------------------------------------------------------------------*/
+@@ -224,7 +225,7 @@ static int __init rndis_do_config(struct usb_configuration *c)
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+-      return rndis_bind_config(c, hostaddr, the_dev);
++      return rndis_bind_config(c, host_mac, the_dev);
+ }
+ static struct usb_configuration rndis_config_driver = {
+@@ -259,9 +260,9 @@ static int __init eth_do_config(struct usb_configuration *c)
+       if (use_eem)
+               return eem_bind_config(c, the_dev);
+       else if (can_support_ecm(c->cdev->gadget))
+-              return ecm_bind_config(c, hostaddr, the_dev);
++              return ecm_bind_config(c, host_mac, the_dev);
+       else
+-              return geth_bind_config(c, hostaddr, the_dev);
++              return geth_bind_config(c, host_mac, the_dev);
+ }
+ static struct usb_configuration eth_config_driver = {
+@@ -279,7 +280,8 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
+       int                     status;
+       /* set up network link layer */
+-      the_dev = gether_setup(cdev->gadget, hostaddr);
++      the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, host_mac,
++                             qmult);
+       if (IS_ERR(the_dev))
+               return PTR_ERR(the_dev);
+diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
+index 787a78e..45f26be 100644
+--- a/drivers/usb/gadget/g_ffs.c
++++ b/drivers/usb/gadget/g_ffs.c
+@@ -34,9 +34,9 @@
+ #    include "f_rndis.c"
+ #    include "rndis.c"
+ #  endif
+-#  include "u_ether.c"
++#  include "u_ether.h"
+-static u8 gfs_hostaddr[ETH_ALEN];
++static u8 gfs_host_mac[ETH_ALEN];
+ static struct eth_dev *the_dev;
+ #  ifdef CONFIG_USB_FUNCTIONFS_ETH
+ static int eth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+@@ -45,7 +45,7 @@ static int eth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+ #else
+ #  define the_dev     NULL
+ #  define gether_cleanup(dev) do { } while (0)
+-#  define gfs_hostaddr NULL
++#  define gfs_host_mac NULL
+ struct eth_dev;
+ #endif
+@@ -73,6 +73,8 @@ struct gfs_ffs_obj {
+ USB_GADGET_COMPOSITE_OPTIONS();
++USB_ETHERNET_MODULE_PARAMETERS();
++
+ static struct usb_device_descriptor gfs_dev_desc = {
+       .bLength                = sizeof gfs_dev_desc,
+       .bDescriptorType        = USB_DT_DEVICE,
+@@ -350,7 +352,8 @@ static int gfs_bind(struct usb_composite_dev *cdev)
+       if (missing_funcs)
+               return -ENODEV;
+ #if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS
+-      the_dev = gether_setup(cdev->gadget, gfs_hostaddr);
++      the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, gfs_host_mac,
++                             qmult);
+ #endif
+       if (IS_ERR(the_dev)) {
+               ret = PTR_ERR(the_dev);
+@@ -446,7 +449,7 @@ static int gfs_do_config(struct usb_configuration *c)
+       }
+       if (gc->eth) {
+-              ret = gc->eth(c, gfs_hostaddr, the_dev);
++              ret = gc->eth(c, gfs_host_mac, the_dev);
+               if (unlikely(ret < 0))
+                       return ret;
+       }
+diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
+index 4a45e80..cdb8dbf 100644
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -49,10 +49,12 @@ MODULE_LICENSE("GPL");
+ #  include "f_rndis.c"
+ #  include "rndis.c"
+ #endif
+-#include "u_ether.c"
++#include "u_ether.h"
+ USB_GADGET_COMPOSITE_OPTIONS();
++USB_ETHERNET_MODULE_PARAMETERS();
++
+ /***************************** Device Descriptor ****************************/
+ #define MULTI_VENDOR_NUM      0x1d6b  /* Linux Foundation */
+@@ -133,7 +135,7 @@ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
+ static struct fsg_common fsg_common;
+-static u8 hostaddr[ETH_ALEN];
++static u8 host_mac[ETH_ALEN];
+ static struct usb_function_instance *fi_acm;
+ static struct eth_dev *the_dev;
+@@ -152,7 +154,7 @@ static __init int rndis_do_config(struct usb_configuration *c)
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+-      ret = rndis_bind_config(c, hostaddr, the_dev);
++      ret = rndis_bind_config(c, host_mac, the_dev);
+       if (ret < 0)
+               return ret;
+@@ -216,7 +218,7 @@ static __init int cdc_do_config(struct usb_configuration *c)
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+-      ret = ecm_bind_config(c, hostaddr, the_dev);
++      ret = ecm_bind_config(c, host_mac, the_dev);
+       if (ret < 0)
+               return ret;
+@@ -280,7 +282,8 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
+       }
+       /* set up network link layer */
+-      the_dev = gether_setup(cdev->gadget, hostaddr);
++      the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, host_mac,
++                             qmult);
+       if (IS_ERR(the_dev))
+               return PTR_ERR(the_dev);
+diff --git a/drivers/usb/gadget/ncm.c b/drivers/usb/gadget/ncm.c
+index 3b02fd4..e411135 100644
+--- a/drivers/usb/gadget/ncm.c
++++ b/drivers/usb/gadget/ncm.c
+@@ -37,7 +37,6 @@
+  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+  */
+ #include "f_ncm.c"
+-#include "u_ether.c"
+ /*-------------------------------------------------------------------------*/
+@@ -54,6 +53,8 @@
+ /*-------------------------------------------------------------------------*/
+ USB_GADGET_COMPOSITE_OPTIONS();
++USB_ETHERNET_MODULE_PARAMETERS();
++
+ static struct usb_device_descriptor device_desc = {
+       .bLength =              sizeof device_desc,
+       .bDescriptorType =      USB_DT_DEVICE,
+@@ -112,7 +113,7 @@ static struct usb_gadget_strings *dev_strings[] = {
+ };
+ struct eth_dev *the_dev;
+-static u8 hostaddr[ETH_ALEN];
++static u8 host_mac[ETH_ALEN];
+ /*-------------------------------------------------------------------------*/
+@@ -125,7 +126,7 @@ static int __init ncm_do_config(struct usb_configuration *c)
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+-      return ncm_bind_config(c, hostaddr, the_dev);
++      return ncm_bind_config(c, host_mac, the_dev);
+ }
+ static struct usb_configuration ncm_config_driver = {
+@@ -144,7 +145,8 @@ static int __init gncm_bind(struct usb_composite_dev *cdev)
+       int                     status;
+       /* set up network link layer */
+-      the_dev = gether_setup(cdev->gadget, hostaddr);
++      the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, host_mac,
++                             qmult);
+       if (IS_ERR(the_dev))
+               return PTR_ERR(the_dev);
+diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c
+index 3b344b4..39f6cb5 100644
+--- a/drivers/usb/gadget/nokia.c
++++ b/drivers/usb/gadget/nokia.c
+@@ -41,11 +41,13 @@
+ #include "f_ecm.c"
+ #include "f_obex.c"
+ #include "f_phonet.c"
+-#include "u_ether.c"
++#include "u_ether.h"
+ /*-------------------------------------------------------------------------*/
+ USB_GADGET_COMPOSITE_OPTIONS();
++USB_ETHERNET_MODULE_PARAMETERS();
++
+ #define NOKIA_VENDOR_ID                       0x0421  /* Nokia */
+ #define NOKIA_PRODUCT_ID              0x01c8  /* Nokia Gadget */
+@@ -98,7 +100,7 @@ MODULE_LICENSE("GPL");
+ /*-------------------------------------------------------------------------*/
+ static struct usb_function *f_acm_cfg1;
+ static struct usb_function *f_acm_cfg2;
+-static u8 hostaddr[ETH_ALEN];
++static u8 host_mac[ETH_ALEN];
+ static struct eth_dev *the_dev;
+ enum {
+@@ -152,7 +154,7 @@ static int __init nokia_bind_config(struct usb_configuration *c)
+       if (status)
+               goto err_conf;
+-      status = ecm_bind_config(c, hostaddr, the_dev);
++      status = ecm_bind_config(c, host_mac, the_dev);
+       if (status) {
+               pr_debug("could not bind ecm config %d\n", status);
+               goto err_ecm;
+@@ -186,7 +188,8 @@ static int __init nokia_bind(struct usb_composite_dev *cdev)
+                       goto err_ether;
+       }
+-      the_dev = gether_setup(cdev->gadget, hostaddr);
++      the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, host_mac,
++                             qmult);
+       if (IS_ERR(the_dev)) {
+               status = PTR_ERR(the_dev);
+               goto err_ether;
+diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
+index 4b76124..5f9dacf 100644
+--- a/drivers/usb/gadget/u_ether.c
++++ b/drivers/usb/gadget/u_ether.c
+@@ -63,6 +63,8 @@ struct eth_dev {
+       struct sk_buff_head     rx_frames;
++      unsigned                qmult;
++
+       unsigned                header_len;
+       struct sk_buff          *(*wrap)(struct gether *, struct sk_buff *skb);
+       int                     (*unwrap)(struct gether *,
+@@ -84,12 +86,8 @@ struct eth_dev {
+ #define DEFAULT_QLEN  2       /* double buffering by default */
+-static unsigned qmult = 5;
+-module_param(qmult, uint, S_IRUGO|S_IWUSR);
+-MODULE_PARM_DESC(qmult, "queue length multiplier at high/super speed");
+-
+ /* for dual-speed hardware, use deeper queues at high/super speed */
+-static inline int qlen(struct usb_gadget *gadget)
++static inline int qlen(struct usb_gadget *gadget, unsigned qmult)
+ {
+       if (gadget_is_dualspeed(gadget) && (gadget->speed == USB_SPEED_HIGH ||
+                                           gadget->speed == USB_SPEED_SUPER))
+@@ -588,7 +586,7 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb,
+       if (gadget_is_dualspeed(dev->gadget))
+               req->no_interrupt = (dev->gadget->speed == USB_SPEED_HIGH ||
+                                    dev->gadget->speed == USB_SPEED_SUPER)
+-                      ? ((atomic_read(&dev->tx_qlen) % qmult) != 0)
++                      ? ((atomic_read(&dev->tx_qlen) % dev->qmult) != 0)
+                       : 0;
+       retval = usb_ep_queue(in, req, GFP_ATOMIC);
+@@ -697,16 +695,6 @@ static int eth_stop(struct net_device *net)
+ /*-------------------------------------------------------------------------*/
+-/* initial value, changed by "ifconfig usb0 hw ether xx:xx:xx:xx:xx:xx" */
+-static char *dev_addr;
+-module_param(dev_addr, charp, S_IRUGO);
+-MODULE_PARM_DESC(dev_addr, "Device Ethernet Address");
+-
+-/* this address is invisible to ifconfig */
+-static char *host_addr;
+-module_param(host_addr, charp, S_IRUGO);
+-MODULE_PARM_DESC(host_addr, "Host Ethernet Address");
+-
+ static int get_ether_addr(const char *str, u8 *dev_addr)
+ {
+       if (str) {
+@@ -755,8 +743,9 @@ static struct device_type gadget_type = {
+  *
+  * Returns negative errno, or zero on success
+  */
+-struct eth_dev *gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN],
+-              const char *netname)
++struct eth_dev *gether_setup_name(struct usb_gadget *g,
++              const char *dev_addr, const char *host_addr,
++              u8 ethaddr[ETH_ALEN], unsigned qmult, const char *netname)
+ {
+       struct eth_dev          *dev;
+       struct net_device       *net;
+@@ -777,6 +766,7 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN],
+       /* network device setup */
+       dev->net = net;
++      dev->qmult = qmult;
+       snprintf(net->name, sizeof(net->name), "%s%%d", netname);
+       if (get_ether_addr(dev_addr, net->dev_addr))
+@@ -815,6 +805,7 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN],
+       return dev;
+ }
++EXPORT_SYMBOL(gether_setup_name);
+ /**
+  * gether_cleanup - remove Ethernet-over-USB device
+@@ -831,6 +822,7 @@ void gether_cleanup(struct eth_dev *dev)
+       flush_work(&dev->work);
+       free_netdev(dev->net);
+ }
++EXPORT_SYMBOL(gether_cleanup);
+ /**
+  * gether_connect - notify network layer that USB link is active
+@@ -873,11 +865,12 @@ struct net_device *gether_connect(struct gether *link)
+       }
+       if (result == 0)
+-              result = alloc_requests(dev, link, qlen(dev->gadget));
++              result = alloc_requests(dev, link, qlen(dev->gadget,
++                                      dev->qmult));
+       if (result == 0) {
+               dev->zlp = link->is_zlp_ok;
+-              DBG(dev, "qlen %d\n", qlen(dev->gadget));
++              DBG(dev, "qlen %d\n", qlen(dev->gadget, dev->qmult));
+               dev->header_len = link->header_len;
+               dev->unwrap = link->unwrap;
+@@ -910,6 +903,7 @@ fail0:
+               return ERR_PTR(result);
+       return dev->net;
+ }
++EXPORT_SYMBOL(gether_connect);
+ /**
+  * gether_disconnect - notify network layer that USB link is inactive
+@@ -980,3 +974,7 @@ void gether_disconnect(struct gether *link)
+       dev->port_usb = NULL;
+       spin_unlock(&dev->lock);
+ }
++EXPORT_SYMBOL(gether_disconnect);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("David Brownell");
+diff --git a/drivers/usb/gadget/u_ether.h b/drivers/usb/gadget/u_ether.h
+index 0252233..02f58ac 100644
+--- a/drivers/usb/gadget/u_ether.h
++++ b/drivers/usb/gadget/u_ether.h
+@@ -21,6 +21,26 @@
+ #include "gadget_chips.h"
++#define QMULT_DEFAULT 5
++
++/*
++ * dev_addr: initial value
++ * changed by "ifconfig usb0 hw ether xx:xx:xx:xx:xx:xx"
++ * host_addr: this address is invisible to ifconfig
++ */
++#define USB_ETHERNET_MODULE_PARAMETERS() \
++      static unsigned qmult = QMULT_DEFAULT;                          \
++      module_param(qmult, uint, S_IRUGO|S_IWUSR);                     \
++      MODULE_PARM_DESC(qmult, "queue length multiplier at high/super speed");\
++                                                                      \
++      static char *dev_addr;                                          \
++      module_param(dev_addr, charp, S_IRUGO);                         \
++      MODULE_PARM_DESC(dev_addr, "Device Ethernet Address");          \
++                                                                      \
++      static char *host_addr;                                         \
++      module_param(host_addr, charp, S_IRUGO);                        \
++      MODULE_PARM_DESC(host_addr, "Host Ethernet Address")
++
+ struct eth_dev;
+ /*
+@@ -71,8 +91,9 @@ struct gether {
+                       |USB_CDC_PACKET_TYPE_DIRECTED)
+ /* variant of gether_setup that allows customizing network device name */
+-struct eth_dev *gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN],
+-              const char *netname);
++struct eth_dev *gether_setup_name(struct usb_gadget *g,
++              const char *dev_addr, const char *host_addr,
++              u8 ethaddr[ETH_ALEN], unsigned qmult, const char *netname);
+ /* netdev setup/teardown as directed by the gadget driver */
+ /* gether_setup - initialize one ethernet-over-usb link
+@@ -88,9 +109,10 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN],
+  * Returns negative errno, or zero on success
+  */
+ static inline struct eth_dev *gether_setup(struct usb_gadget *g,
+-              u8 ethaddr[ETH_ALEN])
++              const char *dev_addr, const char *host_addr,
++              u8 ethaddr[ETH_ALEN], unsigned qmult)
+ {
+-      return gether_setup_name(g, ethaddr, "usb");
++      return gether_setup_name(g, dev_addr, host_addr, ethaddr, qmult, "usb");
+ }
+ void gether_cleanup(struct eth_dev *dev);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0606-usb-gadget-rndis-convert-into-module.patch b/patches.tizen/0606-usb-gadget-rndis-convert-into-module.patch
new file mode 100644 (file)
index 0000000..1deabf8
--- /dev/null
@@ -0,0 +1,269 @@
+From 05c662b19d916876193bbd61181ca3b6de175ea3 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Fri, 24 May 2013 10:23:02 +0200
+Subject: [PATCH 0606/1302] usb: gadget: rndis: convert into module
+
+In order to convert to configfs the usb functions need to be converted
+to a new interface and compiled as modules. This patch creates an rndis
+module which will be used by the new functions. After all users of
+f_rndis are converted to the new interface, this module can be
+merged with f_rndis module.
+
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig  |  6 ++++++
+ drivers/usb/gadget/Makefile |  2 ++
+ drivers/usb/gadget/ether.c  |  4 +++-
+ drivers/usb/gadget/g_ffs.c  |  2 +-
+ drivers/usb/gadget/multi.c  |  2 +-
+ drivers/usb/gadget/rndis.c  | 18 ++++++++++++++++++
+ drivers/usb/gadget/rndis.h  |  1 +
+ 7 files changed, 32 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 751b472..3cde222 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -510,6 +510,9 @@ config USB_U_SERIAL
+ config USB_U_ETHER
+       tristate
++config USB_U_RNDIS
++      tristate
++
+ config USB_F_SERIAL
+       tristate
+@@ -607,6 +610,7 @@ config USB_ETH
+       depends on NET
+       select USB_LIBCOMPOSITE
+       select USB_U_ETHER
++      select USB_U_RNDIS
+       select CRC32
+       help
+         This driver implements Ethernet style communication, in one of
+@@ -732,6 +736,7 @@ config USB_FUNCTIONFS_RNDIS
+       bool "Include configuration with RNDIS (Ethernet)"
+       depends on USB_FUNCTIONFS && NET
+       select USB_U_ETHER
++      select USB_U_RNDIS
+       help
+         Include a configuration with RNDIS function (Ethernet) and the Filesystem.
+@@ -879,6 +884,7 @@ config USB_G_MULTI
+       select USB_LIBCOMPOSITE
+       select USB_U_SERIAL
+       select USB_U_ETHER
++      select USB_U_RNDIS
+       select USB_F_ACM
+       help
+         The Multifunction Composite Gadget provides Ethernet (RNDIS
+diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
+index b6c2bf7..7a0463e 100644
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -46,6 +46,8 @@ obj-$(CONFIG_USB_F_SERIAL)   += usb_f_serial.o
+ usb_f_obex-y                  := f_obex.o
+ obj-$(CONFIG_USB_F_OBEX)      += usb_f_obex.o
+ obj-$(CONFIG_USB_U_ETHER)     += u_ether.o
++u_rndis-y                     := rndis.o
++obj-$(CONFIG_USB_U_RNDIS)     += u_rndis.o
+ #
+ # USB gadget drivers
+diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
+index 75418c7..6bff24f 100644
+--- a/drivers/usb/gadget/ether.c
++++ b/drivers/usb/gadget/ether.c
+@@ -91,6 +91,8 @@ static inline bool has_rndis(void)
+ #endif
+ }
++#include <linux/module.h>
++
+ /*-------------------------------------------------------------------------*/
+ /*
+@@ -104,7 +106,7 @@ static inline bool has_rndis(void)
+ #include "f_subset.c"
+ #ifdef        USB_ETH_RNDIS
+ #include "f_rndis.c"
+-#include "rndis.c"
++#include "rndis.h"
+ #endif
+ #include "f_eem.c"
+diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
+index 45f26be..fbfdb53 100644
+--- a/drivers/usb/gadget/g_ffs.c
++++ b/drivers/usb/gadget/g_ffs.c
+@@ -32,7 +32,7 @@
+ #  include "f_subset.c"
+ #  ifdef USB_ETH_RNDIS
+ #    include "f_rndis.c"
+-#    include "rndis.c"
++#    include "rndis.h"
+ #  endif
+ #  include "u_ether.h"
+diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
+index cdb8dbf..ce21e9f 100644
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -47,7 +47,7 @@ MODULE_LICENSE("GPL");
+ #include "f_subset.c"
+ #ifdef USB_ETH_RNDIS
+ #  include "f_rndis.c"
+-#  include "rndis.c"
++#  include "rndis.h"
+ #endif
+ #include "u_ether.h"
+diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
+index 1e4cfb0..8c5e957 100644
+--- a/drivers/usb/gadget/rndis.c
++++ b/drivers/usb/gadget/rndis.c
+@@ -761,6 +761,7 @@ int rndis_signal_connect(int configNr)
+       return rndis_indicate_status_msg(configNr,
+                                         RNDIS_STATUS_MEDIA_CONNECT);
+ }
++EXPORT_SYMBOL(rndis_signal_connect);
+ int rndis_signal_disconnect(int configNr)
+ {
+@@ -769,6 +770,7 @@ int rndis_signal_disconnect(int configNr)
+       return rndis_indicate_status_msg(configNr,
+                                         RNDIS_STATUS_MEDIA_DISCONNECT);
+ }
++EXPORT_SYMBOL(rndis_signal_disconnect);
+ void rndis_uninit(int configNr)
+ {
+@@ -783,11 +785,13 @@ void rndis_uninit(int configNr)
+       while ((buf = rndis_get_next_response(configNr, &length)))
+               rndis_free_response(configNr, buf);
+ }
++EXPORT_SYMBOL(rndis_uninit);
+ void rndis_set_host_mac(int configNr, const u8 *addr)
+ {
+       rndis_per_dev_params[configNr].host_mac = addr;
+ }
++EXPORT_SYMBOL(rndis_set_host_mac);
+ /*
+  * Message Parser
+@@ -870,6 +874,7 @@ int rndis_msg_parser(u8 configNr, u8 *buf)
+       return -ENOTSUPP;
+ }
++EXPORT_SYMBOL(rndis_msg_parser);
+ int rndis_register(void (*resp_avail)(void *v), void *v)
+ {
+@@ -891,6 +896,7 @@ int rndis_register(void (*resp_avail)(void *v), void *v)
+       return -ENODEV;
+ }
++EXPORT_SYMBOL(rndis_register);
+ void rndis_deregister(int configNr)
+ {
+@@ -899,6 +905,7 @@ void rndis_deregister(int configNr)
+       if (configNr >= RNDIS_MAX_CONFIGS) return;
+       rndis_per_dev_params[configNr].used = 0;
+ }
++EXPORT_SYMBOL(rndis_deregister);
+ int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter)
+ {
+@@ -912,6 +919,7 @@ int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter)
+       return 0;
+ }
++EXPORT_SYMBOL(rndis_set_param_dev);
+ int rndis_set_param_vendor(u8 configNr, u32 vendorID, const char *vendorDescr)
+ {
+@@ -924,6 +932,7 @@ int rndis_set_param_vendor(u8 configNr, u32 vendorID, const char *vendorDescr)
+       return 0;
+ }
++EXPORT_SYMBOL(rndis_set_param_vendor);
+ int rndis_set_param_medium(u8 configNr, u32 medium, u32 speed)
+ {
+@@ -935,6 +944,7 @@ int rndis_set_param_medium(u8 configNr, u32 medium, u32 speed)
+       return 0;
+ }
++EXPORT_SYMBOL(rndis_set_param_medium);
+ void rndis_add_hdr(struct sk_buff *skb)
+ {
+@@ -949,6 +959,7 @@ void rndis_add_hdr(struct sk_buff *skb)
+       header->DataOffset = cpu_to_le32(36);
+       header->DataLength = cpu_to_le32(skb->len - sizeof(*header));
+ }
++EXPORT_SYMBOL(rndis_add_hdr);
+ void rndis_free_response(int configNr, u8 *buf)
+ {
+@@ -965,6 +976,7 @@ void rndis_free_response(int configNr, u8 *buf)
+               }
+       }
+ }
++EXPORT_SYMBOL(rndis_free_response);
+ u8 *rndis_get_next_response(int configNr, u32 *length)
+ {
+@@ -986,6 +998,7 @@ u8 *rndis_get_next_response(int configNr, u32 *length)
+       return NULL;
+ }
++EXPORT_SYMBOL(rndis_get_next_response);
+ static rndis_resp_t *rndis_add_response(int configNr, u32 length)
+ {
+@@ -1029,6 +1042,7 @@ int rndis_rm_hdr(struct gether *port,
+       skb_queue_tail(list, skb);
+       return 0;
+ }
++EXPORT_SYMBOL(rndis_rm_hdr);
+ #ifdef CONFIG_USB_GADGET_DEBUG_FILES
+@@ -1160,6 +1174,7 @@ int rndis_init(void)
+       return 0;
+ }
++EXPORT_SYMBOL(rndis_init);
+ void rndis_exit(void)
+ {
+@@ -1173,3 +1188,6 @@ void rndis_exit(void)
+       }
+ #endif
+ }
++EXPORT_SYMBOL(rndis_exit);
++
++MODULE_LICENSE("GPL");
+diff --git a/drivers/usb/gadget/rndis.h b/drivers/usb/gadget/rndis.h
+index 0647f2f..6e79615 100644
+--- a/drivers/usb/gadget/rndis.h
++++ b/drivers/usb/gadget/rndis.h
+@@ -16,6 +16,7 @@
+ #define _LINUX_RNDIS_H
+ #include <linux/rndis.h>
++#include "u_ether.h"
+ #include "ndis.h"
+ #define RNDIS_MAXIMUM_FRAME_SIZE      1518
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0607-usb-gadget-u_ether-construct-with-default-values-and.patch b/patches.tizen/0607-usb-gadget-u_ether-construct-with-default-values-and.patch
new file mode 100644 (file)
index 0000000..4e6a164
--- /dev/null
@@ -0,0 +1,376 @@
+From 6ca62aa5e25207a2bcda7bfa4cb823500d9763c7 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 23 May 2013 09:22:05 +0200
+Subject: [PATCH 0607/1302] usb: gadget: u_ether: construct with default values
+ and add setters/getters
+
+Add an interface to create a struct netdev_dev filled with default values, an
+interface which makes it an interface to fill the struct with useful values and
+an interface to read the values set.
+
+The patch also adds an interface to register the net device associated with an
+ethernet-over-usb link.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/u_ether.c | 185 ++++++++++++++++++++++++++++++++++++++++++-
+ drivers/usb/gadget/u_ether.h | 123 ++++++++++++++++++++++++++++
+ 2 files changed, 307 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
+index 5f9dacf..6d3ccdc 100644
+--- a/drivers/usb/gadget/u_ether.c
++++ b/drivers/usb/gadget/u_ether.c
+@@ -78,6 +78,7 @@ struct eth_dev {
+       bool                    zlp;
+       u8                      host_mac[ETH_ALEN];
++      u8                      dev_mac[ETH_ALEN];
+ };
+ /*-------------------------------------------------------------------------*/
+@@ -716,6 +717,17 @@ static int get_ether_addr(const char *str, u8 *dev_addr)
+       return 1;
+ }
++static int get_ether_addr_str(u8 dev_addr[ETH_ALEN], char *str, int len)
++{
++      if (len < 18)
++              return -EINVAL;
++
++      snprintf(str, len, "%02x:%02x:%02x:%02x:%02x:%02x",
++               dev_addr[0], dev_addr[1], dev_addr[2],
++               dev_addr[3], dev_addr[4], dev_addr[5]);
++      return 18;
++}
++
+ static const struct net_device_ops eth_netdev_ops = {
+       .ndo_open               = eth_open,
+       .ndo_stop               = eth_stop,
+@@ -796,7 +808,8 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g,
+               INFO(dev, "MAC %pM\n", net->dev_addr);
+               INFO(dev, "HOST MAC %pM\n", dev->host_mac);
+-              /* two kinds of host-initiated state changes:
++              /*
++               * two kinds of host-initiated state changes:
+                *  - iff DATA transfer is active, carrier is "on"
+                *  - tx queueing enabled if open *and* carrier is "on"
+                */
+@@ -807,6 +820,176 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g,
+ }
+ EXPORT_SYMBOL(gether_setup_name);
++struct net_device *gether_setup_name_default(const char *netname)
++{
++      struct net_device       *net;
++      struct eth_dev          *dev;
++
++      net = alloc_etherdev(sizeof(*dev));
++      if (!net)
++              return ERR_PTR(-ENOMEM);
++
++      dev = netdev_priv(net);
++      spin_lock_init(&dev->lock);
++      spin_lock_init(&dev->req_lock);
++      INIT_WORK(&dev->work, eth_work);
++      INIT_LIST_HEAD(&dev->tx_reqs);
++      INIT_LIST_HEAD(&dev->rx_reqs);
++
++      skb_queue_head_init(&dev->rx_frames);
++
++      /* network device setup */
++      dev->net = net;
++      dev->qmult = QMULT_DEFAULT;
++      snprintf(net->name, sizeof(net->name), "%s%%d", netname);
++
++      eth_random_addr(dev->dev_mac);
++      pr_warn("using random %s ethernet address\n", "self");
++      eth_random_addr(dev->host_mac);
++      pr_warn("using random %s ethernet address\n", "host");
++
++      net->netdev_ops = &eth_netdev_ops;
++
++      SET_ETHTOOL_OPS(net, &ops);
++      SET_NETDEV_DEVTYPE(net, &gadget_type);
++
++      return net;
++}
++EXPORT_SYMBOL(gether_setup_name_default);
++
++int gether_register_netdev(struct net_device *net)
++{
++      struct eth_dev *dev;
++      struct usb_gadget *g;
++      struct sockaddr sa;
++      int status;
++
++      if (!net->dev.parent)
++              return -EINVAL;
++      dev = netdev_priv(net);
++      g = dev->gadget;
++      status = register_netdev(net);
++      if (status < 0) {
++              dev_dbg(&g->dev, "register_netdev failed, %d\n", status);
++              return status;
++      } else {
++              INFO(dev, "HOST MAC %pM\n", dev->host_mac);
++
++              /* two kinds of host-initiated state changes:
++               *  - iff DATA transfer is active, carrier is "on"
++               *  - tx queueing enabled if open *and* carrier is "on"
++               */
++              netif_carrier_off(net);
++      }
++      sa.sa_family = net->type;
++      memcpy(sa.sa_data, dev->dev_mac, ETH_ALEN);
++      rtnl_lock();
++      status = dev_set_mac_address(net, &sa);
++      rtnl_unlock();
++      if (status)
++              pr_warn("cannot set self ethernet address: %d\n", status);
++      else
++              INFO(dev, "MAC %pM\n", dev->dev_mac);
++
++      return status;
++}
++EXPORT_SYMBOL(gether_register_netdev);
++
++void gether_set_gadget(struct net_device *net, struct usb_gadget *g)
++{
++      struct eth_dev *dev;
++
++      dev = netdev_priv(net);
++      dev->gadget = g;
++      SET_NETDEV_DEV(net, &g->dev);
++}
++EXPORT_SYMBOL(gether_set_gadget);
++
++int gether_set_dev_addr(struct net_device *net, const char *dev_addr)
++{
++      struct eth_dev *dev;
++      u8 new_addr[ETH_ALEN];
++
++      dev = netdev_priv(net);
++      if (get_ether_addr(dev_addr, new_addr))
++              return -EINVAL;
++      memcpy(dev->dev_mac, new_addr, ETH_ALEN);
++      return 0;
++}
++EXPORT_SYMBOL(gether_set_dev_addr);
++
++int gether_get_dev_addr(struct net_device *net, char *dev_addr, int len)
++{
++      struct eth_dev *dev;
++
++      dev = netdev_priv(net);
++      return get_ether_addr_str(dev->dev_mac, dev_addr, len);
++}
++EXPORT_SYMBOL(gether_get_dev_addr);
++
++int gether_set_host_addr(struct net_device *net, const char *host_addr)
++{
++      struct eth_dev *dev;
++      u8 new_addr[ETH_ALEN];
++
++      dev = netdev_priv(net);
++      if (get_ether_addr(host_addr, new_addr))
++              return -EINVAL;
++      memcpy(dev->host_mac, new_addr, ETH_ALEN);
++      return 0;
++}
++EXPORT_SYMBOL(gether_set_host_addr);
++
++int gether_get_host_addr(struct net_device *net, char *host_addr, int len)
++{
++      struct eth_dev *dev;
++
++      dev = netdev_priv(net);
++      return get_ether_addr_str(dev->host_mac, host_addr, len);
++}
++EXPORT_SYMBOL(gether_get_host_addr);
++
++int gether_get_host_addr_cdc(struct net_device *net, char *host_addr, int len)
++{
++      struct eth_dev *dev;
++
++      if (len < 13)
++              return -EINVAL;
++
++      dev = netdev_priv(net);
++      snprintf(host_addr, len, "%pm", dev->host_mac);
++
++      return strlen(host_addr);
++}
++EXPORT_SYMBOL(gether_get_host_addr_cdc);
++
++void gether_set_qmult(struct net_device *net, unsigned qmult)
++{
++      struct eth_dev *dev;
++
++      dev = netdev_priv(net);
++      dev->qmult = qmult;
++}
++EXPORT_SYMBOL(gether_set_qmult);
++
++unsigned gether_get_qmult(struct net_device *net)
++{
++      struct eth_dev *dev;
++
++      dev = netdev_priv(net);
++      return dev->qmult;
++}
++EXPORT_SYMBOL(gether_get_qmult);
++
++int gether_get_ifname(struct net_device *net, char *name, int len)
++{
++      rtnl_lock();
++      strlcpy(name, netdev_name(net), len);
++      rtnl_unlock();
++      return strlen(name);
++}
++EXPORT_SYMBOL(gether_get_ifname);
++
+ /**
+  * gether_cleanup - remove Ethernet-over-USB device
+  * Context: may sleep
+diff --git a/drivers/usb/gadget/u_ether.h b/drivers/usb/gadget/u_ether.h
+index 02f58ac..d74b8f7 100644
+--- a/drivers/usb/gadget/u_ether.h
++++ b/drivers/usb/gadget/u_ether.h
+@@ -115,6 +115,129 @@ static inline struct eth_dev *gether_setup(struct usb_gadget *g,
+       return gether_setup_name(g, dev_addr, host_addr, ethaddr, qmult, "usb");
+ }
++/*
++ * variant of gether_setup_default that allows customizing
++ * network device name
++ */
++struct net_device *gether_setup_name_default(const char *netname);
++
++/*
++ * gether_register_netdev - register the net device
++ * @net: net device to register
++ *
++ * Registers the net device associated with this ethernet-over-usb link
++ *
++ */
++int gether_register_netdev(struct net_device *net);
++
++/* gether_setup_default - initialize one ethernet-over-usb link
++ * Context: may sleep
++ *
++ * This sets up the single network link that may be exported by a
++ * gadget driver using this framework.  The link layer addresses
++ * are set to random values.
++ *
++ * Returns negative errno, or zero on success
++ */
++static inline struct net_device *gether_setup_default(void)
++{
++      return gether_setup_name_default("usb");
++}
++
++/**
++ * gether_set_gadget - initialize one ethernet-over-usb link with a gadget
++ * @net: device representing this link
++ * @g: the gadget to initialize with
++ *
++ * This associates one ethernet-over-usb link with a gadget.
++ */
++void gether_set_gadget(struct net_device *net, struct usb_gadget *g);
++
++/**
++ * gether_set_dev_addr - initialize an ethernet-over-usb link with eth address
++ * @net: device representing this link
++ * @dev_addr: eth address of this device
++ *
++ * This sets the device-side Ethernet address of this ethernet-over-usb link
++ * if dev_addr is correct.
++ * Returns negative errno if the new address is incorrect.
++ */
++int gether_set_dev_addr(struct net_device *net, const char *dev_addr);
++
++/**
++ * gether_get_dev_addr - get an ethernet-over-usb link eth address
++ * @net: device representing this link
++ * @dev_addr: place to store device's eth address
++ * @len: length of the @dev_addr buffer
++ *
++ * This gets the device-side Ethernet address of this ethernet-over-usb link.
++ * Returns zero on success, else negative errno.
++ */
++int gether_get_dev_addr(struct net_device *net, char *dev_addr, int len);
++
++/**
++ * gether_set_host_addr - initialize an ethernet-over-usb link with host address
++ * @net: device representing this link
++ * @host_addr: eth address of the host
++ *
++ * This sets the host-side Ethernet address of this ethernet-over-usb link
++ * if host_addr is correct.
++ * Returns negative errno if the new address is incorrect.
++ */
++int gether_set_host_addr(struct net_device *net, const char *host_addr);
++
++/**
++ * gether_get_host_addr - get an ethernet-over-usb link host address
++ * @net: device representing this link
++ * @host_addr: place to store eth address of the host
++ * @len: length of the @host_addr buffer
++ *
++ * This gets the host-side Ethernet address of this ethernet-over-usb link.
++ * Returns zero on success, else negative errno.
++ */
++int gether_get_host_addr(struct net_device *net, char *host_addr, int len);
++
++/**
++ * gether_get_host_addr_cdc - get an ethernet-over-usb link host address
++ * @net: device representing this link
++ * @host_addr: place to store eth address of the host
++ * @len: length of the @host_addr buffer
++ *
++ * This gets the CDC formatted host-side Ethernet address of this
++ * ethernet-over-usb link.
++ * Returns zero on success, else negative errno.
++ */
++int gether_get_host_addr_cdc(struct net_device *net, char *host_addr, int len);
++
++/**
++ * gether_set_qmult - initialize an ethernet-over-usb link with a multiplier
++ * @net: device representing this link
++ * @qmult: queue multiplier
++ *
++ * This sets the queue length multiplier of this ethernet-over-usb link.
++ * For higher speeds use longer queues.
++ */
++void gether_set_qmult(struct net_device *net, unsigned qmult);
++
++/**
++ * gether_get_qmult - get an ethernet-over-usb link multiplier
++ * @net: device representing this link
++ *
++ * This gets the queue length multiplier of this ethernet-over-usb link.
++ */
++unsigned gether_get_qmult(struct net_device *net);
++
++/**
++ * gether_get_ifname - get an ethernet-over-usb link interface name
++ * @net: device representing this link
++ * @name: place to store the interface name
++ * @len: length of the @name buffer
++ *
++ * This gets the interface name of this ethernet-over-usb link.
++ * Returns zero on success, else negative errno.
++ */
++int gether_get_ifname(struct net_device *net, char *name, int len);
++
+ void gether_cleanup(struct eth_dev *dev);
+ /* connect/disconnect is handled by individual functions */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0608-usb-gadget-f_ncm-convert-to-new-function-interface-w.patch b/patches.tizen/0608-usb-gadget-f_ncm-convert-to-new-function-interface-w.patch
new file mode 100644 (file)
index 0000000..3637ddf
--- /dev/null
@@ -0,0 +1,470 @@
+From 95de55b043d090fc80d030c4b5cc97601c337508 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 23 May 2013 09:22:06 +0200
+Subject: [PATCH 0608/1302] usb: gadget: f_ncm: convert to new function
+ interface with backward compatibility
+
+Converting ncm to the new function interface requires converting
+the USB ncm's function code and its users.
+
+This patch converts the f_ncm.c to the new function interface.
+
+The file is now compiled into a separate usb_f_ncm.ko module.
+
+The old function interface is provided by means of a preprocessor
+conditional directives. After all users are converted, the old interface
+can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig  |   3 +
+ drivers/usb/gadget/Makefile |   2 +
+ drivers/usb/gadget/f_ncm.c  | 196 ++++++++++++++++++++++++++++++++++++--------
+ drivers/usb/gadget/ncm.c    |   1 +
+ drivers/usb/gadget/u_ncm.h  |  27 ++++++
+ 5 files changed, 194 insertions(+), 35 deletions(-)
+ create mode 100644 drivers/usb/gadget/u_ncm.h
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 3cde222..707bc53 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -519,6 +519,9 @@ config USB_F_SERIAL
+ config USB_F_OBEX
+       tristate
++config USB_F_NCM
++      tristate
++
+ choice
+       tristate "USB Gadget Drivers"
+       default USB_ETH
+diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
+index 7a0463e..34b117e 100644
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -48,6 +48,8 @@ obj-$(CONFIG_USB_F_OBEX)     += usb_f_obex.o
+ obj-$(CONFIG_USB_U_ETHER)     += u_ether.o
+ u_rndis-y                     := rndis.o
+ obj-$(CONFIG_USB_U_RNDIS)     += u_rndis.o
++usb_f_ncm-y                   := f_ncm.o
++obj-$(CONFIG_USB_F_NCM)               += usb_f_ncm.o
+ #
+ # USB gadget drivers
+diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c
+index ee19bc8..722ca1b 100644
+--- a/drivers/usb/gadget/f_ncm.c
++++ b/drivers/usb/gadget/f_ncm.c
+@@ -16,6 +16,7 @@
+  */
+ #include <linux/kernel.h>
++#include <linux/module.h>
+ #include <linux/device.h>
+ #include <linux/etherdevice.h>
+ #include <linux/crc32.h>
+@@ -23,6 +24,7 @@
+ #include <linux/usb/cdc.h>
+ #include "u_ether.h"
++#include "u_ncm.h"
+ /*
+  * This function is a "CDC Network Control Model" (CDC NCM) Ethernet link.
+@@ -125,7 +127,7 @@ static struct usb_cdc_ncm_ntb_parameters ntb_parameters = {
+ #define NCM_STATUS_INTERVAL_MS                32
+ #define NCM_STATUS_BYTECOUNT          16      /* 8 byte header + data */
+-static struct usb_interface_assoc_descriptor ncm_iad_desc __initdata = {
++static struct usb_interface_assoc_descriptor ncm_iad_desc = {
+       .bLength =              sizeof ncm_iad_desc,
+       .bDescriptorType =      USB_DT_INTERFACE_ASSOCIATION,
+@@ -139,7 +141,7 @@ static struct usb_interface_assoc_descriptor ncm_iad_desc __initdata = {
+ /* interface descriptor: */
+-static struct usb_interface_descriptor ncm_control_intf __initdata = {
++static struct usb_interface_descriptor ncm_control_intf = {
+       .bLength =              sizeof ncm_control_intf,
+       .bDescriptorType =      USB_DT_INTERFACE,
+@@ -151,7 +153,7 @@ static struct usb_interface_descriptor ncm_control_intf __initdata = {
+       /* .iInterface = DYNAMIC */
+ };
+-static struct usb_cdc_header_desc ncm_header_desc __initdata = {
++static struct usb_cdc_header_desc ncm_header_desc = {
+       .bLength =              sizeof ncm_header_desc,
+       .bDescriptorType =      USB_DT_CS_INTERFACE,
+       .bDescriptorSubType =   USB_CDC_HEADER_TYPE,
+@@ -159,7 +161,7 @@ static struct usb_cdc_header_desc ncm_header_desc __initdata = {
+       .bcdCDC =               cpu_to_le16(0x0110),
+ };
+-static struct usb_cdc_union_desc ncm_union_desc __initdata = {
++static struct usb_cdc_union_desc ncm_union_desc = {
+       .bLength =              sizeof(ncm_union_desc),
+       .bDescriptorType =      USB_DT_CS_INTERFACE,
+       .bDescriptorSubType =   USB_CDC_UNION_TYPE,
+@@ -167,7 +169,7 @@ static struct usb_cdc_union_desc ncm_union_desc __initdata = {
+       /* .bSlaveInterface0 =  DYNAMIC */
+ };
+-static struct usb_cdc_ether_desc ecm_desc __initdata = {
++static struct usb_cdc_ether_desc ecm_desc = {
+       .bLength =              sizeof ecm_desc,
+       .bDescriptorType =      USB_DT_CS_INTERFACE,
+       .bDescriptorSubType =   USB_CDC_ETHERNET_TYPE,
+@@ -182,7 +184,7 @@ static struct usb_cdc_ether_desc ecm_desc __initdata = {
+ #define NCAPS (USB_CDC_NCM_NCAP_ETH_FILTER | USB_CDC_NCM_NCAP_CRC_MODE)
+-static struct usb_cdc_ncm_desc ncm_desc __initdata = {
++static struct usb_cdc_ncm_desc ncm_desc = {
+       .bLength =              sizeof ncm_desc,
+       .bDescriptorType =      USB_DT_CS_INTERFACE,
+       .bDescriptorSubType =   USB_CDC_NCM_TYPE,
+@@ -194,7 +196,7 @@ static struct usb_cdc_ncm_desc ncm_desc __initdata = {
+ /* the default data interface has no endpoints ... */
+-static struct usb_interface_descriptor ncm_data_nop_intf __initdata = {
++static struct usb_interface_descriptor ncm_data_nop_intf = {
+       .bLength =              sizeof ncm_data_nop_intf,
+       .bDescriptorType =      USB_DT_INTERFACE,
+@@ -209,7 +211,7 @@ static struct usb_interface_descriptor ncm_data_nop_intf __initdata = {
+ /* ... but the "real" data interface has two bulk endpoints */
+-static struct usb_interface_descriptor ncm_data_intf __initdata = {
++static struct usb_interface_descriptor ncm_data_intf = {
+       .bLength =              sizeof ncm_data_intf,
+       .bDescriptorType =      USB_DT_INTERFACE,
+@@ -224,7 +226,7 @@ static struct usb_interface_descriptor ncm_data_intf __initdata = {
+ /* full speed support: */
+-static struct usb_endpoint_descriptor fs_ncm_notify_desc __initdata = {
++static struct usb_endpoint_descriptor fs_ncm_notify_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -234,7 +236,7 @@ static struct usb_endpoint_descriptor fs_ncm_notify_desc __initdata = {
+       .bInterval =            NCM_STATUS_INTERVAL_MS,
+ };
+-static struct usb_endpoint_descriptor fs_ncm_in_desc __initdata = {
++static struct usb_endpoint_descriptor fs_ncm_in_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -242,7 +244,7 @@ static struct usb_endpoint_descriptor fs_ncm_in_desc __initdata = {
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+ };
+-static struct usb_endpoint_descriptor fs_ncm_out_desc __initdata = {
++static struct usb_endpoint_descriptor fs_ncm_out_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -250,7 +252,7 @@ static struct usb_endpoint_descriptor fs_ncm_out_desc __initdata = {
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+ };
+-static struct usb_descriptor_header *ncm_fs_function[] __initdata = {
++static struct usb_descriptor_header *ncm_fs_function[] = {
+       (struct usb_descriptor_header *) &ncm_iad_desc,
+       /* CDC NCM control descriptors */
+       (struct usb_descriptor_header *) &ncm_control_intf,
+@@ -269,7 +271,7 @@ static struct usb_descriptor_header *ncm_fs_function[] __initdata = {
+ /* high speed support: */
+-static struct usb_endpoint_descriptor hs_ncm_notify_desc __initdata = {
++static struct usb_endpoint_descriptor hs_ncm_notify_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -278,7 +280,7 @@ static struct usb_endpoint_descriptor hs_ncm_notify_desc __initdata = {
+       .wMaxPacketSize =       cpu_to_le16(NCM_STATUS_BYTECOUNT),
+       .bInterval =            USB_MS_TO_HS_INTERVAL(NCM_STATUS_INTERVAL_MS),
+ };
+-static struct usb_endpoint_descriptor hs_ncm_in_desc __initdata = {
++static struct usb_endpoint_descriptor hs_ncm_in_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -287,7 +289,7 @@ static struct usb_endpoint_descriptor hs_ncm_in_desc __initdata = {
+       .wMaxPacketSize =       cpu_to_le16(512),
+ };
+-static struct usb_endpoint_descriptor hs_ncm_out_desc __initdata = {
++static struct usb_endpoint_descriptor hs_ncm_out_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -296,7 +298,7 @@ static struct usb_endpoint_descriptor hs_ncm_out_desc __initdata = {
+       .wMaxPacketSize =       cpu_to_le16(512),
+ };
+-static struct usb_descriptor_header *ncm_hs_function[] __initdata = {
++static struct usb_descriptor_header *ncm_hs_function[] = {
+       (struct usb_descriptor_header *) &ncm_iad_desc,
+       /* CDC NCM control descriptors */
+       (struct usb_descriptor_header *) &ncm_control_intf,
+@@ -1152,14 +1154,50 @@ static void ncm_close(struct gether *geth)
+ /* ethernet function driver setup/binding */
+-static int __init
+-ncm_bind(struct usb_configuration *c, struct usb_function *f)
++static int ncm_bind(struct usb_configuration *c, struct usb_function *f)
+ {
+       struct usb_composite_dev *cdev = c->cdev;
+       struct f_ncm            *ncm = func_to_ncm(f);
+       int                     status;
+       struct usb_ep           *ep;
++#ifndef USB_FNCM_INCLUDED
++      struct f_ncm_opts       *ncm_opts;
++
++      if (!can_support_ecm(cdev->gadget))
++              return -EINVAL;
++
++      ncm_opts = container_of(f->fi, struct f_ncm_opts, func_inst);
++      /*
++       * in drivers/usb/gadget/configfs.c:configfs_composite_bind()
++       * configurations are bound in sequence with list_for_each_entry,
++       * in each configuration its functions are bound in sequence
++       * with list_for_each_entry, so we assume no race condition
++       * with regard to ncm_opts->bound access
++       */
++      if (!ncm_opts->bound) {
++              gether_set_gadget(ncm_opts->net, cdev->gadget);
++              status = gether_register_netdev(ncm_opts->net);
++              if (status)
++                      return status;
++              ncm_opts->bound = true;
++      }
++#endif
++      if (ncm_string_defs[0].id == 0) {
++              status = usb_string_ids_tab(c->cdev, ncm_string_defs);
++              if (status < 0)
++                      return status;
++              ncm_control_intf.iInterface =
++                      ncm_string_defs[STRING_CTRL_IDX].id;
++
++              status = ncm_string_defs[STRING_DATA_IDX].id;
++              ncm_data_nop_intf.iInterface = status;
++              ncm_data_intf.iInterface = status;
++
++              ecm_desc.iMACAddress = ncm_string_defs[STRING_MAC_IDX].id;
++              ncm_iad_desc.iFunction = ncm_string_defs[STRING_IAD_IDX].id;
++      }
++
+       /* allocate instance-specific interface IDs */
+       status = usb_interface_id(c, f);
+       if (status < 0)
+@@ -1259,8 +1297,10 @@ fail:
+       return status;
+ }
++#ifdef USB_FNCM_INCLUDED
++
+ static void
+-ncm_unbind(struct usb_configuration *c, struct usb_function *f)
++ncm_old_unbind(struct usb_configuration *c, struct usb_function *f)
+ {
+       struct f_ncm            *ncm = func_to_ncm(f);
+@@ -1296,21 +1336,6 @@ int __init ncm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+       if (!can_support_ecm(c->cdev->gadget) || !ethaddr)
+               return -EINVAL;
+-      if (ncm_string_defs[0].id == 0) {
+-              status = usb_string_ids_tab(c->cdev, ncm_string_defs);
+-              if (status < 0)
+-                      return status;
+-              ncm_control_intf.iInterface =
+-                      ncm_string_defs[STRING_CTRL_IDX].id;
+-
+-              status = ncm_string_defs[STRING_DATA_IDX].id;
+-              ncm_data_nop_intf.iInterface = status;
+-              ncm_data_intf.iInterface = status;
+-
+-              ecm_desc.iMACAddress = ncm_string_defs[STRING_MAC_IDX].id;
+-              ncm_iad_desc.iFunction = ncm_string_defs[STRING_IAD_IDX].id;
+-      }
+-
+       /* allocate and initialize one new instance */
+       ncm = kzalloc(sizeof *ncm, GFP_KERNEL);
+       if (!ncm)
+@@ -1329,7 +1354,7 @@ int __init ncm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+       ncm->port.func.strings = ncm_strings;
+       /* descriptors are per-instance copies */
+       ncm->port.func.bind = ncm_bind;
+-      ncm->port.func.unbind = ncm_unbind;
++      ncm->port.func.unbind = ncm_old_unbind;
+       ncm->port.func.set_alt = ncm_set_alt;
+       ncm->port.func.get_alt = ncm_get_alt;
+       ncm->port.func.setup = ncm_setup;
+@@ -1343,3 +1368,104 @@ int __init ncm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+               kfree(ncm);
+       return status;
+ }
++
++#else
++
++static void ncm_free_inst(struct usb_function_instance *f)
++{
++      struct f_ncm_opts *opts;
++
++      opts = container_of(f, struct f_ncm_opts, func_inst);
++      if (opts->bound)
++              gether_cleanup(netdev_priv(opts->net));
++      else
++              free_netdev(opts->net);
++      kfree(opts);
++}
++
++static struct usb_function_instance *ncm_alloc_inst(void)
++{
++      struct f_ncm_opts *opts;
++
++      opts = kzalloc(sizeof(*opts), GFP_KERNEL);
++      if (!opts)
++              return ERR_PTR(-ENOMEM);
++      opts->func_inst.free_func_inst = ncm_free_inst;
++      opts->net = gether_setup_default();
++      if (IS_ERR(opts->net))
++              return ERR_PTR(PTR_ERR(opts->net));
++
++      return &opts->func_inst;
++}
++
++static void ncm_free(struct usb_function *f)
++{
++      struct f_ncm *ncm;
++
++      ncm = func_to_ncm(f);
++      kfree(ncm);
++}
++
++static void ncm_unbind(struct usb_configuration *c, struct usb_function *f)
++{
++      struct f_ncm *ncm = func_to_ncm(f);
++
++      DBG(c->cdev, "ncm unbind\n");
++
++      ncm_string_defs[0].id = 0;
++      usb_free_all_descriptors(f);
++
++      kfree(ncm->notify_req->buf);
++      usb_ep_free_request(ncm->notify, ncm->notify_req);
++}
++
++struct usb_function *ncm_alloc(struct usb_function_instance *fi)
++{
++      struct f_ncm            *ncm;
++      struct f_ncm_opts       *opts;
++      int status;
++
++      /* allocate and initialize one new instance */
++      ncm = kzalloc(sizeof(*ncm), GFP_KERNEL);
++      if (!ncm)
++              return ERR_PTR(-ENOMEM);
++
++      opts = container_of(fi, struct f_ncm_opts, func_inst);
++
++      /* export host's Ethernet address in CDC format */
++      status = gether_get_host_addr_cdc(opts->net, ncm->ethaddr,
++                                    sizeof(ncm->ethaddr));
++      if (status < 12) { /* strlen("01234567890a") */
++              kfree(ncm);
++              return ERR_PTR(-EINVAL);
++      }
++      ncm_string_defs[STRING_MAC_IDX].s = ncm->ethaddr;
++
++      spin_lock_init(&ncm->lock);
++      ncm_reset_values(ncm);
++      ncm->port.ioport = netdev_priv(opts->net);
++      ncm->port.is_fixed = true;
++
++      ncm->port.func.name = "cdc_network";
++      ncm->port.func.strings = ncm_strings;
++      /* descriptors are per-instance copies */
++      ncm->port.func.bind = ncm_bind;
++      ncm->port.func.unbind = ncm_unbind;
++      ncm->port.func.set_alt = ncm_set_alt;
++      ncm->port.func.get_alt = ncm_get_alt;
++      ncm->port.func.setup = ncm_setup;
++      ncm->port.func.disable = ncm_disable;
++      ncm->port.func.free_func = ncm_free;
++
++      ncm->port.wrap = ncm_wrap_ntb;
++      ncm->port.unwrap = ncm_unwrap_ntb;
++
++      return &ncm->port.func;
++}
++
++DECLARE_USB_FUNCTION_INIT(ncm, ncm_alloc_inst, ncm_alloc);
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Yauheni Kaliuta");
++
++#endif
++
+diff --git a/drivers/usb/gadget/ncm.c b/drivers/usb/gadget/ncm.c
+index e411135..e2f97ee 100644
+--- a/drivers/usb/gadget/ncm.c
++++ b/drivers/usb/gadget/ncm.c
+@@ -36,6 +36,7 @@
+  * the runtime footprint, and giving us at least some parts of what
+  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+  */
++#define USB_FNCM_INCLUDED
+ #include "f_ncm.c"
+ /*-------------------------------------------------------------------------*/
+diff --git a/drivers/usb/gadget/u_ncm.h b/drivers/usb/gadget/u_ncm.h
+new file mode 100644
+index 0000000..1e22b5f
+--- /dev/null
++++ b/drivers/usb/gadget/u_ncm.h
+@@ -0,0 +1,27 @@
++/*
++ * u_ncm.h
++ *
++ * Utility definitions for the ncm function
++ *
++ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
++ *            http://www.samsung.com
++ *
++ * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.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 U_NCM_H
++#define U_NCM_H
++
++#include <linux/usb/composite.h>
++
++struct f_ncm_opts {
++      struct usb_function_instance    func_inst;
++      struct net_device               *net;
++      bool                            bound;
++};
++
++#endif /* U_NCM_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0609-usb-gadget-ncm-convert-to-new-function-interface.patch b/patches.tizen/0609-usb-gadget-ncm-convert-to-new-function-interface.patch
new file mode 100644 (file)
index 0000000..eb40f69
--- /dev/null
@@ -0,0 +1,144 @@
+From 18634b0fb126b312443e718d1e88120e6ea41020 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 23 May 2013 09:22:07 +0200
+Subject: [PATCH 0609/1302] usb: gadget: ncm: convert to new function interface
+
+Utilize our new configfs-based interface.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig |  1 +
+ drivers/usb/gadget/ncm.c   | 57 ++++++++++++++++++++++++++++------------------
+ 2 files changed, 36 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 707bc53..a79f09f 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -687,6 +687,7 @@ config USB_G_NCM
+       depends on NET
+       select USB_LIBCOMPOSITE
+       select USB_U_ETHER
++      select USB_F_NCM
+       select CRC32
+       help
+         This driver implements USB CDC NCM subclass standard. NCM is
+diff --git a/drivers/usb/gadget/ncm.c b/drivers/usb/gadget/ncm.c
+index e2f97ee..81956fe 100644
+--- a/drivers/usb/gadget/ncm.c
++++ b/drivers/usb/gadget/ncm.c
+@@ -24,23 +24,12 @@
+ #include <linux/usb/composite.h>
+ #include "u_ether.h"
++#include "u_ncm.h"
+ #define DRIVER_DESC           "NCM Gadget"
+ /*-------------------------------------------------------------------------*/
+-/*
+- * Kbuild is not very cooperative with respect to linking separately
+- * compiled library objects into one module.  So for now we won't use
+- * separate compilation ... ensuring init/exit sections work to shrink
+- * the runtime footprint, and giving us at least some parts of what
+- * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+- */
+-#define USB_FNCM_INCLUDED
+-#include "f_ncm.c"
+-
+-/*-------------------------------------------------------------------------*/
+-
+ /* DO NOT REUSE THESE IDs with a protocol-incompatible driver!!  Ever!!
+  * Instead:  allocate your own, using normal USB-IF procedures.
+  */
+@@ -113,13 +102,15 @@ static struct usb_gadget_strings *dev_strings[] = {
+       NULL,
+ };
+-struct eth_dev *the_dev;
+-static u8 host_mac[ETH_ALEN];
++static struct usb_function_instance *f_ncm_inst;
++static struct usb_function *f_ncm;
+ /*-------------------------------------------------------------------------*/
+ static int __init ncm_do_config(struct usb_configuration *c)
+ {
++      int status;
++
+       /* FIXME alloc iConfiguration string, set it in c->strings */
+       if (gadget_is_otg(c->cdev->gadget)) {
+@@ -127,7 +118,19 @@ static int __init ncm_do_config(struct usb_configuration *c)
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+-      return ncm_bind_config(c, host_mac, the_dev);
++      f_ncm = usb_get_function(f_ncm_inst);
++      if (IS_ERR(f_ncm)) {
++              status = PTR_ERR(f_ncm);
++              return status;
++      }
++
++      status = usb_add_function(c, f_ncm);
++      if (status < 0) {
++              usb_put_function(f_ncm);
++              return status;
++      }
++
++      return 0;
+ }
+ static struct usb_configuration ncm_config_driver = {
+@@ -143,13 +146,20 @@ static struct usb_configuration ncm_config_driver = {
+ static int __init gncm_bind(struct usb_composite_dev *cdev)
+ {
+       struct usb_gadget       *gadget = cdev->gadget;
++      struct f_ncm_opts       *ncm_opts;
+       int                     status;
+-      /* set up network link layer */
+-      the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, host_mac,
+-                             qmult);
+-      if (IS_ERR(the_dev))
+-              return PTR_ERR(the_dev);
++      f_ncm_inst = usb_get_function_instance("ncm");
++      if (IS_ERR(f_ncm_inst))
++              return PTR_ERR(f_ncm_inst);
++
++      ncm_opts = container_of(f_ncm_inst, struct f_ncm_opts, func_inst);
++
++      gether_set_qmult(ncm_opts->net, qmult);
++      if (!gether_set_host_addr(ncm_opts->net, host_addr))
++              pr_info("using host ethernet address: %s", host_addr);
++      if (!gether_set_dev_addr(ncm_opts->net, dev_addr))
++              pr_info("using self ethernet address: %s", dev_addr);
+       /* Allocate string descriptor numbers ... note that string
+        * contents can be overridden by the composite_dev glue.
+@@ -172,13 +182,16 @@ static int __init gncm_bind(struct usb_composite_dev *cdev)
+       return 0;
+ fail:
+-      gether_cleanup(the_dev);
++      usb_put_function_instance(f_ncm_inst);
+       return status;
+ }
+ static int __exit gncm_unbind(struct usb_composite_dev *cdev)
+ {
+-      gether_cleanup(the_dev);
++      if (!IS_ERR_OR_NULL(f_ncm))
++              usb_put_function(f_ncm);
++      if (!IS_ERR_OR_NULL(f_ncm_inst))
++              usb_put_function_instance(f_ncm_inst);
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0610-usb-gadget-f_ncm-remove-compatibility-layer.patch b/patches.tizen/0610-usb-gadget-f_ncm-remove-compatibility-layer.patch
new file mode 100644 (file)
index 0000000..dff45ee
--- /dev/null
@@ -0,0 +1,142 @@
+From cc241568dea52e8a588eaac8f5c62a326a198a54 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 23 May 2013 09:22:08 +0200
+Subject: [PATCH 0610/1302] usb: gadget: f_ncm: remove compatibility layer
+
+There are no old function interface users left, so the old interface
+can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_ncm.c   | 80 --------------------------------------------
+ drivers/usb/gadget/u_ether.h |  2 --
+ 2 files changed, 82 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c
+index 722ca1b..d8069de 100644
+--- a/drivers/usb/gadget/f_ncm.c
++++ b/drivers/usb/gadget/f_ncm.c
+@@ -1160,8 +1160,6 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f)
+       struct f_ncm            *ncm = func_to_ncm(f);
+       int                     status;
+       struct usb_ep           *ep;
+-
+-#ifndef USB_FNCM_INCLUDED
+       struct f_ncm_opts       *ncm_opts;
+       if (!can_support_ecm(cdev->gadget))
+@@ -1182,7 +1180,6 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f)
+                       return status;
+               ncm_opts->bound = true;
+       }
+-#endif
+       if (ncm_string_defs[0].id == 0) {
+               status = usb_string_ids_tab(c->cdev, ncm_string_defs);
+               if (status < 0)
+@@ -1297,80 +1294,6 @@ fail:
+       return status;
+ }
+-#ifdef USB_FNCM_INCLUDED
+-
+-static void
+-ncm_old_unbind(struct usb_configuration *c, struct usb_function *f)
+-{
+-      struct f_ncm            *ncm = func_to_ncm(f);
+-
+-      DBG(c->cdev, "ncm unbind\n");
+-
+-      ncm_string_defs[0].id = 0;
+-      usb_free_all_descriptors(f);
+-
+-      kfree(ncm->notify_req->buf);
+-      usb_ep_free_request(ncm->notify, ncm->notify_req);
+-
+-      kfree(ncm);
+-}
+-
+-/**
+- * ncm_bind_config - add CDC Network link to a configuration
+- * @c: the configuration to support the network link
+- * @ethaddr: a buffer in which the ethernet address of the host side
+- *    side of the link was recorded
+- * Context: single threaded during gadget setup
+- *
+- * Returns zero on success, else negative errno.
+- *
+- * Caller must have called @gether_setup().  Caller is also responsible
+- * for calling @gether_cleanup() before module unload.
+- */
+-int __init ncm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+-              struct eth_dev *dev)
+-{
+-      struct f_ncm    *ncm;
+-      int             status;
+-
+-      if (!can_support_ecm(c->cdev->gadget) || !ethaddr)
+-              return -EINVAL;
+-
+-      /* allocate and initialize one new instance */
+-      ncm = kzalloc(sizeof *ncm, GFP_KERNEL);
+-      if (!ncm)
+-              return -ENOMEM;
+-
+-      /* export host's Ethernet address in CDC format */
+-      snprintf(ncm->ethaddr, sizeof ncm->ethaddr, "%pm", ethaddr);
+-      ncm_string_defs[STRING_MAC_IDX].s = ncm->ethaddr;
+-
+-      spin_lock_init(&ncm->lock);
+-      ncm_reset_values(ncm);
+-      ncm->port.ioport = dev;
+-      ncm->port.is_fixed = true;
+-
+-      ncm->port.func.name = "cdc_network";
+-      ncm->port.func.strings = ncm_strings;
+-      /* descriptors are per-instance copies */
+-      ncm->port.func.bind = ncm_bind;
+-      ncm->port.func.unbind = ncm_old_unbind;
+-      ncm->port.func.set_alt = ncm_set_alt;
+-      ncm->port.func.get_alt = ncm_get_alt;
+-      ncm->port.func.setup = ncm_setup;
+-      ncm->port.func.disable = ncm_disable;
+-
+-      ncm->port.wrap = ncm_wrap_ntb;
+-      ncm->port.unwrap = ncm_unwrap_ntb;
+-
+-      status = usb_add_function(c, &ncm->port.func);
+-      if (status)
+-              kfree(ncm);
+-      return status;
+-}
+-
+-#else
+-
+ static void ncm_free_inst(struct usb_function_instance *f)
+ {
+       struct f_ncm_opts *opts;
+@@ -1466,6 +1389,3 @@ struct usb_function *ncm_alloc(struct usb_function_instance *fi)
+ DECLARE_USB_FUNCTION_INIT(ncm, ncm_alloc_inst, ncm_alloc);
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Yauheni Kaliuta");
+-
+-#endif
+-
+diff --git a/drivers/usb/gadget/u_ether.h b/drivers/usb/gadget/u_ether.h
+index d74b8f7..1671a79 100644
+--- a/drivers/usb/gadget/u_ether.h
++++ b/drivers/usb/gadget/u_ether.h
+@@ -262,8 +262,6 @@ int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+               struct eth_dev *dev);
+ int ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+               struct eth_dev *dev);
+-int ncm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+-              struct eth_dev *dev);
+ int eem_bind_config(struct usb_configuration *c, struct eth_dev *dev);
+ #ifdef USB_ETH_RNDIS
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0611-usb-gadget-f_ncm-use-usb_gstrings_attach.patch b/patches.tizen/0611-usb-gadget-f_ncm-use-usb_gstrings_attach.patch
new file mode 100644 (file)
index 0000000..0b1597a
--- /dev/null
@@ -0,0 +1,77 @@
+From 7e7bceee7685eb78b80562144651078dfff8ba7c Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 23 May 2013 09:22:09 +0200
+Subject: [PATCH 0611/1302] usb: gadget: f_ncm: use usb_gstrings_attach
+
+Trivial patch making use of the new usb_gstrings_attach
+interface.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_ncm.c | 26 ++++++++++----------------
+ 1 file changed, 10 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c
+index d8069de..effd2fa 100644
+--- a/drivers/usb/gadget/f_ncm.c
++++ b/drivers/usb/gadget/f_ncm.c
+@@ -1158,6 +1158,7 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f)
+ {
+       struct usb_composite_dev *cdev = c->cdev;
+       struct f_ncm            *ncm = func_to_ncm(f);
++      struct usb_string       *us;
+       int                     status;
+       struct usb_ep           *ep;
+       struct f_ncm_opts       *ncm_opts;
+@@ -1180,20 +1181,15 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f)
+                       return status;
+               ncm_opts->bound = true;
+       }
+-      if (ncm_string_defs[0].id == 0) {
+-              status = usb_string_ids_tab(c->cdev, ncm_string_defs);
+-              if (status < 0)
+-                      return status;
+-              ncm_control_intf.iInterface =
+-                      ncm_string_defs[STRING_CTRL_IDX].id;
+-
+-              status = ncm_string_defs[STRING_DATA_IDX].id;
+-              ncm_data_nop_intf.iInterface = status;
+-              ncm_data_intf.iInterface = status;
+-
+-              ecm_desc.iMACAddress = ncm_string_defs[STRING_MAC_IDX].id;
+-              ncm_iad_desc.iFunction = ncm_string_defs[STRING_IAD_IDX].id;
+-      }
++      us = usb_gstrings_attach(cdev, ncm_strings,
++                               ARRAY_SIZE(ncm_string_defs));
++      if (IS_ERR(us))
++              return PTR_ERR(us);
++      ncm_control_intf.iInterface = us[STRING_CTRL_IDX].id;
++      ncm_data_nop_intf.iInterface = us[STRING_DATA_IDX].id;
++      ncm_data_intf.iInterface = us[STRING_DATA_IDX].id;
++      ecm_desc.iMACAddress = us[STRING_MAC_IDX].id;
++      ncm_iad_desc.iFunction = us[STRING_IAD_IDX].id;
+       /* allocate instance-specific interface IDs */
+       status = usb_interface_id(c, f);
+@@ -1335,7 +1331,6 @@ static void ncm_unbind(struct usb_configuration *c, struct usb_function *f)
+       DBG(c->cdev, "ncm unbind\n");
+-      ncm_string_defs[0].id = 0;
+       usb_free_all_descriptors(f);
+       kfree(ncm->notify_req->buf);
+@@ -1370,7 +1365,6 @@ struct usb_function *ncm_alloc(struct usb_function_instance *fi)
+       ncm->port.is_fixed = true;
+       ncm->port.func.name = "cdc_network";
+-      ncm->port.func.strings = ncm_strings;
+       /* descriptors are per-instance copies */
+       ncm->port.func.bind = ncm_bind;
+       ncm->port.func.unbind = ncm_unbind;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0612-usb-gadget-f_ncm-add-configfs-support.patch b/patches.tizen/0612-usb-gadget-f_ncm-add-configfs-support.patch
new file mode 100644 (file)
index 0000000..ad40587
--- /dev/null
@@ -0,0 +1,262 @@
+From cbaff1c7128962ce6ef54bebd512b1b054f884d4 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 23 May 2013 09:22:10 +0200
+Subject: [PATCH 0612/1302] usb: gadget: f_ncm: add configfs support
+
+Add configfs support to the NCM function driver so
+that we can, eventually, get rid of kernel-based
+gadget drivers.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_ncm.c | 166 +++++++++++++++++++++++++++++++++++++++++++++
+ drivers/usb/gadget/u_ncm.h |   9 +++
+ 2 files changed, 175 insertions(+)
+
+diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c
+index effd2fa..697262e2 100644
+--- a/drivers/usb/gadget/f_ncm.c
++++ b/drivers/usb/gadget/f_ncm.c
+@@ -1175,8 +1175,10 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f)
+        * with regard to ncm_opts->bound access
+        */
+       if (!ncm_opts->bound) {
++              mutex_lock(&ncm_opts->lock);
+               gether_set_gadget(ncm_opts->net, cdev->gadget);
+               status = gether_register_netdev(ncm_opts->net);
++              mutex_unlock(&ncm_opts->lock);
+               if (status)
+                       return status;
+               ncm_opts->bound = true;
+@@ -1290,6 +1292,159 @@ fail:
+       return status;
+ }
++static inline struct f_ncm_opts *to_f_ncm_opts(struct config_item *item)
++{
++      return container_of(to_config_group(item), struct f_ncm_opts,
++                          func_inst.group);
++}
++
++CONFIGFS_ATTR_STRUCT(f_ncm_opts);
++CONFIGFS_ATTR_OPS(f_ncm_opts);
++
++static void ncm_attr_release(struct config_item *item)
++{
++      struct f_ncm_opts *opts = to_f_ncm_opts(item);
++
++      usb_put_function_instance(&opts->func_inst);
++}
++
++static struct configfs_item_operations ncm_item_ops = {
++      .release        = ncm_attr_release,
++      .show_attribute = f_ncm_opts_attr_show,
++      .store_attribute = f_ncm_opts_attr_store,
++};
++
++static ssize_t ncm_opts_dev_addr_show(struct f_ncm_opts *opts, char *page)
++{
++      int result;
++
++      mutex_lock(&opts->lock);
++      result = gether_get_dev_addr(opts->net, page, PAGE_SIZE);
++      mutex_unlock(&opts->lock);
++
++      return result;
++}
++
++static ssize_t ncm_opts_dev_addr_store(struct f_ncm_opts *opts,
++              const char *page, size_t len)
++{
++      int ret;
++
++      mutex_lock(&opts->lock);
++      if (opts->refcnt) {
++              mutex_unlock(&opts->lock);
++              return -EBUSY;
++      }
++
++      ret = gether_set_dev_addr(opts->net, page);
++      mutex_unlock(&opts->lock);
++      if (!ret)
++              ret = len;
++      return ret;
++}
++
++static struct f_ncm_opts_attribute f_ncm_opts_dev_addr =
++      __CONFIGFS_ATTR(dev_addr, S_IRUGO | S_IWUSR, ncm_opts_dev_addr_show,
++                      ncm_opts_dev_addr_store);
++
++static ssize_t ncm_opts_host_addr_show(struct f_ncm_opts *opts, char *page)
++{
++      int result;
++
++      mutex_lock(&opts->lock);
++      result = gether_get_host_addr(opts->net, page, PAGE_SIZE);
++      mutex_unlock(&opts->lock);
++
++      return result;
++}
++
++static ssize_t ncm_opts_host_addr_store(struct f_ncm_opts *opts,
++              const char *page, size_t len)
++{
++      int ret;
++
++      mutex_lock(&opts->lock);
++      if (opts->refcnt) {
++              mutex_unlock(&opts->lock);
++              return -EBUSY;
++      }
++
++      ret = gether_set_host_addr(opts->net, page);
++      mutex_unlock(&opts->lock);
++      if (!ret)
++              ret = len;
++      return ret;
++}
++
++static struct f_ncm_opts_attribute f_ncm_opts_host_addr =
++      __CONFIGFS_ATTR(host_addr, S_IRUGO | S_IWUSR, ncm_opts_host_addr_show,
++                      ncm_opts_host_addr_store);
++
++static ssize_t ncm_opts_qmult_show(struct f_ncm_opts *opts, char *page)
++{
++      unsigned qmult;
++
++      mutex_lock(&opts->lock);
++      qmult = gether_get_qmult(opts->net);
++      mutex_unlock(&opts->lock);
++      return sprintf(page, "%d", qmult);
++}
++
++static ssize_t ncm_opts_qmult_store(struct f_ncm_opts *opts,
++              const char *page, size_t len)
++{
++      u8 val;
++      int ret;
++
++      mutex_lock(&opts->lock);
++      if (opts->refcnt) {
++              ret = -EBUSY;
++              goto out;
++      }
++
++      ret = kstrtou8(page, 0, &val);
++      if (ret)
++              goto out;
++
++      gether_set_qmult(opts->net, val);
++      ret = len;
++out:
++      mutex_unlock(&opts->lock);
++      return ret;
++}
++
++static struct f_ncm_opts_attribute f_ncm_opts_qmult =
++      __CONFIGFS_ATTR(qmult, S_IRUGO | S_IWUSR, ncm_opts_qmult_show,
++                      ncm_opts_qmult_store);
++
++static ssize_t ncm_opts_ifname_show(struct f_ncm_opts *opts, char *page)
++{
++      int ret;
++
++      mutex_lock(&opts->lock);
++      ret = gether_get_ifname(opts->net, page, PAGE_SIZE);
++      mutex_unlock(&opts->lock);
++
++      return ret;
++}
++
++static struct f_ncm_opts_attribute f_ncm_opts_ifname =
++      __CONFIGFS_ATTR_RO(ifname, ncm_opts_ifname_show);
++
++static struct configfs_attribute *ncm_attrs[] = {
++      &f_ncm_opts_dev_addr.attr,
++      &f_ncm_opts_host_addr.attr,
++      &f_ncm_opts_qmult.attr,
++      &f_ncm_opts_ifname.attr,
++      NULL,
++};
++
++static struct config_item_type ncm_func_type = {
++      .ct_item_ops    = &ncm_item_ops,
++      .ct_attrs       = ncm_attrs,
++      .ct_owner       = THIS_MODULE,
++};
++
+ static void ncm_free_inst(struct usb_function_instance *f)
+ {
+       struct f_ncm_opts *opts;
+@@ -1309,20 +1464,28 @@ static struct usb_function_instance *ncm_alloc_inst(void)
+       opts = kzalloc(sizeof(*opts), GFP_KERNEL);
+       if (!opts)
+               return ERR_PTR(-ENOMEM);
++      mutex_init(&opts->lock);
+       opts->func_inst.free_func_inst = ncm_free_inst;
+       opts->net = gether_setup_default();
+       if (IS_ERR(opts->net))
+               return ERR_PTR(PTR_ERR(opts->net));
++      config_group_init_type_name(&opts->func_inst.group, "", &ncm_func_type);
++
+       return &opts->func_inst;
+ }
+ static void ncm_free(struct usb_function *f)
+ {
+       struct f_ncm *ncm;
++      struct f_ncm_opts *opts;
+       ncm = func_to_ncm(f);
++      opts = container_of(f->fi, struct f_ncm_opts, func_inst);
+       kfree(ncm);
++      mutex_lock(&opts->lock);
++      opts->refcnt--;
++      mutex_unlock(&opts->lock);
+ }
+ static void ncm_unbind(struct usb_configuration *c, struct usb_function *f)
+@@ -1349,6 +1512,8 @@ struct usb_function *ncm_alloc(struct usb_function_instance *fi)
+               return ERR_PTR(-ENOMEM);
+       opts = container_of(fi, struct f_ncm_opts, func_inst);
++      mutex_lock(&opts->lock);
++      opts->refcnt++;
+       /* export host's Ethernet address in CDC format */
+       status = gether_get_host_addr_cdc(opts->net, ncm->ethaddr,
+@@ -1362,6 +1527,7 @@ struct usb_function *ncm_alloc(struct usb_function_instance *fi)
+       spin_lock_init(&ncm->lock);
+       ncm_reset_values(ncm);
+       ncm->port.ioport = netdev_priv(opts->net);
++      mutex_unlock(&opts->lock);
+       ncm->port.is_fixed = true;
+       ncm->port.func.name = "cdc_network";
+diff --git a/drivers/usb/gadget/u_ncm.h b/drivers/usb/gadget/u_ncm.h
+index 1e22b5f..ce0f3a7 100644
+--- a/drivers/usb/gadget/u_ncm.h
++++ b/drivers/usb/gadget/u_ncm.h
+@@ -22,6 +22,15 @@ struct f_ncm_opts {
+       struct usb_function_instance    func_inst;
+       struct net_device               *net;
+       bool                            bound;
++
++      /*
++       * Read/write access to configfs attributes is handled by configfs.
++       *
++       * This is to protect the data from concurrent access by read/write
++       * and create symlink/remove symlink.
++       */
++      struct mutex                    lock;
++      int                             refcnt;
+ };
+ #endif /* U_NCM_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0613-usb-gadget-add-helpers-for-configfs-support-for-USB-.patch b/patches.tizen/0613-usb-gadget-add-helpers-for-configfs-support-for-USB-.patch
new file mode 100644 (file)
index 0000000..1f99731
--- /dev/null
@@ -0,0 +1,355 @@
+From fa1fe8cdd562feddac1a682fbf7121a44859b1f9 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 23 May 2013 10:32:02 +0200
+Subject: [PATCH 0613/1302] usb: gadget: add helpers for configfs support for
+ USB Ethernet
+
+All USB Ethernet functions will have very similar attributes in configfs.
+
+This patch provides helper definitions to ease writing the functions and
+reduce source code duplication.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_ncm.c            | 139 +++-------------------------
+ drivers/usb/gadget/u_ether_configfs.h | 164 ++++++++++++++++++++++++++++++++++
+ 2 files changed, 175 insertions(+), 128 deletions(-)
+ create mode 100644 drivers/usb/gadget/u_ether_configfs.h
+
+diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c
+index 697262e2..47a5724 100644
+--- a/drivers/usb/gadget/f_ncm.c
++++ b/drivers/usb/gadget/f_ncm.c
+@@ -24,6 +24,7 @@
+ #include <linux/usb/cdc.h>
+ #include "u_ether.h"
++#include "u_ether_configfs.h"
+ #include "u_ncm.h"
+ /*
+@@ -1298,138 +1299,20 @@ static inline struct f_ncm_opts *to_f_ncm_opts(struct config_item *item)
+                           func_inst.group);
+ }
+-CONFIGFS_ATTR_STRUCT(f_ncm_opts);
+-CONFIGFS_ATTR_OPS(f_ncm_opts);
++/* f_ncm_item_ops */
++USB_ETHERNET_CONFIGFS_ITEM(ncm);
+-static void ncm_attr_release(struct config_item *item)
+-{
+-      struct f_ncm_opts *opts = to_f_ncm_opts(item);
+-
+-      usb_put_function_instance(&opts->func_inst);
+-}
+-
+-static struct configfs_item_operations ncm_item_ops = {
+-      .release        = ncm_attr_release,
+-      .show_attribute = f_ncm_opts_attr_show,
+-      .store_attribute = f_ncm_opts_attr_store,
+-};
+-
+-static ssize_t ncm_opts_dev_addr_show(struct f_ncm_opts *opts, char *page)
+-{
+-      int result;
+-
+-      mutex_lock(&opts->lock);
+-      result = gether_get_dev_addr(opts->net, page, PAGE_SIZE);
+-      mutex_unlock(&opts->lock);
+-
+-      return result;
+-}
+-
+-static ssize_t ncm_opts_dev_addr_store(struct f_ncm_opts *opts,
+-              const char *page, size_t len)
+-{
+-      int ret;
+-
+-      mutex_lock(&opts->lock);
+-      if (opts->refcnt) {
+-              mutex_unlock(&opts->lock);
+-              return -EBUSY;
+-      }
+-
+-      ret = gether_set_dev_addr(opts->net, page);
+-      mutex_unlock(&opts->lock);
+-      if (!ret)
+-              ret = len;
+-      return ret;
+-}
+-
+-static struct f_ncm_opts_attribute f_ncm_opts_dev_addr =
+-      __CONFIGFS_ATTR(dev_addr, S_IRUGO | S_IWUSR, ncm_opts_dev_addr_show,
+-                      ncm_opts_dev_addr_store);
+-
+-static ssize_t ncm_opts_host_addr_show(struct f_ncm_opts *opts, char *page)
+-{
+-      int result;
+-
+-      mutex_lock(&opts->lock);
+-      result = gether_get_host_addr(opts->net, page, PAGE_SIZE);
+-      mutex_unlock(&opts->lock);
+-
+-      return result;
+-}
+-
+-static ssize_t ncm_opts_host_addr_store(struct f_ncm_opts *opts,
+-              const char *page, size_t len)
+-{
+-      int ret;
++/* f_ncm_opts_dev_addr */
++USB_ETHERNET_CONFIGFS_ITEM_ATTR_DEV_ADDR(ncm);
+-      mutex_lock(&opts->lock);
+-      if (opts->refcnt) {
+-              mutex_unlock(&opts->lock);
+-              return -EBUSY;
+-      }
+-
+-      ret = gether_set_host_addr(opts->net, page);
+-      mutex_unlock(&opts->lock);
+-      if (!ret)
+-              ret = len;
+-      return ret;
+-}
+-
+-static struct f_ncm_opts_attribute f_ncm_opts_host_addr =
+-      __CONFIGFS_ATTR(host_addr, S_IRUGO | S_IWUSR, ncm_opts_host_addr_show,
+-                      ncm_opts_host_addr_store);
+-
+-static ssize_t ncm_opts_qmult_show(struct f_ncm_opts *opts, char *page)
+-{
+-      unsigned qmult;
+-
+-      mutex_lock(&opts->lock);
+-      qmult = gether_get_qmult(opts->net);
+-      mutex_unlock(&opts->lock);
+-      return sprintf(page, "%d", qmult);
+-}
+-
+-static ssize_t ncm_opts_qmult_store(struct f_ncm_opts *opts,
+-              const char *page, size_t len)
+-{
+-      u8 val;
+-      int ret;
++/* f_ncm_opts_host_addr */
++USB_ETHERNET_CONFIGFS_ITEM_ATTR_HOST_ADDR(ncm);
+-      mutex_lock(&opts->lock);
+-      if (opts->refcnt) {
+-              ret = -EBUSY;
+-              goto out;
+-      }
+-
+-      ret = kstrtou8(page, 0, &val);
+-      if (ret)
+-              goto out;
+-
+-      gether_set_qmult(opts->net, val);
+-      ret = len;
+-out:
+-      mutex_unlock(&opts->lock);
+-      return ret;
+-}
+-
+-static struct f_ncm_opts_attribute f_ncm_opts_qmult =
+-      __CONFIGFS_ATTR(qmult, S_IRUGO | S_IWUSR, ncm_opts_qmult_show,
+-                      ncm_opts_qmult_store);
+-
+-static ssize_t ncm_opts_ifname_show(struct f_ncm_opts *opts, char *page)
+-{
+-      int ret;
+-
+-      mutex_lock(&opts->lock);
+-      ret = gether_get_ifname(opts->net, page, PAGE_SIZE);
+-      mutex_unlock(&opts->lock);
+-
+-      return ret;
+-}
++/* f_ncm_opts_qmult */
++USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(ncm);
+-static struct f_ncm_opts_attribute f_ncm_opts_ifname =
+-      __CONFIGFS_ATTR_RO(ifname, ncm_opts_ifname_show);
++/* f_ncm_opts_ifname */
++USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(ncm);
+ static struct configfs_attribute *ncm_attrs[] = {
+       &f_ncm_opts_dev_addr.attr,
+diff --git a/drivers/usb/gadget/u_ether_configfs.h b/drivers/usb/gadget/u_ether_configfs.h
+new file mode 100644
+index 0000000..bcbd301
+--- /dev/null
++++ b/drivers/usb/gadget/u_ether_configfs.h
+@@ -0,0 +1,164 @@
++/*
++ * u_ether_configfs.h
++ *
++ * Utility definitions for configfs support in USB Ethernet functions
++ *
++ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
++ *            http://www.samsung.com
++ *
++ * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.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 __U_ETHER_CONFIGFS_H
++#define __U_ETHER_CONFIGFS_H
++
++#define USB_ETHERNET_CONFIGFS_ITEM(_f_)                                       \
++      CONFIGFS_ATTR_STRUCT(f_##_f_##_opts);                           \
++      CONFIGFS_ATTR_OPS(f_##_f_##_opts);                              \
++                                                                      \
++      static void _f_##_attr_release(struct config_item *item)        \
++      {                                                               \
++              struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
++                                                                      \
++              usb_put_function_instance(&opts->func_inst);            \
++      }                                                               \
++                                                                      \
++      static struct configfs_item_operations _f_##_item_ops = {       \
++              .release        = _f_##_attr_release,                   \
++              .show_attribute = f_##_f_##_opts_attr_show,             \
++              .store_attribute = f_##_f_##_opts_attr_store,           \
++      }
++
++#define USB_ETHERNET_CONFIGFS_ITEM_ATTR_DEV_ADDR(_f_)                 \
++      static ssize_t _f_##_opts_dev_addr_show(struct f_##_f_##_opts *opts, \
++                                              char *page)             \
++      {                                                               \
++              int result;                                             \
++                                                                      \
++              mutex_lock(&opts->lock);                                \
++              result = gether_get_dev_addr(opts->net, page, PAGE_SIZE); \
++              mutex_unlock(&opts->lock);                              \
++                                                                      \
++              return result;                                          \
++      }                                                               \
++                                                                      \
++      static ssize_t _f_##_opts_dev_addr_store(struct f_##_f_##_opts *opts, \
++                                               const char *page, size_t len)\
++      {                                                               \
++              int ret;                                                \
++                                                                      \
++              mutex_lock(&opts->lock);                                \
++              if (opts->refcnt) {                                     \
++                      mutex_unlock(&opts->lock);                      \
++                      return -EBUSY;                                  \
++              }                                                       \
++                                                                      \
++              ret = gether_set_dev_addr(opts->net, page);             \
++              mutex_unlock(&opts->lock);                              \
++              if (!ret)                                               \
++                      ret = len;                                      \
++              return ret;                                             \
++      }                                                               \
++                                                                      \
++      static struct f_##_f_##_opts_attribute f_##_f_##_opts_dev_addr = \
++              __CONFIGFS_ATTR(dev_addr, S_IRUGO | S_IWUSR,            \
++                              _f_##_opts_dev_addr_show,               \
++                              _f_##_opts_dev_addr_store)
++
++#define USB_ETHERNET_CONFIGFS_ITEM_ATTR_HOST_ADDR(_f_)                        \
++      static ssize_t _f_##_opts_host_addr_show(struct f_##_f_##_opts *opts, \
++                                               char *page)            \
++      {                                                               \
++              int result;                                             \
++                                                                      \
++              mutex_lock(&opts->lock);                                \
++              result = gether_get_host_addr(opts->net, page, PAGE_SIZE); \
++              mutex_unlock(&opts->lock);                              \
++                                                                      \
++              return result;                                          \
++      }                                                               \
++                                                                      \
++      static ssize_t _f_##_opts_host_addr_store(struct f_##_f_##_opts *opts, \
++                                                const char *page, size_t len)\
++      {                                                               \
++              int ret;                                                \
++                                                                      \
++              mutex_lock(&opts->lock);                                \
++              if (opts->refcnt) {                                     \
++                      mutex_unlock(&opts->lock);                      \
++                      return -EBUSY;                                  \
++              }                                                       \
++                                                                      \
++              ret = gether_set_host_addr(opts->net, page);            \
++              mutex_unlock(&opts->lock);                              \
++              if (!ret)                                               \
++                      ret = len;                                      \
++              return ret;                                             \
++      }                                                               \
++                                                                      \
++      static struct f_##_f_##_opts_attribute f_##_f_##_opts_host_addr = \
++              __CONFIGFS_ATTR(host_addr, S_IRUGO | S_IWUSR,           \
++                              _f_##_opts_host_addr_show,              \
++                              _f_##_opts_host_addr_store)
++
++#define USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(_f_)                    \
++      static ssize_t _f_##_opts_qmult_show(struct f_##_f_##_opts *opts, \
++                                           char *page)                \
++      {                                                               \
++              unsigned qmult;                                         \
++                                                                      \
++              mutex_lock(&opts->lock);                                \
++              qmult = gether_get_qmult(opts->net);                    \
++              mutex_unlock(&opts->lock);                              \
++              return sprintf(page, "%d", qmult);                      \
++      }                                                               \
++                                                                      \
++      static ssize_t _f_##_opts_qmult_store(struct f_##_f_##_opts *opts, \
++                                            const char *page, size_t len)\
++      {                                                               \
++              u8 val;                                                 \
++              int ret;                                                \
++                                                                      \
++              mutex_lock(&opts->lock);                                \
++              if (opts->refcnt) {                                     \
++                      ret = -EBUSY;                                   \
++                      goto out;                                       \
++              }                                                       \
++                                                                      \
++              ret = kstrtou8(page, 0, &val);                          \
++              if (ret)                                                \
++                      goto out;                                       \
++                                                                      \
++              gether_set_qmult(opts->net, val);                       \
++              ret = len;                                              \
++out:                                                                  \
++              mutex_unlock(&opts->lock);                              \
++              return ret;                                             \
++      }                                                               \
++                                                                      \
++      static struct f_##_f_##_opts_attribute f_##_f_##_opts_qmult =   \
++              __CONFIGFS_ATTR(qmult, S_IRUGO | S_IWUSR,               \
++                              _f_##_opts_qmult_show,          \
++                              _f_##_opts_qmult_store)
++
++#define USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(_f_)                   \
++      static ssize_t _f_##_opts_ifname_show(struct f_##_f_##_opts *opts, \
++                                            char *page)               \
++      {                                                               \
++              int ret;                                                \
++                                                                      \
++              mutex_lock(&opts->lock);                                \
++              ret = gether_get_ifname(opts->net, page, PAGE_SIZE);    \
++              mutex_unlock(&opts->lock);                              \
++                                                                      \
++              return ret;                                             \
++      }                                                               \
++                                                                      \
++      static struct f_##_f_##_opts_attribute f_##_f_##_opts_ifname =  \
++              __CONFIGFS_ATTR_RO(ifname, _f_##_opts_ifname_show)
++
++#endif /* __U_ETHER_CONFIGFS_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0614-usb-gadget-f_ecm-convert-to-new-function-interface-w.patch b/patches.tizen/0614-usb-gadget-f_ecm-convert-to-new-function-interface-w.patch
new file mode 100644 (file)
index 0000000..df965b9
--- /dev/null
@@ -0,0 +1,357 @@
+From cd4870c58f5c0f1a8711f7969c2e86e1a24501c2 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 23 May 2013 10:32:03 +0200
+Subject: [PATCH 0614/1302] usb: gadget: f_ecm: convert to new function
+ interface with backward compatibility
+
+Converting ecm to the new function interface requires converting
+the USB ecm's function code and its users.
+
+This patch converts the f_ecm.c to the new function interface.
+
+The file is now compiled into a separate usb_f_ecm.ko module.
+
+The old function interface is provided by means of a preprocessor
+conditional directives. After all users are converted, the old interface
+can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig  |   3 +
+ drivers/usb/gadget/Makefile |   2 +
+ drivers/usb/gadget/cdc2.c   |   1 +
+ drivers/usb/gadget/ether.c  |   1 +
+ drivers/usb/gadget/f_ecm.c  | 149 ++++++++++++++++++++++++++++++++++++++++----
+ drivers/usb/gadget/g_ffs.c  |   1 +
+ drivers/usb/gadget/multi.c  |   1 +
+ drivers/usb/gadget/nokia.c  |   3 +-
+ drivers/usb/gadget/u_ecm.h  |  27 ++++++++
+ 9 files changed, 174 insertions(+), 14 deletions(-)
+ create mode 100644 drivers/usb/gadget/u_ecm.h
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index a79f09f..a2dbdcb 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -522,6 +522,9 @@ config USB_F_OBEX
+ config USB_F_NCM
+       tristate
++config USB_F_ECM
++      tristate
++
+ choice
+       tristate "USB Gadget Drivers"
+       default USB_ETH
+diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
+index 34b117e..66152f5 100644
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -50,6 +50,8 @@ u_rndis-y                    := rndis.o
+ obj-$(CONFIG_USB_U_RNDIS)     += u_rndis.o
+ usb_f_ncm-y                   := f_ncm.o
+ obj-$(CONFIG_USB_F_NCM)               += usb_f_ncm.o
++usb_f_ecm-y                   := f_ecm.o
++obj-$(CONFIG_USB_F_ECM)               += usb_f_ecm.o
+ #
+ # USB gadget drivers
+diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c
+index bffa997..ceedaf7 100644
+--- a/drivers/usb/gadget/cdc2.c
++++ b/drivers/usb/gadget/cdc2.c
+@@ -44,6 +44,7 @@ USB_ETHERNET_MODULE_PARAMETERS();
+  * the runtime footprint, and giving us at least some parts of what
+  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+  */
++#define USBF_ECM_INCLUDED
+ #include "f_ecm.c"
+ /*-------------------------------------------------------------------------*/
+diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
+index 6bff24f..862ef65 100644
+--- a/drivers/usb/gadget/ether.c
++++ b/drivers/usb/gadget/ether.c
+@@ -102,6 +102,7 @@ static inline bool has_rndis(void)
+  * the runtime footprint, and giving us at least some parts of what
+  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+  */
++#define USBF_ECM_INCLUDED
+ #include "f_ecm.c"
+ #include "f_subset.c"
+ #ifdef        USB_ETH_RNDIS
+diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c
+index abf8a31..1b5aeb2 100644
+--- a/drivers/usb/gadget/f_ecm.c
++++ b/drivers/usb/gadget/f_ecm.c
+@@ -14,10 +14,12 @@
+ #include <linux/slab.h>
+ #include <linux/kernel.h>
++#include <linux/module.h>
+ #include <linux/device.h>
+ #include <linux/etherdevice.h>
+ #include "u_ether.h"
++#include "u_ecm.h"
+ /*
+@@ -687,6 +689,40 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
+       int                     status;
+       struct usb_ep           *ep;
++#ifndef USBF_ECM_INCLUDED
++      struct f_ecm_opts       *ecm_opts;
++
++      if (!can_support_ecm(cdev->gadget))
++              return -EINVAL;
++
++      ecm_opts = container_of(f->fi, struct f_ecm_opts, func_inst);
++
++      /*
++       * in drivers/usb/gadget/configfs.c:configfs_composite_bind()
++       * configurations are bound in sequence with list_for_each_entry,
++       * in each configuration its functions are bound in sequence
++       * with list_for_each_entry, so we assume no race condition
++       * with regard to ecm_opts->bound access
++       */
++      if (!ecm_opts->bound) {
++              gether_set_gadget(ecm_opts->net, cdev->gadget);
++              status = gether_register_netdev(ecm_opts->net);
++              if (status)
++                      return status;
++              ecm_opts->bound = true;
++      }
++#endif
++      if (ecm_string_defs[0].id == 0) {
++              status = usb_string_ids_tab(c->cdev, ecm_string_defs);
++              if (status)
++                      return status;
++
++              ecm_control_intf.iInterface = ecm_string_defs[0].id;
++              ecm_data_intf.iInterface = ecm_string_defs[2].id;
++              ecm_desc.iMACAddress = ecm_string_defs[1].id;
++              ecm_iad_descriptor.iFunction = ecm_string_defs[3].id;
++      }
++
+       /* allocate instance-specific interface IDs */
+       status = usb_interface_id(c, f);
+       if (status < 0)
+@@ -796,8 +832,10 @@ fail:
+       return status;
+ }
++#ifdef USBF_ECM_INCLUDED
++
+ static void
+-ecm_unbind(struct usb_configuration *c, struct usb_function *f)
++ecm_old_unbind(struct usb_configuration *c, struct usb_function *f)
+ {
+       struct f_ecm            *ecm = func_to_ecm(f);
+@@ -834,17 +872,6 @@ ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+       if (!can_support_ecm(c->cdev->gadget) || !ethaddr)
+               return -EINVAL;
+-      if (ecm_string_defs[0].id == 0) {
+-              status = usb_string_ids_tab(c->cdev, ecm_string_defs);
+-              if (status)
+-                      return status;
+-
+-              ecm_control_intf.iInterface = ecm_string_defs[0].id;
+-              ecm_data_intf.iInterface = ecm_string_defs[2].id;
+-              ecm_desc.iMACAddress = ecm_string_defs[1].id;
+-              ecm_iad_descriptor.iFunction = ecm_string_defs[3].id;
+-      }
+-
+       /* allocate and initialize one new instance */
+       ecm = kzalloc(sizeof *ecm, GFP_KERNEL);
+       if (!ecm)
+@@ -861,7 +888,7 @@ ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+       ecm->port.func.strings = ecm_strings;
+       /* descriptors are per-instance copies */
+       ecm->port.func.bind = ecm_bind;
+-      ecm->port.func.unbind = ecm_unbind;
++      ecm->port.func.unbind = ecm_old_unbind;
+       ecm->port.func.set_alt = ecm_set_alt;
+       ecm->port.func.get_alt = ecm_get_alt;
+       ecm->port.func.setup = ecm_setup;
+@@ -872,3 +899,99 @@ ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+               kfree(ecm);
+       return status;
+ }
++
++#else
++
++static void ecm_free_inst(struct usb_function_instance *f)
++{
++      struct f_ecm_opts *opts;
++
++      opts = container_of(f, struct f_ecm_opts, func_inst);
++      if (opts->bound)
++              gether_cleanup(netdev_priv(opts->net));
++      else
++              free_netdev(opts->net);
++      kfree(opts);
++}
++
++static struct usb_function_instance *ecm_alloc_inst(void)
++{
++      struct f_ecm_opts *opts;
++
++      opts = kzalloc(sizeof(*opts), GFP_KERNEL);
++      if (!opts)
++              return ERR_PTR(-ENOMEM);
++
++      opts->func_inst.free_func_inst = ecm_free_inst;
++      opts->net = gether_setup_default();
++      if (IS_ERR(opts->net))
++              return ERR_PTR(PTR_ERR(opts->net));
++
++      return &opts->func_inst;
++}
++
++static void ecm_free(struct usb_function *f)
++{
++      struct f_ecm *ecm;
++
++      ecm = func_to_ecm(f);
++      kfree(ecm);
++}
++
++static void ecm_unbind(struct usb_configuration *c, struct usb_function *f)
++{
++      struct f_ecm            *ecm = func_to_ecm(f);
++
++      DBG(c->cdev, "ecm unbind\n");
++
++      ecm_string_defs[0].id = 0;
++      usb_free_all_descriptors(f);
++
++      kfree(ecm->notify_req->buf);
++      usb_ep_free_request(ecm->notify, ecm->notify_req);
++}
++
++struct usb_function *ecm_alloc(struct usb_function_instance *fi)
++{
++      struct f_ecm    *ecm;
++      struct f_ecm_opts *opts;
++      int status;
++
++      /* allocate and initialize one new instance */
++      ecm = kzalloc(sizeof(*ecm), GFP_KERNEL);
++      if (!ecm)
++              return ERR_PTR(-ENOMEM);
++
++      opts = container_of(fi, struct f_ecm_opts, func_inst);
++
++      /* export host's Ethernet address in CDC format */
++      status = gether_get_host_addr_cdc(opts->net, ecm->ethaddr,
++                                        sizeof(ecm->ethaddr));
++      if (status < 12) {
++              kfree(ecm);
++              return ERR_PTR(-EINVAL);
++      }
++      ecm_string_defs[1].s = ecm->ethaddr;
++
++      ecm->port.ioport = netdev_priv(opts->net);
++      ecm->port.cdc_filter = DEFAULT_FILTER;
++
++      ecm->port.func.name = "cdc_ethernet";
++      ecm->port.func.strings = ecm_strings;
++      /* descriptors are per-instance copies */
++      ecm->port.func.bind = ecm_bind;
++      ecm->port.func.unbind = ecm_unbind;
++      ecm->port.func.set_alt = ecm_set_alt;
++      ecm->port.func.get_alt = ecm_get_alt;
++      ecm->port.func.setup = ecm_setup;
++      ecm->port.func.disable = ecm_disable;
++      ecm->port.func.free_func = ecm_free;
++
++      return &ecm->port.func;
++}
++
++DECLARE_USB_FUNCTION_INIT(ecm, ecm_alloc_inst, ecm_alloc);
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("David Brownell");
++
++#endif
+diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
+index fbfdb53..d38a073 100644
+--- a/drivers/usb/gadget/g_ffs.c
++++ b/drivers/usb/gadget/g_ffs.c
+@@ -28,6 +28,7 @@
+ #    define USB_ETH_RNDIS y
+ #  endif
++#define USBF_ECM_INCLUDED
+ #  include "f_ecm.c"
+ #  include "f_subset.c"
+ #  ifdef USB_ETH_RNDIS
+diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
+index ce21e9f..6164393 100644
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -43,6 +43,7 @@ MODULE_LICENSE("GPL");
+  */
+ #include "f_mass_storage.c"
++#define USBF_ECM_INCLUDED
+ #include "f_ecm.c"
+ #include "f_subset.c"
+ #ifdef USB_ETH_RNDIS
+diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c
+index 39f6cb5..8e42c88 100644
+--- a/drivers/usb/gadget/nokia.c
++++ b/drivers/usb/gadget/nokia.c
+@@ -37,8 +37,9 @@
+  * the runtime footprint, and giving us at least some parts of what
+  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+  */
+-#define USBF_OBEX_INCLUDED
++#define USBF_ECM_INCLUDED
+ #include "f_ecm.c"
++#define USBF_OBEX_INCLUDED
+ #include "f_obex.c"
+ #include "f_phonet.c"
+ #include "u_ether.h"
+diff --git a/drivers/usb/gadget/u_ecm.h b/drivers/usb/gadget/u_ecm.h
+new file mode 100644
+index 0000000..99b6b99
+--- /dev/null
++++ b/drivers/usb/gadget/u_ecm.h
+@@ -0,0 +1,27 @@
++/*
++ * u_ecm.h
++ *
++ * Utility definitions for the ecm function
++ *
++ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
++ *            http://www.samsung.com
++ *
++ * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.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 U_ECM_H
++#define U_ECM_H
++
++#include <linux/usb/composite.h>
++
++struct f_ecm_opts {
++      struct usb_function_instance    func_inst;
++      struct net_device               *net;
++      bool                            bound;
++};
++
++#endif /* U_ECM_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0615-usb-gadget-cdc2-convert-to-new-interface-of-f_ecm.patch b/patches.tizen/0615-usb-gadget-cdc2-convert-to-new-interface-of-f_ecm.patch
new file mode 100644 (file)
index 0000000..b208d66
--- /dev/null
@@ -0,0 +1,202 @@
+From c33c40582661908620066aa0f083fa7fa8bd78dc Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 23 May 2013 10:32:04 +0200
+Subject: [PATCH 0615/1302] usb: gadget: cdc2: convert to new interface of
+ f_ecm
+
+f_ecm has been converted to new configfs infrastructure,
+fixing cdc2 gadget driver.
+
+[ balbi@ti.com : fixed a bunch of errors when adding ECM function ]
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig |  1 +
+ drivers/usb/gadget/cdc2.c  | 86 +++++++++++++++++++++++++++++++---------------
+ 2 files changed, 60 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index a2dbdcb..c2d374c 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -846,6 +846,7 @@ config USB_CDC_COMPOSITE
+       select USB_U_SERIAL
+       select USB_U_ETHER
+       select USB_F_ACM
++      select USB_F_ECM
+       help
+         This driver provides two functions in one configuration:
+         a CDC Ethernet (ECM) link, and a CDC ACM (serial port) link.
+diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c
+index ceedaf7..5a5acf2 100644
+--- a/drivers/usb/gadget/cdc2.c
++++ b/drivers/usb/gadget/cdc2.c
+@@ -15,6 +15,7 @@
+ #include "u_ether.h"
+ #include "u_serial.h"
++#include "u_ecm.h"
+ #define DRIVER_DESC           "CDC Composite Gadget"
+@@ -32,21 +33,10 @@
+ #define CDC_VENDOR_NUM                0x0525  /* NetChip */
+ #define CDC_PRODUCT_NUM               0xa4aa  /* CDC Composite: ECM + ACM */
+-/*-------------------------------------------------------------------------*/
+ USB_GADGET_COMPOSITE_OPTIONS();
+ USB_ETHERNET_MODULE_PARAMETERS();
+-/*
+- * Kbuild is not very cooperative with respect to linking separately
+- * compiled library objects into one module.  So for now we won't use
+- * separate compilation ... ensuring init/exit sections work to shrink
+- * the runtime footprint, and giving us at least some parts of what
+- * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+- */
+-#define USBF_ECM_INCLUDED
+-#include "f_ecm.c"
+-
+ /*-------------------------------------------------------------------------*/
+ static struct usb_device_descriptor device_desc = {
+@@ -104,12 +94,13 @@ static struct usb_gadget_strings *dev_strings[] = {
+       NULL,
+ };
+-static u8 host_mac[ETH_ALEN];
+-static struct eth_dev *the_dev;
+ /*-------------------------------------------------------------------------*/
+ static struct usb_function *f_acm;
+ static struct usb_function_instance *fi_serial;
++static struct usb_function *f_ecm;
++static struct usb_function_instance *fi_ecm;
++
+ /*
+  * We _always_ have both CDC ECM and CDC ACM functions.
+  */
+@@ -122,13 +113,27 @@ static int __init cdc_do_config(struct usb_configuration *c)
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+-      status = ecm_bind_config(c, host_mac, the_dev);
+-      if (status < 0)
+-              return status;
++      fi_ecm = usb_get_function_instance("ecm");
++      if (IS_ERR(fi_ecm)) {
++              status = PTR_ERR(fi_ecm);
++              goto err_func_ecm;
++      }
++
++      f_ecm = usb_get_function(fi_ecm);
++      if (IS_ERR(f_ecm)) {
++              status = PTR_ERR(f_ecm);
++              goto err_get_ecm;
++      }
++
++      status = usb_add_function(c, f_ecm);
++      if (status)
++              goto err_add_ecm;
+       fi_serial = usb_get_function_instance("acm");
+-      if (IS_ERR(fi_serial))
+-              return PTR_ERR(fi_serial);
++      if (IS_ERR(fi_serial)) {
++              status = PTR_ERR(fi_serial);
++              goto err_get_acm;
++      }
+       f_acm = usb_get_function(fi_serial);
+       if (IS_ERR(f_acm)) {
+@@ -138,12 +143,21 @@ static int __init cdc_do_config(struct usb_configuration *c)
+       status = usb_add_function(c, f_acm);
+       if (status)
+-              goto err_conf;
++              goto err_add_acm;
++
+       return 0;
+-err_conf:
++
++err_add_acm:
+       usb_put_function(f_acm);
+ err_func_acm:
+       usb_put_function_instance(fi_serial);
++err_get_acm:
++      usb_remove_function(c, f_ecm);
++err_add_ecm:
++      usb_put_function(f_ecm);
++err_get_ecm:
++      usb_put_function_instance(fi_ecm);
++err_func_ecm:
+       return status;
+ }
+@@ -159,6 +173,7 @@ static struct usb_configuration cdc_config_driver = {
+ static int __init cdc_bind(struct usb_composite_dev *cdev)
+ {
+       struct usb_gadget       *gadget = cdev->gadget;
++      struct f_ecm_opts       *ecm_opts;
+       int                     status;
+       if (!can_support_ecm(cdev->gadget)) {
+@@ -167,11 +182,23 @@ static int __init cdc_bind(struct usb_composite_dev *cdev)
+               return -EINVAL;
+       }
+-      /* set up network link layer */
+-      the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, host_mac,
+-                             qmult);
+-      if (IS_ERR(the_dev))
+-              return PTR_ERR(the_dev);
++      fi_ecm = usb_get_function_instance("ecm");
++      if (IS_ERR(fi_ecm))
++              return PTR_ERR(fi_ecm);
++
++      ecm_opts = container_of(fi_ecm, struct f_ecm_opts, func_inst);
++
++      gether_set_qmult(ecm_opts->net, qmult);
++      if (!gether_set_host_addr(ecm_opts->net, host_addr))
++              pr_info("using host ethernet address: %s", host_addr);
++      if (!gether_set_dev_addr(ecm_opts->net, dev_addr))
++              pr_info("using self ethernet address: %s", dev_addr);
++
++      fi_serial = usb_get_function_instance("acm");
++      if (IS_ERR(fi_serial)) {
++              status = PTR_ERR(fi_serial);
++              goto fail;
++      }
+       /* Allocate string descriptor numbers ... note that string
+        * contents can be overridden by the composite_dev glue.
+@@ -195,7 +222,9 @@ static int __init cdc_bind(struct usb_composite_dev *cdev)
+       return 0;
+ fail1:
+-      gether_cleanup(the_dev);
++      usb_put_function_instance(fi_serial);
++fail:
++      usb_put_function_instance(fi_ecm);
+       return status;
+ }
+@@ -203,7 +232,10 @@ static int __exit cdc_unbind(struct usb_composite_dev *cdev)
+ {
+       usb_put_function(f_acm);
+       usb_put_function_instance(fi_serial);
+-      gether_cleanup(the_dev);
++      if (!IS_ERR_OR_NULL(f_ecm))
++              usb_put_function(f_ecm);
++      if (!IS_ERR_OR_NULL(fi_ecm))
++              usb_put_function_instance(fi_ecm);
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0616-usb-gadget-f_ecm-use-usb_gstrings_attach.patch b/patches.tizen/0616-usb-gadget-f_ecm-use-usb_gstrings_attach.patch
new file mode 100644 (file)
index 0000000..0b10741
--- /dev/null
@@ -0,0 +1,87 @@
+From 4455bf637bb11117583e0e18af639b611b7e8283 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 23 May 2013 10:32:05 +0200
+Subject: [PATCH 0616/1302] usb: gadget: f_ecm: use usb_gstrings_attach
+
+use the new usb_gstrings_attach interface.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_ecm.c | 23 +++++++++--------------
+ 1 file changed, 9 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c
+index 1b5aeb2..22d1948 100644
+--- a/drivers/usb/gadget/f_ecm.c
++++ b/drivers/usb/gadget/f_ecm.c
+@@ -686,6 +686,7 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
+ {
+       struct usb_composite_dev *cdev = c->cdev;
+       struct f_ecm            *ecm = func_to_ecm(f);
++      struct usb_string       *us;
+       int                     status;
+       struct usb_ep           *ep;
+@@ -712,16 +713,14 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
+               ecm_opts->bound = true;
+       }
+ #endif
+-      if (ecm_string_defs[0].id == 0) {
+-              status = usb_string_ids_tab(c->cdev, ecm_string_defs);
+-              if (status)
+-                      return status;
+-
+-              ecm_control_intf.iInterface = ecm_string_defs[0].id;
+-              ecm_data_intf.iInterface = ecm_string_defs[2].id;
+-              ecm_desc.iMACAddress = ecm_string_defs[1].id;
+-              ecm_iad_descriptor.iFunction = ecm_string_defs[3].id;
+-      }
++      us = usb_gstrings_attach(cdev, ecm_strings,
++                               ARRAY_SIZE(ecm_string_defs));
++      if (IS_ERR(us))
++              return PTR_ERR(us);
++      ecm_control_intf.iInterface = us[0].id;
++      ecm_data_intf.iInterface = us[2].id;
++      ecm_desc.iMACAddress = us[1].id;
++      ecm_iad_descriptor.iFunction = us[3].id;
+       /* allocate instance-specific interface IDs */
+       status = usb_interface_id(c, f);
+@@ -841,7 +840,6 @@ ecm_old_unbind(struct usb_configuration *c, struct usb_function *f)
+       DBG(c->cdev, "ecm unbind\n");
+-      ecm_string_defs[0].id = 0;
+       usb_free_all_descriptors(f);
+       kfree(ecm->notify_req->buf);
+@@ -885,7 +883,6 @@ ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+       ecm->port.cdc_filter = DEFAULT_FILTER;
+       ecm->port.func.name = "cdc_ethernet";
+-      ecm->port.func.strings = ecm_strings;
+       /* descriptors are per-instance copies */
+       ecm->port.func.bind = ecm_bind;
+       ecm->port.func.unbind = ecm_old_unbind;
+@@ -944,7 +941,6 @@ static void ecm_unbind(struct usb_configuration *c, struct usb_function *f)
+       DBG(c->cdev, "ecm unbind\n");
+-      ecm_string_defs[0].id = 0;
+       usb_free_all_descriptors(f);
+       kfree(ecm->notify_req->buf);
+@@ -977,7 +973,6 @@ struct usb_function *ecm_alloc(struct usb_function_instance *fi)
+       ecm->port.cdc_filter = DEFAULT_FILTER;
+       ecm->port.func.name = "cdc_ethernet";
+-      ecm->port.func.strings = ecm_strings;
+       /* descriptors are per-instance copies */
+       ecm->port.func.bind = ecm_bind;
+       ecm->port.func.unbind = ecm_unbind;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0617-usb-gadget-f_ecm-add-configfs-support.patch b/patches.tizen/0617-usb-gadget-f_ecm-add-configfs-support.patch
new file mode 100644 (file)
index 0000000..14fed90
--- /dev/null
@@ -0,0 +1,151 @@
+From e1decfdf90bab463b08b9c8b59013615b8946ff4 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 23 May 2013 10:32:06 +0200
+Subject: [PATCH 0617/1302] usb: gadget: f_ecm: add configfs support
+
+f_ecm learns about our new configfs-based binding.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_ecm.c | 50 +++++++++++++++++++++++++++++++++++++++++++++-
+ drivers/usb/gadget/u_ecm.h |  9 +++++++++
+ 2 files changed, 58 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c
+index 22d1948..fcafe1a 100644
+--- a/drivers/usb/gadget/f_ecm.c
++++ b/drivers/usb/gadget/f_ecm.c
+@@ -19,6 +19,7 @@
+ #include <linux/etherdevice.h>
+ #include "u_ether.h"
++#include "u_ether_configfs.h"
+ #include "u_ecm.h"
+@@ -706,8 +707,10 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
+        * with regard to ecm_opts->bound access
+        */
+       if (!ecm_opts->bound) {
++              mutex_lock(&ecm_opts->lock);
+               gether_set_gadget(ecm_opts->net, cdev->gadget);
+               status = gether_register_netdev(ecm_opts->net);
++              mutex_unlock(&ecm_opts->lock);
+               if (status)
+                       return status;
+               ecm_opts->bound = true;
+@@ -899,6 +902,41 @@ ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+ #else
++static inline struct f_ecm_opts *to_f_ecm_opts(struct config_item *item)
++{
++      return container_of(to_config_group(item), struct f_ecm_opts,
++                          func_inst.group);
++}
++
++/* f_ecm_item_ops */
++USB_ETHERNET_CONFIGFS_ITEM(ecm);
++
++/* f_ecm_opts_dev_addr */
++USB_ETHERNET_CONFIGFS_ITEM_ATTR_DEV_ADDR(ecm);
++
++/* f_ecm_opts_host_addr */
++USB_ETHERNET_CONFIGFS_ITEM_ATTR_HOST_ADDR(ecm);
++
++/* f_ecm_opts_qmult */
++USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(ecm);
++
++/* f_ecm_opts_ifname */
++USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(ecm);
++
++static struct configfs_attribute *ecm_attrs[] = {
++      &f_ecm_opts_dev_addr.attr,
++      &f_ecm_opts_host_addr.attr,
++      &f_ecm_opts_qmult.attr,
++      &f_ecm_opts_ifname.attr,
++      NULL,
++};
++
++static struct config_item_type ecm_func_type = {
++      .ct_item_ops    = &ecm_item_ops,
++      .ct_attrs       = ecm_attrs,
++      .ct_owner       = THIS_MODULE,
++};
++
+ static void ecm_free_inst(struct usb_function_instance *f)
+ {
+       struct f_ecm_opts *opts;
+@@ -918,21 +956,28 @@ static struct usb_function_instance *ecm_alloc_inst(void)
+       opts = kzalloc(sizeof(*opts), GFP_KERNEL);
+       if (!opts)
+               return ERR_PTR(-ENOMEM);
+-
++      mutex_init(&opts->lock);
+       opts->func_inst.free_func_inst = ecm_free_inst;
+       opts->net = gether_setup_default();
+       if (IS_ERR(opts->net))
+               return ERR_PTR(PTR_ERR(opts->net));
++      config_group_init_type_name(&opts->func_inst.group, "", &ecm_func_type);
++
+       return &opts->func_inst;
+ }
+ static void ecm_free(struct usb_function *f)
+ {
+       struct f_ecm *ecm;
++      struct f_ecm_opts *opts;
+       ecm = func_to_ecm(f);
++      opts = container_of(f->fi, struct f_ecm_opts, func_inst);
+       kfree(ecm);
++      mutex_lock(&opts->lock);
++      opts->refcnt--;
++      mutex_unlock(&opts->lock);
+ }
+ static void ecm_unbind(struct usb_configuration *c, struct usb_function *f)
+@@ -959,6 +1004,8 @@ struct usb_function *ecm_alloc(struct usb_function_instance *fi)
+               return ERR_PTR(-ENOMEM);
+       opts = container_of(fi, struct f_ecm_opts, func_inst);
++      mutex_lock(&opts->lock);
++      opts->refcnt++;
+       /* export host's Ethernet address in CDC format */
+       status = gether_get_host_addr_cdc(opts->net, ecm->ethaddr,
+@@ -970,6 +1017,7 @@ struct usb_function *ecm_alloc(struct usb_function_instance *fi)
+       ecm_string_defs[1].s = ecm->ethaddr;
+       ecm->port.ioport = netdev_priv(opts->net);
++      mutex_unlock(&opts->lock);
+       ecm->port.cdc_filter = DEFAULT_FILTER;
+       ecm->port.func.name = "cdc_ethernet";
+diff --git a/drivers/usb/gadget/u_ecm.h b/drivers/usb/gadget/u_ecm.h
+index 99b6b99..262cc03 100644
+--- a/drivers/usb/gadget/u_ecm.h
++++ b/drivers/usb/gadget/u_ecm.h
+@@ -22,6 +22,15 @@ struct f_ecm_opts {
+       struct usb_function_instance    func_inst;
+       struct net_device               *net;
+       bool                            bound;
++
++      /*
++       * Read/write access to configfs attributes is handled by configfs.
++       *
++       * This is to protect the data from concurrent access by read/write
++       * and create symlink/remove symlink.
++       */
++      struct mutex                    lock;
++      int                             refcnt;
+ };
+ #endif /* U_ECM_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0618-usb-gadget-f_obex-use-usb_gstrings_attach.patch b/patches.tizen/0618-usb-gadget-f_obex-use-usb_gstrings_attach.patch
new file mode 100644 (file)
index 0000000..2a7b58f
--- /dev/null
@@ -0,0 +1,86 @@
+From 15dc516b2dd72aa9242d796c99050495a950b157 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 23 May 2013 10:51:07 +0200
+Subject: [PATCH 0618/1302] usb: gadget: f_obex: use usb_gstrings_attach
+
+use the new usb_gstrings_attach interface
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_obex.c | 23 ++++++++---------------
+ 1 file changed, 8 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c
+index 8aa2be5..8d6073a 100644
+--- a/drivers/usb/gadget/f_obex.c
++++ b/drivers/usb/gadget/f_obex.c
+@@ -309,23 +309,20 @@ static int obex_bind(struct usb_configuration *c, struct usb_function *f)
+ {
+       struct usb_composite_dev *cdev = c->cdev;
+       struct f_obex           *obex = func_to_obex(f);
++      struct usb_string       *us;
+       int                     status;
+       struct usb_ep           *ep;
+       if (!can_support_obex(c))
+               return -EINVAL;
+-      if (obex_string_defs[OBEX_CTRL_IDX].id == 0) {
+-              status = usb_string_ids_tab(c->cdev, obex_string_defs);
+-              if (status < 0)
+-                      return status;
+-              obex_control_intf.iInterface =
+-                      obex_string_defs[OBEX_CTRL_IDX].id;
+-
+-              status = obex_string_defs[OBEX_DATA_IDX].id;
+-              obex_data_nop_intf.iInterface = status;
+-              obex_data_intf.iInterface = status;
+-      }
++      us = usb_gstrings_attach(cdev, obex_strings,
++                               ARRAY_SIZE(obex_string_defs));
++      if (IS_ERR(us))
++              return PTR_ERR(us);
++      obex_control_intf.iInterface = us[OBEX_CTRL_IDX].id;
++      obex_data_nop_intf.iInterface = us[OBEX_DATA_IDX].id;
++      obex_data_intf.iInterface = us[OBEX_DATA_IDX].id;
+       /* allocate instance-specific interface IDs, and patch descriptors */
+@@ -411,7 +408,6 @@ fail:
+ static void
+ obex_old_unbind(struct usb_configuration *c, struct usb_function *f)
+ {
+-      obex_string_defs[OBEX_CTRL_IDX].id = 0;
+       usb_free_all_descriptors(f);
+       kfree(func_to_obex(f));
+ }
+@@ -440,7 +436,6 @@ int __init obex_bind_config(struct usb_configuration *c, u8 port_num)
+       obex->port.disconnect = obex_disconnect;
+       obex->port.func.name = "obex";
+-      obex->port.func.strings = obex_strings;
+       /* descriptors are per-instance copies */
+       obex->port.func.bind = obex_bind;
+       obex->port.func.unbind = obex_old_unbind;
+@@ -550,7 +545,6 @@ static void obex_free(struct usb_function *f)
+ static void obex_unbind(struct usb_configuration *c, struct usb_function *f)
+ {
+-      obex_string_defs[OBEX_CTRL_IDX].id = 0;
+       usb_free_all_descriptors(f);
+ }
+@@ -572,7 +566,6 @@ struct usb_function *obex_alloc(struct usb_function_instance *fi)
+       obex->port.disconnect = obex_disconnect;
+       obex->port.func.name = "obex";
+-      obex->port.func.strings = obex_strings;
+       /* descriptors are per-instance copies */
+       obex->port.func.bind = obex_bind;
+       obex->port.func.unbind = obex_unbind;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0619-usb-gadget-nokia-convert-to-new-interface-of-f_obex.patch b/patches.tizen/0619-usb-gadget-nokia-convert-to-new-interface-of-f_obex.patch
new file mode 100644 (file)
index 0000000..59ea4a1
--- /dev/null
@@ -0,0 +1,260 @@
+From 1f25629d503ab7375b5cf077a13ed44fe1cd54ba Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 23 May 2013 10:51:08 +0200
+Subject: [PATCH 0619/1302] usb: gadget: nokia: convert to new interface of
+ f_obex
+
+preparation to use configfs-based approach on g_nokia.ko
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig |   1 +
+ drivers/usb/gadget/nokia.c | 122 +++++++++++++++++++++++++++++++--------------
+ 2 files changed, 85 insertions(+), 38 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index c2d374c..c65427f 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -865,6 +865,7 @@ config USB_G_NOKIA
+       select USB_U_SERIAL
+       select USB_U_ETHER
+       select USB_F_ACM
++      select USB_F_OBEX
+       help
+         The Nokia composite gadget provides support for acm, obex
+         and phonet in only one composite gadget driver.
+diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c
+index 8e42c88..a69e8bf 100644
+--- a/drivers/usb/gadget/nokia.c
++++ b/drivers/usb/gadget/nokia.c
+@@ -16,6 +16,7 @@
+  */
+ #include <linux/kernel.h>
++#include <linux/module.h>
+ #include <linux/device.h>
+ #include "u_serial.h"
+@@ -39,8 +40,6 @@
+  */
+ #define USBF_ECM_INCLUDED
+ #include "f_ecm.c"
+-#define USBF_OBEX_INCLUDED
+-#include "f_obex.c"
+ #include "f_phonet.c"
+ #include "u_ether.h"
+@@ -102,16 +101,12 @@ MODULE_LICENSE("GPL");
+ static struct usb_function *f_acm_cfg1;
+ static struct usb_function *f_acm_cfg2;
+ static u8 host_mac[ETH_ALEN];
++static struct usb_function *f_obex1_cfg1;
++static struct usb_function *f_obex2_cfg1;
++static struct usb_function *f_obex1_cfg2;
++static struct usb_function *f_obex2_cfg2;
+ static struct eth_dev *the_dev;
+-enum {
+-      TTY_PORT_OBEX0,
+-      TTY_PORT_OBEX1,
+-      TTY_PORTS_MAX,
+-};
+-
+-static unsigned char tty_lines[TTY_PORTS_MAX];
+-
+ static struct usb_configuration nokia_config_500ma_driver = {
+       .label          = "Bus Powered",
+       .bConfigurationValue = 1,
+@@ -129,27 +124,51 @@ static struct usb_configuration nokia_config_100ma_driver = {
+ };
+ static struct usb_function_instance *fi_acm;
++static struct usb_function_instance *fi_obex1;
++static struct usb_function_instance *fi_obex2;
+ static int __init nokia_bind_config(struct usb_configuration *c)
+ {
+       struct usb_function *f_acm;
++      struct usb_function *f_obex1 = NULL;
++      struct usb_function *f_obex2 = NULL;
+       int status = 0;
++      int obex1_stat = 0;
++      int obex2_stat = 0;
+       status = phonet_bind_config(c);
+       if (status)
+-              printk(KERN_DEBUG "could not bind phonet config\n");
++              pr_debug("could not bind phonet config\n");
+-      status = obex_bind_config(c, tty_lines[TTY_PORT_OBEX0]);
+-      if (status)
+-              printk(KERN_DEBUG "could not bind obex config %d\n", 0);
++      if (!IS_ERR(fi_obex1)) {
++              f_obex1 = usb_get_function(fi_obex1);
++              if (IS_ERR(f_obex1))
++                      pr_debug("could not get obex function 0\n");
++      }
+-      status = obex_bind_config(c, tty_lines[TTY_PORT_OBEX1]);
+-      if (status)
+-              printk(KERN_DEBUG "could not bind obex config %d\n", 0);
++      if (!IS_ERR(fi_obex2)) {
++              f_obex2 = usb_get_function(fi_obex2);
++              if (IS_ERR(f_obex2))
++                      pr_debug("could not get obex function 1\n");
++      }
+       f_acm = usb_get_function(fi_acm);
+-      if (IS_ERR(f_acm))
+-              return PTR_ERR(f_acm);
++      if (IS_ERR(f_acm)) {
++              status = PTR_ERR(f_acm);
++              goto err_get_acm;
++      }
++
++      if (!IS_ERR_OR_NULL(f_obex1)) {
++              obex1_stat = usb_add_function(c, f_obex1);
++              if (obex1_stat)
++                      pr_debug("could not add obex function 0\n");
++      }
++
++      if (!IS_ERR_OR_NULL(f_obex2)) {
++              obex2_stat = usb_add_function(c, f_obex2);
++              if (obex2_stat)
++                      pr_debug("could not add obex function 1\n");
++      }
+       status = usb_add_function(c, f_acm);
+       if (status)
+@@ -160,16 +179,30 @@ static int __init nokia_bind_config(struct usb_configuration *c)
+               pr_debug("could not bind ecm config %d\n", status);
+               goto err_ecm;
+       }
+-      if (c == &nokia_config_500ma_driver)
++      if (c == &nokia_config_500ma_driver) {
+               f_acm_cfg1 = f_acm;
+-      else
++              f_obex1_cfg1 = f_obex1;
++              f_obex2_cfg1 = f_obex2;
++      } else {
+               f_acm_cfg2 = f_acm;
++              f_obex1_cfg2 = f_obex1;
++              f_obex2_cfg2 = f_obex2;
++      }
+       return status;
+ err_ecm:
+       usb_remove_function(c, f_acm);
+ err_conf:
++      if (!obex2_stat)
++              usb_remove_function(c, f_obex2);
++      if (!obex1_stat)
++              usb_remove_function(c, f_obex1);
+       usb_put_function(f_acm);
++err_get_acm:
++      if (!IS_ERR_OR_NULL(f_obex2))
++              usb_put_function(f_obex2);
++      if (!IS_ERR_OR_NULL(f_obex1))
++              usb_put_function(f_obex1);
+       return status;
+ }
+@@ -177,18 +210,11 @@ static int __init nokia_bind(struct usb_composite_dev *cdev)
+ {
+       struct usb_gadget       *gadget = cdev->gadget;
+       int                     status;
+-      int                     cur_line;
+       status = gphonet_setup(cdev->gadget);
+       if (status < 0)
+               goto err_phonet;
+-      for (cur_line = 0; cur_line < TTY_PORTS_MAX; cur_line++) {
+-              status = gserial_alloc_line(&tty_lines[cur_line]);
+-              if (status)
+-                      goto err_ether;
+-      }
+-
+       the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, host_mac,
+                              qmult);
+       if (IS_ERR(the_dev)) {
+@@ -208,9 +234,17 @@ static int __init nokia_bind(struct usb_composite_dev *cdev)
+       if (!gadget_supports_altsettings(gadget))
+               goto err_usb;
++      fi_obex1 = usb_get_function_instance("obex");
++      if (IS_ERR(fi_obex1))
++              pr_debug("could not find obex function 1\n");
++
++      fi_obex2 = usb_get_function_instance("obex");
++      if (IS_ERR(fi_obex2))
++              pr_debug("could not find obex function 2\n");
++
+       fi_acm = usb_get_function_instance("acm");
+       if (IS_ERR(fi_acm))
+-              goto err_usb;
++              goto err_obex2_inst;
+       /* finally register the configuration */
+       status = usb_add_config(cdev, &nokia_config_500ma_driver,
+@@ -230,15 +264,20 @@ static int __init nokia_bind(struct usb_composite_dev *cdev)
+ err_put_cfg1:
+       usb_put_function(f_acm_cfg1);
++      if (!IS_ERR_OR_NULL(f_obex1_cfg1))
++              usb_put_function(f_obex1_cfg1);
++      if (!IS_ERR_OR_NULL(f_obex2_cfg1))
++              usb_put_function(f_obex2_cfg1);
+ err_acm_inst:
+       usb_put_function_instance(fi_acm);
++err_obex2_inst:
++      if (!IS_ERR(fi_obex2))
++              usb_put_function_instance(fi_obex2);
++      if (!IS_ERR(fi_obex1))
++              usb_put_function_instance(fi_obex1);
+ err_usb:
+       gether_cleanup(the_dev);
+ err_ether:
+-      cur_line--;
+-      while (cur_line >= 0)
+-              gserial_free_line(tty_lines[cur_line--]);
+-
+       gphonet_cleanup();
+ err_phonet:
+       return status;
+@@ -246,16 +285,23 @@ err_phonet:
+ static int __exit nokia_unbind(struct usb_composite_dev *cdev)
+ {
+-      int i;
+-
++      if (!IS_ERR_OR_NULL(f_obex1_cfg2))
++              usb_put_function(f_obex1_cfg2);
++      if (!IS_ERR_OR_NULL(f_obex2_cfg2))
++              usb_put_function(f_obex2_cfg2);
++      if (!IS_ERR_OR_NULL(f_obex1_cfg1))
++              usb_put_function(f_obex1_cfg1);
++      if (!IS_ERR_OR_NULL(f_obex2_cfg1))
++              usb_put_function(f_obex2_cfg1);
+       usb_put_function(f_acm_cfg1);
+       usb_put_function(f_acm_cfg2);
++      if (!IS_ERR(fi_obex1))
++              usb_put_function_instance(fi_obex1);
++      if (!IS_ERR(fi_obex2))
++              usb_put_function_instance(fi_obex2);
+       usb_put_function_instance(fi_acm);
+       gphonet_cleanup();
+-      for (i = 0; i < TTY_PORTS_MAX; i++)
+-              gserial_free_line(tty_lines[i]);
+-
+       gether_cleanup(the_dev);
+       return 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0620-usb-gadget-f_obex-remove-compatibility-layer.patch b/patches.tizen/0620-usb-gadget-f_obex-remove-compatibility-layer.patch
new file mode 100644 (file)
index 0000000..bc6c667
--- /dev/null
@@ -0,0 +1,88 @@
+From 914f7cb5dca7fd22db83b6889346aaff35888f79 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 23 May 2013 10:51:09 +0200
+Subject: [PATCH 0620/1302] usb: gadget: f_obex: remove compatibility layer
+
+There are no old function interface users left, so the old interface
+can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_obex.c | 52 ---------------------------------------------
+ 1 file changed, 52 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c
+index 8d6073a..ad39f1d 100644
+--- a/drivers/usb/gadget/f_obex.c
++++ b/drivers/usb/gadget/f_obex.c
+@@ -403,55 +403,6 @@ fail:
+       return status;
+ }
+-#ifdef USBF_OBEX_INCLUDED
+-
+-static void
+-obex_old_unbind(struct usb_configuration *c, struct usb_function *f)
+-{
+-      usb_free_all_descriptors(f);
+-      kfree(func_to_obex(f));
+-}
+-
+-/**
+- * obex_bind_config - add a CDC OBEX function to a configuration
+- * @c: the configuration to support the CDC OBEX instance
+- * @port_num: /dev/ttyGS* port this interface will use
+- * Context: single threaded during gadget setup
+- *
+- * Returns zero on success, else negative errno.
+- */
+-int __init obex_bind_config(struct usb_configuration *c, u8 port_num)
+-{
+-      struct f_obex   *obex;
+-      int             status;
+-
+-      /* allocate and initialize one new instance */
+-      obex = kzalloc(sizeof *obex, GFP_KERNEL);
+-      if (!obex)
+-              return -ENOMEM;
+-
+-      obex->port_num = port_num;
+-
+-      obex->port.connect = obex_connect;
+-      obex->port.disconnect = obex_disconnect;
+-
+-      obex->port.func.name = "obex";
+-      /* descriptors are per-instance copies */
+-      obex->port.func.bind = obex_bind;
+-      obex->port.func.unbind = obex_old_unbind;
+-      obex->port.func.set_alt = obex_set_alt;
+-      obex->port.func.get_alt = obex_get_alt;
+-      obex->port.func.disable = obex_disable;
+-
+-      status = usb_add_function(c, &obex->port.func);
+-      if (status)
+-              kfree(obex);
+-
+-      return status;
+-}
+-
+-#else
+-
+ static inline struct f_serial_opts *to_f_serial_opts(struct config_item *item)
+ {
+       return container_of(to_config_group(item), struct f_serial_opts,
+@@ -578,8 +529,5 @@ struct usb_function *obex_alloc(struct usb_function_instance *fi)
+ }
+ DECLARE_USB_FUNCTION_INIT(obex, obex_alloc_inst, obex_alloc);
+-
+-#endif
+-
+ MODULE_AUTHOR("Felipe Balbi");
+ MODULE_LICENSE("GPL");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0621-usb-gadget-phonet-move-global-dev-variable-to-its-us.patch b/patches.tizen/0621-usb-gadget-phonet-move-global-dev-variable-to-its-us.patch
new file mode 100644 (file)
index 0000000..ceb4004
--- /dev/null
@@ -0,0 +1,146 @@
+From 9ac09507f1c2d88e895f15b929fb7509e0b8d785 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 23 May 2013 10:51:10 +0200
+Subject: [PATCH 0621/1302] usb: gadget: phonet: move global dev variable to
+ its user
+
+cleanup patch only in preparation for configfs.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_phonet.c | 20 +++++++++++---------
+ drivers/usb/gadget/nokia.c    | 14 +++++++++-----
+ drivers/usb/gadget/u_phonet.h |  6 +++---
+ 3 files changed, 23 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c
+index b21ab55..f8df525 100644
+--- a/drivers/usb/gadget/f_phonet.c
++++ b/drivers/usb/gadget/f_phonet.c
+@@ -579,9 +579,8 @@ pn_unbind(struct usb_configuration *c, struct usb_function *f)
+ /*-------------------------------------------------------------------------*/
+-static struct net_device *dev;
+-
+-int __init phonet_bind_config(struct usb_configuration *c)
++int __init phonet_bind_config(struct usb_configuration *c,
++                            struct net_device *dev)
+ {
+       struct f_phonet *fp;
+       int err, size;
+@@ -606,16 +605,16 @@ int __init phonet_bind_config(struct usb_configuration *c)
+       return err;
+ }
+-int __init gphonet_setup(struct usb_gadget *gadget)
++struct net_device __init *gphonet_setup(struct usb_gadget *gadget)
+ {
++      struct net_device *dev;
+       struct phonet_port *port;
+       int err;
+       /* Create net device */
+-      BUG_ON(dev);
+       dev = alloc_netdev(sizeof(*port), "upnlink%d", pn_net_setup);
+       if (!dev)
+-              return -ENOMEM;
++              return ERR_PTR(-ENOMEM);
+       port = netdev_priv(dev);
+       spin_lock_init(&port->lock);
+@@ -623,12 +622,15 @@ int __init gphonet_setup(struct usb_gadget *gadget)
+       SET_NETDEV_DEV(dev, &gadget->dev);
+       err = register_netdev(dev);
+-      if (err)
++      if (err) {
+               free_netdev(dev);
+-      return err;
++
++              return ERR_PTR(err);
++      }
++      return dev;
+ }
+-void gphonet_cleanup(void)
++void gphonet_cleanup(struct net_device *dev)
+ {
+       unregister_netdev(dev);
+ }
+diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c
+index a69e8bf..5650ece 100644
+--- a/drivers/usb/gadget/nokia.c
++++ b/drivers/usb/gadget/nokia.c
+@@ -106,6 +106,8 @@ static struct usb_function *f_obex2_cfg1;
+ static struct usb_function *f_obex1_cfg2;
+ static struct usb_function *f_obex2_cfg2;
+ static struct eth_dev *the_dev;
++static struct net_device *phonet_dev;
++
+ static struct usb_configuration nokia_config_500ma_driver = {
+       .label          = "Bus Powered",
+@@ -136,7 +138,7 @@ static int __init nokia_bind_config(struct usb_configuration *c)
+       int obex1_stat = 0;
+       int obex2_stat = 0;
+-      status = phonet_bind_config(c);
++      status = phonet_bind_config(c, phonet_dev);
+       if (status)
+               pr_debug("could not bind phonet config\n");
+@@ -211,9 +213,11 @@ static int __init nokia_bind(struct usb_composite_dev *cdev)
+       struct usb_gadget       *gadget = cdev->gadget;
+       int                     status;
+-      status = gphonet_setup(cdev->gadget);
+-      if (status < 0)
++      phonet_dev = gphonet_setup(cdev->gadget);
++      if (IS_ERR(phonet_dev)) {
++              status = PTR_ERR(phonet_dev);
+               goto err_phonet;
++      }
+       the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, host_mac,
+                              qmult);
+@@ -278,7 +282,7 @@ err_obex2_inst:
+ err_usb:
+       gether_cleanup(the_dev);
+ err_ether:
+-      gphonet_cleanup();
++      gphonet_cleanup(phonet_dev);
+ err_phonet:
+       return status;
+ }
+@@ -300,7 +304,7 @@ static int __exit nokia_unbind(struct usb_composite_dev *cdev)
+       if (!IS_ERR(fi_obex2))
+               usb_put_function_instance(fi_obex2);
+       usb_put_function_instance(fi_acm);
+-      gphonet_cleanup();
++      gphonet_cleanup(phonet_dev);
+       gether_cleanup(the_dev);
+diff --git a/drivers/usb/gadget/u_phonet.h b/drivers/usb/gadget/u_phonet.h
+index 09a7525..459ee32 100644
+--- a/drivers/usb/gadget/u_phonet.h
++++ b/drivers/usb/gadget/u_phonet.h
+@@ -14,8 +14,8 @@
+ #include <linux/usb/composite.h>
+ #include <linux/usb/cdc.h>
+-int gphonet_setup(struct usb_gadget *gadget);
+-int phonet_bind_config(struct usb_configuration *c);
+-void gphonet_cleanup(void);
++struct net_device *gphonet_setup(struct usb_gadget *gadget);
++int phonet_bind_config(struct usb_configuration *c, struct net_device *dev);
++void gphonet_cleanup(struct net_device *dev);
+ #endif /* __U_PHONET_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0622-usb-gadget-f_phonet-convert-to-new-function-interfac.patch b/patches.tizen/0622-usb-gadget-f_phonet-convert-to-new-function-interfac.patch
new file mode 100644 (file)
index 0000000..98a68af
--- /dev/null
@@ -0,0 +1,289 @@
+From cd6c5c0ee3522f3889dc305797bcf353e1919384 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 23 May 2013 10:51:11 +0200
+Subject: [PATCH 0622/1302] usb: gadget: f_phonet: convert to new function
+ interface with backward compatibility
+
+Converting f_phonet to the new function interface requires converting
+the f_phonet's function code and its users.
+
+This patch converts the f_phonet.c to the new function interface.
+
+The file is now compiled into a separate usb_f_phonet.ko module.
+
+The old function interface is provided by means of preprocessor
+conditional directives. After all users are converted, the old interface
+can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig    |   3 +
+ drivers/usb/gadget/Makefile   |   2 +
+ drivers/usb/gadget/f_phonet.c | 151 ++++++++++++++++++++++++++++++++++++++++--
+ drivers/usb/gadget/nokia.c    |   1 +
+ drivers/usb/gadget/u_phonet.h |   9 +++
+ 5 files changed, 161 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index c65427f..f1e8534 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -525,6 +525,9 @@ config USB_F_NCM
+ config USB_F_ECM
+       tristate
++config USB_F_PHONET
++      tristate
++
+ choice
+       tristate "USB Gadget Drivers"
+       default USB_ETH
+diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
+index 66152f5..db8ce05 100644
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -52,6 +52,8 @@ usb_f_ncm-y                  := f_ncm.o
+ obj-$(CONFIG_USB_F_NCM)               += usb_f_ncm.o
+ usb_f_ecm-y                   := f_ecm.o
+ obj-$(CONFIG_USB_F_ECM)               += usb_f_ecm.o
++usb_f_phonet-y                        := f_phonet.o
++obj-$(CONFIG_USB_F_PHONET)    += usb_f_phonet.o
+ #
+ # USB gadget drivers
+diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c
+index f8df525..a667dfe 100644
+--- a/drivers/usb/gadget/f_phonet.c
++++ b/drivers/usb/gadget/f_phonet.c
+@@ -13,6 +13,7 @@
+ #include <linux/mm.h>
+ #include <linux/slab.h>
+ #include <linux/kernel.h>
++#include <linux/module.h>
+ #include <linux/device.h>
+ #include <linux/netdevice.h>
+@@ -478,8 +479,7 @@ static void pn_disconnect(struct usb_function *f)
+ /*-------------------------------------------------------------------------*/
+-static __init
+-int pn_bind(struct usb_configuration *c, struct usb_function *f)
++static int pn_bind(struct usb_configuration *c, struct usb_function *f)
+ {
+       struct usb_composite_dev *cdev = c->cdev;
+       struct usb_gadget *gadget = cdev->gadget;
+@@ -487,6 +487,27 @@ int pn_bind(struct usb_configuration *c, struct usb_function *f)
+       struct usb_ep *ep;
+       int status, i;
++#ifndef USBF_PHONET_INCLUDED
++      struct f_phonet_opts *phonet_opts;
++
++      phonet_opts = container_of(f->fi, struct f_phonet_opts, func_inst);
++
++      /*
++       * in drivers/usb/gadget/configfs.c:configfs_composite_bind()
++       * configurations are bound in sequence with list_for_each_entry,
++       * in each configuration its functions are bound in sequence
++       * with list_for_each_entry, so we assume no race condition
++       * with regard to phonet_opts->bound access
++       */
++      if (!phonet_opts->bound) {
++              gphonet_set_gadget(phonet_opts->net, gadget);
++              status = gphonet_register_netdev(phonet_opts->net);
++              if (status)
++                      return status;
++              phonet_opts->bound = true;
++      }
++#endif
++
+       /* Reserve interface IDs */
+       status = usb_interface_id(c, f);
+       if (status < 0)
+@@ -560,8 +581,10 @@ err:
+       return status;
+ }
++#ifdef USBF_PHONET_INCLUDED
++
+ static void
+-pn_unbind(struct usb_configuration *c, struct usb_function *f)
++pn_old_unbind(struct usb_configuration *c, struct usb_function *f)
+ {
+       struct f_phonet *fp = func_to_pn(f);
+       int i;
+@@ -593,7 +616,7 @@ int __init phonet_bind_config(struct usb_configuration *c,
+       fp->dev = dev;
+       fp->function.name = "phonet";
+       fp->function.bind = pn_bind;
+-      fp->function.unbind = pn_unbind;
++      fp->function.unbind = pn_old_unbind;
+       fp->function.set_alt = pn_set_alt;
+       fp->function.get_alt = pn_get_alt;
+       fp->function.disable = pn_disconnect;
+@@ -605,7 +628,125 @@ int __init phonet_bind_config(struct usb_configuration *c,
+       return err;
+ }
+-struct net_device __init *gphonet_setup(struct usb_gadget *gadget)
++#else
++
++static void phonet_free_inst(struct usb_function_instance *f)
++{
++      struct f_phonet_opts *opts;
++
++      opts = container_of(f, struct f_phonet_opts, func_inst);
++      if (opts->bound)
++              gphonet_cleanup(opts->net);
++      else
++              free_netdev(opts->net);
++      kfree(opts);
++}
++
++static struct usb_function_instance *phonet_alloc_inst(void)
++{
++      struct f_phonet_opts *opts;
++
++      opts = kzalloc(sizeof(*opts), GFP_KERNEL);
++      if (!opts)
++              return ERR_PTR(-ENOMEM);
++
++      opts->func_inst.free_func_inst = phonet_free_inst;
++      opts->net = gphonet_setup_default();
++      if (IS_ERR(opts->net))
++              return ERR_PTR(PTR_ERR(opts->net));
++
++      return &opts->func_inst;
++}
++
++static void phonet_free(struct usb_function *f)
++{
++      struct f_phonet *phonet;
++
++      phonet = func_to_pn(f);
++      kfree(phonet);
++}
++
++static void pn_unbind(struct usb_configuration *c, struct usb_function *f)
++{
++      struct f_phonet *fp = func_to_pn(f);
++      int i;
++
++      /* We are already disconnected */
++      if (fp->in_req)
++              usb_ep_free_request(fp->in_ep, fp->in_req);
++      for (i = 0; i < phonet_rxq_size; i++)
++              if (fp->out_reqv[i])
++                      usb_ep_free_request(fp->out_ep, fp->out_reqv[i]);
++
++      usb_free_all_descriptors(f);
++}
++
++struct usb_function *phonet_alloc(struct usb_function_instance *fi)
++{
++      struct f_phonet *fp;
++      struct f_phonet_opts *opts;
++      int size;
++
++      size = sizeof(*fp) + (phonet_rxq_size * sizeof(struct usb_request *));
++      fp = kzalloc(size, GFP_KERNEL);
++      if (!fp)
++              return ERR_PTR(-ENOMEM);
++
++      opts = container_of(fi, struct f_phonet_opts, func_inst);
++
++      fp->dev = opts->net;
++      fp->function.name = "phonet";
++      fp->function.bind = pn_bind;
++      fp->function.unbind = pn_unbind;
++      fp->function.set_alt = pn_set_alt;
++      fp->function.get_alt = pn_get_alt;
++      fp->function.disable = pn_disconnect;
++      fp->function.free_func = phonet_free;
++      spin_lock_init(&fp->rx.lock);
++
++      return &fp->function;
++}
++
++struct net_device *gphonet_setup_default(void)
++{
++      struct net_device *dev;
++      struct phonet_port *port;
++
++      /* Create net device */
++      dev = alloc_netdev(sizeof(*port), "upnlink%d", pn_net_setup);
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      port = netdev_priv(dev);
++      spin_lock_init(&port->lock);
++      netif_carrier_off(dev);
++
++      return dev;
++}
++
++void gphonet_set_gadget(struct net_device *net, struct usb_gadget *g)
++{
++      SET_NETDEV_DEV(net, &g->dev);
++}
++
++int gphonet_register_netdev(struct net_device *net)
++{
++      int status;
++
++      status = register_netdev(net);
++      if (status)
++              free_netdev(net);
++
++      return status;
++}
++
++DECLARE_USB_FUNCTION_INIT(phonet, phonet_alloc_inst, phonet_alloc);
++MODULE_AUTHOR("Rémi Denis-Courmont");
++MODULE_LICENSE("GPL");
++
++#endif
++
++struct net_device *gphonet_setup(struct usb_gadget *gadget)
+ {
+       struct net_device *dev;
+       struct phonet_port *port;
+diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c
+index 5650ece..a20bcbf 100644
+--- a/drivers/usb/gadget/nokia.c
++++ b/drivers/usb/gadget/nokia.c
+@@ -40,6 +40,7 @@
+  */
+ #define USBF_ECM_INCLUDED
+ #include "f_ecm.c"
++#define USBF_PHONET_INCLUDED
+ #include "f_phonet.c"
+ #include "u_ether.h"
+diff --git a/drivers/usb/gadget/u_phonet.h b/drivers/usb/gadget/u_phonet.h
+index 459ee32..1ff5ad5 100644
+--- a/drivers/usb/gadget/u_phonet.h
++++ b/drivers/usb/gadget/u_phonet.h
+@@ -14,6 +14,15 @@
+ #include <linux/usb/composite.h>
+ #include <linux/usb/cdc.h>
++struct f_phonet_opts {
++      struct usb_function_instance func_inst;
++      bool bound;
++      struct net_device *net;
++};
++
++struct net_device *gphonet_setup_default(void);
++void gphonet_set_gadget(struct net_device *net, struct usb_gadget *g);
++int gphonet_register_netdev(struct net_device *net);
+ struct net_device *gphonet_setup(struct usb_gadget *gadget);
+ int phonet_bind_config(struct usb_configuration *c, struct net_device *dev);
+ void gphonet_cleanup(struct net_device *dev);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0623-usb-gadget-nokia-convert-to-new-interface-of-f_phone.patch b/patches.tizen/0623-usb-gadget-nokia-convert-to-new-interface-of-f_phone.patch
new file mode 100644 (file)
index 0000000..11892b1
--- /dev/null
@@ -0,0 +1,199 @@
+From 30114ecb620d7751372cff3e4a4d29b92c0ea0b2 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 23 May 2013 10:51:12 +0200
+Subject: [PATCH 0623/1302] usb: gadget: nokia: convert to new interface of
+ f_phonet
+
+use the new interface which will allow us to deprecate the
+legacy way of binding functions.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig |  1 +
+ drivers/usb/gadget/nokia.c | 56 ++++++++++++++++++++++++++++++++--------------
+ 2 files changed, 40 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index f1e8534..2b75585 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -869,6 +869,7 @@ config USB_G_NOKIA
+       select USB_U_ETHER
+       select USB_F_ACM
+       select USB_F_OBEX
++      select USB_F_PHONET
+       help
+         The Nokia composite gadget provides support for acm, obex
+         and phonet in only one composite gadget driver.
+diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c
+index a20bcbf..084f947 100644
+--- a/drivers/usb/gadget/nokia.c
++++ b/drivers/usb/gadget/nokia.c
+@@ -40,8 +40,6 @@
+  */
+ #define USBF_ECM_INCLUDED
+ #include "f_ecm.c"
+-#define USBF_PHONET_INCLUDED
+-#include "f_phonet.c"
+ #include "u_ether.h"
+ /*-------------------------------------------------------------------------*/
+@@ -106,8 +104,9 @@ static struct usb_function *f_obex1_cfg1;
+ static struct usb_function *f_obex2_cfg1;
+ static struct usb_function *f_obex1_cfg2;
+ static struct usb_function *f_obex2_cfg2;
++static struct usb_function *f_phonet_cfg1;
++static struct usb_function *f_phonet_cfg2;
+ static struct eth_dev *the_dev;
+-static struct net_device *phonet_dev;
+ static struct usb_configuration nokia_config_500ma_driver = {
+@@ -129,19 +128,24 @@ static struct usb_configuration nokia_config_100ma_driver = {
+ static struct usb_function_instance *fi_acm;
+ static struct usb_function_instance *fi_obex1;
+ static struct usb_function_instance *fi_obex2;
++static struct usb_function_instance *fi_phonet;
+ static int __init nokia_bind_config(struct usb_configuration *c)
+ {
+       struct usb_function *f_acm;
++      struct usb_function *f_phonet = NULL;
+       struct usb_function *f_obex1 = NULL;
+       struct usb_function *f_obex2 = NULL;
+       int status = 0;
+       int obex1_stat = 0;
+       int obex2_stat = 0;
++      int phonet_stat = 0;
+-      status = phonet_bind_config(c, phonet_dev);
+-      if (status)
+-              pr_debug("could not bind phonet config\n");
++      if (!IS_ERR(fi_phonet)) {
++              f_phonet = usb_get_function(fi_phonet);
++              if (IS_ERR(f_phonet))
++                      pr_debug("could not get phonet function\n");
++      }
+       if (!IS_ERR(fi_obex1)) {
+               f_obex1 = usb_get_function(fi_obex1);
+@@ -161,6 +165,12 @@ static int __init nokia_bind_config(struct usb_configuration *c)
+               goto err_get_acm;
+       }
++      if (!IS_ERR_OR_NULL(f_phonet)) {
++              phonet_stat = usb_add_function(c, f_phonet);
++              if (phonet_stat)
++                      pr_debug("could not add phonet function\n");
++      }
++
+       if (!IS_ERR_OR_NULL(f_obex1)) {
+               obex1_stat = usb_add_function(c, f_obex1);
+               if (obex1_stat)
+@@ -184,10 +194,12 @@ static int __init nokia_bind_config(struct usb_configuration *c)
+       }
+       if (c == &nokia_config_500ma_driver) {
+               f_acm_cfg1 = f_acm;
++              f_phonet_cfg1 = f_phonet;
+               f_obex1_cfg1 = f_obex1;
+               f_obex2_cfg1 = f_obex2;
+       } else {
+               f_acm_cfg2 = f_acm;
++              f_phonet_cfg2 = f_phonet;
+               f_obex1_cfg2 = f_obex1;
+               f_obex2_cfg2 = f_obex2;
+       }
+@@ -200,12 +212,16 @@ err_conf:
+               usb_remove_function(c, f_obex2);
+       if (!obex1_stat)
+               usb_remove_function(c, f_obex1);
++      if (!phonet_stat)
++              usb_remove_function(c, f_phonet);
+       usb_put_function(f_acm);
+ err_get_acm:
+       if (!IS_ERR_OR_NULL(f_obex2))
+               usb_put_function(f_obex2);
+       if (!IS_ERR_OR_NULL(f_obex1))
+               usb_put_function(f_obex1);
++      if (!IS_ERR_OR_NULL(f_phonet))
++              usb_put_function(f_phonet);
+       return status;
+ }
+@@ -214,12 +230,6 @@ static int __init nokia_bind(struct usb_composite_dev *cdev)
+       struct usb_gadget       *gadget = cdev->gadget;
+       int                     status;
+-      phonet_dev = gphonet_setup(cdev->gadget);
+-      if (IS_ERR(phonet_dev)) {
+-              status = PTR_ERR(phonet_dev);
+-              goto err_phonet;
+-      }
+-
+       the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, host_mac,
+                              qmult);
+       if (IS_ERR(the_dev)) {
+@@ -239,6 +249,10 @@ static int __init nokia_bind(struct usb_composite_dev *cdev)
+       if (!gadget_supports_altsettings(gadget))
+               goto err_usb;
++      fi_phonet = usb_get_function_instance("phonet");
++      if (IS_ERR(fi_phonet))
++              pr_debug("could not find phonet function\n");
++
+       fi_obex1 = usb_get_function_instance("obex");
+       if (IS_ERR(fi_obex1))
+               pr_debug("could not find obex function 1\n");
+@@ -273,6 +287,8 @@ err_put_cfg1:
+               usb_put_function(f_obex1_cfg1);
+       if (!IS_ERR_OR_NULL(f_obex2_cfg1))
+               usb_put_function(f_obex2_cfg1);
++      if (!IS_ERR_OR_NULL(f_phonet_cfg1))
++              usb_put_function(f_phonet_cfg1);
+ err_acm_inst:
+       usb_put_function_instance(fi_acm);
+ err_obex2_inst:
+@@ -280,11 +296,11 @@ err_obex2_inst:
+               usb_put_function_instance(fi_obex2);
+       if (!IS_ERR(fi_obex1))
+               usb_put_function_instance(fi_obex1);
++      if (!IS_ERR(fi_phonet))
++              usb_put_function_instance(fi_phonet);
+ err_usb:
+       gether_cleanup(the_dev);
+ err_ether:
+-      gphonet_cleanup(phonet_dev);
+-err_phonet:
+       return status;
+ }
+@@ -298,14 +314,20 @@ static int __exit nokia_unbind(struct usb_composite_dev *cdev)
+               usb_put_function(f_obex1_cfg1);
+       if (!IS_ERR_OR_NULL(f_obex2_cfg1))
+               usb_put_function(f_obex2_cfg1);
++      if (!IS_ERR_OR_NULL(f_phonet_cfg1))
++              usb_put_function(f_phonet_cfg1);
++      if (!IS_ERR_OR_NULL(f_phonet_cfg2))
++              usb_put_function(f_phonet_cfg2);
+       usb_put_function(f_acm_cfg1);
+       usb_put_function(f_acm_cfg2);
+-      if (!IS_ERR(fi_obex1))
+-              usb_put_function_instance(fi_obex1);
++
+       if (!IS_ERR(fi_obex2))
+               usb_put_function_instance(fi_obex2);
++      if (!IS_ERR(fi_obex1))
++              usb_put_function_instance(fi_obex1);
++      if (!IS_ERR(fi_phonet))
++              usb_put_function_instance(fi_phonet);
+       usb_put_function_instance(fi_acm);
+-      gphonet_cleanup(phonet_dev);
+       gether_cleanup(the_dev);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0624-usb-gadget-f_phonet-remove-compatibility-layer.patch b/patches.tizen/0624-usb-gadget-f_phonet-remove-compatibility-layer.patch
new file mode 100644 (file)
index 0000000..15fd22c
--- /dev/null
@@ -0,0 +1,135 @@
+From e40e931ffad65893ae489f16a41c1d692af8e939 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 23 May 2013 10:51:13 +0200
+Subject: [PATCH 0624/1302] usb: gadget: f_phonet: remove compatibility layer
+
+There are no old function interface users left, so the old interface
+can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_phonet.c | 84 +++----------------------------------------
+ drivers/usb/gadget/u_phonet.h |  1 -
+ 2 files changed, 4 insertions(+), 81 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c
+index a667dfe..5dd7748 100644
+--- a/drivers/usb/gadget/f_phonet.c
++++ b/drivers/usb/gadget/f_phonet.c
+@@ -581,55 +581,6 @@ err:
+       return status;
+ }
+-#ifdef USBF_PHONET_INCLUDED
+-
+-static void
+-pn_old_unbind(struct usb_configuration *c, struct usb_function *f)
+-{
+-      struct f_phonet *fp = func_to_pn(f);
+-      int i;
+-
+-      /* We are already disconnected */
+-      if (fp->in_req)
+-              usb_ep_free_request(fp->in_ep, fp->in_req);
+-      for (i = 0; i < phonet_rxq_size; i++)
+-              if (fp->out_reqv[i])
+-                      usb_ep_free_request(fp->out_ep, fp->out_reqv[i]);
+-
+-      usb_free_all_descriptors(f);
+-      kfree(fp);
+-}
+-
+-/*-------------------------------------------------------------------------*/
+-
+-int __init phonet_bind_config(struct usb_configuration *c,
+-                            struct net_device *dev)
+-{
+-      struct f_phonet *fp;
+-      int err, size;
+-
+-      size = sizeof(*fp) + (phonet_rxq_size * sizeof(struct usb_request *));
+-      fp = kzalloc(size, GFP_KERNEL);
+-      if (!fp)
+-              return -ENOMEM;
+-
+-      fp->dev = dev;
+-      fp->function.name = "phonet";
+-      fp->function.bind = pn_bind;
+-      fp->function.unbind = pn_old_unbind;
+-      fp->function.set_alt = pn_set_alt;
+-      fp->function.get_alt = pn_get_alt;
+-      fp->function.disable = pn_disconnect;
+-      spin_lock_init(&fp->rx.lock);
+-
+-      err = usb_add_function(c, &fp->function);
+-      if (err)
+-              kfree(fp);
+-      return err;
+-}
+-
+-#else
+-
+ static void phonet_free_inst(struct usb_function_instance *f)
+ {
+       struct f_phonet_opts *opts;
+@@ -740,38 +691,11 @@ int gphonet_register_netdev(struct net_device *net)
+       return status;
+ }
+-DECLARE_USB_FUNCTION_INIT(phonet, phonet_alloc_inst, phonet_alloc);
+-MODULE_AUTHOR("Rémi Denis-Courmont");
+-MODULE_LICENSE("GPL");
+-
+-#endif
+-
+-struct net_device *gphonet_setup(struct usb_gadget *gadget)
+-{
+-      struct net_device *dev;
+-      struct phonet_port *port;
+-      int err;
+-
+-      /* Create net device */
+-      dev = alloc_netdev(sizeof(*port), "upnlink%d", pn_net_setup);
+-      if (!dev)
+-              return ERR_PTR(-ENOMEM);
+-
+-      port = netdev_priv(dev);
+-      spin_lock_init(&port->lock);
+-      netif_carrier_off(dev);
+-      SET_NETDEV_DEV(dev, &gadget->dev);
+-
+-      err = register_netdev(dev);
+-      if (err) {
+-              free_netdev(dev);
+-
+-              return ERR_PTR(err);
+-      }
+-      return dev;
+-}
+-
+ void gphonet_cleanup(struct net_device *dev)
+ {
+       unregister_netdev(dev);
+ }
++
++DECLARE_USB_FUNCTION_INIT(phonet, phonet_alloc_inst, phonet_alloc);
++MODULE_AUTHOR("Rémi Denis-Courmont");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/usb/gadget/u_phonet.h b/drivers/usb/gadget/u_phonet.h
+index 1ff5ad5..98ced18 100644
+--- a/drivers/usb/gadget/u_phonet.h
++++ b/drivers/usb/gadget/u_phonet.h
+@@ -23,7 +23,6 @@ struct f_phonet_opts {
+ struct net_device *gphonet_setup_default(void);
+ void gphonet_set_gadget(struct net_device *net, struct usb_gadget *g);
+ int gphonet_register_netdev(struct net_device *net);
+-struct net_device *gphonet_setup(struct usb_gadget *gadget);
+ int phonet_bind_config(struct usb_configuration *c, struct net_device *dev);
+ void gphonet_cleanup(struct net_device *dev);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0625-usb-gadget-nokia-convert-to-new-interface-of-f_ecm.patch b/patches.tizen/0625-usb-gadget-nokia-convert-to-new-interface-of-f_ecm.patch
new file mode 100644 (file)
index 0000000..d0fd8c7
--- /dev/null
@@ -0,0 +1,232 @@
+From 34236d6724396790ab6d52c403126d8e95709405 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 23 May 2013 10:51:14 +0200
+Subject: [PATCH 0625/1302] usb: gadget: nokia: convert to new interface of
+ f_ecm
+
+this will let us deprecate (and remove) the old interface.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig |  1 +
+ drivers/usb/gadget/nokia.c | 66 ++++++++++++++++++++++++----------------------
+ 2 files changed, 36 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 2b75585..52e117f 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -870,6 +870,7 @@ config USB_G_NOKIA
+       select USB_F_ACM
+       select USB_F_OBEX
+       select USB_F_PHONET
++      select USB_F_ECM
+       help
+         The Nokia composite gadget provides support for acm, obex
+         and phonet in only one composite gadget driver.
+diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c
+index 084f947..0a8099a 100644
+--- a/drivers/usb/gadget/nokia.c
++++ b/drivers/usb/gadget/nokia.c
+@@ -22,6 +22,7 @@
+ #include "u_serial.h"
+ #include "u_ether.h"
+ #include "u_phonet.h"
++#include "u_ecm.h"
+ #include "gadget_chips.h"
+ /* Defines */
+@@ -29,20 +30,6 @@
+ #define NOKIA_VERSION_NUM             0x0211
+ #define NOKIA_LONG_NAME                       "N900 (PC-Suite Mode)"
+-/*-------------------------------------------------------------------------*/
+-
+-/*
+- * Kbuild is not very cooperative with respect to linking separately
+- * compiled library objects into one module.  So for now we won't use
+- * separate compilation ... ensuring init/exit sections work to shrink
+- * the runtime footprint, and giving us at least some parts of what
+- * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+- */
+-#define USBF_ECM_INCLUDED
+-#include "f_ecm.c"
+-#include "u_ether.h"
+-
+-/*-------------------------------------------------------------------------*/
+ USB_GADGET_COMPOSITE_OPTIONS();
+ USB_ETHERNET_MODULE_PARAMETERS();
+@@ -99,14 +86,14 @@ MODULE_LICENSE("GPL");
+ /*-------------------------------------------------------------------------*/
+ static struct usb_function *f_acm_cfg1;
+ static struct usb_function *f_acm_cfg2;
+-static u8 host_mac[ETH_ALEN];
++static struct usb_function *f_ecm_cfg1;
++static struct usb_function *f_ecm_cfg2;
+ static struct usb_function *f_obex1_cfg1;
+ static struct usb_function *f_obex2_cfg1;
+ static struct usb_function *f_obex1_cfg2;
+ static struct usb_function *f_obex2_cfg2;
+ static struct usb_function *f_phonet_cfg1;
+ static struct usb_function *f_phonet_cfg2;
+-static struct eth_dev *the_dev;
+ static struct usb_configuration nokia_config_500ma_driver = {
+@@ -126,6 +113,7 @@ static struct usb_configuration nokia_config_100ma_driver = {
+ };
+ static struct usb_function_instance *fi_acm;
++static struct usb_function_instance *fi_ecm;
+ static struct usb_function_instance *fi_obex1;
+ static struct usb_function_instance *fi_obex2;
+ static struct usb_function_instance *fi_phonet;
+@@ -135,6 +123,7 @@ static int __init nokia_bind_config(struct usb_configuration *c)
+       struct usb_function *f_acm;
+       struct usb_function *f_phonet = NULL;
+       struct usb_function *f_obex1 = NULL;
++      struct usb_function *f_ecm;
+       struct usb_function *f_obex2 = NULL;
+       int status = 0;
+       int obex1_stat = 0;
+@@ -165,6 +154,12 @@ static int __init nokia_bind_config(struct usb_configuration *c)
+               goto err_get_acm;
+       }
++      f_ecm = usb_get_function(fi_ecm);
++      if (IS_ERR(f_ecm)) {
++              status = PTR_ERR(f_ecm);
++              goto err_get_ecm;
++      }
++
+       if (!IS_ERR_OR_NULL(f_phonet)) {
+               phonet_stat = usb_add_function(c, f_phonet);
+               if (phonet_stat)
+@@ -187,18 +182,20 @@ static int __init nokia_bind_config(struct usb_configuration *c)
+       if (status)
+               goto err_conf;
+-      status = ecm_bind_config(c, host_mac, the_dev);
++      status = usb_add_function(c, f_ecm);
+       if (status) {
+               pr_debug("could not bind ecm config %d\n", status);
+               goto err_ecm;
+       }
+       if (c == &nokia_config_500ma_driver) {
+               f_acm_cfg1 = f_acm;
++              f_ecm_cfg1 = f_ecm;
+               f_phonet_cfg1 = f_phonet;
+               f_obex1_cfg1 = f_obex1;
+               f_obex2_cfg1 = f_obex2;
+       } else {
+               f_acm_cfg2 = f_acm;
++              f_ecm_cfg2 = f_ecm;
+               f_phonet_cfg2 = f_phonet;
+               f_obex1_cfg2 = f_obex1;
+               f_obex2_cfg2 = f_obex2;
+@@ -214,6 +211,8 @@ err_conf:
+               usb_remove_function(c, f_obex1);
+       if (!phonet_stat)
+               usb_remove_function(c, f_phonet);
++      usb_put_function(f_ecm);
++err_get_ecm:
+       usb_put_function(f_acm);
+ err_get_acm:
+       if (!IS_ERR_OR_NULL(f_obex2))
+@@ -230,13 +229,6 @@ static int __init nokia_bind(struct usb_composite_dev *cdev)
+       struct usb_gadget       *gadget = cdev->gadget;
+       int                     status;
+-      the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, host_mac,
+-                             qmult);
+-      if (IS_ERR(the_dev)) {
+-              status = PTR_ERR(the_dev);
+-              goto err_ether;
+-      }
+-
+       status = usb_string_ids_tab(cdev, strings_dev);
+       if (status < 0)
+               goto err_usb;
+@@ -246,8 +238,10 @@ static int __init nokia_bind(struct usb_composite_dev *cdev)
+       nokia_config_500ma_driver.iConfiguration = status;
+       nokia_config_100ma_driver.iConfiguration = status;
+-      if (!gadget_supports_altsettings(gadget))
++      if (!gadget_supports_altsettings(gadget)) {
++              status = -ENODEV;
+               goto err_usb;
++      }
+       fi_phonet = usb_get_function_instance("phonet");
+       if (IS_ERR(fi_phonet))
+@@ -262,14 +256,22 @@ static int __init nokia_bind(struct usb_composite_dev *cdev)
+               pr_debug("could not find obex function 2\n");
+       fi_acm = usb_get_function_instance("acm");
+-      if (IS_ERR(fi_acm))
++      if (IS_ERR(fi_acm)) {
++              status = PTR_ERR(fi_acm);
+               goto err_obex2_inst;
++      }
++
++      fi_ecm = usb_get_function_instance("ecm");
++      if (IS_ERR(fi_ecm)) {
++              status = PTR_ERR(fi_ecm);
++              goto err_acm_inst;
++      }
+       /* finally register the configuration */
+       status = usb_add_config(cdev, &nokia_config_500ma_driver,
+                       nokia_bind_config);
+       if (status < 0)
+-              goto err_acm_inst;
++              goto err_ecm_inst;
+       status = usb_add_config(cdev, &nokia_config_100ma_driver,
+                       nokia_bind_config);
+@@ -289,6 +291,9 @@ err_put_cfg1:
+               usb_put_function(f_obex2_cfg1);
+       if (!IS_ERR_OR_NULL(f_phonet_cfg1))
+               usb_put_function(f_phonet_cfg1);
++      usb_put_function(f_ecm_cfg1);
++err_ecm_inst:
++      usb_put_function_instance(fi_ecm);
+ err_acm_inst:
+       usb_put_function_instance(fi_acm);
+ err_obex2_inst:
+@@ -299,8 +304,6 @@ err_obex2_inst:
+       if (!IS_ERR(fi_phonet))
+               usb_put_function_instance(fi_phonet);
+ err_usb:
+-      gether_cleanup(the_dev);
+-err_ether:
+       return status;
+ }
+@@ -320,7 +323,10 @@ static int __exit nokia_unbind(struct usb_composite_dev *cdev)
+               usb_put_function(f_phonet_cfg2);
+       usb_put_function(f_acm_cfg1);
+       usb_put_function(f_acm_cfg2);
++      usb_put_function(f_ecm_cfg1);
++      usb_put_function(f_ecm_cfg2);
++      usb_put_function_instance(fi_ecm);
+       if (!IS_ERR(fi_obex2))
+               usb_put_function_instance(fi_obex2);
+       if (!IS_ERR(fi_obex1))
+@@ -329,8 +335,6 @@ static int __exit nokia_unbind(struct usb_composite_dev *cdev)
+               usb_put_function_instance(fi_phonet);
+       usb_put_function_instance(fi_acm);
+-      gether_cleanup(the_dev);
+-
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0626-usb-gadget-f_phonet-add-configfs-support.patch b/patches.tizen/0626-usb-gadget-f_phonet-add-configfs-support.patch
new file mode 100644 (file)
index 0000000..f8b7b5e
--- /dev/null
@@ -0,0 +1,138 @@
+From 6abeb50eceea55dec84e3b2c7ec7a6592df05992 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 23 May 2013 10:51:15 +0200
+Subject: [PATCH 0626/1302] usb: gadget: f_phonet: add configfs support
+
+f_phonet learns about configfs so we can remove
+in-kernel gadget drivers.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../ABI/testing/configfs-usb-gadget-phonet         |  8 ++++
+ drivers/usb/gadget/Kconfig                         | 10 ++++
+ drivers/usb/gadget/f_phonet.c                      | 56 ++++++++++++++++++++++
+ 3 files changed, 74 insertions(+)
+ create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-phonet
+
+diff --git a/Documentation/ABI/testing/configfs-usb-gadget-phonet b/Documentation/ABI/testing/configfs-usb-gadget-phonet
+new file mode 100644
+index 0000000..19b67d3
+--- /dev/null
++++ b/Documentation/ABI/testing/configfs-usb-gadget-phonet
+@@ -0,0 +1,8 @@
++What:         /config/usb-gadget/gadget/functions/phonet.name
++Date:         May 2013
++KenelVersion: 3.11
++Description:
++
++              This item contains just one readonly attribute: ifname.
++              It contains the network interface name assigned during
++              network device registration.
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 52e117f..f0bafa6 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -549,6 +549,16 @@ choice
+ # this first set of drivers all depend on bulk-capable hardware.
++config USB_CONFIGFS_PHONET
++      boolean "Phonet protocol"
++      depends on USB_CONFIGFS
++      depends on NET
++      depends on PHONET
++      select USB_U_ETHER
++      select USB_F_PHONET
++      help
++        The Phonet protocol implementation for USB device.
++
+ config USB_ZERO
+       tristate "Gadget Zero (DEVELOPMENT)"
+       select USB_LIBCOMPOSITE
+diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c
+index 5dd7748..7944fb0 100644
+--- a/drivers/usb/gadget/f_phonet.c
++++ b/drivers/usb/gadget/f_phonet.c
+@@ -26,6 +26,7 @@
+ #include <linux/usb/composite.h>
+ #include "u_phonet.h"
++#include "u_ether.h"
+ #define PN_MEDIA_USB  0x1B
+ #define MAXPACKET     512
+@@ -581,6 +582,58 @@ err:
+       return status;
+ }
++static inline struct f_phonet_opts *to_f_phonet_opts(struct config_item *item)
++{
++      return container_of(to_config_group(item), struct f_phonet_opts,
++                      func_inst.group);
++}
++
++CONFIGFS_ATTR_STRUCT(f_phonet_opts);
++static ssize_t f_phonet_attr_show(struct config_item *item,
++                              struct configfs_attribute *attr,
++                              char *page)
++{
++      struct f_phonet_opts *opts = to_f_phonet_opts(item);
++      struct f_phonet_opts_attribute *f_phonet_opts_attr =
++              container_of(attr, struct f_phonet_opts_attribute, attr);
++      ssize_t ret = 0;
++
++      if (f_phonet_opts_attr->show)
++              ret = f_phonet_opts_attr->show(opts, page);
++      return ret;
++}
++
++static void phonet_attr_release(struct config_item *item)
++{
++      struct f_phonet_opts *opts = to_f_phonet_opts(item);
++
++      usb_put_function_instance(&opts->func_inst);
++}
++
++static struct configfs_item_operations phonet_item_ops = {
++      .release                = phonet_attr_release,
++      .show_attribute         = f_phonet_attr_show,
++};
++
++static ssize_t f_phonet_ifname_show(struct f_phonet_opts *opts, char *page)
++{
++      return gether_get_ifname(opts->net, page, PAGE_SIZE);
++}
++
++static struct f_phonet_opts_attribute f_phonet_ifname =
++      __CONFIGFS_ATTR_RO(ifname, f_phonet_ifname_show);
++
++static struct configfs_attribute *phonet_attrs[] = {
++      &f_phonet_ifname.attr,
++      NULL,
++};
++
++static struct config_item_type phonet_func_type = {
++      .ct_item_ops    = &phonet_item_ops,
++      .ct_attrs       = phonet_attrs,
++      .ct_owner       = THIS_MODULE,
++};
++
+ static void phonet_free_inst(struct usb_function_instance *f)
+ {
+       struct f_phonet_opts *opts;
+@@ -606,6 +659,9 @@ static struct usb_function_instance *phonet_alloc_inst(void)
+       if (IS_ERR(opts->net))
+               return ERR_PTR(PTR_ERR(opts->net));
++      config_group_init_type_name(&opts->func_inst.group, "",
++                      &phonet_func_type);
++
+       return &opts->func_inst;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0627-usb-gadget-u_ether-allow-getting-binary-form-host-ad.patch b/patches.tizen/0627-usb-gadget-u_ether-allow-getting-binary-form-host-ad.patch
new file mode 100644 (file)
index 0000000..b0fc72e
--- /dev/null
@@ -0,0 +1,61 @@
+From be82449c54094f1636380aa70d3e54529e908522 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 28 May 2013 09:15:45 +0200
+Subject: [PATCH 0627/1302] usb: gadget: u_ether: allow getting binary-form
+ host address
+
+helper function to copy MAC address to proper place.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/u_ether.c |  9 +++++++++
+ drivers/usb/gadget/u_ether.h | 10 ++++++++++
+ 2 files changed, 19 insertions(+)
+
+diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
+index 6d3ccdc..2aae0d6 100644
+--- a/drivers/usb/gadget/u_ether.c
++++ b/drivers/usb/gadget/u_ether.c
+@@ -963,6 +963,15 @@ int gether_get_host_addr_cdc(struct net_device *net, char *host_addr, int len)
+ }
+ EXPORT_SYMBOL(gether_get_host_addr_cdc);
++void gether_get_host_addr_u8(struct net_device *net, u8 host_mac[ETH_ALEN])
++{
++      struct eth_dev *dev;
++
++      dev = netdev_priv(net);
++      memcpy(host_mac, dev->host_mac, ETH_ALEN);
++}
++EXPORT_SYMBOL(gether_get_host_addr_u8);
++
+ void gether_set_qmult(struct net_device *net, unsigned qmult)
+ {
+       struct eth_dev *dev;
+diff --git a/drivers/usb/gadget/u_ether.h b/drivers/usb/gadget/u_ether.h
+index 1671a79..5efa657 100644
+--- a/drivers/usb/gadget/u_ether.h
++++ b/drivers/usb/gadget/u_ether.h
+@@ -210,6 +210,16 @@ int gether_get_host_addr(struct net_device *net, char *host_addr, int len);
+ int gether_get_host_addr_cdc(struct net_device *net, char *host_addr, int len);
+ /**
++ * gether_get_host_addr_u8 - get an ethernet-over-usb link host address
++ * @net: device representing this link
++ * @host_mac: place to store the eth address of the host
++ *
++ * This gets the binary formatted host-side Ethernet address of this
++ * ethernet-over-usb link.
++ */
++void gether_get_host_addr_u8(struct net_device *net, u8 host_mac[ETH_ALEN]);
++
++/**
+  * gether_set_qmult - initialize an ethernet-over-usb link with a multiplier
+  * @net: device representing this link
+  * @qmult: queue multiplier
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0628-usb-gadget-ether-convert-to-new-interface-of-f_ecm.patch b/patches.tizen/0628-usb-gadget-ether-convert-to-new-interface-of-f_ecm.patch
new file mode 100644 (file)
index 0000000..10b1c2d
--- /dev/null
@@ -0,0 +1,174 @@
+From a9bfa24ad2f0b14ac09e439684d012b898e95f3e Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 28 May 2013 09:15:46 +0200
+Subject: [PATCH 0628/1302] usb: gadget: ether: convert to new interface of
+ f_ecm
+
+moving to new interface so we can remove the older one.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig |  1 +
+ drivers/usb/gadget/ether.c | 73 +++++++++++++++++++++++++++++++++++++---------
+ 2 files changed, 61 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index f0bafa6..f9d76b2 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -630,6 +630,7 @@ config USB_ETH
+       select USB_LIBCOMPOSITE
+       select USB_U_ETHER
+       select USB_U_RNDIS
++      select USB_F_ECM
+       select CRC32
+       help
+         This driver implements Ethernet style communication, in one of
+diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
+index 862ef65..f4d46d7 100644
+--- a/drivers/usb/gadget/ether.c
++++ b/drivers/usb/gadget/ether.c
+@@ -102,8 +102,7 @@ static inline bool has_rndis(void)
+  * the runtime footprint, and giving us at least some parts of what
+  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+  */
+-#define USBF_ECM_INCLUDED
+-#include "f_ecm.c"
++#include "u_ecm.h"
+ #include "f_subset.c"
+ #ifdef        USB_ETH_RNDIS
+ #include "f_rndis.c"
+@@ -212,6 +211,10 @@ static struct usb_gadget_strings *dev_strings[] = {
+ static u8 host_mac[ETH_ALEN];
+ static struct eth_dev *the_dev;
++
++static struct usb_function_instance *fi_ecm;
++static struct usb_function *f_ecm;
++
+ /*-------------------------------------------------------------------------*/
+ /*
+@@ -253,6 +256,8 @@ MODULE_PARM_DESC(use_eem, "use CDC EEM mode");
+  */
+ static int __init eth_do_config(struct usb_configuration *c)
+ {
++      int status = 0;
++
+       /* FIXME alloc iConfiguration string, set it in c->strings */
+       if (gadget_is_otg(c->cdev->gadget)) {
+@@ -262,10 +267,19 @@ static int __init eth_do_config(struct usb_configuration *c)
+       if (use_eem)
+               return eem_bind_config(c, the_dev);
+-      else if (can_support_ecm(c->cdev->gadget))
+-              return ecm_bind_config(c, host_mac, the_dev);
+-      else
++      else if (can_support_ecm(c->cdev->gadget)) {
++              f_ecm = usb_get_function(fi_ecm);
++              if (IS_ERR(f_ecm))
++                      return PTR_ERR(f_ecm);
++
++              status = usb_add_function(c, f_ecm);
++              if (status < 0)
++                      usb_put_function(f_ecm);
++
++              return status;
++      } else
+               return geth_bind_config(c, host_mac, the_dev);
++
+ }
+ static struct usb_configuration eth_config_driver = {
+@@ -280,13 +294,16 @@ static struct usb_configuration eth_config_driver = {
+ static int __init eth_bind(struct usb_composite_dev *cdev)
+ {
+       struct usb_gadget       *gadget = cdev->gadget;
++      struct f_ecm_opts       *ecm_opts = NULL;
+       int                     status;
+-      /* set up network link layer */
+-      the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, host_mac,
+-                             qmult);
+-      if (IS_ERR(the_dev))
+-              return PTR_ERR(the_dev);
++      if (use_eem || !can_support_ecm(gadget)) {
++              /* set up network link layer */
++              the_dev = gether_setup(cdev->gadget, dev_addr, host_addr,
++                              host_mac, qmult);
++              if (IS_ERR(the_dev))
++                      return PTR_ERR(the_dev);
++      }
+       /* set up main config label and device descriptor */
+       if (use_eem) {
+@@ -294,8 +311,23 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
+               eth_config_driver.label = "CDC Ethernet (EEM)";
+               device_desc.idVendor = cpu_to_le16(EEM_VENDOR_NUM);
+               device_desc.idProduct = cpu_to_le16(EEM_PRODUCT_NUM);
+-      } else if (can_support_ecm(cdev->gadget)) {
++      } else if (can_support_ecm(gadget)) {
+               /* ECM */
++
++              fi_ecm = usb_get_function_instance("ecm");
++              if (IS_ERR(fi_ecm))
++                      return PTR_ERR(fi_ecm);
++
++              ecm_opts = container_of(fi_ecm, struct f_ecm_opts, func_inst);
++
++              gether_set_qmult(ecm_opts->net, qmult);
++              if (!gether_set_host_addr(ecm_opts->net, host_addr))
++                      pr_info("using host ethernet address: %s", host_addr);
++              if (!gether_set_dev_addr(ecm_opts->net, dev_addr))
++                      pr_info("using self ethernet address: %s", dev_addr);
++
++              the_dev = netdev_priv(ecm_opts->net);
++
+               eth_config_driver.label = "CDC Ethernet (ECM)";
+       } else {
+               /* CDC Subset */
+@@ -309,6 +341,15 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
+       if (has_rndis()) {
+               /* RNDIS plus ECM-or-Subset */
++              if (!use_eem && can_support_ecm(gadget)) {
++                      gether_set_gadget(ecm_opts->net, cdev->gadget);
++                      status = gether_register_netdev(ecm_opts->net);
++                      if (status)
++                              goto fail;
++                      ecm_opts->bound = true;
++                      gether_get_host_addr_u8(ecm_opts->net, host_mac);
++              }
++
+               device_desc.idVendor = cpu_to_le16(RNDIS_VENDOR_NUM);
+               device_desc.idProduct = cpu_to_le16(RNDIS_PRODUCT_NUM);
+               device_desc.bNumConfigurations = 2;
+@@ -343,13 +384,19 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
+       return 0;
+ fail:
+-      gether_cleanup(the_dev);
++      if (use_eem || !can_support_ecm(gadget))
++              gether_cleanup(the_dev);
++      else
++              usb_put_function_instance(fi_ecm);
+       return status;
+ }
+ static int __exit eth_unbind(struct usb_composite_dev *cdev)
+ {
+-      gether_cleanup(the_dev);
++      if (use_eem || !can_support_ecm(cdev->gadget))
++              gether_cleanup(the_dev);
++      else
++              usb_put_function_instance(fi_ecm);
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0629-usb-gadget-f_eem-convert-to-new-function-interface-w.patch b/patches.tizen/0629-usb-gadget-f_eem-convert-to-new-function-interface-w.patch
new file mode 100644 (file)
index 0000000..889f50a
--- /dev/null
@@ -0,0 +1,419 @@
+From 4f45804e9f69a2bb2decbd140a3627e73bfe7b30 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 28 May 2013 09:15:47 +0200
+Subject: [PATCH 0629/1302] usb: gadget: f_eem: convert to new function
+ interface with backward compatibility
+
+Converting eem to the new function interface requires converting
+the USB eem's function code and its users.
+
+This patch converts the f_eem.c to the new function interface.
+
+The file is now compiled into a separate usb_f_eem.ko module.
+
+The old function interface is provided by means of a preprocessor
+conditional directives. After all users are converted, the old interface
+can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig  |   3 +
+ drivers/usb/gadget/Makefile |   2 +
+ drivers/usb/gadget/ether.c  |   2 +
+ drivers/usb/gadget/f_eem.c  | 174 +++++++++++++++++++++++++++++++++++---------
+ drivers/usb/gadget/u_eem.h  |  27 +++++++
+ 5 files changed, 172 insertions(+), 36 deletions(-)
+ create mode 100644 drivers/usb/gadget/u_eem.h
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index f9d76b2..0d47e41 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -528,6 +528,9 @@ config USB_F_ECM
+ config USB_F_PHONET
+       tristate
++config USB_F_EEM
++      tristate
++
+ choice
+       tristate "USB Gadget Drivers"
+       default USB_ETH
+diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
+index db8ce05..7069f53 100644
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -54,6 +54,8 @@ usb_f_ecm-y                  := f_ecm.o
+ obj-$(CONFIG_USB_F_ECM)               += usb_f_ecm.o
+ usb_f_phonet-y                        := f_phonet.o
+ obj-$(CONFIG_USB_F_PHONET)    += usb_f_phonet.o
++usb_f_eem-y                   := f_eem.o
++obj-$(CONFIG_USB_F_EEM)               += usb_f_eem.o
+ #
+ # USB gadget drivers
+diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
+index f4d46d7..397609d 100644
+--- a/drivers/usb/gadget/ether.c
++++ b/drivers/usb/gadget/ether.c
+@@ -108,6 +108,8 @@ static inline bool has_rndis(void)
+ #include "f_rndis.c"
+ #include "rndis.h"
+ #endif
++
++#define USB_FEEM_INCLUDED
+ #include "f_eem.c"
+ /*-------------------------------------------------------------------------*/
+diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c
+index f4e0bbe..471acc8 100644
+--- a/drivers/usb/gadget/f_eem.c
++++ b/drivers/usb/gadget/f_eem.c
+@@ -12,12 +12,14 @@
+  */
+ #include <linux/kernel.h>
++#include <linux/module.h>
+ #include <linux/device.h>
+ #include <linux/etherdevice.h>
+ #include <linux/crc32.h>
+ #include <linux/slab.h>
+ #include "u_ether.h"
++#include "u_eem.h"
+ #define EEM_HLEN 2
+@@ -40,7 +42,7 @@ static inline struct f_eem *func_to_eem(struct usb_function *f)
+ /* interface descriptor: */
+-static struct usb_interface_descriptor eem_intf __initdata = {
++static struct usb_interface_descriptor eem_intf = {
+       .bLength =              sizeof eem_intf,
+       .bDescriptorType =      USB_DT_INTERFACE,
+@@ -54,7 +56,7 @@ static struct usb_interface_descriptor eem_intf __initdata = {
+ /* full speed support: */
+-static struct usb_endpoint_descriptor eem_fs_in_desc __initdata = {
++static struct usb_endpoint_descriptor eem_fs_in_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -62,7 +64,7 @@ static struct usb_endpoint_descriptor eem_fs_in_desc __initdata = {
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+ };
+-static struct usb_endpoint_descriptor eem_fs_out_desc __initdata = {
++static struct usb_endpoint_descriptor eem_fs_out_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -70,7 +72,7 @@ static struct usb_endpoint_descriptor eem_fs_out_desc __initdata = {
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+ };
+-static struct usb_descriptor_header *eem_fs_function[] __initdata = {
++static struct usb_descriptor_header *eem_fs_function[] = {
+       /* CDC EEM control descriptors */
+       (struct usb_descriptor_header *) &eem_intf,
+       (struct usb_descriptor_header *) &eem_fs_in_desc,
+@@ -80,7 +82,7 @@ static struct usb_descriptor_header *eem_fs_function[] __initdata = {
+ /* high speed support: */
+-static struct usb_endpoint_descriptor eem_hs_in_desc __initdata = {
++static struct usb_endpoint_descriptor eem_hs_in_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -89,7 +91,7 @@ static struct usb_endpoint_descriptor eem_hs_in_desc __initdata = {
+       .wMaxPacketSize =       cpu_to_le16(512),
+ };
+-static struct usb_endpoint_descriptor eem_hs_out_desc __initdata = {
++static struct usb_endpoint_descriptor eem_hs_out_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -98,7 +100,7 @@ static struct usb_endpoint_descriptor eem_hs_out_desc __initdata = {
+       .wMaxPacketSize =       cpu_to_le16(512),
+ };
+-static struct usb_descriptor_header *eem_hs_function[] __initdata = {
++static struct usb_descriptor_header *eem_hs_function[] = {
+       /* CDC EEM control descriptors */
+       (struct usb_descriptor_header *) &eem_intf,
+       (struct usb_descriptor_header *) &eem_hs_in_desc,
+@@ -108,7 +110,7 @@ static struct usb_descriptor_header *eem_hs_function[] __initdata = {
+ /* super speed support: */
+-static struct usb_endpoint_descriptor eem_ss_in_desc __initdata = {
++static struct usb_endpoint_descriptor eem_ss_in_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -117,7 +119,7 @@ static struct usb_endpoint_descriptor eem_ss_in_desc __initdata = {
+       .wMaxPacketSize =       cpu_to_le16(1024),
+ };
+-static struct usb_endpoint_descriptor eem_ss_out_desc __initdata = {
++static struct usb_endpoint_descriptor eem_ss_out_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -126,7 +128,7 @@ static struct usb_endpoint_descriptor eem_ss_out_desc __initdata = {
+       .wMaxPacketSize =       cpu_to_le16(1024),
+ };
+-static struct usb_ss_ep_comp_descriptor eem_ss_bulk_comp_desc __initdata = {
++static struct usb_ss_ep_comp_descriptor eem_ss_bulk_comp_desc = {
+       .bLength =              sizeof eem_ss_bulk_comp_desc,
+       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
+@@ -135,7 +137,7 @@ static struct usb_ss_ep_comp_descriptor eem_ss_bulk_comp_desc __initdata = {
+       /* .bmAttributes =      0, */
+ };
+-static struct usb_descriptor_header *eem_ss_function[] __initdata = {
++static struct usb_descriptor_header *eem_ss_function[] = {
+       /* CDC EEM control descriptors */
+       (struct usb_descriptor_header *) &eem_intf,
+       (struct usb_descriptor_header *) &eem_ss_in_desc,
+@@ -242,14 +244,44 @@ static void eem_disable(struct usb_function *f)
+ /* EEM function driver setup/binding */
+-static int __init
+-eem_bind(struct usb_configuration *c, struct usb_function *f)
++static int eem_bind(struct usb_configuration *c, struct usb_function *f)
+ {
+       struct usb_composite_dev *cdev = c->cdev;
+       struct f_eem            *eem = func_to_eem(f);
+       int                     status;
+       struct usb_ep           *ep;
++#ifndef USB_FEEM_INCLUDED
++      struct f_eem_opts       *eem_opts;
++
++      eem_opts = container_of(f->fi, struct f_eem_opts, func_inst);
++      /*
++       * in drivers/usb/gadget/configfs.c:configfs_composite_bind()
++       * configurations are bound in sequence with list_for_each_entry,
++       * in each configuration its functions are bound in sequence
++       * with list_for_each_entry, so we assume no race condition
++       * with regard to eem_opts->bound access
++       */
++      if (!eem_opts->bound) {
++              gether_set_gadget(eem_opts->net, cdev->gadget);
++              status = gether_register_netdev(eem_opts->net);
++              if (status)
++                      return status;
++              eem_opts->bound = true;
++      }
++#endif
++
++      /* maybe allocate device-global string IDs */
++      if (eem_string_defs[0].id == 0) {
++
++              /* control interface label */
++              status = usb_string_id(c->cdev);
++              if (status < 0)
++                      return status;
++              eem_string_defs[0].id = status;
++              eem_intf.iInterface = status;
++      }
++
+       /* allocate instance-specific interface IDs */
+       status = usb_interface_id(c, f);
+       if (status < 0)
+@@ -307,17 +339,6 @@ fail:
+       return status;
+ }
+-static void
+-eem_unbind(struct usb_configuration *c, struct usb_function *f)
+-{
+-      struct f_eem    *eem = func_to_eem(f);
+-
+-      DBG(c->cdev, "eem unbind\n");
+-
+-      usb_free_all_descriptors(f);
+-      kfree(eem);
+-}
+-
+ static void eem_cmd_complete(struct usb_ep *ep, struct usb_request *req)
+ {
+       struct sk_buff *skb = (struct sk_buff *)req->context;
+@@ -518,6 +539,18 @@ error:
+       return status;
+ }
++#ifdef USB_FEEM_INCLUDED
++
++static void eem_old_unbind(struct usb_configuration *c, struct usb_function *f)
++{
++      struct f_eem    *eem = func_to_eem(f);
++
++      DBG(c->cdev, "eem unbind\n");
++
++      usb_free_all_descriptors(f);
++      kfree(eem);
++}
++
+ /**
+  * eem_bind_config - add CDC Ethernet (EEM) network link to a configuration
+  * @c: the configuration to support the network link
+@@ -533,17 +566,6 @@ int __init eem_bind_config(struct usb_configuration *c, struct eth_dev *dev)
+       struct f_eem    *eem;
+       int             status;
+-      /* maybe allocate device-global string IDs */
+-      if (eem_string_defs[0].id == 0) {
+-
+-              /* control interface label */
+-              status = usb_string_id(c->cdev);
+-              if (status < 0)
+-                      return status;
+-              eem_string_defs[0].id = status;
+-              eem_intf.iInterface = status;
+-      }
+-
+       /* allocate and initialize one new instance */
+       eem = kzalloc(sizeof *eem, GFP_KERNEL);
+       if (!eem)
+@@ -556,7 +578,7 @@ int __init eem_bind_config(struct usb_configuration *c, struct eth_dev *dev)
+       eem->port.func.strings = eem_strings;
+       /* descriptors are per-instance copies */
+       eem->port.func.bind = eem_bind;
+-      eem->port.func.unbind = eem_unbind;
++      eem->port.func.unbind = eem_old_unbind;
+       eem->port.func.set_alt = eem_set_alt;
+       eem->port.func.setup = eem_setup;
+       eem->port.func.disable = eem_disable;
+@@ -570,3 +592,83 @@ int __init eem_bind_config(struct usb_configuration *c, struct eth_dev *dev)
+       return status;
+ }
++#else
++
++static void eem_free_inst(struct usb_function_instance *f)
++{
++      struct f_eem_opts *opts;
++
++      opts = container_of(f, struct f_eem_opts, func_inst);
++      if (opts->bound)
++              gether_cleanup(netdev_priv(opts->net));
++      else
++              free_netdev(opts->net);
++      kfree(opts);
++}
++
++static struct usb_function_instance *eem_alloc_inst(void)
++{
++      struct f_eem_opts *opts;
++
++      opts = kzalloc(sizeof(*opts), GFP_KERNEL);
++      if (!opts)
++              return ERR_PTR(-ENOMEM);
++      opts->func_inst.free_func_inst = eem_free_inst;
++      opts->net = gether_setup_default();
++      if (IS_ERR(opts->net))
++              return ERR_CAST(opts->net);
++
++      return &opts->func_inst;
++}
++
++static void eem_free(struct usb_function *f)
++{
++      struct f_eem *eem;
++
++      eem = func_to_eem(f);
++      kfree(eem);
++}
++
++static void eem_unbind(struct usb_configuration *c, struct usb_function *f)
++{
++      DBG(c->cdev, "eem unbind\n");
++
++      usb_free_all_descriptors(f);
++}
++
++struct usb_function *eem_alloc(struct usb_function_instance *fi)
++{
++      struct f_eem    *eem;
++      struct f_eem_opts *opts;
++
++      /* allocate and initialize one new instance */
++      eem = kzalloc(sizeof(*eem), GFP_KERNEL);
++      if (!eem)
++              return ERR_PTR(-ENOMEM);
++
++      opts = container_of(fi, struct f_eem_opts, func_inst);
++
++      eem->port.ioport = netdev_priv(opts->net);
++      eem->port.cdc_filter = DEFAULT_FILTER;
++
++      eem->port.func.name = "cdc_eem";
++      eem->port.func.strings = eem_strings;
++      /* descriptors are per-instance copies */
++      eem->port.func.bind = eem_bind;
++      eem->port.func.unbind = eem_unbind;
++      eem->port.func.set_alt = eem_set_alt;
++      eem->port.func.setup = eem_setup;
++      eem->port.func.disable = eem_disable;
++      eem->port.func.free_func = eem_free;
++      eem->port.wrap = eem_wrap;
++      eem->port.unwrap = eem_unwrap;
++      eem->port.header_len = EEM_HLEN;
++
++      return &eem->port.func;
++}
++
++DECLARE_USB_FUNCTION_INIT(eem, eem_alloc_inst, eem_alloc);
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("David Brownell");
++
++#endif
+diff --git a/drivers/usb/gadget/u_eem.h b/drivers/usb/gadget/u_eem.h
+new file mode 100644
+index 0000000..8f432f2
+--- /dev/null
++++ b/drivers/usb/gadget/u_eem.h
+@@ -0,0 +1,27 @@
++/*
++ * u_eem.h
++ *
++ * Utility definitions for the eem function
++ *
++ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
++ *            http://www.samsung.com
++ *
++ * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.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 U_EEM_H
++#define U_EEM_H
++
++#include <linux/usb/composite.h>
++
++struct f_eem_opts {
++      struct usb_function_instance    func_inst;
++      struct net_device               *net;
++      bool                            bound;
++};
++
++#endif /* U_EEM_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0630-usb-gadget-ether-convert-to-new-interface-of-f_eem.patch b/patches.tizen/0630-usb-gadget-ether-convert-to-new-interface-of-f_eem.patch
new file mode 100644 (file)
index 0000000..c1d0614
--- /dev/null
@@ -0,0 +1,151 @@
+From 2c6934d37895019c87988cf9abae1bce28bc6108 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 28 May 2013 09:15:48 +0200
+Subject: [PATCH 0630/1302] usb: gadget: ether: convert to new interface of
+ f_eem
+
+use new interface so old one can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig |  1 +
+ drivers/usb/gadget/ether.c | 54 ++++++++++++++++++++++++++++++++++++++--------
+ 2 files changed, 46 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 0d47e41..ce1abb5 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -689,6 +689,7 @@ config USB_ETH_EEM
+        bool "Ethernet Emulation Model (EEM) support"
+        depends on USB_ETH
+       select USB_LIBCOMPOSITE
++      select USB_F_EEM
+        default n
+        help
+          CDC EEM is a newer USB standard that is somewhat simpler than CDC ECM
+diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
+index 397609d..2078e6c 100644
+--- a/drivers/usb/gadget/ether.c
++++ b/drivers/usb/gadget/ether.c
+@@ -109,8 +109,7 @@ static inline bool has_rndis(void)
+ #include "rndis.h"
+ #endif
+-#define USB_FEEM_INCLUDED
+-#include "f_eem.c"
++#include "u_eem.h"
+ /*-------------------------------------------------------------------------*/
+ USB_GADGET_COMPOSITE_OPTIONS();
+@@ -217,6 +216,9 @@ static struct eth_dev *the_dev;
+ static struct usb_function_instance *fi_ecm;
+ static struct usb_function *f_ecm;
++static struct usb_function_instance *fi_eem;
++static struct usb_function *f_eem;
++
+ /*-------------------------------------------------------------------------*/
+ /*
+@@ -267,9 +269,17 @@ static int __init eth_do_config(struct usb_configuration *c)
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+-      if (use_eem)
+-              return eem_bind_config(c, the_dev);
+-      else if (can_support_ecm(c->cdev->gadget)) {
++      if (use_eem) {
++              f_eem = usb_get_function(fi_eem);
++              if (IS_ERR(f_eem))
++                      return PTR_ERR(f_eem);
++
++              status = usb_add_function(c, f_eem);
++              if (status < 0)
++                      usb_put_function(f_eem);
++
++              return status;
++      } else if (can_support_ecm(c->cdev->gadget)) {
+               f_ecm = usb_get_function(fi_ecm);
+               if (IS_ERR(f_ecm))
+                       return PTR_ERR(f_ecm);
+@@ -296,10 +306,11 @@ static struct usb_configuration eth_config_driver = {
+ static int __init eth_bind(struct usb_composite_dev *cdev)
+ {
+       struct usb_gadget       *gadget = cdev->gadget;
++      struct f_eem_opts       *eem_opts = NULL;
+       struct f_ecm_opts       *ecm_opts = NULL;
+       int                     status;
+-      if (use_eem || !can_support_ecm(gadget)) {
++      if (!use_eem && !can_support_ecm(gadget)) {
+               /* set up network link layer */
+               the_dev = gether_setup(cdev->gadget, dev_addr, host_addr,
+                               host_mac, qmult);
+@@ -310,6 +321,20 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
+       /* set up main config label and device descriptor */
+       if (use_eem) {
+               /* EEM */
++              fi_eem = usb_get_function_instance("eem");
++              if (IS_ERR(fi_eem))
++                      return PTR_ERR(fi_eem);
++
++              eem_opts = container_of(fi_eem, struct f_eem_opts, func_inst);
++
++              gether_set_qmult(eem_opts->net, qmult);
++              if (!gether_set_host_addr(eem_opts->net, host_addr))
++                      pr_info("using host ethernet address: %s", host_addr);
++              if (!gether_set_dev_addr(eem_opts->net, dev_addr))
++                      pr_info("using self ethernet address: %s", dev_addr);
++
++              the_dev = netdev_priv(eem_opts->net);
++
+               eth_config_driver.label = "CDC Ethernet (EEM)";
+               device_desc.idVendor = cpu_to_le16(EEM_VENDOR_NUM);
+               device_desc.idProduct = cpu_to_le16(EEM_PRODUCT_NUM);
+@@ -343,7 +368,14 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
+       if (has_rndis()) {
+               /* RNDIS plus ECM-or-Subset */
+-              if (!use_eem && can_support_ecm(gadget)) {
++              if (use_eem) {
++                      gether_set_gadget(eem_opts->net, cdev->gadget);
++                      status = gether_register_netdev(eem_opts->net);
++                      if (status)
++                              goto fail;
++                      eem_opts->bound = true;
++                      gether_get_host_addr_u8(eem_opts->net, host_mac);
++              } else if (can_support_ecm(gadget)) {
+                       gether_set_gadget(ecm_opts->net, cdev->gadget);
+                       status = gether_register_netdev(ecm_opts->net);
+                       if (status)
+@@ -386,8 +418,10 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
+       return 0;
+ fail:
+-      if (use_eem || !can_support_ecm(gadget))
++      if (!use_eem && !can_support_ecm(gadget))
+               gether_cleanup(the_dev);
++      else if (use_eem)
++              usb_put_function_instance(fi_eem);
+       else
+               usb_put_function_instance(fi_ecm);
+       return status;
+@@ -395,8 +429,10 @@ fail:
+ static int __exit eth_unbind(struct usb_composite_dev *cdev)
+ {
+-      if (use_eem || !can_support_ecm(cdev->gadget))
++      if (!use_eem && !can_support_ecm(cdev->gadget))
+               gether_cleanup(the_dev);
++      else if (use_eem)
++              usb_put_function_instance(fi_eem);
+       else
+               usb_put_function_instance(fi_ecm);
+       return 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0631-usb-gadget-f_eem-remove-compatibility-layer.patch b/patches.tizen/0631-usb-gadget-f_eem-remove-compatibility-layer.patch
new file mode 100644 (file)
index 0000000..c1bebb9
--- /dev/null
@@ -0,0 +1,120 @@
+From 6108cea5fff37d2a07fe2c2d6b1b2824f726850d Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 28 May 2013 09:15:49 +0200
+Subject: [PATCH 0631/1302] usb: gadget: f_eem: remove compatibility layer
+
+There are no old function interface users left, so the old interface
+can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_eem.c   | 59 --------------------------------------------
+ drivers/usb/gadget/u_ether.h |  1 -
+ 2 files changed, 60 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c
+index 471acc8..9d54d68 100644
+--- a/drivers/usb/gadget/f_eem.c
++++ b/drivers/usb/gadget/f_eem.c
+@@ -251,7 +251,6 @@ static int eem_bind(struct usb_configuration *c, struct usb_function *f)
+       int                     status;
+       struct usb_ep           *ep;
+-#ifndef USB_FEEM_INCLUDED
+       struct f_eem_opts       *eem_opts;
+       eem_opts = container_of(f->fi, struct f_eem_opts, func_inst);
+@@ -269,7 +268,6 @@ static int eem_bind(struct usb_configuration *c, struct usb_function *f)
+                       return status;
+               eem_opts->bound = true;
+       }
+-#endif
+       /* maybe allocate device-global string IDs */
+       if (eem_string_defs[0].id == 0) {
+@@ -539,61 +537,6 @@ error:
+       return status;
+ }
+-#ifdef USB_FEEM_INCLUDED
+-
+-static void eem_old_unbind(struct usb_configuration *c, struct usb_function *f)
+-{
+-      struct f_eem    *eem = func_to_eem(f);
+-
+-      DBG(c->cdev, "eem unbind\n");
+-
+-      usb_free_all_descriptors(f);
+-      kfree(eem);
+-}
+-
+-/**
+- * eem_bind_config - add CDC Ethernet (EEM) network link to a configuration
+- * @c: the configuration to support the network link
+- * Context: single threaded during gadget setup
+- *
+- * Returns zero on success, else negative errno.
+- *
+- * Caller must have called @gether_setup().  Caller is also responsible
+- * for calling @gether_cleanup() before module unload.
+- */
+-int __init eem_bind_config(struct usb_configuration *c, struct eth_dev *dev)
+-{
+-      struct f_eem    *eem;
+-      int             status;
+-
+-      /* allocate and initialize one new instance */
+-      eem = kzalloc(sizeof *eem, GFP_KERNEL);
+-      if (!eem)
+-              return -ENOMEM;
+-
+-      eem->port.ioport = dev;
+-      eem->port.cdc_filter = DEFAULT_FILTER;
+-
+-      eem->port.func.name = "cdc_eem";
+-      eem->port.func.strings = eem_strings;
+-      /* descriptors are per-instance copies */
+-      eem->port.func.bind = eem_bind;
+-      eem->port.func.unbind = eem_old_unbind;
+-      eem->port.func.set_alt = eem_set_alt;
+-      eem->port.func.setup = eem_setup;
+-      eem->port.func.disable = eem_disable;
+-      eem->port.wrap = eem_wrap;
+-      eem->port.unwrap = eem_unwrap;
+-      eem->port.header_len = EEM_HLEN;
+-
+-      status = usb_add_function(c, &eem->port.func);
+-      if (status)
+-              kfree(eem);
+-      return status;
+-}
+-
+-#else
+-
+ static void eem_free_inst(struct usb_function_instance *f)
+ {
+       struct f_eem_opts *opts;
+@@ -670,5 +613,3 @@ struct usb_function *eem_alloc(struct usb_function_instance *fi)
+ DECLARE_USB_FUNCTION_INIT(eem, eem_alloc_inst, eem_alloc);
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("David Brownell");
+-
+-#endif
+diff --git a/drivers/usb/gadget/u_ether.h b/drivers/usb/gadget/u_ether.h
+index 5efa657..fb23d1f 100644
+--- a/drivers/usb/gadget/u_ether.h
++++ b/drivers/usb/gadget/u_ether.h
+@@ -272,7 +272,6 @@ int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+               struct eth_dev *dev);
+ int ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+               struct eth_dev *dev);
+-int eem_bind_config(struct usb_configuration *c, struct eth_dev *dev);
+ #ifdef USB_ETH_RNDIS
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0632-usb-gadget-f_eem-use-usb_gstrings_attach.patch b/patches.tizen/0632-usb-gadget-f_eem-use-usb_gstrings_attach.patch
new file mode 100644 (file)
index 0000000..d2bccae
--- /dev/null
@@ -0,0 +1,60 @@
+From 88056ecf32b6d0a615c3971f76ac3e81b02c873b Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 28 May 2013 09:15:50 +0200
+Subject: [PATCH 0632/1302] usb: gadget: f_eem: use usb_gstrings_attach
+
+use the new usb_gstrings_attach interface
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_eem.c | 17 ++++++-----------
+ 1 file changed, 6 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c
+index 9d54d68..31a2cb7 100644
+--- a/drivers/usb/gadget/f_eem.c
++++ b/drivers/usb/gadget/f_eem.c
+@@ -248,6 +248,7 @@ static int eem_bind(struct usb_configuration *c, struct usb_function *f)
+ {
+       struct usb_composite_dev *cdev = c->cdev;
+       struct f_eem            *eem = func_to_eem(f);
++      struct usb_string       *us;
+       int                     status;
+       struct usb_ep           *ep;
+@@ -269,16 +270,11 @@ static int eem_bind(struct usb_configuration *c, struct usb_function *f)
+               eem_opts->bound = true;
+       }
+-      /* maybe allocate device-global string IDs */
+-      if (eem_string_defs[0].id == 0) {
+-
+-              /* control interface label */
+-              status = usb_string_id(c->cdev);
+-              if (status < 0)
+-                      return status;
+-              eem_string_defs[0].id = status;
+-              eem_intf.iInterface = status;
+-      }
++      us = usb_gstrings_attach(cdev, eem_strings,
++                               ARRAY_SIZE(eem_string_defs));
++      if (IS_ERR(us))
++              return PTR_ERR(us);
++      eem_intf.iInterface = us[0].id;
+       /* allocate instance-specific interface IDs */
+       status = usb_interface_id(c, f);
+@@ -595,7 +591,6 @@ struct usb_function *eem_alloc(struct usb_function_instance *fi)
+       eem->port.cdc_filter = DEFAULT_FILTER;
+       eem->port.func.name = "cdc_eem";
+-      eem->port.func.strings = eem_strings;
+       /* descriptors are per-instance copies */
+       eem->port.func.bind = eem_bind;
+       eem->port.func.unbind = eem_unbind;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0633-usb-gadget-f_eem-add-configfs-support.patch b/patches.tizen/0633-usb-gadget-f_eem-add-configfs-support.patch
new file mode 100644 (file)
index 0000000..2bd38a0
--- /dev/null
@@ -0,0 +1,195 @@
+From 4b584efbb9a4ec5dd80006ca46a103ff2fde0804 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 28 May 2013 09:15:51 +0200
+Subject: [PATCH 0633/1302] usb: gadget: f_eem: add configfs support
+
+f_eem learns about our configfs interface so we
+can remove in-kernel gadget drivers in future.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/ABI/testing/configfs-usb-gadget-eem | 14 +++++++
+ drivers/usb/gadget/Kconfig                        | 15 +++++++
+ drivers/usb/gadget/f_eem.c                        | 49 +++++++++++++++++++++++
+ drivers/usb/gadget/u_eem.h                        |  9 +++++
+ 4 files changed, 87 insertions(+)
+ create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-eem
+
+diff --git a/Documentation/ABI/testing/configfs-usb-gadget-eem b/Documentation/ABI/testing/configfs-usb-gadget-eem
+new file mode 100644
+index 0000000..10e87d6
+--- /dev/null
++++ b/Documentation/ABI/testing/configfs-usb-gadget-eem
+@@ -0,0 +1,14 @@
++What:         /config/usb-gadget/gadget/functions/eem.name
++Date:         May 2013
++KenelVersion: 3.11
++Description:
++              The attributes:
++
++              ifname          - network device interface name associated with
++                              this function instance
++              qmult           - queue length multiplier for high and
++                              super speed
++              host_addr       - MAC address of host's end of this
++                              Ethernet over USB link
++              dev_addr        - MAC address of device's end of this
++                              Ethernet over USB link
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index ce1abb5..90e64a9 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -552,6 +552,21 @@ choice
+ # this first set of drivers all depend on bulk-capable hardware.
++config USB_CONFIGFS_EEM
++      bool "Ethernet Emulation Model (EEM)"
++      depends on USB_CONFIGFS
++      depends on NET
++      select USB_U_ETHER
++      select USB_F_EEM
++      help
++        CDC EEM is a newer USB standard that is somewhat simpler than CDC ECM
++        and therefore can be supported by more hardware.  Technically ECM and
++        EEM are designed for different applications.  The ECM model extends
++        the network interface to the target (e.g. a USB cable modem), and the
++        EEM model is for mobile devices to communicate with hosts using
++        ethernet over USB.  For Linux gadgets, however, the interface with
++        the host is the same (a usbX device), so the differences are minimal.
++
+ config USB_CONFIGFS_PHONET
+       boolean "Phonet protocol"
+       depends on USB_CONFIGFS
+diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c
+index 31a2cb7..90ee802 100644
+--- a/drivers/usb/gadget/f_eem.c
++++ b/drivers/usb/gadget/f_eem.c
+@@ -19,6 +19,7 @@
+ #include <linux/slab.h>
+ #include "u_ether.h"
++#include "u_ether_configfs.h"
+ #include "u_eem.h"
+ #define EEM_HLEN 2
+@@ -263,8 +264,10 @@ static int eem_bind(struct usb_configuration *c, struct usb_function *f)
+        * with regard to eem_opts->bound access
+        */
+       if (!eem_opts->bound) {
++              mutex_lock(&eem_opts->lock);
+               gether_set_gadget(eem_opts->net, cdev->gadget);
+               status = gether_register_netdev(eem_opts->net);
++              mutex_unlock(&eem_opts->lock);
+               if (status)
+                       return status;
+               eem_opts->bound = true;
+@@ -533,6 +536,41 @@ error:
+       return status;
+ }
++static inline struct f_eem_opts *to_f_eem_opts(struct config_item *item)
++{
++      return container_of(to_config_group(item), struct f_eem_opts,
++                          func_inst.group);
++}
++
++/* f_eem_item_ops */
++USB_ETHERNET_CONFIGFS_ITEM(eem);
++
++/* f_eem_opts_dev_addr */
++USB_ETHERNET_CONFIGFS_ITEM_ATTR_DEV_ADDR(eem);
++
++/* f_eem_opts_host_addr */
++USB_ETHERNET_CONFIGFS_ITEM_ATTR_HOST_ADDR(eem);
++
++/* f_eem_opts_qmult */
++USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(eem);
++
++/* f_eem_opts_ifname */
++USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(eem);
++
++static struct configfs_attribute *eem_attrs[] = {
++      &f_eem_opts_dev_addr.attr,
++      &f_eem_opts_host_addr.attr,
++      &f_eem_opts_qmult.attr,
++      &f_eem_opts_ifname.attr,
++      NULL,
++};
++
++static struct config_item_type eem_func_type = {
++      .ct_item_ops    = &eem_item_ops,
++      .ct_attrs       = eem_attrs,
++      .ct_owner       = THIS_MODULE,
++};
++
+ static void eem_free_inst(struct usb_function_instance *f)
+ {
+       struct f_eem_opts *opts;
+@@ -552,20 +590,28 @@ static struct usb_function_instance *eem_alloc_inst(void)
+       opts = kzalloc(sizeof(*opts), GFP_KERNEL);
+       if (!opts)
+               return ERR_PTR(-ENOMEM);
++      mutex_init(&opts->lock);
+       opts->func_inst.free_func_inst = eem_free_inst;
+       opts->net = gether_setup_default();
+       if (IS_ERR(opts->net))
+               return ERR_CAST(opts->net);
++      config_group_init_type_name(&opts->func_inst.group, "", &eem_func_type);
++
+       return &opts->func_inst;
+ }
+ static void eem_free(struct usb_function *f)
+ {
+       struct f_eem *eem;
++      struct f_eem_opts *opts;
+       eem = func_to_eem(f);
++      opts = container_of(f->fi, struct f_eem_opts, func_inst);
+       kfree(eem);
++      mutex_lock(&opts->lock);
++      opts->refcnt--;
++      mutex_unlock(&opts->lock);
+ }
+ static void eem_unbind(struct usb_configuration *c, struct usb_function *f)
+@@ -586,8 +632,11 @@ struct usb_function *eem_alloc(struct usb_function_instance *fi)
+               return ERR_PTR(-ENOMEM);
+       opts = container_of(fi, struct f_eem_opts, func_inst);
++      mutex_lock(&opts->lock);
++      opts->refcnt++;
+       eem->port.ioport = netdev_priv(opts->net);
++      mutex_unlock(&opts->lock);
+       eem->port.cdc_filter = DEFAULT_FILTER;
+       eem->port.func.name = "cdc_eem";
+diff --git a/drivers/usb/gadget/u_eem.h b/drivers/usb/gadget/u_eem.h
+index 8f432f2..e3ae978 100644
+--- a/drivers/usb/gadget/u_eem.h
++++ b/drivers/usb/gadget/u_eem.h
+@@ -22,6 +22,15 @@ struct f_eem_opts {
+       struct usb_function_instance    func_inst;
+       struct net_device               *net;
+       bool                            bound;
++
++      /*
++       * Read/write access to configfs attributes is handled by configfs.
++       *
++       * This is to protect the data from concurrent access by read/write
++       * and create symlink/remove symlink.
++       */
++      struct mutex                    lock;
++      int                             refcnt;
+ };
+ #endif /* U_EEM_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0634-usb-gadget-multi-Remove-unused-include.patch b/patches.tizen/0634-usb-gadget-multi-Remove-unused-include.patch
new file mode 100644 (file)
index 0000000..ce2673f
--- /dev/null
@@ -0,0 +1,30 @@
+From 064d8be47636d57befdd30d4659b823111218128 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 28 May 2013 09:15:52 +0200
+Subject: [PATCH 0634/1302] usb: gadget: multi: Remove unused include
+
+cleanup only, no functional changes.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/multi.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
+index 6164393..656c999 100644
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -45,7 +45,6 @@ MODULE_LICENSE("GPL");
+ #define USBF_ECM_INCLUDED
+ #include "f_ecm.c"
+-#include "f_subset.c"
+ #ifdef USB_ETH_RNDIS
+ #  include "f_rndis.c"
+ #  include "rndis.h"
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0635-usb-gadget-f_subset-convert-to-new-function-interfac.patch b/patches.tizen/0635-usb-gadget-f_subset-convert-to-new-function-interfac.patch
new file mode 100644 (file)
index 0000000..b23313c
--- /dev/null
@@ -0,0 +1,302 @@
+From 665921ce15ba630b13073b24576746c728d654dc Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 28 May 2013 09:15:53 +0200
+Subject: [PATCH 0635/1302] usb: gadget: f_subset: convert to new function
+ interface with backward compatibility
+
+Converting ecm subset to the new function interface requires converting
+the USB subset's function code and its users.
+
+This patch converts the f_subset.c to the new function interface.
+
+The file is now compiled into a separate usb_f_subset.ko module.
+
+The old function interface is provided by means of a preprocessor
+conditional directives. After all users are converted, the old interface
+can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig    |   3 +
+ drivers/usb/gadget/Makefile   |   2 +
+ drivers/usb/gadget/ether.c    |   1 +
+ drivers/usb/gadget/f_subset.c | 136 +++++++++++++++++++++++++++++++++++++-----
+ drivers/usb/gadget/g_ffs.c    |   1 +
+ drivers/usb/gadget/u_gether.h |  27 +++++++++
+ 6 files changed, 155 insertions(+), 15 deletions(-)
+ create mode 100644 drivers/usb/gadget/u_gether.h
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 90e64a9..a557205 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -531,6 +531,9 @@ config USB_F_PHONET
+ config USB_F_EEM
+       tristate
++config USB_F_SUBSET
++      tristate
++
+ choice
+       tristate "USB Gadget Drivers"
+       default USB_ETH
+diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
+index 7069f53..1bfad55 100644
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -56,6 +56,8 @@ usb_f_phonet-y                       := f_phonet.o
+ obj-$(CONFIG_USB_F_PHONET)    += usb_f_phonet.o
+ usb_f_eem-y                   := f_eem.o
+ obj-$(CONFIG_USB_F_EEM)               += usb_f_eem.o
++usb_f_ecm_subset-y            := f_subset.o
++obj-$(CONFIG_USB_F_SUBSET)    += usb_f_ecm_subset.o
+ #
+ # USB gadget drivers
+diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
+index 2078e6c..3173966 100644
+--- a/drivers/usb/gadget/ether.c
++++ b/drivers/usb/gadget/ether.c
+@@ -103,6 +103,7 @@ static inline bool has_rndis(void)
+  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+  */
+ #include "u_ecm.h"
++#define USB_FSUBSET_INCLUDED
+ #include "f_subset.c"
+ #ifdef        USB_ETH_RNDIS
+ #include "f_rndis.c"
+diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c
+index 7be04b3..5ae0bf6 100644
+--- a/drivers/usb/gadget/f_subset.c
++++ b/drivers/usb/gadget/f_subset.c
+@@ -12,11 +12,12 @@
+ #include <linux/slab.h>
+ #include <linux/kernel.h>
++#include <linux/module.h>
+ #include <linux/device.h>
+ #include <linux/etherdevice.h>
+ #include "u_ether.h"
+-
++#include "u_gether.h"
+ /*
+  * This function packages a simple "CDC Subset" Ethernet port with no real
+@@ -298,6 +299,35 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
+       int                     status;
+       struct usb_ep           *ep;
++#ifndef USB_FSUBSET_INCLUDED
++      struct f_gether_opts    *gether_opts;
++
++      gether_opts = container_of(f->fi, struct f_gether_opts, func_inst);
++
++      /*
++       * in drivers/usb/gadget/configfs.c:configfs_composite_bind()
++       * configurations are bound in sequence with list_for_each_entry,
++       * in each configuration its functions are bound in sequence
++       * with list_for_each_entry, so we assume no race condition
++       * with regard to gether_opts->bound access
++       */
++      if (!gether_opts->bound) {
++              gether_set_gadget(gether_opts->net, cdev->gadget);
++              status = gether_register_netdev(gether_opts->net);
++              if (status)
++                      return status;
++              gether_opts->bound = true;
++      }
++#endif
++      /* maybe allocate device-global string IDs */
++      if (geth_string_defs[0].id == 0) {
++              status = usb_string_ids_tab(c->cdev, geth_string_defs);
++              if (status < 0)
++                      return status;
++              subset_data_intf.iInterface = geth_string_defs[0].id;
++              ether_desc.iMACAddress = geth_string_defs[1].id;
++      }
++
+       /* allocate instance-specific interface IDs */
+       status = usb_interface_id(c, f);
+       if (status < 0)
+@@ -360,8 +390,10 @@ fail:
+       return status;
+ }
++#ifdef USB_FSUBSET_INCLUDED
++
+ static void
+-geth_unbind(struct usb_configuration *c, struct usb_function *f)
++geth_old_unbind(struct usb_configuration *c, struct usb_function *f)
+ {
+       geth_string_defs[0].id = 0;
+       usb_free_all_descriptors(f);
+@@ -387,18 +419,6 @@ int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+       struct f_gether *geth;
+       int             status;
+-      if (!ethaddr)
+-              return -EINVAL;
+-
+-      /* maybe allocate device-global string IDs */
+-      if (geth_string_defs[0].id == 0) {
+-              status = usb_string_ids_tab(c->cdev, geth_string_defs);
+-              if (status < 0)
+-                      return status;
+-              subset_data_intf.iInterface = geth_string_defs[0].id;
+-              ether_desc.iMACAddress = geth_string_defs[1].id;
+-      }
+-
+       /* allocate and initialize one new instance */
+       geth = kzalloc(sizeof *geth, GFP_KERNEL);
+       if (!geth)
+@@ -414,7 +434,7 @@ int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+       geth->port.func.name = "cdc_subset";
+       geth->port.func.strings = geth_strings;
+       geth->port.func.bind = geth_bind;
+-      geth->port.func.unbind = geth_unbind;
++      geth->port.func.unbind = geth_old_unbind;
+       geth->port.func.set_alt = geth_set_alt;
+       geth->port.func.disable = geth_disable;
+@@ -423,3 +443,89 @@ int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+               kfree(geth);
+       return status;
+ }
++
++#else
++
++static void geth_free_inst(struct usb_function_instance *f)
++{
++      struct f_gether_opts *opts;
++
++      opts = container_of(f, struct f_gether_opts, func_inst);
++      if (opts->bound)
++              gether_cleanup(netdev_priv(opts->net));
++      else
++              free_netdev(opts->net);
++      kfree(opts);
++}
++
++static struct usb_function_instance *geth_alloc_inst(void)
++{
++      struct f_gether_opts *opts;
++
++      opts = kzalloc(sizeof(*opts), GFP_KERNEL);
++      if (!opts)
++              return ERR_PTR(-ENOMEM);
++
++      opts->func_inst.free_func_inst = geth_free_inst;
++      opts->net = gether_setup_default();
++      if (IS_ERR(opts->net))
++              return ERR_CAST(opts->net);
++
++      return &opts->func_inst;
++}
++
++static void geth_free(struct usb_function *f)
++{
++      struct f_gether *eth;
++
++      eth = func_to_geth(f);
++      kfree(eth);
++}
++
++static void geth_unbind(struct usb_configuration *c, struct usb_function *f)
++{
++      geth_string_defs[0].id = 0;
++      usb_free_all_descriptors(f);
++}
++
++static struct usb_function *geth_alloc(struct usb_function_instance *fi)
++{
++      struct f_gether *geth;
++      struct f_gether_opts *opts;
++      int status;
++
++      /* allocate and initialize one new instance */
++      geth = kzalloc(sizeof(*geth), GFP_KERNEL);
++      if (!geth)
++              return ERR_PTR(-ENOMEM);
++
++      opts = container_of(fi, struct f_gether_opts, func_inst);
++
++      /* export host's Ethernet address in CDC format */
++      status = gether_get_host_addr_cdc(opts->net, geth->ethaddr,
++                                        sizeof(geth->ethaddr));
++      if (status < 12) {
++              kfree(geth);
++              return ERR_PTR(-EINVAL);
++      }
++      geth_string_defs[1].s = geth->ethaddr;
++
++      geth->port.ioport = netdev_priv(opts->net);
++      geth->port.cdc_filter = DEFAULT_FILTER;
++
++      geth->port.func.name = "cdc_subset";
++      geth->port.func.strings = geth_strings;
++      geth->port.func.bind = geth_bind;
++      geth->port.func.unbind = geth_unbind;
++      geth->port.func.set_alt = geth_set_alt;
++      geth->port.func.disable = geth_disable;
++      geth->port.func.free_func = geth_free;
++
++      return &geth->port.func;
++}
++
++DECLARE_USB_FUNCTION_INIT(geth, geth_alloc_inst, geth_alloc);
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("David Brownell");
++
++#endif
+diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
+index d38a073..3d290e5 100644
+--- a/drivers/usb/gadget/g_ffs.c
++++ b/drivers/usb/gadget/g_ffs.c
+@@ -30,6 +30,7 @@
+ #define USBF_ECM_INCLUDED
+ #  include "f_ecm.c"
++#define USB_FSUBSET_INCLUDED
+ #  include "f_subset.c"
+ #  ifdef USB_ETH_RNDIS
+ #    include "f_rndis.c"
+diff --git a/drivers/usb/gadget/u_gether.h b/drivers/usb/gadget/u_gether.h
+new file mode 100644
+index 0000000..3a4a2bf
+--- /dev/null
++++ b/drivers/usb/gadget/u_gether.h
+@@ -0,0 +1,27 @@
++/*
++ * u_gether.h
++ *
++ * Utility definitions for the subset function
++ *
++ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
++ *            http://www.samsung.com
++ *
++ * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.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 U_GETHER_H
++#define U_GETHER_H
++
++#include <linux/usb/composite.h>
++
++struct f_gether_opts {
++      struct usb_function_instance    func_inst;
++      struct net_device               *net;
++      bool                            bound;
++};
++
++#endif /* U_GETHER_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0636-usb-gadget-ether-convert-to-new-interface-of-f_subse.patch b/patches.tizen/0636-usb-gadget-ether-convert-to-new-interface-of-f_subse.patch
new file mode 100644 (file)
index 0000000..89a3587
--- /dev/null
@@ -0,0 +1,223 @@
+From b850d196a60df60a14061c910711fbe553285ac2 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 28 May 2013 09:15:54 +0200
+Subject: [PATCH 0636/1302] usb: gadget: ether: convert to new interface of
+ f_subset
+
+teach ethernet code about the new interface of f_subset so
+the old one can eventually be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig |   1 +
+ drivers/usb/gadget/ether.c | 104 +++++++++++++++++++++++++--------------------
+ 2 files changed, 58 insertions(+), 47 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index a557205..15d28e5 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -652,6 +652,7 @@ config USB_ETH
+       select USB_U_ETHER
+       select USB_U_RNDIS
+       select USB_F_ECM
++      select USB_F_SUBSET
+       select CRC32
+       help
+         This driver implements Ethernet style communication, in one of
+diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
+index 3173966..9e96d55 100644
+--- a/drivers/usb/gadget/ether.c
++++ b/drivers/usb/gadget/ether.c
+@@ -14,6 +14,7 @@
+ /* #define VERBOSE_DEBUG */
+ #include <linux/kernel.h>
++#include <linux/netdevice.h>
+ #if defined USB_ETH_RNDIS
+ #  undef USB_ETH_RNDIS
+@@ -103,8 +104,7 @@ static inline bool has_rndis(void)
+  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+  */
+ #include "u_ecm.h"
+-#define USB_FSUBSET_INCLUDED
+-#include "f_subset.c"
++#include "u_gether.h"
+ #ifdef        USB_ETH_RNDIS
+ #include "f_rndis.c"
+ #include "rndis.h"
+@@ -220,6 +220,9 @@ static struct usb_function *f_ecm;
+ static struct usb_function_instance *fi_eem;
+ static struct usb_function *f_eem;
++static struct usb_function_instance *fi_geth;
++static struct usb_function *f_geth;
++
+ /*-------------------------------------------------------------------------*/
+ /*
+@@ -290,8 +293,17 @@ static int __init eth_do_config(struct usb_configuration *c)
+                       usb_put_function(f_ecm);
+               return status;
+-      } else
+-              return geth_bind_config(c, host_mac, the_dev);
++      } else {
++              f_geth = usb_get_function(fi_geth);
++              if (IS_ERR(f_geth))
++                      return PTR_ERR(f_geth);
++
++              status = usb_add_function(c, f_geth);
++              if (status < 0)
++                      usb_put_function(f_geth);
++
++              return status;
++      }
+ }
+@@ -309,16 +321,10 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
+       struct usb_gadget       *gadget = cdev->gadget;
+       struct f_eem_opts       *eem_opts = NULL;
+       struct f_ecm_opts       *ecm_opts = NULL;
++      struct f_gether_opts    *geth_opts = NULL;
++      struct net_device       *net;
+       int                     status;
+-      if (!use_eem && !can_support_ecm(gadget)) {
+-              /* set up network link layer */
+-              the_dev = gether_setup(cdev->gadget, dev_addr, host_addr,
+-                              host_mac, qmult);
+-              if (IS_ERR(the_dev))
+-                      return PTR_ERR(the_dev);
+-      }
+-
+       /* set up main config label and device descriptor */
+       if (use_eem) {
+               /* EEM */
+@@ -328,13 +334,8 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
+               eem_opts = container_of(fi_eem, struct f_eem_opts, func_inst);
+-              gether_set_qmult(eem_opts->net, qmult);
+-              if (!gether_set_host_addr(eem_opts->net, host_addr))
+-                      pr_info("using host ethernet address: %s", host_addr);
+-              if (!gether_set_dev_addr(eem_opts->net, dev_addr))
+-                      pr_info("using self ethernet address: %s", dev_addr);
+-
+-              the_dev = netdev_priv(eem_opts->net);
++              net = eem_opts->net;
++              the_dev = netdev_priv(net);
+               eth_config_driver.label = "CDC Ethernet (EEM)";
+               device_desc.idVendor = cpu_to_le16(EEM_VENDOR_NUM);
+@@ -348,17 +349,23 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
+               ecm_opts = container_of(fi_ecm, struct f_ecm_opts, func_inst);
+-              gether_set_qmult(ecm_opts->net, qmult);
+-              if (!gether_set_host_addr(ecm_opts->net, host_addr))
+-                      pr_info("using host ethernet address: %s", host_addr);
+-              if (!gether_set_dev_addr(ecm_opts->net, dev_addr))
+-                      pr_info("using self ethernet address: %s", dev_addr);
+-
+-              the_dev = netdev_priv(ecm_opts->net);
++              net = ecm_opts->net;
++              the_dev = netdev_priv(net);
+               eth_config_driver.label = "CDC Ethernet (ECM)";
+       } else {
+               /* CDC Subset */
++
++              fi_geth = usb_get_function_instance("geth");
++              if (IS_ERR(fi_geth))
++                      return PTR_ERR(fi_geth);
++
++              geth_opts = container_of(fi_geth, struct f_gether_opts,
++                                       func_inst);
++
++              net = geth_opts->net;
++              the_dev = netdev_priv(net);
++
+               eth_config_driver.label = "CDC Subset/SAFE";
+               device_desc.idVendor = cpu_to_le16(SIMPLE_VENDOR_NUM);
+@@ -367,23 +374,26 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
+                       device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
+       }
++      gether_set_qmult(net, qmult);
++      if (!gether_set_host_addr(net, host_addr))
++              pr_info("using host ethernet address: %s", host_addr);
++      if (!gether_set_dev_addr(net, dev_addr))
++              pr_info("using self ethernet address: %s", dev_addr);
++
+       if (has_rndis()) {
+               /* RNDIS plus ECM-or-Subset */
+-              if (use_eem) {
+-                      gether_set_gadget(eem_opts->net, cdev->gadget);
+-                      status = gether_register_netdev(eem_opts->net);
+-                      if (status)
+-                              goto fail;
++              gether_set_gadget(net, cdev->gadget);
++              status = gether_register_netdev(net);
++              if (status)
++                      goto fail;
++              gether_get_host_addr_u8(net, host_mac);
++
++              if (use_eem)
+                       eem_opts->bound = true;
+-                      gether_get_host_addr_u8(eem_opts->net, host_mac);
+-              } else if (can_support_ecm(gadget)) {
+-                      gether_set_gadget(ecm_opts->net, cdev->gadget);
+-                      status = gether_register_netdev(ecm_opts->net);
+-                      if (status)
+-                              goto fail;
++              else if (can_support_ecm(gadget))
+                       ecm_opts->bound = true;
+-                      gether_get_host_addr_u8(ecm_opts->net, host_mac);
+-              }
++              else
++                      geth_opts->bound = true;
+               device_desc.idVendor = cpu_to_le16(RNDIS_VENDOR_NUM);
+               device_desc.idProduct = cpu_to_le16(RNDIS_PRODUCT_NUM);
+@@ -419,23 +429,23 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
+       return 0;
+ fail:
+-      if (!use_eem && !can_support_ecm(gadget))
+-              gether_cleanup(the_dev);
+-      else if (use_eem)
++      if (use_eem)
+               usb_put_function_instance(fi_eem);
+-      else
++      else if (can_support_ecm(gadget))
+               usb_put_function_instance(fi_ecm);
++      else
++              usb_put_function_instance(fi_geth);
+       return status;
+ }
+ static int __exit eth_unbind(struct usb_composite_dev *cdev)
+ {
+-      if (!use_eem && !can_support_ecm(cdev->gadget))
+-              gether_cleanup(the_dev);
+-      else if (use_eem)
++      if (use_eem)
+               usb_put_function_instance(fi_eem);
+-      else
++      else if (can_support_ecm(cdev->gadget))
+               usb_put_function_instance(fi_ecm);
++      else
++              usb_put_function_instance(fi_geth);
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0637-usb-gadget-f_subset-use-usb_gstrings_attach.patch b/patches.tizen/0637-usb-gadget-f_subset-use-usb_gstrings_attach.patch
new file mode 100644 (file)
index 0000000..734f26b
--- /dev/null
@@ -0,0 +1,68 @@
+From 7262c6120619e93777ee265f2331f49dc3f99810 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 28 May 2013 09:15:55 +0200
+Subject: [PATCH 0637/1302] usb: gadget: f_subset: use usb_gstrings_attach
+
+use the new usb_gstrings_attach interface.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_subset.c | 18 ++++++++----------
+ 1 file changed, 8 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c
+index 5ae0bf6..089881a 100644
+--- a/drivers/usb/gadget/f_subset.c
++++ b/drivers/usb/gadget/f_subset.c
+@@ -296,6 +296,7 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
+ {
+       struct usb_composite_dev *cdev = c->cdev;
+       struct f_gether         *geth = func_to_geth(f);
++      struct usb_string       *us;
+       int                     status;
+       struct usb_ep           *ep;
+@@ -319,14 +320,13 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
+               gether_opts->bound = true;
+       }
+ #endif
+-      /* maybe allocate device-global string IDs */
+-      if (geth_string_defs[0].id == 0) {
+-              status = usb_string_ids_tab(c->cdev, geth_string_defs);
+-              if (status < 0)
+-                      return status;
+-              subset_data_intf.iInterface = geth_string_defs[0].id;
+-              ether_desc.iMACAddress = geth_string_defs[1].id;
+-      }
++      us = usb_gstrings_attach(cdev, geth_strings,
++                               ARRAY_SIZE(geth_string_defs));
++      if (IS_ERR(us))
++              return PTR_ERR(us);
++
++      subset_data_intf.iInterface = us[0].id;
++      ether_desc.iMACAddress = us[1].id;
+       /* allocate instance-specific interface IDs */
+       status = usb_interface_id(c, f);
+@@ -432,7 +432,6 @@ int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+       geth->port.cdc_filter = DEFAULT_FILTER;
+       geth->port.func.name = "cdc_subset";
+-      geth->port.func.strings = geth_strings;
+       geth->port.func.bind = geth_bind;
+       geth->port.func.unbind = geth_old_unbind;
+       geth->port.func.set_alt = geth_set_alt;
+@@ -514,7 +513,6 @@ static struct usb_function *geth_alloc(struct usb_function_instance *fi)
+       geth->port.cdc_filter = DEFAULT_FILTER;
+       geth->port.func.name = "cdc_subset";
+-      geth->port.func.strings = geth_strings;
+       geth->port.func.bind = geth_bind;
+       geth->port.func.unbind = geth_unbind;
+       geth->port.func.set_alt = geth_set_alt;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0638-usb-gadget-f_subset-add-configfs-support.patch b/patches.tizen/0638-usb-gadget-f_subset-add-configfs-support.patch
new file mode 100644 (file)
index 0000000..675aa90
--- /dev/null
@@ -0,0 +1,183 @@
+From dc4f8f5d45f280cb474317a5a06a7dbf87603764 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 28 May 2013 09:15:56 +0200
+Subject: [PATCH 0638/1302] usb: gadget: f_subset: add configfs support
+
+f_subset learns about configfs so we can, eventually,
+remove in-kernel gadget drivers.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../ABI/testing/configfs-usb-gadget-subset         | 14 +++++++
+ drivers/usb/gadget/Kconfig                         | 10 +++++
+ drivers/usb/gadget/f_subset.c                      | 46 +++++++++++++++++++++-
+ drivers/usb/gadget/u_gether.h                      |  9 +++++
+ 4 files changed, 78 insertions(+), 1 deletion(-)
+ create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-subset
+
+diff --git a/Documentation/ABI/testing/configfs-usb-gadget-subset b/Documentation/ABI/testing/configfs-usb-gadget-subset
+new file mode 100644
+index 0000000..f47170a
+--- /dev/null
++++ b/Documentation/ABI/testing/configfs-usb-gadget-subset
+@@ -0,0 +1,14 @@
++What:         /config/usb-gadget/gadget/functions/geth.name
++Date:         May 2013
++KenelVersion: 3.11
++Description:
++              The attributes:
++
++              ifname          - network device interface name associated with
++                              this function instance
++              qmult           - queue length multiplier for high and
++                              super speed
++              host_addr       - MAC address of host's end of this
++                              Ethernet over USB link
++              dev_addr        - MAC address of device's end of this
++                              Ethernet over USB link
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 15d28e5..9b15f51 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -555,6 +555,16 @@ choice
+ # this first set of drivers all depend on bulk-capable hardware.
++config USB_CONFIGFS_ECM_SUBSET
++      boolean "Ethernet Control Model (CDC ECM) subset"
++      depends on USB_CONFIGFS
++      depends on NET
++      select USB_U_ETHER
++      select USB_F_SUBSET
++      help
++        On hardware that can't implement the full protocol,
++        a simple CDC subset is used, placing fewer demands on USB.
++
+ config USB_CONFIGFS_EEM
+       bool "Ethernet Emulation Model (EEM)"
+       depends on USB_CONFIGFS
+diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c
+index 089881a..fbc7a24 100644
+--- a/drivers/usb/gadget/f_subset.c
++++ b/drivers/usb/gadget/f_subset.c
+@@ -17,6 +17,7 @@
+ #include <linux/etherdevice.h>
+ #include "u_ether.h"
++#include "u_ether_configfs.h"
+ #include "u_gether.h"
+ /*
+@@ -313,8 +314,10 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
+        * with regard to gether_opts->bound access
+        */
+       if (!gether_opts->bound) {
++              mutex_lock(&gether_opts->lock);
+               gether_set_gadget(gether_opts->net, cdev->gadget);
+               status = gether_register_netdev(gether_opts->net);
++              mutex_unlock(&gether_opts->lock);
+               if (status)
+                       return status;
+               gether_opts->bound = true;
+@@ -445,6 +448,41 @@ int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+ #else
++static inline struct f_gether_opts *to_f_gether_opts(struct config_item *item)
++{
++      return container_of(to_config_group(item), struct f_gether_opts,
++                          func_inst.group);
++}
++
++/* f_gether_item_ops */
++USB_ETHERNET_CONFIGFS_ITEM(gether);
++
++/* f_gether_opts_dev_addr */
++USB_ETHERNET_CONFIGFS_ITEM_ATTR_DEV_ADDR(gether);
++
++/* f_gether_opts_host_addr */
++USB_ETHERNET_CONFIGFS_ITEM_ATTR_HOST_ADDR(gether);
++
++/* f_gether_opts_qmult */
++USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(gether);
++
++/* f_gether_opts_ifname */
++USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(gether);
++
++static struct configfs_attribute *gether_attrs[] = {
++      &f_gether_opts_dev_addr.attr,
++      &f_gether_opts_host_addr.attr,
++      &f_gether_opts_qmult.attr,
++      &f_gether_opts_ifname.attr,
++      NULL,
++};
++
++static struct config_item_type gether_func_type = {
++      .ct_item_ops    = &gether_item_ops,
++      .ct_attrs       = gether_attrs,
++      .ct_owner       = THIS_MODULE,
++};
++
+ static void geth_free_inst(struct usb_function_instance *f)
+ {
+       struct f_gether_opts *opts;
+@@ -464,12 +502,15 @@ static struct usb_function_instance *geth_alloc_inst(void)
+       opts = kzalloc(sizeof(*opts), GFP_KERNEL);
+       if (!opts)
+               return ERR_PTR(-ENOMEM);
+-
++      mutex_init(&opts->lock);
+       opts->func_inst.free_func_inst = geth_free_inst;
+       opts->net = gether_setup_default();
+       if (IS_ERR(opts->net))
+               return ERR_CAST(opts->net);
++      config_group_init_type_name(&opts->func_inst.group, "",
++                                  &gether_func_type);
++
+       return &opts->func_inst;
+ }
+@@ -500,6 +541,8 @@ static struct usb_function *geth_alloc(struct usb_function_instance *fi)
+       opts = container_of(fi, struct f_gether_opts, func_inst);
++      mutex_lock(&opts->lock);
++      opts->refcnt++;
+       /* export host's Ethernet address in CDC format */
+       status = gether_get_host_addr_cdc(opts->net, geth->ethaddr,
+                                         sizeof(geth->ethaddr));
+@@ -510,6 +553,7 @@ static struct usb_function *geth_alloc(struct usb_function_instance *fi)
+       geth_string_defs[1].s = geth->ethaddr;
+       geth->port.ioport = netdev_priv(opts->net);
++      mutex_unlock(&opts->lock);
+       geth->port.cdc_filter = DEFAULT_FILTER;
+       geth->port.func.name = "cdc_subset";
+diff --git a/drivers/usb/gadget/u_gether.h b/drivers/usb/gadget/u_gether.h
+index 3a4a2bf..d407842 100644
+--- a/drivers/usb/gadget/u_gether.h
++++ b/drivers/usb/gadget/u_gether.h
+@@ -22,6 +22,15 @@ struct f_gether_opts {
+       struct usb_function_instance    func_inst;
+       struct net_device               *net;
+       bool                            bound;
++
++      /*
++       * Read/write access to configfs attributes is handled by configfs.
++       *
++       * This is to protect the data from concurrent access by read/write
++       * and create symlink/remove symlink.
++       */
++      struct mutex                    lock;
++      int                             refcnt;
+ };
+ #endif /* U_GETHER_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0639-usb-gadget-f_rndis-convert-to-new-function-interface.patch b/patches.tizen/0639-usb-gadget-f_rndis-convert-to-new-function-interface.patch
new file mode 100644 (file)
index 0000000..cad715e
--- /dev/null
@@ -0,0 +1,416 @@
+From fae9d57abdaa683ca402ca7fd2fc025627e2be03 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 28 May 2013 09:15:57 +0200
+Subject: [PATCH 0639/1302] usb: gadget: f_rndis: convert to new function
+ interface with backward compatibility
+
+Converting rndis to the new function interface requires converting
+the USB rndis' function code and its users.
+
+This patch converts the f_rndis.c to the new function interface.
+
+The file is now compiled into a separate usb_f_rndis.ko module.
+
+The old function interface is provided by means of a preprocessor
+conditional directives. After all users are converted, the old interface
+can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig   |   3 +
+ drivers/usb/gadget/Makefile  |   2 +
+ drivers/usb/gadget/ether.c   |   1 +
+ drivers/usb/gadget/f_rndis.c | 203 +++++++++++++++++++++++++++++++++++++------
+ drivers/usb/gadget/g_ffs.c   |   1 +
+ drivers/usb/gadget/multi.c   |   1 +
+ drivers/usb/gadget/u_rndis.h |  32 +++++++
+ 7 files changed, 215 insertions(+), 28 deletions(-)
+ create mode 100644 drivers/usb/gadget/u_rndis.h
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 9b15f51..d9535f4 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -534,6 +534,9 @@ config USB_F_EEM
+ config USB_F_SUBSET
+       tristate
++config USB_F_RNDIS
++      tristate
++
+ choice
+       tristate "USB Gadget Drivers"
+       default USB_ETH
+diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
+index 1bfad55..b417760 100644
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -58,6 +58,8 @@ usb_f_eem-y                  := f_eem.o
+ obj-$(CONFIG_USB_F_EEM)               += usb_f_eem.o
+ usb_f_ecm_subset-y            := f_subset.o
+ obj-$(CONFIG_USB_F_SUBSET)    += usb_f_ecm_subset.o
++usb_f_rndis-y                 := f_rndis.o
++obj-$(CONFIG_USB_F_RNDIS)     += usb_f_rndis.o
+ #
+ # USB gadget drivers
+diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
+index 9e96d55..4d7290a 100644
+--- a/drivers/usb/gadget/ether.c
++++ b/drivers/usb/gadget/ether.c
+@@ -106,6 +106,7 @@ static inline bool has_rndis(void)
+ #include "u_ecm.h"
+ #include "u_gether.h"
+ #ifdef        USB_ETH_RNDIS
++#define USB_FRNDIS_INCLUDED
+ #include "f_rndis.c"
+ #include "rndis.h"
+ #endif
+diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
+index 36e8c44..437198b 100644
+--- a/drivers/usb/gadget/f_rndis.c
++++ b/drivers/usb/gadget/f_rndis.c
+@@ -17,15 +17,16 @@
+ #include <linux/slab.h>
+ #include <linux/kernel.h>
++#include <linux/module.h>
+ #include <linux/device.h>
+ #include <linux/etherdevice.h>
+ #include <linux/atomic.h>
+ #include "u_ether.h"
++#include "u_rndis.h"
+ #include "rndis.h"
+-
+ /*
+  * This function is an RNDIS Ethernet port -- a Microsoft protocol that's
+  * been promoted instead of the standard CDC Ethernet.  The published RNDIS
+@@ -655,6 +656,13 @@ static void rndis_close(struct gether *geth)
+ /*-------------------------------------------------------------------------*/
++/* Some controllers can't support RNDIS ... */
++static inline bool can_support_rndis(struct usb_configuration *c)
++{
++      /* everything else is *presumably* fine */
++      return true;
++}
++
+ /* ethernet function driver setup/binding */
+ static int
+@@ -665,6 +673,45 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
+       int                     status;
+       struct usb_ep           *ep;
++#ifndef USB_FRNDIS_INCLUDED
++      struct f_rndis_opts *rndis_opts;
++
++      if (!can_support_rndis(c))
++              return -EINVAL;
++
++      rndis_opts = container_of(f->fi, struct f_rndis_opts, func_inst);
++
++      /*
++       * in drivers/usb/gadget/configfs.c:configfs_composite_bind()
++       * configurations are bound in sequence with list_for_each_entry,
++       * in each configuration its functions are bound in sequence
++       * with list_for_each_entry, so we assume no race condition
++       * with regard to rndis_opts->bound access
++       */
++      if (!rndis_opts->bound) {
++              gether_set_gadget(rndis_opts->net, cdev->gadget);
++              status = gether_register_netdev(rndis_opts->net);
++              if (status)
++                      return status;
++              rndis_opts->bound = true;
++      }
++#endif
++
++      if (rndis_string_defs[0].id == 0) {
++              /* ... and setup RNDIS itself */
++              status = rndis_init();
++              if (status < 0)
++                      return status;
++
++              status = usb_string_ids_tab(c->cdev, rndis_string_defs);
++              if (status)
++                      return status;
++
++              rndis_control_intf.iInterface = rndis_string_defs[0].id;
++              rndis_data_intf.iInterface = rndis_string_defs[1].id;
++              rndis_iad_descriptor.iFunction = rndis_string_defs[2].id;
++      }
++
+       /* allocate instance-specific interface IDs */
+       status = usb_interface_id(c, f);
+       if (status < 0)
+@@ -741,10 +788,12 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
+       rndis->port.open = rndis_open;
+       rndis->port.close = rndis_close;
++#ifdef USB_FRNDIS_INCLUDED
+       status = rndis_register(rndis_response_available, rndis);
+       if (status < 0)
+               goto fail;
+       rndis->config = status;
++#endif
+       rndis_set_param_medium(rndis->config, RNDIS_MEDIUM_802_3, 0);
+       rndis_set_host_mac(rndis->config, rndis->ethaddr);
+@@ -787,8 +836,10 @@ fail:
+       return status;
+ }
++#ifdef USB_FRNDIS_INCLUDED
++
+ static void
+-rndis_unbind(struct usb_configuration *c, struct usb_function *f)
++rndis_old_unbind(struct usb_configuration *c, struct usb_function *f)
+ {
+       struct f_rndis          *rndis = func_to_rndis(f);
+@@ -804,13 +855,6 @@ rndis_unbind(struct usb_configuration *c, struct usb_function *f)
+       kfree(rndis);
+ }
+-/* Some controllers can't support RNDIS ... */
+-static inline bool can_support_rndis(struct usb_configuration *c)
+-{
+-      /* everything else is *presumably* fine */
+-      return true;
+-}
+-
+ int
+ rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+               u32 vendorID, const char *manufacturer, struct eth_dev *dev)
+@@ -818,24 +862,6 @@ rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+       struct f_rndis  *rndis;
+       int             status;
+-      if (!can_support_rndis(c) || !ethaddr)
+-              return -EINVAL;
+-
+-      if (rndis_string_defs[0].id == 0) {
+-              /* ... and setup RNDIS itself */
+-              status = rndis_init();
+-              if (status < 0)
+-                      return status;
+-
+-              status = usb_string_ids_tab(c->cdev, rndis_string_defs);
+-              if (status)
+-                      return status;
+-
+-              rndis_control_intf.iInterface = rndis_string_defs[0].id;
+-              rndis_data_intf.iInterface = rndis_string_defs[1].id;
+-              rndis_iad_descriptor.iFunction = rndis_string_defs[2].id;
+-      }
+-
+       /* allocate and initialize one new instance */
+       status = -ENOMEM;
+       rndis = kzalloc(sizeof *rndis, GFP_KERNEL);
+@@ -859,7 +885,7 @@ rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+       rndis->port.func.strings = rndis_strings;
+       /* descriptors are per-instance copies */
+       rndis->port.func.bind = rndis_bind;
+-      rndis->port.func.unbind = rndis_unbind;
++      rndis->port.func.unbind = rndis_old_unbind;
+       rndis->port.func.set_alt = rndis_set_alt;
+       rndis->port.func.setup = rndis_setup;
+       rndis->port.func.disable = rndis_disable;
+@@ -872,3 +898,124 @@ fail:
+       }
+       return status;
+ }
++
++#else
++
++void rndis_borrow_net(struct usb_function_instance *f, struct net_device *net)
++{
++      struct f_rndis_opts *opts;
++
++      opts = container_of(f, struct f_rndis_opts, func_inst);
++      if (opts->bound)
++              gether_cleanup(netdev_priv(opts->net));
++      else
++              free_netdev(opts->net);
++      opts->borrowed_net = opts->bound = true;
++      opts->net = net;
++}
++EXPORT_SYMBOL(rndis_borrow_net);
++
++static void rndis_free_inst(struct usb_function_instance *f)
++{
++      struct f_rndis_opts *opts;
++
++      opts = container_of(f, struct f_rndis_opts, func_inst);
++      if (!opts->borrowed_net) {
++              if (opts->bound)
++                      gether_cleanup(netdev_priv(opts->net));
++              else
++                      free_netdev(opts->net);
++      }
++      kfree(opts);
++}
++
++static struct usb_function_instance *rndis_alloc_inst(void)
++{
++      struct f_rndis_opts *opts;
++
++      opts = kzalloc(sizeof(*opts), GFP_KERNEL);
++      if (!opts)
++              return ERR_PTR(-ENOMEM);
++
++      opts->func_inst.free_func_inst = rndis_free_inst;
++      opts->net = gether_setup_default();
++      if (IS_ERR(opts->net))
++              return ERR_CAST(opts->net);
++
++      return &opts->func_inst;
++}
++
++static void rndis_free(struct usb_function *f)
++{
++      struct f_rndis *rndis;
++
++      rndis = func_to_rndis(f);
++      rndis_deregister(rndis->config);
++      kfree(rndis);
++}
++
++static void rndis_unbind(struct usb_configuration *c, struct usb_function *f)
++{
++      struct f_rndis          *rndis = func_to_rndis(f);
++
++      rndis_exit();
++      rndis_string_defs[0].id = 0;
++      usb_free_all_descriptors(f);
++
++      kfree(rndis->notify_req->buf);
++      usb_ep_free_request(rndis->notify, rndis->notify_req);
++}
++
++static struct usb_function *rndis_alloc(struct usb_function_instance *fi)
++{
++      struct f_rndis  *rndis;
++      struct f_rndis_opts *opts;
++      int status;
++
++      /* allocate and initialize one new instance */
++      rndis = kzalloc(sizeof(*rndis), GFP_KERNEL);
++      if (!rndis) {
++              rndis_exit();
++              return ERR_PTR(-ENOMEM);
++      }
++
++      opts = container_of(fi, struct f_rndis_opts, func_inst);
++
++      gether_get_host_addr_u8(opts->net, rndis->ethaddr);
++      rndis->vendorID = opts->vendor_id;
++      rndis->manufacturer = opts->manufacturer;
++
++      rndis->port.ioport = netdev_priv(opts->net);
++      /* RNDIS activates when the host changes this filter */
++      rndis->port.cdc_filter = 0;
++
++      /* RNDIS has special (and complex) framing */
++      rndis->port.header_len = sizeof(struct rndis_packet_msg_type);
++      rndis->port.wrap = rndis_add_header;
++      rndis->port.unwrap = rndis_rm_hdr;
++
++      rndis->port.func.name = "rndis";
++      rndis->port.func.strings = rndis_strings;
++      /* descriptors are per-instance copies */
++      rndis->port.func.bind = rndis_bind;
++      rndis->port.func.unbind = rndis_unbind;
++      rndis->port.func.set_alt = rndis_set_alt;
++      rndis->port.func.setup = rndis_setup;
++      rndis->port.func.disable = rndis_disable;
++      rndis->port.func.free_func = rndis_free;
++
++      status = rndis_register(rndis_response_available, rndis);
++      if (status < 0) {
++              kfree(rndis);
++              return ERR_PTR(status);
++      }
++      rndis->config = status;
++
++      return &rndis->port.func;
++}
++
++DECLARE_USB_FUNCTION_INIT(rndis, rndis_alloc_inst, rndis_alloc);
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("David Brownell");
++
++#endif
+diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
+index 3d290e5..5327c82 100644
+--- a/drivers/usb/gadget/g_ffs.c
++++ b/drivers/usb/gadget/g_ffs.c
+@@ -33,6 +33,7 @@
+ #define USB_FSUBSET_INCLUDED
+ #  include "f_subset.c"
+ #  ifdef USB_ETH_RNDIS
++#    define USB_FRNDIS_INCLUDED
+ #    include "f_rndis.c"
+ #    include "rndis.h"
+ #  endif
+diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
+index 656c999..032b96a 100644
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -46,6 +46,7 @@ MODULE_LICENSE("GPL");
+ #define USBF_ECM_INCLUDED
+ #include "f_ecm.c"
+ #ifdef USB_ETH_RNDIS
++#  define USB_FRNDIS_INCLUDED
+ #  include "f_rndis.c"
+ #  include "rndis.h"
+ #endif
+diff --git a/drivers/usb/gadget/u_rndis.h b/drivers/usb/gadget/u_rndis.h
+new file mode 100644
+index 0000000..d274df5
+--- /dev/null
++++ b/drivers/usb/gadget/u_rndis.h
+@@ -0,0 +1,32 @@
++/*
++ * u_rndis.h
++ *
++ * Utility definitions for the subset function
++ *
++ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
++ *            http://www.samsung.com
++ *
++ * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.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 U_RNDIS_H
++#define U_RNDIS_H
++
++#include <linux/usb/composite.h>
++
++struct f_rndis_opts {
++      struct usb_function_instance    func_inst;
++      u32                             vendor_id;
++      const char                      *manufacturer;
++      struct net_device               *net;
++      bool                            bound;
++      bool                            borrowed_net;
++};
++
++void rndis_borrow_net(struct usb_function_instance *f, struct net_device *net);
++
++#endif /* U_RNDIS_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0640-usb-gadget-ether-convert-to-new-interface-of-f_rndis.patch b/patches.tizen/0640-usb-gadget-ether-convert-to-new-interface-of-f_rndis.patch
new file mode 100644 (file)
index 0000000..df0e2a7
--- /dev/null
@@ -0,0 +1,199 @@
+From dbc5c92ab2a38ed442f55e0644c91fbe1ceee26f Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 28 May 2013 09:15:58 +0200
+Subject: [PATCH 0640/1302] usb: gadget: ether: convert to new interface of
+ f_rndis
+
+use new interface so old one can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig |  1 +
+ drivers/usb/gadget/ether.c | 56 +++++++++++++++++++++++++++-------------------
+ 2 files changed, 34 insertions(+), 23 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index d9535f4..b5941bf 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -702,6 +702,7 @@ config USB_ETH_RNDIS
+       bool "RNDIS support"
+       depends on USB_ETH
+       select USB_LIBCOMPOSITE
++      select USB_F_RNDIS
+       default y
+       help
+          Microsoft Windows XP bundles the "Remote NDIS" (RNDIS) protocol,
+diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
+index 4d7290a..f48712f 100644
+--- a/drivers/usb/gadget/ether.c
++++ b/drivers/usb/gadget/ether.c
+@@ -94,23 +94,14 @@ static inline bool has_rndis(void)
+ #include <linux/module.h>
+-/*-------------------------------------------------------------------------*/
+-
+-/*
+- * Kbuild is not very cooperative with respect to linking separately
+- * compiled library objects into one module.  So for now we won't use
+- * separate compilation ... ensuring init/exit sections work to shrink
+- * the runtime footprint, and giving us at least some parts of what
+- * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+- */
+ #include "u_ecm.h"
+ #include "u_gether.h"
+ #ifdef        USB_ETH_RNDIS
+-#define USB_FRNDIS_INCLUDED
+-#include "f_rndis.c"
++#include "u_rndis.h"
+ #include "rndis.h"
++#else
++#define rndis_borrow_net(...) do {} while (0)
+ #endif
+-
+ #include "u_eem.h"
+ /*-------------------------------------------------------------------------*/
+@@ -212,9 +203,6 @@ static struct usb_gadget_strings *dev_strings[] = {
+       NULL,
+ };
+-static u8 host_mac[ETH_ALEN];
+-static struct eth_dev *the_dev;
+-
+ static struct usb_function_instance *fi_ecm;
+ static struct usb_function *f_ecm;
+@@ -224,6 +212,9 @@ static struct usb_function *f_eem;
+ static struct usb_function_instance *fi_geth;
+ static struct usb_function *f_geth;
++static struct usb_function_instance *fi_rndis;
++static struct usb_function *f_rndis;
++
+ /*-------------------------------------------------------------------------*/
+ /*
+@@ -233,6 +224,8 @@ static struct usb_function *f_geth;
+  */
+ static int __init rndis_do_config(struct usb_configuration *c)
+ {
++      int status;
++
+       /* FIXME alloc iConfiguration string, set it in c->strings */
+       if (gadget_is_otg(c->cdev->gadget)) {
+@@ -240,7 +233,15 @@ static int __init rndis_do_config(struct usb_configuration *c)
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+-      return rndis_bind_config(c, host_mac, the_dev);
++      f_rndis = usb_get_function(fi_rndis);
++      if (IS_ERR(f_rndis))
++              return PTR_ERR(f_rndis);
++
++      status = usb_add_function(c, f_rndis);
++      if (status < 0)
++              usb_put_function(f_rndis);
++
++      return status;
+ }
+ static struct usb_configuration rndis_config_driver = {
+@@ -336,7 +337,6 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
+               eem_opts = container_of(fi_eem, struct f_eem_opts, func_inst);
+               net = eem_opts->net;
+-              the_dev = netdev_priv(net);
+               eth_config_driver.label = "CDC Ethernet (EEM)";
+               device_desc.idVendor = cpu_to_le16(EEM_VENDOR_NUM);
+@@ -351,7 +351,6 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
+               ecm_opts = container_of(fi_ecm, struct f_ecm_opts, func_inst);
+               net = ecm_opts->net;
+-              the_dev = netdev_priv(net);
+               eth_config_driver.label = "CDC Ethernet (ECM)";
+       } else {
+@@ -365,7 +364,6 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
+                                        func_inst);
+               net = geth_opts->net;
+-              the_dev = netdev_priv(net);
+               eth_config_driver.label = "CDC Subset/SAFE";
+@@ -387,7 +385,6 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
+               status = gether_register_netdev(net);
+               if (status)
+                       goto fail;
+-              gether_get_host_addr_u8(net, host_mac);
+               if (use_eem)
+                       eem_opts->bound = true;
+@@ -396,6 +393,14 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
+               else
+                       geth_opts->bound = true;
++              fi_rndis = usb_get_function_instance("rndis");
++              if (IS_ERR(fi_rndis)) {
++                      status = PTR_ERR(fi_rndis);
++                      goto fail;
++              }
++
++              rndis_borrow_net(fi_rndis, net);
++
+               device_desc.idVendor = cpu_to_le16(RNDIS_VENDOR_NUM);
+               device_desc.idProduct = cpu_to_le16(RNDIS_PRODUCT_NUM);
+               device_desc.bNumConfigurations = 2;
+@@ -407,7 +412,7 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
+       status = usb_string_ids_tab(cdev, strings_dev);
+       if (status < 0)
+-              goto fail;
++              goto fail1;
+       device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id;
+       device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id;
+@@ -416,12 +421,12 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
+               status = usb_add_config(cdev, &rndis_config_driver,
+                               rndis_do_config);
+               if (status < 0)
+-                      goto fail;
++                      goto fail1;
+       }
+       status = usb_add_config(cdev, &eth_config_driver, eth_do_config);
+       if (status < 0)
+-              goto fail;
++              goto fail1;
+       usb_composite_overwrite_options(cdev, &coverwrite);
+       dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n",
+@@ -429,6 +434,9 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
+       return 0;
++fail1:
++      if (has_rndis())
++              usb_put_function_instance(fi_rndis);
+ fail:
+       if (use_eem)
+               usb_put_function_instance(fi_eem);
+@@ -441,6 +449,8 @@ fail:
+ static int __exit eth_unbind(struct usb_composite_dev *cdev)
+ {
++      if (has_rndis())
++              usb_put_function_instance(fi_rndis);
+       if (use_eem)
+               usb_put_function_instance(fi_eem);
+       else if (can_support_ecm(cdev->gadget))
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0641-usb-gadget-rndis-init-exit-rndis-at-module-load-unlo.patch b/patches.tizen/0641-usb-gadget-rndis-init-exit-rndis-at-module-load-unlo.patch
new file mode 100644 (file)
index 0000000..3be7ca9
--- /dev/null
@@ -0,0 +1,115 @@
+From dbc41a881fb1e41bcb4910fbba9386f428758c70 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 28 May 2013 09:15:59 +0200
+Subject: [PATCH 0641/1302] usb: gadget: rndis: init & exit rndis at module
+ load/unload
+
+This is required in preparation for using usb_gstrings_attach.
+
+The rndis initialization so far has been performed on the first
+occurence of rndis_bind(), but the condition to check it (first
+or not first) was "borrowed" from strings handling.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_rndis.c | 15 ++-------------
+ drivers/usb/gadget/rndis.c   |  4 ++--
+ drivers/usb/gadget/rndis.h   |  3 ---
+ 3 files changed, 4 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
+index 437198b..e5c6aee 100644
+--- a/drivers/usb/gadget/f_rndis.c
++++ b/drivers/usb/gadget/f_rndis.c
+@@ -698,11 +698,6 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
+ #endif
+       if (rndis_string_defs[0].id == 0) {
+-              /* ... and setup RNDIS itself */
+-              status = rndis_init();
+-              if (status < 0)
+-                      return status;
+-
+               status = usb_string_ids_tab(c->cdev, rndis_string_defs);
+               if (status)
+                       return status;
+@@ -844,7 +839,6 @@ rndis_old_unbind(struct usb_configuration *c, struct usb_function *f)
+       struct f_rndis          *rndis = func_to_rndis(f);
+       rndis_deregister(rndis->config);
+-      rndis_exit();
+       rndis_string_defs[0].id = 0;
+       usb_free_all_descriptors(f);
+@@ -891,11 +885,9 @@ rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+       rndis->port.func.disable = rndis_disable;
+       status = usb_add_function(c, &rndis->port.func);
+-      if (status) {
++      if (status)
+               kfree(rndis);
+ fail:
+-              rndis_exit();
+-      }
+       return status;
+ }
+@@ -958,7 +950,6 @@ static void rndis_unbind(struct usb_configuration *c, struct usb_function *f)
+ {
+       struct f_rndis          *rndis = func_to_rndis(f);
+-      rndis_exit();
+       rndis_string_defs[0].id = 0;
+       usb_free_all_descriptors(f);
+@@ -974,10 +965,8 @@ static struct usb_function *rndis_alloc(struct usb_function_instance *fi)
+       /* allocate and initialize one new instance */
+       rndis = kzalloc(sizeof(*rndis), GFP_KERNEL);
+-      if (!rndis) {
+-              rndis_exit();
++      if (!rndis)
+               return ERR_PTR(-ENOMEM);
+-      }
+       opts = container_of(fi, struct f_rndis_opts, func_inst);
+diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
+index 8c5e957..3e3ea72 100644
+--- a/drivers/usb/gadget/rndis.c
++++ b/drivers/usb/gadget/rndis.c
+@@ -1174,7 +1174,7 @@ int rndis_init(void)
+       return 0;
+ }
+-EXPORT_SYMBOL(rndis_init);
++module_init(rndis_init);
+ void rndis_exit(void)
+ {
+@@ -1188,6 +1188,6 @@ void rndis_exit(void)
+       }
+ #endif
+ }
+-EXPORT_SYMBOL(rndis_exit);
++module_exit(rndis_exit);
+ MODULE_LICENSE("GPL");
+diff --git a/drivers/usb/gadget/rndis.h b/drivers/usb/gadget/rndis.h
+index 6e79615..0f4abb4 100644
+--- a/drivers/usb/gadget/rndis.h
++++ b/drivers/usb/gadget/rndis.h
+@@ -217,7 +217,4 @@ int  rndis_signal_disconnect (int configNr);
+ int  rndis_state (int configNr);
+ extern void rndis_set_host_mac (int configNr, const u8 *addr);
+-int rndis_init(void);
+-void rndis_exit (void);
+-
+ #endif  /* _LINUX_RNDIS_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0642-usb-gadget-f_rndis-use-usb_gstrings_attach.patch b/patches.tizen/0642-usb-gadget-f_rndis-use-usb_gstrings_attach.patch
new file mode 100644 (file)
index 0000000..f108274
--- /dev/null
@@ -0,0 +1,86 @@
+From eefe0dc4a1bbf02eb85cfbf9d2e2a1385178f98f Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 28 May 2013 09:16:00 +0200
+Subject: [PATCH 0642/1302] usb: gadget: f_rndis: use usb_gstrings_attach
+
+use new usb_gstrings_attach interface
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_rndis.c | 22 ++++++++--------------
+ 1 file changed, 8 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
+index e5c6aee..4045ca2 100644
+--- a/drivers/usb/gadget/f_rndis.c
++++ b/drivers/usb/gadget/f_rndis.c
+@@ -670,6 +670,7 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
+ {
+       struct usb_composite_dev *cdev = c->cdev;
+       struct f_rndis          *rndis = func_to_rndis(f);
++      struct usb_string       *us;
+       int                     status;
+       struct usb_ep           *ep;
+@@ -696,16 +697,13 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
+               rndis_opts->bound = true;
+       }
+ #endif
+-
+-      if (rndis_string_defs[0].id == 0) {
+-              status = usb_string_ids_tab(c->cdev, rndis_string_defs);
+-              if (status)
+-                      return status;
+-
+-              rndis_control_intf.iInterface = rndis_string_defs[0].id;
+-              rndis_data_intf.iInterface = rndis_string_defs[1].id;
+-              rndis_iad_descriptor.iFunction = rndis_string_defs[2].id;
+-      }
++      us = usb_gstrings_attach(cdev, rndis_strings,
++                               ARRAY_SIZE(rndis_string_defs));
++      if (IS_ERR(us))
++              return PTR_ERR(us);
++      rndis_control_intf.iInterface = us[0].id;
++      rndis_data_intf.iInterface = us[1].id;
++      rndis_iad_descriptor.iFunction = us[2].id;
+       /* allocate instance-specific interface IDs */
+       status = usb_interface_id(c, f);
+@@ -840,7 +838,6 @@ rndis_old_unbind(struct usb_configuration *c, struct usb_function *f)
+       rndis_deregister(rndis->config);
+-      rndis_string_defs[0].id = 0;
+       usb_free_all_descriptors(f);
+       kfree(rndis->notify_req->buf);
+@@ -876,7 +873,6 @@ rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+       rndis->port.unwrap = rndis_rm_hdr;
+       rndis->port.func.name = "rndis";
+-      rndis->port.func.strings = rndis_strings;
+       /* descriptors are per-instance copies */
+       rndis->port.func.bind = rndis_bind;
+       rndis->port.func.unbind = rndis_old_unbind;
+@@ -950,7 +946,6 @@ static void rndis_unbind(struct usb_configuration *c, struct usb_function *f)
+ {
+       struct f_rndis          *rndis = func_to_rndis(f);
+-      rndis_string_defs[0].id = 0;
+       usb_free_all_descriptors(f);
+       kfree(rndis->notify_req->buf);
+@@ -984,7 +979,6 @@ static struct usb_function *rndis_alloc(struct usb_function_instance *fi)
+       rndis->port.unwrap = rndis_rm_hdr;
+       rndis->port.func.name = "rndis";
+-      rndis->port.func.strings = rndis_strings;
+       /* descriptors are per-instance copies */
+       rndis->port.func.bind = rndis_bind;
+       rndis->port.func.unbind = rndis_unbind;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0643-usb-gadget-f_rndis-add-configfs-support.patch b/patches.tizen/0643-usb-gadget-f_rndis-add-configfs-support.patch
new file mode 100644 (file)
index 0000000..2e7f5a0
--- /dev/null
@@ -0,0 +1,192 @@
+From 333155071bb6fe39b104a8e54acd7a53bd5e0d8b Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 28 May 2013 09:16:01 +0200
+Subject: [PATCH 0643/1302] usb: gadget: f_rndis: add configfs support
+
+f_rndis learns about configfs so we can, eventually,
+remove in-kernel gadget drivers.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../ABI/testing/configfs-usb-gadget-rndis          | 14 +++++++
+ drivers/usb/gadget/Kconfig                         | 16 +++++++
+ drivers/usb/gadget/f_rndis.c                       | 49 +++++++++++++++++++++-
+ drivers/usb/gadget/u_rndis.h                       |  9 ++++
+ 4 files changed, 87 insertions(+), 1 deletion(-)
+ create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-rndis
+
+diff --git a/Documentation/ABI/testing/configfs-usb-gadget-rndis b/Documentation/ABI/testing/configfs-usb-gadget-rndis
+new file mode 100644
+index 0000000..ff127dd
+--- /dev/null
++++ b/Documentation/ABI/testing/configfs-usb-gadget-rndis
+@@ -0,0 +1,14 @@
++What:         /config/usb-gadget/gadget/functions/rndis.name
++Date:         May 2013
++KenelVersion: 3.11
++Description:
++              The attributes:
++
++              ifname          - network device interface name associated with
++                              this function instance
++              qmult           - queue length multiplier for high and
++                              super speed
++              host_addr       - MAC address of host's end of this
++                              Ethernet over USB link
++              dev_addr        - MAC address of device's end of this
++                              Ethernet over USB link
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index b5941bf..03bcfa1 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -568,6 +568,22 @@ config USB_CONFIGFS_ECM_SUBSET
+         On hardware that can't implement the full protocol,
+         a simple CDC subset is used, placing fewer demands on USB.
++config USB_CONFIGFS_RNDIS
++      bool "RNDIS"
++      depends on USB_CONFIGFS
++      depends on NET
++      select USB_U_ETHER
++      select USB_F_RNDIS
++      help
++         Microsoft Windows XP bundles the "Remote NDIS" (RNDIS) protocol,
++         and Microsoft provides redistributable binary RNDIS drivers for
++         older versions of Windows.
++
++         To make MS-Windows work with this, use Documentation/usb/linux.inf
++         as the "driver info file".  For versions of MS-Windows older than
++         XP, you'll need to download drivers from Microsoft's website; a URL
++         is given in comments found in that info file.
++
+ config USB_CONFIGFS_EEM
+       bool "Ethernet Emulation Model (EEM)"
+       depends on USB_CONFIGFS
+diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
+index 4045ca2..191df35 100644
+--- a/drivers/usb/gadget/f_rndis.c
++++ b/drivers/usb/gadget/f_rndis.c
+@@ -24,6 +24,7 @@
+ #include <linux/atomic.h>
+ #include "u_ether.h"
++#include "u_ether_configfs.h"
+ #include "u_rndis.h"
+ #include "rndis.h"
+@@ -903,6 +904,41 @@ void rndis_borrow_net(struct usb_function_instance *f, struct net_device *net)
+ }
+ EXPORT_SYMBOL(rndis_borrow_net);
++static inline struct f_rndis_opts *to_f_rndis_opts(struct config_item *item)
++{
++      return container_of(to_config_group(item), struct f_rndis_opts,
++                          func_inst.group);
++}
++
++/* f_rndis_item_ops */
++USB_ETHERNET_CONFIGFS_ITEM(rndis);
++
++/* f_rndis_opts_dev_addr */
++USB_ETHERNET_CONFIGFS_ITEM_ATTR_DEV_ADDR(rndis);
++
++/* f_rndis_opts_host_addr */
++USB_ETHERNET_CONFIGFS_ITEM_ATTR_HOST_ADDR(rndis);
++
++/* f_rndis_opts_qmult */
++USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(rndis);
++
++/* f_rndis_opts_ifname */
++USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(rndis);
++
++static struct configfs_attribute *rndis_attrs[] = {
++      &f_rndis_opts_dev_addr.attr,
++      &f_rndis_opts_host_addr.attr,
++      &f_rndis_opts_qmult.attr,
++      &f_rndis_opts_ifname.attr,
++      NULL,
++};
++
++static struct config_item_type rndis_func_type = {
++      .ct_item_ops    = &rndis_item_ops,
++      .ct_attrs       = rndis_attrs,
++      .ct_owner       = THIS_MODULE,
++};
++
+ static void rndis_free_inst(struct usb_function_instance *f)
+ {
+       struct f_rndis_opts *opts;
+@@ -924,22 +960,30 @@ static struct usb_function_instance *rndis_alloc_inst(void)
+       opts = kzalloc(sizeof(*opts), GFP_KERNEL);
+       if (!opts)
+               return ERR_PTR(-ENOMEM);
+-
++      mutex_init(&opts->lock);
+       opts->func_inst.free_func_inst = rndis_free_inst;
+       opts->net = gether_setup_default();
+       if (IS_ERR(opts->net))
+               return ERR_CAST(opts->net);
++      config_group_init_type_name(&opts->func_inst.group, "",
++                                  &rndis_func_type);
++
+       return &opts->func_inst;
+ }
+ static void rndis_free(struct usb_function *f)
+ {
+       struct f_rndis *rndis;
++      struct f_rndis_opts *opts;
+       rndis = func_to_rndis(f);
+       rndis_deregister(rndis->config);
++      opts = container_of(f->fi, struct f_rndis_opts, func_inst);
+       kfree(rndis);
++      mutex_lock(&opts->lock);
++      opts->refcnt--;
++      mutex_unlock(&opts->lock);
+ }
+ static void rndis_unbind(struct usb_configuration *c, struct usb_function *f)
+@@ -964,12 +1008,15 @@ static struct usb_function *rndis_alloc(struct usb_function_instance *fi)
+               return ERR_PTR(-ENOMEM);
+       opts = container_of(fi, struct f_rndis_opts, func_inst);
++      mutex_lock(&opts->lock);
++      opts->refcnt++;
+       gether_get_host_addr_u8(opts->net, rndis->ethaddr);
+       rndis->vendorID = opts->vendor_id;
+       rndis->manufacturer = opts->manufacturer;
+       rndis->port.ioport = netdev_priv(opts->net);
++      mutex_unlock(&opts->lock);
+       /* RNDIS activates when the host changes this filter */
+       rndis->port.cdc_filter = 0;
+diff --git a/drivers/usb/gadget/u_rndis.h b/drivers/usb/gadget/u_rndis.h
+index d274df5..c62ba82 100644
+--- a/drivers/usb/gadget/u_rndis.h
++++ b/drivers/usb/gadget/u_rndis.h
+@@ -25,6 +25,15 @@ struct f_rndis_opts {
+       struct net_device               *net;
+       bool                            bound;
+       bool                            borrowed_net;
++
++      /*
++       * Read/write access to configfs attributes is handled by configfs.
++       *
++       * This is to protect the data from concurrent access by read/write
++       * and create symlink/remove symlink.
++       */
++      struct mutex                    lock;
++      int                             refcnt;
+ };
+ void rndis_borrow_net(struct usb_function_instance *f, struct net_device *net);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0644-usb-gadget-f_mass_storage-fix-default-product-name.patch b/patches.tizen/0644-usb-gadget-f_mass_storage-fix-default-product-name.patch
new file mode 100644 (file)
index 0000000..0fdf951
--- /dev/null
@@ -0,0 +1,38 @@
+From 6b93a7d91f1211ca19f6617e8208a1e4c2b5fdb8 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 4 Jun 2013 15:27:54 +0200
+Subject: [PATCH 0644/1302] usb: gadget: f_mass_storage: fix default product
+ name
+
+If cfg->product name is not set, a default name is chosen depending
+on the common->luns->cdrom flag. If the flag is set the name should
+be "File-CD Gadget", and if the flag is not set the name should be
+"File-Stor Gadget".
+
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index c35a9ec..56f1fd1 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -2747,8 +2747,8 @@ buffhds_first_it:
+                "%-8s%-16s%04x", cfg->vendor_name ?: "Linux",
+                /* Assume product name dependent on the first LUN */
+                cfg->product_name ?: (common->luns->cdrom
+-                                   ? "File-Stor Gadget"
+-                                   : "File-CD Gadget"),
++                                   ? "File-CD Gadget"
++                                   : "File-Stor Gadget"),
+                i);
+       /*
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0645-usb-gadget-Kconfig-fix-separate-building-of-configfs.patch b/patches.tizen/0645-usb-gadget-Kconfig-fix-separate-building-of-configfs.patch
new file mode 100644 (file)
index 0000000..b4fddbb
--- /dev/null
@@ -0,0 +1,102 @@
+From 33aa866c1d48fef43256c4a54c4cb175ddf766c4 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 13 Jun 2013 10:37:24 +0200
+Subject: [PATCH 0645/1302] usb/gadget: Kconfig: fix separate building of
+ configfs-enabled functions
+
+USB_CONFGFS_ZZZZ should appear under a tristate option in order to allow
+selecting more than one function without building the legacy gadgets.
+Now there are two problems:
+
+1) they can't be selected at all, because they depend on USB_CONFIGFS,
+and the patch which adds USB_CONFIGFS has not been merged.
+2) they don't select USB_LIBCOMPOSITE (which they need but which is
+selected by USB_CONFIGFS)
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig | 64 ++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 64 insertions(+)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 03bcfa1..4b4d748 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -558,6 +558,70 @@ choice
+ # this first set of drivers all depend on bulk-capable hardware.
++config USB_CONFIGFS
++      tristate "USB functions configurable through configfs"
++      select USB_LIBCOMPOSITE
++      help
++        A Linux USB "gadget" can be set up through configfs.
++        If this is the case, the USB functions (which from the host's
++        perspective are seen as interfaces) and configurations are
++        specified simply by creating appropriate directories in configfs.
++        Associating functions with configurations is done by creating
++        appropriate symbolic links.
++        For more information see Documentation/usb/gadget-configfs.txt.
++
++config USB_CONFIGFS_SERIAL
++      boolean "Generic serial bulk in/out"
++      depends on USB_CONFIGFS
++      depends on TTY
++      select USB_U_SERIAL
++      select USB_F_SERIAL
++      help
++        The function talks to the Linux-USB generic serial driver.
++
++config USB_CONFIGFS_ACM
++      boolean "Abstract Control Model (CDC ACM)"
++      depends on USB_CONFIGFS
++      depends on TTY
++      select USB_U_SERIAL
++      select USB_F_ACM
++      help
++        ACM serial link.  This function can be used to interoperate with
++        MS-Windows hosts or with the Linux-USB "cdc-acm" driver.
++
++config USB_CONFIGFS_OBEX
++      boolean "Object Exchange Model (CDC OBEX)"
++      depends on USB_CONFIGFS
++      depends on TTY
++      select USB_U_SERIAL
++      select USB_F_OBEX
++      help
++        You will need a user space OBEX server talking to /dev/ttyGS*,
++        since the kernel itself doesn't implement the OBEX protocol.
++
++config USB_CONFIGFS_NCM
++      boolean "Network Control Model (CDC NCM)"
++      depends on USB_CONFIGFS
++      depends on NET
++      select USB_U_ETHER
++      select USB_F_NCM
++      help
++        NCM is an advanced protocol for Ethernet encapsulation, allows
++        grouping of several ethernet frames into one USB transfer and
++        different alignment possibilities.
++
++config USB_CONFIGFS_ECM
++      boolean "Ethernet Control Model (CDC ECM)"
++      depends on USB_CONFIGFS
++      depends on NET
++      select USB_U_ETHER
++      select USB_F_ECM
++      help
++        The "Communication Device Class" (CDC) Ethernet Control Model.
++        That protocol is often avoided with pure Ethernet adapters, in
++        favor of simpler vendor-specific hardware, but is widely
++        supported by firmware for smart network devices.
++
+ config USB_CONFIGFS_ECM_SUBSET
+       boolean "Ethernet Control Model (CDC ECM) subset"
+       depends on USB_CONFIGFS
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0646-usb-gadget-f_ecm-fix-missing-unlock-on-error-in-ecm_.patch b/patches.tizen/0646-usb-gadget-f_ecm-fix-missing-unlock-on-error-in-ecm_.patch
new file mode 100644 (file)
index 0000000..5f5a36d
--- /dev/null
@@ -0,0 +1,35 @@
+From 918eaa89f0710af1459de4b40ea884ac1a769710 Mon Sep 17 00:00:00 2001
+From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
+Date: Tue, 18 Jun 2013 12:21:21 +0800
+Subject: [PATCH 0646/1302] usb: gadget: f_ecm: fix missing unlock on error in
+ ecm_alloc()
+
+Add the missing unlock before return from function ecm_alloc()
+in the error handling case.
+
+Introduced by commit da92801c647cdebfd45001fd6aaecb8f0be7f56b.
+(usb: gadget: f_ecm: add configfs support)
+
+Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
+Acked-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_ecm.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c
+index fcafe1a..5d3561e 100644
+--- a/drivers/usb/gadget/f_ecm.c
++++ b/drivers/usb/gadget/f_ecm.c
+@@ -1012,6 +1012,7 @@ struct usb_function *ecm_alloc(struct usb_function_instance *fi)
+                                         sizeof(ecm->ethaddr));
+       if (status < 12) {
+               kfree(ecm);
++              mutex_unlock(&opts->lock);
+               return ERR_PTR(-EINVAL);
+       }
+       ecm_string_defs[1].s = ecm->ethaddr;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0647-usb-gadget-f_ncm-fix-missing-unlock-on-error-in-ncm_.patch b/patches.tizen/0647-usb-gadget-f_ncm-fix-missing-unlock-on-error-in-ncm_.patch
new file mode 100644 (file)
index 0000000..d968257
--- /dev/null
@@ -0,0 +1,35 @@
+From 4c4104824565b05e0ddda76ef5a19f7c2fbf63ea Mon Sep 17 00:00:00 2001
+From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
+Date: Tue, 18 Jun 2013 11:43:29 +0800
+Subject: [PATCH 0647/1302] usb: gadget: f_ncm: fix missing unlock on error in
+ ncm_alloc()
+
+Add the missing unlock before return from function ncm_alloc()
+in the error handling case.
+
+Introduced by commit e730660378be92b83288b59b824ccdace5cd2652.
+(usb: gadget: f_ncm: add configfs support)
+
+Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
+Acked-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_ncm.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c
+index 47a5724..952177f 100644
+--- a/drivers/usb/gadget/f_ncm.c
++++ b/drivers/usb/gadget/f_ncm.c
+@@ -1403,6 +1403,7 @@ struct usb_function *ncm_alloc(struct usb_function_instance *fi)
+                                     sizeof(ncm->ethaddr));
+       if (status < 12) { /* strlen("01234567890a") */
+               kfree(ncm);
++              mutex_unlock(&opts->lock);
+               return ERR_PTR(-EINVAL);
+       }
+       ncm_string_defs[STRING_MAC_IDX].s = ncm->ethaddr;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0648-usb-gadget-f_subset-fix-missing-unlock-on-error-in-g.patch b/patches.tizen/0648-usb-gadget-f_subset-fix-missing-unlock-on-error-in-g.patch
new file mode 100644 (file)
index 0000000..1b29b44
--- /dev/null
@@ -0,0 +1,35 @@
+From 08483aefe94ea53802b9bd20f2d77d1da69ccaf0 Mon Sep 17 00:00:00 2001
+From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
+Date: Tue, 18 Jun 2013 11:40:55 +0800
+Subject: [PATCH 0648/1302] usb: gadget: f_subset: fix missing unlock on error
+ in geth_alloc()
+
+Add the missing unlock before return from function geth_alloc()
+in the error handling case.
+
+Introduced by commit 02832e56f88a981474ee4c7c141f46fc1b4454f4.
+(usb: gadget: f_subset: add configfs support)
+
+Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
+Acked-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_subset.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c
+index fbc7a24..5601e1d 100644
+--- a/drivers/usb/gadget/f_subset.c
++++ b/drivers/usb/gadget/f_subset.c
+@@ -548,6 +548,7 @@ static struct usb_function *geth_alloc(struct usb_function_instance *fi)
+                                         sizeof(geth->ethaddr));
+       if (status < 12) {
+               kfree(geth);
++              mutex_unlock(&opts->lock);
+               return ERR_PTR(-EINVAL);
+       }
+       geth_string_defs[1].s = geth->ethaddr;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0649-usb-gadget-Kconfig-Fix-configfs-based-RNDIS-function.patch b/patches.tizen/0649-usb-gadget-Kconfig-Fix-configfs-based-RNDIS-function.patch
new file mode 100644 (file)
index 0000000..18f5e22
--- /dev/null
@@ -0,0 +1,33 @@
+From ca9e9e1dcf7fc130825dd24d0fe788fdc6fb8f30 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 9 Jul 2013 08:14:39 +0200
+Subject: [PATCH 0649/1302] usb: gadget: Kconfig: Fix configfs-based RNDIS
+ function build
+
+USB_CONFIGFS_RNDIS depends on USB_U_RNDIS. Select it.
+
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Reported-by: Fengguang Wu <fengguang.wu@intel.com>
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 4b4d748..c240a4a 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -637,6 +637,7 @@ config USB_CONFIGFS_RNDIS
+       depends on USB_CONFIGFS
+       depends on NET
+       select USB_U_ETHER
++      select USB_U_RNDIS
+       select USB_F_RNDIS
+       help
+          Microsoft Windows XP bundles the "Remote NDIS" (RNDIS) protocol,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0650-usb-gadget-ether-put_usb_function-on-unbind.patch b/patches.tizen/0650-usb-gadget-ether-put_usb_function-on-unbind.patch
new file mode 100644 (file)
index 0000000..e2b2421
--- /dev/null
@@ -0,0 +1,60 @@
+From 13719e5150f4b0c6a19768f7059989a53fb3694c Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 24 Jul 2013 12:47:46 +0200
+Subject: [PATCH 0650/1302] usb: gadget: ether: put_usb_function on unbind
+
+Fix bugs introduced in
+
+9c62ce83e4258bacc459faf57bf2ed83cce6be08
+usb: gadget: ether: convert to new interface of f_ecm
+
+94b5573e97729f0e1496d23b69cbe2c6b24ec0c3
+usb: gadget: ether: convert to new interface of f_eem
+
+8af5232d6f48896b151898ccb2e9e155481bb785
+usb: gadget: ether: convert to new interface of f_subset
+
+9bd4a10e1bf881af0b0a7c117c7092b558447047
+usb: gadget: ether: convert to new interface of f_rndis
+
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/ether.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
+index f48712f..c1c113e 100644
+--- a/drivers/usb/gadget/ether.c
++++ b/drivers/usb/gadget/ether.c
+@@ -449,14 +449,20 @@ fail:
+ static int __exit eth_unbind(struct usb_composite_dev *cdev)
+ {
+-      if (has_rndis())
++      if (has_rndis()) {
++              usb_put_function(f_rndis);
+               usb_put_function_instance(fi_rndis);
+-      if (use_eem)
++      }
++      if (use_eem) {
++              usb_put_function(f_eem);
+               usb_put_function_instance(fi_eem);
+-      else if (can_support_ecm(cdev->gadget))
++      } else if (can_support_ecm(cdev->gadget)) {
++              usb_put_function(f_ecm);
+               usb_put_function_instance(fi_ecm);
+-      else
++      } else {
++              usb_put_function(f_geth);
+               usb_put_function_instance(fi_geth);
++      }
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0651-usb-gadget-free-opts-struct-on-error-recovery.patch b/patches.tizen/0651-usb-gadget-free-opts-struct-on-error-recovery.patch
new file mode 100644 (file)
index 0000000..9ffe255
--- /dev/null
@@ -0,0 +1,150 @@
+From 3477d859ac9daa0f93b8035917c0bc4935e77220 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 25 Jul 2013 09:13:18 +0200
+Subject: [PATCH 0651/1302] usb: gadget: free opts struct on error recovery
+
+Fix memory leaks introduced in commits:
+
+40d133d7f542616cf9538508a372306e626a16e9
+usb: gadget: f_ncm: convert to new function interface with backward compatibility
+
+fee562a6450b7806f1fbbe1469a67b5395b5c10a
+usb: gadget: f_ecm: convert to new function interface with backward compatibility
+
+fcbdf12ebef73a6069e2a1aada1e546fb578a4aa
+usb: gadget: f_phonet: convert to new function interface with backward compatibility
+
+b29002a157940752dfed2c488b2011f63f007d71
+usb: gadget: f_eem: convert to new function interface with backward compatibility
+
+8cedba7c73af1369599b1111639cfeb66fe13aaa
+usb: gadget: f_subset: convert to new function interface with backward compatibility
+
+f466c6353819326873fa48a02c6f2d7c903240d6
+usb: gadget: f_rndis: convert to new function interface with backward compatibility
+
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_ecm.c    | 7 +++++--
+ drivers/usb/gadget/f_eem.c    | 7 +++++--
+ drivers/usb/gadget/f_ncm.c    | 7 +++++--
+ drivers/usb/gadget/f_phonet.c | 7 +++++--
+ drivers/usb/gadget/f_rndis.c  | 7 +++++--
+ drivers/usb/gadget/f_subset.c | 7 +++++--
+ 6 files changed, 30 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c
+index 5d3561e..edab45d 100644
+--- a/drivers/usb/gadget/f_ecm.c
++++ b/drivers/usb/gadget/f_ecm.c
+@@ -959,8 +959,11 @@ static struct usb_function_instance *ecm_alloc_inst(void)
+       mutex_init(&opts->lock);
+       opts->func_inst.free_func_inst = ecm_free_inst;
+       opts->net = gether_setup_default();
+-      if (IS_ERR(opts->net))
+-              return ERR_PTR(PTR_ERR(opts->net));
++      if (IS_ERR(opts->net)) {
++              struct net_device *net = opts->net;
++              kfree(opts);
++              return ERR_CAST(net);
++      }
+       config_group_init_type_name(&opts->func_inst.group, "", &ecm_func_type);
+diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c
+index 90ee802..d00392d 100644
+--- a/drivers/usb/gadget/f_eem.c
++++ b/drivers/usb/gadget/f_eem.c
+@@ -593,8 +593,11 @@ static struct usb_function_instance *eem_alloc_inst(void)
+       mutex_init(&opts->lock);
+       opts->func_inst.free_func_inst = eem_free_inst;
+       opts->net = gether_setup_default();
+-      if (IS_ERR(opts->net))
+-              return ERR_CAST(opts->net);
++      if (IS_ERR(opts->net)) {
++              struct net_device *net = opts->net;
++              kfree(opts);
++              return ERR_CAST(net);
++      }
+       config_group_init_type_name(&opts->func_inst.group, "", &eem_func_type);
+diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c
+index 952177f..1c28fe1 100644
+--- a/drivers/usb/gadget/f_ncm.c
++++ b/drivers/usb/gadget/f_ncm.c
+@@ -1350,8 +1350,11 @@ static struct usb_function_instance *ncm_alloc_inst(void)
+       mutex_init(&opts->lock);
+       opts->func_inst.free_func_inst = ncm_free_inst;
+       opts->net = gether_setup_default();
+-      if (IS_ERR(opts->net))
+-              return ERR_PTR(PTR_ERR(opts->net));
++      if (IS_ERR(opts->net)) {
++              struct net_device *net = opts->net;
++              kfree(opts);
++              return ERR_CAST(net);
++      }
+       config_group_init_type_name(&opts->func_inst.group, "", &ncm_func_type);
+diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c
+index 7944fb0..1bf26e9 100644
+--- a/drivers/usb/gadget/f_phonet.c
++++ b/drivers/usb/gadget/f_phonet.c
+@@ -656,8 +656,11 @@ static struct usb_function_instance *phonet_alloc_inst(void)
+       opts->func_inst.free_func_inst = phonet_free_inst;
+       opts->net = gphonet_setup_default();
+-      if (IS_ERR(opts->net))
+-              return ERR_PTR(PTR_ERR(opts->net));
++      if (IS_ERR(opts->net)) {
++              struct net_device *net = opts->net;
++              kfree(opts);
++              return ERR_CAST(net);
++      }
+       config_group_init_type_name(&opts->func_inst.group, "",
+                       &phonet_func_type);
+diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
+index 191df35..717ed7f 100644
+--- a/drivers/usb/gadget/f_rndis.c
++++ b/drivers/usb/gadget/f_rndis.c
+@@ -963,8 +963,11 @@ static struct usb_function_instance *rndis_alloc_inst(void)
+       mutex_init(&opts->lock);
+       opts->func_inst.free_func_inst = rndis_free_inst;
+       opts->net = gether_setup_default();
+-      if (IS_ERR(opts->net))
+-              return ERR_CAST(opts->net);
++      if (IS_ERR(opts->net)) {
++              struct net_device *net = opts->net;
++              kfree(opts);
++              return ERR_CAST(net);
++      }
+       config_group_init_type_name(&opts->func_inst.group, "",
+                                   &rndis_func_type);
+diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c
+index 5601e1d..7c8674f 100644
+--- a/drivers/usb/gadget/f_subset.c
++++ b/drivers/usb/gadget/f_subset.c
+@@ -505,8 +505,11 @@ static struct usb_function_instance *geth_alloc_inst(void)
+       mutex_init(&opts->lock);
+       opts->func_inst.free_func_inst = geth_free_inst;
+       opts->net = gether_setup_default();
+-      if (IS_ERR(opts->net))
+-              return ERR_CAST(opts->net);
++      if (IS_ERR(opts->net)) {
++              struct net_device *net = opts->net;
++              kfree(opts);
++              return ERR_CAST(net);
++      }
+       config_group_init_type_name(&opts->func_inst.group, "",
+                                   &gether_func_type);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0652-usb-gadget-multi-fix-error-return-code-in-cdc_do_con.patch b/patches.tizen/0652-usb-gadget-multi-fix-error-return-code-in-cdc_do_con.patch
new file mode 100644 (file)
index 0000000..6cbdf0e
--- /dev/null
@@ -0,0 +1,69 @@
+From 3983faadef2741c8029dadebf38a5f8a40864330 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Fri, 26 Jul 2013 14:37:13 +0200
+Subject: [PATCH 0652/1302] usb: gadget: multi: fix error return code in
+ cdc_do_config()
+
+Fix to return a negative error code from the error handling
+case instead of 0, as returned elsewhere in this function.
+
+Introduced by commit 59835a (usb: gadget: multi: use
+function framework for ACM.)
+
+Make rndis_do_config() consistent with cdc_do_config() in the way it
+handles returning the PTR_ERR(f_acm_*).
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/multi.c | 10 +++-------
+ 1 file changed, 3 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
+index 032b96a..2a1ebef 100644
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -160,10 +160,8 @@ static __init int rndis_do_config(struct usb_configuration *c)
+               return ret;
+       f_acm_rndis = usb_get_function(fi_acm);
+-      if (IS_ERR(f_acm_rndis)) {
+-              ret = PTR_ERR(f_acm_rndis);
+-              goto err_func_acm;
+-      }
++      if (IS_ERR(f_acm_rndis))
++              return PTR_ERR(f_acm_rndis);
+       ret = usb_add_function(c, f_acm_rndis);
+       if (ret)
+@@ -178,7 +176,6 @@ err_fsg:
+       usb_remove_function(c, f_acm_rndis);
+ err_conf:
+       usb_put_function(f_acm_rndis);
+-err_func_acm:
+       return ret;
+ }
+@@ -226,7 +223,7 @@ static __init int cdc_do_config(struct usb_configuration *c)
+       /* implicit port_num is zero */
+       f_acm_multi = usb_get_function(fi_acm);
+       if (IS_ERR(f_acm_multi))
+-              goto err_func_acm;
++              return PTR_ERR(f_acm_multi);
+       ret = usb_add_function(c, f_acm_multi);
+       if (ret)
+@@ -241,7 +238,6 @@ err_fsg:
+       usb_remove_function(c, f_acm_multi);
+ err_conf:
+       usb_put_function(f_acm_multi);
+-err_func_acm:
+       return ret;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0653-usb-gadget-f_phonet-remove-unused-preprocessor-condi.patch b/patches.tizen/0653-usb-gadget-f_phonet-remove-unused-preprocessor-condi.patch
new file mode 100644 (file)
index 0000000..534521f
--- /dev/null
@@ -0,0 +1,42 @@
+From f05808b3a7041383738f6a2d1795e80b22fc010d Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Fri, 26 Jul 2013 14:37:14 +0200
+Subject: [PATCH 0653/1302] usb: gadget: f_phonet: remove unused preprocessor
+ conditional
+
+The compatibility layer which the USBF_PHONET_INCLUDED was a part of
+is no longer present - the USBF_PHONET_INCLUDED is not #defined by anyone
+anymore, so the ifndef is always true. Removing it.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_phonet.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c
+index 1bf26e9..eb3aa81 100644
+--- a/drivers/usb/gadget/f_phonet.c
++++ b/drivers/usb/gadget/f_phonet.c
+@@ -488,7 +488,6 @@ static int pn_bind(struct usb_configuration *c, struct usb_function *f)
+       struct usb_ep *ep;
+       int status, i;
+-#ifndef USBF_PHONET_INCLUDED
+       struct f_phonet_opts *phonet_opts;
+       phonet_opts = container_of(f->fi, struct f_phonet_opts, func_inst);
+@@ -507,7 +506,6 @@ static int pn_bind(struct usb_configuration *c, struct usb_function *f)
+                       return status;
+               phonet_opts->bound = true;
+       }
+-#endif
+       /* Reserve interface IDs */
+       status = usb_interface_id(c, f);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0654-usb-gadget-cdc2-fix-conversion-to-new-interface-of-f.patch b/patches.tizen/0654-usb-gadget-cdc2-fix-conversion-to-new-interface-of-f.patch
new file mode 100644 (file)
index 0000000..d09cf81
--- /dev/null
@@ -0,0 +1,76 @@
+From 63895a467fe8fc7754c188ffd819038eea56e878 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 1 Aug 2013 16:04:34 +0200
+Subject: [PATCH 0654/1302] usb/gadget: cdc2: fix conversion to new interface
+ of f_ecm
+
+This fixes commit a38a275030086d95306555e544fc7c0e65ccd00e
+(usb: gadget: cdc2: convert to new interface of f_ecm)
+
+The invocation of usb_get_function_instance() is in cdc_bind()
+and should not be repeated in cdc_do_config().
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/cdc2.c | 19 +------------------
+ 1 file changed, 1 insertion(+), 18 deletions(-)
+
+diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c
+index 5a5acf2..e126b6b 100644
+--- a/drivers/usb/gadget/cdc2.c
++++ b/drivers/usb/gadget/cdc2.c
+@@ -113,12 +113,6 @@ static int __init cdc_do_config(struct usb_configuration *c)
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+-      fi_ecm = usb_get_function_instance("ecm");
+-      if (IS_ERR(fi_ecm)) {
+-              status = PTR_ERR(fi_ecm);
+-              goto err_func_ecm;
+-      }
+-
+       f_ecm = usb_get_function(fi_ecm);
+       if (IS_ERR(f_ecm)) {
+               status = PTR_ERR(f_ecm);
+@@ -129,35 +123,24 @@ static int __init cdc_do_config(struct usb_configuration *c)
+       if (status)
+               goto err_add_ecm;
+-      fi_serial = usb_get_function_instance("acm");
+-      if (IS_ERR(fi_serial)) {
+-              status = PTR_ERR(fi_serial);
+-              goto err_get_acm;
+-      }
+-
+       f_acm = usb_get_function(fi_serial);
+       if (IS_ERR(f_acm)) {
+               status = PTR_ERR(f_acm);
+-              goto err_func_acm;
++              goto err_get_acm;
+       }
+       status = usb_add_function(c, f_acm);
+       if (status)
+               goto err_add_acm;
+-
+       return 0;
+ err_add_acm:
+       usb_put_function(f_acm);
+-err_func_acm:
+-      usb_put_function_instance(fi_serial);
+ err_get_acm:
+       usb_remove_function(c, f_ecm);
+ err_add_ecm:
+       usb_put_function(f_ecm);
+ err_get_ecm:
+-      usb_put_function_instance(fi_ecm);
+-err_func_ecm:
+       return status;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0655-usb-gadget-configfs-keep-a-function-if-it-is-not-suc.patch b/patches.tizen/0655-usb-gadget-configfs-keep-a-function-if-it-is-not-suc.patch
new file mode 100644 (file)
index 0000000..e136c29
--- /dev/null
@@ -0,0 +1,52 @@
+From a8144df8de23565b2c7fcf84c5024bb831e4acce Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 7 Aug 2013 13:58:20 +0200
+Subject: [PATCH 0655/1302] usb/gadget: configfs: keep a function if it is not
+ successfully added
+
+If usb_add_function() fails then the currently processed function
+is already not in the list in struct config_usb_cfg, and neither is it
+in the list in struct usb_configuration. At the err_purge_funcs label the
+purge_config_funcs() is called, which iterates over all configurations,
+and in each configuration it iterates over all _successfully_ added
+functions, and moves them back from the list in struct usb_configuration
+to the list in struct config_usb_cfg. BUT the function which has just
+failed adding and caused the unwind process is not taken care of and
+is effectively lost.
+
+This patch modifies the configfs_composite_bind() function so that if
+the usb_add_function() fails, then the currently processed function
+is returned to the list in struct config_usb_cfg.
+
+It would be tempting to delay the list_del() in question after
+usb_add_function() invocation, but a struct list_head (&f->list) cannot be
+stored in more than one list at the same time, so the list_del() must
+be called before usb_add_function(). Hence, the solution is to list_add()
+after usb_add_function() in case of error.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/configfs.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
+index 80e7f75..8f0d614 100644
+--- a/drivers/usb/gadget/configfs.c
++++ b/drivers/usb/gadget/configfs.c
+@@ -859,8 +859,10 @@ static int configfs_composite_bind(struct usb_gadget *gadget,
+               list_for_each_entry_safe(f, tmp, &cfg->func_list, list) {
+                       list_del(&f->list);
+                       ret = usb_add_function(c, f);
+-                      if (ret)
++                      if (ret) {
++                              list_add(&f->list, &cfg->func_list);
+                               goto err_purge_funcs;
++                      }
+               }
+               usb_ep_autoconfig_reset(cdev->gadget);
+       }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0656-usb-gadget-configfs-add-a-method-to-unregister-the-g.patch b/patches.tizen/0656-usb-gadget-configfs-add-a-method-to-unregister-the-g.patch
new file mode 100644 (file)
index 0000000..b9b87d1
--- /dev/null
@@ -0,0 +1,54 @@
+From 9ab9743e480a3ac334abda56702d3effa2ba7dd2 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Fri, 21 Jun 2013 10:25:27 +0200
+Subject: [PATCH 0656/1302] usb/gadget: configfs: add a method to unregister
+ the gadget
+
+Add a method to unregister the gadget using its config_item.
+
+There can be functions (e.g. mass storage), which in some circumstances
+need the gadget stopped. Add a method of stopping the gadget.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/configfs.c | 8 ++++++++
+ drivers/usb/gadget/configfs.h | 6 ++++++
+ 2 files changed, 14 insertions(+)
+ create mode 100644 drivers/usb/gadget/configfs.h
+
+diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
+index 8f0d614..37e475b 100644
+--- a/drivers/usb/gadget/configfs.c
++++ b/drivers/usb/gadget/configfs.c
+@@ -991,6 +991,14 @@ static struct configfs_subsystem gadget_subsys = {
+       .su_mutex = __MUTEX_INITIALIZER(gadget_subsys.su_mutex),
+ };
++void unregister_gadget_item(struct config_item *item)
++{
++      struct gadget_info *gi = to_gadget_info(item);
++
++      unregister_gadget(gi);
++}
++EXPORT_SYMBOL(unregister_gadget_item);
++
+ static int __init gadget_cfs_init(void)
+ {
+       int ret;
+diff --git a/drivers/usb/gadget/configfs.h b/drivers/usb/gadget/configfs.h
+new file mode 100644
+index 0000000..a7b564a
+--- /dev/null
++++ b/drivers/usb/gadget/configfs.h
+@@ -0,0 +1,6 @@
++#ifndef USB__GADGET__CONFIGFS__H
++#define USB__GADGET__CONFIGFS__H
++
++void unregister_gadget_item(struct config_item *item);
++
++#endif /*  USB__GADGET__CONFIGFS__H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0657-usb-gadget-create-a-utility-module-for-mass_storage.patch b/patches.tizen/0657-usb-gadget-create-a-utility-module-for-mass_storage.patch
new file mode 100644 (file)
index 0000000..5b386a0
--- /dev/null
@@ -0,0 +1,1160 @@
+From 999eab4c72b5afbb59bdb5668a03118ea79e4455 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 3 Jul 2013 14:59:48 +0200
+Subject: [PATCH 0657/1302] usb/gadget: create a utility module for
+ mass_storage
+
+Converting to configfs requires making the f_mass_storage.c a module.
+But first we need to get rid of "#include "storage_common.c".
+This patch makes storage_common.c a separately compiled file, which is
+built as a utility module named u_ms.ko. After all mass storage users are
+converted to the new function interface this module can be eliminated
+by merging it with the mass storage function's module.
+
+USB descriptors are exported so that they can be accessed from
+f_mass_storage.
+
+FSG_VENDOR_ID and FSG_PRODUCT_ID are moved to their only user.
+
+Handling of CONFIG_USB_GADGET_DEBUG_FILES is moved to f_mass_storage.c.
+The fsg_num_buffers static is moved to FSG_MODULE_PARAMETER users, so
+instead of using a global variable the f_mass_storage introduces
+fsg_num_buffers member in fsg_common (and fsg_config).
+
+fsg_strings and fsg_stringtab are moved to f_mass_storage.c.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig          |   6 +
+ drivers/usb/gadget/Makefile         |   2 +
+ drivers/usb/gadget/acm_ms.c         |  17 +-
+ drivers/usb/gadget/f_mass_storage.c |  71 ++++++--
+ drivers/usb/gadget/mass_storage.c   |  25 ++-
+ drivers/usb/gadget/multi.c          |  17 +-
+ drivers/usb/gadget/storage_common.c | 319 ++++++------------------------------
+ drivers/usb/gadget/storage_common.h | 210 ++++++++++++++++++++++++
+ 8 files changed, 382 insertions(+), 285 deletions(-)
+ create mode 100644 drivers/usb/gadget/storage_common.h
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index c240a4a..b5e6c2e 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -537,6 +537,9 @@ config USB_F_SUBSET
+ config USB_F_RNDIS
+       tristate
++config USB_U_MS
++      tristate
++
+ choice
+       tristate "USB Gadget Drivers"
+       default USB_ETH
+@@ -890,6 +893,7 @@ config USB_MASS_STORAGE
+       tristate "Mass Storage Gadget"
+       depends on BLOCK
+       select USB_LIBCOMPOSITE
++      select USB_U_MS
+       help
+         The Mass Storage Gadget acts as a USB Mass Storage disk drive.
+         As its storage repository it can use a regular file or a block
+@@ -1013,6 +1017,7 @@ config USB_G_ACM_MS
+       select USB_LIBCOMPOSITE
+       select USB_U_SERIAL
+       select USB_F_ACM
++      select USB_U_MS
+       help
+         This driver provides two functions in one configuration:
+         a mass storage, and a CDC ACM (serial port) link.
+@@ -1029,6 +1034,7 @@ config USB_G_MULTI
+       select USB_U_ETHER
+       select USB_U_RNDIS
+       select USB_F_ACM
++      select USB_U_MS
+       help
+         The Multifunction Composite Gadget provides Ethernet (RNDIS
+         and/or CDC Ethernet), mass storage and ACM serial link
+diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
+index b417760..3bb34ef 100644
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -60,6 +60,8 @@ usb_f_ecm_subset-y           := f_subset.o
+ obj-$(CONFIG_USB_F_SUBSET)    += usb_f_ecm_subset.o
+ usb_f_rndis-y                 := f_rndis.o
+ obj-$(CONFIG_USB_F_RNDIS)     += usb_f_rndis.o
++u_ms-y                                := storage_common.o
++obj-$(CONFIG_USB_U_MS)                += u_ms.o
+ #
+ # USB gadget drivers
+diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c
+index 4b947bb..992ffb0 100644
+--- a/drivers/usb/gadget/acm_ms.c
++++ b/drivers/usb/gadget/acm_ms.c
+@@ -104,6 +104,20 @@ static struct usb_gadget_strings *dev_strings[] = {
+ /****************************** Configurations ******************************/
+ static struct fsg_module_parameters fsg_mod_data = { .stall = 1 };
++#ifdef CONFIG_USB_GADGET_DEBUG_FILES
++
++static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
++
++#else
++
++/*
++ * Number of buffers we will use.
++ * 2 is usually enough for good buffering pipeline
++ */
++#define fsg_num_buffers       CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
++
++#endif /* CONFIG_USB_DEBUG */
++
+ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
+ static struct fsg_common fsg_common;
+@@ -167,7 +181,8 @@ static int __init acm_ms_bind(struct usb_composite_dev *cdev)
+       void                    *retp;
+       /* set up mass storage function */
+-      retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data);
++      retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data,
++                                    fsg_num_buffers);
+       if (IS_ERR(retp)) {
+               status = PTR_ERR(retp);
+               return PTR_ERR(retp);
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 56f1fd1..163d911 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -228,8 +228,18 @@
+ static const char fsg_string_interface[] = "Mass Storage";
+-#include "storage_common.c"
++#include "storage_common.h"
++/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
++static struct usb_string              fsg_strings[] = {
++      {FSG_STRING_INTERFACE,          fsg_string_interface},
++      {}
++};
++
++static struct usb_gadget_strings      fsg_stringtab = {
++      .language       = 0x0409,               /* en-us */
++      .strings        = fsg_strings,
++};
+ /*-------------------------------------------------------------------------*/
+@@ -268,6 +278,7 @@ struct fsg_common {
+       struct fsg_buffhd       *next_buffhd_to_fill;
+       struct fsg_buffhd       *next_buffhd_to_drain;
+       struct fsg_buffhd       *buffhds;
++      unsigned int            fsg_num_buffers;
+       int                     cmnd_size;
+       u8                      cmnd[MAX_COMMAND_SIZE];
+@@ -332,6 +343,7 @@ struct fsg_config {
+       const char *product_name;               /* 16 characters or less */
+       char                    can_stall;
++      unsigned int            fsg_num_buffers;
+ };
+ struct fsg_dev {
+@@ -2244,7 +2256,7 @@ reset:
+       if (common->fsg) {
+               fsg = common->fsg;
+-              for (i = 0; i < fsg_num_buffers; ++i) {
++              for (i = 0; i < common->fsg_num_buffers; ++i) {
+                       struct fsg_buffhd *bh = &common->buffhds[i];
+                       if (bh->inreq) {
+@@ -2301,7 +2313,7 @@ reset:
+       clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
+       /* Allocate the requests */
+-      for (i = 0; i < fsg_num_buffers; ++i) {
++      for (i = 0; i < common->fsg_num_buffers; ++i) {
+               struct fsg_buffhd       *bh = &common->buffhds[i];
+               rc = alloc_request(common, fsg->bulk_in, &bh->inreq);
+@@ -2370,7 +2382,7 @@ static void handle_exception(struct fsg_common *common)
+       /* Cancel all the pending transfers */
+       if (likely(common->fsg)) {
+-              for (i = 0; i < fsg_num_buffers; ++i) {
++              for (i = 0; i < common->fsg_num_buffers; ++i) {
+                       bh = &common->buffhds[i];
+                       if (bh->inreq_busy)
+                               usb_ep_dequeue(common->fsg->bulk_in, bh->inreq);
+@@ -2382,7 +2394,7 @@ static void handle_exception(struct fsg_common *common)
+               /* Wait until everything is idle */
+               for (;;) {
+                       int num_active = 0;
+-                      for (i = 0; i < fsg_num_buffers; ++i) {
++                      for (i = 0; i < common->fsg_num_buffers; ++i) {
+                               bh = &common->buffhds[i];
+                               num_active += bh->inreq_busy + bh->outreq_busy;
+                       }
+@@ -2405,7 +2417,7 @@ static void handle_exception(struct fsg_common *common)
+        */
+       spin_lock_irq(&common->lock);
+-      for (i = 0; i < fsg_num_buffers; ++i) {
++      for (i = 0; i < common->fsg_num_buffers; ++i) {
+               bh = &common->buffhds[i];
+               bh->state = BUF_STATE_EMPTY;
+       }
+@@ -2607,6 +2619,16 @@ static inline void fsg_common_put(struct fsg_common *common)
+       kref_put(&common->ref, fsg_common_release);
+ }
++/* check if fsg_num_buffers is within a valid range */
++static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
++{
++      if (fsg_num_buffers >= 2 && fsg_num_buffers <= 4)
++              return 0;
++      pr_err("fsg_num_buffers %u is out of range (%d to %d)\n",
++             fsg_num_buffers, 2, 4);
++      return -EINVAL;
++}
++
+ static struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                         struct usb_composite_dev *cdev,
+                                         struct fsg_config *cfg)
+@@ -2618,7 +2640,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
+       int nluns, i, rc;
+       char *pathbuf;
+-      rc = fsg_num_buffers_validate();
++      rc = fsg_num_buffers_validate(cfg->fsg_num_buffers);
+       if (rc != 0)
+               return ERR_PTR(rc);
+@@ -2640,7 +2662,8 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
+               common->free_storage_on_release = 0;
+       }
+-      common->buffhds = kcalloc(fsg_num_buffers,
++      common->fsg_num_buffers = cfg->fsg_num_buffers;
++      common->buffhds = kcalloc(common->fsg_num_buffers,
+                                 sizeof *(common->buffhds), GFP_KERNEL);
+       if (!common->buffhds) {
+               if (common->free_storage_on_release)
+@@ -2727,7 +2750,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
+       /* Data buffers cyclic list */
+       bh = common->buffhds;
+-      i = fsg_num_buffers;
++      i = common->fsg_num_buffers;
+       goto buffhds_first_it;
+       do {
+               bh->next = bh + 1;
+@@ -2847,7 +2870,7 @@ static void fsg_common_release(struct kref *ref)
+       {
+               struct fsg_buffhd *bh = common->buffhds;
+-              unsigned i = fsg_num_buffers;
++              unsigned i = common->fsg_num_buffers;
+               do {
+                       kfree(bh->buf);
+               } while (++bh, --i);
+@@ -3009,7 +3032,7 @@ struct fsg_module_parameters {
+                          S_IRUGO);                                    \
+       MODULE_PARM_DESC(prefix ## name, desc)
+-#define FSG_MODULE_PARAMETERS(prefix, params)                         \
++#define __FSG_MODULE_PARAMETERS(prefix, params)                               \
+       _FSG_MODULE_PARAM_ARRAY(prefix, params, file, charp,            \
+                               "names of backing files or devices");   \
+       _FSG_MODULE_PARAM_ARRAY(prefix, params, ro, bool,               \
+@@ -3025,9 +3048,24 @@ struct fsg_module_parameters {
+       _FSG_MODULE_PARAM(prefix, params, stall, bool,                  \
+                         "false to prevent bulk stalls")
++#ifdef CONFIG_USB_GADGET_DEBUG_FILES
++
++#define FSG_MODULE_PARAMETERS(prefix, params)                         \
++      __FSG_MODULE_PARAMETERS(prefix, params);                        \
++      module_param_named(num_buffers, fsg_num_buffers, uint, S_IRUGO);\
++      MODULE_PARM_DESC(num_buffers, "Number of pipeline buffers")
++#else
++
++#define FSG_MODULE_PARAMETERS(prefix, params)                         \
++      __FSG_MODULE_PARAMETERS(prefix, params)
++
++#endif
++
++
+ static void
+ fsg_config_from_params(struct fsg_config *cfg,
+-                     const struct fsg_module_parameters *params)
++                     const struct fsg_module_parameters *params,
++                     unsigned int fsg_num_buffers)
+ {
+       struct fsg_lun_config *lun;
+       unsigned i;
+@@ -3055,19 +3093,22 @@ fsg_config_from_params(struct fsg_config *cfg,
+       /* Finalise */
+       cfg->can_stall = params->stall;
++      cfg->fsg_num_buffers = fsg_num_buffers;
+ }
+ static inline struct fsg_common *
+ fsg_common_from_params(struct fsg_common *common,
+                      struct usb_composite_dev *cdev,
+-                     const struct fsg_module_parameters *params)
++                     const struct fsg_module_parameters *params,
++                     unsigned int fsg_num_buffers)
+       __attribute__((unused));
+ static inline struct fsg_common *
+ fsg_common_from_params(struct fsg_common *common,
+                      struct usb_composite_dev *cdev,
+-                     const struct fsg_module_parameters *params)
++                     const struct fsg_module_parameters *params,
++                     unsigned int fsg_num_buffers)
+ {
+       struct fsg_config cfg;
+-      fsg_config_from_params(&cfg, params);
++      fsg_config_from_params(&cfg, params, fsg_num_buffers);
+       return fsg_common_init(common, cdev, &cfg);
+ }
+diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c
+index 080e577..bf60a9a 100644
+--- a/drivers/usb/gadget/mass_storage.c
++++ b/drivers/usb/gadget/mass_storage.c
+@@ -37,6 +37,15 @@
+ #define DRIVER_DESC           "Mass Storage Gadget"
+ #define DRIVER_VERSION                "2009/09/11"
++/*
++ * Thanks to NetChip Technologies for donating this product ID.
++ *
++ * DO NOT REUSE THESE IDs with any other driver!!  Ever!!
++ * Instead:  allocate your own, using normal USB-IF procedures.
++ */
++#define FSG_VENDOR_ID 0x0525  /* NetChip */
++#define FSG_PRODUCT_ID        0xa4a5  /* Linux-USB File-backed Storage Gadget */
++
+ /*-------------------------------------------------------------------------*/
+ /*
+@@ -102,6 +111,20 @@ static struct usb_gadget_strings *dev_strings[] = {
+ static struct fsg_module_parameters mod_data = {
+       .stall = 1
+ };
++#ifdef CONFIG_USB_GADGET_DEBUG_FILES
++
++static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
++
++#else
++
++/*
++ * Number of buffers we will use.
++ * 2 is usually enough for good buffering pipeline
++ */
++#define fsg_num_buffers       CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
++
++#endif /* CONFIG_USB_DEBUG */
++
+ FSG_MODULE_PARAMETERS(/* no prefix */, mod_data);
+ static unsigned long msg_registered;
+@@ -129,7 +152,7 @@ static int __init msg_do_config(struct usb_configuration *c)
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+-      fsg_config_from_params(&config, &mod_data);
++      fsg_config_from_params(&config, &mod_data, fsg_num_buffers);
+       config.ops = &ops;
+       retp = fsg_common_init(&common, c->cdev, &config);
+diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
+index 2a1ebef..f610d01 100644
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -132,6 +132,20 @@ static struct usb_gadget_strings *dev_strings[] = {
+ /****************************** Configurations ******************************/
+ static struct fsg_module_parameters fsg_mod_data = { .stall = 1 };
++#ifdef CONFIG_USB_GADGET_DEBUG_FILES
++
++static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
++
++#else
++
++/*
++ * Number of buffers we will use.
++ * 2 is usually enough for good buffering pipeline
++ */
++#define fsg_num_buffers       CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
++
++#endif /* CONFIG_USB_DEBUG */
++
+ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
+ static struct fsg_common fsg_common;
+@@ -294,7 +308,8 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
+       /* set up mass storage function */
+       {
+               void *retp;
+-              retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data);
++              retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data,
++                                            fsg_num_buffers);
+               if (IS_ERR(retp)) {
+                       status = PTR_ERR(retp);
+                       goto fail1;
+diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
+index dbce3a9..942324c 100644
+--- a/drivers/usb/gadget/storage_common.c
++++ b/drivers/usb/gadget/storage_common.c
+@@ -23,242 +23,22 @@
+  * The valid range of num_buffers is: num >= 2 && num <= 4.
+  */
++#include <linux/module.h>
++#include <linux/blkdev.h>
++#include <linux/file.h>
++#include <linux/fs.h>
++#include <linux/usb/composite.h>
+-#include <linux/usb/storage.h>
+-#include <scsi/scsi.h>
+-#include <asm/unaligned.h>
+-
+-
+-/*
+- * Thanks to NetChip Technologies for donating this product ID.
+- *
+- * DO NOT REUSE THESE IDs with any other driver!!  Ever!!
+- * Instead:  allocate your own, using normal USB-IF procedures.
+- */
+-#define FSG_VENDOR_ID 0x0525  /* NetChip */
+-#define FSG_PRODUCT_ID        0xa4a5  /* Linux-USB File-backed Storage Gadget */
+-
+-
+-/*-------------------------------------------------------------------------*/
+-
+-
+-#ifndef DEBUG
+-#undef VERBOSE_DEBUG
+-#undef DUMP_MSGS
+-#endif /* !DEBUG */
+-
+-#ifdef VERBOSE_DEBUG
+-#define VLDBG LDBG
+-#else
+-#define VLDBG(lun, fmt, args...) do { } while (0)
+-#endif /* VERBOSE_DEBUG */
+-
+-#define LDBG(lun, fmt, args...)   dev_dbg (&(lun)->dev, fmt, ## args)
+-#define LERROR(lun, fmt, args...) dev_err (&(lun)->dev, fmt, ## args)
+-#define LWARN(lun, fmt, args...)  dev_warn(&(lun)->dev, fmt, ## args)
+-#define LINFO(lun, fmt, args...)  dev_info(&(lun)->dev, fmt, ## args)
+-
+-
+-#ifdef DUMP_MSGS
+-
+-#  define dump_msg(fsg, /* const char * */ label,                     \
+-                 /* const u8 * */ buf, /* unsigned */ length) do {    \
+-      if (length < 512) {                                             \
+-              DBG(fsg, "%s, length %u:\n", label, length);            \
+-              print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET,      \
+-                             16, 1, buf, length, 0);                  \
+-      }                                                               \
+-} while (0)
+-
+-#  define dump_cdb(fsg) do { } while (0)
+-
+-#else
+-
+-#  define dump_msg(fsg, /* const char * */ label, \
+-                 /* const u8 * */ buf, /* unsigned */ length) do { } while (0)
+-
+-#  ifdef VERBOSE_DEBUG
+-
+-#    define dump_cdb(fsg)                                             \
+-      print_hex_dump(KERN_DEBUG, "SCSI CDB: ", DUMP_PREFIX_NONE,      \
+-                     16, 1, (fsg)->cmnd, (fsg)->cmnd_size, 0)         \
+-
+-#  else
+-
+-#    define dump_cdb(fsg) do { } while (0)
+-
+-#  endif /* VERBOSE_DEBUG */
+-
+-#endif /* DUMP_MSGS */
+-
+-/*-------------------------------------------------------------------------*/
+-
+-/* Length of a SCSI Command Data Block */
+-#define MAX_COMMAND_SIZE      16
+-
+-/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */
+-#define SS_NO_SENSE                           0
+-#define SS_COMMUNICATION_FAILURE              0x040800
+-#define SS_INVALID_COMMAND                    0x052000
+-#define SS_INVALID_FIELD_IN_CDB                       0x052400
+-#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x052100
+-#define SS_LOGICAL_UNIT_NOT_SUPPORTED         0x052500
+-#define SS_MEDIUM_NOT_PRESENT                 0x023a00
+-#define SS_MEDIUM_REMOVAL_PREVENTED           0x055302
+-#define SS_NOT_READY_TO_READY_TRANSITION      0x062800
+-#define SS_RESET_OCCURRED                     0x062900
+-#define SS_SAVING_PARAMETERS_NOT_SUPPORTED    0x053900
+-#define SS_UNRECOVERED_READ_ERROR             0x031100
+-#define SS_WRITE_ERROR                                0x030c02
+-#define SS_WRITE_PROTECTED                    0x072700
+-
+-#define SK(x)         ((u8) ((x) >> 16))      /* Sense Key byte, etc. */
+-#define ASC(x)                ((u8) ((x) >> 8))
+-#define ASCQ(x)               ((u8) (x))
+-
+-
+-/*-------------------------------------------------------------------------*/
+-
+-
+-struct fsg_lun {
+-      struct file     *filp;
+-      loff_t          file_length;
+-      loff_t          num_sectors;
+-
+-      unsigned int    initially_ro:1;
+-      unsigned int    ro:1;
+-      unsigned int    removable:1;
+-      unsigned int    cdrom:1;
+-      unsigned int    prevent_medium_removal:1;
+-      unsigned int    registered:1;
+-      unsigned int    info_valid:1;
+-      unsigned int    nofua:1;
+-
+-      u32             sense_data;
+-      u32             sense_data_info;
+-      u32             unit_attention_data;
+-
+-      unsigned int    blkbits;        /* Bits of logical block size of bound block device */
+-      unsigned int    blksize;        /* logical block size of bound block device */
+-      struct device   dev;
+-};
+-
+-static inline bool fsg_lun_is_open(struct fsg_lun *curlun)
+-{
+-      return curlun->filp != NULL;
+-}
++#include "storage_common.h"
+ static inline struct fsg_lun *fsg_lun_from_dev(struct device *dev)
+ {
+       return container_of(dev, struct fsg_lun, dev);
+ }
+-
+-/* Big enough to hold our biggest descriptor */
+-#define EP0_BUFSIZE   256
+-#define DELAYED_STATUS        (EP0_BUFSIZE + 999)     /* An impossibly large value */
+-
+-#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+-
+-static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
+-module_param_named(num_buffers, fsg_num_buffers, uint, S_IRUGO);
+-MODULE_PARM_DESC(num_buffers, "Number of pipeline buffers");
+-
+-#else
+-
+-/*
+- * Number of buffers we will use.
+- * 2 is usually enough for good buffering pipeline
+- */
+-#define fsg_num_buffers       CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
+-
+-#endif /* CONFIG_USB_DEBUG */
+-
+-/* check if fsg_num_buffers is within a valid range */
+-static inline int fsg_num_buffers_validate(void)
+-{
+-      if (fsg_num_buffers >= 2 && fsg_num_buffers <= 4)
+-              return 0;
+-      pr_err("fsg_num_buffers %u is out of range (%d to %d)\n",
+-             fsg_num_buffers, 2 ,4);
+-      return -EINVAL;
+-}
+-
+-/* Default size of buffer length. */
+-#define FSG_BUFLEN    ((u32)16384)
+-
+-/* Maximal number of LUNs supported in mass storage function */
+-#define FSG_MAX_LUNS  8
+-
+-enum fsg_buffer_state {
+-      BUF_STATE_EMPTY = 0,
+-      BUF_STATE_FULL,
+-      BUF_STATE_BUSY
+-};
+-
+-struct fsg_buffhd {
+-      void                            *buf;
+-      enum fsg_buffer_state           state;
+-      struct fsg_buffhd               *next;
+-
+-      /*
+-       * The NetChip 2280 is faster, and handles some protocol faults
+-       * better, if we don't submit any short bulk-out read requests.
+-       * So we will record the intended request length here.
+-       */
+-      unsigned int                    bulk_out_intended_length;
+-
+-      struct usb_request              *inreq;
+-      int                             inreq_busy;
+-      struct usb_request              *outreq;
+-      int                             outreq_busy;
+-};
+-
+-enum fsg_state {
+-      /* This one isn't used anywhere */
+-      FSG_STATE_COMMAND_PHASE = -10,
+-      FSG_STATE_DATA_PHASE,
+-      FSG_STATE_STATUS_PHASE,
+-
+-      FSG_STATE_IDLE = 0,
+-      FSG_STATE_ABORT_BULK_OUT,
+-      FSG_STATE_RESET,
+-      FSG_STATE_INTERFACE_CHANGE,
+-      FSG_STATE_CONFIG_CHANGE,
+-      FSG_STATE_DISCONNECT,
+-      FSG_STATE_EXIT,
+-      FSG_STATE_TERMINATED
+-};
+-
+-enum data_direction {
+-      DATA_DIR_UNKNOWN = 0,
+-      DATA_DIR_FROM_HOST,
+-      DATA_DIR_TO_HOST,
+-      DATA_DIR_NONE
+-};
+-
+-
+-/*-------------------------------------------------------------------------*/
+-
+-
+-static inline u32 get_unaligned_be24(u8 *buf)
+-{
+-      return 0xffffff & (u32) get_unaligned_be32(buf - 1);
+-}
+-
+-
+-/*-------------------------------------------------------------------------*/
+-
+-
+-enum {
+-      FSG_STRING_INTERFACE
+-};
+-
+-
+ /* There is only one interface. */
+-static struct usb_interface_descriptor
+-fsg_intf_desc = {
++struct usb_interface_descriptor fsg_intf_desc = {
+       .bLength =              sizeof fsg_intf_desc,
+       .bDescriptorType =      USB_DT_INTERFACE,
+@@ -268,14 +48,14 @@ fsg_intf_desc = {
+       .bInterfaceProtocol =   USB_PR_BULK,    /* Adjusted during fsg_bind() */
+       .iInterface =           FSG_STRING_INTERFACE,
+ };
++EXPORT_SYMBOL(fsg_intf_desc);
+ /*
+  * Three full-speed endpoint descriptors: bulk-in, bulk-out, and
+  * interrupt-in.
+  */
+-static struct usb_endpoint_descriptor
+-fsg_fs_bulk_in_desc = {
++struct usb_endpoint_descriptor fsg_fs_bulk_in_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -283,9 +63,9 @@ fsg_fs_bulk_in_desc = {
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       /* wMaxPacketSize set by autoconfiguration */
+ };
++EXPORT_SYMBOL(fsg_fs_bulk_in_desc);
+-static struct usb_endpoint_descriptor
+-fsg_fs_bulk_out_desc = {
++struct usb_endpoint_descriptor fsg_fs_bulk_out_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -293,13 +73,15 @@ fsg_fs_bulk_out_desc = {
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       /* wMaxPacketSize set by autoconfiguration */
+ };
++EXPORT_SYMBOL(fsg_fs_bulk_out_desc);
+-static struct usb_descriptor_header *fsg_fs_function[] = {
++struct usb_descriptor_header *fsg_fs_function[] = {
+       (struct usb_descriptor_header *) &fsg_intf_desc,
+       (struct usb_descriptor_header *) &fsg_fs_bulk_in_desc,
+       (struct usb_descriptor_header *) &fsg_fs_bulk_out_desc,
+       NULL,
+ };
++EXPORT_SYMBOL(fsg_fs_function);
+ /*
+@@ -310,8 +92,7 @@ static struct usb_descriptor_header *fsg_fs_function[] = {
+  * and a "device qualifier" ... plus more construction options
+  * for the configuration descriptor.
+  */
+-static struct usb_endpoint_descriptor
+-fsg_hs_bulk_in_desc = {
++struct usb_endpoint_descriptor fsg_hs_bulk_in_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -319,9 +100,9 @@ fsg_hs_bulk_in_desc = {
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       cpu_to_le16(512),
+ };
++EXPORT_SYMBOL(fsg_hs_bulk_in_desc);
+-static struct usb_endpoint_descriptor
+-fsg_hs_bulk_out_desc = {
++struct usb_endpoint_descriptor fsg_hs_bulk_out_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -330,17 +111,18 @@ fsg_hs_bulk_out_desc = {
+       .wMaxPacketSize =       cpu_to_le16(512),
+       .bInterval =            1,      /* NAK every 1 uframe */
+ };
++EXPORT_SYMBOL(fsg_hs_bulk_out_desc);
+-static struct usb_descriptor_header *fsg_hs_function[] = {
++struct usb_descriptor_header *fsg_hs_function[] = {
+       (struct usb_descriptor_header *) &fsg_intf_desc,
+       (struct usb_descriptor_header *) &fsg_hs_bulk_in_desc,
+       (struct usb_descriptor_header *) &fsg_hs_bulk_out_desc,
+       NULL,
+ };
++EXPORT_SYMBOL(fsg_hs_function);
+-static struct usb_endpoint_descriptor
+-fsg_ss_bulk_in_desc = {
++struct usb_endpoint_descriptor fsg_ss_bulk_in_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -348,16 +130,17 @@ fsg_ss_bulk_in_desc = {
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       cpu_to_le16(1024),
+ };
++EXPORT_SYMBOL(fsg_ss_bulk_in_desc);
+-static struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc = {
++struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc = {
+       .bLength =              sizeof(fsg_ss_bulk_in_comp_desc),
+       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
+       /*.bMaxBurst =          DYNAMIC, */
+ };
++EXPORT_SYMBOL(fsg_ss_bulk_in_comp_desc);
+-static struct usb_endpoint_descriptor
+-fsg_ss_bulk_out_desc = {
++struct usb_endpoint_descriptor fsg_ss_bulk_out_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -365,15 +148,17 @@ fsg_ss_bulk_out_desc = {
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       cpu_to_le16(1024),
+ };
++EXPORT_SYMBOL(fsg_ss_bulk_out_desc);
+-static struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = {
++struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = {
+       .bLength =              sizeof(fsg_ss_bulk_in_comp_desc),
+       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
+       /*.bMaxBurst =          DYNAMIC, */
+ };
++EXPORT_SYMBOL(fsg_ss_bulk_out_comp_desc);
+-static struct usb_descriptor_header *fsg_ss_function[] = {
++struct usb_descriptor_header *fsg_ss_function[] = {
+       (struct usb_descriptor_header *) &fsg_intf_desc,
+       (struct usb_descriptor_header *) &fsg_ss_bulk_in_desc,
+       (struct usb_descriptor_header *) &fsg_ss_bulk_in_comp_desc,
+@@ -381,17 +166,7 @@ static struct usb_descriptor_header *fsg_ss_function[] = {
+       (struct usb_descriptor_header *) &fsg_ss_bulk_out_comp_desc,
+       NULL,
+ };
+-
+-/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
+-static struct usb_string              fsg_strings[] = {
+-      {FSG_STRING_INTERFACE,          fsg_string_interface},
+-      {}
+-};
+-
+-static struct usb_gadget_strings      fsg_stringtab = {
+-      .language       = 0x0409,               /* en-us */
+-      .strings        = fsg_strings,
+-};
++EXPORT_SYMBOL(fsg_ss_function);
+  /*-------------------------------------------------------------------------*/
+@@ -401,7 +176,7 @@ static struct usb_gadget_strings   fsg_stringtab = {
+  * the caller must own fsg->filesem for writing.
+  */
+-static void fsg_lun_close(struct fsg_lun *curlun)
++void fsg_lun_close(struct fsg_lun *curlun)
+ {
+       if (curlun->filp) {
+               LDBG(curlun, "close backing file\n");
+@@ -409,9 +184,9 @@ static void fsg_lun_close(struct fsg_lun *curlun)
+               curlun->filp = NULL;
+       }
+ }
++EXPORT_SYMBOL(fsg_lun_close);
+-
+-static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
++int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
+ {
+       int                             ro;
+       struct file                     *filp = NULL;
+@@ -508,6 +283,7 @@ out:
+       fput(filp);
+       return rc;
+ }
++EXPORT_SYMBOL(fsg_lun_open);
+ /*-------------------------------------------------------------------------*/
+@@ -516,7 +292,7 @@ out:
+  * Sync the file data, don't bother with the metadata.
+  * This code was copied from fs/buffer.c:sys_fdatasync().
+  */
+-static int fsg_lun_fsync_sub(struct fsg_lun *curlun)
++int fsg_lun_fsync_sub(struct fsg_lun *curlun)
+ {
+       struct file     *filp = curlun->filp;
+@@ -524,8 +300,9 @@ static int fsg_lun_fsync_sub(struct fsg_lun *curlun)
+               return 0;
+       return vfs_fsync(filp, 1);
+ }
++EXPORT_SYMBOL(fsg_lun_fsync_sub);
+-static void store_cdrom_address(u8 *dest, int msf, u32 addr)
++void store_cdrom_address(u8 *dest, int msf, u32 addr)
+ {
+       if (msf) {
+               /* Convert to Minutes-Seconds-Frames */
+@@ -542,12 +319,12 @@ static void store_cdrom_address(u8 *dest, int msf, u32 addr)
+               put_unaligned_be32(addr, dest);
+       }
+ }
+-
++EXPORT_SYMBOL(store_cdrom_address);
+ /*-------------------------------------------------------------------------*/
+-static ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr,
++ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr,
+                          char *buf)
+ {
+       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+@@ -556,16 +333,18 @@ static ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr,
+                                 ? curlun->ro
+                                 : curlun->initially_ro);
+ }
++EXPORT_SYMBOL(fsg_show_ro);
+-static ssize_t fsg_show_nofua(struct device *dev, struct device_attribute *attr,
++ssize_t fsg_show_nofua(struct device *dev, struct device_attribute *attr,
+                             char *buf)
+ {
+       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+       return sprintf(buf, "%u\n", curlun->nofua);
+ }
++EXPORT_SYMBOL(fsg_show_nofua);
+-static ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
++ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
+                            char *buf)
+ {
+       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+@@ -591,9 +370,10 @@ static ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
+       up_read(filesem);
+       return rc;
+ }
++EXPORT_SYMBOL(fsg_show_file);
+-static ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr,
++ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr,
+                           const char *buf, size_t count)
+ {
+       ssize_t         rc;
+@@ -622,8 +402,9 @@ static ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr,
+       up_read(filesem);
+       return rc;
+ }
++EXPORT_SYMBOL(fsg_store_ro);
+-static ssize_t fsg_store_nofua(struct device *dev,
++ssize_t fsg_store_nofua(struct device *dev,
+                              struct device_attribute *attr,
+                              const char *buf, size_t count)
+ {
+@@ -643,8 +424,9 @@ static ssize_t fsg_store_nofua(struct device *dev,
+       return count;
+ }
++EXPORT_SYMBOL(fsg_store_nofua);
+-static ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr,
++ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr,
+                             const char *buf, size_t count)
+ {
+       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+@@ -675,3 +457,6 @@ static ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr,
+       up_write(filesem);
+       return (rc < 0 ? rc : count);
+ }
++EXPORT_SYMBOL(fsg_store_file);
++
++MODULE_LICENSE("GPL");
+diff --git a/drivers/usb/gadget/storage_common.h b/drivers/usb/gadget/storage_common.h
+new file mode 100644
+index 0000000..1fcda2b
+--- /dev/null
++++ b/drivers/usb/gadget/storage_common.h
+@@ -0,0 +1,210 @@
++#ifndef USB_STORAGE_COMMON_H
++#define USB_STORAGE_COMMON_H
++
++#include <linux/device.h>
++#include <linux/usb/storage.h>
++#include <scsi/scsi.h>
++#include <asm/unaligned.h>
++
++#ifndef DEBUG
++#undef VERBOSE_DEBUG
++#undef DUMP_MSGS
++#endif /* !DEBUG */
++
++#ifdef VERBOSE_DEBUG
++#define VLDBG LDBG
++#else
++#define VLDBG(lun, fmt, args...) do { } while (0)
++#endif /* VERBOSE_DEBUG */
++
++#define LDBG(lun, fmt, args...)   dev_dbg(&(lun)->dev, fmt, ## args)
++#define LERROR(lun, fmt, args...) dev_err(&(lun)->dev, fmt, ## args)
++#define LWARN(lun, fmt, args...)  dev_warn(&(lun)->dev, fmt, ## args)
++#define LINFO(lun, fmt, args...)  dev_info(&(lun)->dev, fmt, ## args)
++
++#ifdef DUMP_MSGS
++
++#  define dump_msg(fsg, /* const char * */ label,                     \
++                 /* const u8 * */ buf, /* unsigned */ length)         \
++do {                                                                  \
++      if (length < 512) {                                             \
++              DBG(fsg, "%s, length %u:\n", label, length);            \
++              print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET,      \
++                             16, 1, buf, length, 0);                  \
++      }                                                               \
++} while (0)
++
++#  define dump_cdb(fsg) do { } while (0)
++
++#else
++
++#  define dump_msg(fsg, /* const char * */ label, \
++                 /* const u8 * */ buf, /* unsigned */ length) do { } while (0)
++
++#  ifdef VERBOSE_DEBUG
++
++#    define dump_cdb(fsg)                                             \
++      print_hex_dump(KERN_DEBUG, "SCSI CDB: ", DUMP_PREFIX_NONE,      \
++                     16, 1, (fsg)->cmnd, (fsg)->cmnd_size, 0)         \
++
++#  else
++
++#    define dump_cdb(fsg) do { } while (0)
++
++#  endif /* VERBOSE_DEBUG */
++
++#endif /* DUMP_MSGS */
++
++/* Length of a SCSI Command Data Block */
++#define MAX_COMMAND_SIZE      16
++
++/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */
++#define SS_NO_SENSE                           0
++#define SS_COMMUNICATION_FAILURE              0x040800
++#define SS_INVALID_COMMAND                    0x052000
++#define SS_INVALID_FIELD_IN_CDB                       0x052400
++#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x052100
++#define SS_LOGICAL_UNIT_NOT_SUPPORTED         0x052500
++#define SS_MEDIUM_NOT_PRESENT                 0x023a00
++#define SS_MEDIUM_REMOVAL_PREVENTED           0x055302
++#define SS_NOT_READY_TO_READY_TRANSITION      0x062800
++#define SS_RESET_OCCURRED                     0x062900
++#define SS_SAVING_PARAMETERS_NOT_SUPPORTED    0x053900
++#define SS_UNRECOVERED_READ_ERROR             0x031100
++#define SS_WRITE_ERROR                                0x030c02
++#define SS_WRITE_PROTECTED                    0x072700
++
++#define SK(x)         ((u8) ((x) >> 16))      /* Sense Key byte, etc. */
++#define ASC(x)                ((u8) ((x) >> 8))
++#define ASCQ(x)               ((u8) (x))
++
++struct fsg_lun {
++      struct file     *filp;
++      loff_t          file_length;
++      loff_t          num_sectors;
++
++      unsigned int    initially_ro:1;
++      unsigned int    ro:1;
++      unsigned int    removable:1;
++      unsigned int    cdrom:1;
++      unsigned int    prevent_medium_removal:1;
++      unsigned int    registered:1;
++      unsigned int    info_valid:1;
++      unsigned int    nofua:1;
++
++      u32             sense_data;
++      u32             sense_data_info;
++      u32             unit_attention_data;
++
++      unsigned int    blkbits; /* Bits of logical block size
++                                                     of bound block device */
++      unsigned int    blksize; /* logical block size of bound block device */
++      struct device   dev;
++};
++
++static inline bool fsg_lun_is_open(struct fsg_lun *curlun)
++{
++      return curlun->filp != NULL;
++}
++
++/* Big enough to hold our biggest descriptor */
++#define EP0_BUFSIZE   256
++#define DELAYED_STATUS        (EP0_BUFSIZE + 999)     /* An impossibly large value */
++
++/* Default size of buffer length. */
++#define FSG_BUFLEN    ((u32)16384)
++
++/* Maximal number of LUNs supported in mass storage function */
++#define FSG_MAX_LUNS  8
++
++enum fsg_buffer_state {
++      BUF_STATE_EMPTY = 0,
++      BUF_STATE_FULL,
++      BUF_STATE_BUSY
++};
++
++struct fsg_buffhd {
++      void                            *buf;
++      enum fsg_buffer_state           state;
++      struct fsg_buffhd               *next;
++
++      /*
++       * The NetChip 2280 is faster, and handles some protocol faults
++       * better, if we don't submit any short bulk-out read requests.
++       * So we will record the intended request length here.
++       */
++      unsigned int                    bulk_out_intended_length;
++
++      struct usb_request              *inreq;
++      int                             inreq_busy;
++      struct usb_request              *outreq;
++      int                             outreq_busy;
++};
++
++enum fsg_state {
++      /* This one isn't used anywhere */
++      FSG_STATE_COMMAND_PHASE = -10,
++      FSG_STATE_DATA_PHASE,
++      FSG_STATE_STATUS_PHASE,
++
++      FSG_STATE_IDLE = 0,
++      FSG_STATE_ABORT_BULK_OUT,
++      FSG_STATE_RESET,
++      FSG_STATE_INTERFACE_CHANGE,
++      FSG_STATE_CONFIG_CHANGE,
++      FSG_STATE_DISCONNECT,
++      FSG_STATE_EXIT,
++      FSG_STATE_TERMINATED
++};
++
++enum data_direction {
++      DATA_DIR_UNKNOWN = 0,
++      DATA_DIR_FROM_HOST,
++      DATA_DIR_TO_HOST,
++      DATA_DIR_NONE
++};
++
++static inline u32 get_unaligned_be24(u8 *buf)
++{
++      return 0xffffff & (u32) get_unaligned_be32(buf - 1);
++}
++
++enum {
++      FSG_STRING_INTERFACE
++};
++
++extern struct usb_interface_descriptor fsg_intf_desc;
++
++extern struct usb_endpoint_descriptor fsg_fs_bulk_in_desc;
++extern struct usb_endpoint_descriptor fsg_fs_bulk_out_desc;
++extern struct usb_descriptor_header *fsg_fs_function[];
++
++extern struct usb_endpoint_descriptor fsg_hs_bulk_in_desc;
++extern struct usb_endpoint_descriptor fsg_hs_bulk_out_desc;
++extern struct usb_descriptor_header *fsg_hs_function[];
++
++extern struct usb_endpoint_descriptor fsg_ss_bulk_in_desc;
++extern struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc;
++extern struct usb_endpoint_descriptor fsg_ss_bulk_out_desc;
++extern struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc;
++extern struct usb_descriptor_header *fsg_ss_function[];
++
++void fsg_lun_close(struct fsg_lun *curlun);
++int fsg_lun_open(struct fsg_lun *curlun, const char *filename);
++int fsg_lun_fsync_sub(struct fsg_lun *curlun);
++void store_cdrom_address(u8 *dest, int msf, u32 addr);
++ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr,
++                  char *buf);
++ssize_t fsg_show_nofua(struct device *dev, struct device_attribute *attr,
++                     char *buf);
++ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
++                    char *buf);
++ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr,
++                   const char *buf, size_t count);
++ssize_t fsg_store_nofua(struct device *dev,
++                      struct device_attribute *attr,
++                      const char *buf, size_t count);
++ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr,
++                     const char *buf, size_t count);
++
++#endif /* USB_STORAGE_COMMON_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0658-usb-gadget-f_mass_storage-factor-out-a-header-file.patch b/patches.tizen/0658-usb-gadget-f_mass_storage-factor-out-a-header-file.patch
new file mode 100644 (file)
index 0000000..b8fcc15
--- /dev/null
@@ -0,0 +1,326 @@
+From aa42314c87dd9ba2b17aa1cb49d76d95d988dffe Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 6 Jun 2013 13:06:24 +0200
+Subject: [PATCH 0658/1302] usb/gadget: f_mass_storage: factor out a header
+ file
+
+In order to prepare for the new function interface the f_mass_storage.c
+needs to be compiled as a module, and so a header file will be required.
+This patch factors out some code to a new f_mass_storage.h.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 117 ++-------------------------------
+ drivers/usb/gadget/f_mass_storage.h | 126 ++++++++++++++++++++++++++++++++++++
+ 2 files changed, 133 insertions(+), 110 deletions(-)
+ create mode 100644 drivers/usb/gadget/f_mass_storage.h
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 163d911..c36e208 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -229,6 +229,7 @@
+ static const char fsg_string_interface[] = "Mass Storage";
+ #include "storage_common.h"
++#include "f_mass_storage.h"
+ /* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
+ static struct usb_string              fsg_strings[] = {
+@@ -246,18 +247,6 @@ static struct usb_gadget_strings  fsg_stringtab = {
+ struct fsg_dev;
+ struct fsg_common;
+-/* FSF callback functions */
+-struct fsg_operations {
+-      /*
+-       * Callback function to call when thread exits.  If no
+-       * callback is set or it returns value lower then zero MSF
+-       * will force eject all LUNs it operates on (including those
+-       * marked as non-removable or with prevent_medium_removal flag
+-       * set).
+-       */
+-      int (*thread_exits)(struct fsg_common *common);
+-};
+-
+ /* Data shared by all the FSG instances. */
+ struct fsg_common {
+       struct usb_gadget       *gadget;
+@@ -324,28 +313,6 @@ struct fsg_common {
+       struct kref             ref;
+ };
+-struct fsg_config {
+-      unsigned nluns;
+-      struct fsg_lun_config {
+-              const char *filename;
+-              char ro;
+-              char removable;
+-              char cdrom;
+-              char nofua;
+-      } luns[FSG_MAX_LUNS];
+-
+-      /* Callback functions. */
+-      const struct fsg_operations     *ops;
+-      /* Gadget's private data. */
+-      void                    *private_data;
+-
+-      const char *vendor_name;                /*  8 characters or less */
+-      const char *product_name;               /* 16 characters or less */
+-
+-      char                    can_stall;
+-      unsigned int            fsg_num_buffers;
+-};
+-
+ struct fsg_dev {
+       struct usb_function     function;
+       struct usb_gadget       *gadget;        /* Copy of cdev->gadget */
+@@ -2609,12 +2576,12 @@ static void fsg_lun_release(struct device *dev)
+       /* Nothing needs to be done */
+ }
+-static inline void fsg_common_get(struct fsg_common *common)
++void fsg_common_get(struct fsg_common *common)
+ {
+       kref_get(&common->ref);
+ }
+-static inline void fsg_common_put(struct fsg_common *common)
++void fsg_common_put(struct fsg_common *common)
+ {
+       kref_put(&common->ref, fsg_common_release);
+ }
+@@ -2629,9 +2596,9 @@ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
+       return -EINVAL;
+ }
+-static struct fsg_common *fsg_common_init(struct fsg_common *common,
+-                                        struct usb_composite_dev *cdev,
+-                                        struct fsg_config *cfg)
++struct fsg_common *fsg_common_init(struct fsg_common *common,
++                                 struct usb_composite_dev *cdev,
++                                 struct fsg_config *cfg)
+ {
+       struct usb_gadget *gadget = cdev->gadget;
+       struct fsg_buffhd *bh;
+@@ -3008,62 +2975,8 @@ static int fsg_bind_config(struct usb_composite_dev *cdev,
+ /************************* Module parameters *************************/
+-struct fsg_module_parameters {
+-      char            *file[FSG_MAX_LUNS];
+-      bool            ro[FSG_MAX_LUNS];
+-      bool            removable[FSG_MAX_LUNS];
+-      bool            cdrom[FSG_MAX_LUNS];
+-      bool            nofua[FSG_MAX_LUNS];
+-
+-      unsigned int    file_count, ro_count, removable_count, cdrom_count;
+-      unsigned int    nofua_count;
+-      unsigned int    luns;   /* nluns */
+-      bool            stall;  /* can_stall */
+-};
+-
+-#define _FSG_MODULE_PARAM_ARRAY(prefix, params, name, type, desc)     \
+-      module_param_array_named(prefix ## name, params.name, type,     \
+-                               &prefix ## params.name ## _count,      \
+-                               S_IRUGO);                              \
+-      MODULE_PARM_DESC(prefix ## name, desc)
+-
+-#define _FSG_MODULE_PARAM(prefix, params, name, type, desc)           \
+-      module_param_named(prefix ## name, params.name, type,           \
+-                         S_IRUGO);                                    \
+-      MODULE_PARM_DESC(prefix ## name, desc)
+-
+-#define __FSG_MODULE_PARAMETERS(prefix, params)                               \
+-      _FSG_MODULE_PARAM_ARRAY(prefix, params, file, charp,            \
+-                              "names of backing files or devices");   \
+-      _FSG_MODULE_PARAM_ARRAY(prefix, params, ro, bool,               \
+-                              "true to force read-only");             \
+-      _FSG_MODULE_PARAM_ARRAY(prefix, params, removable, bool,        \
+-                              "true to simulate removable media");    \
+-      _FSG_MODULE_PARAM_ARRAY(prefix, params, cdrom, bool,            \
+-                              "true to simulate CD-ROM instead of disk"); \
+-      _FSG_MODULE_PARAM_ARRAY(prefix, params, nofua, bool,            \
+-                              "true to ignore SCSI WRITE(10,12) FUA bit"); \
+-      _FSG_MODULE_PARAM(prefix, params, luns, uint,                   \
+-                        "number of LUNs");                            \
+-      _FSG_MODULE_PARAM(prefix, params, stall, bool,                  \
+-                        "false to prevent bulk stalls")
+-
+-#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+-
+-#define FSG_MODULE_PARAMETERS(prefix, params)                         \
+-      __FSG_MODULE_PARAMETERS(prefix, params);                        \
+-      module_param_named(num_buffers, fsg_num_buffers, uint, S_IRUGO);\
+-      MODULE_PARM_DESC(num_buffers, "Number of pipeline buffers")
+-#else
+-
+-#define FSG_MODULE_PARAMETERS(prefix, params)                         \
+-      __FSG_MODULE_PARAMETERS(prefix, params)
+-
+-#endif
+-
+-static void
+-fsg_config_from_params(struct fsg_config *cfg,
++void fsg_config_from_params(struct fsg_config *cfg,
+                      const struct fsg_module_parameters *params,
+                      unsigned int fsg_num_buffers)
+ {
+@@ -3096,19 +3009,3 @@ fsg_config_from_params(struct fsg_config *cfg,
+       cfg->fsg_num_buffers = fsg_num_buffers;
+ }
+-static inline struct fsg_common *
+-fsg_common_from_params(struct fsg_common *common,
+-                     struct usb_composite_dev *cdev,
+-                     const struct fsg_module_parameters *params,
+-                     unsigned int fsg_num_buffers)
+-      __attribute__((unused));
+-static inline struct fsg_common *
+-fsg_common_from_params(struct fsg_common *common,
+-                     struct usb_composite_dev *cdev,
+-                     const struct fsg_module_parameters *params,
+-                     unsigned int fsg_num_buffers)
+-{
+-      struct fsg_config cfg;
+-      fsg_config_from_params(&cfg, params, fsg_num_buffers);
+-      return fsg_common_init(common, cdev, &cfg);
+-}
+diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h
+new file mode 100644
+index 0000000..b64761d
+--- /dev/null
++++ b/drivers/usb/gadget/f_mass_storage.h
+@@ -0,0 +1,126 @@
++#ifndef USB_F_MASS_STORAGE_H
++#define USB_F_MASS_STORAGE_H
++
++#include "storage_common.h"
++
++struct fsg_module_parameters {
++      char            *file[FSG_MAX_LUNS];
++      bool            ro[FSG_MAX_LUNS];
++      bool            removable[FSG_MAX_LUNS];
++      bool            cdrom[FSG_MAX_LUNS];
++      bool            nofua[FSG_MAX_LUNS];
++
++      unsigned int    file_count, ro_count, removable_count, cdrom_count;
++      unsigned int    nofua_count;
++      unsigned int    luns;   /* nluns */
++      bool            stall;  /* can_stall */
++};
++
++#define _FSG_MODULE_PARAM_ARRAY(prefix, params, name, type, desc)     \
++      module_param_array_named(prefix ## name, params.name, type,     \
++                               &prefix ## params.name ## _count,      \
++                               S_IRUGO);                              \
++      MODULE_PARM_DESC(prefix ## name, desc)
++
++#define _FSG_MODULE_PARAM(prefix, params, name, type, desc)           \
++      module_param_named(prefix ## name, params.name, type,           \
++                         S_IRUGO);                                    \
++      MODULE_PARM_DESC(prefix ## name, desc)
++
++#define __FSG_MODULE_PARAMETERS(prefix, params)                               \
++      _FSG_MODULE_PARAM_ARRAY(prefix, params, file, charp,            \
++                              "names of backing files or devices");   \
++      _FSG_MODULE_PARAM_ARRAY(prefix, params, ro, bool,               \
++                              "true to force read-only");             \
++      _FSG_MODULE_PARAM_ARRAY(prefix, params, removable, bool,        \
++                              "true to simulate removable media");    \
++      _FSG_MODULE_PARAM_ARRAY(prefix, params, cdrom, bool,            \
++                              "true to simulate CD-ROM instead of disk"); \
++      _FSG_MODULE_PARAM_ARRAY(prefix, params, nofua, bool,            \
++                              "true to ignore SCSI WRITE(10,12) FUA bit"); \
++      _FSG_MODULE_PARAM(prefix, params, luns, uint,                   \
++                        "number of LUNs");                            \
++      _FSG_MODULE_PARAM(prefix, params, stall, bool,                  \
++                        "false to prevent bulk stalls")
++
++#ifdef CONFIG_USB_GADGET_DEBUG_FILES
++
++#define FSG_MODULE_PARAMETERS(prefix, params)                         \
++      __FSG_MODULE_PARAMETERS(prefix, params);                        \
++      module_param_named(num_buffers, fsg_num_buffers, uint, S_IRUGO);\
++      MODULE_PARM_DESC(num_buffers, "Number of pipeline buffers")
++#else
++
++#define FSG_MODULE_PARAMETERS(prefix, params)                         \
++      __FSG_MODULE_PARAMETERS(prefix, params)
++
++#endif
++
++struct fsg_common;
++
++/* FSF callback functions */
++struct fsg_operations {
++      /*
++       * Callback function to call when thread exits.  If no
++       * callback is set or it returns value lower then zero MSF
++       * will force eject all LUNs it operates on (including those
++       * marked as non-removable or with prevent_medium_removal flag
++       * set).
++       */
++      int (*thread_exits)(struct fsg_common *common);
++};
++
++struct fsg_lun_config {
++      const char *filename;
++      char ro;
++      char removable;
++      char cdrom;
++      char nofua;
++};
++
++struct fsg_config {
++      unsigned nluns;
++      struct fsg_lun_config luns[FSG_MAX_LUNS];
++
++      /* Callback functions. */
++      const struct fsg_operations     *ops;
++      /* Gadget's private data. */
++      void                    *private_data;
++
++      const char *vendor_name;                /*  8 characters or less */
++      const char *product_name;               /* 16 characters or less */
++
++      char                    can_stall;
++      unsigned int            fsg_num_buffers;
++};
++
++void fsg_common_get(struct fsg_common *common);
++
++void fsg_common_put(struct fsg_common *common);
++
++struct fsg_common *fsg_common_init(struct fsg_common *common,
++                                 struct usb_composite_dev *cdev,
++                                 struct fsg_config *cfg);
++
++void fsg_config_from_params(struct fsg_config *cfg,
++                          const struct fsg_module_parameters *params,
++                          unsigned int fsg_num_buffers);
++
++static inline struct fsg_common *
++fsg_common_from_params(struct fsg_common *common,
++                     struct usb_composite_dev *cdev,
++                     const struct fsg_module_parameters *params,
++                     unsigned int fsg_num_buffers)
++      __attribute__((unused));
++static inline struct fsg_common *
++fsg_common_from_params(struct fsg_common *common,
++                     struct usb_composite_dev *cdev,
++                     const struct fsg_module_parameters *params,
++                     unsigned int fsg_num_buffers)
++{
++      struct fsg_config cfg;
++      fsg_config_from_params(&cfg, params, fsg_num_buffers);
++      return fsg_common_init(common, cdev, &cfg);
++}
++
++#endif /* USB_F_MASS_STORAGE_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0659-usb-gadget-f_mass_storage-add-a-level-of-indirection.patch b/patches.tizen/0659-usb-gadget-f_mass_storage-add-a-level-of-indirection.patch
new file mode 100644 (file)
index 0000000..835ca20
--- /dev/null
@@ -0,0 +1,211 @@
+From 51717e532d24736b2813cfc49e4c48374b2fbd12 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Fri, 26 Jul 2013 12:20:27 +0200
+Subject: [PATCH 0659/1302] usb/gadget: f_mass_storage: add a level of
+ indirection for luns storage
+
+This is needed to prepare for configfs integration.
+
+So far the luns have been allocated during gadget's initialization, based
+on the nluns module parameter's value; the exact number is known when the
+gadget is initialized and that number of luns is allocated in one go; they
+all will be used.
+
+When configfs is in place, the luns will be created one-by-one by the user.
+Once the user is satisfied with the number of luns, they activate the
+gadget. The number of luns must be <= FSG_MAX_LUN (currently 8), but other
+than that it is not known up front and the user need not use contiguous
+numbering (apart from the default lun #0). On the other hand, the function
+code uses lun numbers to identify them and the number needs to be used
+as an index into an array.
+
+Given the above, an array needs to be allocated, but it might happen that
+7 out of its 8 elements will not be used. On my machine
+sizeof(struct fsg_lun) == 462, so > 3k of memory is allocated but not used
+in the worst case.
+
+By adding another level of indirection (allocating an array of pointers
+to struct fsg_lun and then allocating individual luns instead of an array
+of struct fsg_luns) at most 7 pointers are wasted, which is much less.
+
+This patch also changes some for/while loops to cope with the fact
+that in the luns array some entries are potentially empty.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 60 +++++++++++++++++++++++++------------
+ 1 file changed, 41 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index c36e208..05d34a0 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -274,7 +274,7 @@ struct fsg_common {
+       unsigned int            nluns;
+       unsigned int            lun;
+-      struct fsg_lun          *luns;
++      struct fsg_lun          **luns;
+       struct fsg_lun          *curlun;
+       unsigned int            bulk_out_maxpacket;
+@@ -2151,7 +2151,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
+               common->data_dir = DATA_DIR_NONE;
+       common->lun = cbw->Lun;
+       if (common->lun < common->nluns)
+-              common->curlun = &common->luns[common->lun];
++              common->curlun = common->luns[common->lun];
+       else
+               common->curlun = NULL;
+       common->tag = cbw->Tag;
+@@ -2297,7 +2297,9 @@ reset:
+       common->running = 1;
+       for (i = 0; i < common->nluns; ++i)
+-              common->luns[i].unit_attention_data = SS_RESET_OCCURRED;
++              if (common->luns[i])
++                      common->luns[i]->unit_attention_data =
++                              SS_RESET_OCCURRED;
+       return rc;
+ }
+@@ -2397,7 +2399,9 @@ static void handle_exception(struct fsg_common *common)
+               common->state = FSG_STATE_STATUS_PHASE;
+       else {
+               for (i = 0; i < common->nluns; ++i) {
+-                      curlun = &common->luns[i];
++                      curlun = common->luns[i];
++                      if (!curlun)
++                              continue;
+                       curlun->prevent_medium_removal = 0;
+                       curlun->sense_data = SS_NO_SENSE;
+                       curlun->unit_attention_data = SS_NO_SENSE;
+@@ -2439,8 +2443,9 @@ static void handle_exception(struct fsg_common *common)
+                * CONFIG_CHANGE cases.
+                */
+               /* for (i = 0; i < common->nluns; ++i) */
+-              /*      common->luns[i].unit_attention_data = */
+-              /*              SS_RESET_OCCURRED;  */
++              /*      if (common->luns[i]) */
++              /*              common->luns[i]->unit_attention_data = */
++              /*                      SS_RESET_OCCURRED;  */
+               break;
+       case FSG_STATE_CONFIG_CHANGE:
+@@ -2536,12 +2541,13 @@ static int fsg_main_thread(void *common_)
+       if (!common->ops || !common->ops->thread_exits
+        || common->ops->thread_exits(common) < 0) {
+-              struct fsg_lun *curlun = common->luns;
++              struct fsg_lun **curlun_it = common->luns;
+               unsigned i = common->nluns;
+               down_write(&common->filesem);
+-              for (; i--; ++curlun) {
+-                      if (!fsg_lun_is_open(curlun))
++              for (; i--; ++curlun_it) {
++                      struct fsg_lun *curlun = *curlun_it;
++                      if (!curlun || !fsg_lun_is_open(curlun))
+                               continue;
+                       fsg_lun_close(curlun);
+@@ -2602,7 +2608,7 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+ {
+       struct usb_gadget *gadget = cdev->gadget;
+       struct fsg_buffhd *bh;
+-      struct fsg_lun *curlun;
++      struct fsg_lun **curlun_it;
+       struct fsg_lun_config *lcfg;
+       int nluns, i, rc;
+       char *pathbuf;
+@@ -2659,16 +2665,26 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+        * Create the LUNs, open their backing files, and register the
+        * LUN devices in sysfs.
+        */
+-      curlun = kcalloc(nluns, sizeof(*curlun), GFP_KERNEL);
+-      if (unlikely(!curlun)) {
++      curlun_it = kcalloc(nluns, sizeof(*curlun_it), GFP_KERNEL);
++      if (unlikely(!curlun_it)) {
+               rc = -ENOMEM;
+               goto error_release;
+       }
+-      common->luns = curlun;
++      common->luns = curlun_it;
+       init_rwsem(&common->filesem);
+-      for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun, ++lcfg) {
++      for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun_it, ++lcfg) {
++              struct fsg_lun *curlun;
++
++              curlun = kzalloc(sizeof(*curlun), GFP_KERNEL);
++              if (!curlun) {
++                      rc = -ENOMEM;
++                      common->nluns = i;
++                      goto error_release;
++              }
++              *curlun_it = curlun;
++
+               curlun->cdrom = !!lcfg->cdrom;
+               curlun->ro = lcfg->cdrom || lcfg->ro;
+               curlun->initially_ro = curlun->ro;
+@@ -2684,6 +2700,7 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                       INFO(common, "failed to register LUN%d: %d\n", i, rc);
+                       common->nluns = i;
+                       put_device(&curlun->dev);
++                      kfree(curlun);
+                       goto error_release;
+               }
+@@ -2736,7 +2753,7 @@ buffhds_first_it:
+       snprintf(common->inquiry_string, sizeof common->inquiry_string,
+                "%-8s%-16s%04x", cfg->vendor_name ?: "Linux",
+                /* Assume product name dependent on the first LUN */
+-               cfg->product_name ?: (common->luns->cdrom
++               cfg->product_name ?: ((*common->luns)->cdrom
+                                    ? "File-CD Gadget"
+                                    : "File-Stor Gadget"),
+                i);
+@@ -2767,9 +2784,10 @@ buffhds_first_it:
+       INFO(common, "Number of LUNs=%d\n", common->nluns);
+       pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
+-      for (i = 0, nluns = common->nluns, curlun = common->luns;
++      for (i = 0, nluns = common->nluns, curlun_it = common->luns;
+            i < nluns;
+-           ++curlun, ++i) {
++           ++curlun_it, ++i) {
++              struct fsg_lun *curlun = *curlun_it;
+               char *p = "(no medium)";
+               if (fsg_lun_is_open(curlun)) {
+                       p = "(error)";
+@@ -2814,11 +2832,14 @@ static void fsg_common_release(struct kref *ref)
+       }
+       if (likely(common->luns)) {
+-              struct fsg_lun *lun = common->luns;
++              struct fsg_lun **lun_it = common->luns;
+               unsigned i = common->nluns;
+               /* In error recovery common->nluns may be zero. */
+-              for (; i; --i, ++lun) {
++              for (; i; --i, ++lun_it) {
++                      struct fsg_lun *lun = *lun_it;
++                      if (!lun)
++                              continue;
+                       device_remove_file(&lun->dev, &dev_attr_nofua);
+                       device_remove_file(&lun->dev,
+                                          lun->cdrom
+@@ -2830,6 +2851,7 @@ static void fsg_common_release(struct kref *ref)
+                                        : &dev_attr_file_nonremovable);
+                       fsg_lun_close(lun);
+                       device_unregister(&lun->dev);
++                      kfree(lun);
+               }
+               kfree(common->luns);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0660-usb-gadget-f_mass_storage-use-usb_gstrings_attach.patch b/patches.tizen/0660-usb-gadget-f_mass_storage-use-usb_gstrings_attach.patch
new file mode 100644 (file)
index 0000000..3916cae
--- /dev/null
@@ -0,0 +1,82 @@
+From 2089c2070341b55b6476907100bfe2fd04467edd Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 4 Jun 2013 10:58:57 +0200
+Subject: [PATCH 0660/1302] usb/gadget: f_mass_storage: use usb_gstrings_attach
+
+Prepare for handling with configfs.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 25 ++++++++++++-------------
+ 1 file changed, 12 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 05d34a0..04ee635 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -242,6 +242,11 @@ static struct usb_gadget_strings  fsg_stringtab = {
+       .strings        = fsg_strings,
+ };
++static struct usb_gadget_strings *fsg_strings_array[] = {
++      &fsg_stringtab,
++      NULL,
++};
++
+ /*-------------------------------------------------------------------------*/
+ struct fsg_dev;
+@@ -2610,6 +2615,7 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       struct fsg_buffhd *bh;
+       struct fsg_lun **curlun_it;
+       struct fsg_lun_config *lcfg;
++      struct usb_string *us;
+       int nluns, i, rc;
+       char *pathbuf;
+@@ -2652,14 +2658,13 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       common->ep0req = cdev->req;
+       common->cdev = cdev;
+-      /* Maybe allocate device-global string IDs, and patch descriptors */
+-      if (fsg_strings[FSG_STRING_INTERFACE].id == 0) {
+-              rc = usb_string_id(cdev);
+-              if (unlikely(rc < 0))
+-                      goto error_release;
+-              fsg_strings[FSG_STRING_INTERFACE].id = rc;
+-              fsg_intf_desc.iInterface = rc;
++      us = usb_gstrings_attach(cdev, fsg_strings_array,
++                               ARRAY_SIZE(fsg_strings));
++      if (IS_ERR(us)) {
++              rc = PTR_ERR(us);
++              goto error_release;
+       }
++      fsg_intf_desc.iInterface = us[FSG_STRING_INTERFACE].id;
+       /*
+        * Create the LUNs, open their backing files, and register the
+@@ -2953,11 +2958,6 @@ autoconf_fail:
+ /****************************** ADD FUNCTION ******************************/
+-static struct usb_gadget_strings *fsg_strings_array[] = {
+-      &fsg_stringtab,
+-      NULL,
+-};
+-
+ static int fsg_bind_config(struct usb_composite_dev *cdev,
+                          struct usb_configuration *c,
+                          struct fsg_common *common)
+@@ -2970,7 +2970,6 @@ static int fsg_bind_config(struct usb_composite_dev *cdev,
+               return -ENOMEM;
+       fsg->function.name        = FSG_DRIVER_DESC;
+-      fsg->function.strings     = fsg_strings_array;
+       fsg->function.bind        = fsg_bind;
+       fsg->function.unbind      = fsg_unbind;
+       fsg->function.setup       = fsg_setup;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0661-usb-gadget-f_mass_storage-split-fsg_common-initializ.patch b/patches.tizen/0661-usb-gadget-f_mass_storage-split-fsg_common-initializ.patch
new file mode 100644 (file)
index 0000000..2c6cb6a
--- /dev/null
@@ -0,0 +1,597 @@
+From 4198374d675f23cc00a4ebd61f99ef2c8bb4ad82 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Mon, 29 Jul 2013 14:50:17 +0200
+Subject: [PATCH 0661/1302] usb/gadget: f_mass_storage: split fsg_common
+ initialization into a number of functions
+
+When configfs is in place, the things related to intialization
+of struct fsg_common will be split over a number of places.
+This patch adds several functions which together cover the former
+intialization routine fsg_common_init.
+
+When configfs is in place, the luns will not be represented in sysfs,
+so there will be no struct device associated with a lun.
+To prepare for this some debug macros need to be adjusted. Two new
+fields are added to struct fsg_lun: name and name_pfx.
+The "name" is for storing a string which is presented to the user
+instead of the dev_name. The "name_pfx", if non-NULL, is prepended
+to the "name" at printing time.
+
+The name_pfx is for a future lun.0, which will be a default group in
+mass_storage.<name>. By design at USB function configfs group's creation
+time its name is not known (but instead set a bit later in
+drivers/usb/gadget/configfs.c:function_make) and it is this name that
+serves the purpose of the said name prefix. So instead of copying
+a yet-unknown string a pointer to it is stored in struct fsg_lun.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 424 ++++++++++++++++++++++++++++++++++--
+ drivers/usb/gadget/f_mass_storage.h |  33 +++
+ drivers/usb/gadget/storage_common.h |  20 +-
+ 3 files changed, 454 insertions(+), 23 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 04ee635..ef4733c 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -299,6 +299,7 @@ struct fsg_common {
+       unsigned int            short_packet_received:1;
+       unsigned int            bad_lun_okay:1;
+       unsigned int            running:1;
++      unsigned int            sysfs:1;
+       int                     thread_wakeup_needed;
+       struct completion       thread_notifier;
+@@ -2607,6 +2608,393 @@ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
+       return -EINVAL;
+ }
++static struct fsg_common *fsg_common_setup(struct fsg_common *common, bool zero)
++{
++      if (!common) {
++              common = kzalloc(sizeof(*common), GFP_KERNEL);
++              if (!common)
++                      return ERR_PTR(-ENOMEM);
++              common->free_storage_on_release = 1;
++      } else {
++              if (zero)
++                      memset(common, 0, sizeof(*common));
++              common->free_storage_on_release = 0;
++      }
++      init_rwsem(&common->filesem);
++      spin_lock_init(&common->lock);
++      kref_init(&common->ref);
++      init_completion(&common->thread_notifier);
++      init_waitqueue_head(&common->fsg_wait);
++      common->state = FSG_STATE_TERMINATED;
++
++      return common;
++}
++
++void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs)
++{
++      common->sysfs = sysfs;
++}
++
++static void _fsg_common_free_buffers(struct fsg_buffhd *buffhds, unsigned n)
++{
++      if (buffhds) {
++              struct fsg_buffhd *bh = buffhds;
++              while (n--) {
++                      kfree(bh->buf);
++                      ++bh;
++              }
++              kfree(buffhds);
++      }
++}
++
++int fsg_common_set_num_buffers(struct fsg_common *common, unsigned int n)
++{
++      struct fsg_buffhd *bh, *new_buffhds;
++      int i, rc;
++
++      rc = fsg_num_buffers_validate(n);
++      if (rc != 0)
++              return rc;
++
++      new_buffhds = kcalloc(n, sizeof *(new_buffhds), GFP_KERNEL);
++      if (!new_buffhds)
++              return -ENOMEM;
++
++      /* Data buffers cyclic list */
++      bh = new_buffhds;
++      i = n;
++      goto buffhds_first_it;
++      do {
++              bh->next = bh + 1;
++              ++bh;
++buffhds_first_it:
++              bh->buf = kmalloc(FSG_BUFLEN, GFP_KERNEL);
++              if (unlikely(!bh->buf))
++                      goto error_release;
++      } while (--i);
++      bh->next = new_buffhds;
++
++      _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
++      common->fsg_num_buffers = n;
++      common->buffhds = new_buffhds;
++
++      return 0;
++
++error_release:
++      _fsg_common_free_buffers(new_buffhds, n - i);
++
++      return -ENOMEM;
++}
++
++void fsg_common_free_buffers(struct fsg_common *common)
++{
++      _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
++      common->buffhds = NULL;
++}
++
++int fsg_common_set_nluns(struct fsg_common *common, int nluns)
++{
++      struct fsg_lun **curlun;
++
++      /* Find out how many LUNs there should be */
++      if (nluns < 1 || nluns > FSG_MAX_LUNS) {
++              pr_err("invalid number of LUNs: %u\n", nluns);
++              return -EINVAL;
++      }
++
++      curlun = kcalloc(nluns, sizeof(*curlun), GFP_KERNEL);
++      if (unlikely(!curlun))
++              return -ENOMEM;
++
++      if (common->luns)
++              fsg_common_free_luns(common);
++
++      common->luns = curlun;
++      common->nluns = nluns;
++
++      pr_info("Number of LUNs=%d\n", common->nluns);
++
++      return 0;
++}
++
++void fsg_common_free_luns(struct fsg_common *common)
++{
++      fsg_common_remove_luns(common);
++      kfree(common->luns);
++      common->luns = NULL;
++}
++
++void fsg_common_set_ops(struct fsg_common *common,
++                      const struct fsg_operations *ops)
++{
++      common->ops = ops;
++}
++
++void fsg_common_set_private_data(struct fsg_common *common, void *priv)
++{
++      common->private_data = priv;
++}
++
++int fsg_common_set_cdev(struct fsg_common *common,
++                       struct usb_composite_dev *cdev, bool can_stall)
++{
++      struct usb_string *us;
++      int rc;
++
++      common->gadget = cdev->gadget;
++      common->ep0 = cdev->gadget->ep0;
++      common->ep0req = cdev->req;
++      common->cdev = cdev;
++
++      us = usb_gstrings_attach(cdev, fsg_strings_array,
++                               ARRAY_SIZE(fsg_strings));
++      if (IS_ERR(us)) {
++              rc = PTR_ERR(us);
++              return rc;
++      }
++      fsg_intf_desc.iInterface = us[FSG_STRING_INTERFACE].id;
++
++      /*
++       * Some peripheral controllers are known not to be able to
++       * halt bulk endpoints correctly.  If one of them is present,
++       * disable stalls.
++       */
++      common->can_stall = can_stall && !(gadget_is_at91(common->gadget));
++
++      return 0;
++}
++
++static inline int fsg_common_add_sysfs(struct fsg_common *common,
++                                     struct fsg_lun *lun)
++{
++      int rc;
++
++      rc = device_register(&lun->dev);
++      if (rc) {
++              put_device(&lun->dev);
++              return rc;
++      }
++
++      rc = device_create_file(&lun->dev,
++                              lun->cdrom
++                            ? &dev_attr_ro_cdrom
++                            : &dev_attr_ro);
++      if (rc)
++              goto error_cdrom;
++      rc = device_create_file(&lun->dev,
++                              lun->removable
++                            ? &dev_attr_file
++                            : &dev_attr_file_nonremovable);
++      if (rc)
++              goto error_removable;
++      rc = device_create_file(&lun->dev, &dev_attr_nofua);
++      if (rc)
++              goto error_nofua;
++
++      return 0;
++
++error_nofua:
++      device_remove_file(&lun->dev,
++                         lun->removable
++                       ? &dev_attr_file
++                       : &dev_attr_file_nonremovable);
++error_removable:
++      device_remove_file(&lun->dev,
++                         lun->cdrom
++                       ? &dev_attr_ro_cdrom
++                       : &dev_attr_ro);
++error_cdrom:
++      device_unregister(&lun->dev);
++      return rc;
++}
++
++static inline void fsg_common_remove_sysfs(struct fsg_lun *lun)
++{
++      device_remove_file(&lun->dev, &dev_attr_nofua);
++      device_remove_file(&lun->dev, lun->cdrom
++                         ? &dev_attr_ro_cdrom : &dev_attr_ro);
++      device_remove_file(&lun->dev, lun->removable
++                         ? &dev_attr_file : &dev_attr_file_nonremovable);
++}
++
++void fsg_common_remove_lun(struct fsg_lun *lun, bool sysfs)
++{
++      if (sysfs) {
++              fsg_common_remove_sysfs(lun);
++              device_unregister(&lun->dev);
++      }
++      fsg_lun_close(lun);
++      kfree(lun->name);
++      kfree(lun);
++}
++
++void _fsg_common_remove_luns(struct fsg_common *common, int n)
++{
++      int i;
++
++      for (i = 0; i < n; ++i)
++              if (common->luns[i]) {
++                      fsg_common_remove_lun(common->luns[i], common->sysfs);
++                      common->luns[i] = NULL;
++              }
++}
++
++void fsg_common_remove_luns(struct fsg_common *common)
++{
++      _fsg_common_remove_luns(common, common->nluns);
++}
++
++#define MAX_LUN_NAME_LEN 80
++
++int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg,
++                        unsigned int id, const char *name,
++                        const char **name_pfx)
++{
++      struct fsg_lun *lun;
++      char *pathbuf;
++      int rc = -ENOMEM;
++      int name_len;
++
++      if (!common->nluns || !common->luns)
++              return -ENODEV;
++
++      if (common->luns[id])
++              return -EBUSY;
++
++      name_len = strlen(name) + 1;
++      if (name_len > MAX_LUN_NAME_LEN)
++              return -ENAMETOOLONG;
++
++      lun = kzalloc(sizeof(*lun), GFP_KERNEL);
++      if (!lun)
++              return -ENOMEM;
++
++      lun->name = kstrndup(name, name_len, GFP_KERNEL);
++      if (!lun->name)
++              goto error_name;
++      lun->name_pfx = name_pfx;
++
++      lun->cdrom = !!cfg->cdrom;
++      lun->ro = cfg->cdrom || cfg->ro;
++      lun->initially_ro = lun->ro;
++      lun->removable = !!cfg->removable;
++
++      common->luns[id] = lun;
++
++      if (common->sysfs) {
++              lun->dev.release = fsg_lun_release;
++              lun->dev.parent = &common->gadget->dev;
++              dev_set_drvdata(&lun->dev, &common->filesem);
++              dev_set_name(&lun->dev, name);
++
++              rc = fsg_common_add_sysfs(common, lun);
++              if (rc) {
++                      pr_info("failed to register LUN%d: %d\n", id, rc);
++                      goto error_sysfs;
++              }
++      }
++
++      if (cfg->filename) {
++              rc = fsg_lun_open(lun, cfg->filename);
++              if (rc)
++                      goto error_lun;
++      } else if (!lun->removable) {
++              pr_err("no file given for LUN%d\n", id);
++              rc = -EINVAL;
++              goto error_lun;
++      }
++
++      pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
++      {
++              char *p = "(no medium)";
++              if (fsg_lun_is_open(lun)) {
++                      p = "(error)";
++                      if (pathbuf) {
++                              p = d_path(&lun->filp->f_path,
++                                         pathbuf, PATH_MAX);
++                              if (IS_ERR(p))
++                                      p = "(error)";
++                      }
++              }
++              pr_info("LUN: %s%s%sfile: %s\n",
++                    lun->removable ? "removable " : "",
++                    lun->ro ? "read only " : "",
++                    lun->cdrom ? "CD-ROM " : "",
++                    p);
++      }
++      kfree(pathbuf);
++
++      return 0;
++
++error_lun:
++      if (common->sysfs) {
++              fsg_common_remove_sysfs(lun);
++              device_unregister(&lun->dev);
++      }
++      fsg_lun_close(lun);
++error_sysfs:
++      common->luns[id] = NULL;
++      kfree(lun->name);
++error_name:
++      kfree(lun);
++      return rc;
++}
++
++int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg)
++{
++      char buf[40]; /* enough for 2^128 decimal */
++      int i, rc;
++
++      for (i = 0; i < common->nluns; ++i) {
++              snprintf(buf, sizeof(buf), "lun%d", i);
++              rc = fsg_common_create_lun(common, &cfg->luns[i], i, buf, NULL);
++              if (rc)
++                      goto fail;
++      }
++
++      pr_info("Number of LUNs=%d\n", common->nluns);
++
++      return 0;
++
++fail:
++      _fsg_common_remove_luns(common, i);
++      return rc;
++}
++
++void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
++                                 const char *pn)
++{
++      int i;
++
++      /* Prepare inquiryString */
++      i = get_default_bcdDevice();
++      snprintf(common->inquiry_string, sizeof(common->inquiry_string),
++               "%-8s%-16s%04x", vn ?: "Linux",
++               /* Assume product name dependent on the first LUN */
++               pn ?: ((*common->luns)->cdrom
++                   ? "File-CD Gadget"
++                   : "File-Stor Gadget"),
++               i);
++}
++
++int fsg_common_run_thread(struct fsg_common *common)
++{
++      common->state = FSG_STATE_IDLE;
++      /* Tell the thread to start working */
++      common->thread_task =
++              kthread_create(fsg_main_thread, common, "file-storage");
++      if (IS_ERR(common->thread_task)) {
++              common->state = FSG_STATE_TERMINATED;
++              return PTR_ERR(common->thread_task);
++      }
++
++      DBG(common, "I/O thread pid: %d\n", task_pid_nr(common->thread_task));
++
++      wake_up_process(common->thread_task);
++
++      return 0;
++}
++
+ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                  struct usb_composite_dev *cdev,
+                                  struct fsg_config *cfg)
+@@ -2640,6 +3028,8 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+               memset(common, 0, sizeof *common);
+               common->free_storage_on_release = 0;
+       }
++      common->sysfs = true;
++      common->state = FSG_STATE_IDLE;
+       common->fsg_num_buffers = cfg->fsg_num_buffers;
+       common->buffhds = kcalloc(common->fsg_num_buffers,
+@@ -2690,6 +3080,12 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+               }
+               *curlun_it = curlun;
++              curlun->name = kzalloc(MAX_LUN_NAME_LEN, GFP_KERNEL);
++              if (!curlun->name) {
++                      rc = -ENOMEM;
++                      common->nluns = i;
++                      goto error_release;
++              }
+               curlun->cdrom = !!lcfg->cdrom;
+               curlun->ro = lcfg->cdrom || lcfg->ro;
+               curlun->initially_ro = curlun->ro;
+@@ -2699,6 +3095,7 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+               /* curlun->dev.driver = &fsg_driver.driver; XXX */
+               dev_set_drvdata(&curlun->dev, &common->filesem);
+               dev_set_name(&curlun->dev, "lun%d", i);
++              strlcpy(curlun->name, dev_name(&curlun->dev), MAX_LUN_NAME_LEN);
+               rc = device_register(&curlun->dev);
+               if (rc) {
+@@ -2845,32 +3242,21 @@ static void fsg_common_release(struct kref *ref)
+                       struct fsg_lun *lun = *lun_it;
+                       if (!lun)
+                               continue;
+-                      device_remove_file(&lun->dev, &dev_attr_nofua);
+-                      device_remove_file(&lun->dev,
+-                                         lun->cdrom
+-                                       ? &dev_attr_ro_cdrom
+-                                       : &dev_attr_ro);
+-                      device_remove_file(&lun->dev,
+-                                         lun->removable
+-                                       ? &dev_attr_file
+-                                       : &dev_attr_file_nonremovable);
++                      if (common->sysfs)
++                              fsg_common_remove_sysfs(lun);
+                       fsg_lun_close(lun);
+-                      device_unregister(&lun->dev);
++                      if (common->sysfs)
++                              device_unregister(&lun->dev);
++                      kfree(lun->name);
+                       kfree(lun);
+               }
+               kfree(common->luns);
+       }
+-      {
+-              struct fsg_buffhd *bh = common->buffhds;
+-              unsigned i = common->fsg_num_buffers;
+-              do {
+-                      kfree(bh->buf);
+-              } while (++bh, --i);
+-      }
+-
+-      kfree(common->buffhds);
++      if (likely(common->buffhds))
++              _fsg_common_free_buffers(common->buffhds,
++                                       common->fsg_num_buffers);
+       if (common->free_storage_on_release)
+               kfree(common);
+ }
+diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h
+index b64761d..4445e82 100644
+--- a/drivers/usb/gadget/f_mass_storage.h
++++ b/drivers/usb/gadget/f_mass_storage.h
+@@ -102,6 +102,39 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                  struct usb_composite_dev *cdev,
+                                  struct fsg_config *cfg);
++void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs);
++
++int fsg_common_set_num_buffers(struct fsg_common *common, unsigned int n);
++
++void fsg_common_free_buffers(struct fsg_common *common);
++
++int fsg_common_set_nluns(struct fsg_common *common, int nluns);
++
++void fsg_common_free_luns(struct fsg_common *common);
++
++void fsg_common_set_ops(struct fsg_common *common,
++                      const struct fsg_operations *ops);
++
++void fsg_common_set_private_data(struct fsg_common *common, void *priv);
++
++int fsg_common_set_cdev(struct fsg_common *common,
++                      struct usb_composite_dev *cdev, bool can_stall);
++
++void fsg_common_remove_lun(struct fsg_lun *lun, bool sysfs);
++
++void fsg_common_remove_luns(struct fsg_common *common);
++
++int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg,
++                        unsigned int id, const char *name,
++                        const char **name_pfx);
++
++int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg);
++
++void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
++                                 const char *pn);
++
++int fsg_common_run_thread(struct fsg_common *common);
++
+ void fsg_config_from_params(struct fsg_config *cfg,
+                           const struct fsg_module_parameters *params,
+                           unsigned int fsg_num_buffers);
+diff --git a/drivers/usb/gadget/storage_common.h b/drivers/usb/gadget/storage_common.h
+index 1fcda2b..9955477 100644
+--- a/drivers/usb/gadget/storage_common.h
++++ b/drivers/usb/gadget/storage_common.h
+@@ -17,10 +17,20 @@
+ #define VLDBG(lun, fmt, args...) do { } while (0)
+ #endif /* VERBOSE_DEBUG */
+-#define LDBG(lun, fmt, args...)   dev_dbg(&(lun)->dev, fmt, ## args)
+-#define LERROR(lun, fmt, args...) dev_err(&(lun)->dev, fmt, ## args)
+-#define LWARN(lun, fmt, args...)  dev_warn(&(lun)->dev, fmt, ## args)
+-#define LINFO(lun, fmt, args...)  dev_info(&(lun)->dev, fmt, ## args)
++#define _LMSG(func, lun, fmt, args...)                                        \
++      do {                                                            \
++              if ((lun)->name_pfx && *(lun)->name_pfx)                \
++                      func("%s/%s: " fmt, *(lun)->name_pfx,           \
++                               (lun)->name, ## args);                 \
++              else                                                    \
++                      func("%s: " fmt, (lun)->name, ## args);         \
++      } while (0)
++
++#define LDBG(lun, fmt, args...)               _LMSG(pr_debug, lun, fmt, ## args)
++#define LERROR(lun, fmt, args...)     _LMSG(pr_err, lun, fmt, ## args)
++#define LWARN(lun, fmt, args...)      _LMSG(pr_warn, lun, fmt, ## args)
++#define LINFO(lun, fmt, args...)      _LMSG(pr_info, lun, fmt, ## args)
++
+ #ifdef DUMP_MSGS
+@@ -100,6 +110,8 @@ struct fsg_lun {
+                                                      of bound block device */
+       unsigned int    blksize; /* logical block size of bound block device */
+       struct device   dev;
++      char            *name; /* "function.name/lun.name" */
++      const char      **name_pfx;
+ };
+ static inline bool fsg_lun_is_open(struct fsg_lun *curlun)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0662-usb-gadget-f_mass_storage-use-fsg_common_setup-in-fs.patch b/patches.tizen/0662-usb-gadget-f_mass_storage-use-fsg_common_setup-in-fs.patch
new file mode 100644 (file)
index 0000000..4f68aac
--- /dev/null
@@ -0,0 +1,70 @@
+From 6da409d4af402599d135f22d4f0273c42aee5d9c Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 18 Jul 2013 14:02:28 +0200
+Subject: [PATCH 0662/1302] usb/gadget: f_mass_storage: use fsg_common_setup in
+ fsg_common_init
+
+fsg_common_init is a lengthy function. Now there are helper functions
+which cover all parts of it. Use them.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 19 +++----------------
+ 1 file changed, 3 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index ef4733c..2f6e3c3 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -3018,16 +3018,9 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+               return ERR_PTR(-EINVAL);
+       }
+-      /* Allocate? */
+-      if (!common) {
+-              common = kzalloc(sizeof *common, GFP_KERNEL);
+-              if (!common)
+-                      return ERR_PTR(-ENOMEM);
+-              common->free_storage_on_release = 1;
+-      } else {
+-              memset(common, 0, sizeof *common);
+-              common->free_storage_on_release = 0;
+-      }
++      common = fsg_common_setup(common, !!common);
++      if (IS_ERR(common))
++              return common;
+       common->sysfs = true;
+       common->state = FSG_STATE_IDLE;
+@@ -3067,8 +3060,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       }
+       common->luns = curlun_it;
+-      init_rwsem(&common->filesem);
+-
+       for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun_it, ++lcfg) {
+               struct fsg_lun *curlun;
+@@ -3168,8 +3159,6 @@ buffhds_first_it:
+       common->can_stall = cfg->can_stall &&
+               !(gadget_is_at91(common->gadget));
+-      spin_lock_init(&common->lock);
+-      kref_init(&common->ref);
+       /* Tell the thread to start working */
+       common->thread_task =
+@@ -3178,8 +3167,6 @@ buffhds_first_it:
+               rc = PTR_ERR(common->thread_task);
+               goto error_release;
+       }
+-      init_completion(&common->thread_notifier);
+-      init_waitqueue_head(&common->fsg_wait);
+       /* Information */
+       INFO(common, FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0663-usb-gadget-f_mass_storage-use-fsg_common_set_num_buf.patch b/patches.tizen/0663-usb-gadget-f_mass_storage-use-fsg_common_set_num_buf.patch
new file mode 100644 (file)
index 0000000..d5790f9
--- /dev/null
@@ -0,0 +1,82 @@
+From 378d601a3457e66ee10ba1770bfbe9d42d8361da Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 18 Jul 2013 14:02:59 +0200
+Subject: [PATCH 0663/1302] usb/gadget: f_mass_storage: use
+ fsg_common_set_num_buffers in fsg_common_init
+
+fsg_common_init is a lengthy function. Now there are helper functions
+which cover all parts of it. Use them.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 29 +++--------------------------
+ 1 file changed, 3 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 2f6e3c3..2a71540 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -3000,17 +3000,12 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                  struct fsg_config *cfg)
+ {
+       struct usb_gadget *gadget = cdev->gadget;
+-      struct fsg_buffhd *bh;
+       struct fsg_lun **curlun_it;
+       struct fsg_lun_config *lcfg;
+       struct usb_string *us;
+       int nluns, i, rc;
+       char *pathbuf;
+-      rc = fsg_num_buffers_validate(cfg->fsg_num_buffers);
+-      if (rc != 0)
+-              return ERR_PTR(rc);
+-
+       /* Find out how many LUNs there should be */
+       nluns = cfg->nluns;
+       if (nluns < 1 || nluns > FSG_MAX_LUNS) {
+@@ -3024,15 +3019,12 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       common->sysfs = true;
+       common->state = FSG_STATE_IDLE;
+-      common->fsg_num_buffers = cfg->fsg_num_buffers;
+-      common->buffhds = kcalloc(common->fsg_num_buffers,
+-                                sizeof *(common->buffhds), GFP_KERNEL);
+-      if (!common->buffhds) {
++      rc = fsg_common_set_num_buffers(common, cfg->fsg_num_buffers);
++      if (rc) {
+               if (common->free_storage_on_release)
+                       kfree(common);
+-              return ERR_PTR(-ENOMEM);
++              return ERR_PTR(rc);
+       }
+-
+       common->ops = cfg->ops;
+       common->private_data = cfg->private_data;
+@@ -3125,21 +3117,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       }
+       common->nluns = nluns;
+-      /* Data buffers cyclic list */
+-      bh = common->buffhds;
+-      i = common->fsg_num_buffers;
+-      goto buffhds_first_it;
+-      do {
+-              bh->next = bh + 1;
+-              ++bh;
+-buffhds_first_it:
+-              bh->buf = kmalloc(FSG_BUFLEN, GFP_KERNEL);
+-              if (unlikely(!bh->buf)) {
+-                      rc = -ENOMEM;
+-                      goto error_release;
+-              }
+-      } while (--i);
+-      bh->next = common->buffhds;
+       /* Prepare inquiryString */
+       i = get_default_bcdDevice();
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0664-usb-gadget-f_mass_storage-use-fsg_common_set_nluns-i.patch b/patches.tizen/0664-usb-gadget-f_mass_storage-use-fsg_common_set_nluns-i.patch
new file mode 100644 (file)
index 0000000..19ca03f
--- /dev/null
@@ -0,0 +1,67 @@
+From 988ececeab73edfa2e4f27ad7167034d8908aa74 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 18 Jul 2013 14:08:17 +0200
+Subject: [PATCH 0664/1302] usb/gadget: f_mass_storage: use
+ fsg_common_set_nluns in fsg_common_init
+
+fsg_common_init is a lengthy function. Now there are helper functions
+which cover all parts of it. Use them.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 22 +++++-----------------
+ 1 file changed, 5 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 2a71540..691fb51 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -3006,12 +3006,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       int nluns, i, rc;
+       char *pathbuf;
+-      /* Find out how many LUNs there should be */
+-      nluns = cfg->nluns;
+-      if (nluns < 1 || nluns > FSG_MAX_LUNS) {
+-              dev_err(&gadget->dev, "invalid number of LUNs: %u\n", nluns);
+-              return ERR_PTR(-EINVAL);
+-      }
+       common = fsg_common_setup(common, !!common);
+       if (IS_ERR(common))
+@@ -3041,17 +3035,12 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       }
+       fsg_intf_desc.iInterface = us[FSG_STRING_INTERFACE].id;
+-      /*
+-       * Create the LUNs, open their backing files, and register the
+-       * LUN devices in sysfs.
+-       */
+-      curlun_it = kcalloc(nluns, sizeof(*curlun_it), GFP_KERNEL);
+-      if (unlikely(!curlun_it)) {
+-              rc = -ENOMEM;
+-              goto error_release;
+-      }
+-      common->luns = curlun_it;
++      rc = fsg_common_set_nluns(common, cfg->nluns);
++      if (rc)
++              goto error_release;
++      curlun_it = common->luns;
++      nluns = cfg->nluns;
+       for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun_it, ++lcfg) {
+               struct fsg_lun *curlun;
+@@ -3115,7 +3104,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                       goto error_luns;
+               }
+       }
+-      common->nluns = nluns;
+       /* Prepare inquiryString */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0665-usb-gadget-f_mass_storage-use-fsg_common_set_ops-_pr.patch b/patches.tizen/0665-usb-gadget-f_mass_storage-use-fsg_common_set_ops-_pr.patch
new file mode 100644 (file)
index 0000000..6e00892
--- /dev/null
@@ -0,0 +1,35 @@
+From 51c5313aa631785326cf16c39e941edd50b2832f Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Fri, 21 Jun 2013 11:29:58 +0200
+Subject: [PATCH 0665/1302] usb/gadget: f_mass_storage: use
+ fsg_common_set_ops/_private_data in fsg_common_init
+
+fsg_common_init is a lengthy function. Now there are helper functions
+which cover all parts of it. Use them.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 691fb51..8aa6c86 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -3019,8 +3019,9 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                       kfree(common);
+               return ERR_PTR(rc);
+       }
+-      common->ops = cfg->ops;
+-      common->private_data = cfg->private_data;
++
++      fsg_common_set_ops(common, cfg->ops);
++      fsg_common_set_private_data(common, cfg->private_data);
+       common->gadget = gadget;
+       common->ep0 = gadget->ep0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0666-usb-gadget-f_mass_storage-use-fsg_common_set_cdev-in.patch b/patches.tizen/0666-usb-gadget-f_mass_storage-use-fsg_common_set_cdev-in.patch
new file mode 100644 (file)
index 0000000..4110a53
--- /dev/null
@@ -0,0 +1,68 @@
+From 03aec556a53d26977be1c16b3307eae731960cd8 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Fri, 21 Jun 2013 11:30:51 +0200
+Subject: [PATCH 0666/1302] usb/gadget: f_mass_storage: use fsg_common_set_cdev
+ in fsg_common_init
+
+fsg_common_init is a lengthy function. Now there are helper functions
+which cover all parts of it. Use them.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 23 ++---------------------
+ 1 file changed, 2 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 8aa6c86..9dde453 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -3002,7 +3002,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       struct usb_gadget *gadget = cdev->gadget;
+       struct fsg_lun **curlun_it;
+       struct fsg_lun_config *lcfg;
+-      struct usb_string *us;
+       int nluns, i, rc;
+       char *pathbuf;
+@@ -3023,19 +3022,9 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       fsg_common_set_ops(common, cfg->ops);
+       fsg_common_set_private_data(common, cfg->private_data);
+-      common->gadget = gadget;
+-      common->ep0 = gadget->ep0;
+-      common->ep0req = cdev->req;
+-      common->cdev = cdev;
+-
+-      us = usb_gstrings_attach(cdev, fsg_strings_array,
+-                               ARRAY_SIZE(fsg_strings));
+-      if (IS_ERR(us)) {
+-              rc = PTR_ERR(us);
++      rc = fsg_common_set_cdev(common, cdev, cfg->can_stall);
++      if (rc)
+               goto error_release;
+-      }
+-      fsg_intf_desc.iInterface = us[FSG_STRING_INTERFACE].id;
+-
+       rc = fsg_common_set_nluns(common, cfg->nluns);
+       if (rc)
+@@ -3117,14 +3106,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                    : "File-Stor Gadget"),
+                i);
+-      /*
+-       * Some peripheral controllers are known not to be able to
+-       * halt bulk endpoints correctly.  If one of them is present,
+-       * disable stalls.
+-       */
+-      common->can_stall = cfg->can_stall &&
+-              !(gadget_is_at91(common->gadget));
+-
+       /* Tell the thread to start working */
+       common->thread_task =
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0667-usb-gadget-f_mass_storage-use-fsg_common_create_luns.patch b/patches.tizen/0667-usb-gadget-f_mass_storage-use-fsg_common_create_luns.patch
new file mode 100644 (file)
index 0000000..80949db
--- /dev/null
@@ -0,0 +1,159 @@
+From 681ab95e2320cb629954939a867c61de7d7b8372 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Fri, 26 Jul 2013 13:56:33 +0200
+Subject: [PATCH 0667/1302] usb/gadget: f_mass_storage: use
+ fsg_common_create_luns in fsg_common_init
+
+fsg_common_init is a lengthy function. Now there are helper functions
+which cover all parts of it. Use them.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 101 ++----------------------------------
+ 1 file changed, 4 insertions(+), 97 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 9dde453..41a94a1 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -2999,12 +2999,7 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                  struct usb_composite_dev *cdev,
+                                  struct fsg_config *cfg)
+ {
+-      struct usb_gadget *gadget = cdev->gadget;
+-      struct fsg_lun **curlun_it;
+-      struct fsg_lun_config *lcfg;
+-      int nluns, i, rc;
+-      char *pathbuf;
+-
++      int i, rc;
+       common = fsg_common_setup(common, !!common);
+       if (IS_ERR(common))
+@@ -3029,72 +3024,10 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       rc = fsg_common_set_nluns(common, cfg->nluns);
+       if (rc)
+               goto error_release;
+-      curlun_it = common->luns;
+-      nluns = cfg->nluns;
+-      for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun_it, ++lcfg) {
+-              struct fsg_lun *curlun;
+-
+-              curlun = kzalloc(sizeof(*curlun), GFP_KERNEL);
+-              if (!curlun) {
+-                      rc = -ENOMEM;
+-                      common->nluns = i;
+-                      goto error_release;
+-              }
+-              *curlun_it = curlun;
+-
+-              curlun->name = kzalloc(MAX_LUN_NAME_LEN, GFP_KERNEL);
+-              if (!curlun->name) {
+-                      rc = -ENOMEM;
+-                      common->nluns = i;
+-                      goto error_release;
+-              }
+-              curlun->cdrom = !!lcfg->cdrom;
+-              curlun->ro = lcfg->cdrom || lcfg->ro;
+-              curlun->initially_ro = curlun->ro;
+-              curlun->removable = lcfg->removable;
+-              curlun->dev.release = fsg_lun_release;
+-              curlun->dev.parent = &gadget->dev;
+-              /* curlun->dev.driver = &fsg_driver.driver; XXX */
+-              dev_set_drvdata(&curlun->dev, &common->filesem);
+-              dev_set_name(&curlun->dev, "lun%d", i);
+-              strlcpy(curlun->name, dev_name(&curlun->dev), MAX_LUN_NAME_LEN);
+-
+-              rc = device_register(&curlun->dev);
+-              if (rc) {
+-                      INFO(common, "failed to register LUN%d: %d\n", i, rc);
+-                      common->nluns = i;
+-                      put_device(&curlun->dev);
+-                      kfree(curlun);
+-                      goto error_release;
+-              }
+-
+-              rc = device_create_file(&curlun->dev,
+-                                      curlun->cdrom
+-                                    ? &dev_attr_ro_cdrom
+-                                    : &dev_attr_ro);
+-              if (rc)
+-                      goto error_luns;
+-              rc = device_create_file(&curlun->dev,
+-                                      curlun->removable
+-                                    ? &dev_attr_file
+-                                    : &dev_attr_file_nonremovable);
+-              if (rc)
+-                      goto error_luns;
+-              rc = device_create_file(&curlun->dev, &dev_attr_nofua);
+-              if (rc)
+-                      goto error_luns;
+-
+-              if (lcfg->filename) {
+-                      rc = fsg_lun_open(curlun, lcfg->filename);
+-                      if (rc)
+-                              goto error_luns;
+-              } else if (!curlun->removable) {
+-                      ERROR(common, "no file given for LUN%d\n", i);
+-                      rc = -EINVAL;
+-                      goto error_luns;
+-              }
+-      }
++      rc = fsg_common_create_luns(common, cfg);
++      if (rc)
++              goto error_release;
+       /* Prepare inquiryString */
+       i = get_default_bcdDevice();
+@@ -3106,7 +3039,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                    : "File-Stor Gadget"),
+                i);
+-
+       /* Tell the thread to start working */
+       common->thread_task =
+               kthread_create(fsg_main_thread, common, "file-storage");
+@@ -3119,37 +3051,12 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       INFO(common, FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
+       INFO(common, "Number of LUNs=%d\n", common->nluns);
+-      pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
+-      for (i = 0, nluns = common->nluns, curlun_it = common->luns;
+-           i < nluns;
+-           ++curlun_it, ++i) {
+-              struct fsg_lun *curlun = *curlun_it;
+-              char *p = "(no medium)";
+-              if (fsg_lun_is_open(curlun)) {
+-                      p = "(error)";
+-                      if (pathbuf) {
+-                              p = d_path(&curlun->filp->f_path,
+-                                         pathbuf, PATH_MAX);
+-                              if (IS_ERR(p))
+-                                      p = "(error)";
+-                      }
+-              }
+-              LINFO(curlun, "LUN: %s%s%sfile: %s\n",
+-                    curlun->removable ? "removable " : "",
+-                    curlun->ro ? "read only " : "",
+-                    curlun->cdrom ? "CD-ROM " : "",
+-                    p);
+-      }
+-      kfree(pathbuf);
+-
+       DBG(common, "I/O thread pid: %d\n", task_pid_nr(common->thread_task));
+       wake_up_process(common->thread_task);
+       return common;
+-error_luns:
+-      common->nluns = i + 1;
+ error_release:
+       common->state = FSG_STATE_TERMINATED;   /* The thread is dead */
+       /* Call fsg_common_release() directly, ref might be not initialised. */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0668-usb-gadget-f_mass_storage-use-fsg_common_set_inquiry.patch b/patches.tizen/0668-usb-gadget-f_mass_storage-use-fsg_common_set_inquiry.patch
new file mode 100644 (file)
index 0000000..436f8ca
--- /dev/null
@@ -0,0 +1,51 @@
+From 2e9cc80a04c3f5c46640f7a4d347ce37c6f26953 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 3 Jul 2013 14:38:53 +0200
+Subject: [PATCH 0668/1302] usb/gadget: f_mass_storage: use
+ fsg_common_set_inquiry_string in fsg_common_init
+
+fsg_common_init is a lengthy function. Now there are helper functions
+which cover all parts of it. Use them.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 13 +++----------
+ 1 file changed, 3 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 41a94a1..fcc6409 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -2999,7 +2999,7 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                  struct usb_composite_dev *cdev,
+                                  struct fsg_config *cfg)
+ {
+-      int i, rc;
++      int rc;
+       common = fsg_common_setup(common, !!common);
+       if (IS_ERR(common))
+@@ -3029,16 +3029,9 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       if (rc)
+               goto error_release;
+-      /* Prepare inquiryString */
+-      i = get_default_bcdDevice();
+-      snprintf(common->inquiry_string, sizeof common->inquiry_string,
+-               "%-8s%-16s%04x", cfg->vendor_name ?: "Linux",
+-               /* Assume product name dependent on the first LUN */
+-               cfg->product_name ?: ((*common->luns)->cdrom
+-                                   ? "File-CD Gadget"
+-                                   : "File-Stor Gadget"),
+-               i);
++      fsg_common_set_inquiry_string(common, cfg->vendor_name,
++                                    cfg->product_name);
+       /* Tell the thread to start working */
+       common->thread_task =
+               kthread_create(fsg_main_thread, common, "file-storage");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0669-usb-gadget-f_mass_storage-use-fsg_common_run_thread-.patch b/patches.tizen/0669-usb-gadget-f_mass_storage-use-fsg_common_run_thread-.patch
new file mode 100644 (file)
index 0000000..629bafc
--- /dev/null
@@ -0,0 +1,48 @@
+From 9fc1ddf14878e584464ab110ee5150d6ac3151ef Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 3 Jul 2013 14:39:20 +0200
+Subject: [PATCH 0669/1302] usb/gadget: f_mass_storage: use
+ fsg_common_run_thread in fsg_common_init
+
+fsg_common_init is a lengthy function. Now there are helper functions
+which cover all parts of it. Use them.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 14 +++-----------
+ 1 file changed, 3 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index fcc6409..7ef99f1 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -3032,21 +3032,13 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       fsg_common_set_inquiry_string(common, cfg->vendor_name,
+                                     cfg->product_name);
+-      /* Tell the thread to start working */
+-      common->thread_task =
+-              kthread_create(fsg_main_thread, common, "file-storage");
+-      if (IS_ERR(common->thread_task)) {
+-              rc = PTR_ERR(common->thread_task);
+-              goto error_release;
+-      }
+       /* Information */
+       INFO(common, FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
+-      INFO(common, "Number of LUNs=%d\n", common->nluns);
+-      DBG(common, "I/O thread pid: %d\n", task_pid_nr(common->thread_task));
+-
+-      wake_up_process(common->thread_task);
++      rc = fsg_common_run_thread(common);
++      if (rc)
++              goto error_release;
+       return common;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0670-usb-gadget-f_mass_storage-convert-to-new-function-in.patch b/patches.tizen/0670-usb-gadget-f_mass_storage-convert-to-new-function-in.patch
new file mode 100644 (file)
index 0000000..bba4481
--- /dev/null
@@ -0,0 +1,498 @@
+From 2cac3870c00b16a061c42fc4bbd2fd67e957d147 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 3 Jul 2013 14:40:41 +0200
+Subject: [PATCH 0670/1302] usb/gadget: f_mass_storage: convert to new function
+ interface with backward compatibility
+
+Converting mass storage to the new function interface requires converting
+the USB mass storage's function code and its users.
+This patch converts the f_mass_storage.c to the new function interface.
+The file is now compiled into a separate usb_f_mass_storage.ko module.
+The old function interface is provided by means of a preprocessor conditional
+directives. After all users are converted, the old interface can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig          |   3 +
+ drivers/usb/gadget/Makefile         |   2 +
+ drivers/usb/gadget/acm_ms.c         |   1 +
+ drivers/usb/gadget/f_mass_storage.c | 217 ++++++++++++++++++++++++++++++++----
+ drivers/usb/gadget/f_mass_storage.h |   7 ++
+ drivers/usb/gadget/mass_storage.c   |   1 +
+ drivers/usb/gadget/multi.c          |   1 +
+ 7 files changed, 212 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index b5e6c2e..fc8012a 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -540,6 +540,9 @@ config USB_F_RNDIS
+ config USB_U_MS
+       tristate
++config USB_F_MASS_STORAGE
++      tristate
++
+ choice
+       tristate "USB Gadget Drivers"
+       default USB_ETH
+diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
+index 3bb34ef..d232706 100644
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -62,6 +62,8 @@ usb_f_rndis-y                        := f_rndis.o
+ obj-$(CONFIG_USB_F_RNDIS)     += usb_f_rndis.o
+ u_ms-y                                := storage_common.o
+ obj-$(CONFIG_USB_U_MS)                += u_ms.o
++usb_f_mass_storage-y          := f_mass_storage.o
++obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o
+ #
+ # USB gadget drivers
+diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c
+index 992ffb0..31aae8f 100644
+--- a/drivers/usb/gadget/acm_ms.c
++++ b/drivers/usb/gadget/acm_ms.c
+@@ -40,6 +40,7 @@
+  * the runtime footprint, and giving us at least some parts of what
+  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+  */
++#define USB_FMS_INCLUDED
+ #include "f_mass_storage.c"
+ /*-------------------------------------------------------------------------*/
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 7ef99f1..0a2b3ae 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -213,6 +213,7 @@
+ #include <linux/spinlock.h>
+ #include <linux/string.h>
+ #include <linux/freezer.h>
++#include <linux/module.h>
+ #include <linux/usb/ch9.h>
+ #include <linux/usb/gadget.h>
+@@ -2592,11 +2593,17 @@ void fsg_common_get(struct fsg_common *common)
+ {
+       kref_get(&common->ref);
+ }
++#ifndef USB_FMS_INCLUDED
++EXPORT_SYMBOL(fsg_common_get);
++#endif
+ void fsg_common_put(struct fsg_common *common)
+ {
+       kref_put(&common->ref, fsg_common_release);
+ }
++#ifndef USB_FMS_INCLUDED
++EXPORT_SYMBOL(fsg_common_put);
++#endif
+ /* check if fsg_num_buffers is within a valid range */
+ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
+@@ -2634,6 +2641,9 @@ void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs)
+ {
+       common->sysfs = sysfs;
+ }
++#ifndef USB_FMS_INCLUDED
++EXPORT_SYMBOL(fsg_common_set_sysfs);
++#endif
+ static void _fsg_common_free_buffers(struct fsg_buffhd *buffhds, unsigned n)
+ {
+@@ -2685,12 +2695,18 @@ error_release:
+       return -ENOMEM;
+ }
++#ifndef USB_FMS_INCLUDED
++EXPORT_SYMBOL(fsg_common_set_num_buffers);
++#endif
+ void fsg_common_free_buffers(struct fsg_common *common)
+ {
+       _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
+       common->buffhds = NULL;
+ }
++#ifndef USB_FMS_INCLUDED
++EXPORT_SYMBOL(fsg_common_free_buffers);
++#endif
+ int fsg_common_set_nluns(struct fsg_common *common, int nluns)
+ {
+@@ -2716,6 +2732,9 @@ int fsg_common_set_nluns(struct fsg_common *common, int nluns)
+       return 0;
+ }
++#ifndef USB_FMS_INCLUDED
++EXPORT_SYMBOL(fsg_common_set_nluns);
++#endif
+ void fsg_common_free_luns(struct fsg_common *common)
+ {
+@@ -2723,17 +2742,26 @@ void fsg_common_free_luns(struct fsg_common *common)
+       kfree(common->luns);
+       common->luns = NULL;
+ }
++#ifndef USB_FMS_INCLUDED
++EXPORT_SYMBOL(fsg_common_free_luns);
++#endif
+ void fsg_common_set_ops(struct fsg_common *common,
+                       const struct fsg_operations *ops)
+ {
+       common->ops = ops;
+ }
++#ifndef USB_FMS_INCLUDED
++EXPORT_SYMBOL(fsg_common_set_ops);
++#endif
+ void fsg_common_set_private_data(struct fsg_common *common, void *priv)
+ {
+       common->private_data = priv;
+ }
++#ifndef USB_FMS_INCLUDED
++EXPORT_SYMBOL(fsg_common_set_private_data);
++#endif
+ int fsg_common_set_cdev(struct fsg_common *common,
+                        struct usb_composite_dev *cdev, bool can_stall)
+@@ -2763,6 +2791,9 @@ int fsg_common_set_cdev(struct fsg_common *common,
+       return 0;
+ }
++#ifndef USB_FMS_INCLUDED
++EXPORT_SYMBOL(fsg_common_set_cdev);
++#endif
+ static inline int fsg_common_add_sysfs(struct fsg_common *common,
+                                      struct fsg_lun *lun)
+@@ -2827,6 +2858,9 @@ void fsg_common_remove_lun(struct fsg_lun *lun, bool sysfs)
+       kfree(lun->name);
+       kfree(lun);
+ }
++#ifndef USB_FMS_INCLUDED
++EXPORT_SYMBOL(fsg_common_remove_lun);
++#endif
+ void _fsg_common_remove_luns(struct fsg_common *common, int n)
+ {
+@@ -2843,6 +2877,9 @@ void fsg_common_remove_luns(struct fsg_common *common)
+ {
+       _fsg_common_remove_luns(common, common->nluns);
+ }
++#ifndef USB_FMS_INCLUDED
++EXPORT_SYMBOL(fsg_common_remove_luns);
++#endif
+ #define MAX_LUN_NAME_LEN 80
+@@ -2939,6 +2976,9 @@ error_name:
+       kfree(lun);
+       return rc;
+ }
++#ifndef USB_FMS_INCLUDED
++EXPORT_SYMBOL(fsg_common_create_lun);
++#endif
+ int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg)
+ {
+@@ -2960,6 +3000,9 @@ fail:
+       _fsg_common_remove_luns(common, i);
+       return rc;
+ }
++#ifndef USB_FMS_INCLUDED
++EXPORT_SYMBOL(fsg_common_create_luns);
++#endif
+ void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
+                                  const char *pn)
+@@ -2976,6 +3019,9 @@ void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
+                    : "File-Stor Gadget"),
+                i);
+ }
++#ifndef USB_FMS_INCLUDED
++EXPORT_SYMBOL(fsg_common_set_inquiry_string);
++#endif
+ int fsg_common_run_thread(struct fsg_common *common)
+ {
+@@ -2994,6 +3040,9 @@ int fsg_common_run_thread(struct fsg_common *common)
+       return 0;
+ }
++#ifndef USB_FMS_INCLUDED
++EXPORT_SYMBOL(fsg_common_run_thread);
++#endif
+ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                  struct usb_composite_dev *cdev,
+@@ -3048,6 +3097,9 @@ error_release:
+       fsg_common_release(&common->ref);
+       return ERR_PTR(rc);
+ }
++#ifndef USB_FMS_INCLUDED
++EXPORT_SYMBOL(fsg_common_init);
++#endif
+ static void fsg_common_release(struct kref *ref)
+ {
+@@ -3090,24 +3142,6 @@ static void fsg_common_release(struct kref *ref)
+ /*-------------------------------------------------------------------------*/
+-static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
+-{
+-      struct fsg_dev          *fsg = fsg_from_func(f);
+-      struct fsg_common       *common = fsg->common;
+-
+-      DBG(fsg, "unbind\n");
+-      if (fsg->common->fsg == fsg) {
+-              fsg->common->new_fsg = NULL;
+-              raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
+-              /* FIXME: make interruptible or killable somehow? */
+-              wait_event(common->fsg_wait, common->fsg != fsg);
+-      }
+-
+-      fsg_common_put(common);
+-      usb_free_all_descriptors(&fsg->function);
+-      kfree(fsg);
+-}
+-
+ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
+ {
+       struct fsg_dev          *fsg = fsg_from_func(f);
+@@ -3117,6 +3151,21 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
+       unsigned                max_burst;
+       int                     ret;
++#ifndef USB_FMS_INCLUDED
++      struct fsg_opts         *opts;
++      opts = container_of(f->fi, struct fsg_opts, func_inst);
++      if (!opts->no_configfs) {
++              ret = fsg_common_set_cdev(fsg->common, c->cdev,
++                                        fsg->common->can_stall);
++              if (ret)
++                      return ret;
++              fsg_common_set_inquiry_string(fsg->common, 0, 0);
++              ret = fsg_common_run_thread(fsg->common);
++              if (ret)
++                      return ret;
++      }
++#endif
++
+       fsg->gadget = gadget;
+       /* New interface */
+@@ -3168,7 +3217,27 @@ autoconf_fail:
+       return -ENOTSUPP;
+ }
+-/****************************** ADD FUNCTION ******************************/
++/****************************** ALLOCATE FUNCTION *************************/
++
++#ifdef USB_FMS_INCLUDED
++
++static void old_fsg_unbind(struct usb_configuration *c, struct usb_function *f)
++{
++      struct fsg_dev          *fsg = fsg_from_func(f);
++      struct fsg_common       *common = fsg->common;
++
++      DBG(fsg, "unbind\n");
++      if (fsg->common->fsg == fsg) {
++              fsg->common->new_fsg = NULL;
++              raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
++              /* FIXME: make interruptible or killable somehow? */
++              wait_event(common->fsg_wait, common->fsg != fsg);
++      }
++
++      fsg_common_put(common);
++      usb_free_all_descriptors(&fsg->function);
++      kfree(fsg);
++}
+ static int fsg_bind_config(struct usb_composite_dev *cdev,
+                          struct usb_configuration *c,
+@@ -3183,7 +3252,7 @@ static int fsg_bind_config(struct usb_composite_dev *cdev,
+       fsg->function.name        = FSG_DRIVER_DESC;
+       fsg->function.bind        = fsg_bind;
+-      fsg->function.unbind      = fsg_unbind;
++      fsg->function.unbind      = old_fsg_unbind;
+       fsg->function.setup       = fsg_setup;
+       fsg->function.set_alt     = fsg_set_alt;
+       fsg->function.disable     = fsg_disable;
+@@ -3205,6 +3274,111 @@ static int fsg_bind_config(struct usb_composite_dev *cdev,
+       return rc;
+ }
++#else
++
++static void fsg_free_inst(struct usb_function_instance *fi)
++{
++      struct fsg_opts *opts;
++
++      opts = container_of(fi, struct fsg_opts, func_inst);
++      fsg_common_put(opts->common);
++      kfree(opts);
++}
++
++static struct usb_function_instance *fsg_alloc_inst(void)
++{
++      struct fsg_opts *opts;
++      int ret;
++
++      opts = kzalloc(sizeof(*opts), GFP_KERNEL);
++      if (!opts)
++              return ERR_PTR(-ENOMEM);
++      opts->func_inst.free_func_inst = fsg_free_inst;
++      opts->common = fsg_common_setup(opts->common, false);
++      if (IS_ERR(opts->common)) {
++              ret = PTR_ERR(opts->common);
++              goto release_opts;
++      }
++      ret = fsg_common_set_nluns(opts->common, FSG_MAX_LUNS);
++      if (ret)
++              goto release_opts;
++
++      ret = fsg_common_set_num_buffers(opts->common,
++                                       CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS);
++      if (ret)
++              goto release_luns;
++
++      pr_info(FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
++
++      return &opts->func_inst;
++
++release_luns:
++      kfree(opts->common->luns);
++release_opts:
++      kfree(opts);
++      return ERR_PTR(ret);
++}
++
++static void fsg_free(struct usb_function *f)
++{
++      struct fsg_dev *fsg;
++
++      fsg = container_of(f, struct fsg_dev, function);
++
++      kfree(fsg);
++}
++
++static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
++{
++      struct fsg_dev          *fsg = fsg_from_func(f);
++      struct fsg_common       *common = fsg->common;
++
++      DBG(fsg, "unbind\n");
++      if (fsg->common->fsg == fsg) {
++              fsg->common->new_fsg = NULL;
++              raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
++              /* FIXME: make interruptible or killable somehow? */
++              wait_event(common->fsg_wait, common->fsg != fsg);
++      }
++
++      usb_free_all_descriptors(&fsg->function);
++}
++
++static struct usb_function *fsg_alloc(struct usb_function_instance *fi)
++{
++      struct fsg_opts *opts = container_of(fi, struct fsg_opts, func_inst);
++      struct fsg_common *common = opts->common;
++      struct fsg_dev *fsg;
++
++      fsg = kzalloc(sizeof(*fsg), GFP_KERNEL);
++      if (unlikely(!fsg))
++              return ERR_PTR(-ENOMEM);
++
++      fsg->function.name        = FSG_DRIVER_DESC;
++      fsg->function.bind        = fsg_bind;
++      fsg->function.unbind      = fsg_unbind;
++      fsg->function.setup       = fsg_setup;
++      fsg->function.set_alt     = fsg_set_alt;
++      fsg->function.disable     = fsg_disable;
++      fsg->function.free_func   = fsg_free;
++
++      fsg->common               = common;
++      /*
++       * Our caller holds a reference to common structure so we
++       * don't have to be worry about it being freed until we return
++       * from this function.  So instead of incrementing counter now
++       * and decrement in error recovery we increment it only when
++       * call to usb_add_function() was successful.
++       */
++
++      return &fsg->function;
++}
++
++DECLARE_USB_FUNCTION_INIT(mass_storage, fsg_alloc_inst, fsg_alloc);
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Michal Nazarewicz");
++
++#endif
+ /************************* Module parameters *************************/
+@@ -3241,4 +3415,7 @@ void fsg_config_from_params(struct fsg_config *cfg,
+       cfg->can_stall = params->stall;
+       cfg->fsg_num_buffers = fsg_num_buffers;
+ }
++#ifndef USB_FMS_INCLUDED
++EXPORT_SYMBOL(fsg_config_from_params);
++#endif
+diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h
+index 4445e82..7aed1d9 100644
+--- a/drivers/usb/gadget/f_mass_storage.h
++++ b/drivers/usb/gadget/f_mass_storage.h
+@@ -1,6 +1,7 @@
+ #ifndef USB_F_MASS_STORAGE_H
+ #define USB_F_MASS_STORAGE_H
++#include <linux/usb/composite.h>
+ #include "storage_common.h"
+ struct fsg_module_parameters {
+@@ -70,6 +71,12 @@ struct fsg_operations {
+       int (*thread_exits)(struct fsg_common *common);
+ };
++struct fsg_opts {
++      struct fsg_common *common;
++      struct usb_function_instance func_inst;
++      bool no_configfs; /* for legacy gadgets */
++};
++
+ struct fsg_lun_config {
+       const char *filename;
+       char ro;
+diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c
+index bf60a9a..6b79814 100644
+--- a/drivers/usb/gadget/mass_storage.c
++++ b/drivers/usb/gadget/mass_storage.c
+@@ -55,6 +55,7 @@
+  * the runtime footprint, and giving us at least some parts of what
+  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+  */
++#define USB_FMS_INCLUDED
+ #include "f_mass_storage.c"
+ /*-------------------------------------------------------------------------*/
+diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
+index f610d01..c232f76 100644
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -41,6 +41,7 @@ MODULE_LICENSE("GPL");
+  * the runtime footprint, and giving us at least some parts of what
+  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+  */
++#define USB_FMS_INCLUDED
+ #include "f_mass_storage.c"
+ #define USBF_ECM_INCLUDED
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0671-usb-gadget-mass_storage-convert-to-new-interface-of-.patch b/patches.tizen/0671-usb-gadget-mass_storage-convert-to-new-interface-of-.patch
new file mode 100644 (file)
index 0000000..04cd88f
--- /dev/null
@@ -0,0 +1,202 @@
+From d42b40a01037255c0609cfae1607bdf7524c8c75 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 30 Jul 2013 10:24:55 +0200
+Subject: [PATCH 0671/1302] usb/gadget: mass_storage: convert to new interface
+ of f_mass_storage
+
+Convert old mass_storage gadget to use the new interface of f_mass_storage
+so that later the compatibility layer in f_mass_storage can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig        |   1 +
+ drivers/usb/gadget/mass_storage.c | 107 ++++++++++++++++++++++++++++----------
+ 2 files changed, 81 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index fc8012a..073ba0f 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -897,6 +897,7 @@ config USB_MASS_STORAGE
+       depends on BLOCK
+       select USB_LIBCOMPOSITE
+       select USB_U_MS
++      select USB_F_MASS_STORAGE
+       help
+         The Mass Storage Gadget acts as a USB Mass Storage disk drive.
+         As its storage repository it can use a regular file or a block
+diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c
+index 6b79814..39a5316 100644
+--- a/drivers/usb/gadget/mass_storage.c
++++ b/drivers/usb/gadget/mass_storage.c
+@@ -46,17 +46,7 @@
+ #define FSG_VENDOR_ID 0x0525  /* NetChip */
+ #define FSG_PRODUCT_ID        0xa4a5  /* Linux-USB File-backed Storage Gadget */
+-/*-------------------------------------------------------------------------*/
+-
+-/*
+- * kbuild is not very cooperative with respect to linking separately
+- * compiled library objects into one module.  So for now we won't use
+- * separate compilation ... ensuring init/exit sections work to shrink
+- * the runtime footprint, and giving us at least some parts of what
+- * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+- */
+-#define USB_FMS_INCLUDED
+-#include "f_mass_storage.c"
++#include "f_mass_storage.h"
+ /*-------------------------------------------------------------------------*/
+ USB_GADGET_COMPOSITE_OPTIONS();
+@@ -107,6 +97,9 @@ static struct usb_gadget_strings *dev_strings[] = {
+       NULL,
+ };
++static struct usb_function_instance *fi_msg;
++static struct usb_function *f_msg;
++
+ /****************************** Configurations ******************************/
+ static struct fsg_module_parameters mod_data = {
+@@ -139,13 +132,7 @@ static int msg_thread_exits(struct fsg_common *common)
+ static int __init msg_do_config(struct usb_configuration *c)
+ {
+-      static const struct fsg_operations ops = {
+-              .thread_exits = msg_thread_exits,
+-      };
+-      static struct fsg_common common;
+-
+-      struct fsg_common *retp;
+-      struct fsg_config config;
++      struct fsg_opts *opts;
+       int ret;
+       if (gadget_is_otg(c->cdev->gadget)) {
+@@ -153,15 +140,24 @@ static int __init msg_do_config(struct usb_configuration *c)
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+-      fsg_config_from_params(&config, &mod_data, fsg_num_buffers);
+-      config.ops = &ops;
++      opts = container_of(fi_msg, struct fsg_opts, func_inst);
++
++      f_msg = usb_get_function(fi_msg);
++      if (IS_ERR(f_msg))
++              return PTR_ERR(f_msg);
+-      retp = fsg_common_init(&common, c->cdev, &config);
+-      if (IS_ERR(retp))
+-              return PTR_ERR(retp);
++      ret = fsg_common_run_thread(opts->common);
++      if (ret)
++              goto put_func;
+-      ret = fsg_bind_config(c->cdev, c, &common);
+-      fsg_common_put(&common);
++      ret = usb_add_function(c, f_msg);
++      if (ret)
++              goto put_func;
++
++      return 0;
++
++put_func:
++      usb_put_function(f_msg);
+       return ret;
+ }
+@@ -176,23 +172,79 @@ static struct usb_configuration msg_config_driver = {
+ static int __init msg_bind(struct usb_composite_dev *cdev)
+ {
++      static const struct fsg_operations ops = {
++              .thread_exits = msg_thread_exits,
++      };
++      struct fsg_opts *opts;
++      struct fsg_config config;
+       int status;
++      fi_msg = usb_get_function_instance("mass_storage");
++      if (IS_ERR(fi_msg))
++              return PTR_ERR(fi_msg);
++
++      fsg_config_from_params(&config, &mod_data, fsg_num_buffers);
++      opts = container_of(fi_msg, struct fsg_opts, func_inst);
++
++      opts->no_configfs = true;
++      status = fsg_common_set_num_buffers(opts->common, fsg_num_buffers);
++      if (status)
++              goto fail;
++
++      status = fsg_common_set_nluns(opts->common, config.nluns);
++      if (status)
++              goto fail_set_nluns;
++
++      fsg_common_set_ops(opts->common, &ops);
++
++      status = fsg_common_set_cdev(opts->common, cdev, config.can_stall);
++      if (status)
++              goto fail_set_cdev;
++
++      fsg_common_set_sysfs(opts->common, true);
++      status = fsg_common_create_luns(opts->common, &config);
++      if (status)
++              goto fail_set_cdev;
++
++      fsg_common_set_inquiry_string(opts->common, config.vendor_name,
++                                    config.product_name);
++
+       status = usb_string_ids_tab(cdev, strings_dev);
+       if (status < 0)
+-              return status;
++              goto fail_string_ids;
+       msg_device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id;
+       status = usb_add_config(cdev, &msg_config_driver, msg_do_config);
+       if (status < 0)
+-              return status;
++              goto fail_string_ids;
++
+       usb_composite_overwrite_options(cdev, &coverwrite);
+       dev_info(&cdev->gadget->dev,
+                DRIVER_DESC ", version: " DRIVER_VERSION "\n");
+       set_bit(0, &msg_registered);
+       return 0;
++
++fail_string_ids:
++      fsg_common_remove_luns(opts->common);
++fail_set_cdev:
++      fsg_common_free_luns(opts->common);
++fail_set_nluns:
++      fsg_common_free_buffers(opts->common);
++fail:
++      usb_put_function_instance(fi_msg);
++      return status;
+ }
++static int msg_unbind(struct usb_composite_dev *cdev)
++{
++      if (!IS_ERR(f_msg))
++              usb_put_function(f_msg);
++
++      if (!IS_ERR(fi_msg))
++              usb_put_function_instance(fi_msg);
++
++      return 0;
++}
+ /****************************** Some noise ******************************/
+@@ -203,6 +255,7 @@ static __refdata struct usb_composite_driver msg_driver = {
+       .needs_serial   = 1,
+       .strings        = dev_strings,
+       .bind           = msg_bind,
++      .unbind         = msg_unbind,
+ };
+ MODULE_DESCRIPTION(DRIVER_DESC);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0672-usb-gadget-storage_common-make-attribute-operations-.patch b/patches.tizen/0672-usb-gadget-storage_common-make-attribute-operations-.patch
new file mode 100644 (file)
index 0000000..d2e94ca
--- /dev/null
@@ -0,0 +1,237 @@
+From 724a908e741cbd713c95f2a2cedb6a4c7d97ed38 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 3 Jul 2013 14:43:07 +0200
+Subject: [PATCH 0672/1302] usb/gadget: storage_common: make attribute
+ operations more generic
+
+Show/store methods for sysfs attributes contain code which can be used
+also by configfs. Make them abstract the source the lun and rw_semaphore
+are taken from.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 67 ++++++++++++++++++++++++++++++++++---
+ drivers/usb/gadget/storage_common.c | 36 +++++---------------
+ drivers/usb/gadget/storage_common.h | 21 ++++++------
+ 3 files changed, 81 insertions(+), 43 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 0a2b3ae..aaa8349 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -2570,14 +2570,71 @@ static int fsg_main_thread(void *common_)
+ /*************************** DEVICE ATTRIBUTES ***************************/
+-static DEVICE_ATTR(ro, 0644, fsg_show_ro, fsg_store_ro);
+-static DEVICE_ATTR(nofua, 0644, fsg_show_nofua, fsg_store_nofua);
+-static DEVICE_ATTR(file, 0644, fsg_show_file, fsg_store_file);
++static ssize_t sysfs_fsg_show_ro(struct device *dev,
++                               struct device_attribute *attr,
++                               char *buf)
++{
++      struct fsg_lun          *curlun = fsg_lun_from_dev(dev);
++
++      return fsg_show_ro(curlun, buf);
++}
++
++static ssize_t sysfs_fsg_show_nofua(struct device *dev,
++                                  struct device_attribute *attr,
++                                  char *buf)
++{
++      struct fsg_lun          *curlun = fsg_lun_from_dev(dev);
++
++      return fsg_show_nofua(curlun, buf);
++}
++
++static ssize_t sysfs_fsg_show_file(struct device *dev,
++                                 struct device_attribute *attr,
++                                 char *buf)
++{
++      struct fsg_lun          *curlun = fsg_lun_from_dev(dev);
++      struct rw_semaphore     *filesem = dev_get_drvdata(dev);
++
++      return fsg_show_file(curlun, filesem, buf);
++}
++
++static ssize_t sysfs_fsg_store_ro(struct device *dev,
++                                struct device_attribute *attr,
++                                const char *buf, size_t count)
++{
++      struct fsg_lun          *curlun = fsg_lun_from_dev(dev);
++      struct rw_semaphore     *filesem = dev_get_drvdata(dev);
++
++      return fsg_store_ro(curlun, filesem, buf, count);
++}
++
++static ssize_t sysfs_fsg_store_nofua(struct device *dev,
++                                   struct device_attribute *attr,
++                                   const char *buf, size_t count)
++{
++      struct fsg_lun          *curlun = fsg_lun_from_dev(dev);
++
++      return fsg_store_nofua(curlun, buf, count);
++}
++
++static ssize_t sysfs_fsg_store_file(struct device *dev,
++                                  struct device_attribute *attr,
++                                  const char *buf, size_t count)
++{
++      struct fsg_lun          *curlun = fsg_lun_from_dev(dev);
++      struct rw_semaphore     *filesem = dev_get_drvdata(dev);
++
++      return fsg_store_file(curlun, filesem, buf, count);
++}
++
++static DEVICE_ATTR(ro, 0644, sysfs_fsg_show_ro, sysfs_fsg_store_ro);
++static DEVICE_ATTR(nofua, 0644, sysfs_fsg_show_nofua, sysfs_fsg_store_nofua);
++static DEVICE_ATTR(file, 0644, sysfs_fsg_show_file, sysfs_fsg_store_file);
+ static struct device_attribute dev_attr_ro_cdrom =
+-      __ATTR(ro, 0444, fsg_show_ro, NULL);
++      __ATTR(ro, 0444, sysfs_fsg_show_ro, NULL);
+ static struct device_attribute dev_attr_file_nonremovable =
+-      __ATTR(file, 0444, fsg_show_file, NULL);
++      __ATTR(file, 0444, sysfs_fsg_show_file, NULL);
+ /****************************** FSG COMMON ******************************/
+diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
+index 942324c..ab83d11 100644
+--- a/drivers/usb/gadget/storage_common.c
++++ b/drivers/usb/gadget/storage_common.c
+@@ -31,11 +31,6 @@
+ #include "storage_common.h"
+-static inline struct fsg_lun *fsg_lun_from_dev(struct device *dev)
+-{
+-      return container_of(dev, struct fsg_lun, dev);
+-}
+-
+ /* There is only one interface. */
+ struct usb_interface_descriptor fsg_intf_desc = {
+@@ -324,31 +319,23 @@ EXPORT_SYMBOL(store_cdrom_address);
+ /*-------------------------------------------------------------------------*/
+-ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr,
+-                         char *buf)
++ssize_t fsg_show_ro(struct fsg_lun *curlun, char *buf)
+ {
+-      struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+-
+       return sprintf(buf, "%d\n", fsg_lun_is_open(curlun)
+                                 ? curlun->ro
+                                 : curlun->initially_ro);
+ }
+ EXPORT_SYMBOL(fsg_show_ro);
+-ssize_t fsg_show_nofua(struct device *dev, struct device_attribute *attr,
+-                            char *buf)
++ssize_t fsg_show_nofua(struct fsg_lun *curlun, char *buf)
+ {
+-      struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+-
+       return sprintf(buf, "%u\n", curlun->nofua);
+ }
+ EXPORT_SYMBOL(fsg_show_nofua);
+-ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
+-                           char *buf)
++ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
++                    char *buf)
+ {
+-      struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+-      struct rw_semaphore     *filesem = dev_get_drvdata(dev);
+       char            *p;
+       ssize_t         rc;
+@@ -373,12 +360,10 @@ ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
+ EXPORT_SYMBOL(fsg_show_file);
+-ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr,
++ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                           const char *buf, size_t count)
+ {
+       ssize_t         rc;
+-      struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+-      struct rw_semaphore     *filesem = dev_get_drvdata(dev);
+       unsigned        ro;
+       rc = kstrtouint(buf, 2, &ro);
+@@ -404,11 +389,8 @@ ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr,
+ }
+ EXPORT_SYMBOL(fsg_store_ro);
+-ssize_t fsg_store_nofua(struct device *dev,
+-                             struct device_attribute *attr,
+-                             const char *buf, size_t count)
++ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count)
+ {
+-      struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+       unsigned        nofua;
+       int             ret;
+@@ -426,11 +408,9 @@ ssize_t fsg_store_nofua(struct device *dev,
+ }
+ EXPORT_SYMBOL(fsg_store_nofua);
+-ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr,
+-                            const char *buf, size_t count)
++ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
++                     const char *buf, size_t count)
+ {
+-      struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+-      struct rw_semaphore     *filesem = dev_get_drvdata(dev);
+       int             rc = 0;
+       if (curlun->prevent_medium_removal && fsg_lun_is_open(curlun)) {
+diff --git a/drivers/usb/gadget/storage_common.h b/drivers/usb/gadget/storage_common.h
+index 9955477..aa8bf94 100644
+--- a/drivers/usb/gadget/storage_common.h
++++ b/drivers/usb/gadget/storage_common.h
+@@ -181,6 +181,11 @@ static inline u32 get_unaligned_be24(u8 *buf)
+       return 0xffffff & (u32) get_unaligned_be32(buf - 1);
+ }
++static inline struct fsg_lun *fsg_lun_from_dev(struct device *dev)
++{
++      return container_of(dev, struct fsg_lun, dev);
++}
++
+ enum {
+       FSG_STRING_INTERFACE
+ };
+@@ -205,18 +210,14 @@ void fsg_lun_close(struct fsg_lun *curlun);
+ int fsg_lun_open(struct fsg_lun *curlun, const char *filename);
+ int fsg_lun_fsync_sub(struct fsg_lun *curlun);
+ void store_cdrom_address(u8 *dest, int msf, u32 addr);
+-ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr,
+-                  char *buf);
+-ssize_t fsg_show_nofua(struct device *dev, struct device_attribute *attr,
+-                     char *buf);
+-ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
++ssize_t fsg_show_ro(struct fsg_lun *curlun, char *buf);
++ssize_t fsg_show_nofua(struct fsg_lun *curlun, char *buf);
++ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                     char *buf);
+-ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr,
++ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                    const char *buf, size_t count);
+-ssize_t fsg_store_nofua(struct device *dev,
+-                      struct device_attribute *attr,
+-                      const char *buf, size_t count);
+-ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr,
++ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count);
++ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                      const char *buf, size_t count);
+ #endif /* USB_STORAGE_COMMON_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0673-usb-gadget-storage_common-add-methods-to-show-store-.patch b/patches.tizen/0673-usb-gadget-storage_common-add-methods-to-show-store-.patch
new file mode 100644 (file)
index 0000000..df2d8b5
--- /dev/null
@@ -0,0 +1,97 @@
+From 80b546ca2f7a1d6714022e3c791635d7b6ba9766 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 3 Jul 2013 14:44:11 +0200
+Subject: [PATCH 0673/1302] usb/gadget: storage_common: add methods to
+ show/store 'cdrom' and 'removable'
+
+This will be required by configfs integration.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/storage_common.c | 42 +++++++++++++++++++++++++++++++++++++
+ drivers/usb/gadget/storage_common.h |  5 +++++
+ 2 files changed, 47 insertions(+)
+
+diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
+index ab83d11..d59b555 100644
+--- a/drivers/usb/gadget/storage_common.c
++++ b/drivers/usb/gadget/storage_common.c
+@@ -359,6 +359,17 @@ ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+ }
+ EXPORT_SYMBOL(fsg_show_file);
++ssize_t fsg_show_cdrom(struct fsg_lun *curlun, char *buf)
++{
++      return sprintf(buf, "%u\n", curlun->cdrom);
++}
++EXPORT_SYMBOL(fsg_show_cdrom);
++
++ssize_t fsg_show_removable(struct fsg_lun *curlun, char *buf)
++{
++      return sprintf(buf, "%u\n", curlun->removable);
++}
++EXPORT_SYMBOL(fsg_show_removable);
+ ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                           const char *buf, size_t count)
+@@ -439,4 +450,35 @@ ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+ }
+ EXPORT_SYMBOL(fsg_store_file);
++ssize_t fsg_store_cdrom(struct fsg_lun *curlun, const char *buf, size_t count)
++{
++      unsigned        cdrom;
++      int             ret;
++
++      ret = kstrtouint(buf, 2, &cdrom);
++      if (ret)
++              return ret;
++
++      curlun->cdrom = cdrom;
++
++      return count;
++}
++EXPORT_SYMBOL(fsg_store_cdrom);
++
++ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf,
++                          size_t count)
++{
++      unsigned        removable;
++      int             ret;
++
++      ret = kstrtouint(buf, 2, &removable);
++      if (ret)
++              return ret;
++
++      curlun->removable = removable;
++
++      return count;
++}
++EXPORT_SYMBOL(fsg_store_removable);
++
+ MODULE_LICENSE("GPL");
+diff --git a/drivers/usb/gadget/storage_common.h b/drivers/usb/gadget/storage_common.h
+index aa8bf94..ca7b479 100644
+--- a/drivers/usb/gadget/storage_common.h
++++ b/drivers/usb/gadget/storage_common.h
+@@ -214,10 +214,15 @@ ssize_t fsg_show_ro(struct fsg_lun *curlun, char *buf);
+ ssize_t fsg_show_nofua(struct fsg_lun *curlun, char *buf);
+ ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                     char *buf);
++ssize_t fsg_show_cdrom(struct fsg_lun *curlun, char *buf);
++ssize_t fsg_show_removable(struct fsg_lun *curlun, char *buf);
+ ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                    const char *buf, size_t count);
+ ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count);
+ ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                      const char *buf, size_t count);
++ssize_t fsg_store_cdrom(struct fsg_lun *curlun, const char *buf, size_t count);
++ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf,
++                          size_t count);
+ #endif /* USB_STORAGE_COMMON_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0674-usb-gadget-f_mass_storage-add-configfs-support.patch b/patches.tizen/0674-usb-gadget-f_mass_storage-add-configfs-support.patch
new file mode 100644 (file)
index 0000000..1c443d5
--- /dev/null
@@ -0,0 +1,533 @@
+From d1e1911c9b87f7c8aa7cf22ce76dd4cb5a669cdf Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Fri, 19 Jul 2013 09:14:44 +0200
+Subject: [PATCH 0674/1302] usb/gadget: f_mass_storage: add configfs support
+
+From this commit on f_mass_storage is available through configfs.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../ABI/testing/configfs-usb-gadget-mass-storage   |  31 ++
+ drivers/usb/gadget/Kconfig                         |  11 +
+ drivers/usb/gadget/f_mass_storage.c                | 368 +++++++++++++++++++++
+ drivers/usb/gadget/f_mass_storage.h                |  17 +
+ 4 files changed, 427 insertions(+)
+ create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-mass-storage
+
+diff --git a/Documentation/ABI/testing/configfs-usb-gadget-mass-storage b/Documentation/ABI/testing/configfs-usb-gadget-mass-storage
+new file mode 100644
+index 0000000..e1e918e
+--- /dev/null
++++ b/Documentation/ABI/testing/configfs-usb-gadget-mass-storage
+@@ -0,0 +1,31 @@
++What:         /config/usb-gadget/gadget/functions/mass_storage.name
++Date:         Jul 2013
++KenelVersion: 3.12
++Description:
++              The attributes:
++
++              stall           - Set to permit function to halt bulk endpoints.
++                              Disabled on some USB devices known not to work
++                              correctly. You should set it to true.
++              num_buffers     - Number of pipeline buffers. Valid numbers
++                              are 2..4. Available only if
++                              CONFIG_USB_GADGET_DEBUG_FILES is set.
++
++What:         /config/usb-gadget/gadget/functions/mass_storage.name/lun.name
++Date:         Jul 2013
++KenelVersion: 3.12
++Description:
++              The attributes:
++
++              file            - The path to the backing file for the LUN.
++                              Required if LUN is not marked as removable.
++              ro              - Flag specifying access to the LUN shall be
++                              read-only. This is implied if CD-ROM emulation
++                              is enabled as well as when it was impossible
++                              to open "filename" in R/W mode.
++              removable       - Flag specifying that LUN shall be indicated as
++                              being removable.
++              cdrom           - Flag specifying that LUN shall be reported as
++                              being a CD-ROM.
++              nofua           - Flag specifying that FUA flag
++                              in SCSI WRITE(10,12)
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 073ba0f..d499c25 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -680,6 +680,17 @@ config USB_CONFIGFS_PHONET
+       help
+         The Phonet protocol implementation for USB device.
++config USB_CONFIGFS_MASS_STORAGE
++      boolean "Mass storage"
++      depends on USB_CONFIGFS
++      select USB_U_MS
++      select USB_F_MASS_STORAGE
++      help
++        The Mass Storage Gadget acts as a USB Mass Storage disk drive.
++        As its storage repository it can use a regular file or a block
++        device (in much the same way as the "loop" device driver),
++        specified as a module parameter or sysfs option.
++
+ config USB_ZERO
+       tristate "Gadget Zero (DEVELOPMENT)"
+       select USB_LIBCOMPOSITE
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index aaa8349..f1aa6c0 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -220,6 +220,7 @@
+ #include <linux/usb/composite.h>
+ #include "gadget_chips.h"
++#include "configfs.h"
+ /*------------------------------------------------------------------------*/
+@@ -3333,6 +3334,350 @@ static int fsg_bind_config(struct usb_composite_dev *cdev,
+ #else
++static inline struct fsg_lun_opts *to_fsg_lun_opts(struct config_item *item)
++{
++      return container_of(to_config_group(item), struct fsg_lun_opts, group);
++}
++
++static inline struct fsg_opts *to_fsg_opts(struct config_item *item)
++{
++      return container_of(to_config_group(item), struct fsg_opts,
++                          func_inst.group);
++}
++
++CONFIGFS_ATTR_STRUCT(fsg_lun_opts);
++CONFIGFS_ATTR_OPS(fsg_lun_opts);
++
++static void fsg_lun_attr_release(struct config_item *item)
++{
++      struct fsg_lun_opts *lun_opts;
++
++      lun_opts = to_fsg_lun_opts(item);
++      kfree(lun_opts);
++}
++
++static struct configfs_item_operations fsg_lun_item_ops = {
++      .release        = fsg_lun_attr_release,
++      .show_attribute = fsg_lun_opts_attr_show,
++      .store_attribute = fsg_lun_opts_attr_store,
++};
++
++static ssize_t fsg_lun_opts_file_show(struct fsg_lun_opts *opts, char *page)
++{
++      struct fsg_opts *fsg_opts;
++
++      fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
++
++      return fsg_show_file(opts->lun, &fsg_opts->common->filesem, page);
++}
++
++static ssize_t fsg_lun_opts_file_store(struct fsg_lun_opts *opts,
++                                     const char *page, size_t len)
++{
++      struct fsg_opts *fsg_opts;
++
++      fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
++
++      return fsg_store_file(opts->lun, &fsg_opts->common->filesem, page, len);
++}
++
++static struct fsg_lun_opts_attribute fsg_lun_opts_file =
++      __CONFIGFS_ATTR(file, S_IRUGO | S_IWUSR, fsg_lun_opts_file_show,
++                      fsg_lun_opts_file_store);
++
++static ssize_t fsg_lun_opts_ro_show(struct fsg_lun_opts *opts, char *page)
++{
++      return fsg_show_ro(opts->lun, page);
++}
++
++static ssize_t fsg_lun_opts_ro_store(struct fsg_lun_opts *opts,
++                                     const char *page, size_t len)
++{
++      struct fsg_opts *fsg_opts;
++
++      fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
++
++      return fsg_store_ro(opts->lun, &fsg_opts->common->filesem, page, len);
++}
++
++static struct fsg_lun_opts_attribute fsg_lun_opts_ro =
++      __CONFIGFS_ATTR(ro, S_IRUGO | S_IWUSR, fsg_lun_opts_ro_show,
++                      fsg_lun_opts_ro_store);
++
++static ssize_t fsg_lun_opts_removable_show(struct fsg_lun_opts *opts,
++                                         char *page)
++{
++      return fsg_show_removable(opts->lun, page);
++}
++
++static ssize_t fsg_lun_opts_removable_store(struct fsg_lun_opts *opts,
++                                     const char *page, size_t len)
++{
++      return fsg_store_removable(opts->lun, page, len);
++}
++
++static struct fsg_lun_opts_attribute fsg_lun_opts_removable =
++      __CONFIGFS_ATTR(removable, S_IRUGO | S_IWUSR,
++                      fsg_lun_opts_removable_show,
++                      fsg_lun_opts_removable_store);
++
++static ssize_t fsg_lun_opts_cdrom_show(struct fsg_lun_opts *opts, char *page)
++{
++      return fsg_show_cdrom(opts->lun, page);
++}
++
++static ssize_t fsg_lun_opts_cdrom_store(struct fsg_lun_opts *opts,
++                                     const char *page, size_t len)
++{
++      return fsg_store_cdrom(opts->lun, page, len);
++}
++
++static struct fsg_lun_opts_attribute fsg_lun_opts_cdrom =
++      __CONFIGFS_ATTR(cdrom, S_IRUGO | S_IWUSR, fsg_lun_opts_cdrom_show,
++                      fsg_lun_opts_cdrom_store);
++
++static ssize_t fsg_lun_opts_nofua_show(struct fsg_lun_opts *opts, char *page)
++{
++      return fsg_show_nofua(opts->lun, page);
++}
++
++static ssize_t fsg_lun_opts_nofua_store(struct fsg_lun_opts *opts,
++                                     const char *page, size_t len)
++{
++      return fsg_store_nofua(opts->lun, page, len);
++}
++
++static struct fsg_lun_opts_attribute fsg_lun_opts_nofua =
++      __CONFIGFS_ATTR(nofua, S_IRUGO | S_IWUSR, fsg_lun_opts_nofua_show,
++                      fsg_lun_opts_nofua_store);
++
++static struct configfs_attribute *fsg_lun_attrs[] = {
++      &fsg_lun_opts_file.attr,
++      &fsg_lun_opts_ro.attr,
++      &fsg_lun_opts_removable.attr,
++      &fsg_lun_opts_cdrom.attr,
++      &fsg_lun_opts_nofua.attr,
++      NULL,
++};
++
++static struct config_item_type fsg_lun_type = {
++      .ct_item_ops    = &fsg_lun_item_ops,
++      .ct_attrs       = fsg_lun_attrs,
++      .ct_owner       = THIS_MODULE,
++};
++
++#define MAX_NAME_LEN  40
++
++static struct config_group *fsg_lun_make(struct config_group *group,
++                                       const char *name)
++{
++      struct fsg_lun_opts *opts;
++      struct fsg_opts *fsg_opts;
++      char buf[MAX_NAME_LEN];
++      char lun_name[MAX_LUN_NAME_LEN];
++      struct fsg_lun_config config;
++      char *num_str;
++      u8 num;
++      int ret;
++
++      ret = snprintf(buf, MAX_NAME_LEN, "%s", name);
++      if (ret >= MAX_NAME_LEN)
++              return ERR_PTR(-ENAMETOOLONG);
++
++      num_str = strchr(buf, '.');
++      if (!num_str) {
++              pr_err("Unable to locate . in LUN.NUMBER\n");
++              return ERR_PTR(-EINVAL);
++      }
++      *num_str = '\0';
++      num_str++;
++
++      ret = kstrtou8(num_str, 0, &num);
++      if (ret)
++              return ERR_PTR(ret);
++
++      fsg_opts = to_fsg_opts(&group->cg_item);
++      if (num >= FSG_MAX_LUNS)
++              return ERR_PTR(-ENODEV);
++      mutex_lock(&fsg_opts->lock);
++      if (fsg_opts->refcnt || fsg_opts->common->luns[num]) {
++              ret = -EBUSY;
++              goto out;
++      }
++
++      opts = kzalloc(sizeof(*opts), GFP_KERNEL);
++      if (!opts) {
++              ret = -ENOMEM;
++              goto out;
++      }
++
++      memset(&config, 0, sizeof(config));
++      config.removable = true;
++
++      snprintf(lun_name, MAX_LUN_NAME_LEN, "%s/%s",
++               group->cg_item.ci_name, name);
++      ret = fsg_common_create_lun(fsg_opts->common, &config, num, lun_name,
++                                  NULL);
++      if (ret) {
++              kfree(opts);
++              goto out;
++      }
++      opts->lun = fsg_opts->common->luns[num];
++      opts->lun_id = num;
++      mutex_unlock(&fsg_opts->lock);
++
++      config_group_init_type_name(&opts->group, name, &fsg_lun_type);
++
++      return &opts->group;
++out:
++      mutex_unlock(&fsg_opts->lock);
++      return ERR_PTR(ret);
++}
++
++static void fsg_lun_drop(struct config_group *group, struct config_item *item)
++{
++      struct fsg_lun_opts *lun_opts;
++      struct fsg_opts *fsg_opts;
++
++      lun_opts = to_fsg_lun_opts(item);
++      fsg_opts = to_fsg_opts(&group->cg_item);
++
++      mutex_lock(&fsg_opts->lock);
++      if (fsg_opts->refcnt) {
++              struct config_item *gadget;
++
++              gadget = group->cg_item.ci_parent->ci_parent;
++              unregister_gadget_item(gadget);
++      }
++
++      fsg_common_remove_lun(lun_opts->lun, fsg_opts->common->sysfs);
++      fsg_opts->common->luns[lun_opts->lun_id] = NULL;
++      lun_opts->lun_id = 0;
++      mutex_unlock(&fsg_opts->lock);
++
++      config_item_put(item);
++}
++
++CONFIGFS_ATTR_STRUCT(fsg_opts);
++CONFIGFS_ATTR_OPS(fsg_opts);
++
++static void fsg_attr_release(struct config_item *item)
++{
++      struct fsg_opts *opts = to_fsg_opts(item);
++
++      usb_put_function_instance(&opts->func_inst);
++}
++
++static struct configfs_item_operations fsg_item_ops = {
++      .release        = fsg_attr_release,
++      .show_attribute = fsg_opts_attr_show,
++      .store_attribute = fsg_opts_attr_store,
++};
++
++static ssize_t fsg_opts_stall_show(struct fsg_opts *opts, char *page)
++{
++      int result;
++
++      mutex_lock(&opts->lock);
++      result = sprintf(page, "%d", opts->common->can_stall);
++      mutex_unlock(&opts->lock);
++
++      return result;
++}
++
++static ssize_t fsg_opts_stall_store(struct fsg_opts *opts, const char *page,
++                                  size_t len)
++{
++      int ret;
++      u8 num;
++
++      mutex_lock(&opts->lock);
++      if (opts->refcnt) {
++              ret = -EBUSY;
++              goto end;
++      }
++      ret = kstrtou8(page, 0, &num);
++      if (ret)
++              goto end;
++
++      opts->common->can_stall = num != 0;
++      ret = len;
++
++end:
++      mutex_unlock(&opts->lock);
++      return ret;
++}
++
++static struct fsg_opts_attribute fsg_opts_stall =
++      __CONFIGFS_ATTR(stall, S_IRUGO | S_IWUSR, fsg_opts_stall_show,
++                      fsg_opts_stall_store);
++
++#ifdef CONFIG_USB_GADGET_DEBUG_FILES
++static ssize_t fsg_opts_num_buffers_show(struct fsg_opts *opts, char *page)
++{
++      int result;
++
++      mutex_lock(&opts->lock);
++      result = sprintf(page, "%d", opts->common->fsg_num_buffers);
++      mutex_unlock(&opts->lock);
++
++      return result;
++}
++
++static ssize_t fsg_opts_num_buffers_store(struct fsg_opts *opts,
++                                        const char *page, size_t len)
++{
++      int ret;
++      u8 num;
++
++      mutex_lock(&opts->lock);
++      if (opts->refcnt) {
++              ret = -EBUSY;
++              goto end;
++      }
++      ret = kstrtou8(page, 0, &num);
++      if (ret)
++              goto end;
++
++      ret = fsg_num_buffers_validate(num);
++      if (ret)
++              goto end;
++
++      fsg_common_set_num_buffers(opts->common, num);
++      ret = len;
++
++end:
++      mutex_unlock(&opts->lock);
++      return ret;
++}
++
++static struct fsg_opts_attribute fsg_opts_num_buffers =
++      __CONFIGFS_ATTR(num_buffers, S_IRUGO | S_IWUSR,
++                      fsg_opts_num_buffers_show,
++                      fsg_opts_num_buffers_store);
++
++#endif
++
++static struct configfs_attribute *fsg_attrs[] = {
++      &fsg_opts_stall.attr,
++#ifdef CONFIG_USB_GADGET_DEBUG_FILES
++      &fsg_opts_num_buffers.attr,
++#endif
++      NULL,
++};
++
++static struct configfs_group_operations fsg_group_ops = {
++      .make_group     = fsg_lun_make,
++      .drop_item      = fsg_lun_drop,
++};
++
++static struct config_item_type fsg_func_type = {
++      .ct_item_ops    = &fsg_item_ops,
++      .ct_group_ops   = &fsg_group_ops,
++      .ct_attrs       = fsg_attrs,
++      .ct_owner       = THIS_MODULE,
++};
++
+ static void fsg_free_inst(struct usb_function_instance *fi)
+ {
+       struct fsg_opts *opts;
+@@ -3345,11 +3690,13 @@ static void fsg_free_inst(struct usb_function_instance *fi)
+ static struct usb_function_instance *fsg_alloc_inst(void)
+ {
+       struct fsg_opts *opts;
++      struct fsg_lun_config config;
+       int ret;
+       opts = kzalloc(sizeof(*opts), GFP_KERNEL);
+       if (!opts)
+               return ERR_PTR(-ENOMEM);
++      mutex_init(&opts->lock);
+       opts->func_inst.free_func_inst = fsg_free_inst;
+       opts->common = fsg_common_setup(opts->common, false);
+       if (IS_ERR(opts->common)) {
+@@ -3367,6 +3714,18 @@ static struct usb_function_instance *fsg_alloc_inst(void)
+       pr_info(FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
++      memset(&config, 0, sizeof(config));
++      config.removable = true;
++      ret = fsg_common_create_lun(opts->common, &config, 0, "lun.0",
++                      (const char **)&opts->func_inst.group.cg_item.ci_name);
++      opts->lun0.lun = opts->common->luns[0];
++      opts->lun0.lun_id = 0;
++      config_group_init_type_name(&opts->lun0.group, "lun.0", &fsg_lun_type);
++      opts->default_groups[0] = &opts->lun0.group;
++      opts->func_inst.group.default_groups = opts->default_groups;
++
++      config_group_init_type_name(&opts->func_inst.group, "", &fsg_func_type);
++
+       return &opts->func_inst;
+ release_luns:
+@@ -3379,8 +3738,14 @@ release_opts:
+ static void fsg_free(struct usb_function *f)
+ {
+       struct fsg_dev *fsg;
++      struct fsg_opts *opts;
+       fsg = container_of(f, struct fsg_dev, function);
++      opts = container_of(f->fi, struct fsg_opts, func_inst);
++
++      mutex_lock(&opts->lock);
++      opts->refcnt--;
++      mutex_unlock(&opts->lock);
+       kfree(fsg);
+ }
+@@ -3411,6 +3776,9 @@ static struct usb_function *fsg_alloc(struct usb_function_instance *fi)
+       if (unlikely(!fsg))
+               return ERR_PTR(-ENOMEM);
++      mutex_lock(&opts->lock);
++      opts->refcnt++;
++      mutex_unlock(&opts->lock);
+       fsg->function.name        = FSG_DRIVER_DESC;
+       fsg->function.bind        = fsg_bind;
+       fsg->function.unbind      = fsg_unbind;
+diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h
+index 7aed1d9..62b4b8f 100644
+--- a/drivers/usb/gadget/f_mass_storage.h
++++ b/drivers/usb/gadget/f_mass_storage.h
+@@ -71,10 +71,27 @@ struct fsg_operations {
+       int (*thread_exits)(struct fsg_common *common);
+ };
++struct fsg_lun_opts {
++      struct config_group group;
++      struct fsg_lun *lun;
++      int lun_id;
++};
++
+ struct fsg_opts {
+       struct fsg_common *common;
+       struct usb_function_instance func_inst;
++      struct fsg_lun_opts lun0;
++      struct config_group *default_groups[2];
+       bool no_configfs; /* for legacy gadgets */
++
++      /*
++       * Read/write access to configfs attributes is handled by configfs.
++       *
++       * This is to protect the data from concurrent access by read/write
++       * and create symlink/remove symlink.
++       */
++      struct mutex                    lock;
++      int                             refcnt;
+ };
+ struct fsg_lun_config {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0675-usb-gadget-acm_ms-convert-to-new-interface-of-f_mass.patch b/patches.tizen/0675-usb-gadget-acm_ms-convert-to-new-interface-of-f_mass.patch
new file mode 100644 (file)
index 0000000..ee338d8
--- /dev/null
@@ -0,0 +1,225 @@
+From 7ab27e2ab83e3d760dd4ebb8175eac0f04f776f2 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 30 Jul 2013 11:22:47 +0200
+Subject: [PATCH 0675/1302] usb/gadget: acm_ms: convert to new interface of
+ f_mass_storage
+
+Convert the legacy acm_ms gadget to use the new function interface
+of f_mass_storage, so that later the compatibility layer in
+f_mass_storage can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig  |   1 +
+ drivers/usb/gadget/acm_ms.c | 113 +++++++++++++++++++++++++++++---------------
+ 2 files changed, 75 insertions(+), 39 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index d499c25..f03dd3c 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -1033,6 +1033,7 @@ config USB_G_ACM_MS
+       select USB_U_SERIAL
+       select USB_F_ACM
+       select USB_U_MS
++      select USB_F_MASS_STORAGE
+       help
+         This driver provides two functions in one configuration:
+         a mass storage, and a CDC ACM (serial port) link.
+diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c
+index 31aae8f..b405bc4 100644
+--- a/drivers/usb/gadget/acm_ms.c
++++ b/drivers/usb/gadget/acm_ms.c
+@@ -31,17 +31,7 @@
+ #define ACM_MS_VENDOR_NUM     0x1d6b  /* Linux Foundation */
+ #define ACM_MS_PRODUCT_NUM    0x0106  /* Composite Gadget: ACM + MS*/
+-/*-------------------------------------------------------------------------*/
+-
+-/*
+- * Kbuild is not very cooperative with respect to linking separately
+- * compiled library objects into one module.  So for now we won't use
+- * separate compilation ... ensuring init/exit sections work to shrink
+- * the runtime footprint, and giving us at least some parts of what
+- * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+- */
+-#define USB_FMS_INCLUDED
+-#include "f_mass_storage.c"
++#include "f_mass_storage.h"
+ /*-------------------------------------------------------------------------*/
+ USB_GADGET_COMPOSITE_OPTIONS();
+@@ -121,16 +111,19 @@ static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
+ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
+-static struct fsg_common fsg_common;
+-
+ /*-------------------------------------------------------------------------*/
+ static struct usb_function *f_acm;
+ static struct usb_function_instance *f_acm_inst;
++
++static struct usb_function_instance *fi_msg;
++static struct usb_function *f_msg;
++
+ /*
+  * We _always_ have both ACM and mass storage functions.
+  */
+ static int __init acm_ms_do_config(struct usb_configuration *c)
+ {
++      struct fsg_opts *opts;
+       int     status;
+       if (gadget_is_otg(c->cdev->gadget)) {
+@@ -138,31 +131,37 @@ static int __init acm_ms_do_config(struct usb_configuration *c)
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+-      f_acm_inst = usb_get_function_instance("acm");
+-      if (IS_ERR(f_acm_inst))
+-              return PTR_ERR(f_acm_inst);
++      opts = container_of(fi_msg, struct fsg_opts, func_inst);
+       f_acm = usb_get_function(f_acm_inst);
+-      if (IS_ERR(f_acm)) {
+-              status = PTR_ERR(f_acm);
+-              goto err_func;
++      if (IS_ERR(f_acm))
++              return PTR_ERR(f_acm);
++
++      f_msg = usb_get_function(fi_msg);
++      if (IS_ERR(f_msg)) {
++              status = PTR_ERR(f_msg);
++              goto put_acm;
+       }
+       status = usb_add_function(c, f_acm);
+       if (status < 0)
+-              goto err_conf;
++              goto put_msg;
+-      status = fsg_bind_config(c->cdev, c, &fsg_common);
+-      if (status < 0)
+-              goto err_fsg;
++      status = fsg_common_run_thread(opts->common);
++      if (status)
++              goto remove_acm;
++
++      status = usb_add_function(c, f_msg);
++      if (status)
++              goto remove_acm;
+       return 0;
+-err_fsg:
++remove_acm:
+       usb_remove_function(c, f_acm);
+-err_conf:
++put_msg:
++      usb_put_function(f_msg);
++put_acm:
+       usb_put_function(f_acm);
+-err_func:
+-      usb_put_function_instance(f_acm_inst);
+       return status;
+ }
+@@ -178,46 +177,82 @@ static struct usb_configuration acm_ms_config_driver = {
+ static int __init acm_ms_bind(struct usb_composite_dev *cdev)
+ {
+       struct usb_gadget       *gadget = cdev->gadget;
++      struct fsg_opts         *opts;
++      struct fsg_config       config;
+       int                     status;
+-      void                    *retp;
+-      /* set up mass storage function */
+-      retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data,
+-                                    fsg_num_buffers);
+-      if (IS_ERR(retp)) {
+-              status = PTR_ERR(retp);
+-              return PTR_ERR(retp);
++      f_acm_inst = usb_get_function_instance("acm");
++      if (IS_ERR(f_acm_inst))
++              return PTR_ERR(f_acm_inst);
++
++      fi_msg = usb_get_function_instance("mass_storage");
++      if (IS_ERR(fi_msg)) {
++              status = PTR_ERR(fi_msg);
++              goto fail_get_msg;
+       }
++      /* set up mass storage function */
++      fsg_config_from_params(&config, &fsg_mod_data, fsg_num_buffers);
++      opts = container_of(fi_msg, struct fsg_opts, func_inst);
++
++      opts->no_configfs = true;
++      status = fsg_common_set_num_buffers(opts->common, fsg_num_buffers);
++      if (status)
++              goto fail;
++
++      status = fsg_common_set_nluns(opts->common, config.nluns);
++      if (status)
++              goto fail_set_nluns;
++
++      status = fsg_common_set_cdev(opts->common, cdev, config.can_stall);
++      if (status)
++              goto fail_set_cdev;
++
++      fsg_common_set_sysfs(opts->common, true);
++      status = fsg_common_create_luns(opts->common, &config);
++      if (status)
++              goto fail_set_cdev;
++
++      fsg_common_set_inquiry_string(opts->common, config.vendor_name,
++                                    config.product_name);
+       /*
+        * Allocate string descriptor numbers ... note that string
+        * contents can be overridden by the composite_dev glue.
+        */
+       status = usb_string_ids_tab(cdev, strings_dev);
+       if (status < 0)
+-              goto fail1;
++              goto fail_string_ids;
+       device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id;
+       device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id;
+       /* register our configuration */
+       status = usb_add_config(cdev, &acm_ms_config_driver, acm_ms_do_config);
+       if (status < 0)
+-              goto fail1;
++              goto fail_string_ids;
+       usb_composite_overwrite_options(cdev, &coverwrite);
+       dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n",
+                       DRIVER_DESC);
+-      fsg_common_put(&fsg_common);
+       return 0;
+       /* error recovery */
+-fail1:
+-      fsg_common_put(&fsg_common);
++fail_string_ids:
++      fsg_common_remove_luns(opts->common);
++fail_set_cdev:
++      fsg_common_free_luns(opts->common);
++fail_set_nluns:
++      fsg_common_free_buffers(opts->common);
++fail:
++      usb_put_function_instance(fi_msg);
++fail_get_msg:
++      usb_put_function_instance(f_acm_inst);
+       return status;
+ }
+ static int __exit acm_ms_unbind(struct usb_composite_dev *cdev)
+ {
++      usb_put_function(f_msg);
++      usb_put_function_instance(fi_msg);
+       usb_put_function(f_acm);
+       usb_put_function_instance(f_acm_inst);
+       return 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0676-usb-gadget-multi-convert-to-new-interface-of-f_ecm.patch b/patches.tizen/0676-usb-gadget-multi-convert-to-new-interface-of-f_ecm.patch
new file mode 100644 (file)
index 0000000..4e04c32
--- /dev/null
@@ -0,0 +1,192 @@
+From 0f51ef4507d61692afe5de4598b8f5df82f1ada1 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Fri, 26 Jul 2013 11:12:46 +0200
+Subject: [PATCH 0676/1302] usb/gadget: multi: convert to new interface of
+ f_ecm
+
+Convert the legacy multi gadget to the new interface of f_ecm,
+so that later the compatibility layer in f_ecm can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig |  1 +
+ drivers/usb/gadget/multi.c | 68 ++++++++++++++++++++++++++++++++++++++++------
+ 2 files changed, 61 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index f03dd3c..ae584e9 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -1082,6 +1082,7 @@ config USB_G_MULTI_CDC
+       bool "CDC Ethernet + CDC Serial + Storage configuration"
+       depends on USB_G_MULTI
+       default n
++      select USB_F_ECM
+       help
+         This option enables a configuration with CDC Ethernet (ECM), CDC
+         Serial and Mass Storage functions available in the Multifunction
+diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
+index c232f76..0d1d132 100644
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -15,6 +15,7 @@
+ #include <linux/kernel.h>
+ #include <linux/module.h>
++#include <linux/netdevice.h>
+ #include "u_serial.h"
+ #if defined USB_ETH_RNDIS
+@@ -44,8 +45,7 @@ MODULE_LICENSE("GPL");
+ #define USB_FMS_INCLUDED
+ #include "f_mass_storage.c"
+-#define USBF_ECM_INCLUDED
+-#include "f_ecm.c"
++#include "u_ecm.h"
+ #ifdef USB_ETH_RNDIS
+ #  define USB_FRNDIS_INCLUDED
+ #  include "f_rndis.c"
+@@ -151,14 +151,14 @@ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
+ static struct fsg_common fsg_common;
+-static u8 host_mac[ETH_ALEN];
+-
+ static struct usb_function_instance *fi_acm;
+ static struct eth_dev *the_dev;
+ /********** RNDIS **********/
+ #ifdef USB_ETH_RNDIS
++static u8 host_mac[ETH_ALEN];
++
+ static struct usb_function *f_acm_rndis;
+ static __init int rndis_do_config(struct usb_configuration *c)
+@@ -220,7 +220,9 @@ static int rndis_config_register(struct usb_composite_dev *cdev)
+ /********** CDC ECM **********/
+ #ifdef CONFIG_USB_G_MULTI_CDC
++static struct usb_function_instance *fi_ecm;
+ static struct usb_function *f_acm_multi;
++static struct usb_function *f_ecm;
+ static __init int cdc_do_config(struct usb_configuration *c)
+ {
+@@ -231,14 +233,20 @@ static __init int cdc_do_config(struct usb_configuration *c)
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+-      ret = ecm_bind_config(c, host_mac, the_dev);
++      f_ecm = usb_get_function(fi_ecm);
++      if (IS_ERR(f_ecm))
++              return PTR_ERR(f_ecm);
++
++      ret = usb_add_function(c, f_ecm);
+       if (ret < 0)
+-              return ret;
++              goto err_func_ecm;
+       /* implicit port_num is zero */
+       f_acm_multi = usb_get_function(fi_acm);
+-      if (IS_ERR(f_acm_multi))
+-              return PTR_ERR(f_acm_multi);
++      if (IS_ERR(f_acm_multi)) {
++              ret = PTR_ERR(f_acm_multi);
++              goto err_func_acm;
++      }
+       ret = usb_add_function(c, f_acm_multi);
+       if (ret)
+@@ -253,6 +261,10 @@ err_fsg:
+       usb_remove_function(c, f_acm_multi);
+ err_conf:
+       usb_put_function(f_acm_multi);
++err_func_acm:
++      usb_remove_function(c, f_ecm);
++err_func_ecm:
++      usb_put_function(f_ecm);
+       return ret;
+ }
+@@ -285,6 +297,9 @@ static int cdc_config_register(struct usb_composite_dev *cdev)
+ static int __ref multi_bind(struct usb_composite_dev *cdev)
+ {
+       struct usb_gadget *gadget = cdev->gadget;
++#ifdef CONFIG_USB_G_MULTI_CDC
++      struct f_ecm_opts *ecm_opts;
++#endif
+       int status;
+       if (!can_support_ecm(cdev->gadget)) {
+@@ -293,11 +308,39 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
+               return -EINVAL;
+       }
++#ifdef CONFIG_USB_G_MULTI_CDC
++      fi_ecm = usb_get_function_instance("ecm");
++      if (IS_ERR(fi_ecm))
++              return PTR_ERR(fi_ecm);
++
++      ecm_opts = container_of(fi_ecm, struct f_ecm_opts, func_inst);
++
++      gether_set_qmult(ecm_opts->net, qmult);
++      if (!gether_set_host_addr(ecm_opts->net, host_addr))
++              pr_info("using host ethernet address: %s", host_addr);
++      if (!gether_set_dev_addr(ecm_opts->net, dev_addr))
++              pr_info("using self ethernet address: %s", dev_addr);
++
++      the_dev = netdev_priv(ecm_opts->net);
++
++#elif defined USB_ETH_RNDIS
++
+       /* set up network link layer */
+       the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, host_mac,
+                              qmult);
+       if (IS_ERR(the_dev))
+               return PTR_ERR(the_dev);
++#endif
++
++#if (defined CONFIG_USB_G_MULTI_CDC && defined USB_ETH_RNDIS)
++      gether_set_gadget(ecm_opts->net, cdev->gadget);
++      status = gether_register_netdev(ecm_opts->net);
++      if (status)
++              goto fail0;
++      ecm_opts->bound = true;
++
++      gether_get_host_addr_u8(ecm_opts->net, host_mac);
++#endif
+       /* set up serial link layer */
+       fi_acm = usb_get_function_instance("acm");
+@@ -345,7 +388,11 @@ fail2:
+ fail1:
+       usb_put_function_instance(fi_acm);
+ fail0:
++#ifdef CONFIG_USB_G_MULTI_CDC
++      usb_put_function_instance(fi_ecm);
++#else
+       gether_cleanup(the_dev);
++#endif
+       return status;
+ }
+@@ -358,7 +405,12 @@ static int __exit multi_unbind(struct usb_composite_dev *cdev)
+       usb_put_function(f_acm_rndis);
+ #endif
+       usb_put_function_instance(fi_acm);
++#ifdef CONFIG_USB_G_MULTI_CDC
++      usb_put_function(f_ecm);
++      usb_put_function_instance(fi_ecm);
++#else
+       gether_cleanup(the_dev);
++#endif
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0677-usb-gadget-multi-convert-to-new-interface-of-f_rndis.patch b/patches.tizen/0677-usb-gadget-multi-convert-to-new-interface-of-f_rndis.patch
new file mode 100644 (file)
index 0000000..ce08802
--- /dev/null
@@ -0,0 +1,202 @@
+From 341030a348bb6faa52e0b69a3ba17f827aae2af2 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Fri, 26 Jul 2013 11:15:55 +0200
+Subject: [PATCH 0677/1302] usb/gadget: multi: convert to new interface of
+ f_rndis
+
+Convert the legacy multi gadget to the new interface of f_rndis,
+so that later the compatibility layer in f_rndis can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig |  3 +-
+ drivers/usb/gadget/multi.c | 73 +++++++++++++++++++++++++++++++---------------
+ 2 files changed, 52 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index ae584e9..ead7888 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -1048,7 +1048,6 @@ config USB_G_MULTI
+       select USB_LIBCOMPOSITE
+       select USB_U_SERIAL
+       select USB_U_ETHER
+-      select USB_U_RNDIS
+       select USB_F_ACM
+       select USB_U_MS
+       help
+@@ -1069,6 +1068,8 @@ config USB_G_MULTI
+ config USB_G_MULTI_RNDIS
+       bool "RNDIS + CDC Serial + Storage configuration"
+       depends on USB_G_MULTI
++      select USB_U_RNDIS
++      select USB_F_RNDIS
+       default y
+       help
+         This option enables a configuration with RNDIS, CDC Serial and
+diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
+index 0d1d132..be62bea 100644
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -47,8 +47,7 @@ MODULE_LICENSE("GPL");
+ #include "u_ecm.h"
+ #ifdef USB_ETH_RNDIS
+-#  define USB_FRNDIS_INCLUDED
+-#  include "f_rndis.c"
++#  include "u_rndis.h"
+ #  include "rndis.h"
+ #endif
+ #include "u_ether.h"
+@@ -152,14 +151,13 @@ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
+ static struct fsg_common fsg_common;
+ static struct usb_function_instance *fi_acm;
+-static struct eth_dev *the_dev;
+ /********** RNDIS **********/
+ #ifdef USB_ETH_RNDIS
+-static u8 host_mac[ETH_ALEN];
+-
++static struct usb_function_instance *fi_rndis;
+ static struct usb_function *f_acm_rndis;
++static struct usb_function *f_rndis;
+ static __init int rndis_do_config(struct usb_configuration *c)
+ {
+@@ -170,13 +168,19 @@ static __init int rndis_do_config(struct usb_configuration *c)
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+-      ret = rndis_bind_config(c, host_mac, the_dev);
++      f_rndis = usb_get_function(fi_rndis);
++      if (IS_ERR(f_rndis))
++              return PTR_ERR(f_rndis);
++
++      ret = usb_add_function(c, f_rndis);
+       if (ret < 0)
+-              return ret;
++              goto err_func_rndis;
+       f_acm_rndis = usb_get_function(fi_acm);
+-      if (IS_ERR(f_acm_rndis))
+-              return PTR_ERR(f_acm_rndis);
++      if (IS_ERR(f_acm_rndis)) {
++              ret = PTR_ERR(f_acm_rndis);
++              goto err_func_acm;
++      }
+       ret = usb_add_function(c, f_acm_rndis);
+       if (ret)
+@@ -191,6 +195,10 @@ err_fsg:
+       usb_remove_function(c, f_acm_rndis);
+ err_conf:
+       usb_put_function(f_acm_rndis);
++err_func_acm:
++      usb_remove_function(c, f_rndis);
++err_func_rndis:
++      usb_put_function(f_rndis);
+       return ret;
+ }
+@@ -300,11 +308,14 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
+ #ifdef CONFIG_USB_G_MULTI_CDC
+       struct f_ecm_opts *ecm_opts;
+ #endif
++#ifdef USB_ETH_RNDIS
++      struct f_rndis_opts *rndis_opts;
++#endif
+       int status;
+       if (!can_support_ecm(cdev->gadget)) {
+               dev_err(&gadget->dev, "controller '%s' not usable\n",
+-                      gadget->name);
++                      gadget->name);
+               return -EINVAL;
+       }
+@@ -320,26 +331,38 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
+               pr_info("using host ethernet address: %s", host_addr);
+       if (!gether_set_dev_addr(ecm_opts->net, dev_addr))
+               pr_info("using self ethernet address: %s", dev_addr);
++#endif
+-      the_dev = netdev_priv(ecm_opts->net);
++#ifdef USB_ETH_RNDIS
++      fi_rndis = usb_get_function_instance("rndis");
++      if (IS_ERR(fi_rndis)) {
++              status = PTR_ERR(fi_rndis);
++              goto fail;
++      }
+-#elif defined USB_ETH_RNDIS
++      rndis_opts = container_of(fi_rndis, struct f_rndis_opts, func_inst);
+-      /* set up network link layer */
+-      the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, host_mac,
+-                             qmult);
+-      if (IS_ERR(the_dev))
+-              return PTR_ERR(the_dev);
++      gether_set_qmult(rndis_opts->net, qmult);
++      if (!gether_set_host_addr(rndis_opts->net, host_addr))
++              pr_info("using host ethernet address: %s", host_addr);
++      if (!gether_set_dev_addr(rndis_opts->net, dev_addr))
++              pr_info("using self ethernet address: %s", dev_addr);
+ #endif
+ #if (defined CONFIG_USB_G_MULTI_CDC && defined USB_ETH_RNDIS)
++      /*
++       * If both ecm and rndis are selected then:
++       *      1) rndis borrows the net interface from ecm
++       *      2) since the interface is shared it must not be bound
++       *      twice - in ecm's _and_ rndis' binds, so do it here.
++       */
+       gether_set_gadget(ecm_opts->net, cdev->gadget);
+       status = gether_register_netdev(ecm_opts->net);
+       if (status)
+               goto fail0;
+-      ecm_opts->bound = true;
+-      gether_get_host_addr_u8(ecm_opts->net, host_mac);
++      rndis_borrow_net(fi_rndis, ecm_opts->net);
++      ecm_opts->bound = true;
+ #endif
+       /* set up serial link layer */
+@@ -388,10 +411,12 @@ fail2:
+ fail1:
+       usb_put_function_instance(fi_acm);
+ fail0:
++#ifdef USB_ETH_RNDIS
++      usb_put_function_instance(fi_rndis);
++fail:
++#endif
+ #ifdef CONFIG_USB_G_MULTI_CDC
+       usb_put_function_instance(fi_ecm);
+-#else
+-      gether_cleanup(the_dev);
+ #endif
+       return status;
+ }
+@@ -405,11 +430,13 @@ static int __exit multi_unbind(struct usb_composite_dev *cdev)
+       usb_put_function(f_acm_rndis);
+ #endif
+       usb_put_function_instance(fi_acm);
++#ifdef USB_ETH_RNDIS
++      usb_put_function(f_rndis);
++      usb_put_function_instance(fi_rndis);
++#endif
+ #ifdef CONFIG_USB_G_MULTI_CDC
+       usb_put_function(f_ecm);
+       usb_put_function_instance(fi_ecm);
+-#else
+-      gether_cleanup(the_dev);
+ #endif
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0678-usb-gadget-multi-convert-to-new-interface-of-f_mass_.patch b/patches.tizen/0678-usb-gadget-multi-convert-to-new-interface-of-f_mass_.patch
new file mode 100644 (file)
index 0000000..6dd61d4
--- /dev/null
@@ -0,0 +1,246 @@
+From dd7e1f875183653d9a6c94148e19a06bfc81f4ad Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 30 Jul 2013 11:23:28 +0200
+Subject: [PATCH 0678/1302] usb/gadget: multi: convert to new interface of
+ f_mass_storage
+
+Convert the legacy multi gadget to the new interface of f_mass_storage,
+so that later the compatibility layer in f_mass_storage can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig |   1 +
+ drivers/usb/gadget/multi.c | 112 +++++++++++++++++++++++++++++++++------------
+ 2 files changed, 83 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index ead7888..49e7004 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -1050,6 +1050,7 @@ config USB_G_MULTI
+       select USB_U_ETHER
+       select USB_F_ACM
+       select USB_U_MS
++      select USB_F_MASS_STORAGE
+       help
+         The Multifunction Composite Gadget provides Ethernet (RNDIS
+         and/or CDC Ethernet), mass storage and ACM serial link
+diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
+index be62bea..7f84efa 100644
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -33,17 +33,7 @@ MODULE_AUTHOR("Michal Nazarewicz");
+ MODULE_LICENSE("GPL");
+-/***************************** All the files... *****************************/
+-
+-/*
+- * kbuild is not very cooperative with respect to linking separately
+- * compiled library objects into one module.  So for now we won't use
+- * separate compilation ... ensuring init/exit sections work to shrink
+- * the runtime footprint, and giving us at least some parts of what
+- * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+- */
+-#define USB_FMS_INCLUDED
+-#include "f_mass_storage.c"
++#include "f_mass_storage.h"
+ #include "u_ecm.h"
+ #ifdef USB_ETH_RNDIS
+@@ -148,9 +138,8 @@ static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
+ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
+-static struct fsg_common fsg_common;
+-
+ static struct usb_function_instance *fi_acm;
++static struct usb_function_instance *fi_msg;
+ /********** RNDIS **********/
+@@ -158,9 +147,11 @@ static struct usb_function_instance *fi_acm;
+ static struct usb_function_instance *fi_rndis;
+ static struct usb_function *f_acm_rndis;
+ static struct usb_function *f_rndis;
++static struct usb_function *f_msg_rndis;
+ static __init int rndis_do_config(struct usb_configuration *c)
+ {
++      struct fsg_opts *fsg_opts;
+       int ret;
+       if (gadget_is_otg(c->cdev->gadget)) {
+@@ -186,11 +177,24 @@ static __init int rndis_do_config(struct usb_configuration *c)
+       if (ret)
+               goto err_conf;
+-      ret = fsg_bind_config(c->cdev, c, &fsg_common);
+-      if (ret < 0)
++      f_msg_rndis = usb_get_function(fi_msg);
++      if (IS_ERR(f_msg_rndis)) {
++              ret = PTR_ERR(f_msg_rndis);
+               goto err_fsg;
++      }
++
++      fsg_opts = container_of(fi_msg, struct fsg_opts, func_inst);
++      ret = fsg_common_run_thread(fsg_opts->common);
++      if (ret)
++              goto err_run;
++
++      ret = usb_add_function(c, f_msg_rndis);
++      if (ret)
++              goto err_run;
+       return 0;
++err_run:
++      usb_put_function(f_msg_rndis);
+ err_fsg:
+       usb_remove_function(c, f_acm_rndis);
+ err_conf:
+@@ -231,9 +235,11 @@ static int rndis_config_register(struct usb_composite_dev *cdev)
+ static struct usb_function_instance *fi_ecm;
+ static struct usb_function *f_acm_multi;
+ static struct usb_function *f_ecm;
++static struct usb_function *f_msg_multi;
+ static __init int cdc_do_config(struct usb_configuration *c)
+ {
++      struct fsg_opts *fsg_opts;
+       int ret;
+       if (gadget_is_otg(c->cdev->gadget)) {
+@@ -260,11 +266,24 @@ static __init int cdc_do_config(struct usb_configuration *c)
+       if (ret)
+               goto err_conf;
+-      ret = fsg_bind_config(c->cdev, c, &fsg_common);
+-      if (ret < 0)
++      f_msg_multi = usb_get_function(fi_msg);
++      if (IS_ERR(f_msg_multi)) {
++              ret = PTR_ERR(f_msg_multi);
+               goto err_fsg;
++      }
++
++      fsg_opts = container_of(fi_msg, struct fsg_opts, func_inst);
++      ret = fsg_common_run_thread(fsg_opts->common);
++      if (ret)
++              goto err_run;
++
++      ret = usb_add_function(c, f_msg_multi);
++      if (ret)
++              goto err_run;
+       return 0;
++err_run:
++      usb_put_function(f_msg_multi);
+ err_fsg:
+       usb_remove_function(c, f_acm_multi);
+ err_conf:
+@@ -311,6 +330,8 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
+ #ifdef USB_ETH_RNDIS
+       struct f_rndis_opts *rndis_opts;
+ #endif
++      struct fsg_opts *fsg_opts;
++      struct fsg_config config;
+       int status;
+       if (!can_support_ecm(cdev->gadget)) {
+@@ -373,41 +394,65 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
+       }
+       /* set up mass storage function */
+-      {
+-              void *retp;
+-              retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data,
+-                                            fsg_num_buffers);
+-              if (IS_ERR(retp)) {
+-                      status = PTR_ERR(retp);
+-                      goto fail1;
+-              }
++      fi_msg = usb_get_function_instance("mass_storage");
++      if (IS_ERR(fi_msg)) {
++              status = PTR_ERR(fi_msg);
++              goto fail1;
+       }
++      fsg_config_from_params(&config, &fsg_mod_data, fsg_num_buffers);
++      fsg_opts = container_of(fi_msg, struct fsg_opts, func_inst);
++
++      fsg_opts->no_configfs = true;
++      status = fsg_common_set_num_buffers(fsg_opts->common, fsg_num_buffers);
++      if (status)
++              goto fail2;
++
++      status = fsg_common_set_nluns(fsg_opts->common, config.nluns);
++      if (status)
++              goto fail_set_nluns;
++
++      status = fsg_common_set_cdev(fsg_opts->common, cdev, config.can_stall);
++      if (status)
++              goto fail_set_cdev;
++
++      fsg_common_set_sysfs(fsg_opts->common, true);
++      status = fsg_common_create_luns(fsg_opts->common, &config);
++      if (status)
++              goto fail_set_cdev;
++
++      fsg_common_set_inquiry_string(fsg_opts->common, config.vendor_name,
++                                    config.product_name);
+       /* allocate string IDs */
+       status = usb_string_ids_tab(cdev, strings_dev);
+       if (unlikely(status < 0))
+-              goto fail2;
++              goto fail_string_ids;
+       device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id;
+       /* register configurations */
+       status = rndis_config_register(cdev);
+       if (unlikely(status < 0))
+-              goto fail2;
++              goto fail_string_ids;
+       status = cdc_config_register(cdev);
+       if (unlikely(status < 0))
+-              goto fail2;
++              goto fail_string_ids;
+       usb_composite_overwrite_options(cdev, &coverwrite);
+       /* we're done */
+       dev_info(&gadget->dev, DRIVER_DESC "\n");
+-      fsg_common_put(&fsg_common);
+       return 0;
+       /* error recovery */
++fail_string_ids:
++      fsg_common_remove_luns(fsg_opts->common);
++fail_set_cdev:
++      fsg_common_free_luns(fsg_opts->common);
++fail_set_nluns:
++      fsg_common_free_buffers(fsg_opts->common);
+ fail2:
+-      fsg_common_put(&fsg_common);
++      usb_put_function_instance(fi_msg);
+ fail1:
+       usb_put_function_instance(fi_acm);
+ fail0:
+@@ -424,6 +469,13 @@ fail:
+ static int __exit multi_unbind(struct usb_composite_dev *cdev)
+ {
+ #ifdef CONFIG_USB_G_MULTI_CDC
++      usb_put_function(f_msg_multi);
++#endif
++#ifdef USB_ETH_RNDIS
++      usb_put_function(f_msg_rndis);
++#endif
++      usb_put_function_instance(fi_msg);
++#ifdef CONFIG_USB_G_MULTI_CDC
+       usb_put_function(f_acm_multi);
+ #endif
+ #ifdef USB_ETH_RNDIS
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0679-usb-gadget-f_mass_storage-remove-compatibility-layer.patch b/patches.tizen/0679-usb-gadget-f_mass_storage-remove-compatibility-layer.patch
new file mode 100644 (file)
index 0000000..3e55a3a
--- /dev/null
@@ -0,0 +1,371 @@
+From 59aad79c1789c338321789307105f676b8c8b427 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 11 Jul 2013 13:20:53 +0200
+Subject: [PATCH 0679/1302] usb/gadget: f_mass_storage: remove compatibility
+ layer
+
+There are no more old interface users left. Remove it.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 154 +-----------------------------------
+ drivers/usb/gadget/f_mass_storage.h |  21 -----
+ 2 files changed, 1 insertion(+), 174 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index f1aa6c0..3e9a03b 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -2651,17 +2651,13 @@ void fsg_common_get(struct fsg_common *common)
+ {
+       kref_get(&common->ref);
+ }
+-#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_get);
+-#endif
+ void fsg_common_put(struct fsg_common *common)
+ {
+       kref_put(&common->ref, fsg_common_release);
+ }
+-#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_put);
+-#endif
+ /* check if fsg_num_buffers is within a valid range */
+ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
+@@ -2699,9 +2695,7 @@ void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs)
+ {
+       common->sysfs = sysfs;
+ }
+-#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_set_sysfs);
+-#endif
+ static void _fsg_common_free_buffers(struct fsg_buffhd *buffhds, unsigned n)
+ {
+@@ -2753,18 +2747,14 @@ error_release:
+       return -ENOMEM;
+ }
+-#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_set_num_buffers);
+-#endif
+ void fsg_common_free_buffers(struct fsg_common *common)
+ {
+       _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
+       common->buffhds = NULL;
+ }
+-#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_free_buffers);
+-#endif
+ int fsg_common_set_nluns(struct fsg_common *common, int nluns)
+ {
+@@ -2790,9 +2780,7 @@ int fsg_common_set_nluns(struct fsg_common *common, int nluns)
+       return 0;
+ }
+-#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_set_nluns);
+-#endif
+ void fsg_common_free_luns(struct fsg_common *common)
+ {
+@@ -2800,26 +2788,20 @@ void fsg_common_free_luns(struct fsg_common *common)
+       kfree(common->luns);
+       common->luns = NULL;
+ }
+-#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_free_luns);
+-#endif
+ void fsg_common_set_ops(struct fsg_common *common,
+                       const struct fsg_operations *ops)
+ {
+       common->ops = ops;
+ }
+-#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_set_ops);
+-#endif
+ void fsg_common_set_private_data(struct fsg_common *common, void *priv)
+ {
+       common->private_data = priv;
+ }
+-#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_set_private_data);
+-#endif
+ int fsg_common_set_cdev(struct fsg_common *common,
+                        struct usb_composite_dev *cdev, bool can_stall)
+@@ -2849,9 +2831,7 @@ int fsg_common_set_cdev(struct fsg_common *common,
+       return 0;
+ }
+-#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_set_cdev);
+-#endif
+ static inline int fsg_common_add_sysfs(struct fsg_common *common,
+                                      struct fsg_lun *lun)
+@@ -2916,9 +2896,7 @@ void fsg_common_remove_lun(struct fsg_lun *lun, bool sysfs)
+       kfree(lun->name);
+       kfree(lun);
+ }
+-#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_remove_lun);
+-#endif
+ void _fsg_common_remove_luns(struct fsg_common *common, int n)
+ {
+@@ -2935,9 +2913,7 @@ void fsg_common_remove_luns(struct fsg_common *common)
+ {
+       _fsg_common_remove_luns(common, common->nluns);
+ }
+-#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_remove_luns);
+-#endif
+ #define MAX_LUN_NAME_LEN 80
+@@ -3034,9 +3010,7 @@ error_name:
+       kfree(lun);
+       return rc;
+ }
+-#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_create_lun);
+-#endif
+ int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg)
+ {
+@@ -3058,9 +3032,7 @@ fail:
+       _fsg_common_remove_luns(common, i);
+       return rc;
+ }
+-#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_create_luns);
+-#endif
+ void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
+                                  const char *pn)
+@@ -3077,9 +3049,7 @@ void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
+                    : "File-Stor Gadget"),
+                i);
+ }
+-#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_set_inquiry_string);
+-#endif
+ int fsg_common_run_thread(struct fsg_common *common)
+ {
+@@ -3098,66 +3068,7 @@ int fsg_common_run_thread(struct fsg_common *common)
+       return 0;
+ }
+-#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_run_thread);
+-#endif
+-
+-struct fsg_common *fsg_common_init(struct fsg_common *common,
+-                                 struct usb_composite_dev *cdev,
+-                                 struct fsg_config *cfg)
+-{
+-      int rc;
+-
+-      common = fsg_common_setup(common, !!common);
+-      if (IS_ERR(common))
+-              return common;
+-      common->sysfs = true;
+-      common->state = FSG_STATE_IDLE;
+-
+-      rc = fsg_common_set_num_buffers(common, cfg->fsg_num_buffers);
+-      if (rc) {
+-              if (common->free_storage_on_release)
+-                      kfree(common);
+-              return ERR_PTR(rc);
+-      }
+-
+-      fsg_common_set_ops(common, cfg->ops);
+-      fsg_common_set_private_data(common, cfg->private_data);
+-
+-      rc = fsg_common_set_cdev(common, cdev, cfg->can_stall);
+-      if (rc)
+-              goto error_release;
+-
+-      rc = fsg_common_set_nluns(common, cfg->nluns);
+-      if (rc)
+-              goto error_release;
+-
+-      rc = fsg_common_create_luns(common, cfg);
+-      if (rc)
+-              goto error_release;
+-
+-
+-      fsg_common_set_inquiry_string(common, cfg->vendor_name,
+-                                    cfg->product_name);
+-
+-      /* Information */
+-      INFO(common, FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
+-
+-      rc = fsg_common_run_thread(common);
+-      if (rc)
+-              goto error_release;
+-
+-      return common;
+-
+-error_release:
+-      common->state = FSG_STATE_TERMINATED;   /* The thread is dead */
+-      /* Call fsg_common_release() directly, ref might be not initialised. */
+-      fsg_common_release(&common->ref);
+-      return ERR_PTR(rc);
+-}
+-#ifndef USB_FMS_INCLUDED
+-EXPORT_SYMBOL(fsg_common_init);
+-#endif
+ static void fsg_common_release(struct kref *ref)
+ {
+@@ -3208,9 +3119,8 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
+       struct usb_ep           *ep;
+       unsigned                max_burst;
+       int                     ret;
+-
+-#ifndef USB_FMS_INCLUDED
+       struct fsg_opts         *opts;
++
+       opts = container_of(f->fi, struct fsg_opts, func_inst);
+       if (!opts->no_configfs) {
+               ret = fsg_common_set_cdev(fsg->common, c->cdev,
+@@ -3222,7 +3132,6 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
+               if (ret)
+                       return ret;
+       }
+-#endif
+       fsg->gadget = gadget;
+@@ -3277,63 +3186,6 @@ autoconf_fail:
+ /****************************** ALLOCATE FUNCTION *************************/
+-#ifdef USB_FMS_INCLUDED
+-
+-static void old_fsg_unbind(struct usb_configuration *c, struct usb_function *f)
+-{
+-      struct fsg_dev          *fsg = fsg_from_func(f);
+-      struct fsg_common       *common = fsg->common;
+-
+-      DBG(fsg, "unbind\n");
+-      if (fsg->common->fsg == fsg) {
+-              fsg->common->new_fsg = NULL;
+-              raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
+-              /* FIXME: make interruptible or killable somehow? */
+-              wait_event(common->fsg_wait, common->fsg != fsg);
+-      }
+-
+-      fsg_common_put(common);
+-      usb_free_all_descriptors(&fsg->function);
+-      kfree(fsg);
+-}
+-
+-static int fsg_bind_config(struct usb_composite_dev *cdev,
+-                         struct usb_configuration *c,
+-                         struct fsg_common *common)
+-{
+-      struct fsg_dev *fsg;
+-      int rc;
+-
+-      fsg = kzalloc(sizeof *fsg, GFP_KERNEL);
+-      if (unlikely(!fsg))
+-              return -ENOMEM;
+-
+-      fsg->function.name        = FSG_DRIVER_DESC;
+-      fsg->function.bind        = fsg_bind;
+-      fsg->function.unbind      = old_fsg_unbind;
+-      fsg->function.setup       = fsg_setup;
+-      fsg->function.set_alt     = fsg_set_alt;
+-      fsg->function.disable     = fsg_disable;
+-
+-      fsg->common               = common;
+-      /*
+-       * Our caller holds a reference to common structure so we
+-       * don't have to be worry about it being freed until we return
+-       * from this function.  So instead of incrementing counter now
+-       * and decrement in error recovery we increment it only when
+-       * call to usb_add_function() was successful.
+-       */
+-
+-      rc = usb_add_function(c, &fsg->function);
+-      if (unlikely(rc))
+-              kfree(fsg);
+-      else
+-              fsg_common_get(fsg->common);
+-      return rc;
+-}
+-
+-#else
+-
+ static inline struct fsg_lun_opts *to_fsg_lun_opts(struct config_item *item)
+ {
+       return container_of(to_config_group(item), struct fsg_lun_opts, group);
+@@ -3803,8 +3655,6 @@ DECLARE_USB_FUNCTION_INIT(mass_storage, fsg_alloc_inst, fsg_alloc);
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Michal Nazarewicz");
+-#endif
+-
+ /************************* Module parameters *************************/
+@@ -3840,7 +3690,5 @@ void fsg_config_from_params(struct fsg_config *cfg,
+       cfg->can_stall = params->stall;
+       cfg->fsg_num_buffers = fsg_num_buffers;
+ }
+-#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_config_from_params);
+-#endif
+diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h
+index 62b4b8f..a16c2a9 100644
+--- a/drivers/usb/gadget/f_mass_storage.h
++++ b/drivers/usb/gadget/f_mass_storage.h
+@@ -122,10 +122,6 @@ void fsg_common_get(struct fsg_common *common);
+ void fsg_common_put(struct fsg_common *common);
+-struct fsg_common *fsg_common_init(struct fsg_common *common,
+-                                 struct usb_composite_dev *cdev,
+-                                 struct fsg_config *cfg);
+-
+ void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs);
+ int fsg_common_set_num_buffers(struct fsg_common *common, unsigned int n);
+@@ -163,21 +159,4 @@ void fsg_config_from_params(struct fsg_config *cfg,
+                           const struct fsg_module_parameters *params,
+                           unsigned int fsg_num_buffers);
+-static inline struct fsg_common *
+-fsg_common_from_params(struct fsg_common *common,
+-                     struct usb_composite_dev *cdev,
+-                     const struct fsg_module_parameters *params,
+-                     unsigned int fsg_num_buffers)
+-      __attribute__((unused));
+-static inline struct fsg_common *
+-fsg_common_from_params(struct fsg_common *common,
+-                     struct usb_composite_dev *cdev,
+-                     const struct fsg_module_parameters *params,
+-                     unsigned int fsg_num_buffers)
+-{
+-      struct fsg_config cfg;
+-      fsg_config_from_params(&cfg, params, fsg_num_buffers);
+-      return fsg_common_init(common, cdev, &cfg);
+-}
+-
+ #endif /* USB_F_MASS_STORAGE_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0680-usb-gadget-mass_storage-merge-usb_f_mass_storage-mod.patch b/patches.tizen/0680-usb-gadget-mass_storage-merge-usb_f_mass_storage-mod.patch
new file mode 100644 (file)
index 0000000..1eb82e3
--- /dev/null
@@ -0,0 +1,80 @@
+From 2e3f33eddfca46f0d4909d496f6309454b8da298 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 11 Jul 2013 13:24:00 +0200
+Subject: [PATCH 0680/1302] usb/gadget: mass_storage: merge usb_f_mass_storage
+ module with u_ms module
+
+u_ms.ko is needed only together with usb_f_mass_storage.ko. Merge them.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig  | 7 -------
+ drivers/usb/gadget/Makefile | 4 +---
+ 2 files changed, 1 insertion(+), 10 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 49e7004..84ac134 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -537,9 +537,6 @@ config USB_F_SUBSET
+ config USB_F_RNDIS
+       tristate
+-config USB_U_MS
+-      tristate
+-
+ config USB_F_MASS_STORAGE
+       tristate
+@@ -683,7 +680,6 @@ config USB_CONFIGFS_PHONET
+ config USB_CONFIGFS_MASS_STORAGE
+       boolean "Mass storage"
+       depends on USB_CONFIGFS
+-      select USB_U_MS
+       select USB_F_MASS_STORAGE
+       help
+         The Mass Storage Gadget acts as a USB Mass Storage disk drive.
+@@ -907,7 +903,6 @@ config USB_MASS_STORAGE
+       tristate "Mass Storage Gadget"
+       depends on BLOCK
+       select USB_LIBCOMPOSITE
+-      select USB_U_MS
+       select USB_F_MASS_STORAGE
+       help
+         The Mass Storage Gadget acts as a USB Mass Storage disk drive.
+@@ -1032,7 +1027,6 @@ config USB_G_ACM_MS
+       select USB_LIBCOMPOSITE
+       select USB_U_SERIAL
+       select USB_F_ACM
+-      select USB_U_MS
+       select USB_F_MASS_STORAGE
+       help
+         This driver provides two functions in one configuration:
+@@ -1049,7 +1043,6 @@ config USB_G_MULTI
+       select USB_U_SERIAL
+       select USB_U_ETHER
+       select USB_F_ACM
+-      select USB_U_MS
+       select USB_F_MASS_STORAGE
+       help
+         The Multifunction Composite Gadget provides Ethernet (RNDIS
+diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
+index d232706..f106645 100644
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -60,9 +60,7 @@ usb_f_ecm_subset-y           := f_subset.o
+ obj-$(CONFIG_USB_F_SUBSET)    += usb_f_ecm_subset.o
+ usb_f_rndis-y                 := f_rndis.o
+ obj-$(CONFIG_USB_F_RNDIS)     += usb_f_rndis.o
+-u_ms-y                                := storage_common.o
+-obj-$(CONFIG_USB_U_MS)                += u_ms.o
+-usb_f_mass_storage-y          := f_mass_storage.o
++usb_f_mass_storage-y          := f_mass_storage.o storage_common.o
+ obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o
+ #
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0681-clk-Provide-not-locked-variant-of-of_clk_get_from_pr.patch b/patches.tizen/0681-clk-Provide-not-locked-variant-of-of_clk_get_from_pr.patch
new file mode 100644 (file)
index 0000000..37d11a9
--- /dev/null
@@ -0,0 +1,148 @@
+From 1bbf7bbc84a641a805884d1521de2d7f66e057f2 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 9 Aug 2013 20:38:10 +0200
+Subject: [PATCH 0681/1302] clk: Provide not locked variant of
+ of_clk_get_from_provider()
+
+Add helper functions for the of_clk_providers list locking and
+an unlocked variant of of_clk_get_from_provider().
+These functions are intended to be used in the clkdev to avoid
+race condition in the device tree based clock look up in clk_get().
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
+---
+Changes since v3:
+ - none.
+
+Changes since v2:
+ - fixed typo in clk.h.
+
+Changes since v1:
+ - moved the function declaractions to a local header.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/clk.c | 38 ++++++++++++++++++++++++++++++--------
+ drivers/clk/clk.h | 16 ++++++++++++++++
+ 2 files changed, 46 insertions(+), 8 deletions(-)
+ create mode 100644 drivers/clk/clk.h
+
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
+index 5b39cda..8f56e3d 100644
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -21,6 +21,8 @@
+ #include <linux/init.h>
+ #include <linux/sched.h>
++#include "clk.h"
++
+ static DEFINE_SPINLOCK(enable_lock);
+ static DEFINE_MUTEX(prepare_lock);
+@@ -1995,7 +1997,18 @@ static const struct of_device_id __clk_of_table_sentinel
+       __used __section(__clk_of_table_end);
+ static LIST_HEAD(of_clk_providers);
+-static DEFINE_MUTEX(of_clk_lock);
++static DEFINE_MUTEX(of_clk_mutex);
++
++/* of_clk_provider list locking helpers */
++void of_clk_lock(void)
++{
++      mutex_lock(&of_clk_mutex);
++}
++
++void of_clk_unlock(void)
++{
++      mutex_unlock(&of_clk_mutex);
++}
+ struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
+                                    void *data)
+@@ -2039,9 +2052,9 @@ int of_clk_add_provider(struct device_node *np,
+       cp->data = data;
+       cp->get = clk_src_get;
+-      mutex_lock(&of_clk_lock);
++      mutex_lock(&of_clk_mutex);
+       list_add(&cp->link, &of_clk_providers);
+-      mutex_unlock(&of_clk_lock);
++      mutex_unlock(&of_clk_mutex);
+       pr_debug("Added clock from %s\n", np->full_name);
+       return 0;
+@@ -2056,7 +2069,7 @@ void of_clk_del_provider(struct device_node *np)
+ {
+       struct of_clk_provider *cp;
+-      mutex_lock(&of_clk_lock);
++      mutex_lock(&of_clk_mutex);
+       list_for_each_entry(cp, &of_clk_providers, link) {
+               if (cp->node == np) {
+                       list_del(&cp->link);
+@@ -2065,24 +2078,33 @@ void of_clk_del_provider(struct device_node *np)
+                       break;
+               }
+       }
+-      mutex_unlock(&of_clk_lock);
++      mutex_unlock(&of_clk_mutex);
+ }
+ EXPORT_SYMBOL_GPL(of_clk_del_provider);
+-struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
++struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec)
+ {
+       struct of_clk_provider *provider;
+       struct clk *clk = ERR_PTR(-ENOENT);
+       /* Check if we have such a provider in our array */
+-      mutex_lock(&of_clk_lock);
+       list_for_each_entry(provider, &of_clk_providers, link) {
+               if (provider->node == clkspec->np)
+                       clk = provider->get(clkspec, provider->data);
+               if (!IS_ERR(clk))
+                       break;
+       }
+-      mutex_unlock(&of_clk_lock);
++
++      return clk;
++}
++
++struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
++{
++      struct clk *clk;
++
++      mutex_lock(&of_clk_mutex);
++      clk = __of_clk_get_from_provider(clkspec);
++      mutex_unlock(&of_clk_mutex);
+       return clk;
+ }
+diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h
+new file mode 100644
+index 0000000..795cc9f
+--- /dev/null
++++ b/drivers/clk/clk.h
+@@ -0,0 +1,16 @@
++/*
++ * linux/drivers/clk/clk.h
++ *
++ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
++ * Sylwester Nawrocki <s.nawrocki@samsung.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.
++ */
++
++#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
++struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec);
++void of_clk_lock(void);
++void of_clk_unlock(void);
++#endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0682-clkdev-Fix-race-condition-in-clock-lookup-from-devic.patch b/patches.tizen/0682-clkdev-Fix-race-condition-in-clock-lookup-from-devic.patch
new file mode 100644 (file)
index 0000000..283f6d5
--- /dev/null
@@ -0,0 +1,74 @@
+From 645dfcdf3b7b88307f45ee8f31226caef1f2d3e5 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 9 Aug 2013 17:33:39 +0200
+Subject: [PATCH 0682/1302] clkdev: Fix race condition in clock lookup from
+ device tree
+
+There is currently a race condition in the device tree part of clk_get()
+function, since the pointer returned from of_clk_get_by_name() may become
+invalid before __clk_get() call. E.g. due to the clock provider driver
+remove() callback being called in between of_clk_get_by_name() and
+__clk_get().
+
+Fix this by doing both the look up and __clk_get() operations with the
+clock providers list mutex held. This ensures that the clock pointer
+returned from __of_clk_get_from_provider() call and passed to __clk_get()
+is valid, as long as the clock supplier module first removes its clock
+provider instance and then does clk_unregister() on the corresponding
+clocks.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
+---
+Changes since v2:
+ - none.
+
+Changes since v1:
+ - include "clk.h".
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/clkdev.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
+index 442a313..48f6721 100644
+--- a/drivers/clk/clkdev.c
++++ b/drivers/clk/clkdev.c
+@@ -21,6 +21,8 @@
+ #include <linux/clkdev.h>
+ #include <linux/of.h>
++#include "clk.h"
++
+ static LIST_HEAD(clocks);
+ static DEFINE_MUTEX(clocks_mutex);
+@@ -39,7 +41,13 @@ struct clk *of_clk_get(struct device_node *np, int index)
+       if (rc)
+               return ERR_PTR(rc);
+-      clk = of_clk_get_from_provider(&clkspec);
++      of_clk_lock();
++      clk = __of_clk_get_from_provider(&clkspec);
++
++      if (!IS_ERR(clk) && !__clk_get(clk))
++              clk = ERR_PTR(-ENOENT);
++
++      of_clk_unlock();
+       of_node_put(clkspec.np);
+       return clk;
+ }
+@@ -157,7 +165,7 @@ struct clk *clk_get(struct device *dev, const char *con_id)
+       if (dev) {
+               clk = of_clk_get_by_name(dev->of_node, con_id);
+-              if (!IS_ERR(clk) && __clk_get(clk))
++              if (!IS_ERR(clk))
+                       return clk;
+       }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0683-clk-Add-common-__clk_get-__clk_put-implementations.patch b/patches.tizen/0683-clk-Add-common-__clk_get-__clk_put-implementations.patch
new file mode 100644 (file)
index 0000000..f011e2f
--- /dev/null
@@ -0,0 +1,168 @@
+From 37daacc3ba1138c570ac7e914785d2714d8da20b Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 30 Aug 2013 13:02:40 +0200
+Subject: [PATCH 0683/1302] clk: Add common __clk_get(), __clk_put()
+ implementations
+
+This patch adds common __clk_get(), __clk_put() clkdev helpers which
+replace their platform specific counterparts when the common clock
+API is enabled.
+
+The owner module pointer field is added to struct clk so a reference
+to the clock supplier module can be taken by the clock consumers.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+---
+Changes since v5:
+ - none.
+
+Changes since v4:
+ - dropped unnecessary struct module forward declaration from
+   clk-provider.h
+
+Changes since v3:
+ - dropped exporting of __clk_get(), __clk_put().
+
+Changes since v2:
+ - fixed handling of NULL clock pointers in __clk_get(), __clk_put();
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/include/asm/clkdev.h      |  2 ++
+ arch/blackfin/include/asm/clkdev.h |  2 ++
+ arch/mips/include/asm/clkdev.h     |  2 ++
+ arch/sh/include/asm/clkdev.h       |  2 ++
+ drivers/clk/clk.c                  | 20 ++++++++++++++++++++
+ include/linux/clk-private.h        |  3 +++
+ include/linux/clkdev.h             |  5 +++++
+ 7 files changed, 36 insertions(+)
+
+diff --git a/arch/arm/include/asm/clkdev.h b/arch/arm/include/asm/clkdev.h
+index 80751c1..4e8a4b2 100644
+--- a/arch/arm/include/asm/clkdev.h
++++ b/arch/arm/include/asm/clkdev.h
+@@ -14,12 +14,14 @@
+ #include <linux/slab.h>
++#ifndef CONFIG_COMMON_CLK
+ #ifdef CONFIG_HAVE_MACH_CLKDEV
+ #include <mach/clkdev.h>
+ #else
+ #define __clk_get(clk)        ({ 1; })
+ #define __clk_put(clk)        do { } while (0)
+ #endif
++#endif
+ static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
+ {
+diff --git a/arch/blackfin/include/asm/clkdev.h b/arch/blackfin/include/asm/clkdev.h
+index 9053bed..7ac2436 100644
+--- a/arch/blackfin/include/asm/clkdev.h
++++ b/arch/blackfin/include/asm/clkdev.h
+@@ -8,7 +8,9 @@ static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
+       return kzalloc(size, GFP_KERNEL);
+ }
++#ifndef CONFIG_COMMON_CLK
+ #define __clk_put(clk)
+ #define __clk_get(clk) ({ 1; })
++#endif
+ #endif
+diff --git a/arch/mips/include/asm/clkdev.h b/arch/mips/include/asm/clkdev.h
+index 2624754..1b3ad7b 100644
+--- a/arch/mips/include/asm/clkdev.h
++++ b/arch/mips/include/asm/clkdev.h
+@@ -14,8 +14,10 @@
+ #include <linux/slab.h>
++#ifndef CONFIG_COMMON_CLK
+ #define __clk_get(clk)        ({ 1; })
+ #define __clk_put(clk)        do { } while (0)
++#endif
+ static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
+ {
+diff --git a/arch/sh/include/asm/clkdev.h b/arch/sh/include/asm/clkdev.h
+index 6ba9186..c419014 100644
+--- a/arch/sh/include/asm/clkdev.h
++++ b/arch/sh/include/asm/clkdev.h
+@@ -25,7 +25,9 @@ static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
+               return kzalloc(size, GFP_KERNEL);
+ }
++#ifndef CONFIG_COMMON_CLK
+ #define __clk_put(clk)
+ #define __clk_get(clk) ({ 1; })
++#endif
+ #endif /* __CLKDEV_H__ */
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
+index 8f56e3d..05a60cf 100644
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -1857,6 +1857,26 @@ void devm_clk_unregister(struct device *dev, struct clk *clk)
+ }
+ EXPORT_SYMBOL_GPL(devm_clk_unregister);
++/*
++ * clkdev helpers
++ */
++int __clk_get(struct clk *clk)
++{
++      if (clk && !try_module_get(clk->owner))
++              return 0;
++
++      return 1;
++}
++
++void __clk_put(struct clk *clk)
++{
++      if (WARN_ON_ONCE(IS_ERR(clk)))
++              return;
++
++      if (clk)
++              module_put(clk->owner);
++}
++
+ /***        clk rate change notifiers        ***/
+ /**
+diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h
+index dd7adff..b7c0b58 100644
+--- a/include/linux/clk-private.h
++++ b/include/linux/clk-private.h
+@@ -25,10 +25,13 @@
+ #ifdef CONFIG_COMMON_CLK
++struct module;
++
+ struct clk {
+       const char              *name;
+       const struct clk_ops    *ops;
+       struct clk_hw           *hw;
++      struct module           *owner;
+       struct clk              *parent;
+       const char              **parent_names;
+       struct clk              **parents;
+diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h
+index a6a6f60..94bad77 100644
+--- a/include/linux/clkdev.h
++++ b/include/linux/clkdev.h
+@@ -43,4 +43,9 @@ int clk_add_alias(const char *, const char *, char *, struct device *);
+ int clk_register_clkdev(struct clk *, const char *, const char *, ...);
+ int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t);
++#ifdef CONFIG_COMMON_CLK
++int __clk_get(struct clk *clk);
++void __clk_put(struct clk *clk);
++#endif
++
+ #endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0684-clk-Assign-module-owner-of-a-clock-being-registered.patch b/patches.tizen/0684-clk-Assign-module-owner-of-a-clock-being-registered.patch
new file mode 100644 (file)
index 0000000..58e3124
--- /dev/null
@@ -0,0 +1,48 @@
+From 380116d7cc99f1f1abe7b6186539a9aa3fc38589 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 23 Aug 2013 13:04:33 +0200
+Subject: [PATCH 0684/1302] clk: Assign module owner of a clock being
+ registered
+
+Use dev->driver->owner as the owner module of a clock, it ensures
+reference on the module is taken in the __clk_get(), __clk_put()
+helpers.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+---
+Changes since v5:
+ - none.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/clk.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
+index 05a60cf..0fadfe5 100644
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -1697,6 +1697,10 @@ struct clk *__clk_register(struct device *dev, struct clk_hw *hw)
+       clk->flags = hw->init->flags;
+       clk->parent_names = hw->init->parent_names;
+       clk->num_parents = hw->init->num_parents;
++      if (dev && dev->driver)
++              clk->owner = dev->driver->owner;
++      else
++              clk->owner = NULL;
+       ret = __clk_init(dev, clk);
+       if (ret)
+@@ -1717,6 +1721,8 @@ static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk)
+               goto fail_name;
+       }
+       clk->ops = hw->init->ops;
++      if (dev && dev->driver)
++              clk->owner = dev->driver->owner;
+       clk->hw = hw;
+       clk->flags = hw->init->flags;
+       clk->num_parents = hw->init->num_parents;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0685-clk-Implement-clk_unregister.patch b/patches.tizen/0685-clk-Implement-clk_unregister.patch
new file mode 100644 (file)
index 0000000..a234730
--- /dev/null
@@ -0,0 +1,266 @@
+From c2058cda67cc9f159ee899017856f5832909cdcc Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Tue, 6 Aug 2013 12:50:03 +0200
+Subject: [PATCH 0685/1302] clk: Implement clk_unregister
+
+clk_unregister() is currently not implemented and it is required when
+a clock provider module needs to be unloaded.
+
+Normally the clock supplier module is prevented to be unloaded by
+taking reference on the module in clk_get().
+
+For cases when the clock supplier module deinitializes despite the
+consumers of its clocks holding a reference on the module, e.g. when
+the driver is unbound through "unbind" sysfs attribute, there are
+empty clock ops added. These ops are assigned temporarily to struct
+clk and used until all consumers release the clock, to avoid invoking
+callbacks from the module which just got removed.
+
+Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+---
+Changes since v6:
+ - fixed handling of NULL clk in clk_unregister(), clk pointer checks
+   done before taking prepare_lock, pr_err() replaced with WARN_ON_ONCE.
+
+Changes since v5:
+- ensure clk->kref is not referenced when the passed clk is NULL.
+
+Changes since v4:
+ - none.
+
+Changes since v3:
+ - Use WARN_ON_ONCE() rather than WARN_ON() in clk_nodrv_disable_unprepare()
+   callback.
+
+Changes since v2:
+ - none.
+
+Changes since RFC v1:
+ - renamed clk_dummy_* to clk_nodrv_*.
+
+Changes since v3 of the original patch [1]:
+ - reparent all children to the orphan list instead of leaving
+   the clock unregistered when it has child clocks,
+ - removed unnecessary prerequisite checks in clk_debug_unregister(),
+ - struct clk is now being freed only when the last clock consumer
+   calls clk_put(),
+ - empty clock ops are used after clk_unregister() has been called
+   until all references to the clock are released and the clock
+   object is freed.
+
+[1] http://www.spinics.net/lists/arm-kernel/msg247548.html
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/clk.c           | 132 +++++++++++++++++++++++++++++++++++++++++---
+ include/linux/clk-private.h |   2 +
+ 2 files changed, 126 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
+index 0fadfe5..a9abf1b 100644
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -344,6 +344,21 @@ out:
+       return ret;
+ }
++ /**
++ * clk_debug_unregister - remove a clk node from the debugfs clk tree
++ * @clk: the clk being removed from the debugfs clk tree
++ *
++ * Dynamically removes a clk and all it's children clk nodes from the
++ * debugfs clk tree if clk->dentry points to debugfs created by
++ * clk_debug_register in __clk_init.
++ *
++ * Caller must hold prepare_lock.
++ */
++static void clk_debug_unregister(struct clk *clk)
++{
++      debugfs_remove_recursive(clk->dentry);
++}
++
+ /**
+  * clk_debug_reparent - reparent clk node in the debugfs clk tree
+  * @clk: the clk being reparented
+@@ -434,6 +449,9 @@ static inline int clk_debug_register(struct clk *clk) { return 0; }
+ static inline void clk_debug_reparent(struct clk *clk, struct clk *new_parent)
+ {
+ }
++static inline void clk_debug_unregister(struct clk *clk)
++{
++}
+ #endif
+ /* caller must hold prepare_lock */
+@@ -1662,6 +1680,7 @@ int __clk_init(struct device *dev, struct clk *clk)
+       clk_debug_register(clk);
++      kref_init(&clk->ref);
+ out:
+       clk_prepare_unlock();
+@@ -1797,13 +1816,104 @@ fail_out:
+ }
+ EXPORT_SYMBOL_GPL(clk_register);
++/*
++ * Free memory allocated for a clock.
++ * Caller must hold prepare_lock.
++ */
++static void __clk_release(struct kref *ref)
++{
++      struct clk *clk = container_of(ref, struct clk, ref);
++      int i = clk->num_parents;
++
++      kfree(clk->parents);
++      while (--i >= 0)
++              kfree(clk->parent_names[i]);
++
++      kfree(clk->parent_names);
++      kfree(clk->name);
++      kfree(clk);
++}
++
++/*
++ * Empty clk_ops for unregistered clocks. These are used temporarily
++ * after clk_unregister() was called on a clock and until last clock
++ * consumer calls clk_put() and the struct clk object is freed.
++ */
++static int clk_nodrv_prepare_enable(struct clk_hw *hw)
++{
++      return -ENXIO;
++}
++
++static void clk_nodrv_disable_unprepare(struct clk_hw *hw)
++{
++      WARN_ON(1);
++}
++
++static int clk_nodrv_set_rate(struct clk_hw *hw, unsigned long rate,
++                                      unsigned long parent_rate)
++{
++      return -ENXIO;
++}
++
++static int clk_nodrv_set_parent(struct clk_hw *hw, u8 index)
++{
++      return -ENXIO;
++}
++
++static const struct clk_ops clk_nodrv_ops = {
++      .enable         = clk_nodrv_prepare_enable,
++      .disable        = clk_nodrv_disable_unprepare,
++      .prepare        = clk_nodrv_prepare_enable,
++      .unprepare      = clk_nodrv_disable_unprepare,
++      .set_rate       = clk_nodrv_set_rate,
++      .set_parent     = clk_nodrv_set_parent,
++};
++
+ /**
+  * clk_unregister - unregister a currently registered clock
+  * @clk: clock to unregister
+- *
+- * Currently unimplemented.
+  */
+-void clk_unregister(struct clk *clk) {}
++void clk_unregister(struct clk *clk)
++{
++      unsigned long flags;
++
++      if (!clk || WARN_ON_ONCE(IS_ERR(clk)))
++              return;
++
++      clk_prepare_lock();
++
++      if (clk->ops == &clk_nodrv_ops) {
++              pr_err("%s: unregistered clock: %s\n", __func__, clk->name);
++              goto out;
++      }
++      /*
++       * Assign empty clock ops for consumers that might still hold
++       * a reference to this clock.
++       */
++      flags = clk_enable_lock();
++      clk->ops = &clk_nodrv_ops;
++      clk_enable_unlock(flags);
++
++      if (!hlist_empty(&clk->children)) {
++              struct clk *child;
++
++              /* Reparent all children to the orphan list. */
++              hlist_for_each_entry(child, &clk->children, child_node)
++                      clk_set_parent(child, NULL);
++      }
++
++      clk_debug_unregister(clk);
++
++      hlist_del_init(&clk->child_node);
++
++      if (clk->prepare_count)
++              pr_warn("%s: unregistering prepared clock: %s\n",
++                                      __func__, clk->name);
++
++      kref_put(&clk->ref, __clk_release);
++out:
++      clk_prepare_unlock();
++}
+ EXPORT_SYMBOL_GPL(clk_unregister);
+ static void devm_clk_release(struct device *dev, void *res)
+@@ -1868,19 +1978,25 @@ EXPORT_SYMBOL_GPL(devm_clk_unregister);
+  */
+ int __clk_get(struct clk *clk)
+ {
+-      if (clk && !try_module_get(clk->owner))
+-              return 0;
++      if (clk) {
++              if (!try_module_get(clk->owner))
++                      return 0;
++              kref_get(&clk->ref);
++      }
+       return 1;
+ }
+ void __clk_put(struct clk *clk)
+ {
+-      if (WARN_ON_ONCE(IS_ERR(clk)))
++      if (!clk || WARN_ON_ONCE(IS_ERR(clk)))
+               return;
+-      if (clk)
+-              module_put(clk->owner);
++      clk_prepare_lock();
++      kref_put(&clk->ref, __clk_release);
++      clk_prepare_unlock();
++
++      module_put(clk->owner);
+ }
+ /***        clk rate change notifiers        ***/
+diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h
+index b7c0b58..36c1fc8 100644
+--- a/include/linux/clk-private.h
++++ b/include/linux/clk-private.h
+@@ -12,6 +12,7 @@
+ #define __LINUX_CLK_PRIVATE_H
+ #include <linux/clk-provider.h>
++#include <linux/kref.h>
+ #include <linux/list.h>
+ /*
+@@ -47,6 +48,7 @@ struct clk {
+ #ifdef CONFIG_COMMON_CLK_DEBUG
+       struct dentry           *dentry;
+ #endif
++      struct kref             ref;
+ };
+ /*
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0686-media-V4L2-add-temporary-clock-helpers.patch b/patches.tizen/0686-media-V4L2-add-temporary-clock-helpers.patch
new file mode 100644 (file)
index 0000000..80573a2
--- /dev/null
@@ -0,0 +1,351 @@
+From 3166b4d8b7d8b458d0c24daa0847eebb6566c295 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Tue, 4 Dec 2012 07:42:15 -0300
+Subject: [PATCH 0686/1302] [media] V4L2: add temporary clock helpers
+
+Typical video devices like camera sensors require an external clock source.
+Many such devices cannot even access their hardware registers without a
+running clock. These clock sources should be controlled by their consumers.
+This should be performed, using the generic clock framework. Unfortunately
+so far only very few systems have been ported to that framework. This patch
+adds a set of temporary helpers, mimicking the generic clock API, to V4L2.
+Platforms, adopting the clock API, should switch to using it. Eventually
+this temporary API should be removed.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
+Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/v4l2-core/Makefile   |   2 +-
+ drivers/media/v4l2-core/v4l2-clk.c | 242 +++++++++++++++++++++++++++++++++++++
+ include/media/v4l2-clk.h           |  54 +++++++++
+ 3 files changed, 297 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/media/v4l2-core/v4l2-clk.c
+ create mode 100644 include/media/v4l2-clk.h
+
+diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile
+index aa50c46..628c630 100644
+--- a/drivers/media/v4l2-core/Makefile
++++ b/drivers/media/v4l2-core/Makefile
+@@ -5,7 +5,7 @@
+ tuner-objs    :=      tuner-core.o
+ videodev-objs :=      v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \
+-                      v4l2-event.o v4l2-ctrls.o v4l2-subdev.o
++                      v4l2-event.o v4l2-ctrls.o v4l2-subdev.o v4l2-clk.o
+ ifeq ($(CONFIG_COMPAT),y)
+   videodev-objs += v4l2-compat-ioctl32.o
+ endif
+diff --git a/drivers/media/v4l2-core/v4l2-clk.c b/drivers/media/v4l2-core/v4l2-clk.c
+new file mode 100644
+index 0000000..b67de86
+--- /dev/null
++++ b/drivers/media/v4l2-core/v4l2-clk.c
+@@ -0,0 +1,242 @@
++/*
++ * V4L2 clock service
++ *
++ * Copyright (C) 2012-2013, 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/atomic.h>
++#include <linux/device.h>
++#include <linux/errno.h>
++#include <linux/list.h>
++#include <linux/module.h>
++#include <linux/mutex.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++
++#include <media/v4l2-clk.h>
++#include <media/v4l2-subdev.h>
++
++static DEFINE_MUTEX(clk_lock);
++static LIST_HEAD(clk_list);
++
++static struct v4l2_clk *v4l2_clk_find(const char *dev_id, const char *id)
++{
++      struct v4l2_clk *clk;
++
++      list_for_each_entry(clk, &clk_list, list) {
++              if (strcmp(dev_id, clk->dev_id))
++                      continue;
++
++              if (!id || !clk->id || !strcmp(clk->id, id))
++                      return clk;
++      }
++
++      return ERR_PTR(-ENODEV);
++}
++
++struct v4l2_clk *v4l2_clk_get(struct device *dev, const char *id)
++{
++      struct v4l2_clk *clk;
++
++      mutex_lock(&clk_lock);
++      clk = v4l2_clk_find(dev_name(dev), id);
++
++      if (!IS_ERR(clk))
++              atomic_inc(&clk->use_count);
++      mutex_unlock(&clk_lock);
++
++      return clk;
++}
++EXPORT_SYMBOL(v4l2_clk_get);
++
++void v4l2_clk_put(struct v4l2_clk *clk)
++{
++      struct v4l2_clk *tmp;
++
++      if (IS_ERR(clk))
++              return;
++
++      mutex_lock(&clk_lock);
++
++      list_for_each_entry(tmp, &clk_list, list)
++              if (tmp == clk)
++                      atomic_dec(&clk->use_count);
++
++      mutex_unlock(&clk_lock);
++}
++EXPORT_SYMBOL(v4l2_clk_put);
++
++static int v4l2_clk_lock_driver(struct v4l2_clk *clk)
++{
++      struct v4l2_clk *tmp;
++      int ret = -ENODEV;
++
++      mutex_lock(&clk_lock);
++
++      list_for_each_entry(tmp, &clk_list, list)
++              if (tmp == clk) {
++                      ret = !try_module_get(clk->ops->owner);
++                      if (ret)
++                              ret = -EFAULT;
++                      break;
++              }
++
++      mutex_unlock(&clk_lock);
++
++      return ret;
++}
++
++static void v4l2_clk_unlock_driver(struct v4l2_clk *clk)
++{
++      module_put(clk->ops->owner);
++}
++
++int v4l2_clk_enable(struct v4l2_clk *clk)
++{
++      int ret = v4l2_clk_lock_driver(clk);
++
++      if (ret < 0)
++              return ret;
++
++      mutex_lock(&clk->lock);
++
++      if (++clk->enable == 1 && clk->ops->enable) {
++              ret = clk->ops->enable(clk);
++              if (ret < 0)
++                      clk->enable--;
++      }
++
++      mutex_unlock(&clk->lock);
++
++      return ret;
++}
++EXPORT_SYMBOL(v4l2_clk_enable);
++
++/*
++ * You might Oops if you try to disabled a disabled clock, because then the
++ * driver isn't locked and could have been unloaded by now, so, don't do that
++ */
++void v4l2_clk_disable(struct v4l2_clk *clk)
++{
++      int enable;
++
++      mutex_lock(&clk->lock);
++
++      enable = --clk->enable;
++      if (WARN(enable < 0, "Unbalanced %s() on %s:%s!\n", __func__,
++               clk->dev_id, clk->id))
++              clk->enable++;
++      else if (!enable && clk->ops->disable)
++              clk->ops->disable(clk);
++
++      mutex_unlock(&clk->lock);
++
++      v4l2_clk_unlock_driver(clk);
++}
++EXPORT_SYMBOL(v4l2_clk_disable);
++
++unsigned long v4l2_clk_get_rate(struct v4l2_clk *clk)
++{
++      int ret = v4l2_clk_lock_driver(clk);
++
++      if (ret < 0)
++              return ret;
++
++      mutex_lock(&clk->lock);
++      if (!clk->ops->get_rate)
++              ret = -ENOSYS;
++      else
++              ret = clk->ops->get_rate(clk);
++      mutex_unlock(&clk->lock);
++
++      v4l2_clk_unlock_driver(clk);
++
++      return ret;
++}
++EXPORT_SYMBOL(v4l2_clk_get_rate);
++
++int v4l2_clk_set_rate(struct v4l2_clk *clk, unsigned long rate)
++{
++      int ret = v4l2_clk_lock_driver(clk);
++
++      if (ret < 0)
++              return ret;
++
++      mutex_lock(&clk->lock);
++      if (!clk->ops->set_rate)
++              ret = -ENOSYS;
++      else
++              ret = clk->ops->set_rate(clk, rate);
++      mutex_unlock(&clk->lock);
++
++      v4l2_clk_unlock_driver(clk);
++
++      return ret;
++}
++EXPORT_SYMBOL(v4l2_clk_set_rate);
++
++struct v4l2_clk *v4l2_clk_register(const struct v4l2_clk_ops *ops,
++                                 const char *dev_id,
++                                 const char *id, void *priv)
++{
++      struct v4l2_clk *clk;
++      int ret;
++
++      if (!ops || !dev_id)
++              return ERR_PTR(-EINVAL);
++
++      clk = kzalloc(sizeof(struct v4l2_clk), GFP_KERNEL);
++      if (!clk)
++              return ERR_PTR(-ENOMEM);
++
++      clk->id = kstrdup(id, GFP_KERNEL);
++      clk->dev_id = kstrdup(dev_id, GFP_KERNEL);
++      if ((id && !clk->id) || !clk->dev_id) {
++              ret = -ENOMEM;
++              goto ealloc;
++      }
++      clk->ops = ops;
++      clk->priv = priv;
++      atomic_set(&clk->use_count, 0);
++      mutex_init(&clk->lock);
++
++      mutex_lock(&clk_lock);
++      if (!IS_ERR(v4l2_clk_find(dev_id, id))) {
++              mutex_unlock(&clk_lock);
++              ret = -EEXIST;
++              goto eexist;
++      }
++      list_add_tail(&clk->list, &clk_list);
++      mutex_unlock(&clk_lock);
++
++      return clk;
++
++eexist:
++ealloc:
++      kfree(clk->id);
++      kfree(clk->dev_id);
++      kfree(clk);
++      return ERR_PTR(ret);
++}
++EXPORT_SYMBOL(v4l2_clk_register);
++
++void v4l2_clk_unregister(struct v4l2_clk *clk)
++{
++      if (WARN(atomic_read(&clk->use_count),
++               "%s(): Refusing to unregister ref-counted %s:%s clock!\n",
++               __func__, clk->dev_id, clk->id))
++              return;
++
++      mutex_lock(&clk_lock);
++      list_del(&clk->list);
++      mutex_unlock(&clk_lock);
++
++      kfree(clk->id);
++      kfree(clk->dev_id);
++      kfree(clk);
++}
++EXPORT_SYMBOL(v4l2_clk_unregister);
+diff --git a/include/media/v4l2-clk.h b/include/media/v4l2-clk.h
+new file mode 100644
+index 0000000..0503a90
+--- /dev/null
++++ b/include/media/v4l2-clk.h
+@@ -0,0 +1,54 @@
++/*
++ * V4L2 clock service
++ *
++ * Copyright (C) 2012-2013, 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.
++ *
++ * ATTENTION: This is a temporary API and it shall be replaced by the generic
++ * clock API, when the latter becomes widely available.
++ */
++
++#ifndef MEDIA_V4L2_CLK_H
++#define MEDIA_V4L2_CLK_H
++
++#include <linux/atomic.h>
++#include <linux/list.h>
++#include <linux/mutex.h>
++
++struct module;
++struct device;
++
++struct v4l2_clk {
++      struct list_head list;
++      const struct v4l2_clk_ops *ops;
++      const char *dev_id;
++      const char *id;
++      int enable;
++      struct mutex lock; /* Protect the enable count */
++      atomic_t use_count;
++      void *priv;
++};
++
++struct v4l2_clk_ops {
++      struct module   *owner;
++      int             (*enable)(struct v4l2_clk *clk);
++      void            (*disable)(struct v4l2_clk *clk);
++      unsigned long   (*get_rate)(struct v4l2_clk *clk);
++      int             (*set_rate)(struct v4l2_clk *clk, unsigned long);
++};
++
++struct v4l2_clk *v4l2_clk_register(const struct v4l2_clk_ops *ops,
++                                 const char *dev_name,
++                                 const char *name, void *priv);
++void v4l2_clk_unregister(struct v4l2_clk *clk);
++struct v4l2_clk *v4l2_clk_get(struct device *dev, const char *id);
++void v4l2_clk_put(struct v4l2_clk *clk);
++int v4l2_clk_enable(struct v4l2_clk *clk);
++void v4l2_clk_disable(struct v4l2_clk *clk);
++unsigned long v4l2_clk_get_rate(struct v4l2_clk *clk);
++int v4l2_clk_set_rate(struct v4l2_clk *clk, unsigned long rate);
++
++#endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0687-media-V4L2-add-a-device-pointer-to-struct-v4l2_subde.patch b/patches.tizen/0687-media-V4L2-add-a-device-pointer-to-struct-v4l2_subde.patch
new file mode 100644 (file)
index 0000000..3e9602d
--- /dev/null
@@ -0,0 +1,57 @@
+From dacea1964b579a72b8757a1f70a8f00779ba2655 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Mon, 10 Jun 2013 15:07:35 -0300
+Subject: [PATCH 0687/1302] [media] V4L2: add a device pointer to struct
+ v4l2_subdev
+
+It is often useful to have simple means to get from a subdevice to the
+underlying physical device. This patch adds such a pointer to struct
+v4l2_subdev and sets it accordingly in the I2C and SPI cases.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
+Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Tested-by: Lad, Prabhakar <prabhakar.csengg@gmail.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/v4l2-core/v4l2-common.c | 2 ++
+ include/media/v4l2-subdev.h           | 2 ++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
+index 3fed63f..accfec6 100644
+--- a/drivers/media/v4l2-core/v4l2-common.c
++++ b/drivers/media/v4l2-core/v4l2-common.c
+@@ -291,6 +291,7 @@ void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
+       sd->flags |= V4L2_SUBDEV_FL_IS_I2C;
+       /* the owner is the same as the i2c_client's driver owner */
+       sd->owner = client->driver->driver.owner;
++      sd->dev = &client->dev;
+       /* i2c_client and v4l2_subdev point to one another */
+       v4l2_set_subdevdata(sd, client);
+       i2c_set_clientdata(client, sd);
+@@ -426,6 +427,7 @@ void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi,
+       sd->flags |= V4L2_SUBDEV_FL_IS_SPI;
+       /* the owner is the same as the spi_device's driver owner */
+       sd->owner = spi->dev.driver->owner;
++      sd->dev = &spi->dev;
+       /* spi_device and v4l2_subdev point to one another */
+       v4l2_set_subdevdata(sd, spi);
+       spi_set_drvdata(spi, sd);
+diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
+index 5298d67..39a37f5 100644
+--- a/include/media/v4l2-subdev.h
++++ b/include/media/v4l2-subdev.h
+@@ -585,6 +585,8 @@ struct v4l2_subdev {
+       void *host_priv;
+       /* subdev device node */
+       struct video_device *devnode;
++      /* pointer to the physical device, if any */
++      struct device *dev;
+ };
+ #define media_entity_to_v4l2_subdev(ent) \
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0688-media-V4L2-support-asynchronous-subdevice-registrati.patch b/patches.tizen/0688-media-V4L2-support-asynchronous-subdevice-registrati.patch
new file mode 100644 (file)
index 0000000..598af96
--- /dev/null
@@ -0,0 +1,475 @@
+From 714a1754e249fbbae074d7a705802d89f602ab1b Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Tue, 8 Jan 2013 07:06:31 -0300
+Subject: [PATCH 0688/1302] [media] V4L2: support asynchronous subdevice
+ registration
+
+Currently bridge device drivers register devices for all subdevices
+synchronously, typically, during their probing. E.g. if an I2C CMOS sensor
+is attached to a video bridge device, the bridge driver will create an I2C
+device and wait for the respective I2C driver to probe. This makes linking
+of devices straight forward, but this approach cannot be used with
+intrinsically asynchronous and unordered device registration systems like
+the Flattened Device Tree. To support such systems this patch adds an
+asynchronous subdevice registration framework to V4L2. To use it respective
+(e.g. I2C) subdevice drivers must register themselves with the framework.
+A bridge driver on the other hand must register notification callbacks,
+that will be called upon various related events.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
+Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Tested-by: Lad, Prabhakar <prabhakar.csengg@gmail.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/v4l2-core/Makefile     |   3 +-
+ drivers/media/v4l2-core/v4l2-async.c | 280 +++++++++++++++++++++++++++++++++++
+ include/media/v4l2-async.h           | 105 +++++++++++++
+ include/media/v4l2-subdev.h          |   8 +
+ 4 files changed, 395 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/media/v4l2-core/v4l2-async.c
+ create mode 100644 include/media/v4l2-async.h
+
+diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile
+index 628c630..4c33b8d6 100644
+--- a/drivers/media/v4l2-core/Makefile
++++ b/drivers/media/v4l2-core/Makefile
+@@ -5,7 +5,8 @@
+ tuner-objs    :=      tuner-core.o
+ videodev-objs :=      v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \
+-                      v4l2-event.o v4l2-ctrls.o v4l2-subdev.o v4l2-clk.o
++                      v4l2-event.o v4l2-ctrls.o v4l2-subdev.o v4l2-clk.o \
++                      v4l2-async.o
+ ifeq ($(CONFIG_COMPAT),y)
+   videodev-objs += v4l2-compat-ioctl32.o
+ endif
+diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
+new file mode 100644
+index 0000000..c80ffb4
+--- /dev/null
++++ b/drivers/media/v4l2-core/v4l2-async.c
+@@ -0,0 +1,280 @@
++/*
++ * V4L2 asynchronous subdevice registration API
++ *
++ * Copyright (C) 2012-2013, 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/device.h>
++#include <linux/err.h>
++#include <linux/i2c.h>
++#include <linux/list.h>
++#include <linux/module.h>
++#include <linux/mutex.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++
++#include <media/v4l2-async.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-subdev.h>
++
++static bool match_i2c(struct device *dev, struct v4l2_async_subdev *asd)
++{
++      struct i2c_client *client = i2c_verify_client(dev);
++      return client &&
++              asd->bus_type == V4L2_ASYNC_BUS_I2C &&
++              asd->match.i2c.adapter_id == client->adapter->nr &&
++              asd->match.i2c.address == client->addr;
++}
++
++static bool match_platform(struct device *dev, struct v4l2_async_subdev *asd)
++{
++      return asd->bus_type == V4L2_ASYNC_BUS_PLATFORM &&
++              !strcmp(asd->match.platform.name, dev_name(dev));
++}
++
++static LIST_HEAD(subdev_list);
++static LIST_HEAD(notifier_list);
++static DEFINE_MUTEX(list_lock);
++
++static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *notifier,
++                                                  struct v4l2_async_subdev_list *asdl)
++{
++      struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl);
++      struct v4l2_async_subdev *asd;
++      bool (*match)(struct device *,
++                    struct v4l2_async_subdev *);
++
++      list_for_each_entry(asd, &notifier->waiting, list) {
++              /* bus_type has been verified valid before */
++              switch (asd->bus_type) {
++              case V4L2_ASYNC_BUS_CUSTOM:
++                      match = asd->match.custom.match;
++                      if (!match)
++                              /* Match always */
++                              return asd;
++                      break;
++              case V4L2_ASYNC_BUS_PLATFORM:
++                      match = match_platform;
++                      break;
++              case V4L2_ASYNC_BUS_I2C:
++                      match = match_i2c;
++                      break;
++              default:
++                      /* Cannot happen, unless someone breaks us */
++                      WARN_ON(true);
++                      return NULL;
++              }
++
++              /* match cannot be NULL here */
++              if (match(sd->dev, asd))
++                      return asd;
++      }
++
++      return NULL;
++}
++
++static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier,
++                                struct v4l2_async_subdev_list *asdl,
++                                struct v4l2_async_subdev *asd)
++{
++      struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl);
++      int ret;
++
++      /* Remove from the waiting list */
++      list_del(&asd->list);
++      asdl->asd = asd;
++      asdl->notifier = notifier;
++
++      if (notifier->bound) {
++              ret = notifier->bound(notifier, sd, asd);
++              if (ret < 0)
++                      return ret;
++      }
++      /* Move from the global subdevice list to notifier's done */
++      list_move(&asdl->list, &notifier->done);
++
++      ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);
++      if (ret < 0) {
++              if (notifier->unbind)
++                      notifier->unbind(notifier, sd, asd);
++              return ret;
++      }
++
++      if (list_empty(&notifier->waiting) && notifier->complete)
++              return notifier->complete(notifier);
++
++      return 0;
++}
++
++static void v4l2_async_cleanup(struct v4l2_async_subdev_list *asdl)
++{
++      struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl);
++
++      v4l2_device_unregister_subdev(sd);
++      /* Subdevice driver will reprobe and put asdl back onto the list */
++      list_del_init(&asdl->list);
++      asdl->asd = NULL;
++      sd->dev = NULL;
++}
++
++int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
++                               struct v4l2_async_notifier *notifier)
++{
++      struct v4l2_async_subdev_list *asdl, *tmp;
++      struct v4l2_async_subdev *asd;
++      int i;
++
++      if (!notifier->num_subdevs || notifier->num_subdevs > V4L2_MAX_SUBDEVS)
++              return -EINVAL;
++
++      notifier->v4l2_dev = v4l2_dev;
++      INIT_LIST_HEAD(&notifier->waiting);
++      INIT_LIST_HEAD(&notifier->done);
++
++      for (i = 0; i < notifier->num_subdevs; i++) {
++              asd = notifier->subdev[i];
++
++              switch (asd->bus_type) {
++              case V4L2_ASYNC_BUS_CUSTOM:
++              case V4L2_ASYNC_BUS_PLATFORM:
++              case V4L2_ASYNC_BUS_I2C:
++                      break;
++              default:
++                      dev_err(notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL,
++                              "Invalid bus-type %u on %p\n",
++                              asd->bus_type, asd);
++                      return -EINVAL;
++              }
++              list_add_tail(&asd->list, &notifier->waiting);
++      }
++
++      mutex_lock(&list_lock);
++
++      /* Keep also completed notifiers on the list */
++      list_add(&notifier->list, &notifier_list);
++
++      list_for_each_entry_safe(asdl, tmp, &subdev_list, list) {
++              int ret;
++
++              asd = v4l2_async_belongs(notifier, asdl);
++              if (!asd)
++                      continue;
++
++              ret = v4l2_async_test_notify(notifier, asdl, asd);
++              if (ret < 0) {
++                      mutex_unlock(&list_lock);
++                      return ret;
++              }
++      }
++
++      mutex_unlock(&list_lock);
++
++      return 0;
++}
++EXPORT_SYMBOL(v4l2_async_notifier_register);
++
++void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
++{
++      struct v4l2_async_subdev_list *asdl, *tmp;
++      unsigned int notif_n_subdev = notifier->num_subdevs;
++      unsigned int n_subdev = min(notif_n_subdev, V4L2_MAX_SUBDEVS);
++      struct device *dev[n_subdev];
++      int i = 0;
++
++      mutex_lock(&list_lock);
++
++      list_del(&notifier->list);
++
++      list_for_each_entry_safe(asdl, tmp, &notifier->done, list) {
++              struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl);
++
++              dev[i] = get_device(sd->dev);
++
++              v4l2_async_cleanup(asdl);
++
++              /* If we handled USB devices, we'd have to lock the parent too */
++              device_release_driver(dev[i++]);
++
++              if (notifier->unbind)
++                      notifier->unbind(notifier, sd, sd->asdl.asd);
++      }
++
++      mutex_unlock(&list_lock);
++
++      while (i--) {
++              struct device *d = dev[i];
++
++              if (d && device_attach(d) < 0) {
++                      const char *name = "(none)";
++                      int lock = device_trylock(d);
++
++                      if (lock && d->driver)
++                              name = d->driver->name;
++                      dev_err(d, "Failed to re-probe to %s\n", name);
++                      if (lock)
++                              device_unlock(d);
++              }
++              put_device(d);
++      }
++      /*
++       * Don't care about the waiting list, it is initialised and populated
++       * upon notifier registration.
++       */
++}
++EXPORT_SYMBOL(v4l2_async_notifier_unregister);
++
++int v4l2_async_register_subdev(struct v4l2_subdev *sd)
++{
++      struct v4l2_async_subdev_list *asdl = &sd->asdl;
++      struct v4l2_async_notifier *notifier;
++
++      mutex_lock(&list_lock);
++
++      INIT_LIST_HEAD(&asdl->list);
++
++      list_for_each_entry(notifier, &notifier_list, list) {
++              struct v4l2_async_subdev *asd = v4l2_async_belongs(notifier, asdl);
++              if (asd) {
++                      int ret = v4l2_async_test_notify(notifier, asdl, asd);
++                      mutex_unlock(&list_lock);
++                      return ret;
++              }
++      }
++
++      /* None matched, wait for hot-plugging */
++      list_add(&asdl->list, &subdev_list);
++
++      mutex_unlock(&list_lock);
++
++      return 0;
++}
++EXPORT_SYMBOL(v4l2_async_register_subdev);
++
++void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
++{
++      struct v4l2_async_subdev_list *asdl = &sd->asdl;
++      struct v4l2_async_notifier *notifier = asdl->notifier;
++
++      if (!asdl->asd) {
++              if (!list_empty(&asdl->list))
++                      v4l2_async_cleanup(asdl);
++              return;
++      }
++
++      mutex_lock(&list_lock);
++
++      list_add(&asdl->asd->list, &notifier->waiting);
++
++      v4l2_async_cleanup(asdl);
++
++      if (notifier->unbind)
++              notifier->unbind(notifier, sd, sd->asdl.asd);
++
++      mutex_unlock(&list_lock);
++}
++EXPORT_SYMBOL(v4l2_async_unregister_subdev);
+diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
+new file mode 100644
+index 0000000..c3ec6ac
+--- /dev/null
++++ b/include/media/v4l2-async.h
+@@ -0,0 +1,105 @@
++/*
++ * V4L2 asynchronous subdevice registration API
++ *
++ * Copyright (C) 2012-2013, 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 V4L2_ASYNC_H
++#define V4L2_ASYNC_H
++
++#include <linux/list.h>
++#include <linux/mutex.h>
++
++struct device;
++struct v4l2_device;
++struct v4l2_subdev;
++struct v4l2_async_notifier;
++
++/* A random max subdevice number, used to allocate an array on stack */
++#define V4L2_MAX_SUBDEVS 128U
++
++enum v4l2_async_bus_type {
++      V4L2_ASYNC_BUS_CUSTOM,
++      V4L2_ASYNC_BUS_PLATFORM,
++      V4L2_ASYNC_BUS_I2C,
++};
++
++/**
++ * struct v4l2_async_subdev - sub-device descriptor, as known to a bridge
++ * @bus_type: subdevice bus type to select the appropriate matching method
++ * @match:    union of per-bus type matching data sets
++ * @list:     used to link struct v4l2_async_subdev objects, waiting to be
++ *            probed, to a notifier->waiting list
++ */
++struct v4l2_async_subdev {
++      enum v4l2_async_bus_type bus_type;
++      union {
++              struct {
++                      const char *name;
++              } platform;
++              struct {
++                      int adapter_id;
++                      unsigned short address;
++              } i2c;
++              struct {
++                      bool (*match)(struct device *,
++                                    struct v4l2_async_subdev *);
++                      void *priv;
++              } custom;
++      } match;
++
++      /* v4l2-async core private: not to be used by drivers */
++      struct list_head list;
++};
++
++/**
++ * v4l2_async_subdev_list - provided by subdevices
++ * @list:     links struct v4l2_async_subdev_list objects to a global list
++ *            before probing, and onto notifier->done after probing
++ * @asd:      pointer to respective struct v4l2_async_subdev
++ * @notifier: pointer to managing notifier
++ */
++struct v4l2_async_subdev_list {
++      struct list_head list;
++      struct v4l2_async_subdev *asd;
++      struct v4l2_async_notifier *notifier;
++};
++
++/**
++ * v4l2_async_notifier - v4l2_device notifier data
++ * @num_subdevs:number of subdevices
++ * @subdev:   array of pointers to subdevice descriptors
++ * @v4l2_dev: pointer to struct v4l2_device
++ * @waiting:  list of struct v4l2_async_subdev, waiting for their drivers
++ * @done:     list of struct v4l2_async_subdev_list, already probed
++ * @list:     member in a global list of notifiers
++ * @bound:    a subdevice driver has successfully probed one of subdevices
++ * @complete: all subdevices have been probed successfully
++ * @unbind:   a subdevice is leaving
++ */
++struct v4l2_async_notifier {
++      unsigned int num_subdevs;
++      struct v4l2_async_subdev **subdev;
++      struct v4l2_device *v4l2_dev;
++      struct list_head waiting;
++      struct list_head done;
++      struct list_head list;
++      int (*bound)(struct v4l2_async_notifier *notifier,
++                   struct v4l2_subdev *subdev,
++                   struct v4l2_async_subdev *asd);
++      int (*complete)(struct v4l2_async_notifier *notifier);
++      void (*unbind)(struct v4l2_async_notifier *notifier,
++                     struct v4l2_subdev *subdev,
++                     struct v4l2_async_subdev *asd);
++};
++
++int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
++                               struct v4l2_async_notifier *notifier);
++void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier);
++int v4l2_async_register_subdev(struct v4l2_subdev *sd);
++void v4l2_async_unregister_subdev(struct v4l2_subdev *sd);
++#endif
+diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
+index 39a37f5..b27436e 100644
+--- a/include/media/v4l2-subdev.h
++++ b/include/media/v4l2-subdev.h
+@@ -24,6 +24,7 @@
+ #include <linux/types.h>
+ #include <linux/v4l2-subdev.h>
+ #include <media/media-entity.h>
++#include <media/v4l2-async.h>
+ #include <media/v4l2-common.h>
+ #include <media/v4l2-dev.h>
+ #include <media/v4l2-fh.h>
+@@ -587,8 +588,15 @@ struct v4l2_subdev {
+       struct video_device *devnode;
+       /* pointer to the physical device, if any */
+       struct device *dev;
++      struct v4l2_async_subdev_list asdl;
+ };
++static inline struct v4l2_subdev *v4l2_async_to_subdev(
++                      struct v4l2_async_subdev_list *asdl)
++{
++      return container_of(asdl, struct v4l2_subdev, asdl);
++}
++
+ #define media_entity_to_v4l2_subdev(ent) \
+       container_of(ent, struct v4l2_subdev, entity)
+ #define vdev_to_v4l2_subdev(vdev) \
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0689-media-V4L2-fix-compilation-if-CONFIG_I2C-is-undefine.patch b/patches.tizen/0689-media-V4L2-fix-compilation-if-CONFIG_I2C-is-undefine.patch
new file mode 100644 (file)
index 0000000..7001f9b
--- /dev/null
@@ -0,0 +1,39 @@
+From bfc38055c1c295da28ddf925cf4ec9eb48ef5e84 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Mon, 24 Jun 2013 05:13:51 -0300
+Subject: [PATCH 0689/1302] [media] V4L2: fix compilation if CONFIG_I2C is
+ undefined
+
+i2c_verify_client() is only available, if I2C is enabled. Fix v4l2-async.c
+compilation if I2C is disabled.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/v4l2-core/v4l2-async.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
+index c80ffb4..aae2417 100644
+--- a/drivers/media/v4l2-core/v4l2-async.c
++++ b/drivers/media/v4l2-core/v4l2-async.c
+@@ -24,11 +24,15 @@
+ static bool match_i2c(struct device *dev, struct v4l2_async_subdev *asd)
+ {
++#if IS_ENABLED(CONFIG_I2C)
+       struct i2c_client *client = i2c_verify_client(dev);
+       return client &&
+               asd->bus_type == V4L2_ASYNC_BUS_I2C &&
+               asd->match.i2c.adapter_id == client->adapter->nr &&
+               asd->match.i2c.address == client->addr;
++#else
++      return false;
++#endif
+ }
+ static bool match_platform(struct device *dev, struct v4l2_async_subdev *asd)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0690-media-V4L-Drop-bus_type-check-in-v4l2-async-match-fu.patch b/patches.tizen/0690-media-V4L-Drop-bus_type-check-in-v4l2-async-match-fu.patch
new file mode 100644 (file)
index 0000000..e7d9dec
--- /dev/null
@@ -0,0 +1,47 @@
+From 82e3c4c01ed43be5e0200eb49dbeac031df53ffc Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 19 Jul 2013 12:08:08 -0300
+Subject: [PATCH 0690/1302] [media] V4L: Drop bus_type check in v4l2-async
+ match functions
+
+These match_* functions are internal callbacks and are always
+invoked only after checking asd->bus_type. So drop redundant
+checks in match_i2c() and match_platform() functions.
+Acked-and-tested-by: Lad, Prabhakar <prabhakar.csengg@gmail.com>
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
+Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/v4l2-core/v4l2-async.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
+index aae2417..ff87c29 100644
+--- a/drivers/media/v4l2-core/v4l2-async.c
++++ b/drivers/media/v4l2-core/v4l2-async.c
+@@ -27,7 +27,6 @@ static bool match_i2c(struct device *dev, struct v4l2_async_subdev *asd)
+ #if IS_ENABLED(CONFIG_I2C)
+       struct i2c_client *client = i2c_verify_client(dev);
+       return client &&
+-              asd->bus_type == V4L2_ASYNC_BUS_I2C &&
+               asd->match.i2c.adapter_id == client->adapter->nr &&
+               asd->match.i2c.address == client->addr;
+ #else
+@@ -37,8 +36,7 @@ static bool match_i2c(struct device *dev, struct v4l2_async_subdev *asd)
+ static bool match_platform(struct device *dev, struct v4l2_async_subdev *asd)
+ {
+-      return asd->bus_type == V4L2_ASYNC_BUS_PLATFORM &&
+-              !strcmp(asd->match.platform.name, dev_name(dev));
++      return !strcmp(asd->match.platform.name, dev_name(dev));
+ }
+ static LIST_HEAD(subdev_list);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0691-media-V4L-Rename-v4l2_async_bus_-to-v4l2_async_match.patch b/patches.tizen/0691-media-V4L-Rename-v4l2_async_bus_-to-v4l2_async_match.patch
new file mode 100644 (file)
index 0000000..efc274a
--- /dev/null
@@ -0,0 +1,121 @@
+From 72f806632ce51f425da3a174e7346faeed3c5325 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 19 Jul 2013 12:14:46 -0300
+Subject: [PATCH 0691/1302] [media] V4L: Rename v4l2_async_bus_* to
+ v4l2_async_match_*
+
+enum v4l2_async_bus_type also selects a method subdevs are matched
+in the notification handlers, rename it to v4l2_async_match_type
+so V4L2_ASYNC_MATCH_OF entry can be further added for matching by
+device tree node pointer.
+
+Acked-and-tested-by: Lad, Prabhakar <prabhakar.csengg@gmail.com>
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
+Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/v4l2-core/v4l2-async.c | 26 +++++++++++++-------------
+ include/media/v4l2-async.h           | 12 ++++++------
+ 2 files changed, 19 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
+index ff87c29..86934ca 100644
+--- a/drivers/media/v4l2-core/v4l2-async.c
++++ b/drivers/media/v4l2-core/v4l2-async.c
+@@ -34,9 +34,9 @@ static bool match_i2c(struct device *dev, struct v4l2_async_subdev *asd)
+ #endif
+ }
+-static bool match_platform(struct device *dev, struct v4l2_async_subdev *asd)
++static bool match_devname(struct device *dev, struct v4l2_async_subdev *asd)
+ {
+-      return !strcmp(asd->match.platform.name, dev_name(dev));
++      return !strcmp(asd->match.device_name.name, dev_name(dev));
+ }
+ static LIST_HEAD(subdev_list);
+@@ -53,17 +53,17 @@ static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *
+       list_for_each_entry(asd, &notifier->waiting, list) {
+               /* bus_type has been verified valid before */
+-              switch (asd->bus_type) {
+-              case V4L2_ASYNC_BUS_CUSTOM:
++              switch (asd->match_type) {
++              case V4L2_ASYNC_MATCH_CUSTOM:
+                       match = asd->match.custom.match;
+                       if (!match)
+                               /* Match always */
+                               return asd;
+                       break;
+-              case V4L2_ASYNC_BUS_PLATFORM:
+-                      match = match_platform;
++              case V4L2_ASYNC_MATCH_DEVNAME:
++                      match = match_devname;
+                       break;
+-              case V4L2_ASYNC_BUS_I2C:
++              case V4L2_ASYNC_MATCH_I2C:
+                       match = match_i2c;
+                       break;
+               default:
+@@ -141,15 +141,15 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
+       for (i = 0; i < notifier->num_subdevs; i++) {
+               asd = notifier->subdev[i];
+-              switch (asd->bus_type) {
+-              case V4L2_ASYNC_BUS_CUSTOM:
+-              case V4L2_ASYNC_BUS_PLATFORM:
+-              case V4L2_ASYNC_BUS_I2C:
++              switch (asd->match_type) {
++              case V4L2_ASYNC_MATCH_CUSTOM:
++              case V4L2_ASYNC_MATCH_DEVNAME:
++              case V4L2_ASYNC_MATCH_I2C:
+                       break;
+               default:
+                       dev_err(notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL,
+-                              "Invalid bus-type %u on %p\n",
+-                              asd->bus_type, asd);
++                              "Invalid match type %u on %p\n",
++                              asd->match_type, asd);
+                       return -EINVAL;
+               }
+               list_add_tail(&asd->list, &notifier->waiting);
+diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
+index c3ec6ac..33e3b2a 100644
+--- a/include/media/v4l2-async.h
++++ b/include/media/v4l2-async.h
+@@ -22,10 +22,10 @@ struct v4l2_async_notifier;
+ /* A random max subdevice number, used to allocate an array on stack */
+ #define V4L2_MAX_SUBDEVS 128U
+-enum v4l2_async_bus_type {
+-      V4L2_ASYNC_BUS_CUSTOM,
+-      V4L2_ASYNC_BUS_PLATFORM,
+-      V4L2_ASYNC_BUS_I2C,
++enum v4l2_async_match_type {
++      V4L2_ASYNC_MATCH_CUSTOM,
++      V4L2_ASYNC_MATCH_DEVNAME,
++      V4L2_ASYNC_MATCH_I2C,
+ };
+ /**
+@@ -36,11 +36,11 @@ enum v4l2_async_bus_type {
+  *            probed, to a notifier->waiting list
+  */
+ struct v4l2_async_subdev {
+-      enum v4l2_async_bus_type bus_type;
++      enum v4l2_async_match_type match_type;
+       union {
+               struct {
+                       const char *name;
+-              } platform;
++              } device_name;
+               struct {
+                       int adapter_id;
+                       unsigned short address;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0692-media-V4L-Add-V4L2_ASYNC_MATCH_OF-subdev-matching-ty.patch b/patches.tizen/0692-media-V4L-Add-V4L2_ASYNC_MATCH_OF-subdev-matching-ty.patch
new file mode 100644 (file)
index 0000000..a275367
--- /dev/null
@@ -0,0 +1,90 @@
+From 17248e00b81004bb1a8e7066783b0e40e66b8877 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 19 Jul 2013 12:21:29 -0300
+Subject: [PATCH 0692/1302] [media] V4L: Add V4L2_ASYNC_MATCH_OF subdev
+ matching type
+
+Add support for matching by device_node pointer. This allows
+the notifier user to simply pass a list of device_node pointers
+corresponding to sub-devices.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Lad, Prabhakar <prabhakar.csengg@gmail.com>
+Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
+Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/v4l2-core/v4l2-async.c | 9 +++++++++
+ include/media/v4l2-async.h           | 5 +++++
+ 2 files changed, 14 insertions(+)
+
+diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
+index 86934ca..9f91013 100644
+--- a/drivers/media/v4l2-core/v4l2-async.c
++++ b/drivers/media/v4l2-core/v4l2-async.c
+@@ -39,6 +39,11 @@ static bool match_devname(struct device *dev, struct v4l2_async_subdev *asd)
+       return !strcmp(asd->match.device_name.name, dev_name(dev));
+ }
++static bool match_of(struct device *dev, struct v4l2_async_subdev *asd)
++{
++      return dev->of_node == asd->match.of.node;
++}
++
+ static LIST_HEAD(subdev_list);
+ static LIST_HEAD(notifier_list);
+ static DEFINE_MUTEX(list_lock);
+@@ -66,6 +71,9 @@ static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *
+               case V4L2_ASYNC_MATCH_I2C:
+                       match = match_i2c;
+                       break;
++              case V4L2_ASYNC_MATCH_OF:
++                      match = match_of;
++                      break;
+               default:
+                       /* Cannot happen, unless someone breaks us */
+                       WARN_ON(true);
+@@ -145,6 +153,7 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
+               case V4L2_ASYNC_MATCH_CUSTOM:
+               case V4L2_ASYNC_MATCH_DEVNAME:
+               case V4L2_ASYNC_MATCH_I2C:
++              case V4L2_ASYNC_MATCH_OF:
+                       break;
+               default:
+                       dev_err(notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL,
+diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
+index 33e3b2a..82b2981 100644
+--- a/include/media/v4l2-async.h
++++ b/include/media/v4l2-async.h
+@@ -15,6 +15,7 @@
+ #include <linux/mutex.h>
+ struct device;
++struct device_node;
+ struct v4l2_device;
+ struct v4l2_subdev;
+ struct v4l2_async_notifier;
+@@ -26,6 +27,7 @@ enum v4l2_async_match_type {
+       V4L2_ASYNC_MATCH_CUSTOM,
+       V4L2_ASYNC_MATCH_DEVNAME,
+       V4L2_ASYNC_MATCH_I2C,
++      V4L2_ASYNC_MATCH_OF,
+ };
+ /**
+@@ -39,6 +41,9 @@ struct v4l2_async_subdev {
+       enum v4l2_async_match_type match_type;
+       union {
+               struct {
++                      const struct device_node *node;
++              } of;
++              struct {
+                       const char *name;
+               } device_name;
+               struct {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0693-media-V4L-Rename-subdev-field-of-struct-v4l2_async_n.patch b/patches.tizen/0693-media-V4L-Rename-subdev-field-of-struct-v4l2_async_n.patch
new file mode 100644 (file)
index 0000000..9610ed1
--- /dev/null
@@ -0,0 +1,61 @@
+From 74c17d943c257db3620ab6c466a6719a20fe3880 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 19 Jul 2013 12:31:10 -0300
+Subject: [PATCH 0693/1302] [media] V4L: Rename subdev field of struct
+ v4l2_async_notifier
+
+This is a purely cosmetic change. Since the 'subdev' member
+points to an array of subdevs make it more explicit by
+renaming to the plural form.
+
+Acked-and-tested-by: Lad, Prabhakar <prabhakar.csengg@gmail.com>
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
+Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/v4l2-core/v4l2-async.c | 2 +-
+ include/media/v4l2-async.h           | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
+index 9f91013..ed31a65 100644
+--- a/drivers/media/v4l2-core/v4l2-async.c
++++ b/drivers/media/v4l2-core/v4l2-async.c
+@@ -147,7 +147,7 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
+       INIT_LIST_HEAD(&notifier->done);
+       for (i = 0; i < notifier->num_subdevs; i++) {
+-              asd = notifier->subdev[i];
++              asd = notifier->subdevs[i];
+               switch (asd->match_type) {
+               case V4L2_ASYNC_MATCH_CUSTOM:
+diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
+index 82b2981..8fac8ea 100644
+--- a/include/media/v4l2-async.h
++++ b/include/media/v4l2-async.h
+@@ -77,7 +77,7 @@ struct v4l2_async_subdev_list {
+ /**
+  * v4l2_async_notifier - v4l2_device notifier data
+  * @num_subdevs:number of subdevices
+- * @subdev:   array of pointers to subdevice descriptors
++ * @subdevs:  array of pointers to subdevice descriptors
+  * @v4l2_dev: pointer to struct v4l2_device
+  * @waiting:  list of struct v4l2_async_subdev, waiting for their drivers
+  * @done:     list of struct v4l2_async_subdev_list, already probed
+@@ -88,7 +88,7 @@ struct v4l2_async_subdev_list {
+  */
+ struct v4l2_async_notifier {
+       unsigned int num_subdevs;
+-      struct v4l2_async_subdev **subdev;
++      struct v4l2_async_subdev **subdevs;
+       struct v4l2_device *v4l2_dev;
+       struct list_head waiting;
+       struct list_head done;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0694-media-V4L-Merge-struct-v4l2_async_subdev_list-with-s.patch b/patches.tizen/0694-media-V4L-Merge-struct-v4l2_async_subdev_list-with-s.patch
new file mode 100644 (file)
index 0000000..07a3c5e
--- /dev/null
@@ -0,0 +1,268 @@
+From eb944dcfe6f81abe71e81308b80f2a5375979fed Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Mon, 22 Jul 2013 08:01:33 -0300
+Subject: [PATCH 0694/1302] [media] V4L: Merge struct v4l2_async_subdev_list
+ with struct v4l2_subdev
+
+By integrating the v4l2-async API internals a bit more with
+the core overall the v4l2-async code becomes a bit simpler
+and easier to follow.
+Acked-and-tested-by: Lad, Prabhakar <prabhakar.csengg@gmail.com>
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
+Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/v4l2-core/v4l2-async.c | 67 ++++++++++++++++--------------------
+ include/media/v4l2-async.h           | 15 +-------
+ include/media/v4l2-subdev.h          | 13 ++++---
+ 3 files changed, 36 insertions(+), 59 deletions(-)
+
+diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
+index ed31a65..b350ab9 100644
+--- a/drivers/media/v4l2-core/v4l2-async.c
++++ b/drivers/media/v4l2-core/v4l2-async.c
+@@ -49,12 +49,10 @@ static LIST_HEAD(notifier_list);
+ static DEFINE_MUTEX(list_lock);
+ static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *notifier,
+-                                                  struct v4l2_async_subdev_list *asdl)
++                                                  struct v4l2_subdev *sd)
+ {
+-      struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl);
+       struct v4l2_async_subdev *asd;
+-      bool (*match)(struct device *,
+-                    struct v4l2_async_subdev *);
++      bool (*match)(struct device *, struct v4l2_async_subdev *);
+       list_for_each_entry(asd, &notifier->waiting, list) {
+               /* bus_type has been verified valid before */
+@@ -89,16 +87,15 @@ static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *
+ }
+ static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier,
+-                                struct v4l2_async_subdev_list *asdl,
++                                struct v4l2_subdev *sd,
+                                 struct v4l2_async_subdev *asd)
+ {
+-      struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl);
+       int ret;
+       /* Remove from the waiting list */
+       list_del(&asd->list);
+-      asdl->asd = asd;
+-      asdl->notifier = notifier;
++      sd->asd = asd;
++      sd->notifier = notifier;
+       if (notifier->bound) {
+               ret = notifier->bound(notifier, sd, asd);
+@@ -106,7 +103,7 @@ static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier,
+                       return ret;
+       }
+       /* Move from the global subdevice list to notifier's done */
+-      list_move(&asdl->list, &notifier->done);
++      list_move(&sd->async_list, &notifier->done);
+       ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);
+       if (ret < 0) {
+@@ -121,21 +118,19 @@ static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier,
+       return 0;
+ }
+-static void v4l2_async_cleanup(struct v4l2_async_subdev_list *asdl)
++static void v4l2_async_cleanup(struct v4l2_subdev *sd)
+ {
+-      struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl);
+-
+       v4l2_device_unregister_subdev(sd);
+-      /* Subdevice driver will reprobe and put asdl back onto the list */
+-      list_del_init(&asdl->list);
+-      asdl->asd = NULL;
++      /* Subdevice driver will reprobe and put the subdev back onto the list */
++      list_del_init(&sd->async_list);
++      sd->asd = NULL;
+       sd->dev = NULL;
+ }
+ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
+                                struct v4l2_async_notifier *notifier)
+ {
+-      struct v4l2_async_subdev_list *asdl, *tmp;
++      struct v4l2_subdev *sd, *tmp;
+       struct v4l2_async_subdev *asd;
+       int i;
+@@ -169,14 +164,14 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
+       /* Keep also completed notifiers on the list */
+       list_add(&notifier->list, &notifier_list);
+-      list_for_each_entry_safe(asdl, tmp, &subdev_list, list) {
++      list_for_each_entry_safe(sd, tmp, &subdev_list, async_list) {
+               int ret;
+-              asd = v4l2_async_belongs(notifier, asdl);
++              asd = v4l2_async_belongs(notifier, sd);
+               if (!asd)
+                       continue;
+-              ret = v4l2_async_test_notify(notifier, asdl, asd);
++              ret = v4l2_async_test_notify(notifier, sd, asd);
+               if (ret < 0) {
+                       mutex_unlock(&list_lock);
+                       return ret;
+@@ -191,7 +186,7 @@ EXPORT_SYMBOL(v4l2_async_notifier_register);
+ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
+ {
+-      struct v4l2_async_subdev_list *asdl, *tmp;
++      struct v4l2_subdev *sd, *tmp;
+       unsigned int notif_n_subdev = notifier->num_subdevs;
+       unsigned int n_subdev = min(notif_n_subdev, V4L2_MAX_SUBDEVS);
+       struct device *dev[n_subdev];
+@@ -201,18 +196,16 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
+       list_del(&notifier->list);
+-      list_for_each_entry_safe(asdl, tmp, &notifier->done, list) {
+-              struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl);
+-
++      list_for_each_entry_safe(sd, tmp, &notifier->done, list) {
+               dev[i] = get_device(sd->dev);
+-              v4l2_async_cleanup(asdl);
++              v4l2_async_cleanup(sd);
+               /* If we handled USB devices, we'd have to lock the parent too */
+               device_release_driver(dev[i++]);
+               if (notifier->unbind)
+-                      notifier->unbind(notifier, sd, sd->asdl.asd);
++                      notifier->unbind(notifier, sd, sd->asd);
+       }
+       mutex_unlock(&list_lock);
+@@ -241,24 +234,23 @@ EXPORT_SYMBOL(v4l2_async_notifier_unregister);
+ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
+ {
+-      struct v4l2_async_subdev_list *asdl = &sd->asdl;
+       struct v4l2_async_notifier *notifier;
+       mutex_lock(&list_lock);
+-      INIT_LIST_HEAD(&asdl->list);
++      INIT_LIST_HEAD(&sd->async_list);
+       list_for_each_entry(notifier, &notifier_list, list) {
+-              struct v4l2_async_subdev *asd = v4l2_async_belongs(notifier, asdl);
++              struct v4l2_async_subdev *asd = v4l2_async_belongs(notifier, sd);
+               if (asd) {
+-                      int ret = v4l2_async_test_notify(notifier, asdl, asd);
++                      int ret = v4l2_async_test_notify(notifier, sd, asd);
+                       mutex_unlock(&list_lock);
+                       return ret;
+               }
+       }
+       /* None matched, wait for hot-plugging */
+-      list_add(&asdl->list, &subdev_list);
++      list_add(&sd->async_list, &subdev_list);
+       mutex_unlock(&list_lock);
+@@ -268,23 +260,22 @@ EXPORT_SYMBOL(v4l2_async_register_subdev);
+ void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
+ {
+-      struct v4l2_async_subdev_list *asdl = &sd->asdl;
+-      struct v4l2_async_notifier *notifier = asdl->notifier;
++      struct v4l2_async_notifier *notifier = sd->notifier;
+-      if (!asdl->asd) {
+-              if (!list_empty(&asdl->list))
+-                      v4l2_async_cleanup(asdl);
++      if (!sd->asd) {
++              if (!list_empty(&sd->async_list))
++                      v4l2_async_cleanup(sd);
+               return;
+       }
+       mutex_lock(&list_lock);
+-      list_add(&asdl->asd->list, &notifier->waiting);
++      list_add(&sd->asd->list, &notifier->waiting);
+-      v4l2_async_cleanup(asdl);
++      v4l2_async_cleanup(sd);
+       if (notifier->unbind)
+-              notifier->unbind(notifier, sd, sd->asdl.asd);
++              notifier->unbind(notifier, sd, sd->asd);
+       mutex_unlock(&list_lock);
+ }
+diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
+index 8fac8ea..7683569 100644
+--- a/include/media/v4l2-async.h
++++ b/include/media/v4l2-async.h
+@@ -62,25 +62,12 @@ struct v4l2_async_subdev {
+ };
+ /**
+- * v4l2_async_subdev_list - provided by subdevices
+- * @list:     links struct v4l2_async_subdev_list objects to a global list
+- *            before probing, and onto notifier->done after probing
+- * @asd:      pointer to respective struct v4l2_async_subdev
+- * @notifier: pointer to managing notifier
+- */
+-struct v4l2_async_subdev_list {
+-      struct list_head list;
+-      struct v4l2_async_subdev *asd;
+-      struct v4l2_async_notifier *notifier;
+-};
+-
+-/**
+  * v4l2_async_notifier - v4l2_device notifier data
+  * @num_subdevs:number of subdevices
+  * @subdevs:  array of pointers to subdevice descriptors
+  * @v4l2_dev: pointer to struct v4l2_device
+  * @waiting:  list of struct v4l2_async_subdev, waiting for their drivers
+- * @done:     list of struct v4l2_async_subdev_list, already probed
++ * @done:     list of struct v4l2_subdev, already probed
+  * @list:     member in a global list of notifiers
+  * @bound:    a subdevice driver has successfully probed one of subdevices
+  * @complete: all subdevices have been probed successfully
+diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
+index b27436e..7c18cd9 100644
+--- a/include/media/v4l2-subdev.h
++++ b/include/media/v4l2-subdev.h
+@@ -588,15 +588,14 @@ struct v4l2_subdev {
+       struct video_device *devnode;
+       /* pointer to the physical device, if any */
+       struct device *dev;
+-      struct v4l2_async_subdev_list asdl;
++      /* Links this subdev to a global subdev_list or @notifier->done list. */
++      struct list_head async_list;
++      /* Pointer to respective struct v4l2_async_subdev. */
++      struct v4l2_async_subdev *asd;
++      /* Pointer to the managing notifier. */
++      struct v4l2_async_notifier *notifier;
+ };
+-static inline struct v4l2_subdev *v4l2_async_to_subdev(
+-                      struct v4l2_async_subdev_list *asdl)
+-{
+-      return container_of(asdl, struct v4l2_subdev, asdl);
+-}
+-
+ #define media_entity_to_v4l2_subdev(ent) \
+       container_of(ent, struct v4l2_subdev, entity)
+ #define vdev_to_v4l2_subdev(vdev) \
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0695-media-v4l-of-Use-of_get_child_by_name.patch b/patches.tizen/0695-media-v4l-of-Use-of_get_child_by_name.patch
new file mode 100644 (file)
index 0000000..a919541
--- /dev/null
@@ -0,0 +1,38 @@
+From ed148ee468d30a4b2cee76033e43c423be12b6c7 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Tue, 2 Jul 2013 23:04:25 -0300
+Subject: [PATCH 0695/1302] [media] v4l: of: Use of_get_child_by_name()
+
+Replace a manual loop through child nodes with a call to
+of_get_child_by_name().
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Acked-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/v4l2-core/v4l2-of.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/media/v4l2-core/v4l2-of.c b/drivers/media/v4l2-core/v4l2-of.c
+index aa59639..f64d953 100644
+--- a/drivers/media/v4l2-core/v4l2-of.c
++++ b/drivers/media/v4l2-core/v4l2-of.c
+@@ -173,12 +173,8 @@ struct device_node *v4l2_of_get_next_endpoint(const struct device_node *parent,
+               if (node)
+                       parent = node;
+-              for_each_child_of_node(parent, node) {
+-                      if (!of_node_cmp(node->name, "port")) {
+-                              port = node;
+-                              break;
+-                      }
+-              }
++              port = of_get_child_by_name(parent, "port");
++
+               if (port) {
+                       /* Found a port, get an endpoint. */
+                       endpoint = of_get_next_child(port, NULL);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0696-media-v4l-of-Drop-acquired-reference-to-node-when-ge.patch b/patches.tizen/0696-media-v4l-of-Drop-acquired-reference-to-node-when-ge.patch
new file mode 100644 (file)
index 0000000..a0a7388
--- /dev/null
@@ -0,0 +1,33 @@
+From 5cb475fc90769321592850c321e57d7389786fac Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Tue, 2 Jul 2013 23:05:51 -0300
+Subject: [PATCH 0696/1302] [media] v4l: of: Drop acquired reference to node
+ when getting next endpoint
+
+The of_get_child_by_name() function takes a reference to the node it
+returns. Make sure to drop it when looking for the ports node in
+v4l2_of_get_next_endpoint().
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Acked-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/v4l2-core/v4l2-of.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/media/v4l2-core/v4l2-of.c b/drivers/media/v4l2-core/v4l2-of.c
+index f64d953..ed305d8 100644
+--- a/drivers/media/v4l2-core/v4l2-of.c
++++ b/drivers/media/v4l2-core/v4l2-of.c
+@@ -186,6 +186,7 @@ struct device_node *v4l2_of_get_next_endpoint(const struct device_node *parent,
+               if (!endpoint)
+                       pr_err("%s(): no endpoint nodes specified for %s\n",
+                              __func__, parent->full_name);
++              of_node_put(node);
+       } else {
+               port = of_get_parent(prev);
+               if (!port)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0697-media-v4l-async-Make-it-safe-to-unregister-unregiste.patch b/patches.tizen/0697-media-v4l-async-Make-it-safe-to-unregister-unregiste.patch
new file mode 100644 (file)
index 0000000..bfdd6d7
--- /dev/null
@@ -0,0 +1,46 @@
+From 652a58e1a505cc93a2351647e682e2beae08c2d2 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Wed, 3 Jul 2013 07:49:06 -0300
+Subject: [PATCH 0697/1302] [media] v4l: async: Make it safe to unregister
+ unregistered notifier
+
+Calling v4l2_async_notifier_unregister() on a notifier that hasn't been
+registered leads to a crash. To simplify drivers, make it safe to
+unregister a notifier that has not been registered.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Tested-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Acked-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/v4l2-core/v4l2-async.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
+index b350ab9..10bb62c 100644
+--- a/drivers/media/v4l2-core/v4l2-async.c
++++ b/drivers/media/v4l2-core/v4l2-async.c
+@@ -192,6 +192,9 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
+       struct device *dev[n_subdev];
+       int i = 0;
++      if (!notifier->v4l2_dev)
++              return;
++
+       mutex_lock(&list_lock);
+       list_del(&notifier->list);
+@@ -225,6 +228,9 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
+               }
+               put_device(d);
+       }
++
++      notifier->v4l2_dev = NULL;
++
+       /*
+        * Don't care about the waiting list, it is initialised and populated
+        * upon notifier registration.
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0698-media-v4l2-async-Use-proper-list-head-for-iteration-.patch b/patches.tizen/0698-media-v4l2-async-Use-proper-list-head-for-iteration-.patch
new file mode 100644 (file)
index 0000000..14f1ee7
--- /dev/null
@@ -0,0 +1,33 @@
+From 5a844db595f72d539d4926eff3f74feef2588edd Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 31 Jul 2013 13:10:18 -0300
+Subject: [PATCH 0698/1302] [media] v4l2-async: Use proper list head for
+ iteration over registered subdevs
+
+This fixes regression introduced in commit b426b3a660c85faf6e1ca1c92c6d
+[media] V4L: Merge struct v4l2_async_subdev_list with struct v4l2_subdev
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/v4l2-core/v4l2-async.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
+index 10bb62c..c85d69d 100644
+--- a/drivers/media/v4l2-core/v4l2-async.c
++++ b/drivers/media/v4l2-core/v4l2-async.c
+@@ -199,7 +199,7 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
+       list_del(&notifier->list);
+-      list_for_each_entry_safe(sd, tmp, &notifier->done, list) {
++      list_for_each_entry_safe(sd, tmp, &notifier->done, async_list) {
+               dev[i] = get_device(sd->dev);
+               v4l2_async_cleanup(sd);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0699-media-media-OF-add-sync-on-green-active-property.patch b/patches.tizen/0699-media-media-OF-add-sync-on-green-active-property.patch
new file mode 100644 (file)
index 0000000..02c9f20
--- /dev/null
@@ -0,0 +1,65 @@
+From 5db8f40ec129f7c1d239aca64c3044f2be7abbd2 Mon Sep 17 00:00:00 2001
+From: "Lad, Prabhakar" <prabhakar.csengg@gmail.com>
+Date: Sun, 11 Aug 2013 02:02:24 -0300
+Subject: [PATCH 0699/1302] [media] media: OF: add "sync-on-green-active"
+ property
+
+This patch adds 'sync-on-green-active' property as part
+of endpoint property.
+
+Signed-off-by: Lad, Prabhakar <prabhakar.csengg@gmail.com>
+Acked-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
+Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/devicetree/bindings/media/video-interfaces.txt | 2 ++
+ drivers/media/v4l2-core/v4l2-of.c                            | 4 ++++
+ include/media/v4l2-mediabus.h                                | 3 +++
+ 3 files changed, 9 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/media/video-interfaces.txt b/Documentation/devicetree/bindings/media/video-interfaces.txt
+index e022d2d..ce719f8 100644
+--- a/Documentation/devicetree/bindings/media/video-interfaces.txt
++++ b/Documentation/devicetree/bindings/media/video-interfaces.txt
+@@ -88,6 +88,8 @@ Optional endpoint properties
+ - field-even-active: field signal level during the even field data transmission.
+ - pclk-sample: sample data on rising (1) or falling (0) edge of the pixel clock
+   signal.
++- sync-on-green-active: active state of Sync-on-green (SoG) signal, 0/1 for
++  LOW/HIGH respectively.
+ - data-lanes: an array of physical data lane indexes. Position of an entry
+   determines the logical lane number, while the value of an entry indicates
+   physical lane, e.g. for 2-lane MIPI CSI-2 bus we could have
+diff --git a/drivers/media/v4l2-core/v4l2-of.c b/drivers/media/v4l2-core/v4l2-of.c
+index ed305d8..a6478dc 100644
+--- a/drivers/media/v4l2-core/v4l2-of.c
++++ b/drivers/media/v4l2-core/v4l2-of.c
+@@ -100,6 +100,10 @@ static void v4l2_of_parse_parallel_bus(const struct device_node *node,
+       if (!of_property_read_u32(node, "data-shift", &v))
+               bus->data_shift = v;
++      if (!of_property_read_u32(node, "sync-on-green-active", &v))
++              flags |= v ? V4L2_MBUS_VIDEO_SOG_ACTIVE_HIGH :
++                      V4L2_MBUS_VIDEO_SOG_ACTIVE_LOW;
++
+       bus->flags = flags;
+ }
+diff --git a/include/media/v4l2-mediabus.h b/include/media/v4l2-mediabus.h
+index 83ae07e..395c4a9 100644
+--- a/include/media/v4l2-mediabus.h
++++ b/include/media/v4l2-mediabus.h
+@@ -40,6 +40,9 @@
+ #define V4L2_MBUS_FIELD_EVEN_HIGH             (1 << 10)
+ /* FIELD = 1/0 - Field1 (odd)/Field2 (even) */
+ #define V4L2_MBUS_FIELD_EVEN_LOW              (1 << 11)
++/* Active state of Sync-on-green (SoG) signal, 0/1 for LOW/HIGH respectively. */
++#define V4L2_MBUS_VIDEO_SOG_ACTIVE_HIGH       (1 << 12)
++#define V4L2_MBUS_VIDEO_SOG_ACTIVE_LOW                (1 << 13)
+ /* Serial flags */
+ /* How many lanes the client can use */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0700-media-exynos4-is-Fix-potential-NULL-pointer-derefere.patch b/patches.tizen/0700-media-exynos4-is-Fix-potential-NULL-pointer-derefere.patch
new file mode 100644 (file)
index 0000000..74bc35b
--- /dev/null
@@ -0,0 +1,48 @@
+From 6e6f1fba190b438abf450a590fb66a36da30f6fc Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Fri, 2 Aug 2013 04:58:25 -0300
+Subject: [PATCH 0700/1302] [media] exynos4-is: Fix potential NULL pointer
+ dereference
+
+dev->of_node could be NULL. Hence check for the same and return before
+dereferencing it in the subsequent error message.
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-lite.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
+index 08fbfed..318d4c3 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite.c
++++ b/drivers/media/platform/exynos4-is/fimc-lite.c
+@@ -1504,16 +1504,17 @@ static int fimc_lite_probe(struct platform_device *pdev)
+       struct resource *res;
+       int ret;
++      if (!dev->of_node)
++              return -ENODEV;
++
+       fimc = devm_kzalloc(dev, sizeof(*fimc), GFP_KERNEL);
+       if (!fimc)
+               return -ENOMEM;
+-      if (dev->of_node) {
+-              of_id = of_match_node(flite_of_match, dev->of_node);
+-              if (of_id)
+-                      drv_data = (struct flite_drvdata *)of_id->data;
+-              fimc->index = of_alias_get_id(dev->of_node, "fimc-lite");
+-      }
++      of_id = of_match_node(flite_of_match, dev->of_node);
++      if (of_id)
++              drv_data = (struct flite_drvdata *)of_id->data;
++      fimc->index = of_alias_get_id(dev->of_node, "fimc-lite");
+       if (!drv_data || fimc->index >= drv_data->num_instances ||
+                                               fimc->index < 0) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0701-media-exynos4-is-Initialize-the-ISP-subdev-sd-owner-.patch b/patches.tizen/0701-media-exynos4-is-Initialize-the-ISP-subdev-sd-owner-.patch
new file mode 100644 (file)
index 0000000..b66196d
--- /dev/null
@@ -0,0 +1,33 @@
+From b4ebbd1a5e29a3b0b27d684ffd21f1c29c44238c Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Mon, 5 Aug 2013 10:35:25 -0300
+Subject: [PATCH 0701/1302] [media] exynos4-is: Initialize the ISP subdev
+ sd->owner field
+
+Set the subdevs owner module so the exynos4_fimc_is module cannot
+be unloaded when the FIMC-IS driver is in use.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-isp.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c
+index 077993c..f2b25e7 100644
+--- a/drivers/media/platform/exynos4-is/fimc-isp.c
++++ b/drivers/media/platform/exynos4-is/fimc-isp.c
+@@ -699,6 +699,8 @@ int fimc_isp_subdev_create(struct fimc_isp *isp)
+       mutex_init(&isp->subdev_lock);
+       v4l2_subdev_init(sd, &fimc_is_subdev_ops);
++
++      sd->owner = THIS_MODULE;
+       sd->grp_id = GRP_ID_FIMC_IS;
+       sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+       snprintf(sd->name, sizeof(sd->name), "FIMC-IS-ISP");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0702-media-exynos4-is-Add-missing-MODULE_LICENSE-for-exyn.patch b/patches.tizen/0702-media-exynos4-is-Add-missing-MODULE_LICENSE-for-exyn.patch
new file mode 100644 (file)
index 0000000..37d8064
--- /dev/null
@@ -0,0 +1,30 @@
+From 86a45ad881ff767fd6db21cdf84c64d9b74f2983 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 31 Jul 2013 11:08:19 -0300
+Subject: [PATCH 0702/1302] [media] exynos4-is: Add missing MODULE_LICENSE for
+ exynos-fimc-is.ko
+
+This fixes compilation warning:
+WARNING: modpost: missing MODULE_LICENSE() in
+drivers/media/platform/exynos4-is/exynos-fimc-is.o
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-is.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c
+index 0b641b5..76794f1 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is.c
++++ b/drivers/media/platform/exynos4-is/fimc-is.c
+@@ -1018,3 +1018,4 @@ module_exit(fimc_is_module_exit);
+ MODULE_ALIAS("platform:" FIMC_IS_DRV_NAME);
+ MODULE_AUTHOR("Younghwan Joo <yhwan.joo@samsung.com>");
+ MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
++MODULE_LICENSE("GPL v2");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0703-media-exynos4-is-Add-missing-v4l2_device_unregister-.patch b/patches.tizen/0703-media-exynos4-is-Add-missing-v4l2_device_unregister-.patch
new file mode 100644 (file)
index 0000000..1f83d2a
--- /dev/null
@@ -0,0 +1,30 @@
+From c29df92797fd4db2f3b2132fc201c3088c466fc7 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 9 Aug 2013 14:23:53 -0300
+Subject: [PATCH 0703/1302] [media] exynos4-is: Add missing
+ v4l2_device_unregister() call in fimc_md_remove()
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/media-dev.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
+index d1a1ff6..5ccda74 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.c
++++ b/drivers/media/platform/exynos4-is/media-dev.c
+@@ -1561,6 +1561,8 @@ static int fimc_md_remove(struct platform_device *pdev)
+       if (!fmd)
+               return 0;
++
++      v4l2_device_unregister(&fmd->v4l2_dev);
+       device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode);
+       fimc_md_unregister_entities(fmd);
+       fimc_md_pipelines_free(fmd);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0704-media-exynos4-is-Simplify-sclk_cam-clocks-handling.patch b/patches.tizen/0704-media-exynos4-is-Simplify-sclk_cam-clocks-handling.patch
new file mode 100644 (file)
index 0000000..6c5e1a7
--- /dev/null
@@ -0,0 +1,75 @@
+From bde73ea0cbbb55e7683ec3de7d08b0de7b56bcff Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 19 Jul 2013 10:05:17 -0300
+Subject: [PATCH 0704/1302] [media] exynos4-is: Simplify sclk_cam clocks
+ handling
+
+Use clk_prepare_enable()/clk_disable_unprepare() instead of
+separately prearing/unparing the clk_cam clocks. This simplifies
+the code that is now mostly not going to be used, function
+__fimc_md_set_camclk() is only left for S5PV210 platform which
+is not yet converted to Device Tree.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/media-dev.c | 13 +++----------
+ 1 file changed, 3 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
+index 5ccda74..11fddd5 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.c
++++ b/drivers/media/platform/exynos4-is/media-dev.c
+@@ -1167,7 +1167,6 @@ static void fimc_md_put_clocks(struct fimc_md *fmd)
+       while (--i >= 0) {
+               if (IS_ERR(fmd->camclk[i].clock))
+                       continue;
+-              clk_unprepare(fmd->camclk[i].clock);
+               clk_put(fmd->camclk[i].clock);
+               fmd->camclk[i].clock = ERR_PTR(-EINVAL);
+       }
+@@ -1186,7 +1185,7 @@ static int fimc_md_get_clocks(struct fimc_md *fmd)
+       struct device *dev = NULL;
+       char clk_name[32];
+       struct clk *clock;
+-      int ret, i;
++      int i, ret = 0;
+       for (i = 0; i < FIMC_MAX_CAMCLKS; i++)
+               fmd->camclk[i].clock = ERR_PTR(-EINVAL);
+@@ -1204,12 +1203,6 @@ static int fimc_md_get_clocks(struct fimc_md *fmd)
+                       ret = PTR_ERR(clock);
+                       break;
+               }
+-              ret = clk_prepare(clock);
+-              if (ret < 0) {
+-                      clk_put(clock);
+-                      fmd->camclk[i].clock = ERR_PTR(-EINVAL);
+-                      break;
+-              }
+               fmd->camclk[i].clock = clock;
+       }
+       if (ret)
+@@ -1266,7 +1259,7 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd,
+                       ret = pm_runtime_get_sync(fmd->pmf);
+                       if (ret < 0)
+                               return ret;
+-                      ret = clk_enable(camclk->clock);
++                      ret = clk_prepare_enable(camclk->clock);
+                       dbg("Enabled camclk %d: f: %lu", si->clk_id,
+                           clk_get_rate(camclk->clock));
+               }
+@@ -1277,7 +1270,7 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd,
+               return 0;
+       if (--camclk->use_count == 0) {
+-              clk_disable(camclk->clock);
++              clk_disable_unprepare(camclk->clock);
+               pm_runtime_put(fmd->pmf);
+               dbg("Disabled camclk %d", si->clk_id);
+       }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0705-media-exynos4-is-Annotate-unused-functions.patch b/patches.tizen/0705-media-exynos4-is-Annotate-unused-functions.patch
new file mode 100644 (file)
index 0000000..2bed117
--- /dev/null
@@ -0,0 +1,48 @@
+From 1932b46e2446fd67b2560b1203d16347b94e5e1f Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Fri, 2 Aug 2013 02:32:13 -0300
+Subject: [PATCH 0705/1302] [media] exynos4-is: Annotate unused functions
+
+__is_set_init_isp_aa and fimc_is_hw_set_tune currently do not have
+any callers. However these functions may be used in the future. Hence
+instead of deleting them, staticize and annotate them with __maybe_unused
+flag to avoid compiler warnings.
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-is-param.c | 2 +-
+ drivers/media/platform/exynos4-is/fimc-is-regs.c  | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-is-param.c b/drivers/media/platform/exynos4-is/fimc-is-param.c
+index c7e7f69..bf1465d 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is-param.c
++++ b/drivers/media/platform/exynos4-is/fimc-is-param.c
+@@ -287,7 +287,7 @@ void __is_set_sensor(struct fimc_is *is, int fps)
+       fimc_is_set_param_bit(is, PARAM_ISP_OTF_INPUT);
+ }
+-void __is_set_init_isp_aa(struct fimc_is *is)
++static void __maybe_unused __is_set_init_isp_aa(struct fimc_is *is)
+ {
+       struct isp_param *isp;
+diff --git a/drivers/media/platform/exynos4-is/fimc-is-regs.c b/drivers/media/platform/exynos4-is/fimc-is-regs.c
+index 19d3eae..c1589f7 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is-regs.c
++++ b/drivers/media/platform/exynos4-is/fimc-is-regs.c
+@@ -96,7 +96,7 @@ int fimc_is_hw_set_param(struct fimc_is *is)
+       return 0;
+ }
+-int fimc_is_hw_set_tune(struct fimc_is *is)
++static int __maybe_unused fimc_is_hw_set_tune(struct fimc_is *is)
+ {
+       fimc_is_hw_wait_intmsr0_intmsd0(is);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0706-media-exynos4-is-Print-error-message-on-timeout.patch b/patches.tizen/0706-media-exynos4-is-Print-error-message-on-timeout.patch
new file mode 100644 (file)
index 0000000..d17a609
--- /dev/null
@@ -0,0 +1,31 @@
+From 339c5d63d7bf03d3c02723e77239b80be854fb60 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Fri, 23 Aug 2013 05:36:56 -0300
+Subject: [PATCH 0706/1302] [media] exynos4-is: Print error message on timeout
+
+There is a stray '!' character so the error message never gets printed.
+
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-is-regs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-is-regs.c b/drivers/media/platform/exynos4-is/fimc-is-regs.c
+index c1589f7..ad8e630 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is-regs.c
++++ b/drivers/media/platform/exynos4-is/fimc-is-regs.c
+@@ -250,7 +250,7 @@ int fimc_is_itf_mode_change(struct fimc_is *is)
+       fimc_is_hw_change_mode(is);
+       ret = fimc_is_wait_event(is, IS_ST_CHANGE_MODE, 1,
+                               FIMC_IS_CONFIG_TIMEOUT);
+-      if (!ret < 0)
++      if (ret < 0)
+               dev_err(&is->pdev->dev, "%s(): mode change (%d) timeout\n",
+                       __func__, is->config_index);
+       return ret;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0707-media-exynos4-is-Ensure-the-FIMC-gate-clock-is-disab.patch b/patches.tizen/0707-media-exynos4-is-Ensure-the-FIMC-gate-clock-is-disab.patch
new file mode 100644 (file)
index 0000000..4e78258
--- /dev/null
@@ -0,0 +1,50 @@
+From 25350fa928560ffcef5fbc7caafc6570b95b5b6a Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Fri, 19 Jul 2013 07:39:53 -0300
+Subject: [PATCH 0707/1302] [media] exynos4-is: Ensure the FIMC gate clock is
+ disabled at driver remove()
+
+The patch fixes following warning:
+[ 9664.460000] WARNING: CPU: 0 PID: 2880 at drivers/clk/clk.c:695 __clk_unprepare+0x8c/0xa4()
+[ 9664.470000] Modules linked in: m5mols s5k5baf s5p_fimc(-) ipv6 s5p_csis v4l2_mem2mem videobuf2_dma_contig videobuf2_memops exynos4_is_common videobuf2_core [last unloaded: m5mols]
+[ 9664.485000] CPU: 0 PID: 2880 Comm: rmmod Tainted: G        W    3.11.0-rc1-00070-ga94e22f-dirty #1558
+[ 9664.495000] [<c0014aec>] (unwind_backtrace+0x0/0xf8) from [<c0011574>] (show_stack+0x10/0x14)
+[ 9664.505000] [<c0011574>] (show_stack+0x10/0x14) from [<c038b248>] (dump_stack+0x6c/0xac)
+[ 9664.510000] [<c038b248>] (dump_stack+0x6c/0xac) from [<c001d824>] (warn_slowpath_common+0x64/0x88)
+[ 9664.520000] [<c001d824>] (warn_slowpath_common+0x64/0x88) from [<c001d864>] (warn_slowpath_null+0x1c/0x24)
+[ 9664.530000] [<c001d864>] (warn_slowpath_null+0x1c/0x24) from [<c02f0b9c>] (__clk_unprepare+0x8c/0xa4)
+[ 9664.540000] [<c02f0b9c>] (__clk_unprepare+0x8c/0xa4) from [<c02f0bc8>] (clk_unprepare+0x14/0x1c)
+[ 9664.550000] [<c02f0bc8>] (clk_unprepare+0x14/0x1c) from [<bf191344>] (fimc_clk_put+0x3c/0x5c [s5p_fimc])
+[ 9664.560000] [<bf191344>] (fimc_clk_put+0x3c/0x5c [s5p_fimc]) from [<bf1913c0>] (fimc_remove+0x5c/0x90 [s5p_fimc])
+[ 9664.570000] [<bf1913c0>] (fimc_remove+0x5c/0x90 [s5p_fimc]) from [<c0219ca0>] (platform_drv_remove+0x18/0x1c)
+[ 9664.580000] [<c0219ca0>] (platform_drv_remove+0x18/0x1c) from [<c021856c>] (__device_release_driver+0x70/0xcc)
+[ 9664.590000] [<c021856c>] (__device_release_driver+0x70/0xcc) from [<c0218d54>] (driver_detach+0xac/0xb0)
+[ 9664.595000] [<c0218d54>] (driver_detach+0xac/0xb0) from [<c021839c>] (bus_remove_driver+0x7c/0xc0)
+[ 9664.605000] [<c021839c>] (bus_remove_driver+0x7c/0xc0) from [<c00659d8>] (SyS_delete_module+0x11c/0x204)
+[ 9664.615000] [<c00659d8>] (SyS_delete_module+0x11c/0x204) from [<c000e360>] (ret_fast_syscall+0x0/0x30)
+[ 9664.625000] ---[ end trace 662c092cce432c8d ]---
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-core.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c
+index aa6716e..5c0f438 100644
+--- a/drivers/media/platform/exynos4-is/fimc-core.c
++++ b/drivers/media/platform/exynos4-is/fimc-core.c
+@@ -1131,6 +1131,8 @@ static int fimc_remove(struct platform_device *pdev)
+       struct fimc_dev *fimc = platform_get_drvdata(pdev);
+       pm_runtime_disable(&pdev->dev);
++      if (!pm_runtime_status_suspended(&pdev->dev))
++              clk_disable(fimc->clock[CLK_GATE]);
+       pm_runtime_set_suspended(&pdev->dev);
+       fimc_unregister_capture_subdev(fimc);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0708-media-V4L-s5c73m3-Add-format-propagation-for-TRY-for.patch b/patches.tizen/0708-media-V4L-s5c73m3-Add-format-propagation-for-TRY-for.patch
new file mode 100644 (file)
index 0000000..a57199e
--- /dev/null
@@ -0,0 +1,38 @@
+From dd31826e8d5219cadedb4fd8a168495aa566e788 Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Wed, 24 Jul 2013 10:57:32 -0300
+Subject: [PATCH 0708/1302] [media] V4L: s5c73m3: Add format propagation for
+ TRY formats
+
+Resolution set on ISP pad of S5C73M3-OIF subdev should be
+propagated to source pad for TRY and ACTIVE formats.
+The patch adds missing propagation for TRY format.
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/s5c73m3/s5c73m3-core.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+index 1ff7509..b379111 100644
+--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
++++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+@@ -1112,6 +1112,11 @@ static int s5c73m3_oif_set_fmt(struct v4l2_subdev *sd,
+       if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+               mf = v4l2_subdev_get_try_format(fh, fmt->pad);
+               *mf = fmt->format;
++              if (fmt->pad == OIF_ISP_PAD) {
++                      mf = v4l2_subdev_get_try_format(fh, OIF_SOURCE_PAD);
++                      mf->width = fmt->format.width;
++                      mf->height = fmt->format.height;
++              }
+       } else {
+               switch (fmt->pad) {
+               case OIF_ISP_PAD:
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0709-dma-pl330-rip-out-broken-redundant-ID-probing.patch b/patches.tizen/0709-dma-pl330-rip-out-broken-redundant-ID-probing.patch
new file mode 100644 (file)
index 0000000..d20dc72
--- /dev/null
@@ -0,0 +1,108 @@
+From ce23b3e393fc536a5cca7182e0ee157bc5619ad6 Mon Sep 17 00:00:00 2001
+From: Will Deacon <will.deacon@arm.com>
+Date: Mon, 10 Jun 2013 19:34:37 +0100
+Subject: [PATCH 0709/1302] dma: pl330: rip out broken, redundant ID probing
+
+The PL330 driver probes the peripheral and primecell IDs of the device to
+make sure that it is indeed an AMBA PL330. However, it does this by
+making byte accesses to a device mapping of the word-aligned ID
+registers, which is either UNPREDICTABLE or generates an alignment fault
+(depending on the presence of the virtualisation extensions).
+
+Rather than fix this code, we can actually rip most of it out and let
+the AMBA bus driver correctly do the probing for us.
+
+Cc: Jassi Brar <jaswinder.singh@linaro.org>
+Cc: Vinod Koul <vinod.koul@intel.com>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Acked-by: Jassi Brar <jaswinder.singh@linaro.org>
+Acked-by: Grant Likely <grant.likely@linaro.org>
+Signed-off-by: Vinod Koul <vinod.koul@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/dma/pl330.c | 27 +++------------------------
+ 1 file changed, 3 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
+index 4c2f465..8455329 100644
+--- a/drivers/dma/pl330.c
++++ b/drivers/dma/pl330.c
+@@ -157,7 +157,6 @@ enum pl330_reqtype {
+ #define PERIPH_REV_R0P0               0
+ #define PERIPH_REV_R1P0               1
+ #define PERIPH_REV_R1P1               2
+-#define PCELL_ID              0xff0
+ #define CR0_PERIPH_REQ_SET    (1 << 0)
+ #define CR0_BOOT_EN_SET               (1 << 1)
+@@ -193,8 +192,6 @@ enum pl330_reqtype {
+ #define INTEG_CFG             0x0
+ #define PERIPH_ID_VAL         ((PART << 0) | (DESIGNER << 12))
+-#define PCELL_ID_VAL          0xb105f00d
+-
+ #define PL330_STATE_STOPPED           (1 << 0)
+ #define PL330_STATE_EXECUTING         (1 << 1)
+ #define PL330_STATE_WFE                       (1 << 2)
+@@ -292,7 +289,6 @@ static unsigned cmd_line;
+ /* Populated by the PL330 core driver for DMA API driver's info */
+ struct pl330_config {
+       u32     periph_id;
+-      u32     pcell_id;
+ #define DMAC_MODE_NS  (1 << 0)
+       unsigned int    mode;
+       unsigned int    data_bus_width:10; /* In number of bits */
+@@ -650,19 +646,6 @@ static inline bool _manager_ns(struct pl330_thread *thrd)
+       return (pl330->pinfo->pcfg.mode & DMAC_MODE_NS) ? true : false;
+ }
+-static inline u32 get_id(struct pl330_info *pi, u32 off)
+-{
+-      void __iomem *regs = pi->base;
+-      u32 id = 0;
+-
+-      id |= (readb(regs + off + 0x0) << 0);
+-      id |= (readb(regs + off + 0x4) << 8);
+-      id |= (readb(regs + off + 0x8) << 16);
+-      id |= (readb(regs + off + 0xc) << 24);
+-
+-      return id;
+-}
+-
+ static inline u32 get_revision(u32 periph_id)
+ {
+       return (periph_id >> PERIPH_REV_SHIFT) & PERIPH_REV_MASK;
+@@ -1986,9 +1969,6 @@ static void read_dmac_config(struct pl330_info *pi)
+       pi->pcfg.num_events = val;
+       pi->pcfg.irq_ns = readl(regs + CR3);
+-
+-      pi->pcfg.periph_id = get_id(pi, PERIPH_ID);
+-      pi->pcfg.pcell_id = get_id(pi, PCELL_ID);
+ }
+ static inline void _reset_thread(struct pl330_thread *thrd)
+@@ -2098,10 +2078,8 @@ static int pl330_add(struct pl330_info *pi)
+       regs = pi->base;
+       /* Check if we can handle this DMAC */
+-      if ((get_id(pi, PERIPH_ID) & 0xfffff) != PERIPH_ID_VAL
+-         || get_id(pi, PCELL_ID) != PCELL_ID_VAL) {
+-              dev_err(pi->dev, "PERIPH_ID 0x%x, PCELL_ID 0x%x !\n",
+-                      get_id(pi, PERIPH_ID), get_id(pi, PCELL_ID));
++      if ((pi->pcfg.periph_id & 0xfffff) != PERIPH_ID_VAL) {
++              dev_err(pi->dev, "PERIPH_ID 0x%x !\n", pi->pcfg.periph_id);
+               return -EINVAL;
+       }
+@@ -2957,6 +2935,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
+       if (ret)
+               return ret;
++      pi->pcfg.periph_id = adev->periphid;
+       ret = pl330_add(pi);
+       if (ret)
+               goto probe_err1;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0710-dma-pl330-use-dma_addr_t-for-describing-bus-addresse.patch b/patches.tizen/0710-dma-pl330-use-dma_addr_t-for-describing-bus-addresse.patch
new file mode 100644 (file)
index 0000000..1c2f961
--- /dev/null
@@ -0,0 +1,39 @@
+From 09d10ecd146febffac0b77d268e23732ce5bd888 Mon Sep 17 00:00:00 2001
+From: Will Deacon <will.deacon@arm.com>
+Date: Mon, 10 Jun 2013 19:34:38 +0100
+Subject: [PATCH 0710/1302] dma: pl330: use dma_addr_t for describing bus
+ addresses
+
+The microcode bus address (pl330_dmac.mcode_bus) is currently a u32,
+which fails to compile when building on a system with 64-bit bus
+addresses.
+
+This patch uses dma_addr_t to represent the address instead.
+
+Cc: Jassi Brar <jaswinder.singh@linaro.org>
+Cc: Vinod Koul <vinod.koul@intel.com>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Acked-by: Jassi Brar <jaswinder.singh@linaro.org>
+Acked-by: Grant Likely <grant.likely@linaro.org>
+Signed-off-by: Vinod Koul <vinod.koul@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/dma/pl330.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
+index 8455329..fa645d8 100644
+--- a/drivers/dma/pl330.c
++++ b/drivers/dma/pl330.c
+@@ -501,7 +501,7 @@ struct pl330_dmac {
+       /* Maximum possible events/irqs */
+       int                     events[32];
+       /* BUS address of MicroCode buffer */
+-      u32                     mcode_bus;
++      dma_addr_t              mcode_bus;
+       /* CPU address of MicroCode buffer */
+       void                    *mcode_cpu;
+       /* List of all Channel threads */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0711-ARM-tizen_defconfig-disable-s5p-ehci.patch b/patches.tizen/0711-ARM-tizen_defconfig-disable-s5p-ehci.patch
new file mode 100644 (file)
index 0000000..100e8bc
--- /dev/null
@@ -0,0 +1,79 @@
+From 5c2577426b96be5dcd81300631c633af91ccf387 Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Tue, 3 Sep 2013 17:32:00 +0900
+Subject: [PATCH 0711/1302] ARM: tizen_defconfig: disable s5p-ehci
+
+Until we resolve phy issue of otg(host/device), we disable the
+ehci configuration.
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_defconfig | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index dbee6bd..79db035 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -499,6 +499,7 @@ CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+ CONFIG_CROSS_MEMORY_ATTACH=y
+ # CONFIG_CLEANCACHE is not set
+ # CONFIG_FRONTSWAP is not set
++# CONFIG_ZBUD is not set
+ CONFIG_FORCE_MAX_ZONEORDER=11
+ CONFIG_ALIGNMENT_TRAP=y
+ # CONFIG_UACCESS_WITH_MEMCPY is not set
+@@ -535,7 +536,6 @@ CONFIG_CPU_FREQ=y
+ CONFIG_CPU_FREQ_TABLE=y
+ CONFIG_CPU_FREQ_GOV_COMMON=y
+ CONFIG_CPU_FREQ_STAT=y
+-CONFIG_NR_CPU_LOAD_STORAGE=10
+ # CONFIG_CPU_FREQ_STAT_DETAILS is not set
+ # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+ # CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+@@ -1089,6 +1089,7 @@ CONFIG_OF_DEVICE=y
+ CONFIG_OF_I2C=y
+ CONFIG_OF_NET=y
+ CONFIG_OF_MDIO=y
++CONFIG_OF_RESERVED_MEM=y
+ # CONFIG_PARPORT is not set
+ CONFIG_BLK_DEV=y
+ # CONFIG_BLK_DEV_COW_COMMON is not set
+@@ -2337,7 +2338,7 @@ CONFIG_USB_DEFAULT_PERSIST=y
+ CONFIG_USB_EHCI_HCD=y
+ # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+ CONFIG_USB_EHCI_TT_NEWSCHED=y
+-CONFIG_USB_EHCI_S5P=y
++# CONFIG_USB_EHCI_S5P is not set
+ # CONFIG_USB_EHCI_HCD_PLATFORM is not set
+ # CONFIG_USB_OXU210HP_HCD is not set
+ # CONFIG_USB_ISP116X_HCD is not set
+@@ -2435,6 +2436,12 @@ CONFIG_USB_S3C_HSOTG=y
+ # CONFIG_USB_NET2272 is not set
+ # CONFIG_USB_DUMMY_HCD is not set
+ CONFIG_USB_LIBCOMPOSITE=y
++CONFIG_USB_U_ETHER=y
++CONFIG_USB_U_RNDIS=y
++CONFIG_USB_F_ECM=y
++CONFIG_USB_F_SUBSET=y
++CONFIG_USB_F_RNDIS=y
++# CONFIG_USB_CONFIGFS is not set
+ # CONFIG_USB_ZERO is not set
+ # CONFIG_USB_AUDIO is not set
+ CONFIG_USB_ETH=y
+@@ -2939,10 +2946,9 @@ CONFIG_IIO_ST_GYRO_SPI_3AXIS=y
+ # CONFIG_ADJD_S311 is not set
+ # CONFIG_SENSORS_TSL2563 is not set
+ # CONFIG_VCNL4000 is not set
+-#CONFIG_GP2AP002A00F is not set
++# CONFIG_GP2AP002A00F is not set
+ CONFIG_CM36651=y
+-
+ #
+ # Magnetometer sensors
+ #
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0712-spi-spi-s3c64xx-Remove-platform-dependent-code.patch b/patches.tizen/0712-spi-spi-s3c64xx-Remove-platform-dependent-code.patch
new file mode 100644 (file)
index 0000000..f06536f
--- /dev/null
@@ -0,0 +1,147 @@
+From 8c6427b0165710cb8edcc33e48a116b3b8710175 Mon Sep 17 00:00:00 2001
+From: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Date: Wed, 21 Aug 2013 13:13:00 +0200
+Subject: [PATCH 0712/1302] spi: spi-s3c64xx: Remove platform dependent code
+
+This patch removes platform dependent code from the spi-s3c64xx driver.
+
+Signed-off-by: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/spi/spi-s3c64xx.c | 99 +----------------------------------------------
+ 1 file changed, 1 insertion(+), 98 deletions(-)
+
+diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
+index 71cc3e6..c1cf40d 100644
+--- a/drivers/spi/spi-s3c64xx.c
++++ b/drivers/spi/spi-s3c64xx.c
+@@ -34,10 +34,6 @@
+ #include <linux/platform_data/spi-s3c64xx.h>
+-#ifdef CONFIG_S3C_DMA
+-#include <mach/dma.h>
+-#endif
+-
+ #define MAX_SPI_PORTS         3
+ /* Registers and bit-fields */
+@@ -199,9 +195,7 @@ struct s3c64xx_spi_driver_data {
+       unsigned                        cur_speed;
+       struct s3c64xx_spi_dma_data     rx_dma;
+       struct s3c64xx_spi_dma_data     tx_dma;
+-#ifdef CONFIG_S3C_DMA
+-      struct samsung_dma_ops          *ops;
+-#endif
++
+       struct s3c64xx_spi_port_config  *port_conf;
+       unsigned int                    port_id;
+       unsigned long                   gpios[4];
+@@ -283,96 +277,6 @@ static void s3c64xx_spi_dmacb(void *data)
+       spin_unlock_irqrestore(&sdd->lock, flags);
+ }
+-#ifdef CONFIG_S3C_DMA
+-/* FIXME: remove this section once arch/arm/mach-s3c64xx uses dmaengine */
+-
+-static struct s3c2410_dma_client s3c64xx_spi_dma_client = {
+-      .name = "samsung-spi-dma",
+-};
+-
+-static void prepare_dma(struct s3c64xx_spi_dma_data *dma,
+-                                      unsigned len, dma_addr_t buf)
+-{
+-      struct s3c64xx_spi_driver_data *sdd;
+-      struct samsung_dma_prep info;
+-      struct samsung_dma_config config;
+-
+-      if (dma->direction == DMA_DEV_TO_MEM) {
+-              sdd = container_of((void *)dma,
+-                      struct s3c64xx_spi_driver_data, rx_dma);
+-              config.direction = sdd->rx_dma.direction;
+-              config.fifo = sdd->sfr_start + S3C64XX_SPI_RX_DATA;
+-              config.width = sdd->cur_bpw / 8;
+-              sdd->ops->config((enum dma_ch)sdd->rx_dma.ch, &config);
+-      } else {
+-              sdd = container_of((void *)dma,
+-                      struct s3c64xx_spi_driver_data, tx_dma);
+-              config.direction =  sdd->tx_dma.direction;
+-              config.fifo = sdd->sfr_start + S3C64XX_SPI_TX_DATA;
+-              config.width = sdd->cur_bpw / 8;
+-              sdd->ops->config((enum dma_ch)sdd->tx_dma.ch, &config);
+-      }
+-
+-      info.cap = DMA_SLAVE;
+-      info.len = len;
+-      info.fp = s3c64xx_spi_dmacb;
+-      info.fp_param = dma;
+-      info.direction = dma->direction;
+-      info.buf = buf;
+-
+-      sdd->ops->prepare((enum dma_ch)dma->ch, &info);
+-      sdd->ops->trigger((enum dma_ch)dma->ch);
+-}
+-
+-static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
+-{
+-      struct samsung_dma_req req;
+-      struct device *dev = &sdd->pdev->dev;
+-
+-      sdd->ops = samsung_dma_get_ops();
+-
+-      req.cap = DMA_SLAVE;
+-      req.client = &s3c64xx_spi_dma_client;
+-
+-      sdd->rx_dma.ch = (void *)sdd->ops->request(sdd->rx_dma.dmach, &req, dev, "rx");
+-      sdd->tx_dma.ch = (void *)sdd->ops->request(sdd->tx_dma.dmach, &req, dev, "tx");
+-
+-      return 1;
+-}
+-
+-static int s3c64xx_spi_prepare_transfer(struct spi_master *spi)
+-{
+-      struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi);
+-
+-      /* Acquire DMA channels */
+-      while (!acquire_dma(sdd))
+-              usleep_range(10000, 11000);
+-
+-      pm_runtime_get_sync(&sdd->pdev->dev);
+-
+-      return 0;
+-}
+-
+-static int s3c64xx_spi_unprepare_transfer(struct spi_master *spi)
+-{
+-      struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi);
+-
+-      /* Free DMA channels */
+-      sdd->ops->release((enum dma_ch)sdd->rx_dma.ch, &s3c64xx_spi_dma_client);
+-      sdd->ops->release((enum dma_ch)sdd->tx_dma.ch, &s3c64xx_spi_dma_client);
+-
+-      pm_runtime_put(&sdd->pdev->dev);
+-
+-      return 0;
+-}
+-
+-static void s3c64xx_spi_dma_stop(struct s3c64xx_spi_driver_data *sdd,
+-                               struct s3c64xx_spi_dma_data *dma)
+-{
+-      sdd->ops->stop((enum dma_ch)dma->ch);
+-}
+-#else
+-
+ static void prepare_dma(struct s3c64xx_spi_dma_data *dma,
+                                       unsigned len, dma_addr_t buf)
+ {
+@@ -476,7 +380,6 @@ static void s3c64xx_spi_dma_stop(struct s3c64xx_spi_driver_data *sdd,
+ {
+       dmaengine_terminate_all(dma->ch);
+ }
+-#endif
+ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
+                               struct spi_device *spi,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0713-spi-spi-s3c64xx-Correct-functions-namespacing.patch b/patches.tizen/0713-spi-spi-s3c64xx-Correct-functions-namespacing.patch
new file mode 100644 (file)
index 0000000..8655b5a
--- /dev/null
@@ -0,0 +1,130 @@
+From f9da3899da07e12671f6b8a3b3b3f8aa90d1ca6e Mon Sep 17 00:00:00 2001
+From: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Date: Wed, 21 Aug 2013 14:28:01 +0200
+Subject: [PATCH 0713/1302] spi: spi-s3c64xx: Correct functions namespacing
+
+This path adds missing s3c64xx_ prefixes to functions in the driver.
+
+Signed-off-by: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/spi/spi-s3c64xx.c | 28 +++++++++++++++-------------
+ 1 file changed, 15 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
+index c1cf40d..0abaa0c 100644
+--- a/drivers/spi/spi-s3c64xx.c
++++ b/drivers/spi/spi-s3c64xx.c
+@@ -277,7 +277,7 @@ static void s3c64xx_spi_dmacb(void *data)
+       spin_unlock_irqrestore(&sdd->lock, flags);
+ }
+-static void prepare_dma(struct s3c64xx_spi_dma_data *dma,
++static void s3c64xx_prepare_dma(struct s3c64xx_spi_dma_data *dma,
+                                       unsigned len, dma_addr_t buf)
+ {
+       struct s3c64xx_spi_driver_data *sdd;
+@@ -381,7 +381,7 @@ static void s3c64xx_spi_dma_stop(struct s3c64xx_spi_driver_data *sdd,
+       dmaengine_terminate_all(dma->ch);
+ }
+-static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
++static void s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
+                               struct spi_device *spi,
+                               struct spi_transfer *xfer, int dma_mode)
+ {
+@@ -412,7 +412,8 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
+               chcfg |= S3C64XX_SPI_CH_TXCH_ON;
+               if (dma_mode) {
+                       modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
+-                      prepare_dma(&sdd->tx_dma, xfer->len, xfer->tx_dma);
++                      s3c64xx_prepare_dma(&sdd->tx_dma,
++                                      xfer->len, xfer->tx_dma);
+               } else {
+                       switch (sdd->cur_bpw) {
+                       case 32:
+@@ -444,7 +445,8 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
+                       writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff)
+                                       | S3C64XX_SPI_PACKET_CNT_EN,
+                                       regs + S3C64XX_SPI_PACKET_CNT);
+-                      prepare_dma(&sdd->rx_dma, xfer->len, xfer->rx_dma);
++                      s3c64xx_prepare_dma(&sdd->rx_dma,
++                                      xfer->len, xfer->rx_dma);
+               }
+       }
+@@ -452,7 +454,7 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
+       writel(chcfg, regs + S3C64XX_SPI_CH_CFG);
+ }
+-static inline void enable_cs(struct s3c64xx_spi_driver_data *sdd,
++static inline void s3c64xx_enable_cs(struct s3c64xx_spi_driver_data *sdd,
+                                               struct spi_device *spi)
+ {
+       struct s3c64xx_spi_csinfo *cs;
+@@ -471,7 +473,7 @@ static inline void enable_cs(struct s3c64xx_spi_driver_data *sdd,
+       gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 1 : 0);
+ }
+-static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
++static int s3c64xx_wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
+                               struct spi_transfer *xfer, int dma_mode)
+ {
+       void __iomem *regs = sdd->regs;
+@@ -546,7 +548,7 @@ static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
+       return 0;
+ }
+-static inline void disable_cs(struct s3c64xx_spi_driver_data *sdd,
++static inline void s3c64xx_disable_cs(struct s3c64xx_spi_driver_data *sdd,
+                                               struct spi_device *spi)
+ {
+       struct s3c64xx_spi_csinfo *cs = spi->controller_data;
+@@ -774,17 +776,17 @@ static int s3c64xx_spi_transfer_one_message(struct spi_master *master,
+               sdd->state &= ~RXBUSY;
+               sdd->state &= ~TXBUSY;
+-              enable_datapath(sdd, spi, xfer, use_dma);
++              s3c64xx_enable_datapath(sdd, spi, xfer, use_dma);
+               /* Slave Select */
+-              enable_cs(sdd, spi);
++              s3c64xx_enable_cs(sdd, spi);
+               /* Start the signals */
+               writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
+               spin_unlock_irqrestore(&sdd->lock, flags);
+-              status = wait_for_xfer(sdd, xfer, use_dma);
++              status = s3c64xx_wait_for_xfer(sdd, xfer, use_dma);
+               /* Quiese the signals */
+               writel(S3C64XX_SPI_SLAVE_SIG_INACT,
+@@ -827,7 +829,7 @@ static int s3c64xx_spi_transfer_one_message(struct spi_master *master,
+ out:
+       if (!cs_toggle || status)
+-              disable_cs(sdd, spi);
++              s3c64xx_disable_cs(sdd, spi);
+       else
+               sdd->tgl_spi = spi;
+@@ -974,12 +976,12 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
+       }
+       pm_runtime_put(&sdd->pdev->dev);
+-      disable_cs(sdd, spi);
++      s3c64xx_disable_cs(sdd, spi);
+       return 0;
+ setup_exit:
+       /* setup() returns with device de-selected */
+-      disable_cs(sdd, spi);
++      s3c64xx_disable_cs(sdd, spi);
+ err_msgq:
+       gpio_free(cs->line);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0714-spi-spi-s3c64xx-Refactor-dma-sections.patch b/patches.tizen/0714-spi-spi-s3c64xx-Refactor-dma-sections.patch
new file mode 100644 (file)
index 0000000..2bbf0db
--- /dev/null
@@ -0,0 +1,217 @@
+From e7fd10f582f579ff7867e0529ac6e6018c2b53f0 Mon Sep 17 00:00:00 2001
+From: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Date: Mon, 26 Aug 2013 14:11:08 +0200
+Subject: [PATCH 0714/1302] spi: spi-s3c64xx: Refactor dma sections
+
+This patch removes dma channel initialization and deinitialization for each
+transfer. Now dma channel is requested only for the first spi transfer
+and stored in driver data.
+
+This solution optimizes execution time of the send_message loop because
+driver doesn't request dma channel for each transfer anymore. It uses already
+requested dma channel from s3c64xx_spi_dma_data struct.
+
+Signed-off-by: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/spi/spi-s3c64xx.c | 137 +++++++++++++++++++++++++++++-----------------
+ 1 file changed, 87 insertions(+), 50 deletions(-)
+
+diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
+index 0abaa0c..f358c16 100644
+--- a/drivers/spi/spi-s3c64xx.c
++++ b/drivers/spi/spi-s3c64xx.c
+@@ -277,32 +277,87 @@ static void s3c64xx_spi_dmacb(void *data)
+       spin_unlock_irqrestore(&sdd->lock, flags);
+ }
+-static void s3c64xx_prepare_dma(struct s3c64xx_spi_dma_data *dma,
+-                                      unsigned len, dma_addr_t buf)
++static int s3c64xx_dma_init_param(struct s3c64xx_spi_driver_data *sdd,
++                                      bool dma_to_memory)
+ {
+-      struct s3c64xx_spi_driver_data *sdd;
++      struct dma_chan *dma_chan;
+       struct dma_slave_config config;
+-      struct scatterlist sg;
+-      struct dma_async_tx_descriptor *desc;
++      struct device *dev = &sdd->pdev->dev;
++      struct s3c64xx_spi_dma_data *dma_data = NULL;
++      dma_filter_fn filter = sdd->cntrlr_info->filter;
++      dma_cap_mask_t mask;
++      int ret;
+-      if (dma->direction == DMA_DEV_TO_MEM) {
+-              sdd = container_of((void *)dma,
+-                      struct s3c64xx_spi_driver_data, rx_dma);
+-              config.direction = dma->direction;
++      memset(&config, 0, sizeof(struct dma_slave_config));
++
++      dma_cap_zero(mask);
++      dma_cap_set(DMA_SLAVE, mask);
++
++      if (dma_to_memory) {
++              dma_data = &sdd->rx_dma;
++              config.direction = DMA_DEV_TO_MEM;
+               config.src_addr = sdd->sfr_start + S3C64XX_SPI_RX_DATA;
+               config.src_addr_width = sdd->cur_bpw / 8;
+               config.src_maxburst = 1;
+-              dmaengine_slave_config(dma->ch, &config);
+       } else {
+-              sdd = container_of((void *)dma,
+-                      struct s3c64xx_spi_driver_data, tx_dma);
+-              config.direction = dma->direction;
++              dma_data = &sdd->tx_dma;
++              config.direction = DMA_MEM_TO_DEV;
+               config.dst_addr = sdd->sfr_start + S3C64XX_SPI_TX_DATA;
+               config.dst_addr_width = sdd->cur_bpw / 8;
+               config.dst_maxburst = 1;
+-              dmaengine_slave_config(dma->ch, &config);
+       }
++      if (dma_data->ch)
++              return 0;
++
++      dma_chan = dma_request_slave_channel_compat(mask,
++                      filter, (void *)dma_data->dmach, dev,
++                      dma_to_memory ? "rx" : "tx");
++      if (!dma_chan) {
++              dev_err(dev, "Failed to get %d DMA channel\n", dma_data->dmach);
++              return -EBUSY;
++      }
++
++      ret = dmaengine_slave_config(dma_chan, &config);
++      if (ret)
++              goto release;
++
++      ret = pm_runtime_get_sync(&sdd->pdev->dev);
++      if (ret < 0) {
++              dev_err(dev, "Failed to enable device: %d\n", ret);
++              goto release;
++      }
++
++      dma_data->ch = dma_chan;
++
++      return 0;
++
++release:
++      dma_release_channel(dma_chan);
++
++      return ret;
++}
++
++static void s3c64xx_dma_deinit_param(struct s3c64xx_spi_driver_data *sdd,
++                                      bool dma_to_memory)
++{
++      struct dma_chan *dma_chan;
++
++      if (dma_to_memory)
++              dma_chan = sdd->rx_dma.ch;
++      else
++              dma_chan = sdd->tx_dma.ch;
++
++      dma_release_channel(dma_chan);
++      pm_runtime_put(&sdd->pdev->dev);
++}
++
++static void s3c64xx_prepare_dma(struct s3c64xx_spi_dma_data *dma,
++                                      unsigned len, dma_addr_t buf)
++{
++      struct scatterlist sg;
++      struct dma_async_tx_descriptor *desc;
++
+       sg_init_table(&sg, 1);
+       sg_dma_len(&sg) = len;
+       sg_set_page(&sg, pfn_to_page(PFN_DOWN(buf)),
+@@ -322,56 +377,26 @@ static void s3c64xx_prepare_dma(struct s3c64xx_spi_dma_data *dma,
+ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi)
+ {
+       struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi);
+-      dma_filter_fn filter = sdd->cntrlr_info->filter;
+       struct device *dev = &sdd->pdev->dev;
+-      dma_cap_mask_t mask;
+       int ret;
+-      dma_cap_zero(mask);
+-      dma_cap_set(DMA_SLAVE, mask);
+-
+-      /* Acquire DMA channels */
+-      sdd->rx_dma.ch = dma_request_slave_channel_compat(mask, filter,
+-                              (void*)sdd->rx_dma.dmach, dev, "rx");
+-      if (!sdd->rx_dma.ch) {
+-              dev_err(dev, "Failed to get RX DMA channel\n");
+-              ret = -EBUSY;
+-              goto out;
+-      }
+-
+-      sdd->tx_dma.ch = dma_request_slave_channel_compat(mask, filter,
+-                              (void*)sdd->tx_dma.dmach, dev, "tx");
+-      if (!sdd->tx_dma.ch) {
+-              dev_err(dev, "Failed to get TX DMA channel\n");
+-              ret = -EBUSY;
+-              goto out_rx;
+-      }
+-
+       ret = pm_runtime_get_sync(&sdd->pdev->dev);
+-      if (ret < 0) {
++      if (ret < 0)
+               dev_err(dev, "Failed to enable device: %d\n", ret);
+-              goto out_tx;
+-      }
+       return 0;
+-
+-out_tx:
+-      dma_release_channel(sdd->tx_dma.ch);
+-out_rx:
+-      dma_release_channel(sdd->rx_dma.ch);
+-out:
+-      return ret;
+ }
+ static int s3c64xx_spi_unprepare_transfer(struct spi_master *spi)
+ {
+       struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi);
++      struct device *dev = &sdd->pdev->dev;
++      int ret;
+-      /* Free DMA channels */
+-      dma_release_channel(sdd->rx_dma.ch);
+-      dma_release_channel(sdd->tx_dma.ch);
++      ret = pm_runtime_put(&sdd->pdev->dev);
++      if (ret < 0)
++              dev_err(dev, "Failed to disable device: %d\n", ret);
+-      pm_runtime_put(&sdd->pdev->dev);
+       return 0;
+ }
+@@ -728,6 +753,16 @@ static int s3c64xx_spi_transfer_one_message(struct spi_master *master,
+               s3c64xx_spi_config(sdd);
+       }
++      /*  Initialize DMA */
++      if (!sdd->rx_dma.ch || !sdd->tx_dma.ch) {
++              status = s3c64xx_dma_init_param(sdd, false);
++              if (status < 0)
++                      goto out;
++              status = s3c64xx_dma_init_param(sdd, true);
++              if (status < 0)
++                      goto out;
++      }
++
+       /* Map all the transfers if needed */
+       if (s3c64xx_spi_map_mssg(sdd, msg)) {
+               dev_err(&spi->dev,
+@@ -1316,6 +1351,8 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)
+       struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
+       pm_runtime_disable(&pdev->dev);
++      s3c64xx_dma_deinit_param(sdd, false);
++      s3c64xx_dma_deinit_param(sdd, true);
+       spi_unregister_master(master);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0715-spi-spi-s3c64xx-Add-coherent-buffers-for-dma-transfe.patch b/patches.tizen/0715-spi-spi-s3c64xx-Add-coherent-buffers-for-dma-transfe.patch
new file mode 100644 (file)
index 0000000..0ec6c57
--- /dev/null
@@ -0,0 +1,230 @@
+From 307d4697ea7f0eda0fa02508fd8d0b3a4f219216 Mon Sep 17 00:00:00 2001
+From: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Date: Mon, 26 Aug 2013 14:20:44 +0200
+Subject: [PATCH 0715/1302] spi: spi-s3c64xx: Add coherent buffers for dma
+ transfers
+
+The spi-s3c64xx currently doesn't support transfers from non-contiguous
+client buffers.
+
+This patch adds two coherent buffers which allow transfers from
+non-contiguous client buffers without extra coherent memory allocation
+in the client driver.
+
+Buffer size is hardcoded to 16kB for Tx/Rx. Client drivers shouldn't
+exceed that value.
+
+Signed-off-by: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/spi/spi-s3c64xx.c | 81 +++++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 65 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
+index f358c16..6219907 100644
+--- a/drivers/spi/spi-s3c64xx.c
++++ b/drivers/spi/spi-s3c64xx.c
+@@ -112,6 +112,7 @@
+ #define S3C64XX_SPI_SWAP_TX_EN                        (1<<0)
+ #define S3C64XX_SPI_FBCLK_MSK         (3<<0)
++#define S3C64XX_SPI_DMA_BUF_SIZE      (16 * 1024)
+ #define FIFO_LVL_MASK(i) ((i)->port_conf->fifo_lvl_mask[i->port_id])
+ #define S3C64XX_SPI_ST_TX_DONE(v, i) (((v) & \
+@@ -131,6 +132,8 @@
+ #define TXBUSY    (1<<3)
+ struct s3c64xx_spi_dma_data {
++      u32 *vbuf;
++      dma_addr_t dma_phys;
+       struct dma_chan *ch;
+       enum dma_transfer_direction direction;
+       unsigned int dmach;
+@@ -176,6 +179,7 @@ struct s3c64xx_spi_port_config {
+  * @xfer_completion: To indicate completion of xfer task.
+  * @cur_mode: Stores the active configuration of the controller.
+  * @cur_bpw: Stores the active bits per word settings.
++ * @dma_buf_size: Stores buffer size for Rx/Tx.
+  * @cur_speed: Stores the active xfer clock speed.
+  */
+ struct s3c64xx_spi_driver_data {
+@@ -193,6 +197,7 @@ struct s3c64xx_spi_driver_data {
+       unsigned                        state;
+       unsigned                        cur_mode, cur_bpw;
+       unsigned                        cur_speed;
++      unsigned                        dma_buf_size;
+       struct s3c64xx_spi_dma_data     rx_dma;
+       struct s3c64xx_spi_dma_data     tx_dma;
+@@ -286,6 +291,8 @@ static int s3c64xx_dma_init_param(struct s3c64xx_spi_driver_data *sdd,
+       struct s3c64xx_spi_dma_data *dma_data = NULL;
+       dma_filter_fn filter = sdd->cntrlr_info->filter;
+       dma_cap_mask_t mask;
++      dma_addr_t dma_phys;
++      u32 *dma_vbuf;
+       int ret;
+       memset(&config, 0, sizeof(struct dma_slave_config));
+@@ -307,7 +314,7 @@ static int s3c64xx_dma_init_param(struct s3c64xx_spi_driver_data *sdd,
+               config.dst_maxburst = 1;
+       }
+-      if (dma_data->ch)
++      if (dma_data->ch && dma_data->vbuf)
+               return 0;
+       dma_chan = dma_request_slave_channel_compat(mask,
+@@ -318,6 +325,13 @@ static int s3c64xx_dma_init_param(struct s3c64xx_spi_driver_data *sdd,
+               return -EBUSY;
+       }
++      dma_vbuf = dma_alloc_coherent(dev, sdd->dma_buf_size,
++                      &dma_phys, GFP_KERNEL);
++      if (!dma_vbuf) {
++              dev_err(dev, "Not able to allocate the dma buffer\n");
++              return -ENOMEM;
++      }
++
+       ret = dmaengine_slave_config(dma_chan, &config);
+       if (ret)
+               goto release;
+@@ -329,26 +343,31 @@ static int s3c64xx_dma_init_param(struct s3c64xx_spi_driver_data *sdd,
+       }
+       dma_data->ch = dma_chan;
++      dma_data->vbuf = dma_vbuf;
++      dma_data->dma_phys = dma_phys;
+       return 0;
+ release:
+       dma_release_channel(dma_chan);
+-
++      dma_free_coherent(dev, sdd->dma_buf_size, dma_vbuf, dma_phys);
+       return ret;
+ }
+ static void s3c64xx_dma_deinit_param(struct s3c64xx_spi_driver_data *sdd,
+                                       bool dma_to_memory)
+ {
+-      struct dma_chan *dma_chan;
++      struct s3c64xx_spi_dma_data *dma_data;
++      struct device *dev = &sdd->pdev->dev;
+       if (dma_to_memory)
+-              dma_chan = sdd->rx_dma.ch;
++              dma_data = &sdd->rx_dma;
+       else
+-              dma_chan = sdd->tx_dma.ch;
++              dma_data = &sdd->tx_dma;
+-      dma_release_channel(dma_chan);
++      dma_free_coherent(dev, sdd->dma_buf_size, dma_data->vbuf,
++                      dma_data->dma_phys);
++      dma_release_channel(dma_data->ch);
+       pm_runtime_put(&sdd->pdev->dev);
+ }
+@@ -406,6 +425,35 @@ static void s3c64xx_spi_dma_stop(struct s3c64xx_spi_driver_data *sdd,
+       dmaengine_terminate_all(dma->ch);
+ }
++
++static void s3c64xx_copy_txbuf_to_spi(struct s3c64xx_spi_driver_data *sdd,
++                                  struct spi_transfer *xfer)
++{
++      struct device *dev = &sdd->pdev->dev;
++
++      dma_sync_single_for_cpu(dev, sdd->tx_dma.dma_phys,
++                      sdd->dma_buf_size, DMA_TO_DEVICE);
++
++      memcpy(sdd->tx_dma.vbuf, xfer->tx_buf, xfer->len);
++
++      dma_sync_single_for_device(dev, sdd->tx_dma.dma_phys,
++                      sdd->dma_buf_size, DMA_TO_DEVICE);
++}
++
++static void s3c64xx_copy_spi_to_rxbuf(struct s3c64xx_spi_driver_data *sdd,
++                                  struct spi_transfer *xfer)
++{
++      struct device *dev = &sdd->pdev->dev;
++
++      dma_sync_single_for_cpu(dev, sdd->rx_dma.dma_phys,
++                      sdd->dma_buf_size, DMA_FROM_DEVICE);
++
++      memcpy(xfer->rx_buf, sdd->rx_dma.vbuf, xfer->len);
++
++      dma_sync_single_for_device(dev, sdd->rx_dma.dma_phys,
++                      sdd->dma_buf_size, DMA_FROM_DEVICE);
++}
++
+ static void s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
+                               struct spi_device *spi,
+                               struct spi_transfer *xfer, int dma_mode)
+@@ -437,6 +485,7 @@ static void s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
+               chcfg |= S3C64XX_SPI_CH_TXCH_ON;
+               if (dma_mode) {
+                       modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
++                      s3c64xx_copy_txbuf_to_spi(sdd, xfer);
+                       s3c64xx_prepare_dma(&sdd->tx_dma,
+                                       xfer->len, xfer->tx_dma);
+               } else {
+@@ -470,6 +519,7 @@ static void s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
+                       writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff)
+                                       | S3C64XX_SPI_PACKET_CNT_EN,
+                                       regs + S3C64XX_SPI_PACKET_CNT);
++                      s3c64xx_copy_spi_to_rxbuf(sdd, xfer);
+                       s3c64xx_prepare_dma(&sdd->rx_dma,
+                                       xfer->len, xfer->rx_dma);
+               }
+@@ -763,14 +813,6 @@ static int s3c64xx_spi_transfer_one_message(struct spi_master *master,
+                       goto out;
+       }
+-      /* Map all the transfers if needed */
+-      if (s3c64xx_spi_map_mssg(sdd, msg)) {
+-              dev_err(&spi->dev,
+-                      "Xfer: Unable to map message buffers!\n");
+-              status = -ENOMEM;
+-              goto out;
+-      }
+-
+       /* Configure feedback delay */
+       writel(cs->fb_delay & 0x3, sdd->regs + S3C64XX_SPI_FB_CLK);
+@@ -785,6 +827,14 @@ static int s3c64xx_spi_transfer_one_message(struct spi_master *master,
+               bpw = xfer->bits_per_word;
+               speed = xfer->speed_hz ? : spi->max_speed_hz;
++              if (xfer->len > sdd->dma_buf_size) {
++                      dev_err(&spi->dev,
++                              "Message length exceeds dma buffer size %d>%d\n",
++                              xfer->len, sdd->dma_buf_size);
++                      status = -EIO;
++                      goto out;
++              }
++
+               if (xfer->len % (bpw / 8)) {
+                       dev_err(&spi->dev,
+                               "Xfer length(%u) not a multiple of word size(%u)\n",
+@@ -868,8 +918,6 @@ out:
+       else
+               sdd->tgl_spi = spi;
+-      s3c64xx_spi_unmap_mssg(sdd, msg);
+-
+       msg->status = status;
+       spi_finalize_current_message(master);
+@@ -1244,6 +1292,7 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
+       sdd->tx_dma.direction = DMA_MEM_TO_DEV;
+       sdd->rx_dma.direction = DMA_DEV_TO_MEM;
++      sdd->dma_buf_size = S3C64XX_SPI_DMA_BUF_SIZE;
+       master->dev.of_node = pdev->dev.of_node;
+       master->bus_num = sdd->port_id;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0716-spi-spi-s3c64xx-s3c64xx_prepare_dma-clean-up.patch b/patches.tizen/0716-spi-spi-s3c64xx-s3c64xx_prepare_dma-clean-up.patch
new file mode 100644 (file)
index 0000000..7e06a6f
--- /dev/null
@@ -0,0 +1,41 @@
+From 0e483e6fcd9675124ddcb7e0ad3aa7fdbf2b7938 Mon Sep 17 00:00:00 2001
+From: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Date: Mon, 2 Sep 2013 18:23:29 +0200
+Subject: [PATCH 0716/1302] spi: spi-s3c64xx: s3c64xx_prepare_dma() clean up
+
+One element scatterlist initizalization is replaced by the hardcoded
+initization in the dmaengine_prep_slave_single() function.
+
+Signed-off-by: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/spi/spi-s3c64xx.c | 11 ++---------
+ 1 file changed, 2 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
+index 6219907..5eacae5 100644
+--- a/drivers/spi/spi-s3c64xx.c
++++ b/drivers/spi/spi-s3c64xx.c
+@@ -374,17 +374,10 @@ static void s3c64xx_dma_deinit_param(struct s3c64xx_spi_driver_data *sdd,
+ static void s3c64xx_prepare_dma(struct s3c64xx_spi_dma_data *dma,
+                                       unsigned len, dma_addr_t buf)
+ {
+-      struct scatterlist sg;
+       struct dma_async_tx_descriptor *desc;
+-      sg_init_table(&sg, 1);
+-      sg_dma_len(&sg) = len;
+-      sg_set_page(&sg, pfn_to_page(PFN_DOWN(buf)),
+-                  len, offset_in_page(buf));
+-      sg_dma_address(&sg) = buf;
+-
+-      desc = dmaengine_prep_slave_sg(dma->ch,
+-              &sg, 1, dma->direction, DMA_PREP_INTERRUPT);
++      desc = dmaengine_prep_slave_single(dma->ch,
++              dma->dma_phys, len, dma->direction, DMA_PREP_INTERRUPT);
+       desc->callback = s3c64xx_spi_dmacb;
+       desc->callback_param = dma;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0717-spi-spi-s3c64xx-Remove-unused-code.patch b/patches.tizen/0717-spi-spi-s3c64xx-Remove-unused-code.patch
new file mode 100644 (file)
index 0000000..ed4f885
--- /dev/null
@@ -0,0 +1,115 @@
+From 30ebc1122adb1d4f25ab262e05dd7a76fb100271 Mon Sep 17 00:00:00 2001
+From: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Date: Fri, 30 Aug 2013 13:50:30 +0200
+Subject: [PATCH 0717/1302] spi: spi-s3c64xx: Remove unused code
+
+So far physical address (used to set dma transfer) was obtained
+from mapping virtual address of the client buffer address passed
+in SPI message. Deprecated code uses dma_map_single() and
+dma_unmap_single().
+
+Now mapping of virtual address has been replaced by data
+transfer from client buffer to contiguous regions allocated by
+dma_alloc_coherent(). Physical address of dma buffers is used
+to set dma transfer.
+
+This makes functions: s3c64xx_spi_map_mssg(), s3c64xx_spi_unmap()
+redundant hence they are removed.
+
+Signed-off-by: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/spi/spi-s3c64xx.c | 77 -----------------------------------------------
+ 1 file changed, 77 deletions(-)
+
+diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
+index 5eacae5..4a01dda 100644
+--- a/drivers/spi/spi-s3c64xx.c
++++ b/drivers/spi/spi-s3c64xx.c
+@@ -698,83 +698,6 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
+       }
+ }
+-#define XFER_DMAADDR_INVALID DMA_BIT_MASK(32)
+-
+-static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd,
+-                                              struct spi_message *msg)
+-{
+-      struct device *dev = &sdd->pdev->dev;
+-      struct spi_transfer *xfer;
+-
+-      if (msg->is_dma_mapped)
+-              return 0;
+-
+-      /* First mark all xfer unmapped */
+-      list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+-              xfer->rx_dma = XFER_DMAADDR_INVALID;
+-              xfer->tx_dma = XFER_DMAADDR_INVALID;
+-      }
+-
+-      /* Map until end or first fail */
+-      list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+-
+-              if (xfer->len <= ((FIFO_LVL_MASK(sdd) >> 1) + 1))
+-                      continue;
+-
+-              if (xfer->tx_buf != NULL) {
+-                      xfer->tx_dma = dma_map_single(dev,
+-                                      (void *)xfer->tx_buf, xfer->len,
+-                                      DMA_TO_DEVICE);
+-                      if (dma_mapping_error(dev, xfer->tx_dma)) {
+-                              dev_err(dev, "dma_map_single Tx failed\n");
+-                              xfer->tx_dma = XFER_DMAADDR_INVALID;
+-                              return -ENOMEM;
+-                      }
+-              }
+-
+-              if (xfer->rx_buf != NULL) {
+-                      xfer->rx_dma = dma_map_single(dev, xfer->rx_buf,
+-                                              xfer->len, DMA_FROM_DEVICE);
+-                      if (dma_mapping_error(dev, xfer->rx_dma)) {
+-                              dev_err(dev, "dma_map_single Rx failed\n");
+-                              dma_unmap_single(dev, xfer->tx_dma,
+-                                              xfer->len, DMA_TO_DEVICE);
+-                              xfer->tx_dma = XFER_DMAADDR_INVALID;
+-                              xfer->rx_dma = XFER_DMAADDR_INVALID;
+-                              return -ENOMEM;
+-                      }
+-              }
+-      }
+-
+-      return 0;
+-}
+-
+-static void s3c64xx_spi_unmap_mssg(struct s3c64xx_spi_driver_data *sdd,
+-                                              struct spi_message *msg)
+-{
+-      struct device *dev = &sdd->pdev->dev;
+-      struct spi_transfer *xfer;
+-
+-      if (msg->is_dma_mapped)
+-              return;
+-
+-      list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+-
+-              if (xfer->len <= ((FIFO_LVL_MASK(sdd) >> 1) + 1))
+-                      continue;
+-
+-              if (xfer->rx_buf != NULL
+-                              && xfer->rx_dma != XFER_DMAADDR_INVALID)
+-                      dma_unmap_single(dev, xfer->rx_dma,
+-                                              xfer->len, DMA_FROM_DEVICE);
+-
+-              if (xfer->tx_buf != NULL
+-                              && xfer->tx_dma != XFER_DMAADDR_INVALID)
+-                      dma_unmap_single(dev, xfer->tx_dma,
+-                                              xfer->len, DMA_TO_DEVICE);
+-      }
+-}
+-
+ static int s3c64xx_spi_transfer_one_message(struct spi_master *master,
+                                           struct spi_message *msg)
+ {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0718-media-s5c73m3-Change-SPI-write-packet-size.patch b/patches.tizen/0718-media-s5c73m3-Change-SPI-write-packet-size.patch
new file mode 100644 (file)
index 0000000..3afc212
--- /dev/null
@@ -0,0 +1,39 @@
+From 726a78d5afd4b950950540ed04de45d4c4381478 Mon Sep 17 00:00:00 2001
+From: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Date: Mon, 26 Aug 2013 13:49:50 +0200
+Subject: [PATCH 0718/1302] [media] s5c73m3: Change SPI write packet size
+
+This path changes s5c73m3_spi_write() packet size from 64 B
+to 16 kB. Packet length bigger than the TX FIFO buffer enables
+DMA mode for transfer.
+
+Signed-off-by: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/s5c73m3/s5c73m3-core.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+index b379111..6a75a68a 100644
+--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
++++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+@@ -47,6 +47,7 @@ static int update_fw;
+ module_param(update_fw, int, 0644);
+ #define S5C73M3_EMBEDDED_DATA_MAXLEN  SZ_4K
++#define S5C73M3_SPI_TX_SIZE           (16 * SZ_1K)
+ static const char * const s5c73m3_supply_names[S5C73M3_MAX_SUPPLIES] = {
+       "vdd-int",      /* Digital Core supply (1.2V), CAM_ISP_CORE_1.2V */
+@@ -360,7 +361,7 @@ static int s5c73m3_load_fw(struct v4l2_subdev *sd)
+       v4l2_info(sd, "Loading firmware (%s, %zu B)\n", fw_name, fw->size);
+-      ret = s5c73m3_spi_write(state, fw->data, fw->size, 64);
++      ret = s5c73m3_spi_write(state, fw->data, fw->size, S5C73M3_SPI_TX_SIZE);
+       if (ret >= 0)
+               state->isp_ready = 1;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0719-media-s5c73m3-s5c73m3_spi_write-clean-up.patch b/patches.tizen/0719-media-s5c73m3-s5c73m3_spi_write-clean-up.patch
new file mode 100644 (file)
index 0000000..47fed15
--- /dev/null
@@ -0,0 +1,49 @@
+From c56c752cc6de6bb066658c4c1e841942c6b656de Mon Sep 17 00:00:00 2001
+From: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Date: Mon, 26 Aug 2013 13:56:17 +0200
+Subject: [PATCH 0719/1302] [media] s5c73m3: s5c73m3_spi_write() clean up
+
+This path removes unnecessary transfer at the end of s5c73m3_spi_write()
+function.
+
+Signed-off-by: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/s5c73m3/s5c73m3-spi.c | 11 +++--------
+ 1 file changed, 3 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-spi.c b/drivers/media/i2c/s5c73m3/s5c73m3-spi.c
+index cd1074f..323b47b 100644
+--- a/drivers/media/i2c/s5c73m3/s5c73m3-spi.c
++++ b/drivers/media/i2c/s5c73m3/s5c73m3-spi.c
+@@ -73,10 +73,8 @@ int s5c73m3_spi_write(struct s5c73m3 *state, const void *addr,
+       u32 count = len / tx_size;
+       u32 extra = len % tx_size;
+       unsigned int i, j = 0;
+-      u8 padding[32];
+-      int r = 0;
+-      memset(padding, 0, sizeof(padding));
++      int r = 0;
+       for (i = 0; i < count ; i++) {
+               r = spi_xmit(spi_dev, (void *)addr + j, tx_size, SPI_DIR_TX);
+@@ -85,13 +83,10 @@ int s5c73m3_spi_write(struct s5c73m3 *state, const void *addr,
+               j += tx_size;
+       }
+-      if (extra > 0) {
++      if (extra > 0)
+               r = spi_xmit(spi_dev, (void *)addr + j, extra, SPI_DIR_TX);
+-              if (r < 0)
+-                      return r;
+-      }
+-      return spi_xmit(spi_dev, padding, sizeof(padding), SPI_DIR_TX);
++      return r;
+ }
+ int s5c73m3_spi_read(struct s5c73m3 *state, void *addr,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0720-V4L-s5k6a3-Add-DT-binding-documentation.patch b/patches.tizen/0720-V4L-s5k6a3-Add-DT-binding-documentation.patch
new file mode 100644 (file)
index 0000000..2b98330
--- /dev/null
@@ -0,0 +1,85 @@
+From da14e052e0621407ad534991d1a6a3f349e5cadb Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Tue, 27 Aug 2013 11:15:41 +0200
+Subject: [PATCH 0720/1302] V4L: s5k6a3: Add DT binding documentation
+
+This patch adds binding documentation for the Samsung S5K6A3(YX)
+raw image sensor.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+---
+
+The binding of this sensors shows some issue in the generic video-interfaces
+binding. Namely The video bus type (serial MIPI CSI-2, parallel ITU-R BT.656,
+etc.) is being determined by the binding parser (v4l2-of.c) depending on what
+properties are found in an enddpoint node.
+
+Please have a look at the data-lanes property description. The sensor supports
+MIPI CSI-2 and SMIA CCP2 interfaces which both use one data lane. One data lane
+is everything this sensors supports. During our discussions on the generic
+bidings in the past I proposed to introduce a property in the endpoint node
+that would indicate what bus type (standard/protocol) is used, e.g. MIPI CSI-2,
+ITU-R BT.656, SMIA CCP2, etc. It was argued though that we can well determine
+bus type based on properties found in the endpoint node.
+
+So now in case of this sensor I'm not sure how it can be differentiated
+whether MIPI CSI-2 or CCP2 bus is used. There is no CCP2 specific generic
+properties yet. Anyway I'm not really happy there is no property like bus_type
+that would clearly indicate what data bus type is used. Then would would for
+instance not specify "data-lanes" in endpoint node just to differentiate
+between MIPI CSI-2 and the parallel busses.
+
+The main issue for this particular binding is that even with data-lanes = <1>;
+it is still impossible to figure out whether MIPI CSI-2 or SMIA CCP2 data bus
+is used.
+
+So how about introducing, e.g. a string type "bus_type" common property ?
+I'm considering starting a separate thread for discussing this.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/media/samsung-s5k6a3.txt   | 31 ++++++++++++++++++++++
+ 1 file changed, 31 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/media/samsung-s5k6a3.txt
+
+diff --git a/Documentation/devicetree/bindings/media/samsung-s5k6a3.txt b/Documentation/devicetree/bindings/media/samsung-s5k6a3.txt
+new file mode 100644
+index 0000000..a51fbe8
+--- /dev/null
++++ b/Documentation/devicetree/bindings/media/samsung-s5k6a3.txt
+@@ -0,0 +1,31 @@
++Samsung S5K6A3(YX) raw image sensor
++---------------------------------
++
++S5K6A3YX is a raw image sensor with MIPI CSI-2 and CCP2 image data interfaces
++and CCI (I2C compatible) control bus.
++
++Required properties:
++
++- compatible  : "samsung,s5k6a3yx";
++- reg         : I2C slave address of the sensor;
++- svdda-supply        : core voltage supply;
++- svddio-supply       : I/O voltage supply;
++- gpios               : specifier of a GPIO connected to the RESET pin;
++- clocks      : should contain the sensor's EXTCLK clock specifier, from
++                the common clock bindings.
++- clock-names : should contain "extclk" entry;
++
++Optional properties:
++
++- clock-frequency : the frequency at which the "extclk" clock should be
++                  configured to operate, in Hz; if this property is not
++                  specified default 24 MHz value will be used.
++
++The common video interfaces bindings (see video-interfaces.txt) should be
++used to specify link to the image data receiver. The S5K6A3(YX) device
++node should contain one 'port' child node with an 'endpoint' subnode.
++
++Following properties are valid for the endpoint node:
++
++- data-lanes : (optional) specifies MIPI CSI-2 data lanes as covered in
++  video-interfaces.txt.  The sensor supports only one data lane.
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0721-V4L-Add-driver-for-s5k6a3-image-sensor.patch b/patches.tizen/0721-V4L-Add-driver-for-s5k6a3-image-sensor.patch
new file mode 100644 (file)
index 0000000..496904b
--- /dev/null
@@ -0,0 +1,394 @@
+From 676f338cf8d4ef7500f26440e85f94738f333714 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 9 Aug 2013 20:56:00 +0200
+Subject: [PATCH 0721/1302] V4L: Add driver for s5k6a3 image sensor
+
+This patch adds subdev driver for Samsung S5K6A3 raw image sensor.
+As it is intended at the moment to be used only with the Exynos
+FIMC-IS (camera ISP) subsystem it is a pretty minimal subdev driver.
+It doesn't do any I2C communication since the sensor is controlled
+by the ISP and its own firmware.
+This driver can be updated in future, should anyone need it to be
+a regular subdev driver where the main CPU communicates with the
+sensor directly.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+---
+Changes since v1:
+ - added missing pm_runtime_disable(),
+ - removed subdev name overriding,
+ - s/S5K6A3_DEF_PIX/S5K6A3_DEFAULT_
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/Kconfig  |   8 ++
+ drivers/media/i2c/Makefile |   1 +
+ drivers/media/i2c/s5k6a3.c | 324 +++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 333 insertions(+)
+ create mode 100644 drivers/media/i2c/s5k6a3.c
+
+diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
+index 9c6279a..24407cc 100644
+--- a/drivers/media/i2c/Kconfig
++++ b/drivers/media/i2c/Kconfig
+@@ -546,6 +546,14 @@ config VIDEO_S5K6AA
+         This is a V4L2 sensor-level driver for Samsung S5K6AA(FX) 1.3M
+         camera sensor with an embedded SoC image signal processor.
++config VIDEO_S5K6A3
++      tristate "Samsung S5K6A3 sensor support"
++      depends on MEDIA_CAMERA_SUPPORT
++      depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF
++      ---help---
++        This is a V4L2 sensor-level driver for Samsung S5K6A3 raw
++        camera sensor.
++
+ config VIDEO_S5K4ECGX
+         tristate "Samsung S5K4ECGX sensor support"
+         depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
+index 6aeef24..ef4b169 100644
+--- a/drivers/media/i2c/Makefile
++++ b/drivers/media/i2c/Makefile
+@@ -63,6 +63,7 @@ obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o
+ obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o
+ obj-$(CONFIG_VIDEO_NOON010PC30)       += noon010pc30.o
+ obj-$(CONFIG_VIDEO_S5K6AA)    += s5k6aa.o
++obj-$(CONFIG_VIDEO_S5K6A3)    += s5k6a3.o
+ obj-$(CONFIG_VIDEO_S5K4ECGX)  += s5k4ecgx.o
+ obj-$(CONFIG_VIDEO_S5K5BAF)   += s5k5baf.o
+ obj-$(CONFIG_VIDEO_S5C73M3)   += s5c73m3/
+diff --git a/drivers/media/i2c/s5k6a3.c b/drivers/media/i2c/s5k6a3.c
+new file mode 100644
+index 0000000..ba86e24
+--- /dev/null
++++ b/drivers/media/i2c/s5k6a3.c
+@@ -0,0 +1,324 @@
++/*
++ * Samsung S5K6A3 image sensor driver
++ *
++ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
++ * Author: Sylwester Nawrocki <s.nawrocki@samsung.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/clk.h>
++#include <linux/delay.h>
++#include <linux/device.h>
++#include <linux/errno.h>
++#include <linux/gpio.h>
++#include <linux/i2c.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of_gpio.h>
++#include <linux/pm_runtime.h>
++#include <linux/regulator/consumer.h>
++#include <linux/slab.h>
++#include <linux/videodev2.h>
++#include <media/v4l2-async.h>
++#include <media/v4l2-subdev.h>
++
++#define S5K6A3_SENSOR_MAX_WIDTH               1392
++#define S5K6A3_SENSOR_MAX_HEIGHT      1392
++#define S5K6A3_SENSOR_MIN_WIDTH               32
++#define S5K6A3_SENSOR_MIN_HEIGHT      32
++
++#define S5K6A3_DEFAULT_WIDTH          1296
++#define S5K6A3_DEFAULT_HEIGHT         732
++
++#define S5K6A3_DRV_NAME                       "S5K6A3"
++#define S5K6A3_DEFAULT_CLK_FREQ               24000000U
++
++#define S5K6A3_NUM_SUPPLIES           2
++
++/**
++ * struct s5k6a3 - fimc-is sensor data structure
++ * @dev: pointer to this I2C client device structure
++ * @subdev: the image sensor's v4l2 subdev
++ * @pad: subdev media source pad
++ * @supplies: image sensor's voltage regulator supplies
++ * @gpio_reset: GPIO connected to the sensor's reset pin
++ * @lock: mutex protecting the structure's members below
++ * @format: media bus format at the sensor's source pad
++ */
++struct s5k6a3 {
++      struct device *dev;
++      struct v4l2_subdev subdev;
++      struct media_pad pad;
++      struct regulator_bulk_data supplies[S5K6A3_NUM_SUPPLIES];
++      int gpio_reset;
++      struct mutex lock;
++      struct v4l2_mbus_framefmt format;
++      u32 clock_frequency;
++};
++
++static const char * const s5k6a3_supply_names[] = {
++      "svdda",
++      "svddio"
++};
++
++static inline struct s5k6a3 *sd_to_s5k6a3(struct v4l2_subdev *sd)
++{
++      return container_of(sd, struct s5k6a3, subdev);
++}
++
++static const struct v4l2_mbus_framefmt s5k6a3_formats[] = {
++      {
++              .code = V4L2_MBUS_FMT_SGRBG10_1X10,
++              .colorspace = V4L2_COLORSPACE_SRGB,
++              .field = V4L2_FIELD_NONE,
++      }
++};
++
++static const struct v4l2_mbus_framefmt *find_sensor_format(
++      struct v4l2_mbus_framefmt *mf)
++{
++      int i;
++
++      for (i = 0; i < ARRAY_SIZE(s5k6a3_formats); i++)
++              if (mf->code == s5k6a3_formats[i].code)
++                      return &s5k6a3_formats[i];
++
++      return &s5k6a3_formats[0];
++}
++
++static int s5k6a3_enum_mbus_code(struct v4l2_subdev *sd,
++                                struct v4l2_subdev_fh *fh,
++                                struct v4l2_subdev_mbus_code_enum *code)
++{
++      if (code->index >= ARRAY_SIZE(s5k6a3_formats))
++              return -EINVAL;
++
++      code->code = s5k6a3_formats[code->index].code;
++      return 0;
++}
++
++static void s5k6a3_try_format(struct v4l2_mbus_framefmt *mf)
++{
++      const struct v4l2_mbus_framefmt *fmt;
++
++      fmt = find_sensor_format(mf);
++      mf->code = fmt->code;
++      v4l_bound_align_image(&mf->width, S5K6A3_SENSOR_MIN_WIDTH,
++                            S5K6A3_SENSOR_MAX_WIDTH, 0,
++                            &mf->height, S5K6A3_SENSOR_MIN_HEIGHT,
++                            S5K6A3_SENSOR_MAX_HEIGHT, 0, 0);
++}
++
++static struct v4l2_mbus_framefmt *__s5k6a3_get_format(
++              struct s5k6a3 *sensor, struct v4l2_subdev_fh *fh,
++              u32 pad, enum v4l2_subdev_format_whence which)
++{
++      if (which == V4L2_SUBDEV_FORMAT_TRY)
++              return fh ? v4l2_subdev_get_try_format(fh, pad) : NULL;
++
++      return &sensor->format;
++}
++
++static int s5k6a3_set_fmt(struct v4l2_subdev *sd,
++                                struct v4l2_subdev_fh *fh,
++                                struct v4l2_subdev_format *fmt)
++{
++      struct s5k6a3 *sensor = sd_to_s5k6a3(sd);
++      struct v4l2_mbus_framefmt *mf;
++
++      s5k6a3_try_format(&fmt->format);
++
++      mf = __s5k6a3_get_format(sensor, fh, fmt->pad, fmt->which);
++      if (mf) {
++              mutex_lock(&sensor->lock);
++              if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
++                      *mf = fmt->format;
++              mutex_unlock(&sensor->lock);
++      }
++      return 0;
++}
++
++static int s5k6a3_get_fmt(struct v4l2_subdev *sd,
++                                struct v4l2_subdev_fh *fh,
++                                struct v4l2_subdev_format *fmt)
++{
++      struct s5k6a3 *sensor = sd_to_s5k6a3(sd);
++      struct v4l2_mbus_framefmt *mf;
++
++      mf = __s5k6a3_get_format(sensor, fh, fmt->pad, fmt->which);
++
++      mutex_lock(&sensor->lock);
++      fmt->format = *mf;
++      mutex_unlock(&sensor->lock);
++      return 0;
++}
++
++static struct v4l2_subdev_pad_ops s5k6a3_pad_ops = {
++      .enum_mbus_code = s5k6a3_enum_mbus_code,
++      .get_fmt        = s5k6a3_get_fmt,
++      .set_fmt        = s5k6a3_set_fmt,
++};
++
++static int s5k6a3_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
++{
++      struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(fh, 0);
++
++      *format         = s5k6a3_formats[0];
++      format->width   = S5K6A3_DEFAULT_WIDTH;
++      format->height  = S5K6A3_DEFAULT_HEIGHT;
++
++      return 0;
++}
++
++static const struct v4l2_subdev_internal_ops s5k6a3_sd_internal_ops = {
++      .open = s5k6a3_open,
++};
++
++static int s5k6a3_s_power(struct v4l2_subdev *sd, int on)
++{
++      struct s5k6a3 *sensor = sd_to_s5k6a3(sd);
++      int gpio = sensor->gpio_reset;
++      int ret;
++
++      if (on) {
++              ret = pm_runtime_get(sensor->dev);
++              if (ret < 0)
++                      return ret;
++
++              ret = regulator_bulk_enable(S5K6A3_NUM_SUPPLIES,
++                                          sensor->supplies);
++              if (ret < 0) {
++                      pm_runtime_put(sensor->dev);
++                      return ret;
++              }
++
++              if (gpio_is_valid(gpio)) {
++                      gpio_set_value(gpio, 1);
++                      usleep_range(600, 800);
++                      gpio_set_value(gpio, 0);
++                      usleep_range(10000, 11000);
++                      gpio_set_value(gpio, 1);
++              }
++
++              /* Delay needed for the sensor initialization */
++              msleep(20);
++      } else {
++              if (gpio_is_valid(gpio))
++                      gpio_set_value(gpio, 0);
++
++              ret = regulator_bulk_disable(S5K6A3_NUM_SUPPLIES,
++                                           sensor->supplies);
++              if (!ret)
++                      pm_runtime_put(sensor->dev);
++      }
++      return ret;
++}
++
++static struct v4l2_subdev_core_ops s5k6a3_core_ops = {
++      .s_power = s5k6a3_s_power,
++};
++
++static struct v4l2_subdev_ops s5k6a3_subdev_ops = {
++      .core = &s5k6a3_core_ops,
++      .pad = &s5k6a3_pad_ops,
++};
++
++static int s5k6a3_probe(struct i2c_client *client,
++                              const struct i2c_device_id *id)
++{
++      struct device *dev = &client->dev;
++      struct s5k6a3 *sensor;
++      struct v4l2_subdev *sd;
++      int gpio, i, ret;
++
++      sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
++      if (!sensor)
++              return -ENOMEM;
++
++      mutex_init(&sensor->lock);
++      sensor->gpio_reset = -EINVAL;
++      sensor->dev = dev;
++
++      gpio = of_get_gpio_flags(dev->of_node, 0, NULL);
++      if (gpio_is_valid(gpio)) {
++              ret = devm_gpio_request_one(dev, gpio, GPIOF_OUT_INIT_LOW,
++                                                      S5K6A3_DRV_NAME);
++              if (ret < 0)
++                      return ret;
++      }
++      sensor->gpio_reset = gpio;
++
++      if (of_property_read_u32(dev->of_node, "clock-frequency",
++                               &sensor->clock_frequency)) {
++              sensor->clock_frequency = S5K6A3_DEFAULT_CLK_FREQ;
++              dev_info(dev, "using default %u Hz clock frequency\n",
++                                      sensor->clock_frequency);
++      }
++
++      for (i = 0; i < S5K6A3_NUM_SUPPLIES; i++)
++              sensor->supplies[i].supply = s5k6a3_supply_names[i];
++
++      ret = devm_regulator_bulk_get(&client->dev, S5K6A3_NUM_SUPPLIES,
++                                    sensor->supplies);
++      if (ret < 0)
++              return ret;
++
++      sd = &sensor->subdev;
++      v4l2_i2c_subdev_init(sd, client, &s5k6a3_subdev_ops);
++      sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++      sensor->format.code = s5k6a3_formats[0].code;
++      sensor->format.width = S5K6A3_DEFAULT_WIDTH;
++      sensor->format.height = S5K6A3_DEFAULT_HEIGHT;
++
++      sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
++      ret = media_entity_init(&sd->entity, 1, &sensor->pad, 0);
++      if (ret < 0)
++              return ret;
++
++      pm_runtime_no_callbacks(dev);
++      pm_runtime_enable(dev);
++
++      return 0;
++}
++
++static int s5k6a3_remove(struct i2c_client *client)
++{
++      struct v4l2_subdev *sd = i2c_get_clientdata(client);
++
++      pm_runtime_disable(&client->dev);
++      media_entity_cleanup(&sd->entity);
++      return 0;
++}
++
++static const struct i2c_device_id s5k6a3_ids[] = {
++      { }
++};
++
++#ifdef CONFIG_OF
++static const struct of_device_id s5k6a3_of_match[] = {
++      { .compatible = "samsung,s5k6a3" },
++      { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, s5k6a3_of_match);
++#endif
++
++static struct i2c_driver s5k6a3_driver = {
++      .driver = {
++              .of_match_table = of_match_ptr(s5k6a3_of_match),
++              .name           = S5K6A3_DRV_NAME,
++              .owner          = THIS_MODULE,
++      },
++      .probe          = s5k6a3_probe,
++      .remove         = s5k6a3_remove,
++      .id_table       = s5k6a3_ids,
++};
++
++module_i2c_driver(s5k6a3_driver);
++
++MODULE_DESCRIPTION("S5K6A3 image sensor subdev driver");
++MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
++MODULE_LICENSE("GPL v2");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0722-V4L-s5k6a3-Add-support-for-asynchronous-subdev-regis.patch b/patches.tizen/0722-V4L-s5k6a3-Add-support-for-asynchronous-subdev-regis.patch
new file mode 100644 (file)
index 0000000..23ab2f5
--- /dev/null
@@ -0,0 +1,135 @@
+From 0732dec259f2cbad0efc11ae6f39388264bf75c9 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 28 Aug 2013 13:41:03 +0200
+Subject: [PATCH 0722/1302] V4L: s5k6a3: Add support for asynchronous subdev
+ registration
+
+This patch converts the driver to use v4l2 asynchronous subdev
+registration API an the clock API to control the external master
+clock directly.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+---
+Changes since v2:
+ - fixed error paths in probe().
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/s5k6a3.c | 43 +++++++++++++++++++++++++++++++++----------
+ 1 file changed, 33 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/media/i2c/s5k6a3.c b/drivers/media/i2c/s5k6a3.c
+index ba86e24..113751b 100644
+--- a/drivers/media/i2c/s5k6a3.c
++++ b/drivers/media/i2c/s5k6a3.c
+@@ -34,6 +34,7 @@
+ #define S5K6A3_DEFAULT_HEIGHT         732
+ #define S5K6A3_DRV_NAME                       "S5K6A3"
++#define S5K6A3_CLK_NAME                       "extclk"
+ #define S5K6A3_DEFAULT_CLK_FREQ               24000000U
+ #define S5K6A3_NUM_SUPPLIES           2
+@@ -56,6 +57,7 @@ struct s5k6a3 {
+       int gpio_reset;
+       struct mutex lock;
+       struct v4l2_mbus_framefmt format;
++      struct clk *clock;
+       u32 clock_frequency;
+ };
+@@ -181,19 +183,25 @@ static int s5k6a3_s_power(struct v4l2_subdev *sd, int on)
+ {
+       struct s5k6a3 *sensor = sd_to_s5k6a3(sd);
+       int gpio = sensor->gpio_reset;
+-      int ret;
++      int ret = 0;
+       if (on) {
++              ret = clk_set_rate(sensor->clock, sensor->clock_frequency);
++              if (ret < 0)
++                      return ret;
++
+               ret = pm_runtime_get(sensor->dev);
+               if (ret < 0)
+                       return ret;
+               ret = regulator_bulk_enable(S5K6A3_NUM_SUPPLIES,
+                                           sensor->supplies);
+-              if (ret < 0) {
+-                      pm_runtime_put(sensor->dev);
+-                      return ret;
+-              }
++              if (ret < 0)
++                      goto rpm_put;
++
++              ret = clk_prepare_enable(sensor->clock);
++              if (ret < 0)
++                      goto reg_dis;
+               if (gpio_is_valid(gpio)) {
+                       gpio_set_value(gpio, 1);
+@@ -209,10 +217,12 @@ static int s5k6a3_s_power(struct v4l2_subdev *sd, int on)
+               if (gpio_is_valid(gpio))
+                       gpio_set_value(gpio, 0);
+-              ret = regulator_bulk_disable(S5K6A3_NUM_SUPPLIES,
+-                                           sensor->supplies);
+-              if (!ret)
+-                      pm_runtime_put(sensor->dev);
++              clk_disable_unprepare(sensor->clock);
++reg_dis:
++              regulator_bulk_disable(S5K6A3_NUM_SUPPLIES,
++                                              sensor->supplies);
++rpm_put:
++              pm_runtime_put(sensor->dev);
+       }
+       return ret;
+ }
+@@ -240,6 +250,7 @@ static int s5k6a3_probe(struct i2c_client *client,
+       mutex_init(&sensor->lock);
+       sensor->gpio_reset = -EINVAL;
++      sensor->clock = ERR_PTR(-EINVAL);
+       sensor->dev = dev;
+       gpio = of_get_gpio_flags(dev->of_node, 0, NULL);
+@@ -266,6 +277,10 @@ static int s5k6a3_probe(struct i2c_client *client,
+       if (ret < 0)
+               return ret;
++      sensor->clock = devm_clk_get(dev, S5K6A3_CLK_NAME);
++      if (IS_ERR(sensor->clock))
++              return -EPROBE_DEFER;
++
+       sd = &sensor->subdev;
+       v4l2_i2c_subdev_init(sd, client, &s5k6a3_subdev_ops);
+       sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+@@ -282,7 +297,14 @@ static int s5k6a3_probe(struct i2c_client *client,
+       pm_runtime_no_callbacks(dev);
+       pm_runtime_enable(dev);
+-      return 0;
++      ret = v4l2_async_register_subdev(sd);
++
++      if (ret < 0) {
++              pm_runtime_disable(&client->dev);
++              media_entity_cleanup(&sd->entity);
++      }
++
++      return ret;
+ }
+ static int s5k6a3_remove(struct i2c_client *client)
+@@ -290,6 +312,7 @@ static int s5k6a3_remove(struct i2c_client *client)
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       pm_runtime_disable(&client->dev);
++      v4l2_async_unregister_subdev(sd);
+       media_entity_cleanup(&sd->entity);
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0723-Revert-V4L-s5c73m3-Initial-device-tree-support.patch b/patches.tizen/0723-Revert-V4L-s5c73m3-Initial-device-tree-support.patch
new file mode 100644 (file)
index 0000000..3ba6466
--- /dev/null
@@ -0,0 +1,221 @@
+From 84e8affa246b99223e879ae61a58d940d265453d Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Mon, 2 Sep 2013 12:38:19 +0200
+Subject: [PATCH 0723/1302] Revert "V4L: s5c73m3: Initial device tree support"
+
+This reverts commit 73cb9c6410de507d85aec8df3ffcaeb0742c6f00.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/s5c73m3/s5c73m3-core.c | 110 ++++++++++---------------------
+ drivers/media/i2c/s5c73m3/s5c73m3-spi.c  |   6 --
+ 2 files changed, 35 insertions(+), 81 deletions(-)
+
+diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+index 6a75a68a..0339f20 100644
+--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
++++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+@@ -23,7 +23,6 @@
+ #include <linux/init.h>
+ #include <linux/media.h>
+ #include <linux/module.h>
+-#include <linux/of_gpio.h>
+ #include <linux/regulator/consumer.h>
+ #include <linux/slab.h>
+ #include <linux/spi/spi.h>
+@@ -1521,28 +1520,17 @@ static const struct v4l2_subdev_ops oif_subdev_ops = {
+       .video  = &s5c73m3_oif_video_ops,
+ };
+-/*
+- * GPIO control helpers
+- */
+-static int s5c73m3_configure_gpio(struct s5c73m3_gpio *gpio, int idx,
+-                                const char *name, struct device_node *node)
++static int s5c73m3_configure_gpio(int nr, int val, const char *name)
+ {
+-      enum of_gpio_flags of_flags;
+-      unsigned long flags;
+-
+-      if (node) {
+-              gpio->gpio = of_get_gpio_flags(node, idx, &of_flags);
+-              gpio->level = !(of_flags & OF_GPIO_ACTIVE_LOW);
+-      }
++      unsigned long flags = val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
++      int ret;
+-      if (!gpio_is_valid(gpio->gpio))
++      if (!gpio_is_valid(nr))
+               return 0;
+-
+-      flags = gpio->level ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+-      pr_debug("gpio[%d]: %d, flags: %#lx, of_flags: %#x\n",
+-               idx, gpio->gpio, flags, of_flags);
+-
+-      return gpio_request_one(gpio->gpio, flags, name);
++      ret = gpio_request_one(nr, flags, name);
++      if (!ret)
++              gpio_export(nr, 0);
++      return ret;
+ }
+ static int s5c73m3_free_gpios(struct s5c73m3 *state)
+@@ -1559,59 +1547,33 @@ static int s5c73m3_free_gpios(struct s5c73m3 *state)
+ }
+ static int s5c73m3_configure_gpios(struct s5c73m3 *state,
+-                                 struct device *dev)
++                                 const struct s5c73m3_platform_data *pdata)
+ {
+-      const struct s5c73m3_platform_data *pdata = dev->platform_data;
+-      struct s5c73m3_gpio gpio;
++      const struct s5c73m3_gpio *gpio = &pdata->gpio_stby;
+       int ret;
+       state->gpio[STBY].gpio = -EINVAL;
+       state->gpio[RST].gpio  = -EINVAL;
+-      if (pdata)
+-              gpio = pdata->gpio_stby;
+-      else
+-              gpio.gpio = -EINVAL;
+-      ret = s5c73m3_configure_gpio(&gpio, STBY, "S5C73M3_STBY",
+-                                   dev->of_node);
+-      if (!ret) {
+-              state->gpio[STBY] = gpio;
+-              if (gpio_is_valid(gpio.gpio))
+-                      gpio_set_value(gpio.gpio, 0);
+-              if (pdata)
+-                      gpio = pdata->gpio_reset;
+-              else
+-                      gpio.gpio = -EINVAL;
+-              ret = s5c73m3_configure_gpio(&gpio, RST, "S5C73M3_RST",
+-                                           dev->of_node);
+-              if (!ret && gpio_is_valid(gpio.gpio))
+-                      gpio_set_value(gpio.gpio, 0);
+-      }
+-      if (!ret)
+-              state->gpio[RST] = gpio;
+-      else
++      ret = s5c73m3_configure_gpio(gpio->gpio, gpio->level, "S5C73M3_STBY");
++      if (ret) {
+               s5c73m3_free_gpios(state);
++              return ret;
++      }
++      state->gpio[STBY] = *gpio;
++      if (gpio_is_valid(gpio->gpio))
++              gpio_set_value(gpio->gpio, 0);
+-      return ret;
+-}
+-
+-static int s5c73m3_get_platform_data(struct s5c73m3 *state, struct device *dev)
+-{
+-      const struct s5c73m3_platform_data *pdata = dev->platform_data;
+-      struct device_node *node = dev->of_node;
+-
+-      if (!node) {
+-              if (!pdata) {
+-                      dev_err(dev, "Platform data not specified\n");
+-                      return -EINVAL;
+-              }
+-
+-              state->mclk_frequency = pdata->mclk_frequency;
+-              state->bus_type = pdata->bus_type;
+-              return 0;
++      gpio = &pdata->gpio_reset;
++      ret = s5c73m3_configure_gpio(gpio->gpio, gpio->level, "S5C73M3_RST");
++      if (ret) {
++              s5c73m3_free_gpios(state);
++              return ret;
+       }
++      state->gpio[RST] = *gpio;
++      if (gpio_is_valid(gpio->gpio))
++              gpio_set_value(gpio->gpio, 0);
+-      of_property_read_u32(node, "clock-frequency", &state->mclk_frequency);
+       return 0;
+ }
+@@ -1619,19 +1581,21 @@ static int s5c73m3_probe(struct i2c_client *client,
+                               const struct i2c_device_id *id)
+ {
+       struct device *dev = &client->dev;
++      const struct s5c73m3_platform_data *pdata = client->dev.platform_data;
+       struct v4l2_subdev *sd;
+       struct v4l2_subdev *oif_sd;
+       struct s5c73m3 *state;
+       int ret, i;
++      if (pdata == NULL) {
++              dev_err(&client->dev, "Platform data not specified\n");
++              return -EINVAL;
++      }
++
+       state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
+       if (!state)
+               return -ENOMEM;
+-      ret = s5c73m3_get_platform_data(state, dev);
+-      if (ret < 0)
+-              return ret;
+-
+       mutex_init(&state->lock);
+       sd = &state->sensor_sd;
+       oif_sd = &state->oif_sd;
+@@ -1669,7 +1633,10 @@ static int s5c73m3_probe(struct i2c_client *client,
+       if (ret < 0)
+               return ret;
+-      ret = s5c73m3_configure_gpios(state, dev);
++      state->mclk_frequency = pdata->mclk_frequency;
++      state->bus_type = pdata->bus_type;
++
++      ret = s5c73m3_configure_gpios(state, pdata);
+       if (ret)
+               goto out_err1;
+@@ -1745,15 +1712,8 @@ static const struct i2c_device_id s5c73m3_id[] = {
+ };
+ MODULE_DEVICE_TABLE(i2c, s5c73m3_id);
+-static const struct of_device_id s5c73m3_of_match[] = {
+-      { .compatible = "samsung,s5c73m3" },
+-      { }
+-};
+-MODULE_DEVICE_TABLE(of, s5c73m3_of_match);
+-
+ static struct i2c_driver s5c73m3_i2c_driver = {
+       .driver = {
+-              .of_match_table = s5c73m3_of_match,
+               .name   = DRIVER_NAME,
+       },
+       .probe          = s5c73m3_probe,
+diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-spi.c b/drivers/media/i2c/s5c73m3/s5c73m3-spi.c
+index 323b47b..be44558 100644
+--- a/drivers/media/i2c/s5c73m3/s5c73m3-spi.c
++++ b/drivers/media/i2c/s5c73m3/s5c73m3-spi.c
+@@ -27,11 +27,6 @@
+ #define S5C73M3_SPI_DRV_NAME "S5C73M3-SPI"
+-static const struct of_device_id s5c73m3_spi_ids[] = {
+-      { .compatible = "samsung,s5c73m3" },
+-      { }
+-};
+-
+ enum spi_direction {
+       SPI_DIR_RX,
+       SPI_DIR_TX
+@@ -146,7 +141,6 @@ int s5c73m3_register_spi_driver(struct s5c73m3 *state)
+       spidrv->driver.name = S5C73M3_SPI_DRV_NAME;
+       spidrv->driver.bus = &spi_bus_type;
+       spidrv->driver.owner = THIS_MODULE;
+-      spidrv->driver.of_match_table = s5c73m3_spi_ids;
+       return spi_register_driver(spidrv);
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0724-media-s5c73m3-Convert-to-devm_gpio_request_one.patch b/patches.tizen/0724-media-s5c73m3-Convert-to-devm_gpio_request_one.patch
new file mode 100644 (file)
index 0000000..23cec2b
--- /dev/null
@@ -0,0 +1,163 @@
+From 31fcd2ccf01fbc52a27d4c51bf7064e531fbb7a2 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Thu, 2 May 2013 08:29:43 -0300
+Subject: [PATCH 0724/1302] [media] s5c73m3: Convert to devm_gpio_request_one()
+
+Use the devm_gpio_request_one() managed function to simplify cleanup
+code paths.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Acked-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/s5c73m3/s5c73m3-core.c | 79 +++++++++++---------------------
+ 1 file changed, 28 insertions(+), 51 deletions(-)
+
+diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+index 0339f20..45ca106 100644
+--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
++++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+@@ -1520,59 +1520,40 @@ static const struct v4l2_subdev_ops oif_subdev_ops = {
+       .video  = &s5c73m3_oif_video_ops,
+ };
+-static int s5c73m3_configure_gpio(int nr, int val, const char *name)
+-{
+-      unsigned long flags = val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+-      int ret;
+-
+-      if (!gpio_is_valid(nr))
+-              return 0;
+-      ret = gpio_request_one(nr, flags, name);
+-      if (!ret)
+-              gpio_export(nr, 0);
+-      return ret;
+-}
+-
+-static int s5c73m3_free_gpios(struct s5c73m3 *state)
+-{
+-      int i;
+-
+-      for (i = 0; i < ARRAY_SIZE(state->gpio); i++) {
+-              if (!gpio_is_valid(state->gpio[i].gpio))
+-                      continue;
+-              gpio_free(state->gpio[i].gpio);
+-              state->gpio[i].gpio = -EINVAL;
+-      }
+-      return 0;
+-}
+-
+ static int s5c73m3_configure_gpios(struct s5c73m3 *state,
+                                  const struct s5c73m3_platform_data *pdata)
+ {
+-      const struct s5c73m3_gpio *gpio = &pdata->gpio_stby;
++      struct device *dev = &state->i2c_client->dev;
++      const struct s5c73m3_gpio *gpio;
++      unsigned long flags;
+       int ret;
+       state->gpio[STBY].gpio = -EINVAL;
+       state->gpio[RST].gpio  = -EINVAL;
+-      ret = s5c73m3_configure_gpio(gpio->gpio, gpio->level, "S5C73M3_STBY");
+-      if (ret) {
+-              s5c73m3_free_gpios(state);
+-              return ret;
++      gpio = &pdata->gpio_stby;
++      if (gpio_is_valid(gpio->gpio)) {
++              flags = (gpio->level ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW)
++                    | GPIOF_EXPORT;
++              ret = devm_gpio_request_one(dev, gpio->gpio, flags,
++                                          "S5C73M3_STBY");
++              if (ret < 0)
++                      return ret;
++
++              state->gpio[STBY] = *gpio;
+       }
+-      state->gpio[STBY] = *gpio;
+-      if (gpio_is_valid(gpio->gpio))
+-              gpio_set_value(gpio->gpio, 0);
+       gpio = &pdata->gpio_reset;
+-      ret = s5c73m3_configure_gpio(gpio->gpio, gpio->level, "S5C73M3_RST");
+-      if (ret) {
+-              s5c73m3_free_gpios(state);
+-              return ret;
++      if (gpio_is_valid(gpio->gpio)) {
++              flags = (gpio->level ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW)
++                    | GPIOF_EXPORT;
++              ret = devm_gpio_request_one(dev, gpio->gpio, flags,
++                                          "S5C73M3_RST");
++              if (ret < 0)
++                      return ret;
++
++              state->gpio[RST] = *gpio;
+       }
+-      state->gpio[RST] = *gpio;
+-      if (gpio_is_valid(gpio->gpio))
+-              gpio_set_value(gpio->gpio, 0);
+       return 0;
+ }
+@@ -1635,10 +1616,11 @@ static int s5c73m3_probe(struct i2c_client *client,
+       state->mclk_frequency = pdata->mclk_frequency;
+       state->bus_type = pdata->bus_type;
++      state->i2c_client = client;
+       ret = s5c73m3_configure_gpios(state, pdata);
+       if (ret)
+-              goto out_err1;
++              goto out_err;
+       for (i = 0; i < S5C73M3_MAX_SUPPLIES; i++)
+               state->supplies[i].supply = s5c73m3_supply_names[i];
+@@ -1647,12 +1629,12 @@ static int s5c73m3_probe(struct i2c_client *client,
+                              state->supplies);
+       if (ret) {
+               dev_err(dev, "failed to get regulators\n");
+-              goto out_err2;
++              goto out_err;
+       }
+       ret = s5c73m3_init_controls(state);
+       if (ret)
+-              goto out_err2;
++              goto out_err;
+       state->sensor_pix_size[RES_ISP] = &s5c73m3_isp_resolutions[1];
+       state->sensor_pix_size[RES_JPEG] = &s5c73m3_jpeg_resolutions[1];
+@@ -1668,9 +1650,7 @@ static int s5c73m3_probe(struct i2c_client *client,
+       ret = s5c73m3_register_spi_driver(state);
+       if (ret < 0)
+-              goto out_err2;
+-
+-      state->i2c_client = client;
++              goto out_err;
+       /* Initialize data plane lengths for the interleaved image data. */
+       state->frame_desc.entry[0].length = 10 * SZ_1M;
+@@ -1679,9 +1659,7 @@ static int s5c73m3_probe(struct i2c_client *client,
+       v4l2_info(sd, "%s: completed succesfully\n", __func__);
+       return 0;
+-out_err2:
+-      s5c73m3_free_gpios(state);
+-out_err1:
++out_err:
+       media_entity_cleanup(&sd->entity);
+       return ret;
+ }
+@@ -1701,7 +1679,6 @@ static int s5c73m3_remove(struct i2c_client *client)
+       media_entity_cleanup(&sensor_sd->entity);
+       s5c73m3_unregister_spi_driver(state);
+-      s5c73m3_free_gpios(state);
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0725-ARM-dts-Add-missing-data-lanes-property-for-exynos44.patch b/patches.tizen/0725-ARM-dts-Add-missing-data-lanes-property-for-exynos44.patch
new file mode 100644 (file)
index 0000000..0113c40
--- /dev/null
@@ -0,0 +1,42 @@
+From 1e0ffd9d4d3ce07e86b3f8dee46d64b85db8a6e0 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Mon, 2 Sep 2013 14:18:31 +0200
+Subject: [PATCH 0725/1302] ARM: dts: Add missing data-lanes property for
+ exynos4412-* boards
+
+The updated driver requires data-lanes property.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-redwoodlte.dts | 1 +
+ arch/arm/boot/dts/exynos4412-slp_pq.dts     | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-redwoodlte.dts b/arch/arm/boot/dts/exynos4412-redwoodlte.dts
+index a846ea9..fa252d5 100644
+--- a/arch/arm/boot/dts/exynos4412-redwoodlte.dts
++++ b/arch/arm/boot/dts/exynos4412-redwoodlte.dts
+@@ -173,6 +173,7 @@
+                       port {
+                               s5c73m3_ep: endpoint {
+                                       remote-endpoint = <&csis0_ep>;
++                                      data-lanes = <1 2 3 4>;
+                               };
+                       };
+               };
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 729e3c2..2c977b7 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -420,6 +420,7 @@
+                       port {
+                               s5c73m3_ep: endpoint {
+                                       remote-endpoint = <&csis0_ep>;
++                                      data-lanes = <1 2 3 4>;
+                               };
+                       };
+               };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0726-ARM-dts-Add-clock-cells-property-to-camera-node-in-e.patch b/patches.tizen/0726-ARM-dts-Add-clock-cells-property-to-camera-node-in-e.patch
new file mode 100644 (file)
index 0000000..dab3147
--- /dev/null
@@ -0,0 +1,40 @@
+From acec70f3fe914228046f746ab066a633964d685d Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Mon, 2 Sep 2013 15:05:57 +0200
+Subject: [PATCH 0726/1302] ARM: dts: Add #clock-cells property to camera node
+ in exynos4.dtsi
+
+Add #clock-cells property for the CAM_*_CLKOUT clocks provider
+and label the camera node to allow referencing clocks at the
+clock consumers.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index aa7fb0b..1969580 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -134,14 +134,14 @@
+               status = "disabled";
+       };
+-      camera {
++      camera: camera {
+               compatible = "samsung,fimc", "simple-bus";
+               status = "disabled";
+               #address-cells = <1>;
+               #size-cells = <1>;
++              #clock-cells = <1>;
+               ranges;
+-
+               fimc_0: fimc@11800000 {
+                       compatible = "samsung,exynos4210-fimc";
+                       reg = <0x11800000 0x1000>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0727-ARM-dts-Add-clock-properties-for-camera-sensors-on-e.patch b/patches.tizen/0727-ARM-dts-Add-clock-properties-for-camera-sensors-on-e.patch
new file mode 100644 (file)
index 0000000..cb18206
--- /dev/null
@@ -0,0 +1,83 @@
+From 7cb9f151abdc91df31521b09fee09ef1e862e80a Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Mon, 2 Sep 2013 15:13:54 +0200
+Subject: [PATCH 0727/1302] ARM: dts: Add clock properties for camera sensors
+ on exyno4412 boards
+
+Add clock properties to the camera sensor device nodes so the sensor
+drivers can get actual frequency of their master clock and control the
+clock.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-m0.dts         | 6 +++---
+ arch/arm/boot/dts/exynos4412-redwoodlte.dts | 3 ++-
+ arch/arm/boot/dts/exynos4412-slp_pq.dts     | 8 ++++++--
+ 3 files changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-m0.dts b/arch/arm/boot/dts/exynos4412-m0.dts
+index ba9168b..5c2c141 100644
+--- a/arch/arm/boot/dts/exynos4412-m0.dts
++++ b/arch/arm/boot/dts/exynos4412-m0.dts
+@@ -199,12 +199,12 @@
+                                       reg = <0x10>;
+                                       svdda-supply = <&cam_io_reg>;
+                                       svddio-supply = <&ldo19_reg>;
+-                                      clock-frequency = <24000000>;
+-                                      samsung,camclk-out = <1>;
+                                       gpios = <&gpm1 6 0>;
+                                       pinctrl-names = "default";
+                                       pinctrl-0 = <&vt_cam_id>;
+-
++                                      clocks = <&camera 1>; /* CAM_B_CLKOUT */
++                                      clock-names = "extclk";
++                                      clock-frequency = <24000000>;
+                                       port {
+                                               is_s5k6a3_ep: endpoint {
+                                                       remote-endpoint = <&csis1_ep>;
+diff --git a/arch/arm/boot/dts/exynos4412-redwoodlte.dts b/arch/arm/boot/dts/exynos4412-redwoodlte.dts
+index fa252d5..4da7157 100644
+--- a/arch/arm/boot/dts/exynos4412-redwoodlte.dts
++++ b/arch/arm/boot/dts/exynos4412-redwoodlte.dts
+@@ -169,7 +169,8 @@
+                       vdd-af-supply = <&cam_af_reg>;
+                       vdd-reg-supply = <&cam_io_reg>;
+                       clock-frequency = <24000000>;
+-
++                      clocks = <&camera 0>;           /* CAM_A_CLKOUT */
++                      clock-names = "cis_extclk";
+                       port {
+                               s5c73m3_ep: endpoint {
+                                       remote-endpoint = <&csis0_ep>;
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 2c977b7..03f53a4 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -415,8 +415,9 @@
+                       vddio-host-supply = <&ldo18_reg>;
+                       vdd-af-supply = <&cam_af_reg>;
+                       vdd-reg-supply = <&cam_io_reg>;
++                      clocks = <&camera 0>;           /* CAM_A_CLKOUT */
++                      clock-names = "cis_extclk";
+                       clock-frequency = <24000000>;
+-
+                       port {
+                               s5c73m3_ep: endpoint {
+                                       remote-endpoint = <&csis0_ep>;
+@@ -1168,8 +1169,11 @@
+                                       reg = <0x10>;
+                                       svdda-supply = <&cam_io_reg>;
+                                       svddio-supply = <&ldo19_reg>;
+-                                      clock-frequency = <24000000>;
+                                       gpios = <&gpm1 6 0>;
++                                      clocks = <&camera 0>; /* CAM_A_CLKOUT */
++                                      clock-names = "extclk";
++                                      clock-frequency = <24000000>;
++
+                                       port {
+                                               is_s5k6a3_ep: endpoint {
+                                                       remote-endpoint = <&csis1_ep>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0728-ARM-dts-Update-s5c73m3-sensor-gpio-properties-for-ex.patch b/patches.tizen/0728-ARM-dts-Update-s5c73m3-sensor-gpio-properties-for-ex.patch
new file mode 100644 (file)
index 0000000..41fc443
--- /dev/null
@@ -0,0 +1,48 @@
+From ce343c80c2ac872e2cc074e8b8c859346610652a Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Mon, 2 Sep 2013 15:17:12 +0200
+Subject: [PATCH 0728/1302] ARM: dts: Update s5c73m3 sensor gpio properties for
+ exynos4412 boards
+
+For synchronization with the latest driver update for mainline.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-redwoodlte.dts | 4 ++--
+ arch/arm/boot/dts/exynos4412-slp_pq.dts     | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-redwoodlte.dts b/arch/arm/boot/dts/exynos4412-redwoodlte.dts
+index 4da7157..bc61f1c 100644
+--- a/arch/arm/boot/dts/exynos4412-redwoodlte.dts
++++ b/arch/arm/boot/dts/exynos4412-redwoodlte.dts
+@@ -160,8 +160,8 @@
+               s5c73m3@3c {
+                       compatible = "samsung,s5c73m3";
+                       reg = <0x3c>;
+-                      gpios = <&gpm0 1 1>, /* ISP_STANDBY */
+-                              <&gpf1 3 1>; /* ISP_RESET */
++                      standby-gpios = <&gpm0 1 1>;    /* ISP_STANDBY */
++                      xshutdown-gpios = <&gpf1 3 1>;  /* ISP_RESET */
+                       vdd-int-supply = <&buck9_reg>;
+                       vddio-cis-supply = <&ldo9_reg>;
+                       vdda-supply = <&ldo17_reg>;
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 03f53a4..4291f0c 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -407,8 +407,8 @@
+               s5c73m3@3c {
+                       compatible = "samsung,s5c73m3";
+                       reg = <0x3c>;
+-                      gpios = <&gpm0 1 1>, /* ISP_STANDBY */
+-                              <&gpf1 3 1>; /* ISP_RESET */
++                      standby-gpios = <&gpm0 1 1>;    /* ISP_STANDBY */
++                      xshutdown-gpios = <&gpf1 3 1>;  /* ISP_RESET */
+                       vdd-int-supply = <&buck9_reg>;
+                       vddio-cis-supply = <&ldo9_reg>;
+                       vdda-supply = <&ldo17_reg>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0729-V4L-s5c73m3-Add-device-tree-support.patch b/patches.tizen/0729-V4L-s5c73m3-Add-device-tree-support.patch
new file mode 100644 (file)
index 0000000..ab37c3a
--- /dev/null
@@ -0,0 +1,537 @@
+From 8e760838daba94a919df0ebe73252da2fa46466b Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Fri, 12 Jul 2013 11:11:10 +0200
+Subject: [PATCH 0729/1302] V4L: s5c73m3: Add device tree support
+
+This patch adds the V4L2 asynchronous subdev registration and
+device tree support. Common clock API is used to control the
+sensor master clock from within the subdev driver.
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+---
+Changes since v1:
+ - added missing ret assignment on clk_get failure,
+ - fixed error paths in probe(),
+ - changed clock name to cis_extclk as specified in the datasheet,
+ - separate properties used for the XSHUTDOWN, STANDBY GPIOs,
+ - multiple correctiond in the binding documentation (improved
+   description of data-lanes and clock-frequency properties).
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/media/samsung-s5c73m3.txt  |  95 ++++++++++
+ drivers/media/i2c/s5c73m3/s5c73m3-core.c           | 206 ++++++++++++++++-----
+ drivers/media/i2c/s5c73m3/s5c73m3-spi.c            |   6 +
+ drivers/media/i2c/s5c73m3/s5c73m3.h                |   4 +
+ 4 files changed, 261 insertions(+), 50 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/media/samsung-s5c73m3.txt
+
+diff --git a/Documentation/devicetree/bindings/media/samsung-s5c73m3.txt b/Documentation/devicetree/bindings/media/samsung-s5c73m3.txt
+new file mode 100644
+index 0000000..6d6c0b6
+--- /dev/null
++++ b/Documentation/devicetree/bindings/media/samsung-s5c73m3.txt
+@@ -0,0 +1,95 @@
++Samsung S5C73M3 8Mp camera ISP
++------------------------------
++
++The S5C73M3 camera ISP supports MIPI CSI-2 and parallel (ITU-R BT.656) video
++data busses. The I2C bus is the main control bus and additionally the SPI bus
++is used, mostly for transferring the firmware to and from the device. Two
++slave device nodes corresponding to these control bus interfaces are required
++and should be placed under respective bus controller nodes.
++
++I2C slave device node
++---------------------
++
++Required properties:
++
++- compatible      : "samsung,s5c73m3";
++- reg             : I2C slave address of the sensor;
++- vdd-int-supply    : digital power supply (1.2V);
++- vdda-supply     : analog power supply (1.2V);
++- vdd-reg-supply    : regulator input power supply (2.8V);
++- vddio-host-supply : host I/O power supply (1.8V to 2.8V);
++- vddio-cis-supply  : CIS I/O power supply (1.2V to 1.8V);
++- vdd-af-supply           : lens power supply (2.8V);
++- xshutdown-gpios   : specifier of GPIO connected to the XSHUTDOWN pin;
++- standby-gpios     : specifier of GPIO connected to the STANDBY pin;
++- clocks          : contains the sensor's CIS_EXTCLK clock specifier;
++- clock-names     : contains "cis_extclk" entry;
++
++Optional properties:
++
++- clock-frequency   : the frequency at which the "cis_extclk" clock should be
++                    configured to operate, in Hz; if this property is not
++                    specified default 24 MHz value will be used.
++
++The common video interfaces bindings (see video-interfaces.txt) should be used
++to specify link from the S5C73M3 to an external image data receiver. The S5C73M3
++device node should contain one 'port' child node with an 'endpoint' subnode for
++this purpose. The data link from a raw image sensor to the S5C73M3 can be
++similarly specified, but it is optional since the S5C73M3 ISP and a raw image
++sensor are usually inseparable and form a hybrid module.
++
++Following properties are valid for the endpoint node(s):
++
++endpoint subnode
++----------------
++
++- data-lanes : (optional) specifies MIPI CSI-2 data lanes as covered in
++  video-interfaces.txt. This sensor doesn't support data lane remapping
++  and physical lane indexes in subsequent elements of the array should
++  be only consecutive ascending values.
++
++SPI device node
++---------------
++
++Required properties:
++
++- compatible      : "samsung,s5c73m3";
++
++For more details see description of the SPI busses bindings
++(../spi/spi-bus.txt) and bindings of a specific bus controller.
++
++Example:
++
++i2c@138A000000 {
++      ...
++      s5c73m3@3c {
++              compatible = "samsung,s5c73m3";
++              reg = <0x3c>;
++              vdd-int-supply = <&buck9_reg>;
++              vdda-supply = <&ldo17_reg>;
++              vdd-reg-supply = <&cam_io_reg>;
++              vddio-host-supply = <&ldo18_reg>;
++              vddio-cis-supply = <&ldo9_reg>;
++              vdd-af-supply = <&cam_af_reg>;
++              clock-frequency = <24000000>;
++              clocks = <&clk 0>;
++              clock-names = "cis_extclk";
++              reset-gpios = <&gpf1 3 1>;
++              standby-gpios = <&gpm0 1 1>;
++              port {
++                      s5c73m3_ep: endpoint {
++                              remote-endpoint = <&csis0_ep>;
++                              data-lanes = <1 2 3 4>;
++                      };
++              };
++      };
++};
++
++spi@1392000 {
++      ...
++      s5c73m3_spi: s5c73m3 {
++              compatible = "samsung,s5c73m3";
++              reg = <0>;
++              ...
++      };
++};
+diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+index 45ca106..6583f88 100644
+--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
++++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+@@ -15,7 +15,7 @@
+  * GNU General Public License for more details.
+  */
+-#include <linux/sizes.h>
++#include <linux/clk.h>
+ #include <linux/delay.h>
+ #include <linux/firmware.h>
+ #include <linux/gpio.h>
+@@ -23,7 +23,9 @@
+ #include <linux/init.h>
+ #include <linux/media.h>
+ #include <linux/module.h>
++#include <linux/of_gpio.h>
+ #include <linux/regulator/consumer.h>
++#include <linux/sizes.h>
+ #include <linux/slab.h>
+ #include <linux/spi/spi.h>
+ #include <linux/videodev2.h>
+@@ -33,6 +35,7 @@
+ #include <media/v4l2-subdev.h>
+ #include <media/v4l2-mediabus.h>
+ #include <media/s5c73m3.h>
++#include <media/v4l2-of.h>
+ #include "s5c73m3.h"
+@@ -47,6 +50,8 @@ module_param(update_fw, int, 0644);
+ #define S5C73M3_EMBEDDED_DATA_MAXLEN  SZ_4K
+ #define S5C73M3_SPI_TX_SIZE           (16 * SZ_1K)
++#define S5C73M3_MIPI_DATA_LANES               4
++#define S5C73M3_CLK_NAME              "cis_extclk"
+ static const char * const s5c73m3_supply_names[S5C73M3_MAX_SUPPLIES] = {
+       "vdd-int",      /* Digital Core supply (1.2V), CAM_ISP_CORE_1.2V */
+@@ -1356,9 +1361,20 @@ static int __s5c73m3_power_on(struct s5c73m3 *state)
+       for (i = 0; i < S5C73M3_MAX_SUPPLIES; i++) {
+               ret = regulator_enable(state->supplies[i].consumer);
+               if (ret)
+-                      goto err;
++                      goto err_reg_dis;
+       }
++      ret = clk_set_rate(state->clock, state->mclk_frequency);
++      if (ret < 0)
++              goto err_reg_dis;
++
++      ret = clk_prepare_enable(state->clock);
++      if (ret < 0)
++              goto err_reg_dis;
++
++      v4l2_dbg(1, s5c73m3_dbg, &state->oif_sd, "clock frequency: %ld\n",
++                                      clk_get_rate(state->clock));
++
+       s5c73m3_gpio_deassert(state, STBY);
+       usleep_range(100, 200);
+@@ -1366,7 +1382,8 @@ static int __s5c73m3_power_on(struct s5c73m3 *state)
+       usleep_range(50, 100);
+       return 0;
+-err:
++
++err_reg_dis:
+       for (--i; i >= 0; i--)
+               regulator_disable(state->supplies[i].consumer);
+       return ret;
+@@ -1381,6 +1398,9 @@ static int __s5c73m3_power_off(struct s5c73m3 *state)
+       if (s5c73m3_gpio_assert(state, STBY))
+               usleep_range(100, 200);
++
++      clk_disable_unprepare(state->clock);
++
+       state->streaming = 0;
+       state->isp_ready = 0;
+@@ -1389,6 +1409,7 @@ static int __s5c73m3_power_off(struct s5c73m3 *state)
+               if (ret)
+                       goto err;
+       }
++
+       return 0;
+ err:
+       for (++i; i < S5C73M3_MAX_SUPPLIES; i++) {
+@@ -1405,6 +1426,7 @@ static int s5c73m3_oif_set_power(struct v4l2_subdev *sd, int on)
+       struct s5c73m3 *state = oif_sd_to_s5c73m3(sd);
+       int ret = 0;
++
+       mutex_lock(&state->lock);
+       if (on && !state->power) {
+@@ -1452,17 +1474,6 @@ static int s5c73m3_oif_registered(struct v4l2_subdev *sd)
+                       S5C73M3_JPEG_PAD, &state->oif_sd.entity, OIF_JPEG_PAD,
+                       MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
+-      mutex_lock(&state->lock);
+-      ret = __s5c73m3_power_on(state);
+-      if (ret == 0)
+-              s5c73m3_get_fw_version(state);
+-
+-      __s5c73m3_power_off(state);
+-      mutex_unlock(&state->lock);
+-
+-      v4l2_dbg(1, s5c73m3_dbg, sd, "%s: Booting %s (%d)\n",
+-               __func__, ret ? "failed" : "succeded", ret);
+-
+       return ret;
+ }
+@@ -1520,41 +1531,108 @@ static const struct v4l2_subdev_ops oif_subdev_ops = {
+       .video  = &s5c73m3_oif_video_ops,
+ };
+-static int s5c73m3_configure_gpios(struct s5c73m3 *state,
+-                                 const struct s5c73m3_platform_data *pdata)
++static int s5c73m3_configure_gpios(struct s5c73m3 *state)
++{
++      static const char * const gpio_names[] = {
++              "S5C73M3_STBY", "S5C73M3_RST"
++      };
++      struct i2c_client *c = state->i2c_client;
++      struct s5c73m3_gpio *g = state->gpio;
++      int ret, i;
++
++      for (i = 0; i < GPIO_NUM; ++i) {
++              unsigned int flags = GPIOF_DIR_OUT;
++              if (g[i].level)
++                      flags |= GPIOF_INIT_HIGH;
++              ret = devm_gpio_request_one(&c->dev, g[i].gpio, flags,
++                                          gpio_names[i]);
++              if (ret) {
++                      v4l2_err(c, "failed to request gpio %s\n",
++                               gpio_names[i]);
++                      return ret;
++              }
++      }
++      return 0;
++}
++
++static int s5c73m3_parse_gpios(struct s5c73m3 *state)
++{
++      static const char * const prop_names[] = {
++              "standby-gpios", "xshutdown-gpios",
++      };
++      struct device *dev = &state->i2c_client->dev;
++      struct device_node *node = dev->of_node;
++      int ret, i;
++
++      for (i = 0; i < GPIO_NUM; ++i) {
++              enum of_gpio_flags of_flags;
++
++              ret = of_get_named_gpio_flags(node, prop_names[i],
++                                            0, &of_flags);
++              if (ret < 0) {
++                      dev_err(dev, "failed to parse %s DT property\n",
++                              prop_names[i]);
++                      return -EINVAL;
++              }
++              state->gpio[i].gpio = ret;
++              state->gpio[i].level = !(of_flags & OF_GPIO_ACTIVE_LOW);
++      }
++      return 0;
++}
++
++static int s5c73m3_get_platform_data(struct s5c73m3 *state)
+ {
+       struct device *dev = &state->i2c_client->dev;
+-      const struct s5c73m3_gpio *gpio;
+-      unsigned long flags;
++      const struct s5c73m3_platform_data *pdata = dev->platform_data;
++      struct device_node *node = dev->of_node;
++      struct device_node *node_ep;
++      struct v4l2_of_endpoint ep;
+       int ret;
+-      state->gpio[STBY].gpio = -EINVAL;
+-      state->gpio[RST].gpio  = -EINVAL;
++      if (!node) {
++              if (!pdata) {
++                      dev_err(dev, "Platform data not specified\n");
++                      return -EINVAL;
++              }
+-      gpio = &pdata->gpio_stby;
+-      if (gpio_is_valid(gpio->gpio)) {
+-              flags = (gpio->level ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW)
+-                    | GPIOF_EXPORT;
+-              ret = devm_gpio_request_one(dev, gpio->gpio, flags,
+-                                          "S5C73M3_STBY");
+-              if (ret < 0)
+-                      return ret;
++              state->mclk_frequency = pdata->mclk_frequency;
++              state->gpio[STBY] = pdata->gpio_stby;
++              state->gpio[RST] = pdata->gpio_reset;
++              return 0;
++      }
+-              state->gpio[STBY] = *gpio;
++      if (of_property_read_u32(node, "clock-frequency",
++                               &state->mclk_frequency)) {
++              state->mclk_frequency = S5C73M3_DEFAULT_MCLK_FREQ;
++              dev_info(dev, "using default %u Hz clock frequency\n",
++                                      state->mclk_frequency);
+       }
+-      gpio = &pdata->gpio_reset;
+-      if (gpio_is_valid(gpio->gpio)) {
+-              flags = (gpio->level ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW)
+-                    | GPIOF_EXPORT;
+-              ret = devm_gpio_request_one(dev, gpio->gpio, flags,
+-                                          "S5C73M3_RST");
+-              if (ret < 0)
+-                      return ret;
++      ret = s5c73m3_parse_gpios(state);
++      if (ret < 0)
++              return -EINVAL;
+-              state->gpio[RST] = *gpio;
++      node_ep = v4l2_of_get_next_endpoint(node, NULL);
++      if (!node_ep) {
++              dev_warn(dev, "no endpoint defined for node: %s\n",
++                                              node->full_name);
++              return 0;
+       }
++      v4l2_of_parse_endpoint(node_ep, &ep);
++      of_node_put(node_ep);
++
++      if (ep.bus_type != V4L2_MBUS_CSI2) {
++              dev_err(dev, "unsupported bus type: %#x\n", ep.bus_type);
++              return -EINVAL;
++      }
++      /*
++       * Number of MIPI CSI-2 data lanes is currently not configurable,
++       * always a default value of 4 lanes is used.
++       */
++      if (ep.bus.mipi_csi2.num_data_lanes != S5C73M3_MIPI_DATA_LANES)
++              dev_info(dev, "falling back to 4 MIPI CSI-2 data lanes\n");
++
+       return 0;
+ }
+@@ -1562,21 +1640,24 @@ static int s5c73m3_probe(struct i2c_client *client,
+                               const struct i2c_device_id *id)
+ {
+       struct device *dev = &client->dev;
+-      const struct s5c73m3_platform_data *pdata = client->dev.platform_data;
+       struct v4l2_subdev *sd;
+       struct v4l2_subdev *oif_sd;
+       struct s5c73m3 *state;
+       int ret, i;
+-      if (pdata == NULL) {
+-              dev_err(&client->dev, "Platform data not specified\n");
+-              return -EINVAL;
+-      }
+-
+       state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
+       if (!state)
+               return -ENOMEM;
++      state->clock = devm_clk_get(dev, S5C73M3_CLK_NAME);
++      if (IS_ERR(state->clock))
++              return -EPROBE_DEFER;
++
++      state->i2c_client = client;
++      ret = s5c73m3_get_platform_data(state);
++      if (ret < 0)
++              return ret;
++
+       mutex_init(&state->lock);
+       sd = &state->sensor_sd;
+       oif_sd = &state->oif_sd;
+@@ -1614,11 +1695,7 @@ static int s5c73m3_probe(struct i2c_client *client,
+       if (ret < 0)
+               return ret;
+-      state->mclk_frequency = pdata->mclk_frequency;
+-      state->bus_type = pdata->bus_type;
+-      state->i2c_client = client;
+-
+-      ret = s5c73m3_configure_gpios(state, pdata);
++      ret = s5c73m3_configure_gpios(state);
+       if (ret)
+               goto out_err;
+@@ -1656,9 +1733,29 @@ static int s5c73m3_probe(struct i2c_client *client,
+       state->frame_desc.entry[0].length = 10 * SZ_1M;
+       state->frame_desc.entry[1].length = S5C73M3_EMBEDDED_DATA_MAXLEN;
++      oif_sd->dev = dev;
++
++      ret = __s5c73m3_power_on(state);
++      if (ret < 0)
++              goto out_err1;
++
++      ret = s5c73m3_get_fw_version(state);
++      __s5c73m3_power_off(state);
++
++      if (ret < 0) {
++              dev_err(dev, "Device detection failed: %d\n", ret);
++              goto out_err1;
++      }
++
++      ret = v4l2_async_register_subdev(oif_sd);
++      if (ret < 0)
++              goto out_err1;
++
+       v4l2_info(sd, "%s: completed succesfully\n", __func__);
+       return 0;
++out_err1:
++      s5c73m3_unregister_spi_driver(state);
+ out_err:
+       media_entity_cleanup(&sd->entity);
+       return ret;
+@@ -1670,7 +1767,7 @@ static int s5c73m3_remove(struct i2c_client *client)
+       struct s5c73m3 *state = oif_sd_to_s5c73m3(oif_sd);
+       struct v4l2_subdev *sensor_sd = &state->sensor_sd;
+-      v4l2_device_unregister_subdev(oif_sd);
++      v4l2_async_unregister_subdev(oif_sd);
+       v4l2_ctrl_handler_free(oif_sd->ctrl_handler);
+       media_entity_cleanup(&oif_sd->entity);
+@@ -1689,8 +1786,17 @@ static const struct i2c_device_id s5c73m3_id[] = {
+ };
+ MODULE_DEVICE_TABLE(i2c, s5c73m3_id);
++#ifdef CONFIG_OF
++static const struct of_device_id s5c73m3_of_match[] = {
++      { .compatible = "samsung,s5c73m3" },
++      { }
++};
++MODULE_DEVICE_TABLE(of, s5c73m3_of_match);
++#endif
++
+ static struct i2c_driver s5c73m3_i2c_driver = {
+       .driver = {
++              .of_match_table = of_match_ptr(s5c73m3_of_match),
+               .name   = DRIVER_NAME,
+       },
+       .probe          = s5c73m3_probe,
+diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-spi.c b/drivers/media/i2c/s5c73m3/s5c73m3-spi.c
+index be44558..323b47b 100644
+--- a/drivers/media/i2c/s5c73m3/s5c73m3-spi.c
++++ b/drivers/media/i2c/s5c73m3/s5c73m3-spi.c
+@@ -27,6 +27,11 @@
+ #define S5C73M3_SPI_DRV_NAME "S5C73M3-SPI"
++static const struct of_device_id s5c73m3_spi_ids[] = {
++      { .compatible = "samsung,s5c73m3" },
++      { }
++};
++
+ enum spi_direction {
+       SPI_DIR_RX,
+       SPI_DIR_TX
+@@ -141,6 +146,7 @@ int s5c73m3_register_spi_driver(struct s5c73m3 *state)
+       spidrv->driver.name = S5C73M3_SPI_DRV_NAME;
+       spidrv->driver.bus = &spi_bus_type;
+       spidrv->driver.owner = THIS_MODULE;
++      spidrv->driver.of_match_table = s5c73m3_spi_ids;
+       return spi_register_driver(spidrv);
+ }
+diff --git a/drivers/media/i2c/s5c73m3/s5c73m3.h b/drivers/media/i2c/s5c73m3/s5c73m3.h
+index 9d2c086..2917857 100644
+--- a/drivers/media/i2c/s5c73m3/s5c73m3.h
++++ b/drivers/media/i2c/s5c73m3/s5c73m3.h
+@@ -17,6 +17,7 @@
+ #ifndef S5C73M3_H_
+ #define S5C73M3_H_
++#include <linux/clk.h>
+ #include <linux/kernel.h>
+ #include <linux/regulator/consumer.h>
+ #include <media/v4l2-common.h>
+@@ -321,6 +322,7 @@ enum s5c73m3_oif_pads {
+ #define S5C73M3_MAX_SUPPLIES                  6
++#define S5C73M3_DEFAULT_MCLK_FREQ             24000000U
+ struct s5c73m3_ctrls {
+       struct v4l2_ctrl_handler handler;
+@@ -391,6 +393,8 @@ struct s5c73m3 {
+       struct regulator_bulk_data supplies[S5C73M3_MAX_SUPPLIES];
+       struct s5c73m3_gpio gpio[GPIO_NUM];
++      struct clk *clock;
++
+       /* External master clock frequency */
+       u32 mclk_frequency;
+       /* Video bus type - MIPI-CSI2/paralell */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0730-exynos4-is-Add-clock-provider-for-the-external-clock.patch b/patches.tizen/0730-exynos4-is-Add-clock-provider-for-the-external-clock.patch
new file mode 100644 (file)
index 0000000..8bc9852
--- /dev/null
@@ -0,0 +1,295 @@
+From 619a3315bc19f66304e3cbe07e5aa38dd440ede9 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 28 Aug 2013 17:45:53 +0200
+Subject: [PATCH 0730/1302] exynos4-is: Add clock provider for the external
+ clocks
+
+This patch adds clock provider to expose the sclk_cam0/1 clocks
+for image sensor subdevs.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+---
+Changes since v2:
+- embed #clocks-property into 'camera' node rather than creating
+  separate subnode for the clock provider, edited the binding's
+  documentation.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/media/samsung-fimc.txt     |  15 ++-
+ drivers/media/platform/exynos4-is/media-dev.c      | 108 +++++++++++++++++++++
+ drivers/media/platform/exynos4-is/media-dev.h      |  18 +++-
+ 3 files changed, 137 insertions(+), 4 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/media/samsung-fimc.txt b/Documentation/devicetree/bindings/media/samsung-fimc.txt
+index 96312f6..137d540 100644
+--- a/Documentation/devicetree/bindings/media/samsung-fimc.txt
++++ b/Documentation/devicetree/bindings/media/samsung-fimc.txt
+@@ -32,6 +32,15 @@ way around.
+ The 'camera' node must include at least one 'fimc' child node.
++Optional properties:
++
++- #clock-cells: from the common clock bindings (../clock/clock-bindings.txt),
++  must be 1. A clock provider is associated with the camera node and it should
++  be referenced by external sensors that use clocks provided by the SoC on
++  CAM_*_CLKOUT pins. The second cell of the clock specifier is a clock's index.
++  The indexes are 0, 1 for CAM_A_CLKOUT, CAM_B_CLKOUT clocks respectively.
++
++
+ 'fimc' device nodes
+ -------------------
+@@ -114,7 +123,7 @@ Example:
+                       vddio-supply = <...>;
+                       clock-frequency = <24000000>;
+-                      clocks = <...>;
++                      clocks = <&camclk 1>;
+                       clock-names = "mclk";
+                       port {
+@@ -135,7 +144,7 @@ Example:
+                       vddio-supply = <...>;
+                       clock-frequency = <24000000>;
+-                      clocks = <...>;
++                      clocks = <&camclk 0>;
+                       clock-names = "mclk";
+                       port {
+@@ -151,8 +160,8 @@ Example:
+               compatible = "samsung,fimc", "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
++              #clock-cells = <1>;
+               status = "okay";
+-
+               pinctrl-names = "default";
+               pinctrl-0 = <&cam_port_a_clk_active>;
+diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
+index 11fddd5..9d3a38f 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.c
++++ b/drivers/media/platform/exynos4-is/media-dev.c
+@@ -11,6 +11,8 @@
+  */
+ #include <linux/bug.h>
++#include <linux/clk.h>
++#include <linux/clk-provider.h>
+ #include <linux/device.h>
+ #include <linux/errno.h>
+ #include <linux/i2c.h>
+@@ -1455,6 +1457,101 @@ static int fimc_md_get_pinctrl(struct fimc_md *fmd)
+       return 0;
+ }
++#ifdef CONFIG_OF
++static int cam_clk_prepare(struct clk_hw *hw)
++{
++      struct cam_clk *camclk = to_cam_clk(hw);
++      int ret;
++
++      if (camclk->fmd->pmf == NULL)
++              return -ENODEV;
++
++      ret = pm_runtime_get_sync(camclk->fmd->pmf);
++      return ret < 0 ? ret : 0;
++}
++
++static void cam_clk_unprepare(struct clk_hw *hw)
++{
++      struct cam_clk *camclk = to_cam_clk(hw);
++
++      if (camclk->fmd->pmf == NULL)
++              return;
++
++      pm_runtime_put_sync(camclk->fmd->pmf);
++}
++
++static const struct clk_ops cam_clk_ops = {
++      .prepare = cam_clk_prepare,
++      .unprepare = cam_clk_unprepare,
++};
++
++static const char *cam_clk_p_names[] = { "sclk_cam0", "sclk_cam1" };
++
++static void fimc_md_unregister_clk_provider(struct fimc_md *fmd)
++{
++      struct cam_clk_provider *cp = &fmd->clk_provider;
++      unsigned int i;
++
++      if (cp->of_node)
++              of_clk_del_provider(cp->of_node);
++
++      for (i = 0; i < ARRAY_SIZE(cp->clks); i++)
++              if (!IS_ERR(cp->clks[i]))
++                      clk_unregister(cp->clks[i]);
++}
++
++static int fimc_md_register_clk_provider(struct fimc_md *fmd)
++{
++      struct cam_clk_provider *cp = &fmd->clk_provider;
++      struct device *dev = &fmd->pdev->dev;
++      int i, ret;
++
++      for (i = 0; i < ARRAY_SIZE(cp->clks); i++)
++              cp->clks[i] = ERR_PTR(-EINVAL);
++
++      for (i = 0; i < FIMC_MAX_CAMCLKS; i++) {
++              struct cam_clk *camclk = &cp->camclk[i];
++              struct clk_init_data init;
++              char clk_name[16];
++              struct clk *clk;
++
++              snprintf(clk_name, sizeof(clk_name), "cam_clkout%d", i);
++
++              init.name = clk_name;
++              init.ops = &cam_clk_ops;
++              init.flags = CLK_SET_RATE_PARENT;
++              init.parent_names = &cam_clk_p_names[i];
++              init.num_parents = 1;
++              camclk->hw.init = &init;
++              camclk->fmd = fmd;
++
++              clk = clk_register(dev, &camclk->hw);
++              if (IS_ERR(clk)) {
++                      dev_err(dev, "failed to register clock: %s (%ld)\n",
++                                              clk_name, PTR_ERR(clk));
++                      ret = PTR_ERR(clk);
++                      goto err;
++              }
++              cp->clks[i] = clk;
++      }
++
++      cp->clk_data.clks = cp->clks;
++      cp->clk_data.clk_num = i;
++      cp->of_node = dev->of_node;
++
++      ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
++                                &cp->clk_data);
++      if (!ret)
++              return 0;
++err:
++      fimc_md_unregister_clk_provider(fmd);
++      return ret;
++}
++#else
++#define fimc_md_register_clk_provider(fmd) (0)
++#define fimc_md_unregister_clk_provider(fmd) (0)
++#endif
++
+ static int fimc_md_probe(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+@@ -1482,16 +1579,24 @@ static int fimc_md_probe(struct platform_device *pdev)
+       fmd->use_isp = fimc_md_is_isp_available(dev->of_node);
++      ret = fimc_md_register_clk_provider(fmd);
++      if (ret < 0) {
++              v4l2_err(v4l2_dev, "clock provider registration failed\n");
++              return ret;
++      }
++
+       ret = v4l2_device_register(dev, &fmd->v4l2_dev);
+       if (ret < 0) {
+               v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret);
+               return ret;
+       }
++
+       ret = media_device_register(&fmd->media_dev);
+       if (ret < 0) {
+               v4l2_err(v4l2_dev, "Failed to register media device: %d\n", ret);
+               goto err_md;
+       }
++
+       ret = fimc_md_get_clocks(fmd);
+       if (ret)
+               goto err_clk;
+@@ -1525,6 +1630,7 @@ static int fimc_md_probe(struct platform_device *pdev)
+       ret = fimc_md_create_links(fmd);
+       if (ret)
+               goto err_unlock;
++
+       ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev);
+       if (ret)
+               goto err_unlock;
+@@ -1545,6 +1651,7 @@ err_clk:
+       media_device_unregister(&fmd->media_dev);
+ err_md:
+       v4l2_device_unregister(&fmd->v4l2_dev);
++      fimc_md_unregister_clk_provider(fmd);
+       return ret;
+ }
+@@ -1555,6 +1662,7 @@ static int fimc_md_remove(struct platform_device *pdev)
+       if (!fmd)
+               return 0;
++      fimc_md_unregister_clk_provider(fmd);
+       v4l2_device_unregister(&fmd->v4l2_dev);
+       device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode);
+       fimc_md_unregister_entities(fmd);
+diff --git a/drivers/media/platform/exynos4-is/media-dev.h b/drivers/media/platform/exynos4-is/media-dev.h
+index 62599fd..240ca71 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.h
++++ b/drivers/media/platform/exynos4-is/media-dev.h
+@@ -10,6 +10,7 @@
+ #define FIMC_MDEVICE_H_
+ #include <linux/clk.h>
++#include <linux/clk-provider.h>
+ #include <linux/platform_device.h>
+ #include <linux/mutex.h>
+ #include <linux/of.h>
+@@ -89,6 +90,12 @@ struct fimc_sensor_info {
+       struct fimc_dev *host;
+ };
++struct cam_clk {
++      struct clk_hw hw;
++      struct fimc_md *fmd;
++};
++#define to_cam_clk(_hw) container_of(_hw, struct cam_clk, hw)
++
+ /**
+  * struct fimc_md - fimc media device information
+  * @csis: MIPI CSIS subdevs data
+@@ -105,6 +112,7 @@ struct fimc_sensor_info {
+  * @pinctrl: camera port pinctrl handle
+  * @state_default: pinctrl default state handle
+  * @state_idle: pinctrl idle state handle
++ * @cam_clk_provider: CAMCLK clock provider structure
+  * @user_subdev_api: true if subdevs are not configured by the host driver
+  * @slock: spinlock protecting @sensor array
+  */
+@@ -122,13 +130,21 @@ struct fimc_md {
+       struct media_device media_dev;
+       struct v4l2_device v4l2_dev;
+       struct platform_device *pdev;
++
+       struct fimc_pinctrl {
+               struct pinctrl *pinctrl;
+               struct pinctrl_state *state_default;
+               struct pinctrl_state *state_idle;
+       } pinctl;
+-      bool user_subdev_api;
++      struct cam_clk_provider {
++              struct clk *clks[FIMC_MAX_CAMCLKS];
++              struct clk_onecell_data clk_data;
++              struct device_node *of_node;
++              struct cam_clk camclk[FIMC_MAX_CAMCLKS];
++      } clk_provider;
++
++      bool user_subdev_api;
+       spinlock_t slock;
+       struct list_head pipelines;
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0731-exynos4-is-Use-external-s5k6a3-sensor-driver.patch b/patches.tizen/0731-exynos4-is-Use-external-s5k6a3-sensor-driver.patch
new file mode 100644 (file)
index 0000000..fa1dcb4
--- /dev/null
@@ -0,0 +1,632 @@
+From 04bd197873608dc28bc021befd9d7e22fede2854 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 19 Jul 2013 16:35:11 +0200
+Subject: [PATCH 0731/1302] exynos4-is: Use external s5k6a3 sensor driver
+
+This patch removes the common fimc-is-sensor driver for image sensors
+that are normally controlled by the FIMC-IS firmware. The FIMC-IS
+driver now contains only a table of properties specific to each sensor.
+The sensor properties required for the ISP's firmware are parsed from
+device tree and retrieved from the internal table, which is selected
+based on the compatible property of an image sensor.
+
+To use the Exynos4x12 internal ISP the S5K6A3 sensor driver (drivers/
+media/i2c/s5k6a3.c) is now required.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-is-regs.c   |   2 +-
+ drivers/media/platform/exynos4-is/fimc-is-sensor.c | 285 +--------------------
+ drivers/media/platform/exynos4-is/fimc-is-sensor.h |  49 +---
+ drivers/media/platform/exynos4-is/fimc-is.c        |  97 +++----
+ drivers/media/platform/exynos4-is/fimc-is.h        |   4 +-
+ 5 files changed, 57 insertions(+), 380 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-is-regs.c b/drivers/media/platform/exynos4-is/fimc-is-regs.c
+index ad8e630..63f8b5e 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is-regs.c
++++ b/drivers/media/platform/exynos4-is/fimc-is-regs.c
+@@ -150,7 +150,7 @@ void fimc_is_hw_set_sensor_num(struct fimc_is *is)
+       mcuctl_write(IH_REPLY_DONE, is, MCUCTL_REG_ISSR(0));
+       mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
+       mcuctl_write(IHC_GET_SENSOR_NUM, is, MCUCTL_REG_ISSR(2));
+-      mcuctl_write(FIMC_IS_SENSOR_NUM, is, MCUCTL_REG_ISSR(3));
++      mcuctl_write(FIMC_IS_SENSORS_NUM, is, MCUCTL_REG_ISSR(3));
+ }
+ void fimc_is_hw_close_sensor(struct fimc_is *is, unsigned int index)
+diff --git a/drivers/media/platform/exynos4-is/fimc-is-sensor.c b/drivers/media/platform/exynos4-is/fimc-is-sensor.c
+index 6647421..10e82e2 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is-sensor.c
++++ b/drivers/media/platform/exynos4-is/fimc-is-sensor.c
+@@ -2,276 +2,21 @@
+  * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
+  *
+  * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+- *
+  * Author: Sylwester Nawrocki <s.nawrocki@samsung.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/delay.h>
+-#include <linux/device.h>
+-#include <linux/errno.h>
+-#include <linux/gpio.h>
+-#include <linux/i2c.h>
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-#include <linux/of_gpio.h>
+-#include <linux/pm_runtime.h>
+-#include <linux/regulator/consumer.h>
+-#include <linux/slab.h>
+-#include <media/v4l2-subdev.h>
+-#include "fimc-is.h"
+ #include "fimc-is-sensor.h"
+-#define DRIVER_NAME "FIMC-IS-SENSOR"
+-
+-static const char * const sensor_supply_names[] = {
+-      "svdda",
+-      "svddio",
+-};
+-
+-static const struct v4l2_mbus_framefmt fimc_is_sensor_formats[] = {
+-      {
+-              .code = V4L2_MBUS_FMT_SGRBG10_1X10,
+-              .colorspace = V4L2_COLORSPACE_SRGB,
+-              .field = V4L2_FIELD_NONE,
+-      }
+-};
+-
+-static const struct v4l2_mbus_framefmt *find_sensor_format(
+-      struct v4l2_mbus_framefmt *mf)
+-{
+-      int i;
+-
+-      for (i = 0; i < ARRAY_SIZE(fimc_is_sensor_formats); i++)
+-              if (mf->code == fimc_is_sensor_formats[i].code)
+-                      return &fimc_is_sensor_formats[i];
+-
+-      return &fimc_is_sensor_formats[0];
+-}
+-
+-static int fimc_is_sensor_enum_mbus_code(struct v4l2_subdev *sd,
+-                                struct v4l2_subdev_fh *fh,
+-                                struct v4l2_subdev_mbus_code_enum *code)
+-{
+-      if (code->index >= ARRAY_SIZE(fimc_is_sensor_formats))
+-              return -EINVAL;
+-
+-      code->code = fimc_is_sensor_formats[code->index].code;
+-      return 0;
+-}
+-
+-static void fimc_is_sensor_try_format(struct fimc_is_sensor *sensor,
+-                                    struct v4l2_mbus_framefmt *mf)
+-{
+-      const struct sensor_drv_data *dd = sensor->drvdata;
+-      const struct v4l2_mbus_framefmt *fmt;
+-
+-      fmt = find_sensor_format(mf);
+-      mf->code = fmt->code;
+-      v4l_bound_align_image(&mf->width, 16 + 8, dd->width, 0,
+-                            &mf->height, 12 + 8, dd->height, 0, 0);
+-}
+-
+-static struct v4l2_mbus_framefmt *__fimc_is_sensor_get_format(
+-              struct fimc_is_sensor *sensor, struct v4l2_subdev_fh *fh,
+-              u32 pad, enum v4l2_subdev_format_whence which)
+-{
+-      if (which == V4L2_SUBDEV_FORMAT_TRY)
+-              return fh ? v4l2_subdev_get_try_format(fh, pad) : NULL;
+-
+-      return &sensor->format;
+-}
+-
+-static int fimc_is_sensor_set_fmt(struct v4l2_subdev *sd,
+-                                struct v4l2_subdev_fh *fh,
+-                                struct v4l2_subdev_format *fmt)
+-{
+-      struct fimc_is_sensor *sensor = sd_to_fimc_is_sensor(sd);
+-      struct v4l2_mbus_framefmt *mf;
+-
+-      fimc_is_sensor_try_format(sensor, &fmt->format);
+-
+-      mf = __fimc_is_sensor_get_format(sensor, fh, fmt->pad, fmt->which);
+-      if (mf) {
+-              mutex_lock(&sensor->lock);
+-              if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+-                      *mf = fmt->format;
+-              mutex_unlock(&sensor->lock);
+-      }
+-      return 0;
+-}
+-
+-static int fimc_is_sensor_get_fmt(struct v4l2_subdev *sd,
+-                                struct v4l2_subdev_fh *fh,
+-                                struct v4l2_subdev_format *fmt)
+-{
+-      struct fimc_is_sensor *sensor = sd_to_fimc_is_sensor(sd);
+-      struct v4l2_mbus_framefmt *mf;
+-
+-      mf = __fimc_is_sensor_get_format(sensor, fh, fmt->pad, fmt->which);
+-
+-      mutex_lock(&sensor->lock);
+-      fmt->format = *mf;
+-      mutex_unlock(&sensor->lock);
+-      return 0;
+-}
+-
+-static struct v4l2_subdev_pad_ops fimc_is_sensor_pad_ops = {
+-      .enum_mbus_code = fimc_is_sensor_enum_mbus_code,
+-      .get_fmt        = fimc_is_sensor_get_fmt,
+-      .set_fmt        = fimc_is_sensor_set_fmt,
+-};
+-
+-static int fimc_is_sensor_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+-{
+-      struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(fh, 0);
+-
+-      *format         = fimc_is_sensor_formats[0];
+-      format->width   = FIMC_IS_SENSOR_DEF_PIX_WIDTH;
+-      format->height  = FIMC_IS_SENSOR_DEF_PIX_HEIGHT;
+-
+-      return 0;
+-}
+-
+-static const struct v4l2_subdev_internal_ops fimc_is_sensor_sd_internal_ops = {
+-      .open = fimc_is_sensor_open,
+-};
+-
+-static int fimc_is_sensor_s_power(struct v4l2_subdev *sd, int on)
+-{
+-      struct fimc_is_sensor *sensor = sd_to_fimc_is_sensor(sd);
+-      int gpio = sensor->gpio_reset;
+-      int ret;
+-
+-      if (on) {
+-              ret = pm_runtime_get(sensor->dev);
+-              if (ret < 0)
+-                      return ret;
+-
+-              ret = regulator_bulk_enable(SENSOR_NUM_SUPPLIES,
+-                                          sensor->supplies);
+-              if (ret < 0) {
+-                      pm_runtime_put(sensor->dev);
+-                      return ret;
+-              }
+-              if (gpio_is_valid(gpio)) {
+-                      gpio_set_value(gpio, 1);
+-                      usleep_range(600, 800);
+-                      gpio_set_value(gpio, 0);
+-                      usleep_range(10000, 11000);
+-                      gpio_set_value(gpio, 1);
+-              }
+-
+-              /* A delay needed for the sensor initialization. */
+-              msleep(20);
+-      } else {
+-              if (gpio_is_valid(gpio))
+-                      gpio_set_value(gpio, 0);
+-
+-              ret = regulator_bulk_disable(SENSOR_NUM_SUPPLIES,
+-                                           sensor->supplies);
+-              if (!ret)
+-                      pm_runtime_put(sensor->dev);
+-      }
+-
+-      pr_info("%s:%d: on: %d, ret: %d\n", __func__, __LINE__, on, ret);
+-
+-      return ret;
+-}
+-
+-static struct v4l2_subdev_core_ops fimc_is_sensor_core_ops = {
+-      .s_power = fimc_is_sensor_s_power,
+-};
+-
+-static struct v4l2_subdev_ops fimc_is_sensor_subdev_ops = {
+-      .core = &fimc_is_sensor_core_ops,
+-      .pad = &fimc_is_sensor_pad_ops,
+-};
+-
+-static const struct of_device_id fimc_is_sensor_of_match[];
+-
+-static int fimc_is_sensor_probe(struct i2c_client *client,
+-                              const struct i2c_device_id *id)
+-{
+-      struct device *dev = &client->dev;
+-      struct fimc_is_sensor *sensor;
+-      const struct of_device_id *of_id;
+-      struct v4l2_subdev *sd;
+-      int gpio, i, ret;
+-
+-      sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
+-      if (!sensor)
+-              return -ENOMEM;
+-
+-      mutex_init(&sensor->lock);
+-      sensor->gpio_reset = -EINVAL;
+-
+-      gpio = of_get_gpio_flags(dev->of_node, 0, NULL);
+-      if (gpio_is_valid(gpio)) {
+-              ret = devm_gpio_request_one(dev, gpio, GPIOF_OUT_INIT_LOW,
+-                                                      DRIVER_NAME);
+-              if (ret < 0)
+-                      return ret;
+-      }
+-      sensor->gpio_reset = gpio;
+-
+-      for (i = 0; i < SENSOR_NUM_SUPPLIES; i++)
+-              sensor->supplies[i].supply = sensor_supply_names[i];
+-
+-      ret = devm_regulator_bulk_get(&client->dev, SENSOR_NUM_SUPPLIES,
+-                                    sensor->supplies);
+-      if (ret < 0)
+-              return ret;
+-
+-      of_id = of_match_node(fimc_is_sensor_of_match, dev->of_node);
+-      if (!of_id)
+-              return -ENODEV;
+-
+-      sensor->drvdata = of_id->data;
+-      sensor->dev = dev;
+-
+-      sd = &sensor->subdev;
+-      v4l2_i2c_subdev_init(sd, client, &fimc_is_sensor_subdev_ops);
+-      snprintf(sd->name, sizeof(sd->name), sensor->drvdata->subdev_name);
+-      sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+-
+-      sensor->format.code = fimc_is_sensor_formats[0].code;
+-      sensor->format.width = FIMC_IS_SENSOR_DEF_PIX_WIDTH;
+-      sensor->format.height = FIMC_IS_SENSOR_DEF_PIX_HEIGHT;
+-
+-      sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
+-      ret = media_entity_init(&sd->entity, 1, &sensor->pad, 0);
+-      if (ret < 0)
+-              return ret;
+-
+-      pm_runtime_no_callbacks(dev);
+-      pm_runtime_enable(dev);
+-
+-      return ret;
+-}
+-
+-static int fimc_is_sensor_remove(struct i2c_client *client)
+-{
+-      struct v4l2_subdev *sd = i2c_get_clientdata(client);
+-      media_entity_cleanup(&sd->entity);
+-      return 0;
+-}
+-
+-static const struct i2c_device_id fimc_is_sensor_ids[] = {
+-      { }
+-};
+-
+ static const struct sensor_drv_data s5k6a3_drvdata = {
+       .id             = FIMC_IS_SENSOR_ID_S5K6A3,
+-      .subdev_name    = "S5K6A3",
+-      .width          = S5K6A3_SENSOR_WIDTH,
+-      .height         = S5K6A3_SENSOR_HEIGHT,
++      .open_timeout   = S5K6A3_OPEN_TIMEOUT,
+ };
+-static const struct of_device_id fimc_is_sensor_of_match[] = {
++static const struct of_device_id fimc_is_sensor_of_ids[] = {
+       {
+               .compatible     = "samsung,s5k6a3",
+               .data           = &s5k6a3_drvdata,
+@@ -279,27 +24,11 @@ static const struct of_device_id fimc_is_sensor_of_match[] = {
+       {  }
+ };
+-static struct i2c_driver fimc_is_sensor_driver = {
+-      .driver = {
+-              .of_match_table = fimc_is_sensor_of_match,
+-              .name           = DRIVER_NAME,
+-              .owner          = THIS_MODULE,
+-      },
+-      .probe          = fimc_is_sensor_probe,
+-      .remove         = fimc_is_sensor_remove,
+-      .id_table       = fimc_is_sensor_ids,
+-};
+-
+-int fimc_is_register_sensor_driver(void)
++const struct sensor_drv_data *fimc_is_sensor_get_drvdata(
++                      struct device_node *node)
+ {
+-      return i2c_add_driver(&fimc_is_sensor_driver);
+-}
++      const struct of_device_id *of_id;
+-void fimc_is_unregister_sensor_driver(void)
+-{
+-      i2c_del_driver(&fimc_is_sensor_driver);
++      of_id = of_match_node(fimc_is_sensor_of_ids, node);
++      return of_id ? of_id->data : NULL;
+ }
+-
+-MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
+-MODULE_DESCRIPTION("Exynos4x12 FIMC-IS image sensor subdev driver");
+-MODULE_LICENSE("GPL");
+diff --git a/drivers/media/platform/exynos4-is/fimc-is-sensor.h b/drivers/media/platform/exynos4-is/fimc-is-sensor.h
+index 6036d49..173ccff 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is-sensor.h
++++ b/drivers/media/platform/exynos4-is/fimc-is-sensor.h
+@@ -13,24 +13,13 @@
+ #ifndef FIMC_IS_SENSOR_H_
+ #define FIMC_IS_SENSOR_H_
+-#include <linux/clk.h>
+-#include <linux/device.h>
+-#include <linux/kernel.h>
+-#include <linux/platform_device.h>
+-#include <linux/regulator/consumer.h>
+-#include <linux/videodev2.h>
+-#include <media/v4l2-subdev.h>
+-
+-#define FIMC_IS_SENSOR_OPEN_TIMEOUT   2000 /* ms */
+-
+-#define FIMC_IS_SENSOR_DEF_PIX_WIDTH  1296
+-#define FIMC_IS_SENSOR_DEF_PIX_HEIGHT 732
++#include <linux/of.h>
++#include <linux/types.h>
++#define S5K6A3_OPEN_TIMEOUT           2000 /* ms */
+ #define S5K6A3_SENSOR_WIDTH           1392
+ #define S5K6A3_SENSOR_HEIGHT          1392
+-#define SENSOR_NUM_SUPPLIES           2
+-
+ enum fimc_is_sensor_id {
+       FIMC_IS_SENSOR_ID_S5K3H2 = 1,
+       FIMC_IS_SENSOR_ID_S5K6A3,
+@@ -45,45 +34,23 @@ enum fimc_is_sensor_id {
+ struct sensor_drv_data {
+       enum fimc_is_sensor_id id;
+-      const char * const subdev_name;
+-      unsigned int width;
+-      unsigned int height;
++      /* sensor open timeout in ms */
++      unsigned short open_timeout;
+ };
+ /**
+  * struct fimc_is_sensor - fimc-is sensor data structure
+- * @dev: pointer to this I2C client device structure
+- * @subdev: the image sensor's v4l2 subdev
+- * @pad: subdev media source pad
+- * @supplies: image sensor's voltage regulator supplies
+- * @gpio_reset: GPIO connected to the sensor's reset pin
+  * @drvdata: a pointer to the sensor's parameters data structure
+  * @i2c_bus: ISP I2C bus index (0...1)
+  * @test_pattern: true to enable video test pattern
+- * @lock: mutex protecting the structure's members below
+- * @format: media bus format at the sensor's source pad
+  */
+ struct fimc_is_sensor {
+-      struct device *dev;
+-      struct v4l2_subdev subdev;
+-      struct media_pad pad;
+-      struct regulator_bulk_data supplies[SENSOR_NUM_SUPPLIES];
+-      int gpio_reset;
+       const struct sensor_drv_data *drvdata;
+       unsigned int i2c_bus;
+-      bool test_pattern;
+-
+-      struct mutex lock;
+-      struct v4l2_mbus_framefmt format;
++      u8 test_pattern;
+ };
+-static inline
+-struct fimc_is_sensor *sd_to_fimc_is_sensor(struct v4l2_subdev *sd)
+-{
+-      return container_of(sd, struct fimc_is_sensor, subdev);
+-}
+-
+-int fimc_is_register_sensor_driver(void);
+-void fimc_is_unregister_sensor_driver(void);
++const struct sensor_drv_data *fimc_is_sensor_get_drvdata(
++                              struct device_node *node);
+ #endif /* FIMC_IS_SENSOR_H_ */
+diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c
+index 76794f1..5d3586d 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is.c
++++ b/drivers/media/platform/exynos4-is/fimc-is.c
+@@ -161,30 +161,44 @@ static void fimc_is_disable_clocks(struct fimc_is *is)
+       }
+ }
+-static int fimc_is_parse_sensor_config(struct fimc_is_sensor *sensor,
+-                                     struct device_node *np)
++static int fimc_is_parse_sensor_config(struct fimc_is *is, unsigned int index,
++                                              struct device_node *node)
+ {
++      struct fimc_is_sensor *sensor = &is->sensor[index];
+       u32 tmp = 0;
+       int ret;
+-      np = v4l2_of_get_next_endpoint(np, NULL);
+-      if (!np)
++      sensor->drvdata = fimc_is_sensor_get_drvdata(node);
++      if (!sensor->drvdata) {
++              dev_err(&is->pdev->dev, "no driver data found for: %s\n",
++                                                       node->full_name);
++              return -EINVAL;
++      }
++
++      node = v4l2_of_get_next_endpoint(node, NULL);
++      if (!node)
+               return -ENXIO;
+-      np = v4l2_of_get_remote_port(np);
+-      if (!np)
++
++      node = v4l2_of_get_remote_port(node);
++      if (!node)
+               return -ENXIO;
+       /* Use MIPI-CSIS channel id to determine the ISP I2C bus index. */
+-      ret = of_property_read_u32(np, "reg", &tmp);
+-      sensor->i2c_bus = tmp - FIMC_INPUT_MIPI_CSI2_0;
++      ret = of_property_read_u32(node, "reg", &tmp);
++      if (ret < 0) {
++              dev_err(&is->pdev->dev, "reg property not found at: %s\n",
++                                                       node->full_name);
++              return ret;
++      }
+-      return ret;
++      sensor->i2c_bus = tmp - FIMC_INPUT_MIPI_CSI2_0;
++      return 0;
+ }
+ static int fimc_is_register_subdevs(struct fimc_is *is)
+ {
+-      struct device_node *adapter, *child;
+-      int ret;
++      struct device_node *i2c_bus, *child;
++      int ret, index = 0;
+       ret = fimc_isp_subdev_create(&is->isp);
+       if (ret < 0)
+@@ -193,49 +207,23 @@ static int fimc_is_register_subdevs(struct fimc_is *is)
+       /* Initialize memory allocator context for the ISP DMA. */
+       is->isp.alloc_ctx = is->alloc_ctx;
+-      for_each_compatible_node(adapter, NULL, FIMC_IS_I2C_COMPATIBLE) {
+-              if (!of_find_device_by_node(adapter)) {
+-                      of_node_put(adapter);
+-                      return -EPROBE_DEFER;
+-              }
++      for_each_compatible_node(i2c_bus, NULL, FIMC_IS_I2C_COMPATIBLE) {
++              for_each_available_child_of_node(i2c_bus, child) {
++                      ret = fimc_is_parse_sensor_config(is, index, child);
+-              for_each_available_child_of_node(adapter, child) {
+-                      struct i2c_client *client;
+-                      struct v4l2_subdev *sd;
+-
+-                      client = of_find_i2c_device_by_node(child);
+-                      if (!client)
+-                              goto e_retry;
+-
+-                      sd = i2c_get_clientdata(client);
+-                      if (!sd)
+-                              goto e_retry;
+-
+-                      /* FIXME: Add support for multiple sensors. */
+-                      if (WARN_ON(is->sensor))
+-                              continue;
+-
+-                      is->sensor = sd_to_fimc_is_sensor(sd);
+-
+-                      if (fimc_is_parse_sensor_config(is->sensor, child)) {
+-                              dev_warn(&is->pdev->dev, "DT parse error: %s\n",
+-                                                       child->full_name);
++                      if (ret < 0 || index >= FIMC_IS_SENSORS_NUM) {
++                              of_node_put(child);
++                              return ret;
+                       }
+-                      pr_debug("%s(): registered subdev: %p\n",
+-                               __func__, sd->name);
++                      index++;
+               }
+       }
+       return 0;
+-
+-e_retry:
+-      of_node_put(child);
+-      return -EPROBE_DEFER;
+ }
+ static int fimc_is_unregister_subdevs(struct fimc_is *is)
+ {
+       fimc_isp_subdev_destroy(&is->isp);
+-      is->sensor = NULL;
+       return 0;
+ }
+@@ -650,7 +638,7 @@ static int fimc_is_hw_open_sensor(struct fimc_is *is,
+       fimc_is_hw_set_intgr0_gd0(is);
+       return fimc_is_wait_event(is, IS_ST_OPEN_SENSOR, 1,
+-                                FIMC_IS_SENSOR_OPEN_TIMEOUT);
++                                sensor->drvdata->open_timeout);
+ }
+@@ -664,8 +652,8 @@ int fimc_is_hw_initialize(struct fimc_is *is)
+       u32 prev_id;
+       int i, ret;
+-      /* Sensor initialization. */
+-      ret = fimc_is_hw_open_sensor(is, is->sensor);
++      /* Sensor initialization. Only one sensor is currently supported. */
++      ret = fimc_is_hw_open_sensor(is, &is->sensor[0]);
+       if (ret < 0)
+               return ret;
+@@ -987,27 +975,20 @@ static int fimc_is_module_init(void)
+ {
+       int ret;
+-      ret = fimc_is_register_sensor_driver();
+-      if (ret < 0)
+-              return ret;
+-
+       ret = fimc_is_register_i2c_driver();
+       if (ret < 0)
+-              goto err_sens;
++              return ret;
+       ret = platform_driver_register(&fimc_is_driver);
+-      if (!ret)
+-              return ret;
+-      fimc_is_unregister_i2c_driver();
+-err_sens:
+-      fimc_is_unregister_sensor_driver();
++      if (ret < 0)
++              fimc_is_unregister_i2c_driver();
++
+       return ret;
+ }
+ static void fimc_is_module_exit(void)
+ {
+-      fimc_is_unregister_sensor_driver();
+       fimc_is_unregister_i2c_driver();
+       platform_driver_unregister(&fimc_is_driver);
+ }
+diff --git a/drivers/media/platform/exynos4-is/fimc-is.h b/drivers/media/platform/exynos4-is/fimc-is.h
+index fc6d1130..ed40bf7 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is.h
++++ b/drivers/media/platform/exynos4-is/fimc-is.h
+@@ -39,7 +39,7 @@
+ #define FIMC_IS_FW_LOAD_TIMEOUT               1000 /* ms */
+ #define FIMC_IS_POWER_ON_TIMEOUT      1000 /* us */
+-#define FIMC_IS_SENSOR_NUM            2
++#define FIMC_IS_SENSORS_NUM           2
+ /* Memory definitions */
+ #define FIMC_IS_CPU_MEM_SIZE          (0xa00000)
+@@ -254,7 +254,7 @@ struct fimc_is {
+       struct firmware                 *f_w;
+       struct fimc_isp                 isp;
+-      struct fimc_is_sensor           *sensor;
++      struct fimc_is_sensor           sensor[FIMC_IS_SENSORS_NUM];
+       struct fimc_is_setfile          setfile;
+       struct vb2_alloc_ctx            *alloc_ctx;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0732-exynos4-is-Add-support-for-asynchronous-sensor-subdd.patch b/patches.tizen/0732-exynos4-is-Add-support-for-asynchronous-sensor-subdd.patch
new file mode 100644 (file)
index 0000000..14fc632
--- /dev/null
@@ -0,0 +1,467 @@
+From 9cb4cf023f4d793ca8d19ae421cc8989dbe63712 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 9 Aug 2013 20:21:10 +0200
+Subject: [PATCH 0732/1302] exynos4-is: Add support for asynchronous sensor
+ subddevs registration
+
+Add support for registering external sensor subdevs using the v4l2-async
+API. The async API is used only for sensor subdevs and only for platforms
+instantiated from Device Tree.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+---
+
+Changes since v1:
+ - register clock provider after registering FIMC devices so the clock
+   can be actually used right after it is registered.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/media/samsung-fimc.txt     |   4 +-
+ drivers/media/platform/exynos4-is/media-dev.c      | 234 ++++++++++++---------
+ drivers/media/platform/exynos4-is/media-dev.h      |  13 +-
+ 3 files changed, 146 insertions(+), 105 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/media/samsung-fimc.txt b/Documentation/devicetree/bindings/media/samsung-fimc.txt
+index 137d540..6e833e1 100644
+--- a/Documentation/devicetree/bindings/media/samsung-fimc.txt
++++ b/Documentation/devicetree/bindings/media/samsung-fimc.txt
+@@ -106,8 +106,8 @@ Image sensor nodes
+ The sensor device nodes should be added to their control bus controller (e.g.
+ I2C0) nodes and linked to a port node in the csis or the parallel-ports node,
+ using the common video interfaces bindings, defined in video-interfaces.txt.
+-The implementation of this bindings requires clock-frequency property to be
+-present in the sensor device nodes.
++An optional clock-frequency property needs to be present in the sensor device
++nodes. Default value when this property is not present is 24 MHz.
+ Example:
+diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
+index 9d3a38f..68a3022 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.c
++++ b/drivers/media/platform/exynos4-is/media-dev.c
+@@ -27,6 +27,7 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/types.h>
+ #include <linux/slab.h>
++#include <media/v4l2-async.h>
+ #include <media/v4l2-ctrls.h>
+ #include <media/v4l2-of.h>
+ #include <media/media-device.h>
+@@ -221,6 +222,7 @@ static int __fimc_pipeline_open(struct exynos_media_pipeline *ep,
+               if (ret < 0)
+                       return ret;
+       }
++
+       ret = fimc_md_set_camclk(sd, true);
+       if (ret < 0)
+               goto err_wbclk;
+@@ -381,77 +383,18 @@ static void fimc_md_unregister_sensor(struct v4l2_subdev *sd)
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct i2c_adapter *adapter;
+-      if (!client)
++      if (!client || client->dev.of_node)
+               return;
+       v4l2_device_unregister_subdev(sd);
+-      if (!client->dev.of_node) {
+-              adapter = client->adapter;
+-              i2c_unregister_device(client);
+-              if (adapter)
+-                      i2c_put_adapter(adapter);
+-      }
++      adapter = client->adapter;
++      i2c_unregister_device(client);
++      if (adapter)
++              i2c_put_adapter(adapter);
+ }
+ #ifdef CONFIG_OF
+-/* Register I2C client subdev associated with @node. */
+-static int fimc_md_of_add_sensor(struct fimc_md *fmd,
+-                               struct device_node *node, int index)
+-{
+-      struct fimc_sensor_info *si;
+-      struct i2c_client *client;
+-      struct v4l2_subdev *sd;
+-      int ret;
+-
+-      if (WARN_ON(index >= ARRAY_SIZE(fmd->sensor)))
+-              return -EINVAL;
+-      si = &fmd->sensor[index];
+-
+-      client = of_find_i2c_device_by_node(node);
+-      if (!client)
+-              return -EPROBE_DEFER;
+-
+-      device_lock(&client->dev);
+-
+-      if (!client->driver ||
+-          !try_module_get(client->driver->driver.owner)) {
+-              ret = -EPROBE_DEFER;
+-              v4l2_info(&fmd->v4l2_dev, "No driver found for %s\n",
+-                                              node->full_name);
+-              goto dev_put;
+-      }
+-
+-      /* Enable sensor's master clock */
+-      ret = __fimc_md_set_camclk(fmd, &si->pdata, true);
+-      if (ret < 0)
+-              goto mod_put;
+-      sd = i2c_get_clientdata(client);
+-
+-      ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
+-      __fimc_md_set_camclk(fmd, &si->pdata, false);
+-      if (ret < 0)
+-              goto mod_put;
+-
+-      v4l2_set_subdev_hostdata(sd, &si->pdata);
+-      if (si->pdata.fimc_bus_type == FIMC_BUS_TYPE_ISP_WRITEBACK)
+-              sd->grp_id = GRP_ID_FIMC_IS_SENSOR;
+-      else
+-              sd->grp_id = GRP_ID_SENSOR;
+-
+-      si->subdev = sd;
+-      v4l2_info(&fmd->v4l2_dev, "Registered sensor subdevice: %s (%d)\n",
+-                sd->name, fmd->num_sensors);
+-      fmd->num_sensors++;
+-
+-mod_put:
+-      module_put(client->driver->driver.owner);
+-dev_put:
+-      device_unlock(&client->dev);
+-      put_device(&client->dev);
+-      return ret;
+-}
+-
+ /* Parse port node and register as a sub-device any sensor specified there. */
+ static int fimc_md_parse_port_node(struct fimc_md *fmd,
+                                  struct device_node *port,
+@@ -460,7 +403,6 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
+       struct device_node *rem, *ep, *np;
+       struct fimc_source_info *pd;
+       struct v4l2_of_endpoint endpoint;
+-      int ret;
+       u32 val;
+       pd = &fmd->sensor[index].pdata;
+@@ -488,6 +430,8 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
+       if (!of_property_read_u32(rem, "clock-frequency", &val))
+               pd->clk_frequency = val;
++      else
++              pd->clk_frequency = DEFAULT_SENSOR_CLK_FREQ;
+       if (pd->clk_frequency == 0) {
+               v4l2_err(&fmd->v4l2_dev, "Wrong clock frequency at node %s\n",
+@@ -527,10 +471,17 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
+       else
+               pd->fimc_bus_type = pd->sensor_bus_type;
+-      ret = fimc_md_of_add_sensor(fmd, rem, index);
+-      of_node_put(rem);
++      if (WARN_ON(index >= ARRAY_SIZE(fmd->sensor)))
++              return -EINVAL;
+-      return ret;
++      fmd->sensor[index].asd.match_type = V4L2_ASYNC_MATCH_OF;
++      fmd->sensor[index].asd.match.of.node = rem;
++      fmd->async_subdevs[index] = &fmd->sensor[index].asd;
++
++      fmd->num_sensors++;
++
++      of_node_put(rem);
++      return 0;
+ }
+ /* Register all SoC external sub-devices */
+@@ -894,11 +845,13 @@ static void fimc_md_unregister_entities(struct fimc_md *fmd)
+               v4l2_device_unregister_subdev(fmd->csis[i].sd);
+               fmd->csis[i].sd = NULL;
+       }
+-      for (i = 0; i < fmd->num_sensors; i++) {
+-              if (fmd->sensor[i].subdev == NULL)
+-                      continue;
+-              fimc_md_unregister_sensor(fmd->sensor[i].subdev);
+-              fmd->sensor[i].subdev = NULL;
++      if (fmd->pdev->dev.of_node == NULL) {
++              for (i = 0; i < fmd->num_sensors; i++) {
++                      if (fmd->sensor[i].subdev == NULL)
++                              continue;
++                      fimc_md_unregister_sensor(fmd->sensor[i].subdev);
++                      fmd->sensor[i].subdev = NULL;
++              }
+       }
+       if (fmd->fimc_is)
+@@ -1242,6 +1195,14 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd,
+       struct fimc_camclk_info *camclk;
+       int ret = 0;
++      /*
++       * When device tree is used the sensor drivers are supposed to
++       * control the clock themselves. This whole function will be
++       * removed once S5PV210 platform is converted to the device tree.
++       */
++      if (fmd->pdev->dev.of_node)
++              return 0;
++
+       if (WARN_ON(si->clk_id >= FIMC_MAX_CAMCLKS) || !fmd || !fmd->pmf)
+               return -EINVAL;
+@@ -1552,6 +1513,56 @@ err:
+ #define fimc_md_unregister_clk_provider(fmd) (0)
+ #endif
++static int subdev_notifier_bound(struct v4l2_async_notifier *notifier,
++                               struct v4l2_subdev *subdev,
++                               struct v4l2_async_subdev *asd)
++{
++      struct fimc_md *fmd = notifier_to_fimc_md(notifier);
++      struct fimc_sensor_info *si = NULL;
++      int i;
++
++      /* Find platform data for this sensor subdev */
++      for (i = 0; i < ARRAY_SIZE(fmd->sensor); i++)
++              if (fmd->sensor[i].asd.match.of.node == subdev->dev->of_node)
++                      si = &fmd->sensor[i];
++
++      if (si == NULL)
++              return -EINVAL;
++
++      v4l2_set_subdev_hostdata(subdev, &si->pdata);
++
++      if (si->pdata.fimc_bus_type == FIMC_BUS_TYPE_ISP_WRITEBACK)
++              subdev->grp_id = GRP_ID_FIMC_IS_SENSOR;
++      else
++              subdev->grp_id = GRP_ID_SENSOR;
++
++      si->subdev = subdev;
++
++      v4l2_info(&fmd->v4l2_dev, "Registered sensor subdevice: %s (%d)\n",
++                subdev->name, fmd->num_sensors);
++
++      fmd->num_sensors++;
++
++      return 0;
++}
++
++static int subdev_notifier_complete(struct v4l2_async_notifier *notifier)
++{
++      struct fimc_md *fmd = notifier_to_fimc_md(notifier);
++      int ret;
++
++      mutex_lock(&fmd->media_dev.graph_mutex);
++
++      ret = fimc_md_create_links(fmd);
++      if (ret < 0)
++              goto unlock;
++
++      ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev);
++unlock:
++      mutex_unlock(&fmd->media_dev.graph_mutex);
++      return ret;
++}
++
+ static int fimc_md_probe(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+@@ -1579,12 +1590,6 @@ static int fimc_md_probe(struct platform_device *pdev)
+       fmd->use_isp = fimc_md_is_isp_available(dev->of_node);
+-      ret = fimc_md_register_clk_provider(fmd);
+-      if (ret < 0) {
+-              v4l2_err(v4l2_dev, "clock provider registration failed\n");
+-              return ret;
+-      }
+-
+       ret = v4l2_device_register(dev, &fmd->v4l2_dev);
+       if (ret < 0) {
+               v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret);
+@@ -1594,64 +1599,86 @@ static int fimc_md_probe(struct platform_device *pdev)
+       ret = media_device_register(&fmd->media_dev);
+       if (ret < 0) {
+               v4l2_err(v4l2_dev, "Failed to register media device: %d\n", ret);
+-              goto err_md;
++              goto err_v4l2_dev;
+       }
+       ret = fimc_md_get_clocks(fmd);
+       if (ret)
+-              goto err_clk;
++              goto err_md;
+       fmd->user_subdev_api = (dev->of_node != NULL);
+-      /* Protect the media graph while we're registering entities */
+-      mutex_lock(&fmd->media_dev.graph_mutex);
+-
+       ret = fimc_md_get_pinctrl(fmd);
+       if (ret < 0) {
+               if (ret != EPROBE_DEFER)
+                       dev_err(dev, "Failed to get pinctrl: %d\n", ret);
+-              goto err_unlock;
++              goto err_clk;
+       }
++      platform_set_drvdata(pdev, fmd);
++
++      /* Protect the media graph while we're registering entities */
++      mutex_lock(&fmd->media_dev.graph_mutex);
++
+       if (dev->of_node)
+               ret = fimc_md_register_of_platform_entities(fmd, dev->of_node);
+       else
+               ret = bus_for_each_dev(&platform_bus_type, NULL, fmd,
+                                               fimc_md_pdev_match);
+-      if (ret)
+-              goto err_unlock;
++      if (ret) {
++              mutex_unlock(&fmd->media_dev.graph_mutex);
++              goto err_clk;
++      }
+       if (dev->platform_data || dev->of_node) {
+               ret = fimc_md_register_sensor_entities(fmd);
+-              if (ret)
+-                      goto err_unlock;
++              if (ret) {
++                      mutex_unlock(&fmd->media_dev.graph_mutex);
++                      goto err_m_ent;
++              }
+       }
+-      ret = fimc_md_create_links(fmd);
+-      if (ret)
+-              goto err_unlock;
++      mutex_unlock(&fmd->media_dev.graph_mutex);
+-      ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev);
++      ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode);
+       if (ret)
+-              goto err_unlock;
++              goto err_m_ent;
++      /*
++       * FIMC platform devices need to be registered before the sclk_cam
++       * clocks provider, as one of these devices needs to be activated
++       * to enable the clock.
++       */
++      ret = fimc_md_register_clk_provider(fmd);
++      if (ret < 0) {
++              v4l2_err(v4l2_dev, "clock provider registration failed\n");
++              goto err_attr;
++      }
+-      ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode);
++      fmd->subdev_notifier.subdevs = fmd->async_subdevs;
++      fmd->subdev_notifier.num_subdevs = fmd->num_sensors;
++      fmd->subdev_notifier.bound = subdev_notifier_bound;
++      fmd->subdev_notifier.complete = subdev_notifier_complete;
++      fmd->num_sensors = 0;
++
++      ret = v4l2_async_notifier_register(&fmd->v4l2_dev,
++                                         &fmd->subdev_notifier);
+       if (ret)
+-              goto err_unlock;
++              goto err_clk_p;
+-      platform_set_drvdata(pdev, fmd);
+-      mutex_unlock(&fmd->media_dev.graph_mutex);
+       return 0;
+-err_unlock:
+-      mutex_unlock(&fmd->media_dev.graph_mutex);
++err_clk_p:
++      fimc_md_unregister_clk_provider(fmd);
++err_attr:
++      device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode);
+ err_clk:
+       fimc_md_put_clocks(fmd);
++err_m_ent:
+       fimc_md_unregister_entities(fmd);
+-      media_device_unregister(&fmd->media_dev);
+ err_md:
++      media_device_unregister(&fmd->media_dev);
++err_v4l2_dev:
+       v4l2_device_unregister(&fmd->v4l2_dev);
+-      fimc_md_unregister_clk_provider(fmd);
+       return ret;
+ }
+@@ -1663,12 +1690,15 @@ static int fimc_md_remove(struct platform_device *pdev)
+               return 0;
+       fimc_md_unregister_clk_provider(fmd);
++      v4l2_async_notifier_unregister(&fmd->subdev_notifier);
++
+       v4l2_device_unregister(&fmd->v4l2_dev);
+       device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode);
+       fimc_md_unregister_entities(fmd);
+       fimc_md_pipelines_free(fmd);
+       media_device_unregister(&fmd->media_dev);
+       fimc_md_put_clocks(fmd);
++
+       return 0;
+ }
+diff --git a/drivers/media/platform/exynos4-is/media-dev.h b/drivers/media/platform/exynos4-is/media-dev.h
+index 240ca71..169972a 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.h
++++ b/drivers/media/platform/exynos4-is/media-dev.h
+@@ -32,8 +32,9 @@
+ #define PINCTRL_STATE_IDLE    "idle"
+-#define FIMC_MAX_SENSORS      8
++#define FIMC_MAX_SENSORS      4
+ #define FIMC_MAX_CAMCLKS      2
++#define DEFAULT_SENSOR_CLK_FREQ       24000000U
+ /* LCD/ISP Writeback clocks (PIXELASYNCMx) */
+ enum {
+@@ -79,6 +80,7 @@ struct fimc_camclk_info {
+ /**
+  * struct fimc_sensor_info - image data source subdev information
+  * @pdata: sensor's atrributes passed as media device's platform data
++ * @asd: asynchronous subdev registration data structure
+  * @subdev: image sensor v4l2 subdev
+  * @host: fimc device the sensor is currently linked to
+  *
+@@ -86,6 +88,7 @@ struct fimc_camclk_info {
+  */
+ struct fimc_sensor_info {
+       struct fimc_source_info pdata;
++      struct v4l2_async_subdev asd;
+       struct v4l2_subdev *subdev;
+       struct fimc_dev *host;
+ };
+@@ -144,6 +147,9 @@ struct fimc_md {
+               struct cam_clk camclk[FIMC_MAX_CAMCLKS];
+       } clk_provider;
++      struct v4l2_async_notifier subdev_notifier;
++      struct v4l2_async_subdev *async_subdevs[FIMC_MAX_SENSORS];
++
+       bool user_subdev_api;
+       spinlock_t slock;
+       struct list_head pipelines;
+@@ -161,6 +167,11 @@ static inline struct fimc_md *entity_to_fimc_mdev(struct media_entity *me)
+               container_of(me->parent, struct fimc_md, media_dev);
+ }
++static inline struct fimc_md *notifier_to_fimc_md(struct v4l2_async_notifier *n)
++{
++      return container_of(n, struct fimc_md, subdev_notifier);
++}
++
+ static inline void fimc_md_graph_lock(struct exynos_video_entity *ve)
+ {
+       mutex_lock(&ve->vdev.entity.parent->graph_mutex);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0733-Revert-s5k5baf-add-camera-sensor-driver.patch b/patches.tizen/0733-Revert-s5k5baf-add-camera-sensor-driver.patch
new file mode 100644 (file)
index 0000000..70c2025
--- /dev/null
@@ -0,0 +1,2166 @@
+From 1b4afa85593df1b2c24a44e034590deb2c3acc65 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Mon, 2 Sep 2013 16:14:19 +0200
+Subject: [PATCH 0733/1302] Revert "s5k5baf: add camera sensor driver"
+
+This reverts commit 80ca90cdf56ed7a375e31275fde4282e22f8edba.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/media/samsung-s5k5baf.txt  |   53 -
+ MAINTAINERS                                        |    8 -
+ drivers/media/i2c/Kconfig                          |    7 -
+ drivers/media/i2c/Makefile                         |    1 -
+ drivers/media/i2c/s5k5baf.c                        | 1986 --------------------
+ include/uapi/linux/s5k5baf.h                       |   19 -
+ include/uapi/linux/v4l2-controls.h                 |    5 -
+ 7 files changed, 2079 deletions(-)
+ delete mode 100644 Documentation/devicetree/bindings/media/samsung-s5k5baf.txt
+ delete mode 100644 drivers/media/i2c/s5k5baf.c
+ delete mode 100644 include/uapi/linux/s5k5baf.h
+
+diff --git a/Documentation/devicetree/bindings/media/samsung-s5k5baf.txt b/Documentation/devicetree/bindings/media/samsung-s5k5baf.txt
+deleted file mode 100644
+index 0e46743..0000000
+--- a/Documentation/devicetree/bindings/media/samsung-s5k5baf.txt
++++ /dev/null
+@@ -1,53 +0,0 @@
+-Samsung S5K5BAF UXGA 1/5" 2M CMOS Image Sensor with embedded SoC ISP
+--------------------------------------------------------------
+-
+-Required properties:
+-
+-- compatible    : "samsung,s5k5baf";
+-- reg           : i2c slave address of the sensor;
+-- vdda-supply   : analog power supply 2.8V (2.6V to 3.0V);
+-- vddreg-supply         : regulator input power supply 1.8V (1.7V to 1.9V)
+-                    or 2.8V (2.6V to 3.0);
+-- vddio-supply          : I/O power supply 1.8V (1.65V to 1.95V)
+-                    or 2.8V (2.5V to 3.1V);
+-- gpios                 : GPIOs connected to STDBYN and RSTN pins,
+-                    in order: STBYN, RSTN;
+-- clock-frequency : master clock frequency in Hz;
+-
+-Optional properties:
+-
+-- clocks        : contains the sensor's master clock specifier;
+-- clock-names   : contains "mclk" entry;
+-- samsung,hflip         : horizontal image flip;
+-- samsung,vflip         : vertical image flip;
+-
+-The device node should contain one 'port' child node with one child 'endpoint'
+-node, according to the bindings defined in Documentation/devicetree/bindings/
+-media/video-interfaces.txt. The following are properties specific to those nodes.
+-
+-endpoint node
+--------------
+-
+-- data-lanes    : (optional) an array specifying active physical MIPI-CSI2
+-                  data output lanes and their mapping to logical lanes; the
+-                  array's content is unused, only its length is meaningful;
+-
+-Example:
+-
+-s5k5bafx@2d {
+-      compatible = "samsung,s5k5baf";
+-      reg = <0x2d>;
+-      vdda-supply = <&cam_io_en_reg>;
+-      vdd_reg-supply = <&vt_core_15v_reg>;
+-      vddio-supply = <&vtcam_reg>;
+-      gpios = <&gpl2 0 1>,
+-              <&gpl2 1 1>;
+-      clock-frequency = <24000000>;
+-
+-      port {
+-              s5k5bafx_ep: endpoint {
+-                      remote-endpoint = <&csis1_ep>;
+-                      data-lanes = <1>;
+-              };
+-      };
+-};
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 761de43..7684a09 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -6987,14 +6987,6 @@ L:      linux-media@vger.kernel.org
+ S:    Supported
+ F:    drivers/media/i2c/s5c73m3/*
+-SAMSUNG S5K5BAF CAMERA DRIVER
+-M:    Kyungmin Park <kyungmin.park@samsung.com>
+-M:    Andrzej Hajda <a.hajda@samsung.com>
+-L:    linux-media@vger.kernel.org
+-S:    Supported
+-F:    drivers/media/i2c/s5k5baf.c
+-F:    include/media/s5k5baf.h
+-
+ SERIAL DRIVERS
+ M:    Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ L:    linux-serial@vger.kernel.org
+diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
+index 24407cc..9625c5c 100644
+--- a/drivers/media/i2c/Kconfig
++++ b/drivers/media/i2c/Kconfig
+@@ -561,13 +561,6 @@ config VIDEO_S5K4ECGX
+           This is a V4L2 sensor-level driver for Samsung S5K4ECGX 5M
+           camera sensor with an embedded SoC image signal processor.
+-config VIDEO_S5K5BAF
+-      tristate "Samsung S5K5BAF sensor support"
+-      depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+-      ---help---
+-        This is a V4L2 sensor-level driver for Samsung S5K5BAF 2M
+-        camera sensor with an embedded SoC image signal processor.
+-
+ source "drivers/media/i2c/smiapp/Kconfig"
+ config VIDEO_S5C73M3
+diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
+index ef4b169..960fc1e 100644
+--- a/drivers/media/i2c/Makefile
++++ b/drivers/media/i2c/Makefile
+@@ -65,7 +65,6 @@ obj-$(CONFIG_VIDEO_NOON010PC30)      += noon010pc30.o
+ obj-$(CONFIG_VIDEO_S5K6AA)    += s5k6aa.o
+ obj-$(CONFIG_VIDEO_S5K6A3)    += s5k6a3.o
+ obj-$(CONFIG_VIDEO_S5K4ECGX)  += s5k4ecgx.o
+-obj-$(CONFIG_VIDEO_S5K5BAF)   += s5k5baf.o
+ obj-$(CONFIG_VIDEO_S5C73M3)   += s5c73m3/
+ obj-$(CONFIG_VIDEO_ADP1653)   += adp1653.o
+ obj-$(CONFIG_VIDEO_AS3645A)   += as3645a.o
+diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
+deleted file mode 100644
+index cb4eec0..0000000
+--- a/drivers/media/i2c/s5k5baf.c
++++ /dev/null
+@@ -1,1986 +0,0 @@
+-/*
+- * Driver for Samsung S5K5BAF UXGA 1/5" 2M CMOS Image Sensor
+- * with embedded SoC ISP.
+- *
+- * Copyright (C) 2013, Samsung Electronics Co., Ltd.
+- * Andrzej Hajda <a.hajda@samsung.com>
+- *
+- * Based on S5K6AA driver authored by Sylwester Nawrocki
+- * Copyright (C) 2013, Samsung Electronics Co., Ltd.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- */
+-
+-#include <linux/clk.h>
+-#include <linux/delay.h>
+-#include <linux/gpio.h>
+-#include <linux/i2c.h>
+-#include <linux/media.h>
+-#include <linux/module.h>
+-#include <linux/of_gpio.h>
+-#include <linux/regulator/consumer.h>
+-#include <linux/s5k5baf.h>
+-#include <linux/slab.h>
+-
+-#include <media/media-entity.h>
+-#include <media/v4l2-ctrls.h>
+-#include <media/v4l2-device.h>
+-#include <media/v4l2-subdev.h>
+-#include <media/v4l2-mediabus.h>
+-#include <media/v4l2-of.h>
+-
+-static int debug;
+-module_param(debug, int, 0644);
+-
+-#define S5K5BAF_DRIVER_NAME           "s5k5baf"
+-
+-#define S5K5BAF_OUT_WIDTH_DEF         640
+-#define S5K5BAF_OUT_HEIGHT_DEF                480
+-#define S5K5BAF_CIS_WIDTH             1600
+-#define S5K5BAF_CIS_HEIGHT            1200
+-#define S5K5BAF_WIN_WIDTH_MIN         8
+-#define S5K5BAF_WIN_HEIGHT_MIN                8
+-
+-#define AHB_MSB_ADDR_PTR              0xfcfc
+-
+-/*
+- * Register interface pages (the most significant word of the address)
+- */
+-#define PAGE_IF_HW                    0xd000
+-#define PAGE_IF_SW                    0x7000
+-
+-/*
+- * H/W register Interface (PAGE_IF_HW)
+- */
+-#define REG_SW_LOAD_COMPLETE          0x0014
+-#define REG_CMDWR_PAGE                        0x0028
+-#define REG_CMDWR_ADDR                        0x002a
+-#define REG_CMDRD_PAGE                        0x002c
+-#define REG_CMDRD_ADDR                        0x002e
+-#define REG_CMD_BUF                   0x0f12
+-#define REG_SET_HOST_INT              0x1000
+-#define REG_CLEAR_HOST_INT            0x1030
+-#define REG_PATTERN_SET                       0x3100
+-#define REG_PATTERN_WIDTH             0x3118
+-#define REG_PATTERN_HEIGHT            0x311a
+-#define REG_PATTERN_PARAM             0x311c
+-
+-/*
+- * S/W register interface (PAGE_IF_SW)
+- */
+-
+-/* Firmware revision information */
+-#define REG_FW_APIVER                 0x012e
+-#define  S5K5BAF_FW_APIVER            0x0001
+-#define REG_FW_REVISION                       0x0130
+-#define REG_FW_SENSOR_ID              0x0152
+-
+-/* Initialization parameters */
+-/* Master clock frequency in KHz */
+-#define REG_I_INCLK_FREQ_L            0x01b8
+-#define REG_I_INCLK_FREQ_H            0x01ba
+-#define  MIN_MCLK_FREQ_KHZ            6000U
+-#define  MAX_MCLK_FREQ_KHZ            48000U
+-#define REG_I_USE_NPVI_CLOCKS         0x01c6
+-#define  NPVI_CLOCKS                  1
+-#define REG_I_USE_NMIPI_CLOCKS                0x01c8
+-#define  NMIPI_CLOCKS                 1
+-#define REG_I_BLOCK_INTERNAL_PLL_CALC 0x01ca
+-
+-/* Clock configurations, n = 0..2. REG_I_* frequency unit is 4 kHz. */
+-#define REG_I_OPCLK_4KHZ(n)           ((n) * 6 + 0x01cc)
+-#define REG_I_MIN_OUTRATE_4KHZ(n)     ((n) * 6 + 0x01ce)
+-#define REG_I_MAX_OUTRATE_4KHZ(n)     ((n) * 6 + 0x01d0)
+-#define  SCLK_PVI_FREQ                        24000
+-#define  SCLK_MIPI_FREQ                       48000
+-#define  PCLK_MIN_FREQ                        6000
+-#define  PCLK_MAX_FREQ                        48000
+-#define REG_I_USE_REGS_API            0x01de
+-#define REG_I_INIT_PARAMS_UPDATED     0x01e0
+-#define REG_I_ERROR_INFO              0x01e2
+-
+-/* General purpose parameters */
+-#define REG_USER_BRIGHTNESS           0x01e4
+-#define REG_USER_CONTRAST             0x01e6
+-#define REG_USER_SATURATION           0x01e8
+-#define REG_USER_SHARPBLUR            0x01ea
+-
+-#define REG_G_SPEC_EFFECTS            0x01ee
+-#define REG_G_ENABLE_PREV             0x01f0
+-#define REG_G_ENABLE_PREV_CHG         0x01f2
+-#define REG_G_NEW_CFG_SYNC            0x01f8
+-#define REG_G_PREVREQ_IN_WIDTH                0x01fa
+-#define REG_G_PREVREQ_IN_HEIGHT               0x01fc
+-#define REG_G_PREVREQ_IN_XOFFS                0x01fe
+-#define REG_G_PREVREQ_IN_YOFFS                0x0200
+-#define REG_G_PREVZOOM_IN_WIDTH               0x020a
+-#define REG_G_PREVZOOM_IN_HEIGHT      0x020c
+-#define REG_G_PREVZOOM_IN_XOFFS               0x020e
+-#define REG_G_PREVZOOM_IN_YOFFS               0x0210
+-#define REG_G_INPUTS_CHANGE_REQ               0x021a
+-#define REG_G_ACTIVE_PREV_CFG         0x021c
+-#define REG_G_PREV_CFG_CHG            0x021e
+-#define REG_G_PREV_OPEN_AFTER_CH      0x0220
+-#define REG_G_PREV_CFG_ERROR          0x0222
+-#define  CFG_ERROR_RANGE              0x0b
+-#define REG_G_PREV_CFG_BYPASS_CHANGED 0x022a
+-#define REG_G_ACTUAL_P_FR_TIME                0x023a
+-#define REG_G_ACTUAL_P_OUT_RATE               0x023c
+-#define REG_G_ACTUAL_C_FR_TIME                0x023e
+-#define REG_G_ACTUAL_C_OUT_RATE               0x0240
+-
+-/* Preview control section. n = 0...4. */
+-#define PREG(n, x)                    ((n) * 0x26 + x)
+-#define REG_P_OUT_WIDTH(n)            PREG(n, 0x0242)
+-#define REG_P_OUT_HEIGHT(n)           PREG(n, 0x0244)
+-#define REG_P_FMT(n)                  PREG(n, 0x0246)
+-#define REG_P_MAX_OUT_RATE(n)         PREG(n, 0x0248)
+-#define REG_P_MIN_OUT_RATE(n)         PREG(n, 0x024a)
+-#define REG_P_PVI_MASK(n)             PREG(n, 0x024c)
+-#define  PVI_MASK_MIPI                        0x52
+-#define REG_P_CLK_INDEX(n)            PREG(n, 0x024e)
+-#define  CLK_PVI_INDEX                        0
+-#define  CLK_MIPI_INDEX                       NPVI_CLOCKS
+-#define REG_P_FR_RATE_TYPE(n)         PREG(n, 0x0250)
+-#define  FR_RATE_DYNAMIC              0
+-#define  FR_RATE_FIXED                        1
+-#define  FR_RATE_FIXED_ACCURATE               2
+-#define REG_P_FR_RATE_Q_TYPE(n)               PREG(n, 0x0252)
+-#define  FR_RATE_Q_DYNAMIC            0
+-#define  FR_RATE_Q_BEST_FRRATE                1 /* Binning enabled */
+-#define  FR_RATE_Q_BEST_QUALITY               2 /* Binning disabled */
+-/* Frame period in 0.1 ms units */
+-#define REG_P_MAX_FR_TIME(n)          PREG(n, 0x0254)
+-#define REG_P_MIN_FR_TIME(n)          PREG(n, 0x0256)
+-#define  S5K5BAF_MIN_FR_TIME          333  /* x100 us */
+-#define  S5K5BAF_MAX_FR_TIME          6500 /* x100 us */
+-/* The below 5 registers are for "device correction" values */
+-#define REG_P_SATURATION(n)           PREG(n, 0x0258)
+-#define REG_P_SHARP_BLUR(n)           PREG(n, 0x025a)
+-#define REG_P_GLAMOUR(n)              PREG(n, 0x025c)
+-#define REG_P_COLORTEMP(n)            PREG(n, 0x025e)
+-#define REG_P_GAMMA_INDEX(n)          PREG(n, 0x0260)
+-#define REG_P_PREV_MIRROR(n)          PREG(n, 0x0262)
+-#define REG_P_CAP_MIRROR(n)           PREG(n, 0x0264)
+-#define REG_P_CAP_ROTATION(n)         PREG(n, 0x0266)
+-
+-/* Extended image property controls */
+-/* Exposure time in 10 us units */
+-#define REG_SF_USR_EXPOSURE_L         0x03bc
+-#define REG_SF_USR_EXPOSURE_H         0x03be
+-#define REG_SF_USR_EXPOSURE_CHG               0x03c0
+-#define REG_SF_USR_TOT_GAIN           0x03c2
+-#define REG_SF_USR_TOT_GAIN_CHG               0x03c4
+-#define REG_SF_RGAIN                  0x03c6
+-#define REG_SF_RGAIN_CHG              0x03c8
+-#define REG_SF_GGAIN                  0x03ca
+-#define REG_SF_GGAIN_CHG              0x03cc
+-#define REG_SF_BGAIN                  0x03ce
+-#define REG_SF_BGAIN_CHG              0x03d0
+-#define REG_SF_WBGAIN_CHG             0x03d2
+-#define REG_SF_FLICKER_QUANT          0x03d4
+-#define REG_SF_FLICKER_QUANT_CHG      0x03d6
+-
+-/* Output interface (parallel/MIPI) setup */
+-#define REG_OIF_EN_MIPI_LANES         0x03f2
+-#define REG_OIF_EN_PACKETS            0x03f4
+-#define  EN_PACKETS_CSI2              0xc3
+-#define REG_OIF_CFG_CHG                       0x03f6
+-
+-/* Auto-algorithms enable mask */
+-#define REG_DBG_AUTOALG_EN            0x03f8
+-#define  AALG_ALL_EN                  BIT(0)
+-#define  AALG_AE_EN                   BIT(1)
+-#define  AALG_DIVLEI_EN                       BIT(2)
+-#define  AALG_WB_EN                   BIT(3)
+-#define  AALG_USE_WB_FOR_ISP          BIT(4)
+-#define  AALG_FLICKER_EN              BIT(5)
+-#define  AALG_FIT_EN                  BIT(6)
+-#define  AALG_WRHW_EN                 BIT(7)
+-
+-#define REG_PTR_CCM_HORIZON           0x06d0
+-#define REG_PTR_CCM_INCANDESCENT      0x06d4
+-#define REG_PTR_CCM_WARM_WHITE                0x06d8
+-#define REG_PTR_CCM_COOL_WHITE                0x06dc
+-#define REG_PTR_CCM_DL50              0x06e0
+-#define REG_PTR_CCM_DL65              0x06e4
+-#define REG_PTR_CCM_OUTDOOR           0x06ec
+-
+-#define REG_ARR_CCM(n)                        (0x2800 + 36 * (n))
+-
+-static const char * const s5k5baf_supply_names[] = {
+-      "vdda",         /* Analog power supply 2.8V (2.6V to 3.0V) */
+-      "vddreg",       /* Regulator input power supply 1.8V (1.7V to 1.9V)
+-                         or 2.8V (2.6V to 3.0) */
+-      "vddio",        /* I/O power supply 1.8V (1.65V to 1.95V)
+-                         or 2.8V (2.5V to 3.1V) */
+-};
+-#define S5K5BAF_NUM_SUPPLIES ARRAY_SIZE(s5k5baf_supply_names)
+-
+-struct s5k5baf_gpio {
+-      int gpio;
+-      int level;
+-};
+-
+-enum s5k5baf_gpio_id {
+-      STBY,
+-      RST,
+-      GPIO_NUM,
+-};
+-
+-struct s5k5baf_pixfmt {
+-      enum v4l2_mbus_pixelcode code;
+-      u32 colorspace;
+-      /* REG_P_FMT(x) register value */
+-      u16 reg_p_fmt;
+-};
+-
+-struct s5k5baf_ctrls {
+-      struct v4l2_ctrl_handler handler;
+-      struct { /* Auto / manual white balance cluster */
+-              struct v4l2_ctrl *awb;
+-              struct v4l2_ctrl *gain_red;
+-              struct v4l2_ctrl *gain_blue;
+-              struct v4l2_ctrl *gain_green;
+-      };
+-      struct { /* Mirror cluster */
+-              struct v4l2_ctrl *hflip;
+-              struct v4l2_ctrl *vflip;
+-      };
+-      struct { /* Auto exposure / manual exposure and gain cluster */
+-              struct v4l2_ctrl *auto_exp;
+-              struct v4l2_ctrl *exposure;
+-              struct v4l2_ctrl *gain;
+-      };
+-};
+-
+-struct s5k5baf {
+-      u32 mclk_frequency;
+-      struct s5k5baf_gpio gpios[2];
+-      enum v4l2_mbus_type bus_type;
+-      u8 nlanes;
+-      u8 hflip:1;
+-      u8 vflip:1;
+-      struct regulator_bulk_data supplies[S5K5BAF_NUM_SUPPLIES];
+-
+-      struct v4l2_subdev cis_sd;
+-      struct media_pad cis_pad;
+-
+-      struct v4l2_subdev sd;
+-      struct media_pad pads[2];
+-
+-      /* protects the struct members below */
+-      struct mutex lock;
+-
+-      int error;
+-
+-      struct v4l2_rect crop_sink;
+-      struct v4l2_rect compose;
+-      struct v4l2_rect crop_source;
+-      /* index to s5k5baf_formats array */
+-      int pixfmt;
+-      /* actual frame interval in 100us */
+-      u16 fiv;
+-      /* requested frame interval in 100us */
+-      u16 req_fiv;
+-
+-      struct s5k5baf_ctrls ctrls;
+-
+-      unsigned int streaming:1;
+-      unsigned int apply_cfg:1;
+-      unsigned int apply_crop:1;
+-      unsigned int power;
+-};
+-
+-static const struct s5k5baf_pixfmt s5k5baf_formats[] = {
+-      { V4L2_MBUS_FMT_VYUY8_2X8,      V4L2_COLORSPACE_JPEG,   5 },
+-      /* range 16-240 */
+-      { V4L2_MBUS_FMT_VYUY8_2X8,      V4L2_COLORSPACE_REC709, 6 },
+-      { V4L2_MBUS_FMT_RGB565_2X8_BE,  V4L2_COLORSPACE_JPEG,   0 },
+-};
+-
+-static struct v4l2_rect s5k5baf_cis_rect = { 0, 0, S5K5BAF_CIS_WIDTH,
+-                                   S5K5BAF_CIS_HEIGHT };
+-static struct v4l2_rect s5k5baf_def_rect = { 0, 0, S5K5BAF_OUT_WIDTH_DEF,
+-                                   S5K5BAF_OUT_HEIGHT_DEF };
+-
+-static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
+-{
+-      return &container_of(ctrl->handler, struct s5k5baf, ctrls.handler)->sd;
+-}
+-
+-static inline bool s5k5baf_is_cis_subdev(struct v4l2_subdev *sd)
+-{
+-      return sd->entity.type == MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
+-}
+-
+-static inline struct s5k5baf *to_s5k5baf(struct v4l2_subdev *sd)
+-{
+-      if (s5k5baf_is_cis_subdev(sd))
+-              return container_of(sd, struct s5k5baf, cis_sd);
+-      else
+-              return container_of(sd, struct s5k5baf, sd);
+-}
+-
+-static u16 s5k5baf_i2c_read(struct s5k5baf *state, u16 addr)
+-{
+-      struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
+-      u16 w, r;
+-      struct i2c_msg msg[] = {
+-              {.addr = c->addr, .flags = 0, .len = 2, .buf = (u8 *)&w},
+-              {.addr = c->addr, .flags = I2C_M_RD, .len = 2, .buf = (u8 *)&r},
+-      };
+-      int ret;
+-
+-      if (state->error)
+-              return 0;
+-
+-      w = htons(addr);
+-      ret = i2c_transfer(c->adapter, msg, 2);
+-      r = ntohs(r);
+-
+-      v4l2_dbg(3, debug, c, "i2c_read: 0x%04x : 0x%04x\n", addr, r);
+-
+-      if (ret != 2) {
+-              v4l2_err(c, "i2c_read: error during transfer (%d)\n", ret);
+-              state->error = ret;
+-      }
+-      return r;
+-}
+-
+-static void s5k5baf_i2c_write(struct s5k5baf *state, u16 addr, u16 val)
+-{
+-      u8 buf[4] = { addr >> 8, addr & 0xFF, val >> 8, val & 0xFF };
+-      struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
+-      int ret;
+-
+-      if (state->error)
+-              return;
+-
+-      ret = i2c_master_send(c, buf, 4);
+-      v4l2_dbg(3, debug, c, "i2c_write: 0x%04x : 0x%04x\n", addr, val);
+-
+-      if (ret != 4) {
+-              v4l2_err(c, "i2c_write: error during transfer (%d)\n", ret);
+-              state->error = ret;
+-      }
+-}
+-
+-static u16 s5k5baf_read(struct s5k5baf *state, u16 addr)
+-{
+-      s5k5baf_i2c_write(state, REG_CMDRD_ADDR, addr);
+-      return s5k5baf_i2c_read(state, REG_CMD_BUF);
+-}
+-
+-static void s5k5baf_write(struct s5k5baf *state, u16 addr, u16 val)
+-{
+-      s5k5baf_i2c_write(state, REG_CMDWR_ADDR, addr);
+-      s5k5baf_i2c_write(state, REG_CMD_BUF, val);
+-}
+-
+-static void s5k5baf_write_arr_seq(struct s5k5baf *state, u16 addr,
+-                                u16 count, const u16 *seq)
+-{
+-      struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
+-      u16 buf[count + 1];
+-      int ret, n;
+-
+-      s5k5baf_i2c_write(state, REG_CMDWR_ADDR, addr);
+-      if (state->error)
+-              return;
+-
+-      buf[0] = __constant_htons(REG_CMD_BUF);
+-      for (n = 1; n <= count; ++n)
+-              buf[n] = htons(*seq++);
+-
+-      n *= 2;
+-      ret = i2c_master_send(c, (char *)buf, n);
+-      v4l2_dbg(3, debug, c, "i2c_write_seq(count=%d): %*ph\n", count,
+-               min(2 * count, 64), seq - count);
+-
+-      if (ret != n) {
+-              v4l2_err(c, "i2c_write_seq: error during transfer (%d)\n", ret);
+-              state->error = ret;
+-      }
+-}
+-
+-#define s5k5baf_write_seq(state, addr, seq...) \
+-      s5k5baf_write_arr_seq(state, addr, sizeof((char[]){ seq }), \
+-                            (const u16 []){ seq });
+-
+-/* add items count at the beginning of the list */
+-#define NSEQ(seq...) sizeof((char[]){ seq }), seq
+-
+-/*
+- * s5k5baf_write_nseq() - Writes sequences of values to sensor memory via i2c
+- * @nseq: sequence of u16 words in format:
+- *    (N, address, value[1]...value[N-1])*,0
+- * Ex.:
+- *    u16 seq[] = { NSEQ(0x4000, 1, 1), NSEQ(0x4010, 640, 480), 0 };
+- *    ret = s5k5baf_write_nseq(c, seq);
+- */
+-static void s5k5baf_write_nseq(struct s5k5baf *state, const u16 *nseq)
+-{
+-      int count;
+-
+-      while ((count = *nseq++)) {
+-              u16 addr = *nseq++;
+-              --count;
+-
+-              s5k5baf_write_arr_seq(state, addr, count, nseq);
+-              nseq += count;
+-      }
+-}
+-
+-static void s5k5baf_synchronize(struct s5k5baf *state, int timeout, u16 addr)
+-{
+-      unsigned long end = jiffies + msecs_to_jiffies(timeout);
+-      u16 reg;
+-
+-      s5k5baf_write(state, addr, 1);
+-      do {
+-              reg = s5k5baf_read(state, addr);
+-              if (state->error || !reg)
+-                      return;
+-              usleep_range(5000, 10000);
+-      } while (time_is_after_jiffies(end));
+-
+-      v4l2_err(&state->sd, "timeout on register synchronize (%#x)\n", addr);
+-      state->error = -ETIMEDOUT;
+-}
+-
+-static void s5k5baf_hw_patch(struct s5k5baf *state)
+-{
+-      static const u16 nseq_patch[] = {
+-              NSEQ(0x1668,
+-              0xb5fe, 0x0007, 0x683c, 0x687e, 0x1da5, 0x88a0, 0x2800, 0xd00b,
+-              0x88a8, 0x2800, 0xd008, 0x8820, 0x8829, 0x4288, 0xd301, 0x1a40,
+-              0xe000, 0x1a08, 0x9001, 0xe001, 0x2019, 0x9001, 0x4916, 0x466b,
+-              0x8a48, 0x8118, 0x8a88, 0x8158, 0x4814, 0x8940, 0x0040, 0x2103,
+-              0xf000, 0xf826, 0x88a1, 0x4288, 0xd908, 0x8828, 0x8030, 0x8868,
+-              0x8070, 0x88a8, 0x6038, 0xbcfe, 0xbc08, 0x4718, 0x88a9, 0x4288,
+-              0xd906, 0x8820, 0x8030, 0x8860, 0x8070, 0x88a0, 0x6038, 0xe7f2,
+-              0x9801, 0xa902, 0xf000, 0xf812, 0x0033, 0x0029, 0x9a02, 0x0020,
+-              0xf000, 0xf814, 0x6038, 0xe7e6, 0x1a28, 0x7000, 0x0d64, 0x7000,
+-              0x4778, 0x46c0, 0xf004, 0xe51f, 0xa464, 0x0000, 0x4778, 0x46c0,
+-              0xc000, 0xe59f, 0xff1c, 0xe12f, 0x6009, 0x0000, 0x4778, 0x46c0,
+-              0xc000, 0xe59f, 0xff1c, 0xe12f, 0x622f, 0x0000),
+-              NSEQ(0x2080,
+-              0xb510, 0xf000, 0xf8f4, 0xbc10, 0xbc08, 0x4718, 0xb5f0, 0xb08b,
+-              0x0006, 0x2000, 0x9004, 0x6835, 0x6874, 0x68b0, 0x900a, 0x68f0,
+-              0x9009, 0x4f7d, 0x8979, 0x084a, 0x88a8, 0x88a3, 0x4298, 0xd300,
+-              0x0018, 0xf000, 0xf907, 0x9007, 0x0021, 0x0028, 0xaa04, 0xf000,
+-              0xf909, 0x9006, 0x88a8, 0x2800, 0xd102, 0x27ff, 0x1c7f, 0xe047,
+-              0x88a0, 0x2800, 0xd101, 0x2700, 0xe042, 0x8820, 0x466b, 0x8198,
+-              0x8860, 0x81d8, 0x8828, 0x8118, 0x8868, 0x8158, 0xa802, 0xc803,
+-              0xf000, 0xf8f8, 0x9008, 0x8aba, 0x9808, 0x466b, 0x4342, 0x9202,
+-              0x8820, 0x8198, 0x8860, 0x81d8, 0x980a, 0x9903, 0xf000, 0xf8ea,
+-              0x9a02, 0x17d1, 0x0e09, 0x1889, 0x1209, 0x4288, 0xdd1f, 0x8820,
+-              0x466b, 0x8198, 0x8860, 0x81d8, 0x980a, 0x9903, 0xf000, 0xf8da,
+-              0x9001, 0x8828, 0x466b, 0x8118, 0x8868, 0x8158, 0x980a, 0x9902,
+-              0xf000, 0xf8d0, 0x8ab9, 0x9a08, 0x4351, 0x17ca, 0x0e12, 0x1851,
+-              0x120a, 0x9901, 0xf000, 0xf8b6, 0x0407, 0x0c3f, 0xe000, 0x2700,
+-              0x8820, 0x466b, 0xaa05, 0x8198, 0x8860, 0x81d8, 0x8828, 0x8118,
+-              0x8868, 0x8158, 0xa802, 0xc803, 0x003b, 0xf000, 0xf8bb, 0x88a1,
+-              0x88a8, 0x003a, 0xf000, 0xf8be, 0x0004, 0xa804, 0xc803, 0x9a09,
+-              0x9b07, 0xf000, 0xf8af, 0xa806, 0xc805, 0x0021, 0xf000, 0xf8b2,
+-              0x6030, 0xb00b, 0xbcf0, 0xbc08, 0x4718, 0xb5f1, 0x9900, 0x680c,
+-              0x493a, 0x694b, 0x698a, 0x4694, 0x69cd, 0x6a0e, 0x4f38, 0x42bc,
+-              0xd800, 0x0027, 0x4937, 0x6b89, 0x0409, 0x0c09, 0x4a35, 0x1e92,
+-              0x6bd2, 0x0412, 0x0c12, 0x429f, 0xd801, 0x0020, 0xe031, 0x001f,
+-              0x434f, 0x0a3f, 0x42a7, 0xd301, 0x0018, 0xe02a, 0x002b, 0x434b,
+-              0x0a1b, 0x42a3, 0xd303, 0x0220, 0xf000, 0xf88c, 0xe021, 0x0029,
+-              0x4351, 0x0a09, 0x42a1, 0xd301, 0x0028, 0xe01a, 0x0031, 0x4351,
+-              0x0a09, 0x42a1, 0xd304, 0x0220, 0x0011, 0xf000, 0xf87b, 0xe010,
+-              0x491e, 0x8c89, 0x000a, 0x4372, 0x0a12, 0x42a2, 0xd301, 0x0030,
+-              0xe007, 0x4662, 0x434a, 0x0a12, 0x42a2, 0xd302, 0x0220, 0xf000,
+-              0xf869, 0x4b16, 0x4d18, 0x8d99, 0x1fca, 0x3af9, 0xd00a, 0x2001,
+-              0x0240, 0x8468, 0x0220, 0xf000, 0xf85d, 0x9900, 0x6008, 0xbcf8,
+-              0xbc08, 0x4718, 0x8d19, 0x8469, 0x9900, 0x6008, 0xe7f7, 0xb570,
+-              0x2200, 0x490e, 0x480e, 0x2401, 0xf000, 0xf852, 0x0022, 0x490d,
+-              0x480d, 0x2502, 0xf000, 0xf84c, 0x490c, 0x480d, 0x002a, 0xf000,
+-              0xf847, 0xbc70, 0xbc08, 0x4718, 0x0d64, 0x7000, 0x0470, 0x7000,
+-              0xa120, 0x0007, 0x0402, 0x7000, 0x14a0, 0x7000, 0x208d, 0x7000,
+-              0x622f, 0x0000, 0x1669, 0x7000, 0x6445, 0x0000, 0x21ab, 0x7000,
+-              0x2aa9, 0x0000, 0x4778, 0x46c0, 0xc000, 0xe59f, 0xff1c, 0xe12f,
+-              0x5f49, 0x0000, 0x4778, 0x46c0, 0xc000, 0xe59f, 0xff1c, 0xe12f,
+-              0x5fc7, 0x0000, 0x4778, 0x46c0, 0xc000, 0xe59f, 0xff1c, 0xe12f,
+-              0x5457, 0x0000, 0x4778, 0x46c0, 0xc000, 0xe59f, 0xff1c, 0xe12f,
+-              0x5fa3, 0x0000, 0x4778, 0x46c0, 0xc000, 0xe59f, 0xff1c, 0xe12f,
+-              0x51f9, 0x0000, 0x4778, 0x46c0, 0xf004, 0xe51f, 0xa464, 0x0000,
+-              0x4778, 0x46c0, 0xc000, 0xe59f, 0xff1c, 0xe12f, 0xa007, 0x0000,
+-              0x6546, 0x2062, 0x3120, 0x3220, 0x3130, 0x0030, 0xe010, 0x0208,
+-              0x0058, 0x0000),
+-              0
+-      };
+-
+-      s5k5baf_write_nseq(state, nseq_patch);
+-}
+-
+-static void s5k5baf_hw_set_clocks(struct s5k5baf *state)
+-{
+-      unsigned long mclk = state->mclk_frequency / 1000;
+-      u16 status;
+-      static const u16 nseq_clk_cfg[] = {
+-              NSEQ(REG_I_USE_NPVI_CLOCKS,
+-                NPVI_CLOCKS, NMIPI_CLOCKS, 0,
+-                SCLK_PVI_FREQ / 4, PCLK_MIN_FREQ / 4, PCLK_MAX_FREQ / 4,
+-                SCLK_MIPI_FREQ / 4, PCLK_MIN_FREQ / 4, PCLK_MAX_FREQ / 4),
+-              NSEQ(REG_I_USE_REGS_API, 1),
+-              0
+-      };
+-
+-      s5k5baf_write_seq(state, REG_I_INCLK_FREQ_L, mclk & 0xffff, mclk >> 16);
+-      s5k5baf_write_nseq(state, nseq_clk_cfg);
+-
+-      s5k5baf_synchronize(state, 250, REG_I_INIT_PARAMS_UPDATED);
+-      status = s5k5baf_read(state, REG_I_ERROR_INFO);
+-      if (!state->error && status) {
+-              v4l2_err(&state->sd, "error configuring PLL (%d)\n", status);
+-              state->error = -EINVAL;
+-      }
+-}
+-
+-static void s5k5baf_hw_set_ccm(struct s5k5baf *state)
+-{
+-      static const u16 nseq_cfg[] = {
+-              NSEQ(REG_PTR_CCM_HORIZON,
+-              REG_ARR_CCM(0), PAGE_IF_SW,
+-              REG_ARR_CCM(1), PAGE_IF_SW,
+-              REG_ARR_CCM(2), PAGE_IF_SW,
+-              REG_ARR_CCM(3), PAGE_IF_SW,
+-              REG_ARR_CCM(4), PAGE_IF_SW,
+-              REG_ARR_CCM(5), PAGE_IF_SW),
+-              NSEQ(REG_PTR_CCM_OUTDOOR,
+-              REG_ARR_CCM(6), PAGE_IF_SW),
+-              NSEQ(REG_ARR_CCM(0),
+-              /* horizon */
+-              0x010d, 0xffa7, 0xfff5, 0x003b, 0x00ef, 0xff38,
+-              0xfe42, 0x0270, 0xff71, 0xfeed, 0x0198, 0x0198,
+-              0xff95, 0xffa3, 0x0260, 0x00ec, 0xff33, 0x00f4,
+-              /* incandescent */
+-              0x010d, 0xffa7, 0xfff5, 0x003b, 0x00ef, 0xff38,
+-              0xfe42, 0x0270, 0xff71, 0xfeed, 0x0198, 0x0198,
+-              0xff95, 0xffa3, 0x0260, 0x00ec, 0xff33, 0x00f4,
+-              /* warm white */
+-              0x01ea, 0xffb9, 0xffdb, 0x0127, 0x0109, 0xff3c,
+-              0xff2b, 0x021b, 0xff48, 0xff03, 0x0207, 0x0113,
+-              0xffca, 0xff93, 0x016f, 0x0164, 0xff55, 0x0163,
+-              /* cool white */
+-              0x01ea, 0xffb9, 0xffdb, 0x0127, 0x0109, 0xff3c,
+-              0xff2b, 0x021b, 0xff48, 0xff03, 0x0207, 0x0113,
+-              0xffca, 0xff93, 0x016f, 0x0164, 0xff55, 0x0163,
+-              /* daylight 5000K */
+-              0x0194, 0xffad, 0xfffe, 0x00c5, 0x0103, 0xff5d,
+-              0xfee3, 0x01ae, 0xff27, 0xff18, 0x018f, 0x00c8,
+-              0xffe8, 0xffaa, 0x01c8, 0x0132, 0xff3e, 0x0100,
+-              /* daylight 6500K */
+-              0x0194, 0xffad, 0xfffe, 0x00c5, 0x0103, 0xff5d,
+-              0xfee3, 0x01ae, 0xff27, 0xff18, 0x018f, 0x00c8,
+-              0xffe8, 0xffaa, 0x01c8, 0x0132, 0xff3e, 0x0100,
+-              /* outdoor */
+-              0x01cc, 0xffc3, 0x0009, 0x00a2, 0x0106, 0xff3f,
+-              0xfed8, 0x01fe, 0xff08, 0xfec7, 0x00f5, 0x0119,
+-              0xffdf, 0x0024, 0x01a8, 0x0170, 0xffad, 0x011b),
+-              0
+-      };
+-      s5k5baf_write_nseq(state, nseq_cfg);
+-}
+-
+-static void s5k5baf_hw_set_cis(struct s5k5baf *state)
+-{
+-      static const u16 nseq_cfg[] = {
+-              NSEQ(0xc202, 0x0700),
+-              NSEQ(0xf260, 0x0001),
+-              NSEQ(0xf414, 0x0030),
+-              NSEQ(0xc204, 0x0100),
+-              NSEQ(0xf402, 0x0092, 0x007f),
+-              NSEQ(0xf700, 0x0040),
+-              NSEQ(0xf708,
+-              0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+-              0x0040, 0x0040, 0x0040, 0x0040, 0x0040,
+-              0x0001, 0x0015, 0x0001, 0x0040),
+-              NSEQ(0xf48a, 0x0048),
+-              NSEQ(0xf10a, 0x008b),
+-              NSEQ(0xf900, 0x0067),
+-              NSEQ(0xf406, 0x0092, 0x007f, 0x0003, 0x0003, 0x0003),
+-              NSEQ(0xf442, 0x0000, 0x0000),
+-              NSEQ(0xf448, 0x0000),
+-              NSEQ(0xf456, 0x0001, 0x0010, 0x0000),
+-              NSEQ(0xf41a, 0x00ff, 0x0003, 0x0030),
+-              NSEQ(0xf410, 0x0001, 0x0000),
+-              NSEQ(0xf416, 0x0001),
+-              NSEQ(0xf424, 0x0000),
+-              NSEQ(0xf422, 0x0000),
+-              NSEQ(0xf41e, 0x0000),
+-              NSEQ(0xf428, 0x0000, 0x0000, 0x0000),
+-              NSEQ(0xf430, 0x0000, 0x0000, 0x0008, 0x0005, 0x000f, 0x0001,
+-              0x0040, 0x0040, 0x0010),
+-              NSEQ(0xf4d6, 0x0090, 0x0000),
+-              NSEQ(0xf47c, 0x000c, 0x0000),
+-              NSEQ(0xf49a, 0x0008, 0x0000),
+-              NSEQ(0xf4a2, 0x0008, 0x0000),
+-              NSEQ(0xf4b2, 0x0013, 0x0000, 0x0013, 0x0000),
+-              NSEQ(0xf4aa, 0x009b, 0x00fb, 0x009b, 0x00fb),
+-              0
+-      };
+-
+-      s5k5baf_i2c_write(state, REG_CMDWR_PAGE, PAGE_IF_HW);
+-      s5k5baf_write_nseq(state, nseq_cfg);
+-      s5k5baf_i2c_write(state, REG_CMDWR_PAGE, PAGE_IF_SW);
+-}
+-
+-static void s5k5baf_hw_sync_cfg(struct s5k5baf *state)
+-{
+-      s5k5baf_write(state, REG_G_PREV_CFG_CHG, 1);
+-      if (state->apply_crop) {
+-              s5k5baf_write(state, REG_G_INPUTS_CHANGE_REQ, 1);
+-              s5k5baf_write(state, REG_G_PREV_CFG_BYPASS_CHANGED, 1);
+-      }
+-      s5k5baf_synchronize(state, 500, REG_G_NEW_CFG_SYNC);
+-
+-}
+-/* Set horizontal and vertical image flipping */
+-static void s5k5baf_hw_set_mirror(struct s5k5baf *state, int horiz_flip)
+-{
+-      u16 vflip = state->ctrls.vflip->val ^ state->vflip;
+-      u16 flip = (horiz_flip ^ state->hflip) | (vflip << 1);
+-
+-      s5k5baf_write(state, REG_P_PREV_MIRROR(0), flip);
+-      if (state->streaming)
+-              s5k5baf_hw_sync_cfg(state);
+-}
+-
+-/* Configure auto/manual white balance and R/G/B gains */
+-static void s5k5baf_hw_set_awb(struct s5k5baf *state, int awb)
+-{
+-      struct s5k5baf_ctrls *ctrls = &state->ctrls;
+-      u16 reg;
+-
+-      reg = s5k5baf_read(state, REG_DBG_AUTOALG_EN);
+-
+-      if (!awb)
+-              s5k5baf_write_seq(state, REG_SF_RGAIN,
+-                                ctrls->gain_red->val, 1,
+-                                ctrls->gain_green->val, 1,
+-                                ctrls->gain_blue->val, 1);
+-      reg = awb ? reg | AALG_WB_EN : reg & ~AALG_WB_EN;
+-      s5k5baf_write(state, REG_DBG_AUTOALG_EN, reg);
+-}
+-
+-/* Program FW with exposure time, 'exposure' in us units */
+-static void s5k5baf_hw_set_user_exposure(struct s5k5baf *state, int exposure)
+-{
+-      unsigned int time = exposure / 10;
+-
+-      s5k5baf_write_seq(state, REG_SF_USR_EXPOSURE_L,
+-                        time & 0xffff, time >> 16, 1);
+-}
+-
+-static void s5k5baf_hw_set_user_gain(struct s5k5baf *state, int gain)
+-{
+-      s5k5baf_write_seq(state, REG_SF_USR_TOT_GAIN, gain, 1);
+-}
+-
+-/* Set auto/manual exposure and total gain */
+-static void s5k5baf_hw_set_auto_exposure(struct s5k5baf *state, int value)
+-{
+-      unsigned int exp_time = state->ctrls.exposure->val;
+-      u16 auto_alg;
+-
+-      auto_alg = s5k5baf_read(state, REG_DBG_AUTOALG_EN);
+-
+-      if (value == V4L2_EXPOSURE_AUTO) {
+-              auto_alg |= AALG_AE_EN | AALG_DIVLEI_EN;
+-      } else {
+-              s5k5baf_hw_set_user_exposure(state, exp_time);
+-              s5k5baf_hw_set_user_gain(state, state->ctrls.gain->val);
+-              auto_alg &= ~(AALG_AE_EN | AALG_DIVLEI_EN);
+-      }
+-
+-      s5k5baf_write(state, REG_DBG_AUTOALG_EN, auto_alg);
+-}
+-
+-static void s5k5baf_hw_set_anti_flicker(struct s5k5baf *state, int v)
+-{
+-      u16 auto_alg;
+-
+-      auto_alg = s5k5baf_read(state, REG_DBG_AUTOALG_EN);
+-
+-      if (v == V4L2_CID_POWER_LINE_FREQUENCY_AUTO) {
+-              auto_alg |= AALG_FLICKER_EN;
+-      } else {
+-              auto_alg &= ~AALG_FLICKER_EN;
+-              /* The V4L2_CID_LINE_FREQUENCY control values match
+-               * the register values */
+-              s5k5baf_write_seq(state, REG_SF_FLICKER_QUANT, v, 1);
+-      }
+-
+-      s5k5baf_write(state, REG_DBG_AUTOALG_EN, auto_alg);
+-}
+-
+-static void s5k5baf_hw_set_colorfx(struct s5k5baf *state, int val)
+-{
+-      static const u16 colorfx[] = {
+-              [V4L2_COLORFX_NONE] = 0,
+-              [V4L2_COLORFX_BW] = 1,
+-              [V4L2_COLORFX_NEGATIVE] = 2,
+-              [V4L2_COLORFX_SEPIA] = 3,
+-              [V4L2_COLORFX_SKY_BLUE] = 4,
+-              [V4L2_COLORFX_SKETCH] = 5,
+-      };
+-
+-      if (val >= ARRAY_SIZE(colorfx)) {
+-              v4l2_err(&state->sd, "colorfx(%d) out of range(%d)\n",
+-                       val, ARRAY_SIZE(colorfx));
+-              state->error = -EINVAL;
+-      } else {
+-              s5k5baf_write(state, REG_G_SPEC_EFFECTS, colorfx[val]);
+-      }
+-}
+-
+-static int s5k5baf_find_pixfmt(struct v4l2_mbus_framefmt *mf)
+-{
+-      int i, c = -1;
+-
+-      for (i = 0; i < ARRAY_SIZE(s5k5baf_formats); i++) {
+-              if (mf->colorspace != s5k5baf_formats[i].colorspace)
+-                      continue;
+-              if (mf->code == s5k5baf_formats[i].code)
+-                      return i;
+-              if (c < 0)
+-                      c = i;
+-      }
+-      return (c < 0) ? 0 : c;
+-}
+-
+-static void s5k5baf_hw_set_video_bus(struct s5k5baf *state)
+-{
+-      u16 en_packets;
+-
+-      switch (state->bus_type) {
+-      case V4L2_MBUS_CSI2:
+-              en_packets = EN_PACKETS_CSI2;
+-              break;
+-      case V4L2_MBUS_PARALLEL:
+-              en_packets = 0;
+-              break;
+-      default:
+-              v4l2_err(&state->sd, "unknown video bus: %d\n", state->bus_type);
+-              state->error = -EINVAL;
+-              return;
+-      };
+-
+-      s5k5baf_write_seq(state, REG_OIF_EN_MIPI_LANES,
+-                        state->nlanes, en_packets, 1);
+-}
+-
+-static u16 s5k5baf_get_cfg_error(struct s5k5baf *state)
+-{
+-      u16 err = s5k5baf_read(state, REG_G_PREV_CFG_ERROR);
+-      if (err)
+-              s5k5baf_write(state, REG_G_PREV_CFG_ERROR, 0);
+-      return err;
+-}
+-
+-static void s5k5baf_hw_set_fiv(struct s5k5baf *state, u16 fiv)
+-{
+-      s5k5baf_write(state, REG_P_MAX_FR_TIME(0), fiv);
+-      s5k5baf_hw_sync_cfg(state);
+-}
+-
+-static void s5k5baf_hw_find_min_fiv(struct s5k5baf *state)
+-{
+-      u16 err, fiv;
+-      int n;
+-
+-      fiv = s5k5baf_read(state,  REG_G_ACTUAL_P_FR_TIME);
+-      if (state->error)
+-              return;
+-
+-      for (n = 5; n > 0; --n) {
+-              s5k5baf_hw_set_fiv(state, fiv);
+-              err = s5k5baf_get_cfg_error(state);
+-              if (state->error)
+-                      return;
+-              switch (err) {
+-              case CFG_ERROR_RANGE:
+-                      ++fiv;
+-                      break;
+-              case 0:
+-                      state->fiv = fiv;
+-                      v4l2_info(&state->sd,
+-                                "found valid frame interval: %d00us\n", fiv);
+-                      return;
+-              default:
+-                      v4l2_err(&state->sd,
+-                               "error setting frame interval: %d\n", err);
+-                      state->error = -EINVAL;
+-              }
+-      };
+-      v4l2_err(&state->sd, "cannot find correct frame interval\n");
+-      state->error = -ERANGE;
+-}
+-
+-static void s5k5baf_hw_validate_cfg(struct s5k5baf *state)
+-{
+-      u16 err;
+-
+-      err = s5k5baf_get_cfg_error(state);
+-      if (state->error)
+-              return;
+-
+-      switch (err) {
+-      case 0:
+-              state->apply_cfg = 1;
+-              return;
+-      case CFG_ERROR_RANGE:
+-              s5k5baf_hw_find_min_fiv(state);
+-              if (!state->error)
+-                      state->apply_cfg = 1;
+-              return;
+-      default:
+-              v4l2_err(&state->sd,
+-                       "error setting format: %d\n", err);
+-              state->error = -EINVAL;
+-      }
+-}
+-
+-static void s5k5baf_rescale(struct v4l2_rect *r, const struct v4l2_rect *v,
+-                          const struct v4l2_rect *n,
+-                          const struct v4l2_rect *d)
+-{
+-      r->left = v->left * n->width / d->width;
+-      r->top = v->top * n->height / d->height;
+-      r->width = v->width * n->width / d->width;
+-      r->height = v->height * n->height / d->height;
+-}
+-
+-static void s5k5baf_hw_set_crop_rects(struct s5k5baf *state)
+-{
+-      struct v4l2_rect *p, r;
+-      u16 err;
+-
+-      p = &state->crop_sink;
+-      s5k5baf_write_seq(state, REG_G_PREVREQ_IN_WIDTH, p->width, p->height,
+-                        p->left, p->top);
+-
+-      s5k5baf_rescale(&r, &state->crop_source, &state->crop_sink,
+-                      &state->compose);
+-      s5k5baf_write_seq(state, REG_G_PREVZOOM_IN_WIDTH, r.width, r.height,
+-                        r.left, r.top);
+-
+-      s5k5baf_synchronize(state, 500, REG_G_INPUTS_CHANGE_REQ);
+-      s5k5baf_synchronize(state, 500, REG_G_PREV_CFG_BYPASS_CHANGED);
+-      err = s5k5baf_get_cfg_error(state);
+-      if (state->error)
+-              return;
+-
+-      switch (err) {
+-      case 0:
+-              break;
+-      case CFG_ERROR_RANGE:
+-              /* retry crop with frame interval set to max */
+-              s5k5baf_hw_set_fiv(state, S5K5BAF_MAX_FR_TIME);
+-              err = s5k5baf_get_cfg_error(state);
+-              if (state->error)
+-                      return;
+-              if (err) {
+-                      v4l2_err(&state->sd,
+-                               "crop error on max frame interval: %d\n", err);
+-                      state->error = -EINVAL;
+-              }
+-              s5k5baf_hw_set_fiv(state, state->req_fiv);
+-              s5k5baf_hw_validate_cfg(state);
+-              break;
+-      default:
+-              v4l2_err(&state->sd, "crop error: %d\n", err);
+-              state->error = -EINVAL;
+-              return;
+-      }
+-
+-      if (!state->apply_cfg)
+-              return;
+-
+-      p = &state->crop_source;
+-      s5k5baf_write_seq(state, REG_P_OUT_WIDTH(0), p->width, p->height);
+-      s5k5baf_hw_set_fiv(state, state->req_fiv);
+-      s5k5baf_hw_validate_cfg(state);
+-}
+-
+-static void s5k5baf_hw_set_config(struct s5k5baf *state)
+-{
+-      u16 reg_fmt = s5k5baf_formats[state->pixfmt].reg_p_fmt;
+-      struct v4l2_rect *r = &state->crop_source;
+-
+-      s5k5baf_write_seq(state, REG_P_OUT_WIDTH(0),
+-                        r->width, r->height, reg_fmt,
+-                        PCLK_MAX_FREQ >> 2, PCLK_MIN_FREQ >> 2,
+-                        PVI_MASK_MIPI, CLK_MIPI_INDEX,
+-                        FR_RATE_FIXED, FR_RATE_Q_DYNAMIC,
+-                        state->req_fiv, S5K5BAF_MIN_FR_TIME);
+-      s5k5baf_hw_sync_cfg(state);
+-      s5k5baf_hw_validate_cfg(state);
+-}
+-
+-
+-static void s5k5baf_hw_set_test_pattern(struct s5k5baf *state, int id)
+-{
+-      s5k5baf_i2c_write(state, REG_PATTERN_WIDTH, 800);
+-      s5k5baf_i2c_write(state, REG_PATTERN_HEIGHT, 511);
+-      s5k5baf_i2c_write(state, REG_PATTERN_PARAM, 0);
+-      s5k5baf_i2c_write(state, REG_PATTERN_SET, id);
+-}
+-
+-static void s5k5baf_gpio_assert(struct s5k5baf *state, int id)
+-{
+-      struct s5k5baf_gpio *gpio = &state->gpios[id];
+-
+-      gpio_set_value(gpio->gpio, gpio->level);
+-}
+-
+-static void s5k5baf_gpio_deassert(struct s5k5baf *state, int id)
+-{
+-      struct s5k5baf_gpio *gpio = &state->gpios[id];
+-
+-      gpio_set_value(gpio->gpio, !gpio->level);
+-}
+-
+-static void s5k5baf_power_on(struct s5k5baf *state)
+-{
+-      int ret;
+-
+-      ret = regulator_bulk_enable(S5K5BAF_NUM_SUPPLIES, state->supplies);
+-      if (ret) {
+-              state->error = ret;
+-              return;
+-      }
+-
+-      s5k5baf_gpio_deassert(state, STBY);
+-      usleep_range(50, 100);
+-      s5k5baf_gpio_deassert(state, RST);
+-}
+-
+-static void s5k5baf_power_off(struct s5k5baf *state)
+-{
+-      int ret;
+-
+-      state->streaming = 0;
+-      state->apply_cfg = 0;
+-      state->apply_crop = 0;
+-      s5k5baf_gpio_assert(state, RST);
+-      s5k5baf_gpio_assert(state, STBY);
+-      ret = regulator_bulk_disable(S5K5BAF_NUM_SUPPLIES, state->supplies);
+-      if (ret && !state->error)
+-              state->error = ret;
+-}
+-
+-static void s5k5baf_hw_init(struct s5k5baf *state)
+-{
+-      s5k5baf_i2c_write(state, AHB_MSB_ADDR_PTR, PAGE_IF_HW);
+-      s5k5baf_i2c_write(state, REG_CLEAR_HOST_INT, 0);
+-      s5k5baf_i2c_write(state, REG_SW_LOAD_COMPLETE, 1);
+-      s5k5baf_i2c_write(state, REG_CMDRD_PAGE, PAGE_IF_SW);
+-      s5k5baf_i2c_write(state, REG_CMDWR_PAGE, PAGE_IF_SW);
+-}
+-
+-static int s5k5baf_clear_error(struct s5k5baf *state)
+-{
+-      int ret = state->error;
+-
+-      state->error = 0;
+-      return ret;
+-}
+-
+-/*
+- * V4L2 subdev core and video operations
+- */
+-
+-static void s5k5baf_initialize_data(struct s5k5baf *state)
+-{
+-      state->crop_sink = s5k5baf_cis_rect;
+-      state->compose = s5k5baf_def_rect;
+-      state->crop_source = state->compose;
+-      state->pixfmt = 0;
+-      state->req_fiv = 10000 / 15;
+-      state->fiv = state->req_fiv;
+-}
+-
+-static int s5k5baf_set_power(struct v4l2_subdev *sd, int on)
+-{
+-      struct s5k5baf *state = to_s5k5baf(sd);
+-      int ret;
+-
+-      mutex_lock(&state->lock);
+-
+-      if (!on == state->power) {
+-              if (on) {
+-                      s5k5baf_initialize_data(state);
+-                      s5k5baf_power_on(state);
+-                      s5k5baf_hw_init(state);
+-                      s5k5baf_hw_patch(state);
+-                      s5k5baf_i2c_write(state, REG_SET_HOST_INT, 1);
+-                      s5k5baf_hw_set_clocks(state);
+-                      s5k5baf_hw_set_video_bus(state);
+-                      s5k5baf_hw_set_cis(state);
+-                      s5k5baf_hw_set_ccm(state);
+-              } else {
+-                      s5k5baf_power_off(state);
+-              }
+-
+-              if (!state->error)
+-                      state->power += on ? 1 : -1;
+-      }
+-
+-      ret = s5k5baf_clear_error(state);
+-      mutex_unlock(&state->lock);
+-
+-      if (!ret && on && state->power == 1)
+-              ret = v4l2_ctrl_handler_setup(&state->ctrls.handler);
+-
+-      return ret;
+-}
+-
+-static void s5k5baf_hw_set_stream(struct s5k5baf *state, int enable)
+-{
+-      s5k5baf_write_seq(state, REG_G_ENABLE_PREV, enable, 1);
+-}
+-
+-static int s5k5baf_s_stream(struct v4l2_subdev *sd, int on)
+-{
+-      struct s5k5baf *state = to_s5k5baf(sd);
+-      int ret;
+-
+-      if (state->streaming == !!on)
+-              return 0;
+-
+-      mutex_lock(&state->lock);
+-
+-      if (!on) {
+-              s5k5baf_hw_set_stream(state, 0);
+-              goto out;
+-      }
+-
+-      s5k5baf_hw_set_config(state);
+-      s5k5baf_hw_set_stream(state, 1);
+-      s5k5baf_i2c_write(state, 0xb0cc, 0x000b);
+-
+-      if (!state->error)
+-              state->streaming = 1;
+-
+-out:
+-      ret = s5k5baf_clear_error(state);
+-      mutex_unlock(&state->lock);
+-
+-      return ret;
+-}
+-
+-static int s5k5baf_g_frame_interval(struct v4l2_subdev *sd,
+-                                 struct v4l2_subdev_frame_interval *fi)
+-{
+-      struct s5k5baf *state = to_s5k5baf(sd);
+-
+-      mutex_lock(&state->lock);
+-      fi->interval.numerator = state->fiv;
+-      fi->interval.denominator = 10000;
+-      mutex_unlock(&state->lock);
+-
+-      return 0;
+-}
+-
+-static void s5k5baf_set_frame_interval(struct s5k5baf *state,
+-                                     struct v4l2_subdev_frame_interval *fi)
+-{
+-      struct v4l2_fract *i = &fi->interval;
+-
+-      if (fi->interval.denominator == 0)
+-              state->req_fiv = S5K5BAF_MAX_FR_TIME;
+-      else
+-              state->req_fiv = clamp_t(u32,
+-                                       i->numerator * 10000 / i->denominator,
+-                                       S5K5BAF_MIN_FR_TIME,
+-                                       S5K5BAF_MAX_FR_TIME);
+-
+-      state->fiv = state->req_fiv;
+-      if (state->apply_cfg) {
+-              s5k5baf_hw_set_fiv(state, state->req_fiv);
+-              s5k5baf_hw_validate_cfg(state);
+-      }
+-      *i = (struct v4l2_fract){state->fiv, 10000};
+-      if (state->fiv == state->req_fiv)
+-              v4l2_info(&state->sd, "frame interval changed to %d00us\n",
+-                        state->fiv);
+-}
+-
+-static int s5k5baf_s_frame_interval(struct v4l2_subdev *sd,
+-                                 struct v4l2_subdev_frame_interval *fi)
+-{
+-      struct s5k5baf *state = to_s5k5baf(sd);
+-
+-      mutex_lock(&state->lock);
+-      s5k5baf_set_frame_interval(state, fi);
+-      mutex_unlock(&state->lock);
+-      return 0;
+-}
+-
+-/*
+- * V4L2 subdev pad level and video operations
+- */
+-static int s5k5baf_enum_frame_interval(struct v4l2_subdev *sd,
+-                            struct v4l2_subdev_fh *fh,
+-                            struct v4l2_subdev_frame_interval_enum *fie)
+-{
+-      if (fie->index > S5K5BAF_MAX_FR_TIME - S5K5BAF_MIN_FR_TIME ||
+-          fie->pad != 0)
+-              return -EINVAL;
+-
+-      v4l_bound_align_image(&fie->width, S5K5BAF_WIN_WIDTH_MIN,
+-                            S5K5BAF_CIS_WIDTH, 1,
+-                            &fie->height, S5K5BAF_WIN_HEIGHT_MIN,
+-                            S5K5BAF_CIS_HEIGHT, 1, 0);
+-
+-      fie->interval.numerator = S5K5BAF_MIN_FR_TIME + fie->index;
+-      fie->interval.denominator = 10000;
+-
+-      return 0;
+-}
+-
+-static int s5k5baf_enum_mbus_code(struct v4l2_subdev *sd,
+-                               struct v4l2_subdev_fh *fh,
+-                               struct v4l2_subdev_mbus_code_enum *code)
+-{
+-      if (code->pad == 0) {
+-              if (code->index > 0)
+-                      return -EINVAL;
+-              code->code = V4L2_MBUS_FMT_FIXED;
+-              return 0;
+-      }
+-
+-      if (code->index >= ARRAY_SIZE(s5k5baf_formats))
+-              return -EINVAL;
+-
+-      code->code = s5k5baf_formats[code->index].code;
+-      return 0;
+-}
+-
+-static int s5k5baf_enum_frame_size(struct v4l2_subdev *sd,
+-                                struct v4l2_subdev_fh *fh,
+-                                struct v4l2_subdev_frame_size_enum *fse)
+-{
+-      int i;
+-
+-      if (fse->index > 0)
+-              return -EINVAL;
+-
+-      if (fse->pad == 0) {
+-              fse->code = V4L2_MBUS_FMT_FIXED;
+-              fse->min_width = S5K5BAF_CIS_WIDTH;
+-              fse->max_width = S5K5BAF_CIS_WIDTH;
+-              fse->min_height = S5K5BAF_CIS_HEIGHT;
+-              fse->max_height = S5K5BAF_CIS_HEIGHT;
+-              return 0;
+-      }
+-
+-      i = ARRAY_SIZE(s5k5baf_formats);
+-      while (--i)
+-              if (fse->code == s5k5baf_formats[i].code)
+-                      break;
+-      fse->code = s5k5baf_formats[i].code;
+-      fse->min_width = S5K5BAF_WIN_WIDTH_MIN;
+-      fse->max_width = S5K5BAF_CIS_WIDTH;
+-      fse->max_height = S5K5BAF_WIN_HEIGHT_MIN;
+-      fse->min_height = S5K5BAF_CIS_HEIGHT;
+-
+-      return 0;
+-}
+-
+-static void s5k5baf_try_cis_format(struct v4l2_mbus_framefmt *mf)
+-{
+-      mf->width = S5K5BAF_CIS_WIDTH;
+-      mf->height = S5K5BAF_CIS_HEIGHT;
+-      mf->code = V4L2_MBUS_FMT_FIXED;
+-      mf->colorspace = V4L2_COLORSPACE_JPEG;
+-      mf->field = V4L2_FIELD_NONE;
+-}
+-
+-static int s5k5baf_try_isp_format(struct v4l2_mbus_framefmt *mf)
+-{
+-      int pixfmt;
+-
+-      v4l_bound_align_image(&mf->width, S5K5BAF_WIN_WIDTH_MIN,
+-                            S5K5BAF_CIS_WIDTH, 1,
+-                            &mf->height, S5K5BAF_WIN_HEIGHT_MIN,
+-                            S5K5BAF_CIS_HEIGHT, 1, 0);
+-
+-      pixfmt = s5k5baf_find_pixfmt(mf);
+-
+-      mf->colorspace = s5k5baf_formats[pixfmt].colorspace;
+-      mf->code = s5k5baf_formats[pixfmt].code;
+-      mf->field = V4L2_FIELD_NONE;
+-
+-      return pixfmt;
+-}
+-
+-static int s5k5baf_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+-                        struct v4l2_subdev_format *fmt)
+-{
+-      struct s5k5baf *state = to_s5k5baf(sd);
+-      const struct s5k5baf_pixfmt *pixfmt;
+-      struct v4l2_mbus_framefmt *mf;
+-
+-      memset(fmt->reserved, 0, sizeof(fmt->reserved));
+-
+-      if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+-              mf = v4l2_subdev_get_try_format(fh, fmt->pad);
+-              fmt->format = *mf;
+-              return 0;
+-      }
+-
+-      mf = &fmt->format;
+-      if (fmt->pad == 0) {
+-              s5k5baf_try_cis_format(mf);
+-              return 0;
+-      }
+-      mf->field = V4L2_FIELD_NONE;
+-      mutex_lock(&state->lock);
+-      pixfmt = &s5k5baf_formats[state->pixfmt];
+-      mf->width = state->crop_source.width;
+-      mf->height = state->crop_source.height;
+-      mf->code = pixfmt->code;
+-      mf->colorspace = pixfmt->colorspace;
+-      mutex_unlock(&state->lock);
+-
+-      return 0;
+-}
+-
+-static int s5k5baf_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+-                        struct v4l2_subdev_format *fmt)
+-{
+-      struct v4l2_mbus_framefmt *mf = &fmt->format;
+-      struct s5k5baf *state = to_s5k5baf(sd);
+-      const struct s5k5baf_pixfmt *pixfmt;
+-      int ret = 0;
+-
+-      if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+-              *v4l2_subdev_get_try_format(fh, fmt->pad) = *mf;
+-              return 0;
+-      }
+-
+-      if (fmt->pad == 0) {
+-              s5k5baf_try_cis_format(mf);
+-              return 0;
+-      }
+-
+-      mutex_lock(&state->lock);
+-
+-      if (state->streaming) {
+-              ret = -EBUSY;
+-              goto out;
+-      }
+-
+-      state->pixfmt = s5k5baf_try_isp_format(mf);
+-      pixfmt = &s5k5baf_formats[state->pixfmt];
+-      mf->code = pixfmt->code;
+-      mf->colorspace = pixfmt->colorspace;
+-      mf->width = state->crop_source.width;
+-      mf->height = state->crop_source.height;
+-
+-out:
+-      mutex_unlock(&state->lock);
+-
+-      return ret;
+-}
+-
+-enum selection_rect {R_CIS, R_CROP_SINK, R_COMPOSE, R_CROP_SOURCE, R_INVALID};
+-
+-static enum selection_rect s5k5baf_get_sel_rect(u32 pad, u32 target)
+-{
+-      switch (target) {
+-      case V4L2_SEL_TGT_CROP_BOUNDS:
+-              return pad ? R_COMPOSE : R_CIS;
+-      case V4L2_SEL_TGT_CROP:
+-              return pad ? R_CROP_SOURCE : R_CROP_SINK;
+-      case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+-              return pad ? R_INVALID : R_CROP_SINK;
+-      case V4L2_SEL_TGT_COMPOSE:
+-              return pad ? R_INVALID : R_COMPOSE;
+-      default:
+-              return R_INVALID;
+-      }
+-}
+-
+-static int s5k5baf_is_bound_tgt(u32 target)
+-{
+-      return (target == V4L2_SEL_TGT_CROP_BOUNDS ||
+-              target == V4L2_SEL_TGT_COMPOSE_BOUNDS);
+-}
+-
+-static int s5k5baf_get_selection(struct v4l2_subdev *sd,
+-                               struct v4l2_subdev_fh *fh,
+-                               struct v4l2_subdev_selection *sel)
+-{
+-      static enum selection_rect rtype;
+-      struct s5k5baf *state = to_s5k5baf(sd);
+-
+-      rtype = s5k5baf_get_sel_rect(sel->pad, sel->target);
+-
+-      switch (rtype) {
+-      case R_INVALID:
+-              return -EINVAL;
+-      case R_CIS:
+-              sel->r = s5k5baf_cis_rect;
+-              return 0;
+-      default:
+-              break;
+-      }
+-
+-      if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
+-              if (rtype == R_COMPOSE)
+-                      sel->r = *v4l2_subdev_get_try_compose(fh, sel->pad);
+-              else
+-                      sel->r = *v4l2_subdev_get_try_crop(fh, sel->pad);
+-              return 0;
+-      }
+-
+-      mutex_lock(&state->lock);
+-      switch (rtype) {
+-      case R_CROP_SINK:
+-              sel->r = state->crop_sink;
+-              break;
+-      case R_COMPOSE:
+-              sel->r = state->compose;
+-              break;
+-      case R_CROP_SOURCE:
+-              sel->r = state->crop_source;
+-              break;
+-      default:
+-              break;
+-      }
+-      if (s5k5baf_is_bound_tgt(sel->target)) {
+-              sel->r.left = 0;
+-              sel->r.top = 0;
+-      }
+-      mutex_unlock(&state->lock);
+-
+-      return 0;
+-}
+-
+-/* bounds range [start, start+len) to [0, max) and aligns to 2 */
+-static void s5k5baf_bound_range(u32 *start, u32 *len, u32 max)
+-{
+-      if (*len > max)
+-              *len = max;
+-      if (*start + *len > max)
+-              *start = max - *len;
+-      *start &= ~1;
+-      *len &= ~1;
+-      if (*len < S5K5BAF_WIN_WIDTH_MIN)
+-              *len = S5K5BAF_WIN_WIDTH_MIN;
+-}
+-
+-static void s5k5baf_bound_rect(struct v4l2_rect *r, u32 width, u32 height)
+-{
+-      s5k5baf_bound_range(&r->left, &r->width, width);
+-      s5k5baf_bound_range(&r->top, &r->height, height);
+-}
+-
+-static void s5k5baf_set_rect_and_adjust(struct v4l2_rect **rects,
+-                                      enum selection_rect first,
+-                                      struct v4l2_rect *v)
+-{
+-      struct v4l2_rect *r, *br;
+-      enum selection_rect i = first;
+-
+-      *rects[first] = *v;
+-      do {
+-              r = rects[i];
+-              br = rects[i - 1];
+-              s5k5baf_bound_rect(r, br->width, br->height);
+-      } while (++i != R_INVALID);
+-      *v = *rects[first];
+-}
+-
+-static bool s5k5baf_cmp_rect(const struct v4l2_rect *r1,
+-                           const struct v4l2_rect *r2)
+-{
+-      return !memcmp(r1, r2, sizeof(*r1));
+-}
+-
+-static int s5k5baf_set_selection(struct v4l2_subdev *sd,
+-                               struct v4l2_subdev_fh *fh,
+-                               struct v4l2_subdev_selection *sel)
+-{
+-      static enum selection_rect rtype;
+-      struct s5k5baf *state = to_s5k5baf(sd);
+-      struct v4l2_rect **rects;
+-      int ret;
+-
+-      rtype = s5k5baf_get_sel_rect(sel->pad, sel->target);
+-      if (rtype == R_INVALID || s5k5baf_is_bound_tgt(sel->target))
+-              return -EINVAL;
+-
+-      /* allow only scaling on compose */
+-      if (rtype == R_COMPOSE) {
+-              sel->r.left = 0;
+-              sel->r.top = 0;
+-      }
+-
+-      if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
+-              rects = (struct v4l2_rect * []) {
+-                              &s5k5baf_cis_rect,
+-                              v4l2_subdev_get_try_crop(fh, 0),
+-                              v4l2_subdev_get_try_compose(fh, 0),
+-                              v4l2_subdev_get_try_crop(fh, 1)
+-                      };
+-              s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r);
+-              return 0;
+-      }
+-
+-      rects = (struct v4l2_rect * []) {
+-                      &s5k5baf_cis_rect,
+-                      &state->crop_sink,
+-                      &state->compose,
+-                      &state->crop_source
+-              };
+-      mutex_lock(&state->lock);
+-      if (state->streaming) {
+-              /* adjust sel->r to avoid output resolution change */
+-              if (rtype < R_CROP_SOURCE) {
+-                      if (sel->r.width < state->crop_source.width)
+-                              sel->r.width = state->crop_source.width;
+-                      if (sel->r.height < state->crop_source.height)
+-                              sel->r.height = state->crop_source.height;
+-              } else {
+-                      sel->r.width = state->crop_source.width;
+-                      sel->r.height = state->crop_source.height;
+-              }
+-      }
+-      s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r);
+-      if (!s5k5baf_cmp_rect(&state->crop_sink, &s5k5baf_cis_rect) ||
+-          !s5k5baf_cmp_rect(&state->compose, &s5k5baf_def_rect))
+-              state->apply_crop = 1;
+-      s5k5baf_hw_set_crop_rects(state);
+-      ret = s5k5baf_clear_error(state);
+-      mutex_unlock(&state->lock);
+-
+-      return ret;
+-}
+-
+-static const struct v4l2_subdev_pad_ops s5k5baf_cis_pad_ops = {
+-      .enum_mbus_code         = s5k5baf_enum_mbus_code,
+-      .enum_frame_size        = s5k5baf_enum_frame_size,
+-      .get_fmt                = s5k5baf_get_fmt,
+-      .set_fmt                = s5k5baf_set_fmt,
+-};
+-
+-static const struct v4l2_subdev_pad_ops s5k5baf_pad_ops = {
+-      .enum_mbus_code         = s5k5baf_enum_mbus_code,
+-      .enum_frame_size        = s5k5baf_enum_frame_size,
+-      .enum_frame_interval    = s5k5baf_enum_frame_interval,
+-      .get_fmt                = s5k5baf_get_fmt,
+-      .set_fmt                = s5k5baf_set_fmt,
+-      .get_selection          = s5k5baf_get_selection,
+-      .set_selection          = s5k5baf_set_selection,
+-};
+-
+-static const struct v4l2_subdev_video_ops s5k5baf_video_ops = {
+-      .g_frame_interval       = s5k5baf_g_frame_interval,
+-      .s_frame_interval       = s5k5baf_s_frame_interval,
+-      .s_stream               = s5k5baf_s_stream,
+-};
+-
+-/*
+- * V4L2 subdev controls
+- */
+-
+-static int s5k5baf_s_ctrl(struct v4l2_ctrl *ctrl)
+-{
+-      struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
+-      struct s5k5baf *state = to_s5k5baf(sd);
+-      int ret;
+-
+-      v4l2_dbg(1, debug, sd, "ctrl: %s, value: %d\n", ctrl->name, ctrl->val);
+-
+-      mutex_lock(&state->lock);
+-
+-      if (state->power == 0)
+-              goto unlock;
+-
+-      switch (ctrl->id) {
+-      case V4L2_CID_AUTO_WHITE_BALANCE:
+-              s5k5baf_hw_set_awb(state, ctrl->val);
+-              break;
+-
+-      case V4L2_CID_BRIGHTNESS:
+-              s5k5baf_write(state, REG_USER_BRIGHTNESS, ctrl->val);
+-              break;
+-
+-      case V4L2_CID_COLORFX:
+-              s5k5baf_hw_set_colorfx(state, ctrl->val);
+-              break;
+-
+-      case V4L2_CID_CONTRAST:
+-              s5k5baf_write(state, REG_USER_CONTRAST, ctrl->val);
+-              break;
+-
+-      case V4L2_CID_EXPOSURE_AUTO:
+-              s5k5baf_hw_set_auto_exposure(state, ctrl->val);
+-              break;
+-
+-      case V4L2_CID_HFLIP:
+-              s5k5baf_hw_set_mirror(state, ctrl->val);
+-              break;
+-
+-      case V4L2_CID_POWER_LINE_FREQUENCY:
+-              s5k5baf_hw_set_anti_flicker(state, ctrl->val);
+-              break;
+-
+-      case V4L2_CID_SATURATION:
+-              s5k5baf_write(state, REG_USER_SATURATION, ctrl->val);
+-              break;
+-
+-      case V4L2_CID_SHARPNESS:
+-              s5k5baf_write(state, REG_USER_SHARPBLUR, ctrl->val);
+-              break;
+-
+-      case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
+-              s5k5baf_write(state, REG_P_COLORTEMP(0), ctrl->val);
+-              if (state->apply_cfg)
+-                      s5k5baf_hw_sync_cfg(state);
+-              break;
+-
+-      case V4L2_CID_TEST_PATTERN:
+-              s5k5baf_hw_set_test_pattern(state, ctrl->val);
+-              break;
+-      }
+-unlock:
+-      ret = s5k5baf_clear_error(state);
+-      mutex_unlock(&state->lock);
+-      return ret;
+-}
+-
+-static const struct v4l2_ctrl_ops s5k5baf_ctrl_ops = {
+-      .s_ctrl = s5k5baf_s_ctrl,
+-};
+-
+-static const struct v4l2_ctrl_config s5k5baf_ctrls[] = {
+-      {
+-              .ops    = &s5k5baf_ctrl_ops,
+-              .id     = V4L2_CID_RED_GAIN,
+-              .type   = V4L2_CTRL_TYPE_INTEGER,
+-              .name   = "Gain, Red",
+-              .min    = 0,
+-              .max    = 256,
+-              .def    = 127,
+-              .step   = 1,
+-      }, {
+-              .ops    = &s5k5baf_ctrl_ops,
+-              .id     = V4L2_CID_GREEN_GAIN,
+-              .type   = V4L2_CTRL_TYPE_INTEGER,
+-              .name   = "Gain, Green",
+-              .min    = 0,
+-              .max    = 256,
+-              .def    = 127,
+-              .step   = 1,
+-      }, {
+-              .ops    = &s5k5baf_ctrl_ops,
+-              .id     = V4L2_CID_BLUE_GAIN,
+-              .type   = V4L2_CTRL_TYPE_INTEGER,
+-              .name   = "Gain, Blue",
+-              .min    = 0,
+-              .max    = 256,
+-              .def    = 127,
+-              .step   = 1,
+-      },
+-};
+-
+-static const char * const s5k5baf_test_pattern_menu[] = {
+-      "Disabled",
+-      "Blank",
+-      "Bars",
+-      "Gradients",
+-      "Textile",
+-      "Textile2",
+-      "Squares"
+-};
+-
+-static int s5k5baf_initialize_ctrls(struct s5k5baf *state)
+-{
+-      const struct v4l2_ctrl_ops *ops = &s5k5baf_ctrl_ops;
+-      struct s5k5baf_ctrls *ctrls = &state->ctrls;
+-      struct v4l2_ctrl_handler *hdl = &ctrls->handler;
+-      int ret;
+-
+-      ret = v4l2_ctrl_handler_init(hdl, 16);
+-      if (ret) {
+-              v4l2_err(&state->sd, "cannot init ctrl handler (%d)\n", ret);
+-              return ret;
+-      }
+-
+-      /* Auto white balance cluster */
+-      ctrls->awb = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTO_WHITE_BALANCE,
+-                                     0, 1, 1, 1);
+-      ctrls->gain_red = v4l2_ctrl_new_custom(hdl, &s5k5baf_ctrls[0], NULL);
+-      ctrls->gain_green = v4l2_ctrl_new_custom(hdl, &s5k5baf_ctrls[1], NULL);
+-      ctrls->gain_blue = v4l2_ctrl_new_custom(hdl, &s5k5baf_ctrls[2], NULL);
+-      v4l2_ctrl_auto_cluster(4, &ctrls->awb, 0, false);
+-
+-      ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
+-      ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
+-      v4l2_ctrl_cluster(2, &ctrls->hflip);
+-
+-      ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops,
+-                              V4L2_CID_EXPOSURE_AUTO,
+-                              V4L2_EXPOSURE_MANUAL, 0, V4L2_EXPOSURE_AUTO);
+-      /* Exposure time: x 1 us */
+-      ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
+-                                          0, 6000000U, 1, 100000U);
+-      /* Total gain: 256 <=> 1x */
+-      ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN,
+-                                      0, 256, 1, 256);
+-      v4l2_ctrl_auto_cluster(3, &ctrls->auto_exp, 0, false);
+-
+-      v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_POWER_LINE_FREQUENCY,
+-                             V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
+-                             V4L2_CID_POWER_LINE_FREQUENCY_AUTO);
+-
+-      v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_COLORFX,
+-                             V4L2_COLORFX_SKY_BLUE, ~0x6f, V4L2_COLORFX_NONE);
+-
+-      v4l2_ctrl_new_std(hdl, ops, V4L2_CID_WHITE_BALANCE_TEMPERATURE,
+-                        0, 256, 1, 0);
+-
+-      v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION, -127, 127, 1, 0);
+-      v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, -127, 127, 1, 0);
+-      v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -127, 127, 1, 0);
+-      v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SHARPNESS, -127, 127, 1, 0);
+-
+-      v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_TEST_PATTERN,
+-                                   ARRAY_SIZE(s5k5baf_test_pattern_menu) - 1,
+-                                   0, 0, s5k5baf_test_pattern_menu);
+-
+-      if (hdl->error) {
+-              v4l2_err(&state->sd, "error creating controls (%d)\n",
+-                       hdl->error);
+-              ret = hdl->error;
+-              v4l2_ctrl_handler_free(hdl);
+-              return ret;
+-      }
+-
+-      state->sd.ctrl_handler = hdl;
+-      return 0;
+-}
+-
+-/*
+- * V4L2 subdev internal operations
+- */
+-static int s5k5baf_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+-{
+-      struct v4l2_mbus_framefmt *mf;
+-      struct v4l2_rect *r;
+-
+-      mf = v4l2_subdev_get_try_format(fh, 0);
+-      s5k5baf_try_cis_format(mf);
+-
+-      if (s5k5baf_is_cis_subdev(sd))
+-              return 0;
+-
+-      mf = v4l2_subdev_get_try_format(fh, 1);
+-      mf->colorspace = s5k5baf_formats[0].colorspace;
+-      mf->code = s5k5baf_formats[0].code;
+-      mf->width = s5k5baf_def_rect.width;
+-      mf->height = s5k5baf_def_rect.height;
+-      mf->field = V4L2_FIELD_NONE;
+-
+-      *v4l2_subdev_get_try_crop(fh, 0) = s5k5baf_cis_rect;
+-      r = v4l2_subdev_get_try_compose(fh, 0);
+-      *r = s5k5baf_def_rect;
+-      *v4l2_subdev_get_try_crop(fh, 1) = *r;
+-
+-      return 0;
+-}
+-
+-static void s5k5baf_check_fw_revision(struct s5k5baf *state)
+-{
+-      u16 api_ver = 0, fw_rev = 0, s_id = 0;
+-
+-      api_ver = s5k5baf_read(state, REG_FW_APIVER);
+-      fw_rev = s5k5baf_read(state, REG_FW_REVISION) & 0xff;
+-      s_id = s5k5baf_read(state, REG_FW_SENSOR_ID);
+-      if (state->error)
+-              return;
+-
+-      v4l2_info(&state->sd, "FW API=%#x, revision=%#x sensor_id=%#x\n",
+-                api_ver, fw_rev, s_id);
+-
+-      if (api_ver == S5K5BAF_FW_APIVER)
+-              return;
+-
+-      v4l2_err(&state->sd, "FW API version not supported\n");
+-      state->error = -ENODEV;
+-}
+-
+-static int s5k5baf_registered(struct v4l2_subdev *sd)
+-{
+-      struct s5k5baf *state = to_s5k5baf(sd);
+-      int ret;
+-
+-      ret = v4l2_device_register_subdev(sd->v4l2_dev, &state->cis_sd);
+-      if (ret) {
+-              v4l2_err(sd, "failed to register subdev %s\n",
+-                       state->cis_sd.name);
+-              return ret;
+-      }
+-
+-      mutex_lock(&state->lock);
+-
+-      s5k5baf_power_on(state);
+-      s5k5baf_hw_init(state);
+-      s5k5baf_check_fw_revision(state);
+-      s5k5baf_power_off(state);
+-      ret = s5k5baf_clear_error(state);
+-
+-      mutex_unlock(&state->lock);
+-
+-      if (ret)
+-              v4l2_device_unregister_subdev(&state->cis_sd);
+-
+-      return ret;
+-}
+-
+-static void s5k5baf_unregistered(struct v4l2_subdev *sd)
+-{
+-      struct s5k5baf *state = to_s5k5baf(sd);
+-      v4l2_device_unregister_subdev(&state->cis_sd);
+-}
+-
+-static const struct v4l2_subdev_ops s5k5baf_cis_subdev_ops = {
+-      .pad    = &s5k5baf_cis_pad_ops,
+-};
+-
+-static const struct v4l2_subdev_internal_ops s5k5baf_cis_subdev_internal_ops = {
+-      .open = s5k5baf_open,
+-};
+-
+-static const struct v4l2_subdev_internal_ops s5k5baf_subdev_internal_ops = {
+-      .registered = s5k5baf_registered,
+-      .unregistered = s5k5baf_unregistered,
+-      .open = s5k5baf_open,
+-};
+-
+-static const struct v4l2_subdev_core_ops s5k5baf_core_ops = {
+-      .s_power = s5k5baf_set_power,
+-      .log_status = v4l2_ctrl_subdev_log_status,
+-};
+-
+-static const struct v4l2_subdev_ops s5k5baf_subdev_ops = {
+-      .core = &s5k5baf_core_ops,
+-      .pad = &s5k5baf_pad_ops,
+-      .video = &s5k5baf_video_ops,
+-};
+-
+-static int s5k5baf_configure_gpios(struct s5k5baf *state)
+-{
+-      static const char const *name[] = { "S5K5BAF_STBY", "S5K5BAF_RST" };
+-      struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
+-      struct s5k5baf_gpio *g = state->gpios;
+-      int ret, i;
+-
+-      for (i = 0; i < GPIO_NUM; ++i) {
+-              int flags = GPIOF_EXPORT | GPIOF_DIR_OUT;
+-              if (g[i].level)
+-                      flags |= GPIOF_INIT_HIGH;
+-              ret = devm_gpio_request_one(&c->dev, g[i].gpio, flags, name[i]);
+-              if (ret) {
+-                      v4l2_err(c, "failed to request gpio %s\n", name[i]);
+-                      return ret;
+-              }
+-      }
+-      return 0;
+-}
+-
+-static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev)
+-{
+-      struct device_node *node = dev->of_node;
+-      struct device_node *node_ep;
+-      struct v4l2_of_endpoint ep;
+-      enum of_gpio_flags of_flags;
+-
+-      if (!node) {
+-              dev_err(dev, "no device-tree node provided\n");
+-              return -EINVAL;
+-      }
+-
+-      of_property_read_u32(node, "clock-frequency", &state->mclk_frequency);
+-      state->hflip = of_property_read_bool(node, "samsung,hflip");
+-      state->vflip = of_property_read_bool(node, "samsung,vflip");
+-      state->gpios[STBY].gpio = of_get_gpio_flags(node, STBY, &of_flags);
+-      state->gpios[STBY].level = !(of_flags & OF_GPIO_ACTIVE_LOW);
+-      state->gpios[RST].gpio = of_get_gpio_flags(node, RST, &of_flags);
+-      state->gpios[RST].level = !(of_flags & OF_GPIO_ACTIVE_LOW);
+-
+-      node_ep = v4l2_of_get_next_endpoint(node, NULL);
+-      if (!node_ep) {
+-              dev_err(dev, "no endpoint defined\n");
+-              return -EINVAL;
+-      }
+-      v4l2_of_parse_endpoint(node_ep, &ep);
+-      of_node_put(node_ep);
+-      state->bus_type = ep.bus_type;
+-      if (state->bus_type == V4L2_MBUS_CSI2)
+-              state->nlanes = ep.bus.mipi_csi2.num_data_lanes;
+-      return 0;
+-}
+-
+-static int s5k5baf_configure_subdevs(struct s5k5baf *state,
+-                                   struct i2c_client *c)
+-{
+-      struct v4l2_subdev *sd;
+-      int ret;
+-
+-      sd = &state->cis_sd;
+-      v4l2_subdev_init(sd, &s5k5baf_cis_subdev_ops);
+-      sd->owner = c->driver->driver.owner;
+-      v4l2_set_subdevdata(sd, state);
+-      strlcpy(sd->name, "S5K5BAF-CIS", sizeof(sd->name));
+-
+-      sd->internal_ops = &s5k5baf_cis_subdev_internal_ops;
+-      sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+-
+-      state->cis_pad.flags = MEDIA_PAD_FL_SOURCE;
+-      sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
+-      ret = media_entity_init(&sd->entity, 1, &state->cis_pad, 0);
+-      if (ret)
+-              goto err;
+-
+-      sd = &state->sd;
+-      v4l2_i2c_subdev_init(sd, c, &s5k5baf_subdev_ops);
+-      strlcpy(sd->name, "S5K5BAF-ISP", sizeof(sd->name));
+-
+-      sd->internal_ops = &s5k5baf_subdev_internal_ops;
+-      sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+-
+-      state->pads[0].flags = MEDIA_PAD_FL_SINK;
+-      state->pads[1].flags = MEDIA_PAD_FL_SOURCE;
+-      sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+-      ret = media_entity_init(&sd->entity, 2, state->pads, 0);
+-      if (ret)
+-              goto err_cis;
+-
+-      ret = media_entity_create_link(&state->cis_sd.entity,
+-                                     0, &state->sd.entity, 0,
+-                                     MEDIA_LNK_FL_IMMUTABLE |
+-                                     MEDIA_LNK_FL_ENABLED);
+-
+-      if (!ret)
+-              return 0;
+-
+-      media_entity_cleanup(&state->sd.entity);
+-err_cis:
+-      media_entity_cleanup(&state->cis_sd.entity);
+-err:
+-      dev_err(&c->dev, "cannot init media entity %s\n", sd->name);
+-      return ret;
+-}
+-
+-static int s5k5baf_configure_regulators(struct s5k5baf *state)
+-{
+-      struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
+-      int ret;
+-      int i;
+-
+-      for (i = 0; i < S5K5BAF_NUM_SUPPLIES; i++)
+-              state->supplies[i].supply = s5k5baf_supply_names[i];
+-
+-      ret = devm_regulator_bulk_get(&c->dev, S5K5BAF_NUM_SUPPLIES,
+-                                    state->supplies);
+-      if (ret)
+-              v4l2_err(c, "failed to get regulators\n");
+-      return ret;
+-}
+-
+-static int s5k5baf_probe(struct i2c_client *c,
+-                      const struct i2c_device_id *id)
+-{
+-      struct s5k5baf *state;
+-      int ret;
+-
+-      state = devm_kzalloc(&c->dev, sizeof(*state), GFP_KERNEL);
+-      if (!state)
+-              return -ENOMEM;
+-
+-      mutex_init(&state->lock);
+-
+-      ret = s5k5baf_parse_device_node(state, &c->dev);
+-      if (ret)
+-              goto err;
+-
+-      ret = s5k5baf_configure_subdevs(state, c);
+-      if (ret)
+-              goto err;
+-
+-      ret = s5k5baf_configure_gpios(state);
+-      if (ret)
+-              goto err;
+-
+-      ret = s5k5baf_configure_regulators(state);
+-      if (ret)
+-              goto err;
+-
+-      ret = s5k5baf_initialize_ctrls(state);
+-      if (ret)
+-              goto err;
+-
+-      return 0;
+-err:
+-      media_entity_cleanup(&state->sd.entity);
+-      media_entity_cleanup(&state->cis_sd.entity);
+-      return ret;
+-}
+-
+-static int s5k5baf_remove(struct i2c_client *c)
+-{
+-      struct v4l2_subdev *sd = i2c_get_clientdata(c);
+-      struct s5k5baf *state = to_s5k5baf(sd);
+-
+-      v4l2_device_unregister_subdev(sd);
+-      v4l2_ctrl_handler_free(sd->ctrl_handler);
+-      media_entity_cleanup(&sd->entity);
+-
+-      sd = &state->cis_sd;
+-      v4l2_device_unregister_subdev(sd);
+-      media_entity_cleanup(&sd->entity);
+-
+-      return 0;
+-}
+-
+-static const struct i2c_device_id s5k5baf_id[] = {
+-      { S5K5BAF_DRIVER_NAME, 0 },
+-      { },
+-};
+-MODULE_DEVICE_TABLE(i2c, s5k5baf_id);
+-
+-static const struct of_device_id s5k5baf_of_match[] = {
+-      { .compatible = "samsung,s5k5baf" },
+-      { }
+-};
+-MODULE_DEVICE_TABLE(of, s5k5baf_of_match);
+-
+-static struct i2c_driver s5k5baf_i2c_driver = {
+-      .driver = {
+-              .of_match_table = s5k5baf_of_match,
+-              .name = S5K5BAF_DRIVER_NAME
+-      },
+-      .probe          = s5k5baf_probe,
+-      .remove         = s5k5baf_remove,
+-      .id_table       = s5k5baf_id,
+-};
+-
+-module_i2c_driver(s5k5baf_i2c_driver);
+-
+-MODULE_DESCRIPTION("Samsung S5K5BAF(X) UXGA camera driver");
+-MODULE_AUTHOR("Andrzej Hajda <a.hajda@samsung.com>");
+-MODULE_LICENSE("GPL");
+diff --git a/include/uapi/linux/s5k5baf.h b/include/uapi/linux/s5k5baf.h
+deleted file mode 100644
+index e1fcb56..0000000
+--- a/include/uapi/linux/s5k5baf.h
++++ /dev/null
+@@ -1,19 +0,0 @@
+-/*
+- * S5K5BAF camera sensor driver header
+- *
+- * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- */
+-
+-#ifndef _UAPI_LINUX_S5K5BAF_H
+-#define _UAPI_LINUX_S5K5BAF_H
+-
+-#define V4L2_CID_RED_GAIN     (V4L2_CID_CAMERA_S5K5BAF_BASE + 0)
+-#define V4L2_CID_GREEN_GAIN   (V4L2_CID_CAMERA_S5K5BAF_BASE + 1)
+-#define V4L2_CID_BLUE_GAIN    (V4L2_CID_CAMERA_S5K5BAF_BASE + 2)
+-
+-#endif /* _UAPI_LINUX_S5K5BAF_H */
+diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
+index 305d098..69bd5bb 100644
+--- a/include/uapi/linux/v4l2-controls.h
++++ b/include/uapi/linux/v4l2-controls.h
+@@ -700,11 +700,6 @@ enum v4l2_auto_focus_range {
+       V4L2_AUTO_FOCUS_RANGE_INFINITY          = 3,
+ };
+-/* Camera class private control IDs */
+-
+-/* The base for the s5k5baf driver controls. See linux/s5k5baf.h for the list
+- * of controls. We reserve 16 controls for this driver. */
+-#define V4L2_CID_CAMERA_S5K5BAF_BASE          (V4L2_CID_CAMERA_CLASS_BASE + 0x1000)
+ /* FM Modulator class control IDs */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0734-Revert-m5mols-added-device-tree-support.patch b/patches.tizen/0734-Revert-m5mols-added-device-tree-support.patch
new file mode 100644 (file)
index 0000000..b34471b
--- /dev/null
@@ -0,0 +1,209 @@
+From 8681bc9577df6a2c03904ca7a4c89c95f1507d0d Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Mon, 2 Sep 2013 16:32:48 +0200
+Subject: [PATCH 0734/1302] Revert "m5mols: added device tree support"
+
+This reverts commit 12f6bb8f0dc0c8865ca85825596e02a03d907b57.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/m5mols/m5mols.h      |  8 ++--
+ drivers/media/i2c/m5mols/m5mols_core.c | 71 ++++++++++------------------------
+ 2 files changed, 25 insertions(+), 54 deletions(-)
+
+diff --git a/drivers/media/i2c/m5mols/m5mols.h b/drivers/media/i2c/m5mols/m5mols.h
+index 0599b8a..90a6c52 100644
+--- a/drivers/media/i2c/m5mols/m5mols.h
++++ b/drivers/media/i2c/m5mols/m5mols.h
+@@ -18,8 +18,6 @@
+ #include <linux/sizes.h>
+ #include <media/v4l2-subdev.h>
+-#include <media/m5mols.h>
+-
+ #include "m5mols_reg.h"
+@@ -184,6 +182,7 @@ struct m5mols_version {
+  * @wdr: wide dynamic range control
+  * @stabilization: image stabilization control
+  * @jpeg_quality: JPEG compression quality control
++ * @set_power: optional power callback to the board code
+  * @lock: mutex protecting the structure fields below
+  * @ffmt: current fmt according to resolution type
+  * @res_type: current resolution type
+@@ -196,8 +195,7 @@ struct m5mols_version {
+  * @mode: register value for current operation mode
+  */
+ struct m5mols_info {
+-      struct m5mols_platform_data pdata;
+-
++      const struct m5mols_platform_data *pdata;
+       struct v4l2_subdev sd;
+       struct media_pad pad;
+@@ -227,6 +225,8 @@ struct m5mols_info {
+       struct v4l2_ctrl *stabilization;
+       struct v4l2_ctrl *jpeg_quality;
++      int (*set_power)(struct device *dev, int on);
++
+       struct mutex lock;
+       struct v4l2_mbus_framefmt ffmt[M5MOLS_RESTYPE_MAX];
+diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c
+index 4d174c3..f720a41 100644
+--- a/drivers/media/i2c/m5mols/m5mols_core.c
++++ b/drivers/media/i2c/m5mols/m5mols_core.c
+@@ -19,13 +19,13 @@
+ #include <linux/interrupt.h>
+ #include <linux/delay.h>
+ #include <linux/gpio.h>
+-#include <linux/of_gpio.h>
+ #include <linux/regulator/consumer.h>
+ #include <linux/videodev2.h>
+ #include <linux/module.h>
+ #include <media/v4l2-ctrls.h>
+ #include <media/v4l2-device.h>
+ #include <media/v4l2-subdev.h>
++#include <media/m5mols.h>
+ #include "m5mols.h"
+ #include "m5mols_reg.h"
+@@ -762,15 +762,15 @@ static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
+ {
+       struct v4l2_subdev *sd = &info->sd;
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+-      struct m5mols_platform_data *pdata = &info->pdata;
++      const struct m5mols_platform_data *pdata = info->pdata;
+       int ret;
+       if (info->power == enable)
+               return 0;
+       if (enable) {
+-              if (pdata->set_power) {
+-                      ret = pdata->set_power(&client->dev, 1);
++              if (info->set_power) {
++                      ret = info->set_power(&client->dev, 1);
+                       if (ret)
+                               return ret;
+               }
+@@ -778,7 +778,7 @@ static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
+               ret = regulator_bulk_enable_sync(ARRAY_SIZE(supplies),
+                                                 supplies);
+               if (ret) {
+-                      pdata->set_power(&client->dev, 0);
++                      info->set_power(&client->dev, 0);
+                       return ret;
+               }
+@@ -793,8 +793,8 @@ static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
+       if (ret)
+               return ret;
+-      if (pdata->set_power)
+-              pdata->set_power(&client->dev, 0);
++      if (info->set_power)
++              info->set_power(&client->dev, 0);
+       gpio_set_value(pdata->gpio_reset, pdata->reset_polarity);
+       usleep_range(1000, 1000);
+@@ -971,38 +971,24 @@ static irqreturn_t m5mols_irq_handler(int irq, void *data)
+       return IRQ_HANDLED;
+ }
+-static int m5mols_get_platform_data(struct m5mols_info *info,
+-                                  struct device *dev)
+-{
+-      struct m5mols_platform_data *pdata = dev->platform_data;
+-      struct device_node *node = dev->of_node;
+-      enum of_gpio_flags of_flags;
+-
+-      if (!node) {
+-              if (!pdata) {
+-                      dev_err(dev, "No platform data\n");
+-                      return -EINVAL;
+-              }
+-              info->pdata = *pdata;
+-              return 0;
+-      }
+-
+-      pdata = &info->pdata;
+-
+-      pdata->gpio_reset = of_get_gpio_flags(node, 0, &of_flags);
+-      pdata->reset_polarity = !(of_flags & OF_GPIO_ACTIVE_LOW);
+-
+-      return 0;
+-}
+-
+ static int m5mols_probe(struct i2c_client *client,
+                       const struct i2c_device_id *id)
+ {
+-      struct m5mols_platform_data *pdata;
++      const struct m5mols_platform_data *pdata = client->dev.platform_data;
+       struct m5mols_info *info;
+       struct v4l2_subdev *sd;
+       int ret;
++      if (pdata == NULL) {
++              dev_err(&client->dev, "No platform data\n");
++              return -EINVAL;
++      }
++
++      if (!gpio_is_valid(pdata->gpio_reset)) {
++              dev_err(&client->dev, "No valid RESET GPIO specified\n");
++              return -EINVAL;
++      }
++
+       if (!client->irq) {
+               dev_err(&client->dev, "Interrupt not assigned\n");
+               return -EINVAL;
+@@ -1012,16 +998,8 @@ static int m5mols_probe(struct i2c_client *client,
+       if (!info)
+               return -ENOMEM;
+-      ret = m5mols_get_platform_data(info, &client->dev);
+-      if (ret < 0)
+-              return ret;
+-
+-      pdata = &info->pdata;
+-
+-      if (!gpio_is_valid(pdata->gpio_reset)) {
+-              dev_err(&client->dev, "No valid RESET GPIO specified\n");
+-              return -EINVAL;
+-      }
++      info->pdata = pdata;
++      info->set_power = pdata->set_power;
+       ret = gpio_request(pdata->gpio_reset, "M5MOLS_NRST");
+       if (ret) {
+@@ -1084,7 +1062,7 @@ static int m5mols_remove(struct i2c_client *client)
+       free_irq(client->irq, sd);
+       regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
+-      gpio_free(info->pdata.gpio_reset);
++      gpio_free(info->pdata->gpio_reset);
+       media_entity_cleanup(&sd->entity);
+       kfree(info);
+       return 0;
+@@ -1096,15 +1074,8 @@ static const struct i2c_device_id m5mols_id[] = {
+ };
+ MODULE_DEVICE_TABLE(i2c, m5mols_id);
+-static const struct of_device_id m5mols_of_match[] = {
+-      { .compatible = "samsung,m5mols" },
+-      { }
+-};
+-MODULE_DEVICE_TABLE(of, m5mols_of_match);
+-
+ static struct i2c_driver m5mols_i2c_driver = {
+       .driver = {
+-              .of_match_table = m5mols_of_match,
+               .name   = MODULE_NAME,
+       },
+       .probe          = m5mols_probe,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0735-Revert-m5mols-device-initialization-moved-to-V4L2-re.patch b/patches.tizen/0735-Revert-m5mols-device-initialization-moved-to-V4L2-re.patch
new file mode 100644 (file)
index 0000000..17782fa
--- /dev/null
@@ -0,0 +1,74 @@
+From aef6e26468a1c59ac0d3374b731196b2b2574384 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Mon, 2 Sep 2013 16:33:02 +0200
+Subject: [PATCH 0735/1302] Revert "m5mols: device initialization moved to V4L2
+ registered callback"
+
+This reverts commit 30e7664276434227e448742b49738b47d03b6090.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/m5mols/m5mols_core.c | 37 +++++++++++-----------------------
+ 1 file changed, 12 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c
+index f720a41..a364781 100644
+--- a/drivers/media/i2c/m5mols/m5mols_core.c
++++ b/drivers/media/i2c/m5mols/m5mols_core.c
+@@ -927,31 +927,7 @@ static int m5mols_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+       return 0;
+ }
+-static int m5mols_registered(struct v4l2_subdev *sd)
+-{
+-      struct m5mols_info *info = to_m5mols(sd);
+-      int ret;
+-
+-      mutex_lock(&info->lock);
+-
+-      ret = m5mols_sensor_power(info, true);
+-      if (!ret)
+-              ret = m5mols_fw_start(sd);
+-      if (!ret)
+-              ret = m5mols_init_controls(sd);
+-
+-      m5mols_sensor_power(info, false);
+-
+-      mutex_unlock(&info->lock);
+-
+-      v4l2_dbg(1, m5mols_debug, sd, "%s: Booting %s (%d)\n",
+-               __func__, ret ? "failed" : "succeded", ret);
+-
+-      return ret;
+-}
+-
+ static const struct v4l2_subdev_internal_ops m5mols_subdev_internal_ops = {
+-      .registered     = m5mols_registered,
+       .open           = m5mols_open,
+ };
+@@ -1039,8 +1015,19 @@ static int m5mols_probe(struct i2c_client *client,
+       info->ffmt[0] = m5mols_default_ffmt[0];
+       info->ffmt[1] = m5mols_default_ffmt[1];
+-      return 0;
++      ret = m5mols_sensor_power(info, true);
++      if (ret)
++              goto out_irq;
++      ret = m5mols_fw_start(sd);
++      if (!ret)
++              ret = m5mols_init_controls(sd);
++
++      ret = m5mols_sensor_power(info, false);
++      if (!ret)
++              return 0;
++out_irq:
++      free_irq(client->irq, sd);
+ out_me:
+       media_entity_cleanup(&sd->entity);
+ out_reg:
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0736-media-media-i2c-Convert-to-gpio_request_one.patch b/patches.tizen/0736-media-media-i2c-Convert-to-gpio_request_one.patch
new file mode 100644 (file)
index 0000000..083915e
--- /dev/null
@@ -0,0 +1,149 @@
+From 028a1f642fa9bd9067e6b784bcbb16828273af12 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Thu, 2 May 2013 11:11:50 -0300
+Subject: [PATCH 0736/1302] [media] media: i2c: Convert to gpio_request_one()
+
+Replace gpio_request() with gpio_request_one() and remove the associated
+gpio_direction_output() calls.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Acked-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/adv7183.c            | 14 +++++++-------
+ drivers/media/i2c/m5mols/m5mols_core.c |  6 ++++--
+ drivers/media/i2c/noon010pc30.c        |  8 ++++----
+ drivers/media/i2c/vs6624.c             |  3 +--
+ 4 files changed, 16 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/media/i2c/adv7183.c b/drivers/media/i2c/adv7183.c
+index 56a1fa4..2bc0328 100644
+--- a/drivers/media/i2c/adv7183.c
++++ b/drivers/media/i2c/adv7183.c
+@@ -474,9 +474,9 @@ static int adv7183_s_stream(struct v4l2_subdev *sd, int enable)
+       struct adv7183 *decoder = to_adv7183(sd);
+       if (enable)
+-              gpio_direction_output(decoder->oe_pin, 0);
++              gpio_set_value(decoder->oe_pin, 0);
+       else
+-              gpio_direction_output(decoder->oe_pin, 1);
++              gpio_set_value(decoder->oe_pin, 1);
+       udelay(1);
+       return 0;
+ }
+@@ -580,13 +580,15 @@ static int adv7183_probe(struct i2c_client *client,
+       decoder->reset_pin = pin_array[0];
+       decoder->oe_pin = pin_array[1];
+-      if (gpio_request(decoder->reset_pin, "ADV7183 Reset")) {
++      if (gpio_request_one(decoder->reset_pin, GPIOF_OUT_INIT_LOW,
++                           "ADV7183 Reset")) {
+               v4l_err(client, "failed to request GPIO %d\n", decoder->reset_pin);
+               ret = -EBUSY;
+               goto err_free_decoder;
+       }
+-      if (gpio_request(decoder->oe_pin, "ADV7183 Output Enable")) {
++      if (gpio_request_one(decoder->oe_pin, GPIOF_OUT_INIT_HIGH,
++                           "ADV7183 Output Enable")) {
+               v4l_err(client, "failed to request GPIO %d\n", decoder->oe_pin);
+               ret = -EBUSY;
+               goto err_free_reset;
+@@ -619,12 +621,10 @@ static int adv7183_probe(struct i2c_client *client,
+       decoder->input = ADV7183_COMPOSITE4;
+       decoder->output = ADV7183_8BIT_OUT;
+-      gpio_direction_output(decoder->oe_pin, 1);
+       /* reset chip */
+-      gpio_direction_output(decoder->reset_pin, 0);
+       /* reset pulse width at least 5ms */
+       mdelay(10);
+-      gpio_direction_output(decoder->reset_pin, 1);
++      gpio_set_value(decoder->reset_pin, 1);
+       /* wait 5ms before any further i2c writes are performed */
+       mdelay(5);
+diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c
+index a364781..77e1237 100644
+--- a/drivers/media/i2c/m5mols/m5mols_core.c
++++ b/drivers/media/i2c/m5mols/m5mols_core.c
+@@ -951,6 +951,7 @@ static int m5mols_probe(struct i2c_client *client,
+                       const struct i2c_device_id *id)
+ {
+       const struct m5mols_platform_data *pdata = client->dev.platform_data;
++      unsigned long gpio_flags;
+       struct m5mols_info *info;
+       struct v4l2_subdev *sd;
+       int ret;
+@@ -977,12 +978,13 @@ static int m5mols_probe(struct i2c_client *client,
+       info->pdata = pdata;
+       info->set_power = pdata->set_power;
+-      ret = gpio_request(pdata->gpio_reset, "M5MOLS_NRST");
++      gpio_flags = pdata->reset_polarity
++                 ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
++      ret = gpio_request_one(pdata->gpio_reset, gpio_flags, "M5MOLS_NRST");
+       if (ret) {
+               dev_err(&client->dev, "Failed to request gpio: %d\n", ret);
+               goto out_free;
+       }
+-      gpio_direction_output(pdata->gpio_reset, pdata->reset_polarity);
+       ret = regulator_bulk_get(&client->dev, ARRAY_SIZE(supplies), supplies);
+       if (ret) {
+diff --git a/drivers/media/i2c/noon010pc30.c b/drivers/media/i2c/noon010pc30.c
+index 8554b47..a115842 100644
+--- a/drivers/media/i2c/noon010pc30.c
++++ b/drivers/media/i2c/noon010pc30.c
+@@ -746,24 +746,24 @@ static int noon010_probe(struct i2c_client *client,
+       info->curr_win          = &noon010_sizes[0];
+       if (gpio_is_valid(pdata->gpio_nreset)) {
+-              ret = gpio_request(pdata->gpio_nreset, "NOON010PC30 NRST");
++              ret = gpio_request_one(pdata->gpio_nreset, GPIOF_OUT_INIT_LOW,
++                                     "NOON010PC30 NRST");
+               if (ret) {
+                       dev_err(&client->dev, "GPIO request error: %d\n", ret);
+                       goto np_err;
+               }
+               info->gpio_nreset = pdata->gpio_nreset;
+-              gpio_direction_output(info->gpio_nreset, 0);
+               gpio_export(info->gpio_nreset, 0);
+       }
+       if (gpio_is_valid(pdata->gpio_nstby)) {
+-              ret = gpio_request(pdata->gpio_nstby, "NOON010PC30 NSTBY");
++              ret = gpio_request_one(pdata->gpio_nstby, GPIOF_OUT_INIT_LOW,
++                                    "NOON010PC30 NSTBY");
+               if (ret) {
+                       dev_err(&client->dev, "GPIO request error: %d\n", ret);
+                       goto np_gpio_err;
+               }
+               info->gpio_nstby = pdata->gpio_nstby;
+-              gpio_direction_output(info->gpio_nstby, 0);
+               gpio_export(info->gpio_nstby, 0);
+       }
+diff --git a/drivers/media/i2c/vs6624.c b/drivers/media/i2c/vs6624.c
+index f366fad..6b8c0b7 100644
+--- a/drivers/media/i2c/vs6624.c
++++ b/drivers/media/i2c/vs6624.c
+@@ -805,12 +805,11 @@ static int vs6624_probe(struct i2c_client *client,
+       if (ce == NULL)
+               return -EINVAL;
+-      ret = gpio_request(*ce, "VS6624 Chip Enable");
++      ret = gpio_request_one(*ce, GPIOF_OUT_INIT_HIGH, "VS6624 Chip Enable");
+       if (ret) {
+               v4l_err(client, "failed to request GPIO %d\n", *ce);
+               return ret;
+       }
+-      gpio_direction_output(*ce, 1);
+       /* wait 100ms before any further i2c writes are performed */
+       mdelay(100);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0737-media-media-i2c-Convert-to-devm_kzalloc.patch b/patches.tizen/0737-media-media-i2c-Convert-to-devm_kzalloc.patch
new file mode 100644 (file)
index 0000000..efc250d
--- /dev/null
@@ -0,0 +1,1736 @@
+From e71bbb4cc186ef4500ed47301ef1d0b644602784 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Thu, 2 May 2013 08:29:43 -0300
+Subject: [PATCH 0737/1302] [media] media: i2c: Convert to devm_kzalloc()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Using the managed function the kfree() calls can be removed from the
+probe error path and the remove handler.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Acked-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Acked-by: Lad, Prabhakar <prabhakar.csengg@gmail.com>
+Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/ad9389b.c              |  8 ++------
+ drivers/media/i2c/adp1653.c              |  5 ++---
+ drivers/media/i2c/adv7170.c              |  3 +--
+ drivers/media/i2c/adv7175.c              |  3 +--
+ drivers/media/i2c/adv7180.c              |  4 +---
+ drivers/media/i2c/adv7183.c              |  8 ++------
+ drivers/media/i2c/adv7393.c              |  8 ++------
+ drivers/media/i2c/adv7604.c              | 11 +++--------
+ drivers/media/i2c/ak881x.c               |  4 +---
+ drivers/media/i2c/as3645a.c              |  7 ++-----
+ drivers/media/i2c/bt819.c                |  4 +---
+ drivers/media/i2c/bt856.c                |  3 +--
+ drivers/media/i2c/bt866.c                |  3 +--
+ drivers/media/i2c/cs5345.c               |  4 +---
+ drivers/media/i2c/cs53l32a.c             |  4 +---
+ drivers/media/i2c/cx25840/cx25840-core.c |  4 +---
+ drivers/media/i2c/cx25840/cx25840-ir.c   |  7 ++-----
+ drivers/media/i2c/ir-kbd-i2c.c           | 10 +++-------
+ drivers/media/i2c/ks0127.c               |  3 +--
+ drivers/media/i2c/m52790.c               |  3 +--
+ drivers/media/i2c/m5mols/m5mols_core.c   |  8 +++-----
+ drivers/media/i2c/msp3400-driver.c       |  5 +----
+ drivers/media/i2c/mt9m032.c              |  4 +---
+ drivers/media/i2c/mt9t001.c              |  4 +---
+ drivers/media/i2c/mt9v011.c              |  6 ++----
+ drivers/media/i2c/noon010pc30.c          |  5 ++---
+ drivers/media/i2c/ov7640.c               |  5 ++---
+ drivers/media/i2c/ov7670.c               |  5 +----
+ drivers/media/i2c/saa6588.c              | 10 +++-------
+ drivers/media/i2c/saa7110.c              |  4 +---
+ drivers/media/i2c/saa7115.c              |  4 +---
+ drivers/media/i2c/saa7127.c              |  4 +---
+ drivers/media/i2c/saa717x.c              |  5 +----
+ drivers/media/i2c/saa7185.c              |  3 +--
+ drivers/media/i2c/saa7191.c              |  4 +---
+ drivers/media/i2c/sony-btf-mpx.c         |  3 +--
+ drivers/media/i2c/sr030pc30.c            |  4 +---
+ drivers/media/i2c/tda7432.c              |  4 +---
+ drivers/media/i2c/tda9840.c              |  3 +--
+ drivers/media/i2c/tea6415c.c             |  3 +--
+ drivers/media/i2c/tea6420.c              |  3 +--
+ drivers/media/i2c/tlv320aic23b.c         |  4 +---
+ drivers/media/i2c/tvaudio.c              |  5 +----
+ drivers/media/i2c/tvp5150.c              | 14 ++++----------
+ drivers/media/i2c/tw2804.c               |  5 +----
+ drivers/media/i2c/tw9903.c               |  5 +----
+ drivers/media/i2c/tw9906.c               |  5 +----
+ drivers/media/i2c/uda1342.c              |  3 +--
+ drivers/media/i2c/upd64031a.c            |  3 +--
+ drivers/media/i2c/upd64083.c             |  3 +--
+ drivers/media/i2c/vp27smpx.c             |  3 +--
+ drivers/media/i2c/vpx3220.c              |  5 ++---
+ drivers/media/i2c/vs6624.c               |  9 ++-------
+ drivers/media/i2c/wm8739.c               |  4 +---
+ drivers/media/i2c/wm8775.c               |  4 +---
+ 55 files changed, 77 insertions(+), 197 deletions(-)
+
+diff --git a/drivers/media/i2c/ad9389b.c b/drivers/media/i2c/ad9389b.c
+index 58344b6..1504355 100644
+--- a/drivers/media/i2c/ad9389b.c
++++ b/drivers/media/i2c/ad9389b.c
+@@ -1188,15 +1188,14 @@ static int ad9389b_probe(struct i2c_client *client, const struct i2c_device_id *
+       v4l_dbg(1, debug, client, "detecting ad9389b client on address 0x%x\n",
+                       client->addr << 1);
+-      state = kzalloc(sizeof(struct ad9389b_state), GFP_KERNEL);
++      state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
+       if (!state)
+               return -ENOMEM;
+       /* Platform data */
+       if (pdata == NULL) {
+               v4l_err(client, "No platform data!\n");
+-              err = -ENODEV;
+-              goto err_free;
++              return -ENODEV;
+       }
+       memcpy(&state->pdata, pdata, sizeof(state->pdata));
+@@ -1276,8 +1275,6 @@ err_entity:
+       media_entity_cleanup(&sd->entity);
+ err_hdl:
+       v4l2_ctrl_handler_free(&state->hdl);
+-err_free:
+-      kfree(state);
+       return err;
+ }
+@@ -1302,7 +1299,6 @@ static int ad9389b_remove(struct i2c_client *client)
+       v4l2_device_unregister_subdev(sd);
+       media_entity_cleanup(&sd->entity);
+       v4l2_ctrl_handler_free(sd->ctrl_handler);
+-      kfree(get_ad9389b_state(sd));
+       return 0;
+ }
+diff --git a/drivers/media/i2c/adp1653.c b/drivers/media/i2c/adp1653.c
+index ef75abe..873fe19 100644
+--- a/drivers/media/i2c/adp1653.c
++++ b/drivers/media/i2c/adp1653.c
+@@ -417,7 +417,7 @@ static int adp1653_probe(struct i2c_client *client,
+       if (client->dev.platform_data == NULL)
+               return -ENODEV;
+-      flash = kzalloc(sizeof(*flash), GFP_KERNEL);
++      flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL);
+       if (flash == NULL)
+               return -ENOMEM;
+@@ -443,7 +443,6 @@ static int adp1653_probe(struct i2c_client *client,
+ free_and_quit:
+       v4l2_ctrl_handler_free(&flash->ctrls);
+-      kfree(flash);
+       return ret;
+ }
+@@ -455,7 +454,7 @@ static int adp1653_remove(struct i2c_client *client)
+       v4l2_device_unregister_subdev(&flash->subdev);
+       v4l2_ctrl_handler_free(&flash->ctrls);
+       media_entity_cleanup(&flash->subdev.entity);
+-      kfree(flash);
++
+       return 0;
+ }
+diff --git a/drivers/media/i2c/adv7170.c b/drivers/media/i2c/adv7170.c
+index 6bc01fb..d07689d 100644
+--- a/drivers/media/i2c/adv7170.c
++++ b/drivers/media/i2c/adv7170.c
+@@ -359,7 +359,7 @@ static int adv7170_probe(struct i2c_client *client,
+       v4l_info(client, "chip found @ 0x%x (%s)\n",
+                       client->addr << 1, client->adapter->name);
+-      encoder = kzalloc(sizeof(struct adv7170), GFP_KERNEL);
++      encoder = devm_kzalloc(&client->dev, sizeof(*encoder), GFP_KERNEL);
+       if (encoder == NULL)
+               return -ENOMEM;
+       sd = &encoder->sd;
+@@ -384,7 +384,6 @@ static int adv7170_remove(struct i2c_client *client)
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       v4l2_device_unregister_subdev(sd);
+-      kfree(to_adv7170(sd));
+       return 0;
+ }
+diff --git a/drivers/media/i2c/adv7175.c b/drivers/media/i2c/adv7175.c
+index c7640fa..eaefa50 100644
+--- a/drivers/media/i2c/adv7175.c
++++ b/drivers/media/i2c/adv7175.c
+@@ -409,7 +409,7 @@ static int adv7175_probe(struct i2c_client *client,
+       v4l_info(client, "chip found @ 0x%x (%s)\n",
+                       client->addr << 1, client->adapter->name);
+-      encoder = kzalloc(sizeof(struct adv7175), GFP_KERNEL);
++      encoder = devm_kzalloc(&client->dev, sizeof(*encoder), GFP_KERNEL);
+       if (encoder == NULL)
+               return -ENOMEM;
+       sd = &encoder->sd;
+@@ -434,7 +434,6 @@ static int adv7175_remove(struct i2c_client *client)
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       v4l2_device_unregister_subdev(sd);
+-      kfree(to_adv7175(sd));
+       return 0;
+ }
+diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c
+index afd561a..3d14567 100644
+--- a/drivers/media/i2c/adv7180.c
++++ b/drivers/media/i2c/adv7180.c
+@@ -555,7 +555,7 @@ static int adv7180_probe(struct i2c_client *client,
+       v4l_info(client, "chip found @ 0x%02x (%s)\n",
+                client->addr, client->adapter->name);
+-      state = kzalloc(sizeof(struct adv7180_state), GFP_KERNEL);
++      state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
+       if (state == NULL) {
+               ret = -ENOMEM;
+               goto err;
+@@ -582,7 +582,6 @@ err_free_ctrl:
+ err_unreg_subdev:
+       mutex_destroy(&state->mutex);
+       v4l2_device_unregister_subdev(sd);
+-      kfree(state);
+ err:
+       printk(KERN_ERR KBUILD_MODNAME ": Failed to probe: %d\n", ret);
+       return ret;
+@@ -607,7 +606,6 @@ static int adv7180_remove(struct i2c_client *client)
+       mutex_destroy(&state->mutex);
+       v4l2_device_unregister_subdev(sd);
+-      kfree(to_state(sd));
+       return 0;
+ }
+diff --git a/drivers/media/i2c/adv7183.c b/drivers/media/i2c/adv7183.c
+index 2bc0328..5690417 100644
+--- a/drivers/media/i2c/adv7183.c
++++ b/drivers/media/i2c/adv7183.c
+@@ -573,7 +573,7 @@ static int adv7183_probe(struct i2c_client *client,
+       if (pin_array == NULL)
+               return -EINVAL;
+-      decoder = kzalloc(sizeof(struct adv7183), GFP_KERNEL);
++      decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
+       if (decoder == NULL)
+               return -ENOMEM;
+@@ -583,8 +583,7 @@ static int adv7183_probe(struct i2c_client *client,
+       if (gpio_request_one(decoder->reset_pin, GPIOF_OUT_INIT_LOW,
+                            "ADV7183 Reset")) {
+               v4l_err(client, "failed to request GPIO %d\n", decoder->reset_pin);
+-              ret = -EBUSY;
+-              goto err_free_decoder;
++              return -EBUSY;
+       }
+       if (gpio_request_one(decoder->oe_pin, GPIOF_OUT_INIT_HIGH,
+@@ -646,8 +645,6 @@ err_free_oe:
+       gpio_free(decoder->oe_pin);
+ err_free_reset:
+       gpio_free(decoder->reset_pin);
+-err_free_decoder:
+-      kfree(decoder);
+       return ret;
+ }
+@@ -660,7 +657,6 @@ static int adv7183_remove(struct i2c_client *client)
+       v4l2_ctrl_handler_free(sd->ctrl_handler);
+       gpio_free(decoder->oe_pin);
+       gpio_free(decoder->reset_pin);
+-      kfree(decoder);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/adv7393.c b/drivers/media/i2c/adv7393.c
+index 3dc6098..ec50509 100644
+--- a/drivers/media/i2c/adv7393.c
++++ b/drivers/media/i2c/adv7393.c
+@@ -410,7 +410,7 @@ static int adv7393_probe(struct i2c_client *client,
+       v4l_info(client, "chip found @ 0x%x (%s)\n",
+                       client->addr << 1, client->adapter->name);
+-      state = kzalloc(sizeof(struct adv7393_state), GFP_KERNEL);
++      state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
+       if (state == NULL)
+               return -ENOMEM;
+@@ -444,16 +444,13 @@ static int adv7393_probe(struct i2c_client *client,
+               int err = state->hdl.error;
+               v4l2_ctrl_handler_free(&state->hdl);
+-              kfree(state);
+               return err;
+       }
+       v4l2_ctrl_handler_setup(&state->hdl);
+       err = adv7393_initialize(&state->sd);
+-      if (err) {
++      if (err)
+               v4l2_ctrl_handler_free(&state->hdl);
+-              kfree(state);
+-      }
+       return err;
+ }
+@@ -464,7 +461,6 @@ static int adv7393_remove(struct i2c_client *client)
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(&state->hdl);
+-      kfree(state);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
+index 31a63c9..4cdcfc9 100644
+--- a/drivers/media/i2c/adv7604.c
++++ b/drivers/media/i2c/adv7604.c
+@@ -1968,7 +1968,7 @@ static int adv7604_probe(struct i2c_client *client,
+       v4l_dbg(1, debug, client, "detecting adv7604 client on address 0x%x\n",
+                       client->addr << 1);
+-      state = kzalloc(sizeof(struct adv7604_state), GFP_KERNEL);
++      state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
+       if (!state) {
+               v4l_err(client, "Could not allocate adv7604_state memory!\n");
+               return -ENOMEM;
+@@ -1977,8 +1977,7 @@ static int adv7604_probe(struct i2c_client *client,
+       /* platform data */
+       if (!pdata) {
+               v4l_err(client, "No platform data!\n");
+-              err = -ENODEV;
+-              goto err_state;
++              return -ENODEV;
+       }
+       memcpy(&state->pdata, pdata, sizeof(state->pdata));
+@@ -1991,8 +1990,7 @@ static int adv7604_probe(struct i2c_client *client,
+       if (adv_smbus_read_byte_data_check(client, 0xfb, false) != 0x68) {
+               v4l2_info(sd, "not an adv7604 on address 0x%x\n",
+                               client->addr << 1);
+-              err = -ENODEV;
+-              goto err_state;
++              return -ENODEV;
+       }
+       /* control handlers */
+@@ -2093,8 +2091,6 @@ err_i2c:
+       adv7604_unregister_clients(state);
+ err_hdl:
+       v4l2_ctrl_handler_free(hdl);
+-err_state:
+-      kfree(state);
+       return err;
+ }
+@@ -2111,7 +2107,6 @@ static int adv7604_remove(struct i2c_client *client)
+       media_entity_cleanup(&sd->entity);
+       adv7604_unregister_clients(to_state(sd));
+       v4l2_ctrl_handler_free(sd->ctrl_handler);
+-      kfree(to_state(sd));
+       return 0;
+ }
+diff --git a/drivers/media/i2c/ak881x.c b/drivers/media/i2c/ak881x.c
+index fd47465..b918c3f 100644
+--- a/drivers/media/i2c/ak881x.c
++++ b/drivers/media/i2c/ak881x.c
+@@ -264,7 +264,7 @@ static int ak881x_probe(struct i2c_client *client,
+               return -EIO;
+       }
+-      ak881x = kzalloc(sizeof(struct ak881x), GFP_KERNEL);
++      ak881x = devm_kzalloc(&client->dev, sizeof(*ak881x), GFP_KERNEL);
+       if (!ak881x)
+               return -ENOMEM;
+@@ -282,7 +282,6 @@ static int ak881x_probe(struct i2c_client *client,
+       default:
+               dev_err(&client->dev,
+                       "No ak881x chip detected, register read %x\n", data);
+-              kfree(ak881x);
+               return -ENODEV;
+       }
+@@ -331,7 +330,6 @@ static int ak881x_remove(struct i2c_client *client)
+       struct ak881x *ak881x = to_ak881x(client);
+       v4l2_device_unregister_subdev(&ak881x->subdev);
+-      kfree(ak881x);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/as3645a.c b/drivers/media/i2c/as3645a.c
+index 58d523f..301084b 100644
+--- a/drivers/media/i2c/as3645a.c
++++ b/drivers/media/i2c/as3645a.c
+@@ -813,7 +813,7 @@ static int as3645a_probe(struct i2c_client *client,
+       if (client->dev.platform_data == NULL)
+               return -ENODEV;
+-      flash = kzalloc(sizeof(*flash), GFP_KERNEL);
++      flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL);
+       if (flash == NULL)
+               return -ENOMEM;
+@@ -838,10 +838,8 @@ static int as3645a_probe(struct i2c_client *client,
+       flash->led_mode = V4L2_FLASH_LED_MODE_NONE;
+ done:
+-      if (ret < 0) {
++      if (ret < 0)
+               v4l2_ctrl_handler_free(&flash->ctrls);
+-              kfree(flash);
+-      }
+       return ret;
+ }
+@@ -855,7 +853,6 @@ static int as3645a_remove(struct i2c_client *client)
+       v4l2_ctrl_handler_free(&flash->ctrls);
+       media_entity_cleanup(&flash->subdev.entity);
+       mutex_destroy(&flash->power_lock);
+-      kfree(flash);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/bt819.c b/drivers/media/i2c/bt819.c
+index 377bf05..ee9ed67 100644
+--- a/drivers/media/i2c/bt819.c
++++ b/drivers/media/i2c/bt819.c
+@@ -425,7 +425,7 @@ static int bt819_probe(struct i2c_client *client,
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+               return -ENODEV;
+-      decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
++      decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
+       if (decoder == NULL)
+               return -ENOMEM;
+       sd = &decoder->sd;
+@@ -476,7 +476,6 @@ static int bt819_probe(struct i2c_client *client,
+               int err = decoder->hdl.error;
+               v4l2_ctrl_handler_free(&decoder->hdl);
+-              kfree(decoder);
+               return err;
+       }
+       v4l2_ctrl_handler_setup(&decoder->hdl);
+@@ -490,7 +489,6 @@ static int bt819_remove(struct i2c_client *client)
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(&decoder->hdl);
+-      kfree(decoder);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/bt856.c b/drivers/media/i2c/bt856.c
+index 7e5bd36..7e50111 100644
+--- a/drivers/media/i2c/bt856.c
++++ b/drivers/media/i2c/bt856.c
+@@ -216,7 +216,7 @@ static int bt856_probe(struct i2c_client *client,
+       v4l_info(client, "chip found @ 0x%x (%s)\n",
+                       client->addr << 1, client->adapter->name);
+-      encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL);
++      encoder = devm_kzalloc(&client->dev, sizeof(*encoder), GFP_KERNEL);
+       if (encoder == NULL)
+               return -ENOMEM;
+       sd = &encoder->sd;
+@@ -250,7 +250,6 @@ static int bt856_remove(struct i2c_client *client)
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       v4l2_device_unregister_subdev(sd);
+-      kfree(to_bt856(sd));
+       return 0;
+ }
+diff --git a/drivers/media/i2c/bt866.c b/drivers/media/i2c/bt866.c
+index 905320b..9355b92 100644
+--- a/drivers/media/i2c/bt866.c
++++ b/drivers/media/i2c/bt866.c
+@@ -207,7 +207,7 @@ static int bt866_probe(struct i2c_client *client,
+       v4l_info(client, "chip found @ 0x%x (%s)\n",
+                       client->addr << 1, client->adapter->name);
+-      encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
++      encoder = devm_kzalloc(&client->dev, sizeof(*encoder), GFP_KERNEL);
+       if (encoder == NULL)
+               return -ENOMEM;
+       sd = &encoder->sd;
+@@ -220,7 +220,6 @@ static int bt866_remove(struct i2c_client *client)
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       v4l2_device_unregister_subdev(sd);
+-      kfree(to_bt866(sd));
+       return 0;
+ }
+diff --git a/drivers/media/i2c/cs5345.c b/drivers/media/i2c/cs5345.c
+index 1d2f7c8..841b9c4 100644
+--- a/drivers/media/i2c/cs5345.c
++++ b/drivers/media/i2c/cs5345.c
+@@ -190,7 +190,7 @@ static int cs5345_probe(struct i2c_client *client,
+       v4l_info(client, "chip found @ 0x%x (%s)\n",
+                       client->addr << 1, client->adapter->name);
+-      state = kzalloc(sizeof(struct cs5345_state), GFP_KERNEL);
++      state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
+       if (state == NULL)
+               return -ENOMEM;
+       sd = &state->sd;
+@@ -206,7 +206,6 @@ static int cs5345_probe(struct i2c_client *client,
+               int err = state->hdl.error;
+               v4l2_ctrl_handler_free(&state->hdl);
+-              kfree(state);
+               return err;
+       }
+       /* set volume/mute */
+@@ -227,7 +226,6 @@ static int cs5345_remove(struct i2c_client *client)
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(&state->hdl);
+-      kfree(state);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/cs53l32a.c b/drivers/media/i2c/cs53l32a.c
+index b293912..1082fb7 100644
+--- a/drivers/media/i2c/cs53l32a.c
++++ b/drivers/media/i2c/cs53l32a.c
+@@ -175,7 +175,7 @@ static int cs53l32a_probe(struct i2c_client *client,
+       v4l_info(client, "chip found @ 0x%x (%s)\n",
+                       client->addr << 1, client->adapter->name);
+-      state = kzalloc(sizeof(struct cs53l32a_state), GFP_KERNEL);
++      state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
+       if (state == NULL)
+               return -ENOMEM;
+       sd = &state->sd;
+@@ -197,7 +197,6 @@ static int cs53l32a_probe(struct i2c_client *client,
+               int err = state->hdl.error;
+               v4l2_ctrl_handler_free(&state->hdl);
+-              kfree(state);
+               return err;
+       }
+@@ -228,7 +227,6 @@ static int cs53l32a_remove(struct i2c_client *client)
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(&state->hdl);
+-      kfree(state);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c
+index 12fb9b2..bdfec4c 100644
+--- a/drivers/media/i2c/cx25840/cx25840-core.c
++++ b/drivers/media/i2c/cx25840/cx25840-core.c
+@@ -5190,7 +5190,7 @@ static int cx25840_probe(struct i2c_client *client,
+               return -ENODEV;
+       }
+-      state = kzalloc(sizeof(struct cx25840_state), GFP_KERNEL);
++      state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
+       if (state == NULL)
+               return -ENOMEM;
+@@ -5292,7 +5292,6 @@ static int cx25840_probe(struct i2c_client *client,
+               int err = state->hdl.error;
+               v4l2_ctrl_handler_free(&state->hdl);
+-              kfree(state);
+               return err;
+       }
+       if (!is_cx2583x(state))
+@@ -5317,7 +5316,6 @@ static int cx25840_remove(struct i2c_client *client)
+       cx25840_ir_remove(sd);
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(&state->hdl);
+-      kfree(state);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/cx25840/cx25840-ir.c b/drivers/media/i2c/cx25840/cx25840-ir.c
+index 9ae977b..e6588ee 100644
+--- a/drivers/media/i2c/cx25840/cx25840-ir.c
++++ b/drivers/media/i2c/cx25840/cx25840-ir.c
+@@ -1230,16 +1230,14 @@ int cx25840_ir_probe(struct v4l2_subdev *sd)
+       if (!(is_cx23885(state) || is_cx23887(state)))
+               return 0;
+-      ir_state = kzalloc(sizeof(struct cx25840_ir_state), GFP_KERNEL);
++      ir_state = devm_kzalloc(&state->c->dev, sizeof(*ir_state), GFP_KERNEL);
+       if (ir_state == NULL)
+               return -ENOMEM;
+       spin_lock_init(&ir_state->rx_kfifo_lock);
+       if (kfifo_alloc(&ir_state->rx_kfifo,
+-                      CX25840_IR_RX_KFIFO_SIZE, GFP_KERNEL)) {
+-              kfree(ir_state);
++                      CX25840_IR_RX_KFIFO_SIZE, GFP_KERNEL))
+               return -ENOMEM;
+-      }
+       ir_state->c = state->c;
+       state->ir_state = ir_state;
+@@ -1273,7 +1271,6 @@ int cx25840_ir_remove(struct v4l2_subdev *sd)
+       cx25840_ir_tx_shutdown(sd);
+       kfifo_free(&ir_state->rx_kfifo);
+-      kfree(ir_state);
+       state->ir_state = NULL;
+       return 0;
+ }
+diff --git a/drivers/media/i2c/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c
+index 8e2f79c..82bf567 100644
+--- a/drivers/media/i2c/ir-kbd-i2c.c
++++ b/drivers/media/i2c/ir-kbd-i2c.c
+@@ -295,7 +295,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
+       unsigned short addr = client->addr;
+       int err;
+-      ir = kzalloc(sizeof(struct IR_i2c), GFP_KERNEL);
++      ir = devm_kzalloc(&client->dev, sizeof(*ir), GFP_KERNEL);
+       if (!ir)
+               return -ENOMEM;
+@@ -398,10 +398,8 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
+                * internally
+                */
+               rc = rc_allocate_device();
+-              if (!rc) {
+-                      err = -ENOMEM;
+-                      goto err_out_free;
+-              }
++              if (!rc)
++                      return -ENOMEM;
+       }
+       ir->rc = rc;
+@@ -454,7 +452,6 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
+  err_out_free:
+       /* Only frees rc if it were allocated internally */
+       rc_free_device(rc);
+-      kfree(ir);
+       return err;
+ }
+@@ -470,7 +467,6 @@ static int ir_remove(struct i2c_client *client)
+               rc_unregister_device(ir->rc);
+       /* free memory */
+-      kfree(ir);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/ks0127.c b/drivers/media/i2c/ks0127.c
+index 04a6efa..c722776 100644
+--- a/drivers/media/i2c/ks0127.c
++++ b/drivers/media/i2c/ks0127.c
+@@ -685,7 +685,7 @@ static int ks0127_probe(struct i2c_client *client, const struct i2c_device_id *i
+               client->addr == (I2C_KS0127_ADDON >> 1) ? "addon" : "on-board",
+               client->addr << 1, client->adapter->name);
+-      ks = kzalloc(sizeof(*ks), GFP_KERNEL);
++      ks = devm_kzalloc(&client->dev, sizeof(*ks), GFP_KERNEL);
+       if (ks == NULL)
+               return -ENOMEM;
+       sd = &ks->sd;
+@@ -708,7 +708,6 @@ static int ks0127_remove(struct i2c_client *client)
+       v4l2_device_unregister_subdev(sd);
+       ks0127_write(sd, KS_OFMTA, 0x20); /* tristate */
+       ks0127_write(sd, KS_CMDA, 0x2c | 0x80); /* power down */
+-      kfree(to_ks0127(sd));
+       return 0;
+ }
+diff --git a/drivers/media/i2c/m52790.c b/drivers/media/i2c/m52790.c
+index 39f50fd..0d153f3 100644
+--- a/drivers/media/i2c/m52790.c
++++ b/drivers/media/i2c/m52790.c
+@@ -174,7 +174,7 @@ static int m52790_probe(struct i2c_client *client,
+       v4l_info(client, "chip found @ 0x%x (%s)\n",
+                       client->addr << 1, client->adapter->name);
+-      state = kzalloc(sizeof(struct m52790_state), GFP_KERNEL);
++      state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
+       if (state == NULL)
+               return -ENOMEM;
+@@ -191,7 +191,6 @@ static int m52790_remove(struct i2c_client *client)
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       v4l2_device_unregister_subdev(sd);
+-      kfree(to_state(sd));
+       return 0;
+ }
+diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c
+index 77e1237..4f549fa 100644
+--- a/drivers/media/i2c/m5mols/m5mols_core.c
++++ b/drivers/media/i2c/m5mols/m5mols_core.c
+@@ -971,7 +971,7 @@ static int m5mols_probe(struct i2c_client *client,
+               return -EINVAL;
+       }
+-      info = kzalloc(sizeof(struct m5mols_info), GFP_KERNEL);
++      info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+@@ -983,7 +983,7 @@ static int m5mols_probe(struct i2c_client *client,
+       ret = gpio_request_one(pdata->gpio_reset, gpio_flags, "M5MOLS_NRST");
+       if (ret) {
+               dev_err(&client->dev, "Failed to request gpio: %d\n", ret);
+-              goto out_free;
++              return ret;
+       }
+       ret = regulator_bulk_get(&client->dev, ARRAY_SIZE(supplies), supplies);
+@@ -1036,8 +1036,6 @@ out_reg:
+       regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
+ out_gpio:
+       gpio_free(pdata->gpio_reset);
+-out_free:
+-      kfree(info);
+       return ret;
+ }
+@@ -1053,7 +1051,7 @@ static int m5mols_remove(struct i2c_client *client)
+       regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
+       gpio_free(info->pdata->gpio_reset);
+       media_entity_cleanup(&sd->entity);
+-      kfree(info);
++
+       return 0;
+ }
+diff --git a/drivers/media/i2c/msp3400-driver.c b/drivers/media/i2c/msp3400-driver.c
+index 54a9dd3..ae92c20 100644
+--- a/drivers/media/i2c/msp3400-driver.c
++++ b/drivers/media/i2c/msp3400-driver.c
+@@ -707,7 +707,7 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
+               return -ENODEV;
+       }
+-      state = kzalloc(sizeof(*state), GFP_KERNEL);
++      state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
+       if (!state)
+               return -ENOMEM;
+@@ -732,7 +732,6 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
+       if (state->rev1 == -1 || (state->rev1 == 0 && state->rev2 == 0)) {
+               v4l_dbg(1, msp_debug, client,
+                               "not an msp3400 (cannot read chip version)\n");
+-              kfree(state);
+               return -ENODEV;
+       }
+@@ -827,7 +826,6 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
+               int err = hdl->error;
+               v4l2_ctrl_handler_free(hdl);
+-              kfree(state);
+               return err;
+       }
+@@ -889,7 +887,6 @@ static int msp_remove(struct i2c_client *client)
+       msp_reset(client);
+       v4l2_ctrl_handler_free(&state->hdl);
+-      kfree(state);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/mt9m032.c b/drivers/media/i2c/mt9m032.c
+index 8edb3d8..cca704e 100644
+--- a/drivers/media/i2c/mt9m032.c
++++ b/drivers/media/i2c/mt9m032.c
+@@ -730,7 +730,7 @@ static int mt9m032_probe(struct i2c_client *client,
+       if (!client->dev.platform_data)
+               return -ENODEV;
+-      sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
++      sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL);
+       if (sensor == NULL)
+               return -ENOMEM;
+@@ -860,7 +860,6 @@ error_ctrl:
+       v4l2_ctrl_handler_free(&sensor->ctrls);
+ error_sensor:
+       mutex_destroy(&sensor->lock);
+-      kfree(sensor);
+       return ret;
+ }
+@@ -873,7 +872,6 @@ static int mt9m032_remove(struct i2c_client *client)
+       v4l2_ctrl_handler_free(&sensor->ctrls);
+       media_entity_cleanup(&subdev->entity);
+       mutex_destroy(&sensor->lock);
+-      kfree(sensor);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/mt9t001.c b/drivers/media/i2c/mt9t001.c
+index 2e189d8..7964634 100644
+--- a/drivers/media/i2c/mt9t001.c
++++ b/drivers/media/i2c/mt9t001.c
+@@ -740,7 +740,7 @@ static int mt9t001_probe(struct i2c_client *client,
+       if (ret < 0)
+               return ret;
+-      mt9t001 = kzalloc(sizeof(*mt9t001), GFP_KERNEL);
++      mt9t001 = devm_kzalloc(&client->dev, sizeof(*mt9t001), GFP_KERNEL);
+       if (!mt9t001)
+               return -ENOMEM;
+@@ -801,7 +801,6 @@ done:
+       if (ret < 0) {
+               v4l2_ctrl_handler_free(&mt9t001->ctrls);
+               media_entity_cleanup(&mt9t001->subdev.entity);
+-              kfree(mt9t001);
+       }
+       return ret;
+@@ -815,7 +814,6 @@ static int mt9t001_remove(struct i2c_client *client)
+       v4l2_ctrl_handler_free(&mt9t001->ctrls);
+       v4l2_device_unregister_subdev(subdev);
+       media_entity_cleanup(&subdev->entity);
+-      kfree(mt9t001);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/mt9v011.c b/drivers/media/i2c/mt9v011.c
+index 3f415fd..c64c9d9 100644
+--- a/drivers/media/i2c/mt9v011.c
++++ b/drivers/media/i2c/mt9v011.c
+@@ -526,7 +526,7 @@ static int mt9v011_probe(struct i2c_client *c,
+            I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
+               return -EIO;
+-      core = kzalloc(sizeof(struct mt9v011), GFP_KERNEL);
++      core = devm_kzalloc(&c->dev, sizeof(struct mt9v011), GFP_KERNEL);
+       if (!core)
+               return -ENOMEM;
+@@ -539,7 +539,6 @@ static int mt9v011_probe(struct i2c_client *c,
+           (version != MT9V011_REV_B_VERSION)) {
+               v4l2_info(sd, "*** unknown micron chip detected (0x%04x).\n",
+                         version);
+-              kfree(core);
+               return -EINVAL;
+       }
+@@ -562,7 +561,6 @@ static int mt9v011_probe(struct i2c_client *c,
+               v4l2_err(sd, "control initialization error %d\n", ret);
+               v4l2_ctrl_handler_free(&core->ctrls);
+-              kfree(core);
+               return ret;
+       }
+       core->sd.ctrl_handler = &core->ctrls;
+@@ -598,7 +596,7 @@ static int mt9v011_remove(struct i2c_client *c)
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(&core->ctrls);
+-      kfree(to_mt9v011(sd));
++
+       return 0;
+ }
+diff --git a/drivers/media/i2c/noon010pc30.c b/drivers/media/i2c/noon010pc30.c
+index a115842..d205522 100644
+--- a/drivers/media/i2c/noon010pc30.c
++++ b/drivers/media/i2c/noon010pc30.c
+@@ -712,7 +712,7 @@ static int noon010_probe(struct i2c_client *client,
+               return -EIO;
+       }
+-      info = kzalloc(sizeof(*info), GFP_KERNEL);
++      info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+@@ -796,7 +796,6 @@ np_gpio_err:
+ np_err:
+       v4l2_ctrl_handler_free(&info->hdl);
+       v4l2_device_unregister_subdev(sd);
+-      kfree(info);
+       return ret;
+ }
+@@ -817,7 +816,7 @@ static int noon010_remove(struct i2c_client *client)
+               gpio_free(info->gpio_nstby);
+       media_entity_cleanup(&sd->entity);
+-      kfree(info);
++
+       return 0;
+ }
+diff --git a/drivers/media/i2c/ov7640.c b/drivers/media/i2c/ov7640.c
+index b0cc927..5e117ab 100644
+--- a/drivers/media/i2c/ov7640.c
++++ b/drivers/media/i2c/ov7640.c
+@@ -59,7 +59,7 @@ static int ov7640_probe(struct i2c_client *client,
+       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+               return -ENODEV;
+-      sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
++      sd = devm_kzalloc(&client->dev, sizeof(*sd), GFP_KERNEL);
+       if (sd == NULL)
+               return -ENOMEM;
+       v4l2_i2c_subdev_init(sd, client, &ov7640_ops);
+@@ -71,7 +71,6 @@ static int ov7640_probe(struct i2c_client *client,
+       if (write_regs(client, initial_registers) < 0) {
+               v4l_err(client, "error initializing OV7640\n");
+-              kfree(sd);
+               return -ENODEV;
+       }
+@@ -84,7 +83,7 @@ static int ov7640_remove(struct i2c_client *client)
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       v4l2_device_unregister_subdev(sd);
+-      kfree(sd);
++
+       return 0;
+ }
+diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c
+index 617ad3f..d71602f 100644
+--- a/drivers/media/i2c/ov7670.c
++++ b/drivers/media/i2c/ov7670.c
+@@ -1552,7 +1552,7 @@ static int ov7670_probe(struct i2c_client *client,
+       struct ov7670_info *info;
+       int ret;
+-      info = kzalloc(sizeof(struct ov7670_info), GFP_KERNEL);
++      info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
+       if (info == NULL)
+               return -ENOMEM;
+       sd = &info->sd;
+@@ -1590,7 +1590,6 @@ static int ov7670_probe(struct i2c_client *client,
+               v4l_dbg(1, debug, client,
+                       "chip found @ 0x%x (%s) is not an ov7670 chip.\n",
+                       client->addr << 1, client->adapter->name);
+-              kfree(info);
+               return ret;
+       }
+       v4l_info(client, "chip found @ 0x%02x (%s)\n",
+@@ -1635,7 +1634,6 @@ static int ov7670_probe(struct i2c_client *client,
+               int err = info->hdl.error;
+               v4l2_ctrl_handler_free(&info->hdl);
+-              kfree(info);
+               return err;
+       }
+       /*
+@@ -1659,7 +1657,6 @@ static int ov7670_remove(struct i2c_client *client)
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(&info->hdl);
+-      kfree(info);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/saa6588.c b/drivers/media/i2c/saa6588.c
+index b4e1ccb..729e78d 100644
+--- a/drivers/media/i2c/saa6588.c
++++ b/drivers/media/i2c/saa6588.c
+@@ -478,17 +478,15 @@ static int saa6588_probe(struct i2c_client *client,
+       v4l_info(client, "saa6588 found @ 0x%x (%s)\n",
+                       client->addr << 1, client->adapter->name);
+-      s = kzalloc(sizeof(*s), GFP_KERNEL);
++      s = devm_kzalloc(&client->dev, sizeof(*s), GFP_KERNEL);
+       if (s == NULL)
+               return -ENOMEM;
+       s->buf_size = bufblocks * 3;
+-      s->buffer = kmalloc(s->buf_size, GFP_KERNEL);
+-      if (s->buffer == NULL) {
+-              kfree(s);
++      s->buffer = devm_kzalloc(&client->dev, s->buf_size, GFP_KERNEL);
++      if (s->buffer == NULL)
+               return -ENOMEM;
+-      }
+       sd = &s->sd;
+       v4l2_i2c_subdev_init(sd, client, &saa6588_ops);
+       spin_lock_init(&s->lock);
+@@ -516,8 +514,6 @@ static int saa6588_remove(struct i2c_client *client)
+       cancel_delayed_work_sync(&s->work);
+-      kfree(s->buffer);
+-      kfree(s);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/saa7110.c b/drivers/media/i2c/saa7110.c
+index 51cd4c8..e4026aa 100644
+--- a/drivers/media/i2c/saa7110.c
++++ b/drivers/media/i2c/saa7110.c
+@@ -406,7 +406,7 @@ static int saa7110_probe(struct i2c_client *client,
+       v4l_info(client, "chip found @ 0x%x (%s)\n",
+                       client->addr << 1, client->adapter->name);
+-      decoder = kzalloc(sizeof(struct saa7110), GFP_KERNEL);
++      decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
+       if (!decoder)
+               return -ENOMEM;
+       sd = &decoder->sd;
+@@ -428,7 +428,6 @@ static int saa7110_probe(struct i2c_client *client,
+               int err = decoder->hdl.error;
+               v4l2_ctrl_handler_free(&decoder->hdl);
+-              kfree(decoder);
+               return err;
+       }
+       v4l2_ctrl_handler_setup(&decoder->hdl);
+@@ -469,7 +468,6 @@ static int saa7110_remove(struct i2c_client *client)
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(&decoder->hdl);
+-      kfree(decoder);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/saa7115.c b/drivers/media/i2c/saa7115.c
+index 52c717d..eecb92d 100644
+--- a/drivers/media/i2c/saa7115.c
++++ b/drivers/media/i2c/saa7115.c
+@@ -1614,7 +1614,7 @@ static int saa711x_probe(struct i2c_client *client,
+       v4l_info(client, "saa711%c found (%s) @ 0x%x (%s)\n", chip_id, name,
+                client->addr << 1, client->adapter->name);
+-      state = kzalloc(sizeof(struct saa711x_state), GFP_KERNEL);
++      state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
+       if (state == NULL)
+               return -ENOMEM;
+       sd = &state->sd;
+@@ -1640,7 +1640,6 @@ static int saa711x_probe(struct i2c_client *client,
+               int err = hdl->error;
+               v4l2_ctrl_handler_free(hdl);
+-              kfree(state);
+               return err;
+       }
+       v4l2_ctrl_auto_cluster(2, &state->agc, 0, true);
+@@ -1712,7 +1711,6 @@ static int saa711x_remove(struct i2c_client *client)
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(sd->ctrl_handler);
+-      kfree(to_state(sd));
+       return 0;
+ }
+diff --git a/drivers/media/i2c/saa7127.c b/drivers/media/i2c/saa7127.c
+index 8a47ac1..9882c83 100644
+--- a/drivers/media/i2c/saa7127.c
++++ b/drivers/media/i2c/saa7127.c
+@@ -752,7 +752,7 @@ static int saa7127_probe(struct i2c_client *client,
+       v4l_dbg(1, debug, client, "detecting saa7127 client on address 0x%x\n",
+                       client->addr << 1);
+-      state = kzalloc(sizeof(struct saa7127_state), GFP_KERNEL);
++      state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
+       if (state == NULL)
+               return -ENOMEM;
+@@ -767,7 +767,6 @@ static int saa7127_probe(struct i2c_client *client,
+       if ((saa7127_read(sd, 0) & 0xe4) != 0 ||
+                       (saa7127_read(sd, 0x29) & 0x3f) != 0x1d) {
+               v4l2_dbg(1, debug, sd, "saa7127 not found\n");
+-              kfree(state);
+               return -ENODEV;
+       }
+@@ -823,7 +822,6 @@ static int saa7127_remove(struct i2c_client *client)
+       v4l2_device_unregister_subdev(sd);
+       /* Turn off TV output */
+       saa7127_set_video_enable(sd, 0);
+-      kfree(to_state(sd));
+       return 0;
+ }
+diff --git a/drivers/media/i2c/saa717x.c b/drivers/media/i2c/saa717x.c
+index cf3a0aa..7132810 100644
+--- a/drivers/media/i2c/saa717x.c
++++ b/drivers/media/i2c/saa717x.c
+@@ -1262,7 +1262,7 @@ static int saa717x_probe(struct i2c_client *client,
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+               return -EIO;
+-      decoder = kzalloc(sizeof(struct saa717x_state), GFP_KERNEL);
++      decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
+       if (decoder == NULL)
+               return -ENOMEM;
+@@ -1276,7 +1276,6 @@ static int saa717x_probe(struct i2c_client *client,
+               id = saa717x_read(sd, 0x5a0);
+       if (id != 0xc2 && id != 0x32 && id != 0xf2 && id != 0x6c) {
+               v4l2_dbg(1, debug, sd, "saa717x not found (id=%02x)\n", id);
+-              kfree(decoder);
+               return -ENODEV;
+       }
+       if (id == 0xc2)
+@@ -1316,7 +1315,6 @@ static int saa717x_probe(struct i2c_client *client,
+               int err = hdl->error;
+               v4l2_ctrl_handler_free(hdl);
+-              kfree(decoder);
+               return err;
+       }
+@@ -1353,7 +1351,6 @@ static int saa717x_remove(struct i2c_client *client)
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(sd->ctrl_handler);
+-      kfree(to_state(sd));
+       return 0;
+ }
+diff --git a/drivers/media/i2c/saa7185.c b/drivers/media/i2c/saa7185.c
+index 2c6b65c..e95a0ed 100644
+--- a/drivers/media/i2c/saa7185.c
++++ b/drivers/media/i2c/saa7185.c
+@@ -326,7 +326,7 @@ static int saa7185_probe(struct i2c_client *client,
+       v4l_info(client, "chip found @ 0x%x (%s)\n",
+                       client->addr << 1, client->adapter->name);
+-      encoder = kzalloc(sizeof(struct saa7185), GFP_KERNEL);
++      encoder = devm_kzalloc(&client->dev, sizeof(*encoder), GFP_KERNEL);
+       if (encoder == NULL)
+               return -ENOMEM;
+       encoder->norm = V4L2_STD_NTSC;
+@@ -352,7 +352,6 @@ static int saa7185_remove(struct i2c_client *client)
+       v4l2_device_unregister_subdev(sd);
+       /* SW: output off is active */
+       saa7185_write(sd, 0x61, (encoder->reg[0x61]) | 0x40);
+-      kfree(encoder);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/saa7191.c b/drivers/media/i2c/saa7191.c
+index d7d1670..84f7899 100644
+--- a/drivers/media/i2c/saa7191.c
++++ b/drivers/media/i2c/saa7191.c
+@@ -605,7 +605,7 @@ static int saa7191_probe(struct i2c_client *client,
+       v4l_info(client, "chip found @ 0x%x (%s)\n",
+                       client->addr << 1, client->adapter->name);
+-      decoder = kzalloc(sizeof(*decoder), GFP_KERNEL);
++      decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
+       if (!decoder)
+               return -ENOMEM;
+@@ -615,7 +615,6 @@ static int saa7191_probe(struct i2c_client *client,
+       err = saa7191_write_block(sd, sizeof(initseq), initseq);
+       if (err) {
+               printk(KERN_ERR "SAA7191 initialization failed\n");
+-              kfree(decoder);
+               return err;
+       }
+@@ -636,7 +635,6 @@ static int saa7191_remove(struct i2c_client *client)
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       v4l2_device_unregister_subdev(sd);
+-      kfree(to_saa7191(sd));
+       return 0;
+ }
+diff --git a/drivers/media/i2c/sony-btf-mpx.c b/drivers/media/i2c/sony-btf-mpx.c
+index 38cbea9..efa3061 100644
+--- a/drivers/media/i2c/sony-btf-mpx.c
++++ b/drivers/media/i2c/sony-btf-mpx.c
+@@ -355,7 +355,7 @@ static int sony_btf_mpx_probe(struct i2c_client *client,
+       v4l_info(client, "chip found @ 0x%x (%s)\n",
+                       client->addr << 1, client->adapter->name);
+-      t = kzalloc(sizeof(struct sony_btf_mpx), GFP_KERNEL);
++      t = devm_kzalloc(&client->dev, sizeof(*t), GFP_KERNEL);
+       if (t == NULL)
+               return -ENOMEM;
+@@ -374,7 +374,6 @@ static int sony_btf_mpx_remove(struct i2c_client *client)
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       v4l2_device_unregister_subdev(sd);
+-      kfree(to_state(sd));
+       return 0;
+ }
+diff --git a/drivers/media/i2c/sr030pc30.c b/drivers/media/i2c/sr030pc30.c
+index e9d95bd..4c5a9ee 100644
+--- a/drivers/media/i2c/sr030pc30.c
++++ b/drivers/media/i2c/sr030pc30.c
+@@ -820,7 +820,7 @@ static int sr030pc30_probe(struct i2c_client *client,
+       if (ret)
+               return ret;
+-      info = kzalloc(sizeof(*info), GFP_KERNEL);
++      info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+@@ -841,10 +841,8 @@ static int sr030pc30_probe(struct i2c_client *client,
+ static int sr030pc30_remove(struct i2c_client *client)
+ {
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+-      struct sr030pc30_info *info = to_sr030pc30(sd);
+       v4l2_device_unregister_subdev(sd);
+-      kfree(info);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/tda7432.c b/drivers/media/i2c/tda7432.c
+index 28b5121..72af644 100644
+--- a/drivers/media/i2c/tda7432.c
++++ b/drivers/media/i2c/tda7432.c
+@@ -359,7 +359,7 @@ static int tda7432_probe(struct i2c_client *client,
+       v4l_info(client, "chip found @ 0x%02x (%s)\n",
+                       client->addr << 1, client->adapter->name);
+-      t = kzalloc(sizeof(*t), GFP_KERNEL);
++      t = devm_kzalloc(&client->dev, sizeof(*t), GFP_KERNEL);
+       if (!t)
+               return -ENOMEM;
+       sd = &t->sd;
+@@ -380,7 +380,6 @@ static int tda7432_probe(struct i2c_client *client,
+               int err = t->hdl.error;
+               v4l2_ctrl_handler_free(&t->hdl);
+-              kfree(t);
+               return err;
+       }
+       v4l2_ctrl_cluster(2, &t->bass);
+@@ -406,7 +405,6 @@ static int tda7432_remove(struct i2c_client *client)
+       tda7432_set(sd);
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(&t->hdl);
+-      kfree(t);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/tda9840.c b/drivers/media/i2c/tda9840.c
+index 01441e3..3f12662 100644
+--- a/drivers/media/i2c/tda9840.c
++++ b/drivers/media/i2c/tda9840.c
+@@ -184,7 +184,7 @@ static int tda9840_probe(struct i2c_client *client,
+       v4l_info(client, "chip found @ 0x%x (%s)\n",
+                       client->addr << 1, client->adapter->name);
+-      sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
++      sd = devm_kzalloc(&client->dev, sizeof(*sd), GFP_KERNEL);
+       if (sd == NULL)
+               return -ENOMEM;
+       v4l2_i2c_subdev_init(sd, client, &tda9840_ops);
+@@ -201,7 +201,6 @@ static int tda9840_remove(struct i2c_client *client)
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       v4l2_device_unregister_subdev(sd);
+-      kfree(sd);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/tea6415c.c b/drivers/media/i2c/tea6415c.c
+index 3d5b06a..52ebc38 100644
+--- a/drivers/media/i2c/tea6415c.c
++++ b/drivers/media/i2c/tea6415c.c
+@@ -152,7 +152,7 @@ static int tea6415c_probe(struct i2c_client *client,
+       v4l_info(client, "chip found @ 0x%x (%s)\n",
+                       client->addr << 1, client->adapter->name);
+-      sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
++      sd = devm_kzalloc(&client->dev, sizeof(*sd), GFP_KERNEL);
+       if (sd == NULL)
+               return -ENOMEM;
+       v4l2_i2c_subdev_init(sd, client, &tea6415c_ops);
+@@ -164,7 +164,6 @@ static int tea6415c_remove(struct i2c_client *client)
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       v4l2_device_unregister_subdev(sd);
+-      kfree(sd);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/tea6420.c b/drivers/media/i2c/tea6420.c
+index 3875721..1f86974 100644
+--- a/drivers/media/i2c/tea6420.c
++++ b/drivers/media/i2c/tea6420.c
+@@ -125,7 +125,7 @@ static int tea6420_probe(struct i2c_client *client,
+       v4l_info(client, "chip found @ 0x%x (%s)\n",
+                       client->addr << 1, client->adapter->name);
+-      sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
++      sd = devm_kzalloc(&client->dev, sizeof(*sd), GFP_KERNEL);
+       if (sd == NULL)
+               return -ENOMEM;
+       v4l2_i2c_subdev_init(sd, client, &tea6420_ops);
+@@ -146,7 +146,6 @@ static int tea6420_remove(struct i2c_client *client)
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       v4l2_device_unregister_subdev(sd);
+-      kfree(sd);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/tlv320aic23b.c b/drivers/media/i2c/tlv320aic23b.c
+index 809a75a..ef87f7b 100644
+--- a/drivers/media/i2c/tlv320aic23b.c
++++ b/drivers/media/i2c/tlv320aic23b.c
+@@ -162,7 +162,7 @@ static int tlv320aic23b_probe(struct i2c_client *client,
+       v4l_info(client, "chip found @ 0x%x (%s)\n",
+                       client->addr << 1, client->adapter->name);
+-      state = kzalloc(sizeof(struct tlv320aic23b_state), GFP_KERNEL);
++      state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
+       if (state == NULL)
+               return -ENOMEM;
+       sd = &state->sd;
+@@ -191,7 +191,6 @@ static int tlv320aic23b_probe(struct i2c_client *client,
+               int err = state->hdl.error;
+               v4l2_ctrl_handler_free(&state->hdl);
+-              kfree(state);
+               return err;
+       }
+       v4l2_ctrl_handler_setup(&state->hdl);
+@@ -205,7 +204,6 @@ static int tlv320aic23b_remove(struct i2c_client *client)
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(&state->hdl);
+-      kfree(state);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/tvaudio.c b/drivers/media/i2c/tvaudio.c
+index b72a59d..fc69e9c 100644
+--- a/drivers/media/i2c/tvaudio.c
++++ b/drivers/media/i2c/tvaudio.c
+@@ -1910,7 +1910,7 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id *
+               printk("\n");
+       }
+-      chip = kzalloc(sizeof(*chip), GFP_KERNEL);
++      chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
+       if (!chip)
+               return -ENOMEM;
+       sd = &chip->sd;
+@@ -1930,7 +1930,6 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id *
+       }
+       if (desc->name == NULL) {
+               v4l2_dbg(1, debug, sd, "no matching chip description found\n");
+-              kfree(chip);
+               return -EIO;
+       }
+       v4l2_info(sd, "%s found @ 0x%x (%s)\n", desc->name, client->addr<<1, client->adapter->name);
+@@ -2001,7 +2000,6 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id *
+               int err = chip->hdl.error;
+               v4l2_ctrl_handler_free(&chip->hdl);
+-              kfree(chip);
+               return err;
+       }
+       /* set controls to the default values */
+@@ -2043,7 +2041,6 @@ static int tvaudio_remove(struct i2c_client *client)
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(&chip->hdl);
+-      kfree(chip);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
+index 485159a..de9db3b 100644
+--- a/drivers/media/i2c/tvp5150.c
++++ b/drivers/media/i2c/tvp5150.c
+@@ -1152,10 +1152,9 @@ static int tvp5150_probe(struct i2c_client *c,
+            I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
+               return -EIO;
+-      core = kzalloc(sizeof(struct tvp5150), GFP_KERNEL);
+-      if (!core) {
++      core = devm_kzalloc(&c->dev, sizeof(*core), GFP_KERNEL);
++      if (!core)
+               return -ENOMEM;
+-      }
+       sd = &core->sd;
+       v4l2_i2c_subdev_init(sd, c, &tvp5150_ops);
+@@ -1166,7 +1165,7 @@ static int tvp5150_probe(struct i2c_client *c,
+       for (i = 0; i < 4; i++) {
+               res = tvp5150_read(sd, TVP5150_MSB_DEV_ID + i);
+               if (res < 0)
+-                      goto free_core;
++                      return res;
+               tvp5150_id[i] = res;
+       }
+@@ -1209,7 +1208,7 @@ static int tvp5150_probe(struct i2c_client *c,
+       if (core->hdl.error) {
+               res = core->hdl.error;
+               v4l2_ctrl_handler_free(&core->hdl);
+-              goto free_core;
++              return res;
+       }
+       v4l2_ctrl_handler_setup(&core->hdl);
+@@ -1225,10 +1224,6 @@ static int tvp5150_probe(struct i2c_client *c,
+       if (debug > 1)
+               tvp5150_log_status(sd);
+       return 0;
+-
+-free_core:
+-      kfree(core);
+-      return res;
+ }
+ static int tvp5150_remove(struct i2c_client *c)
+@@ -1242,7 +1237,6 @@ static int tvp5150_remove(struct i2c_client *c)
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(&decoder->hdl);
+-      kfree(to_tvp5150(sd));
+       return 0;
+ }
+diff --git a/drivers/media/i2c/tw2804.c b/drivers/media/i2c/tw2804.c
+index c5dc2c3..41a5c9b 100644
+--- a/drivers/media/i2c/tw2804.c
++++ b/drivers/media/i2c/tw2804.c
+@@ -368,8 +368,7 @@ static int tw2804_probe(struct i2c_client *client,
+       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+               return -ENODEV;
+-      state = kzalloc(sizeof(struct tw2804), GFP_KERNEL);
+-
++      state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
+       if (state == NULL)
+               return -ENOMEM;
+       sd = &state->sd;
+@@ -410,7 +409,6 @@ static int tw2804_probe(struct i2c_client *client,
+       err = state->hdl.error;
+       if (err) {
+               v4l2_ctrl_handler_free(&state->hdl);
+-              kfree(state);
+               return err;
+       }
+@@ -427,7 +425,6 @@ static int tw2804_remove(struct i2c_client *client)
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(&state->hdl);
+-      kfree(state);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/tw9903.c b/drivers/media/i2c/tw9903.c
+index 87880b1..285b759 100644
+--- a/drivers/media/i2c/tw9903.c
++++ b/drivers/media/i2c/tw9903.c
+@@ -215,7 +215,7 @@ static int tw9903_probe(struct i2c_client *client,
+       v4l_info(client, "chip found @ 0x%02x (%s)\n",
+                       client->addr << 1, client->adapter->name);
+-      dec = kzalloc(sizeof(struct tw9903), GFP_KERNEL);
++      dec = devm_kzalloc(&client->dev, sizeof(*dec), GFP_KERNEL);
+       if (dec == NULL)
+               return -ENOMEM;
+       sd = &dec->sd;
+@@ -233,7 +233,6 @@ static int tw9903_probe(struct i2c_client *client,
+               int err = hdl->error;
+               v4l2_ctrl_handler_free(hdl);
+-              kfree(dec);
+               return err;
+       }
+@@ -242,7 +241,6 @@ static int tw9903_probe(struct i2c_client *client,
+       if (write_regs(sd, initial_registers) < 0) {
+               v4l2_err(client, "error initializing TW9903\n");
+-              kfree(dec);
+               return -EINVAL;
+       }
+@@ -255,7 +253,6 @@ static int tw9903_remove(struct i2c_client *client)
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(&to_state(sd)->hdl);
+-      kfree(to_state(sd));
+       return 0;
+ }
+diff --git a/drivers/media/i2c/tw9906.c b/drivers/media/i2c/tw9906.c
+index accd79e..f6bef25 100644
+--- a/drivers/media/i2c/tw9906.c
++++ b/drivers/media/i2c/tw9906.c
+@@ -183,7 +183,7 @@ static int tw9906_probe(struct i2c_client *client,
+       v4l_info(client, "chip found @ 0x%02x (%s)\n",
+                       client->addr << 1, client->adapter->name);
+-      dec = kzalloc(sizeof(struct tw9906), GFP_KERNEL);
++      dec = devm_kzalloc(&client->dev, sizeof(*dec), GFP_KERNEL);
+       if (dec == NULL)
+               return -ENOMEM;
+       sd = &dec->sd;
+@@ -201,7 +201,6 @@ static int tw9906_probe(struct i2c_client *client,
+               int err = hdl->error;
+               v4l2_ctrl_handler_free(hdl);
+-              kfree(dec);
+               return err;
+       }
+@@ -210,7 +209,6 @@ static int tw9906_probe(struct i2c_client *client,
+       if (write_regs(sd, initial_registers) < 0) {
+               v4l2_err(client, "error initializing TW9906\n");
+-              kfree(dec);
+               return -EINVAL;
+       }
+@@ -223,7 +221,6 @@ static int tw9906_remove(struct i2c_client *client)
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(&to_state(sd)->hdl);
+-      kfree(to_state(sd));
+       return 0;
+ }
+diff --git a/drivers/media/i2c/uda1342.c b/drivers/media/i2c/uda1342.c
+index 3af4085..081786d 100644
+--- a/drivers/media/i2c/uda1342.c
++++ b/drivers/media/i2c/uda1342.c
+@@ -69,7 +69,7 @@ static int uda1342_probe(struct i2c_client *client,
+       dev_dbg(&client->dev, "initializing UDA1342 at address %d on %s\n",
+               client->addr, adapter->name);
+-      sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
++      sd = devm_kzalloc(&client->dev, sizeof(*sd), GFP_KERNEL);
+       if (sd == NULL)
+               return -ENOMEM;
+@@ -89,7 +89,6 @@ static int uda1342_remove(struct i2c_client *client)
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       v4l2_device_unregister_subdev(sd);
+-      kfree(sd);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/upd64031a.c b/drivers/media/i2c/upd64031a.c
+index f0a0921..4283fc5 100644
+--- a/drivers/media/i2c/upd64031a.c
++++ b/drivers/media/i2c/upd64031a.c
+@@ -230,7 +230,7 @@ static int upd64031a_probe(struct i2c_client *client,
+       v4l_info(client, "chip found @ 0x%x (%s)\n",
+                       client->addr << 1, client->adapter->name);
+-      state = kzalloc(sizeof(struct upd64031a_state), GFP_KERNEL);
++      state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
+       if (state == NULL)
+               return -ENOMEM;
+       sd = &state->sd;
+@@ -249,7 +249,6 @@ static int upd64031a_remove(struct i2c_client *client)
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       v4l2_device_unregister_subdev(sd);
+-      kfree(to_state(sd));
+       return 0;
+ }
+diff --git a/drivers/media/i2c/upd64083.c b/drivers/media/i2c/upd64083.c
+index 343e021..b2ac56c 100644
+--- a/drivers/media/i2c/upd64083.c
++++ b/drivers/media/i2c/upd64083.c
+@@ -202,7 +202,7 @@ static int upd64083_probe(struct i2c_client *client,
+       v4l_info(client, "chip found @ 0x%x (%s)\n",
+                       client->addr << 1, client->adapter->name);
+-      state = kzalloc(sizeof(struct upd64083_state), GFP_KERNEL);
++      state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
+       if (state == NULL)
+               return -ENOMEM;
+       sd = &state->sd;
+@@ -221,7 +221,6 @@ static int upd64083_remove(struct i2c_client *client)
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       v4l2_device_unregister_subdev(sd);
+-      kfree(to_state(sd));
+       return 0;
+ }
+diff --git a/drivers/media/i2c/vp27smpx.c b/drivers/media/i2c/vp27smpx.c
+index e71f139..208a095 100644
+--- a/drivers/media/i2c/vp27smpx.c
++++ b/drivers/media/i2c/vp27smpx.c
+@@ -169,7 +169,7 @@ static int vp27smpx_probe(struct i2c_client *client,
+       v4l_info(client, "chip found @ 0x%x (%s)\n",
+                       client->addr << 1, client->adapter->name);
+-      state = kzalloc(sizeof(struct vp27smpx_state), GFP_KERNEL);
++      state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
+       if (state == NULL)
+               return -ENOMEM;
+       sd = &state->sd;
+@@ -186,7 +186,6 @@ static int vp27smpx_remove(struct i2c_client *client)
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       v4l2_device_unregister_subdev(sd);
+-      kfree(to_state(sd));
+       return 0;
+ }
+diff --git a/drivers/media/i2c/vpx3220.c b/drivers/media/i2c/vpx3220.c
+index 2f67b4c..f02e74b 100644
+--- a/drivers/media/i2c/vpx3220.c
++++ b/drivers/media/i2c/vpx3220.c
+@@ -499,7 +499,7 @@ static int vpx3220_probe(struct i2c_client *client,
+               I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
+               return -ENODEV;
+-      decoder = kzalloc(sizeof(struct vpx3220), GFP_KERNEL);
++      decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
+       if (decoder == NULL)
+               return -ENOMEM;
+       sd = &decoder->sd;
+@@ -521,7 +521,6 @@ static int vpx3220_probe(struct i2c_client *client,
+               int err = decoder->hdl.error;
+               v4l2_ctrl_handler_free(&decoder->hdl);
+-              kfree(decoder);
+               return err;
+       }
+       v4l2_ctrl_handler_setup(&decoder->hdl);
+@@ -566,7 +565,7 @@ static int vpx3220_remove(struct i2c_client *client)
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(&decoder->hdl);
+-      kfree(decoder);
++
+       return 0;
+ }
+diff --git a/drivers/media/i2c/vs6624.c b/drivers/media/i2c/vs6624.c
+index 6b8c0b7..94e2849 100644
+--- a/drivers/media/i2c/vs6624.c
++++ b/drivers/media/i2c/vs6624.c
+@@ -813,11 +813,9 @@ static int vs6624_probe(struct i2c_client *client,
+       /* wait 100ms before any further i2c writes are performed */
+       mdelay(100);
+-      sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
+-      if (sensor == NULL) {
+-              gpio_free(*ce);
++      sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL);
++      if (sensor == NULL)
+               return -ENOMEM;
+-      }
+       sd = &sensor->sd;
+       v4l2_i2c_subdev_init(sd, client, &vs6624_ops);
+@@ -865,7 +863,6 @@ static int vs6624_probe(struct i2c_client *client,
+               int err = hdl->error;
+               v4l2_ctrl_handler_free(hdl);
+-              kfree(sensor);
+               gpio_free(*ce);
+               return err;
+       }
+@@ -874,7 +871,6 @@ static int vs6624_probe(struct i2c_client *client,
+       ret = v4l2_ctrl_handler_setup(hdl);
+       if (ret) {
+               v4l2_ctrl_handler_free(hdl);
+-              kfree(sensor);
+               gpio_free(*ce);
+       }
+       return ret;
+@@ -888,7 +884,6 @@ static int vs6624_remove(struct i2c_client *client)
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(sd->ctrl_handler);
+       gpio_free(sensor->ce_pin);
+-      kfree(sensor);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/wm8739.c b/drivers/media/i2c/wm8739.c
+index 3bb99e9..ac3faa7 100644
+--- a/drivers/media/i2c/wm8739.c
++++ b/drivers/media/i2c/wm8739.c
+@@ -220,7 +220,7 @@ static int wm8739_probe(struct i2c_client *client,
+       v4l_info(client, "chip found @ 0x%x (%s)\n",
+                       client->addr << 1, client->adapter->name);
+-      state = kzalloc(sizeof(struct wm8739_state), GFP_KERNEL);
++      state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
+       if (state == NULL)
+               return -ENOMEM;
+       sd = &state->sd;
+@@ -237,7 +237,6 @@ static int wm8739_probe(struct i2c_client *client,
+               int err = state->hdl.error;
+               v4l2_ctrl_handler_free(&state->hdl);
+-              kfree(state);
+               return err;
+       }
+       v4l2_ctrl_cluster(3, &state->volume);
+@@ -271,7 +270,6 @@ static int wm8739_remove(struct i2c_client *client)
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(&state->hdl);
+-      kfree(to_state(sd));
+       return 0;
+ }
+diff --git a/drivers/media/i2c/wm8775.c b/drivers/media/i2c/wm8775.c
+index 27c27b4..75ded82 100644
+--- a/drivers/media/i2c/wm8775.c
++++ b/drivers/media/i2c/wm8775.c
+@@ -241,7 +241,7 @@ static int wm8775_probe(struct i2c_client *client,
+       v4l_info(client, "chip found @ 0x%02x (%s)\n",
+                       client->addr << 1, client->adapter->name);
+-      state = kzalloc(sizeof(struct wm8775_state), GFP_KERNEL);
++      state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
+       if (state == NULL)
+               return -ENOMEM;
+       sd = &state->sd;
+@@ -261,7 +261,6 @@ static int wm8775_probe(struct i2c_client *client,
+       err = state->hdl.error;
+       if (err) {
+               v4l2_ctrl_handler_free(&state->hdl);
+-              kfree(state);
+               return err;
+       }
+@@ -319,7 +318,6 @@ static int wm8775_remove(struct i2c_client *client)
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(&state->hdl);
+-      kfree(state);
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0738-media-media-i2c-Convert-to-devm_gpio_request_one.patch b/patches.tizen/0738-media-media-i2c-Convert-to-devm_gpio_request_one.patch
new file mode 100644 (file)
index 0000000..fc1f7a3
--- /dev/null
@@ -0,0 +1,296 @@
+From 551a31607af4313cd282a1133b49aacae86b0b51 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Thu, 2 May 2013 08:29:43 -0300
+Subject: [PATCH 0738/1302] [media] media: i2c: Convert to
+ devm_gpio_request_one()
+
+Using the managed function the gpio_free() calls can be removed from the
+probe error path and the remove handler.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Acked-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/adv7183.c            | 24 ++++++++----------------
+ drivers/media/i2c/m5mols/m5mols_core.c |  9 +++------
+ drivers/media/i2c/noon010pc30.c        | 27 ++++++++-------------------
+ drivers/media/i2c/smiapp/smiapp-core.c | 18 +++++-------------
+ drivers/media/i2c/vs6624.c             | 10 +++-------
+ 5 files changed, 27 insertions(+), 61 deletions(-)
+
+diff --git a/drivers/media/i2c/adv7183.c b/drivers/media/i2c/adv7183.c
+index 5690417..42b2dec 100644
+--- a/drivers/media/i2c/adv7183.c
++++ b/drivers/media/i2c/adv7183.c
+@@ -580,17 +580,17 @@ static int adv7183_probe(struct i2c_client *client,
+       decoder->reset_pin = pin_array[0];
+       decoder->oe_pin = pin_array[1];
+-      if (gpio_request_one(decoder->reset_pin, GPIOF_OUT_INIT_LOW,
+-                           "ADV7183 Reset")) {
++      if (devm_gpio_request_one(&client->dev, decoder->reset_pin,
++                                GPIOF_OUT_INIT_LOW, "ADV7183 Reset")) {
+               v4l_err(client, "failed to request GPIO %d\n", decoder->reset_pin);
+               return -EBUSY;
+       }
+-      if (gpio_request_one(decoder->oe_pin, GPIOF_OUT_INIT_HIGH,
+-                           "ADV7183 Output Enable")) {
++      if (devm_gpio_request_one(&client->dev, decoder->oe_pin,
++                                GPIOF_OUT_INIT_HIGH,
++                                "ADV7183 Output Enable")) {
+               v4l_err(client, "failed to request GPIO %d\n", decoder->oe_pin);
+-              ret = -EBUSY;
+-              goto err_free_reset;
++              return -EBUSY;
+       }
+       sd = &decoder->sd;
+@@ -612,7 +612,7 @@ static int adv7183_probe(struct i2c_client *client,
+               ret = hdl->error;
+               v4l2_ctrl_handler_free(hdl);
+-              goto err_free_oe;
++              return ret;
+       }
+       /* v4l2 doesn't support an autodetect standard, pick PAL as default */
+@@ -637,26 +637,18 @@ static int adv7183_probe(struct i2c_client *client,
+       ret = v4l2_ctrl_handler_setup(hdl);
+       if (ret) {
+               v4l2_ctrl_handler_free(hdl);
+-              goto err_free_oe;
++              return ret;
+       }
+       return 0;
+-err_free_oe:
+-      gpio_free(decoder->oe_pin);
+-err_free_reset:
+-      gpio_free(decoder->reset_pin);
+-      return ret;
+ }
+ static int adv7183_remove(struct i2c_client *client)
+ {
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+-      struct adv7183 *decoder = to_adv7183(sd);
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(sd->ctrl_handler);
+-      gpio_free(decoder->oe_pin);
+-      gpio_free(decoder->reset_pin);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c
+index 4f549fa..c69e98b 100644
+--- a/drivers/media/i2c/m5mols/m5mols_core.c
++++ b/drivers/media/i2c/m5mols/m5mols_core.c
+@@ -980,7 +980,8 @@ static int m5mols_probe(struct i2c_client *client,
+       gpio_flags = pdata->reset_polarity
+                  ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+-      ret = gpio_request_one(pdata->gpio_reset, gpio_flags, "M5MOLS_NRST");
++      ret = devm_gpio_request_one(&client->dev, pdata->gpio_reset, gpio_flags,
++                                  "M5MOLS_NRST");
+       if (ret) {
+               dev_err(&client->dev, "Failed to request gpio: %d\n", ret);
+               return ret;
+@@ -989,7 +990,7 @@ static int m5mols_probe(struct i2c_client *client,
+       ret = regulator_bulk_get(&client->dev, ARRAY_SIZE(supplies), supplies);
+       if (ret) {
+               dev_err(&client->dev, "Failed to get regulators: %d\n", ret);
+-              goto out_gpio;
++              return ret;
+       }
+       sd = &info->sd;
+@@ -1034,22 +1035,18 @@ out_me:
+       media_entity_cleanup(&sd->entity);
+ out_reg:
+       regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
+-out_gpio:
+-      gpio_free(pdata->gpio_reset);
+       return ret;
+ }
+ static int m5mols_remove(struct i2c_client *client)
+ {
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+-      struct m5mols_info *info = to_m5mols(sd);
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(sd->ctrl_handler);
+       free_irq(client->irq, sd);
+       regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
+-      gpio_free(info->pdata->gpio_reset);
+       media_entity_cleanup(&sd->entity);
+       return 0;
+diff --git a/drivers/media/i2c/noon010pc30.c b/drivers/media/i2c/noon010pc30.c
+index d205522..6f81b99 100644
+--- a/drivers/media/i2c/noon010pc30.c
++++ b/drivers/media/i2c/noon010pc30.c
+@@ -746,8 +746,9 @@ static int noon010_probe(struct i2c_client *client,
+       info->curr_win          = &noon010_sizes[0];
+       if (gpio_is_valid(pdata->gpio_nreset)) {
+-              ret = gpio_request_one(pdata->gpio_nreset, GPIOF_OUT_INIT_LOW,
+-                                     "NOON010PC30 NRST");
++              ret = devm_gpio_request_one(&client->dev, pdata->gpio_nreset,
++                                          GPIOF_OUT_INIT_LOW,
++                                          "NOON010PC30 NRST");
+               if (ret) {
+                       dev_err(&client->dev, "GPIO request error: %d\n", ret);
+                       goto np_err;
+@@ -757,11 +758,12 @@ static int noon010_probe(struct i2c_client *client,
+       }
+       if (gpio_is_valid(pdata->gpio_nstby)) {
+-              ret = gpio_request_one(pdata->gpio_nstby, GPIOF_OUT_INIT_LOW,
+-                                    "NOON010PC30 NSTBY");
++              ret = devm_gpio_request_one(&client->dev, pdata->gpio_nstby,
++                                          GPIOF_OUT_INIT_LOW,
++                                          "NOON010PC30 NSTBY");
+               if (ret) {
+                       dev_err(&client->dev, "GPIO request error: %d\n", ret);
+-                      goto np_gpio_err;
++                      goto np_err;
+               }
+               info->gpio_nstby = pdata->gpio_nstby;
+               gpio_export(info->gpio_nstby, 0);
+@@ -773,7 +775,7 @@ static int noon010_probe(struct i2c_client *client,
+       ret = regulator_bulk_get(&client->dev, NOON010_NUM_SUPPLIES,
+                                info->supply);
+       if (ret)
+-              goto np_reg_err;
++              goto np_err;
+       info->pad.flags = MEDIA_PAD_FL_SOURCE;
+       sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
+@@ -787,12 +789,6 @@ static int noon010_probe(struct i2c_client *client,
+ np_me_err:
+       regulator_bulk_free(NOON010_NUM_SUPPLIES, info->supply);
+-np_reg_err:
+-      if (gpio_is_valid(info->gpio_nstby))
+-              gpio_free(info->gpio_nstby);
+-np_gpio_err:
+-      if (gpio_is_valid(info->gpio_nreset))
+-              gpio_free(info->gpio_nreset);
+ np_err:
+       v4l2_ctrl_handler_free(&info->hdl);
+       v4l2_device_unregister_subdev(sd);
+@@ -808,13 +804,6 @@ static int noon010_remove(struct i2c_client *client)
+       v4l2_ctrl_handler_free(&info->hdl);
+       regulator_bulk_free(NOON010_NUM_SUPPLIES, info->supply);
+-
+-      if (gpio_is_valid(info->gpio_nreset))
+-              gpio_free(info->gpio_nreset);
+-
+-      if (gpio_is_valid(info->gpio_nstby))
+-              gpio_free(info->gpio_nstby);
+-
+       media_entity_cleanup(&sd->entity);
+       return 0;
+diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
+index cae4f46..c385454 100644
+--- a/drivers/media/i2c/smiapp/smiapp-core.c
++++ b/drivers/media/i2c/smiapp/smiapp-core.c
+@@ -2383,8 +2383,9 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
+       }
+       if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN) {
+-              if (gpio_request_one(sensor->platform_data->xshutdown, 0,
+-                                   "SMIA++ xshutdown") != 0) {
++              if (devm_gpio_request_one(&client->dev,
++                                        sensor->platform_data->xshutdown, 0,
++                                        "SMIA++ xshutdown") != 0) {
+                       dev_err(&client->dev,
+                               "unable to acquire reset gpio %d\n",
+                               sensor->platform_data->xshutdown);
+@@ -2393,10 +2394,8 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
+       }
+       rval = smiapp_power_on(sensor);
+-      if (rval) {
+-              rval = -ENODEV;
+-              goto out_smiapp_power_on;
+-      }
++      if (rval)
++              return -ENODEV;
+       rval = smiapp_identify_module(subdev);
+       if (rval) {
+@@ -2656,11 +2655,6 @@ out_ident_release:
+ out_power_off:
+       smiapp_power_off(sensor);
+-
+-out_smiapp_power_on:
+-      if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
+-              gpio_free(sensor->platform_data->xshutdown);
+-
+       return rval;
+ }
+@@ -2858,8 +2852,6 @@ static int smiapp_remove(struct i2c_client *client)
+               v4l2_device_unregister_subdev(&sensor->ssds[i].sd);
+       }
+       smiapp_free_controls(sensor);
+-      if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
+-              gpio_free(sensor->platform_data->xshutdown);
+       return 0;
+ }
+diff --git a/drivers/media/i2c/vs6624.c b/drivers/media/i2c/vs6624.c
+index 94e2849..7b55b3d 100644
+--- a/drivers/media/i2c/vs6624.c
++++ b/drivers/media/i2c/vs6624.c
+@@ -805,7 +805,8 @@ static int vs6624_probe(struct i2c_client *client,
+       if (ce == NULL)
+               return -EINVAL;
+-      ret = gpio_request_one(*ce, GPIOF_OUT_INIT_HIGH, "VS6624 Chip Enable");
++      ret = devm_gpio_request_one(&client->dev, *ce, GPIOF_OUT_INIT_HIGH,
++                                  "VS6624 Chip Enable");
+       if (ret) {
+               v4l_err(client, "failed to request GPIO %d\n", *ce);
+               return ret;
+@@ -863,27 +864,22 @@ static int vs6624_probe(struct i2c_client *client,
+               int err = hdl->error;
+               v4l2_ctrl_handler_free(hdl);
+-              gpio_free(*ce);
+               return err;
+       }
+       /* initialize the hardware to the default control values */
+       ret = v4l2_ctrl_handler_setup(hdl);
+-      if (ret) {
++      if (ret)
+               v4l2_ctrl_handler_free(hdl);
+-              gpio_free(*ce);
+-      }
+       return ret;
+ }
+ static int vs6624_remove(struct i2c_client *client)
+ {
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+-      struct vs6624 *sensor = to_vs6624(sd);
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(sd->ctrl_handler);
+-      gpio_free(sensor->ce_pin);
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0739-media-media-i2c-Convert-to-devm_regulator_bulk_get.patch b/patches.tizen/0739-media-media-i2c-Convert-to-devm_regulator_bulk_get.patch
new file mode 100644 (file)
index 0000000..10c8f21
--- /dev/null
@@ -0,0 +1,99 @@
+From 481ee1f07825ddf51cde05eace4353426bac2305 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Thu, 2 May 2013 08:29:43 -0300
+Subject: [PATCH 0739/1302] [media] media: i2c: Convert to
+ devm_regulator_bulk_get()
+
+Using the managed function the regulator_bulk_put() calls can be removed
+from the probe error path and the remove handler.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Acked-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/m5mols/m5mols_core.c | 8 +++-----
+ drivers/media/i2c/noon010pc30.c        | 8 ++------
+ 2 files changed, 5 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c
+index c69e98b..ff15e33 100644
+--- a/drivers/media/i2c/m5mols/m5mols_core.c
++++ b/drivers/media/i2c/m5mols/m5mols_core.c
+@@ -987,7 +987,8 @@ static int m5mols_probe(struct i2c_client *client,
+               return ret;
+       }
+-      ret = regulator_bulk_get(&client->dev, ARRAY_SIZE(supplies), supplies);
++      ret = devm_regulator_bulk_get(&client->dev, ARRAY_SIZE(supplies),
++                                    supplies);
+       if (ret) {
+               dev_err(&client->dev, "Failed to get regulators: %d\n", ret);
+               return ret;
+@@ -1002,7 +1003,7 @@ static int m5mols_probe(struct i2c_client *client,
+       info->pad.flags = MEDIA_PAD_FL_SOURCE;
+       ret = media_entity_init(&sd->entity, 1, &info->pad, 0);
+       if (ret < 0)
+-              goto out_reg;
++              return ret;
+       sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
+       init_waitqueue_head(&info->irq_waitq);
+@@ -1033,8 +1034,6 @@ out_irq:
+       free_irq(client->irq, sd);
+ out_me:
+       media_entity_cleanup(&sd->entity);
+-out_reg:
+-      regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
+       return ret;
+ }
+@@ -1046,7 +1045,6 @@ static int m5mols_remove(struct i2c_client *client)
+       v4l2_ctrl_handler_free(sd->ctrl_handler);
+       free_irq(client->irq, sd);
+-      regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
+       media_entity_cleanup(&sd->entity);
+       return 0;
+diff --git a/drivers/media/i2c/noon010pc30.c b/drivers/media/i2c/noon010pc30.c
+index 6f81b99..2284b02 100644
+--- a/drivers/media/i2c/noon010pc30.c
++++ b/drivers/media/i2c/noon010pc30.c
+@@ -772,7 +772,7 @@ static int noon010_probe(struct i2c_client *client,
+       for (i = 0; i < NOON010_NUM_SUPPLIES; i++)
+               info->supply[i].supply = noon010_supply_name[i];
+-      ret = regulator_bulk_get(&client->dev, NOON010_NUM_SUPPLIES,
++      ret = devm_regulator_bulk_get(&client->dev, NOON010_NUM_SUPPLIES,
+                                info->supply);
+       if (ret)
+               goto np_err;
+@@ -781,14 +781,12 @@ static int noon010_probe(struct i2c_client *client,
+       sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
+       ret = media_entity_init(&sd->entity, 1, &info->pad, 0);
+       if (ret < 0)
+-              goto np_me_err;
++              goto np_err;
+       ret = noon010_detect(client, info);
+       if (!ret)
+               return 0;
+-np_me_err:
+-      regulator_bulk_free(NOON010_NUM_SUPPLIES, info->supply);
+ np_err:
+       v4l2_ctrl_handler_free(&info->hdl);
+       v4l2_device_unregister_subdev(sd);
+@@ -802,8 +800,6 @@ static int noon010_remove(struct i2c_client *client)
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(&info->hdl);
+-
+-      regulator_bulk_free(NOON010_NUM_SUPPLIES, info->supply);
+       media_entity_cleanup(&sd->entity);
+       return 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0740-media-m5mols-Convert-to-devm_request_irq.patch b/patches.tizen/0740-media-m5mols-Convert-to-devm_request_irq.patch
new file mode 100644 (file)
index 0000000..bdc361b
--- /dev/null
@@ -0,0 +1,67 @@
+From 27c097c100348917d71432a5e1f5132a073552b8 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Thu, 2 May 2013 08:29:43 -0300
+Subject: [PATCH 0740/1302] [media] m5mols: Convert to devm_request_irq()
+
+Using the managed function the free_irq() calls can be removed from the
+probe error path and the remove handler.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Acked-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/m5mols/m5mols_core.c | 14 +++++---------
+ 1 file changed, 5 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c
+index ff15e33..8119b30 100644
+--- a/drivers/media/i2c/m5mols/m5mols_core.c
++++ b/drivers/media/i2c/m5mols/m5mols_core.c
+@@ -1009,11 +1009,11 @@ static int m5mols_probe(struct i2c_client *client,
+       init_waitqueue_head(&info->irq_waitq);
+       mutex_init(&info->lock);
+-      ret = request_irq(client->irq, m5mols_irq_handler,
+-                        IRQF_TRIGGER_RISING, MODULE_NAME, sd);
++      ret = devm_request_irq(&client->dev, client->irq, m5mols_irq_handler,
++                             IRQF_TRIGGER_RISING, MODULE_NAME, sd);
+       if (ret) {
+               dev_err(&client->dev, "Interrupt request failed: %d\n", ret);
+-              goto out_me;
++              goto error;
+       }
+       info->res_type = M5MOLS_RESTYPE_MONITOR;
+       info->ffmt[0] = m5mols_default_ffmt[0];
+@@ -1021,7 +1021,7 @@ static int m5mols_probe(struct i2c_client *client,
+       ret = m5mols_sensor_power(info, true);
+       if (ret)
+-              goto out_irq;
++              goto error;
+       ret = m5mols_fw_start(sd);
+       if (!ret)
+@@ -1030,9 +1030,7 @@ static int m5mols_probe(struct i2c_client *client,
+       ret = m5mols_sensor_power(info, false);
+       if (!ret)
+               return 0;
+-out_irq:
+-      free_irq(client->irq, sd);
+-out_me:
++error:
+       media_entity_cleanup(&sd->entity);
+       return ret;
+ }
+@@ -1043,8 +1041,6 @@ static int m5mols_remove(struct i2c_client *client)
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(sd->ctrl_handler);
+-      free_irq(client->irq, sd);
+-
+       media_entity_cleanup(&sd->entity);
+       return 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0741-ARM-dts-exynos4210-trats-update-clocks-and-gpios-in-.patch b/patches.tizen/0741-ARM-dts-exynos4210-trats-update-clocks-and-gpios-in-.patch
new file mode 100644 (file)
index 0000000..3ae7f05
--- /dev/null
@@ -0,0 +1,35 @@
+From a42f038a8bcd28fd0ae154d8657bb892298d1bd4 Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Tue, 3 Sep 2013 09:35:30 +0200
+Subject: [PATCH 0741/1302] ARM: dts: exynos4210-trats: update clocks and gpios
+ in s5k5baf node
+
+This patch updates s5k5baf node according to changes in bindings
+of s5k5baf camera.
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index 7dc92cf..6219b31 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -206,8 +206,10 @@
+                       vdda-supply = <&cam_io_en_reg>;
+                       vddreg-supply = <&vt_core_15v_reg>;
+                       vddio-supply = <&vtcam_reg>;
+-                      gpios = <&gpl2 0 1>,
+-                              <&gpl2 1 1>;
++                      clocks = <&camera 0>;
++                      clock-names = "mclk";
++                      stbyn-gpios = <&gpl2 0 1>;
++                      rstn-gpios = <&gpl2 1 1>;
+                       clock-frequency = <24000000>;
+                       port {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0742-s5k5baf-add-camera-sensor-driver.patch b/patches.tizen/0742-s5k5baf-add-camera-sensor-driver.patch
new file mode 100644 (file)
index 0000000..133060f
--- /dev/null
@@ -0,0 +1,2267 @@
+From 779aeb35aab78b59d7328632552676ed3bcbfe9e Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Mon, 2 Sep 2013 16:42:15 +0200
+Subject: [PATCH 0742/1302] s5k5baf: add camera sensor driver
+
+Driver for Samsung S5K5BAF UXGA 1/5" 2M CMOS Image Sensor
+with embedded SoC ISP.
+The driver exposes the sensor as two V4L2 subdevices:
+- S5K5BAF-CIS - pure CMOS Image Sensor, fixed 1600x1200 format,
+  no controls.
+- S5K5BAF-ISP - Image Signal Processor, formats up to 1600x1200,
+  pre/post ISP cropping, downscaling via selection API, controls.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+---
+Hi,
+
+This is the 8th iteration of the patch.
+I have applied suggestions from Laurent, Sylwester and Mark, thanks.
+One exeception, I have left static struct v4l2_rect s5k5baf_cis_rect
+not const due to fact its address is passed to function which could
+modify its arguments, of course it never modifies s5k5baf_cis_rect.
+
+Regards
+Andrzej
+
+v8
+- improved description of data-lanes binding,
+- added algorithm caching,
+- added comments to functions,
+- video bus type checking moved to probe,
+- clk_get/put moved to probe,
+- moved streaming checking under mutex,
+- use proper functions for endian conversion,
+- cosmetic changes
+
+v7
+- changed description of 'clock-frequency' DT property
+
+v6
+- endpoint node presence is now optional,
+- added asynchronous subdev registration support and clock
+  handling,
+- use named gpios in DT bindings
+
+v5
+- removed hflip/vflip device tree properties
+
+v4
+- GPL changed to GPLv2,
+- bitfields replaced by u8,
+- cosmetic changes,
+- corrected s_stream flow,
+- gpio pins are no longer exported,
+- added I2C addresses to subdev names,
+- CIS subdev registration postponed after
+  succesfull HW initialization,
+- added enums for pads,
+- selections are initialized only during probe,
+- default resolution changed to 1600x1200,
+- state->error pattern removed from few other functions,
+- entity link creation moved to registered callback.
+
+v3:
+- narrowed state->error usage to i2c and power errors,
+- private gain controls replaced by red/blue balance user controls,
+- added checks to devicetree gpio node parsing
+
+v2:
+- lower-cased driver name,
+- removed underscore from regulator names,
+- removed platform data code,
+- v4l controls grouped in anonymous structs,
+- added s5k5baf_clear_error function,
+- private controls definitions moved to uapi header file,
+- added v4l2-controls.h reservation for private controls,
+- corrected subdev registered/unregistered code,
+- .log_status sudbev op set to v4l2 helper,
+- moved entity link creation to probe routines,
+- added cleanup on error to probe function.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/media/samsung-s5k5baf.txt  |   58 +
+ MAINTAINERS                                        |    7 +
+ drivers/media/i2c/Kconfig                          |    7 +
+ drivers/media/i2c/Makefile                         |    1 +
+ drivers/media/i2c/s5k5baf.c                        | 2052 ++++++++++++++++++++
+ 5 files changed, 2125 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/media/samsung-s5k5baf.txt
+ create mode 100644 drivers/media/i2c/s5k5baf.c
+
+diff --git a/Documentation/devicetree/bindings/media/samsung-s5k5baf.txt b/Documentation/devicetree/bindings/media/samsung-s5k5baf.txt
+new file mode 100644
+index 0000000..e60017e
+--- /dev/null
++++ b/Documentation/devicetree/bindings/media/samsung-s5k5baf.txt
+@@ -0,0 +1,58 @@
++Samsung S5K5BAF UXGA 1/5" 2M CMOS Image Sensor with embedded SoC ISP
++--------------------------------------------------------------------
++
++Required properties:
++
++- compatible    : "samsung,s5k5baf";
++- reg           : I2C slave address of the sensor;
++- vdda-supply   : analog power supply 2.8V (2.6V to 3.0V);
++- vddreg-supply         : regulator input power supply 1.8V (1.7V to 1.9V)
++                  or 2.8V (2.6V to 3.0);
++- vddio-supply          : I/O power supply 1.8V (1.65V to 1.95V)
++                  or 2.8V (2.5V to 3.1V);
++- stbyn-gpios   : GPIO connected to STBYN pin;
++- rstn-gpios    : GPIO connected to RSTN pin;
++- clocks        : the sensor's master clock specifier (from the common
++                  clock bindings);
++- clock-names   : must be "mclk";
++
++Optional properties:
++
++- clock-frequency : the frequency at which the "mclk" clock should be
++                  configured to operate, in Hz; if this property is not
++                  specified default 24 MHz value will be used.
++
++The device node should contain one 'port' child node with one child 'endpoint'
++node, according to the bindings defined in Documentation/devicetree/bindings/
++media/video-interfaces.txt. The following are properties specific to those
++nodes.
++
++endpoint node
++-------------
++
++- data-lanes : (optional) specifies MIPI CSI-2 data lanes as covered in
++  video-interfaces.txt. This sensor doesn't support data lane remapping
++  and physical lane indexes in subsequent elements of the array should
++  have consecutive values.
++
++Example:
++
++s5k5bafx@2d {
++      compatible = "samsung,s5k5baf";
++      reg = <0x2d>;
++      vdda-supply = <&cam_io_en_reg>;
++      vddreg-supply = <&vt_core_15v_reg>;
++      vddio-supply = <&vtcam_reg>;
++      stbyn-gpios = <&gpl2 0 1>;
++      rstn-gpios = <&gpl2 1 1>;
++      clock-names = "mclk";
++      clocks = <&clock_cam 0>;
++      clock-frequency = <24000000>;
++
++      port {
++              s5k5bafx_ep: endpoint {
++                      remote-endpoint = <&csis1_ep>;
++                      data-lanes = <1>;
++              };
++      };
++};
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 7684a09..cbc462b 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -6987,6 +6987,13 @@ L:      linux-media@vger.kernel.org
+ S:    Supported
+ F:    drivers/media/i2c/s5c73m3/*
++SAMSUNG S5K5BAF CAMERA DRIVER
++M:    Kyungmin Park <kyungmin.park@samsung.com>
++M:    Andrzej Hajda <a.hajda@samsung.com>
++L:    linux-media@vger.kernel.org
++S:    Supported
++F:    drivers/media/i2c/s5k5baf.c
++
+ SERIAL DRIVERS
+ M:    Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ L:    linux-serial@vger.kernel.org
+diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
+index 9625c5c..24407cc 100644
+--- a/drivers/media/i2c/Kconfig
++++ b/drivers/media/i2c/Kconfig
+@@ -561,6 +561,13 @@ config VIDEO_S5K4ECGX
+           This is a V4L2 sensor-level driver for Samsung S5K4ECGX 5M
+           camera sensor with an embedded SoC image signal processor.
++config VIDEO_S5K5BAF
++      tristate "Samsung S5K5BAF sensor support"
++      depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
++      ---help---
++        This is a V4L2 sensor-level driver for Samsung S5K5BAF 2M
++        camera sensor with an embedded SoC image signal processor.
++
+ source "drivers/media/i2c/smiapp/Kconfig"
+ config VIDEO_S5C73M3
+diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
+index 960fc1e..ef4b169 100644
+--- a/drivers/media/i2c/Makefile
++++ b/drivers/media/i2c/Makefile
+@@ -65,6 +65,7 @@ obj-$(CONFIG_VIDEO_NOON010PC30)      += noon010pc30.o
+ obj-$(CONFIG_VIDEO_S5K6AA)    += s5k6aa.o
+ obj-$(CONFIG_VIDEO_S5K6A3)    += s5k6a3.o
+ obj-$(CONFIG_VIDEO_S5K4ECGX)  += s5k4ecgx.o
++obj-$(CONFIG_VIDEO_S5K5BAF)   += s5k5baf.o
+ obj-$(CONFIG_VIDEO_S5C73M3)   += s5c73m3/
+ obj-$(CONFIG_VIDEO_ADP1653)   += adp1653.o
+ obj-$(CONFIG_VIDEO_AS3645A)   += as3645a.o
+diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
+new file mode 100644
+index 0000000..c07dfa7
+--- /dev/null
++++ b/drivers/media/i2c/s5k5baf.c
+@@ -0,0 +1,2052 @@
++/*
++ * Driver for Samsung S5K5BAF UXGA 1/5" 2M CMOS Image Sensor
++ * with embedded SoC ISP.
++ *
++ * Copyright (C) 2013, Samsung Electronics Co., Ltd.
++ * Andrzej Hajda <a.hajda@samsung.com>
++ *
++ * Based on S5K6AA driver authored by Sylwester Nawrocki
++ * Copyright (C) 2013, Samsung Electronics Co., Ltd.
++ *
++ * 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/clk.h>
++#include <linux/delay.h>
++#include <linux/gpio.h>
++#include <linux/i2c.h>
++#include <linux/media.h>
++#include <linux/module.h>
++#include <linux/of_gpio.h>
++#include <linux/regulator/consumer.h>
++#include <linux/slab.h>
++
++#include <media/media-entity.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-subdev.h>
++#include <media/v4l2-mediabus.h>
++#include <media/v4l2-of.h>
++
++static int debug;
++module_param(debug, int, 0644);
++
++#define S5K5BAF_DRIVER_NAME           "s5k5baf"
++#define S5K5BAF_DEFAULT_MCLK_FREQ     24000000U
++#define S5K5BAF_CLK_NAME              "mclk"
++
++#define S5K5BAF_CIS_WIDTH             1600
++#define S5K5BAF_CIS_HEIGHT            1200
++#define S5K5BAF_WIN_WIDTH_MIN         8
++#define S5K5BAF_WIN_HEIGHT_MIN                8
++#define S5K5BAF_GAIN_RED_DEF          127
++#define S5K5BAF_GAIN_GREEN_DEF                95
++#define S5K5BAF_GAIN_BLUE_DEF         180
++/* Default number of MIPI CSI-2 data lanes used */
++#define S5K5BAF_DEF_NUM_LANES         1
++
++#define AHB_MSB_ADDR_PTR              0xfcfc
++
++/*
++ * Register interface pages (the most significant word of the address)
++ */
++#define PAGE_IF_HW                    0xd000
++#define PAGE_IF_SW                    0x7000
++
++/*
++ * H/W register Interface (PAGE_IF_HW)
++ */
++#define REG_SW_LOAD_COMPLETE          0x0014
++#define REG_CMDWR_PAGE                        0x0028
++#define REG_CMDWR_ADDR                        0x002a
++#define REG_CMDRD_PAGE                        0x002c
++#define REG_CMDRD_ADDR                        0x002e
++#define REG_CMD_BUF                   0x0f12
++#define REG_SET_HOST_INT              0x1000
++#define REG_CLEAR_HOST_INT            0x1030
++#define REG_PATTERN_SET                       0x3100
++#define REG_PATTERN_WIDTH             0x3118
++#define REG_PATTERN_HEIGHT            0x311a
++#define REG_PATTERN_PARAM             0x311c
++
++/*
++ * S/W register interface (PAGE_IF_SW)
++ */
++
++/* Firmware revision information */
++#define REG_FW_APIVER                 0x012e
++#define  S5K5BAF_FW_APIVER            0x0001
++#define REG_FW_REVISION                       0x0130
++#define REG_FW_SENSOR_ID              0x0152
++
++/* Initialization parameters */
++/* Master clock frequency in KHz */
++#define REG_I_INCLK_FREQ_L            0x01b8
++#define REG_I_INCLK_FREQ_H            0x01ba
++#define  MIN_MCLK_FREQ_KHZ            6000U
++#define  MAX_MCLK_FREQ_KHZ            48000U
++#define REG_I_USE_NPVI_CLOCKS         0x01c6
++#define  NPVI_CLOCKS                  1
++#define REG_I_USE_NMIPI_CLOCKS                0x01c8
++#define  NMIPI_CLOCKS                 1
++#define REG_I_BLOCK_INTERNAL_PLL_CALC 0x01ca
++
++/* Clock configurations, n = 0..2. REG_I_* frequency unit is 4 kHz. */
++#define REG_I_OPCLK_4KHZ(n)           ((n) * 6 + 0x01cc)
++#define REG_I_MIN_OUTRATE_4KHZ(n)     ((n) * 6 + 0x01ce)
++#define REG_I_MAX_OUTRATE_4KHZ(n)     ((n) * 6 + 0x01d0)
++#define  SCLK_PVI_FREQ                        24000
++#define  SCLK_MIPI_FREQ                       48000
++#define  PCLK_MIN_FREQ                        6000
++#define  PCLK_MAX_FREQ                        48000
++#define REG_I_USE_REGS_API            0x01de
++#define REG_I_INIT_PARAMS_UPDATED     0x01e0
++#define REG_I_ERROR_INFO              0x01e2
++
++/* General purpose parameters */
++#define REG_USER_BRIGHTNESS           0x01e4
++#define REG_USER_CONTRAST             0x01e6
++#define REG_USER_SATURATION           0x01e8
++#define REG_USER_SHARPBLUR            0x01ea
++
++#define REG_G_SPEC_EFFECTS            0x01ee
++#define REG_G_ENABLE_PREV             0x01f0
++#define REG_G_ENABLE_PREV_CHG         0x01f2
++#define REG_G_NEW_CFG_SYNC            0x01f8
++#define REG_G_PREVREQ_IN_WIDTH                0x01fa
++#define REG_G_PREVREQ_IN_HEIGHT               0x01fc
++#define REG_G_PREVREQ_IN_XOFFS                0x01fe
++#define REG_G_PREVREQ_IN_YOFFS                0x0200
++#define REG_G_PREVZOOM_IN_WIDTH               0x020a
++#define REG_G_PREVZOOM_IN_HEIGHT      0x020c
++#define REG_G_PREVZOOM_IN_XOFFS               0x020e
++#define REG_G_PREVZOOM_IN_YOFFS               0x0210
++#define REG_G_INPUTS_CHANGE_REQ               0x021a
++#define REG_G_ACTIVE_PREV_CFG         0x021c
++#define REG_G_PREV_CFG_CHG            0x021e
++#define REG_G_PREV_OPEN_AFTER_CH      0x0220
++#define REG_G_PREV_CFG_ERROR          0x0222
++#define  CFG_ERROR_RANGE              0x0b
++#define REG_G_PREV_CFG_BYPASS_CHANGED 0x022a
++#define REG_G_ACTUAL_P_FR_TIME                0x023a
++#define REG_G_ACTUAL_P_OUT_RATE               0x023c
++#define REG_G_ACTUAL_C_FR_TIME                0x023e
++#define REG_G_ACTUAL_C_OUT_RATE               0x0240
++
++/* Preview control section. n = 0...4. */
++#define PREG(n, x)                    ((n) * 0x26 + x)
++#define REG_P_OUT_WIDTH(n)            PREG(n, 0x0242)
++#define REG_P_OUT_HEIGHT(n)           PREG(n, 0x0244)
++#define REG_P_FMT(n)                  PREG(n, 0x0246)
++#define REG_P_MAX_OUT_RATE(n)         PREG(n, 0x0248)
++#define REG_P_MIN_OUT_RATE(n)         PREG(n, 0x024a)
++#define REG_P_PVI_MASK(n)             PREG(n, 0x024c)
++#define  PVI_MASK_MIPI                        0x52
++#define REG_P_CLK_INDEX(n)            PREG(n, 0x024e)
++#define  CLK_PVI_INDEX                        0
++#define  CLK_MIPI_INDEX                       NPVI_CLOCKS
++#define REG_P_FR_RATE_TYPE(n)         PREG(n, 0x0250)
++#define  FR_RATE_DYNAMIC              0
++#define  FR_RATE_FIXED                        1
++#define  FR_RATE_FIXED_ACCURATE               2
++#define REG_P_FR_RATE_Q_TYPE(n)               PREG(n, 0x0252)
++#define  FR_RATE_Q_DYNAMIC            0
++#define  FR_RATE_Q_BEST_FRRATE                1 /* Binning enabled */
++#define  FR_RATE_Q_BEST_QUALITY               2 /* Binning disabled */
++/* Frame period in 0.1 ms units */
++#define REG_P_MAX_FR_TIME(n)          PREG(n, 0x0254)
++#define REG_P_MIN_FR_TIME(n)          PREG(n, 0x0256)
++#define  S5K5BAF_MIN_FR_TIME          333  /* x100 us */
++#define  S5K5BAF_MAX_FR_TIME          6500 /* x100 us */
++/* The below 5 registers are for "device correction" values */
++#define REG_P_SATURATION(n)           PREG(n, 0x0258)
++#define REG_P_SHARP_BLUR(n)           PREG(n, 0x025a)
++#define REG_P_GLAMOUR(n)              PREG(n, 0x025c)
++#define REG_P_COLORTEMP(n)            PREG(n, 0x025e)
++#define REG_P_GAMMA_INDEX(n)          PREG(n, 0x0260)
++#define REG_P_PREV_MIRROR(n)          PREG(n, 0x0262)
++#define REG_P_CAP_MIRROR(n)           PREG(n, 0x0264)
++#define REG_P_CAP_ROTATION(n)         PREG(n, 0x0266)
++
++/* Extended image property controls */
++/* Exposure time in 10 us units */
++#define REG_SF_USR_EXPOSURE_L         0x03bc
++#define REG_SF_USR_EXPOSURE_H         0x03be
++#define REG_SF_USR_EXPOSURE_CHG               0x03c0
++#define REG_SF_USR_TOT_GAIN           0x03c2
++#define REG_SF_USR_TOT_GAIN_CHG               0x03c4
++#define REG_SF_RGAIN                  0x03c6
++#define REG_SF_RGAIN_CHG              0x03c8
++#define REG_SF_GGAIN                  0x03ca
++#define REG_SF_GGAIN_CHG              0x03cc
++#define REG_SF_BGAIN                  0x03ce
++#define REG_SF_BGAIN_CHG              0x03d0
++#define REG_SF_WBGAIN_CHG             0x03d2
++#define REG_SF_FLICKER_QUANT          0x03d4
++#define REG_SF_FLICKER_QUANT_CHG      0x03d6
++
++/* Output interface (parallel/MIPI) setup */
++#define REG_OIF_EN_MIPI_LANES         0x03f2
++#define REG_OIF_EN_PACKETS            0x03f4
++#define  EN_PACKETS_CSI2              0xc3
++#define REG_OIF_CFG_CHG                       0x03f6
++
++/* Auto-algorithms enable mask */
++#define REG_DBG_AUTOALG_EN            0x03f8
++#define  AALG_ALL_EN                  BIT(0)
++#define  AALG_AE_EN                   BIT(1)
++#define  AALG_DIVLEI_EN                       BIT(2)
++#define  AALG_WB_EN                   BIT(3)
++#define  AALG_USE_WB_FOR_ISP          BIT(4)
++#define  AALG_FLICKER_EN              BIT(5)
++#define  AALG_FIT_EN                  BIT(6)
++#define  AALG_WRHW_EN                 BIT(7)
++
++/* Pointers to color correction matrices */
++#define REG_PTR_CCM_HORIZON           0x06d0
++#define REG_PTR_CCM_INCANDESCENT      0x06d4
++#define REG_PTR_CCM_WARM_WHITE                0x06d8
++#define REG_PTR_CCM_COOL_WHITE                0x06dc
++#define REG_PTR_CCM_DL50              0x06e0
++#define REG_PTR_CCM_DL65              0x06e4
++#define REG_PTR_CCM_OUTDOOR           0x06ec
++
++#define REG_ARR_CCM(n)                        (0x2800 + 36 * (n))
++
++static const char * const s5k5baf_supply_names[] = {
++      "vdda",         /* Analog power supply 2.8V (2.6V to 3.0V) */
++      "vddreg",       /* Regulator input power supply 1.8V (1.7V to 1.9V)
++                         or 2.8V (2.6V to 3.0) */
++      "vddio",        /* I/O power supply 1.8V (1.65V to 1.95V)
++                         or 2.8V (2.5V to 3.1V) */
++};
++#define S5K5BAF_NUM_SUPPLIES ARRAY_SIZE(s5k5baf_supply_names)
++
++struct s5k5baf_gpio {
++      int gpio;
++      int level;
++};
++
++enum s5k5baf_gpio_id {
++      STBY,
++      RST,
++      GPIO_NUM,
++};
++
++#define PAD_CIS 0
++#define PAD_OUT 1
++#define CIS_PAD_NUM 1
++#define ISP_PAD_NUM 2
++
++struct s5k5baf_pixfmt {
++      enum v4l2_mbus_pixelcode code;
++      u32 colorspace;
++      /* REG_P_FMT(x) register value */
++      u16 reg_p_fmt;
++};
++
++struct s5k5baf_ctrls {
++      struct v4l2_ctrl_handler handler;
++      struct { /* Auto / manual white balance cluster */
++              struct v4l2_ctrl *awb;
++              struct v4l2_ctrl *gain_red;
++              struct v4l2_ctrl *gain_blue;
++      };
++      struct { /* Mirror cluster */
++              struct v4l2_ctrl *hflip;
++              struct v4l2_ctrl *vflip;
++      };
++      struct { /* Auto exposure / manual exposure and gain cluster */
++              struct v4l2_ctrl *auto_exp;
++              struct v4l2_ctrl *exposure;
++              struct v4l2_ctrl *gain;
++      };
++};
++
++struct s5k5baf {
++      struct s5k5baf_gpio gpios[GPIO_NUM];
++      enum v4l2_mbus_type bus_type;
++      u8 nlanes;
++      struct regulator_bulk_data supplies[S5K5BAF_NUM_SUPPLIES];
++
++      struct clk *clock;
++      u32 mclk_frequency;
++
++      struct v4l2_subdev cis_sd;
++      struct media_pad cis_pad;
++
++      struct v4l2_subdev sd;
++      struct media_pad pads[ISP_PAD_NUM];
++
++      /* protects the struct members below */
++      struct mutex lock;
++
++      int error;
++
++      struct v4l2_rect crop_sink;
++      struct v4l2_rect compose;
++      struct v4l2_rect crop_source;
++      /* index to s5k5baf_formats array */
++      int pixfmt;
++      /* actual frame interval in 100us */
++      u16 fiv;
++      /* requested frame interval in 100us */
++      u16 req_fiv;
++      /* cache for REG_DBG_AUTOALG_EN register */
++      u16 auto_alg;
++
++      struct s5k5baf_ctrls ctrls;
++
++      unsigned int streaming:1;
++      unsigned int apply_cfg:1;
++      unsigned int apply_crop:1;
++      unsigned int valid_auto_alg:1;
++      unsigned int power;
++};
++
++static const struct s5k5baf_pixfmt s5k5baf_formats[] = {
++      { V4L2_MBUS_FMT_VYUY8_2X8,      V4L2_COLORSPACE_JPEG,   5 },
++      /* range 16-240 */
++      { V4L2_MBUS_FMT_VYUY8_2X8,      V4L2_COLORSPACE_REC709, 6 },
++      { V4L2_MBUS_FMT_RGB565_2X8_BE,  V4L2_COLORSPACE_JPEG,   0 },
++};
++
++static struct v4l2_rect s5k5baf_cis_rect = {
++      0, 0, S5K5BAF_CIS_WIDTH, S5K5BAF_CIS_HEIGHT
++};
++
++static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
++{
++      return &container_of(ctrl->handler, struct s5k5baf, ctrls.handler)->sd;
++}
++
++static inline bool s5k5baf_is_cis_subdev(struct v4l2_subdev *sd)
++{
++      return sd->entity.type == MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
++}
++
++static inline struct s5k5baf *to_s5k5baf(struct v4l2_subdev *sd)
++{
++      if (s5k5baf_is_cis_subdev(sd))
++              return container_of(sd, struct s5k5baf, cis_sd);
++      else
++              return container_of(sd, struct s5k5baf, sd);
++}
++
++static u16 s5k5baf_i2c_read(struct s5k5baf *state, u16 addr)
++{
++      struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
++      __be16 w, r;
++      struct i2c_msg msg[] = {
++              { .addr = c->addr, .flags = 0,
++                .len = 2, .buf = (u8 *)&w },
++              { .addr = c->addr, .flags = I2C_M_RD,
++                .len = 2, .buf = (u8 *)&r },
++      };
++      int ret;
++
++      if (state->error)
++              return 0;
++
++      w = cpu_to_be16(addr);
++      ret = i2c_transfer(c->adapter, msg, 2);
++      r = be16_to_cpu(r);
++
++      v4l2_dbg(3, debug, c, "i2c_read: 0x%04x : 0x%04x\n", addr, r);
++
++      if (ret != 2) {
++              v4l2_err(c, "i2c_read: error during transfer (%d)\n", ret);
++              state->error = ret;
++      }
++      return r;
++}
++
++static void s5k5baf_i2c_write(struct s5k5baf *state, u16 addr, u16 val)
++{
++      u8 buf[4] = { addr >> 8, addr & 0xFF, val >> 8, val & 0xFF };
++      struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
++      int ret;
++
++      if (state->error)
++              return;
++
++      ret = i2c_master_send(c, buf, 4);
++      v4l2_dbg(3, debug, c, "i2c_write: 0x%04x : 0x%04x\n", addr, val);
++
++      if (ret != 4) {
++              v4l2_err(c, "i2c_write: error during transfer (%d)\n", ret);
++              state->error = ret;
++      }
++}
++
++static u16 s5k5baf_read(struct s5k5baf *state, u16 addr)
++{
++      s5k5baf_i2c_write(state, REG_CMDRD_ADDR, addr);
++      return s5k5baf_i2c_read(state, REG_CMD_BUF);
++}
++
++static void s5k5baf_write(struct s5k5baf *state, u16 addr, u16 val)
++{
++      s5k5baf_i2c_write(state, REG_CMDWR_ADDR, addr);
++      s5k5baf_i2c_write(state, REG_CMD_BUF, val);
++}
++
++static void s5k5baf_write_arr_seq(struct s5k5baf *state, u16 addr,
++                                u16 count, const u16 *seq)
++{
++      struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
++      __be16 buf[count + 1];
++      int ret, n;
++
++      s5k5baf_i2c_write(state, REG_CMDWR_ADDR, addr);
++      if (state->error)
++              return;
++
++      buf[0] = __constant_cpu_to_be16(REG_CMD_BUF);
++      for (n = 1; n <= count; ++n)
++              buf[n] = cpu_to_be16(*seq++);
++
++      n *= 2;
++      ret = i2c_master_send(c, (char *)buf, n);
++      v4l2_dbg(3, debug, c, "i2c_write_seq(count=%d): %*ph\n", count,
++               min(2 * count, 64), seq - count);
++
++      if (ret != n) {
++              v4l2_err(c, "i2c_write_seq: error during transfer (%d)\n", ret);
++              state->error = ret;
++      }
++}
++
++#define s5k5baf_write_seq(state, addr, seq...) \
++      s5k5baf_write_arr_seq(state, addr, sizeof((char[]){ seq }), \
++                            (const u16 []){ seq });
++
++/* add items count at the beginning of the list */
++#define NSEQ(seq...) sizeof((char[]){ seq }), seq
++
++/*
++ * s5k5baf_write_nseq() - Writes sequences of values to sensor memory via i2c
++ * @nseq: sequence of u16 words in format:
++ *    (N, address, value[1]...value[N-1])*,0
++ * Ex.:
++ *    u16 seq[] = { NSEQ(0x4000, 1, 1), NSEQ(0x4010, 640, 480), 0 };
++ *    ret = s5k5baf_write_nseq(c, seq);
++ */
++static void s5k5baf_write_nseq(struct s5k5baf *state, const u16 *nseq)
++{
++      int count;
++
++      while ((count = *nseq++)) {
++              u16 addr = *nseq++;
++              --count;
++
++              s5k5baf_write_arr_seq(state, addr, count, nseq);
++              nseq += count;
++      }
++}
++
++static void s5k5baf_synchronize(struct s5k5baf *state, int timeout, u16 addr)
++{
++      unsigned long end = jiffies + msecs_to_jiffies(timeout);
++      u16 reg;
++
++      s5k5baf_write(state, addr, 1);
++      do {
++              reg = s5k5baf_read(state, addr);
++              if (state->error || !reg)
++                      return;
++              usleep_range(5000, 10000);
++      } while (time_is_after_jiffies(end));
++
++      v4l2_err(&state->sd, "timeout on register synchronize (%#x)\n", addr);
++      state->error = -ETIMEDOUT;
++}
++
++static void s5k5baf_hw_patch(struct s5k5baf *state)
++{
++      static const u16 nseq_patch[] = {
++              NSEQ(0x1668,
++              0xb5fe, 0x0007, 0x683c, 0x687e, 0x1da5, 0x88a0, 0x2800, 0xd00b,
++              0x88a8, 0x2800, 0xd008, 0x8820, 0x8829, 0x4288, 0xd301, 0x1a40,
++              0xe000, 0x1a08, 0x9001, 0xe001, 0x2019, 0x9001, 0x4916, 0x466b,
++              0x8a48, 0x8118, 0x8a88, 0x8158, 0x4814, 0x8940, 0x0040, 0x2103,
++              0xf000, 0xf826, 0x88a1, 0x4288, 0xd908, 0x8828, 0x8030, 0x8868,
++              0x8070, 0x88a8, 0x6038, 0xbcfe, 0xbc08, 0x4718, 0x88a9, 0x4288,
++              0xd906, 0x8820, 0x8030, 0x8860, 0x8070, 0x88a0, 0x6038, 0xe7f2,
++              0x9801, 0xa902, 0xf000, 0xf812, 0x0033, 0x0029, 0x9a02, 0x0020,
++              0xf000, 0xf814, 0x6038, 0xe7e6, 0x1a28, 0x7000, 0x0d64, 0x7000,
++              0x4778, 0x46c0, 0xf004, 0xe51f, 0xa464, 0x0000, 0x4778, 0x46c0,
++              0xc000, 0xe59f, 0xff1c, 0xe12f, 0x6009, 0x0000, 0x4778, 0x46c0,
++              0xc000, 0xe59f, 0xff1c, 0xe12f, 0x622f, 0x0000),
++              NSEQ(0x2080,
++              0xb510, 0xf000, 0xf8f4, 0xbc10, 0xbc08, 0x4718, 0xb5f0, 0xb08b,
++              0x0006, 0x2000, 0x9004, 0x6835, 0x6874, 0x68b0, 0x900a, 0x68f0,
++              0x9009, 0x4f7d, 0x8979, 0x084a, 0x88a8, 0x88a3, 0x4298, 0xd300,
++              0x0018, 0xf000, 0xf907, 0x9007, 0x0021, 0x0028, 0xaa04, 0xf000,
++              0xf909, 0x9006, 0x88a8, 0x2800, 0xd102, 0x27ff, 0x1c7f, 0xe047,
++              0x88a0, 0x2800, 0xd101, 0x2700, 0xe042, 0x8820, 0x466b, 0x8198,
++              0x8860, 0x81d8, 0x8828, 0x8118, 0x8868, 0x8158, 0xa802, 0xc803,
++              0xf000, 0xf8f8, 0x9008, 0x8aba, 0x9808, 0x466b, 0x4342, 0x9202,
++              0x8820, 0x8198, 0x8860, 0x81d8, 0x980a, 0x9903, 0xf000, 0xf8ea,
++              0x9a02, 0x17d1, 0x0e09, 0x1889, 0x1209, 0x4288, 0xdd1f, 0x8820,
++              0x466b, 0x8198, 0x8860, 0x81d8, 0x980a, 0x9903, 0xf000, 0xf8da,
++              0x9001, 0x8828, 0x466b, 0x8118, 0x8868, 0x8158, 0x980a, 0x9902,
++              0xf000, 0xf8d0, 0x8ab9, 0x9a08, 0x4351, 0x17ca, 0x0e12, 0x1851,
++              0x120a, 0x9901, 0xf000, 0xf8b6, 0x0407, 0x0c3f, 0xe000, 0x2700,
++              0x8820, 0x466b, 0xaa05, 0x8198, 0x8860, 0x81d8, 0x8828, 0x8118,
++              0x8868, 0x8158, 0xa802, 0xc803, 0x003b, 0xf000, 0xf8bb, 0x88a1,
++              0x88a8, 0x003a, 0xf000, 0xf8be, 0x0004, 0xa804, 0xc803, 0x9a09,
++              0x9b07, 0xf000, 0xf8af, 0xa806, 0xc805, 0x0021, 0xf000, 0xf8b2,
++              0x6030, 0xb00b, 0xbcf0, 0xbc08, 0x4718, 0xb5f1, 0x9900, 0x680c,
++              0x493a, 0x694b, 0x698a, 0x4694, 0x69cd, 0x6a0e, 0x4f38, 0x42bc,
++              0xd800, 0x0027, 0x4937, 0x6b89, 0x0409, 0x0c09, 0x4a35, 0x1e92,
++              0x6bd2, 0x0412, 0x0c12, 0x429f, 0xd801, 0x0020, 0xe031, 0x001f,
++              0x434f, 0x0a3f, 0x42a7, 0xd301, 0x0018, 0xe02a, 0x002b, 0x434b,
++              0x0a1b, 0x42a3, 0xd303, 0x0220, 0xf000, 0xf88c, 0xe021, 0x0029,
++              0x4351, 0x0a09, 0x42a1, 0xd301, 0x0028, 0xe01a, 0x0031, 0x4351,
++              0x0a09, 0x42a1, 0xd304, 0x0220, 0x0011, 0xf000, 0xf87b, 0xe010,
++              0x491e, 0x8c89, 0x000a, 0x4372, 0x0a12, 0x42a2, 0xd301, 0x0030,
++              0xe007, 0x4662, 0x434a, 0x0a12, 0x42a2, 0xd302, 0x0220, 0xf000,
++              0xf869, 0x4b16, 0x4d18, 0x8d99, 0x1fca, 0x3af9, 0xd00a, 0x2001,
++              0x0240, 0x8468, 0x0220, 0xf000, 0xf85d, 0x9900, 0x6008, 0xbcf8,
++              0xbc08, 0x4718, 0x8d19, 0x8469, 0x9900, 0x6008, 0xe7f7, 0xb570,
++              0x2200, 0x490e, 0x480e, 0x2401, 0xf000, 0xf852, 0x0022, 0x490d,
++              0x480d, 0x2502, 0xf000, 0xf84c, 0x490c, 0x480d, 0x002a, 0xf000,
++              0xf847, 0xbc70, 0xbc08, 0x4718, 0x0d64, 0x7000, 0x0470, 0x7000,
++              0xa120, 0x0007, 0x0402, 0x7000, 0x14a0, 0x7000, 0x208d, 0x7000,
++              0x622f, 0x0000, 0x1669, 0x7000, 0x6445, 0x0000, 0x21ab, 0x7000,
++              0x2aa9, 0x0000, 0x4778, 0x46c0, 0xc000, 0xe59f, 0xff1c, 0xe12f,
++              0x5f49, 0x0000, 0x4778, 0x46c0, 0xc000, 0xe59f, 0xff1c, 0xe12f,
++              0x5fc7, 0x0000, 0x4778, 0x46c0, 0xc000, 0xe59f, 0xff1c, 0xe12f,
++              0x5457, 0x0000, 0x4778, 0x46c0, 0xc000, 0xe59f, 0xff1c, 0xe12f,
++              0x5fa3, 0x0000, 0x4778, 0x46c0, 0xc000, 0xe59f, 0xff1c, 0xe12f,
++              0x51f9, 0x0000, 0x4778, 0x46c0, 0xf004, 0xe51f, 0xa464, 0x0000,
++              0x4778, 0x46c0, 0xc000, 0xe59f, 0xff1c, 0xe12f, 0xa007, 0x0000,
++              0x6546, 0x2062, 0x3120, 0x3220, 0x3130, 0x0030, 0xe010, 0x0208,
++              0x0058, 0x0000),
++              0
++      };
++
++      s5k5baf_write_nseq(state, nseq_patch);
++}
++
++static void s5k5baf_hw_set_clocks(struct s5k5baf *state)
++{
++      unsigned long mclk = state->mclk_frequency / 1000;
++      u16 status;
++      static const u16 nseq_clk_cfg[] = {
++              NSEQ(REG_I_USE_NPVI_CLOCKS,
++                NPVI_CLOCKS, NMIPI_CLOCKS, 0,
++                SCLK_PVI_FREQ / 4, PCLK_MIN_FREQ / 4, PCLK_MAX_FREQ / 4,
++                SCLK_MIPI_FREQ / 4, PCLK_MIN_FREQ / 4, PCLK_MAX_FREQ / 4),
++              NSEQ(REG_I_USE_REGS_API, 1),
++              0
++      };
++
++      s5k5baf_write_seq(state, REG_I_INCLK_FREQ_L, mclk & 0xffff, mclk >> 16);
++      s5k5baf_write_nseq(state, nseq_clk_cfg);
++
++      s5k5baf_synchronize(state, 250, REG_I_INIT_PARAMS_UPDATED);
++      status = s5k5baf_read(state, REG_I_ERROR_INFO);
++      if (!state->error && status) {
++              v4l2_err(&state->sd, "error configuring PLL (%d)\n", status);
++              state->error = -EINVAL;
++      }
++}
++
++/* set custom color correction matrices for various illuminations */
++static void s5k5baf_hw_set_ccm(struct s5k5baf *state)
++{
++      static const u16 nseq_cfg[] = {
++              NSEQ(REG_PTR_CCM_HORIZON,
++              REG_ARR_CCM(0), PAGE_IF_SW,
++              REG_ARR_CCM(1), PAGE_IF_SW,
++              REG_ARR_CCM(2), PAGE_IF_SW,
++              REG_ARR_CCM(3), PAGE_IF_SW,
++              REG_ARR_CCM(4), PAGE_IF_SW,
++              REG_ARR_CCM(5), PAGE_IF_SW),
++              NSEQ(REG_PTR_CCM_OUTDOOR,
++              REG_ARR_CCM(6), PAGE_IF_SW),
++              NSEQ(REG_ARR_CCM(0),
++              /* horizon */
++              0x010d, 0xffa7, 0xfff5, 0x003b, 0x00ef, 0xff38,
++              0xfe42, 0x0270, 0xff71, 0xfeed, 0x0198, 0x0198,
++              0xff95, 0xffa3, 0x0260, 0x00ec, 0xff33, 0x00f4,
++              /* incandescent */
++              0x010d, 0xffa7, 0xfff5, 0x003b, 0x00ef, 0xff38,
++              0xfe42, 0x0270, 0xff71, 0xfeed, 0x0198, 0x0198,
++              0xff95, 0xffa3, 0x0260, 0x00ec, 0xff33, 0x00f4,
++              /* warm white */
++              0x01ea, 0xffb9, 0xffdb, 0x0127, 0x0109, 0xff3c,
++              0xff2b, 0x021b, 0xff48, 0xff03, 0x0207, 0x0113,
++              0xffca, 0xff93, 0x016f, 0x0164, 0xff55, 0x0163,
++              /* cool white */
++              0x01ea, 0xffb9, 0xffdb, 0x0127, 0x0109, 0xff3c,
++              0xff2b, 0x021b, 0xff48, 0xff03, 0x0207, 0x0113,
++              0xffca, 0xff93, 0x016f, 0x0164, 0xff55, 0x0163,
++              /* daylight 5000K */
++              0x0194, 0xffad, 0xfffe, 0x00c5, 0x0103, 0xff5d,
++              0xfee3, 0x01ae, 0xff27, 0xff18, 0x018f, 0x00c8,
++              0xffe8, 0xffaa, 0x01c8, 0x0132, 0xff3e, 0x0100,
++              /* daylight 6500K */
++              0x0194, 0xffad, 0xfffe, 0x00c5, 0x0103, 0xff5d,
++              0xfee3, 0x01ae, 0xff27, 0xff18, 0x018f, 0x00c8,
++              0xffe8, 0xffaa, 0x01c8, 0x0132, 0xff3e, 0x0100,
++              /* outdoor */
++              0x01cc, 0xffc3, 0x0009, 0x00a2, 0x0106, 0xff3f,
++              0xfed8, 0x01fe, 0xff08, 0xfec7, 0x00f5, 0x0119,
++              0xffdf, 0x0024, 0x01a8, 0x0170, 0xffad, 0x011b),
++              0
++      };
++      s5k5baf_write_nseq(state, nseq_cfg);
++}
++
++/* CIS sensor tuning, based on undocumented android driver code */
++static void s5k5baf_hw_set_cis(struct s5k5baf *state)
++{
++      static const u16 nseq_cfg[] = {
++              NSEQ(0xc202, 0x0700),
++              NSEQ(0xf260, 0x0001),
++              NSEQ(0xf414, 0x0030),
++              NSEQ(0xc204, 0x0100),
++              NSEQ(0xf402, 0x0092, 0x007f),
++              NSEQ(0xf700, 0x0040),
++              NSEQ(0xf708,
++              0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
++              0x0040, 0x0040, 0x0040, 0x0040, 0x0040,
++              0x0001, 0x0015, 0x0001, 0x0040),
++              NSEQ(0xf48a, 0x0048),
++              NSEQ(0xf10a, 0x008b),
++              NSEQ(0xf900, 0x0067),
++              NSEQ(0xf406, 0x0092, 0x007f, 0x0003, 0x0003, 0x0003),
++              NSEQ(0xf442, 0x0000, 0x0000),
++              NSEQ(0xf448, 0x0000),
++              NSEQ(0xf456, 0x0001, 0x0010, 0x0000),
++              NSEQ(0xf41a, 0x00ff, 0x0003, 0x0030),
++              NSEQ(0xf410, 0x0001, 0x0000),
++              NSEQ(0xf416, 0x0001),
++              NSEQ(0xf424, 0x0000),
++              NSEQ(0xf422, 0x0000),
++              NSEQ(0xf41e, 0x0000),
++              NSEQ(0xf428, 0x0000, 0x0000, 0x0000),
++              NSEQ(0xf430, 0x0000, 0x0000, 0x0008, 0x0005, 0x000f, 0x0001,
++              0x0040, 0x0040, 0x0010),
++              NSEQ(0xf4d6, 0x0090, 0x0000),
++              NSEQ(0xf47c, 0x000c, 0x0000),
++              NSEQ(0xf49a, 0x0008, 0x0000),
++              NSEQ(0xf4a2, 0x0008, 0x0000),
++              NSEQ(0xf4b2, 0x0013, 0x0000, 0x0013, 0x0000),
++              NSEQ(0xf4aa, 0x009b, 0x00fb, 0x009b, 0x00fb),
++              0
++      };
++
++      s5k5baf_i2c_write(state, REG_CMDWR_PAGE, PAGE_IF_HW);
++      s5k5baf_write_nseq(state, nseq_cfg);
++      s5k5baf_i2c_write(state, REG_CMDWR_PAGE, PAGE_IF_SW);
++}
++
++static void s5k5baf_hw_sync_cfg(struct s5k5baf *state)
++{
++      s5k5baf_write(state, REG_G_PREV_CFG_CHG, 1);
++      if (state->apply_crop) {
++              s5k5baf_write(state, REG_G_INPUTS_CHANGE_REQ, 1);
++              s5k5baf_write(state, REG_G_PREV_CFG_BYPASS_CHANGED, 1);
++      }
++      s5k5baf_synchronize(state, 500, REG_G_NEW_CFG_SYNC);
++}
++/* Set horizontal and vertical image flipping */
++static void s5k5baf_hw_set_mirror(struct s5k5baf *state)
++{
++      u16 flip = state->ctrls.vflip->val | (state->ctrls.vflip->val << 1);
++
++      s5k5baf_write(state, REG_P_PREV_MIRROR(0), flip);
++      if (state->streaming)
++              s5k5baf_hw_sync_cfg(state);
++}
++
++static void s5k5baf_hw_set_alg(struct s5k5baf *state, u16 alg, bool enable)
++{
++      u16 cur_alg, new_alg;
++
++      if (!state->valid_auto_alg)
++              cur_alg = s5k5baf_read(state, REG_DBG_AUTOALG_EN);
++      else
++              cur_alg = state->auto_alg;
++
++      new_alg = enable ? (cur_alg | alg) : (cur_alg & ~alg);
++
++      if (new_alg != cur_alg)
++              s5k5baf_write(state, REG_DBG_AUTOALG_EN, new_alg);
++
++      if (state->error)
++              return;
++
++      state->valid_auto_alg = 1;
++      state->auto_alg = new_alg;
++}
++
++/* Configure auto/manual white balance and R/G/B gains */
++static void s5k5baf_hw_set_awb(struct s5k5baf *state, int awb)
++{
++      struct s5k5baf_ctrls *ctrls = &state->ctrls;
++
++      if (!awb)
++              s5k5baf_write_seq(state, REG_SF_RGAIN,
++                                ctrls->gain_red->val, 1,
++                                S5K5BAF_GAIN_GREEN_DEF, 1,
++                                ctrls->gain_blue->val, 1,
++                                1);
++
++      s5k5baf_hw_set_alg(state, AALG_WB_EN, awb);
++}
++
++/* Program FW with exposure time, 'exposure' in us units */
++static void s5k5baf_hw_set_user_exposure(struct s5k5baf *state, int exposure)
++{
++      unsigned int time = exposure / 10;
++
++      s5k5baf_write_seq(state, REG_SF_USR_EXPOSURE_L,
++                        time & 0xffff, time >> 16, 1);
++}
++
++static void s5k5baf_hw_set_user_gain(struct s5k5baf *state, int gain)
++{
++      s5k5baf_write_seq(state, REG_SF_USR_TOT_GAIN, gain, 1);
++}
++
++/* Set auto/manual exposure and total gain */
++static void s5k5baf_hw_set_auto_exposure(struct s5k5baf *state, int value)
++{
++      if (value == V4L2_EXPOSURE_AUTO) {
++              s5k5baf_hw_set_alg(state, AALG_AE_EN | AALG_DIVLEI_EN, true);
++      } else {
++              unsigned int exp_time = state->ctrls.exposure->val;
++
++              s5k5baf_hw_set_user_exposure(state, exp_time);
++              s5k5baf_hw_set_user_gain(state, state->ctrls.gain->val);
++              s5k5baf_hw_set_alg(state, AALG_AE_EN | AALG_DIVLEI_EN, false);
++      }
++}
++
++static void s5k5baf_hw_set_anti_flicker(struct s5k5baf *state, int v)
++{
++      if (v == V4L2_CID_POWER_LINE_FREQUENCY_AUTO) {
++              s5k5baf_hw_set_alg(state, AALG_FLICKER_EN, true);
++      } else {
++              /* The V4L2_CID_LINE_FREQUENCY control values match
++               * the register values */
++              s5k5baf_write_seq(state, REG_SF_FLICKER_QUANT, v, 1);
++              s5k5baf_hw_set_alg(state, AALG_FLICKER_EN, false);
++      }
++}
++
++static void s5k5baf_hw_set_colorfx(struct s5k5baf *state, int val)
++{
++      static const u16 colorfx[] = {
++              [V4L2_COLORFX_NONE] = 0,
++              [V4L2_COLORFX_BW] = 1,
++              [V4L2_COLORFX_NEGATIVE] = 2,
++              [V4L2_COLORFX_SEPIA] = 3,
++              [V4L2_COLORFX_SKY_BLUE] = 4,
++              [V4L2_COLORFX_SKETCH] = 5,
++      };
++
++      s5k5baf_write(state, REG_G_SPEC_EFFECTS, colorfx[val]);
++}
++
++static int s5k5baf_find_pixfmt(struct v4l2_mbus_framefmt *mf)
++{
++      int i, c = -1;
++
++      for (i = 0; i < ARRAY_SIZE(s5k5baf_formats); i++) {
++              if (mf->colorspace != s5k5baf_formats[i].colorspace)
++                      continue;
++              if (mf->code == s5k5baf_formats[i].code)
++                      return i;
++              if (c < 0)
++                      c = i;
++      }
++      return (c < 0) ? 0 : c;
++}
++
++static int s5k5baf_clear_error(struct s5k5baf *state)
++{
++      int ret = state->error;
++
++      state->error = 0;
++      return ret;
++}
++
++static int s5k5baf_hw_set_video_bus(struct s5k5baf *state)
++{
++      u16 en_pkts;
++
++      if (state->bus_type == V4L2_MBUS_CSI2)
++              en_pkts = EN_PACKETS_CSI2;
++      else
++              en_pkts = 0;
++
++      s5k5baf_write_seq(state, REG_OIF_EN_MIPI_LANES,
++                        state->nlanes, en_pkts, 1);
++
++      return s5k5baf_clear_error(state);
++}
++
++static u16 s5k5baf_get_cfg_error(struct s5k5baf *state)
++{
++      u16 err = s5k5baf_read(state, REG_G_PREV_CFG_ERROR);
++      if (err)
++              s5k5baf_write(state, REG_G_PREV_CFG_ERROR, 0);
++      return err;
++}
++
++static void s5k5baf_hw_set_fiv(struct s5k5baf *state, u16 fiv)
++{
++      s5k5baf_write(state, REG_P_MAX_FR_TIME(0), fiv);
++      s5k5baf_hw_sync_cfg(state);
++}
++
++static void s5k5baf_hw_find_min_fiv(struct s5k5baf *state)
++{
++      u16 err, fiv;
++      int n;
++
++      fiv = s5k5baf_read(state,  REG_G_ACTUAL_P_FR_TIME);
++      if (state->error)
++              return;
++
++      for (n = 5; n > 0; --n) {
++              s5k5baf_hw_set_fiv(state, fiv);
++              err = s5k5baf_get_cfg_error(state);
++              if (state->error)
++                      return;
++              switch (err) {
++              case CFG_ERROR_RANGE:
++                      ++fiv;
++                      break;
++              case 0:
++                      state->fiv = fiv;
++                      v4l2_info(&state->sd,
++                                "found valid frame interval: %d00us\n", fiv);
++                      return;
++              default:
++                      v4l2_err(&state->sd,
++                               "error setting frame interval: %d\n", err);
++                      state->error = -EINVAL;
++              }
++      };
++      v4l2_err(&state->sd, "cannot find correct frame interval\n");
++      state->error = -ERANGE;
++}
++
++static void s5k5baf_hw_validate_cfg(struct s5k5baf *state)
++{
++      u16 err;
++
++      err = s5k5baf_get_cfg_error(state);
++      if (state->error)
++              return;
++
++      switch (err) {
++      case 0:
++              state->apply_cfg = 1;
++              return;
++      case CFG_ERROR_RANGE:
++              s5k5baf_hw_find_min_fiv(state);
++              if (!state->error)
++                      state->apply_cfg = 1;
++              return;
++      default:
++              v4l2_err(&state->sd,
++                       "error setting format: %d\n", err);
++              state->error = -EINVAL;
++      }
++}
++
++static void s5k5baf_rescale(struct v4l2_rect *r, const struct v4l2_rect *v,
++                          const struct v4l2_rect *n,
++                          const struct v4l2_rect *d)
++{
++      r->left = v->left * n->width / d->width;
++      r->top = v->top * n->height / d->height;
++      r->width = v->width * n->width / d->width;
++      r->height = v->height * n->height / d->height;
++}
++
++static int s5k5baf_hw_set_crop_rects(struct s5k5baf *state)
++{
++      struct v4l2_rect *p, r;
++      u16 err;
++      int ret;
++
++      p = &state->crop_sink;
++      s5k5baf_write_seq(state, REG_G_PREVREQ_IN_WIDTH, p->width, p->height,
++                        p->left, p->top);
++
++      s5k5baf_rescale(&r, &state->crop_source, &state->crop_sink,
++                      &state->compose);
++      s5k5baf_write_seq(state, REG_G_PREVZOOM_IN_WIDTH, r.width, r.height,
++                        r.left, r.top);
++
++      s5k5baf_synchronize(state, 500, REG_G_INPUTS_CHANGE_REQ);
++      s5k5baf_synchronize(state, 500, REG_G_PREV_CFG_BYPASS_CHANGED);
++      err = s5k5baf_get_cfg_error(state);
++      ret = s5k5baf_clear_error(state);
++      if (ret < 0)
++              return ret;
++
++      switch (err) {
++      case 0:
++              break;
++      case CFG_ERROR_RANGE:
++              /* retry crop with frame interval set to max */
++              s5k5baf_hw_set_fiv(state, S5K5BAF_MAX_FR_TIME);
++              err = s5k5baf_get_cfg_error(state);
++              ret = s5k5baf_clear_error(state);
++              if (ret < 0)
++                      return ret;
++              if (err) {
++                      v4l2_err(&state->sd,
++                               "crop error on max frame interval: %d\n", err);
++                      state->error = -EINVAL;
++              }
++              s5k5baf_hw_set_fiv(state, state->req_fiv);
++              s5k5baf_hw_validate_cfg(state);
++              break;
++      default:
++              v4l2_err(&state->sd, "crop error: %d\n", err);
++              return -EINVAL;
++      }
++
++      if (!state->apply_cfg)
++              return 0;
++
++      p = &state->crop_source;
++      s5k5baf_write_seq(state, REG_P_OUT_WIDTH(0), p->width, p->height);
++      s5k5baf_hw_set_fiv(state, state->req_fiv);
++      s5k5baf_hw_validate_cfg(state);
++
++      return s5k5baf_clear_error(state);
++}
++
++static void s5k5baf_hw_set_config(struct s5k5baf *state)
++{
++      u16 reg_fmt = s5k5baf_formats[state->pixfmt].reg_p_fmt;
++      struct v4l2_rect *r = &state->crop_source;
++
++      s5k5baf_write_seq(state, REG_P_OUT_WIDTH(0),
++                        r->width, r->height, reg_fmt,
++                        PCLK_MAX_FREQ >> 2, PCLK_MIN_FREQ >> 2,
++                        PVI_MASK_MIPI, CLK_MIPI_INDEX,
++                        FR_RATE_FIXED, FR_RATE_Q_DYNAMIC,
++                        state->req_fiv, S5K5BAF_MIN_FR_TIME);
++      s5k5baf_hw_sync_cfg(state);
++      s5k5baf_hw_validate_cfg(state);
++}
++
++
++static void s5k5baf_hw_set_test_pattern(struct s5k5baf *state, int id)
++{
++      s5k5baf_i2c_write(state, REG_PATTERN_WIDTH, 800);
++      s5k5baf_i2c_write(state, REG_PATTERN_HEIGHT, 511);
++      s5k5baf_i2c_write(state, REG_PATTERN_PARAM, 0);
++      s5k5baf_i2c_write(state, REG_PATTERN_SET, id);
++}
++
++static void s5k5baf_gpio_assert(struct s5k5baf *state, int id)
++{
++      struct s5k5baf_gpio *gpio = &state->gpios[id];
++
++      gpio_set_value(gpio->gpio, gpio->level);
++}
++
++static void s5k5baf_gpio_deassert(struct s5k5baf *state, int id)
++{
++      struct s5k5baf_gpio *gpio = &state->gpios[id];
++
++      gpio_set_value(gpio->gpio, !gpio->level);
++}
++
++static int s5k5baf_power_on(struct s5k5baf *state)
++{
++      int ret;
++
++      ret = regulator_bulk_enable(S5K5BAF_NUM_SUPPLIES, state->supplies);
++      if (ret < 0)
++              goto err;
++
++      ret = clk_set_rate(state->clock, state->mclk_frequency);
++      if (ret < 0)
++              goto err_reg_dis;
++
++      ret = clk_prepare_enable(state->clock);
++      if (ret < 0)
++              goto err_reg_dis;
++
++      v4l2_dbg(1, debug, &state->sd, "clock frequency: %ld\n",
++               clk_get_rate(state->clock));
++
++      s5k5baf_gpio_deassert(state, STBY);
++      usleep_range(50, 100);
++      s5k5baf_gpio_deassert(state, RST);
++      return 0;
++
++err_reg_dis:
++      regulator_bulk_disable(S5K5BAF_NUM_SUPPLIES, state->supplies);
++err:
++      v4l2_err(&state->sd, "%s() failed (%d)\n", __func__, ret);
++      return ret;
++}
++
++static int s5k5baf_power_off(struct s5k5baf *state)
++{
++      int ret;
++
++      state->streaming = 0;
++      state->apply_cfg = 0;
++      state->apply_crop = 0;
++
++      s5k5baf_gpio_assert(state, RST);
++      s5k5baf_gpio_assert(state, STBY);
++
++      if (!IS_ERR(state->clock))
++              clk_disable_unprepare(state->clock);
++
++      ret = regulator_bulk_disable(S5K5BAF_NUM_SUPPLIES,
++                                      state->supplies);
++      if (ret < 0)
++              v4l2_err(&state->sd, "failed to disable regulators\n");
++
++      return 0;
++}
++
++static void s5k5baf_hw_init(struct s5k5baf *state)
++{
++      s5k5baf_i2c_write(state, AHB_MSB_ADDR_PTR, PAGE_IF_HW);
++      s5k5baf_i2c_write(state, REG_CLEAR_HOST_INT, 0);
++      s5k5baf_i2c_write(state, REG_SW_LOAD_COMPLETE, 1);
++      s5k5baf_i2c_write(state, REG_CMDRD_PAGE, PAGE_IF_SW);
++      s5k5baf_i2c_write(state, REG_CMDWR_PAGE, PAGE_IF_SW);
++}
++
++/*
++ * V4L2 subdev core and video operations
++ */
++
++static void s5k5baf_initialize_data(struct s5k5baf *state)
++{
++      state->pixfmt = 0;
++      state->req_fiv = 10000 / 15;
++      state->fiv = state->req_fiv;
++      state->valid_auto_alg = 0;
++}
++
++static int s5k5baf_set_power(struct v4l2_subdev *sd, int on)
++{
++      struct s5k5baf *state = to_s5k5baf(sd);
++      int ret = 0;
++
++      mutex_lock(&state->lock);
++
++      if (!on != state->power)
++              goto out;
++
++      if (on) {
++              s5k5baf_initialize_data(state);
++              ret = s5k5baf_power_on(state);
++              if (ret < 0)
++                      goto out;
++
++              s5k5baf_hw_init(state);
++              s5k5baf_hw_patch(state);
++              s5k5baf_i2c_write(state, REG_SET_HOST_INT, 1);
++              s5k5baf_hw_set_clocks(state);
++
++              ret = s5k5baf_hw_set_video_bus(state);
++              if (ret < 0)
++                      goto out;
++
++              s5k5baf_hw_set_cis(state);
++              s5k5baf_hw_set_ccm(state);
++
++              ret = s5k5baf_clear_error(state);
++              if (!ret)
++                      state->power++;
++      } else {
++              s5k5baf_power_off(state);
++              state->power--;
++      }
++
++out:
++      mutex_unlock(&state->lock);
++
++      if (!ret && on)
++              ret = v4l2_ctrl_handler_setup(&state->ctrls.handler);
++
++      return ret;
++}
++
++static void s5k5baf_hw_set_stream(struct s5k5baf *state, int enable)
++{
++      s5k5baf_write_seq(state, REG_G_ENABLE_PREV, enable, 1);
++}
++
++static int s5k5baf_s_stream(struct v4l2_subdev *sd, int on)
++{
++      struct s5k5baf *state = to_s5k5baf(sd);
++      int ret;
++
++      mutex_lock(&state->lock);
++
++      if (state->streaming == !!on) {
++              ret = 0;
++              goto out;
++      }
++
++      if (on) {
++              s5k5baf_hw_set_config(state);
++              ret = s5k5baf_hw_set_crop_rects(state);
++              if (ret < 0)
++                      goto out;
++              s5k5baf_hw_set_stream(state, 1);
++              s5k5baf_i2c_write(state, 0xb0cc, 0x000b);
++      } else {
++              s5k5baf_hw_set_stream(state, 0);
++      }
++      ret = s5k5baf_clear_error(state);
++      if (!ret)
++              state->streaming = !state->streaming;
++
++out:
++      mutex_unlock(&state->lock);
++
++      return ret;
++}
++
++static int s5k5baf_g_frame_interval(struct v4l2_subdev *sd,
++                                 struct v4l2_subdev_frame_interval *fi)
++{
++      struct s5k5baf *state = to_s5k5baf(sd);
++
++      mutex_lock(&state->lock);
++      fi->interval.numerator = state->fiv;
++      fi->interval.denominator = 10000;
++      mutex_unlock(&state->lock);
++
++      return 0;
++}
++
++static void s5k5baf_set_frame_interval(struct s5k5baf *state,
++                                     struct v4l2_subdev_frame_interval *fi)
++{
++      struct v4l2_fract *i = &fi->interval;
++
++      if (fi->interval.denominator == 0)
++              state->req_fiv = S5K5BAF_MAX_FR_TIME;
++      else
++              state->req_fiv = clamp_t(u32,
++                                       i->numerator * 10000 / i->denominator,
++                                       S5K5BAF_MIN_FR_TIME,
++                                       S5K5BAF_MAX_FR_TIME);
++
++      state->fiv = state->req_fiv;
++      if (state->apply_cfg) {
++              s5k5baf_hw_set_fiv(state, state->req_fiv);
++              s5k5baf_hw_validate_cfg(state);
++      }
++      *i = (struct v4l2_fract){ state->fiv, 10000 };
++      if (state->fiv == state->req_fiv)
++              v4l2_info(&state->sd, "frame interval changed to %d00us\n",
++                        state->fiv);
++}
++
++static int s5k5baf_s_frame_interval(struct v4l2_subdev *sd,
++                                 struct v4l2_subdev_frame_interval *fi)
++{
++      struct s5k5baf *state = to_s5k5baf(sd);
++
++      mutex_lock(&state->lock);
++      s5k5baf_set_frame_interval(state, fi);
++      mutex_unlock(&state->lock);
++      return 0;
++}
++
++/*
++ * V4L2 subdev pad level and video operations
++ */
++static int s5k5baf_enum_frame_interval(struct v4l2_subdev *sd,
++                            struct v4l2_subdev_fh *fh,
++                            struct v4l2_subdev_frame_interval_enum *fie)
++{
++      if (fie->index > S5K5BAF_MAX_FR_TIME - S5K5BAF_MIN_FR_TIME ||
++          fie->pad != PAD_CIS)
++              return -EINVAL;
++
++      v4l_bound_align_image(&fie->width, S5K5BAF_WIN_WIDTH_MIN,
++                            S5K5BAF_CIS_WIDTH, 1,
++                            &fie->height, S5K5BAF_WIN_HEIGHT_MIN,
++                            S5K5BAF_CIS_HEIGHT, 1, 0);
++
++      fie->interval.numerator = S5K5BAF_MIN_FR_TIME + fie->index;
++      fie->interval.denominator = 10000;
++
++      return 0;
++}
++
++static int s5k5baf_enum_mbus_code(struct v4l2_subdev *sd,
++                               struct v4l2_subdev_fh *fh,
++                               struct v4l2_subdev_mbus_code_enum *code)
++{
++      if (code->pad == PAD_CIS) {
++              if (code->index > 0)
++                      return -EINVAL;
++              code->code = V4L2_MBUS_FMT_FIXED;
++              return 0;
++      }
++
++      if (code->index >= ARRAY_SIZE(s5k5baf_formats))
++              return -EINVAL;
++
++      code->code = s5k5baf_formats[code->index].code;
++      return 0;
++}
++
++static int s5k5baf_enum_frame_size(struct v4l2_subdev *sd,
++                                struct v4l2_subdev_fh *fh,
++                                struct v4l2_subdev_frame_size_enum *fse)
++{
++      int i;
++
++      if (fse->index > 0)
++              return -EINVAL;
++
++      if (fse->pad == PAD_CIS) {
++              fse->code = V4L2_MBUS_FMT_FIXED;
++              fse->min_width = S5K5BAF_CIS_WIDTH;
++              fse->max_width = S5K5BAF_CIS_WIDTH;
++              fse->min_height = S5K5BAF_CIS_HEIGHT;
++              fse->max_height = S5K5BAF_CIS_HEIGHT;
++              return 0;
++      }
++
++      i = ARRAY_SIZE(s5k5baf_formats);
++      while (--i)
++              if (fse->code == s5k5baf_formats[i].code)
++                      break;
++      fse->code = s5k5baf_formats[i].code;
++      fse->min_width = S5K5BAF_WIN_WIDTH_MIN;
++      fse->max_width = S5K5BAF_CIS_WIDTH;
++      fse->max_height = S5K5BAF_WIN_HEIGHT_MIN;
++      fse->min_height = S5K5BAF_CIS_HEIGHT;
++
++      return 0;
++}
++
++static void s5k5baf_try_cis_format(struct v4l2_mbus_framefmt *mf)
++{
++      mf->width = S5K5BAF_CIS_WIDTH;
++      mf->height = S5K5BAF_CIS_HEIGHT;
++      mf->code = V4L2_MBUS_FMT_FIXED;
++      mf->colorspace = V4L2_COLORSPACE_JPEG;
++      mf->field = V4L2_FIELD_NONE;
++}
++
++static int s5k5baf_try_isp_format(struct v4l2_mbus_framefmt *mf)
++{
++      int pixfmt;
++
++      v4l_bound_align_image(&mf->width, S5K5BAF_WIN_WIDTH_MIN,
++                            S5K5BAF_CIS_WIDTH, 1,
++                            &mf->height, S5K5BAF_WIN_HEIGHT_MIN,
++                            S5K5BAF_CIS_HEIGHT, 1, 0);
++
++      pixfmt = s5k5baf_find_pixfmt(mf);
++
++      mf->colorspace = s5k5baf_formats[pixfmt].colorspace;
++      mf->code = s5k5baf_formats[pixfmt].code;
++      mf->field = V4L2_FIELD_NONE;
++
++      return pixfmt;
++}
++
++static int s5k5baf_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
++                        struct v4l2_subdev_format *fmt)
++{
++      struct s5k5baf *state = to_s5k5baf(sd);
++      const struct s5k5baf_pixfmt *pixfmt;
++      struct v4l2_mbus_framefmt *mf;
++
++      if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
++              mf = v4l2_subdev_get_try_format(fh, fmt->pad);
++              fmt->format = *mf;
++              return 0;
++      }
++
++      mf = &fmt->format;
++      if (fmt->pad == PAD_CIS) {
++              s5k5baf_try_cis_format(mf);
++              return 0;
++      }
++      mf->field = V4L2_FIELD_NONE;
++      mutex_lock(&state->lock);
++      pixfmt = &s5k5baf_formats[state->pixfmt];
++      mf->width = state->crop_source.width;
++      mf->height = state->crop_source.height;
++      mf->code = pixfmt->code;
++      mf->colorspace = pixfmt->colorspace;
++      mutex_unlock(&state->lock);
++
++      return 0;
++}
++
++static int s5k5baf_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
++                        struct v4l2_subdev_format *fmt)
++{
++      struct v4l2_mbus_framefmt *mf = &fmt->format;
++      struct s5k5baf *state = to_s5k5baf(sd);
++      const struct s5k5baf_pixfmt *pixfmt;
++      int ret = 0;
++
++      if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
++              *v4l2_subdev_get_try_format(fh, fmt->pad) = *mf;
++              return 0;
++      }
++
++      if (fmt->pad == PAD_CIS) {
++              s5k5baf_try_cis_format(mf);
++              return 0;
++      }
++
++      mutex_lock(&state->lock);
++
++      if (state->streaming) {
++              mutex_unlock(&state->lock);
++              return -EBUSY;
++      }
++
++      state->pixfmt = s5k5baf_try_isp_format(mf);
++      pixfmt = &s5k5baf_formats[state->pixfmt];
++      mf->code = pixfmt->code;
++      mf->colorspace = pixfmt->colorspace;
++      mf->width = state->crop_source.width;
++      mf->height = state->crop_source.height;
++
++      mutex_unlock(&state->lock);
++      return ret;
++}
++
++enum selection_rect { R_CIS, R_CROP_SINK, R_COMPOSE, R_CROP_SOURCE, R_INVALID };
++
++static enum selection_rect s5k5baf_get_sel_rect(u32 pad, u32 target)
++{
++      switch (target) {
++      case V4L2_SEL_TGT_CROP_BOUNDS:
++              return pad ? R_COMPOSE : R_CIS;
++      case V4L2_SEL_TGT_CROP:
++              return pad ? R_CROP_SOURCE : R_CROP_SINK;
++      case V4L2_SEL_TGT_COMPOSE_BOUNDS:
++              return pad ? R_INVALID : R_CROP_SINK;
++      case V4L2_SEL_TGT_COMPOSE:
++              return pad ? R_INVALID : R_COMPOSE;
++      default:
++              return R_INVALID;
++      }
++}
++
++static int s5k5baf_is_bound_target(u32 target)
++{
++      return (target == V4L2_SEL_TGT_CROP_BOUNDS ||
++              target == V4L2_SEL_TGT_COMPOSE_BOUNDS);
++}
++
++static int s5k5baf_get_selection(struct v4l2_subdev *sd,
++                               struct v4l2_subdev_fh *fh,
++                               struct v4l2_subdev_selection *sel)
++{
++      static enum selection_rect rtype;
++      struct s5k5baf *state = to_s5k5baf(sd);
++
++      rtype = s5k5baf_get_sel_rect(sel->pad, sel->target);
++
++      switch (rtype) {
++      case R_INVALID:
++              return -EINVAL;
++      case R_CIS:
++              sel->r = s5k5baf_cis_rect;
++              return 0;
++      default:
++              break;
++      }
++
++      if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
++              if (rtype == R_COMPOSE)
++                      sel->r = *v4l2_subdev_get_try_compose(fh, sel->pad);
++              else
++                      sel->r = *v4l2_subdev_get_try_crop(fh, sel->pad);
++              return 0;
++      }
++
++      mutex_lock(&state->lock);
++      switch (rtype) {
++      case R_CROP_SINK:
++              sel->r = state->crop_sink;
++              break;
++      case R_COMPOSE:
++              sel->r = state->compose;
++              break;
++      case R_CROP_SOURCE:
++              sel->r = state->crop_source;
++              break;
++      default:
++              break;
++      }
++      if (s5k5baf_is_bound_target(sel->target)) {
++              sel->r.left = 0;
++              sel->r.top = 0;
++      }
++      mutex_unlock(&state->lock);
++
++      return 0;
++}
++
++/* bounds range [start, start+len) to [0, max) and aligns to 2 */
++static void s5k5baf_bound_range(u32 *start, u32 *len, u32 max)
++{
++      if (*len > max)
++              *len = max;
++      if (*start + *len > max)
++              *start = max - *len;
++      *start &= ~1;
++      *len &= ~1;
++      if (*len < S5K5BAF_WIN_WIDTH_MIN)
++              *len = S5K5BAF_WIN_WIDTH_MIN;
++}
++
++static void s5k5baf_bound_rect(struct v4l2_rect *r, u32 width, u32 height)
++{
++      s5k5baf_bound_range(&r->left, &r->width, width);
++      s5k5baf_bound_range(&r->top, &r->height, height);
++}
++
++static void s5k5baf_set_rect_and_adjust(struct v4l2_rect **rects,
++                                      enum selection_rect first,
++                                      struct v4l2_rect *v)
++{
++      struct v4l2_rect *r, *br;
++      enum selection_rect i = first;
++
++      *rects[first] = *v;
++      do {
++              r = rects[i];
++              br = rects[i - 1];
++              s5k5baf_bound_rect(r, br->width, br->height);
++      } while (++i != R_INVALID);
++      *v = *rects[first];
++}
++
++static bool s5k5baf_cmp_rect(const struct v4l2_rect *r1,
++                           const struct v4l2_rect *r2)
++{
++      return !memcmp(r1, r2, sizeof(*r1));
++}
++
++static int s5k5baf_set_selection(struct v4l2_subdev *sd,
++                               struct v4l2_subdev_fh *fh,
++                               struct v4l2_subdev_selection *sel)
++{
++      static enum selection_rect rtype;
++      struct s5k5baf *state = to_s5k5baf(sd);
++      struct v4l2_rect **rects;
++      int ret = 0;
++
++      rtype = s5k5baf_get_sel_rect(sel->pad, sel->target);
++      if (rtype == R_INVALID || s5k5baf_is_bound_target(sel->target))
++              return -EINVAL;
++
++      /* allow only scaling on compose */
++      if (rtype == R_COMPOSE) {
++              sel->r.left = 0;
++              sel->r.top = 0;
++      }
++
++      if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
++              rects = (struct v4l2_rect * []) {
++                              &s5k5baf_cis_rect,
++                              v4l2_subdev_get_try_crop(fh, PAD_CIS),
++                              v4l2_subdev_get_try_compose(fh, PAD_CIS),
++                              v4l2_subdev_get_try_crop(fh, PAD_OUT)
++                      };
++              s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r);
++              return 0;
++      }
++
++      rects = (struct v4l2_rect * []) {
++                      &s5k5baf_cis_rect,
++                      &state->crop_sink,
++                      &state->compose,
++                      &state->crop_source
++              };
++      mutex_lock(&state->lock);
++      if (state->streaming) {
++              /* adjust sel->r to avoid output resolution change */
++              if (rtype < R_CROP_SOURCE) {
++                      if (sel->r.width < state->crop_source.width)
++                              sel->r.width = state->crop_source.width;
++                      if (sel->r.height < state->crop_source.height)
++                              sel->r.height = state->crop_source.height;
++              } else {
++                      sel->r.width = state->crop_source.width;
++                      sel->r.height = state->crop_source.height;
++              }
++      }
++      s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r);
++      if (!s5k5baf_cmp_rect(&state->crop_sink, &s5k5baf_cis_rect) ||
++          !s5k5baf_cmp_rect(&state->compose, &s5k5baf_cis_rect))
++              state->apply_crop = 1;
++      if (state->streaming)
++              ret = s5k5baf_hw_set_crop_rects(state);
++      mutex_unlock(&state->lock);
++
++      return ret;
++}
++
++static const struct v4l2_subdev_pad_ops s5k5baf_cis_pad_ops = {
++      .enum_mbus_code         = s5k5baf_enum_mbus_code,
++      .enum_frame_size        = s5k5baf_enum_frame_size,
++      .get_fmt                = s5k5baf_get_fmt,
++      .set_fmt                = s5k5baf_set_fmt,
++};
++
++static const struct v4l2_subdev_pad_ops s5k5baf_pad_ops = {
++      .enum_mbus_code         = s5k5baf_enum_mbus_code,
++      .enum_frame_size        = s5k5baf_enum_frame_size,
++      .enum_frame_interval    = s5k5baf_enum_frame_interval,
++      .get_fmt                = s5k5baf_get_fmt,
++      .set_fmt                = s5k5baf_set_fmt,
++      .get_selection          = s5k5baf_get_selection,
++      .set_selection          = s5k5baf_set_selection,
++};
++
++static const struct v4l2_subdev_video_ops s5k5baf_video_ops = {
++      .g_frame_interval       = s5k5baf_g_frame_interval,
++      .s_frame_interval       = s5k5baf_s_frame_interval,
++      .s_stream               = s5k5baf_s_stream,
++};
++
++/*
++ * V4L2 subdev controls
++ */
++
++static int s5k5baf_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++      struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
++      struct s5k5baf *state = to_s5k5baf(sd);
++      int ret;
++
++      v4l2_dbg(1, debug, sd, "ctrl: %s, value: %d\n", ctrl->name, ctrl->val);
++
++      mutex_lock(&state->lock);
++
++      if (state->power == 0)
++              goto unlock;
++
++      switch (ctrl->id) {
++      case V4L2_CID_AUTO_WHITE_BALANCE:
++              s5k5baf_hw_set_awb(state, ctrl->val);
++              break;
++
++      case V4L2_CID_BRIGHTNESS:
++              s5k5baf_write(state, REG_USER_BRIGHTNESS, ctrl->val);
++              break;
++
++      case V4L2_CID_COLORFX:
++              s5k5baf_hw_set_colorfx(state, ctrl->val);
++              break;
++
++      case V4L2_CID_CONTRAST:
++              s5k5baf_write(state, REG_USER_CONTRAST, ctrl->val);
++              break;
++
++      case V4L2_CID_EXPOSURE_AUTO:
++              s5k5baf_hw_set_auto_exposure(state, ctrl->val);
++              break;
++
++      case V4L2_CID_HFLIP:
++              s5k5baf_hw_set_mirror(state);
++              break;
++
++      case V4L2_CID_POWER_LINE_FREQUENCY:
++              s5k5baf_hw_set_anti_flicker(state, ctrl->val);
++              break;
++
++      case V4L2_CID_SATURATION:
++              s5k5baf_write(state, REG_USER_SATURATION, ctrl->val);
++              break;
++
++      case V4L2_CID_SHARPNESS:
++              s5k5baf_write(state, REG_USER_SHARPBLUR, ctrl->val);
++              break;
++
++      case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
++              s5k5baf_write(state, REG_P_COLORTEMP(0), ctrl->val);
++              if (state->apply_cfg)
++                      s5k5baf_hw_sync_cfg(state);
++              break;
++
++      case V4L2_CID_TEST_PATTERN:
++              s5k5baf_hw_set_test_pattern(state, ctrl->val);
++              break;
++      }
++unlock:
++      ret = s5k5baf_clear_error(state);
++      mutex_unlock(&state->lock);
++      return ret;
++}
++
++static const struct v4l2_ctrl_ops s5k5baf_ctrl_ops = {
++      .s_ctrl = s5k5baf_s_ctrl,
++};
++
++static const char * const s5k5baf_test_pattern_menu[] = {
++      "Disabled",
++      "Blank",
++      "Bars",
++      "Gradients",
++      "Textile",
++      "Textile2",
++      "Squares"
++};
++
++static int s5k5baf_initialize_ctrls(struct s5k5baf *state)
++{
++      const struct v4l2_ctrl_ops *ops = &s5k5baf_ctrl_ops;
++      struct s5k5baf_ctrls *ctrls = &state->ctrls;
++      struct v4l2_ctrl_handler *hdl = &ctrls->handler;
++      int ret;
++
++      ret = v4l2_ctrl_handler_init(hdl, 16);
++      if (ret < 0) {
++              v4l2_err(&state->sd, "cannot init ctrl handler (%d)\n", ret);
++              return ret;
++      }
++
++      /* Auto white balance cluster */
++      ctrls->awb = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTO_WHITE_BALANCE,
++                                     0, 1, 1, 1);
++      ctrls->gain_red = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_RED_BALANCE,
++                                          0, 255, 1, S5K5BAF_GAIN_RED_DEF);
++      ctrls->gain_blue = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BLUE_BALANCE,
++                                           0, 255, 1, S5K5BAF_GAIN_BLUE_DEF);
++      v4l2_ctrl_auto_cluster(3, &ctrls->awb, 0, false);
++
++      ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
++      ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
++      v4l2_ctrl_cluster(2, &ctrls->hflip);
++
++      ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops,
++                              V4L2_CID_EXPOSURE_AUTO,
++                              V4L2_EXPOSURE_MANUAL, 0, V4L2_EXPOSURE_AUTO);
++      /* Exposure time: x 1 us */
++      ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
++                                          0, 6000000U, 1, 100000U);
++      /* Total gain: 256 <=> 1x */
++      ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN,
++                                      0, 256, 1, 256);
++      v4l2_ctrl_auto_cluster(3, &ctrls->auto_exp, 0, false);
++
++      v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_POWER_LINE_FREQUENCY,
++                             V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
++                             V4L2_CID_POWER_LINE_FREQUENCY_AUTO);
++
++      v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_COLORFX,
++                             V4L2_COLORFX_SKY_BLUE, ~0x6f, V4L2_COLORFX_NONE);
++
++      v4l2_ctrl_new_std(hdl, ops, V4L2_CID_WHITE_BALANCE_TEMPERATURE,
++                        0, 256, 1, 0);
++
++      v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION, -127, 127, 1, 0);
++      v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, -127, 127, 1, 0);
++      v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -127, 127, 1, 0);
++      v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SHARPNESS, -127, 127, 1, 0);
++
++      v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_TEST_PATTERN,
++                                   ARRAY_SIZE(s5k5baf_test_pattern_menu) - 1,
++                                   0, 0, s5k5baf_test_pattern_menu);
++
++      if (hdl->error) {
++              v4l2_err(&state->sd, "error creating controls (%d)\n",
++                       hdl->error);
++              ret = hdl->error;
++              v4l2_ctrl_handler_free(hdl);
++              return ret;
++      }
++
++      state->sd.ctrl_handler = hdl;
++      return 0;
++}
++
++/*
++ * V4L2 subdev internal operations
++ */
++static int s5k5baf_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
++{
++      struct v4l2_mbus_framefmt *mf;
++
++      mf = v4l2_subdev_get_try_format(fh, PAD_CIS);
++      s5k5baf_try_cis_format(mf);
++
++      if (s5k5baf_is_cis_subdev(sd))
++              return 0;
++
++      mf = v4l2_subdev_get_try_format(fh, PAD_OUT);
++      mf->colorspace = s5k5baf_formats[0].colorspace;
++      mf->code = s5k5baf_formats[0].code;
++      mf->width = s5k5baf_cis_rect.width;
++      mf->height = s5k5baf_cis_rect.height;
++      mf->field = V4L2_FIELD_NONE;
++
++      *v4l2_subdev_get_try_crop(fh, PAD_CIS) = s5k5baf_cis_rect;
++      *v4l2_subdev_get_try_compose(fh, PAD_CIS) = s5k5baf_cis_rect;
++      *v4l2_subdev_get_try_crop(fh, PAD_OUT) = s5k5baf_cis_rect;
++
++      return 0;
++}
++
++static int s5k5baf_check_fw_revision(struct s5k5baf *state)
++{
++      u16 api_ver = 0, fw_rev = 0, s_id = 0;
++      int ret;
++
++      api_ver = s5k5baf_read(state, REG_FW_APIVER);
++      fw_rev = s5k5baf_read(state, REG_FW_REVISION) & 0xff;
++      s_id = s5k5baf_read(state, REG_FW_SENSOR_ID);
++      ret = s5k5baf_clear_error(state);
++      if (ret < 0)
++              return ret;
++
++      v4l2_info(&state->sd, "FW API=%#x, revision=%#x sensor_id=%#x\n",
++                api_ver, fw_rev, s_id);
++
++      if (api_ver != S5K5BAF_FW_APIVER) {
++              v4l2_err(&state->sd, "FW API version not supported\n");
++              return -ENODEV;
++      }
++
++      return 0;
++}
++
++static int s5k5baf_registered(struct v4l2_subdev *sd)
++{
++      struct s5k5baf *state = to_s5k5baf(sd);
++      int ret;
++
++      ret = v4l2_device_register_subdev(sd->v4l2_dev, &state->cis_sd);
++      if (ret < 0)
++              v4l2_err(sd, "failed to register subdev %s\n",
++                       state->cis_sd.name);
++      else
++              ret = media_entity_create_link(&state->cis_sd.entity, PAD_CIS,
++                                             &state->sd.entity, PAD_CIS,
++                                             MEDIA_LNK_FL_IMMUTABLE |
++                                             MEDIA_LNK_FL_ENABLED);
++      return ret;
++}
++
++static void s5k5baf_unregistered(struct v4l2_subdev *sd)
++{
++      struct s5k5baf *state = to_s5k5baf(sd);
++      v4l2_device_unregister_subdev(&state->cis_sd);
++}
++
++static const struct v4l2_subdev_ops s5k5baf_cis_subdev_ops = {
++      .pad    = &s5k5baf_cis_pad_ops,
++};
++
++static const struct v4l2_subdev_internal_ops s5k5baf_cis_subdev_internal_ops = {
++      .open = s5k5baf_open,
++};
++
++static const struct v4l2_subdev_internal_ops s5k5baf_subdev_internal_ops = {
++      .registered = s5k5baf_registered,
++      .unregistered = s5k5baf_unregistered,
++      .open = s5k5baf_open,
++};
++
++static const struct v4l2_subdev_core_ops s5k5baf_core_ops = {
++      .s_power = s5k5baf_set_power,
++      .log_status = v4l2_ctrl_subdev_log_status,
++};
++
++static const struct v4l2_subdev_ops s5k5baf_subdev_ops = {
++      .core = &s5k5baf_core_ops,
++      .pad = &s5k5baf_pad_ops,
++      .video = &s5k5baf_video_ops,
++};
++
++static int s5k5baf_configure_gpios(struct s5k5baf *state)
++{
++      static const char const *name[] = { "S5K5BAF_STBY", "S5K5BAF_RST" };
++      struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
++      struct s5k5baf_gpio *g = state->gpios;
++      int ret, i;
++
++      for (i = 0; i < GPIO_NUM; ++i) {
++              int flags = GPIOF_DIR_OUT;
++              if (g[i].level)
++                      flags |= GPIOF_INIT_HIGH;
++              ret = devm_gpio_request_one(&c->dev, g[i].gpio, flags, name[i]);
++              if (ret < 0) {
++                      v4l2_err(c, "failed to request gpio %s\n", name[i]);
++                      return ret;
++              }
++      }
++      return 0;
++}
++
++static int s5k5baf_parse_gpios(struct s5k5baf_gpio *gpios, struct device *dev)
++{
++      static const char * const names[] = {
++              "stbyn-gpios",
++              "rstn-gpios",
++      };
++      struct device_node *node = dev->of_node;
++      enum of_gpio_flags flags;
++      int ret, i;
++
++      for (i = 0; i < GPIO_NUM; ++i) {
++              ret = of_get_named_gpio_flags(node, names[i], 0, &flags);
++              if (ret < 0) {
++                      dev_err(dev, "no %s GPIO pin provided\n", names[i]);
++                      return ret;
++              }
++              gpios[i].gpio = ret;
++              gpios[i].level = !(flags & OF_GPIO_ACTIVE_LOW);
++      }
++
++      return 0;
++}
++
++static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev)
++{
++      struct device_node *node = dev->of_node;
++      struct device_node *node_ep;
++      struct v4l2_of_endpoint ep;
++      int ret;
++
++      if (!node) {
++              dev_err(dev, "no device-tree node provided\n");
++              return -EINVAL;
++      }
++
++      ret = of_property_read_u32(node, "clock-frequency",
++                                 &state->mclk_frequency);
++      if (ret < 0) {
++              state->mclk_frequency = S5K5BAF_DEFAULT_MCLK_FREQ;
++              dev_info(dev, "using default %u Hz clock frequency\n",
++                       state->mclk_frequency);
++      }
++
++      ret = s5k5baf_parse_gpios(state->gpios, dev);
++      if (ret < 0)
++              return ret;
++
++      node_ep = v4l2_of_get_next_endpoint(node, NULL);
++      if (!node_ep) {
++              dev_err(dev, "no endpoint defined at node %s\n",
++                      node->full_name);
++              return -EINVAL;
++      }
++
++      v4l2_of_parse_endpoint(node_ep, &ep);
++      of_node_put(node_ep);
++      state->bus_type = ep.bus_type;
++
++      switch (state->bus_type) {
++      case V4L2_MBUS_CSI2:
++              state->nlanes = ep.bus.mipi_csi2.num_data_lanes;
++              break;
++      case V4L2_MBUS_PARALLEL:
++              break;
++      default:
++              dev_err(dev, "unsupported bus in endpoint defined at node %s\n",
++                      node->full_name);
++              return -EINVAL;
++      }
++
++      return 0;
++}
++
++static int s5k5baf_configure_subdevs(struct s5k5baf *state,
++                                   struct i2c_client *c)
++{
++      struct v4l2_subdev *sd;
++      int ret;
++
++      sd = &state->cis_sd;
++      v4l2_subdev_init(sd, &s5k5baf_cis_subdev_ops);
++      sd->owner = THIS_MODULE;
++      v4l2_set_subdevdata(sd, state);
++      snprintf(sd->name, sizeof(sd->name), "S5K5BAF-CIS %d-%04x",
++               i2c_adapter_id(c->adapter), c->addr);
++
++      sd->internal_ops = &s5k5baf_cis_subdev_internal_ops;
++      sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++      state->cis_pad.flags = MEDIA_PAD_FL_SOURCE;
++      sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
++      ret = media_entity_init(&sd->entity, CIS_PAD_NUM, &state->cis_pad, 0);
++      if (ret < 0)
++              goto err;
++
++      sd = &state->sd;
++      v4l2_i2c_subdev_init(sd, c, &s5k5baf_subdev_ops);
++      snprintf(sd->name, sizeof(sd->name), "S5K5BAF-ISP %d-%04x",
++               i2c_adapter_id(c->adapter), c->addr);
++
++      sd->internal_ops = &s5k5baf_subdev_internal_ops;
++      sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++      state->pads[PAD_CIS].flags = MEDIA_PAD_FL_SINK;
++      state->pads[PAD_OUT].flags = MEDIA_PAD_FL_SOURCE;
++      sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
++      ret = media_entity_init(&sd->entity, ISP_PAD_NUM, state->pads, 0);
++
++      if (!ret)
++              return 0;
++
++      media_entity_cleanup(&state->cis_sd.entity);
++err:
++      dev_err(&c->dev, "cannot init media entity %s\n", sd->name);
++      return ret;
++}
++
++static int s5k5baf_configure_regulators(struct s5k5baf *state)
++{
++      struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
++      int ret;
++      int i;
++
++      for (i = 0; i < S5K5BAF_NUM_SUPPLIES; i++)
++              state->supplies[i].supply = s5k5baf_supply_names[i];
++
++      ret = devm_regulator_bulk_get(&c->dev, S5K5BAF_NUM_SUPPLIES,
++                                    state->supplies);
++      if (ret < 0)
++              v4l2_err(c, "failed to get regulators\n");
++      return ret;
++}
++
++static int s5k5baf_probe(struct i2c_client *c,
++                      const struct i2c_device_id *id)
++{
++      struct s5k5baf *state;
++      int ret;
++
++      state = devm_kzalloc(&c->dev, sizeof(*state), GFP_KERNEL);
++      if (!state)
++              return -ENOMEM;
++
++      mutex_init(&state->lock);
++      state->crop_sink = s5k5baf_cis_rect;
++      state->compose = s5k5baf_cis_rect;
++      state->crop_source = s5k5baf_cis_rect;
++
++      ret = s5k5baf_parse_device_node(state, &c->dev);
++      if (ret < 0)
++              return ret;
++
++      ret = s5k5baf_configure_subdevs(state, c);
++      if (ret < 0)
++              return ret;
++
++      ret = s5k5baf_configure_gpios(state);
++      if (ret < 0)
++              goto err_me;
++
++      ret = s5k5baf_configure_regulators(state);
++      if (ret < 0)
++              goto err_me;
++
++      state->clock = devm_clk_get(state->sd.dev, S5K5BAF_CLK_NAME);
++      if (IS_ERR(state->clock)) {
++              ret = -EPROBE_DEFER;
++              goto err_me;
++      }
++
++      ret = s5k5baf_power_on(state);
++      if (ret < 0) {
++              ret = -EPROBE_DEFER;
++              goto err_me;
++      }
++      s5k5baf_hw_init(state);
++      ret = s5k5baf_check_fw_revision(state);
++
++      s5k5baf_power_off(state);
++      if (ret < 0)
++              goto err_me;
++
++      ret = s5k5baf_initialize_ctrls(state);
++      if (ret < 0)
++              goto err_me;
++
++      ret = v4l2_async_register_subdev(&state->sd);
++      if (ret < 0)
++              goto err_ctrl;
++
++      return 0;
++
++err_ctrl:
++      v4l2_ctrl_handler_free(state->sd.ctrl_handler);
++err_me:
++      media_entity_cleanup(&state->sd.entity);
++      media_entity_cleanup(&state->cis_sd.entity);
++      return ret;
++}
++
++static int s5k5baf_remove(struct i2c_client *c)
++{
++      struct v4l2_subdev *sd = i2c_get_clientdata(c);
++      struct s5k5baf *state = to_s5k5baf(sd);
++
++      v4l2_async_unregister_subdev(sd);
++
++      v4l2_device_unregister_subdev(sd);
++      v4l2_ctrl_handler_free(sd->ctrl_handler);
++      media_entity_cleanup(&sd->entity);
++
++      sd = &state->cis_sd;
++      v4l2_device_unregister_subdev(sd);
++      media_entity_cleanup(&sd->entity);
++
++      return 0;
++}
++
++static const struct i2c_device_id s5k5baf_id[] = {
++      { S5K5BAF_DRIVER_NAME, 0 },
++      { },
++};
++MODULE_DEVICE_TABLE(i2c, s5k5baf_id);
++
++static const struct of_device_id s5k5baf_of_match[] = {
++      { .compatible = "samsung,s5k5baf" },
++      { }
++};
++MODULE_DEVICE_TABLE(of, s5k5baf_of_match);
++
++static struct i2c_driver s5k5baf_i2c_driver = {
++      .driver = {
++              .of_match_table = s5k5baf_of_match,
++              .name = S5K5BAF_DRIVER_NAME
++      },
++      .probe          = s5k5baf_probe,
++      .remove         = s5k5baf_remove,
++      .id_table       = s5k5baf_id,
++};
++
++module_i2c_driver(s5k5baf_i2c_driver);
++
++MODULE_DESCRIPTION("Samsung S5K5BAF(X) UXGA camera driver");
++MODULE_AUTHOR("Andrzej Hajda <a.hajda@samsung.com>");
++MODULE_LICENSE("GPL v2");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0743-m5mols-change-module-name-to-lowercase.patch b/patches.tizen/0743-m5mols-change-module-name-to-lowercase.patch
new file mode 100644 (file)
index 0000000..5c8b532
--- /dev/null
@@ -0,0 +1,40 @@
+From 309d5c46a209175bde0c79ae382640bed8356dfd Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Thu, 18 Jul 2013 11:32:22 +0200
+Subject: [PATCH 0743/1302] m5mols: change module name to lowercase
+
+The change allows automatic load of the module
+in case it is linked dynamically.
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/m5mols/m5mols_core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c
+index 8119b30..dce8b47 100644
+--- a/drivers/media/i2c/m5mols/m5mols_core.c
++++ b/drivers/media/i2c/m5mols/m5mols_core.c
+@@ -33,7 +33,7 @@
+ int m5mols_debug;
+ module_param(m5mols_debug, int, 0644);
+-#define MODULE_NAME           "M5MOLS"
++#define MODULE_NAME           "m5mols"
+ #define M5MOLS_I2C_CHECK_RETRY        500
+ /* The regulator consumer names for external voltage regulators */
+@@ -996,7 +996,7 @@ static int m5mols_probe(struct i2c_client *client,
+       sd = &info->sd;
+       v4l2_i2c_subdev_init(sd, client, &m5mols_ops);
+-      strlcpy(sd->name, MODULE_NAME, sizeof(sd->name));
++      strlcpy(sd->name, "M5MOLS", sizeof(sd->name));
+       sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+       sd->internal_ops = &m5mols_subdev_internal_ops;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0744-m5mols-add-device-tree-support.patch b/patches.tizen/0744-m5mols-add-device-tree-support.patch
new file mode 100644 (file)
index 0000000..a5fe5e4
--- /dev/null
@@ -0,0 +1,255 @@
+From c75f9be8679f0fdd6d8fc5fce6593f573273ba8f Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Tue, 3 Sep 2013 16:34:08 +0200
+Subject: [PATCH 0744/1302] m5mols: add device tree support
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/m5mols/m5mols.h      |   7 ++-
+ drivers/media/i2c/m5mols/m5mols_core.c | 108 ++++++++++++++++++++++-----------
+ 2 files changed, 78 insertions(+), 37 deletions(-)
+
+diff --git a/drivers/media/i2c/m5mols/m5mols.h b/drivers/media/i2c/m5mols/m5mols.h
+index 90a6c52..d06e7fb 100644
+--- a/drivers/media/i2c/m5mols/m5mols.h
++++ b/drivers/media/i2c/m5mols/m5mols.h
+@@ -160,6 +160,11 @@ struct m5mols_version {
+       u8      af;
+ };
++struct m5mols_gpio {
++      int gpio;
++      int level;
++};
++
+ /**
+  * struct m5mols_info - M-5MOLS driver data structure
+  * @pdata: platform data
+@@ -195,13 +200,13 @@ struct m5mols_version {
+  * @mode: register value for current operation mode
+  */
+ struct m5mols_info {
+-      const struct m5mols_platform_data *pdata;
+       struct v4l2_subdev sd;
+       struct media_pad pad;
+       wait_queue_head_t irq_waitq;
+       atomic_t irq_done;
++      struct m5mols_gpio reset_gpio;
+       struct v4l2_ctrl_handler handle;
+       struct {
+               /* exposure/exposure bias/auto exposure cluster */
+diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c
+index dce8b47..5adc6fb 100644
+--- a/drivers/media/i2c/m5mols/m5mols_core.c
++++ b/drivers/media/i2c/m5mols/m5mols_core.c
+@@ -19,6 +19,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/delay.h>
+ #include <linux/gpio.h>
++#include <linux/of_gpio.h>
+ #include <linux/regulator/consumer.h>
+ #include <linux/videodev2.h>
+ #include <linux/module.h>
+@@ -760,9 +761,7 @@ static int regulator_bulk_enable_sync(int num_consumers,
+ static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
+ {
+-      struct v4l2_subdev *sd = &info->sd;
+-      struct i2c_client *client = v4l2_get_subdevdata(sd);
+-      const struct m5mols_platform_data *pdata = info->pdata;
++      struct device *dev = info->sd.dev;
+       int ret;
+       if (info->power == enable)
+@@ -770,19 +769,21 @@ static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
+       if (enable) {
+               if (info->set_power) {
+-                      ret = info->set_power(&client->dev, 1);
++                      ret = info->set_power(dev, 1);
+                       if (ret)
+                               return ret;
+               }
+               ret = regulator_bulk_enable_sync(ARRAY_SIZE(supplies),
+                                                 supplies);
+-              if (ret) {
+-                      info->set_power(&client->dev, 0);
++
++              if (ret < 0) {
++                      regulator_bulk_disable(ARRAY_SIZE(supplies), supplies);
++                      info->set_power(dev, 0);
+                       return ret;
+               }
+-              gpio_set_value(pdata->gpio_reset, !pdata->reset_polarity);
++              gpio_set_value(info->reset_gpio.gpio, !info->reset_gpio.level);
+               usleep_range(1000, 1000);
+               info->power = 1;
+@@ -790,13 +791,14 @@ static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
+       }
+       ret = regulator_bulk_disable(ARRAY_SIZE(supplies), supplies);
+-      if (ret)
+-              return ret;
++      if (ret) {
++              v4l2_err(&info->sd, "error disabling regulators: %d\n", ret);
++      }
+       if (info->set_power)
+-              info->set_power(&client->dev, 0);
++              info->set_power(dev, 0);
+-      gpio_set_value(pdata->gpio_reset, pdata->reset_polarity);
++      gpio_set_value(info->reset_gpio.gpio, info->reset_gpio.level);
+       usleep_range(1000, 1000);
+       info->isp_ready = 0;
+@@ -947,25 +949,46 @@ static irqreturn_t m5mols_irq_handler(int irq, void *data)
+       return IRQ_HANDLED;
+ }
++static int m5mols_get_platform_data(struct m5mols_info *info,
++                                  struct device *dev)
++{
++      const struct m5mols_platform_data *pdata = dev->platform_data;
++
++      if (pdata) {
++              info->reset_gpio.gpio = pdata->gpio_reset;
++              info->reset_gpio.level = pdata->reset_polarity;
++              info->set_power = pdata->set_power;
++              return 0;
++      }
++
++      if (dev->of_node) {
++              int ret;
++              enum of_gpio_flags flags;
++
++              ret = of_get_named_gpio_flags(dev->of_node, "resetb-gpios", 0,
++                                            &flags);
++              if (ret < 0) {
++                      dev_err(dev, "no resetb-gpios GPIO provided\n");
++                      return ret;
++              }
++              info->reset_gpio.gpio = ret;
++              info->reset_gpio.level = !(flags & OF_GPIO_ACTIVE_LOW);
++
++              return 0;
++      }
++
++      dev_err(dev, "no platform data provided\n");
++      return -EINVAL;
++}
++
+ static int m5mols_probe(struct i2c_client *client,
+                       const struct i2c_device_id *id)
+ {
+-      const struct m5mols_platform_data *pdata = client->dev.platform_data;
+       unsigned long gpio_flags;
+       struct m5mols_info *info;
+       struct v4l2_subdev *sd;
+       int ret;
+-      if (pdata == NULL) {
+-              dev_err(&client->dev, "No platform data\n");
+-              return -EINVAL;
+-      }
+-
+-      if (!gpio_is_valid(pdata->gpio_reset)) {
+-              dev_err(&client->dev, "No valid RESET GPIO specified\n");
+-              return -EINVAL;
+-      }
+-
+       if (!client->irq) {
+               dev_err(&client->dev, "Interrupt not assigned\n");
+               return -EINVAL;
+@@ -975,21 +998,23 @@ static int m5mols_probe(struct i2c_client *client,
+       if (!info)
+               return -ENOMEM;
+-      info->pdata = pdata;
+-      info->set_power = pdata->set_power;
++      ret = m5mols_get_platform_data(info, &client->dev);
++      if (ret < 0)
++              return ret;
+-      gpio_flags = pdata->reset_polarity
+-                 ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+-      ret = devm_gpio_request_one(&client->dev, pdata->gpio_reset, gpio_flags,
+-                                  "M5MOLS_NRST");
+-      if (ret) {
+-              dev_err(&client->dev, "Failed to request gpio: %d\n", ret);
++      gpio_flags = info->reset_gpio.level ? GPIOF_OUT_INIT_HIGH :
++                      GPIOF_OUT_INIT_LOW;
++      ret = devm_gpio_request_one(&client->dev, info->reset_gpio.gpio,
++                                  gpio_flags, "M5MOLS_RESETB");
++      if (ret < 0) {
++              dev_err(&client->dev, "Failed to request gpio: %d\n",
++                      ret);
+               return ret;
+       }
+       ret = devm_regulator_bulk_get(&client->dev, ARRAY_SIZE(supplies),
+                                     supplies);
+-      if (ret) {
++      if (ret < 0) {
+               dev_err(&client->dev, "Failed to get regulators: %d\n", ret);
+               return ret;
+       }
+@@ -1011,7 +1036,7 @@ static int m5mols_probe(struct i2c_client *client,
+       ret = devm_request_irq(&client->dev, client->irq, m5mols_irq_handler,
+                              IRQF_TRIGGER_RISING, MODULE_NAME, sd);
+-      if (ret) {
++      if (ret < 0) {
+               dev_err(&client->dev, "Interrupt request failed: %d\n", ret);
+               goto error;
+       }
+@@ -1020,16 +1045,18 @@ static int m5mols_probe(struct i2c_client *client,
+       info->ffmt[1] = m5mols_default_ffmt[1];
+       ret = m5mols_sensor_power(info, true);
+-      if (ret)
++      if (ret < 0)
+               goto error;
+       ret = m5mols_fw_start(sd);
+       if (!ret)
+               ret = m5mols_init_controls(sd);
+-      ret = m5mols_sensor_power(info, false);
+-      if (!ret)
+-              return 0;
++      m5mols_sensor_power(info, false);
++      if (ret < 0)
++              goto error;
++
++      return 0;
+ error:
+       media_entity_cleanup(&sd->entity);
+       return ret;
+@@ -1052,8 +1079,17 @@ static const struct i2c_device_id m5mols_id[] = {
+ };
+ MODULE_DEVICE_TABLE(i2c, m5mols_id);
++#ifdef CONFIG_OF
++static const struct of_device_id m5mols_of_match[] = {
++      { .compatible = "fujitsu,m5mols" },
++      { }
++};
++MODULE_DEVICE_TABLE(of, m5mols_of_match);
++#endif
++
+ static struct i2c_driver m5mols_i2c_driver = {
+       .driver = {
++              .of_match_table = of_match_ptr(m5mols_of_match),
+               .name   = MODULE_NAME,
+       },
+       .probe          = m5mols_probe,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0745-m5mols-add-clock-support.patch b/patches.tizen/0745-m5mols-add-clock-support.patch
new file mode 100644 (file)
index 0000000..52c75dd
--- /dev/null
@@ -0,0 +1,77 @@
+From e862a08f39982b7613bc80864443d4a2973a2667 Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Tue, 3 Sep 2013 16:35:08 +0200
+Subject: [PATCH 0745/1302] m5mols: add clock support
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/m5mols/m5mols.h      |  1 +
+ drivers/media/i2c/m5mols/m5mols_core.c | 11 +++++++++++
+ 2 files changed, 12 insertions(+)
+
+diff --git a/drivers/media/i2c/m5mols/m5mols.h b/drivers/media/i2c/m5mols/m5mols.h
+index d06e7fb..403d5e1 100644
+--- a/drivers/media/i2c/m5mols/m5mols.h
++++ b/drivers/media/i2c/m5mols/m5mols.h
+@@ -207,6 +207,7 @@ struct m5mols_info {
+       atomic_t irq_done;
+       struct m5mols_gpio reset_gpio;
++      struct clk *clock;
+       struct v4l2_ctrl_handler handle;
+       struct {
+               /* exposure/exposure bias/auto exposure cluster */
+diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c
+index 5adc6fb..c0d3551 100644
+--- a/drivers/media/i2c/m5mols/m5mols_core.c
++++ b/drivers/media/i2c/m5mols/m5mols_core.c
+@@ -13,6 +13,7 @@
+  * (at your option) any later version.
+  */
++#include <linux/clk.h>
+ #include <linux/i2c.h>
+ #include <linux/slab.h>
+ #include <linux/irq.h>
+@@ -36,6 +37,7 @@ module_param(m5mols_debug, int, 0644);
+ #define MODULE_NAME           "m5mols"
+ #define M5MOLS_I2C_CHECK_RETRY        500
++#define M5MOLS_CLK_NAME       "clkin"
+ /* The regulator consumer names for external voltage regulators */
+ static struct regulator_bulk_data supplies[] = {
+@@ -777,6 +779,9 @@ static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
+               ret = regulator_bulk_enable_sync(ARRAY_SIZE(supplies),
+                                                 supplies);
++              if (!ret)
++                      ret = clk_prepare_enable(info->clock);
++
+               if (ret < 0) {
+                       regulator_bulk_disable(ARRAY_SIZE(supplies), supplies);
+                       info->set_power(dev, 0);
+@@ -790,6 +795,8 @@ static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
+               return ret;
+       }
++      clk_disable_unprepare(info->clock);
++
+       ret = regulator_bulk_disable(ARRAY_SIZE(supplies), supplies);
+       if (ret) {
+               v4l2_err(&info->sd, "error disabling regulators: %d\n", ret);
+@@ -1019,6 +1026,10 @@ static int m5mols_probe(struct i2c_client *client,
+               return ret;
+       }
++      info->clock = devm_clk_get(&client->dev, M5MOLS_CLK_NAME);
++      if (IS_ERR(info->clock))
++              return -EPROBE_DEFER;
++
+       sd = &info->sd;
+       v4l2_i2c_subdev_init(sd, client, &m5mols_ops);
+       strlcpy(sd->name, "M5MOLS", sizeof(sd->name));
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0746-m5mols-add-async-subdev-registration.patch b/patches.tizen/0746-m5mols-add-async-subdev-registration.patch
new file mode 100644 (file)
index 0000000..55089d7
--- /dev/null
@@ -0,0 +1,38 @@
+From d77fb2a8649fee22dc13290da783522c6f5a5d5f Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Wed, 4 Sep 2013 08:31:48 +0200
+Subject: [PATCH 0746/1302] m5mols: add async subdev registration
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/i2c/m5mols/m5mols_core.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c
+index c0d3551..ad83a43 100644
+--- a/drivers/media/i2c/m5mols/m5mols_core.c
++++ b/drivers/media/i2c/m5mols/m5mols_core.c
+@@ -1067,6 +1067,10 @@ static int m5mols_probe(struct i2c_client *client,
+       if (ret < 0)
+               goto error;
++      ret = v4l2_async_register_subdev(&info->sd);
++      if (ret < 0)
++              goto error;
++
+       return 0;
+ error:
+       media_entity_cleanup(&sd->entity);
+@@ -1077,6 +1081,8 @@ static int m5mols_remove(struct i2c_client *client)
+ {
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
++      v4l2_async_unregister_subdev(sd);
++
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(sd->ctrl_handler);
+       media_entity_cleanup(&sd->entity);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0747-ARM-dts-exynos4210-trats-change-compatible-for-m5mol.patch b/patches.tizen/0747-ARM-dts-exynos4210-trats-change-compatible-for-m5mol.patch
new file mode 100644 (file)
index 0000000..5fb9753
--- /dev/null
@@ -0,0 +1,39 @@
+From 80934aeec09c7993cc53749eac3a3fa352d6b9e0 Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Tue, 23 Jul 2013 16:35:20 +0200
+Subject: [PATCH 0747/1302] ARM: dts: exynos4210-trats: change compatible for
+ m5mols
+
+Changes manufacturer from samsung to fujitsu.
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index 6219b31..a4c377d 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -229,7 +229,7 @@
+               status = "okay";
+               m5mols@1f {
+-                      compatible = "samsung,m5mols";
++                      compatible = "fujitsu,m5mols";
+                       reg = <0x1f>;
+                       interrupt-parent = <&gpx1>;
+                       interrupts = <5 1>;
+@@ -250,7 +250,6 @@
+               };
+       };
+-
+       i2c@13890000 {
+               samsung,i2c-sda-delay = <100>;
+               samsung,i2c-slave-addr = <0x10>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0748-ARM-dts-exynos4210-trats-modify-m5mols-node-accordin.patch b/patches.tizen/0748-ARM-dts-exynos4210-trats-modify-m5mols-node-accordin.patch
new file mode 100644 (file)
index 0000000..033f9db
--- /dev/null
@@ -0,0 +1,36 @@
+From 88a79203be5844f0e5723a4db6caac18bef79cd9 Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Tue, 3 Sep 2013 15:43:52 +0200
+Subject: [PATCH 0748/1302] ARM: dts: exynos4210-trats: modify m5mols node
+ according to driver
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index a4c377d..bed4256 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -239,12 +239,15 @@
+                       dig_28-supply = <&cam_af_28v_reg>;
+                       a_sensor-supply = <&cam_io_en_reg>;
+                       dig_12-supply = <&cam_io_12v_reg>;
+-                      gpios = <&gpy3 7 1>;
++                      resetb-gpios = <&gpy3 7 1>;
++                      clocks = <&camera 0>;
++                      clock-names = "clkin";
+                       clock-frequency = <24000000>;
+                       port {
+                               m5mols_ep: endpoint {
+                                       remote-endpoint = <&m5mols_ep>;
++                                      data-lanes = <1 2 3 4>;
+                               };
+                       };
+               };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0749-exynos4-is-Fix-the-writeback-clocks-handling.patch b/patches.tizen/0749-exynos4-is-Fix-the-writeback-clocks-handling.patch
new file mode 100644 (file)
index 0000000..98d712b
--- /dev/null
@@ -0,0 +1,74 @@
+From aafb873162a33fbe8a6a36101b71c7d317ac289b Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Fri, 30 Aug 2013 09:37:43 +0200
+Subject: [PATCH 0749/1302] exynos4-is: Fix the writeback clocks handling
+
+The patch fixes situation when during probe clk_get() on some clock did
+not succeed and the driver tries to clk_put() invalid clocks.
+The fix prevents faults as follows:
+
+[   43.785000] Unable to handle kernel NULL pointer dereference at virtual address 00000044
+[   43.785000] pgd = e6214000
+[   43.785000] [00000044] *pgd=00000000
+[   43.785000] Internal error: Oops: 5 [#1] PREEMPT SMP ARM
+[   43.785000] Modules linked in: s5p_fimc(+) ipv6 s5p_csis s5k5baf v4l2_mem2mem videobuf2_dma_contig videobuf2_memops exynos4_is_common videobuf2_core m5mols
+[   43.785000] CPU: 0 PID: 2496 Comm: modprobe Not tainted 3.11.0-rc2-00316-ga8cf411 #1612
+[   43.785000] task: e71a0000 ti: e6a08000 task.ti: e6a08000
+[   43.785000] PC is at __clk_put+0x1c/0x8c
+[   43.785000] LR is at clk_prepare_lock+0xc/0xd8
+[   43.785000] pc : [<c02f0d5c>]    lr : [<c02f00f0>]    psr: 60000013
+[   43.785000] sp : e6a09d20  ip : e6a09cd0  fp : c0d9df7c
+[   43.785000] r10: e6698940  r9 : e71b4a00  r8 : c0d9eca0
+[   43.785000] r7 : e71b5400  r6 : c0d9eacc  r5 : fffffdfb  r4 : 00000000
+[   43.785000] r3 : e71a0000  r2 : 00000001  r1 : 00000947  r0 : 00000044
+[   43.785000] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
+[   43.785000] Control: 10c5387d  Table: 6621404a  DAC: 00000015
+[   43.785000] Process modprobe (pid: 2496, stack limit = 0xe6a08238)
+[   43.785000] Stack: (0xe6a09d20 to 0xe6a0a000)
+               ...
+[   43.785000] [<c02f0d5c>] (__clk_put+0x1c/0x8c) from [<bf0992a0>] (fimc_md_put_clocks+0x48/0x6c [s5p_fimc])
+[   43.785000] [<bf0992a0>] (fimc_md_put_clocks+0x48/0x6c [s5p_fimc]) from [<bf09a66c>] (fimc_md_probe+0x484/0x954 [s5p_fimc])
+[   43.785000] [<bf09a66c>] (fimc_md_probe+0x484/0x954 [s5p_fimc]) from [<c0219c78>] (platform_drv_probe+0x18/0x1c)
+[   43.785000] [<c0219c78>] (platform_drv_probe+0x18/0x1c) from [<c0218ab4>] (driver_probe_device+0x108/0x224)
+[   43.785000] [<c0218ab4>] (driver_probe_device+0x108/0x224) from [<c0218c5c>] (__driver_attach+0x8c/0x90)
+[   43.785000] [<c0218c5c>] (__driver_attach+0x8c/0x90) from [<c02171a8>] (bus_for_each_dev+0x54/0x88)
+[   43.785000] [<c02171a8>] (bus_for_each_dev+0x54/0x88) from [<c02181c4>] (bus_add_driver+0xd4/0x22c)
+[   43.785000] [<c02181c4>] (bus_add_driver+0xd4/0x22c) from [<c0219114>] (driver_register+0x78/0x14c)
+[   43.785000] [<c0219114>] (driver_register+0x78/0x14c) from [<c00087a0>] (do_one_initcall+0xe4/0x140)
+[   43.785000] [<c00087a0>] (do_one_initcall+0xe4/0x140) from [<c00672ac>] (load_module+0x17b4/0x1d4c)
+[   43.785000] [<c00672ac>] (load_module+0x17b4/0x1d4c) from [<c006791c>] (SyS_init_module+0xd8/0xec)
+[   43.785000] [<c006791c>] (SyS_init_module+0xd8/0xec) from [<c000e360>] (ret_fast_syscall+0x0/0x30)
+[   43.785000] Code: 8a000012 ebfffce3 e2840044 f57ff05f (e1903f9f)
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/media-dev.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
+index 68a3022..7125411 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.c
++++ b/drivers/media/platform/exynos4-is/media-dev.c
+@@ -1145,6 +1145,9 @@ static int fimc_md_get_clocks(struct fimc_md *fmd)
+       for (i = 0; i < FIMC_MAX_CAMCLKS; i++)
+               fmd->camclk[i].clock = ERR_PTR(-EINVAL);
++      for (i = 0; i < FIMC_MAX_WBCLKS; i++)
++              fmd->wbclk[i] = ERR_PTR(-EINVAL);
++
+       if (fmd->pdev->dev.of_node)
+               dev = &fmd->pdev->dev;
+@@ -1169,8 +1172,6 @@ static int fimc_md_get_clocks(struct fimc_md *fmd)
+        * For now get only PIXELASYNCM1 clock (Writeback B/ISP),
+        * leave PIXELASYNCM0 out for the LCD Writeback driver.
+        */
+-      fmd->wbclk[CLK_IDX_WB_A] = ERR_PTR(-EINVAL);
+-
+       for (i = CLK_IDX_WB_B; i < FIMC_MAX_WBCLKS; i++) {
+               snprintf(clk_name, sizeof(clk_name), "pxl_async%u", i);
+               clock = clk_get(dev, clk_name);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0750-tizen_defconfig-update.patch b/patches.tizen/0750-tizen_defconfig-update.patch
new file mode 100644 (file)
index 0000000..47e756f
--- /dev/null
@@ -0,0 +1,28 @@
+From 902202e785482bf222804192f32b77bd1cf09b19 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 4 Sep 2013 12:53:48 +0200
+Subject: [PATCH 0750/1302] tizen_defconfig update
+
+Enable M0 front facing camera sensor driver.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_defconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index 79db035..2007fcd 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -2011,6 +2011,7 @@ CONFIG_VIDEO_SAMSUNG_S5P_MFC=y
+ # CONFIG_VIDEO_NOON010PC30 is not set
+ CONFIG_VIDEO_M5MOLS=y
+ # CONFIG_VIDEO_S5K6AA is not set
++CONFIG_VIDEO_S5K6A3=y
+ # CONFIG_VIDEO_S5K4ECGX is not set
+ CONFIG_VIDEO_S5K5BAF=y
+ # CONFIG_VIDEO_SMIAPP is not set
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0751-Revert-video-exynos_dsi-Use-generic-PHY-driver.patch b/patches.tizen/0751-Revert-video-exynos_dsi-Use-generic-PHY-driver.patch
new file mode 100644 (file)
index 0000000..c8c5316
--- /dev/null
@@ -0,0 +1,148 @@
+From fc14870772b027b6973cc1ef627e984ea0ebf7e5 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 4 Sep 2013 11:38:47 +0200
+Subject: [PATCH 0751/1302] Revert "video: exynos_dsi: Use generic PHY driver"
+
+This reverts commit 304105d59b61ac6800a274cdcf8f618b5007456a.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/video/display/source-exynos_dsi.c | 36 +++++++++++++++++++++----------
+ include/video/exynos_dsi.h                |  5 +++++
+ 2 files changed, 30 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/video/display/source-exynos_dsi.c b/drivers/video/display/source-exynos_dsi.c
+index d36162f..d7094f4 100644
+--- a/drivers/video/display/source-exynos_dsi.c
++++ b/drivers/video/display/source-exynos_dsi.c
+@@ -24,7 +24,6 @@
+ #include <linux/mm.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
+-#include <linux/phy/phy.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/regulator/consumer.h>
+@@ -220,7 +219,6 @@ struct exynos_dsi {
+       bool enabled;
+       struct platform_device *pdev;
+-      struct phy *phy;
+       struct device *dev;
+       struct resource *res;
+       struct clk *pll_clk;
+@@ -818,7 +816,6 @@ again:
+ static bool exynos_dsi_transfer_finish(struct exynos_dsi *dsi)
+ {
+-      static unsigned long j;
+       struct exynos_dsi_transfer *xfer;
+       unsigned long flags;
+       bool start = true;
+@@ -827,8 +824,7 @@ static bool exynos_dsi_transfer_finish(struct exynos_dsi *dsi)
+       if (list_empty(&dsi->transfer_list)) {
+               spin_unlock_irqrestore(&dsi->transfer_lock, flags);
+-              if (printk_timed_ratelimit(&j, 500))
+-                      dev_warn(dsi->dev, "unexpected TX/RX interrupt\n");
++              dev_warn(dsi->dev, "unexpected TX/RX interrupt\n");
+               return false;
+       }
+@@ -1000,7 +996,8 @@ static int exynos_dsi_enable(struct video_source *src)
+       clk_prepare_enable(dsi->bus_clk);
+       clk_prepare_enable(dsi->pll_clk);
+-      phy_power_on(dsi->phy);
++      if (dsi->pd->phy_enable)
++              dsi->pd->phy_enable(dsi->pdev, true);
+       exynos_dsi_reset(dsi);
+       exynos_dsi_init_link(dsi);
+@@ -1025,7 +1022,8 @@ static int exynos_dsi_disable(struct video_source *src)
+       exynos_dsi_disable_clock(dsi);
+-      phy_power_off(dsi->phy);
++      if (dsi->pd->phy_enable)
++              dsi->pd->phy_enable(dsi->pdev, false);
+       clk_disable_unprepare(dsi->pll_clk);
+       clk_disable_unprepare(dsi->bus_clk);
+@@ -1106,6 +1104,12 @@ static const struct dsi_video_source_ops exynos_dsi_ops = {
+  * Device Tree
+  */
++static int (* const of_phy_enables[])(struct platform_device *, bool) = {
++#ifdef CONFIG_S5P_SETUP_MIPIPHY
++      [0] = s5p_dsim_phy_enable,
++#endif
++};
++
+ static struct exynos_dsi_platform_data *exynos_dsi_parse_dt(
+                                               struct platform_device *pdev)
+ {
+@@ -1113,6 +1117,7 @@ static struct exynos_dsi_platform_data *exynos_dsi_parse_dt(
+       struct exynos_dsi_platform_data *dsi_pd;
+       struct device *dev = &pdev->dev;
+       const __be32 *prop_data;
++      u32 val;
+       dsi_pd = kzalloc(sizeof(*dsi_pd), GFP_KERNEL);
+       if (!dsi_pd) {
+@@ -1120,6 +1125,19 @@ static struct exynos_dsi_platform_data *exynos_dsi_parse_dt(
+               return NULL;
+       }
++      prop_data = of_get_property(node, "samsung,phy-type", NULL);
++      if (!prop_data) {
++              dev_err(dev, "failed to get phy-type property\n");
++              goto err_free_pd;
++      }
++
++      val = be32_to_cpu(*prop_data);
++      if (val >= ARRAY_SIZE(of_phy_enables) || !of_phy_enables[val]) {
++              dev_err(dev, "Invalid phy-type %u\n", val);
++              goto err_free_pd;
++      }
++      dsi_pd->phy_enable = of_phy_enables[val];
++
+       prop_data = of_get_property(node, "samsung,pll-stable-time", NULL);
+       if (!prop_data) {
+               dev_err(dev, "failed to get pll-stable-time property\n");
+@@ -1241,10 +1259,6 @@ static int exynos_dsi_probe(struct platform_device *pdev)
+               return -ENOMEM;
+       }
+-      dsi->phy = devm_phy_get(&pdev->dev, "dsim");
+-      if (IS_ERR(dsi->phy))
+-              return PTR_ERR(dsi->phy);
+-
+       platform_set_drvdata(pdev, dsi);
+       dsi->irq = platform_get_irq(pdev, 0);
+diff --git a/include/video/exynos_dsi.h b/include/video/exynos_dsi.h
+index 5c062c7..95e1568 100644
+--- a/include/video/exynos_dsi.h
++++ b/include/video/exynos_dsi.h
+@@ -25,6 +25,9 @@
+  */
+ struct exynos_dsi_platform_data {
+       unsigned int enabled;
++
++      int (*phy_enable)(struct platform_device *pdev, bool on);
++
+       unsigned int pll_stable_time;
+       unsigned long pll_clk_rate;
+       unsigned long esc_clk_rate;
+@@ -33,4 +36,6 @@ struct exynos_dsi_platform_data {
+       unsigned short rx_timeout;
+ };
++int s5p_dsim_phy_enable(struct platform_device *pdev, bool on);
++
+ #endif /* _EXYNOS_MIPI_DSIM_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0752-Revert-media-exynos4-is-Use-the-generic-MIPI-CSIS-PH.patch b/patches.tizen/0752-Revert-media-exynos4-is-Use-the-generic-MIPI-CSIS-PH.patch
new file mode 100644 (file)
index 0000000..181e6a3
--- /dev/null
@@ -0,0 +1,123 @@
+From 5fafe3b358f138e8e0804d1d5ca9246c0a0a0684 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 4 Sep 2013 11:39:36 +0200
+Subject: [PATCH 0752/1302] Revert "[media] exynos4-is: Use the generic MIPI
+ CSIS PHY driver"
+
+This reverts commit 88d0875e5d8cb005a3c21dff52581b08b6fd22eb.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/mipi-csis.c | 16 +++-------------
+ include/linux/platform_data/mipi-csis.h       | 11 +++++++++--
+ 2 files changed, 12 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
+index c26442d..0fe80e3 100644
+--- a/drivers/media/platform/exynos4-is/mipi-csis.c
++++ b/drivers/media/platform/exynos4-is/mipi-csis.c
+@@ -20,7 +20,6 @@
+ #include <linux/memory.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
+-#include <linux/phy/phy.h>
+ #include <linux/platform_data/mipi-csis.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_runtime.h>
+@@ -185,7 +184,6 @@ struct csis_drvdata {
+  * @sd: v4l2_subdev associated with CSIS device instance
+  * @index: the hardware instance index
+  * @pdev: CSIS platform device
+- * @phy: pointer to the CSIS generic PHY
+  * @regs: mmaped I/O registers memory
+  * @supplies: CSIS regulator supplies
+  * @clock: CSIS clocks
+@@ -209,8 +207,6 @@ struct csis_state {
+       struct v4l2_subdev sd;
+       u8 index;
+       struct platform_device *pdev;
+-      struct phy *phy;
+-      const char *phy_label;
+       void __iomem *regs;
+       struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES];
+       struct clk *clock[NUM_CSIS_CLOCKS];
+@@ -778,7 +774,6 @@ static int s5pcsis_get_platform_data(struct platform_device *pdev,
+       state->index = max(0, pdev->id);
+       state->max_num_lanes = state->index ? CSIS1_MAX_LANES :
+                                             CSIS0_MAX_LANES;
+-      state->phy_label = pdata->phy_label;
+       return 0;
+ }
+@@ -816,9 +811,8 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
+                                       "samsung,csis-wclk");
+       state->num_lanes = endpoint.bus.mipi_csi2.num_data_lanes;
+-      of_node_put(node);
+-      state->phy_label = "csis";
++      of_node_put(node);
+       return 0;
+ }
+ #else
+@@ -867,10 +861,6 @@ static int s5pcsis_probe(struct platform_device *pdev)
+               return -EINVAL;
+       }
+-      state->phy = devm_phy_get(dev, state->phy_label);
+-      if (IS_ERR(state->phy))
+-              return PTR_ERR(state->phy);
+-
+       mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       state->regs = devm_ioremap_resource(dev, mem_res);
+       if (IS_ERR(state->regs))
+@@ -956,7 +946,7 @@ static int s5pcsis_pm_suspend(struct device *dev, bool runtime)
+       mutex_lock(&state->lock);
+       if (state->flags & ST_POWERED) {
+               s5pcsis_stop_stream(state);
+-              ret = phy_power_off(state->phy);
++              ret = s5p_csis_phy_enable(state->index, false);
+               if (ret)
+                       goto unlock;
+               ret = regulator_bulk_disable(CSIS_NUM_SUPPLIES,
+@@ -992,7 +982,7 @@ static int s5pcsis_pm_resume(struct device *dev, bool runtime)
+                                           state->supplies);
+               if (ret)
+                       goto unlock;
+-              ret = phy_power_on(state->phy);
++              ret = s5p_csis_phy_enable(state->index, true);
+               if (!ret) {
+                       state->flags |= ST_POWERED;
+               } else {
+diff --git a/include/linux/platform_data/mipi-csis.h b/include/linux/platform_data/mipi-csis.h
+index 9214317..bf34e17 100644
+--- a/include/linux/platform_data/mipi-csis.h
++++ b/include/linux/platform_data/mipi-csis.h
+@@ -17,14 +17,21 @@
+  * @wclk_source: CSI wrapper clock selection: 0 - bus clock, 1 - ext. SCLK_CAM
+  * @lanes:       number of data lanes used
+  * @hs_settle:   HS-RX settle time
+- * @phy_label:         the generic PHY label
+  */
+ struct s5p_platform_mipi_csis {
+       unsigned long clk_rate;
+       u8 wclk_source;
+       u8 lanes;
+       u8 hs_settle;
+-      const char *phy_label;
+ };
++/**
++ * s5p_csis_phy_enable - global MIPI-CSI receiver D-PHY control
++ * @id:     MIPI-CSIS harware instance index (0...1)
++ * @on:     true to enable D-PHY and deassert its reset
++ *          false to disable D-PHY
++ * @return: 0 on success, or negative error code on failure
++ */
++int s5p_csis_phy_enable(int id, bool on);
++
+ #endif /* __PLAT_SAMSUNG_MIPI_CSIS_H_ */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0753-Revert-phy-Add-driver-for-Exynos-MIPI-CSIS-DSIM-DPHY.patch b/patches.tizen/0753-Revert-phy-Add-driver-for-Exynos-MIPI-CSIS-DSIM-DPHY.patch
new file mode 100644 (file)
index 0000000..92523f1
--- /dev/null
@@ -0,0 +1,245 @@
+From c2a1e082d95edc0476ee65001a400f2bd11058db Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 4 Sep 2013 11:39:48 +0200
+Subject: [PATCH 0753/1302] Revert "phy: Add driver for Exynos MIPI CSIS/DSIM
+ DPHYs"
+
+This reverts commit e1beba577ab67fe06d0d75546b28eea767bae03d.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/phy/samsung-phy.txt        |  14 --
+ drivers/phy/Kconfig                                |   9 --
+ drivers/phy/Makefile                               |   3 +-
+ drivers/phy/phy-exynos-mipi-video.c                | 169 ---------------------
+ 4 files changed, 1 insertion(+), 194 deletions(-)
+ delete mode 100644 Documentation/devicetree/bindings/phy/samsung-phy.txt
+ delete mode 100644 drivers/phy/phy-exynos-mipi-video.c
+
+diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt
+deleted file mode 100644
+index 5ff208c..0000000
+--- a/Documentation/devicetree/bindings/phy/samsung-phy.txt
++++ /dev/null
+@@ -1,14 +0,0 @@
+-Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY
+--------------------------------------------------
+-
+-Required properties:
+-- compatible : should be "samsung,s5pv210-mipi-video-phy";
+-- reg : offset and length of the MIPI DPHY register set;
+-- #phy-cells : from the generic phy bindings, must be 1;
+-
+-For "samsung,s5pv210-mipi-video-phy" compatible PHYs the second cell in
+-the PHY specifier identifies the PHY and its meaning is as follows:
+-  0 - MIPI CSIS 0,
+-  1 - MIPI DSIM 0,
+-  2 - MIPI CSIS 1,
+-  3 - MIPI DSIM 1.
+diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
+index 6f446d0..5f85909 100644
+--- a/drivers/phy/Kconfig
++++ b/drivers/phy/Kconfig
+@@ -11,12 +11,3 @@ menuconfig GENERIC_PHY
+         devices present in the kernel. This layer will have the generic
+         API by which phy drivers can create PHY using the phy framework and
+         phy users can obtain reference to the PHY.
+-
+-if GENERIC_PHY
+-
+-config PHY_EXYNOS_MIPI_VIDEO
+-      tristate "S5P/EXYNOS SoC series MIPI CSI-2/DSI PHY driver"
+-      help
+-        Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung
+-        S5P and EXYNOS SoCs.
+-endif
+diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
+index 71d8841..9e9560f 100644
+--- a/drivers/phy/Makefile
++++ b/drivers/phy/Makefile
+@@ -2,5 +2,4 @@
+ # Makefile for the phy drivers.
+ #
+-obj-$(CONFIG_GENERIC_PHY)             += phy-core.o
+-obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO)   += phy-exynos-mipi-video.o
++obj-$(CONFIG_GENERIC_PHY)     += phy-core.o
+diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/phy-exynos-mipi-video.c
+deleted file mode 100644
+index 7e7fcd7..0000000
+--- a/drivers/phy/phy-exynos-mipi-video.c
++++ /dev/null
+@@ -1,169 +0,0 @@
+-/*
+- * Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY driver
+- *
+- * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+- * Author: Sylwester Nawrocki <s.nawrocki@samsung.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/io.h>
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-#include <linux/of.h>
+-#include <linux/of_address.h>
+-#include <linux/phy/phy.h>
+-#include <linux/platform_device.h>
+-#include <linux/spinlock.h>
+-
+-/* MIPI_PHYn_CONTROL register offset: n = 0..1 */
+-#define EXYNOS_MIPI_PHY_CONTROL(n)    ((n) * 4)
+-#define EXYNOS_MIPI_PHY_ENABLE                (1 << 0)
+-#define EXYNOS_MIPI_PHY_SRESETN               (1 << 1)
+-#define EXYNOS_MIPI_PHY_MRESETN               (1 << 2)
+-#define EXYNOS_MIPI_PHY_RESET_MASK    (3 << 1)
+-
+-enum exynos_mipi_phy_id {
+-      EXYNOS_MIPI_PHY_ID_CSIS0,
+-      EXYNOS_MIPI_PHY_ID_DSIM0,
+-      EXYNOS_MIPI_PHY_ID_CSIS1,
+-      EXYNOS_MIPI_PHY_ID_DSIM1,
+-      EXYNOS_MIPI_PHYS_NUM
+-};
+-
+-#define IS_EXYNOS_MIPI_DSIM_PHY_ID(id) \
+-      ((id) == EXYNOS_MIPI_PHY_ID_DSIM0 || (id) == EXYNOS_MIPI_PHY_ID_DSIM0)
+-
+-struct exynos_mipi_video_phy {
+-      spinlock_t slock;
+-      struct phy *phys[EXYNOS_MIPI_PHYS_NUM];
+-      void __iomem *regs;
+-};
+-
+-static int __set_phy_state(struct exynos_mipi_video_phy *state,
+-                      enum exynos_mipi_phy_id id, unsigned int on)
+-{
+-      void __iomem *addr;
+-      u32 reg, reset;
+-
+-      addr = state->regs + EXYNOS_MIPI_PHY_CONTROL(id / 2);
+-
+-      if (IS_EXYNOS_MIPI_DSIM_PHY_ID(id))
+-              reset = EXYNOS_MIPI_PHY_MRESETN;
+-      else
+-              reset = EXYNOS_MIPI_PHY_SRESETN;
+-
+-      spin_lock(&state->slock);
+-      reg = readl(addr);
+-      if (on)
+-              reg |= reset;
+-      else
+-              reg &= ~reset;
+-      writel(reg, addr);
+-
+-      /* Clear ENABLE bit only if MRESETN, SRESETN bits are not set. */
+-      if (on)
+-              reg |= EXYNOS_MIPI_PHY_ENABLE;
+-      else if (!(reg & EXYNOS_MIPI_PHY_RESET_MASK))
+-              reg &= ~EXYNOS_MIPI_PHY_ENABLE;
+-
+-      writel(reg, addr);
+-      spin_unlock(&state->slock);
+-      return 0;
+-}
+-
+-static int exynos_mipi_video_phy_power_on(struct phy *phy)
+-{
+-      struct exynos_mipi_video_phy *state = phy_get_drvdata(phy);
+-      return __set_phy_state(state, phy->id, 1);
+-}
+-
+-static int exynos_mipi_video_phy_power_off(struct phy *phy)
+-{
+-      struct exynos_mipi_video_phy *state = phy_get_drvdata(phy);
+-      return __set_phy_state(state, phy->id, 0);
+-}
+-
+-static struct phy *exynos_mipi_video_phy_xlate(struct device *dev,
+-                                      struct of_phandle_args *args)
+-{
+-      struct exynos_mipi_video_phy *state = dev_get_drvdata(dev);
+-
+-      if (WARN_ON(args->args[0] > EXYNOS_MIPI_PHYS_NUM))
+-              return ERR_PTR(-ENODEV);
+-
+-      return state->phys[args->args[0]];
+-}
+-
+-static struct phy_ops exynos_mipi_video_phy_ops = {
+-      .power_on       = exynos_mipi_video_phy_power_on,
+-      .power_off      = exynos_mipi_video_phy_power_off,
+-      .owner          = THIS_MODULE,
+-};
+-
+-static int exynos_mipi_video_phy_probe(struct platform_device *pdev)
+-{
+-      struct exynos_mipi_video_phy *state;
+-      struct device *dev = &pdev->dev;
+-      struct resource *res;
+-      struct phy_provider *phy_provider;
+-      int i;
+-
+-      state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
+-      if (!state)
+-              return -ENOMEM;
+-
+-      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-
+-      state->regs = devm_ioremap_resource(dev, res);
+-      if (IS_ERR(state->regs))
+-              return PTR_ERR(state->regs);
+-
+-      dev_set_drvdata(dev, state);
+-      spin_lock_init(&state->slock);
+-
+-      phy_provider = devm_of_phy_provider_register(dev,
+-                                      exynos_mipi_video_phy_xlate);
+-      if (IS_ERR(phy_provider))
+-              return PTR_ERR(phy_provider);
+-
+-      for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) {
+-              char label[8];
+-
+-              snprintf(label, sizeof(label), "%s.%d",
+-                              IS_EXYNOS_MIPI_DSIM_PHY_ID(i) ?
+-                              "dsim" : "csis", i / 2);
+-
+-              state->phys[i] = devm_phy_create(dev, i,
+-                              &exynos_mipi_video_phy_ops, label);
+-              if (IS_ERR(state->phys[i])) {
+-                      dev_err(dev, "failed to create PHY %s\n", label);
+-                      return PTR_ERR(state->phys[i]);
+-              }
+-              phy_set_drvdata(state->phys[i], state);
+-      }
+-
+-      return 0;
+-}
+-
+-static const struct of_device_id exynos_mipi_video_phy_of_match[] = {
+-      { .compatible = "samsung,s5pv210-mipi-video-phy" },
+-      { },
+-};
+-MODULE_DEVICE_TABLE(of, exynos_mipi_video_phy_of_match);
+-
+-static struct platform_driver exynos_mipi_video_phy_driver = {
+-      .probe  = exynos_mipi_video_phy_probe,
+-      .driver = {
+-              .of_match_table = exynos_mipi_video_phy_of_match,
+-              .name  = "exynos-mipi-video-phy",
+-              .owner = THIS_MODULE,
+-      }
+-};
+-module_platform_driver(exynos_mipi_video_phy_driver);
+-
+-MODULE_DESCRIPTION("Samsung S5P/EXYNOS SoC MIPI CSI-2/DSI PHY driver");
+-MODULE_LICENSE("GPL v2");
+-MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0754-Revert-drivers-phy-add-generic-PHY-framework.patch b/patches.tizen/0754-Revert-drivers-phy-add-generic-PHY-framework.patch
new file mode 100644 (file)
index 0000000..ee5cdd3
--- /dev/null
@@ -0,0 +1,1209 @@
+From ea4aa0003a8ee537c718e001b004dfd753edf63f Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 4 Sep 2013 11:40:06 +0200
+Subject: [PATCH 0754/1302] Revert "drivers: phy: add generic PHY framework"
+
+This reverts commit 528bac1d1f2a8bb10ebc3e56dd8f22e2d76f197f.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/phy/phy-bindings.txt       |  66 ---
+ Documentation/phy.txt                              | 129 -----
+ MAINTAINERS                                        |   7 -
+ drivers/Kconfig                                    |   2 -
+ drivers/Makefile                                   |   2 -
+ drivers/phy/Kconfig                                |  13 -
+ drivers/phy/Makefile                               |   5 -
+ drivers/phy/phy-core.c                             | 544 ---------------------
+ include/linux/phy/phy.h                            | 344 -------------
+ 9 files changed, 1112 deletions(-)
+ delete mode 100644 Documentation/devicetree/bindings/phy/phy-bindings.txt
+ delete mode 100644 Documentation/phy.txt
+ delete mode 100644 drivers/phy/Kconfig
+ delete mode 100644 drivers/phy/Makefile
+ delete mode 100644 drivers/phy/phy-core.c
+ delete mode 100644 include/linux/phy/phy.h
+
+diff --git a/Documentation/devicetree/bindings/phy/phy-bindings.txt b/Documentation/devicetree/bindings/phy/phy-bindings.txt
+deleted file mode 100644
+index 8ae844f..0000000
+--- a/Documentation/devicetree/bindings/phy/phy-bindings.txt
++++ /dev/null
+@@ -1,66 +0,0 @@
+-This document explains only the device tree data binding. For general
+-information about PHY subsystem refer to Documentation/phy.txt
+-
+-PHY device node
+-===============
+-
+-Required Properties:
+-#phy-cells:   Number of cells in a PHY specifier;  The meaning of all those
+-              cells is defined by the binding for the phy node. The PHY
+-              provider can use the values in cells to find the appropriate
+-              PHY.
+-
+-For example:
+-
+-phys: phy {
+-    compatible = "xxx";
+-    reg = <...>;
+-    .
+-    .
+-    #phy-cells = <1>;
+-    .
+-    .
+-};
+-
+-That node describes an IP block (PHY provider) that implements 2 different PHYs.
+-In order to differentiate between these 2 PHYs, an additonal specifier should be
+-given while trying to get a reference to it.
+-
+-PHY user node
+-=============
+-
+-Required Properties:
+-phys : the phandle for the PHY device (used by the PHY subsystem)
+-phy-names : the names of the PHY corresponding to the PHYs present in the
+-          *phys* phandle
+-
+-Example 1:
+-usb1: usb_otg_ss@xxx {
+-    compatible = "xxx";
+-    reg = <xxx>;
+-    .
+-    .
+-    phys = <&usb2_phy>, <&usb3_phy>;
+-    phy-names = "usb2phy", "usb3phy";
+-    .
+-    .
+-};
+-
+-This node represents a controller that uses two PHYs, one for usb2 and one for
+-usb3.
+-
+-Example 2:
+-usb2: usb_otg_ss@xxx {
+-    compatible = "xxx";
+-    reg = <xxx>;
+-    .
+-    .
+-    phys = <&phys 1>;
+-    phy-names = "usbphy";
+-    .
+-    .
+-};
+-
+-This node represents a controller that uses one of the PHYs of the PHY provider
+-device defined previously. Note that the phy handle has an additional specifier
+-"1" to differentiate between the two PHYs.
+diff --git a/Documentation/phy.txt b/Documentation/phy.txt
+deleted file mode 100644
+index 05f8fda..0000000
+--- a/Documentation/phy.txt
++++ /dev/null
+@@ -1,129 +0,0 @@
+-                          PHY SUBSYSTEM
+-                Kishon Vijay Abraham I <kishon@ti.com>
+-
+-This document explains the Generic PHY Framework along with the APIs provided,
+-and how-to-use.
+-
+-1. Introduction
+-
+-*PHY* is the abbreviation for physical layer. It is used to connect a device
+-to the physical medium e.g., the USB controller has a PHY to provide functions
+-such as serialization, de-serialization, encoding, decoding and is responsible
+-for obtaining the required data transmission rate. Note that some USB
+-controllers have PHY functionality embedded into it and others use an external
+-PHY. Other peripherals that use PHY include Wireless LAN, Ethernet,
+-SATA etc.
+-
+-The intention of creating this framework is to bring the PHY drivers spread
+-all over the Linux kernel to drivers/phy to increase code re-use and for
+-better code maintainability.
+-
+-This framework will be of use only to devices that use external PHY (PHY
+-functionality is not embedded within the controller).
+-
+-2. Registering/Unregistering the PHY provider
+-
+-PHY provider refers to an entity that implements one or more PHY instances.
+-For the simple case where the PHY provider implements only a single instance of
+-the PHY, the framework provides its own implementation of of_xlate in
+-of_phy_simple_xlate. If the PHY provider implements multiple instances, it
+-should provide its own implementation of of_xlate. of_xlate is used only for
+-dt boot case.
+-
+-struct phy_provider *__of_phy_provider_register(struct device *dev,
+-      struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+-      struct of_phandle_args *args));
+-struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
+-      struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+-      struct of_phandle_args *args))
+-
+-__of_phy_provider_register and __devm_of_phy_provider_register can be used to
+-register the phy_provider and it takes device, owner and of_xlate as
+-arguments. For the dt boot case, all PHY providers should use one of the above
+-2 APIs to register the PHY provider.
+-
+-void devm_of_phy_provider_unregister(struct device *dev,
+-      struct phy_provider *phy_provider);
+-void of_phy_provider_unregister(struct phy_provider *phy_provider);
+-
+-devm_of_phy_provider_unregister and of_phy_provider_unregister can be used to
+-unregister the PHY.
+-
+-3. Creating the PHY
+-
+-The PHY driver should create the PHY in order for other peripheral controllers
+-to make use of it. The PHY framework provides 2 APIs to create the PHY.
+-
+-struct phy *phy_create(struct device *dev, u8 id, const struct phy_ops *ops,
+-      const char *label);
+-extern struct phy *devm_phy_create(struct device *dev, u8 id,
+-        const struct phy_ops *ops, const char *label);
+-
+-The PHY drivers can use one of the above 2 APIs to create the PHY by passing
+-the device pointer, id, phy ops, label and a driver data.
+-phy_ops is a set of function pointers for performing PHY operations such as
+-init, exit, power_on and power_off. *label* is mandatory for non-dt boot case
+-and it should be unique as well.
+-
+-Inorder to dereference the private data (in phy_ops), the phy provider driver
+-can use phy_set_drvdata() after creating the PHY and use phy_get_drvdata() in
+-phy_ops to get back the private data.
+-
+-4. Getting a reference to the PHY
+-
+-Before the controller can make use of the PHY, it has to get a reference to
+-it. This framework provides the following APIs to get a reference to the PHY.
+-
+-struct phy *phy_get(struct device *dev, const char *string);
+-struct phy *devm_phy_get(struct device *dev, const char *string);
+-
+-phy_get and devm_phy_get can be used to get the PHY. In the case of dt boot,
+-the string arguments should contain the phy name as given in the dt data and
+-in the case of non-dt boot, it should contain the label of the PHY.
+-The only difference between the two APIs is that devm_phy_get associates the
+-device with the PHY using devres on successful PHY get. On driver detach,
+-release function is invoked on the the devres data and devres data is freed.
+-
+-5. Releasing a reference to the PHY
+-
+-When the controller no longer needs the PHY, it has to release the reference
+-to the PHY it has obtained using the APIs mentioned in the above section. The
+-PHY framework provides 2 APIs to release a reference to the PHY.
+-
+-void phy_put(struct phy *phy);
+-void devm_phy_put(struct device *dev, struct phy *phy);
+-
+-Both these APIs are used to release a reference to the PHY and devm_phy_put
+-destroys the devres associated with this PHY.
+-
+-6. Destroying the PHY
+-
+-When the driver that created the PHY is unloaded, it should destroy the PHY it
+-created using one of the following 2 APIs.
+-
+-void phy_destroy(struct phy *phy);
+-void devm_phy_destroy(struct device *dev, struct phy *phy);
+-
+-Both these APIs destroy the PHY and devm_phy_destroy destroys the devres
+-associated with this PHY.
+-
+-7. PM Runtime
+-
+-This subsystem is pm runtime enabled. So while creating the PHY,
+-pm_runtime_enable of the phy device created by this subsystem is called and
+-while destroying the PHY, pm_runtime_disable is called. Note that the phy
+-device created by this subsystem will be a child of the device that calls
+-phy_create (PHY provider device).
+-
+-So pm_runtime_get_sync of the phy_device created by this subsystem will invoke
+-pm_runtime_get_sync of PHY provider device because of parent-child relationship.
+-It should also be noted that phy_power_on and phy_power_off performs
+-phy_pm_runtime_get_sync and phy_pm_runtime_put respectively.
+-There are exported APIs like phy_pm_runtime_get, phy_pm_runtime_get_sync,
+-phy_pm_runtime_put, phy_pm_runtime_put_sync, phy_pm_runtime_allow and
+-phy_pm_runtime_forbid for performing PM operations.
+-
+-8. DeviceTree Binding
+-
+-The documentation for PHY dt binding can be found @
+-Documentation/devicetree/bindings/phy/phy-bindings.txt
+diff --git a/MAINTAINERS b/MAINTAINERS
+index cbc462b..f423c84 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -3536,13 +3536,6 @@ S:      Maintained
+ F:    include/asm-generic
+ F:    include/uapi/asm-generic
+-GENERIC PHY FRAMEWORK
+-M:    Kishon Vijay Abraham I <kishon@ti.com>
+-L:    linux-kernel@vger.kernel.org
+-S:    Supported
+-F:    drivers/phy/
+-F:    include/linux/phy/
+-
+ GENERIC UIO DRIVER FOR PCI DEVICES
+ M:    "Michael S. Tsirkin" <mst@redhat.com>
+ L:    kvm@vger.kernel.org
+diff --git a/drivers/Kconfig b/drivers/Kconfig
+index 2943fb6..9953a42 100644
+--- a/drivers/Kconfig
++++ b/drivers/Kconfig
+@@ -166,6 +166,4 @@ source "drivers/ipack/Kconfig"
+ source "drivers/reset/Kconfig"
+-source "drivers/phy/Kconfig"
+-
+ endmenu
+diff --git a/drivers/Makefile b/drivers/Makefile
+index 46c99a1..130abc1 100644
+--- a/drivers/Makefile
++++ b/drivers/Makefile
+@@ -8,8 +8,6 @@
+ obj-y                         += irqchip/
+ obj-y                         += bus/
+-obj-$(CONFIG_GENERIC_PHY)     += phy/
+-
+ # GPIO must come after pinctrl as gpios may need to mux pins etc
+ obj-y                         += pinctrl/
+ obj-y                         += gpio/
+diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
+deleted file mode 100644
+index 5f85909..0000000
+--- a/drivers/phy/Kconfig
++++ /dev/null
+@@ -1,13 +0,0 @@
+-#
+-# PHY
+-#
+-
+-menuconfig GENERIC_PHY
+-      tristate "PHY Subsystem"
+-      help
+-        Generic PHY support.
+-
+-        This framework is designed to provide a generic interface for PHY
+-        devices present in the kernel. This layer will have the generic
+-        API by which phy drivers can create PHY using the phy framework and
+-        phy users can obtain reference to the PHY.
+diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
+deleted file mode 100644
+index 9e9560f..0000000
+--- a/drivers/phy/Makefile
++++ /dev/null
+@@ -1,5 +0,0 @@
+-#
+-# Makefile for the phy drivers.
+-#
+-
+-obj-$(CONFIG_GENERIC_PHY)     += phy-core.o
+diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
+deleted file mode 100644
+index 6c75dc3..0000000
+--- a/drivers/phy/phy-core.c
++++ /dev/null
+@@ -1,544 +0,0 @@
+-/*
+- * phy-core.c  --  Generic Phy framework.
+- *
+- * Copyright (C) 2013 Texas Instruments
+- *
+- * Author: Kishon Vijay Abraham I <kishon@ti.com>
+- *
+- * This program is free software; you can redistribute  it and/or modify it
+- * under  the terms of  the GNU General  Public License as published by the
+- * Free Software Foundation;  either version 2 of the  License, or (at your
+- * option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/export.h>
+-#include <linux/module.h>
+-#include <linux/err.h>
+-#include <linux/device.h>
+-#include <linux/slab.h>
+-#include <linux/of.h>
+-#include <linux/phy/phy.h>
+-#include <linux/pm_runtime.h>
+-
+-static struct class *phy_class;
+-static DEFINE_MUTEX(phy_provider_mutex);
+-static LIST_HEAD(phy_provider_list);
+-
+-static void devm_phy_release(struct device *dev, void *res)
+-{
+-      struct phy *phy = *(struct phy **)res;
+-
+-      phy_put(phy);
+-}
+-
+-static void devm_phy_provider_release(struct device *dev, void *res)
+-{
+-      struct phy_provider *phy_provider = *(struct phy_provider **)res;
+-
+-      of_phy_provider_unregister(phy_provider);
+-}
+-
+-static void devm_phy_consume(struct device *dev, void *res)
+-{
+-      struct phy *phy = *(struct phy **)res;
+-
+-      phy_destroy(phy);
+-}
+-
+-static int devm_phy_match(struct device *dev, void *res, void *match_data)
+-{
+-      return res == match_data;
+-}
+-
+-static struct phy *phy_lookup(const char *phy_name)
+-{
+-      struct phy *phy;
+-      struct device *dev;
+-      struct class_dev_iter iter;
+-
+-      class_dev_iter_init(&iter, phy_class, NULL, NULL);
+-      while ((dev = class_dev_iter_next(&iter))) {
+-              phy = to_phy(dev);
+-              if (strcmp(phy->label, phy_name))
+-                      continue;
+-
+-              class_dev_iter_exit(&iter);
+-              return phy;
+-      }
+-
+-      class_dev_iter_exit(&iter);
+-      return ERR_PTR(-ENODEV);
+-}
+-
+-static struct phy_provider *of_phy_provider_lookup(struct device_node *node)
+-{
+-      struct phy_provider *phy_provider;
+-
+-      list_for_each_entry(phy_provider, &phy_provider_list, list) {
+-              if (phy_provider->dev->of_node == node)
+-                      return phy_provider;
+-      }
+-
+-      return ERR_PTR(-EPROBE_DEFER);
+-}
+-
+-/**
+- * of_phy_get() - lookup and obtain a reference to a phy by phandle
+- * @dev: device that requests this phy
+- * @index: the index of the phy
+- *
+- * Returns the phy associated with the given phandle value,
+- * after getting a refcount to it or -ENODEV if there is no such phy or
+- * -EPROBE_DEFER if there is a phandle to the phy, but the device is
+- * not yet loaded. This function uses of_xlate call back function provided
+- * while registering the phy_provider to find the phy instance.
+- */
+-static struct phy *of_phy_get(struct device *dev, int index)
+-{
+-      int ret;
+-      struct phy_provider *phy_provider;
+-      struct phy *phy = NULL;
+-      struct of_phandle_args args;
+-
+-      ret = of_parse_phandle_with_args(dev->of_node, "phys", "#phy-cells",
+-              index, &args);
+-      if (ret) {
+-              dev_dbg(dev, "failed to get phy in %s node\n",
+-                      dev->of_node->full_name);
+-              return ERR_PTR(-ENODEV);
+-      }
+-
+-      mutex_lock(&phy_provider_mutex);
+-      phy_provider = of_phy_provider_lookup(args.np);
+-      if (IS_ERR(phy_provider) || !try_module_get(phy_provider->owner)) {
+-              phy = ERR_PTR(-EPROBE_DEFER);
+-              goto err0;
+-      }
+-
+-      phy = phy_provider->of_xlate(phy_provider->dev, &args);
+-      module_put(phy_provider->owner);
+-
+-err0:
+-      mutex_unlock(&phy_provider_mutex);
+-      of_node_put(args.np);
+-
+-      return phy;
+-}
+-
+-/**
+- * phy_put() - release the PHY
+- * @phy: the phy returned by phy_get()
+- *
+- * Releases a refcount the caller received from phy_get().
+- */
+-void phy_put(struct phy *phy)
+-{
+-      if (IS_ERR(phy))
+-              return;
+-
+-      module_put(phy->ops->owner);
+-      put_device(&phy->dev);
+-}
+-EXPORT_SYMBOL_GPL(phy_put);
+-
+-/**
+- * devm_phy_put() - release the PHY
+- * @dev: device that wants to release this phy
+- * @phy: the phy returned by devm_phy_get()
+- *
+- * destroys the devres associated with this phy and invokes phy_put
+- * to release the phy.
+- */
+-void devm_phy_put(struct device *dev, struct phy *phy)
+-{
+-      int r;
+-
+-      r = devres_destroy(dev, devm_phy_release, devm_phy_match, phy);
+-      dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n");
+-}
+-EXPORT_SYMBOL_GPL(devm_phy_put);
+-
+-/**
+- * of_phy_simple_xlate() - returns the phy instance from phy provider
+- * @dev: the PHY provider device
+- * @args: of_phandle_args (not used here)
+- *
+- * Intended to be used by phy provider for the common case where #phy-cells is
+- * 0. For other cases where #phy-cells is greater than '0', the phy provider
+- * should provide a custom of_xlate function that reads the *args* and returns
+- * the appropriate phy.
+- */
+-struct phy *of_phy_simple_xlate(struct device *dev, struct of_phandle_args
+-      *args)
+-{
+-      struct phy *phy;
+-      struct class_dev_iter iter;
+-      struct device_node *node = dev->of_node;
+-
+-      class_dev_iter_init(&iter, phy_class, NULL, NULL);
+-      while ((dev = class_dev_iter_next(&iter))) {
+-              phy = to_phy(dev);
+-              if (node != phy->dev.of_node)
+-                      continue;
+-
+-              class_dev_iter_exit(&iter);
+-              return phy;
+-      }
+-
+-      class_dev_iter_exit(&iter);
+-      return ERR_PTR(-ENODEV);
+-}
+-EXPORT_SYMBOL_GPL(of_phy_simple_xlate);
+-
+-/**
+- * phy_get() - lookup and obtain a reference to a phy.
+- * @dev: device that requests this phy
+- * @string: the phy name as given in the dt data or phy device name
+- * for non-dt case
+- *
+- * Returns the phy driver, after getting a refcount to it; or
+- * -ENODEV if there is no such phy.  The caller is responsible for
+- * calling phy_put() to release that count.
+- */
+-struct phy *phy_get(struct device *dev, const char *string)
+-{
+-      int index = 0;
+-      struct phy *phy = NULL;
+-
+-      if (string == NULL) {
+-              dev_WARN(dev, "missing string\n");
+-              return ERR_PTR(-EINVAL);
+-      }
+-
+-      if (dev->of_node) {
+-              index = of_property_match_string(dev->of_node, "phy-names",
+-                      string);
+-              phy = of_phy_get(dev, index);
+-              if (IS_ERR(phy)) {
+-                      dev_WARN(dev, "unable to find phy\n");
+-                      return phy;
+-              }
+-      } else {
+-              phy = phy_lookup(string);
+-              if (IS_ERR(phy)) {
+-                      dev_WARN(dev, "unable to find phy\n");
+-                      return phy;
+-              }
+-      }
+-
+-      if (!try_module_get(phy->ops->owner))
+-              return ERR_PTR(-EPROBE_DEFER);
+-
+-      get_device(&phy->dev);
+-
+-      return phy;
+-}
+-EXPORT_SYMBOL_GPL(phy_get);
+-
+-/**
+- * devm_phy_get() - lookup and obtain a reference to a phy.
+- * @dev: device that requests this phy
+- * @string: the phy name as given in the dt data or phy device name
+- * for non-dt case
+- *
+- * Gets the phy using phy_get(), and associates a device with it using
+- * devres. On driver detach, release function is invoked on the devres data,
+- * then, devres data is freed.
+- */
+-struct phy *devm_phy_get(struct device *dev, const char *string)
+-{
+-      struct phy **ptr, *phy;
+-
+-      ptr = devres_alloc(devm_phy_release, sizeof(*ptr), GFP_KERNEL);
+-      if (!ptr)
+-              return ERR_PTR(-ENOMEM);
+-
+-      phy = phy_get(dev, string);
+-      if (!IS_ERR(phy)) {
+-              *ptr = phy;
+-              devres_add(dev, ptr);
+-      } else {
+-              devres_free(ptr);
+-      }
+-
+-      return phy;
+-}
+-EXPORT_SYMBOL_GPL(devm_phy_get);
+-
+-/**
+- * phy_create() - create a new phy
+- * @dev: device that is creating the new phy
+- * @id: id of the phy
+- * @ops: function pointers for performing phy operations
+- * @label: label given to the phy
+- *
+- * Called to create a phy using phy framework.
+- */
+-struct phy *phy_create(struct device *dev, u8 id, const struct phy_ops *ops,
+-      const char *label)
+-{
+-      int ret;
+-      struct phy *phy;
+-
+-      if (!dev) {
+-              dev_WARN(dev, "no device provided for PHY\n");
+-              ret = -EINVAL;
+-              goto err0;
+-      }
+-
+-      phy = kzalloc(sizeof(*phy), GFP_KERNEL);
+-      if (!phy) {
+-              ret = -ENOMEM;
+-              goto err0;
+-      }
+-
+-      device_initialize(&phy->dev);
+-      mutex_init(&phy->mutex);
+-
+-      phy->dev.class = phy_class;
+-      phy->dev.parent = dev;
+-      phy->dev.of_node = dev->of_node;
+-      phy->id = id;
+-      phy->ops = ops;
+-      phy->label = kstrdup(label, GFP_KERNEL);
+-
+-      ret = dev_set_name(&phy->dev, "%s.%d", dev_name(dev), id);
+-      if (ret)
+-              goto err1;
+-
+-      ret = device_add(&phy->dev);
+-      if (ret)
+-              goto err1;
+-
+-      if (pm_runtime_enabled(dev)) {
+-              pm_runtime_enable(&phy->dev);
+-              pm_runtime_no_callbacks(&phy->dev);
+-      }
+-
+-      return phy;
+-
+-err1:
+-      put_device(&phy->dev);
+-      kfree(phy->label);
+-      kfree(phy);
+-
+-err0:
+-      return ERR_PTR(ret);
+-}
+-EXPORT_SYMBOL_GPL(phy_create);
+-
+-/**
+- * devm_phy_create() - create a new phy
+- * @dev: device that is creating the new phy
+- * @id: id of the phy
+- * @ops: function pointers for performing phy operations
+- * @label: label given to the phy
+- *
+- * Creates a new PHY device adding it to the PHY class.
+- * While at that, it also associates the device with the phy using devres.
+- * On driver detach, release function is invoked on the devres data,
+- * then, devres data is freed.
+- */
+-struct phy *devm_phy_create(struct device *dev, u8 id,
+-      const struct phy_ops *ops, const char *label)
+-{
+-      struct phy **ptr, *phy;
+-
+-      ptr = devres_alloc(devm_phy_consume, sizeof(*ptr), GFP_KERNEL);
+-      if (!ptr)
+-              return ERR_PTR(-ENOMEM);
+-
+-      phy = phy_create(dev, id, ops, label);
+-      if (!IS_ERR(phy)) {
+-              *ptr = phy;
+-              devres_add(dev, ptr);
+-      } else {
+-              devres_free(ptr);
+-      }
+-
+-      return phy;
+-}
+-EXPORT_SYMBOL_GPL(devm_phy_create);
+-
+-/**
+- * phy_destroy() - destroy the phy
+- * @phy: the phy to be destroyed
+- *
+- * Called to destroy the phy.
+- */
+-void phy_destroy(struct phy *phy)
+-{
+-      pm_runtime_disable(&phy->dev);
+-      device_unregister(&phy->dev);
+-}
+-EXPORT_SYMBOL_GPL(phy_destroy);
+-
+-/**
+- * devm_phy_destroy() - destroy the PHY
+- * @dev: device that wants to release this phy
+- * @phy: the phy returned by devm_phy_get()
+- *
+- * destroys the devres associated with this phy and invokes phy_destroy
+- * to destroy the phy.
+- */
+-void devm_phy_destroy(struct device *dev, struct phy *phy)
+-{
+-      int r;
+-
+-      r = devres_destroy(dev, devm_phy_consume, devm_phy_match, phy);
+-      dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n");
+-}
+-EXPORT_SYMBOL_GPL(devm_phy_destroy);
+-
+-/**
+- * __of_phy_provider_register() - create/register phy provider with the framework
+- * @dev: struct device of the phy provider
+- * @owner: the module owner containing of_xlate
+- * @of_xlate: function pointer to obtain phy instance from phy provider
+- *
+- * Creates struct phy_provider from dev and of_xlate function pointer.
+- * This is used in the case of dt boot for finding the phy instance from
+- * phy provider.
+- */
+-struct phy_provider *__of_phy_provider_register(struct device *dev,
+-      struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+-      struct of_phandle_args *args))
+-{
+-      struct phy_provider *phy_provider;
+-
+-      phy_provider = kzalloc(sizeof(*phy_provider), GFP_KERNEL);
+-      if (!phy_provider)
+-              return ERR_PTR(-ENOMEM);
+-
+-      phy_provider->dev = dev;
+-      phy_provider->owner = owner;
+-      phy_provider->of_xlate = of_xlate;
+-
+-      mutex_lock(&phy_provider_mutex);
+-      list_add_tail(&phy_provider->list, &phy_provider_list);
+-      mutex_unlock(&phy_provider_mutex);
+-
+-      return phy_provider;
+-}
+-EXPORT_SYMBOL_GPL(__of_phy_provider_register);
+-
+-/**
+- * __devm_of_phy_provider_register() - create/register phy provider with the
+- * framework
+- * @dev: struct device of the phy provider
+- * @owner: the module owner containing of_xlate
+- * @of_xlate: function pointer to obtain phy instance from phy provider
+- *
+- * Creates struct phy_provider from dev and of_xlate function pointer.
+- * This is used in the case of dt boot for finding the phy instance from
+- * phy provider. While at that, it also associates the device with the
+- * phy provider using devres. On driver detach, release function is invoked
+- * on the devres data, then, devres data is freed.
+- */
+-struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
+-      struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+-      struct of_phandle_args *args))
+-{
+-      struct phy_provider **ptr, *phy_provider;
+-
+-      ptr = devres_alloc(devm_phy_provider_release, sizeof(*ptr), GFP_KERNEL);
+-      if (!ptr)
+-              return ERR_PTR(-ENOMEM);
+-
+-      phy_provider = __of_phy_provider_register(dev, owner, of_xlate);
+-      if (!IS_ERR(phy_provider)) {
+-              *ptr = phy_provider;
+-              devres_add(dev, ptr);
+-      } else {
+-              devres_free(ptr);
+-      }
+-
+-      return phy_provider;
+-}
+-EXPORT_SYMBOL_GPL(__devm_of_phy_provider_register);
+-
+-/**
+- * of_phy_provider_unregister() - unregister phy provider from the framework
+- * @phy_provider: phy provider returned by of_phy_provider_register()
+- *
+- * Removes the phy_provider created using of_phy_provider_register().
+- */
+-void of_phy_provider_unregister(struct phy_provider *phy_provider)
+-{
+-      if (IS_ERR(phy_provider))
+-              return;
+-
+-      mutex_lock(&phy_provider_mutex);
+-      list_del(&phy_provider->list);
+-      kfree(phy_provider);
+-      mutex_unlock(&phy_provider_mutex);
+-}
+-EXPORT_SYMBOL_GPL(of_phy_provider_unregister);
+-
+-/**
+- * devm_of_phy_provider_unregister() - remove phy provider from the framework
+- * @dev: struct device of the phy provider
+- *
+- * destroys the devres associated with this phy provider and invokes
+- * of_phy_provider_unregister to unregister the phy provider.
+- */
+-void devm_of_phy_provider_unregister(struct device *dev,
+-      struct phy_provider *phy_provider) {
+-      int r;
+-
+-      r = devres_destroy(dev, devm_phy_provider_release, devm_phy_match,
+-              phy_provider);
+-      dev_WARN_ONCE(dev, r, "couldn't find PHY provider device resource\n");
+-}
+-EXPORT_SYMBOL_GPL(devm_of_phy_provider_unregister);
+-
+-/**
+- * phy_release() - release the phy
+- * @dev: the dev member within phy
+- *
+- * When the last reference to the device is removed, it is called
+- * from the embedded kobject as release method.
+- */
+-static void phy_release(struct device *dev)
+-{
+-      struct phy *phy;
+-
+-      phy = to_phy(dev);
+-      dev_vdbg(dev, "releasing '%s'\n", dev_name(dev));
+-      kfree(phy->label);
+-      kfree(phy);
+-}
+-
+-static int __init phy_core_init(void)
+-{
+-      phy_class = class_create(THIS_MODULE, "phy");
+-      if (IS_ERR(phy_class)) {
+-              pr_err("failed to create phy class --> %ld\n",
+-                      PTR_ERR(phy_class));
+-              return PTR_ERR(phy_class);
+-      }
+-
+-      phy_class->dev_release = phy_release;
+-
+-      return 0;
+-}
+-module_init(phy_core_init);
+-
+-static void __exit phy_core_exit(void)
+-{
+-      class_destroy(phy_class);
+-}
+-module_exit(phy_core_exit);
+-
+-MODULE_DESCRIPTION("Generic PHY Framework");
+-MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
+-MODULE_LICENSE("GPL v2");
+diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
+deleted file mode 100644
+index 9351a16..0000000
+--- a/include/linux/phy/phy.h
++++ /dev/null
+@@ -1,344 +0,0 @@
+-/*
+- * phy.h -- generic phy header file
+- *
+- * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * Author: Kishon Vijay Abraham I <kishon@ti.com>
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU General Public License for more details.
+- *
+- */
+-
+-#ifndef __DRIVERS_PHY_H
+-#define __DRIVERS_PHY_H
+-
+-#include <linux/err.h>
+-#include <linux/of.h>
+-#include <linux/device.h>
+-#include <linux/pm_runtime.h>
+-
+-struct phy;
+-
+-/**
+- * struct phy_ops - set of function pointers for performing phy operations
+- * @init: operation to be performed for initializing phy
+- * @exit: operation to be performed while exiting
+- * @power_on: powering on the phy
+- * @power_off: powering off the phy
+- * @owner: the module owner containing the ops
+- */
+-struct phy_ops {
+-      int     (*init)(struct phy *phy);
+-      int     (*exit)(struct phy *phy);
+-      int     (*power_on)(struct phy *phy);
+-      int     (*power_off)(struct phy *phy);
+-      struct module *owner;
+-};
+-
+-/**
+- * struct phy - represents the phy device
+- * @dev: phy device
+- * @id: id of the phy
+- * @ops: function pointers for performing phy operations
+- * @label: label given to the phy
+- * @mutex: mutex to protect phy_ops
+- * @init_count: used to protect when the PHY is used by multiple consumers
+- * @power_count: used to protect when the PHY is used by multiple consumers
+- */
+-struct phy {
+-      struct device           dev;
+-      int                     id;
+-      const struct phy_ops    *ops;
+-      const char              *label;
+-      struct mutex            mutex;
+-      int                     init_count;
+-      int                     power_count;
+-};
+-
+-/**
+- * struct phy_provider - represents the phy provider
+- * @dev: phy provider device
+- * @owner: the module owner having of_xlate
+- * @of_xlate: function pointer to obtain phy instance from phy pointer
+- * @list: to maintain a linked list of PHY providers
+- */
+-struct phy_provider {
+-      struct device           *dev;
+-      struct module           *owner;
+-      struct list_head        list;
+-      struct phy * (*of_xlate)(struct device *dev,
+-              struct of_phandle_args *args);
+-};
+-
+-#define       to_phy(dev)     (container_of((dev), struct phy, dev))
+-
+-#define       of_phy_provider_register(dev, xlate)    \
+-      __of_phy_provider_register((dev), THIS_MODULE, (xlate))
+-
+-#define       devm_of_phy_provider_register(dev, xlate)       \
+-      __of_phy_provider_register((dev), THIS_MODULE, (xlate))
+-
+-static inline void phy_set_drvdata(struct phy *phy, void *data)
+-{
+-      dev_set_drvdata(&phy->dev, data);
+-}
+-
+-static inline void *phy_get_drvdata(struct phy *phy)
+-{
+-      return dev_get_drvdata(&phy->dev);
+-}
+-
+-#if IS_ENABLED(CONFIG_GENERIC_PHY)
+-extern struct phy *phy_get(struct device *dev, const char *string);
+-extern struct phy *devm_phy_get(struct device *dev, const char *string);
+-extern void phy_put(struct phy *phy);
+-extern void devm_phy_put(struct device *dev, struct phy *phy);
+-extern struct phy *of_phy_simple_xlate(struct device *dev,
+-      struct of_phandle_args *args);
+-extern struct phy *phy_create(struct device *dev, u8 id,
+-      const struct phy_ops *ops, const char *label);
+-extern struct phy *devm_phy_create(struct device *dev, u8 id,
+-      const struct phy_ops *ops, const char *label);
+-extern void phy_destroy(struct phy *phy);
+-extern void devm_phy_destroy(struct device *dev, struct phy *phy);
+-extern struct phy_provider *__of_phy_provider_register(struct device *dev,
+-      struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+-      struct of_phandle_args *args));
+-extern struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
+-      struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+-      struct of_phandle_args *args));
+-extern void of_phy_provider_unregister(struct phy_provider *phy_provider);
+-extern void devm_of_phy_provider_unregister(struct device *dev,
+-      struct phy_provider *phy_provider);
+-#else
+-static inline struct phy *phy_get(struct device *dev, const char *string)
+-{
+-      return ERR_PTR(-ENOSYS);
+-}
+-
+-static inline struct phy *devm_phy_get(struct device *dev, const char *string)
+-{
+-      return ERR_PTR(-ENOSYS);
+-}
+-
+-static inline void phy_put(struct phy *phy)
+-{
+-}
+-
+-static inline void devm_phy_put(struct device *dev, struct phy *phy)
+-{
+-}
+-
+-static inline struct phy *of_phy_simple_xlate(struct device *dev,
+-      struct of_phandle_args *args)
+-{
+-      return ERR_PTR(-ENOSYS);
+-}
+-
+-static inline struct phy *phy_create(struct device *dev, u8 id,
+-      const struct phy_ops *ops, const char *label)
+-{
+-      return ERR_PTR(-ENOSYS);
+-}
+-
+-static inline struct phy *devm_phy_create(struct device *dev, u8 id,
+-      const struct phy_ops *ops, const char *label)
+-{
+-      return ERR_PTR(-ENOSYS);
+-}
+-
+-static inline void phy_destroy(struct phy *phy)
+-{
+-}
+-
+-static inline void devm_phy_destroy(struct device *dev, struct phy *phy)
+-{
+-}
+-
+-static inline struct phy_provider *__of_phy_provider_register(
+-      struct device *dev, struct module *owner, struct phy * (*of_xlate)(
+-      struct device *dev, struct of_phandle_args *args))
+-{
+-      return ERR_PTR(-ENOSYS);
+-}
+-
+-static inline struct phy_provider *__devm_of_phy_provider_register(struct device
+-      *dev, struct module *owner, struct phy * (*of_xlate)(struct device *dev,
+-      struct of_phandle_args *args))
+-{
+-      return ERR_PTR(-ENOSYS);
+-}
+-
+-static inline void of_phy_provider_unregister(struct phy_provider *phy_provider)
+-{
+-}
+-
+-static inline void devm_of_phy_provider_unregister(struct device *dev,
+-      struct phy_provider *phy_provider)
+-{
+-}
+-#endif
+-
+-static inline int phy_pm_runtime_get(struct phy *phy)
+-{
+-      if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
+-              return -EINVAL;
+-
+-      if (!pm_runtime_enabled(&phy->dev))
+-              return -ENOTSUPP;
+-
+-      return pm_runtime_get(&phy->dev);
+-}
+-
+-static inline int phy_pm_runtime_get_sync(struct phy *phy)
+-{
+-      if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
+-              return -EINVAL;
+-
+-      if (!pm_runtime_enabled(&phy->dev))
+-              return -ENOTSUPP;
+-
+-      return pm_runtime_get_sync(&phy->dev);
+-}
+-
+-static inline int phy_pm_runtime_put(struct phy *phy)
+-{
+-      if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
+-              return -EINVAL;
+-
+-      if (!pm_runtime_enabled(&phy->dev))
+-              return -ENOTSUPP;
+-
+-      return pm_runtime_put(&phy->dev);
+-}
+-
+-static inline int phy_pm_runtime_put_sync(struct phy *phy)
+-{
+-      if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
+-              return -EINVAL;
+-
+-      if (!pm_runtime_enabled(&phy->dev))
+-              return -ENOTSUPP;
+-
+-      return pm_runtime_put_sync(&phy->dev);
+-}
+-
+-static inline void phy_pm_runtime_allow(struct phy *phy)
+-{
+-      if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
+-              return;
+-
+-      if (!pm_runtime_enabled(&phy->dev))
+-              return;
+-
+-      pm_runtime_allow(&phy->dev);
+-}
+-
+-static inline void phy_pm_runtime_forbid(struct phy *phy)
+-{
+-      if (WARN(IS_ERR(phy), "Invalid PHY reference\n"))
+-              return;
+-
+-      if (!pm_runtime_enabled(&phy->dev))
+-              return;
+-
+-      pm_runtime_forbid(&phy->dev);
+-}
+-
+-static inline int phy_init(struct phy *phy)
+-{
+-      int ret;
+-
+-      ret = phy_pm_runtime_get_sync(phy);
+-      if (ret < 0 && ret != -ENOTSUPP)
+-              return ret;
+-
+-      mutex_lock(&phy->mutex);
+-      if (phy->init_count++ == 0 && phy->ops->init) {
+-              ret = phy->ops->init(phy);
+-              if (ret < 0) {
+-                      dev_err(&phy->dev, "phy init failed --> %d\n", ret);
+-                      goto out;
+-              }
+-      }
+-
+-out:
+-      mutex_unlock(&phy->mutex);
+-      phy_pm_runtime_put(phy);
+-      return ret;
+-}
+-
+-static inline int phy_exit(struct phy *phy)
+-{
+-      int ret;
+-
+-      ret = phy_pm_runtime_get_sync(phy);
+-      if (ret < 0 && ret != -ENOTSUPP)
+-              return ret;
+-
+-      mutex_lock(&phy->mutex);
+-      if (--phy->init_count == 0 && phy->ops->exit) {
+-              ret = phy->ops->exit(phy);
+-              if (ret < 0) {
+-                      dev_err(&phy->dev, "phy exit failed --> %d\n", ret);
+-                      goto out;
+-              }
+-      }
+-
+-out:
+-      mutex_unlock(&phy->mutex);
+-      phy_pm_runtime_put(phy);
+-      return ret;
+-}
+-
+-static inline int phy_power_on(struct phy *phy)
+-{
+-      int ret = -ENOTSUPP;
+-
+-      ret = phy_pm_runtime_get_sync(phy);
+-      if (ret < 0 && ret != -ENOTSUPP)
+-              return ret;
+-
+-      mutex_lock(&phy->mutex);
+-      if (phy->power_count++ == 0 && phy->ops->power_on) {
+-              ret = phy->ops->power_on(phy);
+-              if (ret < 0) {
+-                      dev_err(&phy->dev, "phy poweron failed --> %d\n", ret);
+-                      goto out;
+-              }
+-      }
+-
+-out:
+-      mutex_unlock(&phy->mutex);
+-
+-      return ret;
+-}
+-
+-static inline int phy_power_off(struct phy *phy)
+-{
+-      int ret = -ENOTSUPP;
+-
+-      mutex_lock(&phy->mutex);
+-      if (--phy->power_count == 0 && phy->ops->power_off) {
+-              ret =  phy->ops->power_off(phy);
+-              if (ret < 0) {
+-                      dev_err(&phy->dev, "phy poweroff failed --> %d\n", ret);
+-                      goto out;
+-              }
+-      }
+-
+-out:
+-      mutex_unlock(&phy->mutex);
+-      phy_pm_runtime_put(phy);
+-
+-      return ret;
+-}
+-
+-#endif /* __DRIVERS_PHY_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0755-drivers-phy-add-generic-PHY-framework.patch b/patches.tizen/0755-drivers-phy-add-generic-PHY-framework.patch
new file mode 100644 (file)
index 0000000..426c712
--- /dev/null
@@ -0,0 +1,1346 @@
+From 3a7c9a3e3c7e155e1a4da0052a21ddf2bead0166 Mon Sep 17 00:00:00 2001
+From: Kishon Vijay Abraham I <kishon@ti.com>
+Date: Tue, 13 Aug 2013 16:49:01 +0530
+Subject: [PATCH 0755/1302] drivers: phy: add generic PHY framework
+
+The PHY framework provides a set of APIs for the PHY drivers to
+create/destroy a PHY and APIs for the PHY users to obtain a reference to the
+PHY with or without using phandle. For dt-boot, the PHY drivers should
+also register *PHY provider* with the framework.
+
+PHY drivers should create the PHY by passing id and ops like init, exit,
+power_on and power_off. This framework is also pm runtime enabled.
+
+The documentation for the generic PHY framework is added in
+Documentation/phy.txt and the documentation for dt binding can be found at
+Documentation/devicetree/bindings/phy/phy-bindings.txt
+
+Cc: Tomasz Figa <t.figa@samsung.com>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+Acked-by: Felipe Balbi <balbi@ti.com>
+Tested-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/phy/phy-bindings.txt       |  66 ++
+ Documentation/phy.txt                              | 166 +++++
+ MAINTAINERS                                        |   8 +
+ drivers/Kconfig                                    |   2 +
+ drivers/Makefile                                   |   2 +
+ drivers/phy/Kconfig                                |  18 +
+ drivers/phy/Makefile                               |   5 +
+ drivers/phy/phy-core.c                             | 698 +++++++++++++++++++++
+ include/linux/phy/phy.h                            | 270 ++++++++
+ 9 files changed, 1235 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/phy/phy-bindings.txt
+ create mode 100644 Documentation/phy.txt
+ create mode 100644 drivers/phy/Kconfig
+ create mode 100644 drivers/phy/Makefile
+ create mode 100644 drivers/phy/phy-core.c
+ create mode 100644 include/linux/phy/phy.h
+
+diff --git a/Documentation/devicetree/bindings/phy/phy-bindings.txt b/Documentation/devicetree/bindings/phy/phy-bindings.txt
+new file mode 100644
+index 0000000..8ae844f
+--- /dev/null
++++ b/Documentation/devicetree/bindings/phy/phy-bindings.txt
+@@ -0,0 +1,66 @@
++This document explains only the device tree data binding. For general
++information about PHY subsystem refer to Documentation/phy.txt
++
++PHY device node
++===============
++
++Required Properties:
++#phy-cells:   Number of cells in a PHY specifier;  The meaning of all those
++              cells is defined by the binding for the phy node. The PHY
++              provider can use the values in cells to find the appropriate
++              PHY.
++
++For example:
++
++phys: phy {
++    compatible = "xxx";
++    reg = <...>;
++    .
++    .
++    #phy-cells = <1>;
++    .
++    .
++};
++
++That node describes an IP block (PHY provider) that implements 2 different PHYs.
++In order to differentiate between these 2 PHYs, an additonal specifier should be
++given while trying to get a reference to it.
++
++PHY user node
++=============
++
++Required Properties:
++phys : the phandle for the PHY device (used by the PHY subsystem)
++phy-names : the names of the PHY corresponding to the PHYs present in the
++          *phys* phandle
++
++Example 1:
++usb1: usb_otg_ss@xxx {
++    compatible = "xxx";
++    reg = <xxx>;
++    .
++    .
++    phys = <&usb2_phy>, <&usb3_phy>;
++    phy-names = "usb2phy", "usb3phy";
++    .
++    .
++};
++
++This node represents a controller that uses two PHYs, one for usb2 and one for
++usb3.
++
++Example 2:
++usb2: usb_otg_ss@xxx {
++    compatible = "xxx";
++    reg = <xxx>;
++    .
++    .
++    phys = <&phys 1>;
++    phy-names = "usbphy";
++    .
++    .
++};
++
++This node represents a controller that uses one of the PHYs of the PHY provider
++device defined previously. Note that the phy handle has an additional specifier
++"1" to differentiate between the two PHYs.
+diff --git a/Documentation/phy.txt b/Documentation/phy.txt
+new file mode 100644
+index 0000000..0103e4b
+--- /dev/null
++++ b/Documentation/phy.txt
+@@ -0,0 +1,166 @@
++                          PHY SUBSYSTEM
++                Kishon Vijay Abraham I <kishon@ti.com>
++
++This document explains the Generic PHY Framework along with the APIs provided,
++and how-to-use.
++
++1. Introduction
++
++*PHY* is the abbreviation for physical layer. It is used to connect a device
++to the physical medium e.g., the USB controller has a PHY to provide functions
++such as serialization, de-serialization, encoding, decoding and is responsible
++for obtaining the required data transmission rate. Note that some USB
++controllers have PHY functionality embedded into it and others use an external
++PHY. Other peripherals that use PHY include Wireless LAN, Ethernet,
++SATA etc.
++
++The intention of creating this framework is to bring the PHY drivers spread
++all over the Linux kernel to drivers/phy to increase code re-use and for
++better code maintainability.
++
++This framework will be of use only to devices that use external PHY (PHY
++functionality is not embedded within the controller).
++
++2. Registering/Unregistering the PHY provider
++
++PHY provider refers to an entity that implements one or more PHY instances.
++For the simple case where the PHY provider implements only a single instance of
++the PHY, the framework provides its own implementation of of_xlate in
++of_phy_simple_xlate. If the PHY provider implements multiple instances, it
++should provide its own implementation of of_xlate. of_xlate is used only for
++dt boot case.
++
++#define of_phy_provider_register(dev, xlate)    \
++        __of_phy_provider_register((dev), THIS_MODULE, (xlate))
++
++#define devm_of_phy_provider_register(dev, xlate)       \
++        __devm_of_phy_provider_register((dev), THIS_MODULE, (xlate))
++
++of_phy_provider_register and devm_of_phy_provider_register macros can be used to
++register the phy_provider and it takes device and of_xlate as
++arguments. For the dt boot case, all PHY providers should use one of the above
++2 macros to register the PHY provider.
++
++void devm_of_phy_provider_unregister(struct device *dev,
++      struct phy_provider *phy_provider);
++void of_phy_provider_unregister(struct phy_provider *phy_provider);
++
++devm_of_phy_provider_unregister and of_phy_provider_unregister can be used to
++unregister the PHY.
++
++3. Creating the PHY
++
++The PHY driver should create the PHY in order for other peripheral controllers
++to make use of it. The PHY framework provides 2 APIs to create the PHY.
++
++struct phy *phy_create(struct device *dev, const struct phy_ops *ops,
++        struct phy_init_data *init_data);
++struct phy *devm_phy_create(struct device *dev, const struct phy_ops *ops,
++      struct phy_init_data *init_data);
++
++The PHY drivers can use one of the above 2 APIs to create the PHY by passing
++the device pointer, phy ops and init_data.
++phy_ops is a set of function pointers for performing PHY operations such as
++init, exit, power_on and power_off. *init_data* is mandatory to get a reference
++to the PHY in the case of non-dt boot. See section *Board File Initialization*
++on how init_data should be used.
++
++Inorder to dereference the private data (in phy_ops), the phy provider driver
++can use phy_set_drvdata() after creating the PHY and use phy_get_drvdata() in
++phy_ops to get back the private data.
++
++4. Getting a reference to the PHY
++
++Before the controller can make use of the PHY, it has to get a reference to
++it. This framework provides the following APIs to get a reference to the PHY.
++
++struct phy *phy_get(struct device *dev, const char *string);
++struct phy *devm_phy_get(struct device *dev, const char *string);
++
++phy_get and devm_phy_get can be used to get the PHY. In the case of dt boot,
++the string arguments should contain the phy name as given in the dt data and
++in the case of non-dt boot, it should contain the label of the PHY.
++The only difference between the two APIs is that devm_phy_get associates the
++device with the PHY using devres on successful PHY get. On driver detach,
++release function is invoked on the the devres data and devres data is freed.
++
++5. Releasing a reference to the PHY
++
++When the controller no longer needs the PHY, it has to release the reference
++to the PHY it has obtained using the APIs mentioned in the above section. The
++PHY framework provides 2 APIs to release a reference to the PHY.
++
++void phy_put(struct phy *phy);
++void devm_phy_put(struct device *dev, struct phy *phy);
++
++Both these APIs are used to release a reference to the PHY and devm_phy_put
++destroys the devres associated with this PHY.
++
++6. Destroying the PHY
++
++When the driver that created the PHY is unloaded, it should destroy the PHY it
++created using one of the following 2 APIs.
++
++void phy_destroy(struct phy *phy);
++void devm_phy_destroy(struct device *dev, struct phy *phy);
++
++Both these APIs destroy the PHY and devm_phy_destroy destroys the devres
++associated with this PHY.
++
++7. PM Runtime
++
++This subsystem is pm runtime enabled. So while creating the PHY,
++pm_runtime_enable of the phy device created by this subsystem is called and
++while destroying the PHY, pm_runtime_disable is called. Note that the phy
++device created by this subsystem will be a child of the device that calls
++phy_create (PHY provider device).
++
++So pm_runtime_get_sync of the phy_device created by this subsystem will invoke
++pm_runtime_get_sync of PHY provider device because of parent-child relationship.
++It should also be noted that phy_power_on and phy_power_off performs
++phy_pm_runtime_get_sync and phy_pm_runtime_put respectively.
++There are exported APIs like phy_pm_runtime_get, phy_pm_runtime_get_sync,
++phy_pm_runtime_put, phy_pm_runtime_put_sync, phy_pm_runtime_allow and
++phy_pm_runtime_forbid for performing PM operations.
++
++8. Board File Initialization
++
++Certain board file initialization is necessary in order to get a reference
++to the PHY in the case of non-dt boot.
++Say we have a single device that implements 3 PHYs that of USB, SATA and PCIe,
++then in the board file the following initialization should be done.
++
++struct phy_consumer consumers[] = {
++      PHY_CONSUMER("dwc3.0", "usb"),
++      PHY_CONSUMER("pcie.0", "pcie"),
++      PHY_CONSUMER("sata.0", "sata"),
++};
++PHY_CONSUMER takes 2 parameters, first is the device name of the controller
++(PHY consumer) and second is the port name.
++
++struct phy_init_data init_data = {
++      .consumers = consumers,
++      .num_consumers = ARRAY_SIZE(consumers),
++};
++
++static const struct platform_device pipe3_phy_dev = {
++      .name = "pipe3-phy",
++      .id = -1,
++      .dev = {
++              .platform_data = {
++                      .init_data = &init_data,
++              },
++      },
++};
++
++then, while doing phy_create, the PHY driver should pass this init_data
++      phy_create(dev, ops, pdata->init_data);
++
++and the controller driver (phy consumer) should pass the port name along with
++the device to get a reference to the PHY
++      phy_get(dev, "pcie");
++
++9. DeviceTree Binding
++
++The documentation for PHY dt binding can be found @
++Documentation/devicetree/bindings/phy/phy-bindings.txt
+diff --git a/MAINTAINERS b/MAINTAINERS
+index f423c84..f55533c 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -3536,6 +3536,14 @@ S:      Maintained
+ F:    include/asm-generic
+ F:    include/uapi/asm-generic
++GENERIC PHY FRAMEWORK
++M:    Kishon Vijay Abraham I <kishon@ti.com>
++L:    linux-kernel@vger.kernel.org
++T:    git git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux-phy.git
++S:    Supported
++F:    drivers/phy/
++F:    include/linux/phy/
++
+ GENERIC UIO DRIVER FOR PCI DEVICES
+ M:    "Michael S. Tsirkin" <mst@redhat.com>
+ L:    kvm@vger.kernel.org
+diff --git a/drivers/Kconfig b/drivers/Kconfig
+index 9953a42..2943fb6 100644
+--- a/drivers/Kconfig
++++ b/drivers/Kconfig
+@@ -166,4 +166,6 @@ source "drivers/ipack/Kconfig"
+ source "drivers/reset/Kconfig"
++source "drivers/phy/Kconfig"
++
+ endmenu
+diff --git a/drivers/Makefile b/drivers/Makefile
+index 130abc1..46c99a1 100644
+--- a/drivers/Makefile
++++ b/drivers/Makefile
+@@ -8,6 +8,8 @@
+ obj-y                         += irqchip/
+ obj-y                         += bus/
++obj-$(CONFIG_GENERIC_PHY)     += phy/
++
+ # GPIO must come after pinctrl as gpios may need to mux pins etc
+ obj-y                         += pinctrl/
+ obj-y                         += gpio/
+diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
+new file mode 100644
+index 0000000..349bef2
+--- /dev/null
++++ b/drivers/phy/Kconfig
+@@ -0,0 +1,18 @@
++#
++# PHY
++#
++
++menu "PHY Subsystem"
++
++config GENERIC_PHY
++      tristate "PHY Core"
++      help
++        Generic PHY support.
++
++        This framework is designed to provide a generic interface for PHY
++        devices present in the kernel. This layer will have the generic
++        API by which phy drivers can create PHY using the phy framework and
++        phy users can obtain reference to the PHY. All the users of this
++        framework should select this config.
++
++endmenu
+diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
+new file mode 100644
+index 0000000..9e9560f
+--- /dev/null
++++ b/drivers/phy/Makefile
+@@ -0,0 +1,5 @@
++#
++# Makefile for the phy drivers.
++#
++
++obj-$(CONFIG_GENERIC_PHY)     += phy-core.o
+diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
+new file mode 100644
+index 0000000..03cf8fb
+--- /dev/null
++++ b/drivers/phy/phy-core.c
+@@ -0,0 +1,698 @@
++/*
++ * phy-core.c  --  Generic Phy framework.
++ *
++ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
++ *
++ * Author: Kishon Vijay Abraham I <kishon@ti.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/export.h>
++#include <linux/module.h>
++#include <linux/err.h>
++#include <linux/device.h>
++#include <linux/slab.h>
++#include <linux/of.h>
++#include <linux/phy/phy.h>
++#include <linux/idr.h>
++#include <linux/pm_runtime.h>
++
++static struct class *phy_class;
++static DEFINE_MUTEX(phy_provider_mutex);
++static LIST_HEAD(phy_provider_list);
++static DEFINE_IDA(phy_ida);
++
++static void devm_phy_release(struct device *dev, void *res)
++{
++      struct phy *phy = *(struct phy **)res;
++
++      phy_put(phy);
++}
++
++static void devm_phy_provider_release(struct device *dev, void *res)
++{
++      struct phy_provider *phy_provider = *(struct phy_provider **)res;
++
++      of_phy_provider_unregister(phy_provider);
++}
++
++static void devm_phy_consume(struct device *dev, void *res)
++{
++      struct phy *phy = *(struct phy **)res;
++
++      phy_destroy(phy);
++}
++
++static int devm_phy_match(struct device *dev, void *res, void *match_data)
++{
++      return res == match_data;
++}
++
++static struct phy *phy_lookup(struct device *device, const char *port)
++{
++      unsigned int count;
++      struct phy *phy;
++      struct device *dev;
++      struct phy_consumer *consumers;
++      struct class_dev_iter iter;
++
++      class_dev_iter_init(&iter, phy_class, NULL, NULL);
++      while ((dev = class_dev_iter_next(&iter))) {
++              phy = to_phy(dev);
++              count = phy->init_data->num_consumers;
++              consumers = phy->init_data->consumers;
++              while (count--) {
++                      if (!strcmp(consumers->dev_name, dev_name(device)) &&
++                                      !strcmp(consumers->port, port)) {
++                              class_dev_iter_exit(&iter);
++                              return phy;
++                      }
++                      consumers++;
++              }
++      }
++
++      class_dev_iter_exit(&iter);
++      return ERR_PTR(-ENODEV);
++}
++
++static struct phy_provider *of_phy_provider_lookup(struct device_node *node)
++{
++      struct phy_provider *phy_provider;
++
++      list_for_each_entry(phy_provider, &phy_provider_list, list) {
++              if (phy_provider->dev->of_node == node)
++                      return phy_provider;
++      }
++
++      return ERR_PTR(-EPROBE_DEFER);
++}
++
++int phy_pm_runtime_get(struct phy *phy)
++{
++      if (!pm_runtime_enabled(&phy->dev))
++              return -ENOTSUPP;
++
++      return pm_runtime_get(&phy->dev);
++}
++EXPORT_SYMBOL_GPL(phy_pm_runtime_get);
++
++int phy_pm_runtime_get_sync(struct phy *phy)
++{
++      if (!pm_runtime_enabled(&phy->dev))
++              return -ENOTSUPP;
++
++      return pm_runtime_get_sync(&phy->dev);
++}
++EXPORT_SYMBOL_GPL(phy_pm_runtime_get_sync);
++
++int phy_pm_runtime_put(struct phy *phy)
++{
++      if (!pm_runtime_enabled(&phy->dev))
++              return -ENOTSUPP;
++
++      return pm_runtime_put(&phy->dev);
++}
++EXPORT_SYMBOL_GPL(phy_pm_runtime_put);
++
++int phy_pm_runtime_put_sync(struct phy *phy)
++{
++      if (!pm_runtime_enabled(&phy->dev))
++              return -ENOTSUPP;
++
++      return pm_runtime_put_sync(&phy->dev);
++}
++EXPORT_SYMBOL_GPL(phy_pm_runtime_put_sync);
++
++void phy_pm_runtime_allow(struct phy *phy)
++{
++      if (!pm_runtime_enabled(&phy->dev))
++              return;
++
++      pm_runtime_allow(&phy->dev);
++}
++EXPORT_SYMBOL_GPL(phy_pm_runtime_allow);
++
++void phy_pm_runtime_forbid(struct phy *phy)
++{
++      if (!pm_runtime_enabled(&phy->dev))
++              return;
++
++      pm_runtime_forbid(&phy->dev);
++}
++EXPORT_SYMBOL_GPL(phy_pm_runtime_forbid);
++
++int phy_init(struct phy *phy)
++{
++      int ret;
++
++      ret = phy_pm_runtime_get_sync(phy);
++      if (ret < 0 && ret != -ENOTSUPP)
++              return ret;
++
++      mutex_lock(&phy->mutex);
++      if (phy->init_count++ == 0 && phy->ops->init) {
++              ret = phy->ops->init(phy);
++              if (ret < 0) {
++                      dev_err(&phy->dev, "phy init failed --> %d\n", ret);
++                      goto out;
++              }
++      }
++
++out:
++      mutex_unlock(&phy->mutex);
++      phy_pm_runtime_put(phy);
++      return ret;
++}
++EXPORT_SYMBOL_GPL(phy_init);
++
++int phy_exit(struct phy *phy)
++{
++      int ret;
++
++      ret = phy_pm_runtime_get_sync(phy);
++      if (ret < 0 && ret != -ENOTSUPP)
++              return ret;
++
++      mutex_lock(&phy->mutex);
++      if (--phy->init_count == 0 && phy->ops->exit) {
++              ret = phy->ops->exit(phy);
++              if (ret < 0) {
++                      dev_err(&phy->dev, "phy exit failed --> %d\n", ret);
++                      goto out;
++              }
++      }
++
++out:
++      mutex_unlock(&phy->mutex);
++      phy_pm_runtime_put(phy);
++      return ret;
++}
++EXPORT_SYMBOL_GPL(phy_exit);
++
++int phy_power_on(struct phy *phy)
++{
++      int ret = -ENOTSUPP;
++
++      ret = phy_pm_runtime_get_sync(phy);
++      if (ret < 0 && ret != -ENOTSUPP)
++              return ret;
++
++      mutex_lock(&phy->mutex);
++      if (phy->power_count++ == 0 && phy->ops->power_on) {
++              ret = phy->ops->power_on(phy);
++              if (ret < 0) {
++                      dev_err(&phy->dev, "phy poweron failed --> %d\n", ret);
++                      goto out;
++              }
++      }
++
++out:
++      mutex_unlock(&phy->mutex);
++
++      return ret;
++}
++EXPORT_SYMBOL_GPL(phy_power_on);
++
++int phy_power_off(struct phy *phy)
++{
++      int ret = -ENOTSUPP;
++
++      mutex_lock(&phy->mutex);
++      if (--phy->power_count == 0 && phy->ops->power_off) {
++              ret =  phy->ops->power_off(phy);
++              if (ret < 0) {
++                      dev_err(&phy->dev, "phy poweroff failed --> %d\n", ret);
++                      goto out;
++              }
++      }
++
++out:
++      mutex_unlock(&phy->mutex);
++      phy_pm_runtime_put(phy);
++
++      return ret;
++}
++EXPORT_SYMBOL_GPL(phy_power_off);
++
++/**
++ * of_phy_get() - lookup and obtain a reference to a phy by phandle
++ * @dev: device that requests this phy
++ * @index: the index of the phy
++ *
++ * Returns the phy associated with the given phandle value,
++ * after getting a refcount to it or -ENODEV if there is no such phy or
++ * -EPROBE_DEFER if there is a phandle to the phy, but the device is
++ * not yet loaded. This function uses of_xlate call back function provided
++ * while registering the phy_provider to find the phy instance.
++ */
++static struct phy *of_phy_get(struct device *dev, int index)
++{
++      int ret;
++      struct phy_provider *phy_provider;
++      struct phy *phy = NULL;
++      struct of_phandle_args args;
++
++      ret = of_parse_phandle_with_args(dev->of_node, "phys", "#phy-cells",
++              index, &args);
++      if (ret) {
++              dev_dbg(dev, "failed to get phy in %s node\n",
++                      dev->of_node->full_name);
++              return ERR_PTR(-ENODEV);
++      }
++
++      mutex_lock(&phy_provider_mutex);
++      phy_provider = of_phy_provider_lookup(args.np);
++      if (IS_ERR(phy_provider) || !try_module_get(phy_provider->owner)) {
++              phy = ERR_PTR(-EPROBE_DEFER);
++              goto err0;
++      }
++
++      phy = phy_provider->of_xlate(phy_provider->dev, &args);
++      module_put(phy_provider->owner);
++
++err0:
++      mutex_unlock(&phy_provider_mutex);
++      of_node_put(args.np);
++
++      return phy;
++}
++
++/**
++ * phy_put() - release the PHY
++ * @phy: the phy returned by phy_get()
++ *
++ * Releases a refcount the caller received from phy_get().
++ */
++void phy_put(struct phy *phy)
++{
++      if (IS_ERR(phy))
++              return;
++
++      module_put(phy->ops->owner);
++      put_device(&phy->dev);
++}
++EXPORT_SYMBOL_GPL(phy_put);
++
++/**
++ * devm_phy_put() - release the PHY
++ * @dev: device that wants to release this phy
++ * @phy: the phy returned by devm_phy_get()
++ *
++ * destroys the devres associated with this phy and invokes phy_put
++ * to release the phy.
++ */
++void devm_phy_put(struct device *dev, struct phy *phy)
++{
++      int r;
++
++      r = devres_destroy(dev, devm_phy_release, devm_phy_match, phy);
++      dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n");
++}
++EXPORT_SYMBOL_GPL(devm_phy_put);
++
++/**
++ * of_phy_simple_xlate() - returns the phy instance from phy provider
++ * @dev: the PHY provider device
++ * @args: of_phandle_args (not used here)
++ *
++ * Intended to be used by phy provider for the common case where #phy-cells is
++ * 0. For other cases where #phy-cells is greater than '0', the phy provider
++ * should provide a custom of_xlate function that reads the *args* and returns
++ * the appropriate phy.
++ */
++struct phy *of_phy_simple_xlate(struct device *dev, struct of_phandle_args
++      *args)
++{
++      struct phy *phy;
++      struct class_dev_iter iter;
++      struct device_node *node = dev->of_node;
++
++      class_dev_iter_init(&iter, phy_class, NULL, NULL);
++      while ((dev = class_dev_iter_next(&iter))) {
++              phy = to_phy(dev);
++              if (node != phy->dev.of_node)
++                      continue;
++
++              class_dev_iter_exit(&iter);
++              return phy;
++      }
++
++      class_dev_iter_exit(&iter);
++      return ERR_PTR(-ENODEV);
++}
++EXPORT_SYMBOL_GPL(of_phy_simple_xlate);
++
++/**
++ * phy_get() - lookup and obtain a reference to a phy.
++ * @dev: device that requests this phy
++ * @string: the phy name as given in the dt data or the name of the controller
++ * port for non-dt case
++ *
++ * Returns the phy driver, after getting a refcount to it; or
++ * -ENODEV if there is no such phy.  The caller is responsible for
++ * calling phy_put() to release that count.
++ */
++struct phy *phy_get(struct device *dev, const char *string)
++{
++      int index = 0;
++      struct phy *phy = NULL;
++
++      if (string == NULL) {
++              dev_WARN(dev, "missing string\n");
++              return ERR_PTR(-EINVAL);
++      }
++
++      if (dev->of_node) {
++              index = of_property_match_string(dev->of_node, "phy-names",
++                      string);
++              phy = of_phy_get(dev, index);
++              if (IS_ERR(phy)) {
++                      dev_err(dev, "unable to find phy\n");
++                      return phy;
++              }
++      } else {
++              phy = phy_lookup(dev, string);
++              if (IS_ERR(phy)) {
++                      dev_err(dev, "unable to find phy\n");
++                      return phy;
++              }
++      }
++
++      if (!try_module_get(phy->ops->owner))
++              return ERR_PTR(-EPROBE_DEFER);
++
++      get_device(&phy->dev);
++
++      return phy;
++}
++EXPORT_SYMBOL_GPL(phy_get);
++
++/**
++ * devm_phy_get() - lookup and obtain a reference to a phy.
++ * @dev: device that requests this phy
++ * @string: the phy name as given in the dt data or phy device name
++ * for non-dt case
++ *
++ * Gets the phy using phy_get(), and associates a device with it using
++ * devres. On driver detach, release function is invoked on the devres data,
++ * then, devres data is freed.
++ */
++struct phy *devm_phy_get(struct device *dev, const char *string)
++{
++      struct phy **ptr, *phy;
++
++      ptr = devres_alloc(devm_phy_release, sizeof(*ptr), GFP_KERNEL);
++      if (!ptr)
++              return ERR_PTR(-ENOMEM);
++
++      phy = phy_get(dev, string);
++      if (!IS_ERR(phy)) {
++              *ptr = phy;
++              devres_add(dev, ptr);
++      } else {
++              devres_free(ptr);
++      }
++
++      return phy;
++}
++EXPORT_SYMBOL_GPL(devm_phy_get);
++
++/**
++ * phy_create() - create a new phy
++ * @dev: device that is creating the new phy
++ * @ops: function pointers for performing phy operations
++ * @init_data: contains the list of PHY consumers or NULL
++ *
++ * Called to create a phy using phy framework.
++ */
++struct phy *phy_create(struct device *dev, const struct phy_ops *ops,
++      struct phy_init_data *init_data)
++{
++      int ret;
++      int id;
++      struct phy *phy;
++
++      if (!dev) {
++              dev_WARN(dev, "no device provided for PHY\n");
++              ret = -EINVAL;
++              goto err0;
++      }
++
++      phy = kzalloc(sizeof(*phy), GFP_KERNEL);
++      if (!phy) {
++              ret = -ENOMEM;
++              goto err0;
++      }
++
++      id = ida_simple_get(&phy_ida, 0, 0, GFP_KERNEL);
++      if (id < 0) {
++              dev_err(dev, "unable to get id\n");
++              ret = id;
++              goto err0;
++      }
++
++      device_initialize(&phy->dev);
++      mutex_init(&phy->mutex);
++
++      phy->dev.class = phy_class;
++      phy->dev.parent = dev;
++      phy->dev.of_node = dev->of_node;
++      phy->id = id;
++      phy->ops = ops;
++      phy->init_data = init_data;
++
++      ret = dev_set_name(&phy->dev, "phy-%s.%d", dev_name(dev), id);
++      if (ret)
++              goto err1;
++
++      ret = device_add(&phy->dev);
++      if (ret)
++              goto err1;
++
++      if (pm_runtime_enabled(dev)) {
++              pm_runtime_enable(&phy->dev);
++              pm_runtime_no_callbacks(&phy->dev);
++      }
++
++      return phy;
++
++err1:
++      ida_remove(&phy_ida, phy->id);
++      put_device(&phy->dev);
++      kfree(phy);
++
++err0:
++      return ERR_PTR(ret);
++}
++EXPORT_SYMBOL_GPL(phy_create);
++
++/**
++ * devm_phy_create() - create a new phy
++ * @dev: device that is creating the new phy
++ * @ops: function pointers for performing phy operations
++ * @init_data: contains the list of PHY consumers or NULL
++ *
++ * Creates a new PHY device adding it to the PHY class.
++ * While at that, it also associates the device with the phy using devres.
++ * On driver detach, release function is invoked on the devres data,
++ * then, devres data is freed.
++ */
++struct phy *devm_phy_create(struct device *dev, const struct phy_ops *ops,
++      struct phy_init_data *init_data)
++{
++      struct phy **ptr, *phy;
++
++      ptr = devres_alloc(devm_phy_consume, sizeof(*ptr), GFP_KERNEL);
++      if (!ptr)
++              return ERR_PTR(-ENOMEM);
++
++      phy = phy_create(dev, ops, init_data);
++      if (!IS_ERR(phy)) {
++              *ptr = phy;
++              devres_add(dev, ptr);
++      } else {
++              devres_free(ptr);
++      }
++
++      return phy;
++}
++EXPORT_SYMBOL_GPL(devm_phy_create);
++
++/**
++ * phy_destroy() - destroy the phy
++ * @phy: the phy to be destroyed
++ *
++ * Called to destroy the phy.
++ */
++void phy_destroy(struct phy *phy)
++{
++      pm_runtime_disable(&phy->dev);
++      device_unregister(&phy->dev);
++}
++EXPORT_SYMBOL_GPL(phy_destroy);
++
++/**
++ * devm_phy_destroy() - destroy the PHY
++ * @dev: device that wants to release this phy
++ * @phy: the phy returned by devm_phy_get()
++ *
++ * destroys the devres associated with this phy and invokes phy_destroy
++ * to destroy the phy.
++ */
++void devm_phy_destroy(struct device *dev, struct phy *phy)
++{
++      int r;
++
++      r = devres_destroy(dev, devm_phy_consume, devm_phy_match, phy);
++      dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n");
++}
++EXPORT_SYMBOL_GPL(devm_phy_destroy);
++
++/**
++ * __of_phy_provider_register() - create/register phy provider with the framework
++ * @dev: struct device of the phy provider
++ * @owner: the module owner containing of_xlate
++ * @of_xlate: function pointer to obtain phy instance from phy provider
++ *
++ * Creates struct phy_provider from dev and of_xlate function pointer.
++ * This is used in the case of dt boot for finding the phy instance from
++ * phy provider.
++ */
++struct phy_provider *__of_phy_provider_register(struct device *dev,
++      struct module *owner, struct phy * (*of_xlate)(struct device *dev,
++      struct of_phandle_args *args))
++{
++      struct phy_provider *phy_provider;
++
++      phy_provider = kzalloc(sizeof(*phy_provider), GFP_KERNEL);
++      if (!phy_provider)
++              return ERR_PTR(-ENOMEM);
++
++      phy_provider->dev = dev;
++      phy_provider->owner = owner;
++      phy_provider->of_xlate = of_xlate;
++
++      mutex_lock(&phy_provider_mutex);
++      list_add_tail(&phy_provider->list, &phy_provider_list);
++      mutex_unlock(&phy_provider_mutex);
++
++      return phy_provider;
++}
++EXPORT_SYMBOL_GPL(__of_phy_provider_register);
++
++/**
++ * __devm_of_phy_provider_register() - create/register phy provider with the
++ * framework
++ * @dev: struct device of the phy provider
++ * @owner: the module owner containing of_xlate
++ * @of_xlate: function pointer to obtain phy instance from phy provider
++ *
++ * Creates struct phy_provider from dev and of_xlate function pointer.
++ * This is used in the case of dt boot for finding the phy instance from
++ * phy provider. While at that, it also associates the device with the
++ * phy provider using devres. On driver detach, release function is invoked
++ * on the devres data, then, devres data is freed.
++ */
++struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
++      struct module *owner, struct phy * (*of_xlate)(struct device *dev,
++      struct of_phandle_args *args))
++{
++      struct phy_provider **ptr, *phy_provider;
++
++      ptr = devres_alloc(devm_phy_provider_release, sizeof(*ptr), GFP_KERNEL);
++      if (!ptr)
++              return ERR_PTR(-ENOMEM);
++
++      phy_provider = __of_phy_provider_register(dev, owner, of_xlate);
++      if (!IS_ERR(phy_provider)) {
++              *ptr = phy_provider;
++              devres_add(dev, ptr);
++      } else {
++              devres_free(ptr);
++      }
++
++      return phy_provider;
++}
++EXPORT_SYMBOL_GPL(__devm_of_phy_provider_register);
++
++/**
++ * of_phy_provider_unregister() - unregister phy provider from the framework
++ * @phy_provider: phy provider returned by of_phy_provider_register()
++ *
++ * Removes the phy_provider created using of_phy_provider_register().
++ */
++void of_phy_provider_unregister(struct phy_provider *phy_provider)
++{
++      if (IS_ERR(phy_provider))
++              return;
++
++      mutex_lock(&phy_provider_mutex);
++      list_del(&phy_provider->list);
++      kfree(phy_provider);
++      mutex_unlock(&phy_provider_mutex);
++}
++EXPORT_SYMBOL_GPL(of_phy_provider_unregister);
++
++/**
++ * devm_of_phy_provider_unregister() - remove phy provider from the framework
++ * @dev: struct device of the phy provider
++ *
++ * destroys the devres associated with this phy provider and invokes
++ * of_phy_provider_unregister to unregister the phy provider.
++ */
++void devm_of_phy_provider_unregister(struct device *dev,
++      struct phy_provider *phy_provider) {
++      int r;
++
++      r = devres_destroy(dev, devm_phy_provider_release, devm_phy_match,
++              phy_provider);
++      dev_WARN_ONCE(dev, r, "couldn't find PHY provider device resource\n");
++}
++EXPORT_SYMBOL_GPL(devm_of_phy_provider_unregister);
++
++/**
++ * phy_release() - release the phy
++ * @dev: the dev member within phy
++ *
++ * When the last reference to the device is removed, it is called
++ * from the embedded kobject as release method.
++ */
++static void phy_release(struct device *dev)
++{
++      struct phy *phy;
++
++      phy = to_phy(dev);
++      dev_vdbg(dev, "releasing '%s'\n", dev_name(dev));
++      ida_remove(&phy_ida, phy->id);
++      kfree(phy);
++}
++
++static int __init phy_core_init(void)
++{
++      phy_class = class_create(THIS_MODULE, "phy");
++      if (IS_ERR(phy_class)) {
++              pr_err("failed to create phy class --> %ld\n",
++                      PTR_ERR(phy_class));
++              return PTR_ERR(phy_class);
++      }
++
++      phy_class->dev_release = phy_release;
++
++      return 0;
++}
++module_init(phy_core_init);
++
++static void __exit phy_core_exit(void)
++{
++      class_destroy(phy_class);
++}
++module_exit(phy_core_exit);
++
++MODULE_DESCRIPTION("Generic PHY Framework");
++MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
++MODULE_LICENSE("GPL v2");
+diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
+new file mode 100644
+index 0000000..ca9114d
+--- /dev/null
++++ b/include/linux/phy/phy.h
+@@ -0,0 +1,270 @@
++/*
++ * phy.h -- generic phy header file
++ *
++ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
++ *
++ * Author: Kishon Vijay Abraham I <kishon@ti.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.
++ */
++
++#ifndef __DRIVERS_PHY_H
++#define __DRIVERS_PHY_H
++
++#include <linux/err.h>
++#include <linux/of.h>
++#include <linux/device.h>
++#include <linux/pm_runtime.h>
++
++struct phy;
++
++/**
++ * struct phy_ops - set of function pointers for performing phy operations
++ * @init: operation to be performed for initializing phy
++ * @exit: operation to be performed while exiting
++ * @power_on: powering on the phy
++ * @power_off: powering off the phy
++ * @owner: the module owner containing the ops
++ */
++struct phy_ops {
++      int     (*init)(struct phy *phy);
++      int     (*exit)(struct phy *phy);
++      int     (*power_on)(struct phy *phy);
++      int     (*power_off)(struct phy *phy);
++      struct module *owner;
++};
++
++/**
++ * struct phy - represents the phy device
++ * @dev: phy device
++ * @id: id of the phy device
++ * @ops: function pointers for performing phy operations
++ * @init_data: list of PHY consumers (non-dt only)
++ * @mutex: mutex to protect phy_ops
++ * @init_count: used to protect when the PHY is used by multiple consumers
++ * @power_count: used to protect when the PHY is used by multiple consumers
++ */
++struct phy {
++      struct device           dev;
++      int                     id;
++      const struct phy_ops    *ops;
++      struct phy_init_data    *init_data;
++      struct mutex            mutex;
++      int                     init_count;
++      int                     power_count;
++};
++
++/**
++ * struct phy_provider - represents the phy provider
++ * @dev: phy provider device
++ * @owner: the module owner having of_xlate
++ * @of_xlate: function pointer to obtain phy instance from phy pointer
++ * @list: to maintain a linked list of PHY providers
++ */
++struct phy_provider {
++      struct device           *dev;
++      struct module           *owner;
++      struct list_head        list;
++      struct phy * (*of_xlate)(struct device *dev,
++              struct of_phandle_args *args);
++};
++
++/**
++ * struct phy_consumer - represents the phy consumer
++ * @dev_name: the device name of the controller that will use this PHY device
++ * @port: name given to the consumer port
++ */
++struct phy_consumer {
++      const char *dev_name;
++      const char *port;
++};
++
++/**
++ * struct phy_init_data - contains the list of PHY consumers
++ * @num_consumers: number of consumers for this PHY device
++ * @consumers: list of PHY consumers
++ */
++struct phy_init_data {
++      unsigned int num_consumers;
++      struct phy_consumer *consumers;
++};
++
++#define PHY_CONSUMER(_dev_name, _port)                                \
++{                                                             \
++      .dev_name       = _dev_name,                            \
++      .port           = _port,                                \
++}
++
++#define       to_phy(dev)     (container_of((dev), struct phy, dev))
++
++#define       of_phy_provider_register(dev, xlate)    \
++      __of_phy_provider_register((dev), THIS_MODULE, (xlate))
++
++#define       devm_of_phy_provider_register(dev, xlate)       \
++      __devm_of_phy_provider_register((dev), THIS_MODULE, (xlate))
++
++static inline void phy_set_drvdata(struct phy *phy, void *data)
++{
++      dev_set_drvdata(&phy->dev, data);
++}
++
++static inline void *phy_get_drvdata(struct phy *phy)
++{
++      return dev_get_drvdata(&phy->dev);
++}
++
++#if IS_ENABLED(CONFIG_GENERIC_PHY)
++extern int phy_pm_runtime_get(struct phy *phy);
++extern int phy_pm_runtime_get_sync(struct phy *phy);
++extern int phy_pm_runtime_put(struct phy *phy);
++extern int phy_pm_runtime_put_sync(struct phy *phy);
++extern void phy_pm_runtime_allow(struct phy *phy);
++extern void phy_pm_runtime_forbid(struct phy *phy);
++extern int phy_init(struct phy *phy);
++extern int phy_exit(struct phy *phy);
++extern int phy_power_on(struct phy *phy);
++extern int phy_power_off(struct phy *phy);
++extern struct phy *phy_get(struct device *dev, const char *string);
++extern struct phy *devm_phy_get(struct device *dev, const char *string);
++extern void phy_put(struct phy *phy);
++extern void devm_phy_put(struct device *dev, struct phy *phy);
++extern struct phy *of_phy_simple_xlate(struct device *dev,
++      struct of_phandle_args *args);
++extern struct phy *phy_create(struct device *dev, const struct phy_ops *ops,
++      struct phy_init_data *init_data);
++extern struct phy *devm_phy_create(struct device *dev,
++      const struct phy_ops *ops, struct phy_init_data *init_data);
++extern void phy_destroy(struct phy *phy);
++extern void devm_phy_destroy(struct device *dev, struct phy *phy);
++extern struct phy_provider *__of_phy_provider_register(struct device *dev,
++      struct module *owner, struct phy * (*of_xlate)(struct device *dev,
++      struct of_phandle_args *args));
++extern struct phy_provider *__devm_of_phy_provider_register(struct device *dev,
++      struct module *owner, struct phy * (*of_xlate)(struct device *dev,
++      struct of_phandle_args *args));
++extern void of_phy_provider_unregister(struct phy_provider *phy_provider);
++extern void devm_of_phy_provider_unregister(struct device *dev,
++      struct phy_provider *phy_provider);
++#else
++static inline int phy_pm_runtime_get(struct phy *phy)
++{
++      return -ENOSYS;
++}
++
++static inline int phy_pm_runtime_get_sync(struct phy *phy)
++{
++      return -ENOSYS;
++}
++
++static inline int phy_pm_runtime_put(struct phy *phy)
++{
++      return -ENOSYS;
++}
++
++static inline int phy_pm_runtime_put_sync(struct phy *phy)
++{
++      return -ENOSYS;
++}
++
++static inline void phy_pm_runtime_allow(struct phy *phy)
++{
++      return;
++}
++
++static inline void phy_pm_runtime_forbid(struct phy *phy)
++{
++      return;
++}
++
++static inline int phy_init(struct phy *phy)
++{
++      return -ENOSYS;
++}
++
++static inline int phy_exit(struct phy *phy)
++{
++      return -ENOSYS;
++}
++
++static inline int phy_power_on(struct phy *phy)
++{
++      return -ENOSYS;
++}
++
++static inline int phy_power_off(struct phy *phy)
++{
++      return -ENOSYS;
++}
++
++static inline struct phy *phy_get(struct device *dev, const char *string)
++{
++      return ERR_PTR(-ENOSYS);
++}
++
++static inline struct phy *devm_phy_get(struct device *dev, const char *string)
++{
++      return ERR_PTR(-ENOSYS);
++}
++
++static inline void phy_put(struct phy *phy)
++{
++}
++
++static inline void devm_phy_put(struct device *dev, struct phy *phy)
++{
++}
++
++static inline struct phy *of_phy_simple_xlate(struct device *dev,
++      struct of_phandle_args *args)
++{
++      return ERR_PTR(-ENOSYS);
++}
++
++static inline struct phy *phy_create(struct device *dev,
++      const struct phy_ops *ops, struct phy_init_data *init_data)
++{
++      return ERR_PTR(-ENOSYS);
++}
++
++static inline struct phy *devm_phy_create(struct device *dev,
++      const struct phy_ops *ops, struct phy_init_data *init_data)
++{
++      return ERR_PTR(-ENOSYS);
++}
++
++static inline void phy_destroy(struct phy *phy)
++{
++}
++
++static inline void devm_phy_destroy(struct device *dev, struct phy *phy)
++{
++}
++
++static inline struct phy_provider *__of_phy_provider_register(
++      struct device *dev, struct module *owner, struct phy * (*of_xlate)(
++      struct device *dev, struct of_phandle_args *args))
++{
++      return ERR_PTR(-ENOSYS);
++}
++
++static inline struct phy_provider *__devm_of_phy_provider_register(struct device
++      *dev, struct module *owner, struct phy * (*of_xlate)(struct device *dev,
++      struct of_phandle_args *args))
++{
++      return ERR_PTR(-ENOSYS);
++}
++
++static inline void of_phy_provider_unregister(struct phy_provider *phy_provider)
++{
++}
++
++static inline void devm_of_phy_provider_unregister(struct device *dev,
++      struct phy_provider *phy_provider)
++{
++}
++#endif
++
++#endif /* __DRIVERS_PHY_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0756-phy-Add-driver-for-Exynos-MIPI-CSIS-DSIM-DPHYs.patch b/patches.tizen/0756-phy-Add-driver-for-Exynos-MIPI-CSIS-DSIM-DPHYs.patch
new file mode 100644 (file)
index 0000000..68c0de2
--- /dev/null
@@ -0,0 +1,263 @@
+From 384e16b37787c8a97bfd1012c08b51a7a8596c37 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Wed, 4 Sep 2013 15:07:24 +0200
+Subject: [PATCH 0756/1302] phy: Add driver for Exynos MIPI CSIS/DSIM DPHYs
+
+Add a PHY provider driver for the Samsung S5P/Exynos SoC MIPI CSI-2
+receiver and MIPI DSI transmitter DPHYs.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Felipe Balbi <balbi@ti.com>
+---
+Changes since v4:
+ - updated to new version of devm_phy_create().
+
+Changes since v3:
+ - replaced spin_(un)lock_irq_{save,restore} with spin_{lock,unlock}.
+ - DT binding file renamed to samsung-phy.txt, so it can be used for
+   other PHYs as well,
+ - removed <linux/delay.h> inclusion,
+ - added missing spin_lock_init().
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/phy/samsung-phy.txt        |  14 ++
+ drivers/phy/Kconfig                                |   6 +
+ drivers/phy/Makefile                               |   3 +-
+ drivers/phy/phy-exynos-mipi-video.c                | 176 +++++++++++++++++++++
+ 4 files changed, 198 insertions(+), 1 deletion(-)
+ create mode 100644 Documentation/devicetree/bindings/phy/samsung-phy.txt
+ create mode 100644 drivers/phy/phy-exynos-mipi-video.c
+
+diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt
+new file mode 100644
+index 0000000..5ff208c
+--- /dev/null
++++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt
+@@ -0,0 +1,14 @@
++Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY
++-------------------------------------------------
++
++Required properties:
++- compatible : should be "samsung,s5pv210-mipi-video-phy";
++- reg : offset and length of the MIPI DPHY register set;
++- #phy-cells : from the generic phy bindings, must be 1;
++
++For "samsung,s5pv210-mipi-video-phy" compatible PHYs the second cell in
++the PHY specifier identifies the PHY and its meaning is as follows:
++  0 - MIPI CSIS 0,
++  1 - MIPI DSIM 0,
++  2 - MIPI CSIS 1,
++  3 - MIPI DSIM 1.
+diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
+index 349bef2..108c5f6 100644
+--- a/drivers/phy/Kconfig
++++ b/drivers/phy/Kconfig
+@@ -15,4 +15,10 @@ config GENERIC_PHY
+         phy users can obtain reference to the PHY. All the users of this
+         framework should select this config.
++config PHY_EXYNOS_MIPI_VIDEO
++      tristate "S5P/EXYNOS SoC series MIPI CSI-2/DSI PHY driver"
++      help
++        Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung
++        S5P and EXYNOS SoCs.
++
+ endmenu
+diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
+index 9e9560f..71d8841 100644
+--- a/drivers/phy/Makefile
++++ b/drivers/phy/Makefile
+@@ -2,4 +2,5 @@
+ # Makefile for the phy drivers.
+ #
+-obj-$(CONFIG_GENERIC_PHY)     += phy-core.o
++obj-$(CONFIG_GENERIC_PHY)             += phy-core.o
++obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO)   += phy-exynos-mipi-video.o
+diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/phy-exynos-mipi-video.c
+new file mode 100644
+index 0000000..b73b86a
+--- /dev/null
++++ b/drivers/phy/phy-exynos-mipi-video.c
+@@ -0,0 +1,176 @@
++/*
++ * Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY driver
++ *
++ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
++ * Author: Sylwester Nawrocki <s.nawrocki@samsung.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/io.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/phy/phy.h>
++#include <linux/platform_device.h>
++#include <linux/spinlock.h>
++
++/* MIPI_PHYn_CONTROL register offset: n = 0..1 */
++#define EXYNOS_MIPI_PHY_CONTROL(n)    ((n) * 4)
++#define EXYNOS_MIPI_PHY_ENABLE                (1 << 0)
++#define EXYNOS_MIPI_PHY_SRESETN               (1 << 1)
++#define EXYNOS_MIPI_PHY_MRESETN               (1 << 2)
++#define EXYNOS_MIPI_PHY_RESET_MASK    (3 << 1)
++
++enum exynos_mipi_phy_id {
++      EXYNOS_MIPI_PHY_ID_CSIS0,
++      EXYNOS_MIPI_PHY_ID_DSIM0,
++      EXYNOS_MIPI_PHY_ID_CSIS1,
++      EXYNOS_MIPI_PHY_ID_DSIM1,
++      EXYNOS_MIPI_PHYS_NUM
++};
++
++#define is_mipi_dsim_phy_id(id) \
++      ((id) == EXYNOS_MIPI_PHY_ID_DSIM0 || (id) == EXYNOS_MIPI_PHY_ID_DSIM1)
++
++struct exynos_mipi_video_phy {
++      spinlock_t slock;
++      struct video_phy_desc {
++              struct phy *phy;
++              unsigned int index;
++      } phys[EXYNOS_MIPI_PHYS_NUM];
++      void __iomem *regs;
++};
++
++static int __set_phy_state(struct exynos_mipi_video_phy *state,
++                      enum exynos_mipi_phy_id id, unsigned int on)
++{
++      void __iomem *addr;
++      u32 reg, reset;
++
++      addr = state->regs + EXYNOS_MIPI_PHY_CONTROL(id / 2);
++
++      if (is_mipi_dsim_phy_id(id))
++              reset = EXYNOS_MIPI_PHY_MRESETN;
++      else
++              reset = EXYNOS_MIPI_PHY_SRESETN;
++
++      spin_lock(&state->slock);
++      reg = readl(addr);
++      if (on)
++              reg |= reset;
++      else
++              reg &= ~reset;
++      writel(reg, addr);
++
++      /* Clear ENABLE bit only if MRESETN, SRESETN bits are not set. */
++      if (on)
++              reg |= EXYNOS_MIPI_PHY_ENABLE;
++      else if (!(reg & EXYNOS_MIPI_PHY_RESET_MASK))
++              reg &= ~EXYNOS_MIPI_PHY_ENABLE;
++
++      writel(reg, addr);
++      spin_unlock(&state->slock);
++      return 0;
++}
++
++#define to_mipi_video_phy(desc) \
++      container_of((desc), struct exynos_mipi_video_phy, phys[(desc)->index]);
++
++static int exynos_mipi_video_phy_power_on(struct phy *phy)
++{
++      struct video_phy_desc *phy_desc = phy_get_drvdata(phy);
++      struct exynos_mipi_video_phy *state = to_mipi_video_phy(phy_desc);
++
++      return __set_phy_state(state, phy_desc->index, 1);
++}
++
++static int exynos_mipi_video_phy_power_off(struct phy *phy)
++{
++      struct video_phy_desc *phy_desc = phy_get_drvdata(phy);
++      struct exynos_mipi_video_phy *state = to_mipi_video_phy(phy_desc);
++
++      return __set_phy_state(state, phy_desc->index, 1);
++}
++
++static struct phy *exynos_mipi_video_phy_xlate(struct device *dev,
++                                      struct of_phandle_args *args)
++{
++      struct exynos_mipi_video_phy *state = dev_get_drvdata(dev);
++
++      if (WARN_ON(args->args[0] > EXYNOS_MIPI_PHYS_NUM))
++              return ERR_PTR(-ENODEV);
++
++      return state->phys[args->args[0]].phy;
++}
++
++static struct phy_ops exynos_mipi_video_phy_ops = {
++      .power_on       = exynos_mipi_video_phy_power_on,
++      .power_off      = exynos_mipi_video_phy_power_off,
++      .owner          = THIS_MODULE,
++};
++
++static int exynos_mipi_video_phy_probe(struct platform_device *pdev)
++{
++      struct exynos_mipi_video_phy *state;
++      struct device *dev = &pdev->dev;
++      struct resource *res;
++      struct phy_provider *phy_provider;
++      unsigned int i;
++
++      state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
++      if (!state)
++              return -ENOMEM;
++
++      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++
++      state->regs = devm_ioremap_resource(dev, res);
++      if (IS_ERR(state->regs))
++              return PTR_ERR(state->regs);
++
++      dev_set_drvdata(dev, state);
++      spin_lock_init(&state->slock);
++
++      phy_provider = devm_of_phy_provider_register(dev,
++                                      exynos_mipi_video_phy_xlate);
++      if (IS_ERR(phy_provider))
++              return PTR_ERR(phy_provider);
++
++      for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) {
++              struct phy *phy = devm_phy_create(dev,
++                                      &exynos_mipi_video_phy_ops, NULL);
++              if (IS_ERR(phy)) {
++                      dev_err(dev, "failed to create PHY %d\n", i);
++                      return PTR_ERR(phy);
++              }
++
++              state->phys[i].phy = phy;
++              state->phys[i].index = i;
++              phy_set_drvdata(phy, &state->phys[i]);
++      }
++
++      return 0;
++}
++
++static const struct of_device_id exynos_mipi_video_phy_of_match[] = {
++      { .compatible = "samsung,s5pv210-mipi-video-phy" },
++      { },
++};
++MODULE_DEVICE_TABLE(of, exynos_mipi_video_phy_of_match);
++
++static struct platform_driver exynos_mipi_video_phy_driver = {
++      .probe  = exynos_mipi_video_phy_probe,
++      .driver = {
++              .of_match_table = exynos_mipi_video_phy_of_match,
++              .name  = "exynos-mipi-video-phy",
++              .owner = THIS_MODULE,
++      }
++};
++module_platform_driver(exynos_mipi_video_phy_driver);
++
++MODULE_DESCRIPTION("Samsung S5P/EXYNOS SoC MIPI CSI-2/DSI PHY driver");
++MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
++MODULE_LICENSE("GPL v2");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0757-media-exynos4-is-Use-the-generic-MIPI-CSIS-PHY-drive.patch b/patches.tizen/0757-media-exynos4-is-Use-the-generic-MIPI-CSIS-PHY-drive.patch
new file mode 100644 (file)
index 0000000..8627e30
--- /dev/null
@@ -0,0 +1,113 @@
+From 87e8f78c19b62ad31a70e0f8f2ec6310ed1a132c Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 4 Apr 2013 14:15:04 +0200
+Subject: [PATCH 0757/1302] [media] exynos4-is: Use the generic MIPI CSIS PHY
+ driver
+
+Use the generic PHY API instead of the platform callback to control
+the MIPI CSIS DPHY. The 'phy_label' field is added to the platform
+data structure to allow PHY lookup on non-dt platforms
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Felipe Balbi <balbi@ti.com>
+Acked-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+---
+Changes since v4:
+ - updated to latest version of the PHY framework - removed PHY
+   labels.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/mipi-csis.c | 13 ++++++++++---
+ include/linux/platform_data/mipi-csis.h       |  9 ---------
+ 2 files changed, 10 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
+index 0fe80e3..6a3f2b3 100644
+--- a/drivers/media/platform/exynos4-is/mipi-csis.c
++++ b/drivers/media/platform/exynos4-is/mipi-csis.c
+@@ -20,6 +20,7 @@
+ #include <linux/memory.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
++#include <linux/phy/phy.h>
+ #include <linux/platform_data/mipi-csis.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_runtime.h>
+@@ -184,6 +185,7 @@ struct csis_drvdata {
+  * @sd: v4l2_subdev associated with CSIS device instance
+  * @index: the hardware instance index
+  * @pdev: CSIS platform device
++ * @phy: pointer to the CSIS generic PHY
+  * @regs: mmaped I/O registers memory
+  * @supplies: CSIS regulator supplies
+  * @clock: CSIS clocks
+@@ -207,6 +209,7 @@ struct csis_state {
+       struct v4l2_subdev sd;
+       u8 index;
+       struct platform_device *pdev;
++      struct phy *phy;
+       void __iomem *regs;
+       struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES];
+       struct clk *clock[NUM_CSIS_CLOCKS];
+@@ -811,8 +814,8 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
+                                       "samsung,csis-wclk");
+       state->num_lanes = endpoint.bus.mipi_csi2.num_data_lanes;
+-
+       of_node_put(node);
++
+       return 0;
+ }
+ #else
+@@ -861,6 +864,10 @@ static int s5pcsis_probe(struct platform_device *pdev)
+               return -EINVAL;
+       }
++      state->phy = devm_phy_get(dev, "csis");
++      if (IS_ERR(state->phy))
++              return PTR_ERR(state->phy);
++
+       mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       state->regs = devm_ioremap_resource(dev, mem_res);
+       if (IS_ERR(state->regs))
+@@ -946,7 +953,7 @@ static int s5pcsis_pm_suspend(struct device *dev, bool runtime)
+       mutex_lock(&state->lock);
+       if (state->flags & ST_POWERED) {
+               s5pcsis_stop_stream(state);
+-              ret = s5p_csis_phy_enable(state->index, false);
++              ret = phy_power_off(state->phy);
+               if (ret)
+                       goto unlock;
+               ret = regulator_bulk_disable(CSIS_NUM_SUPPLIES,
+@@ -982,7 +989,7 @@ static int s5pcsis_pm_resume(struct device *dev, bool runtime)
+                                           state->supplies);
+               if (ret)
+                       goto unlock;
+-              ret = s5p_csis_phy_enable(state->index, true);
++              ret = phy_power_on(state->phy);
+               if (!ret) {
+                       state->flags |= ST_POWERED;
+               } else {
+diff --git a/include/linux/platform_data/mipi-csis.h b/include/linux/platform_data/mipi-csis.h
+index bf34e17..c2fd902 100644
+--- a/include/linux/platform_data/mipi-csis.h
++++ b/include/linux/platform_data/mipi-csis.h
+@@ -25,13 +25,4 @@ struct s5p_platform_mipi_csis {
+       u8 hs_settle;
+ };
+-/**
+- * s5p_csis_phy_enable - global MIPI-CSI receiver D-PHY control
+- * @id:     MIPI-CSIS harware instance index (0...1)
+- * @on:     true to enable D-PHY and deassert its reset
+- *          false to disable D-PHY
+- * @return: 0 on success, or negative error code on failure
+- */
+-int s5p_csis_phy_enable(int id, bool on);
+-
+ #endif /* __PLAT_SAMSUNG_MIPI_CSIS_H_ */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0758-video-exynos_dsi-Use-generic-PHY-driver.patch b/patches.tizen/0758-video-exynos_dsi-Use-generic-PHY-driver.patch
new file mode 100644 (file)
index 0000000..58b34d0
--- /dev/null
@@ -0,0 +1,200 @@
+From fdf4c640e4b5468b70bcca877b07a345fec18c96 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 4 Apr 2013 14:13:51 +0200
+Subject: [PATCH 0758/1302] video: exynos_dsi: Use generic PHY driver
+
+Use the generic PHY API instead of the platform callback to control
+the MIPI DSIM DPHY.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+---
+Changes since v4:
+ - updated to latest version of the PHY framework - removed PHY
+   labels.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/video/display/source-exynos_dsi.c | 36 ++++++++++---------------------
+ drivers/video/exynos/exynos_mipi_dsi.c    |  2 +-
+ include/video/exynos_dsi.h                |  5 -----
+ include/video/exynos_mipi_dsim.h          |  5 +----
+ 4 files changed, 13 insertions(+), 35 deletions(-)
+
+diff --git a/drivers/video/display/source-exynos_dsi.c b/drivers/video/display/source-exynos_dsi.c
+index d7094f4..d36162f 100644
+--- a/drivers/video/display/source-exynos_dsi.c
++++ b/drivers/video/display/source-exynos_dsi.c
+@@ -24,6 +24,7 @@
+ #include <linux/mm.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
++#include <linux/phy/phy.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/regulator/consumer.h>
+@@ -219,6 +220,7 @@ struct exynos_dsi {
+       bool enabled;
+       struct platform_device *pdev;
++      struct phy *phy;
+       struct device *dev;
+       struct resource *res;
+       struct clk *pll_clk;
+@@ -816,6 +818,7 @@ again:
+ static bool exynos_dsi_transfer_finish(struct exynos_dsi *dsi)
+ {
++      static unsigned long j;
+       struct exynos_dsi_transfer *xfer;
+       unsigned long flags;
+       bool start = true;
+@@ -824,7 +827,8 @@ static bool exynos_dsi_transfer_finish(struct exynos_dsi *dsi)
+       if (list_empty(&dsi->transfer_list)) {
+               spin_unlock_irqrestore(&dsi->transfer_lock, flags);
+-              dev_warn(dsi->dev, "unexpected TX/RX interrupt\n");
++              if (printk_timed_ratelimit(&j, 500))
++                      dev_warn(dsi->dev, "unexpected TX/RX interrupt\n");
+               return false;
+       }
+@@ -996,8 +1000,7 @@ static int exynos_dsi_enable(struct video_source *src)
+       clk_prepare_enable(dsi->bus_clk);
+       clk_prepare_enable(dsi->pll_clk);
+-      if (dsi->pd->phy_enable)
+-              dsi->pd->phy_enable(dsi->pdev, true);
++      phy_power_on(dsi->phy);
+       exynos_dsi_reset(dsi);
+       exynos_dsi_init_link(dsi);
+@@ -1022,8 +1025,7 @@ static int exynos_dsi_disable(struct video_source *src)
+       exynos_dsi_disable_clock(dsi);
+-      if (dsi->pd->phy_enable)
+-              dsi->pd->phy_enable(dsi->pdev, false);
++      phy_power_off(dsi->phy);
+       clk_disable_unprepare(dsi->pll_clk);
+       clk_disable_unprepare(dsi->bus_clk);
+@@ -1104,12 +1106,6 @@ static const struct dsi_video_source_ops exynos_dsi_ops = {
+  * Device Tree
+  */
+-static int (* const of_phy_enables[])(struct platform_device *, bool) = {
+-#ifdef CONFIG_S5P_SETUP_MIPIPHY
+-      [0] = s5p_dsim_phy_enable,
+-#endif
+-};
+-
+ static struct exynos_dsi_platform_data *exynos_dsi_parse_dt(
+                                               struct platform_device *pdev)
+ {
+@@ -1117,7 +1113,6 @@ static struct exynos_dsi_platform_data *exynos_dsi_parse_dt(
+       struct exynos_dsi_platform_data *dsi_pd;
+       struct device *dev = &pdev->dev;
+       const __be32 *prop_data;
+-      u32 val;
+       dsi_pd = kzalloc(sizeof(*dsi_pd), GFP_KERNEL);
+       if (!dsi_pd) {
+@@ -1125,19 +1120,6 @@ static struct exynos_dsi_platform_data *exynos_dsi_parse_dt(
+               return NULL;
+       }
+-      prop_data = of_get_property(node, "samsung,phy-type", NULL);
+-      if (!prop_data) {
+-              dev_err(dev, "failed to get phy-type property\n");
+-              goto err_free_pd;
+-      }
+-
+-      val = be32_to_cpu(*prop_data);
+-      if (val >= ARRAY_SIZE(of_phy_enables) || !of_phy_enables[val]) {
+-              dev_err(dev, "Invalid phy-type %u\n", val);
+-              goto err_free_pd;
+-      }
+-      dsi_pd->phy_enable = of_phy_enables[val];
+-
+       prop_data = of_get_property(node, "samsung,pll-stable-time", NULL);
+       if (!prop_data) {
+               dev_err(dev, "failed to get pll-stable-time property\n");
+@@ -1259,6 +1241,10 @@ static int exynos_dsi_probe(struct platform_device *pdev)
+               return -ENOMEM;
+       }
++      dsi->phy = devm_phy_get(&pdev->dev, "dsim");
++      if (IS_ERR(dsi->phy))
++              return PTR_ERR(dsi->phy);
++
+       platform_set_drvdata(pdev, dsi);
+       dsi->irq = platform_get_irq(pdev, 0);
+diff --git a/drivers/video/exynos/exynos_mipi_dsi.c b/drivers/video/exynos/exynos_mipi_dsi.c
+index 248e444..00b3a52 100644
+--- a/drivers/video/exynos/exynos_mipi_dsi.c
++++ b/drivers/video/exynos/exynos_mipi_dsi.c
+@@ -373,7 +373,7 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)
+               return ret;
+       }
+-      dsim->phy = devm_phy_get(&pdev->dev, dsim_pd->phy_label);
++      dsim->phy = devm_phy_get(&pdev->dev, "dsim");
+       if (IS_ERR(dsim->phy))
+               return PTR_ERR(dsim->phy);
+diff --git a/include/video/exynos_dsi.h b/include/video/exynos_dsi.h
+index 95e1568..5c062c7 100644
+--- a/include/video/exynos_dsi.h
++++ b/include/video/exynos_dsi.h
+@@ -25,9 +25,6 @@
+  */
+ struct exynos_dsi_platform_data {
+       unsigned int enabled;
+-
+-      int (*phy_enable)(struct platform_device *pdev, bool on);
+-
+       unsigned int pll_stable_time;
+       unsigned long pll_clk_rate;
+       unsigned long esc_clk_rate;
+@@ -36,6 +33,4 @@ struct exynos_dsi_platform_data {
+       unsigned short rx_timeout;
+ };
+-int s5p_dsim_phy_enable(struct platform_device *pdev, bool on);
+-
+ #endif /* _EXYNOS_MIPI_DSIM_H */
+diff --git a/include/video/exynos_mipi_dsim.h b/include/video/exynos_mipi_dsim.h
+index 6843385..070983d 100644
+--- a/include/video/exynos_mipi_dsim.h
++++ b/include/video/exynos_mipi_dsim.h
+@@ -216,7 +216,7 @@ struct mipi_dsim_config {
+  *    automatically.
+  * @e_clk_src: select byte clock source.
+  * @pd: pointer to MIPI-DSI driver platform data.
+- * @phy: pointer to the generic PHY
++ * @phy: pointer to the MIPI-DSI PHY
+  */
+ struct mipi_dsim_device {
+       struct device                   *dev;
+@@ -250,7 +250,6 @@ struct mipi_dsim_device {
+  * @enabled: indicate whether mipi controller got enabled or not.
+  * @lcd_panel_info: pointer for lcd panel specific structure.
+  *    this structure specifies width, height, timing and polarity and so on.
+- * @phy_label: the generic PHY label
+  */
+ struct mipi_dsim_platform_data {
+       char                            lcd_panel_name[PANEL_NAME_SIZE];
+@@ -258,8 +257,6 @@ struct mipi_dsim_platform_data {
+       struct mipi_dsim_config         *dsim_config;
+       unsigned int                    enabled;
+       void                            *lcd_panel_info;
+-
+-      const char                      *phy_label;
+ };
+ /*
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0759-ARM-dts-Add-node-aliases-for-ISP_I2C-bus-controllers.patch b/patches.tizen/0759-ARM-dts-Add-node-aliases-for-ISP_I2C-bus-controllers.patch
new file mode 100644 (file)
index 0000000..2c3cd05
--- /dev/null
@@ -0,0 +1,30 @@
+From 7796049fafea06738c2f3003fcdbbbd8f74b1e60 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 5 Sep 2013 19:09:51 +0200
+Subject: [PATCH 0759/1302] ARM: dts: Add node aliases for ISP_I2C bus
+ controllers
+
+Ensure the ISP I2C bus adapters have always same id.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 4291f0c..f99f2c2 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -189,6 +189,8 @@
+               i2c10 = &i2c_if_pmic;
+               i2c11 = &i2c_fuel;
+               i2c12 = &i2c_gp2ap020a00f;
++              /* 15...16 reserved for i2c0_isp, i2c1_isp */
++              i2c16 = &i2c1_isp;
+       };
+       memory {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0760-ARM-dts-Add-common-jpeg-codec-node-for-Exynos4-SoCs.patch b/patches.tizen/0760-ARM-dts-Add-common-jpeg-codec-node-for-Exynos4-SoCs.patch
new file mode 100644 (file)
index 0000000..4127b51
--- /dev/null
@@ -0,0 +1,54 @@
+From 7b40322d9a30b50473036ea25ba9ab5b063800f2 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 6 Sep 2013 12:20:31 +0200
+Subject: [PATCH 0760/1302] ARM: dts: Add common jpeg codec node for Exynos4
+ SoCs
+
+Add common JPEG codec device node for Exynos4 SoCs.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi    | 9 +++++++++
+ arch/arm/boot/dts/exynos4x12.dtsi | 4 ++++
+ 2 files changed, 13 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index 1969580..c5c1516 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -232,6 +232,15 @@
+               status = "disabled";
+       };
++      jpeg-codec@11840000 {
++              compatible = "samsung,exynos4210-jpeg";
++              reg = <0x11840000 0x1000>;
++              interrupts = <0 88 0>;
++              clocks = <&clock 262>;
++              clock-names = "jpeg";
++              samsung,power-domain = <&pd_cam>;
++      };
++
+       sdhci@12510000 {
+               compatible = "samsung,exynos4210-sdhci";
+               reg = <0x12510000 0x100>;
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index 77241e1..e37ced2 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -120,6 +120,10 @@
+               status = "ok";
+       };
++      jpeg-codec@11840000 {
++              compatible = "samsung,exynos4212-jpeg";
++      };
++
+       sysmmu_fimc_isp: sysmmu@12260000 {
+               compatible = "samsung,exynos4210-sysmmu";
+               reg = <0x12260000 0x1000>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0761-tizen_defconfig-update.patch b/patches.tizen/0761-tizen_defconfig-update.patch
new file mode 100644 (file)
index 0000000..386fd1f
--- /dev/null
@@ -0,0 +1,40 @@
+From 37f9d2c990510ceb3f09cd2c7d0c69b2df3b6917 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 6 Sep 2013 15:22:30 +0200
+Subject: [PATCH 0761/1302] tizen_defconfig update
+
+Enable s5p-jpeg, DRM FIMC and DRM image rotator drivers.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_defconfig | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index 2007fcd..02ff16b 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -1914,7 +1914,7 @@ CONFIG_VIDEO_EXYNOS4_FIMC_IS=y
+ CONFIG_V4L_MEM2MEM_DRIVERS=y
+ # CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set
+ # CONFIG_VIDEO_SAMSUNG_S5P_G2D is not set
+-# CONFIG_VIDEO_SAMSUNG_S5P_JPEG is not set
++CONFIG_VIDEO_SAMSUNG_S5P_JPEG=y
+ CONFIG_VIDEO_SAMSUNG_S5P_MFC=y
+ # CONFIG_VIDEO_SH_VEU is not set
+ # CONFIG_V4L_TEST_DRIVERS is not set
+@@ -2083,7 +2083,9 @@ CONFIG_DRM_EXYNOS_FIMD=y
+ # CONFIG_DRM_EXYNOS_HDMI is not set
+ CONFIG_DRM_EXYNOS_VIDI=y
+ CONFIG_DRM_EXYNOS_G2D=y
+-# CONFIG_DRM_EXYNOS_IPP is not set
++CONFIG_DRM_EXYNOS_IPP=y
++CONFIG_DRM_EXYNOS_FIMC=y
++CONFIG_DRM_EXYNOS_ROTATOR=y
+ # CONFIG_DRM_UDL is not set
+ # CONFIG_DRM_TILCDC is not set
+ # CONFIG_VGASTATE is not set
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0762-HACK-usb-gadget-Fix-enumeration-on-boot.patch b/patches.tizen/0762-HACK-usb-gadget-Fix-enumeration-on-boot.patch
new file mode 100644 (file)
index 0000000..0c7378b
--- /dev/null
@@ -0,0 +1,43 @@
+From f8fa1a679d52a0cf1c536c51b3dd0d08abfa411e Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Mon, 9 Sep 2013 17:23:54 +0900
+Subject: [PATCH 0762/1302] HACK: usb: gadget: Fix enumeration on boot
+
+The Android gadget driver disconnects the gadget on bind
+and expects the gadget to stay disconnected until it calls
+usb_gadget_connect when userspace is ready. Removed the call
+to usb_gadget_connect in usb_gadget_probe_driver to avoid
+enabling the pullup before userspace is ready.
+
+Signed-off-by: Benoit Goby <benoit@android.com>
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/udc-core.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
+index 5514822..bef2f4c 100644
+--- a/drivers/usb/gadget/udc-core.c
++++ b/drivers/usb/gadget/udc-core.c
+@@ -335,7 +335,16 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri
+               driver->unbind(udc->gadget);
+               goto err1;
+       }
+-      usb_gadget_connect(udc->gadget);
++      /*
++               * HACK: The Android gadget driver disconnects the gadget
++               * on bind and expects the gadget to stay disconnected until
++               * it calls usb_gadget_connect when userspace is ready. Remove
++               * the call to usb_gadget_connect bellow to avoid enabling the
++               * pullup before userspace is ready.
++               */
++#if !defined(CONFIG_USB_G_ANDROID) && !defined(CONFIG_USB_G_SLP)
++               usb_gadget_connect(udc->gadget);
++#endif
+       kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
+       return 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0763-usb-s3c-hsotg-do-not-disconnect-gadget-when-receivin.patch b/patches.tizen/0763-usb-s3c-hsotg-do-not-disconnect-gadget-when-receivin.patch
new file mode 100644 (file)
index 0000000..0c25c6c
--- /dev/null
@@ -0,0 +1,33 @@
+From 3f99ac798c1577b32388ccd2921259b098c66262 Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Mon, 9 Sep 2013 17:24:35 +0900
+Subject: [PATCH 0763/1302] usb: s3c-hsotg: do not disconnect gadget when
+ receiving ErlySusp intr
+
+DWC2 databook indicates if the core sets "ErlySusp" bit, an idle state has been
+detected on the USB for 3 ms. This situation can be occurred when waiting
+a request from user daemon. So, we should keep the connection between udc and
+gadget even though this interrupt is occurred.
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/s3c-hsotg.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
+index 5fc87ce..afcd326 100644
+--- a/drivers/usb/gadget/s3c-hsotg.c
++++ b/drivers/usb/gadget/s3c-hsotg.c
+@@ -2476,8 +2476,6 @@ irq_retry:
+       if (gintsts & GINTSTS_ErlySusp) {
+               dev_dbg(hsotg->dev, "GINTSTS_ErlySusp\n");
+               writel(GINTSTS_ErlySusp, hsotg->regs + GINTSTS);
+-
+-              s3c_hsotg_disconnect(hsotg);
+       }
+       /*
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0764-WIP-usb-gadget-add-slp-composite-gadget.patch b/patches.tizen/0764-WIP-usb-gadget-add-slp-composite-gadget.patch
new file mode 100644 (file)
index 0000000..d830309
--- /dev/null
@@ -0,0 +1,2204 @@
+From efac50aee64d511b2da54fa5ae23bbf4774f657b Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Mon, 9 Sep 2013 19:14:06 +0900
+Subject: [PATCH 0764/1302] WIP: usb: gadget: add slp composite gadget
+
+This patch only enables 'rndis' and 'sdb' function gadgets. We may need to
+verify 'mtp', 'accessary' and so on. The slp gadget should be removed after
+we migrate to configfs-based gadget configuration successfully.
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig  |   12 +
+ drivers/usb/gadget/Makefile |    2 +
+ drivers/usb/gadget/f_sdb.c  |  763 ++++++++++++++++++++++++
+ drivers/usb/gadget/slp.c    | 1365 +++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 2142 insertions(+)
+ create mode 100644 drivers/usb/gadget/f_sdb.c
+ create mode 100644 drivers/usb/gadget/slp.c
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 84ac134..93dfc90 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -983,6 +983,18 @@ config USB_G_PRINTER
+         For more information, see Documentation/usb/gadget_printer.txt
+         which includes sample code for accessing the device file.
++config USB_G_SLP
++      boolean "SLP Gadget based on Android"
++      select USB_F_ACM
++      select USB_LIBCOMPOSITE
++      select USB_U_SERIAL
++      help
++        The SLP gadget driver supports multiple USB functions.
++        The functions can be configured via a board file and may be
++        enabled and disabled dynamically.
++        Support functions: sdb, acm, mtp, mass storage, rndis,
++        android accessory, diag.
++
+ if TTY
+ config USB_CDC_COMPOSITE
+diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
+index f106645..345a49c 100644
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -82,6 +82,7 @@ g_nokia-y                    := nokia.o
+ g_webcam-y                    := webcam.o
+ g_ncm-y                               := ncm.o
+ g_acm_ms-y                    := acm_ms.o
++g_slp-y                               := slp.o
+ g_tcm_usb_gadget-y            := tcm_usb_gadget.o
+ obj-$(CONFIG_USB_ZERO)                += g_zero.o
+@@ -101,4 +102,5 @@ obj-$(CONFIG_USB_G_NOKIA)  += g_nokia.o
+ obj-$(CONFIG_USB_G_WEBCAM)    += g_webcam.o
+ obj-$(CONFIG_USB_G_NCM)               += g_ncm.o
+ obj-$(CONFIG_USB_G_ACM_MS)    += g_acm_ms.o
++obj-$(CONFIG_USB_G_SLP)               += g_slp.o
+ obj-$(CONFIG_USB_GADGET_TARGET)       += tcm_usb_gadget.o
+diff --git a/drivers/usb/gadget/f_sdb.c b/drivers/usb/gadget/f_sdb.c
+new file mode 100644
+index 0000000..fec7238
+--- /dev/null
++++ b/drivers/usb/gadget/f_sdb.c
+@@ -0,0 +1,763 @@
++/*
++ * Gadget Driver for Samsung SDB (based on Android ADB)
++ *
++ * Copyright (C) 2008 Google, Inc.
++ * Author: Mike Lockwood <lockwood@android.com>
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++/* #define DEBUG */
++/* #define VERBOSE_DEBUG */
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/poll.h>
++#include <linux/delay.h>
++#include <linux/sched.h>
++#include <linux/wait.h>
++#include <linux/err.h>
++#include <linux/interrupt.h>
++
++#include <linux/types.h>
++#include <linux/device.h>
++#include <linux/miscdevice.h>
++
++#define SDB_BULK_BUFFER_SIZE           4096
++
++/* number of tx requests to allocate */
++#define SDB_TX_REQ_MAX 4
++
++static const char sdb_shortname[] = "samsung_sdb";
++
++static DEFINE_MUTEX(sdb_lock);
++
++struct sdb_ep_descs {
++      struct usb_endpoint_descriptor  *in;
++      struct usb_endpoint_descriptor  *out;
++};
++
++struct f_sdb {
++      struct usb_function function;
++      u8      inf_id;
++
++      struct sdb_ep_descs     fs;
++      struct sdb_ep_descs hs;
++
++      struct usb_ep *ep_in;
++      struct usb_ep *ep_out;
++
++      struct list_head bulk_in_q;
++};
++
++struct sdb_dev {
++      struct f_sdb *sdb_func;
++      spinlock_t lock;
++
++      int online;
++      int error;
++
++      atomic_t read_excl;
++      atomic_t write_excl;
++      atomic_t open_excl;
++
++      struct list_head *tx_idle;
++
++      wait_queue_head_t read_wq;
++      wait_queue_head_t write_wq;
++
++      struct usb_request *rx_req;
++      int rx_done;
++};
++
++static struct usb_interface_descriptor sdb_interface_desc = {
++      .bLength                = USB_DT_INTERFACE_SIZE,
++      .bDescriptorType        = USB_DT_INTERFACE,
++      /* .bInterfaceNumber    = DYNAMIC */
++      .bNumEndpoints          = 2,
++      .bInterfaceClass        = 0xFF,
++      .bInterfaceSubClass     = 0x20,
++      .bInterfaceProtocol     = 0x02,
++      /* .iInterface                  = DYNAMIC */
++};
++
++static struct usb_endpoint_descriptor sdb_fullspeed_in_desc = {
++      .bLength                = USB_DT_ENDPOINT_SIZE,
++      .bDescriptorType        = USB_DT_ENDPOINT,
++      .bEndpointAddress       = USB_DIR_IN,
++      .bmAttributes           = USB_ENDPOINT_XFER_BULK,
++      /* .wMaxPacketSize set by autoconfiguration */
++};
++
++static struct usb_endpoint_descriptor sdb_fullspeed_out_desc = {
++      .bLength                = USB_DT_ENDPOINT_SIZE,
++      .bDescriptorType        = USB_DT_ENDPOINT,
++      .bEndpointAddress       = USB_DIR_OUT,
++      .bmAttributes           = USB_ENDPOINT_XFER_BULK,
++      /* .wMaxPacketSize set by autoconfiguration */
++};
++
++static struct usb_descriptor_header *fs_sdb_descs[] = {
++      (struct usb_descriptor_header *) &sdb_interface_desc,
++      (struct usb_descriptor_header *) &sdb_fullspeed_in_desc,
++      (struct usb_descriptor_header *) &sdb_fullspeed_out_desc,
++      NULL,
++};
++
++static struct usb_endpoint_descriptor sdb_highspeed_in_desc = {
++      .bLength                = USB_DT_ENDPOINT_SIZE,
++      .bDescriptorType        = USB_DT_ENDPOINT,
++      /* bEndpointAddress copied from sdb_fullspeed_in_desc
++              during sdb_function_bind() */
++      .bmAttributes           = USB_ENDPOINT_XFER_BULK,
++      .wMaxPacketSize         = cpu_to_le16(512),
++};
++
++static struct usb_endpoint_descriptor sdb_highspeed_out_desc = {
++      .bLength                = USB_DT_ENDPOINT_SIZE,
++      .bDescriptorType        = USB_DT_ENDPOINT,
++      /* bEndpointAddress copied from sdb_fullspeed_in_desc
++              during sdb_function_bind() */
++      .bmAttributes           = USB_ENDPOINT_XFER_BULK,
++      .wMaxPacketSize         = cpu_to_le16(512),
++};
++
++static struct usb_descriptor_header *hs_sdb_descs[] = {
++      (struct usb_descriptor_header *) &sdb_interface_desc,
++      (struct usb_descriptor_header *) &sdb_highspeed_in_desc,
++      (struct usb_descriptor_header *) &sdb_highspeed_out_desc,
++      NULL,
++};
++
++/* string descriptors: */
++
++#define F_SDB_IDX     0
++
++/* static strings, in UTF-8 */
++static struct usb_string sdb_string_defs[] = {
++      [F_SDB_IDX].s = "Samsung SDB",
++      {  /* ZEROES END LIST */ },
++};
++
++static struct usb_gadget_strings sdb_string_table = {
++      .language =             0x0409, /* en-us */
++      .strings =              sdb_string_defs,
++};
++
++static struct usb_gadget_strings *sdb_strings[] = {
++      &sdb_string_table,
++      NULL,
++};
++
++/* temporary variable used between sdb_open() and sdb_gadget_bind() */
++static struct sdb_dev *_sdb_dev;
++
++static inline struct f_sdb *func_to_sdb(struct usb_function *f)
++{
++      return container_of(f, struct f_sdb, function);
++}
++
++static struct usb_request *sdb_request_new(struct usb_ep *ep, int buffer_size)
++{
++      struct usb_request *req = usb_ep_alloc_request(ep, GFP_KERNEL);
++      if (!req)
++              return NULL;
++
++      /* now allocate buffers for the requests */
++      req->buf = kmalloc(buffer_size, GFP_KERNEL);
++      if (!req->buf) {
++              usb_ep_free_request(ep, req);
++              return NULL;
++      }
++
++      return req;
++}
++
++static void sdb_request_free(struct usb_request *req, struct usb_ep *ep)
++{
++      if (req) {
++              kfree(req->buf);
++              usb_ep_free_request(ep, req);
++      }
++}
++
++static inline int _sdb_lock(atomic_t *excl)
++{
++      if (atomic_inc_return(excl) == 1) {
++              return 0;
++      } else {
++              atomic_dec(excl);
++              return -EBUSY;
++      }
++}
++
++static inline void _sdb_unlock(atomic_t *excl)
++{
++      atomic_dec(excl);
++}
++
++/* add a request to the tail of a list */
++static void sdb_req_put(struct sdb_dev *dev, struct list_head *head,
++              struct usb_request *req)
++{
++      unsigned long flags;
++
++      if (!dev || !req)
++              return;
++
++      spin_lock_irqsave(&dev->lock, flags);
++      if (head)
++              list_add_tail(&req->list, head);
++      spin_unlock_irqrestore(&dev->lock, flags);
++}
++
++/* remove a request from the head of a list */
++static struct usb_request *sdb_req_get(struct sdb_dev *dev,
++                              struct list_head *head)
++{
++      unsigned long flags;
++      struct usb_request *req;
++
++      if (!dev)
++              return NULL;
++
++      spin_lock_irqsave(&dev->lock, flags);
++      if (!head)
++              req = NULL;
++      else {
++              if (list_empty(head)) {
++                      req = NULL;
++              } else {
++                      req = list_first_entry(head, struct usb_request, list);
++                      list_del(&req->list);
++              }
++      }
++      spin_unlock_irqrestore(&dev->lock, flags);
++      return req;
++}
++
++static void sdb_complete_in(struct usb_ep *ep, struct usb_request *req)
++{
++      struct sdb_dev *dev = _sdb_dev;
++      struct f_sdb *sdb_func = ep->driver_data;
++
++      if (req->status != 0)
++              dev->error = 1;
++
++      sdb_req_put(dev, &sdb_func->bulk_in_q, req);
++      wake_up(&dev->write_wq);
++}
++
++static void sdb_complete_out(struct usb_ep *ep, struct usb_request *req)
++{
++      struct sdb_dev *dev = _sdb_dev;
++
++      dev->rx_done = 1;
++      if (req->status != 0)
++              dev->error = 1;
++
++      wake_up(&dev->read_wq);
++}
++
++static int sdb_create_bulk_endpoints(struct f_sdb *sdb_func,
++                              struct usb_endpoint_descriptor *in_desc,
++                              struct usb_endpoint_descriptor *out_desc)
++{
++      struct usb_composite_dev *cdev = sdb_func->function.config->cdev;
++      struct usb_request *req;
++      struct sdb_dev *dev = _sdb_dev;
++      struct usb_ep *ep;
++      int i;
++
++      DBG(cdev, "sdb_create_bulk_endpoints dev: %p\n", dev);
++
++      ep = usb_ep_autoconfig(cdev->gadget, in_desc);
++      if (!ep) {
++              ERROR(cdev, "usb_ep_autoconfig for ep_in failed\n");
++              return -ENODEV;
++      }
++      DBG(cdev, "usb_ep_autoconfig for ep_in got %s\n", ep->name);
++      ep->driver_data = cdev;         /* claim the endpoint */
++      sdb_func->ep_in = ep;
++
++      ep = usb_ep_autoconfig(cdev->gadget, out_desc);
++      if (!ep) {
++              ERROR(cdev, "usb_ep_autoconfig for ep_out failed\n");
++              return -ENODEV;
++      }
++      DBG(cdev, "usb_ep_autoconfig for sdb ep_out got %s\n", ep->name);
++      ep->driver_data = cdev;         /* claim the endpoint */
++      sdb_func->ep_out = ep;
++
++      /* now allocate requests for our endpoints */
++      req = sdb_request_new(sdb_func->ep_out, SDB_BULK_BUFFER_SIZE);
++      if (!req)
++              return -ENOMEM;
++      req->complete = sdb_complete_out;
++      dev->rx_req = req;
++
++      for (i = 0; i < SDB_TX_REQ_MAX; i++) {
++              req = sdb_request_new(sdb_func->ep_in, SDB_BULK_BUFFER_SIZE);
++              if (!req)
++                      goto fail;
++              req->complete = sdb_complete_in;
++              sdb_req_put(dev, &sdb_func->bulk_in_q, req);
++      }
++
++      return 0;
++
++fail:
++      while (!!(req = sdb_req_get(dev, &sdb_func->bulk_in_q)))
++              sdb_request_free(req, sdb_func->ep_in);
++
++      sdb_request_free(dev->rx_req, sdb_func->ep_out);
++      dev->rx_req = NULL;
++
++      if (sdb_func->ep_in)
++              sdb_func->ep_in->driver_data = NULL;
++      if (sdb_func->ep_out)
++              sdb_func->ep_out->driver_data = NULL;
++
++      printk(KERN_ERR "sdb_bind() could not allocate requests\n");
++      return -ENOMEM;
++}
++
++static ssize_t sdb_read(struct file *fp, char __user *buf,
++                              size_t count, loff_t *pos)
++{
++      struct sdb_dev *dev = fp->private_data;
++      int r = count, xfer;
++      int ret;
++
++      if (count > SDB_BULK_BUFFER_SIZE)
++              return -EINVAL;
++
++      if (_sdb_lock(&dev->read_excl))
++              return -EBUSY;
++
++      /* we will block until we're online */
++      while (!(dev->online || dev->error)) {
++              ret = wait_event_interruptible(dev->read_wq,
++                              (dev->online || dev->error));
++              if (ret < 0) {
++                      _sdb_unlock(&dev->read_excl);
++                      return ret;
++              }
++      }
++      if (dev->error) {
++              r = -EIO;
++              goto done;
++      }
++
++requeue_req:
++      /* queue a request */
++      mutex_lock(&sdb_lock);
++      if (!dev->sdb_func || !dev->rx_req)
++              ret = -ENODEV;
++      else {
++              dev->rx_req->length = count;
++              dev->rx_done = 0;
++              ret = usb_ep_queue(dev->sdb_func->ep_out,
++                              dev->rx_req, GFP_ATOMIC);
++      }
++      mutex_unlock(&sdb_lock);
++
++      if (ret < 0) {
++              r = -EIO;
++              dev->error = 1;
++              goto done;
++      }
++
++      /* wait for a request to complete */
++      ret = wait_event_interruptible(dev->read_wq, dev->rx_done);
++      if (ret < 0) {
++              dev->error = 1;
++              r = ret;
++              goto done;
++      }
++      if (!dev->error) {
++              /* If we got a 0-len packet, throw it back and try again. */
++              if (dev->rx_req->actual == 0)
++                      goto requeue_req;
++
++              mutex_lock(&sdb_lock);
++              if (!dev->sdb_func || !dev->rx_req)
++                      r = -ENODEV;
++              else {
++                      xfer = (dev->rx_req->actual < count)
++                                      ? dev->rx_req->actual : count;
++                      if (copy_to_user(buf, dev->rx_req->buf, xfer))
++                              r = -EFAULT;
++              }
++              mutex_unlock(&sdb_lock);
++      } else
++              r = -EIO;
++
++done:
++      _sdb_unlock(&dev->read_excl);
++      return r;
++}
++
++static ssize_t sdb_write(struct file *fp, const char __user *buf,
++                               size_t count, loff_t *pos)
++{
++      struct sdb_dev *dev = fp->private_data;
++      struct usb_request *req = 0;
++      int r = count, xfer;
++      int ret;
++
++      if (_sdb_lock(&dev->write_excl))
++              return -EBUSY;
++
++      while (count > 0) {
++              if (dev->error) {
++                      r = -EIO;
++                      break;
++              }
++
++              /* get an idle tx request to use */
++              req = 0;
++              ret = wait_event_interruptible(dev->write_wq,
++                              (!!(req = sdb_req_get(dev, dev->tx_idle))
++                               || dev->error));
++
++              if (ret < 0) {
++                      r = ret;
++                      break;
++              }
++
++              if (req != 0) {
++                      if (count > SDB_BULK_BUFFER_SIZE)
++                              xfer = SDB_BULK_BUFFER_SIZE;
++                      else
++                              xfer = count;
++
++                      mutex_lock(&sdb_lock);
++                      if (!dev->sdb_func) {
++                              mutex_unlock(&sdb_lock);
++                              r = -ENODEV;
++                              break;
++                      } else if (copy_from_user(req->buf, buf, xfer)) {
++                              mutex_unlock(&sdb_lock);
++                              r = -EFAULT;
++                              break;
++                      }
++
++                      req->length = xfer;
++                      ret = usb_ep_queue(dev->sdb_func->ep_in,
++                                      req, GFP_ATOMIC);
++                      mutex_unlock(&sdb_lock);
++
++                      if (ret < 0) {
++                              dev->error = 1;
++                              r = -EIO;
++                              break;
++                      }
++
++                      buf += xfer;
++                      count -= xfer;
++
++                      /* zero this so we don't try to free it on error exit */
++                      req = 0;
++              }
++      }
++
++      if (req)
++              sdb_req_put(dev, dev->tx_idle, req);
++
++      _sdb_unlock(&dev->write_excl);
++      return r;
++}
++
++static int sdb_open(struct inode *ip, struct file *fp)
++{
++      printk(KERN_INFO "sdb_open\n");
++      if (_sdb_lock(&_sdb_dev->open_excl))
++              return -EBUSY;
++
++      fp->private_data = _sdb_dev;
++
++      /* clear the error latch */
++      _sdb_dev->error = 0;
++
++      return 0;
++}
++
++static int sdb_release(struct inode *ip, struct file *fp)
++{
++      printk(KERN_INFO "sdb_release\n");
++
++      if (_sdb_dev != NULL)
++              _sdb_unlock(&_sdb_dev->open_excl);
++
++      return 0;
++}
++
++/* file operations for SDB device /dev/samsung_sdb */
++static const struct file_operations sdb_fops = {
++      .owner = THIS_MODULE,
++      .read = sdb_read,
++      .write = sdb_write,
++      .open = sdb_open,
++      .release = sdb_release,
++};
++
++static struct miscdevice sdb_device = {
++      .minor = MISC_DYNAMIC_MINOR,
++      .name = sdb_shortname,
++      .fops = &sdb_fops,
++};
++
++static int
++sdb_function_bind(struct usb_configuration *c, struct usb_function *f)
++{
++      struct usb_composite_dev *cdev = c->cdev;
++      struct f_sdb *sdb_func = func_to_sdb(f);
++      int                     id;
++      int                     ret;
++
++      DBG(cdev, "sdb_function_bind sdb_func: %p\n", sdb_func);
++
++      /* allocate interface ID(s) */
++      id = usb_interface_id(c, f);
++      if (id < 0)
++              return id;
++
++      sdb_func->inf_id = id;
++      sdb_interface_desc.bInterfaceNumber = id;
++
++      /* allocate endpoints */
++      ret = sdb_create_bulk_endpoints(sdb_func, &sdb_fullspeed_in_desc,
++                      &sdb_fullspeed_out_desc);
++      if (ret)
++              return ret;
++
++      f->fs_descriptors = usb_copy_descriptors(fs_sdb_descs);
++      if (!f->fs_descriptors)
++              goto desc_alloc_fail;
++
++      /* support high speed hardware */
++      if (gadget_is_dualspeed(cdev->gadget)) {
++              sdb_highspeed_in_desc.bEndpointAddress =
++                      sdb_fullspeed_in_desc.bEndpointAddress;
++              sdb_highspeed_out_desc.bEndpointAddress =
++                      sdb_fullspeed_out_desc.bEndpointAddress;
++
++              f->hs_descriptors = usb_copy_descriptors(hs_sdb_descs);
++              if (!f->hs_descriptors)
++                      goto desc_alloc_fail;
++      }
++
++      return 0;
++
++desc_alloc_fail:
++      if (f->fs_descriptors)
++              usb_free_descriptors(f->fs_descriptors);
++
++      return -ENOMEM;
++}
++
++static void
++sdb_function_unbind(struct usb_configuration *c, struct usb_function *f)
++{
++      struct sdb_dev *dev = _sdb_dev;
++      struct f_sdb *sdb_func = func_to_sdb(f);
++      struct usb_request *req;
++
++      dev->online = 0;
++      dev->error = 1;
++
++      if (gadget_is_dualspeed(c->cdev->gadget))
++              usb_free_descriptors(f->hs_descriptors);
++      usb_free_descriptors(f->fs_descriptors);
++
++      mutex_lock(&sdb_lock);
++
++      while (!!(req = sdb_req_get(dev, &sdb_func->bulk_in_q)))
++              sdb_request_free(req, sdb_func->ep_in);
++
++      sdb_request_free(dev->rx_req, sdb_func->ep_out);
++
++      kfree(sdb_func);
++      dev->sdb_func = NULL;
++      dev->rx_req = NULL;
++
++      mutex_unlock(&sdb_lock);
++
++      wake_up(&dev->read_wq);
++      wake_up(&dev->write_wq);
++}
++
++static int sdb_function_set_alt(struct usb_function *f,
++              unsigned intf, unsigned alt)
++{
++      struct f_sdb *sdb_func = func_to_sdb(f);
++      struct usb_composite_dev *cdev = f->config->cdev;
++      struct sdb_dev *dev = _sdb_dev;
++      int ret;
++
++      if (sdb_func->inf_id != intf) {
++              printk(KERN_ERR "sdb_function_set_alt error wrong intf:%d alt:%d\n",
++                                              intf, alt);
++              return -EINVAL;
++      }
++
++      if (sdb_func->ep_in->driver_data)
++              usb_ep_disable(sdb_func->ep_in);
++      else if (config_ep_by_speed(cdev->gadget, f, sdb_func->ep_in))
++              return -EINVAL;
++
++      ret = usb_ep_enable(sdb_func->ep_in);
++      if (ret) {
++              printk(KERN_ERR "error, usb_ep_enable for sdb ep_in\n");
++              return ret;
++      }
++      sdb_func->ep_in->driver_data = sdb_func;
++
++      if (sdb_func->ep_out->driver_data)
++              usb_ep_disable(sdb_func->ep_out);
++      else if (config_ep_by_speed(cdev->gadget, f, sdb_func->ep_out)) {
++              usb_ep_disable(sdb_func->ep_in);
++              sdb_func->ep_in->driver_data = NULL;
++              return -EINVAL;
++      }
++
++      ret = usb_ep_enable(sdb_func->ep_out);
++      if (ret) {
++              usb_ep_disable(sdb_func->ep_in);
++              sdb_func->ep_in->driver_data = NULL;
++              printk(KERN_ERR "error, usb_ep_enable for sdb ep_out\n");
++              return ret;
++      }
++      sdb_func->ep_out->driver_data = sdb_func;
++
++      dev->tx_idle = &sdb_func->bulk_in_q;
++      dev->sdb_func = sdb_func;
++      dev->online = 1;
++
++      /* readers may be blocked waiting for us to go online */
++      wake_up(&dev->read_wq);
++      return 0;
++}
++
++static void sdb_function_disable(struct usb_function *f)
++{
++      struct sdb_dev *dev = _sdb_dev;
++      struct f_sdb *sdb_func = func_to_sdb(f);
++
++      dev->online = 0;
++      dev->error = 1;
++
++      spin_lock(&dev->lock);
++      dev->tx_idle = NULL;
++      spin_unlock(&dev->lock);
++
++      usb_ep_disable(sdb_func->ep_in);
++      sdb_func->ep_in->driver_data = NULL;
++
++      usb_ep_disable(sdb_func->ep_out);
++      sdb_func->ep_out->driver_data = NULL;
++
++      /* readers may be blocked waiting for us to go online */
++      wake_up(&dev->read_wq);
++      wake_up(&dev->write_wq);
++}
++
++static int sdb_setup(struct usb_composite_dev *cdev)
++{
++      struct sdb_dev *dev;
++      int ret;
++
++      printk(KERN_INFO "sdb_bind_config\n");
++
++      dev = kzalloc(sizeof(*dev), GFP_KERNEL);
++      if (!dev)
++              return -ENOMEM;
++
++      if (sdb_string_defs[F_SDB_IDX].id == 0) {
++              ret = usb_string_id(cdev);
++              if (ret < 0) {
++                      kfree(dev);
++                      return ret;
++              }
++              sdb_string_defs[F_SDB_IDX].id = ret;
++              sdb_interface_desc.iInterface = ret;
++      }
++
++      spin_lock_init(&dev->lock);
++
++      init_waitqueue_head(&dev->read_wq);
++      init_waitqueue_head(&dev->write_wq);
++
++      atomic_set(&dev->open_excl, 0);
++      atomic_set(&dev->read_excl, 0);
++      atomic_set(&dev->write_excl, 0);
++
++
++      /* _sdb_dev must be set before calling usb_gadget_register_driver */
++      _sdb_dev = dev;
++
++      ret = misc_register(&sdb_device);
++      if (ret)
++              goto err1;
++
++      return 0;
++
++err1:
++      kfree(dev);
++      _sdb_dev = NULL;
++      printk(KERN_ERR "sdb gadget driver failed to initialize\n");
++      return ret;
++}
++
++static int sdb_bind_config(struct usb_configuration *c)
++{
++      int ret;
++      struct f_sdb *sdb_func;
++
++      if (!_sdb_dev) {
++              printk(KERN_ERR "Error There is no _sdb_dev!!\n");
++              return -ENODEV;
++      }
++
++      sdb_func = kzalloc(sizeof(*sdb_func), GFP_KERNEL);
++      if (!sdb_func) {
++              printk(KERN_ERR "sdb_func memory alloc failed !!!\n");
++              return -ENOMEM;
++      }
++
++      INIT_LIST_HEAD(&sdb_func->bulk_in_q);
++
++      sdb_func->function.name = "sdb";
++      sdb_func->function.strings = sdb_strings;
++      sdb_func->function.bind = sdb_function_bind;
++      sdb_func->function.unbind = sdb_function_unbind;
++      sdb_func->function.set_alt = sdb_function_set_alt;
++      sdb_func->function.disable = sdb_function_disable;
++
++      ret = usb_add_function(c, &sdb_func->function);
++      if (ret)
++              printk(KERN_ERR "Error in usb_add_function failed for sdb\n");
++
++      return ret;
++}
++
++static void sdb_cleanup(void)
++{
++      struct sdb_dev  *dev = _sdb_dev;
++
++      misc_deregister(&sdb_device);
++
++      if (!dev)
++              return;
++      _sdb_dev = NULL;
++      kfree(dev);
++}
+diff --git a/drivers/usb/gadget/slp.c b/drivers/usb/gadget/slp.c
+new file mode 100644
+index 0000000..6a22cf9
+--- /dev/null
++++ b/drivers/usb/gadget/slp.c
+@@ -0,0 +1,1365 @@
++/*
++ * Gadget Driver for SLP based on Android
++ *
++ * Copyright (C) 2008 Google, Inc.
++ * Author: Mike Lockwood <lockwood@android.com>
++ * Modified : Yongsul Oh <yongsul96.oh@samsung.com>
++ *
++ * Heavily based on android.c
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++/* #define DEBUG */
++/* #define VERBOSE_DEBUG */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/fs.h>
++
++#include <linux/delay.h>
++#include <linux/kernel.h>
++#include <linux/utsname.h>
++#include <linux/platform_device.h>
++#include <linux/mutex.h>
++
++#include <linux/usb/ch9.h>
++#include <linux/usb/composite.h>
++#include <linux/usb/gadget.h>
++#include <asm/system_info.h>
++#include <linux/pm_qos.h>
++#include <linux/workqueue.h>
++
++#include "gadget_chips.h"
++
++/*
++ * Kbuild is not very cooperative with respect to linking separately
++ * compiled library objects into one module.  So for now we won't use
++ * separate compilation ... ensuring init/exit sections work to shrink
++ * the runtime footprint, and giving us at least some parts of what
++ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
++ */
++
++#include "f_sdb.c"
++#include "f_acm.c"
++#define USB_ETH_RNDIS y
++#define USB_FRNDIS_INCLUDED y
++#include "f_rndis.c"
++#include "rndis.c"
++#include "u_ether.c"
++
++#define USB_MODE_VERSION      "1.1"
++
++MODULE_AUTHOR("Yongsul Oh <yongsul96.oh@samsung.com>");
++MODULE_DESCRIPTION("SLP Composite USB Driver similar to Android Compiste");
++MODULE_LICENSE("GPL");
++MODULE_VERSION(USB_MODE_VERSION);
++
++static const char slp_longname[] = "Gadget SLP";
++
++/* Default vendor and product IDs, overridden by userspace */
++#define VENDOR_ID             0x04E8  /* Samsung VID */
++#define PRODUCT_ID            0x6860  /* KIES mode PID */
++
++/* DM_PORT NUM : /dev/ttyGS* port number */
++#define DM_PORT_NUM            1
++
++/* Moved from include/linux/usb/slp_multi.h */
++enum slp_multi_config_id {
++      USB_CONFIGURATION_1 = 1,
++      USB_CONFIGURATION_2 = 2,
++      USB_CONFIGURATION_DUAL = 0xFF,
++};
++
++struct slp_multi_func_data {
++      const char *name;
++      enum slp_multi_config_id usb_config_id;
++};
++
++struct slp_multi_usb_function {
++      char *name;
++      void *config;
++
++      struct device *dev;
++      char *dev_name;
++      struct device_attribute **attributes;
++
++      /* for slp_multi_dev.funcs_fconf */
++      struct list_head fconf_list;
++
++      /* for slp_multi_dev.funcs_sconf */
++      struct list_head sconf_list;
++
++      /* for slp_multi_dev.available_functions */
++      struct list_head available_list;
++
++      /* Manndatory: initialization during gadget bind */
++      int (*init) (struct slp_multi_usb_function *,
++                                      struct usb_composite_dev *);
++      /* Optional: cleanup during gadget unbind */
++      void (*cleanup) (struct slp_multi_usb_function *);
++      /* Optional: called when the function is added the list of
++       *              enabled functions */
++      void (*enable)(struct slp_multi_usb_function *);
++      /* Optional: called when it is removed */
++      void (*disable)(struct slp_multi_usb_function *);
++
++      /* Mandatory: called when the usb enabled */
++      int (*bind_config) (struct slp_multi_usb_function *,
++                          struct usb_configuration *);
++      /* Optional: called when the configuration is removed */
++      void (*unbind_config) (struct slp_multi_usb_function *,
++                             struct usb_configuration *);
++      /* Optional: handle ctrl requests before the device is configured */
++      int (*ctrlrequest) (struct slp_multi_usb_function *,
++                          struct usb_composite_dev *,
++                          const struct usb_ctrlrequest *);
++};
++
++struct slp_multi_dev {
++      struct list_head available_functions;
++
++      /* for each configuration control */
++      struct list_head funcs_fconf;
++      struct list_head funcs_sconf;
++
++      struct usb_composite_dev *cdev;
++      struct device *dev;
++
++      bool enabled;
++      bool dual_config;
++      int disable_depth;
++      struct mutex mutex;
++      bool connected;
++      bool sw_connected;
++
++      /* to check USB suspend/resume */
++      unsigned int suspended:1;
++
++      /* to control DMA QOS */
++      char pm_qos[5];
++      s32 swfi_latency;
++      s32 curr_latency;
++      struct pm_qos_request pm_qos_req_dma;
++      struct work_struct qos_work;
++      char ffs_aliases[256];
++};
++
++/* TODO: only enabled 'rndis' and 'sdb'. need to verify more functions */
++static const char *default_funcs[] = {"rndis", "sdb"};
++static unsigned slp_multi_nluns;
++static struct class *slp_multi_class;
++static struct slp_multi_dev *_slp_multi_dev;
++static int slp_multi_bind_config(struct usb_configuration *c);
++static void slp_multi_unbind_config(struct usb_configuration *c);
++
++/* string IDs are assigned dynamically */
++#define STRING_MANUFACTURER_IDX               0
++#define STRING_PRODUCT_IDX            1
++#define STRING_SERIAL_IDX             2
++
++static char manufacturer_string[256];
++static char product_string[256];
++static char serial_string[256];
++
++/* String Table */
++static struct usb_string strings_dev[] = {
++      [STRING_MANUFACTURER_IDX].s = manufacturer_string,
++      [STRING_PRODUCT_IDX].s = product_string,
++      [STRING_SERIAL_IDX].s = serial_string,
++      {}                      /* end of list */
++};
++
++static struct usb_gadget_strings stringtab_dev = {
++      .language = 0x0409,     /* en-us */
++      .strings = strings_dev,
++};
++
++static struct usb_gadget_strings *slp_dev_strings[] = {
++      &stringtab_dev,
++      NULL,
++};
++
++static struct usb_device_descriptor device_desc = {
++      .bLength                = sizeof(device_desc),
++      .bDescriptorType        = USB_DT_DEVICE,
++      .bcdUSB                 = __constant_cpu_to_le16(0x0200),
++      .bDeviceClass           = USB_CLASS_PER_INTERFACE,
++      .idVendor               = __constant_cpu_to_le16(VENDOR_ID),
++      .idProduct              = __constant_cpu_to_le16(PRODUCT_ID),
++      .bcdDevice              = __constant_cpu_to_le16(0xffff),
++      .bNumConfigurations     = 1,
++};
++
++static struct usb_configuration first_config_driver = {
++      .label                  = "slp_first_config",
++      .unbind                 = slp_multi_unbind_config,
++      .bConfigurationValue    = USB_CONFIGURATION_1,
++      .bmAttributes           = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
++      .MaxPower               = 0x30, /* 96ma */
++};
++
++static struct usb_configuration second_config_driver = {
++      .label                  = "slp_second_config",
++      .unbind                 = slp_multi_unbind_config,
++      .bConfigurationValue    = USB_CONFIGURATION_2,
++      .bmAttributes           = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
++      .MaxPower               = 0x30, /* 96ma */
++};
++
++/*-------------------------------------------------------------------------*/
++/* Supported functions initialization */
++
++static int sdb_function_init(struct slp_multi_usb_function *f,
++                           struct usb_composite_dev *cdev)
++{
++      return sdb_setup(cdev);
++}
++
++static void sdb_function_cleanup(struct slp_multi_usb_function *f)
++{
++      sdb_cleanup();
++}
++
++static int sdb_function_bind_config(struct slp_multi_usb_function *f,
++                                  struct usb_configuration *c)
++{
++      return sdb_bind_config(c);
++}
++
++static struct slp_multi_usb_function sdb_function = {
++      .name = "sdb",
++      .init = sdb_function_init,
++      .cleanup = sdb_function_cleanup,
++      .bind_config = sdb_function_bind_config,
++};
++
++#define MAX_ACM_INSTANCES 4
++struct acm_function_config {
++      int instances;
++      int instances_on;
++      struct usb_function *f_acm[MAX_ACM_INSTANCES];
++      struct usb_function_instance *f_acm_inst[MAX_ACM_INSTANCES];
++};
++
++static int
++acm_function_init(struct slp_multi_usb_function *f,
++                struct usb_composite_dev *cdev)
++{
++      int i;
++      int ret;
++      struct acm_function_config *config;
++
++      config = kzalloc(sizeof(struct acm_function_config), GFP_KERNEL);
++      if (!config)
++              return -ENOMEM;
++      f->config = config;
++
++      for (i = 0; i < MAX_ACM_INSTANCES; i++) {
++              config->f_acm_inst[i] = usb_get_function_instance("acm");
++              if (IS_ERR(config->f_acm_inst[i])) {
++                      ret = PTR_ERR(config->f_acm_inst[i]);
++                      goto err_usb_get_function_instance;
++              }
++              config->f_acm[i] = usb_get_function(config->f_acm_inst[i]);
++              if (IS_ERR(config->f_acm[i])) {
++                      ret = PTR_ERR(config->f_acm[i]);
++                      goto err_usb_get_function;
++              }
++      }
++      return 0;
++err_usb_get_function_instance:
++      while (i-- > 0) {
++              usb_put_function(config->f_acm[i]);
++err_usb_get_function:
++              usb_put_function_instance(config->f_acm_inst[i]);
++      }
++      return ret;
++}
++
++static void acm_function_cleanup(struct slp_multi_usb_function *f)
++{
++      int i;
++      struct acm_function_config *config = f->config;
++
++      for (i = 0; i < MAX_ACM_INSTANCES; i++) {
++              usb_put_function(config->f_acm[i]);
++              usb_put_function_instance(config->f_acm_inst[i]);
++      }
++      kfree(f->config);
++      f->config = NULL;
++}
++
++static int
++acm_function_bind_config(struct slp_multi_usb_function *f,
++                       struct usb_configuration *c)
++{
++      int i;
++      int ret = 0;
++      struct acm_function_config *config = f->config;
++
++      config->instances_on = config->instances;
++      for (i = 0; i < config->instances_on; i++) {
++              ret = usb_add_function(c, config->f_acm[i]);
++              if (ret) {
++                      pr_err("Could not bind acm%u config\n", i);
++                      goto err_usb_add_function;
++              }
++      }
++
++      return 0;
++
++err_usb_add_function:
++      while (i-- > 0)
++              usb_remove_function(c, config->f_acm[i]);
++      return ret;
++}
++
++static void acm_function_unbind_config(struct slp_multi_usb_function *f,
++                                     struct usb_configuration *c)
++{
++      int i;
++      struct acm_function_config *config = f->config;
++
++      for (i = 0; i < config->instances_on; i++)
++              usb_remove_function(c, config->f_acm[i]);
++}
++
++static ssize_t acm_instances_show(struct device *dev,
++                                struct device_attribute *attr, char *buf)
++{
++      struct slp_multi_usb_function *f = dev_get_drvdata(dev);
++      struct acm_function_config *config = f->config;
++      return sprintf(buf, "%d\n", config->instances);
++}
++
++static ssize_t acm_instances_store(struct device *dev,
++                                 struct device_attribute *attr,
++                                 const char *buf, size_t size)
++{
++      struct slp_multi_usb_function *f = dev_get_drvdata(dev);
++      struct acm_function_config *config = f->config;
++      int value;
++
++      sscanf(buf, "%d", &value);
++      if (value > MAX_ACM_INSTANCES)
++              value = MAX_ACM_INSTANCES;
++      config->instances = value;
++      return size;
++}
++
++static DEVICE_ATTR(instances, S_IRUGO | S_IWUSR, acm_instances_show,
++                                               acm_instances_store);
++static struct device_attribute *acm_function_attributes[] = {
++      &dev_attr_instances,
++      NULL
++};
++
++static struct slp_multi_usb_function acm_function = {
++      .name           = "acm",
++      .init           = acm_function_init,
++      .cleanup        = acm_function_cleanup,
++      .bind_config    = acm_function_bind_config,
++      .unbind_config  = acm_function_unbind_config,
++      .attributes     = acm_function_attributes,
++};
++
++struct rndis_function_config {
++      u8 ethaddr[ETH_ALEN];
++      u32 vendorID;
++      char manufacturer[256];
++      bool wceis;
++      u8 rndis_string_defs0_id;
++      struct eth_dev *edev;
++};
++static char host_addr_string[18];
++
++static int rndis_function_init(struct slp_multi_usb_function *f,
++                             struct usb_composite_dev *cdev)
++{
++      struct rndis_function_config *config;
++      int status, i;
++
++      config = kzalloc(sizeof(struct rndis_function_config), GFP_KERNEL);
++      if (!config)
++              return -ENOMEM;
++
++      /* maybe allocate device-global string IDs */
++      if (rndis_string_defs[0].id == 0) {
++
++              /* control interface label */
++              status = usb_string_id(cdev);
++              if (status < 0)
++                      goto rndis_init_error;
++              config->rndis_string_defs0_id = status;
++              rndis_string_defs[0].id = status;
++              rndis_control_intf.iInterface = status;
++
++              /* data interface label */
++              status = usb_string_id(cdev);
++              if (status < 0)
++                      goto rndis_init_error;
++              rndis_string_defs[1].id = status;
++              rndis_data_intf.iInterface = status;
++
++              /* IAD iFunction label */
++              status = usb_string_id(cdev);
++              if (status < 0)
++                      goto rndis_init_error;
++              rndis_string_defs[2].id = status;
++              rndis_iad_descriptor.iFunction = status;
++      }
++
++      /* create a fake MAC address from our serial number. */
++      for (i = 0; (i < 256) && serial_string[i]; i++) {
++              /* XOR the USB serial across the remaining bytes */
++              config->ethaddr[i % (ETH_ALEN - 1) + 1] ^= serial_string[i];
++      }
++      config->ethaddr[0] &= 0xfe;     /* clear multicast bit */
++      config->ethaddr[0] |= 0x02;     /* set local assignment bit (IEEE802) */
++
++      snprintf(host_addr_string, sizeof(host_addr_string),
++              "%02x:%02x:%02x:%02x:%02x:%02x",
++              config->ethaddr[0],     config->ethaddr[1],
++              config->ethaddr[2],     config->ethaddr[3],
++              config->ethaddr[4], config->ethaddr[5]);
++
++      f->config = config;
++      return 0;
++
++ rndis_init_error:
++      kfree(config);
++      return status;
++}
++
++static void rndis_function_cleanup(struct slp_multi_usb_function *f)
++{
++      kfree(f->config);
++      f->config = NULL;
++}
++
++static int rndis_function_bind_config(struct slp_multi_usb_function *f,
++                                    struct usb_configuration *c)
++{
++      int ret = -EINVAL;
++      struct rndis_function_config *rndis = f->config;
++
++      if (!rndis) {
++              dev_err(f->dev, "error rndis_pdata is null\n");
++              return ret;
++      }
++
++      rndis->edev = gether_setup(c->cdev->gadget, rndis->ethaddr,
++                                 host_addr_string, rndis->ethaddr,
++                                 QMULT_DEFAULT);
++      if (IS_ERR(rndis->edev)) {
++              dev_err(f->dev, "gether_setup failed\n");
++              return ret;
++      }
++
++      if (rndis->wceis) {
++              /* "Wireless" RNDIS; auto-detected by Windows */
++              rndis_iad_descriptor.bFunctionClass =
++                  USB_CLASS_WIRELESS_CONTROLLER;
++              rndis_iad_descriptor.bFunctionSubClass = 0x01;
++              rndis_iad_descriptor.bFunctionProtocol = 0x03;
++              rndis_control_intf.bInterfaceClass =
++                  USB_CLASS_WIRELESS_CONTROLLER;
++              rndis_control_intf.bInterfaceSubClass = 0x01;
++              rndis_control_intf.bInterfaceProtocol = 0x03;
++      }
++
++      /* ... and setup RNDIS itself */
++      ret = rndis_init();
++      if (ret < 0) {
++              dev_err(f->dev, "rndis_init failed(ret:%d)\n", ret);
++              gether_cleanup(rndis->edev);
++              return ret;
++      }
++
++      /* Android team reset "rndis_string_defs[0].id" when RNDIS unbinded
++       * in f_rndis.c but, that makes failure of rndis_bind_config() by
++       * the overflow of "next_string_id" value in usb_string_id().
++       * So, Android team also reset "next_string_id" value in android.c
++       * but SLP does not reset "next_string_id" value. And we decided to
++       * re-update "rndis_string_defs[0].id" by old value.
++       * 20120224 yongsul96.oh@samsung.com
++       */
++      if (rndis_string_defs[0].id == 0)
++              rndis_string_defs[0].id = rndis->rndis_string_defs0_id;
++
++      ret = rndis_bind_config_vendor(c, rndis->ethaddr, rndis->vendorID,
++                               rndis->manufacturer, rndis->edev);
++      if (ret) {
++              rndis_exit();
++              gether_cleanup(rndis->edev);
++              dev_err(f->dev, "rndis_bind_config failed(ret:%d)\n", ret);
++      }
++
++      return ret;
++}
++
++static void rndis_function_unbind_config(struct slp_multi_usb_function *f,
++                                       struct usb_configuration *c)
++{
++      struct rndis_function_config *rndis = f->config;
++      gether_cleanup(rndis->edev);
++}
++
++static ssize_t rndis_manufacturer_show(struct device *dev,
++                                     struct device_attribute *attr, char *buf)
++{
++      struct slp_multi_usb_function *f = dev_get_drvdata(dev);
++      struct rndis_function_config *config = f->config;
++      return snprintf(buf, PAGE_SIZE, "%s\n", config->manufacturer);
++}
++
++static ssize_t rndis_manufacturer_store(struct device *dev,
++                                      struct device_attribute *attr,
++                                      const char *buf, size_t size)
++{
++      struct slp_multi_usb_function *f = dev_get_drvdata(dev);
++      struct rndis_function_config *config = f->config;
++
++      if ((size >= sizeof(config->manufacturer)) ||
++              (sscanf(buf, "%s", config->manufacturer) != 1))
++              return -EINVAL;
++
++      return size;
++}
++
++static DEVICE_ATTR(manufacturer, S_IRUGO | S_IWUSR, rndis_manufacturer_show,
++                 rndis_manufacturer_store);
++
++static ssize_t rndis_wceis_show(struct device *dev,
++                              struct device_attribute *attr, char *buf)
++{
++      struct slp_multi_usb_function *f = dev_get_drvdata(dev);
++      struct rndis_function_config *config = f->config;
++      return snprintf(buf, PAGE_SIZE, "%d\n", config->wceis);
++}
++
++static ssize_t rndis_wceis_store(struct device *dev,
++                               struct device_attribute *attr, const char *buf,
++                               size_t size)
++{
++      struct slp_multi_usb_function *f = dev_get_drvdata(dev);
++      struct rndis_function_config *config = f->config;
++      int value;
++
++      if (sscanf(buf, "%d", &value) == 1) {
++              config->wceis = value;
++              return size;
++      }
++      return -EINVAL;
++}
++
++static DEVICE_ATTR(wceis, S_IRUGO | S_IWUSR, rndis_wceis_show,
++                 rndis_wceis_store);
++
++static ssize_t rndis_ethaddr_show(struct device *dev,
++                                struct device_attribute *attr, char *buf)
++{
++      struct slp_multi_usb_function *f = dev_get_drvdata(dev);
++      struct rndis_function_config *rndis = f->config;
++      return snprintf(buf, PAGE_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++                     rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2],
++                     rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]);
++}
++
++static DEVICE_ATTR(ethaddr, S_IRUGO, rndis_ethaddr_show,
++                 NULL);
++
++static ssize_t rndis_vendorID_show(struct device *dev,
++                                 struct device_attribute *attr, char *buf)
++{
++      struct slp_multi_usb_function *f = dev_get_drvdata(dev);
++      struct rndis_function_config *config = f->config;
++      return snprintf(buf, PAGE_SIZE, "%04x\n", config->vendorID);
++}
++
++static ssize_t rndis_vendorID_store(struct device *dev,
++                                  struct device_attribute *attr,
++                                  const char *buf, size_t size)
++{
++      struct slp_multi_usb_function *f = dev_get_drvdata(dev);
++      struct rndis_function_config *config = f->config;
++      int value;
++
++      if (sscanf(buf, "%04x", &value) == 1) {
++              config->vendorID = value;
++              return size;
++      }
++      return -EINVAL;
++}
++
++static DEVICE_ATTR(vendorID, S_IRUGO | S_IWUSR, rndis_vendorID_show,
++                 rndis_vendorID_store);
++
++static struct device_attribute *rndis_function_attributes[] = {
++      &dev_attr_manufacturer,
++      &dev_attr_wceis,
++      &dev_attr_ethaddr,
++      &dev_attr_vendorID,
++      NULL
++};
++
++static struct slp_multi_usb_function rndis_function = {
++      .name = "rndis",
++      .init = rndis_function_init,
++      .cleanup = rndis_function_cleanup,
++      .bind_config = rndis_function_bind_config,
++      .unbind_config = rndis_function_unbind_config,
++      .attributes = rndis_function_attributes,
++};
++
++/*-------------------------------------------------------------------------*/
++/* Supported functions initialization */
++
++static struct slp_multi_usb_function *supported_functions[] = {
++      &sdb_function,
++      &acm_function,
++      &rndis_function,
++      NULL,
++};
++
++static void slp_multi_qos_work(struct work_struct *data)
++{
++      struct slp_multi_dev *smdev =
++              container_of(data, struct slp_multi_dev, qos_work);
++
++      if (smdev->suspended) {
++              if (smdev->curr_latency != PM_QOS_DEFAULT_VALUE) {
++                      smdev->curr_latency = PM_QOS_DEFAULT_VALUE;
++                      pm_qos_update_request(&smdev->pm_qos_req_dma,
++                              PM_QOS_DEFAULT_VALUE);
++                      dev_info(smdev->dev, "usb suspended, set default qos\n");
++              }
++      } else {
++              if ((smdev->swfi_latency != PM_QOS_DEFAULT_VALUE) &&
++                      !(strncmp(smdev->pm_qos, "high", 4)) &&
++                      (smdev->curr_latency == PM_QOS_DEFAULT_VALUE)) {
++                      smdev->curr_latency = smdev->swfi_latency;
++                      pm_qos_update_request(&smdev->pm_qos_req_dma,
++                              smdev->swfi_latency);
++                      dev_info(smdev->dev, "usb resumed, set high qos\n");
++              }
++      }
++}
++
++static int slp_multi_init_functions(struct slp_multi_dev *smdev,
++                                struct usb_composite_dev *cdev)
++{
++      struct slp_multi_usb_function *f;
++      struct device_attribute **attrs;
++      struct device_attribute *attr;
++      int err = 0;
++      int index = 0;
++
++      list_for_each_entry(f, &smdev->available_functions, available_list) {
++              f->dev_name = kasprintf(GFP_KERNEL, "f_%s", f->name);
++              f->dev = device_create(slp_multi_class, smdev->dev,
++                                     MKDEV(0, index++), f, f->dev_name);
++              if (IS_ERR(f->dev)) {
++                      dev_err(smdev->dev,
++                              "Failed to create dev %s", f->dev_name);
++                      err = PTR_ERR(f->dev);
++                      goto init_func_err_create;
++              }
++
++              if (f->init) {
++                      err = f->init(f, cdev);
++                      if (err) {
++                              dev_err(smdev->dev,
++                                      "Failed to init %s", f->name);
++                              goto init_func_err_out;
++                      }
++              }
++
++              attrs = f->attributes;
++              if (attrs) {
++                      while ((attr = *attrs++) && !err)
++                              err = device_create_file(f->dev, attr);
++              }
++              if (err) {
++                      dev_err(f->dev, "Failed to create function %s attributes",
++                             f->name);
++                      goto init_func_err_out;
++              }
++      }
++      return 0;
++
++ init_func_err_out:
++      device_destroy(slp_multi_class, f->dev->devt);
++ init_func_err_create:
++      kfree(f->dev_name);
++      return err;
++}
++
++static void slp_multi_cleanup_functions(struct slp_multi_dev *smdev)
++{
++      struct slp_multi_usb_function *f;
++
++      list_for_each_entry(f, &smdev->available_functions, available_list) {
++              if (f->dev) {
++                      device_destroy(slp_multi_class, f->dev->devt);
++                      kfree(f->dev_name);
++              }
++
++              if (f->cleanup)
++                      f->cleanup(f);
++      }
++}
++
++static int
++slp_multi_bind_enabled_functions(struct slp_multi_dev *smdev,
++                             struct usb_configuration *c)
++{
++      struct slp_multi_usb_function *f;
++      int ret;
++
++      if (c->bConfigurationValue == USB_CONFIGURATION_1) {
++              list_for_each_entry(f, &smdev->funcs_fconf, fconf_list) {
++                      dev_dbg(smdev->dev, "usb_bind_conf(1st) f:%s\n",
++                              f->name);
++                      ret = f->bind_config(f, c);
++                      if (ret) {
++                              dev_err(smdev->dev, "%s bind_conf(1st) failed\n",
++                                      f->name);
++                              return ret;
++                      }
++              }
++      } else if (c->bConfigurationValue == USB_CONFIGURATION_2) {
++              list_for_each_entry(f, &smdev->funcs_sconf, sconf_list) {
++                      dev_dbg(smdev->dev, "usb_bind_conf(2nd) f:%s\n",
++                              f->name);
++                      ret = f->bind_config(f, c);
++                      if (ret) {
++                              dev_err(smdev->dev, "%s bind_conf(2nd) failed\n",
++                                      f->name);
++                              return ret;
++                      }
++              }
++      } else {
++              dev_err(smdev->dev, "Not supported configuraton(%d)\n",
++                      c->bConfigurationValue);
++              return -EINVAL;
++      }
++      return 0;
++}
++
++static void
++slp_multi_unbind_enabled_functions(struct slp_multi_dev *smdev,
++                               struct usb_configuration *c)
++{
++      struct slp_multi_usb_function *f;
++
++      if (c->bConfigurationValue == USB_CONFIGURATION_1) {
++              list_for_each_entry(f, &smdev->funcs_fconf, fconf_list) {
++                      if (f->unbind_config)
++                              f->unbind_config(f, c);
++              }
++      } else if (c->bConfigurationValue == USB_CONFIGURATION_2) {
++              list_for_each_entry(f, &smdev->funcs_sconf, sconf_list) {
++                      if (f->unbind_config)
++                              f->unbind_config(f, c);
++              }
++      }
++}
++
++#define ADD_FUNCS_LIST(head, member)  \
++static inline int add_##member(struct slp_multi_dev *smdev, char *name)       \
++{     \
++      struct slp_multi_usb_function *av_f, *en_f;     \
++      \
++      dev_dbg(smdev->dev, "usb: name=%s\n", name);    \
++      list_for_each_entry(av_f, &smdev->available_functions,  \
++                      available_list) {       \
++              if (!strcmp(name, av_f->name)) {        \
++                      list_for_each_entry(en_f, &smdev->head, \
++                                      member) {       \
++                              if (av_f == en_f) {     \
++                                      dev_info(smdev->dev, \
++                                              "usb:%s already enabled!\n", \
++                                              name);  \
++                                      return 0;       \
++                              }       \
++                      }       \
++                      list_add_tail(&av_f->member, &smdev->head);     \
++                      return 0;       \
++              }       \
++      }       \
++      return -EINVAL; \
++}     \
++static ssize_t        show_##head(struct device *pdev,        \
++                      struct device_attribute *attr, char *buf)       \
++{     \
++      struct slp_multi_dev *smdev = dev_get_drvdata(pdev);    \
++      struct slp_multi_usb_function *f;       \
++      char *buff = buf;       \
++      \
++      list_for_each_entry(f, &smdev->head, member) {  \
++              dev_dbg(pdev, "usb: enabled_func=%s\n", \
++                     f->name);        \
++              buff += snprintf(buff, PAGE_SIZE, "%s,", f->name);      \
++      }       \
++      if (buff != buf)        \
++              *(buff - 1) = '\n';     \
++      \
++      return buff - buf;      \
++}     \
++static ssize_t store_##head(struct device *pdev,      \
++              struct device_attribute *attr,  \
++              const char *buff, size_t size)  \
++{     \
++      struct slp_multi_dev *smdev = dev_get_drvdata(pdev);    \
++      char *name;     \
++      char buf[256], *b;      \
++      int err;        \
++      \
++      if (smdev->enabled) {   \
++              dev_info(pdev, "can't change usb functions"     \
++                      "(already enabled)!!\n");       \
++              return -EBUSY;  \
++      }       \
++      \
++      INIT_LIST_HEAD(&smdev->head);   \
++      \
++      dev_dbg(pdev, "usb: buff=%s\n", buff);  \
++      strlcpy(buf, buff, sizeof(buf));        \
++      b = strim(buf); \
++      \
++      while (b) {     \
++              name = strsep(&b, ","); \
++              if (name) {     \
++                      err = add_##member(smdev, name);        \
++                      if (err)        \
++                              dev_err(pdev, \
++                                      "slp_multi_usb: Cannot enable '%s'", \
++                                      name); \
++              }       \
++      }       \
++      \
++      return size;    \
++}     \
++static DEVICE_ATTR(head, S_IRUGO | S_IWUSR, show_##head, store_##head);
++
++ADD_FUNCS_LIST(funcs_fconf, fconf_list)
++ADD_FUNCS_LIST(funcs_sconf, sconf_list)
++
++/*-------------------------------------------------------------------------*/
++/* /sys/class/usb_mode/usb%d/ interface */
++
++static ssize_t pm_qos_show(struct device *pdev,
++                         struct device_attribute *attr, char *buf)
++{
++      struct slp_multi_dev *smdev = dev_get_drvdata(pdev);
++
++      return snprintf(buf, PAGE_SIZE, "%s\n", smdev->pm_qos);
++}
++
++static ssize_t pm_qos_store(struct device *pdev,
++                         struct device_attribute *attr,
++                         const char *buff, size_t size)
++{
++      struct slp_multi_dev *smdev = dev_get_drvdata(pdev);
++
++      if (smdev->enabled) {
++              dev_info(pdev, "Already usb enabled, can't change qos\n");
++              return -EBUSY;
++      }
++
++      strlcpy(smdev->pm_qos, buff, sizeof(smdev->pm_qos));
++      return size;
++}
++
++static DEVICE_ATTR(pm_qos, S_IRUGO | S_IWUSR, pm_qos_show, pm_qos_store);
++
++static ssize_t enable_show(struct device *pdev,
++                         struct device_attribute *attr, char *buf)
++{
++      struct slp_multi_dev *smdev = dev_get_drvdata(pdev);
++      dev_dbg(pdev, "usb: smdev->enabled=%d\n", smdev->enabled);
++      return snprintf(buf, PAGE_SIZE, "%d\n", smdev->enabled);
++}
++
++static ssize_t enable_store(struct device *pdev, struct device_attribute *attr,
++                          const char *buff, size_t size)
++{
++      struct slp_multi_dev *smdev = dev_get_drvdata(pdev);
++      struct usb_composite_dev *cdev = smdev->cdev;
++      int enabled;
++      int ret = 0;
++
++      if (sysfs_streq(buff, "1"))
++              enabled = 1;
++      else if (sysfs_streq(buff, "0"))
++              enabled = 0;
++      else {
++              dev_err(pdev, "Invalid cmd %c%c..", *buff, *(buff+1));
++              return -EINVAL;
++      }
++
++      dev_dbg(pdev, "usb: %s enabled=%d, !smdev->enabled=%d\n",
++             __func__, enabled, !smdev->enabled);
++
++      mutex_lock(&smdev->mutex);
++
++      if (enabled && !smdev->enabled) {
++              struct slp_multi_usb_function *f;
++
++              /* update values in composite driver's
++               * copy of device descriptor
++               */
++              cdev->desc.idVendor = device_desc.idVendor;
++              cdev->desc.idProduct = device_desc.idProduct;
++              cdev->desc.bcdDevice = device_desc.bcdDevice;
++
++              list_for_each_entry(f, &smdev->funcs_fconf, fconf_list) {
++                      if (!strcmp(f->name, "acm"))
++                              cdev->desc.bcdDevice =
++                                      cpu_to_le16(0x0400);
++              }
++
++              list_for_each_entry(f, &smdev->funcs_sconf, sconf_list) {
++                      if (!strcmp(f->name, "acm"))
++                              cdev->desc.bcdDevice =
++                                      cpu_to_le16(0x0400);
++                      smdev->dual_config = true;
++              }
++
++              cdev->desc.bDeviceClass = device_desc.bDeviceClass;
++              cdev->desc.bDeviceSubClass = device_desc.bDeviceSubClass;
++              cdev->desc.bDeviceProtocol = device_desc.bDeviceProtocol;
++
++              dev_dbg(pdev, "usb: %s vendor=%x,product=%x,bcdDevice=%x",
++                     __func__, cdev->desc.idVendor,
++                     cdev->desc.idProduct, cdev->desc.bcdDevice);
++              dev_dbg(pdev, ",Class=%x,SubClass=%x,Protocol=%x\n",
++                     cdev->desc.bDeviceClass,
++                     cdev->desc.bDeviceSubClass, cdev->desc.bDeviceProtocol);
++              dev_dbg(pdev, "usb: %s next cmd : usb_add_config\n",
++                     __func__);
++
++              ret = usb_add_config(cdev,
++                              &first_config_driver, slp_multi_bind_config);
++              if (ret < 0) {
++                      dev_err(pdev,
++                              "usb_add_config fail-1st(%d)\n", ret);
++                      smdev->dual_config = false;
++                      goto done;
++              }
++
++              if (smdev->dual_config) {
++                      ret = usb_add_config(cdev, &second_config_driver,
++                                     slp_multi_bind_config);
++                      if (ret < 0) {
++                              dev_err(pdev,
++                                      "usb_add_config fail-2nd(%d)\n", ret);
++                              usb_remove_config(cdev, &first_config_driver);
++                              smdev->dual_config = false;
++                              goto done;
++                      }
++              }
++
++              smdev->enabled = true;
++              usb_gadget_connect(cdev->gadget);
++
++
++      } else if (!enabled && smdev->enabled) {
++
++              usb_gadget_disconnect(cdev->gadget);
++              /* Cancel pending control requests */
++              usb_ep_dequeue(cdev->gadget->ep0, cdev->req);
++              usb_remove_config(cdev, &first_config_driver);
++              if (smdev->dual_config)
++                      usb_remove_config(cdev, &second_config_driver);
++              smdev->enabled = false;
++              smdev->dual_config = false;
++      } else {
++              dev_info(pdev, "slp_multi_usb: already %s\n",
++                     smdev->enabled ? "enabled" : "disabled");
++      }
++
++done:
++      mutex_unlock(&smdev->mutex);
++      return (ret < 0 ? ret : size);
++}
++
++static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store);
++
++#define DESCRIPTOR_ATTR(field, format_string)                         \
++static ssize_t                                                                \
++field ## _show(struct device *dev, struct device_attribute *attr,     \
++              char *buf)                                              \
++{                                                                     \
++      return snprintf(buf, PAGE_SIZE, format_string, device_desc.field);\
++}                                                                     \
++static ssize_t                                                                \
++field ## _store(struct device *dev, struct device_attribute *attr,    \
++              const char *buf, size_t size)   \
++{                                                                     \
++      int value;      \
++      if (sscanf(buf, format_string, &value) == 1) {                  \
++              device_desc.field = value;                              \
++              return size;                                            \
++      }                                                               \
++      return -EINVAL;                                                 \
++}                                                                     \
++static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, field ## _show, field ## _store);
++
++#define DESCRIPTOR_STRING_ATTR(field, buffer) \
++static ssize_t        \
++field ## _show(struct device *dev, struct device_attribute *attr,     \
++              char *buf)      \
++{     \
++      return snprintf(buf, PAGE_SIZE, "%s", buffer);  \
++}     \
++static ssize_t        \
++field ## _store(struct device *dev, struct device_attribute *attr,    \
++              const char *buf, size_t size)   \
++{     \
++      if ((size >= sizeof(buffer)) || \
++              (sscanf(buf, "%s", buffer) != 1)) {     \
++              return -EINVAL; \
++      }       \
++      return size;    \
++}     \
++static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, field ## _show, field ## _store);
++
++DESCRIPTOR_ATTR(idVendor, "%04x\n")
++DESCRIPTOR_ATTR(idProduct, "%04x\n")
++DESCRIPTOR_ATTR(bcdDevice, "%04x\n")
++DESCRIPTOR_ATTR(bDeviceClass, "%d\n")
++DESCRIPTOR_ATTR(bDeviceSubClass, "%d\n")
++DESCRIPTOR_ATTR(bDeviceProtocol, "%d\n")
++DESCRIPTOR_STRING_ATTR(iManufacturer, manufacturer_string)
++DESCRIPTOR_STRING_ATTR(iProduct, product_string)
++DESCRIPTOR_STRING_ATTR(iSerial, serial_string)
++
++static struct device_attribute *slp_multi_usb_attributes[] = {
++      &dev_attr_idVendor,
++      &dev_attr_idProduct,
++      &dev_attr_bcdDevice,
++      &dev_attr_bDeviceClass,
++      &dev_attr_bDeviceSubClass,
++      &dev_attr_bDeviceProtocol,
++      &dev_attr_iManufacturer,
++      &dev_attr_iProduct,
++      &dev_attr_iSerial,
++      &dev_attr_funcs_fconf,
++      &dev_attr_funcs_sconf,
++      &dev_attr_enable,
++      &dev_attr_pm_qos,
++      NULL
++};
++
++/*-------------------------------------------------------------------------*/
++/* Composite driver */
++
++static int slp_multi_bind_config(struct usb_configuration *c)
++{
++      struct slp_multi_dev *smdev = _slp_multi_dev;
++      int ret = 0;
++
++      ret = slp_multi_bind_enabled_functions(smdev, c);
++      if (ret)
++              return ret;
++
++      if ((smdev->swfi_latency != PM_QOS_DEFAULT_VALUE) &&
++              !(strncmp(smdev->pm_qos, "high", 4)) &&
++                      (smdev->curr_latency == PM_QOS_DEFAULT_VALUE)) {
++              smdev->curr_latency = smdev->swfi_latency;
++              pm_qos_update_request(&smdev->pm_qos_req_dma,
++                      smdev->swfi_latency);
++      }
++
++      return 0;
++}
++
++static void slp_multi_unbind_config(struct usb_configuration *c)
++{
++      struct slp_multi_dev *smdev = _slp_multi_dev;
++
++      cancel_work_sync(&smdev->qos_work);
++
++      if (smdev->curr_latency != PM_QOS_DEFAULT_VALUE) {
++              smdev->curr_latency = PM_QOS_DEFAULT_VALUE;
++              pm_qos_update_request(&smdev->pm_qos_req_dma,
++                      PM_QOS_DEFAULT_VALUE);
++      }
++
++      slp_multi_unbind_enabled_functions(smdev, c);
++}
++
++static int slp_multi_bind(struct usb_composite_dev *cdev)
++{
++      struct slp_multi_dev *smdev = _slp_multi_dev;
++      struct usb_gadget *gadget = cdev->gadget;
++      int id, ret;
++
++      dev_dbg(smdev->dev, "usb: %s disconnect\n", __func__);
++      usb_gadget_disconnect(gadget);
++
++      /* Allocate string descriptor numbers ... note that string
++       * contents can be overridden by the composite_dev glue.
++       */
++      id = usb_string_id(cdev);
++      if (id < 0)
++              return id;
++      strings_dev[STRING_MANUFACTURER_IDX].id = id;
++      device_desc.iManufacturer = id;
++
++      id = usb_string_id(cdev);
++      if (id < 0)
++              return id;
++      strings_dev[STRING_PRODUCT_IDX].id = id;
++      device_desc.iProduct = id;
++
++      /* Default strings - should be updated by userspace */
++      strlcpy(manufacturer_string, "Samsung\0",
++              sizeof(manufacturer_string) - 1);
++      strlcpy(product_string, "SLP\0", sizeof(product_string) - 1);
++      snprintf(serial_string, sizeof(serial_string),
++               "%08x%08x", system_serial_high, system_serial_low);
++
++      id = usb_string_id(cdev);
++      if (id < 0)
++              return id;
++      strings_dev[STRING_SERIAL_IDX].id = id;
++      device_desc.iSerialNumber = id;
++
++      ret = slp_multi_init_functions(smdev, cdev);
++      if (ret)
++              return ret;
++
++      usb_gadget_set_selfpowered(gadget);
++      smdev->cdev = cdev;
++
++      return 0;
++}
++
++static int slp_multi_usb_unbind(struct usb_composite_dev *cdev)
++{
++      struct slp_multi_dev *smdev = _slp_multi_dev;
++      dev_dbg(smdev->dev, "usb: %s\n", __func__);
++      slp_multi_cleanup_functions(smdev);
++      return 0;
++}
++
++static void slp_multi_usb_resume(struct usb_composite_dev *cdev)
++{
++      struct slp_multi_dev *smdev = _slp_multi_dev;
++
++      dev_dbg(smdev->dev, "usb: %s\n", __func__);
++
++      smdev->suspended = 0;
++
++      if ((smdev->swfi_latency != PM_QOS_DEFAULT_VALUE) &&
++              !(strncmp(smdev->pm_qos, "high", 4)))
++              schedule_work(&smdev->qos_work);
++}
++
++static void slp_multi_usb_suspend(struct usb_composite_dev *cdev)
++{
++      struct slp_multi_dev *smdev = _slp_multi_dev;
++
++      dev_dbg(smdev->dev, "usb: %s\n", __func__);
++
++      smdev->suspended = 1;
++
++      if (smdev->curr_latency != PM_QOS_DEFAULT_VALUE)
++              schedule_work(&smdev->qos_work);
++}
++
++static struct usb_composite_driver slp_multi_composite = {
++      .name = "slp_multi_composite",
++      .dev = &device_desc,
++      .strings = slp_dev_strings,
++      .bind = slp_multi_bind,
++      .unbind = slp_multi_usb_unbind,
++      .max_speed = USB_SPEED_HIGH,
++      .resume = slp_multi_usb_resume,
++      .suspend = slp_multi_usb_suspend,
++};
++
++/* HACK: android needs to override setup for accessory to work */
++static int (*composite_setup_func)(struct usb_gadget *gadget,
++                                 const struct usb_ctrlrequest *c);
++
++static int
++slp_multi_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
++{
++      struct slp_multi_dev *smdev = _slp_multi_dev;
++      struct usb_composite_dev *cdev = get_gadget_data(gadget);
++      u8 b_requestType = ctrl->bRequestType;
++      struct slp_multi_usb_function *f;
++      int value = -EOPNOTSUPP;
++
++      if ((b_requestType & USB_TYPE_MASK) == USB_TYPE_VENDOR) {
++              struct usb_request *req = cdev->req;
++
++              req->zero = 0;
++              req->length = 0;
++              gadget->ep0->driver_data = cdev;
++
++              /* To check & report it to platform , we check it all */
++              list_for_each_entry(f, &smdev->available_functions,
++                      available_list) {
++                      if (f->ctrlrequest) {
++                              value = f->ctrlrequest(f, cdev, ctrl);
++                              if (value >= 0)
++                                      break;
++                      }
++              }
++      }
++
++      if (value < 0)
++              value = composite_setup_func(gadget, ctrl);
++
++      return value;
++}
++
++static int slp_multi_create_device(struct slp_multi_dev *smdev)
++{
++      struct device_attribute **attrs = slp_multi_usb_attributes;
++      struct device_attribute *attr;
++      int err;
++
++      smdev->dev = device_create(slp_multi_class, NULL,
++                                MKDEV(0, 0), NULL, "usb0");
++      if (IS_ERR(smdev->dev))
++              return PTR_ERR(smdev->dev);
++
++      dev_set_drvdata(smdev->dev, smdev);
++
++      while ((attr = *attrs++)) {
++              err = device_create_file(smdev->dev, attr);
++              if (err) {
++                      device_destroy(slp_multi_class, smdev->dev->devt);
++                      return err;
++              }
++      }
++      return 0;
++}
++
++static void slp_multi_destroy_device(struct slp_multi_dev *smdev)
++{
++      struct device_attribute **attrs = slp_multi_usb_attributes;
++      struct device_attribute *attr;
++
++      while ((attr = *attrs++))
++              device_destroy(slp_multi_class, smdev->dev->devt);
++
++      dev_set_drvdata(smdev->dev, NULL);
++
++      device_unregister(smdev->dev);
++}
++
++static CLASS_ATTR_STRING(version, S_IRUSR | S_IRGRP | S_IROTH,
++                       USB_MODE_VERSION);
++
++static int __init slp_multi_init(void)
++{
++      int err, i;
++      struct slp_multi_dev *smdev;
++      struct slp_multi_usb_function *f;
++      struct slp_multi_usb_function **functions = supported_functions;
++
++      slp_multi_class = class_create(THIS_MODULE, "usb_mode");
++      if (IS_ERR(slp_multi_class)) {
++              pr_err("failed to create slp_multi class --> %ld\n",
++                              PTR_ERR(slp_multi_class));
++              return PTR_ERR(slp_multi_class);
++      }
++
++      err = class_create_file(slp_multi_class, &class_attr_version.attr);
++      if (err) {
++              pr_err("usb_mode: can't create sysfs version file\n");
++              goto err_class;
++      }
++
++      smdev = kzalloc(sizeof(*smdev), GFP_KERNEL);
++      if (!smdev) {
++              pr_err("usb_mode: can't alloc for smdev\n");
++              err = -ENOMEM;
++              goto err_attr;
++      }
++
++      INIT_LIST_HEAD(&smdev->available_functions);
++      INIT_LIST_HEAD(&smdev->funcs_fconf);
++      INIT_LIST_HEAD(&smdev->funcs_sconf);
++      INIT_WORK(&smdev->qos_work, slp_multi_qos_work);
++
++      mutex_init(&smdev->mutex);
++
++      while ((f = *functions++)) {
++              for (i = 0; i < sizeof(default_funcs) / sizeof(char *); i++)
++                      if (!strcmp(default_funcs[i], f->name))
++                              list_add_tail(&f->available_list,
++                                            &smdev->available_functions);
++      }
++
++      err = slp_multi_create_device(smdev);
++      if (err) {
++              pr_err("usb_mode: can't create device\n");
++              goto err_alloc;
++      }
++
++      slp_multi_nluns = 1;
++      _slp_multi_dev = smdev;
++
++      err = usb_composite_probe(&slp_multi_composite);
++      if (err) {
++              pr_err("usb_mode: can't probe composite\n");
++              goto err_create;
++      }
++
++      /* HACK: exchange composite's setup with ours */
++      composite_setup_func = slp_multi_composite.gadget_driver.setup;
++      slp_multi_composite.gadget_driver.setup = slp_multi_setup;
++
++      smdev->swfi_latency = PM_QOS_DEFAULT_VALUE;
++      strlcpy(smdev->pm_qos, "NONE", sizeof(smdev->pm_qos));
++      smdev->curr_latency = PM_QOS_DEFAULT_VALUE;
++
++      pr_info("usb_mode driver, version:" USB_MODE_VERSION
++              "," " init Ok\n");
++
++      return 0;
++
++err_create:
++      slp_multi_destroy_device(smdev);
++
++err_alloc:
++      kfree(smdev);
++
++err_attr:
++      class_remove_file(slp_multi_class, &class_attr_version.attr);
++err_class:
++      class_destroy(slp_multi_class);
++
++      return err;
++}
++late_initcall(slp_multi_init);
++
++static void __exit slp_multi_exit(void)
++{
++      usb_composite_unregister(&slp_multi_composite);
++      slp_multi_destroy_device(_slp_multi_dev);
++
++      kfree(_slp_multi_dev);
++      _slp_multi_dev = NULL;
++
++      class_remove_file(slp_multi_class, &class_attr_version.attr);
++      class_destroy(slp_multi_class);
++}
++module_exit(slp_multi_exit);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0765-phy-Add-new-Exynos-USB-PHY-driver.patch b/patches.tizen/0765-phy-Add-new-Exynos-USB-PHY-driver.patch
new file mode 100644 (file)
index 0000000..b19d27c
--- /dev/null
@@ -0,0 +1,1155 @@
+From 58a45710fdacc9b3ba5fd94dffb127de633c337a Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Wed, 31 Jul 2013 10:35:15 +0200
+Subject: [PATCH 0765/1302] phy: Add new Exynos USB PHY driver
+
+Add a new driver for the Exynos USB PHY. The new driver uses the generic
+PHY framework.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../devicetree/bindings/phy/samsung-usbphy.txt     |  51 +++
+ drivers/phy/Kconfig                                |  21 ++
+ drivers/phy/Makefile                               |   3 +
+ drivers/phy/phy-exynos-usb.c                       | 245 +++++++++++++++
+ drivers/phy/phy-exynos-usb.h                       |  95 ++++++
+ drivers/phy/phy-exynos4210-usb.c                   | 315 +++++++++++++++++++
+ drivers/phy/phy-exynos4212-usb.c                   | 349 +++++++++++++++++++++
+ 7 files changed, 1079 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/phy/samsung-usbphy.txt
+ create mode 100644 drivers/phy/phy-exynos-usb.c
+ create mode 100644 drivers/phy/phy-exynos-usb.h
+ create mode 100644 drivers/phy/phy-exynos4210-usb.c
+ create mode 100644 drivers/phy/phy-exynos4212-usb.c
+
+diff --git a/Documentation/devicetree/bindings/phy/samsung-usbphy.txt b/Documentation/devicetree/bindings/phy/samsung-usbphy.txt
+new file mode 100644
+index 0000000..f112b37
+--- /dev/null
++++ b/Documentation/devicetree/bindings/phy/samsung-usbphy.txt
+@@ -0,0 +1,51 @@
++Samsung S5P/EXYNOS SoC series USB PHY
++-------------------------------------------------
++
++Required properties:
++- compatible : should be one of the listed compatibles:
++      - "samsung,exynos4210-usbphy"
++      - "samsung,exynos4212-usbphy"
++- reg : a list of registers used by phy driver
++      - first and obligatory is the location of phy modules registers
++      - second and also required is the location of isolation registers
++        (isolation registers control the physical connection between the in
++        SoC modules and outside of the SoC, this also can be called enable
++        control in the documentation of the SoC)
++      - third is the location of the mode switch register, this only applies
++        to SoCs that have such a feature; mode switching enables to have
++        both host and device used the same SoC pins and is commonly used
++        when OTG is supported
++- #phy-cells : from the generic phy bindings, must be 1;
++
++The second cell in the PHY specifier identifies the PHY its meaning is SoC
++dependent. For the currently supported SoCs (Exynos 4210 and Exynos 4212) it
++is as follows:
++  0 - USB device,
++  1 - USB host,
++  2 - HSIC0,
++  3 - HSIC1,
++
++Example:
++
++For Exynos 4412 (compatible with Exynos 4212):
++
++exynos_usbphy: exynos-usbphy@125B0000 {
++      compatible = "samsung,exynos4212-usbphy";
++      reg = <0x125B0000 0x100 0x10020704 0x0c 0x1001021c 0x4>;
++      ranges;
++      #address-cells = <1>;
++      #size-cells = <1>;
++      clocks = <&clock 305>, <&clock 2>, <&clock 2>, <&clock 2>,
++                                                      <&clock 2>;
++      clock-names = "phy", "device", "host", "hsic0", "hsic1";
++      status = "okay";
++      #phy-cells = <1>;
++};
++
++Then the PHY can be used in other nodes such as:
++
++ehci@12580000 {
++      status = "okay";
++      phys = <&exynos_usbphy 2>;
++      phy-names = "hsic0";
++};
+diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
+index 108c5f6..bf63eb8 100644
+--- a/drivers/phy/Kconfig
++++ b/drivers/phy/Kconfig
+@@ -21,4 +21,25 @@ config PHY_EXYNOS_MIPI_VIDEO
+         Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung
+         S5P and EXYNOS SoCs.
++config PHY_EXYNOS_USB
++      tristate "Samsung USB PHY driver (using the Generic PHY Framework)"
++      help
++        Enable this to support Samsung USB phy helper driver for Samsung SoCs.
++        This driver provides common interface to interact, for Samsung
++        USB 2.0 PHY driver.
++
++config PHY_EXYNOS4210_USB
++      bool "Support for Exynos 4210"
++      depends on PHY_EXYNOS_USB
++      depends on CPU_EXYNOS4210
++      help
++        Enable USB PHY support for Exynos 4210
++
++config PHY_EXYNOS4212_USB
++      bool "Support for Exynos 4212"
++      depends on PHY_EXYNOS_USB
++      depends on (SOC_EXYNOS4212 || SOC_EXYNOS4412)
++      help
++        Enable USB PHY support for Exynos 4212
++        
+ endmenu
+diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
+index 71d8841..d75f932 100644
+--- a/drivers/phy/Makefile
++++ b/drivers/phy/Makefile
+@@ -4,3 +4,6 @@
+ obj-$(CONFIG_GENERIC_PHY)             += phy-core.o
+ obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO)   += phy-exynos-mipi-video.o
++obj-$(CONFIG_PHY_EXYNOS_USB)          += phy-exynos-usb.o
++obj-$(CONFIG_PHY_EXYNOS4210_USB)      += phy-exynos4210-usb.o
++obj-$(CONFIG_PHY_EXYNOS4212_USB)      += phy-exynos4212-usb.o
+diff --git a/drivers/phy/phy-exynos-usb.c b/drivers/phy/phy-exynos-usb.c
+new file mode 100644
+index 0000000..b15a19f
+--- /dev/null
++++ b/drivers/phy/phy-exynos-usb.c
+@@ -0,0 +1,245 @@
++/*
++ * Samsung S5P/EXYNOS SoC series USB PHY driver
++ *
++ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
++ * Author: Kamil Debski <k.debski@samsung.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/clk.h>
++#include <linux/delay.h>
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/phy/phy.h>
++#include <linux/platform_device.h>
++#include <linux/spinlock.h>
++#include "phy-exynos-usb.h"
++
++static int exynos_uphy_power_on(struct phy *phy)
++{
++      struct uphy_instance *inst = phy_get_drvdata(phy);
++      struct uphy_driver *drv = inst->drv;
++      int ret;
++
++      dev_info(drv->dev, "Request to power_on \"%s\" usb phy\n",
++                                                      inst->cfg->label);
++      ret = clk_prepare_enable(drv->clk);
++      if (ret)
++              return ret;
++      if (inst->cfg->power_on) {
++              spin_lock(&drv->lock);
++              ret = inst->cfg->power_on(inst);
++              spin_unlock(&drv->lock);
++      }
++      clk_disable_unprepare(drv->clk);
++      return ret;
++}
++
++static int exynos_uphy_power_off(struct phy *phy)
++{
++      struct uphy_instance *inst = phy_get_drvdata(phy);
++      struct uphy_driver *drv = inst->drv;
++      int ret;
++
++      dev_info(drv->dev, "Request to power_off \"%s\" usb phy\n",
++                                                      inst->cfg->label);
++      ret = clk_prepare_enable(drv->clk);
++      if (ret)
++              return ret;
++      if (inst->cfg->power_off) {
++              spin_lock(&drv->lock);
++              ret = inst->cfg->power_off(inst);
++              spin_unlock(&drv->lock);
++      }
++      clk_disable_unprepare(drv->clk);
++      return ret;
++}
++
++static struct phy_ops exynos_uphy_ops = {
++      .power_on       = exynos_uphy_power_on,
++      .power_off      = exynos_uphy_power_off,
++      .owner          = THIS_MODULE,
++};
++
++static struct phy *exynos_uphy_xlate(struct device *dev,
++                                      struct of_phandle_args *args)
++{
++      struct uphy_driver *drv;
++
++      drv = dev_get_drvdata(dev);
++      if (!drv)
++              return ERR_PTR(-EINVAL);
++
++      if (WARN_ON(args->args[0] >= drv->cfg->num_phys))
++              return ERR_PTR(-ENODEV);
++
++      return drv->uphy_instances[args->args[0]].phy;
++}
++
++static const struct of_device_id exynos_uphy_of_match[];
++
++static int exynos_uphy_probe(struct platform_device *pdev)
++{
++      struct uphy_driver *drv;
++      struct device *dev = &pdev->dev;
++      struct resource *mem;
++      struct phy_provider *phy_provider;
++
++      const struct of_device_id *match;
++      const struct uphy_config *cfg;
++      struct clk *clk;
++
++      int i;
++
++      match = of_match_node(exynos_uphy_of_match, pdev->dev.of_node);
++      if (!match) {
++              dev_err(dev, "of_match_node() failed\n");
++              return -EINVAL;
++      }
++      cfg = match->data;
++      if (!cfg) {
++              dev_err(dev, "Failed to get configuration\n");
++              return -EINVAL;
++      }
++
++      drv = devm_kzalloc(dev, sizeof(struct uphy_driver) +
++              cfg->num_phys * sizeof(struct uphy_instance), GFP_KERNEL);
++
++      if (!drv) {
++              dev_err(dev, "Failed to allocate memory\n");
++              return -ENOMEM;
++      }
++
++      dev_set_drvdata(dev, drv);
++      spin_lock_init(&drv->lock);
++
++      drv->cfg = cfg;
++      drv->dev = dev;
++
++      mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++
++      drv->reg_phy = devm_ioremap_resource(dev, mem);
++      if (IS_ERR(drv->reg_phy)) {
++              dev_err(dev, "Failed to map register memory (phy)\n");
++              return PTR_ERR(drv->reg_phy);
++      }
++
++      mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++      drv->reg_isol = devm_ioremap_resource(dev, mem);
++      if (IS_ERR(drv->reg_isol)) {
++              dev_err(dev, "Failed to map register memory (isolation)\n");
++              return PTR_ERR(drv->reg_isol);
++      }
++
++      switch (drv->cfg->cpu) {
++      case TYPE_EXYNOS4210:
++      case TYPE_EXYNOS4212:
++              mem = platform_get_resource(pdev, IORESOURCE_MEM, 2);
++              drv->reg_mode = devm_ioremap_resource(dev, mem);
++              if (IS_ERR(drv->reg_mode)) {
++                      dev_err(dev, "Failed to map register memory (mode switch)\n");
++                      return PTR_ERR(drv->reg_mode);
++              }
++              break;
++      default:
++              break;
++      }
++
++      phy_provider = devm_of_phy_provider_register(dev,
++                                                      exynos_uphy_xlate);
++      if (IS_ERR(phy_provider)) {
++              dev_err(drv->dev, "Failed to register phy provider\n");
++              return PTR_ERR(phy_provider);
++      }
++
++      drv->clk = devm_clk_get(dev, "phy");
++      if (IS_ERR(drv->clk)) {
++              dev_err(dev, "Failed to get clock of phy controller\n");
++              return PTR_ERR(drv->clk);
++      }
++
++      for (i = 0; i < drv->cfg->num_phys; i++) {
++              char *label = drv->cfg->phys[i].label;
++              struct uphy_instance *p = &drv->uphy_instances[i];
++
++              dev_info(dev, "Creating phy \"%s\"\n", label);
++              p->phy = devm_phy_create(dev, &exynos_uphy_ops, NULL);
++              if (IS_ERR(p->phy)) {
++                      dev_err(drv->dev, "Failed to create uphy \"%s\"\n",
++                                              label);
++                      return PTR_ERR(p->phy);
++              }
++
++              p->cfg = &drv->cfg->phys[i];
++              p->drv = drv;
++              phy_set_drvdata(p->phy, p);
++
++              clk = clk_get(dev, p->cfg->label);
++              if (IS_ERR(clk)) {
++                      dev_err(dev, "Failed to get clock of \"%s\" phy\n",
++                                                              p->cfg->label);
++                      return PTR_ERR(drv->clk);
++              }
++
++              p->rate = clk_get_rate(clk);
++
++              if (p->cfg->rate_to_clk) {
++                      p->clk = p->cfg->rate_to_clk(p->rate);
++                      if (p->clk == CLKSEL_ERROR) {
++                              dev_err(dev, "Clock rate (%ld) not supported\n",
++                                                              p->rate);
++                              clk_put(clk);
++                              return -EINVAL;
++                      }
++              }
++              clk_put(clk);
++      }
++
++      return 0;
++}
++
++#ifdef CONFIG_PHY_EXYNOS4210_USB
++extern const struct uphy_config exynos4210_uphy_config;
++#endif
++
++#ifdef CONFIG_PHY_EXYNOS4212_USB
++extern const struct uphy_config exynos4212_uphy_config;
++#endif
++
++static const struct of_device_id exynos_uphy_of_match[] = {
++#ifdef CONFIG_PHY_EXYNOS4210_USB
++      {
++              .compatible = "samsung,exynos4210-usbphy",
++              .data = &exynos4210_uphy_config,
++      },
++#endif
++#ifdef CONFIG_PHY_EXYNOS4212_USB
++      {
++              .compatible = "samsung,exynos4212-usbphy",
++              .data = &exynos4212_uphy_config,
++      },
++#endif
++      { },
++};
++
++static struct platform_driver exynos_uphy_driver = {
++      .probe  = exynos_uphy_probe,
++      .driver = {
++              .of_match_table = exynos_uphy_of_match,
++              .name           = "exynos-usbphy-new",
++              .owner          = THIS_MODULE,
++      }
++};
++
++module_platform_driver(exynos_uphy_driver);
++MODULE_DESCRIPTION("Samsung S5P/EXYNOS SoC USB PHY driver");
++MODULE_AUTHOR("Kamil Debski <k.debski@samsung.com>");
++MODULE_LICENSE("GPL v2");
++MODULE_ALIAS("platform:exynos-uphy-new");
++
+diff --git a/drivers/phy/phy-exynos-usb.h b/drivers/phy/phy-exynos-usb.h
+new file mode 100644
+index 0000000..a9febfa
+--- /dev/null
++++ b/drivers/phy/phy-exynos-usb.h
+@@ -0,0 +1,95 @@
++/*
++ * Samsung S5P/EXYNOS SoC series USB PHY driver
++ *
++ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
++ * Author: Kamil Debski <k.debski@samsung.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 _PHY_SAMSUNG_NEW_H
++#define _PHY_SAMSUNG_NEW_H
++
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/phy/phy.h>
++#include <linux/platform_device.h>
++#include <linux/spinlock.h>
++
++#define CLKSEL_ERROR                       -1
++
++#ifndef KHZ
++#define KHZ 1000
++#endif
++
++#ifndef MHZ
++#define MHZ (KHZ * KHZ)
++#endif
++
++enum phy_type {
++      PHY_DEVICE,
++      PHY_HOST,
++};
++
++enum samsung_cpu_type {
++      TYPE_S3C64XX,
++      TYPE_EXYNOS4210,
++      TYPE_EXYNOS4212,
++      TYPE_EXYNOS5250,
++};
++
++enum uphy_state {
++      STATE_OFF,
++      STATE_ON,
++};
++
++struct uphy_driver;
++struct uphy_instance;
++struct uphy_config;
++
++struct uphy_instance {
++      struct uphy_driver *drv;
++      struct phy *phy;
++      const struct common_phy *cfg;
++      enum uphy_state state;
++      int ref_cnt;
++      u32 clk;
++      unsigned long rate;
++};
++
++struct uphy_driver {
++      struct device *dev;
++      spinlock_t lock;
++      void __iomem *reg_phy;
++      void __iomem *reg_isol;
++      void __iomem *reg_mode;
++      const struct uphy_config *cfg;
++      struct clk *clk;
++      struct uphy_instance uphy_instances[0];
++};
++
++struct common_phy {
++      char *label;
++      enum phy_type type;
++      unsigned int id;
++      u32 (*rate_to_clk)(unsigned long);
++      int (*power_on)(struct uphy_instance*);
++      int (*power_off)(struct uphy_instance*);
++};
++
++
++struct uphy_config {
++      enum samsung_cpu_type cpu;
++      int num_phys;
++      const struct common_phy *phys;
++};
++
++#endif
++
+diff --git a/drivers/phy/phy-exynos4210-usb.c b/drivers/phy/phy-exynos4210-usb.c
+new file mode 100644
+index 0000000..4b849e7
+--- /dev/null
++++ b/drivers/phy/phy-exynos4210-usb.c
+@@ -0,0 +1,315 @@
++/*
++ * Samsung S5P/EXYNOS SoC series USB PHY driver
++ *
++ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
++ * Author: Kamil Debski <k.debski@samsung.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/clk.h>
++#include <linux/delay.h>
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/phy/phy.h>
++#include <linux/platform_device.h>
++#include <linux/spinlock.h>
++#include "phy-exynos-usb.h"
++
++/* Exynos USB PHY registers */
++
++/* PHY power control */
++#define EXYNOS_4210_UPHYPWR                   0x0
++
++#define EXYNOS_4210_UPHYPWR_PHY0_SUSPEND      (1 << 0)
++#define EXYNOS_4210_UPHYPWR_PHY0_PWR          (1 << 3)
++#define EXYNOS_4210_UPHYPWR_PHY0_OTG_PWR      (1 << 4)
++#define EXYNOS_4210_UPHYPWR_PHY0_SLEEP                (1 << 5)
++#define EXYNOS_4210_UPHYPWR_PHY0      ( \
++      EXYNOS_4210_UPHYPWR_PHY0_SUSPEND | \
++      EXYNOS_4210_UPHYPWR_PHY0_PWR | \
++      EXYNOS_4210_UPHYPWR_PHY0_OTG_PWR | \
++      EXYNOS_4210_UPHYPWR_PHY0_SLEEP)
++
++#define EXYNOS_4210_UPHYPWR_PHY1_SUSPEND      (1 << 6)
++#define EXYNOS_4210_UPHYPWR_PHY1_PWR          (1 << 7)
++#define EXYNOS_4210_UPHYPWR_PHY1_SLEEP                (1 << 8)
++#define EXYNOS_4210_UPHYPWR_PHY1 ( \
++      EXYNOS_4210_UPHYPWR_PHY1_SUSPEND | \
++      EXYNOS_4210_UPHYPWR_PHY1_PWR | \
++      EXYNOS_4210_UPHYPWR_PHY1_SLEEP)
++
++#define EXYNOS_4210_UPHYPWR_HSCI0_SUSPEND     (1 << 9)
++#define EXYNOS_4210_UPHYPWR_HSCI0_SLEEP               (1 << 10)
++#define EXYNOS_4210_UPHYPWR_HSCI0 ( \
++      EXYNOS_4210_UPHYPWR_HSCI0_SUSPEND | \
++      EXYNOS_4210_UPHYPWR_HSCI0_SLEEP)
++
++#define EXYNOS_4210_UPHYPWR_HSCI1_SUSPEND     (1 << 11)
++#define EXYNOS_4210_UPHYPWR_HSCI1_SLEEP               (1 << 12)
++#define EXYNOS_4210_UPHYPWR_HSCI1 ( \
++      EXYNOS_4210_UPHYPWR_HSCI1_SUSPEND | \
++      EXYNOS_4210_UPHYPWR_HSCI1_SLEEP)
++
++/* PHY clock control */
++#define EXYNOS_4210_UPHYCLK                   0x4
++
++#define EXYNOS_4210_UPHYCLK_PHYFSEL_MASK      (0x3 << 0)
++#define EXYNOS_4210_UPHYCLK_PHYFSEL_48MHZ     (0x0 << 0)
++#define EXYNOS_4210_UPHYCLK_PHYFSEL_24MHZ     (0x3 << 0)
++#define EXYNOS_4210_UPHYCLK_PHYFSEL_12MHZ     (0x2 << 0)
++
++#define EXYNOS_4210_UPHYCLK_PHY0_ID_PULLUP    (0x1 << 2)
++#define EXYNOS_4210_UPHYCLK_PHY0_COMMON_ON    (0x1 << 4)
++#define EXYNOS_4210_UPHYCLK_PHY1_COMMON_ON    (0x1 << 7)
++
++/* PHY reset control */
++#define EXYNOS_4210_UPHYRST                   0x8
++
++#define EXYNOS_4210_URSTCON_PHY0              (1 << 0)
++#define EXYNOS_4210_URSTCON_OTG_HLINK         (1 << 1)
++#define EXYNOS_4210_URSTCON_OTG_PHYLINK               (1 << 2)
++#define EXYNOS_4210_URSTCON_PHY1_ALL          (1 << 3)
++#define EXYNOS_4210_URSTCON_PHY1_P0           (1 << 4)
++#define EXYNOS_4210_URSTCON_PHY1_P1P2         (1 << 5)
++#define EXYNOS_4210_URSTCON_HOST_LINK_ALL     (1 << 6)
++#define EXYNOS_4210_URSTCON_HOST_LINK_P0      (1 << 7)
++#define EXYNOS_4210_URSTCON_HOST_LINK_P1      (1 << 8)
++#define EXYNOS_4210_URSTCON_HOST_LINK_P2      (1 << 9)
++
++/* Isolation, configured in the power management unit */
++#define EXYNOS_4210_USB_ISOL_DEVICE_OFFSET    0x0
++#define EXYNOS_4210_USB_ISOL_DEVICE           (1 << 0)
++#define EXYNOS_4210_USB_ISOL_HOST_OFFSET      0x4
++#define EXYNOS_4210_USB_ISOL_HOST             (1 << 0)
++
++/* USBYPHY1 Floating prevention */
++#define EXYNOS_4210_UPHY1CON                  0x34
++#define EXYNOS_4210_UPHY1CON_FLOAT_PREVENTION 0x1
++
++enum exynos4210_phy_id {
++      EXYNOS4210_DEVICE,
++      EXYNOS4210_HOST,
++      EXYNOS4210_HSIC0,
++      EXYNOS4210_HSIC1,
++      EXYNOS4210_NUM_PHYS,
++};
++
++/* exynos4210_rate_to_clk() converts the supplied clock rate to the value that
++ * can be written to the phy register. */
++static u32 exynos4210_rate_to_clk(unsigned long rate)
++{
++      unsigned int clksel;
++
++      switch (rate) {
++      case 12 * MHZ:
++              clksel = EXYNOS_4210_UPHYCLK_PHYFSEL_12MHZ;
++              break;
++      case 24 * MHZ:
++              clksel = EXYNOS_4210_UPHYCLK_PHYFSEL_24MHZ;
++              break;
++      case 48 * MHZ:
++              clksel = EXYNOS_4210_UPHYCLK_PHYFSEL_48MHZ;
++              break;
++      default:
++              clksel = CLKSEL_ERROR;
++      }
++
++      return clksel;
++}
++
++static void exynos4210_isol(struct uphy_instance *inst, bool on)
++{
++      struct uphy_driver *drv = inst->drv;
++      u32 offset;
++      u32 mask;
++      u32 tmp;
++
++      if (!drv->reg_isol)
++              return;
++
++      switch (inst->cfg->id) {
++      case EXYNOS4210_DEVICE:
++              offset = EXYNOS_4210_USB_ISOL_DEVICE_OFFSET;
++              mask = EXYNOS_4210_USB_ISOL_DEVICE;
++              break;
++      case EXYNOS4210_HOST:
++              offset = EXYNOS_4210_USB_ISOL_HOST_OFFSET;
++              mask = EXYNOS_4210_USB_ISOL_HOST;
++              break;
++      default:
++              return;
++      };
++
++      tmp = readl(drv->reg_isol + offset);
++      if (on)
++              tmp &= ~mask;
++      else
++              tmp |= mask;
++      writel(tmp, drv->reg_isol + offset);
++}
++
++static void exynos4210_phy_pwr(struct uphy_instance *inst, bool on)
++{
++      struct uphy_driver *drv = inst->drv;
++      u32 rstbits = 0;
++      u32 phypwr = 0;
++      u32 rst;
++      u32 pwr;
++
++      switch (inst->cfg->id) {
++      case EXYNOS4210_DEVICE:
++              phypwr =        EXYNOS_4210_UPHYPWR_PHY0;
++              rstbits =       EXYNOS_4210_URSTCON_PHY0;
++              break;
++      case EXYNOS4210_HOST:
++              phypwr =        EXYNOS_4210_UPHYPWR_PHY1;
++              rstbits =       EXYNOS_4210_URSTCON_PHY1_ALL |
++                              EXYNOS_4210_URSTCON_PHY1_P0 |
++                              EXYNOS_4210_URSTCON_PHY1_P1P2 |
++                              EXYNOS_4210_URSTCON_HOST_LINK_ALL |
++                              EXYNOS_4210_URSTCON_HOST_LINK_P0;
++              writel(on, drv->reg_phy + EXYNOS_4210_UPHY1CON);
++              break;
++      case EXYNOS4210_HSIC0:
++              phypwr =        EXYNOS_4210_UPHYPWR_HSCI0;
++              rstbits =       EXYNOS_4210_URSTCON_PHY1_P1P2 |
++                              EXYNOS_4210_URSTCON_HOST_LINK_P1;
++              break;
++      case EXYNOS4210_HSIC1:
++              phypwr =        EXYNOS_4210_UPHYPWR_HSCI1;
++              rstbits =       EXYNOS_4210_URSTCON_PHY1_P1P2 |
++                              EXYNOS_4210_URSTCON_HOST_LINK_P2;
++              break;
++      };
++
++      if (on) {
++              writel(inst->clk, drv->reg_phy + EXYNOS_4210_UPHYCLK);
++
++              pwr = readl(drv->reg_phy + EXYNOS_4210_UPHYPWR);
++              pwr &= ~phypwr;
++              writel(pwr, drv->reg_phy + EXYNOS_4210_UPHYPWR);
++
++              rst = readl(drv->reg_phy + EXYNOS_4210_UPHYRST);
++              rst |= rstbits;
++              writel(rst, drv->reg_phy + EXYNOS_4210_UPHYRST);
++              udelay(10);
++              rst &= ~rstbits;
++              writel(rst, drv->reg_phy + EXYNOS_4210_UPHYRST);
++      } else {
++              pwr = readl(drv->reg_phy + EXYNOS_4210_UPHYPWR);
++              pwr |= phypwr;
++              writel(pwr, drv->reg_phy + EXYNOS_4210_UPHYPWR);
++      }
++}
++
++static int exynos4210_power_on(struct uphy_instance *inst)
++{
++      struct uphy_driver *drv = inst->drv;
++
++      if (inst->state == STATE_ON) {
++              dev_err(drv->dev, "usb phy \"%s\" already on",
++                                                      inst->cfg->label);
++              return -ENODEV;
++      }
++      inst->state = STATE_ON;
++      inst->ref_cnt++;
++      if (inst->ref_cnt > 1)
++              return 0;
++
++      exynos4210_isol(inst, 0);
++      exynos4210_phy_pwr(inst, 1);
++
++      /* Power on the device, as it is necessary for HSIC to work */
++      if (inst->cfg->id == EXYNOS4210_HOST) {
++              struct uphy_instance *device =
++                                      &drv->uphy_instances[EXYNOS4210_DEVICE];
++              device->ref_cnt++;
++              if (device->ref_cnt > 1)
++                      return 0;
++              exynos4210_phy_pwr(device, 1);
++              exynos4210_isol(device, 0);
++      }
++
++      return 0;
++}
++
++static int exynos4210_power_off(struct uphy_instance *inst)
++{
++      struct uphy_driver *drv = inst->drv;
++
++      if (inst->state == STATE_OFF) {
++              dev_err(drv->dev, "usb phy \"%s\" already off",
++                                                      inst->cfg->label);
++              return -EINVAL;
++      }
++
++      inst->state = STATE_OFF;
++      inst->ref_cnt++;
++      if (inst->ref_cnt > 0)
++              return 0;
++
++      exynos4210_phy_pwr(inst, 0);
++      exynos4210_isol(inst, 1);
++
++      if (inst->cfg->id == EXYNOS4210_HOST) {
++              struct uphy_instance *device =
++                                      &drv->uphy_instances[EXYNOS4210_DEVICE];
++              device->ref_cnt--;
++              if (device->ref_cnt > 0)
++                      return 0;
++              exynos4210_phy_pwr(device, 0);
++              exynos4210_isol(device, 1);
++      }
++
++      return 0;
++}
++
++
++static const struct common_phy exynos4210_phys[] = {
++      {
++              .label          = "device",
++              .type           = PHY_DEVICE,
++              .id             = EXYNOS4210_DEVICE,
++              .rate_to_clk    = exynos4210_rate_to_clk,
++              .power_on       = exynos4210_power_on,
++              .power_off      = exynos4210_power_off,
++      },
++      {
++              .label          = "host",
++              .type           = PHY_HOST,
++              .id             = EXYNOS4210_HOST,
++              .rate_to_clk    = exynos4210_rate_to_clk,
++              .power_on       = exynos4210_power_on,
++              .power_off      = exynos4210_power_off,
++      },
++      {
++              .label          = "hsic0",
++              .type           = PHY_HOST,
++              .id             = EXYNOS4210_HSIC0,
++              .rate_to_clk    = exynos4210_rate_to_clk,
++              .power_on       = exynos4210_power_on,
++              .power_off      = exynos4210_power_off,
++      },
++      {
++              .label          = "hsic1",
++              .type           = PHY_HOST,
++              .id             = EXYNOS4210_HSIC1,
++              .rate_to_clk    = exynos4210_rate_to_clk,
++              .power_on       = exynos4210_power_on,
++              .power_off      = exynos4210_power_off,
++      },
++      {},
++};
++
++const struct uphy_config exynos4210_uphy_config = {
++      .cpu            = TYPE_EXYNOS4210,
++      .num_phys       = EXYNOS4210_NUM_PHYS,
++      .phys           = exynos4210_phys,
++};
++
+diff --git a/drivers/phy/phy-exynos4212-usb.c b/drivers/phy/phy-exynos4212-usb.c
+new file mode 100644
+index 0000000..80480a4
+--- /dev/null
++++ b/drivers/phy/phy-exynos4212-usb.c
+@@ -0,0 +1,349 @@
++/*
++ * Samsung S5P/EXYNOS SoC series USB PHY driver
++ *
++ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
++ * Author: Kamil Debski <k.debski@samsung.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/clk.h>
++#include <linux/delay.h>
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/phy/phy.h>
++#include <linux/platform_device.h>
++#include <linux/spinlock.h>
++#include "phy-exynos-usb.h"
++
++/* Exynos USB PHY registers */
++
++/* PHY power control */
++#define EXYNOS_4212_UPHYPWR                   0x0
++
++#define EXYNOS_4212_UPHYPWR_DEV_SUSPEND               (1 << 0)
++#define EXYNOS_4212_UPHYPWR_DEV_PWR           (1 << 3)
++#define EXYNOS_4212_UPHYPWR_DEV_OTG_PWR               (1 << 4)
++#define EXYNOS_4212_UPHYPWR_DEV_SLEEP         (1 << 5)
++#define EXYNOS_4212_UPHYPWR_DEV       ( \
++      EXYNOS_4212_UPHYPWR_DEV_SUSPEND | \
++      EXYNOS_4212_UPHYPWR_DEV_PWR | \
++      EXYNOS_4212_UPHYPWR_DEV_OTG_PWR | \
++      EXYNOS_4212_UPHYPWR_DEV_SLEEP)
++
++#define EXYNOS_4212_UPHYPWR_HOST_SUSPEND      (1 << 6)
++#define EXYNOS_4212_UPHYPWR_HOST_PWR          (1 << 7)
++#define EXYNOS_4212_UPHYPWR_HOST_SLEEP                (1 << 8)
++#define EXYNOS_4212_UPHYPWR_HOST ( \
++      EXYNOS_4212_UPHYPWR_HOST_SUSPEND | \
++      EXYNOS_4212_UPHYPWR_HOST_PWR | \
++      EXYNOS_4212_UPHYPWR_HOST_SLEEP)
++
++#define EXYNOS_4212_UPHYPWR_HSCI0_SUSPEND     (1 << 9)
++#define EXYNOS_4212_UPHYPWR_HSCI0_PWR         (1 << 10)
++#define EXYNOS_4212_UPHYPWR_HSCI0_SLEEP               (1 << 11)
++#define EXYNOS_4212_UPHYPWR_HSCI0 ( \
++      EXYNOS_4212_UPHYPWR_HSCI0_SUSPEND | \
++      EXYNOS_4212_UPHYPWR_HSCI0_PWR | \
++      EXYNOS_4212_UPHYPWR_HSCI0_SLEEP)
++
++#define EXYNOS_4212_UPHYPWR_HSCI1_SUSPEND     (1 << 12)
++#define EXYNOS_4212_UPHYPWR_HSCI1_PWR         (1 << 13)
++#define EXYNOS_4212_UPHYPWR_HSCI1_SLEEP               (1 << 14)
++#define EXYNOS_4212_UPHYPWR_HSCI1 ( \
++      EXYNOS_4212_UPHYPWR_HSCI1_SUSPEND | \
++      EXYNOS_4212_UPHYPWR_HSCI1_PWR | \
++      EXYNOS_4212_UPHYPWR_HSCI1_SLEEP)
++
++/* PHY clock control */
++#define EXYNOS_4212_UPHYCLK                   0x4
++
++#define EXYNOS_4212_UPHYCLK_PHYFSEL_MASK      (0x7 << 0)
++#define EXYNOS_4212_UPHYCLK_PHYFSEL_9MHZ6     (0x0 << 0)
++#define EXYNOS_4212_UPHYCLK_PHYFSEL_10MHZ     (0x1 << 0)
++#define EXYNOS_4212_UPHYCLK_PHYFSEL_12MHZ     (0x2 << 0)
++#define EXYNOS_4212_UPHYCLK_PHYFSEL_19MHZ2    (0x3 << 0)
++#define EXYNOS_4212_UPHYCLK_PHYFSEL_20MHZ     (0x4 << 0)
++#define EXYNOS_4212_UPHYCLK_PHYFSEL_24MHZ     (0x5 << 0)
++#define EXYNOS_4212_UPHYCLK_PHYFSEL_50MHZ     (0x7 << 0)
++
++#define EXYNOS_4212_UPHYCLK_PHY0_ID_PULLUP    (0x1 << 3)
++#define EXYNOS_4212_UPHYCLK_PHY0_COMMON_ON    (0x1 << 4)
++#define EXYNOS_4212_UPHYCLK_PHY1_COMMON_ON    (0x1 << 7)
++
++#define EXYNOS_4212_UPHYCLK_HSIC_REFCLK_MASK  (0x7f << 10)
++#define EXYNOS_4212_UPHYCLK_HSIC_REFCLK_12MHZ (0x24 << 10)
++#define EXYNOS_4212_UPHYCLK_HSIC_REFCLK_15MHZ (0x1c << 10)
++#define EXYNOS_4212_UPHYCLK_HSIC_REFCLK_16MHZ (0x1a << 10)
++#define EXYNOS_4212_UPHYCLK_HSIC_REFCLK_19MHZ2        (0x15 << 10)
++#define EXYNOS_4212_UPHYCLK_HSIC_REFCLK_20MHZ (0x14 << 10)
++
++/* PHY reset control */
++#define EXYNOS_4212_UPHYRST                   0x8
++
++#define EXYNOS_4212_URSTCON_DEVICE            (1 << 0)
++#define EXYNOS_4212_URSTCON_OTG_HLINK         (1 << 1)
++#define EXYNOS_4212_URSTCON_OTG_PHYLINK               (1 << 2)
++#define EXYNOS_4212_URSTCON_HOST_PHY          (1 << 3)
++#define EXYNOS_4212_URSTCON_PHY1              (1 << 4)
++#define EXYNOS_4212_URSTCON_HSIC0             (1 << 5)
++#define EXYNOS_4212_URSTCON_HSIC1             (1 << 6)
++#define EXYNOS_4212_URSTCON_HOST_LINK_ALL     (1 << 7)
++#define EXYNOS_4212_URSTCON_HOST_LINK_P0      (1 << 8)
++#define EXYNOS_4212_URSTCON_HOST_LINK_P1      (1 << 9)
++#define EXYNOS_4212_URSTCON_HOST_LINK_P2      (1 << 10)
++
++/* Isolation, configured in the power management unit */
++#define EXYNOS_4212_USB_ISOL_OFFSET           0x0
++#define EXYNOS_4212_USB_ISOL_OTG              (1 << 0)
++#define EXYNOS_4212_USB_ISOL_HSIC0_OFFSET     0x4
++#define EXYNOS_4212_USB_ISOL_HSIC0            (1 << 0)
++#define EXYNOS_4212_USB_ISOL_HSIC1_OFFSET     0x8
++#define EXYNOS_4212_USB_ISOL_HSIC1            (1 << 0)
++
++enum exynos4x12_phy_id {
++      EXYNOS4212_DEVICE,
++      EXYNOS4212_HOST,
++      EXYNOS4212_HSIC0,
++      EXYNOS4212_HSIC1,
++      EXYNOS4212_NUM_PHYS,
++};
++
++/* exynos4212_rate_to_clk() converts the supplied clock rate to the value that
++ * can be written to the phy register. */
++static u32 exynos4212_rate_to_clk(unsigned long rate)
++{
++      unsigned int clksel;
++
++      /* EXYNOS_4212_UPHYCLK_PHYFSEL_MASK */
++
++      switch (rate) {
++      case 9600 * KHZ:
++              clksel = EXYNOS_4212_UPHYCLK_PHYFSEL_9MHZ6;
++              break;
++      case 10 * MHZ:
++              clksel = EXYNOS_4212_UPHYCLK_PHYFSEL_10MHZ;
++              break;
++      case 12 * MHZ:
++              clksel = EXYNOS_4212_UPHYCLK_PHYFSEL_12MHZ;
++              break;
++      case 19200 * KHZ:
++              clksel = EXYNOS_4212_UPHYCLK_PHYFSEL_19MHZ2;
++              break;
++      case 20 * MHZ:
++              clksel = EXYNOS_4212_UPHYCLK_PHYFSEL_20MHZ;
++              break;
++      case 24 * MHZ:
++              clksel = EXYNOS_4212_UPHYCLK_PHYFSEL_24MHZ;
++              break;
++      case 50 * MHZ:
++              clksel = EXYNOS_4212_UPHYCLK_PHYFSEL_50MHZ;
++              break;
++      default:
++              clksel = CLKSEL_ERROR;
++      }
++
++      return clksel;
++}
++
++static void exynos4212_isol(struct uphy_instance *inst, bool on)
++{
++      struct uphy_driver *drv = inst->drv;
++      u32 offset;
++      u32 mask;
++      u32 tmp;
++
++      if (!drv->reg_isol)
++              return;
++
++      switch (inst->cfg->id) {
++      case EXYNOS4212_DEVICE:
++              offset = EXYNOS_4212_USB_ISOL_OFFSET;
++              mask = EXYNOS_4212_USB_ISOL_OTG;
++              break;
++      case EXYNOS4212_HOST:
++              offset = EXYNOS_4212_USB_ISOL_OFFSET;
++              mask = EXYNOS_4212_USB_ISOL_OTG;
++              break;
++      case EXYNOS4212_HSIC0:
++              offset = EXYNOS_4212_USB_ISOL_HSIC0_OFFSET;
++              mask = EXYNOS_4212_USB_ISOL_HSIC0;
++              break;
++      case EXYNOS4212_HSIC1:
++              offset = EXYNOS_4212_USB_ISOL_HSIC1_OFFSET;
++              mask = EXYNOS_4212_USB_ISOL_HSIC1;
++              break;
++      default:
++              return;
++      };
++
++      tmp = readl(drv->reg_isol + offset);
++      if (on)
++              tmp &= ~mask;
++      else
++              tmp |= mask;
++      writel(tmp, drv->reg_isol + offset);
++}
++
++static void exynos4212_phy_pwr(struct uphy_instance *inst, bool on)
++{
++      struct uphy_driver *drv = inst->drv;
++      u32 rstbits = 0;
++      u32 phypwr = 0;
++      u32 rst;
++      u32 pwr;
++
++      switch (inst->cfg->id) {
++      case EXYNOS4212_DEVICE:
++              phypwr =        EXYNOS_4212_UPHYPWR_DEV;
++              rstbits =       EXYNOS_4212_URSTCON_DEVICE;
++              break;
++      case EXYNOS4212_HOST:
++              phypwr =        EXYNOS_4212_UPHYPWR_HOST;
++              rstbits =       EXYNOS_4212_URSTCON_HOST_PHY;
++              break;
++      case EXYNOS4212_HSIC0:
++              phypwr =        EXYNOS_4212_UPHYPWR_HSCI0;
++              rstbits =       EXYNOS_4212_URSTCON_HSIC1 |
++                              EXYNOS_4212_URSTCON_HOST_LINK_P0 |
++                              EXYNOS_4212_URSTCON_HOST_PHY;
++              break;
++      case EXYNOS4212_HSIC1:
++              phypwr =        EXYNOS_4212_UPHYPWR_HSCI1;
++              rstbits =       EXYNOS_4212_URSTCON_HSIC1 |
++                              EXYNOS_4212_URSTCON_HOST_LINK_P1;
++              break;
++      };
++
++      if (on) {
++              writel(inst->clk, drv->reg_phy + EXYNOS_4212_UPHYCLK);
++
++              pwr = readl(drv->reg_phy + EXYNOS_4212_UPHYPWR);
++              pwr &= ~phypwr;
++              writel(pwr, drv->reg_phy + EXYNOS_4212_UPHYPWR);
++
++              rst = readl(drv->reg_phy + EXYNOS_4212_UPHYRST);
++              rst |= rstbits;
++              writel(rst, drv->reg_phy + EXYNOS_4212_UPHYRST);
++              udelay(10);
++              rst &= ~rstbits;
++              writel(rst, drv->reg_phy + EXYNOS_4212_UPHYRST);
++      } else {
++              pwr = readl(drv->reg_phy + EXYNOS_4212_UPHYPWR);
++              pwr |= phypwr;
++              writel(pwr, drv->reg_phy + EXYNOS_4212_UPHYPWR);
++      }
++}
++
++static int exynos4212_power_on(struct uphy_instance *inst)
++{
++      struct uphy_driver *drv = inst->drv;
++
++      if (inst->state == STATE_ON) {
++              dev_err(drv->dev, "usb phy \"%s\" already on",
++                                                      inst->cfg->label);
++              return -ENODEV;
++      }
++
++      inst->state = STATE_ON;
++      inst->ref_cnt++;
++      if (inst->ref_cnt > 1)
++              return 0;
++
++      exynos4212_isol(inst, 0);
++      exynos4212_phy_pwr(inst, 1);
++
++      /* Power on the device, as it is necessary for HSIC to work */
++      if (inst->cfg->id == EXYNOS4212_HSIC0) {
++              struct uphy_instance *device =
++                                      &drv->uphy_instances[EXYNOS4212_DEVICE];
++              device->ref_cnt++;
++              if (device->ref_cnt > 1)
++                      return 0;
++              exynos4212_phy_pwr(device, 1);
++              exynos4212_isol(device, 0);
++      }
++
++      return 0;
++}
++
++static int exynos4212_power_off(struct uphy_instance *inst)
++{
++      struct uphy_driver *drv = inst->drv;
++
++      if (inst->state == STATE_OFF) {
++              dev_err(drv->dev, "usb phy \"%s\" already off",
++                                                      inst->cfg->label);
++              return -EINVAL;
++      }
++
++      inst->state = STATE_OFF;
++      inst->ref_cnt--;
++
++      if (inst->ref_cnt > 0)
++              return 0;
++
++      exynos4212_phy_pwr(inst, 0);
++      exynos4212_isol(inst, 1);
++
++      if (inst->cfg->id == EXYNOS4212_HSIC0) {
++              struct uphy_instance *device =
++                                      &drv->uphy_instances[EXYNOS4212_DEVICE];
++              device->ref_cnt--;
++              if (device->ref_cnt > 0)
++                      return 0;
++              exynos4212_phy_pwr(device, 0);
++              exynos4212_isol(device, 1);
++      }
++
++      return 0;
++}
++
++
++static const struct common_phy exynos4212_phys[] = {
++      {
++              .label          = "device",
++              .type           = PHY_DEVICE,
++              .id             = EXYNOS4212_DEVICE,
++              .rate_to_clk    = exynos4212_rate_to_clk,
++              .power_on       = exynos4212_power_on,
++              .power_off      = exynos4212_power_off,
++      },
++      {
++              .label          = "host",
++              .type           = PHY_HOST,
++              .id             = EXYNOS4212_HOST,
++              .rate_to_clk    = exynos4212_rate_to_clk,
++              .power_on       = exynos4212_power_on,
++              .power_off      = exynos4212_power_off,
++      },
++      {
++              .label          = "hsic0",
++              .type           = PHY_HOST,
++              .id             = EXYNOS4212_HSIC0,
++              .rate_to_clk    = exynos4212_rate_to_clk,
++              .power_on       = exynos4212_power_on,
++              .power_off      = exynos4212_power_off,
++      },
++      {
++              .label          = "hsic1",
++              .type           = PHY_HOST,
++              .id             = EXYNOS4212_HSIC1,
++              .rate_to_clk    = exynos4212_rate_to_clk,
++              .power_on       = exynos4212_power_on,
++              .power_off      = exynos4212_power_off,
++      },
++      {},
++};
++
++const struct uphy_config exynos4212_uphy_config = {
++      .cpu            = TYPE_EXYNOS4212,
++      .num_phys       = EXYNOS4212_NUM_PHYS,
++      .phys           = exynos4212_phys,
++};
++
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0766-usb-ehci-s5p-Change-to-use-phy-provided-by-the-gener.patch b/patches.tizen/0766-usb-ehci-s5p-Change-to-use-phy-provided-by-the-gener.patch
new file mode 100644 (file)
index 0000000..3258605
--- /dev/null
@@ -0,0 +1,98 @@
+From 59b98651d1e55c77b9b71f0b611a4ba7f8edaad7 Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Wed, 31 Jul 2013 10:43:00 +0200
+Subject: [PATCH 0766/1302] usb: ehci-s5p: Change to use phy provided by the
+ generic phy framework
+
+Change the phy provider used from the old usb phy specific to a new one
+using the generic phy framework.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/host/ehci-s5p.c | 23 +++++++++--------------
+ 1 file changed, 9 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
+index 671de95..c0b3ebd 100644
+--- a/drivers/usb/host/ehci-s5p.c
++++ b/drivers/usb/host/ehci-s5p.c
+@@ -19,6 +19,7 @@
+ #include <linux/module.h>
+ #include <linux/of.h>
+ #include <linux/of_gpio.h>
++#include <linux/phy/phy.h>
+ #include <linux/platform_device.h>
+ #include <linux/platform_data/usb-ehci-s5p.h>
+ #include <linux/usb/phy.h>
+@@ -49,7 +50,7 @@ static struct hc_driver __read_mostly s5p_ehci_hc_driver;
+ struct s5p_ehci_hcd {
+       struct clk *clk;
+       int power_on;
+-      struct usb_phy *phy;
++      struct phy *phy;
+       struct usb_otg *otg;
+       struct usb_bus *host;
+       struct s5p_ehci_platdata *pdata;
+@@ -60,11 +61,8 @@ struct s5p_ehci_hcd {
+ static void s5p_ehci_phy_enable(struct s5p_ehci_hcd *s5p_ehci,
+                                               struct platform_device *pdev)
+ {
+-      if (s5p_ehci->phy) {
+-              if (s5p_ehci->otg)
+-                      otg_set_host(s5p_ehci->otg, s5p_ehci->host);
+-              usb_phy_init(s5p_ehci->phy);
+-      }
++      if (s5p_ehci->phy)
++              phy_power_on(s5p_ehci->phy);
+       else if (s5p_ehci->pdata->phy_init)
+               s5p_ehci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
+ }
+@@ -72,11 +70,8 @@ static void s5p_ehci_phy_enable(struct s5p_ehci_hcd *s5p_ehci,
+ static void s5p_ehci_phy_disable(struct s5p_ehci_hcd *s5p_ehci,
+                                                struct platform_device *pdev)
+ {
+-      if (s5p_ehci->phy) {
+-              if (s5p_ehci->otg)
+-                      otg_set_host(s5p_ehci->otg, NULL);
+-              usb_phy_shutdown(s5p_ehci->phy);
+-      }
++      if (s5p_ehci->phy)
++              phy_power_off(s5p_ehci->phy);
+       else if (s5p_ehci->pdata->phy_exit)
+               s5p_ehci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
+ }
+@@ -197,10 +192,10 @@ static int s5p_ehci_probe(struct platform_device *pdev)
+ {
+       struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
+       struct s5p_ehci_hcd *s5p_ehci;
++      struct phy *phy;
+       struct usb_hcd *hcd;
+       struct ehci_hcd *ehci;
+       struct resource *res;
+-      struct usb_phy *phy;
+       int irq;
+       int err;
+@@ -223,7 +218,7 @@ static int s5p_ehci_probe(struct platform_device *pdev)
+               return -ENOMEM;
+       }
+       s5p_ehci = to_s5p_ehci(hcd);
+-      phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
++      phy =  devm_phy_get(&pdev->dev, "hsic0");
+       if (IS_ERR(phy)) {
+               /* Fallback to pdata */
+               if (!pdata) {
+@@ -235,7 +230,7 @@ static int s5p_ehci_probe(struct platform_device *pdev)
+               }
+       } else {
+               s5p_ehci->phy = phy;
+-              s5p_ehci->otg = phy->otg;
++/*            s5p_ehci->otg = phy->otg;*/
+       }
+       s5p_ehci->clk = devm_clk_get(&pdev->dev, "usbhost");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0767-usb-s3c-hsotg-Use-the-new-Exynos-USB-phy-driver-with.patch b/patches.tizen/0767-usb-s3c-hsotg-Use-the-new-Exynos-USB-phy-driver-with.patch
new file mode 100644 (file)
index 0000000..8ec7444
--- /dev/null
@@ -0,0 +1,93 @@
+From 92c10821d700ae818671950363e5cb8eb4a3bf50 Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Wed, 31 Jul 2013 12:04:33 +0200
+Subject: [PATCH 0767/1302] usb: s3c-hsotg: Use the new Exynos USB phy driver
+ with the generic phy framework
+
+Change the used phy driver to the new Exynos USB phy driver that uses the
+generic phy framework.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/s3c-hsotg.c | 19 +++++++++----------
+ 1 file changed, 9 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
+index afcd326..0ec467f 100644
+--- a/drivers/usb/gadget/s3c-hsotg.c
++++ b/drivers/usb/gadget/s3c-hsotg.c
+@@ -30,6 +30,7 @@
+ #include <linux/clk.h>
+ #include <linux/regulator/consumer.h>
+ #include <linux/of_platform.h>
++#include <linux/phy/phy.h>
+ #include <linux/usb/ch9.h>
+ #include <linux/usb/gadget.h>
+@@ -133,6 +134,7 @@ struct s3c_hsotg_ep {
+ /**
+  * struct s3c_hsotg - driver state.
+  * @dev: The parent device supplied to the probe function
++
+  * @driver: USB gadget driver
+  * @phy: The otg phy transceiver structure for phy control.
+  * @plat: The platform specific configuration data. This can be removed once
+@@ -156,7 +158,7 @@ struct s3c_hsotg_ep {
+ struct s3c_hsotg {
+       struct device            *dev;
+       struct usb_gadget_driver *driver;
+-      struct usb_phy          *phy;
++      struct phy               *phy;
+       struct s3c_hsotg_plat    *plat;
+       spinlock_t              lock;
+@@ -2823,14 +2825,11 @@ static void s3c_hsotg_phy_enable(struct s3c_hsotg *hsotg)
+       dev_dbg(hsotg->dev, "pdev 0x%p\n", pdev);
+-      if (hsotg->phy) {
+-              struct usb_otg *otg = hsotg->phy->otg;
+-              if (otg && otg->set_host)
+-                      otg->set_host(otg, NULL);
+-              usb_phy_init(hsotg->phy);
+-      }
++      if (hsotg->phy)
++              phy_power_on(hsotg->phy);
+       else if (hsotg->plat->phy_init)
+               hsotg->plat->phy_init(pdev, hsotg->plat->phy_type);
++
+ }
+ /**
+@@ -2845,7 +2844,7 @@ static void s3c_hsotg_phy_disable(struct s3c_hsotg *hsotg)
+       struct platform_device *pdev = to_platform_device(hsotg->dev);
+       if (hsotg->phy)
+-              usb_phy_shutdown(hsotg->phy);
++              phy_power_off(hsotg->phy);
+       else if (hsotg->plat->phy_exit)
+               hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type);
+ }
+@@ -3455,7 +3454,7 @@ static void s3c_hsotg_delete_debug(struct s3c_hsotg *hsotg)
+ static int s3c_hsotg_probe(struct platform_device *pdev)
+ {
+       struct s3c_hsotg_plat *plat = pdev->dev.platform_data;
+-      struct usb_phy *phy;
++      struct phy *phy;
+       struct device *dev = &pdev->dev;
+       struct s3c_hsotg_ep *eps;
+       struct s3c_hsotg *hsotg;
+@@ -3470,7 +3469,7 @@ static int s3c_hsotg_probe(struct platform_device *pdev)
+               return -ENOMEM;
+       }
+-      phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
++      phy = devm_phy_get(&pdev->dev, "device");
+       if (IS_ERR(phy)) {
+               /* Fallback for pdata */
+               plat = pdev->dev.platform_data;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0768-ARM-dts-Add-new-USB-PHY-driver-to-dts-of-exynos4412-.patch b/patches.tizen/0768-ARM-dts-Add-new-USB-PHY-driver-to-dts-of-exynos4412-.patch
new file mode 100644 (file)
index 0000000..2fd8574
--- /dev/null
@@ -0,0 +1,69 @@
+From b10fd659d83cf58d7edb6d5f773ec09034483438 Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Mon, 9 Sep 2013 16:43:47 +0200
+Subject: [PATCH 0768/1302] ARM: dts: Add new USB PHY driver to dts of
+ exynos4412-slp_pq
+
+This patch adds device tree nodes supporting new USB PHY driver using the
+Generic PHY Framework to slp_pq target.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 23 +++++++++++++++++++----
+ 1 file changed, 19 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index f99f2c2..796c0c3 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -1053,20 +1053,21 @@
+               mmu-master = <&g2d>;
+       };
+-      usbphy@125B0000 {
+-              status = "okay";
+-      };
+-
+       hsotg@12480000 {
+               status = "okay";
+               vusb_d-supply = <&ldo15_reg>;
+               vusb_a-supply = <&ldo12_reg>;
++              phys = <&exynos_usbphy 0>;
++              phy-names = "device";
+       };
+       ehci@12580000 {
+               status = "okay";
++              phys = <&exynos_usbphy 2>;
++              phy-names = "hsic0";
+       };
++
+       spi_1: spi@13930000 {
+               pinctrl-names = "default";
+               pinctrl-0 = <&spi1_bus>;
+@@ -1299,6 +1300,20 @@
+               pinctrl-names = "default";
+               status = "okay";
+       };
++
++
++      exynos_usbphy: exynos-usbphy@125B0000 {
++              compatible = "samsung,exynos4212-usbphy";
++              reg = <0x125B0000 0x100 0x10020704 0x0c 0x1001021c 0x4>;
++              ranges;
++              #address-cells = <1>;
++              #size-cells = <1>;
++              clocks = <&clock 305>, <&clock 2>, <&clock 2>, <&clock 2>,
++                                                              <&clock 2>;
++              clock-names = "phy", "device", "host", "hsic0", "hsic1";
++              status = "okay";
++              #phy-cells = <1>;
++      };
+ };
+ &pinctrl_1 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0769-tizen_defconfig-update.patch b/patches.tizen/0769-tizen_defconfig-update.patch
new file mode 100644 (file)
index 0000000..405d48b
--- /dev/null
@@ -0,0 +1,57 @@
+From 5cd67eefc7213cb6d9fc1d243af533182ac8ebc0 Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Mon, 9 Sep 2013 16:52:59 +0200
+Subject: [PATCH 0769/1302] tizen_defconfig update
+
+Enable the new USB PHY driver using the Generic PHY Framework and enable
+EHCI driver (it works well with new PHY driver).
+Disable the old USB PHY driver.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_defconfig | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index 02ff16b..5062ba0 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -2341,7 +2341,7 @@ CONFIG_USB_DEFAULT_PERSIST=y
+ CONFIG_USB_EHCI_HCD=y
+ # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+ CONFIG_USB_EHCI_TT_NEWSCHED=y
+-# CONFIG_USB_EHCI_S5P is not set
++CONFIG_USB_EHCI_S5P=y
+ # CONFIG_USB_EHCI_HCD_PLATFORM is not set
+ # CONFIG_USB_OXU210HP_HCD is not set
+ # CONFIG_USB_ISP116X_HCD is not set
+@@ -2412,8 +2412,7 @@ CONFIG_USB_PHY=y
+ # CONFIG_NOP_USB_XCEIV is not set
+ # CONFIG_OMAP_CONTROL_USB is not set
+ # CONFIG_OMAP_USB3 is not set
+-CONFIG_SAMSUNG_USBPHY=y
+-CONFIG_SAMSUNG_USB2PHY=y
++# CONFIG_SAMSUNG_USB2PHY is not set
+ # CONFIG_SAMSUNG_USB3PHY is not set
+ # CONFIG_USB_GPIO_VBUS is not set
+ # CONFIG_USB_ISP1301 is not set
+@@ -2964,8 +2963,15 @@ CONFIG_ARM_GIC=y
+ CONFIG_GIC_NON_BANKED=y
+ # CONFIG_IPACK_BUS is not set
+ # CONFIG_RESET_CONTROLLER is not set
++
++#
++# PHY Subsystem
++#
+ CONFIG_GENERIC_PHY=y
+ CONFIG_PHY_EXYNOS_MIPI_VIDEO=y
++CONFIG_PHY_EXYNOS_USB=y
++CONFIG_PHY_EXYNOS4210_USB=y
++CONFIG_PHY_EXYNOS4212_USB=y
+ #
+ # File systems
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0770-drm-exynos-fixed-YCbCr-start-addresses-port-for-inpu.patch b/patches.tizen/0770-drm-exynos-fixed-YCbCr-start-addresses-port-for-inpu.patch
new file mode 100644 (file)
index 0000000..0047ac2
--- /dev/null
@@ -0,0 +1,52 @@
+From 8e6b648a3c013b4a9f11d67d339504ee6bffba4b Mon Sep 17 00:00:00 2001
+From: Donghwa Lee <dh09.lee@samsung.com>
+Date: Tue, 10 Sep 2013 14:03:26 +0900
+Subject: [PATCH 0770/1302] drm: exynos: fixed YCbCr start addresses port for
+ input DMA with 0
+
+fixed YCbCr start addresses port for input DMA with 0.
+
+Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_fimc.c | 14 +++++---------
+ 1 file changed, 5 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+index 99d35b8..3e137ae 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+@@ -726,25 +726,21 @@ static int fimc_src_set_addr(struct device *dev,
+       case IPP_BUF_ENQUEUE:
+               config = &property->config[EXYNOS_DRM_OPS_SRC];
+               fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_Y],
+-                      EXYNOS_CIIYSA(buf_id));
++                      EXYNOS_CIIYSA(0));
+               if (config->fmt == DRM_FORMAT_YVU420) {
+                       fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CR],
+-                              EXYNOS_CIICBSA(buf_id));
++                              EXYNOS_CIICBSA(0));
+                       fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CB],
+-                              EXYNOS_CIICRSA(buf_id));
++                              EXYNOS_CIICRSA(0));
+               } else {
+                       fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CB],
+-                              EXYNOS_CIICBSA(buf_id));
++                              EXYNOS_CIICBSA(0));
+                       fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CR],
+-                              EXYNOS_CIICRSA(buf_id));
++                              EXYNOS_CIICRSA(0));
+               }
+               break;
+       case IPP_BUF_DEQUEUE:
+-              fimc_write(0x0, EXYNOS_CIIYSA(buf_id));
+-              fimc_write(0x0, EXYNOS_CIICBSA(buf_id));
+-              fimc_write(0x0, EXYNOS_CIICRSA(buf_id));
+-              break;
+       default:
+               /* bypass */
+               break;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0771-mmc-dw-mmc-check-whether-card-is-busy-or-not-before-.patch b/patches.tizen/0771-mmc-dw-mmc-check-whether-card-is-busy-or-not-before-.patch
new file mode 100644 (file)
index 0000000..bb28cca
--- /dev/null
@@ -0,0 +1,82 @@
+From e07f849566a05d85e31b69fa00cf0cf0f407316b Mon Sep 17 00:00:00 2001
+From: Jaehoon Chung <jh80.chung@samsung.com>
+Date: Tue, 10 Sep 2013 17:43:03 +0900
+Subject: [PATCH 0771/1302] mmc: dw-mmc: check whether card is busy or not,
+ before clock disabled.
+
+Before disable the clock, must check whether card is busy or not.
+(Refer to DesignWare TRM)
+
+Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mmc/host/dw_mmc.c | 39 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 39 insertions(+)
+
+diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
+index 564c9fb..c6deb2b 100644
+--- a/drivers/mmc/host/dw_mmc.c
++++ b/drivers/mmc/host/dw_mmc.c
+@@ -310,6 +310,27 @@ static void dw_mci_stop_dma(struct dw_mci *host)
+       }
+ }
++static bool dw_mci_wait_reset(struct device *dev, struct dw_mci *host,
++              unsigned int reset_val)
++{
++      unsigned long timeout = jiffies + msecs_to_jiffies(500);
++      unsigned int ctrl;
++
++      ctrl = mci_readl(host, CTRL);
++      ctrl |= reset_val;
++      mci_writel(host, CTRL, ctrl);
++
++      /* wait till resets clear */
++      do {
++              if (!(mci_readl(host, CTRL) & reset_val))
++                      return true;
++      } while (time_before(jiffies, timeout));
++
++      dev_err(dev, "Timeout resetting block (ctrl %#x)\n", ctrl);
++
++      return false;
++}
++
+ static int dw_mci_get_dma_dir(struct mmc_data *data)
+ {
+       if (data->flags & MMC_DATA_WRITE)
+@@ -634,6 +655,7 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
+       struct dw_mci *host = slot->host;
+       u32 div;
+       u32 clk_en_a;
++      int timeout = 1000;
+       if (slot->clock != host->current_speed || force_clkinit) {
+               div = host->bus_hz / slot->clock;
+@@ -651,6 +673,23 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
+                        " div = %d)\n", slot->id, host->bus_hz, slot->clock,
+                        div ? ((host->bus_hz / div) >> 1) : host->bus_hz, div);
++              /*
++               * Before disable the clock,
++               * must check whether the card is busy or not.
++               */
++              do {
++                      if (!(mci_readl(host, STATUS) & BIT(9)))
++                              break;
++                      if (timeout-- < 0) {
++                              dev_err(host->dev, "Can't disable clock"
++                                              "because Card is busy!!\n");
++                              return;
++                      }
++                      host->cur_slot = slot;
++                      dw_mci_wait_reset(host->dev, host, SDMMC_CTRL_RESET);
++
++              } while (1);
++
+               /* disable clock */
+               mci_writel(host, CLKENA, 0);
+               mci_writel(host, CLKSRC, 0);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0772-phy-Correct-Exynos-USB-PHY-device-tree-documentation.patch b/patches.tizen/0772-phy-Correct-Exynos-USB-PHY-device-tree-documentation.patch
new file mode 100644 (file)
index 0000000..1342768
--- /dev/null
@@ -0,0 +1,34 @@
+From ff924ae33fa8404bddbcfe3c8fbc662bb2222cee Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Tue, 10 Sep 2013 18:07:12 +0200
+Subject: [PATCH 0772/1302] phy: Correct Exynos USB PHY device tree
+ documentation
+
+Some values (ranges, address-cells, size-cells) were not used hence
+they were removed.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/devicetree/bindings/phy/samsung-usbphy.txt | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/phy/samsung-usbphy.txt b/Documentation/devicetree/bindings/phy/samsung-usbphy.txt
+index f112b37..f618e8d 100644
+--- a/Documentation/devicetree/bindings/phy/samsung-usbphy.txt
++++ b/Documentation/devicetree/bindings/phy/samsung-usbphy.txt
+@@ -31,10 +31,7 @@ For Exynos 4412 (compatible with Exynos 4212):
+ exynos_usbphy: exynos-usbphy@125B0000 {
+       compatible = "samsung,exynos4212-usbphy";
+-      reg = <0x125B0000 0x100 0x10020704 0x0c 0x1001021c 0x4>;
+-      ranges;
+-      #address-cells = <1>;
+-      #size-cells = <1>;
++      reg = <0x125B0000 0x100>, <0x10020704 0x0c>, <0x1001021c 0x4>;
+       clocks = <&clock 305>, <&clock 2>, <&clock 2>, <&clock 2>,
+                                                       <&clock 2>;
+       clock-names = "phy", "device", "host", "hsic0", "hsic1";
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0773-ARM-dts-Correct-USB-PHY-use-in-exynos4412-slp_pq.dts.patch b/patches.tizen/0773-ARM-dts-Correct-USB-PHY-use-in-exynos4412-slp_pq.dts.patch
new file mode 100644 (file)
index 0000000..97a6785
--- /dev/null
@@ -0,0 +1,34 @@
+From 6381b9485508560837f2ee43f06cb25d4709ae3e Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Tue, 10 Sep 2013 18:08:49 +0200
+Subject: [PATCH 0773/1302] ARM: dts: Correct USB PHY use in
+ exynos4412-slp_pq.dts
+
+Some values (ranges, address-cells, size-cells) were not used hence they
+were removed.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 796c0c3..6907e59 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -1304,10 +1304,7 @@
+       exynos_usbphy: exynos-usbphy@125B0000 {
+               compatible = "samsung,exynos4212-usbphy";
+-              reg = <0x125B0000 0x100 0x10020704 0x0c 0x1001021c 0x4>;
+-              ranges;
+-              #address-cells = <1>;
+-              #size-cells = <1>;
++              reg = <0x125B0000 0x100>, <0x10020704 0x0c>, <0x1001021c 0x4>;
+               clocks = <&clock 305>, <&clock 2>, <&clock 2>, <&clock 2>,
+                                                               <&clock 2>;
+               clock-names = "phy", "device", "host", "hsic0", "hsic1";
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0774-mmc-core-Update-the-ext-csd.rev-check-for-eMMC5.1.patch b/patches.tizen/0774-mmc-core-Update-the-ext-csd.rev-check-for-eMMC5.1.patch
new file mode 100644 (file)
index 0000000..b77c25b
--- /dev/null
@@ -0,0 +1,34 @@
+From 9629d4d019b0754422e2275e864751a6b518ce2d Mon Sep 17 00:00:00 2001
+From: Yuvaraj Kumar C D <yuvaraj.cd@gmail.com>
+Date: Tue, 21 May 2013 15:08:43 +0530
+Subject: [PATCH 0774/1302] mmc: core: Update the ext-csd.rev check for eMMC5.1
+
+With the new eMMC5.1 spec, there is a new EXT_CSD register with
+the revision number(EXT_CSD_REV) 7. This patch updates the check
+for ext-csd.rev number as 7.
+
+Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
+Signed-off-by: Yuvaraj Kumar C D <yuvaraj.cd@samsung.com>
+Reviewed-by: Doug Anderson <dianders@chromium.org>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mmc/core/mmc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
+index 0cbd1ef..73f58e0 100644
+--- a/drivers/mmc/core/mmc.c
++++ b/drivers/mmc/core/mmc.c
+@@ -293,7 +293,7 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
+       }
+       card->ext_csd.rev = ext_csd[EXT_CSD_REV];
+-      if (card->ext_csd.rev > 6) {
++      if (card->ext_csd.rev > 7) {
+               pr_err("%s: unrecognised EXT_CSD revision %d\n",
+                       mmc_hostname(card->host), card->ext_csd.rev);
+               err = -EINVAL;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0775-drivers-usb-s3c-hsotg-fix-gadget-unregistering.patch b/patches.tizen/0775-drivers-usb-s3c-hsotg-fix-gadget-unregistering.patch
new file mode 100644 (file)
index 0000000..8d8cd1c
--- /dev/null
@@ -0,0 +1,46 @@
+From 3d9b28cfa48a9b8434190eec71cafb4cce123de5 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Tue, 13 Aug 2013 12:59:10 +0200
+Subject: [PATCH 0775/1302] drivers: usb: s3c-hsotg: fix gadget unregistering
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/s3c-hsotg.c | 10 +++-------
+ 1 file changed, 3 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
+index 0ec467f..69f9c5e 100644
+--- a/drivers/usb/gadget/s3c-hsotg.c
++++ b/drivers/usb/gadget/s3c-hsotg.c
+@@ -2964,9 +2964,6 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget,
+       if (!hsotg)
+               return -ENODEV;
+-      if (!driver || driver != hsotg->driver || !driver->unbind)
+-              return -EINVAL;
+-
+       /* all endpoints should be shutdown */
+       for (ep = 0; ep < hsotg->num_of_eps; ep++)
+               s3c_hsotg_ep_disable(&hsotg->eps[ep].ep);
+@@ -2976,14 +2973,13 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget,
+       s3c_hsotg_phy_disable(hsotg);
+       regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
+-      hsotg->driver = NULL;
++      if (!driver)
++              hsotg->driver = NULL;
++
+       hsotg->gadget.speed = USB_SPEED_UNKNOWN;
+       spin_unlock_irqrestore(&hsotg->lock, flags);
+-      dev_info(hsotg->dev, "unregistered gadget driver '%s'\n",
+-               driver->driver.name);
+-
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0776-usb-gadget-s3c-hsotg-fix-non-dt-build.patch b/patches.tizen/0776-usb-gadget-s3c-hsotg-fix-non-dt-build.patch
new file mode 100644 (file)
index 0000000..bfebec4
--- /dev/null
@@ -0,0 +1,26 @@
+From 12e8bc7881160ec5efc15289ebe9a350e018e759 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Thu, 27 Jun 2013 07:33:28 +0200
+Subject: [PATCH 0776/1302] usb/gadget: s3c-hsotg: fix non-dt build
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/s3c-hsotg.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
+index 69f9c5e..da11a07 100644
+--- a/drivers/usb/gadget/s3c-hsotg.c
++++ b/drivers/usb/gadget/s3c-hsotg.c
+@@ -29,6 +29,7 @@
+ #include <linux/slab.h>
+ #include <linux/clk.h>
+ #include <linux/regulator/consumer.h>
++#include <linux/of.h>
+ #include <linux/of_platform.h>
+ #include <linux/phy/phy.h>
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0777-USB-gadget-s3c-hsotg-fix-protocol-stall-handling.patch b/patches.tizen/0777-USB-gadget-s3c-hsotg-fix-protocol-stall-handling.patch
new file mode 100644 (file)
index 0000000..559d76a
--- /dev/null
@@ -0,0 +1,51 @@
+From e9c756a7fc70defec57389d9447baaf391d6127d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Robert=20Ba=C5=82dyga?= <r.baldyga@samsung.com>
+Date: Mon, 9 Sep 2013 10:44:28 +0200
+Subject: [PATCH 0777/1302] USB: gadget: s3c-hsotg: fix "protocol stall"
+ handling
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+After normal handling of SetupDone interrupt, XferCompl interrupt occurs, and
+then we enqueue new setup request. But when ep0 is stalled, there is no
+XferCompl, so we have to enqueue setup request immediately after stalling ep.
+Otherwise incoming control requests won't be processed correctly.
+
+Signed-off-by: Robert Bałdyga <r.baldyga@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/s3c-hsotg.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
+index da11a07..8eb41d3 100644
+--- a/drivers/usb/gadget/s3c-hsotg.c
++++ b/drivers/usb/gadget/s3c-hsotg.c
+@@ -1151,6 +1151,8 @@ static int s3c_hsotg_process_req_feature(struct s3c_hsotg *hsotg,
+       return 1;
+ }
++static void s3c_hsotg_enqueue_setup(struct s3c_hsotg *hsotg);
++
+ /**
+  * s3c_hsotg_process_control - process a control request
+  * @hsotg: The device state
+@@ -1250,11 +1252,12 @@ static void s3c_hsotg_process_control(struct s3c_hsotg *hsotg,
+                * don't believe we need to anything more to get the EP
+                * to reply with a STALL packet
+                */
++
++               /* complete won't by called, so we enqueue setup request here */
++               s3c_hsotg_enqueue_setup(hsotg);
+       }
+ }
+-static void s3c_hsotg_enqueue_setup(struct s3c_hsotg *hsotg);
+-
+ /**
+  * s3c_hsotg_complete_setup - completion of a setup transfer
+  * @ep: The endpoint the request was on.
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0778-USB-gadget-s3c-hsotg-fix-dedicated-fifos-handling.patch b/patches.tizen/0778-USB-gadget-s3c-hsotg-fix-dedicated-fifos-handling.patch
new file mode 100644 (file)
index 0000000..529bb88
--- /dev/null
@@ -0,0 +1,131 @@
+From eb5c95bfa69fdc9002068c3c1ba5bc15376ba9fe Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Robert=20Ba=C5=82dyga?= <r.baldyga@samsung.com>
+Date: Mon, 9 Sep 2013 10:44:37 +0200
+Subject: [PATCH 0778/1302] USB: gadget: s3c-hsotg: fix dedicated fifos
+ handling
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This patch adds few fixes:
+- In s3c_hsotg_write_fifo function PTxFEmp/NPTxFEmp interrupts are enabled
+  only in shared-fifo mode. In dedicated-fifo mode they should not be used
+  (when enabled then cause interrupt storm).
+- When s3c_hsotg_trytx is called for ep without enqueued request, interrupts
+  for this ep are disabled, to prevent interrupt flooding. Interrupts are
+  enabled when new request for this ep is starting.
+- In s3c_hsotg_core_init enabled INTknTXFEmpMsk, becouse without this mask
+  TxFIFOEmpty interrupt does not occur.
+- In OEPInt/IEPInt interrupts handling added bitwise and of DAINT and
+  DAINTMSK, because we should handle masked interrupts only.
+
+Signed-off-by: Robert Bałdyga <r.baldyga@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/s3c-hsotg.c | 48 ++++++++++++++++++++++++++++++------------
+ 1 file changed, 34 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
+index 8eb41d3..5874a0f 100644
+--- a/drivers/usb/gadget/s3c-hsotg.c
++++ b/drivers/usb/gadget/s3c-hsotg.c
+@@ -558,9 +558,11 @@ static int s3c_hsotg_write_fifo(struct s3c_hsotg *hsotg,
+       if (to_write > hs_ep->ep.maxpacket) {
+               to_write = hs_ep->ep.maxpacket;
+-              s3c_hsotg_en_gsint(hsotg,
+-                                 periodic ? GINTSTS_PTxFEmp :
+-                                 GINTSTS_NPTxFEmp);
++              /* it's needed only when we do not use dedicated fifos */
++              if (!hsotg->dedicated_fifos)
++                      s3c_hsotg_en_gsint(hsotg,
++                                         periodic ? GINTSTS_PTxFEmp :
++                                         GINTSTS_NPTxFEmp);
+       }
+       /* see if we can write data */
+@@ -585,9 +587,11 @@ static int s3c_hsotg_write_fifo(struct s3c_hsotg *hsotg,
+                * is more room left.
+                */
+-              s3c_hsotg_en_gsint(hsotg,
+-                                 periodic ? GINTSTS_PTxFEmp :
+-                                 GINTSTS_NPTxFEmp);
++              /* it's needed only when we do not use dedicated fifos */
++              if (!hsotg->dedicated_fifos)
++                      s3c_hsotg_en_gsint(hsotg,
++                                         periodic ? GINTSTS_PTxFEmp :
++                                         GINTSTS_NPTxFEmp);
+       }
+       dev_dbg(hsotg->dev, "write %d/%d, can_write %d, done %d\n",
+@@ -824,6 +828,9 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg,
+       dev_dbg(hsotg->dev, "%s: DxEPCTL=0x%08x\n",
+               __func__, readl(hsotg->regs + epctrl_reg));
++
++      /* enable ep interrupts */
++      s3c_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 1);
+ }
+ /**
+@@ -1789,8 +1796,15 @@ static int s3c_hsotg_trytx(struct s3c_hsotg *hsotg,
+ {
+       struct s3c_hsotg_req *hs_req = hs_ep->req;
+-      if (!hs_ep->dir_in || !hs_req)
++      if (!hs_ep->dir_in || !hs_req) {
++              /**
++               * if request is not enqueued, we disable interrupts for endpoints,
++               * excepting ep0
++               */
++              if (hs_ep->index != 0)
++                      s3c_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 0);
+               return 0;
++      }
+       if (hs_req->req.actual < hs_req->req.length) {
+               dev_dbg(hsotg->dev, "trying to write more for ep%d\n",
+@@ -2248,15 +2262,17 @@ static void s3c_hsotg_core_init(struct s3c_hsotg *hsotg)
+                      GAHBCFG_HBstLen_Incr4,
+                      hsotg->regs + GAHBCFG);
+       else
+-              writel(GAHBCFG_GlblIntrEn, hsotg->regs + GAHBCFG);
++              writel(GAHBCFG_GlblIntrEn | GAHBCFG_NPTxFEmpLvl,
++                     hsotg->regs + GAHBCFG);
+       /*
+-       * Enabling INTknTXFEmpMsk here seems to be a big mistake, we end
+-       * up being flooded with interrupts if the host is polling the
+-       * endpoint to try and read data.
++       * If INTknTXFEmpMsk is enabled, it's important to disable ep interrupts
++       * when we have no data to transfer. Otherwise we get being flooded by
++       * interrupts.
+        */
+-      writel(((hsotg->dedicated_fifos) ? DIEPMSK_TxFIFOEmpty : 0) |
++      writel(((hsotg->dedicated_fifos) ? DIEPMSK_TxFIFOEmpty |
++             DIEPMSK_INTknTXFEmpMsk : 0) |
+              DIEPMSK_EPDisbldMsk | DIEPMSK_XferComplMsk |
+              DIEPMSK_TimeOUTMsk | DIEPMSK_AHBErrMsk |
+              DIEPMSK_INTknEPMisMsk,
+@@ -2385,10 +2401,14 @@ irq_retry:
+       if (gintsts & (GINTSTS_OEPInt | GINTSTS_IEPInt)) {
+               u32 daint = readl(hsotg->regs + DAINT);
+-              u32 daint_out = daint >> DAINT_OutEP_SHIFT;
+-              u32 daint_in = daint & ~(daint_out << DAINT_OutEP_SHIFT);
++              u32 daintmsk = readl(hsotg->regs + DAINTMSK);
++              u32 daint_out, daint_in;
+               int ep;
++              daint &= daintmsk;
++              daint_out = daint >> DAINT_OutEP_SHIFT;
++              daint_in = daint & ~(daint_out << DAINT_OutEP_SHIFT);
++
+               dev_dbg(hsotg->dev, "%s: daint=%08x\n", __func__, daint);
+               for (ep = 0; ep < 15 && daint_out; ep++, daint_out >>= 1) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0779-USB-gadget-s3c-hsotg-fix-clear-feature-ENDPOINT_HALT.patch b/patches.tizen/0779-USB-gadget-s3c-hsotg-fix-clear-feature-ENDPOINT_HALT.patch
new file mode 100644 (file)
index 0000000..99148bd
--- /dev/null
@@ -0,0 +1,76 @@
+From 76c8f246404b06901c7ab23a4f50908ed60c7bcb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Robert=20Ba=C5=82dyga?= <r.baldyga@samsung.com>
+Date: Wed, 11 Sep 2013 14:35:02 +0200
+Subject: [PATCH 0779/1302] USB: gadget: s3c-hsotg: fix clear feature
+ ENDPOINT_HALT
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This patch adds two fixes:
+- Property halted of s3c_hsotg_ep structure is actually changed when halt is
+  set/cleared.
+- All requests for endpoint are completed when it was halted, and the halt was
+  cleared by CLEAR_FEATURE, but not when new state is same as previous.
+
+Signed-off-by: Robert Bałdyga <r.baldyga@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/s3c-hsotg.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
+index 5874a0f..f9bd408 100644
+--- a/drivers/usb/gadget/s3c-hsotg.c
++++ b/drivers/usb/gadget/s3c-hsotg.c
+@@ -1102,6 +1102,7 @@ static int s3c_hsotg_process_req_feature(struct s3c_hsotg *hsotg,
+       bool set = (ctrl->bRequest == USB_REQ_SET_FEATURE);
+       struct s3c_hsotg_ep *ep;
+       int ret;
++      bool halted;
+       dev_dbg(hsotg->dev, "%s: %s_FEATURE\n",
+               __func__, set ? "SET" : "CLEAR");
+@@ -1116,6 +1117,8 @@ static int s3c_hsotg_process_req_feature(struct s3c_hsotg *hsotg,
+               switch (le16_to_cpu(ctrl->wValue)) {
+               case USB_ENDPOINT_HALT:
++                      halted = ep->halted;
++
+                       s3c_hsotg_ep_sethalt(&ep->ep, set);
+                       ret = s3c_hsotg_send_reply(hsotg, ep0, NULL, 0);
+@@ -1125,7 +1128,12 @@ static int s3c_hsotg_process_req_feature(struct s3c_hsotg *hsotg,
+                               return ret;
+                       }
+-                      if (!set) {
++                      /*
++                       * we have to complete all requests for ep if it was halted,
++                       * and the halt was cleared by CLEAR_FEATURE
++                       */
++
++                      if (!set || halted) {
+                               /*
+                                * If we have request in progress,
+                                * then complete it
+@@ -2608,6 +2616,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
+       /* default, set to non-periodic */
+       hs_ep->periodic = 0;
++      hs_ep->halted = 0;
+       switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+       case USB_ENDPOINT_XFER_ISOC:
+@@ -2803,6 +2812,8 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value)
+       writel(epctl, hs->regs + epreg);
++      hs_ep->halted = value;
++
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0780-ARM-EXYNOS-Avoid-potential-invalid-genpd-pointer-der.patch b/patches.tizen/0780-ARM-EXYNOS-Avoid-potential-invalid-genpd-pointer-der.patch
new file mode 100644 (file)
index 0000000..9705c63
--- /dev/null
@@ -0,0 +1,35 @@
+From d3caeb1f0d6e21cd545eb14aec19d534769d0703 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Mon, 5 Aug 2013 16:10:52 +0200
+Subject: [PATCH 0780/1302] ARM: EXYNOS: Avoid potential invalid genpd pointer
+ dereference
+
+dev_to_gend() may return an invalid pointer. Make
+exynos_remove_device_from_domain() function return and do
+nothing is such case. This prevents an invalid pointer
+dereference further in the function.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/mach-exynos/pm_domains.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c
+index 9f1351d..435e396 100644
+--- a/arch/arm/mach-exynos/pm_domains.c
++++ b/arch/arm/mach-exynos/pm_domains.c
+@@ -107,6 +107,9 @@ static void exynos_remove_device_from_domain(struct device *dev)
+       struct generic_pm_domain *genpd = dev_to_genpd(dev);
+       int ret;
++      if (IS_ERR(genpd))
++              return;
++
+       dev_dbg(dev, "removing from power domain %s\n", genpd->name);
+       while (1) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0781-exynos4-is-Enable-registration-of-fimc-lite-devices-.patch b/patches.tizen/0781-exynos4-is-Enable-registration-of-fimc-lite-devices-.patch
new file mode 100644 (file)
index 0000000..f876b1d
--- /dev/null
@@ -0,0 +1,50 @@
+From 8dae642d639aa6bf5e87c1238ab1b677b78218cc Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 12 Sep 2013 18:57:41 +0200
+Subject: [PATCH 0781/1302] exynos4-is: Enable registration of fimc-lite
+ devices as children of fimc-is
+
+This allows registration of FIMC-LITE devices also when they are
+specified in device tree as fimc-is subnodes.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/media-dev.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
+index 7125411..55a0900 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.c
++++ b/drivers/media/platform/exynos4-is/media-dev.c
+@@ -783,7 +783,7 @@ static int fimc_md_pdev_match(struct device *dev, void *data)
+ static int fimc_md_register_of_platform_entities(struct fimc_md *fmd,
+                                                struct device_node *parent)
+ {
+-      struct device_node *node;
++      struct device_node *node, *fimc_is_node = NULL;
+       int ret = 0;
+       for_each_available_child_of_node(parent, node) {
+@@ -810,10 +810,16 @@ static int fimc_md_register_of_platform_entities(struct fimc_md *fmd,
+                                                       plat_entity);
+               put_device(&pdev->dev);
+               if (ret < 0)
+-                      break;
++                      return ret;
++
++              if (plat_entity == IDX_IS_ISP)
++                      fimc_is_node = node;
+       }
+-      return ret;
++      if (!fimc_is_node)
++              return 0;
++
++      return fimc_md_register_of_platform_entities(fmd, fimc_is_node);
+ }
+ #else
+ #define fimc_md_register_of_platform_entities(fmd, node) (-ENOSYS)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0782-exynos4-is-Do-not-unnecessarily-activate-fimc-lite-d.patch b/patches.tizen/0782-exynos4-is-Do-not-unnecessarily-activate-fimc-lite-d.patch
new file mode 100644 (file)
index 0000000..8b05cd0
--- /dev/null
@@ -0,0 +1,53 @@
+From bb8ea8ebb561427ab99118332308fcc26925e01e Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 12 Sep 2013 18:47:08 +0200
+Subject: [PATCH 0782/1302] exynos4-is: Do not unnecessarily activate fimc-lite
+ device in probe()
+
+There is no use of temporarily activating the device in probe()
+so remove the pm_runtime_get_sync(), pm_runtime_put() calls.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-lite.c | 13 ++++---------
+ 1 file changed, 4 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
+index 318d4c3..c6016df 100644
+--- a/drivers/media/platform/exynos4-is/fimc-lite.c
++++ b/drivers/media/platform/exynos4-is/fimc-lite.c
+@@ -1558,26 +1558,21 @@ static int fimc_lite_probe(struct platform_device *pdev)
+               goto err_clk;
+       platform_set_drvdata(pdev, fimc);
+-      pm_runtime_enable(dev);
+-      ret = pm_runtime_get_sync(dev);
+-      if (ret < 0)
+-              goto err_sd;
+       fimc->alloc_ctx = vb2_dma_contig_init_ctx(dev);
+       if (IS_ERR(fimc->alloc_ctx)) {
+               ret = PTR_ERR(fimc->alloc_ctx);
+-              goto err_pm;
++              goto err_sd;
+       }
+-      pm_runtime_put(dev);
+-
+       fimc_lite_set_default_config(fimc);
++      pm_runtime_enable(dev);
++
+       dev_dbg(dev, "FIMC-LITE.%d registered successfully\n",
+               fimc->index);
+       return 0;
+-err_pm:
+-      pm_runtime_put(dev);
++
+ err_sd:
+       fimc_lite_unregister_capture_subdev(fimc);
+ err_clk:
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0783-exynos4-is-Do-not-unnecessarily-activate-fimc-device.patch b/patches.tizen/0783-exynos4-is-Do-not-unnecessarily-activate-fimc-device.patch
new file mode 100644 (file)
index 0000000..24c8e25
--- /dev/null
@@ -0,0 +1,50 @@
+From 0a13cdbe7f0dab7b17948774df1c9b1a467d8f8c Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 12 Sep 2013 18:48:04 +0200
+Subject: [PATCH 0783/1302] exynos4-is: Do not unnecessarily activate fimc
+ devices in probe()
+
+There is no use of temporarily activating the device in probe()
+so remove the pm_runtime_get_sync(), pm_runtime_put() calls.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-core.c | 13 ++++---------
+ 1 file changed, 4 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c
+index 5c0f438..6823ce0 100644
+--- a/drivers/media/platform/exynos4-is/fimc-core.c
++++ b/drivers/media/platform/exynos4-is/fimc-core.c
+@@ -1029,23 +1029,18 @@ static int fimc_probe(struct platform_device *pdev)
+               goto err_clk;
+       platform_set_drvdata(pdev, fimc);
+-      pm_runtime_enable(dev);
+-      ret = pm_runtime_get_sync(dev);
+-      if (ret < 0)
+-              goto err_sd;
++
+       /* Initialize contiguous memory allocator */
+       fimc->alloc_ctx = vb2_dma_contig_init_ctx(dev);
+       if (IS_ERR(fimc->alloc_ctx)) {
+               ret = PTR_ERR(fimc->alloc_ctx);
+-              goto err_pm;
++              goto err_sd;
+       }
+-      dev_dbg(dev, "FIMC.%d registered successfully\n", fimc->id);
++      pm_runtime_enable(dev);
+-      pm_runtime_put(dev);
++      dev_dbg(dev, "FIMC.%d registered successfully\n", fimc->id);
+       return 0;
+-err_pm:
+-      pm_runtime_put(dev);
+ err_sd:
+       fimc_unregister_capture_subdev(fimc);
+ err_clk:
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0784-exynos4-is-Do-not-unnecessarily-activate-fimc-is-dev.patch b/patches.tizen/0784-exynos4-is-Do-not-unnecessarily-activate-fimc-is-dev.patch
new file mode 100644 (file)
index 0000000..b4ad78e
--- /dev/null
@@ -0,0 +1,44 @@
+From 95e3cd0fff17bd02de1a9123956ad2fc8b7c8793 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Thu, 12 Sep 2013 18:49:09 +0200
+Subject: [PATCH 0784/1302] exynos4-is: Do not unnecessarily activate fimc-is
+ device in probe()
+
+There is no use of temporarily activating the device in probe()
+so remove the pm_runtime_get_sync(), pm_runtime_put() calls.
+This also fixes a bug on error path.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-is.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c
+index 5d3586d..fc4fda3 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is.c
++++ b/drivers/media/platform/exynos4-is/fimc-is.c
+@@ -824,11 +824,6 @@ static int fimc_is_probe(struct platform_device *pdev)
+               dev_err(dev, "irq request failed\n");
+               goto err_clk;
+       }
+-      pm_runtime_enable(dev);
+-
+-      ret = pm_runtime_get_sync(dev);
+-      if (ret < 0)
+-              goto err_irq;
+       is->alloc_ctx = vb2_dma_contig_init_ctx(dev);
+       if (IS_ERR(is->alloc_ctx)) {
+@@ -851,7 +846,7 @@ static int fimc_is_probe(struct platform_device *pdev)
+       if (ret < 0)
+               goto err_dfs;
+-      pm_runtime_put_sync(dev);
++      pm_runtime_enable(dev);
+       dev_dbg(dev, "FIMC-IS registered successfully\n");
+       return 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0785-exynos4-is-Make-fimc-lite-dependency-on-fimc-is-expl.patch b/patches.tizen/0785-exynos4-is-Make-fimc-lite-dependency-on-fimc-is-expl.patch
new file mode 100644 (file)
index 0000000..8634f65
--- /dev/null
@@ -0,0 +1,40 @@
+From b3ede54f2699ec78fc88b9f59330fc905ac38b8e Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 13 Sep 2013 12:50:21 +0200
+Subject: [PATCH 0785/1302] exynos4-is: Make fimc-lite dependency on fimc-is
+ explicit in Kconfig
+
+For power/clock management reasons FIMC-LITE devices can be used only
+when the FIMC-IS driver is initialized.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/Kconfig | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/Kconfig b/drivers/media/platform/exynos4-is/Kconfig
+index d2c670c..7302cd7 100644
+--- a/drivers/media/platform/exynos4-is/Kconfig
++++ b/drivers/media/platform/exynos4-is/Kconfig
+@@ -40,8 +40,7 @@ if SOC_EXYNOS4212 || SOC_EXYNOS4412 || SOC_EXYNOS5250
+ config VIDEO_EXYNOS_FIMC_LITE
+       tristate "EXYNOS FIMC-LITE camera interface driver"
+-      depends on I2C
+-      select VIDEOBUF2_DMA_CONTIG
++      depends on VIDEO_EXYNOS4_FIMC_IS
+       select VIDEO_EXYNOS4_IS_COMMON
+       help
+         This is a V4L2 driver for Samsung EXYNOS4/5 SoC FIMC-LITE camera
+@@ -54,6 +53,7 @@ endif
+ config VIDEO_EXYNOS4_FIMC_IS
+       tristate "EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver"
+       select VIDEOBUF2_DMA_CONTIG
++      select VIDEO_EXYNOS_FIMC_LITE
+       depends on OF
+       select FW_LOADER
+       help
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0786-ARM-exynos-Make-fimc-lite-nodes-children-of-fimc-is-.patch b/patches.tizen/0786-ARM-exynos-Make-fimc-lite-nodes-children-of-fimc-is-.patch
new file mode 100644 (file)
index 0000000..3a2182f
--- /dev/null
@@ -0,0 +1,150 @@
+From 03f35448d6fc685150b2ddab8255e8188a6bd0aa Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 13 Sep 2013 12:57:16 +0200
+Subject: [PATCH 0786/1302] ARM: exynos: Make fimc-lite nodes children of
+ fimc-is node
+
+FIMC-LITE devices are part of the FIMC-IS subsystem a have dependencies
+on resources that are managed by FIMC-IS. Make fimc-lite nodes children
+of fimc-is node, as in case of other FIMC-IS peripheral IP blocks.
+This also removes now unnecessary 'samsung, power-domain' property from
+the fimc-lite nodes.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-m0.dts     | 16 ++++++------
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 16 ++++++------
+ arch/arm/boot/dts/exynos4x12.dtsi       | 43 ++++++++++++++++-----------------
+ 3 files changed, 37 insertions(+), 38 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-m0.dts b/arch/arm/boot/dts/exynos4412-m0.dts
+index 5c2c141..30e34b4 100644
+--- a/arch/arm/boot/dts/exynos4412-m0.dts
++++ b/arch/arm/boot/dts/exynos4412-m0.dts
+@@ -176,20 +176,20 @@
+                       };
+               };
+-              fimc_lite_0: fimc-lite@12390000 {
+-                      status = "okay";
+-              };
+-
+-              fimc_lite_1: fimc-lite@123A0000 {
+-                      status = "okay";
+-              };
+-
+               fimc-is@12000000 {
+                       linux,contiguous-region = <&fimc_mem>;
+                       status = "okay";
+                       pinctrl-0 = <&fimc_is_uart>;
+                       pinctrl-names = "default";
++                      fimc_lite_0: fimc-lite@12390000 {
++                              status = "okay";
++                      };
++
++                      fimc_lite_1: fimc-lite@123A0000 {
++                              status = "okay";
++                      };
++
+                       i2c1_isp: i2c-isp@12140000 {
+                               pinctrl-0 = <&fimc_is_i2c1>;
+                               pinctrl-names = "default";
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 6907e59..e041769 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -1149,20 +1149,20 @@
+                       };
+               };
+-              fimc_lite_0: fimc-lite@12390000 {
+-                      status = "okay";
+-              };
+-
+-              fimc_lite_1: fimc-lite@123A0000 {
+-                      status = "okay";
+-              };
+-
+               fimc-is@12000000 {
+                       status = "okay";
+                       pinctrl-0 = <&fimc_is_uart>;
+                       pinctrl-names = "default";
+                       memory-region = <&fimc_mem>;
++                      fimc_lite_0: fimc-lite@12390000 {
++                              status = "okay";
++                      };
++
++                      fimc_lite_1: fimc-lite@123A0000 {
++                              status = "okay";
++                      };
++
+                       i2c1_isp: i2c-isp@12140000 {
+                               pinctrl-0 = <&fimc_is_i2c1>;
+                               pinctrl-names = "default";
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index e37ced2..894a987 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -265,28 +265,6 @@
+                       clock-names = "csis", "sclk_csis", "mux", "parent";
+               };
+-              fimc_lite_0: fimc-lite@12390000 {
+-                      compatible = "samsung,exynos4212-fimc-lite";
+-                      reg = <0x12390000 0x1000>;
+-                      interrupts = <0 105 0>;
+-                      samsung,power-domain = <&pd_isp>;
+-                      clocks = <&clock 353>;
+-                      clock-names = "flite";
+-                      status = "disabled";
+-                      iommu = <&sysmmu_fimc_lite0>;
+-              };
+-
+-              fimc_lite_1: fimc-lite@123A0000 {
+-                      compatible = "samsung,exynos4212-fimc-lite";
+-                      reg = <0x123A0000 0x1000>;
+-                      interrupts = <0 106 0>;
+-                      samsung,power-domain = <&pd_isp>;
+-                      clocks = <&clock 354>;
+-                      clock-names = "flite";
+-                      status = "disabled";
+-                      iommu = <&sysmmu_fimc_lite1>;
+-              };
+-
+               fimc_is: fimc-is@12000000 {
+                       compatible = "samsung,exynos4212-fimc-is", "simple-bus";
+                       reg = <0x12000000 0x260000>;
+@@ -312,6 +290,27 @@
+                       #size-cells = <1>;
+                       ranges;
++
++                      fimc_lite_0: fimc-lite@12390000 {
++                              compatible = "samsung,exynos4212-fimc-lite";
++                              reg = <0x12390000 0x1000>;
++                              interrupts = <0 105 0>;
++                              clocks = <&clock 353>;
++                              clock-names = "flite";
++                              status = "disabled";
++                              iommu = <&sysmmu_fimc_lite0>;
++                      };
++
++                      fimc_lite_1: fimc-lite@123A0000 {
++                              compatible = "samsung,exynos4212-fimc-lite";
++                              reg = <0x123A0000 0x1000>;
++                              interrupts = <0 106 0>;
++                              clocks = <&clock 354>;
++                              clock-names = "flite";
++                              status = "disabled";
++                              iommu = <&sysmmu_fimc_lite1>;
++                      };
++
+                       pmu {
+                               reg = <0x10020000 0x3000>;
+                       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0787-exynos4-is-Disable-ISP-UART-clock-gating.patch b/patches.tizen/0787-exynos4-is-Disable-ISP-UART-clock-gating.patch
new file mode 100644 (file)
index 0000000..9e6634e
--- /dev/null
@@ -0,0 +1,40 @@
+From 968db14027e852bd2c27f1c1cc77f9b9680823db Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 13 Sep 2013 19:16:07 +0200
+Subject: [PATCH 0787/1302] exynos4-is: Disable ISP UART clock gating
+
+The ISP UART clock causes issues with power management and hangs
+on system supend to RAM. Leave it temporarily always on until the
+issue is properly resolved.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-is.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c
+index fc4fda3..790e71f 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is.c
++++ b/drivers/media/platform/exynos4-is/fimc-is.c
+@@ -52,7 +52,7 @@ static char *fimc_is_clocks[ISS_CLKS_MAX] = {
+       [ISS_CLK_DRC]                   = "drc",
+       [ISS_CLK_FD]                    = "fd",
+       [ISS_CLK_MCUISP]                = "mcuisp",
+-      [ISS_CLK_UART]                  = "uart",
++      /* [ISS_CLK_UART]               = "uart", */
+       [ISS_CLK_ISP_DIV0]              = "ispdiv0",
+       [ISS_CLK_ISP_DIV1]              = "ispdiv1",
+       [ISS_CLK_MCUISP_DIV0]           = "mcuispdiv0",
+@@ -83,6 +83,8 @@ static int fimc_is_get_clocks(struct fimc_is *is)
+               is->clocks[i] = ERR_PTR(-EINVAL);
+       for (i = 0; i < ISS_CLKS_MAX; i++) {
++              if (fimc_is_clocks[i] == NULL)
++                      continue;
+               is->clocks[i] = clk_get(&is->pdev->dev, fimc_is_clocks[i]);
+               if (IS_ERR(is->clocks[i])) {
+                       ret = PTR_ERR(is->clocks[i]);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0788-ARM-dts-Assign-correct-UART-gate-clock-to-Exynos4x12.patch b/patches.tizen/0788-ARM-dts-Assign-correct-UART-gate-clock-to-Exynos4x12.patch
new file mode 100644 (file)
index 0000000..3f6c85e
--- /dev/null
@@ -0,0 +1,31 @@
+From 5677a753f38cef2614199c447e0f7f482f7a797f Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 13 Sep 2013 19:20:21 +0200
+Subject: [PATCH 0788/1302] ARM: dts: Assign correct UART gate clock to
+ Exynos4x12 FIMC-IS
+
+Use gate from CLK_GAT_IP_ISP register rather than MUX clock output gate
+from CLK_SRC_MASK_ISP.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index 894a987..0eafcce 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -274,7 +274,7 @@
+                               <&clock 356>, <&clock 342>, <&clock 17>,
+                               <&clock 357>, <&clock 358>, <&clock 359>,
+                               <&clock 360>, <&clock 450>,<&clock 451>,
+-                              <&clock 452>, <&clock 453>, <&clock 176>,
++                              <&clock 452>, <&clock 453>, <&clock 382>,
+                               <&clock 13>, <&clock 454>, <&clock 395>,
+                               <&clock 455>;
+                       clock-names = "lite0", "lite1", "ppmuispx",
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0789-Revert-exynos4-is-Ungate-uart-clocks-on-system-suspe.patch b/patches.tizen/0789-Revert-exynos4-is-Ungate-uart-clocks-on-system-suspe.patch
new file mode 100644 (file)
index 0000000..3ed7999
--- /dev/null
@@ -0,0 +1,76 @@
+From f3075907e366dc4644f8d68efa86310a3db5ae75 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Fri, 13 Sep 2013 19:38:40 +0200
+Subject: [PATCH 0789/1302] Revert "exynos4-is: Ungate uart clocks on system
+ suspend"
+
+This reverts commit 85f406b4269d2c5905c59b7ca59484c7b7e00842.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-is.c | 22 ----------------------
+ drivers/media/platform/exynos4-is/fimc-is.h |  3 +--
+ 2 files changed, 1 insertion(+), 24 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c
+index 790e71f..93bcb36 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is.c
++++ b/drivers/media/platform/exynos4-is/fimc-is.c
+@@ -890,39 +890,17 @@ static int fimc_is_runtime_suspend(struct device *dev)
+ static int fimc_is_resume(struct device *dev)
+ {
+       /* TODO: */
+-      struct fimc_is *is = dev_get_drvdata(dev);
+-      int i;
+-
+-      for (i = ISS_GATE_CLKS_SUSPEND; i < ISS_GATE_CLKS_MAX; i++)
+-              if (!IS_ERR(is->clocks[i]))
+-                      clk_disable_unprepare(is->clocks[i]);
+-
+       return 0;
+ }
+ static int fimc_is_suspend(struct device *dev)
+ {
+       struct fimc_is *is = dev_get_drvdata(dev);
+-      int i, ret;
+       /* TODO: */
+       if (test_bit(IS_ST_A5_PWR_ON, &is->state))
+               return -EBUSY;
+-      for (i = ISS_GATE_CLKS_SUSPEND; i < ISS_GATE_CLKS_MAX; i++) {
+-              if (IS_ERR(is->clocks[i]))
+-                      continue;
+-
+-              ret = clk_prepare_enable(is->clocks[i]);
+-              if (ret < 0) {
+-                      dev_err(&is->pdev->dev, "clock %s enable failed\n",
+-                                                      fimc_is_clocks[i]);
+-                      for (--i; i >= ISS_GATE_CLKS_SUSPEND; i--)
+-                              clk_disable_unprepare(is->clocks[i]);
+-                      return ret;
+-              }
+-      }
+-
+       return 0;
+ }
+ #endif /* CONFIG_PM_SLEEP */
+diff --git a/drivers/media/platform/exynos4-is/fimc-is.h b/drivers/media/platform/exynos4-is/fimc-is.h
+index ed40bf7..e0be691 100644
+--- a/drivers/media/platform/exynos4-is/fimc-is.h
++++ b/drivers/media/platform/exynos4-is/fimc-is.h
+@@ -77,8 +77,7 @@ enum {
+       ISS_CLK_DRC,
+       ISS_CLK_FD,
+       ISS_CLK_MCUISP,
+-      ISS_GATE_CLKS_SUSPEND,
+-      ISS_CLK_UART = ISS_GATE_CLKS_SUSPEND,
++      ISS_CLK_UART,
+       ISS_GATE_CLKS_MAX,
+       ISS_CLK_ISP_DIV0 = ISS_GATE_CLKS_MAX,
+       ISS_CLK_ISP_DIV1,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0790-dmaengine-add-dma_slave_get_caps-api.patch b/patches.tizen/0790-dmaengine-add-dma_slave_get_caps-api.patch
new file mode 100644 (file)
index 0000000..91384d1
--- /dev/null
@@ -0,0 +1,98 @@
+From 3bc81b2536a636ecf1e6c3a37c24dd28c1b0b3e4 Mon Sep 17 00:00:00 2001
+From: Vinod Koul <vinod.koul@intel.com>
+Date: Mon, 8 Jul 2013 14:15:25 +0530
+Subject: [PATCH 0790/1302] dmaengine: add dma_slave_get_caps api
+
+add new device callback .device_slave_caps api which can be used by clients to
+query the dma channel capablties before they program the channel. This can help
+is removing errors during the channel programming. Also add helper
+dma_slave_get_caps API
+
+This patch folds the work done by Matt earlier
+https://patchwork.kernel.org/patch/2094891/
+
+Signed-off-by: Vinod Koul <vinod.koul@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/dmaengine.h | 44 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 44 insertions(+)
+
+diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
+index 96d3e4a..5642335 100644
+--- a/include/linux/dmaengine.h
++++ b/include/linux/dmaengine.h
+@@ -371,6 +371,33 @@ struct dma_slave_config {
+       unsigned int slave_id;
+ };
++/* struct dma_slave_caps - expose capabilities of a slave channel only
++ *
++ * @src_addr_widths: bit mask of src addr widths the channel supports
++ * @dstn_addr_widths: bit mask of dstn addr widths the channel supports
++ * @directions: bit mask of slave direction the channel supported
++ *    since the enum dma_transfer_direction is not defined as bits for each
++ *    type of direction, the dma controller should fill (1 << <TYPE>) and same
++ *    should be checked by controller as well
++ * @cmd_pause: true, if pause and thereby resume is supported
++ * @cmd_terminate: true, if terminate cmd is supported
++ *
++ * @max_sg_nr: maximum number of SG segments supported
++ *    0 for no maximum
++ * @max_sg_len: maximum length of a SG segment supported
++ *    0 for no maximum
++ */
++struct dma_slave_caps {
++      u32 src_addr_widths;
++      u32 dstn_addr_widths;
++      u32 directions;
++      bool cmd_pause;
++      bool cmd_terminate;
++
++      u32 max_sg_nr;
++      u32 max_sg_len;
++};
++
+ static inline const char *dma_chan_name(struct dma_chan *chan)
+ {
+       return dev_name(&chan->dev->device);
+@@ -534,6 +561,7 @@ struct dma_tx_state {
+  *    struct with auxiliary transfer status information, otherwise the call
+  *    will just return a simple status code
+  * @device_issue_pending: push pending transactions to hardware
++ * @device_slave_caps: return the slave channel capabilities
+  */
+ struct dma_device {
+@@ -602,6 +630,7 @@ struct dma_device {
+                                           dma_cookie_t cookie,
+                                           struct dma_tx_state *txstate);
+       void (*device_issue_pending)(struct dma_chan *chan);
++      int (*device_slave_caps)(struct dma_chan *chan, struct dma_slave_caps *caps);
+ };
+ static inline int dmaengine_device_control(struct dma_chan *chan,
+@@ -675,6 +704,21 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_interleaved_dma(
+       return chan->device->device_prep_interleaved_dma(chan, xt, flags);
+ }
++static inline int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps)
++{
++      if (!chan || !caps)
++              return -EINVAL;
++
++      /* check if the channel supports slave transactions */
++      if (!test_bit(DMA_SLAVE, chan->device->cap_mask.bits))
++              return -ENXIO;
++
++      if (chan->device->device_slave_caps)
++              return chan->device->device_slave_caps(chan, caps);
++
++      return -ENXIO;
++}
++
+ static inline int dmaengine_terminate_all(struct dma_chan *chan)
+ {
+       return dmaengine_device_control(chan, DMA_TERMINATE_ALL, 0);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0791-dma-pl330-Implement-device_slave_caps.patch b/patches.tizen/0791-dma-pl330-Implement-device_slave_caps.patch
new file mode 100644 (file)
index 0000000..75d1e9a
--- /dev/null
@@ -0,0 +1,70 @@
+From 6fec572c1415a90551592331128ab310adb29194 Mon Sep 17 00:00:00 2001
+From: Lars-Peter Clausen <lars@metafoo.de>
+Date: Mon, 15 Jul 2013 17:53:08 +0200
+Subject: [PATCH 0791/1302] dma: pl330: Implement device_slave_caps
+
+Implement the device_slave_caps() callback for the pl330 driver. This allows
+dmaengine users like the generic ALSA dmaengine PCM driver to query the
+capabilities of the driver. The PL330 supports all buswidths and both
+mem-to-dev as well as dev-to-mem transfers. In theory there is no limit on the
+number of segments that can be transferred (in practice you'll run out of memory
+eventually) and the number of bytes per segment is limited by the size of the
+PL330 program buffer. Due to the nature of the PL330 the maximum number of bytes
+per segment depends on the burstsize, the driver sets it to the value for a
+1-byte burstsize, since it is the smallest.
+
+Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
+Signed-off-by: Vinod Koul <vinod.koul@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/dma/pl330.c | 27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
+index fa645d8..4ad13eb 100644
+--- a/drivers/dma/pl330.c
++++ b/drivers/dma/pl330.c
+@@ -2896,6 +2896,32 @@ static irqreturn_t pl330_irq_handler(int irq, void *data)
+               return IRQ_NONE;
+ }
++#define PL330_DMA_BUSWIDTHS \
++      BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) | \
++      BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
++      BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
++      BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \
++      BIT(DMA_SLAVE_BUSWIDTH_8_BYTES)
++
++static int pl330_dma_device_slave_caps(struct dma_chan *dchan,
++      struct dma_slave_caps *caps)
++{
++      caps->src_addr_widths = PL330_DMA_BUSWIDTHS;
++      caps->dstn_addr_widths = PL330_DMA_BUSWIDTHS;
++      caps->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
++      caps->cmd_pause = false;
++      caps->cmd_terminate = true;
++
++      /*
++       * This is the limit for transfers with a buswidth of 1, larger
++       * buswidths will have larger limits.
++       */
++      caps->max_sg_len = 1900800;
++      caps->max_sg_nr = 0;
++
++      return 0;
++}
++
+ static int
+ pl330_probe(struct amba_device *adev, const struct amba_id *id)
+ {
+@@ -3000,6 +3026,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
+       pd->device_prep_slave_sg = pl330_prep_slave_sg;
+       pd->device_control = pl330_control;
+       pd->device_issue_pending = pl330_issue_pending;
++      pd->device_slave_caps = pl330_dma_device_slave_caps;
+       ret = dma_async_device_register(pd);
+       if (ret) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0792-dmaengine-add-interface-of-dma_get_slave_channel.patch b/patches.tizen/0792-dmaengine-add-interface-of-dma_get_slave_channel.patch
new file mode 100644 (file)
index 0000000..dccc5a3
--- /dev/null
@@ -0,0 +1,85 @@
+From 29ab5447cac6828d168346db5134ffa049e165f5 Mon Sep 17 00:00:00 2001
+From: Zhangfei Gao <zhangfei.gao@linaro.org>
+Date: Fri, 28 Jun 2013 20:39:12 +0800
+Subject: [PATCH 0792/1302] dmaengine: add interface of dma_get_slave_channel
+
+Suggested by Arnd, add dma_get_slave_channel interface
+Dma host driver could get specific channel specificied by request line, rather than filter.
+
+host example:
+static struct dma_chan *xx_of_dma_simple_xlate(struct of_phandle_args *dma_spec,
+               struct of_dma *ofdma)
+{
+       struct xx_dma_dev *d = ofdma->of_dma_data;
+       unsigned int request = dma_spec->args[0];
+
+       if (request > d->dma_requests)
+               return NULL;
+
+       return dma_get_slave_channel(&(d->chans[request].vc.chan));
+}
+
+probe:
+of_dma_controller_register((&op->dev)->of_node, xx_of_dma_simple_xlate, d);
+
+Signed-off-by: Zhangfei Gao <zhangfei.gao@linaro.org>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Vinod Koul <vinod.koul@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/dma/dmaengine.c   | 26 ++++++++++++++++++++++++++
+ include/linux/dmaengine.h |  1 +
+ 2 files changed, 27 insertions(+)
+
+diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
+index 93f7992..78dbbe0 100644
+--- a/drivers/dma/dmaengine.c
++++ b/drivers/dma/dmaengine.c
+@@ -504,6 +504,32 @@ static struct dma_chan *private_candidate(const dma_cap_mask_t *mask,
+ }
+ /**
++ * dma_request_channel - try to get specific channel exclusively
++ * @chan: target channel
++ */
++struct dma_chan *dma_get_slave_channel(struct dma_chan *chan)
++{
++      int err = -EBUSY;
++
++      /* lock against __dma_request_channel */
++      mutex_lock(&dma_list_mutex);
++
++      if (chan->client_count == 0)
++              err = dma_chan_get(chan);
++      else
++              chan = NULL;
++
++      mutex_unlock(&dma_list_mutex);
++
++      if (err)
++              pr_debug("%s: failed to get %s: (%d)\n",
++                      __func__, dma_chan_name(chan), err);
++
++      return chan;
++}
++EXPORT_SYMBOL_GPL(dma_get_slave_channel);
++
++/**
+  * dma_request_channel - try to allocate an exclusive channel
+  * @mask: capabilities that the channel must satisfy
+  * @fn: optional callback to disposition available channels
+diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
+index 5642335..99b4f59 100644
+--- a/include/linux/dmaengine.h
++++ b/include/linux/dmaengine.h
+@@ -1044,6 +1044,7 @@ int dma_async_device_register(struct dma_device *device);
+ void dma_async_device_unregister(struct dma_device *device);
+ void dma_run_dependencies(struct dma_async_tx_descriptor *tx);
+ struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type);
++struct dma_chan *dma_get_slave_channel(struct dma_chan *chan);
+ struct dma_chan *net_dma_find_channel(void);
+ #define dma_request_channel(mask, x, y) __dma_request_channel(&(mask), x, y)
+ #define dma_request_slave_channel_compat(mask, x, y, dev, name) \
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0793-dma-pl330-split-off-common-code-to-give-back-descrip.patch b/patches.tizen/0793-dma-pl330-split-off-common-code-to-give-back-descrip.patch
new file mode 100644 (file)
index 0000000..bc515b9
--- /dev/null
@@ -0,0 +1,86 @@
+From 74f2b8026727d9333c10ace5c87961d0a0ff02f3 Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Fri, 9 Aug 2013 20:11:33 +0900
+Subject: [PATCH 0793/1302] dma: pl330: split off common code to give back
+ descriptors
+
+This patch adds __pl330_giveback_descs which give back descriptors when fails
+allocating descriptors. It requires to eliminate duplication for
+pl330_prep_dma_sg which will be added later.
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Acked-by : Jassi Brar <jassisinghbrar@gmail.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Vinod Koul <vinod.koul@intel.com>
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/dma/pl330.c | 38 +++++++++++++++++++++++---------------
+ 1 file changed, 23 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
+index 4ad13eb..ebc2af9 100644
+--- a/drivers/dma/pl330.c
++++ b/drivers/dma/pl330.c
+@@ -2814,6 +2814,28 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst,
+       return &desc->txd;
+ }
++static void __pl330_giveback_desc(struct dma_pl330_dmac *pdmac,
++                                struct dma_pl330_desc *first)
++{
++      unsigned long flags;
++      struct dma_pl330_desc *desc;
++
++      if (!first)
++              return;
++
++      spin_lock_irqsave(&pdmac->pool_lock, flags);
++
++      while (!list_empty(&first->node)) {
++              desc = list_entry(first->node.next,
++                              struct dma_pl330_desc, node);
++              list_move_tail(&desc->node, &pdmac->desc_pool);
++      }
++
++      list_move_tail(&first->node, &pdmac->desc_pool);
++
++      spin_unlock_irqrestore(&pdmac->pool_lock, flags);
++}
++
+ static struct dma_async_tx_descriptor *
+ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
+               unsigned int sg_len, enum dma_transfer_direction direction,
+@@ -2822,7 +2844,6 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
+       struct dma_pl330_desc *first, *desc = NULL;
+       struct dma_pl330_chan *pch = to_pchan(chan);
+       struct scatterlist *sg;
+-      unsigned long flags;
+       int i;
+       dma_addr_t addr;
+@@ -2842,20 +2863,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
+                       dev_err(pch->dmac->pif.dev,
+                               "%s:%d Unable to fetch desc\n",
+                               __func__, __LINE__);
+-                      if (!first)
+-                              return NULL;
+-
+-                      spin_lock_irqsave(&pdmac->pool_lock, flags);
+-
+-                      while (!list_empty(&first->node)) {
+-                              desc = list_entry(first->node.next,
+-                                              struct dma_pl330_desc, node);
+-                              list_move_tail(&desc->node, &pdmac->desc_pool);
+-                      }
+-
+-                      list_move_tail(&first->node, &pdmac->desc_pool);
+-
+-                      spin_unlock_irqrestore(&pdmac->pool_lock, flags);
++                      __pl330_giveback_desc(pdmac, first);
+                       return NULL;
+               }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0794-dmaengine-make-dma_submit_error-return-an-error-code.patch b/patches.tizen/0794-dmaengine-make-dma_submit_error-return-an-error-code.patch
new file mode 100644 (file)
index 0000000..6a4e62e
--- /dev/null
@@ -0,0 +1,43 @@
+From db9e4dd4ef72f0ae369fc1c53a475d4ad223ce0c Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Sat, 10 Aug 2013 10:46:50 +0300
+Subject: [PATCH 0794/1302] dmaengine: make dma_submit_error() return an error
+ code
+
+The problem here is that the dma_xfer() functions in
+drivers/ata/pata_arasan_cf.c and drivers/mtd/nand/fsmc_nand.c expect
+dma_submit_error() to return an error code so they return 1 when they
+intended to return a negative.
+
+So far as I can tell, none of the ->tx_submit() functions ever do
+return error codes so this patch should have no effect in the current
+code.
+
+I also changed it from a define to an inline.
+
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Dan Williams <djbw@fb.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/dmaengine.h | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
+index 99b4f59..372183c 100644
+--- a/include/linux/dmaengine.h
++++ b/include/linux/dmaengine.h
+@@ -38,7 +38,10 @@ typedef s32 dma_cookie_t;
+ #define DMA_MIN_COOKIE        1
+ #define DMA_MAX_COOKIE        INT_MAX
+-#define dma_submit_error(cookie) ((cookie) < 0 ? 1 : 0)
++static inline int dma_submit_error(dma_cookie_t cookie)
++{
++      return cookie < 0 ? cookie : 0;
++}
+ /**
+  * enum dma_status - DMA transaction status
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0795-dma-pl330-Fix-handling-of-TERMINATE_ALL-while-proces.patch b/patches.tizen/0795-dma-pl330-Fix-handling-of-TERMINATE_ALL-while-proces.patch
new file mode 100644 (file)
index 0000000..f258008
--- /dev/null
@@ -0,0 +1,215 @@
+From b4189f4b3d0c3d40a8eb138437004419e6fa71b0 Mon Sep 17 00:00:00 2001
+From: Lars-Peter Clausen <lars@metafoo.de>
+Date: Tue, 27 Aug 2013 20:34:05 +0200
+Subject: [PATCH 0795/1302] dma: pl330: Fix handling of TERMINATE_ALL while
+ processing completed descriptors
+
+The pl330 DMA driver is broken in regard to handling a terminate all request
+while it is processing the list of completed descriptors. This is most visible
+when calling dmaengine_terminate_all() from within the descriptors callback for
+cyclic transfers. In this case the TERMINATE_ALL transfer will clear the
+work_list and stop the transfer. But after all callbacks for all completed
+descriptors have been handled the descriptors will be re-enqueued into the (now
+empty) work_list. So the next time dma_async_issue_pending() is called for the
+channel these descriptors will be transferred again which will cause data
+corruption. Similar issues can occur if dmaengine_terminate_all() is not called
+from within the descriptor callback but runs on a different CPU at the same time
+as the completed descriptor list is processed.
+
+This patch introduces a new per channel list which will hold the completed
+descriptors. While processing the list the channel's lock will be held to avoid
+racing against dmaengine_terminate_all(). The lock will be released when calling
+the descriptors callback though. Since the list of completed descriptors might
+be modified (e.g. by calling dmaengine_terminate_all() from the callback) we can
+not use the normal list iterator macros. Instead we'll need to check for each
+loop iteration again if there are still items in the list. The drivers
+TERMINATE_ALL implementation is updated to move descriptors from both the
+work_list as well the new completed_list back to the descriptor pool. This makes
+sure that none of the descripts finds its way back into the work list and also
+that we do not call any futher complete callbacks after
+dmaengine_terminate_all() has been called.
+
+Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
+Signed-off-by: Vinod Koul <vinod.koul@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/dma/pl330.c | 111 ++++++++++++++++++----------------------------------
+ 1 file changed, 39 insertions(+), 72 deletions(-)
+
+diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
+index ebc2af9..ad43b2a 100644
+--- a/drivers/dma/pl330.c
++++ b/drivers/dma/pl330.c
+@@ -545,6 +545,8 @@ struct dma_pl330_chan {
+       /* List of to be xfered descriptors */
+       struct list_head work_list;
++      /* List of completed descriptors */
++      struct list_head completed_list;
+       /* Pointer to the DMAC that manages this channel,
+        * NULL if the channel is available to be acquired.
+@@ -2198,66 +2200,6 @@ to_desc(struct dma_async_tx_descriptor *tx)
+       return container_of(tx, struct dma_pl330_desc, txd);
+ }
+-static inline void free_desc_list(struct list_head *list)
+-{
+-      struct dma_pl330_dmac *pdmac;
+-      struct dma_pl330_desc *desc;
+-      struct dma_pl330_chan *pch = NULL;
+-      unsigned long flags;
+-
+-      /* Finish off the work list */
+-      list_for_each_entry(desc, list, node) {
+-              dma_async_tx_callback callback;
+-              void *param;
+-
+-              /* All desc in a list belong to same channel */
+-              pch = desc->pchan;
+-              callback = desc->txd.callback;
+-              param = desc->txd.callback_param;
+-
+-              if (callback)
+-                      callback(param);
+-
+-              desc->pchan = NULL;
+-      }
+-
+-      /* pch will be unset if list was empty */
+-      if (!pch)
+-              return;
+-
+-      pdmac = pch->dmac;
+-
+-      spin_lock_irqsave(&pdmac->pool_lock, flags);
+-      list_splice_tail_init(list, &pdmac->desc_pool);
+-      spin_unlock_irqrestore(&pdmac->pool_lock, flags);
+-}
+-
+-static inline void handle_cyclic_desc_list(struct list_head *list)
+-{
+-      struct dma_pl330_desc *desc;
+-      struct dma_pl330_chan *pch = NULL;
+-      unsigned long flags;
+-
+-      list_for_each_entry(desc, list, node) {
+-              dma_async_tx_callback callback;
+-
+-              /* Change status to reload it */
+-              desc->status = PREP;
+-              pch = desc->pchan;
+-              callback = desc->txd.callback;
+-              if (callback)
+-                      callback(desc->txd.callback_param);
+-      }
+-
+-      /* pch will be unset if list was empty */
+-      if (!pch)
+-              return;
+-
+-      spin_lock_irqsave(&pch->lock, flags);
+-      list_splice_tail_init(list, &pch->work_list);
+-      spin_unlock_irqrestore(&pch->lock, flags);
+-}
+-
+ static inline void fill_queue(struct dma_pl330_chan *pch)
+ {
+       struct dma_pl330_desc *desc;
+@@ -2291,7 +2233,6 @@ static void pl330_tasklet(unsigned long data)
+       struct dma_pl330_chan *pch = (struct dma_pl330_chan *)data;
+       struct dma_pl330_desc *desc, *_dt;
+       unsigned long flags;
+-      LIST_HEAD(list);
+       spin_lock_irqsave(&pch->lock, flags);
+@@ -2300,7 +2241,7 @@ static void pl330_tasklet(unsigned long data)
+               if (desc->status == DONE) {
+                       if (!pch->cyclic)
+                               dma_cookie_complete(&desc->txd);
+-                      list_move_tail(&desc->node, &list);
++                      list_move_tail(&desc->node, &pch->completed_list);
+               }
+       /* Try to submit a req imm. next to the last completed cookie */
+@@ -2309,12 +2250,31 @@ static void pl330_tasklet(unsigned long data)
+       /* Make sure the PL330 Channel thread is active */
+       pl330_chan_ctrl(pch->pl330_chid, PL330_OP_START);
+-      spin_unlock_irqrestore(&pch->lock, flags);
++      while (!list_empty(&pch->completed_list)) {
++              dma_async_tx_callback callback;
++              void *callback_param;
+-      if (pch->cyclic)
+-              handle_cyclic_desc_list(&list);
+-      else
+-              free_desc_list(&list);
++              desc = list_first_entry(&pch->completed_list,
++                                      struct dma_pl330_desc, node);
++
++              callback = desc->txd.callback;
++              callback_param = desc->txd.callback_param;
++
++              if (pch->cyclic) {
++                      desc->status = PREP;
++                      list_move_tail(&desc->node, &pch->work_list);
++              } else {
++                      desc->status = FREE;
++                      list_move_tail(&desc->node, &pch->dmac->desc_pool);
++              }
++
++              if (callback) {
++                      spin_unlock_irqrestore(&pch->lock, flags);
++                      callback(callback_param);
++                      spin_lock_irqsave(&pch->lock, flags);
++              }
++      }
++      spin_unlock_irqrestore(&pch->lock, flags);
+ }
+ static void dma_pl330_rqcb(void *token, enum pl330_op_err err)
+@@ -2409,7 +2369,7 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan)
+ static int pl330_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, unsigned long arg)
+ {
+       struct dma_pl330_chan *pch = to_pchan(chan);
+-      struct dma_pl330_desc *desc, *_dt;
++      struct dma_pl330_desc *desc;
+       unsigned long flags;
+       struct dma_pl330_dmac *pdmac = pch->dmac;
+       struct dma_slave_config *slave_config;
+@@ -2423,12 +2383,18 @@ static int pl330_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, unsigned
+               pl330_chan_ctrl(pch->pl330_chid, PL330_OP_FLUSH);
+               /* Mark all desc done */
+-              list_for_each_entry_safe(desc, _dt, &pch->work_list , node) {
+-                      desc->status = DONE;
+-                      list_move_tail(&desc->node, &list);
++              list_for_each_entry(desc, &pch->work_list , node) {
++                      desc->status = FREE;
++                      dma_cookie_complete(&desc->txd);
++              }
++
++              list_for_each_entry(desc, &pch->completed_list , node) {
++                      desc->status = FREE;
++                      dma_cookie_complete(&desc->txd);
+               }
+-              list_splice_tail_init(&list, &pdmac->desc_pool);
++              list_splice_tail_init(&pch->work_list, &pdmac->desc_pool);
++              list_splice_tail_init(&pch->completed_list, &pdmac->desc_pool);
+               spin_unlock_irqrestore(&pch->lock, flags);
+               break;
+       case DMA_SLAVE_CONFIG:
+@@ -3005,6 +2971,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
+                       pch->chan.private = adev->dev.of_node;
+               INIT_LIST_HEAD(&pch->work_list);
++              INIT_LIST_HEAD(&pch->completed_list);
+               spin_lock_init(&pch->lock);
+               pch->pl330_chid = NULL;
+               pch->chan.device = pd;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0796-dmaengine-dma_slave_caps-remove-sg-entries.patch b/patches.tizen/0796-dmaengine-dma_slave_caps-remove-sg-entries.patch
new file mode 100644 (file)
index 0000000..44897cf
--- /dev/null
@@ -0,0 +1,45 @@
+From 06edb3f3fc7a9652ac6a4933f1caaa0e65ff547d Mon Sep 17 00:00:00 2001
+From: Vinod Koul <vinod.koul@intel.com>
+Date: Mon, 2 Sep 2013 17:47:33 +0530
+Subject: [PATCH 0796/1302] dmaengine: dma_slave_caps: remove sg entries
+
+As pointed by Russell in [1], the sg properties are already availble in struct device,
+so no need to duplicate here.
+
+[1]: http://marc.info/?l=linux-omap&m=137416733628831
+
+Signed-off-by: Vinod Koul <vinod.koul@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/dmaengine.h | 8 --------
+ 1 file changed, 8 deletions(-)
+
+diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
+index 372183c..0e0e109 100644
+--- a/include/linux/dmaengine.h
++++ b/include/linux/dmaengine.h
+@@ -384,11 +384,6 @@ struct dma_slave_config {
+  *    should be checked by controller as well
+  * @cmd_pause: true, if pause and thereby resume is supported
+  * @cmd_terminate: true, if terminate cmd is supported
+- *
+- * @max_sg_nr: maximum number of SG segments supported
+- *    0 for no maximum
+- * @max_sg_len: maximum length of a SG segment supported
+- *    0 for no maximum
+  */
+ struct dma_slave_caps {
+       u32 src_addr_widths;
+@@ -396,9 +391,6 @@ struct dma_slave_caps {
+       u32 directions;
+       bool cmd_pause;
+       bool cmd_terminate;
+-
+-      u32 max_sg_nr;
+-      u32 max_sg_len;
+ };
+ static inline const char *dma_chan_name(struct dma_chan *chan)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0797-dmaengine-pl330-use-dma_set_max_seg_size-to-set-the-.patch b/patches.tizen/0797-dmaengine-pl330-use-dma_set_max_seg_size-to-set-the-.patch
new file mode 100644 (file)
index 0000000..faf07de
--- /dev/null
@@ -0,0 +1,48 @@
+From 045ed897dc4cd71a88ac026c540812401e8ece93 Mon Sep 17 00:00:00 2001
+From: Vinod Koul <vinod.koul@intel.com>
+Date: Mon, 2 Sep 2013 21:54:48 +0530
+Subject: [PATCH 0797/1302] dmaengine: pl330: use dma_set_max_seg_size to set
+ the sg limit
+
+Signed-off-by: Vinod Koul <vinod.koul@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/dma/pl330.c | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
+index ad43b2a..24f8ae3 100644
+--- a/drivers/dma/pl330.c
++++ b/drivers/dma/pl330.c
+@@ -2886,13 +2886,6 @@ static int pl330_dma_device_slave_caps(struct dma_chan *dchan,
+       caps->cmd_pause = false;
+       caps->cmd_terminate = true;
+-      /*
+-       * This is the limit for transfers with a buswidth of 1, larger
+-       * buswidths will have larger limits.
+-       */
+-      caps->max_sg_len = 1900800;
+-      caps->max_sg_nr = 0;
+-
+       return 0;
+ }
+@@ -3017,6 +3010,14 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
+                       "unable to register DMA to the generic DT DMA helpers\n");
+               }
+       }
++      /*
++       * This is the limit for transfers with a buswidth of 1, larger
++       * buswidths will have larger limits.
++       */
++      ret = dma_set_max_seg_size(&adev->dev, 1900800);
++      if (ret)
++              dev_err(&adev->dev, "unable to set the seg size\n");
++
+       dev_info(&adev->dev,
+               "Loaded driver for PL330 DMAC-%d\n", adev->periphid);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0798-dts-arm-add-missing-clock-properties-to-MCT-for-Exyn.patch b/patches.tizen/0798-dts-arm-add-missing-clock-properties-to-MCT-for-Exyn.patch
new file mode 100644 (file)
index 0000000..f543384
--- /dev/null
@@ -0,0 +1,29 @@
+From 3de110bcee5201045b46f4719d9b59258017837e Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Wed, 18 Sep 2013 11:09:38 +0200
+Subject: [PATCH 0798/1302] dts: arm: add missing clock properties to MCT for
+ Exynos4212
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4212.dtsi | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4212.dtsi b/arch/arm/boot/dts/exynos4212.dtsi
+index c0f60f4..4f8ccbd 100644
+--- a/arch/arm/boot/dts/exynos4212.dtsi
++++ b/arch/arm/boot/dts/exynos4212.dtsi
+@@ -44,6 +44,9 @@
+               interrupts = <0 0>, <1 0>, <2 0>, <3 0>,
+                            <4 0>, <5 0>;
++              clocks = <&clock 3>, <&clock 344>;
++              clock-names = "fin_pll", "mct";
++
+               mct_map: mct-map {
+                       #interrupt-cells = <2>;
+                       #address-cells = <0>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0799-extcon-Add-extcon-port-driver-to-maintain-compatibil.patch b/patches.tizen/0799-extcon-Add-extcon-port-driver-to-maintain-compatibil.patch
new file mode 100644 (file)
index 0000000..27a1171
--- /dev/null
@@ -0,0 +1,703 @@
+From d177789ba483aaf15d3ad16c713e39712ef14b1b Mon Sep 17 00:00:00 2001
+From: Chanwoo Choi <cw00.choi@samsung.com>
+Date: Fri, 30 Aug 2013 17:15:53 +0900
+Subject: [PATCH 0799/1302] extcon: Add extcon-port driver to maintain
+ compatibility with old jack driver
+
+This patch add extcon-port driver which maintain compatibility with old JACK
+driver(drivers/misc/jack.c). extcon-port driver send uevent to user-space
+when receive notification of cable state from EXTCON.
+
+Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
+
+Conflicts:
+
+       drivers/extcon/Kconfig
+       drivers/extcon/Makefile
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/extcon/Kconfig             |   9 +
+ drivers/extcon/Makefile            |   1 +
+ drivers/extcon/extcon-port.c       | 588 +++++++++++++++++++++++++++++++++++++
+ include/linux/extcon/extcon-port.h |  46 +++
+ 4 files changed, 644 insertions(+)
+ create mode 100644 drivers/extcon/extcon-port.c
+ create mode 100644 include/linux/extcon/extcon-port.h
+
+diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig
+index 3297301..90b3ad0 100644
+--- a/drivers/extcon/Kconfig
++++ b/drivers/extcon/Kconfig
+@@ -53,4 +53,13 @@ config EXTCON_ARIZONA
+         with Wolfson Arizona devices. These are audio CODECs with
+         advanced audio accessory detection support.
++config EXTCON_PORT
++      tristate "MUIC/Jack compatible interface support with EXTCON"
++      depends on !JACK_MON
++      help
++        If you say yes here you get support compatibility of interface
++        between old JACK driver and EXTCON. EXTCON_PORT provide same
++        interface as old JACK driver to remove confusion of applying
++        EXTCON to platform.
++
+ endif # MULTISTATE_SWITCH
+diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile
+index f98a3c4..034bb95 100644
+--- a/drivers/extcon/Makefile
++++ b/drivers/extcon/Makefile
+@@ -8,3 +8,4 @@ obj-$(CONFIG_EXTCON_ADC_JACK)  += extcon-adc-jack.o
+ obj-$(CONFIG_EXTCON_MAX77693) += extcon-max77693.o
+ obj-$(CONFIG_EXTCON_MAX8997)  += extcon-max8997.o
+ obj-$(CONFIG_EXTCON_ARIZONA)  += extcon-arizona.o
++obj-$(CONFIG_EXTCON_PORT)     += extcon-port.o
+diff --git a/drivers/extcon/extcon-port.c b/drivers/extcon/extcon-port.c
+new file mode 100644
+index 0000000..c3121f5
+--- /dev/null
++++ b/drivers/extcon/extcon-port.c
+@@ -0,0 +1,588 @@
++/*
++ * drivers/extcon/extcon-port.c
++ *
++ * MUIC/JACK compatible extcon driver with MUIC/JACK Extcon device driver
++ *
++ * Copyright (C) 2012 Samsung Electronics
++ * Chanwoo Choi <cw00.choi@samsung.com>
++ *
++ * based on drivers/misc/jack.c
++ * Copyright (C) 2009 Samsung Electronics
++ * Minkyu Kang <mk7.samsung.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/io.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/workqueue.h>
++#include <linux/platform_device.h>
++#include <linux/extcon.h>
++#include <linux/extcon/extcon-port.h>
++#include <linux/mfd/max77693.h>
++
++struct extcon_cable_block {
++      char extcon_name[32];
++      char name[32];
++
++      struct extcon_specific_cable_nb obj;
++      struct work_struct wq;
++      struct notifier_block nb;
++
++      bool prev_attached;
++      bool attached;
++
++      void (*function)(struct extcon_cable_block *cable);
++};
++
++struct extcon_port {
++      char extcon_name_muic[CABLE_NAME_MAX];
++      struct extcon_dev *edev_muic;
++      struct extcon_cable_block *cables_muic;
++
++      char extcon_name_jack[CABLE_NAME_MAX];
++      struct extcon_dev *edev_jack;
++      struct extcon_cable_block *cables_jack;
++
++      char extcon_name_hdmi[CABLE_NAME_MAX];
++      struct extcon_dev *edev_hdmi;
++      struct extcon_cable_block *cables_hdmi;
++
++      struct jack_platform_data *pdata;
++};
++
++static struct platform_device *extcon_port_pdev;
++
++/* Dummy event handler */
++void jack_event_handler(char *name, int value) {}
++EXPORT_SYMBOL_GPL(jack_event_handler);
++
++int jack_get_data(const char *name)
++{
++      struct extcon_port *extcon_port
++              = platform_get_drvdata(extcon_port_pdev);
++
++      if (!strcmp(name, "usb"))
++              return extcon_port->pdata->usb_online;
++      else if (!strcmp(name, "charger"))
++              return extcon_port->pdata->charger_online;
++      else if (!strcmp(name, "hdmi"))
++              return extcon_port->pdata->hdmi_online;
++      else if (!strcmp(name, "earjack"))
++              return extcon_port->pdata->earjack_online;
++      else if (!strcmp(name, "earkey"))
++              return extcon_port->pdata->earkey_online;
++      else if (!strcmp(name, "ums"))
++              return extcon_port->pdata->ums_online;
++      else if (!strcmp(name, "cdrom"))
++              return extcon_port->pdata->cdrom_online;
++      else if (!strcmp(name, "jig"))
++              return extcon_port->pdata->jig_online;
++      else if (!strcmp(name, "host"))
++              return extcon_port->pdata->host_online;
++      else if (!strcmp(name, "cradle"))
++              return extcon_port->pdata->cradle_online;
++
++
++      return -EINVAL;
++}
++EXPORT_SYMBOL_GPL(jack_get_data);
++
++#define EXTCON_PORT_ENTRY(name)                                               \
++static ssize_t extcon_port_show_##name(struct device *dev,            \
++              struct device_attribute *attr, char *buf)               \
++{                                                                     \
++      struct extcon_port *extcon_port = dev_get_drvdata(dev);         \
++      return sprintf(buf, "%d\n", extcon_port->pdata->name);          \
++}                                                                     \
++static DEVICE_ATTR(name, S_IRUGO, extcon_port_show_##name, NULL);
++
++EXTCON_PORT_ENTRY(usb_online);
++EXTCON_PORT_ENTRY(charger_online);
++EXTCON_PORT_ENTRY(hdmi_online);
++EXTCON_PORT_ENTRY(earjack_online);
++EXTCON_PORT_ENTRY(earkey_online);
++EXTCON_PORT_ENTRY(jig_online);
++EXTCON_PORT_ENTRY(host_online);
++EXTCON_PORT_ENTRY(cradle_online);
++
++static int extcon_port_create_sysfs(struct extcon_port *extcon_port)
++{
++      struct jack_platform_data *pdata = extcon_port->pdata;
++      int ret;
++
++      if (pdata->usb_online != -1)
++              ret = device_create_file(&extcon_port_pdev->dev,
++                              &dev_attr_usb_online);
++      if (pdata->charger_online != -1)
++              ret = device_create_file(&extcon_port_pdev->dev,
++                              &dev_attr_charger_online);
++      if (pdata->hdmi_online != -1)
++              ret = device_create_file(&extcon_port_pdev->dev,
++                              &dev_attr_hdmi_online);
++      if (pdata->earjack_online != -1)
++              ret = device_create_file(&extcon_port_pdev->dev,
++                              &dev_attr_earjack_online);
++      if (pdata->earkey_online != -1)
++              ret = device_create_file(&extcon_port_pdev->dev,
++                              &dev_attr_earkey_online);
++      if (pdata->jig_online != -1)
++              ret = device_create_file(&extcon_port_pdev->dev,
++                              &dev_attr_jig_online);
++      if (pdata->host_online != -1)
++              ret = device_create_file(&extcon_port_pdev->dev,
++                              &dev_attr_host_online);
++      if (pdata->cradle_online != -1)
++              ret = device_create_file(&extcon_port_pdev->dev,
++                              &dev_attr_cradle_online);
++
++      return 0;
++}
++
++static void extcon_port_set_data(struct jack_platform_data *pdata,
++              const char *name, int value)
++{
++      if (!strcmp(name, "usb"))
++              pdata->usb_online = value;
++      else if (!strcmp(name, "charger"))
++              pdata->charger_online = value;
++      else if (!strcmp(name, "hdmi"))
++              pdata->hdmi_online = value;
++      else if (!strcmp(name, "earjack"))
++              pdata->earjack_online = value;
++      else if (!strcmp(name, "earkey"))
++              pdata->earkey_online = value;
++      else if (!strcmp(name, "ums"))
++              pdata->ums_online = value;
++      else if (!strcmp(name, "cdrom"))
++              pdata->cdrom_online = value;
++      else if (!strcmp(name, "jig"))
++              pdata->jig_online = value;
++      else if (!strcmp(name, "host"))
++              pdata->host_online = value;
++      else if (!strcmp(name, "cradle"))
++              pdata->cradle_online = value;
++}
++
++static int extcon_port_event_handler(char *name, int value)
++{
++      struct extcon_port *extcon_port;
++      char env_str[16];
++      char *envp[] = { env_str, NULL };
++      int ret = 0;
++
++      if (!extcon_port_pdev) {
++              printk(KERN_ERR "jack device is not allocated\n");
++              return -ENODEV;
++      }
++
++      extcon_port = platform_get_drvdata(extcon_port_pdev);
++      extcon_port_set_data(extcon_port->pdata, name, value);
++      sprintf(env_str, "CHGDET=%s", name);
++      dev_info(&extcon_port_pdev->dev, "jack event %s\n", env_str);
++      ret = kobject_uevent_env(&extcon_port_pdev->dev.kobj,
++                      KOBJ_CHANGE, envp);
++      if (ret < 0)
++              pr_err("Failed to send uevent to user-space : extcon-port\n");
++
++      return ret;
++}
++
++static void extcon_muic_function(struct extcon_cable_block *cable)
++{
++      int attached = cable->attached;
++      int ret;
++      char muic_name[10];
++
++      if (!strcmp(cable->name, "USB")) {
++              strcpy(muic_name, "usb");
++      } else if (!strcmp(cable->name, "USB-Host")) {
++              strcpy(muic_name, "host");
++      } else if (!strcmp(cable->name, "TA")
++              || !strcmp(cable->name, "Fast-charger")
++              || !strcmp(cable->name, "Slow-charger")
++              || !strcmp(cable->name, "Charger-downstream")
++              || !strcmp(cable->name, "MHL_TA")) {
++              strcpy(muic_name, "charger");
++      } else if (!strcmp(cable->name, "JIG-USB-ON")
++              || !strcmp(cable->name, "JIG-USB-OFF")
++              || !strcmp(cable->name, "JIG-UART-OFF")) {
++              strcpy(muic_name, "jig");
++      } else if (!strcmp(cable->name, "Dock-Smart")) {
++              strcpy(muic_name, "cradle");
++
++              if (attached)
++                      attached = MAX77693_MUIC_DOCK_SMARTDOCK;
++      } else if (!strcmp(cable->name, "Dock-Car")) {
++              strcpy(muic_name, "cradle");
++
++              if (attached)
++                      attached = MAX77693_MUIC_DOCK_CARDOCK;
++      } else if (!strcmp(cable->name, "Dock-Desk")
++              || !strcmp(cable->name, "Dock-Audio")) {
++              strcpy(muic_name, "cradle");
++
++              if (attached)
++                      attached = MAX77693_MUIC_DOCK_DESKDOCK;
++      } else {
++              pr_err("Cannot detect unknown cable\n");
++              goto out;
++      }
++
++      ret = extcon_port_event_handler(muic_name, attached);
++      if (ret < 0) {
++              pr_info("Faild to set jack event handler(%s)\n",
++                              muic_name);
++              goto out;
++      }
++
++      if (!strcmp(cable->name, "USB")) {
++              ret = extcon_port_event_handler("charger", attached);
++              if (ret < 0) {
++                      pr_info("Faild to set jack event handler(%s)\n",
++                                      muic_name);
++                      goto out;
++              }
++      }
++out:
++      return;
++}
++
++static void extcon_jack_function(struct extcon_cable_block *cable)
++{
++      int state = 0;
++      int ret;
++      char jack_name[10];
++
++      if (!strcmp(cable->name, "Headset")) {
++              strcpy(jack_name, "earjack");
++
++              if (cable->attached)
++                      state = 3;
++
++      } else if (!strcmp(cable->name, "Headphone")) {
++              strcpy(jack_name, "earjack");
++
++              if (cable->attached)
++                      state = 1;
++
++      } else if (!strcmp(cable->name, "Microphone")) {
++              strcpy(jack_name, "earkey");
++              state = cable->attached;
++
++      } else {
++              pr_err("Cannot detect unknown cable\n");
++              goto out;
++      }
++
++      ret = extcon_port_event_handler(jack_name, state);
++      if (ret < 0) {
++              pr_info("Faild to set jack event handler(%s)\n",
++                              jack_name);
++      }
++out:
++      return;
++}
++
++static void extcon_hdmi_function(struct extcon_cable_block *cable)
++{
++      if (!strcmp(cable->name, "HDMI")) {
++              int ret;
++
++              ret = extcon_port_event_handler("hdmi", cable->attached);
++              if (ret < 0) {
++                      pr_info("Faild to set hdmi event handler(%s)\n",
++                                      cable->name);
++              }
++      }
++
++      return;
++}
++
++static void extcon_work(struct work_struct *work)
++{
++      struct extcon_cable_block *cable =
++              container_of(work, struct extcon_cable_block, wq);
++
++      if (cable->function)
++              cable->function(cable);
++}
++
++static int extcon_notifier(struct notifier_block *self,
++                      unsigned long event, void *ptr)
++{
++      struct extcon_cable_block *cable =
++              container_of(self, struct extcon_cable_block, nb);
++
++      /*
++       * The newly state of charger cable.
++       * If cable is attached, cable->attached is true.
++       */
++      cable->prev_attached = cable->attached;
++      cable->attached = event;
++
++      /*
++       * Setup work for controlling charger(regulator)
++       * according to charger cable.
++       */
++      schedule_work(&cable->wq);
++
++      return NOTIFY_DONE;
++}
++
++int extcon_port_register(
++              char *extcon_name,
++              struct extcon_dev *edev,
++              struct extcon_cable_block *cables,
++              void (*fn)(struct extcon_cable_block *))
++{
++      struct extcon_cable_block *cable;
++      int ret = 0, num_cables;
++      int i;
++
++      if (!extcon_name)
++              return -EINVAL;
++
++      edev = extcon_get_extcon_dev(extcon_name);
++      if (!edev)
++              return -ENODEV;
++
++      num_cables = edev->max_supported;
++
++      cables = kzalloc(sizeof(struct extcon_cable_block) * num_cables,
++                      GFP_KERNEL);
++      if (!cables) {
++              pr_err("failed to allocate array of extcon_cable_block(%s)\n",
++                              extcon_name);
++              return -ENOMEM;
++      }
++
++      for (i = 0 ; i < num_cables ; i++) {
++              cable = &cables[i];
++
++              strcpy(cable->extcon_name, extcon_name);
++              strcpy(cable->name, edev->supported_cable[i]);
++              cable->function = fn;
++
++              INIT_WORK(&cable->wq, extcon_work);
++              cable->nb.notifier_call = extcon_notifier;
++              ret = extcon_register_interest(&cable->obj,
++                      cable->extcon_name, cable->name, &cable->nb);
++              if (ret < 0) {
++                      pr_err("Cannot register extcon_dev for %s(cable: %s)\n",
++                                      cable->extcon_name, cable->name);
++                      goto err_extcon;
++              }
++      }
++
++      return 0;
++
++err_extcon:
++      for (i = 0 ; i < num_cables ; i++) {
++              cable = &cables[i];
++
++              /* Unregister only extcon device which is initialized */
++              if (cable->nb.notifier_call) {
++                      ret = extcon_unregister_interest(&cable->obj);
++
++                      pr_err("Unregister extcon_dev for %s(cable: %s)\n",
++                                      cable->extcon_name, cable->name);
++              }
++      }
++      kfree(cables);
++
++      return ret;
++}
++
++int extcon_port_unregister(struct extcon_dev *edev,
++              struct extcon_cable_block *cables)
++{
++      struct extcon_cable_block *cable;
++      int num_cables;
++      int ret = 0;
++      int i;
++
++      if (!edev)
++              return -ENODEV;
++
++      num_cables = edev->max_supported;
++
++      for (i = 0 ; i < num_cables ; i++) {
++              cable = &cables[i];
++
++              /* Unregister only extcon device which is initialized */
++              if (cable->nb.notifier_call) {
++                      ret = extcon_unregister_interest(&cable->obj);
++
++                      pr_err("Unregister extcon_dev for %s(cable: %s)\n",
++                                      cable->extcon_name, cable->name);
++              }
++      }
++      kfree(cables);
++
++      return ret;
++}
++
++static int extcon_port_probe(struct platform_device *pdev)
++{
++      struct jack_platform_data *pdata = pdev->dev.platform_data;
++      struct extcon_port *extcon_port;
++      int ret;
++
++      extcon_port = kzalloc(sizeof(struct extcon_port), GFP_KERNEL);
++      if (!extcon_port) {
++              dev_err(&pdev->dev, "failed to allocate driver data\n");
++              ret = -ENOMEM;
++              goto err;
++      }
++      platform_set_drvdata(pdev, extcon_port);
++      extcon_port->pdata = pdata;
++      extcon_port_pdev = pdev;
++
++      ret = extcon_port_create_sysfs(extcon_port);
++      if (ret < 0) {
++              dev_err(&pdev->dev, "Failed to create sysfs\n");
++              goto err_sysfs;
++      }
++
++      if (!pdata->extcon_name_muic) {
++              dev_err(&pdev->dev,
++                      "Cannot set name of muic device by platform data\n");
++      } else {
++              strcpy(extcon_port->extcon_name_muic, pdata->extcon_name_muic);
++              ret = extcon_port_register(extcon_port->extcon_name_muic,
++                              extcon_port->edev_muic,
++                              extcon_port->cables_muic,
++                              extcon_muic_function);
++              if (ret < 0) {
++                      dev_err(&pdev->dev,
++                              "Failed to register extcon port (%s:%d)\n",
++                              pdata->extcon_name_muic, ret);
++                      goto err_extcon_muic;
++              }
++      }
++
++      if (!pdata->extcon_name_jack) {
++              dev_err(&pdev->dev,
++                      "Cannot set name of jack device by platform data\n");
++      } else {
++              strcpy(extcon_port->extcon_name_jack, pdata->extcon_name_jack);
++              ret = extcon_port_register(extcon_port->extcon_name_jack,
++                              extcon_port->edev_jack,
++                              extcon_port->cables_jack,
++                              extcon_jack_function);
++              if (ret < 0) {
++                      dev_err(&pdev->dev,
++                              "Failed to register extcon port (%s:%d)\n",
++                              pdata->extcon_name_jack, ret);
++                      goto err_extcon_jack;
++              }
++      }
++
++      if (!pdata->extcon_name_hdmi) {
++              dev_err(&pdev->dev,
++                      "Cannot set name of hdmi device by platform data\n");
++      } else {
++              strcpy(extcon_port->extcon_name_hdmi, pdata->extcon_name_hdmi);
++              ret = extcon_port_register(extcon_port->extcon_name_hdmi,
++                              extcon_port->edev_hdmi,
++                              extcon_port->cables_hdmi,
++                              extcon_hdmi_function);
++              if (ret < 0) {
++                      dev_err(&pdev->dev,
++                              "Failed to register extcon port (%s:%d)\n",
++                              pdata->extcon_name_hdmi, ret);
++                      goto err_extcon_hdmi;
++              }
++      }
++
++      return ret;
++
++err_extcon_hdmi:
++      ret = extcon_port_unregister(extcon_port->edev_hdmi,
++                              extcon_port->cables_hdmi);
++err_extcon_jack:
++      ret = extcon_port_unregister(extcon_port->edev_jack,
++                              extcon_port->cables_jack);
++err_extcon_muic:
++      ret = extcon_port_unregister(extcon_port->edev_muic,
++                              extcon_port->cables_muic);
++err_sysfs:
++      kfree(extcon_port);
++err:
++      return ret;
++}
++
++static int extcon_port_remove(struct platform_device *pdev)
++{
++      struct jack_platform_data *pdata = pdev->dev.platform_data;
++      struct extcon_port *extcon_port = platform_get_drvdata(pdev);
++
++      if (pdata->usb_online != -1)
++              device_remove_file(&extcon_port_pdev->dev,
++                              &dev_attr_usb_online);
++      if (pdata->charger_online != -1)
++              device_remove_file(&extcon_port_pdev->dev,
++                              &dev_attr_charger_online);
++      if (pdata->hdmi_online != -1)
++              device_remove_file(&extcon_port_pdev->dev,
++                              &dev_attr_hdmi_online);
++      if (pdata->earjack_online != -1)
++              device_remove_file(&extcon_port_pdev->dev,
++                              &dev_attr_earjack_online);
++      if (pdata->earkey_online != -1)
++              device_remove_file(&extcon_port_pdev->dev,
++                              &dev_attr_earkey_online);
++      if (pdata->jig_online != -1)
++              device_remove_file(&extcon_port_pdev->dev,
++                              &dev_attr_jig_online);
++      if (pdata->host_online != -1)
++              device_remove_file(&extcon_port_pdev->dev,
++                              &dev_attr_host_online);
++      if (pdata->cradle_online != -1)
++              device_remove_file(&extcon_port_pdev->dev,
++                              &dev_attr_cradle_online);
++
++      platform_set_drvdata(pdev, NULL);
++
++      extcon_port_unregister(extcon_port->edev_hdmi,
++                      extcon_port->cables_hdmi);
++      extcon_port_unregister(extcon_port->edev_muic,
++                      extcon_port->cables_jack);
++      extcon_port_unregister(extcon_port->edev_jack,
++                      extcon_port->cables_muic);
++
++      kfree(extcon_port);
++
++      return 0;
++}
++
++static struct platform_driver extcon_port_driver = {
++      .probe          = extcon_port_probe,
++      .remove         = extcon_port_remove,
++      .driver         = {
++              .name   = "jack",
++              .owner  = THIS_MODULE,
++      },
++};
++
++static int __init extcon_port_init(void)
++{
++      return platform_driver_register(&extcon_port_driver);
++}
++late_initcall(extcon_port_init);
++
++static void __exit extcon_port_exit(void)
++{
++      platform_driver_unregister(&extcon_port_driver);
++}
++module_exit(extcon_port_exit);
++
++MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
++MODULE_DESCRIPTION("MUIC/JACK compatible extcon driver with MUIC/JACK device");
++MODULE_LICENSE("GPL");
+diff --git a/include/linux/extcon/extcon-port.h b/include/linux/extcon/extcon-port.h
+new file mode 100644
+index 0000000..6438ec4
+--- /dev/null
++++ b/include/linux/extcon/extcon-port.h
+@@ -0,0 +1,46 @@
++/*
++ * include/linux/extcon/extcon-port.h
++ *
++ * Copyright (C) 2012 Samsung Electronics
++ * Chanwoo Choi <cw00.choi@samsung.com>
++ *
++ * based on include/linux/jack.h
++ * Copyright (C) 2009 Samsung Electronics
++ * Minkyu Kang <mk7.samsung.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 __EXTCON_PORT_H_
++#define __EXTCON_PORT_H_
++
++struct jack_platform_data {
++      int usb_online;
++      int charger_online;
++      int hdmi_online;
++      int earjack_online;
++      int earkey_online;
++      int ums_online;
++      int cdrom_online;
++      int jig_online;
++      int host_online;
++      int cradle_online;
++
++      char *extcon_name_muic;
++      char *extcon_name_jack;
++      char *extcon_name_hdmi;
++};
++
++#ifdef CONFIG_EXTCON_PORT
++extern int jack_get_data(const char *name);
++extern void jack_event_handler(char *name, int value);
++#else
++static int jack_get_data(const char *name)
++{
++      return 0;
++}
++static void jack_event_handler(char *name, int value) {}
++#endif
++#endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0800-extcon-max77693-Define-dock-constant-to-remove-compi.patch b/patches.tizen/0800-extcon-max77693-Define-dock-constant-to-remove-compi.patch
new file mode 100644 (file)
index 0000000..706d891
--- /dev/null
@@ -0,0 +1,34 @@
+From 05989a8a21019f650940fca6ac3ef2fc1beedc62 Mon Sep 17 00:00:00 2001
+From: Chanwoo Choi <cw00.choi@samsung.com>
+Date: Mon, 9 Sep 2013 19:43:13 +0900
+Subject: [PATCH 0800/1302] extcon: max77693: Define dock constant to remove
+ compile error
+
+Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/mfd/max77693.h | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/include/linux/mfd/max77693.h b/include/linux/mfd/max77693.h
+index f42ae8a..c45c296 100644
+--- a/include/linux/mfd/max77693.h
++++ b/include/linux/mfd/max77693.h
+@@ -30,6 +30,14 @@
+ #ifndef __LINUX_MFD_MAX77693_H
+ #define __LINUX_MFD_MAX77693_H
++enum {
++      MAX77693_MUIC_DOCK_DETACHED = 0,
++      MAX77693_MUIC_DOCK_DESKDOCK,
++      MAX77693_MUIC_DOCK_CARDOCK,
++      MAX77693_MUIC_DOCK_AUDIODOCK = 7,
++      MAX77693_MUIC_DOCK_SMARTDOCK = 8
++};
++
+ /* MAX77686 regulator IDs */
+ enum max77693_regulators {
+       MAX77693_ESAFEOUT1 = 0,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0801-extcon-Add-extcon-port-platform-device-to-update-uev.patch b/patches.tizen/0801-extcon-Add-extcon-port-platform-device-to-update-uev.patch
new file mode 100644 (file)
index 0000000..e5b8249
--- /dev/null
@@ -0,0 +1,93 @@
+From 79c863697023223cffb0a52b8abd918f35b178cf Mon Sep 17 00:00:00 2001
+From: Chanwoo Choi <cw00.choi@samsung.com>
+Date: Mon, 9 Sep 2013 19:44:31 +0900
+Subject: [PATCH 0801/1302] extcon: Add extcon-port platform device to update
+ uevent of cable
+
+This patch add extcon-port platform device to extcon-port driver
+to bring up it. extcon-port driver can update uevent of cable
+when cable is attached or detached.
+
+Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/extcon/extcon-port.c | 56 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 56 insertions(+)
+
+diff --git a/drivers/extcon/extcon-port.c b/drivers/extcon/extcon-port.c
+index c3121f5..73ce74a 100644
+--- a/drivers/extcon/extcon-port.c
++++ b/drivers/extcon/extcon-port.c
+@@ -26,6 +26,54 @@
+ #include <linux/extcon/extcon-port.h>
+ #include <linux/mfd/max77693.h>
++/************************************************************/
++/************* extcon-port platform device ******************/
++/************************************************************/
++/*
++ * FIXME: extcon-port driver maintain compatibility of preivous jack device
++ * driver. extcon-port driver have to support DT instead of platform_data way.
++ * Temporarily, add below jack_platform_data to update uevent when cable is
++ * attached or detached.
++ */
++
++/*
++ * extcon-port device
++ */
++#define EXTCON_DEV_MUIC_NAME  "max77693-muic"
++#define EXTCON_DEV_JACK_NAME  "Headset Jack"
++#define EXTCON_DEV_HDMI_NAME  "hdmi"
++
++struct jack_platform_data jack_data = {
++      .usb_online     = 0,
++      .charger_online = 0,
++      .hdmi_online    = 0,
++      .earjack_online = 0,
++      .earkey_online  = 0,
++      .ums_online     = -1,
++      .cdrom_online   = -1,
++      .jig_online     = -1,
++      .host_online    = 0,
++      .cradle_online  = 0,
++
++#ifdef CONFIG_EXTCON_PORT
++      .extcon_name_muic       = EXTCON_DEV_MUIC_NAME,
++      /* .extcon_name_jack    = EXTCON_DEV_JACK_NAME, */
++      /* .extcon_name_hdmi    = EXTCON_DEV_HDMI_NAME, */
++#endif
++};
++
++static struct platform_device extcon_port_device = {
++      .name   = "jack",
++      .id     = -1,
++      .dev    = {
++              .platform_data = &jack_data,
++      },
++};
++
++/************************************************************/
++/************* extcon-port platform driver ******************/
++/************************************************************/
++
+ struct extcon_cable_block {
+       char extcon_name[32];
+       char name[32];
+@@ -573,6 +621,14 @@ static struct platform_driver extcon_port_driver = {
+ static int __init extcon_port_init(void)
+ {
++      int ret;
++
++      ret = platform_device_register(&extcon_port_device);
++      if (ret < 0) {
++              pr_err("Failed to register extcon-port device\n");
++              return ret;
++      }
++
+       return platform_driver_register(&extcon_port_driver);
+ }
+ late_initcall(extcon_port_init);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0802-tizen-Update-default-configuration-to-enable-extcon-.patch b/patches.tizen/0802-tizen-Update-default-configuration-to-enable-extcon-.patch
new file mode 100644 (file)
index 0000000..c6ef1bb
--- /dev/null
@@ -0,0 +1,40 @@
+From 5075b092782f790465bb489ee641d49e4f0c6bb0 Mon Sep 17 00:00:00 2001
+From: Chanwoo Choi <cw00.choi@samsung.com>
+Date: Mon, 9 Sep 2013 19:47:21 +0900
+Subject: [PATCH 0802/1302] tizen: Update default configuration to enable
+ extcon-port driver
+
+Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_defconfig | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index 5062ba0..f14bbbb 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -602,6 +602,7 @@ CONFIG_PM_SLEEP_DEBUG=y
+ # CONFIG_APM_EMULATION is not set
+ CONFIG_PM_CLK=y
+ CONFIG_PM_GENERIC_DOMAINS=y
++# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
+ CONFIG_PM_GENERIC_DOMAINS_SLEEP=y
+ CONFIG_PM_GENERIC_DOMAINS_RUNTIME=y
+ CONFIG_CPU_PM=y
+@@ -2840,10 +2841,12 @@ CONFIG_EXTCON=y
+ #
+ # Extcon Device Drivers
+ #
++CONFIG_OF_EXTCON=y
+ CONFIG_EXTCON_GPIO=y
+ CONFIG_EXTCON_ADC_JACK=y
+ CONFIG_EXTCON_MAX77693=y
+ CONFIG_EXTCON_MAX8997=y
++CONFIG_EXTCON_PORT=y
+ # CONFIG_MEMORY is not set
+ CONFIG_IIO=y
+ CONFIG_IIO_BUFFER=y
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0803-WIP-extcon-do-not-update-cable-state-if-notifier-can.patch b/patches.tizen/0803-WIP-extcon-do-not-update-cable-state-if-notifier-can.patch
new file mode 100644 (file)
index 0000000..950c9a7
--- /dev/null
@@ -0,0 +1,46 @@
+From 5c4726c8b8261f1ee23754218a2ac179fce93226 Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Wed, 25 Sep 2013 16:47:33 +0900
+Subject: [PATCH 0803/1302] WIP: extcon: do not update cable state if notifier
+ cannot handle it
+
+During probing a extcon-max77693 driver, extcon-port driver can't receive nb
+callback due to initializing sequences.
+Thus, if the callback can't be handled, we do not update the cable state.
+I'm not sure this patch is good solution :)
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/extcon/extcon-class.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/extcon/extcon-class.c b/drivers/extcon/extcon-class.c
+index 60adc04..e7b851b 100644
+--- a/drivers/extcon/extcon-class.c
++++ b/drivers/extcon/extcon-class.c
+@@ -229,6 +229,7 @@ int extcon_update_state(struct extcon_dev *edev, u32 mask, u32 state)
+       int env_offset = 0;
+       int length;
+       unsigned long flags;
++      int ret;
+       spin_lock_irqsave(&edev->lock, flags);
+@@ -244,7 +245,12 @@ int extcon_update_state(struct extcon_dev *edev, u32 mask, u32 state)
+               edev->state &= ~mask;
+               edev->state |= state & mask;
+-              raw_notifier_call_chain(&edev->nh, old_state, edev);
++              ret = raw_notifier_call_chain(&edev->nh, old_state, edev);
++              if ((ret & ~NOTIFY_STOP_MASK) != NOTIFY_OK) {
++                      edev->state = old_state;
++                      spin_unlock_irqrestore(&edev->lock, flags);
++                      return -ENODEV;
++              }
+               /* This could be in interrupt handler */
+               prop_buf = (char *)get_zeroed_page(GFP_ATOMIC);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0804-drm-Add-drm-backlight-subsystem-support.patch b/patches.tizen/0804-drm-Add-drm-backlight-subsystem-support.patch
new file mode 100644 (file)
index 0000000..6bb8af9
--- /dev/null
@@ -0,0 +1,210 @@
+From ee9b565194ac93638fc1256ec657d4aef2bb57b8 Mon Sep 17 00:00:00 2001
+From: Donghwa Lee <dh09.lee@samsung.com>
+Date: Thu, 26 Sep 2013 14:31:08 +0900
+Subject: [PATCH 0804/1302] drm: Add drm backlight subsystem support
+
+Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/drm_backlight.c | 117 ++++++++++++++++++++++++++++++++++++++++
+ drivers/video/backlight/lcd.c   |  12 +++++
+ include/drm/drm_backlight.h     |  26 +++++++++
+ 3 files changed, 155 insertions(+)
+ create mode 100644 drivers/gpu/drm/drm_backlight.c
+ create mode 100644 include/drm/drm_backlight.h
+
+diff --git a/drivers/gpu/drm/drm_backlight.c b/drivers/gpu/drm/drm_backlight.c
+new file mode 100644
+index 0000000..0974bcb
+--- /dev/null
++++ b/drivers/gpu/drm/drm_backlight.c
+@@ -0,0 +1,117 @@
++/*
++ * Copyright (C) 2011 Samsung Electronics Co.Ltd
++ * Author: Joonyoung Shim <jy0922.shim@samsung.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/backlight.h>
++#include <linux/lcd.h>
++#include <drm/drm_backlight.h>
++#include <drm/drm_mode.h>
++
++static DEFINE_MUTEX(drm_bl_mutex);
++static LIST_HEAD(drm_bl_list);
++
++struct drm_bl_data {
++      struct device *dev;
++      struct list_head list;
++      int type;
++};
++
++int drm_bl_register(struct device *dev, int type)
++{
++      struct drm_bl_data *data;
++
++      switch (type) {
++      case BL_BACKLIGHT_CLASS:
++      case BL_LCD_CLASS:
++      case BL_TSP_CLASS:
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      data = kzalloc(sizeof(struct drm_bl_data), GFP_KERNEL);
++      if (!data)
++              return -ENOMEM;
++
++      data->dev = dev;
++      data->type = type;
++
++      mutex_lock(&drm_bl_mutex);
++      list_add(&data->list, &drm_bl_list);
++      mutex_unlock(&drm_bl_mutex);
++
++      return 0;
++}
++EXPORT_SYMBOL_GPL(drm_bl_register);
++
++void drm_bl_unregister(struct device *dev)
++{
++      struct drm_bl_data *data;
++
++      list_for_each_entry(data, &drm_bl_list, list) {
++              if (data->dev == dev) {
++                      mutex_lock(&drm_bl_mutex);
++                      list_del(&data->list);
++                      mutex_unlock(&drm_bl_mutex);
++                      kfree(data);
++                      break;
++              }
++      }
++}
++EXPORT_SYMBOL_GPL(drm_bl_unregister);
++
++/* This is called from dpms function of CRTC or encoder */
++void drm_bl_dpms(int mode)
++{
++      struct drm_bl_data *data;
++      struct backlight_device *bd;
++      struct lcd_device *ld;
++      struct drm_bl_notifier *bl_noti;
++      int blank;
++
++      switch (mode) {
++      case DRM_MODE_DPMS_ON:
++              blank = FB_BLANK_UNBLANK;
++              break;
++      case DRM_MODE_DPMS_STANDBY:
++      case DRM_MODE_DPMS_SUSPEND:
++      case DRM_MODE_DPMS_OFF:
++              /* TODO */
++      default:
++              blank = FB_BLANK_POWERDOWN;
++              break;
++      }
++
++      list_for_each_entry(data, &drm_bl_list, list) {
++              switch (data->type) {
++              case BL_BACKLIGHT_CLASS:
++                      bd = container_of(data->dev, struct backlight_device,
++                                      dev);
++                      bd->props.power = blank;
++                      bd->props.fb_blank = blank;
++                      backlight_update_status(bd);
++                      break;
++              case BL_LCD_CLASS:
++                      ld = container_of(data->dev, struct lcd_device, dev);
++                      if (!ld->ops->set_power)
++                              break;
++                      ld->ops->set_power(ld, blank);
++                      break;
++              case BL_TSP_CLASS:
++                      bl_noti = container_of(data->dev,
++                                      struct drm_bl_notifier, dev);
++                      if (!bl_noti->set_power)
++                              break;
++                      bl_noti->set_power(bl_noti->priv, blank);
++                      break;
++              }
++      }
++}
++EXPORT_SYMBOL_GPL(drm_bl_dpms);
+diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
+index 34fb6bd..3a42b2c5d 100644
+--- a/drivers/video/backlight/lcd.c
++++ b/drivers/video/backlight/lcd.c
+@@ -17,6 +17,10 @@
+ #include <linux/fb.h>
+ #include <linux/slab.h>
++#ifdef CONFIG_DRM
++#include <drm/drm_backlight.h>
++#endif
++
+ #if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \
+                          defined(CONFIG_LCD_CLASS_DEVICE_MODULE))
+ /* This callback gets called when something important happens inside a
+@@ -236,6 +240,10 @@ struct lcd_device *lcd_device_register(const char *name, struct device *parent,
+       new_ld->ops = ops;
++#ifdef CONFIG_DRM
++      drm_bl_register(&new_ld->dev, BL_LCD_CLASS);
++#endif
++
+       return new_ld;
+ }
+ EXPORT_SYMBOL(lcd_device_register);
+@@ -251,6 +259,10 @@ void lcd_device_unregister(struct lcd_device *ld)
+       if (!ld)
+               return;
++#ifdef CONFIG_DRM
++      drm_bl_unregister(&ld->dev);
++#endif
++
+       mutex_lock(&ld->ops_lock);
+       ld->ops = NULL;
+       mutex_unlock(&ld->ops_lock);
+diff --git a/include/drm/drm_backlight.h b/include/drm/drm_backlight.h
+new file mode 100644
+index 0000000..cbc4380
+--- /dev/null
++++ b/include/drm/drm_backlight.h
+@@ -0,0 +1,26 @@
++/*
++ * Copyright (C) 2011 Samsung Electronics Co.Ltd
++ * Author: Joonyoung Shim <jy0922.shim@samsung.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.
++ *
++ */
++
++enum drm_bl_class_type {
++      BL_BACKLIGHT_CLASS,
++      BL_LCD_CLASS,
++      BL_TSP_CLASS
++};
++
++struct drm_bl_notifier {
++      struct device dev;
++      void (*set_power)(void *priv, int power);
++      void *priv;
++};
++
++extern int drm_bl_register(struct device *dev, int type);
++extern void drm_bl_unregister(struct device *dev);
++extern void drm_bl_dpms(int mode);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0805-drm-exynos-support-drm-backlight-dpms-on-off.patch b/patches.tizen/0805-drm-exynos-support-drm-backlight-dpms-on-off.patch
new file mode 100644 (file)
index 0000000..2e56628
--- /dev/null
@@ -0,0 +1,204 @@
+From 3c2bf23d79422b1703253248a4e7642a5d8d8a00 Mon Sep 17 00:00:00 2001
+From: Donghwa Lee <dh09.lee@samsung.com>
+Date: Thu, 26 Sep 2013 14:38:02 +0900
+Subject: [PATCH 0805/1302] drm: exynos: support drm backlight dpms on/off
+
+Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/Makefile                 |   2 +-
+ drivers/gpu/drm/exynos/exynos_drm_fimd.c | 122 +++++++++++++++++++------------
+ 2 files changed, 76 insertions(+), 48 deletions(-)
+
+diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
+index 1c9f2439..5d4273d 100644
+--- a/drivers/gpu/drm/Makefile
++++ b/drivers/gpu/drm/Makefile
+@@ -12,7 +12,7 @@ drm-y       :=       drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \
+               drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \
+               drm_crtc.o drm_modes.o drm_edid.o \
+               drm_info.o drm_debugfs.o drm_encoder_slave.o \
+-              drm_trace_points.o drm_global.o drm_prime.o
++              drm_trace_points.o drm_global.o drm_prime.o drm_backlight.o
+ drm-$(CONFIG_COMPAT) += drm_ioc32.o
+ drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+index ec060cb..e3cfa07 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+@@ -23,6 +23,7 @@
+ #include <video/of_display_timing.h>
+ #include <video/samsung_fimd.h>
+ #include <drm/exynos_drm.h>
++#include <drm/drm_backlight.h>
+ #include "exynos_drm_drv.h"
+ #include "exynos_drm_fbdev.h"
+@@ -173,52 +174,33 @@ static int fimd_check_mode(struct device *dev, struct drm_display_mode *mode)
+ static int fimd_display_power_on(struct device *dev, int mode)
+ {
+-      /* TODO */
+-
+-      return 0;
+-}
+-
+-static struct exynos_drm_display_ops fimd_display_ops = {
+-      .type = EXYNOS_DISPLAY_TYPE_LCD,
+-      .is_connected = fimd_display_is_connected,
+-      .get_panel = fimd_get_panel,
+-      .check_mode = fimd_check_mode,
+-      .power_on = fimd_display_power_on,
+-};
+-
+-static void fimd_dpms(struct device *subdrv_dev, int mode)
+-{
+-      struct fimd_context *ctx = get_fimd_context(subdrv_dev);
+-
+-      DRM_DEBUG_KMS("%d\n", mode);
+-
+-      mutex_lock(&ctx->lock);
++      DRM_INFO("%s:mode[%d]\n", __func__, mode);
+       switch (mode) {
+       case DRM_MODE_DPMS_ON:
+-              /*
+-               * enable fimd hardware only if suspended status.
+-               *
+-               * P.S. fimd_dpms function would be called at booting time so
+-               * clk_enable could be called double time.
+-               */
+-              if (ctx->suspended)
+-                      pm_runtime_get_sync(subdrv_dev);
++              drm_bl_dpms(mode);
+               break;
+       case DRM_MODE_DPMS_STANDBY:
+       case DRM_MODE_DPMS_SUSPEND:
+       case DRM_MODE_DPMS_OFF:
+-              if (!ctx->suspended)
+-                      pm_runtime_put_sync(subdrv_dev);
++              drm_bl_dpms(mode);
+               break;
+       default:
+               DRM_DEBUG_KMS("unspecified mode %d\n", mode);
+               break;
+       }
+-      mutex_unlock(&ctx->lock);
++      return 0;
+ }
++static struct exynos_drm_display_ops fimd_display_ops = {
++      .type = EXYNOS_DISPLAY_TYPE_LCD,
++      .is_connected = fimd_display_is_connected,
++      .get_panel = fimd_get_panel,
++      .check_mode = fimd_check_mode,
++      .power_on = fimd_display_power_on,
++};
++
+ static void fimd_apply(struct device *subdrv_dev)
+ {
+       struct fimd_context *ctx = get_fimd_context(subdrv_dev);
+@@ -356,15 +338,6 @@ static void fimd_wait_for_vblank(struct device *dev)
+               DRM_DEBUG_KMS("vblank wait timed out.\n");
+ }
+-static struct exynos_drm_manager_ops fimd_manager_ops = {
+-      .dpms = fimd_dpms,
+-      .apply = fimd_apply,
+-      .commit = fimd_commit,
+-      .enable_vblank = fimd_enable_vblank,
+-      .disable_vblank = fimd_disable_vblank,
+-      .wait_for_vblank = fimd_wait_for_vblank,
+-};
+-
+ static void fimd_win_mode_set(struct device *dev,
+                             struct exynos_drm_overlay *overlay)
+ {
+@@ -680,13 +653,6 @@ static struct exynos_drm_overlay_ops fimd_overlay_ops = {
+       .disable = fimd_win_disable,
+ };
+-static struct exynos_drm_manager fimd_manager = {
+-      .pipe           = -1,
+-      .ops            = &fimd_manager_ops,
+-      .overlay_ops    = &fimd_overlay_ops,
+-      .display_ops    = &fimd_display_ops,
+-};
+-
+ static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
+ {
+       struct fimd_context *ctx = (struct fimd_context *)dev_id;
+@@ -907,6 +873,68 @@ static int fimd_activate(struct fimd_context *ctx, bool enable)
+       return 0;
+ }
++static void fimd_dpms(struct device *subdrv_dev, int mode)
++{
++      struct fimd_context *ctx = get_fimd_context(subdrv_dev);
++      int ret;
++
++      DRM_DEBUG_KMS("%d\n", mode);
++
++      mutex_lock(&ctx->lock);
++
++      switch (mode) {
++      case DRM_MODE_DPMS_ON:
++              /*
++               * enable fimd hardware only if suspended status.
++               *
++               * P.S. fimd_dpms function would be called at booting time so
++               * clk_enable could be called double time.
++               */
++              if (ctx->suspended) {
++                      pm_runtime_get_sync(subdrv_dev);
++
++                      ret = fimd_activate(ctx, true);
++                      if (ret < 0) {
++                              DRM_ERROR("failed to activate.\n");
++                              pm_runtime_put_sync(subdrv_dev);
++                      }
++              }
++              break;
++      case DRM_MODE_DPMS_STANDBY:
++      case DRM_MODE_DPMS_SUSPEND:
++      case DRM_MODE_DPMS_OFF:
++              if (!ctx->suspended) {
++                      ret = fimd_activate(ctx, false);
++                      if (ret < 0)
++                              DRM_ERROR("failed to deactivate.\n");
++
++                      pm_runtime_put_sync(subdrv_dev);
++              }
++              break;
++      default:
++              DRM_DEBUG_KMS("unspecified mode %d\n", mode);
++              break;
++      }
++
++      mutex_unlock(&ctx->lock);
++}
++
++static struct exynos_drm_manager_ops fimd_manager_ops = {
++      .dpms = fimd_dpms,
++      .apply = fimd_apply,
++      .commit = fimd_commit,
++      .enable_vblank = fimd_enable_vblank,
++      .disable_vblank = fimd_disable_vblank,
++      .wait_for_vblank = fimd_wait_for_vblank,
++};
++
++static struct exynos_drm_manager fimd_manager = {
++      .pipe           = -1,
++      .ops            = &fimd_manager_ops,
++      .overlay_ops    = &fimd_overlay_ops,
++      .display_ops    = &fimd_display_ops,
++};
++
+ static int fimd_probe(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0806-usb-gadget-slp-remove-rndis_init.patch b/patches.tizen/0806-usb-gadget-slp-remove-rndis_init.patch
new file mode 100644 (file)
index 0000000..4bbe2fd
--- /dev/null
@@ -0,0 +1,35 @@
+From ed8271e4738edf10c218b5a5289ec9ab0dcf7303 Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Thu, 26 Sep 2013 14:35:25 +0900
+Subject: [PATCH 0806/1302] usb: gadget: slp: remove rndis_init
+
+This patch removes rndis_init because it was already enabled during module_init.
+
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/slp.c | 8 --------
+ 1 file changed, 8 deletions(-)
+
+diff --git a/drivers/usb/gadget/slp.c b/drivers/usb/gadget/slp.c
+index 6a22cf9..0a5fec4 100644
+--- a/drivers/usb/gadget/slp.c
++++ b/drivers/usb/gadget/slp.c
+@@ -477,14 +477,6 @@ static int rndis_function_bind_config(struct slp_multi_usb_function *f,
+               rndis_control_intf.bInterfaceProtocol = 0x03;
+       }
+-      /* ... and setup RNDIS itself */
+-      ret = rndis_init();
+-      if (ret < 0) {
+-              dev_err(f->dev, "rndis_init failed(ret:%d)\n", ret);
+-              gether_cleanup(rndis->edev);
+-              return ret;
+-      }
+-
+       /* Android team reset "rndis_string_defs[0].id" when RNDIS unbinded
+        * in f_rndis.c but, that makes failure of rndis_bind_config() by
+        * the overflow of "next_string_id" value in usb_string_id().
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0807-V4L-Add-mem2mem-ioctl-and-file-operation-helpers.patch b/patches.tizen/0807-V4L-Add-mem2mem-ioctl-and-file-operation-helpers.patch
new file mode 100644 (file)
index 0000000..4fd1c3a
--- /dev/null
@@ -0,0 +1,231 @@
+From a3405ba0689c86ba0d727fdd8011caf69d50d0d5 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Sat, 14 Sep 2013 23:39:04 +0200
+Subject: [PATCH 0807/1302] V4L: Add mem2mem ioctl and file operation helpers
+
+This patch adds ioctl helpers to the V4L2 mem-to-mem API, so we can avoid
+several ioctl handlers in the mem-to-mem video node drivers that are simply
+a pass-through to the v4l2_m2m_* calls. These helpers will only be useful
+for drivers that use same mutex for both OUTPUT and CAPTURE queue, which
+is the case for all currently in tree v4l2 m2m drivers. In order to use
+the helpers the drivers are required to use struct v4l2_fh.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+---
+Changes since v1:
+ - added v4l2_m2m_ioctl_create_buf().
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/v4l2-core/v4l2-mem2mem.c | 118 +++++++++++++++++++++++++++++++++
+ include/media/v4l2-fh.h                |   4 ++
+ include/media/v4l2-mem2mem.h           |  24 +++++++
+ 3 files changed, 146 insertions(+)
+
+diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
+index e96497f..b3a44e2 100644
+--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
++++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
+@@ -502,6 +502,8 @@ unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
+       if (m2m_ctx->m2m_dev->m2m_ops->unlock)
+               m2m_ctx->m2m_dev->m2m_ops->unlock(m2m_ctx->priv);
++      else if (m2m_ctx->q_lock)
++              mutex_unlock(m2m_ctx->q_lock);
+       if (list_empty(&src_q->done_list))
+               poll_wait(file, &src_q->done_wq, wait);
+@@ -510,6 +512,8 @@ unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
+       if (m2m_ctx->m2m_dev->m2m_ops->lock)
+               m2m_ctx->m2m_dev->m2m_ops->lock(m2m_ctx->priv);
++      else if (m2m_ctx->q_lock)
++              mutex_lock(m2m_ctx->q_lock);
+       spin_lock_irqsave(&src_q->done_lock, flags);
+       if (!list_empty(&src_q->done_list))
+@@ -637,6 +641,13 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
+       if (ret)
+               goto err;
++      /*
++       * If both queues use same mutex assign it as the common buffer
++       * queues lock to the m2m context. This lock is used in the
++       * v4l2_m2m_ioctl_* helpers.
++       */
++      if (out_q_ctx->q.lock == cap_q_ctx->q.lock)
++              m2m_ctx->q_lock = out_q_ctx->q.lock;
+       return m2m_ctx;
+ err:
+@@ -703,3 +714,110 @@ void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, struct vb2_buffer *vb)
+ }
+ EXPORT_SYMBOL_GPL(v4l2_m2m_buf_queue);
++/* Videobuf2 ioctl helpers */
++
++int v4l2_m2m_ioctl_reqbufs(struct file *file, void *priv,
++                              struct v4l2_requestbuffers *rb)
++{
++      struct v4l2_fh *fh = file->private_data;
++      return v4l2_m2m_reqbufs(file, fh->m2m_ctx, rb);
++}
++EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_reqbufs);
++
++int v4l2_m2m_ioctl_create_bufs(struct file *file, void *priv,
++                              struct v4l2_create_buffers *create)
++{
++      struct v4l2_fh *fh = file->private_data;
++      return v4l2_m2m_create_bufs(file, fh->m2m_ctx, create);
++}
++EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_create_bufs);
++
++int v4l2_m2m_ioctl_querybuf(struct file *file, void *priv,
++                              struct v4l2_buffer *buf)
++{
++      struct v4l2_fh *fh = file->private_data;
++      return v4l2_m2m_querybuf(file, fh->m2m_ctx, buf);
++}
++EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_querybuf);
++
++int v4l2_m2m_ioctl_qbuf(struct file *file, void *priv,
++                              struct v4l2_buffer *buf)
++{
++      struct v4l2_fh *fh = file->private_data;
++      return v4l2_m2m_qbuf(file, fh->m2m_ctx, buf);
++}
++EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_qbuf);
++
++int v4l2_m2m_ioctl_dqbuf(struct file *file, void *priv,
++                              struct v4l2_buffer *buf)
++{
++      struct v4l2_fh *fh = file->private_data;
++      return v4l2_m2m_dqbuf(file, fh->m2m_ctx, buf);
++}
++EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_dqbuf);
++
++int v4l2_m2m_ioctl_expbuf(struct file *file, void *priv,
++                              struct v4l2_exportbuffer *eb)
++{
++      struct v4l2_fh *fh = file->private_data;
++      return v4l2_m2m_expbuf(file, fh->m2m_ctx, eb);
++}
++EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_expbuf);
++
++int v4l2_m2m_ioctl_streamon(struct file *file, void *priv,
++                              enum v4l2_buf_type type)
++{
++      struct v4l2_fh *fh = file->private_data;
++      return v4l2_m2m_streamon(file, fh->m2m_ctx, type);
++}
++EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_streamon);
++
++int v4l2_m2m_ioctl_streamoff(struct file *file, void *priv,
++                              enum v4l2_buf_type type)
++{
++      struct v4l2_fh *fh = file->private_data;
++      return v4l2_m2m_streamoff(file, fh->m2m_ctx, type);
++}
++EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_streamoff);
++
++/*
++ * v4l2_file_operations helpers. It is assumed here same lock is used
++ * for the output and the capture buffer queue.
++ */
++
++int v4l2_m2m_fop_mmap(struct file *file, struct vm_area_struct *vma)
++{
++      struct v4l2_fh *fh = file->private_data;
++      struct v4l2_m2m_ctx *m2m_ctx = fh->m2m_ctx;
++      int ret;
++
++      if (m2m_ctx->q_lock && mutex_lock_interruptible(m2m_ctx->q_lock))
++              return -ERESTARTSYS;
++
++      ret = v4l2_m2m_mmap(file, m2m_ctx, vma);
++
++      if (m2m_ctx->q_lock)
++              mutex_unlock(m2m_ctx->q_lock);
++
++      return ret;
++}
++EXPORT_SYMBOL_GPL(v4l2_m2m_fop_mmap);
++
++unsigned int v4l2_m2m_fop_poll(struct file *file, poll_table *wait)
++{
++      struct v4l2_fh *fh = file->private_data;
++      struct v4l2_m2m_ctx *m2m_ctx = fh->m2m_ctx;
++      unsigned int ret;
++
++      if (m2m_ctx->q_lock)
++              mutex_lock(m2m_ctx->q_lock);
++
++      ret = v4l2_m2m_poll(file, m2m_ctx, wait);
++
++      if (m2m_ctx->q_lock)
++              mutex_unlock(m2m_ctx->q_lock);
++
++      return ret;
++}
++EXPORT_SYMBOL_GPL(v4l2_m2m_fop_poll);
++
+diff --git a/include/media/v4l2-fh.h b/include/media/v4l2-fh.h
+index a62ee18..d942f79 100644
+--- a/include/media/v4l2-fh.h
++++ b/include/media/v4l2-fh.h
+@@ -43,6 +43,10 @@ struct v4l2_fh {
+       struct list_head        available; /* Dequeueable event */
+       unsigned int            navailable;
+       u32                     sequence;
++
++#if IS_ENABLED(CONFIG_V4L2_MEM2MEM_DEV)
++      struct v4l2_m2m_ctx     *m2m_ctx;
++#endif
+ };
+ /*
+diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
+index 0f4555b..efe765c 100644
+--- a/include/media/v4l2-mem2mem.h
++++ b/include/media/v4l2-mem2mem.h
+@@ -63,6 +63,9 @@ struct v4l2_m2m_queue_ctx {
+ };
+ struct v4l2_m2m_ctx {
++      /* optional cap/out vb2 queues lock */
++      struct mutex                    *q_lock;
++
+ /* private: internal use only */
+       struct v4l2_m2m_dev             *m2m_dev;
+@@ -216,5 +219,26 @@ static inline void *v4l2_m2m_dst_buf_remove(struct v4l2_m2m_ctx *m2m_ctx)
+       return v4l2_m2m_buf_remove(&m2m_ctx->cap_q_ctx);
+ }
++/* v4l2 ioctl helpers */
++
++int v4l2_m2m_ioctl_reqbufs(struct file *file, void *priv,
++                              struct v4l2_requestbuffers *rb);
++int v4l2_m2m_ioctl_create_bufs(struct file *file, void *fh,
++                              struct v4l2_create_buffers *create);
++int v4l2_m2m_ioctl_querybuf(struct file *file, void *fh,
++                              struct v4l2_buffer *buf);
++int v4l2_m2m_ioctl_expbuf(struct file *file, void *fh,
++                              struct v4l2_exportbuffer *eb);
++int v4l2_m2m_ioctl_qbuf(struct file *file, void *fh,
++                              struct v4l2_buffer *buf);
++int v4l2_m2m_ioctl_dqbuf(struct file *file, void *fh,
++                              struct v4l2_buffer *buf);
++int v4l2_m2m_ioctl_streamon(struct file *file, void *fh,
++                              enum v4l2_buf_type type);
++int v4l2_m2m_ioctl_streamoff(struct file *file, void *fh,
++                              enum v4l2_buf_type type);
++int v4l2_m2m_fop_mmap(struct file *file, struct vm_area_struct *vma);
++unsigned int v4l2_m2m_fop_poll(struct file *file, poll_table *wait);
++
+ #endif /* _MEDIA_V4L2_MEM2MEM_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0808-s5p-jpeg-Initialize-vfd_decoder-vfl_dir-field.patch b/patches.tizen/0808-s5p-jpeg-Initialize-vfd_decoder-vfl_dir-field.patch
new file mode 100644 (file)
index 0000000..8cfb546
--- /dev/null
@@ -0,0 +1,39 @@
+From c392349182225b7927617a885f58a543ff6caf09 Mon Sep 17 00:00:00 2001
+From: Jacek Anaszewski <j.anaszewski@samsung.com>
+Date: Wed, 11 Sep 2013 12:11:48 +0200
+Subject: [PATCH 0808/1302] s5p-jpeg: Initialize vfd_decoder->vfl_dir field
+
+This patch fixes regression introduced in the commit
+5c77879ff9ab9e7 and caused by not initializing the
+vfl_dir field of the vfd_decoder instance of the struct
+video_device, after the field was introduced. It precluded
+calling the driver ioctls which require vfl_dir not to be
+equal to VFL_DIR_RX which is defined as 0 and uninitialized
+vfl_dir field is interpreted as such. In effect the unlikely()
+condition in the v4l_s_fmt function failed for the ioctls that
+expect is_tx to be false, which prevented the ioctl callbacks
+registered by the driver from being called.
+
+Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Cc: Hans Verkuil <hverkuil@xs4all.nl>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/s5p-jpeg/jpeg-core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c
+index 88c5beb..1db4736 100644
+--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
++++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
+@@ -1424,6 +1424,7 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
+       jpeg->vfd_decoder->release      = video_device_release;
+       jpeg->vfd_decoder->lock         = &jpeg->lock;
+       jpeg->vfd_decoder->v4l2_dev     = &jpeg->v4l2_dev;
++      jpeg->vfd_decoder->vfl_dir      = VFL_DIR_M2M;
+       ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1);
+       if (ret) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0809-s5p-jpeg-Use-mem-to-mem-ioctl-helpers.patch b/patches.tizen/0809-s5p-jpeg-Use-mem-to-mem-ioctl-helpers.patch
new file mode 100644 (file)
index 0000000..7d577cc
--- /dev/null
@@ -0,0 +1,281 @@
+From 0de2f3cd89d98dade3858b3b6b05f7ddb0db48bb Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Sun, 25 Aug 2013 22:16:56 +0200
+Subject: [PATCH 0809/1302] s5p-jpeg: Use mem-to-mem ioctl helpers
+
+Simplify the driver by using the m2m ioctl and vb2 helpers.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/s5p-jpeg/jpeg-core.c | 134 +++++-----------------------
+ drivers/media/platform/s5p-jpeg/jpeg-core.h |   2 -
+ 2 files changed, 24 insertions(+), 112 deletions(-)
+
+diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c
+index 1db4736..cdeb128 100644
+--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
++++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
+@@ -317,9 +317,9 @@ static int s5p_jpeg_open(struct file *file)
+       if (ret < 0)
+               goto error;
+-      ctx->m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init);
+-      if (IS_ERR(ctx->m2m_ctx)) {
+-              ret = PTR_ERR(ctx->m2m_ctx);
++      ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init);
++      if (IS_ERR(ctx->fh.m2m_ctx)) {
++              ret = PTR_ERR(ctx->fh.m2m_ctx);
+               goto error;
+       }
+@@ -343,7 +343,7 @@ static int s5p_jpeg_release(struct file *file)
+       struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
+       mutex_lock(&jpeg->lock);
+-      v4l2_m2m_ctx_release(ctx->m2m_ctx);
++      v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
+       mutex_unlock(&jpeg->lock);
+       v4l2_ctrl_handler_free(&ctx->ctrl_handler);
+       v4l2_fh_del(&ctx->fh);
+@@ -353,39 +353,13 @@ static int s5p_jpeg_release(struct file *file)
+       return 0;
+ }
+-static unsigned int s5p_jpeg_poll(struct file *file,
+-                               struct poll_table_struct *wait)
+-{
+-      struct s5p_jpeg *jpeg = video_drvdata(file);
+-      struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
+-      unsigned int res;
+-
+-      mutex_lock(&jpeg->lock);
+-      res = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
+-      mutex_unlock(&jpeg->lock);
+-      return res;
+-}
+-
+-static int s5p_jpeg_mmap(struct file *file, struct vm_area_struct *vma)
+-{
+-      struct s5p_jpeg *jpeg = video_drvdata(file);
+-      struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
+-      int ret;
+-
+-      if (mutex_lock_interruptible(&jpeg->lock))
+-              return -ERESTARTSYS;
+-      ret = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
+-      mutex_unlock(&jpeg->lock);
+-      return ret;
+-}
+-
+ static const struct v4l2_file_operations s5p_jpeg_fops = {
+       .owner          = THIS_MODULE,
+       .open           = s5p_jpeg_open,
+       .release        = s5p_jpeg_release,
+-      .poll           = s5p_jpeg_poll,
++      .poll           = v4l2_m2m_fop_poll,
+       .unlocked_ioctl = video_ioctl2,
+-      .mmap           = s5p_jpeg_mmap,
++      .mmap           = v4l2_m2m_fop_mmap,
+ };
+ /*
+@@ -590,7 +564,7 @@ static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
+       struct v4l2_pix_format *pix = &f->fmt.pix;
+       struct s5p_jpeg_ctx *ct = fh_to_ctx(priv);
+-      vq = v4l2_m2m_get_vq(ct->m2m_ctx, f->type);
++      vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
+       if (!vq)
+               return -EINVAL;
+@@ -746,7 +720,7 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
+       struct s5p_jpeg_q_data *q_data = NULL;
+       struct v4l2_pix_format *pix = &f->fmt.pix;
+-      vq = v4l2_m2m_get_vq(ct->m2m_ctx, f->type);
++      vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
+       if (!vq)
+               return -EINVAL;
+@@ -793,53 +767,6 @@ static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
+       return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
+ }
+-static int s5p_jpeg_reqbufs(struct file *file, void *priv,
+-                        struct v4l2_requestbuffers *reqbufs)
+-{
+-      struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
+-
+-      return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
+-}
+-
+-static int s5p_jpeg_querybuf(struct file *file, void *priv,
+-                         struct v4l2_buffer *buf)
+-{
+-      struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
+-
+-      return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
+-}
+-
+-static int s5p_jpeg_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+-{
+-      struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
+-
+-      return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
+-}
+-
+-static int s5p_jpeg_dqbuf(struct file *file, void *priv,
+-                        struct v4l2_buffer *buf)
+-{
+-      struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
+-
+-      return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
+-}
+-
+-static int s5p_jpeg_streamon(struct file *file, void *priv,
+-                         enum v4l2_buf_type type)
+-{
+-      struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
+-
+-      return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
+-}
+-
+-static int s5p_jpeg_streamoff(struct file *file, void *priv,
+-                          enum v4l2_buf_type type)
+-{
+-      struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
+-
+-      return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
+-}
+-
+ static int s5p_jpeg_g_selection(struct file *file, void *priv,
+                        struct v4l2_selection *s)
+ {
+@@ -973,14 +900,13 @@ static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
+       .vidioc_s_fmt_vid_cap           = s5p_jpeg_s_fmt_vid_cap,
+       .vidioc_s_fmt_vid_out           = s5p_jpeg_s_fmt_vid_out,
+-      .vidioc_reqbufs                 = s5p_jpeg_reqbufs,
+-      .vidioc_querybuf                = s5p_jpeg_querybuf,
++      .vidioc_reqbufs                 = v4l2_m2m_ioctl_reqbufs,
++      .vidioc_querybuf                = v4l2_m2m_ioctl_querybuf,
++      .vidioc_qbuf                    = v4l2_m2m_ioctl_qbuf,
++      .vidioc_dqbuf                   = v4l2_m2m_ioctl_dqbuf,
+-      .vidioc_qbuf                    = s5p_jpeg_qbuf,
+-      .vidioc_dqbuf                   = s5p_jpeg_dqbuf,
+-
+-      .vidioc_streamon                = s5p_jpeg_streamon,
+-      .vidioc_streamoff               = s5p_jpeg_streamoff,
++      .vidioc_streamon                = v4l2_m2m_ioctl_streamon,
++      .vidioc_streamoff               = v4l2_m2m_ioctl_streamoff,
+       .vidioc_g_selection             = s5p_jpeg_g_selection,
+ };
+@@ -998,8 +924,8 @@ static void s5p_jpeg_device_run(void *priv)
+       struct vb2_buffer *src_buf, *dst_buf;
+       unsigned long src_addr, dst_addr;
+-      src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
+-      dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
++      src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
++      dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
+       src_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
+       dst_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
+@@ -1171,22 +1097,8 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
+                                     );
+               q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
+       }
+-      if (ctx->m2m_ctx)
+-              v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
+-}
+-
+-static void s5p_jpeg_wait_prepare(struct vb2_queue *vq)
+-{
+-      struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
+-
+-      mutex_unlock(&ctx->jpeg->lock);
+-}
+-
+-static void s5p_jpeg_wait_finish(struct vb2_queue *vq)
+-{
+-      struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
+-      mutex_lock(&ctx->jpeg->lock);
++      v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
+ }
+ static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
+@@ -1212,8 +1124,8 @@ static struct vb2_ops s5p_jpeg_qops = {
+       .queue_setup            = s5p_jpeg_queue_setup,
+       .buf_prepare            = s5p_jpeg_buf_prepare,
+       .buf_queue              = s5p_jpeg_buf_queue,
+-      .wait_prepare           = s5p_jpeg_wait_prepare,
+-      .wait_finish            = s5p_jpeg_wait_finish,
++      .wait_prepare           = vb2_ops_wait_prepare,
++      .wait_finish            = vb2_ops_wait_finish,
+       .start_streaming        = s5p_jpeg_start_streaming,
+       .stop_streaming         = s5p_jpeg_stop_streaming,
+ };
+@@ -1231,6 +1143,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
+       src_vq->ops = &s5p_jpeg_qops;
+       src_vq->mem_ops = &vb2_dma_contig_memops;
+       src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
++      src_vq->lock = &ctx->jpeg->lock;
+       ret = vb2_queue_init(src_vq);
+       if (ret)
+@@ -1243,6 +1156,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
+       dst_vq->ops = &s5p_jpeg_qops;
+       dst_vq->mem_ops = &vb2_dma_contig_memops;
+       dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
++      dst_vq->lock = &ctx->jpeg->lock;
+       return vb2_queue_init(dst_vq);
+ }
+@@ -1268,8 +1182,8 @@ static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
+       curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
+-      src_buf = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
+-      dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
++      src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
++      dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
+       if (curr_ctx->mode == S5P_JPEG_ENCODE)
+               enc_jpeg_too_large = jpeg_enc_stream_stat(jpeg->regs);
+@@ -1297,7 +1211,7 @@ static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
+       if (curr_ctx->mode == S5P_JPEG_ENCODE)
+               vb2_set_plane_payload(dst_buf, 0, payload_size);
+       v4l2_m2m_buf_done(dst_buf, state);
+-      v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->m2m_ctx);
++      v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
+       curr_ctx->subsampling = jpeg_get_subsampling_mode(jpeg->regs);
+       spin_unlock(&jpeg->slock);
+diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.h b/drivers/media/platform/s5p-jpeg/jpeg-core.h
+index 8a4013e..4a4776b 100644
+--- a/drivers/media/platform/s5p-jpeg/jpeg-core.h
++++ b/drivers/media/platform/s5p-jpeg/jpeg-core.h
+@@ -115,7 +115,6 @@ struct s5p_jpeg_q_data {
+  * @jpeg:             JPEG IP device for this context
+  * @mode:             compression (encode) operation or decompression (decode)
+  * @compr_quality:    destination image quality in compression (encode) mode
+- * @m2m_ctx:          mem2mem device context
+  * @out_q:            source (output) queue information
+  * @cap_fmt:          destination (capture) queue queue information
+  * @hdr_parsed:               set if header has been parsed during decompression
+@@ -127,7 +126,6 @@ struct s5p_jpeg_ctx {
+       unsigned short          compr_quality;
+       unsigned short          restart_interval;
+       unsigned short          subsampling;
+-      struct v4l2_m2m_ctx     *m2m_ctx;
+       struct s5p_jpeg_q_data  out_q;
+       struct s5p_jpeg_q_data  cap_q;
+       struct v4l2_fh          fh;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0810-s5p-jpeg-Add-support-for-Exynos4x12.patch b/patches.tizen/0810-s5p-jpeg-Add-support-for-Exynos4x12.patch
new file mode 100644 (file)
index 0000000..8c590f4
--- /dev/null
@@ -0,0 +1,2588 @@
+From 5da96b9e545bcbd2fa3fa4cf8551ad0e2cbc7d69 Mon Sep 17 00:00:00 2001
+From: Jacek Anaszewski <j.anaszewski@samsung.com>
+Date: Thu, 26 Sep 2013 15:36:07 +0200
+Subject: [PATCH 0810/1302] s5p-jpeg: Add support for Exynos4x12
+
+Added support for Exynos4x12 to the s5p-jpeg driver.
+This is work-in-progress - only conversions among formats
+compatible with S5P version are currently reliable.
+
+Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/s5p-jpeg/Makefile         |   2 +-
+ drivers/media/platform/s5p-jpeg/jpeg-core.c      | 764 ++++++++++++++++++-----
+ drivers/media/platform/s5p-jpeg/jpeg-core.h      |  52 +-
+ drivers/media/platform/s5p-jpeg/jpeg-hw-exynos.c | 335 ++++++++++
+ drivers/media/platform/s5p-jpeg/jpeg-hw-exynos.h |  43 ++
+ drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.h    | 354 +++++++++++
+ drivers/media/platform/s5p-jpeg/jpeg-hw.h        | 357 -----------
+ drivers/media/platform/s5p-jpeg/jpeg-regs.h      | 182 ++++++
+ 8 files changed, 1578 insertions(+), 511 deletions(-)
+ create mode 100644 drivers/media/platform/s5p-jpeg/jpeg-hw-exynos.c
+ create mode 100644 drivers/media/platform/s5p-jpeg/jpeg-hw-exynos.h
+ create mode 100644 drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.h
+ delete mode 100644 drivers/media/platform/s5p-jpeg/jpeg-hw.h
+
+diff --git a/drivers/media/platform/s5p-jpeg/Makefile b/drivers/media/platform/s5p-jpeg/Makefile
+index d18cb5e..53527b9 100644
+--- a/drivers/media/platform/s5p-jpeg/Makefile
++++ b/drivers/media/platform/s5p-jpeg/Makefile
+@@ -1,2 +1,2 @@
+-s5p-jpeg-objs := jpeg-core.o
++s5p-jpeg-objs := jpeg-core.o jpeg-hw-exynos.o
+ obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) += s5p-jpeg.o
+diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c
+index cdeb128..58cf5cf 100644
+--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
++++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
+@@ -4,6 +4,7 @@
+  *            http://www.samsung.com
+  *
+  * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
++ * Author: Jacek Anaszewski <j.anaszewski@samsung.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
+@@ -29,80 +30,148 @@
+ #include <media/videobuf2-dma-contig.h>
+ #include "jpeg-core.h"
+-#include "jpeg-hw.h"
++#include "jpeg-hw-s5p.h"
++#include "jpeg-hw-exynos.h"
++#include "jpeg-regs.h"
+-static struct s5p_jpeg_fmt formats_enc[] = {
++static struct s5p_jpeg_fmt sjpeg_formats[] = {
+       {
+               .name           = "JPEG JFIF",
+               .fourcc         = V4L2_PIX_FMT_JPEG,
+-              .colplanes      = 1,
+-              .types          = MEM2MEM_CAPTURE,
++              .types          = SJPEG_FMT_FLAG_ENC_CAPTURE |
++                                SJPEG_FMT_FLAG_DEC_OUTPUT |
++                                SJPEG_FMT_FLAG_S5P |
++                                SJPEG_FMT_FLAG_EXYNOS,
+       },
+       {
+               .name           = "YUV 4:2:2 packed, YCbYCr",
+               .fourcc         = V4L2_PIX_FMT_YUYV,
+               .depth          = 16,
+               .colplanes      = 1,
+-              .types          = MEM2MEM_OUTPUT,
++              .h_align        = 4,
++              .v_align        = 3,
++              .types          = SJPEG_FMT_FLAG_ENC_OUTPUT |
++                                SJPEG_FMT_FLAG_DEC_CAPTURE |
++                                SJPEG_FMT_FLAG_S5P |
++                                SJPEG_FMT_FLAG_EXYNOS,
+       },
+       {
+               .name           = "RGB565",
+               .fourcc         = V4L2_PIX_FMT_RGB565,
+               .depth          = 16,
+               .colplanes      = 1,
+-              .types          = MEM2MEM_OUTPUT,
++              .types          = SJPEG_FMT_FLAG_ENC_OUTPUT |
++                                SJPEG_FMT_FLAG_DEC_CAPTURE |
++                                SJPEG_FMT_FLAG_S5P |
++                                SJPEG_FMT_FLAG_EXYNOS,
++      },
++      {
++              .name           = "ARGB8888, 32 bpp",
++              .fourcc         = V4L2_PIX_FMT_RGB32,
++              .depth          = 32,
++              .colplanes      = 1,
++              .types          = SJPEG_FMT_FLAG_ENC_OUTPUT |
++                                SJPEG_FMT_FLAG_DEC_CAPTURE |
++                                SJPEG_FMT_FLAG_EXYNOS,
++      },
++      {
++              .name           = "YUV 4:4:4 planar, Y/CbCr",
++              .fourcc         = V4L2_PIX_FMT_NV24,
++              .depth          = 24,
++              .colplanes      = 2,
++              .types          = SJPEG_FMT_FLAG_ENC_OUTPUT |
++                                SJPEG_FMT_FLAG_DEC_CAPTURE |
++                                SJPEG_FMT_FLAG_EXYNOS,
+       },
+-};
+-#define NUM_FORMATS_ENC ARRAY_SIZE(formats_enc)
+-
+-static struct s5p_jpeg_fmt formats_dec[] = {
+       {
+-              .name           = "YUV 4:2:0 planar, YCbCr",
++              .name           = "YUV 4:4:4 planar, Y/CrCb",
++              .fourcc         = V4L2_PIX_FMT_NV42,
++              .depth          = 24,
++              .colplanes      = 2,
++              .types          = SJPEG_FMT_FLAG_ENC_OUTPUT |
++                                SJPEG_FMT_FLAG_DEC_CAPTURE |
++                                SJPEG_FMT_FLAG_EXYNOS,
++      },
++      {
++              .name           = "YUV 4:2:2 planar, Y/CrCb",
++              .fourcc         = V4L2_PIX_FMT_NV61,
++              .depth          = 16,
++              .colplanes      = 2,
++              .types          = SJPEG_FMT_FLAG_ENC_OUTPUT |
++                                SJPEG_FMT_FLAG_DEC_CAPTURE |
++                                SJPEG_FMT_FLAG_EXYNOS,
++      },
++      {
++              .name           = "YUV 4:2:2 planar, Y/CbCr",
++              .fourcc         = V4L2_PIX_FMT_NV16,
++              .depth          = 16,
++              .colplanes      = 2,
++              .types          = SJPEG_FMT_FLAG_ENC_OUTPUT |
++                                SJPEG_FMT_FLAG_DEC_CAPTURE |
++                                SJPEG_FMT_FLAG_EXYNOS,
++      },
++      {
++              .name           = "YUV 4:2:0 planar, Y/CbCr",
++              .fourcc         = V4L2_PIX_FMT_NV12,
++              .depth          = 12,
++              .colplanes      = 2,
++              .types          = SJPEG_FMT_FLAG_ENC_OUTPUT |
++                                SJPEG_FMT_FLAG_DEC_CAPTURE |
++                                SJPEG_FMT_FLAG_EXYNOS,
++      },
++      {
++              .name           = "YUV 4:2:0 planar, Y/CrCb",
++              .fourcc         = V4L2_PIX_FMT_NV21,
++              .depth          = 12,
++              .colplanes      = 2,
++              .types          = SJPEG_FMT_FLAG_ENC_OUTPUT |
++                                SJPEG_FMT_FLAG_DEC_CAPTURE |
++                                SJPEG_FMT_FLAG_EXYNOS,
++      },
++      {
++              .name           = "YUV 4:2:0 contiguous 3-planar, Y/Cb/Cr",
+               .fourcc         = V4L2_PIX_FMT_YUV420,
+               .depth          = 12,
+               .colplanes      = 3,
+               .h_align        = 4,
+               .v_align        = 4,
+-              .types          = MEM2MEM_CAPTURE,
++              .types          = SJPEG_FMT_FLAG_ENC_OUTPUT |
++                                SJPEG_FMT_FLAG_DEC_CAPTURE |
++                                SJPEG_FMT_FLAG_S5P |
++                                SJPEG_FMT_FLAG_EXYNOS,
+       },
+       {
+-              .name           = "YUV 4:2:2 packed, YCbYCr",
+-              .fourcc         = V4L2_PIX_FMT_YUYV,
+-              .depth          = 16,
+-              .colplanes      = 1,
+-              .h_align        = 4,
+-              .v_align        = 3,
+-              .types          = MEM2MEM_CAPTURE,
++              .name           = "YUV 4:2:0 contiguous 3-planar, Y/Cr/Cb",
++              .fourcc         = V4L2_PIX_FMT_YVU420,
++              .depth          = 12,
++              .colplanes      = 3,
++              .types          = SJPEG_FMT_FLAG_ENC_OUTPUT |
++                                SJPEG_FMT_FLAG_DEC_CAPTURE |
++                                SJPEG_FMT_FLAG_EXYNOS,
+       },
+       {
+-              .name           = "JPEG JFIF",
+-              .fourcc         = V4L2_PIX_FMT_JPEG,
++              .name           = "Gray",
++              .fourcc         = V4L2_PIX_FMT_GREY,
++              .depth          = 8,
+               .colplanes      = 1,
+-              .types          = MEM2MEM_OUTPUT,
++              .types          = SJPEG_FMT_FLAG_ENC_OUTPUT |
++                                SJPEG_FMT_FLAG_DEC_CAPTURE |
++                                SJPEG_FMT_FLAG_EXYNOS,
+       },
+ };
+-#define NUM_FORMATS_DEC ARRAY_SIZE(formats_dec)
++#define SJPEG_NUM_FORMATS ARRAY_SIZE(sjpeg_formats)
++/* Quantization and Huffman tables for Exynos 4210 IP */
+ static const unsigned char qtbl_luminance[4][64] = {
+-      {/* level 1 - high quality */
+-               8,  6,  6,  8, 12, 14, 16, 17,
+-               6,  6,  6,  8, 10, 13, 12, 15,
+-               6,  6,  7,  8, 13, 14, 18, 24,
+-               8,  8,  8, 14, 13, 19, 24, 35,
+-              12, 10, 13, 13, 20, 26, 34, 39,
+-              14, 13, 14, 19, 26, 34, 39, 39,
+-              16, 12, 18, 24, 34, 39, 39, 39,
+-              17, 15, 24, 35, 39, 39, 39, 39
+-      },
+-      {/* level 2 */
+-              12,  8,  8, 12, 17, 21, 24, 23,
+-               8,  9,  9, 11, 15, 19, 18, 23,
+-               8,  9, 10, 12, 19, 20, 27, 36,
+-              12, 11, 12, 21, 20, 28, 36, 53,
+-              17, 15, 19, 20, 30, 39, 51, 59,
+-              21, 19, 20, 28, 39, 51, 59, 59,
+-              24, 18, 27, 36, 51, 59, 59, 59,
+-              23, 23, 36, 53, 59, 59, 59, 59
++      {/*level 4 - low quality */
++              20, 16, 25, 39, 50, 46, 62, 68,
++              16, 18, 23, 38, 38, 53, 65, 68,
++              25, 23, 31, 38, 53, 65, 68, 68,
++              39, 38, 38, 53, 65, 68, 68, 68,
++              50, 38, 53, 65, 68, 68, 68, 68,
++              46, 53, 65, 68, 68, 68, 68, 68,
++              62, 65, 68, 68, 68, 68, 68, 68,
++              68, 68, 68, 68, 68, 68, 68, 68
+       },
+       {/* level 3 */
+               16, 11, 11, 16, 23, 27, 31, 30,
+@@ -114,38 +183,38 @@ static const unsigned char qtbl_luminance[4][64] = {
+               31, 23, 35, 47, 64, 64, 64, 64,
+               30, 30, 47, 64, 64, 64, 64, 64
+       },
+-      {/*level 4 - low quality */
+-              20, 16, 25, 39, 50, 46, 62, 68,
+-              16, 18, 23, 38, 38, 53, 65, 68,
+-              25, 23, 31, 38, 53, 65, 68, 68,
+-              39, 38, 38, 53, 65, 68, 68, 68,
+-              50, 38, 53, 65, 68, 68, 68, 68,
+-              46, 53, 65, 68, 68, 68, 68, 68,
+-              62, 65, 68, 68, 68, 68, 68, 68,
+-              68, 68, 68, 68, 68, 68, 68, 68
++      {/* level 2 */
++              12,  8,  8, 12, 17, 21, 24, 23,
++               8,  9,  9, 11, 15, 19, 18, 23,
++               8,  9, 10, 12, 19, 20, 27, 36,
++              12, 11, 12, 21, 20, 28, 36, 53,
++              17, 15, 19, 20, 30, 39, 51, 59,
++              21, 19, 20, 28, 39, 51, 59, 59,
++              24, 18, 27, 36, 51, 59, 59, 59,
++              23, 23, 36, 53, 59, 59, 59, 59
++      },
++      {/* level 1 - high quality */
++               8,  6,  6,  8, 12, 14, 16, 17,
++               6,  6,  6,  8, 10, 13, 12, 15,
++               6,  6,  7,  8, 13, 14, 18, 24,
++               8,  8,  8, 14, 13, 19, 24, 35,
++              12, 10, 13, 13, 20, 26, 34, 39,
++              14, 13, 14, 19, 26, 34, 39, 39,
++              16, 12, 18, 24, 34, 39, 39, 39,
++              17, 15, 24, 35, 39, 39, 39, 39
+       }
+ };
+ static const unsigned char qtbl_chrominance[4][64] = {
+-      {/* level 1 - high quality */
+-               9,  8,  9, 11, 14, 17, 19, 24,
+-               8, 10,  9, 11, 14, 13, 17, 22,
+-               9,  9, 13, 14, 13, 15, 23, 26,
+-              11, 11, 14, 14, 15, 20, 26, 33,
+-              14, 14, 13, 15, 20, 24, 33, 39,
+-              17, 13, 15, 20, 24, 32, 39, 39,
+-              19, 17, 23, 26, 33, 39, 39, 39,
+-              24, 22, 26, 33, 39, 39, 39, 39
+-      },
+-      {/* level 2 */
+-              13, 11, 13, 16, 20, 20, 29, 37,
+-              11, 14, 14, 14, 16, 20, 26, 32,
+-              13, 14, 15, 17, 20, 23, 35, 40,
+-              16, 14, 17, 21, 23, 30, 40, 50,
+-              20, 16, 20, 23, 30, 37, 50, 59,
+-              20, 20, 23, 30, 37, 48, 59, 59,
+-              29, 26, 35, 40, 50, 59, 59, 59,
+-              37, 32, 40, 50, 59, 59, 59, 59
++      {/*level 4 - low quality */
++              21, 25, 32, 38, 54, 68, 68, 68,
++              25, 28, 24, 38, 54, 68, 68, 68,
++              32, 24, 32, 43, 66, 68, 68, 68,
++              38, 38, 43, 53, 68, 68, 68, 68,
++              54, 54, 66, 68, 68, 68, 68, 68,
++              68, 68, 68, 68, 68, 68, 68, 68,
++              68, 68, 68, 68, 68, 68, 68, 68,
++              68, 68, 68, 68, 68, 68, 68, 68
+       },
+       {/* level 3 */
+               17, 15, 17, 21, 20, 26, 38, 48,
+@@ -157,15 +226,25 @@ static const unsigned char qtbl_chrominance[4][64] = {
+               38, 35, 46, 53, 64, 64, 64, 64,
+               48, 43, 53, 64, 64, 64, 64, 64
+       },
+-      {/*level 4 - low quality */
+-              21, 25, 32, 38, 54, 68, 68, 68,
+-              25, 28, 24, 38, 54, 68, 68, 68,
+-              32, 24, 32, 43, 66, 68, 68, 68,
+-              38, 38, 43, 53, 68, 68, 68, 68,
+-              54, 54, 66, 68, 68, 68, 68, 68,
+-              68, 68, 68, 68, 68, 68, 68, 68,
+-              68, 68, 68, 68, 68, 68, 68, 68,
+-              68, 68, 68, 68, 68, 68, 68, 68
++      {/* level 2 */
++              13, 11, 13, 16, 20, 20, 29, 37,
++              11, 14, 14, 14, 16, 20, 26, 32,
++              13, 14, 15, 17, 20, 23, 35, 40,
++              16, 14, 17, 21, 23, 30, 40, 50,
++              20, 16, 20, 23, 30, 37, 50, 59,
++              20, 20, 23, 30, 37, 48, 59, 59,
++              29, 26, 35, 40, 50, 59, 59, 59,
++              37, 32, 40, 50, 59, 59, 59, 59
++      },
++      {/* level 1 - high quality */
++               9,  8,  9, 11, 14, 17, 19, 24,
++               8, 10,  9, 11, 14, 13, 17, 22,
++               9,  9, 13, 14, 13, 15, 23, 26,
++              11, 11, 14, 14, 15, 20, 26, 33,
++              14, 14, 13, 15, 20, 24, 33, 39,
++              17, 13, 15, 20, 24, 32, 39, 39,
++              19, 17, 23, 26, 33, 39, 39, 39,
++              24, 22, 26, 33, 39, 39, 39, 39
+       }
+ };
+@@ -203,6 +282,87 @@ static const unsigned char hactblg0[162] = {
+       0xf9, 0xfa
+ };
++/*
++ * Quantization and Huffman tables for Exynos 4412 IP
++ * ITU standard Q-table
++ */
++const unsigned int ITU_Q_tbl[4][16] = {
++      {
++              /*level 4 - low quality */
++              0x2f181211, 0x63636363, 0x421a1512, 0x63636363,
++              0x63381a18, 0x63636363, 0x6363422f, 0x63636363,
++              0x63636363, 0x63636363, 0x63636363, 0x63636363,
++              0x63636363, 0x63636363, 0x63636363, 0x63636363
++      }, {    /* level 3 */
++              0x100a0b10, 0x3d332818, 0x130e0c0c, 0x373c3a1a,
++              0x18100d0e, 0x38453928, 0x1d16110e, 0x3e505733,
++              0x38251612, 0x4d676d44, 0x40372318, 0x5c716851,
++              0x574e4031, 0x65787967, 0x625f5c48, 0x63676470
++      }, {
++              /* level 2 FIXME: Same as index 0 */
++              0x2f181211, 0x63636363, 0x421a1512, 0x63636363,
++              0x63381a18, 0x63636363, 0x6363422f, 0x63636363,
++              0x63636363, 0x63636363, 0x63636363, 0x63636363,
++              0x63636363, 0x63636363, 0x63636363, 0x63636363
++      }, {
++              /* level 1 - high quality FIXME: Same as index 1 */
++              0x100a0b10, 0x3d332818, 0x130e0c0c, 0x373c3a1a,
++              0x18100d0e, 0x38453928, 0x1d16110e, 0x3e505733,
++              0x38251612, 0x4d676d44, 0x40372318, 0x5c716851,
++              0x574e4031, 0x65787967, 0x625f5c48, 0x63676470
++      }
++};
++
++/* ITU Luminace Huffman Table */
++static unsigned int itu_h_tbl_len_dc_luminance[4] = {
++      0x00000000, 0x00000000, 0x00000000, 0x00000c00
++};
++static unsigned int itu_h_tbl_val_dc_luminance[3] = {
++      0x03020100, 0x07060504, 0x0b0a0908
++};
++
++/* ITU Chrominace Huffman Table */
++static unsigned int itu_h_tbl_len_dc_chrominance[4] = {
++      0x00000000, 0x00000000, 0x00000000, 0x000c0000
++};
++static unsigned int itu_h_tbl_val_dc_chrominance[3] = {
++      0x03020100, 0x07060504, 0x0b0a0908
++};
++static unsigned int itu_h_tbl_len_ac_luminance[4] = {
++      0x00000000, 0x00000000, 0x00000000, 0xa2000000
++};
++
++static unsigned int itu_h_tbl_val_ac_luminance[41] = {
++      0x00030201, 0x12051104, 0x06413121, 0x07615113,
++      0x32147122, 0x08a19181, 0xc1b14223, 0xf0d15215,
++      0x72623324, 0x160a0982, 0x1a191817, 0x28272625,
++      0x35342a29, 0x39383736, 0x4544433a, 0x49484746,
++      0x5554534a, 0x59585756, 0x6564635a, 0x69686766,
++      0x7574736a, 0x79787776, 0x8584837a, 0x89888786,
++      0x9493928a, 0x98979695, 0xa3a29a99, 0xa7a6a5a4,
++      0xb2aaa9a8, 0xb6b5b4b3, 0xbab9b8b7, 0xc5c4c3c2,
++      0xc9c8c7c6, 0xd4d3d2ca, 0xd8d7d6d5, 0xe2e1dad9,
++      0xe6e5e4e3, 0xeae9e8e7, 0xf4f3f2f1, 0xf8f7f6f5,
++      0x0000faf9
++};
++
++static u32 itu_h_tbl_len_ac_chrominance[4] = {
++      0x00000000, 0x00000000, 0x51000000, 0x00000051
++};
++static u32 itu_h_tbl_val_ac_chrominance[41] = {
++      0x00030201, 0x12051104, 0x06413121, 0x07615113,
++      0x32147122, 0x08a19181, 0xc1b14223, 0xf0d15215,
++      0x72623324, 0x160a0982, 0x1a191817, 0x28272625,
++      0x35342a29, 0x39383736, 0x4544433a, 0x49484746,
++      0x5554534a, 0x59585756, 0x6564635a, 0x69686766,
++      0x7574736a, 0x79787776, 0x8584837a, 0x89888786,
++      0x9493928a, 0x98979695, 0xa3a29a99, 0xa7a6a5a4,
++      0xb2aaa9a8, 0xb6b5b4b3, 0xbab9b8b7, 0xc5c4c3c2,
++      0xc9c8c7c6, 0xd4d3d2ca, 0xd8d7d6d5, 0xe2e1dad9,
++      0xe6e5e4e3, 0xeae9e8e7, 0xf4f3f2f1, 0xf8f7f6f5,
++      0x0000faf9
++};
++
+ static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c)
+ {
+       return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler);
+@@ -269,6 +429,72 @@ static inline void jpeg_set_hactblg(void __iomem *regs)
+       jpeg_set_htbl(regs, hactblg0, S5P_JPG_HACTBLG(0), ARRAY_SIZE(hactblg0));
+ }
++void jpeg_set_enc_tbl(void __iomem *base)
++{
++      int i;
++
++      for (i = 0; i < 16; i++) {
++              writel((unsigned int)ITU_Q_tbl[0][i],
++                      base + S5P_JPEG_QUAN_TBL_ENTRY_REG + (i*0x04));
++      }
++
++      for (i = 0; i < 16; i++) {
++              writel((unsigned int)ITU_Q_tbl[1][i],
++                      base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0x40 + (i*0x04));
++      }
++
++      for (i = 0; i < 16; i++) {
++              writel((unsigned int)ITU_Q_tbl[2][i],
++                      base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0x80 + (i*0x04));
++      }
++
++      for (i = 0; i < 16; i++) {
++              writel((unsigned int)ITU_Q_tbl[3][i],
++                      base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0xc0 + (i*0x04));
++      }
++
++      for (i = 0; i < 4; i++) {
++              writel((unsigned int)itu_h_tbl_len_dc_luminance[i],
++                      base + S5P_JPEG_HUFF_TBL_ENTRY_REG + (i*0x04));
++      }
++
++      for (i = 0; i < 3; i++) {
++              writel((unsigned int)itu_h_tbl_val_dc_luminance[i],
++                      base + S5P_JPEG_HUFF_TBL_ENTRY_REG + 0x10 + (i*0x04));
++      }
++
++      for (i = 0; i < 4; i++) {
++              writel((unsigned int)itu_h_tbl_len_dc_chrominance[i],
++                      base + S5P_JPEG_HUFF_TBL_ENTRY_REG + 0x20 + (i*0x04));
++      }
++
++      for (i = 0; i < 3; i++) {
++              writel((unsigned int)itu_h_tbl_val_dc_chrominance[i],
++                      base + S5P_JPEG_HUFF_TBL_ENTRY_REG + 0x30 + (i*0x04));
++      }
++
++      for (i = 0; i < 4; i++) {
++              writel((unsigned int)itu_h_tbl_len_ac_luminance[i],
++                      base + S5P_JPEG_HUFF_TBL_ENTRY_REG + 0x40 + (i*0x04));
++      }
++
++      for (i = 0; i < 41; i++) {
++              writel((unsigned int)itu_h_tbl_val_ac_luminance[i],
++                      base + S5P_JPEG_HUFF_TBL_ENTRY_REG + 0x50 + (i*0x04));
++      }
++
++      for (i = 0; i < 4; i++) {
++              writel((unsigned int)itu_h_tbl_len_ac_chrominance[i],
++                      base + S5P_JPEG_HUFF_TBL_ENTRY_REG + 0x100 + (i*0x04));
++      }
++
++      for (i = 0; i < 41; i++) {
++              writel((unsigned int)itu_h_tbl_val_ac_chrominance[i],
++                      base + S5P_JPEG_HUFF_TBL_ENTRY_REG + 0x110 + (i*0x04));
++      }
++
++}
++
+ /*
+  * ============================================================================
+  * Device file operations
+@@ -277,8 +503,8 @@ static inline void jpeg_set_hactblg(void __iomem *regs)
+ static int queue_init(void *priv, struct vb2_queue *src_vq,
+                     struct vb2_queue *dst_vq);
+-static struct s5p_jpeg_fmt *s5p_jpeg_find_format(unsigned int mode,
+-                                               __u32 pixelformat);
++static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
++                              __u32 pixelformat, unsigned int fmt_type);
+ static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx);
+ static int s5p_jpeg_open(struct file *file)
+@@ -286,7 +512,7 @@ static int s5p_jpeg_open(struct file *file)
+       struct s5p_jpeg *jpeg = video_drvdata(file);
+       struct video_device *vfd = video_devdata(file);
+       struct s5p_jpeg_ctx *ctx;
+-      struct s5p_jpeg_fmt *out_fmt;
++      struct s5p_jpeg_fmt *out_fmt, *cap_fmt;
+       int ret = 0;
+       ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+@@ -306,11 +532,17 @@ static int s5p_jpeg_open(struct file *file)
+       ctx->jpeg = jpeg;
+       if (vfd == jpeg->vfd_encoder) {
+-              ctx->mode = S5P_JPEG_ENCODE;
+-              out_fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_RGB565);
++              ctx->mode = SJPEG_ENCODE;
++              out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_RGB565,
++                                                      FMT_TYPE_OUTPUT);
++              cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
++                                                      FMT_TYPE_CAPTURE);
+       } else {
+-              ctx->mode = S5P_JPEG_DECODE;
+-              out_fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_JPEG);
++              ctx->mode = SJPEG_DECODE;
++              out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
++                                                      FMT_TYPE_OUTPUT);
++              cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_YUYV,
++                                                      FMT_TYPE_CAPTURE);
+       }
+       ret = s5p_jpeg_controls_create(ctx);
+@@ -324,7 +556,7 @@ static int s5p_jpeg_open(struct file *file)
+       }
+       ctx->out_q.fmt = out_fmt;
+-      ctx->cap_q.fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_YUYV);
++      ctx->cap_q.fmt = cap_fmt;
+       mutex_unlock(&jpeg->lock);
+       return 0;
+@@ -474,7 +706,7 @@ static int s5p_jpeg_querycap(struct file *file, void *priv,
+ {
+       struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
+-      if (ctx->mode == S5P_JPEG_ENCODE) {
++      if (ctx->mode == SJPEG_ENCODE) {
+               strlcpy(cap->driver, S5P_JPEG_M2M_NAME " encoder",
+                       sizeof(cap->driver));
+               strlcpy(cap->card, S5P_JPEG_M2M_NAME " encoder",
+@@ -496,13 +728,13 @@ static int s5p_jpeg_querycap(struct file *file, void *priv,
+       return 0;
+ }
+-static int enum_fmt(struct s5p_jpeg_fmt *formats, int n,
++static int enum_fmt(struct s5p_jpeg_fmt *sjpeg_formats, int n,
+                   struct v4l2_fmtdesc *f, u32 type)
+ {
+       int i, num = 0;
+       for (i = 0; i < n; ++i) {
+-              if (formats[i].types & type) {
++              if (sjpeg_formats[i].types & type) {
+                       /* index-th format of type type found ? */
+                       if (num == f->index)
+                               break;
+@@ -516,8 +748,8 @@ static int enum_fmt(struct s5p_jpeg_fmt *formats, int n,
+       if (i >= n)
+               return -EINVAL;
+-      strlcpy(f->description, formats[i].name, sizeof(f->description));
+-      f->pixelformat = formats[i].fourcc;
++      strlcpy(f->description, sjpeg_formats[i].name, sizeof(f->description));
++      f->pixelformat = sjpeg_formats[i].fourcc;
+       return 0;
+ }
+@@ -527,11 +759,12 @@ static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
+ {
+       struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
+-      if (ctx->mode == S5P_JPEG_ENCODE)
+-              return enum_fmt(formats_enc, NUM_FORMATS_ENC, f,
+-                              MEM2MEM_CAPTURE);
++      if (ctx->mode == SJPEG_ENCODE)
++              return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
++                              SJPEG_FMT_FLAG_ENC_CAPTURE);
+-      return enum_fmt(formats_dec, NUM_FORMATS_DEC, f, MEM2MEM_CAPTURE);
++      return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
++                                      SJPEG_FMT_FLAG_DEC_CAPTURE);
+ }
+ static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
+@@ -539,11 +772,12 @@ static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
+ {
+       struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
+-      if (ctx->mode == S5P_JPEG_ENCODE)
+-              return enum_fmt(formats_enc, NUM_FORMATS_ENC, f,
+-                              MEM2MEM_OUTPUT);
++      if (ctx->mode == SJPEG_ENCODE)
++              return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
++                              SJPEG_FMT_FLAG_ENC_OUTPUT);
+-      return enum_fmt(formats_dec, NUM_FORMATS_DEC, f, MEM2MEM_OUTPUT);
++      return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
++                                      SJPEG_FMT_FLAG_DEC_OUTPUT);
+ }
+ static struct s5p_jpeg_q_data *get_q_data(struct s5p_jpeg_ctx *ctx,
+@@ -569,7 +803,7 @@ static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
+               return -EINVAL;
+       if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+-          ct->mode == S5P_JPEG_DECODE && !ct->hdr_parsed)
++          ct->mode == SJPEG_DECODE && !ct->hdr_parsed)
+               return -EINVAL;
+       q_data = get_q_data(ct, f->type);
+       BUG_ON(q_data == NULL);
+@@ -590,29 +824,34 @@ static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
+       return 0;
+ }
+-static struct s5p_jpeg_fmt *s5p_jpeg_find_format(unsigned int mode,
+-                                               u32 pixelformat)
++static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
++                              u32 pixelformat, unsigned int fmt_type)
+ {
+-      unsigned int k;
+-      struct s5p_jpeg_fmt *formats;
+-      int n;
++      unsigned int k, fmt_flag, ver_flag;
+-      if (mode == S5P_JPEG_ENCODE) {
+-              formats = formats_enc;
+-              n = NUM_FORMATS_ENC;
+-      } else {
+-              formats = formats_dec;
+-              n = NUM_FORMATS_DEC;
+-      }
+-
+-      for (k = 0; k < n; k++) {
+-              struct s5p_jpeg_fmt *fmt = &formats[k];
+-              if (fmt->fourcc == pixelformat)
++      if (ctx->mode == SJPEG_ENCODE)
++              fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
++                              SJPEG_FMT_FLAG_ENC_OUTPUT :
++                              SJPEG_FMT_FLAG_ENC_CAPTURE;
++      else
++              fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
++                              SJPEG_FMT_FLAG_DEC_OUTPUT :
++                              SJPEG_FMT_FLAG_DEC_CAPTURE;
++
++      ver_flag = (ctx->jpeg->variant->version == SJPEG_S5P) ?
++                      SJPEG_FMT_FLAG_S5P :
++                      SJPEG_FMT_FLAG_EXYNOS;
++
++      for (k = 0; k < ARRAY_SIZE(sjpeg_formats); k++) {
++              struct s5p_jpeg_fmt *fmt = &sjpeg_formats[k];
++              if (fmt->fourcc == pixelformat &&
++                  fmt->types & fmt_flag &&
++                  fmt->types & ver_flag) {
+                       return fmt;
++              }
+       }
+       return NULL;
+-
+ }
+ static void jpeg_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
+@@ -633,7 +872,6 @@ static void jpeg_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
+               *w += w_step;
+       if (*h < height && (*h + h_step) < hmax)
+               *h += h_step;
+-
+ }
+ static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
+@@ -648,7 +886,7 @@ static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
+       /* V4L2 specification suggests the driver corrects the format struct
+        * if any of the dimensions is unsupported */
+-      if (q_type == MEM2MEM_OUTPUT)
++      if (q_type == FMT_TYPE_OUTPUT)
+               jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
+                                      S5P_JPEG_MAX_WIDTH, 0,
+                                      &pix->height, S5P_JPEG_MIN_HEIGHT,
+@@ -686,15 +924,16 @@ static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
+       struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
+       struct s5p_jpeg_fmt *fmt;
+-      fmt = s5p_jpeg_find_format(ctx->mode, f->fmt.pix.pixelformat);
+-      if (!fmt || !(fmt->types & MEM2MEM_CAPTURE)) {
++      fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
++                                              FMT_TYPE_CAPTURE);
++      if (!fmt) {
+               v4l2_err(&ctx->jpeg->v4l2_dev,
+                        "Fourcc format (0x%08x) invalid.\n",
+                        f->fmt.pix.pixelformat);
+               return -EINVAL;
+       }
+-      return vidioc_try_fmt(f, fmt, ctx, MEM2MEM_CAPTURE);
++      return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_CAPTURE);
+ }
+ static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
+@@ -703,15 +942,16 @@ static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
+       struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
+       struct s5p_jpeg_fmt *fmt;
+-      fmt = s5p_jpeg_find_format(ctx->mode, f->fmt.pix.pixelformat);
+-      if (!fmt || !(fmt->types & MEM2MEM_OUTPUT)) {
++      fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
++                                              FMT_TYPE_OUTPUT);
++      if (!fmt) {
+               v4l2_err(&ctx->jpeg->v4l2_dev,
+                        "Fourcc format (0x%08x) invalid.\n",
+                        f->fmt.pix.pixelformat);
+               return -EINVAL;
+       }
+-      return vidioc_try_fmt(f, fmt, ctx, MEM2MEM_OUTPUT);
++      return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_OUTPUT);
+ }
+ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
+@@ -719,6 +959,7 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
+       struct vb2_queue *vq;
+       struct s5p_jpeg_q_data *q_data = NULL;
+       struct v4l2_pix_format *pix = &f->fmt.pix;
++      unsigned int f_type;
+       vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
+       if (!vq)
+@@ -732,7 +973,10 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
+               return -EBUSY;
+       }
+-      q_data->fmt = s5p_jpeg_find_format(ct->mode, pix->pixelformat);
++      f_type = (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ?
++                      FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE;
++
++      q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type);
+       q_data->w = pix->width;
+       q_data->h = pix->height;
+       if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG)
+@@ -834,7 +1078,7 @@ static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
+       switch (ctrl->id) {
+       case V4L2_CID_JPEG_COMPRESSION_QUALITY:
+-              ctx->compr_quality = S5P_JPEG_COMPR_QUAL_WORST - ctrl->val;
++              ctx->compr_quality = ctrl->val;
+               break;
+       case V4L2_CID_JPEG_RESTART_INTERVAL:
+               ctx->restart_interval = ctrl->val;
+@@ -860,15 +1104,16 @@ static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx)
+       v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
+-      if (ctx->mode == S5P_JPEG_ENCODE) {
++      if (ctx->mode == SJPEG_ENCODE) {
+               v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
+                                 V4L2_CID_JPEG_COMPRESSION_QUALITY,
+-                                0, 3, 1, 3);
++                                0, 3, 1, S5P_JPEG_COMPR_QUAL_WORST);
+               v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
+                                 V4L2_CID_JPEG_RESTART_INTERVAL,
+                                 0, 3, 0xffff, 0);
+-              mask = ~0x06; /* 422, 420 */
++              if (ctx->jpeg->variant->version == SJPEG_S5P)
++                      mask = ~0x06; /* 422, 420 */
+       }
+       ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
+@@ -879,9 +1124,16 @@ static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx)
+       if (ctx->ctrl_handler.error)
+               return ctx->ctrl_handler.error;
+-      if (ctx->mode == S5P_JPEG_DECODE)
++      if (ctx->mode == SJPEG_DECODE)
+               ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
+                       V4L2_CTRL_FLAG_READ_ONLY;
++
++      v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
++
++      ctx->compr_quality = S5P_JPEG_COMPR_QUAL_WORST;
++      ctx->restart_interval = 0;
++      ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422;
++
+       return 0;
+ }
+@@ -902,6 +1154,7 @@ static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
+       .vidioc_reqbufs                 = v4l2_m2m_ioctl_reqbufs,
+       .vidioc_querybuf                = v4l2_m2m_ioctl_querybuf,
++
+       .vidioc_qbuf                    = v4l2_m2m_ioctl_qbuf,
+       .vidioc_dqbuf                   = v4l2_m2m_ioctl_dqbuf,
+@@ -932,7 +1185,7 @@ static void s5p_jpeg_device_run(void *priv)
+       jpeg_reset(jpeg->regs);
+       jpeg_poweron(jpeg->regs);
+       jpeg_proc_mode(jpeg->regs, ctx->mode);
+-      if (ctx->mode == S5P_JPEG_ENCODE) {
++      if (ctx->mode == SJPEG_ENCODE) {
+               if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565)
+                       jpeg_input_raw_mode(jpeg->regs, S5P_JPEG_RAW_IN_565);
+               else
+@@ -977,7 +1230,7 @@ static void s5p_jpeg_device_run(void *priv)
+               jpeg_htbl_dc(jpeg->regs, 2);
+               jpeg_htbl_ac(jpeg->regs, 3);
+               jpeg_htbl_dc(jpeg->regs, 3);
+-      } else { /* S5P_JPEG_DECODE */
++      } else { /* SJPEG_DECODE */
+               jpeg_rst_int_enable(jpeg->regs, true);
+               jpeg_data_num_int_enable(jpeg->regs, true);
+               jpeg_final_mcu_num_int_enable(jpeg->regs, true);
+@@ -992,11 +1245,96 @@ static void s5p_jpeg_device_run(void *priv)
+       jpeg_start(jpeg->regs);
+ }
++static void exynos_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
++{
++      struct s5p_jpeg *jpeg = ctx->jpeg;
++      struct s5p_jpeg_fmt *fmt;
++      struct vb2_buffer *vb;
++      u32 pix_size, buf_addr = 0, buf_addr2 = 0, buf_addr3 = 0;
++
++      pix_size = ctx->out_q.w * ctx->out_q.h;
++
++      if (ctx->mode == SJPEG_ENCODE) {
++              vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
++              fmt = ctx->out_q.fmt;
++      } else {
++              vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
++              fmt = ctx->cap_q.fmt;
++      }
++
++      buf_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
++
++      if (fmt->colplanes == 2) {
++              buf_addr2 = (u32)(buf_addr + pix_size);
++      } else if (fmt->colplanes == 3) {
++              buf_addr2 = (u32)(buf_addr + pix_size);
++              if (fmt->fourcc == V4L2_PIX_FMT_YUV420 ||
++                  fmt->fourcc == V4L2_PIX_FMT_YVU420)
++                      buf_addr3 = (u32)(buf_addr2 + (pix_size >> 2));
++              else
++                      buf_addr3 = (u32)(buf_addr2 + (pix_size >> 1));
++      }
++
++      jpeg_set_frame_buf_address(jpeg->regs, fmt->fourcc, buf_addr,
++                                      buf_addr2, buf_addr3);
++}
++
++static void exynos_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
++{
++      struct s5p_jpeg *jpeg = ctx->jpeg;
++      struct vb2_buffer *vb;
++      unsigned int jpeg_addr = 0;
++
++      if (ctx->mode == SJPEG_ENCODE)
++              vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
++      else
++              vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
++
++      jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
++      jpeg_set_stream_buf_address(jpeg->regs, jpeg_addr);
++}
++
++static void exynos_jpeg_device_run(void *priv)
++{
++      struct s5p_jpeg_ctx *ctx = priv;
++      struct s5p_jpeg *jpeg = ctx->jpeg;
++      unsigned int bitstream_size;
++
++      if (ctx->mode == SJPEG_ENCODE) {
++              jpeg_sw_reset(jpeg->regs);
++              jpeg_set_interrupt(jpeg->regs);
++              jpeg_set_huf_table_enable(jpeg->regs, 1);
++              jpeg_set_enc_tbl(jpeg->regs);
++              jpeg_set_encode_tbl_select(jpeg->regs, ctx->compr_quality);
++              jpeg_set_stream_size(jpeg->regs, ctx->out_q.w, ctx->out_q.h);
++              jpeg_set_enc_out_fmt(jpeg->regs, ctx->subsampling);
++              jpeg_set_img_fmt(jpeg->regs, ctx->out_q.fmt->fourcc);
++              exynos_jpeg_set_img_addr(ctx);
++              exynos_jpeg_set_jpeg_addr(ctx);
++              jpeg_set_encode_hoff_cnt(jpeg->regs, ctx->out_q.fmt->fourcc);
++      } else {
++              jpeg_sw_reset(jpeg->regs);
++              jpeg_set_interrupt(jpeg->regs);
++              exynos_jpeg_set_img_addr(ctx);
++              exynos_jpeg_set_jpeg_addr(ctx);
++              jpeg_set_img_fmt(jpeg->regs, ctx->cap_q.fmt->fourcc);
++
++              if ((ctx->out_q.size % 32) == 0)
++                      bitstream_size = (ctx->out_q.size / 32);
++              else
++                      bitstream_size = (ctx->out_q.size / 32) + 1;
++
++              jpeg_set_dec_bitstream_size(jpeg->regs, bitstream_size);
++      }
++
++      jpeg_set_enc_dec_mode(jpeg->regs, ctx->mode);
++}
++
+ static int s5p_jpeg_job_ready(void *priv)
+ {
+       struct s5p_jpeg_ctx *ctx = priv;
+-      if (ctx->mode == S5P_JPEG_DECODE)
++      if (ctx->mode == SJPEG_DECODE)
+               return ctx->hdr_parsed;
+       return 1;
+ }
+@@ -1009,6 +1347,12 @@ static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
+       .device_run     = s5p_jpeg_device_run,
+       .job_ready      = s5p_jpeg_job_ready,
+       .job_abort      = s5p_jpeg_job_abort,
++}
++;
++static struct v4l2_m2m_ops exynos_jpeg_m2m_ops = {
++      .device_run     = exynos_jpeg_device_run,
++      .job_ready      = s5p_jpeg_job_ready,
++      .job_abort      = s5p_jpeg_job_abort,
+ };
+ /*
+@@ -1035,7 +1379,7 @@ static int s5p_jpeg_queue_setup(struct vb2_queue *vq,
+        * header is parsed during decoding and parsed information stored
+        * in the context so we do not allow another buffer to overwrite it
+        */
+-      if (ctx->mode == S5P_JPEG_DECODE)
++      if (ctx->mode == SJPEG_DECODE)
+               count = 1;
+       *nbuffers = count;
+@@ -1070,7 +1414,7 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
+ {
+       struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+-      if (ctx->mode == S5P_JPEG_DECODE &&
++      if (ctx->mode == SJPEG_DECODE &&
+           vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+               struct s5p_jpeg_q_data tmp, *q_data;
+               ctx->hdr_parsed = s5p_jpeg_parse_hdr(&tmp,
+@@ -1185,11 +1529,11 @@ static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
+       src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
+       dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
+-      if (curr_ctx->mode == S5P_JPEG_ENCODE)
++      if (curr_ctx->mode == SJPEG_ENCODE)
+               enc_jpeg_too_large = jpeg_enc_stream_stat(jpeg->regs);
+       timer_elapsed = jpeg_timer_stat(jpeg->regs);
+       op_completed = jpeg_result_stat_ok(jpeg->regs);
+-      if (curr_ctx->mode == S5P_JPEG_DECODE)
++      if (curr_ctx->mode == SJPEG_DECODE)
+               op_completed = op_completed && jpeg_stream_stat_ok(jpeg->regs);
+       if (enc_jpeg_too_large) {
+@@ -1208,7 +1552,7 @@ static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
+       dst_buf->v4l2_buf.timestamp = src_buf->v4l2_buf.timestamp;
+       v4l2_m2m_buf_done(src_buf, state);
+-      if (curr_ctx->mode == S5P_JPEG_ENCODE)
++      if (curr_ctx->mode == SJPEG_ENCODE)
+               vb2_set_plane_payload(dst_buf, 0, payload_size);
+       v4l2_m2m_buf_done(dst_buf, state);
+       v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
+@@ -1221,6 +1565,79 @@ static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
+       return IRQ_HANDLED;
+ }
++int jpeg_int_pending(struct s5p_jpeg *ctrl)
++{
++      unsigned int    int_status;
++
++      int_status = jpeg_get_int_status(ctrl->regs);
++
++      return int_status;
++}
++
++static irqreturn_t exynos_jpeg_irq(int irq, void *priv)
++{
++      unsigned int int_status;
++      struct vb2_buffer *src_vb, *dst_vb;
++      struct s5p_jpeg *jpeg = priv;
++      struct s5p_jpeg_ctx *curr_ctx;
++      unsigned long payload_size = 0;
++
++      spin_lock(&jpeg->slock);
++
++      curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
++
++      src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
++      dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
++
++      int_status = jpeg_int_pending(jpeg);
++
++      if (int_status) {
++              switch (int_status & 0x1f) {
++              case 0x1:
++                      jpeg->irq_ret = ERR_PROT;
++                      break;
++              case 0x2:
++                      jpeg->irq_ret = OK_ENC_OR_DEC;
++                      break;
++              case 0x4:
++                      jpeg->irq_ret = ERR_DEC_INVALID_FORMAT;
++                      break;
++              case 0x8:
++                      jpeg->irq_ret = ERR_MULTI_SCAN;
++                      break;
++              case 0x10:
++                      jpeg->irq_ret = ERR_FRAME;
++                      break;
++              default:
++                      jpeg->irq_ret = ERR_UNKNOWN;
++                      break;
++              }
++      } else {
++              jpeg->irq_ret = ERR_UNKNOWN;
++      }
++
++      if (jpeg->irq_ret == OK_ENC_OR_DEC) {
++              if (curr_ctx->mode == SJPEG_ENCODE) {
++                      payload_size = jpeg_get_stream_size(jpeg->regs);
++                      vb2_set_plane_payload(dst_vb, 0, payload_size);
++              }
++              v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
++              v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
++      } else {
++              v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR);
++              v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR);
++      }
++
++      v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
++      curr_ctx->subsampling = jpeg_get_frame_fmt(jpeg->regs);
++
++      spin_unlock(&jpeg->slock);
++      return IRQ_HANDLED;
++}
++
++
++static void *jpeg_get_drv_data(struct platform_device *pdev);
++
+ /*
+  * ============================================================================
+  * Driver basic infrastructure
+@@ -1231,6 +1648,7 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
+ {
+       struct s5p_jpeg *jpeg;
+       struct resource *res;
++      struct v4l2_m2m_ops *samsung_jpeg_m2m_ops;
+       int ret;
+       /* JPEG IP abstraction struct */
+@@ -1238,6 +1656,8 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
+       if (!jpeg)
+               return -ENOMEM;
++      jpeg->variant = jpeg_get_drv_data(pdev);
++
+       mutex_init(&jpeg->lock);
+       spin_lock_init(&jpeg->slock);
+       jpeg->dev = &pdev->dev;
+@@ -1256,8 +1676,8 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
+               return ret;
+       }
+-      ret = devm_request_irq(&pdev->dev, jpeg->irq, s5p_jpeg_irq, 0,
+-                      dev_name(&pdev->dev), jpeg);
++      ret = devm_request_irq(&pdev->dev, jpeg->irq, jpeg->variant->jpeg_irq,
++                              0, dev_name(&pdev->dev), jpeg);
+       if (ret) {
+               dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq);
+               return ret;
+@@ -1280,8 +1700,13 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
+               goto clk_get_rollback;
+       }
++      if (jpeg->variant->version == SJPEG_S5P)
++              samsung_jpeg_m2m_ops = &s5p_jpeg_m2m_ops;
++      else
++              samsung_jpeg_m2m_ops = &exynos_jpeg_m2m_ops;
++
+       /* mem2mem device */
+-      jpeg->m2m_dev = v4l2_m2m_init(&s5p_jpeg_m2m_ops);
++      jpeg->m2m_dev = v4l2_m2m_init(samsung_jpeg_m2m_ops);
+       if (IS_ERR(jpeg->m2m_dev)) {
+               v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
+               ret = PTR_ERR(jpeg->m2m_dev);
+@@ -1430,21 +1855,57 @@ static const struct dev_pm_ops s5p_jpeg_pm_ops = {
+ };
+ #ifdef CONFIG_OF
+-static const struct of_device_id s5p_jpeg_of_match[] = {
+-      { .compatible = "samsung,s5pv210-jpeg" },
+-      { .compatible = "samsung,exynos4210-jpeg" },
+-      { /* sentinel */ },
++static struct s5p_jpeg_variant s5p_jpeg_drvdata = {
++      .version        = SJPEG_S5P,
++      .jpeg_irq       = s5p_jpeg_irq,
++};
++
++static struct s5p_jpeg_variant exynos_jpeg_drvdata = {
++      .version        = SJPEG_EXYNOS,
++      .jpeg_irq       = exynos_jpeg_irq,
+ };
+-MODULE_DEVICE_TABLE(of, s5p_jpeg_of_match);
++
++static const struct of_device_id samsung_jpeg_match[] = {
++      {
++              .compatible = "samsung,s5pv210-jpeg",
++              .data = &s5p_jpeg_drvdata,
++      }, {
++              .compatible = "samsung,exynos4210-jpeg",
++              .data = &s5p_jpeg_drvdata,
++      }, {
++              .compatible = "samsung,exynos4212-jpeg",
++              .data = &exynos_jpeg_drvdata,
++      },
++      {},
++};
++
++MODULE_DEVICE_TABLE(of, samsung_jpeg_match);
++
++static void *jpeg_get_drv_data(struct platform_device *pdev)
++{
++      struct s5p_jpeg_variant *driver_data = NULL;
++
++      if (pdev->dev.of_node) {
++              const struct of_device_id *match;
++              match = of_match_node(of_match_ptr(samsung_jpeg_match),
++                                       pdev->dev.of_node);
++              if (match)
++                      driver_data = (struct s5p_jpeg_variant *)match->data;
++              } else {
++                      driver_data = (struct s5p_jpeg_variant *)
++                              platform_get_device_id(pdev)->driver_data;
++              }
++      return driver_data;
++}
+ #endif
+ static struct platform_driver s5p_jpeg_driver = {
+       .probe = s5p_jpeg_probe,
+       .remove = s5p_jpeg_remove,
+       .driver = {
+-              .of_match_table = of_match_ptr(s5p_jpeg_of_match),
+-              .owner = THIS_MODULE,
+-              .name = S5P_JPEG_M2M_NAME,
++              .of_match_table = of_match_ptr(samsung_jpeg_match),
++              .owner          = THIS_MODULE,
++              .name           = S5P_JPEG_M2M_NAME,
+               .pm = &s5p_jpeg_pm_ops,
+       },
+ };
+@@ -1452,5 +1913,6 @@ static struct platform_driver s5p_jpeg_driver = {
+ module_platform_driver(s5p_jpeg_driver);
+ MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzej.p@samsung.com>");
++MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
+ MODULE_DESCRIPTION("Samsung JPEG codec driver");
+ MODULE_LICENSE("GPL");
+diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.h b/drivers/media/platform/s5p-jpeg/jpeg-core.h
+index 4a4776b..f299654 100644
+--- a/drivers/media/platform/s5p-jpeg/jpeg-core.h
++++ b/drivers/media/platform/s5p-jpeg/jpeg-core.h
+@@ -13,12 +13,15 @@
+ #ifndef JPEG_CORE_H_
+ #define JPEG_CORE_H_
++#include <linux/interrupt.h>
+ #include <media/v4l2-device.h>
+ #include <media/v4l2-fh.h>
+ #include <media/v4l2-ctrls.h>
+ #define S5P_JPEG_M2M_NAME             "s5p-jpeg"
++#define JPEG_MAX_PLANE                3
++
+ /* JPEG compression quality setting */
+ #define S5P_JPEG_COMPR_QUAL_BEST      0
+ #define S5P_JPEG_COMPR_QUAL_WORST     3
+@@ -43,8 +46,45 @@
+ #define DHP                           0xde
+ /* Flags that indicate a format can be used for capture/output */
+-#define MEM2MEM_CAPTURE                       (1 << 0)
+-#define MEM2MEM_OUTPUT                        (1 << 1)
++#define SJPEG_FMT_FLAG_ENC_CAPTURE    (1 << 0)
++#define SJPEG_FMT_FLAG_ENC_OUTPUT     (1 << 1)
++#define SJPEG_FMT_FLAG_DEC_CAPTURE    (1 << 2)
++#define SJPEG_FMT_FLAG_DEC_OUTPUT     (1 << 3)
++#define SJPEG_FMT_FLAG_S5P            (1 << 4)
++#define SJPEG_FMT_FLAG_EXYNOS         (1 << 5)
++
++#define SJPEG_ENCODE          0
++#define SJPEG_DECODE          1
++
++#define FMT_TYPE_OUTPUT               0
++#define FMT_TYPE_CAPTURE      1
++
++/* Version numbers */
++
++#define SJPEG_S5P     1
++#define SJPEG_EXYNOS  2
++
++enum exynos_jpeg_result {
++      OK_ENC_OR_DEC,
++      ERR_PROT,
++      ERR_DEC_INVALID_FORMAT,
++      ERR_MULTI_SCAN,
++      ERR_FRAME,
++      ERR_UNKNOWN,
++};
++
++enum  exynos_jpeg_img_quality_level {
++      QUALITY_LEVEL_1 = 0,    /* high */
++      QUALITY_LEVEL_2,
++      QUALITY_LEVEL_3,
++      QUALITY_LEVEL_4,        /* low */
++};
++
++enum exynos_jpeg_scale_value {
++      JPEG_SCALE_NORMAL,
++      JPEG_SCALE_2,
++      JPEG_SCALE_4,
++};
+ /**
+  * struct s5p_jpeg - JPEG IP abstraction
+@@ -71,9 +111,16 @@ struct s5p_jpeg {
+       void __iomem            *regs;
+       unsigned int            irq;
++      enum exynos_jpeg_result irq_ret;
+       struct clk              *clk;
+       struct device           *dev;
+       void                    *alloc_ctx;
++      struct s5p_jpeg_variant *variant;
++};
++
++struct s5p_jpeg_variant {
++      unsigned int    version;
++      irqreturn_t     (*jpeg_irq)(int irq, void *priv);
+ };
+ /**
+@@ -91,6 +138,7 @@ struct s5p_jpeg_fmt {
+       u32     fourcc;
+       int     depth;
+       int     colplanes;
++      int     memplanes;
+       int     h_align;
+       int     v_align;
+       u32     types;
+diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos.c b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos.c
+new file mode 100644
+index 0000000..7b48a17
+--- /dev/null
++++ b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos.c
+@@ -0,0 +1,335 @@
++/* Copyright (c) 2013 Samsung Electronics Co., Ltd.
++ *            http://www.samsung.com/
++ *
++ * Register interface file for JPEG driver on Exynos4x12 and 5250.
++ *
++ * 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/io.h>
++#include <linux/delay.h>
++
++#include "jpeg-hw-exynos.h"
++#include "jpeg-regs.h"
++
++void jpeg_sw_reset(void __iomem *base)
++{
++      unsigned int reg;
++
++      reg = readl(base + S5P_JPEG_CNTL_REG);
++      writel(reg & ~S5P_JPEG_SOFT_RESET_HI,
++                      base + S5P_JPEG_CNTL_REG);
++
++      ndelay(100000);
++
++      writel(reg | S5P_JPEG_SOFT_RESET_HI,
++                      base + S5P_JPEG_CNTL_REG);
++}
++
++void jpeg_set_enc_dec_mode(void __iomem *base, unsigned int mode)
++{
++      unsigned int reg;
++
++      reg = readl(base + S5P_JPEG_CNTL_REG);
++      /* set jpeg mod register */
++      if (mode == SJPEG_DECODE) {
++              writel((reg & S5P_JPEG_ENC_DEC_MODE_MASK) | S5P_JPEG_DEC_MODE,
++                      base + S5P_JPEG_CNTL_REG);
++      } else {/* encode */
++              writel((reg & S5P_JPEG_ENC_DEC_MODE_MASK) | S5P_JPEG_ENC_MODE,
++                      base + S5P_JPEG_CNTL_REG);
++      }
++}
++
++void jpeg_set_img_fmt(void __iomem *base, unsigned int img_fmt)
++{
++      unsigned int reg;
++
++      reg = readl(base + S5P_JPEG_IMG_FMT_REG) &
++                      S5P_JPEG_ENC_IN_FMT_MASK; /* clear except enc format */
++
++      switch (img_fmt) {
++      case V4L2_PIX_FMT_GREY:
++              reg = reg | S5P_JPEG_ENC_GRAY_IMG | S5P_JPEG_GRAY_IMG_IP;
++              break;
++      case V4L2_PIX_FMT_RGB32:
++              reg = reg | S5P_JPEG_ENC_RGB_IMG |
++                              S5P_JPEG_RGB_IP_RGB_32BIT_IMG;
++              break;
++      case V4L2_PIX_FMT_RGB565:
++              reg = reg | S5P_JPEG_ENC_RGB_IMG |
++                              S5P_JPEG_RGB_IP_RGB_16BIT_IMG;
++              break;
++      case V4L2_PIX_FMT_NV24:
++              reg = reg | S5P_JPEG_ENC_YUV_444_IMG |
++                              S5P_JPEG_YUV_444_IP_YUV_444_2P_IMG |
++                              S5P_JPEG_SWAP_CHROMA_CbCr;
++              break;
++      case V4L2_PIX_FMT_NV42:
++              reg = reg | S5P_JPEG_ENC_YUV_444_IMG |
++                              S5P_JPEG_YUV_444_IP_YUV_444_2P_IMG |
++                              S5P_JPEG_SWAP_CHROMA_CrCb;
++              break;
++      case V4L2_PIX_FMT_YUYV:
++              reg = reg | S5P_JPEG_DEC_YUV_422_IMG |
++                              S5P_JPEG_YUV_422_IP_YUV_422_1P_IMG |
++                              S5P_JPEG_SWAP_CHROMA_CbCr;
++              break;
++
++      case V4L2_PIX_FMT_YVYU:
++              reg = reg | S5P_JPEG_DEC_YUV_422_IMG |
++                              S5P_JPEG_YUV_422_IP_YUV_422_1P_IMG |
++                              S5P_JPEG_SWAP_CHROMA_CrCb;
++              break;
++      case V4L2_PIX_FMT_NV16:
++              reg = reg | S5P_JPEG_DEC_YUV_422_IMG |
++                              S5P_JPEG_YUV_422_IP_YUV_422_2P_IMG |
++                              S5P_JPEG_SWAP_CHROMA_CbCr;
++              break;
++      case V4L2_PIX_FMT_NV61:
++              reg = reg | S5P_JPEG_DEC_YUV_422_IMG |
++                              S5P_JPEG_YUV_422_IP_YUV_422_2P_IMG |
++                              S5P_JPEG_SWAP_CHROMA_CrCb;
++              break;
++      case V4L2_PIX_FMT_NV12:
++              reg = reg | S5P_JPEG_DEC_YUV_420_IMG |
++                              S5P_JPEG_YUV_420_IP_YUV_420_2P_IMG |
++                              S5P_JPEG_SWAP_CHROMA_CbCr;
++              break;
++      case V4L2_PIX_FMT_NV21:
++              reg = reg | S5P_JPEG_DEC_YUV_420_IMG |
++                              S5P_JPEG_YUV_420_IP_YUV_420_2P_IMG |
++                              S5P_JPEG_SWAP_CHROMA_CrCb;
++              break;
++      case V4L2_PIX_FMT_YUV420:
++              reg = reg | S5P_JPEG_DEC_YUV_420_IMG |
++                              S5P_JPEG_YUV_420_IP_YUV_420_3P_IMG |
++                              S5P_JPEG_SWAP_CHROMA_CbCr;
++              break;
++      case V4L2_PIX_FMT_YVU420:
++              reg = reg | S5P_JPEG_DEC_YUV_420_IMG |
++                              S5P_JPEG_YUV_420_IP_YUV_420_3P_IMG |
++                              S5P_JPEG_SWAP_CHROMA_CrCb;
++              break;
++      default:
++              break;
++
++      }
++
++      writel(reg, base + S5P_JPEG_IMG_FMT_REG);
++}
++
++void jpeg_set_enc_out_fmt(void __iomem *base, unsigned int out_fmt)
++{
++      unsigned int reg;
++
++      reg = readl(base + S5P_JPEG_IMG_FMT_REG) &
++                      ~S5P_JPEG_ENC_FMT_MASK; /* clear enc format */
++
++      switch (out_fmt) {
++      case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY:
++              reg = reg | S5P_JPEG_ENC_FMT_GRAY;
++              break;
++
++      case V4L2_JPEG_CHROMA_SUBSAMPLING_444:
++              reg = reg | S5P_JPEG_ENC_FMT_YUV_444;
++              break;
++
++      case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
++              reg = reg | S5P_JPEG_ENC_FMT_YUV_422;
++              break;
++
++      case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
++              reg = reg | S5P_JPEG_ENC_FMT_YUV_420;
++              break;
++
++      default:
++              break;
++      }
++
++      writel(reg, base + S5P_JPEG_IMG_FMT_REG);
++}
++
++void jpeg_set_interrupt(void __iomem *base)
++{
++      unsigned int reg;
++
++      reg = readl(base + S5P_JPEG_INT_EN_REG) & ~S5P_JPEG_INT_EN_MASK;
++      writel(S5P_JPEG_INT_EN_ALL, base + S5P_JPEG_INT_EN_REG);
++}
++
++unsigned int jpeg_get_int_status(void __iomem *base)
++{
++      unsigned int    int_status;
++
++      int_status = readl(base + S5P_JPEG_INT_STATUS_REG);
++
++      return int_status;
++}
++
++void jpeg_set_huf_table_enable(void __iomem *base, int value)
++{
++      unsigned int    reg;
++
++      reg = readl(base + S5P_JPEG_CNTL_REG) & ~S5P_JPEG_HUF_TBL_EN;
++
++      if (value == 1)
++              writel(reg | S5P_JPEG_HUF_TBL_EN, base + S5P_JPEG_CNTL_REG);
++      else
++              writel(reg | ~S5P_JPEG_HUF_TBL_EN, base + S5P_JPEG_CNTL_REG);
++}
++
++void jpeg_set_dec_scaling(void __iomem *base,
++              enum exynos_jpeg_scale_value x_value, enum exynos_jpeg_scale_value y_value)
++{
++      unsigned int    reg;
++
++      reg = readl(base + S5P_JPEG_CNTL_REG) &
++                      ~(S5P_JPEG_HOR_SCALING_MASK |
++                              S5P_JPEG_VER_SCALING_MASK);
++
++      writel(reg | S5P_JPEG_HOR_SCALING(x_value) |
++                      S5P_JPEG_VER_SCALING(y_value),
++                              base + S5P_JPEG_CNTL_REG);
++}
++
++void jpeg_set_sys_int_enable(void __iomem *base, int value)
++{
++      unsigned int    reg;
++
++      reg = readl(base + S5P_JPEG_CNTL_REG) & ~(S5P_JPEG_SYS_INT_EN);
++
++      if (value == 1)
++              writel(S5P_JPEG_SYS_INT_EN, base + S5P_JPEG_CNTL_REG);
++      else
++              writel(~S5P_JPEG_SYS_INT_EN, base + S5P_JPEG_CNTL_REG);
++}
++
++void jpeg_set_stream_buf_address(void __iomem *base, unsigned int address)
++{
++      writel(address, base + S5P_JPEG_OUT_MEM_BASE_REG);
++}
++
++void jpeg_set_stream_size(void __iomem *base,
++              unsigned int x_value, unsigned int y_value)
++{
++      writel(0x0, base + S5P_JPEG_IMG_SIZE_REG); /* clear */
++      writel(S5P_JPEG_X_SIZE(x_value) | S5P_JPEG_Y_SIZE(y_value),
++                      base + S5P_JPEG_IMG_SIZE_REG);
++}
++
++void jpeg_set_frame_buf_address(void __iomem *base,
++              unsigned int fmt, unsigned int address_1p,
++              unsigned int address_2p, unsigned int address_3p)
++{
++      switch (fmt) {
++      case V4L2_PIX_FMT_GREY:
++      case V4L2_PIX_FMT_RGB565:
++      case V4L2_PIX_FMT_RGB32:
++      case V4L2_PIX_FMT_YUYV:
++      case V4L2_PIX_FMT_YVYU:
++              writel(address_1p, base + S5P_JPEG_IMG_BA_PLANE_1_REG);
++              writel(0, base + S5P_JPEG_IMG_BA_PLANE_2_REG);
++              writel(0, base + S5P_JPEG_IMG_BA_PLANE_3_REG);
++              break;
++      case V4L2_PIX_FMT_NV24:
++      case V4L2_PIX_FMT_NV42:
++      case V4L2_PIX_FMT_NV16:
++      case V4L2_PIX_FMT_NV61:
++      case V4L2_PIX_FMT_NV12:
++      case V4L2_PIX_FMT_NV21:
++              writel(address_1p, base + S5P_JPEG_IMG_BA_PLANE_1_REG);
++              writel(address_2p, base + S5P_JPEG_IMG_BA_PLANE_2_REG);
++              writel(0, base + S5P_JPEG_IMG_BA_PLANE_3_REG);
++              break;
++      case V4L2_PIX_FMT_YUV420:
++      case V4L2_PIX_FMT_YVU420:
++              writel(address_1p, base + S5P_JPEG_IMG_BA_PLANE_1_REG);
++              writel(address_2p, base + S5P_JPEG_IMG_BA_PLANE_2_REG);
++              writel(address_3p, base + S5P_JPEG_IMG_BA_PLANE_3_REG);
++              break;
++      default:
++              break;
++      }
++}
++void jpeg_set_encode_tbl_select(void __iomem *base,
++              enum exynos_jpeg_img_quality_level level)
++{
++      unsigned int    reg;
++
++      switch (level) {
++      case QUALITY_LEVEL_1:
++              reg = S5P_JPEG_Q_TBL_COMP1_0 | S5P_JPEG_Q_TBL_COMP2_0 |
++                      S5P_JPEG_Q_TBL_COMP3_0 |
++                      S5P_JPEG_HUFF_TBL_COMP1_AC_0_DC_1 |
++                      S5P_JPEG_HUFF_TBL_COMP2_AC_0_DC_0 |
++                      S5P_JPEG_HUFF_TBL_COMP3_AC_1_DC_1;
++              break;
++      case QUALITY_LEVEL_2:
++              reg = S5P_JPEG_Q_TBL_COMP1_1 | S5P_JPEG_Q_TBL_COMP2_1 |
++                      S5P_JPEG_Q_TBL_COMP3_1 |
++                      S5P_JPEG_HUFF_TBL_COMP1_AC_0_DC_1 |
++                      S5P_JPEG_HUFF_TBL_COMP2_AC_0_DC_0 |
++                      S5P_JPEG_HUFF_TBL_COMP3_AC_1_DC_1;
++              break;
++      case QUALITY_LEVEL_3:
++              reg = S5P_JPEG_Q_TBL_COMP1_2 | S5P_JPEG_Q_TBL_COMP2_2 |
++                      S5P_JPEG_Q_TBL_COMP3_2 |
++                      S5P_JPEG_HUFF_TBL_COMP1_AC_0_DC_1 |
++                      S5P_JPEG_HUFF_TBL_COMP2_AC_0_DC_0 |
++                      S5P_JPEG_HUFF_TBL_COMP3_AC_1_DC_1;
++              break;
++      case QUALITY_LEVEL_4:
++              reg = S5P_JPEG_Q_TBL_COMP1_3 | S5P_JPEG_Q_TBL_COMP2_3 |
++                      S5P_JPEG_Q_TBL_COMP3_3 |
++                      S5P_JPEG_HUFF_TBL_COMP1_AC_0_DC_1 |
++                      S5P_JPEG_HUFF_TBL_COMP2_AC_0_DC_0 |
++                      S5P_JPEG_HUFF_TBL_COMP3_AC_1_DC_1;
++              break;
++      default:
++              reg = S5P_JPEG_Q_TBL_COMP1_0 | S5P_JPEG_Q_TBL_COMP2_0 |
++                      S5P_JPEG_Q_TBL_COMP3_1 |
++                      S5P_JPEG_HUFF_TBL_COMP1_AC_0_DC_1 |
++                      S5P_JPEG_HUFF_TBL_COMP2_AC_0_DC_0 |
++                      S5P_JPEG_HUFF_TBL_COMP3_AC_1_DC_1;
++              break;
++      }
++      writel(reg, base + S5P_JPEG_TBL_SEL_REG);
++}
++
++void jpeg_set_encode_hoff_cnt(void __iomem *base, unsigned int fmt)
++{
++      if (fmt == V4L2_PIX_FMT_GREY)
++              writel(0xd2, base + S5P_JPEG_HUFF_CNT_REG);
++      else
++              writel(0x1a2, base + S5P_JPEG_HUFF_CNT_REG);
++}
++
++unsigned int jpeg_get_stream_size(void __iomem *base)
++{
++      unsigned int size;
++
++      size = readl(base + S5P_JPEG_BITSTREAM_SIZE_REG);
++      return size;
++}
++
++void jpeg_set_dec_bitstream_size(void __iomem *base, unsigned int size)
++{
++      writel(size, base + S5P_JPEG_BITSTREAM_SIZE_REG);
++}
++
++void jpeg_get_frame_size(void __iomem *base,
++                      unsigned int *width, unsigned int *height)
++{
++      *width = (readl(base + S5P_JPEG_DECODE_XY_SIZE_REG) &
++                              S5P_JPEG_DECODED_SIZE_MASK);
++      *height = (readl(base + S5P_JPEG_DECODE_XY_SIZE_REG) >> 16) &
++                              S5P_JPEG_DECODED_SIZE_MASK;
++}
++
++unsigned int jpeg_get_frame_fmt(void __iomem *base)
++{
++      return readl(base + S5P_JPEG_DECODE_IMG_FMT_REG) &
++                              EXYNOS_JPEG_DECODED_IMG_FMT_MASK;
++}
+diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos.h b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos.h
+new file mode 100644
+index 0000000..7ec3def
+--- /dev/null
++++ b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos.h
+@@ -0,0 +1,43 @@
++/* Copyright (c) 2013 Samsung Electronics Co., Ltd.
++ *            http://www.samsung.com/
++ *
++ * Header file of the register interface for JPEG driver on Exynos4x12 and 5250.
++ *
++ * 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 __JPEG_REGS_H__
++#define __JPEG_REGS_H__
++
++#include "jpeg-core.h"
++
++void jpeg_sw_reset(void __iomem *base);
++void jpeg_set_enc_dec_mode(void __iomem *base, unsigned int mode);
++void jpeg_set_img_fmt(void __iomem *base, unsigned int img_fmt);
++void jpeg_set_enc_out_fmt(void __iomem *base, unsigned int out_fmt);
++void jpeg_set_enc_tbl(void __iomem *base);
++void jpeg_set_interrupt(void __iomem *base);
++unsigned int jpeg_get_int_status(void __iomem *base);
++void jpeg_set_huf_table_enable(void __iomem *base, int value);
++void jpeg_set_dec_scaling(void __iomem *base,
++              enum exynos_jpeg_scale_value x_value,
++              enum exynos_jpeg_scale_value y_value);
++void jpeg_set_sys_int_enable(void __iomem *base, int value);
++void jpeg_set_stream_buf_address(void __iomem *base, unsigned int address);
++void jpeg_set_stream_size(void __iomem *base,
++              unsigned int x_value, unsigned int y_value);
++void jpeg_set_frame_buf_address(void __iomem *base,
++              unsigned int fmt, unsigned int address,
++              unsigned int address_2p, unsigned int address_3p);
++void jpeg_set_encode_tbl_select(void __iomem *base,
++              enum exynos_jpeg_img_quality_level level);
++void jpeg_set_encode_hoff_cnt(void __iomem *base, unsigned int fmt);
++void jpeg_set_dec_bitstream_size(void __iomem *base, unsigned int size);
++unsigned int jpeg_get_stream_size(void __iomem *base);
++void jpeg_get_frame_size(void __iomem *base,
++                      unsigned int *width, unsigned int *height);
++unsigned int jpeg_get_frame_fmt(void __iomem *base);
++
++#endif /* __JPEG_REGS_H__ */
+diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.h b/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.h
+new file mode 100644
+index 0000000..4ec5266
+--- /dev/null
++++ b/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.h
+@@ -0,0 +1,354 @@
++/* linux/drivers/media/platform/s5p-jpeg/jpeg-hw.h
++ *
++ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
++ *            http://www.samsung.com
++ *
++ * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.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 JPEG_HW_H_
++#define JPEG_HW_H_
++
++#include <linux/io.h>
++#include <linux/videodev2.h>
++
++#include "jpeg-regs.h"
++
++#define S5P_JPEG_MIN_WIDTH            32
++#define S5P_JPEG_MIN_HEIGHT           32
++#define S5P_JPEG_MAX_WIDTH            8192
++#define S5P_JPEG_MAX_HEIGHT           8192
++#define S5P_JPEG_RAW_IN_565           0
++#define S5P_JPEG_RAW_IN_422           1
++#define S5P_JPEG_RAW_OUT_422          0
++#define S5P_JPEG_RAW_OUT_420          1
++
++static inline void jpeg_reset(void __iomem *regs)
++{
++      unsigned long reg;
++
++      writel(1, regs + S5P_JPG_SW_RESET);
++      reg = readl(regs + S5P_JPG_SW_RESET);
++      /* no other way but polling for when JPEG IP becomes operational */
++      while (reg != 0) {
++              cpu_relax();
++              reg = readl(regs + S5P_JPG_SW_RESET);
++      }
++}
++
++static inline void jpeg_poweron(void __iomem *regs)
++{
++      writel(S5P_POWER_ON, regs + S5P_JPGCLKCON);
++}
++
++static inline void jpeg_input_raw_mode(void __iomem *regs, unsigned long mode)
++{
++      unsigned long reg, m;
++
++      m = S5P_MOD_SEL_565;
++      if (mode == S5P_JPEG_RAW_IN_565)
++              m = S5P_MOD_SEL_565;
++      else if (mode == S5P_JPEG_RAW_IN_422)
++              m = S5P_MOD_SEL_422;
++
++      reg = readl(regs + S5P_JPGCMOD);
++      reg &= ~S5P_MOD_SEL_MASK;
++      reg |= m;
++      writel(reg, regs + S5P_JPGCMOD);
++}
++
++static inline void jpeg_input_raw_y16(void __iomem *regs, bool y16)
++{
++      unsigned long reg;
++
++      reg = readl(regs + S5P_JPGCMOD);
++      if (y16)
++              reg |= S5P_MODE_Y16;
++      else
++              reg &= ~S5P_MODE_Y16_MASK;
++      writel(reg, regs + S5P_JPGCMOD);
++}
++
++static inline void jpeg_proc_mode(void __iomem *regs, unsigned long mode)
++{
++      unsigned long reg, m;
++
++      m = S5P_PROC_MODE_DECOMPR;
++      if (mode == SJPEG_ENCODE)
++              m = S5P_PROC_MODE_COMPR;
++      else
++              m = S5P_PROC_MODE_DECOMPR;
++      reg = readl(regs + S5P_JPGMOD);
++      reg &= ~S5P_PROC_MODE_MASK;
++      reg |= m;
++      writel(reg, regs + S5P_JPGMOD);
++}
++
++static inline void jpeg_subsampling_mode(void __iomem *regs, unsigned int mode)
++{
++      unsigned long reg, m;
++
++      if (mode == V4L2_JPEG_CHROMA_SUBSAMPLING_420)
++              m = S5P_SUBSAMPLING_MODE_420;
++      else
++              m = S5P_SUBSAMPLING_MODE_422;
++
++      reg = readl(regs + S5P_JPGMOD);
++      reg &= ~S5P_SUBSAMPLING_MODE_MASK;
++      reg |= m;
++      writel(reg, regs + S5P_JPGMOD);
++}
++
++static inline unsigned int jpeg_get_subsampling_mode(void __iomem *regs)
++{
++      return readl(regs + S5P_JPGMOD) & S5P_SUBSAMPLING_MODE_MASK;
++}
++
++static inline void jpeg_dri(void __iomem *regs, unsigned int dri)
++{
++      unsigned long reg;
++
++      reg = readl(regs + S5P_JPGDRI_U);
++      reg &= ~0xff;
++      reg |= (dri >> 8) & 0xff;
++      writel(reg, regs + S5P_JPGDRI_U);
++
++      reg = readl(regs + S5P_JPGDRI_L);
++      reg &= ~0xff;
++      reg |= dri & 0xff;
++      writel(reg, regs + S5P_JPGDRI_L);
++}
++
++static inline void jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n)
++{
++      unsigned long reg;
++
++      reg = readl(regs + S5P_JPG_QTBL);
++      reg &= ~S5P_QT_NUMt_MASK(t);
++      reg |= (n << S5P_QT_NUMt_SHIFT(t)) & S5P_QT_NUMt_MASK(t);
++      writel(reg, regs + S5P_JPG_QTBL);
++}
++
++static inline void jpeg_htbl_ac(void __iomem *regs, unsigned int t)
++{
++      unsigned long reg;
++
++      reg = readl(regs + S5P_JPG_HTBL);
++      reg &= ~S5P_HT_NUMt_AC_MASK(t);
++      /* this driver uses table 0 for all color components */
++      reg |= (0 << S5P_HT_NUMt_AC_SHIFT(t)) & S5P_HT_NUMt_AC_MASK(t);
++      writel(reg, regs + S5P_JPG_HTBL);
++}
++
++static inline void jpeg_htbl_dc(void __iomem *regs, unsigned int t)
++{
++      unsigned long reg;
++
++      reg = readl(regs + S5P_JPG_HTBL);
++      reg &= ~S5P_HT_NUMt_DC_MASK(t);
++      /* this driver uses table 0 for all color components */
++      reg |= (0 << S5P_HT_NUMt_DC_SHIFT(t)) & S5P_HT_NUMt_DC_MASK(t);
++      writel(reg, regs + S5P_JPG_HTBL);
++}
++
++static inline void jpeg_y(void __iomem *regs, unsigned int y)
++{
++      unsigned long reg;
++
++      reg = readl(regs + S5P_JPGY_U);
++      reg &= ~0xff;
++      reg |= (y >> 8) & 0xff;
++      writel(reg, regs + S5P_JPGY_U);
++
++      reg = readl(regs + S5P_JPGY_L);
++      reg &= ~0xff;
++      reg |= y & 0xff;
++      writel(reg, regs + S5P_JPGY_L);
++}
++
++static inline void jpeg_x(void __iomem *regs, unsigned int x)
++{
++      unsigned long reg;
++
++      reg = readl(regs + S5P_JPGX_U);
++      reg &= ~0xff;
++      reg |= (x >> 8) & 0xff;
++      writel(reg, regs + S5P_JPGX_U);
++
++      reg = readl(regs + S5P_JPGX_L);
++      reg &= ~0xff;
++      reg |= x & 0xff;
++      writel(reg, regs + S5P_JPGX_L);
++}
++
++static inline void jpeg_rst_int_enable(void __iomem *regs, bool enable)
++{
++      unsigned long reg;
++
++      reg = readl(regs + S5P_JPGINTSE);
++      reg &= ~S5P_RSTm_INT_EN_MASK;
++      if (enable)
++              reg |= S5P_RSTm_INT_EN;
++      writel(reg, regs + S5P_JPGINTSE);
++}
++
++static inline void jpeg_data_num_int_enable(void __iomem *regs, bool enable)
++{
++      unsigned long reg;
++
++      reg = readl(regs + S5P_JPGINTSE);
++      reg &= ~S5P_DATA_NUM_INT_EN_MASK;
++      if (enable)
++              reg |= S5P_DATA_NUM_INT_EN;
++      writel(reg, regs + S5P_JPGINTSE);
++}
++
++static inline void jpeg_final_mcu_num_int_enable(void __iomem *regs, bool enbl)
++{
++      unsigned long reg;
++
++      reg = readl(regs + S5P_JPGINTSE);
++      reg &= ~S5P_FINAL_MCU_NUM_INT_EN_MASK;
++      if (enbl)
++              reg |= S5P_FINAL_MCU_NUM_INT_EN;
++      writel(reg, regs + S5P_JPGINTSE);
++}
++
++static inline void jpeg_timer_enable(void __iomem *regs, unsigned long val)
++{
++      unsigned long reg;
++
++      reg = readl(regs + S5P_JPG_TIMER_SE);
++      reg |= S5P_TIMER_INT_EN;
++      reg &= ~S5P_TIMER_INIT_MASK;
++      reg |= val & S5P_TIMER_INIT_MASK;
++      writel(reg, regs + S5P_JPG_TIMER_SE);
++}
++
++static inline void jpeg_timer_disable(void __iomem *regs)
++{
++      unsigned long reg;
++
++      reg = readl(regs + S5P_JPG_TIMER_SE);
++      reg &= ~S5P_TIMER_INT_EN_MASK;
++      writel(reg, regs + S5P_JPG_TIMER_SE);
++}
++
++static inline int jpeg_timer_stat(void __iomem *regs)
++{
++      return (int)((readl(regs + S5P_JPG_TIMER_ST) & S5P_TIMER_INT_STAT_MASK)
++                   >> S5P_TIMER_INT_STAT_SHIFT);
++}
++
++static inline void jpeg_clear_timer_stat(void __iomem *regs)
++{
++      unsigned long reg;
++
++      reg = readl(regs + S5P_JPG_TIMER_SE);
++      reg &= ~S5P_TIMER_INT_STAT_MASK;
++      writel(reg, regs + S5P_JPG_TIMER_SE);
++}
++
++static inline void jpeg_enc_stream_int(void __iomem *regs, unsigned long size)
++{
++      unsigned long reg;
++
++      reg = readl(regs + S5P_JPG_ENC_STREAM_INTSE);
++      reg &= ~S5P_ENC_STREAM_BOUND_MASK;
++      reg |= S5P_ENC_STREAM_INT_EN;
++      reg |= size & S5P_ENC_STREAM_BOUND_MASK;
++      writel(reg, regs + S5P_JPG_ENC_STREAM_INTSE);
++}
++
++static inline int jpeg_enc_stream_stat(void __iomem *regs)
++{
++      return (int)(readl(regs + S5P_JPG_ENC_STREAM_INTST) &
++                   S5P_ENC_STREAM_INT_STAT_MASK);
++}
++
++static inline void jpeg_clear_enc_stream_stat(void __iomem *regs)
++{
++      unsigned long reg;
++
++      reg = readl(regs + S5P_JPG_ENC_STREAM_INTSE);
++      reg &= ~S5P_ENC_STREAM_INT_MASK;
++      writel(reg, regs + S5P_JPG_ENC_STREAM_INTSE);
++}
++
++static inline void jpeg_outform_raw(void __iomem *regs, unsigned long format)
++{
++      unsigned long reg, f;
++
++      f = S5P_DEC_OUT_FORMAT_422;
++      if (format == S5P_JPEG_RAW_OUT_422)
++              f = S5P_DEC_OUT_FORMAT_422;
++      else if (format == S5P_JPEG_RAW_OUT_420)
++              f = S5P_DEC_OUT_FORMAT_420;
++      reg = readl(regs + S5P_JPG_OUTFORM);
++      reg &= ~S5P_DEC_OUT_FORMAT_MASK;
++      reg |= f;
++      writel(reg, regs + S5P_JPG_OUTFORM);
++}
++
++static inline void jpeg_jpgadr(void __iomem *regs, unsigned long addr)
++{
++      writel(addr, regs + S5P_JPG_JPGADR);
++}
++
++static inline void jpeg_imgadr(void __iomem *regs, unsigned long addr)
++{
++      writel(addr, regs + S5P_JPG_IMGADR);
++}
++
++static inline void jpeg_coef(void __iomem *regs, unsigned int i,
++                           unsigned int j, unsigned int coef)
++{
++      unsigned long reg;
++
++      reg = readl(regs + S5P_JPG_COEF(i));
++      reg &= ~S5P_COEFn_MASK(j);
++      reg |= (coef << S5P_COEFn_SHIFT(j)) & S5P_COEFn_MASK(j);
++      writel(reg, regs + S5P_JPG_COEF(i));
++}
++
++static inline void jpeg_start(void __iomem *regs)
++{
++      writel(1, regs + S5P_JSTART);
++}
++
++static inline int jpeg_result_stat_ok(void __iomem *regs)
++{
++      return (int)((readl(regs + S5P_JPGINTST) & S5P_RESULT_STAT_MASK)
++                   >> S5P_RESULT_STAT_SHIFT);
++}
++
++static inline int jpeg_stream_stat_ok(void __iomem *regs)
++{
++      return !(int)((readl(regs + S5P_JPGINTST) & S5P_STREAM_STAT_MASK)
++                    >> S5P_STREAM_STAT_SHIFT);
++}
++
++static inline void jpeg_clear_int(void __iomem *regs)
++{
++      unsigned long reg;
++
++      reg = readl(regs + S5P_JPGINTST);
++      writel(S5P_INT_RELEASE, regs + S5P_JPGCOM);
++      reg = readl(regs + S5P_JPGOPR);
++}
++
++static inline unsigned int jpeg_compressed_size(void __iomem *regs)
++{
++      unsigned long jpeg_size = 0;
++
++      jpeg_size |= (readl(regs + S5P_JPGCNT_U) & 0xff) << 16;
++      jpeg_size |= (readl(regs + S5P_JPGCNT_M) & 0xff) << 8;
++      jpeg_size |= (readl(regs + S5P_JPGCNT_L) & 0xff);
++
++      return (unsigned int)jpeg_size;
++}
++
++#endif /* JPEG_HW_H_ */
+diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw.h b/drivers/media/platform/s5p-jpeg/jpeg-hw.h
+deleted file mode 100644
+index b47e887..0000000
+--- a/drivers/media/platform/s5p-jpeg/jpeg-hw.h
++++ /dev/null
+@@ -1,357 +0,0 @@
+-/* linux/drivers/media/platform/s5p-jpeg/jpeg-hw.h
+- *
+- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+- *            http://www.samsung.com
+- *
+- * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.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 JPEG_HW_H_
+-#define JPEG_HW_H_
+-
+-#include <linux/io.h>
+-#include <linux/videodev2.h>
+-
+-#include "jpeg-hw.h"
+-#include "jpeg-regs.h"
+-
+-#define S5P_JPEG_MIN_WIDTH            32
+-#define S5P_JPEG_MIN_HEIGHT           32
+-#define S5P_JPEG_MAX_WIDTH            8192
+-#define S5P_JPEG_MAX_HEIGHT           8192
+-#define S5P_JPEG_ENCODE                       0
+-#define S5P_JPEG_DECODE                       1
+-#define S5P_JPEG_RAW_IN_565           0
+-#define S5P_JPEG_RAW_IN_422           1
+-#define S5P_JPEG_RAW_OUT_422          0
+-#define S5P_JPEG_RAW_OUT_420          1
+-
+-static inline void jpeg_reset(void __iomem *regs)
+-{
+-      unsigned long reg;
+-
+-      writel(1, regs + S5P_JPG_SW_RESET);
+-      reg = readl(regs + S5P_JPG_SW_RESET);
+-      /* no other way but polling for when JPEG IP becomes operational */
+-      while (reg != 0) {
+-              cpu_relax();
+-              reg = readl(regs + S5P_JPG_SW_RESET);
+-      }
+-}
+-
+-static inline void jpeg_poweron(void __iomem *regs)
+-{
+-      writel(S5P_POWER_ON, regs + S5P_JPGCLKCON);
+-}
+-
+-static inline void jpeg_input_raw_mode(void __iomem *regs, unsigned long mode)
+-{
+-      unsigned long reg, m;
+-
+-      m = S5P_MOD_SEL_565;
+-      if (mode == S5P_JPEG_RAW_IN_565)
+-              m = S5P_MOD_SEL_565;
+-      else if (mode == S5P_JPEG_RAW_IN_422)
+-              m = S5P_MOD_SEL_422;
+-
+-      reg = readl(regs + S5P_JPGCMOD);
+-      reg &= ~S5P_MOD_SEL_MASK;
+-      reg |= m;
+-      writel(reg, regs + S5P_JPGCMOD);
+-}
+-
+-static inline void jpeg_input_raw_y16(void __iomem *regs, bool y16)
+-{
+-      unsigned long reg;
+-
+-      reg = readl(regs + S5P_JPGCMOD);
+-      if (y16)
+-              reg |= S5P_MODE_Y16;
+-      else
+-              reg &= ~S5P_MODE_Y16_MASK;
+-      writel(reg, regs + S5P_JPGCMOD);
+-}
+-
+-static inline void jpeg_proc_mode(void __iomem *regs, unsigned long mode)
+-{
+-      unsigned long reg, m;
+-
+-      m = S5P_PROC_MODE_DECOMPR;
+-      if (mode == S5P_JPEG_ENCODE)
+-              m = S5P_PROC_MODE_COMPR;
+-      else
+-              m = S5P_PROC_MODE_DECOMPR;
+-      reg = readl(regs + S5P_JPGMOD);
+-      reg &= ~S5P_PROC_MODE_MASK;
+-      reg |= m;
+-      writel(reg, regs + S5P_JPGMOD);
+-}
+-
+-static inline void jpeg_subsampling_mode(void __iomem *regs, unsigned int mode)
+-{
+-      unsigned long reg, m;
+-
+-      if (mode == V4L2_JPEG_CHROMA_SUBSAMPLING_420)
+-              m = S5P_SUBSAMPLING_MODE_420;
+-      else
+-              m = S5P_SUBSAMPLING_MODE_422;
+-
+-      reg = readl(regs + S5P_JPGMOD);
+-      reg &= ~S5P_SUBSAMPLING_MODE_MASK;
+-      reg |= m;
+-      writel(reg, regs + S5P_JPGMOD);
+-}
+-
+-static inline unsigned int jpeg_get_subsampling_mode(void __iomem *regs)
+-{
+-      return readl(regs + S5P_JPGMOD) & S5P_SUBSAMPLING_MODE_MASK;
+-}
+-
+-static inline void jpeg_dri(void __iomem *regs, unsigned int dri)
+-{
+-      unsigned long reg;
+-
+-      reg = readl(regs + S5P_JPGDRI_U);
+-      reg &= ~0xff;
+-      reg |= (dri >> 8) & 0xff;
+-      writel(reg, regs + S5P_JPGDRI_U);
+-
+-      reg = readl(regs + S5P_JPGDRI_L);
+-      reg &= ~0xff;
+-      reg |= dri & 0xff;
+-      writel(reg, regs + S5P_JPGDRI_L);
+-}
+-
+-static inline void jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n)
+-{
+-      unsigned long reg;
+-
+-      reg = readl(regs + S5P_JPG_QTBL);
+-      reg &= ~S5P_QT_NUMt_MASK(t);
+-      reg |= (n << S5P_QT_NUMt_SHIFT(t)) & S5P_QT_NUMt_MASK(t);
+-      writel(reg, regs + S5P_JPG_QTBL);
+-}
+-
+-static inline void jpeg_htbl_ac(void __iomem *regs, unsigned int t)
+-{
+-      unsigned long reg;
+-
+-      reg = readl(regs + S5P_JPG_HTBL);
+-      reg &= ~S5P_HT_NUMt_AC_MASK(t);
+-      /* this driver uses table 0 for all color components */
+-      reg |= (0 << S5P_HT_NUMt_AC_SHIFT(t)) & S5P_HT_NUMt_AC_MASK(t);
+-      writel(reg, regs + S5P_JPG_HTBL);
+-}
+-
+-static inline void jpeg_htbl_dc(void __iomem *regs, unsigned int t)
+-{
+-      unsigned long reg;
+-
+-      reg = readl(regs + S5P_JPG_HTBL);
+-      reg &= ~S5P_HT_NUMt_DC_MASK(t);
+-      /* this driver uses table 0 for all color components */
+-      reg |= (0 << S5P_HT_NUMt_DC_SHIFT(t)) & S5P_HT_NUMt_DC_MASK(t);
+-      writel(reg, regs + S5P_JPG_HTBL);
+-}
+-
+-static inline void jpeg_y(void __iomem *regs, unsigned int y)
+-{
+-      unsigned long reg;
+-
+-      reg = readl(regs + S5P_JPGY_U);
+-      reg &= ~0xff;
+-      reg |= (y >> 8) & 0xff;
+-      writel(reg, regs + S5P_JPGY_U);
+-
+-      reg = readl(regs + S5P_JPGY_L);
+-      reg &= ~0xff;
+-      reg |= y & 0xff;
+-      writel(reg, regs + S5P_JPGY_L);
+-}
+-
+-static inline void jpeg_x(void __iomem *regs, unsigned int x)
+-{
+-      unsigned long reg;
+-
+-      reg = readl(regs + S5P_JPGX_U);
+-      reg &= ~0xff;
+-      reg |= (x >> 8) & 0xff;
+-      writel(reg, regs + S5P_JPGX_U);
+-
+-      reg = readl(regs + S5P_JPGX_L);
+-      reg &= ~0xff;
+-      reg |= x & 0xff;
+-      writel(reg, regs + S5P_JPGX_L);
+-}
+-
+-static inline void jpeg_rst_int_enable(void __iomem *regs, bool enable)
+-{
+-      unsigned long reg;
+-
+-      reg = readl(regs + S5P_JPGINTSE);
+-      reg &= ~S5P_RSTm_INT_EN_MASK;
+-      if (enable)
+-              reg |= S5P_RSTm_INT_EN;
+-      writel(reg, regs + S5P_JPGINTSE);
+-}
+-
+-static inline void jpeg_data_num_int_enable(void __iomem *regs, bool enable)
+-{
+-      unsigned long reg;
+-
+-      reg = readl(regs + S5P_JPGINTSE);
+-      reg &= ~S5P_DATA_NUM_INT_EN_MASK;
+-      if (enable)
+-              reg |= S5P_DATA_NUM_INT_EN;
+-      writel(reg, regs + S5P_JPGINTSE);
+-}
+-
+-static inline void jpeg_final_mcu_num_int_enable(void __iomem *regs, bool enbl)
+-{
+-      unsigned long reg;
+-
+-      reg = readl(regs + S5P_JPGINTSE);
+-      reg &= ~S5P_FINAL_MCU_NUM_INT_EN_MASK;
+-      if (enbl)
+-              reg |= S5P_FINAL_MCU_NUM_INT_EN;
+-      writel(reg, regs + S5P_JPGINTSE);
+-}
+-
+-static inline void jpeg_timer_enable(void __iomem *regs, unsigned long val)
+-{
+-      unsigned long reg;
+-
+-      reg = readl(regs + S5P_JPG_TIMER_SE);
+-      reg |= S5P_TIMER_INT_EN;
+-      reg &= ~S5P_TIMER_INIT_MASK;
+-      reg |= val & S5P_TIMER_INIT_MASK;
+-      writel(reg, regs + S5P_JPG_TIMER_SE);
+-}
+-
+-static inline void jpeg_timer_disable(void __iomem *regs)
+-{
+-      unsigned long reg;
+-
+-      reg = readl(regs + S5P_JPG_TIMER_SE);
+-      reg &= ~S5P_TIMER_INT_EN_MASK;
+-      writel(reg, regs + S5P_JPG_TIMER_SE);
+-}
+-
+-static inline int jpeg_timer_stat(void __iomem *regs)
+-{
+-      return (int)((readl(regs + S5P_JPG_TIMER_ST) & S5P_TIMER_INT_STAT_MASK)
+-                   >> S5P_TIMER_INT_STAT_SHIFT);
+-}
+-
+-static inline void jpeg_clear_timer_stat(void __iomem *regs)
+-{
+-      unsigned long reg;
+-
+-      reg = readl(regs + S5P_JPG_TIMER_SE);
+-      reg &= ~S5P_TIMER_INT_STAT_MASK;
+-      writel(reg, regs + S5P_JPG_TIMER_SE);
+-}
+-
+-static inline void jpeg_enc_stream_int(void __iomem *regs, unsigned long size)
+-{
+-      unsigned long reg;
+-
+-      reg = readl(regs + S5P_JPG_ENC_STREAM_INTSE);
+-      reg &= ~S5P_ENC_STREAM_BOUND_MASK;
+-      reg |= S5P_ENC_STREAM_INT_EN;
+-      reg |= size & S5P_ENC_STREAM_BOUND_MASK;
+-      writel(reg, regs + S5P_JPG_ENC_STREAM_INTSE);
+-}
+-
+-static inline int jpeg_enc_stream_stat(void __iomem *regs)
+-{
+-      return (int)(readl(regs + S5P_JPG_ENC_STREAM_INTST) &
+-                   S5P_ENC_STREAM_INT_STAT_MASK);
+-}
+-
+-static inline void jpeg_clear_enc_stream_stat(void __iomem *regs)
+-{
+-      unsigned long reg;
+-
+-      reg = readl(regs + S5P_JPG_ENC_STREAM_INTSE);
+-      reg &= ~S5P_ENC_STREAM_INT_MASK;
+-      writel(reg, regs + S5P_JPG_ENC_STREAM_INTSE);
+-}
+-
+-static inline void jpeg_outform_raw(void __iomem *regs, unsigned long format)
+-{
+-      unsigned long reg, f;
+-
+-      f = S5P_DEC_OUT_FORMAT_422;
+-      if (format == S5P_JPEG_RAW_OUT_422)
+-              f = S5P_DEC_OUT_FORMAT_422;
+-      else if (format == S5P_JPEG_RAW_OUT_420)
+-              f = S5P_DEC_OUT_FORMAT_420;
+-      reg = readl(regs + S5P_JPG_OUTFORM);
+-      reg &= ~S5P_DEC_OUT_FORMAT_MASK;
+-      reg |= f;
+-      writel(reg, regs + S5P_JPG_OUTFORM);
+-}
+-
+-static inline void jpeg_jpgadr(void __iomem *regs, unsigned long addr)
+-{
+-      writel(addr, regs + S5P_JPG_JPGADR);
+-}
+-
+-static inline void jpeg_imgadr(void __iomem *regs, unsigned long addr)
+-{
+-      writel(addr, regs + S5P_JPG_IMGADR);
+-}
+-
+-static inline void jpeg_coef(void __iomem *regs, unsigned int i,
+-                           unsigned int j, unsigned int coef)
+-{
+-      unsigned long reg;
+-
+-      reg = readl(regs + S5P_JPG_COEF(i));
+-      reg &= ~S5P_COEFn_MASK(j);
+-      reg |= (coef << S5P_COEFn_SHIFT(j)) & S5P_COEFn_MASK(j);
+-      writel(reg, regs + S5P_JPG_COEF(i));
+-}
+-
+-static inline void jpeg_start(void __iomem *regs)
+-{
+-      writel(1, regs + S5P_JSTART);
+-}
+-
+-static inline int jpeg_result_stat_ok(void __iomem *regs)
+-{
+-      return (int)((readl(regs + S5P_JPGINTST) & S5P_RESULT_STAT_MASK)
+-                   >> S5P_RESULT_STAT_SHIFT);
+-}
+-
+-static inline int jpeg_stream_stat_ok(void __iomem *regs)
+-{
+-      return !(int)((readl(regs + S5P_JPGINTST) & S5P_STREAM_STAT_MASK)
+-                    >> S5P_STREAM_STAT_SHIFT);
+-}
+-
+-static inline void jpeg_clear_int(void __iomem *regs)
+-{
+-      unsigned long reg;
+-
+-      reg = readl(regs + S5P_JPGINTST);
+-      writel(S5P_INT_RELEASE, regs + S5P_JPGCOM);
+-      reg = readl(regs + S5P_JPGOPR);
+-}
+-
+-static inline unsigned int jpeg_compressed_size(void __iomem *regs)
+-{
+-      unsigned long jpeg_size = 0;
+-
+-      jpeg_size |= (readl(regs + S5P_JPGCNT_U) & 0xff) << 16;
+-      jpeg_size |= (readl(regs + S5P_JPGCNT_M) & 0xff) << 8;
+-      jpeg_size |= (readl(regs + S5P_JPGCNT_L) & 0xff);
+-
+-      return (unsigned int)jpeg_size;
+-}
+-
+-#endif /* JPEG_HW_H_ */
+diff --git a/drivers/media/platform/s5p-jpeg/jpeg-regs.h b/drivers/media/platform/s5p-jpeg/jpeg-regs.h
+index 38e5081..bd2224e 100644
+--- a/drivers/media/platform/s5p-jpeg/jpeg-regs.h
++++ b/drivers/media/platform/s5p-jpeg/jpeg-regs.h
+@@ -15,6 +15,8 @@
+ #ifndef JPEG_REGS_H_
+ #define JPEG_REGS_H_
++/* Register and bit definitions for S5PC210 */
++
+ /* JPEG mode register */
+ #define S5P_JPGMOD                    0x00
+ #define S5P_PROC_MODE_MASK            (0x1 << 3)
+@@ -166,5 +168,185 @@
+ /* JPEG AC Huffman table register */
+ #define S5P_JPG_HACTBLG(n)            (0x8c0 + (n) * 0x400)
++
++/* Register and bit definitions for Exynos 4x12 */
++
++/* JPEG Codec Control Registers */
++#define S5P_JPEG_CNTL_REG             0x00
++#define S5P_JPEG_INT_EN_REG           0x04
++/*#define S5P_JPEG_QTBL_REG           0x08*Reserved*/
++#define S5P_JPEG_INT_STATUS_REG               0x0c
++#define S5P_JPEG_OUT_MEM_BASE_REG     0x10
++#define S5P_JPEG_IMG_SIZE_REG         0x14
++#define S5P_JPEG_IMG_BA_PLANE_1_REG   0x18
++#define S5P_JPEG_IMG_SO_PLANE_1_REG   0x1c
++#define S5P_JPEG_IMG_PO_PLANE_1_REG   0x20
++#define S5P_JPEG_IMG_BA_PLANE_2_REG   0x24
++#define S5P_JPEG_IMG_SO_PLANE_2_REG   0x28
++#define S5P_JPEG_IMG_PO_PLANE_2_REG   0x2c
++#define S5P_JPEG_IMG_BA_PLANE_3_REG   0x30
++#define S5P_JPEG_IMG_SO_PLANE_3_REG   0x34
++#define S5P_JPEG_IMG_PO_PLANE_3_REG   0x38
++
++#define S5P_JPEG_TBL_SEL_REG          0x3c
++
++#define S5P_JPEG_IMG_FMT_REG          0x40
++
++#define S5P_JPEG_BITSTREAM_SIZE_REG   0x44
++#define S5P_JPEG_PADDING_REG          0x48
++#define S5P_JPEG_HUFF_CNT_REG         0x4c
++#define S5P_JPEG_FIFO_STATUS_REG      0x50
++#define S5P_JPEG_DECODE_XY_SIZE_REG   0x54
++#define S5P_JPEG_DECODE_IMG_FMT_REG   0x58
++
++#define S5P_JPEG_QUAN_TBL_ENTRY_REG   0x100
++#define S5P_JPEG_HUFF_TBL_ENTRY_REG   0x200
++
++
++/****************************************************************/
++/* Bit definition part                                                */
++/****************************************************************/
++
++/* JPEG CNTL Register bit */
++#define S5P_JPEG_ENC_DEC_MODE_MASK    (0xfffffffc << 0)
++#define S5P_JPEG_DEC_MODE             (1 << 0)
++#define S5P_JPEG_ENC_MODE             (1 << 1)
++#define S5P_JPEG_AUTO_RST_MARKER      (1 << 2)
++#define S5P_JPEG_RST_INTERVAL_SHIFT   3
++#define S5P_JPEG_RST_INTERVAL(x) (((x) & 0xffff) << S5P_JPEG_RST_INTERVAL_SHIFT)
++#define S5P_JPEG_HUF_TBL_EN           (1 << 19)
++#define S5P_JPEG_HOR_SCALING_SHIFT    20
++#define S5P_JPEG_HOR_SCALING_MASK     (3 << S5P_JPEG_HOR_SCALING_SHIFT)
++#define S5P_JPEG_HOR_SCALING(x)       (((x) & 0x3) << S5P_JPEG_HOR_SCALING_SHIFT)
++#define S5P_JPEG_VER_SCALING_SHIFT    22
++#define S5P_JPEG_VER_SCALING_MASK     (3 << S5P_JPEG_VER_SCALING_SHIFT)
++#define S5P_JPEG_VER_SCALING(x)       (((x) & 0x3) << S5P_JPEG_VER_SCALING_SHIFT)
++#define S5P_JPEG_PADDING              (1 << 27)
++#define S5P_JPEG_SYS_INT_EN           (1 << 28)
++#define S5P_JPEG_SOFT_RESET_HI                (1 << 29)
++
++/* JPEG INT Register bit */
++#define S5P_JPEG_INT_EN_MASK                  (0x1f << 0)
++#define S5P_JPEG_PROT_ERR_INT_EN              (1 << 0)
++#define S5P_JPEG_IMG_COMPLETION_INT_EN                (1 << 1)
++#define S5P_JPEG_DEC_INVALID_FORMAT_EN                (1 << 2)
++#define S5P_JPEG_MULTI_SCAN_ERROR_EN          (1 << 3)
++#define S5P_JPEG_FRAME_ERR_EN                 (1 << 4)
++#define S5P_JPEG_INT_EN_ALL                   (0x1f << 0)
++
++#define S5P_JPEG_MOD_REG_PROC_ENC             (0 << 3)
++#define S5P_JPEG_MOD_REG_PROC_DEC             (1 << 3)
++
++#define S5P_JPEG_MOD_REG_SUBSAMPLE_444                (0 << 0)
++#define S5P_JPEG_MOD_REG_SUBSAMPLE_422                (1 << 0)
++#define S5P_JPEG_MOD_REG_SUBSAMPLE_420                (2 << 0)
++#define S5P_JPEG_MOD_REG_SUBSAMPLE_GRAY               (3 << 0)
++
++
++/* JPEG IMAGE SIZE Register bit */
++#define S5P_JPEG_X_SIZE_SHIFT 0
++#define S5P_JPEG_X_SIZE_MASK  (0xffff << S5P_JPEG_X_SIZE_SHIFT)
++#define S5P_JPEG_X_SIZE(x)    (((x) & 0xffff) << S5P_JPEG_X_SIZE_SHIFT)
++#define S5P_JPEG_Y_SIZE_SHIFT 16
++#define S5P_JPEG_Y_SIZE_MASK  (0xffff << S5P_JPEG_Y_SIZE_SHIFT)
++#define S5P_JPEG_Y_SIZE(x)    (((x) & 0xffff) << S5P_JPEG_Y_SIZE_SHIFT)
++
++/* JPEG IMAGE FORMAT Register bit */
++#define S5P_JPEG_ENC_IN_FMT_MASK      0xffff0000
++#define S5P_JPEG_ENC_GRAY_IMG         (0 << 0)
++#define S5P_JPEG_ENC_RGB_IMG          (1 << 0)
++#define S5P_JPEG_ENC_YUV_444_IMG      (2 << 0)
++#define S5P_JPEG_ENC_YUV_422_IMG      (3 << 0)
++#define S5P_JPEG_ENC_YUV_440_IMG      (4 << 0)
++
++#define S5P_JPEG_DEC_GRAY_IMG         (0 << 0)
++#define S5P_JPEG_DEC_RGB_IMG          (1 << 0)
++#define S5P_JPEG_DEC_YUV_444_IMG      (2 << 0)
++#define S5P_JPEG_DEC_YUV_422_IMG      (3 << 0)
++#define S5P_JPEG_DEC_YUV_420_IMG      (4 << 0)
++
++#define S5P_JPEG_GRAY_IMG_IP_SHIFT    3
++#define S5P_JPEG_GRAY_IMG_IP_MASK     (7 << S5P_JPEG_GRAY_IMG_IP_SHIFT)
++#define S5P_JPEG_GRAY_IMG_IP          (4 << S5P_JPEG_GRAY_IMG_IP_SHIFT)
++
++#define S5P_JPEG_RGB_IP_SHIFT                 6
++#define S5P_JPEG_RGB_IP_MASK                  (7 << S5P_JPEG_RGB_IP_SHIFT)
++#define S5P_JPEG_RGB_IP_RGB_16BIT_IMG         (4 << S5P_JPEG_RGB_IP_SHIFT)
++#define S5P_JPEG_RGB_IP_RGB_32BIT_IMG         (5 << S5P_JPEG_RGB_IP_SHIFT)
++
++#define S5P_JPEG_YUV_444_IP_SHIFT             9
++#define S5P_JPEG_YUV_444_IP_MASK              (7 << S5P_JPEG_YUV_444_IP_SHIFT)
++#define S5P_JPEG_YUV_444_IP_YUV_444_2P_IMG    (4 << S5P_JPEG_YUV_444_IP_SHIFT)
++#define S5P_JPEG_YUV_444_IP_YUV_444_3P_IMG    (5 << S5P_JPEG_YUV_444_IP_SHIFT)
++
++#define S5P_JPEG_YUV_422_IP_SHIFT             12
++#define S5P_JPEG_YUV_422_IP_MASK              (7 << S5P_JPEG_YUV_422_IP_SHIFT)
++#define S5P_JPEG_YUV_422_IP_YUV_422_1P_IMG    (4 << S5P_JPEG_YUV_422_IP_SHIFT)
++#define S5P_JPEG_YUV_422_IP_YUV_422_2P_IMG    (5 << S5P_JPEG_YUV_422_IP_SHIFT)
++#define S5P_JPEG_YUV_422_IP_YUV_422_3P_IMG    (6 << S5P_JPEG_YUV_422_IP_SHIFT)
++
++#define S5P_JPEG_YUV_420_IP_SHIFT             15
++#define S5P_JPEG_YUV_420_IP_MASK              (7 << S5P_JPEG_YUV_420_IP_SHIFT)
++#define S5P_JPEG_YUV_420_IP_YUV_420_2P_IMG    (4 << S5P_JPEG_YUV_420_IP_SHIFT)
++#define S5P_JPEG_YUV_420_IP_YUV_420_3P_IMG    (5 << S5P_JPEG_YUV_420_IP_SHIFT)
++
++#define S5P_JPEG_ENC_FMT_SHIFT                        24
++#define S5P_JPEG_ENC_FMT_MASK                 (3 << S5P_JPEG_ENC_FMT_SHIFT)
++#define S5P_JPEG_ENC_FMT_GRAY                 (0 << S5P_JPEG_ENC_FMT_SHIFT)
++#define S5P_JPEG_ENC_FMT_YUV_444              (1 << S5P_JPEG_ENC_FMT_SHIFT)
++#define S5P_JPEG_ENC_FMT_YUV_422              (2 << S5P_JPEG_ENC_FMT_SHIFT)
++#define S5P_JPEG_ENC_FMT_YUV_420              (3 << S5P_JPEG_ENC_FMT_SHIFT)
++
++#define EXYNOS_JPEG_DECODED_IMG_FMT_MASK      0x03
++
++#define S5P_JPEG_SWAP_CHROMA_CrCb             (1 << 26)
++#define S5P_JPEG_SWAP_CHROMA_CbCr             (0 << 26)
++
++/* JPEG HUFF count Register bit */
++#define S5P_JPEG_HUFF_COUNT_MASK              0xffff
++
++/* JPEG Decoded_img_x_y_size Register bit */
++#define S5P_JPEG_DECODED_SIZE_MASK            0x0000ffff
++
++/* JPEG Decoded image format Register bit */
++#define S5P_JPEG_DECODED_IMG_FMT_MASK         0x3
++
++/* JPEG TBL SEL Register bit */
++#define S5P_JPEG_Q_TBL_COMP1_SHIFT        0
++#define S5P_JPEG_Q_TBL_COMP1_0                    (0 << S5P_JPEG_Q_TBL_COMP1_SHIFT)
++#define S5P_JPEG_Q_TBL_COMP1_1                    (1 << S5P_JPEG_Q_TBL_COMP1_SHIFT)
++#define S5P_JPEG_Q_TBL_COMP1_2                    (2 << S5P_JPEG_Q_TBL_COMP1_SHIFT)
++#define S5P_JPEG_Q_TBL_COMP1_3                    (3 << S5P_JPEG_Q_TBL_COMP1_SHIFT)
++
++#define S5P_JPEG_Q_TBL_COMP2_SHIFT        2
++#define S5P_JPEG_Q_TBL_COMP2_0                    (0 << S5P_JPEG_Q_TBL_COMP2_SHIFT)
++#define S5P_JPEG_Q_TBL_COMP2_1                    (1 << S5P_JPEG_Q_TBL_COMP2_SHIFT)
++#define S5P_JPEG_Q_TBL_COMP2_2                    (2 << S5P_JPEG_Q_TBL_COMP2_SHIFT)
++#define S5P_JPEG_Q_TBL_COMP2_3                    (3 << S5P_JPEG_Q_TBL_COMP2_SHIFT)
++
++#define S5P_JPEG_Q_TBL_COMP3_SHIFT          4
++#define S5P_JPEG_Q_TBL_COMP3_0                    (0 << S5P_JPEG_Q_TBL_COMP3_SHIFT)
++#define S5P_JPEG_Q_TBL_COMP3_1                    (1 << S5P_JPEG_Q_TBL_COMP2_SHIFT)
++#define S5P_JPEG_Q_TBL_COMP3_2                    (2 << S5P_JPEG_Q_TBL_COMP2_SHIFT)
++#define S5P_JPEG_Q_TBL_COMP3_3                    (3 << S5P_JPEG_Q_TBL_COMP2_SHIFT)
++
++#define S5P_JPEG_HUFF_TBL_COMP1_SHIFT     6
++#define S5P_JPEG_HUFF_TBL_COMP1_AC_0_DC_0   (0 << S5P_JPEG_HUFF_TBL_COMP1_SHIFT)
++#define S5P_JPEG_HUFF_TBL_COMP1_AC_0_DC_1   (1 << S5P_JPEG_HUFF_TBL_COMP1_SHIFT)
++#define S5P_JPEG_HUFF_TBL_COMP1_AC_1_DC_0   (2 << S5P_JPEG_HUFF_TBL_COMP1_SHIFT)
++#define S5P_JPEG_HUFF_TBL_COMP1_AC_1_DC_1   (3 << S5P_JPEG_HUFF_TBL_COMP1_SHIFT)
++
++#define S5P_JPEG_HUFF_TBL_COMP2_SHIFT     8
++#define S5P_JPEG_HUFF_TBL_COMP2_AC_0_DC_0   (0 << S5P_JPEG_HUFF_TBL_COMP2_SHIFT)
++#define S5P_JPEG_HUFF_TBL_COMP2_AC_0_DC_1   (1 << S5P_JPEG_HUFF_TBL_COMP2_SHIFT)
++#define S5P_JPEG_HUFF_TBL_COMP2_AC_1_DC_0   (2 << S5P_JPEG_HUFF_TBL_COMP2_SHIFT)
++#define S5P_JPEG_HUFF_TBL_COMP2_AC_1_DC_1   (3 << S5P_JPEG_HUFF_TBL_COMP2_SHIFT)
++
++#define S5P_JPEG_HUFF_TBL_COMP3_SHIFT     10
++#define S5P_JPEG_HUFF_TBL_COMP3_AC_0_DC_0   (0 << S5P_JPEG_HUFF_TBL_COMP3_SHIFT)
++#define S5P_JPEG_HUFF_TBL_COMP3_AC_0_DC_1   (1 << S5P_JPEG_HUFF_TBL_COMP3_SHIFT)
++#define S5P_JPEG_HUFF_TBL_COMP3_AC_1_DC_0   (2 << S5P_JPEG_HUFF_TBL_COMP3_SHIFT)
++#define S5P_JPEG_HUFF_TBL_COMP3_AC_1_DC_1   (3 << S5P_JPEG_HUFF_TBL_COMP3_SHIFT)
++
+ #endif /* JPEG_REGS_H_ */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0811-video-cdf-panel-support-lcd-class-operations-for-s6d.patch b/patches.tizen/0811-video-cdf-panel-support-lcd-class-operations-for-s6d.patch
new file mode 100644 (file)
index 0000000..a2df81f
--- /dev/null
@@ -0,0 +1,103 @@
+From d39c773d6367c5e176cf0fe460c1698f2f7b61b5 Mon Sep 17 00:00:00 2001
+From: Donghwa Lee <dh09.lee@samsung.com>
+Date: Fri, 27 Sep 2013 16:42:08 +0900
+Subject: [PATCH 0811/1302] video: cdf-panel: support lcd class operations for
+ s6d6aa1 panel
+
+Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/video/display/panel-s6d6aa1.c | 56 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 56 insertions(+)
+
+diff --git a/drivers/video/display/panel-s6d6aa1.c b/drivers/video/display/panel-s6d6aa1.c
+index d48f926..dd5285d 100644
+--- a/drivers/video/display/panel-s6d6aa1.c
++++ b/drivers/video/display/panel-s6d6aa1.c
+@@ -56,6 +56,7 @@ struct s6d6aa1 {
+       struct device *dev;
+       struct s6d6aa1_platform_data *pdata;
++      struct lcd_device *ld;
+       struct backlight_device *bd;
+       struct regulator_bulk_data supplies[2];
+@@ -415,6 +416,51 @@ static const struct backlight_ops s6d6aa1_backlight_ops = {
+       .update_status = s6d6aa1_set_brightness,
+ };
++static int s6d6aa1_set_power(struct lcd_device *ld, int power)
++{
++      struct s6d6aa1 *lcd = lcd_get_data(ld);
++      enum display_entity_state state;
++      int ret = 0;
++
++      switch (power) {
++      case FB_BLANK_UNBLANK:
++              state = DISPLAY_ENTITY_STATE_ON;
++              ret = display_entity_set_state(&lcd->entity, state);
++              if (ret)
++                      goto unlock;
++
++              s6d6aa1_brightness_ctrl(lcd, lcd->bd->props.brightness);
++              break;
++      case FB_BLANK_POWERDOWN:
++              s6d6aa1_brightness_ctrl(lcd, 0);
++
++              state = DISPLAY_ENTITY_STATE_OFF;
++              ret = display_entity_set_state(&lcd->entity, state);
++              if (ret)
++                      goto unlock;
++              break;
++      default:
++              state = DISPLAY_ENTITY_STATE_STANDBY;
++      }
++
++      lcd->power = power;
++
++unlock:
++      return ret;
++}
++
++static int s6d6aa1_get_power(struct lcd_device *ld)
++{
++      struct s6d6aa1 *lcd = lcd_get_data(ld);
++
++      return lcd->power;
++}
++
++static struct lcd_ops s6d6aa1_lcd_ops = {
++      .set_power = s6d6aa1_set_power,
++      .get_power = s6d6aa1_get_power,
++};
++
+ static int s6d6aa1_check_mtp(struct s6d6aa1 *lcd)
+ {
+       s6d6aa1_apply_level_1_key(lcd);
+@@ -679,6 +725,14 @@ static int s6d6aa1_probe(struct platform_device *pdev)
+               goto err_regulator_bulk_get;
+       }
++      lcd->ld = lcd_device_register("s6d6aa1", &pdev->dev, lcd,
++                      &s6d6aa1_lcd_ops);
++      if (IS_ERR(lcd->ld)) {
++              dev_err(lcd->dev, "failed to register lcd ops.\n");
++              ret = PTR_ERR(lcd->ld);
++              goto err_lcd_register;
++      }
++
+       lcd->bd = backlight_device_register("s6d6aa1", &pdev->dev, lcd,
+                       &s6d6aa1_backlight_ops, NULL);
+       if (IS_ERR(lcd->bd)) {
+@@ -712,6 +766,8 @@ static int s6d6aa1_probe(struct platform_device *pdev)
+ err_display_register:
+       backlight_device_unregister(lcd->bd);
+ err_backlight_register:
++      lcd_device_unregister(lcd->ld);
++err_lcd_register:
+       regulator_bulk_free(ARRAY_SIZE(lcd->supplies), lcd->supplies);
+ err_regulator_bulk_get:
+       kfree(lcd);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0812-arm-dst-add-SLP-Pegasus-Dual-board-for-testing-Exyno.patch b/patches.tizen/0812-arm-dst-add-SLP-Pegasus-Dual-board-for-testing-Exyno.patch
new file mode 100644 (file)
index 0000000..7bb28be
--- /dev/null
@@ -0,0 +1,383 @@
+From 1515fbc1fee8966b16998e54b3268bf44f1807f3 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Wed, 25 Sep 2013 14:21:57 +0200
+Subject: [PATCH 0812/1302] arm: dst: add SLP Pegasus Dual board (for testing
+ Exynos4212)
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/Makefile              |   1 +
+ arch/arm/boot/dts/exynos4212-slp_pd.dts | 348 ++++++++++++++++++++++++++++++++
+ 2 files changed, 349 insertions(+)
+ create mode 100644 arch/arm/boot/dts/exynos4212-slp_pd.dts
+
+diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
+index aa7eb34..ae51aa1 100644
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -50,6 +50,7 @@ dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \
+       exynos4210-smdkv310.dtb \
+       exynos4210-trats.dtb \
+       exynos4210-universal_c210.dtb \
++      exynos4212-slp_pd.dtb \
+       exynos4412-m0.dtb \
+       exynos4412-odroidx.dtb \
+       exynos4412-redwood.dtb \
+diff --git a/arch/arm/boot/dts/exynos4212-slp_pd.dts b/arch/arm/boot/dts/exynos4212-slp_pd.dts
+new file mode 100644
+index 0000000..4b2e573
+--- /dev/null
++++ b/arch/arm/boot/dts/exynos4212-slp_pd.dts
+@@ -0,0 +1,348 @@
++/*
++ * Samsung's Exynos4412 based SMDK board device tree source
++ *
++ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
++ *            http://www.samsung.com
++ *
++ * Device tree source file for Samsung's SMDK4412 board which is based on
++ * Samsung's Exynos4412 SoC.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++*/
++
++/dts-v1/;
++/include/ "exynos4212.dtsi"
++
++/ {
++      model = "Samsung PegasusD evaluation board based on Exynos4212";
++      compatible = "samsung,slp_pd", "samsung,exynos4412";
++
++      aliases {
++      };
++
++      memory {
++              reg = <0x40000000 0x40000000>;
++
++              reserved-memory {
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      contig_mem: region@71000000 {
++                              compatible = "linux,contiguous-memory-region";
++                              reg = <0x71000000 0x0c000000>;
++                              linux,default-contiguous-region;
++                      };
++              };
++      };
++
++      chosen {
++              bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc";
++      };
++
++      vemmc_reg: voltage-regulator@0 {
++              compatible = "regulator-fixed";
++              regulator-name = "VMEM_VDD_2.8V";
++              regulator-min-microvolt = <2800000>;
++              regulator-max-microvolt = <2800000>;
++              gpio = <&gpk0 2 0>;
++              enable-active-high;
++      };
++
++      mshc@12550000 {
++              num-slots = <1>;
++              supports-highspeed;
++              broken-cd;
++              non-removable;
++              fifo-depth = <0x80>;
++              card-detect-delay = <200>;
++              clocks = <&clock 351>, <&clock 132>;
++              clock-name = "biu", "ciu";
++              vmmc-supply = <&vemmc_reg>;
++              clock-frequency = <400000000>;
++              samsung,dw-mshc-ciu-div = <0>;
++              samsung,dw-mshc-sdr-timing = <2 3>;
++              samsung,dw-mshc-ddr-timing = <1 2>;
++              pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>;
++              pinctrl-names = "default";
++              status = "disabled";
++
++              slot@0 {
++                      reg = <0>;
++                      bus-width = <8>;
++              };
++      };
++
++      sdhci_emmc: sdhci@12510000 {
++              bus-width = <8>;
++              non-removable;
++              pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus8>;
++              pinctrl-names = "default";
++              vmmc-supply = <&vemmc_reg>;
++              status = "okay";
++      };
++
++      sdhci_sd: sdhci@12530000 {
++              bus-width = <4>;
++              cd-gpios = <&gpx3 4 0>;
++              cd-inverted;
++              interrupts = <0 75 0>;
++              pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4>;
++              pinctrl-names = "default";
++              status = "okay";
++      };
++
++      serial@13800000 {
++              status = "okay";
++      };
++
++      serial@13810000 {
++              status = "okay";
++      };
++
++      serial@13820000 {
++              status = "okay";
++      };
++
++      serial@13830000 {
++              status = "okay";
++      };
++
++      fixed-rate-clocks {
++              xxti {
++                      compatible = "samsung,clock-xxti";
++                      clock-frequency = <0>;
++              };
++
++              xusbxti {
++                      compatible = "samsung,clock-xusbxti";
++                      clock-frequency = <24000000>;
++              };
++      };
++
++      i2c@138B0000 {
++              samsung,i2c-sda-delay = <100>;
++              samsung,i2c-slave-addr = <0x10>;
++              samsung,i2c-max-bus-freq = <100000>;
++              pinctrl-0 = <&i2c5_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              max8997: max8997_pmic@66 {
++                      compatible = "maxim,max8997-pmic";
++                      interrupt-parent = <&gpx0>;
++                      interrupts = <7 0>;
++                      reg = <0x66>;
++
++                      max8997,pmic-buck1-uses-gpio-dvs;
++                      max8997,pmic-buck2-uses-gpio-dvs;
++                      max8997,pmic-buck5-uses-gpio-dvs;
++
++                      max8997,pmic-ignore-gpiodvs-side-effect;
++                      max8997,pmic-buck125-default-dvs-idx = <0>;
++
++                      max8997,pmic-buck125-dvs-gpios = <&gpj1 1 0>,
++                                                       <&gpj1 2 0>,
++                                                       <&gpl0 0 0>;
++
++                      max8997,pmic-buck1-dvs-voltage = <1100000>, <1100000>,
++                                                       <1100000>, <1100000>,
++                                                       <1100000>, <1100000>,
++                                                       <1100000>, <1100000>;
++
++                      max8997,pmic-buck2-dvs-voltage = <1100000>, <1100000>,
++                                                       <1100000>, <1100000>,
++                                                       <1100000>, <1100000>,
++                                                       <1100000>, <1100000>;
++
++                      max8997,pmic-buck5-dvs-voltage = <1100000>, <1100000>,
++                                                       <1100000>, <1100000>,
++                                                       <1100000>, <1100000>,
++                                                       <1100000>, <1100000>;
++
++                      regulators {
++
++                              ldo1_reg: LDO1 {
++                                      regulator-name = "VMIPI_1.8V_AP";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo2_reg: LDO2 {
++                                      regulator-name = "VALIVE_1.0A_AP";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo3_reg: LDO3 {
++                                      regulator-name = "VMPLL_1.0V_AP";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo4_reg: LDO4 {
++                                      regulator-name = "VABB02_1.8V_AP";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo5_reg: LDO5 {
++                                      regulator-name = "VABB1_1.8V_AP";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo6_reg: LDO6 {
++                                      regulator-name = "VCC_1.8V_AP";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo7_reg: LDO7 {
++                                      regulator-name = "CAM_ISP_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo8_reg: LDO8 {
++                                      regulator-name = "VUOTG_3.0V_AP";
++                                      regulator-min-microvolt = <3000000>;
++                                      regulator-max-microvolt = <3000000>;
++                              };
++
++                              ldo9_reg: LDO9 {
++                                      regulator-name = "VCC_2.8V_AP";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
++                              };
++
++                              ldo10_reg: LDO10 {
++                                      regulator-name = "VPLL_1.0V_AP";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo11_reg: LDO11 {
++                                      regulator-name = "VMIPI_1.0V_AP";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                              };
++
++                              ldo12_reg: LDO12 {
++                                      regulator-name = "VT_CAM_1.8";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                              };
++
++                              ldo13_reg: LDO13 {
++                                      regulator-name = "VCC_3.3V_LCD";
++                                      regulator-min-microvolt = <3300000>;
++                                      regulator-max-microvolt = <3300000>;
++                              };
++
++                              ldo14_reg: LDO14 {
++                                      regulator-name = "VCC_1.8V_IO";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                              };
++
++                              ldo15_reg: LDO15 {
++                                      regulator-name = "LCD_VDD_2.2V";
++                                      regulator-min-microvolt = <2200000>;
++                                      regulator-max-microvolt = <2200000>;
++                              };
++
++                              ldo16_reg: LDO16 {
++                                      regulator-name = "CAM_SENSOR_IO_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                              };
++
++                              ldo17_reg: LDO17 {
++                                      regulator-name = "CAM_AF_2.8V";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
++                                      regulator-mem-idle;
++                              };
++
++                              ldo18_reg: LDO18 {
++                                      regulator-name = "TSP_AVDD_3.3V";
++                                      regulator-min-microvolt = <3300000>;
++                                      regulator-max-microvolt = <3300000>;
++                              };
++
++                              vddq_reg: LDO21 {
++                                   regulator-name = "VM1M2_1.2V_AP";
++                                   regulator-min-microvolt = <1200000>;
++                                   regulator-max-microvolt = <1200000>;
++                                   regulator-always-on;
++                              };
++
++                              buck1_reg: BUCK1 {
++                                      regulator-name = "VARM_1.0V_AP";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                              };
++
++                              buck2_reg: BUCK2 {
++                                      regulator-name = "VINT_1.0V_AP";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                              };
++
++                              buck3_reg: BUCK3 {
++                                      regulator-name = "VG3D_1.0V_AP";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                              };
++
++                              buck4_reg: BUCK4 {
++                                      regulator-name = "CAM_ISO_CORE_1.2V";
++                                      regulator-min-microvolt = <1200000>;
++                                      regulator-max-microvolt = <1200000>;
++                              };
++
++                              safe1_sreg: ESAFEOUT1 {
++                                   regulator-name = "SAFEOUT1";
++                                   regulator-always-on;
++                              };
++
++                              safe2_sreg: ESAFEOUT2 {
++                                   regulator-name = "SAFEOUT2";
++                                   regulator-boot-on;
++                              };
++
++                      };
++              };
++      };
++
++      hsotg@12480000 {
++              status = "okay";
++              vusb_d-supply = <&ldo8_reg>;
++              vusb_a-supply = <&ldo11_reg>;
++              phys = <&exynos_usbphy 0>;
++              phy-names = "device";
++      };
++
++      exynos_usbphy: exynos-usbphy@125B0000 {
++              compatible = "samsung,exynos4212-usbphy";
++              reg = <0x125B0000 0x100>, <0x10020704 0x0c>, <0x1001021c 0x4>;
++              clocks = <&clock 305>, <&clock 2>, <&clock 2>, <&clock 2>,
++                                                              <&clock 2>;
++              clock-names = "phy", "device", "host", "hsic0", "hsic1";
++              status = "okay";
++              #phy-cells = <1>;
++      };
++};
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0813-ARM-dts-Correct-audio-clock-number-in-exynos4412-slp.patch b/patches.tizen/0813-ARM-dts-Correct-audio-clock-number-in-exynos4412-slp.patch
new file mode 100644 (file)
index 0000000..4b84ab5
--- /dev/null
@@ -0,0 +1,31 @@
+From c9155202b93727bac60ac0179885b37043f13d0e Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Wed, 2 Oct 2013 08:51:25 +0200
+Subject: [PATCH 0813/1302] ARM: dts: Correct audio clock number in
+ exynos4412-slp_pq.dts
+
+Audio block should use mout_clkout (396) as parent clock instead of
+incorrect aclk400_mcuisp clokc (395).
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index e041769..7b912dd 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -1208,7 +1208,7 @@
+       sound {
+               compatible = "samsung,exynos4-wm1811";
+-              clocks = <&clock 2>, <&clock 395>, <&clock 21>, <&clock 6>;
++              clocks = <&clock 2>, <&clock 396>, <&clock 21>, <&clock 6>;
+               clock-names = "parent", "out-mux", "out", "pll" /* EPLL */;
+               samsung,i2s-controller = <&i2s0>;
+               samsung,audio-codec = <&wm1811>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0814-vrange-Add-basic-data-structure-and-functions.patch b/patches.tizen/0814-vrange-Add-basic-data-structure-and-functions.patch
new file mode 100644 (file)
index 0000000..1d899f2
--- /dev/null
@@ -0,0 +1,366 @@
+From f1f160881562a0a9bc509cab80af79bad4903476 Mon Sep 17 00:00:00 2001
+From: Minchan Kim <minchan@kernel.org>
+Date: Thu, 25 Jul 2013 13:44:31 +0900
+Subject: [PATCH 0814/1302] vrange: Add basic data structure and functions
+
+This patch adds vrange data structure(interval tree) and
+related functions.
+
+The vrange uses generic interval tree as main data structure
+because it handles address range so generic interval tree
+fits well for the purpose.
+
+The vrange_add/vrange_remove are core functions for the vrange()
+system call that will be introduced in a following patch.
+
+The vrange_add inserts new address range into interval tree.
+If new address range crosses over existing volatile range,
+existing volatile range will be expanded to cover new range.
+Then, if existing volatile range has purged state, new range
+will have a purged state. If new address range is inside
+existing range, we ignore it.
+
+The vrange_remove removes address range. Then, return a purged
+state of the address ranges.
+
+This patch copied some part from John Stultz's work but uses
+slightly different semantics.
+
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Android Kernel Team <kernel-team@android.com>
+Cc: Robert Love <rlove@google.com>
+Cc: Mel Gorman <mel@csn.ul.ie>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Dave Hansen <dave@linux.vnet.ibm.com>
+Cc: Rik van Riel <riel@redhat.com>
+Cc: Dmitry Adamushko <dmitry.adamushko@gmail.com>
+Cc: Dave Chinner <david@fromorbit.com>
+Cc: Neil Brown <neilb@suse.de>
+Cc: Andrea Righi <andrea@betterlinux.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+Cc: Mike Hommey <mh@glandium.org>
+Cc: Taras Glek <tglek@mozilla.com>
+Cc: Dhaval Giani <dgiani@mozilla.com>
+Cc: Jan Kara <jack@suse.cz>
+Cc: KOSAKI Motohiro <kosaki.motohiro@gmail.com>
+Cc: Michel Lespinasse <walken@google.com>
+Cc: Minchan Kim <minchan@kernel.org>
+Cc: linux-mm@kvack.org <linux-mm@kvack.org>
+Signed-off-by: Minchan Kim <minchan@kernel.org>
+[jstultz: Heavy rework and cleanups to make this infrastructure more
+easily reused for both file and anonymous pages]
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/vrange.h       |  45 +++++++++++
+ include/linux/vrange_types.h |  24 ++++++
+ lib/Makefile                 |   2 +-
+ mm/Makefile                  |   2 +-
+ mm/vrange.c                  | 184 +++++++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 255 insertions(+), 2 deletions(-)
+ create mode 100644 include/linux/vrange.h
+ create mode 100644 include/linux/vrange_types.h
+ create mode 100644 mm/vrange.c
+
+diff --git a/include/linux/vrange.h b/include/linux/vrange.h
+new file mode 100644
+index 0000000..27d4c2e
+--- /dev/null
++++ b/include/linux/vrange.h
+@@ -0,0 +1,45 @@
++#ifndef _LINUX_VRANGE_H
++#define _LINUX_VRANGE_H
++
++#include <linux/vrange_types.h>
++#include <linux/mm.h>
++
++#define vrange_from_node(node_ptr) \
++      container_of(node_ptr, struct vrange, node)
++
++#define vrange_entry(ptr) \
++      container_of(ptr, struct vrange, node.rb)
++
++#ifdef CONFIG_MMU
++
++static inline void vrange_root_init(struct vrange_root *vroot, int type)
++{
++      vroot->type = type;
++      vroot->v_rb = RB_ROOT;
++      mutex_init(&vroot->v_lock);
++}
++
++static inline void vrange_lock(struct vrange_root *vroot)
++{
++      mutex_lock(&vroot->v_lock);
++}
++
++static inline void vrange_unlock(struct vrange_root *vroot)
++{
++      mutex_unlock(&vroot->v_lock);
++}
++
++static inline int vrange_type(struct vrange *vrange)
++{
++      return vrange->owner->type;
++}
++
++extern void vrange_root_cleanup(struct vrange_root *vroot);
++
++#else
++
++static inline void vrange_root_init(struct vrange_root *vroot, int type) {};
++static inline void vrange_root_cleanup(struct vrange_root *vroot) {};
++
++#endif
++#endif /* _LINIUX_VRANGE_H */
+diff --git a/include/linux/vrange_types.h b/include/linux/vrange_types.h
+new file mode 100644
+index 0000000..3579983
+--- /dev/null
++++ b/include/linux/vrange_types.h
+@@ -0,0 +1,24 @@
++#ifndef _LINUX_VRANGE_TYPES_H
++#define _LINUX_VRANGE_TYPES_H
++
++#include <linux/mutex.h>
++#include <linux/interval_tree.h>
++
++enum vrange_type {
++      VRANGE_MM,
++      VRANGE_FILE,
++};
++
++struct vrange_root {
++      struct rb_root v_rb;            /* vrange rb tree */
++      struct mutex v_lock;            /* Protect v_rb */
++      enum vrange_type type;          /* range root type */
++};
++
++struct vrange {
++      struct interval_tree_node node;
++      struct vrange_root *owner;
++      int purged;
++};
++#endif
++
+diff --git a/lib/Makefile b/lib/Makefile
+index c55a037..ccd15ff 100644
+--- a/lib/Makefile
++++ b/lib/Makefile
+@@ -13,7 +13,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
+        sha1.o md5.o irq_regs.o reciprocal_div.o argv_split.o \
+        proportions.o flex_proportions.o prio_heap.o ratelimit.o show_mem.o \
+        is_single_threaded.o plist.o decompress.o kobject_uevent.o \
+-       earlycpio.o
++       earlycpio.o interval_tree.o
+ obj-$(CONFIG_ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS) += usercopy.o
+ lib-$(CONFIG_MMU) += ioremap.o
+diff --git a/mm/Makefile b/mm/Makefile
+index f008033..54928af 100644
+--- a/mm/Makefile
++++ b/mm/Makefile
+@@ -5,7 +5,7 @@
+ mmu-y                 := nommu.o
+ mmu-$(CONFIG_MMU)     := fremap.o highmem.o madvise.o memory.o mincore.o \
+                          mlock.o mmap.o mprotect.o mremap.o msync.o rmap.o \
+-                         vmalloc.o pagewalk.o pgtable-generic.o
++                         vmalloc.o pagewalk.o pgtable-generic.o vrange.o
+ ifdef CONFIG_CROSS_MEMORY_ATTACH
+ mmu-$(CONFIG_MMU)     += process_vm_access.o
+diff --git a/mm/vrange.c b/mm/vrange.c
+new file mode 100644
+index 0000000..2e1caf3
+--- /dev/null
++++ b/mm/vrange.c
+@@ -0,0 +1,184 @@
++/*
++ * mm/vrange.c
++ */
++
++#include <linux/vrange.h>
++#include <linux/slab.h>
++
++static struct kmem_cache *vrange_cachep;
++
++static int __init vrange_init(void)
++{
++      vrange_cachep = KMEM_CACHE(vrange, SLAB_PANIC);
++      return 0;
++}
++
++module_init(vrange_init);
++
++static struct vrange *__vrange_alloc(gfp_t flags)
++{
++      struct vrange *vrange = kmem_cache_alloc(vrange_cachep, flags);
++      if (!vrange)
++              return vrange;
++      vrange->owner = NULL;
++      return vrange;
++}
++
++static void __vrange_free(struct vrange *range)
++{
++      WARN_ON(range->owner);
++      kmem_cache_free(vrange_cachep, range);
++}
++
++static void __vrange_add(struct vrange *range, struct vrange_root *vroot)
++{
++      range->owner = vroot;
++      interval_tree_insert(&range->node, &vroot->v_rb);
++}
++
++static void __vrange_remove(struct vrange *range)
++{
++      interval_tree_remove(&range->node, &range->owner->v_rb);
++      range->owner = NULL;
++}
++
++static inline void __vrange_set(struct vrange *range,
++              unsigned long start_idx, unsigned long end_idx,
++              bool purged)
++{
++      range->node.start = start_idx;
++      range->node.last = end_idx;
++      range->purged = purged;
++}
++
++static inline void __vrange_resize(struct vrange *range,
++              unsigned long start_idx, unsigned long end_idx)
++{
++      struct vrange_root *vroot = range->owner;
++      bool purged = range->purged;
++
++      __vrange_remove(range);
++      __vrange_set(range, start_idx, end_idx, purged);
++      __vrange_add(range, vroot);
++}
++
++static int vrange_add(struct vrange_root *vroot,
++                      unsigned long start_idx, unsigned long end_idx)
++{
++      struct vrange *new_range, *range;
++      struct interval_tree_node *node, *next;
++      int purged = 0;
++
++      new_range = __vrange_alloc(GFP_KERNEL);
++      if (!new_range)
++              return -ENOMEM;
++
++      vrange_lock(vroot);
++
++      node = interval_tree_iter_first(&vroot->v_rb, start_idx, end_idx);
++      while (node) {
++              next = interval_tree_iter_next(node, start_idx, end_idx);
++              range = vrange_from_node(node);
++              /* old range covers new range fully */
++              if (node->start <= start_idx && node->last >= end_idx) {
++                      __vrange_free(new_range);
++                      goto out;
++              }
++
++              start_idx = min_t(unsigned long, start_idx, node->start);
++              end_idx = max_t(unsigned long, end_idx, node->last);
++              purged |= range->purged;
++
++              __vrange_remove(range);
++              __vrange_free(range);
++
++              node = next;
++      }
++
++      __vrange_set(new_range, start_idx, end_idx, purged);
++      __vrange_add(new_range, vroot);
++out:
++      vrange_unlock(vroot);
++      return 0;
++}
++
++static int vrange_remove(struct vrange_root *vroot,
++                              unsigned long start_idx, unsigned long end_idx,
++                              int *purged)
++{
++      struct vrange *new_range, *range;
++      struct interval_tree_node *node, *next;
++      bool used_new = false;
++
++      if (!purged)
++              return -EINVAL;
++
++      *purged = 0;
++
++      new_range = __vrange_alloc(GFP_KERNEL);
++      if (!new_range)
++              return -ENOMEM;
++
++      vrange_lock(vroot);
++
++      node = interval_tree_iter_first(&vroot->v_rb, start_idx, end_idx);
++      while (node) {
++              next = interval_tree_iter_next(node, start_idx, end_idx);
++              range = vrange_from_node(node);
++
++              *purged |= range->purged;
++
++              if (start_idx <= node->start && end_idx >= node->last) {
++                      /* argumented range covers the range fully */
++                      __vrange_remove(range);
++                      __vrange_free(range);
++              } else if (node->start >= start_idx) {
++                      /*
++                       * Argumented range covers over the left of the
++                       * range
++                       */
++                      __vrange_resize(range, end_idx + 1, node->last);
++              } else if (node->last <= end_idx) {
++                      /*
++                       * Argumented range covers over the right of the
++                       * range
++                       */
++                      __vrange_resize(range, node->start, start_idx - 1);
++              } else {
++                      /*
++                       * Argumented range is middle of the range
++                       */
++                      unsigned long last = node->last;
++                      used_new = true;
++                      __vrange_resize(range, node->start, start_idx - 1);
++                      __vrange_set(new_range, end_idx + 1, last,
++                                      range->purged);
++                      __vrange_add(new_range, vroot);
++                      break;
++              }
++
++              node = next;
++      }
++      vrange_unlock(vroot);
++
++      if (!used_new)
++              __vrange_free(new_range);
++
++      return 0;
++}
++
++void vrange_root_cleanup(struct vrange_root *vroot)
++{
++      struct vrange *range;
++      struct rb_node *node;
++
++      vrange_lock(vroot);
++      /* We should remove node by post-order traversal */
++      while ((node = rb_first(&vroot->v_rb))) {
++              range = vrange_entry(node);
++              __vrange_remove(range);
++              __vrange_free(range);
++      }
++      vrange_unlock(vroot);
++}
++
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0815-vrange-Add-vrange-support-to-mm_structs.patch b/patches.tizen/0815-vrange-Add-vrange-support-to-mm_structs.patch
new file mode 100644 (file)
index 0000000..dbb68b8
--- /dev/null
@@ -0,0 +1,196 @@
+From 30cf4af092fb003edd9c5f6ac87900838deb6f01 Mon Sep 17 00:00:00 2001
+From: Minchan Kim <minchan@kernel.org>
+Date: Thu, 25 Jul 2013 13:44:32 +0900
+Subject: [PATCH 0815/1302] vrange: Add vrange support to mm_structs
+
+This patch addes vroot on mm_struct so process can have volatile
+ranges on anonymous memory.
+
+This is somewhat wasteful, as it increases the mm struct even
+if the process doesn't use vrange syscall. So an following patch
+will make it dynamically allocated.
+
+One of note on this patch is vrange_fork. Its could deadlock with
+direct reclaim's purging logic due to vrange_lock so vrange_fork
+uses GFP_NOIO.
+
+It does make sense because purging is kind of I/O operation although
+it doesn't do anything related to I/O issuing and it could be very
+understandable when I will introduce vrange-file, which should avoid
+direct purging when caller pass GFP_FS to avoid deadlock.
+
+If vrange_fork fails, it isn't critical because worst case from user
+POV is that pages in vrange of parent can't be purged, which is likely
+better than having fork fail.
+
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Android Kernel Team <kernel-team@android.com>
+Cc: Robert Love <rlove@google.com>
+Cc: Mel Gorman <mel@csn.ul.ie>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Dave Hansen <dave@linux.vnet.ibm.com>
+Cc: Rik van Riel <riel@redhat.com>
+Cc: Dmitry Adamushko <dmitry.adamushko@gmail.com>
+Cc: Dave Chinner <david@fromorbit.com>
+Cc: Neil Brown <neilb@suse.de>
+Cc: Andrea Righi <andrea@betterlinux.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+Cc: Mike Hommey <mh@glandium.org>
+Cc: Taras Glek <tglek@mozilla.com>
+Cc: Dhaval Giani <dgiani@mozilla.com>
+Cc: Jan Kara <jack@suse.cz>
+Cc: KOSAKI Motohiro <kosaki.motohiro@gmail.com>
+Cc: Michel Lespinasse <walken@google.com>
+Cc: Minchan Kim <minchan@kernel.org>
+Cc: linux-mm@kvack.org <linux-mm@kvack.org>
+Signed-off-by: Minchan Kim <minchan@kernel.org>
+[jstultz: Bit of refactoring. Comment cleanups]
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/mm_types.h |  4 ++++
+ include/linux/vrange.h   |  7 ++++++-
+ kernel/fork.c            | 11 +++++++++++
+ mm/vrange.c              | 40 ++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 61 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
+index 4a189ba..7e14abd 100644
+--- a/include/linux/mm_types.h
++++ b/include/linux/mm_types.h
+@@ -13,6 +13,7 @@
+ #include <linux/page-debug-flags.h>
+ #include <linux/uprobes.h>
+ #include <linux/page-flags-layout.h>
++#include <linux/vrange_types.h>
+ #include <asm/page.h>
+ #include <asm/mmu.h>
+@@ -352,6 +353,9 @@ struct mm_struct {
+                                                */
++#ifdef CONFIG_MMU
++      struct vrange_root vroot;
++#endif
+       unsigned long hiwater_rss;      /* High-watermark of RSS usage */
+       unsigned long hiwater_vm;       /* High-water virtual memory usage */
+diff --git a/include/linux/vrange.h b/include/linux/vrange.h
+index 27d4c2e..fc0baf6 100644
+--- a/include/linux/vrange.h
++++ b/include/linux/vrange.h
+@@ -35,11 +35,16 @@ static inline int vrange_type(struct vrange *vrange)
+ }
+ extern void vrange_root_cleanup(struct vrange_root *vroot);
+-
++extern int vrange_fork(struct mm_struct *new,
++                                      struct mm_struct *old);
+ #else
+ static inline void vrange_root_init(struct vrange_root *vroot, int type) {};
+ static inline void vrange_root_cleanup(struct vrange_root *vroot) {};
++static inline int vrange_fork(struct mm_struct *new, struct mm_struct *old)
++{
++      return 0;
++}
+ #endif
+ #endif /* _LINIUX_VRANGE_H */
+diff --git a/kernel/fork.c b/kernel/fork.c
+index 80d92e9..88f5b9f 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -71,6 +71,7 @@
+ #include <linux/signalfd.h>
+ #include <linux/uprobes.h>
+ #include <linux/aio.h>
++#include <linux/vrange.h>
+ #include <asm/pgtable.h>
+ #include <asm/pgalloc.h>
+@@ -379,6 +380,14 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
+       retval = khugepaged_fork(mm, oldmm);
+       if (retval)
+               goto out;
++      /*
++       * Note: vrange_fork can fail in the case of ENOMEM, but
++       * this only results in the child not having any active
++       * volatile ranges. This is not harmful. Thus in this case
++       * the child will not see any pages purged unless it remarks
++       * them as volatile.
++       */
++      vrange_fork(mm, oldmm);
+       prev = NULL;
+       for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) {
+@@ -540,6 +549,7 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p)
+       mm->nr_ptes = 0;
+       memset(&mm->rss_stat, 0, sizeof(mm->rss_stat));
+       spin_lock_init(&mm->page_table_lock);
++      vrange_root_init(&mm->vroot, VRANGE_MM);
+       mm->free_area_cache = TASK_UNMAPPED_BASE;
+       mm->cached_hole_size = ~0UL;
+       mm_init_aio(mm);
+@@ -613,6 +623,7 @@ void mmput(struct mm_struct *mm)
+       if (atomic_dec_and_test(&mm->mm_users)) {
+               uprobe_clear_state(mm);
++              vrange_root_cleanup(&mm->vroot);
+               exit_aio(mm);
+               ksm_exit(mm);
+               khugepaged_exit(mm); /* must run before exit_mmap */
+diff --git a/mm/vrange.c b/mm/vrange.c
+index 2e1caf3..ccd9ff0 100644
+--- a/mm/vrange.c
++++ b/mm/vrange.c
+@@ -182,3 +182,43 @@ void vrange_root_cleanup(struct vrange_root *vroot)
+       vrange_unlock(vroot);
+ }
++/*
++ * It's okay to fail vrange_fork because worst case is child process
++ * can't have copied own vrange data structure so that pages in the
++ * vrange couldn't be purged. It would be better rather than failing
++ * fork.
++ */
++int vrange_fork(struct mm_struct *new_mm, struct mm_struct *old_mm)
++{
++      struct vrange_root *new, *old;
++      struct vrange *range, *new_range;
++      struct rb_node *next;
++
++      new = &new_mm->vroot;
++      old = &old_mm->vroot;
++
++      vrange_lock(old);
++      next = rb_first(&old->v_rb);
++      while (next) {
++              range = vrange_entry(next);
++              next = rb_next(next);
++              /*
++               * We can't use GFP_KERNEL because direct reclaim's
++               * purging logic on vrange could be deadlock by
++               * vrange_lock.
++               */
++              new_range = __vrange_alloc(GFP_NOIO);
++              if (!new_range)
++                      goto fail;
++              __vrange_set(new_range, range->node.start,
++                                      range->node.last, range->purged);
++              __vrange_add(new_range, new);
++
++      }
++      vrange_unlock(old);
++      return 0;
++fail:
++      vrange_unlock(old);
++      vrange_root_cleanup(new);
++      return 0;
++}
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0816-vrange-Clear-volatility-on-new-mmaps.patch b/patches.tizen/0816-vrange-Clear-volatility-on-new-mmaps.patch
new file mode 100644 (file)
index 0000000..16cefa7
--- /dev/null
@@ -0,0 +1,117 @@
+From f94291bbc8c4c44c3917186af4458eef41c0df03 Mon Sep 17 00:00:00 2001
+From: John Stultz <john.stultz@linaro.org>
+Date: Thu, 25 Jul 2013 13:44:33 +0900
+Subject: [PATCH 0816/1302] vrange: Clear volatility on new mmaps
+
+At lsf-mm, the issue was brought up that there is a precedence with
+interfaces like mlock, such that new mappings in a pre-existing range
+do no inherit the mlock state.
+
+This is mostly because mlock only modifies the existing vmas, and so
+any new mmaps create new vmas, which won't be mlocked.
+
+Since volatility is not stored in the vma (for good cause, specfically
+as we'd have to have manage file volatility differently from anonymous
+and we're likely to manage volatility on small chunks of memory, which
+would cause lots of vma splitting and churn), this patch clears volatilty
+on new mappings, to ensure that we don't inherit volatility if memory in
+an existing volatile range is unmapped and then re-mapped with something
+else.
+
+Thus, this patch forces any volatility to be cleared on mmap.
+
+XXX: We expect this patch to be not well loved by mm folks, and are open
+to alternative methods here. Its more of a place holder to address
+the issue from lsf-mm and hopefully will spur some further discussion.
+
+XXX: If Minchan's alternative ends up being the way forward, squish this
+and ideally merge down that change into the previous patch that adds
+vroots to the mm structure.
+
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Android Kernel Team <kernel-team@android.com>
+Cc: Robert Love <rlove@google.com>
+Cc: Mel Gorman <mel@csn.ul.ie>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Dave Hansen <dave@linux.vnet.ibm.com>
+Cc: Rik van Riel <riel@redhat.com>
+Cc: Dmitry Adamushko <dmitry.adamushko@gmail.com>
+Cc: Dave Chinner <david@fromorbit.com>
+Cc: Neil Brown <neilb@suse.de>
+Cc: Andrea Righi <andrea@betterlinux.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+Cc: Mike Hommey <mh@glandium.org>
+Cc: Taras Glek <tglek@mozilla.com>
+Cc: Dhaval Giani <dgiani@mozilla.com>
+Cc: Jan Kara <jack@suse.cz>
+Cc: KOSAKI Motohiro <kosaki.motohiro@gmail.com>
+Cc: Michel Lespinasse <walken@google.com>
+Cc: Minchan Kim <minchan@kernel.org>
+Cc: linux-mm@kvack.org <linux-mm@kvack.org>
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/vrange.h | 2 ++
+ mm/mmap.c              | 5 +++++
+ mm/vrange.c            | 8 ++++++++
+ 3 files changed, 15 insertions(+)
+
+diff --git a/include/linux/vrange.h b/include/linux/vrange.h
+index fc0baf6..235a318 100644
+--- a/include/linux/vrange.h
++++ b/include/linux/vrange.h
+@@ -34,6 +34,8 @@ static inline int vrange_type(struct vrange *vrange)
+       return vrange->owner->type;
+ }
++extern int vrange_clear(struct vrange_root *vroot,
++                              unsigned long start, unsigned long end);
+ extern void vrange_root_cleanup(struct vrange_root *vroot);
+ extern int vrange_fork(struct mm_struct *new,
+                                       struct mm_struct *old);
+diff --git a/mm/mmap.c b/mm/mmap.c
+index 8d25fdc..3d130b9 100644
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -36,6 +36,7 @@
+ #include <linux/sched/sysctl.h>
+ #include <linux/notifier.h>
+ #include <linux/memory.h>
++#include <linux/vrange.h>
+ #include <asm/uaccess.h>
+ #include <asm/cacheflush.h>
+@@ -1500,6 +1501,10 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
+       /* Clear old maps */
+       error = -ENOMEM;
+ munmap_back:
++
++      /* zap any volatile ranges */
++      vrange_clear(&mm->vroot, addr, addr + len);
++
+       if (find_vma_links(mm, addr, addr + len, &prev, &rb_link, &rb_parent)) {
+               if (do_munmap(mm, addr, len))
+                       return -ENOMEM;
+diff --git a/mm/vrange.c b/mm/vrange.c
+index ccd9ff0..66df345 100644
+--- a/mm/vrange.c
++++ b/mm/vrange.c
+@@ -167,6 +167,14 @@ static int vrange_remove(struct vrange_root *vroot,
+       return 0;
+ }
++int vrange_clear(struct vrange_root *vroot,
++                                      unsigned long start, unsigned long end)
++{
++      int purged;
++
++      return vrange_remove(vroot, start, end - 1, &purged);
++}
++
+ void vrange_root_cleanup(struct vrange_root *vroot)
+ {
+       struct vrange *range;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0817-vrange-Add-support-for-volatile-ranges-on-file-mappi.patch b/patches.tizen/0817-vrange-Add-support-for-volatile-ranges-on-file-mappi.patch
new file mode 100644 (file)
index 0000000..142f98b
--- /dev/null
@@ -0,0 +1,84 @@
+From 504a1f15ee695aac07b60e89d6c140980f22ed34 Mon Sep 17 00:00:00 2001
+From: John Stultz <john.stultz@linaro.org>
+Date: Thu, 25 Jul 2013 13:37:51 -0700
+Subject: [PATCH 0817/1302] vrange: Add support for volatile ranges on file
+ mappings
+
+Like with the mm struct, this patch add basic support for
+volatile ranges on file address_space structures. This allows
+for volatile ranges to be set on mmapped files that can be
+shared between processes.
+
+The semantics on the volatile range sharing is that the
+volatility is shared, just as the data is shared. Thus
+if one process marks the range as volatile, the data is
+volatile in all processes that have those pages mapped.
+
+It is advised that processes coodinate when using volatile
+ranges on shared mappings (much as they must coordinate when
+writing to shared data).
+
+XXX: Likely squish down file parts of dynamic vroot allocation into
+this patch
+
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/inode.c         | 4 ++++
+ include/linux/fs.h | 4 ++++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/fs/inode.c b/fs/inode.c
+index 00d5fc3..a4a6844 100644
+--- a/fs/inode.c
++++ b/fs/inode.c
+@@ -17,6 +17,7 @@
+ #include <linux/prefetch.h>
+ #include <linux/buffer_head.h> /* for inode_has_buffers */
+ #include <linux/ratelimit.h>
++#include <linux/vrange.h>
+ #include "internal.h"
+ /*
+@@ -350,6 +351,7 @@ void address_space_init_once(struct address_space *mapping)
+       spin_lock_init(&mapping->private_lock);
+       mapping->i_mmap = RB_ROOT;
+       INIT_LIST_HEAD(&mapping->i_mmap_nonlinear);
++      vrange_root_init(&mapping->vroot, VRANGE_FILE);
+ }
+ EXPORT_SYMBOL(address_space_init_once);
+@@ -1417,6 +1419,8 @@ static void iput_final(struct inode *inode)
+               inode_lru_list_del(inode);
+       spin_unlock(&inode->i_lock);
++      vrange_root_cleanup(&inode->i_mapping->vroot);
++
+       evict(inode);
+ }
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 65c2be2..925714d 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -27,6 +27,7 @@
+ #include <linux/lockdep.h>
+ #include <linux/percpu-rwsem.h>
+ #include <linux/blk_types.h>
++#include <linux/vrange_types.h>
+ #include <asm/byteorder.h>
+ #include <uapi/linux/fs.h>
+@@ -411,6 +412,9 @@ struct address_space {
+       struct rb_root          i_mmap;         /* tree of private and shared mappings */
+       struct list_head        i_mmap_nonlinear;/*list VM_NONLINEAR mappings */
+       struct mutex            i_mmap_mutex;   /* protect tree, count, list */
++#ifdef CONFIG_MMU
++      struct vrange_root      vroot;
++#endif
+       /* Protected by tree_lock together with the radix tree */
+       unsigned long           nrpages;        /* number of total pages */
+       pgoff_t                 writeback_index;/* writeback starts here */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0818-vrange-Add-new-vrange-2-system-call.patch b/patches.tizen/0818-vrange-Add-new-vrange-2-system-call.patch
new file mode 100644 (file)
index 0000000..dbb0122
--- /dev/null
@@ -0,0 +1,315 @@
+From ee0761c7382c415190f8b171f4decedb105615d1 Mon Sep 17 00:00:00 2001
+From: Minchan Kim <minchan@kernel.org>
+Date: Thu, 25 Jul 2013 13:44:34 +0900
+Subject: [PATCH 0818/1302] vrange: Add new vrange(2) system call
+
+This patch adds new system call sys_vrange.
+
+NAME
+       vrange - Mark or unmark range of memory as volatile
+
+SYNOPSIS
+       int vrange(unsigned_long start, size_t length, int mode,
+                        int *purged);
+
+DESCRIPTION
+       Applications can use vrange(2) to advise the kernel how it should
+       handle paging I/O in this VM area.  The idea is to help the kernel
+       discard pages of vrange instead of reclaiming when memory pressure
+       happens. It means kernel doesn't discard any pages of vrange if
+       there is no memory pressure.
+
+       mode:
+       VRANGE_VOLATILE
+               hint to kernel so VM can discard in vrange pages when
+               memory pressure happens.
+       VRANGE_NONVOLATILE
+               hint to kernel so VM doesn't discard vrange pages
+               any more.
+
+       If user try to access purged memory without VRANGE_NOVOLATILE call,
+       he can encounter SIGBUS if the page was discarded by kernel.
+
+       purged: Pointer to an integer which will return 1 if
+       mode == VRANGE_NONVOLATILE and any page in the affected range
+       was purged. If purged returns zero during a mode ==
+       VRANGE_NONVOLATILE call, it means all of the pages in the range
+       are intact.
+
+RETURN VALUE
+       On success vrange returns the number of bytes marked or unmarked.
+       Similar to write(), it may return fewer bytes then specified
+       if it ran into a problem.
+
+       If an error is returned, no changes were made.
+
+ERRORS
+       EINVAL This error can occur for the following reasons:
+               * The value length is negative or not page size units.
+               * addr is not page-aligned
+               * mode not a valid value.
+
+       ENOMEM Not enough memory
+
+       EFAULT purged pointer is invalid
+
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Android Kernel Team <kernel-team@android.com>
+Cc: Robert Love <rlove@google.com>
+Cc: Mel Gorman <mel@csn.ul.ie>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Dave Hansen <dave@linux.vnet.ibm.com>
+Cc: Rik van Riel <riel@redhat.com>
+Cc: Dmitry Adamushko <dmitry.adamushko@gmail.com>
+Cc: Dave Chinner <david@fromorbit.com>
+Cc: Neil Brown <neilb@suse.de>
+Cc: Andrea Righi <andrea@betterlinux.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+Cc: Mike Hommey <mh@glandium.org>
+Cc: Taras Glek <tglek@mozilla.com>
+Cc: Dhaval Giani <dgiani@mozilla.com>
+Cc: Jan Kara <jack@suse.cz>
+Cc: KOSAKI Motohiro <kosaki.motohiro@gmail.com>
+Cc: Michel Lespinasse <walken@google.com>
+Cc: linux-mm@kvack.org <linux-mm@kvack.org>
+Signed-off-by: Minchan Kim <minchan@kernel.org>
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/x86/syscalls/syscall_64.tbl       |   1 +
+ include/linux/syscalls.h               |   2 +
+ include/uapi/asm-generic/mman-common.h |   3 +
+ kernel/sys_ni.c                        |   1 +
+ mm/vrange.c                            | 164 +++++++++++++++++++++++++++++++++
+ 5 files changed, 171 insertions(+)
+
+diff --git a/arch/x86/syscalls/syscall_64.tbl b/arch/x86/syscalls/syscall_64.tbl
+index 38ae65d..dc332bd 100644
+--- a/arch/x86/syscalls/syscall_64.tbl
++++ b/arch/x86/syscalls/syscall_64.tbl
+@@ -320,6 +320,7 @@
+ 311   64      process_vm_writev       sys_process_vm_writev
+ 312   common  kcmp                    sys_kcmp
+ 313   common  finit_module            sys_finit_module
++314   common  vrange                  sys_vrange
+ #
+ # x32-specific system call numbers start at 512 to avoid cache impact
+diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
+index 84662ec..0997165 100644
+--- a/include/linux/syscalls.h
++++ b/include/linux/syscalls.h
+@@ -846,4 +846,6 @@ asmlinkage long sys_process_vm_writev(pid_t pid,
+ asmlinkage long sys_kcmp(pid_t pid1, pid_t pid2, int type,
+                        unsigned long idx1, unsigned long idx2);
+ asmlinkage long sys_finit_module(int fd, const char __user *uargs, int flags);
++asmlinkage long sys_vrange(unsigned long start, size_t len, int mode,
++              int __user *purged);
+ #endif
+diff --git a/include/uapi/asm-generic/mman-common.h b/include/uapi/asm-generic/mman-common.h
+index 4164529..9be120b 100644
+--- a/include/uapi/asm-generic/mman-common.h
++++ b/include/uapi/asm-generic/mman-common.h
+@@ -66,4 +66,7 @@
+ #define MAP_HUGE_SHIFT        26
+ #define MAP_HUGE_MASK 0x3f
++#define VRANGE_VOLATILE               0       /* unpin pages so VM can discard them */
++#define VRANGE_NONVOLATILE    1       /* pin pages so VM can't discard them */
++
+ #endif /* __ASM_GENERIC_MMAN_COMMON_H */
+diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
+index 7078052..f40070e 100644
+--- a/kernel/sys_ni.c
++++ b/kernel/sys_ni.c
+@@ -175,6 +175,7 @@ cond_syscall(sys_mremap);
+ cond_syscall(sys_remap_file_pages);
+ cond_syscall(compat_sys_move_pages);
+ cond_syscall(compat_sys_migrate_pages);
++cond_syscall(sys_vrange);
+ /* block-layer dependent */
+ cond_syscall(sys_bdflush);
+diff --git a/mm/vrange.c b/mm/vrange.c
+index 66df345..a97076b 100644
+--- a/mm/vrange.c
++++ b/mm/vrange.c
+@@ -4,6 +4,8 @@
+ #include <linux/vrange.h>
+ #include <linux/slab.h>
++#include <linux/syscalls.h>
++#include <linux/mman.h>
+ static struct kmem_cache *vrange_cachep;
+@@ -230,3 +232,165 @@ fail:
+       vrange_root_cleanup(new);
+       return 0;
+ }
++
++static inline struct vrange_root *__vma_to_vroot(struct vm_area_struct *vma)
++{
++      struct vrange_root *vroot = NULL;
++
++      if (vma->vm_file && (vma->vm_flags & VM_SHARED))
++              vroot = &vma->vm_file->f_mapping->vroot;
++      else
++              vroot = &vma->vm_mm->vroot;
++      return vroot;
++}
++
++static inline unsigned long __vma_addr_to_index(struct vm_area_struct *vma,
++                                                      unsigned long addr)
++{
++      if (vma->vm_file && (vma->vm_flags & VM_SHARED))
++              return (vma->vm_pgoff << PAGE_SHIFT) + addr - vma->vm_start;
++      return addr;
++}
++
++static ssize_t do_vrange(struct mm_struct *mm, unsigned long start_idx,
++                              unsigned long end_idx, int mode, int *purged)
++{
++      struct vm_area_struct *vma;
++      unsigned long orig_start = start_idx;
++      ssize_t count = 0, ret = 0;
++
++      down_read(&mm->mmap_sem);
++
++      vma = find_vma(mm, start_idx);
++      for (;;) {
++              struct vrange_root *vroot;
++              unsigned long tmp, vstart_idx, vend_idx;
++
++              if (!vma)
++                      goto out;
++
++              if (vma->vm_flags & (VM_SPECIAL|VM_LOCKED|VM_MIXEDMAP|
++                                      VM_HUGETLB))
++                      goto out;
++
++              /* make sure start is at the front of the current vma*/
++              if (start_idx < vma->vm_start) {
++                      start_idx = vma->vm_start;
++                      if (start_idx > end_idx)
++                              goto out;
++              }
++
++              /* bound tmp to closer of vm_end & end */
++              tmp = vma->vm_end - 1;
++              if (end_idx < tmp)
++                      tmp = end_idx;
++
++              vroot = __vma_to_vroot(vma);
++              vstart_idx = __vma_addr_to_index(vma, start_idx);
++              vend_idx = __vma_addr_to_index(vma, tmp);
++
++              /* mark or unmark */
++              if (mode == VRANGE_VOLATILE)
++                      ret = vrange_add(vroot, vstart_idx, vend_idx);
++              else if (mode == VRANGE_NONVOLATILE)
++                      ret = vrange_remove(vroot, vstart_idx, vend_idx,
++                                              purged);
++
++              if (ret)
++                      goto out;
++
++              /* update count to distance covered so far*/
++              count = tmp - orig_start + 1;
++
++              /* move start up to the end of the vma*/
++              start_idx = vma->vm_end;
++              if (start_idx > end_idx)
++                      goto out;
++              /* move to the next vma */
++              vma = vma->vm_next;
++      }
++out:
++      up_read(&mm->mmap_sem);
++
++      /* report bytes successfully marked, even if we're exiting on error */
++      if (count)
++              return count;
++
++      return ret;
++}
++
++/*
++ * The vrange(2) system call.
++ *
++ * Applications can use vrange() to advise the kernel how it should
++ * handle paging I/O in this VM area.  The idea is to help the kernel
++ * discard pages of vrange instead of swapping out when memory pressure
++ * happens. The information provided is advisory only, and can be safely
++ * disregarded by the kernel if system has enough free memory.
++ *
++ * mode values:
++ *  VRANGE_VOLATILE - hint to kernel so VM can discard vrange pages when
++ *            memory pressure happens.
++ *  VRANGE_NONVOLATILE - Removes any volatile hints previous specified in that
++ *            range.
++ *
++ * purged ptr:
++ *  Returns 1 if any page in the range being marked nonvolatile has been purged.
++ *
++ * Return values:
++ *  On success vrange returns the number of bytes marked or unmarked.
++ *  Similar to write(), it may return fewer bytes then specified if
++ *  it ran into a problem.
++ *
++ *  If an error is returned, no changes were made.
++ *
++ * Errors:
++ *  -EINVAL - start  len < 0, start is not page-aligned, start is greater
++ *            than TASK_SIZE or "mode" is not a valid value.
++ *  -ENOMEM - Short of free memory in system for successful system call.
++ *  -EFAULT - Purged pointer is invalid.
++ *  -ENOSUP - Feature not yet supported.
++ */
++SYSCALL_DEFINE4(vrange, unsigned long, start,
++              size_t, len, int, mode, int __user *, purged)
++{
++      unsigned long end;
++      struct mm_struct *mm = current->mm;
++      ssize_t ret = -EINVAL;
++      int p = 0;
++
++      if (start & ~PAGE_MASK)
++              goto out;
++
++      len &= PAGE_MASK;
++      if (!len)
++              goto out;
++
++      end = start + len;
++      if (end < start)
++              goto out;
++
++      if (start >= TASK_SIZE)
++              goto out;
++
++      if (purged) {
++              /* Test pointer is valid before making any changes */
++              if (put_user(p, purged))
++                      return -EFAULT;
++      }
++
++      ret = do_vrange(mm, start, end - 1, mode, &p);
++
++      if (purged) {
++              if (put_user(p, purged)) {
++                      /*
++                       * This would be bad, since we've modified volatilty
++                       * and the change in purged state would be lost.
++                       */
++                      BUG();
++              }
++      }
++
++out:
++      return ret;
++}
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0819-vrange-Add-basic-functions-to-purge-volatile-pages.patch b/patches.tizen/0819-vrange-Add-basic-functions-to-purge-volatile-pages.patch
new file mode 100644 (file)
index 0000000..9128752
--- /dev/null
@@ -0,0 +1,296 @@
+From ca81ef761bebccd7aeefdaa3b5965c5508141eed Mon Sep 17 00:00:00 2001
+From: Minchan Kim <minchan@kernel.org>
+Date: Wed, 2 Oct 2013 17:51:35 -0700
+Subject: [PATCH 0819/1302] vrange: Add basic functions to purge volatile pages
+
+This patch adds discard_vpage and related functions to purge
+anonymous and file volatile pages.
+
+It is in preparation for purging volatile pages when memory is tight.
+The logic to trigger purge volatile pages will be introduced in the
+next patch.
+
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Android Kernel Team <kernel-team@android.com>
+Cc: Robert Love <rlove@google.com>
+Cc: Mel Gorman <mel@csn.ul.ie>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Dave Hansen <dave.hansen@intel.com>
+Cc: Rik van Riel <riel@redhat.com>
+Cc: Dmitry Adamushko <dmitry.adamushko@gmail.com>
+Cc: Dave Chinner <david@fromorbit.com>
+Cc: Neil Brown <neilb@suse.de>
+Cc: Andrea Righi <andrea@betterlinux.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+Cc: Mike Hommey <mh@glandium.org>
+Cc: Taras Glek <tglek@mozilla.com>
+Cc: Dhaval Giani <dhaval.giani@gmail.com>
+Cc: Jan Kara <jack@suse.cz>
+Cc: KOSAKI Motohiro <kosaki.motohiro@gmail.com>
+Cc: Michel Lespinasse <walken@google.com>
+Cc: Rob Clark <robdclark@gmail.com>
+Cc: Minchan Kim <minchan@kernel.org>
+Cc: linux-mm@kvack.org <linux-mm@kvack.org>
+Signed-off-by: Minchan Kim <minchan@kernel.org>
+[jstultz: Reworked to add purging of file pages, commit log tweaks]
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/vrange.h |   9 +++
+ mm/internal.h          |   2 -
+ mm/vrange.c            | 185 +++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 194 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/vrange.h b/include/linux/vrange.h
+index 235a318..b18c31a 100644
+--- a/include/linux/vrange.h
++++ b/include/linux/vrange.h
+@@ -39,6 +39,9 @@ extern int vrange_clear(struct vrange_root *vroot,
+ extern void vrange_root_cleanup(struct vrange_root *vroot);
+ extern int vrange_fork(struct mm_struct *new,
+                                       struct mm_struct *old);
++int discard_vpage(struct page *page);
++bool vrange_addr_volatile(struct vm_area_struct *vma, unsigned long addr);
++
+ #else
+ static inline void vrange_root_init(struct vrange_root *vroot, int type) {};
+@@ -48,5 +51,11 @@ static inline int vrange_fork(struct mm_struct *new, struct mm_struct *old)
+       return 0;
+ }
++static inline bool vrange_addr_volatile(struct vm_area_struct *vma,
++                                      unsigned long addr)
++{
++      return false;
++}
++static inline int discard_vpage(struct page *page) { return 0 };
+ #endif
+ #endif /* _LINIUX_VRANGE_H */
+diff --git a/mm/internal.h b/mm/internal.h
+index 8562de0..9d66ac4 100644
+--- a/mm/internal.h
++++ b/mm/internal.h
+@@ -228,10 +228,8 @@ static inline void mlock_migrate_page(struct page *newpage, struct page *page)
+ extern pmd_t maybe_pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma);
+-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+ extern unsigned long vma_address(struct page *page,
+                                struct vm_area_struct *vma);
+-#endif
+ #else /* !CONFIG_MMU */
+ static inline int mlocked_vma_newpage(struct vm_area_struct *v, struct page *p)
+ {
+diff --git a/mm/vrange.c b/mm/vrange.c
+index a97076b..2ae91e3 100644
+--- a/mm/vrange.c
++++ b/mm/vrange.c
+@@ -6,6 +6,12 @@
+ #include <linux/slab.h>
+ #include <linux/syscalls.h>
+ #include <linux/mman.h>
++#include <linux/pagemap.h>
++#include <linux/rmap.h>
++#include <linux/hugetlb.h>
++#include "internal.h"
++#include <linux/swap.h>
++#include <linux/mmu_notifier.h>
+ static struct kmem_cache *vrange_cachep;
+@@ -64,6 +70,19 @@ static inline void __vrange_resize(struct vrange *range,
+       __vrange_add(range, vroot);
+ }
++static struct vrange *__vrange_find(struct vrange_root *vroot,
++                                      unsigned long start_idx,
++                                      unsigned long end_idx)
++{
++      struct vrange *range = NULL;
++      struct interval_tree_node *node;
++
++      node = interval_tree_iter_first(&vroot->v_rb, start_idx, end_idx);
++      if (node)
++              range = vrange_from_node(node);
++      return range;
++}
++
+ static int vrange_add(struct vrange_root *vroot,
+                       unsigned long start_idx, unsigned long end_idx)
+ {
+@@ -394,3 +413,169 @@ SYSCALL_DEFINE4(vrange, unsigned long, start,
+ out:
+       return ret;
+ }
++
++bool vrange_addr_volatile(struct vm_area_struct *vma, unsigned long addr)
++{
++      struct vrange_root *vroot;
++      unsigned long vstart_idx, vend_idx;
++      bool ret = false;
++
++      vroot = __vma_to_vroot(vma);
++      vstart_idx = __vma_addr_to_index(vma, addr);
++      vend_idx = vstart_idx + PAGE_SIZE - 1;
++
++      vrange_lock(vroot);
++      if (__vrange_find(vroot, vstart_idx, vend_idx))
++              ret = true;
++      vrange_unlock(vroot);
++      return ret;
++}
++
++/* Caller should hold vrange_lock */
++static void do_purge(struct vrange_root *vroot,
++              unsigned long start_idx, unsigned long end_idx)
++{
++      struct vrange *range;
++      struct interval_tree_node *node;
++
++      node = interval_tree_iter_first(&vroot->v_rb, start_idx, end_idx);
++      while (node) {
++              range = container_of(node, struct vrange, node);
++              range->purged = true;
++              node = interval_tree_iter_next(node, start_idx, end_idx);
++      }
++}
++
++static void try_to_discard_one(struct vrange_root *vroot, struct page *page,
++                              struct vm_area_struct *vma, unsigned long addr)
++{
++      struct mm_struct *mm = vma->vm_mm;
++      pte_t *pte;
++      pte_t pteval;
++      spinlock_t *ptl;
++
++      VM_BUG_ON(!PageLocked(page));
++
++      pte = page_check_address(page, mm, addr, &ptl, 0);
++      if (!pte)
++              return;
++
++      BUG_ON(vma->vm_flags & (VM_SPECIAL|VM_LOCKED|VM_MIXEDMAP|VM_HUGETLB));
++
++      flush_cache_page(vma, addr, page_to_pfn(page));
++      pteval = ptep_clear_flush(vma, addr, pte);
++
++      update_hiwater_rss(mm);
++      if (PageAnon(page))
++              dec_mm_counter(mm, MM_ANONPAGES);
++      else
++              dec_mm_counter(mm, MM_FILEPAGES);
++
++      page_remove_rmap(page);
++      page_cache_release(page);
++
++      pte_unmap_unlock(pte, ptl);
++      mmu_notifier_invalidate_page(mm, addr);
++
++      addr = __vma_addr_to_index(vma, addr);
++
++      do_purge(vroot, addr, addr + PAGE_SIZE - 1);
++}
++
++static int try_to_discard_anon_vpage(struct page *page)
++{
++      struct anon_vma *anon_vma;
++      struct anon_vma_chain *avc;
++      pgoff_t pgoff;
++      struct vm_area_struct *vma;
++      struct mm_struct *mm;
++      struct vrange_root *vroot;
++
++      unsigned long address;
++
++      anon_vma = page_lock_anon_vma_read(page);
++      if (!anon_vma)
++              return -1;
++
++      pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
++      /*
++       * During interating the loop, some processes could see a page as
++       * purged while others could see a page as not-purged because we have
++       * no global lock between parent and child for protecting vrange system
++       * call during this loop. But it's not a problem because the page is
++       * not *SHARED* page but *COW* page so parent and child can see other
++       * data anytime. The worst case by this race is a page was purged
++       * but couldn't be discarded so it makes unnecessary page fault but
++       * it wouldn't be severe.
++       */
++      anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root, pgoff, pgoff) {
++              vma = avc->vma;
++              mm = vma->vm_mm;
++              vroot = &mm->vroot;
++              address = vma_address(page, vma);
++
++              vrange_lock(vroot);
++              if (!__vrange_find(vroot, address, address + PAGE_SIZE - 1)) {
++                      vrange_unlock(vroot);
++                      continue;
++              }
++
++              try_to_discard_one(vroot, page, vma, address);
++              vrange_unlock(vroot);
++      }
++
++      page_unlock_anon_vma_read(anon_vma);
++      return 0;
++}
++
++static int try_to_discard_file_vpage(struct page *page)
++{
++      struct address_space *mapping = page->mapping;
++      pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
++      struct vm_area_struct *vma;
++
++      mutex_lock(&mapping->i_mmap_mutex);
++      vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) {
++              unsigned long address = vma_address(page, vma);
++              struct vrange_root *vroot = &mapping->vroot;
++              long vstart_idx;
++
++              vstart_idx = __vma_addr_to_index(vma, address);
++              vrange_lock(vroot);
++              if (!__vrange_find(vroot, vstart_idx,
++                                      vstart_idx + PAGE_SIZE - 1)) {
++                      vrange_unlock(vroot);
++                      continue;
++              }
++              try_to_discard_one(vroot, page, vma, address);
++              vrange_unlock(vroot);
++      }
++
++      mutex_unlock(&mapping->i_mmap_mutex);
++      return 0;
++}
++
++static int try_to_discard_vpage(struct page *page)
++{
++      if (PageAnon(page))
++              return try_to_discard_anon_vpage(page);
++      return try_to_discard_file_vpage(page);
++}
++
++int discard_vpage(struct page *page)
++{
++      VM_BUG_ON(!PageLocked(page));
++      VM_BUG_ON(PageLRU(page));
++
++      if (!try_to_discard_vpage(page)) {
++              if (PageSwapCache(page))
++                      try_to_free_swap(page);
++
++              if (page_freeze_refs(page, 1)) {
++                      unlock_page(page);
++                      return 0;
++              }
++      }
++
++      return 1;
++}
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0820-vrange-Purge-vrange-anon-pages-when-memory-is-tight.patch b/patches.tizen/0820-vrange-Purge-vrange-anon-pages-when-memory-is-tight.patch
new file mode 100644 (file)
index 0000000..8386a0c
--- /dev/null
@@ -0,0 +1,252 @@
+From a1b3b12cebd864a652b5d57f4a3060781b97f156 Mon Sep 17 00:00:00 2001
+From: Minchan Kim <minchan@kernel.org>
+Date: Thu, 25 Jul 2013 13:44:36 +0900
+Subject: [PATCH 0820/1302] vrange: Purge vrange-anon pages when memory is
+ tight
+
+This patch adds purging logic of volatile pages into direct
+reclaim path so that if vrange pages is selected as victim by VM,
+they could be discarded rather than swapping out.
+
+Direct purging doesn't consider volatile page's age because it
+would be better to free the page rather than swapping out
+another working set pages. This makes sense because userspace
+specifies "please remove free these pages when memory is tight"
+via the vrange syscall.
+
+This however is an in-kernel behavior and the purging logic
+could later change. Applications should not assume anything
+about the volatile page purging order, much as they shouldn't
+assume anything about the page swapout order.
+
+XXX: Might be a bug: Seems to purge if any process has anon page marked
+volatile, not if all processes have anon page marked volatile
+
+Signed-off-by: Minchan Kim <minchan@kernel.org>
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/rmap.h | 11 +++++++----
+ mm/ksm.c             |  2 +-
+ mm/rmap.c            | 28 ++++++++++++++++++++--------
+ mm/vmscan.c          | 17 +++++++++++++++--
+ 4 files changed, 43 insertions(+), 15 deletions(-)
+
+diff --git a/include/linux/rmap.h b/include/linux/rmap.h
+index 6dacb93..f38185d 100644
+--- a/include/linux/rmap.h
++++ b/include/linux/rmap.h
+@@ -181,10 +181,11 @@ static inline void page_dup_rmap(struct page *page)
+ /*
+  * Called from mm/vmscan.c to handle paging out
+  */
+-int page_referenced(struct page *, int is_locked,
+-                      struct mem_cgroup *memcg, unsigned long *vm_flags);
++int page_referenced(struct page *, int is_locked, struct mem_cgroup *memcg,
++                              unsigned long *vm_flags, int *is_vrange);
+ int page_referenced_one(struct page *, struct vm_area_struct *,
+-      unsigned long address, unsigned int *mapcount, unsigned long *vm_flags);
++                      unsigned long address, unsigned int *mapcount,
++                      unsigned long *vm_flags, int *is_vrange);
+ #define TTU_ACTION(x) ((x) & TTU_ACTION_MASK)
+@@ -249,9 +250,11 @@ int rmap_walk(struct page *page, int (*rmap_one)(struct page *,
+ static inline int page_referenced(struct page *page, int is_locked,
+                                 struct mem_cgroup *memcg,
+-                                unsigned long *vm_flags)
++                                unsigned long *vm_flags,
++                                int *is_vrange)
+ {
+       *vm_flags = 0;
++      *is_vrange = 0;
+       return 0;
+ }
+diff --git a/mm/ksm.c b/mm/ksm.c
+index b6afe0c..debc20c 100644
+--- a/mm/ksm.c
++++ b/mm/ksm.c
+@@ -1932,7 +1932,7 @@ again:
+                               continue;
+                       referenced += page_referenced_one(page, vma,
+-                              rmap_item->address, &mapcount, vm_flags);
++                              rmap_item->address, &mapcount, vm_flags, NULL);
+                       if (!search_new_forks || !mapcount)
+                               break;
+               }
+diff --git a/mm/rmap.c b/mm/rmap.c
+index 6280da8..007fc3b 100644
+--- a/mm/rmap.c
++++ b/mm/rmap.c
+@@ -57,6 +57,7 @@
+ #include <linux/migrate.h>
+ #include <linux/hugetlb.h>
+ #include <linux/backing-dev.h>
++#include <linux/vrange.h>
+ #include <asm/tlbflush.h>
+@@ -662,7 +663,7 @@ int page_mapped_in_vma(struct page *page, struct vm_area_struct *vma)
+  */
+ int page_referenced_one(struct page *page, struct vm_area_struct *vma,
+                       unsigned long address, unsigned int *mapcount,
+-                      unsigned long *vm_flags)
++                      unsigned long *vm_flags, int *is_vrange)
+ {
+       struct mm_struct *mm = vma->vm_mm;
+       int referenced = 0;
+@@ -724,6 +725,11 @@ int page_referenced_one(struct page *page, struct vm_area_struct *vma,
+                               referenced++;
+               }
+               pte_unmap_unlock(pte, ptl);
++              if (is_vrange && vrange_addr_volatile(vma, address)) {
++                      *is_vrange = 1;
++                      *mapcount = 0; /* break ealry from loop */
++                      goto out;
++              }
+       }
+       (*mapcount)--;
+@@ -736,7 +742,7 @@ out:
+ static int page_referenced_anon(struct page *page,
+                               struct mem_cgroup *memcg,
+-                              unsigned long *vm_flags)
++                              unsigned long *vm_flags, int *is_vrange)
+ {
+       unsigned int mapcount;
+       struct anon_vma *anon_vma;
+@@ -761,7 +767,8 @@ static int page_referenced_anon(struct page *page,
+               if (memcg && !mm_match_cgroup(vma->vm_mm, memcg))
+                       continue;
+               referenced += page_referenced_one(page, vma, address,
+-                                                &mapcount, vm_flags);
++                                                &mapcount, vm_flags,
++                                                is_vrange);
+               if (!mapcount)
+                       break;
+       }
+@@ -785,7 +792,7 @@ static int page_referenced_anon(struct page *page,
+  */
+ static int page_referenced_file(struct page *page,
+                               struct mem_cgroup *memcg,
+-                              unsigned long *vm_flags)
++                              unsigned long *vm_flags, int *is_vrange)
+ {
+       unsigned int mapcount;
+       struct address_space *mapping = page->mapping;
+@@ -826,7 +833,8 @@ static int page_referenced_file(struct page *page,
+               if (memcg && !mm_match_cgroup(vma->vm_mm, memcg))
+                       continue;
+               referenced += page_referenced_one(page, vma, address,
+-                                                &mapcount, vm_flags);
++                                                &mapcount, vm_flags,
++                                                is_vrange);
+               if (!mapcount)
+                       break;
+       }
+@@ -841,6 +849,7 @@ static int page_referenced_file(struct page *page,
+  * @is_locked: caller holds lock on the page
+  * @memcg: target memory cgroup
+  * @vm_flags: collect encountered vma->vm_flags who actually referenced the page
++ * @is_vrange: Is @page in vrange?
+  *
+  * Quick test_and_clear_referenced for all mappings to a page,
+  * returns the number of ptes which referenced the page.
+@@ -848,7 +857,8 @@ static int page_referenced_file(struct page *page,
+ int page_referenced(struct page *page,
+                   int is_locked,
+                   struct mem_cgroup *memcg,
+-                  unsigned long *vm_flags)
++                  unsigned long *vm_flags,
++                  int *is_vrange)
+ {
+       int referenced = 0;
+       int we_locked = 0;
+@@ -867,10 +877,12 @@ int page_referenced(struct page *page,
+                                                               vm_flags);
+               else if (PageAnon(page))
+                       referenced += page_referenced_anon(page, memcg,
+-                                                              vm_flags);
++                                                              vm_flags,
++                                                              is_vrange);
+               else if (page->mapping)
+                       referenced += page_referenced_file(page, memcg,
+-                                                              vm_flags);
++                                                              vm_flags,
++                                                              is_vrange);
+               if (we_locked)
+                       unlock_page(page);
+diff --git a/mm/vmscan.c b/mm/vmscan.c
+index 7dbdb6a..d039e30 100644
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -43,6 +43,7 @@
+ #include <linux/sysctl.h>
+ #include <linux/oom.h>
+ #include <linux/prefetch.h>
++#include <linux/vrange.h>
+ #include <asm/tlbflush.h>
+ #include <asm/div64.h>
+@@ -612,17 +613,19 @@ enum page_references {
+       PAGEREF_RECLAIM,
+       PAGEREF_RECLAIM_CLEAN,
+       PAGEREF_KEEP,
++      PAGEREF_DISCARD,
+       PAGEREF_ACTIVATE,
+ };
+ static enum page_references page_check_references(struct page *page,
+                                                 struct scan_control *sc)
+ {
++      int is_vrange = 0;
+       int referenced_ptes, referenced_page;
+       unsigned long vm_flags;
+       referenced_ptes = page_referenced(page, 1, sc->target_mem_cgroup,
+-                                        &vm_flags);
++                                        &vm_flags, &is_vrange);
+       referenced_page = TestClearPageReferenced(page);
+       /*
+@@ -632,6 +635,13 @@ static enum page_references page_check_references(struct page *page,
+       if (vm_flags & VM_LOCKED)
+               return PAGEREF_RECLAIM;
++      /*
++       * If volatile page is reached on LRU's tail, we discard the
++       * page without considering recycle the page.
++       */
++      if (is_vrange)
++              return PAGEREF_DISCARD;
++
+       if (referenced_ptes) {
+               if (PageSwapBacked(page))
+                       return PAGEREF_ACTIVATE;
+@@ -770,6 +780,9 @@ static unsigned long shrink_page_list(struct list_head *page_list,
+                       goto activate_locked;
+               case PAGEREF_KEEP:
+                       goto keep_locked;
++              case PAGEREF_DISCARD:
++                      if (may_enter_fs && !discard_vpage(page))
++                              goto free_it;
+               case PAGEREF_RECLAIM:
+               case PAGEREF_RECLAIM_CLEAN:
+                       ; /* try to reclaim the page below */
+@@ -1499,7 +1512,7 @@ static void shrink_active_list(unsigned long nr_to_scan,
+               }
+               if (page_referenced(page, 0, sc->target_mem_cgroup,
+-                                  &vm_flags)) {
++                                  &vm_flags, NULL)) {
+                       nr_rotated += hpage_nr_pages(page);
+                       /*
+                        * Identify referenced, file-backed active pages and
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0821-vrange-Send-SIGBUS-when-user-try-to-access-purged-pa.patch b/patches.tizen/0821-vrange-Send-SIGBUS-when-user-try-to-access-purged-pa.patch
new file mode 100644 (file)
index 0000000..108084b
--- /dev/null
@@ -0,0 +1,274 @@
+From 8ca632a6d423c315aa281b330b0f558e1123e948 Mon Sep 17 00:00:00 2001
+From: Minchan Kim <minchan@kernel.org>
+Date: Thu, 25 Jul 2013 13:44:38 +0900
+Subject: [PATCH 0821/1302] vrange: Send SIGBUS when user try to access purged
+ page
+
+By vrange(2) semantic, a user should see SIGBUG if they try to
+access purged page without marking the memory as non-voaltile
+(ie, vrange(...VRANGE_NOVOLATILE)).
+
+This allows for optimistic traversal of volatile pages, without
+having to mark them non-volatile first and the SIGBUS allows
+applications to trap and fixup the purged range before accessing
+them again.
+
+This patch implements it by adding SWP_VRANGE so it consumes one
+from MAX_SWAPFILES. It means worst case of MAX_SWAPFILES in 32 bit
+is 32 - 2 - 1 - 1 = 28. I think it's still enough for everybody.
+If someone complain about that and we shouldn't consume it,
+I will change it with (swp_type 0, pgoffset 0) which is header of swap
+which couldn't be allocated as swp_pte for swapout so we can use it.
+
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Android Kernel Team <kernel-team@android.com>
+Cc: Robert Love <rlove@google.com>
+Cc: Mel Gorman <mel@csn.ul.ie>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Dave Hansen <dave@linux.vnet.ibm.com>
+Cc: Rik van Riel <riel@redhat.com>
+Cc: Dmitry Adamushko <dmitry.adamushko@gmail.com>
+Cc: Dave Chinner <david@fromorbit.com>
+Cc: Neil Brown <neilb@suse.de>
+Cc: Andrea Righi <andrea@betterlinux.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+Cc: Mike Hommey <mh@glandium.org>
+Cc: Taras Glek <tglek@mozilla.com>
+Cc: Dhaval Giani <dgiani@mozilla.com>
+Cc: Jan Kara <jack@suse.cz>
+Cc: KOSAKI Motohiro <kosaki.motohiro@gmail.com>
+Cc: Michel Lespinasse <walken@google.com>
+Cc: linux-mm@kvack.org <linux-mm@kvack.org>
+Signed-off-by: Minchan Kim <minchan@kernel.org>
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/swap.h   |  6 +++++-
+ include/linux/vrange.h | 20 ++++++++++++++++++++
+ mm/memory.c            | 27 +++++++++++++++++++++++++++
+ mm/mincore.c           |  5 ++++-
+ mm/vrange.c            | 20 +++++++++++++++++++-
+ 5 files changed, 75 insertions(+), 3 deletions(-)
+
+diff --git a/include/linux/swap.h b/include/linux/swap.h
+index 1701ce4..8b4265a 100644
+--- a/include/linux/swap.h
++++ b/include/linux/swap.h
+@@ -45,6 +45,9 @@ static inline int current_is_kswapd(void)
+  * actions on faults.
+  */
++#define SWP_VRANGE_NUM 1
++#define SWP_VRANGE    (MAX_SWAPFILES + SWP_HWPOISON_NUM + SWP_MIGRATION_NUM)
++
+ /*
+  * NUMA node memory migration support
+  */
+@@ -67,7 +70,8 @@ static inline int current_is_kswapd(void)
+ #endif
+ #define MAX_SWAPFILES \
+-      ((1 << MAX_SWAPFILES_SHIFT) - SWP_MIGRATION_NUM - SWP_HWPOISON_NUM)
++      ((1 << MAX_SWAPFILES_SHIFT) - SWP_MIGRATION_NUM - SWP_HWPOISON_NUM \
++                      - SWP_VRANGE_NUM)
+ /*
+  * Magic header for a swap area. The first part of the union is
+diff --git a/include/linux/vrange.h b/include/linux/vrange.h
+index b18c31a..b14d054 100644
+--- a/include/linux/vrange.h
++++ b/include/linux/vrange.h
+@@ -3,6 +3,8 @@
+ #include <linux/vrange_types.h>
+ #include <linux/mm.h>
++#include <linux/swap.h>
++#include <linux/swapops.h>
+ #define vrange_from_node(node_ptr) \
+       container_of(node_ptr, struct vrange, node)
+@@ -12,6 +14,16 @@
+ #ifdef CONFIG_MMU
++static inline swp_entry_t make_vrange_entry(void)
++{
++      return swp_entry(SWP_VRANGE, 0);
++}
++
++static inline int is_vrange_entry(swp_entry_t entry)
++{
++      return swp_type(entry) == SWP_VRANGE;
++}
++
+ static inline void vrange_root_init(struct vrange_root *vroot, int type)
+ {
+       vroot->type = type;
+@@ -42,6 +54,9 @@ extern int vrange_fork(struct mm_struct *new,
+ int discard_vpage(struct page *page);
+ bool vrange_addr_volatile(struct vm_area_struct *vma, unsigned long addr);
++extern bool vrange_addr_purged(struct vm_area_struct *vma,
++                                      unsigned long address);
++
+ #else
+ static inline void vrange_root_init(struct vrange_root *vroot, int type) {};
+@@ -57,5 +72,10 @@ static inline bool vrange_addr_volatile(struct vm_area_struct *vma,
+       return false;
+ }
+ static inline int discard_vpage(struct page *page) { return 0 };
++static inline bool vrange_addr_purged(struct vm_area_struct *vma,
++                                      unsigned long address)
++{
++      return false;
++};
+ #endif
+ #endif /* _LINIUX_VRANGE_H */
+diff --git a/mm/memory.c b/mm/memory.c
+index 4b60011..0cd9345 100644
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -59,6 +59,7 @@
+ #include <linux/gfp.h>
+ #include <linux/migrate.h>
+ #include <linux/string.h>
++#include <linux/vrange.h>
+ #include <asm/io.h>
+ #include <asm/pgalloc.h>
+@@ -833,6 +834,8 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
+       if (unlikely(!pte_present(pte))) {
+               if (!pte_file(pte)) {
+                       swp_entry_t entry = pte_to_swp_entry(pte);
++                      if (is_vrange_entry(entry))
++                              goto out_set_pte;
+                       if (swap_duplicate(entry) < 0)
+                               return entry.val;
+@@ -1173,6 +1176,8 @@ again:
+                               print_bad_pte(vma, addr, ptent, NULL);
+               } else {
+                       swp_entry_t entry = pte_to_swp_entry(ptent);
++                      if (is_vrange_entry(entry))
++                              goto out;
+                       if (!non_swap_entry(entry))
+                               rss[MM_SWAPENTS]--;
+@@ -1189,6 +1194,7 @@ again:
+                       if (unlikely(!free_swap_and_cache(entry)))
+                               print_bad_pte(vma, addr, ptent, NULL);
+               }
++out:
+               pte_clear_not_present_full(mm, addr, pte, tlb->fullmm);
+       } while (pte++, addr += PAGE_SIZE, addr != end);
+@@ -3699,15 +3705,36 @@ int handle_pte_fault(struct mm_struct *mm,
+       entry = *pte;
+       if (!pte_present(entry)) {
++              swp_entry_t vrange_entry;
++
+               if (pte_none(entry)) {
+                       if (vma->vm_ops) {
+                               if (likely(vma->vm_ops->fault))
+                                       return do_linear_fault(mm, vma, address,
+                                               pte, pmd, flags, entry);
+                       }
++anon:
+                       return do_anonymous_page(mm, vma, address,
+                                                pte, pmd, flags);
+               }
++
++              vrange_entry = pte_to_swp_entry(entry);
++              if (unlikely(is_vrange_entry(vrange_entry))) {
++                      if (!vrange_addr_purged(vma, address)) {
++                              /* zap pte */
++                              ptl = pte_lockptr(mm, pmd);
++                              spin_lock(ptl);
++                              if (unlikely(!pte_same(*pte, entry)))
++                                      goto unlock;
++                              flush_cache_page(vma, address, pte_pfn(*pte));
++                              ptep_clear_flush(vma, address, pte);
++                              pte_unmap_unlock(pte, ptl);
++                              goto anon;
++                      }
++
++                      return VM_FAULT_SIGBUS;
++              }
++
+               if (pte_file(entry))
+                       return do_nonlinear_fault(mm, vma, address,
+                                       pte, pmd, flags, entry);
+diff --git a/mm/mincore.c b/mm/mincore.c
+index da2be56..2a95eef 100644
+--- a/mm/mincore.c
++++ b/mm/mincore.c
+@@ -15,6 +15,7 @@
+ #include <linux/swap.h>
+ #include <linux/swapops.h>
+ #include <linux/hugetlb.h>
++#include <linux/vrange.h>
+ #include <asm/uaccess.h>
+ #include <asm/pgtable.h>
+@@ -129,7 +130,9 @@ static void mincore_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
+               } else { /* pte is a swap entry */
+                       swp_entry_t entry = pte_to_swp_entry(pte);
+-                      if (is_migration_entry(entry)) {
++                      if (is_vrange_entry(entry))
++                              *vec = 0;
++                      else if (is_migration_entry(entry)) {
+                               /* migration entries are always uptodate */
+                               *vec = 1;
+                       } else {
+diff --git a/mm/vrange.c b/mm/vrange.c
+index 2ae91e3..bb87768 100644
+--- a/mm/vrange.c
++++ b/mm/vrange.c
+@@ -10,7 +10,6 @@
+ #include <linux/rmap.h>
+ #include <linux/hugetlb.h>
+ #include "internal.h"
+-#include <linux/swap.h>
+ #include <linux/mmu_notifier.h>
+ static struct kmem_cache *vrange_cachep;
+@@ -431,6 +430,24 @@ bool vrange_addr_volatile(struct vm_area_struct *vma, unsigned long addr)
+       return ret;
+ }
++bool vrange_addr_purged(struct vm_area_struct *vma, unsigned long addr)
++{
++      struct vrange_root *vroot;
++      struct vrange *range;
++      unsigned long vstart_idx;
++      bool ret = false;
++
++      vroot = __vma_to_vroot(vma);
++      vstart_idx = __vma_addr_to_index(vma, addr);
++
++      vrange_lock(vroot);
++      range = __vrange_find(vroot, vstart_idx, vstart_idx + PAGE_SIZE - 1);
++      if (range && range->purged)
++              ret = true;
++      vrange_unlock(vroot);
++      return ret;
++}
++
+ /* Caller should hold vrange_lock */
+ static void do_purge(struct vrange_root *vroot,
+               unsigned long start_idx, unsigned long end_idx)
+@@ -474,6 +491,7 @@ static void try_to_discard_one(struct vrange_root *vroot, struct page *page,
+       page_remove_rmap(page);
+       page_cache_release(page);
++      set_pte_at(mm, addr, pte, swp_entry_to_pte(make_vrange_entry()));
+       pte_unmap_unlock(pte, ptl);
+       mmu_notifier_invalidate_page(mm, addr);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0822-vrange-Allocate-vroot-dynamically.patch b/patches.tizen/0822-vrange-Allocate-vroot-dynamically.patch
new file mode 100644 (file)
index 0000000..141fad6
--- /dev/null
@@ -0,0 +1,565 @@
+From baf10e747aa6c0022d97f934e1ec7023823b3a02 Mon Sep 17 00:00:00 2001
+From: Minchan Kim <minchan@kernel.org>
+Date: Thu, 25 Jul 2013 13:44:41 +0900
+Subject: [PATCH 0822/1302] vrange: Allocate vroot dynamically
+
+This patch allocates vroot dynamically when vrange syscall is called
+so if anybody doesn't call vrange syscall, we don't waste memory space
+occupied by vroot.
+
+The vroot is allocated by SLAB_DESTROY_BY_RCU because we can't
+gauarantee vroot's validity we we about to access vroot of B process
+conext from A process's one so the rule is following as.
+
+1. rcu_read_lock
+2. checkt vroot == NULL
+3. get vroot's refcount
+4. rcu_read_unlock
+5. vrange_lock(vroot)
+6. get vrange from tree
+7. vrange->owenr == vroot check again because vroot can be allocated
+   for another one in same RCU period.
+
+XXX: ? Squish most of this down into mm and mapping vroot addition patches?
+XXX: Review RCU bits
+
+Signed-off-by: Minchan Kim <minchan@kernel.org>
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/inode.c                   |   4 +-
+ include/linux/fs.h           |   2 +-
+ include/linux/mm_types.h     |   2 +-
+ include/linux/vrange_types.h |   1 +
+ kernel/fork.c                |   5 +-
+ mm/mmap.c                    |   2 +-
+ mm/vrange.c                  | 258 ++++++++++++++++++++++++++++++++++++++++---
+ 7 files changed, 251 insertions(+), 23 deletions(-)
+
+diff --git a/fs/inode.c b/fs/inode.c
+index a4a6844..c9f5a57 100644
+--- a/fs/inode.c
++++ b/fs/inode.c
+@@ -351,7 +351,6 @@ void address_space_init_once(struct address_space *mapping)
+       spin_lock_init(&mapping->private_lock);
+       mapping->i_mmap = RB_ROOT;
+       INIT_LIST_HEAD(&mapping->i_mmap_nonlinear);
+-      vrange_root_init(&mapping->vroot, VRANGE_FILE);
+ }
+ EXPORT_SYMBOL(address_space_init_once);
+@@ -1419,7 +1418,8 @@ static void iput_final(struct inode *inode)
+               inode_lru_list_del(inode);
+       spin_unlock(&inode->i_lock);
+-      vrange_root_cleanup(&inode->i_mapping->vroot);
++      vrange_root_cleanup(inode->i_mapping->vroot);
++      inode->i_mapping->vroot = NULL;
+       evict(inode);
+ }
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 925714d..b9218a7 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -413,7 +413,7 @@ struct address_space {
+       struct list_head        i_mmap_nonlinear;/*list VM_NONLINEAR mappings */
+       struct mutex            i_mmap_mutex;   /* protect tree, count, list */
+ #ifdef CONFIG_MMU
+-      struct vrange_root      vroot;
++      struct vrange_root      *vroot;
+ #endif
+       /* Protected by tree_lock together with the radix tree */
+       unsigned long           nrpages;        /* number of total pages */
+diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
+index 7e14abd..ec5aedb 100644
+--- a/include/linux/mm_types.h
++++ b/include/linux/mm_types.h
+@@ -354,7 +354,7 @@ struct mm_struct {
+ #ifdef CONFIG_MMU
+-      struct vrange_root vroot;
++      struct vrange_root *vroot;
+ #endif
+       unsigned long hiwater_rss;      /* High-watermark of RSS usage */
+       unsigned long hiwater_vm;       /* High-water virtual memory usage */
+diff --git a/include/linux/vrange_types.h b/include/linux/vrange_types.h
+index 3579983..cadb37e 100644
+--- a/include/linux/vrange_types.h
++++ b/include/linux/vrange_types.h
+@@ -13,6 +13,7 @@ struct vrange_root {
+       struct rb_root v_rb;            /* vrange rb tree */
+       struct mutex v_lock;            /* Protect v_rb */
+       enum vrange_type type;          /* range root type */
++      atomic_t refcount;
+ };
+ struct vrange {
+diff --git a/kernel/fork.c b/kernel/fork.c
+index 88f5b9f..2e53bf6 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -547,9 +547,9 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p)
+               (current->mm->flags & MMF_INIT_MASK) : default_dump_filter;
+       mm->core_state = NULL;
+       mm->nr_ptes = 0;
++      mm->vroot = NULL;
+       memset(&mm->rss_stat, 0, sizeof(mm->rss_stat));
+       spin_lock_init(&mm->page_table_lock);
+-      vrange_root_init(&mm->vroot, VRANGE_MM);
+       mm->free_area_cache = TASK_UNMAPPED_BASE;
+       mm->cached_hole_size = ~0UL;
+       mm_init_aio(mm);
+@@ -623,7 +623,8 @@ void mmput(struct mm_struct *mm)
+       if (atomic_dec_and_test(&mm->mm_users)) {
+               uprobe_clear_state(mm);
+-              vrange_root_cleanup(&mm->vroot);
++              vrange_root_cleanup(mm->vroot);
++              mm->vroot = NULL;
+               exit_aio(mm);
+               ksm_exit(mm);
+               khugepaged_exit(mm); /* must run before exit_mmap */
+diff --git a/mm/mmap.c b/mm/mmap.c
+index 3d130b9..8c23c29 100644
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -1503,7 +1503,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
+ munmap_back:
+       /* zap any volatile ranges */
+-      vrange_clear(&mm->vroot, addr, addr + len);
++      vrange_clear(mm->vroot, addr, addr + len);
+       if (find_vma_links(mm, addr, addr + len, &prev, &rb_link, &rb_parent)) {
+               if (do_munmap(mm, addr, len))
+diff --git a/mm/vrange.c b/mm/vrange.c
+index bb87768..0ddece7 100644
+--- a/mm/vrange.c
++++ b/mm/vrange.c
+@@ -13,15 +13,169 @@
+ #include <linux/mmu_notifier.h>
+ static struct kmem_cache *vrange_cachep;
++static struct kmem_cache *vroot_cachep;
+ static int __init vrange_init(void)
+ {
++      vroot_cachep = kmem_cache_create("vrange_root",
++                              sizeof(struct vrange_root), 0,
++                              SLAB_DESTROY_BY_RCU|SLAB_PANIC, NULL);
+       vrange_cachep = KMEM_CACHE(vrange, SLAB_PANIC);
+       return 0;
+ }
+-
+ module_init(vrange_init);
++static struct vrange_root *__vroot_alloc(gfp_t flags)
++{
++      struct vrange_root *vroot = kmem_cache_alloc(vroot_cachep, flags);
++      if (!vroot)
++              return vroot;
++
++      atomic_set(&vroot->refcount, 1);
++      return vroot;
++}
++
++static inline int __vroot_get(struct vrange_root *vroot)
++{
++      if (!atomic_inc_not_zero(&vroot->refcount))
++              return 0;
++
++      return 1;
++}
++
++static inline void __vroot_put(struct vrange_root *vroot)
++{
++      if (atomic_dec_and_test(&vroot->refcount)) {
++              WARN_ON(!RB_EMPTY_ROOT(&vroot->v_rb));
++              kmem_cache_free(vroot_cachep, vroot);
++      }
++}
++
++static bool __vroot_init_mm(struct vrange_root *vroot, struct mm_struct *mm)
++{
++      bool ret = false;
++
++      spin_lock(&mm->page_table_lock);
++      if (!mm->vroot) {
++              mm->vroot = vroot;
++              vrange_root_init(mm->vroot, VRANGE_MM);
++              atomic_inc(&mm->mm_count);
++              ret = true;
++      }
++      spin_unlock(&mm->page_table_lock);
++
++      return ret;
++}
++
++static bool __vroot_init_mapping(struct vrange_root *vroot,
++                                              struct address_space *mapping)
++{
++      bool ret = false;
++
++      mutex_lock(&mapping->i_mmap_mutex);
++      if (!mapping->vroot) {
++              mapping->vroot = vroot;
++              vrange_root_init(mapping->vroot, VRANGE_FILE);
++              /* XXX - inc ref count on mapping? */
++              ret = true;
++      }
++      mutex_unlock(&mapping->i_mmap_mutex);
++
++      return ret;
++}
++
++static struct vrange_root *vroot_alloc_mm_get(struct mm_struct *mm)
++{
++      struct vrange_root *ret, *allocated;
++
++      ret = NULL;
++      allocated = __vroot_alloc(GFP_NOFS);
++      if (!allocated)
++              return NULL;
++
++      if (__vroot_init_mm(allocated, mm)){
++              ret = allocated;
++              allocated = NULL;
++      }
++
++      if(ret && !__vroot_get(ret))
++              ret = NULL;
++
++      if (allocated)
++              __vroot_put(allocated);
++
++      return ret;
++}
++
++static struct vrange_root *vroot_alloc_get_vma(struct vm_area_struct *vma)
++{
++      struct vrange_root *ret, *allocated;
++      bool val;
++
++      ret = NULL;
++      allocated = __vroot_alloc(GFP_NOFS);
++      if (!allocated)
++              return NULL;
++
++      if (vma->vm_file && (vma->vm_flags & VM_SHARED))
++              val = __vroot_init_mapping(allocated, vma->vm_file->f_mapping);
++      else
++              val = __vroot_init_mm(allocated, vma->vm_mm);
++
++      if (val) {
++              ret = allocated;
++              allocated = NULL;
++      }
++
++      if(ret && !__vroot_get(ret))
++              ret = NULL;
++
++      if (allocated)
++              __vroot_put(allocated);
++
++      return ret;
++}
++
++static struct vrange_root *vrange_get_vroot(struct vrange *vrange)
++{
++      struct vrange_root *vroot;
++      struct vrange_root *ret = NULL;
++
++      rcu_read_lock();
++      /*
++       * Prevent compiler from re-fetching vrange->owner while others
++       * clears vrange->owner.
++       */
++      vroot = ACCESS_ONCE(vrange->owner);
++      if (!vroot)
++              goto out;
++
++      /*
++       * vroot couldn't be destroyed while we're holding rcu_read_lock
++       * so it's okay to access vroot
++       */
++      if (!__vroot_get(vroot))
++              goto out;
++
++
++      /* If we reach here, vroot is either ours or others because
++       * vroot could be allocated for othres in same RCU period
++       * so we should check it carefully. For free/reallocating
++       * for others, all vranges from vroot->tree should be detached
++       * firstly right before vroot freeing so if we check vrange->owner
++       * isn't NULL, it means vroot is ours.
++       */
++      smp_rmb();
++      if (!vrange->owner) {
++              __vroot_put(vroot);
++              goto out;
++      }
++      ret = vroot;
++out:
++      rcu_read_unlock();
++      return ret;
++}
++
+ static struct vrange *__vrange_alloc(gfp_t flags)
+ {
+       struct vrange *vrange = kmem_cache_alloc(vrange_cachep, flags);
+@@ -61,12 +215,14 @@ static inline void __vrange_set(struct vrange *range,
+ static inline void __vrange_resize(struct vrange *range,
+               unsigned long start_idx, unsigned long end_idx)
+ {
+-      struct vrange_root *vroot = range->owner;
++      struct vrange_root *vroot;
+       bool purged = range->purged;
++      vroot = vrange_get_vroot(range);
+       __vrange_remove(range);
+       __vrange_set(range, start_idx, end_idx, purged);
+       __vrange_add(range, vroot);
++      __vroot_put(vroot);
+ }
+ static struct vrange *__vrange_find(struct vrange_root *vroot,
+@@ -130,6 +286,9 @@ static int vrange_remove(struct vrange_root *vroot,
+       struct interval_tree_node *node, *next;
+       bool used_new = false;
++      if (!vroot)
++              return 0;
++
+       if (!purged)
+               return -EINVAL;
+@@ -200,6 +359,9 @@ void vrange_root_cleanup(struct vrange_root *vroot)
+       struct vrange *range;
+       struct rb_node *node;
++      if (vroot == NULL)
++              return;
++
+       vrange_lock(vroot);
+       /* We should remove node by post-order traversal */
+       while ((node = rb_first(&vroot->v_rb))) {
+@@ -208,6 +370,12 @@ void vrange_root_cleanup(struct vrange_root *vroot)
+               __vrange_free(range);
+       }
+       vrange_unlock(vroot);
++      /*
++       * Before removing vroot, we should make sure range-owner
++       * should be NULL. See the smp_rmb of vrange_get_vroot.
++       */
++      smp_wmb();
++      __vroot_put(vroot);
+ }
+ /*
+@@ -215,6 +383,7 @@ void vrange_root_cleanup(struct vrange_root *vroot)
+  * can't have copied own vrange data structure so that pages in the
+  * vrange couldn't be purged. It would be better rather than failing
+  * fork.
++ * The down_write of both mm->mmap_sem protects mm->vroot race.
+  */
+ int vrange_fork(struct mm_struct *new_mm, struct mm_struct *old_mm)
+ {
+@@ -222,8 +391,17 @@ int vrange_fork(struct mm_struct *new_mm, struct mm_struct *old_mm)
+       struct vrange *range, *new_range;
+       struct rb_node *next;
+-      new = &new_mm->vroot;
+-      old = &old_mm->vroot;
++      if (!old_mm->vroot)
++              return 0;
++
++      new = vroot_alloc_mm_get(new_mm);
++      if (!new)
++              return -ENOMEM;
++
++      old = old_mm->vroot;
++
++      if (!__vroot_get(old))
++              goto fail_old;
+       vrange_lock(old);
+       next = rb_first(&old->v_rb);
+@@ -244,21 +422,36 @@ int vrange_fork(struct mm_struct *new_mm, struct mm_struct *old_mm)
+       }
+       vrange_unlock(old);
++      __vroot_put(old);
++      __vroot_put(new);
++
+       return 0;
+ fail:
+       vrange_unlock(old);
++      __vroot_put(old);
++fail_old:
++      __vroot_put(new);
+       vrange_root_cleanup(new);
+-      return 0;
++      return -ENOMEM;
+ }
+-static inline struct vrange_root *__vma_to_vroot(struct vm_area_struct *vma)
++static inline struct vrange_root *__vma_to_vroot_get(struct vm_area_struct *vma)
+ {
+       struct vrange_root *vroot = NULL;
++      rcu_read_lock();
+       if (vma->vm_file && (vma->vm_flags & VM_SHARED))
+-              vroot = &vma->vm_file->f_mapping->vroot;
++              vroot = vma->vm_file->f_mapping->vroot;
+       else
+-              vroot = &vma->vm_mm->vroot;
++              vroot = vma->vm_mm->vroot;
++
++      if (!vroot)
++              goto out;
++
++      if (!__vroot_get(vroot))
++              vroot = NULL;
++out:
++      rcu_read_unlock();
+       return vroot;
+ }
+@@ -303,7 +496,12 @@ static ssize_t do_vrange(struct mm_struct *mm, unsigned long start_idx,
+               if (end_idx < tmp)
+                       tmp = end_idx;
+-              vroot = __vma_to_vroot(vma);
++              vroot = __vma_to_vroot_get(vma);
++              if (!vroot)
++                      vroot = vroot_alloc_get_vma(vma);
++              if (!vroot)
++                      goto out;
++
+               vstart_idx = __vma_addr_to_index(vma, start_idx);
+               vend_idx = __vma_addr_to_index(vma, tmp);
+@@ -313,6 +511,7 @@ static ssize_t do_vrange(struct mm_struct *mm, unsigned long start_idx,
+               else if (mode == VRANGE_NONVOLATILE)
+                       ret = vrange_remove(vroot, vstart_idx, vend_idx,
+                                               purged);
++              __vroot_put(vroot);
+               if (ret)
+                       goto out;
+@@ -416,17 +615,30 @@ out:
+ bool vrange_addr_volatile(struct vm_area_struct *vma, unsigned long addr)
+ {
+       struct vrange_root *vroot;
++      struct vrange *vrange;
+       unsigned long vstart_idx, vend_idx;
+       bool ret = false;
+-      vroot = __vma_to_vroot(vma);
++      vroot = __vma_to_vroot_get(vma);
++      if (!vroot)
++              return ret;
++
+       vstart_idx = __vma_addr_to_index(vma, addr);
+       vend_idx = vstart_idx + PAGE_SIZE - 1;
+       vrange_lock(vroot);
+-      if (__vrange_find(vroot, vstart_idx, vend_idx))
+-              ret = true;
++      vrange = __vrange_find(vroot, vstart_idx, vend_idx);
++      if (vrange) {
++              /*
++               * vroot can be allocated for another process in
++               * same period so let's check vroot's stability
++               */
++              if (likely(vroot == vrange->owner))
++                      ret = true;
++      }
+       vrange_unlock(vroot);
++      __vroot_put(vroot);
++
+       return ret;
+ }
+@@ -437,7 +649,9 @@ bool vrange_addr_purged(struct vm_area_struct *vma, unsigned long addr)
+       unsigned long vstart_idx;
+       bool ret = false;
+-      vroot = __vma_to_vroot(vma);
++      vroot = __vma_to_vroot_get(vma);
++      if (!vroot)
++              return false;
+       vstart_idx = __vma_addr_to_index(vma, addr);
+       vrange_lock(vroot);
+@@ -445,6 +659,7 @@ bool vrange_addr_purged(struct vm_area_struct *vma, unsigned long addr)
+       if (range && range->purged)
+               ret = true;
+       vrange_unlock(vroot);
++      __vroot_put(vroot);
+       return ret;
+ }
+@@ -471,6 +686,7 @@ static void try_to_discard_one(struct vrange_root *vroot, struct page *page,
+       pte_t pteval;
+       spinlock_t *ptl;
++      VM_BUG_ON(!vroot);
+       VM_BUG_ON(!PageLocked(page));
+       pte = page_check_address(page, mm, addr, &ptl, 0);
+@@ -529,17 +745,21 @@ static int try_to_discard_anon_vpage(struct page *page)
+       anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root, pgoff, pgoff) {
+               vma = avc->vma;
+               mm = vma->vm_mm;
+-              vroot = &mm->vroot;
+-              address = vma_address(page, vma);
++              vroot = __vma_to_vroot_get(vma);
++              if (!vroot)
++                      continue;
++              address = vma_address(page, vma);
+               vrange_lock(vroot);
+               if (!__vrange_find(vroot, address, address + PAGE_SIZE - 1)) {
+                       vrange_unlock(vroot);
++                      __vroot_put(vroot);
+                       continue;
+               }
+               try_to_discard_one(vroot, page, vma, address);
+               vrange_unlock(vroot);
++              __vroot_put(vroot);
+       }
+       page_unlock_anon_vma_read(anon_vma);
+@@ -555,18 +775,24 @@ static int try_to_discard_file_vpage(struct page *page)
+       mutex_lock(&mapping->i_mmap_mutex);
+       vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) {
+               unsigned long address = vma_address(page, vma);
+-              struct vrange_root *vroot = &mapping->vroot;
++              struct vrange_root *vroot;
+               long vstart_idx;
++              vroot = __vma_to_vroot_get(vma);
++              if (!vroot)
++                      continue;
+               vstart_idx = __vma_addr_to_index(vma, address);
++
+               vrange_lock(vroot);
+               if (!__vrange_find(vroot, vstart_idx,
+                                       vstart_idx + PAGE_SIZE - 1)) {
+                       vrange_unlock(vroot);
++                      __vroot_put(vroot);
+                       continue;
+               }
+               try_to_discard_one(vroot, page, vma, address);
+               vrange_unlock(vroot);
++              __vroot_put(vroot);
+       }
+       mutex_unlock(&mapping->i_mmap_mutex);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0823-vrange-Add-vrange-LRU-list-for-purging.patch b/patches.tizen/0823-vrange-Add-vrange-LRU-list-for-purging.patch
new file mode 100644 (file)
index 0000000..448a075
--- /dev/null
@@ -0,0 +1,179 @@
+From 11fbac586d774c17de92a20fb44161b04453ad84 Mon Sep 17 00:00:00 2001
+From: Minchan Kim <minchan@kernel.org>
+Date: Thu, 25 Jul 2013 13:44:40 +0900
+Subject: [PATCH 0823/1302] vrange: Add vrange LRU list for purging
+
+This patch adds vrange LRU list for managing vranges to purge by
+something (In this implementation, I will use slab shrinker introduced
+by upcoming patches).
+We need something to purge vranges on swapless system because now VM
+does aging anon pages only if system has swap device.
+
+The reason why I select *vrange LRU* is that I see a purging unit as
+volatile range, NOT per-page so worset case is that all pages in a vrange
+can have much different age but purgic logic would have a tendency to
+discard all at once. It means userspace should divide a address range
+into same age's subpart to prevent other hotpages from discarding.
+The vrange system call's cost is very cheap so it(ie, multiple time
+calling of system call) shouldn't be a big problem.
+
+Signed-off-by: Minchan Kim <minchan@kernel.org>
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/vrange_types.h |  2 ++
+ mm/vrange.c                  | 61 ++++++++++++++++++++++++++++++++++++++++----
+ 2 files changed, 58 insertions(+), 5 deletions(-)
+
+diff --git a/include/linux/vrange_types.h b/include/linux/vrange_types.h
+index cadb37e..d1599ee 100644
+--- a/include/linux/vrange_types.h
++++ b/include/linux/vrange_types.h
+@@ -20,6 +20,8 @@ struct vrange {
+       struct interval_tree_node node;
+       struct vrange_root *owner;
+       int purged;
++      struct list_head lru;
++      atomic_t refcount;
+ };
+ #endif
+diff --git a/mm/vrange.c b/mm/vrange.c
+index 0ddece7..7af4584 100644
+--- a/mm/vrange.c
++++ b/mm/vrange.c
+@@ -15,8 +15,21 @@
+ static struct kmem_cache *vrange_cachep;
+ static struct kmem_cache *vroot_cachep;
++static struct vrange_list {
++      struct list_head list;
++      unsigned long size;
++      struct mutex lock;
++} vrange_list;
++
++static inline unsigned int vrange_size(struct vrange *range)
++{
++      return range->node.last + 1 - range->node.start;
++}
++
+ static int __init vrange_init(void)
+ {
++      INIT_LIST_HEAD(&vrange_list.list);
++      mutex_init(&vrange_list.lock);
+       vroot_cachep = kmem_cache_create("vrange_root",
+                               sizeof(struct vrange_root), 0,
+                               SLAB_DESTROY_BY_RCU|SLAB_PANIC, NULL);
+@@ -182,19 +195,56 @@ static struct vrange *__vrange_alloc(gfp_t flags)
+       if (!vrange)
+               return vrange;
+       vrange->owner = NULL;
++      INIT_LIST_HEAD(&vrange->lru);
++      atomic_set(&vrange->refcount, 1);
++
+       return vrange;
+ }
+ static void __vrange_free(struct vrange *range)
+ {
+       WARN_ON(range->owner);
++      WARN_ON(atomic_read(&range->refcount) != 0);
++      WARN_ON(!list_empty(&range->lru));
++
+       kmem_cache_free(vrange_cachep, range);
+ }
++static inline void __vrange_lru_add(struct vrange *range)
++{
++      mutex_lock(&vrange_list.lock);
++      WARN_ON(!list_empty(&range->lru));
++      list_add(&range->lru, &vrange_list.list);
++      vrange_list.size += vrange_size(range);
++      mutex_unlock(&vrange_list.lock);
++}
++
++static inline void __vrange_lru_del(struct vrange *range)
++{
++      mutex_lock(&vrange_list.lock);
++      if (!list_empty(&range->lru)) {
++              list_del_init(&range->lru);
++              vrange_list.size -= vrange_size(range);
++              WARN_ON(range->owner);
++      }
++      mutex_unlock(&vrange_list.lock);
++}
++
+ static void __vrange_add(struct vrange *range, struct vrange_root *vroot)
+ {
+       range->owner = vroot;
+       interval_tree_insert(&range->node, &vroot->v_rb);
++
++      WARN_ON(atomic_read(&range->refcount) <= 0);
++      __vrange_lru_add(range);
++}
++
++static inline void __vrange_put(struct vrange *range)
++{
++      if (atomic_dec_and_test(&range->refcount)) {
++              __vrange_lru_del(range);
++              __vrange_free(range);
++      }
+ }
+ static void __vrange_remove(struct vrange *range)
+@@ -220,6 +270,7 @@ static inline void __vrange_resize(struct vrange *range,
+       vroot = vrange_get_vroot(range);
+       __vrange_remove(range);
++      __vrange_lru_del(range);
+       __vrange_set(range, start_idx, end_idx, purged);
+       __vrange_add(range, vroot);
+       __vroot_put(vroot);
+@@ -257,7 +308,7 @@ static int vrange_add(struct vrange_root *vroot,
+               range = vrange_from_node(node);
+               /* old range covers new range fully */
+               if (node->start <= start_idx && node->last >= end_idx) {
+-                      __vrange_free(new_range);
++                      __vrange_put(new_range);
+                       goto out;
+               }
+@@ -266,7 +317,7 @@ static int vrange_add(struct vrange_root *vroot,
+               purged |= range->purged;
+               __vrange_remove(range);
+-              __vrange_free(range);
++              __vrange_put(range);
+               node = next;
+       }
+@@ -310,7 +361,7 @@ static int vrange_remove(struct vrange_root *vroot,
+               if (start_idx <= node->start && end_idx >= node->last) {
+                       /* argumented range covers the range fully */
+                       __vrange_remove(range);
+-                      __vrange_free(range);
++                      __vrange_put(range);
+               } else if (node->start >= start_idx) {
+                       /*
+                        * Argumented range covers over the left of the
+@@ -341,7 +392,7 @@ static int vrange_remove(struct vrange_root *vroot,
+       vrange_unlock(vroot);
+       if (!used_new)
+-              __vrange_free(new_range);
++              __vrange_put(new_range);
+       return 0;
+ }
+@@ -367,7 +418,7 @@ void vrange_root_cleanup(struct vrange_root *vroot)
+       while ((node = rb_first(&vroot->v_rb))) {
+               range = vrange_entry(node);
+               __vrange_remove(range);
+-              __vrange_free(range);
++              __vrange_put(range);
+       }
+       vrange_unlock(vroot);
+       /*
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0824-vrange-Add-vrange-shrinking-basic-functions-for-swap.patch b/patches.tizen/0824-vrange-Add-vrange-shrinking-basic-functions-for-swap.patch
new file mode 100644 (file)
index 0000000..b4a25d8
--- /dev/null
@@ -0,0 +1,174 @@
+From 660c620704b390e9f2433805c63debf336e8f005 Mon Sep 17 00:00:00 2001
+From: Minchan Kim <minchan@kernel.org>
+Date: Thu, 25 Jul 2013 13:44:42 +0900
+Subject: [PATCH 0824/1302] vrange: Add vrange shrinking basic functions for
+ swapless system
+
+This patch makes vrange works on swapless system by using slab
+shrinker.
+
+The reason I use shrinker is that Dave and Glauber are trying to
+make slab shrinker being aware of node/memcg so if the patchset
+reach on mainline, we also can support node/memcg in vrange, easily.
+
+Another reason I selected slab shrinker is that normally slab shrinker
+is called after normal reclaim of file-backed page(ex, page cache)
+so reclaiming preference would be this, I expect.(TODO: invstigate
+and might need more tunes in reclaim path)
+
+        page cache -> vrange by slab shrinking -> anon page
+
+It does make sense because page cache can have stream data so there is
+no point to shrink vrange pages if there are lots of streaming pages
+in page cache.
+
+In this version, I didn't check it works well but it's design concept
+so we can make it work via modify page reclaim path.
+I will have more experiment.
+
+One of disadvantage with using slab shrink is that slab shrinker isn't
+called in using memcg so memcg-noswap system cannot take advantage of it.
+Hmm, Maybe I will jump into relcaim code to hook some point to control
+vrange page shrinking more freely.
+
+XXX: isolate_vrange maybe should be vrange_isolate?
+XXX: Sanity check function names
+XXX: _vrange_get only has one user?
+
+Signed-off-by: Minchan Kim <minchan@kernel.org>
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ mm/vrange.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 91 insertions(+), 3 deletions(-)
+
+diff --git a/mm/vrange.c b/mm/vrange.c
+index 7af4584..b93d469 100644
+--- a/mm/vrange.c
++++ b/mm/vrange.c
+@@ -26,10 +26,19 @@ static inline unsigned int vrange_size(struct vrange *range)
+       return range->node.last + 1 - range->node.start;
+ }
++static int shrink_vrange(struct shrinker *s, struct shrink_control *sc);
++
++static struct shrinker vrange_shrinker = {
++      .shrink = shrink_vrange,
++      .seeks = DEFAULT_SEEKS
++};
++
+ static int __init vrange_init(void)
+ {
+       INIT_LIST_HEAD(&vrange_list.list);
+       mutex_init(&vrange_list.lock);
++
++      register_shrinker(&vrange_shrinker);
+       vroot_cachep = kmem_cache_create("vrange_root",
+                               sizeof(struct vrange_root), 0,
+                               SLAB_DESTROY_BY_RCU|SLAB_PANIC, NULL);
+@@ -213,9 +222,14 @@ static void __vrange_free(struct vrange *range)
+ static inline void __vrange_lru_add(struct vrange *range)
+ {
+       mutex_lock(&vrange_list.lock);
+-      WARN_ON(!list_empty(&range->lru));
+-      list_add(&range->lru, &vrange_list.list);
+-      vrange_list.size += vrange_size(range);
++      /*
++       * We need this check because it could be raced with
++       * shrink_vrange and vrange_resize
++       */
++      if (list_empty(&range->lru)) {
++              list_add(&range->lru, &vrange_list.list);
++              vrange_list.size += vrange_size(range);
++      }
+       mutex_unlock(&vrange_list.lock);
+ }
+@@ -239,6 +253,14 @@ static void __vrange_add(struct vrange *range, struct vrange_root *vroot)
+       __vrange_lru_add(range);
+ }
++static inline int __vrange_get(struct vrange *vrange)
++{
++      if (!atomic_inc_not_zero(&vrange->refcount))
++              return 0;
++
++      return 1;
++}
++
+ static inline void __vrange_put(struct vrange *range)
+ {
+       if (atomic_dec_and_test(&range->refcount)) {
+@@ -874,3 +896,69 @@ int discard_vpage(struct page *page)
+       return 1;
+ }
++
++static struct vrange *isolate_vrange(void)
++{
++      struct vrange *vrange = NULL;
++      mutex_lock(&vrange_list.lock);
++      while (!list_empty(&vrange_list.list)) {
++              vrange = list_entry(vrange_list.list.prev,
++                              struct vrange, lru);
++              list_del_init(&vrange->lru);
++              vrange_list.size -= vrange_size(vrange);
++
++              /* vrange is going to destroy */
++              if (__vrange_get(vrange))
++                      break;
++
++              vrange = NULL;
++      }
++
++      mutex_unlock(&vrange_list.lock);
++      return vrange;
++}
++
++static unsigned int discard_vrange(struct vrange *vrange)
++{
++      return 0;
++}
++
++static int shrink_vrange(struct shrinker *s, struct shrink_control *sc)
++{
++      struct vrange *range = NULL;
++      long nr_to_scan = sc->nr_to_scan;
++      long size = vrange_list.size;
++
++        /* current is dying so it will release memory soon */
++        if (fatal_signal_pending(current))
++                return -1;
++
++      if (!nr_to_scan)
++              return size;
++
++      if (sc->nr_to_scan && !(sc->gfp_mask & __GFP_IO))
++              return -1;
++
++      while (size > 0 && nr_to_scan > 0) {
++              range = isolate_vrange();
++              if (!range)
++                      break;
++
++              /* range is removing so don't bother */
++              if (!range->owner) {
++                      __vrange_put(range);
++                      size -= vrange_size(range);
++                      nr_to_scan -= vrange_size(range);
++                      continue;
++              }
++
++              if (discard_vrange(range) < 0)
++                      __vrange_lru_add(range);
++              __vrange_put(range);
++
++              size -= vrange_size(range);
++              nr_to_scan -= vrange_size(range);
++      }
++
++      return size;
++}
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0825-vrange-Purging-vrange-anon-pages-from-shrinker.patch b/patches.tizen/0825-vrange-Purging-vrange-anon-pages-from-shrinker.patch
new file mode 100644 (file)
index 0000000..a784341
--- /dev/null
@@ -0,0 +1,315 @@
+From 63ff0738faf0de2b2310c7bd1152d3178357ca8b Mon Sep 17 00:00:00 2001
+From: Minchan Kim <minchan@kernel.org>
+Date: Mon, 22 Jul 2013 15:18:19 +0900
+Subject: [PATCH 0825/1302] vrange: Purging vrange-anon pages from shrinker
+
+This patch supports purging anon-vrange pages from slab shrinker.
+
+XXX: This is super complicated code, and has a very short commit message
+XXX: Sanity check function names.
+XXX: Possibly split out vrange_root object addition into its own patch?
+
+Signed-off-by: Minchan Kim <minchan@kernel.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/vrange.h       |   7 +-
+ include/linux/vrange_types.h |   1 +
+ mm/vrange.c                  | 202 ++++++++++++++++++++++++++++++++++++++++++-
+ 3 files changed, 205 insertions(+), 5 deletions(-)
+
+diff --git a/include/linux/vrange.h b/include/linux/vrange.h
+index b14d054..b5cb7c8 100644
+--- a/include/linux/vrange.h
++++ b/include/linux/vrange.h
+@@ -24,11 +24,13 @@ static inline int is_vrange_entry(swp_entry_t entry)
+       return swp_type(entry) == SWP_VRANGE;
+ }
+-static inline void vrange_root_init(struct vrange_root *vroot, int type)
++static inline void vrange_root_init(struct vrange_root *vroot, int type,
++                                                              void *object)
+ {
+       vroot->type = type;
+       vroot->v_rb = RB_ROOT;
+       mutex_init(&vroot->v_lock);
++      vroot->object = object;
+ }
+ static inline void vrange_lock(struct vrange_root *vroot)
+@@ -59,7 +61,8 @@ extern bool vrange_addr_purged(struct vm_area_struct *vma,
+ #else
+-static inline void vrange_root_init(struct vrange_root *vroot, int type) {};
++static inline void vrange_root_init(struct vrange_root *vroot,
++                                      int type, void *obj) {};
+ static inline void vrange_root_cleanup(struct vrange_root *vroot) {};
+ static inline int vrange_fork(struct mm_struct *new, struct mm_struct *old)
+ {
+diff --git a/include/linux/vrange_types.h b/include/linux/vrange_types.h
+index d1599ee..e8c5f1f 100644
+--- a/include/linux/vrange_types.h
++++ b/include/linux/vrange_types.h
+@@ -14,6 +14,7 @@ struct vrange_root {
+       struct mutex v_lock;            /* Protect v_rb */
+       enum vrange_type type;          /* range root type */
+       atomic_t refcount;
++      void *object;                   /* mm_struct */
+ };
+ struct vrange {
+diff --git a/mm/vrange.c b/mm/vrange.c
+index b93d469..fad50c5 100644
+--- a/mm/vrange.c
++++ b/mm/vrange.c
+@@ -11,6 +11,8 @@
+ #include <linux/hugetlb.h>
+ #include "internal.h"
+ #include <linux/mmu_notifier.h>
++#include <linux/mm_inline.h>
++#include <linux/migrate.h>
+ static struct kmem_cache *vrange_cachep;
+ static struct kmem_cache *vroot_cachep;
+@@ -21,6 +23,11 @@ static struct vrange_list {
+       struct mutex lock;
+ } vrange_list;
++struct vrange_walker {
++      struct vm_area_struct *vma;
++      struct list_head *pagelist;
++};
++
+ static inline unsigned int vrange_size(struct vrange *range)
+ {
+       return range->node.last + 1 - range->node.start;
+@@ -68,6 +75,15 @@ static inline int __vroot_get(struct vrange_root *vroot)
+ static inline void __vroot_put(struct vrange_root *vroot)
+ {
+       if (atomic_dec_and_test(&vroot->refcount)) {
++              enum {VRANGE_MM, VRANGE_FILE} type = vroot->type;
++              if (type == VRANGE_MM) {
++                      struct mm_struct *mm = vroot->object;
++                      mmdrop(mm);
++              } else if (type == VRANGE_FILE) {
++                      /* TODO : */
++              } else
++                      BUG();
++
+               WARN_ON(!RB_EMPTY_ROOT(&vroot->v_rb));
+               kmem_cache_free(vroot_cachep, vroot);
+       }
+@@ -80,7 +96,7 @@ static bool __vroot_init_mm(struct vrange_root *vroot, struct mm_struct *mm)
+       spin_lock(&mm->page_table_lock);
+       if (!mm->vroot) {
+               mm->vroot = vroot;
+-              vrange_root_init(mm->vroot, VRANGE_MM);
++              vrange_root_init(mm->vroot, VRANGE_MM, mm);
+               atomic_inc(&mm->mm_count);
+               ret = true;
+       }
+@@ -97,7 +113,7 @@ static bool __vroot_init_mapping(struct vrange_root *vroot,
+       mutex_lock(&mapping->i_mmap_mutex);
+       if (!mapping->vroot) {
+               mapping->vroot = vroot;
+-              vrange_root_init(mapping->vroot, VRANGE_FILE);
++              vrange_root_init(mapping->vroot, VRANGE_FILE, mapping);
+               /* XXX - inc ref count on mapping? */
+               ret = true;
+       }
+@@ -918,11 +934,191 @@ static struct vrange *isolate_vrange(void)
+       return vrange;
+ }
+-static unsigned int discard_vrange(struct vrange *vrange)
++static unsigned int discard_vrange_pagelist(struct list_head *page_list)
+ {
++      struct page *page;
++      unsigned int nr_discard = 0;
++      LIST_HEAD(ret_pages);
++      LIST_HEAD(free_pages);
++
++      while (!list_empty(page_list)) {
++              int err;
++              page = list_entry(page_list->prev, struct page, lru);
++              list_del(&page->lru);
++              if (!trylock_page(page)) {
++                      list_add(&page->lru, &ret_pages);
++                      continue;
++              }
++
++              /*
++               * discard_vapge returns unlocked page if it
++               * is successful
++               */
++              err = discard_vpage(page);
++              if (err) {
++                      unlock_page(page);
++                      list_add(&page->lru, &ret_pages);
++                      continue;
++              }
++
++              ClearPageActive(page);
++              list_add(&page->lru, &free_pages);
++              dec_zone_page_state(page, NR_ISOLATED_ANON);
++              nr_discard++;
++      }
++
++      free_hot_cold_page_list(&free_pages, 1);
++      list_splice(&ret_pages, page_list);
++      return nr_discard;
++}
++
++static void vrange_pte_entry(pte_t pteval, unsigned long address,
++              unsigned ptent_size, struct mm_walk *walk)
++{
++      struct page *page;
++      struct vrange_walker *vw = walk->private;
++      struct vm_area_struct *vma = vw->vma;
++      struct list_head *pagelist = vw->pagelist;
++
++      if (pte_none(pteval))
++              return;
++
++      if (!pte_present(pteval))
++              return;
++
++      page = vm_normal_page(vma, address, pteval);
++      if (unlikely(!page))
++              return;
++
++      if (!PageLRU(page) || PageLocked(page))
++              return;
++
++      /* TODO : Support THP */
++      if (unlikely(PageCompound(page)))
++              return;
++
++      if (isolate_lru_page(page))
++              return;
++
++      list_add(&page->lru, pagelist);
++
++      VM_BUG_ON(page_is_file_cache(page));
++      inc_zone_page_state(page, NR_ISOLATED_ANON);
++}
++
++static int vrange_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
++              struct mm_walk *walk)
++{
++      pte_t *pte;
++      spinlock_t *ptl;
++
++      pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl);
++      for (; addr != end; pte++, addr += PAGE_SIZE)
++              vrange_pte_entry(*pte, addr, PAGE_SIZE, walk);
++      pte_unmap_unlock(pte - 1, ptl);
++      cond_resched();
++
+       return 0;
+ }
++static unsigned int discard_vma_pages(struct mm_struct *mm,
++              struct vm_area_struct *vma, unsigned long start,
++              unsigned long end)
++{
++      unsigned int ret = 0;
++      LIST_HEAD(pagelist);
++      struct vrange_walker vw;
++      struct mm_walk vrange_walk = {
++              .pmd_entry = vrange_pte_range,
++              .mm = vma->vm_mm,
++              .private = &vw,
++      };
++
++      vw.pagelist = &pagelist;
++      vw.vma = vma;
++
++      walk_page_range(start, end, &vrange_walk);
++
++      if (!list_empty(&pagelist))
++              ret = discard_vrange_pagelist(&pagelist);
++
++      putback_lru_pages(&pagelist);
++      return ret;
++}
++
++/*
++ * vrange->owner isn't stable because caller doesn't hold vrange_lock
++ * so avoid touching vrange->owner.
++ */
++static int __discard_vrange_anon(struct mm_struct *mm, struct vrange *vrange,
++                                      unsigned int *ret_discard)
++{
++      struct vm_area_struct *vma;
++      unsigned int nr_discard = 0;
++      unsigned long start = vrange->node.start;
++      unsigned long end = vrange->node.last + 1;
++      int ret = 0;
++
++      /* It prevent to destroy vma when the process exist */
++      if (!atomic_inc_not_zero(&mm->mm_users))
++              return ret;
++
++      if (!down_read_trylock(&mm->mmap_sem)) {
++              mmput(mm);
++              ret = -EBUSY;
++              goto out; /* this vrange could be retried */
++      }
++
++      vma = find_vma(mm, start);
++      if (!vma || (vma->vm_start >= end))
++              goto out_unlock;
++
++      for (; vma; vma = vma->vm_next) {
++              if (vma->vm_start >= end)
++                      break;
++              BUG_ON(vma->vm_flags & (VM_SPECIAL|VM_LOCKED|VM_MIXEDMAP|
++                                      VM_HUGETLB));
++              cond_resched();
++              nr_discard += discard_vma_pages(mm, vma,
++                              max_t(unsigned long, start, vma->vm_start),
++                              min_t(unsigned long, end, vma->vm_end));
++      }
++out_unlock:
++      up_read(&mm->mmap_sem);
++      mmput(mm);
++      *ret_discard = nr_discard;
++out:
++      return ret;
++}
++
++static int discard_vrange(struct vrange *vrange)
++{
++      int ret = 0;
++      struct mm_struct *mm;
++      struct vrange_root *vroot;
++      unsigned int nr_discard = 0;
++      vroot = vrange_get_vroot(vrange);
++      if (!vroot)
++              return 0;
++
++      /* TODO : handle VRANGE_FILE */
++      if (vroot->type != VRANGE_MM)
++              goto out;
++
++      /*
++       * Race of vrange->owner could happens with __vrange_remove
++       * but it's okay because subfunctions will check it again
++       */
++      if (vrange->owner == NULL)
++              goto out;
++
++      mm = vroot->object;
++      ret = __discard_vrange_anon(mm, vrange, &nr_discard);
++out:
++      __vroot_put(vroot);
++      return nr_discard;
++}
++
+ static int shrink_vrange(struct shrinker *s, struct shrink_control *sc)
+ {
+       struct vrange *range = NULL;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0826-vrange-Support-background-purging-for-vrange-file.patch b/patches.tizen/0826-vrange-Support-background-purging-for-vrange-file.patch
new file mode 100644 (file)
index 0000000..2d41120
--- /dev/null
@@ -0,0 +1,109 @@
+From aa90faf6fddf9ad169c365aa6d91fcd04376267d Mon Sep 17 00:00:00 2001
+From: Minchan Kim <minchan@kernel.org>
+Date: Mon, 22 Jul 2013 17:17:13 +0900
+Subject: [PATCH 0826/1302] vrange: Support background purging for vrange-file
+
+XXX: Needs commit log
+
+Signed-off-by: Minchan Kim <minchan@kernel.org>
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ mm/vrange.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 51 insertions(+), 7 deletions(-)
+
+diff --git a/mm/vrange.c b/mm/vrange.c
+index fad50c5..013859d 100644
+--- a/mm/vrange.c
++++ b/mm/vrange.c
+@@ -13,6 +13,7 @@
+ #include <linux/mmu_notifier.h>
+ #include <linux/mm_inline.h>
+ #include <linux/migrate.h>
++#include <linux/pagevec.h>
+ static struct kmem_cache *vrange_cachep;
+ static struct kmem_cache *vroot_cachep;
+@@ -1091,20 +1092,56 @@ out:
+       return ret;
+ }
++static int __discard_vrange_file(struct address_space *mapping,
++                      struct vrange *vrange, unsigned int *ret_discard)
++{
++      struct pagevec pvec;
++      pgoff_t index;
++      int i;
++      unsigned int nr_discard = 0;
++      unsigned long start_idx = vrange->node.start;
++      unsigned long end_idx = vrange->node.last;
++      const pgoff_t start = start_idx >> PAGE_CACHE_SHIFT;
++      pgoff_t end = end_idx >> PAGE_CACHE_SHIFT;
++      LIST_HEAD(pagelist);
++
++      pagevec_init(&pvec, 0);
++      index = start;
++      while (index <= end && pagevec_lookup(&pvec, mapping, index,
++                      min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1)) {
++              for (i = 0; i < pagevec_count(&pvec); i++) {
++                      struct page *page = pvec.pages[i];
++                      index = page->index;
++                      if (index > end)
++                              break;
++                      if (isolate_lru_page(page))
++                              continue;
++                      list_add(&page->lru, &pagelist);
++                      inc_zone_page_state(page, NR_ISOLATED_ANON);
++              }
++              pagevec_release(&pvec);
++              cond_resched();
++              index++;
++      }
++
++      if (!list_empty(&pagelist))
++              nr_discard = discard_vrange_pagelist(&pagelist);
++
++      *ret_discard = nr_discard;
++      putback_lru_pages(&pagelist);
++
++      return 0;
++}
++
+ static int discard_vrange(struct vrange *vrange)
+ {
+       int ret = 0;
+-      struct mm_struct *mm;
+       struct vrange_root *vroot;
+       unsigned int nr_discard = 0;
+       vroot = vrange_get_vroot(vrange);
+       if (!vroot)
+               return 0;
+-      /* TODO : handle VRANGE_FILE */
+-      if (vroot->type != VRANGE_MM)
+-              goto out;
+-
+       /*
+        * Race of vrange->owner could happens with __vrange_remove
+        * but it's okay because subfunctions will check it again
+@@ -1112,8 +1149,15 @@ static int discard_vrange(struct vrange *vrange)
+       if (vrange->owner == NULL)
+               goto out;
+-      mm = vroot->object;
+-      ret = __discard_vrange_anon(mm, vrange, &nr_discard);
++      if (vroot->type == VRANGE_MM) {
++              struct mm_struct *mm = vroot->object;
++              ret = __discard_vrange_anon(mm, vrange, &nr_discard);
++      } else if (vroot->type == VRANGE_FILE) {
++              struct address_space *mapping = vroot->object;
++              BUG_ON(!mapping);
++              ret = __discard_vrange_file(mapping, vrange, &nr_discard);
++      }
++
+ out:
+       __vroot_put(vroot);
+       return nr_discard;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0827-vrange-Add-vmstat-counter-about-purged-page.patch b/patches.tizen/0827-vrange-Add-vmstat-counter-about-purged-page.patch
new file mode 100644 (file)
index 0000000..793d97d
--- /dev/null
@@ -0,0 +1,74 @@
+From 52558171de87d1784f15e0f35ba7e27292b60563 Mon Sep 17 00:00:00 2001
+From: Minchan Kim <minchan@kernel.org>
+Date: Thu, 25 Jul 2013 13:44:37 +0900
+Subject: [PATCH 0827/1302] vrange: Add vmstat counter about purged page
+
+This patch adds the number of purged page in vmstat so admin can see
+how many of volatile pages are discarded by VM until now.
+
+Signed-off-by: Minchan Kim <minchan@kernel.org>
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/vm_event_item.h |  2 ++
+ mm/vmstat.c                   |  2 ++
+ mm/vrange.c                   | 10 ++++++++++
+ 3 files changed, 14 insertions(+)
+
+diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h
+index bd6cf61..c4aea92 100644
+--- a/include/linux/vm_event_item.h
++++ b/include/linux/vm_event_item.h
+@@ -25,6 +25,8 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
+               FOR_ALL_ZONES(PGALLOC),
+               PGFREE, PGACTIVATE, PGDEACTIVATE,
+               PGFAULT, PGMAJFAULT,
++              PGDISCARD_DIRECT,
++              PGDISCARD_KSWAPD,
+               FOR_ALL_ZONES(PGREFILL),
+               FOR_ALL_ZONES(PGSTEAL_KSWAPD),
+               FOR_ALL_ZONES(PGSTEAL_DIRECT),
+diff --git a/mm/vmstat.c b/mm/vmstat.c
+index f42745e..c54d7e1 100644
+--- a/mm/vmstat.c
++++ b/mm/vmstat.c
+@@ -756,6 +756,8 @@ const char * const vmstat_text[] = {
+       "pgfault",
+       "pgmajfault",
++      "pgdiscard_direct",
++      "pgdiscard_kswapd",
+       TEXTS_FOR_ZONES("pgrefill")
+       TEXTS_FOR_ZONES("pgsteal_kswapd")
+diff --git a/mm/vrange.c b/mm/vrange.c
+index 013859d..37e5037 100644
+--- a/mm/vrange.c
++++ b/mm/vrange.c
+@@ -907,6 +907,10 @@ int discard_vpage(struct page *page)
+               if (page_freeze_refs(page, 1)) {
+                       unlock_page(page);
++                      if (current_is_kswapd())
++                              count_vm_event(PGDISCARD_KSWAPD);
++                      else
++                              count_vm_event(PGDISCARD_DIRECT);
+                       return 0;
+               }
+       }
+@@ -1158,6 +1162,12 @@ static int discard_vrange(struct vrange *vrange)
+               ret = __discard_vrange_file(mapping, vrange, &nr_discard);
+       }
++      if (!ret) {
++              if (current_is_kswapd())
++                      count_vm_events(PGDISCARD_KSWAPD, nr_discard);
++              else
++                      count_vm_events(PGDISCARD_DIRECT, nr_discard);
++      }
+ out:
+       __vroot_put(vroot);
+       return nr_discard;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0828-vrange-Add-ARM-vrange-syscall.patch b/patches.tizen/0828-vrange-Add-ARM-vrange-syscall.patch
new file mode 100644 (file)
index 0000000..d62e177
--- /dev/null
@@ -0,0 +1,53 @@
+From bcb56f20d04932693e233a9ec8e7a230077ff99d Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+Date: Thu, 3 Oct 2013 11:18:37 +0200
+Subject: [PATCH 0828/1302] vrange: Add ARM vrange syscall
+
+Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/include/asm/unistd.h      | 2 +-
+ arch/arm/include/uapi/asm/unistd.h | 1 +
+ arch/arm/kernel/calls.S            | 1 +
+ 3 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
+index 141baa3..acabef1 100644
+--- a/arch/arm/include/asm/unistd.h
++++ b/arch/arm/include/asm/unistd.h
+@@ -15,7 +15,7 @@
+ #include <uapi/asm/unistd.h>
+-#define __NR_syscalls  (380)
++#define __NR_syscalls  (384)
+ #define __ARM_NR_cmpxchg              (__ARM_NR_BASE+0x00fff0)
+ #define __ARCH_WANT_STAT64
+diff --git a/arch/arm/include/uapi/asm/unistd.h b/arch/arm/include/uapi/asm/unistd.h
+index af33b44..179bf9c 100644
+--- a/arch/arm/include/uapi/asm/unistd.h
++++ b/arch/arm/include/uapi/asm/unistd.h
+@@ -406,6 +406,7 @@
+ #define __NR_process_vm_writev                (__NR_SYSCALL_BASE+377)
+ #define __NR_kcmp                     (__NR_SYSCALL_BASE+378)
+ #define __NR_finit_module             (__NR_SYSCALL_BASE+379)
++#define __NR_vrange                   (__NR_SYSCALL_BASE+380)
+ /*
+  * This may need to be greater than __NR_last_syscall+1 in order to
+diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
+index c6ca7e3..6f4161a 100644
+--- a/arch/arm/kernel/calls.S
++++ b/arch/arm/kernel/calls.S
+@@ -389,6 +389,7 @@
+               CALL(sys_process_vm_writev)
+               CALL(sys_kcmp)
+               CALL(sys_finit_module)
++/* 380 */     CALL(sys_vrange)
+ #ifndef syscalls_counted
+ .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
+ #define syscalls_counted
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0829-devfreq-exynos4-Support-DT-in-exynos4-busfreq-driver.patch b/patches.tizen/0829-devfreq-exynos4-Support-DT-in-exynos4-busfreq-driver.patch
new file mode 100644 (file)
index 0000000..a5ea022
--- /dev/null
@@ -0,0 +1,89 @@
+From 5da494c55b3ffcfed32ba0d8b4ad87540f783547 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Mon, 7 Oct 2013 15:25:01 +0900
+Subject: [PATCH 0829/1302] devfreq: exynos4: Support DT in exynos4 busfreq
+ driver.
+
+This patch makes exynos4 busfreq driver to support device tree.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/devfreq/exynos4_bus.c | 31 +++++++++++++++++++++++++++++--
+ 1 file changed, 29 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/devfreq/exynos4_bus.c b/drivers/devfreq/exynos4_bus.c
+index 3f37f3b..7319e81 100644
+--- a/drivers/devfreq/exynos4_bus.c
++++ b/drivers/devfreq/exynos4_bus.c
+@@ -24,6 +24,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/regulator/consumer.h>
+ #include <linux/module.h>
++#include <linux/of.h>
+ /* Exynos4 ASV has been in the mailing list, but not upstreamed, yet. */
+ #ifdef CONFIG_EXYNOS_ASV
+@@ -1016,12 +1017,28 @@ unlock:
+       return NOTIFY_DONE;
+ }
++#ifdef CONFIG_OF
++static const struct of_device_id exynos4_busfreq_match[] = {
++      {
++              .compatible = "samsung,exynos4210-busfreq",
++              .data = (void *)TYPE_BUSF_EXYNOS4210,
++      },
++      {
++              .compatible = "samsung,exynos4x12-busfreq",
++              .data = (void *)TYPE_BUSF_EXYNOS4x12,
++      },
++};
++MODULE_DEVICE_TABLE(of, exynos4_busfreq_match[]);
++#else
++#define exynos4_busfreq_match NULL
++#endif
++
+ static int exynos4_busfreq_probe(struct platform_device *pdev)
+ {
+       struct busfreq_data *data;
+       struct opp *opp;
+       struct device *dev = &pdev->dev;
+-      int err = 0;
++      int type, err = 0;
+       data = devm_kzalloc(&pdev->dev, sizeof(struct busfreq_data), GFP_KERNEL);
+       if (data == NULL) {
+@@ -1029,11 +1046,20 @@ static int exynos4_busfreq_probe(struct platform_device *pdev)
+               return -ENOMEM;
+       }
+-      data->type = pdev->id_entry->driver_data;
++      if (dev->of_node) {
++              const struct of_device_id *match;
++              match = of_match_node(exynos4_busfreq_match, dev->of_node);
++              type = (int) match->data;
++      } else {
++              type = pdev->id_entry->driver_data;
++      }
++
++      data->type = type;
+       data->dmc[0].hw_base = S5P_VA_DMC0;
+       data->dmc[1].hw_base = S5P_VA_DMC1;
+       data->pm_notifier.notifier_call = exynos4_busfreq_pm_notifier_event;
+       data->dev = dev;
++
+       mutex_init(&data->lock);
+       switch (data->type) {
+@@ -1133,6 +1159,7 @@ static struct platform_driver exynos4_busfreq_driver = {
+               .name   = "exynos4-busfreq",
+               .owner  = THIS_MODULE,
+               .pm     = &exynos4_busfreq_pm,
++              .of_match_table = of_match_ptr(exynos4_busfreq_match),
+       },
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0830-dts-exynos4x12-Add-device-tree-node-for-exynos4-busf.patch b/patches.tizen/0830-dts-exynos4x12-Add-device-tree-node-for-exynos4-busf.patch
new file mode 100644 (file)
index 0000000..30ce392
--- /dev/null
@@ -0,0 +1,29 @@
+From 2bc18df98df254bfc090b2e3e8dc9dee8763a23e Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Mon, 7 Oct 2013 15:37:19 +0900
+Subject: [PATCH 0830/1302] dts: exynos4x12: Add device tree node for exynos4
+ busfreq.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4x12.dtsi | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index 0eafcce..5d73533 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -364,4 +364,9 @@
+       rotator@12810000 {
+               compatible = "samsung,exynos4212-rotator";
+       };
++
++      busfreq@0 {
++              compatible = "samsung,exynos4x12-busfreq";
++              status = "disabled";
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0831-WORKAROUND-Temporary-workaround-for-Suspend-To-Ram.patch b/patches.tizen/0831-WORKAROUND-Temporary-workaround-for-Suspend-To-Ram.patch
new file mode 100644 (file)
index 0000000..580f4e6
--- /dev/null
@@ -0,0 +1,43 @@
+From 682061cb597d5174de6fee211a2ad565c33680f7 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Mon, 7 Oct 2013 15:45:12 +0900
+Subject: [PATCH 0831/1302] WORKAROUND: Temporary workaround for
+ Suspend-To-Ram.
+
+*** Should be purged later.
+
+Current issue :
+       @m0, When system wakes from suspend-to-ram state, it often
+       hangs out or shows data abort error due to invalidate PC value
+       (For more information, please reference 'BSP ISSUES'
+       on TizenKernel Wiki (http://10.252.81.130/mediawiki/)
+
+Suspect :
+       Non boot CPUs' hotplugging. Without power-off of non-boot cpus,
+       it never happens.
+
+Workaround :
+       Keep VDD_ARM regulator ON, even system's in STR state.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 7b912dd..3021f27 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -798,7 +798,7 @@
+                                       regulator-max-microvolt = <1500000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+-                                      regulator-mem-off;
++                                      regulator-mem-on;
+                               };
+                               buck3_reg: buck@3 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0832-ARM-defconfig-enable-the-mmc-clock-gating-config.patch b/patches.tizen/0832-ARM-defconfig-enable-the-mmc-clock-gating-config.patch
new file mode 100644 (file)
index 0000000..dadf10e
--- /dev/null
@@ -0,0 +1,53 @@
+From 2d0e16324733a84ccc0580312840ac06dc4def73 Mon Sep 17 00:00:00 2001
+From: Jaehoon Chung <jh80.chung@samsung.com>
+Date: Mon, 7 Oct 2013 16:14:36 +0900
+Subject: [PATCH 0832/1302] ARM: defconfig: enable the mmc clock-gating config
+
+Enable the MMC_CLK_CATING configuration.
+
+Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_defconfig | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index f14bbbb..1940a58 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -602,7 +602,6 @@ CONFIG_PM_SLEEP_DEBUG=y
+ # CONFIG_APM_EMULATION is not set
+ CONFIG_PM_CLK=y
+ CONFIG_PM_GENERIC_DOMAINS=y
+-# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
+ CONFIG_PM_GENERIC_DOMAINS_SLEEP=y
+ CONFIG_PM_GENERIC_DOMAINS_RUNTIME=y
+ CONFIG_CPU_PM=y
+@@ -2457,6 +2456,7 @@ CONFIG_USB_ETH_RNDIS=y
+ # CONFIG_USB_G_SERIAL is not set
+ # CONFIG_USB_MIDI_GADGET is not set
+ # CONFIG_USB_G_PRINTER is not set
++# CONFIG_USB_G_SLP is not set
+ # CONFIG_USB_CDC_COMPOSITE is not set
+ # CONFIG_USB_G_NOKIA is not set
+ # CONFIG_USB_G_ACM_MS is not set
+@@ -2467,7 +2467,7 @@ CONFIG_USB_ETH_RNDIS=y
+ CONFIG_MMC=y
+ # CONFIG_MMC_DEBUG is not set
+ CONFIG_MMC_UNSAFE_RESUME=y
+-# CONFIG_MMC_CLKGATE is not set
++CONFIG_MMC_CLKGATE=y
+ #
+ # MMC/SD/SDIO Card Drivers
+@@ -2841,7 +2841,6 @@ CONFIG_EXTCON=y
+ #
+ # Extcon Device Drivers
+ #
+-CONFIG_OF_EXTCON=y
+ CONFIG_EXTCON_GPIO=y
+ CONFIG_EXTCON_ADC_JACK=y
+ CONFIG_EXTCON_MAX77693=y
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0833-arm-exynos-Fix-SFR-base-address-of-DMC-in-EXYNOS4-se.patch b/patches.tizen/0833-arm-exynos-Fix-SFR-base-address-of-DMC-in-EXYNOS4-se.patch
new file mode 100644 (file)
index 0000000..9d80672
--- /dev/null
@@ -0,0 +1,93 @@
+From dc35488b130cc195ba36cc8c4c10a450f87a59eb Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Mon, 7 Oct 2013 17:03:32 +0900
+Subject: [PATCH 0833/1302] arm: exynos: Fix SFR base address of DMC in EXYNOS4
+ series.
+
+This patch fixes DMC's physical SFR address base which is used for
+static memory mapping as EXYNOS4210 and EXYNOS4x12 uses different SFR
+addresses for them.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/mach-exynos/common.c           | 30 ++++++++++++++++++++----------
+ arch/arm/mach-exynos/include/mach/map.h |  7 +++++--
+ 2 files changed, 25 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
+index a8b62e4..d0dcfc0 100644
+--- a/arch/arm/mach-exynos/common.c
++++ b/arch/arm/mach-exynos/common.c
+@@ -190,16 +190,6 @@ static struct map_desc exynos4_iodesc[] __initdata = {
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+-              .virtual        = (unsigned long)S5P_VA_DMC0,
+-              .pfn            = __phys_to_pfn(EXYNOS4_PA_DMC0),
+-              .length         = SZ_64K,
+-              .type           = MT_DEVICE,
+-      }, {
+-              .virtual        = (unsigned long)S5P_VA_DMC1,
+-              .pfn            = __phys_to_pfn(EXYNOS4_PA_DMC1),
+-              .length         = SZ_64K,
+-              .type           = MT_DEVICE,
+-      }, {
+               .virtual        = (unsigned long)S3C_VA_USB_HSPHY,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_HSPHY),
+               .length         = SZ_4K,
+@@ -231,6 +221,16 @@ static struct map_desc exynos4210_iodesc[] __initdata = {
+               .pfn            = __phys_to_pfn(EXYNOS4210_PA_SYSRAM_NS),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
++      }, {
++              .virtual        = (unsigned long)S5P_VA_DMC0,
++              .pfn            = __phys_to_pfn(EXYNOS4210_PA_DMC0),
++              .length         = SZ_64K,
++              .type           = MT_DEVICE,
++      }, {
++              .virtual        = (unsigned long)S5P_VA_DMC1,
++              .pfn            = __phys_to_pfn(EXYNOS4210_PA_DMC1),
++              .length         = SZ_64K,
++              .type           = MT_DEVICE,
+       },
+ };
+@@ -240,6 +240,16 @@ static struct map_desc exynos4x12_iodesc[] __initdata = {
+               .pfn            = __phys_to_pfn(EXYNOS4x12_PA_SYSRAM_NS),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
++      }, {
++              .virtual        = (unsigned long)S5P_VA_DMC0,
++              .pfn            = __phys_to_pfn(EXYNOS4x12_PA_DMC0),
++              .length         = SZ_64K,
++              .type           = MT_DEVICE,
++      }, {
++              .virtual        = (unsigned long)S5P_VA_DMC1,
++              .pfn            = __phys_to_pfn(EXYNOS4x12_PA_DMC1),
++              .length         = SZ_64K,
++              .type           = MT_DEVICE,
+       },
+ };
+diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
+index e721398..9d8a9b7 100644
+--- a/arch/arm/mach-exynos/include/mach/map.h
++++ b/arch/arm/mach-exynos/include/mach/map.h
+@@ -75,8 +75,11 @@
+ #define EXYNOS4_PA_KEYPAD             0x100A0000
+-#define EXYNOS4_PA_DMC0                       0x10400000
+-#define EXYNOS4_PA_DMC1                       0x10410000
++#define EXYNOS4210_PA_DMC0            0x10400000
++#define EXYNOS4210_PA_DMC1            0x10410000
++
++#define EXYNOS4x12_PA_DMC0            0x10600000
++#define EXYNOS4x12_PA_DMC1            0x10610000
+ #define EXYNOS4_PA_COMBINER           0x10440000
+ #define EXYNOS5_PA_COMBINER           0x10440000
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0834-regulator-max77686-Support-DVS-control-in-max77686-r.patch b/patches.tizen/0834-regulator-max77686-Support-DVS-control-in-max77686-r.patch
new file mode 100644 (file)
index 0000000..c2f8b45
--- /dev/null
@@ -0,0 +1,173 @@
+From 930ef02a3a92e960c8bf281654ce5282cbf3270d Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Mon, 7 Oct 2013 17:02:15 +0900
+Subject: [PATCH 0834/1302] regulator: max77686: Support DVS control in
+ max77686 regulator.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 10 ++++
+ drivers/regulator/max77686.c            | 95 ++++++++++++++++++++++++++++++++-
+ include/linux/mfd/max77686.h            |  2 +
+ 3 files changed, 106 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 3021f27..4cf3f59 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -560,6 +560,16 @@
+                       reg = <0x09>;
+                       #clock-cells = <1>;
++                      max77686,dvs_gpios = <&gpf3 1 0>,
++                                           <&gpf3 2 0>,
++                                           <&gpf3 3 0>;
++
++                      max77686,selb_gpios = <&gpm3 0 0>,
++                                            <&gpm3 1 0>,
++                                            <&gpm3 2 0>;
++
++                      max77686,default_dvs_idx = <1>;
++
+                       voltage-regulators {
+                               ldo1_reg: ldo@1 {
+                                       regulator-compatible = "LDO1";
+diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c
+index 3b9b342..4d40e54 100644
+--- a/drivers/regulator/max77686.c
++++ b/drivers/regulator/max77686.c
+@@ -34,6 +34,7 @@
+ #include <linux/regulator/of_regulator.h>
+ #include <linux/mfd/max77686.h>
+ #include <linux/mfd/max77686-private.h>
++#include <linux/of_gpio.h>
+ #define MAX77686_LDO_MINUV    800000
+ #define MAX77686_LDO_UVSTEP   50000
+@@ -495,9 +496,36 @@ static int max77686_pmic_dt_parse_pdata(struct platform_device *pdev,
+       struct device_node *pmic_np, *regulators_np;
+       struct max77686_regulator_data *rdata;
+       struct of_regulator_match rmatch;
+-      unsigned int i;
++      unsigned int i, gpio;
+       pmic_np = iodev->dev->of_node;
++
++      for (i = 0; i < 3; i++) {
++              /* GPIO-DVS */
++              gpio = of_get_named_gpio(pmic_np, "max77686,dvs_gpios", i);
++              if (!gpio_is_valid(gpio)) {
++                      dev_err(&pdev->dev, "could not find gpio-dvs\n");
++                      while (i--)
++                              pdata->buck234_gpio_dvs[i] = 0;
++                      break;
++              }
++              pdata->buck234_gpio_dvs[i] = gpio;
++
++              /* GPIO-SELB */
++              gpio = of_get_named_gpio(pmic_np, "max77686,selb_gpios", i);
++              if (!gpio_is_valid(gpio)) {
++                      dev_err(&pdev->dev, "could not find gpio-selb\n");
++                      while (i--)
++                              pdata->buck234_gpio_selb[i] = 0;
++                      break;
++              }
++              pdata->buck234_gpio_selb[i] = gpio;
++      }
++
++      if (of_property_read_u32(pmic_np, "max77686,default_dvs_idx",
++                               &pdata->dvs_idx))
++              pdata->dvs_idx = 0;
++
+       regulators_np = of_find_node_by_name(pmic_np, "voltage-regulators");
+       if (!regulators_np) {
+               dev_err(&pdev->dev, "could not find regulators sub-node\n");
+@@ -571,6 +599,71 @@ static int max77686_pmic_probe(struct platform_device *pdev)
+       config.driver_data = max77686;
+       platform_set_drvdata(pdev, max77686);
++      /* GPIO-DVS, SELB */
++      if (pdata->buck234_gpio_dvs[0]) {
++              int ret, i;
++              for (i = 0 ; i < 3; i++) {
++                      char label[20];
++                      unsigned long flag;
++
++                      sprintf(label, "MAX77686_DVS%d", i);
++
++                      flag = (test_bit(i, (unsigned long *) &pdata->dvs_idx)) ?
++                                       GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
++
++                      ret = devm_gpio_request_one(&pdev->dev,
++                                              pdata->buck234_gpio_dvs[i], flag, label);
++                      if (ret) {
++                              dev_err(&pdev->dev, "failed to request gpio-dvs\n");
++                              while (i--)
++                                      gpio_set_value(pdata->buck234_gpio_dvs[i], 0);
++
++                              pdata->dvs_idx = 0;
++                              break;
++                      }
++              }
++      }
++
++      if (pdata->buck234_gpio_selb[0]) {
++              int ret, i;
++              for (i = 0 ; i < 3; i++) {
++                      char label[20];
++                      unsigned long flag;
++
++                      sprintf(label, "MAX77686_SELB%d", i);
++
++                      flag = GPIOF_OUT_INIT_LOW;
++
++                      ret = devm_gpio_request_one(&pdev->dev,
++                                              pdata->buck234_gpio_selb[i], flag, label);
++                      if (ret) {
++                              dev_err(&pdev->dev, "failed to request gpio-dvs\n");
++                              while (i--)
++                                      gpio_set_value(pdata->buck234_gpio_dvs[i], 0);
++                              break;
++                      }
++              }
++      }
++
++      /* Initialize DVS voltage table */
++      for (i = 0; i < 8; i++) {
++              unsigned int buck2_dvs = pdata->buck2_voltage[i];
++              unsigned int buck3_dvs = pdata->buck3_voltage[i];
++              unsigned int buck4_dvs = pdata->buck4_voltage[i];
++              unsigned int reg[3];
++
++              regmap_write(iodev->regmap, MAX77686_REG_BUCK2DVS1 + i,
++                              buck2_dvs ? : 0x28);
++              regmap_write(iodev->regmap, MAX77686_REG_BUCK3DVS1 + i,
++                                      buck3_dvs ? : 0x28);
++              regmap_write(iodev->regmap, MAX77686_REG_BUCK4DVS1 + i,
++                              buck4_dvs ? : 0x28);
++      }
++
++      regulators[MAX77686_BUCK2].vsel_reg += pdata->dvs_idx;
++      regulators[MAX77686_BUCK3].vsel_reg += pdata->dvs_idx;
++      regulators[MAX77686_BUCK4].vsel_reg += pdata->dvs_idx;
++
+       for (i = 0; i < MAX77686_REGULATORS; i++) {
+               config.init_data = pdata->regulators[i].initdata;
+               config.of_node = pdata->regulators[i].of_node;
+diff --git a/include/linux/mfd/max77686.h b/include/linux/mfd/max77686.h
+index 46c0f32..f7dc5f1 100644
+--- a/include/linux/mfd/max77686.h
++++ b/include/linux/mfd/max77686.h
+@@ -110,6 +110,8 @@ struct max77686_platform_data {
+       unsigned int buck2_voltage[8]; /* buckx_voltage in uV */
+       unsigned int buck3_voltage[8];
+       unsigned int buck4_voltage[8];
++
++      unsigned int dvs_idx;
+ };
+ #endif /* __LINUX_MFD_MAX77686_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0835-ehci-s5p-Use-device-tree-to-get-name-of-desired-phy.patch b/patches.tizen/0835-ehci-s5p-Use-device-tree-to-get-name-of-desired-phy.patch
new file mode 100644 (file)
index 0000000..8d4142c
--- /dev/null
@@ -0,0 +1,41 @@
+From 84707d3e02c2d4db6b5d65928dc9ea6cdc4fc737 Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Thu, 26 Sep 2013 10:04:02 +0200
+Subject: [PATCH 0835/1302] ehci-s5p: Use device tree to get name of desired
+ phy
+
+With this patch the name of the phy that should be used is read from
+the device tree. This gives more flexibility to use the driver without
+recompiling.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/host/ehci-s5p.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
+index c0b3ebd..49ec64c 100644
+--- a/drivers/usb/host/ehci-s5p.c
++++ b/drivers/usb/host/ehci-s5p.c
+@@ -196,6 +196,7 @@ static int s5p_ehci_probe(struct platform_device *pdev)
+       struct usb_hcd *hcd;
+       struct ehci_hcd *ehci;
+       struct resource *res;
++      const char *phy_name;
+       int irq;
+       int err;
+@@ -218,7 +219,8 @@ static int s5p_ehci_probe(struct platform_device *pdev)
+               return -ENOMEM;
+       }
+       s5p_ehci = to_s5p_ehci(hcd);
+-      phy =  devm_phy_get(&pdev->dev, "hsic0");
++      phy_name = of_get_property(pdev->dev.of_node, "phy-names", NULL);
++      phy =  devm_phy_get(&pdev->dev, phy_name);
+       if (IS_ERR(phy)) {
+               /* Fallback to pdata */
+               if (!pdata) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0836-dts-arm-Add-dts-file-for-the-exynos4412-odroidx2-boa.patch b/patches.tizen/0836-dts-arm-Add-dts-file-for-the-exynos4412-odroidx2-boa.patch
new file mode 100644 (file)
index 0000000..1934160
--- /dev/null
@@ -0,0 +1,503 @@
+From 11737a64e31926a4c6b9c947bd6071346087e383 Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Mon, 7 Oct 2013 18:21:43 +0200
+Subject: [PATCH 0836/1302] dts: arm: Add dts file for the exynos4412-odroidx2
+ board
+
+This patch add support for the Exynos4412 based Origen-X2 board.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/Makefile                |   1 +
+ arch/arm/boot/dts/exynos4412-odroidx2.dts | 466 ++++++++++++++++++++++++++++++
+ 2 files changed, 467 insertions(+)
+ create mode 100644 arch/arm/boot/dts/exynos4412-odroidx2.dts
+
+diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
+index ae51aa1..b17a6dc 100644
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -53,6 +53,7 @@ dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \
+       exynos4212-slp_pd.dtb \
+       exynos4412-m0.dtb \
+       exynos4412-odroidx.dtb \
++      exynos4412-odroidx2.dtb \
+       exynos4412-redwood.dtb \
+       exynos4412-redwoodlte.dtb \
+       exynos4412-smdk4412.dtb \
+diff --git a/arch/arm/boot/dts/exynos4412-odroidx2.dts b/arch/arm/boot/dts/exynos4412-odroidx2.dts
+new file mode 100644
+index 0000000..c93fb7a
+--- /dev/null
++++ b/arch/arm/boot/dts/exynos4412-odroidx2.dts
+@@ -0,0 +1,466 @@
++/*
++ * Hardkernel's Exynos4412 based ODROID-X2 board device tree source
++ *
++ * Copyright (c) 2012 Dongjin Kim <tobetter@gmail.com>
++ *
++ * Device tree source file for Hardkernel's ODROID-X2 board which is based on
++ * Samsung's Exynos4412 SoC.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++*/
++
++/dts-v1/;
++#include "exynos4412.dtsi"
++
++/ {
++      model = "Hardkernel ODROID-X2 board based on Exynos4412";
++      compatible = "hardkernel,odroid-x2", "samsung,exynos4412";
++
++      memory {
++              reg = <0x40000000 0x10000000
++                      0x50000000 0x10000000
++                      0x60000000 0x10000000
++                      0x70000000 0x10000000>;
++      };
++
++      chosen {
++              bootargs = "console=ttySAC1,115200N8 root=/dev/mmcblk0p2 rootwait earlyprintk panic=5";
++      };
++
++      firmware@0204F000 {
++              compatible = "samsung,secure-firmware";
++              reg = <0x0204F000 0x1000>;
++      };
++
++      leds {
++              compatible = "gpio-leds";
++              led1 {
++                      label = "led1:heart";
++                      gpios = <&gpc1 0 1>;
++                      default-state = "on";
++                      linux,default-trigger = "heartbeat";
++              };
++              led2 {
++                      label = "led2:mmc0";
++                      gpios = <&gpc1 2 1>;
++                      default-state = "on";
++                      linux,default-trigger = "mmc0";
++              };
++      };
++
++      mshc@12550000 {
++              pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              num-slots = <1>;
++              supports-highspeed;
++              broken-cd;
++              fifo-depth = <0x80>;
++              card-detect-delay = <200>;
++              samsung,dw-mshc-ciu-div = <3>;
++              samsung,dw-mshc-sdr-timing = <2 3 3>;
++              samsung,dw-mshc-ddr-timing = <1 2 3>;
++
++              slot@0 {
++                      reg = <0>;
++                      bus-width = <8>;
++              };
++      };
++
++      regulator_p3v3: fixed-regulator-0 {
++              compatible = "regulator-fixed";
++              regulator-name = "p3v3_en";
++              regulator-min-microvolt = <3300000>;
++              regulator-max-microvolt = <3300000>;
++              gpio = <&gpa1 1 1>;
++              enable-active-high;
++              regulator-boot-on;
++      };
++
++      sdhci@12530000 {
++              bus-width = <4>;
++              pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>;
++              pinctrl-names = "default";
++              vmmc-supply = <&regulator_p3v3>;
++              status = "okay";
++      };
++
++      serial@13800000 {
++              status = "okay";
++      };
++
++      serial@13810000 {
++              status = "okay";
++      };
++
++      serial@13820000 {
++              status = "okay";
++      };
++
++      serial@13830000 {
++              status = "okay";
++      };
++
++      fixed-rate-clocks {
++              xxti {
++                      compatible = "samsung,clock-xxti";
++                      clock-frequency = <0>;
++              };
++
++              xusbxti {
++                      compatible = "samsung,clock-xusbxti";
++                      clock-frequency = <24000000>;
++              };
++      };
++
++      i2c@13860000 { // i2c0
++              samsung,i2c-sda-delay = <100>;
++              samsung,i2c-slave-addr = <0x10>; // ?
++              samsung,i2c-max-bus-freq = <100000>;
++              pinctrl-0 = <&i2c0_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              usb3503@08 {
++                      compatible = "smsc,usb3503";
++                      reg = <0x08>;
++
++                      connect-gpios = <&gpx3 0 0>;
++                      intn-gpios = <&gpx3 4 0>;
++                      reset-gpios = <&gpx3 5 0>;
++                      initial-mode = <1>;
++
++              };
++
++              max77686_pmic@09 {
++                      compatible = "maxim,max77686";
++                      reg = <0x09>;
++
++                      voltage-regulators {
++                              ldo1_reg: ldo@1 {
++                                      regulator-compatible = "LDO1";
++                                      regulator-name = "VALIVE_1.0V_AP";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo2_reg: ldo@2 {
++                                      regulator-compatible = "LDO2";
++                                      regulator-name = "VDDQ_M1M2_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo3_reg: ldo@3 {
++                                      regulator-compatible = "LDO3";
++                                      regulator-name = "VDDQ_M0_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo4_reg: ldo@4 {
++                                      regulator-compatible = "LDO4";
++                                      regulator-name = "VDDQ_MMC2_2.8V";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo5_reg: ldo@5 {
++                                      regulator-compatible = "LDO5";
++                                      regulator-name = "VDDQ_MMC13_1V8";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo6_reg: ldo@6 {
++                                      regulator-compatible = "LDO6";
++                                      regulator-name = "VDD_MPLL_1.0V";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo7_reg: ldo@7 {
++                                      regulator-compatible = "LDO7";
++                                      regulator-name = "VDD_VPLL_1.0V";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo8_reg: ldo@8 {
++                                      regulator-compatible = "LDO8";
++                                      regulator-name = "VDD10_HDMI_1.0V";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo9_reg: ldo@9 {
++                                      regulator-compatible = "LDO9";
++                                      regulator-name = "VDD_VTCORE_1.0V";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo10_reg: ldo@10 {
++                                      regulator-compatible = "LDO10";
++                                      regulator-name = "VDDQ_MIPIHSI_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo11_reg: ldo@11 {
++                                      regulator-compatible = "LDO11";
++                                      regulator-name = "VDD18_ABB1_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo12_reg: ldo@12 {
++                                      regulator-compatible = "LDO12";
++                                      regulator-name = "VDD33_UOTG_3.3V";
++                                      regulator-min-microvolt = <3300000>;
++                                      regulator-max-microvolt = <3300000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo13_reg: ldo@13 {
++                                      regulator-compatible = "LDO13";
++                                      regulator-name = "VDDQ_C2C_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo14_reg: ldo@14 {
++                                      regulator-compatible = "LDO14";
++                                      regulator-name = "VDD18_ABB2_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo15_reg: ldo@15 {
++                                      regulator-compatible = "LDO15";
++                                      regulator-name = "VDD10_HSIC_1.0V";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo16_reg: ldo@16 {
++                                      regulator-compatible = "LDO16";
++                                      regulator-name = "VDD18_HSIC_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo17_reg: ldo@17 {
++                                      regulator-compatible = "LDO17";
++                                      regulator-name = "VDDQ_CAM_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo18_reg: ldo@18 {
++                                      regulator-compatible = "LDO18";
++                                      regulator-name = "VDD_LDO18_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo19_reg: ldo@19 {
++                                      regulator-compatible = "LDO19";
++                                      regulator-name = "VDD_VTCAM_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo20_reg: ldo@20 {
++                                      regulator-compatible = "LDO20";
++                                      regulator-name = "VDD_LDO20_1V8";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo21_reg: ldo@21 {
++                                      regulator-compatible = "LDO21";
++                                      regulator-name = "VDD_SDCARD_3.3V";
++                                      regulator-min-microvolt = <3300000>;
++                                      regulator-max-microvolt = <3300000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo22_reg: ldo@22 {
++                                      regulator-compatible = "LDO22";
++                                      regulator-name = "VDD_LDO22_2.8V";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo23_reg: ldo@23 {
++                                      regulator-compatible = "LDO23";
++                                      regulator-name = "VDD_TOUCH_2.8V";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo24_reg: ldo@24 {
++                                      regulator-compatible = "LDO24";
++                                      regulator-name = "VDD_TOUCHLED_3.3V";
++                                      regulator-min-microvolt = <3300000>;
++                                      regulator-max-microvolt = <3300000>;
++                                      regulator-always-on;
++                              };
++
++                              ldo25_reg: ldo@25 {
++                                      regulator-compatible = "LDO25";
++                                      regulator-name = "VDDQ_LCD_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-boot-on;
++                              };
++
++                              ldo26_reg: ldo@26 {
++                                      regulator-compatible = "LDO26";
++                                      regulator-name = "VDD_MOTOR_3.0V";
++                                      regulator-min-microvolt = <3300000>;
++                                      regulator-max-microvolt = <3300000>;
++                                      regulator-always-on;
++                              };
++
++                              buck1_reg: buck@1 {
++                                      regulator-compatible = "BUCK1";
++                                      regulator-name = "VDD_MIF_1.0V";
++                                      regulator-min-microvolt = <800000>;
++                                      regulator-max-microvolt = <1100000>;
++                                      regulator-always-on;
++                                      regulator-boot-on;
++                              };
++
++                              buck2_reg: buck@2 {
++                                      regulator-compatible = "BUCK2";
++                                      regulator-name = "VDD_ARM_1.3V";
++                                      regulator-min-microvolt = <800000>;
++                                      regulator-max-microvolt = <1500000>;
++                                      regulator-always-on;
++                                      regulator-boot-on;
++                              };
++
++                              buck3_reg: buck@3 {
++                                      regulator-compatible = "BUCK3";
++                                      regulator-name = "VDD_INT_1.0V";
++                                      regulator-min-microvolt = <800000>;
++                                      regulator-max-microvolt = <1150000>;
++                                      regulator-always-on;
++                                      regulator-boot-on;
++                              };
++
++                              buck4_reg: buck@4 {
++                                      regulator-compatible = "BUCK4";
++                                      regulator-name = "VDD_G3D_1.0V";
++                                      regulator-min-microvolt = <850000>;
++                                      regulator-max-microvolt = <1200000>;
++                                      regulator-boot-on;
++                              };
++
++                              buck5_reg: buck@5 {
++                                      regulator-compatible = "BUCK5";
++                                      regulator-name = "VDDQ_CKEM1M2_1.2V";
++                                      regulator-min-microvolt = <1200000>;
++                                      regulator-max-microvolt = <1200000>;
++                                      regulator-always-on;
++                              };
++
++                              buck6_reg: buck@6 {
++                                      regulator-compatible = "BUCK6";
++                                      regulator-name = "VDD_INL_1.35V";
++                                      regulator-min-microvolt = <1350000>;
++                                      regulator-max-microvolt = <1350000>;
++                                      regulator-always-on;
++                              };
++
++                              buck7_reg: buck@7 {
++                                      regulator-compatible = "BUCK7";
++                                      regulator-name = "VDD_INL_2.0V";
++                                      regulator-min-microvolt = <2000000>;
++                                      regulator-max-microvolt = <2000000>;
++                                      regulator-always-on;
++                              };
++
++                              buck8_reg: buck@8 {
++                                      regulator-compatible = "BUCK8";
++                                      regulator-name = "VDD_BUCK8_2.8V";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
++                                      regulator-always-on;
++                              };
++
++                              buck9_reg: buck@9 {
++                                      regulator-compatible = "BUCK9";
++                                      regulator-name = "VDD_BUCK9_1.2V";
++                                      regulator-min-microvolt = <1200000>;
++                                      regulator-max-microvolt = <1200000>;
++                                      regulator-always-on;
++                              };
++
++                      };
++
++              };
++      };
++
++
++      hsotg@12480000 {
++              status = "okay";
++              vusb_d-supply = <&ldo15_reg>;
++              vusb_a-supply = <&ldo12_reg>;
++              phys = <&exynos_usbphy 0>;
++              phy-names = "device";
++      };
++
++      ehci@12580000 {
++              status = "okay";
++              phys = <&exynos_usbphy 2>;
++              phy-names = "hsic0";
++      };
++
++      exynos_usbphy: exynos-usbphy@125B0000 {
++              compatible = "samsung,exynos4212-usbphy";
++              reg = <0x125B0000 0x100 0x10020704 0x0c 0x1001021c 0x4>;
++              clocks = <&clock 305>, <&clock 2>, <&clock 2>, <&clock 2>,
++                                                              <&clock 2>;
++              clock-names = "phy", "device", "host", "hsic0", "hsic1";
++              status = "okay";
++              #phy-cells = <1>;
++      };
++
++      register-debug {
++              compatible = "generic,register-debug";
++              status = "okay";
++      };
++
++      mfc: codec@13400000 {
++              status = "okay";
++              samsung,mfc-r = <0x43000000 0x800000>;
++              samsung,mfc-l = <0x51000000 0x800000>;
++      };
++};
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0837-dts-arm-Add-support-for-new-Exynos-USB-phy-driver-to.patch b/patches.tizen/0837-dts-arm-Add-support-for-new-Exynos-USB-phy-driver-to.patch
new file mode 100644 (file)
index 0000000..e0c5b98
--- /dev/null
@@ -0,0 +1,132 @@
+From e02734be29c03cab7367c507891b2e00557c6cdd Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Tue, 8 Oct 2013 10:50:53 +0200
+Subject: [PATCH 0837/1302] dts: arm: Add support for new Exynos USB phy driver
+ to origen and universal
+
+This patch adds support for the new Exynos USB PHY driver. It also removes
+remnants of the old driver's presence in the dts files.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-origen.dts         | 16 +++++++++++++---
+ arch/arm/boot/dts/exynos4210-universal_c210.dts | 22 ++++++++++++++++++----
+ arch/arm/boot/dts/exynos4210.dtsi               | 15 ---------------
+ 3 files changed, 31 insertions(+), 22 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts
+index 95bb61f..40fd476 100644
+--- a/arch/arm/boot/dts/exynos4210-origen.dts
++++ b/arch/arm/boot/dts/exynos4210-origen.dts
+@@ -165,18 +165,19 @@
+               };
+       };
+-      usbphy@125B0000 {
+-              status = "okay";
+-      };
+       hsotg@12480000 {
+               status = "okay";
+               vusb_d-supply = <&ldo8_reg>;
+               vusb_a-supply = <&ldo3_reg>;
++              phys = <&exynos_usbphy 0>;
++              phy-names = "device";
+       };
+       ehci@12580000 {
+               status = "okay";
++              phys = <&exynos_usbphy 1>;
++              phy-names = "host";
+       };
+       i2c@13860000 {
+@@ -328,4 +329,13 @@
+               };
+       };
++      exynos_usbphy: exynos-usbphy@125B0000 {
++              compatible = "samsung,exynos4210-usbphy";
++              reg = <0x125B0000 0x100 0x10020704 0x0c 0x1001021c 0x4>;
++              clocks = <&clock 305>, <&clock 2>, <&clock 2>, <&clock 2>,
++                                                              <&clock 2>;
++              clock-names = "phy", "device", "host", "hsic0", "hsic1";
++              status = "okay";
++              #phy-cells = <1>;
++      };
+ };
+diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts
+index 2c91861..e063602 100644
+--- a/arch/arm/boot/dts/exynos4210-universal_c210.dts
++++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts
+@@ -77,6 +77,8 @@
+       hsotg@12480000 {
+               vusb_d-supply = <&ldo3_reg>;
+               vusb_a-supply = <&ldo8_reg>;
++              phys = <&exynos_usbphy 0>;
++              phy-names = "device";
+               status = "okay";
+       };
+@@ -89,10 +91,6 @@
+               status = "okay";
+       };
+-      usbphy@125B0000 {
+-              status = "okay";
+-      };
+-
+       serial@13800000 {
+               status = "okay";
+       };
+@@ -442,4 +440,20 @@
+                       memory-region = <&mfc_r_mem>;
+               };
+       };
++
++      ehci@12580000 {
++              status = "okay";
++              phys = <&exynos_usbphy 1>;
++              phy-names = "host";
++      };
++
++      exynos_usbphy: exynos-usbphy@125B0000 {
++              compatible = "samsung,exynos4210-usbphy";
++              reg = <0x125B0000 0x100 0x10020704 0x0c 0x1001021c 0x4>;
++              clocks = <&clock 305>, <&clock 2>, <&clock 2>, <&clock 2>,
++                                                              <&clock 2>;
++              clock-names = "phy", "device", "host", "hsic0", "hsic1";
++              status = "okay";
++              #phy-cells = <1>;
++      };
+ };
+diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
+index 0fa11d3..165e1e7 100644
+--- a/arch/arm/boot/dts/exynos4210.dtsi
++++ b/arch/arm/boot/dts/exynos4210.dtsi
+@@ -150,21 +150,6 @@
+               status = "ok";
+       };
+-      usbphy@125B0000 {
+-              compatible = "samsung,exynos4210-usb2phy";
+-              reg = <0x125B0000 0x100>;
+-              ranges;
+-              #address-cells = <1>;
+-              #size-cells = <1>;
+-              clocks = <&clock 305>;
+-              clock-names = "otg";
+-              status = "disabled";
+-
+-              usbphy-sys {
+-                      reg = <0x10020704 0x8>;
+-              };
+-      };
+-
+       camera {
+               clocks = <&clock 132>, <&clock 133>, <&clock 351>, <&clock 352>,
+                        <&clock 388>, <&clock 389>, <&clock 9>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0838-ehci-s5p-Add-power-regulator-support.patch b/patches.tizen/0838-ehci-s5p-Add-power-regulator-support.patch
new file mode 100644 (file)
index 0000000..aaa5d49
--- /dev/null
@@ -0,0 +1,114 @@
+From 7778dad773a9c3c7eae7446f8fdbb9e11043e29e Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Wed, 2 Oct 2013 11:08:17 +0200
+Subject: [PATCH 0838/1302] ehci-s5p: Add power regulator support
+
+Add rgulator support for the ehci-s5p driver. Before this patch the driver
+relied on the regulators being switched on either by bootloader or other
+drivers.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/host/ehci-s5p.c | 36 ++++++++++++++++++++++++++++++++++--
+ 1 file changed, 34 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
+index 49ec64c..4f15e6b 100644
+--- a/drivers/usb/host/ehci-s5p.c
++++ b/drivers/usb/host/ehci-s5p.c
+@@ -22,6 +22,7 @@
+ #include <linux/phy/phy.h>
+ #include <linux/platform_device.h>
+ #include <linux/platform_data/usb-ehci-s5p.h>
++#include <linux/regulator/consumer.h>
+ #include <linux/usb/phy.h>
+ #include <linux/usb/samsung_usb_phy.h>
+ #include <linux/usb.h>
+@@ -47,6 +48,11 @@
+ static const char hcd_name[] = "ehci-s5p";
+ static struct hc_driver __read_mostly s5p_ehci_hc_driver;
++static const char * const s5p_ehci_supply_names[] = {
++      "vusb_d",               /* digital USB supply */
++      "vusb_a",               /* analog USB supply */
++};
++
+ struct s5p_ehci_hcd {
+       struct clk *clk;
+       int power_on;
+@@ -54,6 +60,7 @@ struct s5p_ehci_hcd {
+       struct usb_otg *otg;
+       struct usb_bus *host;
+       struct s5p_ehci_platdata *pdata;
++      struct regulator_bulk_data supplies[ARRAY_SIZE(s5p_ehci_supply_names)];
+ };
+ #define to_s5p_ehci(hcd)      (struct s5p_ehci_hcd *)(hcd_to_ehci(hcd)->priv)
+@@ -138,7 +145,7 @@ static ssize_t store_ehci_power(struct device *dev,
+               }
+               s5p_ehci_phy_enable(s5p_ehci, pdev);
+-                      
++
+               s5p_ehci_configurate(hcd);
+               irq = platform_get_irq(pdev, 0);
+@@ -199,6 +206,7 @@ static int s5p_ehci_probe(struct platform_device *pdev)
+       const char *phy_name;
+       int irq;
+       int err;
++      int i;
+       /*
+        * Right now device-tree probed devices don't get dma_mask set.
+@@ -271,6 +279,25 @@ static int s5p_ehci_probe(struct platform_device *pdev)
+       }
+       s5p_ehci->host = &hcd->self;
++      /* regulators */
++      for (i = 0; i < ARRAY_SIZE(s5p_ehci->supplies); i++)
++              s5p_ehci->supplies[i].supply = s5p_ehci_supply_names[i];
++
++      err = devm_regulator_bulk_get(&pdev->dev, ARRAY_SIZE(s5p_ehci->supplies),
++                               s5p_ehci->supplies);
++      if (err) {
++              dev_err(&pdev->dev, "Failed to request regulators\n");
++              goto fail_get_reg;
++      }
++
++      err = regulator_bulk_enable(ARRAY_SIZE(s5p_ehci->supplies),
++                                  s5p_ehci->supplies);
++
++      if (err) {
++              dev_err(&pdev->dev, "Failed to enable regulators\n");
++              goto fail_enable_reg;
++      }
++
+       s5p_ehci_phy_enable(s5p_ehci, pdev);
+@@ -295,7 +322,10 @@ static int s5p_ehci_probe(struct platform_device *pdev)
+ fail_add_hcd:
+       s5p_ehci_phy_disable(s5p_ehci, pdev);
+-
++      regulator_bulk_disable(ARRAY_SIZE(s5p_ehci->supplies),
++                                  s5p_ehci->supplies);
++fail_enable_reg:
++fail_get_reg:
+ fail_io:
+       clk_disable_unprepare(s5p_ehci->clk);
+ fail_clk:
+@@ -319,6 +349,8 @@ static int s5p_ehci_remove(struct platform_device *pdev)
+       clk_disable_unprepare(s5p_ehci->clk);
++      regulator_bulk_disable(ARRAY_SIZE(s5p_ehci->supplies),
++                                  s5p_ehci->supplies);
+       usb_put_hcd(hcd);
+       return 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0839-ehci-s5p-Add-second-clock-to-the-ehci-s5p-driver.patch b/patches.tizen/0839-ehci-s5p-Add-second-clock-to-the-ehci-s5p-driver.patch
new file mode 100644 (file)
index 0000000..edefe57
--- /dev/null
@@ -0,0 +1,118 @@
+From 7759e2a1a915c27f400ca9289ba84bc8fdfe890e Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Mon, 7 Oct 2013 12:35:40 +0200
+Subject: [PATCH 0839/1302] ehci-s5p: Add second clock to the ehci-s5p driver
+
+Adding the second clock was necessary for the USB HOST to work. Previously
+it was working thanks to the USB DEVICE driver being loaded first.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/host/ehci-s5p.c | 43 ++++++++++++++++++++++++++++++-------------
+ 1 file changed, 30 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
+index 4f15e6b..c321a3b 100644
+--- a/drivers/usb/host/ehci-s5p.c
++++ b/drivers/usb/host/ehci-s5p.c
+@@ -54,7 +54,8 @@ static const char * const s5p_ehci_supply_names[] = {
+ };
+ struct s5p_ehci_hcd {
+-      struct clk *clk;
++      struct clk *clk1;
++      struct clk *clk2;
+       int power_on;
+       struct phy *phy;
+       struct usb_otg *otg;
+@@ -121,7 +122,6 @@ static ssize_t store_ehci_power(struct device *dev,
+                               const char *buf, size_t count)
+ {
+       struct platform_device *pdev = to_platform_device(dev);
+-      struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
+       struct usb_hcd *hcd = platform_get_drvdata(pdev);
+       struct s5p_ehci_hcd *s5p_ehci = to_s5p_ehci(hcd);
+       int power_on;
+@@ -243,17 +243,29 @@ static int s5p_ehci_probe(struct platform_device *pdev)
+ /*            s5p_ehci->otg = phy->otg;*/
+       }
+-      s5p_ehci->clk = devm_clk_get(&pdev->dev, "usbhost");
++      s5p_ehci->clk1 = devm_clk_get(&pdev->dev, "usbhost");
+-      if (IS_ERR(s5p_ehci->clk)) {
++      if (IS_ERR(s5p_ehci->clk1)) {
+               dev_err(&pdev->dev, "Failed to get usbhost clock\n");
+-              err = PTR_ERR(s5p_ehci->clk);
+-              goto fail_clk;
++              err = PTR_ERR(s5p_ehci->clk1);
++              goto fail_clk1;
++      }
++
++      err = clk_prepare_enable(s5p_ehci->clk1);
++      if (err)
++              goto fail_clk1;
++
++      s5p_ehci->clk2 = devm_clk_get(&pdev->dev, "otg");
++
++      if (IS_ERR(s5p_ehci->clk2)) {
++              dev_err(&pdev->dev, "Failed to get otg clock\n");
++              err = PTR_ERR(s5p_ehci->clk2);
++              goto fail_clk2;
+       }
+-      err = clk_prepare_enable(s5p_ehci->clk);
++      err = clk_prepare_enable(s5p_ehci->clk2);
+       if (err)
+-              goto fail_clk;
++              goto fail_clk2;
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+@@ -327,8 +339,10 @@ fail_add_hcd:
+ fail_enable_reg:
+ fail_get_reg:
+ fail_io:
+-      clk_disable_unprepare(s5p_ehci->clk);
+-fail_clk:
++      clk_disable_unprepare(s5p_ehci->clk2);
++fail_clk2:
++      clk_disable_unprepare(s5p_ehci->clk1);
++fail_clk1:
+       usb_put_hcd(hcd);
+       return err;
+ }
+@@ -347,7 +361,8 @@ static int s5p_ehci_remove(struct platform_device *pdev)
+       s5p_ehci_phy_disable(s5p_ehci, pdev);
+-      clk_disable_unprepare(s5p_ehci->clk);
++      clk_disable_unprepare(s5p_ehci->clk1);
++      clk_disable_unprepare(s5p_ehci->clk2);
+       regulator_bulk_disable(ARRAY_SIZE(s5p_ehci->supplies),
+                                   s5p_ehci->supplies);
+@@ -381,7 +396,8 @@ static int s5p_ehci_suspend(struct device *dev)
+       s5p_ehci_phy_disable(s5p_ehci, pdev);
+-      clk_disable_unprepare(s5p_ehci->clk);
++      clk_disable_unprepare(s5p_ehci->clk1);
++      clk_disable_unprepare(s5p_ehci->clk2);
+       return rc;
+ }
+@@ -392,7 +408,8 @@ static int s5p_ehci_resume(struct device *dev)
+       struct  s5p_ehci_hcd *s5p_ehci = to_s5p_ehci(hcd);
+       struct platform_device *pdev = to_platform_device(dev);
+-      clk_prepare_enable(s5p_ehci->clk);
++      clk_prepare_enable(s5p_ehci->clk1);
++      clk_prepare_enable(s5p_ehci->clk2);
+       if (s5p_ehci->otg)
+               s5p_ehci->otg->set_host(s5p_ehci->otg, &hcd->self);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0840-dts-arm-Add-voltage-regulator-and-additional-clock-s.patch b/patches.tizen/0840-dts-arm-Add-voltage-regulator-and-additional-clock-s.patch
new file mode 100644 (file)
index 0000000..95ef37a
--- /dev/null
@@ -0,0 +1,89 @@
+From 1986f941ed6c4a61dafa5498ec06f9671b25b3e9 Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Tue, 8 Oct 2013 10:53:58 +0200
+Subject: [PATCH 0840/1302] dts: arm: Add voltage regulator and additional
+ clock supply to ehci-s5p
+
+This patch adds voltage regulator and additional clock support to the
+ehci-s5p driver.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi                  | 4 ++--
+ arch/arm/boot/dts/exynos4210-origen.dts         | 2 ++
+ arch/arm/boot/dts/exynos4210-universal_c210.dts | 2 ++
+ arch/arm/boot/dts/exynos4412-odroidx2.dts       | 2 ++
+ arch/arm/boot/dts/exynos4412-slp_pq.dts         | 2 ++
+ 5 files changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index c5c1516..d9b14b3 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -506,8 +506,8 @@
+               compatible = "samsung,exynos-ehci";
+               reg = <0x12580000 0x20000>;
+               interrupts = <0 70 0>;
+-              clocks = <&clock 304>;
+-              clock-names = "usbhost";
++              clocks = <&clock 304>, <&clock 305>;
++              clock-names = "usbhost", "otg";
+               status = "disabled";
+       };
+diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts
+index 40fd476..862463b 100644
+--- a/arch/arm/boot/dts/exynos4210-origen.dts
++++ b/arch/arm/boot/dts/exynos4210-origen.dts
+@@ -175,6 +175,8 @@
+       };
+       ehci@12580000 {
++              vusb_d-supply = <&ldo3_reg>;
++              vusb_a-supply = <&ldo8_reg>;
+               status = "okay";
+               phys = <&exynos_usbphy 1>;
+               phy-names = "host";
+diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts
+index e063602..045221e 100644
+--- a/arch/arm/boot/dts/exynos4210-universal_c210.dts
++++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts
+@@ -445,6 +445,8 @@
+               status = "okay";
+               phys = <&exynos_usbphy 1>;
+               phy-names = "host";
++              vusb_d-supply = <&ldo3_reg>;
++              vusb_a-supply = <&ldo8_reg>;
+       };
+       exynos_usbphy: exynos-usbphy@125B0000 {
+diff --git a/arch/arm/boot/dts/exynos4412-odroidx2.dts b/arch/arm/boot/dts/exynos4412-odroidx2.dts
+index c93fb7a..05fea1b 100644
+--- a/arch/arm/boot/dts/exynos4412-odroidx2.dts
++++ b/arch/arm/boot/dts/exynos4412-odroidx2.dts
+@@ -439,6 +439,8 @@
+       ehci@12580000 {
+               status = "okay";
++              vusb_d-supply = <&ldo15_reg>;
++              vusb_a-supply = <&ldo12_reg>;
+               phys = <&exynos_usbphy 2>;
+               phy-names = "hsic0";
+       };
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 4cf3f59..e8d0bbc 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -1073,6 +1073,8 @@
+       ehci@12580000 {
+               status = "okay";
++              vusb_d-supply = <&ldo15_reg>;
++              vusb_a-supply = <&ldo12_reg>;
+               phys = <&exynos_usbphy 2>;
+               phy-names = "hsic0";
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0841-phy-exynos-usb-Fix-referenct-counting.patch b/patches.tizen/0841-phy-exynos-usb-Fix-referenct-counting.patch
new file mode 100644 (file)
index 0000000..654503f
--- /dev/null
@@ -0,0 +1,29 @@
+From 3d4407f5de7182a1d2da00fe6d2175cf7a07b23f Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Tue, 1 Oct 2013 15:48:13 +0200
+Subject: [PATCH 0841/1302] phy: exynos-usb: Fix referenct counting
+
+This patch fixes the reference counting when powerin on/off the phy.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/phy/phy-exynos4210-usb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/phy/phy-exynos4210-usb.c b/drivers/phy/phy-exynos4210-usb.c
+index 4b849e7..d75a554 100644
+--- a/drivers/phy/phy-exynos4210-usb.c
++++ b/drivers/phy/phy-exynos4210-usb.c
+@@ -250,7 +250,7 @@ static int exynos4210_power_off(struct uphy_instance *inst)
+       }
+       inst->state = STATE_OFF;
+-      inst->ref_cnt++;
++      inst->ref_cnt--;
+       if (inst->ref_cnt > 0)
+               return 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0842-phy-exynos-Change-order-of-initialization-of-phy-in-.patch b/patches.tizen/0842-phy-exynos-Change-order-of-initialization-of-phy-in-.patch
new file mode 100644 (file)
index 0000000..54589d4
--- /dev/null
@@ -0,0 +1,79 @@
+From 76b58e12d107da58b45d2fd27087a0360ab379a6 Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Mon, 7 Oct 2013 18:23:49 +0200
+Subject: [PATCH 0842/1302] phy: exynos: Change order of initialization of phy
+ in power_on
+
+The order was changed to turn power on first and the disable the physical
+isolation.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+
+Phy driver change - order of init - to be squashed
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/phy/phy-exynos4210-usb.c | 24 ++----------------------
+ drivers/phy/phy-exynos4212-usb.c |  2 +-
+ 2 files changed, 3 insertions(+), 23 deletions(-)
+
+diff --git a/drivers/phy/phy-exynos4210-usb.c b/drivers/phy/phy-exynos4210-usb.c
+index d75a554..6102aac 100644
+--- a/drivers/phy/phy-exynos4210-usb.c
++++ b/drivers/phy/phy-exynos4210-usb.c
+@@ -222,19 +222,9 @@ static int exynos4210_power_on(struct uphy_instance *inst)
+       if (inst->ref_cnt > 1)
+               return 0;
+-      exynos4210_isol(inst, 0);
++      /* Order of initialisation is important - first power then isolation */
+       exynos4210_phy_pwr(inst, 1);
+-
+-      /* Power on the device, as it is necessary for HSIC to work */
+-      if (inst->cfg->id == EXYNOS4210_HOST) {
+-              struct uphy_instance *device =
+-                                      &drv->uphy_instances[EXYNOS4210_DEVICE];
+-              device->ref_cnt++;
+-              if (device->ref_cnt > 1)
+-                      return 0;
+-              exynos4210_phy_pwr(device, 1);
+-              exynos4210_isol(device, 0);
+-      }
++      exynos4210_isol(inst, 0);
+       return 0;
+ }
+@@ -257,16 +247,6 @@ static int exynos4210_power_off(struct uphy_instance *inst)
+       exynos4210_phy_pwr(inst, 0);
+       exynos4210_isol(inst, 1);
+-      if (inst->cfg->id == EXYNOS4210_HOST) {
+-              struct uphy_instance *device =
+-                                      &drv->uphy_instances[EXYNOS4210_DEVICE];
+-              device->ref_cnt--;
+-              if (device->ref_cnt > 0)
+-                      return 0;
+-              exynos4210_phy_pwr(device, 0);
+-              exynos4210_isol(device, 1);
+-      }
+-
+       return 0;
+ }
+diff --git a/drivers/phy/phy-exynos4212-usb.c b/drivers/phy/phy-exynos4212-usb.c
+index 80480a4..b7de33f 100644
+--- a/drivers/phy/phy-exynos4212-usb.c
++++ b/drivers/phy/phy-exynos4212-usb.c
+@@ -255,8 +255,8 @@ static int exynos4212_power_on(struct uphy_instance *inst)
+       if (inst->ref_cnt > 1)
+               return 0;
+-      exynos4212_isol(inst, 0);
+       exynos4212_phy_pwr(inst, 1);
++      exynos4212_isol(inst, 0);
+       /* Power on the device, as it is necessary for HSIC to work */
+       if (inst->cfg->id == EXYNOS4212_HSIC0) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0843-regulator-dts-slp-PD-MAX8997-device-tree-nodes-defin.patch b/patches.tizen/0843-regulator-dts-slp-PD-MAX8997-device-tree-nodes-defin.patch
new file mode 100644 (file)
index 0000000..2eacd00
--- /dev/null
@@ -0,0 +1,112 @@
+From 3f6f1fb35c2aa14a40d70b4673bae75fc9fee1e2 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Tue, 8 Oct 2013 11:50:35 +0200
+Subject: [PATCH 0843/1302] regulator:dts:slp-PD: MAX8997 device tree nodes
+ definitions for MIDAS (PEGASUS_D)
+
+Adjustment of regulator configuration (max8997) for MIDAS (PEGASUSD) device.
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4212-slp_pd.dts | 50 ++++++++++++++++-----------------
+ 1 file changed, 25 insertions(+), 25 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4212-slp_pd.dts b/arch/arm/boot/dts/exynos4212-slp_pd.dts
+index 4b2e573..7d658f3 100644
+--- a/arch/arm/boot/dts/exynos4212-slp_pd.dts
++++ b/arch/arm/boot/dts/exynos4212-slp_pd.dts
+@@ -143,23 +143,23 @@
+                       max8997,pmic-buck125-default-dvs-idx = <0>;
+                       max8997,pmic-buck125-dvs-gpios = <&gpj1 1 0>,
+-                                                       <&gpj1 2 0>,
++                                                       <&gpj1 2 0>,
+                                                        <&gpl0 0 0>;
+-                      max8997,pmic-buck1-dvs-voltage = <1100000>, <1100000>,
+-                                                       <1100000>, <1100000>,
+-                                                       <1100000>, <1100000>,
+-                                                       <1100000>, <1100000>;
++                      max8997,pmic-buck1-dvs-voltage = <1350000>, <1300000>,
++                                                       <1250000>, <1200000>,
++                                                       <1150000>, <1100000>,
++                                                       <1000000>, <950000>;
+-                      max8997,pmic-buck2-dvs-voltage = <1100000>, <1100000>,
+-                                                       <1100000>, <1100000>,
+-                                                       <1100000>, <1100000>,
+-                                                       <1100000>, <1100000>;
++                      max8997,pmic-buck2-dvs-voltage = <1100000>, <1000000>,
++                                                       <950000>,  <900000>,
++                                                       <1100000>, <1000000>,
++                                                       <950000>,  <900000>;
+-                      max8997,pmic-buck5-dvs-voltage = <1100000>, <1100000>,
+-                                                       <1100000>, <1100000>,
+-                                                       <1100000>, <1100000>,
+-                                                       <1100000>, <1100000>;
++                      max8997,pmic-buck5-dvs-voltage = <1200000>, <1200000>,
++                                                       <1200000>, <1200000>,
++                                                       <1200000>, <1200000>,
++                                                       <1200000>, <1200000>;
+                       regulators {
+@@ -186,8 +186,8 @@
+                               ldo4_reg: LDO4 {
+                                       regulator-name = "VABB02_1.8V_AP";
+-                                      regulator-min-microvolt = <1000000>;
+-                                      regulator-max-microvolt = <1000000>;
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                               };
+@@ -226,8 +226,8 @@
+                               ldo10_reg: LDO10 {
+                                       regulator-name = "VPLL_1.0V_AP";
+-                                      regulator-min-microvolt = <1000000>;
+-                                      regulator-max-microvolt = <1000000>;
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                               };
+@@ -288,23 +288,23 @@
+                               };
+                               buck1_reg: BUCK1 {
+-                                      regulator-name = "VARM_1.0V_AP";
+-                                      regulator-min-microvolt = <1000000>;
+-                                      regulator-max-microvolt = <1000000>;
++                                      regulator-name = "vdd_arm";
++                                      regulator-min-microvolt = <900000>;
++                                      regulator-max-microvolt = <1350000>;
+                                       regulator-always-on;
+                               };
+                               buck2_reg: BUCK2 {
+-                                      regulator-name = "VINT_1.0V_AP";
+-                                      regulator-min-microvolt = <1000000>;
+-                                      regulator-max-microvolt = <1000000>;
++                                      regulator-name = "vdd_int";
++                                      regulator-min-microvolt = <900000>;
++                                      regulator-max-microvolt = <1100000>;
+                                       regulator-always-on;
+                               };
+                               buck3_reg: BUCK3 {
+                                       regulator-name = "VG3D_1.0V_AP";
+-                                      regulator-min-microvolt = <1000000>;
+-                                      regulator-max-microvolt = <1000000>;
++                                      regulator-min-microvolt = <850000>;
++                                      regulator-max-microvolt = <1100000>;
+                                       regulator-always-on;
+                               };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0844-ARM-cpufreq-Parse-CPUFREQ-s-voltage-table-passed-as-.patch b/patches.tizen/0844-ARM-cpufreq-Parse-CPUFREQ-s-voltage-table-passed-as-.patch
new file mode 100644 (file)
index 0000000..79aadce
--- /dev/null
@@ -0,0 +1,105 @@
+From 18776abba56d97c6a3d38de6104fd28c5bca2552 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Tue, 8 Oct 2013 11:57:13 +0200
+Subject: [PATCH 0844/1302] ARM: cpufreq: Parse CPUFREQ's voltage table passed
+ as device tree node
+
+Now it is possible to parse cpufreq's voltage table information passed as
+device tree node. This is handy for various different PMICs.
+
+It is also possible to override this device tree node by defining empty
+"volt_table" node. Then default exynos4x12_volt_table[] is used.
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/exynos-cpufreq.c     | 45 ++++++++++++++++++++++++++++++++++++
+ drivers/cpufreq/exynos-cpufreq.h     |  2 ++
+ drivers/cpufreq/exynos4x12-cpufreq.c |  5 +++-
+ 3 files changed, 51 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c
+index d748ada..aa869de 100644
+--- a/drivers/cpufreq/exynos-cpufreq.c
++++ b/drivers/cpufreq/exynos-cpufreq.c
+@@ -350,6 +350,51 @@ struct cpufreq_frequency_table *exynos_of_parse_freq_table(
+       return ret;
+ }
++unsigned int *exynos_of_parse_volt_table(struct exynos_dvfs_info *info,
++                                       const char *property_name)
++{
++      struct device_node *node = info->dev->of_node;
++      struct property *pp;
++      int len, num;
++      u32 *of_v_tab;
++
++      if (!node)
++              return NULL;
++
++      pp = of_find_property(node, property_name, &len);
++      if (!pp) {
++              pr_debug("%s: Property: %s not found\n", __func__,
++                       property_name);
++              goto err;
++      }
++
++      if (len == 0) {
++              pr_debug("%s: Length wrong value!\n", __func__);
++              goto err;
++      }
++
++      of_v_tab = kzalloc(len, GFP_KERNEL);
++      if (!of_v_tab) {
++              pr_err("%s: Allocation failed\n", __func__);
++              goto err;
++      }
++
++      num = len / sizeof(u32);
++      if (of_property_read_u32_array(node, pp->name, of_v_tab, num)) {
++              pr_err("%s: Property: %s cannot be read!\n", __func__,
++                     pp->name);
++              goto err_of_v_tab;
++      }
++
++      return of_v_tab;
++
++ err_of_v_tab:
++      kfree(of_v_tab);
++ err:
++      return NULL;
++}
++
++
+ #ifdef CONFIG_OF
+ static struct of_device_id exynos_cpufreq_of_match[] = {
+       { .compatible = "samsung,exynos-cpufreq", },
+diff --git a/drivers/cpufreq/exynos-cpufreq.h b/drivers/cpufreq/exynos-cpufreq.h
+index 4e08ba7..8ad711f 100644
+--- a/drivers/cpufreq/exynos-cpufreq.h
++++ b/drivers/cpufreq/exynos-cpufreq.h
+@@ -49,3 +49,5 @@ extern int exynos4x12_cpufreq_init(struct exynos_dvfs_info *);
+ extern int exynos5250_cpufreq_init(struct exynos_dvfs_info *);
+ extern struct cpufreq_frequency_table *exynos_of_parse_freq_table(
+               struct exynos_dvfs_info *info, const char *property_name);
++unsigned int *exynos_of_parse_volt_table(struct exynos_dvfs_info *info,
++                                       const char *property_name);
+diff --git a/drivers/cpufreq/exynos4x12-cpufreq.c b/drivers/cpufreq/exynos4x12-cpufreq.c
+index 1359fd9..8b2749d 100644
+--- a/drivers/cpufreq/exynos4x12-cpufreq.c
++++ b/drivers/cpufreq/exynos4x12-cpufreq.c
+@@ -232,7 +232,10 @@ int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
+       /* 800Mhz */
+       info->pll_safe_idx = L7;
+       info->cpu_clk = cpu_clk;
+-      info->volt_table = exynos4x12_volt_table;
++
++      info->volt_table = exynos_of_parse_volt_table(info, "volt_table");
++      if (!info->volt_table)
++              info->volt_table = exynos4x12_volt_table;
+       info->freq_table = exynos_of_parse_freq_table(info, "freq_table");
+       if (!info->freq_table)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0845-ARM-clk-exynos-pll35xx-Extend-pll35xx_set_rate-to-su.patch b/patches.tizen/0845-ARM-clk-exynos-pll35xx-Extend-pll35xx_set_rate-to-su.patch
new file mode 100644 (file)
index 0000000..7ccecd2
--- /dev/null
@@ -0,0 +1,93 @@
+From 5a7c61fcde55eea20f314c67bd315ebe9b5c77c7 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Tue, 8 Oct 2013 12:02:53 +0200
+Subject: [PATCH 0845/1302] ARM:clk:exynos:pll35xx: Extend pll35xx_set_rate to
+ support only S parameter switch
+
+With PLL35xx device it is possible to switch PLL frequency without waiting
+for locking.
+This situation happens when P and M for new frequency are equal to
+corresponding parameters for old frequency. Then only S needs to be changed.
+In this patch support for such a change is provided.
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/samsung/clk-pll.c | 37 +++++++++++++++++++++++++++----------
+ 1 file changed, 27 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
+index 6be496a..170d6ca3 100644
+--- a/drivers/clk/samsung/clk-pll.c
++++ b/drivers/clk/samsung/clk-pll.c
+@@ -58,16 +58,22 @@ static inline unsigned long samsung_pll35xx_calc_f_out(u64 f_in,
+ #define to_clk_pll35xx(_hw) container_of(_hw, struct samsung_clk_pll35xx, hw)
++static inline void samsung_pll35xx_get_mps(struct samsung_clk_pll35xx *pll,
++                                         u32 *m, u32 *p, u32 *s)
++{
++      u32 pll_con = __raw_readl(pll->base_reg + PLL35XX_PLL_CON0);
++
++      *m = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
++      *p = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
++      *s = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK;
++}
++
+ static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
+                               unsigned long parent_rate)
+ {
+       struct samsung_clk_pll35xx *pll = to_clk_pll35xx(hw);
+-      u32 mdiv, pdiv, sdiv, pll_con;
+-
+-      pll_con = __raw_readl(pll->base_reg + PLL35XX_PLL_CON0);
+-      mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
+-      pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
+-      sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK;
++      u32 mdiv, pdiv, sdiv;
++      samsung_pll35xx_get_mps(pll, &mdiv, &pdiv, &sdiv);
+       return samsung_pll35xx_calc_f_out(parent_rate, pdiv, mdiv, sdiv);
+ }
+@@ -97,6 +103,7 @@ static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
+       struct samsung_clk_pll35xx *pll = to_clk_pll35xx(hw);
+       u32 p = 0, m = 0, s = 0, tmp = 0;
+       struct pll_pms *pms = pll->pms;
++      u32 p_cur, m_cur, s_cur;
+       int index;
+       if (!pms) {
+@@ -105,16 +112,26 @@ static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
+       }
+       index = get_index(drate, pll->pms);
++      p = pms[index].p;
++      m = pms[index].m;
++      s = pms[index].s;
++
++      samsung_pll35xx_get_mps(pll, &m_cur, &p_cur, &s_cur);
++
++      if (p == p_cur && m == m_cur) {
++              tmp = __raw_readl(pll->base_reg + PLL35XX_PLL_CON0);
++              tmp &= ~(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT);
++              tmp |= s << PLL35XX_SDIV_SHIFT;
++              __raw_writel(tmp, (u32 *)(pll->base_reg  + PLL35XX_PLL_CON0));
++
++              return 0;
++      }
+       /* Define PLL lock time */
+-      p = pms[index].p;
+       __raw_writel((p * PLL35XX_PLL_LOCK_CONST),
+                    (u32*) (pll->base_reg + PLL35XX_PLL_LOCK));
+       /* Change PLL PMS */
+-      m = pms[index].m;
+-      s = pms[index].s;
+-
+       tmp = __raw_readl(pll->base_reg + PLL35XX_PLL_CON0);
+       tmp &= ~((PLL35XX_PDIV_MASK << PLL35XX_PDIV_SHIFT) |
+               (PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT) |
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0846-cpufreq-exynos4x12-Support-the-frequency-change-only.patch b/patches.tizen/0846-cpufreq-exynos4x12-Support-the-frequency-change-only.patch
new file mode 100644 (file)
index 0000000..a25edd8
--- /dev/null
@@ -0,0 +1,90 @@
+From 53eebee9a4f2e1691727c201f33736bd60b18b03 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Tue, 8 Oct 2013 12:06:59 +0200
+Subject: [PATCH 0846/1302] cpufreq: exynos4x12: Support the frequency change
+ only with the common clock framework
+
+The exynos4x12_pms_change() function has been removed since the PLL's S
+parameter change is already preformed at PLL code.
+
+Also the code which changed the S value at exynos4x12_set_frequency() has been
+removed.
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/exynos4x12-cpufreq.c | 46 ++++--------------------------------
+ 1 file changed, 4 insertions(+), 42 deletions(-)
+
+diff --git a/drivers/cpufreq/exynos4x12-cpufreq.c b/drivers/cpufreq/exynos4x12-cpufreq.c
+index 8b2749d..1e5331b 100644
+--- a/drivers/cpufreq/exynos4x12-cpufreq.c
++++ b/drivers/cpufreq/exynos4x12-cpufreq.c
+@@ -153,52 +153,15 @@ static void exynos4x12_set_apll(unsigned int index)
+       } while (tmp != (0x1 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT));
+ }
+-static bool exynos4x12_pms_change(unsigned int old_index, unsigned int new_index)
+-{
+-      unsigned int old_pm = apll_freq_4x12[old_index].mps >> 8;
+-      unsigned int new_pm = apll_freq_4x12[new_index].mps >> 8;
+-
+-      return (old_pm == new_pm) ? 0 : 1;
+-}
+-
+ static void exynos4x12_set_frequency(unsigned int old_index,
+                                 unsigned int new_index)
+ {
+-      unsigned int tmp;
+-
+       if (old_index > new_index) {
+-              if (!exynos4x12_pms_change(old_index, new_index)) {
+-                      /* 1. Change the system clock divider values */
+-                      exynos4x12_set_clkdiv(new_index);
+-                      /* 2. Change just s value in apll m,p,s value */
+-                      tmp = __raw_readl(EXYNOS4_APLL_CON0);
+-                      tmp &= ~(0x7 << 0);
+-                      tmp |= apll_freq_4x12[new_index].mps & 0x7;
+-                      __raw_writel(tmp, EXYNOS4_APLL_CON0);
+-
+-              } else {
+-                      /* Clock Configuration Procedure */
+-                      /* 1. Change the system clock divider values */
+-                      exynos4x12_set_clkdiv(new_index);
+-                      /* 2. Change the apll m,p,s value */
+-                      exynos4x12_set_apll(new_index);
+-              }
++              exynos4x12_set_clkdiv(new_index);
++              exynos4x12_set_apll(new_index);
+       } else if (old_index < new_index) {
+-              if (!exynos4x12_pms_change(old_index, new_index)) {
+-                      /* 1. Change just s value in apll m,p,s value */
+-                      tmp = __raw_readl(EXYNOS4_APLL_CON0);
+-                      tmp &= ~(0x7 << 0);
+-                      tmp |= apll_freq_4x12[new_index].mps & 0x7;
+-                      __raw_writel(tmp, EXYNOS4_APLL_CON0);
+-                      /* 2. Change the system clock divider values */
+-                      exynos4x12_set_clkdiv(new_index);
+-              } else {
+-                      /* Clock Configuration Procedure */
+-                      /* 1. Change the apll m,p,s value */
+-                      exynos4x12_set_apll(new_index);
+-                      /* 2. Change the system clock divider values */
+-                      exynos4x12_set_clkdiv(new_index);
+-              }
++              exynos4x12_set_apll(new_index);
++              exynos4x12_set_clkdiv(new_index);
+       }
+ }
+@@ -242,7 +205,6 @@ int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
+               info->freq_table = exynos4x12_freq_table;
+       info->set_freq = exynos4x12_set_frequency;
+-      info->need_apll_change = exynos4x12_pms_change;
+       return 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0847-cosmetic-Remove-extern-from-exynos_of_parse_freq_tab.patch b/patches.tizen/0847-cosmetic-Remove-extern-from-exynos_of_parse_freq_tab.patch
new file mode 100644 (file)
index 0000000..78b9362
--- /dev/null
@@ -0,0 +1,29 @@
+From ec338a8b3489b3c0092746a353fb3136e2d4703d Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Tue, 8 Oct 2013 12:07:43 +0200
+Subject: [PATCH 0847/1302] cosmetic: Remove extern from
+ exynos_of_parse_freq_table() declaration
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/exynos-cpufreq.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/cpufreq/exynos-cpufreq.h b/drivers/cpufreq/exynos-cpufreq.h
+index 8ad711f..12b2b66 100644
+--- a/drivers/cpufreq/exynos-cpufreq.h
++++ b/drivers/cpufreq/exynos-cpufreq.h
+@@ -47,7 +47,7 @@ struct exynos_dvfs_info {
+ extern int exynos4210_cpufreq_init(struct exynos_dvfs_info *);
+ extern int exynos4x12_cpufreq_init(struct exynos_dvfs_info *);
+ extern int exynos5250_cpufreq_init(struct exynos_dvfs_info *);
+-extern struct cpufreq_frequency_table *exynos_of_parse_freq_table(
+-              struct exynos_dvfs_info *info, const char *property_name);
++struct cpufreq_frequency_table *exynos_of_parse_freq_table(
++       struct exynos_dvfs_info *info, const char *property_name);
+ unsigned int *exynos_of_parse_volt_table(struct exynos_dvfs_info *info,
+                                        const char *property_name);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0848-dts-cpufreq-exynos4212-pegasusD-Enable-support-for-c.patch b/patches.tizen/0848-dts-cpufreq-exynos4212-pegasusD-Enable-support-for-c.patch
new file mode 100644 (file)
index 0000000..8d27761
--- /dev/null
@@ -0,0 +1,38 @@
+From e4838f0ee21e969fa888f7274432e7221b06321a Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Tue, 8 Oct 2013 12:13:21 +0200
+Subject: [PATCH 0848/1302] dts:cpufreq:exynos4212:pegasusD: Enable support for
+ cpufreq at PEGASUS D via device tree
+
+Enable cpufreq driver via DTS. Also empty freq_table is defined to override
+"default" freq_table defined for PROXIMA PQ.
+
+The volt_table has been defined to reflect MAX8997 based DVS on the PegasusD
+device. This volt_table also can be overrided when defined as empty.
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4212-slp_pd.dts | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4212-slp_pd.dts b/arch/arm/boot/dts/exynos4212-slp_pd.dts
+index 7d658f3..831e72a 100644
+--- a/arch/arm/boot/dts/exynos4212-slp_pd.dts
++++ b/arch/arm/boot/dts/exynos4212-slp_pd.dts
+@@ -345,4 +345,12 @@
+               status = "okay";
+               #phy-cells = <1>;
+       };
++
++      cpufreq {
++              freq_table;
++              volt_table = <1350000 1300000 1300000 1250000 1250000 1200000
++                           1200000 1150000 1100000 1000000 1000000 950000
++                           950000 950000>;
++              status = "okay";
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0849-dts-thermal-exynos4212-pegasusD-Device-tree-node-def.patch b/patches.tizen/0849-dts-thermal-exynos4212-pegasusD-Device-tree-node-def.patch
new file mode 100644 (file)
index 0000000..cacb86d
--- /dev/null
@@ -0,0 +1,31 @@
+From 59c8b8b56ac301c2da55817979efb42ac0a94853 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Tue, 8 Oct 2013 12:14:28 +0200
+Subject: [PATCH 0849/1302] dts:thermal:exynos4212:pegasusD: Device tree node
+ definition for TMU
+
+Device tree nodes defined for Exynos4212 based PEGASUS D device.
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4212-slp_pd.dts | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4212-slp_pd.dts b/arch/arm/boot/dts/exynos4212-slp_pd.dts
+index 831e72a..4c8d1a7 100644
+--- a/arch/arm/boot/dts/exynos4212-slp_pd.dts
++++ b/arch/arm/boot/dts/exynos4212-slp_pd.dts
+@@ -353,4 +353,9 @@
+                            950000 950000>;
+               status = "okay";
+       };
++
++      tmu@100C0000 {
++              vdd_ts-supply = <&ldo4_reg>;
++              status = "okay";
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0850-dts-exynos4412-redwood-Adjust-REDWOOD-dts-to-support.patch b/patches.tizen/0850-dts-exynos4412-redwood-Adjust-REDWOOD-dts-to-support.patch
new file mode 100644 (file)
index 0000000..36ad53a
--- /dev/null
@@ -0,0 +1,33 @@
+From 542280651b453b04a49775bc619f6934281a495b Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Tue, 8 Oct 2013 12:59:16 +0200
+Subject: [PATCH 0850/1302] dts:exynos4412-redwood: Adjust REDWOOD dts to
+ support changed cpufreq
+
+Overriding the freq_table attribute inherited from SLP_PQ (Proxima).
+Remove bindings for overlocking (now it is called boost).
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-redwood.dts | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-redwood.dts b/arch/arm/boot/dts/exynos4412-redwood.dts
+index b24caa8..e03854e 100644
+--- a/arch/arm/boot/dts/exynos4412-redwood.dts
++++ b/arch/arm/boot/dts/exynos4412-redwood.dts
+@@ -139,9 +139,8 @@
+       };
+       cpufreq {
++              freq_table;
+               status = "okay";
+-              overclocking = "okay";
+-              max_overclocking_freq = <1500000>;
+       };
+       tmu@100C0000 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0851-usb-gadget-Refcount-for-gadget-pullup.patch b/patches.tizen/0851-usb-gadget-Refcount-for-gadget-pullup.patch
new file mode 100644 (file)
index 0000000..54fa1e5
--- /dev/null
@@ -0,0 +1,86 @@
+From ab665417cbc1cab2bf42674bcf97f8c827478522 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Tue, 19 Jun 2012 15:28:05 +0200
+Subject: [PATCH 0851/1302] usb:gadget: Refcount for gadget pullup
+
+This commit fixes the way gadget's pullup method (wrapped at
+usb_gadget_connect/disconnect) is called in the udc-core.
+
+The composite driver allows correct driver registration, even when it calls
+the usb_gadget_disconnect method (composite driver configuration is defered
+for user space - please look into the description of usb_composite_probe at
+composite.c - line: 1623)
+
+One such example is the CCG (Configurable Composite Gadget) driver (at
+drivers/staging/ccg), which after its registration has no usb descriptor
+(i.e. idProduct, idVendor etc.) and functions registered. Those are configured
+after writing to /sys/module/g_ccg/parameters/ or /sys/class/ccg_usb/ccg0/.
+
+Unfortunately, the code at 'usb_gadget_probe_driver' method (some code omitted):
+
+       if (udc_is_newstyle(udc)) {
+               bind(udc->gadget);
+               usb_gadget_udc_start(udc->gadget, driver);
+               usb_gadget_connect(udc->gadget);
+       }
+
+Explicitly calls the usb_gadget_connect method for this driver. It looks like
+the udc-core enables pullup for a driver, which has no functions and no
+descriptor filled (those values are feed from userspace).
+
+The USB composite driver API allows correct driver registration with calling
+usb_gadget_disconnect method, but as it is now, _ALL_ newstyle usb gadgets are
+connected by default. Therefore it violates the composite API.
+
+The solution (at least until the udc-core is reworked) is to add atomic
+variable, which helps in balancing the number of called usb_gadget_connect/
+disconnect functions.
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/usb/gadget.h | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
+index f1b0dca..16892ab 100644
+--- a/include/linux/usb/gadget.h
++++ b/include/linux/usb/gadget.h
+@@ -533,6 +533,7 @@ struct usb_gadget {
+       unsigned                        b_hnp_enable:1;
+       unsigned                        a_hnp_support:1;
+       unsigned                        a_alt_hnp_support:1;
++      atomic_t                        connect_count;
+       const char                      *name;
+       struct device                   dev;
+       unsigned                        out_epnum;
+@@ -724,7 +725,11 @@ static inline int usb_gadget_connect(struct usb_gadget *gadget)
+ {
+       if (!gadget->ops->pullup)
+               return -EOPNOTSUPP;
+-      return gadget->ops->pullup(gadget, 1);
++
++      if (atomic_inc_return(&gadget->connect_count) == 1)
++              return gadget->ops->pullup(gadget, 1);
++
++      return 0;
+ }
+ /**
+@@ -746,7 +751,11 @@ static inline int usb_gadget_disconnect(struct usb_gadget *gadget)
+ {
+       if (!gadget->ops->pullup)
+               return -EOPNOTSUPP;
+-      return gadget->ops->pullup(gadget, 0);
++
++      if (atomic_dec_and_test(&gadget->connect_count))
++              return gadget->ops->pullup(gadget, 0);
++
++      return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0852-Revert-HACK-usb-gadget-Fix-enumeration-on-boot.patch b/patches.tizen/0852-Revert-HACK-usb-gadget-Fix-enumeration-on-boot.patch
new file mode 100644 (file)
index 0000000..b6ff5e9
--- /dev/null
@@ -0,0 +1,37 @@
+From 668b89679908304d0f385bd0b7f259eac152417c Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Tue, 8 Oct 2013 13:03:25 +0200
+Subject: [PATCH 0852/1302] Revert "HACK: usb: gadget: Fix enumeration on boot"
+
+This reverts commit b0c2c319763e2ace63ace30cd5b9e3e0eb0b9b48.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/udc-core.c | 11 +----------
+ 1 file changed, 1 insertion(+), 10 deletions(-)
+
+diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
+index bef2f4c..5514822 100644
+--- a/drivers/usb/gadget/udc-core.c
++++ b/drivers/usb/gadget/udc-core.c
+@@ -335,16 +335,7 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri
+               driver->unbind(udc->gadget);
+               goto err1;
+       }
+-      /*
+-               * HACK: The Android gadget driver disconnects the gadget
+-               * on bind and expects the gadget to stay disconnected until
+-               * it calls usb_gadget_connect when userspace is ready. Remove
+-               * the call to usb_gadget_connect bellow to avoid enabling the
+-               * pullup before userspace is ready.
+-               */
+-#if !defined(CONFIG_USB_G_ANDROID) && !defined(CONFIG_USB_G_SLP)
+-               usb_gadget_connect(udc->gadget);
+-#endif
++      usb_gadget_connect(udc->gadget);
+       kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
+       return 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0853-drivers-iommu-add-workaround-for-multiple-suspend-re.patch b/patches.tizen/0853-drivers-iommu-add-workaround-for-multiple-suspend-re.patch
new file mode 100644 (file)
index 0000000..b1ab60a
--- /dev/null
@@ -0,0 +1,58 @@
+From 8c821ecb8c551677c6016bf28a8ef5d46f5e5b74 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Wed, 9 Oct 2013 15:30:13 +0200
+Subject: [PATCH 0853/1302] drivers: iommu: add workaround for multiple
+ suspend/resume calls
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iommu/exynos-iommu.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
+index 76f423d..78c91c9 100644
+--- a/drivers/iommu/exynos-iommu.c
++++ b/drivers/iommu/exynos-iommu.c
+@@ -183,6 +183,7 @@ struct sysmmu_drvdata {
+       spinlock_t lock;
+       struct iommu_domain *domain;
+       bool runtime_active;
++      bool suspended;
+       unsigned long pgtable;
+       void __iomem *sfrbase;
+ };
+@@ -383,6 +384,10 @@ static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id)
+ static void __sysmmu_disable_nocount(struct sysmmu_drvdata *data)
+ {
++      if (data->suspended)
++              return;
++
++      data->suspended = 1;
+       clk_enable(data->clk_master);
+       __raw_writel(CTRL_DISABLE, data->sfrbase + REG_MMU_CTRL);
+@@ -438,6 +443,11 @@ static void __sysmmu_init_config(struct sysmmu_drvdata *data)
+ static void __sysmmu_enable_nocount(struct sysmmu_drvdata *data)
+ {
++      if (!data->suspended)
++              return;
++
++      data->suspended = 0;
++
+       clk_enable(data->clk_master);
+       clk_enable(data->clk);
+@@ -634,6 +644,7 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev)
+       }
+       data->runtime_active = !pm_runtime_enabled(dev);
++      data->suspended = 1;
+       spin_lock_init(&data->lock);
+       INIT_LIST_HEAD(&data->node);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0854-media-fimc-fix-clock-management-in-suspend-resume-pa.patch b/patches.tizen/0854-media-fimc-fix-clock-management-in-suspend-resume-pa.patch
new file mode 100644 (file)
index 0000000..6479856
--- /dev/null
@@ -0,0 +1,56 @@
+From a8a42403e0cbfdc07ce602b78306f2049682a732 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Thu, 10 Oct 2013 10:05:06 +0200
+Subject: [PATCH 0854/1302] media: fimc: fix clock management in suspend/resume
+ path
+
+Standard suspend/resume path is called after runtime resume of the given
+device, so suspend/resume callbacks must do all clock management done also
+by runtime pm to allow proper power domain shutdown.
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/fimc-core.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c
+index 6823ce0..8108334 100644
+--- a/drivers/media/platform/exynos4-is/fimc-core.c
++++ b/drivers/media/platform/exynos4-is/fimc-core.c
+@@ -1088,6 +1088,8 @@ static int fimc_resume(struct device *dev)
+       struct fimc_dev *fimc = dev_get_drvdata(dev);
+       unsigned long flags;
++      clk_enable(fimc->clock[CLK_GATE]);
++
+       dbg("fimc%d: state: 0x%lx", fimc->id, fimc->state);
+       /* Do not resume if the device was idle before system suspend */
+@@ -1109,15 +1111,20 @@ static int fimc_resume(struct device *dev)
+ static int fimc_suspend(struct device *dev)
+ {
+       struct fimc_dev *fimc = dev_get_drvdata(dev);
++      int ret = 0;
+       dbg("fimc%d: state: 0x%lx", fimc->id, fimc->state);
+       if (test_and_set_bit(ST_LPM, &fimc->state))
+-              return 0;
++              ret = 0;
+       if (fimc_capture_busy(fimc))
+-              return fimc_capture_suspend(fimc);
++              ret = fimc_capture_suspend(fimc);
++
++      ret = fimc_m2m_suspend(fimc);
+-      return fimc_m2m_suspend(fimc);
++      clk_disable(fimc->clock[CLK_GATE]);
++
++      return ret;
+ }
+ #endif /* CONFIG_PM_SLEEP */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0855-media-s5p-jpeg-fix-clock-management-in-suspend-resum.patch b/patches.tizen/0855-media-s5p-jpeg-fix-clock-management-in-suspend-resum.patch
new file mode 100644 (file)
index 0000000..5eb1eb5
--- /dev/null
@@ -0,0 +1,51 @@
+From c4beac330f9a31939259f8a9c290d45514e5e299 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Thu, 10 Oct 2013 10:06:24 +0200
+Subject: [PATCH 0855/1302] media: s5p-jpeg: fix clock management in
+ suspend/resume path
+
+Standard suspend/resume path is called after runtime resume of the given
+device, so suspend/resume callbacks must do all clock management done also
+by runtime pm to allow proper power domain shutdown.
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/s5p-jpeg/jpeg-core.c | 20 ++++++++++++++++++--
+ 1 file changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c
+index 58cf5cf..9b88e4c 100644
+--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
++++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
+@@ -1849,9 +1849,25 @@ static int s5p_jpeg_runtime_resume(struct device *dev)
+       return 0;
+ }
++static int s5p_jpeg_suspend(struct device *dev)
++{
++      struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
++      clk_disable_unprepare(jpeg->clk);
++      s5p_jpeg_runtime_suspend(dev);
++      return 0;
++}
++
++static int s5p_jpeg_resume(struct device *dev)
++{
++      struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
++      clk_prepare_enable(jpeg->clk);
++      s5p_jpeg_runtime_resume(dev);
++      return 0;
++}
++
+ static const struct dev_pm_ops s5p_jpeg_pm_ops = {
+-      .runtime_suspend = s5p_jpeg_runtime_suspend,
+-      .runtime_resume  = s5p_jpeg_runtime_resume,
++      SET_SYSTEM_SLEEP_PM_OPS(s5p_jpeg_suspend, s5p_jpeg_resume)
++      SET_RUNTIME_PM_OPS(s5p_jpeg_runtime_suspend, s5p_jpeg_runtime_resume, NULL)
+ };
+ #ifdef CONFIG_OF
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0856-exynos_drm_ipp-fix-get-property-IOCTL.patch b/patches.tizen/0856-exynos_drm_ipp-fix-get-property-IOCTL.patch
new file mode 100644 (file)
index 0000000..76eb52f
--- /dev/null
@@ -0,0 +1,31 @@
+From 72393e0cac764bc5e75eed3b8f28e5aeec9f9aef Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Mon, 7 Oct 2013 09:22:02 +0200
+Subject: [PATCH 0856/1302] exynos_drm_ipp: fix get property IOCTL
+
+Due to incorrect assignment in EXYNOS_IPP_GET_PROPERTY
+IOCTL handler this IOCTL did not work at all.
+The patch fixes it.
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_ipp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+index 4cd2b40..fb3c791 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+@@ -349,7 +349,7 @@ int exynos_drm_ipp_get_property(struct drm_device *drm_dev, void *data,
+                       return -EINVAL;
+               }
+-              prop_list = ippdrv->prop_list;
++              *prop_list = *ippdrv->prop_list;
+       }
+       return 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0857-exynos_drm-replace-enums-by-__u32-in-structs-used-in.patch b/patches.tizen/0857-exynos_drm-replace-enums-by-__u32-in-structs-used-in.patch
new file mode 100644 (file)
index 0000000..8d8c66e
--- /dev/null
@@ -0,0 +1,64 @@
+From d503c24a1ccb7722bcd177d32bb87e976a1312d5 Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Mon, 7 Oct 2013 15:59:40 +0200
+Subject: [PATCH 0857/1302] exynos_drm: replace enums by __u32 in structs used
+ in IOCTLs
+
+enum type has variable size depending on compiler options,
+so it should be avoided in structs passed to userland.
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/uapi/drm/exynos_drm.h | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/include/uapi/drm/exynos_drm.h b/include/uapi/drm/exynos_drm.h
+index d584412..01879bf 100644
+--- a/include/uapi/drm/exynos_drm.h
++++ b/include/uapi/drm/exynos_drm.h
+@@ -238,9 +238,9 @@ struct drm_exynos_ipp_prop_list {
+  * @pos: property of image position(src-cropped,dst-scaler).
+  */
+ struct drm_exynos_ipp_config {
+-      enum drm_exynos_ops_id ops_id;
+-      enum drm_exynos_flip    flip;
+-      enum drm_exynos_degree  degree;
++      __u32   ops_id;
++      __u32   flip;
++      __u32   degree;
+       __u32   fmt;
+       struct drm_exynos_sz    sz;
+       struct drm_exynos_pos   pos;
+@@ -265,7 +265,7 @@ enum drm_exynos_ipp_cmd {
+  */
+ struct drm_exynos_ipp_property {
+       struct drm_exynos_ipp_config config[EXYNOS_DRM_OPS_MAX];
+-      enum drm_exynos_ipp_cmd cmd;
++      __u32   cmd;
+       __u32   ipp_id;
+       __u32   prop_id;
+       __u32   refresh_rate;
+@@ -287,8 +287,8 @@ enum drm_exynos_ipp_buf_type {
+  * @user_data: user data.
+  */
+ struct drm_exynos_ipp_queue_buf {
+-      enum drm_exynos_ops_id  ops_id;
+-      enum drm_exynos_ipp_buf_type    buf_type;
++      __u32   ops_id;
++      __u32   buf_type;
+       __u32   prop_id;
+       __u32   buf_id;
+       __u32   handle[EXYNOS_DRM_PLANAR_MAX];
+@@ -312,7 +312,7 @@ enum drm_exynos_ipp_ctrl {
+  */
+ struct drm_exynos_ipp_cmd_ctrl {
+       __u32   prop_id;
+-      enum drm_exynos_ipp_ctrl        ctrl;
++      __u32   ctrl;
+ };
+ #define DRM_EXYNOS_GEM_CREATE         0x00
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0858-exynos_drm_fimc-simplify-pre-scaler-ratio-calculatio.patch b/patches.tizen/0858-exynos_drm_fimc-simplify-pre-scaler-ratio-calculatio.patch
new file mode 100644 (file)
index 0000000..2341b7a
--- /dev/null
@@ -0,0 +1,114 @@
+From 4ae6287a4a49350e41f4d0a0d100f001b294e3a6 Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Wed, 9 Oct 2013 09:22:55 +0200
+Subject: [PATCH 0858/1302] exynos_drm_fimc: simplify pre-scaler ratio
+ calculation
+
+The patch replaces special function for scaling ratio
+calculation by simple fls calls.
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_fimc.c | 57 ++++++++------------------------
+ 1 file changed, 14 insertions(+), 43 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+index 3e137ae..f2debf4 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+@@ -957,43 +957,13 @@ static int fimc_dst_set_transf(struct device *dev,
+       return 0;
+ }
+-static int fimc_get_ratio_shift(u32 src, u32 dst, u32 *ratio, u32 *shift)
+-{
+-      DRM_DEBUG_KMS("%s:src[%d]dst[%d]\n", __func__, src, dst);
+-
+-      if (src >= dst * 64) {
+-              DRM_ERROR("failed to make ratio and shift.\n");
+-              return -EINVAL;
+-      } else if (src >= dst * 32) {
+-              *ratio = 32;
+-              *shift = 5;
+-      } else if (src >= dst * 16) {
+-              *ratio = 16;
+-              *shift = 4;
+-      } else if (src >= dst * 8) {
+-              *ratio = 8;
+-              *shift = 3;
+-      } else if (src >= dst * 4) {
+-              *ratio = 4;
+-              *shift = 2;
+-      } else if (src >= dst * 2) {
+-              *ratio = 2;
+-              *shift = 1;
+-      } else {
+-              *ratio = 1;
+-              *shift = 0;
+-      }
+-
+-      return 0;
+-}
+-
+ static int fimc_set_prescaler(struct fimc_context *ctx, struct fimc_scaler *sc,
+               struct drm_exynos_pos *src, struct drm_exynos_pos *dst)
+ {
+       struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
+       u32 cfg, cfg_ext, shfactor;
+       u32 pre_dst_width, pre_dst_height;
+-      u32 pre_hratio, hfactor, pre_vratio, vfactor;
++      u32 hfactor, vfactor;
+       int ret = 0;
+       u32 src_w, src_h, dst_w, dst_h;
+@@ -1014,24 +984,25 @@ static int fimc_set_prescaler(struct fimc_context *ctx, struct fimc_scaler *sc,
+               dst_h = dst->h;
+       }
+-      ret = fimc_get_ratio_shift(src_w, dst_w, &pre_hratio, &hfactor);
+-      if (ret) {
++      /* fimc_ippdrv_check_property assures that dividers are not null */
++      hfactor = fls(src_w / dst_w);
++      if (hfactor > FIMC_SHFACTOR / 2) {
+               dev_err(ippdrv->dev, "failed to get ratio horizontal.\n");
+-              return ret;
++              return -EINVAL;
+       }
+-      ret = fimc_get_ratio_shift(src_h, dst_h, &pre_vratio, &vfactor);
+-      if (ret) {
++      vfactor = fls(src_h / dst_h);
++      if (vfactor > FIMC_SHFACTOR / 2) {
+               dev_err(ippdrv->dev, "failed to get ratio vertical.\n");
+-              return ret;
++              return -EINVAL;
+       }
+-      pre_dst_width = src_w / pre_hratio;
+-      pre_dst_height = src_h / pre_vratio;
++      pre_dst_width = src_w >> hfactor;
++      pre_dst_height = src_h >> vfactor;
+       DRM_DEBUG_KMS("%s:pre_dst_width[%d]pre_dst_height[%d]\n", __func__,
+               pre_dst_width, pre_dst_height);
+-      DRM_DEBUG_KMS("%s:pre_hratio[%d]hfactor[%d]pre_vratio[%d]vfactor[%d]\n",
+-              __func__, pre_hratio, hfactor, pre_vratio, vfactor);
++      DRM_DEBUG_KMS("%s:hfactor[%d]vfactor[%d]\n", __func__, hfactor,
++              vfactor);
+       sc->hratio = (src_w << 14) / (dst_w << hfactor);
+       sc->vratio = (src_h << 14) / (dst_h << vfactor);
+@@ -1044,8 +1015,8 @@ static int fimc_set_prescaler(struct fimc_context *ctx, struct fimc_scaler *sc,
+       DRM_DEBUG_KMS("%s:shfactor[%d]\n", __func__, shfactor);
+       cfg = (EXYNOS_CISCPRERATIO_SHFACTOR(shfactor) |
+-              EXYNOS_CISCPRERATIO_PREHORRATIO(pre_hratio) |
+-              EXYNOS_CISCPRERATIO_PREVERRATIO(pre_vratio));
++              EXYNOS_CISCPRERATIO_PREHORRATIO(1 << hfactor) |
++              EXYNOS_CISCPRERATIO_PREVERRATIO(1 << vfactor));
+       fimc_write(cfg, EXYNOS_CISCPRERATIO);
+       cfg = (EXYNOS_CISCPREDST_PREDSTWIDTH(pre_dst_width) |
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0859-exynos_drm_fimc-rename-fimc_handle_irq-to-fimc_mask_.patch b/patches.tizen/0859-exynos_drm_fimc-rename-fimc_handle_irq-to-fimc_mask_.patch
new file mode 100644 (file)
index 0000000..bd74480
--- /dev/null
@@ -0,0 +1,85 @@
+From e135af1170d1e442989f6e823b6b65749917eee3 Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Wed, 9 Oct 2013 11:45:31 +0200
+Subject: [PATCH 0859/1302] exynos_drm_fimc: rename fimc_handle_irq to
+ fimc_mask_irq
+
+fimc_handle_irq suggests it is IRQ handler but it is
+irq masking function. Additional small code improvement.
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_fimc.c | 20 ++++++++------------
+ 1 file changed, 8 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+index f2debf4..9dbc90d 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+@@ -290,25 +290,21 @@ static void fimc_handle_jpeg(struct fimc_context *ctx, bool enable)
+       fimc_write(cfg, EXYNOS_CIGCTRL);
+ }
+-static void fimc_handle_irq(struct fimc_context *ctx, bool enable,
++static void fimc_mask_irq(struct fimc_context *ctx, bool enable,
+               bool overflow, bool level)
+ {
+       u32 cfg;
+-      DRM_DEBUG_KMS("%s:enable[%d]overflow[%d]level[%d]\n", __func__,
+-                      enable, overflow, level);
+-
+       cfg = fimc_read(EXYNOS_CIGCTRL);
++      cfg &= ~(EXYNOS_CIGCTRL_IRQ_OVFEN | EXYNOS_CIGCTRL_IRQ_ENABLE |
++              EXYNOS_CIGCTRL_IRQ_LEVEL);
+       if (enable) {
+-              cfg &= ~(EXYNOS_CIGCTRL_IRQ_OVFEN | EXYNOS_CIGCTRL_IRQ_LEVEL);
+               cfg |= EXYNOS_CIGCTRL_IRQ_ENABLE;
+               if (overflow)
+                       cfg |= EXYNOS_CIGCTRL_IRQ_OVFEN;
+               if (level)
+                       cfg |= EXYNOS_CIGCTRL_IRQ_LEVEL;
+-      } else
+-              cfg &= ~(EXYNOS_CIGCTRL_IRQ_OVFEN | EXYNOS_CIGCTRL_IRQ_ENABLE);
+-
++      }
+       fimc_write(cfg, EXYNOS_CIGCTRL);
+ }
+@@ -1183,12 +1179,12 @@ static int fimc_dst_set_buf_seq(struct fimc_context *ctx, u32 buf_id,
+       /* interrupt enable */
+       if (buf_type == IPP_BUF_ENQUEUE &&
+           fimc_dst_get_buf_seq(ctx) >= FIMC_BUF_START)
+-              fimc_handle_irq(ctx, true, false, true);
++              fimc_mask_irq(ctx, true, false, true);
+       /* interrupt disable */
+       if (buf_type == IPP_BUF_DEQUEUE &&
+           fimc_dst_get_buf_seq(ctx) <= FIMC_BUF_STOP)
+-              fimc_handle_irq(ctx, false, false, true);
++              fimc_mask_irq(ctx, false, false, true);
+ err_unlock:
+       mutex_unlock(&ctx->lock);
+@@ -1529,7 +1525,7 @@ static int fimc_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd)
+       property = &c_node->property;
+-      fimc_handle_irq(ctx, true, false, true);
++      fimc_mask_irq(ctx, true, false, true);
+       for_each_ipp_ops(i) {
+               config = &property->config[i];
+@@ -1648,7 +1644,7 @@ static void fimc_ippdrv_stop(struct device *dev, enum drm_exynos_ipp_cmd cmd)
+               break;
+       }
+-      fimc_handle_irq(ctx, false, false, true);
++      fimc_mask_irq(ctx, false, false, true);
+       /* reset sequence */
+       fimc_write(0x0, EXYNOS_CIFCNTSEQ);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0860-exynos_drm_fimc-replace-hw-access-macros-with-functi.patch b/patches.tizen/0860-exynos_drm_fimc-replace-hw-access-macros-with-functi.patch
new file mode 100644 (file)
index 0000000..81bd4b9
--- /dev/null
@@ -0,0 +1,850 @@
+From 4e191d4a852529db8643eda73b93f9fa9a4753aa Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Wed, 9 Oct 2013 13:23:21 +0200
+Subject: [PATCH 0860/1302] exynos_drm_fimc: replace hw access macros with
+ functions
+
+HW access macros depended on presence of ctx local variable.
+This patch replaces them with proper functions.
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_fimc.c | 305 +++++++++++++++----------------
+ 1 file changed, 147 insertions(+), 158 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+index 9dbc90d..455266e 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+@@ -69,9 +69,6 @@
+ #define get_fimc_context(dev) platform_get_drvdata(to_platform_device(dev))
+ #define get_ctx_from_ippdrv(ippdrv)   container_of(ippdrv,\
+                                       struct fimc_context, ippdrv);
+-#define fimc_read(offset)             readl(ctx->regs + (offset))
+-#define fimc_write(cfg, offset)       writel(cfg, ctx->regs + (offset))
+-
+ enum fimc_wb {
+       FIMC_WB_NONE,
+       FIMC_WB_A,
+@@ -172,39 +169,53 @@ struct fimc_context {
+       bool    suspended;
+ };
++static u32 fimc_read(struct fimc_context *ctx, u32 reg)
++{
++      return readl(ctx->regs + reg);
++}
++
++static void fimc_write(struct fimc_context *ctx, u32 val, u32 reg)
++{
++      writel(val, ctx->regs + reg);
++}
++
++static void fimc_set_bits(struct fimc_context *ctx, u32 reg, u32 bits)
++{
++      void __iomem *r = ctx->regs + reg;
++
++      writel(readl(r) | bits, r);
++}
++
++static void fimc_clear_bits(struct fimc_context *ctx, u32 reg, u32 bits)
++{
++      void __iomem *r = ctx->regs + reg;
++
++      writel(readl(r) & ~bits, r);
++}
++
+ static void fimc_sw_reset(struct fimc_context *ctx)
+ {
+       u32 cfg;
+       /* stop dma operation */
+-      cfg = fimc_read(EXYNOS_CISTATUS);
+-      if (EXYNOS_CISTATUS_GET_ENVID_STATUS(cfg)) {
+-              cfg = fimc_read(EXYNOS_MSCTRL);
+-              cfg &= ~EXYNOS_MSCTRL_ENVID;
+-              fimc_write(cfg, EXYNOS_MSCTRL);
+-      }
++      cfg = fimc_read(ctx, EXYNOS_CISTATUS);
++      if (EXYNOS_CISTATUS_GET_ENVID_STATUS(cfg))
++              fimc_clear_bits(ctx, EXYNOS_MSCTRL, EXYNOS_MSCTRL_ENVID);
+-      cfg = fimc_read(EXYNOS_CISRCFMT);
+-      cfg |= EXYNOS_CISRCFMT_ITU601_8BIT;
+-      fimc_write(cfg, EXYNOS_CISRCFMT);
++      fimc_set_bits(ctx, EXYNOS_CISRCFMT, EXYNOS_CISRCFMT_ITU601_8BIT);
+       /* disable image capture */
+-      cfg = fimc_read(EXYNOS_CIIMGCPT);
+-      cfg &= ~(EXYNOS_CIIMGCPT_IMGCPTEN_SC | EXYNOS_CIIMGCPT_IMGCPTEN);
+-      fimc_write(cfg, EXYNOS_CIIMGCPT);
++      fimc_clear_bits(ctx, EXYNOS_CIIMGCPT,
++              EXYNOS_CIIMGCPT_IMGCPTEN_SC | EXYNOS_CIIMGCPT_IMGCPTEN);
+       /* s/w reset */
+-      cfg = fimc_read(EXYNOS_CIGCTRL);
+-      cfg |= (EXYNOS_CIGCTRL_SWRST);
+-      fimc_write(cfg, EXYNOS_CIGCTRL);
++      fimc_set_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_SWRST);
+       /* s/w reset complete */
+-      cfg = fimc_read(EXYNOS_CIGCTRL);
+-      cfg &= ~EXYNOS_CIGCTRL_SWRST;
+-      fimc_write(cfg, EXYNOS_CIGCTRL);
++      fimc_clear_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_SWRST);
+       /* reset sequence */
+-      fimc_write(0x0, EXYNOS_CIFCNTSEQ);
++      fimc_write(ctx, 0x0, EXYNOS_CIFCNTSEQ);
+ }
+ static int fimc_set_camblk_fimd0_wb(struct fimc_context *ctx)
+@@ -220,7 +231,7 @@ static void fimc_set_type_ctrl(struct fimc_context *ctx, enum fimc_wb wb)
+       DRM_DEBUG_KMS("%s:wb[%d]\n", __func__, wb);
+-      cfg = fimc_read(EXYNOS_CIGCTRL);
++      cfg = fimc_read(ctx, EXYNOS_CIGCTRL);
+       cfg &= ~(EXYNOS_CIGCTRL_TESTPATTERN_MASK |
+               EXYNOS_CIGCTRL_SELCAM_ITU_MASK |
+               EXYNOS_CIGCTRL_SELCAM_MIPI_MASK |
+@@ -246,7 +257,7 @@ static void fimc_set_type_ctrl(struct fimc_context *ctx, enum fimc_wb wb)
+               break;
+       }
+-      fimc_write(cfg, EXYNOS_CIGCTRL);
++      fimc_write(ctx, cfg, EXYNOS_CIGCTRL);
+ }
+ static void fimc_set_polarity(struct fimc_context *ctx,
+@@ -259,7 +270,7 @@ static void fimc_set_polarity(struct fimc_context *ctx,
+       DRM_DEBUG_KMS("%s:inv_href[%d]inv_hsync[%d]\n",
+               __func__, pol->inv_href, pol->inv_hsync);
+-      cfg = fimc_read(EXYNOS_CIGCTRL);
++      cfg = fimc_read(ctx, EXYNOS_CIGCTRL);
+       cfg &= ~(EXYNOS_CIGCTRL_INVPOLPCLK | EXYNOS_CIGCTRL_INVPOLVSYNC |
+                EXYNOS_CIGCTRL_INVPOLHREF | EXYNOS_CIGCTRL_INVPOLHSYNC);
+@@ -272,7 +283,7 @@ static void fimc_set_polarity(struct fimc_context *ctx,
+       if (pol->inv_hsync)
+               cfg |= EXYNOS_CIGCTRL_INVPOLHSYNC;
+-      fimc_write(cfg, EXYNOS_CIGCTRL);
++      fimc_write(ctx, cfg, EXYNOS_CIGCTRL);
+ }
+ static void fimc_handle_jpeg(struct fimc_context *ctx, bool enable)
+@@ -281,13 +292,13 @@ static void fimc_handle_jpeg(struct fimc_context *ctx, bool enable)
+       DRM_DEBUG_KMS("%s:enable[%d]\n", __func__, enable);
+-      cfg = fimc_read(EXYNOS_CIGCTRL);
++      cfg = fimc_read(ctx, EXYNOS_CIGCTRL);
+       if (enable)
+               cfg |= EXYNOS_CIGCTRL_CAM_JPEG;
+       else
+               cfg &= ~EXYNOS_CIGCTRL_CAM_JPEG;
+-      fimc_write(cfg, EXYNOS_CIGCTRL);
++      fimc_write(ctx, cfg, EXYNOS_CIGCTRL);
+ }
+ static void fimc_mask_irq(struct fimc_context *ctx, bool enable,
+@@ -295,7 +306,7 @@ static void fimc_mask_irq(struct fimc_context *ctx, bool enable,
+ {
+       u32 cfg;
+-      cfg = fimc_read(EXYNOS_CIGCTRL);
++      cfg = fimc_read(ctx, EXYNOS_CIGCTRL);
+       cfg &= ~(EXYNOS_CIGCTRL_IRQ_OVFEN | EXYNOS_CIGCTRL_IRQ_ENABLE |
+               EXYNOS_CIGCTRL_IRQ_LEVEL);
+       if (enable) {
+@@ -305,42 +316,33 @@ static void fimc_mask_irq(struct fimc_context *ctx, bool enable,
+               if (level)
+                       cfg |= EXYNOS_CIGCTRL_IRQ_LEVEL;
+       }
+-      fimc_write(cfg, EXYNOS_CIGCTRL);
++      fimc_write(ctx, cfg, EXYNOS_CIGCTRL);
+ }
+ static void fimc_clear_irq(struct fimc_context *ctx)
+ {
+-      u32 cfg;
+-
+-      cfg = fimc_read(EXYNOS_CIGCTRL);
+-      cfg |= EXYNOS_CIGCTRL_IRQ_CLR;
+-      fimc_write(cfg, EXYNOS_CIGCTRL);
++      fimc_set_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_IRQ_CLR);
+ }
+ static bool fimc_check_ovf(struct fimc_context *ctx)
+ {
+       struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
+-      u32 cfg, status, flag;
++      u32 status, flag;
+-      status = fimc_read(EXYNOS_CISTATUS);
++      status = fimc_read(ctx, EXYNOS_CISTATUS);
+       flag = EXYNOS_CISTATUS_OVFIY | EXYNOS_CISTATUS_OVFICB |
+               EXYNOS_CISTATUS_OVFICR;
+       DRM_DEBUG_KMS("%s:flag[0x%x]\n", __func__, flag);
+       if (status & flag) {
+-              cfg = fimc_read(EXYNOS_CIWDOFST);
+-              cfg |= (EXYNOS_CIWDOFST_CLROVFIY | EXYNOS_CIWDOFST_CLROVFICB |
++              fimc_set_bits(ctx, EXYNOS_CIWDOFST,
++                      EXYNOS_CIWDOFST_CLROVFIY | EXYNOS_CIWDOFST_CLROVFICB |
+                       EXYNOS_CIWDOFST_CLROVFICR);
+-
+-              fimc_write(cfg, EXYNOS_CIWDOFST);
+-
+-              cfg = fimc_read(EXYNOS_CIWDOFST);
+-              cfg &= ~(EXYNOS_CIWDOFST_CLROVFIY | EXYNOS_CIWDOFST_CLROVFICB |
++              fimc_clear_bits(ctx, EXYNOS_CIWDOFST,
++                      EXYNOS_CIWDOFST_CLROVFIY | EXYNOS_CIWDOFST_CLROVFICB |
+                       EXYNOS_CIWDOFST_CLROVFICR);
+-              fimc_write(cfg, EXYNOS_CIWDOFST);
+-
+               dev_err(ippdrv->dev, "occured overflow at %d, status 0x%x.\n",
+                       ctx->id, status);
+               return true;
+@@ -353,7 +355,7 @@ static bool fimc_check_frame_end(struct fimc_context *ctx)
+ {
+       u32 cfg;
+-      cfg = fimc_read(EXYNOS_CISTATUS);
++      cfg = fimc_read(ctx, EXYNOS_CISTATUS);
+       DRM_DEBUG_KMS("%s:cfg[0x%x]\n", __func__, cfg);
+@@ -361,7 +363,7 @@ static bool fimc_check_frame_end(struct fimc_context *ctx)
+               return false;
+       cfg &= ~(EXYNOS_CISTATUS_FRAMEEND);
+-      fimc_write(cfg, EXYNOS_CISTATUS);
++      fimc_write(ctx, cfg, EXYNOS_CISTATUS);
+       return true;
+ }
+@@ -371,7 +373,7 @@ static int fimc_get_buf_id(struct fimc_context *ctx)
+       u32 cfg;
+       int frame_cnt, buf_id;
+-      cfg = fimc_read(EXYNOS_CISTATUS2);
++      cfg = fimc_read(ctx, EXYNOS_CISTATUS2);
+       frame_cnt = EXYNOS_CISTATUS2_GET_FRAMECOUNT_BEFORE(cfg);
+       if (frame_cnt == 0)
+@@ -398,13 +400,13 @@ static void fimc_handle_lastend(struct fimc_context *ctx, bool enable)
+       DRM_DEBUG_KMS("%s:enable[%d]\n", __func__, enable);
+-      cfg = fimc_read(EXYNOS_CIOCTRL);
++      cfg = fimc_read(ctx, EXYNOS_CIOCTRL);
+       if (enable)
+               cfg |= EXYNOS_CIOCTRL_LASTENDEN;
+       else
+               cfg &= ~EXYNOS_CIOCTRL_LASTENDEN;
+-      fimc_write(cfg, EXYNOS_CIOCTRL);
++      fimc_write(ctx, cfg, EXYNOS_CIOCTRL);
+ }
+@@ -416,18 +418,18 @@ static int fimc_src_set_fmt_order(struct fimc_context *ctx, u32 fmt)
+       DRM_DEBUG_KMS("%s:fmt[0x%x]\n", __func__, fmt);
+       /* RGB */
+-      cfg = fimc_read(EXYNOS_CISCCTRL);
++      cfg = fimc_read(ctx, EXYNOS_CISCCTRL);
+       cfg &= ~EXYNOS_CISCCTRL_INRGB_FMT_RGB_MASK;
+       switch (fmt) {
+       case DRM_FORMAT_RGB565:
+               cfg |= EXYNOS_CISCCTRL_INRGB_FMT_RGB565;
+-              fimc_write(cfg, EXYNOS_CISCCTRL);
++              fimc_write(ctx, cfg, EXYNOS_CISCCTRL);
+               return 0;
+       case DRM_FORMAT_RGB888:
+       case DRM_FORMAT_XRGB8888:
+               cfg |= EXYNOS_CISCCTRL_INRGB_FMT_RGB888;
+-              fimc_write(cfg, EXYNOS_CISCCTRL);
++              fimc_write(ctx, cfg, EXYNOS_CISCCTRL);
+               return 0;
+       default:
+               /* bypass */
+@@ -435,7 +437,7 @@ static int fimc_src_set_fmt_order(struct fimc_context *ctx, u32 fmt)
+       }
+       /* YUV */
+-      cfg = fimc_read(EXYNOS_MSCTRL);
++      cfg = fimc_read(ctx, EXYNOS_MSCTRL);
+       cfg &= ~(EXYNOS_MSCTRL_ORDER2P_SHIFT_MASK |
+               EXYNOS_MSCTRL_C_INT_IN_2PLANE |
+               EXYNOS_MSCTRL_ORDER422_YCBYCR);
+@@ -475,7 +477,7 @@ static int fimc_src_set_fmt_order(struct fimc_context *ctx, u32 fmt)
+               return -EINVAL;
+       }
+-      fimc_write(cfg, EXYNOS_MSCTRL);
++      fimc_write(ctx, cfg, EXYNOS_MSCTRL);
+       return 0;
+ }
+@@ -488,7 +490,7 @@ static int fimc_src_set_fmt(struct device *dev, u32 fmt)
+       DRM_DEBUG_KMS("%s:fmt[0x%x]\n", __func__, fmt);
+-      cfg = fimc_read(EXYNOS_MSCTRL);
++      cfg = fimc_read(ctx, EXYNOS_MSCTRL);
+       cfg &= ~EXYNOS_MSCTRL_INFORMAT_RGB;
+       switch (fmt) {
+@@ -523,9 +525,9 @@ static int fimc_src_set_fmt(struct device *dev, u32 fmt)
+               return -EINVAL;
+       }
+-      fimc_write(cfg, EXYNOS_MSCTRL);
++      fimc_write(ctx, cfg, EXYNOS_MSCTRL);
+-      cfg = fimc_read(EXYNOS_CIDMAPARAM);
++      cfg = fimc_read(ctx, EXYNOS_CIDMAPARAM);
+       cfg &= ~EXYNOS_CIDMAPARAM_R_MODE_MASK;
+       if (fmt == DRM_FORMAT_NV12MT)
+@@ -533,7 +535,7 @@ static int fimc_src_set_fmt(struct device *dev, u32 fmt)
+       else
+               cfg |= EXYNOS_CIDMAPARAM_R_MODE_LINEAR;
+-      fimc_write(cfg, EXYNOS_CIDMAPARAM);
++      fimc_write(ctx, cfg, EXYNOS_CIDMAPARAM);
+       return fimc_src_set_fmt_order(ctx, fmt);
+ }
+@@ -549,11 +551,11 @@ static int fimc_src_set_transf(struct device *dev,
+       DRM_DEBUG_KMS("%s:degree[%d]flip[0x%x]\n", __func__,
+               degree, flip);
+-      cfg1 = fimc_read(EXYNOS_MSCTRL);
++      cfg1 = fimc_read(ctx, EXYNOS_MSCTRL);
+       cfg1 &= ~(EXYNOS_MSCTRL_FLIP_X_MIRROR |
+               EXYNOS_MSCTRL_FLIP_Y_MIRROR);
+-      cfg2 = fimc_read(EXYNOS_CITRGFMT);
++      cfg2 = fimc_read(ctx, EXYNOS_CITRGFMT);
+       cfg2 &= ~EXYNOS_CITRGFMT_INROT90_CLOCKWISE;
+       switch (degree) {
+@@ -592,8 +594,8 @@ static int fimc_src_set_transf(struct device *dev,
+               return -EINVAL;
+       }
+-      fimc_write(cfg1, EXYNOS_MSCTRL);
+-      fimc_write(cfg2, EXYNOS_CITRGFMT);
++      fimc_write(ctx, cfg1, EXYNOS_MSCTRL);
++      fimc_write(ctx, cfg2, EXYNOS_CITRGFMT);
+       *swap = (cfg2 & EXYNOS_CITRGFMT_INROT90_CLOCKWISE) ? 1 : 0;
+       return 0;
+@@ -619,17 +621,17 @@ static int fimc_set_window(struct fimc_context *ctx,
+        * set window offset 1, 2 size
+        * check figure 43-21 in user manual
+        */
+-      cfg = fimc_read(EXYNOS_CIWDOFST);
++      cfg = fimc_read(ctx, EXYNOS_CIWDOFST);
+       cfg &= ~(EXYNOS_CIWDOFST_WINHOROFST_MASK |
+               EXYNOS_CIWDOFST_WINVEROFST_MASK);
+       cfg |= (EXYNOS_CIWDOFST_WINHOROFST(h1) |
+               EXYNOS_CIWDOFST_WINVEROFST(v1));
+       cfg |= EXYNOS_CIWDOFST_WINOFSEN;
+-      fimc_write(cfg, EXYNOS_CIWDOFST);
++      fimc_write(ctx, cfg, EXYNOS_CIWDOFST);
+       cfg = (EXYNOS_CIWDOFST2_WINHOROFST2(h2) |
+               EXYNOS_CIWDOFST2_WINVEROFST2(v2));
+-      fimc_write(cfg, EXYNOS_CIWDOFST2);
++      fimc_write(ctx, cfg, EXYNOS_CIWDOFST2);
+       return 0;
+ }
+@@ -649,7 +651,7 @@ static int fimc_src_set_size(struct device *dev, int swap,
+       cfg = (EXYNOS_ORGISIZE_HORIZONTAL(img_sz.hsize) |
+               EXYNOS_ORGISIZE_VERTICAL(img_sz.vsize));
+-      fimc_write(cfg, EXYNOS_ORGISIZE);
++      fimc_write(ctx, cfg, EXYNOS_ORGISIZE);
+       DRM_DEBUG_KMS("%s:x[%d]y[%d]w[%d]h[%d]\n", __func__,
+               pos->x, pos->y, pos->w, pos->h);
+@@ -662,12 +664,12 @@ static int fimc_src_set_size(struct device *dev, int swap,
+       }
+       /* set input DMA image size */
+-      cfg = fimc_read(EXYNOS_CIREAL_ISIZE);
++      cfg = fimc_read(ctx, EXYNOS_CIREAL_ISIZE);
+       cfg &= ~(EXYNOS_CIREAL_ISIZE_HEIGHT_MASK |
+               EXYNOS_CIREAL_ISIZE_WIDTH_MASK);
+       cfg |= (EXYNOS_CIREAL_ISIZE_WIDTH(img_pos.w) |
+               EXYNOS_CIREAL_ISIZE_HEIGHT(img_pos.h));
+-      fimc_write(cfg, EXYNOS_CIREAL_ISIZE);
++      fimc_write(ctx, cfg, EXYNOS_CIREAL_ISIZE);
+       /*
+        * set input FIFO image size
+@@ -676,18 +678,18 @@ static int fimc_src_set_size(struct device *dev, int swap,
+       cfg = (EXYNOS_CISRCFMT_ITU601_8BIT |
+               EXYNOS_CISRCFMT_SOURCEHSIZE(img_sz.hsize) |
+               EXYNOS_CISRCFMT_SOURCEVSIZE(img_sz.vsize));
+-      fimc_write(cfg, EXYNOS_CISRCFMT);
++      fimc_write(ctx, cfg, EXYNOS_CISRCFMT);
+       /* offset Y(RGB), Cb, Cr */
+       cfg = (EXYNOS_CIIYOFF_HORIZONTAL(img_pos.x) |
+               EXYNOS_CIIYOFF_VERTICAL(img_pos.y));
+-      fimc_write(cfg, EXYNOS_CIIYOFF);
++      fimc_write(ctx, cfg, EXYNOS_CIIYOFF);
+       cfg = (EXYNOS_CIICBOFF_HORIZONTAL(img_pos.x) |
+               EXYNOS_CIICBOFF_VERTICAL(img_pos.y));
+-      fimc_write(cfg, EXYNOS_CIICBOFF);
++      fimc_write(ctx, cfg, EXYNOS_CIICBOFF);
+       cfg = (EXYNOS_CIICROFF_HORIZONTAL(img_pos.x) |
+               EXYNOS_CIICROFF_VERTICAL(img_pos.y));
+-      fimc_write(cfg, EXYNOS_CIICROFF);
++      fimc_write(ctx, cfg, EXYNOS_CIICROFF);
+       return fimc_set_window(ctx, &img_pos, &img_sz);
+ }
+@@ -721,18 +723,18 @@ static int fimc_src_set_addr(struct device *dev,
+       switch (buf_type) {
+       case IPP_BUF_ENQUEUE:
+               config = &property->config[EXYNOS_DRM_OPS_SRC];
+-              fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_Y],
++              fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_Y],
+                       EXYNOS_CIIYSA(0));
+               if (config->fmt == DRM_FORMAT_YVU420) {
+-                      fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CR],
++                      fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CR],
+                               EXYNOS_CIICBSA(0));
+-                      fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CB],
++                      fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CB],
+                               EXYNOS_CIICRSA(0));
+               } else {
+-                      fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CB],
++                      fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CB],
+                               EXYNOS_CIICBSA(0));
+-                      fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CR],
++                      fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CR],
+                               EXYNOS_CIICRSA(0));
+               }
+               break;
+@@ -760,22 +762,22 @@ static int fimc_dst_set_fmt_order(struct fimc_context *ctx, u32 fmt)
+       DRM_DEBUG_KMS("%s:fmt[0x%x]\n", __func__, fmt);
+       /* RGB */
+-      cfg = fimc_read(EXYNOS_CISCCTRL);
++      cfg = fimc_read(ctx, EXYNOS_CISCCTRL);
+       cfg &= ~EXYNOS_CISCCTRL_OUTRGB_FMT_RGB_MASK;
+       switch (fmt) {
+       case DRM_FORMAT_RGB565:
+               cfg |= EXYNOS_CISCCTRL_OUTRGB_FMT_RGB565;
+-              fimc_write(cfg, EXYNOS_CISCCTRL);
++              fimc_write(ctx, cfg, EXYNOS_CISCCTRL);
+               return 0;
+       case DRM_FORMAT_RGB888:
+               cfg |= EXYNOS_CISCCTRL_OUTRGB_FMT_RGB888;
+-              fimc_write(cfg, EXYNOS_CISCCTRL);
++              fimc_write(ctx, cfg, EXYNOS_CISCCTRL);
+               return 0;
+       case DRM_FORMAT_XRGB8888:
+               cfg |= (EXYNOS_CISCCTRL_OUTRGB_FMT_RGB888 |
+                       EXYNOS_CISCCTRL_EXTRGB_EXTENSION);
+-              fimc_write(cfg, EXYNOS_CISCCTRL);
++              fimc_write(ctx, cfg, EXYNOS_CISCCTRL);
+               break;
+       default:
+               /* bypass */
+@@ -783,7 +785,7 @@ static int fimc_dst_set_fmt_order(struct fimc_context *ctx, u32 fmt)
+       }
+       /* YUV */
+-      cfg = fimc_read(EXYNOS_CIOCTRL);
++      cfg = fimc_read(ctx, EXYNOS_CIOCTRL);
+       cfg &= ~(EXYNOS_CIOCTRL_ORDER2P_MASK |
+               EXYNOS_CIOCTRL_ORDER422_MASK |
+               EXYNOS_CIOCTRL_YCBCR_PLANE_MASK);
+@@ -825,7 +827,7 @@ static int fimc_dst_set_fmt_order(struct fimc_context *ctx, u32 fmt)
+               return -EINVAL;
+       }
+-      fimc_write(cfg, EXYNOS_CIOCTRL);
++      fimc_write(ctx, cfg, EXYNOS_CIOCTRL);
+       return 0;
+ }
+@@ -838,16 +840,16 @@ static int fimc_dst_set_fmt(struct device *dev, u32 fmt)
+       DRM_DEBUG_KMS("%s:fmt[0x%x]\n", __func__, fmt);
+-      cfg = fimc_read(EXYNOS_CIEXTEN);
++      cfg = fimc_read(ctx, EXYNOS_CIEXTEN);
+       if (fmt == DRM_FORMAT_AYUV) {
+               cfg |= EXYNOS_CIEXTEN_YUV444_OUT;
+-              fimc_write(cfg, EXYNOS_CIEXTEN);
++              fimc_write(ctx, cfg, EXYNOS_CIEXTEN);
+       } else {
+               cfg &= ~EXYNOS_CIEXTEN_YUV444_OUT;
+-              fimc_write(cfg, EXYNOS_CIEXTEN);
++              fimc_write(ctx, cfg, EXYNOS_CIEXTEN);
+-              cfg = fimc_read(EXYNOS_CITRGFMT);
++              cfg = fimc_read(ctx, EXYNOS_CITRGFMT);
+               cfg &= ~EXYNOS_CITRGFMT_OUTFORMAT_MASK;
+               switch (fmt) {
+@@ -880,10 +882,10 @@ static int fimc_dst_set_fmt(struct device *dev, u32 fmt)
+                       return -EINVAL;
+               }
+-              fimc_write(cfg, EXYNOS_CITRGFMT);
++              fimc_write(ctx, cfg, EXYNOS_CITRGFMT);
+       }
+-      cfg = fimc_read(EXYNOS_CIDMAPARAM);
++      cfg = fimc_read(ctx, EXYNOS_CIDMAPARAM);
+       cfg &= ~EXYNOS_CIDMAPARAM_W_MODE_MASK;
+       if (fmt == DRM_FORMAT_NV12MT)
+@@ -891,7 +893,7 @@ static int fimc_dst_set_fmt(struct device *dev, u32 fmt)
+       else
+               cfg |= EXYNOS_CIDMAPARAM_W_MODE_LINEAR;
+-      fimc_write(cfg, EXYNOS_CIDMAPARAM);
++      fimc_write(ctx, cfg, EXYNOS_CIDMAPARAM);
+       return fimc_dst_set_fmt_order(ctx, fmt);
+ }
+@@ -907,7 +909,7 @@ static int fimc_dst_set_transf(struct device *dev,
+       DRM_DEBUG_KMS("%s:degree[%d]flip[0x%x]\n", __func__,
+               degree, flip);
+-      cfg = fimc_read(EXYNOS_CITRGFMT);
++      cfg = fimc_read(ctx, EXYNOS_CITRGFMT);
+       cfg &= ~EXYNOS_CITRGFMT_FLIP_MASK;
+       cfg &= ~EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE;
+@@ -947,7 +949,7 @@ static int fimc_dst_set_transf(struct device *dev,
+               return -EINVAL;
+       }
+-      fimc_write(cfg, EXYNOS_CITRGFMT);
++      fimc_write(ctx, cfg, EXYNOS_CITRGFMT);
+       *swap = (cfg & EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE) ? 1 : 0;
+       return 0;
+@@ -963,7 +965,7 @@ static int fimc_set_prescaler(struct fimc_context *ctx, struct fimc_scaler *sc,
+       int ret = 0;
+       u32 src_w, src_h, dst_w, dst_h;
+-      cfg_ext = fimc_read(EXYNOS_CITRGFMT);
++      cfg_ext = fimc_read(ctx, EXYNOS_CITRGFMT);
+       if (cfg_ext & EXYNOS_CITRGFMT_INROT90_CLOCKWISE) {
+               src_w = src->h;
+               src_h = src->w;
+@@ -1013,11 +1015,11 @@ static int fimc_set_prescaler(struct fimc_context *ctx, struct fimc_scaler *sc,
+       cfg = (EXYNOS_CISCPRERATIO_SHFACTOR(shfactor) |
+               EXYNOS_CISCPRERATIO_PREHORRATIO(1 << hfactor) |
+               EXYNOS_CISCPRERATIO_PREVERRATIO(1 << vfactor));
+-      fimc_write(cfg, EXYNOS_CISCPRERATIO);
++      fimc_write(ctx, cfg, EXYNOS_CISCPRERATIO);
+       cfg = (EXYNOS_CISCPREDST_PREDSTWIDTH(pre_dst_width) |
+               EXYNOS_CISCPREDST_PREDSTHEIGHT(pre_dst_height));
+-      fimc_write(cfg, EXYNOS_CISCPREDST);
++      fimc_write(ctx, cfg, EXYNOS_CISCPREDST);
+       return ret;
+ }
+@@ -1031,7 +1033,7 @@ static void fimc_set_scaler(struct fimc_context *ctx, struct fimc_scaler *sc)
+       DRM_DEBUG_KMS("%s:hratio[%d]vratio[%d]\n",
+               __func__, sc->hratio, sc->vratio);
+-      cfg = fimc_read(EXYNOS_CISCCTRL);
++      cfg = fimc_read(ctx, EXYNOS_CISCCTRL);
+       cfg &= ~(EXYNOS_CISCCTRL_SCALERBYPASS |
+               EXYNOS_CISCCTRL_SCALEUP_H | EXYNOS_CISCCTRL_SCALEUP_V |
+               EXYNOS_CISCCTRL_MAIN_V_RATIO_MASK |
+@@ -1051,14 +1053,14 @@ static void fimc_set_scaler(struct fimc_context *ctx, struct fimc_scaler *sc)
+       cfg |= (EXYNOS_CISCCTRL_MAINHORRATIO((sc->hratio >> 6)) |
+               EXYNOS_CISCCTRL_MAINVERRATIO((sc->vratio >> 6)));
+-      fimc_write(cfg, EXYNOS_CISCCTRL);
++      fimc_write(ctx, cfg, EXYNOS_CISCCTRL);
+-      cfg_ext = fimc_read(EXYNOS_CIEXTEN);
++      cfg_ext = fimc_read(ctx, EXYNOS_CIEXTEN);
+       cfg_ext &= ~EXYNOS_CIEXTEN_MAINHORRATIO_EXT_MASK;
+       cfg_ext &= ~EXYNOS_CIEXTEN_MAINVERRATIO_EXT_MASK;
+       cfg_ext |= (EXYNOS_CIEXTEN_MAINHORRATIO_EXT(sc->hratio) |
+               EXYNOS_CIEXTEN_MAINVERRATIO_EXT(sc->vratio));
+-      fimc_write(cfg_ext, EXYNOS_CIEXTEN);
++      fimc_write(ctx, cfg_ext, EXYNOS_CIEXTEN);
+ }
+ static int fimc_dst_set_size(struct device *dev, int swap,
+@@ -1076,13 +1078,13 @@ static int fimc_dst_set_size(struct device *dev, int swap,
+       cfg = (EXYNOS_ORGOSIZE_HORIZONTAL(img_sz.hsize) |
+               EXYNOS_ORGOSIZE_VERTICAL(img_sz.vsize));
+-      fimc_write(cfg, EXYNOS_ORGOSIZE);
++      fimc_write(ctx, cfg, EXYNOS_ORGOSIZE);
+       DRM_DEBUG_KMS("%s:x[%d]y[%d]w[%d]h[%d]\n",
+               __func__, pos->x, pos->y, pos->w, pos->h);
+       /* CSC ITU */
+-      cfg = fimc_read(EXYNOS_CIGCTRL);
++      cfg = fimc_read(ctx, EXYNOS_CIGCTRL);
+       cfg &= ~EXYNOS_CIGCTRL_CSC_MASK;
+       if (sz->hsize >= FIMC_WIDTH_ITU_709)
+@@ -1090,7 +1092,7 @@ static int fimc_dst_set_size(struct device *dev, int swap,
+       else
+               cfg |= EXYNOS_CIGCTRL_CSC_ITU601;
+-      fimc_write(cfg, EXYNOS_CIGCTRL);
++      fimc_write(ctx, cfg, EXYNOS_CIGCTRL);
+       if (swap) {
+               img_pos.w = pos->h;
+@@ -1100,27 +1102,27 @@ static int fimc_dst_set_size(struct device *dev, int swap,
+       }
+       /* target image size */
+-      cfg = fimc_read(EXYNOS_CITRGFMT);
++      cfg = fimc_read(ctx, EXYNOS_CITRGFMT);
+       cfg &= ~(EXYNOS_CITRGFMT_TARGETH_MASK |
+               EXYNOS_CITRGFMT_TARGETV_MASK);
+       cfg |= (EXYNOS_CITRGFMT_TARGETHSIZE(img_pos.w) |
+               EXYNOS_CITRGFMT_TARGETVSIZE(img_pos.h));
+-      fimc_write(cfg, EXYNOS_CITRGFMT);
++      fimc_write(ctx, cfg, EXYNOS_CITRGFMT);
+       /* target area */
+       cfg = EXYNOS_CITAREA_TARGET_AREA(img_pos.w * img_pos.h);
+-      fimc_write(cfg, EXYNOS_CITAREA);
++      fimc_write(ctx, cfg, EXYNOS_CITAREA);
+       /* offset Y(RGB), Cb, Cr */
+       cfg = (EXYNOS_CIOYOFF_HORIZONTAL(img_pos.x) |
+               EXYNOS_CIOYOFF_VERTICAL(img_pos.y));
+-      fimc_write(cfg, EXYNOS_CIOYOFF);
++      fimc_write(ctx, cfg, EXYNOS_CIOYOFF);
+       cfg = (EXYNOS_CIOCBOFF_HORIZONTAL(img_pos.x) |
+               EXYNOS_CIOCBOFF_VERTICAL(img_pos.y));
+-      fimc_write(cfg, EXYNOS_CIOCBOFF);
++      fimc_write(ctx, cfg, EXYNOS_CIOCBOFF);
+       cfg = (EXYNOS_CIOCROFF_HORIZONTAL(img_pos.x) |
+               EXYNOS_CIOCROFF_VERTICAL(img_pos.y));
+-      fimc_write(cfg, EXYNOS_CIOCROFF);
++      fimc_write(ctx, cfg, EXYNOS_CIOCROFF);
+       return 0;
+ }
+@@ -1130,7 +1132,7 @@ static int fimc_dst_get_buf_seq(struct fimc_context *ctx)
+       u32 cfg, i, buf_num = 0;
+       u32 mask = 0x00000001;
+-      cfg = fimc_read(EXYNOS_CIFCNTSEQ);
++      cfg = fimc_read(ctx, EXYNOS_CIFCNTSEQ);
+       for (i = 0; i < FIMC_REG_SZ; i++)
+               if (cfg & (mask << i))
+@@ -1156,7 +1158,7 @@ static int fimc_dst_set_buf_seq(struct fimc_context *ctx, u32 buf_id,
+       mutex_lock(&ctx->lock);
+       /* mask register set */
+-      cfg = fimc_read(EXYNOS_CIFCNTSEQ);
++      cfg = fimc_read(ctx, EXYNOS_CIFCNTSEQ);
+       switch (buf_type) {
+       case IPP_BUF_ENQUEUE:
+@@ -1174,7 +1176,7 @@ static int fimc_dst_set_buf_seq(struct fimc_context *ctx, u32 buf_id,
+       /* sequence id */
+       cfg &= ~mask;
+       cfg |= (enable << buf_id);
+-      fimc_write(cfg, EXYNOS_CIFCNTSEQ);
++      fimc_write(ctx, cfg, EXYNOS_CIFCNTSEQ);
+       /* interrupt enable */
+       if (buf_type == IPP_BUF_ENQUEUE &&
+@@ -1221,25 +1223,25 @@ static int fimc_dst_set_addr(struct device *dev,
+       case IPP_BUF_ENQUEUE:
+               config = &property->config[EXYNOS_DRM_OPS_DST];
+-              fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_Y],
++              fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_Y],
+                       EXYNOS_CIOYSA(buf_id));
+               if (config->fmt == DRM_FORMAT_YVU420) {
+-                      fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CR],
++                      fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CR],
+                               EXYNOS_CIOCBSA(buf_id));
+-                      fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CB],
++                      fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CB],
+                               EXYNOS_CIOCRSA(buf_id));
+               } else {
+-                      fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CB],
++                      fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CB],
+                               EXYNOS_CIOCBSA(buf_id));
+-                      fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CR],
++                      fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CR],
+                               EXYNOS_CIOCRSA(buf_id));
+               }
+               break;
+       case IPP_BUF_DEQUEUE:
+-              fimc_write(0x0, EXYNOS_CIOYSA(buf_id));
+-              fimc_write(0x0, EXYNOS_CIOCBSA(buf_id));
+-              fimc_write(0x0, EXYNOS_CIOCRSA(buf_id));
++              fimc_write(ctx, 0x0, EXYNOS_CIOYSA(buf_id));
++              fimc_write(ctx, 0x0, EXYNOS_CIOCBSA(buf_id));
++              fimc_write(ctx, 0x0, EXYNOS_CIOCRSA(buf_id));
+               break;
+       default:
+               /* bypass */
+@@ -1477,15 +1479,15 @@ static void fimc_clear_addr(struct fimc_context *ctx)
+       int i;
+       for (i = 0; i < FIMC_MAX_SRC; i++) {
+-              fimc_write(0, EXYNOS_CIIYSA(i));
+-              fimc_write(0, EXYNOS_CIICBSA(i));
+-              fimc_write(0, EXYNOS_CIICRSA(i));
++              fimc_write(ctx, 0, EXYNOS_CIIYSA(i));
++              fimc_write(ctx, 0, EXYNOS_CIICBSA(i));
++              fimc_write(ctx, 0, EXYNOS_CIICRSA(i));
+       }
+       for (i = 0; i < FIMC_MAX_DST; i++) {
+-              fimc_write(0, EXYNOS_CIOYSA(i));
+-              fimc_write(0, EXYNOS_CIOCBSA(i));
+-              fimc_write(0, EXYNOS_CIOCRSA(i));
++              fimc_write(ctx, 0, EXYNOS_CIOYSA(i));
++              fimc_write(ctx, 0, EXYNOS_CIOCBSA(i));
++              fimc_write(ctx, 0, EXYNOS_CIOCRSA(i));
+       }
+ }
+@@ -1551,10 +1553,10 @@ static int fimc_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd)
+               fimc_handle_lastend(ctx, false);
+               /* setup dma */
+-              cfg0 = fimc_read(EXYNOS_MSCTRL);
++              cfg0 = fimc_read(ctx, EXYNOS_MSCTRL);
+               cfg0 &= ~EXYNOS_MSCTRL_INPUT_MASK;
+               cfg0 |= EXYNOS_MSCTRL_INPUT_MEMORY;
+-              fimc_write(cfg0, EXYNOS_MSCTRL);
++              fimc_write(ctx, cfg0, EXYNOS_MSCTRL);
+               break;
+       case IPP_CMD_WB:
+               fimc_set_type_ctrl(ctx, FIMC_WB_A);
+@@ -1579,41 +1581,33 @@ static int fimc_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd)
+       }
+       /* Reset status */
+-      fimc_write(0x0, EXYNOS_CISTATUS);
++      fimc_write(ctx, 0x0, EXYNOS_CISTATUS);
+-      cfg0 = fimc_read(EXYNOS_CIIMGCPT);
++      cfg0 = fimc_read(ctx, EXYNOS_CIIMGCPT);
+       cfg0 &= ~EXYNOS_CIIMGCPT_IMGCPTEN_SC;
+       cfg0 |= EXYNOS_CIIMGCPT_IMGCPTEN_SC;
+       /* Scaler */
+-      cfg1 = fimc_read(EXYNOS_CISCCTRL);
++      cfg1 = fimc_read(ctx, EXYNOS_CISCCTRL);
+       cfg1 &= ~EXYNOS_CISCCTRL_SCAN_MASK;
+       cfg1 |= (EXYNOS_CISCCTRL_PROGRESSIVE |
+               EXYNOS_CISCCTRL_SCALERSTART);
+-      fimc_write(cfg1, EXYNOS_CISCCTRL);
++      fimc_write(ctx, cfg1, EXYNOS_CISCCTRL);
+       /* Enable image capture*/
+       cfg0 |= EXYNOS_CIIMGCPT_IMGCPTEN;
+-      fimc_write(cfg0, EXYNOS_CIIMGCPT);
++      fimc_write(ctx, cfg0, EXYNOS_CIIMGCPT);
+       /* Disable frame end irq */
+-      cfg0 = fimc_read(EXYNOS_CIGCTRL);
+-      cfg0 &= ~EXYNOS_CIGCTRL_IRQ_END_DISABLE;
+-      fimc_write(cfg0, EXYNOS_CIGCTRL);
++      fimc_clear_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_IRQ_END_DISABLE);
+-      cfg0 = fimc_read(EXYNOS_CIOCTRL);
+-      cfg0 &= ~EXYNOS_CIOCTRL_WEAVE_MASK;
+-      fimc_write(cfg0, EXYNOS_CIOCTRL);
++      fimc_clear_bits(ctx, EXYNOS_CIOCTRL, EXYNOS_CIOCTRL_WEAVE_MASK);
+       if (cmd == IPP_CMD_M2M) {
+-              cfg0 = fimc_read(EXYNOS_MSCTRL);
+-              cfg0 |= EXYNOS_MSCTRL_ENVID;
+-              fimc_write(cfg0, EXYNOS_MSCTRL);
++              fimc_set_bits(ctx, EXYNOS_MSCTRL, EXYNOS_MSCTRL_ENVID);
+-              cfg0 = fimc_read(EXYNOS_MSCTRL);
+-              cfg0 |= EXYNOS_MSCTRL_ENVID;
+-              fimc_write(cfg0, EXYNOS_MSCTRL);
++              fimc_set_bits(ctx, EXYNOS_MSCTRL, EXYNOS_MSCTRL_ENVID);
+       }
+       return 0;
+@@ -1630,10 +1624,10 @@ static void fimc_ippdrv_stop(struct device *dev, enum drm_exynos_ipp_cmd cmd)
+       switch (cmd) {
+       case IPP_CMD_M2M:
+               /* Source clear */
+-              cfg = fimc_read(EXYNOS_MSCTRL);
++              cfg = fimc_read(ctx, EXYNOS_MSCTRL);
+               cfg &= ~EXYNOS_MSCTRL_INPUT_MASK;
+               cfg &= ~EXYNOS_MSCTRL_ENVID;
+-              fimc_write(cfg, EXYNOS_MSCTRL);
++              fimc_write(ctx, cfg, EXYNOS_MSCTRL);
+               break;
+       case IPP_CMD_WB:
+               exynos_drm_ippnb_send_event(IPP_SET_WRITEBACK, (void *)&set_wb);
+@@ -1647,22 +1641,17 @@ static void fimc_ippdrv_stop(struct device *dev, enum drm_exynos_ipp_cmd cmd)
+       fimc_mask_irq(ctx, false, false, true);
+       /* reset sequence */
+-      fimc_write(0x0, EXYNOS_CIFCNTSEQ);
++      fimc_write(ctx, 0x0, EXYNOS_CIFCNTSEQ);
+       /* Scaler disable */
+-      cfg = fimc_read(EXYNOS_CISCCTRL);
+-      cfg &= ~EXYNOS_CISCCTRL_SCALERSTART;
+-      fimc_write(cfg, EXYNOS_CISCCTRL);
++      fimc_clear_bits(ctx, EXYNOS_CISCCTRL, EXYNOS_CISCCTRL_SCALERSTART);
+       /* Disable image capture */
+-      cfg = fimc_read(EXYNOS_CIIMGCPT);
+-      cfg &= ~(EXYNOS_CIIMGCPT_IMGCPTEN_SC | EXYNOS_CIIMGCPT_IMGCPTEN);
+-      fimc_write(cfg, EXYNOS_CIIMGCPT);
++      fimc_clear_bits(ctx, EXYNOS_CIIMGCPT,
++              EXYNOS_CIIMGCPT_IMGCPTEN_SC | EXYNOS_CIIMGCPT_IMGCPTEN);
+       /* Enable frame end irq */
+-      cfg = fimc_read(EXYNOS_CIGCTRL);
+-      cfg |= EXYNOS_CIGCTRL_IRQ_END_DISABLE;
+-      fimc_write(cfg, EXYNOS_CIGCTRL);
++      fimc_set_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_IRQ_END_DISABLE);
+ }
+ static void fimc_put_clocks(struct fimc_context *ctx)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0861-exynos_drm_fimc-replace-mutex-by-spinlock.patch b/patches.tizen/0861-exynos_drm_fimc-replace-mutex-by-spinlock.patch
new file mode 100644 (file)
index 0000000..251b6f3
--- /dev/null
@@ -0,0 +1,79 @@
+From c0af8d77084390bd87e276411a1cf1fdbc157b92 Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Wed, 9 Oct 2013 13:43:58 +0200
+Subject: [PATCH 0861/1302] exynos_drm_fimc: replace mutex by spinlock
+
+Function fimc_dst_set_buf_seq is called
+by irq handler so it should not use mutexes.
+This patch fixes it.
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_fimc.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+index 455266e..d6e7bf4 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+@@ -18,6 +18,7 @@
+ #include <linux/clk.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/of.h>
++#include <linux/spinlock.h>
+ #include <drm/drmP.h>
+ #include <drm/exynos_drm.h>
+@@ -158,7 +159,7 @@ struct fimc_context {
+       struct exynos_drm_ippdrv        ippdrv;
+       struct resource *regs_res;
+       void __iomem    *regs;
+-      struct mutex    lock;
++      spinlock_t      lock;
+       struct clk      *clocks[FIMC_CLKS_MAX];
+       u32             clk_frequency;
+       struct regmap   *sysreg;
+@@ -1151,11 +1152,12 @@ static int fimc_dst_set_buf_seq(struct fimc_context *ctx, u32 buf_id,
+       u32 cfg;
+       u32 mask = 0x00000001 << buf_id;
+       int ret = 0;
++      unsigned long flags;
+       DRM_DEBUG_KMS("%s:buf_id[%d]buf_type[%d]\n", __func__,
+               buf_id, buf_type);
+-      mutex_lock(&ctx->lock);
++      spin_lock_irqsave(&ctx->lock, flags);
+       /* mask register set */
+       cfg = fimc_read(ctx, EXYNOS_CIFCNTSEQ);
+@@ -1189,7 +1191,7 @@ static int fimc_dst_set_buf_seq(struct fimc_context *ctx, u32 buf_id,
+               fimc_mask_irq(ctx, false, false, true);
+ err_unlock:
+-      mutex_unlock(&ctx->lock);
++      spin_unlock_irqrestore(&ctx->lock, flags);
+       return ret;
+ }
+@@ -1807,7 +1809,7 @@ static int fimc_probe(struct platform_device *pdev)
+       DRM_DEBUG_KMS("%s:id[%d]ippdrv[0x%x]\n", __func__, ctx->id,
+               (int)ippdrv);
+-      mutex_init(&ctx->lock);
++      spin_lock_init(&ctx->lock);
+       platform_set_drvdata(pdev, ctx);
+       pm_runtime_set_active(dev);
+@@ -1838,7 +1840,6 @@ static int fimc_remove(struct platform_device *pdev)
+       struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
+       exynos_drm_ippdrv_unregister(ippdrv);
+-      mutex_destroy(&ctx->lock);
+       fimc_put_clocks(ctx);
+       pm_runtime_set_suspended(dev);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0862-exynos_drm_fimc-simplify-and-rename-fimc_dst_get_buf.patch b/patches.tizen/0862-exynos_drm_fimc-simplify-and-rename-fimc_dst_get_buf.patch
new file mode 100644 (file)
index 0000000..e0a7e60
--- /dev/null
@@ -0,0 +1,66 @@
+From fd3e22dcc03ead3c2b0c6eb84ad447d611880280 Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Wed, 9 Oct 2013 13:59:43 +0200
+Subject: [PATCH 0862/1302] exynos_drm_fimc: simplify and rename
+ fimc_dst_get_buf_seq
+
+fimc_dst_get_buf_seq returns number of buffers
+so the name should be fimc_dst_get_buf_count.
+Function body has been simplified.
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_fimc.c | 14 +++++---------
+ 1 file changed, 5 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+index d6e7bf4..ee8c821 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+@@ -58,7 +58,6 @@
+ #define FIMC_SHFACTOR 10
+ #define FIMC_BUF_STOP 1
+ #define FIMC_BUF_START        2
+-#define FIMC_REG_SZ           32
+ #define FIMC_WIDTH_ITU_709    1280
+ #define FIMC_REFRESH_MAX      60
+ #define FIMC_REFRESH_MIN      12
+@@ -1128,16 +1127,13 @@ static int fimc_dst_set_size(struct device *dev, int swap,
+       return 0;
+ }
+-static int fimc_dst_get_buf_seq(struct fimc_context *ctx)
++static int fimc_dst_get_buf_count(struct fimc_context *ctx)
+ {
+-      u32 cfg, i, buf_num = 0;
+-      u32 mask = 0x00000001;
++      u32 cfg, buf_num;
+       cfg = fimc_read(ctx, EXYNOS_CIFCNTSEQ);
+-      for (i = 0; i < FIMC_REG_SZ; i++)
+-              if (cfg & (mask << i))
+-                      buf_num++;
++      buf_num = hweight32(cfg);
+       DRM_DEBUG_KMS("%s:buf_num[%d]\n", __func__, buf_num);
+@@ -1182,12 +1178,12 @@ static int fimc_dst_set_buf_seq(struct fimc_context *ctx, u32 buf_id,
+       /* interrupt enable */
+       if (buf_type == IPP_BUF_ENQUEUE &&
+-          fimc_dst_get_buf_seq(ctx) >= FIMC_BUF_START)
++          fimc_dst_get_buf_count(ctx) >= FIMC_BUF_START)
+               fimc_mask_irq(ctx, true, false, true);
+       /* interrupt disable */
+       if (buf_type == IPP_BUF_DEQUEUE &&
+-          fimc_dst_get_buf_seq(ctx) <= FIMC_BUF_STOP)
++          fimc_dst_get_buf_count(ctx) <= FIMC_BUF_STOP)
+               fimc_mask_irq(ctx, false, false, true);
+ err_unlock:
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0863-charger-max77693-code-cleaning.patch b/patches.tizen/0863-charger-max77693-code-cleaning.patch
new file mode 100644 (file)
index 0000000..46089e1
--- /dev/null
@@ -0,0 +1,234 @@
+From 13a2ab9afbde3b320cfa2912eb2390d95f5481bd Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Fri, 11 Oct 2013 21:49:51 +0900
+Subject: [PATCH 0863/1302] charger: max77693: code cleaning
+
+- Remove duplicated macro data.
+- Improve readability.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/power/max77693_charger.c       | 125 ++-------------------------------
+ include/linux/power/max77693_charger.h |  23 +++---
+ 2 files changed, 18 insertions(+), 130 deletions(-)
+
+diff --git a/drivers/power/max77693_charger.c b/drivers/power/max77693_charger.c
+index 71e94c1..71a009d 100644
+--- a/drivers/power/max77693_charger.c
++++ b/drivers/power/max77693_charger.c
+@@ -39,125 +39,10 @@
+ #include <linux/mfd/max77693.h>
+ #include <linux/mfd/max77693-private.h>
+ #include <linux/power/charger-manager.h>
++#include <linux/power/max77693_charger.h>
+ #include <linux/extcon.h>
+ #include <plat/gpio-cfg.h>
+-/* MAX77693 Registers(defined @max77693-private.h) */
+-
+-/* MAX77693_CHG_REG_CHG_INT */
+-#define MAX77693_BYP_I                        (1 << 0)
+-#define MAX77693_THM_I                        (1 << 2)
+-#define MAX77693_BAT_I                        (1 << 3)
+-#define MAX77693_CHG_I                        (1 << 4)
+-#define MAX77693_CHGIN_I              (1 << 6)
+-
+-/* MAX77693_CHG_REG_CHG_INT_MASK */
+-#define MAX77693_BYP_IM                       (1 << 0)
+-#define MAX77693_THM_IM                       (1 << 2)
+-#define MAX77693_BAT_IM                       (1 << 3)
+-#define MAX77693_CHG_IM                       (1 << 4)
+-#define MAX77693_CHGIN_IM             (1 << 6)
+-
+-/* MAX77693_CHG_REG_CHG_INT_OK */
+-#define MAX77693_BYP_OK                       0x01
+-#define MAX77693_BYP_OK_SHIFT         0
+-#define MAX77693_THM_OK                       0x04
+-#define MAX77693_THM_OK_SHIFT         2
+-#define MAX77693_BAT_OK                       0x08
+-#define MAX77693_BAT_OK_SHIFT         3
+-#define MAX77693_CHG_OK                       0x10
+-#define MAX77693_CHG_OK_SHIFT         4
+-#define MAX77693_CHGIN_OK             0x40
+-#define MAX77693_CHGIN_OK_SHIFT               6
+-#define MAX77693_DETBAT                       0x80
+-#define MAX77693_DETBAT_SHIFT         7
+-
+-/* MAX77693_CHG_REG_CHG_DTLS_00 */
+-#define MAX77693_THM_DTLS             0x07
+-#define MAX77693_THM_DTLS_SHIFT               0
+-#define MAX77693_CHGIN_DTLS           0x60
+-#define MAX77693_CHGIN_DTLS_SHIFT     5
+-
+-/* MAX77693_CHG_REG_CHG_DTLS_01 */
+-#define MAX77693_CHG_DTLS             0x0F
+-#define MAX77693_CHG_DTLS_SHIFT               0
+-#define MAX77693_BAT_DTLS             0x70
+-#define MAX77693_BAT_DTLS_SHIFT               4
+-
+-/* MAX77693_CHG_REG_CHG_DTLS_02 */
+-#define MAX77693_BYP_DTLS             0x0F
+-#define MAX77693_BYP_DTLS_SHIFT               0
+-#define MAX77693_BYP_DTLS0    0x1
+-#define MAX77693_BYP_DTLS1    0x2
+-#define MAX77693_BYP_DTLS2    0x4
+-#define MAX77693_BYP_DTLS3    0x8
+-
+-/* MAX77693_CHG_REG_CHG_CNFG_00 */
+-#define MAX77693_MODE_DEFAULT 0x04
+-#define MAX77693_MODE_CHGR    0x01
+-#define MAX77693_MODE_OTG     0x02
+-#define MAX77693_MODE_BUCK    0x04
+-
+-/* MAX77693_CHG_REG_CHG_CNFG_02 */
+-#define MAX77693_CHG_CC               0x3F
+-
+-/* MAX77693_CHG_REG_CHG_CNFG_04 */
+-#define MAX77693_CHG_MINVSYS_MASK     0xE0
+-#define MAX77693_CHG_MINVSYS_SHIFT    5
+-#define MAX77693_CHG_MINVSYS_3_6V     0x06
+-#define MAX77693_CHG_CV_PRM_MASK              0x1F
+-#define MAX77693_CHG_CV_PRM_SHIFT             0
+-#define MAX77693_CHG_CV_PRM_4_20V             0x16
+-#define MAX77693_CHG_CV_PRM_4_35V             0x1D
+-#define MAX77693_CHG_CV_PRM_4_40V             0x1F
+-
+-/* MAX77693_CHG_REG_CHG_CNFG_06 */
+-#define MAX77693_CHG_CHGPROT          0x0C
+-#define MAX77693_CHG_CHGPROT_SHIFT    2
+-#define MAX77693_CHG_CHGPROT_UNLOCK   0x03
+-
+-/* MAX77693_CHG_REG_CHG_CNFG_09 */
+-#define MAX77693_CHG_CHGIN_LIM        0x7F
+-
+-/* MAX77693_MUIC_REG_CDETCTRL1 */
+-#define MAX77693_CHGTYPMAN            0x02
+-#define MAX77693_CHGTYPMAN_SHIFT      1
+-
+-/* MAX77693_MUIC_REG_STATUS2 */
+-#define MAX77693_VBVOLT                       0x40
+-#define MAX77693_VBVOLT_SHIFT         6
+-#define MAX77693_DXOVP                        0x20
+-#define MAX77693_DXOVP_SHIFT          5
+-#define MAX77693_CHGDETRUN            0x08
+-#define MAX77693_CHGDETRUN_SHIFT      3
+-#define MAX77693_CHGTYPE              0x07
+-#define MAX77693_CHGTYPE_SHIFT                0
+-
+-/* irq */
+-#define IRQ_DEBOUNCE_TIME     20      /* msec */
+-
+-/* charger unlock */
+-#define CHG_UNLOCK_RETRY      10
+-#define CHG_UNLOCK_DELAY      100
+-
+-/* power stabe guarantee */
+-#define STABLE_POWER_DELAY    500
+-
+-/* charger type detection */
+-#define DET_ERR_RETRY 5
+-#define DET_ERR_DELAY 200
+-
+-/* soft charging */
+-#define SOFT_CHG_START_CURR   100     /* mA */
+-#define SOFT_CHG_START_DUR    100     /* ms */
+-#define SOFT_CHG_CURR_STEP    100     /* mA */
+-#define SOFT_CHG_STEP_DUR     20      /* ms */
+-
+-/* soft regulation */
+-#define SW_REG_CURR_STEP_MA   100
+-#define SW_REG_START_DELAY    500
+-#define SW_REG_STEP_DELAY     100
+-
+ struct max77693_charger_data {
+       struct max77693_dev     *max77693;
+@@ -218,19 +103,19 @@ static int max77693_get_vbus_state(struct max77693_charger_data *chg_data)
+                               MAX77693_CHGIN_DTLS_SHIFT);
+       switch (reg_data) {
+-      case 0x00:
++      case POWER_SUPPLY_VBUS_UVLO :
+               /* V chgin < UVLO */
+               state = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
+               break;
+-      case 0x01:
++      case POWER_SUPPLY_VBUS_WEAK :
+               /* V chgin < V batt + minimum threshold */
+               state = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
+               break;
+-      case 0x02:
++      case POWER_SUPPLY_VBUS_OVLO :
+               /* V chgin > OVLO */
+               state = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
+               break;
+-      case 0x03:
++      case POWER_SUPPLY_VBUS_GOOD :
+               state = POWER_SUPPLY_HEALTH_GOOD;
+               break;
+       default:
+diff --git a/include/linux/power/max77693_charger.h b/include/linux/power/max77693_charger.h
+index 0ad2f39..6f2b677 100644
+--- a/include/linux/power/max77693_charger.h
++++ b/include/linux/power/max77693_charger.h
+@@ -18,13 +18,8 @@
+ #ifndef __MAX77693_CHARGER_H
+ #define __MAX77693_CHARGER_H __FILE__
+ #include <linux/mfd/core.h>
+-#include <linux/mfd/max77693_sec.h>
+-#include <linux/mfd/max77693-private_sec.h>
+ #include <linux/regulator/machine.h>
+-#define ENABLE 1
+-#define DISABLE 0
+-
+ /* macro */
+ #define MAX(x, y)     ((x) > (y) ? (x) : (y))
+ #define MIN(x, y)     ((x) < (y) ? (x) : (y))
+@@ -128,6 +123,14 @@
+ #define MAX77693_CHG_MINVSYS_SHIFT      5
+ #define MAX77693_CHG_PRM_MASK           0x1F
+ #define MAX77693_CHG_PRM_SHIFT          0
++#define MAX77693_CHG_CV_PRM_4_20V             0x16
++#define MAX77693_CHG_CV_PRM_4_35V             0x1D
++#define MAX77693_CHG_CV_PRM_4_40V             0x1F
++
++/* MAX77693_CHG_REG_CHG_CNFG_06 */
++#define MAX77693_CHG_CHGPROT          0x0C
++#define MAX77693_CHG_CHGPROT_SHIFT    2
++#define MAX77693_CHG_CHGPROT_UNLOCK   0x03
+ /* MAX77693_CHG_REG_CHG_CNFG_09 */
+ #define MAX77693_CHG_CHGIN_LIM  0x7F
+@@ -150,6 +153,10 @@
+ /* irq */
+ #define IRQ_DEBOUNCE_TIME       20      /* msec */
++/* charger unlock */
++#define CHG_UNLOCK_RETRY      10
++#define CHG_UNLOCK_DELAY      100
++
+ /* charger type detection */
+ #define DET_ERR_RETRY   5
+ #define DET_ERR_DELAY   200
+@@ -163,15 +170,11 @@
+ #define DEFAULT_AC_CURRENT    1600    /* mA */
+ #define DEFAULT_USB_CURRENT   500     /* mA */
+-#ifndef CONFIG_MACH_SLP_ADONIS
+ enum {
+-      POWER_SUPPLY_VBUS_UNKNOWN = 0,
+-      POWER_SUPPLY_VBUS_UVLO,
++      POWER_SUPPLY_VBUS_UVLO = 0,
+       POWER_SUPPLY_VBUS_WEAK,
+       POWER_SUPPLY_VBUS_OVLO,
+       POWER_SUPPLY_VBUS_GOOD,
+ };
+-#endif
+-extern sec_battery_platform_data_t sec_battery_pdata;
+ #endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0864-charger-max77693-Fix-initial-charger-configuration-p.patch b/patches.tizen/0864-charger-max77693-Fix-initial-charger-configuration-p.patch
new file mode 100644 (file)
index 0000000..0eb7f6e
--- /dev/null
@@ -0,0 +1,150 @@
+From 42d9e9a68946c4e28a8ec744b8a82f3761bb0101 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Fri, 11 Oct 2013 22:15:16 +0900
+Subject: [PATCH 0864/1302] charger: max77693: Fix initial charger
+ configuration properly.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/power/max77693_charger.c       | 51 ++++++++--------------------------
+ include/linux/power/max77693_charger.h | 27 ++++++++++++------
+ 2 files changed, 31 insertions(+), 47 deletions(-)
+
+diff --git a/drivers/power/max77693_charger.c b/drivers/power/max77693_charger.c
+index 71a009d..87475e5 100644
+--- a/drivers/power/max77693_charger.c
++++ b/drivers/power/max77693_charger.c
+@@ -310,66 +310,39 @@ unlock_finish:
+ static void max77693_charger_reg_init(struct max77693_charger_data *chg_data)
+ {
+       struct regmap *rmap = chg_data->max77693->regmap;
+-      u8 reg_data;
+       /*
+        * fast charge timer 10hrs
+        * restart threshold disable
+        * pre-qual charge enable(default)
+        */
+-      reg_data = (0x04 << 0) | (0x03 << 4);
+-      max77693_write_reg(rmap, MAX77693_CHG_REG_CHG_CNFG_01, reg_data);
++      max77693_update_reg(rmap, MAX77693_CHG_REG_CHG_CNFG_01,
++                      MAX77693_FCHGTIME_10HRS | MAX77693_CHG_RSTRT_MASK,
++                      MAX77693_FCHGTIME_MASK | MAX77693_CHG_RSTRT_MASK);
+       /*
+        * charge current 466mA(default)
+        * otg current limit 900mA
+        */
+-      reg_data = (1 << 7);
+-      max77693_write_reg(rmap, MAX77693_CHG_REG_CHG_CNFG_02, reg_data);
+-
++      max77693_update_reg(rmap, MAX77693_CHG_REG_CHG_CNFG_02,
++                      MAX77693_OTG_ILIM_MASK, MAX77693_OTG_ILIM_MASK);
+       /*
+        * top off current 100mA
+        * top off timer 0min
+        */
+-      reg_data = (0x00 << 0); /* 100mA */
+-
+-      reg_data |= (0x00 << 3);
+-      max77693_write_reg(rmap, MAX77693_CHG_REG_CHG_CNFG_03, reg_data);
++      max77693_update_reg(rmap, MAX77693_CHG_REG_CHG_CNFG_03,
++                      0x0, MAX77693_CHG_TO_ITHM | MAX77693_CHG_TO_TIMEM);
+       /*
+-       * cv voltage 4.2V or 4.35V
++       * cv voltage 4.35V
+        * MINVSYS 3.6V(default)
+        */
+-      reg_data &= (~MAX77693_CHG_MINVSYS_MASK);
+-      reg_data |= (MAX77693_CHG_MINVSYS_3_6V << MAX77693_CHG_MINVSYS_SHIFT);
+-      reg_data &= (~MAX77693_CHG_CV_PRM_MASK);
+-#if defined(CONFIG_MACH_M0)
+-      if ((system_rev != 3) && (system_rev >= 1))
+-              reg_data |= (MAX77693_CHG_CV_PRM_4_35V << 0);
+-      else
+-              reg_data |= (MAX77693_CHG_CV_PRM_4_20V << 0);
+-#else /* C1, C2, M3, T0, ... */
+-              reg_data |= (MAX77693_CHG_CV_PRM_4_35V << 0);
+-#endif
+-
+-      /*
+-       * For GC1 Model,  MINVSYS is 3.4V.
+-       *  For GC1 Model  PRMV( Primary Charge Regn. Voltage) = 4.2V.
+-       * Actual expected regulated voltage needs to be 4.2V but due to
+-       * internal resistance and circuit deviation we might have to set the
+-       * benchmark a bit higher sometimes. (4.225V now)
+-       */
+-#if defined(CONFIG_MACH_GC1)
+-      reg_data &= (~MAX77693_CHG_CV_PRM_MASK);
+-      reg_data |= (0x17 << MAX77693_CHG_CV_PRM_SHIFT);
+-      reg_data &= (~MAX77693_CHG_MINVSYS_MASK);
+-      reg_data |= (0x4 << MAX77693_CHG_MINVSYS_SHIFT);
+-#endif
+-      max77693_write_reg(rmap, MAX77693_CHG_REG_CHG_CNFG_04, reg_data);
++      max77693_update_reg(rmap, MAX77693_CHG_REG_CHG_CNFG_04,
++                      MAX77693_CHG_CV_PRM_4_35V, MAX77693_CHG_MINVSYS_MASK);
+       /* VBYPSET 5V */
+-      reg_data = 0x50;
+-      max77693_write_reg(rmap, MAX77693_CHG_REG_CHG_CNFG_11, reg_data);
++      max77693_write_reg(rmap, MAX77693_CHG_REG_CHG_CNFG_11,
++                                      MAX77693_CHG_VBYPSET_5V);
+ }
+ /* Support property from charger */
+diff --git a/include/linux/power/max77693_charger.h b/include/linux/power/max77693_charger.h
+index 6f2b677..baaf20a 100644
+--- a/include/linux/power/max77693_charger.h
++++ b/include/linux/power/max77693_charger.h
+@@ -112,20 +112,28 @@
+ #define MAX77693_MODE_OTG       0x02
+ #define MAX77693_MODE_BUCK      0x04
++/* MAX77693_CHG_REG_CHG_CNFG_0i */
++#define MAX77693_FCHGTIME_MASK        0x7
++#define MAX77693_FCHGTIME_4HRS        0x1
++#define MAX77693_FCHGTIME_10HRS       0x4
++#define MAX77693_CHG_RSTRT_MASK       0x30
++
+ /* MAX77693_CHG_REG_CHG_CNFG_02 */
+ #define MAX77693_CHG_CC         0x3F
++#define MAX77693_OTG_ILIM_MASK        0x80
+ /* MAX77693_CHG_REG_CHG_CNFG_03 */
+-#define MAX77693_CHG_TO_ITH           0x07
++#define MAX77693_CHG_TO_ITHM  0x07
++#define MAX77693_CHG_TO_TIMEM 0x38
+ /* MAX77693_CHG_REG_CHG_CNFG_04 */
+-#define MAX77693_CHG_MINVSYS_MASK       0xE0
+-#define MAX77693_CHG_MINVSYS_SHIFT      5
+-#define MAX77693_CHG_PRM_MASK           0x1F
+-#define MAX77693_CHG_PRM_SHIFT          0
+-#define MAX77693_CHG_CV_PRM_4_20V             0x16
+-#define MAX77693_CHG_CV_PRM_4_35V             0x1D
+-#define MAX77693_CHG_CV_PRM_4_40V             0x1F
++#define MAX77693_CHG_MINVSYS_MASK     0xE0
++#define MAX77693_CHG_MINVSYS_SHIFT    5
++#define MAX77693_CHG_MINVSYS_3_6V     0x6
++#define MAX77693_CHG_CV_PRM_MASK      0x1F
++#define MAX77693_CHG_CV_PRM_4_20V     0x16
++#define MAX77693_CHG_CV_PRM_4_35V     0x1D
++#define MAX77693_CHG_CV_PRM_4_40V     0x1F
+ /* MAX77693_CHG_REG_CHG_CNFG_06 */
+ #define MAX77693_CHG_CHGPROT          0x0C
+@@ -135,6 +143,9 @@
+ /* MAX77693_CHG_REG_CHG_CNFG_09 */
+ #define MAX77693_CHG_CHGIN_LIM  0x7F
++/* MAX77693_CHG_REG_CHG_CNFG_11 */
++#define MAX77693_CHG_VBYPSET_5V       0x50
++
+ /* MAX77693_CHG_REG_CHG_CNFG_12 */
+ #define MAX77693_CHG_WCINSEL          0x40
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0865-charger-manager-Make-charge_now-node-under-batter-sy.patch b/patches.tizen/0865-charger-manager-Make-charge_now-node-under-batter-sy.patch
new file mode 100644 (file)
index 0000000..0d1009d
--- /dev/null
@@ -0,0 +1,39 @@
+From 3514a200bbe8210b740a627a97bd50b82820458d Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Fri, 11 Oct 2013 22:25:13 +0900
+Subject: [PATCH 0865/1302] charger-manager : Make charge_now node under batter
+ sysfs directory.
+
+CHARGE_NOW property has beed used in wrong way, it should be fixed
+as it is planned initially. But for now, we just leave it for
+upper layer (e.g. OAL) for a while.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/power/charger-manager.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c
+index 7946b8a..2d5867d 100644
+--- a/drivers/power/charger-manager.c
++++ b/drivers/power/charger-manager.c
+@@ -911,9 +911,14 @@ static enum power_supply_property default_charger_props[] = {
+       POWER_SUPPLY_PROP_CAPACITY,
+       POWER_SUPPLY_PROP_ONLINE,
+       POWER_SUPPLY_PROP_CHARGE_FULL,
++
++      /* FIXME : 20131011
++       * This property has been used in wrong way.
++       * It'll be fixed sooner to it's original purpose.
++       */
++      POWER_SUPPLY_PROP_CHARGE_NOW,
+       /*
+        * Optional properties are:
+-       * POWER_SUPPLY_PROP_CHARGE_NOW,
+        * POWER_SUPPLY_PROP_CURRENT_NOW,
+        * POWER_SUPPLY_PROP_TEMP, and
+        * POWER_SUPPLY_PROP_TEMP_AMBIENT,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0866-extcon-Add-an-API-to-get-extcon-device-from-dt-node.patch b/patches.tizen/0866-extcon-Add-an-API-to-get-extcon-device-from-dt-node.patch
new file mode 100644 (file)
index 0000000..b1d0639
--- /dev/null
@@ -0,0 +1,176 @@
+From 7a1e5d177aa332820d97805cd0dc2cbda6dd6ed2 Mon Sep 17 00:00:00 2001
+From: Kishon Vijay Abraham I <kishon@ti.com>
+Date: Tue, 11 Jun 2013 20:48:02 +0900
+Subject: [PATCH 0866/1302] extcon: Add an API to get extcon device from dt
+ node
+
+Added an API of_extcon_get_extcon_dev() to be used by drivers to get
+extcon device in the case of dt boot (this can be used instead of
+extcon_get_extcon_dev()).
+
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: Myungjoo Ham <myungjoo.ham@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/extcon/Kconfig           |  4 +++
+ drivers/extcon/Makefile          |  2 ++
+ drivers/extcon/extcon-class.c    |  3 +-
+ drivers/extcon/of_extcon.c       | 64 ++++++++++++++++++++++++++++++++++++++++
+ include/linux/extcon/of_extcon.h | 31 +++++++++++++++++++
+ 5 files changed, 103 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/extcon/of_extcon.c
+ create mode 100644 include/linux/extcon/of_extcon.h
+
+diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig
+index 90b3ad0..aaebc6d 100644
+--- a/drivers/extcon/Kconfig
++++ b/drivers/extcon/Kconfig
+@@ -14,6 +14,10 @@ if EXTCON
+ comment "Extcon Device Drivers"
++config OF_EXTCON
++      def_tristate y
++      depends on OF
++
+ config EXTCON_GPIO
+       tristate "GPIO extcon support"
+       depends on GPIOLIB
+diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile
+index 034bb95..b04c038 100644
+--- a/drivers/extcon/Makefile
++++ b/drivers/extcon/Makefile
+@@ -2,6 +2,8 @@
+ # Makefile for external connector class (extcon) devices
+ #
++obj-$(CONFIG_OF_EXTCON)               += of_extcon.o
++
+ obj-$(CONFIG_EXTCON)          += extcon-class.o
+ obj-$(CONFIG_EXTCON_GPIO)     += extcon-gpio.o
+ obj-$(CONFIG_EXTCON_ADC_JACK) += extcon-adc-jack.o
+diff --git a/drivers/extcon/extcon-class.c b/drivers/extcon/extcon-class.c
+index e7b851b..972b157 100644
+--- a/drivers/extcon/extcon-class.c
++++ b/drivers/extcon/extcon-class.c
+@@ -626,7 +626,8 @@ int extcon_dev_register(struct extcon_dev *edev, struct device *dev)
+       edev->dev->class = extcon_class;
+       edev->dev->release = extcon_dev_release;
+-      dev_set_name(edev->dev, edev->name ? edev->name : dev_name(dev));
++      edev->name = edev->name ? edev->name : dev_name(dev);
++      dev_set_name(edev->dev, edev->name);
+       if (edev->max_supported) {
+               char buf[10];
+diff --git a/drivers/extcon/of_extcon.c b/drivers/extcon/of_extcon.c
+new file mode 100644
+index 0000000..72173ec
+--- /dev/null
++++ b/drivers/extcon/of_extcon.c
+@@ -0,0 +1,64 @@
++/*
++ * OF helpers for External connector (extcon) framework
++ *
++ * Copyright (C) 2013 Texas Instruments, Inc.
++ * Kishon Vijay Abraham I <kishon@ti.com>
++ *
++ * Copyright (C) 2013 Samsung Electronics
++ * Chanwoo Choi <cw00.choi@samsung.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/module.h>
++#include <linux/slab.h>
++#include <linux/err.h>
++#include <linux/extcon.h>
++#include <linux/of.h>
++#include <linux/of_platform.h>
++#include <linux/extcon/of_extcon.h>
++
++/*
++ * of_extcon_get_extcon_dev - Get the name of extcon device from devicetree
++ * @dev - instance to the given device
++ * @index - index into list of extcon_dev
++ *
++ * return the instance of extcon device
++ */
++struct extcon_dev *of_extcon_get_extcon_dev(struct device *dev, int index)
++{
++      struct device_node *node;
++      struct extcon_dev *edev;
++      struct platform_device *extcon_parent_dev;
++
++      if (!dev->of_node) {
++              dev_dbg(dev, "device does not have a device node entry\n");
++              return ERR_PTR(-EINVAL);
++      }
++
++      node = of_parse_phandle(dev->of_node, "extcon", index);
++      if (!node) {
++              dev_dbg(dev, "failed to get phandle in %s node\n",
++                      dev->of_node->full_name);
++              return ERR_PTR(-ENODEV);
++      }
++
++      extcon_parent_dev = of_find_device_by_node(node);
++      if (!extcon_parent_dev) {
++              dev_dbg(dev, "unable to find device by node\n");
++              return ERR_PTR(-EPROBE_DEFER);
++      }
++
++      edev = extcon_get_extcon_dev(dev_name(&extcon_parent_dev->dev));
++      if (!edev) {
++              dev_dbg(dev, "unable to get extcon device : %s\n",
++                              dev_name(&extcon_parent_dev->dev));
++              return ERR_PTR(-ENODEV);
++      }
++
++      return edev;
++}
++EXPORT_SYMBOL_GPL(of_extcon_get_extcon_dev);
+diff --git a/include/linux/extcon/of_extcon.h b/include/linux/extcon/of_extcon.h
+new file mode 100644
+index 0000000..0ebfeff
+--- /dev/null
++++ b/include/linux/extcon/of_extcon.h
+@@ -0,0 +1,31 @@
++/*
++ * OF helpers for External connector (extcon) framework
++ *
++ * Copyright (C) 2013 Texas Instruments, Inc.
++ * Kishon Vijay Abraham I <kishon@ti.com>
++ *
++ * Copyright (C) 2013 Samsung Electronics
++ * Chanwoo Choi <cw00.choi@samsung.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.
++ */
++
++#ifndef __LINUX_OF_EXTCON_H
++#define __LINUX_OF_EXTCON_H
++
++#include <linux/err.h>
++
++#if IS_ENABLED(CONFIG_OF_EXTCON)
++extern struct extcon_dev
++      *of_extcon_get_extcon_dev(struct device *dev, int index);
++#else
++static inline struct extcon_dev
++      *of_extcon_get_extcon_dev(struct device *dev, int index)
++{
++      return ERR_PTR(-ENOSYS);
++}
++#endif /* CONFIG_OF_EXTCON */
++#endif /* __LINUX_OF_EXTCON_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0867-extcon-Add-EXPORT_SYMBOL_GPL-for-exported-functions.patch b/patches.tizen/0867-extcon-Add-EXPORT_SYMBOL_GPL-for-exported-functions.patch
new file mode 100644 (file)
index 0000000..260aeb9
--- /dev/null
@@ -0,0 +1,43 @@
+From 2a18ff1323135edc46067e56ea80ea0a2d47fd5a Mon Sep 17 00:00:00 2001
+From: Kishon Vijay Abraham I <kishon@ti.com>
+Date: Tue, 4 Jun 2013 01:13:38 +0900
+Subject: [PATCH 0867/1302] extcon: Add EXPORT_SYMBOL_GPL for exported
+ functions
+
+Added EXPORT_SYMBOL_GPL() for extcon_register_interest and
+extcon_register_notifier in order to avoid undefined reference
+error when building the consumer modules of extcon as _modules_.
+
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
+Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: Myungjoo Ham <myungjoo.ham@samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/extcon/extcon-class.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/extcon/extcon-class.c b/drivers/extcon/extcon-class.c
+index 972b157..77fcac5 100644
+--- a/drivers/extcon/extcon-class.c
++++ b/drivers/extcon/extcon-class.c
+@@ -507,6 +507,7 @@ int extcon_register_interest(struct extcon_specific_cable_nb *obj,
+               return -ENODEV;
+       }
+ }
++EXPORT_SYMBOL_GPL(extcon_register_interest);
+ /**
+  * extcon_unregister_interest() - Unregister the notifier registered by
+@@ -521,6 +522,7 @@ int extcon_unregister_interest(struct extcon_specific_cable_nb *obj)
+       return raw_notifier_chain_unregister(&obj->edev->nh, &obj->internal_nb);
+ }
++EXPORT_SYMBOL_GPL(extcon_unregister_interest);
+ /**
+  * extcon_register_notifier() - Register a notifiee to get notified by
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0868-mfd-max77693-Add-max77693-pmuic-compatible.patch b/patches.tizen/0868-mfd-max77693-Add-max77693-pmuic-compatible.patch
new file mode 100644 (file)
index 0000000..b94f51a
--- /dev/null
@@ -0,0 +1,29 @@
+From 4269b3fa9264432e9aff991c74c54568ca282bc0 Mon Sep 17 00:00:00 2001
+From: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Date: Thu, 18 Jul 2013 13:58:43 +0200
+Subject: [PATCH 0868/1302] mfd: max77693: Add max77693-pmuic compatible
+
+This patch adds of_compatible field for max7763-pmuic - mfd device
+
+Signed-off-by: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mfd/max77693.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c
+index 0f925af..d2a6841 100644
+--- a/drivers/mfd/max77693.c
++++ b/drivers/mfd/max77693.c
+@@ -44,7 +44,7 @@ static struct mfd_cell max77693_devs[] = {
+       { .name = "max77693-pmic", },
+       { .name = "max77693-charger", },
+       { .name = "max77693-flash", },
+-      { .name = "max77693-muic", },
++      { .name = "max77693-muic", .of_compatible = "maxim,max77693-muic" },
+       { .name = "max77693-haptic", },
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0869-dts-Add-extcon-phandle-to-hsotg-node.patch b/patches.tizen/0869-dts-Add-extcon-phandle-to-hsotg-node.patch
new file mode 100644 (file)
index 0000000..aeb853e
--- /dev/null
@@ -0,0 +1,50 @@
+From 098b3e8bc85fec541e37b00e2d7e69245b09beb3 Mon Sep 17 00:00:00 2001
+From: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Date: Fri, 19 Jul 2013 09:01:50 +0200
+Subject: [PATCH 0869/1302] dts: Add extcon phandle to hsotg node
+
+This patch adds extconi device(max77693) phandle for s3c_hsotg node.
+
+Signed-off-by: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index e8d0bbc..85fb0cb 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -908,7 +908,9 @@
+                                       regulator-boot-on;
+                               };
+                       };
+-                      muic_regs {
++
++                      max_muic: max77693-muic {
++                              compatible = "maxim,max77693-muic";
+                               intmask@1 {
+                                       addr = <0x7>;
+                                       data = <0x9>;
+@@ -917,8 +919,9 @@
+                                       addr = <0x8>;
+                                       data = <0x1>;
+                               };
++
+                       };
+-              };      
++              };
+       };
+       i2c_fuel: i2c@1 {
+@@ -1067,6 +1070,7 @@
+               status = "okay";
+               vusb_d-supply = <&ldo15_reg>;
+               vusb_a-supply = <&ldo12_reg>;
++              extcon = <&max_muic>;
+               phys = <&exynos_usbphy 0>;
+               phy-names = "device";
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0870-dts-exynos4412-slp_pq-Remove-regulator_always_on-for.patch b/patches.tizen/0870-dts-exynos4412-slp_pq-Remove-regulator_always_on-for.patch
new file mode 100644 (file)
index 0000000..4add055
--- /dev/null
@@ -0,0 +1,37 @@
+From 5f4b49bc14865b1f7b836d05cc5c408db8315eae Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Tue, 15 Oct 2013 15:41:32 +0200
+Subject: [PATCH 0870/1302] dts: exynos4412-slp_pq: Remove regulator_always_on
+ for HSIC regulator
+
+This regulator should be switched on/off by driver that use it.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 85fb0cb..e3c42e1 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -697,7 +697,6 @@
+                                       regulator-name = "VHSIC_1.0V";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+-                                      regulator-always-on;
+                                       regulator-mem-off;
+                               };
+@@ -1083,7 +1082,6 @@
+               phy-names = "hsic0";
+       };
+-
+       spi_1: spi@13930000 {
+               pinctrl-names = "default";
+               pinctrl-0 = <&spi1_bus>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0871-phy-exynos-usb-Remove-ref-counting-for-additional-re.patch b/patches.tizen/0871-phy-exynos-usb-Remove-ref-counting-for-additional-re.patch
new file mode 100644 (file)
index 0000000..30a7c6b
--- /dev/null
@@ -0,0 +1,41 @@
+From 9e4e5c706b131abd8a774b2813901eeba97d9026 Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Tue, 15 Oct 2013 15:41:41 +0200
+Subject: [PATCH 0871/1302] phy: exynos-usb: Remove ref counting for additional
+ reset for Exynos4212
+
+Reference counting in this case is not necessary.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/phy/phy-exynos4212-usb.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/drivers/phy/phy-exynos4212-usb.c b/drivers/phy/phy-exynos4212-usb.c
+index b7de33f..a9fa15d 100644
+--- a/drivers/phy/phy-exynos4212-usb.c
++++ b/drivers/phy/phy-exynos4212-usb.c
+@@ -262,9 +262,6 @@ static int exynos4212_power_on(struct uphy_instance *inst)
+       if (inst->cfg->id == EXYNOS4212_HSIC0) {
+               struct uphy_instance *device =
+                                       &drv->uphy_instances[EXYNOS4212_DEVICE];
+-              device->ref_cnt++;
+-              if (device->ref_cnt > 1)
+-                      return 0;
+               exynos4212_phy_pwr(device, 1);
+               exynos4212_isol(device, 0);
+       }
+@@ -294,9 +291,6 @@ static int exynos4212_power_off(struct uphy_instance *inst)
+       if (inst->cfg->id == EXYNOS4212_HSIC0) {
+               struct uphy_instance *device =
+                                       &drv->uphy_instances[EXYNOS4212_DEVICE];
+-              device->ref_cnt--;
+-              if (device->ref_cnt > 0)
+-                      return 0;
+               exynos4212_phy_pwr(device, 0);
+               exynos4212_isol(device, 1);
+       }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0872-s3c-hsotg-Regulator-switching-fix.patch b/patches.tizen/0872-s3c-hsotg-Regulator-switching-fix.patch
new file mode 100644 (file)
index 0000000..13a64e5
--- /dev/null
@@ -0,0 +1,49 @@
+From e0163452f3f50bf134b6100c7c98f0facfea5c4a Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Tue, 15 Oct 2013 15:26:40 +0200
+Subject: [PATCH 0872/1302] s3c-hsotg: Regulator switching fix
+
+This patch delays switching off regulators in s3c_hsotg_udc_stop after
+the critical section has been finished.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/s3c-hsotg.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
+index f9bd408..dfa56e7 100644
+--- a/drivers/usb/gadget/s3c-hsotg.c
++++ b/drivers/usb/gadget/s3c-hsotg.c
+@@ -3005,9 +3005,6 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget,
+       spin_lock_irqsave(&hsotg->lock, flags);
+-      s3c_hsotg_phy_disable(hsotg);
+-      regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
+-
+       if (!driver)
+               hsotg->driver = NULL;
+@@ -3015,6 +3012,8 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget,
+       spin_unlock_irqrestore(&hsotg->lock, flags);
++      regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
++
+       return 0;
+ }
+@@ -3555,6 +3554,8 @@ static int s3c_hsotg_probe(struct platform_device *pdev)
+       hsotg->gadget.ops = &s3c_hsotg_gadget_ops;
+       hsotg->gadget.name = dev_name(dev);
++      hsotg->gadget.dev.of_node = hsotg->dev->of_node;
++
+       /* reset the system */
+       clk_prepare_enable(hsotg->clk);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0873-s3c-hsotg-Fix-driver-context-storing.patch b/patches.tizen/0873-s3c-hsotg-Fix-driver-context-storing.patch
new file mode 100644 (file)
index 0000000..56258f4
--- /dev/null
@@ -0,0 +1,31 @@
+From 815f85f99a3948016b896e770d565e563fec2592 Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Tue, 15 Oct 2013 15:16:05 +0200
+Subject: [PATCH 0873/1302] s3c-hsotg: Fix driver context storing
+
+Before applying this fix calling s3c_hsotg_udc_start, *stop and *start
+again resulted in a WARN_ON(hsotg->driver) being triggered in *start.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/s3c-hsotg.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
+index dfa56e7..25008c0 100644
+--- a/drivers/usb/gadget/s3c-hsotg.c
++++ b/drivers/usb/gadget/s3c-hsotg.c
+@@ -3005,8 +3005,7 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget,
+       spin_lock_irqsave(&hsotg->lock, flags);
+-      if (!driver)
+-              hsotg->driver = NULL;
++      hsotg->driver = NULL;
+       hsotg->gadget.speed = USB_SPEED_UNKNOWN;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0874-usb-gadget-udc-core-Add-extcon-hanling-to-reduce-pow.patch b/patches.tizen/0874-usb-gadget-udc-core-Add-extcon-hanling-to-reduce-pow.patch
new file mode 100644 (file)
index 0000000..0f57a72
--- /dev/null
@@ -0,0 +1,169 @@
+From 695a5c99e399cf67ae9f9ab724f135af1fb0279d Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Tue, 15 Oct 2013 13:55:18 +0200
+Subject: [PATCH 0874/1302] usb: gadget: udc-core: Add extcon hanling to reduce
+ power use
+
+Extcon driver provides information about what kind of cable has been
+inserted in the device's USB port. Power use can be reduced if UDC is
+switched off while no suitable cable is present.
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/udc-core.c | 90 ++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 88 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
+index 5514822..dcaa5bf 100644
+--- a/drivers/usb/gadget/udc-core.c
++++ b/drivers/usb/gadget/udc-core.c
+@@ -27,6 +27,11 @@
+ #include <linux/usb/ch9.h>
+ #include <linux/usb/gadget.h>
++#include <linux/of.h>
++#include <linux/extcon.h>
++#include <linux/extcon/of_extcon.h>
++#include <linux/workqueue.h>
++
+ /**
+  * struct usb_udc - describes one usb device controller
+  * @driver - the gadget driver pointer. For use by the class code
+@@ -42,6 +47,12 @@ struct usb_udc {
+       struct usb_gadget               *gadget;
+       struct device                   dev;
+       struct list_head                list;
++      struct extcon_specific_cable_nb extcon_usb_dev;
++      struct notifier_block           extcon_nb;
++      struct workqueue_struct         *pwr_workqueue;
++      struct work_struct              pwr_work;
++      char                            cable_state;
++      char                            enabled;
+ };
+ static struct class *udc_class;
+@@ -266,6 +277,10 @@ static void usb_gadget_remove_driver(struct usb_udc *udc)
+       dev_dbg(&udc->dev, "unregistering UDC driver [%s]\n",
+                       udc->gadget->name);
++      if (udc->extcon_usb_dev.edev)
++              extcon_unregister_notifier(udc->extcon_usb_dev.edev,
++                                                      &udc->extcon_nb);
++
+       kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
+       usb_gadget_disconnect(udc->gadget);
+@@ -314,10 +329,44 @@ found:
+ }
+ EXPORT_SYMBOL_GPL(usb_del_gadget_udc);
++static void udc_pwr_worker(struct work_struct * work)
++{
++      struct usb_udc *udc = container_of(work, struct usb_udc, pwr_work);
++
++      dev_dbg(&udc->dev, "UDC power worker, cable_state=%d, enabled=%d\n",
++                                              udc->cable_state, udc->enabled);
++
++      if (udc->cable_state && !udc->enabled) {
++              usb_gadget_udc_start(udc->gadget, udc->driver);
++              usb_gadget_connect(udc->gadget);
++              udc->enabled = 1;
++      } else if (!udc->cable_state && udc->enabled) {
++              usb_gadget_disconnect(udc->gadget);
++              usb_gadget_udc_stop(udc->gadget, udc->driver);
++              udc->enabled = 0;
++      }
++}
++
++static int udc_extcon_notifier(struct notifier_block *nb, unsigned long event,
++                                                              void *ptr)
++{
++      struct usb_udc *udc = container_of(nb, struct usb_udc, extcon_nb);
++
++      dev_dbg(&udc->dev, "extcon notifier, cable state=%lu\n", event);
++      udc->cable_state = event;
++
++      queue_work(udc->pwr_workqueue, &udc->pwr_work);
++
++      return NOTIFY_OK;
++}
++
++
+ /* ------------------------------------------------------------------------- */
+ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *driver)
+ {
++      const struct device_node *node;
++      struct extcon_dev *edev = 0;
+       int ret;
+       dev_dbg(&udc->dev, "registering UDC driver [%s]\n",
+@@ -327,18 +376,54 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri
+       udc->dev.driver = &driver->driver;
+       udc->gadget->dev.driver = &driver->driver;
++      node = udc->gadget->dev.of_node;
++      /* Check if we have an extcon associated with the UDC driver */
++      if (node && of_property_read_bool(node, "extcon")) {
++              edev = of_extcon_get_extcon_dev(&udc->gadget->dev, 0);
++
++              if(IS_ERR(edev)) {
++                      dev_dbg(&udc->dev, "couldn't get extcon device\n");
++                      ret = -EINVAL;
++                      goto err1;
++              }
++
++              udc->pwr_workqueue = create_singlethread_workqueue("udc");
++              INIT_WORK(&udc->pwr_work, udc_pwr_worker);
++              udc->extcon_nb.notifier_call = udc_extcon_notifier;
++              ret = extcon_register_interest(&udc->extcon_usb_dev, edev->name,
++                                                      "USB", &udc->extcon_nb);
++
++              if (ret) {
++                      dev_err(&udc->dev, "failed to register notifier for USB\n");
++                      goto err1;
++              }
++
++      }
++
+       ret = driver->bind(udc->gadget, driver);
+       if (ret)
+-              goto err1;
++              goto err2;
+       ret = usb_gadget_udc_start(udc->gadget, driver);
+       if (ret) {
+               driver->unbind(udc->gadget);
+-              goto err1;
++              goto err2;
+       }
++
+       usb_gadget_connect(udc->gadget);
++      if (udc->extcon_usb_dev.edev) {
++              udc->enabled = 1;
++              udc->cable_state = extcon_get_cable_state_(
++                                      udc->extcon_usb_dev.edev,
++                                      udc->extcon_usb_dev.cable_index);
++              queue_work(udc->pwr_workqueue, &udc->pwr_work);
++      }
++
+       kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
+       return 0;
++err2:
++      if (udc->extcon_usb_dev.edev)
++              extcon_unregister_notifier(edev, &udc->extcon_nb);
+ err1:
+       dev_err(&udc->dev, "failed to start %s: %d\n",
+                       udc->driver->function, ret);
+@@ -551,6 +636,7 @@ static int __init usb_udc_init(void)
+       }
+       udc_class->dev_uevent = usb_udc_uevent;
++
+       return 0;
+ }
+ subsys_initcall(usb_udc_init);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0875-extcon-Extcon-load-time-modification.patch b/patches.tizen/0875-extcon-Extcon-load-time-modification.patch
new file mode 100644 (file)
index 0000000..daf5697
--- /dev/null
@@ -0,0 +1,56 @@
+From a1df23d6d84b5e3f99f83ee941134a19d19651a1 Mon Sep 17 00:00:00 2001
+From: Kamil Debski <k.debski@samsung.com>
+Date: Tue, 15 Oct 2013 15:30:00 +0200
+Subject: [PATCH 0875/1302] extcon: Extcon load time modification
+
+This modification enables use of extcon by drivers loaded early during the
+boot (e.g. udc-core).
+
+Signed-off-by: Kamil Debski <k.debski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/extcon/extcon-class.c    |  2 +-
+ drivers/extcon/extcon-max77693.c | 14 +++++++++++++-
+ 2 files changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/extcon/extcon-class.c b/drivers/extcon/extcon-class.c
+index 77fcac5..5fe0ff7 100644
+--- a/drivers/extcon/extcon-class.c
++++ b/drivers/extcon/extcon-class.c
+@@ -847,7 +847,7 @@ static int __init extcon_class_init(void)
+ {
+       return create_extcon_class();
+ }
+-module_init(extcon_class_init);
++subsys_initcall(extcon_class_init);
+ static void __exit extcon_class_exit(void)
+ {
+diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c
+index 2f1e3f1..eda131c 100644
+--- a/drivers/extcon/extcon-max77693.c
++++ b/drivers/extcon/extcon-max77693.c
+@@ -1312,7 +1312,19 @@ static struct platform_driver max77693_muic_driver = {
+       .remove         = max77693_muic_remove,
+ };
+-module_platform_driver(max77693_muic_driver);
++static int __init max77693_muic_init(void)
++{
++      return platform_driver_register(&max77693_muic_driver);
++}
++
++subsys_initcall(max77693_muic_init);
++
++static void __exit max77693_muic_cleanup(void)
++{
++      platform_driver_unregister(&max77693_muic_driver);
++}
++
++module_exit(max77693_muic_cleanup);
+ MODULE_DESCRIPTION("Maxim MAX77693 Extcon driver");
+ MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0876-Fuel-Guague-MAX17042-Use-regmap-to-interface-with-in.patch b/patches.tizen/0876-Fuel-Guague-MAX17042-Use-regmap-to-interface-with-in.patch
new file mode 100644 (file)
index 0000000..c2aec5e
--- /dev/null
@@ -0,0 +1,673 @@
+From ca3e3ea869cd11b856ec6b2c09701fa8e510aba7 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Wed, 16 Oct 2013 13:39:11 +0900
+Subject: [PATCH 0876/1302] Fuel Guague: MAX17042: Use regmap to interface with
+ internal registers
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/power/max17042_battery.c | 320 +++++++++++++++++++--------------------
+ 1 file changed, 155 insertions(+), 165 deletions(-)
+
+diff --git a/drivers/power/max17042_battery.c b/drivers/power/max17042_battery.c
+index dbe2e08..88e161d 100644
+--- a/drivers/power/max17042_battery.c
++++ b/drivers/power/max17042_battery.c
+@@ -33,6 +33,7 @@
+ #include <linux/power_supply.h>
+ #include <linux/power/max17042_battery.h>
+ #include <linux/of.h>
++#include <linux/regmap.h>
+ /* Status register bits */
+ #define STATUS_POR_BIT         (1 << 1)
+@@ -67,40 +68,12 @@
+ struct max17042_chip {
+       struct i2c_client *client;
++      struct regmap *regmap;
+       struct power_supply battery;
+       enum max170xx_chip_type chip_type;
+       struct max17042_platform_data *pdata;
+ };
+-static int max17042_write_reg(struct i2c_client *client, u8 reg, u16 value)
+-{
+-      int ret = i2c_smbus_write_word_data(client, reg, value);
+-
+-      if (ret < 0)
+-              dev_err(&client->dev, "%s: err %d\n", __func__, ret);
+-
+-      return ret;
+-}
+-
+-static int max17042_read_reg(struct i2c_client *client, u8 reg)
+-{
+-      int ret = i2c_smbus_read_word_data(client, reg);
+-
+-      if (ret < 0)
+-              dev_err(&client->dev, "%s: err %d\n", __func__, ret);
+-
+-      return ret;
+-}
+-
+-static void max17042_set_reg(struct i2c_client *client,
+-                           struct max17042_reg_data *data, int size)
+-{
+-      int i;
+-
+-      for (i = 0; i < size; i++)
+-              max17042_write_reg(client, data[i].addr, data[i].data);
+-}
+-
+ static enum power_supply_property max17042_battery_props[] = {
+       POWER_SUPPLY_PROP_PRESENT,
+       POWER_SUPPLY_PROP_CYCLE_COUNT,
+@@ -123,12 +96,13 @@ static int max17042_get_property(struct power_supply *psy,
+ {
+       struct max17042_chip *chip = container_of(psy,
+                               struct max17042_chip, battery);
++      struct regmap *map = chip->regmap;
+       int ret;
+       u8 reg;
+       switch (psp) {
+       case POWER_SUPPLY_PROP_PRESENT:
+-              ret = max17042_read_reg(chip->client, MAX17042_STATUS);
++              regmap_read(map, MAX17042_STATUS, &ret);
+               if (ret < 0)
+                       return ret;
+@@ -138,14 +112,14 @@ static int max17042_get_property(struct power_supply *psy,
+                       val->intval = 1;
+               break;
+       case POWER_SUPPLY_PROP_CYCLE_COUNT:
+-              ret = max17042_read_reg(chip->client, MAX17042_Cycles);
++              regmap_read(map, MAX17042_Cycles, &ret);
+               if (ret < 0)
+                       return ret;
+               val->intval = ret;
+               break;
+       case POWER_SUPPLY_PROP_VOLTAGE_MAX:
+-              ret = max17042_read_reg(chip->client, MAX17042_MinMaxVolt);
++              regmap_read(map, MAX17042_MinMaxVolt, &ret);
+               if (ret < 0)
+                       return ret;
+@@ -154,9 +128,9 @@ static int max17042_get_property(struct power_supply *psy,
+               break;
+       case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+               if (chip->chip_type == MAX17042)
+-                      ret = max17042_read_reg(chip->client, MAX17042_V_empty);
++                      regmap_read(map, MAX17042_V_empty, &ret);
+               else
+-                      ret = max17042_read_reg(chip->client, MAX17047_V_empty);
++                      regmap_read(map, MAX17047_V_empty, &ret);
+               if (ret < 0)
+                       return ret;
+@@ -164,21 +138,21 @@ static int max17042_get_property(struct power_supply *psy,
+               val->intval *= 10000; /* Units of LSB = 10mV */
+               break;
+       case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+-              ret = max17042_read_reg(chip->client, MAX17042_VCELL);
++              regmap_read(map, MAX17042_VCELL, &ret);
+               if (ret < 0)
+                       return ret;
+               val->intval = ret * 625 / 8;
+               break;
+       case POWER_SUPPLY_PROP_VOLTAGE_AVG:
+-              ret = max17042_read_reg(chip->client, MAX17042_AvgVCELL);
++              regmap_read(map, MAX17042_AvgVCELL, &ret);
+               if (ret < 0)
+                       return ret;
+               val->intval = ret * 625 / 8;
+               break;
+       case POWER_SUPPLY_PROP_VOLTAGE_OCV:
+-              ret = max17042_read_reg(chip->client, MAX17042_OCVInternal);
++              regmap_read(map, MAX17042_OCVInternal, &ret);
+               if (ret < 0)
+                       return ret;
+@@ -190,28 +164,28 @@ static int max17042_get_property(struct power_supply *psy,
+               else
+                       reg = MAX17042_VFSOC;           /* SOC from VFG */
+-              ret = max17042_read_reg(chip->client, reg);
++              regmap_read(map, reg, &ret);
+               if (ret < 0)
+                       return ret;
+               val->intval = ret >> 8;
+               break;
+       case POWER_SUPPLY_PROP_CHARGE_FULL:
+-              ret = max17042_read_reg(chip->client, MAX17042_FullCAP);
++              regmap_read(map, MAX17042_FullCAP, &ret);
+               if (ret < 0)
+                       return ret;
+               val->intval = ret * 1000 / 2;
+               break;
+       case POWER_SUPPLY_PROP_CHARGE_COUNTER:
+-              ret = max17042_read_reg(chip->client, MAX17042_QH);
++              regmap_read(map, MAX17042_QH, &ret);
+               if (ret < 0)
+                       return ret;
+               val->intval = ret * 1000 / 2;
+               break;
+       case POWER_SUPPLY_PROP_TEMP:
+-              ret = max17042_read_reg(chip->client, MAX17042_TEMP);
++              regmap_read(map, MAX17042_TEMP, &ret);
+               if (ret < 0)
+                       return ret;
+@@ -227,7 +201,7 @@ static int max17042_get_property(struct power_supply *psy,
+               break;
+       case POWER_SUPPLY_PROP_CURRENT_NOW:
+               if (chip->pdata->enable_current_sense) {
+-                      ret = max17042_read_reg(chip->client, MAX17042_Current);
++                      regmap_read(map, MAX17042_Current, &ret);
+                       if (ret < 0)
+                               return ret;
+@@ -245,8 +219,7 @@ static int max17042_get_property(struct power_supply *psy,
+               break;
+       case POWER_SUPPLY_PROP_CURRENT_AVG:
+               if (chip->pdata->enable_current_sense) {
+-                      ret = max17042_read_reg(chip->client,
+-                                              MAX17042_AvgCurrent);
++                      regmap_read(map, MAX17042_AvgCurrent, &ret);
+                       if (ret < 0)
+                               return ret;
+@@ -268,16 +241,15 @@ static int max17042_get_property(struct power_supply *psy,
+       return 0;
+ }
+-static int max17042_write_verify_reg(struct i2c_client *client,
+-                              u8 reg, u16 value)
++static int max17042_write_verify_reg(struct regmap *map, u8 reg, u32 value)
+ {
+       int retries = 8;
+       int ret;
+-      u16 read_value;
++      u32 read_value;
+       do {
+-              ret = i2c_smbus_write_word_data(client, reg, value);
+-              read_value =  max17042_read_reg(client, reg);
++              ret = regmap_write(map, reg, value);
++              regmap_read(map, reg, &read_value);
+               if (read_value != value) {
+                       ret = -EIO;
+                       retries--;
+@@ -285,50 +257,51 @@ static int max17042_write_verify_reg(struct i2c_client *client,
+       } while (retries && read_value != value);
+       if (ret < 0)
+-              dev_err(&client->dev, "%s: err %d\n", __func__, ret);
++              pr_err("%s: err %d\n", __func__, ret);
+       return ret;
+ }
+-static inline void max17042_override_por(
+-      struct i2c_client *client, u8 reg, u16 value)
++static inline void max17042_override_por(struct regmap *map,
++                                       u8 reg, u16 value)
+ {
+       if (value)
+-              max17042_write_reg(client, reg, value);
++              regmap_write(map, reg, value);
+ }
+ static inline void max10742_unlock_model(struct max17042_chip *chip)
+ {
+-      struct i2c_client *client = chip->client;
+-      max17042_write_reg(client, MAX17042_MLOCKReg1, MODEL_UNLOCK1);
+-      max17042_write_reg(client, MAX17042_MLOCKReg2, MODEL_UNLOCK2);
++      struct regmap *map = chip->regmap;
++      regmap_write(map, MAX17042_MLOCKReg1, MODEL_UNLOCK1);
++      regmap_write(map, MAX17042_MLOCKReg2, MODEL_UNLOCK2);
+ }
+ static inline void max10742_lock_model(struct max17042_chip *chip)
+ {
+-      struct i2c_client *client = chip->client;
+-      max17042_write_reg(client, MAX17042_MLOCKReg1, MODEL_LOCK1);
+-      max17042_write_reg(client, MAX17042_MLOCKReg2, MODEL_LOCK2);
++      struct regmap *map = chip->regmap;
++
++      regmap_write(map, MAX17042_MLOCKReg1, MODEL_LOCK1);
++      regmap_write(map, MAX17042_MLOCKReg2, MODEL_LOCK2);
+ }
+ static inline void max17042_write_model_data(struct max17042_chip *chip,
+                                       u8 addr, int size)
+ {
+-      struct i2c_client *client = chip->client;
++      struct regmap *map = chip->regmap;
+       int i;
+       for (i = 0; i < size; i++)
+-              max17042_write_reg(client, addr + i,
+-                              chip->pdata->config_data->cell_char_tbl[i]);
++              regmap_write(map, addr + i,
++                      chip->pdata->config_data->cell_char_tbl[i]);
+ }
+ static inline void max17042_read_model_data(struct max17042_chip *chip,
+-                                      u8 addr, u16 *data, int size)
++                                      u8 addr, u32 *data, int size)
+ {
+-      struct i2c_client *client = chip->client;
++      struct regmap *map = chip->regmap;
+       int i;
+       for (i = 0; i < size; i++)
+-              data[i] = max17042_read_reg(client, addr + i);
++              regmap_read(map, addr + i, &data[i]);
+ }
+ static inline int max17042_model_data_compare(struct max17042_chip *chip,
+@@ -351,7 +324,7 @@ static int max17042_init_model(struct max17042_chip *chip)
+ {
+       int ret;
+       int table_size = ARRAY_SIZE(chip->pdata->config_data->cell_char_tbl);
+-      u16 *temp_data;
++      u32 *temp_data;
+       temp_data = kcalloc(table_size, sizeof(*temp_data), GFP_KERNEL);
+       if (!temp_data)
+@@ -366,7 +339,7 @@ static int max17042_init_model(struct max17042_chip *chip)
+       ret = max17042_model_data_compare(
+               chip,
+               chip->pdata->config_data->cell_char_tbl,
+-              temp_data,
++              (u16 *)temp_data,
+               table_size);
+       max10742_lock_model(chip);
+@@ -379,7 +352,7 @@ static int max17042_verify_model_lock(struct max17042_chip *chip)
+ {
+       int i;
+       int table_size = ARRAY_SIZE(chip->pdata->config_data->cell_char_tbl);
+-      u16 *temp_data;
++      u32 *temp_data;
+       int ret = 0;
+       temp_data = kcalloc(table_size, sizeof(*temp_data), GFP_KERNEL);
+@@ -399,40 +372,38 @@ static int max17042_verify_model_lock(struct max17042_chip *chip)
+ static void max17042_write_config_regs(struct max17042_chip *chip)
+ {
+       struct max17042_config_data *config = chip->pdata->config_data;
++      struct regmap *map = chip->regmap;
+-      max17042_write_reg(chip->client, MAX17042_CONFIG, config->config);
+-      max17042_write_reg(chip->client, MAX17042_LearnCFG, config->learn_cfg);
+-      max17042_write_reg(chip->client, MAX17042_FilterCFG,
++      regmap_write(map, MAX17042_CONFIG, config->config);
++      regmap_write(map, MAX17042_LearnCFG, config->learn_cfg);
++      regmap_write(map, MAX17042_FilterCFG,
+                       config->filter_cfg);
+-      max17042_write_reg(chip->client, MAX17042_RelaxCFG, config->relax_cfg);
++      regmap_write(map, MAX17042_RelaxCFG, config->relax_cfg);
+       if (chip->chip_type == MAX17047)
+-              max17042_write_reg(chip->client, MAX17047_FullSOCThr,
++              regmap_write(map, MAX17047_FullSOCThr,
+                                               config->full_soc_thresh);
+ }
+ static void  max17042_write_custom_regs(struct max17042_chip *chip)
+ {
+       struct max17042_config_data *config = chip->pdata->config_data;
++      struct regmap *map = chip->regmap;
+-      max17042_write_verify_reg(chip->client, MAX17042_RCOMP0,
+-                              config->rcomp0);
+-      max17042_write_verify_reg(chip->client, MAX17042_TempCo,
+-                              config->tcompc0);
+-      max17042_write_verify_reg(chip->client, MAX17042_ICHGTerm,
+-                              config->ichgt_term);
++      max17042_write_verify_reg(map, MAX17042_RCOMP0, config->rcomp0);
++      max17042_write_verify_reg(map, MAX17042_TempCo, config->tcompc0);
++      max17042_write_verify_reg(map, MAX17042_ICHGTerm, config->ichgt_term);
+       if (chip->chip_type == MAX17042) {
+-              max17042_write_reg(chip->client, MAX17042_EmptyTempCo,
+-                                      config->empty_tempco);
+-              max17042_write_verify_reg(chip->client, MAX17042_K_empty0,
++              regmap_write(map, MAX17042_EmptyTempCo, config->empty_tempco);
++              max17042_write_verify_reg(map, MAX17042_K_empty0,
+                                       config->kempty0);
+       } else {
+-              max17042_write_verify_reg(chip->client, MAX17047_QRTbl00,
++              max17042_write_verify_reg(map, MAX17047_QRTbl00,
+                                               config->qrtbl00);
+-              max17042_write_verify_reg(chip->client, MAX17047_QRTbl10,
++              max17042_write_verify_reg(map, MAX17047_QRTbl10,
+                                               config->qrtbl10);
+-              max17042_write_verify_reg(chip->client, MAX17047_QRTbl20,
++              max17042_write_verify_reg(map, MAX17047_QRTbl20,
+                                               config->qrtbl20);
+-              max17042_write_verify_reg(chip->client, MAX17047_QRTbl30,
++              max17042_write_verify_reg(map, MAX17047_QRTbl30,
+                                               config->qrtbl30);
+       }
+ }
+@@ -440,58 +411,60 @@ static void  max17042_write_custom_regs(struct max17042_chip *chip)
+ static void max17042_update_capacity_regs(struct max17042_chip *chip)
+ {
+       struct max17042_config_data *config = chip->pdata->config_data;
++      struct regmap *map = chip->regmap;
+-      max17042_write_verify_reg(chip->client, MAX17042_FullCAP,
++      max17042_write_verify_reg(map, MAX17042_FullCAP,
+                               config->fullcap);
+-      max17042_write_reg(chip->client, MAX17042_DesignCap,
+-                      config->design_cap);
+-      max17042_write_verify_reg(chip->client, MAX17042_FullCAPNom,
++      regmap_write(map, MAX17042_DesignCap, config->design_cap);
++      max17042_write_verify_reg(map, MAX17042_FullCAPNom,
+                               config->fullcapnom);
+ }
+ static void max17042_reset_vfsoc0_reg(struct max17042_chip *chip)
+ {
+-      u16 vfSoc;
++      unsigned int vfSoc;
++      struct regmap *map = chip->regmap;
+-      vfSoc = max17042_read_reg(chip->client, MAX17042_VFSOC);
+-      max17042_write_reg(chip->client, MAX17042_VFSOC0Enable, VFSOC0_UNLOCK);
+-      max17042_write_verify_reg(chip->client, MAX17042_VFSOC0, vfSoc);
+-      max17042_write_reg(chip->client, MAX17042_VFSOC0Enable, VFSOC0_LOCK);
++      regmap_read(map, MAX17042_VFSOC, &vfSoc);
++      regmap_write(map, MAX17042_VFSOC0Enable, VFSOC0_UNLOCK);
++      max17042_write_verify_reg(map, MAX17042_VFSOC0, vfSoc);
++      regmap_write(map, MAX17042_VFSOC0Enable, VFSOC0_LOCK);
+ }
+ static void max17042_load_new_capacity_params(struct max17042_chip *chip)
+ {
+-      u16 full_cap0, rep_cap, dq_acc, vfSoc;
++      u32 full_cap0, rep_cap, dq_acc, vfSoc;
+       u32 rem_cap;
+       struct max17042_config_data *config = chip->pdata->config_data;
++      struct regmap *map = chip->regmap;
+-      full_cap0 = max17042_read_reg(chip->client, MAX17042_FullCAP0);
+-      vfSoc = max17042_read_reg(chip->client, MAX17042_VFSOC);
++      regmap_read(map, MAX17042_FullCAP0, &full_cap0);
++      regmap_read(map, MAX17042_VFSOC, &vfSoc);
+       /* fg_vfSoc needs to shifted by 8 bits to get the
+        * perc in 1% accuracy, to get the right rem_cap multiply
+        * full_cap0, fg_vfSoc and devide by 100
+        */
+       rem_cap = ((vfSoc >> 8) * full_cap0) / 100;
+-      max17042_write_verify_reg(chip->client, MAX17042_RemCap, (u16)rem_cap);
++      max17042_write_verify_reg(map, MAX17042_RemCap, rem_cap);
+-      rep_cap = (u16)rem_cap;
+-      max17042_write_verify_reg(chip->client, MAX17042_RepCap, rep_cap);
++      rep_cap = rem_cap;
++      max17042_write_verify_reg(map, MAX17042_RepCap, rep_cap);
+       /* Write dQ_acc to 200% of Capacity and dP_acc to 200% */
+       dq_acc = config->fullcap / dQ_ACC_DIV;
+-      max17042_write_verify_reg(chip->client, MAX17042_dQacc, dq_acc);
+-      max17042_write_verify_reg(chip->client, MAX17042_dPacc, dP_ACC_200);
++      max17042_write_verify_reg(map, MAX17042_dQacc, dq_acc);
++      max17042_write_verify_reg(map, MAX17042_dPacc, dP_ACC_200);
+-      max17042_write_verify_reg(chip->client, MAX17042_FullCAP,
++      max17042_write_verify_reg(map, MAX17042_FullCAP,
+                       config->fullcap);
+-      max17042_write_reg(chip->client, MAX17042_DesignCap,
++      regmap_write(map, MAX17042_DesignCap,
+                       config->design_cap);
+-      max17042_write_verify_reg(chip->client, MAX17042_FullCAPNom,
++      max17042_write_verify_reg(map, MAX17042_FullCAPNom,
+                       config->fullcapnom);
+       /* Update SOC register with new SOC */
+-      max17042_write_reg(chip->client, MAX17042_RepSOC, vfSoc);
++      regmap_write(map, MAX17042_RepSOC, vfSoc);
+ }
+ /*
+@@ -501,59 +474,60 @@ static void max17042_load_new_capacity_params(struct max17042_chip *chip)
+  */
+ static inline void max17042_override_por_values(struct max17042_chip *chip)
+ {
+-      struct i2c_client *client = chip->client;
++      struct regmap *map = chip->regmap;
+       struct max17042_config_data *config = chip->pdata->config_data;
+-      max17042_override_por(client, MAX17042_TGAIN, config->tgain);
+-      max17042_override_por(client, MAx17042_TOFF, config->toff);
+-      max17042_override_por(client, MAX17042_CGAIN, config->cgain);
+-      max17042_override_por(client, MAX17042_COFF, config->coff);
+-
+-      max17042_override_por(client, MAX17042_VALRT_Th, config->valrt_thresh);
+-      max17042_override_por(client, MAX17042_TALRT_Th, config->talrt_thresh);
+-      max17042_override_por(client, MAX17042_SALRT_Th,
+-                      config->soc_alrt_thresh);
+-      max17042_override_por(client, MAX17042_CONFIG, config->config);
+-      max17042_override_por(client, MAX17042_SHDNTIMER, config->shdntimer);
+-
+-      max17042_override_por(client, MAX17042_DesignCap, config->design_cap);
+-      max17042_override_por(client, MAX17042_ICHGTerm, config->ichgt_term);
+-
+-      max17042_override_por(client, MAX17042_AtRate, config->at_rate);
+-      max17042_override_por(client, MAX17042_LearnCFG, config->learn_cfg);
+-      max17042_override_por(client, MAX17042_FilterCFG, config->filter_cfg);
+-      max17042_override_por(client, MAX17042_RelaxCFG, config->relax_cfg);
+-      max17042_override_por(client, MAX17042_MiscCFG, config->misc_cfg);
+-      max17042_override_por(client, MAX17042_MaskSOC, config->masksoc);
+-
+-      max17042_override_por(client, MAX17042_FullCAP, config->fullcap);
+-      max17042_override_por(client, MAX17042_FullCAPNom, config->fullcapnom);
++      max17042_override_por(map, MAX17042_TGAIN, config->tgain);
++      max17042_override_por(map, MAx17042_TOFF, config->toff);
++      max17042_override_por(map, MAX17042_CGAIN, config->cgain);
++      max17042_override_por(map, MAX17042_COFF, config->coff);
++
++      max17042_override_por(map, MAX17042_VALRT_Th, config->valrt_thresh);
++      max17042_override_por(map, MAX17042_TALRT_Th, config->talrt_thresh);
++      max17042_override_por(map, MAX17042_SALRT_Th,
++                                              config->soc_alrt_thresh);
++      max17042_override_por(map, MAX17042_CONFIG, config->config);
++      max17042_override_por(map, MAX17042_SHDNTIMER, config->shdntimer);
++
++      max17042_override_por(map, MAX17042_DesignCap, config->design_cap);
++      max17042_override_por(map, MAX17042_ICHGTerm, config->ichgt_term);
++
++      max17042_override_por(map, MAX17042_AtRate, config->at_rate);
++      max17042_override_por(map, MAX17042_LearnCFG, config->learn_cfg);
++      max17042_override_por(map, MAX17042_FilterCFG, config->filter_cfg);
++      max17042_override_por(map, MAX17042_RelaxCFG, config->relax_cfg);
++      max17042_override_por(map, MAX17042_MiscCFG, config->misc_cfg);
++      max17042_override_por(map, MAX17042_MaskSOC, config->masksoc);
++
++      max17042_override_por(map, MAX17042_FullCAP, config->fullcap);
++      max17042_override_por(map, MAX17042_FullCAPNom, config->fullcapnom);
+       if (chip->chip_type == MAX17042)
+-              max17042_override_por(client, MAX17042_SOC_empty,
++              max17042_override_por(map, MAX17042_SOC_empty,
+                                               config->socempty);
+-      max17042_override_por(client, MAX17042_LAvg_empty, config->lavg_empty);
+-      max17042_override_por(client, MAX17042_dQacc, config->dqacc);
+-      max17042_override_por(client, MAX17042_dPacc, config->dpacc);
++      max17042_override_por(map, MAX17042_LAvg_empty, config->lavg_empty);
++      max17042_override_por(map, MAX17042_dQacc, config->dqacc);
++      max17042_override_por(map, MAX17042_dPacc, config->dpacc);
+       if (chip->chip_type == MAX17042)
+-              max17042_override_por(client, MAX17042_V_empty, config->vempty);
++              max17042_override_por(map, MAX17042_V_empty, config->vempty);
+       else
+-              max17042_override_por(client, MAX17047_V_empty, config->vempty);
+-      max17042_override_por(client, MAX17042_TempNom, config->temp_nom);
+-      max17042_override_por(client, MAX17042_TempLim, config->temp_lim);
+-      max17042_override_por(client, MAX17042_FCTC, config->fctc);
+-      max17042_override_por(client, MAX17042_RCOMP0, config->rcomp0);
+-      max17042_override_por(client, MAX17042_TempCo, config->tcompc0);
++              max17042_override_por(map, MAX17047_V_empty, config->vempty);
++      max17042_override_por(map, MAX17042_TempNom, config->temp_nom);
++      max17042_override_por(map, MAX17042_TempLim, config->temp_lim);
++      max17042_override_por(map, MAX17042_FCTC, config->fctc);
++      max17042_override_por(map, MAX17042_RCOMP0, config->rcomp0);
++      max17042_override_por(map, MAX17042_TempCo, config->tcompc0);
+       if (chip->chip_type) {
+-              max17042_override_por(client, MAX17042_EmptyTempCo,
+-                                      config->empty_tempco);
+-              max17042_override_por(client, MAX17042_K_empty0,
+-                                      config->kempty0);
++              max17042_override_por(map, MAX17042_EmptyTempCo,
++                                              config->empty_tempco);
++              max17042_override_por(map, MAX17042_K_empty0,
++                                              config->kempty0);
+       }
+ }
+ static int max17042_init_chip(struct max17042_chip *chip)
+ {
++      struct regmap *map = chip->regmap;
+       int ret;
+       int val;
+@@ -598,31 +572,32 @@ static int max17042_init_chip(struct max17042_chip *chip)
+       max17042_load_new_capacity_params(chip);
+       /* Init complete, Clear the POR bit */
+-      val = max17042_read_reg(chip->client, MAX17042_STATUS);
+-      max17042_write_reg(chip->client, MAX17042_STATUS,
+-                      val & (~STATUS_POR_BIT));
++      regmap_read(map, MAX17042_STATUS, &val);
++      regmap_write(map, MAX17042_STATUS, val & (~STATUS_POR_BIT));
+       return 0;
+ }
+ static void max17042_set_soc_threshold(struct max17042_chip *chip, u16 off)
+ {
+-      u16 soc, soc_tr;
++      struct regmap *map = chip->regmap;
++      u32 soc, soc_tr;
+       /* program interrupt thesholds such that we should
+        * get interrupt for every 'off' perc change in the soc
+        */
+-      soc = max17042_read_reg(chip->client, MAX17042_RepSOC) >> 8;
++      regmap_read(map, MAX17042_RepSOC, &soc);
++      soc >>= 8;
+       soc_tr = (soc + off) << 8;
+       soc_tr |= (soc - off);
+-      max17042_write_reg(chip->client, MAX17042_SALRT_Th, soc_tr);
++      regmap_write(map, MAX17042_SALRT_Th, soc_tr);
+ }
+ static irqreturn_t max17042_thread_handler(int id, void *dev)
+ {
+       struct max17042_chip *chip = dev;
+-      u16 val;
++      u32 val;
+-      val = max17042_read_reg(chip->client, MAX17042_STATUS);
++      regmap_read(chip->regmap, MAX17042_STATUS, &val);
+       if ((val & STATUS_INTR_SOCMIN_BIT) ||
+               (val & STATUS_INTR_SOCMAX_BIT)) {
+               dev_info(&chip->client->dev, "SOC threshold INTR\n");
+@@ -681,13 +656,20 @@ max17042_get_pdata(struct device *dev)
+ }
+ #endif
++static struct regmap_config max17042_regmap_config = {
++      .reg_bits = 8,
++      .val_bits = 16,
++      .val_format_endian = REGMAP_ENDIAN_NATIVE,
++};
++
+ static int max17042_probe(struct i2c_client *client,
+                       const struct i2c_device_id *id)
+ {
+       struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+       struct max17042_chip *chip;
+-      int ret;
++      u32 ret;
+       int reg;
++      int i;
+       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA))
+               return -EIO;
+@@ -697,6 +679,12 @@ static int max17042_probe(struct i2c_client *client,
+               return -ENOMEM;
+       chip->client = client;
++      chip->regmap = devm_regmap_init_i2c(client, &max17042_regmap_config);
++      if (IS_ERR(chip->regmap)) {
++              dev_err(&client->dev, "Failed to initialize regmap\n");
++              return -EINVAL;
++      }
++
+       chip->pdata = max17042_get_pdata(&client->dev);
+       if (!chip->pdata) {
+               dev_err(&client->dev, "no platform data provided\n");
+@@ -705,7 +693,7 @@ static int max17042_probe(struct i2c_client *client,
+       i2c_set_clientdata(client, chip);
+-      ret = max17042_read_reg(chip->client, MAX17042_DevName);
++      regmap_read(chip->regmap, MAX17042_DevName, &ret);
+       if (ret == MAX17042_IC_VERSION) {
+               dev_dbg(&client->dev, "chip type max17042 detected\n");
+               chip->chip_type = MAX17042;
+@@ -732,13 +720,15 @@ static int max17042_probe(struct i2c_client *client,
+               chip->pdata->r_sns = MAX17042_DEFAULT_SNS_RESISTOR;
+       if (chip->pdata->init_data)
+-              max17042_set_reg(client, chip->pdata->init_data,
+-                              chip->pdata->num_init_data);
++              for (i = 0; i < chip->pdata->num_init_data; i++)
++                      regmap_write(chip->regmap,
++                                      chip->pdata->init_data[i].addr,
++                                      chip->pdata->init_data[i].data);
+       if (!chip->pdata->enable_current_sense) {
+-              max17042_write_reg(client, MAX17042_CGAIN, 0x0000);
+-              max17042_write_reg(client, MAX17042_MiscCFG, 0x0003);
+-              max17042_write_reg(client, MAX17042_LearnCFG, 0x0007);
++              regmap_write(chip->regmap, MAX17042_CGAIN, 0x0000);
++              regmap_write(chip->regmap, MAX17042_MiscCFG, 0x0003);
++              regmap_write(chip->regmap, MAX17042_LearnCFG, 0x0007);
+       }
+       if (client->irq) {
+@@ -747,9 +737,9 @@ static int max17042_probe(struct i2c_client *client,
+                                               IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+                                               chip->battery.name, chip);
+               if (!ret) {
+-                      reg =  max17042_read_reg(client, MAX17042_CONFIG);
++                      regmap_read(chip->regmap, MAX17042_CONFIG, &reg);
+                       reg |= CONFIG_ALRT_BIT_ENBL;
+-                      max17042_write_reg(client, MAX17042_CONFIG, reg);
++                      regmap_write(chip->regmap, MAX17042_CONFIG, reg);
+                       max17042_set_soc_threshold(chip, 1);
+               } else {
+                       client->irq = 0;
+@@ -758,7 +748,7 @@ static int max17042_probe(struct i2c_client *client,
+               }
+       }
+-      reg = max17042_read_reg(chip->client, MAX17042_STATUS);
++      regmap_read(chip->regmap, MAX17042_STATUS, &reg);
+       if (reg & STATUS_POR_BIT) {
+               ret = max17042_init_worker(chip);
+               if (ret) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0877-M0-charging-Make-to-charge-battery-fully.patch b/patches.tizen/0877-M0-charging-Make-to-charge-battery-fully.patch
new file mode 100644 (file)
index 0000000..3137b44
--- /dev/null
@@ -0,0 +1,41 @@
+From 67845ad20573458bb53fccf7fddca667fa3f704a Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Wed, 16 Oct 2013 19:42:19 +0900
+Subject: [PATCH 0877/1302] M0 : charging : Make to charge battery fully.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/power/charger-manager.c  | 2 +-
+ drivers/power/max77693_charger.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c
+index 2d5867d..5c6fb10 100644
+--- a/drivers/power/charger-manager.c
++++ b/drivers/power/charger-manager.c
+@@ -1521,7 +1521,7 @@ static struct charger_desc cm_drv_data = {
+       .polling_interval_ms    = 30000,
+       .fullbatt_vchkdrop_ms   = 30000,
+       .fullbatt_vchkdrop_uV   = 150000,
+-      .fullbatt_uV            = 4200000,
++      .fullbatt_uV            = 0,
+       .fullbatt_soc           = 100,
+       .fullbatt_full_capacity = 0,
+diff --git a/drivers/power/max77693_charger.c b/drivers/power/max77693_charger.c
+index 87475e5..058046f 100644
+--- a/drivers/power/max77693_charger.c
++++ b/drivers/power/max77693_charger.c
+@@ -338,7 +338,7 @@ static void max77693_charger_reg_init(struct max77693_charger_data *chg_data)
+        * MINVSYS 3.6V(default)
+        */
+       max77693_update_reg(rmap, MAX77693_CHG_REG_CHG_CNFG_04,
+-                      MAX77693_CHG_CV_PRM_4_35V, MAX77693_CHG_MINVSYS_MASK);
++                      MAX77693_CHG_CV_PRM_4_35V, MAX77693_CHG_CV_PRM_MASK);
+       /* VBYPSET 5V */
+       max77693_write_reg(rmap, MAX77693_CHG_REG_CHG_CNFG_11,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0878-charger-manager-Add-cm_chg_add_prorperty-macro.patch b/patches.tizen/0878-charger-manager-Add-cm_chg_add_prorperty-macro.patch
new file mode 100644 (file)
index 0000000..e0c810b
--- /dev/null
@@ -0,0 +1,63 @@
+From 9d8ba6f0fd0d62fbedc3079f32e0998beb32fa6d Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Mon, 21 Oct 2013 18:33:48 +0900
+Subject: [PATCH 0878/1302] charger-manager: Add cm_chg_add_prorperty() macro.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/power/charger-manager.c | 26 ++++++++++----------------
+ 1 file changed, 10 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c
+index 5c6fb10..00ae18c 100644
+--- a/drivers/power/charger-manager.c
++++ b/drivers/power/charger-manager.c
+@@ -925,6 +925,10 @@ static enum power_supply_property default_charger_props[] = {
+        */
+ };
++#define cm_chg_add_property(_property) \
++{ cm->charger_psy.properties[cm->charger_psy.num_properties] = _property;\
++  cm->charger_psy.num_properties++; }
++
+ static struct power_supply psy_default = {
+       .name = "battery",
+       .type = POWER_SUPPLY_TYPE_BATTERY,
+@@ -1725,27 +1729,17 @@ static int charger_manager_probe(struct platform_device *pdev)
+       /* Find which optional psy-properties are available */
+       if (!cm->fuel_gauge->get_property(cm->fuel_gauge,
+-                                        POWER_SUPPLY_PROP_CHARGE_NOW, &val)) {
+-              cm->charger_psy.properties[cm->charger_psy.num_properties] =
+-                              POWER_SUPPLY_PROP_CHARGE_NOW;
+-              cm->charger_psy.num_properties++;
+-      }
++                                        POWER_SUPPLY_PROP_CHARGE_NOW, &val))
++              cm_chg_add_property(POWER_SUPPLY_PROP_CHARGE_NOW);
+       if (!cm->fuel_gauge->get_property(cm->fuel_gauge,
+                                         POWER_SUPPLY_PROP_CURRENT_NOW,
+-                                        &val)) {
+-              cm->charger_psy.properties[cm->charger_psy.num_properties] =
+-                              POWER_SUPPLY_PROP_CURRENT_NOW;
+-              cm->charger_psy.num_properties++;
+-      }
++                                        &val))
++              cm_chg_add_property(POWER_SUPPLY_PROP_CURRENT_NOW);
+       if (desc->measure_battery_temp) {
+-              cm->charger_psy.properties[cm->charger_psy.num_properties] =
+-                              POWER_SUPPLY_PROP_TEMP;
+-              cm->charger_psy.num_properties++;
++              cm_chg_add_property(POWER_SUPPLY_PROP_TEMP);
+       } else {
+-              cm->charger_psy.properties[cm->charger_psy.num_properties] =
+-                              POWER_SUPPLY_PROP_TEMP_AMBIENT;
+-              cm->charger_psy.num_properties++;
++              cm_chg_add_property(POWER_SUPPLY_PROP_TEMP_AMBIENT);
+       }
+       INIT_DELAYED_WORK(&cm->fullbatt_vchk_work, fullbatt_vchk);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0879-charger-manager-Replace-kzalloc-to-devm_kzalloc-and-.patch b/patches.tizen/0879-charger-manager-Replace-kzalloc-to-devm_kzalloc-and-.patch
new file mode 100644 (file)
index 0000000..c3a8b24
--- /dev/null
@@ -0,0 +1,203 @@
+From c1f16cb676c47ccd75109d349b7871a9fad7ff1b Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Mon, 21 Oct 2013 20:03:16 +0900
+Subject: [PATCH 0879/1302] charger-manager : Replace kzalloc to devm_kzalloc
+ and remove uneccessary code.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/power/charger-manager.c | 75 ++++++++++++-----------------------------
+ 1 file changed, 22 insertions(+), 53 deletions(-)
+
+diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c
+index 00ae18c..1e2201f 100644
+--- a/drivers/power/charger-manager.c
++++ b/drivers/power/charger-manager.c
+@@ -1393,7 +1393,8 @@ static int charger_manager_register_sysfs(struct charger_manager *cm)
+               charger = &desc->charger_regulators[i];
+               snprintf(buf, 10, "charger.%d", i);
+-              str = kzalloc(sizeof(char) * (strlen(buf) + 1), GFP_KERNEL);
++              str = devm_kzalloc(cm->dev,
++                              sizeof(char) * (strlen(buf) + 1), GFP_KERNEL);
+               if (!str) {
+                       dev_err(cm->dev, "Cannot allocate memory: %s\n",
+                                       charger->regulator_name);
+@@ -1583,8 +1584,7 @@ static int charger_manager_probe(struct platform_device *pdev)
+                       rtc_dev = NULL;
+                       dev_err(&pdev->dev, "Cannot get RTC %s.\n",
+                               g_desc->rtc_name);
+-                      ret = -ENODEV;
+-                      goto err_alloc;
++                      return -ENODEV;
+               }
+       }
+@@ -1592,25 +1592,18 @@ static int charger_manager_probe(struct platform_device *pdev)
+       if (!desc) {
+               dev_err(&pdev->dev, "No platform data (desc) found.\n");
+-              ret = -ENODEV;
+-              goto err_alloc;
++              return -ENODEV;
+       }
+-      cm = kzalloc(sizeof(struct charger_manager), GFP_KERNEL);
++      cm = devm_kzalloc(&pdev->dev, sizeof(struct charger_manager), GFP_KERNEL);
+       if (!cm) {
+               dev_err(&pdev->dev, "Cannot allocate memory.\n");
+-              ret = -ENOMEM;
+-              goto err_alloc;
++              return -ENOMEM;
+       }
+       /* Basic Values. Unspecified are Null or 0 */
+       cm->dev = &pdev->dev;
+-      cm->desc = kmemdup(desc, sizeof(struct charger_desc), GFP_KERNEL);
+-      if (!cm->desc) {
+-              dev_err(&pdev->dev, "Cannot allocate memory.\n");
+-              ret = -ENOMEM;
+-              goto err_alloc_desc;
+-      }
++      cm->desc = desc;
+       cm->last_temp_mC = INT_MIN; /* denotes "unmeasured, yet" */
+       /*
+@@ -1638,26 +1631,23 @@ static int charger_manager_probe(struct platform_device *pdev)
+       }
+       if (!desc->charger_regulators || desc->num_charger_regulators < 1) {
+-              ret = -EINVAL;
+               dev_err(&pdev->dev, "charger_regulators undefined.\n");
+-              goto err_no_charger;
++              return -EINVAL;
+       }
+       if (!desc->psy_charger_stat || !desc->psy_charger_stat[0]) {
+               dev_err(&pdev->dev, "No power supply defined.\n");
+-              ret = -EINVAL;
+-              goto err_no_charger_stat;
++              return -EINVAL;
+       }
+       /* Counting index only */
+       while (desc->psy_charger_stat[i])
+               i++;
+-      cm->charger_stat = kzalloc(sizeof(struct power_supply *) * (i + 1),
+-                                 GFP_KERNEL);
++      cm->charger_stat = devm_kzalloc(&pdev->dev,
++                      sizeof(struct power_supply *) * (i + 1), GFP_KERNEL);
+       if (!cm->charger_stat) {
+-              ret = -ENOMEM;
+-              goto err_no_charger_stat;
++              return -ENOMEM;
+       }
+       for (i = 0; desc->psy_charger_stat[i]; i++) {
+@@ -1667,8 +1657,7 @@ static int charger_manager_probe(struct platform_device *pdev)
+                       dev_err(&pdev->dev, "Cannot find power supply "
+                                       "\"%s\"\n",
+                                       desc->psy_charger_stat[i]);
+-                      ret = -ENODEV;
+-                      goto err_chg_stat;
++                      return -ENODEV;
+               }
+       }
+@@ -1676,21 +1665,18 @@ static int charger_manager_probe(struct platform_device *pdev)
+       if (!cm->fuel_gauge) {
+               dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n",
+                               desc->psy_fuel_gauge);
+-              ret = -ENODEV;
+-              goto err_chg_stat;
++              return -ENODEV;
+       }
+       if (desc->polling_interval_ms == 0 ||
+           msecs_to_jiffies(desc->polling_interval_ms) <= CM_JIFFIES_SMALL) {
+               dev_err(&pdev->dev, "polling_interval_ms is too small\n");
+-              ret = -EINVAL;
+-              goto err_chg_stat;
++              return -EINVAL;
+       }
+       if (!desc->temperature_out_of_range) {
+               dev_err(&pdev->dev, "there is no temperature_out_of_range\n");
+-              ret = -EINVAL;
+-              goto err_chg_stat;
++              return -EINVAL;
+       }
+       if (!desc->charging_max_duration_ms ||
+@@ -1713,14 +1699,13 @@ static int charger_manager_probe(struct platform_device *pdev)
+       cm->charger_psy.name = cm->psy_name_buf;
+       /* Allocate for psy properties because they may vary */
+-      cm->charger_psy.properties = kzalloc(sizeof(enum power_supply_property)
++      cm->charger_psy.properties = devm_kzalloc(&pdev->dev,
++                              sizeof(enum power_supply_property)
+                               * (ARRAY_SIZE(default_charger_props) +
+-                              NUM_CHARGER_PSY_OPTIONAL),
+-                              GFP_KERNEL);
++                              NUM_CHARGER_PSY_OPTIONAL), GFP_KERNEL);
+       if (!cm->charger_psy.properties) {
+               dev_err(&pdev->dev, "Cannot allocate for psy properties.\n");
+-              ret = -ENOMEM;
+-              goto err_chg_stat;
++              return -ENOMEM;
+       }
+       memcpy(cm->charger_psy.properties, default_charger_props,
+               sizeof(enum power_supply_property) *
+@@ -1748,7 +1733,7 @@ static int charger_manager_probe(struct platform_device *pdev)
+       if (ret) {
+               dev_err(&pdev->dev, "Cannot register charger-manager with"
+                               " name \"%s\".\n", cm->charger_psy.name);
+-              goto err_register;
++              return ret;
+       }
+       /* Register extcon device for charger cable */
+@@ -1789,8 +1774,6 @@ err_reg_sysfs:
+               charger = &desc->charger_regulators[i];
+               sysfs_remove_group(&cm->charger_psy.dev->kobj,
+                               &charger->attr_g);
+-
+-              kfree(charger->attr_g.name);
+       }
+ err_reg_extcon:
+       for (i = 0; i < desc->num_charger_regulators; i++) {
+@@ -1808,16 +1791,7 @@ err_reg_extcon:
+       }
+       power_supply_unregister(&cm->charger_psy);
+-err_register:
+-      kfree(cm->charger_psy.properties);
+-err_chg_stat:
+-      kfree(cm->charger_stat);
+-err_no_charger_stat:
+-err_no_charger:
+-      kfree(cm->desc);
+-err_alloc_desc:
+-      kfree(cm);
+-err_alloc:
++
+       return ret;
+ }
+@@ -1852,11 +1826,6 @@ static int charger_manager_remove(struct platform_device *pdev)
+       try_charger_enable(cm, false);
+-      kfree(cm->charger_psy.properties);
+-      kfree(cm->charger_stat);
+-      kfree(cm->desc);
+-      kfree(cm);
+-
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0880-charger-manager-Add-default-battery-temperature-chec.patch b/patches.tizen/0880-charger-manager-Add-default-battery-temperature-chec.patch
new file mode 100644 (file)
index 0000000..35cddcf
--- /dev/null
@@ -0,0 +1,216 @@
+From fa9d0e309b501e283d424697d9c9b498fb106522 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Tue, 22 Oct 2013 17:35:58 +0900
+Subject: [PATCH 0880/1302] charger-manager : Add default battery temperature
+ checking funtion.
+
+During the charger manager driver's probing time, it can't succeed
+if there's no pre-defined .temperature_out_of_range callback function.
+But if fuel gauge supports battery temperature measurement, we
+can use it directly. That's what cm_default_get_temp() function does.
+
+With flag measure_batter_temp ON, we normally use cm_default_get_temp()
+for .temperature_out_of_range callback funtion.
+The TEMP_AMBIENT property is only used for pre-defined one.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/power/charger-manager.c       | 97 ++++++++++++++++++++++++++++-------
+ include/linux/power/charger-manager.h | 11 +++-
+ 2 files changed, 89 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c
+index 1e2201f..108c00c 100644
+--- a/drivers/power/charger-manager.c
++++ b/drivers/power/charger-manager.c
+@@ -552,7 +552,7 @@ static int check_charging_duration(struct charger_manager *cm)
+ static bool _cm_monitor(struct charger_manager *cm)
+ {
+       struct charger_desc *desc = cm->desc;
+-      int temp = desc->temperature_out_of_range(&cm->last_temp_mC);
++      int temp = desc->temperature_out_of_range(cm);
+       dev_dbg(cm->dev, "monitoring (%2.2d.%3.3dC)\n",
+               cm->last_temp_mC / 1000, cm->last_temp_mC % 1000);
+@@ -804,18 +804,19 @@ static int charger_get_property(struct power_supply *psy,
+                               POWER_SUPPLY_PROP_CURRENT_NOW, val);
+               break;
+       case POWER_SUPPLY_PROP_TEMP:
+-              /* in thenth of centigrade */
++              /* in tenth of centigrade */
+               if (cm->last_temp_mC == INT_MIN)
+-                      desc->temperature_out_of_range(&cm->last_temp_mC);
+-              val->intval = cm->last_temp_mC / 100;
++                      desc->temperature_out_of_range(cm);
++
++              val->intval = cm->last_temp_mC;
+               if (!desc->measure_battery_temp)
+                       ret = -ENODEV;
+               break;
+       case POWER_SUPPLY_PROP_TEMP_AMBIENT:
+-              /* in thenth of centigrade */
++              /* in tenth of centigrade */
+               if (cm->last_temp_mC == INT_MIN)
+-                      desc->temperature_out_of_range(&cm->last_temp_mC);
+-              val->intval = cm->last_temp_mC / 100;
++                      desc->temperature_out_of_range(cm);
++              val->intval = cm->last_temp_mC;
+               if (desc->measure_battery_temp)
+                       ret = -ENODEV;
+               break;
+@@ -1461,16 +1462,75 @@ err:
+       return ret;
+ }
++/* Every temperature units are in milli centigrade */
++#define CM_DEFAULT_TEMP_ALERT_DIFF    10000
++#define CM_DEFAULT_TEMP_ALERT_MAX     127000
++#define CM_DEFAULT_TEMP_ALERT_MIN     (-127000)
++
++static int cm_default_get_temp(struct charger_manager *cm)
++{
++      struct charger_desc *desc = cm->desc;
++      union power_supply_propval val;
++      static int temp_alert_min = 0;
++      static int temp_alert_max = 0;
++      static int temp_alert_diff = 0;
++      static int last_temp_status = 0;
++      int ret;
++
++      if (!temp_alert_min && !temp_alert_max) {
++              /* Initialize minimum temperature for alert */
++              ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
++                                      POWER_SUPPLY_PROP_TEMP_ALERT_MIN,
++                                      &val);
++              temp_alert_min = ret ? desc->temp_alert_min :
++                                      min(desc->temp_alert_min, val.intval);
++              if (!temp_alert_min)
++                      temp_alert_min = CM_DEFAULT_TEMP_ALERT_MIN;
++
++              /* Initialize maximum temperature for alert */
++              ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
++                                      POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
++                                      &val);
++              temp_alert_max = ret ? desc->temp_alert_max :
++                                      min(desc->temp_alert_max, val.intval);
++              if (!temp_alert_max)
++                      temp_alert_max = CM_DEFAULT_TEMP_ALERT_MAX;
++
++              temp_alert_diff = desc->temp_alert_diff ?
++                                      : CM_DEFAULT_TEMP_ALERT_DIFF;
++      }
++
++      /* Get battery temperature */
++      ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
++                                      POWER_SUPPLY_PROP_TEMP,
++                                      &val);
++      if (ret) {
++              cm->last_temp_mC = INT_MIN;
++              return 0;
++      }
++
++      cm->last_temp_mC = val.intval;
++
++      if (cm->last_temp_mC > temp_alert_max || (last_temp_status &&
++                      cm->last_temp_mC + temp_alert_diff > temp_alert_max)) {
++              /* OVERHEAT */
++              last_temp_status = 1;
++      } else if (cm->last_temp_mC < temp_alert_min || (last_temp_status &&
++                      cm->last_temp_mC < temp_alert_min + temp_alert_diff)) {
++              /* Too COLD */
++              last_temp_status = -1;
++      } else {
++              last_temp_status = 0;
++      }
++
++      return last_temp_status;
++}
++
+ /*
+  * Charger driver platform data
+  * To do : Should be transferred to DT.
+  */
+-static int thermistor_ck(int *mC)
+-{
+-      return 0;
+-}
+-
+ static char *charger_stats[] = {
+ #if defined(CONFIG_CHARGER_MAX77693)
+       "max77693-charger",
+@@ -1537,7 +1597,6 @@ static struct charger_desc cm_drv_data = {
+       .charger_regulators     = regulators,
+       .num_charger_regulators = ARRAY_SIZE(regulators),
+-      .temperature_out_of_range       = thermistor_ck,
+       .measure_battery_temp   = true,
+       .charging_max_duration_ms       = (6 * 60 * 60 * 1000),  /* 6hr */
+@@ -1674,11 +1733,6 @@ static int charger_manager_probe(struct platform_device *pdev)
+               return -EINVAL;
+       }
+-      if (!desc->temperature_out_of_range) {
+-              dev_err(&pdev->dev, "there is no temperature_out_of_range\n");
+-              return -EINVAL;
+-      }
+-
+       if (!desc->charging_max_duration_ms ||
+                       !desc->discharging_max_duration_ms) {
+               dev_info(&pdev->dev, "Cannot limit charging duration "
+@@ -1723,7 +1777,14 @@ static int charger_manager_probe(struct platform_device *pdev)
+       if (desc->measure_battery_temp) {
+               cm_chg_add_property(POWER_SUPPLY_PROP_TEMP);
++              desc->temperature_out_of_range = cm_default_get_temp;
+       } else {
++              if (!desc->temperature_out_of_range) {
++                      dev_err(&pdev->dev,
++                              "%s : No battery thermometer exists\n",
++                              __func__);
++                      return -EINVAL;
++              }
+               cm_chg_add_property(POWER_SUPPLY_PROP_TEMP_AMBIENT);
+       }
+diff --git a/include/linux/power/charger-manager.h b/include/linux/power/charger-manager.h
+index 0e86840..2088619 100644
+--- a/include/linux/power/charger-manager.h
++++ b/include/linux/power/charger-manager.h
+@@ -148,6 +148,8 @@ struct charger_regulator {
+       struct charger_manager *cm;
+ };
++struct charger_manager;
++
+ /**
+  * struct charger_desc
+  * @psy_name: the name of power-supply-class for charger manager
+@@ -173,6 +175,9 @@ struct charger_regulator {
+  * @num_charger_regulator: the number of entries in charger_regulators
+  * @charger_regulators: array of charger regulators
+  * @psy_fuel_gauge: the name of power-supply for fuel gauge
++ * @temp_alert_min : Minimum battery temperature to be allowed.
++ * @temp_alert_max : Maximum battery temperature to be allowed.
++ * @temp_alert_diff : Temperature diffential to restart charging. 
+  * @temperature_out_of_range:
+  *    Determine whether the status is overheat or cold or normal.
+  *    return_value > 0: overheat
+@@ -210,7 +215,11 @@ struct charger_desc {
+       char *psy_fuel_gauge;
+-      int (*temperature_out_of_range)(int *mC);
++      int temp_alert_min;
++      int temp_alert_max;
++      int temp_alert_diff;
++
++      int (*temperature_out_of_range)(struct charger_manager *);
+       bool measure_battery_temp;
+       u64 charging_max_duration_ms;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0881-battery-max17042-7-Fix-temperature-unit-to-milli-cen.patch b/patches.tizen/0881-battery-max17042-7-Fix-temperature-unit-to-milli-cen.patch
new file mode 100644 (file)
index 0000000..ac8dc75
--- /dev/null
@@ -0,0 +1,31 @@
+From ef9901701897e69f864e8a04000eeb89d8a21708 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Tue, 22 Oct 2013 16:55:52 +0900
+Subject: [PATCH 0881/1302] battery: max17042/7: Fix temperature unit to milli
+ centigrade.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/power/max17042_battery.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/power/max17042_battery.c b/drivers/power/max17042_battery.c
+index 88e161d..8023a5d 100644
+--- a/drivers/power/max17042_battery.c
++++ b/drivers/power/max17042_battery.c
+@@ -195,9 +195,9 @@ static int max17042_get_property(struct power_supply *psy,
+                       val->intval = (0x7fff & ~val->intval) + 1;
+                       val->intval *= -1;
+               }
+-              /* The value is converted into deci-centigrade scale */
++              /* The value is converted into milli-centigrade scale */
+               /* Units of LSB = 1 / 256 degree Celsius */
+-              val->intval = val->intval * 10 / 256;
++              val->intval = val->intval * 1000 / 256;
+               break;
+       case POWER_SUPPLY_PROP_CURRENT_NOW:
+               if (chip->pdata->enable_current_sense) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0882-drivers-s3c-hsotg-add-proper-suspend-resume-support.patch b/patches.tizen/0882-drivers-s3c-hsotg-add-proper-suspend-resume-support.patch
new file mode 100644 (file)
index 0000000..f93cafd
--- /dev/null
@@ -0,0 +1,77 @@
+From 0731988585aff6355bad682f32bc3f4ecca08c84 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Tue, 22 Oct 2013 14:42:14 +0200
+Subject: [PATCH 0882/1302] drivers: s3c-hsotg: add proper suspend/resume
+ support
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/s3c-hsotg.c | 51 ++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 47 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
+index 25008c0..55c6f92 100644
+--- a/drivers/usb/gadget/s3c-hsotg.c
++++ b/drivers/usb/gadget/s3c-hsotg.c
+@@ -3677,10 +3677,53 @@ static int s3c_hsotg_remove(struct platform_device *pdev)
+       return 0;
+ }
+-#if 1
+-#define s3c_hsotg_suspend NULL
+-#define s3c_hsotg_resume NULL
+-#endif
++static int s3c_hsotg_suspend(struct platform_device *pdev, pm_message_t state)
++{
++      struct s3c_hsotg *hsotg = platform_get_drvdata(pdev);
++      unsigned long flags;
++      int ret = 0;
++
++      if (hsotg->driver)
++              dev_info(hsotg->dev, "suspending usb gadget %s\n", hsotg->driver->driver.name);
++
++      spin_lock_irqsave(&hsotg->lock, flags);
++      s3c_hsotg_disconnect(hsotg);
++      s3c_hsotg_phy_disable(hsotg);
++      hsotg->gadget.speed = USB_SPEED_UNKNOWN;
++      spin_unlock_irqrestore(&hsotg->lock, flags);
++
++      if (hsotg->driver) {
++              int ep;
++              for (ep = 0; ep < hsotg->num_of_eps; ep++)
++                      s3c_hsotg_ep_disable(&hsotg->eps[ep].ep);
++
++              ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
++      }
++
++      return ret;
++}
++
++static int s3c_hsotg_resume(struct platform_device *pdev)
++{
++      struct s3c_hsotg *hsotg = platform_get_drvdata(pdev);
++      unsigned long flags;
++      int ret = 0;
++
++      if (hsotg->driver)
++              dev_info(hsotg->dev, "resuming usb gadget %s\n", hsotg->driver->driver.name);
++
++      spin_lock_irqsave(&hsotg->lock, flags);
++      hsotg->last_rst = jiffies;
++      s3c_hsotg_phy_enable(hsotg);
++      s3c_hsotg_core_init(hsotg);
++      spin_unlock_irqrestore(&hsotg->lock, flags);
++
++      if (hsotg->driver)
++              ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
++                                    hsotg->supplies);
++
++      return ret;
++}
+ static const struct of_device_id s3c_hsotg_of_ids[] = {
+       { .compatible = "samsung,s3c-hsotg", },
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0883-charger-manager-Parse-charger_desc-from-device-tree.patch b/patches.tizen/0883-charger-manager-Parse-charger_desc-from-device-tree.patch
new file mode 100644 (file)
index 0000000..b6a27ab
--- /dev/null
@@ -0,0 +1,382 @@
+From d09aa8d0d059d9595c1464276f85f2b77f5ad91a Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Tue, 22 Oct 2013 16:53:55 +0900
+Subject: [PATCH 0883/1302] charger-manager: Parse charger_desc from device
+ tree.
+
+With this patch, charger-manager can support device tree fully.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts |  61 ++++++++-
+ drivers/power/charger-manager.c         | 211 +++++++++++++++++++-------------
+ include/linux/power/charger-manager.h   |  10 +-
+ 3 files changed, 188 insertions(+), 94 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index e3c42e1..af9f366 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -1274,10 +1274,69 @@
+               pinctrl-1 = <&modem_state_active>;
+       };
+-      charger {
++      charger-manager@0 {
+               compatible = "charger-manager";
+               status = "okay";
+               vinchg1-supply = <&charger_reg>;
++
++              cm-name = "battery";
++              cm-poll-mode = <2>;
++              cm-poll-interval = <30000>;
++
++              cm-fullbatt-vchkdrop-ms = <30000>;
++              cm-fullbatt-vchkdrop-volt = <150000>;
++              cm-fullbatt-soc = <100>;
++
++              cm-battery-stat = <3>;
++
++              cm-battery-cold = <5000>;
++              cm-battery-cold-in-minus;
++              cm-battery-hot = <65000>;
++              cm-battery-temp-diff = <15000>;
++
++              cm-num-chargers = <1>;
++              cm-chargers = "max77693-charger";
++
++              cm-fuel-gauge = "max170xx_battery";
++              cm-battery-has-therm;
++
++              cm-charging-max = <21600000>;
++              cm-discharging-max = <540000>;
++
++              regulator@0 {
++                      cm-regulator-name = "vinchg1";
++                      cable@0 {
++                              cm-cable-name = "USB";
++                              cm-cable-extcon = "max77693-muic";
++                              cm-cable-min = <475000>;
++                              cm-cable-max = <500000>;
++                      };
++                      cable@1 {
++                              cm-cable-name = "TA";
++                              cm-cable-extcon = "max77693-muic";
++                              cm-cable-min = <650000>;
++                              cm-cable-max = <675000>;
++                      };
++                      cable@2 {
++                              cm-cable-name = "Slow-charger";
++                              cm-cable-extcon = "max77693-muic";
++                              cm-cable-min = <650000>;
++                              cm-cable-max = <675000>;
++                      };
++                      cable@3 {
++                              cm-cable-name = "Fast-charger";
++                              cm-cable-extcon = "max77693-muic";
++                              cm-cable-min = <650000>;
++                              cm-cable-max = <675000>;
++                      };
++                      cable@4 {
++                              cm-cable-name = "MHL";
++                              cm-cable-extcon = "max77693-muic";
++                              cm-cable-min = <475000>;
++                              cm-cable-max = <500000>;
++                      };
++              };
++
+       };
+       fixed-regulators {
+diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c
+index 108c00c..6974691 100644
+--- a/drivers/power/charger-manager.c
++++ b/drivers/power/charger-manager.c
+@@ -520,7 +520,7 @@ static int check_charging_duration(struct charger_manager *cm)
+               duration = curr - cm->charging_start_time;
+               if (duration > desc->charging_max_duration_ms) {
+-                      dev_info(cm->dev, "Charging duration exceed %lldms",
++                      dev_info(cm->dev, "Charging duration exceed %ums",
+                                desc->charging_max_duration_ms);
+                       uevent_notify(cm, "Discharging");
+                       try_charger_enable(cm, false);
+@@ -531,7 +531,7 @@ static int check_charging_duration(struct charger_manager *cm)
+               if (duration > desc->charging_max_duration_ms &&
+                               is_ext_pwr_online(cm)) {
+-                      dev_info(cm->dev, "DisCharging duration exceed %lldms",
++                      dev_info(cm->dev, "DisCharging duration exceed %ums",
+                                desc->discharging_max_duration_ms);
+                       uevent_notify(cm, "Recharing");
+                       try_charger_enable(cm, true);
+@@ -1526,105 +1526,140 @@ static int cm_default_get_temp(struct charger_manager *cm)
+       return last_temp_status;
+ }
+-/*
+- * Charger driver platform data
+- * To do : Should be transferred to DT.
+- */
+-
+-static char *charger_stats[] = {
+-#if defined(CONFIG_CHARGER_MAX77693)
+-      "max77693-charger",
+-#endif
+-      NULL,
+-};
+-
+-#define BATT_CHARGING_SOURCE_TA               2
+-#define BATT_CHARGING_SOURCE_USB      3
+-#define BATT_CHARGING_SOURCE_SLOW_TA  4
+-#define BATT_CHARGING_SOURCE_FAST_TA  5
+-#define BATT_CHARGING_SOURCE_MHL_TA   6
+-
+-struct charger_cable charger_cable_vinchg1[] = {
+-      {
+-              .extcon_name    = "max77693-muic",
+-              .name           = "USB",
+-              .min_uA         = 475000,
+-              .max_uA         = 475000 + 25000,
+-      }, {
+-              .extcon_name    = "max77693-muic",
+-              .name           = "TA",
+-              .min_uA         = 650000,
+-              .max_uA         = 650000 + 25000,
+-      }, {
+-              .extcon_name    = "max77693-muic",
+-              .name           = "Slow-charger",
+-              .min_uA         = 650000,
+-              .max_uA         = 650000 + 25000,
+-      }, {
+-              .extcon_name    = "max77693-muic",
+-              .name           = "Fast-charger",
+-              .min_uA         = 650000,
+-              .max_uA         = 650000 + 25000,
+-      }, {
+-              .extcon_name    = "max77693-muic",
+-              .name           = "MHL",
+-              .min_uA         = 475000,
+-              .max_uA         = 475000 + 25000,
+-      },
+-};
+-static struct charger_regulator regulators[] = {
+-      {
+-              .regulator_name = "vinchg1",
+-              .cables         = charger_cable_vinchg1,
+-              .num_cables     = ARRAY_SIZE(charger_cable_vinchg1),
+-      },
+-};
+-
+-static struct charger_desc cm_drv_data = {
+-      .psy_name               = "battery",
+-      .polling_mode           = CM_POLL_EXTERNAL_POWER_ONLY,
+-      .polling_interval_ms    = 30000,
+-      .fullbatt_vchkdrop_ms   = 30000,
+-      .fullbatt_vchkdrop_uV   = 150000,
+-      .fullbatt_uV            = 0,
+-      .fullbatt_soc           = 100,
+-      .fullbatt_full_capacity = 0,
+-
+-      .battery_present        = CM_CHARGER_STAT,
+-      .psy_charger_stat       = charger_stats,
+-      .num_charger_regulators = 1,
+-      .psy_fuel_gauge         = "max170xx_battery",
+-      .charger_regulators     = regulators,
+-      .num_charger_regulators = ARRAY_SIZE(regulators),
+-
+-      .measure_battery_temp   = true,
+-
+-      .charging_max_duration_ms       = (6 * 60 * 60 * 1000),  /* 6hr */
+-      .discharging_max_duration_ms    = (1.5 * 60 * 60 * 1000),/* 1.5hr */
+-};
+-
+ #ifdef CONFIG_OF
+ static struct of_device_id charger_manager_match[] = {
+       {
+               .compatible = "charger-manager",
+-              .data   = (void *)&cm_drv_data,
+       },
+       {},
+ };
++
++struct charger_desc *of_cm_parse_desc(struct device *dev)
++{
++      struct charger_desc *desc;
++      struct device_node *np = dev->of_node;
++      u32 poll_mode = CM_POLL_DISABLE;
++      u32 battery_stat = CM_NO_BATTERY;
++      int num_chgs;
++
++      desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
++      if (!desc)
++              return ERR_PTR(-ENOMEM);
++
++      of_property_read_string(np, "cm-name", &desc->psy_name);
++
++      of_property_read_u32(np, "cm-poll-mode", &poll_mode);
++      desc->polling_mode = poll_mode;
++
++      of_property_read_u32(np, "cm-poll-interval",
++                              &desc->polling_interval_ms);
++
++      of_property_read_u32(np, "cm-fullbatt-vchkdrop-ms",
++                                      &desc->fullbatt_vchkdrop_ms);
++      of_property_read_u32(np, "cm-fullbatt-vchkdrop-volt",
++                                      &desc->fullbatt_vchkdrop_uV);
++      of_property_read_u32(np, "cm-fullbatt-voltage", &desc->fullbatt_uV);
++      of_property_read_u32(np, "cm-fullbatt-soc", &desc->fullbatt_soc);
++      of_property_read_u32(np, "cm-fullbatt-capacity",
++                                      &desc->fullbatt_full_capacity);
++
++      of_property_read_u32(np, "cm-battery-stat", &battery_stat);
++      desc->battery_present = battery_stat;
++
++      of_property_read_u32(np, "cm-battery-cold", &desc->temp_alert_min);
++      if (of_get_property(np, "cm-battery-cold-in-minus", NULL))
++              desc->temp_alert_min *= -1;
++      of_property_read_u32(np, "cm-battery-hot", &desc->temp_alert_max);
++      of_property_read_u32(np, "cm-battery-temp-diff",
++                                      &desc->temp_alert_diff);
++
++      /* chargers */
++      of_property_read_u32(np, "cm-num-chargers", &num_chgs);
++      if (num_chgs) {
++              /* Allocate empty bin at the tail of array */
++              desc->psy_charger_stat = devm_kzalloc(dev, sizeof(char *)
++                                              * (num_chgs + 1), GFP_KERNEL);
++              if (desc->psy_charger_stat) {
++                      int i;
++                      for (i = 0; i < num_chgs; i++)
++                              of_property_read_string_index(np, "cm-chargers",
++                                              i, &desc->psy_charger_stat[i]);
++              } else {
++                      return ERR_PTR(-ENOMEM);
++              }
++      }
++
++      of_property_read_string(np, "cm-fuel-gauge", &desc->psy_fuel_gauge);
++      if (of_get_property(np, "cm-battery-has-therm", NULL))
++              desc->measure_battery_temp = true;
++
++      of_property_read_u32(np, "cm-charging-max",
++                              &desc->charging_max_duration_ms);
++      of_property_read_u32(np, "cm-discharging-max",
++                              &desc->discharging_max_duration_ms);
++
++      /* battery charger regualtors */
++      desc->num_charger_regulators = of_get_child_count(np);
++      if (desc->num_charger_regulators) {
++              struct charger_regulator *chg_regs;
++              struct device_node *child;
++
++              chg_regs = devm_kzalloc(dev, sizeof(*chg_regs)
++                                      * desc->num_charger_regulators,
++                                      GFP_KERNEL);
++              if (!chg_regs)
++                      return ERR_PTR(-ENOMEM);
++
++              desc->charger_regulators = chg_regs;
++
++              for_each_child_of_node(np, child) {
++                      struct charger_cable *cables;
++                      struct device_node *_child;
++
++                      of_property_read_string(child, "cm-regulator-name",
++                                      &chg_regs->regulator_name);
++
++                      /* charger cables */
++                      chg_regs->num_cables = of_get_child_count(child);
++                      if (chg_regs->num_cables) {
++                              cables = devm_kzalloc(dev, sizeof(*cables)
++                                              * chg_regs->num_cables,
++                                              GFP_KERNEL);
++                              if (!cables)
++                                      return ERR_PTR(-ENOMEM);
++
++                              chg_regs->cables = cables;
++
++                              for_each_child_of_node(child, _child) {
++                                      of_property_read_string(_child,
++                                      "cm-cable-name", &cables->name);
++                                      of_property_read_string(_child,
++                                      "cm-cable-extcon",
++                                      &cables->extcon_name);
++                                      of_property_read_u32(_child,
++                                      "cm-cable-min",
++                                      &cables->min_uA);
++                                      of_property_read_u32(_child,
++                                      "cm-cable-max",
++                                      &cables->max_uA);
++                                      cables++;
++                              }
++                      }
++                      chg_regs++;
++              }
++      }
++      return desc;
++}
++#else
++#define charger_manager_match NULL
+ #endif
+ static inline struct charger_desc *cm_get_drv_data(
+                               struct platform_device *pdev)
+ {
+ #ifdef CONFIG_OF
+-      if (pdev->dev.of_node) {
+-              const struct of_device_id *match;
+-              match = of_match_node(charger_manager_match,
+-                                      pdev->dev.of_node);
+-              if (!match)
+-                      return NULL;
+-              return (struct charger_desc *)match->data;
+-      }
++      if (pdev->dev.of_node)
++              return of_cm_parse_desc(&pdev->dev);
+ #endif
+       return (struct charger_desc *)dev_get_platdata(&pdev->dev);
+ }
+diff --git a/include/linux/power/charger-manager.h b/include/linux/power/charger-manager.h
+index 2088619..0f6f574 100644
+--- a/include/linux/power/charger-manager.h
++++ b/include/linux/power/charger-manager.h
+@@ -195,7 +195,7 @@ struct charger_manager;
+  *    max_duration_ms', cm start charging.
+  */
+ struct charger_desc {
+-      char *psy_name;
++      const char *psy_name;
+       enum polling_modes polling_mode;
+       unsigned int polling_interval_ms;
+@@ -208,12 +208,12 @@ struct charger_desc {
+       enum data_source battery_present;
+-      char **psy_charger_stat;
++      const char **psy_charger_stat;
+       int num_charger_regulators;
+       struct charger_regulator *charger_regulators;
+-      char *psy_fuel_gauge;
++      const char *psy_fuel_gauge;
+       int temp_alert_min;
+       int temp_alert_max;
+@@ -222,8 +222,8 @@ struct charger_desc {
+       int (*temperature_out_of_range)(struct charger_manager *);
+       bool measure_battery_temp;
+-      u64 charging_max_duration_ms;
+-      u64 discharging_max_duration_ms;
++      u32 charging_max_duration_ms;
++      u32 discharging_max_duration_ms;
+ };
+ #define PSY_NAME_MAX  30
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0884-drm-exynos-add-support-ARGB8888-for-ipp-fimc.patch b/patches.tizen/0884-drm-exynos-add-support-ARGB8888-for-ipp-fimc.patch
new file mode 100644 (file)
index 0000000..27c3752
--- /dev/null
@@ -0,0 +1,58 @@
+From 3e5e2891fa0480ddf72f51c77e43ed5f99ae9bcb Mon Sep 17 00:00:00 2001
+From: Seung-Woo Kim <sw0312.kim@samsung.com>
+Date: Fri, 4 Oct 2013 15:45:37 +0900
+Subject: [PATCH 0884/1302] drm/exynos: add support ARGB8888 for ipp fimc
+
+Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_fimc.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+index ee8c821..4ba1988 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+@@ -428,6 +428,7 @@ static int fimc_src_set_fmt_order(struct fimc_context *ctx, u32 fmt)
+               return 0;
+       case DRM_FORMAT_RGB888:
+       case DRM_FORMAT_XRGB8888:
++      case DRM_FORMAT_ARGB8888:
+               cfg |= EXYNOS_CISCCTRL_INRGB_FMT_RGB888;
+               fimc_write(ctx, cfg, EXYNOS_CISCCTRL);
+               return 0;
+@@ -497,6 +498,7 @@ static int fimc_src_set_fmt(struct device *dev, u32 fmt)
+       case DRM_FORMAT_RGB565:
+       case DRM_FORMAT_RGB888:
+       case DRM_FORMAT_XRGB8888:
++      case DRM_FORMAT_ARGB8888:
+               cfg |= EXYNOS_MSCTRL_INFORMAT_RGB;
+               break;
+       case DRM_FORMAT_YUV444:
+@@ -775,6 +777,7 @@ static int fimc_dst_set_fmt_order(struct fimc_context *ctx, u32 fmt)
+               fimc_write(ctx, cfg, EXYNOS_CISCCTRL);
+               return 0;
+       case DRM_FORMAT_XRGB8888:
++      case DRM_FORMAT_ARGB8888:
+               cfg |= (EXYNOS_CISCCTRL_OUTRGB_FMT_RGB888 |
+                       EXYNOS_CISCCTRL_EXTRGB_EXTENSION);
+               fimc_write(ctx, cfg, EXYNOS_CISCCTRL);
+@@ -792,6 +795,7 @@ static int fimc_dst_set_fmt_order(struct fimc_context *ctx, u32 fmt)
+       switch (fmt) {
+       case DRM_FORMAT_XRGB8888:
++      case DRM_FORMAT_ARGB8888:
+               cfg |= EXYNOS_CIOCTRL_ALPHA_OUT;
+               break;
+       case DRM_FORMAT_YUYV:
+@@ -856,6 +860,7 @@ static int fimc_dst_set_fmt(struct device *dev, u32 fmt)
+               case DRM_FORMAT_RGB565:
+               case DRM_FORMAT_RGB888:
+               case DRM_FORMAT_XRGB8888:
++              case DRM_FORMAT_ARGB8888:
+                       cfg |= EXYNOS_CITRGFMT_OUTFORMAT_RGB;
+                       break;
+               case DRM_FORMAT_YUYV:
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0885-drm-exynos-fix-to-calculate-offset-of-each-plane-for.patch b/patches.tizen/0885-drm-exynos-fix-to-calculate-offset-of-each-plane-for.patch
new file mode 100644 (file)
index 0000000..5c7dfb9
--- /dev/null
@@ -0,0 +1,245 @@
+From b8165558c27fd6cd4e7a34fda63d1eb7ab8c83e0 Mon Sep 17 00:00:00 2001
+From: Seung-Woo Kim <sw0312.kim@samsung.com>
+Date: Tue, 22 Oct 2013 16:44:13 +0900
+Subject: [PATCH 0885/1302] drm/exynos: fix to calculate offset of each plane
+ for ipp fimc
+
+NV12 and YUV420 formats are need to calculate offset of each plane
+for ipp fimc in a gem buffer. Without proper offset, only Y plane
+can be processed, so result shows green frame.
+This patch fixes to calculate offset for cbcr planes for NV12 and
+YUV420 formats.
+
+Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_fimc.c | 124 +++++++++++++++++++++++++++++++
+ drivers/gpu/drm/exynos/exynos_drm_ipp.c  |  14 +++-
+ drivers/gpu/drm/exynos/exynos_drm_ipp.h  |   2 +
+ 3 files changed, 138 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+index 4ba1988..2959c2e 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+@@ -409,6 +409,115 @@ static void fimc_handle_lastend(struct fimc_context *ctx, bool enable)
+       fimc_write(ctx, cfg, EXYNOS_CIOCTRL);
+ }
++static int fimc_set_planar_addr(struct drm_exynos_ipp_buf_info *buf_info,
++                              u32 fmt, struct drm_exynos_sz *sz)
++{
++      dma_addr_t *base[EXYNOS_DRM_PLANAR_MAX];
++      uint64_t size[EXYNOS_DRM_PLANAR_MAX];
++      uint64_t ofs[EXYNOS_DRM_PLANAR_MAX];
++      bool bypass = false;
++      uint64_t tsize = 0;
++      int i;
++
++      for_each_ipp_planar(i) {
++              base[i] = &buf_info->base[i];
++              size[i] = buf_info->size[i];
++              ofs[i] = 0;
++              tsize += size[i];
++      }
++
++      if (!tsize) {
++              DRM_INFO("%s:failed to get buffer size.\n", __func__);
++              return 0;
++      }
++
++      switch (fmt) {
++      case DRM_FORMAT_NV12:
++      case DRM_FORMAT_NV21:
++      case DRM_FORMAT_NV16:
++      case DRM_FORMAT_NV61:
++              ofs[0] = sz->hsize * sz->vsize;
++              ofs[1] = ofs[0] >> 1;
++              if (*base[0] && *base[1]) {
++                      if (size[0] + size[1] < ofs[0] + ofs[1])
++                              goto err_info;
++                      bypass = true;
++              }
++              break;
++      case DRM_FORMAT_NV12MT:
++              ofs[0] = ALIGN(ALIGN(sz->hsize, 128) *
++                             ALIGN(sz->vsize, 32), SZ_8K);
++              ofs[1] = ALIGN(ALIGN(sz->hsize, 128) *
++                             ALIGN(sz->vsize >> 1, 32), SZ_8K);
++              if (*base[0] && *base[1]) {
++                      if (size[0] + size[1] >= ofs[0] + ofs[1])
++                              bypass = true;
++                      else  {
++                              ofs[0] = ALIGN(sz->hsize * sz->vsize,
++                                              PAGE_SIZE);
++                              ofs[1] = ALIGN(ofs[0] >> 1, PAGE_SIZE);
++                              if (size[0] + size[1] < ofs[0] + ofs[1])
++                                      goto err_info;
++                              bypass = true;
++                      }
++              }
++              break;
++      case DRM_FORMAT_YUV410:
++      case DRM_FORMAT_YVU410:
++      case DRM_FORMAT_YUV411:
++      case DRM_FORMAT_YVU411:
++      case DRM_FORMAT_YUV420:
++      case DRM_FORMAT_YVU420:
++      case DRM_FORMAT_YUV422:
++      case DRM_FORMAT_YVU422:
++      case DRM_FORMAT_YUV444:
++      case DRM_FORMAT_YVU444:
++              ofs[0] = sz->hsize * sz->vsize;
++              ofs[1] = ofs[2] = ofs[0] >> 2;
++              if (*base[0] && *base[1] && *base[2]) {
++                      if (size[0]+size[1]+size[2] < ofs[0]+ofs[1]+ofs[2])
++                              goto err_info;
++                      bypass = true;
++              }
++              break;
++      case DRM_FORMAT_XRGB8888:
++      case DRM_FORMAT_ARGB8888:
++              ofs[0] = sz->hsize * sz->vsize << 2;
++              if (*base[0]) {
++                      if (size[0] < ofs[0])
++                              goto err_info;
++              }
++              bypass = true;
++              break;
++      default:
++              bypass = true;
++              break;
++      }
++
++      if (!bypass) {
++              *base[1] = *base[0] + ofs[0];
++              if (ofs[1] && ofs[2])
++                      *base[2] = *base[1] + ofs[1];
++      }
++
++      DRM_DEBUG_KMS("%s:y[0x%x],cb[0x%x],cr[0x%x]\n", __func__,
++              *base[0], *base[1], *base[2]);
++
++      return 0;
++
++err_info:
++      DRM_ERROR("invalid size for fmt[0x%x]\n", fmt);
++
++      for_each_ipp_planar(i) {
++              base[i] = &buf_info->base[i];
++              size[i] = buf_info->size[i];
++
++              DRM_ERROR("buf[%d] - base[0x%x] sz[%llu] ofs[%llu]\n",
++                      i, *base[i], size[i], ofs[i]);
++      }
++
++      return -EINVAL;
++}
+ static int fimc_src_set_fmt_order(struct fimc_context *ctx, u32 fmt)
+ {
+@@ -705,6 +814,7 @@ static int fimc_src_set_addr(struct device *dev,
+       struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node;
+       struct drm_exynos_ipp_property *property;
+       struct drm_exynos_ipp_config *config;
++      int ret;
+       if (!c_node) {
+               DRM_ERROR("failed to get c_node.\n");
+@@ -725,6 +835,12 @@ static int fimc_src_set_addr(struct device *dev,
+       switch (buf_type) {
+       case IPP_BUF_ENQUEUE:
+               config = &property->config[EXYNOS_DRM_OPS_SRC];
++              ret = fimc_set_planar_addr(buf_info, config->fmt, &config->sz);
++              if (ret) {
++                      dev_err(dev, "failed to set plane src addr.\n");
++                      return ret;
++              }
++
+               fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_Y],
+                       EXYNOS_CIIYSA(0));
+@@ -1205,6 +1321,7 @@ static int fimc_dst_set_addr(struct device *dev,
+       struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node;
+       struct drm_exynos_ipp_property *property;
+       struct drm_exynos_ipp_config *config;
++      int ret;
+       if (!c_node) {
+               DRM_ERROR("failed to get c_node.\n");
+@@ -1225,6 +1342,11 @@ static int fimc_dst_set_addr(struct device *dev,
+       switch (buf_type) {
+       case IPP_BUF_ENQUEUE:
+               config = &property->config[EXYNOS_DRM_OPS_DST];
++              ret = fimc_set_planar_addr(buf_info, config->fmt, &config->sz);
++              if (ret) {
++                      dev_err(dev, "failed to set plane dst addr.\n");
++                      return ret;
++              }
+               fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_Y],
+                       EXYNOS_CIOYSA(buf_id));
+@@ -1646,6 +1768,8 @@ static void fimc_ippdrv_stop(struct device *dev, enum drm_exynos_ipp_cmd cmd)
+       /* reset sequence */
+       fimc_write(ctx, 0x0, EXYNOS_CIFCNTSEQ);
++      fimc_clear_addr(ctx);
++
+       /* Scaler disable */
+       fimc_clear_bits(ctx, EXYNOS_CISCCTRL, EXYNOS_CISCCTRL_SCALERSTART);
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+index fb3c791..fb2f1bd 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+@@ -687,6 +687,7 @@ static struct drm_exynos_ipp_mem_node
+       struct drm_exynos_ipp_mem_node *m_node;
+       struct drm_exynos_ipp_buf_info buf_info;
+       void *addr;
++      unsigned long size;
+       int i;
+       mutex_lock(&c_node->mem_lock);
+@@ -721,11 +722,20 @@ static struct drm_exynos_ipp_mem_node
+                               goto err_clear;
+                       }
++                      size = exynos_drm_gem_get_size(drm_dev,
++                                              qbuf->handle[i], file);
++                      if (!size) {
++                              DRM_ERROR("failed to get size.\n");
++                              goto err_clear;
++                      }
++
+                       buf_info.handles[i] = qbuf->handle[i];
+                       buf_info.base[i] = *(dma_addr_t *) addr;
+-                      DRM_DEBUG_KMS("%s:i[%d]base[0x%x]hd[0x%x]\n",
++                      buf_info.size[i] = (uint64_t) size;
++                      DRM_DEBUG_KMS("%s:i[%d]base[0x%x]hd[0x%x]sz[%d]\n",
+                               __func__, i, buf_info.base[i],
+-                              (int)buf_info.handles[i]);
++                              (int)buf_info.handles[i],
++                              (int)buf_info.size[i]);
+               }
+       }
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.h b/drivers/gpu/drm/exynos/exynos_drm_ipp.h
+index 4cadbea..9af69b3 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.h
++++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.h
+@@ -85,10 +85,12 @@ struct drm_exynos_ipp_cmd_node {
+  *
+  * @gem_objs: Y, Cb, Cr each gem object.
+  * @base: Y, Cb, Cr each planar address.
++ * @size: Y, Cb, Cr each planar size.
+  */
+ struct drm_exynos_ipp_buf_info {
+       unsigned long   handles[EXYNOS_DRM_PLANAR_MAX];
+       dma_addr_t      base[EXYNOS_DRM_PLANAR_MAX];
++      uint64_t        size[EXYNOS_DRM_PLANAR_MAX];
+ };
+ /*
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0886-ARM-dts-exynos4412-spl_pq-rename-the-fixed-regulator.patch b/patches.tizen/0886-ARM-dts-exynos4412-spl_pq-rename-the-fixed-regulator.patch
new file mode 100644 (file)
index 0000000..bcc6c81
--- /dev/null
@@ -0,0 +1,31 @@
+From 491dd7b23e5b32d8210851c8d5edb3723dcee09d Mon Sep 17 00:00:00 2001
+From: Jaehoon Chung <jh80.chung@samsung.com>
+Date: Thu, 24 Oct 2013 21:40:24 +0900
+Subject: [PATCH 0886/1302] ARM: dts: exynos4412-spl_pq: rename the fixed
+ regulator for eMMC
+
+VMEM_2.8V is already defined for LDO22.
+Fixed regulator need to rename the other.
+
+Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index af9f366..92bea1f 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -251,7 +251,7 @@
+       vemmc_reg: voltage-regulator@0 {
+               compatible = "regulator-fixed";
+-              regulator-name = "VMEM_VDD_2.8V";
++              regulator-name = "MASSMEMORY_EN";
+               regulator-min-microvolt = <2800000>;
+               regulator-max-microvolt = <2800000>;
+               gpio = <&gpk0 2 0>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0887-mmc-dw_mmc-add-the-platdat-for-descriptor-number.patch b/patches.tizen/0887-mmc-dw_mmc-add-the-platdat-for-descriptor-number.patch
new file mode 100644 (file)
index 0000000..ebf920e
--- /dev/null
@@ -0,0 +1,76 @@
+From 222d16846fc95234e1edbd62423ef2f9e9f86f28 Mon Sep 17 00:00:00 2001
+From: Jaehoon Chung <jh80.chung@samsung.com>
+Date: Thu, 24 Oct 2013 22:35:36 +0900
+Subject: [PATCH 0887/1302] mmc: dw_mmc: add the platdat for descriptor number.
+
+This platdata is related with buffer size.
+It's increaed the performance.
+
+Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mmc/host/dw_mmc.c  | 10 ++++++++--
+ include/linux/mmc/dw_mmc.h |  4 ++++
+ 2 files changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
+index c6deb2b..95e6ba8 100644
+--- a/drivers/mmc/host/dw_mmc.c
++++ b/drivers/mmc/host/dw_mmc.c
+@@ -446,7 +446,7 @@ static int dw_mci_idmac_init(struct dw_mci *host)
+       int i;
+       /* Number of descriptors in the ring buffer */
+-      host->ring_size = PAGE_SIZE / sizeof(struct idmac_desc);
++      host->ring_size = host->buf_size / sizeof(struct idmac_desc);
+       /* Forward link the descriptor list */
+       for (i = 0, p = host->sg_cpu; i < host->ring_size - 1; i++, p++)
+@@ -2078,8 +2078,13 @@ static void dw_mci_cleanup_slot(struct dw_mci_slot *slot, unsigned int id)
+ static void dw_mci_init_dma(struct dw_mci *host)
+ {
++      if (host->pdata->desc_num)
++              host->buf_size = host->pdata->desc_num * PAGE_SIZE;
++      else
++              host->buf_size = PAGE_SIZE;
++
+       /* Alloc memory for sg translation */
+-      host->sg_cpu = dmam_alloc_coherent(host->dev, PAGE_SIZE,
++      host->sg_cpu = dmam_alloc_coherent(host->dev, host->buf_size,
+                                         &host->sg_dma, GFP_KERNEL);
+       if (!host->sg_cpu) {
+               dev_err(host->dev, "%s: could not alloc DMA memory\n",
+@@ -2185,6 +2190,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
+                               "value of FIFOTH register as default\n");
+       of_property_read_u32(np, "card-detect-delay", &pdata->detect_delay_ms);
++      of_property_read_u32(np, "desc-num", &pdata->desc_num);
+       if (!of_property_read_u32(np, "clock-frequency", &clock_frequency))
+               pdata->bus_hz = clock_frequency;
+diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
+index 198f0fa..ae031e1 100644
+--- a/include/linux/mmc/dw_mmc.h
++++ b/include/linux/mmc/dw_mmc.h
+@@ -138,6 +138,7 @@ struct dw_mci {
+       dma_addr_t              sg_dma;
+       void                    *sg_cpu;
+       const struct dw_mci_dma_ops     *dma_ops;
++      unsigned int            buf_size;
+ #ifdef CONFIG_MMC_DW_IDMAC
+       unsigned int            ring_size;
+ #else
+@@ -241,6 +242,9 @@ struct dw_mci_board {
+        */
+       unsigned int fifo_depth;
++      /* Numer of descriptor */
++      unsigned int desc_num;
++
+       /* delay in mS before detecting cards after interrupt */
+       u32 detect_delay_ms;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0888-ARM-dts-exynos4412_slp_pq-add-the-desc_num-for-mshc.patch b/patches.tizen/0888-ARM-dts-exynos4412_slp_pq-add-the-desc_num-for-mshc.patch
new file mode 100644 (file)
index 0000000..a772ae1
--- /dev/null
@@ -0,0 +1,29 @@
+From 3579430169fb2dd8d25603da29bd25d999497774 Mon Sep 17 00:00:00 2001
+From: Jaehoon Chung <jh80.chung@samsung.com>
+Date: Thu, 24 Oct 2013 22:36:43 +0900
+Subject: [PATCH 0888/1302] ARM: dts: exynos4412_slp_pq: add the desc_num for
+ mshc
+
+Add the desc_num for mshc. (using 4)
+
+Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 92bea1f..9f98e32 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -264,6 +264,7 @@
+               broken-cd;
+               non-removable;
+               fifo-depth = <0x80>;
++              desc-num = <4>;
+               card-detect-delay = <200>;
+               clocks = <&clock 351>, <&clock 132>;
+               clock-name = "biu", "ciu";
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0889-ARM-atags_to_fdt-Add-support-for-passing-serial-numb.patch b/patches.tizen/0889-ARM-atags_to_fdt-Add-support-for-passing-serial-numb.patch
new file mode 100644 (file)
index 0000000..946f2a2
--- /dev/null
@@ -0,0 +1,32 @@
+From c4769bdb948c2b0b1328d75385c763ed2cbb1d9e Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 26 Sep 2013 19:14:12 +0200
+Subject: [PATCH 0889/1302] ARM: atags_to_fdt: Add support for passing serial
+ number
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/compressed/atags_to_fdt.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/arch/arm/boot/compressed/atags_to_fdt.c b/arch/arm/boot/compressed/atags_to_fdt.c
+index d1153c8..d819985 100644
+--- a/arch/arm/boot/compressed/atags_to_fdt.c
++++ b/arch/arm/boot/compressed/atags_to_fdt.c
+@@ -177,6 +177,12 @@ int atags_to_fdt(void *atag_list, void *fdt, int total_space)
+                                       initrd_start);
+                       setprop_cell(fdt, "/chosen", "linux,initrd-end",
+                                       initrd_start + initrd_size);
++              } else if (atag->hdr.tag == ATAG_SERIAL) {
++                      uint32_t serial[2];
++                      serial[0] = cpu_to_fdt32(atag->u.serialnr.high);
++                      serial[1] = cpu_to_fdt32(atag->u.serialnr.low);
++                      setprop(fdt, "/chosen", "linux,serial-number",
++                                      serial, sizeof(serial));
+               }
+       }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0890-OF-fdt-Add-support-for-parsing-system-serial-number-.patch b/patches.tizen/0890-OF-fdt-Add-support-for-parsing-system-serial-number-.patch
new file mode 100644 (file)
index 0000000..9703b1b
--- /dev/null
@@ -0,0 +1,49 @@
+From b4008aec0ad41a0882088bde9111a95ca07ef4cc Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 26 Sep 2013 19:14:37 +0200
+Subject: [PATCH 0890/1302] OF: fdt: Add support for parsing system serial
+ number from device tree
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/of/fdt.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
+index a829c28..860dddf 100644
+--- a/drivers/of/fdt.c
++++ b/drivers/of/fdt.c
+@@ -19,6 +19,7 @@
+ #include <linux/slab.h>
+ #include <asm/setup.h>  /* for COMMAND_LINE_SIZE */
++#include <asm/system_info.h>
+ #ifdef CONFIG_PPC
+ #include <asm/machdep.h>
+ #endif /* CONFIG_PPC */
+@@ -741,6 +742,7 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
+                                    int depth, void *data)
+ {
+       unsigned long l;
++      __be32 *serial;
+       char *p;
+       pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
+@@ -751,6 +753,13 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
+       early_init_dt_check_for_initrd(node);
++      /* Retrieve serial number */
++      serial = of_get_flat_dt_prop(node, "linux,serial-number", &l);
++      if (serial != NULL && l == 2 * sizeof(u32)) {
++              system_serial_high = be32_to_cpu(serial[0]);
++              system_serial_low = be32_to_cpu(serial[1]);
++      }
++
+       /* Retrieve command line */
+       p = of_get_flat_dt_prop(node, "bootargs", &l);
+       if (p != NULL && l > 0)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0891-drivers-s3c-hsotg-fix-regulator-enable-sequence-in-r.patch b/patches.tizen/0891-drivers-s3c-hsotg-fix-regulator-enable-sequence-in-r.patch
new file mode 100644 (file)
index 0000000..0cf2f3f
--- /dev/null
@@ -0,0 +1,43 @@
+From af278acad4835d0f7c93579d3bda6e9e44454410 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Fri, 25 Oct 2013 11:24:21 +0200
+Subject: [PATCH 0891/1302] drivers: s3c-hsotg: fix regulator enable sequence
+ in resume callback
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/s3c-hsotg.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
+index 55c6f92..333a647 100644
+--- a/drivers/usb/gadget/s3c-hsotg.c
++++ b/drivers/usb/gadget/s3c-hsotg.c
+@@ -3709,8 +3709,11 @@ static int s3c_hsotg_resume(struct platform_device *pdev)
+       unsigned long flags;
+       int ret = 0;
+-      if (hsotg->driver)
++      if (hsotg->driver) {
+               dev_info(hsotg->dev, "resuming usb gadget %s\n", hsotg->driver->driver.name);
++              ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
++                                    hsotg->supplies);
++      }
+       spin_lock_irqsave(&hsotg->lock, flags);
+       hsotg->last_rst = jiffies;
+@@ -3718,10 +3721,6 @@ static int s3c_hsotg_resume(struct platform_device *pdev)
+       s3c_hsotg_core_init(hsotg);
+       spin_unlock_irqrestore(&hsotg->lock, flags);
+-      if (hsotg->driver)
+-              ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
+-                                    hsotg->supplies);
+-
+       return ret;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0892-drivers-s3c-hsotg-fix-incorrect-condition-for-clear_.patch b/patches.tizen/0892-drivers-s3c-hsotg-fix-incorrect-condition-for-clear_.patch
new file mode 100644 (file)
index 0000000..3e16eed
--- /dev/null
@@ -0,0 +1,28 @@
+From 9fbb2443401ff2298e971850b470edd094c7f169 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Tue, 22 Oct 2013 15:03:59 +0200
+Subject: [PATCH 0892/1302] drivers: s3c-hsotg: fix incorrect condition for
+ clear_feature request
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/s3c-hsotg.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
+index 333a647..60c9216 100644
+--- a/drivers/usb/gadget/s3c-hsotg.c
++++ b/drivers/usb/gadget/s3c-hsotg.c
+@@ -1133,7 +1133,7 @@ static int s3c_hsotg_process_req_feature(struct s3c_hsotg *hsotg,
+                        * and the halt was cleared by CLEAR_FEATURE
+                        */
+-                      if (!set || halted) {
++                      if (!set && halted) {
+                               /*
+                                * If we have request in progress,
+                                * then complete it
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0893-drivers-s3c-hsotg-hide-some-not-really-needed-debug-.patch b/patches.tizen/0893-drivers-s3c-hsotg-hide-some-not-really-needed-debug-.patch
new file mode 100644 (file)
index 0000000..dd7d28d
--- /dev/null
@@ -0,0 +1,28 @@
+From ff93e4747f8a292ab14c0a334c3f5ac51fbe9648 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Tue, 22 Oct 2013 15:23:24 +0200
+Subject: [PATCH 0893/1302] drivers: s3c-hsotg: hide some not really needed
+ debug messages
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/s3c-hsotg.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
+index 60c9216..943a9e5 100644
+--- a/drivers/usb/gadget/s3c-hsotg.c
++++ b/drivers/usb/gadget/s3c-hsotg.c
+@@ -2689,7 +2689,7 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep)
+       u32 epctrl_reg;
+       u32 ctrl;
+-      dev_info(hsotg->dev, "%s(ep %p)\n", __func__, ep);
++      dev_dbg(hsotg->dev, "%s(ep %p)\n", __func__, ep);
+       if (ep == &hsotg->eps[0].ep) {
+               dev_err(hsotg->dev, "%s: called for ep0\n", __func__);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0894-mmc-core-change-the-clkgate_delay-value-from-0-to-3.patch b/patches.tizen/0894-mmc-core-change-the-clkgate_delay-value-from-0-to-3.patch
new file mode 100644 (file)
index 0000000..9659ca9
--- /dev/null
@@ -0,0 +1,35 @@
+From 8a6ca3ceb1434dcf2a7d2d78597361709ef284d2 Mon Sep 17 00:00:00 2001
+From: Jaehoon Chung <jh80.chung@samsung.com>
+Date: Mon, 28 Oct 2013 15:13:22 +0900
+Subject: [PATCH 0894/1302] mmc: core: change the clkgate_delay value from 0 to
+ 3.
+
+When clkgate_delay is set to 0, then clk is gated at every request.
+It's inefficient. So, it's changed from 0 to 3.
+
+Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mmc/core/host.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
+index 2a3593d..7886431 100644
+--- a/drivers/mmc/core/host.c
++++ b/drivers/mmc/core/host.c
+@@ -242,10 +242,10 @@ static inline void mmc_host_clk_init(struct mmc_host *host)
+       /* Hold MCI clock for 8 cycles by default */
+       host->clk_delay = 8;
+       /*
+-       * Default clock gating delay is 0ms to avoid wasting power.
++       * Default clock gating delay is 3ms to avoid wasting power.
+        * This value can be tuned by writing into sysfs entry.
+        */
+-      host->clkgate_delay = 0;
++      host->clkgate_delay = 3;
+       host->clk_gated = false;
+       INIT_DELAYED_WORK(&host->clk_gate_work, mmc_host_clk_gate_work);
+       spin_lock_init(&host->clk_lock);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0895-exynos-drm_fimd-support-lcdblk-system-register-contr.patch b/patches.tizen/0895-exynos-drm_fimd-support-lcdblk-system-register-contr.patch
new file mode 100644 (file)
index 0000000..6382c0e
--- /dev/null
@@ -0,0 +1,108 @@
+From 77cf733457abe33c3184e7780fd4468c97725b73 Mon Sep 17 00:00:00 2001
+From: Donghwa Lee <dh09.lee@samsung.com>
+Date: Tue, 29 Oct 2013 16:40:20 +0900
+Subject: [PATCH 0895/1302] exynos: drm_fimd: support lcdblk system register
+ control
+
+Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi           |  1 +
+ drivers/gpu/drm/exynos/exynos_drm_fimd.c | 24 ++++++++++++++++++++++++
+ 2 files changed, 25 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index d9b14b3..64c93e5 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -599,6 +599,7 @@
+               samsung,power-domain = <&pd_lcd0>;
+               status = "disabled";
+               iommu = <&sysmmu_fimd0>;
++              lcdblk-cfg = <&sys_reg>;
+       };
+       sysmmu_mfc_l: sysmmu@13620000 {
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+index e3cfa07..f2db91f 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+@@ -19,6 +19,8 @@
+ #include <linux/of.h>
+ #include <linux/of_device.h>
+ #include <linux/pm_runtime.h>
++#include <linux/mfd/syscon.h>
++#include <linux/regmap.h>
+ #include <video/of_display_timing.h>
+ #include <video/samsung_fimd.h>
+@@ -64,6 +66,8 @@
+ struct fimd_driver_data {
+       unsigned int timing_base;
++      unsigned int lcdblk_reg;
++      unsigned int lcdblk_fimdbypass;
+       unsigned int has_shadowcon:1;
+       unsigned int has_clksel:1;
+@@ -78,11 +82,15 @@ static struct fimd_driver_data s3c64xx_fimd_driver_data = {
+ static struct fimd_driver_data exynos4_fimd_driver_data = {
+       .timing_base = 0x0,
++      .lcdblk_reg = 0x210,
++      .lcdblk_fimdbypass = 1,
+       .has_shadowcon = 1,
+ };
+ static struct fimd_driver_data exynos5_fimd_driver_data = {
+       .timing_base = 0x20000,
++      .lcdblk_reg = 0x210,
++      .lcdblk_fimdbypass = 15,
+       .has_shadowcon = 1,
+ };
+@@ -109,6 +117,7 @@ struct fimd_context {
+       struct clk                      *bus_clk;
+       struct clk                      *lcd_clk;
+       void __iomem                    *regs;
++      struct regmap                   *sysreg;
+       struct fimd_win_data            win_data[WINDOWS_NR];
+       unsigned int                    clkdiv;
+       unsigned int                    default_win;
+@@ -227,11 +236,21 @@ static void fimd_commit(struct device *dev)
+       struct fb_videomode *timing = &panel->timing;
+       struct fimd_driver_data *driver_data;
+       u32 val;
++      int ret;
+       driver_data = ctx->driver_data;
+       if (ctx->suspended)
+               return;
++      /* enable FIMDBYPASS bit of LCDBLK0 */
++      ret = regmap_update_bits(ctx->sysreg, driver_data->lcdblk_reg,
++                      0x1 << driver_data->lcdblk_fimdbypass,
++                      0x1 << driver_data->lcdblk_fimdbypass);
++      if (ret < 0) {
++              DRM_ERROR("failed to update sysreg.\n");
++              return;
++      }
++
+       /* setup polarity values from machine code. */
+       writel(ctx->vidcon1, ctx->regs + driver_data->timing_base + VIDCON1);
+@@ -1021,6 +1040,11 @@ static int fimd_probe(struct platform_device *pdev)
+               return ret;
+       }
++      ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
++                      "lcdblk-cfg");
++      if (IS_ERR(ctx->sysreg))
++              return PTR_ERR(ctx->sysreg);
++
+       ctx->driver_data = drm_fimd_get_driver_data(pdev);
+       ctx->vidcon0 = pdata->vidcon0;
+       ctx->vidcon1 = pdata->vidcon1;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0896-exynos-drm_fimd-remove-duplicated-clock-control-for-.patch b/patches.tizen/0896-exynos-drm_fimd-remove-duplicated-clock-control-for-.patch
new file mode 100644 (file)
index 0000000..d32f710
--- /dev/null
@@ -0,0 +1,57 @@
+From 56a5eef6800074f5673e7efe4693d43a2b45113a Mon Sep 17 00:00:00 2001
+From: Donghwa Lee <dh09.lee@samsung.com>
+Date: Tue, 29 Oct 2013 16:46:33 +0900
+Subject: [PATCH 0896/1302] exynos: drm_fimd: remove duplicated clock control
+ for fimd_dpms
+
+Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_drm_fimd.c | 17 +++--------------
+ 1 file changed, 3 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+index f2db91f..7d6f3cd 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+@@ -895,7 +895,6 @@ static int fimd_activate(struct fimd_context *ctx, bool enable)
+ static void fimd_dpms(struct device *subdrv_dev, int mode)
+ {
+       struct fimd_context *ctx = get_fimd_context(subdrv_dev);
+-      int ret;
+       DRM_DEBUG_KMS("%d\n", mode);
+@@ -909,26 +908,16 @@ static void fimd_dpms(struct device *subdrv_dev, int mode)
+                * P.S. fimd_dpms function would be called at booting time so
+                * clk_enable could be called double time.
+                */
+-              if (ctx->suspended) {
++              if (ctx->suspended)
+                       pm_runtime_get_sync(subdrv_dev);
+-                      ret = fimd_activate(ctx, true);
+-                      if (ret < 0) {
+-                              DRM_ERROR("failed to activate.\n");
+-                              pm_runtime_put_sync(subdrv_dev);
+-                      }
+-              }
+               break;
+       case DRM_MODE_DPMS_STANDBY:
+       case DRM_MODE_DPMS_SUSPEND:
+       case DRM_MODE_DPMS_OFF:
+-              if (!ctx->suspended) {
+-                      ret = fimd_activate(ctx, false);
+-                      if (ret < 0)
+-                              DRM_ERROR("failed to deactivate.\n");
+-
++              if (!ctx->suspended)
+                       pm_runtime_put_sync(subdrv_dev);
+-              }
++
+               break;
+       default:
+               DRM_DEBUG_KMS("unspecified mode %d\n", mode);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0897-display-panels-remove-duplicated-display_entity_set_.patch b/patches.tizen/0897-display-panels-remove-duplicated-display_entity_set_.patch
new file mode 100644 (file)
index 0000000..c675523
--- /dev/null
@@ -0,0 +1,108 @@
+From 2762d9bbe149213ecf6fc07a0dbe464ee38a1c6e Mon Sep 17 00:00:00 2001
+From: Donghwa Lee <dh09.lee@samsung.com>
+Date: Wed, 30 Oct 2013 15:46:07 +0900
+Subject: [PATCH 0897/1302] display: panels: remove duplicated
+ display_entity_set_state() for pm
+
+remove duplicated display_entity_set_state() in suspend/resume function
+
+Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/video/display/panel-l5f31188.c | 16 ++--------------
+ drivers/video/display/panel-s6d6aa1.c  | 14 ++------------
+ drivers/video/display/panel-s6e8aa0.c  | 14 ++------------
+ 3 files changed, 6 insertions(+), 38 deletions(-)
+
+diff --git a/drivers/video/display/panel-l5f31188.c b/drivers/video/display/panel-l5f31188.c
+index 4330a68..d95bd23 100644
+--- a/drivers/video/display/panel-l5f31188.c
++++ b/drivers/video/display/panel-l5f31188.c
+@@ -632,24 +632,12 @@ static int l5f31188_remove(struct platform_device *pdev)
+ static int l5f31188_suspend(struct device *dev)
+ {
+-      struct l5f31188 *panel = dev_get_drvdata(dev);
+-
+-      if (panel->power != FB_BLANK_UNBLANK)
+-              return 0;
+-
+-      return display_entity_set_state(&panel->entity,
+-                      DISPLAY_ENTITY_STATE_OFF);
++      return 0;
+ }
+ static int l5f31188_resume(struct device *dev)
+ {
+-      struct l5f31188 *panel = dev_get_drvdata(dev);
+-
+-      if (panel->power != FB_BLANK_UNBLANK)
+-              return 0;
+-
+-      return display_entity_set_state(&panel->entity,
+-                      DISPLAY_ENTITY_STATE_ON);
++      return 0;
+ }
+ static const struct dev_pm_ops l5f31188_pm_ops = {
+diff --git a/drivers/video/display/panel-s6d6aa1.c b/drivers/video/display/panel-s6d6aa1.c
+index dd5285d..9d0e7c8 100644
+--- a/drivers/video/display/panel-s6d6aa1.c
++++ b/drivers/video/display/panel-s6d6aa1.c
+@@ -787,22 +787,12 @@ static int s6d6aa1_remove(struct platform_device *dev)
+ static int s6d6aa1_suspend(struct device *dev)
+ {
+-      struct s6d6aa1 *lcd = dev_get_drvdata(dev);
+-
+-      if (lcd->power != FB_BLANK_UNBLANK)
+-              return 0;
+-
+-      return display_entity_set_state(&lcd->entity, DISPLAY_ENTITY_STATE_OFF);
++      return 0;
+ }
+ static int s6d6aa1_resume(struct device *dev)
+ {
+-      struct s6d6aa1 *lcd = dev_get_drvdata(dev);
+-
+-      if (lcd->power != FB_BLANK_UNBLANK)
+-              return 0;
+-
+-      return display_entity_set_state(&lcd->entity, DISPLAY_ENTITY_STATE_ON);
++      return 0;
+ }
+ static struct dev_pm_ops s6d6aa1_pm_ops = {
+diff --git a/drivers/video/display/panel-s6e8aa0.c b/drivers/video/display/panel-s6e8aa0.c
+index 30ed901..66c08f6 100644
+--- a/drivers/video/display/panel-s6e8aa0.c
++++ b/drivers/video/display/panel-s6e8aa0.c
+@@ -1390,22 +1390,12 @@ static int s6e8aa0_remove(struct platform_device *pdev)
+ static int s6e8aa0_suspend(struct device *dev)
+ {
+-      struct s6e8aa0 *lcd = dev_get_drvdata(dev);
+-
+-      if (lcd->power != FB_BLANK_UNBLANK)
+-              return 0;
+-
+-      return display_entity_set_state(&lcd->entity, DISPLAY_ENTITY_STATE_OFF);
++      return 0;
+ }
+ static int s6e8aa0_resume(struct device *dev)
+ {
+-      struct s6e8aa0 *lcd = dev_get_drvdata(dev);
+-
+-      if (lcd->power != FB_BLANK_UNBLANK)
+-              return 0;
+-
+-      return display_entity_set_state(&lcd->entity, DISPLAY_ENTITY_STATE_ON);
++      return 0;
+ }
+ static struct dev_pm_ops s6e8aa0_pm_ops = {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0898-Revert-battery-max17042-7-Fix-temperature-unit-to-mi.patch b/patches.tizen/0898-Revert-battery-max17042-7-Fix-temperature-unit-to-mi.patch
new file mode 100644 (file)
index 0000000..04857b9
--- /dev/null
@@ -0,0 +1,32 @@
+From bf9d49f8812bbb14f81d1f7da300022e955ff65b Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Thu, 31 Oct 2013 11:20:27 +0900
+Subject: [PATCH 0898/1302] Revert "battery: max17042/7: Fix temperature unit
+ to milli centigrade."
+
+This reverts commit 79b1d3591b35022b93f2d70c299e74eb54bfec09.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/power/max17042_battery.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/power/max17042_battery.c b/drivers/power/max17042_battery.c
+index 8023a5d..88e161d 100644
+--- a/drivers/power/max17042_battery.c
++++ b/drivers/power/max17042_battery.c
+@@ -195,9 +195,9 @@ static int max17042_get_property(struct power_supply *psy,
+                       val->intval = (0x7fff & ~val->intval) + 1;
+                       val->intval *= -1;
+               }
+-              /* The value is converted into milli-centigrade scale */
++              /* The value is converted into deci-centigrade scale */
+               /* Units of LSB = 1 / 256 degree Celsius */
+-              val->intval = val->intval * 1000 / 256;
++              val->intval = val->intval * 10 / 256;
+               break;
+       case POWER_SUPPLY_PROP_CURRENT_NOW:
+               if (chip->pdata->enable_current_sense) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0899-charger-manager-Fix-unit-of-temperature-to-deci-cent.patch b/patches.tizen/0899-charger-manager-Fix-unit-of-temperature-to-deci-cent.patch
new file mode 100644 (file)
index 0000000..ce40146
--- /dev/null
@@ -0,0 +1,55 @@
+From 46c022ed818ef55a04a0bed68c2c4b0153ce43eb Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Thu, 31 Oct 2013 11:20:56 +0900
+Subject: [PATCH 0899/1302] charger-manager: Fix unit of temperature to deci
+ centigrade.
+
+Fix temperature unit to follow the standard as document describes.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 6 +++---
+ drivers/power/charger-manager.c         | 8 ++++----
+ 2 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 9f98e32..86c6e5f 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -1290,10 +1290,10 @@
+               cm-battery-stat = <3>;
+-              cm-battery-cold = <5000>;
++              cm-battery-cold = <50>;
+               cm-battery-cold-in-minus;
+-              cm-battery-hot = <65000>;
+-              cm-battery-temp-diff = <15000>;
++              cm-battery-hot = <650>;
++              cm-battery-temp-diff = <150>;
+               cm-num-chargers = <1>;
+               cm-chargers = "max77693-charger";
+diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c
+index 6974691..373281f 100644
+--- a/drivers/power/charger-manager.c
++++ b/drivers/power/charger-manager.c
+@@ -1462,10 +1462,10 @@ err:
+       return ret;
+ }
+-/* Every temperature units are in milli centigrade */
+-#define CM_DEFAULT_TEMP_ALERT_DIFF    10000
+-#define CM_DEFAULT_TEMP_ALERT_MAX     127000
+-#define CM_DEFAULT_TEMP_ALERT_MIN     (-127000)
++/* Every temperature units are in decii centigrade */
++#define CM_DEFAULT_TEMP_ALERT_DIFF    100
++#define CM_DEFAULT_TEMP_ALERT_MAX     1270
++#define CM_DEFAULT_TEMP_ALERT_MIN     (-1270)
+ static int cm_default_get_temp(struct charger_manager *cm)
+ {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0900-ADC-EXYNOS4412-Update-DT-and-board-configuration-to-.patch b/patches.tizen/0900-ADC-EXYNOS4412-Update-DT-and-board-configuration-to-.patch
new file mode 100644 (file)
index 0000000..d5eb12c
--- /dev/null
@@ -0,0 +1,52 @@
+From 47475fd3944d7ad8fc23679f097ef3f171bdd807 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Fri, 1 Nov 2013 00:25:47 +0900
+Subject: [PATCH 0900/1302] ADC: EXYNOS4412: Update DT and board configuration
+ to enable ADC.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 12 ++++++++++++
+ arch/arm/configs/tizen_defconfig        |  2 +-
+ 2 files changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 86c6e5f..5c3bedd 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -1385,6 +1385,18 @@
+               status = "okay";
+               #phy-cells = <1>;
+       };
++
++      adc: adc@126C0000 {
++              compatible = "samsung,exynos-adc-v1";
++              reg = <0x126C0000 0x20>, <0x10020718 0x4>;
++              interrupt-parent = <&combiner>;
++              interrupts = <10 3>;
++              #io-channel-cells = <1>;
++              clocks = <&clock 326>;
++              clock-names = "adc";
++              vdd-supply = <&ldo3_reg>;
++              status = "ok";
++      };
+ };
+ &pinctrl_1 {
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index 1940a58..184e67c 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -2873,7 +2873,7 @@ CONFIG_IIO_ST_ACCEL_SPI_3AXIS=y
+ # CONFIG_AD7793 is not set
+ # CONFIG_AD7476 is not set
+ # CONFIG_AD7887 is not set
+-# CONFIG_EXYNOS_ADC is not set
++CONFIG_EXYNOS_ADC=y
+ # CONFIG_MAX1363 is not set
+ # CONFIG_TI_ADC081C is not set
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0901-ntc_thermistor-Update-DT-and-board-configuration-to-.patch b/patches.tizen/0901-ntc_thermistor-Update-DT-and-board-configuration-to-.patch
new file mode 100644 (file)
index 0000000..e7a0b43
--- /dev/null
@@ -0,0 +1,58 @@
+From ca05947d4d6e0b81d3b1aa1009b4fdda45b10549 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Fri, 1 Nov 2013 00:34:32 +0900
+Subject: [PATCH 0901/1302] ntc_thermistor: Update DT and board configuration
+ to enable NTC thermistors.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-m0.dts | 18 ++++++++++++++++++
+ arch/arm/configs/tizen_defconfig    |  4 +++-
+ 2 files changed, 21 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-m0.dts b/arch/arm/boot/dts/exynos4412-m0.dts
+index 30e34b4..4ec07fc 100644
+--- a/arch/arm/boot/dts/exynos4412-m0.dts
++++ b/arch/arm/boot/dts/exynos4412-m0.dts
+@@ -215,4 +215,22 @@
+                       };
+               };
+       };
++
++      thermistor-ap@0 {
++              compatible = "ntc,ncp03wb473";
++              status = "ok";
++              pullup-uv = <1800000>;
++              pullup-ohm = <100000>;
++              pulldown-ohm = <100000> ;
++              io-channels = <&adc 1>;
++      };
++
++      thermistor-batt@0 {
++              compatible = "ntc,ncp03wb473";
++              status = "ok";
++              pullup-uv = <1800000>;
++              pullup-ohm = <100000>;
++              pulldown-ohm = <100000> ;
++              io-channels = <&adc 2>;
++      };
+ };
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index 184e67c..16598c6 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -1739,7 +1739,9 @@ CONFIG_CHARGER_MAX77693=y
+ # CONFIG_POWER_RESET is not set
+ # CONFIG_POWER_RESET_RESTART is not set
+ # CONFIG_POWER_AVS is not set
+-# CONFIG_HWMON is not set
++CONFIG_HWMON=y
++
++CONFIG_SENSORS_NTC_THERMISTOR=y
+ # CONFIG_THERMAL is not set
+ CONFIG_WATCHDOG=y
+ CONFIG_WATCHDOG_CORE=y
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0902-regulator-max77686-Correct-GPIOs-for-BUCK2-DVS-setti.patch b/patches.tizen/0902-regulator-max77686-Correct-GPIOs-for-BUCK2-DVS-setti.patch
new file mode 100644 (file)
index 0000000..89c3f8c
--- /dev/null
@@ -0,0 +1,52 @@
+From 1da8b9f83d70850381e95fe2a09f1a3ecf2d5890 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Thu, 31 Oct 2013 16:52:55 +0100
+Subject: [PATCH 0902/1302] regulator:max77686: Correct GPIOs for BUCK2 DVS
+ setting
+
+Before this patch SELB and DVS pins were wrongly defined in the DTS.
+
+As a result MAX77686 always used BUCK2_DVS1 register (the DVS pins were
+set all to 0). However the default DVS index (default_dvs_idx) was set to 1.
+
+Therefore, the default value of BUCK2_DVS1 register (1.1V) was always
+setup. Wrongly the driver was changing BUCK2_DVS2 register. Due to that
+voltage was NOT changed at all.
+
+The problem appeared when BOOST was ported to v3.10-mobile. It requires
+around 1.3V, but default voltage is set to 1.1V (0x28). Too small voltage
+resulted in OOPs at random places.
+
+As a side note:
+The MAX77686 is NOT using DVS with GPIO. It changes the value of current
+voltage with I2C utilization.
+
+Tested at: REDWOOD - Exynos4412 - rev1.
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 5c3bedd..e05f3fa 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -561,11 +561,11 @@
+                       reg = <0x09>;
+                       #clock-cells = <1>;
+-                      max77686,dvs_gpios = <&gpf3 1 0>,
++                      max77686,selb_gpios = <&gpf3 1 0>,
+                                            <&gpf3 2 0>,
+                                            <&gpf3 3 0>;
+-                      max77686,selb_gpios = <&gpm3 0 0>,
++                      max77686,dvs_gpios = <&gpm3 0 0>,
+                                             <&gpm3 1 0>,
+                                             <&gpm3 2 0>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0903-cosmetic-max77686-Remove-unused-variable.patch b/patches.tizen/0903-cosmetic-max77686-Remove-unused-variable.patch
new file mode 100644 (file)
index 0000000..1c36bde
--- /dev/null
@@ -0,0 +1,26 @@
+From 1096d8abd0421ee2c00d18251c5c1631d2d2d701 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Thu, 31 Oct 2013 16:51:54 +0100
+Subject: [PATCH 0903/1302] cosmetic: max77686: Remove unused variable
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/regulator/max77686.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c
+index 4d40e54..a8ddbb2 100644
+--- a/drivers/regulator/max77686.c
++++ b/drivers/regulator/max77686.c
+@@ -650,7 +650,6 @@ static int max77686_pmic_probe(struct platform_device *pdev)
+               unsigned int buck2_dvs = pdata->buck2_voltage[i];
+               unsigned int buck3_dvs = pdata->buck3_voltage[i];
+               unsigned int buck4_dvs = pdata->buck4_voltage[i];
+-              unsigned int reg[3];
+               regmap_write(iodev->regmap, MAX77686_REG_BUCK2DVS1 + i,
+                               buck2_dvs ? : 0x28);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0904-cpufreq-Don-t-create-empty-sys-devices-system-cpu-cp.patch b/patches.tizen/0904-cpufreq-Don-t-create-empty-sys-devices-system-cpu-cp.patch
new file mode 100644 (file)
index 0000000..eba5f2e
--- /dev/null
@@ -0,0 +1,161 @@
+From ea2fe7a1477ba794879a1634c4d2e282bc32a691 Mon Sep 17 00:00:00 2001
+From: Viresh Kumar <viresh.kumar@linaro.org>
+Date: Fri, 17 May 2013 16:09:09 +0530
+Subject: [PATCH 0904/1302] cpufreq: Don't create empty
+ /sys/devices/system/cpu/cpufreq directory
+
+When we don't have any file in cpu/cpufreq directory we shouldn't
+create it. Specially with the introduction of per-policy governor
+instance patchset, even governors are moved to
+cpu/cpu*/cpufreq/governor-name directory and so this directory is
+just not required.
+
+Lets have it only when required.
+
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/acpi-cpufreq.c     |  4 ++--
+ drivers/cpufreq/cpufreq.c          | 48 ++++++++++++++++++++++++++++++++++----
+ drivers/cpufreq/cpufreq_governor.c |  6 +++++
+ include/linux/cpufreq.h            |  4 ++++
+ 4 files changed, 56 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
+index edc089e..2845566 100644
+--- a/drivers/cpufreq/acpi-cpufreq.c
++++ b/drivers/cpufreq/acpi-cpufreq.c
+@@ -947,7 +947,7 @@ static void __init acpi_cpufreq_boost_init(void)
+       /* We create the boost file in any case, though for systems without
+        * hardware support it will be read-only and hardwired to return 0.
+        */
+-      if (sysfs_create_file(cpufreq_global_kobject, &(global_boost.attr)))
++      if (cpufreq_sysfs_create_file(&(global_boost.attr)))
+               pr_warn(PFX "could not register global boost sysfs file\n");
+       else
+               pr_debug("registered global boost sysfs file\n");
+@@ -955,7 +955,7 @@ static void __init acpi_cpufreq_boost_init(void)
+ static void __exit acpi_cpufreq_boost_exit(void)
+ {
+-      sysfs_remove_file(cpufreq_global_kobject, &(global_boost.attr));
++      cpufreq_sysfs_remove_file(&(global_boost.attr));
+       if (msrs) {
+               unregister_cpu_notifier(&boost_nb);
+diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
+index 6485547..09ff1b0 100644
+--- a/drivers/cpufreq/cpufreq.c
++++ b/drivers/cpufreq/cpufreq.c
+@@ -630,9 +630,6 @@ static struct attribute *default_attrs[] = {
+       NULL
+ };
+-struct kobject *cpufreq_global_kobject;
+-EXPORT_SYMBOL(cpufreq_global_kobject);
+-
+ #define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
+ #define to_attr(a) container_of(a, struct freq_attr, attr)
+@@ -703,6 +700,49 @@ static struct kobj_type ktype_cpufreq = {
+       .release        = cpufreq_sysfs_release,
+ };
++struct kobject *cpufreq_global_kobject;
++EXPORT_SYMBOL(cpufreq_global_kobject);
++
++static int cpufreq_global_kobject_usage;
++
++int cpufreq_get_global_kobject(void)
++{
++      if (!cpufreq_global_kobject_usage++)
++              return kobject_add(cpufreq_global_kobject,
++                              &cpu_subsys.dev_root->kobj, "%s", "cpufreq");
++
++      return 0;
++}
++EXPORT_SYMBOL(cpufreq_get_global_kobject);
++
++void cpufreq_put_global_kobject(void)
++{
++      if (!--cpufreq_global_kobject_usage)
++              kobject_del(cpufreq_global_kobject);
++}
++EXPORT_SYMBOL(cpufreq_put_global_kobject);
++
++int cpufreq_sysfs_create_file(const struct attribute *attr)
++{
++      int ret = cpufreq_get_global_kobject();
++
++      if (!ret) {
++              ret = sysfs_create_file(cpufreq_global_kobject, attr);
++              if (ret)
++                      cpufreq_put_global_kobject();
++      }
++
++      return ret;
++}
++EXPORT_SYMBOL(cpufreq_sysfs_create_file);
++
++void cpufreq_sysfs_remove_file(const struct attribute *attr)
++{
++      sysfs_remove_file(cpufreq_global_kobject, attr);
++      cpufreq_put_global_kobject();
++}
++EXPORT_SYMBOL(cpufreq_sysfs_remove_file);
++
+ /* symlink affected CPUs */
+ static int cpufreq_add_dev_symlink(unsigned int cpu,
+                                  struct cpufreq_policy *policy)
+@@ -1975,7 +2015,7 @@ static int __init cpufreq_core_init(void)
+               init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
+       }
+-      cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
++      cpufreq_global_kobject = kobject_create();
+       BUG_ON(!cpufreq_global_kobject);
+       register_syscore_ops(&cpufreq_syscore_ops);
+diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
+index a86ff72..a593bb4 100644
+--- a/drivers/cpufreq/cpufreq_governor.c
++++ b/drivers/cpufreq/cpufreq_governor.c
+@@ -275,6 +275,9 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
+                       return rc;
+               }
++              if (!have_governor_per_policy())
++                      WARN_ON(cpufreq_get_global_kobject());
++
+               rc = sysfs_create_group(get_governor_parent_kobj(policy),
+                               get_sysfs_attr(dbs_data));
+               if (rc) {
+@@ -313,6 +316,9 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
+                       sysfs_remove_group(get_governor_parent_kobj(policy),
+                                       get_sysfs_attr(dbs_data));
++                      if (!have_governor_per_policy())
++                              cpufreq_put_global_kobject();
++
+                       if ((dbs_data->cdata->governor == GOV_CONSERVATIVE) &&
+                               (policy->governor->initialized == 1)) {
+                               struct cs_ops *cs_ops = dbs_data->cdata->gov_ops;
+diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
+index 037d36a..ab1932c 100644
+--- a/include/linux/cpufreq.h
++++ b/include/linux/cpufreq.h
+@@ -71,6 +71,10 @@ struct cpufreq_governor;
+ /* /sys/devices/system/cpu/cpufreq: entry point for global variables */
+ extern struct kobject *cpufreq_global_kobject;
++int cpufreq_get_global_kobject(void);
++void cpufreq_put_global_kobject(void);
++int cpufreq_sysfs_create_file(const struct attribute *attr);
++void cpufreq_sysfs_remove_file(const struct attribute *attr);
+ #define CPUFREQ_ETERNAL                       (-1)
+ struct cpufreq_cpuinfo {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0905-cpufreq-Store-cpufreq-policies-in-a-list.patch b/patches.tizen/0905-cpufreq-Store-cpufreq-policies-in-a-list.patch
new file mode 100644 (file)
index 0000000..8363b47
--- /dev/null
@@ -0,0 +1,69 @@
+From 1017b34988574c883de26d12727c57006984b74b Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Tue, 2 Jul 2013 18:01:10 +0200
+Subject: [PATCH 0905/1302] cpufreq: Store cpufreq policies in a list
+
+Policies available in a cpufreq framework are now linked together. They are
+accessible via cpufreq_policy_list defined at cpufreq core.
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: Myungjoo Ham <myungjoo.ham@samsung.com>
+
+Changes for v6:
+- Move policy list entry delete code to __cpufreq_remove_dev()
+
+Changes for v5:
+- Call list_add() only when device successfully added
+
+Changes for v4:
+- New patch
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/cpufreq.c | 3 +++
+ include/linux/cpufreq.h   | 1 +
+ 2 files changed, 4 insertions(+)
+
+diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
+index 09ff1b0..2493537 100644
+--- a/drivers/cpufreq/cpufreq.c
++++ b/drivers/cpufreq/cpufreq.c
+@@ -46,6 +46,7 @@ static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
+ static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
+ #endif
+ static DEFINE_RWLOCK(cpufreq_driver_lock);
++static LIST_HEAD(cpufreq_policy_list);
+ /*
+  * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure
+@@ -993,6 +994,7 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
+       if (ret)
+               goto err_out_unregister;
++      list_add(&policy->policy_list, &cpufreq_policy_list);
+       kobject_uevent(&policy->kobj, KOBJ_ADD);
+       module_put(cpufreq_driver->owner);
+       pr_debug("initialization complete\n");
+@@ -1137,6 +1139,7 @@ static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif
+               if (cpufreq_driver->exit)
+                       cpufreq_driver->exit(data);
++              list_del(&data->policy_list);
+               free_cpumask_var(data->related_cpus);
+               free_cpumask_var(data->cpus);
+               kfree(data);
+diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
+index ab1932c..5348981 100644
+--- a/include/linux/cpufreq.h
++++ b/include/linux/cpufreq.h
+@@ -117,6 +117,7 @@ struct cpufreq_policy {
+       struct cpufreq_real_policy      user_policy;
++      struct list_head        policy_list;
+       struct kobject          kobj;
+       struct completion       kobj_unregister;
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0906-cpufreq-Add-boost-frequency-support-in-core.patch b/patches.tizen/0906-cpufreq-Add-boost-frequency-support-in-core.patch
new file mode 100644 (file)
index 0000000..789cba6
--- /dev/null
@@ -0,0 +1,371 @@
+From 8da3147f53decf5f0bfdcb4760358d6678f3d7b5 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Fri, 19 Jul 2013 13:33:13 +0200
+Subject: [PATCH 0906/1302] cpufreq: Add boost frequency support in core
+
+This commit adds boost frequency support in cpufreq core (Hardware &
+Software).
+Some SoC (like Exynos4 - e.g. 4x12) allow setting frequency above
+its normal operation limits. Such a mode shall be only used for a short
+time.
+
+Overclocking (boost) support is essentially provided by platform
+dependent cpufreq driver.
+
+This commit unifies support for SW and HW (Intel) overclocking solutions
+in the core cpufreq driver. Previously the "boost" sysfs attribute was
+defined at acpi driver code.
+By default boost is disabled. One global attribute is available at:
+/sys/devices/system/cpu/cpufreq/boost.
+
+It only shows up when cpufreq driver supports overclocking.
+Under the hood frequencies dedicated for boosting are marked with a
+special flag (CPUFREQ_BOOST_FREQ) at driver's frequency table.
+It is the user's concern to enable/disable overclocking with proper call to
+sysfs.
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: Myungjoo Ham <myungjoo.ham@samsung.com>
+
+Changes for v6:
+- Remove sysfs boost attribute when subsys_iterface_unregister() fails
+- Move global boost_enabled variable from cpufreq.c to platform dependent
+  struct cpufreq_driver
+- pr_err() message is also printed when boost disable fails
+
+Changes for v5:
+- Rename cpufreq_boost_trigger_state_sw() to cpufreq_boost_enable_sw()
+- Extent cpufreq_register_driver() to check if cpufreq driver provided
+  boost_enable callback. If not provided, then use cpufreq_boost_enable_sw()
+- Use single call to cpufreq_driver->enable_boost() with cpufreq driver
+  provided callback or default SW boost enable routine
+- Move pr_debug call to store_boost() from cpufreq_boost_trigger_state()
+- Change the user_policy.max value when SW boost is toggled. It is necessary
+  for proper operation of e.g. thermal subsystem.
+- Add check if cpufreq_driver pointer is not NULL at
+  cpufreq_boost_supported() routine
+- Add EXPORT_SYMBOL_GPL for cpufreq_boost_supported() and
+  cpufreq_boost_enabled()
+- Remove extra check for cpufreq_boost_supported() at
+  cpufreq_freq_table_cpuinfo()
+- Explanation of show boost logic at show_available_freqs()
+- Add cpufreq_set_boost_enabled() method to set initial value of boost_enabled
+  global flag
+
+Changes for v4:
+- Remove boost parameter from cpufreq_frequency_table_cpuinfo() function
+- Introduce cpufreq_boost_supported() method
+- Use of cpufreq_boost_supported() and cpufreq_boost_enabled() to decide
+  if frequency shall be skipped
+- Rename set_boost_freq() to enable_boost()
+- cpufreq_attr_available_freq() moved to freq_table.c
+- Use policy list to get access to cpufreq policies
+- Rename global boost flag (cpufreq_boost_enabled -> boost_enabled)
+- pr_err corrected ( %sable)
+- Remove sanity check at cpufreq_boost_trigger_state() entrance [to test if
+  boost is supported]
+- Use either HW (boost_enable) callback or SW managed boost
+- Introduce new cpufreq_boost_trigger_state_sw() method to handle boost
+  at SW.
+- Protect boost_enabled manipulation with lock.
+
+Changes for v3:
+- Method for reading boost status
+- Removal of cpufreq_frequency_table_max()
+- Extent cpufreq_frequency_table_cpuinfo() to support boost parameter
+- boost_supported flag added to cpufreq_driver struct
+- "boost" sysfs attribute control flag removed
+- One global flag describing state of the boost defined at cpufreq core
+- Rename cpufreq_driver's low_level_boost field to set_boost_freq()
+- Usage of cpufreq_sysfs_{remove|add}_file() routines
+
+Changes for v2:
+- Removal of cpufreq_boost structure and move its fields to cpufreq_driver
+  structure
+- Flag to indicate if global boost attribute is already defined
+- Extent the pr_{err|debbug} functions to show current function names
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/cpufreq.c    | 110 ++++++++++++++++++++++++++++++++++++++++++-
+ drivers/cpufreq/freq_table.c |  47 +++++++++++++++---
+ include/linux/cpufreq.h      |  12 +++++
+ 3 files changed, 161 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
+index 2493537..bf81873 100644
+--- a/drivers/cpufreq/cpufreq.c
++++ b/drivers/cpufreq/cpufreq.c
+@@ -316,6 +316,32 @@ EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
+ /*********************************************************************
+  *                          SYSFS INTERFACE                          *
+  *********************************************************************/
++ssize_t show_boost(struct kobject *kobj,
++                               struct attribute *attr, char *buf)
++{
++      return sprintf(buf, "%d\n", cpufreq_driver->boost_enabled);
++}
++
++static ssize_t store_boost(struct kobject *kobj, struct attribute *attr,
++                                const char *buf, size_t count)
++{
++      int ret, enable;
++
++      ret = sscanf(buf, "%d", &enable);
++      if (ret != 1 || enable < 0 || enable > 1)
++              return -EINVAL;
++
++      if (cpufreq_boost_trigger_state(enable)) {
++              pr_err("%s: Cannot enable boost!\n", __func__);
++              return -EINVAL;
++      }
++
++      pr_debug("%s: cpufreq BOOST %s\n", __func__,
++               enable ? "enabled" : "disabled");
++
++      return count;
++}
++define_one_global_rw(boost);
+ static struct cpufreq_governor *__find_governor(const char *str_governor)
+ {
+@@ -1902,6 +1928,66 @@ static struct notifier_block __refdata cpufreq_cpu_notifier = {
+ };
+ /*********************************************************************
++ *               BOOST                                                     *
++ *********************************************************************/
++static int cpufreq_boost_enable_sw(int state)
++{
++      struct cpufreq_frequency_table *freq_table;
++      struct cpufreq_policy *policy;
++      int ret = -EINVAL;
++
++      list_for_each_entry(policy, &cpufreq_policy_list, policy_list) {
++              freq_table = cpufreq_frequency_get_table(policy->cpu);
++              if (freq_table) {
++                      ret = cpufreq_frequency_table_cpuinfo(policy,
++                                                      freq_table);
++                      if (!ret)
++                              policy->user_policy.max = policy->max;
++              }
++      }
++
++      return ret;
++}
++
++int cpufreq_boost_trigger_state(int state)
++{
++      unsigned long flags;
++      int ret = 0;
++
++      if (cpufreq_driver->boost_enabled != state) {
++              write_lock_irqsave(&cpufreq_driver_lock, flags);
++              cpufreq_driver->boost_enabled = state;
++
++              ret = cpufreq_driver->enable_boost(state);
++              if (ret)
++                      cpufreq_driver->boost_enabled = 0;
++
++              write_unlock_irqrestore(&cpufreq_driver_lock, flags);
++
++              if (ret)
++                      pr_err("%s: BOOST cannot %s\n", __func__,
++                             state ? "enabled" : "disabled");
++      }
++
++      return ret;
++}
++
++int cpufreq_boost_supported(void)
++{
++      if (cpufreq_driver)
++              return cpufreq_driver->boost_supported;
++
++      return 0;
++}
++EXPORT_SYMBOL_GPL(cpufreq_boost_supported);
++
++int cpufreq_boost_enabled(void)
++{
++      return cpufreq_driver->boost_enabled;
++}
++EXPORT_SYMBOL_GPL(cpufreq_boost_enabled);
++
++/*********************************************************************
+  *               REGISTER / UNREGISTER CPUFREQ DRIVER                *
+  *********************************************************************/
+@@ -1940,9 +2026,25 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
+       cpufreq_driver = driver_data;
+       write_unlock_irqrestore(&cpufreq_driver_lock, flags);
++      if (cpufreq_driver->boost_supported) {
++              /*
++               * Check if boost driver provides function to enable boost -
++               * if not, use cpufreq_boost_enable_sw as default
++               */
++              if (!cpufreq_driver->enable_boost)
++                      cpufreq_driver->enable_boost = cpufreq_boost_enable_sw;
++
++              ret = cpufreq_sysfs_create_file(&(boost.attr));
++              if (ret) {
++                      pr_err("%s: cannot register global boost sysfs file\n",
++                              __func__);
++                      goto err_null_driver;
++              }
++      }
++
+       ret = subsys_interface_register(&cpufreq_interface);
+       if (ret)
+-              goto err_null_driver;
++              goto err_boost_unreg;
+       if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {
+               int i;
+@@ -1969,6 +2071,9 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
+       return 0;
+ err_if_unreg:
+       subsys_interface_unregister(&cpufreq_interface);
++err_boost_unreg:
++      if (cpufreq_driver->boost_supported)
++              cpufreq_sysfs_remove_file(&(boost.attr));
+ err_null_driver:
+       write_lock_irqsave(&cpufreq_driver_lock, flags);
+       cpufreq_driver = NULL;
+@@ -1996,6 +2101,9 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver)
+       pr_debug("unregistering driver %s\n", driver->name);
+       subsys_interface_unregister(&cpufreq_interface);
++      if (cpufreq_driver->boost_supported)
++              cpufreq_sysfs_remove_file(&(boost.attr));
++
+       unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
+       write_lock_irqsave(&cpufreq_driver_lock, flags);
+diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
+index d7a7966..49022f5 100644
+--- a/drivers/cpufreq/freq_table.c
++++ b/drivers/cpufreq/freq_table.c
+@@ -34,6 +34,10 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
+                       continue;
+               }
++              if (!cpufreq_boost_enabled()
++                  && table[i].index == CPUFREQ_BOOST_FREQ)
++                      continue;
++
+               pr_debug("table entry %u: %u kHz, %u index\n",
+                                       i, freq, table[i].index);
+               if (freq < min_freq)
+@@ -171,7 +175,8 @@ static DEFINE_PER_CPU(struct cpufreq_frequency_table *, cpufreq_show_table);
+ /**
+  * show_available_freqs - show available frequencies for the specified CPU
+  */
+-static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf)
++static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf,
++                                  int show_boost)
+ {
+       unsigned int i = 0;
+       unsigned int cpu = policy->cpu;
+@@ -186,6 +191,14 @@ static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf)
+       for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
+               if (table[i].frequency == CPUFREQ_ENTRY_INVALID)
+                       continue;
++              /*
++               * show_boost = true and index = BOOST freq -> display BOOST
++               * show_boost = false and index = BOOST freq -> continue
++               * and display only non BOOST frequencies
++               */
++              if (show_boost ^ (table[i].index == CPUFREQ_BOOST_FREQ))
++                      continue;
++
+               count += sprintf(&buf[count], "%d ", table[i].frequency);
+       }
+       count += sprintf(&buf[count], "\n");
+@@ -194,14 +207,34 @@ static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf)
+ }
+-struct freq_attr cpufreq_freq_attr_scaling_available_freqs = {
+-      .attr = { .name = "scaling_available_frequencies",
+-                .mode = 0444,
+-              },
+-      .show = show_available_freqs,
+-};
++#define cpufreq_attr_available_freq(_name)      \
++struct freq_attr cpufreq_freq_attr_##_name##_freqs =     \
++__ATTR_RO(_name##_frequencies)
++
++/**
++ * show_scaling_available_frequencies - show available normal frequencies for
++ * the specified CPU
++ */
++static ssize_t scaling_available_frequencies_show(struct cpufreq_policy *policy,
++                                                char *buf)
++{
++      return show_available_freqs(policy, buf, 0);
++}
++cpufreq_attr_available_freq(scaling_available);
+ EXPORT_SYMBOL_GPL(cpufreq_freq_attr_scaling_available_freqs);
++/**
++ * show_available_boost_freqs - show available boost frequencies for
++ * the specified CPU
++ */
++static ssize_t scaling_boost_frequencies_show(struct cpufreq_policy *policy,
++                                            char *buf)
++{
++      return show_available_freqs(policy, buf, 1);
++}
++cpufreq_attr_available_freq(scaling_boost);
++EXPORT_SYMBOL_GPL(cpufreq_freq_attr_scaling_boost_freqs);
++
+ /*
+  * if you use these, you must assure that the frequency table is valid
+  * all the time between get_attr and put_attr!
+diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
+index 5348981..afc6225 100644
+--- a/include/linux/cpufreq.h
++++ b/include/linux/cpufreq.h
+@@ -267,6 +267,11 @@ struct cpufreq_driver {
+       int     (*suspend)      (struct cpufreq_policy *policy);
+       int     (*resume)       (struct cpufreq_policy *policy);
+       struct freq_attr        **attr;
++
++      /* platform specific boost support code */
++      bool                    boost_supported;
++      bool                    boost_enabled;
++      int (*enable_boost)     (int state);
+ };
+ /* flags */
+@@ -408,6 +413,9 @@ extern struct cpufreq_governor cpufreq_gov_conservative;
+ #define CPUFREQ_ENTRY_INVALID ~0
+ #define CPUFREQ_TABLE_END     ~1
++/* Define index for boost frequency */
++#define CPUFREQ_BOOST_FREQ    ~2
++
+ struct cpufreq_frequency_table {
+       unsigned int    index;     /* any */
+       unsigned int    frequency; /* kHz - doesn't need to be in ascending
+@@ -426,11 +434,15 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
+                                  unsigned int relation,
+                                  unsigned int *index);
++int cpufreq_boost_trigger_state(int state);
++int cpufreq_boost_supported(void);
++int cpufreq_boost_enabled(void);
+ /* the following 3 funtions are for cpufreq core use only */
+ struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu);
+ /* the following are really really optional */
+ extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs;
++extern struct freq_attr cpufreq_freq_attr_scaling_boost_freqs;
+ void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table,
+                                     unsigned int cpu);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0907-cpufreq-acpi-x86-Adjust-the-acpi-cpufreq.c-code-to-w.patch b/patches.tizen/0907-cpufreq-acpi-x86-Adjust-the-acpi-cpufreq.c-code-to-w.patch
new file mode 100644 (file)
index 0000000..968779f
--- /dev/null
@@ -0,0 +1,192 @@
+From da62a016d855313fa614bd1c64aceae6d4b9832f Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Wed, 3 Jul 2013 17:36:25 +0200
+Subject: [PATCH 0907/1302] cpufreq:acpi:x86: Adjust the acpi-cpufreq.c code to
+ work with common boost solution
+
+The Intel's hardware based boost solution driver has been changed to cooperate with
+common cpufreq boost framework.
+
+The global sysfs boost attribute entry code (/sys/devices/system/cpu/cpufreq/boost)
+has been moved to a core cpufreq code. This attribute is now only visible,
+when cpufreq driver supports it.
+
+The _store_boost() function has been redesigned to be used as enable_boost
+callback.
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: Myungjoo Ham <myungjoo.ham@samsung.com>
+
+Changes for v6:
+- Use boost_enabled flag defined at acpi_cpufreq_driver to store information
+  about boost state
+- Instead of using cpufreq_set_boost_enabled(), modify the boost_enable in
+  the acpi driver code
+
+Changes for v5:
+- Remove acpi-cpufreq's boost_enabled global flag and reuse one defined at
+  cpufreq core
+
+Changes for v4:
+- add _store_boost to acpi_cpufreq_driver structure
+
+Changes for v3:
+- Bring back boost_enabled as a global flag
+- Move boost_supported to cpufreq_driver structure
+
+Changes for v2:
+- Replace boost_enabled and boost_supported global flags with proper entries
+at struct cpufreq_driver.
+- Removal of struct cpufreq_boost
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/acpi-cpufreq.c | 70 +++++++++++++-----------------------------
+ 1 file changed, 22 insertions(+), 48 deletions(-)
+
+diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
+index 2845566..c93e17e 100644
+--- a/drivers/cpufreq/acpi-cpufreq.c
++++ b/drivers/cpufreq/acpi-cpufreq.c
+@@ -80,7 +80,6 @@ static struct acpi_processor_performance __percpu *acpi_perf_data;
+ static struct cpufreq_driver acpi_cpufreq_driver;
+ static unsigned int acpi_pstate_strict;
+-static bool boost_enabled, boost_supported;
+ static struct msr __percpu *msrs;
+ static bool boost_state(unsigned int cpu)
+@@ -133,59 +132,43 @@ static void boost_set_msrs(bool enable, const struct cpumask *cpumask)
+       wrmsr_on_cpus(cpumask, msr_addr, msrs);
+ }
+-static ssize_t _store_boost(const char *buf, size_t count)
++static int _store_boost(int val)
++{
++      get_online_cpus();
++      boost_set_msrs(val, cpu_online_mask);
++      put_online_cpus();
++      pr_debug("Core Boosting %sabled.\n", val ? "en" : "dis");
++
++      return 0;
++}
++
++static ssize_t store_boost(const char *buf, size_t count)
+ {
+       int ret;
+       unsigned long val = 0;
+-      if (!boost_supported)
++      if (!acpi_cpufreq_driver.boost_supported)
+               return -EINVAL;
+       ret = kstrtoul(buf, 10, &val);
+       if (ret || (val > 1))
+               return -EINVAL;
+-      if ((val && boost_enabled) || (!val && !boost_enabled))
+-              return count;
+-
+-      get_online_cpus();
+-
+-      boost_set_msrs(val, cpu_online_mask);
+-
+-      put_online_cpus();
+-
+-      boost_enabled = val;
+-      pr_debug("Core Boosting %sabled.\n", val ? "en" : "dis");
++      _store_boost((int) val);
+       return count;
+ }
+-static ssize_t store_global_boost(struct kobject *kobj, struct attribute *attr,
+-                                const char *buf, size_t count)
+-{
+-      return _store_boost(buf, count);
+-}
+-
+-static ssize_t show_global_boost(struct kobject *kobj,
+-                               struct attribute *attr, char *buf)
+-{
+-      return sprintf(buf, "%u\n", boost_enabled);
+-}
+-
+-static struct global_attr global_boost = __ATTR(boost, 0644,
+-                                              show_global_boost,
+-                                              store_global_boost);
+-
+ #ifdef CONFIG_X86_ACPI_CPUFREQ_CPB
+ static ssize_t store_cpb(struct cpufreq_policy *policy, const char *buf,
+                        size_t count)
+ {
+-      return _store_boost(buf, count);
++      return store_boost(buf, count);
+ }
+ static ssize_t show_cpb(struct cpufreq_policy *policy, char *buf)
+ {
+-      return sprintf(buf, "%u\n", boost_enabled);
++      return sprintf(buf, "%u\n", acpi_cpufreq_driver.boost_enabled);
+ }
+ static struct freq_attr cpb = __ATTR(cpb, 0644, show_cpb, store_cpb);
+@@ -571,7 +554,7 @@ static int boost_notify(struct notifier_block *nb, unsigned long action,
+       switch (action) {
+       case CPU_UP_PREPARE:
+       case CPU_UP_PREPARE_FROZEN:
+-              boost_set_msrs(boost_enabled, cpumask);
++              boost_set_msrs(acpi_cpufreq_driver.boost_enabled, cpumask);
+               break;
+       case CPU_DOWN_PREPARE:
+@@ -920,6 +903,7 @@ static struct cpufreq_driver acpi_cpufreq_driver = {
+       .name           = "acpi-cpufreq",
+       .owner          = THIS_MODULE,
+       .attr           = acpi_cpufreq_attr,
++      .enable_boost   = _store_boost,
+ };
+ static void __init acpi_cpufreq_boost_init(void)
+@@ -930,33 +914,23 @@ static void __init acpi_cpufreq_boost_init(void)
+               if (!msrs)
+                       return;
+-              boost_supported = true;
+-              boost_enabled = boost_state(0);
++              acpi_cpufreq_driver.boost_enabled = boost_state(0);
++              acpi_cpufreq_driver.boost_supported = true;
+               get_online_cpus();
+               /* Force all MSRs to the same value */
+-              boost_set_msrs(boost_enabled, cpu_online_mask);
++              boost_set_msrs(acpi_cpufreq_driver.boost_enabled,
++                             cpu_online_mask);
+               register_cpu_notifier(&boost_nb);
+               put_online_cpus();
+-      } else
+-              global_boost.attr.mode = 0444;
+-
+-      /* We create the boost file in any case, though for systems without
+-       * hardware support it will be read-only and hardwired to return 0.
+-       */
+-      if (cpufreq_sysfs_create_file(&(global_boost.attr)))
+-              pr_warn(PFX "could not register global boost sysfs file\n");
+-      else
+-              pr_debug("registered global boost sysfs file\n");
++      }
+ }
+ static void __exit acpi_cpufreq_boost_exit(void)
+ {
+-      cpufreq_sysfs_remove_file(&(global_boost.attr));
+-
+       if (msrs) {
+               unregister_cpu_notifier(&boost_nb);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0908-cpufreq-exynos-Extend-Exynos-cpufreq-driver-to-suppo.patch b/patches.tizen/0908-cpufreq-exynos-Extend-Exynos-cpufreq-driver-to-suppo.patch
new file mode 100644 (file)
index 0000000..7b7bc3b
--- /dev/null
@@ -0,0 +1,72 @@
+From 2d7fad82be005f639d82bd4f2c8afc99bc08b335 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Thu, 18 Jul 2013 16:49:53 +0200
+Subject: [PATCH 0908/1302] cpufreq:exynos:Extend Exynos cpufreq driver to
+ support boost framework
+
+The struct cpufreq_driver has been extended to embrace the information
+related to boost support.
+
+When "boost_mode" device tree attribute is defined for a platform, the
+boost_supported flag is set. Moreover boost related attributes were
+exported.
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: Myungjoo Ham <myungjoo.ham@samsung.com>
+
+Changes for v6:
+- replace exynos_driver.boost_supported = 1 to = true
+
+Changes for v5:
+- None
+
+Changes for v4:
+- None
+
+Changes for v3:
+- Remove low level boost code
+- Move boost management code to cpufreq core code
+- Use boost_supported flag to indicate if driver supports over clocking
+
+Changes for v2:
+- Removal of struct cpufreq_boost
+- Removal of the CONFIG_CPU_FREQ_BOOST flag
+- low_level_boost with valid address when boost is supported
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/exynos-cpufreq.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c
+index aa869de..3704b51 100644
+--- a/drivers/cpufreq/exynos-cpufreq.c
++++ b/drivers/cpufreq/exynos-cpufreq.c
+@@ -264,6 +264,7 @@ static int exynos_cpufreq_cpu_exit(struct cpufreq_policy *policy)
+ static struct freq_attr *exynos_cpufreq_attr[] = {
+       &cpufreq_freq_attr_scaling_available_freqs,
++      &cpufreq_freq_attr_scaling_boost_freqs,
+       NULL,
+ };
+@@ -404,6 +405,7 @@ static struct of_device_id exynos_cpufreq_of_match[] = {
+ static int exynos_cpufreq_probe(struct platform_device *pdev)
+ {
++      struct device_node *node = pdev->dev.of_node;
+       int ret = -EINVAL;
+       exynos_info = kzalloc(sizeof(struct exynos_dvfs_info), GFP_KERNEL);
+@@ -436,6 +438,8 @@ static int exynos_cpufreq_probe(struct platform_device *pdev)
+       }
+       locking_frequency = exynos_getspeed(0);
++      if (of_property_read_bool(node, "boost_mode"))
++              exynos_driver.boost_supported = true;
+       register_pm_notifier(&exynos_cpufreq_nb);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0909-thermal-boost-Automatic-enable-disable-of-BOOST-feat.patch b/patches.tizen/0909-thermal-boost-Automatic-enable-disable-of-BOOST-feat.patch
new file mode 100644 (file)
index 0000000..4e7b33c
--- /dev/null
@@ -0,0 +1,140 @@
+From 196dd486eac6da653477a16a2c794c240c03a102 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Mon, 8 Jul 2013 17:15:11 +0200
+Subject: [PATCH 0909/1302] thermal:boost: Automatic enable/disable of BOOST
+ feature
+
+This patch provides auto disable/enable operation for boost. When any
+defined trip point is passed, the boost is disabled.
+In that moment thermal monitor workqueue is woken up and it monitors
+if the device temperature drops below 75% of the smallest trip point.
+When device cools down, the boost is enabled again.
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: Myungjoo Ham <myungjoo.ham@samsung.com>
+
+Changes for v6:
+- Disable boost only when supported and enabled
+- Protect boost related thermal_zone_device struct fields with mutex
+- Evaluate temperature trend during boost enable decision
+- Create separate methods to handle boost enable/disable
+  (thermal_boost_{enable|disable}) operations
+- Boost is disabled at any trip point passage (not only the non critical one)
+
+Changes for v5:
+- Move boost disable code from cpu_cooling.c to thermal_core.c
+  (to handle_non_critical_trips)
+- Extent struct thermal_zone_device by adding overheated bool flag
+- Implement auto enable of boost after device cools down
+- Introduce boost_polling flag, which indicates if thermal uses it's predefined
+  pool delay or has woken up thermal workqueue only to wait until device
+  cools down.
+
+Changes for v4:
+- New patch
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/thermal_core.c | 55 ++++++++++++++++++++++++++++++++++++++++++
+ include/linux/thermal.h        |  2 ++
+ 2 files changed, 57 insertions(+)
+
+diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
+index d755440..3258c6a 100644
+--- a/drivers/thermal/thermal_core.c
++++ b/drivers/thermal/thermal_core.c
+@@ -33,6 +33,7 @@
+ #include <linux/idr.h>
+ #include <linux/thermal.h>
+ #include <linux/reboot.h>
++#include <linux/cpufreq.h>
+ #include <net/netlink.h>
+ #include <net/genetlink.h>
+@@ -352,9 +353,59 @@ static void handle_critical_trips(struct thermal_zone_device *tz,
+       }
+ }
++static int thermal_boost_enable(struct thermal_zone_device *tz)
++{
++      enum thermal_trend trend = get_tz_trend(tz, 0);
++      long trip_temp;
++
++      if (!tz->ops->get_trip_temp || !tz->overheated)
++              return -EPERM;
++      if (trend == THERMAL_TREND_RAISING || trend == THERMAL_TREND_RAISE_FULL)
++              return -EBUSY;
++
++      tz->ops->get_trip_temp(tz, 0, &trip_temp);
++      /*
++       * Enable boost again only when current temperature is less
++       * than 75% of trip_temp[0]
++       */
++      if ((tz->temperature + (trip_temp >> 2)) < trip_temp) {
++              mutex_lock(&tz->lock);
++              tz->overheated = false;
++              if (tz->boost_polling) {
++                      tz->boost_polling = false;
++                      tz->polling_delay = 0;
++              }
++              mutex_unlock(&tz->lock);
++              cpufreq_boost_trigger_state(1);
++              return 0;
++      }
++      return -EBUSY;
++}
++
++static void thermal_boost_disable(struct thermal_zone_device *tz)
++{
++      cpufreq_boost_trigger_state(0);
++
++      /*
++       * If no workqueue for monitoring is running - start one with
++       * 1000 ms monitoring period
++       * If workqueue already running - do not change its period and only
++       * test if target CPU has cooled down
++       */
++      mutex_lock(&tz->lock);
++      if (!tz->polling_delay) {
++              tz->boost_polling = true;
++              tz->polling_delay = 1000;
++      }
++      tz->overheated = true;
++      mutex_unlock(&tz->lock);
++}
++
+ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip)
+ {
+       enum thermal_trip_type type;
++      if (cpufreq_boost_supported() && cpufreq_boost_enabled())
++              thermal_boost_disable(tz);
+       tz->ops->get_trip_type(tz, trip, &type);
+@@ -453,6 +504,10 @@ static void thermal_zone_device_check(struct work_struct *work)
+       struct thermal_zone_device *tz = container_of(work, struct
+                                                     thermal_zone_device,
+                                                     poll_queue.work);
++      if (cpufreq_boost_supported())
++              if (!thermal_boost_enable(tz))
++                      return;
++
+       thermal_zone_device_update(tz);
+ }
+diff --git a/include/linux/thermal.h b/include/linux/thermal.h
+index a386a1c..f1aa3c2 100644
+--- a/include/linux/thermal.h
++++ b/include/linux/thermal.h
+@@ -172,6 +172,8 @@ struct thermal_zone_device {
+       int emul_temperature;
+       int passive;
+       unsigned int forced_passive;
++      bool overheated;
++      bool boost_polling;
+       const struct thermal_zone_device_ops *ops;
+       const struct thermal_zone_params *tzp;
+       struct thermal_governor *governor;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0910-cpufreq-boost-Kconfig-Enable-software-managed-BOOST-.patch b/patches.tizen/0910-cpufreq-boost-Kconfig-Enable-software-managed-BOOST-.patch
new file mode 100644 (file)
index 0000000..d9e9942
--- /dev/null
@@ -0,0 +1,90 @@
+From 4bbc9f177fe4620a446f11bf3833810828819582 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Thu, 18 Jul 2013 15:33:28 +0200
+Subject: [PATCH 0910/1302] cpufreq:boost:Kconfig: Enable software managed
+ BOOST support at Kconfig
+
+For safety reasons new flag - CONFIG_CPU_FREQ_BOOST_SW has been added.
+Only after selecting "CPU Frequency Overclocking - Software" Kconfig
+option the software managed boost is enabled. It also requires thermal
+subsystem to be compiled in. Thermal is necessary for disabling boost
+and cooling down the device when overheating detected.
+
+Boost _MUST_NOT_ be enabled without thermal subsystem with properly
+defined temperatures which indicate overheating.
+
+This option doesn't affect x86's ACPI hardware managed boost support
+(i.e. Intel, AMD). In this situation boost management is embedded at
+hardware.
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: Myungjoo Ham <myungjoo.ham@samsung.com>
+
+Changes for v6:
+- Remove platform dependency (EXYNOS_THERMAL) in selecting software
+  managed boost. Now boost only depends on THERMAL.
+- Remove CPUFREQ dependency
+- Software boost Kconfig name has been edited
+
+Changes for v5:
+- New patch
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/Kconfig          | 14 ++++++++++++++
+ drivers/cpufreq/exynos-cpufreq.c |  4 ++++
+ 2 files changed, 18 insertions(+)
+
+diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
+index 534fcb8..79ebd97 100644
+--- a/drivers/cpufreq/Kconfig
++++ b/drivers/cpufreq/Kconfig
+@@ -23,6 +23,20 @@ config CPU_FREQ_TABLE
+ config CPU_FREQ_GOV_COMMON
+       bool
++config CPU_FREQ_BOOST_SW
++      bool "CPU Frequency Overclocking - Software"
++      depends on THERMAL
++      default n
++      help
++        This driver supports software managed overclocking (BOOST).
++        It allows usage of special frequencies for a particular processor
++        if thermal conditions are appropriate.
++
++        It reguires, for safe operation, thermal framework with properly
++        defined trip points.
++
++        If in doubt, say N.
++
+ config CPU_FREQ_STAT
+       tristate "CPU frequency translation statistics"
+       select CPU_FREQ_TABLE
+diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c
+index 3704b51..51a126c 100644
+--- a/drivers/cpufreq/exynos-cpufreq.c
++++ b/drivers/cpufreq/exynos-cpufreq.c
+@@ -405,7 +405,9 @@ static struct of_device_id exynos_cpufreq_of_match[] = {
+ static int exynos_cpufreq_probe(struct platform_device *pdev)
+ {
++#ifdef CONFIG_CPU_FREQ_BOOST_SW
+       struct device_node *node = pdev->dev.of_node;
++#endif
+       int ret = -EINVAL;
+       exynos_info = kzalloc(sizeof(struct exynos_dvfs_info), GFP_KERNEL);
+@@ -438,8 +440,10 @@ static int exynos_cpufreq_probe(struct platform_device *pdev)
+       }
+       locking_frequency = exynos_getspeed(0);
++#ifdef CONFIG_CPU_FREQ_BOOST_SW
+       if (of_property_read_bool(node, "boost_mode"))
+               exynos_driver.boost_supported = true;
++#endif
+       register_pm_notifier(&exynos_cpufreq_nb);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0911-Documentation-cpufreq-boost-Update-BOOST-documentati.patch b/patches.tizen/0911-Documentation-cpufreq-boost-Update-BOOST-documentati.patch
new file mode 100644 (file)
index 0000000..f7b1639
--- /dev/null
@@ -0,0 +1,77 @@
+From 06401927b38a7ec95d423571a4041b31e27d2e7b Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Wed, 3 Jul 2013 14:36:24 +0200
+Subject: [PATCH 0911/1302] Documentation:cpufreq:boost: Update BOOST
+ documentation
+
+Since the support for software and hardware controlled boosting has been
+added, the corresponding Documentation entry had been updated.
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: Myungjoo Ham <myungjoo.ham@samsung.com>
+
+Changes for v6:
+- None
+
+Changes for v5:
+- New patch
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/cpu-freq/boost.txt | 26 +++++++++++++-------------
+ 1 file changed, 13 insertions(+), 13 deletions(-)
+
+diff --git a/Documentation/cpu-freq/boost.txt b/Documentation/cpu-freq/boost.txt
+index 9b4edfc..dd62e13 100644
+--- a/Documentation/cpu-freq/boost.txt
++++ b/Documentation/cpu-freq/boost.txt
+@@ -17,8 +17,8 @@ Introduction
+ Some CPUs support a functionality to raise the operating frequency of
+ some cores in a multi-core package if certain conditions apply, mostly
+ if the whole chip is not fully utilized and below it's intended thermal
+-budget. This is done without operating system control by a combination
+-of hardware and firmware.
++budget. The decision about boost disable/enable is made either at hardware
++(e.g. x86) or software (e.g ARM).
+ On Intel CPUs this is called "Turbo Boost", AMD calls it "Turbo-Core",
+ in technical documentation "Core performance boost". In Linux we use
+ the term "boost" for convenience.
+@@ -48,24 +48,24 @@ be desirable:
+ User controlled switch
+ ----------------------
+-To allow the user to toggle the boosting functionality, the acpi-cpufreq
+-driver exports a sysfs knob to disable it. There is a file:
++To allow the user to toggle the boosting functionality, the cpufreq core
++driver exports a sysfs knob to enable or disable it. There is a file:
+ /sys/devices/system/cpu/cpufreq/boost
+ which can either read "0" (boosting disabled) or "1" (boosting enabled).
+-Reading the file is always supported, even if the processor does not
+-support boosting. In this case the file will be read-only and always
+-reads as "0". Explicitly changing the permissions and writing to that
+-file anyway will return EINVAL.
++The file is exported only when cpufreq driver supports boosting.
++Explicitly changing the permissions and writing to that file anyway will
++return EINVAL.
+ On supported CPUs one can write either a "0" or a "1" into this file.
+ This will either disable the boost functionality on all cores in the
+-whole system (0) or will allow the hardware to boost at will (1).
++whole system (0) or will allow the software or hardware to boost at will
++(1).
+ Writing a "1" does not explicitly boost the system, but just allows the
+-CPU (and the firmware) to boost at their discretion. Some implementations
+-take external factors like the chip's temperature into account, so
+-boosting once does not necessarily mean that it will occur every time
+-even using the exact same software setup.
++CPU to boost at their discretion. Some implementations take external
++factors like the chip's temperature into account, so boosting once does
++not necessarily mean that it will occur every time even using the exact
++same software setup.
+ AMD legacy cpb switch
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0912-cpufreq-exynos4x12-Change-L0-driver-data-to-CPUFREQ_.patch b/patches.tizen/0912-cpufreq-exynos4x12-Change-L0-driver-data-to-CPUFREQ_.patch
new file mode 100644 (file)
index 0000000..0dc7b73
--- /dev/null
@@ -0,0 +1,38 @@
+From caed72affbb2e974b095b2d11b72700224eb274c Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Tue, 9 Jul 2013 09:08:43 +0200
+Subject: [PATCH 0912/1302] cpufreq:exynos4x12: Change L0 driver data to
+ CPUFREQ_BOOST_FREQ
+
+Special driver data flag (CPUFREQ_BOOST_FREQ) has been added to indicate
+frequency, which can be only enabled for BOOST mode.
+This frequency shall be used only for limited time, since it might cause
+target device to overheat.
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: Myungjoo Ham <myungjoo.ham@samsung.com>
+
+Changes for v6:
+- New patch
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/exynos4x12-cpufreq.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/cpufreq/exynos4x12-cpufreq.c b/drivers/cpufreq/exynos4x12-cpufreq.c
+index 1e5331b..410d087 100644
+--- a/drivers/cpufreq/exynos4x12-cpufreq.c
++++ b/drivers/cpufreq/exynos4x12-cpufreq.c
+@@ -32,7 +32,7 @@ static unsigned int exynos4x12_volt_table[] = {
+ };
+ static struct cpufreq_frequency_table exynos4x12_freq_table[] = {
+-      {L0, CPUFREQ_ENTRY_INVALID},
++      {CPUFREQ_BOOST_FREQ, 1500 * 1000},
+       {L1, 1400 * 1000},
+       {L2, 1300 * 1000},
+       {L3, 1200 * 1000},
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0913-ARM-exynos-Enable-boost-mode-for-exynos4412-redwood-.patch b/patches.tizen/0913-ARM-exynos-Enable-boost-mode-for-exynos4412-redwood-.patch
new file mode 100644 (file)
index 0000000..103d7db
--- /dev/null
@@ -0,0 +1,27 @@
+From 376814c7cdc42387de9fd34c1106367183e4b240 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Mon, 10 Jun 2013 13:57:04 +0200
+Subject: [PATCH 0913/1302] ARM:exynos: Enable boost mode for exynos4412
+ redwood target
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-redwood.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-redwood.dts b/arch/arm/boot/dts/exynos4412-redwood.dts
+index e03854e..a8c99fd 100644
+--- a/arch/arm/boot/dts/exynos4412-redwood.dts
++++ b/arch/arm/boot/dts/exynos4412-redwood.dts
+@@ -140,6 +140,7 @@
+       cpufreq {
+               freq_table;
++              boost_mode = "okay";
+               status = "okay";
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0914-BOOST-Core-code-compliant-with-v9-of-the-patch.patch b/patches.tizen/0914-BOOST-Core-code-compliant-with-v9-of-the-patch.patch
new file mode 100644 (file)
index 0000000..dd6f275
--- /dev/null
@@ -0,0 +1,125 @@
+From 34727cbd5818b5bb95789ebced0386050e728ded Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Thu, 31 Oct 2013 16:54:09 +0100
+Subject: [PATCH 0914/1302] BOOST: Core code compliant with v9 of the patch
+
+Update the BOOST framework core to be compliant with v9 version of the patch
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/cpufreq.c | 41 ++++++++++++++++++++++++-----------------
+ include/linux/cpufreq.h   |  2 +-
+ 2 files changed, 25 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
+index bf81873..5dcb6ea 100644
+--- a/drivers/cpufreq/cpufreq.c
++++ b/drivers/cpufreq/cpufreq.c
+@@ -1930,7 +1930,7 @@ static struct notifier_block __refdata cpufreq_cpu_notifier = {
+ /*********************************************************************
+  *               BOOST                                                     *
+  *********************************************************************/
+-static int cpufreq_boost_enable_sw(int state)
++static int cpufreq_boost_set_sw(int state)
+ {
+       struct cpufreq_frequency_table *freq_table;
+       struct cpufreq_policy *policy;
+@@ -1941,8 +1941,13 @@ static int cpufreq_boost_enable_sw(int state)
+               if (freq_table) {
+                       ret = cpufreq_frequency_table_cpuinfo(policy,
+                                                       freq_table);
+-                      if (!ret)
+-                              policy->user_policy.max = policy->max;
++                      if (ret) {
++                              pr_err("%s: Policy frequency update failed\n",
++                                     __func__);
++                              break;
++                      }
++                      policy->user_policy.max = policy->max;
++                      __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
+               }
+       }
+@@ -1954,19 +1959,21 @@ int cpufreq_boost_trigger_state(int state)
+       unsigned long flags;
+       int ret = 0;
+-      if (cpufreq_driver->boost_enabled != state) {
+-              write_lock_irqsave(&cpufreq_driver_lock, flags);
+-              cpufreq_driver->boost_enabled = state;
++      if (cpufreq_driver->boost_enabled == state)
++              return 0;
+-              ret = cpufreq_driver->enable_boost(state);
+-              if (ret)
+-                      cpufreq_driver->boost_enabled = 0;
++      write_lock_irqsave(&cpufreq_driver_lock, flags);
++      cpufreq_driver->boost_enabled = state;
++      write_unlock_irqrestore(&cpufreq_driver_lock, flags);
++      ret = cpufreq_driver->set_boost(state);
++      if (ret) {
++              write_lock_irqsave(&cpufreq_driver_lock, flags);
++              cpufreq_driver->boost_enabled = !state;
+               write_unlock_irqrestore(&cpufreq_driver_lock, flags);
+-              if (ret)
+-                      pr_err("%s: BOOST cannot %s\n", __func__,
+-                             state ? "enabled" : "disabled");
++              pr_err("%s: Cannot %s BOOST\n", __func__,
++                     state ? "enable" : "disable");
+       }
+       return ret;
+@@ -1974,7 +1981,7 @@ int cpufreq_boost_trigger_state(int state)
+ int cpufreq_boost_supported(void)
+ {
+-      if (cpufreq_driver)
++      if (likely(cpufreq_driver))
+               return cpufreq_driver->boost_supported;
+       return 0;
+@@ -2026,13 +2033,13 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
+       cpufreq_driver = driver_data;
+       write_unlock_irqrestore(&cpufreq_driver_lock, flags);
+-      if (cpufreq_driver->boost_supported) {
++      if (cpufreq_boost_supported()) {
+               /*
+                * Check if boost driver provides function to enable boost -
+                * if not, use cpufreq_boost_enable_sw as default
+                */
+-              if (!cpufreq_driver->enable_boost)
+-                      cpufreq_driver->enable_boost = cpufreq_boost_enable_sw;
++              if (!cpufreq_driver->set_boost)
++                      cpufreq_driver->set_boost = cpufreq_boost_set_sw;
+               ret = cpufreq_sysfs_create_file(&(boost.attr));
+               if (ret) {
+@@ -2072,7 +2079,7 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
+ err_if_unreg:
+       subsys_interface_unregister(&cpufreq_interface);
+ err_boost_unreg:
+-      if (cpufreq_driver->boost_supported)
++      if (cpufreq_boost_supported())
+               cpufreq_sysfs_remove_file(&(boost.attr));
+ err_null_driver:
+       write_lock_irqsave(&cpufreq_driver_lock, flags);
+diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
+index afc6225..dbf5744 100644
+--- a/include/linux/cpufreq.h
++++ b/include/linux/cpufreq.h
+@@ -271,7 +271,7 @@ struct cpufreq_driver {
+       /* platform specific boost support code */
+       bool                    boost_supported;
+       bool                    boost_enabled;
+-      int (*enable_boost)     (int state);
++      int     (*set_boost)    (int state);
+ };
+ /* flags */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0915-tizen-config-Enable-THERMAL-and-BOOST.patch b/patches.tizen/0915-tizen-config-Enable-THERMAL-and-BOOST.patch
new file mode 100644 (file)
index 0000000..376ebaf
--- /dev/null
@@ -0,0 +1,162 @@
+From 2b220761429eece56818dcd281a05f2171c33d86 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Thu, 31 Oct 2013 18:01:29 +0100
+Subject: [PATCH 0915/1302] tizen:config: Enable THERMAL and BOOST
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_defconfig | 122 ++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 120 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index 16598c6..41b4304 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -535,6 +535,7 @@ CONFIG_CMDLINE=""
+ CONFIG_CPU_FREQ=y
+ CONFIG_CPU_FREQ_TABLE=y
+ CONFIG_CPU_FREQ_GOV_COMMON=y
++CONFIG_CPU_FREQ_BOOST_SW=y
+ CONFIG_CPU_FREQ_STAT=y
+ # CONFIG_CPU_FREQ_STAT_DETAILS is not set
+ # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+@@ -1740,9 +1741,125 @@ CONFIG_CHARGER_MAX77693=y
+ # CONFIG_POWER_RESET_RESTART is not set
+ # CONFIG_POWER_AVS is not set
+ CONFIG_HWMON=y
+-
++# CONFIG_HWMON_VID is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++
++#
++# Native drivers
++#
++# CONFIG_SENSORS_AD7314 is not set
++# CONFIG_SENSORS_AD7414 is not set
++# CONFIG_SENSORS_AD7418 is not set
++# CONFIG_SENSORS_ADCXX is not set
++# CONFIG_SENSORS_ADM1021 is not set
++# CONFIG_SENSORS_ADM1025 is not set
++# CONFIG_SENSORS_ADM1026 is not set
++# CONFIG_SENSORS_ADM1029 is not set
++# CONFIG_SENSORS_ADM1031 is not set
++# CONFIG_SENSORS_ADM9240 is not set
++# CONFIG_SENSORS_ADT7310 is not set
++# CONFIG_SENSORS_ADT7410 is not set
++# CONFIG_SENSORS_ADT7411 is not set
++# CONFIG_SENSORS_ADT7462 is not set
++# CONFIG_SENSORS_ADT7470 is not set
++# CONFIG_SENSORS_ADT7475 is not set
++# CONFIG_SENSORS_ASC7621 is not set
++# CONFIG_SENSORS_ATXP1 is not set
++# CONFIG_SENSORS_DS620 is not set
++# CONFIG_SENSORS_DS1621 is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_F75375S is not set
++# CONFIG_SENSORS_G760A is not set
++# CONFIG_SENSORS_GL518SM is not set
++# CONFIG_SENSORS_GL520SM is not set
++# CONFIG_SENSORS_GPIO_FAN is not set
++# CONFIG_SENSORS_HIH6130 is not set
++# CONFIG_SENSORS_IIO_HWMON is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_JC42 is not set
++# CONFIG_SENSORS_LINEAGE is not set
++# CONFIG_SENSORS_LM63 is not set
++# CONFIG_SENSORS_LM70 is not set
++# CONFIG_SENSORS_LM73 is not set
++# CONFIG_SENSORS_LM75 is not set
++# CONFIG_SENSORS_LM77 is not set
++# CONFIG_SENSORS_LM78 is not set
++# CONFIG_SENSORS_LM80 is not set
++# CONFIG_SENSORS_LM83 is not set
++# CONFIG_SENSORS_LM85 is not set
++# CONFIG_SENSORS_LM87 is not set
++# CONFIG_SENSORS_LM90 is not set
++# CONFIG_SENSORS_LM92 is not set
++# CONFIG_SENSORS_LM93 is not set
++# CONFIG_SENSORS_LTC4151 is not set
++# CONFIG_SENSORS_LTC4215 is not set
++# CONFIG_SENSORS_LTC4245 is not set
++# CONFIG_SENSORS_LTC4261 is not set
++# CONFIG_SENSORS_LM95234 is not set
++# CONFIG_SENSORS_LM95241 is not set
++# CONFIG_SENSORS_LM95245 is not set
++# CONFIG_SENSORS_MAX1111 is not set
++# CONFIG_SENSORS_MAX16065 is not set
++# CONFIG_SENSORS_MAX1619 is not set
++# CONFIG_SENSORS_MAX1668 is not set
++# CONFIG_SENSORS_MAX197 is not set
++# CONFIG_SENSORS_MAX6639 is not set
++# CONFIG_SENSORS_MAX6642 is not set
++# CONFIG_SENSORS_MAX6650 is not set
++# CONFIG_SENSORS_MAX6697 is not set
++# CONFIG_SENSORS_MCP3021 is not set
++# CONFIG_SENSORS_NCT6775 is not set
+ CONFIG_SENSORS_NTC_THERMISTOR=y
+-# CONFIG_THERMAL is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_PMBUS is not set
++# CONFIG_SENSORS_SHT15 is not set
++# CONFIG_SENSORS_SHT21 is not set
++# CONFIG_SENSORS_S3C is not set
++# CONFIG_SENSORS_SMM665 is not set
++# CONFIG_SENSORS_DME1737 is not set
++# CONFIG_SENSORS_EMC1403 is not set
++# CONFIG_SENSORS_EMC2103 is not set
++# CONFIG_SENSORS_EMC6W201 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47M192 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_SCH56XX_COMMON is not set
++# CONFIG_SENSORS_SCH5627 is not set
++# CONFIG_SENSORS_SCH5636 is not set
++# CONFIG_SENSORS_ADS1015 is not set
++# CONFIG_SENSORS_ADS7828 is not set
++# CONFIG_SENSORS_ADS7871 is not set
++# CONFIG_SENSORS_AMC6821 is not set
++# CONFIG_SENSORS_INA209 is not set
++# CONFIG_SENSORS_INA2XX is not set
++# CONFIG_SENSORS_THMC50 is not set
++# CONFIG_SENSORS_TMP102 is not set
++# CONFIG_SENSORS_TMP401 is not set
++# CONFIG_SENSORS_TMP421 is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_SENSORS_W83781D is not set
++# CONFIG_SENSORS_W83791D is not set
++# CONFIG_SENSORS_W83792D is not set
++# CONFIG_SENSORS_W83793 is not set
++# CONFIG_SENSORS_W83795 is not set
++# CONFIG_SENSORS_W83L785TS is not set
++# CONFIG_SENSORS_W83L786NG is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++CONFIG_THERMAL=y
++CONFIG_THERMAL_HWMON=y
++CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
++# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
++# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
++# CONFIG_THERMAL_GOV_FAIR_SHARE is not set
++CONFIG_THERMAL_GOV_STEP_WISE=y
++# CONFIG_THERMAL_GOV_USER_SPACE is not set
++CONFIG_CPU_THERMAL=y
++# CONFIG_THERMAL_EMULATION is not set
++CONFIG_EXYNOS_THERMAL=y
+ CONFIG_WATCHDOG=y
+ CONFIG_WATCHDOG_CORE=y
+ # CONFIG_WATCHDOG_NOWAYOUT is not set
+@@ -2843,6 +2960,7 @@ CONFIG_EXTCON=y
+ #
+ # Extcon Device Drivers
+ #
++CONFIG_OF_EXTCON=y
+ CONFIG_EXTCON_GPIO=y
+ CONFIG_EXTCON_ADC_JACK=y
+ CONFIG_EXTCON_MAX77693=y
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0916-mmc-sdhci-s3c-Use-mmc_gpio_request_cd-function.patch b/patches.tizen/0916-mmc-sdhci-s3c-Use-mmc_gpio_request_cd-function.patch
new file mode 100644 (file)
index 0000000..611500a
--- /dev/null
@@ -0,0 +1,106 @@
+From 995013dd86557e4fa5b33654b0b80344de76935e Mon Sep 17 00:00:00 2001
+From: Beomho Seo <beomho.seo@samsung.com>
+Date: Fri, 1 Nov 2013 15:17:02 +0900
+Subject: [PATCH 0916/1302] mmc:sdhci-s3c: Use mmc_gpio_request_cd function
+
+This patch used mmc_gpio_request function for detect card from cd gpio pin.
+
+Include slot-gpio header file.
+Use mmc_gpio_request_cd function.
+Remove sdhci_s3c_setup_card_detect_gpio/card_detect_thread functions.
+
+Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
+Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mmc/host/sdhci-s3c.c | 53 ++++++++++++--------------------------------
+ 1 file changed, 14 insertions(+), 39 deletions(-)
+
+diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
+index 1b6485f..c2a7383 100644
+--- a/drivers/mmc/host/sdhci-s3c.c
++++ b/drivers/mmc/host/sdhci-s3c.c
+@@ -27,6 +27,7 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/mmc/host.h>
++#include <linux/mmc/slot-gpio.h>
+ #include "sdhci-s3c-regs.h"
+ #include "sdhci.h"
+@@ -388,43 +389,6 @@ static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
+       }
+ }
+-static irqreturn_t sdhci_s3c_gpio_card_detect_thread(int irq, void *dev_id)
+-{
+-      struct sdhci_s3c *sc = dev_id;
+-      int status = gpio_get_value(sc->ext_cd_gpio);
+-      if (sc->pdata->ext_cd_gpio_invert)
+-              status = !status;
+-      sdhci_s3c_notify_change(sc->pdev, status);
+-      return IRQ_HANDLED;
+-}
+-
+-static void sdhci_s3c_setup_card_detect_gpio(struct sdhci_s3c *sc)
+-{
+-      struct s3c_sdhci_platdata *pdata = sc->pdata;
+-      struct device *dev = &sc->pdev->dev;
+-      int ret = 0;
+-
+-      if (devm_gpio_request(dev, pdata->ext_cd_gpio, "SDHCI EXT CD") == 0) {
+-              sc->ext_cd_gpio = pdata->ext_cd_gpio;
+-              sc->ext_cd_irq = gpio_to_irq(pdata->ext_cd_gpio);
+-              if (sc->ext_cd_irq) {
+-                      ret = request_threaded_irq(sc->ext_cd_irq, NULL,
+-                                      sdhci_s3c_gpio_card_detect_thread,
+-                                      IRQF_TRIGGER_RISING |
+-                                      IRQF_TRIGGER_FALLING |
+-                                      IRQF_ONESHOT,
+-                                      dev_name(dev), sc);
+-                      if (ret) {
+-                              dev_warn(dev,
+-                                      "cannot request irq for card detect\n");
+-                              sc->ext_cd_irq = 0;
+-                      }
+-              }
+-      } else {
+-              dev_err(dev, "cannot request gpio for card detect\n");
+-      }
+-}
+-
+ #ifdef CONFIG_OF
+ static int sdhci_s3c_parse_dt(struct device *dev,
+               struct sdhci_host *host, struct s3c_sdhci_platdata *pdata)
+@@ -685,8 +649,14 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
+       if (pdata->cd_type == S3C_SDHCI_CD_EXTERNAL && pdata->ext_cd_init)
+               pdata->ext_cd_init(&sdhci_s3c_notify_change);
+       if (pdata->cd_type == S3C_SDHCI_CD_GPIO &&
+-          gpio_is_valid(pdata->ext_cd_gpio))
+-              sdhci_s3c_setup_card_detect_gpio(sc);
++          gpio_is_valid(pdata->ext_cd_gpio)) {
++              ret = mmc_gpio_request_cd(host->mmc, pdata->ext_cd_gpio);
++              if (ret) {
++                      dev_err(dev,
++                              "failed to request card detect gpio\n");
++                      goto err_req_cd;
++              }
++      }
+ #ifdef CONFIG_PM_RUNTIME
+       if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL)
+@@ -694,6 +664,11 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
+ #endif
+       return 0;
++ err_req_cd:
++      mmc_gpio_free_cd(host->mmc);
++
++      return ret;
++
+  err_req_regs:
+ #ifndef CONFIG_PM_RUNTIME
+       clk_disable_unprepare(sc->clk_bus[sc->cur_clk]);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0917-Revert-Thermal-exynos-Support-for-TMU-regulator-defi.patch b/patches.tizen/0917-Revert-Thermal-exynos-Support-for-TMU-regulator-defi.patch
new file mode 100644 (file)
index 0000000..51c8d05
--- /dev/null
@@ -0,0 +1,67 @@
+From 859e09f466c94329c538456ba9b125ca4dc672f5 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Fri, 1 Nov 2013 14:54:23 +0900
+Subject: [PATCH 0917/1302] Revert "Thermal: exynos: Support for TMU regulator
+ defined at device tree"
+
+This reverts commit ed58c6a559cf9a870e55587872f9b0eb322e3e6b.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/exynos_thermal.c | 19 -------------------
+ 1 file changed, 19 deletions(-)
+
+diff --git a/drivers/thermal/exynos_thermal.c b/drivers/thermal/exynos_thermal.c
+index 84794b3..788b1dd 100644
+--- a/drivers/thermal/exynos_thermal.c
++++ b/drivers/thermal/exynos_thermal.c
+@@ -38,7 +38,6 @@
+ #include <linux/cpufreq.h>
+ #include <linux/cpu_cooling.h>
+ #include <linux/of.h>
+-#include <linux/regulator/consumer.h>
+ /* Exynos generic registers */
+ #define EXYNOS_TMU_REG_TRIMINFO               0x0
+@@ -118,8 +117,6 @@
+ #define EXYNOS_ZONE_COUNT     3
+-#define EXYNOS_TMU_REGULATOR "vdd_ts"
+-
+ struct exynos_tmu_data {
+       struct exynos_tmu_platform_data *pdata;
+       struct resource *mem;
+@@ -903,7 +900,6 @@ static int exynos_tmu_probe(struct platform_device *pdev)
+ {
+       struct exynos_tmu_data *data;
+       struct exynos_tmu_platform_data *pdata = pdev->dev.platform_data;
+-      struct regulator *reg;
+       int ret, i;
+       if (!pdata)
+@@ -913,21 +909,6 @@ static int exynos_tmu_probe(struct platform_device *pdev)
+               dev_err(&pdev->dev, "No platform init data supplied.\n");
+               return -ENODEV;
+       }
+-
+-      reg = regulator_get(&pdev->dev, EXYNOS_TMU_REGULATOR);
+-      if (!IS_ERR(reg)) {
+-              ret = regulator_enable(reg);
+-              if (ret) {
+-                      dev_err(&pdev->dev, "Regulator %s not enabled.\n",
+-                              EXYNOS_TMU_REGULATOR);
+-                      return ret;
+-              }
+-      } else {
+-              dev_warn(&pdev->dev,
+-                       "Regulator %s not defined at device tree.\n",
+-                       EXYNOS_TMU_REGULATOR);
+-      }
+-
+       data = devm_kzalloc(&pdev->dev, sizeof(struct exynos_tmu_data),
+                                       GFP_KERNEL);
+       if (!data) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0918-Thermal-armada_thermal-Remove-redundant-platform_set.patch b/patches.tizen/0918-Thermal-armada_thermal-Remove-redundant-platform_set.patch
new file mode 100644 (file)
index 0000000..92a71d8
--- /dev/null
@@ -0,0 +1,35 @@
+From 501ef86db5e02091195f141d7a4ee23dab32edaa Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Fri, 3 May 2013 09:57:08 +0000
+Subject: [PATCH 0918/1302] Thermal: armada_thermal: Remove redundant
+ platform_set_drvdata()
+
+Commit 0998d06310 (device-core: Ensure drvdata = NULL when no
+driver is bound) removes the need to set driver data field to
+NULL.
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Cc: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Acked-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/armada_thermal.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
+index 54ffd64..0491465 100644
+--- a/drivers/thermal/armada_thermal.c
++++ b/drivers/thermal/armada_thermal.c
+@@ -200,7 +200,6 @@ static int armada_thermal_exit(struct platform_device *pdev)
+               platform_get_drvdata(pdev);
+       thermal_zone_device_unregister(armada_thermal);
+-      platform_set_drvdata(pdev, NULL);
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0919-Thermal-dove_thermal-Remove-redundant-platform_set_d.patch b/patches.tizen/0919-Thermal-dove_thermal-Remove-redundant-platform_set_d.patch
new file mode 100644 (file)
index 0000000..6daac86
--- /dev/null
@@ -0,0 +1,35 @@
+From 73be680856da40387a34d9f62746a70443a5e8a9 Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Fri, 3 May 2013 09:57:09 +0000
+Subject: [PATCH 0919/1302] Thermal: dove_thermal: Remove redundant
+ platform_set_drvdata()
+
+Commit 0998d06310 (device-core: Ensure drvdata = NULL when no
+driver is bound) removes the need to set driver data field to
+NULL.
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Cc: Andrew Lunn <andrew@lunn.ch>
+Acked-by: Andrew Lunn <andrew@lunn.ch>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/dove_thermal.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/thermal/dove_thermal.c b/drivers/thermal/dove_thermal.c
+index a088d13..954d269 100644
+--- a/drivers/thermal/dove_thermal.c
++++ b/drivers/thermal/dove_thermal.c
+@@ -178,7 +178,6 @@ static int dove_thermal_exit(struct platform_device *pdev)
+               platform_get_drvdata(pdev);
+       thermal_zone_device_unregister(dove_thermal);
+-      platform_set_drvdata(pdev, NULL);
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0920-Thermal-exynos-Remove-redundant-platform_set_drvdata.patch b/patches.tizen/0920-Thermal-exynos-Remove-redundant-platform_set_drvdata.patch
new file mode 100644 (file)
index 0000000..1f39883
--- /dev/null
@@ -0,0 +1,42 @@
+From a2c0bc56c41c4437d9ac8ab601ed6604e795df0f Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Fri, 3 May 2013 09:57:10 +0000
+Subject: [PATCH 0920/1302] Thermal: exynos: Remove redundant
+ platform_set_drvdata()
+
+Commit 0998d06310 (device-core: Ensure drvdata = NULL when no
+driver is bound) removes the need to set driver data field to
+NULL.
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/exynos_thermal.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/drivers/thermal/exynos_thermal.c b/drivers/thermal/exynos_thermal.c
+index 788b1dd..03e4bbc 100644
+--- a/drivers/thermal/exynos_thermal.c
++++ b/drivers/thermal/exynos_thermal.c
+@@ -996,7 +996,6 @@ static int exynos_tmu_probe(struct platform_device *pdev)
+       return 0;
+ err_clk:
+-      platform_set_drvdata(pdev, NULL);
+       clk_unprepare(data->clk);
+       return ret;
+ }
+@@ -1011,8 +1010,6 @@ static int exynos_tmu_remove(struct platform_device *pdev)
+       clk_unprepare(data->clk);
+-      platform_set_drvdata(pdev, NULL);
+-
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0921-Thermal-kirkwood-Remove-redundant-platform_set_drvda.patch b/patches.tizen/0921-Thermal-kirkwood-Remove-redundant-platform_set_drvda.patch
new file mode 100644 (file)
index 0000000..835b3fa
--- /dev/null
@@ -0,0 +1,35 @@
+From 6797ef7238e060345f75a75ba9edb40081b311f2 Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Fri, 3 May 2013 09:57:11 +0000
+Subject: [PATCH 0921/1302] Thermal: kirkwood: Remove redundant
+ platform_set_drvdata()
+
+Commit 0998d06310 (device-core: Ensure drvdata = NULL when no
+driver is bound) removes the need to set driver data field to
+NULL.
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Cc: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Acked-by: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/kirkwood_thermal.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/thermal/kirkwood_thermal.c b/drivers/thermal/kirkwood_thermal.c
+index dfeceaf..b57a45d 100644
+--- a/drivers/thermal/kirkwood_thermal.c
++++ b/drivers/thermal/kirkwood_thermal.c
+@@ -108,7 +108,6 @@ static int kirkwood_thermal_exit(struct platform_device *pdev)
+               platform_get_drvdata(pdev);
+       thermal_zone_device_unregister(kirkwood_thermal);
+-      platform_set_drvdata(pdev, NULL);
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0922-Thermal-rcar-Remove-redundant-platform_set_drvdata.patch b/patches.tizen/0922-Thermal-rcar-Remove-redundant-platform_set_drvdata.patch
new file mode 100644 (file)
index 0000000..94974b8
--- /dev/null
@@ -0,0 +1,35 @@
+From 5ce0cef4150195047b1a6f45251c9f0119cb09b3 Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Fri, 3 May 2013 09:57:12 +0000
+Subject: [PATCH 0922/1302] Thermal: rcar: Remove redundant
+ platform_set_drvdata()
+
+Commit 0998d06310 (device-core: Ensure drvdata = NULL when no
+driver is bound) removes the need to set driver data field to
+NULL.
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Cc: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/rcar_thermal.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c
+index 8d7edd4..63c7c13 100644
+--- a/drivers/thermal/rcar_thermal.c
++++ b/drivers/thermal/rcar_thermal.c
+@@ -487,8 +487,6 @@ static int rcar_thermal_remove(struct platform_device *pdev)
+                       rcar_thermal_irq_disable(priv);
+       }
+-      platform_set_drvdata(pdev, NULL);
+-
+       pm_runtime_put_sync(dev);
+       pm_runtime_disable(dev);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0923-Thermal-spear-Remove-redundant-platform_set_drvdata.patch b/patches.tizen/0923-Thermal-spear-Remove-redundant-platform_set_drvdata.patch
new file mode 100644 (file)
index 0000000..3cedda8
--- /dev/null
@@ -0,0 +1,35 @@
+From 6ed2eb06ec925f59dd8358feff5efbfb389f87a0 Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Fri, 3 May 2013 09:57:13 +0000
+Subject: [PATCH 0923/1302] Thermal: spear: Remove redundant
+ platform_set_drvdata()
+
+Commit 0998d06310 (device-core: Ensure drvdata = NULL when no
+driver is bound) removes the need to set driver data field to
+NULL.
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Cc: Vincenzo Frascino <vincenzo.frascino@st.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/spear_thermal.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/thermal/spear_thermal.c b/drivers/thermal/spear_thermal.c
+index 3c5ee56..1a14eaa 100644
+--- a/drivers/thermal/spear_thermal.c
++++ b/drivers/thermal/spear_thermal.c
+@@ -174,7 +174,6 @@ static int spear_thermal_exit(struct platform_device *pdev)
+       struct spear_thermal_dev *stdev = spear_thermal->devdata;
+       thermal_zone_device_unregister(spear_thermal);
+-      platform_set_drvdata(pdev, NULL);
+       /* Disable SPEAr Thermal Sensor */
+       actual_mask = readl_relaxed(stdev->thermal_base);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0924-drivers-thermal-don-t-check-resource-with-devm_iorem.patch b/patches.tizen/0924-drivers-thermal-don-t-check-resource-with-devm_iorem.patch
new file mode 100644 (file)
index 0000000..ce453c7
--- /dev/null
@@ -0,0 +1,90 @@
+From aae005c7ee62bff7d7fc4f80491d4b59ea68c2c6 Mon Sep 17 00:00:00 2001
+From: Wolfram Sang <wsa@the-dreams.de>
+Date: Fri, 10 May 2013 08:17:11 +0000
+Subject: [PATCH 0924/1302] drivers/thermal: don't check resource with
+ devm_ioremap_resource
+
+devm_ioremap_resource does sanity checks on the given resource. No need to
+duplicate this in the driver.
+
+Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/dove_thermal.c     | 7 +------
+ drivers/thermal/kirkwood_thermal.c | 7 +------
+ drivers/thermal/rcar_thermal.c     | 6 +-----
+ 3 files changed, 3 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/thermal/dove_thermal.c b/drivers/thermal/dove_thermal.c
+index 954d269..db83f7e 100644
+--- a/drivers/thermal/dove_thermal.c
++++ b/drivers/thermal/dove_thermal.c
+@@ -134,16 +134,11 @@ static int dove_thermal_probe(struct platform_device *pdev)
+       struct resource *res;
+       int ret;
+-      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-      if (!res) {
+-              dev_err(&pdev->dev, "Failed to get platform resource\n");
+-              return -ENODEV;
+-      }
+-
+       priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
++      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       priv->sensor = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(priv->sensor))
+               return PTR_ERR(priv->sensor);
+diff --git a/drivers/thermal/kirkwood_thermal.c b/drivers/thermal/kirkwood_thermal.c
+index b57a45d..7160164 100644
+--- a/drivers/thermal/kirkwood_thermal.c
++++ b/drivers/thermal/kirkwood_thermal.c
+@@ -75,16 +75,11 @@ static int kirkwood_thermal_probe(struct platform_device *pdev)
+       struct kirkwood_thermal_priv *priv;
+       struct resource *res;
+-      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-      if (!res) {
+-              dev_err(&pdev->dev, "Failed to get platform resource\n");
+-              return -ENODEV;
+-      }
+-
+       priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
++      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       priv->sensor = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(priv->sensor))
+               return PTR_ERR(priv->sensor);
+diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c
+index 63c7c13..197462d 100644
+--- a/drivers/thermal/rcar_thermal.c
++++ b/drivers/thermal/rcar_thermal.c
+@@ -389,11 +389,6 @@ static int rcar_thermal_probe(struct platform_device *pdev)
+                * platform has IRQ support.
+                * Then, drier use common register
+                */
+-              res = platform_get_resource(pdev, IORESOURCE_MEM, mres++);
+-              if (!res) {
+-                      dev_err(dev, "Could not get platform resource\n");
+-                      return -ENODEV;
+-              }
+               ret = devm_request_irq(dev, irq->start, rcar_thermal_irq, 0,
+                                      dev_name(dev), common);
+@@ -405,6 +400,7 @@ static int rcar_thermal_probe(struct platform_device *pdev)
+               /*
+                * rcar_has_irq_support() will be enabled
+                */
++              res = platform_get_resource(pdev, IORESOURCE_MEM, mres++);
+               common->base = devm_ioremap_resource(dev, res);
+               if (IS_ERR(common->base))
+                       return PTR_ERR(common->base);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0925-Thermal-spear_thermal-convert-to-devm_ioremap_resour.patch b/patches.tizen/0925-Thermal-spear_thermal-convert-to-devm_ioremap_resour.patch
new file mode 100644 (file)
index 0000000..29fef0a
--- /dev/null
@@ -0,0 +1,67 @@
+From 541144bd711d70ced26c2d3b00f93a381c7b870f Mon Sep 17 00:00:00 2001
+From: Zhang Rui <rui.zhang@intel.com>
+Date: Thu, 16 May 2013 02:16:20 +0000
+Subject: [PATCH 0925/1302] Thermal: spear_thermal: convert to
+ devm_ioremap_resource
+
+Use the newly introduced devm_ioremap_resource().
+
+devm_ioremap_resource() provides its own error messages; so all explicit
+error messages can be removed from the failure code paths.
+
+CC: Vincenzo Frascino <vincenzo.frascino@st.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/spear_thermal.c | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/thermal/spear_thermal.c b/drivers/thermal/spear_thermal.c
+index 1a14eaa..1b652ab 100644
+--- a/drivers/thermal/spear_thermal.c
++++ b/drivers/thermal/spear_thermal.c
+@@ -104,7 +104,7 @@ static int spear_thermal_probe(struct platform_device *pdev)
+       struct thermal_zone_device *spear_thermal = NULL;
+       struct spear_thermal_dev *stdev;
+       struct device_node *np = pdev->dev.of_node;
+-      struct resource *stres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      struct resource *res;
+       int ret = 0, val;
+       if (!np || !of_property_read_u32(np, "st,thermal-flags", &val)) {
+@@ -112,23 +112,23 @@ static int spear_thermal_probe(struct platform_device *pdev)
+               return -EINVAL;
+       }
+-      if (!stres) {
+-              dev_err(&pdev->dev, "memory resource missing\n");
+-              return -ENODEV;
+-      }
+-
+       stdev = devm_kzalloc(&pdev->dev, sizeof(*stdev), GFP_KERNEL);
+       if (!stdev) {
+               dev_err(&pdev->dev, "kzalloc fail\n");
+               return -ENOMEM;
+       }
++      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      if (!res) {
++              dev_err(&pdev->dev, "memory resource missing\n");
++              return -ENODEV;
++      }
++
+       /* Enable thermal sensor */
+-      stdev->thermal_base = devm_ioremap(&pdev->dev, stres->start,
+-                      resource_size(stres));
+-      if (!stdev->thermal_base) {
++      stdev->thermal_base = devm_ioremap_resource(dev, res);
++      if (IS_ERR(stdev->thermal_base)) {
+               dev_err(&pdev->dev, "ioremap failed\n");
+-              return -ENOMEM;
++              return PTR_ERR(stdev->thermal_base);
+       }
+       stdev->clk = devm_clk_get(&pdev->dev, NULL);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0926-thermal-rcar-Fix-typo-in-probe-information-message.patch b/patches.tizen/0926-thermal-rcar-Fix-typo-in-probe-information-message.patch
new file mode 100644 (file)
index 0000000..5d29825
--- /dev/null
@@ -0,0 +1,30 @@
+From d60ea1739e7da2dfa855e189042c9db0c52b78b8 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
+Date: Tue, 14 May 2013 23:00:32 +0000
+Subject: [PATCH 0926/1302] thermal: rcar: Fix typo in probe information
+ message
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/rcar_thermal.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c
+index 197462d..88f92e1 100644
+--- a/drivers/thermal/rcar_thermal.c
++++ b/drivers/thermal/rcar_thermal.c
+@@ -454,7 +454,7 @@ static int rcar_thermal_probe(struct platform_device *pdev)
+       platform_set_drvdata(pdev, common);
+-      dev_info(dev, "%d sensor proved\n", i);
++      dev_info(dev, "%d sensor probed\n", i);
+       return 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0927-thermal-cut-the-spaces-when-user-sets-policy.patch b/patches.tizen/0927-thermal-cut-the-spaces-when-user-sets-policy.patch
new file mode 100644 (file)
index 0000000..02e0156
--- /dev/null
@@ -0,0 +1,52 @@
+From 90ceb638d3abc52c5a5d000faa7062c92006f315 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Date: Fri, 17 May 2013 11:52:02 +0000
+Subject: [PATCH 0927/1302] thermal: cut the spaces when user sets policy
+
+Setting policy results in invalid value error.
+       % echo "step_wise" > policy
+       % echo: write error: Invalid argument
+
+Need clean up of the buffer which "echo" may add based on the arguments, before
+comparing aganist list of governor names.
+
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reported-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Tested-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/thermal_core.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
+index 3258c6a..4ab8f38 100644
+--- a/drivers/thermal/thermal_core.c
++++ b/drivers/thermal/thermal_core.c
+@@ -33,6 +33,7 @@
+ #include <linux/idr.h>
+ #include <linux/thermal.h>
+ #include <linux/reboot.h>
++#include <linux/string.h>
+ #include <linux/cpufreq.h>
+ #include <net/netlink.h>
+ #include <net/genetlink.h>
+@@ -768,10 +769,13 @@ policy_store(struct device *dev, struct device_attribute *attr,
+       int ret = -EINVAL;
+       struct thermal_zone_device *tz = to_thermal_zone(dev);
+       struct thermal_governor *gov;
++      char name[THERMAL_NAME_LENGTH];
++
++      snprintf(name, sizeof(name), "%s", buf);
+       mutex_lock(&thermal_governor_lock);
+-      gov = __find_governor(buf);
++      gov = __find_governor(strim(name));
+       if (!gov)
+               goto exit;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0928-Thermal-core-Ask-.get_trip_temp-to-register-thermal-.patch b/patches.tizen/0928-Thermal-core-Ask-.get_trip_temp-to-register-thermal-.patch
new file mode 100644 (file)
index 0000000..19b4130
--- /dev/null
@@ -0,0 +1,35 @@
+From c419ca70d382231230c46404ae74508abaa82a9d Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Sat, 18 May 2013 09:50:26 +0000
+Subject: [PATCH 0928/1302] Thermal: core: Ask .get_trip_temp() to register
+ thermal zone device.
+
+This patch adds a requirement needing .get_trip_temp() callback
+function for registering thermal zone device. This function is
+used when thermal zone is updated and essential where thermal core
+handles thermal trip based only polling way not hw interrupt.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+Acked-by: Durgadoss R <durgadoss.r@intel.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+---
+ drivers/thermal/thermal_core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
+index 4ab8f38..cd9faa8 100644
+--- a/drivers/thermal/thermal_core.c
++++ b/drivers/thermal/thermal_core.c
+@@ -1683,7 +1683,7 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
+       if (!ops || !ops->get_temp)
+               return ERR_PTR(-EINVAL);
+-      if (trips > 0 && !ops->get_trip_type)
++      if (trips > 0 && (!ops->get_trip_type || !ops->get_trip_temp))
+               return ERR_PTR(-EINVAL);
+       tz = kzalloc(sizeof(struct thermal_zone_device), GFP_KERNEL);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0929-Thermal-don-t-check-resource-with-devm_ioremap_resou.patch b/patches.tizen/0929-Thermal-don-t-check-resource-with-devm_ioremap_resou.patch
new file mode 100644 (file)
index 0000000..56896d6
--- /dev/null
@@ -0,0 +1,47 @@
+From 75ec37bf54368b27721c2b5dcd73303f8ca6e0a9 Mon Sep 17 00:00:00 2001
+From: Zhang Rui <rui.zhang@intel.com>
+Date: Thu, 16 May 2013 02:16:21 +0000
+Subject: [PATCH 0929/1302] Thermal: don't check resource with
+ devm_ioremap_resource
+
+devm_ioremap_resource does sanity checks on the given resource.
+No need to duplicate this in the driver.
+
+CC: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+CC: Vincenzo Frascino <vincenzo.frascino@st.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Acked-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/spear_thermal.c | 13 +++----------
+ 1 file changed, 3 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/thermal/spear_thermal.c b/drivers/thermal/spear_thermal.c
+index 1b652ab..813add6 100644
+--- a/drivers/thermal/spear_thermal.c
++++ b/drivers/thermal/spear_thermal.c
+@@ -118,18 +118,11 @@ static int spear_thermal_probe(struct platform_device *pdev)
+               return -ENOMEM;
+       }
+-      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-      if (!res) {
+-              dev_err(&pdev->dev, "memory resource missing\n");
+-              return -ENODEV;
+-      }
+-
+       /* Enable thermal sensor */
+-      stdev->thermal_base = devm_ioremap_resource(dev, res);
+-      if (IS_ERR(stdev->thermal_base)) {
+-              dev_err(&pdev->dev, "ioremap failed\n");
++      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      stdev->thermal_base = devm_ioremap_resource(&pdev->dev, res);
++      if (IS_ERR(stdev->thermal_base))
+               return PTR_ERR(stdev->thermal_base);
+-      }
+       stdev->clk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(stdev->clk)) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0930-thermal-introduce-TI-SoC-thermal-driver.patch b/patches.tizen/0930-thermal-introduce-TI-SoC-thermal-driver.patch
new file mode 100644 (file)
index 0000000..fc295d6
--- /dev/null
@@ -0,0 +1,3642 @@
+From 8e5d1edccfd05a5ce7295adc174f6c02229a8da2 Mon Sep 17 00:00:00 2001
+From: Eduardo Valentin <eduardo.valentin@ti.com>
+Date: Wed, 15 May 2013 15:46:00 +0000
+Subject: [PATCH 0930/1302] thermal: introduce TI SoC thermal driver
+
+This patch moves the ti-soc-thermal driver out of
+the staging tree to the thermal tree.
+
+Cc: Grant Likely <grant.likely@linaro.org>
+Cc: Rob Herring <rob.herring@calxeda.com>
+Cc: Rob Landley <rob@landley.net>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Zhang Rui <rui.zhang@intel.com>
+Cc: Eduardo Valentin <eduardo.valentin@ti.com>
+Cc: J Keerthy <j-keerthy@ti.com>
+Cc: Radhesh Fadnis <radhesh.fadnis@ti.com>
+Cc: Cyril Roelandt <tipecaml@gmail.com>
+Cc: devicetree-discuss@lists.ozlabs.org
+Cc: linux-doc@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Cc: devel@driverdev.osuosl.org
+Cc: linux-pm@vger.kernel.org
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/Kconfig                            |    3 +
+ drivers/thermal/Makefile                           |    2 +-
+ drivers/thermal/ti-soc-thermal/Kconfig             |   48 +
+ drivers/thermal/ti-soc-thermal/Makefile            |    5 +
+ drivers/thermal/ti-soc-thermal/TODO                |   12 +
+ .../thermal/ti-soc-thermal/omap4-thermal-data.c    |  267 ++++
+ drivers/thermal/ti-soc-thermal/omap4xxx-bandgap.h  |  175 +++
+ .../thermal/ti-soc-thermal/omap5-thermal-data.c    |  359 +++++
+ drivers/thermal/ti-soc-thermal/omap5xxx-bandgap.h  |  200 +++
+ drivers/thermal/ti-soc-thermal/ti-bandgap.c        | 1546 ++++++++++++++++++++
+ drivers/thermal/ti-soc-thermal/ti-bandgap.h        |  403 +++++
+ drivers/thermal/ti-soc-thermal/ti-thermal-common.c |  367 +++++
+ drivers/thermal/ti-soc-thermal/ti-thermal.h        |  117 ++
+ 13 files changed, 3503 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/thermal/ti-soc-thermal/Kconfig
+ create mode 100644 drivers/thermal/ti-soc-thermal/Makefile
+ create mode 100644 drivers/thermal/ti-soc-thermal/TODO
+ create mode 100644 drivers/thermal/ti-soc-thermal/omap4-thermal-data.c
+ create mode 100644 drivers/thermal/ti-soc-thermal/omap4xxx-bandgap.h
+ create mode 100644 drivers/thermal/ti-soc-thermal/omap5-thermal-data.c
+ create mode 100644 drivers/thermal/ti-soc-thermal/omap5xxx-bandgap.h
+ create mode 100644 drivers/thermal/ti-soc-thermal/ti-bandgap.c
+ create mode 100644 drivers/thermal/ti-soc-thermal/ti-bandgap.h
+ create mode 100644 drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+ create mode 100644 drivers/thermal/ti-soc-thermal/ti-thermal.h
+
+diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
+index 5e3c025..7205c70 100644
+--- a/drivers/thermal/Kconfig
++++ b/drivers/thermal/Kconfig
+@@ -169,4 +169,7 @@ config INTEL_POWERCLAMP
+         enforce idle time which results in more package C-state residency. The
+         user interface is exposed via generic thermal framework.
++menu "Texas Instruments thermal drivers"
++source "drivers/thermal/ti-soc-thermal/Kconfig"
++endmenu
+ endif
+diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
+index c054d41..8569394 100644
+--- a/drivers/thermal/Makefile
++++ b/drivers/thermal/Makefile
+@@ -23,4 +23,4 @@ obj-$(CONFIG_DB8500_THERMAL) += db8500_thermal.o
+ obj-$(CONFIG_ARMADA_THERMAL)  += armada_thermal.o
+ obj-$(CONFIG_DB8500_CPUFREQ_COOLING)  += db8500_cpufreq_cooling.o
+ obj-$(CONFIG_INTEL_POWERCLAMP)        += intel_powerclamp.o
+-
++obj-$(CONFIG_TI_SOC_THERMAL)  += ti-soc-thermal/
+diff --git a/drivers/thermal/ti-soc-thermal/Kconfig b/drivers/thermal/ti-soc-thermal/Kconfig
+new file mode 100644
+index 0000000..e81375f
+--- /dev/null
++++ b/drivers/thermal/ti-soc-thermal/Kconfig
+@@ -0,0 +1,48 @@
++config TI_SOC_THERMAL
++      tristate "Texas Instruments SoCs temperature sensor driver"
++      depends on THERMAL
++      depends on ARCH_HAS_BANDGAP
++      help
++        If you say yes here you get support for the Texas Instruments
++        OMAP4460+ on die bandgap temperature sensor support. The register
++        set is part of system control module.
++
++        This includes alert interrupts generation and also the TSHUT
++        support.
++
++config TI_THERMAL
++      bool "Texas Instruments SoCs thermal framework support"
++      depends on TI_SOC_THERMAL
++      depends on CPU_THERMAL
++      help
++        If you say yes here you want to get support for generic thermal
++        framework for the Texas Instruments on die bandgap temperature sensor.
++
++        This includes trip points definitions, extrapolation rules and
++        CPU cooling device bindings.
++
++config OMAP4_THERMAL
++      bool "Texas Instruments OMAP4 thermal support"
++      depends on TI_SOC_THERMAL
++      depends on ARCH_OMAP4
++      help
++        If you say yes here you get thermal support for the Texas Instruments
++        OMAP4 SoC family. The current chip supported are:
++         - OMAP4430
++         - OMAP4460
++         - OMAP4470
++
++        This includes alert interrupts generation and also the TSHUT
++        support.
++
++config OMAP5_THERMAL
++      bool "Texas Instruments OMAP5 thermal support"
++      depends on TI_SOC_THERMAL
++      depends on SOC_OMAP5
++      help
++        If you say yes here you get thermal support for the Texas Instruments
++        OMAP5 SoC family. The current chip supported are:
++         - OMAP5430
++
++        This includes alert interrupts generation and also the TSHUT
++        support.
+diff --git a/drivers/thermal/ti-soc-thermal/Makefile b/drivers/thermal/ti-soc-thermal/Makefile
+new file mode 100644
+index 0000000..0ca034f
+--- /dev/null
++++ b/drivers/thermal/ti-soc-thermal/Makefile
+@@ -0,0 +1,5 @@
++obj-$(CONFIG_TI_SOC_THERMAL)          += ti-soc-thermal.o
++ti-soc-thermal-y                      := ti-bandgap.o
++ti-soc-thermal-$(CONFIG_TI_THERMAL)   += ti-thermal-common.o
++ti-soc-thermal-$(CONFIG_OMAP4_THERMAL)        += omap4-thermal-data.o
++ti-soc-thermal-$(CONFIG_OMAP5_THERMAL)        += omap5-thermal-data.o
+diff --git a/drivers/thermal/ti-soc-thermal/TODO b/drivers/thermal/ti-soc-thermal/TODO
+new file mode 100644
+index 0000000..7da787d
+--- /dev/null
++++ b/drivers/thermal/ti-soc-thermal/TODO
+@@ -0,0 +1,12 @@
++List of TODOs (by Eduardo Valentin)
++
++on ti-bandgap.c:
++- Revisit PM support
++
++on ti-thermal-common.c/ti-thermal.h:
++- Revisit need for locking
++
++generally:
++- make sure this code works on OMAP4430, OMAP4460 and OMAP5430
++
++Copy patches to Eduardo Valentin <eduardo.valentin@ti.com>
+diff --git a/drivers/thermal/ti-soc-thermal/omap4-thermal-data.c b/drivers/thermal/ti-soc-thermal/omap4-thermal-data.c
+new file mode 100644
+index 0000000..d255d33
+--- /dev/null
++++ b/drivers/thermal/ti-soc-thermal/omap4-thermal-data.c
+@@ -0,0 +1,267 @@
++/*
++ * OMAP4 thermal driver.
++ *
++ * Copyright (C) 2011-2012 Texas Instruments Inc.
++ * Contact:
++ *    Eduardo Valentin <eduardo.valentin@ti.com>
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include "ti-thermal.h"
++#include "ti-bandgap.h"
++#include "omap4xxx-bandgap.h"
++
++/*
++ * OMAP4430 has one instance of thermal sensor for MPU
++ * need to describe the individual bit fields
++ */
++static struct temp_sensor_registers
++omap4430_mpu_temp_sensor_registers = {
++      .temp_sensor_ctrl = OMAP4430_TEMP_SENSOR_CTRL_OFFSET,
++      .bgap_tempsoff_mask = OMAP4430_BGAP_TEMPSOFF_MASK,
++      .bgap_soc_mask = OMAP4430_BGAP_TEMP_SENSOR_SOC_MASK,
++      .bgap_eocz_mask = OMAP4430_BGAP_TEMP_SENSOR_EOCZ_MASK,
++      .bgap_dtemp_mask = OMAP4430_BGAP_TEMP_SENSOR_DTEMP_MASK,
++
++      .bgap_mode_ctrl = OMAP4430_TEMP_SENSOR_CTRL_OFFSET,
++      .mode_ctrl_mask = OMAP4430_SINGLE_MODE_MASK,
++
++      .bgap_efuse = OMAP4430_FUSE_OPP_BGAP,
++};
++
++/* Thresholds and limits for OMAP4430 MPU temperature sensor */
++static struct temp_sensor_data omap4430_mpu_temp_sensor_data = {
++      .min_freq = OMAP4430_MIN_FREQ,
++      .max_freq = OMAP4430_MAX_FREQ,
++      .max_temp = OMAP4430_MAX_TEMP,
++      .min_temp = OMAP4430_MIN_TEMP,
++      .hyst_val = OMAP4430_HYST_VAL,
++};
++
++/*
++ * Temperature values in milli degree celsius
++ * ADC code values from 530 to 923
++ */
++static const int
++omap4430_adc_to_temp[OMAP4430_ADC_END_VALUE - OMAP4430_ADC_START_VALUE + 1] = {
++      -38000, -35000, -34000, -32000, -30000, -28000, -26000, -24000, -22000,
++      -20000, -18000, -17000, -15000, -13000, -12000, -10000, -8000, -6000,
++      -5000, -3000, -1000, 0, 2000, 3000, 5000, 6000, 8000, 10000, 12000,
++      13000, 15000, 17000, 19000, 21000, 23000, 25000, 27000, 28000, 30000,
++      32000, 33000, 35000, 37000, 38000, 40000, 42000, 43000, 45000, 47000,
++      48000, 50000, 52000, 53000, 55000, 57000, 58000, 60000, 62000, 64000,
++      66000, 68000, 70000, 71000, 73000, 75000, 77000, 78000, 80000, 82000,
++      83000, 85000, 87000, 88000, 90000, 92000, 93000, 95000, 97000, 98000,
++      100000, 102000, 103000, 105000, 107000, 109000, 111000, 113000, 115000,
++      117000, 118000, 120000, 122000, 123000,
++};
++
++/* OMAP4430 data */
++const struct ti_bandgap_data omap4430_data = {
++      .features = TI_BANDGAP_FEATURE_MODE_CONFIG |
++                      TI_BANDGAP_FEATURE_CLK_CTRL |
++                      TI_BANDGAP_FEATURE_POWER_SWITCH,
++      .fclock_name = "bandgap_fclk",
++      .div_ck_name = "bandgap_fclk",
++      .conv_table = omap4430_adc_to_temp,
++      .adc_start_val = OMAP4430_ADC_START_VALUE,
++      .adc_end_val = OMAP4430_ADC_END_VALUE,
++      .expose_sensor = ti_thermal_expose_sensor,
++      .remove_sensor = ti_thermal_remove_sensor,
++      .sensors = {
++              {
++              .registers = &omap4430_mpu_temp_sensor_registers,
++              .ts_data = &omap4430_mpu_temp_sensor_data,
++              .domain = "cpu",
++              .slope = OMAP_GRADIENT_SLOPE_4430,
++              .constant = OMAP_GRADIENT_CONST_4430,
++              .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_4430,
++              .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_4430,
++              .register_cooling = ti_thermal_register_cpu_cooling,
++              .unregister_cooling = ti_thermal_unregister_cpu_cooling,
++              },
++      },
++      .sensor_count = 1,
++};
++/*
++ * OMAP4460 has one instance of thermal sensor for MPU
++ * need to describe the individual bit fields
++ */
++static struct temp_sensor_registers
++omap4460_mpu_temp_sensor_registers = {
++      .temp_sensor_ctrl = OMAP4460_TEMP_SENSOR_CTRL_OFFSET,
++      .bgap_tempsoff_mask = OMAP4460_BGAP_TEMPSOFF_MASK,
++      .bgap_soc_mask = OMAP4460_BGAP_TEMP_SENSOR_SOC_MASK,
++      .bgap_eocz_mask = OMAP4460_BGAP_TEMP_SENSOR_EOCZ_MASK,
++      .bgap_dtemp_mask = OMAP4460_BGAP_TEMP_SENSOR_DTEMP_MASK,
++
++      .bgap_mask_ctrl = OMAP4460_BGAP_CTRL_OFFSET,
++      .mask_hot_mask = OMAP4460_MASK_HOT_MASK,
++      .mask_cold_mask = OMAP4460_MASK_COLD_MASK,
++
++      .bgap_mode_ctrl = OMAP4460_BGAP_CTRL_OFFSET,
++      .mode_ctrl_mask = OMAP4460_SINGLE_MODE_MASK,
++
++      .bgap_counter = OMAP4460_BGAP_COUNTER_OFFSET,
++      .counter_mask = OMAP4460_COUNTER_MASK,
++
++      .bgap_threshold = OMAP4460_BGAP_THRESHOLD_OFFSET,
++      .threshold_thot_mask = OMAP4460_T_HOT_MASK,
++      .threshold_tcold_mask = OMAP4460_T_COLD_MASK,
++
++      .tshut_threshold = OMAP4460_BGAP_TSHUT_OFFSET,
++      .tshut_hot_mask = OMAP4460_TSHUT_HOT_MASK,
++      .tshut_cold_mask = OMAP4460_TSHUT_COLD_MASK,
++
++      .bgap_status = OMAP4460_BGAP_STATUS_OFFSET,
++      .status_clean_stop_mask = OMAP4460_CLEAN_STOP_MASK,
++      .status_bgap_alert_mask = OMAP4460_BGAP_ALERT_MASK,
++      .status_hot_mask = OMAP4460_HOT_FLAG_MASK,
++      .status_cold_mask = OMAP4460_COLD_FLAG_MASK,
++
++      .bgap_efuse = OMAP4460_FUSE_OPP_BGAP,
++};
++
++/* Thresholds and limits for OMAP4460 MPU temperature sensor */
++static struct temp_sensor_data omap4460_mpu_temp_sensor_data = {
++      .tshut_hot = OMAP4460_TSHUT_HOT,
++      .tshut_cold = OMAP4460_TSHUT_COLD,
++      .t_hot = OMAP4460_T_HOT,
++      .t_cold = OMAP4460_T_COLD,
++      .min_freq = OMAP4460_MIN_FREQ,
++      .max_freq = OMAP4460_MAX_FREQ,
++      .max_temp = OMAP4460_MAX_TEMP,
++      .min_temp = OMAP4460_MIN_TEMP,
++      .hyst_val = OMAP4460_HYST_VAL,
++      .update_int1 = 1000,
++      .update_int2 = 2000,
++};
++
++/*
++ * Temperature values in milli degree celsius
++ * ADC code values from 530 to 923
++ */
++static const int
++omap4460_adc_to_temp[OMAP4460_ADC_END_VALUE - OMAP4460_ADC_START_VALUE + 1] = {
++      -40000, -40000, -40000, -40000, -39800, -39400, -39000, -38600, -38200,
++      -37800, -37300, -36800, -36400, -36000, -35600, -35200, -34800,
++      -34300, -33800, -33400, -33000, -32600, -32200, -31800, -31300,
++      -30800, -30400, -30000, -29600, -29200, -28700, -28200, -27800,
++      -27400, -27000, -26600, -26200, -25700, -25200, -24800, -24400,
++      -24000, -23600, -23200, -22700, -22200, -21800, -21400, -21000,
++      -20600, -20200, -19700, -19200, -18800, -18400, -18000, -17600,
++      -17200, -16700, -16200, -15800, -15400, -15000, -14600, -14200,
++      -13700, -13200, -12800, -12400, -12000, -11600, -11200, -10700,
++      -10200, -9800, -9400, -9000, -8600, -8200, -7700, -7200, -6800,
++      -6400, -6000, -5600, -5200, -4800, -4300, -3800, -3400, -3000,
++      -2600, -2200, -1800, -1300, -800, -400, 0, 400, 800, 1200, 1600,
++      2100, 2600, 3000, 3400, 3800, 4200, 4600, 5100, 5600, 6000, 6400,
++      6800, 7200, 7600, 8000, 8500, 9000, 9400, 9800, 10200, 10600, 11000,
++      11400, 11900, 12400, 12800, 13200, 13600, 14000, 14400, 14800,
++      15300, 15800, 16200, 16600, 17000, 17400, 17800, 18200, 18700,
++      19200, 19600, 20000, 20400, 20800, 21200, 21600, 22100, 22600,
++      23000, 23400, 23800, 24200, 24600, 25000, 25400, 25900, 26400,
++      26800, 27200, 27600, 28000, 28400, 28800, 29300, 29800, 30200,
++      30600, 31000, 31400, 31800, 32200, 32600, 33100, 33600, 34000,
++      34400, 34800, 35200, 35600, 36000, 36400, 36800, 37300, 37800,
++      38200, 38600, 39000, 39400, 39800, 40200, 40600, 41100, 41600,
++      42000, 42400, 42800, 43200, 43600, 44000, 44400, 44800, 45300,
++      45800, 46200, 46600, 47000, 47400, 47800, 48200, 48600, 49000,
++      49500, 50000, 50400, 50800, 51200, 51600, 52000, 52400, 52800,
++      53200, 53700, 54200, 54600, 55000, 55400, 55800, 56200, 56600,
++      57000, 57400, 57800, 58200, 58700, 59200, 59600, 60000, 60400,
++      60800, 61200, 61600, 62000, 62400, 62800, 63300, 63800, 64200,
++      64600, 65000, 65400, 65800, 66200, 66600, 67000, 67400, 67800,
++      68200, 68700, 69200, 69600, 70000, 70400, 70800, 71200, 71600,
++      72000, 72400, 72800, 73200, 73600, 74100, 74600, 75000, 75400,
++      75800, 76200, 76600, 77000, 77400, 77800, 78200, 78600, 79000,
++      79400, 79800, 80300, 80800, 81200, 81600, 82000, 82400, 82800,
++      83200, 83600, 84000, 84400, 84800, 85200, 85600, 86000, 86400,
++      86800, 87300, 87800, 88200, 88600, 89000, 89400, 89800, 90200,
++      90600, 91000, 91400, 91800, 92200, 92600, 93000, 93400, 93800,
++      94200, 94600, 95000, 95500, 96000, 96400, 96800, 97200, 97600,
++      98000, 98400, 98800, 99200, 99600, 100000, 100400, 100800, 101200,
++      101600, 102000, 102400, 102800, 103200, 103600, 104000, 104400,
++      104800, 105200, 105600, 106100, 106600, 107000, 107400, 107800,
++      108200, 108600, 109000, 109400, 109800, 110200, 110600, 111000,
++      111400, 111800, 112200, 112600, 113000, 113400, 113800, 114200,
++      114600, 115000, 115400, 115800, 116200, 116600, 117000, 117400,
++      117800, 118200, 118600, 119000, 119400, 119800, 120200, 120600,
++      121000, 121400, 121800, 122200, 122600, 123000, 123400, 123800, 124200,
++      124600, 124900, 125000, 125000, 125000, 125000
++};
++
++/* OMAP4460 data */
++const struct ti_bandgap_data omap4460_data = {
++      .features = TI_BANDGAP_FEATURE_TSHUT |
++                      TI_BANDGAP_FEATURE_TSHUT_CONFIG |
++                      TI_BANDGAP_FEATURE_TALERT |
++                      TI_BANDGAP_FEATURE_MODE_CONFIG |
++                      TI_BANDGAP_FEATURE_POWER_SWITCH |
++                      TI_BANDGAP_FEATURE_CLK_CTRL |
++                      TI_BANDGAP_FEATURE_COUNTER,
++      .fclock_name = "bandgap_ts_fclk",
++      .div_ck_name = "div_ts_ck",
++      .conv_table = omap4460_adc_to_temp,
++      .adc_start_val = OMAP4460_ADC_START_VALUE,
++      .adc_end_val = OMAP4460_ADC_END_VALUE,
++      .expose_sensor = ti_thermal_expose_sensor,
++      .remove_sensor = ti_thermal_remove_sensor,
++      .report_temperature = ti_thermal_report_sensor_temperature,
++      .sensors = {
++              {
++              .registers = &omap4460_mpu_temp_sensor_registers,
++              .ts_data = &omap4460_mpu_temp_sensor_data,
++              .domain = "cpu",
++              .slope = OMAP_GRADIENT_SLOPE_4460,
++              .constant = OMAP_GRADIENT_CONST_4460,
++              .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_4460,
++              .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_4460,
++              .register_cooling = ti_thermal_register_cpu_cooling,
++              .unregister_cooling = ti_thermal_unregister_cpu_cooling,
++              },
++      },
++      .sensor_count = 1,
++};
++
++/* OMAP4470 data */
++const struct ti_bandgap_data omap4470_data = {
++      .features = TI_BANDGAP_FEATURE_TSHUT |
++                      TI_BANDGAP_FEATURE_TSHUT_CONFIG |
++                      TI_BANDGAP_FEATURE_TALERT |
++                      TI_BANDGAP_FEATURE_MODE_CONFIG |
++                      TI_BANDGAP_FEATURE_POWER_SWITCH |
++                      TI_BANDGAP_FEATURE_CLK_CTRL |
++                      TI_BANDGAP_FEATURE_COUNTER,
++      .fclock_name = "bandgap_ts_fclk",
++      .div_ck_name = "div_ts_ck",
++      .conv_table = omap4460_adc_to_temp,
++      .adc_start_val = OMAP4460_ADC_START_VALUE,
++      .adc_end_val = OMAP4460_ADC_END_VALUE,
++      .expose_sensor = ti_thermal_expose_sensor,
++      .remove_sensor = ti_thermal_remove_sensor,
++      .report_temperature = ti_thermal_report_sensor_temperature,
++      .sensors = {
++              {
++              .registers = &omap4460_mpu_temp_sensor_registers,
++              .ts_data = &omap4460_mpu_temp_sensor_data,
++              .domain = "cpu",
++              .slope = OMAP_GRADIENT_SLOPE_4470,
++              .constant = OMAP_GRADIENT_CONST_4470,
++              .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_4470,
++              .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_4470,
++              .register_cooling = ti_thermal_register_cpu_cooling,
++              .unregister_cooling = ti_thermal_unregister_cpu_cooling,
++              },
++      },
++      .sensor_count = 1,
++};
+diff --git a/drivers/thermal/ti-soc-thermal/omap4xxx-bandgap.h b/drivers/thermal/ti-soc-thermal/omap4xxx-bandgap.h
+new file mode 100644
+index 0000000..6f2de3a
+--- /dev/null
++++ b/drivers/thermal/ti-soc-thermal/omap4xxx-bandgap.h
+@@ -0,0 +1,175 @@
++/*
++ * OMAP4xxx bandgap registers, bitfields and temperature definitions
++ *
++ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
++ * Contact:
++ *   Eduardo Valentin <eduardo.valentin@ti.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
++ * 02110-1301 USA
++ *
++ */
++#ifndef __OMAP4XXX_BANDGAP_H
++#define __OMAP4XXX_BANDGAP_H
++
++/**
++ * *** OMAP4430 ***
++ *
++ * Below, in sequence, are the Register definitions,
++ * the bitfields and the temperature definitions for OMAP4430.
++ */
++
++/**
++ * OMAP4430 register definitions
++ *
++ * Registers are defined as offsets. The offsets are
++ * relative to FUSE_OPP_BGAP on 4430.
++ */
++
++/* OMAP4430.FUSE_OPP_BGAP */
++#define OMAP4430_FUSE_OPP_BGAP                                0x0
++
++/* OMAP4430.TEMP_SENSOR  */
++#define OMAP4430_TEMP_SENSOR_CTRL_OFFSET              0xCC
++
++/**
++ * Register and bit definitions for OMAP4430
++ *
++ * All the macros bellow define the required bits for
++ * controlling temperature on OMAP4430. Bit defines are
++ * grouped by register.
++ */
++
++/* OMAP4430.TEMP_SENSOR bits */
++#define OMAP4430_BGAP_TEMPSOFF_MASK                   BIT(12)
++#define OMAP4430_BGAP_TSHUT_MASK                      BIT(11)
++#define OMAP4430_SINGLE_MODE_MASK                     BIT(10)
++#define OMAP4430_BGAP_TEMP_SENSOR_SOC_MASK            BIT(9)
++#define OMAP4430_BGAP_TEMP_SENSOR_EOCZ_MASK           BIT(8)
++#define OMAP4430_BGAP_TEMP_SENSOR_DTEMP_MASK          (0xff << 0)
++
++/**
++ * Temperature limits and thresholds for OMAP4430
++ *
++ * All the macros bellow are definitions for handling the
++ * ADC conversions and representation of temperature limits
++ * and thresholds for OMAP4430.
++ */
++
++/* ADC conversion table limits */
++#define OMAP4430_ADC_START_VALUE                      0
++#define OMAP4430_ADC_END_VALUE                                127
++/* bandgap clock limits (no control on 4430) */
++#define OMAP4430_MAX_FREQ                             32768
++#define OMAP4430_MIN_FREQ                             32768
++/* sensor limits */
++#define OMAP4430_MIN_TEMP                             -40000
++#define OMAP4430_MAX_TEMP                             125000
++#define OMAP4430_HYST_VAL                             5000
++
++/**
++ * *** OMAP4460 *** Applicable for OMAP4470
++ *
++ * Below, in sequence, are the Register definitions,
++ * the bitfields and the temperature definitions for OMAP4460.
++ */
++
++/**
++ * OMAP4460 register definitions
++ *
++ * Registers are defined as offsets. The offsets are
++ * relative to FUSE_OPP_BGAP on 4460.
++ */
++
++/* OMAP4460.FUSE_OPP_BGAP */
++#define OMAP4460_FUSE_OPP_BGAP                                0x0
++
++/* OMAP4460.TEMP_SENSOR */
++#define OMAP4460_TEMP_SENSOR_CTRL_OFFSET              0xCC
++
++/* OMAP4460.BANDGAP_CTRL */
++#define OMAP4460_BGAP_CTRL_OFFSET                     0x118
++
++/* OMAP4460.BANDGAP_COUNTER */
++#define OMAP4460_BGAP_COUNTER_OFFSET                  0x11C
++
++/* OMAP4460.BANDGAP_THRESHOLD */
++#define OMAP4460_BGAP_THRESHOLD_OFFSET                        0x120
++
++/* OMAP4460.TSHUT_THRESHOLD */
++#define OMAP4460_BGAP_TSHUT_OFFSET                    0x124
++
++/* OMAP4460.BANDGAP_STATUS */
++#define OMAP4460_BGAP_STATUS_OFFSET                   0x128
++
++/**
++ * Register bitfields for OMAP4460
++ *
++ * All the macros bellow define the required bits for
++ * controlling temperature on OMAP4460. Bit defines are
++ * grouped by register.
++ */
++/* OMAP4460.TEMP_SENSOR bits */
++#define OMAP4460_BGAP_TEMPSOFF_MASK                   BIT(13)
++#define OMAP4460_BGAP_TEMP_SENSOR_SOC_MASK            BIT(11)
++#define OMAP4460_BGAP_TEMP_SENSOR_EOCZ_MASK           BIT(10)
++#define OMAP4460_BGAP_TEMP_SENSOR_DTEMP_MASK          (0x3ff << 0)
++
++/* OMAP4460.BANDGAP_CTRL bits */
++#define OMAP4460_SINGLE_MODE_MASK                     BIT(31)
++#define OMAP4460_MASK_HOT_MASK                                BIT(1)
++#define OMAP4460_MASK_COLD_MASK                               BIT(0)
++
++/* OMAP4460.BANDGAP_COUNTER bits */
++#define OMAP4460_COUNTER_MASK                         (0xffffff << 0)
++
++/* OMAP4460.BANDGAP_THRESHOLD bits */
++#define OMAP4460_T_HOT_MASK                           (0x3ff << 16)
++#define OMAP4460_T_COLD_MASK                          (0x3ff << 0)
++
++/* OMAP4460.TSHUT_THRESHOLD bits */
++#define OMAP4460_TSHUT_HOT_MASK                               (0x3ff << 16)
++#define OMAP4460_TSHUT_COLD_MASK                      (0x3ff << 0)
++
++/* OMAP4460.BANDGAP_STATUS bits */
++#define OMAP4460_CLEAN_STOP_MASK                      BIT(3)
++#define OMAP4460_BGAP_ALERT_MASK                      BIT(2)
++#define OMAP4460_HOT_FLAG_MASK                                BIT(1)
++#define OMAP4460_COLD_FLAG_MASK                               BIT(0)
++
++/**
++ * Temperature limits and thresholds for OMAP4460
++ *
++ * All the macros bellow are definitions for handling the
++ * ADC conversions and representation of temperature limits
++ * and thresholds for OMAP4460.
++ */
++
++/* ADC conversion table limits */
++#define OMAP4460_ADC_START_VALUE                      530
++#define OMAP4460_ADC_END_VALUE                                932
++/* bandgap clock limits */
++#define OMAP4460_MAX_FREQ                             1500000
++#define OMAP4460_MIN_FREQ                             1000000
++/* sensor limits */
++#define OMAP4460_MIN_TEMP                             -40000
++#define OMAP4460_MAX_TEMP                             123000
++#define OMAP4460_HYST_VAL                             5000
++/* interrupts thresholds */
++#define OMAP4460_TSHUT_HOT                            900     /* 122 deg C */
++#define OMAP4460_TSHUT_COLD                           895     /* 100 deg C */
++#define OMAP4460_T_HOT                                        800     /* 73 deg C */
++#define OMAP4460_T_COLD                                       795     /* 71 deg C */
++
++#endif /* __OMAP4XXX_BANDGAP_H */
+diff --git a/drivers/thermal/ti-soc-thermal/omap5-thermal-data.c b/drivers/thermal/ti-soc-thermal/omap5-thermal-data.c
+new file mode 100644
+index 0000000..eff0c80
+--- /dev/null
++++ b/drivers/thermal/ti-soc-thermal/omap5-thermal-data.c
+@@ -0,0 +1,359 @@
++/*
++ * OMAP5 thermal driver.
++ *
++ * Copyright (C) 2011-2012 Texas Instruments Inc.
++ * Contact:
++ *    Eduardo Valentin <eduardo.valentin@ti.com>
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include "ti-thermal.h"
++#include "ti-bandgap.h"
++#include "omap5xxx-bandgap.h"
++
++/*
++ * OMAP5430 has three instances of thermal sensor for MPU, GPU & CORE,
++ * need to describe the individual registers and bit fields.
++ */
++
++/*
++ * OMAP5430 MPU thermal sensor register offset and bit-fields
++ */
++static struct temp_sensor_registers
++omap5430_mpu_temp_sensor_registers = {
++      .temp_sensor_ctrl = OMAP5430_TEMP_SENSOR_MPU_OFFSET,
++      .bgap_tempsoff_mask = OMAP5430_BGAP_TEMPSOFF_MASK,
++      .bgap_eocz_mask = OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK,
++      .bgap_dtemp_mask = OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK,
++
++      .bgap_mask_ctrl = OMAP5430_BGAP_CTRL_OFFSET,
++      .mask_hot_mask = OMAP5430_MASK_HOT_MPU_MASK,
++      .mask_cold_mask = OMAP5430_MASK_COLD_MPU_MASK,
++      .mask_sidlemode_mask = OMAP5430_MASK_SIDLEMODE_MASK,
++      .mask_counter_delay_mask = OMAP5430_MASK_COUNTER_DELAY_MASK,
++      .mask_freeze_mask = OMAP5430_MASK_FREEZE_MPU_MASK,
++      .mask_clear_mask = OMAP5430_MASK_CLEAR_MPU_MASK,
++      .mask_clear_accum_mask = OMAP5430_MASK_CLEAR_ACCUM_MPU_MASK,
++
++
++      .bgap_counter = OMAP5430_BGAP_CTRL_OFFSET,
++      .counter_mask = OMAP5430_COUNTER_MASK,
++
++      .bgap_threshold = OMAP5430_BGAP_THRESHOLD_MPU_OFFSET,
++      .threshold_thot_mask = OMAP5430_T_HOT_MASK,
++      .threshold_tcold_mask = OMAP5430_T_COLD_MASK,
++
++      .tshut_threshold = OMAP5430_BGAP_TSHUT_MPU_OFFSET,
++      .tshut_hot_mask = OMAP5430_TSHUT_HOT_MASK,
++      .tshut_cold_mask = OMAP5430_TSHUT_COLD_MASK,
++
++      .bgap_status = OMAP5430_BGAP_STATUS_OFFSET,
++      .status_clean_stop_mask = 0x0,
++      .status_bgap_alert_mask = OMAP5430_BGAP_ALERT_MASK,
++      .status_hot_mask = OMAP5430_HOT_MPU_FLAG_MASK,
++      .status_cold_mask = OMAP5430_COLD_MPU_FLAG_MASK,
++
++      .bgap_cumul_dtemp = OMAP5430_BGAP_CUMUL_DTEMP_MPU_OFFSET,
++      .ctrl_dtemp_0 = OMAP5430_BGAP_DTEMP_MPU_0_OFFSET,
++      .ctrl_dtemp_1 = OMAP5430_BGAP_DTEMP_MPU_1_OFFSET,
++      .ctrl_dtemp_2 = OMAP5430_BGAP_DTEMP_MPU_2_OFFSET,
++      .ctrl_dtemp_3 = OMAP5430_BGAP_DTEMP_MPU_3_OFFSET,
++      .ctrl_dtemp_4 = OMAP5430_BGAP_DTEMP_MPU_4_OFFSET,
++      .bgap_efuse = OMAP5430_FUSE_OPP_BGAP_MPU,
++};
++
++/*
++ * OMAP5430 GPU thermal sensor register offset and bit-fields
++ */
++static struct temp_sensor_registers
++omap5430_gpu_temp_sensor_registers = {
++      .temp_sensor_ctrl = OMAP5430_TEMP_SENSOR_GPU_OFFSET,
++      .bgap_tempsoff_mask = OMAP5430_BGAP_TEMPSOFF_MASK,
++      .bgap_eocz_mask = OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK,
++      .bgap_dtemp_mask = OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK,
++
++      .bgap_mask_ctrl = OMAP5430_BGAP_CTRL_OFFSET,
++      .mask_hot_mask = OMAP5430_MASK_HOT_GPU_MASK,
++      .mask_cold_mask = OMAP5430_MASK_COLD_GPU_MASK,
++      .mask_sidlemode_mask = OMAP5430_MASK_SIDLEMODE_MASK,
++      .mask_counter_delay_mask = OMAP5430_MASK_COUNTER_DELAY_MASK,
++      .mask_freeze_mask = OMAP5430_MASK_FREEZE_GPU_MASK,
++      .mask_clear_mask = OMAP5430_MASK_CLEAR_GPU_MASK,
++      .mask_clear_accum_mask = OMAP5430_MASK_CLEAR_ACCUM_GPU_MASK,
++
++      .bgap_counter = OMAP5430_BGAP_CTRL_OFFSET,
++      .counter_mask = OMAP5430_COUNTER_MASK,
++
++      .bgap_threshold = OMAP5430_BGAP_THRESHOLD_GPU_OFFSET,
++      .threshold_thot_mask = OMAP5430_T_HOT_MASK,
++      .threshold_tcold_mask = OMAP5430_T_COLD_MASK,
++
++      .tshut_threshold = OMAP5430_BGAP_TSHUT_GPU_OFFSET,
++      .tshut_hot_mask = OMAP5430_TSHUT_HOT_MASK,
++      .tshut_cold_mask = OMAP5430_TSHUT_COLD_MASK,
++
++      .bgap_status = OMAP5430_BGAP_STATUS_OFFSET,
++      .status_clean_stop_mask = 0x0,
++      .status_bgap_alert_mask = OMAP5430_BGAP_ALERT_MASK,
++      .status_hot_mask = OMAP5430_HOT_GPU_FLAG_MASK,
++      .status_cold_mask = OMAP5430_COLD_GPU_FLAG_MASK,
++
++      .bgap_cumul_dtemp = OMAP5430_BGAP_CUMUL_DTEMP_GPU_OFFSET,
++      .ctrl_dtemp_0 = OMAP5430_BGAP_DTEMP_GPU_0_OFFSET,
++      .ctrl_dtemp_1 = OMAP5430_BGAP_DTEMP_GPU_1_OFFSET,
++      .ctrl_dtemp_2 = OMAP5430_BGAP_DTEMP_GPU_2_OFFSET,
++      .ctrl_dtemp_3 = OMAP5430_BGAP_DTEMP_GPU_3_OFFSET,
++      .ctrl_dtemp_4 = OMAP5430_BGAP_DTEMP_GPU_4_OFFSET,
++
++      .bgap_efuse = OMAP5430_FUSE_OPP_BGAP_GPU,
++};
++
++/*
++ * OMAP5430 CORE thermal sensor register offset and bit-fields
++ */
++static struct temp_sensor_registers
++omap5430_core_temp_sensor_registers = {
++      .temp_sensor_ctrl = OMAP5430_TEMP_SENSOR_CORE_OFFSET,
++      .bgap_tempsoff_mask = OMAP5430_BGAP_TEMPSOFF_MASK,
++      .bgap_eocz_mask = OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK,
++      .bgap_dtemp_mask = OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK,
++
++      .bgap_mask_ctrl = OMAP5430_BGAP_CTRL_OFFSET,
++      .mask_hot_mask = OMAP5430_MASK_HOT_CORE_MASK,
++      .mask_cold_mask = OMAP5430_MASK_COLD_CORE_MASK,
++      .mask_sidlemode_mask = OMAP5430_MASK_SIDLEMODE_MASK,
++      .mask_counter_delay_mask = OMAP5430_MASK_COUNTER_DELAY_MASK,
++      .mask_freeze_mask = OMAP5430_MASK_FREEZE_CORE_MASK,
++      .mask_clear_mask = OMAP5430_MASK_CLEAR_CORE_MASK,
++      .mask_clear_accum_mask = OMAP5430_MASK_CLEAR_ACCUM_CORE_MASK,
++
++      .bgap_counter = OMAP5430_BGAP_CTRL_OFFSET,
++      .counter_mask = OMAP5430_COUNTER_MASK,
++
++      .bgap_threshold = OMAP5430_BGAP_THRESHOLD_CORE_OFFSET,
++      .threshold_thot_mask = OMAP5430_T_HOT_MASK,
++      .threshold_tcold_mask = OMAP5430_T_COLD_MASK,
++
++      .tshut_threshold = OMAP5430_BGAP_TSHUT_CORE_OFFSET,
++      .tshut_hot_mask = OMAP5430_TSHUT_HOT_MASK,
++      .tshut_cold_mask = OMAP5430_TSHUT_COLD_MASK,
++
++      .bgap_status = OMAP5430_BGAP_STATUS_OFFSET,
++      .status_clean_stop_mask = 0x0,
++      .status_bgap_alert_mask = OMAP5430_BGAP_ALERT_MASK,
++      .status_hot_mask = OMAP5430_HOT_CORE_FLAG_MASK,
++      .status_cold_mask = OMAP5430_COLD_CORE_FLAG_MASK,
++
++      .bgap_cumul_dtemp = OMAP5430_BGAP_CUMUL_DTEMP_CORE_OFFSET,
++      .ctrl_dtemp_0 = OMAP5430_BGAP_DTEMP_CORE_0_OFFSET,
++      .ctrl_dtemp_1 = OMAP5430_BGAP_DTEMP_CORE_1_OFFSET,
++      .ctrl_dtemp_2 = OMAP5430_BGAP_DTEMP_CORE_2_OFFSET,
++      .ctrl_dtemp_3 = OMAP5430_BGAP_DTEMP_CORE_3_OFFSET,
++      .ctrl_dtemp_4 = OMAP5430_BGAP_DTEMP_CORE_4_OFFSET,
++
++      .bgap_efuse = OMAP5430_FUSE_OPP_BGAP_CORE,
++};
++
++/* Thresholds and limits for OMAP5430 MPU temperature sensor */
++static struct temp_sensor_data omap5430_mpu_temp_sensor_data = {
++      .tshut_hot = OMAP5430_MPU_TSHUT_HOT,
++      .tshut_cold = OMAP5430_MPU_TSHUT_COLD,
++      .t_hot = OMAP5430_MPU_T_HOT,
++      .t_cold = OMAP5430_MPU_T_COLD,
++      .min_freq = OMAP5430_MPU_MIN_FREQ,
++      .max_freq = OMAP5430_MPU_MAX_FREQ,
++      .max_temp = OMAP5430_MPU_MAX_TEMP,
++      .min_temp = OMAP5430_MPU_MIN_TEMP,
++      .hyst_val = OMAP5430_MPU_HYST_VAL,
++      .update_int1 = 1000,
++      .update_int2 = 2000,
++};
++
++/* Thresholds and limits for OMAP5430 GPU temperature sensor */
++static struct temp_sensor_data omap5430_gpu_temp_sensor_data = {
++      .tshut_hot = OMAP5430_GPU_TSHUT_HOT,
++      .tshut_cold = OMAP5430_GPU_TSHUT_COLD,
++      .t_hot = OMAP5430_GPU_T_HOT,
++      .t_cold = OMAP5430_GPU_T_COLD,
++      .min_freq = OMAP5430_GPU_MIN_FREQ,
++      .max_freq = OMAP5430_GPU_MAX_FREQ,
++      .max_temp = OMAP5430_GPU_MAX_TEMP,
++      .min_temp = OMAP5430_GPU_MIN_TEMP,
++      .hyst_val = OMAP5430_GPU_HYST_VAL,
++      .update_int1 = 1000,
++      .update_int2 = 2000,
++};
++
++/* Thresholds and limits for OMAP5430 CORE temperature sensor */
++static struct temp_sensor_data omap5430_core_temp_sensor_data = {
++      .tshut_hot = OMAP5430_CORE_TSHUT_HOT,
++      .tshut_cold = OMAP5430_CORE_TSHUT_COLD,
++      .t_hot = OMAP5430_CORE_T_HOT,
++      .t_cold = OMAP5430_CORE_T_COLD,
++      .min_freq = OMAP5430_CORE_MIN_FREQ,
++      .max_freq = OMAP5430_CORE_MAX_FREQ,
++      .max_temp = OMAP5430_CORE_MAX_TEMP,
++      .min_temp = OMAP5430_CORE_MIN_TEMP,
++      .hyst_val = OMAP5430_CORE_HYST_VAL,
++      .update_int1 = 1000,
++      .update_int2 = 2000,
++};
++
++/*
++ * OMAP54xx ES2.0 : Temperature values in milli degree celsius
++ * ADC code values from 540 to 945
++ */
++static int
++omap5430_adc_to_temp[
++      OMAP5430_ADC_END_VALUE - OMAP5430_ADC_START_VALUE + 1] = {
++      /* Index 540 - 549 */
++      -40000, -40000, -40000, -40000, -39800, -39400, -39000, -38600, -38200,
++      -37800,
++      /* Index 550 - 559 */
++      -37400, -37000, -36600, -36200, -35800, -35300, -34700, -34200, -33800,
++      -33400,
++      /* Index 560 - 569 */
++      -33000, -32600, -32200, -31800, -31400, -31000, -30600, -30200, -29800,
++      -29400,
++      /* Index 570 - 579 */
++      -29000, -28600, -28200, -27700, -27100, -26600, -26200, -25800, -25400,
++      -25000,
++      /* Index 580 - 589 */
++      -24600, -24200, -23800, -23400, -23000, -22600, -22200, -21600, -21400,
++      -21000,
++      /* Index 590 - 599 */
++      -20500, -19900, -19400, -19000, -18600, -18200, -17800, -17400, -17000,
++      -16600,
++      /* Index 600 - 609 */
++      -16200, -15800, -15400, -15000, -14600, -14200, -13800, -13400, -13000,
++      -12500,
++      /* Index 610 - 619 */
++      -11900, -11400, -11000, -10600, -10200, -9800, -9400, -9000, -8600,
++      -8200,
++      /* Index 620 - 629 */
++      -7800, -7400, -7000, -6600, -6200, -5800, -5400, -5000, -4500, -3900,
++      /* Index 630 - 639 */
++      -3400, -3000, -2600, -2200, -1800, -1400, -1000, -600, -200, 200,
++      /* Index 640 - 649 */
++      600, 1000, 1400, 1800, 2200, 2600, 3000, 3400, 3900, 4500,
++      /* Index 650 - 659 */
++      5000, 5400, 5800, 6200, 6600, 7000, 7400, 7800, 8200, 8600,
++      /* Index 660 - 669 */
++      9000, 9400, 9800, 10200, 10600, 11000, 11400, 11800, 12200, 12700,
++      /* Index 670 - 679 */
++      13300, 13800, 14200, 14600, 15000, 15400, 15800, 16200, 16600, 17000,
++      /* Index 680 - 689 */
++      17400, 17800, 18200, 18600, 19000, 19400, 19800, 20200, 20600, 21100,
++      /* Index 690 - 699 */
++      21400, 21900, 22500, 23000, 23400, 23800, 24200, 24600, 25000, 25400,
++      /* Index 700 - 709 */
++      25800, 26200, 26600, 27000, 27400, 27800, 28200, 28600, 29000, 29400,
++      /* Index 710 - 719 */
++      29800, 30200, 30600, 31000, 31400, 31900, 32500, 33000, 33400, 33800,
++      /* Index 720 - 729 */
++      34200, 34600, 35000, 35400, 35800, 36200, 36600, 37000, 37400, 37800,
++      /* Index 730 - 739 */
++      38200, 38600, 39000, 39400, 39800, 40200, 40600, 41000, 41400, 41800,
++      /* Index 740 - 749 */
++      42200, 42600, 43100, 43700, 44200, 44600, 45000, 45400, 45800, 46200,
++      /* Index 750 - 759 */
++      46600, 47000, 47400, 47800, 48200, 48600, 49000, 49400, 49800, 50200,
++      /* Index 760 - 769 */
++      50600, 51000, 51400, 51800, 52200, 52600, 53000, 53400, 53800, 54200,
++      /* Index 770 - 779 */
++      54600, 55000, 55400, 55900, 56500, 57000, 57400, 57800, 58200, 58600,
++      /* Index 780 - 789 */
++      59000, 59400, 59800, 60200, 60600, 61000, 61400, 61800, 62200, 62600,
++      /* Index 790 - 799 */
++      63000, 63400, 63800, 64200, 64600, 65000, 65400, 65800, 66200, 66600,
++      /* Index 800 - 809 */
++      67000, 67400, 67800, 68200, 68600, 69000, 69400, 69800, 70200, 70600,
++      /* Index 810 - 819 */
++      71000, 71500, 72100, 72600, 73000, 73400, 73800, 74200, 74600, 75000,
++      /* Index 820 - 829 */
++      75400, 75800, 76200, 76600, 77000, 77400, 77800, 78200, 78600, 79000,
++      /* Index 830 - 839 */
++      79400, 79800, 80200, 80600, 81000, 81400, 81800, 82200, 82600, 83000,
++      /* Index 840 - 849 */
++      83400, 83800, 84200, 84600, 85000, 85400, 85800, 86200, 86600, 87000,
++      /* Index 850 - 859 */
++      87400, 87800, 88200, 88600, 89000, 89400, 89800, 90200, 90600, 91000,
++      /* Index 860 - 869 */
++      91400, 91800, 92200, 92600, 93000, 93400, 93800, 94200, 94600, 95000,
++      /* Index 870 - 879 */
++      95400, 95800, 96200, 96600, 97000, 97500, 98100, 98600, 99000, 99400,
++      /* Index 880 - 889 */
++      99800, 100200, 100600, 101000, 101400, 101800, 102200, 102600, 103000,
++      103400,
++      /* Index 890 - 899 */
++      103800, 104200, 104600, 105000, 105400, 105800, 106200, 106600, 107000,
++      107400,
++      /* Index 900 - 909 */
++      107800, 108200, 108600, 109000, 109400, 109800, 110200, 110600, 111000,
++      111400,
++      /* Index 910 - 919 */
++      111800, 112200, 112600, 113000, 113400, 113800, 114200, 114600, 115000,
++      115400,
++      /* Index 920 - 929 */
++      115800, 116200, 116600, 117000, 117400, 117800, 118200, 118600, 119000,
++      119400,
++      /* Index 930 - 939 */
++      119800, 120200, 120600, 121000, 121400, 121800, 122400, 122600, 123000,
++      123400,
++      /* Index 940 - 945 */
++      123800, 1242000, 124600, 124900, 125000, 125000,
++};
++
++/* OMAP54xx ES2.0 data */
++const struct ti_bandgap_data omap5430_data = {
++      .features = TI_BANDGAP_FEATURE_TSHUT_CONFIG |
++                      TI_BANDGAP_FEATURE_FREEZE_BIT |
++                      TI_BANDGAP_FEATURE_TALERT |
++                      TI_BANDGAP_FEATURE_COUNTER_DELAY |
++                      TI_BANDGAP_FEATURE_HISTORY_BUFFER,
++      .fclock_name = "l3instr_ts_gclk_div",
++      .div_ck_name = "l3instr_ts_gclk_div",
++      .conv_table = omap5430_adc_to_temp,
++      .adc_start_val = OMAP5430_ADC_START_VALUE,
++      .adc_end_val = OMAP5430_ADC_END_VALUE,
++      .expose_sensor = ti_thermal_expose_sensor,
++      .remove_sensor = ti_thermal_remove_sensor,
++      .report_temperature = ti_thermal_report_sensor_temperature,
++      .sensors = {
++              {
++              .registers = &omap5430_mpu_temp_sensor_registers,
++              .ts_data = &omap5430_mpu_temp_sensor_data,
++              .domain = "cpu",
++              .register_cooling = ti_thermal_register_cpu_cooling,
++              .unregister_cooling = ti_thermal_unregister_cpu_cooling,
++              .slope = OMAP_GRADIENT_SLOPE_5430_CPU,
++              .constant = OMAP_GRADIENT_CONST_5430_CPU,
++              .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_5430_CPU,
++              .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_5430_CPU,
++              },
++              {
++              .registers = &omap5430_gpu_temp_sensor_registers,
++              .ts_data = &omap5430_gpu_temp_sensor_data,
++              .domain = "gpu",
++              .slope = OMAP_GRADIENT_SLOPE_5430_GPU,
++              .constant = OMAP_GRADIENT_CONST_5430_GPU,
++              .slope_pcb = OMAP_GRADIENT_SLOPE_W_PCB_5430_GPU,
++              .constant_pcb = OMAP_GRADIENT_CONST_W_PCB_5430_GPU,
++              },
++              {
++              .registers = &omap5430_core_temp_sensor_registers,
++              .ts_data = &omap5430_core_temp_sensor_data,
++              .domain = "core",
++              },
++      },
++      .sensor_count = 3,
++};
+diff --git a/drivers/thermal/ti-soc-thermal/omap5xxx-bandgap.h b/drivers/thermal/ti-soc-thermal/omap5xxx-bandgap.h
+new file mode 100644
+index 0000000..400b55d
+--- /dev/null
++++ b/drivers/thermal/ti-soc-thermal/omap5xxx-bandgap.h
+@@ -0,0 +1,200 @@
++/*
++ * OMAP5xxx bandgap registers, bitfields and temperature definitions
++ *
++ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
++ * Contact:
++ *   Eduardo Valentin <eduardo.valentin@ti.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
++ * 02110-1301 USA
++ *
++ */
++#ifndef __OMAP5XXX_BANDGAP_H
++#define __OMAP5XXX_BANDGAP_H
++
++/**
++ * *** OMAP5430 ***
++ *
++ * Below, in sequence, are the Register definitions,
++ * the bitfields and the temperature definitions for OMAP5430.
++ */
++
++/**
++ * OMAP5430 register definitions
++ *
++ * Registers are defined as offsets. The offsets are
++ * relative to FUSE_OPP_BGAP_GPU on 5430.
++ *
++ * Register below are grouped by domain (not necessarily in offset order)
++ */
++
++/* OMAP5430.GPU register offsets */
++#define OMAP5430_FUSE_OPP_BGAP_GPU                    0x0
++#define OMAP5430_TEMP_SENSOR_GPU_OFFSET                       0x150
++#define OMAP5430_BGAP_THRESHOLD_GPU_OFFSET            0x1A8
++#define OMAP5430_BGAP_TSHUT_GPU_OFFSET                        0x1B4
++#define OMAP5430_BGAP_CUMUL_DTEMP_GPU_OFFSET          0x1C0
++#define OMAP5430_BGAP_DTEMP_GPU_0_OFFSET              0x1F4
++#define OMAP5430_BGAP_DTEMP_GPU_1_OFFSET              0x1F8
++#define OMAP5430_BGAP_DTEMP_GPU_2_OFFSET              0x1FC
++#define OMAP5430_BGAP_DTEMP_GPU_3_OFFSET              0x200
++#define OMAP5430_BGAP_DTEMP_GPU_4_OFFSET              0x204
++
++/* OMAP5430.MPU register offsets */
++#define OMAP5430_FUSE_OPP_BGAP_MPU                    0x4
++#define OMAP5430_TEMP_SENSOR_MPU_OFFSET                       0x14C
++#define OMAP5430_BGAP_THRESHOLD_MPU_OFFSET            0x1A4
++#define OMAP5430_BGAP_TSHUT_MPU_OFFSET                        0x1B0
++#define OMAP5430_BGAP_CUMUL_DTEMP_MPU_OFFSET          0x1BC
++#define OMAP5430_BGAP_DTEMP_MPU_0_OFFSET              0x1E0
++#define OMAP5430_BGAP_DTEMP_MPU_1_OFFSET              0x1E4
++#define OMAP5430_BGAP_DTEMP_MPU_2_OFFSET              0x1E8
++#define OMAP5430_BGAP_DTEMP_MPU_3_OFFSET              0x1EC
++#define OMAP5430_BGAP_DTEMP_MPU_4_OFFSET              0x1F0
++
++/* OMAP5430.MPU register offsets */
++#define OMAP5430_FUSE_OPP_BGAP_CORE                   0x8
++#define OMAP5430_TEMP_SENSOR_CORE_OFFSET              0x154
++#define OMAP5430_BGAP_THRESHOLD_CORE_OFFSET           0x1AC
++#define OMAP5430_BGAP_TSHUT_CORE_OFFSET                       0x1B8
++#define OMAP5430_BGAP_CUMUL_DTEMP_CORE_OFFSET         0x1C4
++#define OMAP5430_BGAP_DTEMP_CORE_0_OFFSET             0x208
++#define OMAP5430_BGAP_DTEMP_CORE_1_OFFSET             0x20C
++#define OMAP5430_BGAP_DTEMP_CORE_2_OFFSET             0x210
++#define OMAP5430_BGAP_DTEMP_CORE_3_OFFSET             0x214
++#define OMAP5430_BGAP_DTEMP_CORE_4_OFFSET             0x218
++
++/* OMAP5430.common register offsets */
++#define OMAP5430_BGAP_CTRL_OFFSET                     0x1A0
++#define OMAP5430_BGAP_STATUS_OFFSET                   0x1C8
++
++/**
++ * Register bitfields for OMAP5430
++ *
++ * All the macros bellow define the required bits for
++ * controlling temperature on OMAP5430. Bit defines are
++ * grouped by register.
++ */
++
++/* OMAP5430.TEMP_SENSOR */
++#define OMAP5430_BGAP_TEMP_SENSOR_SOC_MASK            BIT(12)
++#define OMAP5430_BGAP_TEMPSOFF_MASK                   BIT(11)
++#define OMAP5430_BGAP_TEMP_SENSOR_EOCZ_MASK           BIT(10)
++#define OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK          (0x3ff << 0)
++
++/* OMAP5430.BANDGAP_CTRL */
++#define OMAP5430_MASK_SIDLEMODE_MASK                  (0x3 << 30)
++#define OMAP5430_MASK_COUNTER_DELAY_MASK              (0x7 << 27)
++#define OMAP5430_MASK_FREEZE_CORE_MASK                        BIT(23)
++#define OMAP5430_MASK_FREEZE_GPU_MASK                 BIT(22)
++#define OMAP5430_MASK_FREEZE_MPU_MASK                 BIT(21)
++#define OMAP5430_MASK_CLEAR_CORE_MASK                 BIT(20)
++#define OMAP5430_MASK_CLEAR_GPU_MASK                  BIT(19)
++#define OMAP5430_MASK_CLEAR_MPU_MASK                  BIT(18)
++#define OMAP5430_MASK_CLEAR_ACCUM_CORE_MASK           BIT(17)
++#define OMAP5430_MASK_CLEAR_ACCUM_GPU_MASK            BIT(16)
++#define OMAP5430_MASK_CLEAR_ACCUM_MPU_MASK            BIT(15)
++#define OMAP5430_MASK_HOT_CORE_MASK                   BIT(5)
++#define OMAP5430_MASK_COLD_CORE_MASK                  BIT(4)
++#define OMAP5430_MASK_HOT_GPU_MASK                    BIT(3)
++#define OMAP5430_MASK_COLD_GPU_MASK                   BIT(2)
++#define OMAP5430_MASK_HOT_MPU_MASK                    BIT(1)
++#define OMAP5430_MASK_COLD_MPU_MASK                   BIT(0)
++
++/* OMAP5430.BANDGAP_COUNTER */
++#define OMAP5430_COUNTER_MASK                         (0xffffff << 0)
++
++/* OMAP5430.BANDGAP_THRESHOLD */
++#define OMAP5430_T_HOT_MASK                           (0x3ff << 16)
++#define OMAP5430_T_COLD_MASK                          (0x3ff << 0)
++
++/* OMAP5430.TSHUT_THRESHOLD */
++#define OMAP5430_TSHUT_HOT_MASK                               (0x3ff << 16)
++#define OMAP5430_TSHUT_COLD_MASK                      (0x3ff << 0)
++
++/* OMAP5430.BANDGAP_CUMUL_DTEMP_MPU */
++#define OMAP5430_CUMUL_DTEMP_MPU_MASK                 (0xffffffff << 0)
++
++/* OMAP5430.BANDGAP_CUMUL_DTEMP_GPU */
++#define OMAP5430_CUMUL_DTEMP_GPU_MASK                 (0xffffffff << 0)
++
++/* OMAP5430.BANDGAP_CUMUL_DTEMP_CORE */
++#define OMAP5430_CUMUL_DTEMP_CORE_MASK                        (0xffffffff << 0)
++
++/* OMAP5430.BANDGAP_STATUS */
++#define OMAP5430_BGAP_ALERT_MASK                      BIT(31)
++#define OMAP5430_HOT_CORE_FLAG_MASK                   BIT(5)
++#define OMAP5430_COLD_CORE_FLAG_MASK                  BIT(4)
++#define OMAP5430_HOT_GPU_FLAG_MASK                    BIT(3)
++#define OMAP5430_COLD_GPU_FLAG_MASK                   BIT(2)
++#define OMAP5430_HOT_MPU_FLAG_MASK                    BIT(1)
++#define OMAP5430_COLD_MPU_FLAG_MASK                   BIT(0)
++
++/**
++ * Temperature limits and thresholds for OMAP5430
++ *
++ * All the macros bellow are definitions for handling the
++ * ADC conversions and representation of temperature limits
++ * and thresholds for OMAP5430. Definitions are grouped
++ * by temperature domain.
++ */
++
++/* OMAP5430.common temperature definitions */
++/* ADC conversion table limits */
++#define OMAP5430_ADC_START_VALUE                      540
++#define OMAP5430_ADC_END_VALUE                                945
++
++/* OMAP5430.GPU temperature definitions */
++/* bandgap clock limits */
++#define OMAP5430_GPU_MAX_FREQ                         1500000
++#define OMAP5430_GPU_MIN_FREQ                         1000000
++/* sensor limits */
++#define OMAP5430_GPU_MIN_TEMP                         -40000
++#define OMAP5430_GPU_MAX_TEMP                         125000
++#define OMAP5430_GPU_HYST_VAL                         5000
++/* interrupts thresholds */
++#define OMAP5430_GPU_TSHUT_HOT                                915
++#define OMAP5430_GPU_TSHUT_COLD                               900
++#define OMAP5430_GPU_T_HOT                            800
++#define OMAP5430_GPU_T_COLD                           795
++
++/* OMAP5430.MPU temperature definitions */
++/* bandgap clock limits */
++#define OMAP5430_MPU_MAX_FREQ                         1500000
++#define OMAP5430_MPU_MIN_FREQ                         1000000
++/* sensor limits */
++#define OMAP5430_MPU_MIN_TEMP                         -40000
++#define OMAP5430_MPU_MAX_TEMP                         125000
++#define OMAP5430_MPU_HYST_VAL                         5000
++/* interrupts thresholds */
++#define OMAP5430_MPU_TSHUT_HOT                                915
++#define OMAP5430_MPU_TSHUT_COLD                               900
++#define OMAP5430_MPU_T_HOT                            800
++#define OMAP5430_MPU_T_COLD                           795
++
++/* OMAP5430.CORE temperature definitions */
++/* bandgap clock limits */
++#define OMAP5430_CORE_MAX_FREQ                                1500000
++#define OMAP5430_CORE_MIN_FREQ                                1000000
++/* sensor limits */
++#define OMAP5430_CORE_MIN_TEMP                                -40000
++#define OMAP5430_CORE_MAX_TEMP                                125000
++#define OMAP5430_CORE_HYST_VAL                                5000
++/* interrupts thresholds */
++#define OMAP5430_CORE_TSHUT_HOT                               915
++#define OMAP5430_CORE_TSHUT_COLD                      900
++#define OMAP5430_CORE_T_HOT                           800
++#define OMAP5430_CORE_T_COLD                          795
++
++#endif /* __OMAP5XXX_BANDGAP_H */
+diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.c b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
+new file mode 100644
+index 0000000..f20c1cf
+--- /dev/null
++++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
+@@ -0,0 +1,1546 @@
++/*
++ * TI Bandgap temperature sensor driver
++ *
++ * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/
++ * Author: J Keerthy <j-keerthy@ti.com>
++ * Author: Moiz Sonasath <m-sonasath@ti.com>
++ * Couple of fixes, DT and MFD adaptation:
++ *   Eduardo Valentin <eduardo.valentin@ti.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
++ * 02110-1301 USA
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/export.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/interrupt.h>
++#include <linux/clk.h>
++#include <linux/gpio.h>
++#include <linux/platform_device.h>
++#include <linux/err.h>
++#include <linux/types.h>
++#include <linux/spinlock.h>
++#include <linux/reboot.h>
++#include <linux/of_device.h>
++#include <linux/of_platform.h>
++#include <linux/of_irq.h>
++#include <linux/io.h>
++
++#include "ti-bandgap.h"
++
++/***   Helper functions to access registers and their bitfields   ***/
++
++/**
++ * ti_bandgap_readl() - simple read helper function
++ * @bgp: pointer to ti_bandgap structure
++ * @reg: desired register (offset) to be read
++ *
++ * Helper function to read bandgap registers. It uses the io remapped area.
++ * Return: the register value.
++ */
++static u32 ti_bandgap_readl(struct ti_bandgap *bgp, u32 reg)
++{
++      return readl(bgp->base + reg);
++}
++
++/**
++ * ti_bandgap_writel() - simple write helper function
++ * @bgp: pointer to ti_bandgap structure
++ * @val: desired register value to be written
++ * @reg: desired register (offset) to be written
++ *
++ * Helper function to write bandgap registers. It uses the io remapped area.
++ */
++static void ti_bandgap_writel(struct ti_bandgap *bgp, u32 val, u32 reg)
++{
++      writel(val, bgp->base + reg);
++}
++
++/**
++ * DOC: macro to update bits.
++ *
++ * RMW_BITS() - used to read, modify and update bandgap bitfields.
++ *            The value passed will be shifted.
++ */
++#define RMW_BITS(bgp, id, reg, mask, val)                     \
++do {                                                          \
++      struct temp_sensor_registers *t;                        \
++      u32 r;                                                  \
++                                                              \
++      t = bgp->conf->sensors[(id)].registers;         \
++      r = ti_bandgap_readl(bgp, t->reg);                      \
++      r &= ~t->mask;                                          \
++      r |= (val) << __ffs(t->mask);                           \
++      ti_bandgap_writel(bgp, r, t->reg);                      \
++} while (0)
++
++/***   Basic helper functions   ***/
++
++/**
++ * ti_bandgap_power() - controls the power state of a bandgap device
++ * @bgp: pointer to ti_bandgap structure
++ * @on: desired power state (1 - on, 0 - off)
++ *
++ * Used to power on/off a bandgap device instance. Only used on those
++ * that features tempsoff bit.
++ *
++ * Return: 0 on success, -ENOTSUPP if tempsoff is not supported.
++ */
++static int ti_bandgap_power(struct ti_bandgap *bgp, bool on)
++{
++      int i, ret = 0;
++
++      if (!TI_BANDGAP_HAS(bgp, POWER_SWITCH)) {
++              ret = -ENOTSUPP;
++              goto exit;
++      }
++
++      for (i = 0; i < bgp->conf->sensor_count; i++)
++              /* active on 0 */
++              RMW_BITS(bgp, i, temp_sensor_ctrl, bgap_tempsoff_mask, !on);
++
++exit:
++      return ret;
++}
++
++/**
++ * ti_bandgap_read_temp() - helper function to read sensor temperature
++ * @bgp: pointer to ti_bandgap structure
++ * @id: bandgap sensor id
++ *
++ * Function to concentrate the steps to read sensor temperature register.
++ * This function is desired because, depending on bandgap device version,
++ * it might be needed to freeze the bandgap state machine, before fetching
++ * the register value.
++ *
++ * Return: temperature in ADC values.
++ */
++static u32 ti_bandgap_read_temp(struct ti_bandgap *bgp, int id)
++{
++      struct temp_sensor_registers *tsr;
++      u32 temp, reg;
++
++      tsr = bgp->conf->sensors[id].registers;
++      reg = tsr->temp_sensor_ctrl;
++
++      if (TI_BANDGAP_HAS(bgp, FREEZE_BIT)) {
++              RMW_BITS(bgp, id, bgap_mask_ctrl, mask_freeze_mask, 1);
++              /*
++               * In case we cannot read from cur_dtemp / dtemp_0,
++               * then we read from the last valid temp read
++               */
++              reg = tsr->ctrl_dtemp_1;
++      }
++
++      /* read temperature */
++      temp = ti_bandgap_readl(bgp, reg);
++      temp &= tsr->bgap_dtemp_mask;
++
++      if (TI_BANDGAP_HAS(bgp, FREEZE_BIT))
++              RMW_BITS(bgp, id, bgap_mask_ctrl, mask_freeze_mask, 0);
++
++      return temp;
++}
++
++/***   IRQ handlers   ***/
++
++/**
++ * ti_bandgap_talert_irq_handler() - handles Temperature alert IRQs
++ * @irq: IRQ number
++ * @data: private data (struct ti_bandgap *)
++ *
++ * This is the Talert handler. Use it only if bandgap device features
++ * HAS(TALERT). This handler goes over all sensors and checks their
++ * conditions and acts accordingly. In case there are events pending,
++ * it will reset the event mask to wait for the opposite event (next event).
++ * Every time there is a new event, it will be reported to thermal layer.
++ *
++ * Return: IRQ_HANDLED
++ */
++static irqreturn_t ti_bandgap_talert_irq_handler(int irq, void *data)
++{
++      struct ti_bandgap *bgp = data;
++      struct temp_sensor_registers *tsr;
++      u32 t_hot = 0, t_cold = 0, ctrl;
++      int i;
++
++      spin_lock(&bgp->lock);
++      for (i = 0; i < bgp->conf->sensor_count; i++) {
++              tsr = bgp->conf->sensors[i].registers;
++              ctrl = ti_bandgap_readl(bgp, tsr->bgap_status);
++
++              /* Read the status of t_hot */
++              t_hot = ctrl & tsr->status_hot_mask;
++
++              /* Read the status of t_cold */
++              t_cold = ctrl & tsr->status_cold_mask;
++
++              if (!t_cold && !t_hot)
++                      continue;
++
++              ctrl = ti_bandgap_readl(bgp, tsr->bgap_mask_ctrl);
++              /*
++               * One TALERT interrupt: Two sources
++               * If the interrupt is due to t_hot then mask t_hot and
++               * and unmask t_cold else mask t_cold and unmask t_hot
++               */
++              if (t_hot) {
++                      ctrl &= ~tsr->mask_hot_mask;
++                      ctrl |= tsr->mask_cold_mask;
++              } else if (t_cold) {
++                      ctrl &= ~tsr->mask_cold_mask;
++                      ctrl |= tsr->mask_hot_mask;
++              }
++
++              ti_bandgap_writel(bgp, ctrl, tsr->bgap_mask_ctrl);
++
++              dev_dbg(bgp->dev,
++                      "%s: IRQ from %s sensor: hotevent %d coldevent %d\n",
++                      __func__, bgp->conf->sensors[i].domain,
++                      t_hot, t_cold);
++
++              /* report temperature to whom may concern */
++              if (bgp->conf->report_temperature)
++                      bgp->conf->report_temperature(bgp, i);
++      }
++      spin_unlock(&bgp->lock);
++
++      return IRQ_HANDLED;
++}
++
++/**
++ * ti_bandgap_tshut_irq_handler() - handles Temperature shutdown signal
++ * @irq: IRQ number
++ * @data: private data (unused)
++ *
++ * This is the Tshut handler. Use it only if bandgap device features
++ * HAS(TSHUT). If any sensor fires the Tshut signal, we simply shutdown
++ * the system.
++ *
++ * Return: IRQ_HANDLED
++ */
++static irqreturn_t ti_bandgap_tshut_irq_handler(int irq, void *data)
++{
++      pr_emerg("%s: TSHUT temperature reached. Needs shut down...\n",
++               __func__);
++
++      orderly_poweroff(true);
++
++      return IRQ_HANDLED;
++}
++
++/***   Helper functions which manipulate conversion ADC <-> mi Celsius   ***/
++
++/**
++ * ti_bandgap_adc_to_mcelsius() - converts an ADC value to mCelsius scale
++ * @bgp: struct ti_bandgap pointer
++ * @adc_val: value in ADC representation
++ * @t: address where to write the resulting temperature in mCelsius
++ *
++ * Simple conversion from ADC representation to mCelsius. In case the ADC value
++ * is out of the ADC conv table range, it returns -ERANGE, 0 on success.
++ * The conversion table is indexed by the ADC values.
++ *
++ * Return: 0 if conversion was successful, else -ERANGE in case the @adc_val
++ * argument is out of the ADC conv table range.
++ */
++static
++int ti_bandgap_adc_to_mcelsius(struct ti_bandgap *bgp, int adc_val, int *t)
++{
++      const struct ti_bandgap_data *conf = bgp->conf;
++      int ret = 0;
++
++      /* look up for temperature in the table and return the temperature */
++      if (adc_val < conf->adc_start_val || adc_val > conf->adc_end_val) {
++              ret = -ERANGE;
++              goto exit;
++      }
++
++      *t = bgp->conf->conv_table[adc_val - conf->adc_start_val];
++
++exit:
++      return ret;
++}
++
++/**
++ * ti_bandgap_mcelsius_to_adc() - converts a mCelsius value to ADC scale
++ * @bgp: struct ti_bandgap pointer
++ * @temp: value in mCelsius
++ * @adc: address where to write the resulting temperature in ADC representation
++ *
++ * Simple conversion from mCelsius to ADC values. In case the temp value
++ * is out of the ADC conv table range, it returns -ERANGE, 0 on success.
++ * The conversion table is indexed by the ADC values.
++ *
++ * Return: 0 if conversion was successful, else -ERANGE in case the @temp
++ * argument is out of the ADC conv table range.
++ */
++static
++int ti_bandgap_mcelsius_to_adc(struct ti_bandgap *bgp, long temp, int *adc)
++{
++      const struct ti_bandgap_data *conf = bgp->conf;
++      const int *conv_table = bgp->conf->conv_table;
++      int high, low, mid, ret = 0;
++
++      low = 0;
++      high = conf->adc_end_val - conf->adc_start_val;
++      mid = (high + low) / 2;
++
++      if (temp < conv_table[low] || temp > conv_table[high]) {
++              ret = -ERANGE;
++              goto exit;
++      }
++
++      while (low < high) {
++              if (temp < conv_table[mid])
++                      high = mid - 1;
++              else
++                      low = mid + 1;
++              mid = (low + high) / 2;
++      }
++
++      *adc = conf->adc_start_val + low;
++
++exit:
++      return ret;
++}
++
++/**
++ * ti_bandgap_add_hyst() - add hysteresis (in mCelsius) to an ADC value
++ * @bgp: struct ti_bandgap pointer
++ * @adc_val: temperature value in ADC representation
++ * @hyst_val: hysteresis value in mCelsius
++ * @sum: address where to write the resulting temperature (in ADC scale)
++ *
++ * Adds an hysteresis value (in mCelsius) to a ADC temperature value.
++ *
++ * Return: 0 on success, -ERANGE otherwise.
++ */
++static
++int ti_bandgap_add_hyst(struct ti_bandgap *bgp, int adc_val, int hyst_val,
++                      u32 *sum)
++{
++      int temp, ret;
++
++      /*
++       * Need to add in the mcelsius domain, so we have a temperature
++       * the conv_table range
++       */
++      ret = ti_bandgap_adc_to_mcelsius(bgp, adc_val, &temp);
++      if (ret < 0)
++              goto exit;
++
++      temp += hyst_val;
++
++      ret = ti_bandgap_mcelsius_to_adc(bgp, temp, sum);
++
++exit:
++      return ret;
++}
++
++/***   Helper functions handling device Alert/Shutdown signals   ***/
++
++/**
++ * ti_bandgap_unmask_interrupts() - unmasks the events of thot & tcold
++ * @bgp: struct ti_bandgap pointer
++ * @id: bandgap sensor id
++ * @t_hot: hot temperature value to trigger alert signal
++ * @t_cold: cold temperature value to trigger alert signal
++ *
++ * Checks the requested t_hot and t_cold values and configures the IRQ event
++ * masks accordingly. Call this function only if bandgap features HAS(TALERT).
++ */
++static void ti_bandgap_unmask_interrupts(struct ti_bandgap *bgp, int id,
++                                       u32 t_hot, u32 t_cold)
++{
++      struct temp_sensor_registers *tsr;
++      u32 temp, reg_val;
++
++      /* Read the current on die temperature */
++      temp = ti_bandgap_read_temp(bgp, id);
++
++      tsr = bgp->conf->sensors[id].registers;
++      reg_val = ti_bandgap_readl(bgp, tsr->bgap_mask_ctrl);
++
++      if (temp < t_hot)
++              reg_val |= tsr->mask_hot_mask;
++      else
++              reg_val &= ~tsr->mask_hot_mask;
++
++      if (t_cold < temp)
++              reg_val |= tsr->mask_cold_mask;
++      else
++              reg_val &= ~tsr->mask_cold_mask;
++      ti_bandgap_writel(bgp, reg_val, tsr->bgap_mask_ctrl);
++}
++
++/**
++ * ti_bandgap_update_alert_threshold() - sequence to update thresholds
++ * @bgp: struct ti_bandgap pointer
++ * @id: bandgap sensor id
++ * @val: value (ADC) of a new threshold
++ * @hot: desired threshold to be updated. true if threshold hot, false if
++ *       threshold cold
++ *
++ * It will program the required thresholds (hot and cold) for TALERT signal.
++ * This function can be used to update t_hot or t_cold, depending on @hot value.
++ * It checks the resulting t_hot and t_cold values, based on the new passed @val
++ * and configures the thresholds so that t_hot is always greater than t_cold.
++ * Call this function only if bandgap features HAS(TALERT).
++ *
++ * Return: 0 if no error, else corresponding error
++ */
++static int ti_bandgap_update_alert_threshold(struct ti_bandgap *bgp, int id,
++                                           int val, bool hot)
++{
++      struct temp_sensor_data *ts_data = bgp->conf->sensors[id].ts_data;
++      struct temp_sensor_registers *tsr;
++      u32 thresh_val, reg_val, t_hot, t_cold;
++      int err = 0;
++
++      tsr = bgp->conf->sensors[id].registers;
++
++      /* obtain the current value */
++      thresh_val = ti_bandgap_readl(bgp, tsr->bgap_threshold);
++      t_cold = (thresh_val & tsr->threshold_tcold_mask) >>
++              __ffs(tsr->threshold_tcold_mask);
++      t_hot = (thresh_val & tsr->threshold_thot_mask) >>
++              __ffs(tsr->threshold_thot_mask);
++      if (hot)
++              t_hot = val;
++      else
++              t_cold = val;
++
++      if (t_cold > t_hot) {
++              if (hot)
++                      err = ti_bandgap_add_hyst(bgp, t_hot,
++                                                -ts_data->hyst_val,
++                                                &t_cold);
++              else
++                      err = ti_bandgap_add_hyst(bgp, t_cold,
++                                                ts_data->hyst_val,
++                                                &t_hot);
++      }
++
++      /* write the new threshold values */
++      reg_val = thresh_val &
++                ~(tsr->threshold_thot_mask | tsr->threshold_tcold_mask);
++      reg_val |= (t_hot << __ffs(tsr->threshold_thot_mask)) |
++                 (t_cold << __ffs(tsr->threshold_tcold_mask));
++      ti_bandgap_writel(bgp, reg_val, tsr->bgap_threshold);
++
++      if (err) {
++              dev_err(bgp->dev, "failed to reprogram thot threshold\n");
++              err = -EIO;
++              goto exit;
++      }
++
++      ti_bandgap_unmask_interrupts(bgp, id, t_hot, t_cold);
++exit:
++      return err;
++}
++
++/**
++ * ti_bandgap_validate() - helper to check the sanity of a struct ti_bandgap
++ * @bgp: struct ti_bandgap pointer
++ * @id: bandgap sensor id
++ *
++ * Checks if the bandgap pointer is valid and if the sensor id is also
++ * applicable.
++ *
++ * Return: 0 if no errors, -EINVAL for invalid @bgp pointer or -ERANGE if
++ * @id cannot index @bgp sensors.
++ */
++static inline int ti_bandgap_validate(struct ti_bandgap *bgp, int id)
++{
++      int ret = 0;
++
++      if (IS_ERR_OR_NULL(bgp)) {
++              pr_err("%s: invalid bandgap pointer\n", __func__);
++              ret = -EINVAL;
++              goto exit;
++      }
++
++      if ((id < 0) || (id >= bgp->conf->sensor_count)) {
++              dev_err(bgp->dev, "%s: sensor id out of range (%d)\n",
++                      __func__, id);
++              ret = -ERANGE;
++      }
++
++exit:
++      return ret;
++}
++
++/**
++ * _ti_bandgap_write_threshold() - helper to update TALERT t_cold or t_hot
++ * @bgp: struct ti_bandgap pointer
++ * @id: bandgap sensor id
++ * @val: value (mCelsius) of a new threshold
++ * @hot: desired threshold to be updated. true if threshold hot, false if
++ *       threshold cold
++ *
++ * It will update the required thresholds (hot and cold) for TALERT signal.
++ * This function can be used to update t_hot or t_cold, depending on @hot value.
++ * Validates the mCelsius range and update the requested threshold.
++ * Call this function only if bandgap features HAS(TALERT).
++ *
++ * Return: 0 if no error, else corresponding error value.
++ */
++static int _ti_bandgap_write_threshold(struct ti_bandgap *bgp, int id, int val,
++                                     bool hot)
++{
++      struct temp_sensor_data *ts_data;
++      struct temp_sensor_registers *tsr;
++      u32 adc_val;
++      int ret;
++
++      ret = ti_bandgap_validate(bgp, id);
++      if (ret)
++              goto exit;
++
++      if (!TI_BANDGAP_HAS(bgp, TALERT)) {
++              ret = -ENOTSUPP;
++              goto exit;
++      }
++
++      ts_data = bgp->conf->sensors[id].ts_data;
++      tsr = bgp->conf->sensors[id].registers;
++      if (hot) {
++              if (val < ts_data->min_temp + ts_data->hyst_val)
++                      ret = -EINVAL;
++      } else {
++              if (val > ts_data->max_temp + ts_data->hyst_val)
++                      ret = -EINVAL;
++      }
++
++      if (ret)
++              goto exit;
++
++      ret = ti_bandgap_mcelsius_to_adc(bgp, val, &adc_val);
++      if (ret < 0)
++              goto exit;
++
++      spin_lock(&bgp->lock);
++      ret = ti_bandgap_update_alert_threshold(bgp, id, adc_val, hot);
++      spin_unlock(&bgp->lock);
++
++exit:
++      return ret;
++}
++
++/**
++ * _ti_bandgap_read_threshold() - helper to read TALERT t_cold or t_hot
++ * @bgp: struct ti_bandgap pointer
++ * @id: bandgap sensor id
++ * @val: value (mCelsius) of a threshold
++ * @hot: desired threshold to be read. true if threshold hot, false if
++ *       threshold cold
++ *
++ * It will fetch the required thresholds (hot and cold) for TALERT signal.
++ * This function can be used to read t_hot or t_cold, depending on @hot value.
++ * Call this function only if bandgap features HAS(TALERT).
++ *
++ * Return: 0 if no error, -ENOTSUPP if it has no TALERT support, or the
++ * corresponding error value if some operation fails.
++ */
++static int _ti_bandgap_read_threshold(struct ti_bandgap *bgp, int id,
++                                    int *val, bool hot)
++{
++      struct temp_sensor_registers *tsr;
++      u32 temp, mask;
++      int ret = 0;
++
++      ret = ti_bandgap_validate(bgp, id);
++      if (ret)
++              goto exit;
++
++      if (!TI_BANDGAP_HAS(bgp, TALERT)) {
++              ret = -ENOTSUPP;
++              goto exit;
++      }
++
++      tsr = bgp->conf->sensors[id].registers;
++      if (hot)
++              mask = tsr->threshold_thot_mask;
++      else
++              mask = tsr->threshold_tcold_mask;
++
++      temp = ti_bandgap_readl(bgp, tsr->bgap_threshold);
++      temp = (temp & mask) >> __ffs(mask);
++      ret |= ti_bandgap_adc_to_mcelsius(bgp, temp, &temp);
++      if (ret) {
++              dev_err(bgp->dev, "failed to read thot\n");
++              ret = -EIO;
++              goto exit;
++      }
++
++      *val = temp;
++
++exit:
++      return ret;
++}
++
++/***   Exposed APIs   ***/
++
++/**
++ * ti_bandgap_read_thot() - reads sensor current thot
++ * @bgp: pointer to bandgap instance
++ * @id: sensor id
++ * @thot: resulting current thot value
++ *
++ * Return: 0 on success or the proper error code
++ */
++int ti_bandgap_read_thot(struct ti_bandgap *bgp, int id, int *thot)
++{
++      return _ti_bandgap_read_threshold(bgp, id, thot, true);
++}
++
++/**
++ * ti_bandgap_write_thot() - sets sensor current thot
++ * @bgp: pointer to bandgap instance
++ * @id: sensor id
++ * @val: desired thot value
++ *
++ * Return: 0 on success or the proper error code
++ */
++int ti_bandgap_write_thot(struct ti_bandgap *bgp, int id, int val)
++{
++      return _ti_bandgap_write_threshold(bgp, id, val, true);
++}
++
++/**
++ * ti_bandgap_read_tcold() - reads sensor current tcold
++ * @bgp: pointer to bandgap instance
++ * @id: sensor id
++ * @tcold: resulting current tcold value
++ *
++ * Return: 0 on success or the proper error code
++ */
++int ti_bandgap_read_tcold(struct ti_bandgap *bgp, int id, int *tcold)
++{
++      return _ti_bandgap_read_threshold(bgp, id, tcold, false);
++}
++
++/**
++ * ti_bandgap_write_tcold() - sets the sensor tcold
++ * @bgp: pointer to bandgap instance
++ * @id: sensor id
++ * @val: desired tcold value
++ *
++ * Return: 0 on success or the proper error code
++ */
++int ti_bandgap_write_tcold(struct ti_bandgap *bgp, int id, int val)
++{
++      return _ti_bandgap_write_threshold(bgp, id, val, false);
++}
++
++/**
++ * ti_bandgap_read_counter() - read the sensor counter
++ * @bgp: pointer to bandgap instance
++ * @id: sensor id
++ * @interval: resulting update interval in miliseconds
++ */
++static void ti_bandgap_read_counter(struct ti_bandgap *bgp, int id,
++                                  int *interval)
++{
++      struct temp_sensor_registers *tsr;
++      int time;
++
++      tsr = bgp->conf->sensors[id].registers;
++      time = ti_bandgap_readl(bgp, tsr->bgap_counter);
++      time = (time & tsr->counter_mask) >>
++                                      __ffs(tsr->counter_mask);
++      time = time * 1000 / bgp->clk_rate;
++      *interval = time;
++}
++
++/**
++ * ti_bandgap_read_counter_delay() - read the sensor counter delay
++ * @bgp: pointer to bandgap instance
++ * @id: sensor id
++ * @interval: resulting update interval in miliseconds
++ */
++static void ti_bandgap_read_counter_delay(struct ti_bandgap *bgp, int id,
++                                        int *interval)
++{
++      struct temp_sensor_registers *tsr;
++      int reg_val;
++
++      tsr = bgp->conf->sensors[id].registers;
++
++      reg_val = ti_bandgap_readl(bgp, tsr->bgap_mask_ctrl);
++      reg_val = (reg_val & tsr->mask_counter_delay_mask) >>
++                              __ffs(tsr->mask_counter_delay_mask);
++      switch (reg_val) {
++      case 0:
++              *interval = 0;
++              break;
++      case 1:
++              *interval = 1;
++              break;
++      case 2:
++              *interval = 10;
++              break;
++      case 3:
++              *interval = 100;
++              break;
++      case 4:
++              *interval = 250;
++              break;
++      case 5:
++              *interval = 500;
++              break;
++      default:
++              dev_warn(bgp->dev, "Wrong counter delay value read from register %X",
++                       reg_val);
++      }
++}
++
++/**
++ * ti_bandgap_read_update_interval() - read the sensor update interval
++ * @bgp: pointer to bandgap instance
++ * @id: sensor id
++ * @interval: resulting update interval in miliseconds
++ *
++ * Return: 0 on success or the proper error code
++ */
++int ti_bandgap_read_update_interval(struct ti_bandgap *bgp, int id,
++                                  int *interval)
++{
++      int ret = 0;
++
++      ret = ti_bandgap_validate(bgp, id);
++      if (ret)
++              goto exit;
++
++      if (!TI_BANDGAP_HAS(bgp, COUNTER) &&
++          !TI_BANDGAP_HAS(bgp, COUNTER_DELAY)) {
++              ret = -ENOTSUPP;
++              goto exit;
++      }
++
++      if (TI_BANDGAP_HAS(bgp, COUNTER)) {
++              ti_bandgap_read_counter(bgp, id, interval);
++              goto exit;
++      }
++
++      ti_bandgap_read_counter_delay(bgp, id, interval);
++exit:
++      return ret;
++}
++
++/**
++ * ti_bandgap_write_counter_delay() - set the counter_delay
++ * @bgp: pointer to bandgap instance
++ * @id: sensor id
++ * @interval: desired update interval in miliseconds
++ *
++ * Return: 0 on success or the proper error code
++ */
++static int ti_bandgap_write_counter_delay(struct ti_bandgap *bgp, int id,
++                                        u32 interval)
++{
++      int rval;
++
++      switch (interval) {
++      case 0: /* Immediate conversion */
++              rval = 0x0;
++              break;
++      case 1: /* Conversion after ever 1ms */
++              rval = 0x1;
++              break;
++      case 10: /* Conversion after ever 10ms */
++              rval = 0x2;
++              break;
++      case 100: /* Conversion after ever 100ms */
++              rval = 0x3;
++              break;
++      case 250: /* Conversion after ever 250ms */
++              rval = 0x4;
++              break;
++      case 500: /* Conversion after ever 500ms */
++              rval = 0x5;
++              break;
++      default:
++              dev_warn(bgp->dev, "Delay %d ms is not supported\n", interval);
++              return -EINVAL;
++      }
++
++      spin_lock(&bgp->lock);
++      RMW_BITS(bgp, id, bgap_mask_ctrl, mask_counter_delay_mask, rval);
++      spin_unlock(&bgp->lock);
++
++      return 0;
++}
++
++/**
++ * ti_bandgap_write_counter() - set the bandgap sensor counter
++ * @bgp: pointer to bandgap instance
++ * @id: sensor id
++ * @interval: desired update interval in miliseconds
++ */
++static void ti_bandgap_write_counter(struct ti_bandgap *bgp, int id,
++                                   u32 interval)
++{
++      interval = interval * bgp->clk_rate / 1000;
++      spin_lock(&bgp->lock);
++      RMW_BITS(bgp, id, bgap_counter, counter_mask, interval);
++      spin_unlock(&bgp->lock);
++}
++
++/**
++ * ti_bandgap_write_update_interval() - set the update interval
++ * @bgp: pointer to bandgap instance
++ * @id: sensor id
++ * @interval: desired update interval in miliseconds
++ *
++ * Return: 0 on success or the proper error code
++ */
++int ti_bandgap_write_update_interval(struct ti_bandgap *bgp,
++                                   int id, u32 interval)
++{
++      int ret = ti_bandgap_validate(bgp, id);
++      if (ret)
++              goto exit;
++
++      if (!TI_BANDGAP_HAS(bgp, COUNTER) &&
++          !TI_BANDGAP_HAS(bgp, COUNTER_DELAY)) {
++              ret = -ENOTSUPP;
++              goto exit;
++      }
++
++      if (TI_BANDGAP_HAS(bgp, COUNTER)) {
++              ti_bandgap_write_counter(bgp, id, interval);
++              goto exit;
++      }
++
++      ret = ti_bandgap_write_counter_delay(bgp, id, interval);
++exit:
++      return ret;
++}
++
++/**
++ * ti_bandgap_read_temperature() - report current temperature
++ * @bgp: pointer to bandgap instance
++ * @id: sensor id
++ * @temperature: resulting temperature
++ *
++ * Return: 0 on success or the proper error code
++ */
++int ti_bandgap_read_temperature(struct ti_bandgap *bgp, int id,
++                              int *temperature)
++{
++      u32 temp;
++      int ret;
++
++      ret = ti_bandgap_validate(bgp, id);
++      if (ret)
++              return ret;
++
++      spin_lock(&bgp->lock);
++      temp = ti_bandgap_read_temp(bgp, id);
++      spin_unlock(&bgp->lock);
++
++      ret |= ti_bandgap_adc_to_mcelsius(bgp, temp, &temp);
++      if (ret)
++              return -EIO;
++
++      *temperature = temp;
++
++      return 0;
++}
++
++/**
++ * ti_bandgap_set_sensor_data() - helper function to store thermal
++ * framework related data.
++ * @bgp: pointer to bandgap instance
++ * @id: sensor id
++ * @data: thermal framework related data to be stored
++ *
++ * Return: 0 on success or the proper error code
++ */
++int ti_bandgap_set_sensor_data(struct ti_bandgap *bgp, int id, void *data)
++{
++      int ret = ti_bandgap_validate(bgp, id);
++      if (ret)
++              return ret;
++
++      bgp->regval[id].data = data;
++
++      return 0;
++}
++
++/**
++ * ti_bandgap_get_sensor_data() - helper function to get thermal
++ * framework related data.
++ * @bgp: pointer to bandgap instance
++ * @id: sensor id
++ *
++ * Return: data stored by set function with sensor id on success or NULL
++ */
++void *ti_bandgap_get_sensor_data(struct ti_bandgap *bgp, int id)
++{
++      int ret = ti_bandgap_validate(bgp, id);
++      if (ret)
++              return ERR_PTR(ret);
++
++      return bgp->regval[id].data;
++}
++
++/***   Helper functions used during device initialization   ***/
++
++/**
++ * ti_bandgap_force_single_read() - executes 1 single ADC conversion
++ * @bgp: pointer to struct ti_bandgap
++ * @id: sensor id which it is desired to read 1 temperature
++ *
++ * Used to initialize the conversion state machine and set it to a valid
++ * state. Called during device initialization and context restore events.
++ *
++ * Return: 0
++ */
++static int
++ti_bandgap_force_single_read(struct ti_bandgap *bgp, int id)
++{
++      u32 temp = 0, counter = 1000;
++
++      /* Select single conversion mode */
++      if (TI_BANDGAP_HAS(bgp, MODE_CONFIG))
++              RMW_BITS(bgp, id, bgap_mode_ctrl, mode_ctrl_mask, 0);
++
++      /* Start of Conversion = 1 */
++      RMW_BITS(bgp, id, temp_sensor_ctrl, bgap_soc_mask, 1);
++      /* Wait until DTEMP is updated */
++      temp = ti_bandgap_read_temp(bgp, id);
++
++      while ((temp == 0) && --counter)
++              temp = ti_bandgap_read_temp(bgp, id);
++      /* REVISIT: Check correct condition for end of conversion */
++
++      /* Start of Conversion = 0 */
++      RMW_BITS(bgp, id, temp_sensor_ctrl, bgap_soc_mask, 0);
++
++      return 0;
++}
++
++/**
++ * ti_bandgap_set_continous_mode() - One time enabling of continuous mode
++ * @bgp: pointer to struct ti_bandgap
++ *
++ * Call this function only if HAS(MODE_CONFIG) is set. As this driver may
++ * be used for junction temperature monitoring, it is desirable that the
++ * sensors are operational all the time, so that alerts are generated
++ * properly.
++ *
++ * Return: 0
++ */
++static int ti_bandgap_set_continuous_mode(struct ti_bandgap *bgp)
++{
++      int i;
++
++      for (i = 0; i < bgp->conf->sensor_count; i++) {
++              /* Perform a single read just before enabling continuous */
++              ti_bandgap_force_single_read(bgp, i);
++              RMW_BITS(bgp, i, bgap_mode_ctrl, mode_ctrl_mask, 1);
++      }
++
++      return 0;
++}
++
++/**
++ * ti_bandgap_get_trend() - To fetch the temperature trend of a sensor
++ * @bgp: pointer to struct ti_bandgap
++ * @id: id of the individual sensor
++ * @trend: Pointer to trend.
++ *
++ * This function needs to be called to fetch the temperature trend of a
++ * Particular sensor. The function computes the difference in temperature
++ * w.r.t time. For the bandgaps with built in history buffer the temperatures
++ * are read from the buffer and for those without the Buffer -ENOTSUPP is
++ * returned.
++ *
++ * Return: 0 if no error, else return corresponding error. If no
++ *            error then the trend value is passed on to trend parameter
++ */
++int ti_bandgap_get_trend(struct ti_bandgap *bgp, int id, int *trend)
++{
++      struct temp_sensor_registers *tsr;
++      u32 temp1, temp2, reg1, reg2;
++      int t1, t2, interval, ret = 0;
++
++      ret = ti_bandgap_validate(bgp, id);
++      if (ret)
++              goto exit;
++
++      if (!TI_BANDGAP_HAS(bgp, HISTORY_BUFFER) ||
++          !TI_BANDGAP_HAS(bgp, FREEZE_BIT)) {
++              ret = -ENOTSUPP;
++              goto exit;
++      }
++
++      tsr = bgp->conf->sensors[id].registers;
++
++      /* Freeze and read the last 2 valid readings */
++      reg1 = tsr->ctrl_dtemp_1;
++      reg2 = tsr->ctrl_dtemp_2;
++
++      /* read temperature from history buffer */
++      temp1 = ti_bandgap_readl(bgp, reg1);
++      temp1 &= tsr->bgap_dtemp_mask;
++
++      temp2 = ti_bandgap_readl(bgp, reg2);
++      temp2 &= tsr->bgap_dtemp_mask;
++
++      /* Convert from adc values to mCelsius temperature */
++      ret = ti_bandgap_adc_to_mcelsius(bgp, temp1, &t1);
++      if (ret)
++              goto exit;
++
++      ret = ti_bandgap_adc_to_mcelsius(bgp, temp2, &t2);
++      if (ret)
++              goto exit;
++
++      /* Fetch the update interval */
++      ret = ti_bandgap_read_update_interval(bgp, id, &interval);
++      if (ret || !interval)
++              goto exit;
++
++      *trend = (t1 - t2) / interval;
++
++      dev_dbg(bgp->dev, "The temperatures are t1 = %d and t2 = %d and trend =%d\n",
++              t1, t2, *trend);
++
++exit:
++      return ret;
++}
++
++/**
++ * ti_bandgap_tshut_init() - setup and initialize tshut handling
++ * @bgp: pointer to struct ti_bandgap
++ * @pdev: pointer to device struct platform_device
++ *
++ * Call this function only in case the bandgap features HAS(TSHUT).
++ * In this case, the driver needs to handle the TSHUT signal as an IRQ.
++ * The IRQ is wired as a GPIO, and for this purpose, it is required
++ * to specify which GPIO line is used. TSHUT IRQ is fired anytime
++ * one of the bandgap sensors violates the TSHUT high/hot threshold.
++ * And in that case, the system must go off.
++ *
++ * Return: 0 if no error, else error status
++ */
++static int ti_bandgap_tshut_init(struct ti_bandgap *bgp,
++                               struct platform_device *pdev)
++{
++      int gpio_nr = bgp->tshut_gpio;
++      int status;
++
++      /* Request for gpio_86 line */
++      status = gpio_request(gpio_nr, "tshut");
++      if (status < 0) {
++              dev_err(bgp->dev, "Could not request for TSHUT GPIO:%i\n", 86);
++              return status;
++      }
++      status = gpio_direction_input(gpio_nr);
++      if (status) {
++              dev_err(bgp->dev, "Cannot set input TSHUT GPIO %d\n", gpio_nr);
++              return status;
++      }
++
++      status = request_irq(gpio_to_irq(gpio_nr), ti_bandgap_tshut_irq_handler,
++                           IRQF_TRIGGER_RISING, "tshut", NULL);
++      if (status) {
++              gpio_free(gpio_nr);
++              dev_err(bgp->dev, "request irq failed for TSHUT");
++      }
++
++      return 0;
++}
++
++/**
++ * ti_bandgap_alert_init() - setup and initialize talert handling
++ * @bgp: pointer to struct ti_bandgap
++ * @pdev: pointer to device struct platform_device
++ *
++ * Call this function only in case the bandgap features HAS(TALERT).
++ * In this case, the driver needs to handle the TALERT signals as an IRQs.
++ * TALERT is a normal IRQ and it is fired any time thresholds (hot or cold)
++ * are violated. In these situation, the driver must reprogram the thresholds,
++ * accordingly to specified policy.
++ *
++ * Return: 0 if no error, else return corresponding error.
++ */
++static int ti_bandgap_talert_init(struct ti_bandgap *bgp,
++                                struct platform_device *pdev)
++{
++      int ret;
++
++      bgp->irq = platform_get_irq(pdev, 0);
++      if (bgp->irq < 0) {
++              dev_err(&pdev->dev, "get_irq failed\n");
++              return bgp->irq;
++      }
++      ret = request_threaded_irq(bgp->irq, NULL,
++                                 ti_bandgap_talert_irq_handler,
++                                 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
++                                 "talert", bgp);
++      if (ret) {
++              dev_err(&pdev->dev, "Request threaded irq failed.\n");
++              return ret;
++      }
++
++      return 0;
++}
++
++static const struct of_device_id of_ti_bandgap_match[];
++/**
++ * ti_bandgap_build() - parse DT and setup a struct ti_bandgap
++ * @pdev: pointer to device struct platform_device
++ *
++ * Used to read the device tree properties accordingly to the bandgap
++ * matching version. Based on bandgap version and its capabilities it
++ * will build a struct ti_bandgap out of the required DT entries.
++ *
++ * Return: valid bandgap structure if successful, else returns ERR_PTR
++ * return value must be verified with IS_ERR.
++ */
++static struct ti_bandgap *ti_bandgap_build(struct platform_device *pdev)
++{
++      struct device_node *node = pdev->dev.of_node;
++      const struct of_device_id *of_id;
++      struct ti_bandgap *bgp;
++      struct resource *res;
++      u32 prop;
++      int i;
++
++      /* just for the sake */
++      if (!node) {
++              dev_err(&pdev->dev, "no platform information available\n");
++              return ERR_PTR(-EINVAL);
++      }
++
++      bgp = devm_kzalloc(&pdev->dev, sizeof(*bgp), GFP_KERNEL);
++      if (!bgp) {
++              dev_err(&pdev->dev, "Unable to allocate mem for driver ref\n");
++              return ERR_PTR(-ENOMEM);
++      }
++
++      of_id = of_match_device(of_ti_bandgap_match, &pdev->dev);
++      if (of_id)
++              bgp->conf = of_id->data;
++
++      /* register shadow for context save and restore */
++      bgp->regval = devm_kzalloc(&pdev->dev, sizeof(*bgp->regval) *
++                                 bgp->conf->sensor_count, GFP_KERNEL);
++      if (!bgp) {
++              dev_err(&pdev->dev, "Unable to allocate mem for driver ref\n");
++              return ERR_PTR(-ENOMEM);
++      }
++
++      i = 0;
++      do {
++              void __iomem *chunk;
++
++              res = platform_get_resource(pdev, IORESOURCE_MEM, i);
++              if (!res)
++                      break;
++              chunk = devm_ioremap_resource(&pdev->dev, res);
++              if (i == 0)
++                      bgp->base = chunk;
++              if (IS_ERR(chunk))
++                      return ERR_CAST(chunk);
++
++              i++;
++      } while (res);
++
++      if (TI_BANDGAP_HAS(bgp, TSHUT)) {
++              if (of_property_read_u32(node, "ti,tshut-gpio", &prop) < 0) {
++                      dev_err(&pdev->dev, "missing tshut gpio in device tree\n");
++                      return ERR_PTR(-EINVAL);
++              }
++              bgp->tshut_gpio = prop;
++              if (!gpio_is_valid(bgp->tshut_gpio)) {
++                      dev_err(&pdev->dev, "invalid gpio for tshut (%d)\n",
++                              bgp->tshut_gpio);
++                      return ERR_PTR(-EINVAL);
++              }
++      }
++
++      return bgp;
++}
++
++/***   Device driver call backs   ***/
++
++static
++int ti_bandgap_probe(struct platform_device *pdev)
++{
++      struct ti_bandgap *bgp;
++      int clk_rate, ret = 0, i;
++
++      bgp = ti_bandgap_build(pdev);
++      if (IS_ERR_OR_NULL(bgp)) {
++              dev_err(&pdev->dev, "failed to fetch platform data\n");
++              return PTR_ERR(bgp);
++      }
++      bgp->dev = &pdev->dev;
++
++      if (TI_BANDGAP_HAS(bgp, TSHUT)) {
++              ret = ti_bandgap_tshut_init(bgp, pdev);
++              if (ret) {
++                      dev_err(&pdev->dev,
++                              "failed to initialize system tshut IRQ\n");
++                      return ret;
++              }
++      }
++
++      bgp->fclock = clk_get(NULL, bgp->conf->fclock_name);
++      ret = IS_ERR_OR_NULL(bgp->fclock);
++      if (ret) {
++              dev_err(&pdev->dev, "failed to request fclock reference\n");
++              goto free_irqs;
++      }
++
++      bgp->div_clk = clk_get(NULL,  bgp->conf->div_ck_name);
++      ret = IS_ERR_OR_NULL(bgp->div_clk);
++      if (ret) {
++              dev_err(&pdev->dev,
++                      "failed to request div_ts_ck clock ref\n");
++              goto free_irqs;
++      }
++
++      for (i = 0; i < bgp->conf->sensor_count; i++) {
++              struct temp_sensor_registers *tsr;
++              u32 val;
++
++              tsr = bgp->conf->sensors[i].registers;
++              /*
++               * check if the efuse has a non-zero value if not
++               * it is an untrimmed sample and the temperatures
++               * may not be accurate
++               */
++              val = ti_bandgap_readl(bgp, tsr->bgap_efuse);
++              if (ret || !val)
++                      dev_info(&pdev->dev,
++                               "Non-trimmed BGAP, Temp not accurate\n");
++      }
++
++      clk_rate = clk_round_rate(bgp->div_clk,
++                                bgp->conf->sensors[0].ts_data->max_freq);
++      if (clk_rate < bgp->conf->sensors[0].ts_data->min_freq ||
++          clk_rate == 0xffffffff) {
++              ret = -ENODEV;
++              dev_err(&pdev->dev, "wrong clock rate (%d)\n", clk_rate);
++              goto put_clks;
++      }
++
++      ret = clk_set_rate(bgp->div_clk, clk_rate);
++      if (ret)
++              dev_err(&pdev->dev, "Cannot re-set clock rate. Continuing\n");
++
++      bgp->clk_rate = clk_rate;
++      if (TI_BANDGAP_HAS(bgp, CLK_CTRL))
++              clk_prepare_enable(bgp->fclock);
++
++
++      spin_lock_init(&bgp->lock);
++      bgp->dev = &pdev->dev;
++      platform_set_drvdata(pdev, bgp);
++
++      ti_bandgap_power(bgp, true);
++
++      /* Set default counter to 1 for now */
++      if (TI_BANDGAP_HAS(bgp, COUNTER))
++              for (i = 0; i < bgp->conf->sensor_count; i++)
++                      RMW_BITS(bgp, i, bgap_counter, counter_mask, 1);
++
++      /* Set default thresholds for alert and shutdown */
++      for (i = 0; i < bgp->conf->sensor_count; i++) {
++              struct temp_sensor_data *ts_data;
++
++              ts_data = bgp->conf->sensors[i].ts_data;
++
++              if (TI_BANDGAP_HAS(bgp, TALERT)) {
++                      /* Set initial Talert thresholds */
++                      RMW_BITS(bgp, i, bgap_threshold,
++                               threshold_tcold_mask, ts_data->t_cold);
++                      RMW_BITS(bgp, i, bgap_threshold,
++                               threshold_thot_mask, ts_data->t_hot);
++                      /* Enable the alert events */
++                      RMW_BITS(bgp, i, bgap_mask_ctrl, mask_hot_mask, 1);
++                      RMW_BITS(bgp, i, bgap_mask_ctrl, mask_cold_mask, 1);
++              }
++
++              if (TI_BANDGAP_HAS(bgp, TSHUT_CONFIG)) {
++                      /* Set initial Tshut thresholds */
++                      RMW_BITS(bgp, i, tshut_threshold,
++                               tshut_hot_mask, ts_data->tshut_hot);
++                      RMW_BITS(bgp, i, tshut_threshold,
++                               tshut_cold_mask, ts_data->tshut_cold);
++              }
++      }
++
++      if (TI_BANDGAP_HAS(bgp, MODE_CONFIG))
++              ti_bandgap_set_continuous_mode(bgp);
++
++      /* Set .250 seconds time as default counter */
++      if (TI_BANDGAP_HAS(bgp, COUNTER))
++              for (i = 0; i < bgp->conf->sensor_count; i++)
++                      RMW_BITS(bgp, i, bgap_counter, counter_mask,
++                               bgp->clk_rate / 4);
++
++      /* Every thing is good? Then expose the sensors */
++      for (i = 0; i < bgp->conf->sensor_count; i++) {
++              char *domain;
++
++              if (bgp->conf->sensors[i].register_cooling) {
++                      ret = bgp->conf->sensors[i].register_cooling(bgp, i);
++                      if (ret)
++                              goto remove_sensors;
++              }
++
++              if (bgp->conf->expose_sensor) {
++                      domain = bgp->conf->sensors[i].domain;
++                      ret = bgp->conf->expose_sensor(bgp, i, domain);
++                      if (ret)
++                              goto remove_last_cooling;
++              }
++      }
++
++      /*
++       * Enable the Interrupts once everything is set. Otherwise irq handler
++       * might be called as soon as it is enabled where as rest of framework
++       * is still getting initialised.
++       */
++      if (TI_BANDGAP_HAS(bgp, TALERT)) {
++              ret = ti_bandgap_talert_init(bgp, pdev);
++              if (ret) {
++                      dev_err(&pdev->dev, "failed to initialize Talert IRQ\n");
++                      i = bgp->conf->sensor_count;
++                      goto disable_clk;
++              }
++      }
++
++      return 0;
++
++remove_last_cooling:
++      if (bgp->conf->sensors[i].unregister_cooling)
++              bgp->conf->sensors[i].unregister_cooling(bgp, i);
++remove_sensors:
++      for (i--; i >= 0; i--) {
++              if (bgp->conf->sensors[i].unregister_cooling)
++                      bgp->conf->sensors[i].unregister_cooling(bgp, i);
++              if (bgp->conf->remove_sensor)
++                      bgp->conf->remove_sensor(bgp, i);
++      }
++      ti_bandgap_power(bgp, false);
++disable_clk:
++      if (TI_BANDGAP_HAS(bgp, CLK_CTRL))
++              clk_disable_unprepare(bgp->fclock);
++put_clks:
++      clk_put(bgp->fclock);
++      clk_put(bgp->div_clk);
++free_irqs:
++      if (TI_BANDGAP_HAS(bgp, TSHUT)) {
++              free_irq(gpio_to_irq(bgp->tshut_gpio), NULL);
++              gpio_free(bgp->tshut_gpio);
++      }
++
++      return ret;
++}
++
++static
++int ti_bandgap_remove(struct platform_device *pdev)
++{
++      struct ti_bandgap *bgp = platform_get_drvdata(pdev);
++      int i;
++
++      /* First thing is to remove sensor interfaces */
++      for (i = 0; i < bgp->conf->sensor_count; i++) {
++              if (bgp->conf->sensors[i].unregister_cooling)
++                      bgp->conf->sensors[i].unregister_cooling(bgp, i);
++
++              if (bgp->conf->remove_sensor)
++                      bgp->conf->remove_sensor(bgp, i);
++      }
++
++      ti_bandgap_power(bgp, false);
++
++      if (TI_BANDGAP_HAS(bgp, CLK_CTRL))
++              clk_disable_unprepare(bgp->fclock);
++      clk_put(bgp->fclock);
++      clk_put(bgp->div_clk);
++
++      if (TI_BANDGAP_HAS(bgp, TALERT))
++              free_irq(bgp->irq, bgp);
++
++      if (TI_BANDGAP_HAS(bgp, TSHUT)) {
++              free_irq(gpio_to_irq(bgp->tshut_gpio), NULL);
++              gpio_free(bgp->tshut_gpio);
++      }
++
++      return 0;
++}
++
++#ifdef CONFIG_PM
++static int ti_bandgap_save_ctxt(struct ti_bandgap *bgp)
++{
++      int i;
++
++      for (i = 0; i < bgp->conf->sensor_count; i++) {
++              struct temp_sensor_registers *tsr;
++              struct temp_sensor_regval *rval;
++
++              rval = &bgp->regval[i];
++              tsr = bgp->conf->sensors[i].registers;
++
++              if (TI_BANDGAP_HAS(bgp, MODE_CONFIG))
++                      rval->bg_mode_ctrl = ti_bandgap_readl(bgp,
++                                                      tsr->bgap_mode_ctrl);
++              if (TI_BANDGAP_HAS(bgp, COUNTER))
++                      rval->bg_counter = ti_bandgap_readl(bgp,
++                                                      tsr->bgap_counter);
++              if (TI_BANDGAP_HAS(bgp, TALERT)) {
++                      rval->bg_threshold = ti_bandgap_readl(bgp,
++                                                      tsr->bgap_threshold);
++                      rval->bg_ctrl = ti_bandgap_readl(bgp,
++                                                 tsr->bgap_mask_ctrl);
++              }
++
++              if (TI_BANDGAP_HAS(bgp, TSHUT_CONFIG))
++                      rval->tshut_threshold = ti_bandgap_readl(bgp,
++                                                 tsr->tshut_threshold);
++      }
++
++      return 0;
++}
++
++static int ti_bandgap_restore_ctxt(struct ti_bandgap *bgp)
++{
++      int i;
++
++      for (i = 0; i < bgp->conf->sensor_count; i++) {
++              struct temp_sensor_registers *tsr;
++              struct temp_sensor_regval *rval;
++              u32 val = 0;
++
++              rval = &bgp->regval[i];
++              tsr = bgp->conf->sensors[i].registers;
++
++              if (TI_BANDGAP_HAS(bgp, COUNTER))
++                      val = ti_bandgap_readl(bgp, tsr->bgap_counter);
++
++              if (TI_BANDGAP_HAS(bgp, TSHUT_CONFIG))
++                      ti_bandgap_writel(bgp, rval->tshut_threshold,
++                                        tsr->tshut_threshold);
++              /* Force immediate temperature measurement and update
++               * of the DTEMP field
++               */
++              ti_bandgap_force_single_read(bgp, i);
++
++              if (TI_BANDGAP_HAS(bgp, COUNTER))
++                      ti_bandgap_writel(bgp, rval->bg_counter,
++                                        tsr->bgap_counter);
++              if (TI_BANDGAP_HAS(bgp, MODE_CONFIG))
++                      ti_bandgap_writel(bgp, rval->bg_mode_ctrl,
++                                        tsr->bgap_mode_ctrl);
++              if (TI_BANDGAP_HAS(bgp, TALERT)) {
++                      ti_bandgap_writel(bgp, rval->bg_threshold,
++                                        tsr->bgap_threshold);
++                      ti_bandgap_writel(bgp, rval->bg_ctrl,
++                                        tsr->bgap_mask_ctrl);
++              }
++      }
++
++      return 0;
++}
++
++static int ti_bandgap_suspend(struct device *dev)
++{
++      struct ti_bandgap *bgp = dev_get_drvdata(dev);
++      int err;
++
++      err = ti_bandgap_save_ctxt(bgp);
++      ti_bandgap_power(bgp, false);
++
++      if (TI_BANDGAP_HAS(bgp, CLK_CTRL))
++              clk_disable_unprepare(bgp->fclock);
++
++      return err;
++}
++
++static int ti_bandgap_resume(struct device *dev)
++{
++      struct ti_bandgap *bgp = dev_get_drvdata(dev);
++
++      if (TI_BANDGAP_HAS(bgp, CLK_CTRL))
++              clk_prepare_enable(bgp->fclock);
++
++      ti_bandgap_power(bgp, true);
++
++      return ti_bandgap_restore_ctxt(bgp);
++}
++static const struct dev_pm_ops ti_bandgap_dev_pm_ops = {
++      SET_SYSTEM_SLEEP_PM_OPS(ti_bandgap_suspend,
++                              ti_bandgap_resume)
++};
++
++#define DEV_PM_OPS    (&ti_bandgap_dev_pm_ops)
++#else
++#define DEV_PM_OPS    NULL
++#endif
++
++static const struct of_device_id of_ti_bandgap_match[] = {
++#ifdef CONFIG_OMAP4_THERMAL
++      {
++              .compatible = "ti,omap4430-bandgap",
++              .data = (void *)&omap4430_data,
++      },
++      {
++              .compatible = "ti,omap4460-bandgap",
++              .data = (void *)&omap4460_data,
++      },
++      {
++              .compatible = "ti,omap4470-bandgap",
++              .data = (void *)&omap4470_data,
++      },
++#endif
++#ifdef CONFIG_OMAP5_THERMAL
++      {
++              .compatible = "ti,omap5430-bandgap",
++              .data = (void *)&omap5430_data,
++      },
++#endif
++      /* Sentinel */
++      { },
++};
++MODULE_DEVICE_TABLE(of, of_ti_bandgap_match);
++
++static struct platform_driver ti_bandgap_sensor_driver = {
++      .probe = ti_bandgap_probe,
++      .remove = ti_bandgap_remove,
++      .driver = {
++                      .name = "ti-soc-thermal",
++                      .pm = DEV_PM_OPS,
++                      .of_match_table = of_ti_bandgap_match,
++      },
++};
++
++module_platform_driver(ti_bandgap_sensor_driver);
++
++MODULE_DESCRIPTION("OMAP4+ bandgap temperature sensor driver");
++MODULE_LICENSE("GPL v2");
++MODULE_ALIAS("platform:ti-soc-thermal");
++MODULE_AUTHOR("Texas Instrument Inc.");
+diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.h b/drivers/thermal/ti-soc-thermal/ti-bandgap.h
+new file mode 100644
+index 0000000..5f4794a
+--- /dev/null
++++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.h
+@@ -0,0 +1,403 @@
++/*
++ * OMAP4 Bandgap temperature sensor driver
++ *
++ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
++ * Contact:
++ *   Eduardo Valentin <eduardo.valentin@ti.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
++ * 02110-1301 USA
++ *
++ */
++#ifndef __TI_BANDGAP_H
++#define __TI_BANDGAP_H
++
++#include <linux/spinlock.h>
++#include <linux/types.h>
++#include <linux/err.h>
++
++/**
++ * DOC: bandgap driver data structure
++ * ==================================
++ *
++ *   +----------+----------------+
++ *   | struct temp_sensor_regval |
++ *   +---------------------------+
++ *              * (Array of)
++ *              |
++ *              |
++ *   +-------------------+   +-----------------+
++ *   | struct ti_bandgap |-->| struct device * |
++ *   +----------+--------+   +-----------------+
++ *              |
++ *              |
++ *              V
++ *   +------------------------+
++ *   | struct ti_bandgap_data |
++ *   +------------------------+
++ *              |
++ *              |
++ *              * (Array of)
++ * +------------+------------------------------------------------------+
++ * | +----------+------------+   +-------------------------+           |
++ * | | struct ti_temp_sensor |-->| struct temp_sensor_data |           |
++ * | +-----------------------+   +------------+------------+           |
++ * |            |                                                      |
++ * |            +                                                      |
++ * |            V                                                      |
++ * | +----------+-------------------+                                  |
++ * | | struct temp_sensor_registers |                                  |
++ * | +------------------------------+                                  |
++ * |                                                                   |
++ * +-------------------------------------------------------------------+
++ *
++ * Above is a simple diagram describing how the data structure below
++ * are organized. For each bandgap device there should be a ti_bandgap_data
++ * containing the device instance configuration, as well as, an array of
++ * sensors, representing every sensor instance present in this bandgap.
++ */
++
++/**
++ * struct temp_sensor_registers - descriptor to access registers and bitfields
++ * @temp_sensor_ctrl: TEMP_SENSOR_CTRL register offset
++ * @bgap_tempsoff_mask: mask to temp_sensor_ctrl.tempsoff
++ * @bgap_soc_mask: mask to temp_sensor_ctrl.soc
++ * @bgap_eocz_mask: mask to temp_sensor_ctrl.eocz
++ * @bgap_dtemp_mask: mask to temp_sensor_ctrl.dtemp
++ * @bgap_mask_ctrl: BANDGAP_MASK_CTRL register offset
++ * @mask_hot_mask: mask to bandgap_mask_ctrl.mask_hot
++ * @mask_cold_mask: mask to bandgap_mask_ctrl.mask_cold
++ * @mask_sidlemode_mask: mask to bandgap_mask_ctrl.mask_sidlemode
++ * @mask_counter_delay_mask: mask to bandgap_mask_ctrl.mask_counter_delay
++ * @mask_freeze_mask: mask to bandgap_mask_ctrl.mask_free
++ * @mask_clear_mask: mask to bandgap_mask_ctrl.mask_clear
++ * @mask_clear_accum_mask: mask to bandgap_mask_ctrl.mask_clear_accum
++ * @bgap_mode_ctrl: BANDGAP_MODE_CTRL register offset
++ * @mode_ctrl_mask: mask to bandgap_mode_ctrl.mode_ctrl
++ * @bgap_counter: BANDGAP_COUNTER register offset
++ * @counter_mask: mask to bandgap_counter.counter
++ * @bgap_threshold: BANDGAP_THRESHOLD register offset (TALERT thresholds)
++ * @threshold_thot_mask: mask to bandgap_threhold.thot
++ * @threshold_tcold_mask: mask to bandgap_threhold.tcold
++ * @tshut_threshold: TSHUT_THRESHOLD register offset (TSHUT thresholds)
++ * @tshut_efuse_mask: mask to tshut_threshold.tshut_efuse
++ * @tshut_efuse_shift: shift to tshut_threshold.tshut_efuse
++ * @tshut_hot_mask: mask to tshut_threhold.thot
++ * @tshut_cold_mask: mask to tshut_threhold.thot
++ * @bgap_status: BANDGAP_STATUS register offset
++ * @status_clean_stop_mask: mask to bandgap_status.clean_stop
++ * @status_bgap_alert_mask: mask to bandgap_status.bandgap_alert
++ * @status_hot_mask: mask to bandgap_status.hot
++ * @status_cold_mask: mask to bandgap_status.cold
++ * @bgap_cumul_dtemp: BANDGAP_CUMUL_DTEMP register offset
++ * @ctrl_dtemp_0: CTRL_DTEMP0 register offset
++ * @ctrl_dtemp_1: CTRL_DTEMP1 register offset
++ * @ctrl_dtemp_2: CTRL_DTEMP2 register offset
++ * @ctrl_dtemp_3: CTRL_DTEMP3 register offset
++ * @ctrl_dtemp_4: CTRL_DTEMP4 register offset
++ * @bgap_efuse: BANDGAP_EFUSE register offset
++ *
++ * The register offsets and bitfields might change across
++ * OMAP and variants versions. Hence this struct serves as a
++ * descriptor map on how to access the registers and the bitfields.
++ *
++ * This descriptor contains registers of all versions of bandgap chips.
++ * Not all versions will use all registers, depending on the available
++ * features. Please read TRMs for descriptive explanation on each bitfield.
++ */
++
++struct temp_sensor_registers {
++      u32     temp_sensor_ctrl;
++      u32     bgap_tempsoff_mask;
++      u32     bgap_soc_mask;
++      u32     bgap_eocz_mask; /* not used: but needs revisit */
++      u32     bgap_dtemp_mask;
++
++      u32     bgap_mask_ctrl;
++      u32     mask_hot_mask;
++      u32     mask_cold_mask;
++      u32     mask_sidlemode_mask; /* not used: but may be needed for pm */
++      u32     mask_counter_delay_mask;
++      u32     mask_freeze_mask;
++      u32     mask_clear_mask; /* not used: but needed for trending */
++      u32     mask_clear_accum_mask; /* not used: but needed for trending */
++
++      u32     bgap_mode_ctrl;
++      u32     mode_ctrl_mask;
++
++      u32     bgap_counter;
++      u32     counter_mask;
++
++      u32     bgap_threshold;
++      u32     threshold_thot_mask;
++      u32     threshold_tcold_mask;
++
++      u32     tshut_threshold;
++      u32     tshut_efuse_mask; /* not used */
++      u32     tshut_efuse_shift; /* not used */
++      u32     tshut_hot_mask;
++      u32     tshut_cold_mask;
++
++      u32     bgap_status;
++      u32     status_clean_stop_mask; /* not used: but needed for trending */
++      u32     status_bgap_alert_mask; /* not used */
++      u32     status_hot_mask;
++      u32     status_cold_mask;
++
++      u32     bgap_cumul_dtemp; /* not used: but needed for trending */
++      u32     ctrl_dtemp_0; /* not used: but needed for trending */
++      u32     ctrl_dtemp_1; /* not used: but needed for trending */
++      u32     ctrl_dtemp_2; /* not used: but needed for trending */
++      u32     ctrl_dtemp_3; /* not used: but needed for trending */
++      u32     ctrl_dtemp_4; /* not used: but needed for trending */
++      u32     bgap_efuse;
++};
++
++/**
++ * struct temp_sensor_data - The thresholds and limits for temperature sensors.
++ * @tshut_hot: temperature to trigger a thermal reset (initial value)
++ * @tshut_cold: temp to get the plat out of reset due to thermal (init val)
++ * @t_hot: temperature to trigger a thermal alert (high initial value)
++ * @t_cold: temperature to trigger a thermal alert (low initial value)
++ * @min_freq: sensor minimum clock rate
++ * @max_freq: sensor maximum clock rate
++ * @max_temp: sensor maximum temperature
++ * @min_temp: sensor minimum temperature
++ * @hyst_val: temperature hysteresis considered while converting ADC values
++ * @update_int1: update interval
++ * @update_int2: update interval
++ *
++ * This data structure will hold the required thresholds and temperature limits
++ * for a specific temperature sensor, like shutdown temperature, alert
++ * temperature, clock / rate used, ADC conversion limits and update intervals
++ */
++struct temp_sensor_data {
++      u32     tshut_hot;
++      u32     tshut_cold;
++      u32     t_hot;
++      u32     t_cold;
++      u32     min_freq;
++      u32     max_freq;
++      int     max_temp;
++      int     min_temp;
++      int     hyst_val;
++      u32     update_int1; /* not used */
++      u32     update_int2; /* not used */
++};
++
++struct ti_bandgap_data;
++
++/**
++ * struct temp_sensor_regval - temperature sensor register values and priv data
++ * @bg_mode_ctrl: temp sensor control register value
++ * @bg_ctrl: bandgap ctrl register value
++ * @bg_counter: bandgap counter value
++ * @bg_threshold: bandgap threshold register value
++ * @tshut_threshold: bandgap tshut register value
++ * @data: private data
++ *
++ * Data structure to save and restore bandgap register set context. Only
++ * required registers are shadowed, when needed.
++ */
++struct temp_sensor_regval {
++      u32                     bg_mode_ctrl;
++      u32                     bg_ctrl;
++      u32                     bg_counter;
++      u32                     bg_threshold;
++      u32                     tshut_threshold;
++      void                    *data;
++};
++
++/**
++ * struct ti_bandgap - bandgap device structure
++ * @dev: struct device pointer
++ * @base: io memory base address
++ * @conf: struct with bandgap configuration set (# sensors, conv_table, etc)
++ * @regval: temperature sensor register values
++ * @fclock: pointer to functional clock of temperature sensor
++ * @div_clk: pointer to divider clock of temperature sensor fclk
++ * @lock: spinlock for ti_bandgap structure
++ * @irq: MPU IRQ number for thermal alert
++ * @tshut_gpio: GPIO where Tshut signal is routed
++ * @clk_rate: Holds current clock rate
++ *
++ * The bandgap device structure representing the bandgap device instance.
++ * It holds most of the dynamic stuff. Configurations and sensor specific
++ * entries are inside the @conf structure.
++ */
++struct ti_bandgap {
++      struct device                   *dev;
++      void __iomem                    *base;
++      const struct ti_bandgap_data    *conf;
++      struct temp_sensor_regval       *regval;
++      struct clk                      *fclock;
++      struct clk                      *div_clk;
++      spinlock_t                      lock; /* shields this struct */
++      int                             irq;
++      int                             tshut_gpio;
++      u32                             clk_rate;
++};
++
++/**
++ * struct ti_temp_sensor - bandgap temperature sensor configuration data
++ * @ts_data: pointer to struct with thresholds, limits of temperature sensor
++ * @registers: pointer to the list of register offsets and bitfields
++ * @domain: the name of the domain where the sensor is located
++ * @slope: sensor gradient slope info for hotspot extrapolation equation
++ * @constant: sensor gradient const info for hotspot extrapolation equation
++ * @slope_pcb: sensor gradient slope info for hotspot extrapolation equation
++ *             with no external influence
++ * @constant_pcb: sensor gradient const info for hotspot extrapolation equation
++ *             with no external influence
++ * @register_cooling: function to describe how this sensor is going to be cooled
++ * @unregister_cooling: function to release cooling data
++ *
++ * Data structure to describe a temperature sensor handled by a bandgap device.
++ * It should provide configuration details on this sensor, such as how to
++ * access the registers affecting this sensor, shadow register buffer, how to
++ * assess the gradient from hotspot, how to cooldown the domain when sensor
++ * reports too hot temperature.
++ */
++struct ti_temp_sensor {
++      struct temp_sensor_data         *ts_data;
++      struct temp_sensor_registers    *registers;
++      char                            *domain;
++      /* for hotspot extrapolation */
++      const int                       slope;
++      const int                       constant;
++      const int                       slope_pcb;
++      const int                       constant_pcb;
++      int (*register_cooling)(struct ti_bandgap *bgp, int id);
++      int (*unregister_cooling)(struct ti_bandgap *bgp, int id);
++};
++
++/**
++ * DOC: ti bandgap feature types
++ *
++ * TI_BANDGAP_FEATURE_TSHUT - used when the thermal shutdown signal output
++ *      of a bandgap device instance is routed to the processor. This means
++ *      the system must react and perform the shutdown by itself (handle an
++ *      IRQ, for instance).
++ *
++ * TI_BANDGAP_FEATURE_TSHUT_CONFIG - used when the bandgap device has control
++ *      over the thermal shutdown configuration. This means that the thermal
++ *      shutdown thresholds are programmable, for instance.
++ *
++ * TI_BANDGAP_FEATURE_TALERT - used when the bandgap device instance outputs
++ *      a signal representing violation of programmable alert thresholds.
++ *
++ * TI_BANDGAP_FEATURE_MODE_CONFIG - used when it is possible to choose which
++ *      mode, continuous or one shot, the bandgap device instance will operate.
++ *
++ * TI_BANDGAP_FEATURE_COUNTER - used when the bandgap device instance allows
++ *      programming the update interval of its internal state machine.
++ *
++ * TI_BANDGAP_FEATURE_POWER_SWITCH - used when the bandgap device allows
++ *      itself to be switched on/off.
++ *
++ * TI_BANDGAP_FEATURE_CLK_CTRL - used when the clocks feeding the bandgap
++ *      device are gateable or not.
++ *
++ * TI_BANDGAP_FEATURE_FREEZE_BIT - used when the bandgap device features
++ *      a history buffer that its update can be freezed/unfreezed.
++ *
++ * TI_BANDGAP_FEATURE_COUNTER_DELAY - used when the bandgap device features
++ *    a delay programming based on distinct values.
++ *
++ * TI_BANDGAP_FEATURE_HISTORY_BUFFER - used when the bandgap device features
++ *    a history buffer of temperatures.
++ *
++ * TI_BANDGAP_HAS(b, f) - macro to check if a bandgap device is capable of a
++ *      specific feature (above) or not. Return non-zero, if yes.
++ */
++#define TI_BANDGAP_FEATURE_TSHUT              BIT(0)
++#define TI_BANDGAP_FEATURE_TSHUT_CONFIG               BIT(1)
++#define TI_BANDGAP_FEATURE_TALERT             BIT(2)
++#define TI_BANDGAP_FEATURE_MODE_CONFIG                BIT(3)
++#define TI_BANDGAP_FEATURE_COUNTER            BIT(4)
++#define TI_BANDGAP_FEATURE_POWER_SWITCH               BIT(5)
++#define TI_BANDGAP_FEATURE_CLK_CTRL           BIT(6)
++#define TI_BANDGAP_FEATURE_FREEZE_BIT         BIT(7)
++#define TI_BANDGAP_FEATURE_COUNTER_DELAY      BIT(8)
++#define TI_BANDGAP_FEATURE_HISTORY_BUFFER     BIT(9)
++#define TI_BANDGAP_HAS(b, f)                  \
++                      ((b)->conf->features & TI_BANDGAP_FEATURE_ ## f)
++
++/**
++ * struct ti_bandgap_data - ti bandgap data configuration structure
++ * @features: a bitwise flag set to describe the device features
++ * @conv_table: Pointer to ADC to temperature conversion table
++ * @adc_start_val: ADC conversion table starting value
++ * @adc_end_val: ADC conversion table ending value
++ * @fclock_name: clock name of the functional clock
++ * @div_ck_name: clock name of the clock divisor
++ * @sensor_count: count of temperature sensor within this bandgap device
++ * @report_temperature: callback to report thermal alert to thermal API
++ * @expose_sensor: callback to export sensor to thermal API
++ * @remove_sensor: callback to destroy sensor from thermal API
++ * @sensors: array of sensors present in this bandgap instance
++ *
++ * This is a data structure which should hold most of the static configuration
++ * of a bandgap device instance. It should describe which features this instance
++ * is capable of, the clock names to feed this device, the amount of sensors and
++ * their configuration representation, and how to export and unexport them to
++ * a thermal API.
++ */
++struct ti_bandgap_data {
++      unsigned int                    features;
++      const int                       *conv_table;
++      u32                             adc_start_val;
++      u32                             adc_end_val;
++      char                            *fclock_name;
++      char                            *div_ck_name;
++      int                             sensor_count;
++      int (*report_temperature)(struct ti_bandgap *bgp, int id);
++      int (*expose_sensor)(struct ti_bandgap *bgp, int id, char *domain);
++      int (*remove_sensor)(struct ti_bandgap *bgp, int id);
++
++      /* this needs to be at the end */
++      struct ti_temp_sensor           sensors[];
++};
++
++int ti_bandgap_read_thot(struct ti_bandgap *bgp, int id, int *thot);
++int ti_bandgap_write_thot(struct ti_bandgap *bgp, int id, int val);
++int ti_bandgap_read_tcold(struct ti_bandgap *bgp, int id, int *tcold);
++int ti_bandgap_write_tcold(struct ti_bandgap *bgp, int id, int val);
++int ti_bandgap_read_update_interval(struct ti_bandgap *bgp, int id,
++                                  int *interval);
++int ti_bandgap_write_update_interval(struct ti_bandgap *bgp, int id,
++                                   u32 interval);
++int ti_bandgap_read_temperature(struct ti_bandgap *bgp, int id,
++                                int *temperature);
++int ti_bandgap_set_sensor_data(struct ti_bandgap *bgp, int id, void *data);
++void *ti_bandgap_get_sensor_data(struct ti_bandgap *bgp, int id);
++int ti_bandgap_get_trend(struct ti_bandgap *bgp, int id, int *trend);
++
++#ifdef CONFIG_OMAP4_THERMAL
++extern const struct ti_bandgap_data omap4430_data;
++extern const struct ti_bandgap_data omap4460_data;
++extern const struct ti_bandgap_data omap4470_data;
++#else
++#define omap4430_data                                 NULL
++#define omap4460_data                                 NULL
++#define omap4470_data                                 NULL
++#endif
++
++#ifdef CONFIG_OMAP5_THERMAL
++extern const struct ti_bandgap_data omap5430_data;
++#else
++#define omap5430_data                                 NULL
++#endif
++
++#endif
+diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+new file mode 100644
+index 0000000..e3c5e67
+--- /dev/null
++++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+@@ -0,0 +1,367 @@
++/*
++ * OMAP thermal driver interface
++ *
++ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
++ * Contact:
++ *   Eduardo Valentin <eduardo.valentin@ti.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
++ * 02110-1301 USA
++ *
++ */
++
++#include <linux/device.h>
++#include <linux/err.h>
++#include <linux/mutex.h>
++#include <linux/gfp.h>
++#include <linux/kernel.h>
++#include <linux/workqueue.h>
++#include <linux/thermal.h>
++#include <linux/cpufreq.h>
++#include <linux/cpumask.h>
++#include <linux/cpu_cooling.h>
++
++#include "ti-thermal.h"
++#include "ti-bandgap.h"
++
++/* common data structures */
++struct ti_thermal_data {
++      struct thermal_zone_device *ti_thermal;
++      struct thermal_cooling_device *cool_dev;
++      struct ti_bandgap *bgp;
++      enum thermal_device_mode mode;
++      struct work_struct thermal_wq;
++      int sensor_id;
++};
++
++static void ti_thermal_work(struct work_struct *work)
++{
++      struct ti_thermal_data *data = container_of(work,
++                                      struct ti_thermal_data, thermal_wq);
++
++      thermal_zone_device_update(data->ti_thermal);
++
++      dev_dbg(&data->ti_thermal->device, "updated thermal zone %s\n",
++              data->ti_thermal->type);
++}
++
++/**
++ * ti_thermal_hotspot_temperature - returns sensor extrapolated temperature
++ * @t:        omap sensor temperature
++ * @s:        omap sensor slope value
++ * @c:        omap sensor const value
++ */
++static inline int ti_thermal_hotspot_temperature(int t, int s, int c)
++{
++      int delta = t * s / 1000 + c;
++
++      if (delta < 0)
++              delta = 0;
++
++      return t + delta;
++}
++
++/* thermal zone ops */
++/* Get temperature callback function for thermal zone*/
++static inline int ti_thermal_get_temp(struct thermal_zone_device *thermal,
++                                    unsigned long *temp)
++{
++      struct ti_thermal_data *data = thermal->devdata;
++      struct ti_bandgap *bgp;
++      const struct ti_temp_sensor *s;
++      int ret, tmp, pcb_temp, slope, constant;
++
++      if (!data)
++              return 0;
++
++      bgp = data->bgp;
++      s = &bgp->conf->sensors[data->sensor_id];
++
++      ret = ti_bandgap_read_temperature(bgp, data->sensor_id, &tmp);
++      if (ret)
++              return ret;
++
++      pcb_temp = 0;
++      /* TODO: Introduce pcb temperature lookup */
++      /* In case pcb zone is available, use the extrapolation rule with it */
++      if (pcb_temp) {
++              tmp -= pcb_temp;
++              slope = s->slope_pcb;
++              constant = s->constant_pcb;
++      } else {
++              slope = s->slope;
++              constant = s->constant;
++      }
++      *temp = ti_thermal_hotspot_temperature(tmp, slope, constant);
++
++      return ret;
++}
++
++/* Bind callback functions for thermal zone */
++static int ti_thermal_bind(struct thermal_zone_device *thermal,
++                         struct thermal_cooling_device *cdev)
++{
++      struct ti_thermal_data *data = thermal->devdata;
++      int id;
++
++      if (IS_ERR_OR_NULL(data))
++              return -ENODEV;
++
++      /* check if this is the cooling device we registered */
++      if (data->cool_dev != cdev)
++              return 0;
++
++      id = data->sensor_id;
++
++      /* Simple thing, two trips, one passive another critical */
++      return thermal_zone_bind_cooling_device(thermal, 0, cdev,
++      /* bind with min and max states defined by cpu_cooling */
++                                              THERMAL_NO_LIMIT,
++                                              THERMAL_NO_LIMIT);
++}
++
++/* Unbind callback functions for thermal zone */
++static int ti_thermal_unbind(struct thermal_zone_device *thermal,
++                           struct thermal_cooling_device *cdev)
++{
++      struct ti_thermal_data *data = thermal->devdata;
++
++      if (IS_ERR_OR_NULL(data))
++              return -ENODEV;
++
++      /* check if this is the cooling device we registered */
++      if (data->cool_dev != cdev)
++              return 0;
++
++      /* Simple thing, two trips, one passive another critical */
++      return thermal_zone_unbind_cooling_device(thermal, 0, cdev);
++}
++
++/* Get mode callback functions for thermal zone */
++static int ti_thermal_get_mode(struct thermal_zone_device *thermal,
++                             enum thermal_device_mode *mode)
++{
++      struct ti_thermal_data *data = thermal->devdata;
++
++      if (data)
++              *mode = data->mode;
++
++      return 0;
++}
++
++/* Set mode callback functions for thermal zone */
++static int ti_thermal_set_mode(struct thermal_zone_device *thermal,
++                             enum thermal_device_mode mode)
++{
++      struct ti_thermal_data *data = thermal->devdata;
++
++      if (!data->ti_thermal) {
++              dev_notice(&thermal->device, "thermal zone not registered\n");
++              return 0;
++      }
++
++      mutex_lock(&data->ti_thermal->lock);
++
++      if (mode == THERMAL_DEVICE_ENABLED)
++              data->ti_thermal->polling_delay = FAST_TEMP_MONITORING_RATE;
++      else
++              data->ti_thermal->polling_delay = 0;
++
++      mutex_unlock(&data->ti_thermal->lock);
++
++      data->mode = mode;
++      thermal_zone_device_update(data->ti_thermal);
++      dev_dbg(&thermal->device, "thermal polling set for duration=%d msec\n",
++              data->ti_thermal->polling_delay);
++
++      return 0;
++}
++
++/* Get trip type callback functions for thermal zone */
++static int ti_thermal_get_trip_type(struct thermal_zone_device *thermal,
++                                  int trip, enum thermal_trip_type *type)
++{
++      if (!ti_thermal_is_valid_trip(trip))
++              return -EINVAL;
++
++      if (trip + 1 == OMAP_TRIP_NUMBER)
++              *type = THERMAL_TRIP_CRITICAL;
++      else
++              *type = THERMAL_TRIP_PASSIVE;
++
++      return 0;
++}
++
++/* Get trip temperature callback functions for thermal zone */
++static int ti_thermal_get_trip_temp(struct thermal_zone_device *thermal,
++                                  int trip, unsigned long *temp)
++{
++      if (!ti_thermal_is_valid_trip(trip))
++              return -EINVAL;
++
++      *temp = ti_thermal_get_trip_value(trip);
++
++      return 0;
++}
++
++/* Get the temperature trend callback functions for thermal zone */
++static int ti_thermal_get_trend(struct thermal_zone_device *thermal,
++                              int trip, enum thermal_trend *trend)
++{
++      struct ti_thermal_data *data = thermal->devdata;
++      struct ti_bandgap *bgp;
++      int id, tr, ret = 0;
++
++      bgp = data->bgp;
++      id = data->sensor_id;
++
++      ret = ti_bandgap_get_trend(bgp, id, &tr);
++      if (ret)
++              return ret;
++
++      if (tr > 0)
++              *trend = THERMAL_TREND_RAISING;
++      else if (tr < 0)
++              *trend = THERMAL_TREND_DROPPING;
++      else
++              *trend = THERMAL_TREND_STABLE;
++
++      return 0;
++}
++
++/* Get critical temperature callback functions for thermal zone */
++static int ti_thermal_get_crit_temp(struct thermal_zone_device *thermal,
++                                  unsigned long *temp)
++{
++      /* shutdown zone */
++      return ti_thermal_get_trip_temp(thermal, OMAP_TRIP_NUMBER - 1, temp);
++}
++
++static struct thermal_zone_device_ops ti_thermal_ops = {
++      .get_temp = ti_thermal_get_temp,
++      .get_trend = ti_thermal_get_trend,
++      .bind = ti_thermal_bind,
++      .unbind = ti_thermal_unbind,
++      .get_mode = ti_thermal_get_mode,
++      .set_mode = ti_thermal_set_mode,
++      .get_trip_type = ti_thermal_get_trip_type,
++      .get_trip_temp = ti_thermal_get_trip_temp,
++      .get_crit_temp = ti_thermal_get_crit_temp,
++};
++
++static struct ti_thermal_data
++*ti_thermal_build_data(struct ti_bandgap *bgp, int id)
++{
++      struct ti_thermal_data *data;
++
++      data = devm_kzalloc(bgp->dev, sizeof(*data), GFP_KERNEL);
++      if (!data) {
++              dev_err(bgp->dev, "kzalloc fail\n");
++              return NULL;
++      }
++      data->sensor_id = id;
++      data->bgp = bgp;
++      data->mode = THERMAL_DEVICE_ENABLED;
++      INIT_WORK(&data->thermal_wq, ti_thermal_work);
++
++      return data;
++}
++
++int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id,
++                           char *domain)
++{
++      struct ti_thermal_data *data;
++
++      data = ti_bandgap_get_sensor_data(bgp, id);
++
++      if (IS_ERR_OR_NULL(data))
++              data = ti_thermal_build_data(bgp, id);
++
++      if (!data)
++              return -EINVAL;
++
++      /* Create thermal zone */
++      data->ti_thermal = thermal_zone_device_register(domain,
++                              OMAP_TRIP_NUMBER, 0, data, &ti_thermal_ops,
++                              NULL, FAST_TEMP_MONITORING_RATE,
++                              FAST_TEMP_MONITORING_RATE);
++      if (IS_ERR_OR_NULL(data->ti_thermal)) {
++              dev_err(bgp->dev, "thermal zone device is NULL\n");
++              return PTR_ERR(data->ti_thermal);
++      }
++      data->ti_thermal->polling_delay = FAST_TEMP_MONITORING_RATE;
++      ti_bandgap_set_sensor_data(bgp, id, data);
++
++      return 0;
++}
++
++int ti_thermal_remove_sensor(struct ti_bandgap *bgp, int id)
++{
++      struct ti_thermal_data *data;
++
++      data = ti_bandgap_get_sensor_data(bgp, id);
++
++      thermal_zone_device_unregister(data->ti_thermal);
++
++      return 0;
++}
++
++int ti_thermal_report_sensor_temperature(struct ti_bandgap *bgp, int id)
++{
++      struct ti_thermal_data *data;
++
++      data = ti_bandgap_get_sensor_data(bgp, id);
++
++      schedule_work(&data->thermal_wq);
++
++      return 0;
++}
++
++int ti_thermal_register_cpu_cooling(struct ti_bandgap *bgp, int id)
++{
++      struct ti_thermal_data *data;
++
++      data = ti_bandgap_get_sensor_data(bgp, id);
++      if (IS_ERR_OR_NULL(data))
++              data = ti_thermal_build_data(bgp, id);
++
++      if (!data)
++              return -EINVAL;
++
++      if (!cpufreq_get_current_driver()) {
++              dev_dbg(bgp->dev, "no cpufreq driver yet\n");
++              return -EPROBE_DEFER;
++      }
++
++      /* Register cooling device */
++      data->cool_dev = cpufreq_cooling_register(cpu_present_mask);
++      if (IS_ERR_OR_NULL(data->cool_dev)) {
++              dev_err(bgp->dev,
++                      "Failed to register cpufreq cooling device\n");
++              return PTR_ERR(data->cool_dev);
++      }
++      ti_bandgap_set_sensor_data(bgp, id, data);
++
++      return 0;
++}
++
++int ti_thermal_unregister_cpu_cooling(struct ti_bandgap *bgp, int id)
++{
++      struct ti_thermal_data *data;
++
++      data = ti_bandgap_get_sensor_data(bgp, id);
++      cpufreq_cooling_unregister(data->cool_dev);
++
++      return 0;
++}
+diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal.h b/drivers/thermal/ti-soc-thermal/ti-thermal.h
+new file mode 100644
+index 0000000..5055777
+--- /dev/null
++++ b/drivers/thermal/ti-soc-thermal/ti-thermal.h
+@@ -0,0 +1,117 @@
++/*
++ * OMAP thermal definitions
++ *
++ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
++ * Contact:
++ *   Eduardo Valentin <eduardo.valentin@ti.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
++ * 02110-1301 USA
++ *
++ */
++#ifndef __TI_THERMAL_H
++#define __TI_THERMAL_H
++
++#include "ti-bandgap.h"
++
++/* sensors gradient and offsets */
++#define OMAP_GRADIENT_SLOPE_4430                              0
++#define OMAP_GRADIENT_CONST_4430                              20000
++#define OMAP_GRADIENT_SLOPE_4460                              348
++#define OMAP_GRADIENT_CONST_4460                              -9301
++#define OMAP_GRADIENT_SLOPE_4470                              308
++#define OMAP_GRADIENT_CONST_4470                              -7896
++
++#define OMAP_GRADIENT_SLOPE_5430_CPU                          65
++#define OMAP_GRADIENT_CONST_5430_CPU                          -1791
++#define OMAP_GRADIENT_SLOPE_5430_GPU                          117
++#define OMAP_GRADIENT_CONST_5430_GPU                          -2992
++
++/* PCB sensor calculation constants */
++#define OMAP_GRADIENT_SLOPE_W_PCB_4430                                0
++#define OMAP_GRADIENT_CONST_W_PCB_4430                                20000
++#define OMAP_GRADIENT_SLOPE_W_PCB_4460                                1142
++#define OMAP_GRADIENT_CONST_W_PCB_4460                                -393
++#define OMAP_GRADIENT_SLOPE_W_PCB_4470                                1063
++#define OMAP_GRADIENT_CONST_W_PCB_4470                                -477
++
++#define OMAP_GRADIENT_SLOPE_W_PCB_5430_CPU                    100
++#define OMAP_GRADIENT_CONST_W_PCB_5430_CPU                    484
++#define OMAP_GRADIENT_SLOPE_W_PCB_5430_GPU                    464
++#define OMAP_GRADIENT_CONST_W_PCB_5430_GPU                    -5102
++
++/* trip points of interest in milicelsius (at hotspot level) */
++#define OMAP_TRIP_COLD                                                100000
++#define OMAP_TRIP_HOT                                         110000
++#define OMAP_TRIP_SHUTDOWN                                    125000
++#define OMAP_TRIP_NUMBER                                      2
++#define OMAP_TRIP_STEP                                                        \
++      ((OMAP_TRIP_SHUTDOWN - OMAP_TRIP_HOT) / (OMAP_TRIP_NUMBER - 1))
++
++/* Update rates */
++#define FAST_TEMP_MONITORING_RATE                             250
++
++/* helper macros */
++/**
++ * ti_thermal_get_trip_value - returns trip temperature based on index
++ * @i:        trip index
++ */
++#define ti_thermal_get_trip_value(i)                                  \
++      (OMAP_TRIP_HOT + ((i) * OMAP_TRIP_STEP))
++
++/**
++ * ti_thermal_is_valid_trip - check for trip index
++ * @i:        trip index
++ */
++#define ti_thermal_is_valid_trip(trip)                                \
++      ((trip) >= 0 && (trip) < OMAP_TRIP_NUMBER)
++
++#ifdef CONFIG_TI_THERMAL
++int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id, char *domain);
++int ti_thermal_remove_sensor(struct ti_bandgap *bgp, int id);
++int ti_thermal_report_sensor_temperature(struct ti_bandgap *bgp, int id);
++int ti_thermal_register_cpu_cooling(struct ti_bandgap *bgp, int id);
++int ti_thermal_unregister_cpu_cooling(struct ti_bandgap *bgp, int id);
++#else
++static inline
++int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id, char *domain)
++{
++      return 0;
++}
++
++static inline
++int ti_thermal_remove_sensor(struct ti_bandgap *bgp, int id)
++{
++      return 0;
++}
++
++static inline
++int ti_thermal_report_sensor_temperature(struct ti_bandgap *bgp, int id)
++{
++      return 0;
++}
++
++static inline
++int ti_thermal_register_cpu_cooling(struct ti_bandgap *bgp, int id)
++{
++      return 0;
++}
++
++static inline
++int ti_thermal_unregister_cpu_cooling(struct ti_bandgap *bgp, int id)
++{
++      return 0;
++}
++#endif
++#endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0931-Thermal-armada-Remove-redundant-use-of-of_match_ptr.patch b/patches.tizen/0931-Thermal-armada-Remove-redundant-use-of-of_match_ptr.patch
new file mode 100644 (file)
index 0000000..e891ba3
--- /dev/null
@@ -0,0 +1,34 @@
+From d5164cdafd9a6b466d44d406899295756f14a0f1 Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Thu, 16 May 2013 10:28:08 +0000
+Subject: [PATCH 0931/1302] Thermal: armada: Remove redundant use of
+ of_match_ptr
+
+'armada_thermal_id_table' is always compiled in and the driver
+is dependent on OF. Hence use of of_match_ptr is unnecessary.
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Cc: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/armada_thermal.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
+index 0491465..5e53212 100644
+--- a/drivers/thermal/armada_thermal.c
++++ b/drivers/thermal/armada_thermal.c
+@@ -210,7 +210,7 @@ static struct platform_driver armada_thermal_driver = {
+       .driver = {
+               .name = "armada_thermal",
+               .owner = THIS_MODULE,
+-              .of_match_table = of_match_ptr(armada_thermal_id_table),
++              .of_match_table = armada_thermal_id_table,
+       },
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0932-Thermal-dove-Remove-redundant-use-of-of_match_ptr.patch b/patches.tizen/0932-Thermal-dove-Remove-redundant-use-of-of_match_ptr.patch
new file mode 100644 (file)
index 0000000..4f4e9b9
--- /dev/null
@@ -0,0 +1,33 @@
+From b9778b484b08a726a2e5bea68098b2aed908a0ff Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Thu, 16 May 2013 10:28:09 +0000
+Subject: [PATCH 0932/1302] Thermal: dove: Remove redundant use of of_match_ptr
+
+'dove_thermal_id_table' is always compiled in and the driver
+is dependent on OF. Hence use of of_match_ptr is unnecessary.
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Cc: Andrew Lunn <andrew@lunn.ch>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/dove_thermal.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/dove_thermal.c b/drivers/thermal/dove_thermal.c
+index db83f7e..828f5e3 100644
+--- a/drivers/thermal/dove_thermal.c
++++ b/drivers/thermal/dove_thermal.c
+@@ -185,7 +185,7 @@ static struct platform_driver dove_thermal_driver = {
+       .driver = {
+               .name = "dove_thermal",
+               .owner = THIS_MODULE,
+-              .of_match_table = of_match_ptr(dove_thermal_id_table),
++              .of_match_table = dove_thermal_id_table,
+       },
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0933-Thermal-kirkwood-Remove-redundant-use-of-of_match_pt.patch b/patches.tizen/0933-Thermal-kirkwood-Remove-redundant-use-of-of_match_pt.patch
new file mode 100644 (file)
index 0000000..bc8f8c5
--- /dev/null
@@ -0,0 +1,34 @@
+From 04e53873f327296fe4f7c71f6b279b553d0b2e97 Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Thu, 16 May 2013 10:28:10 +0000
+Subject: [PATCH 0933/1302] Thermal: kirkwood: Remove redundant use of
+ of_match_ptr
+
+'kirkwood_thermal_id_table' is always compiled in and the driver
+is dependent on OF. Hence use of of_match_ptr is unnecessary.
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Cc: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/kirkwood_thermal.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/kirkwood_thermal.c b/drivers/thermal/kirkwood_thermal.c
+index 7160164..3b034a0 100644
+--- a/drivers/thermal/kirkwood_thermal.c
++++ b/drivers/thermal/kirkwood_thermal.c
+@@ -115,7 +115,7 @@ static struct platform_driver kirkwood_thermal_driver = {
+       .driver = {
+               .name = "kirkwood_thermal",
+               .owner = THIS_MODULE,
+-              .of_match_table = of_match_ptr(kirkwood_thermal_id_table),
++              .of_match_table = kirkwood_thermal_id_table,
+       },
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0934-Thermal-spear-Remove-redundant-use-of-of_match_ptr.patch b/patches.tizen/0934-Thermal-spear-Remove-redundant-use-of-of_match_ptr.patch
new file mode 100644 (file)
index 0000000..87eb963
--- /dev/null
@@ -0,0 +1,36 @@
+From b06937470d2936f2ec3bc4d9f6354826ff625722 Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Thu, 16 May 2013 10:28:11 +0000
+Subject: [PATCH 0934/1302] Thermal: spear: Remove redundant use of
+ of_match_ptr
+
+'spear_thermal_id_table' is always compiled in and the driver
+is dependent on OF. Hence use of of_match_ptr is unnecessary.
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Cc: Vincenzo Frascino <vincenzo.frascino@st.com>
+Cc: Viresh Kumar <viresh.kumar@linaro.org>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/spear_thermal.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/spear_thermal.c b/drivers/thermal/spear_thermal.c
+index 813add6..ab79ea4 100644
+--- a/drivers/thermal/spear_thermal.c
++++ b/drivers/thermal/spear_thermal.c
+@@ -190,7 +190,7 @@ static struct platform_driver spear_thermal_driver = {
+               .name = "spear_thermal",
+               .owner = THIS_MODULE,
+               .pm = &spear_thermal_pm_ops,
+-              .of_match_table = of_match_ptr(spear_thermal_id_table),
++              .of_match_table = spear_thermal_id_table,
+       },
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0935-thermal-cpu_cooling-fix-descend-check-in-get_propert.patch b/patches.tizen/0935-thermal-cpu_cooling-fix-descend-check-in-get_propert.patch
new file mode 100644 (file)
index 0000000..9ad5fb4
--- /dev/null
@@ -0,0 +1,39 @@
+From 07cc3940d19cb8a2902510e2c277dca6ad00a2c3 Mon Sep 17 00:00:00 2001
+From: Shawn Guo <shawn.guo@linaro.org>
+Date: Tue, 28 May 2013 06:22:32 +0000
+Subject: [PATCH 0935/1302] thermal: cpu_cooling: fix 'descend' check in
+ get_property()
+
+The variable 'descend' is initialized as -1 in function get_property(),
+and will never get any chance to be updated by the following code.
+
+       if (freq != CPUFREQ_ENTRY_INVALID && descend != -1)
+               descend = !!(freq > table[i].frequency);
+
+This makes function get_property() return the wrong frequency for given
+cooling level if the frequency table is sorted in ascending.  Fix it
+by correcting the 'descend' check in if-condition to 'descend == -1'.
+
+Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/cpu_cooling.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
+index c94bf2e..82e15db 100644
+--- a/drivers/thermal/cpu_cooling.c
++++ b/drivers/thermal/cpu_cooling.c
+@@ -167,7 +167,7 @@ static int get_property(unsigned int cpu, unsigned long input,
+                       continue;
+               /* get the frequency order */
+-              if (freq != CPUFREQ_ENTRY_INVALID && descend != -1)
++              if (freq != CPUFREQ_ENTRY_INVALID && descend == -1)
+                       descend = !!(freq > table[i].frequency);
+               freq = table[i].frequency;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0936-thermal-ti-soc-thermal-remove-external-heat-while-ex.patch b/patches.tizen/0936-thermal-ti-soc-thermal-remove-external-heat-while-ex.patch
new file mode 100644 (file)
index 0000000..f40b244
--- /dev/null
@@ -0,0 +1,92 @@
+From aaa4d6165d275c9656869c5a946f72ab9dd1b13b Mon Sep 17 00:00:00 2001
+From: Eduardo Valentin <eduardo.valentin@ti.com>
+Date: Wed, 29 May 2013 15:07:41 +0000
+Subject: [PATCH 0936/1302] thermal: ti-soc-thermal: remove external heat while
+ extrapolating hotspot
+
+For boards that provide a PCB sensor close to SoC junction
+temperature, it is possible to remove the cumulative heat
+reported by the SoC temperature sensor.
+
+This patch changes the extrapolation computation to consider
+an external sensor in the extrapolation equations.
+
+Cc: Zhang Rui <rui.zhang@intel.com>
+Cc: linux-pm@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 30 ++++++++++++++--------
+ 1 file changed, 20 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+index e3c5e67..8e67ebf 100644
+--- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
++++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+@@ -38,6 +38,7 @@
+ /* common data structures */
+ struct ti_thermal_data {
+       struct thermal_zone_device *ti_thermal;
++      struct thermal_zone_device *pcb_tz;
+       struct thermal_cooling_device *cool_dev;
+       struct ti_bandgap *bgp;
+       enum thermal_device_mode mode;
+@@ -77,10 +78,12 @@ static inline int ti_thermal_hotspot_temperature(int t, int s, int c)
+ static inline int ti_thermal_get_temp(struct thermal_zone_device *thermal,
+                                     unsigned long *temp)
+ {
++      struct thermal_zone_device *pcb_tz = NULL;
+       struct ti_thermal_data *data = thermal->devdata;
+       struct ti_bandgap *bgp;
+       const struct ti_temp_sensor *s;
+-      int ret, tmp, pcb_temp, slope, constant;
++      int ret, tmp, slope, constant;
++      unsigned long pcb_temp;
+       if (!data)
+               return 0;
+@@ -92,16 +95,22 @@ static inline int ti_thermal_get_temp(struct thermal_zone_device *thermal,
+       if (ret)
+               return ret;
+-      pcb_temp = 0;
+-      /* TODO: Introduce pcb temperature lookup */
++      /* Default constants */
++      slope = s->slope;
++      constant = s->constant;
++
++      pcb_tz = data->pcb_tz;
+       /* In case pcb zone is available, use the extrapolation rule with it */
+-      if (pcb_temp) {
+-              tmp -= pcb_temp;
+-              slope = s->slope_pcb;
+-              constant = s->constant_pcb;
+-      } else {
+-              slope = s->slope;
+-              constant = s->constant;
++      if (!IS_ERR_OR_NULL(pcb_tz)) {
++              ret = thermal_zone_get_temp(pcb_tz, &pcb_temp);
++              if (!ret) {
++                      tmp -= pcb_temp; /* got a valid PCB temp */
++                      slope = s->slope_pcb;
++                      constant = s->constant_pcb;
++              } else {
++                      dev_err(bgp->dev,
++                              "Failed to read PCB state. Using defaults\n");
++              }
+       }
+       *temp = ti_thermal_hotspot_temperature(tmp, slope, constant);
+@@ -273,6 +282,7 @@ static struct ti_thermal_data
+       data->sensor_id = id;
+       data->bgp = bgp;
+       data->mode = THERMAL_DEVICE_ENABLED;
++      data->pcb_tz = thermal_zone_get_zone_by_name("pcb");
+       INIT_WORK(&data->thermal_wq, ti_thermal_work);
+       return data;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0937-thermal-ti-soc-thermal-freeze-FSM-while-computing-tr.patch b/patches.tizen/0937-thermal-ti-soc-thermal-freeze-FSM-while-computing-tr.patch
new file mode 100644 (file)
index 0000000..648068f
--- /dev/null
@@ -0,0 +1,70 @@
+From a8f57d08dd36bb1a553fab1a23d99f8be195a937 Mon Sep 17 00:00:00 2001
+From: Eduardo Valentin <eduardo.valentin@ti.com>
+Date: Fri, 7 Jun 2013 19:13:13 +0000
+Subject: [PATCH 0937/1302] thermal: ti-soc-thermal: freeze FSM while computing
+ trend
+
+In order to read the history buffer, it is required to
+freeze BG FSM. This patch adds the missing piece of code
+to freeze the FSM and also a contention area to avoid
+other parts of the code to access the DTEMPs.
+
+Cc: Zhang Rui <rui.zhang@intel.com>
+Cc: linux-pm@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/ti-soc-thermal/ti-bandgap.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.c b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
+index f20c1cf..219c051 100644
+--- a/drivers/thermal/ti-soc-thermal/ti-bandgap.c
++++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
+@@ -992,9 +992,12 @@ int ti_bandgap_get_trend(struct ti_bandgap *bgp, int id, int *trend)
+               goto exit;
+       }
++      spin_lock(&bgp->lock);
++
+       tsr = bgp->conf->sensors[id].registers;
+       /* Freeze and read the last 2 valid readings */
++      RMW_BITS(bgp, id, bgap_mask_ctrl, mask_freeze_mask, 1);
+       reg1 = tsr->ctrl_dtemp_1;
+       reg2 = tsr->ctrl_dtemp_2;
+@@ -1008,22 +1011,25 @@ int ti_bandgap_get_trend(struct ti_bandgap *bgp, int id, int *trend)
+       /* Convert from adc values to mCelsius temperature */
+       ret = ti_bandgap_adc_to_mcelsius(bgp, temp1, &t1);
+       if (ret)
+-              goto exit;
++              goto unfreeze;
+       ret = ti_bandgap_adc_to_mcelsius(bgp, temp2, &t2);
+       if (ret)
+-              goto exit;
++              goto unfreeze;
+       /* Fetch the update interval */
+       ret = ti_bandgap_read_update_interval(bgp, id, &interval);
+       if (ret || !interval)
+-              goto exit;
++              goto unfreeze;
+       *trend = (t1 - t2) / interval;
+       dev_dbg(bgp->dev, "The temperatures are t1 = %d and t2 = %d and trend =%d\n",
+               t1, t2, *trend);
++unfreeze:
++      RMW_BITS(bgp, id, bgap_mask_ctrl, mask_freeze_mask, 0);
++      spin_unlock(&bgp->lock);
+ exit:
+       return ret;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0938-thermal-ti-soc-thermal-remove-usage-of-IS_ERR_OR_NUL.patch b/patches.tizen/0938-thermal-ti-soc-thermal-remove-usage-of-IS_ERR_OR_NUL.patch
new file mode 100644 (file)
index 0000000..d077ac4
--- /dev/null
@@ -0,0 +1,151 @@
+From f639bd22d2805694e6181a405188e49ac6050f80 Mon Sep 17 00:00:00 2001
+From: Eduardo Valentin <eduardo.valentin@ti.com>
+Date: Wed, 29 May 2013 15:07:43 +0000
+Subject: [PATCH 0938/1302] thermal: ti-soc-thermal: remove usage of
+ IS_ERR_OR_NULL
+
+This patch changes the driver to avoid the usage of IS_ERR_OR_NULL()
+macro. This macro can lead to dangerous results, like returning
+success (0) during a failure scenario (NULL pointer handling).
+
+For this reason this patch is changing the driver after
+revisiting the code. These are the cases:
+i. For cases in which IS_ERR_OR_NULL() is used for checking
+return values of functions that returns either PTR_ERR()
+or a valid pointer, it has been translated to IS_ERR() check only.
+ii. For cases that a NULL check is still needed, it has been
+translated to if (!ptr || IS_ERR(ptr)).
+
+Cc: Zhang Rui <rui.zhang@intel.com>
+Cc: linux-pm@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/ti-soc-thermal/ti-bandgap.c        | 10 ++++++----
+ drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 15 ++++++++-------
+ 2 files changed, 14 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.c b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
+index 219c051..3f3c512 100644
+--- a/drivers/thermal/ti-soc-thermal/ti-bandgap.c
++++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
+@@ -469,7 +469,7 @@ static inline int ti_bandgap_validate(struct ti_bandgap *bgp, int id)
+ {
+       int ret = 0;
+-      if (IS_ERR_OR_NULL(bgp)) {
++      if (!bgp || IS_ERR(bgp)) {
+               pr_err("%s: invalid bandgap pointer\n", __func__);
+               ret = -EINVAL;
+               goto exit;
+@@ -1197,7 +1197,7 @@ int ti_bandgap_probe(struct platform_device *pdev)
+       int clk_rate, ret = 0, i;
+       bgp = ti_bandgap_build(pdev);
+-      if (IS_ERR_OR_NULL(bgp)) {
++      if (IS_ERR(bgp)) {
+               dev_err(&pdev->dev, "failed to fetch platform data\n");
+               return PTR_ERR(bgp);
+       }
+@@ -1213,17 +1213,19 @@ int ti_bandgap_probe(struct platform_device *pdev)
+       }
+       bgp->fclock = clk_get(NULL, bgp->conf->fclock_name);
+-      ret = IS_ERR_OR_NULL(bgp->fclock);
++      ret = IS_ERR(bgp->fclock);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to request fclock reference\n");
++              ret = PTR_ERR(bgp->fclock);
+               goto free_irqs;
+       }
+       bgp->div_clk = clk_get(NULL,  bgp->conf->div_ck_name);
+-      ret = IS_ERR_OR_NULL(bgp->div_clk);
++      ret = IS_ERR(bgp->div_clk);
+       if (ret) {
+               dev_err(&pdev->dev,
+                       "failed to request div_ts_ck clock ref\n");
++              ret = PTR_ERR(bgp->div_clk);
+               goto free_irqs;
+       }
+diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+index 8e67ebf..4c5f55c37 100644
+--- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
++++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+@@ -101,7 +101,7 @@ static inline int ti_thermal_get_temp(struct thermal_zone_device *thermal,
+       pcb_tz = data->pcb_tz;
+       /* In case pcb zone is available, use the extrapolation rule with it */
+-      if (!IS_ERR_OR_NULL(pcb_tz)) {
++      if (!IS_ERR(pcb_tz)) {
+               ret = thermal_zone_get_temp(pcb_tz, &pcb_temp);
+               if (!ret) {
+                       tmp -= pcb_temp; /* got a valid PCB temp */
+@@ -124,7 +124,7 @@ static int ti_thermal_bind(struct thermal_zone_device *thermal,
+       struct ti_thermal_data *data = thermal->devdata;
+       int id;
+-      if (IS_ERR_OR_NULL(data))
++      if (!data || IS_ERR(data))
+               return -ENODEV;
+       /* check if this is the cooling device we registered */
+@@ -146,7 +146,7 @@ static int ti_thermal_unbind(struct thermal_zone_device *thermal,
+ {
+       struct ti_thermal_data *data = thermal->devdata;
+-      if (IS_ERR_OR_NULL(data))
++      if (!data || IS_ERR(data))
+               return -ENODEV;
+       /* check if this is the cooling device we registered */
+@@ -282,6 +282,7 @@ static struct ti_thermal_data
+       data->sensor_id = id;
+       data->bgp = bgp;
+       data->mode = THERMAL_DEVICE_ENABLED;
++      /* pcb_tz will be either valid or PTR_ERR() */
+       data->pcb_tz = thermal_zone_get_zone_by_name("pcb");
+       INIT_WORK(&data->thermal_wq, ti_thermal_work);
+@@ -295,7 +296,7 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id,
+       data = ti_bandgap_get_sensor_data(bgp, id);
+-      if (IS_ERR_OR_NULL(data))
++      if (!data || IS_ERR(data))
+               data = ti_thermal_build_data(bgp, id);
+       if (!data)
+@@ -306,7 +307,7 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id,
+                               OMAP_TRIP_NUMBER, 0, data, &ti_thermal_ops,
+                               NULL, FAST_TEMP_MONITORING_RATE,
+                               FAST_TEMP_MONITORING_RATE);
+-      if (IS_ERR_OR_NULL(data->ti_thermal)) {
++      if (IS_ERR(data->ti_thermal)) {
+               dev_err(bgp->dev, "thermal zone device is NULL\n");
+               return PTR_ERR(data->ti_thermal);
+       }
+@@ -343,7 +344,7 @@ int ti_thermal_register_cpu_cooling(struct ti_bandgap *bgp, int id)
+       struct ti_thermal_data *data;
+       data = ti_bandgap_get_sensor_data(bgp, id);
+-      if (IS_ERR_OR_NULL(data))
++      if (!data || IS_ERR(data))
+               data = ti_thermal_build_data(bgp, id);
+       if (!data)
+@@ -356,7 +357,7 @@ int ti_thermal_register_cpu_cooling(struct ti_bandgap *bgp, int id)
+       /* Register cooling device */
+       data->cool_dev = cpufreq_cooling_register(cpu_present_mask);
+-      if (IS_ERR_OR_NULL(data->cool_dev)) {
++      if (IS_ERR(data->cool_dev)) {
+               dev_err(bgp->dev,
+                       "Failed to register cpufreq cooling device\n");
+               return PTR_ERR(data->cool_dev);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0939-thermal-ti-soc-thermal-add-thermal-data-for-DRA752-c.patch b/patches.tizen/0939-thermal-ti-soc-thermal-add-thermal-data-for-DRA752-c.patch
new file mode 100644 (file)
index 0000000..b2161ac
--- /dev/null
@@ -0,0 +1,861 @@
+From da0e450c874aad56ae141bf95f59d1a79fb752e4 Mon Sep 17 00:00:00 2001
+From: Eduardo Valentin <eduardo.valentin@ti.com>
+Date: Mon, 3 Jun 2013 20:31:55 +0000
+Subject: [PATCH 0939/1302] thermal: ti-soc-thermal: add thermal data for
+ DRA752 chips
+
+This patch adds the thermal data for TI DRA752 chips.
+In this change it includes (autogen):
+. Register offset definitions
+. Bitfields and masks for all registers
+. Conversion table
+
+Also, the thermal limits, thresholds and extrapolation
+rules are included. The extrapolation rule is simply
+add +2C as margin.
+
+All 5 sensors, MPU, GPU, CORE, DSPEVE and IVA, are defined
+and exposed. Only MPU has cooling device.
+
+Cc: Zhang Rui <rui.zhang@intel.com>
+Cc: linux-pm@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/ti-soc-thermal/Kconfig             |  12 +
+ drivers/thermal/ti-soc-thermal/Makefile            |   1 +
+ drivers/thermal/ti-soc-thermal/dra752-bandgap.h    | 280 ++++++++++++
+ .../thermal/ti-soc-thermal/dra752-thermal-data.c   | 476 +++++++++++++++++++++
+ drivers/thermal/ti-soc-thermal/ti-thermal.h        |   6 +
+ 5 files changed, 775 insertions(+)
+ create mode 100644 drivers/thermal/ti-soc-thermal/dra752-bandgap.h
+ create mode 100644 drivers/thermal/ti-soc-thermal/dra752-thermal-data.c
+
+diff --git a/drivers/thermal/ti-soc-thermal/Kconfig b/drivers/thermal/ti-soc-thermal/Kconfig
+index e81375f..bd4c7be 100644
+--- a/drivers/thermal/ti-soc-thermal/Kconfig
++++ b/drivers/thermal/ti-soc-thermal/Kconfig
+@@ -46,3 +46,15 @@ config OMAP5_THERMAL
+         This includes alert interrupts generation and also the TSHUT
+         support.
++
++config DRA752_THERMAL
++      bool "Texas Instruments DRA752 thermal support"
++      depends on TI_SOC_THERMAL
++      depends on SOC_DRA7XX
++      help
++        If you say yes here you get thermal support for the Texas Instruments
++        DRA752 SoC family. The current chip supported are:
++         - DRA752
++
++        This includes alert interrupts generation and also the TSHUT
++        support.
+diff --git a/drivers/thermal/ti-soc-thermal/Makefile b/drivers/thermal/ti-soc-thermal/Makefile
+index 0ca034f..1226b24 100644
+--- a/drivers/thermal/ti-soc-thermal/Makefile
++++ b/drivers/thermal/ti-soc-thermal/Makefile
+@@ -1,5 +1,6 @@
+ obj-$(CONFIG_TI_SOC_THERMAL)          += ti-soc-thermal.o
+ ti-soc-thermal-y                      := ti-bandgap.o
+ ti-soc-thermal-$(CONFIG_TI_THERMAL)   += ti-thermal-common.o
++ti-soc-thermal-$(CONFIG_DRA752_THERMAL)       += dra752-thermal-data.o
+ ti-soc-thermal-$(CONFIG_OMAP4_THERMAL)        += omap4-thermal-data.o
+ ti-soc-thermal-$(CONFIG_OMAP5_THERMAL)        += omap5-thermal-data.o
+diff --git a/drivers/thermal/ti-soc-thermal/dra752-bandgap.h b/drivers/thermal/ti-soc-thermal/dra752-bandgap.h
+new file mode 100644
+index 0000000..6b0f2b1
+--- /dev/null
++++ b/drivers/thermal/ti-soc-thermal/dra752-bandgap.h
+@@ -0,0 +1,280 @@
++/*
++ * DRA752 bandgap registers, bitfields and temperature definitions
++ *
++ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
++ * Contact:
++ *   Eduardo Valentin <eduardo.valentin@ti.com>
++ *   Tero Kristo <t-kristo@ti.com>
++ *
++ * This is an auto generated file.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
++ * 02110-1301 USA
++ *
++ */
++#ifndef __DRA752_BANDGAP_H
++#define __DRA752_BANDGAP_H
++
++/**
++ * *** DRA752 ***
++ *
++ * Below, in sequence, are the Register definitions,
++ * the bitfields and the temperature definitions for DRA752.
++ */
++
++/**
++ * DRA752 register definitions
++ *
++ * Registers are defined as offsets. The offsets are
++ * relative to FUSE_OPP_BGAP_GPU on DRA752.
++ * DRA752_BANDGAP_BASE                0x4a0021e0
++ *
++ * Register below are grouped by domain (not necessarily in offset order)
++ */
++
++
++/* DRA752.common register offsets */
++#define DRA752_BANDGAP_CTRL_1_OFFSET          0x1a0
++#define DRA752_BANDGAP_STATUS_1_OFFSET                0x1c8
++#define DRA752_BANDGAP_CTRL_2_OFFSET          0x39c
++#define DRA752_BANDGAP_STATUS_2_OFFSET                0x3b8
++
++/* DRA752.core register offsets */
++#define DRA752_STD_FUSE_OPP_BGAP_CORE_OFFSET          0x8
++#define DRA752_TEMP_SENSOR_CORE_OFFSET                        0x154
++#define DRA752_BANDGAP_THRESHOLD_CORE_OFFSET          0x1ac
++#define DRA752_BANDGAP_TSHUT_CORE_OFFSET              0x1b8
++#define DRA752_BANDGAP_CUMUL_DTEMP_CORE_OFFSET                0x1c4
++#define DRA752_DTEMP_CORE_0_OFFSET                    0x208
++#define DRA752_DTEMP_CORE_1_OFFSET                    0x20c
++#define DRA752_DTEMP_CORE_2_OFFSET                    0x210
++#define DRA752_DTEMP_CORE_3_OFFSET                    0x214
++#define DRA752_DTEMP_CORE_4_OFFSET                    0x218
++
++/* DRA752.iva register offsets */
++#define DRA752_STD_FUSE_OPP_BGAP_IVA_OFFSET           0x388
++#define DRA752_TEMP_SENSOR_IVA_OFFSET                 0x398
++#define DRA752_BANDGAP_THRESHOLD_IVA_OFFSET           0x3a4
++#define DRA752_BANDGAP_TSHUT_IVA_OFFSET                       0x3ac
++#define DRA752_BANDGAP_CUMUL_DTEMP_IVA_OFFSET         0x3b4
++#define DRA752_DTEMP_IVA_0_OFFSET                     0x3d0
++#define DRA752_DTEMP_IVA_1_OFFSET                     0x3d4
++#define DRA752_DTEMP_IVA_2_OFFSET                     0x3d8
++#define DRA752_DTEMP_IVA_3_OFFSET                     0x3dc
++#define DRA752_DTEMP_IVA_4_OFFSET                     0x3e0
++
++/* DRA752.mpu register offsets */
++#define DRA752_STD_FUSE_OPP_BGAP_MPU_OFFSET           0x4
++#define DRA752_TEMP_SENSOR_MPU_OFFSET                 0x14c
++#define DRA752_BANDGAP_THRESHOLD_MPU_OFFSET           0x1a4
++#define DRA752_BANDGAP_TSHUT_MPU_OFFSET                       0x1b0
++#define DRA752_BANDGAP_CUMUL_DTEMP_MPU_OFFSET         0x1bc
++#define DRA752_DTEMP_MPU_0_OFFSET                     0x1e0
++#define DRA752_DTEMP_MPU_1_OFFSET                     0x1e4
++#define DRA752_DTEMP_MPU_2_OFFSET                     0x1e8
++#define DRA752_DTEMP_MPU_3_OFFSET                     0x1ec
++#define DRA752_DTEMP_MPU_4_OFFSET                     0x1f0
++
++/* DRA752.dspeve register offsets */
++#define DRA752_STD_FUSE_OPP_BGAP_DSPEVE_OFFSET                        0x384
++#define DRA752_TEMP_SENSOR_DSPEVE_OFFSET                      0x394
++#define DRA752_BANDGAP_THRESHOLD_DSPEVE_OFFSET                        0x3a0
++#define DRA752_BANDGAP_TSHUT_DSPEVE_OFFSET                    0x3a8
++#define DRA752_BANDGAP_CUMUL_DTEMP_DSPEVE_OFFSET              0x3b0
++#define DRA752_DTEMP_DSPEVE_0_OFFSET                          0x3bc
++#define DRA752_DTEMP_DSPEVE_1_OFFSET                          0x3c0
++#define DRA752_DTEMP_DSPEVE_2_OFFSET                          0x3c4
++#define DRA752_DTEMP_DSPEVE_3_OFFSET                          0x3c8
++#define DRA752_DTEMP_DSPEVE_4_OFFSET                          0x3cc
++
++/* DRA752.gpu register offsets */
++#define DRA752_STD_FUSE_OPP_BGAP_GPU_OFFSET           0x0
++#define DRA752_TEMP_SENSOR_GPU_OFFSET                 0x150
++#define DRA752_BANDGAP_THRESHOLD_GPU_OFFSET           0x1a8
++#define DRA752_BANDGAP_TSHUT_GPU_OFFSET                       0x1b4
++#define DRA752_BANDGAP_CUMUL_DTEMP_GPU_OFFSET         0x1c0
++#define DRA752_DTEMP_GPU_0_OFFSET                     0x1f4
++#define DRA752_DTEMP_GPU_1_OFFSET                     0x1f8
++#define DRA752_DTEMP_GPU_2_OFFSET                     0x1fc
++#define DRA752_DTEMP_GPU_3_OFFSET                     0x200
++#define DRA752_DTEMP_GPU_4_OFFSET                     0x204
++
++/**
++ * Register bitfields for DRA752
++ *
++ * All the macros bellow define the required bits for
++ * controlling temperature on DRA752. Bit defines are
++ * grouped by register.
++ */
++
++/* DRA752.BANDGAP_STATUS_1 */
++#define DRA752_BANDGAP_STATUS_1_ALERT_MASK            BIT(31)
++#define DRA752_BANDGAP_STATUS_1_HOT_CORE_MASK         BIT(5)
++#define DRA752_BANDGAP_STATUS_1_COLD_CORE_MASK                BIT(4)
++#define DRA752_BANDGAP_STATUS_1_HOT_GPU_MASK          BIT(3)
++#define DRA752_BANDGAP_STATUS_1_COLD_GPU_MASK         BIT(2)
++#define DRA752_BANDGAP_STATUS_1_HOT_MPU_MASK          BIT(1)
++#define DRA752_BANDGAP_STATUS_1_COLD_MPU_MASK         BIT(0)
++
++/* DRA752.BANDGAP_CTRL_2 */
++#define DRA752_BANDGAP_CTRL_2_FREEZE_IVA_MASK                 BIT(22)
++#define DRA752_BANDGAP_CTRL_2_FREEZE_DSPEVE_MASK              BIT(21)
++#define DRA752_BANDGAP_CTRL_2_CLEAR_IVA_MASK                  BIT(19)
++#define DRA752_BANDGAP_CTRL_2_CLEAR_DSPEVE_MASK                       BIT(18)
++#define DRA752_BANDGAP_CTRL_2_CLEAR_ACCUM_IVA_MASK            BIT(16)
++#define DRA752_BANDGAP_CTRL_2_CLEAR_ACCUM_DSPEVE_MASK         BIT(15)
++#define DRA752_BANDGAP_CTRL_2_MASK_HOT_IVA_MASK                       BIT(3)
++#define DRA752_BANDGAP_CTRL_2_MASK_COLD_IVA_MASK              BIT(2)
++#define DRA752_BANDGAP_CTRL_2_MASK_HOT_DSPEVE_MASK            BIT(1)
++#define DRA752_BANDGAP_CTRL_2_MASK_COLD_DSPEVE_MASK           BIT(0)
++
++/* DRA752.BANDGAP_STATUS_2 */
++#define DRA752_BANDGAP_STATUS_2_HOT_IVA_MASK                  BIT(3)
++#define DRA752_BANDGAP_STATUS_2_COLD_IVA_MASK                 BIT(2)
++#define DRA752_BANDGAP_STATUS_2_HOT_DSPEVE_MASK                       BIT(1)
++#define DRA752_BANDGAP_STATUS_2_COLD_DSPEVE_MASK              BIT(0)
++
++/* DRA752.BANDGAP_CTRL_1 */
++#define DRA752_BANDGAP_CTRL_1_SIDLEMODE_MASK                  (0x3 << 30)
++#define DRA752_BANDGAP_CTRL_1_COUNTER_DELAY_MASK              (0x7 << 27)
++#define DRA752_BANDGAP_CTRL_1_FREEZE_CORE_MASK                        BIT(23)
++#define DRA752_BANDGAP_CTRL_1_FREEZE_GPU_MASK                 BIT(22)
++#define DRA752_BANDGAP_CTRL_1_FREEZE_MPU_MASK                 BIT(21)
++#define DRA752_BANDGAP_CTRL_1_CLEAR_CORE_MASK                 BIT(20)
++#define DRA752_BANDGAP_CTRL_1_CLEAR_GPU_MASK                  BIT(19)
++#define DRA752_BANDGAP_CTRL_1_CLEAR_MPU_MASK                  BIT(18)
++#define DRA752_BANDGAP_CTRL_1_CLEAR_ACCUM_CORE_MASK           BIT(17)
++#define DRA752_BANDGAP_CTRL_1_CLEAR_ACCUM_GPU_MASK            BIT(16)
++#define DRA752_BANDGAP_CTRL_1_CLEAR_ACCUM_MPU_MASK            BIT(15)
++#define DRA752_BANDGAP_CTRL_1_MASK_HOT_CORE_MASK              BIT(5)
++#define DRA752_BANDGAP_CTRL_1_MASK_COLD_CORE_MASK             BIT(4)
++#define DRA752_BANDGAP_CTRL_1_MASK_HOT_GPU_MASK                       BIT(3)
++#define DRA752_BANDGAP_CTRL_1_MASK_COLD_GPU_MASK              BIT(2)
++#define DRA752_BANDGAP_CTRL_1_MASK_HOT_MPU_MASK                       BIT(1)
++#define DRA752_BANDGAP_CTRL_1_MASK_COLD_MPU_MASK              BIT(0)
++
++/* DRA752.TEMP_SENSOR */
++#define DRA752_TEMP_SENSOR_TMPSOFF_MASK               BIT(11)
++#define DRA752_TEMP_SENSOR_EOCZ_MASK          BIT(10)
++#define DRA752_TEMP_SENSOR_DTEMP_MASK         (0x3ff << 0)
++
++/* DRA752.BANDGAP_THRESHOLD */
++#define DRA752_BANDGAP_THRESHOLD_HOT_MASK             (0x3ff << 16)
++#define DRA752_BANDGAP_THRESHOLD_COLD_MASK            (0x3ff << 0)
++
++/* DRA752.TSHUT_THRESHOLD */
++#define DRA752_TSHUT_THRESHOLD_MUXCTRL_MASK           BIT(31)
++#define DRA752_TSHUT_THRESHOLD_HOT_MASK                       (0x3ff << 16)
++#define DRA752_TSHUT_THRESHOLD_COLD_MASK              (0x3ff << 0)
++
++/* DRA752.BANDGAP_CUMUL_DTEMP_CORE */
++#define DRA752_BANDGAP_CUMUL_DTEMP_CORE_MASK          (0xffffffff << 0)
++
++/* DRA752.BANDGAP_CUMUL_DTEMP_IVA */
++#define DRA752_BANDGAP_CUMUL_DTEMP_IVA_MASK           (0xffffffff << 0)
++
++/* DRA752.BANDGAP_CUMUL_DTEMP_MPU */
++#define DRA752_BANDGAP_CUMUL_DTEMP_MPU_MASK           (0xffffffff << 0)
++
++/* DRA752.BANDGAP_CUMUL_DTEMP_DSPEVE */
++#define DRA752_BANDGAP_CUMUL_DTEMP_DSPEVE_MASK                (0xffffffff << 0)
++
++/* DRA752.BANDGAP_CUMUL_DTEMP_GPU */
++#define DRA752_BANDGAP_CUMUL_DTEMP_GPU_MASK           (0xffffffff << 0)
++
++/**
++ * Temperature limits and thresholds for DRA752
++ *
++ * All the macros bellow are definitions for handling the
++ * ADC conversions and representation of temperature limits
++ * and thresholds for DRA752. Definitions are grouped
++ * by temperature domain.
++ */
++
++/* DRA752.common temperature definitions */
++/* ADC conversion table limits */
++#define DRA752_ADC_START_VALUE                540
++#define DRA752_ADC_END_VALUE          945
++
++/* DRA752.GPU temperature definitions */
++/* bandgap clock limits */
++#define DRA752_GPU_MAX_FREQ                           1500000
++#define DRA752_GPU_MIN_FREQ                           1000000
++/* sensor limits */
++#define DRA752_GPU_MIN_TEMP                           -40000
++#define DRA752_GPU_MAX_TEMP                           125000
++#define DRA752_GPU_HYST_VAL                           5000
++/* interrupts thresholds */
++#define DRA752_GPU_TSHUT_HOT                          915
++#define DRA752_GPU_TSHUT_COLD                         900
++#define DRA752_GPU_T_HOT                              800
++#define DRA752_GPU_T_COLD                             795
++
++/* DRA752.MPU temperature definitions */
++/* bandgap clock limits */
++#define DRA752_MPU_MAX_FREQ                           1500000
++#define DRA752_MPU_MIN_FREQ                           1000000
++/* sensor limits */
++#define DRA752_MPU_MIN_TEMP                           -40000
++#define DRA752_MPU_MAX_TEMP                           125000
++#define DRA752_MPU_HYST_VAL                           5000
++/* interrupts thresholds */
++#define DRA752_MPU_TSHUT_HOT                          915
++#define DRA752_MPU_TSHUT_COLD                         900
++#define DRA752_MPU_T_HOT                              800
++#define DRA752_MPU_T_COLD                             795
++
++/* DRA752.CORE temperature definitions */
++/* bandgap clock limits */
++#define DRA752_CORE_MAX_FREQ                          1500000
++#define DRA752_CORE_MIN_FREQ                          1000000
++/* sensor limits */
++#define DRA752_CORE_MIN_TEMP                          -40000
++#define DRA752_CORE_MAX_TEMP                          125000
++#define DRA752_CORE_HYST_VAL                          5000
++/* interrupts thresholds */
++#define DRA752_CORE_TSHUT_HOT                         915
++#define DRA752_CORE_TSHUT_COLD                                900
++#define DRA752_CORE_T_HOT                             800
++#define DRA752_CORE_T_COLD                            795
++
++/* DRA752.DSPEVE temperature definitions */
++/* bandgap clock limits */
++#define DRA752_DSPEVE_MAX_FREQ                                1500000
++#define DRA752_DSPEVE_MIN_FREQ                                1000000
++/* sensor limits */
++#define DRA752_DSPEVE_MIN_TEMP                                -40000
++#define DRA752_DSPEVE_MAX_TEMP                                125000
++#define DRA752_DSPEVE_HYST_VAL                                5000
++/* interrupts thresholds */
++#define DRA752_DSPEVE_TSHUT_HOT                               915
++#define DRA752_DSPEVE_TSHUT_COLD                      900
++#define DRA752_DSPEVE_T_HOT                           800
++#define DRA752_DSPEVE_T_COLD                          795
++
++/* DRA752.IVA temperature definitions */
++/* bandgap clock limits */
++#define DRA752_IVA_MAX_FREQ                           1500000
++#define DRA752_IVA_MIN_FREQ                           1000000
++/* sensor limits */
++#define DRA752_IVA_MIN_TEMP                           -40000
++#define DRA752_IVA_MAX_TEMP                           125000
++#define DRA752_IVA_HYST_VAL                           5000
++/* interrupts thresholds */
++#define DRA752_IVA_TSHUT_HOT                          915
++#define DRA752_IVA_TSHUT_COLD                         900
++#define DRA752_IVA_T_HOT                              800
++#define DRA752_IVA_T_COLD                             795
++
++#endif /* __DRA752_BANDGAP_H */
+diff --git a/drivers/thermal/ti-soc-thermal/dra752-thermal-data.c b/drivers/thermal/ti-soc-thermal/dra752-thermal-data.c
+new file mode 100644
+index 0000000..e5d8326
+--- /dev/null
++++ b/drivers/thermal/ti-soc-thermal/dra752-thermal-data.c
+@@ -0,0 +1,476 @@
++/*
++ * DRA752 thermal data.
++ *
++ * Copyright (C) 2013 Texas Instruments Inc.
++ * Contact:
++ *    Eduardo Valentin <eduardo.valentin@ti.com>
++ *    Tero Kristo <t-kristo@ti.com>
++ *
++ * This file is partially autogenerated.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include "ti-thermal.h"
++#include "ti-bandgap.h"
++#include "dra752-bandgap.h"
++
++/*
++ * DRA752 has five instances of thermal sensor: MPU, GPU, CORE,
++ * IVA and DSPEVE need to describe the individual registers and
++ * bit fields.
++ */
++
++/*
++ * DRA752 CORE thermal sensor register offsets and bit-fields
++ */
++static struct temp_sensor_registers
++dra752_core_temp_sensor_registers = {
++      .temp_sensor_ctrl = DRA752_TEMP_SENSOR_CORE_OFFSET,
++      .bgap_tempsoff_mask = DRA752_TEMP_SENSOR_TMPSOFF_MASK,
++      .bgap_eocz_mask = DRA752_TEMP_SENSOR_EOCZ_MASK,
++      .bgap_dtemp_mask = DRA752_TEMP_SENSOR_DTEMP_MASK,
++      .bgap_mask_ctrl = DRA752_BANDGAP_CTRL_1_OFFSET,
++      .mask_hot_mask = DRA752_BANDGAP_CTRL_1_MASK_HOT_CORE_MASK,
++      .mask_cold_mask = DRA752_BANDGAP_CTRL_1_MASK_COLD_CORE_MASK,
++      .mask_sidlemode_mask = DRA752_BANDGAP_CTRL_1_SIDLEMODE_MASK,
++      .mask_freeze_mask = DRA752_BANDGAP_CTRL_1_FREEZE_CORE_MASK,
++      .mask_clear_mask = DRA752_BANDGAP_CTRL_1_CLEAR_CORE_MASK,
++      .mask_clear_accum_mask = DRA752_BANDGAP_CTRL_1_CLEAR_ACCUM_CORE_MASK,
++      .bgap_threshold = DRA752_BANDGAP_THRESHOLD_CORE_OFFSET,
++      .threshold_thot_mask = DRA752_BANDGAP_THRESHOLD_HOT_MASK,
++      .threshold_tcold_mask = DRA752_BANDGAP_THRESHOLD_COLD_MASK,
++      .tshut_threshold = DRA752_BANDGAP_TSHUT_CORE_OFFSET,
++      .tshut_hot_mask = DRA752_TSHUT_THRESHOLD_HOT_MASK,
++      .tshut_cold_mask = DRA752_TSHUT_THRESHOLD_COLD_MASK,
++      .bgap_status = DRA752_BANDGAP_STATUS_1_OFFSET,
++      .status_bgap_alert_mask = DRA752_BANDGAP_STATUS_1_ALERT_MASK,
++      .status_hot_mask = DRA752_BANDGAP_STATUS_1_HOT_CORE_MASK,
++      .status_cold_mask = DRA752_BANDGAP_STATUS_1_COLD_CORE_MASK,
++      .bgap_cumul_dtemp = DRA752_BANDGAP_CUMUL_DTEMP_CORE_OFFSET,
++      .ctrl_dtemp_0 = DRA752_DTEMP_CORE_0_OFFSET,
++      .ctrl_dtemp_1 = DRA752_DTEMP_CORE_1_OFFSET,
++      .ctrl_dtemp_2 = DRA752_DTEMP_CORE_2_OFFSET,
++      .ctrl_dtemp_3 = DRA752_DTEMP_CORE_3_OFFSET,
++      .ctrl_dtemp_4 = DRA752_DTEMP_CORE_4_OFFSET,
++      .bgap_efuse = DRA752_STD_FUSE_OPP_BGAP_CORE_OFFSET,
++};
++
++/*
++ * DRA752 IVA thermal sensor register offsets and bit-fields
++ */
++static struct temp_sensor_registers
++dra752_iva_temp_sensor_registers = {
++      .temp_sensor_ctrl = DRA752_TEMP_SENSOR_IVA_OFFSET,
++      .bgap_tempsoff_mask = DRA752_TEMP_SENSOR_TMPSOFF_MASK,
++      .bgap_eocz_mask = DRA752_TEMP_SENSOR_EOCZ_MASK,
++      .bgap_dtemp_mask = DRA752_TEMP_SENSOR_DTEMP_MASK,
++      .bgap_mask_ctrl = DRA752_BANDGAP_CTRL_2_OFFSET,
++      .mask_hot_mask = DRA752_BANDGAP_CTRL_2_MASK_HOT_IVA_MASK,
++      .mask_cold_mask = DRA752_BANDGAP_CTRL_2_MASK_COLD_IVA_MASK,
++      .mask_sidlemode_mask = DRA752_BANDGAP_CTRL_1_SIDLEMODE_MASK,
++      .mask_freeze_mask = DRA752_BANDGAP_CTRL_2_FREEZE_IVA_MASK,
++      .mask_clear_mask = DRA752_BANDGAP_CTRL_2_CLEAR_IVA_MASK,
++      .mask_clear_accum_mask = DRA752_BANDGAP_CTRL_2_CLEAR_ACCUM_IVA_MASK,
++      .bgap_threshold = DRA752_BANDGAP_THRESHOLD_IVA_OFFSET,
++      .threshold_thot_mask = DRA752_BANDGAP_THRESHOLD_HOT_MASK,
++      .threshold_tcold_mask = DRA752_BANDGAP_THRESHOLD_COLD_MASK,
++      .tshut_threshold = DRA752_BANDGAP_TSHUT_IVA_OFFSET,
++      .tshut_hot_mask = DRA752_TSHUT_THRESHOLD_HOT_MASK,
++      .tshut_cold_mask = DRA752_TSHUT_THRESHOLD_COLD_MASK,
++      .bgap_status = DRA752_BANDGAP_STATUS_2_OFFSET,
++      .status_bgap_alert_mask = DRA752_BANDGAP_STATUS_1_ALERT_MASK,
++      .status_hot_mask = DRA752_BANDGAP_STATUS_2_HOT_IVA_MASK,
++      .status_cold_mask = DRA752_BANDGAP_STATUS_2_COLD_IVA_MASK,
++      .bgap_cumul_dtemp = DRA752_BANDGAP_CUMUL_DTEMP_IVA_OFFSET,
++      .ctrl_dtemp_0 = DRA752_DTEMP_IVA_0_OFFSET,
++      .ctrl_dtemp_1 = DRA752_DTEMP_IVA_1_OFFSET,
++      .ctrl_dtemp_2 = DRA752_DTEMP_IVA_2_OFFSET,
++      .ctrl_dtemp_3 = DRA752_DTEMP_IVA_3_OFFSET,
++      .ctrl_dtemp_4 = DRA752_DTEMP_IVA_4_OFFSET,
++      .bgap_efuse = DRA752_STD_FUSE_OPP_BGAP_IVA_OFFSET,
++};
++
++/*
++ * DRA752 MPU thermal sensor register offsets and bit-fields
++ */
++static struct temp_sensor_registers
++dra752_mpu_temp_sensor_registers = {
++      .temp_sensor_ctrl = DRA752_TEMP_SENSOR_MPU_OFFSET,
++      .bgap_tempsoff_mask = DRA752_TEMP_SENSOR_TMPSOFF_MASK,
++      .bgap_eocz_mask = DRA752_TEMP_SENSOR_EOCZ_MASK,
++      .bgap_dtemp_mask = DRA752_TEMP_SENSOR_DTEMP_MASK,
++      .bgap_mask_ctrl = DRA752_BANDGAP_CTRL_1_OFFSET,
++      .mask_hot_mask = DRA752_BANDGAP_CTRL_1_MASK_HOT_MPU_MASK,
++      .mask_cold_mask = DRA752_BANDGAP_CTRL_1_MASK_COLD_MPU_MASK,
++      .mask_sidlemode_mask = DRA752_BANDGAP_CTRL_1_SIDLEMODE_MASK,
++      .mask_freeze_mask = DRA752_BANDGAP_CTRL_1_FREEZE_MPU_MASK,
++      .mask_clear_mask = DRA752_BANDGAP_CTRL_1_CLEAR_MPU_MASK,
++      .mask_clear_accum_mask = DRA752_BANDGAP_CTRL_1_CLEAR_ACCUM_MPU_MASK,
++      .bgap_threshold = DRA752_BANDGAP_THRESHOLD_MPU_OFFSET,
++      .threshold_thot_mask = DRA752_BANDGAP_THRESHOLD_HOT_MASK,
++      .threshold_tcold_mask = DRA752_BANDGAP_THRESHOLD_COLD_MASK,
++      .tshut_threshold = DRA752_BANDGAP_TSHUT_MPU_OFFSET,
++      .tshut_hot_mask = DRA752_TSHUT_THRESHOLD_HOT_MASK,
++      .tshut_cold_mask = DRA752_TSHUT_THRESHOLD_COLD_MASK,
++      .bgap_status = DRA752_BANDGAP_STATUS_1_OFFSET,
++      .status_bgap_alert_mask = DRA752_BANDGAP_STATUS_1_ALERT_MASK,
++      .status_hot_mask = DRA752_BANDGAP_STATUS_1_HOT_MPU_MASK,
++      .status_cold_mask = DRA752_BANDGAP_STATUS_1_COLD_MPU_MASK,
++      .bgap_cumul_dtemp = DRA752_BANDGAP_CUMUL_DTEMP_MPU_OFFSET,
++      .ctrl_dtemp_0 = DRA752_DTEMP_MPU_0_OFFSET,
++      .ctrl_dtemp_1 = DRA752_DTEMP_MPU_1_OFFSET,
++      .ctrl_dtemp_2 = DRA752_DTEMP_MPU_2_OFFSET,
++      .ctrl_dtemp_3 = DRA752_DTEMP_MPU_3_OFFSET,
++      .ctrl_dtemp_4 = DRA752_DTEMP_MPU_4_OFFSET,
++      .bgap_efuse = DRA752_STD_FUSE_OPP_BGAP_MPU_OFFSET,
++};
++
++/*
++ * DRA752 DSPEVE thermal sensor register offsets and bit-fields
++ */
++static struct temp_sensor_registers
++dra752_dspeve_temp_sensor_registers = {
++      .temp_sensor_ctrl = DRA752_TEMP_SENSOR_DSPEVE_OFFSET,
++      .bgap_tempsoff_mask = DRA752_TEMP_SENSOR_TMPSOFF_MASK,
++      .bgap_eocz_mask = DRA752_TEMP_SENSOR_EOCZ_MASK,
++      .bgap_dtemp_mask = DRA752_TEMP_SENSOR_DTEMP_MASK,
++      .bgap_mask_ctrl = DRA752_BANDGAP_CTRL_2_OFFSET,
++      .mask_hot_mask = DRA752_BANDGAP_CTRL_2_MASK_HOT_DSPEVE_MASK,
++      .mask_cold_mask = DRA752_BANDGAP_CTRL_2_MASK_COLD_DSPEVE_MASK,
++      .mask_sidlemode_mask = DRA752_BANDGAP_CTRL_1_SIDLEMODE_MASK,
++      .mask_freeze_mask = DRA752_BANDGAP_CTRL_2_FREEZE_DSPEVE_MASK,
++      .mask_clear_mask = DRA752_BANDGAP_CTRL_2_CLEAR_DSPEVE_MASK,
++      .mask_clear_accum_mask = DRA752_BANDGAP_CTRL_2_CLEAR_ACCUM_DSPEVE_MASK,
++      .bgap_threshold = DRA752_BANDGAP_THRESHOLD_DSPEVE_OFFSET,
++      .threshold_thot_mask = DRA752_BANDGAP_THRESHOLD_HOT_MASK,
++      .threshold_tcold_mask = DRA752_BANDGAP_THRESHOLD_COLD_MASK,
++      .tshut_threshold = DRA752_BANDGAP_TSHUT_DSPEVE_OFFSET,
++      .tshut_hot_mask = DRA752_TSHUT_THRESHOLD_HOT_MASK,
++      .tshut_cold_mask = DRA752_TSHUT_THRESHOLD_COLD_MASK,
++      .bgap_status = DRA752_BANDGAP_STATUS_2_OFFSET,
++      .status_bgap_alert_mask = DRA752_BANDGAP_STATUS_1_ALERT_MASK,
++      .status_hot_mask = DRA752_BANDGAP_STATUS_2_HOT_DSPEVE_MASK,
++      .status_cold_mask = DRA752_BANDGAP_STATUS_2_COLD_DSPEVE_MASK,
++      .bgap_cumul_dtemp = DRA752_BANDGAP_CUMUL_DTEMP_DSPEVE_OFFSET,
++      .ctrl_dtemp_0 = DRA752_DTEMP_DSPEVE_0_OFFSET,
++      .ctrl_dtemp_1 = DRA752_DTEMP_DSPEVE_1_OFFSET,
++      .ctrl_dtemp_2 = DRA752_DTEMP_DSPEVE_2_OFFSET,
++      .ctrl_dtemp_3 = DRA752_DTEMP_DSPEVE_3_OFFSET,
++      .ctrl_dtemp_4 = DRA752_DTEMP_DSPEVE_4_OFFSET,
++      .bgap_efuse = DRA752_STD_FUSE_OPP_BGAP_DSPEVE_OFFSET,
++};
++
++/*
++ * DRA752 GPU thermal sensor register offsets and bit-fields
++ */
++static struct temp_sensor_registers
++dra752_gpu_temp_sensor_registers = {
++      .temp_sensor_ctrl = DRA752_TEMP_SENSOR_GPU_OFFSET,
++      .bgap_tempsoff_mask = DRA752_TEMP_SENSOR_TMPSOFF_MASK,
++      .bgap_eocz_mask = DRA752_TEMP_SENSOR_EOCZ_MASK,
++      .bgap_dtemp_mask = DRA752_TEMP_SENSOR_DTEMP_MASK,
++      .bgap_mask_ctrl = DRA752_BANDGAP_CTRL_1_OFFSET,
++      .mask_hot_mask = DRA752_BANDGAP_CTRL_1_MASK_HOT_GPU_MASK,
++      .mask_cold_mask = DRA752_BANDGAP_CTRL_1_MASK_COLD_GPU_MASK,
++      .mask_sidlemode_mask = DRA752_BANDGAP_CTRL_1_SIDLEMODE_MASK,
++      .mask_freeze_mask = DRA752_BANDGAP_CTRL_1_FREEZE_GPU_MASK,
++      .mask_clear_mask = DRA752_BANDGAP_CTRL_1_CLEAR_GPU_MASK,
++      .mask_clear_accum_mask = DRA752_BANDGAP_CTRL_1_CLEAR_ACCUM_GPU_MASK,
++      .bgap_threshold = DRA752_BANDGAP_THRESHOLD_GPU_OFFSET,
++      .threshold_thot_mask = DRA752_BANDGAP_THRESHOLD_HOT_MASK,
++      .threshold_tcold_mask = DRA752_BANDGAP_THRESHOLD_COLD_MASK,
++      .tshut_threshold = DRA752_BANDGAP_TSHUT_GPU_OFFSET,
++      .tshut_hot_mask = DRA752_TSHUT_THRESHOLD_HOT_MASK,
++      .tshut_cold_mask = DRA752_TSHUT_THRESHOLD_COLD_MASK,
++      .bgap_status = DRA752_BANDGAP_STATUS_1_OFFSET,
++      .status_bgap_alert_mask = DRA752_BANDGAP_STATUS_1_ALERT_MASK,
++      .status_hot_mask = DRA752_BANDGAP_STATUS_1_HOT_GPU_MASK,
++      .status_cold_mask = DRA752_BANDGAP_STATUS_1_COLD_GPU_MASK,
++      .bgap_cumul_dtemp = DRA752_BANDGAP_CUMUL_DTEMP_GPU_OFFSET,
++      .ctrl_dtemp_0 = DRA752_DTEMP_GPU_0_OFFSET,
++      .ctrl_dtemp_1 = DRA752_DTEMP_GPU_1_OFFSET,
++      .ctrl_dtemp_2 = DRA752_DTEMP_GPU_2_OFFSET,
++      .ctrl_dtemp_3 = DRA752_DTEMP_GPU_3_OFFSET,
++      .ctrl_dtemp_4 = DRA752_DTEMP_GPU_4_OFFSET,
++      .bgap_efuse = DRA752_STD_FUSE_OPP_BGAP_GPU_OFFSET,
++};
++
++/* Thresholds and limits for DRA752 MPU temperature sensor */
++static struct temp_sensor_data dra752_mpu_temp_sensor_data = {
++      .tshut_hot = DRA752_MPU_TSHUT_HOT,
++      .tshut_cold = DRA752_MPU_TSHUT_COLD,
++      .t_hot = DRA752_MPU_T_HOT,
++      .t_cold = DRA752_MPU_T_COLD,
++      .min_freq = DRA752_MPU_MIN_FREQ,
++      .max_freq = DRA752_MPU_MAX_FREQ,
++      .max_temp = DRA752_MPU_MAX_TEMP,
++      .min_temp = DRA752_MPU_MIN_TEMP,
++      .hyst_val = DRA752_MPU_HYST_VAL,
++      .update_int1 = 1000,
++      .update_int2 = 2000,
++};
++
++/* Thresholds and limits for DRA752 GPU temperature sensor */
++static struct temp_sensor_data dra752_gpu_temp_sensor_data = {
++      .tshut_hot = DRA752_GPU_TSHUT_HOT,
++      .tshut_cold = DRA752_GPU_TSHUT_COLD,
++      .t_hot = DRA752_GPU_T_HOT,
++      .t_cold = DRA752_GPU_T_COLD,
++      .min_freq = DRA752_GPU_MIN_FREQ,
++      .max_freq = DRA752_GPU_MAX_FREQ,
++      .max_temp = DRA752_GPU_MAX_TEMP,
++      .min_temp = DRA752_GPU_MIN_TEMP,
++      .hyst_val = DRA752_GPU_HYST_VAL,
++      .update_int1 = 1000,
++      .update_int2 = 2000,
++};
++
++/* Thresholds and limits for DRA752 CORE temperature sensor */
++static struct temp_sensor_data dra752_core_temp_sensor_data = {
++      .tshut_hot = DRA752_CORE_TSHUT_HOT,
++      .tshut_cold = DRA752_CORE_TSHUT_COLD,
++      .t_hot = DRA752_CORE_T_HOT,
++      .t_cold = DRA752_CORE_T_COLD,
++      .min_freq = DRA752_CORE_MIN_FREQ,
++      .max_freq = DRA752_CORE_MAX_FREQ,
++      .max_temp = DRA752_CORE_MAX_TEMP,
++      .min_temp = DRA752_CORE_MIN_TEMP,
++      .hyst_val = DRA752_CORE_HYST_VAL,
++      .update_int1 = 1000,
++      .update_int2 = 2000,
++};
++
++/* Thresholds and limits for DRA752 DSPEVE temperature sensor */
++static struct temp_sensor_data dra752_dspeve_temp_sensor_data = {
++      .tshut_hot = DRA752_DSPEVE_TSHUT_HOT,
++      .tshut_cold = DRA752_DSPEVE_TSHUT_COLD,
++      .t_hot = DRA752_DSPEVE_T_HOT,
++      .t_cold = DRA752_DSPEVE_T_COLD,
++      .min_freq = DRA752_DSPEVE_MIN_FREQ,
++      .max_freq = DRA752_DSPEVE_MAX_FREQ,
++      .max_temp = DRA752_DSPEVE_MAX_TEMP,
++      .min_temp = DRA752_DSPEVE_MIN_TEMP,
++      .hyst_val = DRA752_DSPEVE_HYST_VAL,
++      .update_int1 = 1000,
++      .update_int2 = 2000,
++};
++
++/* Thresholds and limits for DRA752 IVA temperature sensor */
++static struct temp_sensor_data dra752_iva_temp_sensor_data = {
++      .tshut_hot = DRA752_IVA_TSHUT_HOT,
++      .tshut_cold = DRA752_IVA_TSHUT_COLD,
++      .t_hot = DRA752_IVA_T_HOT,
++      .t_cold = DRA752_IVA_T_COLD,
++      .min_freq = DRA752_IVA_MIN_FREQ,
++      .max_freq = DRA752_IVA_MAX_FREQ,
++      .max_temp = DRA752_IVA_MAX_TEMP,
++      .min_temp = DRA752_IVA_MIN_TEMP,
++      .hyst_val = DRA752_IVA_HYST_VAL,
++      .update_int1 = 1000,
++      .update_int2 = 2000,
++};
++
++/*
++ * DRA752 : Temperature values in milli degree celsius
++ * ADC code values from 540 to 945
++ */
++static
++int dra752_adc_to_temp[DRA752_ADC_END_VALUE - DRA752_ADC_START_VALUE + 1] = {
++      /* Index 540 - 549 */
++      -40000, -40000, -40000, -40000, -39800, -39400, -39000, -38600, -38200,
++      -37800,
++      /* Index 550 - 559 */
++      -37400, -37000, -36600, -36200, -35800, -35300, -34700, -34200, -33800,
++      -33400,
++      /* Index 560 - 569 */
++      -33000, -32600, -32200, -31800, -31400, -31000, -30600, -30200, -29800,
++      -29400,
++      /* Index 570 - 579 */
++      -29000, -28600, -28200, -27700, -27100, -26600, -26200, -25800, -25400,
++      -25000,
++      /* Index 580 - 589 */
++      -24600, -24200, -23800, -23400, -23000, -22600, -22200, -21800, -21400,
++      -21000,
++      /* Index 590 - 599 */
++      -20500, -19900, -19400, -19000, -18600, -18200, -17800, -17400, -17000,
++      -16600,
++      /* Index 600 - 609 */
++      -16200, -15800, -15400, -15000, -14600, -14200, -13800, -13400, -13000,
++      -12500,
++      /* Index 610 - 619 */
++      -11900, -11400, -11000, -10600, -10200, -9800, -9400, -9000, -8600,
++      -8200,
++      /* Index 620 - 629 */
++      -7800, -7400, -7000, -6600, -6200, -5800, -5400, -5000, -4500,
++      -3900,
++      /* Index 630 - 639 */
++      -3400, -3000, -2600, -2200, -1800, -1400, -1000, -600, -200,
++      200,
++      /* Index 640 - 649 */
++      600, 1000, 1400, 1800, 2200, 2600, 3000, 3400, 3900,
++      4500,
++      /* Index 650 - 659 */
++      5000, 5400, 5800, 6200, 6600, 7000, 7400, 7800, 8200,
++      8600,
++      /* Index 660 - 669 */
++      9000, 9400, 9800, 10200, 10600, 11000, 11400, 11800, 12200,
++      12700,
++      /* Index 670 - 679 */
++      13300, 13800, 14200, 14600, 15000, 15400, 15800, 16200, 16600,
++      17000,
++      /* Index 680 - 689 */
++      17400, 17800, 18200, 18600, 19000, 19400, 19800, 20200, 20600,
++      21000,
++      /* Index 690 - 699 */
++      21400, 21900, 22500, 23000, 23400, 23800, 24200, 24600, 25000,
++      25400,
++      /* Index 700 - 709 */
++      25800, 26200, 26600, 27000, 27400, 27800, 28200, 28600, 29000,
++      29400,
++      /* Index 710 - 719 */
++      29800, 30200, 30600, 31000, 31400, 31900, 32500, 33000, 33400,
++      33800,
++      /* Index 720 - 729 */
++      34200, 34600, 35000, 35400, 35800, 36200, 36600, 37000, 37400,
++      37800,
++      /* Index 730 - 739 */
++      38200, 38600, 39000, 39400, 39800, 40200, 40600, 41000, 41400,
++      41800,
++      /* Index 740 - 749 */
++      42200, 42600, 43100, 43700, 44200, 44600, 45000, 45400, 45800,
++      46200,
++      /* Index 750 - 759 */
++      46600, 47000, 47400, 47800, 48200, 48600, 49000, 49400, 49800,
++      50200,
++      /* Index 760 - 769 */
++      50600, 51000, 51400, 51800, 52200, 52600, 53000, 53400, 53800,
++      54200,
++      /* Index 770 - 779 */
++      54600, 55000, 55400, 55900, 56500, 57000, 57400, 57800, 58200,
++      58600,
++      /* Index 780 - 789 */
++      59000, 59400, 59800, 60200, 60600, 61000, 61400, 61800, 62200,
++      62600,
++      /* Index 790 - 799 */
++      63000, 63400, 63800, 64200, 64600, 65000, 65400, 65800, 66200,
++      66600,
++      /* Index 800 - 809 */
++      67000, 67400, 67800, 68200, 68600, 69000, 69400, 69800, 70200,
++      70600,
++      /* Index 810 - 819 */
++      71000, 71500, 72100, 72600, 73000, 73400, 73800, 74200, 74600,
++      75000,
++      /* Index 820 - 829 */
++      75400, 75800, 76200, 76600, 77000, 77400, 77800, 78200, 78600,
++      79000,
++      /* Index 830 - 839 */
++      79400, 79800, 80200, 80600, 81000, 81400, 81800, 82200, 82600,
++      83000,
++      /* Index 840 - 849 */
++      83400, 83800, 84200, 84600, 85000, 85400, 85800, 86200, 86600,
++      87000,
++      /* Index 850 - 859 */
++      87400, 87800, 88200, 88600, 89000, 89400, 89800, 90200, 90600,
++      91000,
++      /* Index 860 - 869 */
++      91400, 91800, 92200, 92600, 93000, 93400, 93800, 94200, 94600,
++      95000,
++      /* Index 870 - 879 */
++      95400, 95800, 96200, 96600, 97000, 97500, 98100, 98600, 99000,
++      99400,
++      /* Index 880 - 889 */
++      99800, 100200, 100600, 101000, 101400, 101800, 102200, 102600, 103000,
++      103400,
++      /* Index 890 - 899 */
++      103800, 104200, 104600, 105000, 105400, 105800, 106200, 106600, 107000,
++      107400,
++      /* Index 900 - 909 */
++      107800, 108200, 108600, 109000, 109400, 109800, 110200, 110600, 111000,
++      111400,
++      /* Index 910 - 919 */
++      111800, 112200, 112600, 113000, 113400, 113800, 114200, 114600, 115000,
++      115400,
++      /* Index 920 - 929 */
++      115800, 116200, 116600, 117000, 117400, 117800, 118200, 118600, 119000,
++      119400,
++      /* Index 930 - 939 */
++      119800, 120200, 120600, 121000, 121400, 121800, 122200, 122600, 123000,
++      123400,
++      /* Index 940 - 945 */
++      123800, 124200, 124600, 124900, 125000, 125000,
++};
++
++/* DRA752 data */
++const struct ti_bandgap_data dra752_data = {
++      .features = TI_BANDGAP_FEATURE_TSHUT_CONFIG |
++                      TI_BANDGAP_FEATURE_FREEZE_BIT |
++                      TI_BANDGAP_FEATURE_TALERT |
++                      TI_BANDGAP_FEATURE_COUNTER_DELAY |
++                      TI_BANDGAP_FEATURE_HISTORY_BUFFER,
++      .fclock_name = "l3instr_ts_gclk_div",
++      .div_ck_name = "l3instr_ts_gclk_div",
++      .conv_table = dra752_adc_to_temp,
++      .adc_start_val = DRA752_ADC_START_VALUE,
++      .adc_end_val = DRA752_ADC_END_VALUE,
++      .expose_sensor = ti_thermal_expose_sensor,
++      .remove_sensor = ti_thermal_remove_sensor,
++      .sensors = {
++              {
++              .registers = &dra752_mpu_temp_sensor_registers,
++              .ts_data = &dra752_mpu_temp_sensor_data,
++              .domain = "cpu",
++              .register_cooling = ti_thermal_register_cpu_cooling,
++              .unregister_cooling = ti_thermal_unregister_cpu_cooling,
++              .slope = DRA752_GRADIENT_SLOPE,
++              .constant = DRA752_GRADIENT_CONST,
++              .slope_pcb = DRA752_GRADIENT_SLOPE_W_PCB,
++              .constant_pcb = DRA752_GRADIENT_CONST_W_PCB,
++              },
++              {
++              .registers = &dra752_gpu_temp_sensor_registers,
++              .ts_data = &dra752_gpu_temp_sensor_data,
++              .domain = "gpu",
++              .slope = DRA752_GRADIENT_SLOPE,
++              .constant = DRA752_GRADIENT_CONST,
++              .slope_pcb = DRA752_GRADIENT_SLOPE_W_PCB,
++              .constant_pcb = DRA752_GRADIENT_CONST_W_PCB,
++              },
++              {
++              .registers = &dra752_core_temp_sensor_registers,
++              .ts_data = &dra752_core_temp_sensor_data,
++              .domain = "core",
++              .slope = DRA752_GRADIENT_SLOPE,
++              .constant = DRA752_GRADIENT_CONST,
++              .slope_pcb = DRA752_GRADIENT_SLOPE_W_PCB,
++              .constant_pcb = DRA752_GRADIENT_CONST_W_PCB,
++              },
++              {
++              .registers = &dra752_dspeve_temp_sensor_registers,
++              .ts_data = &dra752_dspeve_temp_sensor_data,
++              .domain = "dspeve",
++              .slope = DRA752_GRADIENT_SLOPE,
++              .constant = DRA752_GRADIENT_CONST,
++              .slope_pcb = DRA752_GRADIENT_SLOPE_W_PCB,
++              .constant_pcb = DRA752_GRADIENT_CONST_W_PCB,
++              },
++              {
++              .registers = &dra752_iva_temp_sensor_registers,
++              .ts_data = &dra752_iva_temp_sensor_data,
++              .domain = "iva",
++              .slope = DRA752_GRADIENT_SLOPE,
++              .constant = DRA752_GRADIENT_CONST,
++              .slope_pcb = DRA752_GRADIENT_SLOPE_W_PCB,
++              .constant_pcb = DRA752_GRADIENT_CONST_W_PCB,
++              },
++      },
++      .sensor_count = 5,
++};
+diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal.h b/drivers/thermal/ti-soc-thermal/ti-thermal.h
+index 5055777..f8b7ffe 100644
+--- a/drivers/thermal/ti-soc-thermal/ti-thermal.h
++++ b/drivers/thermal/ti-soc-thermal/ti-thermal.h
+@@ -38,6 +38,9 @@
+ #define OMAP_GRADIENT_SLOPE_5430_GPU                          117
+ #define OMAP_GRADIENT_CONST_5430_GPU                          -2992
++#define DRA752_GRADIENT_SLOPE                                 0
++#define DRA752_GRADIENT_CONST                                 2000
++
+ /* PCB sensor calculation constants */
+ #define OMAP_GRADIENT_SLOPE_W_PCB_4430                                0
+ #define OMAP_GRADIENT_CONST_W_PCB_4430                                20000
+@@ -51,6 +54,9 @@
+ #define OMAP_GRADIENT_SLOPE_W_PCB_5430_GPU                    464
+ #define OMAP_GRADIENT_CONST_W_PCB_5430_GPU                    -5102
++#define DRA752_GRADIENT_SLOPE_W_PCB                           0
++#define DRA752_GRADIENT_CONST_W_PCB                           2000
++
+ /* trip points of interest in milicelsius (at hotspot level) */
+ #define OMAP_TRIP_COLD                                                100000
+ #define OMAP_TRIP_HOT                                         110000
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0940-thermal-ti-soc-thermal-add-dra752-chip-to-device-tab.patch b/patches.tizen/0940-thermal-ti-soc-thermal-add-dra752-chip-to-device-tab.patch
new file mode 100644 (file)
index 0000000..9d3f6bf
--- /dev/null
@@ -0,0 +1,54 @@
+From e0a2bf6e61b616b85f390a0b86b9b7b1271ec185 Mon Sep 17 00:00:00 2001
+From: Eduardo Valentin <eduardo.valentin@ti.com>
+Date: Wed, 29 May 2013 15:07:45 +0000
+Subject: [PATCH 0940/1302] thermal: ti-soc-thermal: add dra752 chip to device
+ table
+
+Add support to TI dra752 chips by adapting the driver
+device table.
+
+Cc: Zhang Rui <rui.zhang@intel.com>
+Cc: linux-pm@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/ti-soc-thermal/ti-bandgap.c | 6 ++++++
+ drivers/thermal/ti-soc-thermal/ti-bandgap.h | 5 +++++
+ 2 files changed, 11 insertions(+)
+
+diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.c b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
+index 3f3c512..7c0b3eb 100644
+--- a/drivers/thermal/ti-soc-thermal/ti-bandgap.c
++++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
+@@ -1531,6 +1531,12 @@ static const struct of_device_id of_ti_bandgap_match[] = {
+               .data = (void *)&omap5430_data,
+       },
+ #endif
++#ifdef CONFIG_DRA752_THERMAL
++      {
++              .compatible = "ti,dra752-bandgap",
++              .data = (void *)&dra752_data,
++      },
++#endif
+       /* Sentinel */
+       { },
+ };
+diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.h b/drivers/thermal/ti-soc-thermal/ti-bandgap.h
+index 5f4794a..b3adf72 100644
+--- a/drivers/thermal/ti-soc-thermal/ti-bandgap.h
++++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.h
+@@ -400,4 +400,9 @@ extern const struct ti_bandgap_data omap5430_data;
+ #define omap5430_data                                 NULL
+ #endif
++#ifdef CONFIG_DRA752_THERMAL
++extern const struct ti_bandgap_data dra752_data;
++#else
++#define dra752_data                                   NULL
++#endif
+ #endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0941-thermal-consider-emul_temperature-while-computing-tr.patch b/patches.tizen/0941-thermal-consider-emul_temperature-while-computing-tr.patch
new file mode 100644 (file)
index 0000000..8d29210
--- /dev/null
@@ -0,0 +1,43 @@
+From 176a8dd1e6ddf00cd792faeaaaa614b44f88e963 Mon Sep 17 00:00:00 2001
+From: Eduardo Valentin <eduardo.valentin@ti.com>
+Date: Wed, 29 May 2013 21:37:00 +0000
+Subject: [PATCH 0941/1302] thermal: consider emul_temperature while computing
+ trend
+
+In case emulated temperature is in use, using the trend
+provided by driver layer can lead to bogus situation.
+In this case, debugger user would set a temperature value,
+but the trend would be from driver computation.
+
+To avoid this situation, this patch changes the get_tz_trend()
+to consider the emulated temperature whenever that is in use.
+
+Cc: Zhang Rui <rui.zhang@intel.com>
+Cc: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Cc: Durgadoss R <durgadoss.r@intel.com>
+Cc: linux-pm@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/thermal_core.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
+index cd9faa8..8f4be55 100644
+--- a/drivers/thermal/thermal_core.c
++++ b/drivers/thermal/thermal_core.c
+@@ -157,7 +157,8 @@ int get_tz_trend(struct thermal_zone_device *tz, int trip)
+ {
+       enum thermal_trend trend;
+-      if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
++      if (tz->emul_temperature || !tz->ops->get_trend ||
++          tz->ops->get_trend(tz, trip, &trend)) {
+               if (tz->temperature > tz->last_temperature)
+                       trend = THERMAL_TREND_RAISING;
+               else if (tz->temperature < tz->last_temperature)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0942-Thermal-CPU-Package-temperature-thermal.patch b/patches.tizen/0942-Thermal-CPU-Package-temperature-thermal.patch
new file mode 100644 (file)
index 0000000..f46189e
--- /dev/null
@@ -0,0 +1,707 @@
+From e4187ca8ee54d3e3274ab28857f2315ffa24b386 Mon Sep 17 00:00:00 2001
+From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Date: Fri, 17 May 2013 23:42:02 +0000
+Subject: [PATCH 0942/1302] Thermal: CPU Package temperature thermal
+
+This driver register CPU digital temperature sensor as a thermal
+zone at package level.
+Each package will show up as one zone with at max two trip points.
+These trip points can be both read and updated. Once a non zero
+value is set in the trip point, if the package package temperature
+goes above or below this setting, a thermal notification is
+generated.
+
+Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/Kconfig                |  12 +
+ drivers/thermal/Makefile               |   1 +
+ drivers/thermal/x86_pkg_temp_thermal.c | 642 +++++++++++++++++++++++++++++++++
+ 3 files changed, 655 insertions(+)
+ create mode 100644 drivers/thermal/x86_pkg_temp_thermal.c
+
+diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
+index 7205c70..fe04d56 100644
+--- a/drivers/thermal/Kconfig
++++ b/drivers/thermal/Kconfig
+@@ -169,6 +169,18 @@ config INTEL_POWERCLAMP
+         enforce idle time which results in more package C-state residency. The
+         user interface is exposed via generic thermal framework.
++config X86_PKG_TEMP_THERMAL
++      tristate "X86 package temperature thermal driver"
++      depends on THERMAL
++      depends on X86
++      select THERMAL_GOV_USER_SPACE
++      default m
++      help
++        Enable this to register CPU digital sensor for package temperature as
++        thermal zone. Each package will have its own thermal zone. There are
++        two trip points which can be set by user to get notifications via thermal
++        notification methods.
++
+ menu "Texas Instruments thermal drivers"
+ source "drivers/thermal/ti-soc-thermal/Kconfig"
+ endmenu
+diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
+index 8569394..67184a2 100644
+--- a/drivers/thermal/Makefile
++++ b/drivers/thermal/Makefile
+@@ -23,4 +23,5 @@ obj-$(CONFIG_DB8500_THERMAL) += db8500_thermal.o
+ obj-$(CONFIG_ARMADA_THERMAL)  += armada_thermal.o
+ obj-$(CONFIG_DB8500_CPUFREQ_COOLING)  += db8500_cpufreq_cooling.o
+ obj-$(CONFIG_INTEL_POWERCLAMP)        += intel_powerclamp.o
++obj-$(CONFIG_X86_PKG_TEMP_THERMAL)    += x86_pkg_temp_thermal.o
+ obj-$(CONFIG_TI_SOC_THERMAL)  += ti-soc-thermal/
+diff --git a/drivers/thermal/x86_pkg_temp_thermal.c b/drivers/thermal/x86_pkg_temp_thermal.c
+new file mode 100644
+index 0000000..61c9e9f
+--- /dev/null
++++ b/drivers/thermal/x86_pkg_temp_thermal.c
+@@ -0,0 +1,642 @@
++/*
++ * x86_pkg_temp_thermal driver
++ * Copyright (c) 2013, Intel Corporation.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope 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.
++ *
++ */
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/err.h>
++#include <linux/param.h>
++#include <linux/device.h>
++#include <linux/platform_device.h>
++#include <linux/cpu.h>
++#include <linux/smp.h>
++#include <linux/slab.h>
++#include <linux/pm.h>
++#include <linux/thermal.h>
++#include <linux/debugfs.h>
++#include <asm/cpu_device_id.h>
++#include <asm/mce.h>
++
++/*
++* Rate control delay: Idea is to introduce denounce effect
++* This should be long enough to avoid reduce events, when
++* threshold is set to a temperature, which is constantly
++* violated, but at the short enough to take any action.
++* The action can be remove threshold or change it to next
++* interesting setting. Based on experiments, in around
++* every 5 seconds under load will give us a significant
++* temperature change.
++*/
++#define PKG_TEMP_THERMAL_NOTIFY_DELAY 5000
++static int notify_delay_ms = PKG_TEMP_THERMAL_NOTIFY_DELAY;
++module_param(notify_delay_ms, int, 0644);
++MODULE_PARM_DESC(notify_delay_ms,
++      "User space notification delay in milli seconds.");
++
++/* Number of trip points in thermal zone. Currently it can't
++* be more than 2. MSR can allow setting and getting notifications
++* for only 2 thresholds. This define enforces this, if there
++* is some wrong values returned by cpuid for number of thresholds.
++*/
++#define MAX_NUMBER_OF_TRIPS   2
++
++struct phy_dev_entry {
++      struct list_head list;
++      u16 phys_proc_id;
++      u16 first_cpu;
++      u32 tj_max;
++      int ref_cnt;
++      u32 start_pkg_therm_low;
++      u32 start_pkg_therm_high;
++      struct thermal_zone_device *tzone;
++};
++
++/* List maintaining number of package instances */
++static LIST_HEAD(phy_dev_list);
++static DEFINE_MUTEX(phy_dev_list_mutex);
++
++/* Interrupt to work function schedule queue */
++static DEFINE_PER_CPU(struct delayed_work, pkg_temp_thermal_threshold_work);
++
++/* To track if the work is already scheduled on a package */
++static u8 *pkg_work_scheduled;
++
++/* Spin lock to prevent races with pkg_work_scheduled */
++static spinlock_t pkg_work_lock;
++static u16 max_phy_id;
++
++/* Debug counters to show using debugfs */
++static struct dentry *debugfs;
++static unsigned int pkg_interrupt_cnt;
++static unsigned int pkg_work_cnt;
++
++static int pkg_temp_debugfs_init(void)
++{
++      struct dentry *d;
++
++      debugfs = debugfs_create_dir("pkg_temp_thermal", NULL);
++      if (!debugfs)
++              return -ENOENT;
++
++      d = debugfs_create_u32("pkg_thres_interrupt", S_IRUGO, debugfs,
++                              (u32 *)&pkg_interrupt_cnt);
++      if (!d)
++              goto err_out;
++
++      d = debugfs_create_u32("pkg_thres_work", S_IRUGO, debugfs,
++                              (u32 *)&pkg_work_cnt);
++      if (!d)
++              goto err_out;
++
++      return 0;
++
++err_out:
++      debugfs_remove_recursive(debugfs);
++      return -ENOENT;
++}
++
++static struct phy_dev_entry
++                      *pkg_temp_thermal_get_phy_entry(unsigned int cpu)
++{
++      u16 phys_proc_id = topology_physical_package_id(cpu);
++      struct phy_dev_entry *phy_ptr;
++
++      mutex_lock(&phy_dev_list_mutex);
++
++      list_for_each_entry(phy_ptr, &phy_dev_list, list)
++              if (phy_ptr->phys_proc_id == phys_proc_id) {
++                      mutex_unlock(&phy_dev_list_mutex);
++                      return phy_ptr;
++              }
++
++      mutex_unlock(&phy_dev_list_mutex);
++
++      return NULL;
++}
++
++/*
++* tj-max is is interesting because threshold is set relative to this
++* temperature.
++*/
++static int get_tj_max(int cpu, u32 *tj_max)
++{
++      u32 eax, edx;
++      u32 val;
++      int err;
++
++      err = rdmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx);
++      if (err)
++              goto err_ret;
++      else {
++              val = (eax >> 16) & 0xff;
++              if (val)
++                      *tj_max = val * 1000;
++              else {
++                      err = -EINVAL;
++                      goto err_ret;
++              }
++      }
++
++      return 0;
++err_rt:
++      *tj_max = 0;
++      return err;
++}
++
++static int sys_get_curr_temp(struct thermal_zone_device *tzd, unsigned long *temp)
++{
++      u32 eax, edx;
++      struct phy_dev_entry *phy_dev_entry;
++
++      phy_dev_entry = tzd->devdata;
++      rdmsr_on_cpu(phy_dev_entry->first_cpu, MSR_IA32_PACKAGE_THERM_STATUS,
++                      &eax, &edx);
++      if (eax & 0x80000000) {
++              *temp = phy_dev_entry->tj_max -
++                              ((eax >> 16) & 0x7f) * 1000;
++              pr_debug("sys_get_curr_temp %ld\n", *temp);
++              return 0;
++      }
++
++      return -EINVAL;
++}
++
++static int sys_get_trip_temp(struct thermal_zone_device *tzd,
++              int trip, unsigned long *temp)
++{
++      u32 eax, edx;
++      struct phy_dev_entry *phy_dev_entry;
++      u32 mask, shift;
++      unsigned long thres_reg_value;
++      int ret;
++
++      if (trip >= MAX_NUMBER_OF_TRIPS)
++              return -EINVAL;
++
++      phy_dev_entry = tzd->devdata;
++
++      if (trip) {
++              mask = THERM_MASK_THRESHOLD1;
++              shift = THERM_SHIFT_THRESHOLD1;
++      } else {
++              mask = THERM_MASK_THRESHOLD0;
++              shift = THERM_SHIFT_THRESHOLD0;
++      }
++
++      ret = rdmsr_on_cpu(phy_dev_entry->first_cpu,
++                              MSR_IA32_PACKAGE_THERM_INTERRUPT, &eax, &edx);
++      if (ret < 0)
++              return -EINVAL;
++
++      thres_reg_value = (eax & mask) >> shift;
++      if (thres_reg_value)
++              *temp = phy_dev_entry->tj_max - thres_reg_value * 1000;
++      else
++              *temp = 0;
++      pr_debug("sys_get_trip_temp %ld\n", *temp);
++
++      return 0;
++}
++
++int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip,
++                                                      unsigned long temp)
++{
++      u32 l, h;
++      struct phy_dev_entry *phy_dev_entry;
++      u32 mask, shift, intr;
++      int ret;
++
++      phy_dev_entry = tzd->devdata;
++
++      if (trip >= MAX_NUMBER_OF_TRIPS || temp >= phy_dev_entry->tj_max)
++              return -EINVAL;
++
++      ret = rdmsr_on_cpu(phy_dev_entry->first_cpu,
++                                      MSR_IA32_PACKAGE_THERM_INTERRUPT,
++                                      &l, &h);
++      if (ret < 0)
++              return -EINVAL;
++
++      if (trip) {
++              mask = THERM_MASK_THRESHOLD1;
++              shift = THERM_SHIFT_THRESHOLD1;
++              intr = THERM_INT_THRESHOLD1_ENABLE;
++      } else {
++              mask = THERM_MASK_THRESHOLD0;
++              shift = THERM_SHIFT_THRESHOLD0;
++              intr = THERM_INT_THRESHOLD0_ENABLE;
++      }
++      l &= ~mask;
++      /*
++      * When users space sets a trip temperature == 0, which is indication
++      * that, it is no longer interested in receiving notifications.
++      */
++      if (!temp)
++              l &= ~intr;
++      else {
++              l |= (phy_dev_entry->tj_max - temp)/1000 << shift;
++              l |= intr;
++      }
++
++      return wrmsr_on_cpu(phy_dev_entry->first_cpu,
++                                      MSR_IA32_PACKAGE_THERM_INTERRUPT,
++                                      l, h);
++}
++
++static int sys_get_trip_type(struct thermal_zone_device *thermal,
++              int trip, enum thermal_trip_type *type)
++{
++
++      *type = THERMAL_TRIP_PASSIVE;
++
++      return 0;
++}
++
++/* Thermal zone callback registry */
++static struct thermal_zone_device_ops tzone_ops = {
++      .get_temp = sys_get_curr_temp,
++      .get_trip_temp = sys_get_trip_temp,
++      .get_trip_type = sys_get_trip_type,
++      .set_trip_temp = sys_set_trip_temp,
++};
++
++static bool pkg_temp_thermal_platform_thermal_rate_control(void)
++{
++      return true;
++}
++
++/* Enable threshold interrupt on local package/cpu */
++static inline void enable_pkg_thres_interrupt(void)
++{
++      u32 l, h;
++      u8 thres_0, thres_1;
++
++      rdmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
++      /* only enable/disable if it had valid threshold value */
++      thres_0 = (l & THERM_MASK_THRESHOLD0) >> THERM_SHIFT_THRESHOLD0;
++      thres_1 = (l & THERM_MASK_THRESHOLD1) >> THERM_SHIFT_THRESHOLD1;
++      if (thres_0)
++              l |= THERM_INT_THRESHOLD0_ENABLE;
++      if (thres_1)
++              l |= THERM_INT_THRESHOLD1_ENABLE;
++      wrmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
++}
++
++/* Disable threshold interrupt on local package/cpu */
++static inline void disable_pkg_thres_interrupt(void)
++{
++      u32 l, h;
++      rdmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
++      wrmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT,
++                      l & (~THERM_INT_THRESHOLD0_ENABLE) &
++                              (~THERM_INT_THRESHOLD1_ENABLE), h);
++}
++
++static void pkg_temp_thermal_threshold_work_fn(struct work_struct *work)
++{
++      __u64 msr_val;
++      int cpu = smp_processor_id();
++      int phy_id = topology_physical_package_id(cpu);
++      struct phy_dev_entry *phdev = pkg_temp_thermal_get_phy_entry(cpu);
++      bool notify = false;
++
++      if (!phdev)
++              return;
++
++      spin_lock(&pkg_work_lock);
++      ++pkg_work_cnt;
++      if (unlikely(phy_id > max_phy_id)) {
++              spin_unlock(&pkg_work_lock);
++              return;
++      }
++      pkg_work_scheduled[phy_id] = 0;
++      spin_unlock(&pkg_work_lock);
++
++      enable_pkg_thres_interrupt();
++      rdmsrl(MSR_IA32_PACKAGE_THERM_STATUS, msr_val);
++      if (msr_val & THERM_LOG_THRESHOLD0) {
++              wrmsrl(MSR_IA32_PACKAGE_THERM_STATUS,
++                              msr_val & ~THERM_LOG_THRESHOLD0);
++              notify = true;
++      }
++      if (msr_val & THERM_LOG_THRESHOLD1) {
++              wrmsrl(MSR_IA32_PACKAGE_THERM_STATUS,
++                              msr_val & ~THERM_LOG_THRESHOLD1);
++              notify = true;
++      }
++      if (notify) {
++              pr_debug("thermal_zone_device_update\n");
++              thermal_zone_device_update(phdev->tzone);
++      }
++}
++
++static int pkg_temp_thermal_platform_thermal_notify(__u64 msr_val)
++{
++      unsigned long flags;
++      int cpu = smp_processor_id();
++      int phy_id = topology_physical_package_id(cpu);
++
++      /*
++      * When a package is in interrupted state, all CPU's in that package
++      * are in the same interrupt state. So scheduling on any one CPU in
++      * the package is enough and simply return for others.
++      */
++      spin_lock_irqsave(&pkg_work_lock, flags);
++      ++pkg_interrupt_cnt;
++      if (unlikely(phy_id > max_phy_id) || unlikely(!pkg_work_scheduled) ||
++                      pkg_work_scheduled[phy_id]) {
++              disable_pkg_thres_interrupt();
++              spin_unlock_irqrestore(&pkg_work_lock, flags);
++              return -EINVAL;
++      }
++      pkg_work_scheduled[phy_id] = 1;
++      spin_unlock_irqrestore(&pkg_work_lock, flags);
++
++      disable_pkg_thres_interrupt();
++      schedule_delayed_work_on(cpu,
++                              &per_cpu(pkg_temp_thermal_threshold_work, cpu),
++                              msecs_to_jiffies(notify_delay_ms));
++      return 0;
++}
++
++static int find_siblings_cpu(int cpu)
++{
++      int i;
++      int id = topology_physical_package_id(cpu);
++
++      for_each_online_cpu(i)
++              if (i != cpu && topology_physical_package_id(i) == id)
++                      return i;
++
++      return 0;
++}
++
++static int pkg_temp_thermal_device_add(unsigned int cpu)
++{
++      int err;
++      u32 tj_max;
++      struct phy_dev_entry *phy_dev_entry;
++      char buffer[30];
++      int thres_count;
++      u32 eax, ebx, ecx, edx;
++
++      cpuid(6, &eax, &ebx, &ecx, &edx);
++      thres_count = ebx & 0x07;
++      if (!thres_count)
++              return -ENODEV;
++
++      thres_count = clamp_val(thres_count, 0, MAX_NUMBER_OF_TRIPS);
++
++      err = get_tj_max(cpu, &tj_max);
++      if (err)
++              goto err_ret;
++
++      mutex_lock(&phy_dev_list_mutex);
++
++      phy_dev_entry = kzalloc(sizeof(*phy_dev_entry), GFP_KERNEL);
++      if (!phy_dev_entry) {
++              err = -ENOMEM;
++              goto err_ret_unlock;
++      }
++
++      spin_lock(&pkg_work_lock);
++      if (topology_physical_package_id(cpu) > max_phy_id)
++              max_phy_id = topology_physical_package_id(cpu);
++      pkg_work_scheduled = krealloc(pkg_work_scheduled,
++                              (max_phy_id+1) * sizeof(u8), GFP_ATOMIC);
++      if (!pkg_work_scheduled) {
++              spin_unlock(&pkg_work_lock);
++              err = -ENOMEM;
++              goto err_ret_free;
++      }
++      pkg_work_scheduled[topology_physical_package_id(cpu)] = 0;
++      spin_unlock(&pkg_work_lock);
++
++      phy_dev_entry->phys_proc_id = topology_physical_package_id(cpu);
++      phy_dev_entry->first_cpu = cpu;
++      phy_dev_entry->tj_max = tj_max;
++      phy_dev_entry->ref_cnt = 1;
++      snprintf(buffer, sizeof(buffer), "pkg-temp-%d\n",
++                                      phy_dev_entry->phys_proc_id);
++      phy_dev_entry->tzone = thermal_zone_device_register(buffer,
++                      thres_count,
++                      (thres_count == MAX_NUMBER_OF_TRIPS) ?
++                              0x03 : 0x01,
++                      phy_dev_entry, &tzone_ops, NULL, 0, 0);
++      if (IS_ERR(phy_dev_entry->tzone)) {
++              err = PTR_ERR(phy_dev_entry->tzone);
++              goto err_ret_free;
++      }
++      /* Store MSR value for package thermal interrupt, to restore at exit */
++      rdmsr_on_cpu(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT,
++                              &phy_dev_entry->start_pkg_therm_low,
++                              &phy_dev_entry->start_pkg_therm_high);
++
++      list_add_tail(&phy_dev_entry->list, &phy_dev_list);
++      pr_debug("pkg_temp_thermal_device_add :phy_id %d cpu %d\n",
++                      phy_dev_entry->phys_proc_id, cpu);
++
++      mutex_unlock(&phy_dev_list_mutex);
++
++      return 0;
++
++err_ret_free:
++      kfree(phy_dev_entry);
++err_ret_unlock:
++      mutex_unlock(&phy_dev_list_mutex);
++
++err_ret:
++      return err;
++}
++
++static int pkg_temp_thermal_device_remove(unsigned int cpu)
++{
++      struct phy_dev_entry *n;
++      u16 phys_proc_id = topology_physical_package_id(cpu);
++      struct phy_dev_entry *phdev =
++                      pkg_temp_thermal_get_phy_entry(cpu);
++
++      if (!phdev)
++              return -ENODEV;
++
++      mutex_lock(&phy_dev_list_mutex);
++      /* If we are loosing the first cpu for this package, we need change */
++      if (phdev->first_cpu == cpu) {
++              phdev->first_cpu = find_siblings_cpu(cpu);
++              pr_debug("thermal_device_remove: first cpu switched %d\n",
++                                      phdev->first_cpu);
++      }
++      /*
++      * It is possible that no siblings left as this was the last cpu
++      * going offline. We don't need to worry about this assignment
++      * as the phydev entry will be removed in this case and
++      * thermal zone is removed.
++      */
++      --phdev->ref_cnt;
++      pr_debug("thermal_device_remove: pkg: %d cpu %d ref_cnt %d\n",
++                                      phys_proc_id, cpu, phdev->ref_cnt);
++      if (!phdev->ref_cnt)
++              list_for_each_entry_safe(phdev, n, &phy_dev_list, list) {
++                      if (phdev->phys_proc_id == phys_proc_id) {
++                              thermal_zone_device_unregister(phdev->tzone);
++                              list_del(&phdev->list);
++                              kfree(phdev);
++                              break;
++                      }
++              }
++      mutex_unlock(&phy_dev_list_mutex);
++
++      return 0;
++}
++
++static int get_core_online(unsigned int cpu)
++{
++      struct cpuinfo_x86 *c = &cpu_data(cpu);
++      struct phy_dev_entry *phdev = pkg_temp_thermal_get_phy_entry(cpu);
++
++      /* Check if there is already an instance for this package */
++      if (!phdev) {
++              if (!cpu_has(c, X86_FEATURE_DTHERM) &&
++                                      !cpu_has(c, X86_FEATURE_PTS))
++                      return -ENODEV;
++              if (pkg_temp_thermal_device_add(cpu))
++                      return -ENODEV;
++      } else {
++              mutex_lock(&phy_dev_list_mutex);
++              ++phdev->ref_cnt;
++              pr_debug("get_core_online: cpu %d ref_cnt %d\n",
++                                              cpu, phdev->ref_cnt);
++              mutex_unlock(&phy_dev_list_mutex);
++      }
++      INIT_DELAYED_WORK(&per_cpu(pkg_temp_thermal_threshold_work, cpu),
++                      pkg_temp_thermal_threshold_work_fn);
++
++      pr_debug("get_core_online: cpu %d successful\n", cpu);
++
++      return 0;
++}
++
++static void put_core_offline(unsigned int cpu)
++{
++      if (!pkg_temp_thermal_device_remove(cpu))
++              cancel_delayed_work_sync(
++                      &per_cpu(pkg_temp_thermal_threshold_work, cpu));
++
++      pr_debug("put_core_offline: cpu %d\n", cpu);
++}
++
++static int pkg_temp_thermal_cpu_callback(struct notifier_block *nfb,
++                               unsigned long action, void *hcpu)
++{
++      unsigned int cpu = (unsigned long) hcpu;
++
++      switch (action) {
++      case CPU_ONLINE:
++      case CPU_DOWN_FAILED:
++              get_core_online(cpu);
++              break;
++      case CPU_DOWN_PREPARE:
++              put_core_offline(cpu);
++              break;
++      }
++      return NOTIFY_OK;
++}
++
++static struct notifier_block pkg_temp_thermal_notifier __refdata = {
++      .notifier_call = pkg_temp_thermal_cpu_callback,
++};
++
++static const struct x86_cpu_id __initconst pkg_temp_thermal_ids[] = {
++      { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTHERM },
++      {}
++};
++MODULE_DEVICE_TABLE(x86cpu, pkg_temp_thermal_ids);
++
++static int __init pkg_temp_thermal_init(void)
++{
++      int i;
++
++      if (!x86_match_cpu(pkg_temp_thermal_ids))
++              return -ENODEV;
++
++      spin_lock_init(&pkg_work_lock);
++      platform_thermal_package_notify =
++                      pkg_temp_thermal_platform_thermal_notify;
++      platform_thermal_package_rate_control =
++                      pkg_temp_thermal_platform_thermal_rate_control;
++
++      get_online_cpus();
++      for_each_online_cpu(i)
++              if (get_core_online(i))
++                      goto err_ret;
++      register_hotcpu_notifier(&pkg_temp_thermal_notifier);
++      put_online_cpus();
++
++      pkg_temp_debugfs_init(); /* Don't care if fails */
++
++      return 0;
++
++err_ret:
++      get_online_cpus();
++      for_each_online_cpu(i)
++              put_core_offline(i);
++      put_online_cpus();
++      kfree(pkg_work_scheduled);
++      platform_thermal_package_notify = NULL;
++      platform_thermal_package_rate_control = NULL;
++
++      return -ENODEV;
++}
++
++static void __exit pkg_temp_thermal_exit(void)
++{
++      struct phy_dev_entry *phdev, *n;
++      int i;
++
++      get_online_cpus();
++      unregister_hotcpu_notifier(&pkg_temp_thermal_notifier);
++      mutex_lock(&phy_dev_list_mutex);
++      list_for_each_entry_safe(phdev, n, &phy_dev_list, list) {
++              /* Retore old MSR value for package thermal interrupt */
++              wrmsr_on_cpu(phdev->first_cpu,
++                      MSR_IA32_PACKAGE_THERM_INTERRUPT,
++                      phdev->start_pkg_therm_low,
++                      phdev->start_pkg_therm_high);
++              thermal_zone_device_unregister(phdev->tzone);
++              list_del(&phdev->list);
++              kfree(phdev);
++      }
++      mutex_unlock(&phy_dev_list_mutex);
++      platform_thermal_package_notify = NULL;
++      platform_thermal_package_rate_control = NULL;
++      for_each_online_cpu(i)
++              cancel_delayed_work_sync(
++                      &per_cpu(pkg_temp_thermal_threshold_work, i));
++      put_online_cpus();
++
++      kfree(pkg_work_scheduled);
++
++      debugfs_remove_recursive(debugfs);
++}
++
++module_init(pkg_temp_thermal_init)
++module_exit(pkg_temp_thermal_exit)
++
++MODULE_DESCRIPTION("X86 PKG TEMP Thermal Driver");
++MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
++MODULE_LICENSE("GPL v2");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0943-thermal-fix-x86_pkg_temp_thermal.c-build-and-Kconfig.patch b/patches.tizen/0943-thermal-fix-x86_pkg_temp_thermal.c-build-and-Kconfig.patch
new file mode 100644 (file)
index 0000000..28e1bd1
--- /dev/null
@@ -0,0 +1,41 @@
+From 000deb989617d380a652531d9a16204d14bb1abf Mon Sep 17 00:00:00 2001
+From: Randy Dunlap <rdunlap@infradead.org>
+Date: Mon, 17 Jun 2013 12:27:17 -0700
+Subject: [PATCH 0943/1302] thermal: fix x86_pkg_temp_thermal.c build and
+ Kconfig
+
+Fix build error in x86_pkg_temp_thermal.c.  It requires that
+X86_MCE & X86_THERMAL_VECTOR be enabled, so depend on the latter symbol,
+since it depends on X86_MCE (indirectly).
+
+Also, X86_PKG_TEMP_THERMAL is already inside an "if THERMAL" block,
+so remove that duplicated dependency.
+
+ERROR: "platform_thermal_package_rate_control" [drivers/thermal/x86_pkg_temp_thermal.ko] undefined!
+ERROR: "platform_thermal_package_notify" [drivers/thermal/x86_pkg_temp_thermal.ko] undefined!
+
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Acked-by: Borislav Petkov <bp@suse.de>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/Kconfig | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
+index fe04d56..a60e1ce 100644
+--- a/drivers/thermal/Kconfig
++++ b/drivers/thermal/Kconfig
+@@ -171,8 +171,7 @@ config INTEL_POWERCLAMP
+ config X86_PKG_TEMP_THERMAL
+       tristate "X86 package temperature thermal driver"
+-      depends on THERMAL
+-      depends on X86
++      depends on X86_THERMAL_VECTOR
+       select THERMAL_GOV_USER_SPACE
+       default m
+       help
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0944-thermal-exynos-Support-both-EXYNOS4X12-SoCs.patch b/patches.tizen/0944-thermal-exynos-Support-both-EXYNOS4X12-SoCs.patch
new file mode 100644 (file)
index 0000000..78c744e
--- /dev/null
@@ -0,0 +1,36 @@
+From 8ae14fc974e9cc80cf095cfc6e69a94e308487d9 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 19 Jun 2013 01:31:50 +0900
+Subject: [PATCH 0944/1302] thermal: exynos: Support both EXYNOS4X12 SoCs
+
+EXYNOS4212 and EXYNOS4412 have the same thermal block, so there is no
+reason to include support only for EXYNOS4412 in this driver.
+
+Cc: linux-pm@vger.kernel.org
+Cc: Zhang Rui <rui.zhang@intel.com>
+Cc: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/exynos_thermal.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/exynos_thermal.c b/drivers/thermal/exynos_thermal.c
+index 03e4bbc..9af4b93 100644
+--- a/drivers/thermal/exynos_thermal.c
++++ b/drivers/thermal/exynos_thermal.c
+@@ -817,7 +817,8 @@ static struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
+ #define EXYNOS4210_TMU_DRV_DATA (NULL)
+ #endif
+-#if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412)
++#if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412) || \
++      defined(CONFIG_SOC_EXYNOS4212)
+ static struct exynos_tmu_platform_data const exynos_default_tmu_data = {
+       .threshold_falling = 10,
+       .trigger_levels[0] = 85,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0945-thermal-ti-soc-thermal-use-standard-GPIO-DT-bindings.patch b/patches.tizen/0945-thermal-ti-soc-thermal-use-standard-GPIO-DT-bindings.patch
new file mode 100644 (file)
index 0000000..8b4d94c
--- /dev/null
@@ -0,0 +1,62 @@
+From b196ea2e63b310670ed7297eb54ff9f4a9512b45 Mon Sep 17 00:00:00 2001
+From: Eduardo Valentin <eduardo.valentin@ti.com>
+Date: Fri, 7 Jun 2013 11:11:53 -0400
+Subject: [PATCH 0945/1302] thermal: ti-soc-thermal: use standard GPIO DT
+ bindings
+
+This change updates the ti-soc-thermal driver to use
+standard GPIO DT bindings to read the GPIO number associated
+to thermal shutdown IRQ, in case the device features it.
+
+Previously, the code was using a specific DT bindings.
+As now OMAP supports the standard way to model GPIOs,
+there is no point in having a ti specific binding.
+
+Cc: Zhang Rui <rui.zhang@intel.com>
+Cc: Grant Likely <grant.likely@linaro.org>
+Cc: Rob Herring <rob.herring@calxeda.com>
+Cc: linux-pm@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Cc: devicetree-discuss@lists.ozlabs.org
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/ti-soc-thermal/ti-bandgap.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.c b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
+index 7c0b3eb..9dfd471 100644
+--- a/drivers/thermal/ti-soc-thermal/ti-bandgap.c
++++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
+@@ -38,6 +38,7 @@
+ #include <linux/of_device.h>
+ #include <linux/of_platform.h>
+ #include <linux/of_irq.h>
++#include <linux/of_gpio.h>
+ #include <linux/io.h>
+ #include "ti-bandgap.h"
+@@ -1129,7 +1130,6 @@ static struct ti_bandgap *ti_bandgap_build(struct platform_device *pdev)
+       const struct of_device_id *of_id;
+       struct ti_bandgap *bgp;
+       struct resource *res;
+-      u32 prop;
+       int i;
+       /* just for the sake */
+@@ -1173,11 +1173,7 @@ static struct ti_bandgap *ti_bandgap_build(struct platform_device *pdev)
+       } while (res);
+       if (TI_BANDGAP_HAS(bgp, TSHUT)) {
+-              if (of_property_read_u32(node, "ti,tshut-gpio", &prop) < 0) {
+-                      dev_err(&pdev->dev, "missing tshut gpio in device tree\n");
+-                      return ERR_PTR(-EINVAL);
+-              }
+-              bgp->tshut_gpio = prop;
++              bgp->tshut_gpio = of_get_gpio(node, 0);
+               if (!gpio_is_valid(bgp->tshut_gpio)) {
+                       dev_err(&pdev->dev, "invalid gpio for tshut (%d)\n",
+                               bgp->tshut_gpio);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0946-Thermal-x86-package-temp-thermal-crash.patch b/patches.tizen/0946-Thermal-x86-package-temp-thermal-crash.patch
new file mode 100644 (file)
index 0000000..a51e86e
--- /dev/null
@@ -0,0 +1,45 @@
+From 755ab53f5e93de77d367bc77a1fb1f0cd2464663 Mon Sep 17 00:00:00 2001
+From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Date: Thu, 11 Jul 2013 09:50:30 -0700
+Subject: [PATCH 0946/1302] Thermal: x86 package temp thermal crash
+
+On systems with no package MSR support this caused crash as there
+is a bug in the logic to check presence of DTHERM and PTS feature
+together. Added a change so that when there is no PTS support, module
+doesn't get loaded. Even if some CPU comes online with the PTS
+feature disabled, and other CPUs has this support, this patch
+will still prevent such MSR accesses.
+
+Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Reported-by: Daniel Walker <dwalker@fifo99.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/x86_pkg_temp_thermal.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/thermal/x86_pkg_temp_thermal.c b/drivers/thermal/x86_pkg_temp_thermal.c
+index 61c9e9f..8c4a8ce 100644
+--- a/drivers/thermal/x86_pkg_temp_thermal.c
++++ b/drivers/thermal/x86_pkg_temp_thermal.c
+@@ -511,7 +511,7 @@ static int get_core_online(unsigned int cpu)
+       /* Check if there is already an instance for this package */
+       if (!phdev) {
+-              if (!cpu_has(c, X86_FEATURE_DTHERM) &&
++              if (!cpu_has(c, X86_FEATURE_DTHERM) ||
+                                       !cpu_has(c, X86_FEATURE_PTS))
+                       return -ENODEV;
+               if (pkg_temp_thermal_device_add(cpu))
+@@ -562,7 +562,7 @@ static struct notifier_block pkg_temp_thermal_notifier __refdata = {
+ };
+ static const struct x86_cpu_id __initconst pkg_temp_thermal_ids[] = {
+-      { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTHERM },
++      { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_PTS },
+       {}
+ };
+ MODULE_DEVICE_TABLE(x86cpu, pkg_temp_thermal_ids);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0947-Thermal-x86_pkg_temp-fix-krealloc-misuse-in-in-pkg_t.patch b/patches.tizen/0947-Thermal-x86_pkg_temp-fix-krealloc-misuse-in-in-pkg_t.patch
new file mode 100644 (file)
index 0000000..b49b924
--- /dev/null
@@ -0,0 +1,49 @@
+From 2c373f4ddf5d34207cdafa7f76742acf19a0b825 Mon Sep 17 00:00:00 2001
+From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
+Date: Tue, 18 Jun 2013 21:09:12 +0800
+Subject: [PATCH 0947/1302] Thermal: x86_pkg_temp: fix krealloc() misuse in in
+ pkg_temp_thermal_device_add()
+
+If krealloc() returns NULL, it doesn't free the original. So any code
+of the form 'foo = krealloc(foo, ...);' is almost certainly a bug.
+
+Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/x86_pkg_temp_thermal.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/thermal/x86_pkg_temp_thermal.c b/drivers/thermal/x86_pkg_temp_thermal.c
+index 8c4a8ce..1dca011 100644
+--- a/drivers/thermal/x86_pkg_temp_thermal.c
++++ b/drivers/thermal/x86_pkg_temp_thermal.c
+@@ -394,6 +394,7 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
+       char buffer[30];
+       int thres_count;
+       u32 eax, ebx, ecx, edx;
++      u8 *temp;
+       cpuid(6, &eax, &ebx, &ecx, &edx);
+       thres_count = ebx & 0x07;
+@@ -417,13 +418,14 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
+       spin_lock(&pkg_work_lock);
+       if (topology_physical_package_id(cpu) > max_phy_id)
+               max_phy_id = topology_physical_package_id(cpu);
+-      pkg_work_scheduled = krealloc(pkg_work_scheduled,
+-                              (max_phy_id+1) * sizeof(u8), GFP_ATOMIC);
+-      if (!pkg_work_scheduled) {
++      temp = krealloc(pkg_work_scheduled,
++                      (max_phy_id+1) * sizeof(u8), GFP_ATOMIC);
++      if (!temp) {
+               spin_unlock(&pkg_work_lock);
+               err = -ENOMEM;
+               goto err_ret_free;
+       }
++      pkg_work_scheduled = temp;
+       pkg_work_scheduled[topology_physical_package_id(cpu)] = 0;
+       spin_unlock(&pkg_work_lock);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0948-Thermal-x86_pkg_temp-Limit-number-of-pkg-temp-zones.patch b/patches.tizen/0948-Thermal-x86_pkg_temp-Limit-number-of-pkg-temp-zones.patch
new file mode 100644 (file)
index 0000000..a7511bb
--- /dev/null
@@ -0,0 +1,44 @@
+From e690469793f10b44738c482fe6e0c7e043c7960c Mon Sep 17 00:00:00 2001
+From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Date: Mon, 15 Jul 2013 15:38:52 -0700
+Subject: [PATCH 0948/1302] Thermal: x86_pkg_temp: Limit number of pkg temp
+ zones
+
+Although it is unlikley that physical package id is set to some
+arbitary number, it is better to prevent in anycase. Since package
+temp zones use this in thermal zone type and for allocation, added
+a limit.
+
+Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/x86_pkg_temp_thermal.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/thermal/x86_pkg_temp_thermal.c b/drivers/thermal/x86_pkg_temp_thermal.c
+index 1dca011..eb2b045 100644
+--- a/drivers/thermal/x86_pkg_temp_thermal.c
++++ b/drivers/thermal/x86_pkg_temp_thermal.c
+@@ -54,6 +54,8 @@ MODULE_PARM_DESC(notify_delay_ms,
+ * is some wrong values returned by cpuid for number of thresholds.
+ */
+ #define MAX_NUMBER_OF_TRIPS   2
++/* Limit number of package temp zones */
++#define MAX_PKG_TEMP_ZONE_IDS 256
+ struct phy_dev_entry {
+       struct list_head list;
+@@ -401,6 +403,9 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
+       if (!thres_count)
+               return -ENODEV;
++      if (topology_physical_package_id(cpu) > MAX_PKG_TEMP_ZONE_IDS)
++              return -ENODEV;
++
+       thres_count = clamp_val(thres_count, 0, MAX_NUMBER_OF_TRIPS);
+       err = get_tj_max(cpu, &tj_max);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0949-Thermal-Fix-lockup-of-cpu_down.patch b/patches.tizen/0949-Thermal-Fix-lockup-of-cpu_down.patch
new file mode 100644 (file)
index 0000000..3350ac4
--- /dev/null
@@ -0,0 +1,43 @@
+From 389c34030afdb37201ef07cfc3e870979d62a601 Mon Sep 17 00:00:00 2001
+From: Steven Rostedt <rostedt@goodmis.org>
+Date: Tue, 16 Jul 2013 14:02:28 -0400
+Subject: [PATCH 0949/1302] Thermal: Fix lockup of cpu_down()
+
+Commit f1a18a105 "Thermal: CPU Package temperature thermal" had code
+that did a get_online_cpus(), run a loop and then do a
+put_online_cpus(). The problem is that the loop had an error exit that
+would skip the put_online_cpus() part.
+
+In the error exit part of the function, it also did a get_online_cpus(),
+run a loop and then put_online_cpus(). The only way to get to the error
+exit part is with get_online_cpus() already performed. If this error
+condition is hit, the system will be prevented from taking CPUs offline.
+The process taking the CPU offline will lock up hard.
+
+Removing the get_online_cpus() removes the lockup as the hotplug CPU
+refcount is back to zero.
+
+This was bisected with ktest.
+
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/x86_pkg_temp_thermal.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/thermal/x86_pkg_temp_thermal.c b/drivers/thermal/x86_pkg_temp_thermal.c
+index eb2b045..cf59433 100644
+--- a/drivers/thermal/x86_pkg_temp_thermal.c
++++ b/drivers/thermal/x86_pkg_temp_thermal.c
+@@ -599,7 +599,6 @@ static int __init pkg_temp_thermal_init(void)
+       return 0;
+ err_ret:
+-      get_online_cpus();
+       for_each_online_cpu(i)
+               put_core_offline(i);
+       put_online_cpus();
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0950-thermal-add-imx-thermal-driver-support.patch b/patches.tizen/0950-thermal-add-imx-thermal-driver-support.patch
new file mode 100644 (file)
index 0000000..8f218d9
--- /dev/null
@@ -0,0 +1,466 @@
+From 2a8d9be062514d377adb93a0fb4bb57ac37e876b Mon Sep 17 00:00:00 2001
+From: Shawn Guo <shawn.guo@linaro.org>
+Date: Mon, 24 Jun 2013 14:30:44 +0800
+Subject: [PATCH 0950/1302] thermal: add imx thermal driver support
+
+This is based on the initial imx thermal work done by
+Rob Lee <rob.lee@linaro.org> (Not sure if the email address is still
+valid).  Since he is no longer interested in the work and I have
+rewritten a significant amount of the code, I just took the authorship
+over from him.
+
+It adds the imx thermal support using Temperature Monitor (TEMPMON)
+block found on some Freescale i.MX SoCs.  The driver uses syscon regmap
+interface to access TEMPMON control registers and calibration data, and
+supports cpufreq as the cooling device.
+
+Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/Kconfig       |  11 ++
+ drivers/thermal/Makefile      |   1 +
+ drivers/thermal/imx_thermal.c | 397 ++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 409 insertions(+)
+ create mode 100644 drivers/thermal/imx_thermal.c
+
+diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
+index a60e1ce..cb24078 100644
+--- a/drivers/thermal/Kconfig
++++ b/drivers/thermal/Kconfig
+@@ -91,6 +91,17 @@ config THERMAL_EMULATION
+         because userland can easily disable the thermal policy by simply
+         flooding this sysfs node with low temperature values.
++config IMX_THERMAL
++      tristate "Temperature sensor driver for Freescale i.MX SoCs"
++      depends on CPU_THERMAL
++      depends on MFD_SYSCON
++      depends on OF
++      help
++        Support for Temperature Monitor (TEMPMON) found on Freescale i.MX SoCs.
++        It supports one critical trip point and one passive trip point.  The
++        cpufreq is used as the cooling device to throttle CPUs when the
++        passive trip is crossed.
++
+ config SPEAR_THERMAL
+       bool "SPEAr thermal sensor driver"
+       depends on PLAT_SPEAR
+diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
+index 67184a2..dff19c6 100644
+--- a/drivers/thermal/Makefile
++++ b/drivers/thermal/Makefile
+@@ -21,6 +21,7 @@ obj-$(CONFIG_EXYNOS_THERMAL) += exynos_thermal.o
+ obj-$(CONFIG_DOVE_THERMAL)    += dove_thermal.o
+ obj-$(CONFIG_DB8500_THERMAL)  += db8500_thermal.o
+ obj-$(CONFIG_ARMADA_THERMAL)  += armada_thermal.o
++obj-$(CONFIG_IMX_THERMAL)     += imx_thermal.o
+ obj-$(CONFIG_DB8500_CPUFREQ_COOLING)  += db8500_cpufreq_cooling.o
+ obj-$(CONFIG_INTEL_POWERCLAMP)        += intel_powerclamp.o
+ obj-$(CONFIG_X86_PKG_TEMP_THERMAL)    += x86_pkg_temp_thermal.o
+diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
+new file mode 100644
+index 0000000..d16c33c
+--- /dev/null
++++ b/drivers/thermal/imx_thermal.c
+@@ -0,0 +1,397 @@
++/*
++ * Copyright 2013 Freescale Semiconductor, Inc.
++ *
++ * 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/cpu_cooling.h>
++#include <linux/cpufreq.h>
++#include <linux/delay.h>
++#include <linux/device.h>
++#include <linux/init.h>
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/mfd/syscon.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/regmap.h>
++#include <linux/slab.h>
++#include <linux/thermal.h>
++#include <linux/types.h>
++
++#define REG_SET               0x4
++#define REG_CLR               0x8
++#define REG_TOG               0xc
++
++#define MISC0                         0x0150
++#define MISC0_REFTOP_SELBIASOFF               (1 << 3)
++
++#define TEMPSENSE0                    0x0180
++#define TEMPSENSE0_TEMP_CNT_SHIFT     8
++#define TEMPSENSE0_TEMP_CNT_MASK      (0xfff << TEMPSENSE0_TEMP_CNT_SHIFT)
++#define TEMPSENSE0_FINISHED           (1 << 2)
++#define TEMPSENSE0_MEASURE_TEMP               (1 << 1)
++#define TEMPSENSE0_POWER_DOWN         (1 << 0)
++
++#define TEMPSENSE1                    0x0190
++#define TEMPSENSE1_MEASURE_FREQ               0xffff
++
++#define OCOTP_ANA1                    0x04e0
++
++/* The driver supports 1 passive trip point and 1 critical trip point */
++enum imx_thermal_trip {
++      IMX_TRIP_PASSIVE,
++      IMX_TRIP_CRITICAL,
++      IMX_TRIP_NUM,
++};
++
++/*
++ * It defines the temperature in millicelsius for passive trip point
++ * that will trigger cooling action when crossed.
++ */
++#define IMX_TEMP_PASSIVE              85000
++
++/*
++ * The maximum die temperature on imx parts is 105C, let's give some cushion
++ * for noise and possible temperature rise between measurements.
++ */
++#define IMX_TEMP_CRITICAL             100000
++
++#define IMX_POLLING_DELAY             2000 /* millisecond */
++#define IMX_PASSIVE_DELAY             1000
++
++struct imx_thermal_data {
++      struct thermal_zone_device *tz;
++      struct thermal_cooling_device *cdev;
++      enum thermal_device_mode mode;
++      struct regmap *tempmon;
++      int c1, c2; /* See formula in imx_get_sensor_data() */
++};
++
++static int imx_get_temp(struct thermal_zone_device *tz, unsigned long *temp)
++{
++      struct imx_thermal_data *data = tz->devdata;
++      struct regmap *map = data->tempmon;
++      static unsigned long last_temp;
++      unsigned int n_meas;
++      u32 val;
++
++      /*
++       * Every time we measure the temperature, we will power on the
++       * temperature sensor, enable measurements, take a reading,
++       * disable measurements, power off the temperature sensor.
++       */
++      regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN);
++      regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP);
++
++      /*
++       * According to the temp sensor designers, it may require up to ~17us
++       * to complete a measurement.
++       */
++      usleep_range(20, 50);
++
++      regmap_read(map, TEMPSENSE0, &val);
++      regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP);
++      regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);
++
++      if ((val & TEMPSENSE0_FINISHED) == 0) {
++              dev_dbg(&tz->device, "temp measurement never finished\n");
++              return -EAGAIN;
++      }
++
++      n_meas = (val & TEMPSENSE0_TEMP_CNT_MASK) >> TEMPSENSE0_TEMP_CNT_SHIFT;
++
++      /* See imx_get_sensor_data() for formula derivation */
++      *temp = data->c2 + data->c1 * n_meas;
++
++      if (*temp != last_temp) {
++              dev_dbg(&tz->device, "millicelsius: %ld\n", *temp);
++              last_temp = *temp;
++      }
++
++      return 0;
++}
++
++static int imx_get_mode(struct thermal_zone_device *tz,
++                      enum thermal_device_mode *mode)
++{
++      struct imx_thermal_data *data = tz->devdata;
++
++      *mode = data->mode;
++
++      return 0;
++}
++
++static int imx_set_mode(struct thermal_zone_device *tz,
++                      enum thermal_device_mode mode)
++{
++      struct imx_thermal_data *data = tz->devdata;
++
++      if (mode == THERMAL_DEVICE_ENABLED) {
++              tz->polling_delay = IMX_POLLING_DELAY;
++              tz->passive_delay = IMX_PASSIVE_DELAY;
++      } else {
++              tz->polling_delay = 0;
++              tz->passive_delay = 0;
++      }
++
++      data->mode = mode;
++      thermal_zone_device_update(tz);
++
++      return 0;
++}
++
++static int imx_get_trip_type(struct thermal_zone_device *tz, int trip,
++                           enum thermal_trip_type *type)
++{
++      *type = (trip == IMX_TRIP_PASSIVE) ? THERMAL_TRIP_PASSIVE :
++                                           THERMAL_TRIP_CRITICAL;
++      return 0;
++}
++
++static int imx_get_crit_temp(struct thermal_zone_device *tz,
++                           unsigned long *temp)
++{
++      *temp = IMX_TEMP_CRITICAL;
++      return 0;
++}
++
++static int imx_get_trip_temp(struct thermal_zone_device *tz, int trip,
++                           unsigned long *temp)
++{
++      *temp = (trip == IMX_TRIP_PASSIVE) ? IMX_TEMP_PASSIVE :
++                                           IMX_TEMP_CRITICAL;
++      return 0;
++}
++
++static int imx_bind(struct thermal_zone_device *tz,
++                  struct thermal_cooling_device *cdev)
++{
++      int ret;
++
++      ret = thermal_zone_bind_cooling_device(tz, IMX_TRIP_PASSIVE, cdev,
++                                             THERMAL_NO_LIMIT,
++                                             THERMAL_NO_LIMIT);
++      if (ret) {
++              dev_err(&tz->device,
++                      "binding zone %s with cdev %s failed:%d\n",
++                      tz->type, cdev->type, ret);
++              return ret;
++      }
++
++      return 0;
++}
++
++static int imx_unbind(struct thermal_zone_device *tz,
++                    struct thermal_cooling_device *cdev)
++{
++      int ret;
++
++      ret = thermal_zone_unbind_cooling_device(tz, IMX_TRIP_PASSIVE, cdev);
++      if (ret) {
++              dev_err(&tz->device,
++                      "unbinding zone %s with cdev %s failed:%d\n",
++                      tz->type, cdev->type, ret);
++              return ret;
++      }
++
++      return 0;
++}
++
++static const struct thermal_zone_device_ops imx_tz_ops = {
++      .bind = imx_bind,
++      .unbind = imx_unbind,
++      .get_temp = imx_get_temp,
++      .get_mode = imx_get_mode,
++      .set_mode = imx_set_mode,
++      .get_trip_type = imx_get_trip_type,
++      .get_trip_temp = imx_get_trip_temp,
++      .get_crit_temp = imx_get_crit_temp,
++};
++
++static int imx_get_sensor_data(struct platform_device *pdev)
++{
++      struct imx_thermal_data *data = platform_get_drvdata(pdev);
++      struct regmap *map;
++      int t1, t2, n1, n2;
++      int ret;
++      u32 val;
++
++      map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
++                                            "fsl,tempmon-data");
++      if (IS_ERR(map)) {
++              ret = PTR_ERR(map);
++              dev_err(&pdev->dev, "failed to get sensor regmap: %d\n", ret);
++              return ret;
++      }
++
++      ret = regmap_read(map, OCOTP_ANA1, &val);
++      if (ret) {
++              dev_err(&pdev->dev, "failed to read sensor data: %d\n", ret);
++              return ret;
++      }
++
++      if (val == 0 || val == ~0) {
++              dev_err(&pdev->dev, "invalid sensor calibration data\n");
++              return -EINVAL;
++      }
++
++      /*
++       * Sensor data layout:
++       *   [31:20] - sensor value @ 25C
++       *    [19:8] - sensor value of hot
++       *     [7:0] - hot temperature value
++       */
++      n1 = val >> 20;
++      n2 = (val & 0xfff00) >> 8;
++      t2 = val & 0xff;
++      t1 = 25; /* t1 always 25C */
++
++      /*
++       * Derived from linear interpolation,
++       * Tmeas = T2 + (Nmeas - N2) * (T1 - T2) / (N1 - N2)
++       * We want to reduce this down to the minimum computation necessary
++       * for each temperature read.  Also, we want Tmeas in millicelsius
++       * and we don't want to lose precision from integer division. So...
++       * milli_Tmeas = 1000 * T2 + 1000 * (Nmeas - N2) * (T1 - T2) / (N1 - N2)
++       * Let constant c1 = 1000 * (T1 - T2) / (N1 - N2)
++       * milli_Tmeas = (1000 * T2) + c1 * (Nmeas - N2)
++       * milli_Tmeas = (1000 * T2) + (c1 * Nmeas) - (c1 * N2)
++       * Let constant c2 = (1000 * T2) - (c1 * N2)
++       * milli_Tmeas = c2 + (c1 * Nmeas)
++       */
++      data->c1 = 1000 * (t1 - t2) / (n1 - n2);
++      data->c2 = 1000 * t2 - data->c1 * n2;
++
++      return 0;
++}
++
++static int imx_thermal_probe(struct platform_device *pdev)
++{
++      struct imx_thermal_data *data;
++      struct cpumask clip_cpus;
++      struct regmap *map;
++      int ret;
++
++      data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
++      if (!data)
++              return -ENOMEM;
++
++      map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "fsl,tempmon");
++      if (IS_ERR(map)) {
++              ret = PTR_ERR(map);
++              dev_err(&pdev->dev, "failed to get tempmon regmap: %d\n", ret);
++              return ret;
++      }
++      data->tempmon = map;
++
++      platform_set_drvdata(pdev, data);
++
++      ret = imx_get_sensor_data(pdev);
++      if (ret) {
++              dev_err(&pdev->dev, "failed to get sensor data\n");
++              return ret;
++      }
++
++      /* Make sure sensor is in known good state for measurements */
++      regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN);
++      regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP);
++      regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ);
++      regmap_write(map, MISC0 + REG_SET, MISC0_REFTOP_SELBIASOFF);
++      regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);
++
++      cpumask_set_cpu(0, &clip_cpus);
++      data->cdev = cpufreq_cooling_register(&clip_cpus);
++      if (IS_ERR(data->cdev)) {
++              ret = PTR_ERR(data->cdev);
++              dev_err(&pdev->dev,
++                      "failed to register cpufreq cooling device: %d\n", ret);
++              return ret;
++      }
++
++      data->tz = thermal_zone_device_register("imx_thermal_zone",
++                                              IMX_TRIP_NUM, 0, data,
++                                              &imx_tz_ops, NULL,
++                                              IMX_PASSIVE_DELAY,
++                                              IMX_POLLING_DELAY);
++      if (IS_ERR(data->tz)) {
++              ret = PTR_ERR(data->tz);
++              dev_err(&pdev->dev,
++                      "failed to register thermal zone device %d\n", ret);
++              cpufreq_cooling_unregister(data->cdev);
++              return ret;
++      }
++
++      data->mode = THERMAL_DEVICE_ENABLED;
++
++      return 0;
++}
++
++static int imx_thermal_remove(struct platform_device *pdev)
++{
++      struct imx_thermal_data *data = platform_get_drvdata(pdev);
++
++      thermal_zone_device_unregister(data->tz);
++      cpufreq_cooling_unregister(data->cdev);
++
++      return 0;
++}
++
++#ifdef CONFIG_PM_SLEEP
++static int imx_thermal_suspend(struct device *dev)
++{
++      struct imx_thermal_data *data = dev_get_drvdata(dev);
++      struct regmap *map = data->tempmon;
++      u32 val;
++
++      regmap_read(map, TEMPSENSE0, &val);
++      if ((val & TEMPSENSE0_POWER_DOWN) == 0) {
++              /*
++               * If a measurement is taking place, wait for a long enough
++               * time for it to finish, and then check again.  If it still
++               * does not finish, something must go wrong.
++               */
++              udelay(50);
++              regmap_read(map, TEMPSENSE0, &val);
++              if ((val & TEMPSENSE0_POWER_DOWN) == 0)
++                      return -ETIMEDOUT;
++      }
++
++      return 0;
++}
++
++static int imx_thermal_resume(struct device *dev)
++{
++      /* Nothing to do for now */
++      return 0;
++}
++#endif
++
++static SIMPLE_DEV_PM_OPS(imx_thermal_pm_ops,
++                       imx_thermal_suspend, imx_thermal_resume);
++
++static const struct of_device_id of_imx_thermal_match[] = {
++      { .compatible = "fsl,imx6q-tempmon", },
++      { /* end */ }
++};
++
++static struct platform_driver imx_thermal = {
++      .driver = {
++              .name   = "imx_thermal",
++              .owner  = THIS_MODULE,
++              .pm     = &imx_thermal_pm_ops,
++              .of_match_table = of_imx_thermal_match,
++      },
++      .probe          = imx_thermal_probe,
++      .remove         = imx_thermal_remove,
++};
++module_platform_driver(imx_thermal);
++
++MODULE_AUTHOR("Freescale Semiconductor, Inc.");
++MODULE_DESCRIPTION("Thermal driver for Freescale i.MX SoCs");
++MODULE_LICENSE("GPL v2");
++MODULE_ALIAS("platform:imx-thermal");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0951-thermal-exynos-Moving-exynos-thermal-files-into-sams.patch b/patches.tizen/0951-thermal-exynos-Moving-exynos-thermal-files-into-sams.patch
new file mode 100644 (file)
index 0000000..1a80a77
--- /dev/null
@@ -0,0 +1,2230 @@
+From 985b3f16f3264b16ecfcfdca52e0a89f1a605809 Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Fri, 1 Nov 2013 15:45:25 +0900
+Subject: [PATCH 0951/1302] thermal: exynos: Moving exynos thermal files into
+ samsung directory
+
+This movement of files is done for easy maintenance and adding more
+new sensor's support for exynos platform easily . This will also help in
+bifurcating exynos common, sensor driver and sensor data related parts.
+
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/Kconfig                  |   14 +-
+ drivers/thermal/Makefile                 |    2 +-
+ drivers/thermal/exynos_thermal.c         | 1059 ------------------------------
+ drivers/thermal/samsung/Kconfig          |    9 +
+ drivers/thermal/samsung/Makefile         |    4 +
+ drivers/thermal/samsung/exynos_thermal.c | 1059 ++++++++++++++++++++++++++++++
+ 6 files changed, 1079 insertions(+), 1068 deletions(-)
+ delete mode 100644 drivers/thermal/exynos_thermal.c
+ create mode 100644 drivers/thermal/samsung/Kconfig
+ create mode 100644 drivers/thermal/samsung/Makefile
+ create mode 100644 drivers/thermal/samsung/exynos_thermal.c
+
+diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
+index cb24078..ae18f02 100644
+--- a/drivers/thermal/Kconfig
++++ b/drivers/thermal/Kconfig
+@@ -125,14 +125,6 @@ config KIRKWOOD_THERMAL
+         Support for the Kirkwood thermal sensor driver into the Linux thermal
+         framework. Only kirkwood 88F6282 and 88F6283 have this sensor.
+-config EXYNOS_THERMAL
+-      tristate "Temperature sensor on Samsung EXYNOS"
+-      depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5)
+-      depends on CPU_THERMAL
+-      help
+-        If you say yes here you get support for TMU (Thermal Management
+-        Unit) on SAMSUNG EXYNOS series of SoC.
+-
+ config DOVE_THERMAL
+       tristate "Temperature sensor on Marvell Dove SoCs"
+       depends on ARCH_DOVE
+@@ -194,4 +186,10 @@ config X86_PKG_TEMP_THERMAL
+ menu "Texas Instruments thermal drivers"
+ source "drivers/thermal/ti-soc-thermal/Kconfig"
+ endmenu
++
++menu "Samsung thermal drivers"
++depends on PLAT_SAMSUNG
++source "drivers/thermal/samsung/Kconfig"
++endmenu
++
+ endif
+diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
+index dff19c6..c19df7a 100644
+--- a/drivers/thermal/Makefile
++++ b/drivers/thermal/Makefile
+@@ -17,7 +17,7 @@ thermal_sys-$(CONFIG_CPU_THERMAL)    += cpu_cooling.o
+ obj-$(CONFIG_SPEAR_THERMAL)   += spear_thermal.o
+ obj-$(CONFIG_RCAR_THERMAL)    += rcar_thermal.o
+ obj-$(CONFIG_KIRKWOOD_THERMAL)  += kirkwood_thermal.o
+-obj-$(CONFIG_EXYNOS_THERMAL)  += exynos_thermal.o
++obj-y                         += samsung/
+ obj-$(CONFIG_DOVE_THERMAL)    += dove_thermal.o
+ obj-$(CONFIG_DB8500_THERMAL)  += db8500_thermal.o
+ obj-$(CONFIG_ARMADA_THERMAL)  += armada_thermal.o
+diff --git a/drivers/thermal/exynos_thermal.c b/drivers/thermal/exynos_thermal.c
+deleted file mode 100644
+index 9af4b93..0000000
+--- a/drivers/thermal/exynos_thermal.c
++++ /dev/null
+@@ -1,1059 +0,0 @@
+-/*
+- * exynos_thermal.c - Samsung EXYNOS TMU (Thermal Management Unit)
+- *
+- *  Copyright (C) 2011 Samsung Electronics
+- *  Donggeun Kim <dg77.kim@samsung.com>
+- *  Amit Daniel Kachhap <amit.kachhap@linaro.org>
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+- *
+- */
+-
+-#include <linux/module.h>
+-#include <linux/err.h>
+-#include <linux/kernel.h>
+-#include <linux/slab.h>
+-#include <linux/platform_device.h>
+-#include <linux/interrupt.h>
+-#include <linux/clk.h>
+-#include <linux/workqueue.h>
+-#include <linux/sysfs.h>
+-#include <linux/kobject.h>
+-#include <linux/io.h>
+-#include <linux/mutex.h>
+-#include <linux/platform_data/exynos_thermal.h>
+-#include <linux/thermal.h>
+-#include <linux/cpufreq.h>
+-#include <linux/cpu_cooling.h>
+-#include <linux/of.h>
+-
+-/* Exynos generic registers */
+-#define EXYNOS_TMU_REG_TRIMINFO               0x0
+-#define EXYNOS_TMU_REG_CONTROL                0x20
+-#define EXYNOS_TMU_REG_STATUS         0x28
+-#define EXYNOS_TMU_REG_CURRENT_TEMP   0x40
+-#define EXYNOS_TMU_REG_INTEN          0x70
+-#define EXYNOS_TMU_REG_INTSTAT                0x74
+-#define EXYNOS_TMU_REG_INTCLEAR               0x78
+-
+-#define EXYNOS_TMU_TRIM_TEMP_MASK     0xff
+-#define EXYNOS_TMU_GAIN_SHIFT         8
+-#define EXYNOS_TMU_REF_VOLTAGE_SHIFT  24
+-#define EXYNOS_TMU_CORE_ON            3
+-#define EXYNOS_TMU_CORE_OFF           2
+-#define EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET    50
+-
+-/* Exynos4210 specific registers */
+-#define EXYNOS4210_TMU_REG_THRESHOLD_TEMP     0x44
+-#define EXYNOS4210_TMU_REG_TRIG_LEVEL0        0x50
+-#define EXYNOS4210_TMU_REG_TRIG_LEVEL1        0x54
+-#define EXYNOS4210_TMU_REG_TRIG_LEVEL2        0x58
+-#define EXYNOS4210_TMU_REG_TRIG_LEVEL3        0x5C
+-#define EXYNOS4210_TMU_REG_PAST_TEMP0 0x60
+-#define EXYNOS4210_TMU_REG_PAST_TEMP1 0x64
+-#define EXYNOS4210_TMU_REG_PAST_TEMP2 0x68
+-#define EXYNOS4210_TMU_REG_PAST_TEMP3 0x6C
+-
+-#define EXYNOS4210_TMU_TRIG_LEVEL0_MASK       0x1
+-#define EXYNOS4210_TMU_TRIG_LEVEL1_MASK       0x10
+-#define EXYNOS4210_TMU_TRIG_LEVEL2_MASK       0x100
+-#define EXYNOS4210_TMU_TRIG_LEVEL3_MASK       0x1000
+-#define EXYNOS4210_TMU_INTCLEAR_VAL   0x1111
+-
+-/* Exynos5250 and Exynos4412 specific registers */
+-#define EXYNOS_TMU_TRIMINFO_CON       0x14
+-#define EXYNOS_THD_TEMP_RISE          0x50
+-#define EXYNOS_THD_TEMP_FALL          0x54
+-#define EXYNOS_EMUL_CON               0x80
+-
+-#define EXYNOS_TRIMINFO_RELOAD                0x1
+-#define EXYNOS_TMU_CLEAR_RISE_INT     0x111
+-#define EXYNOS_TMU_CLEAR_FALL_INT     (0x111 << 12)
+-#define EXYNOS_MUX_ADDR_VALUE         6
+-#define EXYNOS_MUX_ADDR_SHIFT         20
+-#define EXYNOS_TMU_TRIP_MODE_SHIFT    13
+-
+-#define EFUSE_MIN_VALUE 40
+-#define EFUSE_MAX_VALUE 100
+-
+-/* In-kernel thermal framework related macros & definations */
+-#define SENSOR_NAME_LEN       16
+-#define MAX_TRIP_COUNT        8
+-#define MAX_COOLING_DEVICE 4
+-#define MAX_THRESHOLD_LEVS 4
+-
+-#define ACTIVE_INTERVAL 500
+-#define IDLE_INTERVAL 10000
+-#define MCELSIUS      1000
+-
+-#ifdef CONFIG_THERMAL_EMULATION
+-#define EXYNOS_EMUL_TIME      0x57F0
+-#define EXYNOS_EMUL_TIME_SHIFT        16
+-#define EXYNOS_EMUL_DATA_SHIFT        8
+-#define EXYNOS_EMUL_DATA_MASK 0xFF
+-#define EXYNOS_EMUL_ENABLE    0x1
+-#endif /* CONFIG_THERMAL_EMULATION */
+-
+-/* CPU Zone information */
+-#define PANIC_ZONE      4
+-#define WARN_ZONE       3
+-#define MONITOR_ZONE    2
+-#define SAFE_ZONE       1
+-
+-#define GET_ZONE(trip) (trip + 2)
+-#define GET_TRIP(zone) (zone - 2)
+-
+-#define EXYNOS_ZONE_COUNT     3
+-
+-struct exynos_tmu_data {
+-      struct exynos_tmu_platform_data *pdata;
+-      struct resource *mem;
+-      void __iomem *base;
+-      int irq;
+-      enum soc_type soc;
+-      struct work_struct irq_work;
+-      struct mutex lock;
+-      struct clk *clk;
+-      u8 temp_error1, temp_error2;
+-};
+-
+-struct        thermal_trip_point_conf {
+-      int trip_val[MAX_TRIP_COUNT];
+-      int trip_count;
+-      u8 trigger_falling;
+-};
+-
+-struct        thermal_cooling_conf {
+-      struct freq_clip_table freq_data[MAX_TRIP_COUNT];
+-      int freq_clip_count;
+-};
+-
+-struct thermal_sensor_conf {
+-      char name[SENSOR_NAME_LEN];
+-      int (*read_temperature)(void *data);
+-      int (*write_emul_temp)(void *drv_data, unsigned long temp);
+-      struct thermal_trip_point_conf trip_data;
+-      struct thermal_cooling_conf cooling_data;
+-      void *private_data;
+-};
+-
+-struct exynos_thermal_zone {
+-      enum thermal_device_mode mode;
+-      struct thermal_zone_device *therm_dev;
+-      struct thermal_cooling_device *cool_dev[MAX_COOLING_DEVICE];
+-      unsigned int cool_dev_size;
+-      struct platform_device *exynos4_dev;
+-      struct thermal_sensor_conf *sensor_conf;
+-      bool bind;
+-};
+-
+-static struct exynos_thermal_zone *th_zone;
+-static void exynos_unregister_thermal(void);
+-static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf);
+-
+-/* Get mode callback functions for thermal zone */
+-static int exynos_get_mode(struct thermal_zone_device *thermal,
+-                      enum thermal_device_mode *mode)
+-{
+-      if (th_zone)
+-              *mode = th_zone->mode;
+-      return 0;
+-}
+-
+-/* Set mode callback functions for thermal zone */
+-static int exynos_set_mode(struct thermal_zone_device *thermal,
+-                      enum thermal_device_mode mode)
+-{
+-      if (!th_zone->therm_dev) {
+-              pr_notice("thermal zone not registered\n");
+-              return 0;
+-      }
+-
+-      mutex_lock(&th_zone->therm_dev->lock);
+-
+-      if (mode == THERMAL_DEVICE_ENABLED &&
+-              !th_zone->sensor_conf->trip_data.trigger_falling)
+-              th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
+-      else
+-              th_zone->therm_dev->polling_delay = 0;
+-
+-      mutex_unlock(&th_zone->therm_dev->lock);
+-
+-      th_zone->mode = mode;
+-      thermal_zone_device_update(th_zone->therm_dev);
+-      pr_info("thermal polling set for duration=%d msec\n",
+-                              th_zone->therm_dev->polling_delay);
+-      return 0;
+-}
+-
+-
+-/* Get trip type callback functions for thermal zone */
+-static int exynos_get_trip_type(struct thermal_zone_device *thermal, int trip,
+-                               enum thermal_trip_type *type)
+-{
+-      switch (GET_ZONE(trip)) {
+-      case MONITOR_ZONE:
+-      case WARN_ZONE:
+-              *type = THERMAL_TRIP_ACTIVE;
+-              break;
+-      case PANIC_ZONE:
+-              *type = THERMAL_TRIP_CRITICAL;
+-              break;
+-      default:
+-              return -EINVAL;
+-      }
+-      return 0;
+-}
+-
+-/* Get trip temperature callback functions for thermal zone */
+-static int exynos_get_trip_temp(struct thermal_zone_device *thermal, int trip,
+-                              unsigned long *temp)
+-{
+-      if (trip < GET_TRIP(MONITOR_ZONE) || trip > GET_TRIP(PANIC_ZONE))
+-              return -EINVAL;
+-
+-      *temp = th_zone->sensor_conf->trip_data.trip_val[trip];
+-      /* convert the temperature into millicelsius */
+-      *temp = *temp * MCELSIUS;
+-
+-      return 0;
+-}
+-
+-/* Get critical temperature callback functions for thermal zone */
+-static int exynos_get_crit_temp(struct thermal_zone_device *thermal,
+-                              unsigned long *temp)
+-{
+-      int ret;
+-      /* Panic zone */
+-      ret = exynos_get_trip_temp(thermal, GET_TRIP(PANIC_ZONE), temp);
+-      return ret;
+-}
+-
+-/* Bind callback functions for thermal zone */
+-static int exynos_bind(struct thermal_zone_device *thermal,
+-                      struct thermal_cooling_device *cdev)
+-{
+-      int ret = 0, i, tab_size, level;
+-      struct freq_clip_table *tab_ptr, *clip_data;
+-      struct thermal_sensor_conf *data = th_zone->sensor_conf;
+-
+-      tab_ptr = (struct freq_clip_table *)data->cooling_data.freq_data;
+-      tab_size = data->cooling_data.freq_clip_count;
+-
+-      if (tab_ptr == NULL || tab_size == 0)
+-              return -EINVAL;
+-
+-      /* find the cooling device registered*/
+-      for (i = 0; i < th_zone->cool_dev_size; i++)
+-              if (cdev == th_zone->cool_dev[i])
+-                      break;
+-
+-      /* No matching cooling device */
+-      if (i == th_zone->cool_dev_size)
+-              return 0;
+-
+-      /* Bind the thermal zone to the cpufreq cooling device */
+-      for (i = 0; i < tab_size; i++) {
+-              clip_data = (struct freq_clip_table *)&(tab_ptr[i]);
+-              level = cpufreq_cooling_get_level(0, clip_data->freq_clip_max);
+-              if (level == THERMAL_CSTATE_INVALID)
+-                      return 0;
+-              switch (GET_ZONE(i)) {
+-              case MONITOR_ZONE:
+-              case WARN_ZONE:
+-                      if (thermal_zone_bind_cooling_device(thermal, i, cdev,
+-                                                              level, 0)) {
+-                              pr_err("error binding cdev inst %d\n", i);
+-                              ret = -EINVAL;
+-                      }
+-                      th_zone->bind = true;
+-                      break;
+-              default:
+-                      ret = -EINVAL;
+-              }
+-      }
+-
+-      return ret;
+-}
+-
+-/* Unbind callback functions for thermal zone */
+-static int exynos_unbind(struct thermal_zone_device *thermal,
+-                      struct thermal_cooling_device *cdev)
+-{
+-      int ret = 0, i, tab_size;
+-      struct thermal_sensor_conf *data = th_zone->sensor_conf;
+-
+-      if (th_zone->bind == false)
+-              return 0;
+-
+-      tab_size = data->cooling_data.freq_clip_count;
+-
+-      if (tab_size == 0)
+-              return -EINVAL;
+-
+-      /* find the cooling device registered*/
+-      for (i = 0; i < th_zone->cool_dev_size; i++)
+-              if (cdev == th_zone->cool_dev[i])
+-                      break;
+-
+-      /* No matching cooling device */
+-      if (i == th_zone->cool_dev_size)
+-              return 0;
+-
+-      /* Bind the thermal zone to the cpufreq cooling device */
+-      for (i = 0; i < tab_size; i++) {
+-              switch (GET_ZONE(i)) {
+-              case MONITOR_ZONE:
+-              case WARN_ZONE:
+-                      if (thermal_zone_unbind_cooling_device(thermal, i,
+-                                                              cdev)) {
+-                              pr_err("error unbinding cdev inst=%d\n", i);
+-                              ret = -EINVAL;
+-                      }
+-                      th_zone->bind = false;
+-                      break;
+-              default:
+-                      ret = -EINVAL;
+-              }
+-      }
+-      return ret;
+-}
+-
+-/* Get temperature callback functions for thermal zone */
+-static int exynos_get_temp(struct thermal_zone_device *thermal,
+-                      unsigned long *temp)
+-{
+-      void *data;
+-
+-      if (!th_zone->sensor_conf) {
+-              pr_info("Temperature sensor not initialised\n");
+-              return -EINVAL;
+-      }
+-      data = th_zone->sensor_conf->private_data;
+-      *temp = th_zone->sensor_conf->read_temperature(data);
+-      /* convert the temperature into millicelsius */
+-      *temp = *temp * MCELSIUS;
+-      return 0;
+-}
+-
+-/* Get temperature callback functions for thermal zone */
+-static int exynos_set_emul_temp(struct thermal_zone_device *thermal,
+-                                              unsigned long temp)
+-{
+-      void *data;
+-      int ret = -EINVAL;
+-
+-      if (!th_zone->sensor_conf) {
+-              pr_info("Temperature sensor not initialised\n");
+-              return -EINVAL;
+-      }
+-      data = th_zone->sensor_conf->private_data;
+-      if (th_zone->sensor_conf->write_emul_temp)
+-              ret = th_zone->sensor_conf->write_emul_temp(data, temp);
+-      return ret;
+-}
+-
+-/* Get the temperature trend */
+-static int exynos_get_trend(struct thermal_zone_device *thermal,
+-                      int trip, enum thermal_trend *trend)
+-{
+-      int ret;
+-      unsigned long trip_temp;
+-
+-      ret = exynos_get_trip_temp(thermal, trip, &trip_temp);
+-      if (ret < 0)
+-              return ret;
+-
+-      if (thermal->temperature >= trip_temp)
+-              *trend = THERMAL_TREND_RAISE_FULL;
+-      else
+-              *trend = THERMAL_TREND_DROP_FULL;
+-
+-      return 0;
+-}
+-/* Operation callback functions for thermal zone */
+-static struct thermal_zone_device_ops const exynos_dev_ops = {
+-      .bind = exynos_bind,
+-      .unbind = exynos_unbind,
+-      .get_temp = exynos_get_temp,
+-      .set_emul_temp = exynos_set_emul_temp,
+-      .get_trend = exynos_get_trend,
+-      .get_mode = exynos_get_mode,
+-      .set_mode = exynos_set_mode,
+-      .get_trip_type = exynos_get_trip_type,
+-      .get_trip_temp = exynos_get_trip_temp,
+-      .get_crit_temp = exynos_get_crit_temp,
+-};
+-
+-/*
+- * This function may be called from interrupt based temperature sensor
+- * when threshold is changed.
+- */
+-static void exynos_report_trigger(void)
+-{
+-      unsigned int i;
+-      char data[10];
+-      char *envp[] = { data, NULL };
+-
+-      if (!th_zone || !th_zone->therm_dev)
+-              return;
+-      if (th_zone->bind == false) {
+-              for (i = 0; i < th_zone->cool_dev_size; i++) {
+-                      if (!th_zone->cool_dev[i])
+-                              continue;
+-                      exynos_bind(th_zone->therm_dev,
+-                                      th_zone->cool_dev[i]);
+-              }
+-      }
+-
+-      thermal_zone_device_update(th_zone->therm_dev);
+-
+-      mutex_lock(&th_zone->therm_dev->lock);
+-      /* Find the level for which trip happened */
+-      for (i = 0; i < th_zone->sensor_conf->trip_data.trip_count; i++) {
+-              if (th_zone->therm_dev->last_temperature <
+-                      th_zone->sensor_conf->trip_data.trip_val[i] * MCELSIUS)
+-                      break;
+-      }
+-
+-      if (th_zone->mode == THERMAL_DEVICE_ENABLED &&
+-              !th_zone->sensor_conf->trip_data.trigger_falling) {
+-              if (i > 0)
+-                      th_zone->therm_dev->polling_delay = ACTIVE_INTERVAL;
+-              else
+-                      th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
+-      }
+-
+-      snprintf(data, sizeof(data), "%u", i);
+-      kobject_uevent_env(&th_zone->therm_dev->device.kobj, KOBJ_CHANGE, envp);
+-      mutex_unlock(&th_zone->therm_dev->lock);
+-}
+-
+-/* Register with the in-kernel thermal management */
+-static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
+-{
+-      int ret;
+-      struct cpumask mask_val;
+-
+-      if (!sensor_conf || !sensor_conf->read_temperature) {
+-              pr_err("Temperature sensor not initialised\n");
+-              return -EINVAL;
+-      }
+-
+-      th_zone = kzalloc(sizeof(struct exynos_thermal_zone), GFP_KERNEL);
+-      if (!th_zone)
+-              return -ENOMEM;
+-
+-      th_zone->sensor_conf = sensor_conf;
+-      cpumask_set_cpu(0, &mask_val);
+-      th_zone->cool_dev[0] = cpufreq_cooling_register(&mask_val);
+-      if (IS_ERR(th_zone->cool_dev[0])) {
+-              pr_err("Failed to register cpufreq cooling device\n");
+-              ret = -EINVAL;
+-              goto err_unregister;
+-      }
+-      th_zone->cool_dev_size++;
+-
+-      th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name,
+-                      EXYNOS_ZONE_COUNT, 0, NULL, &exynos_dev_ops, NULL, 0,
+-                      sensor_conf->trip_data.trigger_falling ?
+-                      0 : IDLE_INTERVAL);
+-
+-      if (IS_ERR(th_zone->therm_dev)) {
+-              pr_err("Failed to register thermal zone device\n");
+-              ret = PTR_ERR(th_zone->therm_dev);
+-              goto err_unregister;
+-      }
+-      th_zone->mode = THERMAL_DEVICE_ENABLED;
+-
+-      pr_info("Exynos: Kernel Thermal management registered\n");
+-
+-      return 0;
+-
+-err_unregister:
+-      exynos_unregister_thermal();
+-      return ret;
+-}
+-
+-/* Un-Register with the in-kernel thermal management */
+-static void exynos_unregister_thermal(void)
+-{
+-      int i;
+-
+-      if (!th_zone)
+-              return;
+-
+-      if (th_zone->therm_dev)
+-              thermal_zone_device_unregister(th_zone->therm_dev);
+-
+-      for (i = 0; i < th_zone->cool_dev_size; i++) {
+-              if (th_zone->cool_dev[i])
+-                      cpufreq_cooling_unregister(th_zone->cool_dev[i]);
+-      }
+-
+-      kfree(th_zone);
+-      pr_info("Exynos: Kernel Thermal management unregistered\n");
+-}
+-
+-/*
+- * TMU treats temperature as a mapped temperature code.
+- * The temperature is converted differently depending on the calibration type.
+- */
+-static int temp_to_code(struct exynos_tmu_data *data, u8 temp)
+-{
+-      struct exynos_tmu_platform_data *pdata = data->pdata;
+-      int temp_code;
+-
+-      if (data->soc == SOC_ARCH_EXYNOS4210)
+-              /* temp should range between 25 and 125 */
+-              if (temp < 25 || temp > 125) {
+-                      temp_code = -EINVAL;
+-                      goto out;
+-              }
+-
+-      switch (pdata->cal_type) {
+-      case TYPE_TWO_POINT_TRIMMING:
+-              temp_code = (temp - 25) *
+-                  (data->temp_error2 - data->temp_error1) /
+-                  (85 - 25) + data->temp_error1;
+-              break;
+-      case TYPE_ONE_POINT_TRIMMING:
+-              temp_code = temp + data->temp_error1 - 25;
+-              break;
+-      default:
+-              temp_code = temp + EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET;
+-              break;
+-      }
+-out:
+-      return temp_code;
+-}
+-
+-/*
+- * Calculate a temperature value from a temperature code.
+- * The unit of the temperature is degree Celsius.
+- */
+-static int code_to_temp(struct exynos_tmu_data *data, u8 temp_code)
+-{
+-      struct exynos_tmu_platform_data *pdata = data->pdata;
+-      int temp;
+-
+-      if (data->soc == SOC_ARCH_EXYNOS4210)
+-              /* temp_code should range between 75 and 175 */
+-              if (temp_code < 75 || temp_code > 175) {
+-                      temp = -ENODATA;
+-                      goto out;
+-              }
+-
+-      switch (pdata->cal_type) {
+-      case TYPE_TWO_POINT_TRIMMING:
+-              temp = (temp_code - data->temp_error1) * (85 - 25) /
+-                  (data->temp_error2 - data->temp_error1) + 25;
+-              break;
+-      case TYPE_ONE_POINT_TRIMMING:
+-              temp = temp_code - data->temp_error1 + 25;
+-              break;
+-      default:
+-              temp = temp_code - EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET;
+-              break;
+-      }
+-out:
+-      return temp;
+-}
+-
+-static int exynos_tmu_initialize(struct platform_device *pdev)
+-{
+-      struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+-      struct exynos_tmu_platform_data *pdata = data->pdata;
+-      unsigned int status, trim_info;
+-      unsigned int rising_threshold = 0, falling_threshold = 0;
+-      int ret = 0, threshold_code, i, trigger_levs = 0;
+-
+-      mutex_lock(&data->lock);
+-      clk_enable(data->clk);
+-
+-      status = readb(data->base + EXYNOS_TMU_REG_STATUS);
+-      if (!status) {
+-              ret = -EBUSY;
+-              goto out;
+-      }
+-
+-      if (data->soc == SOC_ARCH_EXYNOS) {
+-              __raw_writel(EXYNOS_TRIMINFO_RELOAD,
+-                              data->base + EXYNOS_TMU_TRIMINFO_CON);
+-      }
+-      /* Save trimming info in order to perform calibration */
+-      trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
+-      data->temp_error1 = trim_info & EXYNOS_TMU_TRIM_TEMP_MASK;
+-      data->temp_error2 = ((trim_info >> 8) & EXYNOS_TMU_TRIM_TEMP_MASK);
+-
+-      if ((EFUSE_MIN_VALUE > data->temp_error1) ||
+-                      (data->temp_error1 > EFUSE_MAX_VALUE) ||
+-                      (data->temp_error2 != 0))
+-              data->temp_error1 = pdata->efuse_value;
+-
+-      /* Count trigger levels to be enabled */
+-      for (i = 0; i < MAX_THRESHOLD_LEVS; i++)
+-              if (pdata->trigger_levels[i])
+-                      trigger_levs++;
+-
+-      if (data->soc == SOC_ARCH_EXYNOS4210) {
+-              /* Write temperature code for threshold */
+-              threshold_code = temp_to_code(data, pdata->threshold);
+-              if (threshold_code < 0) {
+-                      ret = threshold_code;
+-                      goto out;
+-              }
+-              writeb(threshold_code,
+-                      data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP);
+-              for (i = 0; i < trigger_levs; i++)
+-                      writeb(pdata->trigger_levels[i],
+-                      data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + i * 4);
+-
+-              writel(EXYNOS4210_TMU_INTCLEAR_VAL,
+-                      data->base + EXYNOS_TMU_REG_INTCLEAR);
+-      } else if (data->soc == SOC_ARCH_EXYNOS) {
+-              /* Write temperature code for rising and falling threshold */
+-              for (i = 0; i < trigger_levs; i++) {
+-                      threshold_code = temp_to_code(data,
+-                                              pdata->trigger_levels[i]);
+-                      if (threshold_code < 0) {
+-                              ret = threshold_code;
+-                              goto out;
+-                      }
+-                      rising_threshold |= threshold_code << 8 * i;
+-                      if (pdata->threshold_falling) {
+-                              threshold_code = temp_to_code(data,
+-                                              pdata->trigger_levels[i] -
+-                                              pdata->threshold_falling);
+-                              if (threshold_code > 0)
+-                                      falling_threshold |=
+-                                              threshold_code << 8 * i;
+-                      }
+-              }
+-
+-              writel(rising_threshold,
+-                              data->base + EXYNOS_THD_TEMP_RISE);
+-              writel(falling_threshold,
+-                              data->base + EXYNOS_THD_TEMP_FALL);
+-
+-              writel(EXYNOS_TMU_CLEAR_RISE_INT | EXYNOS_TMU_CLEAR_FALL_INT,
+-                              data->base + EXYNOS_TMU_REG_INTCLEAR);
+-      }
+-out:
+-      clk_disable(data->clk);
+-      mutex_unlock(&data->lock);
+-
+-      return ret;
+-}
+-
+-static void exynos_tmu_control(struct platform_device *pdev, bool on)
+-{
+-      struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+-      struct exynos_tmu_platform_data *pdata = data->pdata;
+-      unsigned int con, interrupt_en;
+-
+-      mutex_lock(&data->lock);
+-      clk_enable(data->clk);
+-
+-      con = pdata->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT |
+-              pdata->gain << EXYNOS_TMU_GAIN_SHIFT;
+-
+-      if (data->soc == SOC_ARCH_EXYNOS) {
+-              con |= pdata->noise_cancel_mode << EXYNOS_TMU_TRIP_MODE_SHIFT;
+-              con |= (EXYNOS_MUX_ADDR_VALUE << EXYNOS_MUX_ADDR_SHIFT);
+-      }
+-
+-      if (on) {
+-              con |= EXYNOS_TMU_CORE_ON;
+-              interrupt_en = pdata->trigger_level3_en << 12 |
+-                      pdata->trigger_level2_en << 8 |
+-                      pdata->trigger_level1_en << 4 |
+-                      pdata->trigger_level0_en;
+-              if (pdata->threshold_falling)
+-                      interrupt_en |= interrupt_en << 16;
+-      } else {
+-              con |= EXYNOS_TMU_CORE_OFF;
+-              interrupt_en = 0; /* Disable all interrupts */
+-      }
+-      writel(interrupt_en, data->base + EXYNOS_TMU_REG_INTEN);
+-      writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
+-
+-      clk_disable(data->clk);
+-      mutex_unlock(&data->lock);
+-}
+-
+-static int exynos_tmu_read(struct exynos_tmu_data *data)
+-{
+-      u8 temp_code;
+-      int temp;
+-
+-      mutex_lock(&data->lock);
+-      clk_enable(data->clk);
+-
+-      temp_code = readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP);
+-      temp = code_to_temp(data, temp_code);
+-
+-      clk_disable(data->clk);
+-      mutex_unlock(&data->lock);
+-
+-      return temp;
+-}
+-
+-#ifdef CONFIG_THERMAL_EMULATION
+-static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp)
+-{
+-      struct exynos_tmu_data *data = drv_data;
+-      unsigned int reg;
+-      int ret = -EINVAL;
+-
+-      if (data->soc == SOC_ARCH_EXYNOS4210)
+-              goto out;
+-
+-      if (temp && temp < MCELSIUS)
+-              goto out;
+-
+-      mutex_lock(&data->lock);
+-      clk_enable(data->clk);
+-
+-      reg = readl(data->base + EXYNOS_EMUL_CON);
+-
+-      if (temp) {
+-              temp /= MCELSIUS;
+-
+-              reg = (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT) |
+-                      (temp_to_code(data, temp)
+-                       << EXYNOS_EMUL_DATA_SHIFT) | EXYNOS_EMUL_ENABLE;
+-      } else {
+-              reg &= ~EXYNOS_EMUL_ENABLE;
+-      }
+-
+-      writel(reg, data->base + EXYNOS_EMUL_CON);
+-
+-      clk_disable(data->clk);
+-      mutex_unlock(&data->lock);
+-      return 0;
+-out:
+-      return ret;
+-}
+-#else
+-static int exynos_tmu_set_emulation(void *drv_data,   unsigned long temp)
+-      { return -EINVAL; }
+-#endif/*CONFIG_THERMAL_EMULATION*/
+-
+-static void exynos_tmu_work(struct work_struct *work)
+-{
+-      struct exynos_tmu_data *data = container_of(work,
+-                      struct exynos_tmu_data, irq_work);
+-
+-      exynos_report_trigger();
+-      mutex_lock(&data->lock);
+-      clk_enable(data->clk);
+-      if (data->soc == SOC_ARCH_EXYNOS)
+-              writel(EXYNOS_TMU_CLEAR_RISE_INT |
+-                              EXYNOS_TMU_CLEAR_FALL_INT,
+-                              data->base + EXYNOS_TMU_REG_INTCLEAR);
+-      else
+-              writel(EXYNOS4210_TMU_INTCLEAR_VAL,
+-                              data->base + EXYNOS_TMU_REG_INTCLEAR);
+-      clk_disable(data->clk);
+-      mutex_unlock(&data->lock);
+-
+-      enable_irq(data->irq);
+-}
+-
+-static irqreturn_t exynos_tmu_irq(int irq, void *id)
+-{
+-      struct exynos_tmu_data *data = id;
+-
+-      disable_irq_nosync(irq);
+-      schedule_work(&data->irq_work);
+-
+-      return IRQ_HANDLED;
+-}
+-static struct thermal_sensor_conf exynos_sensor_conf = {
+-      .name                   = "exynos-therm",
+-      .read_temperature       = (int (*)(void *))exynos_tmu_read,
+-      .write_emul_temp        = exynos_tmu_set_emulation,
+-};
+-
+-#if defined(CONFIG_CPU_EXYNOS4210)
+-static struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
+-      .threshold = 80,
+-      .trigger_levels[0] = 5,
+-      .trigger_levels[1] = 20,
+-      .trigger_levels[2] = 30,
+-      .trigger_level0_en = 1,
+-      .trigger_level1_en = 1,
+-      .trigger_level2_en = 1,
+-      .trigger_level3_en = 0,
+-      .gain = 15,
+-      .reference_voltage = 7,
+-      .cal_type = TYPE_ONE_POINT_TRIMMING,
+-      .freq_tab[0] = {
+-              .freq_clip_max = 800 * 1000,
+-              .temp_level = 85,
+-      },
+-      .freq_tab[1] = {
+-              .freq_clip_max = 200 * 1000,
+-              .temp_level = 100,
+-      },
+-      .freq_tab_count = 2,
+-      .type = SOC_ARCH_EXYNOS4210,
+-};
+-#define EXYNOS4210_TMU_DRV_DATA (&exynos4210_default_tmu_data)
+-#else
+-#define EXYNOS4210_TMU_DRV_DATA (NULL)
+-#endif
+-
+-#if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412) || \
+-      defined(CONFIG_SOC_EXYNOS4212)
+-static struct exynos_tmu_platform_data const exynos_default_tmu_data = {
+-      .threshold_falling = 10,
+-      .trigger_levels[0] = 85,
+-      .trigger_levels[1] = 103,
+-      .trigger_levels[2] = 110,
+-      .trigger_level0_en = 1,
+-      .trigger_level1_en = 1,
+-      .trigger_level2_en = 1,
+-      .trigger_level3_en = 0,
+-      .gain = 8,
+-      .reference_voltage = 16,
+-      .noise_cancel_mode = 4,
+-      .cal_type = TYPE_ONE_POINT_TRIMMING,
+-      .efuse_value = 55,
+-      .freq_tab[0] = {
+-              .freq_clip_max = 800 * 1000,
+-              .temp_level = 85,
+-      },
+-      .freq_tab[1] = {
+-              .freq_clip_max = 200 * 1000,
+-              .temp_level = 103,
+-      },
+-      .freq_tab_count = 2,
+-      .type = SOC_ARCH_EXYNOS,
+-};
+-#define EXYNOS_TMU_DRV_DATA (&exynos_default_tmu_data)
+-#else
+-#define EXYNOS_TMU_DRV_DATA (NULL)
+-#endif
+-
+-#ifdef CONFIG_OF
+-static const struct of_device_id exynos_tmu_match[] = {
+-      {
+-              .compatible = "samsung,exynos4210-tmu",
+-              .data = (void *)EXYNOS4210_TMU_DRV_DATA,
+-      },
+-      {
+-              .compatible = "samsung,exynos4412-tmu",
+-              .data = (void *)EXYNOS_TMU_DRV_DATA,
+-      },
+-      {
+-              .compatible = "samsung,exynos5250-tmu",
+-              .data = (void *)EXYNOS_TMU_DRV_DATA,
+-      },
+-      {},
+-};
+-MODULE_DEVICE_TABLE(of, exynos_tmu_match);
+-#endif
+-
+-static struct platform_device_id exynos_tmu_driver_ids[] = {
+-      {
+-              .name           = "exynos4210-tmu",
+-              .driver_data    = (kernel_ulong_t)EXYNOS4210_TMU_DRV_DATA,
+-      },
+-      {
+-              .name           = "exynos5250-tmu",
+-              .driver_data    = (kernel_ulong_t)EXYNOS_TMU_DRV_DATA,
+-      },
+-      { },
+-};
+-MODULE_DEVICE_TABLE(platform, exynos_tmu_driver_ids);
+-
+-static inline struct  exynos_tmu_platform_data *exynos_get_driver_data(
+-                      struct platform_device *pdev)
+-{
+-#ifdef CONFIG_OF
+-      if (pdev->dev.of_node) {
+-              const struct of_device_id *match;
+-              match = of_match_node(exynos_tmu_match, pdev->dev.of_node);
+-              if (!match)
+-                      return NULL;
+-              return (struct exynos_tmu_platform_data *) match->data;
+-      }
+-#endif
+-      return (struct exynos_tmu_platform_data *)
+-                      platform_get_device_id(pdev)->driver_data;
+-}
+-
+-static int exynos_tmu_probe(struct platform_device *pdev)
+-{
+-      struct exynos_tmu_data *data;
+-      struct exynos_tmu_platform_data *pdata = pdev->dev.platform_data;
+-      int ret, i;
+-
+-      if (!pdata)
+-              pdata = exynos_get_driver_data(pdev);
+-
+-      if (!pdata) {
+-              dev_err(&pdev->dev, "No platform init data supplied.\n");
+-              return -ENODEV;
+-      }
+-      data = devm_kzalloc(&pdev->dev, sizeof(struct exynos_tmu_data),
+-                                      GFP_KERNEL);
+-      if (!data) {
+-              dev_err(&pdev->dev, "Failed to allocate driver structure\n");
+-              return -ENOMEM;
+-      }
+-
+-      data->irq = platform_get_irq(pdev, 0);
+-      if (data->irq < 0) {
+-              dev_err(&pdev->dev, "Failed to get platform irq\n");
+-              return data->irq;
+-      }
+-
+-      INIT_WORK(&data->irq_work, exynos_tmu_work);
+-
+-      data->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-      data->base = devm_ioremap_resource(&pdev->dev, data->mem);
+-      if (IS_ERR(data->base))
+-              return PTR_ERR(data->base);
+-
+-      ret = devm_request_irq(&pdev->dev, data->irq, exynos_tmu_irq,
+-              IRQF_TRIGGER_RISING, "exynos-tmu", data);
+-      if (ret) {
+-              dev_err(&pdev->dev, "Failed to request irq: %d\n", data->irq);
+-              return ret;
+-      }
+-
+-      data->clk = devm_clk_get(&pdev->dev, "tmu_apbif");
+-      if (IS_ERR(data->clk)) {
+-              dev_err(&pdev->dev, "Failed to get clock\n");
+-              return  PTR_ERR(data->clk);
+-      }
+-
+-      ret = clk_prepare(data->clk);
+-      if (ret)
+-              return ret;
+-
+-      if (pdata->type == SOC_ARCH_EXYNOS ||
+-                              pdata->type == SOC_ARCH_EXYNOS4210)
+-              data->soc = pdata->type;
+-      else {
+-              ret = -EINVAL;
+-              dev_err(&pdev->dev, "Platform not supported\n");
+-              goto err_clk;
+-      }
+-
+-      data->pdata = pdata;
+-      platform_set_drvdata(pdev, data);
+-      mutex_init(&data->lock);
+-
+-      ret = exynos_tmu_initialize(pdev);
+-      if (ret) {
+-              dev_err(&pdev->dev, "Failed to initialize TMU\n");
+-              goto err_clk;
+-      }
+-
+-      exynos_tmu_control(pdev, true);
+-
+-      /* Register the sensor with thermal management interface */
+-      (&exynos_sensor_conf)->private_data = data;
+-      exynos_sensor_conf.trip_data.trip_count = pdata->trigger_level0_en +
+-                      pdata->trigger_level1_en + pdata->trigger_level2_en +
+-                      pdata->trigger_level3_en;
+-
+-      for (i = 0; i < exynos_sensor_conf.trip_data.trip_count; i++)
+-              exynos_sensor_conf.trip_data.trip_val[i] =
+-                      pdata->threshold + pdata->trigger_levels[i];
+-
+-      exynos_sensor_conf.trip_data.trigger_falling = pdata->threshold_falling;
+-
+-      exynos_sensor_conf.cooling_data.freq_clip_count =
+-                                              pdata->freq_tab_count;
+-      for (i = 0; i < pdata->freq_tab_count; i++) {
+-              exynos_sensor_conf.cooling_data.freq_data[i].freq_clip_max =
+-                                      pdata->freq_tab[i].freq_clip_max;
+-              exynos_sensor_conf.cooling_data.freq_data[i].temp_level =
+-                                      pdata->freq_tab[i].temp_level;
+-      }
+-
+-      ret = exynos_register_thermal(&exynos_sensor_conf);
+-      if (ret) {
+-              dev_err(&pdev->dev, "Failed to register thermal interface\n");
+-              goto err_clk;
+-      }
+-
+-      return 0;
+-err_clk:
+-      clk_unprepare(data->clk);
+-      return ret;
+-}
+-
+-static int exynos_tmu_remove(struct platform_device *pdev)
+-{
+-      struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+-
+-      exynos_tmu_control(pdev, false);
+-
+-      exynos_unregister_thermal();
+-
+-      clk_unprepare(data->clk);
+-
+-      return 0;
+-}
+-
+-#ifdef CONFIG_PM_SLEEP
+-static int exynos_tmu_suspend(struct device *dev)
+-{
+-      exynos_tmu_control(to_platform_device(dev), false);
+-
+-      return 0;
+-}
+-
+-static int exynos_tmu_resume(struct device *dev)
+-{
+-      struct platform_device *pdev = to_platform_device(dev);
+-
+-      exynos_tmu_initialize(pdev);
+-      exynos_tmu_control(pdev, true);
+-
+-      return 0;
+-}
+-
+-static SIMPLE_DEV_PM_OPS(exynos_tmu_pm,
+-                       exynos_tmu_suspend, exynos_tmu_resume);
+-#define EXYNOS_TMU_PM (&exynos_tmu_pm)
+-#else
+-#define EXYNOS_TMU_PM NULL
+-#endif
+-
+-static struct platform_driver exynos_tmu_driver = {
+-      .driver = {
+-              .name   = "exynos-tmu",
+-              .owner  = THIS_MODULE,
+-              .pm     = EXYNOS_TMU_PM,
+-              .of_match_table = of_match_ptr(exynos_tmu_match),
+-      },
+-      .probe = exynos_tmu_probe,
+-      .remove = exynos_tmu_remove,
+-      .id_table = exynos_tmu_driver_ids,
+-};
+-
+-module_platform_driver(exynos_tmu_driver);
+-
+-MODULE_DESCRIPTION("EXYNOS TMU Driver");
+-MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
+-MODULE_LICENSE("GPL");
+-MODULE_ALIAS("platform:exynos-tmu");
+diff --git a/drivers/thermal/samsung/Kconfig b/drivers/thermal/samsung/Kconfig
+new file mode 100644
+index 0000000..2d3d9dc
+--- /dev/null
++++ b/drivers/thermal/samsung/Kconfig
+@@ -0,0 +1,9 @@
++config EXYNOS_THERMAL
++      tristate "Temperature sensor on Samsung EXYNOS"
++      depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5)
++      depends on CPU_THERMAL
++      help
++        If you say yes here you get support for TMU (Thermal Management
++        Unit) on SAMSUNG EXYNOS series of SoC. This helps in registering
++        the exynos thermal driver with the core thermal layer and cpu
++        cooling API's.
+diff --git a/drivers/thermal/samsung/Makefile b/drivers/thermal/samsung/Makefile
+new file mode 100644
+index 0000000..1fe6d93
+--- /dev/null
++++ b/drivers/thermal/samsung/Makefile
+@@ -0,0 +1,4 @@
++#
++# Samsung thermal specific Makefile
++#
++obj-$(CONFIG_EXYNOS_THERMAL)  += exynos_thermal.o
+diff --git a/drivers/thermal/samsung/exynos_thermal.c b/drivers/thermal/samsung/exynos_thermal.c
+new file mode 100644
+index 0000000..9af4b93
+--- /dev/null
++++ b/drivers/thermal/samsung/exynos_thermal.c
+@@ -0,0 +1,1059 @@
++/*
++ * exynos_thermal.c - Samsung EXYNOS TMU (Thermal Management Unit)
++ *
++ *  Copyright (C) 2011 Samsung Electronics
++ *  Donggeun Kim <dg77.kim@samsung.com>
++ *  Amit Daniel Kachhap <amit.kachhap@linaro.org>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/err.h>
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/platform_device.h>
++#include <linux/interrupt.h>
++#include <linux/clk.h>
++#include <linux/workqueue.h>
++#include <linux/sysfs.h>
++#include <linux/kobject.h>
++#include <linux/io.h>
++#include <linux/mutex.h>
++#include <linux/platform_data/exynos_thermal.h>
++#include <linux/thermal.h>
++#include <linux/cpufreq.h>
++#include <linux/cpu_cooling.h>
++#include <linux/of.h>
++
++/* Exynos generic registers */
++#define EXYNOS_TMU_REG_TRIMINFO               0x0
++#define EXYNOS_TMU_REG_CONTROL                0x20
++#define EXYNOS_TMU_REG_STATUS         0x28
++#define EXYNOS_TMU_REG_CURRENT_TEMP   0x40
++#define EXYNOS_TMU_REG_INTEN          0x70
++#define EXYNOS_TMU_REG_INTSTAT                0x74
++#define EXYNOS_TMU_REG_INTCLEAR               0x78
++
++#define EXYNOS_TMU_TRIM_TEMP_MASK     0xff
++#define EXYNOS_TMU_GAIN_SHIFT         8
++#define EXYNOS_TMU_REF_VOLTAGE_SHIFT  24
++#define EXYNOS_TMU_CORE_ON            3
++#define EXYNOS_TMU_CORE_OFF           2
++#define EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET    50
++
++/* Exynos4210 specific registers */
++#define EXYNOS4210_TMU_REG_THRESHOLD_TEMP     0x44
++#define EXYNOS4210_TMU_REG_TRIG_LEVEL0        0x50
++#define EXYNOS4210_TMU_REG_TRIG_LEVEL1        0x54
++#define EXYNOS4210_TMU_REG_TRIG_LEVEL2        0x58
++#define EXYNOS4210_TMU_REG_TRIG_LEVEL3        0x5C
++#define EXYNOS4210_TMU_REG_PAST_TEMP0 0x60
++#define EXYNOS4210_TMU_REG_PAST_TEMP1 0x64
++#define EXYNOS4210_TMU_REG_PAST_TEMP2 0x68
++#define EXYNOS4210_TMU_REG_PAST_TEMP3 0x6C
++
++#define EXYNOS4210_TMU_TRIG_LEVEL0_MASK       0x1
++#define EXYNOS4210_TMU_TRIG_LEVEL1_MASK       0x10
++#define EXYNOS4210_TMU_TRIG_LEVEL2_MASK       0x100
++#define EXYNOS4210_TMU_TRIG_LEVEL3_MASK       0x1000
++#define EXYNOS4210_TMU_INTCLEAR_VAL   0x1111
++
++/* Exynos5250 and Exynos4412 specific registers */
++#define EXYNOS_TMU_TRIMINFO_CON       0x14
++#define EXYNOS_THD_TEMP_RISE          0x50
++#define EXYNOS_THD_TEMP_FALL          0x54
++#define EXYNOS_EMUL_CON               0x80
++
++#define EXYNOS_TRIMINFO_RELOAD                0x1
++#define EXYNOS_TMU_CLEAR_RISE_INT     0x111
++#define EXYNOS_TMU_CLEAR_FALL_INT     (0x111 << 12)
++#define EXYNOS_MUX_ADDR_VALUE         6
++#define EXYNOS_MUX_ADDR_SHIFT         20
++#define EXYNOS_TMU_TRIP_MODE_SHIFT    13
++
++#define EFUSE_MIN_VALUE 40
++#define EFUSE_MAX_VALUE 100
++
++/* In-kernel thermal framework related macros & definations */
++#define SENSOR_NAME_LEN       16
++#define MAX_TRIP_COUNT        8
++#define MAX_COOLING_DEVICE 4
++#define MAX_THRESHOLD_LEVS 4
++
++#define ACTIVE_INTERVAL 500
++#define IDLE_INTERVAL 10000
++#define MCELSIUS      1000
++
++#ifdef CONFIG_THERMAL_EMULATION
++#define EXYNOS_EMUL_TIME      0x57F0
++#define EXYNOS_EMUL_TIME_SHIFT        16
++#define EXYNOS_EMUL_DATA_SHIFT        8
++#define EXYNOS_EMUL_DATA_MASK 0xFF
++#define EXYNOS_EMUL_ENABLE    0x1
++#endif /* CONFIG_THERMAL_EMULATION */
++
++/* CPU Zone information */
++#define PANIC_ZONE      4
++#define WARN_ZONE       3
++#define MONITOR_ZONE    2
++#define SAFE_ZONE       1
++
++#define GET_ZONE(trip) (trip + 2)
++#define GET_TRIP(zone) (zone - 2)
++
++#define EXYNOS_ZONE_COUNT     3
++
++struct exynos_tmu_data {
++      struct exynos_tmu_platform_data *pdata;
++      struct resource *mem;
++      void __iomem *base;
++      int irq;
++      enum soc_type soc;
++      struct work_struct irq_work;
++      struct mutex lock;
++      struct clk *clk;
++      u8 temp_error1, temp_error2;
++};
++
++struct        thermal_trip_point_conf {
++      int trip_val[MAX_TRIP_COUNT];
++      int trip_count;
++      u8 trigger_falling;
++};
++
++struct        thermal_cooling_conf {
++      struct freq_clip_table freq_data[MAX_TRIP_COUNT];
++      int freq_clip_count;
++};
++
++struct thermal_sensor_conf {
++      char name[SENSOR_NAME_LEN];
++      int (*read_temperature)(void *data);
++      int (*write_emul_temp)(void *drv_data, unsigned long temp);
++      struct thermal_trip_point_conf trip_data;
++      struct thermal_cooling_conf cooling_data;
++      void *private_data;
++};
++
++struct exynos_thermal_zone {
++      enum thermal_device_mode mode;
++      struct thermal_zone_device *therm_dev;
++      struct thermal_cooling_device *cool_dev[MAX_COOLING_DEVICE];
++      unsigned int cool_dev_size;
++      struct platform_device *exynos4_dev;
++      struct thermal_sensor_conf *sensor_conf;
++      bool bind;
++};
++
++static struct exynos_thermal_zone *th_zone;
++static void exynos_unregister_thermal(void);
++static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf);
++
++/* Get mode callback functions for thermal zone */
++static int exynos_get_mode(struct thermal_zone_device *thermal,
++                      enum thermal_device_mode *mode)
++{
++      if (th_zone)
++              *mode = th_zone->mode;
++      return 0;
++}
++
++/* Set mode callback functions for thermal zone */
++static int exynos_set_mode(struct thermal_zone_device *thermal,
++                      enum thermal_device_mode mode)
++{
++      if (!th_zone->therm_dev) {
++              pr_notice("thermal zone not registered\n");
++              return 0;
++      }
++
++      mutex_lock(&th_zone->therm_dev->lock);
++
++      if (mode == THERMAL_DEVICE_ENABLED &&
++              !th_zone->sensor_conf->trip_data.trigger_falling)
++              th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
++      else
++              th_zone->therm_dev->polling_delay = 0;
++
++      mutex_unlock(&th_zone->therm_dev->lock);
++
++      th_zone->mode = mode;
++      thermal_zone_device_update(th_zone->therm_dev);
++      pr_info("thermal polling set for duration=%d msec\n",
++                              th_zone->therm_dev->polling_delay);
++      return 0;
++}
++
++
++/* Get trip type callback functions for thermal zone */
++static int exynos_get_trip_type(struct thermal_zone_device *thermal, int trip,
++                               enum thermal_trip_type *type)
++{
++      switch (GET_ZONE(trip)) {
++      case MONITOR_ZONE:
++      case WARN_ZONE:
++              *type = THERMAL_TRIP_ACTIVE;
++              break;
++      case PANIC_ZONE:
++              *type = THERMAL_TRIP_CRITICAL;
++              break;
++      default:
++              return -EINVAL;
++      }
++      return 0;
++}
++
++/* Get trip temperature callback functions for thermal zone */
++static int exynos_get_trip_temp(struct thermal_zone_device *thermal, int trip,
++                              unsigned long *temp)
++{
++      if (trip < GET_TRIP(MONITOR_ZONE) || trip > GET_TRIP(PANIC_ZONE))
++              return -EINVAL;
++
++      *temp = th_zone->sensor_conf->trip_data.trip_val[trip];
++      /* convert the temperature into millicelsius */
++      *temp = *temp * MCELSIUS;
++
++      return 0;
++}
++
++/* Get critical temperature callback functions for thermal zone */
++static int exynos_get_crit_temp(struct thermal_zone_device *thermal,
++                              unsigned long *temp)
++{
++      int ret;
++      /* Panic zone */
++      ret = exynos_get_trip_temp(thermal, GET_TRIP(PANIC_ZONE), temp);
++      return ret;
++}
++
++/* Bind callback functions for thermal zone */
++static int exynos_bind(struct thermal_zone_device *thermal,
++                      struct thermal_cooling_device *cdev)
++{
++      int ret = 0, i, tab_size, level;
++      struct freq_clip_table *tab_ptr, *clip_data;
++      struct thermal_sensor_conf *data = th_zone->sensor_conf;
++
++      tab_ptr = (struct freq_clip_table *)data->cooling_data.freq_data;
++      tab_size = data->cooling_data.freq_clip_count;
++
++      if (tab_ptr == NULL || tab_size == 0)
++              return -EINVAL;
++
++      /* find the cooling device registered*/
++      for (i = 0; i < th_zone->cool_dev_size; i++)
++              if (cdev == th_zone->cool_dev[i])
++                      break;
++
++      /* No matching cooling device */
++      if (i == th_zone->cool_dev_size)
++              return 0;
++
++      /* Bind the thermal zone to the cpufreq cooling device */
++      for (i = 0; i < tab_size; i++) {
++              clip_data = (struct freq_clip_table *)&(tab_ptr[i]);
++              level = cpufreq_cooling_get_level(0, clip_data->freq_clip_max);
++              if (level == THERMAL_CSTATE_INVALID)
++                      return 0;
++              switch (GET_ZONE(i)) {
++              case MONITOR_ZONE:
++              case WARN_ZONE:
++                      if (thermal_zone_bind_cooling_device(thermal, i, cdev,
++                                                              level, 0)) {
++                              pr_err("error binding cdev inst %d\n", i);
++                              ret = -EINVAL;
++                      }
++                      th_zone->bind = true;
++                      break;
++              default:
++                      ret = -EINVAL;
++              }
++      }
++
++      return ret;
++}
++
++/* Unbind callback functions for thermal zone */
++static int exynos_unbind(struct thermal_zone_device *thermal,
++                      struct thermal_cooling_device *cdev)
++{
++      int ret = 0, i, tab_size;
++      struct thermal_sensor_conf *data = th_zone->sensor_conf;
++
++      if (th_zone->bind == false)
++              return 0;
++
++      tab_size = data->cooling_data.freq_clip_count;
++
++      if (tab_size == 0)
++              return -EINVAL;
++
++      /* find the cooling device registered*/
++      for (i = 0; i < th_zone->cool_dev_size; i++)
++              if (cdev == th_zone->cool_dev[i])
++                      break;
++
++      /* No matching cooling device */
++      if (i == th_zone->cool_dev_size)
++              return 0;
++
++      /* Bind the thermal zone to the cpufreq cooling device */
++      for (i = 0; i < tab_size; i++) {
++              switch (GET_ZONE(i)) {
++              case MONITOR_ZONE:
++              case WARN_ZONE:
++                      if (thermal_zone_unbind_cooling_device(thermal, i,
++                                                              cdev)) {
++                              pr_err("error unbinding cdev inst=%d\n", i);
++                              ret = -EINVAL;
++                      }
++                      th_zone->bind = false;
++                      break;
++              default:
++                      ret = -EINVAL;
++              }
++      }
++      return ret;
++}
++
++/* Get temperature callback functions for thermal zone */
++static int exynos_get_temp(struct thermal_zone_device *thermal,
++                      unsigned long *temp)
++{
++      void *data;
++
++      if (!th_zone->sensor_conf) {
++              pr_info("Temperature sensor not initialised\n");
++              return -EINVAL;
++      }
++      data = th_zone->sensor_conf->private_data;
++      *temp = th_zone->sensor_conf->read_temperature(data);
++      /* convert the temperature into millicelsius */
++      *temp = *temp * MCELSIUS;
++      return 0;
++}
++
++/* Get temperature callback functions for thermal zone */
++static int exynos_set_emul_temp(struct thermal_zone_device *thermal,
++                                              unsigned long temp)
++{
++      void *data;
++      int ret = -EINVAL;
++
++      if (!th_zone->sensor_conf) {
++              pr_info("Temperature sensor not initialised\n");
++              return -EINVAL;
++      }
++      data = th_zone->sensor_conf->private_data;
++      if (th_zone->sensor_conf->write_emul_temp)
++              ret = th_zone->sensor_conf->write_emul_temp(data, temp);
++      return ret;
++}
++
++/* Get the temperature trend */
++static int exynos_get_trend(struct thermal_zone_device *thermal,
++                      int trip, enum thermal_trend *trend)
++{
++      int ret;
++      unsigned long trip_temp;
++
++      ret = exynos_get_trip_temp(thermal, trip, &trip_temp);
++      if (ret < 0)
++              return ret;
++
++      if (thermal->temperature >= trip_temp)
++              *trend = THERMAL_TREND_RAISE_FULL;
++      else
++              *trend = THERMAL_TREND_DROP_FULL;
++
++      return 0;
++}
++/* Operation callback functions for thermal zone */
++static struct thermal_zone_device_ops const exynos_dev_ops = {
++      .bind = exynos_bind,
++      .unbind = exynos_unbind,
++      .get_temp = exynos_get_temp,
++      .set_emul_temp = exynos_set_emul_temp,
++      .get_trend = exynos_get_trend,
++      .get_mode = exynos_get_mode,
++      .set_mode = exynos_set_mode,
++      .get_trip_type = exynos_get_trip_type,
++      .get_trip_temp = exynos_get_trip_temp,
++      .get_crit_temp = exynos_get_crit_temp,
++};
++
++/*
++ * This function may be called from interrupt based temperature sensor
++ * when threshold is changed.
++ */
++static void exynos_report_trigger(void)
++{
++      unsigned int i;
++      char data[10];
++      char *envp[] = { data, NULL };
++
++      if (!th_zone || !th_zone->therm_dev)
++              return;
++      if (th_zone->bind == false) {
++              for (i = 0; i < th_zone->cool_dev_size; i++) {
++                      if (!th_zone->cool_dev[i])
++                              continue;
++                      exynos_bind(th_zone->therm_dev,
++                                      th_zone->cool_dev[i]);
++              }
++      }
++
++      thermal_zone_device_update(th_zone->therm_dev);
++
++      mutex_lock(&th_zone->therm_dev->lock);
++      /* Find the level for which trip happened */
++      for (i = 0; i < th_zone->sensor_conf->trip_data.trip_count; i++) {
++              if (th_zone->therm_dev->last_temperature <
++                      th_zone->sensor_conf->trip_data.trip_val[i] * MCELSIUS)
++                      break;
++      }
++
++      if (th_zone->mode == THERMAL_DEVICE_ENABLED &&
++              !th_zone->sensor_conf->trip_data.trigger_falling) {
++              if (i > 0)
++                      th_zone->therm_dev->polling_delay = ACTIVE_INTERVAL;
++              else
++                      th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
++      }
++
++      snprintf(data, sizeof(data), "%u", i);
++      kobject_uevent_env(&th_zone->therm_dev->device.kobj, KOBJ_CHANGE, envp);
++      mutex_unlock(&th_zone->therm_dev->lock);
++}
++
++/* Register with the in-kernel thermal management */
++static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
++{
++      int ret;
++      struct cpumask mask_val;
++
++      if (!sensor_conf || !sensor_conf->read_temperature) {
++              pr_err("Temperature sensor not initialised\n");
++              return -EINVAL;
++      }
++
++      th_zone = kzalloc(sizeof(struct exynos_thermal_zone), GFP_KERNEL);
++      if (!th_zone)
++              return -ENOMEM;
++
++      th_zone->sensor_conf = sensor_conf;
++      cpumask_set_cpu(0, &mask_val);
++      th_zone->cool_dev[0] = cpufreq_cooling_register(&mask_val);
++      if (IS_ERR(th_zone->cool_dev[0])) {
++              pr_err("Failed to register cpufreq cooling device\n");
++              ret = -EINVAL;
++              goto err_unregister;
++      }
++      th_zone->cool_dev_size++;
++
++      th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name,
++                      EXYNOS_ZONE_COUNT, 0, NULL, &exynos_dev_ops, NULL, 0,
++                      sensor_conf->trip_data.trigger_falling ?
++                      0 : IDLE_INTERVAL);
++
++      if (IS_ERR(th_zone->therm_dev)) {
++              pr_err("Failed to register thermal zone device\n");
++              ret = PTR_ERR(th_zone->therm_dev);
++              goto err_unregister;
++      }
++      th_zone->mode = THERMAL_DEVICE_ENABLED;
++
++      pr_info("Exynos: Kernel Thermal management registered\n");
++
++      return 0;
++
++err_unregister:
++      exynos_unregister_thermal();
++      return ret;
++}
++
++/* Un-Register with the in-kernel thermal management */
++static void exynos_unregister_thermal(void)
++{
++      int i;
++
++      if (!th_zone)
++              return;
++
++      if (th_zone->therm_dev)
++              thermal_zone_device_unregister(th_zone->therm_dev);
++
++      for (i = 0; i < th_zone->cool_dev_size; i++) {
++              if (th_zone->cool_dev[i])
++                      cpufreq_cooling_unregister(th_zone->cool_dev[i]);
++      }
++
++      kfree(th_zone);
++      pr_info("Exynos: Kernel Thermal management unregistered\n");
++}
++
++/*
++ * TMU treats temperature as a mapped temperature code.
++ * The temperature is converted differently depending on the calibration type.
++ */
++static int temp_to_code(struct exynos_tmu_data *data, u8 temp)
++{
++      struct exynos_tmu_platform_data *pdata = data->pdata;
++      int temp_code;
++
++      if (data->soc == SOC_ARCH_EXYNOS4210)
++              /* temp should range between 25 and 125 */
++              if (temp < 25 || temp > 125) {
++                      temp_code = -EINVAL;
++                      goto out;
++              }
++
++      switch (pdata->cal_type) {
++      case TYPE_TWO_POINT_TRIMMING:
++              temp_code = (temp - 25) *
++                  (data->temp_error2 - data->temp_error1) /
++                  (85 - 25) + data->temp_error1;
++              break;
++      case TYPE_ONE_POINT_TRIMMING:
++              temp_code = temp + data->temp_error1 - 25;
++              break;
++      default:
++              temp_code = temp + EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET;
++              break;
++      }
++out:
++      return temp_code;
++}
++
++/*
++ * Calculate a temperature value from a temperature code.
++ * The unit of the temperature is degree Celsius.
++ */
++static int code_to_temp(struct exynos_tmu_data *data, u8 temp_code)
++{
++      struct exynos_tmu_platform_data *pdata = data->pdata;
++      int temp;
++
++      if (data->soc == SOC_ARCH_EXYNOS4210)
++              /* temp_code should range between 75 and 175 */
++              if (temp_code < 75 || temp_code > 175) {
++                      temp = -ENODATA;
++                      goto out;
++              }
++
++      switch (pdata->cal_type) {
++      case TYPE_TWO_POINT_TRIMMING:
++              temp = (temp_code - data->temp_error1) * (85 - 25) /
++                  (data->temp_error2 - data->temp_error1) + 25;
++              break;
++      case TYPE_ONE_POINT_TRIMMING:
++              temp = temp_code - data->temp_error1 + 25;
++              break;
++      default:
++              temp = temp_code - EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET;
++              break;
++      }
++out:
++      return temp;
++}
++
++static int exynos_tmu_initialize(struct platform_device *pdev)
++{
++      struct exynos_tmu_data *data = platform_get_drvdata(pdev);
++      struct exynos_tmu_platform_data *pdata = data->pdata;
++      unsigned int status, trim_info;
++      unsigned int rising_threshold = 0, falling_threshold = 0;
++      int ret = 0, threshold_code, i, trigger_levs = 0;
++
++      mutex_lock(&data->lock);
++      clk_enable(data->clk);
++
++      status = readb(data->base + EXYNOS_TMU_REG_STATUS);
++      if (!status) {
++              ret = -EBUSY;
++              goto out;
++      }
++
++      if (data->soc == SOC_ARCH_EXYNOS) {
++              __raw_writel(EXYNOS_TRIMINFO_RELOAD,
++                              data->base + EXYNOS_TMU_TRIMINFO_CON);
++      }
++      /* Save trimming info in order to perform calibration */
++      trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
++      data->temp_error1 = trim_info & EXYNOS_TMU_TRIM_TEMP_MASK;
++      data->temp_error2 = ((trim_info >> 8) & EXYNOS_TMU_TRIM_TEMP_MASK);
++
++      if ((EFUSE_MIN_VALUE > data->temp_error1) ||
++                      (data->temp_error1 > EFUSE_MAX_VALUE) ||
++                      (data->temp_error2 != 0))
++              data->temp_error1 = pdata->efuse_value;
++
++      /* Count trigger levels to be enabled */
++      for (i = 0; i < MAX_THRESHOLD_LEVS; i++)
++              if (pdata->trigger_levels[i])
++                      trigger_levs++;
++
++      if (data->soc == SOC_ARCH_EXYNOS4210) {
++              /* Write temperature code for threshold */
++              threshold_code = temp_to_code(data, pdata->threshold);
++              if (threshold_code < 0) {
++                      ret = threshold_code;
++                      goto out;
++              }
++              writeb(threshold_code,
++                      data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP);
++              for (i = 0; i < trigger_levs; i++)
++                      writeb(pdata->trigger_levels[i],
++                      data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + i * 4);
++
++              writel(EXYNOS4210_TMU_INTCLEAR_VAL,
++                      data->base + EXYNOS_TMU_REG_INTCLEAR);
++      } else if (data->soc == SOC_ARCH_EXYNOS) {
++              /* Write temperature code for rising and falling threshold */
++              for (i = 0; i < trigger_levs; i++) {
++                      threshold_code = temp_to_code(data,
++                                              pdata->trigger_levels[i]);
++                      if (threshold_code < 0) {
++                              ret = threshold_code;
++                              goto out;
++                      }
++                      rising_threshold |= threshold_code << 8 * i;
++                      if (pdata->threshold_falling) {
++                              threshold_code = temp_to_code(data,
++                                              pdata->trigger_levels[i] -
++                                              pdata->threshold_falling);
++                              if (threshold_code > 0)
++                                      falling_threshold |=
++                                              threshold_code << 8 * i;
++                      }
++              }
++
++              writel(rising_threshold,
++                              data->base + EXYNOS_THD_TEMP_RISE);
++              writel(falling_threshold,
++                              data->base + EXYNOS_THD_TEMP_FALL);
++
++              writel(EXYNOS_TMU_CLEAR_RISE_INT | EXYNOS_TMU_CLEAR_FALL_INT,
++                              data->base + EXYNOS_TMU_REG_INTCLEAR);
++      }
++out:
++      clk_disable(data->clk);
++      mutex_unlock(&data->lock);
++
++      return ret;
++}
++
++static void exynos_tmu_control(struct platform_device *pdev, bool on)
++{
++      struct exynos_tmu_data *data = platform_get_drvdata(pdev);
++      struct exynos_tmu_platform_data *pdata = data->pdata;
++      unsigned int con, interrupt_en;
++
++      mutex_lock(&data->lock);
++      clk_enable(data->clk);
++
++      con = pdata->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT |
++              pdata->gain << EXYNOS_TMU_GAIN_SHIFT;
++
++      if (data->soc == SOC_ARCH_EXYNOS) {
++              con |= pdata->noise_cancel_mode << EXYNOS_TMU_TRIP_MODE_SHIFT;
++              con |= (EXYNOS_MUX_ADDR_VALUE << EXYNOS_MUX_ADDR_SHIFT);
++      }
++
++      if (on) {
++              con |= EXYNOS_TMU_CORE_ON;
++              interrupt_en = pdata->trigger_level3_en << 12 |
++                      pdata->trigger_level2_en << 8 |
++                      pdata->trigger_level1_en << 4 |
++                      pdata->trigger_level0_en;
++              if (pdata->threshold_falling)
++                      interrupt_en |= interrupt_en << 16;
++      } else {
++              con |= EXYNOS_TMU_CORE_OFF;
++              interrupt_en = 0; /* Disable all interrupts */
++      }
++      writel(interrupt_en, data->base + EXYNOS_TMU_REG_INTEN);
++      writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
++
++      clk_disable(data->clk);
++      mutex_unlock(&data->lock);
++}
++
++static int exynos_tmu_read(struct exynos_tmu_data *data)
++{
++      u8 temp_code;
++      int temp;
++
++      mutex_lock(&data->lock);
++      clk_enable(data->clk);
++
++      temp_code = readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP);
++      temp = code_to_temp(data, temp_code);
++
++      clk_disable(data->clk);
++      mutex_unlock(&data->lock);
++
++      return temp;
++}
++
++#ifdef CONFIG_THERMAL_EMULATION
++static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp)
++{
++      struct exynos_tmu_data *data = drv_data;
++      unsigned int reg;
++      int ret = -EINVAL;
++
++      if (data->soc == SOC_ARCH_EXYNOS4210)
++              goto out;
++
++      if (temp && temp < MCELSIUS)
++              goto out;
++
++      mutex_lock(&data->lock);
++      clk_enable(data->clk);
++
++      reg = readl(data->base + EXYNOS_EMUL_CON);
++
++      if (temp) {
++              temp /= MCELSIUS;
++
++              reg = (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT) |
++                      (temp_to_code(data, temp)
++                       << EXYNOS_EMUL_DATA_SHIFT) | EXYNOS_EMUL_ENABLE;
++      } else {
++              reg &= ~EXYNOS_EMUL_ENABLE;
++      }
++
++      writel(reg, data->base + EXYNOS_EMUL_CON);
++
++      clk_disable(data->clk);
++      mutex_unlock(&data->lock);
++      return 0;
++out:
++      return ret;
++}
++#else
++static int exynos_tmu_set_emulation(void *drv_data,   unsigned long temp)
++      { return -EINVAL; }
++#endif/*CONFIG_THERMAL_EMULATION*/
++
++static void exynos_tmu_work(struct work_struct *work)
++{
++      struct exynos_tmu_data *data = container_of(work,
++                      struct exynos_tmu_data, irq_work);
++
++      exynos_report_trigger();
++      mutex_lock(&data->lock);
++      clk_enable(data->clk);
++      if (data->soc == SOC_ARCH_EXYNOS)
++              writel(EXYNOS_TMU_CLEAR_RISE_INT |
++                              EXYNOS_TMU_CLEAR_FALL_INT,
++                              data->base + EXYNOS_TMU_REG_INTCLEAR);
++      else
++              writel(EXYNOS4210_TMU_INTCLEAR_VAL,
++                              data->base + EXYNOS_TMU_REG_INTCLEAR);
++      clk_disable(data->clk);
++      mutex_unlock(&data->lock);
++
++      enable_irq(data->irq);
++}
++
++static irqreturn_t exynos_tmu_irq(int irq, void *id)
++{
++      struct exynos_tmu_data *data = id;
++
++      disable_irq_nosync(irq);
++      schedule_work(&data->irq_work);
++
++      return IRQ_HANDLED;
++}
++static struct thermal_sensor_conf exynos_sensor_conf = {
++      .name                   = "exynos-therm",
++      .read_temperature       = (int (*)(void *))exynos_tmu_read,
++      .write_emul_temp        = exynos_tmu_set_emulation,
++};
++
++#if defined(CONFIG_CPU_EXYNOS4210)
++static struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
++      .threshold = 80,
++      .trigger_levels[0] = 5,
++      .trigger_levels[1] = 20,
++      .trigger_levels[2] = 30,
++      .trigger_level0_en = 1,
++      .trigger_level1_en = 1,
++      .trigger_level2_en = 1,
++      .trigger_level3_en = 0,
++      .gain = 15,
++      .reference_voltage = 7,
++      .cal_type = TYPE_ONE_POINT_TRIMMING,
++      .freq_tab[0] = {
++              .freq_clip_max = 800 * 1000,
++              .temp_level = 85,
++      },
++      .freq_tab[1] = {
++              .freq_clip_max = 200 * 1000,
++              .temp_level = 100,
++      },
++      .freq_tab_count = 2,
++      .type = SOC_ARCH_EXYNOS4210,
++};
++#define EXYNOS4210_TMU_DRV_DATA (&exynos4210_default_tmu_data)
++#else
++#define EXYNOS4210_TMU_DRV_DATA (NULL)
++#endif
++
++#if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412) || \
++      defined(CONFIG_SOC_EXYNOS4212)
++static struct exynos_tmu_platform_data const exynos_default_tmu_data = {
++      .threshold_falling = 10,
++      .trigger_levels[0] = 85,
++      .trigger_levels[1] = 103,
++      .trigger_levels[2] = 110,
++      .trigger_level0_en = 1,
++      .trigger_level1_en = 1,
++      .trigger_level2_en = 1,
++      .trigger_level3_en = 0,
++      .gain = 8,
++      .reference_voltage = 16,
++      .noise_cancel_mode = 4,
++      .cal_type = TYPE_ONE_POINT_TRIMMING,
++      .efuse_value = 55,
++      .freq_tab[0] = {
++              .freq_clip_max = 800 * 1000,
++              .temp_level = 85,
++      },
++      .freq_tab[1] = {
++              .freq_clip_max = 200 * 1000,
++              .temp_level = 103,
++      },
++      .freq_tab_count = 2,
++      .type = SOC_ARCH_EXYNOS,
++};
++#define EXYNOS_TMU_DRV_DATA (&exynos_default_tmu_data)
++#else
++#define EXYNOS_TMU_DRV_DATA (NULL)
++#endif
++
++#ifdef CONFIG_OF
++static const struct of_device_id exynos_tmu_match[] = {
++      {
++              .compatible = "samsung,exynos4210-tmu",
++              .data = (void *)EXYNOS4210_TMU_DRV_DATA,
++      },
++      {
++              .compatible = "samsung,exynos4412-tmu",
++              .data = (void *)EXYNOS_TMU_DRV_DATA,
++      },
++      {
++              .compatible = "samsung,exynos5250-tmu",
++              .data = (void *)EXYNOS_TMU_DRV_DATA,
++      },
++      {},
++};
++MODULE_DEVICE_TABLE(of, exynos_tmu_match);
++#endif
++
++static struct platform_device_id exynos_tmu_driver_ids[] = {
++      {
++              .name           = "exynos4210-tmu",
++              .driver_data    = (kernel_ulong_t)EXYNOS4210_TMU_DRV_DATA,
++      },
++      {
++              .name           = "exynos5250-tmu",
++              .driver_data    = (kernel_ulong_t)EXYNOS_TMU_DRV_DATA,
++      },
++      { },
++};
++MODULE_DEVICE_TABLE(platform, exynos_tmu_driver_ids);
++
++static inline struct  exynos_tmu_platform_data *exynos_get_driver_data(
++                      struct platform_device *pdev)
++{
++#ifdef CONFIG_OF
++      if (pdev->dev.of_node) {
++              const struct of_device_id *match;
++              match = of_match_node(exynos_tmu_match, pdev->dev.of_node);
++              if (!match)
++                      return NULL;
++              return (struct exynos_tmu_platform_data *) match->data;
++      }
++#endif
++      return (struct exynos_tmu_platform_data *)
++                      platform_get_device_id(pdev)->driver_data;
++}
++
++static int exynos_tmu_probe(struct platform_device *pdev)
++{
++      struct exynos_tmu_data *data;
++      struct exynos_tmu_platform_data *pdata = pdev->dev.platform_data;
++      int ret, i;
++
++      if (!pdata)
++              pdata = exynos_get_driver_data(pdev);
++
++      if (!pdata) {
++              dev_err(&pdev->dev, "No platform init data supplied.\n");
++              return -ENODEV;
++      }
++      data = devm_kzalloc(&pdev->dev, sizeof(struct exynos_tmu_data),
++                                      GFP_KERNEL);
++      if (!data) {
++              dev_err(&pdev->dev, "Failed to allocate driver structure\n");
++              return -ENOMEM;
++      }
++
++      data->irq = platform_get_irq(pdev, 0);
++      if (data->irq < 0) {
++              dev_err(&pdev->dev, "Failed to get platform irq\n");
++              return data->irq;
++      }
++
++      INIT_WORK(&data->irq_work, exynos_tmu_work);
++
++      data->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      data->base = devm_ioremap_resource(&pdev->dev, data->mem);
++      if (IS_ERR(data->base))
++              return PTR_ERR(data->base);
++
++      ret = devm_request_irq(&pdev->dev, data->irq, exynos_tmu_irq,
++              IRQF_TRIGGER_RISING, "exynos-tmu", data);
++      if (ret) {
++              dev_err(&pdev->dev, "Failed to request irq: %d\n", data->irq);
++              return ret;
++      }
++
++      data->clk = devm_clk_get(&pdev->dev, "tmu_apbif");
++      if (IS_ERR(data->clk)) {
++              dev_err(&pdev->dev, "Failed to get clock\n");
++              return  PTR_ERR(data->clk);
++      }
++
++      ret = clk_prepare(data->clk);
++      if (ret)
++              return ret;
++
++      if (pdata->type == SOC_ARCH_EXYNOS ||
++                              pdata->type == SOC_ARCH_EXYNOS4210)
++              data->soc = pdata->type;
++      else {
++              ret = -EINVAL;
++              dev_err(&pdev->dev, "Platform not supported\n");
++              goto err_clk;
++      }
++
++      data->pdata = pdata;
++      platform_set_drvdata(pdev, data);
++      mutex_init(&data->lock);
++
++      ret = exynos_tmu_initialize(pdev);
++      if (ret) {
++              dev_err(&pdev->dev, "Failed to initialize TMU\n");
++              goto err_clk;
++      }
++
++      exynos_tmu_control(pdev, true);
++
++      /* Register the sensor with thermal management interface */
++      (&exynos_sensor_conf)->private_data = data;
++      exynos_sensor_conf.trip_data.trip_count = pdata->trigger_level0_en +
++                      pdata->trigger_level1_en + pdata->trigger_level2_en +
++                      pdata->trigger_level3_en;
++
++      for (i = 0; i < exynos_sensor_conf.trip_data.trip_count; i++)
++              exynos_sensor_conf.trip_data.trip_val[i] =
++                      pdata->threshold + pdata->trigger_levels[i];
++
++      exynos_sensor_conf.trip_data.trigger_falling = pdata->threshold_falling;
++
++      exynos_sensor_conf.cooling_data.freq_clip_count =
++                                              pdata->freq_tab_count;
++      for (i = 0; i < pdata->freq_tab_count; i++) {
++              exynos_sensor_conf.cooling_data.freq_data[i].freq_clip_max =
++                                      pdata->freq_tab[i].freq_clip_max;
++              exynos_sensor_conf.cooling_data.freq_data[i].temp_level =
++                                      pdata->freq_tab[i].temp_level;
++      }
++
++      ret = exynos_register_thermal(&exynos_sensor_conf);
++      if (ret) {
++              dev_err(&pdev->dev, "Failed to register thermal interface\n");
++              goto err_clk;
++      }
++
++      return 0;
++err_clk:
++      clk_unprepare(data->clk);
++      return ret;
++}
++
++static int exynos_tmu_remove(struct platform_device *pdev)
++{
++      struct exynos_tmu_data *data = platform_get_drvdata(pdev);
++
++      exynos_tmu_control(pdev, false);
++
++      exynos_unregister_thermal();
++
++      clk_unprepare(data->clk);
++
++      return 0;
++}
++
++#ifdef CONFIG_PM_SLEEP
++static int exynos_tmu_suspend(struct device *dev)
++{
++      exynos_tmu_control(to_platform_device(dev), false);
++
++      return 0;
++}
++
++static int exynos_tmu_resume(struct device *dev)
++{
++      struct platform_device *pdev = to_platform_device(dev);
++
++      exynos_tmu_initialize(pdev);
++      exynos_tmu_control(pdev, true);
++
++      return 0;
++}
++
++static SIMPLE_DEV_PM_OPS(exynos_tmu_pm,
++                       exynos_tmu_suspend, exynos_tmu_resume);
++#define EXYNOS_TMU_PM (&exynos_tmu_pm)
++#else
++#define EXYNOS_TMU_PM NULL
++#endif
++
++static struct platform_driver exynos_tmu_driver = {
++      .driver = {
++              .name   = "exynos-tmu",
++              .owner  = THIS_MODULE,
++              .pm     = EXYNOS_TMU_PM,
++              .of_match_table = of_match_ptr(exynos_tmu_match),
++      },
++      .probe = exynos_tmu_probe,
++      .remove = exynos_tmu_remove,
++      .id_table = exynos_tmu_driver_ids,
++};
++
++module_platform_driver(exynos_tmu_driver);
++
++MODULE_DESCRIPTION("EXYNOS TMU Driver");
++MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:exynos-tmu");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0952-thermal-exynos-Use-ARCH_HAS_BANDGAP-config-to-know-t.patch b/patches.tizen/0952-thermal-exynos-Use-ARCH_HAS_BANDGAP-config-to-know-t.patch
new file mode 100644 (file)
index 0000000..7b7accf
--- /dev/null
@@ -0,0 +1,36 @@
+From 8d56050ad01cbcaad806666ac3bea73565b7c95c Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Mon, 24 Jun 2013 16:20:23 +0530
+Subject: [PATCH 0952/1302] thermal: exynos: Use ARCH_HAS_BANDGAP config to
+ know the supported soc's
+
+This patch uses the recently added config sybmol ARCH_HAS_BANDGAP to enable
+the TMU driver. This will allow adding support for new soc easily as now it
+is the platform responsibility to enable this config symbol for a particular
+soc.
+
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/samsung/Kconfig b/drivers/thermal/samsung/Kconfig
+index 2d3d9dc..883a8a8 100644
+--- a/drivers/thermal/samsung/Kconfig
++++ b/drivers/thermal/samsung/Kconfig
+@@ -1,6 +1,6 @@
+ config EXYNOS_THERMAL
+       tristate "Temperature sensor on Samsung EXYNOS"
+-      depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5)
++      depends on ARCH_HAS_BANDGAP
+       depends on CPU_THERMAL
+       help
+         If you say yes here you get support for TMU (Thermal Management
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0953-thermal-exynos-Remove-un-necessary-CPU_THERMAL-depen.patch b/patches.tizen/0953-thermal-exynos-Remove-un-necessary-CPU_THERMAL-depen.patch
new file mode 100644 (file)
index 0000000..330cdc4
--- /dev/null
@@ -0,0 +1,35 @@
+From ac23ff274ef217f24674e3cd5aba417a8a13d995 Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Mon, 24 Jun 2013 16:20:24 +0530
+Subject: [PATCH 0953/1302] thermal: exynos: Remove un-necessary CPU_THERMAL
+ dependency
+
+This patch removes the dependency on CPU_THERMAL for compiling TMU driver.
+This is useful for cases when only TMU controller needs to be initialised
+without cpu cooling action.
+
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/Kconfig | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/thermal/samsung/Kconfig b/drivers/thermal/samsung/Kconfig
+index 883a8a8..2cf31ad 100644
+--- a/drivers/thermal/samsung/Kconfig
++++ b/drivers/thermal/samsung/Kconfig
+@@ -1,7 +1,6 @@
+ config EXYNOS_THERMAL
+       tristate "Temperature sensor on Samsung EXYNOS"
+       depends on ARCH_HAS_BANDGAP
+-      depends on CPU_THERMAL
+       help
+         If you say yes here you get support for TMU (Thermal Management
+         Unit) on SAMSUNG EXYNOS series of SoC. This helps in registering
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0954-thermal-exynos-Bifurcate-exynos-thermal-common-and-t.patch b/patches.tizen/0954-thermal-exynos-Bifurcate-exynos-thermal-common-and-t.patch
new file mode 100644 (file)
index 0000000..ad355e1
--- /dev/null
@@ -0,0 +1,1003 @@
+From edfb76bc55440d9a466408f01c6978e79d25845a Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Mon, 24 Jun 2013 16:20:25 +0530
+Subject: [PATCH 0954/1302] thermal: exynos: Bifurcate exynos thermal common
+ and tmu controller code
+
+This code bifurcates exynos thermal implementation into common and sensor
+specific parts. The common thermal code interacts with core thermal layer and
+core cpufreq cooling parts and is independent of SOC specific driver. This
+change is needed to cleanly add support for new TMU sensors.
+
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/Kconfig                 |  19 +-
+ drivers/thermal/samsung/Makefile                |   4 +-
+ drivers/thermal/samsung/exynos_thermal.c        | 419 +-----------------------
+ drivers/thermal/samsung/exynos_thermal_common.c | 385 ++++++++++++++++++++++
+ drivers/thermal/samsung/exynos_thermal_common.h |  83 +++++
+ 5 files changed, 491 insertions(+), 419 deletions(-)
+ create mode 100644 drivers/thermal/samsung/exynos_thermal_common.c
+ create mode 100644 drivers/thermal/samsung/exynos_thermal_common.h
+
+diff --git a/drivers/thermal/samsung/Kconfig b/drivers/thermal/samsung/Kconfig
+index 2cf31ad..f8100b1 100644
+--- a/drivers/thermal/samsung/Kconfig
++++ b/drivers/thermal/samsung/Kconfig
+@@ -1,8 +1,17 @@
+ config EXYNOS_THERMAL
+-      tristate "Temperature sensor on Samsung EXYNOS"
++      tristate "Exynos thermal management unit driver"
+       depends on ARCH_HAS_BANDGAP
+       help
+-        If you say yes here you get support for TMU (Thermal Management
+-        Unit) on SAMSUNG EXYNOS series of SoC. This helps in registering
+-        the exynos thermal driver with the core thermal layer and cpu
+-        cooling API's.
++        If you say yes here you get support for the TMU (Thermal Management
++        Unit) driver for SAMSUNG EXYNOS series of soc. This driver initialises
++        the TMU, reports temperature and handles cooling action if defined.
++        This driver uses the exynos core thermal API's.
++
++config EXYNOS_THERMAL_CORE
++      bool "Core thermal framework support for EXYNOS SOC's"
++      depends on EXYNOS_THERMAL
++      help
++        If you say yes here you get support for EXYNOS TMU
++        (Thermal Management Unit) common registration/unregistration
++        functions to the core thermal layer and also to use the generic
++        cpu cooling API's.
+diff --git a/drivers/thermal/samsung/Makefile b/drivers/thermal/samsung/Makefile
+index 1fe6d93..6227d4f 100644
+--- a/drivers/thermal/samsung/Makefile
++++ b/drivers/thermal/samsung/Makefile
+@@ -1,4 +1,6 @@
+ #
+ # Samsung thermal specific Makefile
+ #
+-obj-$(CONFIG_EXYNOS_THERMAL)  += exynos_thermal.o
++obj-$(CONFIG_EXYNOS_THERMAL)                  += exynos_soc_thermal.o
++exynos_soc_thermal-y                          := exynos_thermal.o
++exynos_soc_thermal-$(CONFIG_EXYNOS_THERMAL_CORE) += exynos_thermal_common.o
+diff --git a/drivers/thermal/samsung/exynos_thermal.c b/drivers/thermal/samsung/exynos_thermal.c
+index 9af4b93..f3500ab 100644
+--- a/drivers/thermal/samsung/exynos_thermal.c
++++ b/drivers/thermal/samsung/exynos_thermal.c
+@@ -21,23 +21,15 @@
+  *
+  */
+-#include <linux/module.h>
+-#include <linux/err.h>
+-#include <linux/kernel.h>
+-#include <linux/slab.h>
+-#include <linux/platform_device.h>
+-#include <linux/interrupt.h>
+ #include <linux/clk.h>
+-#include <linux/workqueue.h>
+-#include <linux/sysfs.h>
+-#include <linux/kobject.h>
+ #include <linux/io.h>
+-#include <linux/mutex.h>
+-#include <linux/platform_data/exynos_thermal.h>
+-#include <linux/thermal.h>
+-#include <linux/cpufreq.h>
+-#include <linux/cpu_cooling.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
+ #include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/platform_data/exynos_thermal.h>
++
++#include "exynos_thermal_common.h"
+ /* Exynos generic registers */
+ #define EXYNOS_TMU_REG_TRIMINFO               0x0
+@@ -88,16 +80,6 @@
+ #define EFUSE_MIN_VALUE 40
+ #define EFUSE_MAX_VALUE 100
+-/* In-kernel thermal framework related macros & definations */
+-#define SENSOR_NAME_LEN       16
+-#define MAX_TRIP_COUNT        8
+-#define MAX_COOLING_DEVICE 4
+-#define MAX_THRESHOLD_LEVS 4
+-
+-#define ACTIVE_INTERVAL 500
+-#define IDLE_INTERVAL 10000
+-#define MCELSIUS      1000
+-
+ #ifdef CONFIG_THERMAL_EMULATION
+ #define EXYNOS_EMUL_TIME      0x57F0
+ #define EXYNOS_EMUL_TIME_SHIFT        16
+@@ -106,17 +88,6 @@
+ #define EXYNOS_EMUL_ENABLE    0x1
+ #endif /* CONFIG_THERMAL_EMULATION */
+-/* CPU Zone information */
+-#define PANIC_ZONE      4
+-#define WARN_ZONE       3
+-#define MONITOR_ZONE    2
+-#define SAFE_ZONE       1
+-
+-#define GET_ZONE(trip) (trip + 2)
+-#define GET_TRIP(zone) (zone - 2)
+-
+-#define EXYNOS_ZONE_COUNT     3
+-
+ struct exynos_tmu_data {
+       struct exynos_tmu_platform_data *pdata;
+       struct resource *mem;
+@@ -129,384 +100,6 @@ struct exynos_tmu_data {
+       u8 temp_error1, temp_error2;
+ };
+-struct        thermal_trip_point_conf {
+-      int trip_val[MAX_TRIP_COUNT];
+-      int trip_count;
+-      u8 trigger_falling;
+-};
+-
+-struct        thermal_cooling_conf {
+-      struct freq_clip_table freq_data[MAX_TRIP_COUNT];
+-      int freq_clip_count;
+-};
+-
+-struct thermal_sensor_conf {
+-      char name[SENSOR_NAME_LEN];
+-      int (*read_temperature)(void *data);
+-      int (*write_emul_temp)(void *drv_data, unsigned long temp);
+-      struct thermal_trip_point_conf trip_data;
+-      struct thermal_cooling_conf cooling_data;
+-      void *private_data;
+-};
+-
+-struct exynos_thermal_zone {
+-      enum thermal_device_mode mode;
+-      struct thermal_zone_device *therm_dev;
+-      struct thermal_cooling_device *cool_dev[MAX_COOLING_DEVICE];
+-      unsigned int cool_dev_size;
+-      struct platform_device *exynos4_dev;
+-      struct thermal_sensor_conf *sensor_conf;
+-      bool bind;
+-};
+-
+-static struct exynos_thermal_zone *th_zone;
+-static void exynos_unregister_thermal(void);
+-static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf);
+-
+-/* Get mode callback functions for thermal zone */
+-static int exynos_get_mode(struct thermal_zone_device *thermal,
+-                      enum thermal_device_mode *mode)
+-{
+-      if (th_zone)
+-              *mode = th_zone->mode;
+-      return 0;
+-}
+-
+-/* Set mode callback functions for thermal zone */
+-static int exynos_set_mode(struct thermal_zone_device *thermal,
+-                      enum thermal_device_mode mode)
+-{
+-      if (!th_zone->therm_dev) {
+-              pr_notice("thermal zone not registered\n");
+-              return 0;
+-      }
+-
+-      mutex_lock(&th_zone->therm_dev->lock);
+-
+-      if (mode == THERMAL_DEVICE_ENABLED &&
+-              !th_zone->sensor_conf->trip_data.trigger_falling)
+-              th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
+-      else
+-              th_zone->therm_dev->polling_delay = 0;
+-
+-      mutex_unlock(&th_zone->therm_dev->lock);
+-
+-      th_zone->mode = mode;
+-      thermal_zone_device_update(th_zone->therm_dev);
+-      pr_info("thermal polling set for duration=%d msec\n",
+-                              th_zone->therm_dev->polling_delay);
+-      return 0;
+-}
+-
+-
+-/* Get trip type callback functions for thermal zone */
+-static int exynos_get_trip_type(struct thermal_zone_device *thermal, int trip,
+-                               enum thermal_trip_type *type)
+-{
+-      switch (GET_ZONE(trip)) {
+-      case MONITOR_ZONE:
+-      case WARN_ZONE:
+-              *type = THERMAL_TRIP_ACTIVE;
+-              break;
+-      case PANIC_ZONE:
+-              *type = THERMAL_TRIP_CRITICAL;
+-              break;
+-      default:
+-              return -EINVAL;
+-      }
+-      return 0;
+-}
+-
+-/* Get trip temperature callback functions for thermal zone */
+-static int exynos_get_trip_temp(struct thermal_zone_device *thermal, int trip,
+-                              unsigned long *temp)
+-{
+-      if (trip < GET_TRIP(MONITOR_ZONE) || trip > GET_TRIP(PANIC_ZONE))
+-              return -EINVAL;
+-
+-      *temp = th_zone->sensor_conf->trip_data.trip_val[trip];
+-      /* convert the temperature into millicelsius */
+-      *temp = *temp * MCELSIUS;
+-
+-      return 0;
+-}
+-
+-/* Get critical temperature callback functions for thermal zone */
+-static int exynos_get_crit_temp(struct thermal_zone_device *thermal,
+-                              unsigned long *temp)
+-{
+-      int ret;
+-      /* Panic zone */
+-      ret = exynos_get_trip_temp(thermal, GET_TRIP(PANIC_ZONE), temp);
+-      return ret;
+-}
+-
+-/* Bind callback functions for thermal zone */
+-static int exynos_bind(struct thermal_zone_device *thermal,
+-                      struct thermal_cooling_device *cdev)
+-{
+-      int ret = 0, i, tab_size, level;
+-      struct freq_clip_table *tab_ptr, *clip_data;
+-      struct thermal_sensor_conf *data = th_zone->sensor_conf;
+-
+-      tab_ptr = (struct freq_clip_table *)data->cooling_data.freq_data;
+-      tab_size = data->cooling_data.freq_clip_count;
+-
+-      if (tab_ptr == NULL || tab_size == 0)
+-              return -EINVAL;
+-
+-      /* find the cooling device registered*/
+-      for (i = 0; i < th_zone->cool_dev_size; i++)
+-              if (cdev == th_zone->cool_dev[i])
+-                      break;
+-
+-      /* No matching cooling device */
+-      if (i == th_zone->cool_dev_size)
+-              return 0;
+-
+-      /* Bind the thermal zone to the cpufreq cooling device */
+-      for (i = 0; i < tab_size; i++) {
+-              clip_data = (struct freq_clip_table *)&(tab_ptr[i]);
+-              level = cpufreq_cooling_get_level(0, clip_data->freq_clip_max);
+-              if (level == THERMAL_CSTATE_INVALID)
+-                      return 0;
+-              switch (GET_ZONE(i)) {
+-              case MONITOR_ZONE:
+-              case WARN_ZONE:
+-                      if (thermal_zone_bind_cooling_device(thermal, i, cdev,
+-                                                              level, 0)) {
+-                              pr_err("error binding cdev inst %d\n", i);
+-                              ret = -EINVAL;
+-                      }
+-                      th_zone->bind = true;
+-                      break;
+-              default:
+-                      ret = -EINVAL;
+-              }
+-      }
+-
+-      return ret;
+-}
+-
+-/* Unbind callback functions for thermal zone */
+-static int exynos_unbind(struct thermal_zone_device *thermal,
+-                      struct thermal_cooling_device *cdev)
+-{
+-      int ret = 0, i, tab_size;
+-      struct thermal_sensor_conf *data = th_zone->sensor_conf;
+-
+-      if (th_zone->bind == false)
+-              return 0;
+-
+-      tab_size = data->cooling_data.freq_clip_count;
+-
+-      if (tab_size == 0)
+-              return -EINVAL;
+-
+-      /* find the cooling device registered*/
+-      for (i = 0; i < th_zone->cool_dev_size; i++)
+-              if (cdev == th_zone->cool_dev[i])
+-                      break;
+-
+-      /* No matching cooling device */
+-      if (i == th_zone->cool_dev_size)
+-              return 0;
+-
+-      /* Bind the thermal zone to the cpufreq cooling device */
+-      for (i = 0; i < tab_size; i++) {
+-              switch (GET_ZONE(i)) {
+-              case MONITOR_ZONE:
+-              case WARN_ZONE:
+-                      if (thermal_zone_unbind_cooling_device(thermal, i,
+-                                                              cdev)) {
+-                              pr_err("error unbinding cdev inst=%d\n", i);
+-                              ret = -EINVAL;
+-                      }
+-                      th_zone->bind = false;
+-                      break;
+-              default:
+-                      ret = -EINVAL;
+-              }
+-      }
+-      return ret;
+-}
+-
+-/* Get temperature callback functions for thermal zone */
+-static int exynos_get_temp(struct thermal_zone_device *thermal,
+-                      unsigned long *temp)
+-{
+-      void *data;
+-
+-      if (!th_zone->sensor_conf) {
+-              pr_info("Temperature sensor not initialised\n");
+-              return -EINVAL;
+-      }
+-      data = th_zone->sensor_conf->private_data;
+-      *temp = th_zone->sensor_conf->read_temperature(data);
+-      /* convert the temperature into millicelsius */
+-      *temp = *temp * MCELSIUS;
+-      return 0;
+-}
+-
+-/* Get temperature callback functions for thermal zone */
+-static int exynos_set_emul_temp(struct thermal_zone_device *thermal,
+-                                              unsigned long temp)
+-{
+-      void *data;
+-      int ret = -EINVAL;
+-
+-      if (!th_zone->sensor_conf) {
+-              pr_info("Temperature sensor not initialised\n");
+-              return -EINVAL;
+-      }
+-      data = th_zone->sensor_conf->private_data;
+-      if (th_zone->sensor_conf->write_emul_temp)
+-              ret = th_zone->sensor_conf->write_emul_temp(data, temp);
+-      return ret;
+-}
+-
+-/* Get the temperature trend */
+-static int exynos_get_trend(struct thermal_zone_device *thermal,
+-                      int trip, enum thermal_trend *trend)
+-{
+-      int ret;
+-      unsigned long trip_temp;
+-
+-      ret = exynos_get_trip_temp(thermal, trip, &trip_temp);
+-      if (ret < 0)
+-              return ret;
+-
+-      if (thermal->temperature >= trip_temp)
+-              *trend = THERMAL_TREND_RAISE_FULL;
+-      else
+-              *trend = THERMAL_TREND_DROP_FULL;
+-
+-      return 0;
+-}
+-/* Operation callback functions for thermal zone */
+-static struct thermal_zone_device_ops const exynos_dev_ops = {
+-      .bind = exynos_bind,
+-      .unbind = exynos_unbind,
+-      .get_temp = exynos_get_temp,
+-      .set_emul_temp = exynos_set_emul_temp,
+-      .get_trend = exynos_get_trend,
+-      .get_mode = exynos_get_mode,
+-      .set_mode = exynos_set_mode,
+-      .get_trip_type = exynos_get_trip_type,
+-      .get_trip_temp = exynos_get_trip_temp,
+-      .get_crit_temp = exynos_get_crit_temp,
+-};
+-
+-/*
+- * This function may be called from interrupt based temperature sensor
+- * when threshold is changed.
+- */
+-static void exynos_report_trigger(void)
+-{
+-      unsigned int i;
+-      char data[10];
+-      char *envp[] = { data, NULL };
+-
+-      if (!th_zone || !th_zone->therm_dev)
+-              return;
+-      if (th_zone->bind == false) {
+-              for (i = 0; i < th_zone->cool_dev_size; i++) {
+-                      if (!th_zone->cool_dev[i])
+-                              continue;
+-                      exynos_bind(th_zone->therm_dev,
+-                                      th_zone->cool_dev[i]);
+-              }
+-      }
+-
+-      thermal_zone_device_update(th_zone->therm_dev);
+-
+-      mutex_lock(&th_zone->therm_dev->lock);
+-      /* Find the level for which trip happened */
+-      for (i = 0; i < th_zone->sensor_conf->trip_data.trip_count; i++) {
+-              if (th_zone->therm_dev->last_temperature <
+-                      th_zone->sensor_conf->trip_data.trip_val[i] * MCELSIUS)
+-                      break;
+-      }
+-
+-      if (th_zone->mode == THERMAL_DEVICE_ENABLED &&
+-              !th_zone->sensor_conf->trip_data.trigger_falling) {
+-              if (i > 0)
+-                      th_zone->therm_dev->polling_delay = ACTIVE_INTERVAL;
+-              else
+-                      th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
+-      }
+-
+-      snprintf(data, sizeof(data), "%u", i);
+-      kobject_uevent_env(&th_zone->therm_dev->device.kobj, KOBJ_CHANGE, envp);
+-      mutex_unlock(&th_zone->therm_dev->lock);
+-}
+-
+-/* Register with the in-kernel thermal management */
+-static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
+-{
+-      int ret;
+-      struct cpumask mask_val;
+-
+-      if (!sensor_conf || !sensor_conf->read_temperature) {
+-              pr_err("Temperature sensor not initialised\n");
+-              return -EINVAL;
+-      }
+-
+-      th_zone = kzalloc(sizeof(struct exynos_thermal_zone), GFP_KERNEL);
+-      if (!th_zone)
+-              return -ENOMEM;
+-
+-      th_zone->sensor_conf = sensor_conf;
+-      cpumask_set_cpu(0, &mask_val);
+-      th_zone->cool_dev[0] = cpufreq_cooling_register(&mask_val);
+-      if (IS_ERR(th_zone->cool_dev[0])) {
+-              pr_err("Failed to register cpufreq cooling device\n");
+-              ret = -EINVAL;
+-              goto err_unregister;
+-      }
+-      th_zone->cool_dev_size++;
+-
+-      th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name,
+-                      EXYNOS_ZONE_COUNT, 0, NULL, &exynos_dev_ops, NULL, 0,
+-                      sensor_conf->trip_data.trigger_falling ?
+-                      0 : IDLE_INTERVAL);
+-
+-      if (IS_ERR(th_zone->therm_dev)) {
+-              pr_err("Failed to register thermal zone device\n");
+-              ret = PTR_ERR(th_zone->therm_dev);
+-              goto err_unregister;
+-      }
+-      th_zone->mode = THERMAL_DEVICE_ENABLED;
+-
+-      pr_info("Exynos: Kernel Thermal management registered\n");
+-
+-      return 0;
+-
+-err_unregister:
+-      exynos_unregister_thermal();
+-      return ret;
+-}
+-
+-/* Un-Register with the in-kernel thermal management */
+-static void exynos_unregister_thermal(void)
+-{
+-      int i;
+-
+-      if (!th_zone)
+-              return;
+-
+-      if (th_zone->therm_dev)
+-              thermal_zone_device_unregister(th_zone->therm_dev);
+-
+-      for (i = 0; i < th_zone->cool_dev_size; i++) {
+-              if (th_zone->cool_dev[i])
+-                      cpufreq_cooling_unregister(th_zone->cool_dev[i]);
+-      }
+-
+-      kfree(th_zone);
+-      pr_info("Exynos: Kernel Thermal management unregistered\n");
+-}
+-
+ /*
+  * TMU treats temperature as a mapped temperature code.
+  * The temperature is converted differently depending on the calibration type.
+diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c
+new file mode 100644
+index 0000000..f20f458
+--- /dev/null
++++ b/drivers/thermal/samsung/exynos_thermal_common.c
+@@ -0,0 +1,385 @@
++/*
++ * exynos_thermal_common.c - Samsung EXYNOS common thermal file
++ *
++ *  Copyright (C) 2013 Samsung Electronics
++ *  Amit Daniel Kachhap <amit.daniel@samsung.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
++ */
++
++#include <linux/cpu_cooling.h>
++#include <linux/err.h>
++#include <linux/platform_data/exynos_thermal.h>
++#include <linux/slab.h>
++#include <linux/thermal.h>
++
++#include "exynos_thermal_common.h"
++
++struct exynos_thermal_zone {
++      enum thermal_device_mode mode;
++      struct thermal_zone_device *therm_dev;
++      struct thermal_cooling_device *cool_dev[MAX_COOLING_DEVICE];
++      unsigned int cool_dev_size;
++      struct platform_device *exynos4_dev;
++      struct thermal_sensor_conf *sensor_conf;
++      bool bind;
++};
++
++static struct exynos_thermal_zone *th_zone;
++
++/* Get mode callback functions for thermal zone */
++static int exynos_get_mode(struct thermal_zone_device *thermal,
++                      enum thermal_device_mode *mode)
++{
++      if (th_zone)
++              *mode = th_zone->mode;
++      return 0;
++}
++
++/* Set mode callback functions for thermal zone */
++static int exynos_set_mode(struct thermal_zone_device *thermal,
++                      enum thermal_device_mode mode)
++{
++      if (!th_zone->therm_dev) {
++              pr_notice("thermal zone not registered\n");
++              return 0;
++      }
++
++      mutex_lock(&th_zone->therm_dev->lock);
++
++      if (mode == THERMAL_DEVICE_ENABLED &&
++              !th_zone->sensor_conf->trip_data.trigger_falling)
++              th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
++      else
++              th_zone->therm_dev->polling_delay = 0;
++
++      mutex_unlock(&th_zone->therm_dev->lock);
++
++      th_zone->mode = mode;
++      thermal_zone_device_update(th_zone->therm_dev);
++      pr_info("thermal polling set for duration=%d msec\n",
++                              th_zone->therm_dev->polling_delay);
++      return 0;
++}
++
++
++/* Get trip type callback functions for thermal zone */
++static int exynos_get_trip_type(struct thermal_zone_device *thermal, int trip,
++                               enum thermal_trip_type *type)
++{
++      switch (GET_ZONE(trip)) {
++      case MONITOR_ZONE:
++      case WARN_ZONE:
++              *type = THERMAL_TRIP_ACTIVE;
++              break;
++      case PANIC_ZONE:
++              *type = THERMAL_TRIP_CRITICAL;
++              break;
++      default:
++              return -EINVAL;
++      }
++      return 0;
++}
++
++/* Get trip temperature callback functions for thermal zone */
++static int exynos_get_trip_temp(struct thermal_zone_device *thermal, int trip,
++                              unsigned long *temp)
++{
++      if (trip < GET_TRIP(MONITOR_ZONE) || trip > GET_TRIP(PANIC_ZONE))
++              return -EINVAL;
++
++      *temp = th_zone->sensor_conf->trip_data.trip_val[trip];
++      /* convert the temperature into millicelsius */
++      *temp = *temp * MCELSIUS;
++
++      return 0;
++}
++
++/* Get critical temperature callback functions for thermal zone */
++static int exynos_get_crit_temp(struct thermal_zone_device *thermal,
++                              unsigned long *temp)
++{
++      int ret;
++      /* Panic zone */
++      ret = exynos_get_trip_temp(thermal, GET_TRIP(PANIC_ZONE), temp);
++      return ret;
++}
++
++/* Bind callback functions for thermal zone */
++static int exynos_bind(struct thermal_zone_device *thermal,
++                      struct thermal_cooling_device *cdev)
++{
++      int ret = 0, i, tab_size, level;
++      struct freq_clip_table *tab_ptr, *clip_data;
++      struct thermal_sensor_conf *data = th_zone->sensor_conf;
++
++      tab_ptr = (struct freq_clip_table *)data->cooling_data.freq_data;
++      tab_size = data->cooling_data.freq_clip_count;
++
++      if (tab_ptr == NULL || tab_size == 0)
++              return -EINVAL;
++
++      /* find the cooling device registered*/
++      for (i = 0; i < th_zone->cool_dev_size; i++)
++              if (cdev == th_zone->cool_dev[i])
++                      break;
++
++      /* No matching cooling device */
++      if (i == th_zone->cool_dev_size)
++              return 0;
++
++      /* Bind the thermal zone to the cpufreq cooling device */
++      for (i = 0; i < tab_size; i++) {
++              clip_data = (struct freq_clip_table *)&(tab_ptr[i]);
++              level = cpufreq_cooling_get_level(0, clip_data->freq_clip_max);
++              if (level == THERMAL_CSTATE_INVALID)
++                      return 0;
++              switch (GET_ZONE(i)) {
++              case MONITOR_ZONE:
++              case WARN_ZONE:
++                      if (thermal_zone_bind_cooling_device(thermal, i, cdev,
++                                                              level, 0)) {
++                              pr_err("error binding cdev inst %d\n", i);
++                              ret = -EINVAL;
++                      }
++                      th_zone->bind = true;
++                      break;
++              default:
++                      ret = -EINVAL;
++              }
++      }
++
++      return ret;
++}
++
++/* Unbind callback functions for thermal zone */
++static int exynos_unbind(struct thermal_zone_device *thermal,
++                      struct thermal_cooling_device *cdev)
++{
++      int ret = 0, i, tab_size;
++      struct thermal_sensor_conf *data = th_zone->sensor_conf;
++
++      if (th_zone->bind == false)
++              return 0;
++
++      tab_size = data->cooling_data.freq_clip_count;
++
++      if (tab_size == 0)
++              return -EINVAL;
++
++      /* find the cooling device registered*/
++      for (i = 0; i < th_zone->cool_dev_size; i++)
++              if (cdev == th_zone->cool_dev[i])
++                      break;
++
++      /* No matching cooling device */
++      if (i == th_zone->cool_dev_size)
++              return 0;
++
++      /* Bind the thermal zone to the cpufreq cooling device */
++      for (i = 0; i < tab_size; i++) {
++              switch (GET_ZONE(i)) {
++              case MONITOR_ZONE:
++              case WARN_ZONE:
++                      if (thermal_zone_unbind_cooling_device(thermal, i,
++                                                              cdev)) {
++                              pr_err("error unbinding cdev inst=%d\n", i);
++                              ret = -EINVAL;
++                      }
++                      th_zone->bind = false;
++                      break;
++              default:
++                      ret = -EINVAL;
++              }
++      }
++      return ret;
++}
++
++/* Get temperature callback functions for thermal zone */
++static int exynos_get_temp(struct thermal_zone_device *thermal,
++                      unsigned long *temp)
++{
++      void *data;
++
++      if (!th_zone->sensor_conf) {
++              pr_info("Temperature sensor not initialised\n");
++              return -EINVAL;
++      }
++      data = th_zone->sensor_conf->private_data;
++      *temp = th_zone->sensor_conf->read_temperature(data);
++      /* convert the temperature into millicelsius */
++      *temp = *temp * MCELSIUS;
++      return 0;
++}
++
++/* Get temperature callback functions for thermal zone */
++static int exynos_set_emul_temp(struct thermal_zone_device *thermal,
++                                              unsigned long temp)
++{
++      void *data;
++      int ret = -EINVAL;
++
++      if (!th_zone->sensor_conf) {
++              pr_info("Temperature sensor not initialised\n");
++              return -EINVAL;
++      }
++      data = th_zone->sensor_conf->private_data;
++      if (th_zone->sensor_conf->write_emul_temp)
++              ret = th_zone->sensor_conf->write_emul_temp(data, temp);
++      return ret;
++}
++
++/* Get the temperature trend */
++static int exynos_get_trend(struct thermal_zone_device *thermal,
++                      int trip, enum thermal_trend *trend)
++{
++      int ret;
++      unsigned long trip_temp;
++
++      ret = exynos_get_trip_temp(thermal, trip, &trip_temp);
++      if (ret < 0)
++              return ret;
++
++      if (thermal->temperature >= trip_temp)
++              *trend = THERMAL_TREND_RAISE_FULL;
++      else
++              *trend = THERMAL_TREND_DROP_FULL;
++
++      return 0;
++}
++/* Operation callback functions for thermal zone */
++static struct thermal_zone_device_ops const exynos_dev_ops = {
++      .bind = exynos_bind,
++      .unbind = exynos_unbind,
++      .get_temp = exynos_get_temp,
++      .set_emul_temp = exynos_set_emul_temp,
++      .get_trend = exynos_get_trend,
++      .get_mode = exynos_get_mode,
++      .set_mode = exynos_set_mode,
++      .get_trip_type = exynos_get_trip_type,
++      .get_trip_temp = exynos_get_trip_temp,
++      .get_crit_temp = exynos_get_crit_temp,
++};
++
++/*
++ * This function may be called from interrupt based temperature sensor
++ * when threshold is changed.
++ */
++void exynos_report_trigger(void)
++{
++      unsigned int i;
++      char data[10];
++      char *envp[] = { data, NULL };
++
++      if (!th_zone || !th_zone->therm_dev)
++              return;
++      if (th_zone->bind == false) {
++              for (i = 0; i < th_zone->cool_dev_size; i++) {
++                      if (!th_zone->cool_dev[i])
++                              continue;
++                      exynos_bind(th_zone->therm_dev,
++                                      th_zone->cool_dev[i]);
++              }
++      }
++
++      thermal_zone_device_update(th_zone->therm_dev);
++
++      mutex_lock(&th_zone->therm_dev->lock);
++      /* Find the level for which trip happened */
++      for (i = 0; i < th_zone->sensor_conf->trip_data.trip_count; i++) {
++              if (th_zone->therm_dev->last_temperature <
++                      th_zone->sensor_conf->trip_data.trip_val[i] * MCELSIUS)
++                      break;
++      }
++
++      if (th_zone->mode == THERMAL_DEVICE_ENABLED &&
++              !th_zone->sensor_conf->trip_data.trigger_falling) {
++              if (i > 0)
++                      th_zone->therm_dev->polling_delay = ACTIVE_INTERVAL;
++              else
++                      th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
++      }
++
++      snprintf(data, sizeof(data), "%u", i);
++      kobject_uevent_env(&th_zone->therm_dev->device.kobj, KOBJ_CHANGE, envp);
++      mutex_unlock(&th_zone->therm_dev->lock);
++}
++
++/* Register with the in-kernel thermal management */
++int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
++{
++      int ret;
++      struct cpumask mask_val;
++
++      if (!sensor_conf || !sensor_conf->read_temperature) {
++              pr_err("Temperature sensor not initialised\n");
++              return -EINVAL;
++      }
++
++      th_zone = kzalloc(sizeof(struct exynos_thermal_zone), GFP_KERNEL);
++      if (!th_zone)
++              return -ENOMEM;
++
++      th_zone->sensor_conf = sensor_conf;
++      cpumask_set_cpu(0, &mask_val);
++      th_zone->cool_dev[0] = cpufreq_cooling_register(&mask_val);
++      if (IS_ERR(th_zone->cool_dev[0])) {
++              pr_err("Failed to register cpufreq cooling device\n");
++              ret = -EINVAL;
++              goto err_unregister;
++      }
++      th_zone->cool_dev_size++;
++
++      th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name,
++                      EXYNOS_ZONE_COUNT, 0, NULL, &exynos_dev_ops, NULL, 0,
++                      sensor_conf->trip_data.trigger_falling ?
++                      0 : IDLE_INTERVAL);
++
++      if (IS_ERR(th_zone->therm_dev)) {
++              pr_err("Failed to register thermal zone device\n");
++              ret = PTR_ERR(th_zone->therm_dev);
++              goto err_unregister;
++      }
++      th_zone->mode = THERMAL_DEVICE_ENABLED;
++
++      pr_info("Exynos: Kernel Thermal management registered\n");
++
++      return 0;
++
++err_unregister:
++      exynos_unregister_thermal();
++      return ret;
++}
++
++/* Un-Register with the in-kernel thermal management */
++void exynos_unregister_thermal(void)
++{
++      int i;
++
++      if (!th_zone)
++              return;
++
++      if (th_zone->therm_dev)
++              thermal_zone_device_unregister(th_zone->therm_dev);
++
++      for (i = 0; i < th_zone->cool_dev_size; i++) {
++              if (th_zone->cool_dev[i])
++                      cpufreq_cooling_unregister(th_zone->cool_dev[i]);
++      }
++
++      kfree(th_zone);
++      pr_info("Exynos: Kernel Thermal management unregistered\n");
++}
+diff --git a/drivers/thermal/samsung/exynos_thermal_common.h b/drivers/thermal/samsung/exynos_thermal_common.h
+new file mode 100644
+index 0000000..8df1848
+--- /dev/null
++++ b/drivers/thermal/samsung/exynos_thermal_common.h
+@@ -0,0 +1,83 @@
++/*
++ * exynos_thermal_common.h - Samsung EXYNOS common header file
++ *
++ *  Copyright (C) 2013 Samsung Electronics
++ *  Amit Daniel Kachhap <amit.daniel@samsung.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
++ */
++
++#ifndef _EXYNOS_THERMAL_COMMON_H
++#define _EXYNOS_THERMAL_COMMON_H
++
++/* In-kernel thermal framework related macros & definations */
++#define SENSOR_NAME_LEN       16
++#define MAX_TRIP_COUNT        8
++#define MAX_COOLING_DEVICE 4
++#define MAX_THRESHOLD_LEVS 4
++
++#define ACTIVE_INTERVAL 500
++#define IDLE_INTERVAL 10000
++#define MCELSIUS      1000
++
++/* CPU Zone information */
++#define PANIC_ZONE      4
++#define WARN_ZONE       3
++#define MONITOR_ZONE    2
++#define SAFE_ZONE       1
++
++#define GET_ZONE(trip) (trip + 2)
++#define GET_TRIP(zone) (zone - 2)
++
++#define EXYNOS_ZONE_COUNT     3
++
++struct        thermal_trip_point_conf {
++      int trip_val[MAX_TRIP_COUNT];
++      int trip_count;
++      unsigned char trigger_falling;
++};
++
++struct        thermal_cooling_conf {
++      struct freq_clip_table freq_data[MAX_TRIP_COUNT];
++      int freq_clip_count;
++};
++
++struct thermal_sensor_conf {
++      char name[SENSOR_NAME_LEN];
++      int (*read_temperature)(void *data);
++      int (*write_emul_temp)(void *drv_data, unsigned long temp);
++      struct thermal_trip_point_conf trip_data;
++      struct thermal_cooling_conf cooling_data;
++      void *private_data;
++};
++
++/*Functions used exynos based thermal sensor driver*/
++#ifdef CONFIG_EXYNOS_THERMAL_CORE
++void exynos_unregister_thermal(void);
++int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf);
++void exynos_report_trigger(void);
++#else
++static inline void
++exynos_unregister_thermal(void) { return; }
++
++static inline int
++exynos_register_thermal(struct thermal_sensor_conf *sensor_conf) { return 0; }
++
++static inline void
++exynos_report_trigger(void) { return; }
++
++#endif /* CONFIG_EXYNOS_THERMAL_CORE */
++#endif /* _EXYNOS_THERMAL_COMMON_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0955-thermal-exynos-Rename-exynos_thermal.c-to-exynos_tmu.patch b/patches.tizen/0955-thermal-exynos-Rename-exynos_thermal.c-to-exynos_tmu.patch
new file mode 100644 (file)
index 0000000..08b1b8b
--- /dev/null
@@ -0,0 +1,1357 @@
+From 122c2b5fbfe092cbb59968e2e486c4fd626050fd Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Mon, 24 Jun 2013 16:20:26 +0530
+Subject: [PATCH 0955/1302] thermal: exynos: Rename exynos_thermal.c to
+ exynos_tmu.c
+
+This patch renames exynos_thermal.c to exynos_tmu.c. This change is needed as
+this file now just contains exynos tmu driver related codes and thermal zone
+or cpufreq cooling registration related changes are not there anymore.
+
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/Makefile         |   6 +-
+ drivers/thermal/samsung/exynos_thermal.c | 652 -------------------------------
+ drivers/thermal/samsung/exynos_tmu.c     | 652 +++++++++++++++++++++++++++++++
+ 3 files changed, 655 insertions(+), 655 deletions(-)
+ delete mode 100644 drivers/thermal/samsung/exynos_thermal.c
+ create mode 100644 drivers/thermal/samsung/exynos_tmu.c
+
+diff --git a/drivers/thermal/samsung/Makefile b/drivers/thermal/samsung/Makefile
+index 6227d4f..22528d6 100644
+--- a/drivers/thermal/samsung/Makefile
++++ b/drivers/thermal/samsung/Makefile
+@@ -1,6 +1,6 @@
+ #
+ # Samsung thermal specific Makefile
+ #
+-obj-$(CONFIG_EXYNOS_THERMAL)                  += exynos_soc_thermal.o
+-exynos_soc_thermal-y                          := exynos_thermal.o
+-exynos_soc_thermal-$(CONFIG_EXYNOS_THERMAL_CORE) += exynos_thermal_common.o
++obj-$(CONFIG_EXYNOS_THERMAL)                  += exynos_thermal.o
++exynos_thermal-y                              := exynos_tmu.o
++exynos_thermal-$(CONFIG_EXYNOS_THERMAL_CORE)  += exynos_thermal_common.o
+diff --git a/drivers/thermal/samsung/exynos_thermal.c b/drivers/thermal/samsung/exynos_thermal.c
+deleted file mode 100644
+index f3500ab..0000000
+--- a/drivers/thermal/samsung/exynos_thermal.c
++++ /dev/null
+@@ -1,652 +0,0 @@
+-/*
+- * exynos_thermal.c - Samsung EXYNOS TMU (Thermal Management Unit)
+- *
+- *  Copyright (C) 2011 Samsung Electronics
+- *  Donggeun Kim <dg77.kim@samsung.com>
+- *  Amit Daniel Kachhap <amit.kachhap@linaro.org>
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+- *
+- */
+-
+-#include <linux/clk.h>
+-#include <linux/io.h>
+-#include <linux/interrupt.h>
+-#include <linux/module.h>
+-#include <linux/of.h>
+-#include <linux/platform_device.h>
+-#include <linux/platform_data/exynos_thermal.h>
+-
+-#include "exynos_thermal_common.h"
+-
+-/* Exynos generic registers */
+-#define EXYNOS_TMU_REG_TRIMINFO               0x0
+-#define EXYNOS_TMU_REG_CONTROL                0x20
+-#define EXYNOS_TMU_REG_STATUS         0x28
+-#define EXYNOS_TMU_REG_CURRENT_TEMP   0x40
+-#define EXYNOS_TMU_REG_INTEN          0x70
+-#define EXYNOS_TMU_REG_INTSTAT                0x74
+-#define EXYNOS_TMU_REG_INTCLEAR               0x78
+-
+-#define EXYNOS_TMU_TRIM_TEMP_MASK     0xff
+-#define EXYNOS_TMU_GAIN_SHIFT         8
+-#define EXYNOS_TMU_REF_VOLTAGE_SHIFT  24
+-#define EXYNOS_TMU_CORE_ON            3
+-#define EXYNOS_TMU_CORE_OFF           2
+-#define EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET    50
+-
+-/* Exynos4210 specific registers */
+-#define EXYNOS4210_TMU_REG_THRESHOLD_TEMP     0x44
+-#define EXYNOS4210_TMU_REG_TRIG_LEVEL0        0x50
+-#define EXYNOS4210_TMU_REG_TRIG_LEVEL1        0x54
+-#define EXYNOS4210_TMU_REG_TRIG_LEVEL2        0x58
+-#define EXYNOS4210_TMU_REG_TRIG_LEVEL3        0x5C
+-#define EXYNOS4210_TMU_REG_PAST_TEMP0 0x60
+-#define EXYNOS4210_TMU_REG_PAST_TEMP1 0x64
+-#define EXYNOS4210_TMU_REG_PAST_TEMP2 0x68
+-#define EXYNOS4210_TMU_REG_PAST_TEMP3 0x6C
+-
+-#define EXYNOS4210_TMU_TRIG_LEVEL0_MASK       0x1
+-#define EXYNOS4210_TMU_TRIG_LEVEL1_MASK       0x10
+-#define EXYNOS4210_TMU_TRIG_LEVEL2_MASK       0x100
+-#define EXYNOS4210_TMU_TRIG_LEVEL3_MASK       0x1000
+-#define EXYNOS4210_TMU_INTCLEAR_VAL   0x1111
+-
+-/* Exynos5250 and Exynos4412 specific registers */
+-#define EXYNOS_TMU_TRIMINFO_CON       0x14
+-#define EXYNOS_THD_TEMP_RISE          0x50
+-#define EXYNOS_THD_TEMP_FALL          0x54
+-#define EXYNOS_EMUL_CON               0x80
+-
+-#define EXYNOS_TRIMINFO_RELOAD                0x1
+-#define EXYNOS_TMU_CLEAR_RISE_INT     0x111
+-#define EXYNOS_TMU_CLEAR_FALL_INT     (0x111 << 12)
+-#define EXYNOS_MUX_ADDR_VALUE         6
+-#define EXYNOS_MUX_ADDR_SHIFT         20
+-#define EXYNOS_TMU_TRIP_MODE_SHIFT    13
+-
+-#define EFUSE_MIN_VALUE 40
+-#define EFUSE_MAX_VALUE 100
+-
+-#ifdef CONFIG_THERMAL_EMULATION
+-#define EXYNOS_EMUL_TIME      0x57F0
+-#define EXYNOS_EMUL_TIME_SHIFT        16
+-#define EXYNOS_EMUL_DATA_SHIFT        8
+-#define EXYNOS_EMUL_DATA_MASK 0xFF
+-#define EXYNOS_EMUL_ENABLE    0x1
+-#endif /* CONFIG_THERMAL_EMULATION */
+-
+-struct exynos_tmu_data {
+-      struct exynos_tmu_platform_data *pdata;
+-      struct resource *mem;
+-      void __iomem *base;
+-      int irq;
+-      enum soc_type soc;
+-      struct work_struct irq_work;
+-      struct mutex lock;
+-      struct clk *clk;
+-      u8 temp_error1, temp_error2;
+-};
+-
+-/*
+- * TMU treats temperature as a mapped temperature code.
+- * The temperature is converted differently depending on the calibration type.
+- */
+-static int temp_to_code(struct exynos_tmu_data *data, u8 temp)
+-{
+-      struct exynos_tmu_platform_data *pdata = data->pdata;
+-      int temp_code;
+-
+-      if (data->soc == SOC_ARCH_EXYNOS4210)
+-              /* temp should range between 25 and 125 */
+-              if (temp < 25 || temp > 125) {
+-                      temp_code = -EINVAL;
+-                      goto out;
+-              }
+-
+-      switch (pdata->cal_type) {
+-      case TYPE_TWO_POINT_TRIMMING:
+-              temp_code = (temp - 25) *
+-                  (data->temp_error2 - data->temp_error1) /
+-                  (85 - 25) + data->temp_error1;
+-              break;
+-      case TYPE_ONE_POINT_TRIMMING:
+-              temp_code = temp + data->temp_error1 - 25;
+-              break;
+-      default:
+-              temp_code = temp + EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET;
+-              break;
+-      }
+-out:
+-      return temp_code;
+-}
+-
+-/*
+- * Calculate a temperature value from a temperature code.
+- * The unit of the temperature is degree Celsius.
+- */
+-static int code_to_temp(struct exynos_tmu_data *data, u8 temp_code)
+-{
+-      struct exynos_tmu_platform_data *pdata = data->pdata;
+-      int temp;
+-
+-      if (data->soc == SOC_ARCH_EXYNOS4210)
+-              /* temp_code should range between 75 and 175 */
+-              if (temp_code < 75 || temp_code > 175) {
+-                      temp = -ENODATA;
+-                      goto out;
+-              }
+-
+-      switch (pdata->cal_type) {
+-      case TYPE_TWO_POINT_TRIMMING:
+-              temp = (temp_code - data->temp_error1) * (85 - 25) /
+-                  (data->temp_error2 - data->temp_error1) + 25;
+-              break;
+-      case TYPE_ONE_POINT_TRIMMING:
+-              temp = temp_code - data->temp_error1 + 25;
+-              break;
+-      default:
+-              temp = temp_code - EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET;
+-              break;
+-      }
+-out:
+-      return temp;
+-}
+-
+-static int exynos_tmu_initialize(struct platform_device *pdev)
+-{
+-      struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+-      struct exynos_tmu_platform_data *pdata = data->pdata;
+-      unsigned int status, trim_info;
+-      unsigned int rising_threshold = 0, falling_threshold = 0;
+-      int ret = 0, threshold_code, i, trigger_levs = 0;
+-
+-      mutex_lock(&data->lock);
+-      clk_enable(data->clk);
+-
+-      status = readb(data->base + EXYNOS_TMU_REG_STATUS);
+-      if (!status) {
+-              ret = -EBUSY;
+-              goto out;
+-      }
+-
+-      if (data->soc == SOC_ARCH_EXYNOS) {
+-              __raw_writel(EXYNOS_TRIMINFO_RELOAD,
+-                              data->base + EXYNOS_TMU_TRIMINFO_CON);
+-      }
+-      /* Save trimming info in order to perform calibration */
+-      trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
+-      data->temp_error1 = trim_info & EXYNOS_TMU_TRIM_TEMP_MASK;
+-      data->temp_error2 = ((trim_info >> 8) & EXYNOS_TMU_TRIM_TEMP_MASK);
+-
+-      if ((EFUSE_MIN_VALUE > data->temp_error1) ||
+-                      (data->temp_error1 > EFUSE_MAX_VALUE) ||
+-                      (data->temp_error2 != 0))
+-              data->temp_error1 = pdata->efuse_value;
+-
+-      /* Count trigger levels to be enabled */
+-      for (i = 0; i < MAX_THRESHOLD_LEVS; i++)
+-              if (pdata->trigger_levels[i])
+-                      trigger_levs++;
+-
+-      if (data->soc == SOC_ARCH_EXYNOS4210) {
+-              /* Write temperature code for threshold */
+-              threshold_code = temp_to_code(data, pdata->threshold);
+-              if (threshold_code < 0) {
+-                      ret = threshold_code;
+-                      goto out;
+-              }
+-              writeb(threshold_code,
+-                      data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP);
+-              for (i = 0; i < trigger_levs; i++)
+-                      writeb(pdata->trigger_levels[i],
+-                      data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + i * 4);
+-
+-              writel(EXYNOS4210_TMU_INTCLEAR_VAL,
+-                      data->base + EXYNOS_TMU_REG_INTCLEAR);
+-      } else if (data->soc == SOC_ARCH_EXYNOS) {
+-              /* Write temperature code for rising and falling threshold */
+-              for (i = 0; i < trigger_levs; i++) {
+-                      threshold_code = temp_to_code(data,
+-                                              pdata->trigger_levels[i]);
+-                      if (threshold_code < 0) {
+-                              ret = threshold_code;
+-                              goto out;
+-                      }
+-                      rising_threshold |= threshold_code << 8 * i;
+-                      if (pdata->threshold_falling) {
+-                              threshold_code = temp_to_code(data,
+-                                              pdata->trigger_levels[i] -
+-                                              pdata->threshold_falling);
+-                              if (threshold_code > 0)
+-                                      falling_threshold |=
+-                                              threshold_code << 8 * i;
+-                      }
+-              }
+-
+-              writel(rising_threshold,
+-                              data->base + EXYNOS_THD_TEMP_RISE);
+-              writel(falling_threshold,
+-                              data->base + EXYNOS_THD_TEMP_FALL);
+-
+-              writel(EXYNOS_TMU_CLEAR_RISE_INT | EXYNOS_TMU_CLEAR_FALL_INT,
+-                              data->base + EXYNOS_TMU_REG_INTCLEAR);
+-      }
+-out:
+-      clk_disable(data->clk);
+-      mutex_unlock(&data->lock);
+-
+-      return ret;
+-}
+-
+-static void exynos_tmu_control(struct platform_device *pdev, bool on)
+-{
+-      struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+-      struct exynos_tmu_platform_data *pdata = data->pdata;
+-      unsigned int con, interrupt_en;
+-
+-      mutex_lock(&data->lock);
+-      clk_enable(data->clk);
+-
+-      con = pdata->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT |
+-              pdata->gain << EXYNOS_TMU_GAIN_SHIFT;
+-
+-      if (data->soc == SOC_ARCH_EXYNOS) {
+-              con |= pdata->noise_cancel_mode << EXYNOS_TMU_TRIP_MODE_SHIFT;
+-              con |= (EXYNOS_MUX_ADDR_VALUE << EXYNOS_MUX_ADDR_SHIFT);
+-      }
+-
+-      if (on) {
+-              con |= EXYNOS_TMU_CORE_ON;
+-              interrupt_en = pdata->trigger_level3_en << 12 |
+-                      pdata->trigger_level2_en << 8 |
+-                      pdata->trigger_level1_en << 4 |
+-                      pdata->trigger_level0_en;
+-              if (pdata->threshold_falling)
+-                      interrupt_en |= interrupt_en << 16;
+-      } else {
+-              con |= EXYNOS_TMU_CORE_OFF;
+-              interrupt_en = 0; /* Disable all interrupts */
+-      }
+-      writel(interrupt_en, data->base + EXYNOS_TMU_REG_INTEN);
+-      writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
+-
+-      clk_disable(data->clk);
+-      mutex_unlock(&data->lock);
+-}
+-
+-static int exynos_tmu_read(struct exynos_tmu_data *data)
+-{
+-      u8 temp_code;
+-      int temp;
+-
+-      mutex_lock(&data->lock);
+-      clk_enable(data->clk);
+-
+-      temp_code = readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP);
+-      temp = code_to_temp(data, temp_code);
+-
+-      clk_disable(data->clk);
+-      mutex_unlock(&data->lock);
+-
+-      return temp;
+-}
+-
+-#ifdef CONFIG_THERMAL_EMULATION
+-static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp)
+-{
+-      struct exynos_tmu_data *data = drv_data;
+-      unsigned int reg;
+-      int ret = -EINVAL;
+-
+-      if (data->soc == SOC_ARCH_EXYNOS4210)
+-              goto out;
+-
+-      if (temp && temp < MCELSIUS)
+-              goto out;
+-
+-      mutex_lock(&data->lock);
+-      clk_enable(data->clk);
+-
+-      reg = readl(data->base + EXYNOS_EMUL_CON);
+-
+-      if (temp) {
+-              temp /= MCELSIUS;
+-
+-              reg = (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT) |
+-                      (temp_to_code(data, temp)
+-                       << EXYNOS_EMUL_DATA_SHIFT) | EXYNOS_EMUL_ENABLE;
+-      } else {
+-              reg &= ~EXYNOS_EMUL_ENABLE;
+-      }
+-
+-      writel(reg, data->base + EXYNOS_EMUL_CON);
+-
+-      clk_disable(data->clk);
+-      mutex_unlock(&data->lock);
+-      return 0;
+-out:
+-      return ret;
+-}
+-#else
+-static int exynos_tmu_set_emulation(void *drv_data,   unsigned long temp)
+-      { return -EINVAL; }
+-#endif/*CONFIG_THERMAL_EMULATION*/
+-
+-static void exynos_tmu_work(struct work_struct *work)
+-{
+-      struct exynos_tmu_data *data = container_of(work,
+-                      struct exynos_tmu_data, irq_work);
+-
+-      exynos_report_trigger();
+-      mutex_lock(&data->lock);
+-      clk_enable(data->clk);
+-      if (data->soc == SOC_ARCH_EXYNOS)
+-              writel(EXYNOS_TMU_CLEAR_RISE_INT |
+-                              EXYNOS_TMU_CLEAR_FALL_INT,
+-                              data->base + EXYNOS_TMU_REG_INTCLEAR);
+-      else
+-              writel(EXYNOS4210_TMU_INTCLEAR_VAL,
+-                              data->base + EXYNOS_TMU_REG_INTCLEAR);
+-      clk_disable(data->clk);
+-      mutex_unlock(&data->lock);
+-
+-      enable_irq(data->irq);
+-}
+-
+-static irqreturn_t exynos_tmu_irq(int irq, void *id)
+-{
+-      struct exynos_tmu_data *data = id;
+-
+-      disable_irq_nosync(irq);
+-      schedule_work(&data->irq_work);
+-
+-      return IRQ_HANDLED;
+-}
+-static struct thermal_sensor_conf exynos_sensor_conf = {
+-      .name                   = "exynos-therm",
+-      .read_temperature       = (int (*)(void *))exynos_tmu_read,
+-      .write_emul_temp        = exynos_tmu_set_emulation,
+-};
+-
+-#if defined(CONFIG_CPU_EXYNOS4210)
+-static struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
+-      .threshold = 80,
+-      .trigger_levels[0] = 5,
+-      .trigger_levels[1] = 20,
+-      .trigger_levels[2] = 30,
+-      .trigger_level0_en = 1,
+-      .trigger_level1_en = 1,
+-      .trigger_level2_en = 1,
+-      .trigger_level3_en = 0,
+-      .gain = 15,
+-      .reference_voltage = 7,
+-      .cal_type = TYPE_ONE_POINT_TRIMMING,
+-      .freq_tab[0] = {
+-              .freq_clip_max = 800 * 1000,
+-              .temp_level = 85,
+-      },
+-      .freq_tab[1] = {
+-              .freq_clip_max = 200 * 1000,
+-              .temp_level = 100,
+-      },
+-      .freq_tab_count = 2,
+-      .type = SOC_ARCH_EXYNOS4210,
+-};
+-#define EXYNOS4210_TMU_DRV_DATA (&exynos4210_default_tmu_data)
+-#else
+-#define EXYNOS4210_TMU_DRV_DATA (NULL)
+-#endif
+-
+-#if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412) || \
+-      defined(CONFIG_SOC_EXYNOS4212)
+-static struct exynos_tmu_platform_data const exynos_default_tmu_data = {
+-      .threshold_falling = 10,
+-      .trigger_levels[0] = 85,
+-      .trigger_levels[1] = 103,
+-      .trigger_levels[2] = 110,
+-      .trigger_level0_en = 1,
+-      .trigger_level1_en = 1,
+-      .trigger_level2_en = 1,
+-      .trigger_level3_en = 0,
+-      .gain = 8,
+-      .reference_voltage = 16,
+-      .noise_cancel_mode = 4,
+-      .cal_type = TYPE_ONE_POINT_TRIMMING,
+-      .efuse_value = 55,
+-      .freq_tab[0] = {
+-              .freq_clip_max = 800 * 1000,
+-              .temp_level = 85,
+-      },
+-      .freq_tab[1] = {
+-              .freq_clip_max = 200 * 1000,
+-              .temp_level = 103,
+-      },
+-      .freq_tab_count = 2,
+-      .type = SOC_ARCH_EXYNOS,
+-};
+-#define EXYNOS_TMU_DRV_DATA (&exynos_default_tmu_data)
+-#else
+-#define EXYNOS_TMU_DRV_DATA (NULL)
+-#endif
+-
+-#ifdef CONFIG_OF
+-static const struct of_device_id exynos_tmu_match[] = {
+-      {
+-              .compatible = "samsung,exynos4210-tmu",
+-              .data = (void *)EXYNOS4210_TMU_DRV_DATA,
+-      },
+-      {
+-              .compatible = "samsung,exynos4412-tmu",
+-              .data = (void *)EXYNOS_TMU_DRV_DATA,
+-      },
+-      {
+-              .compatible = "samsung,exynos5250-tmu",
+-              .data = (void *)EXYNOS_TMU_DRV_DATA,
+-      },
+-      {},
+-};
+-MODULE_DEVICE_TABLE(of, exynos_tmu_match);
+-#endif
+-
+-static struct platform_device_id exynos_tmu_driver_ids[] = {
+-      {
+-              .name           = "exynos4210-tmu",
+-              .driver_data    = (kernel_ulong_t)EXYNOS4210_TMU_DRV_DATA,
+-      },
+-      {
+-              .name           = "exynos5250-tmu",
+-              .driver_data    = (kernel_ulong_t)EXYNOS_TMU_DRV_DATA,
+-      },
+-      { },
+-};
+-MODULE_DEVICE_TABLE(platform, exynos_tmu_driver_ids);
+-
+-static inline struct  exynos_tmu_platform_data *exynos_get_driver_data(
+-                      struct platform_device *pdev)
+-{
+-#ifdef CONFIG_OF
+-      if (pdev->dev.of_node) {
+-              const struct of_device_id *match;
+-              match = of_match_node(exynos_tmu_match, pdev->dev.of_node);
+-              if (!match)
+-                      return NULL;
+-              return (struct exynos_tmu_platform_data *) match->data;
+-      }
+-#endif
+-      return (struct exynos_tmu_platform_data *)
+-                      platform_get_device_id(pdev)->driver_data;
+-}
+-
+-static int exynos_tmu_probe(struct platform_device *pdev)
+-{
+-      struct exynos_tmu_data *data;
+-      struct exynos_tmu_platform_data *pdata = pdev->dev.platform_data;
+-      int ret, i;
+-
+-      if (!pdata)
+-              pdata = exynos_get_driver_data(pdev);
+-
+-      if (!pdata) {
+-              dev_err(&pdev->dev, "No platform init data supplied.\n");
+-              return -ENODEV;
+-      }
+-      data = devm_kzalloc(&pdev->dev, sizeof(struct exynos_tmu_data),
+-                                      GFP_KERNEL);
+-      if (!data) {
+-              dev_err(&pdev->dev, "Failed to allocate driver structure\n");
+-              return -ENOMEM;
+-      }
+-
+-      data->irq = platform_get_irq(pdev, 0);
+-      if (data->irq < 0) {
+-              dev_err(&pdev->dev, "Failed to get platform irq\n");
+-              return data->irq;
+-      }
+-
+-      INIT_WORK(&data->irq_work, exynos_tmu_work);
+-
+-      data->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-      data->base = devm_ioremap_resource(&pdev->dev, data->mem);
+-      if (IS_ERR(data->base))
+-              return PTR_ERR(data->base);
+-
+-      ret = devm_request_irq(&pdev->dev, data->irq, exynos_tmu_irq,
+-              IRQF_TRIGGER_RISING, "exynos-tmu", data);
+-      if (ret) {
+-              dev_err(&pdev->dev, "Failed to request irq: %d\n", data->irq);
+-              return ret;
+-      }
+-
+-      data->clk = devm_clk_get(&pdev->dev, "tmu_apbif");
+-      if (IS_ERR(data->clk)) {
+-              dev_err(&pdev->dev, "Failed to get clock\n");
+-              return  PTR_ERR(data->clk);
+-      }
+-
+-      ret = clk_prepare(data->clk);
+-      if (ret)
+-              return ret;
+-
+-      if (pdata->type == SOC_ARCH_EXYNOS ||
+-                              pdata->type == SOC_ARCH_EXYNOS4210)
+-              data->soc = pdata->type;
+-      else {
+-              ret = -EINVAL;
+-              dev_err(&pdev->dev, "Platform not supported\n");
+-              goto err_clk;
+-      }
+-
+-      data->pdata = pdata;
+-      platform_set_drvdata(pdev, data);
+-      mutex_init(&data->lock);
+-
+-      ret = exynos_tmu_initialize(pdev);
+-      if (ret) {
+-              dev_err(&pdev->dev, "Failed to initialize TMU\n");
+-              goto err_clk;
+-      }
+-
+-      exynos_tmu_control(pdev, true);
+-
+-      /* Register the sensor with thermal management interface */
+-      (&exynos_sensor_conf)->private_data = data;
+-      exynos_sensor_conf.trip_data.trip_count = pdata->trigger_level0_en +
+-                      pdata->trigger_level1_en + pdata->trigger_level2_en +
+-                      pdata->trigger_level3_en;
+-
+-      for (i = 0; i < exynos_sensor_conf.trip_data.trip_count; i++)
+-              exynos_sensor_conf.trip_data.trip_val[i] =
+-                      pdata->threshold + pdata->trigger_levels[i];
+-
+-      exynos_sensor_conf.trip_data.trigger_falling = pdata->threshold_falling;
+-
+-      exynos_sensor_conf.cooling_data.freq_clip_count =
+-                                              pdata->freq_tab_count;
+-      for (i = 0; i < pdata->freq_tab_count; i++) {
+-              exynos_sensor_conf.cooling_data.freq_data[i].freq_clip_max =
+-                                      pdata->freq_tab[i].freq_clip_max;
+-              exynos_sensor_conf.cooling_data.freq_data[i].temp_level =
+-                                      pdata->freq_tab[i].temp_level;
+-      }
+-
+-      ret = exynos_register_thermal(&exynos_sensor_conf);
+-      if (ret) {
+-              dev_err(&pdev->dev, "Failed to register thermal interface\n");
+-              goto err_clk;
+-      }
+-
+-      return 0;
+-err_clk:
+-      clk_unprepare(data->clk);
+-      return ret;
+-}
+-
+-static int exynos_tmu_remove(struct platform_device *pdev)
+-{
+-      struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+-
+-      exynos_tmu_control(pdev, false);
+-
+-      exynos_unregister_thermal();
+-
+-      clk_unprepare(data->clk);
+-
+-      return 0;
+-}
+-
+-#ifdef CONFIG_PM_SLEEP
+-static int exynos_tmu_suspend(struct device *dev)
+-{
+-      exynos_tmu_control(to_platform_device(dev), false);
+-
+-      return 0;
+-}
+-
+-static int exynos_tmu_resume(struct device *dev)
+-{
+-      struct platform_device *pdev = to_platform_device(dev);
+-
+-      exynos_tmu_initialize(pdev);
+-      exynos_tmu_control(pdev, true);
+-
+-      return 0;
+-}
+-
+-static SIMPLE_DEV_PM_OPS(exynos_tmu_pm,
+-                       exynos_tmu_suspend, exynos_tmu_resume);
+-#define EXYNOS_TMU_PM (&exynos_tmu_pm)
+-#else
+-#define EXYNOS_TMU_PM NULL
+-#endif
+-
+-static struct platform_driver exynos_tmu_driver = {
+-      .driver = {
+-              .name   = "exynos-tmu",
+-              .owner  = THIS_MODULE,
+-              .pm     = EXYNOS_TMU_PM,
+-              .of_match_table = of_match_ptr(exynos_tmu_match),
+-      },
+-      .probe = exynos_tmu_probe,
+-      .remove = exynos_tmu_remove,
+-      .id_table = exynos_tmu_driver_ids,
+-};
+-
+-module_platform_driver(exynos_tmu_driver);
+-
+-MODULE_DESCRIPTION("EXYNOS TMU Driver");
+-MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
+-MODULE_LICENSE("GPL");
+-MODULE_ALIAS("platform:exynos-tmu");
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+new file mode 100644
+index 0000000..2b2cc33
+--- /dev/null
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -0,0 +1,652 @@
++/*
++ * exynos_tmu.c - Samsung EXYNOS TMU (Thermal Management Unit)
++ *
++ *  Copyright (C) 2011 Samsung Electronics
++ *  Donggeun Kim <dg77.kim@samsung.com>
++ *  Amit Daniel Kachhap <amit.kachhap@linaro.org>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
++ */
++
++#include <linux/clk.h>
++#include <linux/io.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/platform_data/exynos_thermal.h>
++
++#include "exynos_thermal_common.h"
++
++/* Exynos generic registers */
++#define EXYNOS_TMU_REG_TRIMINFO               0x0
++#define EXYNOS_TMU_REG_CONTROL                0x20
++#define EXYNOS_TMU_REG_STATUS         0x28
++#define EXYNOS_TMU_REG_CURRENT_TEMP   0x40
++#define EXYNOS_TMU_REG_INTEN          0x70
++#define EXYNOS_TMU_REG_INTSTAT                0x74
++#define EXYNOS_TMU_REG_INTCLEAR               0x78
++
++#define EXYNOS_TMU_TRIM_TEMP_MASK     0xff
++#define EXYNOS_TMU_GAIN_SHIFT         8
++#define EXYNOS_TMU_REF_VOLTAGE_SHIFT  24
++#define EXYNOS_TMU_CORE_ON            3
++#define EXYNOS_TMU_CORE_OFF           2
++#define EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET    50
++
++/* Exynos4210 specific registers */
++#define EXYNOS4210_TMU_REG_THRESHOLD_TEMP     0x44
++#define EXYNOS4210_TMU_REG_TRIG_LEVEL0        0x50
++#define EXYNOS4210_TMU_REG_TRIG_LEVEL1        0x54
++#define EXYNOS4210_TMU_REG_TRIG_LEVEL2        0x58
++#define EXYNOS4210_TMU_REG_TRIG_LEVEL3        0x5C
++#define EXYNOS4210_TMU_REG_PAST_TEMP0 0x60
++#define EXYNOS4210_TMU_REG_PAST_TEMP1 0x64
++#define EXYNOS4210_TMU_REG_PAST_TEMP2 0x68
++#define EXYNOS4210_TMU_REG_PAST_TEMP3 0x6C
++
++#define EXYNOS4210_TMU_TRIG_LEVEL0_MASK       0x1
++#define EXYNOS4210_TMU_TRIG_LEVEL1_MASK       0x10
++#define EXYNOS4210_TMU_TRIG_LEVEL2_MASK       0x100
++#define EXYNOS4210_TMU_TRIG_LEVEL3_MASK       0x1000
++#define EXYNOS4210_TMU_INTCLEAR_VAL   0x1111
++
++/* Exynos5250 and Exynos4412 specific registers */
++#define EXYNOS_TMU_TRIMINFO_CON       0x14
++#define EXYNOS_THD_TEMP_RISE          0x50
++#define EXYNOS_THD_TEMP_FALL          0x54
++#define EXYNOS_EMUL_CON               0x80
++
++#define EXYNOS_TRIMINFO_RELOAD                0x1
++#define EXYNOS_TMU_CLEAR_RISE_INT     0x111
++#define EXYNOS_TMU_CLEAR_FALL_INT     (0x111 << 12)
++#define EXYNOS_MUX_ADDR_VALUE         6
++#define EXYNOS_MUX_ADDR_SHIFT         20
++#define EXYNOS_TMU_TRIP_MODE_SHIFT    13
++
++#define EFUSE_MIN_VALUE 40
++#define EFUSE_MAX_VALUE 100
++
++#ifdef CONFIG_THERMAL_EMULATION
++#define EXYNOS_EMUL_TIME      0x57F0
++#define EXYNOS_EMUL_TIME_SHIFT        16
++#define EXYNOS_EMUL_DATA_SHIFT        8
++#define EXYNOS_EMUL_DATA_MASK 0xFF
++#define EXYNOS_EMUL_ENABLE    0x1
++#endif /* CONFIG_THERMAL_EMULATION */
++
++struct exynos_tmu_data {
++      struct exynos_tmu_platform_data *pdata;
++      struct resource *mem;
++      void __iomem *base;
++      int irq;
++      enum soc_type soc;
++      struct work_struct irq_work;
++      struct mutex lock;
++      struct clk *clk;
++      u8 temp_error1, temp_error2;
++};
++
++/*
++ * TMU treats temperature as a mapped temperature code.
++ * The temperature is converted differently depending on the calibration type.
++ */
++static int temp_to_code(struct exynos_tmu_data *data, u8 temp)
++{
++      struct exynos_tmu_platform_data *pdata = data->pdata;
++      int temp_code;
++
++      if (data->soc == SOC_ARCH_EXYNOS4210)
++              /* temp should range between 25 and 125 */
++              if (temp < 25 || temp > 125) {
++                      temp_code = -EINVAL;
++                      goto out;
++              }
++
++      switch (pdata->cal_type) {
++      case TYPE_TWO_POINT_TRIMMING:
++              temp_code = (temp - 25) *
++                  (data->temp_error2 - data->temp_error1) /
++                  (85 - 25) + data->temp_error1;
++              break;
++      case TYPE_ONE_POINT_TRIMMING:
++              temp_code = temp + data->temp_error1 - 25;
++              break;
++      default:
++              temp_code = temp + EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET;
++              break;
++      }
++out:
++      return temp_code;
++}
++
++/*
++ * Calculate a temperature value from a temperature code.
++ * The unit of the temperature is degree Celsius.
++ */
++static int code_to_temp(struct exynos_tmu_data *data, u8 temp_code)
++{
++      struct exynos_tmu_platform_data *pdata = data->pdata;
++      int temp;
++
++      if (data->soc == SOC_ARCH_EXYNOS4210)
++              /* temp_code should range between 75 and 175 */
++              if (temp_code < 75 || temp_code > 175) {
++                      temp = -ENODATA;
++                      goto out;
++              }
++
++      switch (pdata->cal_type) {
++      case TYPE_TWO_POINT_TRIMMING:
++              temp = (temp_code - data->temp_error1) * (85 - 25) /
++                  (data->temp_error2 - data->temp_error1) + 25;
++              break;
++      case TYPE_ONE_POINT_TRIMMING:
++              temp = temp_code - data->temp_error1 + 25;
++              break;
++      default:
++              temp = temp_code - EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET;
++              break;
++      }
++out:
++      return temp;
++}
++
++static int exynos_tmu_initialize(struct platform_device *pdev)
++{
++      struct exynos_tmu_data *data = platform_get_drvdata(pdev);
++      struct exynos_tmu_platform_data *pdata = data->pdata;
++      unsigned int status, trim_info;
++      unsigned int rising_threshold = 0, falling_threshold = 0;
++      int ret = 0, threshold_code, i, trigger_levs = 0;
++
++      mutex_lock(&data->lock);
++      clk_enable(data->clk);
++
++      status = readb(data->base + EXYNOS_TMU_REG_STATUS);
++      if (!status) {
++              ret = -EBUSY;
++              goto out;
++      }
++
++      if (data->soc == SOC_ARCH_EXYNOS) {
++              __raw_writel(EXYNOS_TRIMINFO_RELOAD,
++                              data->base + EXYNOS_TMU_TRIMINFO_CON);
++      }
++      /* Save trimming info in order to perform calibration */
++      trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
++      data->temp_error1 = trim_info & EXYNOS_TMU_TRIM_TEMP_MASK;
++      data->temp_error2 = ((trim_info >> 8) & EXYNOS_TMU_TRIM_TEMP_MASK);
++
++      if ((EFUSE_MIN_VALUE > data->temp_error1) ||
++                      (data->temp_error1 > EFUSE_MAX_VALUE) ||
++                      (data->temp_error2 != 0))
++              data->temp_error1 = pdata->efuse_value;
++
++      /* Count trigger levels to be enabled */
++      for (i = 0; i < MAX_THRESHOLD_LEVS; i++)
++              if (pdata->trigger_levels[i])
++                      trigger_levs++;
++
++      if (data->soc == SOC_ARCH_EXYNOS4210) {
++              /* Write temperature code for threshold */
++              threshold_code = temp_to_code(data, pdata->threshold);
++              if (threshold_code < 0) {
++                      ret = threshold_code;
++                      goto out;
++              }
++              writeb(threshold_code,
++                      data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP);
++              for (i = 0; i < trigger_levs; i++)
++                      writeb(pdata->trigger_levels[i],
++                      data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + i * 4);
++
++              writel(EXYNOS4210_TMU_INTCLEAR_VAL,
++                      data->base + EXYNOS_TMU_REG_INTCLEAR);
++      } else if (data->soc == SOC_ARCH_EXYNOS) {
++              /* Write temperature code for rising and falling threshold */
++              for (i = 0; i < trigger_levs; i++) {
++                      threshold_code = temp_to_code(data,
++                                              pdata->trigger_levels[i]);
++                      if (threshold_code < 0) {
++                              ret = threshold_code;
++                              goto out;
++                      }
++                      rising_threshold |= threshold_code << 8 * i;
++                      if (pdata->threshold_falling) {
++                              threshold_code = temp_to_code(data,
++                                              pdata->trigger_levels[i] -
++                                              pdata->threshold_falling);
++                              if (threshold_code > 0)
++                                      falling_threshold |=
++                                              threshold_code << 8 * i;
++                      }
++              }
++
++              writel(rising_threshold,
++                              data->base + EXYNOS_THD_TEMP_RISE);
++              writel(falling_threshold,
++                              data->base + EXYNOS_THD_TEMP_FALL);
++
++              writel(EXYNOS_TMU_CLEAR_RISE_INT | EXYNOS_TMU_CLEAR_FALL_INT,
++                              data->base + EXYNOS_TMU_REG_INTCLEAR);
++      }
++out:
++      clk_disable(data->clk);
++      mutex_unlock(&data->lock);
++
++      return ret;
++}
++
++static void exynos_tmu_control(struct platform_device *pdev, bool on)
++{
++      struct exynos_tmu_data *data = platform_get_drvdata(pdev);
++      struct exynos_tmu_platform_data *pdata = data->pdata;
++      unsigned int con, interrupt_en;
++
++      mutex_lock(&data->lock);
++      clk_enable(data->clk);
++
++      con = pdata->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT |
++              pdata->gain << EXYNOS_TMU_GAIN_SHIFT;
++
++      if (data->soc == SOC_ARCH_EXYNOS) {
++              con |= pdata->noise_cancel_mode << EXYNOS_TMU_TRIP_MODE_SHIFT;
++              con |= (EXYNOS_MUX_ADDR_VALUE << EXYNOS_MUX_ADDR_SHIFT);
++      }
++
++      if (on) {
++              con |= EXYNOS_TMU_CORE_ON;
++              interrupt_en = pdata->trigger_level3_en << 12 |
++                      pdata->trigger_level2_en << 8 |
++                      pdata->trigger_level1_en << 4 |
++                      pdata->trigger_level0_en;
++              if (pdata->threshold_falling)
++                      interrupt_en |= interrupt_en << 16;
++      } else {
++              con |= EXYNOS_TMU_CORE_OFF;
++              interrupt_en = 0; /* Disable all interrupts */
++      }
++      writel(interrupt_en, data->base + EXYNOS_TMU_REG_INTEN);
++      writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
++
++      clk_disable(data->clk);
++      mutex_unlock(&data->lock);
++}
++
++static int exynos_tmu_read(struct exynos_tmu_data *data)
++{
++      u8 temp_code;
++      int temp;
++
++      mutex_lock(&data->lock);
++      clk_enable(data->clk);
++
++      temp_code = readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP);
++      temp = code_to_temp(data, temp_code);
++
++      clk_disable(data->clk);
++      mutex_unlock(&data->lock);
++
++      return temp;
++}
++
++#ifdef CONFIG_THERMAL_EMULATION
++static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp)
++{
++      struct exynos_tmu_data *data = drv_data;
++      unsigned int reg;
++      int ret = -EINVAL;
++
++      if (data->soc == SOC_ARCH_EXYNOS4210)
++              goto out;
++
++      if (temp && temp < MCELSIUS)
++              goto out;
++
++      mutex_lock(&data->lock);
++      clk_enable(data->clk);
++
++      reg = readl(data->base + EXYNOS_EMUL_CON);
++
++      if (temp) {
++              temp /= MCELSIUS;
++
++              reg = (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT) |
++                      (temp_to_code(data, temp)
++                       << EXYNOS_EMUL_DATA_SHIFT) | EXYNOS_EMUL_ENABLE;
++      } else {
++              reg &= ~EXYNOS_EMUL_ENABLE;
++      }
++
++      writel(reg, data->base + EXYNOS_EMUL_CON);
++
++      clk_disable(data->clk);
++      mutex_unlock(&data->lock);
++      return 0;
++out:
++      return ret;
++}
++#else
++static int exynos_tmu_set_emulation(void *drv_data,   unsigned long temp)
++      { return -EINVAL; }
++#endif/*CONFIG_THERMAL_EMULATION*/
++
++static void exynos_tmu_work(struct work_struct *work)
++{
++      struct exynos_tmu_data *data = container_of(work,
++                      struct exynos_tmu_data, irq_work);
++
++      exynos_report_trigger();
++      mutex_lock(&data->lock);
++      clk_enable(data->clk);
++      if (data->soc == SOC_ARCH_EXYNOS)
++              writel(EXYNOS_TMU_CLEAR_RISE_INT |
++                              EXYNOS_TMU_CLEAR_FALL_INT,
++                              data->base + EXYNOS_TMU_REG_INTCLEAR);
++      else
++              writel(EXYNOS4210_TMU_INTCLEAR_VAL,
++                              data->base + EXYNOS_TMU_REG_INTCLEAR);
++      clk_disable(data->clk);
++      mutex_unlock(&data->lock);
++
++      enable_irq(data->irq);
++}
++
++static irqreturn_t exynos_tmu_irq(int irq, void *id)
++{
++      struct exynos_tmu_data *data = id;
++
++      disable_irq_nosync(irq);
++      schedule_work(&data->irq_work);
++
++      return IRQ_HANDLED;
++}
++static struct thermal_sensor_conf exynos_sensor_conf = {
++      .name                   = "exynos-therm",
++      .read_temperature       = (int (*)(void *))exynos_tmu_read,
++      .write_emul_temp        = exynos_tmu_set_emulation,
++};
++
++#if defined(CONFIG_CPU_EXYNOS4210)
++static struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
++      .threshold = 80,
++      .trigger_levels[0] = 5,
++      .trigger_levels[1] = 20,
++      .trigger_levels[2] = 30,
++      .trigger_level0_en = 1,
++      .trigger_level1_en = 1,
++      .trigger_level2_en = 1,
++      .trigger_level3_en = 0,
++      .gain = 15,
++      .reference_voltage = 7,
++      .cal_type = TYPE_ONE_POINT_TRIMMING,
++      .freq_tab[0] = {
++              .freq_clip_max = 800 * 1000,
++              .temp_level = 85,
++      },
++      .freq_tab[1] = {
++              .freq_clip_max = 200 * 1000,
++              .temp_level = 100,
++      },
++      .freq_tab_count = 2,
++      .type = SOC_ARCH_EXYNOS4210,
++};
++#define EXYNOS4210_TMU_DRV_DATA (&exynos4210_default_tmu_data)
++#else
++#define EXYNOS4210_TMU_DRV_DATA (NULL)
++#endif
++
++#if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412) || \
++      defined(CONFIG_SOC_EXYNOS4212)
++static struct exynos_tmu_platform_data const exynos_default_tmu_data = {
++      .threshold_falling = 10,
++      .trigger_levels[0] = 85,
++      .trigger_levels[1] = 103,
++      .trigger_levels[2] = 110,
++      .trigger_level0_en = 1,
++      .trigger_level1_en = 1,
++      .trigger_level2_en = 1,
++      .trigger_level3_en = 0,
++      .gain = 8,
++      .reference_voltage = 16,
++      .noise_cancel_mode = 4,
++      .cal_type = TYPE_ONE_POINT_TRIMMING,
++      .efuse_value = 55,
++      .freq_tab[0] = {
++              .freq_clip_max = 800 * 1000,
++              .temp_level = 85,
++      },
++      .freq_tab[1] = {
++              .freq_clip_max = 200 * 1000,
++              .temp_level = 103,
++      },
++      .freq_tab_count = 2,
++      .type = SOC_ARCH_EXYNOS,
++};
++#define EXYNOS_TMU_DRV_DATA (&exynos_default_tmu_data)
++#else
++#define EXYNOS_TMU_DRV_DATA (NULL)
++#endif
++
++#ifdef CONFIG_OF
++static const struct of_device_id exynos_tmu_match[] = {
++      {
++              .compatible = "samsung,exynos4210-tmu",
++              .data = (void *)EXYNOS4210_TMU_DRV_DATA,
++      },
++      {
++              .compatible = "samsung,exynos4412-tmu",
++              .data = (void *)EXYNOS_TMU_DRV_DATA,
++      },
++      {
++              .compatible = "samsung,exynos5250-tmu",
++              .data = (void *)EXYNOS_TMU_DRV_DATA,
++      },
++      {},
++};
++MODULE_DEVICE_TABLE(of, exynos_tmu_match);
++#endif
++
++static struct platform_device_id exynos_tmu_driver_ids[] = {
++      {
++              .name           = "exynos4210-tmu",
++              .driver_data    = (kernel_ulong_t)EXYNOS4210_TMU_DRV_DATA,
++      },
++      {
++              .name           = "exynos5250-tmu",
++              .driver_data    = (kernel_ulong_t)EXYNOS_TMU_DRV_DATA,
++      },
++      { },
++};
++MODULE_DEVICE_TABLE(platform, exynos_tmu_driver_ids);
++
++static inline struct  exynos_tmu_platform_data *exynos_get_driver_data(
++                      struct platform_device *pdev)
++{
++#ifdef CONFIG_OF
++      if (pdev->dev.of_node) {
++              const struct of_device_id *match;
++              match = of_match_node(exynos_tmu_match, pdev->dev.of_node);
++              if (!match)
++                      return NULL;
++              return (struct exynos_tmu_platform_data *) match->data;
++      }
++#endif
++      return (struct exynos_tmu_platform_data *)
++                      platform_get_device_id(pdev)->driver_data;
++}
++
++static int exynos_tmu_probe(struct platform_device *pdev)
++{
++      struct exynos_tmu_data *data;
++      struct exynos_tmu_platform_data *pdata = pdev->dev.platform_data;
++      int ret, i;
++
++      if (!pdata)
++              pdata = exynos_get_driver_data(pdev);
++
++      if (!pdata) {
++              dev_err(&pdev->dev, "No platform init data supplied.\n");
++              return -ENODEV;
++      }
++      data = devm_kzalloc(&pdev->dev, sizeof(struct exynos_tmu_data),
++                                      GFP_KERNEL);
++      if (!data) {
++              dev_err(&pdev->dev, "Failed to allocate driver structure\n");
++              return -ENOMEM;
++      }
++
++      data->irq = platform_get_irq(pdev, 0);
++      if (data->irq < 0) {
++              dev_err(&pdev->dev, "Failed to get platform irq\n");
++              return data->irq;
++      }
++
++      INIT_WORK(&data->irq_work, exynos_tmu_work);
++
++      data->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      data->base = devm_ioremap_resource(&pdev->dev, data->mem);
++      if (IS_ERR(data->base))
++              return PTR_ERR(data->base);
++
++      ret = devm_request_irq(&pdev->dev, data->irq, exynos_tmu_irq,
++              IRQF_TRIGGER_RISING, "exynos-tmu", data);
++      if (ret) {
++              dev_err(&pdev->dev, "Failed to request irq: %d\n", data->irq);
++              return ret;
++      }
++
++      data->clk = devm_clk_get(&pdev->dev, "tmu_apbif");
++      if (IS_ERR(data->clk)) {
++              dev_err(&pdev->dev, "Failed to get clock\n");
++              return  PTR_ERR(data->clk);
++      }
++
++      ret = clk_prepare(data->clk);
++      if (ret)
++              return ret;
++
++      if (pdata->type == SOC_ARCH_EXYNOS ||
++                              pdata->type == SOC_ARCH_EXYNOS4210)
++              data->soc = pdata->type;
++      else {
++              ret = -EINVAL;
++              dev_err(&pdev->dev, "Platform not supported\n");
++              goto err_clk;
++      }
++
++      data->pdata = pdata;
++      platform_set_drvdata(pdev, data);
++      mutex_init(&data->lock);
++
++      ret = exynos_tmu_initialize(pdev);
++      if (ret) {
++              dev_err(&pdev->dev, "Failed to initialize TMU\n");
++              goto err_clk;
++      }
++
++      exynos_tmu_control(pdev, true);
++
++      /* Register the sensor with thermal management interface */
++      (&exynos_sensor_conf)->private_data = data;
++      exynos_sensor_conf.trip_data.trip_count = pdata->trigger_level0_en +
++                      pdata->trigger_level1_en + pdata->trigger_level2_en +
++                      pdata->trigger_level3_en;
++
++      for (i = 0; i < exynos_sensor_conf.trip_data.trip_count; i++)
++              exynos_sensor_conf.trip_data.trip_val[i] =
++                      pdata->threshold + pdata->trigger_levels[i];
++
++      exynos_sensor_conf.trip_data.trigger_falling = pdata->threshold_falling;
++
++      exynos_sensor_conf.cooling_data.freq_clip_count =
++                                              pdata->freq_tab_count;
++      for (i = 0; i < pdata->freq_tab_count; i++) {
++              exynos_sensor_conf.cooling_data.freq_data[i].freq_clip_max =
++                                      pdata->freq_tab[i].freq_clip_max;
++              exynos_sensor_conf.cooling_data.freq_data[i].temp_level =
++                                      pdata->freq_tab[i].temp_level;
++      }
++
++      ret = exynos_register_thermal(&exynos_sensor_conf);
++      if (ret) {
++              dev_err(&pdev->dev, "Failed to register thermal interface\n");
++              goto err_clk;
++      }
++
++      return 0;
++err_clk:
++      clk_unprepare(data->clk);
++      return ret;
++}
++
++static int exynos_tmu_remove(struct platform_device *pdev)
++{
++      struct exynos_tmu_data *data = platform_get_drvdata(pdev);
++
++      exynos_tmu_control(pdev, false);
++
++      exynos_unregister_thermal();
++
++      clk_unprepare(data->clk);
++
++      return 0;
++}
++
++#ifdef CONFIG_PM_SLEEP
++static int exynos_tmu_suspend(struct device *dev)
++{
++      exynos_tmu_control(to_platform_device(dev), false);
++
++      return 0;
++}
++
++static int exynos_tmu_resume(struct device *dev)
++{
++      struct platform_device *pdev = to_platform_device(dev);
++
++      exynos_tmu_initialize(pdev);
++      exynos_tmu_control(pdev, true);
++
++      return 0;
++}
++
++static SIMPLE_DEV_PM_OPS(exynos_tmu_pm,
++                       exynos_tmu_suspend, exynos_tmu_resume);
++#define EXYNOS_TMU_PM (&exynos_tmu_pm)
++#else
++#define EXYNOS_TMU_PM NULL
++#endif
++
++static struct platform_driver exynos_tmu_driver = {
++      .driver = {
++              .name   = "exynos-tmu",
++              .owner  = THIS_MODULE,
++              .pm     = EXYNOS_TMU_PM,
++              .of_match_table = of_match_ptr(exynos_tmu_match),
++      },
++      .probe = exynos_tmu_probe,
++      .remove = exynos_tmu_remove,
++      .id_table = exynos_tmu_driver_ids,
++};
++
++module_platform_driver(exynos_tmu_driver);
++
++MODULE_DESCRIPTION("EXYNOS TMU Driver");
++MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:exynos-tmu");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0956-thermal-exynos-Move-exynos_thermal.h-from-include-to.patch b/patches.tizen/0956-thermal-exynos-Move-exynos_thermal.h-from-include-to.patch
new file mode 100644 (file)
index 0000000..ea5e2c5
--- /dev/null
@@ -0,0 +1,198 @@
+From c919aee0d77c3651f16fce7741cff100b1cdf24b Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Mon, 24 Jun 2013 16:20:27 +0530
+Subject: [PATCH 0956/1302] thermal: exynos: Move exynos_thermal.h from
+ include/* to driver/* folder
+
+This patch renames and moves include/linux/platform_data/exynos_thermal.h to
+drivers/thermal/samsung/exynos_tmu.h. This file movement is needed as exynos
+SOC's are not supporting non-DT based platforms and this file now just contains
+exynos tmu driver related definations.
+Also struct freq_clip_table is now moved to exynos_thermal_common.c as it fixes
+the compilation issue occuring because now this new tmu header file is included
+in tmu driver c file and not in the common thermal header file.
+
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_thermal_common.c |   1 -
+ drivers/thermal/samsung/exynos_thermal_common.h |  16 ++++
+ drivers/thermal/samsung/exynos_tmu.c            |   2 +-
+ drivers/thermal/samsung/exynos_tmu.h            | 107 ++++++++++++++++++++++++
+ 4 files changed, 124 insertions(+), 2 deletions(-)
+ create mode 100644 drivers/thermal/samsung/exynos_tmu.h
+
+diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c
+index f20f458..c9edc30 100644
+--- a/drivers/thermal/samsung/exynos_thermal_common.c
++++ b/drivers/thermal/samsung/exynos_thermal_common.c
+@@ -22,7 +22,6 @@
+ #include <linux/cpu_cooling.h>
+ #include <linux/err.h>
+-#include <linux/platform_data/exynos_thermal.h>
+ #include <linux/slab.h>
+ #include <linux/thermal.h>
+diff --git a/drivers/thermal/samsung/exynos_thermal_common.h b/drivers/thermal/samsung/exynos_thermal_common.h
+index 8df1848..57ce33b 100644
+--- a/drivers/thermal/samsung/exynos_thermal_common.h
++++ b/drivers/thermal/samsung/exynos_thermal_common.h
+@@ -44,6 +44,22 @@
+ #define EXYNOS_ZONE_COUNT     3
++/**
++ * struct freq_clip_table
++ * @freq_clip_max: maximum frequency allowed for this cooling state.
++ * @temp_level: Temperature level at which the temperature clipping will
++ *    happen.
++ * @mask_val: cpumask of the allowed cpu's where the clipping will take place.
++ *
++ * This structure is required to be filled and passed to the
++ * cpufreq_cooling_unregister function.
++ */
++struct freq_clip_table {
++      unsigned int freq_clip_max;
++      unsigned int temp_level;
++      const struct cpumask *mask_val;
++};
++
+ struct        thermal_trip_point_conf {
+       int trip_val[MAX_TRIP_COUNT];
+       int trip_count;
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+index 2b2cc33..568c31d 100644
+--- a/drivers/thermal/samsung/exynos_tmu.c
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -27,9 +27,9 @@
+ #include <linux/module.h>
+ #include <linux/of.h>
+ #include <linux/platform_device.h>
+-#include <linux/platform_data/exynos_thermal.h>
+ #include "exynos_thermal_common.h"
++#include "exynos_tmu.h"
+ /* Exynos generic registers */
+ #define EXYNOS_TMU_REG_TRIMINFO               0x0
+diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h
+new file mode 100644
+index 0000000..1857609
+--- /dev/null
++++ b/drivers/thermal/samsung/exynos_tmu.h
+@@ -0,0 +1,107 @@
++/*
++ * exynos_tmu.h - Samsung EXYNOS TMU (Thermal Management Unit)
++ *
++ *  Copyright (C) 2011 Samsung Electronics
++ *  Donggeun Kim <dg77.kim@samsung.com>
++ *  Amit Daniel Kachhap <amit.daniel@samsung.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ */
++
++#ifndef _EXYNOS_TMU_H
++#define _EXYNOS_TMU_H
++#include <linux/cpu_cooling.h>
++
++#include "exynos_thermal_common.h"
++
++enum calibration_type {
++      TYPE_ONE_POINT_TRIMMING,
++      TYPE_TWO_POINT_TRIMMING,
++      TYPE_NONE,
++};
++
++enum soc_type {
++      SOC_ARCH_EXYNOS4210 = 1,
++      SOC_ARCH_EXYNOS,
++};
++
++/**
++ * struct exynos_tmu_platform_data
++ * @threshold: basic temperature for generating interrupt
++ *           25 <= threshold <= 125 [unit: degree Celsius]
++ * @threshold_falling: differntial value for setting threshold
++ *                   of temperature falling interrupt.
++ * @trigger_levels: array for each interrupt levels
++ *    [unit: degree Celsius]
++ *    0: temperature for trigger_level0 interrupt
++ *       condition for trigger_level0 interrupt:
++ *            current temperature > threshold + trigger_levels[0]
++ *    1: temperature for trigger_level1 interrupt
++ *       condition for trigger_level1 interrupt:
++ *            current temperature > threshold + trigger_levels[1]
++ *    2: temperature for trigger_level2 interrupt
++ *       condition for trigger_level2 interrupt:
++ *            current temperature > threshold + trigger_levels[2]
++ *    3: temperature for trigger_level3 interrupt
++ *       condition for trigger_level3 interrupt:
++ *            current temperature > threshold + trigger_levels[3]
++ * @trigger_level0_en:
++ *    1 = enable trigger_level0 interrupt,
++ *    0 = disable trigger_level0 interrupt
++ * @trigger_level1_en:
++ *    1 = enable trigger_level1 interrupt,
++ *    0 = disable trigger_level1 interrupt
++ * @trigger_level2_en:
++ *    1 = enable trigger_level2 interrupt,
++ *    0 = disable trigger_level2 interrupt
++ * @trigger_level3_en:
++ *    1 = enable trigger_level3 interrupt,
++ *    0 = disable trigger_level3 interrupt
++ * @gain: gain of amplifier in the positive-TC generator block
++ *    0 <= gain <= 15
++ * @reference_voltage: reference voltage of amplifier
++ *    in the positive-TC generator block
++ *    0 <= reference_voltage <= 31
++ * @noise_cancel_mode: noise cancellation mode
++ *    000, 100, 101, 110 and 111 can be different modes
++ * @type: determines the type of SOC
++ * @efuse_value: platform defined fuse value
++ * @cal_type: calibration type for temperature
++ * @freq_clip_table: Table representing frequency reduction percentage.
++ * @freq_tab_count: Count of the above table as frequency reduction may
++ *    applicable to only some of the trigger levels.
++ *
++ * This structure is required for configuration of exynos_tmu driver.
++ */
++struct exynos_tmu_platform_data {
++      u8 threshold;
++      u8 threshold_falling;
++      u8 trigger_levels[4];
++      bool trigger_level0_en;
++      bool trigger_level1_en;
++      bool trigger_level2_en;
++      bool trigger_level3_en;
++
++      u8 gain;
++      u8 reference_voltage;
++      u8 noise_cancel_mode;
++      u32 efuse_value;
++
++      enum calibration_type cal_type;
++      enum soc_type type;
++      struct freq_clip_table freq_tab[4];
++      unsigned int freq_tab_count;
++};
++#endif /* _EXYNOS_TMU_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0957-thermal-exynos-Bifurcate-exynos-tmu-driver-and-confi.patch b/patches.tizen/0957-thermal-exynos-Bifurcate-exynos-tmu-driver-and-confi.patch
new file mode 100644 (file)
index 0000000..68890da
--- /dev/null
@@ -0,0 +1,286 @@
+From e429d5728123eecee917d47cc71248afbd67ef9f Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Mon, 24 Jun 2013 16:20:28 +0530
+Subject: [PATCH 0957/1302] thermal: exynos: Bifurcate exynos tmu driver and
+ configuration data
+
+This code splits the exynos tmu driver code into SOC specific data parts.
+This will simplify adding new SOC specific data to the same TMU controller.
+
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/Kconfig           |  3 +-
+ drivers/thermal/samsung/Makefile          |  1 +
+ drivers/thermal/samsung/exynos_tmu.c      | 68 ++------------------------
+ drivers/thermal/samsung/exynos_tmu_data.c | 79 +++++++++++++++++++++++++++++++
+ drivers/thermal/samsung/exynos_tmu_data.h | 40 ++++++++++++++++
+ 5 files changed, 126 insertions(+), 65 deletions(-)
+ create mode 100644 drivers/thermal/samsung/exynos_tmu_data.c
+ create mode 100644 drivers/thermal/samsung/exynos_tmu_data.h
+
+diff --git a/drivers/thermal/samsung/Kconfig b/drivers/thermal/samsung/Kconfig
+index f8100b1..b653f15 100644
+--- a/drivers/thermal/samsung/Kconfig
++++ b/drivers/thermal/samsung/Kconfig
+@@ -5,7 +5,8 @@ config EXYNOS_THERMAL
+         If you say yes here you get support for the TMU (Thermal Management
+         Unit) driver for SAMSUNG EXYNOS series of soc. This driver initialises
+         the TMU, reports temperature and handles cooling action if defined.
+-        This driver uses the exynos core thermal API's.
++        This driver uses the exynos core thermal API's and TMU configuration
++        data from the supported soc's.
+ config EXYNOS_THERMAL_CORE
+       bool "Core thermal framework support for EXYNOS SOC's"
+diff --git a/drivers/thermal/samsung/Makefile b/drivers/thermal/samsung/Makefile
+index 22528d6..c09d830 100644
+--- a/drivers/thermal/samsung/Makefile
++++ b/drivers/thermal/samsung/Makefile
+@@ -3,4 +3,5 @@
+ #
+ obj-$(CONFIG_EXYNOS_THERMAL)                  += exynos_thermal.o
+ exynos_thermal-y                              := exynos_tmu.o
++exynos_thermal-y                              += exynos_tmu_data.o
+ exynos_thermal-$(CONFIG_EXYNOS_THERMAL_CORE)  += exynos_thermal_common.o
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+index 568c31d..5df04a1 100644
+--- a/drivers/thermal/samsung/exynos_tmu.c
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -30,6 +30,7 @@
+ #include "exynos_thermal_common.h"
+ #include "exynos_tmu.h"
++#include "exynos_tmu_data.h"
+ /* Exynos generic registers */
+ #define EXYNOS_TMU_REG_TRIMINFO               0x0
+@@ -381,67 +382,6 @@ static struct thermal_sensor_conf exynos_sensor_conf = {
+       .write_emul_temp        = exynos_tmu_set_emulation,
+ };
+-#if defined(CONFIG_CPU_EXYNOS4210)
+-static struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
+-      .threshold = 80,
+-      .trigger_levels[0] = 5,
+-      .trigger_levels[1] = 20,
+-      .trigger_levels[2] = 30,
+-      .trigger_level0_en = 1,
+-      .trigger_level1_en = 1,
+-      .trigger_level2_en = 1,
+-      .trigger_level3_en = 0,
+-      .gain = 15,
+-      .reference_voltage = 7,
+-      .cal_type = TYPE_ONE_POINT_TRIMMING,
+-      .freq_tab[0] = {
+-              .freq_clip_max = 800 * 1000,
+-              .temp_level = 85,
+-      },
+-      .freq_tab[1] = {
+-              .freq_clip_max = 200 * 1000,
+-              .temp_level = 100,
+-      },
+-      .freq_tab_count = 2,
+-      .type = SOC_ARCH_EXYNOS4210,
+-};
+-#define EXYNOS4210_TMU_DRV_DATA (&exynos4210_default_tmu_data)
+-#else
+-#define EXYNOS4210_TMU_DRV_DATA (NULL)
+-#endif
+-
+-#if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412) || \
+-      defined(CONFIG_SOC_EXYNOS4212)
+-static struct exynos_tmu_platform_data const exynos_default_tmu_data = {
+-      .threshold_falling = 10,
+-      .trigger_levels[0] = 85,
+-      .trigger_levels[1] = 103,
+-      .trigger_levels[2] = 110,
+-      .trigger_level0_en = 1,
+-      .trigger_level1_en = 1,
+-      .trigger_level2_en = 1,
+-      .trigger_level3_en = 0,
+-      .gain = 8,
+-      .reference_voltage = 16,
+-      .noise_cancel_mode = 4,
+-      .cal_type = TYPE_ONE_POINT_TRIMMING,
+-      .efuse_value = 55,
+-      .freq_tab[0] = {
+-              .freq_clip_max = 800 * 1000,
+-              .temp_level = 85,
+-      },
+-      .freq_tab[1] = {
+-              .freq_clip_max = 200 * 1000,
+-              .temp_level = 103,
+-      },
+-      .freq_tab_count = 2,
+-      .type = SOC_ARCH_EXYNOS,
+-};
+-#define EXYNOS_TMU_DRV_DATA (&exynos_default_tmu_data)
+-#else
+-#define EXYNOS_TMU_DRV_DATA (NULL)
+-#endif
+-
+ #ifdef CONFIG_OF
+ static const struct of_device_id exynos_tmu_match[] = {
+       {
+@@ -450,11 +390,11 @@ static const struct of_device_id exynos_tmu_match[] = {
+       },
+       {
+               .compatible = "samsung,exynos4412-tmu",
+-              .data = (void *)EXYNOS_TMU_DRV_DATA,
++              .data = (void *)EXYNOS5250_TMU_DRV_DATA,
+       },
+       {
+               .compatible = "samsung,exynos5250-tmu",
+-              .data = (void *)EXYNOS_TMU_DRV_DATA,
++              .data = (void *)EXYNOS5250_TMU_DRV_DATA,
+       },
+       {},
+ };
+@@ -468,7 +408,7 @@ static struct platform_device_id exynos_tmu_driver_ids[] = {
+       },
+       {
+               .name           = "exynos5250-tmu",
+-              .driver_data    = (kernel_ulong_t)EXYNOS_TMU_DRV_DATA,
++              .driver_data    = (kernel_ulong_t)EXYNOS5250_TMU_DRV_DATA,
+       },
+       { },
+ };
+diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c
+new file mode 100644
+index 0000000..144ba44
+--- /dev/null
++++ b/drivers/thermal/samsung/exynos_tmu_data.c
+@@ -0,0 +1,79 @@
++/*
++ * exynos_tmu_data.c - Samsung EXYNOS tmu data file
++ *
++ *  Copyright (C) 2013 Samsung Electronics
++ *  Amit Daniel Kachhap <amit.daniel@samsung.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
++ */
++
++#include "exynos_thermal_common.h"
++#include "exynos_tmu.h"
++#include "exynos_tmu_data.h"
++
++#if defined(CONFIG_CPU_EXYNOS4210)
++struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
++      .threshold = 80,
++      .trigger_levels[0] = 5,
++      .trigger_levels[1] = 20,
++      .trigger_levels[2] = 30,
++      .trigger_level0_en = 1,
++      .trigger_level1_en = 1,
++      .trigger_level2_en = 1,
++      .trigger_level3_en = 0,
++      .gain = 15,
++      .reference_voltage = 7,
++      .cal_type = TYPE_ONE_POINT_TRIMMING,
++      .freq_tab[0] = {
++              .freq_clip_max = 800 * 1000,
++              .temp_level = 85,
++      },
++      .freq_tab[1] = {
++              .freq_clip_max = 200 * 1000,
++              .temp_level = 100,
++      },
++      .freq_tab_count = 2,
++      .type = SOC_ARCH_EXYNOS4210,
++};
++#endif
++
++#if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412)
++struct exynos_tmu_platform_data const exynos5250_default_tmu_data = {
++      .threshold_falling = 10,
++      .trigger_levels[0] = 85,
++      .trigger_levels[1] = 103,
++      .trigger_levels[2] = 110,
++      .trigger_level0_en = 1,
++      .trigger_level1_en = 1,
++      .trigger_level2_en = 1,
++      .trigger_level3_en = 0,
++      .gain = 8,
++      .reference_voltage = 16,
++      .noise_cancel_mode = 4,
++      .cal_type = TYPE_ONE_POINT_TRIMMING,
++      .efuse_value = 55,
++      .freq_tab[0] = {
++              .freq_clip_max = 800 * 1000,
++              .temp_level = 85,
++      },
++      .freq_tab[1] = {
++              .freq_clip_max = 200 * 1000,
++              .temp_level = 103,
++      },
++      .freq_tab_count = 2,
++      .type = SOC_ARCH_EXYNOS,
++};
++#endif
+diff --git a/drivers/thermal/samsung/exynos_tmu_data.h b/drivers/thermal/samsung/exynos_tmu_data.h
+new file mode 100644
+index 0000000..b7835fe
+--- /dev/null
++++ b/drivers/thermal/samsung/exynos_tmu_data.h
+@@ -0,0 +1,40 @@
++/*
++ * exynos_tmu_data.h - Samsung EXYNOS tmu data header file
++ *
++ *  Copyright (C) 2013 Samsung Electronics
++ *  Amit Daniel Kachhap <amit.daniel@samsung.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
++ */
++
++#ifndef _EXYNOS_TMU_DATA_H
++#define _EXYNOS_TMU_DATA_H
++
++#if defined(CONFIG_CPU_EXYNOS4210)
++extern struct exynos_tmu_platform_data const exynos4210_default_tmu_data;
++#define EXYNOS4210_TMU_DRV_DATA (&exynos4210_default_tmu_data)
++#else
++#define EXYNOS4210_TMU_DRV_DATA (NULL)
++#endif
++
++#if (defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412))
++extern struct exynos_tmu_platform_data const exynos5250_default_tmu_data;
++#define EXYNOS5250_TMU_DRV_DATA (&exynos5250_default_tmu_data)
++#else
++#define EXYNOS5250_TMU_DRV_DATA (NULL)
++#endif
++
++#endif /*_EXYNOS_TMU_DATA_H*/
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0958-thermal-exynos-Add-missing-definations-and-code-clea.patch b/patches.tizen/0958-thermal-exynos-Add-missing-definations-and-code-clea.patch
new file mode 100644 (file)
index 0000000..ca1c7ee
--- /dev/null
@@ -0,0 +1,134 @@
+From 0178d953a1236276a843e98e70b707d716681b9e Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Mon, 24 Jun 2013 16:20:29 +0530
+Subject: [PATCH 0958/1302] thermal: exynos: Add missing definations and code
+ cleanup
+
+This patch adds some extra register bitfield definations and cleans
+up the code to prepare for moving register macros and definations inside
+the TMU data section. In this code cleanup the TMU enable bit is correctly used
+as bit0 and bit1 is taken care which is reserve bit.
+
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_tmu.c | 62 ++++++++++++++++++++++++++----------
+ 1 file changed, 46 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+index 5df04a1..fa33a48 100644
+--- a/drivers/thermal/samsung/exynos_tmu.c
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -43,9 +43,12 @@
+ #define EXYNOS_TMU_TRIM_TEMP_MASK     0xff
+ #define EXYNOS_TMU_GAIN_SHIFT         8
++#define EXYNOS_TMU_GAIN_MASK          0xf
+ #define EXYNOS_TMU_REF_VOLTAGE_SHIFT  24
+-#define EXYNOS_TMU_CORE_ON            3
+-#define EXYNOS_TMU_CORE_OFF           2
++#define EXYNOS_TMU_REF_VOLTAGE_MASK   0x1f
++#define EXYNOS_TMU_BUF_SLOPE_SEL_MASK 0xf
++#define EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT        8
++#define EXYNOS_TMU_CORE_EN_SHIFT      0
+ #define EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET    50
+ /* Exynos4210 specific registers */
+@@ -63,6 +66,7 @@
+ #define EXYNOS4210_TMU_TRIG_LEVEL1_MASK       0x10
+ #define EXYNOS4210_TMU_TRIG_LEVEL2_MASK       0x100
+ #define EXYNOS4210_TMU_TRIG_LEVEL3_MASK       0x1000
++#define EXYNOS4210_TMU_TRIG_LEVEL_MASK        0x1111
+ #define EXYNOS4210_TMU_INTCLEAR_VAL   0x1111
+ /* Exynos5250 and Exynos4412 specific registers */
+@@ -72,17 +76,30 @@
+ #define EXYNOS_EMUL_CON               0x80
+ #define EXYNOS_TRIMINFO_RELOAD                0x1
++#define EXYNOS_TRIMINFO_SHIFT         0x0
++#define EXYNOS_TMU_RISE_INT_MASK      0x111
++#define EXYNOS_TMU_RISE_INT_SHIFT     0
++#define EXYNOS_TMU_FALL_INT_MASK      0x111
++#define EXYNOS_TMU_FALL_INT_SHIFT     12
+ #define EXYNOS_TMU_CLEAR_RISE_INT     0x111
+ #define EXYNOS_TMU_CLEAR_FALL_INT     (0x111 << 12)
+-#define EXYNOS_MUX_ADDR_VALUE         6
+-#define EXYNOS_MUX_ADDR_SHIFT         20
+ #define EXYNOS_TMU_TRIP_MODE_SHIFT    13
++#define EXYNOS_TMU_TRIP_MODE_MASK     0x7
++
++#define EXYNOS_TMU_INTEN_RISE0_SHIFT  0
++#define EXYNOS_TMU_INTEN_RISE1_SHIFT  4
++#define EXYNOS_TMU_INTEN_RISE2_SHIFT  8
++#define EXYNOS_TMU_INTEN_RISE3_SHIFT  12
++#define EXYNOS_TMU_INTEN_FALL0_SHIFT  16
++#define EXYNOS_TMU_INTEN_FALL1_SHIFT  20
++#define EXYNOS_TMU_INTEN_FALL2_SHIFT  24
+ #define EFUSE_MIN_VALUE 40
+ #define EFUSE_MAX_VALUE 100
+ #ifdef CONFIG_THERMAL_EMULATION
+ #define EXYNOS_EMUL_TIME      0x57F0
++#define EXYNOS_EMUL_TIME_MASK 0xffff
+ #define EXYNOS_EMUL_TIME_SHIFT        16
+ #define EXYNOS_EMUL_DATA_SHIFT        8
+ #define EXYNOS_EMUL_DATA_MASK 0xFF
+@@ -261,24 +278,37 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on)
+       mutex_lock(&data->lock);
+       clk_enable(data->clk);
+-      con = pdata->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT |
+-              pdata->gain << EXYNOS_TMU_GAIN_SHIFT;
++      con = readl(data->base + EXYNOS_TMU_REG_CONTROL);
+-      if (data->soc == SOC_ARCH_EXYNOS) {
+-              con |= pdata->noise_cancel_mode << EXYNOS_TMU_TRIP_MODE_SHIFT;
+-              con |= (EXYNOS_MUX_ADDR_VALUE << EXYNOS_MUX_ADDR_SHIFT);
++      if (pdata->reference_voltage) {
++              con &= ~(EXYNOS_TMU_REF_VOLTAGE_MASK <<
++                              EXYNOS_TMU_REF_VOLTAGE_SHIFT);
++              con |= pdata->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT;
++      }
++
++      if (pdata->gain) {
++              con &= ~(EXYNOS_TMU_GAIN_MASK << EXYNOS_TMU_GAIN_SHIFT);
++              con |= (pdata->gain << EXYNOS_TMU_GAIN_SHIFT);
++      }
++
++      if (pdata->noise_cancel_mode) {
++              con &= ~(EXYNOS_TMU_TRIP_MODE_MASK <<
++                                      EXYNOS_TMU_TRIP_MODE_SHIFT);
++              con |= (pdata->noise_cancel_mode << EXYNOS_TMU_TRIP_MODE_SHIFT);
+       }
+       if (on) {
+-              con |= EXYNOS_TMU_CORE_ON;
+-              interrupt_en = pdata->trigger_level3_en << 12 |
+-                      pdata->trigger_level2_en << 8 |
+-                      pdata->trigger_level1_en << 4 |
+-                      pdata->trigger_level0_en;
++              con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT);
++              interrupt_en =
++              pdata->trigger_level3_en << EXYNOS_TMU_INTEN_RISE3_SHIFT |
++              pdata->trigger_level2_en << EXYNOS_TMU_INTEN_RISE2_SHIFT |
++              pdata->trigger_level1_en << EXYNOS_TMU_INTEN_RISE1_SHIFT |
++              pdata->trigger_level0_en << EXYNOS_TMU_INTEN_RISE0_SHIFT;
+               if (pdata->threshold_falling)
+-                      interrupt_en |= interrupt_en << 16;
++                      interrupt_en |=
++                              interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT;
+       } else {
+-              con |= EXYNOS_TMU_CORE_OFF;
++              con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT);
+               interrupt_en = 0; /* Disable all interrupts */
+       }
+       writel(interrupt_en, data->base + EXYNOS_TMU_REG_INTEN);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0959-thermal-exynos-Add-extra-entries-in-the-tmu-platform.patch b/patches.tizen/0959-thermal-exynos-Add-extra-entries-in-the-tmu-platform.patch
new file mode 100644 (file)
index 0000000..7cdcb35
--- /dev/null
@@ -0,0 +1,299 @@
+From b020199365e07c9a3fe225555a302a62c970a48a Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Mon, 24 Jun 2013 16:20:30 +0530
+Subject: [PATCH 0959/1302] thermal: exynos: Add extra entries in the tmu
+ platform data
+
+This patch adds entries min_efuse_value, max_efuse_value, default_temp_offset,
+trigger_type, cal_type, trim_first_point, trim_second_point, max_trigger_level
+trigger_enable in the TMU platform data structure. Also the driver is modified
+to use the data passed by these new platform memebers instead of the constant
+macros. All these changes helps in separating the SOC specific data part from
+the TMU driver.
+
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_thermal_common.h |  7 ++++
+ drivers/thermal/samsung/exynos_tmu.c            | 43 +++++++++++-----------
+ drivers/thermal/samsung/exynos_tmu.h            | 49 ++++++++++++++++---------
+ drivers/thermal/samsung/exynos_tmu_data.c       | 34 +++++++++++++----
+ 4 files changed, 85 insertions(+), 48 deletions(-)
+
+diff --git a/drivers/thermal/samsung/exynos_thermal_common.h b/drivers/thermal/samsung/exynos_thermal_common.h
+index 57ce33b..fee1588 100644
+--- a/drivers/thermal/samsung/exynos_thermal_common.h
++++ b/drivers/thermal/samsung/exynos_thermal_common.h
+@@ -44,6 +44,13 @@
+ #define EXYNOS_ZONE_COUNT     3
++enum trigger_type {
++      THROTTLE_ACTIVE = 1,
++      THROTTLE_PASSIVE,
++      SW_TRIP,
++      HW_TRIP,
++};
++
+ /**
+  * struct freq_clip_table
+  * @freq_clip_max: maximum frequency allowed for this cooling state.
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+index fa33a48..401ec98 100644
+--- a/drivers/thermal/samsung/exynos_tmu.c
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -49,7 +49,6 @@
+ #define EXYNOS_TMU_BUF_SLOPE_SEL_MASK 0xf
+ #define EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT        8
+ #define EXYNOS_TMU_CORE_EN_SHIFT      0
+-#define EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET    50
+ /* Exynos4210 specific registers */
+ #define EXYNOS4210_TMU_REG_THRESHOLD_TEMP     0x44
+@@ -94,9 +93,6 @@
+ #define EXYNOS_TMU_INTEN_FALL1_SHIFT  20
+ #define EXYNOS_TMU_INTEN_FALL2_SHIFT  24
+-#define EFUSE_MIN_VALUE 40
+-#define EFUSE_MAX_VALUE 100
+-
+ #ifdef CONFIG_THERMAL_EMULATION
+ #define EXYNOS_EMUL_TIME      0x57F0
+ #define EXYNOS_EMUL_TIME_MASK 0xffff
+@@ -136,15 +132,16 @@ static int temp_to_code(struct exynos_tmu_data *data, u8 temp)
+       switch (pdata->cal_type) {
+       case TYPE_TWO_POINT_TRIMMING:
+-              temp_code = (temp - 25) *
+-                  (data->temp_error2 - data->temp_error1) /
+-                  (85 - 25) + data->temp_error1;
++              temp_code = (temp - pdata->first_point_trim) *
++                      (data->temp_error2 - data->temp_error1) /
++                      (pdata->second_point_trim - pdata->first_point_trim) +
++                      data->temp_error1;
+               break;
+       case TYPE_ONE_POINT_TRIMMING:
+-              temp_code = temp + data->temp_error1 - 25;
++              temp_code = temp + data->temp_error1 - pdata->first_point_trim;
+               break;
+       default:
+-              temp_code = temp + EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET;
++              temp_code = temp + pdata->default_temp_offset;
+               break;
+       }
+ out:
+@@ -169,14 +166,16 @@ static int code_to_temp(struct exynos_tmu_data *data, u8 temp_code)
+       switch (pdata->cal_type) {
+       case TYPE_TWO_POINT_TRIMMING:
+-              temp = (temp_code - data->temp_error1) * (85 - 25) /
+-                  (data->temp_error2 - data->temp_error1) + 25;
++              temp = (temp_code - data->temp_error1) *
++                      (pdata->second_point_trim - pdata->first_point_trim) /
++                      (data->temp_error2 - data->temp_error1) +
++                      pdata->first_point_trim;
+               break;
+       case TYPE_ONE_POINT_TRIMMING:
+-              temp = temp_code - data->temp_error1 + 25;
++              temp = temp_code - data->temp_error1 + pdata->first_point_trim;
+               break;
+       default:
+-              temp = temp_code - EXYNOS_TMU_DEF_CODE_TO_TEMP_OFFSET;
++              temp = temp_code - pdata->default_temp_offset;
+               break;
+       }
+ out:
+@@ -209,8 +208,8 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
+       data->temp_error1 = trim_info & EXYNOS_TMU_TRIM_TEMP_MASK;
+       data->temp_error2 = ((trim_info >> 8) & EXYNOS_TMU_TRIM_TEMP_MASK);
+-      if ((EFUSE_MIN_VALUE > data->temp_error1) ||
+-                      (data->temp_error1 > EFUSE_MAX_VALUE) ||
++      if ((pdata->min_efuse_value > data->temp_error1) ||
++                      (data->temp_error1 > pdata->max_efuse_value) ||
+                       (data->temp_error2 != 0))
+               data->temp_error1 = pdata->efuse_value;
+@@ -300,10 +299,10 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on)
+       if (on) {
+               con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT);
+               interrupt_en =
+-              pdata->trigger_level3_en << EXYNOS_TMU_INTEN_RISE3_SHIFT |
+-              pdata->trigger_level2_en << EXYNOS_TMU_INTEN_RISE2_SHIFT |
+-              pdata->trigger_level1_en << EXYNOS_TMU_INTEN_RISE1_SHIFT |
+-              pdata->trigger_level0_en << EXYNOS_TMU_INTEN_RISE0_SHIFT;
++              pdata->trigger_enable[3] << EXYNOS_TMU_INTEN_RISE3_SHIFT |
++              pdata->trigger_enable[2] << EXYNOS_TMU_INTEN_RISE2_SHIFT |
++              pdata->trigger_enable[1] << EXYNOS_TMU_INTEN_RISE1_SHIFT |
++              pdata->trigger_enable[0] << EXYNOS_TMU_INTEN_RISE0_SHIFT;
+               if (pdata->threshold_falling)
+                       interrupt_en |=
+                               interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT;
+@@ -533,9 +532,9 @@ static int exynos_tmu_probe(struct platform_device *pdev)
+       /* Register the sensor with thermal management interface */
+       (&exynos_sensor_conf)->private_data = data;
+-      exynos_sensor_conf.trip_data.trip_count = pdata->trigger_level0_en +
+-                      pdata->trigger_level1_en + pdata->trigger_level2_en +
+-                      pdata->trigger_level3_en;
++      exynos_sensor_conf.trip_data.trip_count = pdata->trigger_enable[0] +
++                      pdata->trigger_enable[1] + pdata->trigger_enable[2]+
++                      pdata->trigger_enable[3];
+       for (i = 0; i < exynos_sensor_conf.trip_data.trip_count; i++)
+               exynos_sensor_conf.trip_data.trip_val[i] =
+diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h
+index 1857609..473acae 100644
+--- a/drivers/thermal/samsung/exynos_tmu.h
++++ b/drivers/thermal/samsung/exynos_tmu.h
+@@ -32,6 +32,11 @@ enum calibration_type {
+       TYPE_NONE,
+ };
++enum calibration_mode {
++      SW_MODE,
++      HW_MODE,
++};
++
+ enum soc_type {
+       SOC_ARCH_EXYNOS4210 = 1,
+       SOC_ARCH_EXYNOS,
+@@ -57,18 +62,15 @@ enum soc_type {
+  *    3: temperature for trigger_level3 interrupt
+  *       condition for trigger_level3 interrupt:
+  *            current temperature > threshold + trigger_levels[3]
+- * @trigger_level0_en:
+- *    1 = enable trigger_level0 interrupt,
+- *    0 = disable trigger_level0 interrupt
+- * @trigger_level1_en:
+- *    1 = enable trigger_level1 interrupt,
+- *    0 = disable trigger_level1 interrupt
+- * @trigger_level2_en:
+- *    1 = enable trigger_level2 interrupt,
+- *    0 = disable trigger_level2 interrupt
+- * @trigger_level3_en:
+- *    1 = enable trigger_level3 interrupt,
+- *    0 = disable trigger_level3 interrupt
++ * @trigger_type: defines the type of trigger. Possible values are,
++ *    THROTTLE_ACTIVE trigger type
++ *    THROTTLE_PASSIVE trigger type
++ *    SW_TRIP trigger type
++ *    HW_TRIP
++ * @trigger_enable[]: array to denote which trigger levels are enabled.
++ *    1 = enable trigger_level[] interrupt,
++ *    0 = disable trigger_level[] interrupt
++ * @max_trigger_level: max trigger level supported by the TMU
+  * @gain: gain of amplifier in the positive-TC generator block
+  *    0 <= gain <= 15
+  * @reference_voltage: reference voltage of amplifier
+@@ -78,7 +80,13 @@ enum soc_type {
+  *    000, 100, 101, 110 and 111 can be different modes
+  * @type: determines the type of SOC
+  * @efuse_value: platform defined fuse value
++ * @min_efuse_value: minimum valid trimming data
++ * @max_efuse_value: maximum valid trimming data
++ * @first_point_trim: temp value of the first point trimming
++ * @second_point_trim: temp value of the second point trimming
++ * @default_temp_offset: default temperature offset in case of no trimming
+  * @cal_type: calibration type for temperature
++ * @cal_mode: calibration mode for temperature
+  * @freq_clip_table: Table representing frequency reduction percentage.
+  * @freq_tab_count: Count of the above table as frequency reduction may
+  *    applicable to only some of the trigger levels.
+@@ -88,18 +96,23 @@ enum soc_type {
+ struct exynos_tmu_platform_data {
+       u8 threshold;
+       u8 threshold_falling;
+-      u8 trigger_levels[4];
+-      bool trigger_level0_en;
+-      bool trigger_level1_en;
+-      bool trigger_level2_en;
+-      bool trigger_level3_en;
+-
++      u8 trigger_levels[MAX_TRIP_COUNT];
++      enum trigger_type trigger_type[MAX_TRIP_COUNT];
++      bool trigger_enable[MAX_TRIP_COUNT];
++      u8 max_trigger_level;
+       u8 gain;
+       u8 reference_voltage;
+       u8 noise_cancel_mode;
++
+       u32 efuse_value;
++      u32 min_efuse_value;
++      u32 max_efuse_value;
++      u8 first_point_trim;
++      u8 second_point_trim;
++      u8 default_temp_offset;
+       enum calibration_type cal_type;
++      enum calibration_mode cal_mode;
+       enum soc_type type;
+       struct freq_clip_table freq_tab[4];
+       unsigned int freq_tab_count;
+diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c
+index 144ba44..24934d7 100644
+--- a/drivers/thermal/samsung/exynos_tmu_data.c
++++ b/drivers/thermal/samsung/exynos_tmu_data.c
+@@ -30,13 +30,22 @@ struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
+       .trigger_levels[0] = 5,
+       .trigger_levels[1] = 20,
+       .trigger_levels[2] = 30,
+-      .trigger_level0_en = 1,
+-      .trigger_level1_en = 1,
+-      .trigger_level2_en = 1,
+-      .trigger_level3_en = 0,
++      .trigger_enable[0] = true,
++      .trigger_enable[1] = true,
++      .trigger_enable[2] = true,
++      .trigger_enable[3] = false,
++      .trigger_type[0] = THROTTLE_ACTIVE,
++      .trigger_type[1] = THROTTLE_ACTIVE,
++      .trigger_type[2] = SW_TRIP,
++      .max_trigger_level = 4,
+       .gain = 15,
+       .reference_voltage = 7,
+       .cal_type = TYPE_ONE_POINT_TRIMMING,
++      .min_efuse_value = 40,
++      .max_efuse_value = 100,
++      .first_point_trim = 25,
++      .second_point_trim = 85,
++      .default_temp_offset = 50,
+       .freq_tab[0] = {
+               .freq_clip_max = 800 * 1000,
+               .temp_level = 85,
+@@ -56,15 +65,24 @@ struct exynos_tmu_platform_data const exynos5250_default_tmu_data = {
+       .trigger_levels[0] = 85,
+       .trigger_levels[1] = 103,
+       .trigger_levels[2] = 110,
+-      .trigger_level0_en = 1,
+-      .trigger_level1_en = 1,
+-      .trigger_level2_en = 1,
+-      .trigger_level3_en = 0,
++      .trigger_enable[0] = true,
++      .trigger_enable[1] = true,
++      .trigger_enable[2] = true,
++      .trigger_enable[3] = false,
++      .trigger_type[0] = THROTTLE_ACTIVE,
++      .trigger_type[1] = THROTTLE_ACTIVE,
++      .trigger_type[2] = SW_TRIP,
++      .max_trigger_level = 4,
+       .gain = 8,
+       .reference_voltage = 16,
+       .noise_cancel_mode = 4,
+       .cal_type = TYPE_ONE_POINT_TRIMMING,
+       .efuse_value = 55,
++      .min_efuse_value = 40,
++      .max_efuse_value = 100,
++      .first_point_trim = 25,
++      .second_point_trim = 85,
++      .default_temp_offset = 50,
+       .freq_tab[0] = {
+               .freq_clip_max = 800 * 1000,
+               .temp_level = 85,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0960-thermal-exynos-Move-register-definitions-from-driver.patch b/patches.tizen/0960-thermal-exynos-Move-register-definitions-from-driver.patch
new file mode 100644 (file)
index 0000000..41797ef
--- /dev/null
@@ -0,0 +1,647 @@
+From e3bc1460199bbdb0e10b03276bcab6c6c0dc69ce Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Mon, 24 Jun 2013 16:20:31 +0530
+Subject: [PATCH 0960/1302] thermal: exynos: Move register definitions from
+ driver to data file
+
+This patch migrates the TMU register definition/bitfields to data file. This
+is needed to support SoC's which use the same TMU controller but register
+validity, offsets or bitfield may slightly vary across SOC's.
+
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_tmu.c      | 172 ++++++++++--------------------
+ drivers/thermal/samsung/exynos_tmu.h      | 133 +++++++++++++++++++++++
+ drivers/thermal/samsung/exynos_tmu_data.c |  59 ++++++++++
+ drivers/thermal/samsung/exynos_tmu_data.h |  68 ++++++++++++
+ 4 files changed, 315 insertions(+), 117 deletions(-)
+
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+index 401ec98..6fd776f 100644
+--- a/drivers/thermal/samsung/exynos_tmu.c
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -32,76 +32,6 @@
+ #include "exynos_tmu.h"
+ #include "exynos_tmu_data.h"
+-/* Exynos generic registers */
+-#define EXYNOS_TMU_REG_TRIMINFO               0x0
+-#define EXYNOS_TMU_REG_CONTROL                0x20
+-#define EXYNOS_TMU_REG_STATUS         0x28
+-#define EXYNOS_TMU_REG_CURRENT_TEMP   0x40
+-#define EXYNOS_TMU_REG_INTEN          0x70
+-#define EXYNOS_TMU_REG_INTSTAT                0x74
+-#define EXYNOS_TMU_REG_INTCLEAR               0x78
+-
+-#define EXYNOS_TMU_TRIM_TEMP_MASK     0xff
+-#define EXYNOS_TMU_GAIN_SHIFT         8
+-#define EXYNOS_TMU_GAIN_MASK          0xf
+-#define EXYNOS_TMU_REF_VOLTAGE_SHIFT  24
+-#define EXYNOS_TMU_REF_VOLTAGE_MASK   0x1f
+-#define EXYNOS_TMU_BUF_SLOPE_SEL_MASK 0xf
+-#define EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT        8
+-#define EXYNOS_TMU_CORE_EN_SHIFT      0
+-
+-/* Exynos4210 specific registers */
+-#define EXYNOS4210_TMU_REG_THRESHOLD_TEMP     0x44
+-#define EXYNOS4210_TMU_REG_TRIG_LEVEL0        0x50
+-#define EXYNOS4210_TMU_REG_TRIG_LEVEL1        0x54
+-#define EXYNOS4210_TMU_REG_TRIG_LEVEL2        0x58
+-#define EXYNOS4210_TMU_REG_TRIG_LEVEL3        0x5C
+-#define EXYNOS4210_TMU_REG_PAST_TEMP0 0x60
+-#define EXYNOS4210_TMU_REG_PAST_TEMP1 0x64
+-#define EXYNOS4210_TMU_REG_PAST_TEMP2 0x68
+-#define EXYNOS4210_TMU_REG_PAST_TEMP3 0x6C
+-
+-#define EXYNOS4210_TMU_TRIG_LEVEL0_MASK       0x1
+-#define EXYNOS4210_TMU_TRIG_LEVEL1_MASK       0x10
+-#define EXYNOS4210_TMU_TRIG_LEVEL2_MASK       0x100
+-#define EXYNOS4210_TMU_TRIG_LEVEL3_MASK       0x1000
+-#define EXYNOS4210_TMU_TRIG_LEVEL_MASK        0x1111
+-#define EXYNOS4210_TMU_INTCLEAR_VAL   0x1111
+-
+-/* Exynos5250 and Exynos4412 specific registers */
+-#define EXYNOS_TMU_TRIMINFO_CON       0x14
+-#define EXYNOS_THD_TEMP_RISE          0x50
+-#define EXYNOS_THD_TEMP_FALL          0x54
+-#define EXYNOS_EMUL_CON               0x80
+-
+-#define EXYNOS_TRIMINFO_RELOAD                0x1
+-#define EXYNOS_TRIMINFO_SHIFT         0x0
+-#define EXYNOS_TMU_RISE_INT_MASK      0x111
+-#define EXYNOS_TMU_RISE_INT_SHIFT     0
+-#define EXYNOS_TMU_FALL_INT_MASK      0x111
+-#define EXYNOS_TMU_FALL_INT_SHIFT     12
+-#define EXYNOS_TMU_CLEAR_RISE_INT     0x111
+-#define EXYNOS_TMU_CLEAR_FALL_INT     (0x111 << 12)
+-#define EXYNOS_TMU_TRIP_MODE_SHIFT    13
+-#define EXYNOS_TMU_TRIP_MODE_MASK     0x7
+-
+-#define EXYNOS_TMU_INTEN_RISE0_SHIFT  0
+-#define EXYNOS_TMU_INTEN_RISE1_SHIFT  4
+-#define EXYNOS_TMU_INTEN_RISE2_SHIFT  8
+-#define EXYNOS_TMU_INTEN_RISE3_SHIFT  12
+-#define EXYNOS_TMU_INTEN_FALL0_SHIFT  16
+-#define EXYNOS_TMU_INTEN_FALL1_SHIFT  20
+-#define EXYNOS_TMU_INTEN_FALL2_SHIFT  24
+-
+-#ifdef CONFIG_THERMAL_EMULATION
+-#define EXYNOS_EMUL_TIME      0x57F0
+-#define EXYNOS_EMUL_TIME_MASK 0xffff
+-#define EXYNOS_EMUL_TIME_SHIFT        16
+-#define EXYNOS_EMUL_DATA_SHIFT        8
+-#define EXYNOS_EMUL_DATA_MASK 0xFF
+-#define EXYNOS_EMUL_ENABLE    0x1
+-#endif /* CONFIG_THERMAL_EMULATION */
+-
+ struct exynos_tmu_data {
+       struct exynos_tmu_platform_data *pdata;
+       struct resource *mem;
+@@ -186,6 +116,7 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
+ {
+       struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+       struct exynos_tmu_platform_data *pdata = data->pdata;
++      const struct exynos_tmu_registers *reg = pdata->registers;
+       unsigned int status, trim_info;
+       unsigned int rising_threshold = 0, falling_threshold = 0;
+       int ret = 0, threshold_code, i, trigger_levs = 0;
+@@ -193,20 +124,20 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
+       mutex_lock(&data->lock);
+       clk_enable(data->clk);
+-      status = readb(data->base + EXYNOS_TMU_REG_STATUS);
++      status = readb(data->base + reg->tmu_status);
+       if (!status) {
+               ret = -EBUSY;
+               goto out;
+       }
+-      if (data->soc == SOC_ARCH_EXYNOS) {
+-              __raw_writel(EXYNOS_TRIMINFO_RELOAD,
+-                              data->base + EXYNOS_TMU_TRIMINFO_CON);
+-      }
++      if (data->soc == SOC_ARCH_EXYNOS)
++              __raw_writel(1, data->base + reg->triminfo_ctrl);
++
+       /* Save trimming info in order to perform calibration */
+-      trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
+-      data->temp_error1 = trim_info & EXYNOS_TMU_TRIM_TEMP_MASK;
+-      data->temp_error2 = ((trim_info >> 8) & EXYNOS_TMU_TRIM_TEMP_MASK);
++      trim_info = readl(data->base + reg->triminfo_data);
++      data->temp_error1 = trim_info & EXYNOS_TMU_TEMP_MASK;
++      data->temp_error2 = ((trim_info >> reg->triminfo_85_shift) &
++                              EXYNOS_TMU_TEMP_MASK);
+       if ((pdata->min_efuse_value > data->temp_error1) ||
+                       (data->temp_error1 > pdata->max_efuse_value) ||
+@@ -226,13 +157,12 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
+                       goto out;
+               }
+               writeb(threshold_code,
+-                      data->base + EXYNOS4210_TMU_REG_THRESHOLD_TEMP);
++                      data->base + reg->threshold_temp);
+               for (i = 0; i < trigger_levs; i++)
+-                      writeb(pdata->trigger_levels[i],
+-                      data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + i * 4);
++                      writeb(pdata->trigger_levels[i], data->base +
++                      reg->threshold_th0 + i * sizeof(reg->threshold_th0));
+-              writel(EXYNOS4210_TMU_INTCLEAR_VAL,
+-                      data->base + EXYNOS_TMU_REG_INTCLEAR);
++              writel(reg->inten_rise_mask, data->base + reg->tmu_intclear);
+       } else if (data->soc == SOC_ARCH_EXYNOS) {
+               /* Write temperature code for rising and falling threshold */
+               for (i = 0; i < trigger_levs; i++) {
+@@ -254,12 +184,13 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
+               }
+               writel(rising_threshold,
+-                              data->base + EXYNOS_THD_TEMP_RISE);
++                              data->base + reg->threshold_th0);
+               writel(falling_threshold,
+-                              data->base + EXYNOS_THD_TEMP_FALL);
++                              data->base + reg->threshold_th1);
+-              writel(EXYNOS_TMU_CLEAR_RISE_INT | EXYNOS_TMU_CLEAR_FALL_INT,
+-                              data->base + EXYNOS_TMU_REG_INTCLEAR);
++              writel((reg->inten_rise_mask << reg->inten_rise_shift) |
++                      (reg->inten_fall_mask << reg->inten_fall_shift),
++                              data->base + reg->tmu_intclear);
+       }
+ out:
+       clk_disable(data->clk);
+@@ -272,46 +203,46 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on)
+ {
+       struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+       struct exynos_tmu_platform_data *pdata = data->pdata;
++      const struct exynos_tmu_registers *reg = pdata->registers;
+       unsigned int con, interrupt_en;
+       mutex_lock(&data->lock);
+       clk_enable(data->clk);
+-      con = readl(data->base + EXYNOS_TMU_REG_CONTROL);
++      con = readl(data->base + reg->tmu_ctrl);
+       if (pdata->reference_voltage) {
+-              con &= ~(EXYNOS_TMU_REF_VOLTAGE_MASK <<
+-                              EXYNOS_TMU_REF_VOLTAGE_SHIFT);
+-              con |= pdata->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT;
++              con &= ~(reg->buf_vref_sel_mask << reg->buf_vref_sel_shift);
++              con |= pdata->reference_voltage << reg->buf_vref_sel_shift;
+       }
+       if (pdata->gain) {
+-              con &= ~(EXYNOS_TMU_GAIN_MASK << EXYNOS_TMU_GAIN_SHIFT);
+-              con |= (pdata->gain << EXYNOS_TMU_GAIN_SHIFT);
++              con &= ~(reg->buf_slope_sel_mask << reg->buf_slope_sel_shift);
++              con |= (pdata->gain << reg->buf_slope_sel_shift);
+       }
+       if (pdata->noise_cancel_mode) {
+-              con &= ~(EXYNOS_TMU_TRIP_MODE_MASK <<
+-                                      EXYNOS_TMU_TRIP_MODE_SHIFT);
+-              con |= (pdata->noise_cancel_mode << EXYNOS_TMU_TRIP_MODE_SHIFT);
++              con &= ~(reg->therm_trip_mode_mask <<
++                                      reg->therm_trip_mode_shift);
++              con |= (pdata->noise_cancel_mode << reg->therm_trip_mode_shift);
+       }
+       if (on) {
+-              con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT);
++              con |= (1 << reg->core_en_shift);
+               interrupt_en =
+-              pdata->trigger_enable[3] << EXYNOS_TMU_INTEN_RISE3_SHIFT |
+-              pdata->trigger_enable[2] << EXYNOS_TMU_INTEN_RISE2_SHIFT |
+-              pdata->trigger_enable[1] << EXYNOS_TMU_INTEN_RISE1_SHIFT |
+-              pdata->trigger_enable[0] << EXYNOS_TMU_INTEN_RISE0_SHIFT;
++                      pdata->trigger_enable[3] << reg->inten_rise3_shift |
++                      pdata->trigger_enable[2] << reg->inten_rise2_shift |
++                      pdata->trigger_enable[1] << reg->inten_rise1_shift |
++                      pdata->trigger_enable[0] << reg->inten_rise0_shift;
+               if (pdata->threshold_falling)
+                       interrupt_en |=
+-                              interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT;
++                              interrupt_en << reg->inten_fall0_shift;
+       } else {
+-              con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT);
++              con &= ~(1 << reg->core_en_shift);
+               interrupt_en = 0; /* Disable all interrupts */
+       }
+-      writel(interrupt_en, data->base + EXYNOS_TMU_REG_INTEN);
+-      writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
++      writel(interrupt_en, data->base + reg->tmu_inten);
++      writel(con, data->base + reg->tmu_ctrl);
+       clk_disable(data->clk);
+       mutex_unlock(&data->lock);
+@@ -319,13 +250,15 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on)
+ static int exynos_tmu_read(struct exynos_tmu_data *data)
+ {
++      struct exynos_tmu_platform_data *pdata = data->pdata;
++      const struct exynos_tmu_registers *reg = pdata->registers;
+       u8 temp_code;
+       int temp;
+       mutex_lock(&data->lock);
+       clk_enable(data->clk);
+-      temp_code = readb(data->base + EXYNOS_TMU_REG_CURRENT_TEMP);
++      temp_code = readb(data->base + reg->tmu_cur_temp);
+       temp = code_to_temp(data, temp_code);
+       clk_disable(data->clk);
+@@ -338,7 +271,9 @@ static int exynos_tmu_read(struct exynos_tmu_data *data)
+ static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp)
+ {
+       struct exynos_tmu_data *data = drv_data;
+-      unsigned int reg;
++      struct exynos_tmu_platform_data *pdata = data->pdata;
++      const struct exynos_tmu_registers *reg = pdata->registers;
++      unsigned int val;
+       int ret = -EINVAL;
+       if (data->soc == SOC_ARCH_EXYNOS4210)
+@@ -350,19 +285,19 @@ static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp)
+       mutex_lock(&data->lock);
+       clk_enable(data->clk);
+-      reg = readl(data->base + EXYNOS_EMUL_CON);
++      val = readl(data->base + reg->emul_con);
+       if (temp) {
+               temp /= MCELSIUS;
+-              reg = (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT) |
++              val = (EXYNOS_EMUL_TIME << reg->emul_time_shift) |
+                       (temp_to_code(data, temp)
+-                       << EXYNOS_EMUL_DATA_SHIFT) | EXYNOS_EMUL_ENABLE;
++                       << reg->emul_temp_shift) | EXYNOS_EMUL_ENABLE;
+       } else {
+-              reg &= ~EXYNOS_EMUL_ENABLE;
++              val &= ~EXYNOS_EMUL_ENABLE;
+       }
+-      writel(reg, data->base + EXYNOS_EMUL_CON);
++      writel(val, data->base + reg->emul_con);
+       clk_disable(data->clk);
+       mutex_unlock(&data->lock);
+@@ -379,17 +314,20 @@ static void exynos_tmu_work(struct work_struct *work)
+ {
+       struct exynos_tmu_data *data = container_of(work,
+                       struct exynos_tmu_data, irq_work);
++      struct exynos_tmu_platform_data *pdata = data->pdata;
++      const struct exynos_tmu_registers *reg = pdata->registers;
+       exynos_report_trigger();
+       mutex_lock(&data->lock);
+       clk_enable(data->clk);
++
+       if (data->soc == SOC_ARCH_EXYNOS)
+-              writel(EXYNOS_TMU_CLEAR_RISE_INT |
+-                              EXYNOS_TMU_CLEAR_FALL_INT,
+-                              data->base + EXYNOS_TMU_REG_INTCLEAR);
++              writel((reg->inten_rise_mask << reg->inten_rise_shift) |
++                      (reg->inten_fall_mask << reg->inten_fall_shift),
++                              data->base + reg->tmu_intclear);
+       else
+-              writel(EXYNOS4210_TMU_INTCLEAR_VAL,
+-                              data->base + EXYNOS_TMU_REG_INTCLEAR);
++              writel(reg->inten_rise_mask, data->base + reg->tmu_intclear);
++
+       clk_disable(data->clk);
+       mutex_unlock(&data->lock);
+diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h
+index 473acae..ef5dc0e 100644
+--- a/drivers/thermal/samsung/exynos_tmu.h
++++ b/drivers/thermal/samsung/exynos_tmu.h
+@@ -43,6 +43,136 @@ enum soc_type {
+ };
+ /**
++ * struct exynos_tmu_register - register descriptors to access registers and
++ * bitfields. The register validity, offsets and bitfield values may vary
++ * slightly across different exynos SOC's.
++ * @triminfo_data: register containing 2 pont trimming data
++ * @triminfo_25_shift: shift bit of the 25 C trim value in triminfo_data reg.
++ * @triminfo_85_shift: shift bit of the 85 C trim value in triminfo_data reg.
++ * @triminfo_ctrl: trim info controller register.
++ * @triminfo_reload_shift: shift of triminfo reload enable bit in triminfo_ctrl
++      reg.
++ * @tmu_ctrl: TMU main controller register.
++ * @buf_vref_sel_shift: shift bits of reference voltage in tmu_ctrl register.
++ * @buf_vref_sel_mask: mask bits of reference voltage in tmu_ctrl register.
++ * @therm_trip_mode_shift: shift bits of tripping mode in tmu_ctrl register.
++ * @therm_trip_mode_mask: mask bits of tripping mode in tmu_ctrl register.
++ * @therm_trip_en_shift: shift bits of tripping enable in tmu_ctrl register.
++ * @buf_slope_sel_shift: shift bits of amplifier gain value in tmu_ctrl
++      register.
++ * @buf_slope_sel_mask: mask bits of amplifier gain value in tmu_ctrl register.
++ * @therm_trip_tq_en_shift: shift bits of thermal trip enable by TQ pin in
++      tmu_ctrl register.
++ * @core_en_shift: shift bits of TMU core enable bit in tmu_ctrl register.
++ * @tmu_status: register drescribing the TMU status.
++ * @tmu_cur_temp: register containing the current temperature of the TMU.
++ * @tmu_cur_temp_shift: shift bits of current temp value in tmu_cur_temp
++      register.
++ * @threshold_temp: register containing the base threshold level.
++ * @threshold_th0: Register containing first set of rising levels.
++ * @threshold_th0_l0_shift: shift bits of level0 threshold temperature.
++ * @threshold_th0_l1_shift: shift bits of level1 threshold temperature.
++ * @threshold_th0_l2_shift: shift bits of level2 threshold temperature.
++ * @threshold_th0_l3_shift: shift bits of level3 threshold temperature.
++ * @threshold_th1: Register containing second set of rising levels.
++ * @threshold_th1_l0_shift: shift bits of level0 threshold temperature.
++ * @threshold_th1_l1_shift: shift bits of level1 threshold temperature.
++ * @threshold_th1_l2_shift: shift bits of level2 threshold temperature.
++ * @threshold_th1_l3_shift: shift bits of level3 threshold temperature.
++ * @threshold_th2: Register containing third set of rising levels.
++ * @threshold_th2_l0_shift: shift bits of level0 threshold temperature.
++ * @threshold_th3: Register containing fourth set of rising levels.
++ * @threshold_th3_l0_shift: shift bits of level0 threshold temperature.
++ * @tmu_inten: register containing the different threshold interrupt
++      enable bits.
++ * @inten_rise_shift: shift bits of all rising interrupt bits.
++ * @inten_rise_mask: mask bits of all rising interrupt bits.
++ * @inten_fall_shift: shift bits of all rising interrupt bits.
++ * @inten_fall_mask: mask bits of all rising interrupt bits.
++ * @inten_rise0_shift: shift bits of rising 0 interrupt bits.
++ * @inten_rise1_shift: shift bits of rising 1 interrupt bits.
++ * @inten_rise2_shift: shift bits of rising 2 interrupt bits.
++ * @inten_rise3_shift: shift bits of rising 3 interrupt bits.
++ * @inten_fall0_shift: shift bits of falling 0 interrupt bits.
++ * @inten_fall1_shift: shift bits of falling 1 interrupt bits.
++ * @inten_fall2_shift: shift bits of falling 2 interrupt bits.
++ * @inten_fall3_shift: shift bits of falling 3 interrupt bits.
++ * @tmu_intstat: Register containing the interrupt status values.
++ * @tmu_intclear: Register for clearing the raised interrupt status.
++ * @emul_con: TMU emulation controller register.
++ * @emul_temp_shift: shift bits of emulation temperature.
++ * @emul_time_shift: shift bits of emulation time.
++ * @emul_time_mask: mask bits of emulation time.
++ */
++struct exynos_tmu_registers {
++      u32     triminfo_data;
++      u32     triminfo_25_shift;
++      u32     triminfo_85_shift;
++
++      u32     triminfo_ctrl;
++      u32     triminfo_reload_shift;
++
++      u32     tmu_ctrl;
++      u32     buf_vref_sel_shift;
++      u32     buf_vref_sel_mask;
++      u32     therm_trip_mode_shift;
++      u32     therm_trip_mode_mask;
++      u32     therm_trip_en_shift;
++      u32     buf_slope_sel_shift;
++      u32     buf_slope_sel_mask;
++      u32     therm_trip_tq_en_shift;
++      u32     core_en_shift;
++
++      u32     tmu_status;
++
++      u32     tmu_cur_temp;
++      u32     tmu_cur_temp_shift;
++
++      u32     threshold_temp;
++
++      u32     threshold_th0;
++      u32     threshold_th0_l0_shift;
++      u32     threshold_th0_l1_shift;
++      u32     threshold_th0_l2_shift;
++      u32     threshold_th0_l3_shift;
++
++      u32     threshold_th1;
++      u32     threshold_th1_l0_shift;
++      u32     threshold_th1_l1_shift;
++      u32     threshold_th1_l2_shift;
++      u32     threshold_th1_l3_shift;
++
++      u32     threshold_th2;
++      u32     threshold_th2_l0_shift;
++
++      u32     threshold_th3;
++      u32     threshold_th3_l0_shift;
++
++      u32     tmu_inten;
++      u32     inten_rise_shift;
++      u32     inten_rise_mask;
++      u32     inten_fall_shift;
++      u32     inten_fall_mask;
++      u32     inten_rise0_shift;
++      u32     inten_rise1_shift;
++      u32     inten_rise2_shift;
++      u32     inten_rise3_shift;
++      u32     inten_fall0_shift;
++      u32     inten_fall1_shift;
++      u32     inten_fall2_shift;
++      u32     inten_fall3_shift;
++
++      u32     tmu_intstat;
++
++      u32     tmu_intclear;
++
++      u32     emul_con;
++      u32     emul_temp_shift;
++      u32     emul_time_shift;
++      u32     emul_time_mask;
++};
++
++/**
+  * struct exynos_tmu_platform_data
+  * @threshold: basic temperature for generating interrupt
+  *           25 <= threshold <= 125 [unit: degree Celsius]
+@@ -90,6 +220,8 @@ enum soc_type {
+  * @freq_clip_table: Table representing frequency reduction percentage.
+  * @freq_tab_count: Count of the above table as frequency reduction may
+  *    applicable to only some of the trigger levels.
++ * @registers: Pointer to structure containing all the TMU controller registers
++ *    and bitfields shifts and masks.
+  *
+  * This structure is required for configuration of exynos_tmu driver.
+  */
+@@ -116,5 +248,6 @@ struct exynos_tmu_platform_data {
+       enum soc_type type;
+       struct freq_clip_table freq_tab[4];
+       unsigned int freq_tab_count;
++      const struct exynos_tmu_registers *registers;
+ };
+ #endif /* _EXYNOS_TMU_H */
+diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c
+index 24934d7..896aa2a 100644
+--- a/drivers/thermal/samsung/exynos_tmu_data.c
++++ b/drivers/thermal/samsung/exynos_tmu_data.c
+@@ -25,6 +25,28 @@
+ #include "exynos_tmu_data.h"
+ #if defined(CONFIG_CPU_EXYNOS4210)
++static const struct exynos_tmu_registers exynos4210_tmu_registers = {
++      .triminfo_data = EXYNOS_TMU_REG_TRIMINFO,
++      .triminfo_25_shift = EXYNOS_TRIMINFO_25_SHIFT,
++      .triminfo_85_shift = EXYNOS_TRIMINFO_85_SHIFT,
++      .tmu_ctrl = EXYNOS_TMU_REG_CONTROL,
++      .buf_vref_sel_shift = EXYNOS_TMU_REF_VOLTAGE_SHIFT,
++      .buf_vref_sel_mask = EXYNOS_TMU_REF_VOLTAGE_MASK,
++      .buf_slope_sel_shift = EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT,
++      .buf_slope_sel_mask = EXYNOS_TMU_BUF_SLOPE_SEL_MASK,
++      .core_en_shift = EXYNOS_TMU_CORE_EN_SHIFT,
++      .tmu_status = EXYNOS_TMU_REG_STATUS,
++      .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP,
++      .threshold_temp = EXYNOS4210_TMU_REG_THRESHOLD_TEMP,
++      .threshold_th0 = EXYNOS4210_TMU_REG_TRIG_LEVEL0,
++      .tmu_inten = EXYNOS_TMU_REG_INTEN,
++      .inten_rise_mask = EXYNOS4210_TMU_TRIG_LEVEL_MASK,
++      .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT,
++      .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT,
++      .inten_rise2_shift = EXYNOS_TMU_INTEN_RISE2_SHIFT,
++      .inten_rise3_shift = EXYNOS_TMU_INTEN_RISE3_SHIFT,
++      .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR,
++};
+ struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
+       .threshold = 80,
+       .trigger_levels[0] = 5,
+@@ -56,10 +78,46 @@ struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
+       },
+       .freq_tab_count = 2,
+       .type = SOC_ARCH_EXYNOS4210,
++      .registers = &exynos4210_tmu_registers,
+ };
+ #endif
+ #if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412)
++static const struct exynos_tmu_registers exynos5250_tmu_registers = {
++      .triminfo_data = EXYNOS_TMU_REG_TRIMINFO,
++      .triminfo_25_shift = EXYNOS_TRIMINFO_25_SHIFT,
++      .triminfo_85_shift = EXYNOS_TRIMINFO_85_SHIFT,
++      .triminfo_ctrl = EXYNOS_TMU_TRIMINFO_CON,
++      .triminfo_reload_shift = EXYNOS_TRIMINFO_RELOAD_SHIFT,
++      .tmu_ctrl = EXYNOS_TMU_REG_CONTROL,
++      .buf_vref_sel_shift = EXYNOS_TMU_REF_VOLTAGE_SHIFT,
++      .buf_vref_sel_mask = EXYNOS_TMU_REF_VOLTAGE_MASK,
++      .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT,
++      .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK,
++      .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT,
++      .buf_slope_sel_shift = EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT,
++      .buf_slope_sel_mask = EXYNOS_TMU_BUF_SLOPE_SEL_MASK,
++      .core_en_shift = EXYNOS_TMU_CORE_EN_SHIFT,
++      .tmu_status = EXYNOS_TMU_REG_STATUS,
++      .tmu_cur_temp = EXYNOS_TMU_REG_CURRENT_TEMP,
++      .threshold_th0 = EXYNOS_THD_TEMP_RISE,
++      .threshold_th1 = EXYNOS_THD_TEMP_FALL,
++      .tmu_inten = EXYNOS_TMU_REG_INTEN,
++      .inten_rise_mask = EXYNOS_TMU_RISE_INT_MASK,
++      .inten_rise_shift = EXYNOS_TMU_RISE_INT_SHIFT,
++      .inten_fall_mask = EXYNOS_TMU_FALL_INT_MASK,
++      .inten_fall_shift = EXYNOS_TMU_FALL_INT_SHIFT,
++      .inten_rise0_shift = EXYNOS_TMU_INTEN_RISE0_SHIFT,
++      .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT,
++      .inten_rise2_shift = EXYNOS_TMU_INTEN_RISE2_SHIFT,
++      .inten_rise3_shift = EXYNOS_TMU_INTEN_RISE3_SHIFT,
++      .inten_fall0_shift = EXYNOS_TMU_INTEN_FALL0_SHIFT,
++      .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR,
++      .emul_con = EXYNOS_EMUL_CON,
++      .emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT,
++      .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT,
++      .emul_time_mask = EXYNOS_EMUL_TIME_MASK,
++};
+ struct exynos_tmu_platform_data const exynos5250_default_tmu_data = {
+       .threshold_falling = 10,
+       .trigger_levels[0] = 85,
+@@ -93,5 +151,6 @@ struct exynos_tmu_platform_data const exynos5250_default_tmu_data = {
+       },
+       .freq_tab_count = 2,
+       .type = SOC_ARCH_EXYNOS,
++      .registers = &exynos5250_tmu_registers,
+ };
+ #endif
+diff --git a/drivers/thermal/samsung/exynos_tmu_data.h b/drivers/thermal/samsung/exynos_tmu_data.h
+index b7835fe..0e2244f 100644
+--- a/drivers/thermal/samsung/exynos_tmu_data.h
++++ b/drivers/thermal/samsung/exynos_tmu_data.h
+@@ -23,6 +23,74 @@
+ #ifndef _EXYNOS_TMU_DATA_H
+ #define _EXYNOS_TMU_DATA_H
++/* Exynos generic registers */
++#define EXYNOS_TMU_REG_TRIMINFO               0x0
++#define EXYNOS_TMU_REG_CONTROL                0x20
++#define EXYNOS_TMU_REG_STATUS         0x28
++#define EXYNOS_TMU_REG_CURRENT_TEMP   0x40
++#define EXYNOS_TMU_REG_INTEN          0x70
++#define EXYNOS_TMU_REG_INTSTAT                0x74
++#define EXYNOS_TMU_REG_INTCLEAR               0x78
++
++#define EXYNOS_TMU_TEMP_MASK          0xff
++#define EXYNOS_TMU_REF_VOLTAGE_SHIFT  24
++#define EXYNOS_TMU_REF_VOLTAGE_MASK   0x1f
++#define EXYNOS_TMU_BUF_SLOPE_SEL_MASK 0xf
++#define EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT        8
++#define EXYNOS_TMU_CORE_EN_SHIFT      0
++
++/* Exynos4210 specific registers */
++#define EXYNOS4210_TMU_REG_THRESHOLD_TEMP     0x44
++#define EXYNOS4210_TMU_REG_TRIG_LEVEL0        0x50
++#define EXYNOS4210_TMU_REG_TRIG_LEVEL1        0x54
++#define EXYNOS4210_TMU_REG_TRIG_LEVEL2        0x58
++#define EXYNOS4210_TMU_REG_TRIG_LEVEL3        0x5C
++#define EXYNOS4210_TMU_REG_PAST_TEMP0 0x60
++#define EXYNOS4210_TMU_REG_PAST_TEMP1 0x64
++#define EXYNOS4210_TMU_REG_PAST_TEMP2 0x68
++#define EXYNOS4210_TMU_REG_PAST_TEMP3 0x6C
++
++#define EXYNOS4210_TMU_TRIG_LEVEL0_MASK       0x1
++#define EXYNOS4210_TMU_TRIG_LEVEL1_MASK       0x10
++#define EXYNOS4210_TMU_TRIG_LEVEL2_MASK       0x100
++#define EXYNOS4210_TMU_TRIG_LEVEL3_MASK       0x1000
++#define EXYNOS4210_TMU_TRIG_LEVEL_MASK        0x1111
++#define EXYNOS4210_TMU_INTCLEAR_VAL   0x1111
++
++/* Exynos5250 and Exynos4412 specific registers */
++#define EXYNOS_TMU_TRIMINFO_CON       0x14
++#define EXYNOS_THD_TEMP_RISE          0x50
++#define EXYNOS_THD_TEMP_FALL          0x54
++#define EXYNOS_EMUL_CON               0x80
++
++#define EXYNOS_TRIMINFO_RELOAD_SHIFT  1
++#define EXYNOS_TRIMINFO_25_SHIFT      0
++#define EXYNOS_TRIMINFO_85_SHIFT      8
++#define EXYNOS_TMU_RISE_INT_MASK      0x111
++#define EXYNOS_TMU_RISE_INT_SHIFT     0
++#define EXYNOS_TMU_FALL_INT_MASK      0x111
++#define EXYNOS_TMU_FALL_INT_SHIFT     12
++#define EXYNOS_TMU_CLEAR_RISE_INT     0x111
++#define EXYNOS_TMU_CLEAR_FALL_INT     (0x111 << 12)
++#define EXYNOS_TMU_TRIP_MODE_SHIFT    13
++#define EXYNOS_TMU_TRIP_MODE_MASK     0x7
++#define EXYNOS_TMU_THERM_TRIP_EN_SHIFT        12
++
++#define EXYNOS_TMU_INTEN_RISE0_SHIFT  0
++#define EXYNOS_TMU_INTEN_RISE1_SHIFT  4
++#define EXYNOS_TMU_INTEN_RISE2_SHIFT  8
++#define EXYNOS_TMU_INTEN_RISE3_SHIFT  12
++#define EXYNOS_TMU_INTEN_FALL0_SHIFT  16
++#define EXYNOS_TMU_INTEN_FALL1_SHIFT  20
++#define EXYNOS_TMU_INTEN_FALL2_SHIFT  24
++
++#define EXYNOS_EMUL_TIME      0x57F0
++#define EXYNOS_EMUL_TIME_MASK 0xffff
++#define EXYNOS_EMUL_TIME_SHIFT        16
++#define EXYNOS_EMUL_DATA_SHIFT        8
++#define EXYNOS_EMUL_DATA_MASK 0xFF
++#define EXYNOS_EMUL_ENABLE    0x1
++
+ #if defined(CONFIG_CPU_EXYNOS4210)
+ extern struct exynos_tmu_platform_data const exynos4210_default_tmu_data;
+ #define EXYNOS4210_TMU_DRV_DATA (&exynos4210_default_tmu_data)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0961-thermal-exynos-Support-thermal-tripping.patch b/patches.tizen/0961-thermal-exynos-Support-thermal-tripping.patch
new file mode 100644 (file)
index 0000000..3ea6574
--- /dev/null
@@ -0,0 +1,136 @@
+From cbf4fe63e1239999b04b735241ac233f0544ebec Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Mon, 24 Jun 2013 16:20:32 +0530
+Subject: [PATCH 0961/1302] thermal: exynos: Support thermal tripping
+
+TMU urgently sends active-high signal (thermal trip) to PMU, and thermal
+tripping by hardware logic. Thermal tripping means that PMU cuts off the
+whole power of SoC by controlling external voltage regulator.
+
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Jonghwan Choi <jhbird.choi@samsung.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_tmu.c      | 45 +++++++++++++++++++++++++++----
+ drivers/thermal/samsung/exynos_tmu_data.c |  2 ++
+ drivers/thermal/samsung/exynos_tmu_data.h |  2 ++
+ 3 files changed, 44 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+index 6fd776f..33f494e 100644
+--- a/drivers/thermal/samsung/exynos_tmu.c
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -117,7 +117,7 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
+       struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+       struct exynos_tmu_platform_data *pdata = data->pdata;
+       const struct exynos_tmu_registers *reg = pdata->registers;
+-      unsigned int status, trim_info;
++      unsigned int status, trim_info = 0, con;
+       unsigned int rising_threshold = 0, falling_threshold = 0;
+       int ret = 0, threshold_code, i, trigger_levs = 0;
+@@ -144,10 +144,26 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
+                       (data->temp_error2 != 0))
+               data->temp_error1 = pdata->efuse_value;
+-      /* Count trigger levels to be enabled */
+-      for (i = 0; i < MAX_THRESHOLD_LEVS; i++)
+-              if (pdata->trigger_levels[i])
++      if (pdata->max_trigger_level > MAX_THRESHOLD_LEVS) {
++              dev_err(&pdev->dev, "Invalid max trigger level\n");
++              goto out;
++      }
++
++      for (i = 0; i < pdata->max_trigger_level; i++) {
++              if (!pdata->trigger_levels[i])
++                      continue;
++
++              if ((pdata->trigger_type[i] == HW_TRIP) &&
++              (!pdata->trigger_levels[pdata->max_trigger_level - 1])) {
++                      dev_err(&pdev->dev, "Invalid hw trigger level\n");
++                      ret = -EINVAL;
++                      goto out;
++              }
++
++              /* Count trigger levels except the HW trip*/
++              if (!(pdata->trigger_type[i] == HW_TRIP))
+                       trigger_levs++;
++      }
+       if (data->soc == SOC_ARCH_EXYNOS4210) {
+               /* Write temperature code for threshold */
+@@ -165,7 +181,8 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
+               writel(reg->inten_rise_mask, data->base + reg->tmu_intclear);
+       } else if (data->soc == SOC_ARCH_EXYNOS) {
+               /* Write temperature code for rising and falling threshold */
+-              for (i = 0; i < trigger_levs; i++) {
++              for (i = 0;
++              i < trigger_levs && i < EXYNOS_MAX_TRIGGER_PER_REG; i++) {
+                       threshold_code = temp_to_code(data,
+                                               pdata->trigger_levels[i]);
+                       if (threshold_code < 0) {
+@@ -191,6 +208,24 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
+               writel((reg->inten_rise_mask << reg->inten_rise_shift) |
+                       (reg->inten_fall_mask << reg->inten_fall_shift),
+                               data->base + reg->tmu_intclear);
++
++              /* if last threshold limit is also present */
++              i = pdata->max_trigger_level - 1;
++              if (pdata->trigger_levels[i] &&
++                              (pdata->trigger_type[i] == HW_TRIP)) {
++                      threshold_code = temp_to_code(data,
++                                              pdata->trigger_levels[i]);
++                      if (threshold_code < 0) {
++                              ret = threshold_code;
++                              goto out;
++                      }
++                      rising_threshold |= threshold_code << 8 * i;
++                      writel(rising_threshold,
++                              data->base + reg->threshold_th0);
++                      con = readl(data->base + reg->tmu_ctrl);
++                      con |= (1 << reg->therm_trip_en_shift);
++                      writel(con, data->base + reg->tmu_ctrl);
++              }
+       }
+ out:
+       clk_disable(data->clk);
+diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c
+index 896aa2a..6cac393 100644
+--- a/drivers/thermal/samsung/exynos_tmu_data.c
++++ b/drivers/thermal/samsung/exynos_tmu_data.c
+@@ -123,6 +123,7 @@ struct exynos_tmu_platform_data const exynos5250_default_tmu_data = {
+       .trigger_levels[0] = 85,
+       .trigger_levels[1] = 103,
+       .trigger_levels[2] = 110,
++      .trigger_levels[3] = 120,
+       .trigger_enable[0] = true,
+       .trigger_enable[1] = true,
+       .trigger_enable[2] = true,
+@@ -130,6 +131,7 @@ struct exynos_tmu_platform_data const exynos5250_default_tmu_data = {
+       .trigger_type[0] = THROTTLE_ACTIVE,
+       .trigger_type[1] = THROTTLE_ACTIVE,
+       .trigger_type[2] = SW_TRIP,
++      .trigger_type[3] = HW_TRIP,
+       .max_trigger_level = 4,
+       .gain = 8,
+       .reference_voltage = 16,
+diff --git a/drivers/thermal/samsung/exynos_tmu_data.h b/drivers/thermal/samsung/exynos_tmu_data.h
+index 0e2244f..4acf070 100644
+--- a/drivers/thermal/samsung/exynos_tmu_data.h
++++ b/drivers/thermal/samsung/exynos_tmu_data.h
+@@ -91,6 +91,8 @@
+ #define EXYNOS_EMUL_DATA_MASK 0xFF
+ #define EXYNOS_EMUL_ENABLE    0x1
++#define EXYNOS_MAX_TRIGGER_PER_REG    4
++
+ #if defined(CONFIG_CPU_EXYNOS4210)
+ extern struct exynos_tmu_platform_data const exynos4210_default_tmu_data;
+ #define EXYNOS4210_TMU_DRV_DATA (&exynos4210_default_tmu_data)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0962-thermal-exynos-Fix-to-clear-only-the-generated-inter.patch b/patches.tizen/0962-thermal-exynos-Fix-to-clear-only-the-generated-inter.patch
new file mode 100644 (file)
index 0000000..df7e350
--- /dev/null
@@ -0,0 +1,70 @@
+From c09a32491d27d1ced26dad6b1937187b804f3e06 Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Mon, 24 Jun 2013 16:20:33 +0530
+Subject: [PATCH 0962/1302] thermal: exynos: Fix to clear only the generated
+ interrupts
+
+This patch uses the TMU status register to know the generated interrupts
+and only clear them in the interrupt handler.
+
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_tmu.c      | 11 +++++------
+ drivers/thermal/samsung/exynos_tmu_data.c |  2 ++
+ 2 files changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+index 33f494e..f6f63ca 100644
+--- a/drivers/thermal/samsung/exynos_tmu.c
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -351,17 +351,16 @@ static void exynos_tmu_work(struct work_struct *work)
+                       struct exynos_tmu_data, irq_work);
+       struct exynos_tmu_platform_data *pdata = data->pdata;
+       const struct exynos_tmu_registers *reg = pdata->registers;
++      unsigned int val_irq;
+       exynos_report_trigger();
+       mutex_lock(&data->lock);
+       clk_enable(data->clk);
+-      if (data->soc == SOC_ARCH_EXYNOS)
+-              writel((reg->inten_rise_mask << reg->inten_rise_shift) |
+-                      (reg->inten_fall_mask << reg->inten_fall_shift),
+-                              data->base + reg->tmu_intclear);
+-      else
+-              writel(reg->inten_rise_mask, data->base + reg->tmu_intclear);
++      /* TODO: take action based on particular interrupt */
++      val_irq = readl(data->base + reg->tmu_intstat);
++      /* clear the interrupts */
++      writel(val_irq, data->base + reg->tmu_intclear);
+       clk_disable(data->clk);
+       mutex_unlock(&data->lock);
+diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c
+index 6cac393..217b8f5 100644
+--- a/drivers/thermal/samsung/exynos_tmu_data.c
++++ b/drivers/thermal/samsung/exynos_tmu_data.c
+@@ -45,6 +45,7 @@ static const struct exynos_tmu_registers exynos4210_tmu_registers = {
+       .inten_rise1_shift = EXYNOS_TMU_INTEN_RISE1_SHIFT,
+       .inten_rise2_shift = EXYNOS_TMU_INTEN_RISE2_SHIFT,
+       .inten_rise3_shift = EXYNOS_TMU_INTEN_RISE3_SHIFT,
++      .tmu_intstat = EXYNOS_TMU_REG_INTSTAT,
+       .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR,
+ };
+ struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
+@@ -112,6 +113,7 @@ static const struct exynos_tmu_registers exynos5250_tmu_registers = {
+       .inten_rise2_shift = EXYNOS_TMU_INTEN_RISE2_SHIFT,
+       .inten_rise3_shift = EXYNOS_TMU_INTEN_RISE3_SHIFT,
+       .inten_fall0_shift = EXYNOS_TMU_INTEN_FALL0_SHIFT,
++      .tmu_intstat = EXYNOS_TMU_REG_INTSTAT,
+       .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR,
+       .emul_con = EXYNOS_EMUL_CON,
+       .emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0963-thermal-exynos-Add-support-for-instance-based-regist.patch b/patches.tizen/0963-thermal-exynos-Add-support-for-instance-based-regist.patch
new file mode 100644 (file)
index 0000000..f499bc5
--- /dev/null
@@ -0,0 +1,272 @@
+From c8e8e7bee1f3bcefba4918cc90ef189aefeaa6fa Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Mon, 24 Jun 2013 16:20:34 +0530
+Subject: [PATCH 0963/1302] thermal: exynos: Add support for instance based
+ register/unregister
+
+This code modifies the thermal driver to have multiple thermal zone
+support by replacing the global thermal zone variable with device data
+member of thermal_zone_device.
+
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_thermal_common.c | 51 +++++++++++++++++--------
+ drivers/thermal/samsung/exynos_thermal_common.h |  9 +++--
+ drivers/thermal/samsung/exynos_tmu.c            | 15 ++++----
+ 3 files changed, 49 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c
+index c9edc30..0b014e8 100644
+--- a/drivers/thermal/samsung/exynos_thermal_common.c
++++ b/drivers/thermal/samsung/exynos_thermal_common.c
+@@ -37,12 +37,11 @@ struct exynos_thermal_zone {
+       bool bind;
+ };
+-static struct exynos_thermal_zone *th_zone;
+-
+ /* Get mode callback functions for thermal zone */
+ static int exynos_get_mode(struct thermal_zone_device *thermal,
+                       enum thermal_device_mode *mode)
+ {
++      struct exynos_thermal_zone *th_zone = thermal->devdata;
+       if (th_zone)
+               *mode = th_zone->mode;
+       return 0;
+@@ -52,25 +51,26 @@ static int exynos_get_mode(struct thermal_zone_device *thermal,
+ static int exynos_set_mode(struct thermal_zone_device *thermal,
+                       enum thermal_device_mode mode)
+ {
+-      if (!th_zone->therm_dev) {
++      struct exynos_thermal_zone *th_zone = thermal->devdata;
++      if (!th_zone) {
+               pr_notice("thermal zone not registered\n");
+               return 0;
+       }
+-      mutex_lock(&th_zone->therm_dev->lock);
++      mutex_lock(&thermal->lock);
+       if (mode == THERMAL_DEVICE_ENABLED &&
+               !th_zone->sensor_conf->trip_data.trigger_falling)
+-              th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
++              thermal->polling_delay = IDLE_INTERVAL;
+       else
+-              th_zone->therm_dev->polling_delay = 0;
++              thermal->polling_delay = 0;
+-      mutex_unlock(&th_zone->therm_dev->lock);
++      mutex_unlock(&thermal->lock);
+       th_zone->mode = mode;
+-      thermal_zone_device_update(th_zone->therm_dev);
++      thermal_zone_device_update(thermal);
+       pr_info("thermal polling set for duration=%d msec\n",
+-                              th_zone->therm_dev->polling_delay);
++                              thermal->polling_delay);
+       return 0;
+ }
+@@ -97,6 +97,8 @@ static int exynos_get_trip_type(struct thermal_zone_device *thermal, int trip,
+ static int exynos_get_trip_temp(struct thermal_zone_device *thermal, int trip,
+                               unsigned long *temp)
+ {
++      struct exynos_thermal_zone *th_zone = thermal->devdata;
++
+       if (trip < GET_TRIP(MONITOR_ZONE) || trip > GET_TRIP(PANIC_ZONE))
+               return -EINVAL;
+@@ -123,6 +125,7 @@ static int exynos_bind(struct thermal_zone_device *thermal,
+ {
+       int ret = 0, i, tab_size, level;
+       struct freq_clip_table *tab_ptr, *clip_data;
++      struct exynos_thermal_zone *th_zone = thermal->devdata;
+       struct thermal_sensor_conf *data = th_zone->sensor_conf;
+       tab_ptr = (struct freq_clip_table *)data->cooling_data.freq_data;
+@@ -169,6 +172,7 @@ static int exynos_unbind(struct thermal_zone_device *thermal,
+                       struct thermal_cooling_device *cdev)
+ {
+       int ret = 0, i, tab_size;
++      struct exynos_thermal_zone *th_zone = thermal->devdata;
+       struct thermal_sensor_conf *data = th_zone->sensor_conf;
+       if (th_zone->bind == false)
+@@ -211,6 +215,7 @@ static int exynos_unbind(struct thermal_zone_device *thermal,
+ static int exynos_get_temp(struct thermal_zone_device *thermal,
+                       unsigned long *temp)
+ {
++      struct exynos_thermal_zone *th_zone = thermal->devdata;
+       void *data;
+       if (!th_zone->sensor_conf) {
+@@ -230,6 +235,7 @@ static int exynos_set_emul_temp(struct thermal_zone_device *thermal,
+ {
+       void *data;
+       int ret = -EINVAL;
++      struct exynos_thermal_zone *th_zone = thermal->devdata;
+       if (!th_zone->sensor_conf) {
+               pr_info("Temperature sensor not initialised\n");
+@@ -277,14 +283,22 @@ static struct thermal_zone_device_ops const exynos_dev_ops = {
+  * This function may be called from interrupt based temperature sensor
+  * when threshold is changed.
+  */
+-void exynos_report_trigger(void)
++void exynos_report_trigger(struct thermal_sensor_conf *conf)
+ {
+       unsigned int i;
+       char data[10];
+       char *envp[] = { data, NULL };
++      struct exynos_thermal_zone *th_zone;
+-      if (!th_zone || !th_zone->therm_dev)
++      if (!conf || !conf->pzone_data) {
++              pr_err("Invalid temperature sensor configuration data\n");
+               return;
++      }
++
++      th_zone = conf->pzone_data;
++      if (th_zone->therm_dev)
++              return;
++
+       if (th_zone->bind == false) {
+               for (i = 0; i < th_zone->cool_dev_size; i++) {
+                       if (!th_zone->cool_dev[i])
+@@ -322,6 +336,7 @@ int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
+ {
+       int ret;
+       struct cpumask mask_val;
++      struct exynos_thermal_zone *th_zone;
+       if (!sensor_conf || !sensor_conf->read_temperature) {
+               pr_err("Temperature sensor not initialised\n");
+@@ -343,7 +358,7 @@ int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
+       th_zone->cool_dev_size++;
+       th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name,
+-                      EXYNOS_ZONE_COUNT, 0, NULL, &exynos_dev_ops, NULL, 0,
++                      EXYNOS_ZONE_COUNT, 0, th_zone, &exynos_dev_ops, NULL, 0,
+                       sensor_conf->trip_data.trigger_falling ?
+                       0 : IDLE_INTERVAL);
+@@ -353,23 +368,29 @@ int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
+               goto err_unregister;
+       }
+       th_zone->mode = THERMAL_DEVICE_ENABLED;
++      sensor_conf->pzone_data = th_zone;
+       pr_info("Exynos: Kernel Thermal management registered\n");
+       return 0;
+ err_unregister:
+-      exynos_unregister_thermal();
++      exynos_unregister_thermal(sensor_conf);
+       return ret;
+ }
+ /* Un-Register with the in-kernel thermal management */
+-void exynos_unregister_thermal(void)
++void exynos_unregister_thermal(struct thermal_sensor_conf *sensor_conf)
+ {
+       int i;
++      struct exynos_thermal_zone *th_zone;
+-      if (!th_zone)
++      if (!sensor_conf || !sensor_conf->pzone_data) {
++              pr_err("Invalid temperature sensor configuration data\n");
+               return;
++      }
++
++      th_zone = sensor_conf->pzone_data;
+       if (th_zone->therm_dev)
+               thermal_zone_device_unregister(th_zone->therm_dev);
+diff --git a/drivers/thermal/samsung/exynos_thermal_common.h b/drivers/thermal/samsung/exynos_thermal_common.h
+index fee1588..86c1f84 100644
+--- a/drivers/thermal/samsung/exynos_thermal_common.h
++++ b/drivers/thermal/samsung/exynos_thermal_common.h
+@@ -85,22 +85,23 @@ struct thermal_sensor_conf {
+       struct thermal_trip_point_conf trip_data;
+       struct thermal_cooling_conf cooling_data;
+       void *private_data;
++      void *pzone_data;
+ };
+ /*Functions used exynos based thermal sensor driver*/
+ #ifdef CONFIG_EXYNOS_THERMAL_CORE
+-void exynos_unregister_thermal(void);
++void exynos_unregister_thermal(struct thermal_sensor_conf *sensor_conf);
+ int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf);
+-void exynos_report_trigger(void);
++void exynos_report_trigger(struct thermal_sensor_conf *sensor_conf);
+ #else
+ static inline void
+-exynos_unregister_thermal(void) { return; }
++exynos_unregister_thermal(struct thermal_sensor_conf *sensor_conf) { return; }
+ static inline int
+ exynos_register_thermal(struct thermal_sensor_conf *sensor_conf) { return 0; }
+ static inline void
+-exynos_report_trigger(void) { return; }
++exynos_report_trigger(struct thermal_sensor_conf *sensor_conf) { return; }
+ #endif /* CONFIG_EXYNOS_THERMAL_CORE */
+ #endif /* _EXYNOS_THERMAL_COMMON_H */
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+index f6f63ca..a7bba69 100644
+--- a/drivers/thermal/samsung/exynos_tmu.c
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -345,6 +345,12 @@ static int exynos_tmu_set_emulation(void *drv_data,       unsigned long temp)
+       { return -EINVAL; }
+ #endif/*CONFIG_THERMAL_EMULATION*/
++static struct thermal_sensor_conf exynos_sensor_conf = {
++      .name                   = "exynos-therm",
++      .read_temperature       = (int (*)(void *))exynos_tmu_read,
++      .write_emul_temp        = exynos_tmu_set_emulation,
++};
++
+ static void exynos_tmu_work(struct work_struct *work)
+ {
+       struct exynos_tmu_data *data = container_of(work,
+@@ -353,7 +359,7 @@ static void exynos_tmu_work(struct work_struct *work)
+       const struct exynos_tmu_registers *reg = pdata->registers;
+       unsigned int val_irq;
+-      exynos_report_trigger();
++      exynos_report_trigger(&exynos_sensor_conf);
+       mutex_lock(&data->lock);
+       clk_enable(data->clk);
+@@ -377,11 +383,6 @@ static irqreturn_t exynos_tmu_irq(int irq, void *id)
+       return IRQ_HANDLED;
+ }
+-static struct thermal_sensor_conf exynos_sensor_conf = {
+-      .name                   = "exynos-therm",
+-      .read_temperature       = (int (*)(void *))exynos_tmu_read,
+-      .write_emul_temp        = exynos_tmu_set_emulation,
+-};
+ #ifdef CONFIG_OF
+ static const struct of_device_id exynos_tmu_match[] = {
+@@ -541,7 +542,7 @@ static int exynos_tmu_remove(struct platform_device *pdev)
+       exynos_tmu_control(pdev, false);
+-      exynos_unregister_thermal();
++      exynos_unregister_thermal(&exynos_sensor_conf);
+       clk_unprepare(data->clk);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0964-thermal-exynos-Modify-private_data-to-appropriate-na.patch b/patches.tizen/0964-thermal-exynos-Modify-private_data-to-appropriate-na.patch
new file mode 100644 (file)
index 0000000..63bbd0a
--- /dev/null
@@ -0,0 +1,73 @@
+From 2309bd6f9ed9a36bd16af34a27b438553a5f8f23 Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Mon, 24 Jun 2013 16:20:35 +0530
+Subject: [PATCH 0964/1302] thermal: exynos: Modify private_data to appropriate
+ name driver_data
+
+This patch renames member private_data to driver_data of the thermal
+zone registration structure as this item stores the driver related
+data and uses it to call the driver related callbacks.
+
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_thermal_common.c | 4 ++--
+ drivers/thermal/samsung/exynos_thermal_common.h | 2 +-
+ drivers/thermal/samsung/exynos_tmu.c            | 2 +-
+ 3 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c
+index 0b014e8..c6eab8c 100644
+--- a/drivers/thermal/samsung/exynos_thermal_common.c
++++ b/drivers/thermal/samsung/exynos_thermal_common.c
+@@ -222,7 +222,7 @@ static int exynos_get_temp(struct thermal_zone_device *thermal,
+               pr_info("Temperature sensor not initialised\n");
+               return -EINVAL;
+       }
+-      data = th_zone->sensor_conf->private_data;
++      data = th_zone->sensor_conf->driver_data;
+       *temp = th_zone->sensor_conf->read_temperature(data);
+       /* convert the temperature into millicelsius */
+       *temp = *temp * MCELSIUS;
+@@ -241,7 +241,7 @@ static int exynos_set_emul_temp(struct thermal_zone_device *thermal,
+               pr_info("Temperature sensor not initialised\n");
+               return -EINVAL;
+       }
+-      data = th_zone->sensor_conf->private_data;
++      data = th_zone->sensor_conf->driver_data;
+       if (th_zone->sensor_conf->write_emul_temp)
+               ret = th_zone->sensor_conf->write_emul_temp(data, temp);
+       return ret;
+diff --git a/drivers/thermal/samsung/exynos_thermal_common.h b/drivers/thermal/samsung/exynos_thermal_common.h
+index 86c1f84..6ca3096 100644
+--- a/drivers/thermal/samsung/exynos_thermal_common.h
++++ b/drivers/thermal/samsung/exynos_thermal_common.h
+@@ -84,7 +84,7 @@ struct thermal_sensor_conf {
+       int (*write_emul_temp)(void *drv_data, unsigned long temp);
+       struct thermal_trip_point_conf trip_data;
+       struct thermal_cooling_conf cooling_data;
+-      void *private_data;
++      void *driver_data;
+       void *pzone_data;
+ };
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+index a7bba69..40e0cfd 100644
+--- a/drivers/thermal/samsung/exynos_tmu.c
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -504,7 +504,7 @@ static int exynos_tmu_probe(struct platform_device *pdev)
+       exynos_tmu_control(pdev, true);
+       /* Register the sensor with thermal management interface */
+-      (&exynos_sensor_conf)->private_data = data;
++      (&exynos_sensor_conf)->driver_data = data;
+       exynos_sensor_conf.trip_data.trip_count = pdata->trigger_enable[0] +
+                       pdata->trigger_enable[1] + pdata->trigger_enable[2]+
+                       pdata->trigger_enable[3];
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0965-thermal-exynos-Return-success-even-if-no-cooling-dat.patch b/patches.tizen/0965-thermal-exynos-Return-success-even-if-no-cooling-dat.patch
new file mode 100644 (file)
index 0000000..6b7a0f8
--- /dev/null
@@ -0,0 +1,44 @@
+From 0d7c5cef9f3d3bea953854e79713fb427e638224 Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Mon, 24 Jun 2013 16:20:36 +0530
+Subject: [PATCH 0965/1302] thermal: exynos: Return success even if no cooling
+ data supplied
+
+This patch removes the error return in the bind/unbind routine
+as the platform may not register any cpufreq cooling data.
+
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_thermal_common.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c
+index c6eab8c..99318e5 100644
+--- a/drivers/thermal/samsung/exynos_thermal_common.c
++++ b/drivers/thermal/samsung/exynos_thermal_common.c
+@@ -132,7 +132,7 @@ static int exynos_bind(struct thermal_zone_device *thermal,
+       tab_size = data->cooling_data.freq_clip_count;
+       if (tab_ptr == NULL || tab_size == 0)
+-              return -EINVAL;
++              return 0;
+       /* find the cooling device registered*/
+       for (i = 0; i < th_zone->cool_dev_size; i++)
+@@ -181,7 +181,7 @@ static int exynos_unbind(struct thermal_zone_device *thermal,
+       tab_size = data->cooling_data.freq_clip_count;
+       if (tab_size == 0)
+-              return -EINVAL;
++              return 0;
+       /* find the cooling device registered*/
+       for (i = 0; i < th_zone->cool_dev_size; i++)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0966-thermal-exynos-Make-the-zone-handling-use-trip-infor.patch b/patches.tizen/0966-thermal-exynos-Make-the-zone-handling-use-trip-infor.patch
new file mode 100644 (file)
index 0000000..a9159f0
--- /dev/null
@@ -0,0 +1,167 @@
+From 786884168c167d68a698cafe0bb220cba8f73824 Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Mon, 24 Jun 2013 16:20:37 +0530
+Subject: [PATCH 0966/1302] thermal: exynos: Make the zone handling use trip
+ information
+
+This code simplifies the zone handling to use the trip information passed
+by the TMU driver and not the hardcoded macros. This also helps in adding
+more zone support.
+
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_thermal_common.c | 67 ++++++++++++++++---------
+ drivers/thermal/samsung/exynos_thermal_common.h |  3 +-
+ drivers/thermal/samsung/exynos_tmu.c            |  5 +-
+ 3 files changed, 47 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c
+index 99318e5..af0ae77 100644
+--- a/drivers/thermal/samsung/exynos_thermal_common.c
++++ b/drivers/thermal/samsung/exynos_thermal_common.c
+@@ -79,17 +79,24 @@ static int exynos_set_mode(struct thermal_zone_device *thermal,
+ static int exynos_get_trip_type(struct thermal_zone_device *thermal, int trip,
+                                enum thermal_trip_type *type)
+ {
+-      switch (GET_ZONE(trip)) {
+-      case MONITOR_ZONE:
+-      case WARN_ZONE:
+-              *type = THERMAL_TRIP_ACTIVE;
+-              break;
+-      case PANIC_ZONE:
++      struct exynos_thermal_zone *th_zone = thermal->devdata;
++      int max_trip = th_zone->sensor_conf->trip_data.trip_count;
++      int trip_type;
++
++      if (trip < 0 || trip >= max_trip)
++              return -EINVAL;
++
++      trip_type = th_zone->sensor_conf->trip_data.trip_type[trip];
++
++      if (trip_type == SW_TRIP)
+               *type = THERMAL_TRIP_CRITICAL;
+-              break;
+-      default:
++      else if (trip_type == THROTTLE_ACTIVE)
++              *type = THERMAL_TRIP_ACTIVE;
++      else if (trip_type == THROTTLE_PASSIVE)
++              *type = THERMAL_TRIP_PASSIVE;
++      else
+               return -EINVAL;
+-      }
++
+       return 0;
+ }
+@@ -98,8 +105,9 @@ static int exynos_get_trip_temp(struct thermal_zone_device *thermal, int trip,
+                               unsigned long *temp)
+ {
+       struct exynos_thermal_zone *th_zone = thermal->devdata;
++      int max_trip = th_zone->sensor_conf->trip_data.trip_count;
+-      if (trip < GET_TRIP(MONITOR_ZONE) || trip > GET_TRIP(PANIC_ZONE))
++      if (trip < 0 || trip >= max_trip)
+               return -EINVAL;
+       *temp = th_zone->sensor_conf->trip_data.trip_val[trip];
+@@ -113,10 +121,10 @@ static int exynos_get_trip_temp(struct thermal_zone_device *thermal, int trip,
+ static int exynos_get_crit_temp(struct thermal_zone_device *thermal,
+                               unsigned long *temp)
+ {
+-      int ret;
+-      /* Panic zone */
+-      ret = exynos_get_trip_temp(thermal, GET_TRIP(PANIC_ZONE), temp);
+-      return ret;
++      struct exynos_thermal_zone *th_zone = thermal->devdata;
++      int max_trip = th_zone->sensor_conf->trip_data.trip_count;
++      /* Get the temp of highest trip*/
++      return exynos_get_trip_temp(thermal, max_trip - 1, temp);
+ }
+ /* Bind callback functions for thermal zone */
+@@ -348,19 +356,28 @@ int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
+               return -ENOMEM;
+       th_zone->sensor_conf = sensor_conf;
+-      cpumask_set_cpu(0, &mask_val);
+-      th_zone->cool_dev[0] = cpufreq_cooling_register(&mask_val);
+-      if (IS_ERR(th_zone->cool_dev[0])) {
+-              pr_err("Failed to register cpufreq cooling device\n");
+-              ret = -EINVAL;
+-              goto err_unregister;
++      /*
++       * TODO: 1) Handle multiple cooling devices in a thermal zone
++       *       2) Add a flag/name in cooling info to map to specific
++       *       sensor
++       */
++      if (sensor_conf->cooling_data.freq_clip_count > 0) {
++              cpumask_set_cpu(0, &mask_val);
++              th_zone->cool_dev[th_zone->cool_dev_size] =
++                                      cpufreq_cooling_register(&mask_val);
++              if (IS_ERR(th_zone->cool_dev[th_zone->cool_dev_size])) {
++                      pr_err("Failed to register cpufreq cooling device\n");
++                      ret = -EINVAL;
++                      goto err_unregister;
++              }
++              th_zone->cool_dev_size++;
+       }
+-      th_zone->cool_dev_size++;
+-      th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name,
+-                      EXYNOS_ZONE_COUNT, 0, th_zone, &exynos_dev_ops, NULL, 0,
+-                      sensor_conf->trip_data.trigger_falling ?
+-                      0 : IDLE_INTERVAL);
++      th_zone->therm_dev = thermal_zone_device_register(
++                      sensor_conf->name, sensor_conf->trip_data.trip_count,
++                      0, th_zone, &exynos_dev_ops, NULL, 0,
++                      sensor_conf->trip_data.trigger_falling ? 0 :
++                      IDLE_INTERVAL);
+       if (IS_ERR(th_zone->therm_dev)) {
+               pr_err("Failed to register thermal zone device\n");
+diff --git a/drivers/thermal/samsung/exynos_thermal_common.h b/drivers/thermal/samsung/exynos_thermal_common.h
+index 6ca3096..bfcf69e 100644
+--- a/drivers/thermal/samsung/exynos_thermal_common.h
++++ b/drivers/thermal/samsung/exynos_thermal_common.h
+@@ -42,8 +42,6 @@
+ #define GET_ZONE(trip) (trip + 2)
+ #define GET_TRIP(zone) (zone - 2)
+-#define EXYNOS_ZONE_COUNT     3
+-
+ enum trigger_type {
+       THROTTLE_ACTIVE = 1,
+       THROTTLE_PASSIVE,
+@@ -69,6 +67,7 @@ struct freq_clip_table {
+ struct        thermal_trip_point_conf {
+       int trip_val[MAX_TRIP_COUNT];
++      int trip_type[MAX_TRIP_COUNT];
+       int trip_count;
+       unsigned char trigger_falling;
+ };
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+index 40e0cfd..acbd295 100644
+--- a/drivers/thermal/samsung/exynos_tmu.c
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -509,9 +509,12 @@ static int exynos_tmu_probe(struct platform_device *pdev)
+                       pdata->trigger_enable[1] + pdata->trigger_enable[2]+
+                       pdata->trigger_enable[3];
+-      for (i = 0; i < exynos_sensor_conf.trip_data.trip_count; i++)
++      for (i = 0; i < exynos_sensor_conf.trip_data.trip_count; i++) {
+               exynos_sensor_conf.trip_data.trip_val[i] =
+                       pdata->threshold + pdata->trigger_levels[i];
++              exynos_sensor_conf.trip_data.trip_type[i] =
++                                      pdata->trigger_type[i];
++      }
+       exynos_sensor_conf.trip_data.trigger_falling = pdata->threshold_falling;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0967-thermal-exynos-Remove-non-DT-based-support.patch b/patches.tizen/0967-thermal-exynos-Remove-non-DT-based-support.patch
new file mode 100644 (file)
index 0000000..ecfd281
--- /dev/null
@@ -0,0 +1,63 @@
+From 0d752e697ca4008ba7c5b635fbb01c2183873438 Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Mon, 24 Jun 2013 16:20:38 +0530
+Subject: [PATCH 0967/1302] thermal: exynos: Remove non DT based support
+
+Recently non DT support from Exynos platform is removed and hence
+removing non DT support from the driver also. This will help in easy
+maintainence.
+
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_tmu.c | 17 +----------------
+ 1 file changed, 1 insertion(+), 16 deletions(-)
+
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+index acbd295..4356118 100644
+--- a/drivers/thermal/samsung/exynos_tmu.c
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -403,19 +403,6 @@ static const struct of_device_id exynos_tmu_match[] = {
+ MODULE_DEVICE_TABLE(of, exynos_tmu_match);
+ #endif
+-static struct platform_device_id exynos_tmu_driver_ids[] = {
+-      {
+-              .name           = "exynos4210-tmu",
+-              .driver_data    = (kernel_ulong_t)EXYNOS4210_TMU_DRV_DATA,
+-      },
+-      {
+-              .name           = "exynos5250-tmu",
+-              .driver_data    = (kernel_ulong_t)EXYNOS5250_TMU_DRV_DATA,
+-      },
+-      { },
+-};
+-MODULE_DEVICE_TABLE(platform, exynos_tmu_driver_ids);
+-
+ static inline struct  exynos_tmu_platform_data *exynos_get_driver_data(
+                       struct platform_device *pdev)
+ {
+@@ -428,8 +415,7 @@ static inline struct  exynos_tmu_platform_data *exynos_get_driver_data(
+               return (struct exynos_tmu_platform_data *) match->data;
+       }
+ #endif
+-      return (struct exynos_tmu_platform_data *)
+-                      platform_get_device_id(pdev)->driver_data;
++      return NULL;
+ }
+ static int exynos_tmu_probe(struct platform_device *pdev)
+@@ -586,7 +572,6 @@ static struct platform_driver exynos_tmu_driver = {
+       },
+       .probe = exynos_tmu_probe,
+       .remove = exynos_tmu_remove,
+-      .id_table = exynos_tmu_driver_ids,
+ };
+ module_platform_driver(exynos_tmu_driver);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0968-thermal-exynos-Add-support-to-handle-many-instances-.patch b/patches.tizen/0968-thermal-exynos-Add-support-to-handle-many-instances-.patch
new file mode 100644 (file)
index 0000000..7d7c4cb
--- /dev/null
@@ -0,0 +1,522 @@
+From 82ff262bbb141ec5b1739d885672b79327ba1482 Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Mon, 24 Jun 2013 16:20:39 +0530
+Subject: [PATCH 0968/1302] thermal: exynos: Add support to handle many
+ instances of TMU
+
+This patch adds support to handle multiple instances of the TMU controllers.
+This is done by removing the static structure to register with the core thermal
+and creating it dynamically for each instance of the TMU controller. The
+interrupt is made shared type to handle shared interrupts. Now since the ISR needs
+the core thermal framework to be registered so request_irq is moved after the core
+registration is done.
+Also the identifier of the TMU controller is extracted from device tree alias. This
+will be used for TMU specific initialisation.
+
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_thermal_common.h |   1 +
+ drivers/thermal/samsung/exynos_tmu.c            | 158 ++++++++++++++++--------
+ drivers/thermal/samsung/exynos_tmu.h            |  13 ++
+ drivers/thermal/samsung/exynos_tmu_data.c       | 145 ++++++++++++----------
+ drivers/thermal/samsung/exynos_tmu_data.h       |   4 +-
+ 5 files changed, 203 insertions(+), 118 deletions(-)
+
+diff --git a/drivers/thermal/samsung/exynos_thermal_common.h b/drivers/thermal/samsung/exynos_thermal_common.h
+index bfcf69e..bc3016e 100644
+--- a/drivers/thermal/samsung/exynos_thermal_common.h
++++ b/drivers/thermal/samsung/exynos_thermal_common.h
+@@ -85,6 +85,7 @@ struct thermal_sensor_conf {
+       struct thermal_cooling_conf cooling_data;
+       void *driver_data;
+       void *pzone_data;
++      struct device *dev;
+ };
+ /*Functions used exynos based thermal sensor driver*/
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+index 4356118..7f65fe0 100644
+--- a/drivers/thermal/samsung/exynos_tmu.c
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -26,15 +26,32 @@
+ #include <linux/interrupt.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/of_irq.h>
+ #include <linux/platform_device.h>
+ #include "exynos_thermal_common.h"
+ #include "exynos_tmu.h"
+ #include "exynos_tmu_data.h"
++/**
++ * struct exynos_tmu_data : A structure to hold the private data of the TMU
++      driver
++ * @id: identifier of the one instance of the TMU controller.
++ * @pdata: pointer to the tmu platform/configuration data
++ * @base: base address of the single instance of the TMU controller.
++ * @irq: irq number of the TMU controller.
++ * @soc: id of the SOC type.
++ * @irq_work: pointer to the irq work structure.
++ * @lock: lock to implement synchronization.
++ * @clk: pointer to the clock structure.
++ * @temp_error1: fused value of the first point trim.
++ * @temp_error2: fused value of the second point trim.
++ * @reg_conf: pointer to structure to register with core thermal.
++ */
+ struct exynos_tmu_data {
++      int id;
+       struct exynos_tmu_platform_data *pdata;
+-      struct resource *mem;
+       void __iomem *base;
+       int irq;
+       enum soc_type soc;
+@@ -42,6 +59,7 @@ struct exynos_tmu_data {
+       struct mutex lock;
+       struct clk *clk;
+       u8 temp_error1, temp_error2;
++      struct thermal_sensor_conf *reg_conf;
+ };
+ /*
+@@ -345,12 +363,6 @@ static int exynos_tmu_set_emulation(void *drv_data,       unsigned long temp)
+       { return -EINVAL; }
+ #endif/*CONFIG_THERMAL_EMULATION*/
+-static struct thermal_sensor_conf exynos_sensor_conf = {
+-      .name                   = "exynos-therm",
+-      .read_temperature       = (int (*)(void *))exynos_tmu_read,
+-      .write_emul_temp        = exynos_tmu_set_emulation,
+-};
+-
+ static void exynos_tmu_work(struct work_struct *work)
+ {
+       struct exynos_tmu_data *data = container_of(work,
+@@ -359,7 +371,7 @@ static void exynos_tmu_work(struct work_struct *work)
+       const struct exynos_tmu_registers *reg = pdata->registers;
+       unsigned int val_irq;
+-      exynos_report_trigger(&exynos_sensor_conf);
++      exynos_report_trigger(data->reg_conf);
+       mutex_lock(&data->lock);
+       clk_enable(data->clk);
+@@ -404,33 +416,73 @@ MODULE_DEVICE_TABLE(of, exynos_tmu_match);
+ #endif
+ static inline struct  exynos_tmu_platform_data *exynos_get_driver_data(
+-                      struct platform_device *pdev)
++                      struct platform_device *pdev, int id)
+ {
+ #ifdef CONFIG_OF
++      struct  exynos_tmu_init_data *data_table;
++      struct exynos_tmu_platform_data *tmu_data;
+       if (pdev->dev.of_node) {
+               const struct of_device_id *match;
+               match = of_match_node(exynos_tmu_match, pdev->dev.of_node);
+               if (!match)
+                       return NULL;
+-              return (struct exynos_tmu_platform_data *) match->data;
++              data_table = (struct exynos_tmu_init_data *) match->data;
++              if (!data_table || id >= data_table->tmu_count)
++                      return NULL;
++              tmu_data = data_table->tmu_data;
++              return (struct exynos_tmu_platform_data *) (tmu_data + id);
+       }
+ #endif
+       return NULL;
+ }
+-static int exynos_tmu_probe(struct platform_device *pdev)
++static int exynos_map_dt_data(struct platform_device *pdev)
+ {
+-      struct exynos_tmu_data *data;
+-      struct exynos_tmu_platform_data *pdata = pdev->dev.platform_data;
+-      int ret, i;
++      struct exynos_tmu_data *data = platform_get_drvdata(pdev);
++      struct exynos_tmu_platform_data *pdata;
++      struct resource res;
++
++      if (!data)
++              return -ENODEV;
+-      if (!pdata)
+-              pdata = exynos_get_driver_data(pdev);
++      data->id = of_alias_get_id(pdev->dev.of_node, "tmuctrl");
++      if (data->id < 0)
++              data->id = 0;
++      data->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
++      if (data->irq <= 0) {
++              dev_err(&pdev->dev, "failed to get IRQ\n");
++              return -ENODEV;
++      }
++
++      if (of_address_to_resource(pdev->dev.of_node, 0, &res)) {
++              dev_err(&pdev->dev, "failed to get Resource 0\n");
++              return -ENODEV;
++      }
++
++      data->base = devm_ioremap(&pdev->dev, res.start, resource_size(&res));
++      if (!data->base) {
++              dev_err(&pdev->dev, "Failed to ioremap memory\n");
++              return -EADDRNOTAVAIL;
++      }
++
++      pdata = exynos_get_driver_data(pdev, data->id);
+       if (!pdata) {
+               dev_err(&pdev->dev, "No platform init data supplied.\n");
+               return -ENODEV;
+       }
++      data->pdata = pdata;
++
++      return 0;
++}
++
++static int exynos_tmu_probe(struct platform_device *pdev)
++{
++      struct exynos_tmu_data *data;
++      struct exynos_tmu_platform_data *pdata;
++      struct thermal_sensor_conf *sensor_conf;
++      int ret, i;
++
+       data = devm_kzalloc(&pdev->dev, sizeof(struct exynos_tmu_data),
+                                       GFP_KERNEL);
+       if (!data) {
+@@ -438,25 +490,16 @@ static int exynos_tmu_probe(struct platform_device *pdev)
+               return -ENOMEM;
+       }
+-      data->irq = platform_get_irq(pdev, 0);
+-      if (data->irq < 0) {
+-              dev_err(&pdev->dev, "Failed to get platform irq\n");
+-              return data->irq;
+-      }
++      platform_set_drvdata(pdev, data);
++      mutex_init(&data->lock);
+-      INIT_WORK(&data->irq_work, exynos_tmu_work);
++      ret = exynos_map_dt_data(pdev);
++      if (ret)
++              return ret;
+-      data->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-      data->base = devm_ioremap_resource(&pdev->dev, data->mem);
+-      if (IS_ERR(data->base))
+-              return PTR_ERR(data->base);
++      pdata = data->pdata;
+-      ret = devm_request_irq(&pdev->dev, data->irq, exynos_tmu_irq,
+-              IRQF_TRIGGER_RISING, "exynos-tmu", data);
+-      if (ret) {
+-              dev_err(&pdev->dev, "Failed to request irq: %d\n", data->irq);
+-              return ret;
+-      }
++      INIT_WORK(&data->irq_work, exynos_tmu_work);
+       data->clk = devm_clk_get(&pdev->dev, "tmu_apbif");
+       if (IS_ERR(data->clk)) {
+@@ -477,10 +520,6 @@ static int exynos_tmu_probe(struct platform_device *pdev)
+               goto err_clk;
+       }
+-      data->pdata = pdata;
+-      platform_set_drvdata(pdev, data);
+-      mutex_init(&data->lock);
+-
+       ret = exynos_tmu_initialize(pdev);
+       if (ret) {
+               dev_err(&pdev->dev, "Failed to initialize TMU\n");
+@@ -489,35 +528,54 @@ static int exynos_tmu_probe(struct platform_device *pdev)
+       exynos_tmu_control(pdev, true);
+-      /* Register the sensor with thermal management interface */
+-      (&exynos_sensor_conf)->driver_data = data;
+-      exynos_sensor_conf.trip_data.trip_count = pdata->trigger_enable[0] +
++      /* Allocate a structure to register with the exynos core thermal */
++      sensor_conf = devm_kzalloc(&pdev->dev,
++                              sizeof(struct thermal_sensor_conf), GFP_KERNEL);
++      if (!sensor_conf) {
++              dev_err(&pdev->dev, "Failed to allocate registration struct\n");
++              ret = -ENOMEM;
++              goto err_clk;
++      }
++      sprintf(sensor_conf->name, "therm_zone%d", data->id);
++      sensor_conf->read_temperature = (int (*)(void *))exynos_tmu_read;
++      sensor_conf->write_emul_temp =
++              (int (*)(void *, unsigned long))exynos_tmu_set_emulation;
++      sensor_conf->driver_data = data;
++      sensor_conf->trip_data.trip_count = pdata->trigger_enable[0] +
+                       pdata->trigger_enable[1] + pdata->trigger_enable[2]+
+                       pdata->trigger_enable[3];
+-      for (i = 0; i < exynos_sensor_conf.trip_data.trip_count; i++) {
+-              exynos_sensor_conf.trip_data.trip_val[i] =
++      for (i = 0; i < sensor_conf->trip_data.trip_count; i++) {
++              sensor_conf->trip_data.trip_val[i] =
+                       pdata->threshold + pdata->trigger_levels[i];
+-              exynos_sensor_conf.trip_data.trip_type[i] =
++              sensor_conf->trip_data.trip_type[i] =
+                                       pdata->trigger_type[i];
+       }
+-      exynos_sensor_conf.trip_data.trigger_falling = pdata->threshold_falling;
++      sensor_conf->trip_data.trigger_falling = pdata->threshold_falling;
+-      exynos_sensor_conf.cooling_data.freq_clip_count =
+-                                              pdata->freq_tab_count;
++      sensor_conf->cooling_data.freq_clip_count = pdata->freq_tab_count;
+       for (i = 0; i < pdata->freq_tab_count; i++) {
+-              exynos_sensor_conf.cooling_data.freq_data[i].freq_clip_max =
++              sensor_conf->cooling_data.freq_data[i].freq_clip_max =
+                                       pdata->freq_tab[i].freq_clip_max;
+-              exynos_sensor_conf.cooling_data.freq_data[i].temp_level =
++              sensor_conf->cooling_data.freq_data[i].temp_level =
+                                       pdata->freq_tab[i].temp_level;
+       }
+-
+-      ret = exynos_register_thermal(&exynos_sensor_conf);
++      sensor_conf->dev = &pdev->dev;
++      /* Register the sensor with thermal management interface */
++      ret = exynos_register_thermal(sensor_conf);
+       if (ret) {
+               dev_err(&pdev->dev, "Failed to register thermal interface\n");
+               goto err_clk;
+       }
++      data->reg_conf = sensor_conf;
++
++      ret = devm_request_irq(&pdev->dev, data->irq, exynos_tmu_irq,
++              IRQF_TRIGGER_RISING | IRQF_SHARED, dev_name(&pdev->dev), data);
++      if (ret) {
++              dev_err(&pdev->dev, "Failed to request irq: %d\n", data->irq);
++              goto err_clk;
++      }
+       return 0;
+ err_clk:
+@@ -531,7 +589,7 @@ static int exynos_tmu_remove(struct platform_device *pdev)
+       exynos_tmu_control(pdev, false);
+-      exynos_unregister_thermal(&exynos_sensor_conf);
++      exynos_unregister_thermal(data->reg_conf);
+       clk_unprepare(data->clk);
+diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h
+index ef5dc0e..53fa702 100644
+--- a/drivers/thermal/samsung/exynos_tmu.h
++++ b/drivers/thermal/samsung/exynos_tmu.h
+@@ -250,4 +250,17 @@ struct exynos_tmu_platform_data {
+       unsigned int freq_tab_count;
+       const struct exynos_tmu_registers *registers;
+ };
++
++/**
++ * struct exynos_tmu_init_data
++ * @tmu_count: number of TMU instances.
++ * @tmu_data: platform data of all TMU instances.
++ * This structure is required to store data for multi-instance exynos tmu
++ * driver.
++ */
++struct exynos_tmu_init_data {
++      int tmu_count;
++      struct exynos_tmu_platform_data tmu_data[];
++};
++
+ #endif /* _EXYNOS_TMU_H */
+diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c
+index 217b8f5..a5c25b4 100644
+--- a/drivers/thermal/samsung/exynos_tmu_data.c
++++ b/drivers/thermal/samsung/exynos_tmu_data.c
+@@ -48,38 +48,44 @@ static const struct exynos_tmu_registers exynos4210_tmu_registers = {
+       .tmu_intstat = EXYNOS_TMU_REG_INTSTAT,
+       .tmu_intclear = EXYNOS_TMU_REG_INTCLEAR,
+ };
+-struct exynos_tmu_platform_data const exynos4210_default_tmu_data = {
+-      .threshold = 80,
+-      .trigger_levels[0] = 5,
+-      .trigger_levels[1] = 20,
+-      .trigger_levels[2] = 30,
+-      .trigger_enable[0] = true,
+-      .trigger_enable[1] = true,
+-      .trigger_enable[2] = true,
+-      .trigger_enable[3] = false,
+-      .trigger_type[0] = THROTTLE_ACTIVE,
+-      .trigger_type[1] = THROTTLE_ACTIVE,
+-      .trigger_type[2] = SW_TRIP,
+-      .max_trigger_level = 4,
+-      .gain = 15,
+-      .reference_voltage = 7,
+-      .cal_type = TYPE_ONE_POINT_TRIMMING,
+-      .min_efuse_value = 40,
+-      .max_efuse_value = 100,
+-      .first_point_trim = 25,
+-      .second_point_trim = 85,
+-      .default_temp_offset = 50,
+-      .freq_tab[0] = {
+-              .freq_clip_max = 800 * 1000,
+-              .temp_level = 85,
+-      },
+-      .freq_tab[1] = {
+-              .freq_clip_max = 200 * 1000,
+-              .temp_level = 100,
++
++struct exynos_tmu_init_data const exynos4210_default_tmu_data = {
++      .tmu_data = {
++              {
++              .threshold = 80,
++              .trigger_levels[0] = 5,
++              .trigger_levels[1] = 20,
++              .trigger_levels[2] = 30,
++              .trigger_enable[0] = true,
++              .trigger_enable[1] = true,
++              .trigger_enable[2] = true,
++              .trigger_enable[3] = false,
++              .trigger_type[0] = THROTTLE_ACTIVE,
++              .trigger_type[1] = THROTTLE_ACTIVE,
++              .trigger_type[2] = SW_TRIP,
++              .max_trigger_level = 4,
++              .gain = 15,
++              .reference_voltage = 7,
++              .cal_type = TYPE_ONE_POINT_TRIMMING,
++              .min_efuse_value = 40,
++              .max_efuse_value = 100,
++              .first_point_trim = 25,
++              .second_point_trim = 85,
++              .default_temp_offset = 50,
++              .freq_tab[0] = {
++                      .freq_clip_max = 800 * 1000,
++                      .temp_level = 85,
++                      },
++              .freq_tab[1] = {
++                      .freq_clip_max = 200 * 1000,
++                      .temp_level = 100,
++              },
++              .freq_tab_count = 2,
++              .type = SOC_ARCH_EXYNOS4210,
++              .registers = &exynos4210_tmu_registers,
++              },
+       },
+-      .freq_tab_count = 2,
+-      .type = SOC_ARCH_EXYNOS4210,
+-      .registers = &exynos4210_tmu_registers,
++      .tmu_count = 1,
+ };
+ #endif
+@@ -120,41 +126,48 @@ static const struct exynos_tmu_registers exynos5250_tmu_registers = {
+       .emul_time_shift = EXYNOS_EMUL_TIME_SHIFT,
+       .emul_time_mask = EXYNOS_EMUL_TIME_MASK,
+ };
+-struct exynos_tmu_platform_data const exynos5250_default_tmu_data = {
+-      .threshold_falling = 10,
+-      .trigger_levels[0] = 85,
+-      .trigger_levels[1] = 103,
+-      .trigger_levels[2] = 110,
+-      .trigger_levels[3] = 120,
+-      .trigger_enable[0] = true,
+-      .trigger_enable[1] = true,
+-      .trigger_enable[2] = true,
+-      .trigger_enable[3] = false,
+-      .trigger_type[0] = THROTTLE_ACTIVE,
+-      .trigger_type[1] = THROTTLE_ACTIVE,
+-      .trigger_type[2] = SW_TRIP,
+-      .trigger_type[3] = HW_TRIP,
+-      .max_trigger_level = 4,
+-      .gain = 8,
+-      .reference_voltage = 16,
+-      .noise_cancel_mode = 4,
+-      .cal_type = TYPE_ONE_POINT_TRIMMING,
+-      .efuse_value = 55,
+-      .min_efuse_value = 40,
+-      .max_efuse_value = 100,
+-      .first_point_trim = 25,
+-      .second_point_trim = 85,
+-      .default_temp_offset = 50,
+-      .freq_tab[0] = {
+-              .freq_clip_max = 800 * 1000,
+-              .temp_level = 85,
+-      },
+-      .freq_tab[1] = {
+-              .freq_clip_max = 200 * 1000,
+-              .temp_level = 103,
+-      },
+-      .freq_tab_count = 2,
+-      .type = SOC_ARCH_EXYNOS,
++
++#define EXYNOS5250_TMU_DATA \
++      .threshold_falling = 10, \
++      .trigger_levels[0] = 85, \
++      .trigger_levels[1] = 103, \
++      .trigger_levels[2] = 110, \
++      .trigger_levels[3] = 120, \
++      .trigger_enable[0] = true, \
++      .trigger_enable[1] = true, \
++      .trigger_enable[2] = true, \
++      .trigger_enable[3] = false, \
++      .trigger_type[0] = THROTTLE_ACTIVE, \
++      .trigger_type[1] = THROTTLE_ACTIVE, \
++      .trigger_type[2] = SW_TRIP, \
++      .trigger_type[3] = HW_TRIP, \
++      .max_trigger_level = 4, \
++      .gain = 8, \
++      .reference_voltage = 16, \
++      .noise_cancel_mode = 4, \
++      .cal_type = TYPE_ONE_POINT_TRIMMING, \
++      .efuse_value = 55, \
++      .min_efuse_value = 40, \
++      .max_efuse_value = 100, \
++      .first_point_trim = 25, \
++      .second_point_trim = 85, \
++      .default_temp_offset = 50, \
++      .freq_tab[0] = { \
++              .freq_clip_max = 800 * 1000, \
++              .temp_level = 85, \
++      }, \
++      .freq_tab[1] = { \
++              .freq_clip_max = 200 * 1000, \
++              .temp_level = 103, \
++      }, \
++      .freq_tab_count = 2, \
++      .type = SOC_ARCH_EXYNOS, \
+       .registers = &exynos5250_tmu_registers,
++
++struct exynos_tmu_init_data const exynos5250_default_tmu_data = {
++      .tmu_data = {
++              { EXYNOS5250_TMU_DATA },
++      },
++      .tmu_count = 1,
+ };
+ #endif
+diff --git a/drivers/thermal/samsung/exynos_tmu_data.h b/drivers/thermal/samsung/exynos_tmu_data.h
+index 4acf070..139dbbb 100644
+--- a/drivers/thermal/samsung/exynos_tmu_data.h
++++ b/drivers/thermal/samsung/exynos_tmu_data.h
+@@ -94,14 +94,14 @@
+ #define EXYNOS_MAX_TRIGGER_PER_REG    4
+ #if defined(CONFIG_CPU_EXYNOS4210)
+-extern struct exynos_tmu_platform_data const exynos4210_default_tmu_data;
++extern struct exynos_tmu_init_data const exynos4210_default_tmu_data;
+ #define EXYNOS4210_TMU_DRV_DATA (&exynos4210_default_tmu_data)
+ #else
+ #define EXYNOS4210_TMU_DRV_DATA (NULL)
+ #endif
+ #if (defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412))
+-extern struct exynos_tmu_platform_data const exynos5250_default_tmu_data;
++extern struct exynos_tmu_init_data const exynos5250_default_tmu_data;
+ #define EXYNOS5250_TMU_DRV_DATA (&exynos5250_default_tmu_data)
+ #else
+ #define EXYNOS5250_TMU_DRV_DATA (NULL)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0969-thermal-exynos-Add-TMU-features-to-check-instead-of-.patch b/patches.tizen/0969-thermal-exynos-Add-TMU-features-to-check-instead-of-.patch
new file mode 100644 (file)
index 0000000..65109c5
--- /dev/null
@@ -0,0 +1,166 @@
+From 5110de02c7add83b9d598d7a0207d9cd2f490a17 Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Mon, 24 Jun 2013 16:20:40 +0530
+Subject: [PATCH 0969/1302] thermal: exynos: Add TMU features to check instead
+ of using SOC type
+
+This patch adds several features supported by TMU as bitfields.
+This features varies across different SOC type and comparing
+the features present in the TMU is more logical than comparing
+the soc itself.
+
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_tmu.c      | 26 ++++++++++++++++----------
+ drivers/thermal/samsung/exynos_tmu.h      | 31 +++++++++++++++++++++++++++++++
+ drivers/thermal/samsung/exynos_tmu_data.c |  6 +++++-
+ 3 files changed, 52 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+index 7f65fe0..05b95c6 100644
+--- a/drivers/thermal/samsung/exynos_tmu.c
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -142,13 +142,15 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
+       mutex_lock(&data->lock);
+       clk_enable(data->clk);
+-      status = readb(data->base + reg->tmu_status);
+-      if (!status) {
+-              ret = -EBUSY;
+-              goto out;
++      if (TMU_SUPPORTS(pdata, READY_STATUS)) {
++              status = readb(data->base + reg->tmu_status);
++              if (!status) {
++                      ret = -EBUSY;
++                      goto out;
++              }
+       }
+-      if (data->soc == SOC_ARCH_EXYNOS)
++      if (TMU_SUPPORTS(pdata, TRIM_RELOAD))
+               __raw_writel(1, data->base + reg->triminfo_ctrl);
+       /* Save trimming info in order to perform calibration */
+@@ -287,7 +289,7 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on)
+                       pdata->trigger_enable[2] << reg->inten_rise2_shift |
+                       pdata->trigger_enable[1] << reg->inten_rise1_shift |
+                       pdata->trigger_enable[0] << reg->inten_rise0_shift;
+-              if (pdata->threshold_falling)
++              if (TMU_SUPPORTS(pdata, FALLING_TRIP))
+                       interrupt_en |=
+                               interrupt_en << reg->inten_fall0_shift;
+       } else {
+@@ -329,7 +331,7 @@ static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp)
+       unsigned int val;
+       int ret = -EINVAL;
+-      if (data->soc == SOC_ARCH_EXYNOS4210)
++      if (!TMU_SUPPORTS(pdata, EMULATION))
+               goto out;
+       if (temp && temp < MCELSIUS)
+@@ -343,9 +345,13 @@ static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp)
+       if (temp) {
+               temp /= MCELSIUS;
+-              val = (EXYNOS_EMUL_TIME << reg->emul_time_shift) |
+-                      (temp_to_code(data, temp)
+-                       << reg->emul_temp_shift) | EXYNOS_EMUL_ENABLE;
++              if (TMU_SUPPORTS(pdata, EMUL_TIME)) {
++                      val &= ~(EXYNOS_EMUL_TIME_MASK << reg->emul_time_shift);
++                      val |= (EXYNOS_EMUL_TIME << reg->emul_time_shift);
++              }
++              val &= ~(EXYNOS_EMUL_DATA_MASK << reg->emul_temp_shift);
++              val |= (temp_to_code(data, temp) << reg->emul_temp_shift) |
++                      EXYNOS_EMUL_ENABLE;
+       } else {
+               val &= ~EXYNOS_EMUL_ENABLE;
+       }
+diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h
+index 53fa702..ff8844f 100644
+--- a/drivers/thermal/samsung/exynos_tmu.h
++++ b/drivers/thermal/samsung/exynos_tmu.h
+@@ -43,6 +43,34 @@ enum soc_type {
+ };
+ /**
++ * EXYNOS TMU supported features.
++ * TMU_SUPPORT_EMULATION - This features is used to set user defined
++ *                    temperature to the TMU controller.
++ * TMU_SUPPORT_MULTI_INST - This features denotes that the soc
++ *                    has many instances of TMU.
++ * TMU_SUPPORT_TRIM_RELOAD - This features shows that trimming can
++ *                    be reloaded.
++ * TMU_SUPPORT_FALLING_TRIP - This features shows that interrupt can
++ *                    be registered for falling trips also.
++ * TMU_SUPPORT_READY_STATUS - This feature tells that the TMU current
++ *                    state(active/idle) can be checked.
++ * TMU_SUPPORT_EMUL_TIME - This features allows to set next temp emulation
++ *                    sample time.
++ * TMU_SUPPORT_SHARED_MEMORY - This feature tells that the different TMU
++ *                    sensors shares some common registers.
++ * TMU_SUPPORT - macro to compare the above features with the supplied.
++ */
++#define TMU_SUPPORT_EMULATION                 BIT(0)
++#define TMU_SUPPORT_MULTI_INST                        BIT(1)
++#define TMU_SUPPORT_TRIM_RELOAD                       BIT(2)
++#define TMU_SUPPORT_FALLING_TRIP              BIT(3)
++#define TMU_SUPPORT_READY_STATUS              BIT(4)
++#define TMU_SUPPORT_EMUL_TIME                 BIT(5)
++#define TMU_SUPPORT_SHARED_MEMORY             BIT(6)
++
++#define TMU_SUPPORTS(a, b)    (a->features & TMU_SUPPORT_ ## b)
++
++/**
+  * struct exynos_tmu_register - register descriptors to access registers and
+  * bitfields. The register validity, offsets and bitfield values may vary
+  * slightly across different exynos SOC's.
+@@ -222,6 +250,8 @@ struct exynos_tmu_registers {
+  *    applicable to only some of the trigger levels.
+  * @registers: Pointer to structure containing all the TMU controller registers
+  *    and bitfields shifts and masks.
++ * @features: a bitfield value indicating the features supported in SOC like
++ *    emulation, multi instance etc
+  *
+  * This structure is required for configuration of exynos_tmu driver.
+  */
+@@ -249,6 +279,7 @@ struct exynos_tmu_platform_data {
+       struct freq_clip_table freq_tab[4];
+       unsigned int freq_tab_count;
+       const struct exynos_tmu_registers *registers;
++      unsigned int features;
+ };
+ /**
+diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c
+index a5c25b4..2612b45 100644
+--- a/drivers/thermal/samsung/exynos_tmu_data.c
++++ b/drivers/thermal/samsung/exynos_tmu_data.c
+@@ -83,6 +83,7 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = {
+               .freq_tab_count = 2,
+               .type = SOC_ARCH_EXYNOS4210,
+               .registers = &exynos4210_tmu_registers,
++              .features = TMU_SUPPORT_READY_STATUS,
+               },
+       },
+       .tmu_count = 1,
+@@ -162,7 +163,10 @@ static const struct exynos_tmu_registers exynos5250_tmu_registers = {
+       }, \
+       .freq_tab_count = 2, \
+       .type = SOC_ARCH_EXYNOS, \
+-      .registers = &exynos5250_tmu_registers,
++      .registers = &exynos5250_tmu_registers, \
++      .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_TRIM_RELOAD | \
++                      TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_READY_STATUS | \
++                      TMU_SUPPORT_EMUL_TIME)
+ struct exynos_tmu_init_data const exynos5250_default_tmu_data = {
+       .tmu_data = {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0970-thermal-exynos-use-device-resource-management-infras.patch b/patches.tizen/0970-thermal-exynos-use-device-resource-management-infras.patch
new file mode 100644 (file)
index 0000000..cce9a80
--- /dev/null
@@ -0,0 +1,136 @@
+From bd2486b902229b60715b0c461b012aa787d94b29 Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Tue, 25 Jun 2013 17:11:42 +0530
+Subject: [PATCH 0970/1302] thermal: exynos: use device resource management
+ infrastructure
+
+This patch uses the device pointer stored in the configuration structure
+and converts to dev_* prints and devm API's.
+
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_thermal_common.c | 36 ++++++++++++++++---------
+ 1 file changed, 23 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c
+index af0ae77..4d8e444 100644
+--- a/drivers/thermal/samsung/exynos_thermal_common.c
++++ b/drivers/thermal/samsung/exynos_thermal_common.c
+@@ -53,7 +53,8 @@ static int exynos_set_mode(struct thermal_zone_device *thermal,
+ {
+       struct exynos_thermal_zone *th_zone = thermal->devdata;
+       if (!th_zone) {
+-              pr_notice("thermal zone not registered\n");
++              dev_err(th_zone->sensor_conf->dev,
++                      "thermal zone not registered\n");
+               return 0;
+       }
+@@ -69,8 +70,9 @@ static int exynos_set_mode(struct thermal_zone_device *thermal,
+       th_zone->mode = mode;
+       thermal_zone_device_update(thermal);
+-      pr_info("thermal polling set for duration=%d msec\n",
+-                              thermal->polling_delay);
++      dev_dbg(th_zone->sensor_conf->dev,
++              "thermal polling set for duration=%d msec\n",
++              thermal->polling_delay);
+       return 0;
+ }
+@@ -162,7 +164,8 @@ static int exynos_bind(struct thermal_zone_device *thermal,
+               case WARN_ZONE:
+                       if (thermal_zone_bind_cooling_device(thermal, i, cdev,
+                                                               level, 0)) {
+-                              pr_err("error binding cdev inst %d\n", i);
++                              dev_err(data->dev,
++                                      "error unbinding cdev inst=%d\n", i);
+                               ret = -EINVAL;
+                       }
+                       th_zone->bind = true;
+@@ -207,7 +210,8 @@ static int exynos_unbind(struct thermal_zone_device *thermal,
+               case WARN_ZONE:
+                       if (thermal_zone_unbind_cooling_device(thermal, i,
+                                                               cdev)) {
+-                              pr_err("error unbinding cdev inst=%d\n", i);
++                              dev_err(data->dev,
++                                      "error unbinding cdev inst=%d\n", i);
+                               ret = -EINVAL;
+                       }
+                       th_zone->bind = false;
+@@ -227,7 +231,8 @@ static int exynos_get_temp(struct thermal_zone_device *thermal,
+       void *data;
+       if (!th_zone->sensor_conf) {
+-              pr_info("Temperature sensor not initialised\n");
++              dev_err(th_zone->sensor_conf->dev,
++                      "Temperature sensor not initialised\n");
+               return -EINVAL;
+       }
+       data = th_zone->sensor_conf->driver_data;
+@@ -246,7 +251,8 @@ static int exynos_set_emul_temp(struct thermal_zone_device *thermal,
+       struct exynos_thermal_zone *th_zone = thermal->devdata;
+       if (!th_zone->sensor_conf) {
+-              pr_info("Temperature sensor not initialised\n");
++              dev_err(th_zone->sensor_conf->dev,
++                      "Temperature sensor not initialised\n");
+               return -EINVAL;
+       }
+       data = th_zone->sensor_conf->driver_data;
+@@ -351,7 +357,8 @@ int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
+               return -EINVAL;
+       }
+-      th_zone = kzalloc(sizeof(struct exynos_thermal_zone), GFP_KERNEL);
++      th_zone = devm_kzalloc(sensor_conf->dev,
++                              sizeof(struct exynos_thermal_zone), GFP_KERNEL);
+       if (!th_zone)
+               return -ENOMEM;
+@@ -366,7 +373,8 @@ int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
+               th_zone->cool_dev[th_zone->cool_dev_size] =
+                                       cpufreq_cooling_register(&mask_val);
+               if (IS_ERR(th_zone->cool_dev[th_zone->cool_dev_size])) {
+-                      pr_err("Failed to register cpufreq cooling device\n");
++                      dev_err(sensor_conf->dev,
++                              "Failed to register cpufreq cooling device\n");
+                       ret = -EINVAL;
+                       goto err_unregister;
+               }
+@@ -380,14 +388,16 @@ int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
+                       IDLE_INTERVAL);
+       if (IS_ERR(th_zone->therm_dev)) {
+-              pr_err("Failed to register thermal zone device\n");
++              dev_err(sensor_conf->dev,
++                      "Failed to register thermal zone device\n");
+               ret = PTR_ERR(th_zone->therm_dev);
+               goto err_unregister;
+       }
+       th_zone->mode = THERMAL_DEVICE_ENABLED;
+       sensor_conf->pzone_data = th_zone;
+-      pr_info("Exynos: Kernel Thermal management registered\n");
++      dev_info(sensor_conf->dev,
++              "Exynos: Thermal zone(%s) registered\n", sensor_conf->name);
+       return 0;
+@@ -417,6 +427,6 @@ void exynos_unregister_thermal(struct thermal_sensor_conf *sensor_conf)
+                       cpufreq_cooling_unregister(th_zone->cool_dev[i]);
+       }
+-      kfree(th_zone);
+-      pr_info("Exynos: Kernel Thermal management unregistered\n");
++      dev_info(sensor_conf->dev,
++              "Exynos: Kernel Thermal management unregistered\n");
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0971-thermal-exynos-Add-support-to-access-common-register.patch b/patches.tizen/0971-thermal-exynos-Add-support-to-access-common-register.patch
new file mode 100644 (file)
index 0000000..b2ef12b
--- /dev/null
@@ -0,0 +1,68 @@
+From 78bb4f6bd30f67f996a9da1a1b51232b14dfb1e3 Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Mon, 24 Jun 2013 16:20:42 +0530
+Subject: [PATCH 0971/1302] thermal: exynos: Add support to access common
+ register for multistance
+
+This patch adds support to parse one more common set of TMU register. First
+set of register belongs to each instance of TMU and second set belongs to
+common TMU registers.
+
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_tmu.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+index 05b95c6..31bf373 100644
+--- a/drivers/thermal/samsung/exynos_tmu.c
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -40,6 +40,7 @@
+  * @id: identifier of the one instance of the TMU controller.
+  * @pdata: pointer to the tmu platform/configuration data
+  * @base: base address of the single instance of the TMU controller.
++ * @base_common: base address of the common registers of the TMU controller.
+  * @irq: irq number of the TMU controller.
+  * @soc: id of the SOC type.
+  * @irq_work: pointer to the irq work structure.
+@@ -53,6 +54,7 @@ struct exynos_tmu_data {
+       int id;
+       struct exynos_tmu_platform_data *pdata;
+       void __iomem *base;
++      void __iomem *base_common;
+       int irq;
+       enum soc_type soc;
+       struct work_struct irq_work;
+@@ -478,6 +480,24 @@ static int exynos_map_dt_data(struct platform_device *pdev)
+               return -ENODEV;
+       }
+       data->pdata = pdata;
++      /*
++       * Check if the TMU shares some registers and then try to map the
++       * memory of common registers.
++       */
++      if (!TMU_SUPPORTS(pdata, SHARED_MEMORY))
++              return 0;
++
++      if (of_address_to_resource(pdev->dev.of_node, 1, &res)) {
++              dev_err(&pdev->dev, "failed to get Resource 1\n");
++              return -ENODEV;
++      }
++
++      data->base_common = devm_ioremap(&pdev->dev, res.start,
++                                      resource_size(&res));
++      if (!data->base) {
++              dev_err(&pdev->dev, "Failed to ioremap memory\n");
++              return -ENOMEM;
++      }
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0972-thermal-exynos-Add-driver-support-for-exynos5440-TMU.patch b/patches.tizen/0972-thermal-exynos-Add-driver-support-for-exynos5440-TMU.patch
new file mode 100644 (file)
index 0000000..f96f677
--- /dev/null
@@ -0,0 +1,226 @@
+From 4b1492360406cfda2d9899bcaa69903e6c8e60cf Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Mon, 24 Jun 2013 16:20:43 +0530
+Subject: [PATCH 0972/1302] thermal: exynos: Add driver support for exynos5440
+ TMU sensor
+
+This patch modifies TMU controller to add changes needed to work with
+exynos5440 platform. This sensor registers 3 instance of the tmu controller
+with the thermal zone and hence reports 3 temperature output. This controller
+supports upto five trip points. For critical threshold the driver uses the
+core driver thermal framework for shutdown.
+
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Signed-off-by: Jungseok Lee <jays.lee@samsung.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_thermal_common.h |  2 +-
+ drivers/thermal/samsung/exynos_tmu.c            | 55 +++++++++++++++++++++----
+ drivers/thermal/samsung/exynos_tmu.h            |  6 +++
+ drivers/thermal/samsung/exynos_tmu_data.h       | 36 ++++++++++++++++
+ 4 files changed, 90 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/thermal/samsung/exynos_thermal_common.h b/drivers/thermal/samsung/exynos_thermal_common.h
+index bc3016e..3eb2ed9 100644
+--- a/drivers/thermal/samsung/exynos_thermal_common.h
++++ b/drivers/thermal/samsung/exynos_thermal_common.h
+@@ -27,7 +27,7 @@
+ #define SENSOR_NAME_LEN       16
+ #define MAX_TRIP_COUNT        8
+ #define MAX_COOLING_DEVICE 4
+-#define MAX_THRESHOLD_LEVS 4
++#define MAX_THRESHOLD_LEVS 5
+ #define ACTIVE_INTERVAL 500
+ #define IDLE_INTERVAL 10000
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+index 31bf373..6bc86f6 100644
+--- a/drivers/thermal/samsung/exynos_tmu.c
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -156,7 +156,26 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
+               __raw_writel(1, data->base + reg->triminfo_ctrl);
+       /* Save trimming info in order to perform calibration */
+-      trim_info = readl(data->base + reg->triminfo_data);
++      if (data->soc == SOC_ARCH_EXYNOS5440) {
++              /*
++               * For exynos5440 soc triminfo value is swapped between TMU0 and
++               * TMU2, so the below logic is needed.
++               */
++              switch (data->id) {
++              case 0:
++                      trim_info = readl(data->base +
++                      EXYNOS5440_EFUSE_SWAP_OFFSET + reg->triminfo_data);
++                      break;
++              case 1:
++                      trim_info = readl(data->base + reg->triminfo_data);
++                      break;
++              case 2:
++                      trim_info = readl(data->base -
++                      EXYNOS5440_EFUSE_SWAP_OFFSET + reg->triminfo_data);
++              }
++      } else {
++              trim_info = readl(data->base + reg->triminfo_data);
++      }
+       data->temp_error1 = trim_info & EXYNOS_TMU_TEMP_MASK;
+       data->temp_error2 = ((trim_info >> reg->triminfo_85_shift) &
+                               EXYNOS_TMU_TEMP_MASK);
+@@ -201,7 +220,7 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
+                       reg->threshold_th0 + i * sizeof(reg->threshold_th0));
+               writel(reg->inten_rise_mask, data->base + reg->tmu_intclear);
+-      } else if (data->soc == SOC_ARCH_EXYNOS) {
++      } else {
+               /* Write temperature code for rising and falling threshold */
+               for (i = 0;
+               i < trigger_levs && i < EXYNOS_MAX_TRIGGER_PER_REG; i++) {
+@@ -241,14 +260,26 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
+                               ret = threshold_code;
+                               goto out;
+                       }
+-                      rising_threshold |= threshold_code << 8 * i;
+-                      writel(rising_threshold,
+-                              data->base + reg->threshold_th0);
++                      if (i == EXYNOS_MAX_TRIGGER_PER_REG - 1) {
++                              /* 1-4 level to be assigned in th0 reg */
++                              rising_threshold |= threshold_code << 8 * i;
++                              writel(rising_threshold,
++                                      data->base + reg->threshold_th0);
++                      } else if (i == EXYNOS_MAX_TRIGGER_PER_REG) {
++                              /* 5th level to be assigned in th2 reg */
++                              rising_threshold =
++                              threshold_code << reg->threshold_th3_l0_shift;
++                              writel(rising_threshold,
++                                      data->base + reg->threshold_th2);
++                      }
+                       con = readl(data->base + reg->tmu_ctrl);
+                       con |= (1 << reg->therm_trip_en_shift);
+                       writel(con, data->base + reg->tmu_ctrl);
+               }
+       }
++      /*Clear the PMIN in the common TMU register*/
++      if (reg->tmu_pmin && !data->id)
++              writel(0, data->base_common + reg->tmu_pmin);
+ out:
+       clk_disable(data->clk);
+       mutex_unlock(&data->lock);
+@@ -377,7 +408,14 @@ static void exynos_tmu_work(struct work_struct *work)
+                       struct exynos_tmu_data, irq_work);
+       struct exynos_tmu_platform_data *pdata = data->pdata;
+       const struct exynos_tmu_registers *reg = pdata->registers;
+-      unsigned int val_irq;
++      unsigned int val_irq, val_type;
++
++      /* Find which sensor generated this interrupt */
++      if (reg->tmu_irqstatus) {
++              val_type = readl(data->base_common + reg->tmu_irqstatus);
++              if (!((val_type >> data->id) & 0x1))
++                      goto out;
++      }
+       exynos_report_trigger(data->reg_conf);
+       mutex_lock(&data->lock);
+@@ -390,7 +428,7 @@ static void exynos_tmu_work(struct work_struct *work)
+       clk_disable(data->clk);
+       mutex_unlock(&data->lock);
+-
++out:
+       enable_irq(data->irq);
+ }
+@@ -538,7 +576,8 @@ static int exynos_tmu_probe(struct platform_device *pdev)
+               return ret;
+       if (pdata->type == SOC_ARCH_EXYNOS ||
+-                              pdata->type == SOC_ARCH_EXYNOS4210)
++              pdata->type == SOC_ARCH_EXYNOS4210 ||
++                              pdata->type == SOC_ARCH_EXYNOS5440)
+               data->soc = pdata->type;
+       else {
+               ret = -EINVAL;
+diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h
+index ff8844f..25c48d4 100644
+--- a/drivers/thermal/samsung/exynos_tmu.h
++++ b/drivers/thermal/samsung/exynos_tmu.h
+@@ -40,6 +40,7 @@ enum calibration_mode {
+ enum soc_type {
+       SOC_ARCH_EXYNOS4210 = 1,
+       SOC_ARCH_EXYNOS,
++      SOC_ARCH_EXYNOS5440,
+ };
+ /**
+@@ -131,6 +132,8 @@ enum soc_type {
+  * @emul_temp_shift: shift bits of emulation temperature.
+  * @emul_time_shift: shift bits of emulation time.
+  * @emul_time_mask: mask bits of emulation time.
++ * @tmu_irqstatus: register to find which TMU generated interrupts.
++ * @tmu_pmin: register to get/set the Pmin value.
+  */
+ struct exynos_tmu_registers {
+       u32     triminfo_data;
+@@ -198,6 +201,9 @@ struct exynos_tmu_registers {
+       u32     emul_temp_shift;
+       u32     emul_time_shift;
+       u32     emul_time_mask;
++
++      u32     tmu_irqstatus;
++      u32     tmu_pmin;
+ };
+ /**
+diff --git a/drivers/thermal/samsung/exynos_tmu_data.h b/drivers/thermal/samsung/exynos_tmu_data.h
+index 139dbbb..ad263e9 100644
+--- a/drivers/thermal/samsung/exynos_tmu_data.h
++++ b/drivers/thermal/samsung/exynos_tmu_data.h
+@@ -93,6 +93,42 @@
+ #define EXYNOS_MAX_TRIGGER_PER_REG    4
++/*exynos5440 specific registers*/
++#define EXYNOS5440_TMU_S0_7_TRIM              0x000
++#define EXYNOS5440_TMU_S0_7_CTRL              0x020
++#define EXYNOS5440_TMU_S0_7_DEBUG             0x040
++#define EXYNOS5440_TMU_S0_7_STATUS            0x060
++#define EXYNOS5440_TMU_S0_7_TEMP              0x0f0
++#define EXYNOS5440_TMU_S0_7_TH0                       0x110
++#define EXYNOS5440_TMU_S0_7_TH1                       0x130
++#define EXYNOS5440_TMU_S0_7_TH2                       0x150
++#define EXYNOS5440_TMU_S0_7_EVTEN             0x1F0
++#define EXYNOS5440_TMU_S0_7_IRQEN             0x210
++#define EXYNOS5440_TMU_S0_7_IRQ                       0x230
++/* exynos5440 common registers */
++#define EXYNOS5440_TMU_IRQ_STATUS             0x000
++#define EXYNOS5440_TMU_PMIN                   0x004
++#define EXYNOS5440_TMU_TEMP                   0x008
++
++#define EXYNOS5440_TMU_RISE_INT_MASK          0xf
++#define EXYNOS5440_TMU_RISE_INT_SHIFT         0
++#define EXYNOS5440_TMU_FALL_INT_MASK          0xf
++#define EXYNOS5440_TMU_FALL_INT_SHIFT         4
++#define EXYNOS5440_TMU_INTEN_RISE0_SHIFT      0
++#define EXYNOS5440_TMU_INTEN_RISE1_SHIFT      1
++#define EXYNOS5440_TMU_INTEN_RISE2_SHIFT      2
++#define EXYNOS5440_TMU_INTEN_RISE3_SHIFT      3
++#define EXYNOS5440_TMU_INTEN_FALL0_SHIFT      4
++#define EXYNOS5440_TMU_INTEN_FALL1_SHIFT      5
++#define EXYNOS5440_TMU_INTEN_FALL2_SHIFT      6
++#define EXYNOS5440_TMU_INTEN_FALL3_SHIFT      7
++#define EXYNOS5440_TMU_TH_RISE0_SHIFT         0
++#define EXYNOS5440_TMU_TH_RISE1_SHIFT         8
++#define EXYNOS5440_TMU_TH_RISE2_SHIFT         16
++#define EXYNOS5440_TMU_TH_RISE3_SHIFT         24
++#define EXYNOS5440_TMU_TH_RISE4_SHIFT         24
++#define EXYNOS5440_EFUSE_SWAP_OFFSET          8
++
+ #if defined(CONFIG_CPU_EXYNOS4210)
+ extern struct exynos_tmu_init_data const exynos4210_default_tmu_data;
+ #define EXYNOS4210_TMU_DRV_DATA (&exynos4210_default_tmu_data)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0973-thermal-exynos-Add-thermal-configuration-data-for-ex.patch b/patches.tizen/0973-thermal-exynos-Add-thermal-configuration-data-for-ex.patch
new file mode 100644 (file)
index 0000000..d0ccba3
--- /dev/null
@@ -0,0 +1,134 @@
+From 91768d59767e1ec037e717d3ed39ae05c26ea9f1 Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Mon, 24 Jun 2013 16:20:44 +0530
+Subject: [PATCH 0973/1302] thermal: exynos: Add thermal configuration data for
+ exynos5440 TMU sensor
+
+This patch adds configuration data for exynos5440 soc. Also register
+definations for the controller are added.
+
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_tmu.c      |  4 ++
+ drivers/thermal/samsung/exynos_tmu_data.c | 71 +++++++++++++++++++++++++++++++
+ drivers/thermal/samsung/exynos_tmu_data.h |  7 +++
+ 3 files changed, 82 insertions(+)
+
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+index 6bc86f6..651f460 100644
+--- a/drivers/thermal/samsung/exynos_tmu.c
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -456,6 +456,10 @@ static const struct of_device_id exynos_tmu_match[] = {
+               .compatible = "samsung,exynos5250-tmu",
+               .data = (void *)EXYNOS5250_TMU_DRV_DATA,
+       },
++      {
++              .compatible = "samsung,exynos5440-tmu",
++              .data = (void *)EXYNOS5440_TMU_DRV_DATA,
++      },
+       {},
+ };
+ MODULE_DEVICE_TABLE(of, exynos_tmu_match);
+diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c
+index 2612b45..5952915 100644
+--- a/drivers/thermal/samsung/exynos_tmu_data.c
++++ b/drivers/thermal/samsung/exynos_tmu_data.c
+@@ -175,3 +175,74 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = {
+       .tmu_count = 1,
+ };
+ #endif
++
++#if defined(CONFIG_SOC_EXYNOS5440)
++static const struct exynos_tmu_registers exynos5440_tmu_registers = {
++      .triminfo_data = EXYNOS5440_TMU_S0_7_TRIM,
++      .triminfo_25_shift = EXYNOS_TRIMINFO_25_SHIFT,
++      .triminfo_85_shift = EXYNOS_TRIMINFO_85_SHIFT,
++      .tmu_ctrl = EXYNOS5440_TMU_S0_7_CTRL,
++      .buf_vref_sel_shift = EXYNOS_TMU_REF_VOLTAGE_SHIFT,
++      .buf_vref_sel_mask = EXYNOS_TMU_REF_VOLTAGE_MASK,
++      .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT,
++      .therm_trip_mode_mask = EXYNOS_TMU_TRIP_MODE_MASK,
++      .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT,
++      .buf_slope_sel_shift = EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT,
++      .buf_slope_sel_mask = EXYNOS_TMU_BUF_SLOPE_SEL_MASK,
++      .core_en_shift = EXYNOS_TMU_CORE_EN_SHIFT,
++      .tmu_status = EXYNOS5440_TMU_S0_7_STATUS,
++      .tmu_cur_temp = EXYNOS5440_TMU_S0_7_TEMP,
++      .threshold_th0 = EXYNOS5440_TMU_S0_7_TH0,
++      .threshold_th1 = EXYNOS5440_TMU_S0_7_TH1,
++      .threshold_th2 = EXYNOS5440_TMU_S0_7_TH2,
++      .threshold_th3_l0_shift = EXYNOS5440_TMU_TH_RISE4_SHIFT,
++      .tmu_inten = EXYNOS5440_TMU_S0_7_IRQEN,
++      .inten_rise_mask = EXYNOS5440_TMU_RISE_INT_MASK,
++      .inten_rise_shift = EXYNOS5440_TMU_RISE_INT_SHIFT,
++      .inten_fall_mask = EXYNOS5440_TMU_FALL_INT_MASK,
++      .inten_fall_shift = EXYNOS5440_TMU_FALL_INT_SHIFT,
++      .inten_rise0_shift = EXYNOS5440_TMU_INTEN_RISE0_SHIFT,
++      .inten_rise1_shift = EXYNOS5440_TMU_INTEN_RISE1_SHIFT,
++      .inten_rise2_shift = EXYNOS5440_TMU_INTEN_RISE2_SHIFT,
++      .inten_rise3_shift = EXYNOS5440_TMU_INTEN_RISE3_SHIFT,
++      .inten_fall0_shift = EXYNOS5440_TMU_INTEN_FALL0_SHIFT,
++      .tmu_intstat = EXYNOS5440_TMU_S0_7_IRQ,
++      .tmu_intclear = EXYNOS5440_TMU_S0_7_IRQ,
++      .tmu_irqstatus = EXYNOS5440_TMU_IRQ_STATUS,
++      .emul_con = EXYNOS5440_TMU_S0_7_DEBUG,
++      .emul_temp_shift = EXYNOS_EMUL_DATA_SHIFT,
++      .tmu_pmin = EXYNOS5440_TMU_PMIN,
++};
++
++#define EXYNOS5440_TMU_DATA \
++      .trigger_levels[0] = 100, \
++      .trigger_levels[4] = 105, \
++      .trigger_enable[0] = 1, \
++      .trigger_type[0] = SW_TRIP, \
++      .trigger_type[4] = HW_TRIP, \
++      .max_trigger_level = 5, \
++      .gain = 5, \
++      .reference_voltage = 16, \
++      .noise_cancel_mode = 4, \
++      .cal_type = TYPE_ONE_POINT_TRIMMING, \
++      .cal_mode = 0, \
++      .efuse_value = 0x5b2d, \
++      .min_efuse_value = 16, \
++      .max_efuse_value = 76, \
++      .first_point_trim = 25, \
++      .second_point_trim = 70, \
++      .default_temp_offset = 25, \
++      .type = SOC_ARCH_EXYNOS5440, \
++      .registers = &exynos5440_tmu_registers, \
++      .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_FALLING_TRIP | \
++                      TMU_SUPPORT_MULTI_INST | TMU_SUPPORT_SHARED_MEMORY),
++
++struct exynos_tmu_init_data const exynos5440_default_tmu_data = {
++      .tmu_data = {
++              { EXYNOS5440_TMU_DATA } ,
++              { EXYNOS5440_TMU_DATA } ,
++              { EXYNOS5440_TMU_DATA } ,
++      },
++      .tmu_count = 3,
++};
++#endif
+diff --git a/drivers/thermal/samsung/exynos_tmu_data.h b/drivers/thermal/samsung/exynos_tmu_data.h
+index ad263e9..43ce5fb 100644
+--- a/drivers/thermal/samsung/exynos_tmu_data.h
++++ b/drivers/thermal/samsung/exynos_tmu_data.h
+@@ -143,4 +143,11 @@ extern struct exynos_tmu_init_data const exynos5250_default_tmu_data;
+ #define EXYNOS5250_TMU_DRV_DATA (NULL)
+ #endif
++#if defined(CONFIG_SOC_EXYNOS5440)
++extern struct exynos_tmu_init_data const exynos5440_default_tmu_data;
++#define EXYNOS5440_TMU_DRV_DATA (&exynos5440_default_tmu_data)
++#else
++#define EXYNOS5440_TMU_DRV_DATA (NULL)
++#endif
++
+ #endif /*_EXYNOS_TMU_DATA_H*/
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0974-thermal-exynos-Fix-to-set-the-second-point-correctio.patch b/patches.tizen/0974-thermal-exynos-Fix-to-set-the-second-point-correctio.patch
new file mode 100644 (file)
index 0000000..229e0de
--- /dev/null
@@ -0,0 +1,46 @@
+From 9e6d43b54dc4f68ef1056f419163b6bcd5a6f779 Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Mon, 24 Jun 2013 16:20:45 +0530
+Subject: [PATCH 0974/1302] thermal: exynos: Fix to set the second point
+ correction value
+
+This patch sets the second point trimming value according to the platform
+data if the register value is 0.
+
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_tmu.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+index 651f460..3fac0f9 100644
+--- a/drivers/thermal/samsung/exynos_tmu.c
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -180,10 +180,15 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
+       data->temp_error2 = ((trim_info >> reg->triminfo_85_shift) &
+                               EXYNOS_TMU_TEMP_MASK);
+-      if ((pdata->min_efuse_value > data->temp_error1) ||
+-                      (data->temp_error1 > pdata->max_efuse_value) ||
+-                      (data->temp_error2 != 0))
+-              data->temp_error1 = pdata->efuse_value;
++      if (!data->temp_error1 ||
++              (pdata->min_efuse_value > data->temp_error1) ||
++              (data->temp_error1 > pdata->max_efuse_value))
++              data->temp_error1 = pdata->efuse_value & EXYNOS_TMU_TEMP_MASK;
++
++      if (!data->temp_error2)
++              data->temp_error2 =
++                      (pdata->efuse_value >> reg->triminfo_85_shift) &
++                      EXYNOS_TMU_TEMP_MASK;
+       if (pdata->max_trigger_level > MAX_THRESHOLD_LEVS) {
+               dev_err(&pdev->dev, "Invalid max trigger level\n");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0975-thermal-exynos-Add-hardware-mode-thermal-calibration.patch b/patches.tizen/0975-thermal-exynos-Add-hardware-mode-thermal-calibration.patch
new file mode 100644 (file)
index 0000000..5dafb1f
--- /dev/null
@@ -0,0 +1,163 @@
+From e34d18e6f25741c1f44713e1bc5acee0a44aa62b Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Mon, 24 Jun 2013 16:20:46 +0530
+Subject: [PATCH 0975/1302] thermal: exynos: Add hardware mode thermal
+ calibration support
+
+This patch adds support for h/w mode calibration in the TMU controller.
+Soc's like 5440 support this features. The h/w bits needed for calibration
+setting are same as that of enum calibration_type.
+
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_tmu.c      | 33 ++++++++++++++++++++++++++++++-
+ drivers/thermal/samsung/exynos_tmu.h      |  8 ++++++++
+ drivers/thermal/samsung/exynos_tmu_data.c |  2 ++
+ drivers/thermal/samsung/exynos_tmu_data.h |  2 ++
+ 4 files changed, 44 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+index 3fac0f9..a6fc379 100644
+--- a/drivers/thermal/samsung/exynos_tmu.c
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -73,6 +73,9 @@ static int temp_to_code(struct exynos_tmu_data *data, u8 temp)
+       struct exynos_tmu_platform_data *pdata = data->pdata;
+       int temp_code;
++      if (pdata->cal_mode == HW_MODE)
++              return temp;
++
+       if (data->soc == SOC_ARCH_EXYNOS4210)
+               /* temp should range between 25 and 125 */
+               if (temp < 25 || temp > 125) {
+@@ -107,6 +110,9 @@ static int code_to_temp(struct exynos_tmu_data *data, u8 temp_code)
+       struct exynos_tmu_platform_data *pdata = data->pdata;
+       int temp;
++      if (pdata->cal_mode == HW_MODE)
++              return temp_code;
++
+       if (data->soc == SOC_ARCH_EXYNOS4210)
+               /* temp_code should range between 75 and 175 */
+               if (temp_code < 75 || temp_code > 175) {
+@@ -155,6 +161,9 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
+       if (TMU_SUPPORTS(pdata, TRIM_RELOAD))
+               __raw_writel(1, data->base + reg->triminfo_ctrl);
++      if (pdata->cal_mode == HW_MODE)
++              goto skip_calib_data;
++
+       /* Save trimming info in order to perform calibration */
+       if (data->soc == SOC_ARCH_EXYNOS5440) {
+               /*
+@@ -190,6 +199,7 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
+                       (pdata->efuse_value >> reg->triminfo_85_shift) &
+                       EXYNOS_TMU_TEMP_MASK;
++skip_calib_data:
+       if (pdata->max_trigger_level > MAX_THRESHOLD_LEVS) {
+               dev_err(&pdev->dev, "Invalid max trigger level\n");
+               goto out;
+@@ -297,7 +307,7 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on)
+       struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+       struct exynos_tmu_platform_data *pdata = data->pdata;
+       const struct exynos_tmu_registers *reg = pdata->registers;
+-      unsigned int con, interrupt_en;
++      unsigned int con, interrupt_en, cal_val;
+       mutex_lock(&data->lock);
+       clk_enable(data->clk);
+@@ -320,6 +330,27 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on)
+               con |= (pdata->noise_cancel_mode << reg->therm_trip_mode_shift);
+       }
++      if (pdata->cal_mode == HW_MODE) {
++              con &= ~(reg->calib_mode_mask << reg->calib_mode_shift);
++              cal_val = 0;
++              switch (pdata->cal_type) {
++              case TYPE_TWO_POINT_TRIMMING:
++                      cal_val = 3;
++                      break;
++              case TYPE_ONE_POINT_TRIMMING_85:
++                      cal_val = 2;
++                      break;
++              case TYPE_ONE_POINT_TRIMMING_25:
++                      cal_val = 1;
++                      break;
++              case TYPE_NONE:
++                      break;
++              default:
++                      dev_err(&pdev->dev, "Invalid calibration type, using none\n");
++              }
++              con |= cal_val << reg->calib_mode_shift;
++      }
++
+       if (on) {
+               con |= (1 << reg->core_en_shift);
+               interrupt_en =
+diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h
+index 25c48d4..b364c9e 100644
+--- a/drivers/thermal/samsung/exynos_tmu.h
++++ b/drivers/thermal/samsung/exynos_tmu.h
+@@ -28,6 +28,8 @@
+ enum calibration_type {
+       TYPE_ONE_POINT_TRIMMING,
++      TYPE_ONE_POINT_TRIMMING_25,
++      TYPE_ONE_POINT_TRIMMING_85,
+       TYPE_TWO_POINT_TRIMMING,
+       TYPE_NONE,
+ };
+@@ -90,6 +92,10 @@ enum soc_type {
+  * @buf_slope_sel_shift: shift bits of amplifier gain value in tmu_ctrl
+       register.
+  * @buf_slope_sel_mask: mask bits of amplifier gain value in tmu_ctrl register.
++ * @calib_mode_shift: shift bits of calibration mode value in tmu_ctrl
++      register.
++ * @calib_mode_mask: mask bits of calibration mode value in tmu_ctrl
++      register.
+  * @therm_trip_tq_en_shift: shift bits of thermal trip enable by TQ pin in
+       tmu_ctrl register.
+  * @core_en_shift: shift bits of TMU core enable bit in tmu_ctrl register.
+@@ -151,6 +157,8 @@ struct exynos_tmu_registers {
+       u32     therm_trip_en_shift;
+       u32     buf_slope_sel_shift;
+       u32     buf_slope_sel_mask;
++      u32     calib_mode_shift;
++      u32     calib_mode_mask;
+       u32     therm_trip_tq_en_shift;
+       u32     core_en_shift;
+diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c
+index 5952915..9002499 100644
+--- a/drivers/thermal/samsung/exynos_tmu_data.c
++++ b/drivers/thermal/samsung/exynos_tmu_data.c
+@@ -189,6 +189,8 @@ static const struct exynos_tmu_registers exynos5440_tmu_registers = {
+       .therm_trip_en_shift = EXYNOS_TMU_THERM_TRIP_EN_SHIFT,
+       .buf_slope_sel_shift = EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT,
+       .buf_slope_sel_mask = EXYNOS_TMU_BUF_SLOPE_SEL_MASK,
++      .calib_mode_shift = EXYNOS_TMU_CALIB_MODE_SHIFT,
++      .calib_mode_mask = EXYNOS_TMU_CALIB_MODE_MASK,
+       .core_en_shift = EXYNOS_TMU_CORE_EN_SHIFT,
+       .tmu_status = EXYNOS5440_TMU_S0_7_STATUS,
+       .tmu_cur_temp = EXYNOS5440_TMU_S0_7_TEMP,
+diff --git a/drivers/thermal/samsung/exynos_tmu_data.h b/drivers/thermal/samsung/exynos_tmu_data.h
+index 43ce5fb..dc7feb5 100644
+--- a/drivers/thermal/samsung/exynos_tmu_data.h
++++ b/drivers/thermal/samsung/exynos_tmu_data.h
+@@ -75,6 +75,8 @@
+ #define EXYNOS_TMU_TRIP_MODE_SHIFT    13
+ #define EXYNOS_TMU_TRIP_MODE_MASK     0x7
+ #define EXYNOS_TMU_THERM_TRIP_EN_SHIFT        12
++#define EXYNOS_TMU_CALIB_MODE_SHIFT   4
++#define EXYNOS_TMU_CALIB_MODE_MASK    0x3
+ #define EXYNOS_TMU_INTEN_RISE0_SHIFT  0
+ #define EXYNOS_TMU_INTEN_RISE1_SHIFT  4
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0976-thermal-exynos-Support-for-TMU-regulator-defined-at-.patch b/patches.tizen/0976-thermal-exynos-Support-for-TMU-regulator-defined-at-.patch
new file mode 100644 (file)
index 0000000..ee38375
--- /dev/null
@@ -0,0 +1,90 @@
+From 6e966de7746e60ef802c190b9b1db3d32b31e6e8 Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Mon, 24 Jun 2013 16:20:47 +0530
+Subject: [PATCH 0976/1302] thermal: exynos: Support for TMU regulator defined
+ at device tree
+
+TMU probe function now checks for a device tree defined regulator.
+For compatibility reasons it is allowed to probe driver even without
+this regulator defined.
+
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_tmu.c | 23 +++++++++++++++++++++++
+ 1 file changed, 23 insertions(+)
+
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+index a6fc379..ec01dfe 100644
+--- a/drivers/thermal/samsung/exynos_tmu.c
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -29,6 +29,7 @@
+ #include <linux/of_address.h>
+ #include <linux/of_irq.h>
+ #include <linux/platform_device.h>
++#include <linux/regulator/consumer.h>
+ #include "exynos_thermal_common.h"
+ #include "exynos_tmu.h"
+@@ -48,6 +49,7 @@
+  * @clk: pointer to the clock structure.
+  * @temp_error1: fused value of the first point trim.
+  * @temp_error2: fused value of the second point trim.
++ * @regulator: pointer to the TMU regulator structure.
+  * @reg_conf: pointer to structure to register with core thermal.
+  */
+ struct exynos_tmu_data {
+@@ -61,6 +63,7 @@ struct exynos_tmu_data {
+       struct mutex lock;
+       struct clk *clk;
+       u8 temp_error1, temp_error2;
++      struct regulator *regulator;
+       struct thermal_sensor_conf *reg_conf;
+ };
+@@ -527,10 +530,27 @@ static int exynos_map_dt_data(struct platform_device *pdev)
+       struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+       struct exynos_tmu_platform_data *pdata;
+       struct resource res;
++      int ret;
+       if (!data)
+               return -ENODEV;
++      /*
++       * Try enabling the regulator if found
++       * TODO: Add regulator as an SOC feature, so that regulator enable
++       * is a compulsory call.
++       */
++      data->regulator = devm_regulator_get(&pdev->dev, "vtmu");
++      if (!IS_ERR(data->regulator)) {
++              ret = regulator_enable(data->regulator);
++              if (ret) {
++                      dev_err(&pdev->dev, "failed to enable vtmu\n");
++                      return ret;
++              }
++      } else {
++              dev_info(&pdev->dev, "Regulator node (vtmu) not found\n");
++      }
++
+       data->id = of_alias_get_id(pdev->dev.of_node, "tmuctrl");
+       if (data->id < 0)
+               data->id = 0;
+@@ -698,6 +718,9 @@ static int exynos_tmu_remove(struct platform_device *pdev)
+       clk_unprepare(data->clk);
++      if (!IS_ERR(data->regulator))
++              regulator_disable(data->regulator);
++
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0977-thermal-imx-dynamic-passive-and-SoC-specific-critica.patch b/patches.tizen/0977-thermal-imx-dynamic-passive-and-SoC-specific-critica.patch
new file mode 100644 (file)
index 0000000..dd6c4d1
--- /dev/null
@@ -0,0 +1,124 @@
+From 84a52af3b15abc8894ba8b44defade561c2a9e9c Mon Sep 17 00:00:00 2001
+From: Philipp Zabel <p.zabel@pengutronix.de>
+Date: Thu, 1 Aug 2013 18:33:11 +0200
+Subject: [PATCH 0977/1302] thermal: imx: dynamic passive and SoC specific
+ critical trip points
+
+Set passive and critical trip point values depending on the maximum die
+temperature stored in the OCOTP fuses. This allows higher trip points
+for industrial and automotive rated i.MX6 SoCs.
+Also allow to configure the passive trip point from userspace.
+
+Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
+Acked-by: Shawn Guo <shawn.guo@linaro.org>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/imx_thermal.c | 50 ++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 40 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
+index d16c33c..c9a55b02 100644
+--- a/drivers/thermal/imx_thermal.c
++++ b/drivers/thermal/imx_thermal.c
+@@ -55,12 +55,6 @@ enum imx_thermal_trip {
+  */
+ #define IMX_TEMP_PASSIVE              85000
+-/*
+- * The maximum die temperature on imx parts is 105C, let's give some cushion
+- * for noise and possible temperature rise between measurements.
+- */
+-#define IMX_TEMP_CRITICAL             100000
+-
+ #define IMX_POLLING_DELAY             2000 /* millisecond */
+ #define IMX_PASSIVE_DELAY             1000
+@@ -70,6 +64,8 @@ struct imx_thermal_data {
+       enum thermal_device_mode mode;
+       struct regmap *tempmon;
+       int c1, c2; /* See formula in imx_get_sensor_data() */
++      unsigned long temp_passive;
++      unsigned long temp_critical;
+ };
+ static int imx_get_temp(struct thermal_zone_device *tz, unsigned long *temp)
+@@ -156,15 +152,35 @@ static int imx_get_trip_type(struct thermal_zone_device *tz, int trip,
+ static int imx_get_crit_temp(struct thermal_zone_device *tz,
+                            unsigned long *temp)
+ {
+-      *temp = IMX_TEMP_CRITICAL;
++      struct imx_thermal_data *data = tz->devdata;
++
++      *temp = data->temp_critical;
+       return 0;
+ }
+ static int imx_get_trip_temp(struct thermal_zone_device *tz, int trip,
+                            unsigned long *temp)
+ {
+-      *temp = (trip == IMX_TRIP_PASSIVE) ? IMX_TEMP_PASSIVE :
+-                                           IMX_TEMP_CRITICAL;
++      struct imx_thermal_data *data = tz->devdata;
++
++      *temp = (trip == IMX_TRIP_PASSIVE) ? data->temp_passive :
++                                           data->temp_critical;
++      return 0;
++}
++
++static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,
++                           unsigned long temp)
++{
++      struct imx_thermal_data *data = tz->devdata;
++
++      if (trip == IMX_TRIP_CRITICAL)
++              return -EPERM;
++
++      if (temp > IMX_TEMP_PASSIVE)
++              return -EINVAL;
++
++      data->temp_passive = temp;
++
+       return 0;
+ }
+@@ -211,6 +227,7 @@ static const struct thermal_zone_device_ops imx_tz_ops = {
+       .get_trip_type = imx_get_trip_type,
+       .get_trip_temp = imx_get_trip_temp,
+       .get_crit_temp = imx_get_crit_temp,
++      .set_trip_temp = imx_set_trip_temp,
+ };
+ static int imx_get_sensor_data(struct platform_device *pdev)
+@@ -267,6 +284,18 @@ static int imx_get_sensor_data(struct platform_device *pdev)
+       data->c1 = 1000 * (t1 - t2) / (n1 - n2);
+       data->c2 = 1000 * t2 - data->c1 * n2;
++      /*
++       * Set the default passive cooling trip point to 20 °C below the
++       * maximum die temperature. Can be changed from userspace.
++       */
++      data->temp_passive = 1000 * (t2 - 20);
++
++      /*
++       * The maximum die temperature is t2, let's give 5 °C cushion
++       * for noise and possible temperature rise between measurements.
++       */
++      data->temp_critical = 1000 * (t2 - 5);
++
+       return 0;
+ }
+@@ -314,7 +343,8 @@ static int imx_thermal_probe(struct platform_device *pdev)
+       }
+       data->tz = thermal_zone_device_register("imx_thermal_zone",
+-                                              IMX_TRIP_NUM, 0, data,
++                                              IMX_TRIP_NUM,
++                                              BIT(IMX_TRIP_PASSIVE), data,
+                                               &imx_tz_ops, NULL,
+                                               IMX_PASSIVE_DELAY,
+                                               IMX_POLLING_DELAY);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0978-thermal-imx-implement-thermal-alarm-interrupt-handli.patch b/patches.tizen/0978-thermal-imx-implement-thermal-alarm-interrupt-handli.patch
new file mode 100644 (file)
index 0000000..5f071cd
--- /dev/null
@@ -0,0 +1,264 @@
+From 11defc080ea2ba975c34db7c83963f427c1bd9b7 Mon Sep 17 00:00:00 2001
+From: Philipp Zabel <p.zabel@pengutronix.de>
+Date: Thu, 1 Aug 2013 18:33:12 +0200
+Subject: [PATCH 0978/1302] thermal: imx: implement thermal alarm interrupt
+ handling
+
+Enable automatic measurements at 10 Hz and use the alarm interrupt to react
+more quickly to sudden temperature changes above the passive or critical
+temperature trip points.
+
+Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
+Acked-by: Shawn Guo <shawn.guo@linaro.org>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/imx_thermal.c | 140 ++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 127 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
+index c9a55b02..1d6c801 100644
+--- a/drivers/thermal/imx_thermal.c
++++ b/drivers/thermal/imx_thermal.c
+@@ -12,6 +12,7 @@
+ #include <linux/delay.h>
+ #include <linux/device.h>
+ #include <linux/init.h>
++#include <linux/interrupt.h>
+ #include <linux/io.h>
+ #include <linux/kernel.h>
+ #include <linux/mfd/syscon.h>
+@@ -31,6 +32,8 @@
+ #define MISC0_REFTOP_SELBIASOFF               (1 << 3)
+ #define TEMPSENSE0                    0x0180
++#define TEMPSENSE0_ALARM_VALUE_SHIFT  20
++#define TEMPSENSE0_ALARM_VALUE_MASK   (0xfff << TEMPSENSE0_ALARM_VALUE_SHIFT)
+ #define TEMPSENSE0_TEMP_CNT_SHIFT     8
+ #define TEMPSENSE0_TEMP_CNT_MASK      (0xfff << TEMPSENSE0_TEMP_CNT_SHIFT)
+ #define TEMPSENSE0_FINISHED           (1 << 2)
+@@ -66,33 +69,62 @@ struct imx_thermal_data {
+       int c1, c2; /* See formula in imx_get_sensor_data() */
+       unsigned long temp_passive;
+       unsigned long temp_critical;
++      unsigned long alarm_temp;
++      unsigned long last_temp;
++      bool irq_enabled;
++      int irq;
+ };
++static void imx_set_alarm_temp(struct imx_thermal_data *data,
++                             signed long alarm_temp)
++{
++      struct regmap *map = data->tempmon;
++      int alarm_value;
++
++      data->alarm_temp = alarm_temp;
++      alarm_value = (alarm_temp - data->c2) / data->c1;
++      regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_ALARM_VALUE_MASK);
++      regmap_write(map, TEMPSENSE0 + REG_SET, alarm_value <<
++                      TEMPSENSE0_ALARM_VALUE_SHIFT);
++}
++
+ static int imx_get_temp(struct thermal_zone_device *tz, unsigned long *temp)
+ {
+       struct imx_thermal_data *data = tz->devdata;
+       struct regmap *map = data->tempmon;
+-      static unsigned long last_temp;
+       unsigned int n_meas;
++      bool wait;
+       u32 val;
+-      /*
+-       * Every time we measure the temperature, we will power on the
+-       * temperature sensor, enable measurements, take a reading,
+-       * disable measurements, power off the temperature sensor.
+-       */
+-      regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN);
+-      regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP);
++      if (data->mode == THERMAL_DEVICE_ENABLED) {
++              /* Check if a measurement is currently in progress */
++              regmap_read(map, TEMPSENSE0, &val);
++              wait = !(val & TEMPSENSE0_FINISHED);
++      } else {
++              /*
++               * Every time we measure the temperature, we will power on the
++               * temperature sensor, enable measurements, take a reading,
++               * disable measurements, power off the temperature sensor.
++               */
++              regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN);
++              regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP);
++
++              wait = true;
++      }
+       /*
+        * According to the temp sensor designers, it may require up to ~17us
+        * to complete a measurement.
+        */
+-      usleep_range(20, 50);
++      if (wait)
++              usleep_range(20, 50);
+       regmap_read(map, TEMPSENSE0, &val);
+-      regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP);
+-      regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);
++
++      if (data->mode != THERMAL_DEVICE_ENABLED) {
++              regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP);
++              regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);
++      }
+       if ((val & TEMPSENSE0_FINISHED) == 0) {
+               dev_dbg(&tz->device, "temp measurement never finished\n");
+@@ -104,9 +136,24 @@ static int imx_get_temp(struct thermal_zone_device *tz, unsigned long *temp)
+       /* See imx_get_sensor_data() for formula derivation */
+       *temp = data->c2 + data->c1 * n_meas;
+-      if (*temp != last_temp) {
++      /* Update alarm value to next higher trip point */
++      if (data->alarm_temp == data->temp_passive && *temp >= data->temp_passive)
++              imx_set_alarm_temp(data, data->temp_critical);
++      if (data->alarm_temp == data->temp_critical && *temp < data->temp_passive) {
++              imx_set_alarm_temp(data, data->temp_passive);
++              dev_dbg(&tz->device, "thermal alarm off: T < %lu\n",
++                      data->alarm_temp / 1000);
++      }
++
++      if (*temp != data->last_temp) {
+               dev_dbg(&tz->device, "millicelsius: %ld\n", *temp);
+-              last_temp = *temp;
++              data->last_temp = *temp;
++      }
++
++      /* Reenable alarm IRQ if temperature below alarm temperature */
++      if (!data->irq_enabled && *temp < data->alarm_temp) {
++              data->irq_enabled = true;
++              enable_irq(data->irq);
+       }
+       return 0;
+@@ -126,13 +173,30 @@ static int imx_set_mode(struct thermal_zone_device *tz,
+                       enum thermal_device_mode mode)
+ {
+       struct imx_thermal_data *data = tz->devdata;
++      struct regmap *map = data->tempmon;
+       if (mode == THERMAL_DEVICE_ENABLED) {
+               tz->polling_delay = IMX_POLLING_DELAY;
+               tz->passive_delay = IMX_PASSIVE_DELAY;
++
++              regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN);
++              regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP);
++
++              if (!data->irq_enabled) {
++                      data->irq_enabled = true;
++                      enable_irq(data->irq);
++              }
+       } else {
++              regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP);
++              regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);
++
+               tz->polling_delay = 0;
+               tz->passive_delay = 0;
++
++              if (data->irq_enabled) {
++                      disable_irq(data->irq);
++                      data->irq_enabled = false;
++              }
+       }
+       data->mode = mode;
+@@ -181,6 +245,8 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,
+       data->temp_passive = temp;
++      imx_set_alarm_temp(data, temp);
++
+       return 0;
+ }
+@@ -299,11 +365,34 @@ static int imx_get_sensor_data(struct platform_device *pdev)
+       return 0;
+ }
++static irqreturn_t imx_thermal_alarm_irq(int irq, void *dev)
++{
++      struct imx_thermal_data *data = dev;
++
++      disable_irq_nosync(irq);
++      data->irq_enabled = false;
++
++      return IRQ_WAKE_THREAD;
++}
++
++static irqreturn_t imx_thermal_alarm_irq_thread(int irq, void *dev)
++{
++      struct imx_thermal_data *data = dev;
++
++      dev_dbg(&data->tz->device, "THERMAL ALARM: T > %lu\n",
++              data->alarm_temp / 1000);
++
++      thermal_zone_device_update(data->tz);
++
++      return IRQ_HANDLED;
++}
++
+ static int imx_thermal_probe(struct platform_device *pdev)
+ {
+       struct imx_thermal_data *data;
+       struct cpumask clip_cpus;
+       struct regmap *map;
++      int measure_freq;
+       int ret;
+       data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+@@ -318,6 +407,18 @@ static int imx_thermal_probe(struct platform_device *pdev)
+       }
+       data->tempmon = map;
++      data->irq = platform_get_irq(pdev, 0);
++      if (data->irq < 0)
++              return data->irq;
++
++      ret = devm_request_threaded_irq(&pdev->dev, data->irq,
++                      imx_thermal_alarm_irq, imx_thermal_alarm_irq_thread,
++                      0, "imx_thermal", data);
++      if (ret < 0) {
++              dev_err(&pdev->dev, "failed to request alarm irq: %d\n", ret);
++              return ret;
++      }
++
+       platform_set_drvdata(pdev, data);
+       ret = imx_get_sensor_data(pdev);
+@@ -356,6 +457,15 @@ static int imx_thermal_probe(struct platform_device *pdev)
+               return ret;
+       }
++      /* Enable measurements at ~ 10 Hz */
++      regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ);
++      measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */
++      regmap_write(map, TEMPSENSE1 + REG_SET, measure_freq);
++      imx_set_alarm_temp(data, data->temp_passive);
++      regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN);
++      regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP);
++
++      data->irq_enabled = true;
+       data->mode = THERMAL_DEVICE_ENABLED;
+       return 0;
+@@ -364,6 +474,10 @@ static int imx_thermal_probe(struct platform_device *pdev)
+ static int imx_thermal_remove(struct platform_device *pdev)
+ {
+       struct imx_thermal_data *data = platform_get_drvdata(pdev);
++      struct regmap *map = data->tempmon;
++
++      /* Disable measurements */
++      regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);
+       thermal_zone_device_unregister(data->tz);
+       cpufreq_cooling_unregister(data->cdev);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0979-thermal-exynos_tmu-fix-wrong-error-check-for-mapped-.patch b/patches.tizen/0979-thermal-exynos_tmu-fix-wrong-error-check-for-mapped-.patch
new file mode 100644 (file)
index 0000000..683b2d6
--- /dev/null
@@ -0,0 +1,32 @@
+From 3bbc1028565351fbddc62843a3aa16cc49286d8c Mon Sep 17 00:00:00 2001
+From: Naveen Krishna Chatradhi <ch.naveen@samsung.com>
+Date: Wed, 7 Aug 2013 14:01:09 +0530
+Subject: [PATCH 0979/1302] thermal: exynos_tmu: fix wrong error check for
+ mapped memory
+
+The error check is checking for a "base" mapped memory base
+instead of "base_common". Fixing the same.
+
+Signed-off-by: Naveen Krishna Chatradhi <ch.naveen@samsung.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_tmu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+index ec01dfe..a033dbb 100644
+--- a/drivers/thermal/samsung/exynos_tmu.c
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -592,7 +592,7 @@ static int exynos_map_dt_data(struct platform_device *pdev)
+       data->base_common = devm_ioremap(&pdev->dev, res.start,
+                                       resource_size(&res));
+-      if (!data->base) {
++      if (!data->base_common) {
+               dev_err(&pdev->dev, "Failed to ioremap memory\n");
+               return -ENOMEM;
+       }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0980-Thermal-cpu_cooling-Return-directly-for-the-cpu-out-.patch b/patches.tizen/0980-Thermal-cpu_cooling-Return-directly-for-the-cpu-out-.patch
new file mode 100644 (file)
index 0000000..9cb448a
--- /dev/null
@@ -0,0 +1,41 @@
+From a4e537485cd11c8645b403db3853bbc10fffce60 Mon Sep 17 00:00:00 2001
+From: Lan Tianyu <tianyu.lan@intel.com>
+Date: Tue, 13 Aug 2013 10:07:28 +0800
+Subject: [PATCH 0980/1302] Thermal/cpu_cooling: Return directly for the cpu
+ out of allowed_cpus in the cpufreq_thermal_notifier()
+
+cpufreq_thermal_notifier() is to change the cpu's cpufreq in the allowed_cpus mask
+when associated thermal-cpufreq cdev's cooling state is changed. It's a cpufreq policy
+notifier handler and it will be triggered even if those cpus out of allowed_cpus has
+changed freq policy.
+
+cpufreq_thermal_notifier() checks the policy->cpu. If it belongs to allowed_cpus,
+change max_freq(default to 0) to the desire cpufreq value and pass 0 and max_freq
+to cpufreq_verify_within_limits() as cpufreq scope. But if not, do nothing and
+max_freq will remain 0. This will cause the cpufreq scope to become 0~0. This
+is not right. This patch is to return directly after finding cpu not belonging
+to allowed_cpus.
+
+Signed-off-by: Lan Tianyu <tianyu.lan@intel.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/cpu_cooling.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
+index 82e15db..5b3744e 100644
+--- a/drivers/thermal/cpu_cooling.c
++++ b/drivers/thermal/cpu_cooling.c
+@@ -322,6 +322,8 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
+       if (cpumask_test_cpu(policy->cpu, &notify_device->allowed_cpus))
+               max_freq = notify_device->cpufreq_val;
++      else
++              return 0;
+       /* Never exceed user_policy.max */
+       if (max_freq > policy->user_policy.max)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0981-thermal-step_wise-cdev-only-needs-update-on-a-new-ta.patch b/patches.tizen/0981-thermal-step_wise-cdev-only-needs-update-on-a-new-ta.patch
new file mode 100644 (file)
index 0000000..ee68ce9
--- /dev/null
@@ -0,0 +1,36 @@
+From 0ff220df7d93fdd06775f5b39af87757973bc415 Mon Sep 17 00:00:00 2001
+From: Shawn Guo <shawn.guo@linaro.org>
+Date: Mon, 17 Jun 2013 21:24:23 +0800
+Subject: [PATCH 0981/1302] thermal: step_wise: cdev only needs update on a new
+ target state
+
+The cooling device only needs update on a new target state.  Since we
+already check old target in thermal_zone_trip_update(), we can do one
+more check to see if it's a new target state.  If not, we can reasonably
+save some uncecesary code execution.
+
+Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/step_wise.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/thermal/step_wise.c b/drivers/thermal/step_wise.c
+index 4d4ddae..0afbd86 100644
+--- a/drivers/thermal/step_wise.c
++++ b/drivers/thermal/step_wise.c
+@@ -133,6 +133,9 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
+               old_target = instance->target;
+               instance->target = get_target_state(instance, trend, throttle);
++              if (old_target == instance->target)
++                      continue;
++
+               /* Activate a passive thermal instance */
+               if (old_target == THERMAL_NO_TARGET &&
+                       instance->target != THERMAL_NO_TARGET)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0982-thermal-step_wise-return-instance-target-by-default.patch b/patches.tizen/0982-thermal-step_wise-return-instance-target-by-default.patch
new file mode 100644 (file)
index 0000000..7765a8c
--- /dev/null
@@ -0,0 +1,109 @@
+From 0ba444ccc022591a2a776066336227187c9cba42 Mon Sep 17 00:00:00 2001
+From: Eduardo Valentin <eduardo.valentin@ti.com>
+Date: Mon, 17 Jun 2013 21:24:24 +0800
+Subject: [PATCH 0982/1302] thermal: step_wise: return instance->target by
+ default
+
+In case the trend is not changing or when there is no
+request for throttling, it is expected that the instance
+would not change its requested target. This patch improves
+the code implementation to cover for this expected behavior.
+
+With current implementation, the instance will always
+reset to cdev.cur_state, even in not expected cases,
+like those mentioned above.
+
+This patch changes the step_wise governor implementation
+of get_target so that we accomplish:
+(a) - default value will be current instance->target, so
+we do not change the thermal instance target unnecessarily.
+(b) - the code now it is clear about what is the intention.
+There is a clear statement of what are the expected outcomes
+(c) - removal of hardcoded constants, now it is put in use
+the THERMAL_NO_TARGET macro.
+(d) - variable names are also improved so that reader can
+clearly understand the difference between instance cur target,
+next target and cdev cur_state.
+
+Cc: Zhang Rui <rui.zhang@intel.com>
+Cc: Durgadoss R <durgadoss.r@intel.com>
+Cc: linux-pm@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Reported-by: Ruslan Ruslichenko <ruslan.ruslichenko@ti.com>
+Signed-of-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/step_wise.c | 29 ++++++++++++++++++-----------
+ 1 file changed, 18 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/thermal/step_wise.c b/drivers/thermal/step_wise.c
+index 0afbd86..d89e781 100644
+--- a/drivers/thermal/step_wise.c
++++ b/drivers/thermal/step_wise.c
+@@ -51,44 +51,51 @@ static unsigned long get_target_state(struct thermal_instance *instance,
+ {
+       struct thermal_cooling_device *cdev = instance->cdev;
+       unsigned long cur_state;
++      unsigned long next_target;
++      /*
++       * We keep this instance the way it is by default.
++       * Otherwise, we use the current state of the
++       * cdev in use to determine the next_target.
++       */
+       cdev->ops->get_cur_state(cdev, &cur_state);
++      next_target = instance->target;
+       switch (trend) {
+       case THERMAL_TREND_RAISING:
+               if (throttle) {
+-                      cur_state = cur_state < instance->upper ?
++                      next_target = cur_state < instance->upper ?
+                                   (cur_state + 1) : instance->upper;
+-                      if (cur_state < instance->lower)
+-                              cur_state = instance->lower;
++                      if (next_target < instance->lower)
++                              next_target = instance->lower;
+               }
+               break;
+       case THERMAL_TREND_RAISE_FULL:
+               if (throttle)
+-                      cur_state = instance->upper;
++                      next_target = instance->upper;
+               break;
+       case THERMAL_TREND_DROPPING:
+               if (cur_state == instance->lower) {
+                       if (!throttle)
+-                              cur_state = -1;
++                              next_target = THERMAL_NO_TARGET;
+               } else {
+-                      cur_state -= 1;
+-                      if (cur_state > instance->upper)
+-                              cur_state = instance->upper;
++                      next_target = cur_state - 1;
++                      if (next_target > instance->upper)
++                              next_target = instance->upper;
+               }
+               break;
+       case THERMAL_TREND_DROP_FULL:
+               if (cur_state == instance->lower) {
+                       if (!throttle)
+-                              cur_state = -1;
++                              next_target = THERMAL_NO_TARGET;
+               } else
+-                      cur_state = instance->lower;
++                      next_target = instance->lower;
+               break;
+       default:
+               break;
+       }
+-      return cur_state;
++      return next_target;
+ }
+ static void update_passive_instance(struct thermal_zone_device *tz,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0983-thermal-ti-soc-thermal-Initialize-counter_delay-fiel.patch b/patches.tizen/0983-thermal-ti-soc-thermal-Initialize-counter_delay-fiel.patch
new file mode 100644 (file)
index 0000000..6c49afe
--- /dev/null
@@ -0,0 +1,63 @@
+From a5083eaed5aee8ae1bc76733141e1e008decde45 Mon Sep 17 00:00:00 2001
+From: Ranganath Krishnan <ranganath@ti.com>
+Date: Fri, 23 Aug 2013 11:08:21 -0500
+Subject: [PATCH 0983/1302] thermal: ti-soc-thermal: Initialize counter_delay
+ field for TI DRA752 sensors
+
+Initialize MPU, GPU, CORE, DSPEVE and IVA thermal sensors of DRA752 bandgap
+with the counter delay mask.
+
+Signed-off-by: Ranganath Krishnan <ranganath@ti.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/ti-soc-thermal/dra752-thermal-data.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/thermal/ti-soc-thermal/dra752-thermal-data.c b/drivers/thermal/ti-soc-thermal/dra752-thermal-data.c
+index e5d8326..a492927 100644
+--- a/drivers/thermal/ti-soc-thermal/dra752-thermal-data.c
++++ b/drivers/thermal/ti-soc-thermal/dra752-thermal-data.c
+@@ -42,6 +42,7 @@ dra752_core_temp_sensor_registers = {
+       .mask_hot_mask = DRA752_BANDGAP_CTRL_1_MASK_HOT_CORE_MASK,
+       .mask_cold_mask = DRA752_BANDGAP_CTRL_1_MASK_COLD_CORE_MASK,
+       .mask_sidlemode_mask = DRA752_BANDGAP_CTRL_1_SIDLEMODE_MASK,
++      .mask_counter_delay_mask = DRA752_BANDGAP_CTRL_1_COUNTER_DELAY_MASK,
+       .mask_freeze_mask = DRA752_BANDGAP_CTRL_1_FREEZE_CORE_MASK,
+       .mask_clear_mask = DRA752_BANDGAP_CTRL_1_CLEAR_CORE_MASK,
+       .mask_clear_accum_mask = DRA752_BANDGAP_CTRL_1_CLEAR_ACCUM_CORE_MASK,
+@@ -77,6 +78,7 @@ dra752_iva_temp_sensor_registers = {
+       .mask_hot_mask = DRA752_BANDGAP_CTRL_2_MASK_HOT_IVA_MASK,
+       .mask_cold_mask = DRA752_BANDGAP_CTRL_2_MASK_COLD_IVA_MASK,
+       .mask_sidlemode_mask = DRA752_BANDGAP_CTRL_1_SIDLEMODE_MASK,
++      .mask_counter_delay_mask = DRA752_BANDGAP_CTRL_1_COUNTER_DELAY_MASK,
+       .mask_freeze_mask = DRA752_BANDGAP_CTRL_2_FREEZE_IVA_MASK,
+       .mask_clear_mask = DRA752_BANDGAP_CTRL_2_CLEAR_IVA_MASK,
+       .mask_clear_accum_mask = DRA752_BANDGAP_CTRL_2_CLEAR_ACCUM_IVA_MASK,
+@@ -112,6 +114,7 @@ dra752_mpu_temp_sensor_registers = {
+       .mask_hot_mask = DRA752_BANDGAP_CTRL_1_MASK_HOT_MPU_MASK,
+       .mask_cold_mask = DRA752_BANDGAP_CTRL_1_MASK_COLD_MPU_MASK,
+       .mask_sidlemode_mask = DRA752_BANDGAP_CTRL_1_SIDLEMODE_MASK,
++      .mask_counter_delay_mask = DRA752_BANDGAP_CTRL_1_COUNTER_DELAY_MASK,
+       .mask_freeze_mask = DRA752_BANDGAP_CTRL_1_FREEZE_MPU_MASK,
+       .mask_clear_mask = DRA752_BANDGAP_CTRL_1_CLEAR_MPU_MASK,
+       .mask_clear_accum_mask = DRA752_BANDGAP_CTRL_1_CLEAR_ACCUM_MPU_MASK,
+@@ -147,6 +150,7 @@ dra752_dspeve_temp_sensor_registers = {
+       .mask_hot_mask = DRA752_BANDGAP_CTRL_2_MASK_HOT_DSPEVE_MASK,
+       .mask_cold_mask = DRA752_BANDGAP_CTRL_2_MASK_COLD_DSPEVE_MASK,
+       .mask_sidlemode_mask = DRA752_BANDGAP_CTRL_1_SIDLEMODE_MASK,
++      .mask_counter_delay_mask = DRA752_BANDGAP_CTRL_1_COUNTER_DELAY_MASK,
+       .mask_freeze_mask = DRA752_BANDGAP_CTRL_2_FREEZE_DSPEVE_MASK,
+       .mask_clear_mask = DRA752_BANDGAP_CTRL_2_CLEAR_DSPEVE_MASK,
+       .mask_clear_accum_mask = DRA752_BANDGAP_CTRL_2_CLEAR_ACCUM_DSPEVE_MASK,
+@@ -182,6 +186,7 @@ dra752_gpu_temp_sensor_registers = {
+       .mask_hot_mask = DRA752_BANDGAP_CTRL_1_MASK_HOT_GPU_MASK,
+       .mask_cold_mask = DRA752_BANDGAP_CTRL_1_MASK_COLD_GPU_MASK,
+       .mask_sidlemode_mask = DRA752_BANDGAP_CTRL_1_SIDLEMODE_MASK,
++      .mask_counter_delay_mask = DRA752_BANDGAP_CTRL_1_COUNTER_DELAY_MASK,
+       .mask_freeze_mask = DRA752_BANDGAP_CTRL_1_FREEZE_GPU_MASK,
+       .mask_clear_mask = DRA752_BANDGAP_CTRL_1_CLEAR_GPU_MASK,
+       .mask_clear_accum_mask = DRA752_BANDGAP_CTRL_1_CLEAR_ACCUM_GPU_MASK,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0984-thermal-ti-soc-thermal-Set-the-bandgap-mask-counter-.patch b/patches.tizen/0984-thermal-ti-soc-thermal-Set-the-bandgap-mask-counter-.patch
new file mode 100644 (file)
index 0000000..2fd169e
--- /dev/null
@@ -0,0 +1,52 @@
+From f04b8b9b64d1371bdbb7eb89558319921cfcd77e Mon Sep 17 00:00:00 2001
+From: Ranganath Krishnan <ranganath@ti.com>
+Date: Fri, 23 Aug 2013 11:08:22 -0500
+Subject: [PATCH 0984/1302] thermal: ti-soc-thermal: Set the bandgap mask
+ counter delay value
+
+Set the bandgap mask counter_delay with the polling_delay value on
+registering the thermal zone. This patch will ensure to get the
+correct update interval for computing the thermal trend.
+
+Signed-off-by: Ranganath Krishnan <ranganath@ti.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+index 4c5f55c37..4f8b9af 100644
+--- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
++++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+@@ -174,6 +174,9 @@ static int ti_thermal_set_mode(struct thermal_zone_device *thermal,
+                              enum thermal_device_mode mode)
+ {
+       struct ti_thermal_data *data = thermal->devdata;
++      struct ti_bandgap *bgp;
++
++      bgp = data->bgp;
+       if (!data->ti_thermal) {
+               dev_notice(&thermal->device, "thermal zone not registered\n");
+@@ -190,6 +193,8 @@ static int ti_thermal_set_mode(struct thermal_zone_device *thermal,
+       mutex_unlock(&data->ti_thermal->lock);
+       data->mode = mode;
++      ti_bandgap_write_update_interval(bgp, data->sensor_id,
++                                      data->ti_thermal->polling_delay);
+       thermal_zone_device_update(data->ti_thermal);
+       dev_dbg(&thermal->device, "thermal polling set for duration=%d msec\n",
+               data->ti_thermal->polling_delay);
+@@ -313,6 +318,8 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id,
+       }
+       data->ti_thermal->polling_delay = FAST_TEMP_MONITORING_RATE;
+       ti_bandgap_set_sensor_data(bgp, id, data);
++      ti_bandgap_write_update_interval(bgp, data->sensor_id,
++                                      data->ti_thermal->polling_delay);
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0985-thermal-ti-soc-thermal-Ensure-to-compute-thermal-tre.patch b/patches.tizen/0985-thermal-ti-soc-thermal-Ensure-to-compute-thermal-tre.patch
new file mode 100644 (file)
index 0000000..5ecd280
--- /dev/null
@@ -0,0 +1,39 @@
+From 4bbc95bbaa8be3651ba9c15309a2e6b2dd9b6b2f Mon Sep 17 00:00:00 2001
+From: Ranganath Krishnan <ranganath@ti.com>
+Date: Fri, 23 Aug 2013 11:08:23 -0500
+Subject: [PATCH 0985/1302] thermal: ti-soc-thermal: Ensure to compute thermal
+ trend
+
+Workaround to compute thermal trend even when update interval
+is not set. This patch will ensure to compute the thermal trend
+when bandgap counter delay is not set.
+
+Signed-off-by: Ranganath Krishnan <ranganath@ti.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/ti-soc-thermal/ti-bandgap.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/ti-soc-thermal/ti-bandgap.c b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
+index 9dfd471..74c0e34 100644
+--- a/drivers/thermal/ti-soc-thermal/ti-bandgap.c
++++ b/drivers/thermal/ti-soc-thermal/ti-bandgap.c
+@@ -1020,9 +1020,13 @@ int ti_bandgap_get_trend(struct ti_bandgap *bgp, int id, int *trend)
+       /* Fetch the update interval */
+       ret = ti_bandgap_read_update_interval(bgp, id, &interval);
+-      if (ret || !interval)
++      if (ret)
+               goto unfreeze;
++      /* Set the interval to 1 ms if bandgap counter delay is not set */
++      if (interval == 0)
++              interval = 1;
++
+       *trend = (t1 - t2) / interval;
+       dev_dbg(bgp->dev, "The temperatures are t1 = %d and t2 = %d and trend =%d\n",
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0986-thermal-exynos-Fix-typos-in-Kconfig.patch b/patches.tizen/0986-thermal-exynos-Fix-typos-in-Kconfig.patch
new file mode 100644 (file)
index 0000000..6e5702c
--- /dev/null
@@ -0,0 +1,43 @@
+From a7378a5eb1d638587d52e2f6cd6ecaee2e50fa81 Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Mon, 19 Aug 2013 11:58:41 +0530
+Subject: [PATCH 0986/1302] thermal: exynos: Fix typos in Kconfig
+
+Fixes some trivial typos.
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/Kconfig | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/thermal/samsung/Kconfig b/drivers/thermal/samsung/Kconfig
+index b653f15..92492e4 100644
+--- a/drivers/thermal/samsung/Kconfig
++++ b/drivers/thermal/samsung/Kconfig
+@@ -3,16 +3,16 @@ config EXYNOS_THERMAL
+       depends on ARCH_HAS_BANDGAP
+       help
+         If you say yes here you get support for the TMU (Thermal Management
+-        Unit) driver for SAMSUNG EXYNOS series of soc. This driver initialises
++        Unit) driver for SAMSUNG EXYNOS series of SoCs. This driver initialises
+         the TMU, reports temperature and handles cooling action if defined.
+-        This driver uses the exynos core thermal API's and TMU configuration
+-        data from the supported soc's.
++        This driver uses the Exynos core thermal APIs and TMU configuration
++        data from the supported SoCs.
+ config EXYNOS_THERMAL_CORE
+-      bool "Core thermal framework support for EXYNOS SOC's"
++      bool "Core thermal framework support for EXYNOS SOCs"
+       depends on EXYNOS_THERMAL
+       help
+         If you say yes here you get support for EXYNOS TMU
+         (Thermal Management Unit) common registration/unregistration
+         functions to the core thermal layer and also to use the generic
+-        cpu cooling API's.
++        CPU cooling APIs.
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0987-thermal-exynos-Fix-potential-NULL-pointer-dereferenc.patch b/patches.tizen/0987-thermal-exynos-Fix-potential-NULL-pointer-dereferenc.patch
new file mode 100644 (file)
index 0000000..962be04
--- /dev/null
@@ -0,0 +1,50 @@
+From 70cf1aacb024bccd8f54d3dc0ef4ea824bdd6faa Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Mon, 19 Aug 2013 11:58:42 +0530
+Subject: [PATCH 0987/1302] thermal: exynos: Fix potential NULL pointer
+ dereference
+
+NULL pointer was being dereferenced in its own error message.
+Changed it to the correct device pointer.
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_thermal_common.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c
+index 4d8e444..f10a6ad 100644
+--- a/drivers/thermal/samsung/exynos_thermal_common.c
++++ b/drivers/thermal/samsung/exynos_thermal_common.c
+@@ -53,7 +53,7 @@ static int exynos_set_mode(struct thermal_zone_device *thermal,
+ {
+       struct exynos_thermal_zone *th_zone = thermal->devdata;
+       if (!th_zone) {
+-              dev_err(th_zone->sensor_conf->dev,
++              dev_err(&thermal->device,
+                       "thermal zone not registered\n");
+               return 0;
+       }
+@@ -231,7 +231,7 @@ static int exynos_get_temp(struct thermal_zone_device *thermal,
+       void *data;
+       if (!th_zone->sensor_conf) {
+-              dev_err(th_zone->sensor_conf->dev,
++              dev_err(&thermal->device,
+                       "Temperature sensor not initialised\n");
+               return -EINVAL;
+       }
+@@ -251,7 +251,7 @@ static int exynos_set_emul_temp(struct thermal_zone_device *thermal,
+       struct exynos_thermal_zone *th_zone = thermal->devdata;
+       if (!th_zone->sensor_conf) {
+-              dev_err(th_zone->sensor_conf->dev,
++              dev_err(&thermal->device,
+                       "Temperature sensor not initialised\n");
+               return -EINVAL;
+       }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0988-thermal-exynos-Clean-up-non-DT-remnants.patch b/patches.tizen/0988-thermal-exynos-Clean-up-non-DT-remnants.patch
new file mode 100644 (file)
index 0000000..8e40adb
--- /dev/null
@@ -0,0 +1,100 @@
+From 4e70f5a38affb991886b7c21c91c61c6efad36c9 Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Mon, 19 Aug 2013 11:58:43 +0530
+Subject: [PATCH 0988/1302] thermal: exynos: Clean up non-DT remnants
+
+Commit 1cd1ecb6 ("thermal: exynos: Remove non DT based support")
+cleaned up some non-DT code. However, there were few more things
+needed for complete cleanup to make this driver DT only.
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/Kconfig      |  2 +-
+ drivers/thermal/samsung/exynos_tmu.c | 30 ++++++++++++------------------
+ 2 files changed, 13 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/thermal/samsung/Kconfig b/drivers/thermal/samsung/Kconfig
+index 92492e4..f760389 100644
+--- a/drivers/thermal/samsung/Kconfig
++++ b/drivers/thermal/samsung/Kconfig
+@@ -1,6 +1,6 @@
+ config EXYNOS_THERMAL
+       tristate "Exynos thermal management unit driver"
+-      depends on ARCH_HAS_BANDGAP
++      depends on ARCH_HAS_BANDGAP && OF
+       help
+         If you say yes here you get support for the TMU (Thermal Management
+         Unit) driver for SAMSUNG EXYNOS series of SoCs. This driver initialises
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+index a033dbb..b43afda 100644
+--- a/drivers/thermal/samsung/exynos_tmu.c
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -481,7 +481,6 @@ static irqreturn_t exynos_tmu_irq(int irq, void *id)
+       return IRQ_HANDLED;
+ }
+-#ifdef CONFIG_OF
+ static const struct of_device_id exynos_tmu_match[] = {
+       {
+               .compatible = "samsung,exynos4210-tmu",
+@@ -502,27 +501,22 @@ static const struct of_device_id exynos_tmu_match[] = {
+       {},
+ };
+ MODULE_DEVICE_TABLE(of, exynos_tmu_match);
+-#endif
+ static inline struct  exynos_tmu_platform_data *exynos_get_driver_data(
+                       struct platform_device *pdev, int id)
+ {
+-#ifdef CONFIG_OF
+       struct  exynos_tmu_init_data *data_table;
+       struct exynos_tmu_platform_data *tmu_data;
+-      if (pdev->dev.of_node) {
+-              const struct of_device_id *match;
+-              match = of_match_node(exynos_tmu_match, pdev->dev.of_node);
+-              if (!match)
+-                      return NULL;
+-              data_table = (struct exynos_tmu_init_data *) match->data;
+-              if (!data_table || id >= data_table->tmu_count)
+-                      return NULL;
+-              tmu_data = data_table->tmu_data;
+-              return (struct exynos_tmu_platform_data *) (tmu_data + id);
+-      }
+-#endif
+-      return NULL;
++      const struct of_device_id *match;
++
++      match = of_match_node(exynos_tmu_match, pdev->dev.of_node);
++      if (!match)
++              return NULL;
++      data_table = (struct exynos_tmu_init_data *) match->data;
++      if (!data_table || id >= data_table->tmu_count)
++              return NULL;
++      tmu_data = data_table->tmu_data;
++      return (struct exynos_tmu_platform_data *) (tmu_data + id);
+ }
+ static int exynos_map_dt_data(struct platform_device *pdev)
+@@ -532,7 +526,7 @@ static int exynos_map_dt_data(struct platform_device *pdev)
+       struct resource res;
+       int ret;
+-      if (!data)
++      if (!data || !pdev->dev.of_node)
+               return -ENODEV;
+       /*
+@@ -754,7 +748,7 @@ static struct platform_driver exynos_tmu_driver = {
+               .name   = "exynos-tmu",
+               .owner  = THIS_MODULE,
+               .pm     = EXYNOS_TMU_PM,
+-              .of_match_table = of_match_ptr(exynos_tmu_match),
++              .of_match_table = exynos_tmu_match,
+       },
+       .probe = exynos_tmu_probe,
+       .remove = exynos_tmu_remove,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0989-thermal-hwmon-move-hwmon-support-to-single-file.patch b/patches.tizen/0989-thermal-hwmon-move-hwmon-support-to-single-file.patch
new file mode 100644 (file)
index 0000000..7d7807f
--- /dev/null
@@ -0,0 +1,673 @@
+From 6620854a9d627297f26b6bb1f96822d2a184cc3d Mon Sep 17 00:00:00 2001
+From: Eduardo Valentin <eduardo.valentin@ti.com>
+Date: Wed, 3 Jul 2013 15:14:28 -0400
+Subject: [PATCH 0989/1302] thermal: hwmon: move hwmon support to single file
+
+In order to improve code organization, this patch
+moves the hwmon sysfs support to a file named
+thermal_hwmon. This helps to add extra support
+for hwmon without scrambling the code.
+
+In order to do this move, the hwmon list head is now
+using its own locking. Before, the list used
+the global thermal locking. Also, some minor changes
+in the code were required, as recommended by checkpatch.pl.
+
+Cc: Zhang Rui <rui.zhang@intel.com>
+Cc: linux-pm@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Acked-by: Durgadoss R <durgadoss.r@intel.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/Kconfig         |   9 ++
+ drivers/thermal/Makefile        |   3 +
+ drivers/thermal/thermal_core.c  | 255 +------------------------------------
+ drivers/thermal/thermal_hwmon.c | 269 ++++++++++++++++++++++++++++++++++++++++
+ drivers/thermal/thermal_hwmon.h |  49 ++++++++
+ 5 files changed, 331 insertions(+), 254 deletions(-)
+ create mode 100644 drivers/thermal/thermal_hwmon.c
+ create mode 100644 drivers/thermal/thermal_hwmon.h
+
+diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
+index ae18f02..dbfc390 100644
+--- a/drivers/thermal/Kconfig
++++ b/drivers/thermal/Kconfig
+@@ -17,8 +17,17 @@ if THERMAL
+ config THERMAL_HWMON
+       bool
++      prompt "Expose thermal sensors as hwmon device"
+       depends on HWMON=y || HWMON=THERMAL
+       default y
++      help
++        In case a sensor is registered with the thermal
++        framework, this option will also register it
++        as a hwmon. The sensor will then have the common
++        hwmon sysfs interface.
++
++        Say 'Y' here if you want all thermal sensors to
++        have hwmon sysfs interface too.
+ choice
+       prompt "Default Thermal governor"
+diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
+index c19df7a..584b363 100644
+--- a/drivers/thermal/Makefile
++++ b/drivers/thermal/Makefile
+@@ -5,6 +5,9 @@
+ obj-$(CONFIG_THERMAL)         += thermal_sys.o
+ thermal_sys-y                 += thermal_core.o
++# interface to/from other layers providing sensors
++thermal_sys-$(CONFIG_THERMAL_HWMON)           += thermal_hwmon.o
++
+ # governors
+ thermal_sys-$(CONFIG_THERMAL_GOV_FAIR_SHARE)  += fair_share.o
+ thermal_sys-$(CONFIG_THERMAL_GOV_STEP_WISE)   += step_wise.o
+diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
+index 8f4be55..2c1ef1b 100644
+--- a/drivers/thermal/thermal_core.c
++++ b/drivers/thermal/thermal_core.c
+@@ -39,6 +39,7 @@
+ #include <net/genetlink.h>
+ #include "thermal_core.h"
++#include "thermal_hwmon.h"
+ MODULE_AUTHOR("Zhang Rui");
+ MODULE_DESCRIPTION("Generic thermal management sysfs support");
+@@ -914,260 +915,6 @@ thermal_cooling_device_trip_point_show(struct device *dev,
+ /* Device management */
+-#if defined(CONFIG_THERMAL_HWMON)
+-
+-/* hwmon sys I/F */
+-#include <linux/hwmon.h>
+-
+-/* thermal zone devices with the same type share one hwmon device */
+-struct thermal_hwmon_device {
+-      char type[THERMAL_NAME_LENGTH];
+-      struct device *device;
+-      int count;
+-      struct list_head tz_list;
+-      struct list_head node;
+-};
+-
+-struct thermal_hwmon_attr {
+-      struct device_attribute attr;
+-      char name[16];
+-};
+-
+-/* one temperature input for each thermal zone */
+-struct thermal_hwmon_temp {
+-      struct list_head hwmon_node;
+-      struct thermal_zone_device *tz;
+-      struct thermal_hwmon_attr temp_input;   /* hwmon sys attr */
+-      struct thermal_hwmon_attr temp_crit;    /* hwmon sys attr */
+-};
+-
+-static LIST_HEAD(thermal_hwmon_list);
+-
+-static ssize_t
+-name_show(struct device *dev, struct device_attribute *attr, char *buf)
+-{
+-      struct thermal_hwmon_device *hwmon = dev_get_drvdata(dev);
+-      return sprintf(buf, "%s\n", hwmon->type);
+-}
+-static DEVICE_ATTR(name, 0444, name_show, NULL);
+-
+-static ssize_t
+-temp_input_show(struct device *dev, struct device_attribute *attr, char *buf)
+-{
+-      long temperature;
+-      int ret;
+-      struct thermal_hwmon_attr *hwmon_attr
+-                      = container_of(attr, struct thermal_hwmon_attr, attr);
+-      struct thermal_hwmon_temp *temp
+-                      = container_of(hwmon_attr, struct thermal_hwmon_temp,
+-                                     temp_input);
+-      struct thermal_zone_device *tz = temp->tz;
+-
+-      ret = thermal_zone_get_temp(tz, &temperature);
+-
+-      if (ret)
+-              return ret;
+-
+-      return sprintf(buf, "%ld\n", temperature);
+-}
+-
+-static ssize_t
+-temp_crit_show(struct device *dev, struct device_attribute *attr,
+-              char *buf)
+-{
+-      struct thermal_hwmon_attr *hwmon_attr
+-                      = container_of(attr, struct thermal_hwmon_attr, attr);
+-      struct thermal_hwmon_temp *temp
+-                      = container_of(hwmon_attr, struct thermal_hwmon_temp,
+-                                     temp_crit);
+-      struct thermal_zone_device *tz = temp->tz;
+-      long temperature;
+-      int ret;
+-
+-      ret = tz->ops->get_trip_temp(tz, 0, &temperature);
+-      if (ret)
+-              return ret;
+-
+-      return sprintf(buf, "%ld\n", temperature);
+-}
+-
+-
+-static struct thermal_hwmon_device *
+-thermal_hwmon_lookup_by_type(const struct thermal_zone_device *tz)
+-{
+-      struct thermal_hwmon_device *hwmon;
+-
+-      mutex_lock(&thermal_list_lock);
+-      list_for_each_entry(hwmon, &thermal_hwmon_list, node)
+-              if (!strcmp(hwmon->type, tz->type)) {
+-                      mutex_unlock(&thermal_list_lock);
+-                      return hwmon;
+-              }
+-      mutex_unlock(&thermal_list_lock);
+-
+-      return NULL;
+-}
+-
+-/* Find the temperature input matching a given thermal zone */
+-static struct thermal_hwmon_temp *
+-thermal_hwmon_lookup_temp(const struct thermal_hwmon_device *hwmon,
+-                        const struct thermal_zone_device *tz)
+-{
+-      struct thermal_hwmon_temp *temp;
+-
+-      mutex_lock(&thermal_list_lock);
+-      list_for_each_entry(temp, &hwmon->tz_list, hwmon_node)
+-              if (temp->tz == tz) {
+-                      mutex_unlock(&thermal_list_lock);
+-                      return temp;
+-              }
+-      mutex_unlock(&thermal_list_lock);
+-
+-      return NULL;
+-}
+-
+-static int
+-thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
+-{
+-      struct thermal_hwmon_device *hwmon;
+-      struct thermal_hwmon_temp *temp;
+-      int new_hwmon_device = 1;
+-      int result;
+-
+-      hwmon = thermal_hwmon_lookup_by_type(tz);
+-      if (hwmon) {
+-              new_hwmon_device = 0;
+-              goto register_sys_interface;
+-      }
+-
+-      hwmon = kzalloc(sizeof(struct thermal_hwmon_device), GFP_KERNEL);
+-      if (!hwmon)
+-              return -ENOMEM;
+-
+-      INIT_LIST_HEAD(&hwmon->tz_list);
+-      strlcpy(hwmon->type, tz->type, THERMAL_NAME_LENGTH);
+-      hwmon->device = hwmon_device_register(NULL);
+-      if (IS_ERR(hwmon->device)) {
+-              result = PTR_ERR(hwmon->device);
+-              goto free_mem;
+-      }
+-      dev_set_drvdata(hwmon->device, hwmon);
+-      result = device_create_file(hwmon->device, &dev_attr_name);
+-      if (result)
+-              goto free_mem;
+-
+- register_sys_interface:
+-      temp = kzalloc(sizeof(struct thermal_hwmon_temp), GFP_KERNEL);
+-      if (!temp) {
+-              result = -ENOMEM;
+-              goto unregister_name;
+-      }
+-
+-      temp->tz = tz;
+-      hwmon->count++;
+-
+-      snprintf(temp->temp_input.name, sizeof(temp->temp_input.name),
+-               "temp%d_input", hwmon->count);
+-      temp->temp_input.attr.attr.name = temp->temp_input.name;
+-      temp->temp_input.attr.attr.mode = 0444;
+-      temp->temp_input.attr.show = temp_input_show;
+-      sysfs_attr_init(&temp->temp_input.attr.attr);
+-      result = device_create_file(hwmon->device, &temp->temp_input.attr);
+-      if (result)
+-              goto free_temp_mem;
+-
+-      if (tz->ops->get_crit_temp) {
+-              unsigned long temperature;
+-              if (!tz->ops->get_crit_temp(tz, &temperature)) {
+-                      snprintf(temp->temp_crit.name,
+-                               sizeof(temp->temp_crit.name),
+-                              "temp%d_crit", hwmon->count);
+-                      temp->temp_crit.attr.attr.name = temp->temp_crit.name;
+-                      temp->temp_crit.attr.attr.mode = 0444;
+-                      temp->temp_crit.attr.show = temp_crit_show;
+-                      sysfs_attr_init(&temp->temp_crit.attr.attr);
+-                      result = device_create_file(hwmon->device,
+-                                                  &temp->temp_crit.attr);
+-                      if (result)
+-                              goto unregister_input;
+-              }
+-      }
+-
+-      mutex_lock(&thermal_list_lock);
+-      if (new_hwmon_device)
+-              list_add_tail(&hwmon->node, &thermal_hwmon_list);
+-      list_add_tail(&temp->hwmon_node, &hwmon->tz_list);
+-      mutex_unlock(&thermal_list_lock);
+-
+-      return 0;
+-
+- unregister_input:
+-      device_remove_file(hwmon->device, &temp->temp_input.attr);
+- free_temp_mem:
+-      kfree(temp);
+- unregister_name:
+-      if (new_hwmon_device) {
+-              device_remove_file(hwmon->device, &dev_attr_name);
+-              hwmon_device_unregister(hwmon->device);
+-      }
+- free_mem:
+-      if (new_hwmon_device)
+-              kfree(hwmon);
+-
+-      return result;
+-}
+-
+-static void
+-thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
+-{
+-      struct thermal_hwmon_device *hwmon;
+-      struct thermal_hwmon_temp *temp;
+-
+-      hwmon = thermal_hwmon_lookup_by_type(tz);
+-      if (unlikely(!hwmon)) {
+-              /* Should never happen... */
+-              dev_dbg(&tz->device, "hwmon device lookup failed!\n");
+-              return;
+-      }
+-
+-      temp = thermal_hwmon_lookup_temp(hwmon, tz);
+-      if (unlikely(!temp)) {
+-              /* Should never happen... */
+-              dev_dbg(&tz->device, "temperature input lookup failed!\n");
+-              return;
+-      }
+-
+-      device_remove_file(hwmon->device, &temp->temp_input.attr);
+-      if (tz->ops->get_crit_temp)
+-              device_remove_file(hwmon->device, &temp->temp_crit.attr);
+-
+-      mutex_lock(&thermal_list_lock);
+-      list_del(&temp->hwmon_node);
+-      kfree(temp);
+-      if (!list_empty(&hwmon->tz_list)) {
+-              mutex_unlock(&thermal_list_lock);
+-              return;
+-      }
+-      list_del(&hwmon->node);
+-      mutex_unlock(&thermal_list_lock);
+-
+-      device_remove_file(hwmon->device, &dev_attr_name);
+-      hwmon_device_unregister(hwmon->device);
+-      kfree(hwmon);
+-}
+-#else
+-static int
+-thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
+-{
+-      return 0;
+-}
+-
+-static void
+-thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
+-{
+-}
+-#endif
+-
+ /**
+  * thermal_zone_bind_cooling_device() - bind a cooling device to a thermal zone
+  * @tz:               pointer to struct thermal_zone_device
+diff --git a/drivers/thermal/thermal_hwmon.c b/drivers/thermal/thermal_hwmon.c
+new file mode 100644
+index 0000000..fdb0719
+--- /dev/null
++++ b/drivers/thermal/thermal_hwmon.c
+@@ -0,0 +1,269 @@
++/*
++ *  thermal_hwmon.c - Generic Thermal Management hwmon support.
++ *
++ *  Code based on Intel thermal_core.c. Copyrights of the original code:
++ *  Copyright (C) 2008 Intel Corp
++ *  Copyright (C) 2008 Zhang Rui <rui.zhang@intel.com>
++ *  Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com>
++ *
++ *  Copyright (C) 2013 Texas Instruments
++ *  Copyright (C) 2013 Eduardo Valentin <eduardo.valentin@ti.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.,
++ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
++ *
++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++ */
++#include <linux/hwmon.h>
++#include <linux/thermal.h>
++#include <linux/slab.h>
++#include <linux/err.h>
++#include "thermal_hwmon.h"
++
++/* hwmon sys I/F */
++/* thermal zone devices with the same type share one hwmon device */
++struct thermal_hwmon_device {
++      char type[THERMAL_NAME_LENGTH];
++      struct device *device;
++      int count;
++      struct list_head tz_list;
++      struct list_head node;
++};
++
++struct thermal_hwmon_attr {
++      struct device_attribute attr;
++      char name[16];
++};
++
++/* one temperature input for each thermal zone */
++struct thermal_hwmon_temp {
++      struct list_head hwmon_node;
++      struct thermal_zone_device *tz;
++      struct thermal_hwmon_attr temp_input;   /* hwmon sys attr */
++      struct thermal_hwmon_attr temp_crit;    /* hwmon sys attr */
++};
++
++static LIST_HEAD(thermal_hwmon_list);
++
++static DEFINE_MUTEX(thermal_hwmon_list_lock);
++
++static ssize_t
++name_show(struct device *dev, struct device_attribute *attr, char *buf)
++{
++      struct thermal_hwmon_device *hwmon = dev_get_drvdata(dev);
++      return sprintf(buf, "%s\n", hwmon->type);
++}
++static DEVICE_ATTR(name, 0444, name_show, NULL);
++
++static ssize_t
++temp_input_show(struct device *dev, struct device_attribute *attr, char *buf)
++{
++      long temperature;
++      int ret;
++      struct thermal_hwmon_attr *hwmon_attr
++                      = container_of(attr, struct thermal_hwmon_attr, attr);
++      struct thermal_hwmon_temp *temp
++                      = container_of(hwmon_attr, struct thermal_hwmon_temp,
++                                     temp_input);
++      struct thermal_zone_device *tz = temp->tz;
++
++      ret = thermal_zone_get_temp(tz, &temperature);
++
++      if (ret)
++              return ret;
++
++      return sprintf(buf, "%ld\n", temperature);
++}
++
++static ssize_t
++temp_crit_show(struct device *dev, struct device_attribute *attr, char *buf)
++{
++      struct thermal_hwmon_attr *hwmon_attr
++                      = container_of(attr, struct thermal_hwmon_attr, attr);
++      struct thermal_hwmon_temp *temp
++                      = container_of(hwmon_attr, struct thermal_hwmon_temp,
++                                     temp_crit);
++      struct thermal_zone_device *tz = temp->tz;
++      long temperature;
++      int ret;
++
++      ret = tz->ops->get_trip_temp(tz, 0, &temperature);
++      if (ret)
++              return ret;
++
++      return sprintf(buf, "%ld\n", temperature);
++}
++
++
++static struct thermal_hwmon_device *
++thermal_hwmon_lookup_by_type(const struct thermal_zone_device *tz)
++{
++      struct thermal_hwmon_device *hwmon;
++
++      mutex_lock(&thermal_hwmon_list_lock);
++      list_for_each_entry(hwmon, &thermal_hwmon_list, node)
++              if (!strcmp(hwmon->type, tz->type)) {
++                      mutex_unlock(&thermal_hwmon_list_lock);
++                      return hwmon;
++              }
++      mutex_unlock(&thermal_hwmon_list_lock);
++
++      return NULL;
++}
++
++/* Find the temperature input matching a given thermal zone */
++static struct thermal_hwmon_temp *
++thermal_hwmon_lookup_temp(const struct thermal_hwmon_device *hwmon,
++                        const struct thermal_zone_device *tz)
++{
++      struct thermal_hwmon_temp *temp;
++
++      mutex_lock(&thermal_hwmon_list_lock);
++      list_for_each_entry(temp, &hwmon->tz_list, hwmon_node)
++              if (temp->tz == tz) {
++                      mutex_unlock(&thermal_hwmon_list_lock);
++                      return temp;
++              }
++      mutex_unlock(&thermal_hwmon_list_lock);
++
++      return NULL;
++}
++
++int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
++{
++      struct thermal_hwmon_device *hwmon;
++      struct thermal_hwmon_temp *temp;
++      int new_hwmon_device = 1;
++      int result;
++
++      hwmon = thermal_hwmon_lookup_by_type(tz);
++      if (hwmon) {
++              new_hwmon_device = 0;
++              goto register_sys_interface;
++      }
++
++      hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);
++      if (!hwmon)
++              return -ENOMEM;
++
++      INIT_LIST_HEAD(&hwmon->tz_list);
++      strlcpy(hwmon->type, tz->type, THERMAL_NAME_LENGTH);
++      hwmon->device = hwmon_device_register(NULL);
++      if (IS_ERR(hwmon->device)) {
++              result = PTR_ERR(hwmon->device);
++              goto free_mem;
++      }
++      dev_set_drvdata(hwmon->device, hwmon);
++      result = device_create_file(hwmon->device, &dev_attr_name);
++      if (result)
++              goto free_mem;
++
++ register_sys_interface:
++      temp = kzalloc(sizeof(*temp), GFP_KERNEL);
++      if (!temp) {
++              result = -ENOMEM;
++              goto unregister_name;
++      }
++
++      temp->tz = tz;
++      hwmon->count++;
++
++      snprintf(temp->temp_input.name, sizeof(temp->temp_input.name),
++               "temp%d_input", hwmon->count);
++      temp->temp_input.attr.attr.name = temp->temp_input.name;
++      temp->temp_input.attr.attr.mode = 0444;
++      temp->temp_input.attr.show = temp_input_show;
++      sysfs_attr_init(&temp->temp_input.attr.attr);
++      result = device_create_file(hwmon->device, &temp->temp_input.attr);
++      if (result)
++              goto free_temp_mem;
++
++      if (tz->ops->get_crit_temp) {
++              unsigned long temperature;
++              if (!tz->ops->get_crit_temp(tz, &temperature)) {
++                      snprintf(temp->temp_crit.name,
++                               sizeof(temp->temp_crit.name),
++                              "temp%d_crit", hwmon->count);
++                      temp->temp_crit.attr.attr.name = temp->temp_crit.name;
++                      temp->temp_crit.attr.attr.mode = 0444;
++                      temp->temp_crit.attr.show = temp_crit_show;
++                      sysfs_attr_init(&temp->temp_crit.attr.attr);
++                      result = device_create_file(hwmon->device,
++                                                  &temp->temp_crit.attr);
++                      if (result)
++                              goto unregister_input;
++              }
++      }
++
++      mutex_lock(&thermal_hwmon_list_lock);
++      if (new_hwmon_device)
++              list_add_tail(&hwmon->node, &thermal_hwmon_list);
++      list_add_tail(&temp->hwmon_node, &hwmon->tz_list);
++      mutex_unlock(&thermal_hwmon_list_lock);
++
++      return 0;
++
++ unregister_input:
++      device_remove_file(hwmon->device, &temp->temp_input.attr);
++ free_temp_mem:
++      kfree(temp);
++ unregister_name:
++      if (new_hwmon_device) {
++              device_remove_file(hwmon->device, &dev_attr_name);
++              hwmon_device_unregister(hwmon->device);
++      }
++ free_mem:
++      if (new_hwmon_device)
++              kfree(hwmon);
++
++      return result;
++}
++
++void thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
++{
++      struct thermal_hwmon_device *hwmon;
++      struct thermal_hwmon_temp *temp;
++
++      hwmon = thermal_hwmon_lookup_by_type(tz);
++      if (unlikely(!hwmon)) {
++              /* Should never happen... */
++              dev_dbg(&tz->device, "hwmon device lookup failed!\n");
++              return;
++      }
++
++      temp = thermal_hwmon_lookup_temp(hwmon, tz);
++      if (unlikely(!temp)) {
++              /* Should never happen... */
++              dev_dbg(&tz->device, "temperature input lookup failed!\n");
++              return;
++      }
++
++      device_remove_file(hwmon->device, &temp->temp_input.attr);
++      if (tz->ops->get_crit_temp)
++              device_remove_file(hwmon->device, &temp->temp_crit.attr);
++
++      mutex_lock(&thermal_hwmon_list_lock);
++      list_del(&temp->hwmon_node);
++      kfree(temp);
++      if (!list_empty(&hwmon->tz_list)) {
++              mutex_unlock(&thermal_hwmon_list_lock);
++              return;
++      }
++      list_del(&hwmon->node);
++      mutex_unlock(&thermal_hwmon_list_lock);
++
++      device_remove_file(hwmon->device, &dev_attr_name);
++      hwmon_device_unregister(hwmon->device);
++      kfree(hwmon);
++}
+diff --git a/drivers/thermal/thermal_hwmon.h b/drivers/thermal/thermal_hwmon.h
+new file mode 100644
+index 0000000..c798fdb
+--- /dev/null
++++ b/drivers/thermal/thermal_hwmon.h
+@@ -0,0 +1,49 @@
++/*
++ *  thermal_hwmon.h - Generic Thermal Management hwmon support.
++ *
++ *  Code based on Intel thermal_core.c. Copyrights of the original code:
++ *  Copyright (C) 2008 Intel Corp
++ *  Copyright (C) 2008 Zhang Rui <rui.zhang@intel.com>
++ *  Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com>
++ *
++ *  Copyright (C) 2013 Texas Instruments
++ *  Copyright (C) 2013 Eduardo Valentin <eduardo.valentin@ti.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.,
++ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
++ *
++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++ */
++#ifndef __THERMAL_HWMON_H__
++#define __THERMAL_HWMON_H__
++
++#include <linux/thermal.h>
++
++#ifdef CONFIG_THERMAL_HWMON
++int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz);
++void thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz);
++#else
++static int
++thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
++{
++      return 0;
++}
++
++static void
++thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
++{
++}
++#endif
++
++#endif /* __THERMAL_HWMON_H__ */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0990-drivers-thermal-parent-virtual-hwmon-with-thermal-zo.patch b/patches.tizen/0990-drivers-thermal-parent-virtual-hwmon-with-thermal-zo.patch
new file mode 100644 (file)
index 0000000..409a2ee
--- /dev/null
@@ -0,0 +1,38 @@
+From 65d1fa232d591f1102167aad7885a31eb21aba1e Mon Sep 17 00:00:00 2001
+From: Eduardo Valentin <eduardo.valentin@ti.com>
+Date: Fri, 23 Aug 2013 17:07:58 -0400
+Subject: [PATCH 0990/1302] drivers: thermal: parent virtual hwmon with thermal
+ zone
+
+When  creating virtual hwmon devices based out of thermal
+zone devices, the virtual devices won't have parents.
+
+This patch changes the code so that the parent of virtual
+hwmon devices is the thermal zone device that they are
+based of.
+
+Cc: Zhang Rui <rui.zhang@intel.com>
+Cc: linux-pm@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/thermal_hwmon.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/thermal_hwmon.c b/drivers/thermal/thermal_hwmon.c
+index fdb0719..eeef0e2 100644
+--- a/drivers/thermal/thermal_hwmon.c
++++ b/drivers/thermal/thermal_hwmon.c
+@@ -159,7 +159,7 @@ int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
+       INIT_LIST_HEAD(&hwmon->tz_list);
+       strlcpy(hwmon->type, tz->type, THERMAL_NAME_LENGTH);
+-      hwmon->device = hwmon_device_register(NULL);
++      hwmon->device = hwmon_device_register(&tz->device);
+       if (IS_ERR(hwmon->device)) {
+               result = PTR_ERR(hwmon->device);
+               goto free_mem;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0991-drivers-thermal-make-usage-of-CONFIG_THERMAL_HWMON-o.patch b/patches.tizen/0991-drivers-thermal-make-usage-of-CONFIG_THERMAL_HWMON-o.patch
new file mode 100644 (file)
index 0000000..f478061
--- /dev/null
@@ -0,0 +1,52 @@
+From 8ba0bbc3e968d9430db2228df87f43fe3b624f61 Mon Sep 17 00:00:00 2001
+From: Eduardo Valentin <eduardo.valentin@ti.com>
+Date: Thu, 15 Aug 2013 11:34:17 -0400
+Subject: [PATCH 0991/1302] drivers: thermal: make usage of
+ CONFIG_THERMAL_HWMON optional
+
+When registering a new thermal_device, the thermal framework
+will always add a hwmon sysfs interface.
+
+This patch adds a flag to make this behavior optional. Now
+when registering a new thermal device, the caller can
+optionally inform if hwmon interface is desirable. This can
+be done by means of passing a thermal_zone_params.no_hwmon == true.
+
+In order to keep same behavior as of today, all current
+calls will by default create the hwmon interface.
+
+Cc: David Woodhouse <dwmw2@infradead.org>
+Cc: linux-acpi@vger.kernel.org
+Cc: linux-arm-kernel@lists.infradead.org
+Cc: linux-kernel@vger.kernel.org
+Cc: linux-pm@vger.kernel.org
+Cc: Zhang Rui <rui.zhang@intel.com>
+Suggested-by: Wei Ni <wni@nvidia.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/thermal_core.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
+index 2c1ef1b..7e62cc4 100644
+--- a/drivers/thermal/thermal_core.c
++++ b/drivers/thermal/thermal_core.c
+@@ -1517,9 +1517,11 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
+       mutex_unlock(&thermal_governor_lock);
+-      result = thermal_add_hwmon_sysfs(tz);
+-      if (result)
+-              goto unregister;
++      if (!tz->tzp || !tz->tzp->no_hwmon) {
++              result = thermal_add_hwmon_sysfs(tz);
++              if (result)
++                      goto unregister;
++      }
+       mutex_lock(&thermal_list_lock);
+       list_add_tail(&tz->node, &thermal_tz_list);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0992-thermal-thermal_core-allow-binding-with-limits-on-bi.patch b/patches.tizen/0992-thermal-thermal_core-allow-binding-with-limits-on-bi.patch
new file mode 100644 (file)
index 0000000..ff4f468
--- /dev/null
@@ -0,0 +1,77 @@
+From 3f14c783e0683f0d8186383712d9675f471feed4 Mon Sep 17 00:00:00 2001
+From: Eduardo Valentin <eduardo.valentin@ti.com>
+Date: Tue, 16 Jul 2013 15:26:28 -0400
+Subject: [PATCH 0992/1302] thermal: thermal_core: allow binding with limits on
+ bind_params
+
+When registering a thermal zone device using platform information
+via bind_params, the thermal framework will always perform the
+cdev binding using the lowest and highest limits (THERMAL_NO_LIMIT).
+
+This patch changes the data structures so that it is possible
+to inform what are the desired limits for each trip point
+inside a bind_param. The way the binding is performed is also
+changed so that it uses the new data structure.
+
+Cc: Zhang Rui <rui.zhang@intel.com>
+Cc: linux-pm@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/thermal_core.c | 19 +++++++++++++++----
+ 1 file changed, 15 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
+index 7e62cc4..a167ab9 100644
+--- a/drivers/thermal/thermal_core.c
++++ b/drivers/thermal/thermal_core.c
+@@ -203,14 +203,23 @@ static void print_bind_err_msg(struct thermal_zone_device *tz,
+ }
+ static void __bind(struct thermal_zone_device *tz, int mask,
+-                      struct thermal_cooling_device *cdev)
++                      struct thermal_cooling_device *cdev,
++                      unsigned long *limits)
+ {
+       int i, ret;
+       for (i = 0; i < tz->trips; i++) {
+               if (mask & (1 << i)) {
++                      unsigned long upper, lower;
++
++                      upper = THERMAL_NO_LIMIT;
++                      lower = THERMAL_NO_LIMIT;
++                      if (limits) {
++                              lower = limits[i * 2];
++                              upper = limits[i * 2 + 1];
++                      }
+                       ret = thermal_zone_bind_cooling_device(tz, i, cdev,
+-                                      THERMAL_NO_LIMIT, THERMAL_NO_LIMIT);
++                                                             upper, lower);
+                       if (ret)
+                               print_bind_err_msg(tz, cdev, ret);
+               }
+@@ -255,7 +264,8 @@ static void bind_cdev(struct thermal_cooling_device *cdev)
+                       if (tzp->tbp[i].match(pos, cdev))
+                               continue;
+                       tzp->tbp[i].cdev = cdev;
+-                      __bind(pos, tzp->tbp[i].trip_mask, cdev);
++                      __bind(pos, tzp->tbp[i].trip_mask, cdev,
++                             tzp->tbp[i].binding_limits);
+               }
+       }
+@@ -293,7 +303,8 @@ static void bind_tz(struct thermal_zone_device *tz)
+                       if (tzp->tbp[i].match(tz, pos))
+                               continue;
+                       tzp->tbp[i].cdev = pos;
+-                      __bind(tz, tzp->tbp[i].trip_mask, pos);
++                      __bind(tz, tzp->tbp[i].trip_mask, pos,
++                             tzp->tbp[i].binding_limits);
+               }
+       }
+ exit:
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0993-drivers-thermal-add-check-when-unregistering-cpu-coo.patch b/patches.tizen/0993-drivers-thermal-add-check-when-unregistering-cpu-coo.patch
new file mode 100644 (file)
index 0000000..b77874c
--- /dev/null
@@ -0,0 +1,39 @@
+From 170fd934745b29cf49418d2e54c19154904a3db0 Mon Sep 17 00:00:00 2001
+From: Eduardo Valentin <eduardo.valentin@ti.com>
+Date: Thu, 15 Aug 2013 10:54:46 -0400
+Subject: [PATCH 0993/1302] drivers: thermal: add check when unregistering cpu
+ cooling
+
+This patch avoids NULL pointer accesses while unregistering
+cpu cooling devices, in case a NULL pointer is received.
+
+Cc: Zhang Rui <rui.zhang@intel.com>
+Cc: linux-pm@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/cpu_cooling.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
+index 5b3744e..d179028 100644
+--- a/drivers/thermal/cpu_cooling.c
++++ b/drivers/thermal/cpu_cooling.c
+@@ -498,8 +498,12 @@ EXPORT_SYMBOL_GPL(cpufreq_cooling_register);
+  */
+ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
+ {
+-      struct cpufreq_cooling_device *cpufreq_dev = cdev->devdata;
++      struct cpufreq_cooling_device *cpufreq_dev;
++      if (!cdev)
++              return;
++
++      cpufreq_dev = cdev->devdata;
+       mutex_lock(&cooling_cpufreq_lock);
+       cpufreq_dev_count--;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0994-dts-Fix-exynos4x12-dts-file-to-get-thermal-sensor-re.patch b/patches.tizen/0994-dts-Fix-exynos4x12-dts-file-to-get-thermal-sensor-re.patch
new file mode 100644 (file)
index 0000000..4ee631e
--- /dev/null
@@ -0,0 +1,82 @@
+From 8b406abadeb34e4dfab97b20495ce6401273b344 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Fri, 1 Nov 2013 17:32:40 +0900
+Subject: [PATCH 0994/1302] dts: Fix exynos4x12 dts file to get thermal sensor
+ regualtor properly.
+
+Fixes regulator consumer name from DT from 'vdd_ts' to 'vtmu' which
+is used in Exynos tmu driver. And also enable tmu in all exynos4412 boards.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4212-slp_pd.dts     | 2 +-
+ arch/arm/boot/dts/exynos4412-redwood.dts    | 5 -----
+ arch/arm/boot/dts/exynos4412-redwoodlte.dts | 5 -----
+ arch/arm/boot/dts/exynos4412-slp_pq.dts     | 5 +++++
+ 4 files changed, 6 insertions(+), 11 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4212-slp_pd.dts b/arch/arm/boot/dts/exynos4212-slp_pd.dts
+index 4c8d1a7..cdf5cc3 100644
+--- a/arch/arm/boot/dts/exynos4212-slp_pd.dts
++++ b/arch/arm/boot/dts/exynos4212-slp_pd.dts
+@@ -355,7 +355,7 @@
+       };
+       tmu@100C0000 {
+-              vdd_ts-supply = <&ldo4_reg>;
++              vtmu-supply = <&ldo4_reg>;
+               status = "okay";
+       };
+ };
+diff --git a/arch/arm/boot/dts/exynos4412-redwood.dts b/arch/arm/boot/dts/exynos4412-redwood.dts
+index a8c99fd..e6dca07 100644
+--- a/arch/arm/boot/dts/exynos4412-redwood.dts
++++ b/arch/arm/boot/dts/exynos4412-redwood.dts
+@@ -144,11 +144,6 @@
+               status = "okay";
+       };
+-      tmu@100C0000 {
+-              vdd_ts-supply = <&ldo10_reg>;
+-              status = "okay";
+-      };
+-
+       ehci@12580000 {
+               status = "okay";
+       };
+diff --git a/arch/arm/boot/dts/exynos4412-redwoodlte.dts b/arch/arm/boot/dts/exynos4412-redwoodlte.dts
+index bc61f1c..6d38430 100644
+--- a/arch/arm/boot/dts/exynos4412-redwoodlte.dts
++++ b/arch/arm/boot/dts/exynos4412-redwoodlte.dts
+@@ -750,11 +750,6 @@
+               max_overclocking_freq = <1500000>;
+       };
+-      tmu@100C0000 {
+-              vdd_ts-supply = <&ldo10_reg>;
+-              status = "okay";
+-      };
+-
+       ehci@12580000 {
+               status = "okay";
+       };
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index e05f3fa..e99ddc9 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -1397,6 +1397,11 @@
+               vdd-supply = <&ldo3_reg>;
+               status = "ok";
+       };
++
++      tmu@100C0000 {
++              vtmu-supply = <&ldo10_reg>;
++              status = "okay";
++      };
+ };
+ &pinctrl_1 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0995-Documentation-thermal-Explain-the-exynos-thermal-dri.patch b/patches.tizen/0995-Documentation-thermal-Explain-the-exynos-thermal-dri.patch
new file mode 100644 (file)
index 0000000..277d5b1
--- /dev/null
@@ -0,0 +1,95 @@
+From fc17901a7e6a72f7b3f84b6661b7fe417ba48870 Mon Sep 17 00:00:00 2001
+From: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Date: Mon, 24 Jun 2013 16:20:49 +0530
+Subject: [PATCH 0995/1302] Documentation: thermal: Explain the exynos thermal
+ driver model
+
+This patch updates the documentation to explain the driver model
+and file layout.
+
+Acked-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Acked-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/thermal/exynos_thermal | 43 ++++++++++++++++++++++++++++--------
+ 1 file changed, 34 insertions(+), 9 deletions(-)
+
+diff --git a/Documentation/thermal/exynos_thermal b/Documentation/thermal/exynos_thermal
+index 2b46f67..9010c44 100644
+--- a/Documentation/thermal/exynos_thermal
++++ b/Documentation/thermal/exynos_thermal
+@@ -1,17 +1,17 @@
+-Kernel driver exynos4_tmu
++Kernel driver exynos_tmu
+ =================
+ Supported chips:
+-* ARM SAMSUNG EXYNOS4 series of SoC
+-  Prefix: 'exynos4-tmu'
++* ARM SAMSUNG EXYNOS4, EXYNOS5 series of SoC
+   Datasheet: Not publicly available
+ Authors: Donggeun Kim <dg77.kim@samsung.com>
++Authors: Amit Daniel <amit.daniel@samsung.com>
+-Description
+------------
++TMU controller Description:
++---------------------------
+-This driver allows to read temperature inside SAMSUNG EXYNOS4 series of SoC.
++This driver allows to read temperature inside SAMSUNG EXYNOS4/5 series of SoC.
+ The chip only exposes the measured 8-bit temperature code value
+ through a register.
+@@ -34,9 +34,9 @@ The three equations are:
+   TI2: Trimming info for 85 degree Celsius (stored at TRIMINFO register)
+        Temperature code measured at 85 degree Celsius which is unchanged
+-TMU(Thermal Management Unit) in EXYNOS4 generates interrupt
++TMU(Thermal Management Unit) in EXYNOS4/5 generates interrupt
+ when temperature exceeds pre-defined levels.
+-The maximum number of configurable threshold is four.
++The maximum number of configurable threshold is five.
+ The threshold levels are defined as follows:
+   Level_0: current temperature > trigger_level_0 + threshold
+   Level_1: current temperature > trigger_level_1 + threshold
+@@ -47,6 +47,31 @@ The threshold levels are defined as follows:
+   through the corresponding registers.
+ When an interrupt occurs, this driver notify kernel thermal framework
+-with the function exynos4_report_trigger.
++with the function exynos_report_trigger.
+ Although an interrupt condition for level_0 can be set,
+ it can be used to synchronize the cooling action.
++
++TMU driver description:
++-----------------------
++
++The exynos thermal driver is structured as,
++
++                                      Kernel Core thermal framework
++                              (thermal_core.c, step_wise.c, cpu_cooling.c)
++                                                              ^
++                                                              |
++                                                              |
++TMU configuration data -------> TMU Driver  <------> Exynos Core thermal wrapper
++(exynos_tmu_data.c)         (exynos_tmu.c)       (exynos_thermal_common.c)
++(exynos_tmu_data.h)         (exynos_tmu.h)       (exynos_thermal_common.h)
++
++a) TMU configuration data: This consist of TMU register offsets/bitfields
++              described through structure exynos_tmu_registers. Also several
++              other platform data (struct exynos_tmu_platform_data) members
++              are used to configure the TMU.
++b) TMU driver: This component initialises the TMU controller and sets different
++              thresholds. It invokes core thermal implementation with the call
++              exynos_report_trigger.
++c) Exynos Core thermal wrapper: This provides 3 wrapper function to use the
++              Kernel core thermal framework. They are exynos_unregister_thermal,
++              exynos_register_thermal and exynos_report_trigger.
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0996-thermal-Add-ommitted-codes-from-merging.patch b/patches.tizen/0996-thermal-Add-ommitted-codes-from-merging.patch
new file mode 100644 (file)
index 0000000..c6011e2
--- /dev/null
@@ -0,0 +1,86 @@
+From 2beeb87d2a585562e9c7cdd1e4193a4064c0844d Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Fri, 1 Nov 2013 18:44:14 +0900
+Subject: [PATCH 0996/1302] thermal: Add ommitted codes from merging.
+
+Add omitted codes from commits,
+
+<commit-id d9e6913d1> "drivers: thermal: add check when ~ ", and
+<commit-id efbf8d7a3> "thermal: thermal_core: allow binding with ~"
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/thermal/sysfs-api.txt | 12 ++++++++++++
+ include/linux/thermal.h             | 18 ++++++++++++++++++
+ 2 files changed, 30 insertions(+)
+
+diff --git a/Documentation/thermal/sysfs-api.txt b/Documentation/thermal/sysfs-api.txt
+index a71bd5b..87519cb 100644
+--- a/Documentation/thermal/sysfs-api.txt
++++ b/Documentation/thermal/sysfs-api.txt
+@@ -134,6 +134,13 @@ temperature) and throttle appropriate devices.
+                this thermal zone and cdev, for a particular trip point.
+                If nth bit is set, then the cdev and thermal zone are bound
+                for trip point n.
++    .limits: This is an array of cooling state limits. Must have exactly
++         2 * thermal_zone.number_of_trip_points. It is an array consisting
++         of tuples <lower-state upper-state> of state limits. Each trip
++         will be associated with one state limit tuple when binding.
++         A NULL pointer means <THERMAL_NO_LIMITS THERMAL_NO_LIMITS>
++         on all trips. These limits are used when binding a cdev to a
++         trip point.
+     .match: This call back returns success(0) if the 'tz and cdev' need to
+           be bound, as per platform data.
+ 1.4.2 struct thermal_zone_params
+@@ -142,6 +149,11 @@ temperature) and throttle appropriate devices.
+     This is an optional feature where some platforms can choose not to
+     provide this data.
+     .governor_name: Name of the thermal governor used for this zone
++    .no_hwmon: a boolean to indicate if the thermal to hwmon sysfs interface
++               is required. when no_hwmon == false, a hwmon sysfs interface
++               will be created. when no_hwmon == true, nothing will be done.
++               In case the thermal_zone_params is NULL, the hwmon interface
++               will be created (for backward compatibility).
+     .num_tbps: Number of thermal_bind_params entries for this zone
+     .tbp: thermal_bind_params entries
+diff --git a/include/linux/thermal.h b/include/linux/thermal.h
+index f1aa3c2..b316bdf 100644
+--- a/include/linux/thermal.h
++++ b/include/linux/thermal.h
+@@ -209,6 +209,16 @@ struct thermal_bind_params {
+        * See Documentation/thermal/sysfs-api.txt for more information.
+        */
+       int trip_mask;
++
++      /*
++       * This is an array of cooling state limits. Must have exactly
++       * 2 * thermal_zone.number_of_trip_points. It is an array consisting
++       * of tuples <lower-state upper-state> of state limits. Each trip
++       * will be associated with one state limit tuple when binding.
++       * A NULL pointer means <THERMAL_NO_LIMITS THERMAL_NO_LIMITS>
++       * on all trips.
++       */
++      unsigned long *binding_limits;
+       int (*match) (struct thermal_zone_device *tz,
+                       struct thermal_cooling_device *cdev);
+ };
+@@ -216,6 +226,14 @@ struct thermal_bind_params {
+ /* Structure to define Thermal Zone parameters */
+ struct thermal_zone_params {
+       char governor_name[THERMAL_NAME_LENGTH];
++
++      /*
++       * a boolean to indicate if the thermal to hwmon sysfs interface
++       * is required. when no_hwmon == false, a hwmon sysfs interface
++       * will be created. when no_hwmon == true, nothing will be done
++       */
++      bool no_hwmon;
++
+       int num_tbps;   /* Number of tbp entries */
+       struct thermal_bind_params *tbp;
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0997-Introduce-CONFIG_ARCH_HAS_BANDGAP-and-ARCH_EXYNOS4-5.patch b/patches.tizen/0997-Introduce-CONFIG_ARCH_HAS_BANDGAP-and-ARCH_EXYNOS4-5.patch
new file mode 100644 (file)
index 0000000..9eb3524
--- /dev/null
@@ -0,0 +1,52 @@
+From 136413c6a101ece8d7ddfdc38d4ceb45b255384c Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Fri, 1 Nov 2013 18:53:09 +0900
+Subject: [PATCH 0997/1302] Introduce CONFIG_ARCH_HAS_BANDGAP and
+ ARCH_EXYNOS4/5 selects it.
+
+CONFIG_ARCH_HAS_BANDGAP is used for tmu driver in thermal fw.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/Kconfig             | 3 +++
+ arch/arm/mach-exynos/Kconfig | 2 ++
+ 2 files changed, 5 insertions(+)
+
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index 18a9f5e..27194fa 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -174,6 +174,9 @@ config ARCH_HAS_CPUFREQ
+         and that the relevant menu configurations are displayed for
+         it.
++config ARCH_HAS_BANDGAP
++      bool
++
+ config GENERIC_HWEIGHT
+       bool
+       default y
+diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
+index 549cb32..3e53ad7 100644
+--- a/arch/arm/mach-exynos/Kconfig
++++ b/arch/arm/mach-exynos/Kconfig
+@@ -17,6 +17,7 @@ config ARCH_EXYNOS4
+       select HAVE_ARM_SCU if SMP
+       select HAVE_SMP
+       select MIGHT_HAVE_CACHE_L2X0
++      select ARCH_HAS_BANDGAP
+       help
+         Samsung EXYNOS4 SoCs based systems
+@@ -24,6 +25,7 @@ config ARCH_EXYNOS5
+       bool "SAMSUNG EXYNOS5"
+       select HAVE_ARM_SCU if SMP
+       select HAVE_SMP
++      select ARCH_HAS_BANDGAP
+       help
+         Samsung EXYNOS5 (Cortex-A15) SoC based systems
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0998-thermal-EXYNOS-always-register-TMU-driver-with-core-.patch b/patches.tizen/0998-thermal-EXYNOS-always-register-TMU-driver-with-core-.patch
new file mode 100644 (file)
index 0000000..6e0b268
--- /dev/null
@@ -0,0 +1,79 @@
+From d818f3e406067ff54faa4e75bbed8419e67921d2 Mon Sep 17 00:00:00 2001
+From: Bartlomiej Zolnierkiewicz <b.zolniekie@samsung.com>
+Date: Mon, 4 Nov 2013 15:48:45 +0900
+Subject: [PATCH 0998/1302] thermal: EXYNOS: always register TMU driver with
+ core thermal framework
+
+There is little sense in having separate config option for
+registering EXYNOS TMU driver with the core thermal framework.
+Fix it by integrating EXYNOS_THERMAL_CORE config option with
+EXYNOS_THERMAL one.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/Kconfig                 | 14 +++-----------
+ drivers/thermal/samsung/Makefile                |  2 +-
+ drivers/thermal/samsung/exynos_thermal_common.h | 12 ------------
+ 3 files changed, 4 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/thermal/samsung/Kconfig b/drivers/thermal/samsung/Kconfig
+index f760389..04eabee 100644
+--- a/drivers/thermal/samsung/Kconfig
++++ b/drivers/thermal/samsung/Kconfig
+@@ -5,14 +5,6 @@ config EXYNOS_THERMAL
+         If you say yes here you get support for the TMU (Thermal Management
+         Unit) driver for SAMSUNG EXYNOS series of SoCs. This driver initialises
+         the TMU, reports temperature and handles cooling action if defined.
+-        This driver uses the Exynos core thermal APIs and TMU configuration
+-        data from the supported SoCs.
+-
+-config EXYNOS_THERMAL_CORE
+-      bool "Core thermal framework support for EXYNOS SOCs"
+-      depends on EXYNOS_THERMAL
+-      help
+-        If you say yes here you get support for EXYNOS TMU
+-        (Thermal Management Unit) common registration/unregistration
+-        functions to the core thermal layer and also to use the generic
+-        CPU cooling APIs.
++        This driver uses the Exynos core thermal APIs, TMU configuration data
++        from the supported SoCs, common registration/unregistration functions
++        to the core thermal layer and also the generic CPU cooling APIs.
+diff --git a/drivers/thermal/samsung/Makefile b/drivers/thermal/samsung/Makefile
+index c09d830..a829107 100644
+--- a/drivers/thermal/samsung/Makefile
++++ b/drivers/thermal/samsung/Makefile
+@@ -4,4 +4,4 @@
+ obj-$(CONFIG_EXYNOS_THERMAL)                  += exynos_thermal.o
+ exynos_thermal-y                              := exynos_tmu.o
+ exynos_thermal-y                              += exynos_tmu_data.o
+-exynos_thermal-$(CONFIG_EXYNOS_THERMAL_CORE)  += exynos_thermal_common.o
++exynos_thermal-y                              += exynos_thermal_common.o
+diff --git a/drivers/thermal/samsung/exynos_thermal_common.h b/drivers/thermal/samsung/exynos_thermal_common.h
+index 3eb2ed9..8681679 100644
+--- a/drivers/thermal/samsung/exynos_thermal_common.h
++++ b/drivers/thermal/samsung/exynos_thermal_common.h
+@@ -88,20 +88,8 @@ struct thermal_sensor_conf {
+       struct device *dev;
+ };
+-/*Functions used exynos based thermal sensor driver*/
+-#ifdef CONFIG_EXYNOS_THERMAL_CORE
+ void exynos_unregister_thermal(struct thermal_sensor_conf *sensor_conf);
+ int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf);
+ void exynos_report_trigger(struct thermal_sensor_conf *sensor_conf);
+-#else
+-static inline void
+-exynos_unregister_thermal(struct thermal_sensor_conf *sensor_conf) { return; }
+-static inline int
+-exynos_register_thermal(struct thermal_sensor_conf *sensor_conf) { return 0; }
+-
+-static inline void
+-exynos_report_trigger(struct thermal_sensor_conf *sensor_conf) { return; }
+-
+-#endif /* CONFIG_EXYNOS_THERMAL_CORE */
+ #endif /* _EXYNOS_THERMAL_COMMON_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/0999-thermal-exynos-Set-MUX-bits-in-tmu-s-control-registe.patch b/patches.tizen/0999-thermal-exynos-Set-MUX-bits-in-tmu-s-control-registe.patch
new file mode 100644 (file)
index 0000000..53b2402
--- /dev/null
@@ -0,0 +1,55 @@
+From 1c0b05d076f242e5ce62ba9275653beed73f52b5 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Mon, 4 Nov 2013 14:23:22 +0900
+Subject: [PATCH 0999/1302] thermal: exynos: Set MUX bits in tmu's control
+ register to work correctly.
+
+Exynos 4x12 and 5250 need that MUX bits in control register is set to be
+certain value at reset. Otherwise it'll reflect improper data when we
+read current sensor's value. For other Exynos series, it doesn't need.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_tmu.c      | 10 ++++++++++
+ drivers/thermal/samsung/exynos_tmu_data.h |  3 +++
+ 2 files changed, 13 insertions(+)
+
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+index b43afda..fa6631a 100644
+--- a/drivers/thermal/samsung/exynos_tmu.c
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -322,6 +322,16 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on)
+               con |= pdata->reference_voltage << reg->buf_vref_sel_shift;
+       }
++      /*
++       * In Exynos 4x12 and 5250,
++       * MUX bits should be set to 0x6 for normal operation.
++       * For ohters, it can be ignored.
++       */
++      if (pdata->type == SOC_ARCH_EXYNOS) {
++              con &= ~(EXYNOS_TMU_MUX_ADDR_MASK << EXYNOS_TMU_MUX_ADDR_SHIFT);
++              con |= EXYNOS_TMU_MUX_ADDR_DEFAULT << EXYNOS_TMU_MUX_ADDR_SHIFT;
++      }
++
+       if (pdata->gain) {
+               con &= ~(reg->buf_slope_sel_mask << reg->buf_slope_sel_shift);
+               con |= (pdata->gain << reg->buf_slope_sel_shift);
+diff --git a/drivers/thermal/samsung/exynos_tmu_data.h b/drivers/thermal/samsung/exynos_tmu_data.h
+index dc7feb5..2144eaf 100644
+--- a/drivers/thermal/samsung/exynos_tmu_data.h
++++ b/drivers/thermal/samsung/exynos_tmu_data.h
+@@ -35,6 +35,9 @@
+ #define EXYNOS_TMU_TEMP_MASK          0xff
+ #define EXYNOS_TMU_REF_VOLTAGE_SHIFT  24
+ #define EXYNOS_TMU_REF_VOLTAGE_MASK   0x1f
++#define EXYNOS_TMU_MUX_ADDR_DEFAULT   0x6
++#define EXYNOS_TMU_MUX_ADDR_MASK      0x7
++#define EXYNOS_TMU_MUX_ADDR_SHIFT     20
+ #define EXYNOS_TMU_BUF_SLOPE_SEL_MASK 0xf
+ #define EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT        8
+ #define EXYNOS_TMU_CORE_EN_SHIFT      0
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1000-Revert-thermal-exynos-Set-MUX-bits-in-tmu-s-control-.patch b/patches.tizen/1000-Revert-thermal-exynos-Set-MUX-bits-in-tmu-s-control-.patch
new file mode 100644 (file)
index 0000000..398bdee
--- /dev/null
@@ -0,0 +1,55 @@
+From b06aa43792f87bf3c301669d8d4b332f364bf616 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Mon, 4 Nov 2013 16:12:26 +0900
+Subject: [PATCH 1000/1302] Revert "thermal: exynos: Set MUX bits in tmu's
+ control register to work correctly."
+
+This reverts commit e612d47f36eb9eb90ee88fd11addfe5aac8cdae4.
+This will be suppported later with Lukasz's pathches.
+
+Signed-off-by : Jonghwa Lee <jonghwa3.lee@samsung.com>
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_tmu.c      | 10 ----------
+ drivers/thermal/samsung/exynos_tmu_data.h |  3 ---
+ 2 files changed, 13 deletions(-)
+
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+index fa6631a..b43afda 100644
+--- a/drivers/thermal/samsung/exynos_tmu.c
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -322,16 +322,6 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on)
+               con |= pdata->reference_voltage << reg->buf_vref_sel_shift;
+       }
+-      /*
+-       * In Exynos 4x12 and 5250,
+-       * MUX bits should be set to 0x6 for normal operation.
+-       * For ohters, it can be ignored.
+-       */
+-      if (pdata->type == SOC_ARCH_EXYNOS) {
+-              con &= ~(EXYNOS_TMU_MUX_ADDR_MASK << EXYNOS_TMU_MUX_ADDR_SHIFT);
+-              con |= EXYNOS_TMU_MUX_ADDR_DEFAULT << EXYNOS_TMU_MUX_ADDR_SHIFT;
+-      }
+-
+       if (pdata->gain) {
+               con &= ~(reg->buf_slope_sel_mask << reg->buf_slope_sel_shift);
+               con |= (pdata->gain << reg->buf_slope_sel_shift);
+diff --git a/drivers/thermal/samsung/exynos_tmu_data.h b/drivers/thermal/samsung/exynos_tmu_data.h
+index 2144eaf..dc7feb5 100644
+--- a/drivers/thermal/samsung/exynos_tmu_data.h
++++ b/drivers/thermal/samsung/exynos_tmu_data.h
+@@ -35,9 +35,6 @@
+ #define EXYNOS_TMU_TEMP_MASK          0xff
+ #define EXYNOS_TMU_REF_VOLTAGE_SHIFT  24
+ #define EXYNOS_TMU_REF_VOLTAGE_MASK   0x1f
+-#define EXYNOS_TMU_MUX_ADDR_DEFAULT   0x6
+-#define EXYNOS_TMU_MUX_ADDR_MASK      0x7
+-#define EXYNOS_TMU_MUX_ADDR_SHIFT     20
+ #define EXYNOS_TMU_BUF_SLOPE_SEL_MASK 0xf
+ #define EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT        8
+ #define EXYNOS_TMU_CORE_EN_SHIFT      0
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1001-thermal-exynos-Remove-check-for-thermal-device-point.patch b/patches.tizen/1001-thermal-exynos-Remove-check-for-thermal-device-point.patch
new file mode 100644 (file)
index 0000000..953b71f
--- /dev/null
@@ -0,0 +1,45 @@
+From 37ba7f3055a207b7a8dca272a2f7b915409e7b13 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Wed, 9 Oct 2013 08:29:50 +0200
+Subject: [PATCH 1001/1302] thermal: exynos: Remove check for thermal device
+ pointer at exynos_report_trigger()
+
+The commit 4de0bdaa9677d11406c9becb70c60887c957e1f0
+("thermal: exynos: Add support for instance based register/unregister")
+broke check for presence of therm_dev at global thermal zone in
+exynos_report_trigger().
+
+The resulting wrong test prevents thermal_zone_device_update() call, which
+calls handlers for situation when trip points are passed.
+Such behavior prevents thermal driver from proper reaction (when TMU interrupt
+is raised) in a situation when overheating is detected at TMU hardware.
+
+It turns out, that after exynos thermal subsystem redesign (at v3.12) this
+check is not needed, since it is not possible to register thermal zone
+without valid thermal device.
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Reviewed-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
+Reviewed-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_thermal_common.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c
+index f10a6ad..c2301da 100644
+--- a/drivers/thermal/samsung/exynos_thermal_common.c
++++ b/drivers/thermal/samsung/exynos_thermal_common.c
+@@ -310,8 +310,6 @@ void exynos_report_trigger(struct thermal_sensor_conf *conf)
+       }
+       th_zone = conf->pzone_data;
+-      if (th_zone->therm_dev)
+-              return;
+       if (th_zone->bind == false) {
+               for (i = 0; i < th_zone->cool_dev_size; i++) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1002-thermal-exynos-Provide-separate-TMU-data-for-Exynos4.patch b/patches.tizen/1002-thermal-exynos-Provide-separate-TMU-data-for-Exynos4.patch
new file mode 100644 (file)
index 0000000..0f26dc1
--- /dev/null
@@ -0,0 +1,152 @@
+From 8d12c3982c11e89b65a08ae84606deea0f0fc5cf Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Wed, 9 Oct 2013 08:29:51 +0200
+Subject: [PATCH 1002/1302] thermal: exynos: Provide separate TMU data for
+ Exynos4412
+
+Up till now Exynos5250 and Exynos4412 had the same definitions for TMU
+data. Following commit changes that, by introducing separate
+exynos4412_default_tmu_data structure.
+
+Since Exynos4412 was chronologically first, the corresponding name for
+TMU registers and default data was renamed.
+
+Additionally, new SOC_ARCH_EXYNOS4412 type has been defined.
+
+Moreover, the SOC_ARCH_EXYNOS name has been changed to SOC_ARCH_EXYNOS5250.
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Reviewed-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
+Reviewed-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_tmu.c      |  9 +++++----
+ drivers/thermal/samsung/exynos_tmu.h      |  3 ++-
+ drivers/thermal/samsung/exynos_tmu_data.c | 28 ++++++++++++++++++++++------
+ drivers/thermal/samsung/exynos_tmu_data.h |  9 ++++++++-
+ 4 files changed, 37 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+index b43afda..1312b34 100644
+--- a/drivers/thermal/samsung/exynos_tmu.c
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -488,7 +488,7 @@ static const struct of_device_id exynos_tmu_match[] = {
+       },
+       {
+               .compatible = "samsung,exynos4412-tmu",
+-              .data = (void *)EXYNOS5250_TMU_DRV_DATA,
++              .data = (void *)EXYNOS4412_TMU_DRV_DATA,
+       },
+       {
+               .compatible = "samsung,exynos5250-tmu",
+@@ -629,9 +629,10 @@ static int exynos_tmu_probe(struct platform_device *pdev)
+       if (ret)
+               return ret;
+-      if (pdata->type == SOC_ARCH_EXYNOS ||
+-              pdata->type == SOC_ARCH_EXYNOS4210 ||
+-                              pdata->type == SOC_ARCH_EXYNOS5440)
++      if (pdata->type == SOC_ARCH_EXYNOS4210 ||
++          pdata->type == SOC_ARCH_EXYNOS4412 ||
++          pdata->type == SOC_ARCH_EXYNOS5250 ||
++          pdata->type == SOC_ARCH_EXYNOS5440)
+               data->soc = pdata->type;
+       else {
+               ret = -EINVAL;
+diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h
+index b364c9e..b42ece4 100644
+--- a/drivers/thermal/samsung/exynos_tmu.h
++++ b/drivers/thermal/samsung/exynos_tmu.h
+@@ -41,7 +41,8 @@ enum calibration_mode {
+ enum soc_type {
+       SOC_ARCH_EXYNOS4210 = 1,
+-      SOC_ARCH_EXYNOS,
++      SOC_ARCH_EXYNOS4412,
++      SOC_ARCH_EXYNOS5250,
+       SOC_ARCH_EXYNOS5440,
+ };
+diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c
+index 9002499..d8de5c1 100644
+--- a/drivers/thermal/samsung/exynos_tmu_data.c
++++ b/drivers/thermal/samsung/exynos_tmu_data.c
+@@ -90,8 +90,8 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = {
+ };
+ #endif
+-#if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412)
+-static const struct exynos_tmu_registers exynos5250_tmu_registers = {
++#if defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250)
++static const struct exynos_tmu_registers exynos4412_tmu_registers = {
+       .triminfo_data = EXYNOS_TMU_REG_TRIMINFO,
+       .triminfo_25_shift = EXYNOS_TRIMINFO_25_SHIFT,
+       .triminfo_85_shift = EXYNOS_TRIMINFO_85_SHIFT,
+@@ -128,7 +128,7 @@ static const struct exynos_tmu_registers exynos5250_tmu_registers = {
+       .emul_time_mask = EXYNOS_EMUL_TIME_MASK,
+ };
+-#define EXYNOS5250_TMU_DATA \
++#define EXYNOS4412_TMU_DATA \
+       .threshold_falling = 10, \
+       .trigger_levels[0] = 85, \
+       .trigger_levels[1] = 103, \
+@@ -162,15 +162,31 @@ static const struct exynos_tmu_registers exynos5250_tmu_registers = {
+               .temp_level = 103, \
+       }, \
+       .freq_tab_count = 2, \
+-      .type = SOC_ARCH_EXYNOS, \
+-      .registers = &exynos5250_tmu_registers, \
++      .registers = &exynos4412_tmu_registers, \
+       .features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_TRIM_RELOAD | \
+                       TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_READY_STATUS | \
+                       TMU_SUPPORT_EMUL_TIME)
++#endif
++#if defined(CONFIG_SOC_EXYNOS4412)
++struct exynos_tmu_init_data const exynos4412_default_tmu_data = {
++      .tmu_data = {
++              {
++                      EXYNOS4412_TMU_DATA,
++                      .type = SOC_ARCH_EXYNOS4412,
++              },
++      },
++      .tmu_count = 1,
++};
++#endif
++
++#if defined(CONFIG_SOC_EXYNOS5250)
+ struct exynos_tmu_init_data const exynos5250_default_tmu_data = {
+       .tmu_data = {
+-              { EXYNOS5250_TMU_DATA },
++              {
++                      EXYNOS4412_TMU_DATA,
++                      .type = SOC_ARCH_EXYNOS5250,
++              },
+       },
+       .tmu_count = 1,
+ };
+diff --git a/drivers/thermal/samsung/exynos_tmu_data.h b/drivers/thermal/samsung/exynos_tmu_data.h
+index dc7feb5..b130b1e 100644
+--- a/drivers/thermal/samsung/exynos_tmu_data.h
++++ b/drivers/thermal/samsung/exynos_tmu_data.h
+@@ -138,7 +138,14 @@ extern struct exynos_tmu_init_data const exynos4210_default_tmu_data;
+ #define EXYNOS4210_TMU_DRV_DATA (NULL)
+ #endif
+-#if (defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412))
++#if defined(CONFIG_SOC_EXYNOS4412)
++extern struct exynos_tmu_init_data const exynos4412_default_tmu_data;
++#define EXYNOS4412_TMU_DRV_DATA (&exynos4412_default_tmu_data)
++#else
++#define EXYNOS4412_TMU_DRV_DATA (NULL)
++#endif
++
++#if defined(CONFIG_SOC_EXYNOS5250)
+ extern struct exynos_tmu_init_data const exynos5250_default_tmu_data;
+ #define EXYNOS5250_TMU_DRV_DATA (&exynos5250_default_tmu_data)
+ #else
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1003-thermal-exynos-Provide-initial-setting-for-TMU-s-tes.patch b/patches.tizen/1003-thermal-exynos-Provide-initial-setting-for-TMU-s-tes.patch
new file mode 100644 (file)
index 0000000..b130775
--- /dev/null
@@ -0,0 +1,114 @@
+From 79d0d71df4df46c58308b31f18f2d0a0fecd3d05 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Wed, 9 Oct 2013 08:29:52 +0200
+Subject: [PATCH 1003/1302] thermal: exynos: Provide initial setting for TMU's
+ test MUX address at Exynos4412
+
+The commit d0a0ce3e77c795258d47f9163e92d5031d0c5221 ("thermal: exynos: Add
+missing definations and code cleanup") has removed setting of test MUX address
+value at TMU configuration setting.
+
+This field is not present on Exynos4210 and Exynos5 SoCs. However on Exynos4412
+SoC it is required to set this field after reset because without it TMU shows
+maximal available temperature, which causes immediate platform shutdown.
+
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Reviewed-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
+Reviewed-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/thermal/samsung/exynos_tmu.c      | 3 +++
+ drivers/thermal/samsung/exynos_tmu.h      | 4 ++++
+ drivers/thermal/samsung/exynos_tmu_data.c | 2 ++
+ drivers/thermal/samsung/exynos_tmu_data.h | 4 ++++
+ 4 files changed, 13 insertions(+)
+
+diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
+index 1312b34..32f38b9 100644
+--- a/drivers/thermal/samsung/exynos_tmu.c
++++ b/drivers/thermal/samsung/exynos_tmu.c
+@@ -317,6 +317,9 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on)
+       con = readl(data->base + reg->tmu_ctrl);
++      if (pdata->test_mux)
++              con |= (pdata->test_mux << reg->test_mux_addr_shift);
++
+       if (pdata->reference_voltage) {
+               con &= ~(reg->buf_vref_sel_mask << reg->buf_vref_sel_shift);
+               con |= pdata->reference_voltage << reg->buf_vref_sel_shift;
+diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h
+index b42ece4..3fb6554 100644
+--- a/drivers/thermal/samsung/exynos_tmu.h
++++ b/drivers/thermal/samsung/exynos_tmu.h
+@@ -85,6 +85,7 @@ enum soc_type {
+  * @triminfo_reload_shift: shift of triminfo reload enable bit in triminfo_ctrl
+       reg.
+  * @tmu_ctrl: TMU main controller register.
++ * @test_mux_addr_shift: shift bits of test mux address.
+  * @buf_vref_sel_shift: shift bits of reference voltage in tmu_ctrl register.
+  * @buf_vref_sel_mask: mask bits of reference voltage in tmu_ctrl register.
+  * @therm_trip_mode_shift: shift bits of tripping mode in tmu_ctrl register.
+@@ -151,6 +152,7 @@ struct exynos_tmu_registers {
+       u32     triminfo_reload_shift;
+       u32     tmu_ctrl;
++      u32     test_mux_addr_shift;
+       u32     buf_vref_sel_shift;
+       u32     buf_vref_sel_mask;
+       u32     therm_trip_mode_shift;
+@@ -258,6 +260,7 @@ struct exynos_tmu_registers {
+  * @first_point_trim: temp value of the first point trimming
+  * @second_point_trim: temp value of the second point trimming
+  * @default_temp_offset: default temperature offset in case of no trimming
++ * @test_mux; information if SoC supports test MUX
+  * @cal_type: calibration type for temperature
+  * @cal_mode: calibration mode for temperature
+  * @freq_clip_table: Table representing frequency reduction percentage.
+@@ -287,6 +290,7 @@ struct exynos_tmu_platform_data {
+       u8 first_point_trim;
+       u8 second_point_trim;
+       u8 default_temp_offset;
++      u8 test_mux;
+       enum calibration_type cal_type;
+       enum calibration_mode cal_mode;
+diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c
+index d8de5c1..073c292 100644
+--- a/drivers/thermal/samsung/exynos_tmu_data.c
++++ b/drivers/thermal/samsung/exynos_tmu_data.c
+@@ -98,6 +98,7 @@ static const struct exynos_tmu_registers exynos4412_tmu_registers = {
+       .triminfo_ctrl = EXYNOS_TMU_TRIMINFO_CON,
+       .triminfo_reload_shift = EXYNOS_TRIMINFO_RELOAD_SHIFT,
+       .tmu_ctrl = EXYNOS_TMU_REG_CONTROL,
++      .test_mux_addr_shift = EXYNOS4412_MUX_ADDR_SHIFT,
+       .buf_vref_sel_shift = EXYNOS_TMU_REF_VOLTAGE_SHIFT,
+       .buf_vref_sel_mask = EXYNOS_TMU_REF_VOLTAGE_MASK,
+       .therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT,
+@@ -174,6 +175,7 @@ struct exynos_tmu_init_data const exynos4412_default_tmu_data = {
+               {
+                       EXYNOS4412_TMU_DATA,
+                       .type = SOC_ARCH_EXYNOS4412,
++                      .test_mux = EXYNOS4412_MUX_ADDR_VALUE,
+               },
+       },
+       .tmu_count = 1,
+diff --git a/drivers/thermal/samsung/exynos_tmu_data.h b/drivers/thermal/samsung/exynos_tmu_data.h
+index b130b1e..a1ea19d 100644
+--- a/drivers/thermal/samsung/exynos_tmu_data.h
++++ b/drivers/thermal/samsung/exynos_tmu_data.h
+@@ -95,6 +95,10 @@
+ #define EXYNOS_MAX_TRIGGER_PER_REG    4
++/* Exynos4412 specific */
++#define EXYNOS4412_MUX_ADDR_VALUE          6
++#define EXYNOS4412_MUX_ADDR_SHIFT          20
++
+ /*exynos5440 specific registers*/
+ #define EXYNOS5440_TMU_S0_7_TRIM              0x000
+ #define EXYNOS5440_TMU_S0_7_CTRL              0x020
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1004-pwm-devm-alloc-correct-pointer-size.patch b/patches.tizen/1004-pwm-devm-alloc-correct-pointer-size.patch
new file mode 100644 (file)
index 0000000..ce1d4f4
--- /dev/null
@@ -0,0 +1,41 @@
+From fe6649e2f44e0e7b88c8aa364bfc69de02cbb971 Mon Sep 17 00:00:00 2001
+From: Wolfram Sang <wsa@the-dreams.de>
+Date: Mon, 3 Jun 2013 22:27:17 +0200
+Subject: [PATCH 1004/1302] pwm: devm: alloc correct pointer size
+
+The allocated object should be the size of what the pointer is pointing
+to and not the size of the pointer itself.
+
+Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/pwm/core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
+index 32221cb..0cf0f65 100644
+--- a/drivers/pwm/core.c
++++ b/drivers/pwm/core.c
+@@ -694,7 +694,7 @@ struct pwm_device *devm_pwm_get(struct device *dev, const char *con_id)
+ {
+       struct pwm_device **ptr, *pwm;
+-      ptr = devres_alloc(devm_pwm_release, sizeof(**ptr), GFP_KERNEL);
++      ptr = devres_alloc(devm_pwm_release, sizeof(*ptr), GFP_KERNEL);
+       if (!ptr)
+               return ERR_PTR(-ENOMEM);
+@@ -724,7 +724,7 @@ struct pwm_device *devm_of_pwm_get(struct device *dev, struct device_node *np,
+ {
+       struct pwm_device **ptr, *pwm;
+-      ptr = devres_alloc(devm_pwm_release, sizeof(**ptr), GFP_KERNEL);
++      ptr = devres_alloc(devm_pwm_release, sizeof(*ptr), GFP_KERNEL);
+       if (!ptr)
+               return ERR_PTR(-ENOMEM);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1005-pwm-Add-sysfs-interface.patch b/patches.tizen/1005-pwm-Add-sysfs-interface.patch
new file mode 100644 (file)
index 0000000..d9ecae8
--- /dev/null
@@ -0,0 +1,684 @@
+From ee90e61ec1c5957c5282d5587f10a3acb110ffc4 Mon Sep 17 00:00:00 2001
+From: H Hartley Sweeten <hartleys@visionengravers.com>
+Date: Tue, 11 Jun 2013 10:38:59 -0700
+Subject: [PATCH 1005/1302] pwm: Add sysfs interface
+
+Add a simple sysfs interface to the generic PWM framework.
+
+  /sys/class/pwm/
+  `-- pwmchipN/           for each PWM chip
+      |-- export          (w/o) ask the kernel to export a PWM channel
+      |-- npwm            (r/o) number of PWM channels in this PWM chip
+      |-- pwmX/           for each exported PWM channel
+      |   |-- duty_cycle  (r/w) duty cycle (in nanoseconds)
+      |   |-- enable      (r/w) enable/disable PWM
+      |   |-- period      (r/w) period (in nanoseconds)
+      |   `-- polarity    (r/w) polarity of PWM (normal/inversed)
+      `-- unexport        (w/o) return a PWM channel to the kernel
+
+Based on work by Lars Poeschel.
+
+Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
+Cc: Thierry Reding <thierry.reding@gmail.com>
+Cc: Lars Poeschel <poeschel@lemonage.de>
+Cc: Ryan Mallon <rmallon@gmail.com>
+Cc: Rob Landley <rob@landley.net>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/ABI/testing/sysfs-class-pwm |  79 +++++++
+ Documentation/pwm.txt                     |  37 ++++
+ drivers/pwm/Kconfig                       |   4 +
+ drivers/pwm/Makefile                      |   1 +
+ drivers/pwm/core.c                        |  25 ++-
+ drivers/pwm/sysfs.c                       | 352 ++++++++++++++++++++++++++++++
+ include/linux/pwm.h                       |  29 ++-
+ 7 files changed, 524 insertions(+), 3 deletions(-)
+ create mode 100644 Documentation/ABI/testing/sysfs-class-pwm
+ create mode 100644 drivers/pwm/sysfs.c
+
+diff --git a/Documentation/ABI/testing/sysfs-class-pwm b/Documentation/ABI/testing/sysfs-class-pwm
+new file mode 100644
+index 0000000..c479d77
+--- /dev/null
++++ b/Documentation/ABI/testing/sysfs-class-pwm
+@@ -0,0 +1,79 @@
++What:         /sys/class/pwm/
++Date:         May 2013
++KernelVersion:        3.11
++Contact:      H Hartley Sweeten <hsweeten@visionengravers.com>
++Description:
++              The pwm/ class sub-directory belongs to the Generic PWM
++              Framework and provides a sysfs interface for using PWM
++              channels.
++
++What:         /sys/class/pwm/pwmchipN/
++Date:         May 2013
++KernelVersion:        3.11
++Contact:      H Hartley Sweeten <hsweeten@visionengravers.com>
++Description:
++              A /sys/class/pwm/pwmchipN directory is created for each
++              probed PWM controller/chip where N is the base of the
++              PWM chip.
++
++What:         /sys/class/pwm/pwmchipN/npwm
++Date:         May 2013
++KernelVersion:        3.11
++Contact:      H Hartley Sweeten <hsweeten@visionengravers.com>
++Description:
++              The number of PWM channels supported by the PWM chip.
++
++What:         /sys/class/pwm/pwmchipN/export
++Date:         May 2013
++KernelVersion:        3.11
++Contact:      H Hartley Sweeten <hsweeten@visionengravers.com>
++Description:
++              Exports a PWM channel from the PWM chip for sysfs control.
++              Value is between 0 and /sys/class/pwm/pwmchipN/npwm - 1.
++
++What:         /sys/class/pwm/pwmchipN/unexport
++Date:         May 2013
++KernelVersion:        3.11
++Contact:      H Hartley Sweeten <hsweeten@visionengravers.com>
++Description:
++              Unexports a PWM channel.
++
++What:         /sys/class/pwm/pwmchipN/pwmX
++Date:         May 2013
++KernelVersion:        3.11
++Contact:      H Hartley Sweeten <hsweeten@visionengravers.com>
++Description:
++              A /sys/class/pwm/pwmchipN/pwmX directory is created for
++              each exported PWM channel where X is the exported PWM
++              channel number.
++
++What:         /sys/class/pwm/pwmchipN/pwmX/period
++Date:         May 2013
++KernelVersion:        3.11
++Contact:      H Hartley Sweeten <hsweeten@visionengravers.com>
++Description:
++              Sets the PWM signal period in nanoseconds.
++
++What:         /sys/class/pwm/pwmchipN/pwmX/duty_cycle
++Date:         May 2013
++KernelVersion:        3.11
++Contact:      H Hartley Sweeten <hsweeten@visionengravers.com>
++Description:
++              Sets the PWM signal duty cycle in nanoseconds.
++
++What:         /sys/class/pwm/pwmchipN/pwmX/polarity
++Date:         May 2013
++KernelVersion:        3.11
++Contact:      H Hartley Sweeten <hsweeten@visionengravers.com>
++Description:
++              Sets the output polarity of the PWM signal to "normal" or
++              "inversed".
++
++What:         /sys/class/pwm/pwmchipN/pwmX/enable
++Date:         May 2013
++KernelVersion:        3.11
++Contact:      H Hartley Sweeten <hsweeten@visionengravers.com>
++Description:
++              Enable/disable the PWM signal.
++              0 is disabled
++              1 is enabled
+diff --git a/Documentation/pwm.txt b/Documentation/pwm.txt
+index 7d2b4c9..1039b68 100644
+--- a/Documentation/pwm.txt
++++ b/Documentation/pwm.txt
+@@ -45,6 +45,43 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns);
+ To start/stop toggling the PWM output use pwm_enable()/pwm_disable().
++Using PWMs with the sysfs interface
++-----------------------------------
++
++If CONFIG_SYSFS is enabled in your kernel configuration a simple sysfs
++interface is provided to use the PWMs from userspace. It is exposed at
++/sys/class/pwm/. Each probed PWM controller/chip will be exported as
++pwmchipN, where N is the base of the PWM chip. Inside the directory you
++will find:
++
++npwm - The number of PWM channels this chip supports (read-only).
++
++export - Exports a PWM channel for use with sysfs (write-only).
++
++unexport - Unexports a PWM channel from sysfs (write-only).
++
++The PWM channels are numbered using a per-chip index from 0 to npwm-1.
++
++When a PWM channel is exported a pwmX directory will be created in the
++pwmchipN directory it is associated with, where X is the number of the
++channel that was exported. The following properties will then be available:
++
++period - The total period of the PWM signal (read/write).
++      Value is in nanoseconds and is the sum of the active and inactive
++      time of the PWM.
++
++duty_cycle - The active time of the PWM signal (read/write).
++      Value is in nanoseconds and must be less than the period.
++
++polarity - Changes the polarity of the PWM signal (read/write).
++      Writes to this property only work if the PWM chip supports changing
++      the polarity. The polarity can only be changed if the PWM is not
++      enabled. Value is the string "normal" or "inversed".
++
++enable - Enable/disable the PWM signal (read/write).
++      0 - disabled
++      1 - enabled
++
+ Implementing a PWM driver
+ -------------------------
+diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
+index 115b644..43cd255 100644
+--- a/drivers/pwm/Kconfig
++++ b/drivers/pwm/Kconfig
+@@ -28,6 +28,10 @@ menuconfig PWM
+ if PWM
++config PWM_SYSFS
++      bool
++      default y if SYSFS
++
+ config PWM_AB8500
+       tristate "AB8500 PWM support"
+       depends on AB8500_CORE && ARCH_U8500
+diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
+index 94ba21e..a025439 100644
+--- a/drivers/pwm/Makefile
++++ b/drivers/pwm/Makefile
+@@ -1,4 +1,5 @@
+ obj-$(CONFIG_PWM)             += core.o
++obj-$(CONFIG_PWM_SYSFS)               += sysfs.o
+ obj-$(CONFIG_PWM_AB8500)      += pwm-ab8500.o
+ obj-$(CONFIG_PWM_ATMEL_TCB)   += pwm-atmel-tcb.o
+ obj-$(CONFIG_PWM_BFIN)                += pwm-bfin.o
+diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
+index 0cf0f65..dfbfbc5 100644
+--- a/drivers/pwm/core.c
++++ b/drivers/pwm/core.c
+@@ -274,6 +274,8 @@ int pwmchip_add(struct pwm_chip *chip)
+       if (IS_ENABLED(CONFIG_OF))
+               of_pwmchip_add(chip);
++      pwmchip_sysfs_export(chip);
++
+ out:
+       mutex_unlock(&pwm_lock);
+       return ret;
+@@ -310,6 +312,8 @@ int pwmchip_remove(struct pwm_chip *chip)
+       free_pwms(chip);
++      pwmchip_sysfs_unexport(chip);
++
+ out:
+       mutex_unlock(&pwm_lock);
+       return ret;
+@@ -402,10 +406,19 @@ EXPORT_SYMBOL_GPL(pwm_free);
+  */
+ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+ {
++      int err;
++
+       if (!pwm || duty_ns < 0 || period_ns <= 0 || duty_ns > period_ns)
+               return -EINVAL;
+-      return pwm->chip->ops->config(pwm->chip, pwm, duty_ns, period_ns);
++      err = pwm->chip->ops->config(pwm->chip, pwm, duty_ns, period_ns);
++      if (err)
++              return err;
++
++      pwm->duty_cycle = duty_ns;
++      pwm->period = period_ns;
++
++      return 0;
+ }
+ EXPORT_SYMBOL_GPL(pwm_config);
+@@ -418,6 +431,8 @@ EXPORT_SYMBOL_GPL(pwm_config);
+  */
+ int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)
+ {
++      int err;
++
+       if (!pwm || !pwm->chip->ops)
+               return -EINVAL;
+@@ -427,7 +442,13 @@ int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)
+       if (test_bit(PWMF_ENABLED, &pwm->flags))
+               return -EBUSY;
+-      return pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity);
++      err = pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity);
++      if (err)
++              return err;
++
++      pwm->polarity = polarity;
++
++      return 0;
+ }
+ EXPORT_SYMBOL_GPL(pwm_set_polarity);
+diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c
+new file mode 100644
+index 0000000..8ca5de3
+--- /dev/null
++++ b/drivers/pwm/sysfs.c
+@@ -0,0 +1,352 @@
++/*
++ * A simple sysfs interface for the generic PWM framework
++ *
++ * Copyright (C) 2013 H Hartley Sweeten <hsweeten@visionengravers.com>
++ *
++ * Based on previous work by Lars Poeschel <poeschel@lemonage.de>
++ *
++ * 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, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ */
++
++#include <linux/device.h>
++#include <linux/mutex.h>
++#include <linux/err.h>
++#include <linux/slab.h>
++#include <linux/kdev_t.h>
++#include <linux/pwm.h>
++
++struct pwm_export {
++      struct device child;
++      struct pwm_device *pwm;
++};
++
++static struct pwm_export *child_to_pwm_export(struct device *child)
++{
++      return container_of(child, struct pwm_export, child);
++}
++
++static struct pwm_device *child_to_pwm_device(struct device *child)
++{
++      struct pwm_export *export = child_to_pwm_export(child);
++
++      return export->pwm;
++}
++
++static ssize_t pwm_period_show(struct device *child,
++                             struct device_attribute *attr,
++                             char *buf)
++{
++      const struct pwm_device *pwm = child_to_pwm_device(child);
++
++      return sprintf(buf, "%u\n", pwm->period);
++}
++
++static ssize_t pwm_period_store(struct device *child,
++                              struct device_attribute *attr,
++                              const char *buf, size_t size)
++{
++      struct pwm_device *pwm = child_to_pwm_device(child);
++      unsigned int val;
++      int ret;
++
++      ret = kstrtouint(buf, 0, &val);
++      if (ret)
++              return ret;
++
++      ret = pwm_config(pwm, pwm->duty_cycle, val);
++
++      return ret ? : size;
++}
++
++static ssize_t pwm_duty_cycle_show(struct device *child,
++                                 struct device_attribute *attr,
++                                 char *buf)
++{
++      const struct pwm_device *pwm = child_to_pwm_device(child);
++
++      return sprintf(buf, "%u\n", pwm->duty_cycle);
++}
++
++static ssize_t pwm_duty_cycle_store(struct device *child,
++                                  struct device_attribute *attr,
++                                  const char *buf, size_t size)
++{
++      struct pwm_device *pwm = child_to_pwm_device(child);
++      unsigned int val;
++      int ret;
++
++      ret = kstrtouint(buf, 0, &val);
++      if (ret)
++              return ret;
++
++      ret = pwm_config(pwm, val, pwm->period);
++
++      return ret ? : size;
++}
++
++static ssize_t pwm_enable_show(struct device *child,
++                             struct device_attribute *attr,
++                             char *buf)
++{
++      const struct pwm_device *pwm = child_to_pwm_device(child);
++      int enabled = test_bit(PWMF_ENABLED, &pwm->flags);
++
++      return sprintf(buf, "%d\n", enabled);
++}
++
++static ssize_t pwm_enable_store(struct device *child,
++                              struct device_attribute *attr,
++                              const char *buf, size_t size)
++{
++      struct pwm_device *pwm = child_to_pwm_device(child);
++      int val, ret;
++
++      ret = kstrtoint(buf, 0, &val);
++      if (ret)
++              return ret;
++
++      switch (val) {
++      case 0:
++              pwm_disable(pwm);
++              break;
++      case 1:
++              ret = pwm_enable(pwm);
++              break;
++      default:
++              ret = -EINVAL;
++              break;
++      }
++
++      return ret ? : size;
++}
++
++static ssize_t pwm_polarity_show(struct device *child,
++                               struct device_attribute *attr,
++                               char *buf)
++{
++      const struct pwm_device *pwm = child_to_pwm_device(child);
++
++      return sprintf(buf, "%s\n", pwm->polarity ? "inversed" : "normal");
++}
++
++static ssize_t pwm_polarity_store(struct device *child,
++                                struct device_attribute *attr,
++                                const char *buf, size_t size)
++{
++      struct pwm_device *pwm = child_to_pwm_device(child);
++      enum pwm_polarity polarity;
++      int ret;
++
++      if (sysfs_streq(buf, "normal"))
++              polarity = PWM_POLARITY_NORMAL;
++      else if (sysfs_streq(buf, "inversed"))
++              polarity = PWM_POLARITY_INVERSED;
++      else
++              return -EINVAL;
++
++      ret = pwm_set_polarity(pwm, polarity);
++
++      return ret ? : size;
++}
++
++static DEVICE_ATTR(period, 0644, pwm_period_show, pwm_period_store);
++static DEVICE_ATTR(duty_cycle, 0644, pwm_duty_cycle_show, pwm_duty_cycle_store);
++static DEVICE_ATTR(enable, 0644, pwm_enable_show, pwm_enable_store);
++static DEVICE_ATTR(polarity, 0644, pwm_polarity_show, pwm_polarity_store);
++
++static struct attribute *pwm_attrs[] = {
++      &dev_attr_period.attr,
++      &dev_attr_duty_cycle.attr,
++      &dev_attr_enable.attr,
++      &dev_attr_polarity.attr,
++      NULL
++};
++
++static const struct attribute_group pwm_attr_group = {
++      .attrs          = pwm_attrs,
++};
++
++static const struct attribute_group *pwm_attr_groups[] = {
++      &pwm_attr_group,
++      NULL,
++};
++
++static void pwm_export_release(struct device *child)
++{
++      struct pwm_export *export = child_to_pwm_export(child);
++
++      kfree(export);
++}
++
++static int pwm_export_child(struct device *parent, struct pwm_device *pwm)
++{
++      struct pwm_export *export;
++      int ret;
++
++      if (test_and_set_bit(PWMF_EXPORTED, &pwm->flags))
++              return -EBUSY;
++
++      export = kzalloc(sizeof(*export), GFP_KERNEL);
++      if (!export) {
++              clear_bit(PWMF_EXPORTED, &pwm->flags);
++              return -ENOMEM;
++      }
++
++      export->pwm = pwm;
++
++      export->child.release = pwm_export_release;
++      export->child.parent = parent;
++      export->child.devt = MKDEV(0, 0);
++      export->child.groups = pwm_attr_groups;
++      dev_set_name(&export->child, "pwm%u", pwm->hwpwm);
++
++      ret = device_register(&export->child);
++      if (ret) {
++              clear_bit(PWMF_EXPORTED, &pwm->flags);
++              kfree(export);
++              return ret;
++      }
++
++      return 0;
++}
++
++static int pwm_unexport_match(struct device *child, void *data)
++{
++      return child_to_pwm_device(child) == data;
++}
++
++static int pwm_unexport_child(struct device *parent, struct pwm_device *pwm)
++{
++      struct device *child;
++
++      if (!test_and_clear_bit(PWMF_EXPORTED, &pwm->flags))
++              return -ENODEV;
++
++      child = device_find_child(parent, pwm, pwm_unexport_match);
++      if (!child)
++              return -ENODEV;
++
++      /* for device_find_child() */
++      put_device(child);
++      device_unregister(child);
++      pwm_put(pwm);
++
++      return 0;
++}
++
++static ssize_t pwm_export_store(struct device *parent,
++                              struct device_attribute *attr,
++                              const char *buf, size_t len)
++{
++      struct pwm_chip *chip = dev_get_drvdata(parent);
++      struct pwm_device *pwm;
++      unsigned int hwpwm;
++      int ret;
++
++      ret = kstrtouint(buf, 0, &hwpwm);
++      if (ret < 0)
++              return ret;
++
++      if (hwpwm >= chip->npwm)
++              return -ENODEV;
++
++      pwm = pwm_request_from_chip(chip, hwpwm, "sysfs");
++      if (IS_ERR(pwm))
++              return PTR_ERR(pwm);
++
++      ret = pwm_export_child(parent, pwm);
++      if (ret < 0)
++              pwm_put(pwm);
++
++      return ret ? : len;
++}
++
++static ssize_t pwm_unexport_store(struct device *parent,
++                                struct device_attribute *attr,
++                                const char *buf, size_t len)
++{
++      struct pwm_chip *chip = dev_get_drvdata(parent);
++      unsigned int hwpwm;
++      int ret;
++
++      ret = kstrtouint(buf, 0, &hwpwm);
++      if (ret < 0)
++              return ret;
++
++      if (hwpwm >= chip->npwm)
++              return -ENODEV;
++
++      ret = pwm_unexport_child(parent, &chip->pwms[hwpwm]);
++
++      return ret ? : len;
++}
++
++static ssize_t pwm_npwm_show(struct device *parent,
++                           struct device_attribute *attr,
++                           char *buf)
++{
++      const struct pwm_chip *chip = dev_get_drvdata(parent);
++
++      return sprintf(buf, "%u\n", chip->npwm);
++}
++
++static struct device_attribute pwm_chip_attrs[] = {
++      __ATTR(export, 0200, NULL, pwm_export_store),
++      __ATTR(unexport, 0200, NULL, pwm_unexport_store),
++      __ATTR(npwm, 0444, pwm_npwm_show, NULL),
++      __ATTR_NULL,
++};
++
++static struct class pwm_class = {
++      .name           = "pwm",
++      .owner          = THIS_MODULE,
++      .dev_attrs      = pwm_chip_attrs,
++};
++
++static int pwmchip_sysfs_match(struct device *parent, const void *data)
++{
++      return dev_get_drvdata(parent) == data;
++}
++
++void pwmchip_sysfs_export(struct pwm_chip *chip)
++{
++      struct device *parent;
++
++      /*
++       * If device_create() fails the pwm_chip is still usable by
++       * the kernel its just not exported.
++       */
++      parent = device_create(&pwm_class, chip->dev, MKDEV(0, 0), chip,
++                             "pwmchip%d", chip->base);
++      if (IS_ERR(parent)) {
++              dev_warn(chip->dev,
++                       "device_create failed for pwm_chip sysfs export\n");
++      }
++}
++
++void pwmchip_sysfs_unexport(struct pwm_chip *chip)
++{
++      struct device *parent;
++
++      parent = class_find_device(&pwm_class, NULL, chip,
++                                 pwmchip_sysfs_match);
++      if (parent) {
++              /* for class_find_device() */
++              put_device(parent);
++              device_unregister(parent);
++      }
++}
++
++static int __init pwm_sysfs_init(void)
++{
++      return class_register(&pwm_class);
++}
++subsys_initcall(pwm_sysfs_init);
+diff --git a/include/linux/pwm.h b/include/linux/pwm.h
+index a4df204..f0feafd 100644
+--- a/include/linux/pwm.h
++++ b/include/linux/pwm.h
+@@ -76,6 +76,7 @@ enum pwm_polarity {
+ enum {
+       PWMF_REQUESTED = 1 << 0,
+       PWMF_ENABLED = 1 << 1,
++      PWMF_EXPORTED = 1 << 2,
+ };
+ struct pwm_device {
+@@ -86,7 +87,9 @@ struct pwm_device {
+       struct pwm_chip         *chip;
+       void                    *chip_data;
+-      unsigned int            period; /* in nanoseconds */
++      unsigned int            period;         /* in nanoseconds */
++      unsigned int            duty_cycle;     /* in nanoseconds */
++      enum pwm_polarity       polarity;
+ };
+ static inline void pwm_set_period(struct pwm_device *pwm, unsigned int period)
+@@ -100,6 +103,17 @@ static inline unsigned int pwm_get_period(struct pwm_device *pwm)
+       return pwm ? pwm->period : 0;
+ }
++static inline void pwm_set_duty_cycle(struct pwm_device *pwm, unsigned int duty)
++{
++      if (pwm)
++              pwm->duty_cycle = duty;
++}
++
++static inline unsigned int pwm_get_duty_cycle(struct pwm_device *pwm)
++{
++      return pwm ? pwm->duty_cycle : 0;
++}
++
+ /*
+  * pwm_set_polarity - configure the polarity of a PWM signal
+  */
+@@ -278,4 +292,17 @@ static inline void pwm_add_table(struct pwm_lookup *table, size_t num)
+ }
+ #endif
++#ifdef CONFIG_PWM_SYSFS
++void pwmchip_sysfs_export(struct pwm_chip *chip);
++void pwmchip_sysfs_unexport(struct pwm_chip *chip);
++#else
++static inline void pwmchip_sysfs_export(struct pwm_chip *chip)
++{
++}
++
++static inline void pwmchip_sysfs_unexport(struct pwm_chip *chip)
++{
++}
++#endif /* CONFIG_PWM_SYSFS */
++
+ #endif /* __LINUX_PWM_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1006-pwm-Use-the-DT-macro-directly-when-parsing-PWM-DT-fl.patch b/patches.tizen/1006-pwm-Use-the-DT-macro-directly-when-parsing-PWM-DT-fl.patch
new file mode 100644 (file)
index 0000000..544b192
--- /dev/null
@@ -0,0 +1,46 @@
+From 73ef24362fe595524f4de6b3bc1ea7934a156670 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
+Date: Thu, 18 Jul 2013 00:54:22 +0200
+Subject: [PATCH 1006/1302] pwm: Use the DT macro directly when parsing PWM DT
+ flags
+
+Don't redefine a PWM_SPEC_POLARITY macro with a value identical to
+PWM_POLARITY_INVERTED, use the PWM DT macro directly.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
+Reviewed-by: Stephen Warren <swarren@nvidia.com>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/pwm/core.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
+index dfbfbc5..2ca9504 100644
+--- a/drivers/pwm/core.c
++++ b/drivers/pwm/core.c
+@@ -30,10 +30,9 @@
+ #include <linux/debugfs.h>
+ #include <linux/seq_file.h>
+-#define MAX_PWMS 1024
++#include <dt-bindings/pwm/pwm.h>
+-/* flags in the third cell of the DT PWM specifier */
+-#define PWM_SPEC_POLARITY     (1 << 0)
++#define MAX_PWMS 1024
+ static DEFINE_MUTEX(pwm_lookup_lock);
+ static LIST_HEAD(pwm_lookup_list);
+@@ -149,7 +148,7 @@ of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args)
+       pwm_set_period(pwm, args->args[1]);
+-      if (args->args[2] & PWM_SPEC_POLARITY)
++      if (args->args[2] & PWM_POLARITY_INVERTED)
+               pwm_set_polarity(pwm, PWM_POLARITY_INVERSED);
+       else
+               pwm_set_polarity(pwm, PWM_POLARITY_NORMAL);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1007-pwm-samsung-Rename-to-pwm-samsung-legacy.patch b/patches.tizen/1007-pwm-samsung-Rename-to-pwm-samsung-legacy.patch
new file mode 100644 (file)
index 0000000..d64836c
--- /dev/null
@@ -0,0 +1,758 @@
+From 210bd3109abee6398edd7a22b8e9071a506a8080 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <tomasz.figa@gmail.com>
+Date: Sat, 6 Apr 2013 01:08:03 +0200
+Subject: [PATCH 1007/1302] pwm: samsung: Rename to pwm-samsung-legacy
+
+This patch renames the old pwm-samsung driver to pwm-samsung-legacy to
+create place for the new, rewritten, DT-aware pwm-samsung driver.
+
+Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
+Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Tested-by: Heiko Stuebner <heiko@sntech.de>
+Tested-by: Mark Brown <broonie@linaro.org>
+Tested-by: Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/pwm/Makefile             |   2 +-
+ drivers/pwm/pwm-samsung-legacy.c | 353 +++++++++++++++++++++++++++++++++++++++
+ drivers/pwm/pwm-samsung.c        | 353 ---------------------------------------
+ 3 files changed, 354 insertions(+), 354 deletions(-)
+ create mode 100644 drivers/pwm/pwm-samsung-legacy.c
+ delete mode 100644 drivers/pwm/pwm-samsung.c
+
+diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
+index a025439..64d4042 100644
+--- a/drivers/pwm/Makefile
++++ b/drivers/pwm/Makefile
+@@ -9,7 +9,7 @@ obj-$(CONFIG_PWM_LPC32XX)      += pwm-lpc32xx.o
+ obj-$(CONFIG_PWM_MXS)         += pwm-mxs.o
+ obj-$(CONFIG_PWM_PUV3)                += pwm-puv3.o
+ obj-$(CONFIG_PWM_PXA)         += pwm-pxa.o
+-obj-$(CONFIG_PWM_SAMSUNG)     += pwm-samsung.o
++obj-$(CONFIG_PWM_SAMSUNG)     += pwm-samsung-legacy.o
+ obj-$(CONFIG_PWM_SPEAR)               += pwm-spear.o
+ obj-$(CONFIG_PWM_TEGRA)               += pwm-tegra.o
+ obj-$(CONFIG_PWM_TIECAP)      += pwm-tiecap.o
+diff --git a/drivers/pwm/pwm-samsung-legacy.c b/drivers/pwm/pwm-samsung-legacy.c
+new file mode 100644
+index 0000000..a0ece50
+--- /dev/null
++++ b/drivers/pwm/pwm-samsung-legacy.c
+@@ -0,0 +1,353 @@
++/* drivers/pwm/pwm-samsung.c
++ *
++ * Copyright (c) 2007 Ben Dooks
++ * Copyright (c) 2008 Simtec Electronics
++ *    Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
++ *
++ * S3C series PWM device core
++ *
++ * 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.
++*/
++
++#define pr_fmt(fmt) "pwm-samsung: " fmt
++
++#include <linux/export.h>
++#include <linux/kernel.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++#include <linux/err.h>
++#include <linux/clk.h>
++#include <linux/io.h>
++#include <linux/pwm.h>
++
++#include <mach/map.h>
++
++#include <plat/regs-timer.h>
++
++struct s3c_chip {
++      struct platform_device  *pdev;
++
++      struct clk              *clk_div;
++      struct clk              *clk;
++      const char              *label;
++
++      unsigned int             period_ns;
++      unsigned int             duty_ns;
++
++      unsigned char            tcon_base;
++      unsigned char            pwm_id;
++      struct pwm_chip          chip;
++};
++
++#define to_s3c_chip(chip)     container_of(chip, struct s3c_chip, chip)
++
++#define pwm_dbg(_pwm, msg...) dev_dbg(&(_pwm)->pdev->dev, msg)
++
++static struct clk *clk_scaler[2];
++
++static inline int pwm_is_tdiv(struct s3c_chip *chip)
++{
++      return clk_get_parent(chip->clk) == chip->clk_div;
++}
++
++#define pwm_tcon_start(pwm) (1 << (pwm->tcon_base + 0))
++#define pwm_tcon_invert(pwm) (1 << (pwm->tcon_base + 2))
++#define pwm_tcon_autoreload(pwm) (1 << (pwm->tcon_base + 3))
++#define pwm_tcon_manulupdate(pwm) (1 << (pwm->tcon_base + 1))
++
++static int s3c_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
++{
++      struct s3c_chip *s3c = to_s3c_chip(chip);
++      unsigned long flags;
++      unsigned long tcon;
++
++      local_irq_save(flags);
++
++      tcon = __raw_readl(S3C2410_TCON);
++      tcon |= pwm_tcon_start(s3c);
++      __raw_writel(tcon, S3C2410_TCON);
++
++      local_irq_restore(flags);
++
++      return 0;
++}
++
++static void s3c_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
++{
++      struct s3c_chip *s3c = to_s3c_chip(chip);
++      unsigned long flags;
++      unsigned long tcon;
++
++      local_irq_save(flags);
++
++      tcon = __raw_readl(S3C2410_TCON);
++      tcon &= ~pwm_tcon_start(s3c);
++      __raw_writel(tcon, S3C2410_TCON);
++
++      local_irq_restore(flags);
++}
++
++static unsigned long pwm_calc_tin(struct s3c_chip *s3c, unsigned long freq)
++{
++      unsigned long tin_parent_rate;
++      unsigned int div;
++
++      tin_parent_rate = clk_get_rate(clk_get_parent(s3c->clk_div));
++      pwm_dbg(s3c, "tin parent at %lu\n", tin_parent_rate);
++
++      for (div = 2; div <= 16; div *= 2) {
++              if ((tin_parent_rate / (div << 16)) < freq)
++                      return tin_parent_rate / div;
++      }
++
++      return tin_parent_rate / 16;
++}
++
++#define NS_IN_HZ (1000000000UL)
++
++static int s3c_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
++              int duty_ns, int period_ns)
++{
++      struct s3c_chip *s3c = to_s3c_chip(chip);
++      unsigned long tin_rate;
++      unsigned long tin_ns;
++      unsigned long period;
++      unsigned long flags;
++      unsigned long tcon;
++      unsigned long tcnt;
++      long tcmp;
++
++      /* We currently avoid using 64bit arithmetic by using the
++       * fact that anything faster than 1Hz is easily representable
++       * by 32bits. */
++
++      if (period_ns > NS_IN_HZ || duty_ns > NS_IN_HZ)
++              return -ERANGE;
++
++      if (period_ns == s3c->period_ns &&
++          duty_ns == s3c->duty_ns)
++              return 0;
++
++      /* The TCMP and TCNT can be read without a lock, they're not
++       * shared between the timers. */
++
++      tcmp = __raw_readl(S3C2410_TCMPB(s3c->pwm_id));
++      tcnt = __raw_readl(S3C2410_TCNTB(s3c->pwm_id));
++
++      period = NS_IN_HZ / period_ns;
++
++      pwm_dbg(s3c, "duty_ns=%d, period_ns=%d (%lu)\n",
++              duty_ns, period_ns, period);
++
++      /* Check to see if we are changing the clock rate of the PWM */
++
++      if (s3c->period_ns != period_ns) {
++              if (pwm_is_tdiv(s3c)) {
++                      tin_rate = pwm_calc_tin(s3c, period);
++                      clk_set_rate(s3c->clk_div, tin_rate);
++              } else
++                      tin_rate = clk_get_rate(s3c->clk);
++
++              s3c->period_ns = period_ns;
++
++              pwm_dbg(s3c, "tin_rate=%lu\n", tin_rate);
++
++              tin_ns = NS_IN_HZ / tin_rate;
++              tcnt = period_ns / tin_ns;
++      } else
++              tin_ns = NS_IN_HZ / clk_get_rate(s3c->clk);
++
++      /* Note, counters count down */
++
++      tcmp = duty_ns / tin_ns;
++      tcmp = tcnt - tcmp;
++      /* the pwm hw only checks the compare register after a decrement,
++         so the pin never toggles if tcmp = tcnt */
++      if (tcmp == tcnt)
++              tcmp--;
++
++      pwm_dbg(s3c, "tin_ns=%lu, tcmp=%ld/%lu\n", tin_ns, tcmp, tcnt);
++
++      if (tcmp < 0)
++              tcmp = 0;
++
++      /* Update the PWM register block. */
++
++      local_irq_save(flags);
++
++      __raw_writel(tcmp, S3C2410_TCMPB(s3c->pwm_id));
++      __raw_writel(tcnt, S3C2410_TCNTB(s3c->pwm_id));
++
++      tcon = __raw_readl(S3C2410_TCON);
++      tcon |= pwm_tcon_manulupdate(s3c);
++      tcon |= pwm_tcon_autoreload(s3c);
++      __raw_writel(tcon, S3C2410_TCON);
++
++      tcon &= ~pwm_tcon_manulupdate(s3c);
++      __raw_writel(tcon, S3C2410_TCON);
++
++      local_irq_restore(flags);
++
++      return 0;
++}
++
++static struct pwm_ops s3c_pwm_ops = {
++      .enable = s3c_pwm_enable,
++      .disable = s3c_pwm_disable,
++      .config = s3c_pwm_config,
++      .owner = THIS_MODULE,
++};
++
++static int s3c_pwm_probe(struct platform_device *pdev)
++{
++      struct device *dev = &pdev->dev;
++      struct s3c_chip *s3c;
++      unsigned long flags;
++      unsigned long tcon;
++      unsigned int id = pdev->id;
++      int ret;
++
++      if (id == 4) {
++              dev_err(dev, "TIMER4 is currently not supported\n");
++              return -ENXIO;
++      }
++
++      s3c = devm_kzalloc(&pdev->dev, sizeof(*s3c), GFP_KERNEL);
++      if (s3c == NULL) {
++              dev_err(dev, "failed to allocate pwm_device\n");
++              return -ENOMEM;
++      }
++
++      /* calculate base of control bits in TCON */
++      s3c->tcon_base = id == 0 ? 0 : (id * 4) + 4;
++      s3c->pwm_id = id;
++      s3c->chip.dev = &pdev->dev;
++      s3c->chip.ops = &s3c_pwm_ops;
++      s3c->chip.base = -1;
++      s3c->chip.npwm = 1;
++
++      s3c->clk = devm_clk_get(dev, "pwm-tin");
++      if (IS_ERR(s3c->clk)) {
++              dev_err(dev, "failed to get pwm tin clk\n");
++              return PTR_ERR(s3c->clk);
++      }
++
++      s3c->clk_div = devm_clk_get(dev, "pwm-tdiv");
++      if (IS_ERR(s3c->clk_div)) {
++              dev_err(dev, "failed to get pwm tdiv clk\n");
++              return PTR_ERR(s3c->clk_div);
++      }
++
++      clk_enable(s3c->clk);
++      clk_enable(s3c->clk_div);
++
++      local_irq_save(flags);
++
++      tcon = __raw_readl(S3C2410_TCON);
++      tcon |= pwm_tcon_invert(s3c);
++      __raw_writel(tcon, S3C2410_TCON);
++
++      local_irq_restore(flags);
++
++      ret = pwmchip_add(&s3c->chip);
++      if (ret < 0) {
++              dev_err(dev, "failed to register pwm\n");
++              goto err_clk_tdiv;
++      }
++
++      pwm_dbg(s3c, "config bits %02x\n",
++              (__raw_readl(S3C2410_TCON) >> s3c->tcon_base) & 0x0f);
++
++      dev_info(dev, "tin at %lu, tdiv at %lu, tin=%sclk, base %d\n",
++               clk_get_rate(s3c->clk),
++               clk_get_rate(s3c->clk_div),
++               pwm_is_tdiv(s3c) ? "div" : "ext", s3c->tcon_base);
++
++      platform_set_drvdata(pdev, s3c);
++      return 0;
++
++ err_clk_tdiv:
++      clk_disable(s3c->clk_div);
++      clk_disable(s3c->clk);
++      return ret;
++}
++
++static int s3c_pwm_remove(struct platform_device *pdev)
++{
++      struct s3c_chip *s3c = platform_get_drvdata(pdev);
++      int err;
++
++      err = pwmchip_remove(&s3c->chip);
++      if (err < 0)
++              return err;
++
++      clk_disable(s3c->clk_div);
++      clk_disable(s3c->clk);
++
++      return 0;
++}
++
++#ifdef CONFIG_PM_SLEEP
++static int s3c_pwm_suspend(struct device *dev)
++{
++      struct s3c_chip *s3c = dev_get_drvdata(dev);
++
++      /* No one preserve these values during suspend so reset them
++       * Otherwise driver leaves PWM unconfigured if same values
++       * passed to pwm_config
++       */
++      s3c->period_ns = 0;
++      s3c->duty_ns = 0;
++
++      return 0;
++}
++
++static int s3c_pwm_resume(struct device *dev)
++{
++      struct s3c_chip *s3c = dev_get_drvdata(dev);
++      unsigned long tcon;
++
++      /* Restore invertion */
++      tcon = __raw_readl(S3C2410_TCON);
++      tcon |= pwm_tcon_invert(s3c);
++      __raw_writel(tcon, S3C2410_TCON);
++
++      return 0;
++}
++#endif
++
++static SIMPLE_DEV_PM_OPS(s3c_pwm_pm_ops, s3c_pwm_suspend,
++                      s3c_pwm_resume);
++
++static struct platform_driver s3c_pwm_driver = {
++      .driver         = {
++              .name   = "s3c24xx-pwm",
++              .owner  = THIS_MODULE,
++              .pm     = &s3c_pwm_pm_ops,
++      },
++      .probe          = s3c_pwm_probe,
++      .remove         = s3c_pwm_remove,
++};
++
++static int __init pwm_init(void)
++{
++      int ret;
++
++      clk_scaler[0] = clk_get(NULL, "pwm-scaler0");
++      clk_scaler[1] = clk_get(NULL, "pwm-scaler1");
++
++      if (IS_ERR(clk_scaler[0]) || IS_ERR(clk_scaler[1])) {
++              pr_err("failed to get scaler clocks\n");
++              return -EINVAL;
++      }
++
++      ret = platform_driver_register(&s3c_pwm_driver);
++      if (ret)
++              pr_err("failed to add pwm driver\n");
++
++      return ret;
++}
++
++arch_initcall(pwm_init);
+diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c
+deleted file mode 100644
+index a0ece50..0000000
+--- a/drivers/pwm/pwm-samsung.c
++++ /dev/null
+@@ -1,353 +0,0 @@
+-/* drivers/pwm/pwm-samsung.c
+- *
+- * Copyright (c) 2007 Ben Dooks
+- * Copyright (c) 2008 Simtec Electronics
+- *    Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
+- *
+- * S3C series PWM device core
+- *
+- * 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.
+-*/
+-
+-#define pr_fmt(fmt) "pwm-samsung: " fmt
+-
+-#include <linux/export.h>
+-#include <linux/kernel.h>
+-#include <linux/platform_device.h>
+-#include <linux/slab.h>
+-#include <linux/err.h>
+-#include <linux/clk.h>
+-#include <linux/io.h>
+-#include <linux/pwm.h>
+-
+-#include <mach/map.h>
+-
+-#include <plat/regs-timer.h>
+-
+-struct s3c_chip {
+-      struct platform_device  *pdev;
+-
+-      struct clk              *clk_div;
+-      struct clk              *clk;
+-      const char              *label;
+-
+-      unsigned int             period_ns;
+-      unsigned int             duty_ns;
+-
+-      unsigned char            tcon_base;
+-      unsigned char            pwm_id;
+-      struct pwm_chip          chip;
+-};
+-
+-#define to_s3c_chip(chip)     container_of(chip, struct s3c_chip, chip)
+-
+-#define pwm_dbg(_pwm, msg...) dev_dbg(&(_pwm)->pdev->dev, msg)
+-
+-static struct clk *clk_scaler[2];
+-
+-static inline int pwm_is_tdiv(struct s3c_chip *chip)
+-{
+-      return clk_get_parent(chip->clk) == chip->clk_div;
+-}
+-
+-#define pwm_tcon_start(pwm) (1 << (pwm->tcon_base + 0))
+-#define pwm_tcon_invert(pwm) (1 << (pwm->tcon_base + 2))
+-#define pwm_tcon_autoreload(pwm) (1 << (pwm->tcon_base + 3))
+-#define pwm_tcon_manulupdate(pwm) (1 << (pwm->tcon_base + 1))
+-
+-static int s3c_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+-{
+-      struct s3c_chip *s3c = to_s3c_chip(chip);
+-      unsigned long flags;
+-      unsigned long tcon;
+-
+-      local_irq_save(flags);
+-
+-      tcon = __raw_readl(S3C2410_TCON);
+-      tcon |= pwm_tcon_start(s3c);
+-      __raw_writel(tcon, S3C2410_TCON);
+-
+-      local_irq_restore(flags);
+-
+-      return 0;
+-}
+-
+-static void s3c_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+-{
+-      struct s3c_chip *s3c = to_s3c_chip(chip);
+-      unsigned long flags;
+-      unsigned long tcon;
+-
+-      local_irq_save(flags);
+-
+-      tcon = __raw_readl(S3C2410_TCON);
+-      tcon &= ~pwm_tcon_start(s3c);
+-      __raw_writel(tcon, S3C2410_TCON);
+-
+-      local_irq_restore(flags);
+-}
+-
+-static unsigned long pwm_calc_tin(struct s3c_chip *s3c, unsigned long freq)
+-{
+-      unsigned long tin_parent_rate;
+-      unsigned int div;
+-
+-      tin_parent_rate = clk_get_rate(clk_get_parent(s3c->clk_div));
+-      pwm_dbg(s3c, "tin parent at %lu\n", tin_parent_rate);
+-
+-      for (div = 2; div <= 16; div *= 2) {
+-              if ((tin_parent_rate / (div << 16)) < freq)
+-                      return tin_parent_rate / div;
+-      }
+-
+-      return tin_parent_rate / 16;
+-}
+-
+-#define NS_IN_HZ (1000000000UL)
+-
+-static int s3c_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+-              int duty_ns, int period_ns)
+-{
+-      struct s3c_chip *s3c = to_s3c_chip(chip);
+-      unsigned long tin_rate;
+-      unsigned long tin_ns;
+-      unsigned long period;
+-      unsigned long flags;
+-      unsigned long tcon;
+-      unsigned long tcnt;
+-      long tcmp;
+-
+-      /* We currently avoid using 64bit arithmetic by using the
+-       * fact that anything faster than 1Hz is easily representable
+-       * by 32bits. */
+-
+-      if (period_ns > NS_IN_HZ || duty_ns > NS_IN_HZ)
+-              return -ERANGE;
+-
+-      if (period_ns == s3c->period_ns &&
+-          duty_ns == s3c->duty_ns)
+-              return 0;
+-
+-      /* The TCMP and TCNT can be read without a lock, they're not
+-       * shared between the timers. */
+-
+-      tcmp = __raw_readl(S3C2410_TCMPB(s3c->pwm_id));
+-      tcnt = __raw_readl(S3C2410_TCNTB(s3c->pwm_id));
+-
+-      period = NS_IN_HZ / period_ns;
+-
+-      pwm_dbg(s3c, "duty_ns=%d, period_ns=%d (%lu)\n",
+-              duty_ns, period_ns, period);
+-
+-      /* Check to see if we are changing the clock rate of the PWM */
+-
+-      if (s3c->period_ns != period_ns) {
+-              if (pwm_is_tdiv(s3c)) {
+-                      tin_rate = pwm_calc_tin(s3c, period);
+-                      clk_set_rate(s3c->clk_div, tin_rate);
+-              } else
+-                      tin_rate = clk_get_rate(s3c->clk);
+-
+-              s3c->period_ns = period_ns;
+-
+-              pwm_dbg(s3c, "tin_rate=%lu\n", tin_rate);
+-
+-              tin_ns = NS_IN_HZ / tin_rate;
+-              tcnt = period_ns / tin_ns;
+-      } else
+-              tin_ns = NS_IN_HZ / clk_get_rate(s3c->clk);
+-
+-      /* Note, counters count down */
+-
+-      tcmp = duty_ns / tin_ns;
+-      tcmp = tcnt - tcmp;
+-      /* the pwm hw only checks the compare register after a decrement,
+-         so the pin never toggles if tcmp = tcnt */
+-      if (tcmp == tcnt)
+-              tcmp--;
+-
+-      pwm_dbg(s3c, "tin_ns=%lu, tcmp=%ld/%lu\n", tin_ns, tcmp, tcnt);
+-
+-      if (tcmp < 0)
+-              tcmp = 0;
+-
+-      /* Update the PWM register block. */
+-
+-      local_irq_save(flags);
+-
+-      __raw_writel(tcmp, S3C2410_TCMPB(s3c->pwm_id));
+-      __raw_writel(tcnt, S3C2410_TCNTB(s3c->pwm_id));
+-
+-      tcon = __raw_readl(S3C2410_TCON);
+-      tcon |= pwm_tcon_manulupdate(s3c);
+-      tcon |= pwm_tcon_autoreload(s3c);
+-      __raw_writel(tcon, S3C2410_TCON);
+-
+-      tcon &= ~pwm_tcon_manulupdate(s3c);
+-      __raw_writel(tcon, S3C2410_TCON);
+-
+-      local_irq_restore(flags);
+-
+-      return 0;
+-}
+-
+-static struct pwm_ops s3c_pwm_ops = {
+-      .enable = s3c_pwm_enable,
+-      .disable = s3c_pwm_disable,
+-      .config = s3c_pwm_config,
+-      .owner = THIS_MODULE,
+-};
+-
+-static int s3c_pwm_probe(struct platform_device *pdev)
+-{
+-      struct device *dev = &pdev->dev;
+-      struct s3c_chip *s3c;
+-      unsigned long flags;
+-      unsigned long tcon;
+-      unsigned int id = pdev->id;
+-      int ret;
+-
+-      if (id == 4) {
+-              dev_err(dev, "TIMER4 is currently not supported\n");
+-              return -ENXIO;
+-      }
+-
+-      s3c = devm_kzalloc(&pdev->dev, sizeof(*s3c), GFP_KERNEL);
+-      if (s3c == NULL) {
+-              dev_err(dev, "failed to allocate pwm_device\n");
+-              return -ENOMEM;
+-      }
+-
+-      /* calculate base of control bits in TCON */
+-      s3c->tcon_base = id == 0 ? 0 : (id * 4) + 4;
+-      s3c->pwm_id = id;
+-      s3c->chip.dev = &pdev->dev;
+-      s3c->chip.ops = &s3c_pwm_ops;
+-      s3c->chip.base = -1;
+-      s3c->chip.npwm = 1;
+-
+-      s3c->clk = devm_clk_get(dev, "pwm-tin");
+-      if (IS_ERR(s3c->clk)) {
+-              dev_err(dev, "failed to get pwm tin clk\n");
+-              return PTR_ERR(s3c->clk);
+-      }
+-
+-      s3c->clk_div = devm_clk_get(dev, "pwm-tdiv");
+-      if (IS_ERR(s3c->clk_div)) {
+-              dev_err(dev, "failed to get pwm tdiv clk\n");
+-              return PTR_ERR(s3c->clk_div);
+-      }
+-
+-      clk_enable(s3c->clk);
+-      clk_enable(s3c->clk_div);
+-
+-      local_irq_save(flags);
+-
+-      tcon = __raw_readl(S3C2410_TCON);
+-      tcon |= pwm_tcon_invert(s3c);
+-      __raw_writel(tcon, S3C2410_TCON);
+-
+-      local_irq_restore(flags);
+-
+-      ret = pwmchip_add(&s3c->chip);
+-      if (ret < 0) {
+-              dev_err(dev, "failed to register pwm\n");
+-              goto err_clk_tdiv;
+-      }
+-
+-      pwm_dbg(s3c, "config bits %02x\n",
+-              (__raw_readl(S3C2410_TCON) >> s3c->tcon_base) & 0x0f);
+-
+-      dev_info(dev, "tin at %lu, tdiv at %lu, tin=%sclk, base %d\n",
+-               clk_get_rate(s3c->clk),
+-               clk_get_rate(s3c->clk_div),
+-               pwm_is_tdiv(s3c) ? "div" : "ext", s3c->tcon_base);
+-
+-      platform_set_drvdata(pdev, s3c);
+-      return 0;
+-
+- err_clk_tdiv:
+-      clk_disable(s3c->clk_div);
+-      clk_disable(s3c->clk);
+-      return ret;
+-}
+-
+-static int s3c_pwm_remove(struct platform_device *pdev)
+-{
+-      struct s3c_chip *s3c = platform_get_drvdata(pdev);
+-      int err;
+-
+-      err = pwmchip_remove(&s3c->chip);
+-      if (err < 0)
+-              return err;
+-
+-      clk_disable(s3c->clk_div);
+-      clk_disable(s3c->clk);
+-
+-      return 0;
+-}
+-
+-#ifdef CONFIG_PM_SLEEP
+-static int s3c_pwm_suspend(struct device *dev)
+-{
+-      struct s3c_chip *s3c = dev_get_drvdata(dev);
+-
+-      /* No one preserve these values during suspend so reset them
+-       * Otherwise driver leaves PWM unconfigured if same values
+-       * passed to pwm_config
+-       */
+-      s3c->period_ns = 0;
+-      s3c->duty_ns = 0;
+-
+-      return 0;
+-}
+-
+-static int s3c_pwm_resume(struct device *dev)
+-{
+-      struct s3c_chip *s3c = dev_get_drvdata(dev);
+-      unsigned long tcon;
+-
+-      /* Restore invertion */
+-      tcon = __raw_readl(S3C2410_TCON);
+-      tcon |= pwm_tcon_invert(s3c);
+-      __raw_writel(tcon, S3C2410_TCON);
+-
+-      return 0;
+-}
+-#endif
+-
+-static SIMPLE_DEV_PM_OPS(s3c_pwm_pm_ops, s3c_pwm_suspend,
+-                      s3c_pwm_resume);
+-
+-static struct platform_driver s3c_pwm_driver = {
+-      .driver         = {
+-              .name   = "s3c24xx-pwm",
+-              .owner  = THIS_MODULE,
+-              .pm     = &s3c_pwm_pm_ops,
+-      },
+-      .probe          = s3c_pwm_probe,
+-      .remove         = s3c_pwm_remove,
+-};
+-
+-static int __init pwm_init(void)
+-{
+-      int ret;
+-
+-      clk_scaler[0] = clk_get(NULL, "pwm-scaler0");
+-      clk_scaler[1] = clk_get(NULL, "pwm-scaler1");
+-
+-      if (IS_ERR(clk_scaler[0]) || IS_ERR(clk_scaler[1])) {
+-              pr_err("failed to get scaler clocks\n");
+-              return -EINVAL;
+-      }
+-
+-      ret = platform_driver_register(&s3c_pwm_driver);
+-      if (ret)
+-              pr_err("failed to add pwm driver\n");
+-
+-      return ret;
+-}
+-
+-arch_initcall(pwm_init);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1008-pwm-Add-new-pwm-samsung-driver.patch b/patches.tizen/1008-pwm-Add-new-pwm-samsung-driver.patch
new file mode 100644 (file)
index 0000000..5ce4dde
--- /dev/null
@@ -0,0 +1,688 @@
+From c515c2b6c840b9a80a7a847d54d80b32f167c117 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <tomasz.figa@gmail.com>
+Date: Sat, 6 Apr 2013 02:40:36 +0200
+Subject: [PATCH 1008/1302] pwm: Add new pwm-samsung driver
+
+This patch introduces new Samsung PWM driver, which is completely
+rewritten to be multiplatform- and DeviceTree-aware.
+
+In addition, remaining problems of old driver are fixed, such as:
+ - proper handling of hardware variants,
+ - synchronization on SMP systems,
+ - handling of boundary parameter values,
+ - hardware sharing with PWM clocksource driver,
+ - undefined state of PWM output after stopping PWM channel.
+
+Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
+Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Tested-by: Heiko Stuebner <heiko@sntech.de>
+Tested-by: Mark Brown <broonie@linaro.org>
+Tested-by: Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/pwm/Makefile              |   1 +
+ drivers/pwm/pwm-samsung.c         | 618 ++++++++++++++++++++++++++++++++++++++
+ include/clocksource/samsung_pwm.h |   7 +
+ 3 files changed, 626 insertions(+)
+ create mode 100644 drivers/pwm/pwm-samsung.c
+
+diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
+index 64d4042..e2483e4 100644
+--- a/drivers/pwm/Makefile
++++ b/drivers/pwm/Makefile
+@@ -10,6 +10,7 @@ obj-$(CONFIG_PWM_MXS)                += pwm-mxs.o
+ obj-$(CONFIG_PWM_PUV3)                += pwm-puv3.o
+ obj-$(CONFIG_PWM_PXA)         += pwm-pxa.o
+ obj-$(CONFIG_PWM_SAMSUNG)     += pwm-samsung-legacy.o
++obj-$(CONFIG_PWM_SAMSUNG)     += pwm-samsung.o
+ obj-$(CONFIG_PWM_SPEAR)               += pwm-spear.o
+ obj-$(CONFIG_PWM_TEGRA)               += pwm-tegra.o
+ obj-$(CONFIG_PWM_TIECAP)      += pwm-tiecap.o
+diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c
+new file mode 100644
+index 0000000..fcc8b9a
+--- /dev/null
++++ b/drivers/pwm/pwm-samsung.c
+@@ -0,0 +1,618 @@
++/*
++ * Copyright (c) 2007 Ben Dooks
++ * Copyright (c) 2008 Simtec Electronics
++ *     Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
++ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
++ *
++ * PWM driver for Samsung SoCs
++ *
++ * 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.
++ */
++
++#include <linux/bitops.h>
++#include <linux/clk.h>
++#include <linux/export.h>
++#include <linux/err.h>
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/pwm.h>
++#include <linux/slab.h>
++#include <linux/spinlock.h>
++#include <linux/time.h>
++
++/* For struct samsung_timer_variant and samsung_pwm_lock. */
++#include <clocksource/samsung_pwm.h>
++
++#define REG_TCFG0                     0x00
++#define REG_TCFG1                     0x04
++#define REG_TCON                      0x08
++
++#define REG_TCNTB(chan)                       (0x0c + ((chan) * 0xc))
++#define REG_TCMPB(chan)                       (0x10 + ((chan) * 0xc))
++
++#define TCFG0_PRESCALER_MASK          0xff
++#define TCFG0_PRESCALER1_SHIFT                8
++
++#define TCFG1_MUX_MASK                        0xf
++#define TCFG1_SHIFT(chan)             (4 * (chan))
++
++/*
++ * Each channel occupies 4 bits in TCON register, but there is a gap of 4
++ * bits (one channel) after channel 0, so channels have different numbering
++ * when accessing TCON register. See to_tcon_channel() function.
++ *
++ * In addition, the location of autoreload bit for channel 4 (TCON channel 5)
++ * in its set of bits is 2 as opposed to 3 for other channels.
++ */
++#define TCON_START(chan)              BIT(4 * (chan) + 0)
++#define TCON_MANUALUPDATE(chan)               BIT(4 * (chan) + 1)
++#define TCON_INVERT(chan)             BIT(4 * (chan) + 2)
++#define _TCON_AUTORELOAD(chan)                BIT(4 * (chan) + 3)
++#define _TCON_AUTORELOAD4(chan)               BIT(4 * (chan) + 2)
++#define TCON_AUTORELOAD(chan)         \
++      ((chan < 5) ? _TCON_AUTORELOAD(chan) : _TCON_AUTORELOAD4(chan))
++
++/**
++ * struct samsung_pwm_channel - private data of PWM channel
++ * @period_ns:        current period in nanoseconds programmed to the hardware
++ * @duty_ns:  current duty time in nanoseconds programmed to the hardware
++ * @tin_ns:   time of one timer tick in nanoseconds with current timer rate
++ */
++struct samsung_pwm_channel {
++      u32 period_ns;
++      u32 duty_ns;
++      u32 tin_ns;
++};
++
++/**
++ * struct samsung_pwm_chip - private data of PWM chip
++ * @chip:             generic PWM chip
++ * @variant:          local copy of hardware variant data
++ * @inverter_mask:    inverter status for all channels - one bit per channel
++ * @base:             base address of mapped PWM registers
++ * @base_clk:         base clock used to drive the timers
++ * @tclk0:            external clock 0 (can be ERR_PTR if not present)
++ * @tclk1:            external clock 1 (can be ERR_PTR if not present)
++ */
++struct samsung_pwm_chip {
++      struct pwm_chip chip;
++      struct samsung_pwm_variant variant;
++      u8 inverter_mask;
++
++      void __iomem *base;
++      struct clk *base_clk;
++      struct clk *tclk0;
++      struct clk *tclk1;
++};
++
++#ifndef CONFIG_CLKSRC_SAMSUNG_PWM
++/*
++ * PWM block is shared between pwm-samsung and samsung_pwm_timer drivers
++ * and some registers need access synchronization. If both drivers are
++ * compiled in, the spinlock is defined in the clocksource driver,
++ * otherwise following definition is used.
++ *
++ * Currently we do not need any more complex synchronization method
++ * because all the supported SoCs contain only one instance of the PWM
++ * IP. Should this change, both drivers will need to be modified to
++ * properly synchronize accesses to particular instances.
++ */
++static DEFINE_SPINLOCK(samsung_pwm_lock);
++#endif
++
++static inline
++struct samsung_pwm_chip *to_samsung_pwm_chip(struct pwm_chip *chip)
++{
++      return container_of(chip, struct samsung_pwm_chip, chip);
++}
++
++static inline unsigned int to_tcon_channel(unsigned int channel)
++{
++      /* TCON register has a gap of 4 bits (1 channel) after channel 0 */
++      return (channel == 0) ? 0 : (channel + 1);
++}
++
++static void pwm_samsung_set_divisor(struct samsung_pwm_chip *pwm,
++                                  unsigned int channel, u8 divisor)
++{
++      u8 shift = TCFG1_SHIFT(channel);
++      unsigned long flags;
++      u32 reg;
++      u8 bits;
++
++      bits = (fls(divisor) - 1) - pwm->variant.div_base;
++
++      spin_lock_irqsave(&samsung_pwm_lock, flags);
++
++      reg = readl(pwm->base + REG_TCFG1);
++      reg &= ~(TCFG1_MUX_MASK << shift);
++      reg |= bits << shift;
++      writel(reg, pwm->base + REG_TCFG1);
++
++      spin_unlock_irqrestore(&samsung_pwm_lock, flags);
++}
++
++static int pwm_samsung_is_tdiv(struct samsung_pwm_chip *chip, unsigned int chan)
++{
++      struct samsung_pwm_variant *variant = &chip->variant;
++      u32 reg;
++
++      reg = readl(chip->base + REG_TCFG1);
++      reg >>= TCFG1_SHIFT(chan);
++      reg &= TCFG1_MUX_MASK;
++
++      return (BIT(reg) & variant->tclk_mask) == 0;
++}
++
++static unsigned long pwm_samsung_get_tin_rate(struct samsung_pwm_chip *chip,
++                                            unsigned int chan)
++{
++      unsigned long rate;
++      u32 reg;
++
++      rate = clk_get_rate(chip->base_clk);
++
++      reg = readl(chip->base + REG_TCFG0);
++      if (chan >= 2)
++              reg >>= TCFG0_PRESCALER1_SHIFT;
++      reg &= TCFG0_PRESCALER_MASK;
++
++      return rate / (reg + 1);
++}
++
++static unsigned long pwm_samsung_calc_tin(struct samsung_pwm_chip *chip,
++                                        unsigned int chan, unsigned long freq)
++{
++      struct samsung_pwm_variant *variant = &chip->variant;
++      unsigned long rate;
++      struct clk *clk;
++      u8 div;
++
++      if (!pwm_samsung_is_tdiv(chip, chan)) {
++              clk = (chan < 2) ? chip->tclk0 : chip->tclk1;
++              if (!IS_ERR(clk)) {
++                      rate = clk_get_rate(clk);
++                      if (rate)
++                              return rate;
++              }
++
++              dev_warn(chip->chip.dev,
++                      "tclk of PWM %d is inoperational, using tdiv\n", chan);
++      }
++
++      rate = pwm_samsung_get_tin_rate(chip, chan);
++      dev_dbg(chip->chip.dev, "tin parent at %lu\n", rate);
++
++      /*
++       * Compare minimum PWM frequency that can be achieved with possible
++       * divider settings and choose the lowest divisor that can generate
++       * frequencies lower than requested.
++       */
++      for (div = variant->div_base; div < 4; ++div)
++              if ((rate >> (variant->bits + div)) < freq)
++                      break;
++
++      pwm_samsung_set_divisor(chip, chan, BIT(div));
++
++      return rate >> div;
++}
++
++static int pwm_samsung_request(struct pwm_chip *chip, struct pwm_device *pwm)
++{
++      struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
++      struct samsung_pwm_channel *our_chan;
++
++      if (!(our_chip->variant.output_mask & BIT(pwm->hwpwm))) {
++              dev_warn(chip->dev,
++                      "tried to request PWM channel %d without output\n",
++                      pwm->hwpwm);
++              return -EINVAL;
++      }
++
++      our_chan = devm_kzalloc(chip->dev, sizeof(*our_chan), GFP_KERNEL);
++      if (!our_chan)
++              return -ENOMEM;
++
++      pwm_set_chip_data(pwm, our_chan);
++
++      return 0;
++}
++
++static void pwm_samsung_free(struct pwm_chip *chip, struct pwm_device *pwm)
++{
++      pwm_set_chip_data(pwm, NULL);
++      devm_kfree(chip->dev, pwm_get_chip_data(pwm));
++}
++
++static int pwm_samsung_enable(struct pwm_chip *chip, struct pwm_device *pwm)
++{
++      struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
++      unsigned int tcon_chan = to_tcon_channel(pwm->hwpwm);
++      unsigned long flags;
++      u32 tcon;
++
++      spin_lock_irqsave(&samsung_pwm_lock, flags);
++
++      tcon = readl(our_chip->base + REG_TCON);
++
++      tcon &= ~TCON_START(tcon_chan);
++      tcon |= TCON_MANUALUPDATE(tcon_chan);
++      writel(tcon, our_chip->base + REG_TCON);
++
++      tcon &= ~TCON_MANUALUPDATE(tcon_chan);
++      tcon |= TCON_START(tcon_chan) | TCON_AUTORELOAD(tcon_chan);
++      writel(tcon, our_chip->base + REG_TCON);
++
++      spin_unlock_irqrestore(&samsung_pwm_lock, flags);
++
++      return 0;
++}
++
++static void pwm_samsung_disable(struct pwm_chip *chip, struct pwm_device *pwm)
++{
++      struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
++      unsigned int tcon_chan = to_tcon_channel(pwm->hwpwm);
++      unsigned long flags;
++      u32 tcon;
++
++      spin_lock_irqsave(&samsung_pwm_lock, flags);
++
++      tcon = readl(our_chip->base + REG_TCON);
++      tcon &= ~TCON_AUTORELOAD(tcon_chan);
++      writel(tcon, our_chip->base + REG_TCON);
++
++      spin_unlock_irqrestore(&samsung_pwm_lock, flags);
++}
++
++static int pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm,
++                            int duty_ns, int period_ns)
++{
++      struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
++      struct samsung_pwm_channel *chan = pwm_get_chip_data(pwm);
++      u32 tin_ns = chan->tin_ns, tcnt, tcmp;
++
++      /*
++       * We currently avoid using 64bit arithmetic by using the
++       * fact that anything faster than 1Hz is easily representable
++       * by 32bits.
++       */
++      if (period_ns > NSEC_PER_SEC)
++              return -ERANGE;
++
++      if (period_ns == chan->period_ns && duty_ns == chan->duty_ns)
++              return 0;
++
++      tcnt = readl(our_chip->base + REG_TCNTB(pwm->hwpwm));
++
++      /* We need tick count for calculation, not last tick. */
++      ++tcnt;
++
++      /* Check to see if we are changing the clock rate of the PWM. */
++      if (chan->period_ns != period_ns) {
++              unsigned long tin_rate;
++              u32 period;
++
++              period = NSEC_PER_SEC / period_ns;
++
++              dev_dbg(our_chip->chip.dev, "duty_ns=%d, period_ns=%d (%u)\n",
++                                              duty_ns, period_ns, period);
++
++              tin_rate = pwm_samsung_calc_tin(our_chip, pwm->hwpwm, period);
++
++              dev_dbg(our_chip->chip.dev, "tin_rate=%lu\n", tin_rate);
++
++              tin_ns = NSEC_PER_SEC / tin_rate;
++              tcnt = period_ns / tin_ns;
++      }
++
++      /* Period is too short. */
++      if (tcnt <= 1)
++              return -ERANGE;
++
++      /* Note that counters count down. */
++      tcmp = duty_ns / tin_ns;
++
++      /* 0% duty is not available */
++      if (!tcmp)
++              ++tcmp;
++
++      tcmp = tcnt - tcmp;
++
++      /* Decrement to get tick numbers, instead of tick counts. */
++      --tcnt;
++      /* -1UL will give 100% duty. */
++      --tcmp;
++
++      dev_dbg(our_chip->chip.dev,
++                              "tin_ns=%u, tcmp=%u/%u\n", tin_ns, tcmp, tcnt);
++
++      /* Update PWM registers. */
++      writel(tcnt, our_chip->base + REG_TCNTB(pwm->hwpwm));
++      writel(tcmp, our_chip->base + REG_TCMPB(pwm->hwpwm));
++
++      if (test_bit(PWMF_ENABLED, &pwm->flags))
++              pwm_samsung_enable(chip, pwm);
++
++      chan->period_ns = period_ns;
++      chan->tin_ns = tin_ns;
++      chan->duty_ns = duty_ns;
++
++      return 0;
++}
++
++static void pwm_samsung_set_invert(struct samsung_pwm_chip *chip,
++                                 unsigned int channel, bool invert)
++{
++      unsigned int tcon_chan = to_tcon_channel(channel);
++      unsigned long flags;
++      u32 tcon;
++
++      spin_lock_irqsave(&samsung_pwm_lock, flags);
++
++      tcon = readl(chip->base + REG_TCON);
++
++      if (invert) {
++              chip->inverter_mask |= BIT(channel);
++              tcon |= TCON_INVERT(tcon_chan);
++      } else {
++              chip->inverter_mask &= ~BIT(channel);
++              tcon &= ~TCON_INVERT(tcon_chan);
++      }
++
++      writel(tcon, chip->base + REG_TCON);
++
++      spin_unlock_irqrestore(&samsung_pwm_lock, flags);
++}
++
++static int pwm_samsung_set_polarity(struct pwm_chip *chip,
++                                  struct pwm_device *pwm,
++                                  enum pwm_polarity polarity)
++{
++      struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
++      bool invert = (polarity == PWM_POLARITY_NORMAL);
++
++      /* Inverted means normal in the hardware. */
++      pwm_samsung_set_invert(our_chip, pwm->hwpwm, invert);
++
++      return 0;
++}
++
++static const struct pwm_ops pwm_samsung_ops = {
++      .request        = pwm_samsung_request,
++      .free           = pwm_samsung_free,
++      .enable         = pwm_samsung_enable,
++      .disable        = pwm_samsung_disable,
++      .config         = pwm_samsung_config,
++      .set_polarity   = pwm_samsung_set_polarity,
++      .owner          = THIS_MODULE,
++};
++
++#ifdef CONFIG_OF
++static const struct samsung_pwm_variant s3c24xx_variant = {
++      .bits           = 16,
++      .div_base       = 1,
++      .has_tint_cstat = false,
++      .tclk_mask      = BIT(4),
++};
++
++static const struct samsung_pwm_variant s3c64xx_variant = {
++      .bits           = 32,
++      .div_base       = 0,
++      .has_tint_cstat = true,
++      .tclk_mask      = BIT(7) | BIT(6) | BIT(5),
++};
++
++static const struct samsung_pwm_variant s5p64x0_variant = {
++      .bits           = 32,
++      .div_base       = 0,
++      .has_tint_cstat = true,
++      .tclk_mask      = 0,
++};
++
++static const struct samsung_pwm_variant s5pc100_variant = {
++      .bits           = 32,
++      .div_base       = 0,
++      .has_tint_cstat = true,
++      .tclk_mask      = BIT(5),
++};
++
++static const struct of_device_id samsung_pwm_matches[] = {
++      { .compatible = "samsung,s3c2410-pwm", .data = &s3c24xx_variant },
++      { .compatible = "samsung,s3c6400-pwm", .data = &s3c64xx_variant },
++      { .compatible = "samsung,s5p6440-pwm", .data = &s5p64x0_variant },
++      { .compatible = "samsung,s5pc100-pwm", .data = &s5pc100_variant },
++      { .compatible = "samsung,exynos4210-pwm", .data = &s5p64x0_variant },
++      {},
++};
++
++static int pwm_samsung_parse_dt(struct samsung_pwm_chip *chip)
++{
++      struct device_node *np = chip->chip.dev->of_node;
++      const struct of_device_id *match;
++      struct property *prop;
++      const __be32 *cur;
++      u32 val;
++
++      match = of_match_node(samsung_pwm_matches, np);
++      if (!match)
++              return -ENODEV;
++
++      memcpy(&chip->variant, match->data, sizeof(chip->variant));
++
++      of_property_for_each_u32(np, "samsung,pwm-outputs", prop, cur, val) {
++              if (val >= SAMSUNG_PWM_NUM) {
++                      dev_err(chip->chip.dev,
++                              "%s: invalid channel index in samsung,pwm-outputs property\n",
++                                                              __func__);
++                      continue;
++              }
++              chip->variant.output_mask |= BIT(val);
++      }
++
++      return 0;
++}
++#else
++static int pwm_samsung_parse_dt(struct samsung_pwm_chip *chip)
++{
++      return -ENODEV;
++}
++#endif
++
++static int pwm_samsung_probe(struct platform_device *pdev)
++{
++      struct device *dev = &pdev->dev;
++      struct samsung_pwm_chip *chip;
++      struct resource *res;
++      unsigned int chan;
++      int ret;
++
++      chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
++      if (chip == NULL)
++              return -ENOMEM;
++
++      chip->chip.dev = &pdev->dev;
++      chip->chip.ops = &pwm_samsung_ops;
++      chip->chip.base = -1;
++      chip->chip.npwm = SAMSUNG_PWM_NUM;
++      chip->inverter_mask = BIT(SAMSUNG_PWM_NUM) - 1;
++
++      if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
++              ret = pwm_samsung_parse_dt(chip);
++              if (ret)
++                      return ret;
++
++              chip->chip.of_xlate = of_pwm_xlate_with_flags;
++              chip->chip.of_pwm_n_cells = 3;
++      } else {
++              if (!pdev->dev.platform_data) {
++                      dev_err(&pdev->dev, "no platform data specified\n");
++                      return -EINVAL;
++              }
++
++              memcpy(&chip->variant, pdev->dev.platform_data,
++                                                      sizeof(chip->variant));
++      }
++
++      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      chip->base = devm_ioremap_resource(&pdev->dev, res);
++      if (IS_ERR(chip->base))
++              return PTR_ERR(chip->base);
++
++      chip->base_clk = devm_clk_get(&pdev->dev, "timers");
++      if (IS_ERR(chip->base_clk)) {
++              dev_err(dev, "failed to get timer base clk\n");
++              return PTR_ERR(chip->base_clk);
++      }
++
++      ret = clk_prepare_enable(chip->base_clk);
++      if (ret < 0) {
++              dev_err(dev, "failed to enable base clock\n");
++              return ret;
++      }
++
++      for (chan = 0; chan < SAMSUNG_PWM_NUM; ++chan)
++              if (chip->variant.output_mask & BIT(chan))
++                      pwm_samsung_set_invert(chip, chan, true);
++
++      /* Following clocks are optional. */
++      chip->tclk0 = devm_clk_get(&pdev->dev, "pwm-tclk0");
++      chip->tclk1 = devm_clk_get(&pdev->dev, "pwm-tclk1");
++
++      platform_set_drvdata(pdev, chip);
++
++      ret = pwmchip_add(&chip->chip);
++      if (ret < 0) {
++              dev_err(dev, "failed to register PWM chip\n");
++              clk_disable_unprepare(chip->base_clk);
++              return ret;
++      }
++
++      dev_dbg(dev, "base_clk at %lu, tclk0 at %lu, tclk1 at %lu\n",
++              clk_get_rate(chip->base_clk),
++              !IS_ERR(chip->tclk0) ? clk_get_rate(chip->tclk0) : 0,
++              !IS_ERR(chip->tclk1) ? clk_get_rate(chip->tclk1) : 0);
++
++      return 0;
++}
++
++static int pwm_samsung_remove(struct platform_device *pdev)
++{
++      struct samsung_pwm_chip *chip = platform_get_drvdata(pdev);
++      int ret;
++
++      ret = pwmchip_remove(&chip->chip);
++      if (ret < 0)
++              return ret;
++
++      clk_disable_unprepare(chip->base_clk);
++
++      return 0;
++}
++
++#ifdef CONFIG_PM_SLEEP
++static int pwm_samsung_suspend(struct device *dev)
++{
++      struct samsung_pwm_chip *chip = dev_get_drvdata(dev);
++      unsigned int i;
++
++      /*
++       * No one preserves these values during suspend so reset them.
++       * Otherwise driver leaves PWM unconfigured if same values are
++       * passed to pwm_config() next time.
++       */
++      for (i = 0; i < SAMSUNG_PWM_NUM; ++i) {
++              struct pwm_device *pwm = &chip->chip.pwms[i];
++              struct samsung_pwm_channel *chan = pwm_get_chip_data(pwm);
++
++              if (!chan)
++                      continue;
++
++              chan->period_ns = 0;
++              chan->duty_ns = 0;
++      }
++
++      return 0;
++}
++
++static int pwm_samsung_resume(struct device *dev)
++{
++      struct samsung_pwm_chip *chip = dev_get_drvdata(dev);
++      unsigned int chan;
++
++      /*
++       * Inverter setting must be preserved across suspend/resume
++       * as nobody really seems to configure it more than once.
++       */
++      for (chan = 0; chan < SAMSUNG_PWM_NUM; ++chan) {
++              if (chip->variant.output_mask & BIT(chan))
++                      pwm_samsung_set_invert(chip, chan,
++                                      chip->inverter_mask & BIT(chan));
++      }
++
++      return 0;
++}
++#endif
++
++static const struct dev_pm_ops pwm_samsung_pm_ops = {
++      SET_SYSTEM_SLEEP_PM_OPS(pwm_samsung_suspend, pwm_samsung_resume)
++};
++
++static struct platform_driver pwm_samsung_driver = {
++      .driver         = {
++              .name   = "samsung-pwm",
++              .owner  = THIS_MODULE,
++              .pm     = &pwm_samsung_pm_ops,
++              .of_match_table = of_match_ptr(samsung_pwm_matches),
++      },
++      .probe          = pwm_samsung_probe,
++      .remove         = pwm_samsung_remove,
++};
++module_platform_driver(pwm_samsung_driver);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Tomasz Figa <tomasz.figa@gmail.com>");
++MODULE_ALIAS("platform:samsung-pwm");
+diff --git a/include/clocksource/samsung_pwm.h b/include/clocksource/samsung_pwm.h
+index 5c449c8..0c7d48b 100644
+--- a/include/clocksource/samsung_pwm.h
++++ b/include/clocksource/samsung_pwm.h
+@@ -20,7 +20,14 @@
+ #define SAMSUNG_PWM_NUM               5
++/*
++ * Following declaration must be in an ifdef due to this symbol being static
++ * in pwm-samsung driver if the clocksource driver is not compiled in and the
++ * spinlock is not shared between both drivers.
++ */
++#ifdef CONFIG_CLKSRC_SAMSUNG_PWM
+ extern spinlock_t samsung_pwm_lock;
++#endif
+ struct samsung_pwm_variant {
+       u8 bits;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1009-pwm-Remove-superseded-pwm-samsung-legacy-driver.patch b/patches.tizen/1009-pwm-Remove-superseded-pwm-samsung-legacy-driver.patch
new file mode 100644 (file)
index 0000000..04c91cb
--- /dev/null
@@ -0,0 +1,396 @@
+From 28527b4a4abb993ed3a29c4beec31a202a773a02 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <tomasz.figa@gmail.com>
+Date: Sat, 6 Apr 2013 02:54:30 +0200
+Subject: [PATCH 1009/1302] pwm: Remove superseded pwm-samsung-legacy driver
+
+This patch removes the now unused pwm-samsung-legacy driver, which was
+replaced by new pwm-samsung driver.
+
+Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
+Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Tested-by: Heiko Stuebner <heiko@sntech.de>
+Tested-by: Mark Brown <broonie@linaro.org>
+Tested-by: Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/pwm/Makefile             |   1 -
+ drivers/pwm/pwm-samsung-legacy.c | 353 ---------------------------------------
+ 2 files changed, 354 deletions(-)
+ delete mode 100644 drivers/pwm/pwm-samsung-legacy.c
+
+diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
+index e2483e4..a025439 100644
+--- a/drivers/pwm/Makefile
++++ b/drivers/pwm/Makefile
+@@ -9,7 +9,6 @@ obj-$(CONFIG_PWM_LPC32XX)      += pwm-lpc32xx.o
+ obj-$(CONFIG_PWM_MXS)         += pwm-mxs.o
+ obj-$(CONFIG_PWM_PUV3)                += pwm-puv3.o
+ obj-$(CONFIG_PWM_PXA)         += pwm-pxa.o
+-obj-$(CONFIG_PWM_SAMSUNG)     += pwm-samsung-legacy.o
+ obj-$(CONFIG_PWM_SAMSUNG)     += pwm-samsung.o
+ obj-$(CONFIG_PWM_SPEAR)               += pwm-spear.o
+ obj-$(CONFIG_PWM_TEGRA)               += pwm-tegra.o
+diff --git a/drivers/pwm/pwm-samsung-legacy.c b/drivers/pwm/pwm-samsung-legacy.c
+deleted file mode 100644
+index a0ece50..0000000
+--- a/drivers/pwm/pwm-samsung-legacy.c
++++ /dev/null
+@@ -1,353 +0,0 @@
+-/* drivers/pwm/pwm-samsung.c
+- *
+- * Copyright (c) 2007 Ben Dooks
+- * Copyright (c) 2008 Simtec Electronics
+- *    Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
+- *
+- * S3C series PWM device core
+- *
+- * 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.
+-*/
+-
+-#define pr_fmt(fmt) "pwm-samsung: " fmt
+-
+-#include <linux/export.h>
+-#include <linux/kernel.h>
+-#include <linux/platform_device.h>
+-#include <linux/slab.h>
+-#include <linux/err.h>
+-#include <linux/clk.h>
+-#include <linux/io.h>
+-#include <linux/pwm.h>
+-
+-#include <mach/map.h>
+-
+-#include <plat/regs-timer.h>
+-
+-struct s3c_chip {
+-      struct platform_device  *pdev;
+-
+-      struct clk              *clk_div;
+-      struct clk              *clk;
+-      const char              *label;
+-
+-      unsigned int             period_ns;
+-      unsigned int             duty_ns;
+-
+-      unsigned char            tcon_base;
+-      unsigned char            pwm_id;
+-      struct pwm_chip          chip;
+-};
+-
+-#define to_s3c_chip(chip)     container_of(chip, struct s3c_chip, chip)
+-
+-#define pwm_dbg(_pwm, msg...) dev_dbg(&(_pwm)->pdev->dev, msg)
+-
+-static struct clk *clk_scaler[2];
+-
+-static inline int pwm_is_tdiv(struct s3c_chip *chip)
+-{
+-      return clk_get_parent(chip->clk) == chip->clk_div;
+-}
+-
+-#define pwm_tcon_start(pwm) (1 << (pwm->tcon_base + 0))
+-#define pwm_tcon_invert(pwm) (1 << (pwm->tcon_base + 2))
+-#define pwm_tcon_autoreload(pwm) (1 << (pwm->tcon_base + 3))
+-#define pwm_tcon_manulupdate(pwm) (1 << (pwm->tcon_base + 1))
+-
+-static int s3c_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+-{
+-      struct s3c_chip *s3c = to_s3c_chip(chip);
+-      unsigned long flags;
+-      unsigned long tcon;
+-
+-      local_irq_save(flags);
+-
+-      tcon = __raw_readl(S3C2410_TCON);
+-      tcon |= pwm_tcon_start(s3c);
+-      __raw_writel(tcon, S3C2410_TCON);
+-
+-      local_irq_restore(flags);
+-
+-      return 0;
+-}
+-
+-static void s3c_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+-{
+-      struct s3c_chip *s3c = to_s3c_chip(chip);
+-      unsigned long flags;
+-      unsigned long tcon;
+-
+-      local_irq_save(flags);
+-
+-      tcon = __raw_readl(S3C2410_TCON);
+-      tcon &= ~pwm_tcon_start(s3c);
+-      __raw_writel(tcon, S3C2410_TCON);
+-
+-      local_irq_restore(flags);
+-}
+-
+-static unsigned long pwm_calc_tin(struct s3c_chip *s3c, unsigned long freq)
+-{
+-      unsigned long tin_parent_rate;
+-      unsigned int div;
+-
+-      tin_parent_rate = clk_get_rate(clk_get_parent(s3c->clk_div));
+-      pwm_dbg(s3c, "tin parent at %lu\n", tin_parent_rate);
+-
+-      for (div = 2; div <= 16; div *= 2) {
+-              if ((tin_parent_rate / (div << 16)) < freq)
+-                      return tin_parent_rate / div;
+-      }
+-
+-      return tin_parent_rate / 16;
+-}
+-
+-#define NS_IN_HZ (1000000000UL)
+-
+-static int s3c_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+-              int duty_ns, int period_ns)
+-{
+-      struct s3c_chip *s3c = to_s3c_chip(chip);
+-      unsigned long tin_rate;
+-      unsigned long tin_ns;
+-      unsigned long period;
+-      unsigned long flags;
+-      unsigned long tcon;
+-      unsigned long tcnt;
+-      long tcmp;
+-
+-      /* We currently avoid using 64bit arithmetic by using the
+-       * fact that anything faster than 1Hz is easily representable
+-       * by 32bits. */
+-
+-      if (period_ns > NS_IN_HZ || duty_ns > NS_IN_HZ)
+-              return -ERANGE;
+-
+-      if (period_ns == s3c->period_ns &&
+-          duty_ns == s3c->duty_ns)
+-              return 0;
+-
+-      /* The TCMP and TCNT can be read without a lock, they're not
+-       * shared between the timers. */
+-
+-      tcmp = __raw_readl(S3C2410_TCMPB(s3c->pwm_id));
+-      tcnt = __raw_readl(S3C2410_TCNTB(s3c->pwm_id));
+-
+-      period = NS_IN_HZ / period_ns;
+-
+-      pwm_dbg(s3c, "duty_ns=%d, period_ns=%d (%lu)\n",
+-              duty_ns, period_ns, period);
+-
+-      /* Check to see if we are changing the clock rate of the PWM */
+-
+-      if (s3c->period_ns != period_ns) {
+-              if (pwm_is_tdiv(s3c)) {
+-                      tin_rate = pwm_calc_tin(s3c, period);
+-                      clk_set_rate(s3c->clk_div, tin_rate);
+-              } else
+-                      tin_rate = clk_get_rate(s3c->clk);
+-
+-              s3c->period_ns = period_ns;
+-
+-              pwm_dbg(s3c, "tin_rate=%lu\n", tin_rate);
+-
+-              tin_ns = NS_IN_HZ / tin_rate;
+-              tcnt = period_ns / tin_ns;
+-      } else
+-              tin_ns = NS_IN_HZ / clk_get_rate(s3c->clk);
+-
+-      /* Note, counters count down */
+-
+-      tcmp = duty_ns / tin_ns;
+-      tcmp = tcnt - tcmp;
+-      /* the pwm hw only checks the compare register after a decrement,
+-         so the pin never toggles if tcmp = tcnt */
+-      if (tcmp == tcnt)
+-              tcmp--;
+-
+-      pwm_dbg(s3c, "tin_ns=%lu, tcmp=%ld/%lu\n", tin_ns, tcmp, tcnt);
+-
+-      if (tcmp < 0)
+-              tcmp = 0;
+-
+-      /* Update the PWM register block. */
+-
+-      local_irq_save(flags);
+-
+-      __raw_writel(tcmp, S3C2410_TCMPB(s3c->pwm_id));
+-      __raw_writel(tcnt, S3C2410_TCNTB(s3c->pwm_id));
+-
+-      tcon = __raw_readl(S3C2410_TCON);
+-      tcon |= pwm_tcon_manulupdate(s3c);
+-      tcon |= pwm_tcon_autoreload(s3c);
+-      __raw_writel(tcon, S3C2410_TCON);
+-
+-      tcon &= ~pwm_tcon_manulupdate(s3c);
+-      __raw_writel(tcon, S3C2410_TCON);
+-
+-      local_irq_restore(flags);
+-
+-      return 0;
+-}
+-
+-static struct pwm_ops s3c_pwm_ops = {
+-      .enable = s3c_pwm_enable,
+-      .disable = s3c_pwm_disable,
+-      .config = s3c_pwm_config,
+-      .owner = THIS_MODULE,
+-};
+-
+-static int s3c_pwm_probe(struct platform_device *pdev)
+-{
+-      struct device *dev = &pdev->dev;
+-      struct s3c_chip *s3c;
+-      unsigned long flags;
+-      unsigned long tcon;
+-      unsigned int id = pdev->id;
+-      int ret;
+-
+-      if (id == 4) {
+-              dev_err(dev, "TIMER4 is currently not supported\n");
+-              return -ENXIO;
+-      }
+-
+-      s3c = devm_kzalloc(&pdev->dev, sizeof(*s3c), GFP_KERNEL);
+-      if (s3c == NULL) {
+-              dev_err(dev, "failed to allocate pwm_device\n");
+-              return -ENOMEM;
+-      }
+-
+-      /* calculate base of control bits in TCON */
+-      s3c->tcon_base = id == 0 ? 0 : (id * 4) + 4;
+-      s3c->pwm_id = id;
+-      s3c->chip.dev = &pdev->dev;
+-      s3c->chip.ops = &s3c_pwm_ops;
+-      s3c->chip.base = -1;
+-      s3c->chip.npwm = 1;
+-
+-      s3c->clk = devm_clk_get(dev, "pwm-tin");
+-      if (IS_ERR(s3c->clk)) {
+-              dev_err(dev, "failed to get pwm tin clk\n");
+-              return PTR_ERR(s3c->clk);
+-      }
+-
+-      s3c->clk_div = devm_clk_get(dev, "pwm-tdiv");
+-      if (IS_ERR(s3c->clk_div)) {
+-              dev_err(dev, "failed to get pwm tdiv clk\n");
+-              return PTR_ERR(s3c->clk_div);
+-      }
+-
+-      clk_enable(s3c->clk);
+-      clk_enable(s3c->clk_div);
+-
+-      local_irq_save(flags);
+-
+-      tcon = __raw_readl(S3C2410_TCON);
+-      tcon |= pwm_tcon_invert(s3c);
+-      __raw_writel(tcon, S3C2410_TCON);
+-
+-      local_irq_restore(flags);
+-
+-      ret = pwmchip_add(&s3c->chip);
+-      if (ret < 0) {
+-              dev_err(dev, "failed to register pwm\n");
+-              goto err_clk_tdiv;
+-      }
+-
+-      pwm_dbg(s3c, "config bits %02x\n",
+-              (__raw_readl(S3C2410_TCON) >> s3c->tcon_base) & 0x0f);
+-
+-      dev_info(dev, "tin at %lu, tdiv at %lu, tin=%sclk, base %d\n",
+-               clk_get_rate(s3c->clk),
+-               clk_get_rate(s3c->clk_div),
+-               pwm_is_tdiv(s3c) ? "div" : "ext", s3c->tcon_base);
+-
+-      platform_set_drvdata(pdev, s3c);
+-      return 0;
+-
+- err_clk_tdiv:
+-      clk_disable(s3c->clk_div);
+-      clk_disable(s3c->clk);
+-      return ret;
+-}
+-
+-static int s3c_pwm_remove(struct platform_device *pdev)
+-{
+-      struct s3c_chip *s3c = platform_get_drvdata(pdev);
+-      int err;
+-
+-      err = pwmchip_remove(&s3c->chip);
+-      if (err < 0)
+-              return err;
+-
+-      clk_disable(s3c->clk_div);
+-      clk_disable(s3c->clk);
+-
+-      return 0;
+-}
+-
+-#ifdef CONFIG_PM_SLEEP
+-static int s3c_pwm_suspend(struct device *dev)
+-{
+-      struct s3c_chip *s3c = dev_get_drvdata(dev);
+-
+-      /* No one preserve these values during suspend so reset them
+-       * Otherwise driver leaves PWM unconfigured if same values
+-       * passed to pwm_config
+-       */
+-      s3c->period_ns = 0;
+-      s3c->duty_ns = 0;
+-
+-      return 0;
+-}
+-
+-static int s3c_pwm_resume(struct device *dev)
+-{
+-      struct s3c_chip *s3c = dev_get_drvdata(dev);
+-      unsigned long tcon;
+-
+-      /* Restore invertion */
+-      tcon = __raw_readl(S3C2410_TCON);
+-      tcon |= pwm_tcon_invert(s3c);
+-      __raw_writel(tcon, S3C2410_TCON);
+-
+-      return 0;
+-}
+-#endif
+-
+-static SIMPLE_DEV_PM_OPS(s3c_pwm_pm_ops, s3c_pwm_suspend,
+-                      s3c_pwm_resume);
+-
+-static struct platform_driver s3c_pwm_driver = {
+-      .driver         = {
+-              .name   = "s3c24xx-pwm",
+-              .owner  = THIS_MODULE,
+-              .pm     = &s3c_pwm_pm_ops,
+-      },
+-      .probe          = s3c_pwm_probe,
+-      .remove         = s3c_pwm_remove,
+-};
+-
+-static int __init pwm_init(void)
+-{
+-      int ret;
+-
+-      clk_scaler[0] = clk_get(NULL, "pwm-scaler0");
+-      clk_scaler[1] = clk_get(NULL, "pwm-scaler1");
+-
+-      if (IS_ERR(clk_scaler[0]) || IS_ERR(clk_scaler[1])) {
+-              pr_err("failed to get scaler clocks\n");
+-              return -EINVAL;
+-      }
+-
+-      ret = platform_driver_register(&s3c_pwm_driver);
+-      if (ret)
+-              pr_err("failed to add pwm driver\n");
+-
+-      return ret;
+-}
+-
+-arch_initcall(pwm_init);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1010-pwm-Add-PWM-polarity-flag-macro-for-DT.patch b/patches.tizen/1010-pwm-Add-PWM-polarity-flag-macro-for-DT.patch
new file mode 100644 (file)
index 0000000..30a62e8
--- /dev/null
@@ -0,0 +1,63 @@
+From 124335d11ccdd3dd7b62fc45d0933553496eaeba Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
+Date: Thu, 18 Jul 2013 00:54:21 +0200
+Subject: [PATCH 1010/1302] pwm: Add PWM polarity flag macro for DT
+
+Define a PWM_POLARITY_INVERTED macro in include/dt-bindings/pwm/pwm.h to
+be used by device tree sources.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
+Reviewed-by: Stephen Warren <swarren@nvidia.com>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/devicetree/bindings/pwm/pwm.txt |  7 ++++---
+ include/dt-bindings/pwm/pwm.h                 | 14 ++++++++++++++
+ 2 files changed, 18 insertions(+), 3 deletions(-)
+ create mode 100644 include/dt-bindings/pwm/pwm.h
+
+diff --git a/Documentation/devicetree/bindings/pwm/pwm.txt b/Documentation/devicetree/bindings/pwm/pwm.txt
+index 06e6724..8556263 100644
+--- a/Documentation/devicetree/bindings/pwm/pwm.txt
++++ b/Documentation/devicetree/bindings/pwm/pwm.txt
+@@ -43,13 +43,14 @@ because the name "backlight" would be used as fallback anyway.
+ pwm-specifier typically encodes the chip-relative PWM number and the PWM
+ period in nanoseconds.
+-Optionally, the pwm-specifier can encode a number of flags in a third cell:
+-- bit 0: PWM signal polarity (0: normal polarity, 1: inverse polarity)
++Optionally, the pwm-specifier can encode a number of flags (defined in
++<dt-bindings/pwm/pwm.h>) in a third cell:
++- PWM_POLARITY_INVERTED: invert the PWM signal polarity
+ Example with optional PWM specifier for inverse polarity
+       bl: backlight {
+-              pwms = <&pwm 0 5000000 1>;
++              pwms = <&pwm 0 5000000 PWM_POLARITY_INVERTED>;
+               pwm-names = "backlight";
+       };
+diff --git a/include/dt-bindings/pwm/pwm.h b/include/dt-bindings/pwm/pwm.h
+new file mode 100644
+index 0000000..96f49e8
+--- /dev/null
++++ b/include/dt-bindings/pwm/pwm.h
+@@ -0,0 +1,14 @@
++/*
++ * This header provides constants for most PWM bindings.
++ *
++ * Most PWM bindings can include a flags cell as part of the PWM specifier.
++ * In most cases, the format of the flags cell uses the standard values
++ * defined in this header.
++ */
++
++#ifndef _DT_BINDINGS_PWM_PWM_H
++#define _DT_BINDINGS_PWM_PWM_H
++
++#define PWM_POLARITY_INVERTED                 (1 << 0)
++
++#endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1011-ARM-dts-add-clocks-and-enable-pwm-for-exynos4.patch b/patches.tizen/1011-ARM-dts-add-clocks-and-enable-pwm-for-exynos4.patch
new file mode 100644 (file)
index 0000000..a3b1b6a
--- /dev/null
@@ -0,0 +1,34 @@
+From b9d60b42a2ca9dd47a57b3f50006d60b3e3ec2bf Mon Sep 17 00:00:00 2001
+From: Sangjung Woo <sangjung.woo@samsung.com>
+Date: Tue, 5 Nov 2013 10:48:07 +0900
+Subject: [PATCH 1011/1302] ARM: dts: add clocks and enable pwm for exynos4
+
+This patch adds clocks for PWM(Pulse width modulation) timer and enable
+it.
+
+Signed-off-by: Sangjung Woo <sangjung.woo@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index 64c93e5..47605f1 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -489,8 +489,11 @@
+               compatible = "samsung,exynos4210-pwm";
+               reg = <0x139D0000 0x1000>;
+               interrupts = <0 37 0>, <0 38 0>, <0 39 0>, <0 40 0>, <0 41 0>;
++              clocks = <&clock 336>;
++              clock-names = "timers";
+               #pwm-cells = <2>;
+-              status = "disabled";
++              samsung,pwm-outputs = <0>;
++              status = "ok";
+       };
+       hsotg@12480000 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1012-pwm-samsung-memory-leak-bugfix-in-pwm_samsung_free.patch b/patches.tizen/1012-pwm-samsung-memory-leak-bugfix-in-pwm_samsung_free.patch
new file mode 100644 (file)
index 0000000..e68d717
--- /dev/null
@@ -0,0 +1,34 @@
+From 38d35de94bd0778f1b68b2183c04fef2b585629d Mon Sep 17 00:00:00 2001
+From: Sangjung Woo <sangjung.woo@samsung.com>
+Date: Tue, 5 Nov 2013 11:08:34 +0900
+Subject: [PATCH 1012/1302] pwm: samsung: memory leak bugfix in
+ pwm_samsung_free
+
+There is certainly a kind of memory leak since allocated data (i.e.
+chip_data) is set NULL before freeing it by calling devm_kfree().This
+patch fixes the memory leak bug by modifying its call order.
+
+Signed-off-by: Sangjung Woo <sangjung.woo@samsung.com>
+Reviewed-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/pwm/pwm-samsung.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c
+index fcc8b9a..07b2d9d 100644
+--- a/drivers/pwm/pwm-samsung.c
++++ b/drivers/pwm/pwm-samsung.c
+@@ -224,8 +224,8 @@ static int pwm_samsung_request(struct pwm_chip *chip, struct pwm_device *pwm)
+ static void pwm_samsung_free(struct pwm_chip *chip, struct pwm_device *pwm)
+ {
+-      pwm_set_chip_data(pwm, NULL);
+       devm_kfree(chip->dev, pwm_get_chip_data(pwm));
++      pwm_set_chip_data(pwm, NULL);
+ }
+ static int pwm_samsung_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1013-arm-Thumb-ARM-signal-handling-setup-skips-the-a-few-.patch b/patches.tizen/1013-arm-Thumb-ARM-signal-handling-setup-skips-the-a-few-.patch
new file mode 100644 (file)
index 0000000..9481f9a
--- /dev/null
@@ -0,0 +1,76 @@
+From 0bdc4f4130b4b8f9ca5f0453979b15447765573f Mon Sep 17 00:00:00 2001
+From: "T.J. Purtell" <tj@mobisocial.us>
+Date: Tue, 5 Nov 2013 16:52:10 +0900
+Subject: [PATCH 1013/1302] arm: Thumb=>ARM signal handling setup skips the a
+ few instructions on Snapdragon S4/Krait
+
+The Thumb instruction set include an If-Then instruction.  If an ARM
+function is registered as a signal handler, and that signal is
+delivered inside the block of instructions follow the IT instruction,
+some of the instructions at the beginning of the signal handler are
+skipped.  This occurs because the IT state bits of the Program Status
+Register are not cleared by the kernel.
+
+The ARM architecture reference specifies that the IT state bits in the
+PSR must be all zeros in ARM mode or behavior is unspecified.  On the
+Qualcomm Snapdragon S4/Krait architecture CPUs the processor continues
+to consider the IT state bits while in ARM mode.  This makes it so
+that some instructions are skipped by the CPU.
+
+The relevant clipping of the ARM architecture  document is available
+here: https://www.dropbox.com/s/6hpwey3kklw20c1/ITState-ARM-Architecture.pdf
+
+This manifests itself in code that uses a lot of signal handling
+concurrently with complicated logic code compiled for thumb when the
+signal handler compiled as ARM code.  One example is the mono runtime.
+ It uses a signal based mechanism to perform stop the world operation
+needed by its garbage collector.  It is compiled for ARM and generates
+ARM code, however, bionic (libc for android) is compiled for thumb.
+During a test case involving native allocation in parallel with
+garbage collection (signal handling), we found that the test case
+would crash only when running on a Krait architecture CPU.  We found
+the preceding instructions before the signal to always point to
+something inside an IT sequence, in this case the logic in the dlfree
+merging of free heap blocks.  After adding a sequence of NOPs to the
+beginning of the signal handlers, the problem disappeared.  We applied
+the attached patch to the kernel on one of the Krait devices and found
+that it also alleviated the crashes.
+
+The patch simply clears the IT State bits regardless of if the signal
+handler is an ARM/Thumb function.  It also includes the same fix
+applied to the arm64 compat handler.
+
+Signed-off-by: T.J. Purtell <tj@mobisocial.us>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/kernel/signal.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
+index 5a42c12..b1fb338 100644
+--- a/arch/arm/kernel/signal.c
++++ b/arch/arm/kernel/signal.c
+@@ -375,12 +375,16 @@ setup_return(struct pt_regs *regs, struct ksignal *ksig,
+                */
+               thumb = handler & 1;
+-              if (thumb) {
+-                      cpsr |= PSR_T_BIT;
+ #if __LINUX_ARM_ARCH__ >= 7
+-                      /* clear the If-Then Thumb-2 execution state */
+-                      cpsr &= ~PSR_IT_MASK;
++              /*
++               * Clear the If-Then Thumb-2 execution state
++               * ARM spec requires this to be all 000s in ARM mode
++              */
++              cpsr &= ~PSR_IT_MASK;
+ #endif
++
++              if (thumb) {
++                      cpsr |= PSR_T_BIT;
+               } else
+                       cpsr &= ~PSR_T_BIT;
+       }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1014-mmc-sdhci-s3c-Revised-sdhci_s3c_remove-function.patch b/patches.tizen/1014-mmc-sdhci-s3c-Revised-sdhci_s3c_remove-function.patch
new file mode 100644 (file)
index 0000000..2ef93eb
--- /dev/null
@@ -0,0 +1,41 @@
+From fb62dd3925bc704a5ec9562a8887e3a1e71fc19f Mon Sep 17 00:00:00 2001
+From: Beomho Seo <beomho.seo@samsung.com>
+Date: Tue, 5 Nov 2013 20:51:00 +0900
+Subject: [PATCH 1014/1302] mmc: sdhci-s3c: Revised sdhci_s3c_remove function.
+
+Remove "return ret;" from "err_req_cd:".
+Revised sdhci_s3c_remove function.
+
+Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mmc/host/sdhci-s3c.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
+index c2a7383..acc0099 100644
+--- a/drivers/mmc/host/sdhci-s3c.c
++++ b/drivers/mmc/host/sdhci-s3c.c
+@@ -667,8 +667,6 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
+  err_req_cd:
+       mmc_gpio_free_cd(host->mmc);
+-      return ret;
+-
+  err_req_regs:
+ #ifndef CONFIG_PM_RUNTIME
+       clk_disable_unprepare(sc->clk_bus[sc->cur_clk]);
+@@ -692,8 +690,8 @@ static int sdhci_s3c_remove(struct platform_device *pdev)
+       if (pdata->cd_type == S3C_SDHCI_CD_EXTERNAL && pdata->ext_cd_cleanup)
+               pdata->ext_cd_cleanup(&sdhci_s3c_notify_change);
+-      if (sc->ext_cd_irq)
+-              free_irq(sc->ext_cd_irq, sc);
++      if (pdata->ext_cd_gpio)
++              mmc_gpio_free_cd(host->mmc);
+ #ifdef CONFIG_PM_RUNTIME
+       if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1015-config-tizen-Enable-CONFIG_BRCMFMAC-for-supporting-W.patch b/patches.tizen/1015-config-tizen-Enable-CONFIG_BRCMFMAC-for-supporting-W.patch
new file mode 100644 (file)
index 0000000..6cb79d3
--- /dev/null
@@ -0,0 +1,33 @@
+From 28357a308c59db990c3000c4d6e17a9020523ea1 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Thu, 7 Nov 2013 16:51:07 +0900
+Subject: [PATCH 1015/1302] config: tizen: Enable CONFIG_BRCMFMAC for
+ supporting WIFI on M0
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_defconfig | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index 41b4304..a6559b1 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -1379,7 +1379,12 @@ CONFIG_WLAN=y
+ # CONFIG_USB_ZD1201 is not set
+ # CONFIG_USB_NET_RNDIS_WLAN is not set
+ # CONFIG_ATH_CARDS is not set
+-# CONFIG_BRCMFMAC is not set
++CONFIG_BRCMUTIL=m
++CONFIG_BRCMFMAC=m
++CONFIG_BRCMFMAC_SDIO=y
++# CONFIG_BRCMFMAC_USB is not set
++# CONFIG_BRCM_TRACING is not set
++# CONFIG_BRCMDBG is not set
+ # CONFIG_HOSTAP is not set
+ # CONFIG_LIBERTAS is not set
+ # CONFIG_WL_TI is not set
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1016-cpufreq-M0-Allow-sailable-frequency-up-to-1.4Ghz-M0.patch b/patches.tizen/1016-cpufreq-M0-Allow-sailable-frequency-up-to-1.4Ghz-M0.patch
new file mode 100644 (file)
index 0000000..74450fa
--- /dev/null
@@ -0,0 +1,33 @@
+From c015593300e5f8f31bd21b625b70ac1de1eb46a5 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Fri, 8 Nov 2013 10:51:00 +0900
+Subject: [PATCH 1016/1302] cpufreq : M0: Allow sailable frequency up to 1.4Ghz
+ @ M0
+
+Signed-off-by : Jonghwa Lee <jonghwa3.lee@samsung.com>
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-m0.dts | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-m0.dts b/arch/arm/boot/dts/exynos4412-m0.dts
+index 4ec07fc..4bf6677 100644
+--- a/arch/arm/boot/dts/exynos4412-m0.dts
++++ b/arch/arm/boot/dts/exynos4412-m0.dts
+@@ -216,6 +216,12 @@
+               };
+       };
++      cpufreq {
++              freq_table = <1400000 1300000 1200000 1100000 1000000
++                           900000 800000 700000 600000 500000 400000 300000
++                           200000>;
++      };
++
+       thermistor-ap@0 {
+               compatible = "ntc,ncp03wb473";
+               status = "ok";
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1017-cpufreq-LAB-Introduce-new-cpufreq-LAB-Legaccy-Applic.patch b/patches.tizen/1017-cpufreq-LAB-Introduce-new-cpufreq-LAB-Legaccy-Applic.patch
new file mode 100644 (file)
index 0000000..578d953
--- /dev/null
@@ -0,0 +1,663 @@
+From 2638e0bd78008199690955dd2ad5ef052ab984ae Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Fri, 8 Nov 2013 16:20:45 +0900
+Subject: [PATCH 1017/1302] cpufreq:LAB: Introduce new cpufreq LAB(Legaccy 
+ Application Boost) governor
+
+This patch introduces new cpufreq governor named 'LAB'.
+LAB governor will use scheduler, per-CPU information to determine how many
+CPUs are in busy now. As a result the number of idle CPUs is calculated
+for current load (digital low pass filtering is used to provide more stable
+results). It will determine next frequency.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+
+Conflicts:
+
+       drivers/cpufreq/cpufreq_governor.c
+Resolved-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/Kconfig            |  26 +++
+ drivers/cpufreq/Makefile           |   1 +
+ drivers/cpufreq/cpufreq_governor.c |  72 +++----
+ drivers/cpufreq/cpufreq_governor.h |  17 ++
+ drivers/cpufreq/cpufreq_lab.c      | 377 +++++++++++++++++++++++++++++++++++++
+ include/linux/cpufreq.h            |   3 +
+ 6 files changed, 464 insertions(+), 32 deletions(-)
+ create mode 100644 drivers/cpufreq/cpufreq_lab.c
+
+diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
+index 79ebd97..9ee9d3c 100644
+--- a/drivers/cpufreq/Kconfig
++++ b/drivers/cpufreq/Kconfig
+@@ -116,6 +116,18 @@ config CPU_FREQ_DEFAULT_GOV_CONSERVATIVE
+         Be aware that not all cpufreq drivers support the conservative
+         governor. If unsure have a look at the help section of the
+         driver. Fallback governor will be the performance governor.
++
++config CPU_FREQ_DEFAULT_GOV_LAB
++      bool "lab"
++      select CPU_FREQ_GOV_LAB
++      select CPU_FREQ_GOV_PERFORMANCE
++      help
++        Use the CPUFreq governor 'lab' as default. This allows
++        you to get a full dynamic frequency capable system by simply
++        loading your cpufreq low-level hardware driver.
++        Be aware that not all cpufreq drivers support the lab governor.
++        If unsure have a look at the help section of the driver.
++        Fallback governor will be the performance governor.
+ endchoice
+ config CPU_FREQ_GOV_PERFORMANCE
+@@ -198,6 +210,20 @@ config CPU_FREQ_GOV_CONSERVATIVE
+         If in doubt, say N.
++config CPU_FREQ_GOV_LAB
++      tristate "'lab' cpufreq policy governor"
++      select CPU_FREQ_TABLE
++      select CPU_FREQ_GOV_COMMON
++      help
++        'lab' - This driver adds a dynamic cpufreq policy governor.
++
++        To compile this driver as a module, choose M here: the
++        module will be called cpufreq_ondemand.
++
++        For details, take a look at linux/Documentation/cpu-freq.
++
++        If in doubt, say N.
++
+ config GENERIC_CPUFREQ_CPU0
+       tristate "Generic CPU0 cpufreq driver"
+       depends on HAVE_CLK && REGULATOR && PM_OPP && OF
+diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
+index 315b923..d8252a7 100644
+--- a/drivers/cpufreq/Makefile
++++ b/drivers/cpufreq/Makefile
+@@ -9,6 +9,7 @@ obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE)   += cpufreq_powersave.o
+ obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE)  += cpufreq_userspace.o
+ obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND)   += cpufreq_ondemand.o
+ obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE)       += cpufreq_conservative.o
++obj-$(CONFIG_CPU_FREQ_GOV_LAB)                += cpufreq_lab.o
+ obj-$(CONFIG_CPU_FREQ_GOV_COMMON)             += cpufreq_governor.o
+ # CPUfreq cross-arch helpers
+diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
+index a593bb4..86a3816 100644
+--- a/drivers/cpufreq/cpufreq_governor.c
++++ b/drivers/cpufreq/cpufreq_governor.c
+@@ -148,6 +148,13 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu)
+               load = 100 * (wall_time - idle_time) / wall_time;
++              if (dbs_data->cdata->governor == GOV_LAB) {
++                      struct lb_cpu_dbs_info_s *lb_dbs_info =
++                              dbs_data->cdata->get_cpu_dbs_info_s(j);
++
++                      lb_dbs_info->idle_time = (100 * idle_time) / wall_time;
++              }
++
+               if (dbs_data->cdata->governor == GOV_ONDEMAND) {
+                       int freq_avg = __cpufreq_driver_getavg(policy, j);
+                       if (freq_avg <= 0)
+@@ -235,13 +242,16 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
+       struct dbs_data *dbs_data;
+       struct od_cpu_dbs_info_s *od_dbs_info = NULL;
+       struct cs_cpu_dbs_info_s *cs_dbs_info = NULL;
++      struct lb_cpu_dbs_info_s *lb_dbs_info = NULL;
+       struct od_ops *od_ops = NULL;
+       struct od_dbs_tuners *od_tuners = NULL;
+       struct cs_dbs_tuners *cs_tuners = NULL;
++      struct lb_dbs_tuners *lb_tuners = NULL;
+       struct cpu_dbs_common_info *cpu_cdbs;
+-      unsigned int sampling_rate, latency, ignore_nice, j, cpu = policy->cpu;
++      unsigned int sampling_rate = 0, ignore_nice = 0, latency, j, cpu = policy->cpu;
+       int io_busy = 0;
+       int rc;
++      int governor = cdata->governor;
+       if (have_governor_per_policy())
+               dbs_data = policy->governor_data;
+@@ -299,7 +309,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
+               set_sampling_rate(dbs_data, max(dbs_data->min_sampling_rate,
+                                       latency * LATENCY_MULTIPLIER));
+-              if ((cdata->governor == GOV_CONSERVATIVE) &&
++              if ((governor == GOV_CONSERVATIVE) &&
+                               (!policy->governor->initialized)) {
+                       struct cs_ops *cs_ops = dbs_data->cdata->gov_ops;
+@@ -319,7 +329,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
+                       if (!have_governor_per_policy())
+                               cpufreq_put_global_kobject();
+-                      if ((dbs_data->cdata->governor == GOV_CONSERVATIVE) &&
++                      if ((governor == GOV_CONSERVATIVE) &&
+                               (policy->governor->initialized == 1)) {
+                               struct cs_ops *cs_ops = dbs_data->cdata->gov_ops;
+@@ -338,25 +348,37 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
+       cpu_cdbs = dbs_data->cdata->get_cpu_cdbs(cpu);
+-      if (dbs_data->cdata->governor == GOV_CONSERVATIVE) {
+-              cs_tuners = dbs_data->tuners;
+-              cs_dbs_info = dbs_data->cdata->get_cpu_dbs_info_s(cpu);
+-              sampling_rate = cs_tuners->sampling_rate;
+-              ignore_nice = cs_tuners->ignore_nice_load;
+-      } else {
+-              od_tuners = dbs_data->tuners;
+-              od_dbs_info = dbs_data->cdata->get_cpu_dbs_info_s(cpu);
+-              sampling_rate = od_tuners->sampling_rate;
+-              ignore_nice = od_tuners->ignore_nice_load;
+-              od_ops = dbs_data->cdata->gov_ops;
+-              io_busy = od_tuners->io_is_busy;
+-      }
+-
+       switch (event) {
+       case CPUFREQ_GOV_START:
+               if (!policy->cur)
+                       return -EINVAL;
++              if (governor == GOV_CONSERVATIVE) {
++                      cs_tuners = dbs_data->tuners;
++                      cs_dbs_info = dbs_data->cdata->get_cpu_dbs_info_s(cpu);
++                      cs_dbs_info->down_skip = 0;
++                      cs_dbs_info->requested_freq = policy->cur;
++                      sampling_rate = cs_tuners->sampling_rate;
++                      ignore_nice = cs_tuners->ignore_nice_load;
++                      cs_dbs_info->enable = 1;
++              } else if (governor == GOV_ONDEMAND) {
++                      od_tuners = dbs_data->tuners;
++                      od_dbs_info = dbs_data->cdata->get_cpu_dbs_info_s(cpu);
++                      od_dbs_info->rate_mult = 1;
++                      od_dbs_info->sample_type = OD_NORMAL_SAMPLE;
++                      sampling_rate = od_tuners->sampling_rate;
++                      ignore_nice = od_tuners->ignore_nice_load;
++                      od_ops = dbs_data->cdata->gov_ops;
++                      io_busy = od_tuners->io_is_busy;
++                      od_ops->powersave_bias_init_cpu(cpu);
++              } else {
++                      lb_tuners = dbs_data->tuners;
++                      lb_dbs_info = dbs_data->cdata->get_cpu_dbs_info_s(cpu);
++                      lb_dbs_info->rate_mult = 1;
++                      sampling_rate = lb_tuners->sampling_rate;
++                      ignore_nice = lb_tuners->ignore_nice;
++              }
++
+               mutex_lock(&dbs_data->mutex);
+               for_each_cpu(j, policy->cpus) {
+@@ -376,20 +398,6 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
+                                            dbs_data->cdata->gov_dbs_timer);
+               }
+-              /*
+-               * conservative does not implement micro like ondemand
+-               * governor, thus we are bound to jiffes/HZ
+-               */
+-              if (dbs_data->cdata->governor == GOV_CONSERVATIVE) {
+-                      cs_dbs_info->down_skip = 0;
+-                      cs_dbs_info->enable = 1;
+-                      cs_dbs_info->requested_freq = policy->cur;
+-              } else {
+-                      od_dbs_info->rate_mult = 1;
+-                      od_dbs_info->sample_type = OD_NORMAL_SAMPLE;
+-                      od_ops->powersave_bias_init_cpu(cpu);
+-              }
+-
+               mutex_unlock(&dbs_data->mutex);
+               /* Initiate timer time stamp */
+@@ -400,7 +408,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
+               break;
+       case CPUFREQ_GOV_STOP:
+-              if (dbs_data->cdata->governor == GOV_CONSERVATIVE)
++              if (governor == GOV_CONSERVATIVE)
+                       cs_dbs_info->enable = 0;
+               gov_cancel_work(dbs_data, policy);
+diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h
+index 0d9e6be..09d9603 100644
+--- a/drivers/cpufreq/cpufreq_governor.h
++++ b/drivers/cpufreq/cpufreq_governor.h
+@@ -163,6 +163,14 @@ struct cs_cpu_dbs_info_s {
+       unsigned int enable:1;
+ };
++struct lb_cpu_dbs_info_s {
++      struct cpu_dbs_common_info cdbs;
++      u64 prev_cpu_iowait;
++      struct cpufreq_frequency_table *freq_table;
++      unsigned int rate_mult;
++      unsigned int idle_time;
++};
++
+ /* Per policy Governers sysfs tunables */
+ struct od_dbs_tuners {
+       unsigned int ignore_nice_load;
+@@ -183,12 +191,21 @@ struct cs_dbs_tuners {
+       unsigned int freq_step;
+ };
++struct lb_dbs_tuners {
++      unsigned int ignore_nice;
++      unsigned int sampling_rate;
++      unsigned int sampling_down_factor;
++      unsigned int up_threshold;
++      unsigned int adj_up_threshold;
++};
++
+ /* Common Governer data across policies */
+ struct dbs_data;
+ struct common_dbs_data {
+       /* Common across governors */
+       #define GOV_ONDEMAND            0
+       #define GOV_CONSERVATIVE        1
++      #define GOV_LAB                 2
+       int governor;
+       struct attribute_group *attr_group_gov_sys; /* one governor - system */
+       struct attribute_group *attr_group_gov_pol; /* one governor - policy */
+diff --git a/drivers/cpufreq/cpufreq_lab.c b/drivers/cpufreq/cpufreq_lab.c
+new file mode 100644
+index 0000000..3fe876b
+--- /dev/null
++++ b/drivers/cpufreq/cpufreq_lab.c
+@@ -0,0 +1,377 @@
++/*
++ *  drivers/cpufreq/cpufreq_lab.c
++ *
++ *  LAB(Legacy Application Boost) cpufreq governor
++ *
++ *  Copyright (C) SAMSUNG Electronics. CO.
++ *            Jonghwa Lee <jonghw3.lee@samusng.com>
++ *            Lukasz Majewski <l.majewski@samsung.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.
++ */
++
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/cpufreq.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/kernel_stat.h>
++#include <linux/kobject.h>
++#include <linux/module.h>
++#include <linux/mutex.h>
++#include <linux/percpu-defs.h>
++#include <linux/sysfs.h>
++#include <linux/tick.h>
++#include <linux/types.h>
++#include <linux/cpuidle.h>
++#include <linux/slab.h>
++
++#include "cpufreq_governor.h"
++
++#define DEF_FREQUENCY_DOWN_DIFFERENTIAL               (10)
++#define DEF_FREQUENCY_UP_THRESHOLD            (80)
++#define DEF_SAMPLING_DOWN_FACTOR              (1)
++#define MICRO_FREQUENCY_DOWN_DIFFERENTIAL     (3)
++#define MICRO_FREQUENCY_UP_THRESHOLD          (95)
++#define MICRO_FREQUENCY_MIN_SAMPLE_RATE               (10000)
++
++#define MAX_HIST              5
++#define FREQ_STEP             50000
++#define IDLE_THRESHOLD                90
++
++/* Pre-calculated summation of weight, 0.5
++ * 1
++ * 1 + 0.5^1 = 1.5
++ * 1 + 0.5^1 + 0.5^2 = 1.75
++ * 1 + 0.5^1 + 0.5^2 + 0.5^3 = 1.87
++ * 1 + 0.5^1 + 0.5^2 + 0.5^3 + 0.5^4 = 1.93
++ */
++static int history_weight_sum[] = { 100, 150, 175, 187, 193 };
++
++static unsigned int idle_avg[NR_CPUS];
++static unsigned int idle_hist[NR_CPUS][MAX_HIST];
++
++static DEFINE_PER_CPU(struct lb_cpu_dbs_info_s, lb_cpu_dbs_info);
++
++#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_LAB
++static struct cpufreq_governor cpufreq_gov_lab;
++#endif
++
++/* Single polynomial approx -> all CPUs busy */
++static int a_all = -6, b_all = 1331;
++/* Single polynomial approx -> one CPUs busy */
++static int a_one = 10, b_one = 205;
++/* Single polynomial approx -> 2,3... CPUs busy */
++static int a_rest = 4, b_rest1 = 100, b_rest2 = 300;
++/* Polynomial divider */
++static int poly_div = 1024;
++
++static void dbs_freq_increase(struct cpufreq_policy *p, unsigned int freq)
++{
++      if (p->cur == freq)
++              return;
++
++      __cpufreq_driver_target(p, freq, CPUFREQ_RELATION_L);
++}
++
++/* Calculate average of idle time with weighting 50% less to older one.
++ * With weight, average can be affected by current phase more rapidly than
++ * normal average. And it also has tolerance for temporary fluctuation of
++ * idle time as normal average has.
++ *
++ * Weigted average = sum(ai * wi) / sum(wi)
++ */
++static inline int cpu_idle_calc_avg(unsigned int *p, int size)
++{
++      int i, sum;
++
++      for (i = 0, sum = 0; i < size; p++, i++) {
++              sum += *p;
++              *p >>= 1;
++      }
++      sum *= 100;
++
++      return (int) (sum / history_weight_sum[size - 1]);
++}
++
++/*
++ * LAB governor policy adjustement
++ */
++static void lb_check_cpu(int cpu, unsigned int load_freq)
++{
++      struct lb_cpu_dbs_info_s *dbs_info = &per_cpu(lb_cpu_dbs_info, cpu);
++      struct cpufreq_policy *policy = dbs_info->cdbs.cur_policy;
++      int i, idx, idle_cpus = 0, b = 0;
++      static int cnt = 0;
++      unsigned int freq = 0;
++
++      idx = cnt++ % MAX_HIST;
++
++      for_each_possible_cpu(i) {
++              struct lb_cpu_dbs_info_s *dbs_cpu_info =
++                      &per_cpu(lb_cpu_dbs_info, i);
++
++              idle_hist[i][idx] = dbs_cpu_info->idle_time;
++              idle_avg[i] = cpu_idle_calc_avg(idle_hist[i],
++                                      cnt < MAX_HIST ? cnt : MAX_HIST);
++
++              if (idle_avg[i] > IDLE_THRESHOLD)
++                      idle_cpus++;
++      }
++
++      if (idle_cpus < 0 || idle_cpus > NR_CPUS) {
++              pr_warn("idle_cpus: %d out of range\n", idle_cpus);
++              return;
++      }
++
++      if (idle_cpus == 0) {
++              /* Full load -> reduce freq */
++              freq = policy->max * (a_all * load_freq + b_all) / poly_div;
++      } else if (idle_cpus == NR_CPUS) {
++              /* Idle cpus */
++              freq = policy->min;
++      } else if (idle_cpus == (NR_CPUS - 1)) {
++              freq = policy->max * (a_one * load_freq + b_one) / poly_div;
++      } else {
++              /* Adjust frequency with number of available CPUS */
++              /* smaller idle_cpus -> smaller frequency */
++              b = ((idle_cpus - 1) * b_rest1) + b_rest2;
++              freq = policy->max * (a_rest * load_freq + b) / poly_div;
++      }
++#if 0 
++      if (!idx)
++              pr_info("p->max:%d,freq: %d,idle_cpus: %d,avg : %d %d %d %d load_f: %d\n",
++                     policy->max, freq, idle_cpus, idle_avg[0], idle_avg[1],
++                      idle_avg[2], idle_avg[3], load_freq);
++#endif
++
++      dbs_freq_increase(policy, freq);
++}
++
++static void lb_dbs_timer(struct work_struct *work)
++{
++      struct lb_cpu_dbs_info_s *dbs_info =
++              container_of(work, struct lb_cpu_dbs_info_s, cdbs.work.work);
++      unsigned int cpu = dbs_info->cdbs.cur_policy->cpu;
++      struct lb_cpu_dbs_info_s *core_dbs_info = &per_cpu(lb_cpu_dbs_info,
++                      cpu);
++      struct dbs_data *dbs_data = dbs_info->cdbs.cur_policy->governor_data;
++      struct lb_dbs_tuners *lb_tuners = dbs_data->tuners;
++      int delay;
++
++      mutex_lock(&core_dbs_info->cdbs.timer_mutex);
++
++      dbs_check_cpu(dbs_data, cpu);
++
++      delay = delay_for_sampling_rate(lb_tuners->sampling_rate
++                                              * core_dbs_info->rate_mult);
++
++      gov_queue_work(dbs_data, dbs_info->cdbs.cur_policy, delay, false);
++      mutex_unlock(&core_dbs_info->cdbs.timer_mutex);
++}
++
++/************************** sysfs interface ************************/
++static struct common_dbs_data lb_dbs_cdata;
++
++/**
++ * update_sampling_rate - update sampling rate effective immediately if needed.
++ * @new_rate: new sampling rate
++ *
++ * If new rate is smaller than the old, simply updating
++ * dbs_tuners_int.sampling_rate might not be appropriate. For example, if the
++ * original sampling_rate was 1 second and the requested new sampling rate is 10
++ * ms because the user needs immediate reaction from lab governor, but not
++ * sure if higher frequency will be required or not, then, the governor may
++ * change the sampling rate too late; up to 1 second later. Thus, if we are
++ * reducing the sampling rate, we need to make the new value effective
++ * immediately.
++ */
++static void update_sampling_rate(struct dbs_data *dbs_data,
++                      unsigned int new_rate)
++{
++      struct lb_dbs_tuners *lb_tuners = dbs_data->tuners;
++      int cpu;
++
++      lb_tuners->sampling_rate = new_rate = max(new_rate,
++                      dbs_data->min_sampling_rate);
++
++      for_each_online_cpu(cpu) {
++              struct cpufreq_policy *policy;
++              struct lb_cpu_dbs_info_s *dbs_info;
++              unsigned long next_sampling, appointed_at;
++
++              policy = cpufreq_cpu_get(cpu);
++              if (!policy)
++                      continue;
++              if (policy->governor != &cpufreq_gov_lab) {
++                      cpufreq_cpu_put(policy);
++                      continue;
++              }
++              dbs_info = &per_cpu(lb_cpu_dbs_info, cpu);
++              cpufreq_cpu_put(policy);
++
++              mutex_lock(&dbs_info->cdbs.timer_mutex);
++
++              if (!delayed_work_pending(&dbs_info->cdbs.work)) {
++                      mutex_unlock(&dbs_info->cdbs.timer_mutex);
++                      continue;
++              }
++
++              next_sampling = jiffies + usecs_to_jiffies(new_rate);
++              appointed_at = dbs_info->cdbs.work.timer.expires;
++
++              if (time_before(next_sampling, appointed_at)) {
++
++                      mutex_unlock(&dbs_info->cdbs.timer_mutex);
++                      cancel_delayed_work_sync(&dbs_info->cdbs.work);
++                      mutex_lock(&dbs_info->cdbs.timer_mutex);
++
++                      schedule_delayed_work_on(cpu, &dbs_info->cdbs.work,
++                                      usecs_to_jiffies(new_rate));
++
++              }
++              mutex_unlock(&dbs_info->cdbs.timer_mutex);
++      }
++}
++
++static ssize_t store_sampling_rate(struct dbs_data *dbs_data, const char *buf,
++                              size_t count)
++{
++      unsigned int input;
++      int ret;
++      ret = sscanf(buf, "%u", &input);
++      if (ret != 1)
++              return -EINVAL;
++
++      update_sampling_rate(dbs_data, input);
++      return count;
++}
++
++show_store_one(lb, sampling_rate);
++gov_sys_pol_attr_rw(sampling_rate);
++
++static struct attribute *dbs_attributes_gov_sys[] = {
++      &sampling_rate_gov_sys.attr,
++      NULL
++};
++
++static struct attribute_group lb_attr_group_gov_sys = {
++      .attrs = dbs_attributes_gov_sys,
++      .name = "lab",
++};
++
++static struct attribute *dbs_attributes_gov_pol[] = {
++      &sampling_rate_gov_pol.attr,
++      NULL
++};
++
++static struct attribute_group lb_attr_group_gov_pol = {
++      .attrs = dbs_attributes_gov_pol,
++      .name = "lab",
++};
++
++/************************** sysfs end ************************/
++
++static int lb_init(struct dbs_data *dbs_data)
++{
++      struct lb_dbs_tuners *tuners;
++      u64 idle_time;
++      int cpu;
++
++      tuners = kzalloc(sizeof(struct od_dbs_tuners), GFP_KERNEL);
++      if (!tuners) {
++              pr_err("%s: kzalloc failed\n", __func__);
++              return -ENOMEM;
++      }
++
++      cpu = get_cpu();
++      idle_time = get_cpu_idle_time_us(cpu, NULL);
++      put_cpu();
++      if (idle_time != -1ULL) {
++              /* Idle micro accounting is supported. Use finer thresholds */
++              tuners->up_threshold = MICRO_FREQUENCY_UP_THRESHOLD;
++              tuners->adj_up_threshold = MICRO_FREQUENCY_UP_THRESHOLD -
++                      MICRO_FREQUENCY_DOWN_DIFFERENTIAL;
++              /*
++               * In nohz/micro accounting case we set the minimum frequency
++               * not depending on HZ, but fixed (very low). The deferred
++               * timer might skip some samples if idle/sleeping as needed.
++              */
++              dbs_data->min_sampling_rate = MICRO_FREQUENCY_MIN_SAMPLE_RATE;
++      } else {
++              tuners->up_threshold = DEF_FREQUENCY_UP_THRESHOLD;
++              tuners->adj_up_threshold = DEF_FREQUENCY_UP_THRESHOLD -
++                      DEF_FREQUENCY_DOWN_DIFFERENTIAL;
++
++              /* For correct statistics, we need 10 ticks for each measure */
++              dbs_data->min_sampling_rate = MIN_SAMPLING_RATE_RATIO *
++                      jiffies_to_usecs(10);
++      }
++
++      tuners->sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR;
++      tuners->ignore_nice = 0;
++
++      dbs_data->tuners = tuners;
++      mutex_init(&dbs_data->mutex);
++      return 0;
++}
++
++static void lb_exit(struct dbs_data *dbs_data)
++{
++      kfree(dbs_data->tuners);
++}
++
++define_get_cpu_dbs_routines(lb_cpu_dbs_info);
++
++static struct common_dbs_data lb_dbs_data = {
++      .governor = GOV_LAB,
++      .attr_group_gov_sys = &lb_attr_group_gov_sys,
++      .attr_group_gov_pol = &lb_attr_group_gov_pol,
++      .get_cpu_cdbs = get_cpu_cdbs,
++      .get_cpu_dbs_info_s = get_cpu_dbs_info_s,
++      .gov_dbs_timer = lb_dbs_timer,
++      .gov_check_cpu = lb_check_cpu,
++      .init = lb_init,
++      .exit = lb_exit,
++};
++
++static int lb_cpufreq_governor_dbs(struct cpufreq_policy *policy,
++              unsigned int event)
++{
++      return cpufreq_governor_dbs(policy, &lb_dbs_data, event);
++}
++
++#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_LAB
++static
++#endif
++struct cpufreq_governor cpufreq_gov_lab = {
++      .name                   = "lab",
++      .governor               = lb_cpufreq_governor_dbs,
++      .max_transition_latency = TRANSITION_LATENCY_LIMIT,
++      .owner                  = THIS_MODULE,
++};
++
++static int __init cpufreq_gov_dbs_init(void)
++{
++      return cpufreq_register_governor(&cpufreq_gov_lab);
++}
++
++static void __exit cpufreq_gov_dbs_exit(void)
++{
++      cpufreq_unregister_governor(&cpufreq_gov_lab);
++}
++
++MODULE_AUTHOR("Jonghwa Lee <jonghwa3.lee@samsung.com>");
++MODULE_AUTHOR("Lukasz Majewski <l.majewski@samsung.com>");
++MODULE_DESCRIPTION("'cpufreq_lab' - A dynamic cpufreq governor for "
++              "Legacy Application Boosting");
++MODULE_LICENSE("GPL");
++
++#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_LAB
++fs_initcall(cpufreq_gov_dbs_init);
++#else
++module_init(cpufreq_gov_dbs_init);
++#endif
++module_exit(cpufreq_gov_dbs_exit);
+diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
+index dbf5744..6b076e3 100644
+--- a/include/linux/cpufreq.h
++++ b/include/linux/cpufreq.h
+@@ -403,6 +403,9 @@ extern struct cpufreq_governor cpufreq_gov_ondemand;
+ #elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE)
+ extern struct cpufreq_governor cpufreq_gov_conservative;
+ #define CPUFREQ_DEFAULT_GOVERNOR      (&cpufreq_gov_conservative)
++#elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_LAB)
++extern struct cpufreq_governor cpufreq_gov_lab;
++#define CPUFREQ_DEFAULT_GOVERNOR      (&cpufreq_gov_lab)
+ #endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1018-cpufreq-lab-Enable-overclocking-in-LAB.patch b/patches.tizen/1018-cpufreq-lab-Enable-overclocking-in-LAB.patch
new file mode 100644 (file)
index 0000000..6cce3e4
--- /dev/null
@@ -0,0 +1,33 @@
+From a02f80423b95e4d136af6fc9e88fa911f815a092 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Fri, 8 Nov 2013 17:40:25 +0900
+Subject: [PATCH 1018/1302] cpufreq: lab: Enable overclocking in LAB
+
+Overclocking is always on for LAB governor's working.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/cpufreq_lab.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/cpufreq/cpufreq_lab.c b/drivers/cpufreq/cpufreq_lab.c
+index 3fe876b..c09e352 100644
+--- a/drivers/cpufreq/cpufreq_lab.c
++++ b/drivers/cpufreq/cpufreq_lab.c
+@@ -163,7 +163,11 @@ static void lb_dbs_timer(struct work_struct *work)
+       mutex_lock(&core_dbs_info->cdbs.timer_mutex);
+-      dbs_check_cpu(dbs_data, cpu);
++      /* Enable overclocking always for LAB governor */
++      if (cpufreq_boost_supported() && unlikely(!cpufreq_boost_enabled()))
++              cpufreq_boost_trigger_state(1);
++      else
++              dbs_check_cpu(dbs_data, cpu);
+       delay = delay_for_sampling_rate(lb_tuners->sampling_rate
+                                               * core_dbs_info->rate_mult);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1019-cpufreq-exysnos-Fix-the-way-of-enabling-boost-in-exy.patch b/patches.tizen/1019-cpufreq-exysnos-Fix-the-way-of-enabling-boost-in-exy.patch
new file mode 100644 (file)
index 0000000..68c43ac
--- /dev/null
@@ -0,0 +1,65 @@
+From 0e2c8bcfafe8e2f29bfbb6da649506c221d72fdd Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Fri, 8 Nov 2013 17:53:46 +0900
+Subject: [PATCH 1019/1302] cpufreq: exysnos: Fix the way of enabling boost in
+ exynos cpufreq driver.
+
+Follow the codes from ML.
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-redwood.dts |  1 -
+ drivers/cpufreq/exynos-cpufreq.c         | 10 +++-------
+ 2 files changed, 3 insertions(+), 8 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-redwood.dts b/arch/arm/boot/dts/exynos4412-redwood.dts
+index e6dca07..09cf22c 100644
+--- a/arch/arm/boot/dts/exynos4412-redwood.dts
++++ b/arch/arm/boot/dts/exynos4412-redwood.dts
+@@ -140,7 +140,6 @@
+       cpufreq {
+               freq_table;
+-              boost_mode = "okay";
+               status = "okay";
+       };
+diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c
+index 51a126c..249d19b 100644
+--- a/drivers/cpufreq/exynos-cpufreq.c
++++ b/drivers/cpufreq/exynos-cpufreq.c
+@@ -277,6 +277,9 @@ static struct cpufreq_driver exynos_driver = {
+       .exit           = exynos_cpufreq_cpu_exit,
+       .name           = "exynos_cpufreq",
+       .attr           = exynos_cpufreq_attr,
++#ifdef CONFIG_CPU_FREQ_BOOST_SW
++      .boost_supported = true,
++#endif
+ #ifdef CONFIG_PM
+       .suspend        = exynos_cpufreq_suspend,
+       .resume         = exynos_cpufreq_resume,
+@@ -405,9 +408,6 @@ static struct of_device_id exynos_cpufreq_of_match[] = {
+ static int exynos_cpufreq_probe(struct platform_device *pdev)
+ {
+-#ifdef CONFIG_CPU_FREQ_BOOST_SW
+-      struct device_node *node = pdev->dev.of_node;
+-#endif
+       int ret = -EINVAL;
+       exynos_info = kzalloc(sizeof(struct exynos_dvfs_info), GFP_KERNEL);
+@@ -440,10 +440,6 @@ static int exynos_cpufreq_probe(struct platform_device *pdev)
+       }
+       locking_frequency = exynos_getspeed(0);
+-#ifdef CONFIG_CPU_FREQ_BOOST_SW
+-      if (of_property_read_bool(node, "boost_mode"))
+-              exynos_driver.boost_supported = true;
+-#endif
+       register_pm_notifier(&exynos_cpufreq_nb);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1020-cpufreq-lab-Fix-codes-for-correct-working-of-lab-gov.patch b/patches.tizen/1020-cpufreq-lab-Fix-codes-for-correct-working-of-lab-gov.patch
new file mode 100644 (file)
index 0000000..583fd87
--- /dev/null
@@ -0,0 +1,129 @@
+From 2683734d07e2fa27ebdbbdc716966891a550cc08 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Mon, 11 Nov 2013 17:29:24 +0900
+Subject: [PATCH 1020/1302] cpufreq: lab: Fix codes for correct working of lab
+ governor.
+
+- Modify typo in lab govnernor.
+- Remove deadlock in lab governor which is occured when it enables
+  overclocking
+- Add initialization of LAB's data to cpufreq_governor driver
+
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+
+Conflicts:
+
+       drivers/cpufreq/cpufreq_governor.c
+
+Resolved-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/cpufreq_governor.c | 11 ++++++++++-
+ drivers/cpufreq/cpufreq_lab.c      | 19 +++++++++++--------
+ 2 files changed, 21 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
+index 86a3816..f45f6a4 100644
+--- a/drivers/cpufreq/cpufreq_governor.c
++++ b/drivers/cpufreq/cpufreq_governor.c
+@@ -85,6 +85,7 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu)
+       struct cpu_dbs_common_info *cdbs = dbs_data->cdata->get_cpu_cdbs(cpu);
+       struct od_dbs_tuners *od_tuners = dbs_data->tuners;
+       struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
++      struct lb_dbs_tuners *lb_tuners = dbs_data->tuners;
+       struct cpufreq_policy *policy;
+       unsigned int max_load = 0;
+       unsigned int ignore_nice;
+@@ -92,6 +93,8 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu)
+       if (dbs_data->cdata->governor == GOV_ONDEMAND)
+               ignore_nice = od_tuners->ignore_nice_load;
++      else if (dbs_data->cdata->governor == GOV_LAB)
++              ignore_nice = lb_tuners->ignore_nice;
+       else
+               ignore_nice = cs_tuners->ignore_nice_load;
+@@ -143,9 +146,12 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu)
+                       idle_time += jiffies_to_usecs(cur_nice_jiffies);
+               }
+-              if (unlikely(!wall_time || wall_time < idle_time))
++              if (unlikely(!wall_time))
+                       continue;
++              if (wall_time < idle_time)
++                      idle_time = wall_time;
++
+               load = 100 * (wall_time - idle_time) / wall_time;
+               if (dbs_data->cdata->governor == GOV_LAB) {
+@@ -230,6 +236,9 @@ static void set_sampling_rate(struct dbs_data *dbs_data,
+       if (dbs_data->cdata->governor == GOV_CONSERVATIVE) {
+               struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
+               cs_tuners->sampling_rate = sampling_rate;
++      } else if(dbs_data->cdata->governor == GOV_LAB) {
++              struct lb_dbs_tuners *lb_tuners = dbs_data->tuners;
++              lb_tuners->sampling_rate = sampling_rate;
+       } else {
+               struct od_dbs_tuners *od_tuners = dbs_data->tuners;
+               od_tuners->sampling_rate = sampling_rate;
+diff --git a/drivers/cpufreq/cpufreq_lab.c b/drivers/cpufreq/cpufreq_lab.c
+index c09e352..28f4932 100644
+--- a/drivers/cpufreq/cpufreq_lab.c
++++ b/drivers/cpufreq/cpufreq_lab.c
+@@ -161,17 +161,20 @@ static void lb_dbs_timer(struct work_struct *work)
+       struct lb_dbs_tuners *lb_tuners = dbs_data->tuners;
+       int delay;
+-      mutex_lock(&core_dbs_info->cdbs.timer_mutex);
+-
+       /* Enable overclocking always for LAB governor */
+-      if (cpufreq_boost_supported() && unlikely(!cpufreq_boost_enabled()))
++      if (cpufreq_boost_supported() && unlikely(!cpufreq_boost_enabled())) {
++              /* To avoid deadlock, mutex_lock() is called
++               * after cpufreq_boost_trigger_state().
++               */
+               cpufreq_boost_trigger_state(1);
+-      else
++              mutex_lock(&core_dbs_info->cdbs.timer_mutex);
++      } else {
++              mutex_lock(&core_dbs_info->cdbs.timer_mutex);
+               dbs_check_cpu(dbs_data, cpu);
++      }
+       delay = delay_for_sampling_rate(lb_tuners->sampling_rate
+                                               * core_dbs_info->rate_mult);
+-
+       gov_queue_work(dbs_data, dbs_info->cdbs.cur_policy, delay, false);
+       mutex_unlock(&core_dbs_info->cdbs.timer_mutex);
+ }
+@@ -284,7 +287,7 @@ static int lb_init(struct dbs_data *dbs_data)
+       u64 idle_time;
+       int cpu;
+-      tuners = kzalloc(sizeof(struct od_dbs_tuners), GFP_KERNEL);
++      tuners = kzalloc(sizeof(struct lb_dbs_tuners), GFP_KERNEL);
+       if (!tuners) {
+               pr_err("%s: kzalloc failed\n", __func__);
+               return -ENOMEM;
+@@ -329,7 +332,7 @@ static void lb_exit(struct dbs_data *dbs_data)
+ define_get_cpu_dbs_routines(lb_cpu_dbs_info);
+-static struct common_dbs_data lb_dbs_data = {
++static struct common_dbs_data lb_dbs_cdata = {
+       .governor = GOV_LAB,
+       .attr_group_gov_sys = &lb_attr_group_gov_sys,
+       .attr_group_gov_pol = &lb_attr_group_gov_pol,
+@@ -344,7 +347,7 @@ static struct common_dbs_data lb_dbs_data = {
+ static int lb_cpufreq_governor_dbs(struct cpufreq_policy *policy,
+               unsigned int event)
+ {
+-      return cpufreq_governor_dbs(policy, &lb_dbs_data, event);
++      return cpufreq_governor_dbs(policy, &lb_dbs_cdata, event);
+ }
+ #ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_LAB
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1021-mmc-sdhci-s3c-Add-irq_set_wake-function.patch b/patches.tizen/1021-mmc-sdhci-s3c-Add-irq_set_wake-function.patch
new file mode 100644 (file)
index 0000000..9a403f0
--- /dev/null
@@ -0,0 +1,67 @@
+From 9549c16d7d2b46f290cc855abaa61373605f3ba7 Mon Sep 17 00:00:00 2001
+From: Beomho Seo <beomho.seo@samsung.com>
+Date: Tue, 12 Nov 2013 16:36:22 +0900
+Subject: [PATCH 1021/1302] mmc: sdhci-s3c: Add irq_set_wake function
+
+- Add irq_set_irq_wake function for control irq
+- Remove unused variables
+
+Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mmc/host/sdhci-s3c.c | 10 +++-------
+ 1 file changed, 3 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
+index acc0099..17abed3 100644
+--- a/drivers/mmc/host/sdhci-s3c.c
++++ b/drivers/mmc/host/sdhci-s3c.c
+@@ -53,8 +53,6 @@ struct sdhci_s3c {
+       struct resource         *ioarea;
+       struct s3c_sdhci_platdata *pdata;
+       unsigned int            cur_clk;
+-      int                     ext_cd_irq;
+-      int                     ext_cd_gpio;
+       struct clk              *clk_io;
+       struct clk              *clk_bus[MAX_BUS_CLK];
+@@ -394,7 +392,6 @@ static int sdhci_s3c_parse_dt(struct device *dev,
+               struct sdhci_host *host, struct s3c_sdhci_platdata *pdata)
+ {
+       struct device_node *node = dev->of_node;
+-      struct sdhci_s3c *ourhost = to_s3c(host);
+       u32 max_width;
+       int gpio;
+@@ -418,7 +415,6 @@ static int sdhci_s3c_parse_dt(struct device *dev,
+       if (gpio_is_valid(gpio)) {
+               pdata->cd_type = S3C_SDHCI_CD_GPIO;
+               pdata->ext_cd_gpio = gpio;
+-              ourhost->ext_cd_gpio = -1;
+               if (of_get_property(node, "cd-inverted", NULL))
+                       pdata->ext_cd_gpio_invert = 1;
+               return 0;
+@@ -493,10 +489,9 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
+               ret = sdhci_s3c_parse_dt(&pdev->dev, host, pdata);
+               if (ret)
+                       goto err_pdata_io_clk;
+-      } else {
++      } else
+               memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata));
+-              sc->ext_cd_gpio = -1; /* invalid gpio number */
+-      }
++
+       drv_data = sdhci_s3c_get_driver_data(pdev);
+@@ -656,6 +651,7 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
+                               "failed to request card detect gpio\n");
+                       goto err_req_cd;
+               }
++              irq_set_irq_wake(gpio_to_irq(pdata->ext_cd_gpio), 1);
+       }
+ #ifdef CONFIG_PM_RUNTIME
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1022-gpu-arm-mali400-ump-Fix-svn-revision-check.patch b/patches.tizen/1022-gpu-arm-mali400-ump-Fix-svn-revision-check.patch
new file mode 100644 (file)
index 0000000..b58d600
--- /dev/null
@@ -0,0 +1,28 @@
+From 142295478b0e9c929188dcda50421dac82bbdbfc Mon Sep 17 00:00:00 2001
+From: Nikita Kalyazin <n.kalyazin@samsung.com>
+Date: Thu, 14 Nov 2013 09:05:32 +0400
+Subject: [PATCH 1022/1302] gpu: arm: mali400: ump: Fix svn revision check
+
+Change-Id: Ic5a3d69518be56a800d4233a48ba8bb719e67c52
+Signed-off-by: Nikita Kalyazin <n.kalyazin@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/arm/mali400/ump/Kbuild | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/arm/mali400/ump/Kbuild b/drivers/gpu/arm/mali400/ump/Kbuild
+index 55aa2d9..5b3150b 100644
+--- a/drivers/gpu/arm/mali400/ump/Kbuild
++++ b/drivers/gpu/arm/mali400/ump/Kbuild
+@@ -27,7 +27,7 @@ endif
+ UDD_FILE_PREFIX = ../mali/
+ # Get subversion revision number, fall back to 0000 if no svn info is available
+-SVN_REV := $(shell ((svnversion | grep -qv exported && echo -n 'Revision: ' && svnversion) || git svn info | sed -e 's/$$$$/M/' | grep '^Revision: ' || echo ${MALI_RELEASE_NAME}) 2>/dev/null | sed -e 's/^Revision: //')
++SVN_REV := $(shell ((svnversion | grep -qv "\(exported\|Unversioned\)" && echo -n 'Revision: ' && svnversion) || git svn info | sed -e 's/$$$$/M/' | grep '^Revision: ' || echo ${MALI_RELEASE_NAME}) 2>/dev/null | sed -e 's/^Revision: //')
+ ccflags-y += -DSVN_REV=$(SVN_REV)
+ ccflags-y += -DSVN_REV_STRING=\"$(SVN_REV)\"
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1023-packaging-Bump-version.patch b/patches.tizen/1023-packaging-Bump-version.patch
new file mode 100644 (file)
index 0000000..655d965
--- /dev/null
@@ -0,0 +1,29 @@
+From a58d547de0bf7cbfa84fa98de3ccdb3cbe473a5a Mon Sep 17 00:00:00 2001
+From: Karol Lewandowski <k.lewandowsk@samsung.com>
+Date: Tue, 29 Oct 2013 14:00:53 +0100
+Subject: [PATCH 1023/1302] packaging: Bump version
+
+Modified version number, again.
+
+Change-Id: Idf67ccbf9c36030644be6c6f76f5fe0e2b857246
+Signed-off-by: Karol Lewandowski <k.lewandowsk@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ packaging/linux-kernel.spec | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/packaging/linux-kernel.spec b/packaging/linux-kernel.spec
+index dbd105f..bb7ef64 100644
+--- a/packaging/linux-kernel.spec
++++ b/packaging/linux-kernel.spec
+@@ -1,6 +1,6 @@
+ Name: linux-kernel
+ Summary: The Linux Kernel
+-Version: 3.8.3
++Version: 3.10.19
+ Release: 1
+ License: GPL
+ Group: System Environment/Kernel
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1024-mali-Support-build-to-different-objdir-O.patch b/patches.tizen/1024-mali-Support-build-to-different-objdir-O.patch
new file mode 100644 (file)
index 0000000..3b1eb07
--- /dev/null
@@ -0,0 +1,135 @@
+From f6c78ba97c3cc2ffd42f3acb43a7b373256363a7 Mon Sep 17 00:00:00 2001
+From: Karol Lewandowski <k.lewandowsk@samsung.com>
+Date: Thu, 31 Oct 2013 19:56:58 +0100
+Subject: [PATCH 1024/1302] mali: Support build to different objdir (O=...).
+
+Change-Id: I3b76381af1ec083c41e321e55c10eb1e75e42155
+Signed-off-by: Karol Lewandowski <k.lewandowsk@samsung.com>
+Signed-off-by: Jacek Pielaszkiewicz <j.pielaszkie@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/arm/mali400/mali/Kbuild | 22 +++++++++++-----------
+ drivers/gpu/arm/mali400/ump/Kbuild  | 15 +++++++--------
+ 2 files changed, 18 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/gpu/arm/mali400/mali/Kbuild b/drivers/gpu/arm/mali400/mali/Kbuild
+index 58c8d05..b17fbc5 100644
+--- a/drivers/gpu/arm/mali400/mali/Kbuild
++++ b/drivers/gpu/arm/mali400/mali/Kbuild
+@@ -23,15 +23,15 @@ MALI_UPPER_HALF_SCHEDULING ?= 1
+ # MALI_SEC 
+ # Include the mapping between TARGET_PLATFORM and KDIR + MALI_PLATFORM
+ TARGET_PLATFORM=exynos4
+-include $(src)/MALI_CONFIGURATION
++include $(srctree)/$(src)/MALI_CONFIGURATION
+ MALI_PLATFORM = $(MALI_PLATFORM-$(TARGET_PLATFORM))
+-MALI_PLATFORM_FILES = $(subst $(src)/,,$(wildcard $(src)/platform/$(MALI_PLATFORM)/*.c))
++MALI_PLATFORM_FILES = $(subst $(srctree)/$(src)/,,$(wildcard $(srctree)/$(src)/platform/$(MALI_PLATFORM)/*.c))
+ # For customer releases the Linux Device Drivers will be provided as ARM proprietary and GPL releases:
+ # The ARM proprietary product will only include the license/proprietary directory
+ # The GPL product will only include the license/gpl directory
+-ifeq ($(wildcard $(src)/linux/license/gpl/*),)
+-    ccflags-y += -I$(src)/linux/license/proprietary
++ifeq ($(wildcard $(srctree)/$(src)/linux/license/gpl/*),)
++    ccflags-y += -I$(srctree)/$(src)/linux/license/proprietary
+     ifeq ($(CONFIG_MALI400_PROFILING),y)
+         $(error Profiling is incompatible with non-GPL license)
+     endif
+@@ -43,7 +43,7 @@ ifeq ($(wildcard $(src)/linux/license/gpl/*),)
+     endif
+     $(error Linux Device integration is incompatible with non-GPL license)
+ else
+-    ccflags-y += -I$(src)/linux/license/gpl
++    ccflags-y += -I$(srctree)/$(src)/linux/license/gpl
+ endif
+ mali-y += \
+@@ -112,7 +112,7 @@ mali-$(CONFIG_MALI400_PROFILING) += linux/mali_ukk_profiling.o
+ mali-$(CONFIG_MALI400_PROFILING) += linux/mali_osk_profiling.o
+ mali-$(CONFIG_MALI400_INTERNAL_PROFILING) += linux/mali_profiling_internal.o timestamp-$(TIMESTAMP)/mali_timestamp.o
+-ccflags-$(CONFIG_MALI400_INTERNAL_PROFILING) += -I$(src)/timestamp-$(TIMESTAMP)
++ccflags-$(CONFIG_MALI400_INTERNAL_PROFILING) += -I$(srctree)/$(src)/timestamp-$(TIMESTAMP)
+ mali-$(CONFIG_DMA_SHARED_BUFFER) += linux/mali_dma_buf.o
+ mali-$(CONFIG_SYNC) += linux/mali_sync.o linux/mali_sync_user.o
+@@ -137,16 +137,16 @@ ifeq ($(MALI_UPPER_HALF_SCHEDULING),1)
+       ccflags-y += -DMALI_UPPER_HALF_SCHEDULING
+ endif
+-ccflags-$(CONFIG_MALI400_UMP) += -I$(src)/../../ump/include/ump
++ccflags-$(CONFIG_MALI400_UMP) += -I$(srctree)/$(src)/../../ump/include/ump
+ ccflags-$(CONFIG_MALI400_DEBUG) += -DDEBUG
+ # Use our defines when compiling
+-ccflags-y += -I$(src) -I$(src)/include -I$(src)/common -I$(src)/linux -I$(src)/platform
++ccflags-y += -I$(srctree)/$(src) -I$(srctree)/$(src)/include -I$(srctree)/$(src)/common -I$(srctree)/$(src)/linux -I$(srctree)/$(src)/platform
+ # MALI_SEC 
+-ccflags-y += -I$(src)/../ump/include
++ccflags-y += -I$(srctree)/$(src)/../ump/include
+ # Get subversion revision number, fall back to only ${MALI_RELEASE_NAME} if no svn info is available
+-MALI_RELEASE_NAME=$(shell cat $(src)/.version 2> /dev/null)
++MALI_RELEASE_NAME=$(shell cat $(srctree)/$(src)/.version 2> /dev/null)
+ SVN_INFO = (cd $(src); (svn info || git svn info || \
+       echo -e "\nURL: $(MALI_RELEASE_NAME)\n" \
+@@ -163,7 +163,7 @@ endif
+ ccflags-y += -DSVN_REV_STRING=\"$(SVN_REV)\"
+ VERSION_STRINGS :=
+-VERSION_STRINGS += API_VERSION=$(shell cd $(src); grep "\#define _MALI_API_VERSION" $(FILES_PREFIX)include/linux/mali/mali_utgard_uk_types.h | cut -d' ' -f 3 )
++VERSION_STRINGS += API_VERSION=$(shell cd $(srctree)/$(src); grep "\#define _MALI_API_VERSION" $(FILES_PREFIX)include/linux/mali/mali_utgard_uk_types.h | cut -d' ' -f 3 )
+ VERSION_STRINGS += REPO_URL=$(shell $(SVN_INFO) | grep '^URL: ' | cut -d: -f2- | cut -b2-)
+ VERSION_STRINGS += REVISION=$(SVN_REV)
+ VERSION_STRINGS += CHANGED_REVISION=$(shell $(SVN_INFO) | grep '^Last Changed Rev: ' | cut -d: -f2- | cut -b2-)
+diff --git a/drivers/gpu/arm/mali400/ump/Kbuild b/drivers/gpu/arm/mali400/ump/Kbuild
+index 5b3150b..c5505fa 100644
+--- a/drivers/gpu/arm/mali400/ump/Kbuild
++++ b/drivers/gpu/arm/mali400/ump/Kbuild
+@@ -15,13 +15,12 @@
+ CONFIG ?= release
+ # Validate selected config
+-ifneq ($(shell [ -d $(src)/arch-$(CONFIG) ] && [ -f  $(src)/arch-$(CONFIG)/config.h ] && echo "OK"), OK)
+-$(warning Current directory is $(src))
++ifneq ($(shell [ -d $(srctree)/$(src)/arch-$(CONFIG) ] && [ -f  $(srctree)/$(src)/arch-$(CONFIG)/config.h ] && echo "OK"), OK)
+ $(error No configuration found for config $(CONFIG). Check that arch-$(CONFIG)/config.h exists)
+ else
+ # Link arch to the selected arch-config directory
+ $(shell [ -L $(src)/arch ] && rm $(src)/arch)
+-$(shell ln -sf arch-$(CONFIG) $(src)/arch)
++$(shell ln -sf arch-$(CONFIG) $(srctree)/$(src)/arch)
+ endif
+ UDD_FILE_PREFIX = ../mali/
+@@ -32,9 +31,9 @@ SVN_REV := $(shell ((svnversion | grep -qv "\(exported\|Unversioned\)" && echo -
+ ccflags-y += -DSVN_REV=$(SVN_REV)
+ ccflags-y += -DSVN_REV_STRING=\"$(SVN_REV)\"
+-ccflags-y += -I$(src) -I$(src)/common -I$(src)/linux -I$(src)/../mali/common -I$(src)/../mali/linux -I$(src)/../../ump/include/ump
++ccflags-y += -I$(srctree)/$(src) -I$(srctree)/$(src)/common -I$(srctree)/$(src)/linux -I$(srctree)/$(src)/../mali/common -I$(srctree)/$(src)/../mali/linux -I$(srctree)/$(src)/../../ump/include/ump
+ # MALI_SEC
+-ccflags-y += -I$(src)/include
++ccflags-y += -I$(srctree)/$(src)/include
+ ccflags-y += -DUSING_MEMORY=1 -DUMP_MEM_SIZE=512
+ ccflags-y += -DMALI_STATE_TRACKING=0
+@@ -44,10 +43,10 @@ ccflags-$(CONFIG_UMP_DEBUG) += -DDEBUG
+ # The ARM proprietary product will only include the license/proprietary directory
+ # The GPL product will only include the license/gpl directory
+-ifeq ($(wildcard $(src)/linux/license/gpl/*),)
+-ccflags-y += -I$(src)/linux/license/proprietary
++ifeq ($(wildcard $(srctree)/$(src)/linux/license/gpl/*),)
++ccflags-y += -I$(srctree)/$(src)/linux/license/proprietary
+ else
+-ccflags-y += -I$(src)/linux/license/gpl
++ccflags-y += -I$(srctree)/$(src)/linux/license/gpl
+ endif
+ ump-y = common/ump_kernel_common.o \
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1025-update-linux-kernel.spec-file-to-fix-build-problems.patch b/patches.tizen/1025-update-linux-kernel.spec-file-to-fix-build-problems.patch
new file mode 100644 (file)
index 0000000..22b1fd8
--- /dev/null
@@ -0,0 +1,154 @@
+From ef4dde1bddd32f95370d058a75a4de190545dee8 Mon Sep 17 00:00:00 2001
+From: Karol Lewandowski <k.lewandowsk@samsung.com>
+Date: Tue, 29 Oct 2013 14:00:53 +0100
+Subject: [PATCH 1025/1302] update linux-kernel.spec file to fix build
+ problems.
+
+The following changes have been implemented:
+1. kernel-source package
+2. kernel-build package
+3. linux-kernel package
+4. add kernel configuration name and abi version to output names.
+
+Change-Id: I95479b660dda8a18f3e8f32c20fcbfbab8ab6000
+Signed-off-by: Jacek Pielaszkiewicz <j.pielaszkie@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ packaging/linux-kernel.spec | 92 +++++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 88 insertions(+), 4 deletions(-)
+
+diff --git a/packaging/linux-kernel.spec b/packaging/linux-kernel.spec
+index bb7ef64..5e64441 100644
+--- a/packaging/linux-kernel.spec
++++ b/packaging/linux-kernel.spec
+@@ -1,3 +1,7 @@
++%define config_name tizen_defconfig
++%define abiver current
++%define build_id %{config_name}.%{abiver}
++
+ Name: linux-kernel
+ Summary: The Linux Kernel
+ Version: 3.10.19
+@@ -6,8 +10,13 @@ License: GPL
+ Group: System Environment/Kernel
+ Vendor: The Linux Community
+ URL: http://www.kernel.org
+-Source0:   %{name}-%{version}.tar.gz
++Source0:   %{name}-%{version}-%{build_id}.tar.gz
+ BuildRoot: %{_tmppath}/%{name}-%{PACKAGE_VERSION}-root
++BuildRequires: linux-glibc-devel
++BuildRequires: bc
++
++%define kernel_build_dir_name .%{name}-%{version}-%{build_id}
++%define kernel_build_dir %{_builddir}/%{name}-%{version}/%{kernel_build_dir_name}
+ %description
+ The Linux Kernel, the operating system core itself
+@@ -17,6 +26,7 @@ Summary: Header files for the Linux kernel for use by glibc
+ Group: Development/System
+ Obsoletes: kernel-headers
+ Provides: kernel-headers = %{version}
++
+ %description headers
+ Kernel-headers includes the C header files that specify the interface
+ between the Linux kernel and userspace libraries and programs.  The
+@@ -24,19 +34,93 @@ header files define structures and constants that are needed for
+ building most standard programs and are also needed for rebuilding the
+ glibc package.
++%package sources
++Summary: Full linux kernel sources for out-of-tree modules
++Group: Development/System
++Provides: kernel-sources = %{version}-%{build_id}
++
++%description sources
++Full linux kernel sources for out-of-tree modules.
++
++%package build
++Summary: Prebuilt linux kernel for out-of-tree modules
++Group: Development/System
++Requires: kernel-sources = %{version}-%{build_id}
++
++%description build
++Prebuilt linux kernel for out-of-tree modules.
++
+ %prep
+ %setup -q
+ %build
++# 1. Create main build directory
++rm -rf %{kernel_build_dir}
++mkdir -p %{kernel_build_dir}
++
++# 2. Create tar archive for sources
++tar cpsf %{kernel_build_dir}/linux-kernel-sources-%{version}-%{build_id}.tar . --one-file-system --exclude ".git*"
++
++# 3. Create kernel build directory
++mkdir -p %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}
++
++# 4. Compile sources
++make EXTRAVERSION="-%{build_id}" O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} %{config_name}
++make EXTRAVERSION="-%{build_id}" O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} %{?_smp_mflags}
++
++# 5. Update Makefile in output build
++cat %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/Makefile | sed 's/\/home\/abuild\/rpmbuild\/BUILD\/%{name}-%{version}/\/usr\/src\/linux-kernel-sources-%{version}-%{build_id}/' > %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/Makefile.new
++mv %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/Makefile.new %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/Makefile
++rm -f %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/Makefile.new
++
++# 6. Create tar repo for build directory
++( cd %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} ; tar cpsf %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}.tar . )
+ %install
+ QA_SKIP_BUILD_ROOT="DO_NOT_WANT"; export QA_SKIP_BUILD_ROOT
+-mkdir $RPM_BUILD_ROOT/usr
+-make ARCH=arm INSTALL_HDR_PATH=$RPM_BUILD_ROOT/usr headers_install
++
++# 1. Destynation directories
++mkdir -p %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}
++mkdir -p %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}
++
++# 2. Restore source and build irectory
++tar -xf %{kernel_build_dir}/linux-kernel-sources-%{version}-%{build_id}.tar -C %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}
++tar -xf %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}.tar   -C %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}
++
++# 3. Install kernel headers
++make INSTALL_PATH=%{buildroot} INSTALL_MOD_PATH=%{buildroot} O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} INSTALL_HDR_PATH=%{buildroot}/usr headers_install
++
++# 4. Remove files
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name ".tmp_vmlinux1" -exec rm -f {} +
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name ".tmp_vmlinux2" -exec rm -f {} +
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "vmlinux" -exec rm -f {} +
++find %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id} -name "*.c" -exec rm -f {} +
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*.cmd" -exec rm -f {} +
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.o" -exec rm -f {} +
++find %{buildroot}/usr -name "..install.cmd" -exec rm -f {} +
++
++find %{buildroot}/usr/include -name "\.\.install.cmd"  -exec rm -f {} +
++find %{buildroot}/usr/include -name "\.install"  -exec rm -f {} +
++
++rm -rf %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}/%{kernel_build_dir_name}
++rm -f %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}/source
++rm -f %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/source
++rm -f %{buildroot}/System.map-3.10.0 %{buildroot}/vmlinux-3.10.0
++
++# 5. Create symbolic links
++ln -sf /usr/src/linux-kernel-sources-%{version}-%{build_id} %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/source
+ %clean
+-rm -rf $RPM_BUILD_ROOT
++rm -rf %{buildroot}
+ %files headers
+ %defattr (-, root, root)
+ /usr/include
++
++%files sources
++%defattr (-, root, root)
++/usr/src/linux-kernel-sources-%{version}-%{build_id}
++
++%files build
++%defattr (-, root, root)
++/usr/src/linux-kernel-build-%{version}-%{build_id}
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1026-tizen-update-default-config-to-use-slp-gadget.patch b/patches.tizen/1026-tizen-update-default-config-to-use-slp-gadget.patch
new file mode 100644 (file)
index 0000000..f9c65de
--- /dev/null
@@ -0,0 +1,126 @@
+From 39ce9fb76c4c0838fde4df3362614eb0eea5fb6b Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Fri, 22 Nov 2013 19:11:44 +0900
+Subject: [PATCH 1026/1302] tizen: update default config to use slp gadget
+
+The Tizen uses slp composite gadget which is based on android gadget.
+Until we migrate to configfs based gadget configuration, we should use the slp
+gadget. It only support sdb and rndis gadget.
+
+Change-Id: I9e7afd3ef9865d43d43d2221b30b7b10ef039399
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_defconfig | 33 +++++++++++++++++++++------------
+ 1 file changed, 21 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index a6559b1..7f0e7ea 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -1,6 +1,6 @@
+ #
+ # Automatically generated file; DO NOT EDIT.
+-# Linux/arm 3.10.0 Kernel Configuration
++# Linux/arm 3.10.19 Kernel Configuration
+ #
+ CONFIG_ARM=y
+ CONFIG_ARM_HAS_SG_CHAIN=y
+@@ -15,6 +15,7 @@ CONFIG_LOCKDEP_SUPPORT=y
+ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ CONFIG_ARCH_HAS_CPUFREQ=y
++CONFIG_ARCH_HAS_BANDGAP=y
+ CONFIG_GENERIC_HWEIGHT=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
+ CONFIG_NEED_DMA_MAP_STATE=y
+@@ -406,6 +407,7 @@ CONFIG_SWP_EMULATE=y
+ # CONFIG_CPU_ICACHE_DISABLE is not set
+ # CONFIG_CPU_DCACHE_DISABLE is not set
+ # CONFIG_CPU_BPREDICT_DISABLE is not set
++CONFIG_KUSER_HELPERS=y
+ CONFIG_OUTER_CACHE=y
+ CONFIG_OUTER_CACHE_SYNC=y
+ CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+@@ -543,11 +545,13 @@ CONFIG_CPU_FREQ_STAT=y
+ # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+ CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+ # CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
++# CONFIG_CPU_FREQ_DEFAULT_GOV_LAB is not set
+ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+ CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+ CONFIG_CPU_FREQ_GOV_USERSPACE=y
+ CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+ CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
++# CONFIG_CPU_FREQ_GOV_LAB is not set
+ #
+ # ARM CPU frequency scaling drivers
+@@ -580,8 +584,7 @@ CONFIG_BINFMT_ELF=y
+ CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+ CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+ CONFIG_BINFMT_SCRIPT=y
+-CONFIG_HAVE_AOUT=y
+-# CONFIG_BINFMT_AOUT is not set
++# CONFIG_HAVE_AOUT is not set
+ # CONFIG_BINFMT_MISC is not set
+ CONFIG_COREDUMP=y
+@@ -1864,6 +1867,16 @@ CONFIG_THERMAL_GOV_STEP_WISE=y
+ # CONFIG_THERMAL_GOV_USER_SPACE is not set
+ CONFIG_CPU_THERMAL=y
+ # CONFIG_THERMAL_EMULATION is not set
++# CONFIG_IMX_THERMAL is not set
++
++#
++# Texas Instruments thermal drivers
++#
++# CONFIG_TI_SOC_THERMAL is not set
++
++#
++# Samsung thermal drivers
++#
+ CONFIG_EXYNOS_THERMAL=y
+ CONFIG_WATCHDOG=y
+ CONFIG_WATCHDOG_CORE=y
+@@ -2562,17 +2575,12 @@ CONFIG_USB_S3C_HSOTG=y
+ # CONFIG_USB_NET2272 is not set
+ # CONFIG_USB_DUMMY_HCD is not set
+ CONFIG_USB_LIBCOMPOSITE=y
+-CONFIG_USB_U_ETHER=y
+-CONFIG_USB_U_RNDIS=y
+-CONFIG_USB_F_ECM=y
+-CONFIG_USB_F_SUBSET=y
+-CONFIG_USB_F_RNDIS=y
++CONFIG_USB_F_ACM=y
++CONFIG_USB_U_SERIAL=y
+ # CONFIG_USB_CONFIGFS is not set
+ # CONFIG_USB_ZERO is not set
+ # CONFIG_USB_AUDIO is not set
+-CONFIG_USB_ETH=y
+-CONFIG_USB_ETH_RNDIS=y
+-# CONFIG_USB_ETH_EEM is not set
++# CONFIG_USB_ETH is not set
+ # CONFIG_USB_G_NCM is not set
+ # CONFIG_USB_GADGETFS is not set
+ # CONFIG_USB_FUNCTIONFS is not set
+@@ -2580,7 +2588,7 @@ CONFIG_USB_ETH_RNDIS=y
+ # CONFIG_USB_G_SERIAL is not set
+ # CONFIG_USB_MIDI_GADGET is not set
+ # CONFIG_USB_G_PRINTER is not set
+-# CONFIG_USB_G_SLP is not set
++CONFIG_USB_G_SLP=y
+ # CONFIG_USB_CDC_COMPOSITE is not set
+ # CONFIG_USB_G_NOKIA is not set
+ # CONFIG_USB_G_ACM_MS is not set
+@@ -3084,6 +3092,7 @@ CONFIG_CM36651=y
+ CONFIG_AK8975=y
+ # CONFIG_IIO_ST_MAGN_3AXIS is not set
+ CONFIG_PWM=y
++CONFIG_PWM_SYSFS=y
+ CONFIG_PWM_SAMSUNG=y
+ CONFIG_IRQCHIP=y
+ CONFIG_ARM_GIC=y
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1027-gpu-arm-mali400-support-gpu-frequency-profiling.patch b/patches.tizen/1027-gpu-arm-mali400-support-gpu-frequency-profiling.patch
new file mode 100644 (file)
index 0000000..691b662
--- /dev/null
@@ -0,0 +1,82 @@
+From f5183364c05addaca41265aff3168ad64b20658f Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Mon, 25 Nov 2013 11:52:04 +0900
+Subject: [PATCH 1027/1302] gpu: arm: mali400: support gpu frequency profiling
+
+This patch supports gpu frequency profiling by using ARM streamline.
+You must turn on below configuration if you want to get a profiling data.
+
+CONFIG_MALI400_PROFILING
+CONFIG_MALI400_INTERNAL_PROFILING
+
+Change-Id: Id8cc59b80dcf4483cc5944283fc95daaca6f0839
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../arm/mali400/mali/platform/exynos4/exynos4.c    | 23 ++++++++++++++++++++++
+ 1 file changed, 23 insertions(+)
+
+diff --git a/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4.c b/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4.c
+index 64fd5de..58b3ae0 100644
+--- a/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4.c
++++ b/drivers/gpu/arm/mali400/mali/platform/exynos4/exynos4.c
+@@ -22,6 +22,10 @@
+ #include "mali_kernel_common.h"
+ #include "mali_osk.h"
++#ifdef CONFIG_MALI400_PROFILING
++#include "mali_osk_profiling.h"
++#endif
++
+ #include "exynos4.h"
+ struct mali_exynos_variant {
+@@ -118,6 +122,20 @@ const struct of_device_id mali_of_matches[] = {
+       { /* Sentinel */ }
+ };
++#ifdef CONFIG_MALI400_PROFILING
++static inline void _mali_osk_profiling_add_gpufreq_event(int rate, int vol)
++{
++      _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
++               MALI_PROFILING_EVENT_CHANNEL_GPU |
++               MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
++               rate, vol, 0, 0, 0);
++}
++#else
++static inline void _mali_osk_profiling_add_gpufreq_event(int rate, int vol)
++{
++}
++#endif
++
+ /*
+  * DVFS control
+  */
+@@ -136,6 +154,8 @@ static void mali_exynos_set_dvfs_step(struct mali_exynos_drvdata *mali,
+       if (step > mali->dvfs_step)
+               clk_set_rate(mali->sclk_g3d, next->rate);
++      _mali_osk_profiling_add_gpufreq_event(next->rate / 1000000,
++               regulator_get_voltage(mali->vdd_g3d) / 1000);
+       mali->dvfs_step = step;
+ }
+@@ -185,6 +205,7 @@ _mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode)
+       case MALI_POWER_MODE_LIGHT_SLEEP:
+       case MALI_POWER_MODE_DEEP_SLEEP:
+               clk_disable_unprepare(mali->sclk_g3d);
++              _mali_osk_profiling_add_gpufreq_event(0, 0);
+               break;
+       }
+@@ -312,5 +333,7 @@ _mali_osk_errcode_t mali_platform_deinit(void)
+       regulator_disable(mali->vdd_g3d);
++      _mali_osk_profiling_add_gpufreq_event(0, 0);
++
+       MALI_SUCCESS;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1028-arch-ARM-dts-add-support-for-exynos4210-usbphy-drive.patch b/patches.tizen/1028-arch-ARM-dts-add-support-for-exynos4210-usbphy-drive.patch
new file mode 100644 (file)
index 0000000..4486fea
--- /dev/null
@@ -0,0 +1,61 @@
+From 4048f4dfcde4950caf46680e8104bb781254e80c Mon Sep 17 00:00:00 2001
+From: Andrzej Hajda <a.hajda@samsung.com>
+Date: Tue, 15 Oct 2013 10:45:34 +0200
+Subject: [PATCH 1028/1302] arch: ARM: dts: add support for exynos4210-usbphy
+ driver to trats
+
+Change-Id: I9758e15225e86050b62068b1156709a71799e4f1
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-trats.dts | 25 +++++++++++++++++++++----
+ 1 file changed, 21 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index bed4256..e783c05 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -523,14 +523,13 @@
+               };
+       };
+-      usbphy@125B0000 {
+-              status = "okay";
+-      };
+-
+       hsotg@12480000 {
+               status = "okay";
+               vusb_d-supply = <&vusb_reg>;
+               vusb_a-supply = <&vusbdac_reg>;
++              phys = <&exynos_usbphy 0>;
++              phy-names = "device";
++              status = "okay";
+       };
+       fixed-rate-clocks {
+@@ -695,4 +694,22 @@
+               status = "okay";
+               vdd_g3d-supply = <&vg3d_breg>;
+       };
++
++      ehci@12580000 {
++              status = "okay";
++              phys = <&exynos_usbphy 1>;
++              phy-names = "host";
++              vusb_d-supply = <&vusb_reg>;
++              vusb_a-supply = <&vusbdac_reg>;
++      };
++
++      exynos_usbphy: exynos-usbphy@125B0000 {
++              compatible = "samsung,exynos4210-usbphy";
++              reg = <0x125B0000 0x100 0x10020704 0x0c 0x1001021c 0x4>;
++              clocks = <&clock 305>, <&clock 2>, <&clock 2>, <&clock 2>,
++                                                              <&clock 2>;
++              clock-names = "phy", "device", "host", "hsic0", "hsic1";
++              status = "okay";
++              #phy-cells = <1>;
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1029-USB-gadget-s3c-hsotg-fix-spinlock-locking.patch b/patches.tizen/1029-USB-gadget-s3c-hsotg-fix-spinlock-locking.patch
new file mode 100644 (file)
index 0000000..51abc2f
--- /dev/null
@@ -0,0 +1,45 @@
+From 5408146904f463333ba3987401dce3398ed000a9 Mon Sep 17 00:00:00 2001
+From: Robert Baldyga <r.baldyga@samsung.com>
+Date: Thu, 14 Nov 2013 12:07:29 +0100
+Subject: [PATCH 1029/1302] USB: gadget: s3c-hsotg: fix spinlock locking
+
+This patch adds missing spinlock locking in s3c_hsotg_complete_setup function,
+and unlocking for gadget setup call.
+
+Change-Id: I73dc683a9df16872d9d6ba2b6b7c98a48418c500
+Signed-off-by: Robert Baldyga <r.baldyga@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/s3c-hsotg.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
+index 943a9e5..6cfb562 100644
+--- a/drivers/usb/gadget/s3c-hsotg.c
++++ b/drivers/usb/gadget/s3c-hsotg.c
+@@ -1232,7 +1232,9 @@ static void s3c_hsotg_process_control(struct s3c_hsotg *hsotg,
+       /* as a fallback, try delivering it to the driver to deal with */
+       if (ret == 0 && hsotg->driver) {
++              spin_unlock(&hsotg->lock);
+               ret = hsotg->driver->setup(&hsotg->gadget, ctrl);
++              spin_lock(&hsotg->lock);
+               if (ret < 0)
+                       dev_dbg(hsotg->dev, "driver->setup() ret %d\n", ret);
+       }
+@@ -1292,10 +1294,12 @@ static void s3c_hsotg_complete_setup(struct usb_ep *ep,
+               return;
+       }
++      spin_lock(&hsotg->lock);
+       if (req->actual == 0)
+               s3c_hsotg_enqueue_setup(hsotg);
+       else
+               s3c_hsotg_process_control(hsotg, req->buf);
++      spin_unlock(&hsotg->lock);
+ }
+ /**
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1030-USB-gadget-s3c-hsotg-fix-disconnect-handling.patch b/patches.tizen/1030-USB-gadget-s3c-hsotg-fix-disconnect-handling.patch
new file mode 100644 (file)
index 0000000..2e55676
--- /dev/null
@@ -0,0 +1,57 @@
+From 2d4c789908c85dbb8f5ea362f1bb626fe7b428be Mon Sep 17 00:00:00 2001
+From: Robert Baldyga <r.baldyga@samsung.com>
+Date: Thu, 14 Nov 2013 12:10:20 +0100
+Subject: [PATCH 1030/1302] USB: gadget: s3c-hsotg: fix disconnect handling
+
+This patch moves s3c_hsotg_disconnect function call from USBSusp interrupt
+handler to SET_ADDRESS request handler.
+
+It's because disconnected state can't be detected directly, because this
+hardware doesn't support Disconnected interrupt for device mode. For both
+Suspend and Disconnect events there is one interrupt USBSusp, but calling
+s3c_hsotg_disconnect from this interrupt handler causes config reset in
+composite layer, which is not undesirable for Suspended state.
+
+For this reason s3c_hsotg_disconnect is called from SET_ADDRESS request
+handler, which occurs always after disconnection, so we do disconnect
+immediately before we are connected again. It's probably only way we
+can do handle disconnection correctly.
+
+Change-Id: I8e69b532077c6ad76489e70fcc3f8d525fe75cf3
+Signed-off-by: Robert Baldyga <r.baldyga@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/s3c-hsotg.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
+index 6cfb562..175f35a 100644
+--- a/drivers/usb/gadget/s3c-hsotg.c
++++ b/drivers/usb/gadget/s3c-hsotg.c
+@@ -1167,6 +1167,7 @@ static int s3c_hsotg_process_req_feature(struct s3c_hsotg *hsotg,
+ }
+ static void s3c_hsotg_enqueue_setup(struct s3c_hsotg *hsotg);
++static void s3c_hsotg_disconnect(struct s3c_hsotg *hsotg);
+ /**
+  * s3c_hsotg_process_control - process a control request
+@@ -1208,6 +1209,7 @@ static void s3c_hsotg_process_control(struct s3c_hsotg *hsotg,
+       if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
+               switch (ctrl->bRequest) {
+               case USB_REQ_SET_ADDRESS:
++                      s3c_hsotg_disconnect(hsotg);
+                       dcfg = readl(hsotg->regs + DCFG);
+                       dcfg &= ~DCFG_DevAddr_MASK;
+                       dcfg |= ctrl->wValue << DCFG_DevAddr_SHIFT;
+@@ -2501,7 +2503,6 @@ irq_retry:
+               writel(GINTSTS_USBSusp, hsotg->regs + GINTSTS);
+               call_gadget(hsotg, suspend);
+-              s3c_hsotg_disconnect(hsotg);
+       }
+       if (gintsts & GINTSTS_WkUpInt) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1031-Include-kernel-configuration-in-kernel-image.patch b/patches.tizen/1031-Include-kernel-configuration-in-kernel-image.patch
new file mode 100644 (file)
index 0000000..a091017
--- /dev/null
@@ -0,0 +1,35 @@
+From 7e920996e4e8df709b0a1abf0887c0079e074a7f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C5=81ukasz=20Stelmach?= <l.stelmach@samsung.com>
+Date: Wed, 27 Nov 2013 15:59:56 +0100
+Subject: [PATCH 1031/1302] Include kernel configuration in kernel image
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Enable IKCONFIG and IKCONFIG_PROC to include the configuration of the
+kernel in the image and export it via /proc/config.gz.
+
+Change-Id: I868ba4cabd4a1517b625e81037d7758651dfa4b4
+Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_defconfig | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index 7f0e7ea..3714242 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -101,7 +101,8 @@ CONFIG_RCU_FANOUT_LEAF=16
+ # CONFIG_TREE_RCU_TRACE is not set
+ # CONFIG_RCU_BOOST is not set
+ # CONFIG_RCU_NOCB_CPU is not set
+-# CONFIG_IKCONFIG is not set
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
+ CONFIG_LOG_BUF_SHIFT=19
+ CONFIG_CGROUPS=y
+ CONFIG_CGROUP_DEBUG=y
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1032-Enable-RTC-chips-on-M0-devices.patch b/patches.tizen/1032-Enable-RTC-chips-on-M0-devices.patch
new file mode 100644 (file)
index 0000000..66a93bf
--- /dev/null
@@ -0,0 +1,45 @@
+From e5739e5325c7f4c53a40ccbfd97bb7ed84676fe5 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C5=81ukasz=20Stelmach?= <l.stelmach@samsung.com>
+Date: Wed, 27 Nov 2013 16:25:27 +0100
+Subject: [PATCH 1032/1302] Enable RTC chips on M0 devices
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Change-Id: Ide6d17af6d026230c48bededf32e8f15ca41b8e4
+Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-m0.dts | 4 ++++
+ arch/arm/configs/tizen_defconfig    | 2 +-
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-m0.dts b/arch/arm/boot/dts/exynos4412-m0.dts
+index 4bf6677..c6120bb 100644
+--- a/arch/arm/boot/dts/exynos4412-m0.dts
++++ b/arch/arm/boot/dts/exynos4412-m0.dts
+@@ -239,4 +239,8 @@
+               pulldown-ohm = <100000> ;
+               io-channels = <&adc 2>;
+       };
++
++      rtc@10070000 {
++              status = "okay";
++      };
+ };
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index 3714242..1b89de4 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -2700,7 +2700,7 @@ CONFIG_RTC_INTF_DEV=y
+ # CONFIG_RTC_DRV_DS3232 is not set
+ # CONFIG_RTC_DRV_MAX6900 is not set
+ # CONFIG_RTC_DRV_MAX8997 is not set
+-# CONFIG_RTC_DRV_MAX77686 is not set
++CONFIG_RTC_DRV_MAX77686=y
+ # CONFIG_RTC_DRV_RS5C372 is not set
+ # CONFIG_RTC_DRV_ISL1208 is not set
+ # CONFIG_RTC_DRV_ISL12022 is not set
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1033-video-display-panel-s6d6aa1-Use-devm_kzalloc-to-allo.patch b/patches.tizen/1033-video-display-panel-s6d6aa1-Use-devm_kzalloc-to-allo.patch
new file mode 100644 (file)
index 0000000..db5047b
--- /dev/null
@@ -0,0 +1,57 @@
+From ebd396d8f0fca259a69e0cb40f23475ec9148d7d Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Mon, 4 Nov 2013 16:38:47 +0100
+Subject: [PATCH 1033/1302] video: display: panel-s6d6aa1: Use devm_kzalloc to
+ allocate driver data
+
+This fixes memory leak on probe error path.
+
+Change-Id: Iafc7a9920869e59d792c480770dcb07507a998da
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/video/display/panel-s6d6aa1.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/video/display/panel-s6d6aa1.c b/drivers/video/display/panel-s6d6aa1.c
+index 9d0e7c8..b3bdf7c 100644
+--- a/drivers/video/display/panel-s6d6aa1.c
++++ b/drivers/video/display/panel-s6d6aa1.c
+@@ -691,7 +691,6 @@ static void s6d6aa1_release(struct display_entity *entity)
+       backlight_device_unregister(panel->bd);
+       regulator_bulk_free(ARRAY_SIZE(panel->supplies), panel->supplies);
+-      kfree(panel);
+ }
+ static int s6d6aa1_probe(struct platform_device *pdev)
+@@ -699,7 +698,7 @@ static int s6d6aa1_probe(struct platform_device *pdev)
+       struct s6d6aa1 *lcd;
+       int ret;
+-      lcd = kzalloc(sizeof(struct s6d6aa1), GFP_KERNEL);
++      lcd = devm_kzalloc(&pdev->dev, sizeof(struct s6d6aa1), GFP_KERNEL);
+       if (!lcd) {
+               dev_err(&pdev->dev, "failed to allocate s6d6aa1 structure.\n");
+               return -ENOMEM;
+@@ -722,7 +721,7 @@ static int s6d6aa1_probe(struct platform_device *pdev)
+                               ARRAY_SIZE(lcd->supplies), lcd->supplies);
+       if (ret) {
+               dev_err(&pdev->dev, "Failed to get regulators: %d\n", ret);
+-              goto err_regulator_bulk_get;
++              return ret;
+       }
+       lcd->ld = lcd_device_register("s6d6aa1", &pdev->dev, lcd,
+@@ -769,8 +768,6 @@ err_backlight_register:
+       lcd_device_unregister(lcd->ld);
+ err_lcd_register:
+       regulator_bulk_free(ARRAY_SIZE(lcd->supplies), lcd->supplies);
+-err_regulator_bulk_get:
+-      kfree(lcd);
+       return ret;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1034-video-display-panel-s6e8aa0-Use-devm_kzalloc-to-allo.patch b/patches.tizen/1034-video-display-panel-s6e8aa0-Use-devm_kzalloc-to-allo.patch
new file mode 100644 (file)
index 0000000..fd83471
--- /dev/null
@@ -0,0 +1,57 @@
+From ecdcadcc78238b072705a4dd3d796265e78981ed Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Mon, 4 Nov 2013 16:38:47 +0100
+Subject: [PATCH 1034/1302] video: display: panel-s6e8aa0: Use devm_kzalloc to
+ allocate driver data
+
+This fixes memory leak on probe error path.
+
+Change-Id: Ibea51282dee8139a85764f39e7c894a94036f0cf
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/video/display/panel-s6e8aa0.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/video/display/panel-s6e8aa0.c b/drivers/video/display/panel-s6e8aa0.c
+index 66c08f6..1bfa30f 100644
+--- a/drivers/video/display/panel-s6e8aa0.c
++++ b/drivers/video/display/panel-s6e8aa0.c
+@@ -1291,7 +1291,6 @@ static void s6e8aa0_release(struct display_entity *entity)
+       struct s6e8aa0 *panel = to_panel(entity);
+       regulator_bulk_free(ARRAY_SIZE(panel->supplies), panel->supplies);
+-      kfree(panel);
+ }
+ static int s6e8aa0_probe(struct platform_device *pdev)
+@@ -1299,7 +1298,7 @@ static int s6e8aa0_probe(struct platform_device *pdev)
+       struct s6e8aa0 *lcd;
+       int ret;
+-      lcd = kzalloc(sizeof(struct s6e8aa0), GFP_KERNEL);
++      lcd = devm_kzalloc(&pdev->dev, sizeof(struct s6e8aa0), GFP_KERNEL);
+       if (!lcd) {
+               dev_err(&pdev->dev, "failed to allocate s6e8aa0 structure.\n");
+               return -ENOMEM;
+@@ -1322,7 +1321,7 @@ static int s6e8aa0_probe(struct platform_device *pdev)
+                               ARRAY_SIZE(lcd->supplies), lcd->supplies);
+       if (ret) {
+               dev_err(&pdev->dev, "Failed to get regulators: %d\n", ret);
+-              goto err_regulator_bulk_get;
++              return ret;
+       }
+       lcd->ld = lcd_device_register("s6e8aa0", &pdev->dev, lcd,
+@@ -1370,8 +1369,6 @@ err_backlight_register:
+       lcd_device_unregister(lcd->ld);
+ err_lcd_register:
+       regulator_bulk_free(ARRAY_SIZE(lcd->supplies), lcd->supplies);
+-err_regulator_bulk_get:
+-      kfree(lcd);
+       return ret;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1035-mmc-sdhci-pltfm-Use-devm_ioremap_resource.patch b/patches.tizen/1035-mmc-sdhci-pltfm-Use-devm_ioremap_resource.patch
new file mode 100644 (file)
index 0000000..1fae583
--- /dev/null
@@ -0,0 +1,66 @@
+From 76d2df2a41da7fee04cc8a512758e03813420480 Mon Sep 17 00:00:00 2001
+From: Beomho Seo <beomho.seo@samsung.com>
+Date: Tue, 3 Dec 2013 17:25:13 +0900
+Subject: [PATCH 1035/1302] mmc: sdhci-pltfm: Use devm_ioremap_resource()
+
+This patch devm_ioremap_resource for replace request region and ioremap.
+
+Change-Id: I6b63e1db0d0c9d6d8cf89a93d57db0b253418e3a
+Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mmc/host/sdhci-pltfm.c | 23 ++++-------------------
+ 1 file changed, 4 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
+index cd0f1f6..be90c47 100644
+--- a/drivers/mmc/host/sdhci-pltfm.c
++++ b/drivers/mmc/host/sdhci-pltfm.c
+@@ -154,18 +154,10 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
+               host->quirks = pdata->quirks;
+       host->irq = platform_get_irq(pdev, 0);
+-      if (!request_mem_region(iomem->start, resource_size(iomem),
+-              mmc_hostname(host->mmc))) {
+-              dev_err(&pdev->dev, "cannot request region\n");
+-              ret = -EBUSY;
+-              goto err_request;
+-      }
+-
+-      host->ioaddr = ioremap(iomem->start, resource_size(iomem));
+-      if (!host->ioaddr) {
+-              dev_err(&pdev->dev, "failed to remap registers\n");
+-              ret = -ENOMEM;
+-              goto err_remap;
++      host->ioaddr = devm_ioremap_resource(&pdev->dev, iomem);
++      if (IS_ERR(host->ioaddr)) {
++              ret = PTR_ERR(host->ioaddr);
++              goto err;
+       }
+       /*
+@@ -179,10 +171,6 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
+       return host;
+-err_remap:
+-      release_mem_region(iomem->start, resource_size(iomem));
+-err_request:
+-      sdhci_free_host(host);
+ err:
+       dev_err(&pdev->dev, "%s failed %d\n", __func__, ret);
+       return ERR_PTR(ret);
+@@ -192,10 +180,7 @@ EXPORT_SYMBOL_GPL(sdhci_pltfm_init);
+ void sdhci_pltfm_free(struct platform_device *pdev)
+ {
+       struct sdhci_host *host = platform_get_drvdata(pdev);
+-      struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-      iounmap(host->ioaddr);
+-      release_mem_region(iomem->start, resource_size(iomem));
+       sdhci_free_host(host);
+       platform_set_drvdata(pdev, NULL);
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1036-mfd-max77693-Fix-mapping-IRQ-during-mask-unmask.patch b/patches.tizen/1036-mfd-max77693-Fix-mapping-IRQ-during-mask-unmask.patch
new file mode 100644 (file)
index 0000000..c3821fd
--- /dev/null
@@ -0,0 +1,33 @@
+From d5d7c6aa9bc065ab5531808297cb6cd4aa06bbd4 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+Date: Tue, 3 Dec 2013 15:49:13 +0100
+Subject: [PATCH 1036/1302] mfd: max77693: Fix mapping IRQ during mask/unmask
+
+Use hwirq in max77693_irq_mask() and max77693_irq_unmask() for accessing
+irq array. Previously the virtual irq was used which resulted in
+out-of-bounds access.
+
+Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+Change-Id: I6e2e6751d07427072e90d9f4dfef921108485f29
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mfd/max77693-irq.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mfd/max77693-irq.c b/drivers/mfd/max77693-irq.c
+index 1029d01..66b58fe 100644
+--- a/drivers/mfd/max77693-irq.c
++++ b/drivers/mfd/max77693-irq.c
+@@ -128,7 +128,8 @@ static void max77693_irq_sync_unlock(struct irq_data *data)
+ static const inline struct max77693_irq_data *
+ irq_to_max77693_irq(struct max77693_dev *max77693, int irq)
+ {
+-      return &max77693_irqs[irq];
++      struct irq_data *data = irq_get_irq_data(irq);
++      return &max77693_irqs[data->hwirq];
+ }
+ static void max77693_irq_mask(struct irq_data *data)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1037-mmc-sdhci-s3c-sdhci-s3c-driver-use-sdhci-pltfm.patch b/patches.tizen/1037-mmc-sdhci-s3c-sdhci-s3c-driver-use-sdhci-pltfm.patch
new file mode 100644 (file)
index 0000000..d5ac063
--- /dev/null
@@ -0,0 +1,590 @@
+From 35c31a61d072db7ca564837a407c519246448f3b Mon Sep 17 00:00:00 2001
+From: Beomho Seo <beomho.seo@samsung.com>
+Date: Wed, 4 Dec 2013 19:46:44 +0900
+Subject: [PATCH 1037/1302] mmc: sdhci-s3c: sdhci-s3c driver use sdhci-pltfm
+
+This patch revised to use sdhci-pltfm.
+
+Change-Id: Ib11e5a4005aa7c78261c12e7c8df027acd71575e
+Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mmc/host/sdhci-s3c.c | 247 +++++++++++++++++++------------------------
+ 1 file changed, 107 insertions(+), 140 deletions(-)
+
+diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
+index 17abed3..d6ea10b 100644
+--- a/drivers/mmc/host/sdhci-s3c.c
++++ b/drivers/mmc/host/sdhci-s3c.c
+@@ -31,6 +31,7 @@
+ #include "sdhci-s3c-regs.h"
+ #include "sdhci.h"
++#include "sdhci-pltfm.h"
+ #define MAX_BUS_CLK   (4)
+@@ -39,22 +40,13 @@
+ /**
+  * struct sdhci_s3c - S3C SDHCI instance
+- * @host: The SDHCI host created
+  * @pdev: The platform device we where created from.
+- * @ioarea: The resource created when we claimed the IO area.
+  * @pdata: The platform data for this controller.
+- * @cur_clk: The index of the current bus clock.
+- * @clk_io: The clock for the internal bus interface.
+  * @clk_bus: The clocks that are available for the SD/MMC bus clock.
+  */
+ struct sdhci_s3c {
+-      struct sdhci_host       *host;
+       struct platform_device  *pdev;
+-      struct resource         *ioarea;
+       struct s3c_sdhci_platdata *pdata;
+-      unsigned int            cur_clk;
+-
+-      struct clk              *clk_io;
+       struct clk              *clk_bus[MAX_BUS_CLK];
+ };
+@@ -70,11 +62,6 @@ struct sdhci_s3c_drv_data {
+       unsigned int    sdhci_quirks;
+ };
+-static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host)
+-{
+-      return sdhci_priv(host);
+-}
+-
+ /**
+  * get_curclk - convert ctrl2 register to clock source number
+  * @ctrl2: Control2 register value.
+@@ -89,14 +76,15 @@ static u32 get_curclk(u32 ctrl2)
+ static void sdhci_s3c_check_sclk(struct sdhci_host *host)
+ {
+-      struct sdhci_s3c *ourhost = to_s3c(host);
++      struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
++      struct sdhci_s3c *ourhost = pltfm_host->priv;
+       u32 tmp = readl(host->ioaddr + S3C_SDHCI_CONTROL2);
+-      if (get_curclk(tmp) != ourhost->cur_clk) {
++      if (get_curclk(tmp) != pltfm_host->clock) {
+               dev_dbg(&ourhost->pdev->dev, "restored ctrl2 clock setting\n");
+               tmp &= ~S3C_SDHCI_CTRL2_SELBASECLK_MASK;
+-              tmp |= ourhost->cur_clk << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT;
++              tmp |= pltfm_host->clock << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT;
+               writel(tmp, host->ioaddr + S3C_SDHCI_CONTROL2);
+       }
+ }
+@@ -109,7 +97,8 @@ static void sdhci_s3c_check_sclk(struct sdhci_host *host)
+ */
+ static unsigned int sdhci_s3c_get_max_clk(struct sdhci_host *host)
+ {
+-      struct sdhci_s3c *ourhost = to_s3c(host);
++      struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
++      struct sdhci_s3c *ourhost = pltfm_host->priv;
+       struct clk *busclk;
+       unsigned int rate, max;
+       int clk;
+@@ -137,11 +126,13 @@ static unsigned int sdhci_s3c_get_max_clk(struct sdhci_host *host)
+  * @src: The source clock index.
+  * @wanted: The clock frequency wanted.
+  */
+-static unsigned int sdhci_s3c_consider_clock(struct sdhci_s3c *ourhost,
++static unsigned int sdhci_s3c_consider_clock(struct sdhci_host *host,
+                                            unsigned int src,
+                                            unsigned int wanted)
+ {
+       unsigned long rate;
++      struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
++      struct sdhci_s3c *ourhost = pltfm_host->priv;
+       struct clk *clksrc = ourhost->clk_bus[src];
+       int div;
+@@ -152,7 +143,7 @@ static unsigned int sdhci_s3c_consider_clock(struct sdhci_s3c *ourhost,
+        * If controller uses a non-standard clock division, find the best clock
+        * speed possible with selected clock source and skip the division.
+        */
+-      if (ourhost->host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) {
++      if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) {
+               rate = clk_round_rate(clksrc, wanted);
+               return wanted - rate;
+       }
+@@ -180,7 +171,8 @@ static unsigned int sdhci_s3c_consider_clock(struct sdhci_s3c *ourhost,
+ */
+ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
+ {
+-      struct sdhci_s3c *ourhost = to_s3c(host);
++      struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
++      struct sdhci_s3c *ourhost = pltfm_host->priv;
+       unsigned int best = UINT_MAX;
+       unsigned int delta;
+       int best_src = 0;
+@@ -192,7 +184,7 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
+               return;
+       for (src = 0; src < MAX_BUS_CLK; src++) {
+-              delta = sdhci_s3c_consider_clock(ourhost, src, clock);
++              delta = sdhci_s3c_consider_clock(host, src, clock);
+               if (delta < best) {
+                       best = delta;
+                       best_src = src;
+@@ -204,16 +196,16 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
+                best_src, clock, best);
+       /* select the new clock source */
+-      if (ourhost->cur_clk != best_src) {
++      if (pltfm_host->clock != best_src) {
+               struct clk *clk = ourhost->clk_bus[best_src];
+               clk_prepare_enable(clk);
+-              clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]);
++              clk_disable_unprepare(ourhost->clk_bus[pltfm_host->clock]);
+               /* turn clock off to card before changing clock source */
+               writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
+-              ourhost->cur_clk = best_src;
++              pltfm_host->clock = best_src;
+               host->max_clk = clk_get_rate(clk);
+               ctrl = readl(host->ioaddr + S3C_SDHCI_CONTROL2);
+@@ -252,12 +244,11 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
+ */
+ static unsigned int sdhci_s3c_get_min_clock(struct sdhci_host *host)
+ {
+-      struct sdhci_s3c *ourhost = to_s3c(host);
+       unsigned int delta, min = UINT_MAX;
+       int src;
+       for (src = 0; src < MAX_BUS_CLK; src++) {
+-              delta = sdhci_s3c_consider_clock(ourhost, src, 0);
++              delta = sdhci_s3c_consider_clock(host, src, 0);
+               if (delta == UINT_MAX)
+                       continue;
+               /* delta is a negative value in this case */
+@@ -270,27 +261,30 @@ static unsigned int sdhci_s3c_get_min_clock(struct sdhci_host *host)
+ /* sdhci_cmu_get_max_clk - callback to get maximum clock frequency.*/
+ static unsigned int sdhci_cmu_get_max_clock(struct sdhci_host *host)
+ {
+-      struct sdhci_s3c *ourhost = to_s3c(host);
++      struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
++      struct sdhci_s3c *ourhost = pltfm_host->priv;
+-      return clk_round_rate(ourhost->clk_bus[ourhost->cur_clk], UINT_MAX);
++      return clk_round_rate(ourhost->clk_bus[pltfm_host->clock], UINT_MAX);
+ }
+ /* sdhci_cmu_get_min_clock - callback to get minimal supported clock value. */
+ static unsigned int sdhci_cmu_get_min_clock(struct sdhci_host *host)
+ {
+-      struct sdhci_s3c *ourhost = to_s3c(host);
++      struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
++      struct sdhci_s3c *ourhost = pltfm_host->priv;
+       /*
+        * initial clock can be in the frequency range of
+        * 100KHz-400KHz, so we set it as max value.
+        */
+-      return clk_round_rate(ourhost->clk_bus[ourhost->cur_clk], 400000);
++      return clk_round_rate(ourhost->clk_bus[pltfm_host->clock], 400000);
+ }
+ /* sdhci_cmu_set_clock - callback on clock change.*/
+ static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
+ {
+-      struct sdhci_s3c *ourhost = to_s3c(host);
++      struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
++      struct sdhci_s3c *ourhost = pltfm_host->priv;
+       struct device *dev = &ourhost->pdev->dev;
+       unsigned long timeout;
+       u16 clk = 0;
+@@ -301,7 +295,7 @@ static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
+       sdhci_s3c_set_clock(host, clock);
+-      clk_set_rate(ourhost->clk_bus[ourhost->cur_clk], clock);
++      clk_set_rate(ourhost->clk_bus[pltfm_host->clock], clock);
+       host->clock = clock;
+@@ -388,13 +382,19 @@ static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
+ }
+ #ifdef CONFIG_OF
+-static int sdhci_s3c_parse_dt(struct device *dev,
+-              struct sdhci_host *host, struct s3c_sdhci_platdata *pdata)
++static struct s3c_sdhci_platdata *sdhci_s3c_parse_dt(struct device *dev)
+ {
++      struct s3c_sdhci_platdata *pdata = NULL;
+       struct device_node *node = dev->of_node;
+       u32 max_width;
+       int gpio;
++      pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
++      if (!pdata) {
++              dev_err(dev, "No memory for pdata\n");
++              return ERR_PTR(-EINVAL);
++      }
++
+       /* if the bus-width property is not specified, assume width as 1 */
+       if (of_property_read_u32(node, "bus-width", &max_width))
+               max_width = 1;
+@@ -403,12 +403,12 @@ static int sdhci_s3c_parse_dt(struct device *dev,
+       /* get the card detection method */
+       if (of_get_property(node, "broken-cd", NULL)) {
+               pdata->cd_type = S3C_SDHCI_CD_NONE;
+-              return 0;
++              return pdata;
+       }
+       if (of_get_property(node, "non-removable", NULL)) {
+               pdata->cd_type = S3C_SDHCI_CD_PERMANENT;
+-              return 0;
++              return pdata;
+       }
+       gpio = of_get_named_gpio(node, "cd-gpios", 0);
+@@ -417,21 +417,20 @@ static int sdhci_s3c_parse_dt(struct device *dev,
+               pdata->ext_cd_gpio = gpio;
+               if (of_get_property(node, "cd-inverted", NULL))
+                       pdata->ext_cd_gpio_invert = 1;
+-              return 0;
++              return pdata;
+       } else if (gpio != -ENOENT) {
+               dev_err(dev, "invalid card detect gpio specified\n");
+-              return -EINVAL;
++              return ERR_PTR(-EINVAL);
+       }
+       /* assuming internal card detect that will be configured by pinctrl */
+       pdata->cd_type = S3C_SDHCI_CD_INTERNAL;
+-      return 0;
++      return pdata;
+ }
+ #else
+-static int sdhci_s3c_parse_dt(struct device *dev,
+-              struct sdhci_host *host, struct s3c_sdhci_platdata *pdata)
++static struct s3c_sdhci_platdata *sdhci_s3c_parse_dt(struct device *dev)
+ {
+-      return -EINVAL;
++      return ERR_PTR(-EINVAL);
+ }
+ #endif
+@@ -451,65 +450,67 @@ static inline struct sdhci_s3c_drv_data *sdhci_s3c_get_driver_data(
+                       platform_get_device_id(pdev)->driver_data;
+ }
++static struct sdhci_pltfm_data sdhci_s3c_pdata = {
++      .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC |
++              SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_NO_BUSY_IRQ |
++              SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 |
++              SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC |
++              SDHCI_QUIRK_32BIT_DMA_ADDR | SDHCI_QUIRK_32BIT_DMA_SIZE |
++              SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK,
++      .ops = &sdhci_s3c_ops,
++};
++
+ static int sdhci_s3c_probe(struct platform_device *pdev)
+ {
+-      struct s3c_sdhci_platdata *pdata;
+       struct sdhci_s3c_drv_data *drv_data;
+       struct device *dev = &pdev->dev;
+       struct sdhci_host *host;
+       struct sdhci_s3c *sc;
+-      struct resource *res;
+-      int ret, irq, ptr, clks;
++      int ret = 0, ptr, clks;
++      struct sdhci_pltfm_host *pltfm_host;
+       if (!pdev->dev.platform_data && !pdev->dev.of_node) {
+               dev_err(dev, "no device data specified\n");
+               return -ENOENT;
+       }
+-      irq = platform_get_irq(pdev, 0);
+-      if (irq < 0) {
+-              dev_err(dev, "no irq specified\n");
+-              return irq;
+-      }
+-
+-      host = sdhci_alloc_host(dev, sizeof(struct sdhci_s3c));
++      host = sdhci_pltfm_init(pdev, &sdhci_s3c_pdata);
+       if (IS_ERR(host)) {
+               dev_err(dev, "sdhci_alloc_host() failed\n");
+               return PTR_ERR(host);
+       }
+-      sc = sdhci_priv(host);
+-      pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+-      if (!pdata) {
++      sc = devm_kzalloc(dev, sizeof(struct sdhci_s3c), GFP_KERNEL);
++      if (!sc) {
+               ret = -ENOMEM;
+               goto err_pdata_io_clk;
+       }
++      pltfm_host = sdhci_priv(host);
++      pltfm_host->priv = sc;
++
+       if (pdev->dev.of_node) {
+-              ret = sdhci_s3c_parse_dt(&pdev->dev, host, pdata);
+-              if (ret)
++              sc->pdata = sdhci_s3c_parse_dt(&pdev->dev);
++              if (!sc->pdata)
+                       goto err_pdata_io_clk;
+       } else
+-              memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata));
+-
++              memcpy(&sc->pdata, &pdev->dev.platform_data, sizeof(sc->pdata));
+       drv_data = sdhci_s3c_get_driver_data(pdev);
++      if (drv_data)
++              host->quirks |= drv_data->sdhci_quirks;
+-      sc->host = host;
+       sc->pdev = pdev;
+-      sc->pdata = pdata;
+-
+-      platform_set_drvdata(pdev, host);
+-      sc->clk_io = devm_clk_get(dev, "hsmmc");
+-      if (IS_ERR(sc->clk_io)) {
++      pltfm_host->clk = devm_clk_get(dev, "hsmmc");
++      if (IS_ERR(pltfm_host->clk)) {
+               dev_err(dev, "failed to get io clock\n");
+-              ret = PTR_ERR(sc->clk_io);
++              ret = PTR_ERR(pltfm_host->clk);
+               goto err_pdata_io_clk;
+       }
+       /* enable the local io clock and keep it running for the moment. */
+-      clk_prepare_enable(sc->clk_io);
++      clk_prepare_enable(pltfm_host->clk);
+       for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
+               struct clk *clk;
+@@ -527,7 +528,7 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
+                * save current clock index to know which clock bus
+                * is used later in overriding functions.
+                */
+-              sc->cur_clk = ptr;
++              pltfm_host->clock = ptr;
+               dev_info(dev, "clock source %d: %s (%ld Hz)\n",
+                        ptr, name, clk_get_rate(clk));
+@@ -540,30 +541,12 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
+       }
+ #ifndef CONFIG_PM_RUNTIME
+-      clk_prepare_enable(sc->clk_bus[sc->cur_clk]);
++      clk_prepare_enable(sc->clk_bus[pltfm_host->clock]);
+ #endif
+-      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-      host->ioaddr = devm_ioremap_resource(&pdev->dev, res);
+-      if (IS_ERR(host->ioaddr)) {
+-              ret = PTR_ERR(host->ioaddr);
+-              goto err_req_regs;
+-      }
+-
+       /* Ensure we have minimal gpio selected CMD/CLK/Detect */
+-      if (pdata->cfg_gpio)
+-              pdata->cfg_gpio(pdev, pdata->max_width);
+-
+-      host->hw_name = "samsung-hsmmc";
+-      host->ops = &sdhci_s3c_ops;
+-      host->quirks = 0;
+-      host->irq = irq;
+-
+-      /* Setup quirks for the controller */
+-      host->quirks |= SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC;
+-      host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
+-      if (drv_data)
+-              host->quirks |= drv_data->sdhci_quirks;
++      if (sc->pdata->cfg_gpio)
++              sc->pdata->cfg_gpio(pdev, sc->pdata->max_width);
+ #ifndef CONFIG_MMC_SDHCI_S3C_DMA
+@@ -573,25 +556,14 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
+ #endif /* CONFIG_MMC_SDHCI_S3C_DMA */
+-      /* It seems we do not get an DATA transfer complete on non-busy
+-       * transfers, not sure if this is a problem with this specific
+-       * SDHCI block, or a missing configuration that needs to be set. */
+-      host->quirks |= SDHCI_QUIRK_NO_BUSY_IRQ;
+-
+-      /* This host supports the Auto CMD12 */
+-      host->quirks |= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12;
+-
+-      /* Samsung SoCs need BROKEN_ADMA_ZEROLEN_DESC */
+-      host->quirks |= SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC;
+-
+-      if (pdata->cd_type == S3C_SDHCI_CD_NONE ||
+-          pdata->cd_type == S3C_SDHCI_CD_PERMANENT)
++      if (sc->pdata->cd_type == S3C_SDHCI_CD_NONE ||
++          sc->pdata->cd_type == S3C_SDHCI_CD_PERMANENT)
+               host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
+-      if (pdata->cd_type == S3C_SDHCI_CD_PERMANENT)
++      if (sc->pdata->cd_type == S3C_SDHCI_CD_PERMANENT)
+               host->mmc->caps = MMC_CAP_NONREMOVABLE;
+-      switch (pdata->max_width) {
++      switch (sc->pdata->max_width) {
+       case 8:
+               host->mmc->caps |= MMC_CAP_8_BIT_DATA;
+       case 4:
+@@ -599,14 +571,8 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
+               break;
+       }
+-      if (pdata->pm_caps)
+-              host->mmc->pm_caps |= pdata->pm_caps;
+-
+-      host->quirks |= (SDHCI_QUIRK_32BIT_DMA_ADDR |
+-                       SDHCI_QUIRK_32BIT_DMA_SIZE);
+-
+-      /* HSMMC on Samsung SoCs uses SDCLK as timeout clock */
+-      host->quirks |= SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK;
++      if (sc->pdata->pm_caps)
++              host->mmc->pm_caps |= sc->pdata->pm_caps;
+       /*
+        * If controller does not have internal clock divider,
+@@ -619,11 +585,11 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
+       }
+       /* It supports additional host capabilities if needed */
+-      if (pdata->host_caps)
+-              host->mmc->caps |= pdata->host_caps;
++      if (sc->pdata->host_caps)
++              host->mmc->caps |= sc->pdata->host_caps;
+-      if (pdata->host_caps2)
+-              host->mmc->caps2 |= pdata->host_caps2;
++      if (sc->pdata->host_caps2)
++              host->mmc->caps2 |= sc->pdata->host_caps2;
+       pm_runtime_enable(&pdev->dev);
+       pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
+@@ -641,22 +607,23 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
+       /* The following two methods of card detection might call
+          sdhci_s3c_notify_change() immediately, so they can be called
+          only after sdhci_add_host(). Setup errors are ignored. */
+-      if (pdata->cd_type == S3C_SDHCI_CD_EXTERNAL && pdata->ext_cd_init)
+-              pdata->ext_cd_init(&sdhci_s3c_notify_change);
+-      if (pdata->cd_type == S3C_SDHCI_CD_GPIO &&
+-          gpio_is_valid(pdata->ext_cd_gpio)) {
+-              ret = mmc_gpio_request_cd(host->mmc, pdata->ext_cd_gpio);
++      if (sc->pdata->cd_type == S3C_SDHCI_CD_EXTERNAL &&
++          sc->pdata->ext_cd_init)
++              sc->pdata->ext_cd_init(&sdhci_s3c_notify_change);
++      if (sc->pdata->cd_type == S3C_SDHCI_CD_GPIO &&
++          gpio_is_valid(sc->pdata->ext_cd_gpio)) {
++              ret = mmc_gpio_request_cd(host->mmc, sc->pdata->ext_cd_gpio);
+               if (ret) {
+                       dev_err(dev,
+                               "failed to request card detect gpio\n");
+                       goto err_req_cd;
+               }
+-              irq_set_irq_wake(gpio_to_irq(pdata->ext_cd_gpio), 1);
++              irq_set_irq_wake(gpio_to_irq(sc->pdata->ext_cd_gpio), 1);
+       }
+ #ifdef CONFIG_PM_RUNTIME
+-      if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL)
+-              clk_disable_unprepare(sc->clk_io);
++      if (sc->pdata->cd_type != S3C_SDHCI_CD_INTERNAL)
++              clk_disable_unprepare(pltfm_host->clk);
+ #endif
+       return 0;
+@@ -665,11 +632,11 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
+  err_req_regs:
+ #ifndef CONFIG_PM_RUNTIME
+-      clk_disable_unprepare(sc->clk_bus[sc->cur_clk]);
++      clk_disable_unprepare(sc->clk_bus[pltfm_host->clock]);
+ #endif
+  err_no_busclks:
+-      clk_disable_unprepare(sc->clk_io);
++      clk_disable_unprepare(pltfm_host->clk);
+  err_pdata_io_clk:
+       sdhci_free_host(host);
+@@ -680,7 +647,8 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
+ static int sdhci_s3c_remove(struct platform_device *pdev)
+ {
+       struct sdhci_host *host =  platform_get_drvdata(pdev);
+-      struct sdhci_s3c *sc = sdhci_priv(host);
++      struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
++      struct sdhci_s3c *sc = pltfm_host->priv;
+       struct s3c_sdhci_platdata *pdata = sc->pdata;
+       if (pdata->cd_type == S3C_SDHCI_CD_EXTERNAL && pdata->ext_cd_cleanup)
+@@ -691,7 +659,7 @@ static int sdhci_s3c_remove(struct platform_device *pdev)
+ #ifdef CONFIG_PM_RUNTIME
+       if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL)
+-              clk_prepare_enable(sc->clk_io);
++              clk_prepare_enable(pltfm_host->clk);
+ #endif
+       sdhci_remove_host(host, 1);
+@@ -699,9 +667,9 @@ static int sdhci_s3c_remove(struct platform_device *pdev)
+       pm_runtime_disable(&pdev->dev);
+ #ifndef CONFIG_PM_RUNTIME
+-      clk_disable_unprepare(sc->clk_bus[sc->cur_clk]);
++      clk_disable_unprepare(sc->clk_bus[pltfm_host->clock]);
+ #endif
+-      clk_disable_unprepare(sc->clk_io);
++      clk_disable_unprepare(pltfm_host->clk);
+       sdhci_free_host(host);
+       platform_set_drvdata(pdev, NULL);
+@@ -729,26 +697,25 @@ static int sdhci_s3c_resume(struct device *dev)
+ static int sdhci_s3c_runtime_suspend(struct device *dev)
+ {
+       struct sdhci_host *host = dev_get_drvdata(dev);
+-      struct sdhci_s3c *ourhost = to_s3c(host);
+-      struct clk *busclk = ourhost->clk_io;
++      struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
++      struct sdhci_s3c *ourhost = pltfm_host->priv;
+       int ret;
+       ret = sdhci_runtime_suspend_host(host);
+-
+-      clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]);
+-      clk_disable_unprepare(busclk);
++      clk_disable_unprepare(ourhost->clk_bus[pltfm_host->clock]);
++      clk_disable_unprepare(pltfm_host->clk);
+       return ret;
+ }
+ static int sdhci_s3c_runtime_resume(struct device *dev)
+ {
+       struct sdhci_host *host = dev_get_drvdata(dev);
+-      struct sdhci_s3c *ourhost = to_s3c(host);
+-      struct clk *busclk = ourhost->clk_io;
++      struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
++      struct sdhci_s3c *ourhost = pltfm_host->priv;
+       int ret;
+-      clk_prepare_enable(busclk);
+-      clk_prepare_enable(ourhost->clk_bus[ourhost->cur_clk]);
++      clk_prepare_enable(pltfm_host->clk);
++      clk_prepare_enable(ourhost->clk_bus[pltfm_host->clock]);
+       ret = sdhci_runtime_resume_host(host);
+       return ret;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1038-dts-exynos4x12-fix-clock-properties.patch b/patches.tizen/1038-dts-exynos4x12-fix-clock-properties.patch
new file mode 100644 (file)
index 0000000..f3413c6
--- /dev/null
@@ -0,0 +1,46 @@
+From c3f62262be187c199f4dfa9980a4aa0f132b1957 Mon Sep 17 00:00:00 2001
+From: Beomho Seo <beomho.seo@samsung.com>
+Date: Mon, 9 Dec 2013 19:43:06 +0900
+Subject: [PATCH 1038/1302] dts: exynos4x12: fix clock properties.
+
+This patch fix incorrect clock properties.
+And then, move fixed clock properties to
+exynos4x12.dtsi to avoid further duplication of broken properties.
+
+Change-Id: Ib980422ad67af8dc2493f1886f6e26f23b451d12
+Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 2 --
+ arch/arm/boot/dts/exynos4x12.dtsi       | 2 ++
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index e99ddc9..0867ada 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -266,8 +266,6 @@
+               fifo-depth = <0x80>;
+               desc-num = <4>;
+               card-detect-delay = <200>;
+-              clocks = <&clock 351>, <&clock 132>;
+-              clock-name = "biu", "ciu";
+               vmmc-supply = <&vemmc_reg>;
+               clock-frequency = <400000000>;
+               samsung,dw-mshc-ciu-div = <0>;
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index 5d73533..f47b326 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -83,6 +83,8 @@
+               interrupts = <0 77 0>;
+               #address-cells = <1>;
+               #size-cells = <0>;
++              clocks = <&clock 301>, <&clock 149>;
++              clock-names = "biu", "ciu";
+       };
+       pinctrl_2: pinctrl@03860000 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1039-pinctrl-exynos-Add-spinlocks-to-irq_mask-and-irq_unm.patch b/patches.tizen/1039-pinctrl-exynos-Add-spinlocks-to-irq_mask-and-irq_unm.patch
new file mode 100644 (file)
index 0000000..92877b3
--- /dev/null
@@ -0,0 +1,94 @@
+From 57e707a8272884bf153036c255c9b95394408804 Mon Sep 17 00:00:00 2001
+From: Doug Anderson <dianders@chromium.org>
+Date: Wed, 12 Jun 2013 10:33:17 -0700
+Subject: [PATCH 1039/1302] pinctrl: exynos: Add spinlocks to irq_mask and
+ irq_unmask
+
+The patch:
+  1984695 pinctrl: samsung: Protect bank registers with a spinlock
+
+...added spinlocks to protect many accesses.  However, the irq_mask
+and irq_unmask functions still do an unprotected read/modify/write.
+Add the spinlock there.
+
+Change-Id: I892cfcd82368466184b99eab75d2bc7882674211
+Signed-off-by: Doug Anderson <dianders@chromium.org>
+Acked-by: Tomasz Figa <t.figa@samsung.com>
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/pinctrl/pinctrl-exynos.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
+index 2d76f66..c29a28e 100644
+--- a/drivers/pinctrl/pinctrl-exynos.c
++++ b/drivers/pinctrl/pinctrl-exynos.c
+@@ -56,10 +56,15 @@ static void exynos_gpio_irq_unmask(struct irq_data *irqd)
+       struct samsung_pinctrl_drv_data *d = bank->drvdata;
+       unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset;
+       unsigned long mask;
++      unsigned long flags;
++
++      spin_lock_irqsave(&bank->slock, flags);
+       mask = readl(d->virt_base + reg_mask);
+       mask &= ~(1 << irqd->hwirq);
+       writel(mask, d->virt_base + reg_mask);
++
++      spin_unlock_irqrestore(&bank->slock, flags);
+ }
+ static void exynos_gpio_irq_mask(struct irq_data *irqd)
+@@ -68,10 +73,15 @@ static void exynos_gpio_irq_mask(struct irq_data *irqd)
+       struct samsung_pinctrl_drv_data *d = bank->drvdata;
+       unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset;
+       unsigned long mask;
++      unsigned long flags;
++
++      spin_lock_irqsave(&bank->slock, flags);
+       mask = readl(d->virt_base + reg_mask);
+       mask |= 1 << irqd->hwirq;
+       writel(mask, d->virt_base + reg_mask);
++
++      spin_unlock_irqrestore(&bank->slock, flags);
+ }
+ static void exynos_gpio_irq_ack(struct irq_data *irqd)
+@@ -264,10 +274,15 @@ static void exynos_wkup_irq_unmask(struct irq_data *irqd)
+       struct samsung_pinctrl_drv_data *d = b->drvdata;
+       unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset;
+       unsigned long mask;
++      unsigned long flags;
++
++      spin_lock_irqsave(&b->slock, flags);
+       mask = readl(d->virt_base + reg_mask);
+       mask &= ~(1 << irqd->hwirq);
+       writel(mask, d->virt_base + reg_mask);
++
++      spin_unlock_irqrestore(&b->slock, flags);
+ }
+ static void exynos_wkup_irq_mask(struct irq_data *irqd)
+@@ -276,10 +291,15 @@ static void exynos_wkup_irq_mask(struct irq_data *irqd)
+       struct samsung_pinctrl_drv_data *d = b->drvdata;
+       unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset;
+       unsigned long mask;
++      unsigned long flags;
++
++      spin_lock_irqsave(&b->slock, flags);
+       mask = readl(d->virt_base + reg_mask);
+       mask |= 1 << irqd->hwirq;
+       writel(mask, d->virt_base + reg_mask);
++
++      spin_unlock_irqrestore(&b->slock, flags);
+ }
+ static void exynos_wkup_irq_ack(struct irq_data *irqd)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1040-pinctrl-exynos-reorder-xyz_irq_unmask-so-future-patc.patch b/patches.tizen/1040-pinctrl-exynos-reorder-xyz_irq_unmask-so-future-patc.patch
new file mode 100644 (file)
index 0000000..e344d7c
--- /dev/null
@@ -0,0 +1,140 @@
+From 3f3cfdda411a43c846dd043abaf90216e558d96d Mon Sep 17 00:00:00 2001
+From: Doug Anderson <dianders@chromium.org>
+Date: Wed, 12 Jun 2013 10:33:18 -0700
+Subject: [PATCH 1040/1302] pinctrl: exynos: reorder xyz_irq_unmask() so future
+ patch can ack
+
+This patch does nothing but reorder the functions to improve the
+readability of a future patch.
+
+Change-Id: Ia70d2969d88f6b4579617209be1cedbbf6bbc26c
+Signed-off-by: Doug Anderson <dianders@chromium.org>
+Acked-by: Tomasz Figa <t.figa@samsung.com>
+Acked-by: Kukjin Kim <kgene.kim@samsung.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/pinctrl/pinctrl-exynos.c | 52 ++++++++++++++++++++--------------------
+ 1 file changed, 26 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
+index c29a28e..c0729a3 100644
+--- a/drivers/pinctrl/pinctrl-exynos.c
++++ b/drivers/pinctrl/pinctrl-exynos.c
+@@ -50,7 +50,7 @@ static const struct of_device_id exynos_wkup_irq_ids[] = {
+       { }
+ };
+-static void exynos_gpio_irq_unmask(struct irq_data *irqd)
++static void exynos_gpio_irq_mask(struct irq_data *irqd)
+ {
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+       struct samsung_pinctrl_drv_data *d = bank->drvdata;
+@@ -61,13 +61,22 @@ static void exynos_gpio_irq_unmask(struct irq_data *irqd)
+       spin_lock_irqsave(&bank->slock, flags);
+       mask = readl(d->virt_base + reg_mask);
+-      mask &= ~(1 << irqd->hwirq);
++      mask |= 1 << irqd->hwirq;
+       writel(mask, d->virt_base + reg_mask);
+       spin_unlock_irqrestore(&bank->slock, flags);
+ }
+-static void exynos_gpio_irq_mask(struct irq_data *irqd)
++static void exynos_gpio_irq_ack(struct irq_data *irqd)
++{
++      struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
++      struct samsung_pinctrl_drv_data *d = bank->drvdata;
++      unsigned long reg_pend = d->ctrl->geint_pend + bank->eint_offset;
++
++      writel(1 << irqd->hwirq, d->virt_base + reg_pend);
++}
++
++static void exynos_gpio_irq_unmask(struct irq_data *irqd)
+ {
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+       struct samsung_pinctrl_drv_data *d = bank->drvdata;
+@@ -78,21 +87,12 @@ static void exynos_gpio_irq_mask(struct irq_data *irqd)
+       spin_lock_irqsave(&bank->slock, flags);
+       mask = readl(d->virt_base + reg_mask);
+-      mask |= 1 << irqd->hwirq;
++      mask &= ~(1 << irqd->hwirq);
+       writel(mask, d->virt_base + reg_mask);
+       spin_unlock_irqrestore(&bank->slock, flags);
+ }
+-static void exynos_gpio_irq_ack(struct irq_data *irqd)
+-{
+-      struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+-      struct samsung_pinctrl_drv_data *d = bank->drvdata;
+-      unsigned long reg_pend = d->ctrl->geint_pend + bank->eint_offset;
+-
+-      writel(1 << irqd->hwirq, d->virt_base + reg_pend);
+-}
+-
+ static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
+ {
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+@@ -268,7 +268,7 @@ err_domains:
+       return ret;
+ }
+-static void exynos_wkup_irq_unmask(struct irq_data *irqd)
++static void exynos_wkup_irq_mask(struct irq_data *irqd)
+ {
+       struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
+       struct samsung_pinctrl_drv_data *d = b->drvdata;
+@@ -279,13 +279,22 @@ static void exynos_wkup_irq_unmask(struct irq_data *irqd)
+       spin_lock_irqsave(&b->slock, flags);
+       mask = readl(d->virt_base + reg_mask);
+-      mask &= ~(1 << irqd->hwirq);
++      mask |= 1 << irqd->hwirq;
+       writel(mask, d->virt_base + reg_mask);
+       spin_unlock_irqrestore(&b->slock, flags);
+ }
+-static void exynos_wkup_irq_mask(struct irq_data *irqd)
++static void exynos_wkup_irq_ack(struct irq_data *irqd)
++{
++      struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
++      struct samsung_pinctrl_drv_data *d = b->drvdata;
++      unsigned long pend = d->ctrl->weint_pend + b->eint_offset;
++
++      writel(1 << irqd->hwirq, d->virt_base + pend);
++}
++
++static void exynos_wkup_irq_unmask(struct irq_data *irqd)
+ {
+       struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
+       struct samsung_pinctrl_drv_data *d = b->drvdata;
+@@ -296,21 +305,12 @@ static void exynos_wkup_irq_mask(struct irq_data *irqd)
+       spin_lock_irqsave(&b->slock, flags);
+       mask = readl(d->virt_base + reg_mask);
+-      mask |= 1 << irqd->hwirq;
++      mask &= ~(1 << irqd->hwirq);
+       writel(mask, d->virt_base + reg_mask);
+       spin_unlock_irqrestore(&b->slock, flags);
+ }
+-static void exynos_wkup_irq_ack(struct irq_data *irqd)
+-{
+-      struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
+-      struct samsung_pinctrl_drv_data *d = b->drvdata;
+-      unsigned long pend = d->ctrl->weint_pend + b->eint_offset;
+-
+-      writel(1 << irqd->hwirq, d->virt_base + pend);
+-}
+-
+ static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type)
+ {
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1041-pinctrl-exynos-ack-level-triggered-interrupts-before.patch b/patches.tizen/1041-pinctrl-exynos-ack-level-triggered-interrupts-before.patch
new file mode 100644 (file)
index 0000000..c566cc1
--- /dev/null
@@ -0,0 +1,64 @@
+From 62eaa36425b1612931820a29b3fa2525602aded2 Mon Sep 17 00:00:00 2001
+From: Doug Anderson <dianders@chromium.org>
+Date: Mon, 17 Jun 2013 09:50:43 -0700
+Subject: [PATCH 1041/1302] pinctrl: exynos: ack level-triggered interrupts
+ before unmasking
+
+A level-triggered interrupt should be acked after the interrupt line
+becomes inactive and before it is unmasked, or else another interrupt
+will be immediately triggered.  Acking before or after calling the
+handler is not enough.
+
+Change-Id: I553444ce552df5722e606d71bea8bf7b862cce25
+Signed-off-by: Luigi Semenzato <semenzato@chromium.org>
+Signed-off-by: Doug Anderson <dianders@chromium.org>
+Acked-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/pinctrl/pinctrl-exynos.c | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
+index c0729a3..ef75321 100644
+--- a/drivers/pinctrl/pinctrl-exynos.c
++++ b/drivers/pinctrl/pinctrl-exynos.c
+@@ -84,6 +84,17 @@ static void exynos_gpio_irq_unmask(struct irq_data *irqd)
+       unsigned long mask;
+       unsigned long flags;
++      /*
++       * Ack level interrupts right before unmask
++       *
++       * If we don't do this we'll get a double-interrupt.  Level triggered
++       * interrupts must not fire an interrupt if the level is not
++       * _currently_ active, even if it was active while the interrupt was
++       * masked.
++       */
++      if (irqd_get_trigger_type(irqd) & IRQ_TYPE_LEVEL_MASK)
++              exynos_gpio_irq_ack(irqd);
++
+       spin_lock_irqsave(&bank->slock, flags);
+       mask = readl(d->virt_base + reg_mask);
+@@ -302,6 +313,17 @@ static void exynos_wkup_irq_unmask(struct irq_data *irqd)
+       unsigned long mask;
+       unsigned long flags;
++      /*
++       * Ack level interrupts right before unmask
++       *
++       * If we don't do this we'll get a double-interrupt.  Level triggered
++       * interrupts must not fire an interrupt if the level is not
++       * _currently_ active, even if it was active while the interrupt was
++       * masked.
++       */
++      if (irqd_get_trigger_type(irqd) & IRQ_TYPE_LEVEL_MASK)
++              exynos_wkup_irq_ack(irqd);
++
+       spin_lock_irqsave(&b->slock, flags);
+       mask = readl(d->virt_base + reg_mask);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1042-clk-samsung-exynos4-Propagate-rate-change-of-SPI-div.patch b/patches.tizen/1042-clk-samsung-exynos4-Propagate-rate-change-of-SPI-div.patch
new file mode 100644 (file)
index 0000000..fe76412
--- /dev/null
@@ -0,0 +1,42 @@
+From ffd9522281988a6c1fe84960de3cc6092b8693d4 Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Wed, 4 Dec 2013 14:09:46 +0100
+Subject: [PATCH 1042/1302] clk: samsung: exynos4: Propagate rate change of SPI
+ dividers
+
+This patch adds missing CLK_SET_RATE_PARENT flag to div_spi{0,1,2} clocks
+to allow rate change propagation to div_spi{0,1,2}_pre. This fixes the
+problem with SPI bus clock rate setting.
+
+Change-Id: I26ef7028297914d5c99e55f0e9fa6dc6a9292e94
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/samsung/clk-exynos4.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
+index ee932d4..a9be318 100644
+--- a/drivers/clk/samsung/clk-exynos4.c
++++ b/drivers/clk/samsung/clk-exynos4.c
+@@ -534,11 +534,14 @@ struct samsung_div_clock exynos4_div_clks[] __initdata = {
+       DIV(none, "div_uart3", "mout_uart3", DIV_PERIL0, 12, 4),
+       DIV(none, "div_uart4", "mout_uart4", DIV_PERIL0, 16, 4),
+       DIV(none, "div_spi0", "mout_spi0", DIV_PERIL1, 0, 4),
+-      DIV(none, "div_spi_pre0", "div_spi0", DIV_PERIL1, 8, 8),
++      DIV_F(none, "div_spi_pre0", "div_spi0", DIV_PERIL1, 8, 8,
++                      CLK_SET_RATE_PARENT, 0),
+       DIV(none, "div_spi1", "mout_spi1", DIV_PERIL1, 16, 4),
+-      DIV(none, "div_spi_pre1", "div_spi1", DIV_PERIL1, 24, 8),
++      DIV_F(none, "div_spi_pre1", "div_spi1", DIV_PERIL1, 24, 8,
++                      CLK_SET_RATE_PARENT, 0),
+       DIV(none, "div_spi2", "mout_spi2", DIV_PERIL2, 0, 4),
+-      DIV(none, "div_spi_pre2", "div_spi2", DIV_PERIL2, 8, 8),
++      DIV_F(none, "div_spi_pre2", "div_spi2", DIV_PERIL2, 8, 8,
++                      CLK_SET_RATE_PARENT, 0),
+       DIV(none, "div_audio1", "mout_audio1", DIV_PERIL4, 0, 4),
+       DIV(none, "div_audio2", "mout_audio2", DIV_PERIL4, 16, 4),
+       DIV_A(arm_clk, "arm_clk", "div_core2", DIV_CPU0, 28, 3, "arm_clk"),
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1043-Smack-Local-IPv6-port-based-controls.patch b/patches.tizen/1043-Smack-Local-IPv6-port-based-controls.patch
new file mode 100644 (file)
index 0000000..e6f405d
--- /dev/null
@@ -0,0 +1,515 @@
+From 437baf9e5b2eef3278bf7e8d3ea1dcf3c647c908 Mon Sep 17 00:00:00 2001
+From: Casey Schaufler <casey@schaufler-ca.com>
+Date: Wed, 22 May 2013 18:42:56 -0700
+Subject: [PATCH 1043/1302] Smack: Local IPv6 port based controls
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Smack does not provide access controls on IPv6 communications.
+This patch introduces a mechanism for maintaining Smack lables
+for local IPv6 communications. It is based on labeling local ports.
+The behavior should be compatible with any future "real" IPv6
+support as it provides no interfaces for users to manipulate
+the labeling. Remote IPv6 connections use the ambient label
+the same way that unlabeled IPv4 packets are treated.
+
+Targeted for git://git.gitorious.org/smack-next/kernel.git
+
+Change-Id: I6c00966cc88b36611214cc438c47ecdab63077c7
+Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
+Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ security/smack/smack.h     |  11 ++
+ security/smack/smack_lsm.c | 348 +++++++++++++++++++++++++++++++++++++++------
+ 2 files changed, 319 insertions(+), 40 deletions(-)
+
+diff --git a/security/smack/smack.h b/security/smack/smack.h
+index 8ad3095..bb28e09 100644
+--- a/security/smack/smack.h
++++ b/security/smack/smack.h
+@@ -94,6 +94,17 @@ struct smk_netlbladdr {
+ };
+ /*
++ * An entry in the table identifying ports.
++ */
++struct smk_port_label {
++      struct list_head        list;
++      struct sock             *smk_sock;      /* socket initialized on */
++      unsigned short          smk_port;       /* the port number */
++      char                    *smk_in;        /* incoming label */
++      char                    *smk_out;       /* outgoing label */
++};
++
++/*
+  * This is the repository for labels seen so that it is
+  * not necessary to keep allocating tiny chuncks of memory
+  * and so that they can be shared.
+diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
+index d52c780..609e89d 100644
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -27,10 +27,13 @@
+ #include <linux/ip.h>
+ #include <linux/tcp.h>
+ #include <linux/udp.h>
++#include <linux/dccp.h>
+ #include <linux/slab.h>
+ #include <linux/mutex.h>
+ #include <linux/pipe_fs_i.h>
+ #include <net/cipso_ipv4.h>
++#include <net/ip.h>
++#include <net/ipv6.h>
+ #include <linux/audit.h>
+ #include <linux/magic.h>
+ #include <linux/dcache.h>
+@@ -45,6 +48,12 @@
+ #define TRANS_TRUE    "TRUE"
+ #define TRANS_TRUE_SIZE       4
++#define SMK_CONNECTING        0
++#define SMK_RECEIVING 1
++#define SMK_SENDING   2
++
++LIST_HEAD(smk_ipv6_port_list);
++
+ /**
+  * smk_fetch - Fetch the smack label from a file.
+  * @ip: a pointer to the inode
+@@ -1878,6 +1887,155 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
+ }
+ /**
++ * smk_ipv6_port_label - Smack port access table management
++ * @sock: socket
++ * @address: address
++ *
++ * Create or update the port list entry
++ */
++static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address)
++{
++      struct sock *sk = sock->sk;
++      struct sockaddr_in6 *addr6;
++      struct socket_smack *ssp = sock->sk->sk_security;
++      struct smk_port_label *spp;
++      unsigned short port = 0;
++
++      if (address == NULL) {
++              /*
++               * This operation is changing the Smack information
++               * on the bound socket. Take the changes to the port
++               * as well.
++               */
++              list_for_each_entry(spp, &smk_ipv6_port_list, list) {
++                      if (sk != spp->smk_sock)
++                              continue;
++                      spp->smk_in = ssp->smk_in;
++                      spp->smk_out = ssp->smk_out;
++                      return;
++              }
++              /*
++               * A NULL address is only used for updating existing
++               * bound entries. If there isn't one, it's OK.
++               */
++              return;
++      }
++
++      addr6 = (struct sockaddr_in6 *)address;
++      port = ntohs(addr6->sin6_port);
++      /*
++       * This is a special case that is safely ignored.
++       */
++      if (port == 0)
++              return;
++
++      /*
++       * Look for an existing port list entry.
++       * This is an indication that a port is getting reused.
++       */
++      list_for_each_entry(spp, &smk_ipv6_port_list, list) {
++              if (spp->smk_port != port)
++                      continue;
++              spp->smk_port = port;
++              spp->smk_sock = sk;
++              spp->smk_in = ssp->smk_in;
++              spp->smk_out = ssp->smk_out;
++              return;
++      }
++
++      /*
++       * A new port entry is required.
++       */
++      spp = kzalloc(sizeof(*spp), GFP_KERNEL);
++      if (spp == NULL)
++              return;
++
++      spp->smk_port = port;
++      spp->smk_sock = sk;
++      spp->smk_in = ssp->smk_in;
++      spp->smk_out = ssp->smk_out;
++
++      list_add(&spp->list, &smk_ipv6_port_list);
++      return;
++}
++
++/**
++ * smk_ipv6_port_check - check Smack port access
++ * @sock: socket
++ * @address: address
++ *
++ * Create or update the port list entry
++ */
++static int smk_ipv6_port_check(struct sock *sk, struct sockaddr *address,
++                              int act)
++{
++      __be16 *bep;
++      __be32 *be32p;
++      struct sockaddr_in6 *addr6;
++      struct smk_port_label *spp;
++      struct socket_smack *ssp = sk->sk_security;
++      unsigned short port = 0;
++      char *subject;
++      char *object;
++      struct smk_audit_info ad;
++#ifdef CONFIG_AUDIT
++      struct lsm_network_audit net;
++#endif
++
++      if (act == SMK_RECEIVING) {
++              subject = smack_net_ambient;
++              object = ssp->smk_in;
++      } else {
++              subject = ssp->smk_out;
++              object = smack_net_ambient;
++      }
++
++      /*
++       * Get the IP address and port from the address.
++       */
++      addr6 = (struct sockaddr_in6 *)address;
++      port = ntohs(addr6->sin6_port);
++      bep = (__be16 *)(&addr6->sin6_addr);
++      be32p = (__be32 *)(&addr6->sin6_addr);
++
++      /*
++       * It's remote, so port lookup does no good.
++       */
++      if (be32p[0] || be32p[1] || be32p[2] || bep[6] || ntohs(bep[7]) != 1)
++              goto auditout;
++
++      /*
++       * It's local so the send check has to have passed.
++       */
++      if (act == SMK_RECEIVING) {
++              subject = smack_known_web.smk_known;
++              goto auditout;
++      }
++
++      list_for_each_entry(spp, &smk_ipv6_port_list, list) {
++              if (spp->smk_port != port)
++                      continue;
++              object = spp->smk_in;
++              if (act == SMK_CONNECTING)
++                      ssp->smk_packet = spp->smk_out;
++              break;
++      }
++
++auditout:
++
++#ifdef CONFIG_AUDIT
++      smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
++      ad.a.u.net->family = sk->sk_family;
++      ad.a.u.net->dport = port;
++      if (act == SMK_RECEIVING)
++              ad.a.u.net->v6info.saddr = addr6->sin6_addr;
++      else
++              ad.a.u.net->v6info.daddr = addr6->sin6_addr;
++#endif
++      return smk_access(subject, object, MAY_WRITE, &ad);
++}
++
++/**
+  * smack_inode_setsecurity - set smack xattrs
+  * @inode: the object
+  * @name: attribute name
+@@ -1926,7 +2084,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
+               ssp->smk_in = sp;
+       else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) {
+               ssp->smk_out = sp;
+-              if (sock->sk->sk_family != PF_UNIX) {
++              if (sock->sk->sk_family == PF_INET) {
+                       rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
+                       if (rc != 0)
+                               printk(KERN_WARNING
+@@ -1936,6 +2094,9 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
+       } else
+               return -EOPNOTSUPP;
++      if (sock->sk->sk_family == PF_INET6)
++              smk_ipv6_port_label(sock, NULL);
++
+       return 0;
+ }
+@@ -1963,6 +2124,25 @@ static int smack_socket_post_create(struct socket *sock, int family,
+ }
+ /**
++ * smack_socket_bind - record port binding information.
++ * @sock: the socket
++ * @address: the port address
++ * @addrlen: size of the address
++ *
++ * Records the label bound to a port.
++ *
++ * Returns 0
++ */
++static int smack_socket_bind(struct socket *sock, struct sockaddr *address,
++                              int addrlen)
++{
++      if (sock->sk != NULL && sock->sk->sk_family == PF_INET6)
++              smk_ipv6_port_label(sock, address);
++
++      return 0;
++}
++
++/**
+  * smack_socket_connect - connect access check
+  * @sock: the socket
+  * @sap: the other end
+@@ -1975,12 +2155,24 @@ static int smack_socket_post_create(struct socket *sock, int family,
+ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
+                               int addrlen)
+ {
+-      if (sock->sk == NULL || sock->sk->sk_family != PF_INET)
++      int rc = 0;
++
++      if (sock->sk == NULL)
+               return 0;
+-      if (addrlen < sizeof(struct sockaddr_in))
+-              return -EINVAL;
+-      return smack_netlabel_send(sock->sk, (struct sockaddr_in *)sap);
++      switch (sock->sk->sk_family) {
++      case PF_INET:
++              if (addrlen < sizeof(struct sockaddr_in))
++                      return -EINVAL;
++              rc = smack_netlabel_send(sock->sk, (struct sockaddr_in *)sap);
++              break;
++      case PF_INET6:
++              if (addrlen < sizeof(struct sockaddr_in6))
++                      return -EINVAL;
++              rc = smk_ipv6_port_check(sock->sk, sap, SMK_CONNECTING);
++              break;
++      }
++      return rc;
+ }
+ /**
+@@ -2792,22 +2984,32 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
+  * @msg: the message
+  * @size: the size of the message
+  *
+- * Return 0 if the current subject can write to the destination
+- * host. This is only a question if the destination is a single
+- * label host.
++ * Return 0 if the current subject can write to the destination host.
++ * For IPv4 this is only a question if the destination is a single label host.
++ * For IPv6 this is a check against the label of the port.
+  */
+ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
+                               int size)
+ {
+       struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name;
++      struct sockaddr *sap = (struct sockaddr *) msg->msg_name;
++      int rc = 0;
+       /*
+        * Perfectly reasonable for this to be NULL
+        */
+-      if (sip == NULL || sip->sin_family != AF_INET)
++      if (sip == NULL)
+               return 0;
+-      return smack_netlabel_send(sock->sk, sip);
++      switch (sip->sin_family) {
++      case AF_INET:
++              rc = smack_netlabel_send(sock->sk, sip);
++              break;
++      case AF_INET6:
++              rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING);
++              break;
++      }
++      return rc;
+ }
+ /**
+@@ -2878,6 +3080,54 @@ static char *smack_from_secattr(struct netlbl_lsm_secattr *sap,
+       return smack_net_ambient;
+ }
++static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr *sap)
++{
++      struct sockaddr_in6 *sip = (struct sockaddr_in6 *)sap;
++      u8 nexthdr;
++      int offset;
++      int proto = -EINVAL;
++      struct ipv6hdr _ipv6h;
++      struct ipv6hdr *ip6;
++      __be16 frag_off;
++      struct tcphdr _tcph, *th;
++      struct udphdr _udph, *uh;
++      struct dccp_hdr _dccph, *dh;
++
++      sip->sin6_port = 0;
++
++      offset = skb_network_offset(skb);
++      ip6 = skb_header_pointer(skb, offset, sizeof(_ipv6h), &_ipv6h);
++      if (ip6 == NULL)
++              return -EINVAL;
++      sip->sin6_addr = ip6->saddr;
++
++      nexthdr = ip6->nexthdr;
++      offset += sizeof(_ipv6h);
++      offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off);
++      if (offset < 0)
++              return -EINVAL;
++
++      proto = nexthdr;
++      switch (proto) {
++      case IPPROTO_TCP:
++              th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
++              if (th != NULL)
++                      sip->sin6_port = th->source;
++              break;
++      case IPPROTO_UDP:
++              uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
++              if (uh != NULL)
++                      sip->sin6_port = uh->source;
++              break;
++      case IPPROTO_DCCP:
++              dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
++              if (dh != NULL)
++                      sip->sin6_port = dh->dccph_sport;
++              break;
++      }
++      return proto;
++}
++
+ /**
+  * smack_socket_sock_rcv_skb - Smack packet delivery access check
+  * @sk: socket
+@@ -2889,43 +3139,52 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
+ {
+       struct netlbl_lsm_secattr secattr;
+       struct socket_smack *ssp = sk->sk_security;
++      struct sockaddr sadd;
+       char *csp;
+-      int rc;
++      int rc = 0;
+       struct smk_audit_info ad;
+ #ifdef CONFIG_AUDIT
+       struct lsm_network_audit net;
+ #endif
+-      if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)
+-              return 0;
+-
+-      /*
+-       * Translate what netlabel gave us.
+-       */
+-      netlbl_secattr_init(&secattr);
++      switch (sk->sk_family) {
++      case PF_INET:
++              /*
++               * Translate what netlabel gave us.
++               */
++              netlbl_secattr_init(&secattr);
+-      rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr);
+-      if (rc == 0)
+-              csp = smack_from_secattr(&secattr, ssp);
+-      else
+-              csp = smack_net_ambient;
++              rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr);
++              if (rc == 0)
++                      csp = smack_from_secattr(&secattr, ssp);
++              else
++                      csp = smack_net_ambient;
+-      netlbl_secattr_destroy(&secattr);
++              netlbl_secattr_destroy(&secattr);
+ #ifdef CONFIG_AUDIT
+-      smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
+-      ad.a.u.net->family = sk->sk_family;
+-      ad.a.u.net->netif = skb->skb_iif;
+-      ipv4_skb_to_auditdata(skb, &ad.a, NULL);
++              smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
++              ad.a.u.net->family = sk->sk_family;
++              ad.a.u.net->netif = skb->skb_iif;
++              ipv4_skb_to_auditdata(skb, &ad.a, NULL);
+ #endif
+-      /*
+-       * Receiving a packet requires that the other end
+-       * be able to write here. Read access is not required.
+-       * This is the simplist possible security model
+-       * for networking.
+-       */
+-      rc = smk_access(csp, ssp->smk_in, MAY_WRITE, &ad);
+-      if (rc != 0)
+-              netlbl_skbuff_err(skb, rc, 0);
++              /*
++               * Receiving a packet requires that the other end
++               * be able to write here. Read access is not required.
++               * This is the simplist possible security model
++               * for networking.
++               */
++              rc = smk_access(csp, ssp->smk_in, MAY_WRITE, &ad);
++              if (rc != 0)
++                      netlbl_skbuff_err(skb, rc, 0);
++              break;
++      case PF_INET6:
++              rc = smk_skb_to_addr_ipv6(skb, &sadd);
++              if (rc == IPPROTO_UDP || rc == IPPROTO_TCP)
++                      rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING);
++              else
++                      rc = 0;
++              break;
++      }
+       return rc;
+ }
+@@ -3063,9 +3322,17 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
+       struct lsm_network_audit net;
+ #endif
+-      /* handle mapped IPv4 packets arriving via IPv6 sockets */
+-      if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
+-              family = PF_INET;
++      if (family == PF_INET6) {
++              /*
++               * Handle mapped IPv4 packets arriving
++               * via IPv6 sockets. Don't set up netlabel
++               * processing on IPv6.
++               */
++              if (skb->protocol == htons(ETH_P_IP))
++                      family = PF_INET;
++              else
++                      return 0;
++      }
+       netlbl_secattr_init(&secattr);
+       rc = netlbl_skbuff_getattr(skb, family, &secattr);
+@@ -3498,6 +3765,7 @@ struct security_operations smack_ops = {
+       .unix_may_send =                smack_unix_may_send,
+       .socket_post_create =           smack_socket_post_create,
++      .socket_bind =                  smack_socket_bind,
+       .socket_connect =               smack_socket_connect,
+       .socket_sendmsg =               smack_socket_sendmsg,
+       .socket_sock_rcv_skb =          smack_socket_sock_rcv_skb,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1044-Smack-Improve-access-check-performance.patch b/patches.tizen/1044-Smack-Improve-access-check-performance.patch
new file mode 100644 (file)
index 0000000..75234bf
--- /dev/null
@@ -0,0 +1,1589 @@
+From 792563c93e7d1af2065781757cb14279c6847473 Mon Sep 17 00:00:00 2001
+From: Casey Schaufler <casey@schaufler-ca.com>
+Date: Wed, 22 May 2013 18:43:03 -0700
+Subject: [PATCH 1044/1302] Smack: Improve access check performance
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Each Smack label that the kernel has seen is added to a
+list of labels. The list of access rules for a given subject
+label hangs off of the label list entry for the label.
+This patch changes the structures that contain subject
+labels to point at the label list entry rather that the
+label itself. Doing so removes a label list lookup in
+smk_access() that was accounting for the largest single
+chunk of Smack overhead.
+
+Targeted for git://git.gitorious.org/smack-next/kernel.git
+
+Change-Id: I15f3cde6f0c3db9af056d35fc224d6295dff130c
+Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
+Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ security/smack/smack.h        | 108 +++++++-------
+ security/smack/smack_access.c |  41 +++---
+ security/smack/smack_lsm.c    | 331 +++++++++++++++++++++++-------------------
+ security/smack/smackfs.c      |  51 +++----
+ 4 files changed, 282 insertions(+), 249 deletions(-)
+
+diff --git a/security/smack/smack.h b/security/smack/smack.h
+index bb28e09..159f25b 100644
+--- a/security/smack/smack.h
++++ b/security/smack/smack.h
+@@ -29,6 +29,38 @@
+ #define SMK_LONGLABEL 256
+ /*
++ * This is the repository for labels seen so that it is
++ * not necessary to keep allocating tiny chuncks of memory
++ * and so that they can be shared.
++ *
++ * Labels are never modified in place. Anytime a label
++ * is imported (e.g. xattrset on a file) the list is checked
++ * for it and it is added if it doesn't exist. The address
++ * is passed out in either case. Entries are added, but
++ * never deleted.
++ *
++ * Since labels are hanging around anyway it doesn't
++ * hurt to maintain a secid for those awkward situations
++ * where kernel components that ought to use LSM independent
++ * interfaces don't. The secid should go away when all of
++ * these components have been repaired.
++ *
++ * The cipso value associated with the label gets stored here, too.
++ *
++ * Keep the access rules for this subject label here so that
++ * the entire set of rules does not need to be examined every
++ * time.
++ */
++struct smack_known {
++      struct list_head                list;
++      char                            *smk_known;
++      u32                             smk_secid;
++      struct netlbl_lsm_secattr       smk_netlabel;   /* on wire labels */
++      struct list_head                smk_rules;      /* access rules */
++      struct mutex                    smk_rules_lock; /* lock for rules */
++};
++
++/*
+  * Maximum number of bytes for the levels in a CIPSO IP option.
+  * Why 23? CIPSO is constrained to 30, so a 32 byte buffer is
+  * bigger than can be used, and 24 is the next lower multiple
+@@ -46,25 +78,25 @@ struct superblock_smack {
+ };
+ struct socket_smack {
+-      char            *smk_out;       /* outbound label */
+-      char            *smk_in;        /* inbound label */
+-      char            *smk_packet;    /* TCP peer label */
++      struct smack_known      *smk_out;       /* outbound label */
++      char                    *smk_in;        /* inbound label */
++      char                    *smk_packet;    /* TCP peer label */
+ };
+ /*
+  * Inode smack data
+  */
+ struct inode_smack {
+-      char            *smk_inode;     /* label of the fso */
+-      char            *smk_task;      /* label of the task */
+-      char            *smk_mmap;      /* label of the mmap domain */
+-      struct mutex    smk_lock;       /* initialization lock */
+-      int             smk_flags;      /* smack inode flags */
++      char                    *smk_inode;     /* label of the fso */
++      struct smack_known      *smk_task;      /* label of the task */
++      struct smack_known      *smk_mmap;      /* label of the mmap domain */
++      struct mutex            smk_lock;       /* initialization lock */
++      int                     smk_flags;      /* smack inode flags */
+ };
+ struct task_smack {
+-      char                    *smk_task;      /* label for access control */
+-      char                    *smk_forked;    /* label when forked */
++      struct smack_known      *smk_task;      /* label for access control */
++      struct smack_known      *smk_forked;    /* label when forked */
+       struct list_head        smk_rules;      /* per task access rules */
+       struct mutex            smk_rules_lock; /* lock for the rules */
+ };
+@@ -78,7 +110,7 @@ struct task_smack {
+  */
+ struct smack_rule {
+       struct list_head        list;
+-      char                    *smk_subject;
++      struct smack_known      *smk_subject;
+       char                    *smk_object;
+       int                     smk_access;
+ };
+@@ -101,39 +133,7 @@ struct smk_port_label {
+       struct sock             *smk_sock;      /* socket initialized on */
+       unsigned short          smk_port;       /* the port number */
+       char                    *smk_in;        /* incoming label */
+-      char                    *smk_out;       /* outgoing label */
+-};
+-
+-/*
+- * This is the repository for labels seen so that it is
+- * not necessary to keep allocating tiny chuncks of memory
+- * and so that they can be shared.
+- *
+- * Labels are never modified in place. Anytime a label
+- * is imported (e.g. xattrset on a file) the list is checked
+- * for it and it is added if it doesn't exist. The address
+- * is passed out in either case. Entries are added, but
+- * never deleted.
+- *
+- * Since labels are hanging around anyway it doesn't
+- * hurt to maintain a secid for those awkward situations
+- * where kernel components that ought to use LSM independent
+- * interfaces don't. The secid should go away when all of
+- * these components have been repaired.
+- *
+- * The cipso value associated with the label gets stored here, too.
+- *
+- * Keep the access rules for this subject label here so that
+- * the entire set of rules does not need to be examined every
+- * time.
+- */
+-struct smack_known {
+-      struct list_head                list;
+-      char                            *smk_known;
+-      u32                             smk_secid;
+-      struct netlbl_lsm_secattr       smk_netlabel;   /* on wire labels */
+-      struct list_head                smk_rules;      /* access rules */
+-      struct mutex                    smk_rules_lock; /* lock for rules */
++      struct smack_known      *smk_out;       /* outgoing label */
+ };
+ /*
+@@ -214,9 +214,9 @@ struct inode_smack *new_inode_smack(char *);
+  * These functions are in smack_access.c
+  */
+ int smk_access_entry(char *, char *, struct list_head *);
+-int smk_access(char *, char *, int, struct smk_audit_info *);
++int smk_access(struct smack_known *, char *, int, struct smk_audit_info *);
+ int smk_curacc(char *, u32, struct smk_audit_info *);
+-char *smack_from_secid(const u32);
++struct smack_known *smack_from_secid(const u32);
+ char *smk_parse_smack(const char *string, int len);
+ int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int);
+ char *smk_import(const char *, int);
+@@ -229,7 +229,7 @@ u32 smack_to_secid(const char *);
+  */
+ extern int smack_cipso_direct;
+ extern int smack_cipso_mapped;
+-extern char *smack_net_ambient;
++extern struct smack_known *smack_net_ambient;
+ extern char *smack_onlycap;
+ extern const char *smack_cipso_option;
+@@ -265,17 +265,17 @@ static inline char *smk_of_inode(const struct inode *isp)
+ }
+ /*
+- * Present a pointer to the smack label in an task blob.
++ * Present a pointer to the smack label entry in an task blob.
+  */
+-static inline char *smk_of_task(const struct task_smack *tsp)
++static inline struct smack_known *smk_of_task(const struct task_smack *tsp)
+ {
+       return tsp->smk_task;
+ }
+ /*
+- * Present a pointer to the forked smack label in an task blob.
++ * Present a pointer to the forked smack label entry in an task blob.
+  */
+-static inline char *smk_of_forked(const struct task_smack *tsp)
++static inline struct smack_known *smk_of_forked(const struct task_smack *tsp)
+ {
+       return tsp->smk_forked;
+ }
+@@ -283,7 +283,7 @@ static inline char *smk_of_forked(const struct task_smack *tsp)
+ /*
+  * Present a pointer to the smack label in the current task blob.
+  */
+-static inline char *smk_of_current(void)
++static inline struct smack_known *smk_of_current(void)
+ {
+       return smk_of_task(current_security());
+ }
+@@ -294,9 +294,11 @@ static inline char *smk_of_current(void)
+  */
+ static inline int smack_privileged(int cap)
+ {
++      struct smack_known *skp = smk_of_current();
++
+       if (!capable(cap))
+               return 0;
+-      if (smack_onlycap == NULL || smack_onlycap == smk_of_current())
++      if (smack_onlycap == NULL || smack_onlycap == skp->smk_known)
+               return 1;
+       return 0;
+ }
+diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
+index 2e397a8..53f2327 100644
+--- a/security/smack/smack_access.c
++++ b/security/smack/smack_access.c
+@@ -93,7 +93,7 @@ int smk_access_entry(char *subject_label, char *object_label,
+       list_for_each_entry_rcu(srp, rule_list, list) {
+               if (srp->smk_object == object_label &&
+-                  srp->smk_subject == subject_label) {
++                  srp->smk_subject->smk_known == subject_label) {
+                       may = srp->smk_access;
+                       break;
+               }
+@@ -104,7 +104,7 @@ int smk_access_entry(char *subject_label, char *object_label,
+ /**
+  * smk_access - determine if a subject has a specific access to an object
+- * @subject_label: a pointer to the subject's Smack label
++ * @subject_known: a pointer to the subject's Smack label entry
+  * @object_label: a pointer to the object's Smack label
+  * @request: the access requested, in "MAY" format
+  * @a : a pointer to the audit data
+@@ -115,10 +115,9 @@ int smk_access_entry(char *subject_label, char *object_label,
+  *
+  * Smack labels are shared on smack_list
+  */
+-int smk_access(char *subject_label, char *object_label, int request,
+-             struct smk_audit_info *a)
++int smk_access(struct smack_known *subject_known, char *object_label,
++              int request, struct smk_audit_info *a)
+ {
+-      struct smack_known *skp;
+       int may = MAY_NOT;
+       int rc = 0;
+@@ -127,7 +126,7 @@ int smk_access(char *subject_label, char *object_label, int request,
+        *
+        * A star subject can't access any object.
+        */
+-      if (subject_label == smack_known_star.smk_known) {
++      if (subject_known == &smack_known_star) {
+               rc = -EACCES;
+               goto out_audit;
+       }
+@@ -137,7 +136,7 @@ int smk_access(char *subject_label, char *object_label, int request,
+        * An internet subject can access any object.
+        */
+       if (object_label == smack_known_web.smk_known ||
+-          subject_label == smack_known_web.smk_known)
++          subject_known == &smack_known_web)
+               goto out_audit;
+       /*
+        * A star object can be accessed by any subject.
+@@ -148,7 +147,7 @@ int smk_access(char *subject_label, char *object_label, int request,
+        * An object can be accessed in any way by a subject
+        * with the same label.
+        */
+-      if (subject_label == object_label)
++      if (subject_known->smk_known == object_label)
+               goto out_audit;
+       /*
+        * A hat subject can read any object.
+@@ -157,7 +156,7 @@ int smk_access(char *subject_label, char *object_label, int request,
+       if ((request & MAY_ANYREAD) == request) {
+               if (object_label == smack_known_floor.smk_known)
+                       goto out_audit;
+-              if (subject_label == smack_known_hat.smk_known)
++              if (subject_known == &smack_known_hat)
+                       goto out_audit;
+       }
+       /*
+@@ -167,9 +166,9 @@ int smk_access(char *subject_label, char *object_label, int request,
+        * good. A negative response from smk_access_entry()
+        * indicates there is no entry for this pair.
+        */
+-      skp = smk_find_entry(subject_label);
+       rcu_read_lock();
+-      may = smk_access_entry(subject_label, object_label, &skp->smk_rules);
++      may = smk_access_entry(subject_known->smk_known, object_label,
++                              &subject_known->smk_rules);
+       rcu_read_unlock();
+       if (may > 0 && (request & may) == request)
+@@ -179,7 +178,8 @@ int smk_access(char *subject_label, char *object_label, int request,
+ out_audit:
+ #ifdef CONFIG_AUDIT
+       if (a)
+-              smack_log(subject_label, object_label, request, rc, a);
++              smack_log(subject_known->smk_known, object_label, request,
++                              rc, a);
+ #endif
+       return rc;
+ }
+@@ -198,20 +198,21 @@ out_audit:
+ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
+ {
+       struct task_smack *tsp = current_security();
+-      char *sp = smk_of_task(tsp);
++      struct smack_known *skp = smk_of_task(tsp);
+       int may;
+       int rc;
+       /*
+        * Check the global rule list
+        */
+-      rc = smk_access(sp, obj_label, mode, NULL);
++      rc = smk_access(skp, obj_label, mode, NULL);
+       if (rc == 0) {
+               /*
+                * If there is an entry in the task's rule list
+                * it can further restrict access.
+                */
+-              may = smk_access_entry(sp, obj_label, &tsp->smk_rules);
++              may = smk_access_entry(skp->smk_known, obj_label,
++                                      &tsp->smk_rules);
+               if (may < 0)
+                       goto out_audit;
+               if ((mode & may) == mode)
+@@ -228,7 +229,7 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
+ out_audit:
+ #ifdef CONFIG_AUDIT
+       if (a)
+-              smack_log(sp, obj_label, mode, rc, a);
++              smack_log(skp->smk_known, obj_label, mode, rc, a);
+ #endif
+       return rc;
+ }
+@@ -513,10 +514,10 @@ char *smk_import(const char *string, int len)
+  * smack_from_secid - find the Smack label associated with a secid
+  * @secid: an integer that might be associated with a Smack label
+  *
+- * Returns a pointer to the appropriate Smack label if there is one,
++ * Returns a pointer to the appropriate Smack label entry if there is one,
+  * otherwise a pointer to the invalid Smack label.
+  */
+-char *smack_from_secid(const u32 secid)
++struct smack_known *smack_from_secid(const u32 secid)
+ {
+       struct smack_known *skp;
+@@ -524,7 +525,7 @@ char *smack_from_secid(const u32 secid)
+       list_for_each_entry_rcu(skp, &smack_known_list, list) {
+               if (skp->smk_secid == secid) {
+                       rcu_read_unlock();
+-                      return skp->smk_known;
++                      return skp;
+               }
+       }
+@@ -533,7 +534,7 @@ char *smack_from_secid(const u32 secid)
+        * of a secid that is not on the list.
+        */
+       rcu_read_unlock();
+-      return smack_known_invalid.smk_known;
++      return &smack_known_invalid;
+ }
+ /**
+diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
+index 609e89d..3669d9f 100644
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -62,11 +62,12 @@ LIST_HEAD(smk_ipv6_port_list);
+  * Returns a pointer to the master list entry for the Smack label
+  * or NULL if there was no label to fetch.
+  */
+-static char *smk_fetch(const char *name, struct inode *ip, struct dentry *dp)
++static struct smack_known *smk_fetch(const char *name, struct inode *ip,
++                                      struct dentry *dp)
+ {
+       int rc;
+       char *buffer;
+-      char *result = NULL;
++      struct smack_known *skp = NULL;
+       if (ip->i_op->getxattr == NULL)
+               return NULL;
+@@ -77,11 +78,11 @@ static char *smk_fetch(const char *name, struct inode *ip, struct dentry *dp)
+       rc = ip->i_op->getxattr(dp, name, buffer, SMK_LONGLABEL);
+       if (rc > 0)
+-              result = smk_import(buffer, rc);
++              skp = smk_import_entry(buffer, rc);
+       kfree(buffer);
+-      return result;
++      return skp;
+ }
+ /**
+@@ -111,7 +112,8 @@ struct inode_smack *new_inode_smack(char *smack)
+  *
+  * Returns the new blob or NULL if there's no memory available
+  */
+-static struct task_smack *new_task_smack(char *task, char *forked, gfp_t gfp)
++static struct task_smack *new_task_smack(struct smack_known *task,
++                                      struct smack_known *forked, gfp_t gfp)
+ {
+       struct task_smack *tsp;
+@@ -173,17 +175,17 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
+ {
+       int rc;
+       struct smk_audit_info ad;
+-      char *tsp;
++      struct smack_known *skp;
+       rc = cap_ptrace_access_check(ctp, mode);
+       if (rc != 0)
+               return rc;
+-      tsp = smk_of_task(task_security(ctp));
++      skp = smk_of_task(task_security(ctp));
+       smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
+       smk_ad_setfield_u_tsk(&ad, ctp);
+-      rc = smk_curacc(tsp, MAY_READWRITE, &ad);
++      rc = smk_curacc(skp->smk_known, MAY_READWRITE, &ad);
+       return rc;
+ }
+@@ -199,17 +201,17 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
+ {
+       int rc;
+       struct smk_audit_info ad;
+-      char *tsp;
++      struct smack_known *skp;
+       rc = cap_ptrace_traceme(ptp);
+       if (rc != 0)
+               return rc;
+-      tsp = smk_of_task(task_security(ptp));
++      skp = smk_of_task(task_security(ptp));
+       smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
+       smk_ad_setfield_u_tsk(&ad, ptp);
+-      rc = smk_curacc(tsp, MAY_READWRITE, &ad);
++      rc = smk_curacc(skp->smk_known, MAY_READWRITE, &ad);
+       return rc;
+ }
+@@ -224,12 +226,12 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
+ static int smack_syslog(int typefrom_file)
+ {
+       int rc = 0;
+-      char *sp = smk_of_current();
++      struct smack_known *skp = smk_of_current();
+       if (smack_privileged(CAP_MAC_OVERRIDE))
+               return 0;
+-       if (sp != smack_known_floor.smk_known)
++       if (skp != &smack_known_floor)
+               rc = -EACCES;
+       return rc;
+@@ -533,7 +535,9 @@ static int smack_bprm_secureexec(struct linux_binprm *bprm)
+  */
+ static int smack_inode_alloc_security(struct inode *inode)
+ {
+-      inode->i_security = new_inode_smack(smk_of_current());
++      struct smack_known *skp = smk_of_current();
++
++      inode->i_security = new_inode_smack(skp->smk_known);
+       if (inode->i_security == NULL)
+               return -ENOMEM;
+       return 0;
+@@ -566,9 +570,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
+                                    const struct qstr *qstr, char **name,
+                                    void **value, size_t *len)
+ {
+-      struct smack_known *skp;
+       struct inode_smack *issp = inode->i_security;
+-      char *csp = smk_of_current();
++      struct smack_known *skp = smk_of_current();
+       char *isp = smk_of_inode(inode);
+       char *dsp = smk_of_inode(dir);
+       int may;
+@@ -580,9 +583,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
+       }
+       if (value) {
+-              skp = smk_find_entry(csp);
+               rcu_read_lock();
+-              may = smk_access_entry(csp, dsp, &skp->smk_rules);
++              may = smk_access_entry(skp->smk_known, dsp, &skp->smk_rules);
+               rcu_read_unlock();
+               /*
+@@ -871,29 +873,31 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
+ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
+                                     const void *value, size_t size, int flags)
+ {
+-      char *nsp;
++      struct smack_known *skp;
+       struct inode_smack *isp = dentry->d_inode->i_security;
++      if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
++              isp->smk_flags |= SMK_INODE_TRANSMUTE;
++              return;
++      }
++
++      skp = smk_import_entry(value, size);
+       if (strcmp(name, XATTR_NAME_SMACK) == 0) {
+-              nsp = smk_import(value, size);
+-              if (nsp != NULL)
+-                      isp->smk_inode = nsp;
++              if (skp != NULL)
++                      isp->smk_inode = skp->smk_known;
+               else
+                       isp->smk_inode = smack_known_invalid.smk_known;
+       } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) {
+-              nsp = smk_import(value, size);
+-              if (nsp != NULL)
+-                      isp->smk_task = nsp;
++              if (skp != NULL)
++                      isp->smk_task = skp;
+               else
+-                      isp->smk_task = smack_known_invalid.smk_known;
++                      isp->smk_task = &smack_known_invalid;
+       } else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
+-              nsp = smk_import(value, size);
+-              if (nsp != NULL)
+-                      isp->smk_mmap = nsp;
++              if (skp != NULL)
++                      isp->smk_mmap = skp;
+               else
+-                      isp->smk_mmap = smack_known_invalid.smk_known;
+-      } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0)
+-              isp->smk_flags |= SMK_INODE_TRANSMUTE;
++                      isp->smk_mmap = &smack_known_invalid;
++      }
+       return;
+ }
+@@ -999,7 +1003,7 @@ static int smack_inode_getsecurity(const struct inode *inode,
+       if (strcmp(name, XATTR_SMACK_IPIN) == 0)
+               isp = ssp->smk_in;
+       else if (strcmp(name, XATTR_SMACK_IPOUT) == 0)
+-              isp = ssp->smk_out;
++              isp = ssp->smk_out->smk_known;
+       else
+               return -EOPNOTSUPP;
+@@ -1079,7 +1083,9 @@ static int smack_file_permission(struct file *file, int mask)
+  */
+ static int smack_file_alloc_security(struct file *file)
+ {
+-      file->f_security = smk_of_current();
++      struct smack_known *skp = smk_of_current();
++
++      file->f_security = skp->smk_known;
+       return 0;
+ }
+@@ -1190,10 +1196,9 @@ static int smack_mmap_file(struct file *file,
+                          unsigned long flags)
+ {
+       struct smack_known *skp;
++      struct smack_known *mkp;
+       struct smack_rule *srp;
+       struct task_smack *tsp;
+-      char *sp;
+-      char *msmack;
+       char *osmack;
+       struct inode_smack *isp;
+       int may;
+@@ -1207,11 +1212,10 @@ static int smack_mmap_file(struct file *file,
+       isp = file_inode(file)->i_security;
+       if (isp->smk_mmap == NULL)
+               return 0;
+-      msmack = isp->smk_mmap;
++      mkp = isp->smk_mmap;
+       tsp = current_security();
+-      sp = smk_of_current();
+-      skp = smk_find_entry(sp);
++      skp = smk_of_current();
+       rc = 0;
+       rcu_read_lock();
+@@ -1225,13 +1229,13 @@ static int smack_mmap_file(struct file *file,
+               /*
+                * Matching labels always allows access.
+                */
+-              if (msmack == osmack)
++              if (mkp->smk_known == osmack)
+                       continue;
+               /*
+                * If there is a matching local rule take
+                * that into account as well.
+                */
+-              may = smk_access_entry(srp->smk_subject, osmack,
++              may = smk_access_entry(srp->smk_subject->smk_known, osmack,
+                                       &tsp->smk_rules);
+               if (may == -ENOENT)
+                       may = srp->smk_access;
+@@ -1249,8 +1253,8 @@ static int smack_mmap_file(struct file *file,
+                * If there isn't one a SMACK64MMAP subject
+                * can't have as much access as current.
+                */
+-              skp = smk_find_entry(msmack);
+-              mmay = smk_access_entry(msmack, osmack, &skp->smk_rules);
++              mmay = smk_access_entry(mkp->smk_known, osmack,
++                                              &mkp->smk_rules);
+               if (mmay == -ENOENT) {
+                       rc = -EACCES;
+                       break;
+@@ -1259,7 +1263,8 @@ static int smack_mmap_file(struct file *file,
+                * If there is a local entry it modifies the
+                * potential access, too.
+                */
+-              tmay = smk_access_entry(msmack, osmack, &tsp->smk_rules);
++              tmay = smk_access_entry(mkp->smk_known, osmack,
++                                              &tsp->smk_rules);
+               if (tmay != -ENOENT)
+                       mmay &= tmay;
+@@ -1288,7 +1293,9 @@ static int smack_mmap_file(struct file *file,
+  */
+ static int smack_file_set_fowner(struct file *file)
+ {
+-      file->f_security = smk_of_current();
++      struct smack_known *skp = smk_of_current();
++
++      file->f_security = skp->smk_known;
+       return 0;
+ }
+@@ -1306,9 +1313,10 @@ static int smack_file_set_fowner(struct file *file)
+ static int smack_file_send_sigiotask(struct task_struct *tsk,
+                                    struct fown_struct *fown, int signum)
+ {
++      struct smack_known *skp;
++      struct smack_known *tkp = smk_of_task(tsk->cred->security);
+       struct file *file;
+       int rc;
+-      char *tsp = smk_of_task(tsk->cred->security);
+       struct smk_audit_info ad;
+       /*
+@@ -1317,13 +1325,14 @@ static int smack_file_send_sigiotask(struct task_struct *tsk,
+       file = container_of(fown, struct file, f_owner);
+       /* we don't log here as rc can be overriden */
+-      rc = smk_access(file->f_security, tsp, MAY_WRITE, NULL);
++      skp = smk_find_entry(file->f_security);
++      rc = smk_access(skp, tkp->smk_known, MAY_WRITE, NULL);
+       if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE))
+               rc = 0;
+       smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
+       smk_ad_setfield_u_tsk(&ad, tsk);
+-      smack_log(file->f_security, tsp, MAY_WRITE, rc, &ad);
++      smack_log(file->f_security, tkp->smk_known, MAY_WRITE, rc, &ad);
+       return rc;
+ }
+@@ -1478,12 +1487,12 @@ static void smack_cred_transfer(struct cred *new, const struct cred *old)
+ static int smack_kernel_act_as(struct cred *new, u32 secid)
+ {
+       struct task_smack *new_tsp = new->security;
+-      char *smack = smack_from_secid(secid);
++      struct smack_known *skp = smack_from_secid(secid);
+-      if (smack == NULL)
++      if (skp == NULL)
+               return -EINVAL;
+-      new_tsp->smk_task = smack;
++      new_tsp->smk_task = skp;
+       return 0;
+ }
+@@ -1501,8 +1510,8 @@ static int smack_kernel_create_files_as(struct cred *new,
+       struct inode_smack *isp = inode->i_security;
+       struct task_smack *tsp = new->security;
+-      tsp->smk_forked = isp->smk_inode;
+-      tsp->smk_task = isp->smk_inode;
++      tsp->smk_forked = smk_find_entry(isp->smk_inode);
++      tsp->smk_task = tsp->smk_forked;
+       return 0;
+ }
+@@ -1518,10 +1527,11 @@ static int smk_curacc_on_task(struct task_struct *p, int access,
+                               const char *caller)
+ {
+       struct smk_audit_info ad;
++      struct smack_known *skp = smk_of_task(task_security(p));
+       smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK);
+       smk_ad_setfield_u_tsk(&ad, p);
+-      return smk_curacc(smk_of_task(task_security(p)), access, &ad);
++      return smk_curacc(skp->smk_known, access, &ad);
+ }
+ /**
+@@ -1567,7 +1577,9 @@ static int smack_task_getsid(struct task_struct *p)
+  */
+ static void smack_task_getsecid(struct task_struct *p, u32 *secid)
+ {
+-      *secid = smack_to_secid(smk_of_task(task_security(p)));
++      struct smack_known *skp = smk_of_task(task_security(p));
++
++      *secid = skp->smk_secid;
+ }
+ /**
+@@ -1671,6 +1683,8 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
+                          int sig, u32 secid)
+ {
+       struct smk_audit_info ad;
++      struct smack_known *skp;
++      struct smack_known *tkp = smk_of_task(task_security(p));
+       smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
+       smk_ad_setfield_u_tsk(&ad, p);
+@@ -1679,15 +1693,14 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
+        * can write the receiver.
+        */
+       if (secid == 0)
+-              return smk_curacc(smk_of_task(task_security(p)), MAY_WRITE,
+-                                &ad);
++              return smk_curacc(tkp->smk_known, MAY_WRITE, &ad);
+       /*
+        * If the secid isn't 0 we're dealing with some USB IO
+        * specific behavior. This is not clean. For one thing
+        * we can't take privilege into account.
+        */
+-      return smk_access(smack_from_secid(secid),
+-                        smk_of_task(task_security(p)), MAY_WRITE, &ad);
++      skp = smack_from_secid(secid);
++      return smk_access(skp, tkp->smk_known, MAY_WRITE, &ad);
+ }
+ /**
+@@ -1719,7 +1732,9 @@ static int smack_task_wait(struct task_struct *p)
+ static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
+ {
+       struct inode_smack *isp = inode->i_security;
+-      isp->smk_inode = smk_of_task(task_security(p));
++      struct smack_known *skp = smk_of_task(task_security(p));
++
++      isp->smk_inode = skp->smk_known;
+ }
+ /*
+@@ -1738,15 +1753,15 @@ static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
+  */
+ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
+ {
+-      char *csp = smk_of_current();
++      struct smack_known *skp = smk_of_current();
+       struct socket_smack *ssp;
+       ssp = kzalloc(sizeof(struct socket_smack), gfp_flags);
+       if (ssp == NULL)
+               return -ENOMEM;
+-      ssp->smk_in = csp;
+-      ssp->smk_out = csp;
++      ssp->smk_in = skp->smk_known;
++      ssp->smk_out = skp;
+       ssp->smk_packet = NULL;
+       sk->sk_security = ssp;
+@@ -1833,7 +1848,7 @@ static int smack_netlabel(struct sock *sk, int labeled)
+           labeled == SMACK_UNLABELED_SOCKET)
+               netlbl_sock_delattr(sk);
+       else {
+-              skp = smk_find_entry(ssp->smk_out);
++              skp = ssp->smk_out;
+               rc = netlbl_sock_setattr(sk, sk->sk_family, &skp->smk_netlabel);
+       }
+@@ -1856,6 +1871,7 @@ static int smack_netlabel(struct sock *sk, int labeled)
+  */
+ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
+ {
++      struct smack_known *skp;
+       int rc;
+       int sk_lbl;
+       char *hostsp;
+@@ -1874,7 +1890,8 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
+               ad.a.u.net->v4info.daddr = sap->sin_addr.s_addr;
+ #endif
+               sk_lbl = SMACK_UNLABELED_SOCKET;
+-              rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE, &ad);
++              skp = ssp->smk_out;
++              rc = smk_access(skp, hostsp, MAY_WRITE, &ad);
+       } else {
+               sk_lbl = SMACK_CIPSO_SOCKET;
+               rc = 0;
+@@ -1974,8 +1991,8 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr *address,
+       struct sockaddr_in6 *addr6;
+       struct smk_port_label *spp;
+       struct socket_smack *ssp = sk->sk_security;
++      struct smack_known *skp;
+       unsigned short port = 0;
+-      char *subject;
+       char *object;
+       struct smk_audit_info ad;
+ #ifdef CONFIG_AUDIT
+@@ -1983,11 +2000,11 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr *address,
+ #endif
+       if (act == SMK_RECEIVING) {
+-              subject = smack_net_ambient;
++              skp = smack_net_ambient;
+               object = ssp->smk_in;
+       } else {
+-              subject = ssp->smk_out;
+-              object = smack_net_ambient;
++              skp = ssp->smk_out;
++              object = smack_net_ambient->smk_known;
+       }
+       /*
+@@ -2008,7 +2025,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr *address,
+        * It's local so the send check has to have passed.
+        */
+       if (act == SMK_RECEIVING) {
+-              subject = smack_known_web.smk_known;
++              skp = &smack_known_web;
+               goto auditout;
+       }
+@@ -2017,7 +2034,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr *address,
+                       continue;
+               object = spp->smk_in;
+               if (act == SMK_CONNECTING)
+-                      ssp->smk_packet = spp->smk_out;
++                      ssp->smk_packet = spp->smk_out->smk_known;
+               break;
+       }
+@@ -2032,7 +2049,7 @@ auditout:
+       else
+               ad.a.u.net->v6info.daddr = addr6->sin6_addr;
+ #endif
+-      return smk_access(subject, object, MAY_WRITE, &ad);
++      return smk_access(skp, object, MAY_WRITE, &ad);
+ }
+ /**
+@@ -2050,7 +2067,7 @@ auditout:
+ static int smack_inode_setsecurity(struct inode *inode, const char *name,
+                                  const void *value, size_t size, int flags)
+ {
+-      char *sp;
++      struct smack_known *skp;
+       struct inode_smack *nsp = inode->i_security;
+       struct socket_smack *ssp;
+       struct socket *sock;
+@@ -2059,12 +2076,12 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
+       if (value == NULL || size > SMK_LONGLABEL || size == 0)
+               return -EACCES;
+-      sp = smk_import(value, size);
+-      if (sp == NULL)
++      skp = smk_import_entry(value, size);
++      if (skp == NULL)
+               return -EINVAL;
+       if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) {
+-              nsp->smk_inode = sp;
++              nsp->smk_inode = skp->smk_known;
+               nsp->smk_flags |= SMK_INODE_INSTANT;
+               return 0;
+       }
+@@ -2081,9 +2098,9 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
+       ssp = sock->sk->sk_security;
+       if (strcmp(name, XATTR_SMACK_IPIN) == 0)
+-              ssp->smk_in = sp;
++              ssp->smk_in = skp->smk_known;
+       else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) {
+-              ssp->smk_out = sp;
++              ssp->smk_out = skp;
+               if (sock->sk->sk_family == PF_INET) {
+                       rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
+                       if (rc != 0)
+@@ -2203,7 +2220,9 @@ static int smack_flags_to_may(int flags)
+  */
+ static int smack_msg_msg_alloc_security(struct msg_msg *msg)
+ {
+-      msg->security = smk_of_current();
++      struct smack_known *skp = smk_of_current();
++
++      msg->security = skp->smk_known;
+       return 0;
+ }
+@@ -2238,8 +2257,9 @@ static char *smack_of_shm(struct shmid_kernel *shp)
+ static int smack_shm_alloc_security(struct shmid_kernel *shp)
+ {
+       struct kern_ipc_perm *isp = &shp->shm_perm;
++      struct smack_known *skp = smk_of_current();
+-      isp->security = smk_of_current();
++      isp->security = skp->smk_known;
+       return 0;
+ }
+@@ -2361,8 +2381,9 @@ static char *smack_of_sem(struct sem_array *sma)
+ static int smack_sem_alloc_security(struct sem_array *sma)
+ {
+       struct kern_ipc_perm *isp = &sma->sem_perm;
++      struct smack_known *skp = smk_of_current();
+-      isp->security = smk_of_current();
++      isp->security = skp->smk_known;
+       return 0;
+ }
+@@ -2479,8 +2500,9 @@ static int smack_sem_semop(struct sem_array *sma, struct sembuf *sops,
+ static int smack_msg_queue_alloc_security(struct msg_queue *msq)
+ {
+       struct kern_ipc_perm *kisp = &msq->q_perm;
++      struct smack_known *skp = smk_of_current();
+-      kisp->security = smk_of_current();
++      kisp->security = skp->smk_known;
+       return 0;
+ }
+@@ -2652,8 +2674,8 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
+       struct super_block *sbp;
+       struct superblock_smack *sbsp;
+       struct inode_smack *isp;
+-      char *csp = smk_of_current();
+-      char *fetched;
++      struct smack_known *skp;
++      struct smack_known *ckp = smk_of_current();
+       char *final;
+       char trattr[TRANS_TRUE_SIZE];
+       int transflag = 0;
+@@ -2720,7 +2742,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
+                * Programs that change smack have to treat the
+                * pty with respect.
+                */
+-              final = csp;
++              final = ckp->smk_known;
+               break;
+       case SOCKFS_MAGIC:
+               /*
+@@ -2775,9 +2797,9 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
+                * Get the dentry for xattr.
+                */
+               dp = dget(opt_dentry);
+-              fetched = smk_fetch(XATTR_NAME_SMACK, inode, dp);
+-              if (fetched != NULL)
+-                      final = fetched;
++              skp = smk_fetch(XATTR_NAME_SMACK, inode, dp);
++              if (skp != NULL)
++                      final = skp->smk_known;
+               /*
+                * Transmuting directory
+@@ -2817,7 +2839,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
+       }
+       if (final == NULL)
+-              isp->smk_inode = csp;
++              isp->smk_inode = ckp->smk_known;
+       else
+               isp->smk_inode = final;
+@@ -2840,13 +2862,14 @@ unlockandout:
+  */
+ static int smack_getprocattr(struct task_struct *p, char *name, char **value)
+ {
++      struct smack_known *skp = smk_of_task(task_security(p));
+       char *cp;
+       int slen;
+       if (strcmp(name, "current") != 0)
+               return -EINVAL;
+-      cp = kstrdup(smk_of_task(task_security(p)), GFP_KERNEL);
++      cp = kstrdup(skp->smk_known, GFP_KERNEL);
+       if (cp == NULL)
+               return -ENOMEM;
+@@ -2872,7 +2895,7 @@ static int smack_setprocattr(struct task_struct *p, char *name,
+ {
+       struct task_smack *tsp;
+       struct cred *new;
+-      char *newsmack;
++      struct smack_known *skp;
+       /*
+        * Changing another process' Smack value is too dangerous
+@@ -2890,14 +2913,14 @@ static int smack_setprocattr(struct task_struct *p, char *name,
+       if (strcmp(name, "current") != 0)
+               return -EINVAL;
+-      newsmack = smk_import(value, size);
+-      if (newsmack == NULL)
++      skp = smk_import_entry(value, size);
++      if (skp == NULL)
+               return -EINVAL;
+       /*
+        * No process is ever allowed the web ("@") label.
+        */
+-      if (newsmack == smack_known_web.smk_known)
++      if (skp == &smack_known_web)
+               return -EPERM;
+       new = prepare_creds();
+@@ -2905,7 +2928,7 @@ static int smack_setprocattr(struct task_struct *p, char *name,
+               return -ENOMEM;
+       tsp = new->security;
+-      tsp->smk_task = newsmack;
++      tsp->smk_task = skp;
+       commit_creds(new);
+       return size;
+@@ -2923,6 +2946,7 @@ static int smack_setprocattr(struct task_struct *p, char *name,
+ static int smack_unix_stream_connect(struct sock *sock,
+                                    struct sock *other, struct sock *newsk)
+ {
++      struct smack_known *skp;
+       struct socket_smack *ssp = sock->sk_security;
+       struct socket_smack *osp = other->sk_security;
+       struct socket_smack *nsp = newsk->sk_security;
+@@ -2936,15 +2960,17 @@ static int smack_unix_stream_connect(struct sock *sock,
+       smk_ad_setfield_u_net_sk(&ad, other);
+ #endif
+-      if (!smack_privileged(CAP_MAC_OVERRIDE))
+-              rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
++      if (!smack_privileged(CAP_MAC_OVERRIDE)) {
++              skp = ssp->smk_out;
++              rc = smk_access(skp, osp->smk_in, MAY_WRITE, &ad);
++      }
+       /*
+        * Cross reference the peer labels for SO_PEERSEC.
+        */
+       if (rc == 0) {
+-              nsp->smk_packet = ssp->smk_out;
+-              ssp->smk_packet = osp->smk_out;
++              nsp->smk_packet = ssp->smk_out->smk_known;
++              ssp->smk_packet = osp->smk_out->smk_known;
+       }
+       return rc;
+@@ -2962,8 +2988,8 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
+ {
+       struct socket_smack *ssp = sock->sk->sk_security;
+       struct socket_smack *osp = other->sk->sk_security;
++      struct smack_known *skp;
+       struct smk_audit_info ad;
+-      int rc = 0;
+ #ifdef CONFIG_AUDIT
+       struct lsm_network_audit net;
+@@ -2972,10 +2998,11 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
+       smk_ad_setfield_u_net_sk(&ad, other->sk);
+ #endif
+-      if (!smack_privileged(CAP_MAC_OVERRIDE))
+-              rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
++      if (smack_privileged(CAP_MAC_OVERRIDE))
++              return 0;
+-      return rc;
++      skp = ssp->smk_out;
++      return smk_access(skp, osp->smk_in, MAY_WRITE, &ad);
+ }
+ /**
+@@ -3017,13 +3044,12 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
+  * @sap: netlabel secattr
+  * @ssp: socket security information
+  *
+- * Returns a pointer to a Smack label found on the label list.
++ * Returns a pointer to a Smack label entry found on the label list.
+  */
+-static char *smack_from_secattr(struct netlbl_lsm_secattr *sap,
+-                              struct socket_smack *ssp)
++static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
++                                              struct socket_smack *ssp)
+ {
+-      struct smack_known *kp;
+-      char *sp;
++      struct smack_known *skp;
+       int found = 0;
+       if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) {
+@@ -3038,11 +3064,11 @@ static char *smack_from_secattr(struct netlbl_lsm_secattr *sap,
+                * ambient value.
+                */
+               rcu_read_lock();
+-              list_for_each_entry(kp, &smack_known_list, list) {
+-                      if (sap->attr.mls.lvl != kp->smk_netlabel.attr.mls.lvl)
++              list_for_each_entry(skp, &smack_known_list, list) {
++                      if (sap->attr.mls.lvl != skp->smk_netlabel.attr.mls.lvl)
+                               continue;
+                       if (memcmp(sap->attr.mls.cat,
+-                              kp->smk_netlabel.attr.mls.cat,
++                              skp->smk_netlabel.attr.mls.cat,
+                               SMK_CIPSOLEN) != 0)
+                               continue;
+                       found = 1;
+@@ -3051,17 +3077,17 @@ static char *smack_from_secattr(struct netlbl_lsm_secattr *sap,
+               rcu_read_unlock();
+               if (found)
+-                      return kp->smk_known;
++                      return skp;
+               if (ssp != NULL && ssp->smk_in == smack_known_star.smk_known)
+-                      return smack_known_web.smk_known;
+-              return smack_known_star.smk_known;
++                      return &smack_known_web;
++              return &smack_known_star;
+       }
+       if ((sap->flags & NETLBL_SECATTR_SECID) != 0) {
+               /*
+                * Looks like a fallback, which gives us a secid.
+                */
+-              sp = smack_from_secid(sap->attr.secid);
++              skp = smack_from_secid(sap->attr.secid);
+               /*
+                * This has got to be a bug because it is
+                * impossible to specify a fallback without
+@@ -3069,8 +3095,8 @@ static char *smack_from_secattr(struct netlbl_lsm_secattr *sap,
+                * it has a secid, and the only way to get a
+                * secid is from a fallback.
+                */
+-              BUG_ON(sp == NULL);
+-              return sp;
++              BUG_ON(skp == NULL);
++              return skp;
+       }
+       /*
+        * Without guidance regarding the smack value
+@@ -3139,8 +3165,8 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
+ {
+       struct netlbl_lsm_secattr secattr;
+       struct socket_smack *ssp = sk->sk_security;
++      struct smack_known *skp;
+       struct sockaddr sadd;
+-      char *csp;
+       int rc = 0;
+       struct smk_audit_info ad;
+ #ifdef CONFIG_AUDIT
+@@ -3155,9 +3181,9 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
+               rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr);
+               if (rc == 0)
+-                      csp = smack_from_secattr(&secattr, ssp);
++                      skp = smack_from_secattr(&secattr, ssp);
+               else
+-                      csp = smack_net_ambient;
++                      skp = smack_net_ambient;
+               netlbl_secattr_destroy(&secattr);
+@@ -3173,7 +3199,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
+                * This is the simplist possible security model
+                * for networking.
+                */
+-              rc = smk_access(csp, ssp->smk_in, MAY_WRITE, &ad);
++              rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
+               if (rc != 0)
+                       netlbl_skbuff_err(skb, rc, 0);
+               break;
+@@ -3238,7 +3264,7 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
+ {
+       struct netlbl_lsm_secattr secattr;
+       struct socket_smack *ssp = NULL;
+-      char *sp;
++      struct smack_known *skp;
+       int family = PF_UNSPEC;
+       u32 s = 0;      /* 0 is the invalid secid */
+       int rc;
+@@ -3254,7 +3280,7 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
+       if (family == PF_UNIX) {
+               ssp = sock->sk->sk_security;
+-              s = smack_to_secid(ssp->smk_out);
++              s = ssp->smk_out->smk_secid;
+       } else if (family == PF_INET || family == PF_INET6) {
+               /*
+                * Translate what netlabel gave us.
+@@ -3264,8 +3290,8 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
+               netlbl_secattr_init(&secattr);
+               rc = netlbl_skbuff_getattr(skb, family, &secattr);
+               if (rc == 0) {
+-                      sp = smack_from_secattr(&secattr, ssp);
+-                      s = smack_to_secid(sp);
++                      skp = smack_from_secattr(&secattr, ssp);
++                      s = skp->smk_secid;
+               }
+               netlbl_secattr_destroy(&secattr);
+       }
+@@ -3286,13 +3312,15 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
+ static void smack_sock_graft(struct sock *sk, struct socket *parent)
+ {
+       struct socket_smack *ssp;
++      struct smack_known *skp = smk_of_current();
+       if (sk == NULL ||
+           (sk->sk_family != PF_INET && sk->sk_family != PF_INET6))
+               return;
+       ssp = sk->sk_security;
+-      ssp->smk_in = ssp->smk_out = smk_of_current();
++      ssp->smk_in = skp->smk_known;
++      ssp->smk_out = skp;
+       /* cssp->smk_packet is already set in smack_inet_csk_clone() */
+ }
+@@ -3314,7 +3342,6 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
+       struct netlbl_lsm_secattr secattr;
+       struct sockaddr_in addr;
+       struct iphdr *hdr;
+-      char *sp;
+       char *hsp;
+       int rc;
+       struct smk_audit_info ad;
+@@ -3337,9 +3364,9 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
+       netlbl_secattr_init(&secattr);
+       rc = netlbl_skbuff_getattr(skb, family, &secattr);
+       if (rc == 0)
+-              sp = smack_from_secattr(&secattr, ssp);
++              skp = smack_from_secattr(&secattr, ssp);
+       else
+-              sp = smack_known_huh.smk_known;
++              skp = &smack_known_huh;
+       netlbl_secattr_destroy(&secattr);
+ #ifdef CONFIG_AUDIT
+@@ -3352,7 +3379,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
+        * Receiving a packet requires that the other end be able to write
+        * here. Read access is not required.
+        */
+-      rc = smk_access(sp, ssp->smk_in, MAY_WRITE, &ad);
++      rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
+       if (rc != 0)
+               return rc;
+@@ -3360,7 +3387,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
+        * Save the peer's label in the request_sock so we can later setup
+        * smk_packet in the child socket so that SO_PEERCRED can report it.
+        */
+-      req->peer_secid = smack_to_secid(sp);
++      req->peer_secid = skp->smk_secid;
+       /*
+        * We need to decide if we want to label the incoming connection here
+@@ -3373,10 +3400,9 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
+       hsp = smack_host_label(&addr);
+       rcu_read_unlock();
+-      if (hsp == NULL) {
+-              skp = smk_find_entry(sp);
++      if (hsp == NULL)
+               rc = netlbl_req_setattr(req, &skp->smk_netlabel);
+-      } else
++      else
+               netlbl_req_delattr(req);
+       return rc;
+@@ -3393,10 +3419,12 @@ static void smack_inet_csk_clone(struct sock *sk,
+                                const struct request_sock *req)
+ {
+       struct socket_smack *ssp = sk->sk_security;
++      struct smack_known *skp;
+-      if (req->peer_secid != 0)
+-              ssp->smk_packet = smack_from_secid(req->peer_secid);
+-      else
++      if (req->peer_secid != 0) {
++              skp = smack_from_secid(req->peer_secid);
++              ssp->smk_packet = skp->smk_known;
++      } else
+               ssp->smk_packet = NULL;
+ }
+@@ -3422,7 +3450,9 @@ static void smack_inet_csk_clone(struct sock *sk,
+ static int smack_key_alloc(struct key *key, const struct cred *cred,
+                          unsigned long flags)
+ {
+-      key->security = smk_of_task(cred->security);
++      struct smack_known *skp = smk_of_task(cred->security);
++
++      key->security = skp->smk_known;
+       return 0;
+ }
+@@ -3451,7 +3481,7 @@ static int smack_key_permission(key_ref_t key_ref,
+ {
+       struct key *keyp;
+       struct smk_audit_info ad;
+-      char *tsp = smk_of_task(cred->security);
++      struct smack_known *tkp = smk_of_task(cred->security);
+       keyp = key_ref_to_ptr(key_ref);
+       if (keyp == NULL)
+@@ -3465,15 +3495,14 @@ static int smack_key_permission(key_ref_t key_ref,
+       /*
+        * This should not occur
+        */
+-      if (tsp == NULL)
++      if (tkp == NULL)
+               return -EACCES;
+ #ifdef CONFIG_AUDIT
+       smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY);
+       ad.a.u.key_struct.key = keyp->serial;
+       ad.a.u.key_struct.key_desc = keyp->description;
+ #endif
+-      return smk_access(tsp, keyp->security,
+-                               MAY_READWRITE, &ad);
++      return smk_access(tkp, keyp->security, MAY_READWRITE, &ad);
+ }
+ #endif /* CONFIG_KEYS */
+@@ -3555,7 +3584,7 @@ static int smack_audit_rule_known(struct audit_krule *krule)
+ static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
+                                 struct audit_context *actx)
+ {
+-      char *smack;
++      struct smack_known *skp;
+       char *rule = vrule;
+       if (!rule) {
+@@ -3567,7 +3596,7 @@ static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
+       if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
+               return 0;
+-      smack = smack_from_secid(secid);
++      skp = smack_from_secid(secid);
+       /*
+        * No need to do string comparisons. If a match occurs,
+@@ -3575,9 +3604,9 @@ static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
+        * label.
+        */
+       if (op == Audit_equal)
+-              return (rule == smack);
++              return (rule == skp->smk_known);
+       if (op == Audit_not_equal)
+-              return (rule != smack);
++              return (rule != skp->smk_known);
+       return 0;
+ }
+@@ -3605,11 +3634,11 @@ static void smack_audit_rule_free(void *vrule)
+  */
+ static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
+ {
+-      char *sp = smack_from_secid(secid);
++      struct smack_known *skp = smack_from_secid(secid);
+       if (secdata)
+-              *secdata = sp;
+-      *seclen = strlen(sp);
++              *secdata = skp->smk_known;
++      *seclen = strlen(skp->smk_known);
+       return 0;
+ }
+@@ -3845,8 +3874,8 @@ static __init int smack_init(void)
+       if (!security_module_enable(&smack_ops))
+               return 0;
+-      tsp = new_task_smack(smack_known_floor.smk_known,
+-                              smack_known_floor.smk_known, GFP_KERNEL);
++      tsp = new_task_smack(&smack_known_floor, &smack_known_floor,
++                              GFP_KERNEL);
+       if (tsp == NULL)
+               return -ENOMEM;
+diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
+index 53a08b8..3c79cba 100644
+--- a/security/smack/smackfs.c
++++ b/security/smack/smackfs.c
+@@ -66,7 +66,7 @@ static DEFINE_MUTEX(smk_netlbladdr_lock);
+  * If it isn't somehow marked, use this.
+  * It can be reset via smackfs/ambient
+  */
+-char *smack_net_ambient;
++struct smack_known *smack_net_ambient;
+ /*
+  * This is the level in a CIPSO header that indicates a
+@@ -112,7 +112,7 @@ struct smack_master_list {
+ LIST_HEAD(smack_rule_list);
+ struct smack_parsed_rule {
+-      char                    *smk_subject;
++      struct smack_known      *smk_subject;
+       char                    *smk_object;
+       int                     smk_access1;
+       int                     smk_access2;
+@@ -163,9 +163,11 @@ static inline void smack_catset_bit(unsigned int cat, char *catsetp)
+  */
+ static void smk_netlabel_audit_set(struct netlbl_audit *nap)
+ {
++      struct smack_known *skp = smk_of_current();
++
+       nap->loginuid = audit_get_loginuid(current);
+       nap->sessionid = audit_get_sessionid(current);
+-      nap->secid = smack_to_secid(smk_of_current());
++      nap->secid = skp->smk_secid;
+ }
+ /*
+@@ -306,7 +308,7 @@ static int smk_fill_rule(const char *subject, const char *object,
+       struct smack_known *skp;
+       if (import) {
+-              rule->smk_subject = smk_import(subject, len);
++              rule->smk_subject = smk_import_entry(subject, len);
+               if (rule->smk_subject == NULL)
+                       return -1;
+@@ -321,7 +323,7 @@ static int smk_fill_rule(const char *subject, const char *object,
+               kfree(cp);
+               if (skp == NULL)
+                       return -1;
+-              rule->smk_subject = skp->smk_known;
++              rule->smk_subject = skp;
+               cp = smk_parse_smack(object, len);
+               if (cp == NULL)
+@@ -445,7 +447,6 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
+                                       struct list_head *rule_list,
+                                       struct mutex *rule_lock, int format)
+ {
+-      struct smack_known *skp;
+       struct smack_parsed_rule *rule;
+       char *data;
+       int datalen;
+@@ -505,12 +506,10 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
+                       goto out_free_rule;
+       }
+-
+       if (rule_list == NULL) {
+               load = 1;
+-              skp = smk_find_entry(rule->smk_subject);
+-              rule_list = &skp->smk_rules;
+-              rule_lock = &skp->smk_rules_lock;
++              rule_list = &rule->smk_subject->smk_rules;
++              rule_lock = &rule->smk_subject->smk_rules_lock;
+       }
+       rc = smk_set_access(rule, rule_list, rule_lock, load);
+@@ -579,13 +578,14 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max)
+        * because you should expect to be able to write
+        * anything you read back.
+        */
+-      if (strlen(srp->smk_subject) >= max || strlen(srp->smk_object) >= max)
++      if (strlen(srp->smk_subject->smk_known) >= max ||
++          strlen(srp->smk_object) >= max)
+               return;
+       if (srp->smk_access == 0)
+               return;
+-      seq_printf(s, "%s %s", srp->smk_subject, srp->smk_object);
++      seq_printf(s, "%s %s", srp->smk_subject->smk_known, srp->smk_object);
+       seq_putc(s, ' ');
+@@ -738,9 +738,9 @@ static void smk_unlbl_ambient(char *oldambient)
+                              __func__, __LINE__, rc);
+       }
+       if (smack_net_ambient == NULL)
+-              smack_net_ambient = smack_known_floor.smk_known;
++              smack_net_ambient = &smack_known_floor;
+-      rc = netlbl_cfg_unlbl_map_add(smack_net_ambient, PF_INET,
++      rc = netlbl_cfg_unlbl_map_add(smack_net_ambient->smk_known, PF_INET,
+                                     NULL, NULL, &nai);
+       if (rc != 0)
+               printk(KERN_WARNING "%s:%d add rc = %d\n",
+@@ -1535,11 +1535,12 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
+        */
+       mutex_lock(&smack_ambient_lock);
+-      asize = strlen(smack_net_ambient) + 1;
++      asize = strlen(smack_net_ambient->smk_known) + 1;
+       if (cn >= asize)
+               rc = simple_read_from_buffer(buf, cn, ppos,
+-                                           smack_net_ambient, asize);
++                                           smack_net_ambient->smk_known,
++                                           asize);
+       else
+               rc = -EINVAL;
+@@ -1560,8 +1561,8 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
+ static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
+                                size_t count, loff_t *ppos)
+ {
++      struct smack_known *skp;
+       char *oldambient;
+-      char *smack = NULL;
+       char *data;
+       int rc = count;
+@@ -1577,16 +1578,16 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
+               goto out;
+       }
+-      smack = smk_import(data, count);
+-      if (smack == NULL) {
++      skp = smk_import_entry(data, count);
++      if (skp == NULL) {
+               rc = -EINVAL;
+               goto out;
+       }
+       mutex_lock(&smack_ambient_lock);
+-      oldambient = smack_net_ambient;
+-      smack_net_ambient = smack;
++      oldambient = smack_net_ambient->smk_known;
++      smack_net_ambient = skp;
+       smk_unlbl_ambient(oldambient);
+       mutex_unlock(&smack_ambient_lock);
+@@ -1645,7 +1646,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
+                                size_t count, loff_t *ppos)
+ {
+       char *data;
+-      char *sp = smk_of_task(current->cred->security);
++      struct smack_known *skp = smk_of_task(current->cred->security);
+       int rc = count;
+       if (!smack_privileged(CAP_MAC_ADMIN))
+@@ -1656,7 +1657,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
+        * explicitly for clarity. The smk_access() implementation
+        * would use smk_access(smack_onlycap, MAY_WRITE)
+        */
+-      if (smack_onlycap != NULL && smack_onlycap != sp)
++      if (smack_onlycap != NULL && smack_onlycap != skp->smk_known)
+               return -EPERM;
+       data = kzalloc(count, GFP_KERNEL);
+@@ -1866,8 +1867,8 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf,
+       if (res)
+               return -EINVAL;
+-      res = smk_access(rule.smk_subject, rule.smk_object, rule.smk_access1,
+-                        NULL);
++      res = smk_access(rule.smk_subject, rule.smk_object,
++                              rule.smk_access1, NULL);
+       data[0] = res == 0 ? '1' : '0';
+       data[1] = '\0';
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1045-Smack-Add-smkfstransmute-mount-option.patch b/patches.tizen/1045-Smack-Add-smkfstransmute-mount-option.patch
new file mode 100644 (file)
index 0000000..915bd88
--- /dev/null
@@ -0,0 +1,107 @@
+From b5cb6e1e81cb6392a91f4ffb6a662b11f7bb333a Mon Sep 17 00:00:00 2001
+From: Casey Schaufler <casey@schaufler-ca.com>
+Date: Wed, 22 May 2013 18:43:07 -0700
+Subject: [PATCH 1045/1302] Smack: Add smkfstransmute mount option
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Suppliment the smkfsroot mount option with another, smkfstransmute,
+that does the same thing but also marks the root inode as
+transmutting. This allows a freshly created filesystem to
+be mounted with a transmutting heirarchy.
+
+Targeted for git://git.gitorious.org/smack-next/kernel.git
+
+Change-Id: I3d7238ca1c5251fcfc96a6a61bec47bdf9466152
+Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
+Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ security/smack/smack.h     |  1 +
+ security/smack/smack_lsm.c | 25 ++++++++++++++++++++-----
+ 2 files changed, 21 insertions(+), 5 deletions(-)
+
+diff --git a/security/smack/smack.h b/security/smack/smack.h
+index 159f25b..339614c 100644
+--- a/security/smack/smack.h
++++ b/security/smack/smack.h
+@@ -143,6 +143,7 @@ struct smk_port_label {
+ #define SMK_FSFLOOR   "smackfsfloor="
+ #define SMK_FSHAT     "smackfshat="
+ #define SMK_FSROOT    "smackfsroot="
++#define SMK_FSTRANS   "smackfstransmute="
+ #define SMACK_CIPSO_OPTION    "-CIPSO"
+diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
+index 3669d9f..6a08330 100644
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -261,8 +261,9 @@ static int smack_sb_alloc_security(struct super_block *sb)
+       sbsp->smk_default = smack_known_floor.smk_known;
+       sbsp->smk_floor = smack_known_floor.smk_known;
+       sbsp->smk_hat = smack_known_hat.smk_known;
+-      sbsp->smk_initialized = 0;
+-
++      /*
++       * smk_initialized will be zero from kzalloc.
++       */
+       sb->s_security = sbsp;
+       return 0;
+@@ -306,6 +307,8 @@ static int smack_sb_copy_data(char *orig, char *smackopts)
+                       dp = smackopts;
+               else if (strstr(cp, SMK_FSROOT) == cp)
+                       dp = smackopts;
++              else if (strstr(cp, SMK_FSTRANS) == cp)
++                      dp = smackopts;
+               else
+                       dp = otheropts;
+@@ -341,8 +344,9 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
+       char *op;
+       char *commap;
+       char *nsp;
++      int transmute = 0;
+-      if (sp->smk_initialized != 0)
++      if (sp->smk_initialized)
+               return 0;
+       sp->smk_initialized = 1;
+@@ -373,6 +377,13 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
+                       nsp = smk_import(op, 0);
+                       if (nsp != NULL)
+                               sp->smk_root = nsp;
++              } else if (strncmp(op, SMK_FSTRANS, strlen(SMK_FSTRANS)) == 0) {
++                      op += strlen(SMK_FSTRANS);
++                      nsp = smk_import(op, 0);
++                      if (nsp != NULL) {
++                              sp->smk_root = nsp;
++                              transmute = 1;
++                      }
+               }
+       }
+@@ -380,11 +391,15 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
+        * Initialize the root inode.
+        */
+       isp = inode->i_security;
+-      if (isp == NULL)
++      if (inode->i_security == NULL) {
+               inode->i_security = new_inode_smack(sp->smk_root);
+-      else
++              isp = inode->i_security;
++      } else
+               isp->smk_inode = sp->smk_root;
++      if (transmute)
++              isp->smk_flags |= SMK_INODE_TRANSMUTE;
++
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1046-Smack-Fix-possible-NULL-pointer-dereference-at-smk_n.patch b/patches.tizen/1046-Smack-Fix-possible-NULL-pointer-dereference-at-smk_n.patch
new file mode 100644 (file)
index 0000000..86ef02f
--- /dev/null
@@ -0,0 +1,35 @@
+From 7cb8c24389c6d3bd3745506480e103fdb8574ab3 Mon Sep 17 00:00:00 2001
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Date: Mon, 27 May 2013 20:11:27 +0900
+Subject: [PATCH 1046/1302] Smack: Fix possible NULL pointer dereference at
+ smk_netlbl_mls()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+netlbl_secattr_catmap_alloc(GFP_ATOMIC) can return NULL.
+
+Change-Id: Id67f7f66a61a05e7e45b66a50b5d0869ef7e5117
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ security/smack/smack_access.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
+index 53f2327..6a0377f 100644
+--- a/security/smack/smack_access.c
++++ b/security/smack/smack_access.c
+@@ -403,6 +403,8 @@ int smk_netlbl_mls(int level, char *catset, struct netlbl_lsm_secattr *sap,
+       sap->flags |= NETLBL_SECATTR_MLS_CAT;
+       sap->attr.mls.lvl = level;
+       sap->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
++      if (!sap->attr.mls.cat)
++              return -ENOMEM;
+       sap->attr.mls.cat->startbit = 0;
+       for (cat = 1, cp = catset, byte = 0; byte < len; cp++, byte++)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1047-Smack-Fix-the-bug-smackcipso-can-t-set-CIPSO-correct.patch b/patches.tizen/1047-Smack-Fix-the-bug-smackcipso-can-t-set-CIPSO-correct.patch
new file mode 100644 (file)
index 0000000..6b12d70
--- /dev/null
@@ -0,0 +1,43 @@
+From 1888abdbaf5078ad6c4a08d461d0f3f3701962d8 Mon Sep 17 00:00:00 2001
+From: "Passion,Zhao" <passion.zhao@intel.com>
+Date: Mon, 3 Jun 2013 11:42:24 +0800
+Subject: [PATCH 1047/1302] Smack: Fix the bug smackcipso can't set CIPSO
+ correctly
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Bug report: https://tizendev.org/bugs/browse/TDIS-3891
+
+The reason is userspace libsmack only use "smackfs/cipso2" long-label interface,
+but the code's logical is still for orginal fixed length label. Now update
+smack_cipso_apply() to support flexible label (<=256 including tailing '\0')
+
+There is also a bug in kernel/security/smack/smackfs.c:
+When smk_set_cipso() parsing the CIPSO setting from userspace, the offset of
+CIPSO level should be "strlen(label)+1" instead of "strlen(label)"
+
+Change-Id: I7be85b4ade557e25569970e61c9e09ca01b5f2d9
+Signed-off-by: Passion,Zhao <passion.zhao@intel.com>
+Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ security/smack/smackfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
+index 3c79cba..ab16703 100644
+--- a/security/smack/smackfs.c
++++ b/security/smack/smackfs.c
+@@ -881,7 +881,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
+       if (format == SMK_FIXED24_FMT)
+               rule += SMK_LABELLEN;
+       else
+-              rule += strlen(skp->smk_known);
++              rule += strlen(skp->smk_known) + 1;
+       ret = sscanf(rule, "%d", &maplevel);
+       if (ret != 1 || maplevel > SMACK_CIPSO_MAXLEVEL)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1048-Security-Add-Hook-to-test-if-the-particular-xattr-is.patch b/patches.tizen/1048-Security-Add-Hook-to-test-if-the-particular-xattr-is.patch
new file mode 100644 (file)
index 0000000..e1ccf5e
--- /dev/null
@@ -0,0 +1,176 @@
+From 9cf5cc4f969032b8f571025845a59fce3ba2a17c Mon Sep 17 00:00:00 2001
+From: David Quigley <dpquigl@davequigley.com>
+Date: Wed, 22 May 2013 12:50:35 -0400
+Subject: [PATCH 1048/1302] Security: Add Hook to test if the particular xattr
+ is part of a MAC model.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The interface to request security labels from user space is the xattr
+interface. When requesting the security label from an NFS server it is
+important to make sure the requested xattr actually is a MAC label. This allows
+us to make sure that we get the desired semantics from the attribute instead of
+something else such as capabilities or a time based LSM.
+
+Change-Id: I283f116953f958877826ba772661b5755986ac99
+Acked-by: Eric Paris <eparis@redhat.com>
+Acked-by: James Morris <james.l.morris@oracle.com>
+Signed-off-by: Matthew N. Dodd <Matthew.Dodd@sparta.com>
+Signed-off-by: Miguel Rodel Felipe <Rodel_FM@dsi.a-star.edu.sg>
+Signed-off-by: Phua Eu Gene <PHUA_Eu_Gene@dsi.a-star.edu.sg>
+Signed-off-by: Khin Mi Mi Aung <Mi_Mi_AUNG@dsi.a-star.edu.sg>
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/security.h   | 14 ++++++++++++++
+ security/capability.c      |  6 ++++++
+ security/security.c        |  6 ++++++
+ security/selinux/hooks.c   |  6 ++++++
+ security/smack/smack_lsm.c | 11 +++++++++++
+ 5 files changed, 43 insertions(+)
+
+diff --git a/include/linux/security.h b/include/linux/security.h
+index 4686491..1d8fe3c 100644
+--- a/include/linux/security.h
++++ b/include/linux/security.h
+@@ -1313,6 +1313,13 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
+  *    @pages contains the number of pages.
+  *    Return 0 if permission is granted.
+  *
++ * @ismaclabel:
++ *    Check if the extended attribute specified by @name
++ *    represents a MAC label. Returns 1 if name is a MAC
++ *    attribute otherwise returns 0.
++ *    @name full extended attribute name to check against
++ *    LSM as a MAC label.
++ *
+  * @secid_to_secctx:
+  *    Convert secid to security context.  If secdata is NULL the length of
+  *    the result will be returned in seclen, but no secdata will be returned.
+@@ -1590,6 +1597,7 @@ struct security_operations {
+       int (*getprocattr) (struct task_struct *p, char *name, char **value);
+       int (*setprocattr) (struct task_struct *p, char *name, void *value, size_t size);
++      int (*ismaclabel) (const char *name);
+       int (*secid_to_secctx) (u32 secid, char **secdata, u32 *seclen);
+       int (*secctx_to_secid) (const char *secdata, u32 seclen, u32 *secid);
+       void (*release_secctx) (char *secdata, u32 seclen);
+@@ -1840,6 +1848,7 @@ void security_d_instantiate(struct dentry *dentry, struct inode *inode);
+ int security_getprocattr(struct task_struct *p, char *name, char **value);
+ int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size);
+ int security_netlink_send(struct sock *sk, struct sk_buff *skb);
++int security_ismaclabel(const char *name);
+ int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
+ int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
+ void security_release_secctx(char *secdata, u32 seclen);
+@@ -2520,6 +2529,11 @@ static inline int security_netlink_send(struct sock *sk, struct sk_buff *skb)
+       return cap_netlink_send(sk, skb);
+ }
++static inline int security_ismaclabel(const char *name)
++{
++      return 0;
++}
++
+ static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
+ {
+       return -EOPNOTSUPP;
+diff --git a/security/capability.c b/security/capability.c
+index 1728d4e..26e0d3d 100644
+--- a/security/capability.c
++++ b/security/capability.c
+@@ -816,6 +816,11 @@ static int cap_setprocattr(struct task_struct *p, char *name, void *value,
+       return -EINVAL;
+ }
++static int cap_ismaclabel(const char *name)
++{
++      return 0;
++}
++
+ static int cap_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
+ {
+       return -EOPNOTSUPP;
+@@ -1034,6 +1039,7 @@ void __init security_fixup_ops(struct security_operations *ops)
+       set_to_cap_if_null(ops, d_instantiate);
+       set_to_cap_if_null(ops, getprocattr);
+       set_to_cap_if_null(ops, setprocattr);
++      set_to_cap_if_null(ops, ismaclabel);
+       set_to_cap_if_null(ops, secid_to_secctx);
+       set_to_cap_if_null(ops, secctx_to_secid);
+       set_to_cap_if_null(ops, release_secctx);
+diff --git a/security/security.c b/security/security.c
+index a3dce87..bf919ce 100644
+--- a/security/security.c
++++ b/security/security.c
+@@ -1047,6 +1047,12 @@ int security_netlink_send(struct sock *sk, struct sk_buff *skb)
+       return security_ops->netlink_send(sk, skb);
+ }
++int security_ismaclabel(const char *name)
++{
++      return security_ops->ismaclabel(name);
++}
++EXPORT_SYMBOL(security_ismaclabel);
++
+ int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
+ {
+       return security_ops->secid_to_secctx(secid, secdata, seclen);
+diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
+index 5c6f2cd..11d2fc0 100644
+--- a/security/selinux/hooks.c
++++ b/security/selinux/hooks.c
+@@ -5420,6 +5420,11 @@ abort_change:
+       return error;
+ }
++static int selinux_ismaclabel(const char *name)
++{
++      return (strcmp(name, XATTR_SELINUX_SUFFIX) == 0);
++}
++
+ static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
+ {
+       return security_sid_to_context(secid, secdata, seclen);
+@@ -5657,6 +5662,7 @@ static struct security_operations selinux_ops = {
+       .getprocattr =                  selinux_getprocattr,
+       .setprocattr =                  selinux_setprocattr,
++      .ismaclabel =                   selinux_ismaclabel,
+       .secid_to_secctx =              selinux_secid_to_secctx,
+       .secctx_to_secid =              selinux_secctx_to_secid,
+       .release_secctx =               selinux_release_secctx,
+diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
+index 6a08330..3f7682a 100644
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -3640,6 +3640,16 @@ static void smack_audit_rule_free(void *vrule)
+ #endif /* CONFIG_AUDIT */
+ /**
++ * smack_ismaclabel - check if xattr @name references a smack MAC label
++ * @name: Full xattr name to check.
++ */
++static int smack_ismaclabel(const char *name)
++{
++      return (strcmp(name, XATTR_SMACK_SUFFIX) == 0);
++}
++
++
++/**
+  * smack_secid_to_secctx - return the smack label for a secid
+  * @secid: incoming integer
+  * @secdata: destination
+@@ -3836,6 +3846,7 @@ struct security_operations smack_ops = {
+       .audit_rule_free =              smack_audit_rule_free,
+ #endif /* CONFIG_AUDIT */
++      .ismaclabel =                   smack_ismaclabel,
+       .secid_to_secctx =              smack_secid_to_secctx,
+       .secctx_to_secid =              smack_secctx_to_secid,
+       .release_secctx =               smack_release_secctx,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1049-xattr-Constify-name-member-of-struct-xattr.patch b/patches.tizen/1049-xattr-Constify-name-member-of-struct-xattr.patch
new file mode 100644 (file)
index 0000000..71ebdf5
--- /dev/null
@@ -0,0 +1,245 @@
+From 1ff243e2568c443807cf699fce52a9ddecc2fcef Mon Sep 17 00:00:00 2001
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Date: Thu, 25 Jul 2013 05:44:02 +0900
+Subject: [PATCH 1049/1302] xattr: Constify ->name member of "struct xattr".
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Since everybody sets kstrdup()ed constant string to "struct xattr"->name but
+nobody modifies "struct xattr"->name , we can omit kstrdup() and its failure
+checking by constifying ->name member of "struct xattr".
+
+Change-Id: I6cb5cd7f29c01956dd0d1579af81a518a5936071
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Reviewed-by: Joel Becker <jlbec@evilplan.org> [ocfs2]
+Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com>
+Acked-by: Casey Schaufler <casey@schaufler-ca.com>
+Acked-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
+Reviewed-by: Paul Moore <paul@paul-moore.com>
+Tested-by: Paul Moore <paul@paul-moore.com>
+Acked-by: Eric Paris <eparis@redhat.com>
+Signed-off-by: James Morris <james.l.morris@oracle.com>
+Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ fs/ocfs2/xattr.h                    |  2 +-
+ include/linux/security.h            |  8 ++++----
+ include/linux/xattr.h               |  2 +-
+ include/uapi/linux/reiserfs_xattr.h |  2 +-
+ security/capability.c               |  2 +-
+ security/integrity/evm/evm_main.c   |  2 +-
+ security/security.c                 |  8 +++-----
+ security/selinux/hooks.c            | 17 ++++++-----------
+ security/smack/smack_lsm.c          |  9 +++------
+ 9 files changed, 21 insertions(+), 31 deletions(-)
+
+diff --git a/fs/ocfs2/xattr.h b/fs/ocfs2/xattr.h
+index e5c7f15..19f134e 100644
+--- a/fs/ocfs2/xattr.h
++++ b/fs/ocfs2/xattr.h
+@@ -32,7 +32,7 @@ enum ocfs2_xattr_type {
+ struct ocfs2_security_xattr_info {
+       int enable;
+-      char *name;
++      const char *name;
+       void *value;
+       size_t value_len;
+ };
+diff --git a/include/linux/security.h b/include/linux/security.h
+index 1d8fe3c..0f246d4 100644
+--- a/include/linux/security.h
++++ b/include/linux/security.h
+@@ -1472,7 +1472,7 @@ struct security_operations {
+       int (*inode_alloc_security) (struct inode *inode);
+       void (*inode_free_security) (struct inode *inode);
+       int (*inode_init_security) (struct inode *inode, struct inode *dir,
+-                                  const struct qstr *qstr, char **name,
++                                  const struct qstr *qstr, const char **name,
+                                   void **value, size_t *len);
+       int (*inode_create) (struct inode *dir,
+                            struct dentry *dentry, umode_t mode);
+@@ -1744,7 +1744,7 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
+                                const struct qstr *qstr,
+                                initxattrs initxattrs, void *fs_data);
+ int security_old_inode_init_security(struct inode *inode, struct inode *dir,
+-                                   const struct qstr *qstr, char **name,
++                                   const struct qstr *qstr, const char **name,
+                                    void **value, size_t *len);
+ int security_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode);
+ int security_inode_link(struct dentry *old_dentry, struct inode *dir,
+@@ -2056,8 +2056,8 @@ static inline int security_inode_init_security(struct inode *inode,
+ static inline int security_old_inode_init_security(struct inode *inode,
+                                                  struct inode *dir,
+                                                  const struct qstr *qstr,
+-                                                 char **name, void **value,
+-                                                 size_t *len)
++                                                 const char **name,
++                                                 void **value, size_t *len)
+ {
+       return -EOPNOTSUPP;
+ }
+diff --git a/include/linux/xattr.h b/include/linux/xattr.h
+index fdbafc6..91b0a68 100644
+--- a/include/linux/xattr.h
++++ b/include/linux/xattr.h
+@@ -31,7 +31,7 @@ struct xattr_handler {
+ };
+ struct xattr {
+-      char *name;
++      const char *name;
+       void *value;
+       size_t value_len;
+ };
+diff --git a/include/uapi/linux/reiserfs_xattr.h b/include/uapi/linux/reiserfs_xattr.h
+index d8ce17c..38fdd64 100644
+--- a/include/uapi/linux/reiserfs_xattr.h
++++ b/include/uapi/linux/reiserfs_xattr.h
+@@ -16,7 +16,7 @@ struct reiserfs_xattr_header {
+ };
+ struct reiserfs_security_handle {
+-      char *name;
++      const char *name;
+       void *value;
+       size_t length;
+ };
+diff --git a/security/capability.c b/security/capability.c
+index 26e0d3d..432e8af 100644
+--- a/security/capability.c
++++ b/security/capability.c
+@@ -119,7 +119,7 @@ static void cap_inode_free_security(struct inode *inode)
+ }
+ static int cap_inode_init_security(struct inode *inode, struct inode *dir,
+-                                 const struct qstr *qstr, char **name,
++                                 const struct qstr *qstr, const char **name,
+                                  void **value, size_t *len)
+ {
+       return -EOPNOTSUPP;
+diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
+index cdbde17..2787080 100644
+--- a/security/integrity/evm/evm_main.c
++++ b/security/integrity/evm/evm_main.c
+@@ -405,7 +405,7 @@ int evm_inode_init_security(struct inode *inode,
+       evm_xattr->value = xattr_data;
+       evm_xattr->value_len = sizeof(*xattr_data);
+-      evm_xattr->name = kstrdup(XATTR_EVM_SUFFIX, GFP_NOFS);
++      evm_xattr->name = XATTR_EVM_SUFFIX;
+       return 0;
+ out:
+       kfree(xattr_data);
+diff --git a/security/security.c b/security/security.c
+index bf919ce..7813fd8 100644
+--- a/security/security.c
++++ b/security/security.c
+@@ -335,10 +335,10 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
+       if (unlikely(IS_PRIVATE(inode)))
+               return 0;
+-      memset(new_xattrs, 0, sizeof new_xattrs);
+       if (!initxattrs)
+               return security_ops->inode_init_security(inode, dir, qstr,
+                                                        NULL, NULL, NULL);
++      memset(new_xattrs, 0, sizeof(new_xattrs));
+       lsm_xattr = new_xattrs;
+       ret = security_ops->inode_init_security(inode, dir, qstr,
+                                               &lsm_xattr->name,
+@@ -353,16 +353,14 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
+               goto out;
+       ret = initxattrs(inode, new_xattrs, fs_data);
+ out:
+-      for (xattr = new_xattrs; xattr->name != NULL; xattr++) {
+-              kfree(xattr->name);
++      for (xattr = new_xattrs; xattr->value != NULL; xattr++)
+               kfree(xattr->value);
+-      }
+       return (ret == -EOPNOTSUPP) ? 0 : ret;
+ }
+ EXPORT_SYMBOL(security_inode_init_security);
+ int security_old_inode_init_security(struct inode *inode, struct inode *dir,
+-                                   const struct qstr *qstr, char **name,
++                                   const struct qstr *qstr, const char **name,
+                                    void **value, size_t *len)
+ {
+       if (unlikely(IS_PRIVATE(inode)))
+diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
+index 11d2fc0..6bf3f9a 100644
+--- a/security/selinux/hooks.c
++++ b/security/selinux/hooks.c
+@@ -2516,7 +2516,8 @@ static void selinux_inode_free_security(struct inode *inode)
+ }
+ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
+-                                     const struct qstr *qstr, char **name,
++                                     const struct qstr *qstr,
++                                     const char **name,
+                                      void **value, size_t *len)
+ {
+       const struct task_security_struct *tsec = current_security();
+@@ -2524,7 +2525,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
+       struct superblock_security_struct *sbsec;
+       u32 sid, newsid, clen;
+       int rc;
+-      char *namep = NULL, *context;
++      char *context;
+       dsec = dir->i_security;
+       sbsec = dir->i_sb->s_security;
+@@ -2560,19 +2561,13 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
+       if (!ss_initialized || !(sbsec->flags & SE_SBLABELSUPP))
+               return -EOPNOTSUPP;
+-      if (name) {
+-              namep = kstrdup(XATTR_SELINUX_SUFFIX, GFP_NOFS);
+-              if (!namep)
+-                      return -ENOMEM;
+-              *name = namep;
+-      }
++      if (name)
++              *name = XATTR_SELINUX_SUFFIX;
+       if (value && len) {
+               rc = security_sid_to_context_force(newsid, &context, &clen);
+-              if (rc) {
+-                      kfree(namep);
++              if (rc)
+                       return rc;
+-              }
+               *value = context;
+               *len = clen;
+       }
+diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
+index 3f7682a..a113a77 100644
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -582,7 +582,7 @@ static void smack_inode_free_security(struct inode *inode)
+  * Returns 0 if it all works out, -ENOMEM if there's no memory
+  */
+ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
+-                                   const struct qstr *qstr, char **name,
++                                   const struct qstr *qstr, const char **name,
+                                    void **value, size_t *len)
+ {
+       struct inode_smack *issp = inode->i_security;
+@@ -591,11 +591,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
+       char *dsp = smk_of_inode(dir);
+       int may;
+-      if (name) {
+-              *name = kstrdup(XATTR_SMACK_SUFFIX, GFP_NOFS);
+-              if (*name == NULL)
+-                      return -ENOMEM;
+-      }
++      if (name)
++              *name = XATTR_SMACK_SUFFIX;
+       if (value) {
+               rcu_read_lock();
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1050-security-smack-fix-memleak-in-smk_write_rules_list.patch b/patches.tizen/1050-security-smack-fix-memleak-in-smk_write_rules_list.patch
new file mode 100644 (file)
index 0000000..da4906b
--- /dev/null
@@ -0,0 +1,96 @@
+From 2ee409b5009476618833fd7dccb3ee382bfaaa9c Mon Sep 17 00:00:00 2001
+From: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Date: Thu, 6 Jun 2013 09:30:50 +0200
+Subject: [PATCH 1050/1302] security: smack: fix memleak in
+ smk_write_rules_list()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The smack_parsed_rule structure is allocated.  If a rule is successfully
+installed then the last reference to the object is lost.  This patch fixes this
+leak. Moreover smack_parsed_rule is allocated on stack because it no longer
+needed ofter smk_write_rules_list() is finished.
+
+Change-Id: I5b4dcadc6a9d675ab630b23c00edeaf595b5b857
+Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ security/smack/smackfs.c | 33 +++++++++++----------------------
+ 1 file changed, 11 insertions(+), 22 deletions(-)
+
+diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
+index ab16703..269b270 100644
+--- a/security/smack/smackfs.c
++++ b/security/smack/smackfs.c
+@@ -447,7 +447,7 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
+                                       struct list_head *rule_list,
+                                       struct mutex *rule_lock, int format)
+ {
+-      struct smack_parsed_rule *rule;
++      struct smack_parsed_rule rule;
+       char *data;
+       int datalen;
+       int rc = -EINVAL;
+@@ -479,47 +479,36 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
+               goto out;
+       }
+-      rule = kzalloc(sizeof(*rule), GFP_KERNEL);
+-      if (rule == NULL) {
+-              rc = -ENOMEM;
+-              goto out;
+-      }
+-
+       if (format == SMK_LONG_FMT) {
+               /*
+                * Be sure the data string is terminated.
+                */
+               data[count] = '\0';
+-              if (smk_parse_long_rule(data, rule, 1, 0))
+-                      goto out_free_rule;
++              if (smk_parse_long_rule(data, &rule, 1, 0))
++                      goto out;
+       } else if (format == SMK_CHANGE_FMT) {
+               data[count] = '\0';
+-              if (smk_parse_long_rule(data, rule, 1, 1))
+-                      goto out_free_rule;
++              if (smk_parse_long_rule(data, &rule, 1, 1))
++                      goto out;
+       } else {
+               /*
+                * More on the minor hack for backward compatibility
+                */
+               if (count == (SMK_OLOADLEN))
+                       data[SMK_OLOADLEN] = '-';
+-              if (smk_parse_rule(data, rule, 1))
+-                      goto out_free_rule;
++              if (smk_parse_rule(data, &rule, 1))
++                      goto out;
+       }
+       if (rule_list == NULL) {
+               load = 1;
+-              rule_list = &rule->smk_subject->smk_rules;
+-              rule_lock = &rule->smk_subject->smk_rules_lock;
++              rule_list = &rule.smk_subject->smk_rules;
++              rule_lock = &rule.smk_subject->smk_rules_lock;
+       }
+-      rc = smk_set_access(rule, rule_list, rule_lock, load);
+-      if (rc == 0) {
++      rc = smk_set_access(&rule, rule_list, rule_lock, load);
++      if (rc == 0)
+               rc = count;
+-              goto out;
+-      }
+-
+-out_free_rule:
+-      kfree(rule);
+ out:
+       kfree(data);
+       return rc;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1051-security-smack-add-a-hash-table-to-quicken-smk_find_.patch b/patches.tizen/1051-security-smack-add-a-hash-table-to-quicken-smk_find_.patch
new file mode 100644 (file)
index 0000000..7b7e811
--- /dev/null
@@ -0,0 +1,172 @@
+From afe16280f7f3740b8644dcae9993c71bdeacff83 Mon Sep 17 00:00:00 2001
+From: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Date: Tue, 11 Jun 2013 14:55:13 +0200
+Subject: [PATCH 1051/1302] security: smack: add a hash table to quicken
+ smk_find_entry()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Accepted for the smack-next tree after changing the number of
+slots from 128 to 16.
+
+This patch adds a hash table to quicken searching of a smack label by its name.
+
+Basically, the patch improves performance of SMACK initialization.  Parsing of
+rules involves translation from a string to a smack_known (aka label) entity
+which is done in smk_find_entry().
+
+The current implementation of the function iterates over a global list of
+smack_known resulting in O(N) complexity for smk_find_entry().  The total
+complexity of SMACK initialization becomes O(rules * labels).  Therefore it
+scales quadratically with a complexity of a system.
+
+Applying the patch reduced the complexity of smk_find_entry() to O(1) as long
+as number of label is in hundreds. If the number of labels is increased please
+update SMACK_HASH_SLOTS constant defined in security/smack/smack.h. Introducing
+the configuration of this constant with Kconfig or cmdline might be a good
+idea.
+
+The size of the hash table was adjusted experimentally.  The rule set used by
+TIZEN contains circa 17K rules for 500 labels.  The table above contains
+results of SMACK initialization using 'time smackctl apply' bash command.
+The 'Ref' is a kernel without this patch applied. The consecutive values
+refers to value of SMACK_HASH_SLOTS.  Every measurement was repeated three
+times to reduce noise.
+
+     |  Ref  |   1   |   2   |   4   |   8   |   16  |   32  |   64  |  128  |  256  |  512
+--------------------------------------------------------------------------------------------
+Run1 | 1.156 | 1.096 | 0.883 | 0.764 | 0.692 | 0.667 | 0.649 | 0.633 | 0.634 | 0.629 | 0.620
+Run2 | 1.156 | 1.111 | 0.885 | 0.764 | 0.694 | 0.661 | 0.649 | 0.651 | 0.634 | 0.638 | 0.623
+Run3 | 1.160 | 1.107 | 0.886 | 0.764 | 0.694 | 0.671 | 0.661 | 0.638 | 0.631 | 0.624 | 0.638
+AVG  | 1.157 | 1.105 | 0.885 | 0.764 | 0.693 | 0.666 | 0.653 | 0.641 | 0.633 | 0.630 | 0.627
+
+Surprisingly, a single hlist is slightly faster than a double-linked list.
+The speed-up saturates near 64 slots.  Therefore I chose value 128 to provide
+some margin if more labels were used.
+It looks that IO becomes a new bottleneck.
+
+Change-Id: Ib1f7bf9f52337b07ccfab10e8fdf52014bd3b466
+Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ security/smack/smack.h        |  5 +++++
+ security/smack/smack_access.c | 29 ++++++++++++++++++++++++++---
+ security/smack/smack_lsm.c    | 12 ++++++------
+ 3 files changed, 37 insertions(+), 9 deletions(-)
+
+diff --git a/security/smack/smack.h b/security/smack/smack.h
+index 339614c..e80597a 100644
+--- a/security/smack/smack.h
++++ b/security/smack/smack.h
+@@ -53,6 +53,7 @@
+  */
+ struct smack_known {
+       struct list_head                list;
++      struct hlist_node               smk_hashed;
+       char                            *smk_known;
+       u32                             smk_secid;
+       struct netlbl_lsm_secattr       smk_netlabel;   /* on wire labels */
+@@ -222,6 +223,7 @@ char *smk_parse_smack(const char *string, int len);
+ int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int);
+ char *smk_import(const char *, int);
+ struct smack_known *smk_import_entry(const char *, int);
++void smk_insert_entry(struct smack_known *skp);
+ struct smack_known *smk_find_entry(const char *);
+ u32 smack_to_secid(const char *);
+@@ -247,6 +249,9 @@ extern struct list_head smk_netlbladdr_list;
+ extern struct security_operations smack_ops;
++#define SMACK_HASH_SLOTS 16
++extern struct hlist_head smack_known_hash[SMACK_HASH_SLOTS];
++
+ /*
+  * Is the directory transmuting?
+  */
+diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
+index 6a0377f..b3b59b1 100644
+--- a/security/smack/smack_access.c
++++ b/security/smack/smack_access.c
+@@ -325,6 +325,25 @@ void smack_log(char *subject_label, char *object_label, int request,
+ DEFINE_MUTEX(smack_known_lock);
++struct hlist_head smack_known_hash[SMACK_HASH_SLOTS];
++
++/**
++ * smk_insert_entry - insert a smack label into a hash map,
++ *
++ * this function must be called under smack_known_lock
++ */
++void smk_insert_entry(struct smack_known *skp)
++{
++      unsigned int hash;
++      struct hlist_head *head;
++
++      hash = full_name_hash(skp->smk_known, strlen(skp->smk_known));
++      head = &smack_known_hash[hash & (SMACK_HASH_SLOTS - 1)];
++
++      hlist_add_head_rcu(&skp->smk_hashed, head);
++      list_add_rcu(&skp->list, &smack_known_list);
++}
++
+ /**
+  * smk_find_entry - find a label on the list, return the list entry
+  * @string: a text string that might be a Smack label
+@@ -334,12 +353,16 @@ DEFINE_MUTEX(smack_known_lock);
+  */
+ struct smack_known *smk_find_entry(const char *string)
+ {
++      unsigned int hash;
++      struct hlist_head *head;
+       struct smack_known *skp;
+-      list_for_each_entry_rcu(skp, &smack_known_list, list) {
++      hash = full_name_hash(string, strlen(string));
++      head = &smack_known_hash[hash & (SMACK_HASH_SLOTS - 1)];
++
++      hlist_for_each_entry_rcu(skp, head, smk_hashed)
+               if (strcmp(skp->smk_known, string) == 0)
+                       return skp;
+-      }
+       return NULL;
+ }
+@@ -475,7 +498,7 @@ struct smack_known *smk_import_entry(const char *string, int len)
+                * Make sure that the entry is actually
+                * filled before putting it on the list.
+                */
+-              list_add_rcu(&skp->list, &smack_known_list);
++              smk_insert_entry(skp);
+               goto unlockout;
+       }
+       /*
+diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
+index a113a77..f70a0fa 100644
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -3876,12 +3876,12 @@ static __init void init_smack_known_list(void)
+       /*
+        * Create the known labels list
+        */
+-      list_add(&smack_known_huh.list, &smack_known_list);
+-      list_add(&smack_known_hat.list, &smack_known_list);
+-      list_add(&smack_known_star.list, &smack_known_list);
+-      list_add(&smack_known_floor.list, &smack_known_list);
+-      list_add(&smack_known_invalid.list, &smack_known_list);
+-      list_add(&smack_known_web.list, &smack_known_list);
++      smk_insert_entry(&smack_known_huh);
++      smk_insert_entry(&smack_known_hat);
++      smk_insert_entry(&smack_known_star);
++      smk_insert_entry(&smack_known_floor);
++      smk_insert_entry(&smack_known_invalid);
++      smk_insert_entry(&smack_known_web);
+ }
+ /**
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1052-Smack-network-label-match-fix.patch b/patches.tizen/1052-Smack-network-label-match-fix.patch
new file mode 100644 (file)
index 0000000..798504e
--- /dev/null
@@ -0,0 +1,116 @@
+From 5d10a57e98373f562c0f57b07ee0f265f785964e Mon Sep 17 00:00:00 2001
+From: Casey Schaufler <casey@schaufler-ca.com>
+Date: Fri, 28 Jun 2013 13:47:07 -0700
+Subject: [PATCH 1052/1302] Smack: network label match fix
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The Smack code that matches incoming CIPSO tags with Smack labels
+reaches through the NetLabel interfaces and compares the network
+data with the CIPSO header associated with a Smack label. This was
+done in a ill advised attempt to optimize performance. It works
+so long as the categories fit in a single capset, but this isn't
+always the case.
+
+This patch changes the Smack code to use the appropriate NetLabel
+interfaces to compare the incoming CIPSO header with the CIPSO
+header associated with a label. It will always match the CIPSO
+headers correctly.
+
+Targeted for git://git.gitorious.org/smack-next/kernel.git
+
+Change-Id: I22a2fd758b5a7764cbeb3ebf9f4dadd12d5b170b
+Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
+Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ security/smack/smack.h     |  8 ++++++--
+ security/smack/smack_lsm.c | 30 ++++++++++++++++++++++++------
+ security/smack/smackfs.c   |  2 +-
+ 3 files changed, 31 insertions(+), 9 deletions(-)
+
+diff --git a/security/smack/smack.h b/security/smack/smack.h
+index e80597a..076b8e8 100644
+--- a/security/smack/smack.h
++++ b/security/smack/smack.h
+@@ -168,9 +168,13 @@ struct smk_port_label {
+ #define SMACK_CIPSO_DOI_INVALID               -1      /* Not a DOI */
+ #define SMACK_CIPSO_DIRECT_DEFAULT    250     /* Arbitrary */
+ #define SMACK_CIPSO_MAPPED_DEFAULT    251     /* Also arbitrary */
+-#define SMACK_CIPSO_MAXCATVAL         63      /* Bigger gets harder */
+ #define SMACK_CIPSO_MAXLEVEL            255     /* CIPSO 2.2 standard */
+-#define SMACK_CIPSO_MAXCATNUM           239     /* CIPSO 2.2 standard */
++/*
++ * CIPSO 2.2 standard is 239, but Smack wants to use the
++ * categories in a structured way that limits the value to
++ * the bits in 23 bytes, hence the unusual number.
++ */
++#define SMACK_CIPSO_MAXCATNUM           184     /* 23 * 8 */
+ /*
+  * Flag for transmute access
+diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
+index f70a0fa..19de5e2 100644
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -3063,6 +3063,8 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
+ {
+       struct smack_known *skp;
+       int found = 0;
++      int acat;
++      int kcat;
+       if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) {
+               /*
+@@ -3079,12 +3081,28 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
+               list_for_each_entry(skp, &smack_known_list, list) {
+                       if (sap->attr.mls.lvl != skp->smk_netlabel.attr.mls.lvl)
+                               continue;
+-                      if (memcmp(sap->attr.mls.cat,
+-                              skp->smk_netlabel.attr.mls.cat,
+-                              SMK_CIPSOLEN) != 0)
+-                              continue;
+-                      found = 1;
+-                      break;
++                      /*
++                       * Compare the catsets. Use the netlbl APIs.
++                       */
++                      if ((sap->flags & NETLBL_SECATTR_MLS_CAT) == 0) {
++                              if ((skp->smk_netlabel.flags &
++                                   NETLBL_SECATTR_MLS_CAT) == 0)
++                                      found = 1;
++                              break;
++                      }
++                      for (acat = -1, kcat = -1; acat == kcat; ) {
++                              acat = netlbl_secattr_catmap_walk(
++                                      sap->attr.mls.cat, acat + 1);
++                              kcat = netlbl_secattr_catmap_walk(
++                                      skp->smk_netlabel.attr.mls.cat,
++                                      kcat + 1);
++                              if (acat < 0 || kcat < 0)
++                                      break;
++                      }
++                      if (acat == kcat) {
++                              found = 1;
++                              break;
++                      }
+               }
+               rcu_read_unlock();
+diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
+index 269b270..a07e93f 100644
+--- a/security/smack/smackfs.c
++++ b/security/smack/smackfs.c
+@@ -890,7 +890,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
+       for (i = 0; i < catlen; i++) {
+               rule += SMK_DIGITLEN;
+               ret = sscanf(rule, "%u", &cat);
+-              if (ret != 1 || cat > SMACK_CIPSO_MAXCATVAL)
++              if (ret != 1 || cat > SMACK_CIPSO_MAXCATNUM)
+                       goto out;
+               smack_catset_bit(cat, mapcatset);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1053-Smack-IPv6-casting-error-fix-for-3.11.patch b/patches.tizen/1053-Smack-IPv6-casting-error-fix-for-3.11.patch
new file mode 100644 (file)
index 0000000..9bec148
--- /dev/null
@@ -0,0 +1,111 @@
+From 9b27db2d839e7aabe7d60f8ff6198ffa195b475d Mon Sep 17 00:00:00 2001
+From: Casey Schaufler <casey@schaufler-ca.com>
+Date: Mon, 5 Aug 2013 13:21:22 -0700
+Subject: [PATCH 1053/1302] Smack: IPv6 casting error fix for 3.11
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The original implementation of the Smack IPv6 port based
+local controls works most of the time using a sockaddr as
+a temporary variable, but not always as it overflows in
+some circumstances. The correct data is a sockaddr_in6.
+A struct sockaddr isn't as large as a struct sockaddr_in6.
+There would need to be casting one way or the other. This
+patch gets it the right way.
+
+Change-Id: Iac627fa0ddb77e3ff4b8c9c81bd838141a5638e9
+Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
+Signed-off-by: James Morris <james.l.morris@oracle.com>
+Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ security/smack/smack_lsm.c | 24 +++++++++++-------------
+ 1 file changed, 11 insertions(+), 13 deletions(-)
+
+diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
+index 19de5e2..8825375 100644
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -1995,12 +1995,11 @@ static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address)
+  *
+  * Create or update the port list entry
+  */
+-static int smk_ipv6_port_check(struct sock *sk, struct sockaddr *address,
++static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
+                               int act)
+ {
+       __be16 *bep;
+       __be32 *be32p;
+-      struct sockaddr_in6 *addr6;
+       struct smk_port_label *spp;
+       struct socket_smack *ssp = sk->sk_security;
+       struct smack_known *skp;
+@@ -2022,10 +2021,9 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr *address,
+       /*
+        * Get the IP address and port from the address.
+        */
+-      addr6 = (struct sockaddr_in6 *)address;
+-      port = ntohs(addr6->sin6_port);
+-      bep = (__be16 *)(&addr6->sin6_addr);
+-      be32p = (__be32 *)(&addr6->sin6_addr);
++      port = ntohs(address->sin6_port);
++      bep = (__be16 *)(&address->sin6_addr);
++      be32p = (__be32 *)(&address->sin6_addr);
+       /*
+        * It's remote, so port lookup does no good.
+@@ -2057,9 +2055,9 @@ auditout:
+       ad.a.u.net->family = sk->sk_family;
+       ad.a.u.net->dport = port;
+       if (act == SMK_RECEIVING)
+-              ad.a.u.net->v6info.saddr = addr6->sin6_addr;
++              ad.a.u.net->v6info.saddr = address->sin6_addr;
+       else
+-              ad.a.u.net->v6info.daddr = addr6->sin6_addr;
++              ad.a.u.net->v6info.daddr = address->sin6_addr;
+ #endif
+       return smk_access(skp, object, MAY_WRITE, &ad);
+ }
+@@ -2198,7 +2196,8 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
+       case PF_INET6:
+               if (addrlen < sizeof(struct sockaddr_in6))
+                       return -EINVAL;
+-              rc = smk_ipv6_port_check(sock->sk, sap, SMK_CONNECTING);
++              rc = smk_ipv6_port_check(sock->sk, (struct sockaddr_in6 *)sap,
++                                              SMK_CONNECTING);
+               break;
+       }
+       return rc;
+@@ -3031,7 +3030,7 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
+                               int size)
+ {
+       struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name;
+-      struct sockaddr *sap = (struct sockaddr *) msg->msg_name;
++      struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name;
+       int rc = 0;
+       /*
+@@ -3136,9 +3135,8 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
+       return smack_net_ambient;
+ }
+-static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr *sap)
++static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip)
+ {
+-      struct sockaddr_in6 *sip = (struct sockaddr_in6 *)sap;
+       u8 nexthdr;
+       int offset;
+       int proto = -EINVAL;
+@@ -3196,7 +3194,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
+       struct netlbl_lsm_secattr secattr;
+       struct socket_smack *ssp = sk->sk_security;
+       struct smack_known *skp;
+-      struct sockaddr sadd;
++      struct sockaddr_in6 sadd;
+       int rc = 0;
+       struct smk_audit_info ad;
+ #ifdef CONFIG_AUDIT
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1054-Smack-parse-multiple-rules-per-write-to-load2-up-to-.patch b/patches.tizen/1054-Smack-parse-multiple-rules-per-write-to-load2-up-to-.patch
new file mode 100644 (file)
index 0000000..ba6444a
--- /dev/null
@@ -0,0 +1,258 @@
+From d2e0d1c07d510529e97b544bb007ff06cf1669e4 Mon Sep 17 00:00:00 2001
+From: Rafal Krypa <r.krypa@samsung.com>
+Date: Fri, 9 Aug 2013 11:47:07 +0200
+Subject: [PATCH 1054/1302] Smack: parse multiple rules per write to load2, up
+ to PAGE_SIZE-1 bytes
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Smack interface for loading rules has always parsed only single rule from
+data written to it. This requires user program to call one write() per
+each rule it wants to load.
+This change makes it possible to write multiple rules, separated by new
+line character. Smack will load at most PAGE_SIZE-1 characters and properly
+return number of processed bytes. In case when user buffer is larger, it
+will be additionally truncated. All characters after last \n will not get
+parsed to avoid partial rule near input buffer boundary.
+
+Change-Id: I81766925a9522fcb811fe3046850cdc45067838a
+Signed-off-by: Rafal Krypa <r.krypa@samsung.com>
+Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ security/smack/smackfs.c | 167 +++++++++++++++++++++++------------------------
+ 1 file changed, 82 insertions(+), 85 deletions(-)
+
+diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
+index a07e93f..80f4b4a 100644
+--- a/security/smack/smackfs.c
++++ b/security/smack/smackfs.c
+@@ -368,56 +368,43 @@ static int smk_parse_rule(const char *data, struct smack_parsed_rule *rule,
+  * @data: string to be parsed, null terminated
+  * @rule: Will be filled with Smack parsed rule
+  * @import: if non-zero, import labels
+- * @change: if non-zero, data is from /smack/change-rule
++ * @tokens: numer of substrings expected in data
+  *
+- * Returns 0 on success, -1 on failure
++ * Returns number of processed bytes on success, -1 on failure.
+  */
+-static int smk_parse_long_rule(const char *data, struct smack_parsed_rule *rule,
+-                              int import, int change)
++static ssize_t smk_parse_long_rule(char *data, struct smack_parsed_rule *rule,
++                              int import, int tokens)
+ {
+-      char *subject;
+-      char *object;
+-      char *access1;
+-      char *access2;
+-      int datalen;
+-      int rc = -1;
++      ssize_t cnt = 0;
++      char *tok[4];
++      int i;
+-      /* This is inefficient */
+-      datalen = strlen(data);
++      /*
++       * Parsing the rule in-place, filling all white-spaces with '\0'
++       */
++      for (i = 0; i < tokens; ++i) {
++              while (isspace(data[cnt]))
++                      data[cnt++] = '\0';
+-      /* Our first element can be 64 + \0 with no spaces */
+-      subject = kzalloc(datalen + 1, GFP_KERNEL);
+-      if (subject == NULL)
+-              return -1;
+-      object = kzalloc(datalen, GFP_KERNEL);
+-      if (object == NULL)
+-              goto free_out_s;
+-      access1 = kzalloc(datalen, GFP_KERNEL);
+-      if (access1 == NULL)
+-              goto free_out_o;
+-      access2 = kzalloc(datalen, GFP_KERNEL);
+-      if (access2 == NULL)
+-              goto free_out_a;
+-
+-      if (change) {
+-              if (sscanf(data, "%s %s %s %s",
+-                      subject, object, access1, access2) == 4)
+-                      rc = smk_fill_rule(subject, object, access1, access2,
+-                              rule, import, 0);
+-      } else {
+-              if (sscanf(data, "%s %s %s", subject, object, access1) == 3)
+-                      rc = smk_fill_rule(subject, object, access1, NULL,
+-                              rule, import, 0);
++              if (data[cnt] == '\0')
++                      /* Unexpected end of data */
++                      return -1;
++
++              tok[i] = data + cnt;
++
++              while (data[cnt] && !isspace(data[cnt]))
++                      ++cnt;
+       }
++      while (isspace(data[cnt]))
++              data[cnt++] = '\0';
+-      kfree(access2);
+-free_out_a:
+-      kfree(access1);
+-free_out_o:
+-      kfree(object);
+-free_out_s:
+-      kfree(subject);
+-      return rc;
++      while (i < 4)
++              tok[i++] = NULL;
++
++      if (smk_fill_rule(tok[0], tok[1], tok[2], tok[3], rule, import, 0))
++              return -1;
++
++      return cnt;
+ }
+ #define SMK_FIXED24_FMT       0       /* Fixed 24byte label format */
+@@ -449,9 +436,10 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
+ {
+       struct smack_parsed_rule rule;
+       char *data;
+-      int datalen;
+-      int rc = -EINVAL;
+-      int load = 0;
++      int rc;
++      int trunc = 0;
++      int tokens;
++      ssize_t cnt = 0;
+       /*
+        * No partial writes.
+@@ -466,11 +454,14 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
+                */
+               if (count != SMK_OLOADLEN && count != SMK_LOADLEN)
+                       return -EINVAL;
+-              datalen = SMK_LOADLEN;
+-      } else
+-              datalen = count + 1;
++      } else {
++              if (count >= PAGE_SIZE) {
++                      count = PAGE_SIZE - 1;
++                      trunc = 1;
++              }
++      }
+-      data = kzalloc(datalen, GFP_KERNEL);
++      data = kmalloc(count + 1, GFP_KERNEL);
+       if (data == NULL)
+               return -ENOMEM;
+@@ -479,36 +470,49 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
+               goto out;
+       }
+-      if (format == SMK_LONG_FMT) {
+-              /*
+-               * Be sure the data string is terminated.
+-               */
+-              data[count] = '\0';
+-              if (smk_parse_long_rule(data, &rule, 1, 0))
+-                      goto out;
+-      } else if (format == SMK_CHANGE_FMT) {
+-              data[count] = '\0';
+-              if (smk_parse_long_rule(data, &rule, 1, 1))
+-                      goto out;
+-      } else {
+-              /*
+-               * More on the minor hack for backward compatibility
+-               */
+-              if (count == (SMK_OLOADLEN))
+-                      data[SMK_OLOADLEN] = '-';
+-              if (smk_parse_rule(data, &rule, 1))
++      /*
++       * In case of parsing only part of user buf,
++       * avoid having partial rule at the data buffer
++       */
++      if (trunc) {
++              while (count > 0 && (data[count - 1] != '\n'))
++                      --count;
++              if (count == 0) {
++                      rc = -EINVAL;
+                       goto out;
++              }
+       }
+-      if (rule_list == NULL) {
+-              load = 1;
+-              rule_list = &rule.smk_subject->smk_rules;
+-              rule_lock = &rule.smk_subject->smk_rules_lock;
++      data[count] = '\0';
++      tokens = (format == SMK_CHANGE_FMT ? 4 : 3);
++      while (cnt < count) {
++              if (format == SMK_FIXED24_FMT) {
++                      rc = smk_parse_rule(data, &rule, 1);
++                      if (rc != 0) {
++                              rc = -EINVAL;
++                              goto out;
++                      }
++                      cnt = count;
++              } else {
++                      rc = smk_parse_long_rule(data + cnt, &rule, 1, tokens);
++                      if (rc <= 0) {
++                              rc = -EINVAL;
++                              goto out;
++                      }
++                      cnt += rc;
++              }
++
++              if (rule_list == NULL)
++                      rc = smk_set_access(&rule, &rule.smk_subject->smk_rules,
++                              &rule.smk_subject->smk_rules_lock, 1);
++              else
++                      rc = smk_set_access(&rule, rule_list, rule_lock, 0);
++
++              if (rc)
++                      goto out;
+       }
+-      rc = smk_set_access(&rule, rule_list, rule_lock, load);
+-      if (rc == 0)
+-              rc = count;
++      rc = cnt;
+ out:
+       kfree(data);
+       return rc;
+@@ -1829,7 +1833,6 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf,
+ {
+       struct smack_parsed_rule rule;
+       char *data;
+-      char *cod;
+       int res;
+       data = simple_transaction_get(file, buf, count);
+@@ -1842,18 +1845,12 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf,
+               res = smk_parse_rule(data, &rule, 0);
+       } else {
+               /*
+-               * Copy the data to make sure the string is terminated.
++               * simple_transaction_get() returns null-terminated data
+                */
+-              cod = kzalloc(count + 1, GFP_KERNEL);
+-              if (cod == NULL)
+-                      return -ENOMEM;
+-              memcpy(cod, data, count);
+-              cod[count] = '\0';
+-              res = smk_parse_long_rule(cod, &rule, 0, 0);
+-              kfree(cod);
++              res = smk_parse_long_rule(data, &rule, 0, 3);
+       }
+-      if (res)
++      if (res < 0)
+               return -EINVAL;
+       res = smk_access(rule.smk_subject, rule.smk_object,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1055-Smack-Implement-lock-security-mode.patch b/patches.tizen/1055-Smack-Implement-lock-security-mode.patch
new file mode 100644 (file)
index 0000000..22734f5
--- /dev/null
@@ -0,0 +1,195 @@
+From 96c833ab84c190078efd6b24d9bb6ee6514d2d02 Mon Sep 17 00:00:00 2001
+From: Casey Schaufler <casey@schaufler-ca.com>
+Date: Fri, 11 Oct 2013 18:06:39 -0700
+Subject: [PATCH 1055/1302] Smack: Implement lock security mode
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Linux file locking does not follow the same rules
+as other mechanisms. Even though it is a write operation
+a process can set a read lock on files which it has open
+only for read access. Two programs with read access to
+a file can use read locks to communicate.
+
+This is not acceptable in a Mandatory Access Control
+environment. Smack treats setting a read lock as the
+write operation that it is. Unfortunately, many programs
+assume that setting a read lock is a read operation.
+These programs are unhappy in the Smack environment.
+
+This patch introduces a new access mode (lock) to address
+this problem. A process with lock access to a file can
+set a read lock. A process with write access to a file can
+set a read lock or a write lock. This prevents a situation
+where processes are granted write access just so they can
+set read locks.
+
+Targeted for git://git.gitorious.org/smack-next/kernel.git
+
+Change-Id: I9bf4df25088d2dd49aadfa0ced844b147ad1c81d
+Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
+Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ security/smack/smack.h        | 12 ++++++++----
+ security/smack/smack_access.c | 10 ++++++++++
+ security/smack/smack_lsm.c    |  9 +++++++--
+ security/smack/smackfs.c      | 10 ++++++++--
+ 4 files changed, 33 insertions(+), 8 deletions(-)
+
+diff --git a/security/smack/smack.h b/security/smack/smack.h
+index 076b8e8..364cc64 100644
+--- a/security/smack/smack.h
++++ b/security/smack/smack.h
+@@ -177,9 +177,13 @@ struct smk_port_label {
+ #define SMACK_CIPSO_MAXCATNUM           184     /* 23 * 8 */
+ /*
+- * Flag for transmute access
++ * Flags for untraditional access modes.
++ * It shouldn't be necessary to avoid conflicts with definitions
++ * in fs.h, but do so anyway.
+  */
+-#define MAY_TRANSMUTE 64
++#define MAY_TRANSMUTE 0x00001000      /* Controls directory labeling */
++#define MAY_LOCK      0x00002000      /* Locks should be writes, but ... */
++
+ /*
+  * Just to make the common cases easier to deal with
+  */
+@@ -188,9 +192,9 @@ struct smk_port_label {
+ #define MAY_NOT               0
+ /*
+- * Number of access types used by Smack (rwxat)
++ * Number of access types used by Smack (rwxatl)
+  */
+-#define SMK_NUM_ACCESS_TYPE 5
++#define SMK_NUM_ACCESS_TYPE 6
+ /* SMACK data */
+ struct smack_audit_data {
+diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
+index b3b59b1..14293cd 100644
+--- a/security/smack/smack_access.c
++++ b/security/smack/smack_access.c
+@@ -84,6 +84,8 @@ int log_policy = SMACK_AUDIT_DENIED;
+  *
+  * Do the object check first because that is more
+  * likely to differ.
++ *
++ * Allowing write access implies allowing locking.
+  */
+ int smk_access_entry(char *subject_label, char *object_label,
+                       struct list_head *rule_list)
+@@ -99,6 +101,11 @@ int smk_access_entry(char *subject_label, char *object_label,
+               }
+       }
++      /*
++       * MAY_WRITE implies MAY_LOCK.
++       */
++      if ((may & MAY_WRITE) == MAY_WRITE)
++              may |= MAY_LOCK;
+       return may;
+ }
+@@ -245,6 +252,7 @@ out_audit:
+ static inline void smack_str_from_perm(char *string, int access)
+ {
+       int i = 0;
++
+       if (access & MAY_READ)
+               string[i++] = 'r';
+       if (access & MAY_WRITE)
+@@ -255,6 +263,8 @@ static inline void smack_str_from_perm(char *string, int access)
+               string[i++] = 'a';
+       if (access & MAY_TRANSMUTE)
+               string[i++] = 't';
++      if (access & MAY_LOCK)
++              string[i++] = 'l';
+       string[i] = '\0';
+ }
+ /**
+diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
+index 8825375..88d366e5 100644
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -1146,7 +1146,7 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd,
+  * @file: the object
+  * @cmd: unused
+  *
+- * Returns 0 if current has write access, error code otherwise
++ * Returns 0 if current has lock access, error code otherwise
+  */
+ static int smack_file_lock(struct file *file, unsigned int cmd)
+ {
+@@ -1154,7 +1154,7 @@ static int smack_file_lock(struct file *file, unsigned int cmd)
+       smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
+       smk_ad_setfield_u_fs_path(&ad, file->f_path);
+-      return smk_curacc(file->f_security, MAY_WRITE, &ad);
++      return smk_curacc(file->f_security, MAY_LOCK, &ad);
+ }
+ /**
+@@ -1178,8 +1178,13 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd,
+       switch (cmd) {
+       case F_GETLK:
++              break;
+       case F_SETLK:
+       case F_SETLKW:
++              smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
++              smk_ad_setfield_u_fs_path(&ad, file->f_path);
++              rc = smk_curacc(file->f_security, MAY_LOCK, &ad);
++              break;
+       case F_SETOWN:
+       case F_SETSIG:
+               smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
+diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
+index 80f4b4a..160aa08 100644
+--- a/security/smack/smackfs.c
++++ b/security/smack/smackfs.c
+@@ -139,7 +139,7 @@ const char *smack_cipso_option = SMACK_CIPSO_OPTION;
+  * SMK_LOADLEN: Smack rule length
+  */
+ #define SMK_OACCESS   "rwxa"
+-#define SMK_ACCESS    "rwxat"
++#define SMK_ACCESS    "rwxatl"
+ #define SMK_OACCESSLEN        (sizeof(SMK_OACCESS) - 1)
+ #define SMK_ACCESSLEN (sizeof(SMK_ACCESS) - 1)
+ #define SMK_OLOADLEN  (SMK_LABELLEN + SMK_LABELLEN + SMK_OACCESSLEN)
+@@ -282,6 +282,10 @@ static int smk_perm_from_str(const char *string)
+               case 'T':
+                       perm |= MAY_TRANSMUTE;
+                       break;
++              case 'l':
++              case 'L':
++                      perm |= MAY_LOCK;
++                      break;
+               default:
+                       return perm;
+               }
+@@ -452,7 +456,7 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
+               /*
+                * Minor hack for backward compatibility
+                */
+-              if (count != SMK_OLOADLEN && count != SMK_LOADLEN)
++              if (count < SMK_OLOADLEN || count > SMK_LOADLEN)
+                       return -EINVAL;
+       } else {
+               if (count >= PAGE_SIZE) {
+@@ -592,6 +596,8 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max)
+               seq_putc(s, 'a');
+       if (srp->smk_access & MAY_TRANSMUTE)
+               seq_putc(s, 't');
++      if (srp->smk_access & MAY_LOCK)
++              seq_putc(s, 'l');
+       seq_putc(s, '\n');
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1056-Smack-Ptrace-access-check-mode.patch b/patches.tizen/1056-Smack-Ptrace-access-check-mode.patch
new file mode 100644 (file)
index 0000000..040816a
--- /dev/null
@@ -0,0 +1,40 @@
+From dfb6577817caddd151dda1c4a3be2d2b314fba57 Mon Sep 17 00:00:00 2001
+From: Casey Schaufler <casey@schaufler-ca.com>
+Date: Tue, 22 Oct 2013 11:47:45 -0700
+Subject: [PATCH 1056/1302] Smack: Ptrace access check mode
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When the ptrace security hooks were split the addition of
+a mode parameter was not taken advantage of in the Smack
+ptrace access check. This changes the access check from
+always looking for read and write access to using the
+passed mode. This will make use of /proc much happier.
+
+Targeted for git://git.gitorious.org/smack-next/kernel.git
+
+Change-Id: I979f36da1b26d0fba5d73744f340422aaae5cc74
+Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
+Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ security/smack/smack_lsm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
+index 88d366e5..b0be893 100644
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -185,7 +185,7 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
+       smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
+       smk_ad_setfield_u_tsk(&ad, ctp);
+-      rc = smk_curacc(skp->smk_known, MAY_READWRITE, &ad);
++      rc = smk_curacc(skp->smk_known, mode, &ad);
+       return rc;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1057-Smack-Cgroup-filesystem-access.patch b/patches.tizen/1057-Smack-Cgroup-filesystem-access.patch
new file mode 100644 (file)
index 0000000..1e84788
--- /dev/null
@@ -0,0 +1,86 @@
+From c25bbcf39c1c3a2ce9aaea532f4ba51bf00d48c4 Mon Sep 17 00:00:00 2001
+From: Casey Schaufler <casey@schaufler-ca.com>
+Date: Thu, 21 Nov 2013 10:55:10 +0200
+Subject: [PATCH 1057/1302] Smack: Cgroup filesystem access
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The cgroup filesystems are not mounted using conventional
+mechanisms. This prevents the use of mount options to
+set Smack attributes. This patch makes the behavior
+of cgroup filesystems compatable with the way systemd
+uses them.
+
+Change-Id: I1e0429f133db9e14117dc754d682dec08221354c
+Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
+Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
+Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ security/smack/smack_lsm.c | 30 ++++++++++++++++++------------
+ 1 file changed, 18 insertions(+), 12 deletions(-)
+
+diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
+index b0be893..3f01cf5 100644
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -2726,6 +2726,15 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
+        * of the superblock.
+        */
+       if (opt_dentry->d_parent == opt_dentry) {
++              if (sbp->s_magic == CGROUP_SUPER_MAGIC) {
++                      /*
++                       * The cgroup filesystem is never mounted,
++                       * so there's no opportunity to set the mount
++                       * options.
++                       */
++                      sbsp->smk_root = smack_known_star.smk_known;
++                      sbsp->smk_default = smack_known_star.smk_known;
++              }
+               isp->smk_inode = sbsp->smk_root;
+               isp->smk_flags |= SMK_INODE_INSTANT;
+               goto unlockandout;
+@@ -2739,16 +2748,20 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
+        */
+       switch (sbp->s_magic) {
+       case SMACK_MAGIC:
++      case PIPEFS_MAGIC:
++      case SOCKFS_MAGIC:
++      case CGROUP_SUPER_MAGIC:
+               /*
+                * Casey says that it's a little embarrassing
+                * that the smack file system doesn't do
+                * extended attributes.
+-               */
+-              final = smack_known_star.smk_known;
+-              break;
+-      case PIPEFS_MAGIC:
+-              /*
++               *
+                * Casey says pipes are easy (?)
++               *
++               * Socket access is controlled by the socket
++               * structures associated with the task involved.
++               *
++               * Cgroupfs is special
+                */
+               final = smack_known_star.smk_known;
+               break;
+@@ -2760,13 +2773,6 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
+                */
+               final = ckp->smk_known;
+               break;
+-      case SOCKFS_MAGIC:
+-              /*
+-               * Socket access is controlled by the socket
+-               * structures associated with the task involved.
+-               */
+-              final = smack_known_star.smk_known;
+-              break;
+       case PROC_SUPER_MAGIC:
+               /*
+                * Casey says procfs appears not to care.
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1058-linux-kernel-and-linux-kernel-modules-ABI-tools.patch b/patches.tizen/1058-linux-kernel-and-linux-kernel-modules-ABI-tools.patch
new file mode 100644 (file)
index 0000000..80b4a4e
--- /dev/null
@@ -0,0 +1,8302 @@
+From 23b22df7b6b7d91e7c1866dc760c2586ba161c43 Mon Sep 17 00:00:00 2001
+From: Jacek Pielaszkiewicz <j.pielaszkie@samsung.com>
+Date: Mon, 9 Dec 2013 13:37:39 +0100
+Subject: [PATCH 1058/1302] linux-kernel and linux kernel modules ABI tools.
+
+The following changes have been implemented:
+    1. A new tool "abi-checker" has been created. The tool allows:
+       - compare two Module.symvers files.
+       - reports which symbols are new, changed or have been removed.
+       - create dump all kernel symbols that are present in external kernel
+         module.
+
+    2. linux-3.10.spec has been updated to check changes in kernel ABI/API.
+       In case if any change kernel installation process aborts. In such case
+       user is requested to update kernel version and update ABI dump file.
+       ABI dump file should be located in "abi-checker/data" directory.
+
+    3. Output rpm with uImage has been extended by ABI dump. Default location for
+       the file is /boot/abi/_kernel_version_.
+
+    4. New output rpm package is build - "abi-tools". The package delivers ABI-checker.
+       By default the rpm install ABI-checker tool into /usr/local/bin directory.
+
+Change-Id: I37a2a52f64fde915cff24aa85349aa1dbee3a5b8
+Signed-off-by: Jacek Pielaszkiewicz <j.pielaszkie@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ abi-checker/data/abi_3.10.19_1              | 6900 +++++++++++++++++++++++++++
+ abi-checker/src/Makefile                    |   31 +
+ abi-checker/src/build_api_kernel_checker.sh |   24 +
+ abi-checker/src/kernel_abi_checker.c        |  834 ++++
+ abi-checker/src/kernel_abi_checker.h        |   62 +
+ abi-checker/src/kernel_abi_checker_elf.c    |  172 +
+ packaging/linux-kernel.spec                 |  125 +-
+ 7 files changed, 8129 insertions(+), 19 deletions(-)
+ create mode 100644 abi-checker/data/abi_3.10.19_1
+ create mode 100644 abi-checker/src/Makefile
+ create mode 100755 abi-checker/src/build_api_kernel_checker.sh
+ create mode 100644 abi-checker/src/kernel_abi_checker.c
+ create mode 100644 abi-checker/src/kernel_abi_checker.h
+ create mode 100644 abi-checker/src/kernel_abi_checker_elf.c
+
+diff --git a/abi-checker/data/abi_3.10.19_1 b/abi-checker/data/abi_3.10.19_1
+new file mode 100644
+index 0000000..eea3455
+--- /dev/null
++++ b/abi-checker/data/abi_3.10.19_1
+@@ -0,0 +1,6900 @@
++0x80e54114    cfg80211_send_rx_assoc  vmlinux EXPORT_SYMBOL
++0xd4dd4a5f    ipv6_chk_custom_prefix  vmlinux EXPORT_SYMBOL
++0x765592d7    generic_file_splice_write       vmlinux EXPORT_SYMBOL
++0x74f78b5f    set_anon_super  vmlinux EXPORT_SYMBOL
++0x88ea56ef    kmem_cache_alloc        vmlinux EXPORT_SYMBOL
++0x149d22ae    replace_page_cache_page vmlinux EXPORT_SYMBOL_GPL
++0x70523a7a    __cond_resched_softirq  vmlinux EXPORT_SYMBOL
++0x55417264    unregister_vt_notifier  vmlinux EXPORT_SYMBOL_GPL
++0xc2ea8e64    snd_soc_platform_read   vmlinux EXPORT_SYMBOL_GPL
++0x0a2487e0    unblock_all_signals     vmlinux EXPORT_SYMBOL
++0x260cf8f8    of_get_property vmlinux EXPORT_SYMBOL
++0x6ac315b3    v4l2_m2m_ioctl_dqbuf    vmlinux EXPORT_SYMBOL_GPL
++0x5c421d9d    i2c_put_adapter vmlinux EXPORT_SYMBOL
++0x4d8e0b9c    rtc_class_open  vmlinux EXPORT_SYMBOL_GPL
++0x96cd2b04    scsi_sense_key_string   vmlinux EXPORT_SYMBOL
++0xedf10a85    request_firmware        vmlinux EXPORT_SYMBOL
++0x70230d35    __hci_cmd_sync  vmlinux EXPORT_SYMBOL
++0x79dc2bec    dev_uc_sync     vmlinux EXPORT_SYMBOL
++0xeb396e95    dev_mc_sync     vmlinux EXPORT_SYMBOL
++0x80ca5026    _bin2bcd        vmlinux EXPORT_SYMBOL
++0xfbaaf01e    console_lock    vmlinux EXPORT_SYMBOL
++0xdf5311f6    hwmon_device_unregister vmlinux EXPORT_SYMBOL_GPL
++0xe113bbbc    csum_partial    vmlinux EXPORT_SYMBOL
++0x1ef4f43e    cfg80211_wext_siwscan   vmlinux EXPORT_SYMBOL_GPL
++0xb343d54f    cfg80211_wext_giwscan   vmlinux EXPORT_SYMBOL_GPL
++0xc068440e    __kfifo_alloc   vmlinux EXPORT_SYMBOL
++0x376eb932    kmap_atomic     vmlinux EXPORT_SYMBOL
++0xaadff4e7    nf_log_register vmlinux EXPORT_SYMBOL
++0xc8276a79    nf_hooks_needed vmlinux EXPORT_SYMBOL
++0x1b17e06c    kstrtoll        vmlinux EXPORT_SYMBOL
++0xa7d57242    scsi_execute    vmlinux EXPORT_SYMBOL
++0x9b757ebd    raw_seq_open    vmlinux EXPORT_SYMBOL_GPL
++0x1b479d00    snd_soc_of_parse_audio_routing  vmlinux EXPORT_SYMBOL_GPL
++0x3b2785b0    crypto_hash_walk_done   vmlinux EXPORT_SYMBOL_GPL
++0xa1d55e90    _raw_spin_lock_bh       vmlinux EXPORT_SYMBOL
++0xdd391eff    profile_event_unregister        vmlinux EXPORT_SYMBOL_GPL
++0xa724257f    init_uts_ns     vmlinux EXPORT_SYMBOL_GPL
++0xc97d1140    cpufreq_cooling_get_level       vmlinux EXPORT_SYMBOL_GPL
++0x5898fd79    device_add      vmlinux EXPORT_SYMBOL_GPL
++0x5081d0b3    device_del      vmlinux EXPORT_SYMBOL_GPL
++0x37246b6e    __inet6_hash    vmlinux EXPORT_SYMBOL
++0xad3a5766    dst_release     vmlinux EXPORT_SYMBOL
++0x1e254a30    sock_no_mmap    vmlinux EXPORT_SYMBOL
++0x854e1c0b    sg_nents        vmlinux EXPORT_SYMBOL
++0xb4c753a2    disk_map_sector_rcu     vmlinux EXPORT_SYMBOL_GPL
++0x942da6f0    sysfs_update_group      vmlinux EXPORT_SYMBOL_GPL
++0xa38602cd    drain_workqueue vmlinux EXPORT_SYMBOL_GPL
++0xd4b5f202    led_trigger_store       vmlinux EXPORT_SYMBOL_GPL
++0x80104269    tcp_initialize_rcv_mss  vmlinux EXPORT_SYMBOL
++0x54e6fcdd    net_enable_timestamp    vmlinux EXPORT_SYMBOL
++0xeb32f5c3    sockfd_lookup   vmlinux EXPORT_SYMBOL
++0x02aa8f04    snd_soc_dapm_get_pin_switch     vmlinux EXPORT_SYMBOL_GPL
++0x762265ad    snd_soc_dapm_put_pin_switch     vmlinux EXPORT_SYMBOL_GPL
++0xb0ffda2f    blk_limits_max_hw_sectors       vmlinux EXPORT_SYMBOL
++0x7cd8695d    directly_mappable_cdev_bdi      vmlinux EXPORT_SYMBOL
++0x6bc3fbc0    __unregister_chrdev     vmlinux EXPORT_SYMBOL
++0x6bb86c7d    srcu_notifier_chain_register    vmlinux EXPORT_SYMBOL_GPL
++0x4b661f3f    v4l2_ctrl_grab  vmlinux EXPORT_SYMBOL
++0xd2bbf775    fb_validate_mode        vmlinux EXPORT_SYMBOL
++0xe8d75b12    nfc_target_lost vmlinux EXPORT_SYMBOL
++0xb2d299a9    dev_graft_qdisc vmlinux EXPORT_SYMBOL
++0xa851973a    raw_notifier_call_chain vmlinux EXPORT_SYMBOL_GPL
++0x138709ec    scsi_get_command        vmlinux EXPORT_SYMBOL
++0x174afb1a    __sg_page_iter_next     vmlinux EXPORT_SYMBOL
++0x30cada8f    radix_tree_next_hole    vmlinux EXPORT_SYMBOL
++0xc0412578    scsi_target_quiesce     vmlinux EXPORT_SYMBOL
++0xd7a5d2f8    transport_class_register        vmlinux EXPORT_SYMBOL_GPL
++0xd2335101    drm_fb_get_bpp_depth    vmlinux EXPORT_SYMBOL
++0xa9a33fdf    jbd2_journal_try_to_free_buffers        vmlinux EXPORT_SYMBOL
++0xffd5a395    default_wake_function   vmlinux EXPORT_SYMBOL
++0xd6cb49e3    dm_put_device   vmlinux EXPORT_SYMBOL
++0xb6e1e07d    dm_get_device   vmlinux EXPORT_SYMBOL
++0x1f9218e9    input_handler_for_each_handle   vmlinux EXPORT_SYMBOL
++0x560c6863    transport_class_unregister      vmlinux EXPORT_SYMBOL_GPL
++0x65f3ad9a    fb_videomode_to_var     vmlinux EXPORT_SYMBOL
++0x79ad634c    nfc_hci_send_cmd_async  vmlinux EXPORT_SYMBOL
++0x6bbf9530    mount_subtree   vmlinux EXPORT_SYMBOL
++0x8f22ce41    iget_locked     vmlinux EXPORT_SYMBOL
++0x6fba7c75    sdhci_runtime_suspend_host      vmlinux EXPORT_SYMBOL_GPL
++0x7f923f2a    v4l2_of_parse_endpoint  vmlinux EXPORT_SYMBOL
++0xaa2d0ca7    input_mt_assign_slots   vmlinux EXPORT_SYMBOL
++0x167fd723    drm_mm_clean    vmlinux EXPORT_SYMBOL
++0x9733c21d    sock_get_timestampns    vmlinux EXPORT_SYMBOL
++0xf42e571f    snd_soc_dapm_put_enum_virt      vmlinux EXPORT_SYMBOL_GPL
++0xcd16649c    snd_soc_dapm_get_enum_virt      vmlinux EXPORT_SYMBOL_GPL
++0x38cb130f    iommu_group_add_device  vmlinux EXPORT_SYMBOL_GPL
++0xe90d597e    class_interface_register        vmlinux EXPORT_SYMBOL_GPL
++0x49ebacbd    _clear_bit      vmlinux EXPORT_SYMBOL
++0x853b6dce    nfc_tm_activated        vmlinux EXPORT_SYMBOL
++0xc617f82c    unregister_oom_notifier vmlinux EXPORT_SYMBOL_GPL
++0x8da9fa20    spi_get_device_id       vmlinux EXPORT_SYMBOL_GPL
++0x882f44c1    class_interface_unregister      vmlinux EXPORT_SYMBOL_GPL
++0x03757c9b    of_get_named_gpio_flags vmlinux EXPORT_SYMBOL
++0x1b68aba6    pin_config_set  vmlinux EXPORT_SYMBOL
++0x7505e34c    snd_power_wait  vmlinux EXPORT_SYMBOL
++0x44366cfc    simple_write_to_buffer  vmlinux EXPORT_SYMBOL
++0x3fec6133    read_code       vmlinux EXPORT_SYMBOL
++0xf7bb3a63    __srcu_read_unlock      vmlinux EXPORT_SYMBOL_GPL
++0xc2e587d1    reset_devices   vmlinux EXPORT_SYMBOL
++0x07b991fc    iio_kfifo_free  vmlinux EXPORT_SYMBOL
++0x36c38507    tty_register_device     vmlinux EXPORT_SYMBOL
++0xa5a633b9    sg_last vmlinux EXPORT_SYMBOL
++0x62c4e40d    __blk_run_queue vmlinux EXPORT_SYMBOL
++0x3eaf291d    param_get_string        vmlinux EXPORT_SYMBOL
++0x95cb929c    of_find_all_nodes       vmlinux EXPORT_SYMBOL
++0xc2c5a45e    mmc_app_cmd     vmlinux EXPORT_SYMBOL_GPL
++0xfa388487    usb_bus_list_lock       vmlinux EXPORT_SYMBOL_GPL
++0xdbbaeb6e    regulator_map_voltage_linear    vmlinux EXPORT_SYMBOL_GPL
++0x99bb8806    memmove vmlinux EXPORT_SYMBOL
++0x9e6e25f9    jbd2_journal_start_commit       vmlinux EXPORT_SYMBOL
++0x4c0f005a    __block_page_mkwrite    vmlinux EXPORT_SYMBOL
++0x76d3cd60    laptop_mode     vmlinux EXPORT_SYMBOL
++0x8fd01dea    generic_file_direct_write       vmlinux EXPORT_SYMBOL
++0xa1f38f97    end_page_writeback      vmlinux EXPORT_SYMBOL
++0xa75312bc    call_rcu_sched  vmlinux EXPORT_SYMBOL_GPL
++0xb67b2219    cm_suspend_again        vmlinux EXPORT_SYMBOL_GPL
++0x80311392    dmam_declare_coherent_memory    vmlinux EXPORT_SYMBOL
++0xf2e8c6fe    skb_recv_datagram       vmlinux EXPORT_SYMBOL
++0x4325cade    snd_soc_jack_add_pins   vmlinux EXPORT_SYMBOL_GPL
++0x69cadac1    d_alloc_pseudo  vmlinux EXPORT_SYMBOL
++0x871c0a7e    fiemap_check_flags      vmlinux EXPORT_SYMBOL
++0xd0804fe2    generic_file_readonly_mmap      vmlinux EXPORT_SYMBOL
++0xd06524ba    raw_notifier_chain_unregister   vmlinux EXPORT_SYMBOL_GPL
++0x26448a56    usbnet_cdc_unbind       vmlinux EXPORT_SYMBOL_GPL
++0x0bbae511    return_address  vmlinux EXPORT_SYMBOL_GPL
++0x0d542439    __ipv6_addr_type        vmlinux EXPORT_SYMBOL
++0xcf470397    unregister_qdisc        vmlinux EXPORT_SYMBOL
++0x66a8c67c    crypto_shash_finup      vmlinux EXPORT_SYMBOL_GPL
++0x5647361d    crypto_shash_final      vmlinux EXPORT_SYMBOL_GPL
++0xf1c942f4    crypto_ahash_finup      vmlinux EXPORT_SYMBOL_GPL
++0x17209ab0    crypto_ahash_final      vmlinux EXPORT_SYMBOL_GPL
++0x8da17b42    scatterwalk_copychunks  vmlinux EXPORT_SYMBOL_GPL
++0xd766d6a2    sdhci_suspend_host      vmlinux EXPORT_SYMBOL_GPL
++0x9b05a0c7    usb_autopm_get_interface        vmlinux EXPORT_SYMBOL_GPL
++0x8eff5a5b    phy_device_register     vmlinux EXPORT_SYMBOL
++0xa2101833    sock_diag_put_meminfo   vmlinux EXPORT_SYMBOL_GPL
++0xc8339e24    string_unescape vmlinux EXPORT_SYMBOL
++0xeb55a931    __kfifo_max_r   vmlinux EXPORT_SYMBOL
++0xe6511495    vm_insert_page  vmlinux EXPORT_SYMBOL
++0x4396b273    irq_domain_add_legacy   vmlinux EXPORT_SYMBOL_GPL
++0x24fdb0df    register_console        vmlinux EXPORT_SYMBOL
++0x6ac76b42    pin_is_valid    vmlinux EXPORT_SYMBOL_GPL
++0xe279ec34    nf_conntrack_l4proto_tcp4       vmlinux EXPORT_SYMBOL_GPL
++0x512ce34d    sock_no_socketpair      vmlinux EXPORT_SYMBOL
++0x236032ef    input_ff_event  vmlinux EXPORT_SYMBOL_GPL
++0x1e5431bd    devm_gpio_request       vmlinux EXPORT_SYMBOL
++0x86383d16    arpt_do_table   vmlinux EXPORT_SYMBOL
++0x3c89040c    dev_addr_del    vmlinux EXPORT_SYMBOL
++0xd900e010    gnet_stats_start_copy   vmlinux EXPORT_SYMBOL
++0x33f0768c    cpufreq_quick_get_max   vmlinux EXPORT_SYMBOL
++0xa88a70b0    tcp_tso_segment vmlinux EXPORT_SYMBOL
++0xa652c4ef    __kfifo_dma_in_prepare_r        vmlinux EXPORT_SYMBOL
++0xdfb895e4    __fat_fs_error  vmlinux EXPORT_SYMBOL_GPL
++0x00438c43    bio_copy_kern   vmlinux EXPORT_SYMBOL
++0xe0878bfe    __krealloc      vmlinux EXPORT_SYMBOL
++0xa849b57b    devm_free_irq   vmlinux EXPORT_SYMBOL
++0x995d1071    prof_on vmlinux EXPORT_SYMBOL_GPL
++0x3328c21e    task_nice       vmlinux EXPORT_SYMBOL
++0x84109a46    i2c_lock_adapter        vmlinux EXPORT_SYMBOL_GPL
++0x76f824bb    usb_gadget_set_state    vmlinux EXPORT_SYMBOL_GPL
++0x702c11cd    platform_device_del     vmlinux EXPORT_SYMBOL_GPL
++0xccfe749d    platform_device_put     vmlinux EXPORT_SYMBOL_GPL
++0x6499c2c3    kernel_accept   vmlinux EXPORT_SYMBOL
++0x0147e076    kset_create_and_add     vmlinux EXPORT_SYMBOL_GPL
++0xf60d1625    mm_kobj vmlinux EXPORT_SYMBOL_GPL
++0x66561d40    set_bdi_congested       vmlinux EXPORT_SYMBOL
++0xa064fc2f    gs_free_req     vmlinux EXPORT_SYMBOL_GPL
++0xaf70f0bf    xt_proto_fini   vmlinux EXPORT_SYMBOL_GPL
++0xc1e7bf31    devm_ioremap_resource   vmlinux EXPORT_SYMBOL
++0x71d3571b    sg_miter_start  vmlinux EXPORT_SYMBOL
++0xc5894dbd    blk_queue_unprep_rq     vmlinux EXPORT_SYMBOL
++0x159c0774    lock_may_read   vmlinux EXPORT_SYMBOL
++0x56d697ce    cpu_up  vmlinux EXPORT_SYMBOL_GPL
++0xba406d79    usb_gadget_map_request  vmlinux EXPORT_SYMBOL_GPL
++0xe2b9dcc5    wakeup_source_drop      vmlinux EXPORT_SYMBOL_GPL
++0x19011c29    driver_find     vmlinux EXPORT_SYMBOL_GPL
++0x13031824    devm_gpio_request_one   vmlinux EXPORT_SYMBOL
++0x91db6962    snd_card_free   vmlinux EXPORT_SYMBOL
++0x157b3f69    load_nls        vmlinux EXPORT_SYMBOL
++0xffe5318c    dma_buf_map_attachment  vmlinux EXPORT_SYMBOL_GPL
++0x10030de6    tty_mode_ioctl  vmlinux EXPORT_SYMBOL_GPL
++0x00109670    fb_class        vmlinux EXPORT_SYMBOL
++0x97999817    rfkill_set_hw_state     vmlinux EXPORT_SYMBOL
++0x6597fe84    crypto_lookup_aead      vmlinux EXPORT_SYMBOL_GPL
++0xd7b4b67a    bio_advance     vmlinux EXPORT_SYMBOL
++0x4b8408ef    from_kuid       vmlinux EXPORT_SYMBOL
++0xb65bd3fc    add_timer_on    vmlinux EXPORT_SYMBOL_GPL
++0x4859b8bb    rtc_year_days   vmlinux EXPORT_SYMBOL
++0xa064f393    ehci_cf_port_reset_rwsem        vmlinux EXPORT_SYMBOL_GPL
++0x0c65e73c    scsi_normalize_sense    vmlinux EXPORT_SYMBOL
++0x8e84b481    __pm_runtime_use_autosuspend    vmlinux EXPORT_SYMBOL_GPL
++0xab2495da    drm_mode_connector_detach_encoder       vmlinux EXPORT_SYMBOL
++0xbb11cfba    klist_iter_exit vmlinux EXPORT_SYMBOL_GPL
++0x84044a12    ip6_local_out   vmlinux EXPORT_SYMBOL_GPL
++0xc80b5684    snd_compress_deregister vmlinux EXPORT_SYMBOL_GPL
++0x215ebd78    bitrev16        vmlinux EXPORT_SYMBOL
++0x390def22    kstrtou16_from_user     vmlinux EXPORT_SYMBOL
++0x9a74417e    kstrtoull_from_user     vmlinux EXPORT_SYMBOL
++0x6949942d    pm_runtime_set_autosuspend_delay        vmlinux EXPORT_SYMBOL_GPL
++0xfb6eedf9    power_group_name        vmlinux EXPORT_SYMBOL_GPL
++0x7752eabc    snd_pcm_new_internal    vmlinux EXPORT_SYMBOL
++0x59cdb28e    crypto_aead_type        vmlinux EXPORT_SYMBOL_GPL
++0xeadf5b18    jbd2_journal_load       vmlinux EXPORT_SYMBOL
++0xcd6a7390    v4l2_i2c_new_subdev     vmlinux EXPORT_SYMBOL_GPL
++0x997574ce    device_unregister       vmlinux EXPORT_SYMBOL_GPL
++0xedbfb39a    serial8250_request_dma  vmlinux EXPORT_SYMBOL_GPL
++0x19a156ad    xfrm_state_add  vmlinux EXPORT_SYMBOL
++0x4d4a6141    __netlink_kernel_create vmlinux EXPORT_SYMBOL
++0x3ad82802    of_property_read_u32_index      vmlinux EXPORT_SYMBOL_GPL
++0x96b53df6    mmc_cleanup_queue       vmlinux EXPORT_SYMBOL
++0x7b9ee22c    v4l2_ctrl_notify        vmlinux EXPORT_SYMBOL
++0xda3a7ca9    regulator_is_enabled    vmlinux EXPORT_SYMBOL_GPL
++0x137def66    nf_ct_l4proto_put       vmlinux EXPORT_SYMBOL_GPL
++0x7efdb4fb    nf_ct_l3proto_put       vmlinux EXPORT_SYMBOL_GPL
++0x9948898e    dapm_mark_dirty vmlinux EXPORT_SYMBOL_GPL
++0x2484d571    single_release_net      vmlinux EXPORT_SYMBOL_GPL
++0x5612133a    I_BDEV  vmlinux EXPORT_SYMBOL
++0x7729cbdd    task_handoff_register   vmlinux EXPORT_SYMBOL_GPL
++0x19353b86    scsicam_bios_param      vmlinux EXPORT_SYMBOL
++0xb6a76b8e    pn544_hci_probe vmlinux EXPORT_SYMBOL
++0x476c3efa    drm_fill_in_dev vmlinux EXPORT_SYMBOL
++0x4f1cd128    security_tun_dev_create vmlinux EXPORT_SYMBOL
++0x76f29bbf    seq_release_net vmlinux EXPORT_SYMBOL_GPL
++0x980420fb    tty_port_tty_set        vmlinux EXPORT_SYMBOL
++0xc215715c    tty_port_tty_get        vmlinux EXPORT_SYMBOL
++0xa8c74dc5    devm_regulator_get      vmlinux EXPORT_SYMBOL_GPL
++0x3441c3d6    gpio_set_value_cansleep vmlinux EXPORT_SYMBOL_GPL
++0xcd68dc1d    nfc_get_local_general_bytes     vmlinux EXPORT_SYMBOL
++0xf617c0a1    inet_csk_route_child_sock       vmlinux EXPORT_SYMBOL_GPL
++0xfce4d2e1    vfs_path_lookup vmlinux EXPORT_SYMBOL
++0x326314e4    find_or_create_page     vmlinux EXPORT_SYMBOL
++0x65bbbc78    schedule_hrtimeout_range        vmlinux EXPORT_SYMBOL_GPL
++0x8d7b0a28    phy_stop_interrupts     vmlinux EXPORT_SYMBOL
++0xe9e87de1    crypto_register_pcomp   vmlinux EXPORT_SYMBOL_GPL
++0x2d7966fb    jbd2_journal_flush      vmlinux EXPORT_SYMBOL
++0x1c4e8441    invalidate_bdev vmlinux EXPORT_SYMBOL
++0x9aeacb87    ring_buffer_iter_empty  vmlinux EXPORT_SYMBOL_GPL
++0x49eb1c4a    put_pid_ns      vmlinux EXPORT_SYMBOL_GPL
++0xb7e67f9a    iio_sw_buffer_preenable vmlinux EXPORT_SYMBOL
++0xeae6b2cc    usb_sg_init     vmlinux EXPORT_SYMBOL_GPL
++0x2f33a47d    usb_sg_wait     vmlinux EXPORT_SYMBOL_GPL
++0xba136537    scsi_reset_provider     vmlinux EXPORT_SYMBOL
++0xa9170094    drm_kms_helper_hotplug_event    vmlinux EXPORT_SYMBOL
++0xb007d3b8    tcp_twsk_unique vmlinux EXPORT_SYMBOL_GPL
++0xd35091f2    netdev_info     vmlinux EXPORT_SYMBOL
++0x3517b864    kobject_uevent  vmlinux EXPORT_SYMBOL_GPL
++0x82a5ee54    mmc_try_claim_host      vmlinux EXPORT_SYMBOL
++0x11267875    scsi_extd_sense_format  vmlinux EXPORT_SYMBOL
++0x4f56540f    pm_wakeup_event vmlinux EXPORT_SYMBOL_GPL
++0x6c61ce70    num_registered_fb       vmlinux EXPORT_SYMBOL
++0xcc2f1602    st_sensors_sysfs_get_sampling_frequency vmlinux EXPORT_SYMBOL
++0x0bf95cc0    st_sensors_sysfs_set_sampling_frequency vmlinux EXPORT_SYMBOL
++0xa73fc98f    of_n_addr_cells vmlinux EXPORT_SYMBOL
++0xaf5c2852    wakeup_source_add       vmlinux EXPORT_SYMBOL_GPL
++0xc27732b1    snd_pcm_lib_default_mmap        vmlinux EXPORT_SYMBOL_GPL
++0x3ca17104    __snd_printk    vmlinux EXPORT_SYMBOL_GPL
++0xa6a59f23    blk_cleanup_queue       vmlinux EXPORT_SYMBOL
++0xec3364ec    generic_setlease        vmlinux EXPORT_SYMBOL
++0x440d8a62    tty_hung_up_p   vmlinux EXPORT_SYMBOL
++0xfa2e4ead    ip6_tnl_dst_store       vmlinux EXPORT_SYMBOL_GPL
++0x5a0647c1    ipv6_getsockopt vmlinux EXPORT_SYMBOL
++0x329bbbde    timerqueue_del  vmlinux EXPORT_SYMBOL_GPL
++0x34161524    st_sensors_read_event_value     vmlinux EXPORT_SYMBOL
++0x3e16c1b5    v4l2_clk_put    vmlinux EXPORT_SYMBOL
++0xdc047fc4    scsi_dev_info_list_add_keyed    vmlinux EXPORT_SYMBOL
++0xdc97af2e    syscore_suspend vmlinux EXPORT_SYMBOL_GPL
++0xaebbf521    cfg80211_ch_switch_notify       vmlinux EXPORT_SYMBOL
++0x4fdb4cdf    proc_mkdir_data vmlinux EXPORT_SYMBOL_GPL
++0x8ffad455    mpage_writepages        vmlinux EXPORT_SYMBOL
++0x258f05ac    write_one_page  vmlinux EXPORT_SYMBOL
++0x32b31a8c    ktime_get_boottime      vmlinux EXPORT_SYMBOL_GPL
++0x15892417    async_synchronize_cookie        vmlinux EXPORT_SYMBOL_GPL
++0x5a596330    v4l2_i2c_new_subdev_board       vmlinux EXPORT_SYMBOL_GPL
++0xbd05974a    usb_driver_release_interface    vmlinux EXPORT_SYMBOL_GPL
++0xce190a28    cfg80211_notify_new_peer_candidate      vmlinux EXPORT_SYMBOL
++0x23c45e2a    inet_add_protocol       vmlinux EXPORT_SYMBOL
++0xe19c66e3    sync_blockdev   vmlinux EXPORT_SYMBOL
++0xd36667e2    nobh_write_end  vmlinux EXPORT_SYMBOL
++0x815a1805    n_tty_ioctl_helper      vmlinux EXPORT_SYMBOL
++0xedd9106d    __ashrdi3       vmlinux EXPORT_SYMBOL
++0xff67b37f    __lshrdi3       vmlinux EXPORT_SYMBOL
++0x85b5e625    rfkill_set_states       vmlinux EXPORT_SYMBOL
++0x6e720ff2    rtnl_unlock     vmlinux EXPORT_SYMBOL
++0x4c02a5f2    sock_rfree      vmlinux EXPORT_SYMBOL
++0xe252485d    kernel_recvmsg  vmlinux EXPORT_SYMBOL
++0x0693eedb    disk_part_iter_init     vmlinux EXPORT_SYMBOL_GPL
++0x4019ac2a    freeze_bdev     vmlinux EXPORT_SYMBOL
++0x9f1c66aa    srcu_batches_completed  vmlinux EXPORT_SYMBOL_GPL
++0xa6ec6db0    sdhci_alloc_host        vmlinux EXPORT_SYMBOL_GPL
++0x0bfba95f    usb_hub_find_child      vmlinux EXPORT_SYMBOL_GPL
++0x9f83d040    __root_device_register  vmlinux EXPORT_SYMBOL_GPL
++0x63b124fc    drm_bl_dpms     vmlinux EXPORT_SYMBOL_GPL
++0xb35f8f7f    __hci_cmd_sync_ev       vmlinux EXPORT_SYMBOL
++0xe177ecc2    skb_kill_datagram       vmlinux EXPORT_SYMBOL
++0x985c6297    kfree_skb       vmlinux EXPORT_SYMBOL
++0xdcb83c11    kernel_kobj     vmlinux EXPORT_SYMBOL_GPL
++0x1bb5fc26    atomic_notifier_chain_register  vmlinux EXPORT_SYMBOL_GPL
++0xab1d6cc1    param_get_long  vmlinux EXPORT_SYMBOL
++0x75d68801    inet_twsk_schedule      vmlinux EXPORT_SYMBOL_GPL
++0x68b83ac6    posix_acl_alloc vmlinux EXPORT_SYMBOL
++0x306b23a8    drm_mm_takedown vmlinux EXPORT_SYMBOL
++0x698be398    regulator_get_voltage   vmlinux EXPORT_SYMBOL_GPL
++0xc8bed9c5    amba_driver_unregister  vmlinux EXPORT_SYMBOL
++0x1db7dc40    pgprot_kernel   vmlinux EXPORT_SYMBOL
++0x19e03378    cfg80211_get_p2p_attr   vmlinux EXPORT_SYMBOL
++0x44a5de9b    nfnetlink_parse_nat_setup_hook  vmlinux EXPORT_SYMBOL_GPL
++0x52d047db    skb_copy_datagram_iovec vmlinux EXPORT_SYMBOL
++0x731f351a    __kfree_skb     vmlinux EXPORT_SYMBOL
++0xd544b6fe    fuse_do_open    vmlinux EXPORT_SYMBOL_GPL
++0xd98f64fc    tty_port_register_device        vmlinux EXPORT_SYMBOL_GPL
++0xfd305341    walk_stackframe vmlinux EXPORT_SYMBOL
++0x58378f4a    snd_soc_dapm_force_enable_pin   vmlinux EXPORT_SYMBOL_GPL
++0x31b31f5c    csum_partial_copy_nocheck       vmlinux EXPORT_SYMBOL
++0xeea82d10    ip_defrag       vmlinux EXPORT_SYMBOL
++0xd75abd53    register_qdisc  vmlinux EXPORT_SYMBOL
++0xe4bf323c    snd_soc_test_bits       vmlinux EXPORT_SYMBOL_GPL
++0x5d891a64    idr_destroy     vmlinux EXPORT_SYMBOL
++0xeb9e7cdd    ida_destroy     vmlinux EXPORT_SYMBOL
++0x302b0f11    generic_file_aio_read   vmlinux EXPORT_SYMBOL
++0x3fe00f7d    mmc_can_discard vmlinux EXPORT_SYMBOL
++0x51246a07    mmc_interrupt_hpi       vmlinux EXPORT_SYMBOL
++0xce55bca9    scsi_flush_work vmlinux EXPORT_SYMBOL_GPL
++0x3ca53f5d    arpt_alloc_initial_table        vmlinux EXPORT_SYMBOL_GPL
++0x3ab45d33    free_netdev     vmlinux EXPORT_SYMBOL
++0xc9ec4e21    free_percpu     vmlinux EXPORT_SYMBOL_GPL
++0x431fd1f6    v4l2_subdev_queryctrl   vmlinux EXPORT_SYMBOL
++0x7c0f2bb5    drm_mm_create_block     vmlinux EXPORT_SYMBOL
++0x3fa79dd5    ip6_datagram_recv_ctl   vmlinux EXPORT_SYMBOL_GPL
++0xd56d7aae    sk_setup_caps   vmlinux EXPORT_SYMBOL_GPL
++0x668da8d5    zlib_inflateIncomp      vmlinux EXPORT_SYMBOL
++0xe0f99a2f    ida_pre_get     vmlinux EXPORT_SYMBOL
++0xf932015f    __raw_notifier_call_chain       vmlinux EXPORT_SYMBOL_GPL
++0x4d3c153f    sigprocmask     vmlinux EXPORT_SYMBOL
++0xd1974639    spi_sync_locked vmlinux EXPORT_SYMBOL_GPL
++0xdcbd7c06    scsi_host_get   vmlinux EXPORT_SYMBOL
++0x8ccc342d    drm_helper_move_panel_connectors_to_head        vmlinux EXPORT_SYMBOL
++0x98578bb6    regulator_bulk_get      vmlinux EXPORT_SYMBOL_GPL
++0x85ddc629    sk_stream_wait_connect  vmlinux EXPORT_SYMBOL
++0x4db49a03    vb2_ioctl_dqbuf vmlinux EXPORT_SYMBOL_GPL
++0xf720d75c    drm_vblank_init vmlinux EXPORT_SYMBOL
++0x8d551bef    sysctl_tcp_rmem vmlinux EXPORT_SYMBOL
++0x6c8c2ae7    sock_no_sendmsg vmlinux EXPORT_SYMBOL
++0x3b1b7e9f    snd_soc_bytes_get       vmlinux EXPORT_SYMBOL_GPL
++0xf74dae0f    idr_alloc       vmlinux EXPORT_SYMBOL_GPL
++0x7c666ca1    jbd2_journal_update_sb_errno    vmlinux EXPORT_SYMBOL
++0x98d00f33    vfs_unlink      vmlinux EXPORT_SYMBOL
++0x9ee85355    extcon_unregister_notifier      vmlinux EXPORT_SYMBOL_GPL
++0xf9e3887b    i2c_master_recv vmlinux EXPORT_SYMBOL
++0xaff711f1    drm_global_mutex        vmlinux EXPORT_SYMBOL
++0x62c5828a    nfc_hci_set_param       vmlinux EXPORT_SYMBOL
++0x52512e8e    nfc_hci_get_param       vmlinux EXPORT_SYMBOL
++0x4c90a5a9    lro_flush_all   vmlinux EXPORT_SYMBOL
++0xc5116125    pipe_unlock     vmlinux EXPORT_SYMBOL
++0x2d6bcdcb    iio_trigger_generic_data_rdy_poll       vmlinux EXPORT_SYMBOL
++0x48c6db53    of_get_child_by_name    vmlinux EXPORT_SYMBOL
++0x4379f0a6    genlmsg_multicast_allns vmlinux EXPORT_SYMBOL
++0x43e32587    __sock_recv_wifi_status vmlinux EXPORT_SYMBOL_GPL
++0x83a5ae2e    __tracepoint_rpm_resume vmlinux EXPORT_SYMBOL_GPL
++0xb2d48a2e    queue_work_on   vmlinux EXPORT_SYMBOL
++0x59d8223a    ioport_resource vmlinux EXPORT_SYMBOL
++0x73a25185    pm_generic_restore      vmlinux EXPORT_SYMBOL_GPL
++0x401ad827    bus_rescan_devices      vmlinux EXPORT_SYMBOL_GPL
++0x3b4e8e6c    serial8250_tx_dma       vmlinux EXPORT_SYMBOL_GPL
++0xba9f64c5    put_tty_driver  vmlinux EXPORT_SYMBOL
++0xa46a0fcf    backlight_force_update  vmlinux EXPORT_SYMBOL
++0xc7a4fbed    rtnl_lock       vmlinux EXPORT_SYMBOL
++0x27b3484e    debugfs_create_bool     vmlinux EXPORT_SYMBOL_GPL
++0x3691702f    generic_file_splice_read        vmlinux EXPORT_SYMBOL
++0xdd2efc0f    ring_buffer_reset_cpu   vmlinux EXPORT_SYMBOL_GPL
++0x2c1d69dc    prepare_kernel_cred     vmlinux EXPORT_SYMBOL
++0x897473df    mktime  vmlinux EXPORT_SYMBOL
++0xa8721b97    system_state    vmlinux EXPORT_SYMBOL
++0x2b768df3    iio_buffer_show_enable  vmlinux EXPORT_SYMBOL
++0xc3070585    xfrm6_tunnel_alloc_spi  vmlinux EXPORT_SYMBOL
++0x6e583bdd    udp_push_pending_frames vmlinux EXPORT_SYMBOL
++0xead6dbe6    splice_from_pipe_next   vmlinux EXPORT_SYMBOL
++0x6d044c26    param_ops_uint  vmlinux EXPORT_SYMBOL
++0x6f0036d9    del_timer_sync  vmlinux EXPORT_SYMBOL
++0xc9db98ec    hidinput_connect        vmlinux EXPORT_SYMBOL_GPL
++0xa3a75748    sec_bulk_read   vmlinux EXPORT_SYMBOL_GPL
++0x7c640527    bt_info vmlinux EXPORT_SYMBOL
++0x00e8097b    csum_partial_copy_fromiovecend  vmlinux EXPORT_SYMBOL
++0x098ef076    wm_hubs_vmid_ena        vmlinux EXPORT_SYMBOL_GPL
++0xc29591b4    drm_framebuffer_unreference     vmlinux EXPORT_SYMBOL
++0xdbfa4d5b    con_set_default_unimap  vmlinux EXPORT_SYMBOL
++0x08b75c5b    inet_diag_bc_sk vmlinux EXPORT_SYMBOL_GPL
++0x3dea553f    __qdisc_calculate_pkt_len       vmlinux EXPORT_SYMBOL
++0xab5f8242    dev_get_by_index        vmlinux EXPORT_SYMBOL
++0x3e9d0c22    wm8958_mic_detect       vmlinux EXPORT_SYMBOL_GPL
++0x462a2e75    match_strlcpy   vmlinux EXPORT_SYMBOL
++0xf768dabc    ioctl_by_bdev   vmlinux EXPORT_SYMBOL
++0x426b04e4    dma_buf_unmap_attachment        vmlinux EXPORT_SYMBOL_GPL
++0x27146b38    init_net        vmlinux EXPORT_SYMBOL
++0x9fe06761    wm_hubs_update_class_w  vmlinux EXPORT_SYMBOL_GPL
++0x8978d687    textsearch_find_continuous      vmlinux EXPORT_SYMBOL
++0xf7b12aee    __next_cpu      vmlinux EXPORT_SYMBOL
++0x96905151    crypto_larval_lookup    vmlinux EXPORT_SYMBOL_GPL
++0xb14bfc6b    __crypto_alloc_tfm      vmlinux EXPORT_SYMBOL_GPL
++0x3ca95bb3    configfs_unregister_subsystem   vmlinux EXPORT_SYMBOL
++0xd820c283    eventfd_ctx_remove_wait_queue   vmlinux EXPORT_SYMBOL_GPL
++0x699d1d6a    generic_delete_inode    vmlinux EXPORT_SYMBOL
++0xb5f17edf    perf_register_guest_info_callbacks      vmlinux EXPORT_SYMBOL_GPL
++0x1d209e24    mmc_power_restore_host  vmlinux EXPORT_SYMBOL
++0x8c66045e    cpufreq_freq_attr_scaling_boost_freqs   vmlinux EXPORT_SYMBOL_GPL
++0x6114d8a4    regulator_force_disable vmlinux EXPORT_SYMBOL_GPL
++0x7e606130    snd_soc_calc_bclk       vmlinux EXPORT_SYMBOL_GPL
++0xac480322    nf_nat_pptp_hook_expectfn       vmlinux EXPORT_SYMBOL_GPL
++0x7f19e69f    blk_run_queue   vmlinux EXPORT_SYMBOL
++0x98dbc3bc    mmc_wait_for_req        vmlinux EXPORT_SYMBOL
++0xa0d2b347    regmap_init_spi vmlinux EXPORT_SYMBOL_GPL
++0xff7a8968    regmap_init_i2c vmlinux EXPORT_SYMBOL_GPL
++0x98cc564a    regulator_set_voltage   vmlinux EXPORT_SYMBOL_GPL
++0xcd63c845    __aeabi_lasr    vmlinux EXPORT_SYMBOL
++0x8a4fa83b    __aeabi_llsr    vmlinux EXPORT_SYMBOL
++0x78cfc117    hci_register_dev        vmlinux EXPORT_SYMBOL
++0xd458f195    __secpath_destroy       vmlinux EXPORT_SYMBOL
++0xaf64ad0d    zlib_deflate    vmlinux EXPORT_SYMBOL
++0x24fdac79    wake_bit_function       vmlinux EXPORT_SYMBOL
++0x864f4a52    of_clk_add_provider     vmlinux EXPORT_SYMBOL_GPL
++0x1de054d5    of_clk_del_provider     vmlinux EXPORT_SYMBOL_GPL
++0x42c8e001    v4l2_ctrl_next  vmlinux EXPORT_SYMBOL
++0x1e95b9ac    i2c_smbus_write_i2c_block_data  vmlinux EXPORT_SYMBOL
++0xc61c11c2    inet_csk_route_req      vmlinux EXPORT_SYMBOL_GPL
++0xed597524    qdisc_get_rtab  vmlinux EXPORT_SYMBOL
++0x9a633fbd    fuse_request_send_background    vmlinux EXPORT_SYMBOL_GPL
++0x578e47c8    locks_release_private   vmlinux EXPORT_SYMBOL_GPL
++0x40ce485b    mempool_resize  vmlinux EXPORT_SYMBOL
++0xc60f75ec    __ftrace_vprintk        vmlinux EXPORT_SYMBOL_GPL
++0xb88fb22f    hid_set_field   vmlinux EXPORT_SYMBOL_GPL
++0xd954e4a7    bus_remove_file vmlinux EXPORT_SYMBOL_GPL
++0x6172f515    xfrm_unregister_km      vmlinux EXPORT_SYMBOL
++0xc5e4258e    in_dev_finish_destroy   vmlinux EXPORT_SYMBOL
++0xe094ef39    sg_next vmlinux EXPORT_SYMBOL
++0x6b4be175    bio_map_user    vmlinux EXPORT_SYMBOL
++0x0b07abe2    unshare_fs_struct       vmlinux EXPORT_SYMBOL_GPL
++0x2ef6b5bf    smp_call_function_any   vmlinux EXPORT_SYMBOL_GPL
++0xd0fb7cd4    __tasklet_hi_schedule_first     vmlinux EXPORT_SYMBOL
++0xe35c5285    of_find_node_by_phandle vmlinux EXPORT_SYMBOL
++0x55724b35    hid_destroy_device      vmlinux EXPORT_SYMBOL_GPL
++0x85ad5803    cfg80211_wext_siwrts    vmlinux EXPORT_SYMBOL_GPL
++0x87cfc6e0    cfg80211_wext_giwrts    vmlinux EXPORT_SYMBOL_GPL
++0xd1b091c0    unix_inq_len    vmlinux EXPORT_SYMBOL_GPL
++0xc4d21124    __nf_conntrack_confirm  vmlinux EXPORT_SYMBOL_GPL
++0x452a56c2    __brelse        vmlinux EXPORT_SYMBOL
++0xbddeca9d    pipe_lock       vmlinux EXPORT_SYMBOL
++0x33bfdca2    gserial_alloc_line      vmlinux EXPORT_SYMBOL_GPL
++0x4edb7421    config_ep_by_speed      vmlinux EXPORT_SYMBOL_GPL
++0xa473e3d4    usbnet_suspend  vmlinux EXPORT_SYMBOL_GPL
++0x06521223    mdiobus_scan    vmlinux EXPORT_SYMBOL
++0xed8f1a2b    dmam_alloc_coherent     vmlinux EXPORT_SYMBOL
++0x9535ce7b    tty_port_carrier_raised vmlinux EXPORT_SYMBOL
++0x71280d73    regulator_set_voltage_time_sel  vmlinux EXPORT_SYMBOL_GPL
++0x1e314b21    regulator_use_dummy_regulator   vmlinux EXPORT_SYMBOL_GPL
++0x347fd4b3    eventfd_ctx_get vmlinux EXPORT_SYMBOL_GPL
++0x941f2aaa    eventfd_ctx_put vmlinux EXPORT_SYMBOL_GPL
++0xf9d18552    mark_buffer_async_write vmlinux EXPORT_SYMBOL
++0x6c6cdd4d    wait_for_completion_interruptible_timeout       vmlinux EXPORT_SYMBOL
++0xe5525b81    scsi_device_set_state   vmlinux EXPORT_SYMBOL
++0x28e23139    xfrm_probe_algs vmlinux EXPORT_SYMBOL_GPL
++0x9a9ff422    ip_route_me_harder      vmlinux EXPORT_SYMBOL
++0xb7cbbafa    inet_sock_destruct      vmlinux EXPORT_SYMBOL
++0xf26e8a56    nf_reinject     vmlinux EXPORT_SYMBOL
++0x3a9b6fb9    blk_unregister_region   vmlinux EXPORT_SYMBOL
++0x2a2c3036    unregister_nls  vmlinux EXPORT_SYMBOL
++0x5358fc36    ring_buffer_discard_commit      vmlinux EXPORT_SYMBOL_GPL
++0x555621fa    clk_enable      vmlinux EXPORT_SYMBOL_GPL
++0xf25af73c    mmc_add_host    vmlinux EXPORT_SYMBOL
++0x4b02b5ca    dev_pm_qos_update_request       vmlinux EXPORT_SYMBOL_GPL
++0xe11c3bb2    tty_chars_in_buffer     vmlinux EXPORT_SYMBOL
++0x4e60ec09    __serio_register_port   vmlinux EXPORT_SYMBOL
++0xc17515d7    usb_hcds_loaded vmlinux EXPORT_SYMBOL_GPL
++0xadfe5127    usbnet_write_cmd_nopm   vmlinux EXPORT_SYMBOL_GPL
++0x9c6c1c9c    phy_exit        vmlinux EXPORT_SYMBOL_GPL
++0x44da5d0f    __csum_ipv6_magic       vmlinux EXPORT_SYMBOL
++0x2ef42c91    l2cap_register_user     vmlinux EXPORT_SYMBOL
++0xa83b115e    skb_pull_rcsum  vmlinux EXPORT_SYMBOL_GPL
++0xbaa490f8    snd_ctl_unregister_ioctl        vmlinux EXPORT_SYMBOL
++0xe3df2eb1    v4l2_async_notifier_register    vmlinux EXPORT_SYMBOL
++0x950c4994    __scsi_device_lookup_by_target  vmlinux EXPORT_SYMBOL
++0xed3baf1d    tcp_fetch_timewait_stamp        vmlinux EXPORT_SYMBOL_GPL
++0xebdbe48c    radix_tree_gang_lookup  vmlinux EXPORT_SYMBOL
++0xc00b1f1e    register_nls    vmlinux EXPORT_SYMBOL
++0x62543231    locks_alloc_lock        vmlinux EXPORT_SYMBOL_GPL
++0x6585e310    alloc_pages_exact_nid   vmlinux EXPORT_SYMBOL
++0xb121390a    probe_irq_on    vmlinux EXPORT_SYMBOL
++0xc58f706b    usbnet_get_msglevel     vmlinux EXPORT_SYMBOL_GPL
++0x1007becd    usbnet_set_msglevel     vmlinux EXPORT_SYMBOL_GPL
++0xb9eb9d79    pm_generic_suspend      vmlinux EXPORT_SYMBOL_GPL
++0xca860514    xfrm_state_lookup       vmlinux EXPORT_SYMBOL
++0x795598eb    tcp_parse_options       vmlinux EXPORT_SYMBOL
++0x17a3ce1e    rps_may_expire_flow     vmlinux EXPORT_SYMBOL
++0x7b3d29ac    i2c_smbus_write_block_data      vmlinux EXPORT_SYMBOL
++0x8164b1cc    ump_dd_handle_create_from_secure_id     vmlinux EXPORT_SYMBOL
++0x7f04682a    of_gpio_simple_xlate    vmlinux EXPORT_SYMBOL
++0xefd6cf06    __aeabi_unwind_cpp_pr0  vmlinux EXPORT_SYMBOL
++0xb7ba76c7    __aeabi_unwind_cpp_pr2  vmlinux EXPORT_SYMBOL
++0x43f0af31    snd_soc_codec_set_pll   vmlinux EXPORT_SYMBOL_GPL
++0x6e46b07b    module_refcount vmlinux EXPORT_SYMBOL
++0x455348d7    usb_composite_probe     vmlinux EXPORT_SYMBOL_GPL
++0x0e8110c3    sec_reg_write   vmlinux EXPORT_SYMBOL_GPL
++0xba0edce6    inet_ctl_sock_create    vmlinux EXPORT_SYMBOL_GPL
++0x8454f899    dev_addr_add_multiple   vmlinux EXPORT_SYMBOL
++0x62e4112b    _submit_bh      vmlinux EXPORT_SYMBOL_GPL
++0x715622e2    handle_edge_irq vmlinux EXPORT_SYMBOL
++0x0e639705    usbnet_link_change      vmlinux EXPORT_SYMBOL
++0x8043eb8c    firmware_kobj   vmlinux EXPORT_SYMBOL_GPL
++0x130bf78b    drm_mode_create_from_cmdline_mode       vmlinux EXPORT_SYMBOL
++0xbdd37f04    usb_autopm_put_interface_async  vmlinux EXPORT_SYMBOL_GPL
++0x63c46f03    usb_lock_device_for_reset       vmlinux EXPORT_SYMBOL_GPL
++0x1bc5eebe    pinctrl_gpio_direction_input    vmlinux EXPORT_SYMBOL_GPL
++0x519b061e    genl_register_mc_group  vmlinux EXPORT_SYMBOL
++0xf81e0907    ___pskb_trim    vmlinux EXPORT_SYMBOL
++0xd352e668    snd_timer_global_new    vmlinux EXPORT_SYMBOL
++0x85df9b6c    strsep  vmlinux EXPORT_SYMBOL
++0xe2d5255a    strcmp  vmlinux EXPORT_SYMBOL
++0x788fe103    iomem_resource  vmlinux EXPORT_SYMBOL
++0xe7a9a6a0    tty_driver_flush_buffer vmlinux EXPORT_SYMBOL
++0xd648e564    fb_match_mode   vmlinux EXPORT_SYMBOL
++0xbc10dd97    __put_user_4    vmlinux EXPORT_SYMBOL
++0x353e3fa5    __get_user_4    vmlinux EXPORT_SYMBOL
++0xe50ad8a8    snd_ctl_add     vmlinux EXPORT_SYMBOL
++0x6323f87b    mnt_unpin       vmlinux EXPORT_SYMBOL
++0xbb524006    vfs_create      vmlinux EXPORT_SYMBOL
++0x2f47d8c7    cpufreq_frequency_get_table     vmlinux EXPORT_SYMBOL_GPL
++0xda44cb37    setup_charger_manager   vmlinux EXPORT_SYMBOL_GPL
++0x01ab74a6    devm_kfree      vmlinux EXPORT_SYMBOL_GPL
++0x153be8a8    drm_fb_helper_pan_display       vmlinux EXPORT_SYMBOL
++0xc676a007    __ablkcipher_walk_complete      vmlinux EXPORT_SYMBOL_GPL
++0x868bf31d    sb_min_blocksize        vmlinux EXPORT_SYMBOL
++0xaf5f7994    remove_conflicting_framebuffers vmlinux EXPORT_SYMBOL
++0x49e5aa17    bt_procfs_init  vmlinux EXPORT_SYMBOL
++0xf353a698    register_module_notifier        vmlinux EXPORT_SYMBOL
++0x154c6338    dm_kcopyd_client_destroy        vmlinux EXPORT_SYMBOL
++0xdd4cc94f    v4l2_device_set_name    vmlinux EXPORT_SYMBOL_GPL
++0x703189d7    regulator_get_mode      vmlinux EXPORT_SYMBOL_GPL
++0x43028a27    nfc_hci_result_to_errno vmlinux EXPORT_SYMBOL
++0x0551f0ce    tick_nohz_idle_exit     vmlinux EXPORT_SYMBOL_GPL
++0xc7208c3a    serial8250_resume_port  vmlinux EXPORT_SYMBOL
++0xe91355f8    inet_csk_clone_lock     vmlinux EXPORT_SYMBOL_GPL
++0xe912da6b    unregister_sysctl_table vmlinux EXPORT_SYMBOL
++0xaf91d89f    __kernel_param_lock     vmlinux EXPORT_SYMBOL
++0x31cdd70c    hid_input_report        vmlinux EXPORT_SYMBOL_GPL
++0xd73ee981    cdc_ncm_fill_tx_frame   vmlinux EXPORT_SYMBOL_GPL
++0xa01c6bfd    del_gendisk     vmlinux EXPORT_SYMBOL
++0x4d74d134    block_write_full_page   vmlinux EXPORT_SYMBOL
++0x43632d7d    of_find_property        vmlinux EXPORT_SYMBOL
++0xa76550fa    xfrm_register_type      vmlinux EXPORT_SYMBOL
++0xde08bdaf    nf_ct_invert_tuple      vmlinux EXPORT_SYMBOL_GPL
++0xa61aa028    snd_pcm_format_unsigned vmlinux EXPORT_SYMBOL
++0x0b51f3e2    fat_sync_inode  vmlinux EXPORT_SYMBOL_GPL
++0xb3e441b1    clear_bdi_congested     vmlinux EXPORT_SYMBOL
++0x9305f8e6    cpufreq_get     vmlinux EXPORT_SYMBOL
++0x8708f581    usbnet_stop     vmlinux EXPORT_SYMBOL_GPL
++0x581e0fb1    sock_no_setsockopt      vmlinux EXPORT_SYMBOL
++0xdf40231d    sock_no_getsockopt      vmlinux EXPORT_SYMBOL
++0xa3355ffa    snd_soc_default_writable_register       vmlinux EXPORT_SYMBOL_GPL
++0xb8ba4a80    __blockdev_direct_IO    vmlinux EXPORT_SYMBOL
++0x4f70015c    splice_from_pipe_end    vmlinux EXPORT_SYMBOL
++0x93658a27    migrate_page    vmlinux EXPORT_SYMBOL
++0x2e45e488    rcu_note_context_switch vmlinux EXPORT_SYMBOL_GPL
++0xf0d68ed6    clk_register_clkdevs    vmlinux EXPORT_SYMBOL
++0xec58fd46    ip6_route_me_harder     vmlinux EXPORT_SYMBOL
++0xccec571a    thermal_zone_device_update      vmlinux EXPORT_SYMBOL_GPL
++0x011c6bf0    regulator_map_voltage_iterate   vmlinux EXPORT_SYMBOL_GPL
++0x44eabd85    km_new_mapping  vmlinux EXPORT_SYMBOL
++0x4469fe89    lro_receive_skb vmlinux EXPORT_SYMBOL
++0x6d54f969    napi_complete   vmlinux EXPORT_SYMBOL
++0xb740018f    snd_device_new  vmlinux EXPORT_SYMBOL
++0xab363caa    generic_block_bmap      vmlinux EXPORT_SYMBOL
++0x868784cb    __symbol_get    vmlinux EXPORT_SYMBOL_GPL
++0x142a8be4    of_clk_get_parent_name  vmlinux EXPORT_SYMBOL_GPL
++0x991484c4    of_property_count_strings       vmlinux EXPORT_SYMBOL_GPL
++0x5f3c8f5c    mmc_assume_removable    vmlinux EXPORT_SYMBOL
++0xf9c1f53f    pm_generic_thaw_early   vmlinux EXPORT_SYMBOL_GPL
++0x47229b5c    gpio_request    vmlinux EXPORT_SYMBOL_GPL
++0x517deb22    __ip_dev_find   vmlinux EXPORT_SYMBOL
++0x815fe221    snd_pcm_hw_constraint_list      vmlinux EXPORT_SYMBOL
++0xbe0e5118    nla_memcmp      vmlinux EXPORT_SYMBOL
++0xf1db1704    nla_memcpy      vmlinux EXPORT_SYMBOL
++0x1f77b093    file_remove_suid        vmlinux EXPORT_SYMBOL
++0xfd6794fe    d_materialise_unique    vmlinux EXPORT_SYMBOL_GPL
++0x26622a2b    kmem_cache_free vmlinux EXPORT_SYMBOL
++0x7aab19fb    vb2_ops_wait_prepare    vmlinux EXPORT_SYMBOL_GPL
++0x5d22b406    rndis_register  vmlinux EXPORT_SYMBOL
++0xd25dc9c5    cdc_ncm_rx_verify_nth16 vmlinux EXPORT_SYMBOL_GPL
++0x8299a21a    ieee80211_data_from_8023        vmlinux EXPORT_SYMBOL
++0x499cb58c    prepare_to_wait vmlinux EXPORT_SYMBOL
++0xadf42bd5    __request_region        vmlinux EXPORT_SYMBOL
++0x9f560253    get_cpu_device  vmlinux EXPORT_SYMBOL_GPL
++0x923b1276    dmaengine_get   vmlinux EXPORT_SYMBOL
++0x56d9b1de    amba_device_register    vmlinux EXPORT_SYMBOL
++0x6fa16209    bdev_read_only  vmlinux EXPORT_SYMBOL
++0xf0009fee    put_pages_list  vmlinux EXPORT_SYMBOL
++0xdf73013e    from_kprojid    vmlinux EXPORT_SYMBOL
++0x2609451c    sock_wfree      vmlinux EXPORT_SYMBOL
++0x0de80eba    snd_soc_info_volsw      vmlinux EXPORT_SYMBOL_GPL
++0xd7f77051    test_set_page_writeback vmlinux EXPORT_SYMBOL
++0xa734a3e9    abort_exclusive_wait    vmlinux EXPORT_SYMBOL
++0x091eb9b4    round_jiffies   vmlinux EXPORT_SYMBOL_GPL
++0x99429b47    display_entity_unregister       vmlinux EXPORT_SYMBOL_GPL
++0x40d0b751    qdisc_destroy   vmlinux EXPORT_SYMBOL
++0x16445cb3    inet_proto_csum_replace16       vmlinux EXPORT_SYMBOL
++0x5594be03    bitmap_remap    vmlinux EXPORT_SYMBOL
++0x7fe04a49    truncate_inode_pages    vmlinux EXPORT_SYMBOL
++0x42f865b4    fb_videomode_from_videomode     vmlinux EXPORT_SYMBOL_GPL
++0x0422fe4a    inet_csk_timer_bug_msg  vmlinux EXPORT_SYMBOL
++0x1b0c9510    sysfs_notify    vmlinux EXPORT_SYMBOL_GPL
++0x0948cde9    num_physpages   vmlinux EXPORT_SYMBOL
++0x7818fe23    input_flush_device      vmlinux EXPORT_SYMBOL
++0x2da17677    regmap_bulk_write       vmlinux EXPORT_SYMBOL_GPL
++0x03ba39b0    v7_flush_user_cache_all vmlinux EXPORT_SYMBOL
++0x9d0403b2    inet_hash       vmlinux EXPORT_SYMBOL_GPL
++0x9a1dfd65    strpbrk vmlinux EXPORT_SYMBOL
++0xa040153b    sysfs_create_file       vmlinux EXPORT_SYMBOL_GPL
++0x99cbae17    seq_lseek       vmlinux EXPORT_SYMBOL
++0x092c2a7a    irq_domain_add_tree     vmlinux EXPORT_SYMBOL_GPL
++0x23a42148    media_entity_pipeline_stop      vmlinux EXPORT_SYMBOL_GPL
++0xd87b6687    ip6_frag_match  vmlinux EXPORT_SYMBOL
++0x9e6d79f8    snd_info_get_str        vmlinux EXPORT_SYMBOL
++0x1551dc51    bitmap_find_free_region vmlinux EXPORT_SYMBOL
++0x9f491e5d    ftrace_print_symbols_seq_u64    vmlinux EXPORT_SYMBOL
++0x9b6bedb6    sdhci_add_host  vmlinux EXPORT_SYMBOL_GPL
++0x928f84b5    drm_crtc_init   vmlinux EXPORT_SYMBOL
++0x56b63670    lzo1x_1_compress        vmlinux EXPORT_SYMBOL_GPL
++0x637d3d6a    set_disk_ro     vmlinux EXPORT_SYMBOL
++0x5053e2a6    leds_list_lock  vmlinux EXPORT_SYMBOL_GPL
++0x19fc7f60    regulator_set_mode      vmlinux EXPORT_SYMBOL_GPL
++0x7e703a3d    snd_soc_limit_volume    vmlinux EXPORT_SYMBOL_GPL
++0x3bdbf275    sg_alloc_table_from_pages       vmlinux EXPORT_SYMBOL
++0xb87bf605    blk_rq_unprep_clone     vmlinux EXPORT_SYMBOL_GPL
++0xe04f7caa    dm_read_arg_group       vmlinux EXPORT_SYMBOL
++0xb26725f8    bus_find_device vmlinux EXPORT_SYMBOL_GPL
++0x7ff32312    drm_gem_handle_create   vmlinux EXPORT_SYMBOL
++0xcd7edbe9    cfg80211_sched_scan_results     vmlinux EXPORT_SYMBOL
++0x92dbc6c1    xfrm_aalg_get_byid      vmlinux EXPORT_SYMBOL_GPL
++0x6fb14f17    tcp_create_openreq_child        vmlinux EXPORT_SYMBOL
++0x2f368d4c    sk_common_release       vmlinux EXPORT_SYMBOL
++0xd60281a9    st_sensors_set_fullscale_by_gain        vmlinux EXPORT_SYMBOL
++0x228bec81    led_trigger_register    vmlinux EXPORT_SYMBOL_GPL
++0x28c52e3f    video_device_release    vmlinux EXPORT_SYMBOL
++0x3faac56f    drm_mode_set_config_internal    vmlinux EXPORT_SYMBOL
++0xf86d3493    skb_queue_head  vmlinux EXPORT_SYMBOL
++0x5fd1e756    skb_prepare_seq_read    vmlinux EXPORT_SYMBOL
++0x02ff8c3e    sk_reset_timer  vmlinux EXPORT_SYMBOL
++0xb08f47ec    snd_soc_resume  vmlinux EXPORT_SYMBOL_GPL
++0x0f055dad    snd_pcm_hw_rule_noresample      vmlinux EXPORT_SYMBOL
++0x9529f10a    fuse_conn_put   vmlinux EXPORT_SYMBOL_GPL
++0xf6bb8bf1    irq_get_irq_data        vmlinux EXPORT_SYMBOL_GPL
++0x02c3c736    v4l2_subdev_querymenu   vmlinux EXPORT_SYMBOL
++0xfb42deb3    drm_helper_mode_fill_fb_struct  vmlinux EXPORT_SYMBOL
++0x4920a692    regulator_bulk_enable   vmlinux EXPORT_SYMBOL_GPL
++0x85963907    netdev_has_upper_dev    vmlinux EXPORT_SYMBOL
++0x5f58f676    flex_array_get_ptr      vmlinux EXPORT_SYMBOL
++0x3e6c012e    bio_alloc_bioset        vmlinux EXPORT_SYMBOL
++0xb9ac0503    mali_set_user_setting   vmlinux EXPORT_SYMBOL
++0xbd22a332    drm_pci_free    vmlinux EXPORT_SYMBOL
++0x171addd2    ieee80211_get_hdrlen_from_skb   vmlinux EXPORT_SYMBOL
++0xe41115b7    vfs_cancel_lock vmlinux EXPORT_SYMBOL_GPL
++0x912c123d    pm_qos_remove_request   vmlinux EXPORT_SYMBOL_GPL
++0x8e2d17cc    v4l2_clk_enable vmlinux EXPORT_SYMBOL
++0xfe3150df    usb_driver_set_configuration    vmlinux EXPORT_SYMBOL_GPL
++0x3b5bb4f2    mii_ethtool_sset        vmlinux EXPORT_SYMBOL
++0xe9bc24c2    mii_ethtool_gset        vmlinux EXPORT_SYMBOL
++0x62e1f48d    class_compat_create_link        vmlinux EXPORT_SYMBOL_GPL
++0xb602c57e    nf_ct_l3proto_module_put        vmlinux EXPORT_SYMBOL_GPL
++0xcd4b940c    release_sock    vmlinux EXPORT_SYMBOL
++0x90e5450f    textsearch_destroy      vmlinux EXPORT_SYMBOL
++0x50e7193a    __i2c_first_dynamic_bus_num     vmlinux EXPORT_SYMBOL_GPL
++0xa2a8e81f    class_remove_file       vmlinux EXPORT_SYMBOL_GPL
++0x95f56edb    drm_i2c_encoder_init    vmlinux EXPORT_SYMBOL
++0xdd1dd3a7    snd_pcm_hw_constraint_msbits    vmlinux EXPORT_SYMBOL
++0x23a574fd    security_secmark_relabel_packet vmlinux EXPORT_SYMBOL
++0x3f01eca9    unmap_underlying_metadata       vmlinux EXPORT_SYMBOL
++0x55feec9e    sync_inode      vmlinux EXPORT_SYMBOL
++0xb859f38b    krealloc        vmlinux EXPORT_SYMBOL
++0x9af5fc30    of_phy_connect_fixed_link       vmlinux EXPORT_SYMBOL
++0xa2307653    v4l2_device_register_subdev_nodes       vmlinux EXPORT_SYMBOL_GPL
++0x66e9dc03    usbnet_status_stop      vmlinux EXPORT_SYMBOL_GPL
++0x419a9395    snd_card_create vmlinux EXPORT_SYMBOL
++0x9edc4cdb    __invalidate_device     vmlinux EXPORT_SYMBOL
++0x301fa826    seq_put_decimal_ull     vmlinux EXPORT_SYMBOL
++0x8f7b5061    jack_event_handler      vmlinux EXPORT_SYMBOL_GPL
++0xf8e6aed1    input_register_device   vmlinux EXPORT_SYMBOL
++0xfba9b108    drm_fb_helper_fini      vmlinux EXPORT_SYMBOL
++0x31266931    con_debug_leave vmlinux EXPORT_SYMBOL_GPL
++0x2ba707a8    sysctl_tcp_low_latency  vmlinux EXPORT_SYMBOL
++0x1163f0a7    blk_max_low_pfn vmlinux EXPORT_SYMBOL
++0x94c6b808    blk_queue_free_tags     vmlinux EXPORT_SYMBOL
++0xe0413655    elv_unregister_queue    vmlinux EXPORT_SYMBOL
++0x3fab3ca9    register_sysctl_table   vmlinux EXPORT_SYMBOL
++0x67b78eb3    seq_hlist_next_rcu      vmlinux EXPORT_SYMBOL
++0x571767e3    led_classdev_unregister vmlinux EXPORT_SYMBOL_GPL
++0x9323826a    ipv4_redirect   vmlinux EXPORT_SYMBOL_GPL
++0x495c96f8    posix_acl_init  vmlinux EXPORT_SYMBOL
++0xd59c42a1    drm_idlelock_release    vmlinux EXPORT_SYMBOL
++0x490355ba    tty_flip_buffer_push    vmlinux EXPORT_SYMBOL
++0x3ef6c408    bio_copy_data   vmlinux EXPORT_SYMBOL
++0x6fe3d8cf    ktime_add_safe  vmlinux EXPORT_SYMBOL_GPL
++0xf9a482f9    msleep  vmlinux EXPORT_SYMBOL
++0xc66b77b1    iommu_group_set_iommudata       vmlinux EXPORT_SYMBOL_GPL
++0xd55ad93b    iommu_group_get_iommudata       vmlinux EXPORT_SYMBOL_GPL
++0x0d0549e1    hidinput_calc_abs_res   vmlinux EXPORT_SYMBOL_GPL
++0x07608656    uart_get_divisor        vmlinux EXPORT_SYMBOL
++0xc8f72480    unregister_netdev       vmlinux EXPORT_SYMBOL
++0x1ce42553    __bforget       vmlinux EXPORT_SYMBOL
++0x8427e5bd    v4l2_event_subdev_unsubscribe   vmlinux EXPORT_SYMBOL_GPL
++0x8e865d3c    arm_delay_ops   vmlinux EXPORT_SYMBOL
++0x2f88c16b    inet6_add_protocol      vmlinux EXPORT_SYMBOL
++0x9fda569e    raw_unhash_sk   vmlinux EXPORT_SYMBOL_GPL
++0x1def6812    xt_register_table       vmlinux EXPORT_SYMBOL_GPL
++0xe7e87d7a    set_h225_addr_hook      vmlinux EXPORT_SYMBOL_GPL
++0xd2037371    sock_no_listen  vmlinux EXPORT_SYMBOL
++0x33607e14    snd_soc_poweroff        vmlinux EXPORT_SYMBOL_GPL
++0xab600421    probe_irq_off   vmlinux EXPORT_SYMBOL
++0xfc8ace2f    input_mt_destroy_slots  vmlinux EXPORT_SYMBOL
++0xf222f80f    usb_unpoison_anchored_urbs      vmlinux EXPORT_SYMBOL_GPL
++0x4845cdbc    scsi_device_lookup_by_target    vmlinux EXPORT_SYMBOL
++0x79aa04a2    get_random_bytes        vmlinux EXPORT_SYMBOL
++0x9db44776    nfc_hci_connect_gate    vmlinux EXPORT_SYMBOL
++0x4d2726f3    tcf_exts_destroy        vmlinux EXPORT_SYMBOL
++0xbaa8249a    snd_ctl_activate_id     vmlinux EXPORT_SYMBOL_GPL
++0x55ef85b4    blk_peek_request        vmlinux EXPORT_SYMBOL
++0xc8b267ae    seq_vprintf     vmlinux EXPORT_SYMBOL
++0xe6504df3    sdhci_get_of_property   vmlinux EXPORT_SYMBOL_GPL
++0x3ad12077    regcache_sync_region    vmlinux EXPORT_SYMBOL_GPL
++0x80af255f    pm_runtime_allow        vmlinux EXPORT_SYMBOL_GPL
++0x16105b8e    do_unbind_con_driver    vmlinux EXPORT_SYMBOL_GPL
++0xdaf4dfb3    fb_mode_option  vmlinux EXPORT_SYMBOL_GPL
++0x1f5dd478    tcf_hash_lookup vmlinux EXPORT_SYMBOL
++0x14965155    sock_no_poll    vmlinux EXPORT_SYMBOL
++0xfcbe775e    blk_rq_prep_clone       vmlinux EXPORT_SYMBOL_GPL
++0x53e6cd86    crypto_alloc_shash      vmlinux EXPORT_SYMBOL_GPL
++0x93f84c0c    crypto_alloc_ahash      vmlinux EXPORT_SYMBOL_GPL
++0xae1d4afd    sdio_unregister_driver  vmlinux EXPORT_SYMBOL_GPL
++0x1b50682a    drm_mode_connector_attach_encoder       vmlinux EXPORT_SYMBOL
++0x78bed30e    regulator_get   vmlinux EXPORT_SYMBOL_GPL
++0xae4e6d07    inet6_register_icmp_sender      vmlinux EXPORT_SYMBOL
++0xcd67300d    vlan_ioctl_set  vmlinux EXPORT_SYMBOL
++0x4d9b6d35    snd_pcm_format_size     vmlinux EXPORT_SYMBOL
++0xc11d8093    iov_shorten     vmlinux EXPORT_SYMBOL
++0x6a037cf1    mempool_kfree   vmlinux EXPORT_SYMBOL
++0x0cebb5a5    __ww_mutex_lock vmlinux EXPORT_SYMBOL
++0x430e5257    of_alias_get_id vmlinux EXPORT_SYMBOL_GPL
++0x5d9260a1    v4l2_ctrl_activate      vmlinux EXPORT_SYMBOL
++0x17622c01    display_entity_set_state        vmlinux EXPORT_SYMBOL_GPL
++0x26adb815    thread_notify_head      vmlinux EXPORT_SYMBOL_GPL
++0xf0ef15b4    list_sort       vmlinux EXPORT_SYMBOL
++0x958974d4    remove_arg_zero vmlinux EXPORT_SYMBOL
++0x7b5c8440    vm_munmap       vmlinux EXPORT_SYMBOL
++0x46178343    remap_pfn_range vmlinux EXPORT_SYMBOL
++0x46608fa0    getnstimeofday  vmlinux EXPORT_SYMBOL
++0x51a049e1    scsi_scan_target        vmlinux EXPORT_SYMBOL
++0x61b31a8a    subsys_dev_iter_init    vmlinux EXPORT_SYMBOL_GPL
++0x054aade6    subsys_dev_iter_exit    vmlinux EXPORT_SYMBOL_GPL
++0x4099164a    skcipher_geniv_exit     vmlinux EXPORT_SYMBOL_GPL
++0x9c144793    file_update_time        vmlinux EXPORT_SYMBOL
++0x8a162c7d    bdi_unregister  vmlinux EXPORT_SYMBOL
++0x755d68eb    iio_enum_read   vmlinux EXPORT_SYMBOL_GPL
++0x03e593b9    vb2_wait_for_all_buffers        vmlinux EXPORT_SYMBOL_GPL
++0xc06a30a4    phy_register_fixup      vmlinux EXPORT_SYMBOL
++0x3c308a26    device_bind_driver      vmlinux EXPORT_SYMBOL_GPL
++0x55010072    device_store_ulong      vmlinux EXPORT_SYMBOL_GPL
++0x0b405d40    inet6_csk_search_req    vmlinux EXPORT_SYMBOL_GPL
++0x7a1acc62    dev_mc_init     vmlinux EXPORT_SYMBOL
++0x93fcc9bd    dev_uc_init     vmlinux EXPORT_SYMBOL
++0x865029ac    __hw_addr_sync  vmlinux EXPORT_SYMBOL
++0xb04359d9    snd_soc_bytes_info      vmlinux EXPORT_SYMBOL_GPL
++0x11a13e31    _kstrtol        vmlinux EXPORT_SYMBOL
++0x6e73746d    kobject_uevent_env      vmlinux EXPORT_SYMBOL_GPL
++0x7d830ea5    mb_cache_entry_alloc    vmlinux EXPORT_SYMBOL
++0xd702e480    _raw_read_unlock        vmlinux EXPORT_SYMBOL
++0xfa2bcf10    init_timer_key  vmlinux EXPORT_SYMBOL
++0xe03525ac    of_irq_map_raw  vmlinux EXPORT_SYMBOL_GPL
++0xb39171d5    cdc_ncm_select_altsetting       vmlinux EXPORT_SYMBOL_GPL
++0xec52c42e    scsi_setup_blk_pc_cmnd  vmlinux EXPORT_SYMBOL
++0x337cce46    put_cmsg        vmlinux EXPORT_SYMBOL
++0x655656dc    skb_free_datagram       vmlinux EXPORT_SYMBOL
++0x2ad0e68c    sound_class     vmlinux EXPORT_SYMBOL
++0x7a98596c    filp_close      vmlinux EXPORT_SYMBOL
++0x4c39b01b    truncate_setsize        vmlinux EXPORT_SYMBOL
++0xfd5683b9    wait_for_completion_interruptible       vmlinux EXPORT_SYMBOL
++0xfc38a837    extcon_update_state     vmlinux EXPORT_SYMBOL_GPL
++0xdba80fc1    of_fdt_unflatten_tree   vmlinux EXPORT_SYMBOL_GPL
++0x3be54580    generic_readlink        vmlinux EXPORT_SYMBOL
++0x6cee2e42    drm_object_property_get_value   vmlinux EXPORT_SYMBOL
++0x67b27ec1    tty_std_termios vmlinux EXPORT_SYMBOL
++0x4298b775    v7_flush_kern_cache_all vmlinux EXPORT_SYMBOL
++0x66ac9af0    ether_setup     vmlinux EXPORT_SYMBOL
++0xafb2d50e    __break_lease   vmlinux EXPORT_SYMBOL
++0x9e6500de    get_task_comm   vmlinux EXPORT_SYMBOL_GPL
++0xd5df9165    __get_vm_area   vmlinux EXPORT_SYMBOL_GPL
++0x6b7589f4    param_set_bool  vmlinux EXPORT_SYMBOL
++0xbfc407b4    param_ops_bint  vmlinux EXPORT_SYMBOL
++0xadb5559d    param_ops_byte  vmlinux EXPORT_SYMBOL
++0xd2a3a2e7    usb_deregister_device_driver    vmlinux EXPORT_SYMBOL_GPL
++0x0264e273    usbnet_nway_reset       vmlinux EXPORT_SYMBOL_GPL
++0xbc31af43    device_create_file      vmlinux EXPORT_SYMBOL_GPL
++0x34bb0082    snd_soc_dapm_put_volsw  vmlinux EXPORT_SYMBOL_GPL
++0xcec0e354    snd_soc_dapm_get_volsw  vmlinux EXPORT_SYMBOL_GPL
++0xa3d6bc8a    would_dump      vmlinux EXPORT_SYMBOL
++0x782cd0c9    truncate_inode_pages_range      vmlinux EXPORT_SYMBOL
++0xefc7de8e    force_sig       vmlinux EXPORT_SYMBOL
++0xb3b30554    fimc_find_remote_sensor vmlinux EXPORT_SYMBOL
++0xf3be20f4    v4l2_m2m_querybuf       vmlinux EXPORT_SYMBOL_GPL
++0x0fccafb1    drm_global_item_unref   vmlinux EXPORT_SYMBOL
++0xe8d24f74    arm_coherent_dma_ops    vmlinux EXPORT_SYMBOL
++0x05240ee7    percpu_counter_batch    vmlinux EXPORT_SYMBOL
++0x5d75cd76    d_path  vmlinux EXPORT_SYMBOL
++0x495426ee    v4l2_ctrl_get_name      vmlinux EXPORT_SYMBOL
++0x6e89a560    regmap_irq_chip_get_base        vmlinux EXPORT_SYMBOL_GPL
++0x587616f1    vfs_fstatat     vmlinux EXPORT_SYMBOL
++0x162ccc0c    lg_local_lock   vmlinux EXPORT_SYMBOL
++0x498225b6    v4l2_m2m_expbuf vmlinux EXPORT_SYMBOL_GPL
++0x21b2c1ab    __pm_genpd_remove_callbacks     vmlinux EXPORT_SYMBOL_GPL
++0x1516aa21    brcmf_sdio_probe        drivers/net/wireless/brcm80211/brcmfmac/brcmfmac        EXPORT_SYMBOL
++0x36c61868    hci_free_dev    vmlinux EXPORT_SYMBOL
++0xcfa46265    igrab   vmlinux EXPORT_SYMBOL
++0x36150611    iio_validate_scan_mask_onehot   vmlinux EXPORT_SYMBOL_GPL
++0x01ac01fc    usbnet_resume   vmlinux EXPORT_SYMBOL_GPL
++0x43421b4f    sdev_evt_send   vmlinux EXPORT_SYMBOL_GPL
++0x1fdcc615    rtnl_notify     vmlinux EXPORT_SYMBOL
++0xe4ad075c    __rtnl_link_register    vmlinux EXPORT_SYMBOL_GPL
++0x41366c3b    sock_recvmsg    vmlinux EXPORT_SYMBOL
++0x3468cb4a    snd_soc_set_runtime_hwparams    vmlinux EXPORT_SYMBOL_GPL
++0x308e4695    snd_pcm_open_substream  vmlinux EXPORT_SYMBOL
++0x2ef9dbdc    blk_end_request_err     vmlinux EXPORT_SYMBOL_GPL
++0x9b11d9bf    blk_end_request_all     vmlinux EXPORT_SYMBOL
++0x2f5bf998    blk_queue_bio   vmlinux EXPORT_SYMBOL_GPL
++0xd16712f3    crypto_check_attr_type  vmlinux EXPORT_SYMBOL_GPL
++0x16305289    warn_slowpath_null      vmlinux EXPORT_SYMBOL
++0xcb0288ea    ledtrig_cpu     vmlinux EXPORT_SYMBOL
++0xe6431c3b    mmc_can_secure_erase_trim       vmlinux EXPORT_SYMBOL
++0x916dbe7c    usb_hcd_unmap_urb_for_dma       vmlinux EXPORT_SYMBOL_GPL
++0x8dc2569e    nf_ct_l3protos  vmlinux EXPORT_SYMBOL_GPL
++0x1471e34e    linkwatch_fire_event    vmlinux EXPORT_SYMBOL
++0x56db40e5    snd_device_free vmlinux EXPORT_SYMBOL
++0xe1b524a3    fs_bio_set      vmlinux EXPORT_SYMBOL
++0x8d522714    __rcu_read_lock vmlinux EXPORT_SYMBOL_GPL
++0x4906a967    hid_snto32      vmlinux EXPORT_SYMBOL_GPL
++0xfbf6bb67    watchdog_init_timeout   vmlinux EXPORT_SYMBOL_GPL
++0xd37e13b4    regulator_set_optimum_mode      vmlinux EXPORT_SYMBOL_GPL
++0x4fe1eddf    unregister_netevent_notifier    vmlinux EXPORT_SYMBOL_GPL
++0x66af941c    snd_soc_debugfs_root    vmlinux EXPORT_SYMBOL_GPL
++0x42c43759    input_mt_report_slot_state      vmlinux EXPORT_SYMBOL
++0x8fccb56f    scsi_init_io    vmlinux EXPORT_SYMBOL
++0x375fce7f    asoc_dma_platform_unregister    vmlinux EXPORT_SYMBOL_GPL
++0xa58dee99    _raw_write_unlock       vmlinux EXPORT_SYMBOL
++0x252efd1e    sdhci_remove_host       vmlinux EXPORT_SYMBOL_GPL
++0xb5128e67    v4l2_i2c_subdev_init    vmlinux EXPORT_SYMBOL_GPL
++0x6d680e52    v4l2_i2c_subdev_addr    vmlinux EXPORT_SYMBOL_GPL
++0xb56fc02f    fib_default_rule_pref   vmlinux EXPORT_SYMBOL
++0x97359c5f    snd_pcm_period_elapsed  vmlinux EXPORT_SYMBOL
++0x3df477d7    debugfs_create_x8       vmlinux EXPORT_SYMBOL_GPL
++0x314d3160    kmap_to_page    vmlinux EXPORT_SYMBOL
++0x8afbf7b1    irq_domain_xlate_onecell        vmlinux EXPORT_SYMBOL_GPL
++0x6b264960    irq_domain_xlate_twocell        vmlinux EXPORT_SYMBOL_GPL
++0xee3c209d    cgroup_next_descendant_pre      vmlinux EXPORT_SYMBOL_GPL
++0x6776c27a    drm_av_sync_delay       vmlinux EXPORT_SYMBOL
++0x0fe112dc    of_dma_controller_free  vmlinux EXPORT_SYMBOL_GPL
++0xfccc95e9    pwm_put vmlinux EXPORT_SYMBOL_GPL
++0xb8a5a2d7    iio_convert_raw_to_processed    vmlinux EXPORT_SYMBOL_GPL
++0x8f7df3a7    drm_object_attach_property      vmlinux EXPORT_SYMBOL
++0xd248fe40    uart_write_wakeup       vmlinux EXPORT_SYMBOL
++0x0483a4c2    skb_append      vmlinux EXPORT_SYMBOL
++0xb28d7c56    snd_soc_read    vmlinux EXPORT_SYMBOL_GPL
++0x6f1f9555    read_cache_page_gfp     vmlinux EXPORT_SYMBOL
++0xe12954af    pwm_can_sleep   vmlinux EXPORT_SYMBOL_GPL
++0x333147c5    sk_stream_error vmlinux EXPORT_SYMBOL
++0x37f30c3d    devm_request_and_ioremap        vmlinux EXPORT_SYMBOL
++0x40d57aa3    audit_log_start vmlinux EXPORT_SYMBOL
++0x3232306b    need_load_eval  vmlinux EXPORT_SYMBOL_GPL
++0x27328cec    drm_fb_helper_debug_leave       vmlinux EXPORT_SYMBOL
++0x2f4df599    arm_iommu_attach_device vmlinux EXPORT_SYMBOL_GPL
++0x38ec6320    netdev_crit     vmlinux EXPORT_SYMBOL
++0x7385ebdb    sysfs_create_files      vmlinux EXPORT_SYMBOL_GPL
++0x0758ff61    sget    vmlinux EXPORT_SYMBOL
++0xca20d111    v4l2_ctrl_cluster       vmlinux EXPORT_SYMBOL
++0x5f754e5a    memset  vmlinux EXPORT_SYMBOL
++0xbd70447e    ip_tunnel_setup vmlinux EXPORT_SYMBOL_GPL
++0x2541a979    snd_soc_calc_frame_size vmlinux EXPORT_SYMBOL_GPL
++0xdc3fcbc9    __sw_hweight8   vmlinux EXPORT_SYMBOL
++0x02ee26c1    free_pages_exact        vmlinux EXPORT_SYMBOL
++0x885bcec8    tasklet_hrtimer_init    vmlinux EXPORT_SYMBOL_GPL
++0xe80bbfc6    v4l2_event_pending      vmlinux EXPORT_SYMBOL_GPL
++0x356cb8d3    debugfs_create_atomic_t vmlinux EXPORT_SYMBOL_GPL
++0x064db9a5    mark_mounts_for_expiry  vmlinux EXPORT_SYMBOL_GPL
++0x8b43159b    register_cpu_notifier   vmlinux EXPORT_SYMBOL
++0xd0d5f859    st_sensors_read_event_config    vmlinux EXPORT_SYMBOL
++0xba490602    nci_to_errno    vmlinux EXPORT_SYMBOL
++0x26cae22e    snd_soc_dapm_free       vmlinux EXPORT_SYMBOL_GPL
++0x6b4f9016    d_set_d_op      vmlinux EXPORT_SYMBOL
++0x6d340f64    tty_termios_input_baud_rate     vmlinux EXPORT_SYMBOL
++0x0d3f57a2    _find_next_bit_le       vmlinux EXPORT_SYMBOL
++0x74e1a843    xfrm_aalg_get_byidx     vmlinux EXPORT_SYMBOL_GPL
++0x56b147ce    unregister_tcf_proto_ops        vmlinux EXPORT_SYMBOL
++0xb6936ffe    _bcd2bin        vmlinux EXPORT_SYMBOL
++0x707f5f40    vb2_fop_write   vmlinux EXPORT_SYMBOL_GPL
++0x598cd828    udp_table       vmlinux EXPORT_SYMBOL
++0x7d0e3e72    ida_get_new_above       vmlinux EXPORT_SYMBOL
++0x2e2f1740    ring_buffer_record_disable_cpu  vmlinux EXPORT_SYMBOL_GPL
++0xafe38346    mmc_erase_group_aligned vmlinux EXPORT_SYMBOL
++0x1af8e94b    nla_put vmlinux EXPORT_SYMBOL
++0xf23fcb99    __kfifo_in      vmlinux EXPORT_SYMBOL
++0xf8ac3a16    revalidate_disk vmlinux EXPORT_SYMBOL
++0xca5967e3    vm_stat vmlinux EXPORT_SYMBOL
++0xd5b1376d    register_shrinker       vmlinux EXPORT_SYMBOL
++0xa6c3a59e    power_supply_am_i_supplied      vmlinux EXPORT_SYMBOL_GPL
++0x35aa9322    regcache_mark_dirty     vmlinux EXPORT_SYMBOL_GPL
++0xbdb14b0b    transport_configure_device      vmlinux EXPORT_SYMBOL_GPL
++0x391c8c77    drm_bl_register vmlinux EXPORT_SYMBOL_GPL
++0x2c744386    ip_tunnel_dellink       vmlinux EXPORT_SYMBOL_GPL
++0xc10022a2    register_sound_dsp      vmlinux EXPORT_SYMBOL
++0x6d29349e    blk_post_runtime_suspend        vmlinux EXPORT_SYMBOL
++0x803eda06    block_invalidatepage    vmlinux EXPORT_SYMBOL
++0x22ba7f9f    may_umount_tree vmlinux EXPORT_SYMBOL
++0x7a944007    rcu_idle_enter  vmlinux EXPORT_SYMBOL_GPL
++0x3ce3f899    iio_device_register     vmlinux EXPORT_SYMBOL
++0x624a6406    hwrng_register  vmlinux EXPORT_SYMBOL_GPL
++0xa408cd5e    misc_register   vmlinux EXPORT_SYMBOL
++0x636b12c8    nf_nat_need_gre vmlinux EXPORT_SYMBOL_GPL
++0xe58ab676    ip_tunnel_init_net      vmlinux EXPORT_SYMBOL_GPL
++0x38c6e66b    udp_lib_get_port        vmlinux EXPORT_SYMBOL
++0x7cda3781    ip_route_input_noref    vmlinux EXPORT_SYMBOL
++0x207ffd0a    kernel_write    vmlinux EXPORT_SYMBOL
++0xbbabb724    tty_ldisc_ref   vmlinux EXPORT_SYMBOL_GPL
++0x899a5d37    rtnl_af_unregister      vmlinux EXPORT_SYMBOL_GPL
++0x1c7f08a9    snd_soc_dapm_del_routes vmlinux EXPORT_SYMBOL_GPL
++0xe71105e8    iget_failed     vmlinux EXPORT_SYMBOL
++0x0fc01e9f    static_key_slow_inc     vmlinux EXPORT_SYMBOL_GPL
++0xbfee3ad5    loop_unregister_transfer        vmlinux EXPORT_SYMBOL
++0xaaef0fd2    class_dev_iter_exit     vmlinux EXPORT_SYMBOL_GPL
++0xd2b18e1d    __of_phy_provider_register      vmlinux EXPORT_SYMBOL_GPL
++0x1751de15    phy_create      vmlinux EXPORT_SYMBOL_GPL
++0x25c677c4    mac_pton        vmlinux EXPORT_SYMBOL
++0xc54cd128    filemap_fdatawait_range vmlinux EXPORT_SYMBOL
++0x05afc379    mmc_cache_ctrl  vmlinux EXPORT_SYMBOL
++0x814e4cf8    cfg80211_chandef_usable vmlinux EXPORT_SYMBOL
++0x829865cd    inode_sub_bytes vmlinux EXPORT_SYMBOL
++0xec602814    inode_set_bytes vmlinux EXPORT_SYMBOL
++0x47e70229    v7_flush_user_cache_range       vmlinux EXPORT_SYMBOL
++0x51cb6360    arp_xmit        vmlinux EXPORT_SYMBOL
++0xc84ab6f8    __dev_getfirstbyhwtype  vmlinux EXPORT_SYMBOL
++0xd499d564    __dev_get_by_index      vmlinux EXPORT_SYMBOL
++0x66a67dab    flex_array_shrink       vmlinux EXPORT_SYMBOL
++0xd41fe818    _raw_read_unlock_irqrestore     vmlinux EXPORT_SYMBOL
++0x47fdbc4f    v4l2_ctrl_new_std       vmlinux EXPORT_SYMBOL
++0xb2fe3cab    mdiobus_register        vmlinux EXPORT_SYMBOL
++0xf70d473a    __inet6_lookup_established      vmlinux EXPORT_SYMBOL
++0x8187321e    snd_timer_interrupt     vmlinux EXPORT_SYMBOL
++0xec5d6a71    __nla_put_nohdr vmlinux EXPORT_SYMBOL
++0xda5506a3    crypto_unregister_instance      vmlinux EXPORT_SYMBOL_GPL
++0xfd361609    bdi_init        vmlinux EXPORT_SYMBOL
++0xf8d88cd8    clk_get vmlinux EXPORT_SYMBOL
++0x22df2dd3    sdio_claim_host vmlinux EXPORT_SYMBOL_GPL
++0x40973662    sysctl_udp_mem  vmlinux EXPORT_SYMBOL
++0x3b50ba06    cpufreq_cooling_register        vmlinux EXPORT_SYMBOL_GPL
++0xb1c29e91    usbnet_probe    vmlinux EXPORT_SYMBOL_GPL
++0x5e1176a3    nfc_hci_send_cmd        vmlinux EXPORT_SYMBOL
++0x1bc8ce1b    inet_csk_accept vmlinux EXPORT_SYMBOL
++0x35cdd9d0    inet_hash_connect       vmlinux EXPORT_SYMBOL_GPL
++0x0334da4e    scsi_command_size_tbl   vmlinux EXPORT_SYMBOL
++0xa843805a    get_unused_fd_flags     vmlinux EXPORT_SYMBOL
++0xb1e25684    __trace_bputs   vmlinux EXPORT_SYMBOL_GPL
++0xb58dcfa2    synchronize_sched_expedited     vmlinux EXPORT_SYMBOL_GPL
++0x17cefda4    cpufreq_cooling_unregister      vmlinux EXPORT_SYMBOL_GPL
++0xc6fca5ad    v4l2_m2m_release        vmlinux EXPORT_SYMBOL_GPL
++0x0614dd5a    v4l2_video_std_frame_period     vmlinux EXPORT_SYMBOL
++0x08195a4e    generic_mii_ioctl       vmlinux EXPORT_SYMBOL
++0xe64e4a5b    drm_select_eld  vmlinux EXPORT_SYMBOL
++0xa3b4f14d    bt_accept_dequeue       vmlinux EXPORT_SYMBOL
++0x8e20620c    tcf_unregister_action   vmlinux EXPORT_SYMBOL
++0x52026cdf    security_sb_parse_opts_str      vmlinux EXPORT_SYMBOL
++0xe82c33bd    usb_bulk_msg    vmlinux EXPORT_SYMBOL_GPL
++0x876abdb2    xfrm_state_delete_tunnel        vmlinux EXPORT_SYMBOL
++0xfdb4778c    sock_edemux     vmlinux EXPORT_SYMBOL
++0x4688d7ec    pvclock_gtod_unregister_notifier        vmlinux EXPORT_SYMBOL_GPL
++0xc6b72634    gserial_connect vmlinux EXPORT_SYMBOL_GPL
++0x55046eb2    platform_device_add_resources   vmlinux EXPORT_SYMBOL_GPL
++0x1b25d2b3    of_pwm_xlate_with_flags vmlinux EXPORT_SYMBOL_GPL
++0x6e1ba077    in6_dev_finish_destroy  vmlinux EXPORT_SYMBOL
++0xecd68a44    tcp_gro_receive vmlinux EXPORT_SYMBOL
++0x922e5568    eth_header      vmlinux EXPORT_SYMBOL
++0xf82ec573    rb_prev vmlinux EXPORT_SYMBOL
++0xfe2f7b7e    jbd2_journal_init_dev   vmlinux EXPORT_SYMBOL
++0xd4114894    bd_unlink_disk_holder   vmlinux EXPORT_SYMBOL_GPL
++0xa9e18049    task_handoff_unregister vmlinux EXPORT_SYMBOL_GPL
++0x4b5366cf    down_killable   vmlinux EXPORT_SYMBOL
++0x1129616d    scsi_rescan_device      vmlinux EXPORT_SYMBOL
++0x9ed554b3    unregister_keyboard_notifier    vmlinux EXPORT_SYMBOL_GPL
++0x3271e6e4    unregister_framebuffer  vmlinux EXPORT_SYMBOL
++0x4acb9a7c    napi_gro_receive        vmlinux EXPORT_SYMBOL
++0x38ed4ee7    netdev_master_upper_dev_get_rcu vmlinux EXPORT_SYMBOL
++0x5ae87753    debugfs_print_regs32    vmlinux EXPORT_SYMBOL_GPL
++0xeac5a47a    clk_notifier_register   vmlinux EXPORT_SYMBOL_GPL
++0xdcc389f7    usb_get_phy     vmlinux EXPORT_SYMBOL_GPL
++0x5cfbd179    phonet_stream_ops       vmlinux EXPORT_SYMBOL
++0xd7ea7094    nf_unregister_queue_handler     vmlinux EXPORT_SYMBOL
++0xa9b804f6    snd_soc_dapm_ignore_suspend     vmlinux EXPORT_SYMBOL_GPL
++0xb04cf0fe    lg_local_unlock vmlinux EXPORT_SYMBOL
++0x24eb7e32    leds_list       vmlinux EXPORT_SYMBOL_GPL
++0xb2f2f502    dev_get_by_flags_rcu    vmlinux EXPORT_SYMBOL
++0x996bdb64    _kstrtoul       vmlinux EXPORT_SYMBOL
++0xd6f8cf35    __block_write_begin     vmlinux EXPORT_SYMBOL
++0x3517383e    register_reboot_notifier        vmlinux EXPORT_SYMBOL
++0x188a3dfb    timespec_trunc  vmlinux EXPORT_SYMBOL
++0x7647726c    handle_sysrq    vmlinux EXPORT_SYMBOL
++0x2a55c54a    l2cap_unregister_user   vmlinux EXPORT_SYMBOL
++0xdaafc807    tcp_sockets_allocated   vmlinux EXPORT_SYMBOL
++0x61618241    netlink_alloc_skb       vmlinux EXPORT_SYMBOL_GPL
++0x883edc99    snd_soc_dapm_weak_routes        vmlinux EXPORT_SYMBOL_GPL
++0x0b20ad4e    inode_owner_or_capable  vmlinux EXPORT_SYMBOL
++0x5ddfdc97    generic_pipe_buf_confirm        vmlinux EXPORT_SYMBOL
++0x27fede28    get_super_thawed        vmlinux EXPORT_SYMBOL
++0x7ff20102    v4l2_s_ctrl     vmlinux EXPORT_SYMBOL
++0x9745d638    drm_err vmlinux EXPORT_SYMBOL
++0x1c1a727a    v4l2_ctrl_subdev_subscribe_event        vmlinux EXPORT_SYMBOL
++0x157df959    usbnet_tx_timeout       vmlinux EXPORT_SYMBOL_GPL
++0x33ca0b9d    scsi_device_quiesce     vmlinux EXPORT_SYMBOL
++0x18a12a47    drm_modeset_unlock_all  vmlinux EXPORT_SYMBOL
++0x59d29dab    v7_flush_kern_dcache_area       vmlinux EXPORT_SYMBOL
++0x9ca80cdd    inet6_protos    vmlinux EXPORT_SYMBOL
++0x58714dc9    snd_soc_jack_add_zones  vmlinux EXPORT_SYMBOL_GPL
++0xdc9110f5    snd_pcm_hw_param_first  vmlinux EXPORT_SYMBOL
++0xf184d189    kernel_power_off        vmlinux EXPORT_SYMBOL_GPL
++0xc8a270a1    usb_put_function        vmlinux EXPORT_SYMBOL_GPL
++0xdfe8f93c    display_entity_get_size vmlinux EXPORT_SYMBOL_GPL
++0x0ef959a5    ip6t_unregister_table   vmlinux EXPORT_SYMBOL
++0x5ee28af3    genl_register_ops       vmlinux EXPORT_SYMBOL
++0xda91a719    snd_pcm_new     vmlinux EXPORT_SYMBOL
++0x8731837f    debugfs_create_u64      vmlinux EXPORT_SYMBOL_GPL
++0x0d350531    block_commit_write      vmlinux EXPORT_SYMBOL
++0xcb62227b    con_copy_unimap vmlinux EXPORT_SYMBOL
++0x9b90584e    tty_ldisc_ref_wait      vmlinux EXPORT_SYMBOL_GPL
++0xf727c5be    __netdev_alloc_skb      vmlinux EXPORT_SYMBOL
++0xf186dfad    wm_hubs_set_bias_level  vmlinux EXPORT_SYMBOL_GPL
++0x5bc4fef5    snd_soc_get_dai_substream       vmlinux EXPORT_SYMBOL_GPL
++0xabefee2b    _snd_pcm_lib_alloc_vmalloc_buffer       vmlinux EXPORT_SYMBOL
++0x5a116367    perf_event_create_kernel_counter        vmlinux EXPORT_SYMBOL_GPL
++0x0bfa3a19    rcu_idle_exit   vmlinux EXPORT_SYMBOL_GPL
++0x90ff6c9f    nf_ct_invert_tuplepr    vmlinux EXPORT_SYMBOL_GPL
++0xf3cd9688    snd_soc_dapm_sync       vmlinux EXPORT_SYMBOL_GPL
++0x68fb4f69    locks_delete_block      vmlinux EXPORT_SYMBOL
++0xdca2a7bb    dput    vmlinux EXPORT_SYMBOL
++0x67a000fa    try_module_get  vmlinux EXPORT_SYMBOL
++0x4790cc27    v4l2_s_ext_ctrls        vmlinux EXPORT_SYMBOL
++0xf39c1176    tty_kref_put    vmlinux EXPORT_SYMBOL
++0x56310925    regulator_mode_to_status        vmlinux EXPORT_SYMBOL_GPL
++0x0825a4fe    regulator_list_voltage_linear   vmlinux EXPORT_SYMBOL_GPL
++0x43db92ba    fb_set_suspend  vmlinux EXPORT_SYMBOL
++0x4993cc2b    register_net_sysctl     vmlinux EXPORT_SYMBOL_GPL
++0x8a490c90    rfkill_set_sw_state     vmlinux EXPORT_SYMBOL
++0xaae97496    snd_soc_bulk_write_raw  vmlinux EXPORT_SYMBOL_GPL
++0xb4dd257b    srcu_notifier_call_chain        vmlinux EXPORT_SYMBOL_GPL
++0x4403ead3    usb_match_one_id        vmlinux EXPORT_SYMBOL_GPL
++0x829a0b6c    screen_glyph    vmlinux EXPORT_SYMBOL_GPL
++0xf7802486    __aeabi_uidivmod        vmlinux EXPORT_SYMBOL
++0x4b8f110e    sk_free vmlinux EXPORT_SYMBOL
++0x4fbbaedb    snd_soc_free_ac97_codec vmlinux EXPORT_SYMBOL_GPL
++0xfd5566cf    scsi_is_sdev_device     vmlinux EXPORT_SYMBOL
++0x17dc8b68    drm_vblank_pre_modeset  vmlinux EXPORT_SYMBOL
++0x7ef39823    ieee80211_hdrlen        vmlinux EXPORT_SYMBOL
++0xc8f36b20    kobject_init    vmlinux EXPORT_SYMBOL
++0xb2e764e8    suspend_valid_only_mem  vmlinux EXPORT_SYMBOL_GPL
++0xfaf9995e    sleep_on        vmlinux EXPORT_SYMBOL
++0x42160169    flush_workqueue vmlinux EXPORT_SYMBOL_GPL
++0xf3251e7b    v4l2_norm_to_name       vmlinux EXPORT_SYMBOL
++0xd7b664df    regulator_list_voltage_table    vmlinux EXPORT_SYMBOL_GPL
++0xfe13b82a    snd_soc_info_enum_ext   vmlinux EXPORT_SYMBOL_GPL
++0x22a8b63d    bio_flush_dcache_pages  vmlinux EXPORT_SYMBOL
++0x0c3d1edb    simple_lookup   vmlinux EXPORT_SYMBOL
++0x4cbc159a    gether_set_dev_addr     vmlinux EXPORT_SYMBOL
++0xdac8e102    gether_get_dev_addr     vmlinux EXPORT_SYMBOL
++0xfa599bb2    netlink_register_notifier       vmlinux EXPORT_SYMBOL
++0xb7e5c788    cgroup_next_descendant_post     vmlinux EXPORT_SYMBOL_GPL
++0xd7dc295c    dm_io   vmlinux EXPORT_SYMBOL
++0xb8698990    usb_match_id    vmlinux EXPORT_SYMBOL_GPL
++0x91a5dbd2    drm_idlelock_take       vmlinux EXPORT_SYMBOL
++0xba86f941    xfrm_policy_insert      vmlinux EXPORT_SYMBOL
++0x2519a629    skb_segment     vmlinux EXPORT_SYMBOL_GPL
++0x2f574814    blk_queue_max_segments  vmlinux EXPORT_SYMBOL
++0xa17232f2    bio_clone_bioset        vmlinux EXPORT_SYMBOL
++0xba2bc8de    unlock_rename   vmlinux EXPORT_SYMBOL
++0x9820b644    warn_slowpath_fmt_taint vmlinux EXPORT_SYMBOL
++0x184b82fb    mmc_vddrange_to_ocrmask vmlinux EXPORT_SYMBOL
++0x0a67ddd9    dm_suspended    vmlinux EXPORT_SYMBOL_GPL
++0xfc8bcbaf    usb_add_hcd     vmlinux EXPORT_SYMBOL_GPL
++0x965d4e18    tcp_init_congestion_ops vmlinux EXPORT_SYMBOL_GPL
++0xe587559a    skb_push        vmlinux EXPORT_SYMBOL
++0x1a32c5c7    blk_run_queue_async     vmlinux EXPORT_SYMBOL
++0x7fa439cd    simple_rmdir    vmlinux EXPORT_SYMBOL
++0xe6790d49    alloc_file      vmlinux EXPORT_SYMBOL
++0xe8214f7a    free_task       vmlinux EXPORT_SYMBOL
++0x2b9e3380    samsung_dmadev_get_ops  vmlinux EXPORT_SYMBOL
++0x8e671fe0    sdio_f0_writeb  vmlinux EXPORT_SYMBOL_GPL
++0x919b5fa4    device_create   vmlinux EXPORT_SYMBOL_GPL
++0x5cf4fc85    psched_ratecfg_precompute       vmlinux EXPORT_SYMBOL
++0x96573b80    __kfifo_dma_in_finish_r vmlinux EXPORT_SYMBOL
++0xf520f285    sysfs_get       vmlinux EXPORT_SYMBOL_GPL
++0x543ef284    seq_hlist_start vmlinux EXPORT_SYMBOL
++0xbfffc4e0    vb2_read        vmlinux EXPORT_SYMBOL_GPL
++0x45f39483    i2c_del_adapter vmlinux EXPORT_SYMBOL
++0x5838f6c9    rtc_valid_tm    vmlinux EXPORT_SYMBOL
++0xb7a638f3    usb_register_driver     vmlinux EXPORT_SYMBOL_GPL
++0xb83a9297    scsi_block_requests     vmlinux EXPORT_SYMBOL
++0xd5d8b6b8    drm_dp_get_adjust_request_pre_emphasis  vmlinux EXPORT_SYMBOL
++0x99c95fa5    unregister_sound_special        vmlinux EXPORT_SYMBOL
++0x056b6c53    fat_dir_empty   vmlinux EXPORT_SYMBOL_GPL
++0xb51c8891    __getblk        vmlinux EXPORT_SYMBOL
++0x1d9658d5    cdev_alloc      vmlinux EXPORT_SYMBOL
++0x1dd73224    st_sensors_i2c_configure        vmlinux EXPORT_SYMBOL
++0x22379ca8    led_blink_set_oneshot   vmlinux EXPORT_SYMBOL
++0xe7e76d97    mmc_release_host        vmlinux EXPORT_SYMBOL
++0x6e04a077    usb_bind_phy    vmlinux EXPORT_SYMBOL_GPL
++0x47d9cfba    sdev_disable_disk_events        vmlinux EXPORT_SYMBOL
++0x142b8b35    drm_buffer_copy_from_user       vmlinux EXPORT_SYMBOL
++0x55f04c21    trace_buffer_unlock_commit_regs vmlinux EXPORT_SYMBOL_GPL
++0x8c333b2b    usb_hcd_unlink_urb_from_ep      vmlinux EXPORT_SYMBOL_GPL
++0x1fa2251f    device_wakeup_enable    vmlinux EXPORT_SYMBOL_GPL
++0xbbe4496d    dev_warn        vmlinux EXPORT_SYMBOL
++0xab3d1f95    nf_ct_untracked_status_or       vmlinux EXPORT_SYMBOL_GPL
++0x131c2452    snd_jack_set_key        vmlinux EXPORT_SYMBOL
++0x74c134b9    __sw_hweight32  vmlinux EXPORT_SYMBOL
++0x57674fd7    __sw_hweight16  vmlinux EXPORT_SYMBOL
++0x9f46ced8    __sw_hweight64  vmlinux EXPORT_SYMBOL
++0x93215e1d    __kfifo_skip_r  vmlinux EXPORT_SYMBOL
++0x1ec4eb34    flex_array_prealloc     vmlinux EXPORT_SYMBOL
++0x01e6b7fa    get_phy_device  vmlinux EXPORT_SYMBOL
++0x391c17d1    wakeup_source_register  vmlinux EXPORT_SYMBOL_GPL
++0xfe85236b    cpu_user        vmlinux EXPORT_SYMBOL
++0x35e62033    pagevec_lookup_tag      vmlinux EXPORT_SYMBOL
++0x34184afe    current_kernel_time     vmlinux EXPORT_SYMBOL
++0x0eb2ceba    tcp_reno_cong_avoid     vmlinux EXPORT_SYMBOL_GPL
++0x2fce25e3    print_tuple     vmlinux EXPORT_SYMBOL_GPL
++0x62496fbf    snd_soc_dai_set_clkdiv  vmlinux EXPORT_SYMBOL_GPL
++0x7505bdef    memchr_inv      vmlinux EXPORT_SYMBOL
++0x3b21bfec    locks_copy_lock vmlinux EXPORT_SYMBOL
++0xb47a0298    hid_dump_report vmlinux EXPORT_SYMBOL_GPL
++0x391147d1    led_trigger_blink       vmlinux EXPORT_SYMBOL_GPL
++0xb65a6bb8    usb_reset_device        vmlinux EXPORT_SYMBOL_GPL
++0x007b6ccf    gnet_stats_start_copy_compat    vmlinux EXPORT_SYMBOL
++0x7522f3ba    irq_modify_status       vmlinux EXPORT_SYMBOL_GPL
++0xd9052a07    rtc_alarm_irq_enable    vmlinux EXPORT_SYMBOL_GPL
++0xcb6dc422    usb_add_config_only     vmlinux EXPORT_SYMBOL_GPL
++0xd38b2d79    inet6_del_protocol      vmlinux EXPORT_SYMBOL
++0x98b8ddd3    xfrm_input_resume       vmlinux EXPORT_SYMBOL
++0xf71914b4    udplite_prot    vmlinux EXPORT_SYMBOL
++0xdc48464a    sock_create_kern        vmlinux EXPORT_SYMBOL
++0x8260686f    bitmap_find_next_zero_area      vmlinux EXPORT_SYMBOL
++0x354ac8ad    scsi_eh_restore_cmnd    vmlinux EXPORT_SYMBOL
++0x6f988f59    transport_remove_device vmlinux EXPORT_SYMBOL_GPL
++0x600f8836    drm_class_device_register       vmlinux EXPORT_SYMBOL_GPL
++0xd589c1c3    sk_clone_lock   vmlinux EXPORT_SYMBOL_GPL
++0xf8798032    d_find_any_alias        vmlinux EXPORT_SYMBOL
++0x56e4cd15    ftrace_event_reg        vmlinux EXPORT_SYMBOL_GPL
++0xab29d75c    thermal_zone_get_zone_by_name   vmlinux EXPORT_SYMBOL_GPL
++0x2a678a13    __suspend_report_result vmlinux EXPORT_SYMBOL_GPL
++0xe36d12fc    drm_gtf_mode    vmlinux EXPORT_SYMBOL
++0x5a48534a    regulator_count_voltages        vmlinux EXPORT_SYMBOL_GPL
++0x2edb3fd8    sk_attach_filter        vmlinux EXPORT_SYMBOL_GPL
++0x8d107d70    sk_detach_filter        vmlinux EXPORT_SYMBOL_GPL
++0x5da176fe    snd_timer_open  vmlinux EXPORT_SYMBOL
++0xf741c793    zlib_deflateEnd vmlinux EXPORT_SYMBOL
++0x7469fcfe    radix_tree_tagged       vmlinux EXPORT_SYMBOL
++0x57c405a5    unload_nls      vmlinux EXPORT_SYMBOL
++0xcaa97c6a    seq_open_private        vmlinux EXPORT_SYMBOL
++0xf3d2b805    st_sensors_get_buffer_element   vmlinux EXPORT_SYMBOL
++0x82286526    vb2_ioctl_create_bufs   vmlinux EXPORT_SYMBOL_GPL
++0xfb7d95b7    fb_set_cmap     vmlinux EXPORT_SYMBOL
++0xed46d9ec    kernel_listen   vmlinux EXPORT_SYMBOL
++0xb1b16346    snd_jack_set_parent     vmlinux EXPORT_SYMBOL
++0x76bf656d    __bitmap_shift_left     vmlinux EXPORT_SYMBOL
++0x1979065a    serio_unregister_driver vmlinux EXPORT_SYMBOL
++0x3a94c8e6    drm_modeset_lock_all    vmlinux EXPORT_SYMBOL
++0xa093e7da    nat_rtp_rtcp_hook       vmlinux EXPORT_SYMBOL_GPL
++0xe23ae481    blk_iopoll_complete     vmlinux EXPORT_SYMBOL
++0x4f6172ff    crypto_chain    vmlinux EXPORT_SYMBOL_GPL
++0xd66a562b    __scsi_device_lookup    vmlinux EXPORT_SYMBOL
++0x9d669763    memcpy  vmlinux EXPORT_SYMBOL
++0x15c5eea4    ip6t_do_table   vmlinux EXPORT_SYMBOL
++0x6b6533af    bdevname        vmlinux EXPORT_SYMBOL
++0x65d67a20    blk_start_plug  vmlinux EXPORT_SYMBOL
++0xdd686f05    cdev_init       vmlinux EXPORT_SYMBOL
++0xbe63ee40    request_resource        vmlinux EXPORT_SYMBOL
++0xb2018900    inet_getname    vmlinux EXPORT_SYMBOL
++0x01610153    nf_ct_expect_init       vmlinux EXPORT_SYMBOL_GPL
++0x04e1b99f    snd_pcm_std_chmaps      vmlinux EXPORT_SYMBOL_GPL
++0x24a42b51    snd_unregister_oss_device       vmlinux EXPORT_SYMBOL
++0x85e7deb2    iov_iter_fault_in_readable      vmlinux EXPORT_SYMBOL
++0x8f049b6c    module_mutex    vmlinux EXPORT_SYMBOL_GPL
++0x931b242d    regcache_sync   vmlinux EXPORT_SYMBOL_GPL
++0xb95f98d6    _memset_io      vmlinux EXPORT_SYMBOL
++0xa98e796e    modify_user_hw_breakpoint       vmlinux EXPORT_SYMBOL_GPL
++0xbf9bcc8d    __cap_empty_set vmlinux EXPORT_SYMBOL
++0xfba8bb33    dm_get_mapinfo  vmlinux EXPORT_SYMBOL
++0x988ad2a2    rndis_set_param_vendor  vmlinux EXPORT_SYMBOL
++0xb67d6992    usb_ep_autoconfig_reset vmlinux EXPORT_SYMBOL_GPL
++0xfbe5910d    drm_mode_config_init    vmlinux EXPORT_SYMBOL
++0x6443df4e    videomode_from_timings  vmlinux EXPORT_SYMBOL_GPL
++0xad059f21    ip_tunnel_changelink    vmlinux EXPORT_SYMBOL_GPL
++0x2c7fb2d0    crypto_shoot_alg        vmlinux EXPORT_SYMBOL_GPL
++0xac226765    iput    vmlinux EXPORT_SYMBOL
++0x77fe4cb2    sleep_on_timeout        vmlinux EXPORT_SYMBOL
++0x1d88a23f    platform_get_resource   vmlinux EXPORT_SYMBOL_GPL
++0xb95beb55    drm_object_property_set_value   vmlinux EXPORT_SYMBOL
++0x8481713b    pn_sock_unhash  vmlinux EXPORT_SYMBOL
++0x28a82da4    snmp_mib_init   vmlinux EXPORT_SYMBOL_GPL
++0x03fd2571    vm_unmap_ram    vmlinux EXPORT_SYMBOL
++0x65466939    proc_doulongvec_ms_jiffies_minmax       vmlinux EXPORT_SYMBOL
++0x23654452    input_ff_upload vmlinux EXPORT_SYMBOL_GPL
++0x45bda0d5    system_serial_low       vmlinux EXPORT_SYMBOL
++0xa682a886    xfrm_output     vmlinux EXPORT_SYMBOL_GPL
++0xeea9dbaf    bitmap_bitremap vmlinux EXPORT_SYMBOL
++0x71a50dbc    register_blkdev vmlinux EXPORT_SYMBOL
++0x43c0e15b    fuse_sync_release       vmlinux EXPORT_SYMBOL_GPL
++0x972213d1    of_phy_connect  vmlinux EXPORT_SYMBOL
++0x95390328    __fimc_vidioc_querycap  vmlinux EXPORT_SYMBOL
++0xe453b342    ipv6_select_ident       vmlinux EXPORT_SYMBOL
++0xabca477d    nf_conntrack_alter_reply        vmlinux EXPORT_SYMBOL_GPL
++0x72c09e90    neigh_event_ns  vmlinux EXPORT_SYMBOL
++0x32590631    snd_soc_update_bits     vmlinux EXPORT_SYMBOL_GPL
++0xb96df73b    elevator_change vmlinux EXPORT_SYMBOL
++0xa30a6f34    jbd2_journal_blocks_per_page    vmlinux EXPORT_SYMBOL
++0x6103b2f2    iterate_supers_type     vmlinux EXPORT_SYMBOL
++0x0a311e2a    iio_read_channel_processed      vmlinux EXPORT_SYMBOL_GPL
++0x89953a68    sdhci_free_host vmlinux EXPORT_SYMBOL_GPL
++0xb8de0d37    dpm_for_each_dev        vmlinux EXPORT_SYMBOL_GPL
++0xe35ba70f    drm_prime_destroy_file_private  vmlinux EXPORT_SYMBOL
++0x1cb4683d    drm_framebuffer_lookup  vmlinux EXPORT_SYMBOL
++0xbaa9e7e0    fb_firmware_edid        vmlinux EXPORT_SYMBOL
++0xa2ede8b2    nf_queue_entry_get_refs vmlinux EXPORT_SYMBOL_GPL
++0x0ff98044    jump_label_rate_limit   vmlinux EXPORT_SYMBOL_GPL
++0x3fd9109b    v4l2_ctrl_subdev_log_status     vmlinux EXPORT_SYMBOL
++0x78cf4589    usb_kill_anchored_urbs  vmlinux EXPORT_SYMBOL_GPL
++0x3b79aef9    request_firmware_nowait vmlinux EXPORT_SYMBOL
++0xab160376    create_syslog_header    vmlinux EXPORT_SYMBOL
++0x6d42bb18    drm_gem_handle_delete   vmlinux EXPORT_SYMBOL
++0x366d19ef    genericbl_limit_intensity       vmlinux EXPORT_SYMBOL
++0x7380780d    cfg80211_unlink_bss     vmlinux EXPORT_SYMBOL
++0xff6b7f32    netdev_change_features  vmlinux EXPORT_SYMBOL
++0x5613414a    init_dummy_netdev       vmlinux EXPORT_SYMBOL_GPL
++0xbd5cb8b9    ring_buffer_resize      vmlinux EXPORT_SYMBOL_GPL
++0xa55e517c    ip_tunnel_xmit  vmlinux EXPORT_SYMBOL_GPL
++0x3b870a79    dst_destroy     vmlinux EXPORT_SYMBOL
++0xad6b883a    usbnet_get_drvinfo      vmlinux EXPORT_SYMBOL_GPL
++0x5df7a89b    nf_ct_helper_expectfn_unregister        vmlinux EXPORT_SYMBOL_GPL
++0x275ef902    __init_waitqueue_head   vmlinux EXPORT_SYMBOL
++0x472b2841    devm_usb_get_phy        vmlinux EXPORT_SYMBOL_GPL
++0x790d8481    scsi_mode_sense vmlinux EXPORT_SYMBOL
++0x2d89342a    scsi_show_sense_hdr     vmlinux EXPORT_SYMBOL
++0xda7ca6cb    fb_mode_is_equal        vmlinux EXPORT_SYMBOL
++0xdc4798d2    xfrm6_tunnel_register   vmlinux EXPORT_SYMBOL
++0xd587e7b5    xfrm4_tunnel_register   vmlinux EXPORT_SYMBOL
++0x360b01a3    nf_ct_get_tuple vmlinux EXPORT_SYMBOL_GPL
++0x6c74c2ee    blk_insert_cloned_request       vmlinux EXPORT_SYMBOL_GPL
++0x46cb2731    security_sb_set_mnt_opts        vmlinux EXPORT_SYMBOL
++0x1b995ffb    iommu_domain_window_enable      vmlinux EXPORT_SYMBOL_GPL
++0xa4ea04ee    of_property_read_u64    vmlinux EXPORT_SYMBOL_GPL
++0x411e4ef5    brcmu_pktq_pdeq_tail    drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x422d82d0    brcmu_pktq_penq_head    drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x41cc94d0    brcmu_pktq_peek_tail    drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x0c6f118f    nf_nat_icmpv6_reply_translation vmlinux EXPORT_SYMBOL_GPL
++0xa07842c6    skb_copy_datagram_from_iovec    vmlinux EXPORT_SYMBOL
++0xc8269f94    snd_soc_params_to_frame_size    vmlinux EXPORT_SYMBOL_GPL
++0x43eeb6cf    snd_pcm_lib_ioctl       vmlinux EXPORT_SYMBOL
++0x9ac11b74    suspend_set_ops vmlinux EXPORT_SYMBOL_GPL
++0xca16dbe7    regulator_enable        vmlinux EXPORT_SYMBOL_GPL
++0xecc84eb2    dst_alloc       vmlinux EXPORT_SYMBOL
++0xf0f5dbc2    timerqueue_iterate_next vmlinux EXPORT_SYMBOL_GPL
++0xab4a5add    blk_put_queue   vmlinux EXPORT_SYMBOL
++0x11bef8bd    single_release  vmlinux EXPORT_SYMBOL
++0x7aad72c6    get_user_pages  vmlinux EXPORT_SYMBOL
++0x6214aef2    cpufreq_unregister_notifier     vmlinux EXPORT_SYMBOL
++0xe93e49c3    devres_free     vmlinux EXPORT_SYMBOL_GPL
++0xd95fbe77    of_find_backlight_by_node       vmlinux EXPORT_SYMBOL
++0xe3f553d9    ip6_append_data vmlinux EXPORT_SYMBOL_GPL
++0xa108eb4d    sysctl_optmem_max       vmlinux EXPORT_SYMBOL
++0xdc323ca6    jbd2_journal_destroy    vmlinux EXPORT_SYMBOL
++0x3c7a1672    jbd2_journal_restart    vmlinux EXPORT_SYMBOL
++0x9805d460    v4l2_device_register    vmlinux EXPORT_SYMBOL_GPL
++0x1db6d990    display_entity_get_first        vmlinux EXPORT_SYMBOL
++0xe57878a1    in6_pton        vmlinux EXPORT_SYMBOL
++0xaccabc6a    in4_pton        vmlinux EXPORT_SYMBOL
++0xd0181f4f    __bitmap_xor    vmlinux EXPORT_SYMBOL
++0x208c317e    mnt_want_write  vmlinux EXPORT_SYMBOL_GPL
++0xbcdedba7    of_get_mac_address      vmlinux EXPORT_SYMBOL
++0x859bbb79    scsi_mode_select        vmlinux EXPORT_SYMBOL_GPL
++0x48991892    cfb_copyarea    vmlinux EXPORT_SYMBOL
++0x2455c156    __clear_user    vmlinux EXPORT_SYMBOL
++0x42c7d35b    __dev_remove_pack       vmlinux EXPORT_SYMBOL
++0x465cab34    secure_ipv6_port_ephemeral      vmlinux EXPORT_SYMBOL
++0x5ddbac94    config_group_init       vmlinux EXPORT_SYMBOL
++0x773c1fdc    posix_acl_to_xattr      vmlinux EXPORT_SYMBOL
++0xb18429eb    suspend_device_irqs     vmlinux EXPORT_SYMBOL_GPL
++0x50c52151    _raw_write_unlock_irq   vmlinux EXPORT_SYMBOL
++0xf5bc65a3    iommu_unmap     vmlinux EXPORT_SYMBOL_GPL
++0x710e2b07    tcf_hash_insert vmlinux EXPORT_SYMBOL
++0xf13feb57    radix_tree_next_chunk   vmlinux EXPORT_SYMBOL
++0x90a1004a    crypto_has_alg  vmlinux EXPORT_SYMBOL_GPL
++0x8cd44e50    iget5_locked    vmlinux EXPORT_SYMBOL
++0x3dcb88a0    irq_set_handler_data    vmlinux EXPORT_SYMBOL
++0xaa7de358    yield_to        vmlinux EXPORT_SYMBOL_GPL
++0xc54649ff    __starget_for_each_device       vmlinux EXPORT_SYMBOL
++0x2bd1f745    drm_mode_config_cleanup vmlinux EXPORT_SYMBOL
++0xa1425906    ieee80211_channel_to_frequency  vmlinux EXPORT_SYMBOL
++0x59806cb9    sk_page_frag_refill     vmlinux EXPORT_SYMBOL
++0xce90ef6b    debugfs_create_dir      vmlinux EXPORT_SYMBOL_GPL
++0xa4827144    dcache_dir_lseek        vmlinux EXPORT_SYMBOL
++0x0c2cdbf1    synchronize_sched       vmlinux EXPORT_SYMBOL_GPL
++0x92a9c60c    time_to_tm      vmlinux EXPORT_SYMBOL
++0x651a4139    test_taint      vmlinux EXPORT_SYMBOL
++0x2b66e1b8    mii_check_media vmlinux EXPORT_SYMBOL
++0xfb7d9c45    __udivsi3       vmlinux EXPORT_SYMBOL
++0x633fafc5    netdev_printk   vmlinux EXPORT_SYMBOL
++0xf5a691cd    invalidate_bh_lrus      vmlinux EXPORT_SYMBOL_GPL
++0xe5524eab    of_address_to_resource  vmlinux EXPORT_SYMBOL_GPL
++0xe22f01b0    thermal_zone_device_register    vmlinux EXPORT_SYMBOL_GPL
++0x3fc8bae1    ipcomp_init_state       vmlinux EXPORT_SYMBOL_GPL
++0xf5b5f1ec    xt_check_match  vmlinux EXPORT_SYMBOL_GPL
++0x24aac4d9    crypto_aes_expand_key   vmlinux EXPORT_SYMBOL_GPL
++0x6f798a9c    d_splice_alias  vmlinux EXPORT_SYMBOL
++0x88196936    do_sync_read    vmlinux EXPORT_SYMBOL
++0x4a18707e    mem_map vmlinux EXPORT_SYMBOL
++0x0366307a    console_suspend_enabled vmlinux EXPORT_SYMBOL
++0x204d506e    st_sensors_write_event_value    vmlinux EXPORT_SYMBOL
++0x4c22a54d    usb_ep_autoconfig       vmlinux EXPORT_SYMBOL_GPL
++0x32c3cb4e    class_compat_register   vmlinux EXPORT_SYMBOL_GPL
++0x7b85f6f8    drm_mm_insert_node      vmlinux EXPORT_SYMBOL
++0x78f9b710    nf_ct_l3proto_try_module_get    vmlinux EXPORT_SYMBOL_GPL
++0x44594236    snd_soc_unregister_component    vmlinux EXPORT_SYMBOL_GPL
++0x05e4e6be    register_sound_midi     vmlinux EXPORT_SYMBOL
++0x07341a03    kobject_rename  vmlinux EXPORT_SYMBOL_GPL
++0x35b6b772    param_ops_charp vmlinux EXPORT_SYMBOL
++0xb4c1829e    clk_round_rate  vmlinux EXPORT_SYMBOL_GPL
++0x1bb061cc    sdio_release_irq        vmlinux EXPORT_SYMBOL_GPL
++0xe4c673df    mmc_wait_for_cmd        vmlinux EXPORT_SYMBOL
++0x4d088d1f    drm_mm_replace_node     vmlinux EXPORT_SYMBOL
++0xe24e09b0    cgroup_taskset_cur_cgroup       vmlinux EXPORT_SYMBOL_GPL
++0x7c5cf140    cad_pid vmlinux EXPORT_SYMBOL
++0xaea8b9a5    drm_get_encoder_name    vmlinux EXPORT_SYMBOL
++0xe4c80097    cacheid vmlinux EXPORT_SYMBOL
++0x5a5a94a6    kstrtou8        vmlinux EXPORT_SYMBOL
++0x2b4aa9c9    get_task_pid    vmlinux EXPORT_SYMBOL_GPL
++0x30f43c3b    sdhci_enable_irq_wakeups        vmlinux EXPORT_SYMBOL_GPL
++0x3a6d4f22    rndis_free_response     vmlinux EXPORT_SYMBOL
++0x85478a0b    inet6_hash_frag vmlinux EXPORT_SYMBOL_GPL
++0x0efbc42d    snd_component_add       vmlinux EXPORT_SYMBOL
++0x6605f97f    flex_array_clear        vmlinux EXPORT_SYMBOL
++0x5a7bfe41    crypto_probing_notify   vmlinux EXPORT_SYMBOL_GPL
++0x94fd7214    serial8250_rx_chars     vmlinux EXPORT_SYMBOL_GPL
++0x13a6027a    ip6t_alloc_initial_table        vmlinux EXPORT_SYMBOL_GPL
++0x03a9a7bd    netif_receive_skb       vmlinux EXPORT_SYMBOL
++0xfb6af58d    recalc_sigpending       vmlinux EXPORT_SYMBOL
++0x2d0ea593    spi_new_device  vmlinux EXPORT_SYMBOL_GPL
++0xfbc4e14c    pm_runtime_enable       vmlinux EXPORT_SYMBOL_GPL
++0xc583bf57    of_regulator_match      vmlinux EXPORT_SYMBOL_GPL
++0xebfdcbdf    system_serial_high      vmlinux EXPORT_SYMBOL
++0x28d7fc1f    nf_nat_mangle_udp_packet        vmlinux EXPORT_SYMBOL
++0xf71016b7    snd_soc_dapm_get_pin_status     vmlinux EXPORT_SYMBOL_GPL
++0xf05c8ab1    vb2_get_contig_userptr  vmlinux EXPORT_SYMBOL_GPL
++0xd045db89    nfc_class       vmlinux EXPORT_SYMBOL
++0x606340d3    disk_part_iter_exit     vmlinux EXPORT_SYMBOL_GPL
++0xa1bd7822    __tracepoint_block_bio_complete vmlinux EXPORT_SYMBOL_GPL
++0x16138f6f    follow_down_one vmlinux EXPORT_SYMBOL
++0x7944e0fc    tracing_off     vmlinux EXPORT_SYMBOL_GPL
++0xb1425b32    dm_table_add_target_callbacks   vmlinux EXPORT_SYMBOL_GPL
++0xbdfb8830    anon_transport_class_register   vmlinux EXPORT_SYMBOL_GPL
++0x911d700e    devm_phy_create vmlinux EXPORT_SYMBOL_GPL
++0xeb908d00    raw_seq_next    vmlinux EXPORT_SYMBOL_GPL
++0x30b265dd    ip_setsockopt   vmlinux EXPORT_SYMBOL
++0x9f45de2c    ip_getsockopt   vmlinux EXPORT_SYMBOL
++0x30322337    nf_ct_l3proto_unregister        vmlinux EXPORT_SYMBOL_GPL
++0x8106c2de    nf_ct_l4proto_unregister        vmlinux EXPORT_SYMBOL_GPL
++0x4b015768    snd_iprintf     vmlinux EXPORT_SYMBOL
++0xec728ca6    blk_unprep_request      vmlinux EXPORT_SYMBOL_GPL
++0x0bae62b1    ktime_get_monotonic_offset      vmlinux EXPORT_SYMBOL_GPL
++0x6f8450af    tty_encode_baud_rate    vmlinux EXPORT_SYMBOL_GPL
++0xead6a706    devm_phy_destroy        vmlinux EXPORT_SYMBOL_GPL
++0x2cf3c356    ip6_redirect    vmlinux EXPORT_SYMBOL_GPL
++0x2cdb55d1    ip_options_rcv_srr      vmlinux EXPORT_SYMBOL
++0x105bdf9b    dentry_open     vmlinux EXPORT_SYMBOL
++0x724bf4b2    i2c_bit_add_numbered_bus        vmlinux EXPORT_SYMBOL
++0x2e09263f    usb_copy_descriptors    vmlinux EXPORT_SYMBOL_GPL
++0xbec98305    device_register vmlinux EXPORT_SYMBOL_GPL
++0xff519474    skb_checksum_help       vmlinux EXPORT_SYMBOL
++0x293d87a4    unregister_netdevice_queue      vmlinux EXPORT_SYMBOL
++0xa692560a    snd_soc_lookup_platform vmlinux EXPORT_SYMBOL_GPL
++0x9545af6d    tasklet_init    vmlinux EXPORT_SYMBOL
++0x87374f66    extcon_unregister_interest      vmlinux EXPORT_SYMBOL_GPL
++0x40a27c37    scsi_dev_info_remove_list       vmlinux EXPORT_SYMBOL
++0x42a2164f    regmap_write    vmlinux EXPORT_SYMBOL_GPL
++0xe6f46e6e    drm_clflush_virt_range  vmlinux EXPORT_SYMBOL
++0x17f8217b    nf_nat_setup_info       vmlinux EXPORT_SYMBOL
++0xb3daf4bf    jbd2_journal_get_undo_access    vmlinux EXPORT_SYMBOL
++0xe16591ab    stop_machine    vmlinux EXPORT_SYMBOL_GPL
++0xb6261484    register_die_notifier   vmlinux EXPORT_SYMBOL_GPL
++0x415838be    led_trigger_set_default vmlinux EXPORT_SYMBOL_GPL
++0x843020c0    ip6_find_1stfragopt     vmlinux EXPORT_SYMBOL
++0x062936ed    nf_ct_unlink_expect_report      vmlinux EXPORT_SYMBOL_GPL
++0xa6d16c61    sock_no_recvmsg vmlinux EXPORT_SYMBOL
++0x4b0ac955    hrtimer_cancel  vmlinux EXPORT_SYMBOL_GPL
++0x3626ebf4    xt_unregister_matches   vmlinux EXPORT_SYMBOL
++0x72ea7812    security_inode_setattr  vmlinux EXPORT_SYMBOL_GPL
++0xfdfc0b3b    fiemap_fill_next_extent vmlinux EXPORT_SYMBOL
++0x82d19daa    qdisc_watchdog_cancel   vmlinux EXPORT_SYMBOL
++0xc0581ee5    crypto_shash_digest     vmlinux EXPORT_SYMBOL_GPL
++0x78728b6b    crypto_ahash_digest     vmlinux EXPORT_SYMBOL_GPL
++0x3de9cae1    crypto_remove_final     vmlinux EXPORT_SYMBOL_GPL
++0x31faa864    media_entity_init       vmlinux EXPORT_SYMBOL_GPL
++0xe827112b    rtnl_set_sk_err vmlinux EXPORT_SYMBOL
++0x5b23591f    snd_soc_jack_new        vmlinux EXPORT_SYMBOL_GPL
++0x7b6646bb    _raw_read_lock  vmlinux EXPORT_SYMBOL
++0xd4669fad    complete        vmlinux EXPORT_SYMBOL
++0x488882e7    downgrade_write vmlinux EXPORT_SYMBOL
++0xbaac427c    get_mem_type    vmlinux EXPORT_SYMBOL
++0xc4014b9d    ip_check_defrag vmlinux EXPORT_SYMBOL
++0x6aaccee0    config_item_init_type_name      vmlinux EXPORT_SYMBOL
++0x62822d05    iov_iter_single_seg_count       vmlinux EXPORT_SYMBOL
++0xb1f1a6ea    gether_get_host_addr_u8 vmlinux EXPORT_SYMBOL
++0xf7f652fe    dma_mmap_from_coherent  vmlinux EXPORT_SYMBOL
++0xfa9720a0    rdev_get_dev    vmlinux EXPORT_SYMBOL_GPL
++0x62186db5    brcmu_pkt_buf_get_skb   drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0xf7af6d75    snd_pcm_new_stream      vmlinux EXPORT_SYMBOL
++0x17320c5c    dentry_update_name_case vmlinux EXPORT_SYMBOL
++0x8a7d1c31    high_memory     vmlinux EXPORT_SYMBOL
++0x0186e2de    smp_call_function_many  vmlinux EXPORT_SYMBOL
++0xbdf098ae    scsi_test_unit_ready    vmlinux EXPORT_SYMBOL
++0x119b50e7    elf_check_arch  vmlinux EXPORT_SYMBOL
++0xbf6d5c21    inet6_csk_update_pmtu   vmlinux EXPORT_SYMBOL_GPL
++0x6b9a4457    snd_soc_jack_free_gpios vmlinux EXPORT_SYMBOL_GPL
++0xd28c735f    simple_link     vmlinux EXPORT_SYMBOL
++0xbdd2f42a    rcu_bh_force_quiescent_state    vmlinux EXPORT_SYMBOL_GPL
++0x7a3cd015    v4l2_ctrl_get_menu      vmlinux EXPORT_SYMBOL
++0x97f5694d    page_cache_async_readahead      vmlinux EXPORT_SYMBOL_GPL
++0x2b4e956e    mempool_create  vmlinux EXPORT_SYMBOL
++0x57231f45    ring_buffer_record_on   vmlinux EXPORT_SYMBOL_GPL
++0x8e311007    hidinput_find_field     vmlinux EXPORT_SYMBOL_GPL
++0x7ae1ae8e    cpufreq_frequency_table_put_attr        vmlinux EXPORT_SYMBOL_GPL
++0x6c6a4b95    scsi_remove_target      vmlinux EXPORT_SYMBOL
++0xb6c5a973    scsi_show_result        vmlinux EXPORT_SYMBOL
++0x1ec3bed9    hdmi_audio_infoframe_init       vmlinux EXPORT_SYMBOL
++0x3244dece    kblockd_schedule_work   vmlinux EXPORT_SYMBOL
++0xafac4a33    mem_section     vmlinux EXPORT_SYMBOL
++0xfd044751    send_sig_info   vmlinux EXPORT_SYMBOL
++0xc02cf69b    clkdev_drop     vmlinux EXPORT_SYMBOL
++0x39c95e24    phy_init_eee    vmlinux EXPORT_SYMBOL
++0xfc53eac8    drm_cvt_mode    vmlinux EXPORT_SYMBOL
++0x6a5e6530    __neigh_event_send      vmlinux EXPORT_SYMBOL
++0x6c4d4cfe    sk_stream_wait_close    vmlinux EXPORT_SYMBOL
++0x3d1cdeca    read_cache_page_async   vmlinux EXPORT_SYMBOL
++0xd0ee38b8    schedule_timeout_uninterruptible        vmlinux EXPORT_SYMBOL
++0xd79b5a02    allow_signal    vmlinux EXPORT_SYMBOL
++0xd14fa335    show_class_attr_string  vmlinux EXPORT_SYMBOL_GPL
++0xacb2a583    ndo_dflt_fdb_add        vmlinux EXPORT_SYMBOL
++0x49a39542    snd_timer_global_register       vmlinux EXPORT_SYMBOL
++0x63407037    kill_anon_super vmlinux EXPORT_SYMBOL
++0xdc2b4205    platform_get_irq        vmlinux EXPORT_SYMBOL_GPL
++0xc777ecaa    xfrm6_rcv       vmlinux EXPORT_SYMBOL
++0x2fee3a7e    xfrm4_rcv       vmlinux EXPORT_SYMBOL
++0xe94fef47    nf_ct_delete_from_lists vmlinux EXPORT_SYMBOL_GPL
++0x6d466653    snd_soc_unregister_platform     vmlinux EXPORT_SYMBOL_GPL
++0xb61a0c3b    bt_err  vmlinux EXPORT_SYMBOL
++0x79536600    snd_soc_dpcm_can_be_params      vmlinux EXPORT_SYMBOL_GPL
++0x016c4bc3    cfg80211_put_bss        vmlinux EXPORT_SYMBOL
++0x90922aec    inet_dgram_connect      vmlinux EXPORT_SYMBOL
++0x103ea6ec    generic_pipe_buf_steal  vmlinux EXPORT_SYMBOL
++0x5fe77756    generic_pipe_buf_unmap  vmlinux EXPORT_SYMBOL
++0xe5d95985    param_ops_ulong vmlinux EXPORT_SYMBOL
++0xb03c01e8    dbs_check_cpu   vmlinux EXPORT_SYMBOL_GPL
++0xff15acd6    usb_put_function_instance       vmlinux EXPORT_SYMBOL_GPL
++0x6406cdf0    usb_find_alt_setting    vmlinux EXPORT_SYMBOL_GPL
++0x4626bf6d    phy_connect     vmlinux EXPORT_SYMBOL
++0x7a9326c6    driver_unregister       vmlinux EXPORT_SYMBOL_GPL
++0xc5570382    inet_frags_exit_net     vmlinux EXPORT_SYMBOL
++0x08216276    kobject_get     vmlinux EXPORT_SYMBOL
++0x006818a5    kobject_put     vmlinux EXPORT_SYMBOL
++0x37b777df    param_set_copystring    vmlinux EXPORT_SYMBOL
++0x54f21cff    __send_remote_softirq   vmlinux EXPORT_SYMBOL
++0x7a925833    cpufreq_get_global_kobject      vmlinux EXPORT_SYMBOL
++0x2c900d91    cpufreq_put_global_kobject      vmlinux EXPORT_SYMBOL
++0xbac4a225    v4l2_ctrl_fill  vmlinux EXPORT_SYMBOL
++0xf7e6e534    v4l2_ctrl_find  vmlinux EXPORT_SYMBOL
++0xbc5671dc    v4l_printk_ioctl        vmlinux EXPORT_SYMBOL
++0x17021c93    drm_i2c_encoder_commit  vmlinux EXPORT_SYMBOL
++0x10e70fd2    display_entity_get_modes        vmlinux EXPORT_SYMBOL_GPL
++0xf1deabf2    div64_u64       vmlinux EXPORT_SYMBOL
++0x2488515b    vb2_put_vma     vmlinux EXPORT_SYMBOL_GPL
++0xd2ea2134    usb_descriptor_fillbuf  vmlinux EXPORT_SYMBOL_GPL
++0xdacd26c5    usb_scuttle_anchored_urbs       vmlinux EXPORT_SYMBOL_GPL
++0xfc39e32f    ioport_unmap    vmlinux EXPORT_SYMBOL
++0x348998d3    sysfs_merge_group       vmlinux EXPORT_SYMBOL_GPL
++0xc84a0a7e    seq_hlist_start_rcu     vmlinux EXPORT_SYMBOL
++0xdd51deeb    d_validate      vmlinux EXPORT_SYMBOL
++0x88ea60db    __get_user_pages_fast   vmlinux EXPORT_SYMBOL_GPL
++0xe9bff861    down_trylock    vmlinux EXPORT_SYMBOL
++0xff9e0620    usb_reset_configuration vmlinux EXPORT_SYMBOL_GPL
++0x00130217    pwm_free        vmlinux EXPORT_SYMBOL_GPL
++0x8fedcd53    snd_soc_info_xr_sx      vmlinux EXPORT_SYMBOL_GPL
++0xc256e762    __bitmap_equal  vmlinux EXPORT_SYMBOL
++0x7d4e2276    __init_rwsem    vmlinux EXPORT_SYMBOL
++0xee5a877d    page_zero_new_buffers   vmlinux EXPORT_SYMBOL
++0x96710252    mntget  vmlinux EXPORT_SYMBOL
++0xe85c78e2    mntput  vmlinux EXPORT_SYMBOL
++0x038e97d3    fasync_helper   vmlinux EXPORT_SYMBOL
++0xf75c7d80    wm8994_mic_detect       vmlinux EXPORT_SYMBOL_GPL
++0x2f4113a2    dcookie_register        vmlinux EXPORT_SYMBOL_GPL
++0xce37be95    locks_mandatory_area    vmlinux EXPORT_SYMBOL
++0x8be294cd    iommu_domain_free       vmlinux EXPORT_SYMBOL_GPL
++0x23b5b8d1    exynos_drm_subdrv_register      vmlinux EXPORT_SYMBOL_GPL
++0x6867f405    inet_twsk_deschedule    vmlinux EXPORT_SYMBOL
++0x244e2178    xt_table_unlock vmlinux EXPORT_SYMBOL_GPL
++0x52b9d131    tcf_exts_dump_stats     vmlinux EXPORT_SYMBOL
++0x48bb9eb5    sock_alloc_send_pskb    vmlinux EXPORT_SYMBOL
++0x757206d5    wm_hubs_spkmix_tlv      vmlinux EXPORT_SYMBOL_GPL
++0x0acb1a3c    __bitmap_shift_right    vmlinux EXPORT_SYMBOL
++0xaaa918c9    ftrace_dump     vmlinux EXPORT_SYMBOL_GPL
++0x402b8281    __request_module        vmlinux EXPORT_SYMBOL
++0xe944ba87    st_sensors_set_axis_enable      vmlinux EXPORT_SYMBOL
++0x822f9003    inet_register_protosw   vmlinux EXPORT_SYMBOL
++0xbe3a4f06    __inet_inherit_port     vmlinux EXPORT_SYMBOL_GPL
++0xb63f16de    dev_deactivate  vmlinux EXPORT_SYMBOL
++0xa014da84    snd_soc_add_platform_controls   vmlinux EXPORT_SYMBOL_GPL
++0xeaaee9e6    submit_bio_wait vmlinux EXPORT_SYMBOL
++0x23fd3028    vmalloc_node    vmlinux EXPORT_SYMBOL
++0xa58fea9d    mempool_destroy vmlinux EXPORT_SYMBOL
++0x054e550b    kernel_halt     vmlinux EXPORT_SYMBOL_GPL
++0xf4c770ec    v4l2_clk_disable        vmlinux EXPORT_SYMBOL
++0xd597e74e    phy_find_first  vmlinux EXPORT_SYMBOL
++0x50621015    xfrm6_tunnel_spi_lookup vmlinux EXPORT_SYMBOL
++0xc0f8a5b0    set_binfmt      vmlinux EXPORT_SYMBOL
++0x36075bb5    iommu_group_register_notifier   vmlinux EXPORT_SYMBOL_GPL
++0x93b8b0d3    scsi_ioctl      vmlinux EXPORT_SYMBOL
++0xd0dcdd90    drm_mm_insert_node_in_range_generic     vmlinux EXPORT_SYMBOL
++0xb2eaff96    km_policy_expired       vmlinux EXPORT_SYMBOL
++0xa9effda5    __first_cpu     vmlinux EXPORT_SYMBOL
++0xc24ba3ed    elv_rb_find     vmlinux EXPORT_SYMBOL
++0xf0619801    timekeeping_clocktai    vmlinux EXPORT_SYMBOL
++0x9e4faeef    dm_io_client_destroy    vmlinux EXPORT_SYMBOL
++0x95cbb942    usb_add_gadget_udc_release      vmlinux EXPORT_SYMBOL_GPL
++0x14c3db3e    spi_unregister_master   vmlinux EXPORT_SYMBOL_GPL
++0xbee90f2f    __kfifo_out_peek_r      vmlinux EXPORT_SYMBOL
++0x2869ebaf    regulator_bulk_force_disable    vmlinux EXPORT_SYMBOL_GPL
++0xa04a01bd    qdisc_class_hash_insert vmlinux EXPORT_SYMBOL
++0x43a261a8    eth_commit_mac_addr_change      vmlinux EXPORT_SYMBOL
++0xe5867808    dlci_ioctl_set  vmlinux EXPORT_SYMBOL
++0xbae6da94    crypto_alg_lookup       vmlinux EXPORT_SYMBOL_GPL
++0x330d748a    v4l2_subdev_init        vmlinux EXPORT_SYMBOL
++0xc6ff1a7d    phonet_header_ops       vmlinux EXPORT_SYMBOL
++0xfaefacf3    locks_free_lock vmlinux EXPORT_SYMBOL
++0xcbfa0b41    scsi_report_device_reset        vmlinux EXPORT_SYMBOL
++0xbe1e4cd0    scsi_print_sense        vmlinux EXPORT_SYMBOL
++0xe87ed821    drm_mode_create_dirty_info_property     vmlinux EXPORT_SYMBOL
++0xb6d97288    inet6_add_offload       vmlinux EXPORT_SYMBOL
++0xa681ec81    snd_soc_jack_notifier_register  vmlinux EXPORT_SYMBOL_GPL
++0xd64b88b6    register_sound_mixer    vmlinux EXPORT_SYMBOL
++0x02701efc    simple_attr_release     vmlinux EXPORT_SYMBOL_GPL
++0xf6e04730    event_storage   vmlinux EXPORT_SYMBOL_GPL
++0x95b5af62    mmc_regulator_set_ocr   vmlinux EXPORT_SYMBOL_GPL
++0x77e78218    regulator_allow_bypass  vmlinux EXPORT_SYMBOL_GPL
++0xf1070592    cfg80211_wext_giwretry  vmlinux EXPORT_SYMBOL_GPL
++0x8a0f4230    rename_lock     vmlinux EXPORT_SYMBOL
++0xda259c5d    page_symlink_inode_operations   vmlinux EXPORT_SYMBOL
++0x8bd0a3fd    _raw_write_unlock_bh    vmlinux EXPORT_SYMBOL
++0x99b0f1ff    usb_submit_urb  vmlinux EXPORT_SYMBOL_GPL
++0x1fbd16da    ip_tos2prio     vmlinux EXPORT_SYMBOL
++0x060ea2d6    kstrtoull       vmlinux EXPORT_SYMBOL
++0x5ac15bae    kstrtou16       vmlinux EXPORT_SYMBOL
++0x1998d8b6    jbd2_inode_cache        vmlinux EXPORT_SYMBOL
++0x94961283    vunmap  vmlinux EXPORT_SYMBOL
++0x74c4a01e    write_cache_pages       vmlinux EXPORT_SYMBOL
++0xc1ddc02b    pinctrl_register        vmlinux EXPORT_SYMBOL_GPL
++0x0ca54fee    _test_and_set_bit       vmlinux EXPORT_SYMBOL
++0x80dfa464    xfrm_policy_alloc       vmlinux EXPORT_SYMBOL
++0xd04f8eb6    nf_conntrack_l4proto_tcp6       vmlinux EXPORT_SYMBOL_GPL
++0xcf28b516    finish_open     vmlinux EXPORT_SYMBOL
++0x10f734ff    led_blink_set   vmlinux EXPORT_SYMBOL
++0xc9086110    dw_mci_pltfm_remove     vmlinux EXPORT_SYMBOL_GPL
++0xe5c78a99    do_blank_screen vmlinux EXPORT_SYMBOL
++0xf17c6528    cfg80211_remain_on_channel_expired      vmlinux EXPORT_SYMBOL
++0x117093be    qdisc_class_hash_init   vmlinux EXPORT_SYMBOL
++0x13e6a1a2    sk_prot_clear_portaddr_nulls    vmlinux EXPORT_SYMBOL
++0xa2a2d730    task_current_syscall    vmlinux EXPORT_SYMBOL_GPL
++0x4411c503    prandom_seed    vmlinux EXPORT_SYMBOL
++0x547ba3f6    single_open_net vmlinux EXPORT_SYMBOL_GPL
++0xb9012717    set_page_dirty_lock     vmlinux EXPORT_SYMBOL
++0x9a37cbf4    tcp_v4_conn_request     vmlinux EXPORT_SYMBOL
++0xc81ae040    snd_soc_codec_volatile_register vmlinux EXPORT_SYMBOL_GPL
++0xbe52317a    blk_rq_init     vmlinux EXPORT_SYMBOL
++0x9ef34ad4    cpufreq_frequency_table_cpuinfo vmlinux EXPORT_SYMBOL_GPL
++0x5bcf159d    usb_get_descriptor      vmlinux EXPORT_SYMBOL_GPL
++0xf2e5cabe    spi_async_locked        vmlinux EXPORT_SYMBOL_GPL
++0x26e76fb8    sysctl_udp_wmem_min     vmlinux EXPORT_SYMBOL
++0x1fb12a69    tcp_v4_syn_recv_sock    vmlinux EXPORT_SYMBOL
++0x6d464175    __sg_free_table vmlinux EXPORT_SYMBOL
++0x59056c08    kmem_cache_shrink       vmlinux EXPORT_SYMBOL
++0xc3aef602    usb_put_dev     vmlinux EXPORT_SYMBOL_GPL
++0x520a3baf    drm_vm_open_locked      vmlinux EXPORT_SYMBOL_GPL
++0x711a004a    drm_dp_link_rate_to_bw_code     vmlinux EXPORT_SYMBOL
++0x919029aa    __readwrite_bug vmlinux EXPORT_SYMBOL
++0x49045426    icmp_err_convert        vmlinux EXPORT_SYMBOL
++0xf087137d    __dynamic_pr_debug      vmlinux EXPORT_SYMBOL
++0x1e5b03dc    pm_qos_add_notifier     vmlinux EXPORT_SYMBOL_GPL
++0x5e9d9e1e    gov_queue_work  vmlinux EXPORT_SYMBOL_GPL
++0x601f665f    dm_io_client_create     vmlinux EXPORT_SYMBOL
++0x05c311c2    vb2_ioctl_prepare_buf   vmlinux EXPORT_SYMBOL_GPL
++0x14f62d2b    mii_check_link  vmlinux EXPORT_SYMBOL
++0x36c69db7    dma_common_mmap vmlinux EXPORT_SYMBOL
++0x1072a394    csum_partial_copy_from_user     vmlinux EXPORT_SYMBOL
++0x3f878645    inet_diag_dump_one_icsk vmlinux EXPORT_SYMBOL_GPL
++0xd7b85107    tcp_hashinfo    vmlinux EXPORT_SYMBOL
++0x2d140a58    genl_unlock     vmlinux EXPORT_SYMBOL
++0xeed1b62f    crypto_aead_setauthsize vmlinux EXPORT_SYMBOL_GPL
++0x5f7bdc58    fd_install      vmlinux EXPORT_SYMBOL
++0xe11f3cbc    _raw_read_lock_bh       vmlinux EXPORT_SYMBOL
++0x3fd55724    of_n_size_cells vmlinux EXPORT_SYMBOL
++0xd17aae7c    hid_report_raw_event    vmlinux EXPORT_SYMBOL_GPL
++0xe469207d    scsi_unregister vmlinux EXPORT_SYMBOL
++0xbf5da77e    dma_buf_begin_cpu_access        vmlinux EXPORT_SYMBOL_GPL
++0x47ed7ca1    inet6_unregister_icmp_sender    vmlinux EXPORT_SYMBOL
++0xed8b1ab6    nf_nat_used_tuple       vmlinux EXPORT_SYMBOL
++0x46e928cf    nf_nat_packet   vmlinux EXPORT_SYMBOL_GPL
++0xdc854ee4    blk_init_tags   vmlinux EXPORT_SYMBOL
++0x4b134056    vfs_fsync_range vmlinux EXPORT_SYMBOL
++0x3ce4ca6f    disable_irq     vmlinux EXPORT_SYMBOL
++0xdc9fa232    raw_notifier_chain_register     vmlinux EXPORT_SYMBOL_GPL
++0x2b0d15d8    scsi_internal_device_unblock    vmlinux EXPORT_SYMBOL_GPL
++0x09d12bc0    sysfs_remove_file       vmlinux EXPORT_SYMBOL_GPL
++0x85a8465a    path_put        vmlinux EXPORT_SYMBOL
++0xe0dec72b    apply_to_page_range     vmlinux EXPORT_SYMBOL_GPL
++0xa0ceef51    out_of_line_wait_on_bit vmlinux EXPORT_SYMBOL
++0x7f04e7d5    dm_set_target_max_io_len        vmlinux EXPORT_SYMBOL_GPL
++0x84a26155    v4l2_ctrl_g_ctrl        vmlinux EXPORT_SYMBOL
++0x1254f0e4    scsi_host_alloc vmlinux EXPORT_SYMBOL
++0x0e09444b    bus_get_device_klist    vmlinux EXPORT_SYMBOL_GPL
++0xbebc3cd2    dst_discard     vmlinux EXPORT_SYMBOL
++0x8d25ae30    snd_soc_dapm_put_value_enum_double      vmlinux EXPORT_SYMBOL_GPL
++0x8d02ccf1    snd_soc_dapm_get_value_enum_double      vmlinux EXPORT_SYMBOL_GPL
++0xaa2a72bf    __iowrite64_copy        vmlinux EXPORT_SYMBOL_GPL
++0x373d62c5    invalidate_partition    vmlinux EXPORT_SYMBOL
++0xd217e9e6    trace_set_clr_event     vmlinux EXPORT_SYMBOL_GPL
++0x00e86db4    kick_process    vmlinux EXPORT_SYMBOL_GPL
++0xa625110d    kmsg_dump_rewind        vmlinux EXPORT_SYMBOL_GPL
++0x17eb0eee    v4l2_m2m_init   vmlinux EXPORT_SYMBOL_GPL
++0xd153a267    drm_irq_uninstall       vmlinux EXPORT_SYMBOL
++0x6ccf7bd7    __pv_phys_offset        vmlinux EXPORT_SYMBOL
++0x6cf45a72    sk_release_kernel       vmlinux EXPORT_SYMBOL
++0x7cff72b3    sg_miter_stop   vmlinux EXPORT_SYMBOL
++0x0da10ec3    security_sock_graft     vmlinux EXPORT_SYMBOL
++0xe601743b    jbd2_journal_init_jbd_inode     vmlinux EXPORT_SYMBOL
++0xdd3916ac    _raw_spin_unlock_bh     vmlinux EXPORT_SYMBOL
++0xb5ab5fe9    usb_function_register   vmlinux EXPORT_SYMBOL_GPL
++0xa20bbbd7    xt_proto_init   vmlinux EXPORT_SYMBOL_GPL
++0x13b715e2    blk_finish_plug vmlinux EXPORT_SYMBOL
++0x0b1beb31    vmalloc_32_user vmlinux EXPORT_SYMBOL
++0x85dfe0aa    fget_light      vmlinux EXPORT_SYMBOL
++0x8bebc4a8    drm_master_put  vmlinux EXPORT_SYMBOL
++0xf073bd48    nfc_hci_target_discovered       vmlinux EXPORT_SYMBOL
++0x878ab3ce    sysctl_tcp_adv_win_scale        vmlinux EXPORT_SYMBOL
++0x11e11bef    ip_local_out    vmlinux EXPORT_SYMBOL_GPL
++0xafe96047    generic_permission      vmlinux EXPORT_SYMBOL
++0x96123b65    iio_trigger_unregister  vmlinux EXPORT_SYMBOL
++0xf7b01b50    gether_get_host_addr_cdc        vmlinux EXPORT_SYMBOL
++0x3324e6d2    ehci_suspend    vmlinux EXPORT_SYMBOL_GPL
++0x7ef61596    usb_hcd_check_unlink_urb        vmlinux EXPORT_SYMBOL_GPL
++0x7ced7048    phy_device_free vmlinux EXPORT_SYMBOL
++0x9afda3df    regcache_cache_bypass   vmlinux EXPORT_SYMBOL_GPL
++0xd59668e6    unlock_flocks   vmlinux EXPORT_SYMBOL_GPL
++0xb818e055    usbnet_open     vmlinux EXPORT_SYMBOL_GPL
++0x4683093b    snd_ctl_notify  vmlinux EXPORT_SYMBOL
++0x9d3aa376    blk_iopoll_init vmlinux EXPORT_SYMBOL
++0x226a674d    atomic_notifier_chain_unregister        vmlinux EXPORT_SYMBOL_GPL
++0x0144d325    regmap_async_complete   vmlinux EXPORT_SYMBOL_GPL
++0x27f4cbdb    uart_get_baud_rate      vmlinux EXPORT_SYMBOL
++0x878175c4    secpath_dup     vmlinux EXPORT_SYMBOL
++0x7931d788    snd_pcm_hw_constraint_step      vmlinux EXPORT_SYMBOL
++0x36170e28    set_user_nice   vmlinux EXPORT_SYMBOL
++0x45de06d1    iio_buffer_write_length vmlinux EXPORT_SYMBOL
++0x5babbf10    media_device_unregister_entity  vmlinux EXPORT_SYMBOL_GPL
++0xe593d0c8    usbnet_disconnect       vmlinux EXPORT_SYMBOL_GPL
++0xb7e8ce46    exynos_drm_subdrv_close vmlinux EXPORT_SYMBOL_GPL
++0xc29dc1ad    drm_framebuffer_init    vmlinux EXPORT_SYMBOL
++0x7fe1a403    cfg80211_find_ie        vmlinux EXPORT_SYMBOL
++0xa8469c88    netdev_notify_peers     vmlinux EXPORT_SYMBOL
++0xe81978c6    splice_direct_to_actor  vmlinux EXPORT_SYMBOL
++0xb5cb8145    hrtimer_get_res vmlinux EXPORT_SYMBOL_GPL
++0x9a70b0fd    nf_nat_pptp_hook_inbound        vmlinux EXPORT_SYMBOL_GPL
++0x2b9da7a4    genl_lock       vmlinux EXPORT_SYMBOL
++0xb72e58d6    qdisc_class_hash_grow   vmlinux EXPORT_SYMBOL
++0x0e59e8cf    sock_setsockopt vmlinux EXPORT_SYMBOL
++0x20df2681    ida_simple_remove       vmlinux EXPORT_SYMBOL
++0xbdef23a2    unlock_buffer   vmlinux EXPORT_SYMBOL
++0x3b231b68    simple_transaction_release      vmlinux EXPORT_SYMBOL
++0xad098b64    usb_unlocked_enable_lpm vmlinux EXPORT_SYMBOL_GPL
++0x4b05e7ed    tty_port_close_start    vmlinux EXPORT_SYMBOL
++0x14789075    dma_find_channel        vmlinux EXPORT_SYMBOL
++0x77c05b09    fb_find_mode    vmlinux EXPORT_SYMBOL
++0x01010c6d    klist_add_before        vmlinux EXPORT_SYMBOL_GPL
++0x292c29ad    nfulnl_log_packet       vmlinux EXPORT_SYMBOL_GPL
++0x521b36b5    qdisc_put_rtab  vmlinux EXPORT_SYMBOL
++0x69c66f79    crypto_attr_alg2        vmlinux EXPORT_SYMBOL_GPL
++0x341dbfa3    __per_cpu_offset        vmlinux EXPORT_SYMBOL
++0x8953f8ff    __tracepoint_kmem_cache_alloc   vmlinux EXPORT_SYMBOL
++0x7e0ef97c    regmap_irq_get_domain   vmlinux EXPORT_SYMBOL_GPL
++0x437ff921    subsys_find_device_by_id        vmlinux EXPORT_SYMBOL_GPL
++0x975e0663    set_sig_addr_hook       vmlinux EXPORT_SYMBOL_GPL
++0xe86f0da8    proto_register  vmlinux EXPORT_SYMBOL
++0xb838d98e    event_storage_mutex     vmlinux EXPORT_SYMBOL_GPL
++0x9ca1dc35    vb2_fop_mmap    vmlinux EXPORT_SYMBOL_GPL
++0xde1a5959    rtc_irq_unregister      vmlinux EXPORT_SYMBOL_GPL
++0xbeca75ff    drm_crtc_helper_set_mode        vmlinux EXPORT_SYMBOL
++0x65f850bc    tty_wakeup      vmlinux EXPORT_SYMBOL_GPL
++0xf4743f88    amba_ahb_device_add     vmlinux EXPORT_SYMBOL_GPL
++0xa994f545    check_disk_size_change  vmlinux EXPORT_SYMBOL
++0x455293f6    down_read       vmlinux EXPORT_SYMBOL
++0x7eaf8e7a    v4l2_detect_gtf vmlinux EXPORT_SYMBOL_GPL
++0x53105839    v4l2_detect_cvt vmlinux EXPORT_SYMBOL_GPL
++0x6a41ea71    v4l2_clk_get_rate       vmlinux EXPORT_SYMBOL
++0xc50c3f79    v4l2_clk_set_rate       vmlinux EXPORT_SYMBOL
++0x52bc9e2a    drm_plane_cleanup       vmlinux EXPORT_SYMBOL
++0x0d4cb82a    km_report       vmlinux EXPORT_SYMBOL
++0xcffe8e42    __napi_complete vmlinux EXPORT_SYMBOL
++0xb17c5844    skb_copy_expand vmlinux EXPORT_SYMBOL
++0xaaaa5788    blk_queue_softirq_done  vmlinux EXPORT_SYMBOL
++0x43a762e5    d_lookup        vmlinux EXPORT_SYMBOL
++0xebc525f4    iio_triggered_buffer_cleanup    vmlinux EXPORT_SYMBOL
++0xabd0c91c    rtc_time_to_tm  vmlinux EXPORT_SYMBOL
++0x70f3f9b2    dmam_free_coherent      vmlinux EXPORT_SYMBOL
++0xba361646    transport_setup_device  vmlinux EXPORT_SYMBOL_GPL
++0x950ee7d1    fb_find_logo    vmlinux EXPORT_SYMBOL_GPL
++0x20294ce8    genl_unregister_mc_group        vmlinux EXPORT_SYMBOL
++0x1d7aabfd    path_is_under   vmlinux EXPORT_SYMBOL
++0x17975413    iio_map_array_register  vmlinux EXPORT_SYMBOL_GPL
++0xf811e69d    scsi_eh_flush_done_q    vmlinux EXPORT_SYMBOL
++0x8b95a59f    xt_hook_unlink  vmlinux EXPORT_SYMBOL_GPL
++0x557cb7c6    skb_morph       vmlinux EXPORT_SYMBOL_GPL
++0x02ef742b    percpu_counter_set      vmlinux EXPORT_SYMBOL
++0x03ae21fb    mmc_erase       vmlinux EXPORT_SYMBOL
++0x7c46233a    cpufreq_quick_get       vmlinux EXPORT_SYMBOL
++0xa4f8a168    dm_underlying_device_busy       vmlinux EXPORT_SYMBOL_GPL
++0x1d41eadc    v4l2_ctrl_s_ctrl        vmlinux EXPORT_SYMBOL
++0xa11295ab    serio_unregister_port   vmlinux EXPORT_SYMBOL
++0x11065515    drm_mode_equal  vmlinux EXPORT_SYMBOL
++0x4c47ec15    klist_add_head  vmlinux EXPORT_SYMBOL_GPL
++0x68a24153    snd_pcm_format_physical_width   vmlinux EXPORT_SYMBOL
++0xb6822a33    radix_tree_gang_lookup_tag      vmlinux EXPORT_SYMBOL
++0xdaa16b82    of_clk_get      vmlinux EXPORT_SYMBOL
++0x5c625801    scsi_remove_host        vmlinux EXPORT_SYMBOL
++0xa7de1327    flush_dcache_page       vmlinux EXPORT_SYMBOL
++0x2d6507b5    _find_next_zero_bit_le  vmlinux EXPORT_SYMBOL
++0xf26e1c06    snd_soc_suspend vmlinux EXPORT_SYMBOL_GPL
++0xc213a12a    devm_ioremap_nocache    vmlinux EXPORT_SYMBOL
++0xb43a5300    sync_dirty_buffer       vmlinux EXPORT_SYMBOL
++0xd303fa4e    clk_notifier_unregister vmlinux EXPORT_SYMBOL_GPL
++0x496c3d67    v4l2_querymenu  vmlinux EXPORT_SYMBOL
++0x02b44bb5    scsi_is_host_device     vmlinux EXPORT_SYMBOL
++0x91c9a325    bt_to_errno     vmlinux EXPORT_SYMBOL
++0x86a85b06    tcp_reno_ssthresh       vmlinux EXPORT_SYMBOL_GPL
++0xfc5c6b3e    netlink_has_listeners   vmlinux EXPORT_SYMBOL_GPL
++0xe075d6eb    iter_div_u64_rem        vmlinux EXPORT_SYMBOL
++0xcf0e08ad    filter_current_check_discard    vmlinux EXPORT_SYMBOL_GPL
++0x5afb47fc    of_irq_to_resource_table        vmlinux EXPORT_SYMBOL_GPL
++0xf1421d13    drm_mode_sort   vmlinux EXPORT_SYMBOL
++0xd06ec95f    dma_supported   vmlinux EXPORT_SYMBOL
++0xf1b80226    nf_nat_seq_adjust_hook  vmlinux EXPORT_SYMBOL_GPL
++0xf4c02b65    inode_init_once vmlinux EXPORT_SYMBOL
++0x369fcd70    tracing_snapshot        vmlinux EXPORT_SYMBOL_GPL
++0x73d69364    ring_buffer_change_overwrite    vmlinux EXPORT_SYMBOL_GPL
++0x339d542a    __srcu_notifier_call_chain      vmlinux EXPORT_SYMBOL_GPL
++0xe2d3d0b9    v4l2_ctrl_sub_ev_ops    vmlinux EXPORT_SYMBOL
++0xee129bef    usb_alloc_urb   vmlinux EXPORT_SYMBOL_GPL
++0x64a127a3    spi_setup       vmlinux EXPORT_SYMBOL_GPL
++0x3a8da0aa    nf_ip6_checksum vmlinux EXPORT_SYMBOL
++0xb46a6cbb    scsi_cmd_ioctl  vmlinux EXPORT_SYMBOL
++0xf7d52055    iio_bus_type    vmlinux EXPORT_SYMBOL
++0x75b9f8b8    device_move     vmlinux EXPORT_SYMBOL_GPL
++0x34dc9b87    neigh_seq_stop  vmlinux EXPORT_SYMBOL
++0x82b802b2    snd_soc_dai_set_pll     vmlinux EXPORT_SYMBOL_GPL
++0x0f4c91ed    ns_to_timespec  vmlinux EXPORT_SYMBOL
++0xca34e63d    iio_triggered_buffer_postenable vmlinux EXPORT_SYMBOL
++0x8d3ecd41    drm_core_ioremapfree    vmlinux EXPORT_SYMBOL
++0xed93f29e    __kunmap_atomic vmlinux EXPORT_SYMBOL
++0xe7cd755a    nf_ct_dying_timeout     vmlinux EXPORT_SYMBOL_GPL
++0xe5452cbf    dev_mc_del_global       vmlinux EXPORT_SYMBOL
++0x1a77ed38    dev_mc_add_global       vmlinux EXPORT_SYMBOL
++0x7b4901f5    snd_soc_add_platform    vmlinux EXPORT_SYMBOL_GPL
++0xdff7c9ce    blocking_notifier_chain_unregister      vmlinux EXPORT_SYMBOL_GPL
++0x346127a7    drm_global_item_ref     vmlinux EXPORT_SYMBOL
++0xf763bb6d    drm_framebuffer_cleanup vmlinux EXPORT_SYMBOL
++0x4a6b641b    fifo_create_dflt        vmlinux EXPORT_SYMBOL
++0x3a39f5ed    neigh_table_init        vmlinux EXPORT_SYMBOL
++0xc7207cfe    blk_queue_segment_boundary      vmlinux EXPORT_SYMBOL
++0x183b1236    blk_stop_queue  vmlinux EXPORT_SYMBOL
++0x632b18ed    blkcipher_walk_virt_block       vmlinux EXPORT_SYMBOL_GPL
++0x68ecff32    sysfs_create_link       vmlinux EXPORT_SYMBOL_GPL
++0x2bc64f3b    task_active_pid_ns      vmlinux EXPORT_SYMBOL_GPL
++0xda83d7a1    mmc_register_driver     vmlinux EXPORT_SYMBOL
++0x85e9caff    exynos4x12_cpufreq_init vmlinux EXPORT_SYMBOL
++0xf75603a3    exynos4210_cpufreq_init vmlinux EXPORT_SYMBOL
++0x38a9c2c7    input_ff_effect_from_user       vmlinux EXPORT_SYMBOL_GPL
++0x4f92c146    mfd_cell_enable vmlinux EXPORT_SYMBOL
++0xeacc50bc    attribute_container_register    vmlinux EXPORT_SYMBOL_GPL
++0x53465c39    drm_vblank_count_and_time       vmlinux EXPORT_SYMBOL
++0xc0e23731    inetpeer_invalidate_tree        vmlinux EXPORT_SYMBOL
++0x7d1904b2    __neigh_create  vmlinux EXPORT_SYMBOL
++0x6d294e43    clock_t_to_jiffies      vmlinux EXPORT_SYMBOL
++0x327bf883    of_can_translate_address        vmlinux EXPORT_SYMBOL
++0x6232e48e    power_supply_powers     vmlinux EXPORT_SYMBOL_GPL
++0x15b9125f    hdmi_avi_infoframe_pack vmlinux EXPORT_SYMBOL
++0x48e7c422    fanout_mutex    vmlinux EXPORT_SYMBOL_GPL
++0xdf050302    skb_mac_gso_segment     vmlinux EXPORT_SYMBOL
++0x4afb74d0    snd_pcm_lib_preallocate_pages_for_all   vmlinux EXPORT_SYMBOL
++0xf874d572    crypto_larval_alloc     vmlinux EXPORT_SYMBOL_GPL
++0x540a73a6    seq_release     vmlinux EXPORT_SYMBOL
++0xb3826d47    insert_inode_locked     vmlinux EXPORT_SYMBOL
++0x1866cec2    ring_buffer_size        vmlinux EXPORT_SYMBOL_GPL
++0x838b13e7    ring_buffer_free        vmlinux EXPORT_SYMBOL_GPL
++0x41d8cf05    module_layout   vmlinux EXPORT_SYMBOL
++0xdbb5a9f5    drm_ht_remove_item      vmlinux EXPORT_SYMBOL
++0x654a5368    drm_vblank_off  vmlinux EXPORT_SYMBOL
++0xb3e9e167    drm_vblank_get  vmlinux EXPORT_SYMBOL
++0xa795c78d    pl330_filter    vmlinux EXPORT_SYMBOL
++0x0335cb43    __sb_start_write        vmlinux EXPORT_SYMBOL
++0x6955eb5f    hidinput_disconnect     vmlinux EXPORT_SYMBOL_GPL
++0xd49dd4f4    cfg80211_cqm_txe_notify vmlinux EXPORT_SYMBOL
++0xcc1fb551    baswap  vmlinux EXPORT_SYMBOL
++0x653aa466    __blk_put_request       vmlinux EXPORT_SYMBOL_GPL
++0x99401626    elv_rb_latter_request   vmlinux EXPORT_SYMBOL
++0x0da68fbf    sysfs_create_bin_file   vmlinux EXPORT_SYMBOL_GPL
++0x27fa66e1    nr_free_buffer_pages    vmlinux EXPORT_SYMBOL_GPL
++0x7452437c    cgroup_taskset_next     vmlinux EXPORT_SYMBOL_GPL
++0xd2e7fb21    mod_delayed_work_on     vmlinux EXPORT_SYMBOL_GPL
++0x3d388324    dpm_resume_end  vmlinux EXPORT_SYMBOL_GPL
++0xfda2fc6f    pinctrl_remove_gpio_range       vmlinux EXPORT_SYMBOL_GPL
++0x98c9f584    klist_init      vmlinux EXPORT_SYMBOL_GPL
++0x72e52881    xfrm_state_unregister_afinfo    vmlinux EXPORT_SYMBOL
++0xec57ea15    snd_card_unref  vmlinux EXPORT_SYMBOL
++0x6cdc5c6b    nla_strlcpy     vmlinux EXPORT_SYMBOL
++0xa46f2f1b    kstrtouint      vmlinux EXPORT_SYMBOL
++0x315c8d71    blk_init_queue_node     vmlinux EXPORT_SYMBOL
++0x83211609    up_write        vmlinux EXPORT_SYMBOL
++0x19610e1f    cpu_all_bits    vmlinux EXPORT_SYMBOL
++0x4f248523    of_find_node_by_name    vmlinux EXPORT_SYMBOL
++0x14d0738e    dm_noflush_suspending   vmlinux EXPORT_SYMBOL_GPL
++0x488cee4b    serial8250_do_pm        vmlinux EXPORT_SYMBOL
++0xe4e38519    tcf_hash_release        vmlinux EXPORT_SYMBOL
++0xf1298271    free_buffer_head        vmlinux EXPORT_SYMBOL
++0x08559b9a    fget    vmlinux EXPORT_SYMBOL
++0x4a57b339    wait_for_completion_io_timeout  vmlinux EXPORT_SYMBOL
++0xcccd9343    mmc_gpio_get_ro vmlinux EXPORT_SYMBOL
++0xa3959367    mmc_gpio_get_cd vmlinux EXPORT_SYMBOL
++0xbc3a2d91    cpufreq_cpu_put vmlinux EXPORT_SYMBOL_GPL
++0x238dd120    cpufreq_cpu_get vmlinux EXPORT_SYMBOL_GPL
++0xfe7c6819    scsi_target_block       vmlinux EXPORT_SYMBOL_GPL
++0x42488405    scsi_prep_state_check   vmlinux EXPORT_SYMBOL
++0xf4b2e991    drm_mm_put_block        vmlinux EXPORT_SYMBOL
++0x688bd4c5    snd_ctl_boolean_mono_info       vmlinux EXPORT_SYMBOL
++0xe1e281d6    jbd2_log_start_commit   vmlinux EXPORT_SYMBOL
++0x9130f1c7    remove_proc_subtree     vmlinux EXPORT_SYMBOL
++0xfa1eb910    unregister_syscore_ops  vmlinux EXPORT_SYMBOL_GPL
++0x4d7f9839    snd_soc_of_parse_card_name      vmlinux EXPORT_SYMBOL_GPL
++0x44e9a829    match_token     vmlinux EXPORT_SYMBOL
++0x49b26c63    jbd2_journal_abort      vmlinux EXPORT_SYMBOL
++0x1a323362    __ftrace_vbprintk       vmlinux EXPORT_SYMBOL_GPL
++0x0a958ed4    down_write      vmlinux EXPORT_SYMBOL
++0x706b3a33    cpufreq_frequency_table_get_attr        vmlinux EXPORT_SYMBOL_GPL
++0xbdba9828    hdmi_audio_infoframe_pack       vmlinux EXPORT_SYMBOL
++0x09c64fbd    ieee80211_frequency_to_channel  vmlinux EXPORT_SYMBOL
++0x64d41d38    ip_route_output_flow    vmlinux EXPORT_SYMBOL_GPL
++0xc23832c5    snd_soc_add_card_controls       vmlinux EXPORT_SYMBOL_GPL
++0x43326227    posix_test_lock vmlinux EXPORT_SYMBOL
++0xd7289dfe    kill_block_super        vmlinux EXPORT_SYMBOL
++0x2b0f3b97    flush_signals   vmlinux EXPORT_SYMBOL
++0x1b9e0ff1    scsilun_to_int  vmlinux EXPORT_SYMBOL
++0x97a0de2c    drm_prime_pages_to_sg   vmlinux EXPORT_SYMBOL
++0x0442abb5    __inet_stream_connect   vmlinux EXPORT_SYMBOL
++0xc6f7d745    nf_ct_remove_expectations       vmlinux EXPORT_SYMBOL_GPL
++0xecdea3ba    neigh_lookup_nodev      vmlinux EXPORT_SYMBOL
++0x10c58227    kernel_setsockopt       vmlinux EXPORT_SYMBOL
++0x8fd29b0f    kernel_getsockopt       vmlinux EXPORT_SYMBOL
++0xed5cfaa9    kernel_sock_ioctl       vmlinux EXPORT_SYMBOL
++0x8ffdb3b8    crc16   vmlinux EXPORT_SYMBOL
++0xadc7f742    mb_cache_entry_insert   vmlinux EXPORT_SYMBOL
++0x4e1e8913    kallsyms_on_each_symbol vmlinux EXPORT_SYMBOL_GPL
++0xf82f3657    work_on_cpu     vmlinux EXPORT_SYMBOL_GPL
++0x459e133f    v4l2_m2m_get_curr_priv  vmlinux EXPORT_SYMBOL
++0x4dd51c13    phy_pm_runtime_allow    vmlinux EXPORT_SYMBOL_GPL
++0xcbbaba0b    nf_tproxy_assign_sock   vmlinux EXPORT_SYMBOL_GPL
++0x3e220367    nfnetlink_unicast       vmlinux EXPORT_SYMBOL_GPL
++0x55504881    snd_mixer_oss_ioctl_card        vmlinux EXPORT_SYMBOL
++0xab694444    bsearch vmlinux EXPORT_SYMBOL
++0x662edc7c    blk_put_request vmlinux EXPORT_SYMBOL
++0x6ca4bf88    async_synchronize_full_domain   vmlinux EXPORT_SYMBOL_GPL
++0x12456a92    iommu_iova_to_phys      vmlinux EXPORT_SYMBOL_GPL
++0xdc7b411a    dev_pm_qos_hide_latency_limit   vmlinux EXPORT_SYMBOL_GPL
++0x28441b73    drm_get_last_vbltimestamp       vmlinux EXPORT_SYMBOL
++0x83eab4ef    crypto_create_tfm       vmlinux EXPORT_SYMBOL_GPL
++0x42e2c53b    nf_conntrack_in vmlinux EXPORT_SYMBOL_GPL
++0x3ea1d70f    sock_queue_rcv_skb      vmlinux EXPORT_SYMBOL
++0xe7820ad2    snd_pcm_lib_preallocate_free_for_all    vmlinux EXPORT_SYMBOL
++0x754dac78    blk_limits_io_min       vmlinux EXPORT_SYMBOL
++0x0cd9cfec    sysfs_remove_files      vmlinux EXPORT_SYMBOL_GPL
++0xc237047a    mapping_tagged  vmlinux EXPORT_SYMBOL
++0xd777c9b7    iio_device_alloc        vmlinux EXPORT_SYMBOL
++0xd688716b    dm_kcopyd_client_create vmlinux EXPORT_SYMBOL
++0x2502c67c    v4l2_fh_add     vmlinux EXPORT_SYMBOL_GPL
++0x088675f7    usbnet_write_cmd_async  vmlinux EXPORT_SYMBOL_GPL
++0xb35659de    drm_mode_remove vmlinux EXPORT_SYMBOL
++0x16acff8a    devm_of_pwm_get vmlinux EXPORT_SYMBOL_GPL
++0xd2bd22d2    s3c_gpio_getpull        vmlinux EXPORT_SYMBOL
++0x5fbecd25    s3c_gpio_setpull        vmlinux EXPORT_SYMBOL
++0x67c2fa54    __copy_to_user  vmlinux EXPORT_SYMBOL
++0x7c6a49ce    unix_table_lock vmlinux EXPORT_SYMBOL_GPL
++0x38d60861    put_disk        vmlinux EXPORT_SYMBOL
++0x871bcaa4    irq_find_host   vmlinux EXPORT_SYMBOL_GPL
++0xd9605d4c    add_timer       vmlinux EXPORT_SYMBOL
++0xea97fb5e    usbhid_set_leds vmlinux EXPORT_SYMBOL_GPL
++0x70915b51    serio_interrupt vmlinux EXPORT_SYMBOL
++0x92a772c3    usbnet_purge_paused_rxq vmlinux EXPORT_SYMBOL_GPL
++0xf6bb4729    color_table     vmlinux EXPORT_SYMBOL
++0x8c637d43    irq_cpu_rmap_add        vmlinux EXPORT_SYMBOL
++0x9ba7089d    argv_split      vmlinux EXPORT_SYMBOL
++0x34f3484e    security_tun_dev_attach_queue   vmlinux EXPORT_SYMBOL
++0x1a1431fd    _raw_spin_unlock_irq    vmlinux EXPORT_SYMBOL
++0x7c08f605    hid_allocate_device     vmlinux EXPORT_SYMBOL_GPL
++0xe5a8e6b5    spi_sync        vmlinux EXPORT_SYMBOL_GPL
++0xcc69f0f8    dma_sync_wait   vmlinux EXPORT_SYMBOL
++0x43e33157    blk_queue_max_hw_sectors        vmlinux EXPORT_SYMBOL
++0x8ea0cdd5    drm_add_modes_noedid    vmlinux EXPORT_SYMBOL
++0x9a8318ef    v7_coherent_kern_range  vmlinux EXPORT_SYMBOL
++0x5de3ad52    cfg80211_ref_bss        vmlinux EXPORT_SYMBOL
++0xdc1b2765    crypto_aes_set_key      vmlinux EXPORT_SYMBOL_GPL
++0x5086ac3a    alg_test        vmlinux EXPORT_SYMBOL_GPL
++0x9c35fb24    jbd2__journal_restart   vmlinux EXPORT_SYMBOL
++0xbef43296    console_conditional_schedule    vmlinux EXPORT_SYMBOL
++0xa71c1b98    bus_set_iommu   vmlinux EXPORT_SYMBOL_GPL
++0x8e801428    bus_create_file vmlinux EXPORT_SYMBOL_GPL
++0x8fc34c2d    drm_warn_on_modeset_not_all_locked      vmlinux EXPORT_SYMBOL
++0x2e0a06e3    snd_unregister_device   vmlinux EXPORT_SYMBOL
++0x9caaf6cf    blkdev_issue_discard    vmlinux EXPORT_SYMBOL
++0x3e6444e8    crypto_unregister_pcomp vmlinux EXPORT_SYMBOL_GPL
++0xc1d19fdd    debugfs_create_symlink  vmlinux EXPORT_SYMBOL_GPL
++0x9bd7640e    fat_detach      vmlinux EXPORT_SYMBOL_GPL
++0x698a899f    ring_buffer_peek        vmlinux EXPORT_SYMBOL_GPL
++0xe2e7840d    regmap_init_mmio_clk    vmlinux EXPORT_SYMBOL_GPL
++0xe556d687    xt_request_find_match   vmlinux EXPORT_SYMBOL_GPL
++0xcf25e6b2    xattr_getsecurity       vmlinux EXPORT_SYMBOL_GPL
++0x6228c21f    smp_call_function_single        vmlinux EXPORT_SYMBOL
++0x5f324ec1    drm_ioctl       vmlinux EXPORT_SYMBOL
++0x4d9b652b    rb_erase        vmlinux EXPORT_SYMBOL
++0xcc71d484    drm_mode_duplicate      vmlinux EXPORT_SYMBOL
++0x2b02560b    devm_pwm_put    vmlinux EXPORT_SYMBOL_GPL
++0x3659d5ac    devm_phy_get    vmlinux EXPORT_SYMBOL_GPL
++0xaafdc258    strcasecmp      vmlinux EXPORT_SYMBOL
++0xc296567b    save_mount_options      vmlinux EXPORT_SYMBOL
++0xbade32c7    clockevents_register_device     vmlinux EXPORT_SYMBOL_GPL
++0xfb8a84a4    drm_mm_get_block_range_generic  vmlinux EXPORT_SYMBOL
++0x058b582a    vt_get_leds     vmlinux EXPORT_SYMBOL_GPL
++0xb2a0603e    nci_recv_frame  vmlinux EXPORT_SYMBOL
++0xc0240dd4    nf_conntrack_set_hashsize       vmlinux EXPORT_SYMBOL_GPL
++0x45c8cd86    ifla_policy     vmlinux EXPORT_SYMBOL
++0xd251d7b0    security_socket_getpeersec_dgram        vmlinux EXPORT_SYMBOL
++0xf05e203c    set_blocksize   vmlinux EXPORT_SYMBOL
++0xc1c995a0    block_page_mkwrite      vmlinux EXPORT_SYMBOL
++0x85b9e216    set_timer_slack vmlinux EXPORT_SYMBOL_GPL
++0x2665c0a3    vb2_qbuf        vmlinux EXPORT_SYMBOL_GPL
++0x9abe8d18    video_usercopy  vmlinux EXPORT_SYMBOL
++0x1d93e603    tty_unthrottle  vmlinux EXPORT_SYMBOL
++0x1142511d    crypto_spawn_tfm        vmlinux EXPORT_SYMBOL_GPL
++0xeb9ddf6d    security_inode_notifysecctx     vmlinux EXPORT_SYMBOL
++0x68df960a    generic_error_remove_page       vmlinux EXPORT_SYMBOL
++0x7000dc34    class_compat_remove_link        vmlinux EXPORT_SYMBOL_GPL
++0x816dee03    uart_unregister_driver  vmlinux EXPORT_SYMBOL
++0x0acf7679    dma_issue_pending_all   vmlinux EXPORT_SYMBOL
++0x8792d764    l2cap_conn_get  vmlinux EXPORT_SYMBOL
++0xcf2890b2    ipv6_chk_prefix vmlinux EXPORT_SYMBOL
++0x616ff33b    ip6_dst_lookup_flow     vmlinux EXPORT_SYMBOL_GPL
++0x3e963d19    inet_csk_search_req     vmlinux EXPORT_SYMBOL_GPL
++0xdd632e58    inet_unhash     vmlinux EXPORT_SYMBOL_GPL
++0x98e40edf    nf_ct_nat_offset        vmlinux EXPORT_SYMBOL_GPL
++0x0a7ed556    blk_execute_rq  vmlinux EXPORT_SYMBOL
++0x44408a4a    mdio_bus_type   vmlinux EXPORT_SYMBOL
++0xac74a2a9    ip6_xmit        vmlinux EXPORT_SYMBOL
++0x411d75db    ip_tunnel_init  vmlinux EXPORT_SYMBOL_GPL
++0x7a442539    tcf_exts_dump   vmlinux EXPORT_SYMBOL
++0x13307fde    vsscanf vmlinux EXPORT_SYMBOL
++0xcc368515    jbd2_journal_unlock_updates     vmlinux EXPORT_SYMBOL
++0x21bfb720    seq_open_net    vmlinux EXPORT_SYMBOL_GPL
++0x82d79b51    sysctl_vfs_cache_pressure       vmlinux EXPORT_SYMBOL_GPL
++0x04486e88    rcu_batches_completed   vmlinux EXPORT_SYMBOL_GPL
++0x7c1372e8    panic   vmlinux EXPORT_SYMBOL
++0x9808f34e    dev_pm_qos_expose_flags vmlinux EXPORT_SYMBOL_GPL
++0x544b5ea8    pwm_disable     vmlinux EXPORT_SYMBOL_GPL
++0x5c265cba    sg_init_one     vmlinux EXPORT_SYMBOL
++0x12da5bb2    __kmalloc       vmlinux EXPORT_SYMBOL
++0x28d6861d    __vmalloc       vmlinux EXPORT_SYMBOL
++0x5db7b0d3    led_trigger_remove      vmlinux EXPORT_SYMBOL_GPL
++0x83b38ee6    kobject_init_and_add    vmlinux EXPORT_SYMBOL_GPL
++0x757cdadf    usbnet_get_ethernet_addr        vmlinux EXPORT_SYMBOL_GPL
++0x43a286d1    drm_prime_remove_buf_handle     vmlinux EXPORT_SYMBOL
++0xea8ddd89    __ip_select_ident       vmlinux EXPORT_SYMBOL
++0x1f984870    skb_gro_receive vmlinux EXPORT_SYMBOL_GPL
++0x48f8aa53    flock_lock_file_wait    vmlinux EXPORT_SYMBOL
++0x05e067d7    __media_entity_remove_links     vmlinux EXPORT_SYMBOL_GPL
++0xe7cb87e4    xt_find_match   vmlinux EXPORT_SYMBOL
++0x9d62c35b    nfq_ct_hook     vmlinux EXPORT_SYMBOL_GPL
++0xe12b4adb    __skb_warn_lro_forwarding       vmlinux EXPORT_SYMBOL
++0x471eeac6    snd_soc_platform_write  vmlinux EXPORT_SYMBOL_GPL
++0x71c90087    memcmp  vmlinux EXPORT_SYMBOL
++0x4881d505    idr_for_each    vmlinux EXPORT_SYMBOL
++0x79b33953    shash_ahash_digest      vmlinux EXPORT_SYMBOL_GPL
++0xcf1d92aa    locks_init_lock vmlinux EXPORT_SYMBOL
++0x11cfbadb    bio_add_pc_page vmlinux EXPORT_SYMBOL
++0x2917e251    split_page      vmlinux EXPORT_SYMBOL_GPL
++0xda53403f    v4l2_m2m_ctx_init       vmlinux EXPORT_SYMBOL_GPL
++0x4f4d910e    regmap_init     vmlinux EXPORT_SYMBOL_GPL
++0xb2a9634b    regmap_exit     vmlinux EXPORT_SYMBOL_GPL
++0xe16838c2    drm_mm_search_free_in_range_generic     vmlinux EXPORT_SYMBOL
++0xf05ffa15    fb_var_to_videomode     vmlinux EXPORT_SYMBOL
++0xab707907    inet6_del_offload       vmlinux EXPORT_SYMBOL
++0x13e229c2    nf_ct_helper_expectfn_find_by_name      vmlinux EXPORT_SYMBOL_GPL
++0x1f0547c1    netif_stacked_transfer_operstate        vmlinux EXPORT_SYMBOL
++0xd435e67a    snd_card_set_id vmlinux EXPORT_SYMBOL
++0xc7236f77    d_alloc_name    vmlinux EXPORT_SYMBOL
++0x2f3857e2    _raw_write_lock_irqsave vmlinux EXPORT_SYMBOL
++0x37c199e6    serio_reconnect vmlinux EXPORT_SYMBOL
++0x6754f715    drm_fb_helper_fill_fix  vmlinux EXPORT_SYMBOL
++0xc6df7ef6    cont_write_begin        vmlinux EXPORT_SYMBOL
++0x1c97e3ec    vfs_readdir     vmlinux EXPORT_SYMBOL
++0xbdd295f0    trace_vprintk   vmlinux EXPORT_SYMBOL_GPL
++0x8faa4598    of_translate_address    vmlinux EXPORT_SYMBOL
++0x0699040f    drm_encoder_cleanup     vmlinux EXPORT_SYMBOL
++0x7f8c7b48    dma_async_memcpy_buf_to_buf     vmlinux EXPORT_SYMBOL
++0x1ed85a8d    pinctrl_dev_get_drvdata vmlinux EXPORT_SYMBOL_GPL
++0x881039d0    zlib_inflate    vmlinux EXPORT_SYMBOL
++0x3771b461    crc_ccitt       vmlinux EXPORT_SYMBOL
++0xa43b1297    vscnprintf      vmlinux EXPORT_SYMBOL
++0x166e361d    blk_recount_segments    vmlinux EXPORT_SYMBOL
++0x887ece4a    simple_statfs   vmlinux EXPORT_SYMBOL
++0x617643a2    param_set_long  vmlinux EXPORT_SYMBOL
++0x6c69a9be    xfrm6_tunnel_deregister vmlinux EXPORT_SYMBOL
++0x3b850073    km_policy_notify        vmlinux EXPORT_SYMBOL
++0x10cc1e43    xfrm4_tunnel_deregister vmlinux EXPORT_SYMBOL
++0xc0f95b9e    ip_mc_join_group        vmlinux EXPORT_SYMBOL
++0xdb760f52    __kfifo_free    vmlinux EXPORT_SYMBOL
++0x3a288321    configfs_undepend_item  vmlinux EXPORT_SYMBOL
++0x2cc83b45    usb_string      vmlinux EXPORT_SYMBOL_GPL
++0x98442d13    inet_csk_reqsk_queue_hash_add   vmlinux EXPORT_SYMBOL_GPL
++0x8d33679f    nf_ct_unexpect_related  vmlinux EXPORT_SYMBOL_GPL
++0xe6e1c5fe    uuid_be_gen     vmlinux EXPORT_SYMBOL_GPL
++0x289ea691    debugfs_remove  vmlinux EXPORT_SYMBOL_GPL
++0xbb4e9599    lease_modify    vmlinux EXPORT_SYMBOL
++0x2fb6e20e    drop_nlink      vmlinux EXPORT_SYMBOL
++0xdfaa6b6b    v4l2_ctrl_radio_filter  vmlinux EXPORT_SYMBOL
++0xa3675712    xfrm_dst_ifdown vmlinux EXPORT_SYMBOL
++0x0d9bae4b    nf_nat_l4proto_nlattr_to_range  vmlinux EXPORT_SYMBOL_GPL
++0xc17f8f83    neigh_seq_start vmlinux EXPORT_SYMBOL
++0x6e7943ec    iommu_group_id  vmlinux EXPORT_SYMBOL_GPL
++0x1aef1e27    eth_header_cache_update vmlinux EXPORT_SYMBOL
++0xd800dc59    snd_pcm_hw_constraint_ratdens   vmlinux EXPORT_SYMBOL
++0xd1157735    release_and_free_resource       vmlinux EXPORT_SYMBOL
++0xb31526ee    sg_copy_from_buffer     vmlinux EXPORT_SYMBOL
++0x73e20c1c    strlcpy vmlinux EXPORT_SYMBOL
++0x328a05f1    strncpy vmlinux EXPORT_SYMBOL
++0x8abacc47    get_max_files   vmlinux EXPORT_SYMBOL_GPL
++0xae0f6b4e    regulator_unregister_notifier   vmlinux EXPORT_SYMBOL_GPL
++0x386f5a4e    tcf_em_tree_destroy     vmlinux EXPORT_SYMBOL
++0x97b4500c    __tracepoint_kmem_cache_free    vmlinux EXPORT_SYMBOL
++0x4a69690c    scsi_release_buffers    vmlinux EXPORT_SYMBOL
++0xf195c682    fb_invert_cmaps vmlinux EXPORT_SYMBOL
++0xab156bb5    kern_mount_data vmlinux EXPORT_SYMBOL_GPL
++0x1902f934    __init_kthread_worker   vmlinux EXPORT_SYMBOL_GPL
++0xdac0df4a    driver_create_file      vmlinux EXPORT_SYMBOL_GPL
++0x083eb21c    rfkill_unregister       vmlinux EXPORT_SYMBOL
++0x3e52c876    blk_requeue_request     vmlinux EXPORT_SYMBOL
++0xdca5d880    insert_inode_locked4    vmlinux EXPORT_SYMBOL
++0x41482d8b    strndup_user    vmlinux EXPORT_SYMBOL
++0xddd58dc0    ring_buffer_reset       vmlinux EXPORT_SYMBOL_GPL
++0x6b172795    media_entity_graph_walk_next    vmlinux EXPORT_SYMBOL_GPL
++0x0591a4d1    usb_ep_autoconfig_ss    vmlinux EXPORT_SYMBOL_GPL
++0x4b076147    uncache_firmware        vmlinux EXPORT_SYMBOL_GPL
++0x098b71c6    fb_dealloc_cmap vmlinux EXPORT_SYMBOL
++0x83d1444a    crypto_init_spawn       vmlinux EXPORT_SYMBOL_GPL
++0x60061dd7    mount_nodev     vmlinux EXPORT_SYMBOL
++0x7bb32751    pagevec_lookup  vmlinux EXPORT_SYMBOL
++0x47b6a10f    ftrace_print_symbols_seq        vmlinux EXPORT_SYMBOL
++0x8664f62e    cpufreq_update_policy   vmlinux EXPORT_SYMBOL
++0x29f39077    pwmchip_remove  vmlinux EXPORT_SYMBOL_GPL
++0x905baf48    xfrm_find_acq   vmlinux EXPORT_SYMBOL
++0x9487bc19    eth_mac_addr    vmlinux EXPORT_SYMBOL
++0xad1ed84c    unregister_hw_breakpoint        vmlinux EXPORT_SYMBOL_GPL
++0x993805c1    scsi_scan_host  vmlinux EXPORT_SYMBOL
++0x7a77dfe4    scsi_setup_fs_cmnd      vmlinux EXPORT_SYMBOL
++0xbbc9fd6e    cfg80211_wext_siwfrag   vmlinux EXPORT_SYMBOL_GPL
++0x82c82c32    cfg80211_wext_giwfrag   vmlinux EXPORT_SYMBOL_GPL
++0xe80dd06a    tcp_sendpage    vmlinux EXPORT_SYMBOL
++0x47b3f862    radix_tree_lookup_slot  vmlinux EXPORT_SYMBOL
++0x91621d6a    allocate_resource       vmlinux EXPORT_SYMBOL
++0xb98a0185    rtc_tm_to_time  vmlinux EXPORT_SYMBOL
++0xe5883bd9    class_compat_unregister vmlinux EXPORT_SYMBOL_GPL
++0x7bf9c108    serial8250_rx_dma       vmlinux EXPORT_SYMBOL_GPL
++0xc7856a3d    inet6addr_notifier_call_chain   vmlinux EXPORT_SYMBOL
++0xc08647ff    ring_buffer_bytes_cpu   vmlinux EXPORT_SYMBOL_GPL
++0xcbbf0a6f    audit_log_task_context  vmlinux EXPORT_SYMBOL
++0x0a0ab757    pm_schedule_suspend     vmlinux EXPORT_SYMBOL_GPL
++0x617ae32f    of_get_display_timings  vmlinux EXPORT_SYMBOL_GPL
++0xe442a492    splice_from_pipe_feed   vmlinux EXPORT_SYMBOL
++0xf9a054b5    __round_jiffies vmlinux EXPORT_SYMBOL_GPL
++0x38e20383    hid_alloc_report_buf    vmlinux EXPORT_SYMBOL_GPL
++0x626ffd48    spi_write_then_read     vmlinux EXPORT_SYMBOL_GPL
++0x7b5fc447    pinctrl_lookup_state    vmlinux EXPORT_SYMBOL_GPL
++0x8c49e9fe    cfg80211_conn_failed    vmlinux EXPORT_SYMBOL
++0x03c06156    bitmap_fold     vmlinux EXPORT_SYMBOL
++0x04d5a096    security_sb_clone_mnt_opts      vmlinux EXPORT_SYMBOL
++0x424b2fdf    vfs_rmdir       vmlinux EXPORT_SYMBOL
++0x52856d8e    generic_shutdown_super  vmlinux EXPORT_SYMBOL
++0xbd10541e    css_lookup      vmlinux EXPORT_SYMBOL_GPL
++0x37e74642    get_jiffies_64  vmlinux EXPORT_SYMBOL
++0xb8117014    cfg80211_rx_spurious_frame      vmlinux EXPORT_SYMBOL
++0x790c2d9c    netdev_master_upper_dev_link    vmlinux EXPORT_SYMBOL
++0x02a6ce5a    crc16_table     vmlinux EXPORT_SYMBOL
++0xe280ea92    init_buffer     vmlinux EXPORT_SYMBOL
++0xf21e1f9b    disable_percpu_irq      vmlinux EXPORT_SYMBOL_GPL
++0xb5ae5758    scsi_track_queue_full   vmlinux EXPORT_SYMBOL
++0xa26b1ba8    exynos_drm_device_register      vmlinux EXPORT_SYMBOL_GPL
++0xbe55cd3e    __sock_recv_ts_and_drops        vmlinux EXPORT_SYMBOL_GPL
++0xcedd3329    jbd2__journal_start     vmlinux EXPORT_SYMBOL
++0x838a3169    pm_qos_request_active   vmlinux EXPORT_SYMBOL_GPL
++0xbf7fd2f5    schedule_timeout_killable       vmlinux EXPORT_SYMBOL
++0xd9c4cec4    sock_no_getname vmlinux EXPORT_SYMBOL
++0x24678be3    snd_pcm_lib_readv       vmlinux EXPORT_SYMBOL
++0x292a0b74    vfs_link        vmlinux EXPORT_SYMBOL
++0x85050965    __irq_alloc_descs       vmlinux EXPORT_SYMBOL_GPL
++0xe3e7dba0    from_kuid_munged        vmlinux EXPORT_SYMBOL
++0x582bb484    call_usermodehelper_setup       vmlinux EXPORT_SYMBOL
++0xe52c5e63    v4l2_event_subscribe    vmlinux EXPORT_SYMBOL_GPL
++0xcd0fc417    drm_ht_just_insert_please       vmlinux EXPORT_SYMBOL
++0xdacbc24d    netlink_rcv_skb vmlinux EXPORT_SYMBOL
++0x33d23d14    sk_unattached_filter_create     vmlinux EXPORT_SYMBOL_GPL
++0x1f07ae8f    crypto_alloc_pcomp      vmlinux EXPORT_SYMBOL_GPL
++0x2447533c    ktime_get_real  vmlinux EXPORT_SYMBOL_GPL
++0x68869bae    panic_notifier_list     vmlinux EXPORT_SYMBOL
++0xdae1eb6a    of_clk_src_onecell_get  vmlinux EXPORT_SYMBOL_GPL
++0x3444d892    phy_driver_unregister   vmlinux EXPORT_SYMBOL
++0x107b31ec    __xfrm_state_delete     vmlinux EXPORT_SYMBOL
++0x4e6165cf    d_delete        vmlinux EXPORT_SYMBOL
++0x5f0e672b    find_get_pages_tag      vmlinux EXPORT_SYMBOL
++0xc8fd727e    mod_timer       vmlinux EXPORT_SYMBOL
++0xd2fe47b1    rndis_set_host_mac      vmlinux EXPORT_SYMBOL
++0xd768e985    regulator_has_full_constraints  vmlinux EXPORT_SYMBOL_GPL
++0x82f776b7    gpio_export     vmlinux EXPORT_SYMBOL_GPL
++0xdf401846    idr_remove      vmlinux EXPORT_SYMBOL
++0x29baff70    ida_remove      vmlinux EXPORT_SYMBOL
++0x220b4b23    mnt_set_expiry  vmlinux EXPORT_SYMBOL
++0x3dd9c200    use_mm  vmlinux EXPORT_SYMBOL_GPL
++0x2d41e6f5    __trace_puts    vmlinux EXPORT_SYMBOL_GPL
++0x5143c678    param_get_invbool       vmlinux EXPORT_SYMBOL
++0x914a1c17    ip_tunnel_newlink       vmlinux EXPORT_SYMBOL_GPL
++0xc5b6b555    genl_notify     vmlinux EXPORT_SYMBOL
++0xada52470    wm_hubs_hpl_mux vmlinux EXPORT_SYMBOL_GPL
++0x9393c812    add_page_wait_queue     vmlinux EXPORT_SYMBOL_GPL
++0xb16abad2    devm_rtc_device_register        vmlinux EXPORT_SYMBOL_GPL
++0xbd92ef65    devres_destroy  vmlinux EXPORT_SYMBOL_GPL
++0x1297fa08    tty_hangup      vmlinux EXPORT_SYMBOL
++0x580c94d2    seq_put_decimal_ll      vmlinux EXPORT_SYMBOL
++0xb22596e0    devm_rtc_device_unregister      vmlinux EXPORT_SYMBOL_GPL
++0x1b95d5c1    mdiobus_read    vmlinux EXPORT_SYMBOL
++0xea59b757    pm_runtime_forbid       vmlinux EXPORT_SYMBOL_GPL
++0x30e74134    tty_termios_copy_hw     vmlinux EXPORT_SYMBOL
++0x4455e1b3    regulator_disable_deferred      vmlinux EXPORT_SYMBOL_GPL
++0x8e322129    dma_release_channel     vmlinux EXPORT_SYMBOL_GPL
++0xcfd9a2c0    des_ekey        vmlinux EXPORT_SYMBOL_GPL
++0x66c78bd2    irq_domain_remove       vmlinux EXPORT_SYMBOL_GPL
++0x640c2da8    devm_clk_get    vmlinux EXPORT_SYMBOL
++0xd02c73c7    drm_dp_link_train_clock_recovery_delay  vmlinux EXPORT_SYMBOL
++0x2be0f12d    dql_completed   vmlinux EXPORT_SYMBOL
++0xad3f5f91    read_cache_page vmlinux EXPORT_SYMBOL
++0x4ca90996    rndis_signal_disconnect vmlinux EXPORT_SYMBOL
++0x917229dc    drm_irq_install vmlinux EXPORT_SYMBOL
++0x787bcffe    con_is_bound    vmlinux EXPORT_SYMBOL
++0xefb6eb3f    dev_change_flags        vmlinux EXPORT_SYMBOL
++0x0e352145    __skb_gso_segment       vmlinux EXPORT_SYMBOL
++0xa5d14a5e    xfrm_state_walk vmlinux EXPORT_SYMBOL
++0x6a0ae2ec    nla_put_nohdr   vmlinux EXPORT_SYMBOL
++0x0411124a    pid_nr_ns       vmlinux EXPORT_SYMBOL_GPL
++0x2133271d    phy_scan_fixups vmlinux EXPORT_SYMBOL
++0x64d233c8    ioremap_page    vmlinux EXPORT_SYMBOL
++0x8fea24bd    bt_sock_unregister      vmlinux EXPORT_SYMBOL
++0x16c3cf65    napi_gro_flush  vmlinux EXPORT_SYMBOL
++0xf001dc80    irq_domain_add_linear   vmlinux EXPORT_SYMBOL_GPL
++0xec069709    scsi_set_medium_removal vmlinux EXPORT_SYMBOL
++0xc0a98385    profile_pc      vmlinux EXPORT_SYMBOL
++0x79a2f120    snd_timer_resolution    vmlinux EXPORT_SYMBOL
++0x46c67b94    jbd2_journal_wipe       vmlinux EXPORT_SYMBOL
++0x444f1735    cpu_pm_register_notifier        vmlinux EXPORT_SYMBOL_GPL
++0xcc85fcb6    async_schedule  vmlinux EXPORT_SYMBOL_GPL
++0x9caf61d6    __nla_put       vmlinux EXPORT_SYMBOL
++0x4c2ae700    strnstr vmlinux EXPORT_SYMBOL
++0x07bf12c5    perf_pmu_migrate_context        vmlinux EXPORT_SYMBOL_GPL
++0x4268de2e    __css_put       vmlinux EXPORT_SYMBOL_GPL
++0x32fdb1ea    usb_block_urb   vmlinux EXPORT_SYMBOL_GPL
++0xd76e3ec9    fb_set_var      vmlinux EXPORT_SYMBOL
++0x7c0643d0    inet_diag_register      vmlinux EXPORT_SYMBOL_GPL
++0x598542b2    _raw_spin_lock_irqsave  vmlinux EXPORT_SYMBOL
++0xd468cd0b    sdhci_pltfm_unregister  vmlinux EXPORT_SYMBOL_GPL
++0x44f93f86    vb2_ops_wait_finish     vmlinux EXPORT_SYMBOL_GPL
++0x5be57447    dma_buf_kmap_atomic     vmlinux EXPORT_SYMBOL_GPL
++0xfac68eba    arm_elf_read_implies_exec       vmlinux EXPORT_SYMBOL
++0xca1e6f11    tcp_done        vmlinux EXPORT_SYMBOL_GPL
++0x885f07c4    snd_pcm_hw_rule_add     vmlinux EXPORT_SYMBOL
++0xb1c0c1c2    async_schedule_domain   vmlinux EXPORT_SYMBOL_GPL
++0x65497c9a    wm8994_bulk_write       vmlinux EXPORT_SYMBOL_GPL
++0x2fb6de5d    add_device_randomness   vmlinux EXPORT_SYMBOL
++0xda8af7ad    fb_find_nearest_mode    vmlinux EXPORT_SYMBOL
++0x0a575945    xfrm_count_pfkey_auth_supported vmlinux EXPORT_SYMBOL_GPL
++0x3b91f3af    snd_free_pages  vmlinux EXPORT_SYMBOL
++0xdf2278c1    snd_card_file_remove    vmlinux EXPORT_SYMBOL
++0xc848d220    blk_free_tags   vmlinux EXPORT_SYMBOL
++0xff492454    security_inode_getsecctx        vmlinux EXPORT_SYMBOL
++0xce46e140    ktime_get_ts    vmlinux EXPORT_SYMBOL_GPL
++0x3b0d157a    v4l2_m2m_ioctl_querybuf vmlinux EXPORT_SYMBOL_GPL
++0x054177ad    usb_init_urb    vmlinux EXPORT_SYMBOL_GPL
++0x1ad1f2e7    _memcpy_fromio  vmlinux EXPORT_SYMBOL
++0x95dbe078    __get_user_2    vmlinux EXPORT_SYMBOL
++0xb9acd3d9    __put_user_2    vmlinux EXPORT_SYMBOL
++0xf3797152    snd_interval_ratnum     vmlinux EXPORT_SYMBOL
++0x9d2edcd6    map_vm_area     vmlinux EXPORT_SYMBOL_GPL
++0xbfd8d187    balloon_page_enqueue    vmlinux EXPORT_SYMBOL_GPL
++0xb7e3198c    balloon_page_dequeue    vmlinux EXPORT_SYMBOL_GPL
++0x0084e86d    unregister_shrinker     vmlinux EXPORT_SYMBOL
++0x23424fab    usb_hcd_unmap_urb_setup_for_dma vmlinux EXPORT_SYMBOL_GPL
++0x6c06c6f7    scsi_device_get vmlinux EXPORT_SYMBOL
++0x970b4c98    scsi_device_put vmlinux EXPORT_SYMBOL
++0x66109b05    __pm_runtime_set_status vmlinux EXPORT_SYMBOL_GPL
++0x6d134a2a    drm_prime_sg_to_page_addr_arrays        vmlinux EXPORT_SYMBOL
++0xbce458b3    drm_framebuffer_reference       vmlinux EXPORT_SYMBOL
++0xa773e935    ipv6_dev_get_saddr      vmlinux EXPORT_SYMBOL
++0x38308727    xfrm_policy_flush       vmlinux EXPORT_SYMBOL
++0x6ebf58d8    skb_tx_error    vmlinux EXPORT_SYMBOL
++0xea793efe    snd_soc_cache_sync      vmlinux EXPORT_SYMBOL_GPL
++0xb8aa2342    __check_region  vmlinux EXPORT_SYMBOL
++0x99638333    mmc_set_blocklen        vmlinux EXPORT_SYMBOL
++0xc5e4da95    pn_sock_hash    vmlinux EXPORT_SYMBOL
++0xf6388c56    sysctl_ip_default_ttl   vmlinux EXPORT_SYMBOL
++0x0e7c2436    napi_gro_frags  vmlinux EXPORT_SYMBOL
++0x217dda13    flex_array_get  vmlinux EXPORT_SYMBOL
++0x09437748    ring_buffer_read_events_cpu     vmlinux EXPORT_SYMBOL_GPL
++0xb974ccc1    inet_diag_unregister    vmlinux EXPORT_SYMBOL_GPL
++0x0423031f    sock_sendmsg    vmlinux EXPORT_SYMBOL
++0xade88e76    snd_malloc_pages        vmlinux EXPORT_SYMBOL
++0x7ca50cfa    disk_get_part   vmlinux EXPORT_SYMBOL_GPL
++0xfed4d591    cfg80211_find_vendor_ie vmlinux EXPORT_SYMBOL
++0xe45ee6f0    netlink_kernel_release  vmlinux EXPORT_SYMBOL
++0xf310e4d9    __sock_create   vmlinux EXPORT_SYMBOL
++0x4153512b    snd_hwdep_new   vmlinux EXPORT_SYMBOL
++0x1afae5e7    down_interruptible      vmlinux EXPORT_SYMBOL
++0x2051f1d8    rtc_set_mmss    vmlinux EXPORT_SYMBOL_GPL
++0x23dfa3ab    netif_carrier_off       vmlinux EXPORT_SYMBOL
++0x10895a2a    lease_get_mtime vmlinux EXPORT_SYMBOL
++0x7cd8f487    sb_set_blocksize        vmlinux EXPORT_SYMBOL
++0x0effeb6c    srcu_barrier    vmlinux EXPORT_SYMBOL_GPL
++0xf3de55df    mmc_request_done        vmlinux EXPORT_SYMBOL
++0x46074c17    sdev_evt_alloc  vmlinux EXPORT_SYMBOL_GPL
++0x17077530    pinctrl_force_default   vmlinux EXPORT_SYMBOL_GPL
++0x0d40713a    snd_ctl_boolean_stereo_info     vmlinux EXPORT_SYMBOL
++0x3744cf36    vmalloc_to_pfn  vmlinux EXPORT_SYMBOL
++0xc783b0e1    get_task_mm     vmlinux EXPORT_SYMBOL_GPL
++0xa8950567    sdio_writew     vmlinux EXPORT_SYMBOL_GPL
++0xca443371    inet_csk_prepare_forced_close   vmlinux EXPORT_SYMBOL
++0x252f76b5    snd_soc_default_readable_register       vmlinux EXPORT_SYMBOL_GPL
++0x551bd071    __rb_erase_color        vmlinux EXPORT_SYMBOL
++0xfff8d451    fuse_request_send       vmlinux EXPORT_SYMBOL_GPL
++0x88b5647c    trace_clock_local       vmlinux EXPORT_SYMBOL_GPL
++0x683928de    nf_ct_expect_put        vmlinux EXPORT_SYMBOL_GPL
++0x7c96bf14    register_tcf_proto_ops  vmlinux EXPORT_SYMBOL
++0x76aea351    crypto_unregister_alg   vmlinux EXPORT_SYMBOL_GPL
++0x5c24f853    dump_write      vmlinux EXPORT_SYMBOL
++0x89485687    iommu_group_put vmlinux EXPORT_SYMBOL_GPL
++0x00f4d0cf    iommu_group_get vmlinux EXPORT_SYMBOL_GPL
++0xb4626765    v4l2_ctrl_new_custom    vmlinux EXPORT_SYMBOL
++0x511746c1    dump_fpu        vmlinux EXPORT_SYMBOL
++0x28927989    qdisc_watchdog_schedule_ns      vmlinux EXPORT_SYMBOL
++0x57fec35a    fuse_conn_get   vmlinux EXPORT_SYMBOL_GPL
++0xff3f1877    filp_open       vmlinux EXPORT_SYMBOL
++0x7cb7e8a5    generic_file_aio_write  vmlinux EXPORT_SYMBOL
++0x1d9317d8    smpboot_register_percpu_thread  vmlinux EXPORT_SYMBOL_GPL
++0x426362dc    __class_create  vmlinux EXPORT_SYMBOL_GPL
++0xebd6ff6e    xfrm6_prepare_output    vmlinux EXPORT_SYMBOL
++0x7c30b8c7    xfrm_calg_get_byname    vmlinux EXPORT_SYMBOL_GPL
++0xf23624a6    xfrm4_prepare_output    vmlinux EXPORT_SYMBOL
++0x6e88e56f    snd_pcm_link_rwlock     vmlinux EXPORT_SYMBOL
++0x2ebe3135    cpu_is_hotpluggable     vmlinux EXPORT_SYMBOL_GPL
++0xd3dbfbc4    _find_first_zero_bit_le vmlinux EXPORT_SYMBOL
++0x949f7fd6    snd_soc_unregister_codec        vmlinux EXPORT_SYMBOL_GPL
++0x66b5d30a    get_disk        vmlinux EXPORT_SYMBOL
++0xd5c3ad66    blk_pm_runtime_init     vmlinux EXPORT_SYMBOL
++0x55737546    __free_pages    vmlinux EXPORT_SYMBOL
++0xfa012fe7    tracepoint_probe_register       vmlinux EXPORT_SYMBOL_GPL
++0xf8802492    print_stack_trace       vmlinux EXPORT_SYMBOL_GPL
++0x50601122    of_property_match_string        vmlinux EXPORT_SYMBOL_GPL
++0x70fde9b2    vb2_reqbufs     vmlinux EXPORT_SYMBOL_GPL
++0x9b680a42    ump_dd_reference_release        vmlinux EXPORT_SYMBOL
++0x13d5d619    cfg80211_crit_proto_stopped     vmlinux EXPORT_SYMBOL
++0xd5a7d477    inet_bind       vmlinux EXPORT_SYMBOL
++0xc5495840    nf_nat_amanda_hook      vmlinux EXPORT_SYMBOL_GPL
++0xe08e58c9    qdisc_watchdog_init     vmlinux EXPORT_SYMBOL
++0xe447fb89    __register_binfmt       vmlinux EXPORT_SYMBOL
++0xbd3321ae    power_supply_class      vmlinux EXPORT_SYMBOL_GPL
++0x0ce6d0b9    usb_gadget_probe_driver vmlinux EXPORT_SYMBOL_GPL
++0xae544f3a    usb_hcd_end_port_resume vmlinux EXPORT_SYMBOL_GPL
++0x8fd8a453    pm_genpd_dev_need_restore       vmlinux EXPORT_SYMBOL_GPL
++0x7b95ab7d    class_find_device       vmlinux EXPORT_SYMBOL_GPL
++0x21455002    xfrm_init_state vmlinux EXPORT_SYMBOL
++0xf06e724d    snd_pcm_debug_name      vmlinux EXPORT_SYMBOL
++0x89ca47bf    kstrtos8_from_user      vmlinux EXPORT_SYMBOL
++0x68d0d389    crypto_init_spawn2      vmlinux EXPORT_SYMBOL_GPL
++0x01c6cb0c    cpu_cluster_pm_enter    vmlinux EXPORT_SYMBOL_GPL
++0xd1efa60f    st_accel_common_remove  vmlinux EXPORT_SYMBOL
++0xf398c9eb    vb2_create_bufs vmlinux EXPORT_SYMBOL_GPL
++0xc385cb58    perf_num_counters       vmlinux EXPORT_SYMBOL_GPL
++0x87634adf    xfrm_user_policy        vmlinux EXPORT_SYMBOL
++0xe0741a0a    netif_napi_add  vmlinux EXPORT_SYMBOL
++0xf12cddd6    skb_split       vmlinux EXPORT_SYMBOL
++0xdee12a28    input_grab_device       vmlinux EXPORT_SYMBOL
++0x95e73973    tty_port_block_til_ready        vmlinux EXPORT_SYMBOL
++0x53a3e486    regulator_get_current_limit     vmlinux EXPORT_SYMBOL_GPL
++0x5dd18380    regulator_get_init_drvdata      vmlinux EXPORT_SYMBOL_GPL
++0x8467a73f    netlink_broadcast       vmlinux EXPORT_SYMBOL
++0x6d1a8997    block_write_full_page_endio     vmlinux EXPORT_SYMBOL
++0x197519cc    shmem_file_setup        vmlinux EXPORT_SYMBOL_GPL
++0x8b8059bd    in_group_p      vmlinux EXPORT_SYMBOL
++0xc631580a    console_unlock  vmlinux EXPORT_SYMBOL
++0xe8400441    of_property_read_string_index   vmlinux EXPORT_SYMBOL_GPL
++0x0343bdf1    __i2c_board_list        vmlinux EXPORT_SYMBOL_GPL
++0xa5dd6fae    arm_pm_restart  vmlinux EXPORT_SYMBOL_GPL
++0x97fe8a2d    udp_sendmsg     vmlinux EXPORT_SYMBOL
++0x35fbd6a1    __kfifo_dma_out_prepare_r       vmlinux EXPORT_SYMBOL
++0xa3e220e7    elv_rb_former_request   vmlinux EXPORT_SYMBOL
++0xdf76bbeb    iio_pollfunc_store_time vmlinux EXPORT_SYMBOL
++0xfc30d3a1    mmc_start_req   vmlinux EXPORT_SYMBOL
++0xf53d4c26    qdisc_class_hash_destroy        vmlinux EXPORT_SYMBOL
++0x5e61da38    snd_timer_stop  vmlinux EXPORT_SYMBOL
++0xa6e1a69d    kick_all_cpus_sync      vmlinux EXPORT_SYMBOL_GPL
++0x68cb9861    sdio_register_driver    vmlinux EXPORT_SYMBOL_GPL
++0xb575c1a1    usb_kill_urb    vmlinux EXPORT_SYMBOL_GPL
++0x8ab265d2    usb_get_intf    vmlinux EXPORT_SYMBOL_GPL
++0xdbd7794d    cfg80211_ready_on_channel       vmlinux EXPORT_SYMBOL
++0xff112bd5    proc_get_parent_data    vmlinux EXPORT_SYMBOL_GPL
++0x0bec8a3d    audit_log       vmlinux EXPORT_SYMBOL
++0x5d9521f8    set_security_override_from_ctx  vmlinux EXPORT_SYMBOL
++0x235d1d10    drm_gem_prime_import    vmlinux EXPORT_SYMBOL
++0x7da24ff0    drm_helper_encoder_in_use       vmlinux EXPORT_SYMBOL
++0x6f3c606d    nfc_hci_register_device vmlinux EXPORT_SYMBOL
++0xf447e205    ip_tunnel_uninit        vmlinux EXPORT_SYMBOL_GPL
++0x5055493c    sk_wait_data    vmlinux EXPORT_SYMBOL
++0xb1b87423    crypto_remove_spawns    vmlinux EXPORT_SYMBOL_GPL
++0x4fd4e89d    ring_buffer_empty_cpu   vmlinux EXPORT_SYMBOL_GPL
++0xaa4704e1    usb_autopm_put_interface_no_suspend     vmlinux EXPORT_SYMBOL_GPL
++0x50e28c07    drm_edid_to_sad vmlinux EXPORT_SYMBOL
++0x6d57e7f8    drm_edid_to_eld vmlinux EXPORT_SYMBOL
++0x3fe12ddc    xt_replace_table        vmlinux EXPORT_SYMBOL_GPL
++0x9c3737fc    __percpu_counter_init   vmlinux EXPORT_SYMBOL
++0xf846506f    irq_set_affinity_notifier       vmlinux EXPORT_SYMBOL_GPL
++0x469a0b25    inet_hashinfo_init      vmlinux EXPORT_SYMBOL_GPL
++0x3fbf68bd    ipv4_sk_redirect        vmlinux EXPORT_SYMBOL_GPL
++0x151bc10b    end_buffer_read_sync    vmlinux EXPORT_SYMBOL
++0xb013af25    set_cpus_allowed_ptr    vmlinux EXPORT_SYMBOL_GPL
++0x227badd6    mod_timer_pinned        vmlinux EXPORT_SYMBOL
++0xf37cfbf5    dm_dispatch_request     vmlinux EXPORT_SYMBOL_GPL
++0x1d96bf04    input_mt_report_pointer_emulation       vmlinux EXPORT_SYMBOL
++0x94289922    mali_pmu_powerdown      vmlinux EXPORT_SYMBOL
++0xe9d6e0bd    pwm_request     vmlinux EXPORT_SYMBOL_GPL
++0xd66a2750    tcf_em_tree_dump        vmlinux EXPORT_SYMBOL
++0x790c22d3    neigh_for_each  vmlinux EXPORT_SYMBOL
++0x3ed096c1    sg_miter_next   vmlinux EXPORT_SYMBOL
++0x96b878b6    crypto_init_shash_spawn vmlinux EXPORT_SYMBOL_GPL
++0x1fd19684    crypto_init_ahash_spawn vmlinux EXPORT_SYMBOL_GPL
++0xedc85914    posix_timers_register_clock     vmlinux EXPORT_SYMBOL_GPL
++0xc702156b    param_get_ushort        vmlinux EXPORT_SYMBOL
++0x65bca4ff    vb2_plane_cookie        vmlinux EXPORT_SYMBOL_GPL
++0x294a6993    rtc_initialize_alarm    vmlinux EXPORT_SYMBOL_GPL
++0x6971447a    rtc_month_days  vmlinux EXPORT_SYMBOL
++0x7e64181d    usb_calc_bus_time       vmlinux EXPORT_SYMBOL_GPL
++0x5f1f36bc    drm_calc_vbltimestamp_from_scanoutpos   vmlinux EXPORT_SYMBOL
++0xe0af2dc1    regulator_is_enabled_regmap     vmlinux EXPORT_SYMBOL_GPL
++0x57c3621e    skb_pull        vmlinux EXPORT_SYMBOL
++0xeb0a7f4c    clk_register    vmlinux EXPORT_SYMBOL_GPL
++0xabc6dd63    cpufreq_sysfs_create_file       vmlinux EXPORT_SYMBOL
++0x1eee0a80    usb_find_interface      vmlinux EXPORT_SYMBOL_GPL
++0xb524d8dc    amba_find_device        vmlinux EXPORT_SYMBOL
++0x8574ca6c    gpio_request_array      vmlinux EXPORT_SYMBOL_GPL
++0x93d2422d    snmp_mib_free   vmlinux EXPORT_SYMBOL_GPL
++0x5d51bcf7    scatterwalk_start       vmlinux EXPORT_SYMBOL_GPL
++0x417e3755    sysfs_put       vmlinux EXPORT_SYMBOL_GPL
++0x2ba54bff    irq_remove_generic_chip vmlinux EXPORT_SYMBOL_GPL
++0x420c729a    vb2_fop_poll    vmlinux EXPORT_SYMBOL_GPL
++0xe6d23987    phy_start_interrupts    vmlinux EXPORT_SYMBOL
++0x1fb1615f    spi_master_resume       vmlinux EXPORT_SYMBOL_GPL
++0xcd721bb7    scsi_get_vpd_page       vmlinux EXPORT_SYMBOL_GPL
++0xac2bd611    pm_generic_restore_noirq        vmlinux EXPORT_SYMBOL_GPL
++0xe0b7aa47    drm_i2c_encoder_dpms    vmlinux EXPORT_SYMBOL
++0x9dfdf722    gpio_free_array vmlinux EXPORT_SYMBOL_GPL
++0x7345660c    xfrm_state_check_expire vmlinux EXPORT_SYMBOL
++0xd5dba10e    sock_diag_unregister_inet_compat        vmlinux EXPORT_SYMBOL_GPL
++0xfd719be0    netdev_boot_setup_check vmlinux EXPORT_SYMBOL
++0xa9c6e543    sock_i_uid      vmlinux EXPORT_SYMBOL
++0x2dfe841c    sock_i_ino      vmlinux EXPORT_SYMBOL
++0x4bc2dc22    seq_bitmap      vmlinux EXPORT_SYMBOL
++0x4b8e839a    cpufreq_global_kobject  vmlinux EXPORT_SYMBOL
++0xc12cf8f8    v4l2_ctrl_replace       vmlinux EXPORT_SYMBOL
++0xf3dd036d    regulator_set_voltage_time      vmlinux EXPORT_SYMBOL_GPL
++0x88826167    ip_build_and_send_pkt   vmlinux EXPORT_SYMBOL_GPL
++0xd09ce8d0    register_gifconf        vmlinux EXPORT_SYMBOL
++0xaa6901ac    __kfifo_out_r   vmlinux EXPORT_SYMBOL
++0x64f7667b    crypto_rng_type vmlinux EXPORT_SYMBOL_GPL
++0x457594fa    crypto_alg_list vmlinux EXPORT_SYMBOL_GPL
++0x665b8183    sync_inode_metadata     vmlinux EXPORT_SYMBOL
++0x03026722    mempool_alloc   vmlinux EXPORT_SYMBOL
++0x0034f927    unregister_wide_hw_breakpoint   vmlinux EXPORT_SYMBOL_GPL
++0x86f6b99d    synchronize_rcu_expedited       vmlinux EXPORT_SYMBOL_GPL
++0xec4d9e3a    clk_get_sys     vmlinux EXPORT_SYMBOL
++0x1b6b3f33    cpufreq_unregister_driver       vmlinux EXPORT_SYMBOL_GPL
++0x56ca80ea    drm_mode_validate_clocks        vmlinux EXPORT_SYMBOL
++0xa66a1f63    drm_rmmap_locked        vmlinux EXPORT_SYMBOL
++0x6b07a31b    regulator_get_voltage_sel_regmap        vmlinux EXPORT_SYMBOL_GPL
++0x5107f9ce    gpiochip_find   vmlinux EXPORT_SYMBOL_GPL
++0x05365f80    cfg80211_cac_event      vmlinux EXPORT_SYMBOL
++0xc05ac2c8    cfg80211_classify8021d  vmlinux EXPORT_SYMBOL
++0x92be9264    snd_soc_register_platform       vmlinux EXPORT_SYMBOL_GPL
++0xfaf79bc2    __srcu_read_lock        vmlinux EXPORT_SYMBOL_GPL
++0xada5e980    media_entity_pipeline_start     vmlinux EXPORT_SYMBOL_GPL
++0x74fbf451    drm_mm_init_scan_with_range     vmlinux EXPORT_SYMBOL
++0xd03c7700    secure_ipv4_port_ephemeral      vmlinux EXPORT_SYMBOL_GPL
++0x9c9ec2a0    proc_dointvec_minmax    vmlinux EXPORT_SYMBOL
++0x8d772b8c    v4l2_clk_get    vmlinux EXPORT_SYMBOL
++0x32680bfc    usb_function_unregister vmlinux EXPORT_SYMBOL_GPL
++0x6dd8ac23    dev_uc_add_excl vmlinux EXPORT_SYMBOL
++0xced0fa87    dev_mc_add_excl vmlinux EXPORT_SYMBOL
++0x51cc09c6    kmalloc_caches  vmlinux EXPORT_SYMBOL
++0x3ef23944    i2c_bus_type    vmlinux EXPORT_SYMBOL_GPL
++0x015f6d7d    kmap    vmlinux EXPORT_SYMBOL
++0x0b9a5c65    icmpv6_send     vmlinux EXPORT_SYMBOL
++0x6625c30d    blk_queue_make_request  vmlinux EXPORT_SYMBOL
++0x25dd3b83    sysfs_add_link_to_group vmlinux EXPORT_SYMBOL_GPL
++0x472d363a    truncate_pagecache_range        vmlinux EXPORT_SYMBOL
++0x0bf3e830    put_page        vmlinux EXPORT_SYMBOL
++0x74954462    timecounter_read        vmlinux EXPORT_SYMBOL_GPL
++0x3aa9f288    iio_channel_get vmlinux EXPORT_SYMBOL_GPL
++0x1fd6672b    video_device_release_empty      vmlinux EXPORT_SYMBOL
++0x931dcc9d    usbnet_pause_rx vmlinux EXPORT_SYMBOL_GPL
++0x4c83a264    do_take_over_console    vmlinux EXPORT_SYMBOL_GPL
++0xe2dd67e5    regulator_set_current_limit     vmlinux EXPORT_SYMBOL_GPL
++0xb23f3373    nf_conntrack_lock       vmlinux EXPORT_SYMBOL_GPL
++0xebfa66fa    security_inode_setsecctx        vmlinux EXPORT_SYMBOL
++0x819ed3be    vfs_getattr     vmlinux EXPORT_SYMBOL
++0x2fad0dbe    led_classdev_resume     vmlinux EXPORT_SYMBOL_GPL
++0xbc497919    rtc_device_register     vmlinux EXPORT_SYMBOL_GPL
++0xd58c665a    input_reset_device      vmlinux EXPORT_SYMBOL
++0x34c728d0    tty_ldisc_deref vmlinux EXPORT_SYMBOL_GPL
++0xfb28827b    inet_del_protocol       vmlinux EXPORT_SYMBOL
++0x95587915    neigh_update    vmlinux EXPORT_SYMBOL
++0xc9b8c308    __kfifo_dma_out_prepare vmlinux EXPORT_SYMBOL
++0xd9b9b70a    put_io_context  vmlinux EXPORT_SYMBOL
++0xac7726b4    blk_queue_io_min        vmlinux EXPORT_SYMBOL
++0xcf807506    nobh_truncate_page      vmlinux EXPORT_SYMBOL
++0x43ec231b    iio_device_free vmlinux EXPORT_SYMBOL
++0x95ae5064    phy_stop        vmlinux EXPORT_SYMBOL
++0xb69d1c51    spi_bitbang_start       vmlinux EXPORT_SYMBOL_GPL
++0x87876bed    drm_kms_helper_poll_enable      vmlinux EXPORT_SYMBOL
++0x045072cd    nf_ct_port_nla_policy   vmlinux EXPORT_SYMBOL_GPL
++0x4be7fb63    up      vmlinux EXPORT_SYMBOL
++0xf8a32b55    icmp_send       vmlinux EXPORT_SYMBOL
++0x69f7d81d    path_get        vmlinux EXPORT_SYMBOL
++0xd715763b    iov_iter_copy_from_user_atomic  vmlinux EXPORT_SYMBOL
++0xc7b9fe08    drm_property_create_bitmask     vmlinux EXPORT_SYMBOL
++0x671a649b    xfrm_state_update       vmlinux EXPORT_SYMBOL
++0xce3c5240    crypto_grab_aead        vmlinux EXPORT_SYMBOL_GPL
++0xb590822d    hrtimer_start   vmlinux EXPORT_SYMBOL_GPL
++0xaebe783e    get_pid_task    vmlinux EXPORT_SYMBOL_GPL
++0xa8bcfa1a    usb_deregister_dev      vmlinux EXPORT_SYMBOL_GPL
++0xc398c5f3    usb_hcd_is_primary_hcd  vmlinux EXPORT_SYMBOL_GPL
++0x7c45fec1    pm_generic_resume_noirq vmlinux EXPORT_SYMBOL_GPL
++0x6c702af7    sysctl_udp_rmem_min     vmlinux EXPORT_SYMBOL
++0x9b3122cd    dev_open        vmlinux EXPORT_SYMBOL
++0x7ee7a9f8    lock_sock_fast  vmlinux EXPORT_SYMBOL
++0xc3b7e3fb    snd_cards       vmlinux EXPORT_SYMBOL
++0x82bbf933    ilookup vmlinux EXPORT_SYMBOL
++0x4302d0eb    free_pages      vmlinux EXPORT_SYMBOL
++0xefc91531    irq_create_of_mapping   vmlinux EXPORT_SYMBOL_GPL
++0xb90f9844    sdhci_resume_host       vmlinux EXPORT_SYMBOL_GPL
++0x8ec22c0b    nat_q931_hook   vmlinux EXPORT_SYMBOL_GPL
++0x03592ea0    security_unix_stream_connect    vmlinux EXPORT_SYMBOL
++0x4397c48f    generic_file_fsync      vmlinux EXPORT_SYMBOL
++0x5154c361    unlock_new_inode        vmlinux EXPORT_SYMBOL
++0xa9b83487    __f_setown      vmlinux EXPORT_SYMBOL
++0x9ccb1788    irq_create_direct_mapping       vmlinux EXPORT_SYMBOL_GPL
++0xf82f16b3    execute_in_process_context      vmlinux EXPORT_SYMBOL_GPL
++0xcd06de19    mdiobus_free    vmlinux EXPORT_SYMBOL
++0xfd99623a    ip_frag_ecn_table       vmlinux EXPORT_SYMBOL
++0x17ee142e    xt_find_table_lock      vmlinux EXPORT_SYMBOL_GPL
++0x62737e1d    sock_unregister vmlinux EXPORT_SYMBOL
++0x67095031    kset_register   vmlinux EXPORT_SYMBOL
++0x84ffea8b    idr_preload     vmlinux EXPORT_SYMBOL
++0xd29fb507    fput    vmlinux EXPORT_SYMBOL
++0xe3d6f284    fb_find_mode_cvt        vmlinux EXPORT_SYMBOL
++0x14d4a9c5    _change_bit     vmlinux EXPORT_SYMBOL
++0x54411a42    posix_timer_event       vmlinux EXPORT_SYMBOL_GPL
++0x2a79ac13    clkdev_add      vmlinux EXPORT_SYMBOL
++0x3d6f446b    platform_device_alloc   vmlinux EXPORT_SYMBOL_GPL
++0xf85bebf9    dev_printk_emit vmlinux EXPORT_SYMBOL
++0xde36a037    ip6_frag_init   vmlinux EXPORT_SYMBOL
++0x31e23d78    __fsnotify_parent       vmlinux EXPORT_SYMBOL_GPL
++0xdea4fcaa    pm_qos_add_request      vmlinux EXPORT_SYMBOL_GPL
++0x1976aa06    param_ops_bool  vmlinux EXPORT_SYMBOL
++0x98ba0e88    pm_generic_suspend_noirq        vmlinux EXPORT_SYMBOL_GPL
++0xecefd1b6    display_entity_get_params       vmlinux EXPORT_SYMBOL_GPL
++0xdfb5c1e5    add_disk        vmlinux EXPORT_SYMBOL
++0x5754706e    media_entity_get        vmlinux EXPORT_SYMBOL_GPL
++0xbd008b38    media_entity_put        vmlinux EXPORT_SYMBOL_GPL
++0x5d1e2494    usb_ep0_reinit  vmlinux EXPORT_SYMBOL_GPL
++0x0ae4b94c    drm_ht_remove   vmlinux EXPORT_SYMBOL
++0x6ab922b2    regulator_get_drvdata   vmlinux EXPORT_SYMBOL_GPL
++0x4432d365    __udp6_lib_lookup       vmlinux EXPORT_SYMBOL_GPL
++0x08696053    inet_shutdown   vmlinux EXPORT_SYMBOL
++0x52212010    __tracepoint_block_bio_remap    vmlinux EXPORT_SYMBOL_GPL
++0xc29afc9a    posix_lock_file_wait    vmlinux EXPORT_SYMBOL
++0x01fd453e    usbhid_lookup_quirk     vmlinux EXPORT_SYMBOL_GPL
++0x90705b7f    syscon_node_to_regmap   vmlinux EXPORT_SYMBOL_GPL
++0xf72d56a2    regulator_set_voltage_sel_regmap        vmlinux EXPORT_SYMBOL_GPL
++0xa308e150    nfc_hci_disconnect_gate vmlinux EXPORT_SYMBOL
++0x7707c1b0    xt_unregister_table     vmlinux EXPORT_SYMBOL_GPL
++0x4e830a3e    strnicmp        vmlinux EXPORT_SYMBOL
++0x48f2cf7c    vmalloc_to_page vmlinux EXPORT_SYMBOL
++0x3dca446d    drm_handle_vblank       vmlinux EXPORT_SYMBOL
++0x22ca070b    uart_remove_one_port    vmlinux EXPORT_SYMBOL
++0x1d027e4b    snd_pcm_format_signed   vmlinux EXPORT_SYMBOL
++0x3535ae4a    blk_update_request      vmlinux EXPORT_SYMBOL_GPL
++0x02649054    security_sock_rcv_skb   vmlinux EXPORT_SYMBOL
++0x547077ec    __wake_up_bit   vmlinux EXPORT_SYMBOL
++0x1c5541bd    cpufreq_boost_enabled   vmlinux EXPORT_SYMBOL_GPL
++0x6d186427    usb_get_hcd     vmlinux EXPORT_SYMBOL_GPL
++0x8eff9111    drm_ht_find_item        vmlinux EXPORT_SYMBOL
++0xd9d18f03    fbcon_set_bitops        vmlinux EXPORT_SYMBOL
++0xfaea036f    sock_release    vmlinux EXPORT_SYMBOL
++0xa414882d    add_wait_queue_exclusive        vmlinux EXPORT_SYMBOL
++0x06e80ae6    s3c_adc_register        vmlinux EXPORT_SYMBOL_GPL
++0x63805ac9    usb_hcd_giveback_urb    vmlinux EXPORT_SYMBOL_GPL
++0xf8d54998    ump_dd_handle_create_from_phys_blocks   vmlinux EXPORT_SYMBOL
++0x44242685    drm_prime_gem_destroy   vmlinux EXPORT_SYMBOL
++0x4faff87a    drm_i2c_encoder_mode_fixup      vmlinux EXPORT_SYMBOL
++0x0f995f4e    tty_port_tty_wakeup     vmlinux EXPORT_SYMBOL_GPL
++0x91b2790d    regulator_map_voltage_ascend    vmlinux EXPORT_SYMBOL_GPL
++0x0e29d022    nf_nat_icmp_reply_translation   vmlinux EXPORT_SYMBOL_GPL
++0x75811312    crc_ccitt_table vmlinux EXPORT_SYMBOL
++0xe9eb0c04    d_add_ci        vmlinux EXPORT_SYMBOL
++0x4c55b4df    led_trigger_rename_static       vmlinux EXPORT_SYMBOL_GPL
++0x6f344bb9    v4l2_calc_aspect_ratio  vmlinux EXPORT_SYMBOL_GPL
++0xc4f83bea    drm_debugfs_create_files        vmlinux EXPORT_SYMBOL
++0x9ae51e43    tty_register_device_attr        vmlinux EXPORT_SYMBOL_GPL
++0x80c70b19    phys_mem_access_prot    vmlinux EXPORT_SYMBOL
++0x17770200    __skb_checksum_complete_head    vmlinux EXPORT_SYMBOL
++0x1eeb848e    __percpu_counter_sum    vmlinux EXPORT_SYMBOL
++0xd74289f9    __percpu_counter_add    vmlinux EXPORT_SYMBOL
++0xa77a369d    idr_init        vmlinux EXPORT_SYMBOL
++0x8e5c580a    ida_init        vmlinux EXPORT_SYMBOL
++0xb99d677c    mpage_readpage  vmlinux EXPORT_SYMBOL
++0x70bc17d7    inode_wait      vmlinux EXPORT_SYMBOL
++0xd6ee688f    vmalloc vmlinux EXPORT_SYMBOL
++0xf31b3fd1    workqueue_set_max_active        vmlinux EXPORT_SYMBOL_GPL
++0x9745c52a    of_fixed_clk_setup      vmlinux EXPORT_SYMBOL_GPL
++0xbfd6a20b    phy_ethtool_set_wol     vmlinux EXPORT_SYMBOL
++0x64004900    phy_ethtool_get_wol     vmlinux EXPORT_SYMBOL
++0x28492539    spi_bitbang_transfer    vmlinux EXPORT_SYMBOL_GPL
++0x6552f2d8    unlink_framebuffer      vmlinux EXPORT_SYMBOL
++0xbdf2580d    __raw_readsl    vmlinux EXPORT_SYMBOL
++0xabe519d2    blk_queue_io_opt        vmlinux EXPORT_SYMBOL
++0x05b2af42    bdgrab  vmlinux EXPORT_SYMBOL
++0xd4c14632    system_unbound_wq       vmlinux EXPORT_SYMBOL_GPL
++0x098859e1    usbnet_cdc_status       vmlinux EXPORT_SYMBOL_GPL
++0xd1bd52ba    tty_port_raise_dtr_rts  vmlinux EXPORT_SYMBOL
++0x4ea1f5a2    drm_gem_object_free     vmlinux EXPORT_SYMBOL
++0x86d53c76    mb_cache_entry_find_first       vmlinux EXPORT_SYMBOL
++0xf0b9f940    usb_function_activate   vmlinux EXPORT_SYMBOL_GPL
++0x9d2ee507    scsi_adjust_queue_depth vmlinux EXPORT_SYMBOL
++0x4bca6b0c    drm_get_edid    vmlinux EXPORT_SYMBOL
++0x4a5d2ace    tcp_unregister_congestion_control       vmlinux EXPORT_SYMBOL_GPL
++0x0274dc2b    netif_get_num_default_rss_queues        vmlinux EXPORT_SYMBOL
++0x53be6f80    bio_split       vmlinux EXPORT_SYMBOL
++0x1fc0da41    lock_rename     vmlinux EXPORT_SYMBOL
++0xbe421975    __locks_copy_lock       vmlinux EXPORT_SYMBOL
++0x69e3cb9f    mutex_lock_killable     vmlinux EXPORT_SYMBOL
++0x9c612795    v4l2_chip_match_i2c_client      vmlinux EXPORT_SYMBOL
++0xd2f84424    i2c_bit_add_bus vmlinux EXPORT_SYMBOL
++0x421cdcbd    usb_function_deactivate vmlinux EXPORT_SYMBOL_GPL
++0x63a86872    class_destroy   vmlinux EXPORT_SYMBOL_GPL
++0x231d4001    fb_edid_add_monspecs    vmlinux EXPORT_SYMBOL
++0xb01a37d3    gpiochip_remove vmlinux EXPORT_SYMBOL_GPL
++0xcc2b7257    tcp_check_req   vmlinux EXPORT_SYMBOL
++0x16270acd    tcp_init_sock   vmlinux EXPORT_SYMBOL
++0x143dc3b0    netlink_unicast vmlinux EXPORT_SYMBOL
++0x8452993c    neigh_sysctl_register   vmlinux EXPORT_SYMBOL
++0xce602df6    cgroup_is_descendant    vmlinux EXPORT_SYMBOL_GPL
++0xdddba0ab    exynos_g2d_get_ver_ioctl        vmlinux EXPORT_SYMBOL_GPL
++0xf2c642ed    tty_port_tty_hangup     vmlinux EXPORT_SYMBOL_GPL
++0x7d086e6f    snd_soc_put_volsw_range vmlinux EXPORT_SYMBOL_GPL
++0xaf23bb74    snd_soc_get_volsw_range vmlinux EXPORT_SYMBOL_GPL
++0x01b2facc    snd_timer_start vmlinux EXPORT_SYMBOL
++0x1e693956    set_nlink       vmlinux EXPORT_SYMBOL
++0xdcb0349b    sys_close       vmlinux EXPORT_SYMBOL
++0xaf348da7    cpu_pm_exit     vmlinux EXPORT_SYMBOL_GPL
++0x77d1afb4    kill_pgrp       vmlinux EXPORT_SYMBOL
++0x3b9d009a    drm_format_plane_cpp    vmlinux EXPORT_SYMBOL
++0x2acd3e60    fat_build_inode vmlinux EXPORT_SYMBOL_GPL
++0x0f3ef271    seq_read        vmlinux EXPORT_SYMBOL
++0x712fb5a8    is_bad_inode    vmlinux EXPORT_SYMBOL
++0x253bdb78    param_get_int   vmlinux EXPORT_SYMBOL
++0xd35fa891    st_sensors_write_event_config   vmlinux EXPORT_SYMBOL
++0x203bef91    device_wakeup_disable   vmlinux EXPORT_SYMBOL_GPL
++0xd454eabb    tcf_hash_new_index      vmlinux EXPORT_SYMBOL
++0x235e7e6a    shash_ahash_finup       vmlinux EXPORT_SYMBOL_GPL
++0x60384c87    start_tty       vmlinux EXPORT_SYMBOL
++0x6513a3fa    fb_get_color_depth      vmlinux EXPORT_SYMBOL
++0x7ffc8718    gpio_set_debounce       vmlinux EXPORT_SYMBOL_GPL
++0x6c95cbd5    phonet_proto_register   vmlinux EXPORT_SYMBOL
++0xa01cac38    nf_ct_get_tuplepr       vmlinux EXPORT_SYMBOL_GPL
++0x3e872db6    __netdev_pick_tx        vmlinux EXPORT_SYMBOL
++0x981f509d    skb_free_datagram_locked        vmlinux EXPORT_SYMBOL
++0x93e0379d    kernel_sock_shutdown    vmlinux EXPORT_SYMBOL
++0x878eae99    snd_pcm_add_chmap_ctls  vmlinux EXPORT_SYMBOL_GPL
++0xd454865d    snd_pcm_notify  vmlinux EXPORT_SYMBOL
++0xa735db59    prandom_u32     vmlinux EXPORT_SYMBOL
++0x8e864a86    posix_acl_chmod vmlinux EXPORT_SYMBOL
++0xf9910a86    notify_change   vmlinux EXPORT_SYMBOL
++0x423b589c    follow_up       vmlinux EXPORT_SYMBOL
++0xa577a850    param_get_short vmlinux EXPORT_SYMBOL
++0x24b55d2b    of_find_i2c_adapter_by_node     vmlinux EXPORT_SYMBOL
++0x6d0f1f89    dm_table_get_mode       vmlinux EXPORT_SYMBOL
++0x2ca4ebcd    regulator_set_drvdata   vmlinux EXPORT_SYMBOL_GPL
++0x02196324    __aeabi_idiv    vmlinux EXPORT_SYMBOL
++0xf0e3bec8    nf_log_bind_pf  vmlinux EXPORT_SYMBOL
++0xd12698d0    skb_copy_and_csum_datagram_iovec        vmlinux EXPORT_SYMBOL
++0xd23bebab    sock_no_ioctl   vmlinux EXPORT_SYMBOL
++0xf401a5f4    get_user_pages_fast     vmlinux EXPORT_SYMBOL_GPL
++0xca85d8cf    tracepoint_probe_update_all     vmlinux EXPORT_SYMBOL_GPL
++0x54740eb7    get_cpu_idle_time       vmlinux EXPORT_SYMBOL_GPL
++0x2a3aa678    _test_and_clear_bit     vmlinux EXPORT_SYMBOL
++0x694967d9    nf_conntrack_find_get   vmlinux EXPORT_SYMBOL_GPL
++0x19a2badf    snd_soc_codec_set_sysclk        vmlinux EXPORT_SYMBOL_GPL
++0x93a2419d    simple_empty    vmlinux EXPORT_SYMBOL
++0x68a13545    vm_mmap vmlinux EXPORT_SYMBOL
++0x224190b8    shmem_read_mapping_page_gfp     vmlinux EXPORT_SYMBOL_GPL
++0xd859f1d5    dw_mci_pltfm_register   vmlinux EXPORT_SYMBOL_GPL
++0xc955c267    serio_unregister_child_port     vmlinux EXPORT_SYMBOL
++0xcbee09f7    scsi_remove_device      vmlinux EXPORT_SYMBOL
++0xcd579f54    xfrm_cfg_mutex  vmlinux EXPORT_SYMBOL
++0xb63be252    __sk_mem_schedule       vmlinux EXPORT_SYMBOL
++0xcde172ac    radix_tree_gang_lookup_tag_slot vmlinux EXPORT_SYMBOL
++0x61860fe5    blk_queue_merge_bvec    vmlinux EXPORT_SYMBOL
++0xd223c00d    fuse_file_poll  vmlinux EXPORT_SYMBOL_GPL
++0x4b6e004b    mnt_want_write_file     vmlinux EXPORT_SYMBOL_GPL
++0x11ad8ba6    __hid_register_driver   vmlinux EXPORT_SYMBOL_GPL
++0x3d8ed8f5    hid_disconnect  vmlinux EXPORT_SYMBOL_GPL
++0x70cf032f    usb_hcd_irq     vmlinux EXPORT_SYMBOL_GPL
++0xc0a9a9a1    hci_register_cb vmlinux EXPORT_SYMBOL
++0x83b21051    ip_ct_attach    vmlinux EXPORT_SYMBOL
++0x24eb8d39    dev_set_mtu     vmlinux EXPORT_SYMBOL
++0xbd5c42d9    crypto_unregister_template      vmlinux EXPORT_SYMBOL_GPL
++0x2deda4a1    security_sk_classify_flow       vmlinux EXPORT_SYMBOL
++0xe694a9ce    bd_link_disk_holder     vmlinux EXPORT_SYMBOL_GPL
++0xf1a33551    usb_string_ids_tab      vmlinux EXPORT_SYMBOL_GPL
++0x565b6892    uuid_le_gen     vmlinux EXPORT_SYMBOL_GPL
++0x68956406    static_key_slow_dec     vmlinux EXPORT_SYMBOL_GPL
++0x335c570f    enable_percpu_irq       vmlinux EXPORT_SYMBOL_GPL
++0x02e1a3ed    should_remove_suid      vmlinux EXPORT_SYMBOL
++0x0626da5f    od_unregister_powersave_bias_handler    vmlinux EXPORT_SYMBOL_GPL
++0x4dcfd46b    scsi_free_host_dev      vmlinux EXPORT_SYMBOL
++0xfec445a3    driver_register vmlinux EXPORT_SYMBOL_GPL
++0x3d1b2e32    find_lock_page  vmlinux EXPORT_SYMBOL
++0x92ea202d    srcu_notifier_chain_unregister  vmlinux EXPORT_SYMBOL_GPL
++0xdb9d11d6    iio_buffer_store_enable vmlinux EXPORT_SYMBOL
++0x2ceca451    input_ff_create vmlinux EXPORT_SYMBOL_GPL
++0x6e3d17ac    device_destroy  vmlinux EXPORT_SYMBOL_GPL
++0xb8d2fd38    wiphy_register  vmlinux EXPORT_SYMBOL
++0xfa4d8a1f    unregister_pernet_device        vmlinux EXPORT_SYMBOL_GPL
++0x4c86184b    remove_wait_queue       vmlinux EXPORT_SYMBOL
++0x4845c423    param_array_ops vmlinux EXPORT_SYMBOL
++0x2cd6eb8b    input_ff_destroy        vmlinux EXPORT_SYMBOL_GPL
++0xb9500ec7    mfd_cell_disable        vmlinux EXPORT_SYMBOL
++0x1a2759ff    platform_get_irq_byname vmlinux EXPORT_SYMBOL_GPL
++0x8daf9344    napi_get_frags  vmlinux EXPORT_SYMBOL
++0x60c805dd    sk_stream_write_space   vmlinux EXPORT_SYMBOL
++0x570e3195    scsi_verify_blk_ioctl   vmlinux EXPORT_SYMBOL
++0xecbe66b8    sysfs_notify_dirent     vmlinux EXPORT_SYMBOL_GPL
++0x158df5f3    kill_bdev       vmlinux EXPORT_SYMBOL
++0x3eb2b460    v4l2_event_unsubscribe  vmlinux EXPORT_SYMBOL_GPL
++0x8e38bb44    ipv6_dup_options        vmlinux EXPORT_SYMBOL_GPL
++0xe306f9d8    cgroup_attach_task_all  vmlinux EXPORT_SYMBOL_GPL
++0x6b06fdce    delayed_work_timer_fn   vmlinux EXPORT_SYMBOL
++0x8104c3bb    phy_register_fixup_for_id       vmlinux EXPORT_SYMBOL
++0x46d3b28c    __div0  vmlinux EXPORT_SYMBOL
++0x7ead817c    __idr_pre_get   vmlinux EXPORT_SYMBOL
++0x6cc299a1    zap_vma_ptes    vmlinux EXPORT_SYMBOL_GPL
++0x1f0972cb    drm_fasync      vmlinux EXPORT_SYMBOL
++0x35c653fb    xfrm_policy_bysel_ctx   vmlinux EXPORT_SYMBOL
++0x8e81d5af    tcp_sendmsg     vmlinux EXPORT_SYMBOL
++0xf9ebc368    snd_soc_new_ac97_codec  vmlinux EXPORT_SYMBOL_GPL
++0x4528c501    elv_rb_del      vmlinux EXPORT_SYMBOL
++0x056bf03a    elv_rb_add      vmlinux EXPORT_SYMBOL
++0x5b2c1c77    init_user_ns    vmlinux EXPORT_SYMBOL_GPL
++0x0b5996ef    st_sensors_sysfs_sampling_frequency_avail       vmlinux EXPORT_SYMBOL
++0x3a17a800    vb2_dqbuf       vmlinux EXPORT_SYMBOL_GPL
++0xe55de32d    i2c_smbus_write_word_data       vmlinux EXPORT_SYMBOL
++0xd1c2d294    ip_mc_leave_group       vmlinux EXPORT_SYMBOL
++0x05843ade    netif_skb_features      vmlinux EXPORT_SYMBOL
++0x00632780    work_busy       vmlinux EXPORT_SYMBOL_GPL
++0x06d2c86e    pm_runtime_set_memalloc_noio    vmlinux EXPORT_SYMBOL_GPL
++0x97c6c5dd    drm_pci_exit    vmlinux EXPORT_SYMBOL
++0x1a1938a1    drm_pci_init    vmlinux EXPORT_SYMBOL
++0xf7a0d470    __sk_mem_reclaim        vmlinux EXPORT_SYMBOL
++0xc4f45210    d_prune_aliases vmlinux EXPORT_SYMBOL
++0x498d293a    trace_buffer_unlock_commit      vmlinux EXPORT_SYMBOL_GPL
++0x12a38747    usleep_range    vmlinux EXPORT_SYMBOL
++0xef409b74    kmsg_dump_get_line      vmlinux EXPORT_SYMBOL_GPL
++0xdd3202eb    lcd_device_unregister   vmlinux EXPORT_SYMBOL
++0x1fa2ae70    tcf_hash_check  vmlinux EXPORT_SYMBOL
++0xa43b9539    memcpy_fromiovecend     vmlinux EXPORT_SYMBOL
++0x4b4f96c3    blk_make_request        vmlinux EXPORT_SYMBOL
++0xe290713d    __pagevec_release       vmlinux EXPORT_SYMBOL
++0x1e047854    warn_slowpath_fmt       vmlinux EXPORT_SYMBOL
++0xbca701eb    vb2_ioctl_expbuf        vmlinux EXPORT_SYMBOL_GPL
++0x01508e49    cfg80211_cqm_rssi_notify        vmlinux EXPORT_SYMBOL
++0xff3e2712    nla_reserve_nohdr       vmlinux EXPORT_SYMBOL
++0xc442fa87    ilookup5        vmlinux EXPORT_SYMBOL
++0x1650bf27    rcutorture_record_progress      vmlinux EXPORT_SYMBOL_GPL
++0x3507a132    _raw_spin_lock_irq      vmlinux EXPORT_SYMBOL
++0x1b24bd6e    prepare_creds   vmlinux EXPORT_SYMBOL
++0x97c03a7e    mutex_unlock    vmlinux EXPORT_SYMBOL
++0x5bf35318    hid_unregister_driver   vmlinux EXPORT_SYMBOL_GPL
++0xd989fc54    usb_autopm_put_interface        vmlinux EXPORT_SYMBOL_GPL
++0x64d3db1a    dev_addr_flush  vmlinux EXPORT_SYMBOL
++0x6d92d23c    snd_dma_reserve_buf     vmlinux EXPORT_SYMBOL
++0x83a476ce    bitmap_scnlistprintf    vmlinux EXPORT_SYMBOL
++0x61660b0f    thermal_notify_framework        vmlinux EXPORT_SYMBOL_GPL
++0x1e925a2f    drm_unplug_dev  vmlinux EXPORT_SYMBOL
++0xef76af89    wiphy_rfkill_set_hw_state       vmlinux EXPORT_SYMBOL
++0x920aacca    nl_table_lock   vmlinux EXPORT_SYMBOL_GPL
++0x69b0b6dd    blkdev_get_by_dev       vmlinux EXPORT_SYMBOL
++0xd87601cc    ring_buffer_unlock_commit       vmlinux EXPORT_SYMBOL_GPL
++0xee7e7bbe    simple_fill_super       vmlinux EXPORT_SYMBOL
++0xf8fffd67    have_submounts  vmlinux EXPORT_SYMBOL
++0x07cc4a5d    printk_timed_ratelimit  vmlinux EXPORT_SYMBOL
++0x274944b3    sock_queue_err_skb      vmlinux EXPORT_SYMBOL
++0x7b03f66f    snd_add_device_sysfs_file       vmlinux EXPORT_SYMBOL
++0x1f8db7f9    ring_buffer_overrun_cpu vmlinux EXPORT_SYMBOL_GPL
++0x0faef0ed    __tasklet_schedule      vmlinux EXPORT_SYMBOL
++0x8ec68aa9    dev_load        vmlinux EXPORT_SYMBOL
++0xf4f14de6    rtnl_trylock    vmlinux EXPORT_SYMBOL
++0xac0ba8c1    blk_iopoll_disable      vmlinux EXPORT_SYMBOL
++0x1bb201ff    debugfs_create_u16      vmlinux EXPORT_SYMBOL_GPL
++0xcae7b03f    bio_add_page    vmlinux EXPORT_SYMBOL
++0x61af42e6    init_pid_ns     vmlinux EXPORT_SYMBOL_GPL
++0x3c420cae    v4l2_m2m_buf_queue      vmlinux EXPORT_SYMBOL_GPL
++0x0fa2a45e    __memzero       vmlinux EXPORT_SYMBOL
++0x674c71f7    ipt_unregister_table    vmlinux EXPORT_SYMBOL
++0x77ecac9f    zlib_inflateEnd vmlinux EXPORT_SYMBOL
++0x7ca5798f    contig_page_data        vmlinux EXPORT_SYMBOL
++0x3b66dc5f    vb2_buffer_done vmlinux EXPORT_SYMBOL_GPL
++0x07b291d1    usb_unlink_anchored_urbs        vmlinux EXPORT_SYMBOL_GPL
++0x06fbba42    usbnet_write_cmd        vmlinux EXPORT_SYMBOL_GPL
++0xc6b4b7b5    inet_frag_evictor       vmlinux EXPORT_SYMBOL
++0x9d44f8f6    xt_unregister_target    vmlinux EXPORT_SYMBOL
++0x0dca487b    led_trigger_show        vmlinux EXPORT_SYMBOL_GPL
++0xb423dba1    console_blanked vmlinux EXPORT_SYMBOL
++0x23679939    __iowrite32_copy        vmlinux EXPORT_SYMBOL_GPL
++0x38361fbf    config_group_init_type_name     vmlinux EXPORT_SYMBOL
++0x668fe138    __sb_end_write  vmlinux EXPORT_SYMBOL
++0xd67296c6    from_kgid       vmlinux EXPORT_SYMBOL
++0x2fd8e085    sdhci_pltfm_clk_get_max_clock   vmlinux EXPORT_SYMBOL_GPL
++0x4222235b    v4l2_fh_is_singular     vmlinux EXPORT_SYMBOL_GPL
++0x27cbc081    nf_conntrack_unregister_notifier        vmlinux EXPORT_SYMBOL_GPL
++0x638eeb4d    fib_rules_register      vmlinux EXPORT_SYMBOL_GPL
++0xfaf98462    bitrev32        vmlinux EXPORT_SYMBOL
++0x0399203b    simple_transaction_read vmlinux EXPORT_SYMBOL
++0x8a99a016    mempool_free_slab       vmlinux EXPORT_SYMBOL
++0x41c72de9    generic_setxattr        vmlinux EXPORT_SYMBOL
++0x75d94810    generic_getxattr        vmlinux EXPORT_SYMBOL
++0xe384a102    usb_speed_string        vmlinux EXPORT_SYMBOL_GPL
++0xf70fecd0    pm_generic_resume_early vmlinux EXPORT_SYMBOL_GPL
++0x48cb14ac    pm_generic_thaw vmlinux EXPORT_SYMBOL_GPL
++0x1d061186    cfg80211_connect_result vmlinux EXPORT_SYMBOL
++0xdd8800ff    jbd2_journal_set_features       vmlinux EXPORT_SYMBOL
++0xdadafdd7    mpage_readpages vmlinux EXPORT_SYMBOL
++0x4045c494    filter_match_preds      vmlinux EXPORT_SYMBOL_GPL
++0x5482fcef    usbnet_start_xmit       vmlinux EXPORT_SYMBOL_GPL
++0x9e074139    __pm_runtime_resume     vmlinux EXPORT_SYMBOL_GPL
++0x4df119fa    __bitmap_parse  vmlinux EXPORT_SYMBOL
++0x2cfc8703    __wait_on_buffer        vmlinux EXPORT_SYMBOL
++0x4a8907de    cancel_delayed_work_sync        vmlinux EXPORT_SYMBOL
++0x4c5566c5    extcon_set_cable_state  vmlinux EXPORT_SYMBOL_GPL
++0x1114ede2    extcon_get_cable_state  vmlinux EXPORT_SYMBOL_GPL
++0xcac8aaf3    i2c_unlock_adapter      vmlinux EXPORT_SYMBOL_GPL
++0xc3107f52    regmap_raw_read vmlinux EXPORT_SYMBOL_GPL
++0x6b807a5f    gpio_sysfs_set_active_low       vmlinux EXPORT_SYMBOL_GPL
++0xad4d490d    sock_create     vmlinux EXPORT_SYMBOL
++0x1bcfb1fa    debugfs_create_x32      vmlinux EXPORT_SYMBOL_GPL
++0xb0440408    bprm_change_interp      vmlinux EXPORT_SYMBOL
++0xbf7f05c3    kill_litter_super       vmlinux EXPORT_SYMBOL
++0xcb34aaf6    iommu_domain_window_disable     vmlinux EXPORT_SYMBOL_GPL
++0x7c9e0f69    clk_add_alias   vmlinux EXPORT_SYMBOL
++0xad84bef8    dm_table_event  vmlinux EXPORT_SYMBOL
++0xc91b3468    class_dev_iter_next     vmlinux EXPORT_SYMBOL_GPL
++0x64038eb3    inet_proto_csum_replace4        vmlinux EXPORT_SYMBOL
++0xb6e03027    neigh_direct_output     vmlinux EXPORT_SYMBOL
++0xce9a717b    blk_rq_check_limits     vmlinux EXPORT_SYMBOL_GPL
++0x75bda77a    seq_hlist_next  vmlinux EXPORT_SYMBOL
++0xb9c24bba    account_page_dirtied    vmlinux EXPORT_SYMBOL
++0xde037eaa    __lock_page_killable    vmlinux EXPORT_SYMBOL_GPL
++0x73c2d5f0    usb_free_urb    vmlinux EXPORT_SYMBOL_GPL
++0x9faa8d4a    tty_prepare_flip_string_flags   vmlinux EXPORT_SYMBOL_GPL
++0xb8de9394    tty_prepare_flip_string vmlinux EXPORT_SYMBOL_GPL
++0x4db0cbcf    fib_rules_unregister    vmlinux EXPORT_SYMBOL_GPL
++0x5fe6f617    skb_copy_bits   vmlinux EXPORT_SYMBOL
++0x71bf6cf0    __blk_end_request_all   vmlinux EXPORT_SYMBOL
++0xede99a14    crypto_register_ahash   vmlinux EXPORT_SYMBOL_GPL
++0xbdb3fd8c    sysfs_remove_link       vmlinux EXPORT_SYMBOL_GPL
++0x8924eb1e    rcu_force_quiescent_state       vmlinux EXPORT_SYMBOL_GPL
++0xe77924e8    drm_match_cea_mode      vmlinux EXPORT_SYMBOL
++0x189868d7    get_random_bytes_arch   vmlinux EXPORT_SYMBOL
++0x3aeef779    tcp_make_synack vmlinux EXPORT_SYMBOL
++0xc1c0b09b    snd_soc_add_codec_controls      vmlinux EXPORT_SYMBOL_GPL
++0xcc402882    find_get_page   vmlinux EXPORT_SYMBOL
++0x7d59dd46    pm_wq   vmlinux EXPORT_SYMBOL_GPL
++0x9a47820d    hrtimer_forward vmlinux EXPORT_SYMBOL_GPL
++0xa1f0ebea    bit_waitqueue   vmlinux EXPORT_SYMBOL
++0x52bd048a    iio_get_channel_type    vmlinux EXPORT_SYMBOL_GPL
++0x37b330b1    mii_check_gmii_support  vmlinux EXPORT_SYMBOL
++0x964bc3de    dma_async_device_register       vmlinux EXPORT_SYMBOL
++0x0adc9704    display_timings_release vmlinux EXPORT_SYMBOL_GPL
++0xe6c818f2    sock_common_recvmsg     vmlinux EXPORT_SYMBOL
++0xb62a00b3    mem_cgroup_subsys       vmlinux EXPORT_SYMBOL
++0x64652950    __video_register_device vmlinux EXPORT_SYMBOL
++0x9572f9d0    inet_csk_addr2sockaddr  vmlinux EXPORT_SYMBOL_GPL
++0xeda0d76e    gen_estimator_active    vmlinux EXPORT_SYMBOL
++0x8251bcc3    bitmap_release_region   vmlinux EXPORT_SYMBOL
++0x5567c227    kernel_cpustat  vmlinux EXPORT_SYMBOL
++0x9133fe16    vb2_write       vmlinux EXPORT_SYMBOL_GPL
++0x9bb89701    cfg80211_roamed vmlinux EXPORT_SYMBOL
++0x5eb03c4c    ip_mc_inc_group vmlinux EXPORT_SYMBOL
++0x06438115    tcp_orphan_count        vmlinux EXPORT_SYMBOL_GPL
++0x43804ba2    fat_attach      vmlinux EXPORT_SYMBOL_GPL
++0x30788c84    sysfs_remove_bin_file   vmlinux EXPORT_SYMBOL_GPL
++0xb11bad4f    register_wide_hw_breakpoint     vmlinux EXPORT_SYMBOL_GPL
++0xbd8b253c    tcf_exts_validate       vmlinux EXPORT_SYMBOL
++0xb81960ca    snprintf        vmlinux EXPORT_SYMBOL
++0x7cae600c    get_io_context  vmlinux EXPORT_SYMBOL
++0x70bb651d    __tracepoint_block_rq_remap     vmlinux EXPORT_SYMBOL_GPL
++0x9be42ea4    proc_mkdir_mode vmlinux EXPORT_SYMBOL
++0xf0701cc6    tag_pages_for_writeback vmlinux EXPORT_SYMBOL
++0x3cf525fb    hid_dump_device vmlinux EXPORT_SYMBOL_GPL
++0x219e9575    wakeup_source_unregister        vmlinux EXPORT_SYMBOL_GPL
++0xff43d5b5    cfg80211_check_station_change   vmlinux EXPORT_SYMBOL
++0x2296c00d    crypto_attr_u32 vmlinux EXPORT_SYMBOL_GPL
++0x710eaf23    PDE_DATA        vmlinux EXPORT_SYMBOL
++0xc1fac3b3    __bread vmlinux EXPORT_SYMBOL
++0x55af945f    follow_pfn      vmlinux EXPORT_SYMBOL
++0x275ae863    make_kuid       vmlinux EXPORT_SYMBOL
++0x54d8b7ba    hrtimer_init    vmlinux EXPORT_SYMBOL_GPL
++0x7c8f0303    dma_buf_export_named    vmlinux EXPORT_SYMBOL_GPL
++0x079f8b38    devm_kzalloc    vmlinux EXPORT_SYMBOL_GPL
++0x9ddbb3f6    tty_port_link_device    vmlinux EXPORT_SYMBOL_GPL
++0x9e8d08a7    pinctrl_find_and_add_gpio_range vmlinux EXPORT_SYMBOL_GPL
++0x9ceb163c    memcpy_toiovec  vmlinux EXPORT_SYMBOL
++0x44c38935    v4l2_subdev_g_ext_ctrls vmlinux EXPORT_SYMBOL
++0xc5fab8f0    v4l2_subdev_s_ext_ctrls vmlinux EXPORT_SYMBOL
++0x4cf092e4    scsi_report_opcode      vmlinux EXPORT_SYMBOL
++0x1b6314fd    in_aton vmlinux EXPORT_SYMBOL
++0x1027ae8c    neigh_resolve_output    vmlinux EXPORT_SYMBOL
++0xc492c2d9    snd_card_register       vmlinux EXPORT_SYMBOL
++0xa3018431    posix_unblock_lock      vmlinux EXPORT_SYMBOL
++0xf3d6e3aa    __mnt_is_readonly       vmlinux EXPORT_SYMBOL_GPL
++0x87984b16    __tracepoint_cpu_idle   vmlinux EXPORT_SYMBOL_GPL
++0x89205531    cfb_imageblit   vmlinux EXPORT_SYMBOL
++0x3bbf46ea    vga_base        vmlinux EXPORT_SYMBOL
++0x6fea34fd    tcp_close       vmlinux EXPORT_SYMBOL
++0x7bd5c87c    inet_add_offload        vmlinux EXPORT_SYMBOL
++0x024ea18c    nf_nat_irc_hook vmlinux EXPORT_SYMBOL_GPL
++0x18d1ab6f    nf_nat_ftp_hook vmlinux EXPORT_SYMBOL_GPL
++0xeb780f0e    nfq_ct_nat_hook vmlinux EXPORT_SYMBOL_GPL
++0x06277150    __scm_send      vmlinux EXPORT_SYMBOL
++0xc49eea50    skb_try_coalesce        vmlinux EXPORT_SYMBOL
++0xec007de7    snd_soc_dapm_new_controls       vmlinux EXPORT_SYMBOL_GPL
++0xa07ed110    xz_dec_init     vmlinux EXPORT_SYMBOL
++0x3dd4d3a7    bprintf vmlinux EXPORT_SYMBOL_GPL
++0xa4a0aeb8    try_to_free_buffers     vmlinux EXPORT_SYMBOL
++0xe9f098a6    wait_iff_congested      vmlinux EXPORT_SYMBOL
++0xcb5bf3f1    __put_cred      vmlinux EXPORT_SYMBOL
++0x3f80e476    get_thermal_instance    vmlinux EXPORT_SYMBOL
++0xb6979f60    usb_register_dev        vmlinux EXPORT_SYMBOL_GPL
++0xe0d8227f    scsi_dma_map    vmlinux EXPORT_SYMBOL
++0xa5de5bb1    blk_queue_bypass_start  vmlinux EXPORT_SYMBOL_GPL
++0xb9617f29    dm_path_uevent  vmlinux EXPORT_SYMBOL_GPL
++0xd909cae6    serial8250_clear_and_reinit_fifos       vmlinux EXPORT_SYMBOL_GPL
++0x755da9a0    register_framebuffer    vmlinux EXPORT_SYMBOL
++0x9ed685ee    iov_iter_advance        vmlinux EXPORT_SYMBOL
++0xf86a3a9f    clk_gate_ops    vmlinux EXPORT_SYMBOL_GPL
++0xfcc9ce6a    mmc_of_parse    vmlinux EXPORT_SYMBOL
++0xb486e84e    mfd_remove_devices      vmlinux EXPORT_SYMBOL
++0xc5a484ac    pm_generic_suspend_late vmlinux EXPORT_SYMBOL_GPL
++0x3cd06035    add_input_randomness    vmlinux EXPORT_SYMBOL_GPL
++0xf50d8f59    regulator_enable_regmap vmlinux EXPORT_SYMBOL_GPL
++0x09774d0b    pinctrl_force_sleep     vmlinux EXPORT_SYMBOL_GPL
++0xc7c3c6d2    ip6_tnl_dst_reset       vmlinux EXPORT_SYMBOL_GPL
++0x225d0386    nf_ct_l4proto_pernet_register   vmlinux EXPORT_SYMBOL_GPL
++0xf7d31a5d    nf_ct_l3proto_pernet_register   vmlinux EXPORT_SYMBOL_GPL
++0x8401c62f    scsi_unblock_requests   vmlinux EXPORT_SYMBOL
++0x8ca1a1dc    device_remove_bin_file  vmlinux EXPORT_SYMBOL_GPL
++0xccb1ba6b    of_get_drm_display_mode vmlinux EXPORT_SYMBOL_GPL
++0xe3f48cba    tty_port_free_xmit_buf  vmlinux EXPORT_SYMBOL
++0xec1b043e    regulator_suspend_prepare       vmlinux EXPORT_SYMBOL_GPL
++0xecbda9c5    display_entity_get      vmlinux EXPORT_SYMBOL_GPL
++0x13b89dee    pinctrl_request_gpio    vmlinux EXPORT_SYMBOL_GPL
++0xdcb3410a    nf_ct_deliver_cached_events     vmlinux EXPORT_SYMBOL_GPL
++0x32ddd5b6    call_rcu        vmlinux EXPORT_SYMBOL_GPL
++0xf1267848    usb_composite_unregister        vmlinux EXPORT_SYMBOL_GPL
++0x877509c0    crypto_nivaead_type     vmlinux EXPORT_SYMBOL_GPL
++0x9263cf47    bdi_writeout_inc        vmlinux EXPORT_SYMBOL_GPL
++0x26f6b499    iio_str_to_fixpoint     vmlinux EXPORT_SYMBOL_GPL
++0x7267db00    hwrng_unregister        vmlinux EXPORT_SYMBOL_GPL
++0x19cbf31d    xfrm6_rcv_spi   vmlinux EXPORT_SYMBOL
++0xe5a42822    ip_tunnel_change_mtu    vmlinux EXPORT_SYMBOL_GPL
++0xf236a5de    tcf_exts_change vmlinux EXPORT_SYMBOL
++0x058b95e3    snd_pcm_release_substream       vmlinux EXPORT_SYMBOL
++0x9a6e183a    __idr_remove_all        vmlinux EXPORT_SYMBOL
++0x7b9bf08e    disk_stack_limits       vmlinux EXPORT_SYMBOL
++0x9879932b    crypto_register_notifier        vmlinux EXPORT_SYMBOL_GPL
++0xd220cf8a    jiffies_to_timespec     vmlinux EXPORT_SYMBOL
++0xce4f758e    dma_release_from_coherent       vmlinux EXPORT_SYMBOL
++0xe238b99e    pskb_put        vmlinux EXPORT_SYMBOL_GPL
++0xe11dd614    fib_table_lookup        vmlinux EXPORT_SYMBOL_GPL
++0x3862b0a7    snd_soc_bytes_put       vmlinux EXPORT_SYMBOL_GPL
++0xa5ed8e2c    inc_nlink       vmlinux EXPORT_SYMBOL
++0xf43bdbf8    smpboot_unregister_percpu_thread        vmlinux EXPORT_SYMBOL_GPL
++0x8a1ab4ee    timeval_to_jiffies      vmlinux EXPORT_SYMBOL
++0x39375395    i2c_master_send vmlinux EXPORT_SYMBOL
++0x3a517b2b    device_reprobe  vmlinux EXPORT_SYMBOL_GPL
++0xb22e34bd    wiphy_free      vmlinux EXPORT_SYMBOL
++0x76a01893    __netlink_dump_start    vmlinux EXPORT_SYMBOL
++0xa96c3c3b    dev_kfree_skb_any       vmlinux EXPORT_SYMBOL
++0xfdaeced1    snd_ctl_new1    vmlinux EXPORT_SYMBOL
++0xb4f57a24    security_task_getsecid  vmlinux EXPORT_SYMBOL
++0x09d71f87    seq_open        vmlinux EXPORT_SYMBOL
++0x29a73c29    mnt_drop_write  vmlinux EXPORT_SYMBOL_GPL
++0xbcdd5b99    iommu_group_set_name    vmlinux EXPORT_SYMBOL_GPL
++0x7e394c4e    sysctl_local_reserved_ports     vmlinux EXPORT_SYMBOL
++0x094bac5f    simple_readpage vmlinux EXPORT_SYMBOL
++0x5a39720e    __lock_page     vmlinux EXPORT_SYMBOL
++0xb140d14c    ring_buffer_read        vmlinux EXPORT_SYMBOL_GPL
++0xf499fdb2    rcu_barrier_bh  vmlinux EXPORT_SYMBOL_GPL
++0x03d9fff7    synchronize_srcu_expedited      vmlinux EXPORT_SYMBOL_GPL
++0x1c0ae7d7    drm_mm_init_scan        vmlinux EXPORT_SYMBOL
++0x8320bea8    __umodsi3       vmlinux EXPORT_SYMBOL
++0xc3706dce    tcp_cong_avoid_ai       vmlinux EXPORT_SYMBOL_GPL
++0xab6bde28    sysctl_max_syn_backlog  vmlinux EXPORT_SYMBOL
++0x5d90d2ce    blk_delay_queue vmlinux EXPORT_SYMBOL
++0xefdd70ce    security_secid_to_secctx        vmlinux EXPORT_SYMBOL
++0x77d67659    follow_down     vmlinux EXPORT_SYMBOL
++0x083eb1cc    __generic_file_aio_write        vmlinux EXPORT_SYMBOL
++0x46646afc    filemap_write_and_wait_range    vmlinux EXPORT_SYMBOL
++0xc72c4abb    usb_altnum_to_altsetting        vmlinux EXPORT_SYMBOL_GPL
++0x0a98333a    snd_soc_dpcm_get_substream      vmlinux EXPORT_SYMBOL_GPL
++0x360b1afe    probe_irq_mask  vmlinux EXPORT_SYMBOL
++0x8f2154e4    cfg80211_rx_mgmt        vmlinux EXPORT_SYMBOL
++0xafa574d0    snd_soc_jack_notifier_unregister        vmlinux EXPORT_SYMBOL_GPL
++0x93af86c9    get_write_access        vmlinux EXPORT_SYMBOL
++0x2350c4a6    invalidate_mapping_pages        vmlinux EXPORT_SYMBOL
++0x84c6c77a    genphy_read_status      vmlinux EXPORT_SYMBOL
++0x96fb7fef    drm_mode_create_dithering_property      vmlinux EXPORT_SYMBOL
++0xef56f51e    redraw_screen   vmlinux EXPORT_SYMBOL
++0x2394545f    tty_unregister_driver   vmlinux EXPORT_SYMBOL
++0xf3bf0bce    __bitmap_complement     vmlinux EXPORT_SYMBOL
++0xe2e8065e    memdup_user     vmlinux EXPORT_SYMBOL
++0x3bdd0f94    v4l2_prio_change        vmlinux EXPORT_SYMBOL
++0x7ab9b430    drm_poll        vmlinux EXPORT_SYMBOL
++0x760d494e    pinctrl_find_gpio_range_from_pin        vmlinux EXPORT_SYMBOL_GPL
++0xcca27eeb    del_timer       vmlinux EXPORT_SYMBOL
++0x39e773af    thermal_cooling_device_unregister       vmlinux EXPORT_SYMBOL_GPL
++0xcba9dbcf    dma_get_required_mask   vmlinux EXPORT_SYMBOL_GPL
++0x2fb1d233    nf_log_unbind_pf        vmlinux EXPORT_SYMBOL
++0x460f7531    wait_rcu_gp     vmlinux EXPORT_SYMBOL_GPL
++0x9bfaf424    usb_get_current_frame_number    vmlinux EXPORT_SYMBOL_GPL
++0xad9bbf9f    hci_suspend_dev vmlinux EXPORT_SYMBOL
++0x56c5a136    tcp_v4_send_check       vmlinux EXPORT_SYMBOL
++0x0a4862b9    nf_ct_expect_find_get   vmlinux EXPORT_SYMBOL_GPL
++0x30e3e930    dev_close       vmlinux EXPORT_SYMBOL
++0xc3e46db4    snd_pcm_lib_free_pages  vmlinux EXPORT_SYMBOL
++0x3b735a2b    __mark_inode_dirty      vmlinux EXPORT_SYMBOL
++0x91437bc9    dma_buf_put     vmlinux EXPORT_SYMBOL_GPL
++0x8e09c957    dma_buf_get     vmlinux EXPORT_SYMBOL_GPL
++0x98aba977    ip6_update_pmtu vmlinux EXPORT_SYMBOL_GPL
++0x019daa72    noop_qdisc      vmlinux EXPORT_SYMBOL
++0x240646b9    sock_alloc_send_skb     vmlinux EXPORT_SYMBOL
++0x871f2cb1    snd_soc_dapm_nc_pin     vmlinux EXPORT_SYMBOL_GPL
++0x97440f69    snd_card_disconnect     vmlinux EXPORT_SYMBOL
++0xd9ce8f0c    strnlen vmlinux EXPORT_SYMBOL
++0xe7c9dbc0    unregister_filesystem   vmlinux EXPORT_SYMBOL
++0x4abbe3c2    vm_brk  vmlinux EXPORT_SYMBOL
++0x2439abc9    irq_domain_add_simple   vmlinux EXPORT_SYMBOL_GPL
++0xd418e1c0    adjust_resource vmlinux EXPORT_SYMBOL
++0x31c0c2d1    dm_put  vmlinux EXPORT_SYMBOL_GPL
++0x140e371b    v4l2_of_get_remote_port_parent  vmlinux EXPORT_SYMBOL
++0x3adbd595    v4l2_field_names        vmlinux EXPORT_SYMBOL
++0xdcece020    xfrm_state_insert       vmlinux EXPORT_SYMBOL
++0xf8fe3d0b    kmsg_dump_register      vmlinux EXPORT_SYMBOL_GPL
++0x40728a63    xt_find_revision        vmlinux EXPORT_SYMBOL_GPL
++0xcb534ec9    __destroy_inode vmlinux EXPORT_SYMBOL
++0xea1f5b88    samsung_rev     vmlinux EXPORT_SYMBOL
++0xd3dd145a    tcp_is_cwnd_limited     vmlinux EXPORT_SYMBOL_GPL
++0x392697b4    nf_conntrack_l3proto_generic    vmlinux EXPORT_SYMBOL_GPL
++0x2549013a    snd_soc_dai_set_channel_map     vmlinux EXPORT_SYMBOL_GPL
++0x421e53cf    blk_rq_unmap_user       vmlinux EXPORT_SYMBOL
++0xacf1d33d    crypto_mod_get  vmlinux EXPORT_SYMBOL_GPL
++0x0bc477a2    irq_set_irq_type        vmlinux EXPORT_SYMBOL
++0xce2840e7    irq_set_irq_wake        vmlinux EXPORT_SYMBOL
++0x2650d835    sysctl_ip_early_demux   vmlinux EXPORT_SYMBOL
++0x07e472e5    __remove_inode_hash     vmlinux EXPORT_SYMBOL
++0x82b7cda8    __lru_cache_add vmlinux EXPORT_SYMBOL
++0x457b77ca    of_fixed_factor_clk_setup       vmlinux EXPORT_SYMBOL_GPL
++0x840b929e    v4l2_device_unregister_subdev   vmlinux EXPORT_SYMBOL_GPL
++0x6128b5fc    __printk_ratelimit      vmlinux EXPORT_SYMBOL
++0xcc1f1c3d    inet_twdr_hangman       vmlinux EXPORT_SYMBOL_GPL
++0x71faed49    __blk_end_request_cur   vmlinux EXPORT_SYMBOL
++0xab5cbfa1    __blk_end_request_err   vmlinux EXPORT_SYMBOL_GPL
++0xb2682405    utf8_to_utf32   vmlinux EXPORT_SYMBOL
++0x9621849f    ring_buffer_event_data  vmlinux EXPORT_SYMBOL_GPL
++0x2761c400    pm_generic_restore_early        vmlinux EXPORT_SYMBOL_GPL
++0x36d31f9e    crypto_sha1_update      vmlinux EXPORT_SYMBOL
++0x8798e453    __tracepoint_kfree      vmlinux EXPORT_SYMBOL
++0x247ba373    override_creds  vmlinux EXPORT_SYMBOL
++0x131db64a    system_long_wq  vmlinux EXPORT_SYMBOL_GPL
++0xc0d26387    kmsg_dump_unregister    vmlinux EXPORT_SYMBOL_GPL
++0x6b132713    __clk_register  vmlinux EXPORT_SYMBOL_GPL
++0x5292f4ea    scsi_prep_return        vmlinux EXPORT_SYMBOL
++0x34a13791    __pm_runtime_disable    vmlinux EXPORT_SYMBOL_GPL
++0xa10db0ce    phy_pm_runtime_get_sync vmlinux EXPORT_SYMBOL_GPL
++0x1b62df19    arm_iommu_create_mapping        vmlinux EXPORT_SYMBOL_GPL
++0x606d0b09    secure_tcpv6_sequence_number    vmlinux EXPORT_SYMBOL
++0xa75bc594    blkdev_issue_zeroout    vmlinux EXPORT_SYMBOL
++0x8f12669a    irq_linear_revmap       vmlinux EXPORT_SYMBOL_GPL
++0x938244d0    handle_level_irq        vmlinux EXPORT_SYMBOL_GPL
++0xb336e1d2    extcon_set_cable_state_ vmlinux EXPORT_SYMBOL_GPL
++0x067ef5d5    extcon_get_cable_state_ vmlinux EXPORT_SYMBOL_GPL
++0x8d22bb58    iommu_group_alloc       vmlinux EXPORT_SYMBOL_GPL
++0xa7e20df3    clk_mux_ops     vmlinux EXPORT_SYMBOL_GPL
++0x7f9eeaae    input_register_handle   vmlinux EXPORT_SYMBOL
++0x6cc78c5c    set_irq_flags   vmlinux EXPORT_SYMBOL_GPL
++0xc781bd9f    rfkill_resume_polling   vmlinux EXPORT_SYMBOL
++0x982e6b6d    ieee80211_radiotap_iterator_init        vmlinux EXPORT_SYMBOL
++0xf30fda27    lzo1x_decompress_safe   vmlinux EXPORT_SYMBOL_GPL
++0x42b364ef    scatterwalk_done        vmlinux EXPORT_SYMBOL_GPL
++0x2158c0d7    kern_unmount    vmlinux EXPORT_SYMBOL
++0xd31ccb06    of_machine_is_compatible        vmlinux EXPORT_SYMBOL
++0xd6d49c42    sdio_writesb    vmlinux EXPORT_SYMBOL_GPL
++0xe6fa2163    v4l2_async_notifier_unregister  vmlinux EXPORT_SYMBOL
++0x20234f83    nla_append      vmlinux EXPORT_SYMBOL
++0x4cf41ed3    skcipher_geniv_free     vmlinux EXPORT_SYMBOL_GPL
++0x4bc07110    jbd2_journal_lock_updates       vmlinux EXPORT_SYMBOL
++0xf37671d2    vfs_llseek      vmlinux EXPORT_SYMBOL
++0x8720876b    __page_file_index       vmlinux EXPORT_SYMBOL_GPL
++0x609d9c25    __irq_set_handler       vmlinux EXPORT_SYMBOL_GPL
++0x2d17a0e1    cgroup_taskset_size     vmlinux EXPORT_SYMBOL_GPL
++0xabe27502    v4l2_ctrl_query_fill    vmlinux EXPORT_SYMBOL
++0x5b1a060c    usb_control_msg vmlinux EXPORT_SYMBOL_GPL
++0xe59c5ea4    snd_dma_free_pages      vmlinux EXPORT_SYMBOL
++0x85541e31    iterate_fd      vmlinux EXPORT_SYMBOL
++0x7ceaf0d5    generic_handle_irq      vmlinux EXPORT_SYMBOL_GPL
++0x46feb099    dm_read_arg     vmlinux EXPORT_SYMBOL
++0xe8125c91    dev_set_drvdata vmlinux EXPORT_SYMBOL
++0x8d60d310    dev_get_drvdata vmlinux EXPORT_SYMBOL
++0x84510ec6    bt_sock_unlink  vmlinux EXPORT_SYMBOL
++0x14f626f7    snd_soc_dapm_add_routes vmlinux EXPORT_SYMBOL_GPL
++0x5d1c1bac    blocking_notifier_chain_cond_register   vmlinux EXPORT_SYMBOL_GPL
++0xefd5b1f1    nfc_hci_disconnect_all_gates    vmlinux EXPORT_SYMBOL
++0x009c0acf    __xfrm_state_destroy    vmlinux EXPORT_SYMBOL
++0x256e5691    bfifo_qdisc_ops vmlinux EXPORT_SYMBOL
++0x1f8544b8    panic_timeout   vmlinux EXPORT_SYMBOL_GPL
++0x5b4e379c    of_prop_next_u32        vmlinux EXPORT_SYMBOL_GPL
++0x8106095a    v4l2_prio_max   vmlinux EXPORT_SYMBOL
++0xfff74a32    usb_unpoison_urb        vmlinux EXPORT_SYMBOL_GPL
++0xc532db16    tty_port_init   vmlinux EXPORT_SYMBOL
++0xa20ce1b8    net_msg_warn    vmlinux EXPORT_SYMBOL
++0x2aa97a28    __sock_recv_timestamp   vmlinux EXPORT_SYMBOL_GPL
++0x6225637e    md5_transform   vmlinux EXPORT_SYMBOL
++0xa3301b08    noop_fsync      vmlinux EXPORT_SYMBOL
++0x31ab0e28    extcon_dev_unregister   vmlinux EXPORT_SYMBOL_GPL
++0xc5176fe9    usb_hcd_resume_root_hub vmlinux EXPORT_SYMBOL_GPL
++0x13bdb1fd    cfg80211_ibss_joined    vmlinux EXPORT_SYMBOL
++0x587763dd    blkdev_issue_write_same vmlinux EXPORT_SYMBOL
++0x627b7988    crypto_hash_walk_first  vmlinux EXPORT_SYMBOL_GPL
++0x85d438aa    scsi_add_host_with_dma  vmlinux EXPORT_SYMBOL
++0x2b26ce97    devres_remove_group     vmlinux EXPORT_SYMBOL_GPL
++0x8e007d5e    inet_sendpage   vmlinux EXPORT_SYMBOL
++0xbb713e6d    sk_filter_release_rcu   vmlinux EXPORT_SYMBOL
++0xf1dc9acb    dev_get_by_index_rcu    vmlinux EXPORT_SYMBOL
++0x5364397d    dev_set_allmulti        vmlinux EXPORT_SYMBOL
++0xd20a4e9e    snd_ctl_remove_id       vmlinux EXPORT_SYMBOL
++0xea10655a    __bitmap_intersects     vmlinux EXPORT_SYMBOL
++0xf313da4e    sha_transform   vmlinux EXPORT_SYMBOL
++0x9b6eb137    ksize   vmlinux EXPORT_SYMBOL
++0x38869d88    kstat   vmlinux EXPORT_SYMBOL
++0x43caf714    mmc_can_erase   vmlinux EXPORT_SYMBOL
++0xa42810a9    i2c_add_adapter vmlinux EXPORT_SYMBOL
++0xaf5ddb02    input_mt_report_finger_count    vmlinux EXPORT_SYMBOL
++0x3a09b033    drm_mmap        vmlinux EXPORT_SYMBOL
++0xcc16f79c    drm_kms_helper_poll_fini        vmlinux EXPORT_SYMBOL
++0xe707d823    __aeabi_uidiv   vmlinux EXPORT_SYMBOL
++0xcd2a33d7    hci_conn_security       vmlinux EXPORT_SYMBOL
++0xd456425d    kobject_set_name        vmlinux EXPORT_SYMBOL
++0x60642a60    shmem_truncate_range    vmlinux EXPORT_SYMBOL_GPL
++0xa3e7c113    ring_buffer_iter_peek   vmlinux EXPORT_SYMBOL_GPL
++0xa5efbf4c    async_synchronize_full  vmlinux EXPORT_SYMBOL_GPL
++0x3ac75973    dm_send_uevents vmlinux EXPORT_SYMBOL_GPL
++0x47f757de    elf_platform    vmlinux EXPORT_SYMBOL
++0x48994b32    bt_debugfs      vmlinux EXPORT_SYMBOL_GPL
++0xc3f4c43b    set_device_ro   vmlinux EXPORT_SYMBOL
++0xbb038ce4    perf_unregister_guest_info_callbacks    vmlinux EXPORT_SYMBOL_GPL
++0x8cc44150    of_clk_src_simple_get   vmlinux EXPORT_SYMBOL_GPL
++0x09378170    shash_attr_alg  vmlinux EXPORT_SYMBOL_GPL
++0x63eb9355    panic_blink     vmlinux EXPORT_SYMBOL
++0x37df5b58    usb_anchor_urb  vmlinux EXPORT_SYMBOL_GPL
++0x665ccdb6    __sync_dirty_buffer     vmlinux EXPORT_SYMBOL
++0xb370f2b0    kmap_high       vmlinux EXPORT_SYMBOL
++0xc3042166    cancel_dirty_page       vmlinux EXPORT_SYMBOL
++0xf4fc2d6c    __ring_buffer_alloc     vmlinux EXPORT_SYMBOL_GPL
++0x82072614    tasklet_kill    vmlinux EXPORT_SYMBOL
++0x653cd720    exynos_g2d_set_cmdlist_ioctl    vmlinux EXPORT_SYMBOL_GPL
++0xa2a78b0e    blk_post_runtime_resume vmlinux EXPORT_SYMBOL
++0xf7f02ddf    bio_endio       vmlinux EXPORT_SYMBOL
++0x269b337f    account_page_redirty    vmlinux EXPORT_SYMBOL
++0x85c7f674    ring_buffer_normalize_time_stamp        vmlinux EXPORT_SYMBOL_GPL
++0xf4597085    i2c_use_client  vmlinux EXPORT_SYMBOL
++0x2da746c5    scsi_print_command      vmlinux EXPORT_SYMBOL
++0xd0e73a87    amba_driver_register    vmlinux EXPORT_SYMBOL
++0x3810da45    nf_ct_expect_unregister_notifier        vmlinux EXPORT_SYMBOL_GPL
++0x50b236e9    eth_prepare_mac_addr_change     vmlinux EXPORT_SYMBOL
++0xd32c0bf4    sk_stop_timer   vmlinux EXPORT_SYMBOL
++0xffdb82bc    sg_free_table   vmlinux EXPORT_SYMBOL
++0xfcbba27f    locks_remove_posix      vmlinux EXPORT_SYMBOL
++0xb0b85f47    ring_buffer_iter_reset  vmlinux EXPORT_SYMBOL_GPL
++0x43b0c9c3    preempt_schedule        vmlinux EXPORT_SYMBOL
++0x7c010229    of_platform_bus_probe   vmlinux EXPORT_SYMBOL
++0xf74656ab    regulator_can_change_voltage    vmlinux EXPORT_SYMBOL_GPL
++0x5d5b5a16    radix_tree_delete       vmlinux EXPORT_SYMBOL
++0x4b37f24f    of_extcon_get_extcon_dev        vmlinux EXPORT_SYMBOL_GPL
++0x728be72e    pm_generic_thaw_noirq   vmlinux EXPORT_SYMBOL_GPL
++0x94de4a33    tcp_slow_start  vmlinux EXPORT_SYMBOL_GPL
++0x4a73178a    dev_activate    vmlinux EXPORT_SYMBOL
++0x7649cfce    __pneigh_lookup vmlinux EXPORT_SYMBOL_GPL
++0xaafcd87b    devm_iounmap    vmlinux EXPORT_SYMBOL
++0x3bfc99a5    devm_ioremap    vmlinux EXPORT_SYMBOL
++0x5541ea93    on_each_cpu     vmlinux EXPORT_SYMBOL
++0x176af8ec    cdc_ncm_rx_verify_ndp16 vmlinux EXPORT_SYMBOL_GPL
++0x572d7fe7    pn544_hci_remove        vmlinux EXPORT_SYMBOL
++0x74e5ff1a    udpv6_encap_enable      vmlinux EXPORT_SYMBOL
++0x7a08f61d    snd_pcm_set_sync        vmlinux EXPORT_SYMBOL
++0x164b50d3    nla_reserve     vmlinux EXPORT_SYMBOL
++0x08758d9c    bioset_create   vmlinux EXPORT_SYMBOL
++0x08365975    drm_gem_object_lookup   vmlinux EXPORT_SYMBOL
++0x862b9816    cpu_topology    vmlinux EXPORT_SYMBOL_GPL
++0x3722cf9f    rtnl_put_cacheinfo      vmlinux EXPORT_SYMBOL_GPL
++0xea124bd1    gcd     vmlinux EXPORT_SYMBOL_GPL
++0xce3e95d0    ihold   vmlinux EXPORT_SYMBOL
++0xd11031b4    names_cachep    vmlinux EXPORT_SYMBOL
++0x8890cade    invalidate_inode_pages2_range   vmlinux EXPORT_SYMBOL_GPL
++0x83130f62    cancel_delayed_work     vmlinux EXPORT_SYMBOL
++0xcbc428db    __cpufreq_driver_target vmlinux EXPORT_SYMBOL_GPL
++0xd6233445    xfrm_policy_register_afinfo     vmlinux EXPORT_SYMBOL
++0xc8afb46b    snd_info_create_card_entry      vmlinux EXPORT_SYMBOL
++0xb7850524    crypto_unregister_shashes       vmlinux EXPORT_SYMBOL_GPL
++0x4acc9be5    dentry_path_raw vmlinux EXPORT_SYMBOL
++0x475ea860    xfrm_sad_getinfo        vmlinux EXPORT_SYMBOL
++0x9429e18f    netif_napi_del  vmlinux EXPORT_SYMBOL
++0x03a3ce75    crypto_register_alg     vmlinux EXPORT_SYMBOL_GPL
++0x1a3e0511    debugfs_rename  vmlinux EXPORT_SYMBOL_GPL
++0xb69186d9    simple_open     vmlinux EXPORT_SYMBOL
++0xe513ed5c    single_open     vmlinux EXPORT_SYMBOL
++0x9072472b    page_follow_link_light  vmlinux EXPORT_SYMBOL
++0xdbbd4688    __page_file_mapping     vmlinux EXPORT_SYMBOL_GPL
++0x0f751aea    input_event_from_user   vmlinux EXPORT_SYMBOL_GPL
++0x4484a5a4    wait_for_device_probe   vmlinux EXPORT_SYMBOL_GPL
++0xd53e17fd    tty_port_put    vmlinux EXPORT_SYMBOL
++0xa1b759ce    fb_add_videomode        vmlinux EXPORT_SYMBOL
++0x3c831441    arm_check_condition     vmlinux EXPORT_SYMBOL_GPL
++0x44fa52dd    brcmu_pktq_mdeq drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x471d6f83    brcmu_pktq_mlen drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x6af410ae    cfg80211_send_disassoc  vmlinux EXPORT_SYMBOL
++0x1baa3892    xfrm6_find_1stfragopt   vmlinux EXPORT_SYMBOL
++0x198788b4    snd_lookup_oss_minor_data       vmlinux EXPORT_SYMBOL
++0x4a3ea5c0    snd_request_card        vmlinux EXPORT_SYMBOL
++0x56451890    register_ftrace_event   vmlinux EXPORT_SYMBOL_GPL
++0x4ae313f9    kthread_stop    vmlinux EXPORT_SYMBOL
++0x1438fff0    st_sensors_sysfs_scale_avail    vmlinux EXPORT_SYMBOL
++0x31178006    clk_unregister  vmlinux EXPORT_SYMBOL_GPL
++0x083c2cbe    of_get_next_parent      vmlinux EXPORT_SYMBOL
++0xfef96e23    __scsi_print_command    vmlinux EXPORT_SYMBOL
++0x670cff67    drm_helper_disable_unused_functions     vmlinux EXPORT_SYMBOL
++0xe7048594    cfg80211_chandef_create vmlinux EXPORT_SYMBOL
++0x020d1750    cfg80211_tdls_oper_request      vmlinux EXPORT_SYMBOL
++0xbec63ca7    security_inode_create   vmlinux EXPORT_SYMBOL_GPL
++0xfe72e11b    dm_register_target      vmlinux EXPORT_SYMBOL
++0xaa4a7797    hex2bin vmlinux EXPORT_SYMBOL
++0xe924fd45    crypto_default_rng      vmlinux EXPORT_SYMBOL_GPL
++0xddab6b08    d_make_root     vmlinux EXPORT_SYMBOL
++0xa3b40cfd    hid_register_report     vmlinux EXPORT_SYMBOL_GPL
++0xcda04a5b    v4l2_prio_close vmlinux EXPORT_SYMBOL
++0x2e12216c    rtc_set_alarm   vmlinux EXPORT_SYMBOL_GPL
++0xaefe5034    __scsi_get_command      vmlinux EXPORT_SYMBOL_GPL
++0x31547da3    __scsi_put_command      vmlinux EXPORT_SYMBOL
++0x0fa5f996    inet_csk_listen_start   vmlinux EXPORT_SYMBOL_GPL
++0xfcc2a43c    utf32_to_utf8   vmlinux EXPORT_SYMBOL
++0xeef161aa    groups_free     vmlinux EXPORT_SYMBOL
++0xc5a25ce7    cleanup_srcu_struct     vmlinux EXPORT_SYMBOL_GPL
++0xac1a55be    unregister_reboot_notifier      vmlinux EXPORT_SYMBOL
++0x4557930f    regmap_update_bits_check        vmlinux EXPORT_SYMBOL_GPL
++0x0e0eb67f    ip6_flush_pending_frames        vmlinux EXPORT_SYMBOL_GPL
++0xb670b4cf    tcf_destroy_chain       vmlinux EXPORT_SYMBOL
++0x5fa48b4e    generic_file_remap_pages        vmlinux EXPORT_SYMBOL
++0xe13fa8ed    regmap_register_patch   vmlinux EXPORT_SYMBOL_GPL
++0x18c77c17    tty_perform_flush       vmlinux EXPORT_SYMBOL_GPL
++0x5ece6555    debugfs_remove_recursive        vmlinux EXPORT_SYMBOL_GPL
++0x1fcf4d4b    _raw_read_unlock_bh     vmlinux EXPORT_SYMBOL
++0x04cabed9    rfkill_register vmlinux EXPORT_SYMBOL
++0x774a552a    cfg80211_send_deauth    vmlinux EXPORT_SYMBOL
++0xc1691764    neigh_parms_alloc       vmlinux EXPORT_SYMBOL
++0x75fac20b    mount_single    vmlinux EXPORT_SYMBOL
++0x9ecc6a7a    interruptible_sleep_on  vmlinux EXPORT_SYMBOL
++0x19a304ba    usb_disabled    vmlinux EXPORT_SYMBOL_GPL
++0x48f20051    __ip_route_output_key   vmlinux EXPORT_SYMBOL_GPL
++0x5e7f4920    snd_pcm_format_set_silence      vmlinux EXPORT_SYMBOL
++0x9ef5a297    blk_queue_invalidate_tags       vmlinux EXPORT_SYMBOL
++0xffb6db4a    remove_irq      vmlinux EXPORT_SYMBOL_GPL
++0x93a6e0b2    io_schedule     vmlinux EXPORT_SYMBOL
++0xa604bba5    cpufreq_notify_transition       vmlinux EXPORT_SYMBOL_GPL
++0xb9c425de    register_syscore_ops    vmlinux EXPORT_SYMBOL_GPL
++0x7317fc49    disk_part_iter_next     vmlinux EXPORT_SYMBOL_GPL
++0xc4c6c770    block_write_end vmlinux EXPORT_SYMBOL
++0x437e0be6    pid_vnr vmlinux EXPORT_SYMBOL_GPL
++0xcb476f4a    cfb_fillrect    vmlinux EXPORT_SYMBOL
++0xc6241aec    cfg80211_roamed_bss     vmlinux EXPORT_SYMBOL
++0x44336387    __xfrm_decode_session   vmlinux EXPORT_SYMBOL
++0xf803fe39    bitmap_set      vmlinux EXPORT_SYMBOL
++0x1bbcbb78    __pagevec_lru_add       vmlinux EXPORT_SYMBOL
++0xd1b2db37    tracepoint_probe_register_noupdate      vmlinux EXPORT_SYMBOL_GPL
++0x230e0698    __clocksource_updatefreq_scale  vmlinux EXPORT_SYMBOL_GPL
++0xd8004073    sdhci_runtime_resume_host       vmlinux EXPORT_SYMBOL_GPL
++0x04369954    devm_regmap_init        vmlinux EXPORT_SYMBOL_GPL
++0xa2a36526    tty_port_lower_dtr_rts  vmlinux EXPORT_SYMBOL
++0xf369df34    wiphy_rfkill_stop_polling       vmlinux EXPORT_SYMBOL
++0x253ec879    netlink_set_err vmlinux EXPORT_SYMBOL
++0x71d7bf40    alloc_netdev_mqs        vmlinux EXPORT_SYMBOL
++0x336154ca    rcutorture_record_test_transition       vmlinux EXPORT_SYMBOL_GPL
++0x1aa1c9f2    make_kprojid    vmlinux EXPORT_SYMBOL
++0xa42a123d    bus_register_notifier   vmlinux EXPORT_SYMBOL_GPL
++0xd2cf977d    gpiochip_add    vmlinux EXPORT_SYMBOL_GPL
++0xd3c40b56    inet_listen     vmlinux EXPORT_SYMBOL
++0xfdc9a24f    __dst_destroy_metrics_generic   vmlinux EXPORT_SYMBOL
++0x44e276d8    skb_queue_purge vmlinux EXPORT_SYMBOL
++0x588eccde    get_unmapped_area       vmlinux EXPORT_SYMBOL
++0x0f29f7c9    add_to_page_cache_lru   vmlinux EXPORT_SYMBOL_GPL
++0xb7d4b252    iommu_present   vmlinux EXPORT_SYMBOL_GPL
++0x01c483a9    v4l2_get_timestamp      vmlinux EXPORT_SYMBOL_GPL
++0xbf041102    register_vt_notifier    vmlinux EXPORT_SYMBOL_GPL
++0xf85885d1    nci_unregister_device   vmlinux EXPORT_SYMBOL
++0x07b52e38    rtnl_unregister vmlinux EXPORT_SYMBOL_GPL
++0xe3bc40f6    dpcm_be_dai_trigger     vmlinux EXPORT_SYMBOL_GPL
++0xfbed2f3c    snd_soc_info_volsw_range        vmlinux EXPORT_SYMBOL_GPL
++0x9545974d    blk_rq_map_user vmlinux EXPORT_SYMBOL
++0x693ca44e    jbd2_journal_clear_features     vmlinux EXPORT_SYMBOL
++0x538410d3    generic_pipe_buf_release        vmlinux EXPORT_SYMBOL
++0x8878cfa6    gether_cleanup  vmlinux EXPORT_SYMBOL
++0xc1c72997    platform_bus_type       vmlinux EXPORT_SYMBOL_GPL
++0x2c61162c    drm_fb_helper_check_var vmlinux EXPORT_SYMBOL
++0x7a8cea07    bt_accept_unlink        vmlinux EXPORT_SYMBOL
++0x61812beb    nf_ct_gre_keymap_add    vmlinux EXPORT_SYMBOL_GPL
++0xcf596042    d_find_alias    vmlinux EXPORT_SYMBOL
++0x81d10f5f    trace_seq_putc  vmlinux EXPORT_SYMBOL
++0x760a0f4f    yield   vmlinux EXPORT_SYMBOL
++0xac472389    iio_buffer_register     vmlinux EXPORT_SYMBOL
++0x5dd590c3    sdhci_pltfm_pmops       vmlinux EXPORT_SYMBOL_GPL
++0x0c5b9900    xt_check_target vmlinux EXPORT_SYMBOL_GPL
++0xb67c64fd    __tracepoint_kfree_skb  vmlinux EXPORT_SYMBOL_GPL
++0xd6c2e04b    __tracepoint_napi_poll  vmlinux EXPORT_SYMBOL_GPL
++0x01bb81cc    netdev_upper_dev_unlink vmlinux EXPORT_SYMBOL
++0x5bb9daec    __sg_page_iter_start    vmlinux EXPORT_SYMBOL
++0xac3d64d9    fsstack_copy_attr_all   vmlinux EXPORT_SYMBOL_GPL
++0xda48e711    sdio_claim_irq  vmlinux EXPORT_SYMBOL_GPL
++0x1dc36131    fb_destroy_modedb       vmlinux EXPORT_SYMBOL
++0xca2159d7    udp6_lib_lookup vmlinux EXPORT_SYMBOL_GPL
++0xbf58f5e7    xfrm_init_replay        vmlinux EXPORT_SYMBOL
++0xfb74be78    udp4_lib_lookup vmlinux EXPORT_SYMBOL_GPL
++0x419cfeed    __nf_ct_try_assign_helper       vmlinux EXPORT_SYMBOL_GPL
++0x610dbc32    genl_unregister_ops     vmlinux EXPORT_SYMBOL
++0x9e2000a7    memcpy_toiovecend       vmlinux EXPORT_SYMBOL
++0x3fc5d39f    snd_jack_report vmlinux EXPORT_SYMBOL
++0x93949c2a    inode_sb_list_add       vmlinux EXPORT_SYMBOL_GPL
++0x3d4ee67b    inode_init_always       vmlinux EXPORT_SYMBOL
++0x38883d79    d_invalidate    vmlinux EXPORT_SYMBOL
++0xa0b04675    vmalloc_32      vmlinux EXPORT_SYMBOL
++0xedca9389    pid_task        vmlinux EXPORT_SYMBOL
++0xc1c2b8e5    scsi_command_normalize_sense    vmlinux EXPORT_SYMBOL
++0x4d0d163d    copy_page       vmlinux EXPORT_SYMBOL
++0xe0becdbc    set_h245_addr_hook      vmlinux EXPORT_SYMBOL_GPL
++0xd9a79782    seq_print_acct  vmlinux EXPORT_SYMBOL_GPL
++0xbc9f30d7    textsearch_unregister   vmlinux EXPORT_SYMBOL
++0xf54c51a2    dma_pool_free   vmlinux EXPORT_SYMBOL
++0x32fd447a    monotonic_to_bootbased  vmlinux EXPORT_SYMBOL_GPL
++0x45a6be13    cpufreq_sysfs_remove_file       vmlinux EXPORT_SYMBOL
++0x9a5723c8    input_register_handler  vmlinux EXPORT_SYMBOL
++0x0f618e15    drm_class_device_unregister     vmlinux EXPORT_SYMBOL_GPL
++0xbae73813    inet6_csk_bind_conflict vmlinux EXPORT_SYMBOL_GPL
++0xa35de80f    ipv4_config     vmlinux EXPORT_SYMBOL
++0x7411b488    netif_carrier_on        vmlinux EXPORT_SYMBOL
++0x1212d241    fib_rules_lookup        vmlinux EXPORT_SYMBOL_GPL
++0xb0b847ac    __bitmap_full   vmlinux EXPORT_SYMBOL
++0x4059792f    print_hex_dump  vmlinux EXPORT_SYMBOL
++0x99d40bce    cfg80211_del_sta        vmlinux EXPORT_SYMBOL
++0xe8068f48    ip6_route_output        vmlinux EXPORT_SYMBOL
++0xb57e5e86    __dst_free      vmlinux EXPORT_SYMBOL
++0x9fb986a9    inode_newsize_ok        vmlinux EXPORT_SYMBOL
++0xf39a1727    dev_pm_qos_add_notifier vmlinux EXPORT_SYMBOL_GPL
++0xbb6297fd    drm_mode_group_init_legacy_group        vmlinux EXPORT_SYMBOL
++0xd3ce735a    drm_crtc_helper_set_config      vmlinux EXPORT_SYMBOL
++0xa68b2c0b    pn_sock_get_port        vmlinux EXPORT_SYMBOL
++0x04797338    inet_csk_destroy_sock   vmlinux EXPORT_SYMBOL
++0x050e881c    inet_peer_base_init     vmlinux EXPORT_SYMBOL_GPL
++0x84b183ae    strncmp vmlinux EXPORT_SYMBOL
++0xb6f24459    crypto_register_shashes vmlinux EXPORT_SYMBOL_GPL
++0x1e26be3b    get_anon_bdev   vmlinux EXPORT_SYMBOL
++0x6b29a1fa    ring_buffer_event_length        vmlinux EXPORT_SYMBOL_GPL
++0x5634e278    __clk_get_flags vmlinux EXPORT_SYMBOL_GPL
++0x2e1ca751    clk_put vmlinux EXPORT_SYMBOL
++0xf474a207    usb_gadget_config_buf   vmlinux EXPORT_SYMBOL_GPL
++0x20838fc5    __pm_runtime_idle       vmlinux EXPORT_SYMBOL_GPL
++0x062de44d    sock_kfree_s    vmlinux EXPORT_SYMBOL
++0x3796bdcc    snd_pcm_format_little_endian    vmlinux EXPORT_SYMBOL
++0xa34f1ef5    crc32_le        vmlinux EXPORT_SYMBOL
++0xf54bd49b    lcm     vmlinux EXPORT_SYMBOL_GPL
++0x13354608    scatterwalk_map_and_copy        vmlinux EXPORT_SYMBOL_GPL
++0xf2bec139    empty_aops      vmlinux EXPORT_SYMBOL
++0x45755a66    __task_pid_nr_ns        vmlinux EXPORT_SYMBOL
++0xcbc23c9a    ethtool_op_get_link     vmlinux EXPORT_SYMBOL
++0x5735fbd5    read_cache_pages        vmlinux EXPORT_SYMBOL
++0x4aadeb9a    ring_buffer_alloc_read_page     vmlinux EXPORT_SYMBOL_GPL
++0x2f3f62cd    v4l2_try_ext_ctrls      vmlinux EXPORT_SYMBOL
++0x5d12e48f    input_event_to_user     vmlinux EXPORT_SYMBOL_GPL
++0x6947468c    input_unregister_device vmlinux EXPORT_SYMBOL
++0x91600a8e    usb_string_id   vmlinux EXPORT_SYMBOL_GPL
++0xcc924d52    regulator_disable_regmap        vmlinux EXPORT_SYMBOL_GPL
++0x3a4402b4    ip_generic_getfrag      vmlinux EXPORT_SYMBOL
++0x6308d2cf    call_netdevice_notifiers        vmlinux EXPORT_SYMBOL
++0xc02df0b8    snd_soc_pm_ops  vmlinux EXPORT_SYMBOL_GPL
++0xf9436986    crypto_dequeue_request  vmlinux EXPORT_SYMBOL_GPL
++0xb6555d54    crypto_enqueue_request  vmlinux EXPORT_SYMBOL_GPL
++0x6c2dc956    fat_add_entries vmlinux EXPORT_SYMBOL_GPL
++0xb7fc7a60    thaw_bdev       vmlinux EXPORT_SYMBOL
++0x99a170f8    kmem_cache_alloc_trace  vmlinux EXPORT_SYMBOL
++0x06f22ca2    irq_create_mapping      vmlinux EXPORT_SYMBOL_GPL
++0x992e5dbd    mii_nway_restart        vmlinux EXPORT_SYMBOL
++0xa6a0a273    max77693_write_reg      vmlinux EXPORT_SYMBOL_GPL
++0xa6b21ef2    dpm_suspend_end vmlinux EXPORT_SYMBOL_GPL
++0x27f9262d    sk_run_filter   vmlinux EXPORT_SYMBOL
++0x8bfe698b    netdev_rx_csum_fault    vmlinux EXPORT_SYMBOL
++0x9e61bb05    set_freezable   vmlinux EXPORT_SYMBOL
++0xd5418207    devres_release_group    vmlinux EXPORT_SYMBOL_GPL
++0x45669e2c    drm_fb_helper_restore_fbdev_mode        vmlinux EXPORT_SYMBOL
++0x93fcb0ed    bt_sock_reclassify_lock vmlinux EXPORT_SYMBOL
++0xb6d8be2d    ipv6_push_nfrag_opts    vmlinux EXPORT_SYMBOL
++0x8cdb54d7    ipt_register_table      vmlinux EXPORT_SYMBOL
++0xcc0aef97    neigh_sysctl_unregister vmlinux EXPORT_SYMBOL
++0xe56a9336    snd_pcm_format_width    vmlinux EXPORT_SYMBOL
++0x9077c297    blk_abort_request       vmlinux EXPORT_SYMBOL_GPL
++0x6ed8eb1f    extcon_register_notifier        vmlinux EXPORT_SYMBOL_GPL
++0xc9561772    fb_destroy_modelist     vmlinux EXPORT_SYMBOL_GPL
++0xf494fae4    tcp_peer_is_proven      vmlinux EXPORT_SYMBOL_GPL
++0xdc70cab5    __scm_destroy   vmlinux EXPORT_SYMBOL
++0xfb2acf00    snd_mixer_oss_notify_callback   vmlinux EXPORT_SYMBOL
++0x3a016c77    d_move  vmlinux EXPORT_SYMBOL
++0x5091b823    ring_buffer_read_start  vmlinux EXPORT_SYMBOL_GPL
++0x171751ed    sdio_writeb_readb       vmlinux EXPORT_SYMBOL_GPL
++0x3d94fdae    usb_put_phy     vmlinux EXPORT_SYMBOL_GPL
++0xfbf7bde5    drm_crtc_cleanup        vmlinux EXPORT_SYMBOL
++0x52aaee97    amba_ahb_device_add_res vmlinux EXPORT_SYMBOL_GPL
++0xd0706e35    phy_pm_runtime_put      vmlinux EXPORT_SYMBOL_GPL
++0x0ff178f6    __aeabi_idivmod vmlinux EXPORT_SYMBOL
++0xfb11005b    ipcomp_destroy  vmlinux EXPORT_SYMBOL_GPL
++0x6f81b189    dev_addr_del_multiple   vmlinux EXPORT_SYMBOL
++0xf5ce8c40    touch_atime     vmlinux EXPORT_SYMBOL
++0x53614269    get_cpu_idle_time_us    vmlinux EXPORT_SYMBOL_GPL
++0x61c243fc    mod_timer_pending       vmlinux EXPORT_SYMBOL
++0xf821b501    device_set_wakeup_capable       vmlinux EXPORT_SYMBOL_GPL
++0x80bbfeb1    s3c_gpio_cfgall_range   vmlinux EXPORT_SYMBOL_GPL
++0x10081d73    s3c_gpio_cfgpin_range   vmlinux EXPORT_SYMBOL_GPL
++0x75464443    phonet_proto_unregister vmlinux EXPORT_SYMBOL
++0x7d6fed76    rtnl_configure_link     vmlinux EXPORT_SYMBOL
++0x8c844510    sock_wmalloc    vmlinux EXPORT_SYMBOL
++0xbaf75338    snd_soc_codec_writable_register vmlinux EXPORT_SYMBOL_GPL
++0x1e6d26a8    strstr  vmlinux EXPORT_SYMBOL
++0xea6f9ca2    task_user_regset_view   vmlinux EXPORT_SYMBOL_GPL
++0x4de17ab3    usb_state_string        vmlinux EXPORT_SYMBOL_GPL
++0x349cba85    strchr  vmlinux EXPORT_SYMBOL
++0xb83a0cc6    perf_event_disable      vmlinux EXPORT_SYMBOL_GPL
++0x3b5965e0    inet_csk_listen_stop    vmlinux EXPORT_SYMBOL_GPL
++0x6be59bed    kobject_create_and_add  vmlinux EXPORT_SYMBOL_GPL
++0xdced71ac    setup_new_exec  vmlinux EXPORT_SYMBOL
++0xdb8a1b3f    usermodehelper_read_trylock     vmlinux EXPORT_SYMBOL_GPL
++0x7c9ad2eb    usb_wait_anchor_empty_timeout   vmlinux EXPORT_SYMBOL_GPL
++0xf2fca922    uart_parse_options      vmlinux EXPORT_SYMBOL_GPL
++0x7f63b31e    _memcpy_toio    vmlinux EXPORT_SYMBOL
++0x3e3fcdf2    xfrm_state_lookup_byaddr        vmlinux EXPORT_SYMBOL
++0x2b538790    pskb_expand_head        vmlinux EXPORT_SYMBOL
++0xdb67d9bb    of_i2c_register_devices vmlinux EXPORT_SYMBOL
++0x9f7314d6    wakeup_source_prepare   vmlinux EXPORT_SYMBOL_GPL
++0x2a828cb7    drm_noop        vmlinux EXPORT_SYMBOL
++0x3d3c540f    elf_hwcap       vmlinux EXPORT_SYMBOL
++0xa045219b    fuse_do_ioctl   vmlinux EXPORT_SYMBOL_GPL
++0x8fa5cf61    pm_qos_update_request   vmlinux EXPORT_SYMBOL_GPL
++0x73514fba    i2c_release_client      vmlinux EXPORT_SYMBOL
++0x168db450    take_over_console       vmlinux EXPORT_SYMBOL
++0x0aa13d05    __raw_readsw    vmlinux EXPORT_SYMBOL
++0x816a1ee5    rtnl_link_register      vmlinux EXPORT_SYMBOL_GPL
++0x9fd1a952    sk_set_memalloc vmlinux EXPORT_SYMBOL_GPL
++0x8605ed02    lock_may_write  vmlinux EXPORT_SYMBOL
++0xb24e73ff    bh_submit_read  vmlinux EXPORT_SYMBOL
++0x455db47d    dma_mark_declared_memory_occupied       vmlinux EXPORT_SYMBOL
++0x1a65f4ad    __arm_ioremap_pfn       vmlinux EXPORT_SYMBOL
++0x955e8436    eth_change_mtu  vmlinux EXPORT_SYMBOL
++0xa300e599    eth_header_parse        vmlinux EXPORT_SYMBOL
++0x42977ad4    __hw_addr_del_multiple  vmlinux EXPORT_SYMBOL
++0xf57de517    bdev_stack_limits       vmlinux EXPORT_SYMBOL
++0x25bed5a1    static_key_slow_dec_deferred    vmlinux EXPORT_SYMBOL_GPL
++0xd2aaeb4e    kmsg_dump_get_buffer    vmlinux EXPORT_SYMBOL_GPL
++0xedb320d6    nf_nat_pptp_hook_exp_gre        vmlinux EXPORT_SYMBOL_GPL
++0xdc0a9f66    sock_wake_async vmlinux EXPORT_SYMBOL
++0x68e05d57    getrawmonotonic vmlinux EXPORT_SYMBOL
++0xee715ef8    lg_global_unlock        vmlinux EXPORT_SYMBOL
++0xbebb2820    crypto_register_algs    vmlinux EXPORT_SYMBOL_GPL
++0xccc2bc05    fat_free_clusters       vmlinux EXPORT_SYMBOL_GPL
++0xde99c012    jbd2_complete_transaction       vmlinux EXPORT_SYMBOL
++0x60599993    __set_page_dirty_buffers        vmlinux EXPORT_SYMBOL
++0x8b775d3a    __wake_up_locked        vmlinux EXPORT_SYMBOL_GPL
++0x93eb18c6    of_platform_device_create       vmlinux EXPORT_SYMBOL
++0x9e5bfa34    bt_sock_poll    vmlinux EXPORT_SYMBOL
++0x7e98f5ff    sock_prot_inuse_add     vmlinux EXPORT_SYMBOL_GPL
++0xf9e73082    scnprintf       vmlinux EXPORT_SYMBOL
++0xa1b4cc6a    aead_geniv_exit vmlinux EXPORT_SYMBOL_GPL
++0xa7001f92    mod_zone_page_state     vmlinux EXPORT_SYMBOL
++0x92e79788    perf_event_refresh      vmlinux EXPORT_SYMBOL_GPL
++0x77e7babf    usb_hcd_platform_shutdown       vmlinux EXPORT_SYMBOL_GPL
++0x6d4d6df5    s3c_gpio_cfgpin vmlinux EXPORT_SYMBOL
++0x7f250a18    tcf_register_action     vmlinux EXPORT_SYMBOL
++0x41852af3    blk_add_request_payload vmlinux EXPORT_SYMBOL_GPL
++0x8bf05477    pm_runtime_autosuspend_expiration       vmlinux EXPORT_SYMBOL_GPL
++0xea25f714    rtnl_link_unregister    vmlinux EXPORT_SYMBOL_GPL
++0x5f75b2b7    snd_soc_dapm_enable_pin vmlinux EXPORT_SYMBOL_GPL
++0x87879778    copy_strings_kernel     vmlinux EXPORT_SYMBOL
++0x731b81f1    __wait_on_bit   vmlinux EXPORT_SYMBOL
++0x18838e93    hrtimer_get_remaining   vmlinux EXPORT_SYMBOL_GPL
++0x0be4ca5a    extcon_set_state        vmlinux EXPORT_SYMBOL_GPL
++0xacdf7eb6    led_trigger_register_simple     vmlinux EXPORT_SYMBOL_GPL
++0x20645642    drm_debug       vmlinux EXPORT_SYMBOL
++0x5f41d1f8    rdev_get_id     vmlinux EXPORT_SYMBOL_GPL
++0xf6f440a6    tcp_enter_memory_pressure       vmlinux EXPORT_SYMBOL
++0x3b9a9d19    skb_add_rx_frag vmlinux EXPORT_SYMBOL
++0x32b2bc89    snd_soc_write   vmlinux EXPORT_SYMBOL_GPL
++0x5b44d926    snd_soc_get_xr_sx       vmlinux EXPORT_SYMBOL_GPL
++0xf1395b13    snd_soc_put_xr_sx       vmlinux EXPORT_SYMBOL_GPL
++0x4982a57f    probe_kernel_write      vmlinux EXPORT_SYMBOL_GPL
++0x811dc334    usb_unregister_notify   vmlinux EXPORT_SYMBOL_GPL
++0xa6f7283b    arp_create      vmlinux EXPORT_SYMBOL
++0x660b5392    jbd2_journal_get_create_access  vmlinux EXPORT_SYMBOL
++0x99dd4a27    no_llseek       vmlinux EXPORT_SYMBOL
++0x72532806    _raw_read_unlock_irq    vmlinux EXPORT_SYMBOL
++0xe4719990    rt_mutex_timed_lock     vmlinux EXPORT_SYMBOL_GPL
++0xb5d9454c    printk_emit     vmlinux EXPORT_SYMBOL
++0x801e5a15    st_sensors_check_device_support vmlinux EXPORT_SYMBOL
++0xeec77f6d    iio_map_array_unregister        vmlinux EXPORT_SYMBOL_GPL
++0x6390efda    of_modalias_node        vmlinux EXPORT_SYMBOL_GPL
++0x7ac03539    tty_port_alloc_xmit_buf vmlinux EXPORT_SYMBOL
++0x5cebb76e    vfs_truncate    vmlinux EXPORT_SYMBOL_GPL
++0xfc52a8aa    mmc_gpio_request_cd     vmlinux EXPORT_SYMBOL
++0xf7a4e432    mmc_gpio_request_ro     vmlinux EXPORT_SYMBOL
++0x74d52889    rtc_irq_set_freq        vmlinux EXPORT_SYMBOL_GPL
++0x8e9efd84    dma_declare_coherent_memory     vmlinux EXPORT_SYMBOL
++0xfcfa03ff    fb_videomode_to_modelist        vmlinux EXPORT_SYMBOL
++0x789c0277    nfc_unregister_device   vmlinux EXPORT_SYMBOL
++0x48744ce2    lro_receive_frags       vmlinux EXPORT_SYMBOL
++0xf6851d5f    register_sysctl_paths   vmlinux EXPORT_SYMBOL
++0x90a4a466    generic_show_options    vmlinux EXPORT_SYMBOL
++0x74dd4a76    pagecache_write_begin   vmlinux EXPORT_SYMBOL
++0x7b42b5d4    drm_mode_copy   vmlinux EXPORT_SYMBOL
++0x6a7c03c7    asoc_dma_platform_register      vmlinux EXPORT_SYMBOL_GPL
++0xc6cbbc89    capable vmlinux EXPORT_SYMBOL
++0xd07125d9    spi_finalize_current_message    vmlinux EXPORT_SYMBOL_GPL
++0xf5514ce6    dev_pm_qos_add_request  vmlinux EXPORT_SYMBOL_GPL
++0xb316e246    nf_afinfo       vmlinux EXPORT_SYMBOL
++0x4ef5bcf4    perf_swevent_get_recursion_context      vmlinux EXPORT_SYMBOL_GPL
++0xab7e3362    irq_find_mapping        vmlinux EXPORT_SYMBOL_GPL
++0xbcf89ab6    __wake_up_sync  vmlinux EXPORT_SYMBOL_GPL
++0xc8b57c27    autoremove_wake_function        vmlinux EXPORT_SYMBOL
++0x36aa3266    hid_debug_event vmlinux EXPORT_SYMBOL_GPL
++0x9ed21fce    mmc_can_trim    vmlinux EXPORT_SYMBOL
++0x5658ad69    v4l2_async_register_subdev      vmlinux EXPORT_SYMBOL
++0x99781445    input_set_capability    vmlinux EXPORT_SYMBOL
++0xf3343f80    drm_mode_create_tv_properties   vmlinux EXPORT_SYMBOL
++0x69fefbb6    nf_ct_port_tuple_to_nlattr      vmlinux EXPORT_SYMBOL_GPL
++0xd9a9bb30    getname vmlinux EXPORT_SYMBOL
++0xe7ffe877    pcpu_base_addr  vmlinux EXPORT_SYMBOL_GPL
++0x131e7ee8    drm_fb_helper_hotplug_event     vmlinux EXPORT_SYMBOL
++0x983f0520    drm_fb_helper_initial_config    vmlinux EXPORT_SYMBOL
++0x469972c2    give_up_console vmlinux EXPORT_SYMBOL
++0x300573d1    nf_conntrack_helper_register    vmlinux EXPORT_SYMBOL_GPL
++0x2597c27d    snd_seq_root    vmlinux EXPORT_SYMBOL
++0x9a11a0fc    crypto_attr_alg_name    vmlinux EXPORT_SYMBOL_GPL
++0xa0f2a42b    debugfs_create_regset32 vmlinux EXPORT_SYMBOL_GPL
++0x3e08c129    drm_mode_find_dmt       vmlinux EXPORT_SYMBOL
++0xbc8b0f41    xfrm_calg_get_byid      vmlinux EXPORT_SYMBOL_GPL
++0xf20dabd8    free_irq        vmlinux EXPORT_SYMBOL
++0x9073a3d4    usb_hc_died     vmlinux EXPORT_SYMBOL_GPL
++0xe61a6d2f    gpio_unexport   vmlinux EXPORT_SYMBOL_GPL
++0xdf58d91e    pinctrl_dev_get_name    vmlinux EXPORT_SYMBOL_GPL
++0x4c3b5878    ieee80211_get_response_rate     vmlinux EXPORT_SYMBOL
++0xa6b9609a    jbd2_journal_init_inode vmlinux EXPORT_SYMBOL
++0xe91ef2b5    deactivate_locked_super vmlinux EXPORT_SYMBOL
++0x0280cf55    filemap_fdatawait       vmlinux EXPORT_SYMBOL
++0x134178d9    v4l2_m2m_fop_mmap       vmlinux EXPORT_SYMBOL_GPL
++0x9091c717    netdev_class_create_file        vmlinux EXPORT_SYMBOL
++0x4f816e9b    snd_pcm_format_big_endian       vmlinux EXPORT_SYMBOL
++0x09d44df9    in_lock_functions       vmlinux EXPORT_SYMBOL
++0x509817cf    vprintk_emit    vmlinux EXPORT_SYMBOL
++0x4c571d12    cfg80211_cqm_pktloss_notify     vmlinux EXPORT_SYMBOL
++0x8b260b7f    ip6_tnl_xmit_ctl        vmlinux EXPORT_SYMBOL_GPL
++0x7b9e609a    ip6_sk_update_pmtu      vmlinux EXPORT_SYMBOL_GPL
++0x199db92b    netdev_rx_handler_unregister    vmlinux EXPORT_SYMBOL_GPL
++0x4cdf24a6    skb_copy_datagram_const_iovec   vmlinux EXPORT_SYMBOL
++0xb994401f    kernel_getpeername      vmlinux EXPORT_SYMBOL
++0x7b10e656    sysfs_chmod_file        vmlinux EXPORT_SYMBOL_GPL
++0x55d7c934    find_module     vmlinux EXPORT_SYMBOL_GPL
++0x548b482c    rt_mutex_lock   vmlinux EXPORT_SYMBOL_GPL
++0x39533602    media_entity_graph_walk_start   vmlinux EXPORT_SYMBOL_GPL
++0x51ef2459    platform_driver_probe   vmlinux EXPORT_SYMBOL_GPL
++0xeb93a8ee    serial8250_do_set_termios       vmlinux EXPORT_SYMBOL
++0x8afc7ce3    __devm_of_phy_provider_register vmlinux EXPORT_SYMBOL_GPL
++0x548fedb9    skb_complete_wifi_ack   vmlinux EXPORT_SYMBOL_GPL
++0x11f7ed4c    hex_to_bin      vmlinux EXPORT_SYMBOL
++0x9aeecd64    simple_pin_fs   vmlinux EXPORT_SYMBOL
++0x5635a60a    vmalloc_user    vmlinux EXPORT_SYMBOL
++0xd36ab13e    posix_clock_unregister  vmlinux EXPORT_SYMBOL_GPL
++0x1fe9f800    unregister_cpu_notifier vmlinux EXPORT_SYMBOL
++0xb59a9548    vb2_expbuf      vmlinux EXPORT_SYMBOL_GPL
++0xf6eb0d71    input_event     vmlinux EXPORT_SYMBOL
++0xfc3a261f    dev_get_regmap  vmlinux EXPORT_SYMBOL_GPL
++0x89d145ed    pin_config_get  vmlinux EXPORT_SYMBOL
++0xc54fc2d7    devm_pinctrl_put        vmlinux EXPORT_SYMBOL_GPL
++0x9671e047    devm_pinctrl_get        vmlinux EXPORT_SYMBOL_GPL
++0x4d45d89e    udp_memory_allocated    vmlinux EXPORT_SYMBOL
++0x3e8b4fda    tc_classify     vmlinux EXPORT_SYMBOL
++0x98509e55    sock_no_sendpage        vmlinux EXPORT_SYMBOL
++0x7bd6700d    blk_pre_runtime_suspend vmlinux EXPORT_SYMBOL
++0x6444b7bb    iio_read_channel_raw    vmlinux EXPORT_SYMBOL_GPL
++0x70120108    thermal_generate_netlink_event  vmlinux EXPORT_SYMBOL_GPL
++0x800e4ffa    __muldi3        vmlinux EXPORT_SYMBOL
++0x4c1182cb    bitmap_scnprintf        vmlinux EXPORT_SYMBOL
++0xd7b4599b    __idr_get_new_above     vmlinux EXPORT_SYMBOL
++0x368dc456    proc_create_data        vmlinux EXPORT_SYMBOL
++0x4d405db8    param_ops_string        vmlinux EXPORT_SYMBOL
++0xdd021b6b    get_current_tty vmlinux EXPORT_SYMBOL_GPL
++0xabbaaf4c    kernel_getsockname      vmlinux EXPORT_SYMBOL
++0x5caf4413    kernel_sendmsg  vmlinux EXPORT_SYMBOL
++0x3971b4df    snd_ecards_limit        vmlinux EXPORT_SYMBOL
++0xd77a5aa5    __bitmap_and    vmlinux EXPORT_SYMBOL
++0xfac05b29    unregister_gadget_item  vmlinux EXPORT_SYMBOL
++0x268930d0    uart_register_driver    vmlinux EXPORT_SYMBOL
++0xace7ae5c    xfrm_alloc_spi  vmlinux EXPORT_SYMBOL
++0x0a4a1a2f    blk_rq_err_bytes        vmlinux EXPORT_SYMBOL_GPL
++0x6d414f53    crypto_blkcipher_type   vmlinux EXPORT_SYMBOL_GPL
++0x2ffe9a6b    crypto_givcipher_type   vmlinux EXPORT_SYMBOL_GPL
++0xe5ddcbd8    nfc_targets_found       vmlinux EXPORT_SYMBOL
++0x028f3057    nf_log_packet   vmlinux EXPORT_SYMBOL
++0xc8949349    qdisc_tree_decrease_qlen        vmlinux EXPORT_SYMBOL
++0x7d16c025    dev_remove_pack vmlinux EXPORT_SYMBOL
++0xf88eb7f2    rq_flush_dcache_pages   vmlinux EXPORT_SYMBOL_GPL
++0x2d8764e5    blkcipher_walk_virt     vmlinux EXPORT_SYMBOL_GPL
++0x5fce0dc6    posix_lock_file vmlinux EXPORT_SYMBOL
++0x71a672ef    dmam_pool_destroy       vmlinux EXPORT_SYMBOL
++0x3832da09    set_page_dirty  vmlinux EXPORT_SYMBOL
++0xe4937b31    i2c_bit_algo    vmlinux EXPORT_SYMBOL
++0x2c256e1f    input_scancode_to_scalar        vmlinux EXPORT_SYMBOL
++0x758978d2    spi_get_next_queued_message     vmlinux EXPORT_SYMBOL_GPL
++0xde9360ba    totalram_pages  vmlinux EXPORT_SYMBOL
++0xacc53440    video_device_alloc      vmlinux EXPORT_SYMBOL
++0x331f6073    udp_disconnect  vmlinux EXPORT_SYMBOL
++0x8a5c060e    nf_conntrack_l4proto_udp4       vmlinux EXPORT_SYMBOL_GPL
++0x492ab82c    dev_uc_unsync   vmlinux EXPORT_SYMBOL
++0xb1615d69    dev_mc_unsync   vmlinux EXPORT_SYMBOL
++0xa73acb8d    dump_seek       vmlinux EXPORT_SYMBOL
++0xea63afac    usb_free_streams        vmlinux EXPORT_SYMBOL_GPL
++0x0fb8623c    regcache_cache_only     vmlinux EXPORT_SYMBOL_GPL
++0xb89f40b3    __register_chrdev       vmlinux EXPORT_SYMBOL
++0x4ed5e0d7    v4l2_chip_match_host    vmlinux EXPORT_SYMBOL
++0x78272b1e    bus_get_kset    vmlinux EXPORT_SYMBOL_GPL
++0x87c0bce8    net_dma_find_channel    vmlinux EXPORT_SYMBOL
++0xc31f408b    __display_entity_register       vmlinux EXPORT_SYMBOL_GPL
++0x5b1cfbcd    of_get_fb_videomode     vmlinux EXPORT_SYMBOL_GPL
++0xe6775a2f    fb_show_logo    vmlinux EXPORT_SYMBOL
++0xa290f4a9    fb_pan_display  vmlinux EXPORT_SYMBOL
++0x61c2dac6    kstrtoll_from_user      vmlinux EXPORT_SYMBOL
++0x83904bc7    st_sensors_deallocate_trigger   vmlinux EXPORT_SYMBOL
++0x7bc41c7c    rtc_class_close vmlinux EXPORT_SYMBOL_GPL
++0x218b226c    sec_bulk_write  vmlinux EXPORT_SYMBOL_GPL
++0xf09de776    get_random_int  vmlinux EXPORT_SYMBOL
++0x5a937d99    blk_queue_stack_limits  vmlinux EXPORT_SYMBOL
++0x174b7df6    free_vm_area    vmlinux EXPORT_SYMBOL_GPL
++0x8ffa3ccd    devres_alloc    vmlinux EXPORT_SYMBOL_GPL
++0x956a91ba    gpio_get_value_cansleep vmlinux EXPORT_SYMBOL_GPL
++0x92886ef2    udp_lib_setsockopt      vmlinux EXPORT_SYMBOL
++0xc4a35da7    udp_lib_getsockopt      vmlinux EXPORT_SYMBOL
++0xdb1ed3be    nf_conntrack_free       vmlinux EXPORT_SYMBOL_GPL
++0x96898769    sysfs_format_mac        vmlinux EXPORT_SYMBOL
++0x15604324    sk_send_sigurg  vmlinux EXPORT_SYMBOL
++0x8fca87b8    proc_set_size   vmlinux EXPORT_SYMBOL
++0x4b5fd49e    dm_kcopyd_do_callback   vmlinux EXPORT_SYMBOL
++0x289bc356    mdiobus_alloc_size      vmlinux EXPORT_SYMBOL
++0xf36e7280    spi_bus_lock    vmlinux EXPORT_SYMBOL_GPL
++0x0c060ece    cfg80211_sched_scan_stopped     vmlinux EXPORT_SYMBOL
++0xab2289f2    drop_super      vmlinux EXPORT_SYMBOL
++0x27e1a049    printk  vmlinux EXPORT_SYMBOL
++0x3194878b    pm_generic_poweroff_noirq       vmlinux EXPORT_SYMBOL_GPL
++0x688f09be    dev_crit        vmlinux EXPORT_SYMBOL
++0xfd94d6cb    drm_get_connector_status_name   vmlinux EXPORT_SYMBOL
++0xbdef1e6b    drm_gem_object_release  vmlinux EXPORT_SYMBOL
++0x36fa2c4a    cfg80211_get_bss        vmlinux EXPORT_SYMBOL
++0xef2e65fd    sk_alloc        vmlinux EXPORT_SYMBOL
++0x096e7523    try_to_release_page     vmlinux EXPORT_SYMBOL
++0xa61b1477    tracepoint_iter_start   vmlinux EXPORT_SYMBOL_GPL
++0x9d05f6c4    ktime_get_clocktai      vmlinux EXPORT_SYMBOL
++0x6a87a478    synchronize_srcu        vmlinux EXPORT_SYMBOL_GPL
++0xa3afa3ce    bus_unregister_notifier vmlinux EXPORT_SYMBOL_GPL
++0xbe001c53    drm_property_add_enum   vmlinux EXPORT_SYMBOL
++0x48c2a99d    drm_helper_resume_force_mode    vmlinux EXPORT_SYMBOL
++0x1258d9d9    regulator_disable       vmlinux EXPORT_SYMBOL_GPL
++0x1b3261e0    klist_iter_init vmlinux EXPORT_SYMBOL_GPL
++0xaeec4fd1    hci_conn_switch_role    vmlinux EXPORT_SYMBOL
++0x8809bdee    kobject_add     vmlinux EXPORT_SYMBOL
++0x10138352    tracing_on      vmlinux EXPORT_SYMBOL_GPL
++0x39aa4754    dma_buf_mmap    vmlinux EXPORT_SYMBOL_GPL
++0x58c6fc51    dma_buf_kmap    vmlinux EXPORT_SYMBOL_GPL
++0x299bbc21    dma_buf_vmap    vmlinux EXPORT_SYMBOL_GPL
++0x5a2579f9    platform_driver_register        vmlinux EXPORT_SYMBOL_GPL
++0xa8d6809d    drm_dp_bw_code_to_link_rate     vmlinux EXPORT_SYMBOL
++0xfd86731b    drm_fb_helper_init      vmlinux EXPORT_SYMBOL
++0xd4880725    __video_source_register vmlinux EXPORT_SYMBOL_GPL
++0xe08f4a3d    devm_of_phy_provider_unregister vmlinux EXPORT_SYMBOL_GPL
++0x61634f05    lock_flocks     vmlinux EXPORT_SYMBOL_GPL
++0x3843f6b8    queue_kthread_work      vmlinux EXPORT_SYMBOL_GPL
++0x8e332478    thermal_zone_get_temp   vmlinux EXPORT_SYMBOL_GPL
++0xdd64085c    platform_driver_unregister      vmlinux EXPORT_SYMBOL_GPL
++0xaa6f23ad    rfkill_get_led_trigger_name     vmlinux EXPORT_SYMBOL
++0x9cab34a6    rfkill_set_led_trigger_name     vmlinux EXPORT_SYMBOL
++0x23b075bd    gnet_stats_copy_queue   vmlinux EXPORT_SYMBOL
++0x12e85778    kstrtol_from_user       vmlinux EXPORT_SYMBOL
++0x331504fa    simple_dir_operations   vmlinux EXPORT_SYMBOL
++0x3eabdee4    of_match_device vmlinux EXPORT_SYMBOL
++0x610e908e    hid_ignore      vmlinux EXPORT_SYMBOL_GPL
++0x3838d3de    usb_get_urb     vmlinux EXPORT_SYMBOL_GPL
++0xd400a944    cfg80211_gtk_rekey_notify       vmlinux EXPORT_SYMBOL
++0x6403e338    tcp_memory_pressure     vmlinux EXPORT_SYMBOL
++0x23a650aa    setattr_copy    vmlinux EXPORT_SYMBOL
++0x6b6b3081    iommu_domain_has_cap    vmlinux EXPORT_SYMBOL_GPL
++0xdd9fe08e    nfc_hci_driver_failure  vmlinux EXPORT_SYMBOL
++0x091cae50    cfg80211_probe_status   vmlinux EXPORT_SYMBOL
++0xa5e8f497    inet_frags_fini vmlinux EXPORT_SYMBOL
++0xff048999    snd_register_oss_device vmlinux EXPORT_SYMBOL
++0x24a94b26    snd_info_get_line       vmlinux EXPORT_SYMBOL
++0x7ba9873c    elv_dispatch_sort       vmlinux EXPORT_SYMBOL
++0x1471fd44    elv_add_request vmlinux EXPORT_SYMBOL
++0x9be7bde4    security_tun_dev_attach vmlinux EXPORT_SYMBOL
++0xf346231f    seq_list_start_head     vmlinux EXPORT_SYMBOL
++0x65d9e877    cpufreq_register_notifier       vmlinux EXPORT_SYMBOL
++0x399ed296    v4l2_subdev_link_validate_default       vmlinux EXPORT_SYMBOL_GPL
++0xfb974dd4    v4l2_ctrl_auto_cluster  vmlinux EXPORT_SYMBOL
++0xd9097364    v4l2_event_dequeue      vmlinux EXPORT_SYMBOL_GPL
++0xd9a8b315    scsi_queue_work vmlinux EXPORT_SYMBOL_GPL
++0xf564412a    __aeabi_ulcmp   vmlinux EXPORT_SYMBOL
++0x67e6edc4    netif_device_attach     vmlinux EXPORT_SYMBOL
++0x6c3962d5    netif_device_detach     vmlinux EXPORT_SYMBOL
++0x7464ec66    netdev_set_default_ethtool_ops  vmlinux EXPORT_SYMBOL_GPL
++0x08cf6c97    snd_soc_dai_digital_mute        vmlinux EXPORT_SYMBOL_GPL
++0x47628784    simple_attr_read        vmlinux EXPORT_SYMBOL_GPL
++0xe4bad1e4    sdhci_pltfm_init        vmlinux EXPORT_SYMBOL_GPL
++0xe3b2bc37    gether_connect  vmlinux EXPORT_SYMBOL
++0x2fe1cc7e    device_rename   vmlinux EXPORT_SYMBOL_GPL
++0xc147be94    drm_i2c_encoder_restore vmlinux EXPORT_SYMBOL
++0x56f369aa    kernel_bind     vmlinux EXPORT_SYMBOL
++0xcd279169    nla_find        vmlinux EXPORT_SYMBOL
++0x5cdf6de2    kernel_read     vmlinux EXPORT_SYMBOL
++0xfcc43f3f    vfs_read        vmlinux EXPORT_SYMBOL
++0xc8add232    ring_buffer_record_disable      vmlinux EXPORT_SYMBOL_GPL
++0xf2e84b50    __devm_release_region   vmlinux EXPORT_SYMBOL
++0xd4292ec2    dev_notice      vmlinux EXPORT_SYMBOL
++0x02e6e099    drm_mode_width  vmlinux EXPORT_SYMBOL
++0xcc248d26    serial8250_suspend_port vmlinux EXPORT_SYMBOL
++0x4e6e8ea7    fg_console      vmlinux EXPORT_SYMBOL
++0xbb9cc562    fl6_merge_options       vmlinux EXPORT_SYMBOL_GPL
++0x20bf8fa2    __inet_hash_nolisten    vmlinux EXPORT_SYMBOL_GPL
++0x9fb3dd30    memcpy_fromiovec        vmlinux EXPORT_SYMBOL
++0x9cde26bf    blk_queue_prep_rq       vmlinux EXPORT_SYMBOL
++0x262f20a8    local_clock     vmlinux EXPORT_SYMBOL_GPL
++0x7ebf0ef8    __nf_nat_l4proto_find   vmlinux EXPORT_SYMBOL_GPL
++0x503bc70a    drm_gem_prime_export    vmlinux EXPORT_SYMBOL
++0x8d6f81b4    __div64_32      vmlinux EXPORT_SYMBOL
++0x93fca811    __get_free_pages        vmlinux EXPORT_SYMBOL
++0xbb189cad    disallow_signal vmlinux EXPORT_SYMBOL
++0xefe5a9bf    usbnet_resume_rx        vmlinux EXPORT_SYMBOL_GPL
++0x1c4116bc    __class_register        vmlinux EXPORT_SYMBOL_GPL
++0x72cae0c9    nfc_driver_failure      vmlinux EXPORT_SYMBOL
++0xc3d70f22    rawv6_mh_filter_register        vmlinux EXPORT_SYMBOL
++0xdbcd416e    sysctl_ip_nonlocal_bind vmlinux EXPORT_SYMBOL
++0xa675804c    utf8s_to_utf16s vmlinux EXPORT_SYMBOL
++0xb4b97c90    pvclock_gtod_register_notifier  vmlinux EXPORT_SYMBOL_GPL
++0xdf9d0875    ns_capable      vmlinux EXPORT_SYMBOL
++0x13ba72ba    usb_free_coherent       vmlinux EXPORT_SYMBOL_GPL
++0x4671c723    rawv6_mh_filter_unregister      vmlinux EXPORT_SYMBOL
++0x5855bb11    blk_queue_resize_tags   vmlinux EXPORT_SYMBOL
++0x5159ff6c    mmc_fixup_device        vmlinux EXPORT_SYMBOL
++0x186b8590    ipv4_specific   vmlinux EXPORT_SYMBOL
++0x9d5e9b60    nf_ct_l3proto_find_get  vmlinux EXPORT_SYMBOL_GPL
++0x3f2c16f1    nf_ct_l4proto_find_get  vmlinux EXPORT_SYMBOL_GPL
++0xe20a528d    nf_queue_entry_release_refs     vmlinux EXPORT_SYMBOL_GPL
++0x4335fafb    proto_unregister        vmlinux EXPORT_SYMBOL
++0x5762296f    fuse_conn_kill  vmlinux EXPORT_SYMBOL_GPL
++0xe473e06d    __fsnotify_inode_delete vmlinux EXPORT_SYMBOL_GPL
++0xe2ed7067    i2c_new_dummy   vmlinux EXPORT_SYMBOL_GPL
++0x3cac21b9    regulator_sync_voltage  vmlinux EXPORT_SYMBOL_GPL
++0x71e7aab0    from_kprojid_munged     vmlinux EXPORT_SYMBOL
++0x3ca7e128    tty_unlock_pair vmlinux EXPORT_SYMBOL
++0x146d2f0c    rtnl_af_register        vmlinux EXPORT_SYMBOL_GPL
++0x97ecf37c    kunmap_high     vmlinux EXPORT_SYMBOL
++0x4470a79b    param_ops_long  vmlinux EXPORT_SYMBOL
++0x45bd9efd    dm_table_put    vmlinux EXPORT_SYMBOL
++0xf2a353ac    v4l2_i2c_tuner_addrs    vmlinux EXPORT_SYMBOL_GPL
++0xc7fd39bb    drm_dp_channel_eq_ok    vmlinux EXPORT_SYMBOL
++0xa0472547    inet_csk_update_pmtu    vmlinux EXPORT_SYMBOL_GPL
++0xacf4d843    match_strdup    vmlinux EXPORT_SYMBOL
++0x870bf928    radix_tree_lookup       vmlinux EXPORT_SYMBOL
++0x4672e88b    __crypto_dequeue_request        vmlinux EXPORT_SYMBOL_GPL
++0x7b0f1ab3    ring_buffer_free_read_page      vmlinux EXPORT_SYMBOL_GPL
++0x9745b34c    rt_mutex_unlock vmlinux EXPORT_SYMBOL_GPL
++0xac745cfe    s3c_adc_read    vmlinux EXPORT_SYMBOL_GPL
++0x4dc817ff    usb_composite_overwrite_options vmlinux EXPORT_SYMBOL_GPL
++0xcd8ff108    neigh_seq_next  vmlinux EXPORT_SYMBOL
++0xb4062ffd    vfs_rename      vmlinux EXPORT_SYMBOL
++0xdc4ed03b    generic_ro_fops vmlinux EXPORT_SYMBOL
++0x1300b437    nci_register_device     vmlinux EXPORT_SYMBOL
++0xbcfcecc3    user_path_create        vmlinux EXPORT_SYMBOL
++0xcf71a180    kthread_bind    vmlinux EXPORT_SYMBOL
++0x4571f8be    usb_string_ids_n        vmlinux EXPORT_SYMBOL_GPL
++0xf1ea24f2    ipv6_setsockopt vmlinux EXPORT_SYMBOL
++0x2d97bed6    dm_kcopyd_zero  vmlinux EXPORT_SYMBOL
++0xa1f5edea    drm_property_destroy    vmlinux EXPORT_SYMBOL
++0x3548305a    inet_frag_find  vmlinux EXPORT_SYMBOL
++0xf937428d    inetdev_by_index        vmlinux EXPORT_SYMBOL
++0x33f234ad    __sk_backlog_rcv        vmlinux EXPORT_SYMBOL
++0xb0fbdabc    crypto_lookup_skcipher  vmlinux EXPORT_SYMBOL_GPL
++0xdf0f75c6    eventfd_signal  vmlinux EXPORT_SYMBOL_GPL
++0x21f678b9    clocksource_unregister  vmlinux EXPORT_SYMBOL
++0xe3b5bb1e    usb_poison_anchored_urbs        vmlinux EXPORT_SYMBOL_GPL
++0x36003409    nfc_hci_send_event      vmlinux EXPORT_SYMBOL
++0xd26c8ac5    bt_sock_wait_state      vmlinux EXPORT_SYMBOL
++0x8bd1c81c    fifo_set_limit  vmlinux EXPORT_SYMBOL
++0xe630ebe9    snd_soc_get_pcm_runtime vmlinux EXPORT_SYMBOL_GPL
++0x9f7af994    writeback_in_progress   vmlinux EXPORT_SYMBOL
++0x94048818    filemap_fdatawrite      vmlinux EXPORT_SYMBOL
++0x9cc4f70a    register_pm_notifier    vmlinux EXPORT_SYMBOL_GPL
++0xdf6f4023    phy_drivers_unregister  vmlinux EXPORT_SYMBOL
++0x4cc1d9d6    con_debug_enter vmlinux EXPORT_SYMBOL_GPL
++0x807d2b2c    xt_recseq       vmlinux EXPORT_SYMBOL_GPL
++0x089e2060    __ethtool_get_settings  vmlinux EXPORT_SYMBOL
++0xcdd9e311    dev_add_offload vmlinux EXPORT_SYMBOL
++0x90ac3102    dev_base_lock   vmlinux EXPORT_SYMBOL
++0xfcc256a6    css_id  vmlinux EXPORT_SYMBOL_GPL
++0x2e7be112    _raw_read_lock_irqsave  vmlinux EXPORT_SYMBOL
++0x284633c4    devm_clk_register       vmlinux EXPORT_SYMBOL_GPL
++0x440982c5    usb_del_gadget_udc      vmlinux EXPORT_SYMBOL_GPL
++0x0d7b25d8    drm_i2c_encoder_destroy vmlinux EXPORT_SYMBOL
++0xd25d4f74    console_blank_hook      vmlinux EXPORT_SYMBOL
++0x968b41f8    nfc_hci_unregister_device       vmlinux EXPORT_SYMBOL
++0x71917221    xt_request_find_target  vmlinux EXPORT_SYMBOL_GPL
++0x14ccc8d6    sg_scsi_ioctl   vmlinux EXPORT_SYMBOL_GPL
++0xc22a3091    vm_unmap_aliases        vmlinux EXPORT_SYMBOL_GPL
++0x936d3888    dm_kill_unmapped_request        vmlinux EXPORT_SYMBOL_GPL
++0x56f3f495    vb2_querybuf    vmlinux EXPORT_SYMBOL
++0xcd773fe8    gnet_stats_finish_copy  vmlinux EXPORT_SYMBOL
++0x75ffa405    blk_fetch_request       vmlinux EXPORT_SYMBOL
++0xc51700fb    free_inode_nonrcu       vmlinux EXPORT_SYMBOL
++0x87471cdc    dma_pool_create vmlinux EXPORT_SYMBOL
++0x4b34fbf5    block_all_signals       vmlinux EXPORT_SYMBOL
++0x1910bed7    v4l2_m2m_next_buf       vmlinux EXPORT_SYMBOL_GPL
++0xda6389c8    scsi_get_device_flags_keyed     vmlinux EXPORT_SYMBOL
++0x384fda7f    device_show_int vmlinux EXPORT_SYMBOL_GPL
++0x853ce11c    uart_handle_cts_change  vmlinux EXPORT_SYMBOL_GPL
++0x2167989c    uart_handle_dcd_change  vmlinux EXPORT_SYMBOL_GPL
++0x832c7303    cfg80211_chandef_compatible     vmlinux EXPORT_SYMBOL
++0xb5aa7165    dma_pool_destroy        vmlinux EXPORT_SYMBOL
++0x3a81993a    irq_create_strict_mappings      vmlinux EXPORT_SYMBOL_GPL
++0xf7951d2a    sdio_writeb     vmlinux EXPORT_SYMBOL_GPL
++0x73286449    gether_set_gadget       vmlinux EXPORT_SYMBOL
++0x0958f0a1    gether_disconnect       vmlinux EXPORT_SYMBOL
++0xc7141639    tty_name        vmlinux EXPORT_SYMBOL
++0x52e54a99    udp6_csum_init  vmlinux EXPORT_SYMBOL
++0x20c95ebb    __dev_remove_offload    vmlinux EXPORT_SYMBOL
++0xff6104d0    snd_pcm_rate_bit_to_rate        vmlinux EXPORT_SYMBOL
++0xcfa8d57b    sysfs_get_dirent        vmlinux EXPORT_SYMBOL_GPL
++0x8e0d66f4    __tracepoint_kmalloc    vmlinux EXPORT_SYMBOL
++0x3bfcc1f8    perf_event_release_kernel       vmlinux EXPORT_SYMBOL_GPL
++0x8c03d20c    destroy_workqueue       vmlinux EXPORT_SYMBOL_GPL
++0x7e36685b    of_dev_put      vmlinux EXPORT_SYMBOL
++0x379d3e07    of_dev_get      vmlinux EXPORT_SYMBOL
++0xf494f618    mmc_regulator_get_ocrmask       vmlinux EXPORT_SYMBOL_GPL
++0xd9fb5e67    power_supply_register   vmlinux EXPORT_SYMBOL_GPL
++0x3697b3a2    usb_assign_descriptors  vmlinux EXPORT_SYMBOL_GPL
++0x6789d290    serial8250_register_8250_port   vmlinux EXPORT_SYMBOL
++0xa34d0cc4    inet6_csk_reqsk_queue_hash_add  vmlinux EXPORT_SYMBOL_GPL
++0x81de8eb2    inet_twsk_put   vmlinux EXPORT_SYMBOL_GPL
++0x687019ad    fib_default_rule_add    vmlinux EXPORT_SYMBOL
++0x8eef430a    fat_get_dotdot_entry    vmlinux EXPORT_SYMBOL_GPL
++0x2a3f1eb3    check_disk_change       vmlinux EXPORT_SYMBOL
++0xd5325933    default_file_splice_read        vmlinux EXPORT_SYMBOL
++0xd83215e5    writeback_inodes_sb     vmlinux EXPORT_SYMBOL
++0x506cc085    tracepoint_iter_stop    vmlinux EXPORT_SYMBOL_GPL
++0xe200d2d5    param_get_uint  vmlinux EXPORT_SYMBOL
++0x79cb0ce1    pm_generic_runtime_suspend      vmlinux EXPORT_SYMBOL_GPL
++0x364477d8    do_SAK  vmlinux EXPORT_SYMBOL
++0x8d9c96ee    elv_register    vmlinux EXPORT_SYMBOL_GPL
++0x0c77c871    page_put_link   vmlinux EXPORT_SYMBOL
++0x8f03ba03    release_pages   vmlinux EXPORT_SYMBOL
++0xa4a39c18    v4l2_m2m_streamon       vmlinux EXPORT_SYMBOL_GPL
++0xa2d6eedc    bt_sock_stream_recvmsg  vmlinux EXPORT_SYMBOL
++0xb1bed25d    dpm_resume_start        vmlinux EXPORT_SYMBOL_GPL
++0x10291853    devm_regulator_put      vmlinux EXPORT_SYMBOL_GPL
++0xcf618a57    cfg80211_calculate_bitrate      vmlinux EXPORT_SYMBOL
++0xa9f48f53    km_state_expired        vmlinux EXPORT_SYMBOL
++0x6417850b    qdisc_list_del  vmlinux EXPORT_SYMBOL
++0xb0e10781    get_option      vmlinux EXPORT_SYMBOL
++0x6a3d6744    drm_property_create     vmlinux EXPORT_SYMBOL
++0x60352082    register_inet6addr_notifier     vmlinux EXPORT_SYMBOL
++0x7cabb84d    inet_accept     vmlinux EXPORT_SYMBOL
++0x49b07aec    tcp_select_initial_window       vmlinux EXPORT_SYMBOL
++0xd41766d2    nf_ct_gre_keymap_destroy        vmlinux EXPORT_SYMBOL_GPL
++0x0b225b92    register_pernet_device  vmlinux EXPORT_SYMBOL_GPL
++0xe697d108    __blk_iopoll_complete   vmlinux EXPORT_SYMBOL
++0xa1c76e0a    _cond_resched   vmlinux EXPORT_SYMBOL
++0x22e1ae6f    up_read vmlinux EXPORT_SYMBOL
++0x9fbe4605    class_for_each_device   vmlinux EXPORT_SYMBOL_GPL
++0x4c1e4dba    unbind_con_driver       vmlinux EXPORT_SYMBOL
++0x352cbaad    empty_zero_page vmlinux EXPORT_SYMBOL
++0x66f6b51b    nfnetlink_subsys_register       vmlinux EXPORT_SYMBOL_GPL
++0x2de03b66    ndo_dflt_bridge_getlink vmlinux EXPORT_SYMBOL
++0x1f404818    __pskb_pull_tail        vmlinux EXPORT_SYMBOL
++0x848618a1    snd_pcm_lib_free_vmalloc_buffer vmlinux EXPORT_SYMBOL
++0x11575bf3    bioset_free     vmlinux EXPORT_SYMBOL
++0x2acf0feb    vfs_fstat       vmlinux EXPORT_SYMBOL
++0x0c45fc96    vfs_lstat       vmlinux EXPORT_SYMBOL
++0x20bc3470    orderly_poweroff        vmlinux EXPORT_SYMBOL_GPL
++0xd0c74120    cpufreq_frequency_table_verify  vmlinux EXPORT_SYMBOL_GPL
++0x93af794b    dev_alert       vmlinux EXPORT_SYMBOL
++0x96cd86f2    tty_wait_until_sent     vmlinux EXPORT_SYMBOL
++0x4384f1be    gether_setup_name       vmlinux EXPORT_SYMBOL
++0xa598e29c    vesa_modes      vmlinux EXPORT_SYMBOL
++0x4ead0283    pn_skb_send     vmlinux EXPORT_SYMBOL
++0xc01a92eb    __netif_schedule        vmlinux EXPORT_SYMBOL
++0xd42d86c0    generic_fh_to_parent    vmlinux EXPORT_SYMBOL_GPL
++0x9eaba82f    generic_fillattr        vmlinux EXPORT_SYMBOL
++0x183fa88b    mempool_alloc_slab      vmlinux EXPORT_SYMBOL
++0x5d0b1892    param_set_invbool       vmlinux EXPORT_SYMBOL
++0xe103ee04    gpio_export_link        vmlinux EXPORT_SYMBOL_GPL
++0x24bfaf10    d_instantiate_unique    vmlinux EXPORT_SYMBOL
++0xd6b8e852    request_threaded_irq    vmlinux EXPORT_SYMBOL
++0x18bd76a4    _raw_spin_trylock       vmlinux EXPORT_SYMBOL
++0xc2ffd5d5    iio_trigger_alloc       vmlinux EXPORT_SYMBOL
++0xa749c072    i2c_register_driver     vmlinux EXPORT_SYMBOL
++0x6ea05e17    of_phy_provider_unregister      vmlinux EXPORT_SYMBOL_GPL
++0xc359fb65    abort   vmlinux EXPORT_SYMBOL
++0x9f0f5d05    cfg80211_send_unprot_disassoc   vmlinux EXPORT_SYMBOL
++0xc575c737    debug_locks_off vmlinux EXPORT_SYMBOL_GPL
++0xab2f97aa    jbd2_journal_forget     vmlinux EXPORT_SYMBOL
++0xffea14aa    mutex_lock_interruptible        vmlinux EXPORT_SYMBOL
++0xdb9cfd07    skb_clone       vmlinux EXPORT_SYMBOL
++0x0cdd5fd1    crypto_find_alg vmlinux EXPORT_SYMBOL_GPL
++0x076aff85    set_task_ioprio vmlinux EXPORT_SYMBOL_GPL
++0x773522a8    setup_arg_pages vmlinux EXPORT_SYMBOL
++0x430348ff    input_get_keycode       vmlinux EXPORT_SYMBOL
++0x3c50bfc9    regmap_can_raw_write    vmlinux EXPORT_SYMBOL_GPL
++0x8209afe6    wakeup_source_destroy   vmlinux EXPORT_SYMBOL_GPL
++0x0487f831    fb_find_best_display    vmlinux EXPORT_SYMBOL
++0x83dab696    inode_dio_wait  vmlinux EXPORT_SYMBOL
++0xa3a19433    of_get_regulator_init_data      vmlinux EXPORT_SYMBOL_GPL
++0x43ca0eb7    amba_request_regions    vmlinux EXPORT_SYMBOL
++0xc34efe27    snmp_fold_field vmlinux EXPORT_SYMBOL_GPL
++0x3e48e980    tcp_init_xmit_timers    vmlinux EXPORT_SYMBOL
++0x267c8e5b    snd_soc_register_card   vmlinux EXPORT_SYMBOL_GPL
++0x2d13dc4b    jbd2_journal_start      vmlinux EXPORT_SYMBOL
++0xd67364f7    eventfd_ctx_fdget       vmlinux EXPORT_SYMBOL_GPL
++0xaefaecb4    phy_ethtool_gset        vmlinux EXPORT_SYMBOL
++0x86dded2c    phy_ethtool_sset        vmlinux EXPORT_SYMBOL
++0x1b15cf75    drm_encoder_init        vmlinux EXPORT_SYMBOL
++0x540ef2af    vfs_lock_file   vmlinux EXPORT_SYMBOL_GPL
++0x56fcacd4    bio_uncopy_user vmlinux EXPORT_SYMBOL
++0x9401ec10    make_bad_inode  vmlinux EXPORT_SYMBOL
++0x8ec007a4    __d_drop        vmlinux EXPORT_SYMBOL
++0x7f39e9f3    __mmdrop        vmlinux EXPORT_SYMBOL_GPL
++0x731e1d9d    thermal_zone_device_unregister  vmlinux EXPORT_SYMBOL_GPL
++0x31528994    __i2c_transfer  vmlinux EXPORT_SYMBOL
++0x33dbfd93    tcp_memory_allocated    vmlinux EXPORT_SYMBOL
++0xa8232c78    strtobool       vmlinux EXPORT_SYMBOL
++0xbe744811    jbd2_journal_force_commit_nested        vmlinux EXPORT_SYMBOL
++0xce03751f    seq_release_private     vmlinux EXPORT_SYMBOL
++0xd788742d    perf_trace_buf_prepare  vmlinux EXPORT_SYMBOL_GPL
++0x269f017e    st_sensors_set_dataready_irq    vmlinux EXPORT_SYMBOL
++0x379ea057    hid_check_keys_pressed  vmlinux EXPORT_SYMBOL_GPL
++0xe19a7489    scsi_bus_type   vmlinux EXPORT_SYMBOL_GPL
++0x11f13f3f    snd_ctl_remove  vmlinux EXPORT_SYMBOL
++0xb7a5a52f    writeback_inodes_sb_nr  vmlinux EXPORT_SYMBOL
++0x8efefdc1    vfs_removexattr vmlinux EXPORT_SYMBOL_GPL
++0xbd7c9ac7    find_symbol     vmlinux EXPORT_SYMBOL_GPL
++0xc6ca6078    __mutex_init    vmlinux EXPORT_SYMBOL
++0xe8349cd8    uart_console_write      vmlinux EXPORT_SYMBOL_GPL
++0x2e5810c6    __aeabi_unwind_cpp_pr1  vmlinux EXPORT_SYMBOL
++0x80f711c7    jbd2_journal_check_used_features        vmlinux EXPORT_SYMBOL
++0xcd91b127    system_highpri_wq       vmlinux EXPORT_SYMBOL_GPL
++0x5d2137b0    sdio_readsb     vmlinux EXPORT_SYMBOL_GPL
++0x6883e0d5    rtc_set_time    vmlinux EXPORT_SYMBOL_GPL
++0xf753d6ff    drm_i2c_encoder_mode_set        vmlinux EXPORT_SYMBOL
++0x0b0d888b    icmpv6_err_convert      vmlinux EXPORT_SYMBOL
++0x908cb3fc    vfs_readv       vmlinux EXPORT_SYMBOL
++0x3e467689    do_sync_write   vmlinux EXPORT_SYMBOL
++0xe01edb1a    vb2_plane_vaddr vmlinux EXPORT_SYMBOL_GPL
++0xff9c7899    fb_get_mode     vmlinux EXPORT_SYMBOL
++0x63923641    crypto_shash_setkey     vmlinux EXPORT_SYMBOL_GPL
++0x66c159c0    crypto_ahash_setkey     vmlinux EXPORT_SYMBOL_GPL
++0xb2c17922    search_binary_handler   vmlinux EXPORT_SYMBOL
++0x07438699    rt_mutex_trylock        vmlinux EXPORT_SYMBOL_GPL
++0x559b763f    mmc_detect_change       vmlinux EXPORT_SYMBOL
++0xed2c3cec    drm_debugfs_remove_files        vmlinux EXPORT_SYMBOL
++0xea5c6ccb    rtnl_link_get_net       vmlinux EXPORT_SYMBOL
++0x420c7411    ahash_attr_alg  vmlinux EXPORT_SYMBOL_GPL
++0xc690866c    irq_work_queue  vmlinux EXPORT_SYMBOL_GPL
++0x22640142    sdio_readw      vmlinux EXPORT_SYMBOL_GPL
++0x246e1a87    sdio_readl      vmlinux EXPORT_SYMBOL_GPL
++0xafb35b17    sdio_readb      vmlinux EXPORT_SYMBOL_GPL
++0x713125bd    cpufreq_freq_attr_scaling_available_freqs       vmlinux EXPORT_SYMBOL_GPL
++0xd7095481    usb_remove_phy  vmlinux EXPORT_SYMBOL_GPL
++0x76d878f8    usb_remove_hcd  vmlinux EXPORT_SYMBOL_GPL
++0x7e543e70    device_store_bool       vmlinux EXPORT_SYMBOL_GPL
++0x407136b1    __put_user_8    vmlinux EXPORT_SYMBOL
++0x1567020f    tcp_disconnect  vmlinux EXPORT_SYMBOL
++0x1f615e38    bio_pair_release        vmlinux EXPORT_SYMBOL
++0x2469810f    __rcu_read_unlock       vmlinux EXPORT_SYMBOL_GPL
++0xea51d53a    extcon_get_extcon_dev   vmlinux EXPORT_SYMBOL_GPL
++0x52c47236    put_device      vmlinux EXPORT_SYMBOL_GPL
++0x194eadaa    drm_edid_header_is_valid        vmlinux EXPORT_SYMBOL
++0x7d89e34a    drm_gtf_mode_complex    vmlinux EXPORT_SYMBOL
++0x75c2b9f1    memalloc_socks  vmlinux EXPORT_SYMBOL_GPL
++0xb10dfa5a    register_filesystem     vmlinux EXPORT_SYMBOL
++0x758a782e    blk_fill_rwbs   vmlinux EXPORT_SYMBOL_GPL
++0xba497f13    loops_per_jiffy vmlinux EXPORT_SYMBOL
++0xc657abdc    v4l2_ctrl_subscribe_event       vmlinux EXPORT_SYMBOL
++0xc7472c0b    devm_input_allocate_device      vmlinux EXPORT_SYMBOL
++0xdb2c2fbf    spi_alloc_device        vmlinux EXPORT_SYMBOL_GPL
++0xa33be4ce    inet_confirm_addr       vmlinux EXPORT_SYMBOL
++0x48eb98d1    eth_validate_addr       vmlinux EXPORT_SYMBOL
++0xc5718627    sg_copy_to_buffer       vmlinux EXPORT_SYMBOL
++0x7ab88a45    system_freezing_cnt     vmlinux EXPORT_SYMBOL
++0x7d0db45c    jiffies_to_clock_t      vmlinux EXPORT_SYMBOL
++0x2c208607    power_supply_is_system_supplied vmlinux EXPORT_SYMBOL_GPL
++0xc9422c05    devm_usb_get_phy_dev    vmlinux EXPORT_SYMBOL_GPL
++0xba3a6941    drm_getsarea    vmlinux EXPORT_SYMBOL
++0x1ffe8e3f    nfc_register_device     vmlinux EXPORT_SYMBOL
++0x0478373c    generic_make_request    vmlinux EXPORT_SYMBOL
++0x0b9a91be    generic_file_llseek_size        vmlinux EXPORT_SYMBOL
++0x1c87a811    __round_jiffies_up      vmlinux EXPORT_SYMBOL_GPL
++0x93d6ad2c    usb_debug_root  vmlinux EXPORT_SYMBOL_GPL
++0xd3ce47fe    drm_mode_crtc_set_gamma_size    vmlinux EXPORT_SYMBOL
++0xbe16ad70    drm_addbufs_pci vmlinux EXPORT_SYMBOL
++0xd5dae19f    regulator_get_exclusive vmlinux EXPORT_SYMBOL_GPL
++0x02124474    ip_send_check   vmlinux EXPORT_SYMBOL
++0x628cbfaa    rtmsg_ifinfo    vmlinux EXPORT_SYMBOL
++0xb0d3bca5    __rtnl_register vmlinux EXPORT_SYMBOL_GPL
++0x23b9d6e2    mangle_path     vmlinux EXPORT_SYMBOL
++0xe7c52663    v4l2_m2m_create_bufs    vmlinux EXPORT_SYMBOL_GPL
++0x63625aaa    usb_composite_setup_continue    vmlinux EXPORT_SYMBOL_GPL
++0x41f53df0    anon_inode_getfd        vmlinux EXPORT_SYMBOL_GPL
++0x24d5ba21    filemap_flush   vmlinux EXPORT_SYMBOL
++0xb49f6bea    iio_enum_write  vmlinux EXPORT_SYMBOL_GPL
++0x1bfbfeeb    mc1n2_set_mclk_source   vmlinux EXPORT_SYMBOL
++0x95e6e500    blk_stack_limits        vmlinux EXPORT_SYMBOL
++0xeb46c362    fuse_conn_init  vmlinux EXPORT_SYMBOL_GPL
++0x0e9003db    pm_generic_freeze_late  vmlinux EXPORT_SYMBOL_GPL
++0xf2fa6c7e    drm_gem_vm_close        vmlinux EXPORT_SYMBOL
++0x5bbc0a12    __fib_lookup    vmlinux EXPORT_SYMBOL_GPL
++0x1dd6e42b    tcp_set_state   vmlinux EXPORT_SYMBOL_GPL
++0xa77d88f6    strnlen_user    vmlinux EXPORT_SYMBOL
++0x191ef206    i2c_smbus_read_i2c_block_data   vmlinux EXPORT_SYMBOL
++0x52b992dc    drm_kms_helper_poll_disable     vmlinux EXPORT_SYMBOL
++0x6fc997a4    tty_mutex       vmlinux EXPORT_SYMBOL
++0x3973c5f8    kunmap  vmlinux EXPORT_SYMBOL
++0xb28f5ef1    xt_free_table_info      vmlinux EXPORT_SYMBOL
++0x1d0b568b    mnt_pin vmlinux EXPORT_SYMBOL
++0x50ba53b9    set_create_files_as     vmlinux EXPORT_SYMBOL
++0xcbd3dbd0    serial8250_modem_status vmlinux EXPORT_SYMBOL_GPL
++0xe38dd51c    dev_get_by_name vmlinux EXPORT_SYMBOL
++0x69458fd5    snd_dma_alloc_pages_fallback    vmlinux EXPORT_SYMBOL
++0xb3fda4b7    __page_symlink  vmlinux EXPORT_SYMBOL
++0x400fb79c    install_exec_creds      vmlinux EXPORT_SYMBOL
++0xbed3ae54    sched_setscheduler      vmlinux EXPORT_SYMBOL_GPL
++0xeb923e09    power_supply_set_battery_charged        vmlinux EXPORT_SYMBOL_GPL
++0xfdab6de3    unregister_sound_midi   vmlinux EXPORT_SYMBOL
++0x30a80826    __kfifo_from_user       vmlinux EXPORT_SYMBOL
++0x6923ce63    irq_work_sync   vmlinux EXPORT_SYMBOL_GPL
++0xe7197773    drm_ht_insert_item      vmlinux EXPORT_SYMBOL
++0xdf75f3c9    ipcomp_input    vmlinux EXPORT_SYMBOL_GPL
++0xac966a6d    udp_prot        vmlinux EXPORT_SYMBOL
++0xc6531cd4    inet_putpeer    vmlinux EXPORT_SYMBOL_GPL
++0xe2b955e2    nat_h245_hook   vmlinux EXPORT_SYMBOL_GPL
++0xf34732f2    netif_set_xps_queue     vmlinux EXPORT_SYMBOL
++0x7681d145    snd_ctl_register_ioctl  vmlinux EXPORT_SYMBOL
++0xaae48971    mmc_card_sleep  vmlinux EXPORT_SYMBOL
++0x58fe6474    v4l2_m2m_ioctl_qbuf     vmlinux EXPORT_SYMBOL_GPL
++0x00d1d0d0    i2c_adapter_type        vmlinux EXPORT_SYMBOL_GPL
++0xb971ebca    rndis_get_next_response vmlinux EXPORT_SYMBOL
++0xc88b565d    inet6_sk_rebuild_header vmlinux EXPORT_SYMBOL_GPL
++0x83a4c277    mb_cache_shrink vmlinux EXPORT_SYMBOL
++0xf1e98c74    avenrun vmlinux EXPORT_SYMBOL
++0x1318fa1c    __ww_mutex_lock_interruptible   vmlinux EXPORT_SYMBOL
++0x2d3385d3    system_wq       vmlinux EXPORT_SYMBOL
++0x94e4e64e    v4l2_event_queue        vmlinux EXPORT_SYMBOL_GPL
++0x76fd0937    device_init_wakeup      vmlinux EXPORT_SYMBOL_GPL
++0x40a6f522    __arm_ioremap   vmlinux EXPORT_SYMBOL
++0xc2165d85    __arm_iounmap   vmlinux EXPORT_SYMBOL
++0xaf50e76d    elf_set_personality     vmlinux EXPORT_SYMBOL
++0xd9f8f32d    nf_ct_extend_register   vmlinux EXPORT_SYMBOL_GPL
++0x6ceb8cf4    mark_page_accessed      vmlinux EXPORT_SYMBOL
++0x17f36c02    mmc_calc_max_discard    vmlinux EXPORT_SYMBOL
++0x0d45c48f    v4l2_clk_register       vmlinux EXPORT_SYMBOL
++0x123959a1    v4l2_type_names vmlinux EXPORT_SYMBOL
++0x02a18c74    nf_conntrack_destroy    vmlinux EXPORT_SYMBOL
++0x679f4b6b    scsi_report_bus_reset   vmlinux EXPORT_SYMBOL
++0xf8224b12    mali_get_user_setting   vmlinux EXPORT_SYMBOL
++0x3c93ad98    tty_port_install        vmlinux EXPORT_SYMBOL_GPL
++0x63fb81e4    brcmu_pktq_penq drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x723a1683    brcmu_pktq_pdeq drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0xfa595453    ip6_sk_dst_lookup_flow  vmlinux EXPORT_SYMBOL_GPL
++0xa76f7e50    snd_dma_get_reserved_buf        vmlinux EXPORT_SYMBOL
++0x61ed1c8e    cdev_add        vmlinux EXPORT_SYMBOL
++0x69447467    ring_buffer_write       vmlinux EXPORT_SYMBOL_GPL
++0xfcd7bc0b    ring_buffer_empty       vmlinux EXPORT_SYMBOL_GPL
++0x82939ebd    rcu_batches_completed_sched     vmlinux EXPORT_SYMBOL_GPL
++0x9e44b9b7    of_get_next_available_child     vmlinux EXPORT_SYMBOL
++0x1010f1ee    hid_output_report       vmlinux EXPORT_SYMBOL_GPL
++0x59e5070d    __do_div64      vmlinux EXPORT_SYMBOL
++0xa2d91fcc    xfrm_input      vmlinux EXPORT_SYMBOL
++0x07a62853    dev_mc_add      vmlinux EXPORT_SYMBOL
++0x40908b29    dev_mc_del      vmlinux EXPORT_SYMBOL
++0x2eed048e    dev_uc_add      vmlinux EXPORT_SYMBOL
++0x69dba7f4    dev_uc_del      vmlinux EXPORT_SYMBOL
++0x15361516    register_pernet_subsys  vmlinux EXPORT_SYMBOL_GPL
++0x915be34a    snd_timer_new   vmlinux EXPORT_SYMBOL
++0x3c45a56f    blk_queue_update_dma_pad        vmlinux EXPORT_SYMBOL
++0x069d40a0    blkdev_get_by_path      vmlinux EXPORT_SYMBOL
++0xa440bdfe    open_exec       vmlinux EXPORT_SYMBOL
++0x374682ce    rtc_update_irq  vmlinux EXPORT_SYMBOL_GPL
++0xba2d0719    drm_mode_hsync  vmlinux EXPORT_SYMBOL
++0x2d7a787f    drm_dp_clock_recovery_ok        vmlinux EXPORT_SYMBOL
++0xd59b2bb0    fb_blank        vmlinux EXPORT_SYMBOL
++0x0b48677a    __kfifo_init    vmlinux EXPORT_SYMBOL
++0x249c96e2    mb_cache_entry_find_next        vmlinux EXPORT_SYMBOL
++0xaee2539e    inode_init_owner        vmlinux EXPORT_SYMBOL
++0x7b24ccb3    file_ns_capable vmlinux EXPORT_SYMBOL
++0x37c0412f    cpu_subsys      vmlinux EXPORT_SYMBOL_GPL
++0x9993bf08    rt_mutex_destroy        vmlinux EXPORT_SYMBOL_GPL
++0xd4034828    system_freezable_wq     vmlinux EXPORT_SYMBOL_GPL
++0x9963a089    queue_delayed_work_on   vmlinux EXPORT_SYMBOL
++0x1284891b    iio_trigger_notify_done vmlinux EXPORT_SYMBOL
++0x03212586    v4l2_m2m_streamoff      vmlinux EXPORT_SYMBOL_GPL
++0x5b19634d    div_s64_rem     vmlinux EXPORT_SYMBOL
++0xb110bb66    __set_page_dirty_nobuffers      vmlinux EXPORT_SYMBOL
++0xd7d79132    put_online_cpus vmlinux EXPORT_SYMBOL_GPL
++0x121e3c12    devres_open_group       vmlinux EXPORT_SYMBOL_GPL
++0x8eae4744    __nf_ct_kill_acct       vmlinux EXPORT_SYMBOL_GPL
++0xcf88625f    mempool_create_node     vmlinux EXPORT_SYMBOL
++0x222fa684    lg_global_lock  vmlinux EXPORT_SYMBOL
++0x7cb2eca1    find_get_pid    vmlinux EXPORT_SYMBOL_GPL
++0x971ad8d8    usbnet_unlink_rx_urbs   vmlinux EXPORT_SYMBOL_GPL
++0xa551b417    devm_pwm_get    vmlinux EXPORT_SYMBOL_GPL
++0xb138607d    dev_set_promiscuity     vmlinux EXPORT_SYMBOL
++0xc8ca31af    timed_output_dev_register       vmlinux EXPORT_SYMBOL_GPL
++0x2967cbf7    dm_get_rq_mapinfo       vmlinux EXPORT_SYMBOL_GPL
++0x07013243    scsi_bios_ptable        vmlinux EXPORT_SYMBOL
++0x9780e683    pm_generic_resume       vmlinux EXPORT_SYMBOL_GPL
++0x3074f033    drm_order       vmlinux EXPORT_SYMBOL
++0xa87f4ece    neigh_connected_output  vmlinux EXPORT_SYMBOL
++0xe9f7149c    zlib_deflate_workspacesize      vmlinux EXPORT_SYMBOL
++0x2d03c10d    posix_acl_create        vmlinux EXPORT_SYMBOL
++0xbe254e92    param_set_ushort        vmlinux EXPORT_SYMBOL
++0xf0ca36cf    drm_prime_init_file_private     vmlinux EXPORT_SYMBOL
++0xb001e18c    drm_plane_init  vmlinux EXPORT_SYMBOL
++0xb2922319    bt_sock_recvmsg vmlinux EXPORT_SYMBOL
++0xe7f38f6d    udp_flush_pending_frames        vmlinux EXPORT_SYMBOL
++0xf0726368    dev_get_stats   vmlinux EXPORT_SYMBOL
++0xd3f7e5cc    snd_soc_default_volatile_register       vmlinux EXPORT_SYMBOL_GPL
++0x92c5fcb5    snd_timer_notify        vmlinux EXPORT_SYMBOL
++0x86fb9b05    bitmap_parse_user       vmlinux EXPORT_SYMBOL
++0x01000e51    schedule        vmlinux EXPORT_SYMBOL
++0xbd597aa3    usb_add_function        vmlinux EXPORT_SYMBOL_GPL
++0x460e4737    pm_generic_poweroff     vmlinux EXPORT_SYMBOL_GPL
++0x6920e885    nlmsg_notify    vmlinux EXPORT_SYMBOL
++0x247a1d7a    ww_mutex_unlock vmlinux EXPORT_SYMBOL
++0x1498f6af    mmput   vmlinux EXPORT_SYMBOL_GPL
++0x709eb78b    init_task       vmlinux EXPORT_SYMBOL
++0x3052a0ee    watchdog_unregister_device      vmlinux EXPORT_SYMBOL_GPL
++0x80eaa56e    drm_i2c_encoder_save    vmlinux EXPORT_SYMBOL
++0xe540813f    drm_property_create_enum        vmlinux EXPORT_SYMBOL
++0x6c642207    drm_get_connector_name  vmlinux EXPORT_SYMBOL
++0x42151efa    balloon_devinfo_alloc   vmlinux EXPORT_SYMBOL_GPL
++0xfa544711    video_devdata   vmlinux EXPORT_SYMBOL
++0x8e9618cd    wakeup_source_create    vmlinux EXPORT_SYMBOL_GPL
++0x72f12e79    drm_probe_ddc   vmlinux EXPORT_SYMBOL
++0x89d66811    build_ehash_secret      vmlinux EXPORT_SYMBOL
++0xf4329926    __inet_twsk_hashdance   vmlinux EXPORT_SYMBOL_GPL
++0xd0e13603    gnet_stats_copy_app     vmlinux EXPORT_SYMBOL
++0x1b015d25    bitmap_parselist        vmlinux EXPORT_SYMBOL
++0xf91bf3db    __insert_inode_hash     vmlinux EXPORT_SYMBOL
++0x308b733a    getboottime     vmlinux EXPORT_SYMBOL_GPL
++0x69f04aa3    revert_creds    vmlinux EXPORT_SYMBOL
++0xdf929370    fs_overflowgid  vmlinux EXPORT_SYMBOL
++0xa1177bf1    i2c_verify_client       vmlinux EXPORT_SYMBOL
++0x0e5358d0    input_allocate_device   vmlinux EXPORT_SYMBOL
++0x4fed4ee0    pm_runtime_barrier      vmlinux EXPORT_SYMBOL_GPL
++0xb939d297    dev_printk      vmlinux EXPORT_SYMBOL
++0x090849e3    phy_power_on    vmlinux EXPORT_SYMBOL_GPL
++0x47416e14    cpu_rmap_add    vmlinux EXPORT_SYMBOL
++0x08fbaf94    xfrm_policy_walk        vmlinux EXPORT_SYMBOL
++0x774846b4    nf_log_unset    vmlinux EXPORT_SYMBOL
++0x00aaf0d4    wm_hubs_add_analogue_routes     vmlinux EXPORT_SYMBOL_GPL
++0xe9d7e477    snd_card_proc_new       vmlinux EXPORT_SYMBOL
++0x97de2b83    debug_locks_silent      vmlinux EXPORT_SYMBOL_GPL
++0x3e452a00    blocking_notifier_call_chain    vmlinux EXPORT_SYMBOL_GPL
++0xae83dc8c    spi_bitbang_setup_transfer      vmlinux EXPORT_SYMBOL_GPL
++0x8d871961    cpu_tlb vmlinux EXPORT_SYMBOL
++0xfe694f5b    regmap_read     vmlinux EXPORT_SYMBOL_GPL
++0x594bf15b    ioport_map      vmlinux EXPORT_SYMBOL
++0x2d3abae7    __skb_checksum_complete vmlinux EXPORT_SYMBOL
++0xb5a459dc    unregister_blkdev       vmlinux EXPORT_SYMBOL
++0xd0a8eac3    write_inode_now vmlinux EXPORT_SYMBOL
++0x7d3a11d4    tty_lock        vmlinux EXPORT_SYMBOL
++0xa6dea12e    regulator_register      vmlinux EXPORT_SYMBOL_GPL
++0x0ce021b8    ieee80211_amsdu_to_8023s        vmlinux EXPORT_SYMBOL
++0xe0088286    fat_search_long vmlinux EXPORT_SYMBOL_GPL
++0x08ca5b31    seq_path        vmlinux EXPORT_SYMBOL
++0xcc5005fe    msleep_interruptible    vmlinux EXPORT_SYMBOL
++0x2f0d9053    usb_otg_state_string    vmlinux EXPORT_SYMBOL_GPL
++0xf2997713    tty_termios_hw_change   vmlinux EXPORT_SYMBOL
++0x53893194    dev_addr_add    vmlinux EXPORT_SYMBOL
++0x0dd3fd84    netdev_err      vmlinux EXPORT_SYMBOL
++0x62849ac7    dev_valid_name  vmlinux EXPORT_SYMBOL
++0x193466be    kfree_skb_partial       vmlinux EXPORT_SYMBOL
++0xd2a941d4    sg_init_table   vmlinux EXPORT_SYMBOL
++0x5642793a    radix_tree_tag_clear    vmlinux EXPORT_SYMBOL
++0xc3bb6d9e    blk_pre_runtime_resume  vmlinux EXPORT_SYMBOL
++0xd3a7747d    fsnotify        vmlinux EXPORT_SYMBOL_GPL
++0x4f3b569c    generic_file_open       vmlinux EXPORT_SYMBOL
++0xc87c1f84    ktime_get       vmlinux EXPORT_SYMBOL_GPL
++0x89bbafc6    usb_register_notify     vmlinux EXPORT_SYMBOL_GPL
++0x19ac480a    cfg80211_new_sta        vmlinux EXPORT_SYMBOL
++0xd18ba458    generic_cont_expand_simple      vmlinux EXPORT_SYMBOL
++0x5cf6467f    d_instantiate   vmlinux EXPORT_SYMBOL
++0xd1ef6f16    genphy_update_link      vmlinux EXPORT_SYMBOL
++0x4a77677a    nfc_hci_recv_frame      vmlinux EXPORT_SYMBOL
++0xc2a19d85    register_sound_special_device   vmlinux EXPORT_SYMBOL
++0x5b3060c4    blk_queue_rq_timed_out  vmlinux EXPORT_SYMBOL_GPL
++0x2cbfd99b    vb2_queue_init  vmlinux EXPORT_SYMBOL_GPL
++0x955d725c    drm_mm_scan_remove_block        vmlinux EXPORT_SYMBOL
++0x6d346792    pin_config_group_get    vmlinux EXPORT_SYMBOL
++0xf82a1863    pin_config_group_set    vmlinux EXPORT_SYMBOL
++0x08c473b7    xt_alloc_table_info     vmlinux EXPORT_SYMBOL
++0xb7b61546    crc32_be        vmlinux EXPORT_SYMBOL
++0x26520970    vm_memory_committed     vmlinux EXPORT_SYMBOL_GPL
++0xcf283b4f    iommu_domain_alloc      vmlinux EXPORT_SYMBOL_GPL
++0x52ffd07f    xfrm_output_resume      vmlinux EXPORT_SYMBOL_GPL
++0x4c21e163    skb_find_text   vmlinux EXPORT_SYMBOL
++0x5279b639    current_fs_time vmlinux EXPORT_SYMBOL
++0x04cc0a21    i2c_unregister_device   vmlinux EXPORT_SYMBOL_GPL
++0x13fc56de    drm_helper_crtc_in_use  vmlinux EXPORT_SYMBOL
++0x6d399587    regulator_unregister    vmlinux EXPORT_SYMBOL_GPL
++0x6b037ba6    nf_nat_l4proto_unregister       vmlinux EXPORT_SYMBOL_GPL
++0x8231a8bd    nf_nat_l3proto_unregister       vmlinux EXPORT_SYMBOL_GPL
++0x6350314b    tcf_hash_create vmlinux EXPORT_SYMBOL
++0xf339287c    skb_queue_tail  vmlinux EXPORT_SYMBOL
++0x5409775b    free_irq_cpu_rmap       vmlinux EXPORT_SYMBOL
++0x65771426    crypto_lookup_template  vmlinux EXPORT_SYMBOL_GPL
++0xd61347c6    register_sysctl vmlinux EXPORT_SYMBOL
++0xd8c37e37    vfs_test_lock   vmlinux EXPORT_SYMBOL_GPL
++0x952664c5    do_exit vmlinux EXPORT_SYMBOL_GPL
++0xcb07e4af    tcf_hash_destroy        vmlinux EXPORT_SYMBOL
++0x78953de6    mark_buffer_dirty_inode vmlinux EXPORT_SYMBOL
++0x3109b751    cpu_clock       vmlinux EXPORT_SYMBOL_GPL
++0xdf842e2b    drm_vblank_cleanup      vmlinux EXPORT_SYMBOL
++0x57810201    ip_tunnel_lookup        vmlinux EXPORT_SYMBOL_GPL
++0xb1c3a01a    oops_in_progress        vmlinux EXPORT_SYMBOL
++0x0fca29c0    dev_pm_qos_remove_request       vmlinux EXPORT_SYMBOL_GPL
++0xc407a137    dma_wait_for_async_tx   vmlinux EXPORT_SYMBOL_GPL
++0x046a9d1b    backlight_device_register       vmlinux EXPORT_SYMBOL
++0x2a36b31a    nf_ct_helper_log        vmlinux EXPORT_SYMBOL_GPL
++0xb442919d    blk_get_backing_dev_info        vmlinux EXPORT_SYMBOL
++0x0ed2f3b5    elevator_init   vmlinux EXPORT_SYMBOL
++0x21bda10a    kill_fasync     vmlinux EXPORT_SYMBOL
++0x622dacba    tick_nohz_idle_enter    vmlinux EXPORT_SYMBOL_GPL
++0xdd4a5569    param_get_byte  vmlinux EXPORT_SYMBOL
++0x764d38f1    tty_insert_flip_string_fixed_flag       vmlinux EXPORT_SYMBOL
++0xcf5bc354    tty_register_ldisc      vmlinux EXPORT_SYMBOL
++0x88f68355    tty_throttle    vmlinux EXPORT_SYMBOL
++0x335e720e    tty_check_change        vmlinux EXPORT_SYMBOL
++0x1d5568cb    dev_disable_lro vmlinux EXPORT_SYMBOL
++0xb2be6e92    netdev_stats_to_stats64 vmlinux EXPORT_SYMBOL
++0x728261ca    kblockd_schedule_delayed_work   vmlinux EXPORT_SYMBOL
++0x5c959646    debugfs_create_u8       vmlinux EXPORT_SYMBOL_GPL
++0x0c150d31    cgroup_taskset_first    vmlinux EXPORT_SYMBOL_GPL
++0xec690544    attribute_container_classdev_to_container       vmlinux EXPORT_SYMBOL_GPL
++0xda1613df    drm_put_dev     vmlinux EXPORT_SYMBOL
++0x157667da    drm_gem_vm_open vmlinux EXPORT_SYMBOL
++0x8ad8d79e    drm_fb_helper_setcmap   vmlinux EXPORT_SYMBOL
++0x5550f136    snd_soc_dapm_info_pin_switch    vmlinux EXPORT_SYMBOL_GPL
++0xcb08eeba    drm_core_ioremap        vmlinux EXPORT_SYMBOL
++0x6aba167a    regulator_list_voltage  vmlinux EXPORT_SYMBOL_GPL
++0x1b0ac272    __tracepoint_kmalloc_node       vmlinux EXPORT_SYMBOL
++0xd62c833f    schedule_timeout        vmlinux EXPORT_SYMBOL
++0x432fd7f6    __gpio_set_value        vmlinux EXPORT_SYMBOL_GPL
++0x6c8d5ae8    __gpio_get_value        vmlinux EXPORT_SYMBOL_GPL
++0x65ccb6f0    call_netevent_notifiers vmlinux EXPORT_SYMBOL_GPL
++0x4a7fb243    percpu_counter_compare  vmlinux EXPORT_SYMBOL
++0xced58760    crypto_alloc_base       vmlinux EXPORT_SYMBOL_GPL
++0xfcf2f8c0    aio_put_req     vmlinux EXPORT_SYMBOL
++0x6f3a36eb    dw_mci_pltfm_pmops      vmlinux EXPORT_SYMBOL_GPL
++0xe6c3ebb0    __raw_writesw   vmlinux EXPORT_SYMBOL
++0x51908eb8    __raw_writesl   vmlinux EXPORT_SYMBOL
++0x75fee7fd    __raw_writesb   vmlinux EXPORT_SYMBOL
++0xef35b0c3    cfg80211_report_wowlan_wakeup   vmlinux EXPORT_SYMBOL
++0x99591a7a    ipv6_ext_hdr    vmlinux EXPORT_SYMBOL
++0x65396d44    neigh_destroy   vmlinux EXPORT_SYMBOL
++0x405b485b    netdev_warn     vmlinux EXPORT_SYMBOL
++0xf45f8934    blk_end_request_cur     vmlinux EXPORT_SYMBOL
++0x9a682368    replace_mount_options   vmlinux EXPORT_SYMBOL
++0x5a7c0586    hid_validate_values     vmlinux EXPORT_SYMBOL_GPL
++0x88618588    mmc_wait_for_app_cmd    vmlinux EXPORT_SYMBOL
++0xccbbfe3b    v4l2_fh_del     vmlinux EXPORT_SYMBOL_GPL
++0xcefcd99a    serial8250_unregister_port      vmlinux EXPORT_SYMBOL
++0x0bed6399    __xfrm_policy_check     vmlinux EXPORT_SYMBOL
++0xf1947b5c    snd_ctl_rename_id       vmlinux EXPORT_SYMBOL
++0xb9220639    blk_lld_busy    vmlinux EXPORT_SYMBOL_GPL
++0x4178eee3    blk_sync_queue  vmlinux EXPORT_SYMBOL
++0x32b0e045    usbnet_get_link vmlinux EXPORT_SYMBOL_GPL
++0xd578f42c    fat_alloc_new_dir       vmlinux EXPORT_SYMBOL_GPL
++0x0eacb23a    simple_write_end        vmlinux EXPORT_SYMBOL
++0xcbee20b2    get_cpu_iowait_time_us  vmlinux EXPORT_SYMBOL_GPL
++0xea01bd2a    st_sensors_init_sensor  vmlinux EXPORT_SYMBOL
++0xb7433944    hid_open_report vmlinux EXPORT_SYMBOL_GPL
++0x2d339a62    scsi_schedule_eh        vmlinux EXPORT_SYMBOL_GPL
++0xc6544448    pm_runtime_irq_safe     vmlinux EXPORT_SYMBOL_GPL
++0xa5afacf6    class_unregister        vmlinux EXPORT_SYMBOL_GPL
++0xedf69cd6    drm_gem_private_object_init     vmlinux EXPORT_SYMBOL
++0x999c3148    __raw_readsb    vmlinux EXPORT_SYMBOL
++0xfb268a5f    ip_mc_rejoin_groups     vmlinux EXPORT_SYMBOL
++0xafe4c25e    netdev_update_features  vmlinux EXPORT_SYMBOL
++0xd75c79df    smp_call_function       vmlinux EXPORT_SYMBOL
++0xef6c3f70    round_jiffies_up_relative       vmlinux EXPORT_SYMBOL_GPL
++0x64420947    spi_async       vmlinux EXPORT_SYMBOL_GPL
++0xe62c2cf6    regmap_raw_write_async  vmlinux EXPORT_SYMBOL_GPL
++0x226a057d    eth_header_cache        vmlinux EXPORT_SYMBOL
++0xb9d025c9    llist_del_first vmlinux EXPORT_SYMBOL_GPL
++0xb678366f    int_sqrt        vmlinux EXPORT_SYMBOL
++0x9d28f747    dec_zone_page_state     vmlinux EXPORT_SYMBOL
++0x0799aca4    local_bh_enable vmlinux EXPORT_SYMBOL
++0x8d07023c    i2c_smbus_read_byte_data        vmlinux EXPORT_SYMBOL
++0xca5dbc50    scsi_print_sense_hdr    vmlinux EXPORT_SYMBOL
++0x3da076a8    scsi_host_lookup        vmlinux EXPORT_SYMBOL
++0xf54ff64f    uart_set_options        vmlinux EXPORT_SYMBOL_GPL
++0x47ff399f    regulator_is_supported_voltage  vmlinux EXPORT_SYMBOL_GPL
++0x585469ee    of_get_videomode        vmlinux EXPORT_SYMBOL_GPL
++0x852786a9    phy_get vmlinux EXPORT_SYMBOL_GPL
++0xaf8aa518    system_rev      vmlinux EXPORT_SYMBOL
++0x6c3d2a02    tcp_syn_flood_action    vmlinux EXPORT_SYMBOL
++0xf38bcdf3    nf_conntrack_max        vmlinux EXPORT_SYMBOL_GPL
++0x44de5177    snd_pcm_suspend vmlinux EXPORT_SYMBOL
++0xb23ef570    blk_bio_map_sg  vmlinux EXPORT_SYMBOL
++0x4c5e7289    config_item_get vmlinux EXPORT_SYMBOL
++0xea12473b    config_item_put vmlinux EXPORT_SYMBOL
++0xbe68ef11    mnt_drop_write_file     vmlinux EXPORT_SYMBOL
++0x381144a9    __tracepoint_module_get vmlinux EXPORT_SYMBOL
++0xc5fdef94    call_usermodehelper     vmlinux EXPORT_SYMBOL
++0x1eb9516e    round_jiffies_relative  vmlinux EXPORT_SYMBOL_GPL
++0x7cc035a7    __ucmpdi2       vmlinux EXPORT_SYMBOL
++0xe42e1f70    klist_iter_init_node    vmlinux EXPORT_SYMBOL_GPL
++0x5c440c21    hci_conn_check_secure   vmlinux EXPORT_SYMBOL
++0x5b34d4b0    snd_soc_codec_readable_register vmlinux EXPORT_SYMBOL_GPL
++0x0634100a    bitmap_parselist_user   vmlinux EXPORT_SYMBOL
++0x5b72009f    ida_simple_get  vmlinux EXPORT_SYMBOL
++0x11a6ce4b    blk_queue_update_dma_alignment  vmlinux EXPORT_SYMBOL
++0x3e0dd939    blk_start_request       vmlinux EXPORT_SYMBOL
++0x51749fc8    _raw_read_lock_irq      vmlinux EXPORT_SYMBOL
++0x757bbc48    hrtimer_try_to_cancel   vmlinux EXPORT_SYMBOL_GPL
++0x70899e95    v4l2_m2m_buf_remove     vmlinux EXPORT_SYMBOL_GPL
++0x5f96a661    v4l2_ctrl_check vmlinux EXPORT_SYMBOL
++0x42bf1c34    video_unregister_device vmlinux EXPORT_SYMBOL
++0xcd914413    drm_get_minor   vmlinux EXPORT_SYMBOL
++0xa0e5202d    nf_register_hook        vmlinux EXPORT_SYMBOL
++0x86d5e343    __dev_get_by_name       vmlinux EXPORT_SYMBOL
++0x2cc749f6    skb_copy_and_csum_dev   vmlinux EXPORT_SYMBOL
++0x9613509a    idr_replace     vmlinux EXPORT_SYMBOL
++0x82acfb70    blk_iopoll_sched        vmlinux EXPORT_SYMBOL
++0x2c7db649    irq_dispose_mapping     vmlinux EXPORT_SYMBOL_GPL
++0x530b1e98    pm_suspend      vmlinux EXPORT_SYMBOL
++0xae69b1c1    usermodehelper_read_unlock      vmlinux EXPORT_SYMBOL_GPL
++0x39f4b0d2    s3c_adc_release vmlinux EXPORT_SYMBOL_GPL
++0xc2f16e25    input_unregister_handle vmlinux EXPORT_SYMBOL
++0x67326732    usb_hcd_map_urb_for_dma vmlinux EXPORT_SYMBOL_GPL
++0xd125790d    drm_hdmi_avi_infoframe_from_display_mode        vmlinux EXPORT_SYMBOL
++0xe10a472d    drm_mm_pre_get  vmlinux EXPORT_SYMBOL
++0xf082ddf3    register_netdev vmlinux EXPORT_SYMBOL
++0x935b5da0    snd_timer_continue      vmlinux EXPORT_SYMBOL
++0xcc37f55c    blk_limits_io_opt       vmlinux EXPORT_SYMBOL
++0xd4c5def3    inet_twsk_purge vmlinux EXPORT_SYMBOL_GPL
++0x9e9f1714    __bitmap_andnot vmlinux EXPORT_SYMBOL
++0x737de5e9    radix_tree_tag_get      vmlinux EXPORT_SYMBOL
++0xed1e0a03    posix_acl_from_xattr    vmlinux EXPORT_SYMBOL
++0x5256cd6e    clear_nlink     vmlinux EXPORT_SYMBOL
++0xc9f0ae5d    nf_xfrm_me_harder       vmlinux EXPORT_SYMBOL
++0x4751c2af    dev_loopback_xmit       vmlinux EXPORT_SYMBOL
++0x74bd982c    skb_seq_read    vmlinux EXPORT_SYMBOL
++0x798c5110    snd_soc_platform_trigger        vmlinux EXPORT_SYMBOL_GPL
++0x5362ae46    config_item_init        vmlinux EXPORT_SYMBOL
++0x83c8a355    param_set_int   vmlinux EXPORT_SYMBOL
++0x8099b954    i2c_transfer    vmlinux EXPORT_SYMBOL
++0x61e262f1    scsi_device_lookup      vmlinux EXPORT_SYMBOL
++0xfbb86a51    drm_i2c_encoder_prepare vmlinux EXPORT_SYMBOL
++0x4090c0fe    snd_card_file_add       vmlinux EXPORT_SYMBOL
++0x559879f5    crypto_drop_spawn       vmlinux EXPORT_SYMBOL_GPL
++0x27c2197f    param_set_short vmlinux EXPORT_SYMBOL
++0xcc4c1be7    nf_nat_tftp_hook        vmlinux EXPORT_SYMBOL_GPL
++0xc9a3b093    get_h225_addr   vmlinux EXPORT_SYMBOL_GPL
++0x59e9d996    skb_pad vmlinux EXPORT_SYMBOL
++0x77bc13a0    strim   vmlinux EXPORT_SYMBOL
++0x4c2a94b4    shash_register_instance vmlinux EXPORT_SYMBOL_GPL
++0x33c77d65    seq_write       vmlinux EXPORT_SYMBOL
++0x44aec3a4    generic_file_llseek     vmlinux EXPORT_SYMBOL
++0x12d60b5f    v4l2_ctrl_handler_free  vmlinux EXPORT_SYMBOL
++0x19f0c50a    ip6_tnl_parse_tlv_enc_lim       vmlinux EXPORT_SYMBOL
++0x1cea8d0a    snd_soc_dapm_new_widgets        vmlinux EXPORT_SYMBOL_GPL
++0xe1f4606d    snd_info_create_module_entry    vmlinux EXPORT_SYMBOL
++0x999e8297    vfree   vmlinux EXPORT_SYMBOL
++0x841575f5    wait_on_page_bit        vmlinux EXPORT_SYMBOL
++0x51205d4b    mutex_lock      vmlinux EXPORT_SYMBOL
++0xe97c74fd    rtc_update_irq_enable   vmlinux EXPORT_SYMBOL_GPL
++0x849722db    dma_request_slave_channel       vmlinux EXPORT_SYMBOL_GPL
++0x120b336a    __rb_insert_augmented   vmlinux EXPORT_SYMBOL
++0x6359b128    elv_rq_merge_ok vmlinux EXPORT_SYMBOL
++0xee3496c3    dma_pool_alloc  vmlinux EXPORT_SYMBOL
++0xa835f402    mmc_detect_card_removed vmlinux EXPORT_SYMBOL
++0xbe1b0b72    scsi_get_host_dev       vmlinux EXPORT_SYMBOL
++0xaf4e166f    dma_async_memcpy_pg_to_pg       vmlinux EXPORT_SYMBOL
++0xe34d76a6    l2cap_is_socket vmlinux EXPORT_SYMBOL
++0xd875e3e2    ip6_route_lookup        vmlinux EXPORT_SYMBOL_GPL
++0xd58c5fcb    tcp_v4_do_rcv   vmlinux EXPORT_SYMBOL
++0x3413b5de    blk_dump_rq_flags       vmlinux EXPORT_SYMBOL
++0xc8449f3c    sysfs_create_group      vmlinux EXPORT_SYMBOL_GPL
++0xf3e42ab4    get_device      vmlinux EXPORT_SYMBOL_GPL
++0xf147dcb2    hdmi_spd_infoframe_init vmlinux EXPORT_SYMBOL
++0x1776281f    xfrm_unregister_mode    vmlinux EXPORT_SYMBOL
++0x4737cc63    consume_skb     vmlinux EXPORT_SYMBOL
++0x72081296    extcon_find_cable_index vmlinux EXPORT_SYMBOL_GPL
++0x641d5fb6    usbnet_status_start     vmlinux EXPORT_SYMBOL_GPL
++0x8f2c5edc    scsi_add_device vmlinux EXPORT_SYMBOL
++0x8652db9f    __pm_stay_awake vmlinux EXPORT_SYMBOL_GPL
++0xb9d3a88c    tcf_action_dump_1       vmlinux EXPORT_SYMBOL
++0xb6f19e98    snd_pcm_lib_get_vmalloc_page    vmlinux EXPORT_SYMBOL
++0x29e5e6f3    poll_schedule_timeout   vmlinux EXPORT_SYMBOL
++0x99f58330    lg_local_lock_cpu       vmlinux EXPORT_SYMBOL
++0x58862e69    v4l2_m2m_ioctl_streamon vmlinux EXPORT_SYMBOL_GPL
++0xa340fae0    i2c_add_numbered_adapter        vmlinux EXPORT_SYMBOL_GPL
++0x806c2801    usb_unanchor_urb        vmlinux EXPORT_SYMBOL_GPL
++0x485b3745    dma_get_slave_channel   vmlinux EXPORT_SYMBOL_GPL
++0x1d0a43c3    phy_power_off   vmlinux EXPORT_SYMBOL_GPL
++0x0fd14a9d    tcp_prot        vmlinux EXPORT_SYMBOL
++0x4bfdc9e2    textsearch_prepare      vmlinux EXPORT_SYMBOL
++0x988958ef    fuse_direct_io  vmlinux EXPORT_SYMBOL_GPL
++0x996c4d30    proc_dointvec_ms_jiffies        vmlinux EXPORT_SYMBOL
++0x785d494b    rndis_msg_parser        vmlinux EXPORT_SYMBOL
++0xcea853d2    root_device_unregister  vmlinux EXPORT_SYMBOL_GPL
++0xf13f5821    inet_frag_kill  vmlinux EXPORT_SYMBOL
++0x8f4f1272    simple_setattr  vmlinux EXPORT_SYMBOL
++0x9c0dba49    simple_getattr  vmlinux EXPORT_SYMBOL
++0x2232a8a5    mempool_free    vmlinux EXPORT_SYMBOL
++0xc72ca946    v4l2_fh_release vmlinux EXPORT_SYMBOL_GPL
++0x2a0afd5e    videomode_from_timing   vmlinux EXPORT_SYMBOL_GPL
++0xaf157b0c    nfc_dep_link_is_up      vmlinux EXPORT_SYMBOL
++0x20efc937    tcf_em_tree_validate    vmlinux EXPORT_SYMBOL
++0xd05683cc    cred_to_ucred   vmlinux EXPORT_SYMBOL_GPL
++0xa1ac0050    sock_tx_timestamp       vmlinux EXPORT_SYMBOL
++0x48bd992d    bdget_disk      vmlinux EXPORT_SYMBOL
++0x50985501    configfs_register_subsystem     vmlinux EXPORT_SYMBOL
++0x041a8568    attribute_container_unregister  vmlinux EXPORT_SYMBOL_GPL
++0x3de4b634    driver_for_each_device  vmlinux EXPORT_SYMBOL_GPL
++0xc1984867    drm_vblank_put  vmlinux EXPORT_SYMBOL
++0xc8c20253    tcp_rcv_state_process   vmlinux EXPORT_SYMBOL
++0x280525ed    skb_to_sgvec    vmlinux EXPORT_SYMBOL_GPL
++0x20c55ae0    sscanf  vmlinux EXPORT_SYMBOL
++0xe3dd61a6    __breadahead    vmlinux EXPORT_SYMBOL
++0x1b42a36f    vb2_dma_contig_init_ctx vmlinux EXPORT_SYMBOL_GPL
++0xc326f752    v4l2_g_ctrl     vmlinux EXPORT_SYMBOL
++0x3adca4e5    pfifo_fast_ops  vmlinux EXPORT_SYMBOL
++0x67677183    snd_pcm_hw_constraint_integer   vmlinux EXPORT_SYMBOL
++0x1fab5905    wait_for_completion     vmlinux EXPORT_SYMBOL
++0x0b972255    led_classdev_suspend    vmlinux EXPORT_SYMBOL_GPL
++0xd617281d    wm8994_set_bits vmlinux EXPORT_SYMBOL_GPL
++0x4ad196c8    wm8994_reg_read vmlinux EXPORT_SYMBOL_GPL
++0xb3f0ca49    platform_device_register_full   vmlinux EXPORT_SYMBOL_GPL
++0x13bfa97e    devm_gpio_free  vmlinux EXPORT_SYMBOL
++0xe5646321    dev_get_by_name_rcu     vmlinux EXPORT_SYMBOL
++0x8fed35b2    snd_soc_dpcm_can_be_free_stop   vmlinux EXPORT_SYMBOL_GPL
++0x30a4f4ca    bstr_printf     vmlinux EXPORT_SYMBOL_GPL
++0x72350130    ___ratelimit    vmlinux EXPORT_SYMBOL
++0x0e5d4fe1    i2c_smbus_write_byte_data       vmlinux EXPORT_SYMBOL
++0xe7d93ea1    usb_unlink_urb  vmlinux EXPORT_SYMBOL_GPL
++0xaf141636    __nf_nat_mangle_tcp_packet      vmlinux EXPORT_SYMBOL
++0x584e1dcb    wm_hubs_add_analogue_controls   vmlinux EXPORT_SYMBOL_GPL
++0x15e14e37    snd_dma_alloc_pages     vmlinux EXPORT_SYMBOL
++0x3a26ed11    sched_clock     vmlinux EXPORT_SYMBOL_GPL
++0x6f5d8c04    iio_device_unregister   vmlinux EXPORT_SYMBOL
++0x9e672ff6    scsi_kmap_atomic_sg     vmlinux EXPORT_SYMBOL
++0xe8d95e86    platform_device_add_data        vmlinux EXPORT_SYMBOL_GPL
++0x1fcece42    inet_twdr_twcal_tick    vmlinux EXPORT_SYMBOL_GPL
++0xd1f0ea5e    sk_unattached_filter_destroy    vmlinux EXPORT_SYMBOL_GPL
++0xdb647fcf    sock_create_lite        vmlinux EXPORT_SYMBOL
++0x82b125fb    mmc_hw_reset_check      vmlinux EXPORT_SYMBOL
++0x45db3821    drm_gem_create_mmap_offset      vmlinux EXPORT_SYMBOL
++0x4eca00d2    nfc_proto_register      vmlinux EXPORT_SYMBOL
++0x8b69cf06    d_obtain_alias  vmlinux EXPORT_SYMBOL
++0xc7462fc5    cpufreq_unregister_governor     vmlinux EXPORT_SYMBOL_GPL
++0xc7280d53    v4l2_g_ext_ctrls        vmlinux EXPORT_SYMBOL
++0xb3b58737    ip6_datagram_connect    vmlinux EXPORT_SYMBOL_GPL
++0x365bf841    ip4_datagram_connect    vmlinux EXPORT_SYMBOL
++0x4a8cb865    tcp_timewait_state_process      vmlinux EXPORT_SYMBOL
++0xa34e2838    nf_conntrack_helper_try_module_get      vmlinux EXPORT_SYMBOL_GPL
++0x26dcd9ac    security_inode_init_security    vmlinux EXPORT_SYMBOL
++0xd705b4c7    schedule_hrtimeout      vmlinux EXPORT_SYMBOL_GPL
++0x44643b93    __aeabi_lmul    vmlinux EXPORT_SYMBOL
++0x824efa53    nobh_writepage  vmlinux EXPORT_SYMBOL
++0x78eb3b6d    clear_page_dirty_for_io vmlinux EXPORT_SYMBOL
++0xad6bf99a    srcu_init_notifier_head vmlinux EXPORT_SYMBOL_GPL
++0x9a1fc4b4    jiffies_to_timeval      vmlinux EXPORT_SYMBOL
++0xf1823632    clk_disable     vmlinux EXPORT_SYMBOL_GPL
++0x69da85e3    v4l2_ctrl_poll  vmlinux EXPORT_SYMBOL
++0xdcd7d2a3    starget_for_each_device vmlinux EXPORT_SYMBOL
++0x4dd58b53    subsys_interface_register       vmlinux EXPORT_SYMBOL_GPL
++0xf3916987    global_cursor_default   vmlinux EXPORT_SYMBOL
++0x3d2b2b9f    tcp_reno_min_cwnd       vmlinux EXPORT_SYMBOL_GPL
++0xf3bd26cd    vfs_follow_link vmlinux EXPORT_SYMBOL
++0xc11bd00f    tracepoint_probe_unregister     vmlinux EXPORT_SYMBOL_GPL
++0xb5532b8b    spi_bitbang_stop        vmlinux EXPORT_SYMBOL_GPL
++0x4deb10c3    tty_schedule_flip       vmlinux EXPORT_SYMBOL
++0x2dc227f8    brcmu_d11_attach        drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0xc009330d    sysfs_rename_link       vmlinux EXPORT_SYMBOL_GPL
++0xce0b9b59    max77693_read_reg       vmlinux EXPORT_SYMBOL_GPL
++0xc0c44856    tty_devnum      vmlinux EXPORT_SYMBOL
++0x4f391d0e    nla_parse       vmlinux EXPORT_SYMBOL
++0xc39a1e2a    write_dirty_buffer      vmlinux EXPORT_SYMBOL
++0xc8a154f9    noop_llseek     vmlinux EXPORT_SYMBOL
++0xc65d3eed    ring_buffer_entries_cpu vmlinux EXPORT_SYMBOL_GPL
++0x16807034    iommu_group_for_each_dev        vmlinux EXPORT_SYMBOL_GPL
++0x76829e1b    nfc_proto_unregister    vmlinux EXPORT_SYMBOL
++0x21ac8b77    iommu_group_get_by_id   vmlinux EXPORT_SYMBOL_GPL
++0x60601d69    input_free_device       vmlinux EXPORT_SYMBOL
++0x3a03067b    regulator_notifier_call_chain   vmlinux EXPORT_SYMBOL_GPL
++0x3e9110fa    __hw_addr_unsync        vmlinux EXPORT_SYMBOL
++0x7d11c268    jiffies vmlinux EXPORT_SYMBOL
++0x3987712e    iio_read_channel_scale  vmlinux EXPORT_SYMBOL_GPL
++0x7deff673    dm_consume_args vmlinux EXPORT_SYMBOL
++0xc092d57b    i2c_verify_adapter      vmlinux EXPORT_SYMBOL
++0x2e7a4300    drm_rgb_quant_range_selectable  vmlinux EXPORT_SYMBOL
++0x594e1317    __modsi3        vmlinux EXPORT_SYMBOL
++0x211331fa    __divsi3        vmlinux EXPORT_SYMBOL
++0xa3482467    dev_queue_xmit  vmlinux EXPORT_SYMBOL
++0x13d0adf7    __kfifo_out     vmlinux EXPORT_SYMBOL
++0xe06141e9    security_sk_clone       vmlinux EXPORT_SYMBOL
++0x75d5b827    proc_mkdir      vmlinux EXPORT_SYMBOL
++0x6f6ac78c    dummy_irq_chip  vmlinux EXPORT_SYMBOL_GPL
++0x3efb35c9    get_online_cpus vmlinux EXPORT_SYMBOL_GPL
++0x5907773b    of_device_alloc vmlinux EXPORT_SYMBOL
++0x1c00411e    blk_rq_map_sg   vmlinux EXPORT_SYMBOL
++0x09cf1b46    proc_dointvec_jiffies   vmlinux EXPORT_SYMBOL
++0x5db2254a    devm_usb_get_phy_by_phandle     vmlinux EXPORT_SYMBOL_GPL
++0x85caf365    usb_hcd_start_port_resume       vmlinux EXPORT_SYMBOL_GPL
++0x0a469d23    mfd_clone_cell  vmlinux EXPORT_SYMBOL
++0x93e85c29    dmam_free_noncoherent   vmlinux EXPORT_SYMBOL
++0x241ab4c2    phy_destroy     vmlinux EXPORT_SYMBOL_GPL
++0x408b2c52    __napi_schedule vmlinux EXPORT_SYMBOL
++0xc911f7d5    dev_change_carrier      vmlinux EXPORT_SYMBOL
++0xbfaa31e1    sk_stream_wait_memory   vmlinux EXPORT_SYMBOL
++0x0d3cb182    kstrtos16_from_user     vmlinux EXPORT_SYMBOL
++0x9f2bdaac    __bitmap_or     vmlinux EXPORT_SYMBOL
++0xae729e59    security_req_classify_flow      vmlinux EXPORT_SYMBOL
++0x273cbba4    get_dcookie     vmlinux EXPORT_SYMBOL_GPL
++0x9b7510d1    trace_event_raw_init    vmlinux EXPORT_SYMBOL_GPL
++0xb24585bc    usb_set_interface       vmlinux EXPORT_SYMBOL_GPL
++0x08cbe96c    tty_unlock      vmlinux EXPORT_SYMBOL
++0x07e3f668    netlink_broadcast_filtered      vmlinux EXPORT_SYMBOL
++0x4761f17c    register_netevent_notifier      vmlinux EXPORT_SYMBOL_GPL
++0xc7ec6c27    strspn  vmlinux EXPORT_SYMBOL
++0x97255bdf    strlen  vmlinux EXPORT_SYMBOL
++0xcdb399d4    cgroup_rightmost_descendant     vmlinux EXPORT_SYMBOL_GPL
++0x4bc7787e    iio_trigger_register    vmlinux EXPORT_SYMBOL
++0x05d7e32a    pm_generic_runtime_idle vmlinux EXPORT_SYMBOL_GPL
++0xcb0b5e8e    of_display_timings_exist        vmlinux EXPORT_SYMBOL_GPL
++0xdb68bbad    rfkill_destroy  vmlinux EXPORT_SYMBOL
++0x2e6a04e3    hci_recv_frame  vmlinux EXPORT_SYMBOL
++0xedbaee5e    nla_strcmp      vmlinux EXPORT_SYMBOL
++0x26bb950b    __kfifo_from_user_r     vmlinux EXPORT_SYMBOL
++0xca2ff6df    crypto_ahash_type       vmlinux EXPORT_SYMBOL_GPL
++0x2c41c751    v4l2_m2m_ctx_release    vmlinux EXPORT_SYMBOL_GPL
++0x99213409    scsi_allocate_command   vmlinux EXPORT_SYMBOL
++0x6827603e    skb_trim        vmlinux EXPORT_SYMBOL
++0x5cca80cf    perf_tp_event   vmlinux EXPORT_SYMBOL_GPL
++0xa6961e25    vb2_common_vm_ops       vmlinux EXPORT_SYMBOL_GPL
++0x72856c9e    v4l2_m2m_ioctl_expbuf   vmlinux EXPORT_SYMBOL_GPL
++0xb8acff80    usb_enable_autosuspend  vmlinux EXPORT_SYMBOL_GPL
++0x403f9529    gpio_request_one        vmlinux EXPORT_SYMBOL_GPL
++0x06d549e6    pinctrl_free_gpio       vmlinux EXPORT_SYMBOL_GPL
++0x02ae8433    xfrm_policy_delete      vmlinux EXPORT_SYMBOL
++0x6e71c6be    inet_frags_init vmlinux EXPORT_SYMBOL
++0x4e3567f7    match_int       vmlinux EXPORT_SYMBOL
++0x054434d6    radix_tree_tag_set      vmlinux EXPORT_SYMBOL
++0x31f956eb    blk_queue_lld_busy      vmlinux EXPORT_SYMBOL_GPL
++0x26565c84    shash_free_instance     vmlinux EXPORT_SYMBOL_GPL
++0x38668bab    debugfs_create_x64      vmlinux EXPORT_SYMBOL_GPL
++0xbf1f9a9b    bdi_setup_and_register  vmlinux EXPORT_SYMBOL
++0xfc64abed    power_supply_changed    vmlinux EXPORT_SYMBOL_GPL
++0x19326753    rtc_irq_register        vmlinux EXPORT_SYMBOL_GPL
++0xaf3cc095    nfc_hci_free_device     vmlinux EXPORT_SYMBOL
++0x86f38980    skb_cow_data    vmlinux EXPORT_SYMBOL_GPL
++0xe0c0d2af    snd_pcm_kernel_ioctl    vmlinux EXPORT_SYMBOL
++0xdfb01a80    cpu_v7_dcache_clean_area        vmlinux EXPORT_SYMBOL
++0x1879fcbd    bridge_tunnel_header    vmlinux EXPORT_SYMBOL
++0x9a011a6b    l2cap_conn_put  vmlinux EXPORT_SYMBOL
++0x6b3ee85a    ip4_datagram_release_cb vmlinux EXPORT_SYMBOL_GPL
++0xdd07d415    snd_card_free_when_closed       vmlinux EXPORT_SYMBOL
++0x868acba5    get_options     vmlinux EXPORT_SYMBOL
++0xa2409544    setup_irq       vmlinux EXPORT_SYMBOL_GPL
++0x567b73f9    i2c_get_adapter vmlinux EXPORT_SYMBOL
++0x7a4e7297    drm_edid_block_valid    vmlinux EXPORT_SYMBOL
++0x2ec524ad    __kfifo_in_r    vmlinux EXPORT_SYMBOL
++0x66f9da32    bh_uptodate_or_lock     vmlinux EXPORT_SYMBOL
++0xf9ffcd69    input_unregister_handler        vmlinux EXPORT_SYMBOL
++0x51dce73b    xfrm_state_walk_init    vmlinux EXPORT_SYMBOL
++0x113554e9    __skb_dst_set_noref     vmlinux EXPORT_SYMBOL
++0x3c9d1211    string_get_size vmlinux EXPORT_SYMBOL
++0xe654362e    fat_fill_super  vmlinux EXPORT_SYMBOL_GPL
++0xea5a46e7    register_exec_domain    vmlinux EXPORT_SYMBOL
++0xaf473214    iio_channel_get_all     vmlinux EXPORT_SYMBOL_GPL
++0xf8a9d6b2    rtc_read_alarm  vmlinux EXPORT_SYMBOL_GPL
++0xa0c8e0ed    usbnet_set_settings     vmlinux EXPORT_SYMBOL_GPL
++0x170bb6a9    usbnet_get_settings     vmlinux EXPORT_SYMBOL_GPL
++0xe0701fe6    fl6_sock_lookup vmlinux EXPORT_SYMBOL_GPL
++0x9330cb9f    sg_alloc_table  vmlinux EXPORT_SYMBOL
++0x5873f4c0    handle_simple_irq       vmlinux EXPORT_SYMBOL_GPL
++0xf27977e2    async_synchronize_cookie_domain vmlinux EXPORT_SYMBOL_GPL
++0xcf732e49    call_usermodehelper_exec        vmlinux EXPORT_SYMBOL
++0xd789a39d    cpufreq_governor_dbs    vmlinux EXPORT_SYMBOL_GPL
++0x4ff0c84f    of_mdio_find_bus        vmlinux EXPORT_SYMBOL
++0xe7a664c4    nf_hooks        vmlinux EXPORT_SYMBOL
++0xd366806d    snd_info_free_entry     vmlinux EXPORT_SYMBOL
++0xbcac6160    pm_qos_remove_notifier  vmlinux EXPORT_SYMBOL_GPL
++0x698d1e98    v4l2_ctrl_handler_init_class    vmlinux EXPORT_SYMBOL
++0x79c0d5a3    drm_gem_prime_fd_to_handle      vmlinux EXPORT_SYMBOL
++0xff1e9dd8    seq_list_start  vmlinux EXPORT_SYMBOL
++0x01accd73    __clk_get_name  vmlinux EXPORT_SYMBOL_GPL
++0x3e92b3d3    power_supply_unregister vmlinux EXPORT_SYMBOL_GPL
++0x71590103    drm_release     vmlinux EXPORT_SYMBOL
++0x0b9e5852    xfrm_aead_get_byname    vmlinux EXPORT_SYMBOL_GPL
++0xb7b856bf    km_state_notify vmlinux EXPORT_SYMBOL
++0x3f5b1415    nf_ct_port_nlattr_to_tuple      vmlinux EXPORT_SYMBOL_GPL
++0x98b6628a    snd_pcm_set_ops vmlinux EXPORT_SYMBOL
++0x1ea06663    _raw_write_lock vmlinux EXPORT_SYMBOL
++0x44dd3d8d    completion_done vmlinux EXPORT_SYMBOL
++0xa1eabd87    drm_mode_list_concat    vmlinux EXPORT_SYMBOL
++0x581ed292    drm_mm_get_block_generic        vmlinux EXPORT_SYMBOL
++0xefa98e30    dma_run_dependencies    vmlinux EXPORT_SYMBOL_GPL
++0xe8bea3bc    qdisc_put_stab  vmlinux EXPORT_SYMBOL
++0x2247cba2    seq_printf      vmlinux EXPORT_SYMBOL
++0x7e646f56    media_entity_remove_links       vmlinux EXPORT_SYMBOL_GPL
++0xa0e05fb1    drm_connector_cleanup   vmlinux EXPORT_SYMBOL
++0xb1cf44df    fb_find_best_mode       vmlinux EXPORT_SYMBOL
++0x0b742fd7    simple_strtol   vmlinux EXPORT_SYMBOL
++0xd709e32c    ilookup5_nowait vmlinux EXPORT_SYMBOL
++0x25865b31    mmc_free_host   vmlinux EXPORT_SYMBOL
++0x054063e9    devres_release  vmlinux EXPORT_SYMBOL_GPL
++0xc9b2045b    drm_mode_validate_size  vmlinux EXPORT_SYMBOL
++0xac6855b0    gen_kill_estimator      vmlinux EXPORT_SYMBOL
++0xc32b07a0    blk_queue_alignment_offset      vmlinux EXPORT_SYMBOL
++0x630c9194    fuse_dev_operations     vmlinux EXPORT_SYMBOL_GPL
++0xa4824580    devm_add_action vmlinux EXPORT_SYMBOL_GPL
++0xd8fe5b35    drm_mm_init     vmlinux EXPORT_SYMBOL
++0x9b9b05b4    __bio_clone     vmlinux EXPORT_SYMBOL
++0x5fda0227    vfs_stat        vmlinux EXPORT_SYMBOL
++0xa0fbac79    wake_up_bit     vmlinux EXPORT_SYMBOL
++0x796fc5ce    scsi_get_sense_info_fld vmlinux EXPORT_SYMBOL
++0x699ffdcd    nf_conntrack_flush_report       vmlinux EXPORT_SYMBOL_GPL
++0x89e6edac    snd_pcm_lib_malloc_pages        vmlinux EXPORT_SYMBOL
++0x48034724    zlib_deflateReset       vmlinux EXPORT_SYMBOL
++0xcdca3691    nr_irqs vmlinux EXPORT_SYMBOL_GPL
++0xcff6b676    _raw_spin_trylock_bh    vmlinux EXPORT_SYMBOL
++0xca45efbc    drm_format_horz_chroma_subsampling      vmlinux EXPORT_SYMBOL
++0xb6f4cc92    tty_do_resize   vmlinux EXPORT_SYMBOL
++0x51e77c97    pfn_valid       vmlinux EXPORT_SYMBOL
++0xa2446605    jbd2_journal_set_triggers       vmlinux EXPORT_SYMBOL
++0xebbb44c8    f_setown        vmlinux EXPORT_SYMBOL
++0xdfef3371    v4l2_m2m_ioctl_streamoff        vmlinux EXPORT_SYMBOL_GPL
++0x56c8799d    scsi_kunmap_atomic_sg   vmlinux EXPORT_SYMBOL
++0xaae1593e    scsi_block_when_processing_errors       vmlinux EXPORT_SYMBOL
++0xe330bf1f    ip6_dst_hoplimit        vmlinux EXPORT_SYMBOL
++0xf8996ee4    arp_invalidate  vmlinux EXPORT_SYMBOL
++0x6d27ef64    __bitmap_empty  vmlinux EXPORT_SYMBOL
++0xbfa789ca    elv_unregister  vmlinux EXPORT_SYMBOL_GPL
++0x06ae2b19    mmc_can_sanitize        vmlinux EXPORT_SYMBOL
++0xdd3dc2ce    usb_clear_halt  vmlinux EXPORT_SYMBOL_GPL
++0xfe0b2aae    amba_device_unregister  vmlinux EXPORT_SYMBOL
++0xc3771b21    of_pwm_get      vmlinux EXPORT_SYMBOL_GPL
++0x21b7d56d    dev_mc_sync_multiple    vmlinux EXPORT_SYMBOL
++0x1dfc5292    dev_uc_sync_multiple    vmlinux EXPORT_SYMBOL
++0xde7da8e3    submit_bh       vmlinux EXPORT_SYMBOL
++0xc15d05d9    mnt_clone_write vmlinux EXPORT_SYMBOL_GPL
++0x25fa84a3    page_mkclean    vmlinux EXPORT_SYMBOL_GPL
++0x405c1144    get_seconds     vmlinux EXPORT_SYMBOL
++0xf0f1246c    kvasprintf      vmlinux EXPORT_SYMBOL
++0xa5526619    rb_insert_color vmlinux EXPORT_SYMBOL
++0x7bb12a75    v4l2_m2m_get_vq vmlinux EXPORT_SYMBOL
++0x5819c8aa    usb_anchor_empty        vmlinux EXPORT_SYMBOL_GPL
++0x4e3d273c    __xfrm_init_state       vmlinux EXPORT_SYMBOL
++0xa2a69edc    __module_text_address   vmlinux EXPORT_SYMBOL_GPL
++0x66d87d38    symbol_put_addr vmlinux EXPORT_SYMBOL_GPL
++0xe45cc839    hrtimer_start_range_ns  vmlinux EXPORT_SYMBOL_GPL
++0xd3e6f60d    cpu_possible_mask       vmlinux EXPORT_SYMBOL
++0x52451ffe    hid_dump_field  vmlinux EXPORT_SYMBOL_GPL
++0xbd5a9986    drm_helper_probe_single_connector_modes vmlinux EXPORT_SYMBOL
++0xb694ce34    tcf_hash_search vmlinux EXPORT_SYMBOL
++0xaaefb815    d_alloc vmlinux EXPORT_SYMBOL
++0xaca38c86    unuse_mm        vmlinux EXPORT_SYMBOL_GPL
++0x5de3d7af    __alloc_pages_nodemask  vmlinux EXPORT_SYMBOL
++0xe2142ad8    i2c_smbus_read_word_data        vmlinux EXPORT_SYMBOL
++0xbfe4cfe6    tty_buffer_request_room vmlinux EXPORT_SYMBOL_GPL
++0xa6089679    elv_abort_queue vmlinux EXPORT_SYMBOL
++0x918ad429    ring_buffer_lock_reserve        vmlinux EXPORT_SYMBOL_GPL
++0xdc461430    irq_set_affinity_hint   vmlinux EXPORT_SYMBOL_GPL
++0x37258879    iio_channel_release     vmlinux EXPORT_SYMBOL_GPL
++0x1a082d69    max77693_update_reg     vmlinux EXPORT_SYMBOL_GPL
++0x4b0bd573    wiphy_unregister        vmlinux EXPORT_SYMBOL
++0x575d8c47    inet_sk_rx_dst_set      vmlinux EXPORT_SYMBOL
++0x3c6f5a97    snd_soc_register_component      vmlinux EXPORT_SYMBOL_GPL
++0xb9e03943    blk_execute_rq_nowait   vmlinux EXPORT_SYMBOL_GPL
++0x15f571ec    blk_set_stacking_limits vmlinux EXPORT_SYMBOL
++0x721585fd    security_inode_mkdir    vmlinux EXPORT_SYMBOL_GPL
++0xbf16ef9a    clk_get_rate    vmlinux EXPORT_SYMBOL_GPL
++0x22b79dae    clk_set_rate    vmlinux EXPORT_SYMBOL_GPL
++0x0dbd0e20    of_property_read_u8_array       vmlinux EXPORT_SYMBOL_GPL
++0xe6fce6f2    v4l2_ctrl_merge vmlinux EXPORT_SYMBOL
++0x12f1d8d3    dev_err vmlinux EXPORT_SYMBOL
++0x1c3e0368    drm_gem_object_handle_free      vmlinux EXPORT_SYMBOL
++0xfda9ed46    udp_proc_register       vmlinux EXPORT_SYMBOL
++0xccf2974f    kernel_sendpage vmlinux EXPORT_SYMBOL
++0x4b77922a    delete_from_page_cache  vmlinux EXPORT_SYMBOL
++0x3f5b67d5    wait_for_completion_killable    vmlinux EXPORT_SYMBOL
++0xa62fb61a    usb_gstrings_attach     vmlinux EXPORT_SYMBOL_GPL
++0x5cabdced    dev_pm_qos_remove_global_notifier       vmlinux EXPORT_SYMBOL_GPL
++0x27b864a9    s5p_gpio_get_drvstr     vmlinux EXPORT_SYMBOL
++0xc828d2a3    s5p_gpio_set_drvstr     vmlinux EXPORT_SYMBOL
++0xd9cf81bd    cfg80211_send_assoc_timeout     vmlinux EXPORT_SYMBOL
++0x693c3961    nf_ct_helper_hash       vmlinux EXPORT_SYMBOL_GPL
++0x487ef8ba    snd_soc_dai_set_sysclk  vmlinux EXPORT_SYMBOL_GPL
++0x50c89f23    __alloc_percpu  vmlinux EXPORT_SYMBOL_GPL
++0x09469482    kfree_call_rcu  vmlinux EXPORT_SYMBOL_GPL
++0x177d5d5e    uart_insert_char        vmlinux EXPORT_SYMBOL_GPL
++0xb17c2f9b    clear_inode     vmlinux EXPORT_SYMBOL
++0x3b733a7c    led_trigger_unregister  vmlinux EXPORT_SYMBOL_GPL
++0x16000a3c    dm_device_name  vmlinux EXPORT_SYMBOL_GPL
++0x0465ca31    scsi_cmd_get_serial     vmlinux EXPORT_SYMBOL
++0x0f52944d    drm_helper_hpd_irq_event        vmlinux EXPORT_SYMBOL
++0x99517682    udp_encap_enable        vmlinux EXPORT_SYMBOL
++0x1e43dec1    neigh_parms_release     vmlinux EXPORT_SYMBOL
++0x572e85d4    blk_lookup_devt vmlinux EXPORT_SYMBOL
++0xf7bb06b2    crypto_grab_skcipher    vmlinux EXPORT_SYMBOL_GPL
++0xe953b21f    get_next_ino    vmlinux EXPORT_SYMBOL
++0xdb225b82    pm_vt_switch_required   vmlinux EXPORT_SYMBOL
++0xe1a4b69f    mmc_card_awake  vmlinux EXPORT_SYMBOL
++0x33234a30    usb_hcd_link_urb_to_ep  vmlinux EXPORT_SYMBOL_GPL
++0xb61a0dba    dmam_release_declared_memory    vmlinux EXPORT_SYMBOL
++0x6865b5f6    device_release_driver   vmlinux EXPORT_SYMBOL_GPL
++0x920accbd    ump_dd_secure_id_get    vmlinux EXPORT_SYMBOL
++0xffb94ef0    _test_and_change_bit    vmlinux EXPORT_SYMBOL
++0xb7a1ff6d    tcp_prequeue    vmlinux EXPORT_SYMBOL
++0xce3ca308    copy_from_user_toio     vmlinux EXPORT_SYMBOL
++0xd08137e8    vfs_setlease    vmlinux EXPORT_SYMBOL_GPL
++0x89eabc8c    from_kgid_munged        vmlinux EXPORT_SYMBOL
++0x40d04664    console_trylock vmlinux EXPORT_SYMBOL
++0x0955d1f2    iommu_attach_device     vmlinux EXPORT_SYMBOL_GPL
++0x9cf3e94a    dm_kcopyd_copy  vmlinux EXPORT_SYMBOL
++0x1cec399d    v4l2_m2m_ioctl_create_bufs      vmlinux EXPORT_SYMBOL_GPL
++0x8cae11ac    usb_alloc_streams       vmlinux EXPORT_SYMBOL_GPL
++0xd3299096    scsi_register_interface vmlinux EXPORT_SYMBOL
++0x885369a2    dma_common_get_sgtable  vmlinux EXPORT_SYMBOL
++0x2251d13d    blk_queue_dma_pad       vmlinux EXPORT_SYMBOL
++0x07cf9099    wait_for_completion_timeout     vmlinux EXPORT_SYMBOL
++0x0efcbb1b    set_current_groups      vmlinux EXPORT_SYMBOL
++0xea9b0ab7    v4l2_ctrl_add_handler   vmlinux EXPORT_SYMBOL
++0x79aaab2b    i2c_smbus_read_block_data       vmlinux EXPORT_SYMBOL
++0x964ff64a    usb_put_intf    vmlinux EXPORT_SYMBOL_GPL
++0x9f97bf25    xfrm6_input_addr        vmlinux EXPORT_SYMBOL
++0x81db6ebb    xz_dec_reset    vmlinux EXPORT_SYMBOL
++0x661601de    sprint_symbol   vmlinux EXPORT_SYMBOL_GPL
++0x1e59773c    st_gyro_common_remove   vmlinux EXPORT_SYMBOL
++0x921e453c    drm_get_platform_dev    vmlinux EXPORT_SYMBOL
++0x720b245e    update_region   vmlinux EXPORT_SYMBOL
++0x2bda5922    hci_get_route   vmlinux EXPORT_SYMBOL
++0xaa939a8b    tcf_em_unregister       vmlinux EXPORT_SYMBOL
++0x590cf866    scm_fp_dup      vmlinux EXPORT_SYMBOL
++0x2ce98559    kcrypto_wq      vmlinux EXPORT_SYMBOL_GPL
++0x5351af17    shrink_dcache_parent    vmlinux EXPORT_SYMBOL
++0x1ad83009    trace_seq_vprintf       vmlinux EXPORT_SYMBOL_GPL
++0x8fcafa61    led_stop_software_blink vmlinux EXPORT_SYMBOL_GPL
++0xd4a7943a    mmc_card_can_sleep      vmlinux EXPORT_SYMBOL
++0x52f378a8    devres_remove   vmlinux EXPORT_SYMBOL_GPL
++0x6288b8b9    serial8250_release_dma  vmlinux EXPORT_SYMBOL_GPL
++0x63556dea    tty_vhangup     vmlinux EXPORT_SYMBOL
++0x75c8a11c    inet_twdr_twkill_work   vmlinux EXPORT_SYMBOL_GPL
++0x609f1c7e    synchronize_net vmlinux EXPORT_SYMBOL
++0x6091797f    synchronize_rcu vmlinux EXPORT_SYMBOL_GPL
++0x42825ce2    rcu_scheduler_active    vmlinux EXPORT_SYMBOL_GPL
++0xe523ad75    synchronize_irq vmlinux EXPORT_SYMBOL
++0xb77b0159    v4l2_prio_init  vmlinux EXPORT_SYMBOL
++0x840dd143    rndis_deregister        vmlinux EXPORT_SYMBOL
++0x7464ea38    dev_pm_qos_add_global_notifier  vmlinux EXPORT_SYMBOL_GPL
++0xd325a885    bus_for_each_dev        vmlinux EXPORT_SYMBOL_GPL
++0x3ec3d061    bus_for_each_drv        vmlinux EXPORT_SYMBOL_GPL
++0xb2823478    pneigh_lookup   vmlinux EXPORT_SYMBOL
++0x7037aaf0    kern_path_create        vmlinux EXPORT_SYMBOL
++0x85061b76    _raw_write_lock_bh      vmlinux EXPORT_SYMBOL
++0xb90cbedf    v4l2_of_get_next_endpoint       vmlinux EXPORT_SYMBOL
++0x9d2ed0a8    snd_timer_close vmlinux EXPORT_SYMBOL
++0x1057d320    blk_queue_find_tag      vmlinux EXPORT_SYMBOL
++0x1e3a88fb    trace_seq_printf        vmlinux EXPORT_SYMBOL_GPL
++0x4bc62a81    audit_enabled   vmlinux EXPORT_SYMBOL_GPL
++0x39461d6a    in_egroup_p     vmlinux EXPORT_SYMBOL
++0xccefabad    drm_mode_create_scaling_mode_property   vmlinux EXPORT_SYMBOL
++0x43384bd9    drm_buffer_alloc        vmlinux EXPORT_SYMBOL
++0x184e6c85    radix_tree_gang_lookup_slot     vmlinux EXPORT_SYMBOL
++0xdf347b52    sec_reg_read    vmlinux EXPORT_SYMBOL_GPL
++0x409873e3    tty_termios_baud_rate   vmlinux EXPORT_SYMBOL
++0x07a890c8    fb_alloc_cmap   vmlinux EXPORT_SYMBOL
++0x7d04aaa6    nf_conntrack_broadcast_help     vmlinux EXPORT_SYMBOL_GPL
++0x5cdc7a62    skb_append_datato_frags vmlinux EXPORT_SYMBOL
++0x9e0c711d    vzalloc_node    vmlinux EXPORT_SYMBOL
++0x7f24de73    jiffies_to_usecs        vmlinux EXPORT_SYMBOL
++0x37befc70    jiffies_to_msecs        vmlinux EXPORT_SYMBOL
++0xe9807d5b    input_mt_sync_frame     vmlinux EXPORT_SYMBOL
++0x0c0c8520    release_firmware        vmlinux EXPORT_SYMBOL
++0x442aa46d    tcp_child_process       vmlinux EXPORT_SYMBOL
++0x67663177    sock_diag_put_filterinfo        vmlinux EXPORT_SYMBOL
++0xa250c838    param_get_charp vmlinux EXPORT_SYMBOL
++0xf0b613ad    __pm_runtime_suspend    vmlinux EXPORT_SYMBOL_GPL
++0x1a770ac3    drm_detect_hdmi_monitor vmlinux EXPORT_SYMBOL
++0x70d7e40d    prepare_binprm  vmlinux EXPORT_SYMBOL
++0x36d7b11a    of_find_matching_node_and_match vmlinux EXPORT_SYMBOL
++0x8e30ad82    mdiobus_write   vmlinux EXPORT_SYMBOL
++0xeb6173b8    tty_port_destroy        vmlinux EXPORT_SYMBOL
++0x6c0154da    tcp_v4_destroy_sock     vmlinux EXPORT_SYMBOL
++0x5afe3100    snd_soc_add_dai_controls        vmlinux EXPORT_SYMBOL_GPL
++0xdf2c2742    rb_last vmlinux EXPORT_SYMBOL
++0x7ab3ca18    eventfd_ctx_read        vmlinux EXPORT_SYMBOL_GPL
++0xeb32e3af    mount_bdev      vmlinux EXPORT_SYMBOL
++0xe6fbe430    can_do_mlock    vmlinux EXPORT_SYMBOL
++0x60a13e90    rcu_barrier     vmlinux EXPORT_SYMBOL_GPL
++0xdf60cc27    __print_symbol  vmlinux EXPORT_SYMBOL
++0xa2a2031e    ehci_setup      vmlinux EXPORT_SYMBOL_GPL
++0x686f8200    ndisc_mc_map    vmlinux EXPORT_SYMBOL
++0xab8647cf    nf_ct_helper_expectfn_find_by_symbol    vmlinux EXPORT_SYMBOL_GPL
++0x91715312    sprintf vmlinux EXPORT_SYMBOL
++0xda3d10a8    security_tun_dev_open   vmlinux EXPORT_SYMBOL
++0xa4a91e54    simple_unlink   vmlinux EXPORT_SYMBOL
++0xf377a0b5    simple_attr_write       vmlinux EXPORT_SYMBOL_GPL
++0x97263968    generic_listxattr       vmlinux EXPORT_SYMBOL
++0x53c9394f    v4l2_ctrl_query_menu    vmlinux EXPORT_SYMBOL
++0xf6ebc03b    net_ratelimit   vmlinux EXPORT_SYMBOL
++0x3977cbea    dev_addr_init   vmlinux EXPORT_SYMBOL
++0x2789cd4f    snd_soc_put_strobe      vmlinux EXPORT_SYMBOL_GPL
++0x719074ee    snd_soc_get_strobe      vmlinux EXPORT_SYMBOL_GPL
++0xdace599d    shash_ahash_update      vmlinux EXPORT_SYMBOL_GPL
++0x7add44b5    posix_acl_valid vmlinux EXPORT_SYMBOL
++0xe8fbe1c9    invalidate_inode_buffers        vmlinux EXPORT_SYMBOL
++0x5442b464    media_device_register_entity    vmlinux EXPORT_SYMBOL_GPL
++0xa279bad0    usb_add_config  vmlinux EXPORT_SYMBOL_GPL
++0x1d77b0f8    unix_socket_table       vmlinux EXPORT_SYMBOL_GPL
++0x7932f1fc    ip_tunnel_ioctl vmlinux EXPORT_SYMBOL_GPL
++0x153b7ac0    nl_table        vmlinux EXPORT_SYMBOL_GPL
++0xfdfcdc90    crypto_shash_update     vmlinux EXPORT_SYMBOL_GPL
++0xa376521b    find_vma        vmlinux EXPORT_SYMBOL
++0xe57f0426    vb2_dma_contig_cleanup_ctx      vmlinux EXPORT_SYMBOL_GPL
++0x0f53690e    usb_autopm_get_interface_async  vmlinux EXPORT_SYMBOL_GPL
++0xe97e3624    scsi_register   vmlinux EXPORT_SYMBOL
++0x07d4567b    max8997_write_reg       vmlinux EXPORT_SYMBOL_GPL
++0x24f2d831    regulator_register_notifier     vmlinux EXPORT_SYMBOL_GPL
++0x85ab9275    nf_ct_extend_unregister vmlinux EXPORT_SYMBOL_GPL
++0x7721fbd2    kernel_connect  vmlinux EXPORT_SYMBOL
++0x3095e489    single_open_size        vmlinux EXPORT_SYMBOL
++0x54ff695a    inet_stream_connect     vmlinux EXPORT_SYMBOL
++0xa05c03df    mempool_kmalloc vmlinux EXPORT_SYMBOL
++0xd6df7b3f    dma_buf_end_cpu_access  vmlinux EXPORT_SYMBOL_GPL
++0x2d5eac78    qdisc_warn_nonwc        vmlinux EXPORT_SYMBOL
++0x7bc477d0    splice_from_pipe_begin  vmlinux EXPORT_SYMBOL
++0xfd6293c2    boot_tvec_bases vmlinux EXPORT_SYMBOL
++0x6d662533    _find_first_bit_le      vmlinux EXPORT_SYMBOL
++0xd41f3207    netdev_class_remove_file        vmlinux EXPORT_SYMBOL
++0xdf48a0eb    flex_array_put  vmlinux EXPORT_SYMBOL
++0xcf048d93    blk_queue_physical_block_size   vmlinux EXPORT_SYMBOL
++0xd5790350    dio_end_io      vmlinux EXPORT_SYMBOL_GPL
++0xc0bf6ead    timecounter_cyc2time    vmlinux EXPORT_SYMBOL_GPL
++0x303087f1    v4l2_queryctrl  vmlinux EXPORT_SYMBOL
++0x506691f1    sock_diag_check_cookie  vmlinux EXPORT_SYMBOL_GPL
++0x307c2fd0    generic_check_addressable       vmlinux EXPORT_SYMBOL
++0x40b313d1    perf_event_read_value   vmlinux EXPORT_SYMBOL_GPL
++0x04482cdb    __refrigerator  vmlinux EXPORT_SYMBOL
++0x7cb1ae69    cpu_down        vmlinux EXPORT_SYMBOL
++0xc9aca11e    v4l2_ctrl_handler_log_status    vmlinux EXPORT_SYMBOL
++0xb7f77027    rtc_tm_to_ktime vmlinux EXPORT_SYMBOL_GPL
++0x70c8201b    tty_lock_pair   vmlinux EXPORT_SYMBOL
++0x1565add4    inet6_csk_addr2sockaddr vmlinux EXPORT_SYMBOL_GPL
++0x72a112d9    netdev_refcnt_read      vmlinux EXPORT_SYMBOL
++0xacc6730b    __blk_end_request       vmlinux EXPORT_SYMBOL
++0xbe54542c    input_mt_init_slots     vmlinux EXPORT_SYMBOL
++0xca3920b5    usb_disable_lpm vmlinux EXPORT_SYMBOL_GPL
++0x0cd967c3    usb_disable_ltm vmlinux EXPORT_SYMBOL_GPL
++0x3b66b0c1    __pm_wakeup_event       vmlinux EXPORT_SYMBOL_GPL
++0x0f480178    devres_close_group      vmlinux EXPORT_SYMBOL_GPL
++0xf0bd9740    drm_mode_parse_command_line_for_connector       vmlinux EXPORT_SYMBOL
++0x12c6276a    drm_buffer_read_object  vmlinux EXPORT_SYMBOL
++0xc3b93bba    klist_next      vmlinux EXPORT_SYMBOL_GPL
++0x3d342d92    tcp_rcv_established     vmlinux EXPORT_SYMBOL
++0x540c6f94    inet_getpeer    vmlinux EXPORT_SYMBOL_GPL
++0x153c8015    ipv4_update_pmtu        vmlinux EXPORT_SYMBOL_GPL
++0x0c4bfb03    xt_unregister_targets   vmlinux EXPORT_SYMBOL
++0x5cd7eb9b    wm_hubs_dcs_done        vmlinux EXPORT_SYMBOL_GPL
++0xd7e56a4e    simple_strtoll  vmlinux EXPORT_SYMBOL
++0x20000329    simple_strtoul  vmlinux EXPORT_SYMBOL
++0x9e784e44    balance_dirty_pages_ratelimited vmlinux EXPORT_SYMBOL
++0x11195d33    usb_enable_lpm  vmlinux EXPORT_SYMBOL_GPL
++0xd7f91a45    usb_enable_ltm  vmlinux EXPORT_SYMBOL_GPL
++0x39e2b6d2    spi_alloc_master        vmlinux EXPORT_SYMBOL_GPL
++0x82eb671b    scsi_prep_fn    vmlinux EXPORT_SYMBOL
++0x4473fccc    nf_register_afinfo      vmlinux EXPORT_SYMBOL_GPL
++0xd1e13a97    net_ns_type_operations  vmlinux EXPORT_SYMBOL_GPL
++0x1bf69c17    proc_symlink    vmlinux EXPORT_SYMBOL
++0x651c3828    usb_add_phy_dev vmlinux EXPORT_SYMBOL_GPL
++0xf571b062    drm_addmap      vmlinux EXPORT_SYMBOL
++0xb41150b4    pwm_enable      vmlinux EXPORT_SYMBOL_GPL
++0x8c52195f    __rtnl_link_unregister  vmlinux EXPORT_SYMBOL_GPL
++0xe2cb9278    snd_soc_dai_set_tdm_slot        vmlinux EXPORT_SYMBOL_GPL
++0x4de34a07    cpu_rmap_put    vmlinux EXPORT_SYMBOL
++0xb51797f0    blk_queue_dma_alignment vmlinux EXPORT_SYMBOL
++0xdab3304e    remap_vmalloc_range     vmlinux EXPORT_SYMBOL
++0x5113c626    noop_backing_dev_info   vmlinux EXPORT_SYMBOL_GPL
++0xd985dc99    mempool_free_pages      vmlinux EXPORT_SYMBOL
++0xfcec0987    enable_irq      vmlinux EXPORT_SYMBOL
++0x1e7bbcb3    kernel_restart  vmlinux EXPORT_SYMBOL_GPL
++0xa26c3f65    mmc_gpio_free_cd        vmlinux EXPORT_SYMBOL
++0x6461806d    max8997_bulk_write      vmlinux EXPORT_SYMBOL_GPL
++0x2ff9c227    filemap_page_mkwrite    vmlinux EXPORT_SYMBOL
++0xd2917bd3    v4l2_m2m_fop_poll       vmlinux EXPORT_SYMBOL_GPL
++0xc11159cc    drm_mode_create vmlinux EXPORT_SYMBOL
++0xdd27fa87    memchr  vmlinux EXPORT_SYMBOL
++0x10329729    inet6_release   vmlinux EXPORT_SYMBOL
++0xc18ac88d    nf_ct_expect_hsize      vmlinux EXPORT_SYMBOL_GPL
++0x005e9828    vfs_kern_mount  vmlinux EXPORT_SYMBOL_GPL
++0xd5bd7dac    ring_buffer_record_enable_cpu   vmlinux EXPORT_SYMBOL_GPL
++0x00cf4a7f    of_get_parent   vmlinux EXPORT_SYMBOL
++0xd6097597    v4l2_ctrl_new_int_menu  vmlinux EXPORT_SYMBOL
++0x3cdbf719    drm_mode_destroy        vmlinux EXPORT_SYMBOL
++0xb03e9a0f    nfc_set_remote_general_bytes    vmlinux EXPORT_SYMBOL
++0x2059c814    sock_diag_register      vmlinux EXPORT_SYMBOL_GPL
++0x315c65fd    zlib_deflateInit2       vmlinux EXPORT_SYMBOL
++0x1ab8c624    submit_bio      vmlinux EXPORT_SYMBOL
++0xd070d52e    alloc_page_buffers      vmlinux EXPORT_SYMBOL_GPL
++0x622c7922    register_oom_notifier   vmlinux EXPORT_SYMBOL_GPL
++0xe806f5a2    trace_event_buffer_lock_reserve vmlinux EXPORT_SYMBOL_GPL
++0xcfc68341    synchronize_rcu_bh      vmlinux EXPORT_SYMBOL_GPL
++0x549525ef    handle_nested_irq       vmlinux EXPORT_SYMBOL_GPL
++0x20421305    on_each_cpu_mask        vmlinux EXPORT_SYMBOL
++0xa1bb9fb1    spi_bus_type    vmlinux EXPORT_SYMBOL_GPL
++0x8a627eb3    anon_transport_class_unregister vmlinux EXPORT_SYMBOL_GPL
++0xd8525ea7    fl6_update_dst  vmlinux EXPORT_SYMBOL_GPL
++0xbac1a16b    tcp_valid_rtt_meas      vmlinux EXPORT_SYMBOL
++0xb67cd6f1    neigh_lookup    vmlinux EXPORT_SYMBOL
++0xc2c639ae    debugfs_create_u32_array        vmlinux EXPORT_SYMBOL_GPL
++0xd4a33b98    mmc_remove_host vmlinux EXPORT_SYMBOL
++0x1f65abdf    usb_put_hcd     vmlinux EXPORT_SYMBOL_GPL
++0x2ef63ad6    scsi_dev_info_list_del_keyed    vmlinux EXPORT_SYMBOL
++0x0bf18882    tcp_mtup_init   vmlinux EXPORT_SYMBOL
++0x0ea07ec7    kstrtou8_from_user      vmlinux EXPORT_SYMBOL
++0x973d0f9e    kstrtoul_from_user      vmlinux EXPORT_SYMBOL
++0x7c8db884    devm_clk_unregister     vmlinux EXPORT_SYMBOL_GPL
++0x46066e5b    perf_pmu_name   vmlinux EXPORT_SYMBOL_GPL
++0x951ac153    snd_soc_jack_report     vmlinux EXPORT_SYMBOL_GPL
++0x7c1464a6    snd_soc_dapm_get_enum_double    vmlinux EXPORT_SYMBOL_GPL
++0xd36af700    snd_soc_dapm_put_enum_double    vmlinux EXPORT_SYMBOL_GPL
++0x222e7ce2    sysfs_streq     vmlinux EXPORT_SYMBOL
++0xca72b2e9    alloc_buffer_head       vmlinux EXPORT_SYMBOL
++0x364d71cb    iio_scan_mask_set       vmlinux EXPORT_SYMBOL_GPL
++0x813f3de4    v4l2_find_nearest_format        vmlinux EXPORT_SYMBOL_GPL
++0xb37a0603    drm_dp_link_train_channel_eq_delay      vmlinux EXPORT_SYMBOL
++0x1fe912f1    netdev_alloc_frag       vmlinux EXPORT_SYMBOL
++0x7bdee655    usbnet_get_endpoints    vmlinux EXPORT_SYMBOL_GPL
++0x589e4569    syscon_regmap_lookup_by_pdevname        vmlinux EXPORT_SYMBOL_GPL
++0x60506751    unmap_kernel_range_noflush      vmlinux EXPORT_SYMBOL_GPL
++0x224b5740    device_remove_file      vmlinux EXPORT_SYMBOL_GPL
++0x1b8822d8    pinctrl_gpio_direction_output   vmlinux EXPORT_SYMBOL_GPL
++0x985e0b7d    ipv6_skip_exthdr        vmlinux EXPORT_SYMBOL
++0xa0e33feb    ip_options_compile      vmlinux EXPORT_SYMBOL
++0x289c3714    nf_ct_alloc_hashtable   vmlinux EXPORT_SYMBOL_GPL
++0xc33e401a    sock_diag_unregister    vmlinux EXPORT_SYMBOL_GPL
++0xba86c38e    aio_complete    vmlinux EXPORT_SYMBOL
++0x03bd889d    param_get_ulong vmlinux EXPORT_SYMBOL
++0xa4ca666e    kill_pid        vmlinux EXPORT_SYMBOL
++0xe56cb560    rt6_lookup      vmlinux EXPORT_SYMBOL
++0xc8fb75a8    unix_outq_len   vmlinux EXPORT_SYMBOL_GPL
++0xd5c5ff75    inet_frags_init_net     vmlinux EXPORT_SYMBOL
++0x64999478    congestion_wait vmlinux EXPORT_SYMBOL
++0x59eae699    ring_buffer_read_prepare        vmlinux EXPORT_SYMBOL_GPL
++0xa23061f8    mmc_read_bkops_status   vmlinux EXPORT_SYMBOL
++0xa1c46bd3    spi_bitbang_cleanup     vmlinux EXPORT_SYMBOL_GPL
++0x4d126acf    device_store_int        vmlinux EXPORT_SYMBOL_GPL
++0x5b546bbb    drm_gem_mmap    vmlinux EXPORT_SYMBOL
++0xd37d6496    hci_recv_fragment       vmlinux EXPORT_SYMBOL
++0x1c86d31e    ip_tunnel_delete_net    vmlinux EXPORT_SYMBOL_GPL
++0x9684e8c6    blk_queue_dma_drain     vmlinux EXPORT_SYMBOL_GPL
++0xf89e28e9    config_item_set_name    vmlinux EXPORT_SYMBOL
++0x9d8331c0    ring_buffer_read_page   vmlinux EXPORT_SYMBOL_GPL
++0x572d0104    _raw_write_unlock_irqrestore    vmlinux EXPORT_SYMBOL
++0x8e7894bd    __atomic_notifier_call_chain    vmlinux EXPORT_SYMBOL_GPL
++0xb202dbc6    i2c_del_driver  vmlinux EXPORT_SYMBOL
++0x057ce975    hex_dump_to_buffer      vmlinux EXPORT_SYMBOL
++0xe09f5fdd    file_ra_state_init      vmlinux EXPORT_SYMBOL_GPL
++0x011c93d4    v4l2_m2m_reqbufs        vmlinux EXPORT_SYMBOL_GPL
++0x5b185975    __dma_request_channel   vmlinux EXPORT_SYMBOL_GPL
++0xe02299ef    nfc_hci_send_response   vmlinux EXPORT_SYMBOL
++0xe8beb828    crypto_larval_kill      vmlinux EXPORT_SYMBOL_GPL
++0x8704eb06    irq_set_default_host    vmlinux EXPORT_SYMBOL_GPL
++0x7ac1d551    vb2_prepare_buf vmlinux EXPORT_SYMBOL_GPL
++0xfcab3072    media_entity_cleanup    vmlinux EXPORT_SYMBOL_GPL
++0x75d69d69    usb_alloc_coherent      vmlinux EXPORT_SYMBOL_GPL
++0x2f3857a0    xfrm_register_mode      vmlinux EXPORT_SYMBOL
++0x09c1fbfd    inet_csk_get_port       vmlinux EXPORT_SYMBOL_GPL
++0x1e6fd62f    kiocb_set_cancel_fn     vmlinux EXPORT_SYMBOL
++0xb20a8d04    mmc_flush_cache vmlinux EXPORT_SYMBOL
++0xb321b21c    i2c_clients_command     vmlinux EXPORT_SYMBOL
++0xd77c0bc8    klist_remove    vmlinux EXPORT_SYMBOL_GPL
++0x8cfe5489    dev_get_flags   vmlinux EXPORT_SYMBOL
++0x8022b19a    crypto_sha256_update    vmlinux EXPORT_SYMBOL
++0x0adfab73    __wait_on_bit_lock      vmlinux EXPORT_SYMBOL
++0x4a169d0b    usb_get_status  vmlinux EXPORT_SYMBOL_GPL
++0xe5122890    flow_cache_genid        vmlinux EXPORT_SYMBOL
++0x31cef011    gen_new_estimator       vmlinux EXPORT_SYMBOL
++0xbb6bebbd    crypto_alg_mod_lookup   vmlinux EXPORT_SYMBOL_GPL
++0xe208f5c9    freeze_super    vmlinux EXPORT_SYMBOL
++0xbf5b2016    __devm_request_region   vmlinux EXPORT_SYMBOL
++0x7cd6f042    cpufreq_get_current_driver      vmlinux EXPORT_SYMBOL_GPL
++0x946f789a    input_class     vmlinux EXPORT_SYMBOL_GPL
++0x33abb76e    usb_remove_function     vmlinux EXPORT_SYMBOL_GPL
++0x54c41f03    __cfg80211_send_disassoc        vmlinux EXPORT_SYMBOL
++0x886bcea3    hid_connect     vmlinux EXPORT_SYMBOL_GPL
++0x1d4cf31c    mmc_set_data_timeout    vmlinux EXPORT_SYMBOL
++0x020bb7c4    v4l2_m2m_qbuf   vmlinux EXPORT_SYMBOL_GPL
++0xf5ef842e    v4l_bound_align_image   vmlinux EXPORT_SYMBOL_GPL
++0x628c65bc    usb_set_device_state    vmlinux EXPORT_SYMBOL_GPL
++0x1d182b56    scsi_autopm_get_device  vmlinux EXPORT_SYMBOL_GPL
++0xa8b77259    scsi_autopm_put_device  vmlinux EXPORT_SYMBOL_GPL
++0x2641488c    scsi_eh_finish_cmd      vmlinux EXPORT_SYMBOL
++0x773650a0    vc_cons vmlinux EXPORT_SYMBOL
++0x6d203b02    dma_async_device_unregister     vmlinux EXPORT_SYMBOL
++0x18c2227f    cpu_rmap_update vmlinux EXPORT_SYMBOL
++0xdd0a2ba2    strlcat vmlinux EXPORT_SYMBOL
++0xd627480b    strncat vmlinux EXPORT_SYMBOL
++0x0dd47f83    blk_queue_max_discard_sectors   vmlinux EXPORT_SYMBOL
++0xb3f7646e    kthread_should_stop     vmlinux EXPORT_SYMBOL
++0x8d335f49    mmc_can_reset   vmlinux EXPORT_SYMBOL
++0x474576c2    v4l2_ctrl_new_std_menu  vmlinux EXPORT_SYMBOL
++0x735d80ef    drm_add_edid_modes      vmlinux EXPORT_SYMBOL
++0xbfdbe956    nfnetlink_set_err       vmlinux EXPORT_SYMBOL_GPL
++0xc0891ac5    netdev_notice   vmlinux EXPORT_SYMBOL
++0x03b5c8d0    blk_rq_map_kern vmlinux EXPORT_SYMBOL
++0x20f6c302    sync_mapping_buffers    vmlinux EXPORT_SYMBOL
++0x5610de90    pm_generic_freeze_noirq vmlinux EXPORT_SYMBOL_GPL
++0x33186585    drm_prime_lookup_buf_handle     vmlinux EXPORT_SYMBOL
++0x5c746654    bt_sock_register        vmlinux EXPORT_SYMBOL
++0x1f2ca4fa    fat_scan        vmlinux EXPORT_SYMBOL_GPL
++0x4ade2e74    inode_change_ok vmlinux EXPORT_SYMBOL
++0x2b2264c1    __scsi_add_device       vmlinux EXPORT_SYMBOL
++0x3a8903bb    datagram_poll   vmlinux EXPORT_SYMBOL
++0x75767b6f    snd_pcm_hw_constraint_minmax    vmlinux EXPORT_SYMBOL
++0xe623e6db    blk_queue_end_tag       vmlinux EXPORT_SYMBOL
++0x1e9edfb7    seq_hlist_start_head_rcu        vmlinux EXPORT_SYMBOL
++0x69d38ed9    __scsi_print_sense      vmlinux EXPORT_SYMBOL
++0xc6de7303    __tty_alloc_driver      vmlinux EXPORT_SYMBOL
++0xcdb5f930    __tcf_em_tree_match     vmlinux EXPORT_SYMBOL
++0x7a0a2470    dev_uc_flush    vmlinux EXPORT_SYMBOL
++0x6c8f0d30    dev_mc_flush    vmlinux EXPORT_SYMBOL
++0x067d8d35    security_release_secctx vmlinux EXPORT_SYMBOL
++0xb10e668e    jbd2_journal_check_available_features   vmlinux EXPORT_SYMBOL
++0xe2e8ac87    flush_old_exec  vmlinux EXPORT_SYMBOL
++0x00c4dc87    timecounter_init        vmlinux EXPORT_SYMBOL_GPL
++0xeb793d66    media_device_register   vmlinux EXPORT_SYMBOL_GPL
++0x694be42a    usb_show_dynids vmlinux EXPORT_SYMBOL_GPL
++0xdf3ec432    drm_gem_object_alloc    vmlinux EXPORT_SYMBOL
++0xa3d3ab7e    inet_addr_type  vmlinux EXPORT_SYMBOL
++0x97a2e370    inet_recvmsg    vmlinux EXPORT_SYMBOL
++0x0b59390b    __tracepoint_rpm_suspend        vmlinux EXPORT_SYMBOL_GPL
++0xa4701e9e    timekeeping_inject_offset       vmlinux EXPORT_SYMBOL
++0x1f54f1b4    do_trace_rcu_torture_read       vmlinux EXPORT_SYMBOL_GPL
++0x6275fa23    mdiobus_unregister      vmlinux EXPORT_SYMBOL
++0x639399b9    ump_dd_phys_block_count_get     vmlinux EXPORT_SYMBOL
++0x6812cf8d    __tracepoint_rpm_idle   vmlinux EXPORT_SYMBOL_GPL
++0xaa90f5bc    phy_detach      vmlinux EXPORT_SYMBOL
++0x8ded75c5    mii_link_ok     vmlinux EXPORT_SYMBOL
++0xa6dd4938    cfg80211_inform_bss_frame       vmlinux EXPORT_SYMBOL
++0xd4cc3c98    bt_procfs_cleanup       vmlinux EXPORT_SYMBOL
++0xd856b532    tcp_proc_register       vmlinux EXPORT_SYMBOL
++0xb86a648c    nf_conntrack_l4proto_udp6       vmlinux EXPORT_SYMBOL_GPL
++0x2c81ec75    __irq_regs      vmlinux EXPORT_SYMBOL
++0x3f182756    generic_write_sync      vmlinux EXPORT_SYMBOL
++0x48bd4a65    wakeup_source_remove    vmlinux EXPORT_SYMBOL_GPL
++0x027c2c52    stop_tty        vmlinux EXPORT_SYMBOL
++0xc18578ed    process_srcu    vmlinux EXPORT_SYMBOL_GPL
++0xf3cf07b0    sdio_writel     vmlinux EXPORT_SYMBOL_GPL
++0x9b54326d    xfrm_policy_destroy     vmlinux EXPORT_SYMBOL
++0x667cc3f3    inet_del_offload        vmlinux EXPORT_SYMBOL
++0xbc9cfb6e    jbd2_journal_stop       vmlinux EXPORT_SYMBOL
++0x43aec82a    sdhci_pltfm_register    vmlinux EXPORT_SYMBOL_GPL
++0x1db8867b    sdio_memcpy_toio        vmlinux EXPORT_SYMBOL_GPL
++0x48499aa5    neigh_ifdown    vmlinux EXPORT_SYMBOL
++0x4b53ee2c    snd_pcm_hw_constraint_ratnums   vmlinux EXPORT_SYMBOL
++0x9650df0b    snd_ctl_replace vmlinux EXPORT_SYMBOL
++0x6c1ce5ce    strcspn vmlinux EXPORT_SYMBOL
++0xa68698f6    jbd2_journal_extend     vmlinux EXPORT_SYMBOL
++0x7eb6d1eb    thermal_zone_unbind_cooling_device      vmlinux EXPORT_SYMBOL_GPL
++0x81328587    blkdev_aio_write        vmlinux EXPORT_SYMBOL_GPL
++0xf8bec8e3    seq_bitmap_list vmlinux EXPORT_SYMBOL
++0xaec655c7    alloc_pages_exact       vmlinux EXPORT_SYMBOL
++0x6ce5ade9    hid_parse_report        vmlinux EXPORT_SYMBOL_GPL
++0x66f7b07e    ehci_resume     vmlinux EXPORT_SYMBOL_GPL
++0x95c578a0    ioremap_page_range      vmlinux EXPORT_SYMBOL_GPL
++0x498dcb5e    drm_ut_debug_printk     vmlinux EXPORT_SYMBOL
++0x6c1f6c7e    drm_rmmap       vmlinux EXPORT_SYMBOL
++0x8b55de97    devm_regulator_bulk_get vmlinux EXPORT_SYMBOL_GPL
++0x8190aef3    register_sound_special  vmlinux EXPORT_SYMBOL
++0x6c255d20    __nla_reserve   vmlinux EXPORT_SYMBOL
++0x29537c9e    alloc_chrdev_region     vmlinux EXPORT_SYMBOL
++0x05273827    inc_zone_page_state     vmlinux EXPORT_SYMBOL
++0xc665d6d7    of_parse_phandle_with_args      vmlinux EXPORT_SYMBOL
++0x01f7b595    usbnet_skb_return       vmlinux EXPORT_SYMBOL_GPL
++0x0740687f    arp_find        vmlinux EXPORT_SYMBOL
++0x269fbd1b    nf_ct_iterate_cleanup   vmlinux EXPORT_SYMBOL_GPL
++0x22ce6bb8    skb_checksum    vmlinux EXPORT_SYMBOL
++0x669f1bc1    kfree_skb_list  vmlinux EXPORT_SYMBOL
++0xca9360b5    rb_next vmlinux EXPORT_SYMBOL
++0x3c010e48    inode_permission        vmlinux EXPORT_SYMBOL
++0xba34ed58    buffer_migrate_page     vmlinux EXPORT_SYMBOL
++0x1cfb04fa    finish_wait     vmlinux EXPORT_SYMBOL
++0xcb0b79fb    max8997_read_reg        vmlinux EXPORT_SYMBOL_GPL
++0x564f1dca    klist_add_after vmlinux EXPORT_SYMBOL_GPL
++0x4cbbd171    __bitmap_weight vmlinux EXPORT_SYMBOL
++0x61b7b126    simple_strtoull vmlinux EXPORT_SYMBOL
++0x528c709d    simple_read_from_buffer vmlinux EXPORT_SYMBOL
++0x10c9d678    irq_domain_simple_ops   vmlinux EXPORT_SYMBOL_GPL
++0x5d8d802b    clockevent_delta2ns     vmlinux EXPORT_SYMBOL_GPL
++0xe8731295    gether_get_ifname       vmlinux EXPORT_SYMBOL
++0x8619c1c9    phy_start_aneg  vmlinux EXPORT_SYMBOL
++0x2a1c0adc    scsi_print_result       vmlinux EXPORT_SYMBOL
++0x6eb85693    nf_defrag_ipv6_enable   vmlinux EXPORT_SYMBOL_GPL
++0x6b6c3d10    nf_defrag_ipv4_enable   vmlinux EXPORT_SYMBOL_GPL
++0xa681fe88    generate_random_uuid    vmlinux EXPORT_SYMBOL
++0x3147857d    default_red     vmlinux EXPORT_SYMBOL
++0xff9ca065    fb_edid_to_monspecs     vmlinux EXPORT_SYMBOL
++0x22e14acd    gpiochip_add_pin_range  vmlinux EXPORT_SYMBOL_GPL
++0xad1bb027    nf_ct_free_hashtable    vmlinux EXPORT_SYMBOL_GPL
++0xaf509095    get_net_ns_by_pid       vmlinux EXPORT_SYMBOL_GPL
++0xcff75292    vfs_statfs      vmlinux EXPORT_SYMBOL
++0x2756ceb6    mmc_power_save_host     vmlinux EXPORT_SYMBOL
++0x438610bd    security_tun_dev_alloc_security vmlinux EXPORT_SYMBOL
++0xb1d9068c    ip6_datagram_send_ctl   vmlinux EXPORT_SYMBOL_GPL
++0x365c213d    udp_ioctl       vmlinux EXPORT_SYMBOL
++0x53877b9f    __nla_reserve_nohdr     vmlinux EXPORT_SYMBOL
++0xd64146c4    __get_page_tail vmlinux EXPORT_SYMBOL
++0x9b1bc5fa    i2c_new_probed_device   vmlinux EXPORT_SYMBOL_GPL
++0x3c787bd5    rtnetlink_put_metrics   vmlinux EXPORT_SYMBOL
++0xcb5c97f9    blk_queue_max_write_same_sectors        vmlinux EXPORT_SYMBOL
++0x3b909e7e    may_umount      vmlinux EXPORT_SYMBOL
++0x0c8099b1    v4l2_spi_new_subdev     vmlinux EXPORT_SYMBOL_GPL
++0xd00b0085    v4l2_ctrl_handler_setup vmlinux EXPORT_SYMBOL
++0xea10212a    int_to_scsilun  vmlinux EXPORT_SYMBOL
++0xcb0944d8    pwm_set_chip_data       vmlinux EXPORT_SYMBOL_GPL
++0xde5846c4    pwm_get_chip_data       vmlinux EXPORT_SYMBOL_GPL
++0x915917a3    block_read_full_page    vmlinux EXPORT_SYMBOL
++0xe5d61b91    console_drivers vmlinux EXPORT_SYMBOL_GPL
++0xb776298b    iommu_detach_device     vmlinux EXPORT_SYMBOL_GPL
++0xeb711ae7    snd_soc_params_to_bclk  vmlinux EXPORT_SYMBOL_GPL
++0x90ed601f    mmc_hw_reset    vmlinux EXPORT_SYMBOL
++0x1cbd340b    cdc_ncm_unbind  vmlinux EXPORT_SYMBOL_GPL
++0x9caab5b6    __scsi_alloc_queue      vmlinux EXPORT_SYMBOL
++0x2506e85a    bus_sort_breadthfirst   vmlinux EXPORT_SYMBOL_GPL
++0xd6769f27    ipt_alloc_initial_table vmlinux EXPORT_SYMBOL_GPL
++0x439fe23e    tcp_v4_connect  vmlinux EXPORT_SYMBOL
++0x02de3eaf    tcp_sync_mss    vmlinux EXPORT_SYMBOL
++0x4be85a03    memweight       vmlinux EXPORT_SYMBOL
++0x93021b18    jbd2_journal_ack_err    vmlinux EXPORT_SYMBOL
++0xd0c05159    emergency_restart       vmlinux EXPORT_SYMBOL_GPL
++0x3ff62317    local_bh_disable        vmlinux EXPORT_SYMBOL
++0xd88781bd    regmap_raw_write        vmlinux EXPORT_SYMBOL_GPL
++0xada38534    regulator_bulk_disable  vmlinux EXPORT_SYMBOL_GPL
++0x2ad4daf6    tcp_death_row   vmlinux EXPORT_SYMBOL_GPL
++0x87751cba    netdev_upper_dev_link   vmlinux EXPORT_SYMBOL
++0xe187693c    kstrtouint_from_user    vmlinux EXPORT_SYMBOL
++0xbe797e8f    bio_get_nr_vecs vmlinux EXPORT_SYMBOL
++0x2373352a    clk_fixed_factor_ops    vmlinux EXPORT_SYMBOL_GPL
++0xccbee9bd    mmc_set_blockcount      vmlinux EXPORT_SYMBOL
++0x9ebb3718    v4l2_clk_unregister     vmlinux EXPORT_SYMBOL
++0xe28ade94    serio_rescan    vmlinux EXPORT_SYMBOL
++0x1b5c713f    drm_send_vblank_event   vmlinux EXPORT_SYMBOL
++0xa257d9cd    framebuffer_alloc       vmlinux EXPORT_SYMBOL
++0x0916cc54    xfrm_policy_byid        vmlinux EXPORT_SYMBOL
++0x07319ef1    ahash_register_instance vmlinux EXPORT_SYMBOL_GPL
++0x11c55999    load_nls_default        vmlinux EXPORT_SYMBOL
++0xcae08d66    nonseekable_open        vmlinux EXPORT_SYMBOL
++0x3651150d    kmem_cache_create       vmlinux EXPORT_SYMBOL
++0xfd26424e    cpufreq_driver_target   vmlinux EXPORT_SYMBOL_GPL
++0x66adff69    vb2_fop_read    vmlinux EXPORT_SYMBOL_GPL
++0x09a5b743    amba_apb_device_add     vmlinux EXPORT_SYMBOL_GPL
++0x475100c2    inet_get_local_port_range       vmlinux EXPORT_SYMBOL
++0x8c1e0ffe    __seq_open_private      vmlinux EXPORT_SYMBOL
++0xd60c8ab0    seq_escape      vmlinux EXPORT_SYMBOL
++0xc81ec7cb    phy_get_eee_err vmlinux EXPORT_SYMBOL
++0x00778770    xfrm_ealg_get_byname    vmlinux EXPORT_SYMBOL_GPL
++0x5bc722fb    sock_alloc_file vmlinux EXPORT_SYMBOL
++0xddf821b8    page_address    vmlinux EXPORT_SYMBOL
++0x9771ccf0    of_mdiobus_register     vmlinux EXPORT_SYMBOL
++0x5eb24829    dm_shift_arg    vmlinux EXPORT_SYMBOL
++0x119e8920    v4l2_async_unregister_subdev    vmlinux EXPORT_SYMBOL
++0x7bc3e7c1    xfrm_lookup     vmlinux EXPORT_SYMBOL
++0xae0410db    skb_store_bits  vmlinux EXPORT_SYMBOL
++0xf86deaaa    page_cache_sync_readahead       vmlinux EXPORT_SYMBOL_GPL
++0x7681946c    unregister_pm_notifier  vmlinux EXPORT_SYMBOL_GPL
++0x3d98d961    inet_unregister_protosw vmlinux EXPORT_SYMBOL
++0x82108639    snd_soc_get_volsw       vmlinux EXPORT_SYMBOL_GPL
++0x286d040c    snd_soc_put_volsw       vmlinux EXPORT_SYMBOL_GPL
++0x371c0db7    blk_queue_bypass_end    vmlinux EXPORT_SYMBOL_GPL
++0x8589f760    mb_cache_entry_free     vmlinux EXPORT_SYMBOL
++0x87a795d4    i2c_probe_func_quick_read       vmlinux EXPORT_SYMBOL_GPL
++0xb05661a7    i2c_smbus_read_byte     vmlinux EXPORT_SYMBOL
++0x167977e6    platform_create_bundle  vmlinux EXPORT_SYMBOL_GPL
++0xb626c977    _dev_info       vmlinux EXPORT_SYMBOL
++0x0d5db696    arm_iommu_detach_device vmlinux EXPORT_SYMBOL_GPL
++0x001f6379    blkcipher_walk_phys     vmlinux EXPORT_SYMBOL_GPL
++0x3dfc897c    seq_hlist_start_head    vmlinux EXPORT_SYMBOL
++0xc34ff0bb    clocksource_change_rating       vmlinux EXPORT_SYMBOL
++0x5ace7e88    devres_for_each_res     vmlinux EXPORT_SYMBOL_GPL
++0xd4390384    __ieee80211_get_channel vmlinux EXPORT_SYMBOL
++0xe55e04a1    ip6_tnl_rcv_ctl vmlinux EXPORT_SYMBOL_GPL
++0xa389a49a    profile_event_register  vmlinux EXPORT_SYMBOL_GPL
++0x5ef37944    sdio_set_block_size     vmlinux EXPORT_SYMBOL_GPL
++0x9924c496    __usb_get_extra_descriptor      vmlinux EXPORT_SYMBOL_GPL
++0xcfa57ce1    __nf_conntrack_helper_find      vmlinux EXPORT_SYMBOL_GPL
++0x5460c8d8    fsnotify_get_cookie     vmlinux EXPORT_SYMBOL_GPL
++0xf5f58a7b    gether_register_netdev  vmlinux EXPORT_SYMBOL
++0xe774e9e4    register_netdevice      vmlinux EXPORT_SYMBOL
++0x9209f545    blkdev_put      vmlinux EXPORT_SYMBOL
++0x6a1c9c55    blkdev_get      vmlinux EXPORT_SYMBOL
++0x4d0cbb95    finish_no_open  vmlinux EXPORT_SYMBOL
++0xa1ef69b9    unregister_ftrace_event vmlinux EXPORT_SYMBOL_GPL
++0x09d6a08d    v4l2_device_disconnect  vmlinux EXPORT_SYMBOL_GPL
++0x613a7741    scsi_finish_command     vmlinux EXPORT_SYMBOL
++0x11f447ce    __gpio_to_irq   vmlinux EXPORT_SYMBOL_GPL
++0xb8a9ab06    hci_unregister_cb       vmlinux EXPORT_SYMBOL
++0xca0741ee    nf_nat_l4proto_register vmlinux EXPORT_SYMBOL_GPL
++0x70f09a3d    nf_nat_l3proto_register vmlinux EXPORT_SYMBOL_GPL
++0x10447797    build_skb       vmlinux EXPORT_SYMBOL
++0xf2b1ac8e    __getnstimeofday        vmlinux EXPORT_SYMBOL
++0x8923ab21    get_tz_trend    vmlinux EXPORT_SYMBOL
++0x450e1fb7    gs_alloc_req    vmlinux EXPORT_SYMBOL_GPL
++0x176df204    tcp_get_info    vmlinux EXPORT_SYMBOL_GPL
++0x4c2a5480    __alloc_skb     vmlinux EXPORT_SYMBOL
++0x90814050    snd_soc_cache_write     vmlinux EXPORT_SYMBOL_GPL
++0xa4ba4393    snd_soc_dai_set_fmt     vmlinux EXPORT_SYMBOL_GPL
++0x2d98d3e7    jbd2_journal_begin_ordered_truncate     vmlinux EXPORT_SYMBOL
++0x5b79185b    jbd2_trans_will_send_data_barrier       vmlinux EXPORT_SYMBOL
++0xc200914d    mutex_trylock   vmlinux EXPORT_SYMBOL
++0xe24d3a97    jiffies_64      vmlinux EXPORT_SYMBOL
++0x7eb7b3f8    of_get_dma_window       vmlinux EXPORT_SYMBOL_GPL
++0xc5c9bb41    regmap_get_val_bytes    vmlinux EXPORT_SYMBOL_GPL
++0x8226642f    __gpio_cansleep vmlinux EXPORT_SYMBOL_GPL
++0x6def2db2    half_md4_transform      vmlinux EXPORT_SYMBOL
++0xb835b3e4    radix_tree_prev_hole    vmlinux EXPORT_SYMBOL
++0xbed06655    dcache_readdir  vmlinux EXPORT_SYMBOL
++0x980c6433    inode_add_bytes vmlinux EXPORT_SYMBOL
++0xdc092d5b    thaw_super      vmlinux EXPORT_SYMBOL
++0x1ef192c5    generic_file_mmap       vmlinux EXPORT_SYMBOL
++0x9075cea3    abort_creds     vmlinux EXPORT_SYMBOL
++0x4ef8e23f    led_set_brightness      vmlinux EXPORT_SYMBOL
++0x48a5b067    __machine_arch_type     vmlinux EXPORT_SYMBOL
++0x4188d439    neigh_rand_reach_time   vmlinux EXPORT_SYMBOL
++0x7eef21b4    dev_forward_skb vmlinux EXPORT_SYMBOL_GPL
++0x5825f0e7    sock_common_getsockopt  vmlinux EXPORT_SYMBOL
++0x2de67218    sock_common_setsockopt  vmlinux EXPORT_SYMBOL
++0x65408378    zlib_inflate_blob       vmlinux EXPORT_SYMBOL
++0xc6d9568b    try_to_writeback_inodes_sb      vmlinux EXPORT_SYMBOL
++0x5ad87de6    vfs_mknod       vmlinux EXPORT_SYMBOL
++0x6f5c943e    rndis_add_hdr   vmlinux EXPORT_SYMBOL
++0x6a91e934    drm_mode_create_dvi_i_properties        vmlinux EXPORT_SYMBOL
++0x3eb37b9d    drm_ht_create   vmlinux EXPORT_SYMBOL
++0xcdf8626d    n_tty_inherit_ops       vmlinux EXPORT_SYMBOL_GPL
++0x65d6d0f0    gpio_direction_input    vmlinux EXPORT_SYMBOL_GPL
++0x74acd28a    nfc_hci_set_clientdata  vmlinux EXPORT_SYMBOL
++0x6c6a3e69    nfc_hci_get_clientdata  vmlinux EXPORT_SYMBOL
++0x8e235e9b    cfg80211_disconnected   vmlinux EXPORT_SYMBOL
++0x2d6b040a    cfg80211_send_rx_auth   vmlinux EXPORT_SYMBOL
++0x987f5e85    skb_dequeue     vmlinux EXPORT_SYMBOL
++0x413461c0    filemap_write_and_wait  vmlinux EXPORT_SYMBOL
++0x27bbf221    disable_irq_nosync      vmlinux EXPORT_SYMBOL
++0x00000000    softirq_work_list       vmlinux EXPORT_SYMBOL
++0x8c298b56    vb2_ioctl_querybuf      vmlinux EXPORT_SYMBOL_GPL
++0x94d7075a    usb_gadget_get_string   vmlinux EXPORT_SYMBOL_GPL
++0x19ef30a6    usbnet_manage_power     vmlinux EXPORT_SYMBOL
++0x967e7ec8    inet_rtx_syn_ack        vmlinux EXPORT_SYMBOL
++0x9b9e05f9    alloc_cpu_rmap  vmlinux EXPORT_SYMBOL
++0xa7f92105    add_uevent_var  vmlinux EXPORT_SYMBOL_GPL
++0x6e6c5939    dma_buf_kunmap_atomic   vmlinux EXPORT_SYMBOL_GPL
++0x3723eb08    __pm_relax      vmlinux EXPORT_SYMBOL_GPL
++0x1ae74b3a    drm_framebuffer_unregister_private      vmlinux EXPORT_SYMBOL
++0xf7584a9c    find_font       vmlinux EXPORT_SYMBOL
++0x88e316d7    netdev_features_change  vmlinux EXPORT_SYMBOL
++0xf19e9355    cpu_online_mask vmlinux EXPORT_SYMBOL
++0xaa8195e9    media_entity_remote_pad vmlinux EXPORT_SYMBOL_GPL
++0x19ec698c    platform_get_resource_byname    vmlinux EXPORT_SYMBOL_GPL
++0x62813e5c    nf_ct_port_nlattr_tuple_size    vmlinux EXPORT_SYMBOL_GPL
++0x4ff4a58a    nfnetlink_alloc_skb     vmlinux EXPORT_SYMBOL_GPL
++0xeed3635b    proc_dostring   vmlinux EXPORT_SYMBOL
++0xb54533f7    usecs_to_jiffies        vmlinux EXPORT_SYMBOL
++0x0b56117f    of_find_node_by_path    vmlinux EXPORT_SYMBOL
++0xcc4b84da    of_find_node_by_type    vmlinux EXPORT_SYMBOL
++0xf9fd4da3    phy_start       vmlinux EXPORT_SYMBOL
++0x5ea42ad5    devres_find     vmlinux EXPORT_SYMBOL_GPL
++0x598a2261    drm_mode_probed_add     vmlinux EXPORT_SYMBOL
++0xc35b2a18    xt_hook_link    vmlinux EXPORT_SYMBOL_GPL
++0xc1c24fbc    genlmsg_put     vmlinux EXPORT_SYMBOL
++0xf177aba7    sysfs_schedule_callback vmlinux EXPORT_SYMBOL_GPL
++0xabcaa577    free_anon_bdev  vmlinux EXPORT_SYMBOL
++0x6d289788    pwm_set_polarity        vmlinux EXPORT_SYMBOL_GPL
++0x2546de76    raw_hash_sk     vmlinux EXPORT_SYMBOL_GPL
++0xa2ef34d7    rps_sock_flow_table     vmlinux EXPORT_SYMBOL
++0x3730910b    skb_insert      vmlinux EXPORT_SYMBOL
++0xb8b7395a    snd_compress_new        vmlinux EXPORT_SYMBOL_GPL
++0x1c132024    request_any_context_irq vmlinux EXPORT_SYMBOL_GPL
++0x5aba52ab    iio_trigger_poll        vmlinux EXPORT_SYMBOL
++0xe9b6f3f3    dev_emerg       vmlinux EXPORT_SYMBOL
++0xfacd2e14    pgprot_user     vmlinux EXPORT_SYMBOL
++0x0a0786de    udplite_table   vmlinux EXPORT_SYMBOL
++0xd9bbcf52    tc_classify_compat      vmlinux EXPORT_SYMBOL
++0x72f15b74    blk_queue_max_segment_size      vmlinux EXPORT_SYMBOL
++0x544aab61    klist_add_tail  vmlinux EXPORT_SYMBOL_GPL
++0x490434ad    dev_kfree_skb_irq       vmlinux EXPORT_SYMBOL
++0xdb3a9b04    jbd2_journal_file_inode vmlinux EXPORT_SYMBOL
++0x6e9dd606    __symbol_put    vmlinux EXPORT_SYMBOL
++0x40a2d1dd    dm_table_get_size       vmlinux EXPORT_SYMBOL
++0xceee316a    gether_set_host_addr    vmlinux EXPORT_SYMBOL
++0x32f81723    gether_get_host_addr    vmlinux EXPORT_SYMBOL
++0xae387af1    usb_gadget_unmap_request        vmlinux EXPORT_SYMBOL_GPL
++0x8dfb019d    drm_buffer_free vmlinux EXPORT_SYMBOL
++0x600683d3    do_unblank_screen       vmlinux EXPORT_SYMBOL
++0xc1ebf6fe    get_kernel_page vmlinux EXPORT_SYMBOL_GPL
++0x9b388444    get_zeroed_page vmlinux EXPORT_SYMBOL
++0x53b69429    vb2_streamon    vmlinux EXPORT_SYMBOL_GPL
++0x211aedde    genphy_restart_aneg     vmlinux EXPORT_SYMBOL
++0xebdba37a    ndo_dflt_fdb_dump       vmlinux EXPORT_SYMBOL
++0x604ef7b4    snd_pcm_lib_read        vmlinux EXPORT_SYMBOL
++0x60541cbf    st_sensors_set_odr      vmlinux EXPORT_SYMBOL
++0xe53d1faa    of_translate_dma_address        vmlinux EXPORT_SYMBOL
++0xaf05b91b    of_device_is_available  vmlinux EXPORT_SYMBOL
++0x1a426d0c    input_close_device      vmlinux EXPORT_SYMBOL
++0xe720411b    rtnl_create_link        vmlinux EXPORT_SYMBOL
++0x650f8603    snd_pcm_format_silence_64       vmlinux EXPORT_SYMBOL
++0x7164c04b    address_space_init_once vmlinux EXPORT_SYMBOL
++0xfda0dbe8    ftrace_print_hex_seq    vmlinux EXPORT_SYMBOL
++0x2c988955    prepare_to_wait_exclusive       vmlinux EXPORT_SYMBOL
++0x9c3206d8    v4l2_device_unregister  vmlinux EXPORT_SYMBOL_GPL
++0xd5c2bed3    phy_connect_direct      vmlinux EXPORT_SYMBOL
++0xed2b0677    drm_mode_connector_update_edid_property vmlinux EXPORT_SYMBOL
++0xbf17b32e    tty_insert_flip_string_flags    vmlinux EXPORT_SYMBOL
++0xadc9ed27    bt_sock_ioctl   vmlinux EXPORT_SYMBOL
++0x33ea8640    inet_dev_addr_type      vmlinux EXPORT_SYMBOL
++0xd265ad57    tcf_action_exec vmlinux EXPORT_SYMBOL
++0xec8d9205    snd_soc_register_codec  vmlinux EXPORT_SYMBOL_GPL
++0x5e8ff943    debugfs_create_size_t   vmlinux EXPORT_SYMBOL_GPL
++0x5b968338    remove_proc_entry       vmlinux EXPORT_SYMBOL
++0x4717eaaf    platform_device_add     vmlinux EXPORT_SYMBOL_GPL
++0x44a0c113    drm_mode_height vmlinux EXPORT_SYMBOL
++0xe219d715    ipv6_opt_accepted       vmlinux EXPORT_SYMBOL_GPL
++0x503ed988    xfrm_spd_getinfo        vmlinux EXPORT_SYMBOL
++0x1fd1fabe    arpt_register_table     vmlinux EXPORT_SYMBOL
++0xf9ed2e31    block_is_partially_uptodate     vmlinux EXPORT_SYMBOL
++0xd9ecb670    ring_buffer_overruns    vmlinux EXPORT_SYMBOL_GPL
++0x5e911cf3    exynos_g2d_exec_ioctl   vmlinux EXPORT_SYMBOL_GPL
++0xbf69cda1    drm_connector_unplug_all        vmlinux EXPORT_SYMBOL
++0xafe3eb1b    alloc_etherdev_mqs      vmlinux EXPORT_SYMBOL
++0x39bf9301    _snd_pcm_hw_param_setempty      vmlinux EXPORT_SYMBOL
++0xd81836ce    uart_resume_port        vmlinux EXPORT_SYMBOL
++0x46931864    nfc_tm_data_received    vmlinux EXPORT_SYMBOL
++0xfac8865f    sysctl_wmem_max vmlinux EXPORT_SYMBOL
++0xb05fc310    sysctl_rmem_max vmlinux EXPORT_SYMBOL
++0xe9b673fa    dapm_mark_io_dirty      vmlinux EXPORT_SYMBOL_GPL
++0xbf0046d7    ahash_free_instance     vmlinux EXPORT_SYMBOL_GPL
++0x825a0923    jbd2_journal_errno      vmlinux EXPORT_SYMBOL
++0x03cb2c1a    bdi_register_dev        vmlinux EXPORT_SYMBOL
++0x018f7433    pm_relax        vmlinux EXPORT_SYMBOL_GPL
++0x63e0cc67    pagecache_write_end     vmlinux EXPORT_SYMBOL
++0x8a04b9fe    tracepoint_iter_reset   vmlinux EXPORT_SYMBOL_GPL
++0x5cf53ce2    input_free_minor        vmlinux EXPORT_SYMBOL
++0x17bfef6c    drm_clflush_pages       vmlinux EXPORT_SYMBOL
++0x5f14861d    pwm_get vmlinux EXPORT_SYMBOL_GPL
++0xb8a5d4ee    cfg80211_ft_event       vmlinux EXPORT_SYMBOL
++0xb9da2997    snmp_fold_field64       vmlinux EXPORT_SYMBOL_GPL
++0x87925ca6    kstrtoint_from_user     vmlinux EXPORT_SYMBOL
++0x6e891ea0    clk_unprepare   vmlinux EXPORT_SYMBOL_GPL
++0x3d41904f    of_get_next_child       vmlinux EXPORT_SYMBOL
++0x687835e7    hidinput_get_led_field  vmlinux EXPORT_SYMBOL_GPL
++0x36859243    hid_resolv_usage        vmlinux EXPORT_SYMBOL_GPL
++0x995dedd6    sdio_f0_readb   vmlinux EXPORT_SYMBOL_GPL
++0x19f5809b    dm_ratelimit_state      vmlinux EXPORT_SYMBOL
++0xe684f045    v4l2_subdev_try_ext_ctrls       vmlinux EXPORT_SYMBOL
++0x41f62b69    spi_register_master     vmlinux EXPORT_SYMBOL_GPL
++0x49428bcb    drm_read        vmlinux EXPORT_SYMBOL
++0xb12cbacb    fb_unregister_client    vmlinux EXPORT_SYMBOL
++0x7c53b814    xfrm_inner_extract_output       vmlinux EXPORT_SYMBOL_GPL
++0x86dd59c8    inet_csk_init_xmit_timers       vmlinux EXPORT_SYMBOL
++0x51e297e3    __nf_ct_l4proto_find    vmlinux EXPORT_SYMBOL_GPL
++0x1b52db1c    probe_kernel_read       vmlinux EXPORT_SYMBOL_GPL
++0xd4e65e28    irq_set_chip_and_handler_name   vmlinux EXPORT_SYMBOL_GPL
++0x9c7a3b79    drm_fb_helper_debug_enter       vmlinux EXPORT_SYMBOL
++0xc25d1133    vfs_readlink    vmlinux EXPORT_SYMBOL
++0x7e9efe8e    complete_and_exit       vmlinux EXPORT_SYMBOL
++0xd8d64478    v4l2_ctrl_new_std_menu_items    vmlinux EXPORT_SYMBOL
++0xb6652875    gserial_free_line       vmlinux EXPORT_SYMBOL_GPL
++0xd4adf602    dev_pm_get_subsys_data  vmlinux EXPORT_SYMBOL_GPL
++0x1f335345    dev_pm_put_subsys_data  vmlinux EXPORT_SYMBOL_GPL
++0x30399f8a    transport_add_device    vmlinux EXPORT_SYMBOL_GPL
++0x44c2d1be    drm_mode_prune_invalid  vmlinux EXPORT_SYMBOL
++0x3e9d6f44    cfg80211_unregister_wdev        vmlinux EXPORT_SYMBOL
++0xfb5bb3ee    inet6_lookup    vmlinux EXPORT_SYMBOL_GPL
++0x535cfa1f    sysfs_remove_group      vmlinux EXPORT_SYMBOL_GPL
++0x795b1ab0    sysfs_remove_file_from_group    vmlinux EXPORT_SYMBOL_GPL
++0x9aca444b    get_monotonic_boottime  vmlinux EXPORT_SYMBOL_GPL
++0x91aec064    down_read_trylock       vmlinux EXPORT_SYMBOL
++0x87e148ee    v4l2_m2m_poll   vmlinux EXPORT_SYMBOL_GPL
++0xfcb34391    scsi_execute_req_flags  vmlinux EXPORT_SYMBOL
++0x19391863    regmap_reinit_cache     vmlinux EXPORT_SYMBOL_GPL
++0xff6878cf    fb_default_cmap vmlinux EXPORT_SYMBOL
++0x38524c14    cpufreq_register_driver vmlinux EXPORT_SYMBOL_GPL
++0x4ca0e0e5    v4l2_ctrl_modify_range  vmlinux EXPORT_SYMBOL
++0x4f6f28fb    serial8250_handle_irq   vmlinux EXPORT_SYMBOL_GPL
++0x7b56a1b0    nf_nat_set_seq_adjust   vmlinux EXPORT_SYMBOL_GPL
++0x63df94bc    nf_nat_tcp_seq_adjust   vmlinux EXPORT_SYMBOL_GPL
++0x8ffb22a4    nf_setsockopt   vmlinux EXPORT_SYMBOL
++0xefd0fb67    nf_getsockopt   vmlinux EXPORT_SYMBOL
++0x579e0bf5    rtnl_unregister_all     vmlinux EXPORT_SYMBOL_GPL
++0x87e5d976    netif_rx_ni     vmlinux EXPORT_SYMBOL
++0xe27cea7b    alloc_disk      vmlinux EXPORT_SYMBOL
++0x1f867001    blk_rq_map_user_iov     vmlinux EXPORT_SYMBOL
++0xa3829135    ioc_lookup_icq  vmlinux EXPORT_SYMBOL
++0xd2ce469a    seq_puts        vmlinux EXPORT_SYMBOL
++0xf29942b3    seq_putc        vmlinux EXPORT_SYMBOL
++0xf268be24    dw_mci_remove   vmlinux EXPORT_SYMBOL
++0xb7ef4006    i2c_smbus_xfer  vmlinux EXPORT_SYMBOL
++0xb8a16d46    dev_pm_qos_remove_notifier      vmlinux EXPORT_SYMBOL_GPL
++0x37afc4f0    device_attach   vmlinux EXPORT_SYMBOL_GPL
++0x581e8240    tty_port_open   vmlinux EXPORT_SYMBOL
++0xa4583858    snd_pcm_hw_param_last   vmlinux EXPORT_SYMBOL
++0x43497fcc    part_round_stats        vmlinux EXPORT_SYMBOL_GPL
++0x0cd23659    d_genocide      vmlinux EXPORT_SYMBOL
++0x328995b5    tracing_generic_entry_update    vmlinux EXPORT_SYMBOL_GPL
++0xfe24d1c7    __module_put_and_exit   vmlinux EXPORT_SYMBOL
++0x43a53735    __alloc_workqueue_key   vmlinux EXPORT_SYMBOL_GPL
++0x2a902f32    usb_create_shared_hcd   vmlinux EXPORT_SYMBOL_GPL
++0xdbdbb6e7    uart_update_timeout     vmlinux EXPORT_SYMBOL
++0xf71617c1    cfg80211_report_obss_beacon     vmlinux EXPORT_SYMBOL
++0x3e5d6dc3    snd_soc_put_value_enum_double   vmlinux EXPORT_SYMBOL_GPL
++0xef67a6d3    snd_soc_get_value_enum_double   vmlinux EXPORT_SYMBOL_GPL
++0x81b69e41    snd_ctl_enum_info       vmlinux EXPORT_SYMBOL
++0xb2b94674    __crc32c_le     vmlinux EXPORT_SYMBOL
++0xc61cc06d    elv_dispatch_add_tail   vmlinux EXPORT_SYMBOL
++0x85e0bce2    end_buffer_write_sync   vmlinux EXPORT_SYMBOL
++0x3cc671ae    d_drop  vmlinux EXPORT_SYMBOL
++0x7469f641    d_rehash        vmlinux EXPORT_SYMBOL
++0xddcebac8    file_open_root  vmlinux EXPORT_SYMBOL
++0x310308c3    flush_kthread_work      vmlinux EXPORT_SYMBOL_GPL
++0x40f07981    __ashldi3       vmlinux EXPORT_SYMBOL
++0x88e83ca7    snd_soc_dpcm_be_set_state       vmlinux EXPORT_SYMBOL_GPL
++0x5eca39b9    snd_soc_dpcm_be_get_state       vmlinux EXPORT_SYMBOL_GPL
++0x6b1b67d3    __bdevname      vmlinux EXPORT_SYMBOL
++0xe4315493    vfs_write       vmlinux EXPORT_SYMBOL
++0x99fab0b8    __mmc_claim_host        vmlinux EXPORT_SYMBOL
++0x2c8e9ced    usb_poison_urb  vmlinux EXPORT_SYMBOL_GPL
++0x33a8a5f0    netif_rx        vmlinux EXPORT_SYMBOL
++0x1d54bb24    snd_pcm_hw_refine       vmlinux EXPORT_SYMBOL
++0x955b0e2e    kthread_worker_fn       vmlinux EXPORT_SYMBOL_GPL
++0x276ad369    dm_set_device_limits    vmlinux EXPORT_SYMBOL_GPL
++0x9e61f179    xfrm_stateonly_find     vmlinux EXPORT_SYMBOL
++0x972bcca5    usb_create_hcd  vmlinux EXPORT_SYMBOL_GPL
++0x72ea7b2d    scsi_device_type        vmlinux EXPORT_SYMBOL
++0x318cadb1    reciprocal_value        vmlinux EXPORT_SYMBOL
++0x22f77bec    unregister_binfmt       vmlinux EXPORT_SYMBOL
++0xafceeb25    alloc_vm_area   vmlinux EXPORT_SYMBOL_GPL
++0xcfe980c6    make_kgid       vmlinux EXPORT_SYMBOL
++0xb71fb74f    _raw_read_trylock       vmlinux EXPORT_SYMBOL
++0x9dadbb88    cpufreq_boost_supported vmlinux EXPORT_SYMBOL_GPL
++0xab9e471e    usb_autopm_get_interface_no_resume      vmlinux EXPORT_SYMBOL_GPL
++0x42453e50    sk_reset_txq    vmlinux EXPORT_SYMBOL
++0x05d48045    sock_no_accept  vmlinux EXPORT_SYMBOL
++0xb511dcf5    set_groups      vmlinux EXPORT_SYMBOL
++0x5f0abc76    pinctrl_dev_get_devname vmlinux EXPORT_SYMBOL_GPL
++0xec25f967    klist_del       vmlinux EXPORT_SYMBOL_GPL
++0x530ed62b    tcf_generic_walker      vmlinux EXPORT_SYMBOL
++0xacd392a0    sock_diag_register_inet_compat  vmlinux EXPORT_SYMBOL_GPL
++0x2509c465    dev_remove_offload      vmlinux EXPORT_SYMBOL
++0x8ee1a28d    elevator_exit   vmlinux EXPORT_SYMBOL
++0xcd357308    __lock_buffer   vmlinux EXPORT_SYMBOL
++0xd85139d2    mmc_unregister_driver   vmlinux EXPORT_SYMBOL
++0xb53559bb    brcmu_pktq_pflush       drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0xbb0ab47b    debug_locks     vmlinux EXPORT_SYMBOL_GPL
++0x56b2a97f    ablkcipher_walk_done    vmlinux EXPORT_SYMBOL_GPL
++0xd3630b88    ablkcipher_walk_phys    vmlinux EXPORT_SYMBOL_GPL
++0x3116987e    aead_geniv_alloc        vmlinux EXPORT_SYMBOL_GPL
++0x20a789ac    irq_set_chip_data       vmlinux EXPORT_SYMBOL
++0xeda65ce1    dma_release_declared_memory     vmlinux EXPORT_SYMBOL
++0xa984aab8    cfg80211_scan_done      vmlinux EXPORT_SYMBOL
++0x254c40cf    inet6_csk_xmit  vmlinux EXPORT_SYMBOL_GPL
++0xca805e0b    tcp_ioctl       vmlinux EXPORT_SYMBOL
++0x4ebc74b2    vfs_symlink     vmlinux EXPORT_SYMBOL
++0xefcf3143    wait_for_completion_io  vmlinux EXPORT_SYMBOL
++0xa9efcc8b    find_vpid       vmlinux EXPORT_SYMBOL_GPL
++0xd273b1b1    __round_jiffies_up_relative     vmlinux EXPORT_SYMBOL_GPL
++0xb8973764    iommu_attach_group      vmlinux EXPORT_SYMBOL_GPL
++0x5d550c4d    scsi_sd_probe_domain    vmlinux EXPORT_SYMBOL
++0x52f9bd8e    registered_fb   vmlinux EXPORT_SYMBOL
++0xe67d81ba    strlen_user     vmlinux EXPORT_SYMBOL
++0x480f1913    unmap_mapping_range     vmlinux EXPORT_SYMBOL
++0x8b618d08    overflowuid     vmlinux EXPORT_SYMBOL
++0x7171121c    overflowgid     vmlinux EXPORT_SYMBOL
++0xb3514b24    cfg80211_radar_event    vmlinux EXPORT_SYMBOL
++0xf06154af    inet_select_addr        vmlinux EXPORT_SYMBOL
++0x340854b4    dev_getbyhwaddr_rcu     vmlinux EXPORT_SYMBOL
++0x4ce033c8    skb_flow_dissect        vmlinux EXPORT_SYMBOL
++0x465757c3    cpu_present_mask        vmlinux EXPORT_SYMBOL
++0xb3a37086    dma_async_tx_descriptor_init    vmlinux EXPORT_SYMBOL
++0x955eec37    wireless_send_event     vmlinux EXPORT_SYMBOL
++0x7954e502    ipv6_recv_error vmlinux EXPORT_SYMBOL_GPL
++0xcebcfddd    snd_soc_get_enum_double vmlinux EXPORT_SYMBOL_GPL
++0x1c9728c6    snd_soc_put_enum_double vmlinux EXPORT_SYMBOL_GPL
++0xb4711532    get_task_io_context     vmlinux EXPORT_SYMBOL
++0x6cce08e5    dcache_dir_close        vmlinux EXPORT_SYMBOL
++0x3e884f4b    vm_get_page_prot        vmlinux EXPORT_SYMBOL
++0x20886a16    v4l2_subdev_g_ctrl      vmlinux EXPORT_SYMBOL
++0xd56dcf8e    v4l2_subdev_s_ctrl      vmlinux EXPORT_SYMBOL
++0x0465a073    regmap_reg_in_ranges    vmlinux EXPORT_SYMBOL_GPL
++0x74bc0dea    extcon_register_interest        vmlinux EXPORT_SYMBOL_GPL
++0x59c427c5    rtc_irq_set_state       vmlinux EXPORT_SYMBOL_GPL
++0x3302f88f    phy_driver_register     vmlinux EXPORT_SYMBOL
++0x848dd958    scsi_dma_unmap  vmlinux EXPORT_SYMBOL
++0xfbc74f64    __copy_from_user        vmlinux EXPORT_SYMBOL
++0xc9bb229b    inet_put_port   vmlinux EXPORT_SYMBOL
++0x73ac2c51    nf_conntrack_register_notifier  vmlinux EXPORT_SYMBOL_GPL
++0xbdca8444    sock_no_connect vmlinux EXPORT_SYMBOL
++0xe85a9fd3    cpu_cluster_pm_exit     vmlinux EXPORT_SYMBOL_GPL
++0xcb466063    wait_for_completion_killable_timeout    vmlinux EXPORT_SYMBOL
++0x9205953f    send_remote_softirq     vmlinux EXPORT_SYMBOL
++0x1852156d    phy_print_status        vmlinux EXPORT_SYMBOL
++0x486517f6    pinctrl_select_state    vmlinux EXPORT_SYMBOL_GPL
++0xfec26b4f    skcipher_geniv_alloc    vmlinux EXPORT_SYMBOL_GPL
++0x24094dc0    xfrm_garbage_collect    vmlinux EXPORT_SYMBOL
++0x6e224a7a    need_conntrack  vmlinux EXPORT_SYMBOL_GPL
++0x4a358252    __bitmap_subset vmlinux EXPORT_SYMBOL
++0x785d8ef0    ftrace_raw_output_prep  vmlinux EXPORT_SYMBOL
++0x697c5d0d    tracing_snapshot_alloc  vmlinux EXPORT_SYMBOL_GPL
++0x0e6da44a    set_normalized_timespec vmlinux EXPORT_SYMBOL
++0x789aafbd    iommu_map       vmlinux EXPORT_SYMBOL_GPL
++0x3a5f1e17    cfg80211_chandef_valid  vmlinux EXPORT_SYMBOL
++0xa11c9c1a    eth_type_trans  vmlinux EXPORT_SYMBOL
++0xe0f1fc5d    debugfs_create_blob     vmlinux EXPORT_SYMBOL_GPL
++0xd0f2dba2    mb_cache_entry_get      vmlinux EXPORT_SYMBOL
++0x233ed03d    vm_insert_mixed vmlinux EXPORT_SYMBOL
++0xa96bca8e    send_sig        vmlinux EXPORT_SYMBOL
++0x97cdf185    iio_buffer_read_length  vmlinux EXPORT_SYMBOL
++0x58d1070a    of_get_address  vmlinux EXPORT_SYMBOL
++0x620868cc    tcp_shutdown    vmlinux EXPORT_SYMBOL
++0x602c96f0    copy_to_user_fromio     vmlinux EXPORT_SYMBOL
++0x6d31e93b    tracepoint_iter_next    vmlinux EXPORT_SYMBOL_GPL
++0xe8b53ecc    down_write_trylock      vmlinux EXPORT_SYMBOL
++0x8bfe8c57    param_set_uint  vmlinux EXPORT_SYMBOL
++0x39422b14    usbnet_change_mtu       vmlinux EXPORT_SYMBOL_GPL
++0x4bd9c5ed    scsi_nonblockable_ioctl vmlinux EXPORT_SYMBOL
++0xcd319eaa    drm_vblank_count        vmlinux EXPORT_SYMBOL
++0x58413099    ipv6_fixup_options      vmlinux EXPORT_SYMBOL_GPL
++0xf389fe60    __hw_addr_init  vmlinux EXPORT_SYMBOL
++0x199ed0cd    net_disable_timestamp   vmlinux EXPORT_SYMBOL
++0x5ad8bb47    sdio_set_host_pm_flags  vmlinux EXPORT_SYMBOL_GPL
++0xdbbdaaf8    gether_get_qmult        vmlinux EXPORT_SYMBOL
++0x3d6846fc    gether_set_qmult        vmlinux EXPORT_SYMBOL
++0x14b14b7a    usb_get_function        vmlinux EXPORT_SYMBOL_GPL
++0x28fca1f1    pwmchip_add     vmlinux EXPORT_SYMBOL_GPL
++0xfbbedefd    of_prop_next_string     vmlinux EXPORT_SYMBOL_GPL
++0x4afe9a77    scsi_partsize   vmlinux EXPORT_SYMBOL
++0x14f875ce    devm_regmap_init_mmio_clk       vmlinux EXPORT_SYMBOL_GPL
++0x695aa696    __genl_register_family  vmlinux EXPORT_SYMBOL
++0x36bd681b    groups_alloc    vmlinux EXPORT_SYMBOL
++0x6a5b121d    of_find_device_by_node  vmlinux EXPORT_SYMBOL
++0x0dd989e3    vb2_streamoff   vmlinux EXPORT_SYMBOL_GPL
++0xa82de4f7    drm_pci_alloc   vmlinux EXPORT_SYMBOL
++0xdf54a8f7    netlink_unregister_notifier     vmlinux EXPORT_SYMBOL
++0xc4388843    dapm_regulator_event    vmlinux EXPORT_SYMBOL_GPL
++0x7a6fa714    __dynamic_dev_dbg       vmlinux EXPORT_SYMBOL
++0xfa4d00bd    simple_release_fs       vmlinux EXPORT_SYMBOL
++0xf473ffaf    down    vmlinux EXPORT_SYMBOL
++0xac6539ec    cm_notify_event vmlinux EXPORT_SYMBOL_GPL
++0xf49484e8    blk_end_request vmlinux EXPORT_SYMBOL
++0xb72a3fdb    drm_sysfs_connector_add vmlinux EXPORT_SYMBOL
++0x76cf47f6    __aeabi_llsl    vmlinux EXPORT_SYMBOL
++0x0573e568    inet_diag_dump_icsk     vmlinux EXPORT_SYMBOL_GPL
++0xc6a360e4    skb_put vmlinux EXPORT_SYMBOL
++0xf76b0a59    read_current_timer      vmlinux EXPORT_SYMBOL_GPL
++0xf1d6f94c    v4l2_m2m_ioctl_reqbufs  vmlinux EXPORT_SYMBOL_GPL
++0x5411bf06    scsi_host_put   vmlinux EXPORT_SYMBOL
++0xbca0b4fd    nfc_hci_sak_to_protocol vmlinux EXPORT_SYMBOL
++0x37386cac    nf_conntrack_hash_rnd   vmlinux EXPORT_SYMBOL_GPL
++0xdb065657    nfnl_unlock     vmlinux EXPORT_SYMBOL_GPL
++0xc5bd3b96    ethtool_op_get_ts_info  vmlinux EXPORT_SYMBOL
++0x5f8ed047    configfs_depend_item    vmlinux EXPORT_SYMBOL
++0x77fa6486    generic_block_fiemap    vmlinux EXPORT_SYMBOL
++0xc7bcbc8d    add_wait_queue  vmlinux EXPORT_SYMBOL
++0x046c1f16    param_ops_invbool       vmlinux EXPORT_SYMBOL
++0x4fe5c427    pinctrl_put     vmlinux EXPORT_SYMBOL_GPL
++0x547101cd    pinctrl_get     vmlinux EXPORT_SYMBOL_GPL
++0xdcc5846a    brcmu_pktq_flush        drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x4075ad18    dev_add_pack    vmlinux EXPORT_SYMBOL
++0x0a3131f6    strnchr vmlinux EXPORT_SYMBOL
++0xd20bf6ba    dcookie_unregister      vmlinux EXPORT_SYMBOL_GPL
++0x9e2be04d    vb2_poll        vmlinux EXPORT_SYMBOL_GPL
++0xa8f0aba7    usb_hub_clear_tt_buffer vmlinux EXPORT_SYMBOL_GPL
++0x2698ff67    drm_helper_connector_dpms       vmlinux EXPORT_SYMBOL
++0x48d34903    arm_dma_ops     vmlinux EXPORT_SYMBOL
++0x9f984513    strrchr vmlinux EXPORT_SYMBOL
++0x7afa89fc    vsnprintf       vmlinux EXPORT_SYMBOL
++0x7fe32873    rb_replace_node vmlinux EXPORT_SYMBOL
++0x6ff607b6    crypto_get_default_rng  vmlinux EXPORT_SYMBOL_GPL
++0x668402aa    crypto_put_default_rng  vmlinux EXPORT_SYMBOL_GPL
++0x850ff7d2    crypto_mod_put  vmlinux EXPORT_SYMBOL_GPL
++0x1db21259    mount_pseudo    vmlinux EXPORT_SYMBOL
++0x304ec72b    _raw_write_trylock      vmlinux EXPORT_SYMBOL
++0x4205ad24    cancel_work_sync        vmlinux EXPORT_SYMBOL_GPL
++0x99cdc86b    sysctl_tcp_reordering   vmlinux EXPORT_SYMBOL
++0x19d94b34    nf_ct_gre_keymap_flush  vmlinux EXPORT_SYMBOL
++0x356bcd72    nf_log_set      vmlinux EXPORT_SYMBOL
++0xd9e69bb2    dapm_reg_event  vmlinux EXPORT_SYMBOL_GPL
++0xb2959203    snd_pcm_hw_constraint_pow2      vmlinux EXPORT_SYMBOL
++0x9754ec10    radix_tree_preload      vmlinux EXPORT_SYMBOL
++0xc8cd27b8    blkdev_ioctl    vmlinux EXPORT_SYMBOL_GPL
++0xd11c0dc1    __kernel_param_unlock   vmlinux EXPORT_SYMBOL
++0xcda686ec    input_set_keycode       vmlinux EXPORT_SYMBOL
++0xc69c2d23    subsys_virtual_register vmlinux EXPORT_SYMBOL_GPL
++0x4eb8fe91    drm_gem_free_mmap_offset        vmlinux EXPORT_SYMBOL
++0x61cdf6e6    nfc_hci_allocate_device vmlinux EXPORT_SYMBOL
++0x2dda642f    __dynamic_netdev_dbg    vmlinux EXPORT_SYMBOL
++0x890dc2ed    idr_alloc_cyclic        vmlinux EXPORT_SYMBOL
++0x5cf6db68    crypto_register_instance        vmlinux EXPORT_SYMBOL_GPL
++0x93bd657f    crypto_alloc_tfm        vmlinux EXPORT_SYMBOL_GPL
++0x9c48a3ba    bdi_destroy     vmlinux EXPORT_SYMBOL
++0x29047f1a    __i2c_board_lock        vmlinux EXPORT_SYMBOL_GPL
++0x02e49d29    tty_ldisc_flush vmlinux EXPORT_SYMBOL_GPL
++0xb06d489b    skb_tstamp_tx   vmlinux EXPORT_SYMBOL_GPL
++0xe66452ab    dql_init        vmlinux EXPORT_SYMBOL
++0x69e27c7a    bitmap_copy_le  vmlinux EXPORT_SYMBOL
++0x4dec6038    memscan vmlinux EXPORT_SYMBOL
++0xa9148d85    mark_buffer_dirty       vmlinux EXPORT_SYMBOL
++0x304b568f    get_super       vmlinux EXPORT_SYMBOL
++0x00801678    flush_scheduled_work    vmlinux EXPORT_SYMBOL
++0xb6115ca3    tty_set_operations      vmlinux EXPORT_SYMBOL
++0x6d6cb9ad    ieee80211_operating_class_to_band       vmlinux EXPORT_SYMBOL
++0x32e1f29c    skb_copy_and_csum_bits  vmlinux EXPORT_SYMBOL
++0x776c599d    idma_reg_addr_init      vmlinux EXPORT_SYMBOL_GPL
++0xef9f2dc8    ll_rw_block     vmlinux EXPORT_SYMBOL
++0x13014091    block_write_begin       vmlinux EXPORT_SYMBOL
++0x93226faa    irq_domain_associate_many       vmlinux EXPORT_SYMBOL_GPL
++0x756a4248    st_sensors_read_info_raw        vmlinux EXPORT_SYMBOL
++0x04339915    iio_update_buffers      vmlinux EXPORT_SYMBOL_GPL
++0x55784228    regmap_irq_get_virq     vmlinux EXPORT_SYMBOL_GPL
++0xbc25aac9    ump_dd_phys_blocks_get  vmlinux EXPORT_SYMBOL
++0xe1761617    security_inet_conn_request      vmlinux EXPORT_SYMBOL
++0x1268f357    resume_device_irqs      vmlinux EXPORT_SYMBOL_GPL
++0xbe2e3b75    kstrtos8        vmlinux EXPORT_SYMBOL
++0x124f2056    crypto_get_attr_type    vmlinux EXPORT_SYMBOL_GPL
++0x2fc54b62    nfnetlink_send  vmlinux EXPORT_SYMBOL_GPL
++0x9479479b    wm_hubs_hpr_mux vmlinux EXPORT_SYMBOL_GPL
++0x49e22268    snd_soc_info_volsw_s8   vmlinux EXPORT_SYMBOL_GPL
++0x329aef1b    crypto_alloc_aead       vmlinux EXPORT_SYMBOL_GPL
++0x851d17d2    crypto_spawn_tfm2       vmlinux EXPORT_SYMBOL_GPL
++0xce6a9d9a    trace_current_buffer_discard_commit     vmlinux EXPORT_SYMBOL_GPL
++0x50fad434    round_jiffies_up        vmlinux EXPORT_SYMBOL_GPL
++0xf7f16b3f    input_get_new_minor     vmlinux EXPORT_SYMBOL
++0x26c90ea4    scsi_eh_get_sense       vmlinux EXPORT_SYMBOL_GPL
++0x75e49326    device_create_bin_file  vmlinux EXPORT_SYMBOL_GPL
++0x113c622e    dev_set_mac_address     vmlinux EXPORT_SYMBOL
++0xe13ad642    sk_receive_skb  vmlinux EXPORT_SYMBOL
++0xf5c05914    generic_segment_checks  vmlinux EXPORT_SYMBOL
++0xd0f36f0d    audit_log_format        vmlinux EXPORT_SYMBOL
++0xdbaf59ef    v4l2_m2m_mmap   vmlinux EXPORT_SYMBOL
++0xde520229    serio_open      vmlinux EXPORT_SYMBOL
++0xc5714a65    spi_master_suspend      vmlinux EXPORT_SYMBOL_GPL
++0x22b325d5    kd_mksound      vmlinux EXPORT_SYMBOL
++0x6d2fc5a6    net_namespace_list      vmlinux EXPORT_SYMBOL_GPL
++0x9f6381e8    sock_register   vmlinux EXPORT_SYMBOL
++0xf1806da9    idr_find_slowpath       vmlinux EXPORT_SYMBOL
++0x5ae5be44    lg_lock_init    vmlinux EXPORT_SYMBOL
++0x2d307e05    vb2_ioctl_qbuf  vmlinux EXPORT_SYMBOL_GPL
++0xaad6c827    serio_close     vmlinux EXPORT_SYMBOL
++0x8b092f05    loop_register_transfer  vmlinux EXPORT_SYMBOL
++0x3c967a5a    device_set_wakeup_enable        vmlinux EXPORT_SYMBOL_GPL
++0xc34b9b1f    regulator_get_bypass_regmap     vmlinux EXPORT_SYMBOL_GPL
++0xde9cc521    pinctrl_unregister      vmlinux EXPORT_SYMBOL_GPL
++0xd1c5bc52    __cfg80211_send_deauth  vmlinux EXPORT_SYMBOL
++0x126ad73c    inet6_register_protosw  vmlinux EXPORT_SYMBOL
++0x5ce3b588    nfnl_lock       vmlinux EXPORT_SYMBOL_GPL
++0xdc197993    netif_set_real_num_tx_queues    vmlinux EXPORT_SYMBOL
++0xd4d07dc9    netif_set_real_num_rx_queues    vmlinux EXPORT_SYMBOL
++0xbdc3f3e4    dev_set_group   vmlinux EXPORT_SYMBOL
++0xb4176982    proc_remove     vmlinux EXPORT_SYMBOL
++0x663e9182    end_buffer_async_write  vmlinux EXPORT_SYMBOL
++0x3d517179    phy_register_fixup_for_uid      vmlinux EXPORT_SYMBOL
++0xb4709322    scsi_dev_info_add_list  vmlinux EXPORT_SYMBOL
++0x9dd34b62    drm_mm_insert_node_in_range     vmlinux EXPORT_SYMBOL
++0x69b18f43    rfc1042_header  vmlinux EXPORT_SYMBOL
++0x50097088    security_tun_dev_free_security  vmlinux EXPORT_SYMBOL
++0x050c08c1    vfs_writev      vmlinux EXPORT_SYMBOL
++0xd6b5a293    iio_buffer_init vmlinux EXPORT_SYMBOL
++0x811e0359    sdio_get_host_pm_caps   vmlinux EXPORT_SYMBOL_GPL
++0x9062c322    ring_buffer_consume     vmlinux EXPORT_SYMBOL_GPL
++0x1c5b1f28    irq_free_descs  vmlinux EXPORT_SYMBOL_GPL
++0xf2791baa    cgroup_unload_subsys    vmlinux EXPORT_SYMBOL_GPL
++0xe43274bc    proc_dointvec   vmlinux EXPORT_SYMBOL
++0xe8948e95    mmc_stop_bkops  vmlinux EXPORT_SYMBOL
++0xa2a5fd77    inet_ehash_secret       vmlinux EXPORT_SYMBOL
++0x2363e5bf    __inet_lookup_established       vmlinux EXPORT_SYMBOL_GPL
++0x3eeb1d5e    netdev_alert    vmlinux EXPORT_SYMBOL
++0x26ad413b    netdev_has_any_upper_dev        vmlinux EXPORT_SYMBOL
++0x7604b234    udp_lib_rehash  vmlinux EXPORT_SYMBOL
++0x5e5d53d3    udp_lib_unhash  vmlinux EXPORT_SYMBOL
++0x2b12925d    cpumask_next_and        vmlinux EXPORT_SYMBOL
++0x05495392    hid_debug       vmlinux EXPORT_SYMBOL_GPL
++0x1d1ca867    pm_stay_awake   vmlinux EXPORT_SYMBOL_GPL
++0x8c1a19df    device_show_ulong       vmlinux EXPORT_SYMBOL_GPL
++0x46940ff4    set_ras_addr_hook       vmlinux EXPORT_SYMBOL_GPL
++0x6088da85    nf_hook_slow    vmlinux EXPORT_SYMBOL
++0xce5ac24f    zlib_inflate_workspacesize      vmlinux EXPORT_SYMBOL
++0x2e73d9a1    v4l2_chip_ident_i2c_client      vmlinux EXPORT_SYMBOL
++0x3783cdae    drm_open        vmlinux EXPORT_SYMBOL
++0x5404b1e7    tcp_recvmsg     vmlinux EXPORT_SYMBOL
++0x47b90df9    snd_pcm_limit_hw_rates  vmlinux EXPORT_SYMBOL
++0x63baba6b    irq_alloc_generic_chip  vmlinux EXPORT_SYMBOL_GPL
++0xace5c0fc    usb_bus_list    vmlinux EXPORT_SYMBOL_GPL
++0xe8b63ace    radix_tree_range_tag_if_tagged  vmlinux EXPORT_SYMBOL
++0x8d8b6353    proc_dointvec_userhz_jiffies    vmlinux EXPORT_SYMBOL
++0x7ec5c02b    console_start   vmlinux EXPORT_SYMBOL
++0x1a1aebf8    s3c_adc_start   vmlinux EXPORT_SYMBOL_GPL
++0xffc6c87a    drm_detect_monitor_audio        vmlinux EXPORT_SYMBOL
++0xe1371ad4    tcp_simple_retransmit   vmlinux EXPORT_SYMBOL
++0x0f18b144    inet_csk_bind_conflict  vmlinux EXPORT_SYMBOL_GPL
++0x708e56bd    xt_register_match       vmlinux EXPORT_SYMBOL
++0xf3526269    proc_set_user   vmlinux EXPORT_SYMBOL
++0x752dff9d    anon_inode_getfile      vmlinux EXPORT_SYMBOL_GPL
++0xcd10fb11    simple_dir_inode_operations     vmlinux EXPORT_SYMBOL
++0x708bd95d    irq_domain_xlate_onetwocell     vmlinux EXPORT_SYMBOL_GPL
++0x122043a8    of_find_node_with_property      vmlinux EXPORT_SYMBOL
++0xb3453966    vb2_fop_release vmlinux EXPORT_SYMBOL_GPL
++0x59dddb40    ump_dd_reference_add    vmlinux EXPORT_SYMBOL
++0xe8bcc079    snd_soc_codec_set_cache_io      vmlinux EXPORT_SYMBOL_GPL
++0x67ae5cfb    dmam_pool_create        vmlinux EXPORT_SYMBOL
++0x1e7f65cb    vb2_mmap        vmlinux EXPORT_SYMBOL_GPL
++0xb33ff162    __find_get_block        vmlinux EXPORT_SYMBOL
++0x23a997f4    dcache_dir_open vmlinux EXPORT_SYMBOL
++0x3f4547a7    put_unused_fd   vmlinux EXPORT_SYMBOL
++0xd2555f19    jiffies_64_to_clock_t   vmlinux EXPORT_SYMBOL
++0xef969c64    input_mt_get_slot_by_key        vmlinux EXPORT_SYMBOL
++0x2b547fec    genphy_suspend  vmlinux EXPORT_SYMBOL
++0x0a04ac5b    subsys_system_register  vmlinux EXPORT_SYMBOL_GPL
++0x919a5e62    inet6_lookup_listener   vmlinux EXPORT_SYMBOL_GPL
++0xece784c2    rb_first        vmlinux EXPORT_SYMBOL
++0xc72e1233    __trace_bprintk vmlinux EXPORT_SYMBOL_GPL
++0x6a5ecb18    unregister_module_notifier      vmlinux EXPORT_SYMBOL
++0x19f115c3    flush_delayed_work      vmlinux EXPORT_SYMBOL
++0xf82f5060    usbnet_read_cmd vmlinux EXPORT_SYMBOL_GPL
++0xf3e09d59    dev_pm_qos_expose_latency_limit vmlinux EXPORT_SYMBOL_GPL
++0xfc4cb906    exynos_drm_subdrv_unregister    vmlinux EXPORT_SYMBOL_GPL
++0x04911106    of_dma_simple_xlate     vmlinux EXPORT_SYMBOL_GPL
++0x7211e749    nf_conntrack_hash_check_insert  vmlinux EXPORT_SYMBOL_GPL
++0x68b80336    zero_fill_bio   vmlinux EXPORT_SYMBOL
++0xe83fad56    mmc_switch      vmlinux EXPORT_SYMBOL_GPL
++0xa5a8337c    scsi_cmd_print_sense_hdr        vmlinux EXPORT_SYMBOL
++0x8b08c5c1    unix_peer_get   vmlinux EXPORT_SYMBOL_GPL
++0xef3b173b    audit_log_task_info     vmlinux EXPORT_SYMBOL
++0xacc26098    iio_read_const_attr     vmlinux EXPORT_SYMBOL
++0x47d7d62e    mmc_resume_host vmlinux EXPORT_SYMBOL
++0x323758b8    v4l2_spi_subdev_init    vmlinux EXPORT_SYMBOL_GPL
++0xbaa5b6b2    bus_register    vmlinux EXPORT_SYMBOL_GPL
++0xf39ab86b    tcp_syn_ack_timeout     vmlinux EXPORT_SYMBOL
++0xe73dda41    __nf_ct_ext_add_length  vmlinux EXPORT_SYMBOL
++0xc4ff89ae    nf_log_unregister       vmlinux EXPORT_SYMBOL
++0xd8e38717    d_hash_and_lookup       vmlinux EXPORT_SYMBOL
++0x63193a50    generic_file_buffered_write     vmlinux EXPORT_SYMBOL
++0xcce7df45    iio_alloc_pollfunc      vmlinux EXPORT_SYMBOL_GPL
++0x24b0f90c    of_clk_get_by_name      vmlinux EXPORT_SYMBOL
++0x3fb35146    mmc_alloc_host  vmlinux EXPORT_SYMBOL
++0xe6099979    scsi_eh_ready_devs      vmlinux EXPORT_SYMBOL_GPL
++0x986e6135    fb_pad_unaligned_buffer vmlinux EXPORT_SYMBOL
++0xc1c2dd09    __hw_addr_flush vmlinux EXPORT_SYMBOL
++0xae249a24    snd_register_device_for_dev     vmlinux EXPORT_SYMBOL
++0xea054b22    nla_policy_len  vmlinux EXPORT_SYMBOL
++0xd92afabe    bitmap_clear    vmlinux EXPORT_SYMBOL
++0x80f48353    fsync_bdev      vmlinux EXPORT_SYMBOL
++0x71930ed3    of_property_read_string vmlinux EXPORT_SYMBOL_GPL
++0x570f339b    thermal_cooling_device_register vmlinux EXPORT_SYMBOL_GPL
++0xcfcdd86a    input_open_device       vmlinux EXPORT_SYMBOL
++0x84ac53cc    drm_fb_helper_single_add_all_connectors vmlinux EXPORT_SYMBOL
++0x0e3edf75    regulator_set_bypass_regmap     vmlinux EXPORT_SYMBOL_GPL
++0xfe990052    gpio_free       vmlinux EXPORT_SYMBOL_GPL
++0x0b63a348    cfg80211_wext_giwrange  vmlinux EXPORT_SYMBOL_GPL
++0x6d815a8f    ip6_dst_lookup  vmlinux EXPORT_SYMBOL_GPL
++0x40a9b349    vzalloc vmlinux EXPORT_SYMBOL
++0xc2f9c045    timespec_to_jiffies     vmlinux EXPORT_SYMBOL
++0x54159824    iio_push_event  vmlinux EXPORT_SYMBOL
++0x94f95b4e    i2c_new_device  vmlinux EXPORT_SYMBOL_GPL
++0xe04e6d60    device_for_each_child   vmlinux EXPORT_SYMBOL_GPL
++0x5eafb8e9    drm_mode_set_name       vmlinux EXPORT_SYMBOL
++0x3b0a974f    arm_iommu_release_mapping       vmlinux EXPORT_SYMBOL_GPL
++0xed76ba4a    hci_resume_dev  vmlinux EXPORT_SYMBOL
++0x9cfaab5e    media_device_unregister vmlinux EXPORT_SYMBOL_GPL
++0x5783d440    pm_generic_poweroff_late        vmlinux EXPORT_SYMBOL_GPL
++0x59c8991b    nci_allocate_device     vmlinux EXPORT_SYMBOL
++0x11089ac7    _ctype  vmlinux EXPORT_SYMBOL
++0x66d480cb    blk_get_queue   vmlinux EXPORT_SYMBOL
++0x60b78a66    bd_set_size     vmlinux EXPORT_SYMBOL
++0x71f34013    __mem_cgroup_count_vm_event     vmlinux EXPORT_SYMBOL
++0x2d45b494    pm_vt_switch_unregister vmlinux EXPORT_SYMBOL
++0xca7d8764    kthread_freezable_should_stop   vmlinux EXPORT_SYMBOL_GPL
++0x03b3002e    st_sensors_enable_events        vmlinux EXPORT_SYMBOL
++0xfc937fcb    usb_add_gadget_udc      vmlinux EXPORT_SYMBOL_GPL
++0x420323e6    i2c_dp_aux_add_bus      vmlinux EXPORT_SYMBOL
++0xd6ef94db    udp_proc_unregister     vmlinux EXPORT_SYMBOL
++0x37f614b7    __kfifo_len_r   vmlinux EXPORT_SYMBOL
++0xac6e0f5a    power_supply_get_by_name        vmlinux EXPORT_SYMBOL_GPL
++0x86047552    inet_sk_rebuild_header  vmlinux EXPORT_SYMBOL
++0x3c878c55    skb_copy        vmlinux EXPORT_SYMBOL
++0xe5b6e62e    snd_pcm_stop    vmlinux EXPORT_SYMBOL
++0x7593d385    div64_s64       vmlinux EXPORT_SYMBOL
++0x27864d57    memparse        vmlinux EXPORT_SYMBOL
++0xe8f9c617    block_truncate_page     vmlinux EXPORT_SYMBOL
++0xbc036e9e    generic_write_checks    vmlinux EXPORT_SYMBOL
++0x4f68e5c9    do_gettimeofday vmlinux EXPORT_SYMBOL
++0xa6715115    do_settimeofday vmlinux EXPORT_SYMBOL
++0xd9efbe4c    input_inject_event      vmlinux EXPORT_SYMBOL
++0x3dc565d9    drm_mm_insert_node_generic      vmlinux EXPORT_SYMBOL
++0x0c58a8cd    netdev_increment_features       vmlinux EXPORT_SYMBOL
++0xb3c487b6    uart_match_port vmlinux EXPORT_SYMBOL
++0x208f2017    brcmu_pktq_pdeq_match   drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0xbc455bde    cfg80211_pmksa_candidate_notify vmlinux EXPORT_SYMBOL
++0x3bef03b9    flow_cache_lookup       vmlinux EXPORT_SYMBOL
++0x5002ec2f    __splice_from_pipe      vmlinux EXPORT_SYMBOL
++0x863c552c    cache_firmware  vmlinux EXPORT_SYMBOL_GPL
++0xe5274b72    unregister_net_sysctl_table     vmlinux EXPORT_SYMBOL_GPL
++0xa197b1ff    ieee80211_get_mesh_hdrlen       vmlinux EXPORT_SYMBOL
++0x3a9592df    __nf_ct_ext_destroy     vmlinux EXPORT_SYMBOL
++0xa2c640f9    sysfs_add_file_to_group vmlinux EXPORT_SYMBOL_GPL
++0x487d9343    param_ops_ushort        vmlinux EXPORT_SYMBOL
++0x58804ca9    sdio_align_size vmlinux EXPORT_SYMBOL_GPL
++0xa09e1f4c    cpufreq_register_governor       vmlinux EXPORT_SYMBOL_GPL
++0x8ee7279a    ump_dd_size_get vmlinux EXPORT_SYMBOL
++0xfb858f46    tty_write_room  vmlinux EXPORT_SYMBOL
++0x3d715445    dev_trans_start vmlinux EXPORT_SYMBOL
++0xa381944f    dql_reset       vmlinux EXPORT_SYMBOL
++0x8f99ae4c    blk_register_region     vmlinux EXPORT_SYMBOL
++0xa8242495    bio_put vmlinux EXPORT_SYMBOL
++0x488d1fd7    task_tgid_nr_ns vmlinux EXPORT_SYMBOL
++0xc8d55b31    usb_unlocked_disable_lpm        vmlinux EXPORT_SYMBOL_GPL
++0x10ee20bb    default_blu     vmlinux EXPORT_SYMBOL
++0x57575f08    dmaengine_put   vmlinux EXPORT_SYMBOL
++0x60577ee3    ip6_expire_frag_queue   vmlinux EXPORT_SYMBOL
++0xdb5d34e0    rcu_batches_completed_preempt   vmlinux EXPORT_SYMBOL_GPL
++0xec6f4d80    each_symbol_section     vmlinux EXPORT_SYMBOL_GPL
++0xea6e3003    of_find_compatible_node vmlinux EXPORT_SYMBOL
++0x0d95dc3b    video_ioctl2    vmlinux EXPORT_SYMBOL
++0x26156aad    input_alloc_absinfo     vmlinux EXPORT_SYMBOL
++0x244b53b3    scsi_is_target_device   vmlinux EXPORT_SYMBOL
++0xd0cf28c6    sk_dst_check    vmlinux EXPORT_SYMBOL
++0xa5dd45f3    prandom_bytes_state     vmlinux EXPORT_SYMBOL
++0x6a76f3ac    blk_iopoll_enable       vmlinux EXPORT_SYMBOL
++0x17e1907b    inode_needs_sync        vmlinux EXPORT_SYMBOL
++0x9c6ac1ed    grab_cache_page_nowait  vmlinux EXPORT_SYMBOL
++0xe7a81967    audit_log_secctx        vmlinux EXPORT_SYMBOL
++0x2babe81f    __wake_up_sync_key      vmlinux EXPORT_SYMBOL_GPL
++0x4adaf0f3    v4l2_ctrl_query_menu_valid_items        vmlinux EXPORT_SYMBOL
++0xcb6f482d    dev_getfirstbyhwtype    vmlinux EXPORT_SYMBOL
++0xb23df37e    wake_up_process vmlinux EXPORT_SYMBOL
++0x25820c64    fs_overflowuid  vmlinux EXPORT_SYMBOL
++0x24ddf922    scsi_internal_device_block      vmlinux EXPORT_SYMBOL_GPL
++0x1079ac8f    drm_framebuffer_remove  vmlinux EXPORT_SYMBOL
++0x160f2f7e    of_phy_simple_xlate     vmlinux EXPORT_SYMBOL_GPL
++0xe669c8a2    __nf_ct_refresh_acct    vmlinux EXPORT_SYMBOL_GPL
++0xa2f20d05    skb_dequeue_tail        vmlinux EXPORT_SYMBOL
++0x19a025aa    __get_user_pages        vmlinux EXPORT_SYMBOL
++0x286acd69    free_css_id     vmlinux EXPORT_SYMBOL_GPL
++0x404c4f08    __module_address        vmlinux EXPORT_SYMBOL_GPL
++0x195d329a    hidinput_count_leds     vmlinux EXPORT_SYMBOL_GPL
++0x280c859a    input_ff_erase  vmlinux EXPORT_SYMBOL_GPL
++0x886d02da    scsi_target_resume      vmlinux EXPORT_SYMBOL
++0x8f31e347    inet_stream_ops vmlinux EXPORT_SYMBOL
++0x9b0dcfa2    qdisc_reset     vmlinux EXPORT_SYMBOL
++0xd2da1048    register_netdevice_notifier     vmlinux EXPORT_SYMBOL
++0x1b5fff19    blk_complete_request    vmlinux EXPORT_SYMBOL
++0x808ec1a3    crypto_alg_tested       vmlinux EXPORT_SYMBOL_GPL
++0xda920cd9    bio_unmap_user  vmlinux EXPORT_SYMBOL
++0xe769232e    sprint_symbol_no_offset vmlinux EXPORT_SYMBOL_GPL
++0x2b7a6de8    syscon_regmap_lookup_by_phandle vmlinux EXPORT_SYMBOL_GPL
++0x9728e93f    of_dma_controller_register      vmlinux EXPORT_SYMBOL_GPL
++0x1b61c5b3    pwm_config      vmlinux EXPORT_SYMBOL_GPL
++0x39bdf0f0    nci_free_device vmlinux EXPORT_SYMBOL
++0xe3a306b5    udp_seq_open    vmlinux EXPORT_SYMBOL
++0x38c97d50    idr_get_next    vmlinux EXPORT_SYMBOL
++0xeaacc92f    fail_migrate_page       vmlinux EXPORT_SYMBOL
++0x4cdb3178    ns_to_timeval   vmlinux EXPORT_SYMBOL
++0xc78d0953    ehci_init_driver        vmlinux EXPORT_SYMBOL_GPL
++0xcd6ff125    nf_ct_expect_register_notifier  vmlinux EXPORT_SYMBOL_GPL
++0x721b1851    skip_spaces     vmlinux EXPORT_SYMBOL
++0x0c0c015e    ring_buffer_swap_cpu    vmlinux EXPORT_SYMBOL_GPL
++0x76d451c4    add_taint       vmlinux EXPORT_SYMBOL
++0x1c2596ba    regmap_async_complete_cb        vmlinux EXPORT_SYMBOL_GPL
++0x60a32ea9    pm_power_off    vmlinux EXPORT_SYMBOL
++0x2b911208    __neigh_for_each_release        vmlinux EXPORT_SYMBOL
++0x0bc7e6ff    blk_queue_init_tags     vmlinux EXPORT_SYMBOL
++0xa666946b    bdget   vmlinux EXPORT_SYMBOL
++0x885a4cc9    bdput   vmlinux EXPORT_SYMBOL
++0x2517dbbb    fsstack_copy_inode_size vmlinux EXPORT_SYMBOL_GPL
++0x7d4ed855    iio_trigger_poll_chained        vmlinux EXPORT_SYMBOL
++0x561e4b77    irq_of_parse_and_map    vmlinux EXPORT_SYMBOL_GPL
++0x308efc55    spi_busnum_to_master    vmlinux EXPORT_SYMBOL_GPL
++0xe862c4b7    dpm_suspend_start       vmlinux EXPORT_SYMBOL_GPL
++0xd728282d    device_initialize       vmlinux EXPORT_SYMBOL_GPL
++0xf6b77868    nf_conntrack_untracked  vmlinux EXPORT_SYMBOL
++0xed9f8e6d    kstrtos16       vmlinux EXPORT_SYMBOL
++0xfb32b30f    ring_buffer_read_prepare_sync   vmlinux EXPORT_SYMBOL_GPL
++0x846bcc01    dm_table_get    vmlinux EXPORT_SYMBOL
++0x1416333b    tcf_em_register vmlinux EXPORT_SYMBOL
++0x19546cac    snd_soc_cache_read      vmlinux EXPORT_SYMBOL_GPL
++0xfd2f4f20    snd_soc_info_volsw_ext  vmlinux EXPORT_SYMBOL_GPL
++0x6c749afe    __tracepoint_block_unplug       vmlinux EXPORT_SYMBOL_GPL
++0x9c86ede0    fs_kobj vmlinux EXPORT_SYMBOL_GPL
++0x796c2d48    dm_get_md       vmlinux EXPORT_SYMBOL_GPL
++0xf8fbb4f0    __bad_xchg      vmlinux EXPORT_SYMBOL
++0xc40f284c    nf_ct_helper_hsize      vmlinux EXPORT_SYMBOL_GPL
++0x24428be5    strncpy_from_user       vmlinux EXPORT_SYMBOL
++0x6d74d462    crypto_alloc_ablkcipher vmlinux EXPORT_SYMBOL_GPL
++0x0b96efa8    bio_init        vmlinux EXPORT_SYMBOL
++0x7278d328    all_vm_events   vmlinux EXPORT_SYMBOL_GPL
++0x41814cb8    dirty_writeback_interval        vmlinux EXPORT_SYMBOL_GPL
++0x1c32da2a    iio_enum_available_read vmlinux EXPORT_SYMBOL_GPL
++0xcda91c46    drm_mode_debug_printmodeline    vmlinux EXPORT_SYMBOL
++0xa9cae71a    inet6_hash_connect      vmlinux EXPORT_SYMBOL_GPL
++0x92f5d840    gnet_stats_copy_rate_est        vmlinux EXPORT_SYMBOL
++0x17f61c70    skb_partial_csum_set    vmlinux EXPORT_SYMBOL_GPL
++0xb86cf818    create_empty_buffers    vmlinux EXPORT_SYMBOL
++0x26332c2f    init_special_inode      vmlinux EXPORT_SYMBOL
++0xd0720a17    on_each_cpu_cond        vmlinux EXPORT_SYMBOL
++0x870713f0    iommu_detach_group      vmlinux EXPORT_SYMBOL_GPL
++0x00c8b1c1    sdio_enable_func        vmlinux EXPORT_SYMBOL_GPL
++0x22f907ec    pm_runtime_no_callbacks vmlinux EXPORT_SYMBOL_GPL
++0x8d4234e8    subsys_dev_iter_next    vmlinux EXPORT_SYMBOL_GPL
++0x706fc943    mali_pmu_powerup        vmlinux EXPORT_SYMBOL
++0xf24fbd54    cfg80211_mgmt_tx_status vmlinux EXPORT_SYMBOL
++0xa8bae0ab    inet_frag_destroy       vmlinux EXPORT_SYMBOL
++0xca1aff2d    ipv4_sk_update_pmtu     vmlinux EXPORT_SYMBOL_GPL
++0x539973c5    skb_make_writable       vmlinux EXPORT_SYMBOL
++0x2eeceb42    sk_chk_filter   vmlinux EXPORT_SYMBOL
++0x8f595b11    snd_major       vmlinux EXPORT_SYMBOL
++0xf8433bfd    pipe_to_file    vmlinux EXPORT_SYMBOL
++0x0dc1d65b    __dec_zone_page_state   vmlinux EXPORT_SYMBOL
++0x95ce193b    __inc_zone_page_state   vmlinux EXPORT_SYMBOL
++0x736c2d7c    __mod_zone_page_state   vmlinux EXPORT_SYMBOL
++0xab6babaf    pm_qos_request  vmlinux EXPORT_SYMBOL_GPL
++0xeed6cc4b    flush_kthread_worker    vmlinux EXPORT_SYMBOL_GPL
++0xa5cef8ad    release_resource        vmlinux EXPORT_SYMBOL
++0x4584b8a3    iio_push_to_buffers     vmlinux EXPORT_SYMBOL_GPL
++0xc79bcd36    dm_vcalloc      vmlinux EXPORT_SYMBOL
++0xa7dd8c46    ump_dd_phys_block_get   vmlinux EXPORT_SYMBOL
++0x83bd3297    brioctl_set     vmlinux EXPORT_SYMBOL
++0x09e913c1    snd_pcm_alt_chmaps      vmlinux EXPORT_SYMBOL_GPL
++0xbf33e600    vm_insert_pfn   vmlinux EXPORT_SYMBOL
++0xda050109    irq_domain_add_nomap    vmlinux EXPORT_SYMBOL_GPL
++0xfcaa04a0    out_of_line_wait_on_bit_lock    vmlinux EXPORT_SYMBOL
++0xa7bb71ae    input_set_abs_params    vmlinux EXPORT_SYMBOL
++0x22f9a7f4    spi_bus_unlock  vmlinux EXPORT_SYMBOL_GPL
++0x2ea5ad9c    device_schedule_callback_owner  vmlinux EXPORT_SYMBOL_GPL
++0x4c511235    drm_edid_is_valid       vmlinux EXPORT_SYMBOL
++0x3939f8f0    rfkill_pause_polling    vmlinux EXPORT_SYMBOL
++0xebc7bcd9    xfrm_state_alloc        vmlinux EXPORT_SYMBOL
++0x85670f1d    rtnl_is_locked  vmlinux EXPORT_SYMBOL
++0x726d45d3    fat_remove_entries      vmlinux EXPORT_SYMBOL_GPL
++0xd963ea55    page_symlink    vmlinux EXPORT_SYMBOL
++0xa26d9b4f    workqueue_congested     vmlinux EXPORT_SYMBOL_GPL
++0xf7cd6b11    freq_reg_info   vmlinux EXPORT_SYMBOL
++0x764dafa5    __xfrm_route_forward    vmlinux EXPORT_SYMBOL
++0xd317cce2    snd_soc_put_volsw_sx    vmlinux EXPORT_SYMBOL_GPL
++0x587ba0c8    snd_soc_get_volsw_s8    vmlinux EXPORT_SYMBOL_GPL
++0x5dda7051    snd_soc_put_volsw_s8    vmlinux EXPORT_SYMBOL_GPL
++0xd6b61c7b    snd_soc_get_volsw_sx    vmlinux EXPORT_SYMBOL_GPL
++0x9f0664bf    dm_get_queue_limits     vmlinux EXPORT_SYMBOL_GPL
++0x0364983f    gen_replace_estimator   vmlinux EXPORT_SYMBOL
++0x2f03fc4b    security_secmark_refcount_inc   vmlinux EXPORT_SYMBOL
++0x19bd383b    security_secmark_refcount_dec   vmlinux EXPORT_SYMBOL
++0xc22b50ad    param_set_bint  vmlinux EXPORT_SYMBOL
++0x21315700    param_get_bool  vmlinux EXPORT_SYMBOL
++0x3eae292f    param_set_byte  vmlinux EXPORT_SYMBOL
++0xcea1a019    dw_mci_suspend  vmlinux EXPORT_SYMBOL
++0x8657c2d4    spi_bitbang_setup       vmlinux EXPORT_SYMBOL_GPL
++0xb13fbb9a    scsi_target_unblock     vmlinux EXPORT_SYMBOL_GPL
++0xbf3a015f    brcmf_sdio_remove       drivers/net/wireless/brcm80211/brcmfmac/brcmfmac        EXPORT_SYMBOL
++0xeb1c3628    nf_ipv6_ops     vmlinux EXPORT_SYMBOL_GPL
++0x9fdecc31    unregister_netdevice_many       vmlinux EXPORT_SYMBOL
++0x75308bb0    blk_queue_logical_block_size    vmlinux EXPORT_SYMBOL
++0x2fe50bdf    init_srcu_struct        vmlinux EXPORT_SYMBOL_GPL
++0xfba64859    rtc_device_unregister   vmlinux EXPORT_SYMBOL_GPL
++0xbd10afa1    drm_platform_init       vmlinux EXPORT_SYMBOL
++0xa1ceb496    drm_platform_exit       vmlinux EXPORT_SYMBOL
++0xd10d7d37    arp_tbl vmlinux EXPORT_SYMBOL
++0x9aa6cefb    __skb_recv_datagram     vmlinux EXPORT_SYMBOL
++0x0430401c    snd_soc_remove_platform vmlinux EXPORT_SYMBOL_GPL
++0xfe7c4287    nr_cpu_ids      vmlinux EXPORT_SYMBOL
++0x18b6fa40    v4l2_ctrl_add_ctrl      vmlinux EXPORT_SYMBOL
++0xb21d34e2    phy_attach      vmlinux EXPORT_SYMBOL
++0x67f7fd01    gpiochip_remove_pin_ranges      vmlinux EXPORT_SYMBOL_GPL
++0x5c9284a0    processor_id    vmlinux EXPORT_SYMBOL
++0x688e3c72    tcp_splice_read vmlinux EXPORT_SYMBOL
++0x9f7f32fe    xt_unregister_match     vmlinux EXPORT_SYMBOL
++0x2822f8fe    irq_setup_generic_chip  vmlinux EXPORT_SYMBOL_GPL
++0x8763d790    pm_genpd_syscore_switch vmlinux EXPORT_SYMBOL_GPL
++0xc898f9f7    css_depth       vmlinux EXPORT_SYMBOL_GPL
++0x95d97984    devm_regmap_init_spi    vmlinux EXPORT_SYMBOL_GPL
++0x32108723    devm_regmap_init_i2c    vmlinux EXPORT_SYMBOL_GPL
++0x824028e1    drm_master_get  vmlinux EXPORT_SYMBOL
++0x36e360e3    __hw_addr_add_multiple  vmlinux EXPORT_SYMBOL
++0x92e42550    snd_soc_jack_add_gpios  vmlinux EXPORT_SYMBOL_GPL
++0x9552bd34    crypto_unregister_algs  vmlinux EXPORT_SYMBOL_GPL
++0x70bd3119    simple_transaction_set  vmlinux EXPORT_SYMBOL
++0x5cf1e7e1    simple_transaction_get  vmlinux EXPORT_SYMBOL
++0x86b57862    find_pid_ns     vmlinux EXPORT_SYMBOL_GPL
++0x0b59c21c    st_gyro_common_probe    vmlinux EXPORT_SYMBOL
++0x3a4c6000    of_irq_to_resource      vmlinux EXPORT_SYMBOL_GPL
++0xcbc9557f    unregister_sysrq_key    vmlinux EXPORT_SYMBOL
++0xd85ac634    regulator_put   vmlinux EXPORT_SYMBOL_GPL
++0x56e75d47    klist_node_attached     vmlinux EXPORT_SYMBOL_GPL
++0xf0d6c49d    rfkill_alloc    vmlinux EXPORT_SYMBOL
++0xe118d3ca    __nf_conntrack_find     vmlinux EXPORT_SYMBOL_GPL
++0x67fa9d64    __nlmsg_put     vmlinux EXPORT_SYMBOL
++0xc5f839f2    lock_sock_nested        vmlinux EXPORT_SYMBOL
++0x92b57248    flush_work      vmlinux EXPORT_SYMBOL_GPL
++0x63aecd53    hid_add_device  vmlinux EXPORT_SYMBOL_GPL
++0x870e11ef    sdio_disable_func       vmlinux EXPORT_SYMBOL_GPL
++0xd6c99af7    devm_usb_put_phy        vmlinux EXPORT_SYMBOL_GPL
++0x60652b23    usbnet_cdc_bind vmlinux EXPORT_SYMBOL_GPL
++0x0f1fd032    scsi_free_command       vmlinux EXPORT_SYMBOL
++0x150d593e    platform_add_devices    vmlinux EXPORT_SYMBOL_GPL
++0xdc2235fd    device_show_bool        vmlinux EXPORT_SYMBOL_GPL
++0xe800ece3    __mmc_switch    vmlinux EXPORT_SYMBOL_GPL
++0x8650b7ba    usb_deregister  vmlinux EXPORT_SYMBOL_GPL
++0x83a82050    phy_ethtool_get_eee     vmlinux EXPORT_SYMBOL
++0xccb94d1a    phy_ethtool_set_eee     vmlinux EXPORT_SYMBOL
++0x1a81168a    drm_mm_dump_table       vmlinux EXPORT_SYMBOL
++0x04cda566    snd_interval_refine     vmlinux EXPORT_SYMBOL
++0x6b2dc060    dump_stack      vmlinux EXPORT_SYMBOL
++0x23476dca    crypto_alloc_instance   vmlinux EXPORT_SYMBOL_GPL
++0x31cd11aa    mpage_writepage vmlinux EXPORT_SYMBOL
++0xa219c44e    try_to_writeback_inodes_sb_nr   vmlinux EXPORT_SYMBOL
++0xd942d353    ring_buffer_record_off  vmlinux EXPORT_SYMBOL_GPL
++0x178768e1    set_security_override   vmlinux EXPORT_SYMBOL
++0x7930d225    of_device_is_compatible vmlinux EXPORT_SYMBOL
++0xa1fb703c    drm_mm_remove_node      vmlinux EXPORT_SYMBOL
++0x3fce0784    rdev_get_drvdata        vmlinux EXPORT_SYMBOL_GPL
++0x193f9832    nfc_allocate_device     vmlinux EXPORT_SYMBOL
++0xcefba9ae    raw_seq_start   vmlinux EXPORT_SYMBOL_GPL
++0x353b4dcf    nfnetlink_subsys_unregister     vmlinux EXPORT_SYMBOL_GPL
++0x1db53c10    dst_cow_metrics_generic vmlinux EXPORT_SYMBOL
++0x884c205c    mount_ns        vmlinux EXPORT_SYMBOL
++0x26b0e339    sdhci_disable_irq_wakeups       vmlinux EXPORT_SYMBOL_GPL
++0x69e3154c    rtc_read_time   vmlinux EXPORT_SYMBOL_GPL
++0xde6ff4ec    usb_get_function_instance       vmlinux EXPORT_SYMBOL_GPL
++0x0c29207f    netdev_master_upper_dev_get     vmlinux EXPORT_SYMBOL
++0x62d34ec2    kobject_del     vmlinux EXPORT_SYMBOL
++0x7489664f    crypto_unregister_shash vmlinux EXPORT_SYMBOL_GPL
++0x5ca7f0f8    crypto_unregister_ahash vmlinux EXPORT_SYMBOL_GPL
++0x86a4889a    kmalloc_order_trace     vmlinux EXPORT_SYMBOL
++0x0698cb23    drm_core_reclaim_buffers        vmlinux EXPORT_SYMBOL
++0x94478b76    nat_callforwarding_hook vmlinux EXPORT_SYMBOL_GPL
++0x6e4b8906    snd_ctl_find_numid      vmlinux EXPORT_SYMBOL
++0xb6a68816    find_last_bit   vmlinux EXPORT_SYMBOL
++0xc8d47bdb    inode_dio_done  vmlinux EXPORT_SYMBOL
++0xb9ca066f    poll_initwait   vmlinux EXPORT_SYMBOL
++0x193d48e0    trace_current_buffer_unlock_commit      vmlinux EXPORT_SYMBOL_GPL
++0x46a36032    unregister_console      vmlinux EXPORT_SYMBOL
++0xd0fbc335    vb2_get_vma     vmlinux EXPORT_SYMBOL_GPL
++0x6ebd302d    usb_reset_endpoint      vmlinux EXPORT_SYMBOL_GPL
++0x38a4f7ae    drm_format_num_planes   vmlinux EXPORT_SYMBOL
++0xc414c422    drm_vblank_offdelay     vmlinux EXPORT_SYMBOL
++0x96554810    register_keyboard_notifier      vmlinux EXPORT_SYMBOL_GPL
++0x2ec0f25c    nf_ct_helper_ext_add    vmlinux EXPORT_SYMBOL_GPL
++0xe745ec59    aead_geniv_free vmlinux EXPORT_SYMBOL_GPL
++0xd8e484f0    register_chrdev_region  vmlinux EXPORT_SYMBOL
++0xc58b6dd5    led_trigger_unregister_simple   vmlinux EXPORT_SYMBOL_GPL
++0x068f1d12    phy_disconnect  vmlinux EXPORT_SYMBOL
++0x9c518b55    regmap_update_bits      vmlinux EXPORT_SYMBOL_GPL
++0xc63f1b81    ieee80211_radiotap_iterator_next        vmlinux EXPORT_SYMBOL
++0x9744e080    inet_csk_reqsk_queue_prune      vmlinux EXPORT_SYMBOL_GPL
++0xb9ff0fd7    netdev_state_change     vmlinux EXPORT_SYMBOL
++0x310917fe    sort    vmlinux EXPORT_SYMBOL
++0xa8fef7bb    security_unix_may_send  vmlinux EXPORT_SYMBOL
++0x541bd60a    irq_work_run    vmlinux EXPORT_SYMBOL_GPL
++0x6c49c4f2    clockevents_notify      vmlinux EXPORT_SYMBOL_GPL
++0xe208ea98    hci_recv_stream_fragment        vmlinux EXPORT_SYMBOL
++0xe6c68334    ddebug_remove_module    vmlinux EXPORT_SYMBOL_GPL
++0xf8ae0cbf    kern_path       vmlinux EXPORT_SYMBOL
++0x6e9dd7bc    usb_sg_cancel   vmlinux EXPORT_SYMBOL_GPL
++0x7c05fd17    nf_register_queue_handler       vmlinux EXPORT_SYMBOL
++0x2a8db409    snd_soc_dai_set_tristate        vmlinux EXPORT_SYMBOL_GPL
++0x29b1c366    __sg_alloc_table        vmlinux EXPORT_SYMBOL
++0x9c3889f4    shrink_dcache_sb        vmlinux EXPORT_SYMBOL
++0x15692c87    param_ops_int   vmlinux EXPORT_SYMBOL
++0xd04e04f7    iio_update_demux        vmlinux EXPORT_SYMBOL_GPL
++0x105a7a58    dma_alloc_from_coherent vmlinux EXPORT_SYMBOL
++0xe4309905    syscore_resume  vmlinux EXPORT_SYMBOL_GPL
++0xab482a65    blkdev_issue_flush      vmlinux EXPORT_SYMBOL
++0x499043d3    crypto_init_queue       vmlinux EXPORT_SYMBOL_GPL
++0xca871be2    default_backing_dev_info        vmlinux EXPORT_SYMBOL_GPL
++0x3d5120d1    st_accel_common_probe   vmlinux EXPORT_SYMBOL
++0x44f5e8b5    of_allnodes     vmlinux EXPORT_SYMBOL
++0xf563353a    v4l2_subdev_link_validate       vmlinux EXPORT_SYMBOL_GPL
++0x011cf028    regulator_suspend_finish        vmlinux EXPORT_SYMBOL_GPL
++0x1b88e3fa    find_inode_number       vmlinux EXPORT_SYMBOL
++0xb2d307de    param_ops_short vmlinux EXPORT_SYMBOL
++0x0b586662    drm_gem_object_init     vmlinux EXPORT_SYMBOL
++0xaad6d92f    rfkill_init_sw_state    vmlinux EXPORT_SYMBOL
++0x4f4d4dc8    hci_unregister_dev      vmlinux EXPORT_SYMBOL
++0xa6970398    __kfifo_to_user_r       vmlinux EXPORT_SYMBOL
++0xf7f92f26    st_sensors_set_enable   vmlinux EXPORT_SYMBOL
++0x236bcb52    unregister_con_driver   vmlinux EXPORT_SYMBOL
++0x39898017    amba_device_put vmlinux EXPORT_SYMBOL_GPL
++0x8d28fc98    amba_device_add vmlinux EXPORT_SYMBOL_GPL
++0x3169d518    softnet_data    vmlinux EXPORT_SYMBOL
++0x5fc56a46    _raw_spin_unlock        vmlinux EXPORT_SYMBOL
++0xfe5d4bb2    sys_tz  vmlinux EXPORT_SYMBOL
++0x81ced62d    ip6_sk_redirect vmlinux EXPORT_SYMBOL_GPL
++0x9ffa3a75    netdev_max_backlog      vmlinux EXPORT_SYMBOL
++0xfa237e15    __skb_tx_hash   vmlinux EXPORT_SYMBOL
++0x1b701804    blk_init_queue  vmlinux EXPORT_SYMBOL
++0x474d3122    unlock_page     vmlinux EXPORT_SYMBOL
++0x4f98d766    cpu_pm_unregister_notifier      vmlinux EXPORT_SYMBOL_GPL
++0x76963409    lock_fb_info    vmlinux EXPORT_SYMBOL
++0x11e2ec12    flex_array_free_parts   vmlinux EXPORT_SYMBOL
++0x5ecb52ac    sdio_memcpy_fromio      vmlinux EXPORT_SYMBOL_GPL
++0xa4480afe    drm_sysfs_hotplug_event vmlinux EXPORT_SYMBOL
++0xeaab7f82    lcd_device_register     vmlinux EXPORT_SYMBOL
++0x0c12eee9    xfrm_unregister_type    vmlinux EXPORT_SYMBOL
++0x297f1a00    nf_ip_checksum  vmlinux EXPORT_SYMBOL
++0xd14bc4d9    sock_diag_save_cookie   vmlinux EXPORT_SYMBOL_GPL
++0xdd810ba9    snd_info_register       vmlinux EXPORT_SYMBOL
++0x773a9c94    blk_iopoll_enabled      vmlinux EXPORT_SYMBOL
++0xd704f458    jbd2_log_wait_commit    vmlinux EXPORT_SYMBOL
++0x22e82b9e    hrtimer_init_sleeper    vmlinux EXPORT_SYMBOL_GPL
++0x437e0518    eth_rebuild_header      vmlinux EXPORT_SYMBOL
++0x47fb2e90    neigh_compat_output     vmlinux EXPORT_SYMBOL
++0x0283dfe3    _snd_pcm_hw_params_any  vmlinux EXPORT_SYMBOL
++0xe2407fb6    user_path_at    vmlinux EXPORT_SYMBOL
++0x35d93ce8    cgroup_add_cftypes      vmlinux EXPORT_SYMBOL_GPL
++0x4ac62273    module_put      vmlinux EXPORT_SYMBOL
++0x2459bbcc    console_set_on_cmdline  vmlinux EXPORT_SYMBOL
++0xbec530ad    max8997_update_reg      vmlinux EXPORT_SYMBOL_GPL
++0x3255972d    hdmi_vendor_infoframe_pack      vmlinux EXPORT_SYMBOL
++0x8da61397    ip_tunnel_rcv   vmlinux EXPORT_SYMBOL_GPL
++0x3c44f68c    inode_get_bytes vmlinux EXPORT_SYMBOL
++0xd85cd67e    __wake_up       vmlinux EXPORT_SYMBOL
++0xcefe5c3b    usb_get_from_anchor     vmlinux EXPORT_SYMBOL_GPL
++0x9a858808    genphy_resume   vmlinux EXPORT_SYMBOL
++0x606ae2bc    drm_mm_debug_table      vmlinux EXPORT_SYMBOL
++0xed636ddf    nf_conntrack_helper_unregister  vmlinux EXPORT_SYMBOL_GPL
++0xc7a1840e    llist_add_batch vmlinux EXPORT_SYMBOL_GPL
++0x2787db00    vbin_printf     vmlinux EXPORT_SYMBOL_GPL
++0xfe59fc1b    security_d_instantiate  vmlinux EXPORT_SYMBOL
++0x6b8286e4    bio_reset       vmlinux EXPORT_SYMBOL
++0x86414ad5    vfs_mkdir       vmlinux EXPORT_SYMBOL
++0x87b883c7    i2c_for_each_dev        vmlinux EXPORT_SYMBOL_GPL
++0x26f81b6a    dev_driver_string       vmlinux EXPORT_SYMBOL
++0x1c787b32    eventfd_ctx_fileget     vmlinux EXPORT_SYMBOL_GPL
++0x01139ffc    max_mapnr       vmlinux EXPORT_SYMBOL
++0xec17ebb0    of_match_node   vmlinux EXPORT_SYMBOL
++0x69ce0071    usb_driver_claim_interface      vmlinux EXPORT_SYMBOL_GPL
++0x9cfd56c5    scsi_print_status       vmlinux EXPORT_SYMBOL
++0xdce6abcd    drm_gem_prime_handle_to_fd      vmlinux EXPORT_SYMBOL
++0x020f03b7    drm_sysfs_connector_remove      vmlinux EXPORT_SYMBOL
++0x2a8aa04e    pinctrl_add_gpio_range  vmlinux EXPORT_SYMBOL_GPL
++0x981dcc58    eventfd_fget    vmlinux EXPORT_SYMBOL_GPL
++0x7c995f04    dget_parent     vmlinux EXPORT_SYMBOL
++0x9a932b80    of_find_i2c_device_by_node      vmlinux EXPORT_SYMBOL
++0x2b460363    led_trigger_set vmlinux EXPORT_SYMBOL_GPL
++0x107733e3    wiphy_new       vmlinux EXPORT_SYMBOL
++0xd7b7598e    snd_pcm_mmap_data       vmlinux EXPORT_SYMBOL
++0x4e1636f1    mb_cache_create vmlinux EXPORT_SYMBOL
++0x70bec618    iunique vmlinux EXPORT_SYMBOL
++0x121d958a    unregister_die_notifier vmlinux EXPORT_SYMBOL_GPL
++0xbef4c852    hid_dump_input  vmlinux EXPORT_SYMBOL_GPL
++0x55423fc4    dm_requeue_unmapped_request     vmlinux EXPORT_SYMBOL_GPL
++0x2e67fc27    matrix_keypad_build_keymap      vmlinux EXPORT_SYMBOL
++0xe7c7c6b0    usb_disable_autosuspend vmlinux EXPORT_SYMBOL_GPL
++0x783194cd    usb_get_dev     vmlinux EXPORT_SYMBOL_GPL
++0x5614b010    xfrm_policy_walk_done   vmlinux EXPORT_SYMBOL
++0x6d5a6c10    inet_dgram_ops  vmlinux EXPORT_SYMBOL
++0x42e7ca3d    blk_alloc_queue vmlinux EXPORT_SYMBOL
++0xfdbd0a9b    mb_cache_destroy        vmlinux EXPORT_SYMBOL
++0x59cbc3ca    input_release_device    vmlinux EXPORT_SYMBOL
++0xd0e5d6d2    scsi_put_command        vmlinux EXPORT_SYMBOL
++0x480dca40    sec_reg_update  vmlinux EXPORT_SYMBOL_GPL
++0x28a73d8e    snd_soc_unregister_card vmlinux EXPORT_SYMBOL_GPL
++0x05fc144e    get_gendisk     vmlinux EXPORT_SYMBOL
++0xfef8a166    trace_current_buffer_lock_reserve       vmlinux EXPORT_SYMBOL_GPL
++0x7dccc294    proc_doulongvec_minmax  vmlinux EXPORT_SYMBOL
++0x92c0c538    ieee80211_bss_get_ie    vmlinux EXPORT_SYMBOL
++0x386ec802    tcp_proc_unregister     vmlinux EXPORT_SYMBOL
++0xb327256f    simple_attr_open        vmlinux EXPORT_SYMBOL_GPL
++0x56e9103b    cpu_pm_enter    vmlinux EXPORT_SYMBOL_GPL
++0x1e48b59d    __css_tryget    vmlinux EXPORT_SYMBOL_GPL
++0xbcbaa80a    __wake_up_locked_key    vmlinux EXPORT_SYMBOL_GPL
++0x2d1b02d2    usermodehelper_read_lock_wait   vmlinux EXPORT_SYMBOL_GPL
++0x72bfae4f    hwmon_device_register   vmlinux EXPORT_SYMBOL_GPL
++0x3db7f213    v4l2_of_get_remote_port vmlinux EXPORT_SYMBOL
++0x5de3f132    usb_interface_id        vmlinux EXPORT_SYMBOL_GPL
++0x9ca5592b    usb_store_new_id        vmlinux EXPORT_SYMBOL_GPL
++0x90fb0fa6    sdev_evt_send_simple    vmlinux EXPORT_SYMBOL_GPL
++0x25892d59    drm_vblank_post_modeset vmlinux EXPORT_SYMBOL
++0x8ecafd4a    drm_fb_helper_blank     vmlinux EXPORT_SYMBOL
++0x590d45c1    sk_clear_memalloc       vmlinux EXPORT_SYMBOL_GPL
++0x4578f528    __kfifo_to_user vmlinux EXPORT_SYMBOL
++0xf7ddfd4e    done_path_create        vmlinux EXPORT_SYMBOL
++0x85c10896    rcu_batches_completed_bh        vmlinux EXPORT_SYMBOL_GPL
++0x036dd11a    cgroup_path     vmlinux EXPORT_SYMBOL_GPL
++0xcc7fa952    local_bh_enable_ip      vmlinux EXPORT_SYMBOL
++0xa90054ee    rndis_uninit    vmlinux EXPORT_SYMBOL
++0x15407a03    usb_root_hub_lost_power vmlinux EXPORT_SYMBOL_GPL
++0x06fc143d    xfrm4_rcv_encap vmlinux EXPORT_SYMBOL
++0xa0c5538e    udp_poll        vmlinux EXPORT_SYMBOL
++0xd9f41f16    skb_copy_ubufs  vmlinux EXPORT_SYMBOL_GPL
++0xc83b4d5b    posix_acl_from_mode     vmlinux EXPORT_SYMBOL
++0x51ef33b8    kstrndup        vmlinux EXPORT_SYMBOL
++0x0bed814c    irq_set_chip    vmlinux EXPORT_SYMBOL
++0xd0f6cf25    console_stop    vmlinux EXPORT_SYMBOL
++0xd955eb7d    iommu_group_remove_device       vmlinux EXPORT_SYMBOL_GPL
++0xfb5dc251    gserial_disconnect      vmlinux EXPORT_SYMBOL_GPL
++0x42252607    inet6_getname   vmlinux EXPORT_SYMBOL
++0xe65b1e97    nf_conntrack_tuple_taken        vmlinux EXPORT_SYMBOL_GPL
++0x7abbee1e    wm_hubs_handle_analogue_pdata   vmlinux EXPORT_SYMBOL_GPL
++0x06dceffb    snd_soc_of_parse_daifmt vmlinux EXPORT_SYMBOL_GPL
++0xf4439247    snd_device_register     vmlinux EXPORT_SYMBOL
++0xebcea57f    evict_bh_lrus   vmlinux EXPORT_SYMBOL_GPL
++0x9714253c    mfd_add_devices vmlinux EXPORT_SYMBOL
++0x26256356    drm_mode_equal_no_clocks        vmlinux EXPORT_SYMBOL
++0x1be7f7c8    debugfs_create_file     vmlinux EXPORT_SYMBOL_GPL
++0xdbb607c7    new_inode       vmlinux EXPORT_SYMBOL
++0xa576c92e    drm_mode_config_reset   vmlinux EXPORT_SYMBOL
++0x832ca829    snd_ctl_find_id vmlinux EXPORT_SYMBOL
++0x65dccf13    xz_dec_end      vmlinux EXPORT_SYMBOL
++0xf9348cbc    xz_dec_run      vmlinux EXPORT_SYMBOL
++0xe0b13336    argv_free       vmlinux EXPORT_SYMBOL
++0x8815b870    jbd2_journal_clear_err  vmlinux EXPORT_SYMBOL
++0x861359ed    of_get_phy_mode vmlinux EXPORT_SYMBOL_GPL
++0x28a2ed02    scsi_build_sense_buffer vmlinux EXPORT_SYMBOL
++0x86240fb6    tty_port_close  vmlinux EXPORT_SYMBOL
++0x8d3e24c6    genl_unregister_family  vmlinux EXPORT_SYMBOL
++0x9d0d6206    unregister_netdevice_notifier   vmlinux EXPORT_SYMBOL
++0x18640d1b    mmc_suspend_host        vmlinux EXPORT_SYMBOL
++0x9082ce2b    tty_register_driver     vmlinux EXPORT_SYMBOL
++0x71f65175    hdmi_spd_infoframe_pack vmlinux EXPORT_SYMBOL
++0x3d6f0d06    ndo_dflt_fdb_del        vmlinux EXPORT_SYMBOL
++0xaeefbeed    kset_unregister vmlinux EXPORT_SYMBOL
++0xa498b92e    debugfs_create_u32      vmlinux EXPORT_SYMBOL_GPL
++0x7ed8eb88    sdio_release_host       vmlinux EXPORT_SYMBOL_GPL
++0xd1e4eed4    v4l2_fh_init    vmlinux EXPORT_SYMBOL_GPL
++0x5b42ed42    v4l2_fh_exit    vmlinux EXPORT_SYMBOL_GPL
++0x5947abbe    max77693_bulk_write     vmlinux EXPORT_SYMBOL_GPL
++0x7afa1fc2    driver_remove_file      vmlinux EXPORT_SYMBOL_GPL
++0xacefc84d    netdev_rx_handler_register      vmlinux EXPORT_SYMBOL_GPL
++0xd2e829b5    jbd2_journal_release_jbd_inode  vmlinux EXPORT_SYMBOL
++0xcd343f41    mmc_gpio_free_ro        vmlinux EXPORT_SYMBOL
++0x26f37f1a    inet_csk_reset_keepalive_timer  vmlinux EXPORT_SYMBOL
++0x49603fb8    security_sb_copy_data   vmlinux EXPORT_SYMBOL
++0x53326531    mempool_alloc_pages     vmlinux EXPORT_SYMBOL
++0x2b49351d    trace_define_field      vmlinux EXPORT_SYMBOL_GPL
++0x47939e0d    __tasklet_hi_schedule   vmlinux EXPORT_SYMBOL
++0x78c5a239    clk_prepare     vmlinux EXPORT_SYMBOL_GPL
++0x1a36f8fd    udc_attach_driver       vmlinux EXPORT_SYMBOL_GPL
++0xcb56fc45    dev_vprintk_emit        vmlinux EXPORT_SYMBOL
++0xed2817be    arp_send        vmlinux EXPORT_SYMBOL
++0x7d903146    xt_register_matches     vmlinux EXPORT_SYMBOL
++0x3ed63055    zlib_inflateReset       vmlinux EXPORT_SYMBOL
++0x281823c5    __kfifo_out_peek        vmlinux EXPORT_SYMBOL
++0xb19760c3    bitmap_onto     vmlinux EXPORT_SYMBOL
++0xaf9b8476    cdev_del        vmlinux EXPORT_SYMBOL
++0xbc8da552    tcp_seq_open    vmlinux EXPORT_SYMBOL
++0x35224ff2    pneigh_enqueue  vmlinux EXPORT_SYMBOL
++0x0d2e0ab9    dev_alloc_name  vmlinux EXPORT_SYMBOL
++0xebd8aaa8    iov_iter_copy_from_user vmlinux EXPORT_SYMBOL
++0x134dc23b    v4l2_m2m_dqbuf  vmlinux EXPORT_SYMBOL_GPL
++0x1cfa672b    soft_cursor     vmlinux EXPORT_SYMBOL
++0xac8f37b2    outer_cache     vmlinux EXPORT_SYMBOL
++0x744bfef9    generic_fh_to_dentry    vmlinux EXPORT_SYMBOL_GPL
++0xa3225eb1    try_to_del_timer_sync   vmlinux EXPORT_SYMBOL
++0x6a1733eb    iommu_group_unregister_notifier vmlinux EXPORT_SYMBOL_GPL
++0xc84dae86    matrix_keypad_parse_of_params   vmlinux EXPORT_SYMBOL_GPL
++0x404403a9    usb_free_all_descriptors        vmlinux EXPORT_SYMBOL_GPL
++0x50eca283    ipcomp_output   vmlinux EXPORT_SYMBOL_GPL
++0xe482d673    nf_ct_expect_related_report     vmlinux EXPORT_SYMBOL_GPL
++0x26e58975    __pskb_copy     vmlinux EXPORT_SYMBOL
++0xd3dcab0b    flex_array_alloc        vmlinux EXPORT_SYMBOL
++0x247f1878    blk_queue_bounce        vmlinux EXPORT_SYMBOL
++0x97b13dad    __clocksource_register_scale    vmlinux EXPORT_SYMBOL_GPL
++0xdc73e48f    dm_unregister_target    vmlinux EXPORT_SYMBOL
++0xfe0f06c0    tty_init_termios        vmlinux EXPORT_SYMBOL_GPL
++0xb8356d30    dma_async_memcpy_buf_to_pg      vmlinux EXPORT_SYMBOL
++0xd8d3cf00    read_dev_sector vmlinux EXPORT_SYMBOL
++0x220669c4    scsi_cmd_blk_ioctl      vmlinux EXPORT_SYMBOL
++0x03c91b88    crypto_alloc_instance2  vmlinux EXPORT_SYMBOL_GPL
++0x4d9c0e6d    jbd2_journal_revoke     vmlinux EXPORT_SYMBOL
++0xaca5e909    config_group_find_item  vmlinux EXPORT_SYMBOL
++0xe01ba49b    iio_kfifo_allocate      vmlinux EXPORT_SYMBOL
++0xe170917a    timed_output_dev_unregister     vmlinux EXPORT_SYMBOL_GPL
++0x4f689046    brcmu_pkt_buf_free_skb  drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x932f03cb    security_old_inode_init_security        vmlinux EXPORT_SYMBOL
++0xa4e5092b    debugfs_create_x16      vmlinux EXPORT_SYMBOL_GPL
++0x1826f089    __tracepoint_kmem_cache_alloc_node      vmlinux EXPORT_SYMBOL
++0xd81de62c    ring_buffer_record_enable       vmlinux EXPORT_SYMBOL_GPL
++0xc7fe94dd    usb_ifnum_to_if vmlinux EXPORT_SYMBOL_GPL
++0xc2af811e    inet6_destroy_sock      vmlinux EXPORT_SYMBOL_GPL
++0x061651be    strcat  vmlinux EXPORT_SYMBOL
++0xb39ec138    mb_cache_entry_release  vmlinux EXPORT_SYMBOL
++0x51d559d1    _raw_spin_unlock_irqrestore     vmlinux EXPORT_SYMBOL
++0xa6eb0e39    phy_device_create       vmlinux EXPORT_SYMBOL
++0xf92c66be    drm_mm_search_free_generic      vmlinux EXPORT_SYMBOL
++0x97270fcf    crypto_register_shash   vmlinux EXPORT_SYMBOL_GPL
++0x495f2be4    jbd2_journal_get_write_access   vmlinux EXPORT_SYMBOL
++0x3826f483    jbd2_journal_invalidatepage     vmlinux EXPORT_SYMBOL
++0xd8a12f4d    iio_scan_mask_query     vmlinux EXPORT_SYMBOL_GPL
++0x09b069ea    v4l2_ctrl_log_status    vmlinux EXPORT_SYMBOL
++0x0a513c7c    usb_gadget_unregister_driver    vmlinux EXPORT_SYMBOL_GPL
++0x39ef8cc9    dma_buf_kunmap  vmlinux EXPORT_SYMBOL_GPL
++0xd28b5dda    dma_buf_vunmap  vmlinux EXPORT_SYMBOL_GPL
++0x3fcf2826    inet6_unregister_protosw        vmlinux EXPORT_SYMBOL
++0x551c3633    nf_nat_l4proto_unique_tuple     vmlinux EXPORT_SYMBOL_GPL
++0x86700640    nf_register_hooks       vmlinux EXPORT_SYMBOL
++0x44e94d6c    pfifo_qdisc_ops vmlinux EXPORT_SYMBOL
++0xf202c5cb    radix_tree_insert       vmlinux EXPORT_SYMBOL
++0x24ffe755    vfs_listxattr   vmlinux EXPORT_SYMBOL_GPL
++0x52428cc8    parent_mem_cgroup       vmlinux EXPORT_SYMBOL
++0x9d59c0f2    find_get_pages_contig   vmlinux EXPORT_SYMBOL
++0x80f3268f    __trace_printk  vmlinux EXPORT_SYMBOL_GPL
++0x22a27a85    st_sensors_spi_configure        vmlinux EXPORT_SYMBOL
++0x7880c781    dm_kcopyd_prepare_callback      vmlinux EXPORT_SYMBOL
++0xc53f0876    vb2_dma_contig_memops   vmlinux EXPORT_SYMBOL_GPL
++0x388f9128    xfrm_state_walk_done    vmlinux EXPORT_SYMBOL
++0x6d6888a7    qdisc_create_dflt       vmlinux EXPORT_SYMBOL
++0x194ccf46    bmap    vmlinux EXPORT_SYMBOL
++0xe2fae716    kmemdup vmlinux EXPORT_SYMBOL
++0x07ed48c3    __blocking_notifier_call_chain  vmlinux EXPORT_SYMBOL_GPL
++0x074d7047    st_sensors_trigger_handler      vmlinux EXPORT_SYMBOL
++0x33883929    clk_divider_ops vmlinux EXPORT_SYMBOL_GPL
++0xe2b92059    v4l2_video_std_construct        vmlinux EXPORT_SYMBOL
++0x06ea1593    usbnet_defer_kevent     vmlinux EXPORT_SYMBOL_GPL
++0x6650ad3e    uart_add_one_port       vmlinux EXPORT_SYMBOL
++0x5dda183c    snd_soc_dapm_disable_pin        vmlinux EXPORT_SYMBOL_GPL
++0x7a188791    prandom_bytes   vmlinux EXPORT_SYMBOL
++0xc25a61ec    drm_mode_set_crtcinfo   vmlinux EXPORT_SYMBOL
++0xcb1beab5    drm_mode_vrefresh       vmlinux EXPORT_SYMBOL
++0x4a94168c    tcp_register_congestion_control vmlinux EXPORT_SYMBOL_GPL
++0x4f5836c8    tcp_release_cb  vmlinux EXPORT_SYMBOL
++0x2f366d34    tcp_gro_complete        vmlinux EXPORT_SYMBOL
++0x1eba8ee6    nf_conntrack_alloc      vmlinux EXPORT_SYMBOL_GPL
++0x28a903c8    timerqueue_add  vmlinux EXPORT_SYMBOL_GPL
++0x96cea50b    sync_filesystem vmlinux EXPORT_SYMBOL_GPL
++0x68c0685a    media_entity_setup_link vmlinux EXPORT_SYMBOL_GPL
++0x69b83c18    usb_get_phy_dev vmlinux EXPORT_SYMBOL_GPL
++0x7e6bf1b2    dma_buf_fd      vmlinux EXPORT_SYMBOL_GPL
++0x4d974b9c    register_sysrq_key      vmlinux EXPORT_SYMBOL
++0xf79531f4    tcp_connect     vmlinux EXPORT_SYMBOL
++0x3f45ea36    neigh_table_clear       vmlinux EXPORT_SYMBOL
++0xf6de842c    clk_get_parent  vmlinux EXPORT_SYMBOL_GPL
++0x4782eebf    clk_set_parent  vmlinux EXPORT_SYMBOL_GPL
++0x45a20c5a    of_phy_find_device      vmlinux EXPORT_SYMBOL
++0xcbbedfcb    led_trigger_event       vmlinux EXPORT_SYMBOL_GPL
++0x69281b40    thermal_zone_bind_cooling_device        vmlinux EXPORT_SYMBOL_GPL
++0xe122af95    xfrm_aalg_get_byname    vmlinux EXPORT_SYMBOL_GPL
++0x74b1375e    xfrm_state_flush        vmlinux EXPORT_SYMBOL
++0x94098ff8    snd_interval_list       vmlinux EXPORT_SYMBOL
++0x64f01d42    fuse_put_request        vmlinux EXPORT_SYMBOL_GPL
++0x1811ac2f    fat_flush_inodes        vmlinux EXPORT_SYMBOL_GPL
++0x73198f14    mmc_align_data_size     vmlinux EXPORT_SYMBOL
++0xa70df32d    drm_fb_helper_fill_var  vmlinux EXPORT_SYMBOL
++0x209e95ea    xfrm_find_acq_byseq     vmlinux EXPORT_SYMBOL
++0x4b9e2d58    xfrm_policy_unregister_afinfo   vmlinux EXPORT_SYMBOL
++0x461a1d6a    __rtnl_af_register      vmlinux EXPORT_SYMBOL_GPL
++0x09c55cec    schedule_timeout_interruptible  vmlinux EXPORT_SYMBOL
++0xf512c668    iio_trigger_free        vmlinux EXPORT_SYMBOL
++0xdac28b43    dw_mci_resume   vmlinux EXPORT_SYMBOL
++0x361e2bcc    save_stack_trace        vmlinux EXPORT_SYMBOL_GPL
++0x25e6af56    snd_compress_register   vmlinux EXPORT_SYMBOL_GPL
++0x1ace138d    bitmap_allocate_region  vmlinux EXPORT_SYMBOL
++0x250113b4    memory_read_from_buffer vmlinux EXPORT_SYMBOL
++0x4ae22649    iommu_set_fault_handler vmlinux EXPORT_SYMBOL_GPL
++0x3ca38e3a    rndis_signal_connect    vmlinux EXPORT_SYMBOL
++0x9d01b017    dma_buf_attach  vmlinux EXPORT_SYMBOL_GPL
++0x3930a5b6    dma_buf_detach  vmlinux EXPORT_SYMBOL_GPL
++0x2aec4354    hci_alloc_dev   vmlinux EXPORT_SYMBOL
++0xbb5d343d    xfrm_get_acqseq vmlinux EXPORT_SYMBOL
++0x4082abfe    __scsi_iterate_devices  vmlinux EXPORT_SYMBOL
++0x6b6d7375    drm_timestamp_precision vmlinux EXPORT_SYMBOL
++0x7ffcb57f    ip6_tnl_get_cap vmlinux EXPORT_SYMBOL
++0xccc812c3    dapm_clock_event        vmlinux EXPORT_SYMBOL_GPL
++0x1a47bf65    blk_queue_bounce_limit  vmlinux EXPORT_SYMBOL
++0xcc13c782    vb2_ioctl_streamon      vmlinux EXPORT_SYMBOL_GPL
++0x8afddc98    spi_register_driver     vmlinux EXPORT_SYMBOL_GPL
++0x17ae6853    platform_bus    vmlinux EXPORT_SYMBOL_GPL
++0x72ac0290    exynos_drm_device_unregister    vmlinux EXPORT_SYMBOL_GPL
++0xf71ca112    skb_abort_seq_read      vmlinux EXPORT_SYMBOL
++0x18bbe186    snd_soc_cnew    vmlinux EXPORT_SYMBOL_GPL
++0x2b0ba2b0    scsi_sense_desc_find    vmlinux EXPORT_SYMBOL
++0x8de13715    drm_format_vert_chroma_subsampling      vmlinux EXPORT_SYMBOL
++0x06fe3b14    default_grn     vmlinux EXPORT_SYMBOL
++0xee683d16    inet6_ioctl     vmlinux EXPORT_SYMBOL
++0x47252a20    tcp_getsockopt  vmlinux EXPORT_SYMBOL
++0x7027c3ad    tcp_setsockopt  vmlinux EXPORT_SYMBOL
++0xb7f74966    rtnl_unicast    vmlinux EXPORT_SYMBOL
++0x525971d4    snd_soc_update_bits_locked      vmlinux EXPORT_SYMBOL_GPL
++0x6ef8fcd8    snd_pcm_format_linear   vmlinux EXPORT_SYMBOL
++0x8f8f6e19    alloc_disk_node vmlinux EXPORT_SYMBOL
++0x71c445f5    fuse_get_req    vmlinux EXPORT_SYMBOL_GPL
++0xc41cff79    dequeue_signal  vmlinux EXPORT_SYMBOL_GPL
++0x5d9d3491    v4l_match_dv_timings    vmlinux EXPORT_SYMBOL_GPL
++0x829a8cac    drm_property_create_range       vmlinux EXPORT_SYMBOL
++0xf3189246    __rtnl_af_unregister    vmlinux EXPORT_SYMBOL_GPL
++0x0d7e8390    crypto_ablkcipher_type  vmlinux EXPORT_SYMBOL_GPL
++0xaf8e1608    ip6t_register_table     vmlinux EXPORT_SYMBOL
++0xb1a1e40e    crypto_tfm_in_queue     vmlinux EXPORT_SYMBOL_GPL
++0xc73f3f9a    fget_raw        vmlinux EXPORT_SYMBOL
++0x71008581    atomic_notifier_call_chain      vmlinux EXPORT_SYMBOL_GPL
++0x12bf1d5c    usbnet_device_suggests_idle     vmlinux EXPORT_SYMBOL
++0x79b993ef    cfg80211_send_unprot_deauth     vmlinux EXPORT_SYMBOL
++0xdacc53b2    spi_add_device  vmlinux EXPORT_SYMBOL_GPL
++0xf5a5c913    backlight_device_unregister     vmlinux EXPORT_SYMBOL
++0xadce320f    pinctrl_add_gpio_ranges vmlinux EXPORT_SYMBOL_GPL
++0x0f8342e1    phy_pm_runtime_forbid   vmlinux EXPORT_SYMBOL_GPL
++0xc0763484    rfkill_blocked  vmlinux EXPORT_SYMBOL
++0xb0bad0e8    ip6_push_pending_frames vmlinux EXPORT_SYMBOL_GPL
++0xfc02b7ad    sysctl_tcp_wmem vmlinux EXPORT_SYMBOL
++0xac782342    nf_unregister_hook      vmlinux EXPORT_SYMBOL
++0xa08421e0    dev_change_net_namespace        vmlinux EXPORT_SYMBOL_GPL
++0x47c6d038    blk_queue_flush_queueable       vmlinux EXPORT_SYMBOL_GPL
++0x2db8f309    blk_queue_rq_timeout    vmlinux EXPORT_SYMBOL_GPL
++0x6fb277a1    flush_kernel_dcache_page        vmlinux EXPORT_SYMBOL
++0x1d633e6a    tcp_twsk_destructor     vmlinux EXPORT_SYMBOL_GPL
++0x7611866b    scm_detach_fds  vmlinux EXPORT_SYMBOL
++0xd3b02cea    put_pid vmlinux EXPORT_SYMBOL_GPL
++0xed20e404    iio_dealloc_pollfunc    vmlinux EXPORT_SYMBOL_GPL
++0xba706bd7    samsung_pwm_lock        vmlinux EXPORT_SYMBOL
++0x158b7724    media_entity_create_link        vmlinux EXPORT_SYMBOL_GPL
++0x1172ce54    rtc_ktime_to_tm vmlinux EXPORT_SYMBOL_GPL
++0xa286a234    snd_pcm_format_name     vmlinux EXPORT_SYMBOL_GPL
++0xc7e39bca    ring_buffer_dropped_events_cpu  vmlinux EXPORT_SYMBOL_GPL
++0xaa957320    posix_clock_register    vmlinux EXPORT_SYMBOL_GPL
++0xad46dec2    of_count_phandle_with_args      vmlinux EXPORT_SYMBOL
++0x7120d717    regmap_bulk_read        vmlinux EXPORT_SYMBOL_GPL
++0xca56dea4    driver_find_device      vmlinux EXPORT_SYMBOL_GPL
++0x9c9d19e7    blk_get_request vmlinux EXPORT_SYMBOL
++0x2c790eff    usbnet_read_cmd_nopm    vmlinux EXPORT_SYMBOL_GPL
++0xbb99125c    get_default_font        vmlinux EXPORT_SYMBOL
++0x6e5cf115    cfg80211_inform_bss     vmlinux EXPORT_SYMBOL
++0xce7a55c1    xfrm_ealg_get_byid      vmlinux EXPORT_SYMBOL_GPL
++0x0cc1e40f    crypto_it_tab   vmlinux EXPORT_SYMBOL_GPL
++0x3dc916b6    crypto_fl_tab   vmlinux EXPORT_SYMBOL_GPL
++0x40d46b21    crypto_ft_tab   vmlinux EXPORT_SYMBOL_GPL
++0x71dc9998    crypto_il_tab   vmlinux EXPORT_SYMBOL_GPL
++0x837d0f0a    down_timeout    vmlinux EXPORT_SYMBOL
++0x2cd7dd71    __cpufreq_driver_getavg vmlinux EXPORT_SYMBOL_GPL
++0xee6b71c4    syscon_regmap_lookup_by_compatible      vmlinux EXPORT_SYMBOL_GPL
++0xae77b400    device_pm_wait_for_dev  vmlinux EXPORT_SYMBOL_GPL
++0x1d5a2494    nfnetlink_has_listeners vmlinux EXPORT_SYMBOL_GPL
++0x3bd1b1f6    msecs_to_jiffies        vmlinux EXPORT_SYMBOL
++0xfb09f255    cpufreq_frequency_table_target  vmlinux EXPORT_SYMBOL_GPL
++0xb52e203b    snd_pcm_suspend_all     vmlinux EXPORT_SYMBOL
++0xc1ec3550    blkdev_fsync    vmlinux EXPORT_SYMBOL
++0x0ebe6f54    lookup_one_len  vmlinux EXPORT_SYMBOL
++0x151404f6    misc_deregister vmlinux EXPORT_SYMBOL
++0xb2856c71    inet6_bind      vmlinux EXPORT_SYMBOL
++0xf68285c0    register_inetaddr_notifier      vmlinux EXPORT_SYMBOL
++0x7afc9d8a    unregister_sound_mixer  vmlinux EXPORT_SYMBOL
++0xd5d80496    atomic_dec_and_mutex_lock       vmlinux EXPORT_SYMBOL
++0x4351577a    fb_parse_edid   vmlinux EXPORT_SYMBOL
++0x68beb163    nf_ct_l3proto_pernet_unregister vmlinux EXPORT_SYMBOL_GPL
++0x7751fba7    nf_ct_l4proto_pernet_unregister vmlinux EXPORT_SYMBOL_GPL
++0x5cbe0b31    snd_pcm_lib_write       vmlinux EXPORT_SYMBOL
++0x6cecc98a    devres_get      vmlinux EXPORT_SYMBOL_GPL
++0x20925954    devres_add      vmlinux EXPORT_SYMBOL_GPL
++0x99a9dfa6    ieee80211_data_to_8023  vmlinux EXPORT_SYMBOL
++0x21036b2c    bt_accept_enqueue       vmlinux EXPORT_SYMBOL
++0x0cd5a88b    sync_inodes_sb  vmlinux EXPORT_SYMBOL
++0x7485e15e    unregister_chrdev_region        vmlinux EXPORT_SYMBOL
++0x7e8ad403    generic_writepages      vmlinux EXPORT_SYMBOL
++0x07cf3227    clk_fixed_rate_ops      vmlinux EXPORT_SYMBOL_GPL
++0xf5463be8    led_trigger_blink_oneshot       vmlinux EXPORT_SYMBOL_GPL
++0xdbf18207    v4l2_device_register_subdev     vmlinux EXPORT_SYMBOL_GPL
++0x131a5ed7    regmap_del_irq_chip     vmlinux EXPORT_SYMBOL_GPL
++0xb09c8d37    regmap_add_irq_chip     vmlinux EXPORT_SYMBOL_GPL
++0x26f0453a    blk_set_default_limits  vmlinux EXPORT_SYMBOL
++0xf21f8a44    blk_init_allocated_queue        vmlinux EXPORT_SYMBOL
++0x60df1e3b    posix_acl_equiv_mode    vmlinux EXPORT_SYMBOL
++0xc131c5dd    usb_add_phy     vmlinux EXPORT_SYMBOL_GPL
++0x211c5b26    cdc_ncm_bind_common     vmlinux EXPORT_SYMBOL_GPL
++0x61f6939e    drm_i2c_encoder_detect  vmlinux EXPORT_SYMBOL
++0xd9f310b2    gpiochip_is_requested   vmlinux EXPORT_SYMBOL_GPL
++0xb9639d32    rtnl_register   vmlinux EXPORT_SYMBOL_GPL
++0xf2254dc3    sock_from_file  vmlinux EXPORT_SYMBOL
++0x0f5455e2    snd_soc_info_enum_double        vmlinux EXPORT_SYMBOL_GPL
++0xdd89a6bf    lookup_bdev     vmlinux EXPORT_SYMBOL
++0x55704318    clockevents_config_and_register vmlinux EXPORT_SYMBOL_GPL
++0x2fd8cba9    freeze_wake     vmlinux EXPORT_SYMBOL_GPL
++0x071b7eea    irq_stat        vmlinux EXPORT_SYMBOL
++0x7a8ca627    xfrm_count_pfkey_enc_supported  vmlinux EXPORT_SYMBOL_GPL
++0x1ff2a733    raw_seq_stop    vmlinux EXPORT_SYMBOL_GPL
++0x85b825e7    gnet_stats_copy_basic   vmlinux EXPORT_SYMBOL
++0x0cfefe1e    percpu_counter_destroy  vmlinux EXPORT_SYMBOL
++0x02ea69e2    vm_map_ram      vmlinux EXPORT_SYMBOL
++0x36eb3583    filemap_fdatawrite_range        vmlinux EXPORT_SYMBOL
++0xb977cf42    inet_sendmsg    vmlinux EXPORT_SYMBOL
++0xddbcead7    ip_cmsg_recv    vmlinux EXPORT_SYMBOL
++0xb9a64b20    elevator_alloc  vmlinux EXPORT_SYMBOL
++0xbcaf3971    crypto_alg_sem  vmlinux EXPORT_SYMBOL_GPL
++0xe71dab2c    bio_sector_offset       vmlinux EXPORT_SYMBOL
++0x2c44797e    hidinput_report_event   vmlinux EXPORT_SYMBOL_GPL
++0x5d9e8570    drm_display_mode_from_videomode vmlinux EXPORT_SYMBOL_GPL
++0x2b8e67cd    fuse_get_req_for_background     vmlinux EXPORT_SYMBOL_GPL
++0x2b1c6816    extcon_dev_register     vmlinux EXPORT_SYMBOL_GPL
++0xdef26358    dw_mci_probe    vmlinux EXPORT_SYMBOL
++0xcbde0d9d    inverse_translate       vmlinux EXPORT_SYMBOL_GPL
++0x056ee730    ipv6_hash_secret        vmlinux EXPORT_SYMBOL
++0xfe029963    unregister_inetaddr_notifier    vmlinux EXPORT_SYMBOL
++0x650a6767    prandom_u32_state       vmlinux EXPORT_SYMBOL
++0x4148a5ff    get_kernel_pages        vmlinux EXPORT_SYMBOL_GPL
++0x24d3448d    perf_event_enable       vmlinux EXPORT_SYMBOL_GPL
++0x1c5a04e0    irq_domain_generate_simple      vmlinux EXPORT_SYMBOL_GPL
++0xb7b4232a    unregister_exec_domain  vmlinux EXPORT_SYMBOL
++0xd6f86c04    amba_release_regions    vmlinux EXPORT_SYMBOL
++0x89d5538d    fb_pad_aligned_buffer   vmlinux EXPORT_SYMBOL
++0x93237692    nobh_write_begin        vmlinux EXPORT_SYMBOL
++0x920eb90c    interruptible_sleep_on_timeout  vmlinux EXPORT_SYMBOL
++0x3a36ce8c    od_register_powersave_bias_handler      vmlinux EXPORT_SYMBOL_GPL
++0x946b8b6c    netlink_ack     vmlinux EXPORT_SYMBOL
++0x1000be5b    sock_no_bind    vmlinux EXPORT_SYMBOL
++0x1e5479ed    sock_get_timestamp      vmlinux EXPORT_SYMBOL
++0x4211c3c1    zlib_inflateInit2       vmlinux EXPORT_SYMBOL
++0x2486141e    bio_alloc_pages vmlinux EXPORT_SYMBOL
++0x62fd6207    param_set_charp vmlinux EXPORT_SYMBOL
++0x0862d814    v4l2_event_unsubscribe_all      vmlinux EXPORT_SYMBOL_GPL
++0x2f10e618    v4l2_event_queue_fh     vmlinux EXPORT_SYMBOL_GPL
++0x6bdcfd99    qdisc_class_hash_remove vmlinux EXPORT_SYMBOL
++0xf070e888    __put_net       vmlinux EXPORT_SYMBOL_GPL
++0x8df3789f    snd_oss_info_register   vmlinux EXPORT_SYMBOL
++0x68c73797    fuse_request_alloc      vmlinux EXPORT_SYMBOL_GPL
++0x2342f1ae    v4l2_prio_open  vmlinux EXPORT_SYMBOL
++0x4ddaa6ea    dmam_alloc_noncoherent  vmlinux EXPORT_SYMBOL
++0x7dfdf9a1    transport_destroy_device        vmlinux EXPORT_SYMBOL_GPL
++0x8c510862    drm_find_cea_extension  vmlinux EXPORT_SYMBOL
++0x7c0267ee    serial8250_tx_chars     vmlinux EXPORT_SYMBOL_GPL
++0x6879e81d    display_entity_put      vmlinux EXPORT_SYMBOL_GPL
++0xf19a455d    lro_flush_pkt   vmlinux EXPORT_SYMBOL
++0xbf8ba54a    vprintk vmlinux EXPORT_SYMBOL
++0x7bd1de14    thermal_cdev_update     vmlinux EXPORT_SYMBOL
++0x2631d719    tty_unregister_device   vmlinux EXPORT_SYMBOL
++0xa7e7f050    __udp4_lib_lookup       vmlinux EXPORT_SYMBOL_GPL
++0x2e2ce9e0    sysctl_tcp_syncookies   vmlinux EXPORT_SYMBOL
++0xd5a8fd58    tcp_poll        vmlinux EXPORT_SYMBOL
++0x3f74afb9    nf_ct_l3proto_register  vmlinux EXPORT_SYMBOL_GPL
++0xb4998fd0    nf_ct_l4proto_register  vmlinux EXPORT_SYMBOL_GPL
++0x2482e688    vsprintf        vmlinux EXPORT_SYMBOL
++0x59e4b703    generic_splice_sendpage vmlinux EXPORT_SYMBOL
++0x1795a16b    __genl_register_family_with_ops vmlinux EXPORT_SYMBOL
++0xcb469d2b    ddebug_add_module       vmlinux EXPORT_SYMBOL_GPL
++0xa2d83f8b    grab_cache_page_write_begin     vmlinux EXPORT_SYMBOL
++0x8c930a68    rt_mutex_lock_interruptible     vmlinux EXPORT_SYMBOL_GPL
++0xcc0871f2    attribute_container_find_class_device   vmlinux EXPORT_SYMBOL_GPL
++0x13b52797    pwm_request_from_chip   vmlinux EXPORT_SYMBOL_GPL
++0x28118cb6    __get_user_1    vmlinux EXPORT_SYMBOL
++0xbb72d4fe    __put_user_1    vmlinux EXPORT_SYMBOL
++0x0cae232b    utf16s_to_utf8s vmlinux EXPORT_SYMBOL
++0x617a218d    __cond_resched_lock     vmlinux EXPORT_SYMBOL
++0x44224883    __put_task_struct       vmlinux EXPORT_SYMBOL_GPL
++0xbc65845b    class_create_file       vmlinux EXPORT_SYMBOL_GPL
++0xe459c49b    unregister_pernet_subsys        vmlinux EXPORT_SYMBOL_GPL
++0xd882a162    wait_on_sync_kiocb      vmlinux EXPORT_SYMBOL
++0x28acb0e5    simple_write_begin      vmlinux EXPORT_SYMBOL
++0x5c1cb07e    redirty_page_for_writepage      vmlinux EXPORT_SYMBOL
++0x6070a6fb    bdi_set_max_ratio       vmlinux EXPORT_SYMBOL
++0xfee43a69    drm_dp_get_adjust_request_voltage       vmlinux EXPORT_SYMBOL
++0x8ffe7e89    nf_conntrack_htable_size        vmlinux EXPORT_SYMBOL_GPL
++0x79c527b0    netdev_emerg    vmlinux EXPORT_SYMBOL
++0x0bc7142a    sk_stream_kill_queues   vmlinux EXPORT_SYMBOL
++0xeb37101c    audit_log_end   vmlinux EXPORT_SYMBOL
++0xc3577d50    dev_set_name    vmlinux EXPORT_SYMBOL_GPL
++0x6d40a921    need_ipv4_conntrack     vmlinux EXPORT_SYMBOL_GPL
++0x6b98f5bd    __sk_dst_check  vmlinux EXPORT_SYMBOL
++0x003ed69a    __kfifo_dma_in_prepare  vmlinux EXPORT_SYMBOL
++0xd27b25dd    blk_check_plugged       vmlinux EXPORT_SYMBOL
++0x9e093f78    elv_register_queue      vmlinux EXPORT_SYMBOL
++0x716265c7    debugfs_initialized     vmlinux EXPORT_SYMBOL_GPL
++0x8e19dd86    of_platform_populate    vmlinux EXPORT_SYMBOL_GPL
++0x2a4ee199    v4l2_m2m_job_finish     vmlinux EXPORT_SYMBOL
++0x8c62225c    usb_queue_reset_device  vmlinux EXPORT_SYMBOL_GPL
++0x1e837252    drm_mm_scan_add_block   vmlinux EXPORT_SYMBOL
++0x6c9424d9    snd_pcm_lib_preallocate_pages   vmlinux EXPORT_SYMBOL
++0x4c759827    byte_rev_table  vmlinux EXPORT_SYMBOL_GPL
++0xdf7090e0    __elv_add_request       vmlinux EXPORT_SYMBOL
++0x911010cb    skcipher_geniv_init     vmlinux EXPORT_SYMBOL_GPL
++0x9bd700dd    set_bh_page     vmlinux EXPORT_SYMBOL
++0x13a2a2e3    free_user_ns    vmlinux EXPORT_SYMBOL
++0x4fe8770d    usb_interrupt_msg       vmlinux EXPORT_SYMBOL_GPL
++0x0d7dd3fc    pm_generic_runtime_resume       vmlinux EXPORT_SYMBOL_GPL
++0x3df0b6c5    bus_unregister  vmlinux EXPORT_SYMBOL_GPL
++0x131f636c    nf_nat_l4proto_in_range vmlinux EXPORT_SYMBOL_GPL
++0xe6643a60    snd_soc_dpcm_be_can_update      vmlinux EXPORT_SYMBOL_GPL
++0x059c8bf5    snd_soc_dpcm_fe_can_update      vmlinux EXPORT_SYMBOL_GPL
++0xe914e41e    strcpy  vmlinux EXPORT_SYMBOL
++0x27235c89    crypto_destroy_tfm      vmlinux EXPORT_SYMBOL_GPL
++0xe44b1603    sysfs_remove_link_from_group    vmlinux EXPORT_SYMBOL_GPL
++0x1dff6af1    filemap_fault   vmlinux EXPORT_SYMBOL
++0xb1d9aabd    lg_local_unlock_cpu     vmlinux EXPORT_SYMBOL
++0x59d9c8d7    jack_get_data   vmlinux EXPORT_SYMBOL_GPL
++0x7a91726b    clkdev_alloc    vmlinux EXPORT_SYMBOL
++0x6138cad8    nfc_tm_deactivated      vmlinux EXPORT_SYMBOL
++0xe50e65bf    blocking_notifier_chain_register        vmlinux EXPORT_SYMBOL_GPL
++0x9acf72e4    rndis_set_param_medium  vmlinux EXPORT_SYMBOL
++0x677428bf    sdev_enable_disk_events vmlinux EXPORT_SYMBOL
++0x45ef1157    tty_pair_get_tty        vmlinux EXPORT_SYMBOL
++0x4338e523    tty_pair_get_pty        vmlinux EXPORT_SYMBOL
++0x51c0d211    fb_get_buffer_offset    vmlinux EXPORT_SYMBOL
++0xe7f26347    skb_unlink      vmlinux EXPORT_SYMBOL
++0xc3f69ac2    crypto_register_template        vmlinux EXPORT_SYMBOL_GPL
++0x00fe8031    fuse_abort_conn vmlinux EXPORT_SYMBOL_GPL
++0x3dc45692    vm_iomap_memory vmlinux EXPORT_SYMBOL
++0xc41f0516    node_states     vmlinux EXPORT_SYMBOL
++0x6a5fb566    rcu_sched_force_quiescent_state vmlinux EXPORT_SYMBOL_GPL
++0xc89e91fb    irq_setup_alt_chip      vmlinux EXPORT_SYMBOL_GPL
++0xe8a39d68    vb2_ioctl_streamoff     vmlinux EXPORT_SYMBOL_GPL
++0xb2e5ae4a    snd_lookup_minor_data   vmlinux EXPORT_SYMBOL
++0xaafd1f6c    iio_triggered_buffer_setup      vmlinux EXPORT_SYMBOL
++0x4b17b645    of_property_read_u16_array      vmlinux EXPORT_SYMBOL_GPL
++0xdac11bae    of_property_read_u32_array      vmlinux EXPORT_SYMBOL_GPL
++0x5641485b    tty_termios_encode_baud_rate    vmlinux EXPORT_SYMBOL_GPL
++0x85d549dc    s3c_gpio_getcfg vmlinux EXPORT_SYMBOL
++0x1189692c    inet_csk_delete_keepalive_timer vmlinux EXPORT_SYMBOL
++0xbec25473    of_parse_phandle        vmlinux EXPORT_SYMBOL
++0x53f0b470    dev_pm_qos_add_ancestor_request vmlinux EXPORT_SYMBOL_GPL
++0x0ddc826c    drm_fb_helper_set_par   vmlinux EXPORT_SYMBOL
++0x64bb0960    cfg80211_wext_giwmode   vmlinux EXPORT_SYMBOL_GPL
++0xd4cc3fbd    cfg80211_wext_giwname   vmlinux EXPORT_SYMBOL_GPL
++0x8697617d    cfg80211_wext_siwmode   vmlinux EXPORT_SYMBOL_GPL
++0xe3643cca    cfg80211_send_auth_timeout      vmlinux EXPORT_SYMBOL
++0x377db989    xfrm_state_register_afinfo      vmlinux EXPORT_SYMBOL
++0x2cdca56b    usb_register_device_driver      vmlinux EXPORT_SYMBOL_GPL
++0x7f9066b4    subsys_interface_unregister     vmlinux EXPORT_SYMBOL_GPL
++0xfbc8e9a2    regulatory_hint vmlinux EXPORT_SYMBOL
++0xbdf0ff3a    wiphy_rfkill_start_polling      vmlinux EXPORT_SYMBOL
++0x74631c0e    inet_ioctl      vmlinux EXPORT_SYMBOL
++0x5cbe31bd    snd_soc_dapm_mixer_update_power vmlinux EXPORT_SYMBOL_GPL
++0x5a3c2afd    kobject_get_path        vmlinux EXPORT_SYMBOL_GPL
++0xd8ce7e67    clocksource_register    vmlinux EXPORT_SYMBOL
++0x802c194a    of_device_register      vmlinux EXPORT_SYMBOL
++0x0c8c9e99    scsi_show_extd_sense    vmlinux EXPORT_SYMBOL
++0x2155f85c    bt_sock_link    vmlinux EXPORT_SYMBOL
++0x0ccfae80    xt_register_target      vmlinux EXPORT_SYMBOL
++0x6f20960a    full_name_hash  vmlinux EXPORT_SYMBOL
++0xcded9074    phy_drivers_register    vmlinux EXPORT_SYMBOL
++0xae5ba460    ping_prot       vmlinux EXPORT_SYMBOL
++0x814e7730    nf_ct_destroy   vmlinux EXPORT_SYMBOL
++0xe8279caa    nf_unregister_hooks     vmlinux EXPORT_SYMBOL
++0x8810ad5e    crypto_xor      vmlinux EXPORT_SYMBOL_GPL
++0x45bf1ff3    crypto_inc      vmlinux EXPORT_SYMBOL_GPL
++0x5ac71347    wait_for_stable_page    vmlinux EXPORT_SYMBOL_GPL
++0xe07ca631    cpu_bit_bitmap  vmlinux EXPORT_SYMBOL_GPL
++0x9c5bf378    pm_generic_freeze       vmlinux EXPORT_SYMBOL_GPL
++0x50bd1b27    device_create_vargs     vmlinux EXPORT_SYMBOL_GPL
++0x30775773    drm_bl_unregister       vmlinux EXPORT_SYMBOL_GPL
++0xf4f3abb6    tty_port_hangup vmlinux EXPORT_SYMBOL
++0xca0bdf70    framebuffer_release     vmlinux EXPORT_SYMBOL
++0x86743fc9    touch_buffer    vmlinux EXPORT_SYMBOL
++0x5671b6e0    iio_triggered_buffer_predisable vmlinux EXPORT_SYMBOL
++0x2eb9cd44    brcmu_pktq_init drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x77c7a73e    wiphy_apply_custom_regulatory   vmlinux EXPORT_SYMBOL
++0xd796d321    fat_getattr     vmlinux EXPORT_SYMBOL_GPL
++0x41e95f70    fat_setattr     vmlinux EXPORT_SYMBOL_GPL
++0x2750ffee    generic_read_dir        vmlinux EXPORT_SYMBOL
++0x00c3b7ed    dentry_unhash   vmlinux EXPORT_SYMBOL
++0xe007de41    kallsyms_lookup_name    vmlinux EXPORT_SYMBOL_GPL
++0x43f23311    dm_table_get_md vmlinux EXPORT_SYMBOL
++0x9db747a3    usb_hcd_poll_rh_status  vmlinux EXPORT_SYMBOL_GPL
++0xfd1cd45b    dev_pm_qos_hide_flags   vmlinux EXPORT_SYMBOL_GPL
++0xe15b1685    device_find_child       vmlinux EXPORT_SYMBOL_GPL
++0x1a022e5e    truncate_pagecache      vmlinux EXPORT_SYMBOL
++0x26b71fb4    ring_buffer_time_stamp  vmlinux EXPORT_SYMBOL_GPL
++0x4e6a500f    phy_pm_runtime_get      vmlinux EXPORT_SYMBOL_GPL
++0x056bb269    xfrm_ealg_get_byidx     vmlinux EXPORT_SYMBOL_GPL
++0x094585f4    sock_no_shutdown        vmlinux EXPORT_SYMBOL
++0x0a5ea478    __generic_block_fiemap  vmlinux EXPORT_SYMBOL
++0xb1acbcce    rcu_barrier_sched       vmlinux EXPORT_SYMBOL_GPL
++0x3924dd56    try_wait_for_completion vmlinux EXPORT_SYMBOL
++0x8f7014a1    param_set_ulong vmlinux EXPORT_SYMBOL
++0xee2d0fc7    _local_bh_enable        vmlinux EXPORT_SYMBOL
++0x34e8e0a0    of_device_unregister    vmlinux EXPORT_SYMBOL
++0xbed3ee5e    watchdog_register_device        vmlinux EXPORT_SYMBOL_GPL
++0x16244fe5    v4l2_prio_check vmlinux EXPORT_SYMBOL
++0x324a8332    vc_resize       vmlinux EXPORT_SYMBOL
++0xb410d84f    phy_put vmlinux EXPORT_SYMBOL_GPL
++0xa41b1e49    phy_pm_runtime_put_sync vmlinux EXPORT_SYMBOL_GPL
++0xb3d5242c    nf_ct_expect_alloc      vmlinux EXPORT_SYMBOL_GPL
++0xbdfe32cf    sysfs_unmerge_group     vmlinux EXPORT_SYMBOL_GPL
++0xdb04cacc    tracepoint_probe_unregister_noupdate    vmlinux EXPORT_SYMBOL_GPL
++0x481ce6ce    cpu_active_mask vmlinux EXPORT_SYMBOL
++0x78f47a5c    drm_kms_helper_poll_init        vmlinux EXPORT_SYMBOL
++0x62827bec    security_secctx_to_secid        vmlinux EXPORT_SYMBOL
++0xcb97ad8c    bus_find_device_by_name vmlinux EXPORT_SYMBOL_GPL
++0x427dce2d    drm_put_minor   vmlinux EXPORT_SYMBOL
++0xf7b743b5    drm_calc_timestamping_constants vmlinux EXPORT_SYMBOL
++0x62746f06    video_source_unregister vmlinux EXPORT_SYMBOL_GPL
++0xacde6340    inet_peer_xrlim_allow   vmlinux EXPORT_SYMBOL
++0xd4b0b600    nf_ct_attach    vmlinux EXPORT_SYMBOL
++0x3e1314f1    snd_timer_global_free   vmlinux EXPORT_SYMBOL
++0xd37725bb    register_user_hw_breakpoint     vmlinux EXPORT_SYMBOL_GPL
++0x4f741917    devm_phy_put    vmlinux EXPORT_SYMBOL_GPL
++0xe5ed5467    xfrm_policy_walk_init   vmlinux EXPORT_SYMBOL
++0xfd6eefb8    nf_nat_decode_session_hook      vmlinux EXPORT_SYMBOL
++0x82627707    snd_pcm_lib_writev      vmlinux EXPORT_SYMBOL
++0x28b2dd21    textsearch_register     vmlinux EXPORT_SYMBOL
++0x74baf17a    tracing_is_on   vmlinux EXPORT_SYMBOL_GPL
++0x381a798a    setup_max_cpus  vmlinux EXPORT_SYMBOL
++0xf442e8f8    commit_creds    vmlinux EXPORT_SYMBOL
++0xab598227    driver_attach   vmlinux EXPORT_SYMBOL_GPL
++0xa1d5de65    drm_mode_connector_list_update  vmlinux EXPORT_SYMBOL
++0xf3f5690b    __nf_ct_expect_find     vmlinux EXPORT_SYMBOL_GPL
++0xad0413d4    match_hex       vmlinux EXPORT_SYMBOL
++0xbfdbee53    usbnet_generic_cdc_bind vmlinux EXPORT_SYMBOL_GPL
++0x329edb99    platform_device_register        vmlinux EXPORT_SYMBOL_GPL
++0x80d68d3e    fb_register_client      vmlinux EXPORT_SYMBOL
++0x3638b44e    __inet_lookup_listener  vmlinux EXPORT_SYMBOL_GPL
++0x89636597    nf_unregister_sockopt   vmlinux EXPORT_SYMBOL
++0xadac214f    __skb_get_rxhash        vmlinux EXPORT_SYMBOL
++0x10ae54ba    skb_realloc_headroom    vmlinux EXPORT_SYMBOL
++0xdaa5b6fe    generic_pipe_buf_get    vmlinux EXPORT_SYMBOL
++0x461fff7e    generic_pipe_buf_map    vmlinux EXPORT_SYMBOL
++0x36f9cd94    rcu_is_cpu_idle vmlinux EXPORT_SYMBOL
++0x4102e3db    media_entity_find_link  vmlinux EXPORT_SYMBOL_GPL
++0xcd0e7389    platform_device_unregister      vmlinux EXPORT_SYMBOL_GPL
++0xf86dc7d7    serial8250_set_isa_configurator vmlinux EXPORT_SYMBOL
++0xbe1c5d4d    ipv6_find_hdr   vmlinux EXPORT_SYMBOL
++0xc6ed2b40    jbd2_journal_dirty_metadata     vmlinux EXPORT_SYMBOL
++0x77df0847    __set_personality       vmlinux EXPORT_SYMBOL
++0x92c6523d    tty_port_close_end      vmlinux EXPORT_SYMBOL
++0x78843287    blkcipher_walk_done     vmlinux EXPORT_SYMBOL_GPL
++0x96f90809    page_readlink   vmlinux EXPORT_SYMBOL
++0xc7c4f4ed    account_page_writeback  vmlinux EXPORT_SYMBOL
++0xa1edf7f3    drm_core_ioremap_wc     vmlinux EXPORT_SYMBOL
++0x08ad3fc2    register_con_driver     vmlinux EXPORT_SYMBOL
++0x676bbc0f    _set_bit        vmlinux EXPORT_SYMBOL
++0xd46c9ca5    nf_unregister_afinfo    vmlinux EXPORT_SYMBOL_GPL
++0xf5eb86ea    blk_verify_command      vmlinux EXPORT_SYMBOL
++0xc499ae1e    kstrdup vmlinux EXPORT_SYMBOL
++0x2aa1ad41    _raw_write_lock_irq     vmlinux EXPORT_SYMBOL
++0xb5b7345d    freezing_slow_path      vmlinux EXPORT_SYMBOL
++0xe505e34f    mmc_start_bkops vmlinux EXPORT_SYMBOL
++0x1dd571e6    fb_copy_cmap    vmlinux EXPORT_SYMBOL
++0x0d4d7a32    _atomic_dec_and_lock    vmlinux EXPORT_SYMBOL
++0x11c9185c    of_iomap        vmlinux EXPORT_SYMBOL
++0xf918f7de    xfrm_register_km        vmlinux EXPORT_SYMBOL
++0xde4bc28c    ip_mc_dec_group vmlinux EXPORT_SYMBOL
++0x03f12ac0    snd_soc_dapm_mux_update_power   vmlinux EXPORT_SYMBOL_GPL
++0x733c3b54    kasprintf       vmlinux EXPORT_SYMBOL
++0x8aaa8b57    simple_rename   vmlinux EXPORT_SYMBOL
++0x512579ee    vfs_setxattr    vmlinux EXPORT_SYMBOL_GPL
++0x3d8f75d6    vfs_getxattr    vmlinux EXPORT_SYMBOL_GPL
++0xcb7131fb    fb_get_options  vmlinux EXPORT_SYMBOL
++0xd49c7d00    phy_init        vmlinux EXPORT_SYMBOL_GPL
++0xf8c54a02    sock_init_data  vmlinux EXPORT_SYMBOL
++0x1209a558    snd_ctl_free_one        vmlinux EXPORT_SYMBOL
++0xe02eb6d0    ring_buffer_commit_overrun_cpu  vmlinux EXPORT_SYMBOL_GPL
++0x3a536bd7    ring_buffer_read_finish vmlinux EXPORT_SYMBOL_GPL
++0x9c0bd51f    _raw_spin_lock  vmlinux EXPORT_SYMBOL
++0xcf7c760d    mmc_send_ext_csd        vmlinux EXPORT_SYMBOL_GPL
++0x0f7cb7fa    tty_set_termios vmlinux EXPORT_SYMBOL_GPL
++0x86ffe7d1    ip_queue_xmit   vmlinux EXPORT_SYMBOL
++0xc30b3a36    scatterwalk_map vmlinux EXPORT_SYMBOL_GPL
++0x23532c4d    ftrace_print_flags_seq  vmlinux EXPORT_SYMBOL
++0x3500818d    v4l2_fh_open    vmlinux EXPORT_SYMBOL_GPL
++0xadc7d94a    class_dev_iter_init     vmlinux EXPORT_SYMBOL_GPL
++0xb95ec685    km_query        vmlinux EXPORT_SYMBOL
++0xf569d921    inet_release    vmlinux EXPORT_SYMBOL
++0x4251ff78    nf_ct_helper_expectfn_register  vmlinux EXPORT_SYMBOL_GPL
++0xa3f35bf5    rwsem_is_locked vmlinux EXPORT_SYMBOL
++0x518c4113    blk_queue_start_tag     vmlinux EXPORT_SYMBOL
++0x299f45b9    jbd2_journal_force_commit       vmlinux EXPORT_SYMBOL
++0x373db350    kstrtoint       vmlinux EXPORT_SYMBOL
++0xfffad96c    call_srcu       vmlinux EXPORT_SYMBOL_GPL
++0x4806c9d5    drm_connector_init      vmlinux EXPORT_SYMBOL
++0x9fce80db    fb_notifier_call_chain  vmlinux EXPORT_SYMBOL_GPL
++0x856629e7    __tracepoint_rpm_return_int     vmlinux EXPORT_SYMBOL_GPL
++0x8f6cee77    __round_jiffies_relative        vmlinux EXPORT_SYMBOL_GPL
++0xb992cdc2    cpufreq_get_policy      vmlinux EXPORT_SYMBOL
++0x9a7784ef    v4l2_device_put vmlinux EXPORT_SYMBOL_GPL
++0xab2d53fe    wm8994_reg_write        vmlinux EXPORT_SYMBOL_GPL
++0xa7c124ba    inet_frag_maybe_warn_overflow   vmlinux EXPORT_SYMBOL
++0x81cbdbae    inet_twsk_alloc vmlinux EXPORT_SYMBOL_GPL
++0x037a0cba    kfree   vmlinux EXPORT_SYMBOL
++0xfb0c30cd    __rt_mutex_init vmlinux EXPORT_SYMBOL_GPL
++0x578a9e0d    kill_pid_info_as_cred   vmlinux EXPORT_SYMBOL_GPL
++0xa8ca80b5    __serio_register_driver vmlinux EXPORT_SYMBOL
++0x182a39a6    max8997_bulk_read       vmlinux EXPORT_SYMBOL_GPL
++0x2fd9648c    pm_genpd_add_callbacks  vmlinux EXPORT_SYMBOL_GPL
++0xc5c2a452    tty_put_char    vmlinux EXPORT_SYMBOL_GPL
++0x49b60948    xfrm_state_delete       vmlinux EXPORT_SYMBOL
++0x0693c220    nf_register_sockopt     vmlinux EXPORT_SYMBOL
++0x8c9e0cae    sock_kmalloc    vmlinux EXPORT_SYMBOL
++0xb9638db4    snd_pcm_rate_to_rate_bit        vmlinux EXPORT_SYMBOL
++0xf3b3adff    cgroup_load_subsys      vmlinux EXPORT_SYMBOL_GPL
++0x75911fdf    ip_tunnel_get_stats64   vmlinux EXPORT_SYMBOL_GPL
++0xe7d4daac    seq_list_next   vmlinux EXPORT_SYMBOL
++0x2fe252cc    unregister_inet6addr_notifier   vmlinux EXPORT_SYMBOL
++0xa06df9e1    __kfifo_dma_out_finish_r        vmlinux EXPORT_SYMBOL
++0x01e0e788    st_sensors_allocate_trigger     vmlinux EXPORT_SYMBOL
++0xcdd15087    of_irq_map_one  vmlinux EXPORT_SYMBOL_GPL
++0xea97422f    vb2_queue_release       vmlinux EXPORT_SYMBOL_GPL
++0xb37c3615    cfg80211_rx_unexpected_4addr_frame      vmlinux EXPORT_SYMBOL
++0xbc2271b2    ipv6_chk_addr   vmlinux EXPORT_SYMBOL
++0x9e9ab99d    __blkdev_driver_ioctl   vmlinux EXPORT_SYMBOL_GPL
++0x54f3cc64    blk_alloc_queue_node    vmlinux EXPORT_SYMBOL
++0xd20b9da2    iio_buffer_unregister   vmlinux EXPORT_SYMBOL
++0xa8f8abd2    v4l2_ctrl_g_ctrl_int64  vmlinux EXPORT_SYMBOL
++0xc2aa0765    dev_pm_qos_flags        vmlinux EXPORT_SYMBOL_GPL
++0xf5f14859    uart_suspend_port       vmlinux EXPORT_SYMBOL
++0xe7722171    flex_array_free vmlinux EXPORT_SYMBOL
++0xa27aead4    blk_queue_flush vmlinux EXPORT_SYMBOL_GPL
++0x713c83fa    bio_phys_segments       vmlinux EXPORT_SYMBOL
++0xdaa57ec3    totalhigh_pages vmlinux EXPORT_SYMBOL
++0x2a2a7a3b    rndis_set_param_dev     vmlinux EXPORT_SYMBOL
++0x54fd2e8d    scsi_device_resume      vmlinux EXPORT_SYMBOL
++0x7a060e19    ipv6_find_tlv   vmlinux EXPORT_SYMBOL_GPL
++0x8fe6ac1e    neigh_changeaddr        vmlinux EXPORT_SYMBOL
++0xa38c2c00    snd_soc_jack_get_type   vmlinux EXPORT_SYMBOL_GPL
++0x710c73b6    crypto_unregister_notifier      vmlinux EXPORT_SYMBOL_GPL
++0xda0c24cc    invalidate_inode_pages2 vmlinux EXPORT_SYMBOL_GPL
++0x72741f25    trace_vbprintk  vmlinux EXPORT_SYMBOL_GPL
++0xccb0efda    do_unregister_con_driver        vmlinux EXPORT_SYMBOL_GPL
++0xa120d33c    tty_unregister_ldisc    vmlinux EXPORT_SYMBOL
++0xd644f377    tty_standard_install    vmlinux EXPORT_SYMBOL_GPL
++0x31222024    amba_apb_device_add_res vmlinux EXPORT_SYMBOL_GPL
++0xf8299259    cfg80211_michael_mic_failure    vmlinux EXPORT_SYMBOL
++0xbe53b873    ipt_do_table    vmlinux EXPORT_SYMBOL
++0xc96046ab    kmem_cache_destroy      vmlinux EXPORT_SYMBOL
++0x79105e99    add_to_page_cache_locked        vmlinux EXPORT_SYMBOL
++0x4e109192    ring_buffer_entries     vmlinux EXPORT_SYMBOL_GPL
++0x82a5e5e7    led_classdev_register   vmlinux EXPORT_SYMBOL_GPL
++0xd952a550    vb2_ioctl_reqbufs       vmlinux EXPORT_SYMBOL_GPL
++0xcb929a3c    scsi_calculate_bounce_limit     vmlinux EXPORT_SYMBOL
++0x33746f3f    xfrm_prepare_input      vmlinux EXPORT_SYMBOL
++0xd1dc81ae    xt_find_target  vmlinux EXPORT_SYMBOL
++0x92f468ad    drm_mode_object_find    vmlinux EXPORT_SYMBOL
++0x5a268d54    drm_clflush_sg  vmlinux EXPORT_SYMBOL
++0x827cc6a1    pptp_msg_name   vmlinux EXPORT_SYMBOL
++0xd4433787    vm_event_states vmlinux EXPORT_SYMBOL
++0x488b605d    __module_get    vmlinux EXPORT_SYMBOL
++0x081f3afb    complete_all    vmlinux EXPORT_SYMBOL
++0x9bce482f    __release_region        vmlinux EXPORT_SYMBOL
++0xd007f03b    phy_mii_ioctl   vmlinux EXPORT_SYMBOL
++0x5ef79e43    exynos_drm_subdrv_open  vmlinux EXPORT_SYMBOL_GPL
++0x34b60845    nfc_alloc_recv_skb      vmlinux EXPORT_SYMBOL
++0x075af6c0    cfg80211_reg_can_beacon vmlinux EXPORT_SYMBOL
++0x347013de    nla_validate    vmlinux EXPORT_SYMBOL
++0x70f6100f    bdi_register    vmlinux EXPORT_SYMBOL
++0xcf54ea93    async_unregister_domain vmlinux EXPORT_SYMBOL_GPL
++0xb6efaccd    rndis_rm_hdr    vmlinux EXPORT_SYMBOL
++0x5ed040b0    pm_set_vt_switch        vmlinux EXPORT_SYMBOL
++0x3ad0517a    tty_free_termios        vmlinux EXPORT_SYMBOL
++0x5fa643a3    amba_device_alloc       vmlinux EXPORT_SYMBOL_GPL
++0x73abc38f    inet_csk_clear_xmit_timers      vmlinux EXPORT_SYMBOL
++0x52e3e4a5    snd_pcm_hw_param_value  vmlinux EXPORT_SYMBOL
++0x7129e5f8    hex_asc vmlinux EXPORT_SYMBOL
++0xa0973520    fat_time_unix2fat       vmlinux EXPORT_SYMBOL_GPL
++0x522a28d0    mmc_regulator_get_supply        vmlinux EXPORT_SYMBOL_GPL
++0xac84055a    nf_nat_follow_master    vmlinux EXPORT_SYMBOL
++0x2aa0e4fc    strncasecmp     vmlinux EXPORT_SYMBOL
++0x9d5dfdfe    fuse_dev_release        vmlinux EXPORT_SYMBOL_GPL
++0xf54fdd41    default_llseek  vmlinux EXPORT_SYMBOL
++0xebec57c4    ring_buffer_oldest_event_ts     vmlinux EXPORT_SYMBOL_GPL
++0x329318c8    iio_channel_release_all vmlinux EXPORT_SYMBOL_GPL
++0xfc9a70ae    tty_get_pgrp    vmlinux EXPORT_SYMBOL_GPL
++0xdbf66d36    tcp_read_sock   vmlinux EXPORT_SYMBOL
++0xc18db9a3    snd_jack_new    vmlinux EXPORT_SYMBOL
++0x5df2ea54    sdhci_pltfm_free        vmlinux EXPORT_SYMBOL_GPL
++0x137901ef    ip_fragment     vmlinux EXPORT_SYMBOL
++0x815b5dd4    match_octal     vmlinux EXPORT_SYMBOL
++0x6b475280    bio_map_kern    vmlinux EXPORT_SYMBOL
++0x3abac74c    scsi_eh_prep_cmnd       vmlinux EXPORT_SYMBOL
++0xd162929f    tty_port_register_device_attr   vmlinux EXPORT_SYMBOL_GPL
++0x296f9f79    xt_register_targets     vmlinux EXPORT_SYMBOL
++0x27000b29    crc32c  vmlinux EXPORT_SYMBOL
++0x2956cef1    vfs_fsync       vmlinux EXPORT_SYMBOL
++0x18ae03d3    poll_freewait   vmlinux EXPORT_SYMBOL
++0x40c7247c    si_meminfo      vmlinux EXPORT_SYMBOL
++0x0034e52c    kthread_create_on_node  vmlinux EXPORT_SYMBOL
++0xeecb608e    i2c_smbus_write_byte    vmlinux EXPORT_SYMBOL
++0x907ada97    scsi_register_driver    vmlinux EXPORT_SYMBOL
++0x7cc1b7fd    max77693_bulk_read      vmlinux EXPORT_SYMBOL_GPL
++0x3274b08e    hdmi_avi_infoframe_init vmlinux EXPORT_SYMBOL
++0xde8c763d    cpu_v7_set_pte_ext      vmlinux EXPORT_SYMBOL
++0x2294b28a    snd_timer_pause vmlinux EXPORT_SYMBOL
++0x5e95b1cd    current_umask   vmlinux EXPORT_SYMBOL
++0xd2091a52    get_fs_type     vmlinux EXPORT_SYMBOL
++0x94893493    ref_module      vmlinux EXPORT_SYMBOL_GPL
++0x657ca634    iommu_domain_get_attr   vmlinux EXPORT_SYMBOL_GPL
++0x6b758637    iommu_domain_set_attr   vmlinux EXPORT_SYMBOL_GPL
++0xe835dcde    nf_nat_pptp_hook_outbound       vmlinux EXPORT_SYMBOL_GPL
++0x3ac1fef9    drm_mode_legacy_fb_format       vmlinux EXPORT_SYMBOL
++0x7cc88e22    tty_driver_kref_put     vmlinux EXPORT_SYMBOL
++0x24fc46b6    regulator_bulk_free     vmlinux EXPORT_SYMBOL_GPL
++0x776bea60    ip6_tnl_dst_check       vmlinux EXPORT_SYMBOL_GPL
++0x80690fc4    sock_prot_inuse_get     vmlinux EXPORT_SYMBOL_GPL
++0xb8aa9e8f    aead_geniv_init vmlinux EXPORT_SYMBOL_GPL
++0x35bac202    generic_write_end       vmlinux EXPORT_SYMBOL
++0x59e2743e    call_rcu_bh     vmlinux EXPORT_SYMBOL_GPL
++0x639f9176    devm_request_threaded_irq       vmlinux EXPORT_SYMBOL
++0x67955ce6    profile_hits    vmlinux EXPORT_SYMBOL_GPL
++0xa53a0240    usb_wakeup_notification vmlinux EXPORT_SYMBOL_GPL
++0xf5e3c0cf    scsi_host_set_state     vmlinux EXPORT_SYMBOL
++0x31b21f37    nat_t120_hook   vmlinux EXPORT_SYMBOL_GPL
++0xcd083b10    unregister_sound_dsp    vmlinux EXPORT_SYMBOL
++0xda529e9e    blk_start_queue vmlinux EXPORT_SYMBOL
++0xd84ce699    bio_copy_user   vmlinux EXPORT_SYMBOL
++0x7a4497db    kzfree  vmlinux EXPORT_SYMBOL
++0x91bbc6b9    genphy_config_aneg      vmlinux EXPORT_SYMBOL
++0x1c251434    of_mm_gpiochip_add      vmlinux EXPORT_SYMBOL
++0x8e10854d    inet_sk_diag_fill       vmlinux EXPORT_SYMBOL_GPL
++0x07d2ea7a    arpt_unregister_table   vmlinux EXPORT_SYMBOL
++0x2c038769    sk_filter       vmlinux EXPORT_SYMBOL
++0x57e267af    generic_removexattr     vmlinux EXPORT_SYMBOL
++0x643b400e    deactivate_super        vmlinux EXPORT_SYMBOL
++0xcf241a0c    vmap    vmlinux EXPORT_SYMBOL
++0x31f0bb78    __kmap_atomic_idx       vmlinux EXPORT_SYMBOL
++0x4e32f63f    devm_clk_put    vmlinux EXPORT_SYMBOL
++0x77f2c351    v4l2_ctrl_s_ctrl_int64  vmlinux EXPORT_SYMBOL
++0xed9fdd16    gether_setup_name_default       vmlinux EXPORT_SYMBOL
++0x6f572dd2    devm_remove_action      vmlinux EXPORT_SYMBOL_GPL
++0xa8f59416    gpio_direction_output   vmlinux EXPORT_SYMBOL_GPL
+diff --git a/abi-checker/src/Makefile b/abi-checker/src/Makefile
+new file mode 100644
+index 0000000..b020bc6
+--- /dev/null
++++ b/abi-checker/src/Makefile
+@@ -0,0 +1,31 @@
++PROGRAM = abi-checker
++GCC = gcc
++LDD = gcc
++
++CFLAGS = $(shell pkg-config --cflags glib-2.0 libelf) -I.
++
++LDFLAGS = $(shell pkg-config --libs glib-2.0 libelf)
++
++SRC = kernel_abi_checker.c kernel_abi_checker_elf.c
++
++HEADER = kernel_abi_checker.h
++
++DEST_DIR = /usr/local/bin
++
++OBJECTS = kernel_abi_checker.o kernel_abi_checker_elf.o
++
++all : $(PROGRAM)
++
++.c.o : $(HEADER)
++      $(GCC) -c $(CFLAGS) $< -o $@
++
++$(PROGRAM) : $(OBJECTS)
++      $(LDD) $(OBJECTS) -o $@ $(LDFLAGS)
++
++install :
++      mkdir -p $(DEST_DIR)
++      cp $(PROGRAM) $(DEST_DIR)
++
++clean :
++      rm -f $(PROGRAM)
++      rm -f $(OBJECTS)
+diff --git a/abi-checker/src/build_api_kernel_checker.sh b/abi-checker/src/build_api_kernel_checker.sh
+new file mode 100755
+index 0000000..d9e348b
+--- /dev/null
++++ b/abi-checker/src/build_api_kernel_checker.sh
+@@ -0,0 +1,24 @@
++#!/bin/sh
++
++# Find abi_version file
++ksymver=`find ../.. -name "Module.symvers"`
++
++# compare abi fingerprint file with kernel abi file
++./abi-checker test-kernel "${ksymver}" "../data/abi_${1}_${2}"
++rc="${?}"
++
++# Test result
++if [ ${rc} != "0" ]
++then
++      echo ""
++      echo "----------------------------------------------------------------------------------------------------------------------------"
++      echo ""
++      echo "The kernel ABI/API has changed. Please update kernel version and add a new abi-checker/data/abi_VERSION_ABIVER file "
++      echo "(example abi-checker/data/abi_${1}_${2} )."
++      echo "The kernel sources build will abort."
++      echo ""
++      echo ""
++      exit 1
++fi
++
++exit 0
+diff --git a/abi-checker/src/kernel_abi_checker.c b/abi-checker/src/kernel_abi_checker.c
+new file mode 100644
+index 0000000..ae362d6
+--- /dev/null
++++ b/abi-checker/src/kernel_abi_checker.c
+@@ -0,0 +1,834 @@
++/*
++ * Build command
++ *
++ * gcc `pkg-config --cflags glib-2.0` kernel_abi_checker.c kernel_abi_checker_elf.c -lglib-2.0 -lelf
++ */
++
++#include <stdio.h>
++#include <string.h>
++#include <stdlib.h>
++#include <glib.h>
++
++#include "kernel_abi_checker.h"
++
++/*
++ * Functions write single record into ouptu symver file
++ */
++int writeKernelSymbolsFile( FILE *ptr, char *symbolNameCrc, char *symbolName, char *symbolModule, char *flag )
++{
++      return fprintf( ptr, "%s\t%s\t%s\t%s\n", symbolNameCrc, symbolName, symbolModule, flag );
++}
++
++/*
++ * Function open *symver file
++ */
++FILE *getFile( char *fileName )
++{
++      FILE *fPtr = fopen( fileName, "r" );
++
++      if( fPtr == (FILE *)NULL )
++      {
++              PRINT_ERROR( "Canniot open : %s\n", fileName );
++              return (FILE *)NULL;
++      }
++
++      return fPtr;
++}
++
++FILE *getOutputFile( char *fileName )
++{
++      FILE *fPtr = fopen( fileName, "w" );
++
++      if( fPtr == (FILE *)NULL )
++      {
++              PRINT_ERROR( "Canniot open : %s\n", fileName );
++              return (FILE *)NULL;
++      }
++
++      return fPtr;
++}
++
++void releaseFile( FILE *fptr )
++{
++      if( fptr != (FILE *)NULL )
++              fclose( fptr );
++}
++
++void freeHashElement( gpointer data )
++{
++      free( (void *)data );
++}
++
++/*
++ * Function creates hash table
++ */
++GHashTable *createHashTable( void )
++{
++      return g_hash_table_new_full( g_str_hash, g_str_equal, NULL, freeHashElement );
++}
++
++/*
++ * Function destroy hash table
++ */
++void destroyHashTable( GHashTable *tab )
++{
++      if( tab != (GHashTable *)NULL )
++              g_hash_table_destroy( tab );
++}
++
++/*
++ * Function read i mput file.
++ * Function return single KernelSymbol structure.
++ *
++ * Return (KernelSymbol *)-1 - if errora
++          (KernelSymbol *)NULL - eof
++ *
++ */
++
++KernelSymbol *readFileLine( FILE *fptr )
++{
++      KernelSymbol *symbolPtr = (KernelSymbol *)NULL;
++      char inputLine[_LINE_LENGTH_ + 1];
++      char *crcPtr;
++      char *symNamePtr;
++      char *moduleNamePtr;
++      char *flag;
++      char *ptr;
++      int len;
++      int i;
++
++      memset( inputLine, 0, sizeof( inputLine ) );
++      ptr = fgets( inputLine, _LINE_LENGTH_, fptr );
++      if( ptr == (char *) NULL )
++              return (KernelSymbol *)NULL;
++
++      i = 0;
++
++      /* CRC */
++      crcPtr = inputLine + i;
++      for( ;inputLine[i] != '\0' && inputLine[i] != '\t' && i < _LINE_LENGTH_; i ++ );
++
++      if( i >= _LINE_LENGTH_ )
++      {
++              PRINT_ERROR( "Incorect input record format : \"%s\"\n", inputLine );
++              return (KernelSymbol *)-1;
++      }
++      inputLine[i] = '\0';
++      i++;
++
++      /* Symbol name */
++      symNamePtr = inputLine + i;
++
++      for( ;inputLine[i] != '\0' && inputLine[i] != '\t' && i < _LINE_LENGTH_; i ++ );
++      if( i >= _LINE_LENGTH_ )
++      {
++              PRINT_ERROR( "Incorect input record format : \"%s\"\n", inputLine );
++              return (KernelSymbol *)-1;
++      }
++      inputLine[i] = '\0';
++      i ++;
++
++      /* Module name */
++      moduleNamePtr = inputLine + i;
++
++
++      for( ;inputLine[i] != '\0' && inputLine[i] != '\t' && i < _LINE_LENGTH_; i ++ );
++      if( i >= _LINE_LENGTH_ )
++      {
++              PRINT_ERROR( "Incorect input record format : \"%s\"\n", inputLine );
++              return (KernelSymbol *)-1;
++      }
++      inputLine[i] = '\0';
++      i ++;
++
++      /* Flag */
++      flag = inputLine + i;
++
++
++      len = strlen( flag );
++      flag[len ==  0 ? 0 : len -1] = '\0';
++
++      /* Allocate new KernelSymbol */
++      symbolPtr = (KernelSymbol *)malloc( sizeof( KernelSymbol ) );
++      if( symbolPtr == (KernelSymbol *)NULL )
++              return (KernelSymbol *)-1;
++
++      for( i = 0; moduleNamePtr[i] != '\0' && moduleNamePtr[i] != '\n'; i ++ );
++      moduleNamePtr[i] = '\0';
++
++      /* Polulate output structure */
++      strncpy( symbolPtr -> symbolName, symNamePtr, KERNEL_SYMBOL_NAME_LENGTH );
++      strncpy( symbolPtr -> symbolNameCrc, crcPtr, KERNEL_SYMBOL_NAME_CRC );
++      strncpy( symbolPtr -> symbolModule, moduleNamePtr, KERNEL_SYMBOL_MODULE );
++      strncpy( symbolPtr -> flag, flag, KERNEL_SYMBOL_FLAG );
++      symbolPtr -> status = KERNEL_SYMBOL_STATUS_NO_TESTED;
++
++      /* Return KernModule structure */
++      return symbolPtr;
++}
++
++/*
++ * Function adds single kernel symbol into hashtable.
++ * Functions assumes that hash table is correctlly allocated.
++ *
++ * Returns:
++ * -1 - duplicated key
++ *  0 - success
++ */
++
++int addKernelSymboltoHashBase( void *s, char *key, GHashTable *tab )
++{
++      void *testSym;
++
++      /* Check duplicates */
++      testSym = (void *)g_hash_table_lookup( tab, key );
++      if( testSym != (void *)NULL )
++              return -1;
++
++      /* Add new symbol into hash table */
++      g_hash_table_insert( tab, key, s );
++      return 0;
++}
++
++int addKernelSymboltoHash( KernelSymbol *s, GHashTable *tab )
++{
++      return addKernelSymboltoHashBase( (void *)s, s -> symbolName, tab );
++}
++
++int readFile( FILE *fptr, GHashTable *tab )
++{
++        KernelSymbol *sym = (KernelSymbol *)NULL;
++        while( 1 == 1 )
++        {
++                sym = readFileLine( fptr );
++              if( sym == (KernelSymbol *)NULL )
++              {
++                      /* Koniec pliku */
++                      break;
++              }
++
++              if( sym == (KernelSymbol *)-1 )
++              {
++                      /* Error */
++                      return -1;
++              }
++
++              if( addKernelSymboltoHash( sym, tab ) < 0 )
++              {
++                      /* Error - duplicated value */
++                      return -1;
++              }
++        }
++
++      /* Success */
++      return 0;
++}
++
++GHashTable *procesInputFile( char *name )
++{
++      GHashTable *hashTable = (GHashTable *)NULL;
++      FILE *fptr = (FILE *)NULL;
++
++      /* Open input file */
++      fptr = getFile( name );
++      if( fptr == (FILE *)NULL )
++              return (GHashTable *)NULL;
++
++      /* Create hash table for current symver */
++      hashTable = createHashTable();
++      if( hashTable == (GHashTable *)NULL )
++      {
++              PRINT_ERROR( "Error creating hash table \n" );
++              releaseFile( fptr );
++              return (GHashTable *)NULL;
++      }
++
++      /* Read and create current hash table */
++      if( readFile( fptr, hashTable ) != 0 )
++      {
++              PRINT_ERROR( "Error reading %s\n", name );
++              destroyHashTable( hashTable );
++              releaseFile( fptr );
++              return (GHashTable *)NULL;
++      }
++
++      /* Close input file */
++      releaseFile( fptr );
++
++      return hashTable;
++}
++
++typedef struct _foreachHashData_
++{
++      KernelSymbolStatistics *stat;
++      GHashTable *curr;
++      GHashTable *new;
++} _foreachHashData_;
++
++void calculateStatistics_1( gpointer key_, gpointer value_, gpointer user_data_ )
++{
++      KernelSymbol *value = (KernelSymbol *)value_;
++      _foreachHashData_ *user_data = (_foreachHashData_ *)user_data_;
++      KernelSymbol *newSym;
++
++      /* Update current hash table symbols count */
++      user_data -> stat -> symver_current_count ++;
++
++      /* Search for symbol in new hash table */
++      newSym = (KernelSymbol *)g_hash_table_lookup( user_data -> new, key_ );
++
++      if( newSym == (KernelSymbol *)NULL )
++      {
++              /* Symbol was removed */
++
++              /* Set status */
++              value -> status = KERNEL_SYMBOL_STATUS_REMOVED;
++
++              user_data -> stat -> removed_symbols_count ++;
++              return;
++      }
++
++      newSym -> status = KERNEL_SYMBOL_STATUS_VIEWED;
++
++      if( strcmp( value -> symbolNameCrc, newSym -> symbolNameCrc ) == 0 )
++      {
++              user_data -> stat -> no_changed_symbols_count ++;
++              value -> status = KERNEL_SYMBOL_STATUS_NO_CHANGES;
++      }
++      else
++      {
++              user_data -> stat -> changed_symbols_count ++;
++              value -> status = KERNEL_SYMBOL_STATUS_CHANGED;
++      }
++}
++
++void calculateStatistics_2( gpointer key_, gpointer value_, gpointer user_data_ )
++{
++      KernelSymbol *value = (KernelSymbol *)value_;
++      _foreachHashData_ *user_data = (_foreachHashData_ *)user_data_;
++
++      /* Update current hash table symbols count */
++      user_data -> stat -> symver_new_count ++;
++
++      if( value -> status == KERNEL_SYMBOL_STATUS_NO_TESTED )
++      {
++              user_data -> stat -> new_symbols_count ++;
++              value -> status = KERNEL_SYMBOL_STATUS_NEW;
++      }
++}
++
++void collectStatistics( GHashTable *curr, GHashTable *new, KernelSymbolStatistics *statistics )
++{
++      _foreachHashData_ foreachdata;
++
++      /* Init foreach data */
++      memset( (void *)statistics, 0, sizeof( KernelSymbolStatistics ) );
++      foreachdata.stat = statistics;
++      foreachdata.curr = curr;
++      foreachdata.new = new;
++
++      /* Scan current hash table */
++      g_hash_table_foreach( curr, calculateStatistics_1, (gpointer)&foreachdata );
++
++      /* Scan new hash table */
++      g_hash_table_foreach( new, calculateStatistics_2, (gpointer)&foreachdata );
++}
++
++void reportSymbolsDetails( gpointer key_, gpointer value_, gpointer user_data_ )
++{
++      KernelSymbol *value = (KernelSymbol *)value_;
++
++      switch( *((int *)user_data_) )
++      {
++      case 0 :        /* New */
++              if( value -> status == KERNEL_SYMBOL_STATUS_NEW )
++                      PRINT_INFO_RAW( "\t| NEW     | %40s | %10s | %s\n", value -> symbolName, value -> symbolNameCrc, value -> symbolModule );
++              break;
++
++      case 1 :        /* Changed */
++              if( value -> status == KERNEL_SYMBOL_STATUS_CHANGED )
++                      PRINT_INFO_RAW( "\t| CHANGED | %40s | %10s | %s\n", value -> symbolName, value -> symbolNameCrc, value -> symbolModule );
++              break;
++
++      case 2 :        /* Removed */
++              if( value -> status == KERNEL_SYMBOL_STATUS_REMOVED )
++                      PRINT_INFO_RAW( "\t| REMOVED | %40s | %10s | %s\n", value -> symbolName, value -> symbolNameCrc, value -> symbolModule );
++              break;
++      }
++}
++//[CHANGED]         cfg80211_send_rx_assoc         0x80e54114                  vmlinux
++
++void listChangedSymbols( GHashTable *curr, GHashTable *new, KernelSymbolStatistics *statistics )
++{
++      int mode = 0;
++      int printFooter = 0;
++
++      if( statistics -> new_symbols_count == 0 && statistics -> changed_symbols_count == 0 && statistics -> removed_symbols_count == 0 )
++              return;
++
++      PRINT_INFO_RAW( "\n" );
++
++      PRINT_INFO_RAW( "\tNew symbols in kernel\n" );
++      PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
++      PRINT_INFO_RAW( "\t| Change  |                 Linux kernel symbol name |        CRC | Module name \n" );
++      PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
++
++      if( statistics -> new_symbols_count != 0 && new != (GHashTable *)NULL )
++      {
++              mode = 0;
++              g_hash_table_foreach( new, reportSymbolsDetails, (gpointer)&mode );
++              printFooter = 1;
++      }
++
++      if( statistics -> changed_symbols_count != 0 && curr != (GHashTable *)NULL )
++      {
++              if( statistics -> new_symbols_count != 0 )
++                      PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
++
++              mode = 1;
++              g_hash_table_foreach( curr, reportSymbolsDetails, (gpointer)&mode );
++              printFooter = 1;
++      }
++
++      if( statistics -> removed_symbols_count != 0 && curr != (GHashTable *)NULL )
++      {
++              if( statistics -> new_symbols_count != 0 || statistics -> changed_symbols_count != 0 )
++                      PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
++
++              mode = 2;
++              g_hash_table_foreach( curr, reportSymbolsDetails, (gpointer)&mode );
++              printFooter = 1;
++      }
++
++      if( printFooter == 1 )
++              PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
++}
++
++void reportsStatistics( GHashTable *curr, GHashTable *new, KernelSymbolStatistics *statistics )
++{
++      listChangedSymbols( curr, new, statistics );
++
++      PRINT_INFO_RAW( "\n" );
++      PRINT_INFO_RAW( "\tKernel symbols version statistics \n" );
++      PRINT_INFO_RAW( "\t-------------------------------------------------\n" );
++      PRINT_INFO_RAW( "\tSymbols in actual kernel/module . %d\n", statistics -> symver_current_count );
++      if( new != (GHashTable *)NULL )
++              PRINT_INFO_RAW( "\tSymbols in new kernel/module .... %d\n", statistics -> symver_new_count );
++      PRINT_INFO_RAW( "\tNew symbols ..................... %d\n", statistics -> new_symbols_count );
++      PRINT_INFO_RAW( "\tRemoved symbols ................. %d\n", statistics -> removed_symbols_count );
++      PRINT_INFO_RAW( "\tChanged symbols ................. %d\n", statistics -> changed_symbols_count );
++      PRINT_INFO_RAW( "\tUnchanged symbols ............... %d\n", statistics -> no_changed_symbols_count );
++      PRINT_INFO_RAW( "\n" );
++}
++
++void printUsage( char *progName, int type )
++{
++      switch( type )
++      {
++      case 0 :
++              PRINT_INFO_RAW( "\tUsage: %s test-kernel in_symver_file_1 in_symver_file_2\n", progName );
++              break;
++
++      case 1 :
++              PRINT_INFO_RAW( "\tUsage: %s build-list in_module_symbols_file in_kernel_symver_file outt_module_symver_file\n", progName );
++              break;
++
++      case 2 :
++              PRINT_INFO_RAW( "\tUsage: %s dump-module kernel_symver_file ko_module_file output_module_symver_file\n", progName );
++              break;
++
++      case 4 :
++              PRINT_INFO_RAW( "\tUsage: %s test-module kernel_symver_file ko_module_file \n", progName );
++              break;
++
++      default :
++              PRINT_INFO_RAW( "\tUsage: %s test|build-list file1 file2 [output_file] \n", progName );
++              break;
++      }
++}
++
++/*
++ * Function parses input parameters and return.
++ * Return:
++ *            -1 - error
++ *             0 - test mode  - the program will compare two symver files
++ *             1 - build mode - for given module sybmbols file and kernel symver creates files
++ *                              with list kernel symbols used by the module.
++ */
++int parsInputParameters( int argc, char **argv, char **f1, char **f2, char **f3 )
++{
++      char *toolName = argv[0];
++
++      if( argc < 2 )
++      {
++              printUsage( toolName, -1 );
++              return -1;
++      }
++
++      if( strcmp( argv[1], "test-kernel" ) == 0 )
++      {
++              /* Test mode */
++              if( argc < 4 )
++              {
++                      printUsage( toolName, 0 );
++                      return -1;
++              }
++              *f1 = argv[2];
++              *f2 = argv[3];
++              *f3 = (char *)NULL;
++
++              return 0;
++
++      }
++      else
++      if( strcmp( argv[1], "build-list" ) == 0 )
++      {
++              /* Build mode */
++              if( argc < 5 )
++              {
++                      printUsage( toolName, 1 );
++                      return -1;
++              }
++              *f1 = argv[2];
++              *f2 = argv[3];
++              *f3 = argv[4];
++
++              return 1;
++      }
++      else
++      if( strcmp( argv[1], "dump-module" ) == 0 )
++      {
++              /* Build mode */
++              if( argc < 5 )
++              {
++                      printUsage( toolName, 2 );
++                      return -1;
++              }
++              *f1 = argv[2];
++              *f2 = argv[3];
++              *f3 = argv[4];
++
++              return 2;
++      }
++      else
++      if( strcmp( argv[1], "usage" ) == 0 )
++      {
++              return 3;
++      }
++      else
++      if( strcmp( argv[1], "test-module" ) == 0 )
++      {
++              /* Test mode */
++              if( argc < 4 )
++              {
++                      printUsage( toolName, 4 );
++                      return -1;
++              }
++              *f1 = argv[2];
++              *f2 = argv[3];
++              *f3 = (char *)NULL;
++
++              return 4;
++      }
++
++
++      printUsage( toolName, -1 );
++      return -1;
++}
++
++int testKernel( char *f1, char *f2 )
++{
++      GHashTable *curr_hashTable = (GHashTable *)NULL;
++      GHashTable *new_hashTable = (GHashTable *)NULL;
++      KernelSymbolStatistics statistics;
++
++      /*
++       * ----------------------------------------------
++       * Read current symver file
++       * ----------------------------------------------
++       */
++      curr_hashTable = procesInputFile( f1 );
++      if( curr_hashTable == (GHashTable *)NULL )
++      {
++              PRINT_ERROR( "Error read input \"%s\" file.\n", f1 );
++              return 1;
++      }
++
++      /*
++       * ----------------------------------------------
++       * Read new symver file
++       * ----------------------------------------------
++      */
++      new_hashTable = procesInputFile( f2 );
++      if( new_hashTable == (GHashTable *)NULL )
++      {
++              destroyHashTable( curr_hashTable );
++              PRINT_ERROR( "Error read input \"%s\" file.\n", f2 );
++        return 1;
++      }
++
++      /*
++       * ----------------------------------------------
++       * Compute statistics
++       * ----------------------------------------------
++       */
++      collectStatistics( curr_hashTable, new_hashTable, &statistics );
++
++      /*
++       * ---------------------------------------------
++       * Report changes
++       * ---------------------------------------------
++       */
++      reportsStatistics( curr_hashTable, new_hashTable, &statistics );
++
++      /*
++       * --------------------------------------------
++       * Free hash tables
++       * --------------------------------------------
++       */
++      destroyHashTable( curr_hashTable );
++      destroyHashTable( new_hashTable );
++
++      if( statistics.changed_symbols_count != 0 || statistics.removed_symbols_count != 0 || statistics.new_symbols_count != 0 )
++              return 2;
++
++      return 0;
++}
++
++void collectStatisticsModule( GHashTable *curr, GHashTable *module, KernelSymbolStatistics *statistics )
++{
++      _foreachHashData_ foreachdata;
++
++      /* Init foreach data */
++      memset( (void *)statistics, 0, sizeof( KernelSymbolStatistics ) );
++      foreachdata.stat = statistics;
++      foreachdata.curr = module;
++      foreachdata.new = curr;
++
++      /* Scan current hash table */
++      g_hash_table_foreach( module, calculateStatistics_1, (gpointer)&foreachdata );
++}
++
++
++int testModule( char *f1, char *f2 )
++{
++      GHashTable *curr_hashTable = (GHashTable *)NULL;
++      GHashTable *module_hashTable = (GHashTable *)NULL;
++      KernelSymbolStatistics statistics;
++
++      /*
++       * ----------------------------------------------
++       * Read current symver file
++       * ----------------------------------------------
++       */
++      curr_hashTable = procesInputFile( f1 );
++      if( curr_hashTable == (GHashTable *)NULL )
++      {
++              PRINT_ERROR( "Error read input \"%s\" file.\n", f1 );
++              return 1;
++      }
++
++      /*
++       * ----------------------------------------------
++       * Read module symbols
++       * ----------------------------------------------
++      */
++      module_hashTable = procesInputFile( f2 );
++      if( module_hashTable == (GHashTable *)NULL )
++      {
++              destroyHashTable( curr_hashTable );
++              PRINT_ERROR( "Error read input \"%s\" file.\n", f2 );
++        return 1;
++      }
++
++      /*
++       * ----------------------------------------------
++       * Compute statistics
++       * ----------------------------------------------
++       */
++      collectStatisticsModule( curr_hashTable, module_hashTable, &statistics );
++
++      /*
++       * ---------------------------------------------
++       * Report changes
++       * ---------------------------------------------
++       */
++      reportsStatistics( module_hashTable, (GHashTable *)NULL, &statistics );
++
++      /*
++       * --------------------------------------------
++       * Free hash tables
++       * --------------------------------------------
++       */
++      destroyHashTable( curr_hashTable );
++      destroyHashTable( module_hashTable );
++
++      if( statistics.changed_symbols_count != 0 || statistics.removed_symbols_count != 0 )
++              return 2;
++
++      return 0;
++}
++
++int buildListMode( char *f1, char *f2, char *f3 )
++{
++      GHashTable *curr_hashTable = (GHashTable *)NULL;
++      char inputLine[_LINE_LENGTH_ + 1];
++      FILE *symListFptr = (FILE *)NULL;
++      FILE *outFptr = (FILE *)NULL;
++      KernelSymbol *kSym;
++      int size;
++
++      /*
++       * ----------------------------------------------
++       * Read current symver file
++       * ----------------------------------------------
++       */
++      curr_hashTable = procesInputFile( f1 );
++      if( curr_hashTable == (GHashTable *)NULL )
++      {
++              PRINT_ERROR( "Error read input \"%s\" file.\n", f1 );
++              return 1;
++      }
++
++      /*
++       * Open files
++       */
++      outFptr = getOutputFile( f3 );
++      symListFptr = getFile( f2 );
++
++      if( symListFptr == (FILE *)NULL || outFptr == (FILE *)NULL )
++      {
++              destroyHashTable( curr_hashTable );
++              releaseFile( symListFptr );
++              releaseFile( outFptr );
++              PRINT_ERROR( "Error open files : \"%s\", \"%s\".\n", f2, f3 );
++              return 1;
++      }
++
++      while( fgets( inputLine, _LINE_LENGTH_, symListFptr ) )
++      {
++              size = strlen( inputLine );
++              inputLine[size == 0 ? 0 :size - 1] = '\0';
++
++              /* Search for symbol in new hash table */
++              kSym = (KernelSymbol *)g_hash_table_lookup( curr_hashTable, inputLine );
++
++              if( kSym != (KernelSymbol *)NULL )
++                      writeKernelSymbolsFile( outFptr, kSym -> symbolNameCrc, kSym -> symbolName, kSym -> symbolModule, kSym -> flag );
++      }
++
++      destroyHashTable( curr_hashTable );
++      releaseFile( symListFptr );
++      releaseFile( outFptr );
++
++      return 0;
++}
++
++int callDumpModuleSymbols( char *f1, char *f2, char *f3 )
++{
++      GHashTable *curr_hashTable = (GHashTable *)NULL;
++      GHashTable *module_hashTable = (GHashTable *)NULL;
++
++      /*
++       * ----------------------------------------------
++       * Read current symver file
++       * ----------------------------------------------
++       */
++      curr_hashTable = procesInputFile( f1 );
++      if( curr_hashTable == (GHashTable *)NULL )
++      {
++              PRINT_ERROR( "Error read input \"%s\" file.\n", f1 );
++              return 1;
++      }
++
++      /*
++       * ----------------------------------------------
++       * Read kernel module *.ko file
++       * ----------------------------------------------
++       */
++      module_hashTable = readEfl( f2 );
++      if( module_hashTable == (GHashTable *)NULL )
++      {
++              PRINT_ERROR( "Error read input \"%s\" file.\n", f2 );
++              destroyHashTable( curr_hashTable );
++              return 1;
++      }
++
++      /*
++       * Dump module symbols into output file
++       */
++      if( dumpModuleSymbols( f3, module_hashTable, curr_hashTable ) < 0 )
++      {
++              PRINT_ERROR( "Error creating dump file \"%s\"\n", f3 );
++              destroyHashTable( curr_hashTable );
++              return 1;
++      }
++
++      /*
++       * Free hash tables
++       */
++      destroyHashTable( module_hashTable );
++      destroyHashTable( curr_hashTable );
++
++      return 0;
++}
++
++int printUsageInfo( char *f1 )
++{
++      PRINT_INFO_RAW( "\n" );
++      PRINT_INFO_RAW( "\tProgram usage\n" );
++      PRINT_INFO_RAW( "\t-----------------------------------------------\n" );
++      PRINT_INFO_RAW( "\n" );
++      printUsage( f1, 0 );
++      printUsage( f1, 1 );
++      printUsage( f1, 2 );
++
++      return 0;
++}
++
++int main(int argc, char** argv)
++{
++      char *f1 = (char *)NULL;
++      char *f2 = (char *)NULL;
++      char *f3 = (char *)NULL;
++      int rc = -1;
++
++      int mode = parsInputParameters( argc, argv, &f1, &f2, &f3 );
++
++      switch( mode )
++      {
++      case 0 :
++              rc = testKernel( f1, f2 );
++              break;
++
++      case 1 :
++              rc = buildListMode( f1, f2, f3 );
++              break;
++
++      case 2 :
++              rc = callDumpModuleSymbols( f1, f2, f3 );
++              break;
++
++      case 3 :
++              rc = printUsageInfo( argv[0] );
++              break;
++
++      case 4 :
++              rc = testModule( f1, f2 );
++              break;
++      }
++
++      PRINT_INFO_RAW( "\n" );
++
++      if( rc == 2 )
++              PRINT_INFO_RAW( "\tChanges !!!\n" );
++      else
++      if( rc == 1 )
++              PRINT_INFO_RAW( "\tError !!!\n" );
++      else
++              PRINT_INFO_RAW( "\tDone\n" );
++
++      PRINT_INFO_RAW( "\n" );
++
++      return ( rc != 0 ) ? 1 : 0;
++}
+diff --git a/abi-checker/src/kernel_abi_checker.h b/abi-checker/src/kernel_abi_checker.h
+new file mode 100644
+index 0000000..8df231e
+--- /dev/null
++++ b/abi-checker/src/kernel_abi_checker.h
+@@ -0,0 +1,62 @@
++#ifndef _kernel_abi_checker_h_
++#define _kernel_abi_checker_h_
++
++#include <stdio.h>
++#include <glib.h>
++
++/*
++ * Definitions
++ */
++#define KERNEL_SYMBOL_NAME_LENGTH     64
++#define KERNEL_SYMBOL_NAME_CRC                32
++#define KERNEL_SYMBOL_MODULE          256
++#define KERNEL_SYMBOL_FLAG                    256
++
++#define KERNEL_SYMBOL_STATUS_NO_TESTED        0
++#define KERNEL_SYMBOL_STATUS_NO_CHANGES       1
++#define KERNEL_SYMBOL_STATUS_NEW              2
++#define KERNEL_SYMBOL_STATUS_REMOVED  3
++#define KERNEL_SYMBOL_STATUS_CHANGED  4
++#define KERNEL_SYMBOL_STATUS_VIEWED           5
++
++#define _LINE_LENGTH_ 4096
++
++/*
++ * Data types
++ */
++typedef struct KernelSymbol
++{
++      char symbolName[KERNEL_SYMBOL_NAME_LENGTH + 1];
++      char symbolNameCrc[KERNEL_SYMBOL_NAME_CRC + 1];
++      char symbolModule[KERNEL_SYMBOL_MODULE + 1];
++      char flag[KERNEL_SYMBOL_FLAG + 1];
++      int status;
++
++} KernelSymbol;
++
++typedef struct KernelSymbolStatistics
++{
++      int symver_current_count;
++      int symver_new_count;
++
++      int new_symbols_count;
++      int removed_symbols_count;
++      int changed_symbols_count;
++      int no_changed_symbols_count;
++
++} KernelSymbolStatistics;
++
++extern int writeKernelSymbolsFile( FILE *, char *, char *, char *, char * );
++extern int addKernelSymboltoHashBase( void *, char *, GHashTable * );
++extern int dumpModuleSymbols( char *, GHashTable *, GHashTable * );
++extern void destroyHashTable( GHashTable * );
++extern GHashTable *createHashTable( void );
++extern FILE *getOutputFile( char * );
++extern void releaseFile( FILE * );
++GHashTable *readEfl( char * );
++
++#define PRINT_ERROR(...)  do { fprintf( stderr, "ERROR : " ); fprintf( stderr, __VA_ARGS__ ); } while( 0 )
++#define PRINT_INFO_RAW(...)   do { fprintf( stdout, __VA_ARGS__ ); } while( 0 )
++#define PRINT_INFO(...)   do { fprintf( stderr, "INFO  : " ); fprintf( stdout, __VA_ARGS__ ); } while( 0 )
++
++#endif
+diff --git a/abi-checker/src/kernel_abi_checker_elf.c b/abi-checker/src/kernel_abi_checker_elf.c
+new file mode 100644
+index 0000000..6f4f28c
+--- /dev/null
++++ b/abi-checker/src/kernel_abi_checker_elf.c
+@@ -0,0 +1,172 @@
++#include "kernel_abi_checker.h"
++
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <unistd.h>
++#include <string.h>
++#include <stdlib.h>
++#include <libelf.h>
++#include <stdio.h>
++#include <fcntl.h>
++#include <gelf.h>
++
++GHashTable *readEfl( char *file )
++{
++      GHashTable *outputHashTable = (GHashTable *)NULL;
++      Elf_Data *edata = (Elf_Data *)NULL;
++      Elf_Scn *scn = (Elf_Scn *)NULL;
++      char *base_ptr = (char *)NULL;
++      char *sname = (char *)NULL;
++      Elf *elf = (Elf *)NULL;
++      struct stat elf_stats;
++      int symbol_count;
++      GElf_Shdr shdr;
++      GElf_Sym sym;
++      int size;
++      int fd;
++      int i;
++
++      fd = open( file, O_RDONLY );
++      if( fd < 0 )
++      {
++              PRINT_ERROR( "Cannot open efl file : %s\n", file );
++              return (GHashTable *)NULL;
++      }
++
++      if( ( fstat( fd, &elf_stats ) ) )
++      {
++              PRINT_ERROR( "Cannot stat efl file : %s\n", file );
++              close(fd );
++              return (GHashTable *)NULL;
++      }
++
++      base_ptr = (char *) malloc( elf_stats.st_size );
++      if( base_ptr == (char *)NULL )
++      {
++              PRINT_ERROR( "Memory allocation error.\n" );
++              close( fd );
++              return (GHashTable *)NULL;
++      }
++
++      if( ( read( fd, base_ptr, elf_stats.st_size ) ) < elf_stats.st_size )
++      {
++              PRINT_ERROR( "Cannot read input efl file : %s\n", file );
++        free( base_ptr );
++        close( fd );
++              return (GHashTable *)NULL;
++      }
++      free( base_ptr );
++
++      /* Create output hash table */
++      outputHashTable = createHashTable();
++      if( outputHashTable == (GHashTable *)NULL )
++      {
++              PRINT_ERROR( "Memory allocation for hash table error : %s\n", file );
++        free( base_ptr );
++        close( fd );
++              return (GHashTable *)NULL;
++      }
++
++      if( elf_version( EV_CURRENT ) == EV_NONE )
++              fprintf( stderr, "WARNING Elf Library is out of date!\n" );
++
++      // Iterate through section headers again this time well stop when we find symbols
++      elf = elf_begin( fd, ELF_C_READ, NULL );
++
++      while( ( scn = elf_nextscn( elf, scn ) ) != (Elf_Scn *)NULL )
++      {
++              gelf_getshdr( scn, &shdr );
++
++              // When we find a section header marked SHT_SYMTAB stop and get symbols
++              if(shdr.sh_type == SHT_SYMTAB)
++              {
++                      // edata points to our symbol table
++                      edata = elf_getdata(scn, edata);
++
++                      symbol_count = shdr.sh_size / shdr.sh_entsize;
++
++                      for( i = 0; i < symbol_count; i++ )
++                      {
++                              /* Get symbol */
++                              gelf_getsym( edata, i, &sym );
++
++                              /* Get symbol name length */
++                              size = strlen( elf_strptr( elf, shdr.sh_link, sym.st_name ) );
++                              if( size != 0 )
++                              {
++                                      /* allocate memory for symbol name */
++                                      sname = (char *)malloc( sizeof( char ) * ( size + 1 ) );
++                                      if( sname == (char *)NULL )
++                                      {
++                                              PRINT_ERROR( "Memory allocation for hash table error : %s\n", file );
++                                              destroyHashTable( outputHashTable );
++                                      close( fd );
++                                              return (GHashTable *)NULL;
++                                      }
++
++                                      strcpy( sname, elf_strptr( elf, shdr.sh_link, sym.st_name ) );
++
++                                      // Add symbol to hash
++                                      if( addKernelSymboltoHashBase( (void *)sname, sname, outputHashTable ) < 0 )
++                                      {
++                                              // If duplicated key free memory
++                                              free( sname );
++                                      }
++
++                              }
++                      }
++              }
++      }
++
++      /* Close file */
++      close( fd );
++
++      /* Return hash table */
++      return outputHashTable;
++}
++
++/*
++ * Private user data definition.
++ */
++
++typedef struct _efl_user_data_
++{
++      GHashTable *kernelHash;
++      FILE *outFilePtr;
++} _efl_user_data_;
++
++
++void dumpModuleSymbolsIteration( gpointer key_, gpointer value_, gpointer user_data_ )
++{
++      char *key = (char *)key_;
++      _efl_user_data_ *user_data = (_efl_user_data_ *)user_data_;
++      KernelSymbol *ptr = (KernelSymbol *)NULL;
++
++      ptr = (KernelSymbol *)g_hash_table_lookup( user_data -> kernelHash, key );
++      if( ptr != (void *)NULL )
++              writeKernelSymbolsFile( user_data -> outFilePtr, ptr -> symbolNameCrc, ptr -> symbolName, ptr -> symbolModule, ptr -> flag );
++}
++
++/*
++ * Function dumps into output files kernel symbols that
++ * are use in the module
++ */
++int dumpModuleSymbols( char *outoutFile, GHashTable *moduleSymbols, GHashTable *kernelSymbols )
++{
++      FILE *outputFilePtr = getOutputFile( outoutFile );
++      _efl_user_data_ userData;
++
++      if( outputFilePtr == (FILE *)NULL )
++              return -1;
++
++      userData.outFilePtr = outputFilePtr;
++      userData.kernelHash = kernelSymbols;
++
++      /* Loob module symbols */
++      g_hash_table_foreach( moduleSymbols, dumpModuleSymbolsIteration, (gpointer)&userData );
++
++      /* Close output file */
++      releaseFile( outputFilePtr );
++
++      return 0;
++}
+diff --git a/packaging/linux-kernel.spec b/packaging/linux-kernel.spec
+index 5e64441..e199f9b 100644
+--- a/packaging/linux-kernel.spec
++++ b/packaging/linux-kernel.spec
+@@ -1,5 +1,6 @@
++%bcond_with abidev
+ %define config_name tizen_defconfig
+-%define abiver current
++%define abiver 1
+ %define build_id %{config_name}.%{abiver}
+ Name: linux-kernel
+@@ -12,7 +13,12 @@ Vendor: The Linux Community
+ URL: http://www.kernel.org
+ Source0:   %{name}-%{version}-%{build_id}.tar.gz
+ BuildRoot: %{_tmppath}/%{name}-%{PACKAGE_VERSION}-root
++
++BuildRequires: pkgconfig(glib-2.0)
++BuildRequires: pkgconfig(libelf)
++
+ BuildRequires: linux-glibc-devel
++BuildRequires: u-boot-tools
+ BuildRequires: bc
+ %define kernel_build_dir_name .%{name}-%{version}-%{build_id}
+@@ -21,6 +27,15 @@ BuildRequires: bc
+ %description
+ The Linux Kernel, the operating system core itself
++%if %{with abidev}
++%package abi-dev
++Summary: Header files for the Linux kernel for use by glibc
++Group: Development/System
++
++%description abi-dev
++The package provide linux kernel API/ABI development file.
++%endif
++
+ %package headers
+ Summary: Header files for the Linux kernel for use by glibc
+ Group: Development/System
+@@ -29,11 +44,18 @@ Provides: kernel-headers = %{version}
+ %description headers
+ Kernel-headers includes the C header files that specify the interface
+-between the Linux kernel and userspace libraries and programs.  The
++between the Linux kernel and userspace libraries and programs. The
+ header files define structures and constants that are needed for
+ building most standard programs and are also needed for rebuilding the
+ glibc package.
++%package abi-tools
++Summary: Kernael ABI tools
++Group: Development/System
++
++%description abi-tools
++The package provide set of tools to test and create ABI/API dumps.
++
+ %package sources
+ Summary: Full linux kernel sources for out-of-tree modules
+ Group: Development/System
+@@ -50,10 +72,20 @@ Requires: kernel-sources = %{version}-%{build_id}
+ %description build
+ Prebuilt linux kernel for out-of-tree modules.
++%package uImage
++Summary: Linux kernel image
++Group: Development/System
++
++%description uImage
++Linux kernel uImage
++
+ %prep
+ %setup -q
+ %build
++# 0. Build abi checker
++make -C abi-checker/src
++
+ # 1. Create main build directory
+ rm -rf %{kernel_build_dir}
+ mkdir -p %{kernel_build_dir}
+@@ -68,6 +100,15 @@ mkdir -p %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}
+ make EXTRAVERSION="-%{build_id}" O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} %{config_name}
+ make EXTRAVERSION="-%{build_id}" O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} %{?_smp_mflags}
++# 4.1 Test ABI/API kernel change
++%if %{with abidev}
++echo "No linuks kernel ABI/API checks"
++%else
++( cd abi-checker/src; chmod 755 build_api_kernel_checker.sh; ./build_api_kernel_checker.sh "%{version}" "%{abiver}" )
++%endif
++
++make EXTRAVERSION="-%{build_id}" O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} uImage %{?jobs:-j%jobs}
++
+ # 5. Update Makefile in output build
+ cat %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/Makefile | sed 's/\/home\/abuild\/rpmbuild\/BUILD\/%{name}-%{version}/\/usr\/src\/linux-kernel-sources-%{version}-%{build_id}/' > %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/Makefile.new
+ mv %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/Makefile.new %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/Makefile
+@@ -82,32 +123,63 @@ QA_SKIP_BUILD_ROOT="DO_NOT_WANT"; export QA_SKIP_BUILD_ROOT
+ # 1. Destynation directories
+ mkdir -p %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}
+ mkdir -p %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}
++mkdir -p %{buildroot}/boot/abi/
++mkdir -p %{buildroot}/usr/local/bin
+-# 2. Restore source and build irectory
++# 2. Install uImage
++cp %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/arch/arm/boot/uImage %{buildroot}/boot/
++
++# 3. Restore source and build irectory
+ tar -xf %{kernel_build_dir}/linux-kernel-sources-%{version}-%{build_id}.tar -C %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}
+ tar -xf %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}.tar   -C %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}
+-# 3. Install kernel headers
++# 4. Install kernel headers
++make INSTALL_PATH=%{buildroot}/boot INSTALL_MOD_PATH=%{buildroot} O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} install
+ make INSTALL_PATH=%{buildroot} INSTALL_MOD_PATH=%{buildroot} O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} INSTALL_HDR_PATH=%{buildroot}/usr headers_install
+-# 4. Remove files
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name ".tmp_vmlinux1" -exec rm -f {} +
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name ".tmp_vmlinux2" -exec rm -f {} +
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "vmlinux" -exec rm -f {} +
+-find %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id} -name "*.c" -exec rm -f {} +
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*.cmd" -exec rm -f {} +
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.o" -exec rm -f {} +
+-find %{buildroot}/usr -name "..install.cmd" -exec rm -f {} +
+-
+-find %{buildroot}/usr/include -name "\.\.install.cmd"  -exec rm -f {} +
+-find %{buildroot}/usr/include -name "\.install"  -exec rm -f {} +
++# 4.1 Install ABI/API tools
++cp abi-checker/src/abi-checker %{buildroot}/usr/local/bin
++
++# 4.2 Install abi_%{version} file
++%if %{with abidev}
++find ../.. -name "Module.symvers" -exec cp {} %{buildroot}/boot/abi/abi_devel \;
++%else
++cp abi-checker/data/abi* %{buildroot}/boot/abi/.
++ln -sf /boot/abi/abi_%{version}_%{abiver} %{buildroot}/boot/abi/current
++%endif
++
++# 5. Remove files
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name ".tmp_vmlinux1" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name ".tmp_vmlinux2" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "vmlinux" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "uImage" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "zImage" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*.cmd" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.o" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "\.*dtb*tmp" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.*tmp" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.c" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.S" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.ko" -exec rm -f {} \;
++
++find %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id} -name "*.c" -exec rm -f {} \;
++
++find %{buildroot}/usr -name "\.\.install.cmd"  -exec rm -f {} \;
++find %{buildroot}/usr -name "\.install"  -exec rm -f {} \;
+ rm -rf %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}/%{kernel_build_dir_name}
+-rm -f %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}/source
+-rm -f %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/source
+-rm -f %{buildroot}/System.map-3.10.0 %{buildroot}/vmlinux-3.10.0
++rm -f  %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}/source
++rm -f  %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/source
++
++rm -rf %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}/abi-checker
+-# 5. Create symbolic links
++rm -rf %{buildroot}/System.map*
++rm -rf %{buildroot}/vmlinux*
++
++rm -rf %{buildroot}/boot/System.map*
++rm -rf %{buildroot}/boot/vmlinux*
++
++# 6. Create symbolic links
+ ln -sf /usr/src/linux-kernel-sources-%{version}-%{build_id} %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/source
+ %clean
+@@ -124,3 +196,18 @@ rm -rf %{buildroot}
+ %files build
+ %defattr (-, root, root)
+ /usr/src/linux-kernel-build-%{version}-%{build_id}
++
++%files uImage
++%if %{without abidev}
++/boot/
++%else
++/boot/uImage
++%endif
++
++%files abi-tools
++/usr/local/bin
++
++%if %{with abidev}
++%files abi-dev
++/boot/abi
++%endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1059-linux-kernel-and-linux-kernel-modules-ABI-next-chang.patch b/patches.tizen/1059-linux-kernel-and-linux-kernel-modules-ABI-next-chang.patch
new file mode 100644 (file)
index 0000000..dc65545
--- /dev/null
@@ -0,0 +1,1284 @@
+From 45fe7044915b03bc6444102e55e45cccf4a4455d Mon Sep 17 00:00:00 2001
+From: Jacek Pielaszkiewicz <j.pielaszkie@samsung.com>
+Date: Thu, 12 Dec 2013 15:06:24 +0100
+Subject: [PATCH 1059/1302] linux-kernel and linux kernel modules ABI - next
+ changes
+
+The following changes have implemented:
+   1. New API/ABI check tools were added:
+      - "abi-module-checker" - single module ABI/API checker. The tool
+        compare module fingerprint with kernel fingerprint.
+      - "abi-module-dumper" - create for current kernel version
+        ABI/API fingerprint file.
+      - "abi-module-kernels-list" - list compatible kernel versions with given kernel module
+
+   2. sample kernel module was added to show how to use ABI/API tools
+
+   3. a new rpm package "linux-kernel-abi-devel" is build. The package
+      deliver kernel fingerprints repository for development .
+
+   4. New links "linux-kernel-build-current" and "linux-kernel-sources-current"
+      are make easer access to sources and build kernel
+      directories.
+
+Change-Id: I06f7dc1b8cc118f48e64595d257dbd29fd53e11e
+Signed-off-by: Jacek Pielaszkiewicz <j.pielaszkie@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ abi-checker/sample/LICENSE                         | 848 +++++++++++++++++++++
+ abi-checker/sample/Makefile                        |  12 +
+ .../packaging/udisks-automount-agent.spec.txt      |  53 ++
+ abi-checker/sample/sample_module.c                 | 107 +++
+ abi-checker/src/abi-module-checker                 |  29 +
+ abi-checker/src/abi-module-dumper                  |  38 +
+ abi-checker/src/abi-module-kernels-list            |  31 +
+ abi-checker/src/kernel_abi_checker.c               |   2 +-
+ packaging/linux-kernel.spec                        |  19 +
+ 9 files changed, 1138 insertions(+), 1 deletion(-)
+ create mode 100644 abi-checker/sample/LICENSE
+ create mode 100644 abi-checker/sample/Makefile
+ create mode 100644 abi-checker/sample/packaging/udisks-automount-agent.spec.txt
+ create mode 100644 abi-checker/sample/sample_module.c
+ create mode 100755 abi-checker/src/abi-module-checker
+ create mode 100755 abi-checker/src/abi-module-dumper
+ create mode 100755 abi-checker/src/abi-module-kernels-list
+
+diff --git a/abi-checker/sample/LICENSE b/abi-checker/sample/LICENSE
+new file mode 100644
+index 0000000..63fabc1
+--- /dev/null
++++ b/abi-checker/sample/LICENSE
+@@ -0,0 +1,848 @@
++Copyright (C) 2007-2011 David Zeuthen <zeuthen@gmail.com>
++Copyright (C) 2007-2011 Red Hat, Inc.
++All Rights Reserved.
++
++The source code for the udisks daemon and command-line tools are
++licensed to you under the GNU General Public License. Either version 2
++of the License, or (at your option) any later version.
++
++The source code for the libudisks2 dynamic library is licensed to you
++under the GNU Library General Public License. Either version 2 of the
++License, or (at your option) any later version.
++
++Each file is marked with copyright and licensing headers.
++
++The GPLv2 and LGPLv2 licenses are included below.
++
++-- BEGIN GPLv2+ License ---
++
++                    GNU GENERAL PUBLIC LICENSE
++                       Version 2, June 1991
++
++ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
++ 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++
++ Everyone is permitted to copy and distribute verbatim copies
++ of this license document, but changing it is not allowed.
++
++                            Preamble
++
++  The licenses for most software are designed to take away your
++freedom to share and change it.  By contrast, the GNU General Public
++License is intended to guarantee your freedom to share and change free
++software--to make sure the software is free for all its users.  This
++General Public License applies to most of the Free Software
++Foundation's software and to any other program whose authors commit to
++using it.  (Some other Free Software Foundation software is covered by
++the GNU Library General Public License instead.)  You can apply it to
++your programs, too.
++
++  When we speak of free software, we are referring to freedom, not
++price.  Our General Public Licenses are designed to make sure that you
++have the freedom to distribute copies of free software (and charge for
++this service if you wish), that you receive source code or can get it
++if you want it, that you can change the software or use pieces of it
++in new free programs; and that you know you can do these things.
++
++  To protect your rights, we need to make restrictions that forbid
++anyone to deny you these rights or to ask you to surrender the rights.
++These restrictions translate to certain responsibilities for you if you
++distribute copies of the software, or if you modify it.
++
++  For example, if you distribute copies of such a program, whether
++gratis or for a fee, you must give the recipients all the rights that
++you have.  You must make sure that they, too, receive or can get the
++source code.  And you must show them these terms so they know their
++rights.
++
++  We protect your rights with two steps: (1) copyright the software, and
++(2) offer you this license which gives you legal permission to copy,
++distribute and/or modify the software.
++
++  Also, for each author's protection and ours, we want to make certain
++that everyone understands that there is no warranty for this free
++software.  If the software is modified by someone else and passed on, we
++want its recipients to know that what they have is not the original, so
++that any problems introduced by others will not reflect on the original
++authors' reputations.
++
++  Finally, any free program is threatened constantly by software
++patents.  We wish to avoid the danger that redistributors of a free
++program will individually obtain patent licenses, in effect making the
++program proprietary.  To prevent this, we have made it clear that any
++patent must be licensed for everyone's free use or not licensed at all.
++
++  The precise terms and conditions for copying, distribution and
++modification follow.
++
++                    GNU GENERAL PUBLIC LICENSE
++   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
++
++  0. This License applies to any program or other work which contains
++a notice placed by the copyright holder saying it may be distributed
++under the terms of this General Public License.  The "Program", below,
++refers to any such program or work, and a "work based on the Program"
++means either the Program or any derivative work under copyright law:
++that is to say, a work containing the Program or a portion of it,
++either verbatim or with modifications and/or translated into another
++language.  (Hereinafter, translation is included without limitation in
++the term "modification".)  Each licensee is addressed as "you".
++
++Activities other than copying, distribution and modification are not
++covered by this License; they are outside its scope.  The act of
++running the Program is not restricted, and the output from the Program
++is covered only if its contents constitute a work based on the
++Program (independent of having been made by running the Program).
++Whether that is true depends on what the Program does.
++
++  1. You may copy and distribute verbatim copies of the Program's
++source code as you receive it, in any medium, provided that you
++conspicuously and appropriately publish on each copy an appropriate
++copyright notice and disclaimer of warranty; keep intact all the
++notices that refer to this License and to the absence of any warranty;
++and give any other recipients of the Program a copy of this License
++along with the Program.
++
++You may charge a fee for the physical act of transferring a copy, and
++you may at your option offer warranty protection in exchange for a fee.
++
++  2. You may modify your copy or copies of the Program or any portion
++of it, thus forming a work based on the Program, and copy and
++distribute such modifications or work under the terms of Section 1
++above, provided that you also meet all of these conditions:
++
++    a) You must cause the modified files to carry prominent notices
++    stating that you changed the files and the date of any change.
++
++    b) You must cause any work that you distribute or publish, that in
++    whole or in part contains or is derived from the Program or any
++    part thereof, to be licensed as a whole at no charge to all third
++    parties under the terms of this License.
++
++    c) If the modified program normally reads commands interactively
++    when run, you must cause it, when started running for such
++    interactive use in the most ordinary way, to print or display an
++    announcement including an appropriate copyright notice and a
++    notice that there is no warranty (or else, saying that you provide
++    a warranty) and that users may redistribute the program under
++    these conditions, and telling the user how to view a copy of this
++    License.  (Exception: if the Program itself is interactive but
++    does not normally print such an announcement, your work based on
++    the Program is not required to print an announcement.)
++
++These requirements apply to the modified work as a whole.  If
++identifiable sections of that work are not derived from the Program,
++and can be reasonably considered independent and separate works in
++themselves, then this License, and its terms, do not apply to those
++sections when you distribute them as separate works.  But when you
++distribute the same sections as part of a whole which is a work based
++on the Program, the distribution of the whole must be on the terms of
++this License, whose permissions for other licensees extend to the
++entire whole, and thus to each and every part regardless of who wrote it.
++
++Thus, it is not the intent of this section to claim rights or contest
++your rights to work written entirely by you; rather, the intent is to
++exercise the right to control the distribution of derivative or
++collective works based on the Program.
++
++In addition, mere aggregation of another work not based on the Program
++with the Program (or with a work based on the Program) on a volume of
++a storage or distribution medium does not bring the other work under
++the scope of this License.
++
++  3. You may copy and distribute the Program (or a work based on it,
++under Section 2) in object code or executable form under the terms of
++Sections 1 and 2 above provided that you also do one of the following:
++
++    a) Accompany it with the complete corresponding machine-readable
++    source code, which must be distributed under the terms of Sections
++    1 and 2 above on a medium customarily used for software interchange; or,
++
++    b) Accompany it with a written offer, valid for at least three
++    years, to give any third party, for a charge no more than your
++    cost of physically performing source distribution, a complete
++    machine-readable copy of the corresponding source code, to be
++    distributed under the terms of Sections 1 and 2 above on a medium
++    customarily used for software interchange; or,
++
++    c) Accompany it with the information you received as to the offer
++    to distribute corresponding source code.  (This alternative is
++    allowed only for noncommercial distribution and only if you
++    received the program in object code or executable form with such
++    an offer, in accord with Subsection b above.)
++
++The source code for a work means the preferred form of the work for
++making modifications to it.  For an executable work, complete source
++code means all the source code for all modules it contains, plus any
++associated interface definition files, plus the scripts used to
++control compilation and installation of the executable.  However, as a
++special exception, the source code distributed need not include
++anything that is normally distributed (in either source or binary
++form) with the major components (compiler, kernel, and so on) of the
++operating system on which the executable runs, unless that component
++itself accompanies the executable.
++
++If distribution of executable or object code is made by offering
++access to copy from a designated place, then offering equivalent
++access to copy the source code from the same place counts as
++distribution of the source code, even though third parties are not
++compelled to copy the source along with the object code.
++
++  4. You may not copy, modify, sublicense, or distribute the Program
++except as expressly provided under this License.  Any attempt
++otherwise to copy, modify, sublicense or distribute the Program is
++void, and will automatically terminate your rights under this License.
++However, parties who have received copies, or rights, from you under
++this License will not have their licenses terminated so long as such
++parties remain in full compliance.
++
++  5. You are not required to accept this License, since you have not
++signed it.  However, nothing else grants you permission to modify or
++distribute the Program or its derivative works.  These actions are
++prohibited by law if you do not accept this License.  Therefore, by
++modifying or distributing the Program (or any work based on the
++Program), you indicate your acceptance of this License to do so, and
++all its terms and conditions for copying, distributing or modifying
++the Program or works based on it.
++
++  6. Each time you redistribute the Program (or any work based on the
++Program), the recipient automatically receives a license from the
++original licensor to copy, distribute or modify the Program subject to
++these terms and conditions.  You may not impose any further
++restrictions on the recipients' exercise of the rights granted herein.
++You are not responsible for enforcing compliance by third parties to
++this License.
++
++  7. If, as a consequence of a court judgment or allegation of patent
++infringement or for any other reason (not limited to patent issues),
++conditions are imposed on you (whether by court order, agreement or
++otherwise) that contradict the conditions of this License, they do not
++excuse you from the conditions of this License.  If you cannot
++distribute so as to satisfy simultaneously your obligations under this
++License and any other pertinent obligations, then as a consequence you
++may not distribute the Program at all.  For example, if a patent
++license would not permit royalty-free redistribution of the Program by
++all those who receive copies directly or indirectly through you, then
++the only way you could satisfy both it and this License would be to
++refrain entirely from distribution of the Program.
++
++If any portion of this section is held invalid or unenforceable under
++any particular circumstance, the balance of the section is intended to
++apply and the section as a whole is intended to apply in other
++circumstances.
++
++It is not the purpose of this section to induce you to infringe any
++patents or other property right claims or to contest validity of any
++such claims; this section has the sole purpose of protecting the
++integrity of the free software distribution system, which is
++implemented by public license practices.  Many people have made
++generous contributions to the wide range of software distributed
++through that system in reliance on consistent application of that
++system; it is up to the author/donor to decide if he or she is willing
++to distribute software through any other system and a licensee cannot
++impose that choice.
++
++This section is intended to make thoroughly clear what is believed to
++be a consequence of the rest of this License.
++
++  8. If the distribution and/or use of the Program is restricted in
++certain countries either by patents or by copyrighted interfaces, the
++original copyright holder who places the Program under this License
++may add an explicit geographical distribution limitation excluding
++those countries, so that distribution is permitted only in or among
++countries not thus excluded.  In such case, this License incorporates
++the limitation as if written in the body of this License.
++
++  9. The Free Software Foundation may publish revised and/or new versions
++of the General Public License from time to time.  Such new versions will
++be similar in spirit to the present version, but may differ in detail to
++address new problems or concerns.
++
++Each version is given a distinguishing version number.  If the Program
++specifies a version number of this License which applies to it and "any
++later version", you have the option of following the terms and conditions
++either of that version or of any later version published by the Free
++Software Foundation.  If the Program does not specify a version number of
++this License, you may choose any version ever published by the Free Software
++Foundation.
++
++  10. If you wish to incorporate parts of the Program into other free
++programs whose distribution conditions are different, write to the author
++to ask for permission.  For software which is copyrighted by the Free
++Software Foundation, write to the Free Software Foundation; we sometimes
++make exceptions for this.  Our decision will be guided by the two goals
++of preserving the free status of all derivatives of our free software and
++of promoting the sharing and reuse of software generally.
++
++                            NO WARRANTY
++
++  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
++FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
++OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
++PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
++OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
++TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
++PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
++REPAIR OR CORRECTION.
++
++  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
++WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
++REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
++INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
++OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
++TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
++YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
++PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
++POSSIBILITY OF SUCH DAMAGES.
++
++                     END OF TERMS AND CONDITIONS
++
++            How to Apply These Terms to Your New Programs
++
++  If you develop a new program, and you want it to be of the greatest
++possible use to the public, the best way to achieve this is to make it
++free software which everyone can redistribute and change under these terms.
++
++  To do so, attach the following notices to the program.  It is safest
++to attach them to the start of each source file to most effectively
++convey the exclusion of warranty; and each file should have at least
++the "copyright" line and a pointer to where the full notice is found.
++
++    <one line to give the program's name and a brief idea of what it does.>
++    Copyright (C) <year>  <name of author>
++
++    This program is free software; you can redistribute it and/or modify
++    it under the terms of the GNU General Public License as published by
++    the Free Software Foundation; either version 2 of the License, or
++    (at your option) any later version.
++
++    This program is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++    GNU General Public License for more details.
++
++    You should have received a copy of the GNU General Public License
++    along with this program; if not, write to the Free Software
++    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++
++
++Also add information on how to contact you by electronic and paper mail.
++
++If the program is interactive, make it output a short notice like this
++when it starts in an interactive mode:
++
++    Gnomovision version 69, Copyright (C) year name of author
++    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
++    This is free software, and you are welcome to redistribute it
++    under certain conditions; type `show c' for details.
++
++The hypothetical commands `show w' and `show c' should show the appropriate
++parts of the General Public License.  Of course, the commands you use may
++be called something other than `show w' and `show c'; they could even be
++mouse-clicks or menu items--whatever suits your program.
++
++You should also get your employer (if you work as a programmer) or your
++school, if any, to sign a "copyright disclaimer" for the program, if
++necessary.  Here is a sample; alter the names:
++
++  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
++  `Gnomovision' (which makes passes at compilers) written by James Hacker.
++
++  <signature of Ty Coon>, 1 April 1989
++  Ty Coon, President of Vice
++
++This General Public License does not permit incorporating your program into
++proprietary programs.  If your program is a subroutine library, you may
++consider it more useful to permit linking proprietary applications with the
++library.  If this is what you want to do, use the GNU Library General
++Public License instead of this License.
++
++-- END GPLv2+ License ---
++
++-- BEGIN LGPLv2+ License ---
++
++                  GNU LIBRARY GENERAL PUBLIC LICENSE
++                       Version 2, June 1991
++
++ Copyright (C) 1991 Free Software Foundation, Inc.
++                    59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ Everyone is permitted to copy and distribute verbatim copies
++ of this license document, but changing it is not allowed.
++
++[This is the first released version of the library GPL.  It is
++ numbered 2 because it goes with version 2 of the ordinary GPL.]
++
++                            Preamble
++
++  The licenses for most software are designed to take away your
++freedom to share and change it.  By contrast, the GNU General Public
++Licenses are intended to guarantee your freedom to share and change
++free software--to make sure the software is free for all its users.
++
++  This license, the Library General Public License, applies to some
++specially designated Free Software Foundation software, and to any
++other libraries whose authors decide to use it.  You can use it for
++your libraries, too.
++
++  When we speak of free software, we are referring to freedom, not
++price.  Our General Public Licenses are designed to make sure that you
++have the freedom to distribute copies of free software (and charge for
++this service if you wish), that you receive source code or can get it
++if you want it, that you can change the software or use pieces of it
++in new free programs; and that you know you can do these things.
++
++  To protect your rights, we need to make restrictions that forbid
++anyone to deny you these rights or to ask you to surrender the rights.
++These restrictions translate to certain responsibilities for you if
++you distribute copies of the library, or if you modify it.
++
++  For example, if you distribute copies of the library, whether gratis
++or for a fee, you must give the recipients all the rights that we gave
++you.  You must make sure that they, too, receive or can get the source
++code.  If you link a program with the library, you must provide
++complete object files to the recipients so that they can relink them
++with the library, after making changes to the library and recompiling
++it.  And you must show them these terms so they know their rights.
++
++  Our method of protecting your rights has two steps: (1) copyright
++the library, and (2) offer you this license which gives you legal
++permission to copy, distribute and/or modify the library.
++
++  Also, for each distributor's protection, we want to make certain
++that everyone understands that there is no warranty for this free
++library.  If the library is modified by someone else and passed on, we
++want its recipients to know that what they have is not the original
++version, so that any problems introduced by others will not reflect on
++the original authors' reputations.
++
++  Finally, any free program is threatened constantly by software
++patents.  We wish to avoid the danger that companies distributing free
++software will individually obtain patent licenses, thus in effect
++transforming the program into proprietary software.  To prevent this,
++we have made it clear that any patent must be licensed for everyone's
++free use or not licensed at all.
++
++  Most GNU software, including some libraries, is covered by the ordinary
++GNU General Public License, which was designed for utility programs.  This
++license, the GNU Library General Public License, applies to certain
++designated libraries.  This license is quite different from the ordinary
++one; be sure to read it in full, and don't assume that anything in it is
++the same as in the ordinary license.
++
++  The reason we have a separate public license for some libraries is that
++they blur the distinction we usually make between modifying or adding to a
++program and simply using it.  Linking a program with a library, without
++changing the library, is in some sense simply using the library, and is
++analogous to running a utility program or application program.  However, in
++a textual and legal sense, the linked executable is a combined work, a
++derivative of the original library, and the ordinary General Public License
++treats it as such.
++
++  Because of this blurred distinction, using the ordinary General
++Public License for libraries did not effectively promote software
++sharing, because most developers did not use the libraries.  We
++concluded that weaker conditions might promote sharing better.
++
++  However, unrestricted linking of non-free programs would deprive the
++users of those programs of all benefit from the free status of the
++libraries themselves.  This Library General Public License is intended to
++permit developers of non-free programs to use free libraries, while
++preserving your freedom as a user of such programs to change the free
++libraries that are incorporated in them.  (We have not seen how to achieve
++this as regards changes in header files, but we have achieved it as regards
++changes in the actual functions of the Library.)  The hope is that this
++will lead to faster development of free libraries.
++
++  The precise terms and conditions for copying, distribution and
++modification follow.  Pay close attention to the difference between a
++"work based on the library" and a "work that uses the library".  The
++former contains code derived from the library, while the latter only
++works together with the library.
++
++  Note that it is possible for a library to be covered by the ordinary
++General Public License rather than by this special one.
++
++                  GNU LIBRARY GENERAL PUBLIC LICENSE
++   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
++
++  0. This License Agreement applies to any software library which
++contains a notice placed by the copyright holder or other authorized
++party saying it may be distributed under the terms of this Library
++General Public License (also called "this License").  Each licensee is
++addressed as "you".
++
++  A "library" means a collection of software functions and/or data
++prepared so as to be conveniently linked with application programs
++(which use some of those functions and data) to form executables.
++
++  The "Library", below, refers to any such software library or work
++which has been distributed under these terms.  A "work based on the
++Library" means either the Library or any derivative work under
++copyright law: that is to say, a work containing the Library or a
++portion of it, either verbatim or with modifications and/or translated
++straightforwardly into another language.  (Hereinafter, translation is
++included without limitation in the term "modification".)
++
++  "Source code" for a work means the preferred form of the work for
++making modifications to it.  For a library, complete source code means
++all the source code for all modules it contains, plus any associated
++interface definition files, plus the scripts used to control compilation
++and installation of the library.
++
++  Activities other than copying, distribution and modification are not
++covered by this License; they are outside its scope.  The act of
++running a program using the Library is not restricted, and output from
++such a program is covered only if its contents constitute a work based
++on the Library (independent of the use of the Library in a tool for
++writing it).  Whether that is true depends on what the Library does
++and what the program that uses the Library does.
++
++  1. You may copy and distribute verbatim copies of the Library's
++complete source code as you receive it, in any medium, provided that
++you conspicuously and appropriately publish on each copy an
++appropriate copyright notice and disclaimer of warranty; keep intact
++all the notices that refer to this License and to the absence of any
++warranty; and distribute a copy of this License along with the
++Library.
++
++  You may charge a fee for the physical act of transferring a copy,
++and you may at your option offer warranty protection in exchange for a
++fee.
++
++  2. You may modify your copy or copies of the Library or any portion
++of it, thus forming a work based on the Library, and copy and
++distribute such modifications or work under the terms of Section 1
++above, provided that you also meet all of these conditions:
++
++    a) The modified work must itself be a software library.
++
++    b) You must cause the files modified to carry prominent notices
++    stating that you changed the files and the date of any change.
++
++    c) You must cause the whole of the work to be licensed at no
++    charge to all third parties under the terms of this License.
++
++    d) If a facility in the modified Library refers to a function or a
++    table of data to be supplied by an application program that uses
++    the facility, other than as an argument passed when the facility
++    is invoked, then you must make a good faith effort to ensure that,
++    in the event an application does not supply such function or
++    table, the facility still operates, and performs whatever part of
++    its purpose remains meaningful.
++
++    (For example, a function in a library to compute square roots has
++    a purpose that is entirely well-defined independent of the
++    application.  Therefore, Subsection 2d requires that any
++    application-supplied function or table used by this function must
++    be optional: if the application does not supply it, the square
++    root function must still compute square roots.)
++
++These requirements apply to the modified work as a whole.  If
++identifiable sections of that work are not derived from the Library,
++and can be reasonably considered independent and separate works in
++themselves, then this License, and its terms, do not apply to those
++sections when you distribute them as separate works.  But when you
++distribute the same sections as part of a whole which is a work based
++on the Library, the distribution of the whole must be on the terms of
++this License, whose permissions for other licensees extend to the
++entire whole, and thus to each and every part regardless of who wrote
++it.
++
++Thus, it is not the intent of this section to claim rights or contest
++your rights to work written entirely by you; rather, the intent is to
++exercise the right to control the distribution of derivative or
++collective works based on the Library.
++
++In addition, mere aggregation of another work not based on the Library
++with the Library (or with a work based on the Library) on a volume of
++a storage or distribution medium does not bring the other work under
++the scope of this License.
++
++  3. You may opt to apply the terms of the ordinary GNU General Public
++License instead of this License to a given copy of the Library.  To do
++this, you must alter all the notices that refer to this License, so
++that they refer to the ordinary GNU General Public License, version 2,
++instead of to this License.  (If a newer version than version 2 of the
++ordinary GNU General Public License has appeared, then you can specify
++that version instead if you wish.)  Do not make any other change in
++these notices.
++
++  Once this change is made in a given copy, it is irreversible for
++that copy, so the ordinary GNU General Public License applies to all
++subsequent copies and derivative works made from that copy.
++
++  This option is useful when you wish to copy part of the code of
++the Library into a program that is not a library.
++
++  4. You may copy and distribute the Library (or a portion or
++derivative of it, under Section 2) in object code or executable form
++under the terms of Sections 1 and 2 above provided that you accompany
++it with the complete corresponding machine-readable source code, which
++must be distributed under the terms of Sections 1 and 2 above on a
++medium customarily used for software interchange.
++
++  If distribution of object code is made by offering access to copy
++from a designated place, then offering equivalent access to copy the
++source code from the same place satisfies the requirement to
++distribute the source code, even though third parties are not
++compelled to copy the source along with the object code.
++
++  5. A program that contains no derivative of any portion of the
++Library, but is designed to work with the Library by being compiled or
++linked with it, is called a "work that uses the Library".  Such a
++work, in isolation, is not a derivative work of the Library, and
++therefore falls outside the scope of this License.
++
++  However, linking a "work that uses the Library" with the Library
++creates an executable that is a derivative of the Library (because it
++contains portions of the Library), rather than a "work that uses the
++library".  The executable is therefore covered by this License.
++Section 6 states terms for distribution of such executables.
++
++  When a "work that uses the Library" uses material from a header file
++that is part of the Library, the object code for the work may be a
++derivative work of the Library even though the source code is not.
++Whether this is true is especially significant if the work can be
++linked without the Library, or if the work is itself a library.  The
++threshold for this to be true is not precisely defined by law.
++
++  If such an object file uses only numerical parameters, data
++structure layouts and accessors, and small macros and small inline
++functions (ten lines or less in length), then the use of the object
++file is unrestricted, regardless of whether it is legally a derivative
++work.  (Executables containing this object code plus portions of the
++Library will still fall under Section 6.)
++
++  Otherwise, if the work is a derivative of the Library, you may
++distribute the object code for the work under the terms of Section 6.
++Any executables containing that work also fall under Section 6,
++whether or not they are linked directly with the Library itself.
++
++  6. As an exception to the Sections above, you may also compile or
++link a "work that uses the Library" with the Library to produce a
++work containing portions of the Library, and distribute that work
++under terms of your choice, provided that the terms permit
++modification of the work for the customer's own use and reverse
++engineering for debugging such modifications.
++
++  You must give prominent notice with each copy of the work that the
++Library is used in it and that the Library and its use are covered by
++this License.  You must supply a copy of this License.  If the work
++during execution displays copyright notices, you must include the
++copyright notice for the Library among them, as well as a reference
++directing the user to the copy of this License.  Also, you must do one
++of these things:
++
++    a) Accompany the work with the complete corresponding
++    machine-readable source code for the Library including whatever
++    changes were used in the work (which must be distributed under
++    Sections 1 and 2 above); and, if the work is an executable linked
++    with the Library, with the complete machine-readable "work that
++    uses the Library", as object code and/or source code, so that the
++    user can modify the Library and then relink to produce a modified
++    executable containing the modified Library.  (It is understood
++    that the user who changes the contents of definitions files in the
++    Library will not necessarily be able to recompile the application
++    to use the modified definitions.)
++
++    b) Accompany the work with a written offer, valid for at
++    least three years, to give the same user the materials
++    specified in Subsection 6a, above, for a charge no more
++    than the cost of performing this distribution.
++
++    c) If distribution of the work is made by offering access to copy
++    from a designated place, offer equivalent access to copy the above
++    specified materials from the same place.
++
++    d) Verify that the user has already received a copy of these
++    materials or that you have already sent this user a copy.
++
++  For an executable, the required form of the "work that uses the
++Library" must include any data and utility programs needed for
++reproducing the executable from it.  However, as a special exception,
++the source code distributed need not include anything that is normally
++distributed (in either source or binary form) with the major
++components (compiler, kernel, and so on) of the operating system on
++which the executable runs, unless that component itself accompanies
++the executable.
++
++  It may happen that this requirement contradicts the license
++restrictions of other proprietary libraries that do not normally
++accompany the operating system.  Such a contradiction means you cannot
++use both them and the Library together in an executable that you
++distribute.
++
++  7. You may place library facilities that are a work based on the
++Library side-by-side in a single library together with other library
++facilities not covered by this License, and distribute such a combined
++library, provided that the separate distribution of the work based on
++the Library and of the other library facilities is otherwise
++permitted, and provided that you do these two things:
++
++    a) Accompany the combined library with a copy of the same work
++    based on the Library, uncombined with any other library
++    facilities.  This must be distributed under the terms of the
++    Sections above.
++
++    b) Give prominent notice with the combined library of the fact
++    that part of it is a work based on the Library, and explaining
++    where to find the accompanying uncombined form of the same work.
++
++  8. You may not copy, modify, sublicense, link with, or distribute
++the Library except as expressly provided under this License.  Any
++attempt otherwise to copy, modify, sublicense, link with, or
++distribute the Library is void, and will automatically terminate your
++rights under this License.  However, parties who have received copies,
++or rights, from you under this License will not have their licenses
++terminated so long as such parties remain in full compliance.
++
++  9. You are not required to accept this License, since you have not
++signed it.  However, nothing else grants you permission to modify or
++distribute the Library or its derivative works.  These actions are
++prohibited by law if you do not accept this License.  Therefore, by
++modifying or distributing the Library (or any work based on the
++Library), you indicate your acceptance of this License to do so, and
++all its terms and conditions for copying, distributing or modifying
++the Library or works based on it.
++
++  10. Each time you redistribute the Library (or any work based on the
++Library), the recipient automatically receives a license from the
++original licensor to copy, distribute, link with or modify the Library
++subject to these terms and conditions.  You may not impose any further
++restrictions on the recipients' exercise of the rights granted herein.
++You are not responsible for enforcing compliance by third parties to
++this License.
++
++  11. If, as a consequence of a court judgment or allegation of patent
++infringement or for any other reason (not limited to patent issues),
++conditions are imposed on you (whether by court order, agreement or
++otherwise) that contradict the conditions of this License, they do not
++excuse you from the conditions of this License.  If you cannot
++distribute so as to satisfy simultaneously your obligations under this
++License and any other pertinent obligations, then as a consequence you
++may not distribute the Library at all.  For example, if a patent
++license would not permit royalty-free redistribution of the Library by
++all those who receive copies directly or indirectly through you, then
++the only way you could satisfy both it and this License would be to
++refrain entirely from distribution of the Library.
++
++If any portion of this section is held invalid or unenforceable under any
++particular circumstance, the balance of the section is intended to apply,
++and the section as a whole is intended to apply in other circumstances.
++
++It is not the purpose of this section to induce you to infringe any
++patents or other property right claims or to contest validity of any
++such claims; this section has the sole purpose of protecting the
++integrity of the free software distribution system which is
++implemented by public license practices.  Many people have made
++generous contributions to the wide range of software distributed
++through that system in reliance on consistent application of that
++system; it is up to the author/donor to decide if he or she is willing
++to distribute software through any other system and a licensee cannot
++impose that choice.
++
++This section is intended to make thoroughly clear what is believed to
++be a consequence of the rest of this License.
++
++  12. If the distribution and/or use of the Library is restricted in
++certain countries either by patents or by copyrighted interfaces, the
++original copyright holder who places the Library under this License may add
++an explicit geographical distribution limitation excluding those countries,
++so that distribution is permitted only in or among countries not thus
++excluded.  In such case, this License incorporates the limitation as if
++written in the body of this License.
++
++  13. The Free Software Foundation may publish revised and/or new
++versions of the Library General Public License from time to time.
++Such new versions will be similar in spirit to the present version,
++but may differ in detail to address new problems or concerns.
++
++Each version is given a distinguishing version number.  If the Library
++specifies a version number of this License which applies to it and
++"any later version", you have the option of following the terms and
++conditions either of that version or of any later version published by
++the Free Software Foundation.  If the Library does not specify a
++license version number, you may choose any version ever published by
++the Free Software Foundation.
++
++  14. If you wish to incorporate parts of the Library into other free
++programs whose distribution conditions are incompatible with these,
++write to the author to ask for permission.  For software which is
++copyrighted by the Free Software Foundation, write to the Free
++Software Foundation; we sometimes make exceptions for this.  Our
++decision will be guided by the two goals of preserving the free status
++of all derivatives of our free software and of promoting the sharing
++and reuse of software generally.
++
++                            NO WARRANTY
++
++  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
++WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
++EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
++OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
++KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
++IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
++LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
++THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
++
++  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
++WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
++AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
++FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
++CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
++LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
++RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
++FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
++SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
++DAMAGES.
++
++                     END OF TERMS AND CONDITIONS
++
++           How to Apply These Terms to Your New Libraries
++
++  If you develop a new library, and you want it to be of the greatest
++possible use to the public, we recommend making it free software that
++everyone can redistribute and change.  You can do so by permitting
++redistribution under these terms (or, alternatively, under the terms of the
++ordinary General Public License).
++
++  To apply these terms, attach the following notices to the library.  It is
++safest to attach them to the start of each source file to most effectively
++convey the exclusion of warranty; and each file should have at least the
++"copyright" line and a pointer to where the full notice is found.
++
++    <one line to give the library's name and a brief idea of what it does.>
++    Copyright (C) <year>  <name of author>
++
++    This library is free software; you can redistribute it and/or
++    modify it under the terms of the GNU Library General Public
++    License as published by the Free Software Foundation; either
++    version 2 of the License, or (at your option) any later version.
++
++    This library 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
++    Library General Public License for more details.
++
++    You should have received a copy of the GNU Library General Public
++    License along with this library; if not, write to the
++    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++    Boston, MA  02111-1307  USA.
++
++Also add information on how to contact you by electronic and paper mail.
++
++You should also get your employer (if you work as a programmer) or your
++school, if any, to sign a "copyright disclaimer" for the library, if
++necessary.  Here is a sample; alter the names:
++
++  Yoyodyne, Inc., hereby disclaims all copyright interest in the
++  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
++
++  <signature of Ty Coon>, 1 April 1990
++  Ty Coon, President of Vice
++
++That's all there is to it!
++
++-- END LGPLv2+ License ---
+diff --git a/abi-checker/sample/Makefile b/abi-checker/sample/Makefile
+new file mode 100644
+index 0000000..4759f3c
+--- /dev/null
++++ b/abi-checker/sample/Makefile
+@@ -0,0 +1,12 @@
++obj-m = sample_module.o
++
++all:
++      make -C /usr/src/linux-kernel-build-3.10.19-tizen_defconfig.1 M=$(PWD) modules
++
++install:
++      make -C /usr/src/linux-kernel-build-3.10.19-tizen_defconfig.1 M=$(PWD) modules_install
++
++clean:
++      make -C /usr/src/linux-kernel-build-3.10.19-tizen_defconfig.1 M=$(PWD) clean
++      
++
+diff --git a/abi-checker/sample/packaging/udisks-automount-agent.spec.txt b/abi-checker/sample/packaging/udisks-automount-agent.spec.txt
+new file mode 100644
+index 0000000..bca8416
+--- /dev/null
++++ b/abi-checker/sample/packaging/udisks-automount-agent.spec.txt
+@@ -0,0 +1,53 @@
++%define debug_package %{nil}
++Name:       sample-module
++Summary:    Test sample kernel module 2
++Version:    0.1.0
++Release:    1
++Group:      Base/Device Management
++License:    GPL-2.0
++Source0:    %{name}-%{version}.tar.gz
++BuildRequires: linux-kernel-sources
++BuildRequires: linux-kernel-headers
++BuildRequires: linux-kernel-build
++BuildRequires: linux-kernel-abi-tools
++BuildRequires: linux-kernel-abi-devel
++
++Requires: linux-kernel-uImage
++
++%package source
++Summary: Debug sample-kernel-module-2
++Group: Base/Device Management
++
++%description source
++Debug and sources sample-kernel-module-2
++
++%description
++TIZEN simple kernel module.  
++
++%prep
++%setup -q
++
++%build
++make %{?jobs:-j%jobs}
++# Create ABI/API dump fingerprint file
++/usr/local/bin/abi-module-dumper sample_module_2.ko sample_module_2.abidump
++
++%install
++mkdir -p %{_builddir}/lib/modules/3.10.19-tizen_defconfig.1/
++make INSTALL_MOD_PATH=%{buildroot}  install
++cp sample_module_2.abidump %{buildroot}/lib/modules/3.10.19-tizen_defconfig.1/extra/
++
++%post
++# list comptible kerel ABI/API versions
++/usr/local/bin/abi-module-kernels-list /lib/modules/3.10.19-tizen_defconfig.1/extra/sample_module_2.abidump
++
++# Test module ABI/API with the kernel ABI/API
++/usr/local/bin/abi-module-checker /lib/modules/3.10.19-tizen_defconfig.1/extra/sample_module_2.abidump
++
++%files
++/lib/modules/3.10.19-tizen_defconfig.1/extra/
++%license LICENSE
++
++%files source
++/usr/src/debug/sample-kernel-module-2-0.1.0/sample_module_2.c
++/usr/src/debug/sample-kernel-module-2-0.1.0/sample_module_2.mod.c
+diff --git a/abi-checker/sample/sample_module.c b/abi-checker/sample/sample_module.c
+new file mode 100644
+index 0000000..b95a7af
+--- /dev/null
++++ b/abi-checker/sample/sample_module.c
+@@ -0,0 +1,107 @@
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <asm/uaccess.h>
++#include <linux/init.h>
++#include <linux/fs.h>
++
++#define DEVICE_NAME "sample_module"
++#define TEST_MSG_BUFF_LEN     1024
++
++extern int snd_timer_pause;
++
++static unsigned int majorNumber = 0;
++
++static char message[TEST_MSG_BUFF_LEN + 1];
++
++static ssize_t device_write(struct file *filp, const char *buff, size_t len, loff_t *off)
++{
++      printk(KERN_ALERT "Empty write operation. %d\n", snd_timer_pause);
++      return 0;
++}
++
++static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t * offset)
++{
++      int bytes_read = 0;
++
++      /*
++       * Copy message
++       */
++      for(bytes_read = 0; bytes_read < (length - 1) && bytes_read < TEST_MSG_BUFF_LEN; bytes_read ++)
++              put_user(message[bytes_read], buffer + bytes_read );
++      put_user('\0', buffer + bytes_read );
++
++      return bytes_read + 1;
++}
++
++static int device_open(struct inode *inode, struct file *file)
++{
++      static int counter = 0;
++
++      printk( "Open device, count = %d\n", counter++ );
++
++      try_module_get( THIS_MODULE );
++      return 0;
++}
++
++static int device_release(struct inode *inode, struct file *file)
++{
++      printk("Release device\n");
++
++      module_put( THIS_MODULE );
++      return 0;
++}
++
++struct file_operations fileOperations =
++{
++      read:    device_read,
++      write:   device_write,
++      open:    device_open,
++      release: device_release
++};
++
++static int __init test_module_init( void )
++{
++      int i;
++      int j;
++
++      printk(KERN_ALERT "Test kernel module 2 - enter\n");
++
++      /*
++       * Init test message
++       */
++      for(i = 0; i < TEST_MSG_BUFF_LEN;)
++      {
++              for(j = 0; j < 10 && i < TEST_MSG_BUFF_LEN; j ++, i ++ )
++              {
++                      message[i] = '0' + j;
++                      message[i + 1] = '\0';
++              }
++      }
++
++      /*
++       * Register device
++       */
++      majorNumber = register_chrdev(0, DEVICE_NAME, &fileOperations);
++      if (majorNumber < 0)
++      {
++                printk(KERN_ALERT "Blad rejestrowania urzadzenia => [%d]\n", majorNumber );
++                return majorNumber;
++      }
++
++      return 0;
++}
++
++static void __exit test_module_exit(void)
++{
++      printk(KERN_ALERT "Test kernel module 2 - exit\n");
++
++      unregister_chrdev(majorNumber, DEVICE_NAME);
++}
++
++module_init(test_module_init);
++module_exit(test_module_exit);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Jacek Pielaszkiewicz");        /* Who wrote this module? */
++MODULE_DESCRIPTION("Sample test kernel module.");     /* What does this module do */
++MODULE_SUPPORTED_DEVICE("sample_test_module_2");
+diff --git a/abi-checker/src/abi-module-checker b/abi-checker/src/abi-module-checker
+new file mode 100755
+index 0000000..78e5a89
+--- /dev/null
++++ b/abi-checker/src/abi-module-checker
+@@ -0,0 +1,29 @@
++#!/bin/sh
++
++echo ""
++echo "Module ABI/API checker"
++echo ""
++echo ""
++
++if [ "${#}" != "1"  ]
++then
++      echo ""
++      echo "ERROR: "
++      echo "       Usage: ${0} _module_abi_fingerprint_"
++      echo ""
++      exit 1
++fi
++
++kerne_abi_file="/boot/abi/current"
++
++if [ ! -f "${1}" -o ! -f "${kerne_abi_file}" ]
++then
++      echo ""
++      echo "ERROR: Please check \"${1}\", \"${kerne_abi_file}\" files"
++      echo ""
++      exit 1
++fi
++
++/usr/local/bin/abi-checker "test-module" "${kerne_abi_file}" "${1}"
++
++exit ${?}
+diff --git a/abi-checker/src/abi-module-dumper b/abi-checker/src/abi-module-dumper
+new file mode 100755
+index 0000000..783e02a
+--- /dev/null
++++ b/abi-checker/src/abi-module-dumper
+@@ -0,0 +1,38 @@
++#!/bin/sh
++
++echo ""
++echo "Module ABI/API fingerprint file generation"
++echo ""
++echo ""
++
++if [ "${#}" != "2"  ]
++then
++      echo ""
++      echo "ERROR: "
++      echo "       Usage: ${0} _module_ko_file_ _output_file_"
++      echo ""
++      exit 1
++fi
++
++kerne_abi_file="/boot/abi/current"
++
++if [ ! -f "${kerne_abi_file}" ]
++then
++      echo ""
++      echo "ERROR: Please check ${kerne_abi_file} file"
++      echo "       Check if linux-kernel-uImage package is installed in development environment."
++      echo ""
++      exit 1
++fi
++
++if [ ! -f "${1}" ]
++then
++      echo "ERROR: Please check input file ${1}"
++      echo ""
++      exit 1
++      
++fi
++
++/usr/local/bin/abi-checker "dump-module" "${kerne_abi_file}" "${1}" "${2}"
++
++exit ${?}
+diff --git a/abi-checker/src/abi-module-kernels-list b/abi-checker/src/abi-module-kernels-list
+new file mode 100755
+index 0000000..12105e1
+--- /dev/null
++++ b/abi-checker/src/abi-module-kernels-list
+@@ -0,0 +1,31 @@
++#!/bin/sh
++
++echo ""
++echo "List all comatible kernels."
++echo ""
++
++if [ "${#}" != 1  ]
++then
++      echo ""
++      echo "ERROR: "
++      echo "       Usage: ${0} _module_fingerprint_"
++      echo ""
++      exit 1
++fi
++
++#
++# Check all historical abi kernel files
++#
++for file in /boot/abi/abi_*
++do
++      filename=`basename ${file}`
++      version=`echo ${filename} | awk -F _ '{ print $2 }'`
++      abi=`echo ${filename} | awk -F _ '{ print $3 }'`
++
++      /usr/local/bin/abi-checker "test-module" "${file}" "${1}" 2> /dev/null > /dev/null
++      if [ "${?}" = "0" ]
++      then
++              echo "        Kernel:${version}, ABI/API:${abi} .... compatible"
++      fi
++done
++
+diff --git a/abi-checker/src/kernel_abi_checker.c b/abi-checker/src/kernel_abi_checker.c
+index ae362d6..da396e1 100644
+--- a/abi-checker/src/kernel_abi_checker.c
++++ b/abi-checker/src/kernel_abi_checker.c
+@@ -638,7 +638,7 @@ int testModule( char *f1, char *f2 )
+       {
+               destroyHashTable( curr_hashTable );
+               PRINT_ERROR( "Error read input \"%s\" file.\n", f2 );
+-        return 1;
++              return 1;
+       }
+       /*
+diff --git a/packaging/linux-kernel.spec b/packaging/linux-kernel.spec
+index e199f9b..485f06e 100644
+--- a/packaging/linux-kernel.spec
++++ b/packaging/linux-kernel.spec
+@@ -52,10 +52,18 @@ glibc package.
+ %package abi-tools
+ Summary: Kernael ABI tools
+ Group: Development/System
++Requires: libelf
+ %description abi-tools
+ The package provide set of tools to test and create ABI/API dumps.
++%package abi-devel
++Summary: Kernael ABI development package
++Group: Development/System
++
++%description abi-devel
++The package provide ABI/API fingerprint developemnt repository
++
+ %package sources
+ Summary: Full linux kernel sources for out-of-tree modules
+ Group: Development/System
+@@ -139,6 +147,10 @@ make INSTALL_PATH=%{buildroot} INSTALL_MOD_PATH=%{buildroot} O=%{kernel_build_di
+ # 4.1 Install ABI/API tools
+ cp abi-checker/src/abi-checker %{buildroot}/usr/local/bin
++cp abi-checker/src/abi-module-checker %{buildroot}/usr/local/bin
++cp abi-checker/src/abi-module-dumper %{buildroot}/usr/local/bin
++cp abi-checker/src/abi-module-kernels-list %{buildroot}/usr/local/bin
++chmod 755 %{buildroot}/usr/local/bin/*
+ # 4.2 Install abi_%{version} file
+ %if %{with abidev}
+@@ -181,6 +193,8 @@ rm -rf %{buildroot}/boot/vmlinux*
+ # 6. Create symbolic links
+ ln -sf /usr/src/linux-kernel-sources-%{version}-%{build_id} %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/source
++ln -sf /usr/src/linux-kernel-build-%{version}-%{build_id}   %{buildroot}/usr/src/linux-kernel-build-current
++ln -sf /usr/src/linux-kernel-sources-%{version}-%{build_id} %{buildroot}/usr/src/linux-kernel-sources-current
+ %clean
+ rm -rf %{buildroot}
+@@ -192,10 +206,12 @@ rm -rf %{buildroot}
+ %files sources
+ %defattr (-, root, root)
+ /usr/src/linux-kernel-sources-%{version}-%{build_id}
++/usr/src/linux-kernel-sources-current
+ %files build
+ %defattr (-, root, root)
+ /usr/src/linux-kernel-build-%{version}-%{build_id}
++/usr/src/linux-kernel-build-current
+ %files uImage
+ %if %{without abidev}
+@@ -211,3 +227,6 @@ rm -rf %{buildroot}
+ %files abi-dev
+ /boot/abi
+ %endif
++
++%files abi-devel
++/boot/abi
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1060-abi-checker-tool-directory-location-update.patch b/patches.tizen/1060-abi-checker-tool-directory-location-update.patch
new file mode 100644 (file)
index 0000000..d0ceb45
--- /dev/null
@@ -0,0 +1,18757 @@
+From 952c6d9596e18f9df43174f513ce84ebe7cd6ca2 Mon Sep 17 00:00:00 2001
+From: Jacek Pielaszkiewicz <j.pielaszkie@samsung.com>
+Date: Tue, 17 Dec 2013 14:27:39 +0100
+Subject: [PATCH 1060/1302] abi-checker - tool directory location update.
+
+- abi-checker tool has been moved into tools/directory
+- abi-checker short documentation has been added.
+
+Change-Id: I88d4c6081b1df276243c9edfb44d1de2e009cc10
+Signed-off-by: Jacek Pielaszkiewicz <j.pielaszkie@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/abi-checker.txt                      |  132 +
+ abi-checker/data/abi_3.10.19_1                     | 6900 --------------------
+ abi-checker/sample/LICENSE                         |  848 ---
+ abi-checker/sample/Makefile                        |   12 -
+ .../packaging/udisks-automount-agent.spec.txt      |   53 -
+ abi-checker/sample/sample_module.c                 |  107 -
+ abi-checker/src/Makefile                           |   31 -
+ abi-checker/src/abi-module-checker                 |   29 -
+ abi-checker/src/abi-module-dumper                  |   38 -
+ abi-checker/src/abi-module-kernels-list            |   31 -
+ abi-checker/src/build_api_kernel_checker.sh        |   24 -
+ abi-checker/src/kernel_abi_checker.c               |  834 ---
+ abi-checker/src/kernel_abi_checker.h               |   62 -
+ abi-checker/src/kernel_abi_checker_elf.c           |  172 -
+ packaging/linux-kernel.spec                        |   16 +-
+ tools/abi-checker/data/abi_3.10.19_1               | 6900 ++++++++++++++++++++
+ tools/abi-checker/sample/LICENSE                   |  848 +++
+ tools/abi-checker/sample/Makefile                  |   12 +
+ .../sample/packaging/sample-module.spec.txt        |   53 +
+ tools/abi-checker/sample/sample_module.c           |  107 +
+ tools/abi-checker/src/Makefile                     |   31 +
+ tools/abi-checker/src/abi-module-checker           |   43 +
+ tools/abi-checker/src/abi-module-dumper            |   51 +
+ tools/abi-checker/src/abi-module-kernels-list      |   45 +
+ tools/abi-checker/src/build_api_kernel_checker.sh  |   38 +
+ tools/abi-checker/src/kernel_abi_checker.c         |  834 +++
+ tools/abi-checker/src/kernel_abi_checker.h         |   62 +
+ tools/abi-checker/src/kernel_abi_checker_elf.c     |  172 +
+ 28 files changed, 9336 insertions(+), 9149 deletions(-)
+ create mode 100644 Documentation/abi-checker.txt
+ delete mode 100644 abi-checker/data/abi_3.10.19_1
+ delete mode 100644 abi-checker/sample/LICENSE
+ delete mode 100644 abi-checker/sample/Makefile
+ delete mode 100644 abi-checker/sample/packaging/udisks-automount-agent.spec.txt
+ delete mode 100644 abi-checker/sample/sample_module.c
+ delete mode 100644 abi-checker/src/Makefile
+ delete mode 100755 abi-checker/src/abi-module-checker
+ delete mode 100755 abi-checker/src/abi-module-dumper
+ delete mode 100755 abi-checker/src/abi-module-kernels-list
+ delete mode 100755 abi-checker/src/build_api_kernel_checker.sh
+ delete mode 100644 abi-checker/src/kernel_abi_checker.c
+ delete mode 100644 abi-checker/src/kernel_abi_checker.h
+ delete mode 100644 abi-checker/src/kernel_abi_checker_elf.c
+ create mode 100644 tools/abi-checker/data/abi_3.10.19_1
+ create mode 100644 tools/abi-checker/sample/LICENSE
+ create mode 100644 tools/abi-checker/sample/Makefile
+ create mode 100644 tools/abi-checker/sample/packaging/sample-module.spec.txt
+ create mode 100644 tools/abi-checker/sample/sample_module.c
+ create mode 100644 tools/abi-checker/src/Makefile
+ create mode 100755 tools/abi-checker/src/abi-module-checker
+ create mode 100755 tools/abi-checker/src/abi-module-dumper
+ create mode 100755 tools/abi-checker/src/abi-module-kernels-list
+ create mode 100755 tools/abi-checker/src/build_api_kernel_checker.sh
+ create mode 100644 tools/abi-checker/src/kernel_abi_checker.c
+ create mode 100644 tools/abi-checker/src/kernel_abi_checker.h
+ create mode 100644 tools/abi-checker/src/kernel_abi_checker_elf.c
+
+diff --git a/Documentation/abi-checker.txt b/Documentation/abi-checker.txt
+new file mode 100644
+index 0000000..57caa21
+--- /dev/null
++++ b/Documentation/abi-checker.txt
+@@ -0,0 +1,132 @@
++
++                       Linux kernel ABI/API checker
++--------------------------------------------------------------------------
++
++I. Introduction
++===============
++
++   "abi-checker" is a simple set of tools to:
++- test changes in Linux kernel API/ABI.
++- test compatibility kernel module wth kernel
++- creates dump for external kernel modules with list of kernel symbols
++  used by the module.
++
++
++II. Application/scripts
++=======================
++
++1. abi-checker
++
++   The application can be run in the following modes:
++   - "test-kernel" - in the mode compares two Module.symvers files.
++                   In case if some changes have been detected the
++                   application creates report containg list of changed symbols
++                   (added/changed/removed). Additionally summary ireport with
++                   total number symbols, itotal number changed/modified/removed
++                   symbols is created.
++
++                   Usage:
++                     abi-checker test-kernel file1 file2
++
++                   Return values:
++                     0 - if Module.symvers are identical
++                     1 - if some changes have been detected.
++
++   - "build-list" - in the mode the applications creates file containing linux kernel
++                   symbols uses by the module.
++                   As input the application expect:
++                   - kernel Module.symvers file
++                   - module symbols file - each line of the file has
++                     name of the module symbol.
++
++                   As output the application creates file in format like "Modules.symvers".
++
++                   Usage:
++                     abi-checker build-list Module.symvers kernel_symbols_file output_file
++
++                   Return:
++                     0 - success
++                     1 - any error
++
++   - "dump-module" - in the mode the application directly extracts from *.ko file
++                   symbols and creates file in format like Module.symvers containing list
++                   of kernel symbols used by the module.
++
++                   Usage:
++                     abi-checker dump-module Module.symvers module_ko_file output_file
++
++                   Return:
++                     0 - success
++                     1 - any error
++
++   - "test-module" - in the mode the application compares kernel "Module.symvers" file
++                   with external module "Module.symvers" file. In case of any differences
++                   list of changed/removed symbols is reported. Additionally summary info
++                   with numer total number symbols, total number changed/modified/removed
++                   symbols is created also.
++
++                   Usage:
++                     abi-checker test-module kernel_Module.symvers module_Module.symvers
++
++                   Return:
++                     0 - if all module symbols are identical with kernel symbols
++                     1 - if some changes have been detected.
++
++2. abi-module-checker - helper script. It simplify API/API checks for kernel module. Internally
++                  the script call abi-checker in "test-module" mode. The script assumes that in
++                  /boot/abi directory is present ABI/API repository for linux kernel.
++
++                  Usage:
++                    abi-module-checker kernel_module_abi_file
++
++                  Return:
++                    0 - if module API/ABI file is compatible with current kernel
++                    1 - in case if module is not compatible with current kernel or error
++
++3. abi-module-dumper - helper script. It simplify ABI/API module dump file creation. The script
++                  assumes that in /boot/abi directory is present ABI/API repository for linux kernel.
++
++                  Usage:
++                    abi-module-dumper _module_ko_file_ _output_file_
++
++                  Return:
++                    0 - success
++                    1 - any error
++
++4. abi-module-kernels-list - helper script. The script reporst all kernel version compatible
++                  with the given kernel module. The script assumes that in /boot/abi directory
++                  is present ABI/API repository for linux kernel.
++
++                  Usage:
++                    abi-module-kernels-list _module_abi_file_
++
++                  Return:
++                    0 - success
++                    1 - any error
++
++III. Module.symvers file format
++===============================
++
++   Each line of the Module.symvers file has the folloing format:
++
++      symbol_name<tab>symbol_crc<tab>module_name<tab>additiona_info
++
++Example:
++      ...
++      0x27e1a049      printk  vmlinux EXPORT_SYMBOL
++      0xf85bebf9      dev_printk_emit vmlinux EXPORT_SYMBOL
++      ...
++
++IV. Kernel ABI/API repository
++=============================
++
++   The ABI/API repository is located in /boot/abi direcotry. The repository contains list of all
++ABI/API versions (also for historical kernel versions).
++   The repository contains list of files which names are in format abi_${KERNELVERSION}_${ABIVERSION}.
++ABI/API file for current kernel version is marked by current symbolic link.
++
++V. Kernel ABI/API repository
++============================
++
++   Directory tools/abi-checker/data ABI/API Module.symvers for current and older kernel version.
++Module.symvers for current kernel version is indicated by current symbolic link.
+diff --git a/abi-checker/data/abi_3.10.19_1 b/abi-checker/data/abi_3.10.19_1
+deleted file mode 100644
+index eea3455..0000000
+--- a/abi-checker/data/abi_3.10.19_1
++++ /dev/null
+@@ -1,6900 +0,0 @@
+-0x80e54114    cfg80211_send_rx_assoc  vmlinux EXPORT_SYMBOL
+-0xd4dd4a5f    ipv6_chk_custom_prefix  vmlinux EXPORT_SYMBOL
+-0x765592d7    generic_file_splice_write       vmlinux EXPORT_SYMBOL
+-0x74f78b5f    set_anon_super  vmlinux EXPORT_SYMBOL
+-0x88ea56ef    kmem_cache_alloc        vmlinux EXPORT_SYMBOL
+-0x149d22ae    replace_page_cache_page vmlinux EXPORT_SYMBOL_GPL
+-0x70523a7a    __cond_resched_softirq  vmlinux EXPORT_SYMBOL
+-0x55417264    unregister_vt_notifier  vmlinux EXPORT_SYMBOL_GPL
+-0xc2ea8e64    snd_soc_platform_read   vmlinux EXPORT_SYMBOL_GPL
+-0x0a2487e0    unblock_all_signals     vmlinux EXPORT_SYMBOL
+-0x260cf8f8    of_get_property vmlinux EXPORT_SYMBOL
+-0x6ac315b3    v4l2_m2m_ioctl_dqbuf    vmlinux EXPORT_SYMBOL_GPL
+-0x5c421d9d    i2c_put_adapter vmlinux EXPORT_SYMBOL
+-0x4d8e0b9c    rtc_class_open  vmlinux EXPORT_SYMBOL_GPL
+-0x96cd2b04    scsi_sense_key_string   vmlinux EXPORT_SYMBOL
+-0xedf10a85    request_firmware        vmlinux EXPORT_SYMBOL
+-0x70230d35    __hci_cmd_sync  vmlinux EXPORT_SYMBOL
+-0x79dc2bec    dev_uc_sync     vmlinux EXPORT_SYMBOL
+-0xeb396e95    dev_mc_sync     vmlinux EXPORT_SYMBOL
+-0x80ca5026    _bin2bcd        vmlinux EXPORT_SYMBOL
+-0xfbaaf01e    console_lock    vmlinux EXPORT_SYMBOL
+-0xdf5311f6    hwmon_device_unregister vmlinux EXPORT_SYMBOL_GPL
+-0xe113bbbc    csum_partial    vmlinux EXPORT_SYMBOL
+-0x1ef4f43e    cfg80211_wext_siwscan   vmlinux EXPORT_SYMBOL_GPL
+-0xb343d54f    cfg80211_wext_giwscan   vmlinux EXPORT_SYMBOL_GPL
+-0xc068440e    __kfifo_alloc   vmlinux EXPORT_SYMBOL
+-0x376eb932    kmap_atomic     vmlinux EXPORT_SYMBOL
+-0xaadff4e7    nf_log_register vmlinux EXPORT_SYMBOL
+-0xc8276a79    nf_hooks_needed vmlinux EXPORT_SYMBOL
+-0x1b17e06c    kstrtoll        vmlinux EXPORT_SYMBOL
+-0xa7d57242    scsi_execute    vmlinux EXPORT_SYMBOL
+-0x9b757ebd    raw_seq_open    vmlinux EXPORT_SYMBOL_GPL
+-0x1b479d00    snd_soc_of_parse_audio_routing  vmlinux EXPORT_SYMBOL_GPL
+-0x3b2785b0    crypto_hash_walk_done   vmlinux EXPORT_SYMBOL_GPL
+-0xa1d55e90    _raw_spin_lock_bh       vmlinux EXPORT_SYMBOL
+-0xdd391eff    profile_event_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0xa724257f    init_uts_ns     vmlinux EXPORT_SYMBOL_GPL
+-0xc97d1140    cpufreq_cooling_get_level       vmlinux EXPORT_SYMBOL_GPL
+-0x5898fd79    device_add      vmlinux EXPORT_SYMBOL_GPL
+-0x5081d0b3    device_del      vmlinux EXPORT_SYMBOL_GPL
+-0x37246b6e    __inet6_hash    vmlinux EXPORT_SYMBOL
+-0xad3a5766    dst_release     vmlinux EXPORT_SYMBOL
+-0x1e254a30    sock_no_mmap    vmlinux EXPORT_SYMBOL
+-0x854e1c0b    sg_nents        vmlinux EXPORT_SYMBOL
+-0xb4c753a2    disk_map_sector_rcu     vmlinux EXPORT_SYMBOL_GPL
+-0x942da6f0    sysfs_update_group      vmlinux EXPORT_SYMBOL_GPL
+-0xa38602cd    drain_workqueue vmlinux EXPORT_SYMBOL_GPL
+-0xd4b5f202    led_trigger_store       vmlinux EXPORT_SYMBOL_GPL
+-0x80104269    tcp_initialize_rcv_mss  vmlinux EXPORT_SYMBOL
+-0x54e6fcdd    net_enable_timestamp    vmlinux EXPORT_SYMBOL
+-0xeb32f5c3    sockfd_lookup   vmlinux EXPORT_SYMBOL
+-0x02aa8f04    snd_soc_dapm_get_pin_switch     vmlinux EXPORT_SYMBOL_GPL
+-0x762265ad    snd_soc_dapm_put_pin_switch     vmlinux EXPORT_SYMBOL_GPL
+-0xb0ffda2f    blk_limits_max_hw_sectors       vmlinux EXPORT_SYMBOL
+-0x7cd8695d    directly_mappable_cdev_bdi      vmlinux EXPORT_SYMBOL
+-0x6bc3fbc0    __unregister_chrdev     vmlinux EXPORT_SYMBOL
+-0x6bb86c7d    srcu_notifier_chain_register    vmlinux EXPORT_SYMBOL_GPL
+-0x4b661f3f    v4l2_ctrl_grab  vmlinux EXPORT_SYMBOL
+-0xd2bbf775    fb_validate_mode        vmlinux EXPORT_SYMBOL
+-0xe8d75b12    nfc_target_lost vmlinux EXPORT_SYMBOL
+-0xb2d299a9    dev_graft_qdisc vmlinux EXPORT_SYMBOL
+-0xa851973a    raw_notifier_call_chain vmlinux EXPORT_SYMBOL_GPL
+-0x138709ec    scsi_get_command        vmlinux EXPORT_SYMBOL
+-0x174afb1a    __sg_page_iter_next     vmlinux EXPORT_SYMBOL
+-0x30cada8f    radix_tree_next_hole    vmlinux EXPORT_SYMBOL
+-0xc0412578    scsi_target_quiesce     vmlinux EXPORT_SYMBOL
+-0xd7a5d2f8    transport_class_register        vmlinux EXPORT_SYMBOL_GPL
+-0xd2335101    drm_fb_get_bpp_depth    vmlinux EXPORT_SYMBOL
+-0xa9a33fdf    jbd2_journal_try_to_free_buffers        vmlinux EXPORT_SYMBOL
+-0xffd5a395    default_wake_function   vmlinux EXPORT_SYMBOL
+-0xd6cb49e3    dm_put_device   vmlinux EXPORT_SYMBOL
+-0xb6e1e07d    dm_get_device   vmlinux EXPORT_SYMBOL
+-0x1f9218e9    input_handler_for_each_handle   vmlinux EXPORT_SYMBOL
+-0x560c6863    transport_class_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0x65f3ad9a    fb_videomode_to_var     vmlinux EXPORT_SYMBOL
+-0x79ad634c    nfc_hci_send_cmd_async  vmlinux EXPORT_SYMBOL
+-0x6bbf9530    mount_subtree   vmlinux EXPORT_SYMBOL
+-0x8f22ce41    iget_locked     vmlinux EXPORT_SYMBOL
+-0x6fba7c75    sdhci_runtime_suspend_host      vmlinux EXPORT_SYMBOL_GPL
+-0x7f923f2a    v4l2_of_parse_endpoint  vmlinux EXPORT_SYMBOL
+-0xaa2d0ca7    input_mt_assign_slots   vmlinux EXPORT_SYMBOL
+-0x167fd723    drm_mm_clean    vmlinux EXPORT_SYMBOL
+-0x9733c21d    sock_get_timestampns    vmlinux EXPORT_SYMBOL
+-0xf42e571f    snd_soc_dapm_put_enum_virt      vmlinux EXPORT_SYMBOL_GPL
+-0xcd16649c    snd_soc_dapm_get_enum_virt      vmlinux EXPORT_SYMBOL_GPL
+-0x38cb130f    iommu_group_add_device  vmlinux EXPORT_SYMBOL_GPL
+-0xe90d597e    class_interface_register        vmlinux EXPORT_SYMBOL_GPL
+-0x49ebacbd    _clear_bit      vmlinux EXPORT_SYMBOL
+-0x853b6dce    nfc_tm_activated        vmlinux EXPORT_SYMBOL
+-0xc617f82c    unregister_oom_notifier vmlinux EXPORT_SYMBOL_GPL
+-0x8da9fa20    spi_get_device_id       vmlinux EXPORT_SYMBOL_GPL
+-0x882f44c1    class_interface_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0x03757c9b    of_get_named_gpio_flags vmlinux EXPORT_SYMBOL
+-0x1b68aba6    pin_config_set  vmlinux EXPORT_SYMBOL
+-0x7505e34c    snd_power_wait  vmlinux EXPORT_SYMBOL
+-0x44366cfc    simple_write_to_buffer  vmlinux EXPORT_SYMBOL
+-0x3fec6133    read_code       vmlinux EXPORT_SYMBOL
+-0xf7bb3a63    __srcu_read_unlock      vmlinux EXPORT_SYMBOL_GPL
+-0xc2e587d1    reset_devices   vmlinux EXPORT_SYMBOL
+-0x07b991fc    iio_kfifo_free  vmlinux EXPORT_SYMBOL
+-0x36c38507    tty_register_device     vmlinux EXPORT_SYMBOL
+-0xa5a633b9    sg_last vmlinux EXPORT_SYMBOL
+-0x62c4e40d    __blk_run_queue vmlinux EXPORT_SYMBOL
+-0x3eaf291d    param_get_string        vmlinux EXPORT_SYMBOL
+-0x95cb929c    of_find_all_nodes       vmlinux EXPORT_SYMBOL
+-0xc2c5a45e    mmc_app_cmd     vmlinux EXPORT_SYMBOL_GPL
+-0xfa388487    usb_bus_list_lock       vmlinux EXPORT_SYMBOL_GPL
+-0xdbbaeb6e    regulator_map_voltage_linear    vmlinux EXPORT_SYMBOL_GPL
+-0x99bb8806    memmove vmlinux EXPORT_SYMBOL
+-0x9e6e25f9    jbd2_journal_start_commit       vmlinux EXPORT_SYMBOL
+-0x4c0f005a    __block_page_mkwrite    vmlinux EXPORT_SYMBOL
+-0x76d3cd60    laptop_mode     vmlinux EXPORT_SYMBOL
+-0x8fd01dea    generic_file_direct_write       vmlinux EXPORT_SYMBOL
+-0xa1f38f97    end_page_writeback      vmlinux EXPORT_SYMBOL
+-0xa75312bc    call_rcu_sched  vmlinux EXPORT_SYMBOL_GPL
+-0xb67b2219    cm_suspend_again        vmlinux EXPORT_SYMBOL_GPL
+-0x80311392    dmam_declare_coherent_memory    vmlinux EXPORT_SYMBOL
+-0xf2e8c6fe    skb_recv_datagram       vmlinux EXPORT_SYMBOL
+-0x4325cade    snd_soc_jack_add_pins   vmlinux EXPORT_SYMBOL_GPL
+-0x69cadac1    d_alloc_pseudo  vmlinux EXPORT_SYMBOL
+-0x871c0a7e    fiemap_check_flags      vmlinux EXPORT_SYMBOL
+-0xd0804fe2    generic_file_readonly_mmap      vmlinux EXPORT_SYMBOL
+-0xd06524ba    raw_notifier_chain_unregister   vmlinux EXPORT_SYMBOL_GPL
+-0x26448a56    usbnet_cdc_unbind       vmlinux EXPORT_SYMBOL_GPL
+-0x0bbae511    return_address  vmlinux EXPORT_SYMBOL_GPL
+-0x0d542439    __ipv6_addr_type        vmlinux EXPORT_SYMBOL
+-0xcf470397    unregister_qdisc        vmlinux EXPORT_SYMBOL
+-0x66a8c67c    crypto_shash_finup      vmlinux EXPORT_SYMBOL_GPL
+-0x5647361d    crypto_shash_final      vmlinux EXPORT_SYMBOL_GPL
+-0xf1c942f4    crypto_ahash_finup      vmlinux EXPORT_SYMBOL_GPL
+-0x17209ab0    crypto_ahash_final      vmlinux EXPORT_SYMBOL_GPL
+-0x8da17b42    scatterwalk_copychunks  vmlinux EXPORT_SYMBOL_GPL
+-0xd766d6a2    sdhci_suspend_host      vmlinux EXPORT_SYMBOL_GPL
+-0x9b05a0c7    usb_autopm_get_interface        vmlinux EXPORT_SYMBOL_GPL
+-0x8eff5a5b    phy_device_register     vmlinux EXPORT_SYMBOL
+-0xa2101833    sock_diag_put_meminfo   vmlinux EXPORT_SYMBOL_GPL
+-0xc8339e24    string_unescape vmlinux EXPORT_SYMBOL
+-0xeb55a931    __kfifo_max_r   vmlinux EXPORT_SYMBOL
+-0xe6511495    vm_insert_page  vmlinux EXPORT_SYMBOL
+-0x4396b273    irq_domain_add_legacy   vmlinux EXPORT_SYMBOL_GPL
+-0x24fdb0df    register_console        vmlinux EXPORT_SYMBOL
+-0x6ac76b42    pin_is_valid    vmlinux EXPORT_SYMBOL_GPL
+-0xe279ec34    nf_conntrack_l4proto_tcp4       vmlinux EXPORT_SYMBOL_GPL
+-0x512ce34d    sock_no_socketpair      vmlinux EXPORT_SYMBOL
+-0x236032ef    input_ff_event  vmlinux EXPORT_SYMBOL_GPL
+-0x1e5431bd    devm_gpio_request       vmlinux EXPORT_SYMBOL
+-0x86383d16    arpt_do_table   vmlinux EXPORT_SYMBOL
+-0x3c89040c    dev_addr_del    vmlinux EXPORT_SYMBOL
+-0xd900e010    gnet_stats_start_copy   vmlinux EXPORT_SYMBOL
+-0x33f0768c    cpufreq_quick_get_max   vmlinux EXPORT_SYMBOL
+-0xa88a70b0    tcp_tso_segment vmlinux EXPORT_SYMBOL
+-0xa652c4ef    __kfifo_dma_in_prepare_r        vmlinux EXPORT_SYMBOL
+-0xdfb895e4    __fat_fs_error  vmlinux EXPORT_SYMBOL_GPL
+-0x00438c43    bio_copy_kern   vmlinux EXPORT_SYMBOL
+-0xe0878bfe    __krealloc      vmlinux EXPORT_SYMBOL
+-0xa849b57b    devm_free_irq   vmlinux EXPORT_SYMBOL
+-0x995d1071    prof_on vmlinux EXPORT_SYMBOL_GPL
+-0x3328c21e    task_nice       vmlinux EXPORT_SYMBOL
+-0x84109a46    i2c_lock_adapter        vmlinux EXPORT_SYMBOL_GPL
+-0x76f824bb    usb_gadget_set_state    vmlinux EXPORT_SYMBOL_GPL
+-0x702c11cd    platform_device_del     vmlinux EXPORT_SYMBOL_GPL
+-0xccfe749d    platform_device_put     vmlinux EXPORT_SYMBOL_GPL
+-0x6499c2c3    kernel_accept   vmlinux EXPORT_SYMBOL
+-0x0147e076    kset_create_and_add     vmlinux EXPORT_SYMBOL_GPL
+-0xf60d1625    mm_kobj vmlinux EXPORT_SYMBOL_GPL
+-0x66561d40    set_bdi_congested       vmlinux EXPORT_SYMBOL
+-0xa064fc2f    gs_free_req     vmlinux EXPORT_SYMBOL_GPL
+-0xaf70f0bf    xt_proto_fini   vmlinux EXPORT_SYMBOL_GPL
+-0xc1e7bf31    devm_ioremap_resource   vmlinux EXPORT_SYMBOL
+-0x71d3571b    sg_miter_start  vmlinux EXPORT_SYMBOL
+-0xc5894dbd    blk_queue_unprep_rq     vmlinux EXPORT_SYMBOL
+-0x159c0774    lock_may_read   vmlinux EXPORT_SYMBOL
+-0x56d697ce    cpu_up  vmlinux EXPORT_SYMBOL_GPL
+-0xba406d79    usb_gadget_map_request  vmlinux EXPORT_SYMBOL_GPL
+-0xe2b9dcc5    wakeup_source_drop      vmlinux EXPORT_SYMBOL_GPL
+-0x19011c29    driver_find     vmlinux EXPORT_SYMBOL_GPL
+-0x13031824    devm_gpio_request_one   vmlinux EXPORT_SYMBOL
+-0x91db6962    snd_card_free   vmlinux EXPORT_SYMBOL
+-0x157b3f69    load_nls        vmlinux EXPORT_SYMBOL
+-0xffe5318c    dma_buf_map_attachment  vmlinux EXPORT_SYMBOL_GPL
+-0x10030de6    tty_mode_ioctl  vmlinux EXPORT_SYMBOL_GPL
+-0x00109670    fb_class        vmlinux EXPORT_SYMBOL
+-0x97999817    rfkill_set_hw_state     vmlinux EXPORT_SYMBOL
+-0x6597fe84    crypto_lookup_aead      vmlinux EXPORT_SYMBOL_GPL
+-0xd7b4b67a    bio_advance     vmlinux EXPORT_SYMBOL
+-0x4b8408ef    from_kuid       vmlinux EXPORT_SYMBOL
+-0xb65bd3fc    add_timer_on    vmlinux EXPORT_SYMBOL_GPL
+-0x4859b8bb    rtc_year_days   vmlinux EXPORT_SYMBOL
+-0xa064f393    ehci_cf_port_reset_rwsem        vmlinux EXPORT_SYMBOL_GPL
+-0x0c65e73c    scsi_normalize_sense    vmlinux EXPORT_SYMBOL
+-0x8e84b481    __pm_runtime_use_autosuspend    vmlinux EXPORT_SYMBOL_GPL
+-0xab2495da    drm_mode_connector_detach_encoder       vmlinux EXPORT_SYMBOL
+-0xbb11cfba    klist_iter_exit vmlinux EXPORT_SYMBOL_GPL
+-0x84044a12    ip6_local_out   vmlinux EXPORT_SYMBOL_GPL
+-0xc80b5684    snd_compress_deregister vmlinux EXPORT_SYMBOL_GPL
+-0x215ebd78    bitrev16        vmlinux EXPORT_SYMBOL
+-0x390def22    kstrtou16_from_user     vmlinux EXPORT_SYMBOL
+-0x9a74417e    kstrtoull_from_user     vmlinux EXPORT_SYMBOL
+-0x6949942d    pm_runtime_set_autosuspend_delay        vmlinux EXPORT_SYMBOL_GPL
+-0xfb6eedf9    power_group_name        vmlinux EXPORT_SYMBOL_GPL
+-0x7752eabc    snd_pcm_new_internal    vmlinux EXPORT_SYMBOL
+-0x59cdb28e    crypto_aead_type        vmlinux EXPORT_SYMBOL_GPL
+-0xeadf5b18    jbd2_journal_load       vmlinux EXPORT_SYMBOL
+-0xcd6a7390    v4l2_i2c_new_subdev     vmlinux EXPORT_SYMBOL_GPL
+-0x997574ce    device_unregister       vmlinux EXPORT_SYMBOL_GPL
+-0xedbfb39a    serial8250_request_dma  vmlinux EXPORT_SYMBOL_GPL
+-0x19a156ad    xfrm_state_add  vmlinux EXPORT_SYMBOL
+-0x4d4a6141    __netlink_kernel_create vmlinux EXPORT_SYMBOL
+-0x3ad82802    of_property_read_u32_index      vmlinux EXPORT_SYMBOL_GPL
+-0x96b53df6    mmc_cleanup_queue       vmlinux EXPORT_SYMBOL
+-0x7b9ee22c    v4l2_ctrl_notify        vmlinux EXPORT_SYMBOL
+-0xda3a7ca9    regulator_is_enabled    vmlinux EXPORT_SYMBOL_GPL
+-0x137def66    nf_ct_l4proto_put       vmlinux EXPORT_SYMBOL_GPL
+-0x7efdb4fb    nf_ct_l3proto_put       vmlinux EXPORT_SYMBOL_GPL
+-0x9948898e    dapm_mark_dirty vmlinux EXPORT_SYMBOL_GPL
+-0x2484d571    single_release_net      vmlinux EXPORT_SYMBOL_GPL
+-0x5612133a    I_BDEV  vmlinux EXPORT_SYMBOL
+-0x7729cbdd    task_handoff_register   vmlinux EXPORT_SYMBOL_GPL
+-0x19353b86    scsicam_bios_param      vmlinux EXPORT_SYMBOL
+-0xb6a76b8e    pn544_hci_probe vmlinux EXPORT_SYMBOL
+-0x476c3efa    drm_fill_in_dev vmlinux EXPORT_SYMBOL
+-0x4f1cd128    security_tun_dev_create vmlinux EXPORT_SYMBOL
+-0x76f29bbf    seq_release_net vmlinux EXPORT_SYMBOL_GPL
+-0x980420fb    tty_port_tty_set        vmlinux EXPORT_SYMBOL
+-0xc215715c    tty_port_tty_get        vmlinux EXPORT_SYMBOL
+-0xa8c74dc5    devm_regulator_get      vmlinux EXPORT_SYMBOL_GPL
+-0x3441c3d6    gpio_set_value_cansleep vmlinux EXPORT_SYMBOL_GPL
+-0xcd68dc1d    nfc_get_local_general_bytes     vmlinux EXPORT_SYMBOL
+-0xf617c0a1    inet_csk_route_child_sock       vmlinux EXPORT_SYMBOL_GPL
+-0xfce4d2e1    vfs_path_lookup vmlinux EXPORT_SYMBOL
+-0x326314e4    find_or_create_page     vmlinux EXPORT_SYMBOL
+-0x65bbbc78    schedule_hrtimeout_range        vmlinux EXPORT_SYMBOL_GPL
+-0x8d7b0a28    phy_stop_interrupts     vmlinux EXPORT_SYMBOL
+-0xe9e87de1    crypto_register_pcomp   vmlinux EXPORT_SYMBOL_GPL
+-0x2d7966fb    jbd2_journal_flush      vmlinux EXPORT_SYMBOL
+-0x1c4e8441    invalidate_bdev vmlinux EXPORT_SYMBOL
+-0x9aeacb87    ring_buffer_iter_empty  vmlinux EXPORT_SYMBOL_GPL
+-0x49eb1c4a    put_pid_ns      vmlinux EXPORT_SYMBOL_GPL
+-0xb7e67f9a    iio_sw_buffer_preenable vmlinux EXPORT_SYMBOL
+-0xeae6b2cc    usb_sg_init     vmlinux EXPORT_SYMBOL_GPL
+-0x2f33a47d    usb_sg_wait     vmlinux EXPORT_SYMBOL_GPL
+-0xba136537    scsi_reset_provider     vmlinux EXPORT_SYMBOL
+-0xa9170094    drm_kms_helper_hotplug_event    vmlinux EXPORT_SYMBOL
+-0xb007d3b8    tcp_twsk_unique vmlinux EXPORT_SYMBOL_GPL
+-0xd35091f2    netdev_info     vmlinux EXPORT_SYMBOL
+-0x3517b864    kobject_uevent  vmlinux EXPORT_SYMBOL_GPL
+-0x82a5ee54    mmc_try_claim_host      vmlinux EXPORT_SYMBOL
+-0x11267875    scsi_extd_sense_format  vmlinux EXPORT_SYMBOL
+-0x4f56540f    pm_wakeup_event vmlinux EXPORT_SYMBOL_GPL
+-0x6c61ce70    num_registered_fb       vmlinux EXPORT_SYMBOL
+-0xcc2f1602    st_sensors_sysfs_get_sampling_frequency vmlinux EXPORT_SYMBOL
+-0x0bf95cc0    st_sensors_sysfs_set_sampling_frequency vmlinux EXPORT_SYMBOL
+-0xa73fc98f    of_n_addr_cells vmlinux EXPORT_SYMBOL
+-0xaf5c2852    wakeup_source_add       vmlinux EXPORT_SYMBOL_GPL
+-0xc27732b1    snd_pcm_lib_default_mmap        vmlinux EXPORT_SYMBOL_GPL
+-0x3ca17104    __snd_printk    vmlinux EXPORT_SYMBOL_GPL
+-0xa6a59f23    blk_cleanup_queue       vmlinux EXPORT_SYMBOL
+-0xec3364ec    generic_setlease        vmlinux EXPORT_SYMBOL
+-0x440d8a62    tty_hung_up_p   vmlinux EXPORT_SYMBOL
+-0xfa2e4ead    ip6_tnl_dst_store       vmlinux EXPORT_SYMBOL_GPL
+-0x5a0647c1    ipv6_getsockopt vmlinux EXPORT_SYMBOL
+-0x329bbbde    timerqueue_del  vmlinux EXPORT_SYMBOL_GPL
+-0x34161524    st_sensors_read_event_value     vmlinux EXPORT_SYMBOL
+-0x3e16c1b5    v4l2_clk_put    vmlinux EXPORT_SYMBOL
+-0xdc047fc4    scsi_dev_info_list_add_keyed    vmlinux EXPORT_SYMBOL
+-0xdc97af2e    syscore_suspend vmlinux EXPORT_SYMBOL_GPL
+-0xaebbf521    cfg80211_ch_switch_notify       vmlinux EXPORT_SYMBOL
+-0x4fdb4cdf    proc_mkdir_data vmlinux EXPORT_SYMBOL_GPL
+-0x8ffad455    mpage_writepages        vmlinux EXPORT_SYMBOL
+-0x258f05ac    write_one_page  vmlinux EXPORT_SYMBOL
+-0x32b31a8c    ktime_get_boottime      vmlinux EXPORT_SYMBOL_GPL
+-0x15892417    async_synchronize_cookie        vmlinux EXPORT_SYMBOL_GPL
+-0x5a596330    v4l2_i2c_new_subdev_board       vmlinux EXPORT_SYMBOL_GPL
+-0xbd05974a    usb_driver_release_interface    vmlinux EXPORT_SYMBOL_GPL
+-0xce190a28    cfg80211_notify_new_peer_candidate      vmlinux EXPORT_SYMBOL
+-0x23c45e2a    inet_add_protocol       vmlinux EXPORT_SYMBOL
+-0xe19c66e3    sync_blockdev   vmlinux EXPORT_SYMBOL
+-0xd36667e2    nobh_write_end  vmlinux EXPORT_SYMBOL
+-0x815a1805    n_tty_ioctl_helper      vmlinux EXPORT_SYMBOL
+-0xedd9106d    __ashrdi3       vmlinux EXPORT_SYMBOL
+-0xff67b37f    __lshrdi3       vmlinux EXPORT_SYMBOL
+-0x85b5e625    rfkill_set_states       vmlinux EXPORT_SYMBOL
+-0x6e720ff2    rtnl_unlock     vmlinux EXPORT_SYMBOL
+-0x4c02a5f2    sock_rfree      vmlinux EXPORT_SYMBOL
+-0xe252485d    kernel_recvmsg  vmlinux EXPORT_SYMBOL
+-0x0693eedb    disk_part_iter_init     vmlinux EXPORT_SYMBOL_GPL
+-0x4019ac2a    freeze_bdev     vmlinux EXPORT_SYMBOL
+-0x9f1c66aa    srcu_batches_completed  vmlinux EXPORT_SYMBOL_GPL
+-0xa6ec6db0    sdhci_alloc_host        vmlinux EXPORT_SYMBOL_GPL
+-0x0bfba95f    usb_hub_find_child      vmlinux EXPORT_SYMBOL_GPL
+-0x9f83d040    __root_device_register  vmlinux EXPORT_SYMBOL_GPL
+-0x63b124fc    drm_bl_dpms     vmlinux EXPORT_SYMBOL_GPL
+-0xb35f8f7f    __hci_cmd_sync_ev       vmlinux EXPORT_SYMBOL
+-0xe177ecc2    skb_kill_datagram       vmlinux EXPORT_SYMBOL
+-0x985c6297    kfree_skb       vmlinux EXPORT_SYMBOL
+-0xdcb83c11    kernel_kobj     vmlinux EXPORT_SYMBOL_GPL
+-0x1bb5fc26    atomic_notifier_chain_register  vmlinux EXPORT_SYMBOL_GPL
+-0xab1d6cc1    param_get_long  vmlinux EXPORT_SYMBOL
+-0x75d68801    inet_twsk_schedule      vmlinux EXPORT_SYMBOL_GPL
+-0x68b83ac6    posix_acl_alloc vmlinux EXPORT_SYMBOL
+-0x306b23a8    drm_mm_takedown vmlinux EXPORT_SYMBOL
+-0x698be398    regulator_get_voltage   vmlinux EXPORT_SYMBOL_GPL
+-0xc8bed9c5    amba_driver_unregister  vmlinux EXPORT_SYMBOL
+-0x1db7dc40    pgprot_kernel   vmlinux EXPORT_SYMBOL
+-0x19e03378    cfg80211_get_p2p_attr   vmlinux EXPORT_SYMBOL
+-0x44a5de9b    nfnetlink_parse_nat_setup_hook  vmlinux EXPORT_SYMBOL_GPL
+-0x52d047db    skb_copy_datagram_iovec vmlinux EXPORT_SYMBOL
+-0x731f351a    __kfree_skb     vmlinux EXPORT_SYMBOL
+-0xd544b6fe    fuse_do_open    vmlinux EXPORT_SYMBOL_GPL
+-0xd98f64fc    tty_port_register_device        vmlinux EXPORT_SYMBOL_GPL
+-0xfd305341    walk_stackframe vmlinux EXPORT_SYMBOL
+-0x58378f4a    snd_soc_dapm_force_enable_pin   vmlinux EXPORT_SYMBOL_GPL
+-0x31b31f5c    csum_partial_copy_nocheck       vmlinux EXPORT_SYMBOL
+-0xeea82d10    ip_defrag       vmlinux EXPORT_SYMBOL
+-0xd75abd53    register_qdisc  vmlinux EXPORT_SYMBOL
+-0xe4bf323c    snd_soc_test_bits       vmlinux EXPORT_SYMBOL_GPL
+-0x5d891a64    idr_destroy     vmlinux EXPORT_SYMBOL
+-0xeb9e7cdd    ida_destroy     vmlinux EXPORT_SYMBOL
+-0x302b0f11    generic_file_aio_read   vmlinux EXPORT_SYMBOL
+-0x3fe00f7d    mmc_can_discard vmlinux EXPORT_SYMBOL
+-0x51246a07    mmc_interrupt_hpi       vmlinux EXPORT_SYMBOL
+-0xce55bca9    scsi_flush_work vmlinux EXPORT_SYMBOL_GPL
+-0x3ca53f5d    arpt_alloc_initial_table        vmlinux EXPORT_SYMBOL_GPL
+-0x3ab45d33    free_netdev     vmlinux EXPORT_SYMBOL
+-0xc9ec4e21    free_percpu     vmlinux EXPORT_SYMBOL_GPL
+-0x431fd1f6    v4l2_subdev_queryctrl   vmlinux EXPORT_SYMBOL
+-0x7c0f2bb5    drm_mm_create_block     vmlinux EXPORT_SYMBOL
+-0x3fa79dd5    ip6_datagram_recv_ctl   vmlinux EXPORT_SYMBOL_GPL
+-0xd56d7aae    sk_setup_caps   vmlinux EXPORT_SYMBOL_GPL
+-0x668da8d5    zlib_inflateIncomp      vmlinux EXPORT_SYMBOL
+-0xe0f99a2f    ida_pre_get     vmlinux EXPORT_SYMBOL
+-0xf932015f    __raw_notifier_call_chain       vmlinux EXPORT_SYMBOL_GPL
+-0x4d3c153f    sigprocmask     vmlinux EXPORT_SYMBOL
+-0xd1974639    spi_sync_locked vmlinux EXPORT_SYMBOL_GPL
+-0xdcbd7c06    scsi_host_get   vmlinux EXPORT_SYMBOL
+-0x8ccc342d    drm_helper_move_panel_connectors_to_head        vmlinux EXPORT_SYMBOL
+-0x98578bb6    regulator_bulk_get      vmlinux EXPORT_SYMBOL_GPL
+-0x85ddc629    sk_stream_wait_connect  vmlinux EXPORT_SYMBOL
+-0x4db49a03    vb2_ioctl_dqbuf vmlinux EXPORT_SYMBOL_GPL
+-0xf720d75c    drm_vblank_init vmlinux EXPORT_SYMBOL
+-0x8d551bef    sysctl_tcp_rmem vmlinux EXPORT_SYMBOL
+-0x6c8c2ae7    sock_no_sendmsg vmlinux EXPORT_SYMBOL
+-0x3b1b7e9f    snd_soc_bytes_get       vmlinux EXPORT_SYMBOL_GPL
+-0xf74dae0f    idr_alloc       vmlinux EXPORT_SYMBOL_GPL
+-0x7c666ca1    jbd2_journal_update_sb_errno    vmlinux EXPORT_SYMBOL
+-0x98d00f33    vfs_unlink      vmlinux EXPORT_SYMBOL
+-0x9ee85355    extcon_unregister_notifier      vmlinux EXPORT_SYMBOL_GPL
+-0xf9e3887b    i2c_master_recv vmlinux EXPORT_SYMBOL
+-0xaff711f1    drm_global_mutex        vmlinux EXPORT_SYMBOL
+-0x62c5828a    nfc_hci_set_param       vmlinux EXPORT_SYMBOL
+-0x52512e8e    nfc_hci_get_param       vmlinux EXPORT_SYMBOL
+-0x4c90a5a9    lro_flush_all   vmlinux EXPORT_SYMBOL
+-0xc5116125    pipe_unlock     vmlinux EXPORT_SYMBOL
+-0x2d6bcdcb    iio_trigger_generic_data_rdy_poll       vmlinux EXPORT_SYMBOL
+-0x48c6db53    of_get_child_by_name    vmlinux EXPORT_SYMBOL
+-0x4379f0a6    genlmsg_multicast_allns vmlinux EXPORT_SYMBOL
+-0x43e32587    __sock_recv_wifi_status vmlinux EXPORT_SYMBOL_GPL
+-0x83a5ae2e    __tracepoint_rpm_resume vmlinux EXPORT_SYMBOL_GPL
+-0xb2d48a2e    queue_work_on   vmlinux EXPORT_SYMBOL
+-0x59d8223a    ioport_resource vmlinux EXPORT_SYMBOL
+-0x73a25185    pm_generic_restore      vmlinux EXPORT_SYMBOL_GPL
+-0x401ad827    bus_rescan_devices      vmlinux EXPORT_SYMBOL_GPL
+-0x3b4e8e6c    serial8250_tx_dma       vmlinux EXPORT_SYMBOL_GPL
+-0xba9f64c5    put_tty_driver  vmlinux EXPORT_SYMBOL
+-0xa46a0fcf    backlight_force_update  vmlinux EXPORT_SYMBOL
+-0xc7a4fbed    rtnl_lock       vmlinux EXPORT_SYMBOL
+-0x27b3484e    debugfs_create_bool     vmlinux EXPORT_SYMBOL_GPL
+-0x3691702f    generic_file_splice_read        vmlinux EXPORT_SYMBOL
+-0xdd2efc0f    ring_buffer_reset_cpu   vmlinux EXPORT_SYMBOL_GPL
+-0x2c1d69dc    prepare_kernel_cred     vmlinux EXPORT_SYMBOL
+-0x897473df    mktime  vmlinux EXPORT_SYMBOL
+-0xa8721b97    system_state    vmlinux EXPORT_SYMBOL
+-0x2b768df3    iio_buffer_show_enable  vmlinux EXPORT_SYMBOL
+-0xc3070585    xfrm6_tunnel_alloc_spi  vmlinux EXPORT_SYMBOL
+-0x6e583bdd    udp_push_pending_frames vmlinux EXPORT_SYMBOL
+-0xead6dbe6    splice_from_pipe_next   vmlinux EXPORT_SYMBOL
+-0x6d044c26    param_ops_uint  vmlinux EXPORT_SYMBOL
+-0x6f0036d9    del_timer_sync  vmlinux EXPORT_SYMBOL
+-0xc9db98ec    hidinput_connect        vmlinux EXPORT_SYMBOL_GPL
+-0xa3a75748    sec_bulk_read   vmlinux EXPORT_SYMBOL_GPL
+-0x7c640527    bt_info vmlinux EXPORT_SYMBOL
+-0x00e8097b    csum_partial_copy_fromiovecend  vmlinux EXPORT_SYMBOL
+-0x098ef076    wm_hubs_vmid_ena        vmlinux EXPORT_SYMBOL_GPL
+-0xc29591b4    drm_framebuffer_unreference     vmlinux EXPORT_SYMBOL
+-0xdbfa4d5b    con_set_default_unimap  vmlinux EXPORT_SYMBOL
+-0x08b75c5b    inet_diag_bc_sk vmlinux EXPORT_SYMBOL_GPL
+-0x3dea553f    __qdisc_calculate_pkt_len       vmlinux EXPORT_SYMBOL
+-0xab5f8242    dev_get_by_index        vmlinux EXPORT_SYMBOL
+-0x3e9d0c22    wm8958_mic_detect       vmlinux EXPORT_SYMBOL_GPL
+-0x462a2e75    match_strlcpy   vmlinux EXPORT_SYMBOL
+-0xf768dabc    ioctl_by_bdev   vmlinux EXPORT_SYMBOL
+-0x426b04e4    dma_buf_unmap_attachment        vmlinux EXPORT_SYMBOL_GPL
+-0x27146b38    init_net        vmlinux EXPORT_SYMBOL
+-0x9fe06761    wm_hubs_update_class_w  vmlinux EXPORT_SYMBOL_GPL
+-0x8978d687    textsearch_find_continuous      vmlinux EXPORT_SYMBOL
+-0xf7b12aee    __next_cpu      vmlinux EXPORT_SYMBOL
+-0x96905151    crypto_larval_lookup    vmlinux EXPORT_SYMBOL_GPL
+-0xb14bfc6b    __crypto_alloc_tfm      vmlinux EXPORT_SYMBOL_GPL
+-0x3ca95bb3    configfs_unregister_subsystem   vmlinux EXPORT_SYMBOL
+-0xd820c283    eventfd_ctx_remove_wait_queue   vmlinux EXPORT_SYMBOL_GPL
+-0x699d1d6a    generic_delete_inode    vmlinux EXPORT_SYMBOL
+-0xb5f17edf    perf_register_guest_info_callbacks      vmlinux EXPORT_SYMBOL_GPL
+-0x1d209e24    mmc_power_restore_host  vmlinux EXPORT_SYMBOL
+-0x8c66045e    cpufreq_freq_attr_scaling_boost_freqs   vmlinux EXPORT_SYMBOL_GPL
+-0x6114d8a4    regulator_force_disable vmlinux EXPORT_SYMBOL_GPL
+-0x7e606130    snd_soc_calc_bclk       vmlinux EXPORT_SYMBOL_GPL
+-0xac480322    nf_nat_pptp_hook_expectfn       vmlinux EXPORT_SYMBOL_GPL
+-0x7f19e69f    blk_run_queue   vmlinux EXPORT_SYMBOL
+-0x98dbc3bc    mmc_wait_for_req        vmlinux EXPORT_SYMBOL
+-0xa0d2b347    regmap_init_spi vmlinux EXPORT_SYMBOL_GPL
+-0xff7a8968    regmap_init_i2c vmlinux EXPORT_SYMBOL_GPL
+-0x98cc564a    regulator_set_voltage   vmlinux EXPORT_SYMBOL_GPL
+-0xcd63c845    __aeabi_lasr    vmlinux EXPORT_SYMBOL
+-0x8a4fa83b    __aeabi_llsr    vmlinux EXPORT_SYMBOL
+-0x78cfc117    hci_register_dev        vmlinux EXPORT_SYMBOL
+-0xd458f195    __secpath_destroy       vmlinux EXPORT_SYMBOL
+-0xaf64ad0d    zlib_deflate    vmlinux EXPORT_SYMBOL
+-0x24fdac79    wake_bit_function       vmlinux EXPORT_SYMBOL
+-0x864f4a52    of_clk_add_provider     vmlinux EXPORT_SYMBOL_GPL
+-0x1de054d5    of_clk_del_provider     vmlinux EXPORT_SYMBOL_GPL
+-0x42c8e001    v4l2_ctrl_next  vmlinux EXPORT_SYMBOL
+-0x1e95b9ac    i2c_smbus_write_i2c_block_data  vmlinux EXPORT_SYMBOL
+-0xc61c11c2    inet_csk_route_req      vmlinux EXPORT_SYMBOL_GPL
+-0xed597524    qdisc_get_rtab  vmlinux EXPORT_SYMBOL
+-0x9a633fbd    fuse_request_send_background    vmlinux EXPORT_SYMBOL_GPL
+-0x578e47c8    locks_release_private   vmlinux EXPORT_SYMBOL_GPL
+-0x40ce485b    mempool_resize  vmlinux EXPORT_SYMBOL
+-0xc60f75ec    __ftrace_vprintk        vmlinux EXPORT_SYMBOL_GPL
+-0xb88fb22f    hid_set_field   vmlinux EXPORT_SYMBOL_GPL
+-0xd954e4a7    bus_remove_file vmlinux EXPORT_SYMBOL_GPL
+-0x6172f515    xfrm_unregister_km      vmlinux EXPORT_SYMBOL
+-0xc5e4258e    in_dev_finish_destroy   vmlinux EXPORT_SYMBOL
+-0xe094ef39    sg_next vmlinux EXPORT_SYMBOL
+-0x6b4be175    bio_map_user    vmlinux EXPORT_SYMBOL
+-0x0b07abe2    unshare_fs_struct       vmlinux EXPORT_SYMBOL_GPL
+-0x2ef6b5bf    smp_call_function_any   vmlinux EXPORT_SYMBOL_GPL
+-0xd0fb7cd4    __tasklet_hi_schedule_first     vmlinux EXPORT_SYMBOL
+-0xe35c5285    of_find_node_by_phandle vmlinux EXPORT_SYMBOL
+-0x55724b35    hid_destroy_device      vmlinux EXPORT_SYMBOL_GPL
+-0x85ad5803    cfg80211_wext_siwrts    vmlinux EXPORT_SYMBOL_GPL
+-0x87cfc6e0    cfg80211_wext_giwrts    vmlinux EXPORT_SYMBOL_GPL
+-0xd1b091c0    unix_inq_len    vmlinux EXPORT_SYMBOL_GPL
+-0xc4d21124    __nf_conntrack_confirm  vmlinux EXPORT_SYMBOL_GPL
+-0x452a56c2    __brelse        vmlinux EXPORT_SYMBOL
+-0xbddeca9d    pipe_lock       vmlinux EXPORT_SYMBOL
+-0x33bfdca2    gserial_alloc_line      vmlinux EXPORT_SYMBOL_GPL
+-0x4edb7421    config_ep_by_speed      vmlinux EXPORT_SYMBOL_GPL
+-0xa473e3d4    usbnet_suspend  vmlinux EXPORT_SYMBOL_GPL
+-0x06521223    mdiobus_scan    vmlinux EXPORT_SYMBOL
+-0xed8f1a2b    dmam_alloc_coherent     vmlinux EXPORT_SYMBOL
+-0x9535ce7b    tty_port_carrier_raised vmlinux EXPORT_SYMBOL
+-0x71280d73    regulator_set_voltage_time_sel  vmlinux EXPORT_SYMBOL_GPL
+-0x1e314b21    regulator_use_dummy_regulator   vmlinux EXPORT_SYMBOL_GPL
+-0x347fd4b3    eventfd_ctx_get vmlinux EXPORT_SYMBOL_GPL
+-0x941f2aaa    eventfd_ctx_put vmlinux EXPORT_SYMBOL_GPL
+-0xf9d18552    mark_buffer_async_write vmlinux EXPORT_SYMBOL
+-0x6c6cdd4d    wait_for_completion_interruptible_timeout       vmlinux EXPORT_SYMBOL
+-0xe5525b81    scsi_device_set_state   vmlinux EXPORT_SYMBOL
+-0x28e23139    xfrm_probe_algs vmlinux EXPORT_SYMBOL_GPL
+-0x9a9ff422    ip_route_me_harder      vmlinux EXPORT_SYMBOL
+-0xb7cbbafa    inet_sock_destruct      vmlinux EXPORT_SYMBOL
+-0xf26e8a56    nf_reinject     vmlinux EXPORT_SYMBOL
+-0x3a9b6fb9    blk_unregister_region   vmlinux EXPORT_SYMBOL
+-0x2a2c3036    unregister_nls  vmlinux EXPORT_SYMBOL
+-0x5358fc36    ring_buffer_discard_commit      vmlinux EXPORT_SYMBOL_GPL
+-0x555621fa    clk_enable      vmlinux EXPORT_SYMBOL_GPL
+-0xf25af73c    mmc_add_host    vmlinux EXPORT_SYMBOL
+-0x4b02b5ca    dev_pm_qos_update_request       vmlinux EXPORT_SYMBOL_GPL
+-0xe11c3bb2    tty_chars_in_buffer     vmlinux EXPORT_SYMBOL
+-0x4e60ec09    __serio_register_port   vmlinux EXPORT_SYMBOL
+-0xc17515d7    usb_hcds_loaded vmlinux EXPORT_SYMBOL_GPL
+-0xadfe5127    usbnet_write_cmd_nopm   vmlinux EXPORT_SYMBOL_GPL
+-0x9c6c1c9c    phy_exit        vmlinux EXPORT_SYMBOL_GPL
+-0x44da5d0f    __csum_ipv6_magic       vmlinux EXPORT_SYMBOL
+-0x2ef42c91    l2cap_register_user     vmlinux EXPORT_SYMBOL
+-0xa83b115e    skb_pull_rcsum  vmlinux EXPORT_SYMBOL_GPL
+-0xbaa490f8    snd_ctl_unregister_ioctl        vmlinux EXPORT_SYMBOL
+-0xe3df2eb1    v4l2_async_notifier_register    vmlinux EXPORT_SYMBOL
+-0x950c4994    __scsi_device_lookup_by_target  vmlinux EXPORT_SYMBOL
+-0xed3baf1d    tcp_fetch_timewait_stamp        vmlinux EXPORT_SYMBOL_GPL
+-0xebdbe48c    radix_tree_gang_lookup  vmlinux EXPORT_SYMBOL
+-0xc00b1f1e    register_nls    vmlinux EXPORT_SYMBOL
+-0x62543231    locks_alloc_lock        vmlinux EXPORT_SYMBOL_GPL
+-0x6585e310    alloc_pages_exact_nid   vmlinux EXPORT_SYMBOL
+-0xb121390a    probe_irq_on    vmlinux EXPORT_SYMBOL
+-0xc58f706b    usbnet_get_msglevel     vmlinux EXPORT_SYMBOL_GPL
+-0x1007becd    usbnet_set_msglevel     vmlinux EXPORT_SYMBOL_GPL
+-0xb9eb9d79    pm_generic_suspend      vmlinux EXPORT_SYMBOL_GPL
+-0xca860514    xfrm_state_lookup       vmlinux EXPORT_SYMBOL
+-0x795598eb    tcp_parse_options       vmlinux EXPORT_SYMBOL
+-0x17a3ce1e    rps_may_expire_flow     vmlinux EXPORT_SYMBOL
+-0x7b3d29ac    i2c_smbus_write_block_data      vmlinux EXPORT_SYMBOL
+-0x8164b1cc    ump_dd_handle_create_from_secure_id     vmlinux EXPORT_SYMBOL
+-0x7f04682a    of_gpio_simple_xlate    vmlinux EXPORT_SYMBOL
+-0xefd6cf06    __aeabi_unwind_cpp_pr0  vmlinux EXPORT_SYMBOL
+-0xb7ba76c7    __aeabi_unwind_cpp_pr2  vmlinux EXPORT_SYMBOL
+-0x43f0af31    snd_soc_codec_set_pll   vmlinux EXPORT_SYMBOL_GPL
+-0x6e46b07b    module_refcount vmlinux EXPORT_SYMBOL
+-0x455348d7    usb_composite_probe     vmlinux EXPORT_SYMBOL_GPL
+-0x0e8110c3    sec_reg_write   vmlinux EXPORT_SYMBOL_GPL
+-0xba0edce6    inet_ctl_sock_create    vmlinux EXPORT_SYMBOL_GPL
+-0x8454f899    dev_addr_add_multiple   vmlinux EXPORT_SYMBOL
+-0x62e4112b    _submit_bh      vmlinux EXPORT_SYMBOL_GPL
+-0x715622e2    handle_edge_irq vmlinux EXPORT_SYMBOL
+-0x0e639705    usbnet_link_change      vmlinux EXPORT_SYMBOL
+-0x8043eb8c    firmware_kobj   vmlinux EXPORT_SYMBOL_GPL
+-0x130bf78b    drm_mode_create_from_cmdline_mode       vmlinux EXPORT_SYMBOL
+-0xbdd37f04    usb_autopm_put_interface_async  vmlinux EXPORT_SYMBOL_GPL
+-0x63c46f03    usb_lock_device_for_reset       vmlinux EXPORT_SYMBOL_GPL
+-0x1bc5eebe    pinctrl_gpio_direction_input    vmlinux EXPORT_SYMBOL_GPL
+-0x519b061e    genl_register_mc_group  vmlinux EXPORT_SYMBOL
+-0xf81e0907    ___pskb_trim    vmlinux EXPORT_SYMBOL
+-0xd352e668    snd_timer_global_new    vmlinux EXPORT_SYMBOL
+-0x85df9b6c    strsep  vmlinux EXPORT_SYMBOL
+-0xe2d5255a    strcmp  vmlinux EXPORT_SYMBOL
+-0x788fe103    iomem_resource  vmlinux EXPORT_SYMBOL
+-0xe7a9a6a0    tty_driver_flush_buffer vmlinux EXPORT_SYMBOL
+-0xd648e564    fb_match_mode   vmlinux EXPORT_SYMBOL
+-0xbc10dd97    __put_user_4    vmlinux EXPORT_SYMBOL
+-0x353e3fa5    __get_user_4    vmlinux EXPORT_SYMBOL
+-0xe50ad8a8    snd_ctl_add     vmlinux EXPORT_SYMBOL
+-0x6323f87b    mnt_unpin       vmlinux EXPORT_SYMBOL
+-0xbb524006    vfs_create      vmlinux EXPORT_SYMBOL
+-0x2f47d8c7    cpufreq_frequency_get_table     vmlinux EXPORT_SYMBOL_GPL
+-0xda44cb37    setup_charger_manager   vmlinux EXPORT_SYMBOL_GPL
+-0x01ab74a6    devm_kfree      vmlinux EXPORT_SYMBOL_GPL
+-0x153be8a8    drm_fb_helper_pan_display       vmlinux EXPORT_SYMBOL
+-0xc676a007    __ablkcipher_walk_complete      vmlinux EXPORT_SYMBOL_GPL
+-0x868bf31d    sb_min_blocksize        vmlinux EXPORT_SYMBOL
+-0xaf5f7994    remove_conflicting_framebuffers vmlinux EXPORT_SYMBOL
+-0x49e5aa17    bt_procfs_init  vmlinux EXPORT_SYMBOL
+-0xf353a698    register_module_notifier        vmlinux EXPORT_SYMBOL
+-0x154c6338    dm_kcopyd_client_destroy        vmlinux EXPORT_SYMBOL
+-0xdd4cc94f    v4l2_device_set_name    vmlinux EXPORT_SYMBOL_GPL
+-0x703189d7    regulator_get_mode      vmlinux EXPORT_SYMBOL_GPL
+-0x43028a27    nfc_hci_result_to_errno vmlinux EXPORT_SYMBOL
+-0x0551f0ce    tick_nohz_idle_exit     vmlinux EXPORT_SYMBOL_GPL
+-0xc7208c3a    serial8250_resume_port  vmlinux EXPORT_SYMBOL
+-0xe91355f8    inet_csk_clone_lock     vmlinux EXPORT_SYMBOL_GPL
+-0xe912da6b    unregister_sysctl_table vmlinux EXPORT_SYMBOL
+-0xaf91d89f    __kernel_param_lock     vmlinux EXPORT_SYMBOL
+-0x31cdd70c    hid_input_report        vmlinux EXPORT_SYMBOL_GPL
+-0xd73ee981    cdc_ncm_fill_tx_frame   vmlinux EXPORT_SYMBOL_GPL
+-0xa01c6bfd    del_gendisk     vmlinux EXPORT_SYMBOL
+-0x4d74d134    block_write_full_page   vmlinux EXPORT_SYMBOL
+-0x43632d7d    of_find_property        vmlinux EXPORT_SYMBOL
+-0xa76550fa    xfrm_register_type      vmlinux EXPORT_SYMBOL
+-0xde08bdaf    nf_ct_invert_tuple      vmlinux EXPORT_SYMBOL_GPL
+-0xa61aa028    snd_pcm_format_unsigned vmlinux EXPORT_SYMBOL
+-0x0b51f3e2    fat_sync_inode  vmlinux EXPORT_SYMBOL_GPL
+-0xb3e441b1    clear_bdi_congested     vmlinux EXPORT_SYMBOL
+-0x9305f8e6    cpufreq_get     vmlinux EXPORT_SYMBOL
+-0x8708f581    usbnet_stop     vmlinux EXPORT_SYMBOL_GPL
+-0x581e0fb1    sock_no_setsockopt      vmlinux EXPORT_SYMBOL
+-0xdf40231d    sock_no_getsockopt      vmlinux EXPORT_SYMBOL
+-0xa3355ffa    snd_soc_default_writable_register       vmlinux EXPORT_SYMBOL_GPL
+-0xb8ba4a80    __blockdev_direct_IO    vmlinux EXPORT_SYMBOL
+-0x4f70015c    splice_from_pipe_end    vmlinux EXPORT_SYMBOL
+-0x93658a27    migrate_page    vmlinux EXPORT_SYMBOL
+-0x2e45e488    rcu_note_context_switch vmlinux EXPORT_SYMBOL_GPL
+-0xf0d68ed6    clk_register_clkdevs    vmlinux EXPORT_SYMBOL
+-0xec58fd46    ip6_route_me_harder     vmlinux EXPORT_SYMBOL
+-0xccec571a    thermal_zone_device_update      vmlinux EXPORT_SYMBOL_GPL
+-0x011c6bf0    regulator_map_voltage_iterate   vmlinux EXPORT_SYMBOL_GPL
+-0x44eabd85    km_new_mapping  vmlinux EXPORT_SYMBOL
+-0x4469fe89    lro_receive_skb vmlinux EXPORT_SYMBOL
+-0x6d54f969    napi_complete   vmlinux EXPORT_SYMBOL
+-0xb740018f    snd_device_new  vmlinux EXPORT_SYMBOL
+-0xab363caa    generic_block_bmap      vmlinux EXPORT_SYMBOL
+-0x868784cb    __symbol_get    vmlinux EXPORT_SYMBOL_GPL
+-0x142a8be4    of_clk_get_parent_name  vmlinux EXPORT_SYMBOL_GPL
+-0x991484c4    of_property_count_strings       vmlinux EXPORT_SYMBOL_GPL
+-0x5f3c8f5c    mmc_assume_removable    vmlinux EXPORT_SYMBOL
+-0xf9c1f53f    pm_generic_thaw_early   vmlinux EXPORT_SYMBOL_GPL
+-0x47229b5c    gpio_request    vmlinux EXPORT_SYMBOL_GPL
+-0x517deb22    __ip_dev_find   vmlinux EXPORT_SYMBOL
+-0x815fe221    snd_pcm_hw_constraint_list      vmlinux EXPORT_SYMBOL
+-0xbe0e5118    nla_memcmp      vmlinux EXPORT_SYMBOL
+-0xf1db1704    nla_memcpy      vmlinux EXPORT_SYMBOL
+-0x1f77b093    file_remove_suid        vmlinux EXPORT_SYMBOL
+-0xfd6794fe    d_materialise_unique    vmlinux EXPORT_SYMBOL_GPL
+-0x26622a2b    kmem_cache_free vmlinux EXPORT_SYMBOL
+-0x7aab19fb    vb2_ops_wait_prepare    vmlinux EXPORT_SYMBOL_GPL
+-0x5d22b406    rndis_register  vmlinux EXPORT_SYMBOL
+-0xd25dc9c5    cdc_ncm_rx_verify_nth16 vmlinux EXPORT_SYMBOL_GPL
+-0x8299a21a    ieee80211_data_from_8023        vmlinux EXPORT_SYMBOL
+-0x499cb58c    prepare_to_wait vmlinux EXPORT_SYMBOL
+-0xadf42bd5    __request_region        vmlinux EXPORT_SYMBOL
+-0x9f560253    get_cpu_device  vmlinux EXPORT_SYMBOL_GPL
+-0x923b1276    dmaengine_get   vmlinux EXPORT_SYMBOL
+-0x56d9b1de    amba_device_register    vmlinux EXPORT_SYMBOL
+-0x6fa16209    bdev_read_only  vmlinux EXPORT_SYMBOL
+-0xf0009fee    put_pages_list  vmlinux EXPORT_SYMBOL
+-0xdf73013e    from_kprojid    vmlinux EXPORT_SYMBOL
+-0x2609451c    sock_wfree      vmlinux EXPORT_SYMBOL
+-0x0de80eba    snd_soc_info_volsw      vmlinux EXPORT_SYMBOL_GPL
+-0xd7f77051    test_set_page_writeback vmlinux EXPORT_SYMBOL
+-0xa734a3e9    abort_exclusive_wait    vmlinux EXPORT_SYMBOL
+-0x091eb9b4    round_jiffies   vmlinux EXPORT_SYMBOL_GPL
+-0x99429b47    display_entity_unregister       vmlinux EXPORT_SYMBOL_GPL
+-0x40d0b751    qdisc_destroy   vmlinux EXPORT_SYMBOL
+-0x16445cb3    inet_proto_csum_replace16       vmlinux EXPORT_SYMBOL
+-0x5594be03    bitmap_remap    vmlinux EXPORT_SYMBOL
+-0x7fe04a49    truncate_inode_pages    vmlinux EXPORT_SYMBOL
+-0x42f865b4    fb_videomode_from_videomode     vmlinux EXPORT_SYMBOL_GPL
+-0x0422fe4a    inet_csk_timer_bug_msg  vmlinux EXPORT_SYMBOL
+-0x1b0c9510    sysfs_notify    vmlinux EXPORT_SYMBOL_GPL
+-0x0948cde9    num_physpages   vmlinux EXPORT_SYMBOL
+-0x7818fe23    input_flush_device      vmlinux EXPORT_SYMBOL
+-0x2da17677    regmap_bulk_write       vmlinux EXPORT_SYMBOL_GPL
+-0x03ba39b0    v7_flush_user_cache_all vmlinux EXPORT_SYMBOL
+-0x9d0403b2    inet_hash       vmlinux EXPORT_SYMBOL_GPL
+-0x9a1dfd65    strpbrk vmlinux EXPORT_SYMBOL
+-0xa040153b    sysfs_create_file       vmlinux EXPORT_SYMBOL_GPL
+-0x99cbae17    seq_lseek       vmlinux EXPORT_SYMBOL
+-0x092c2a7a    irq_domain_add_tree     vmlinux EXPORT_SYMBOL_GPL
+-0x23a42148    media_entity_pipeline_stop      vmlinux EXPORT_SYMBOL_GPL
+-0xd87b6687    ip6_frag_match  vmlinux EXPORT_SYMBOL
+-0x9e6d79f8    snd_info_get_str        vmlinux EXPORT_SYMBOL
+-0x1551dc51    bitmap_find_free_region vmlinux EXPORT_SYMBOL
+-0x9f491e5d    ftrace_print_symbols_seq_u64    vmlinux EXPORT_SYMBOL
+-0x9b6bedb6    sdhci_add_host  vmlinux EXPORT_SYMBOL_GPL
+-0x928f84b5    drm_crtc_init   vmlinux EXPORT_SYMBOL
+-0x56b63670    lzo1x_1_compress        vmlinux EXPORT_SYMBOL_GPL
+-0x637d3d6a    set_disk_ro     vmlinux EXPORT_SYMBOL
+-0x5053e2a6    leds_list_lock  vmlinux EXPORT_SYMBOL_GPL
+-0x19fc7f60    regulator_set_mode      vmlinux EXPORT_SYMBOL_GPL
+-0x7e703a3d    snd_soc_limit_volume    vmlinux EXPORT_SYMBOL_GPL
+-0x3bdbf275    sg_alloc_table_from_pages       vmlinux EXPORT_SYMBOL
+-0xb87bf605    blk_rq_unprep_clone     vmlinux EXPORT_SYMBOL_GPL
+-0xe04f7caa    dm_read_arg_group       vmlinux EXPORT_SYMBOL
+-0xb26725f8    bus_find_device vmlinux EXPORT_SYMBOL_GPL
+-0x7ff32312    drm_gem_handle_create   vmlinux EXPORT_SYMBOL
+-0xcd7edbe9    cfg80211_sched_scan_results     vmlinux EXPORT_SYMBOL
+-0x92dbc6c1    xfrm_aalg_get_byid      vmlinux EXPORT_SYMBOL_GPL
+-0x6fb14f17    tcp_create_openreq_child        vmlinux EXPORT_SYMBOL
+-0x2f368d4c    sk_common_release       vmlinux EXPORT_SYMBOL
+-0xd60281a9    st_sensors_set_fullscale_by_gain        vmlinux EXPORT_SYMBOL
+-0x228bec81    led_trigger_register    vmlinux EXPORT_SYMBOL_GPL
+-0x28c52e3f    video_device_release    vmlinux EXPORT_SYMBOL
+-0x3faac56f    drm_mode_set_config_internal    vmlinux EXPORT_SYMBOL
+-0xf86d3493    skb_queue_head  vmlinux EXPORT_SYMBOL
+-0x5fd1e756    skb_prepare_seq_read    vmlinux EXPORT_SYMBOL
+-0x02ff8c3e    sk_reset_timer  vmlinux EXPORT_SYMBOL
+-0xb08f47ec    snd_soc_resume  vmlinux EXPORT_SYMBOL_GPL
+-0x0f055dad    snd_pcm_hw_rule_noresample      vmlinux EXPORT_SYMBOL
+-0x9529f10a    fuse_conn_put   vmlinux EXPORT_SYMBOL_GPL
+-0xf6bb8bf1    irq_get_irq_data        vmlinux EXPORT_SYMBOL_GPL
+-0x02c3c736    v4l2_subdev_querymenu   vmlinux EXPORT_SYMBOL
+-0xfb42deb3    drm_helper_mode_fill_fb_struct  vmlinux EXPORT_SYMBOL
+-0x4920a692    regulator_bulk_enable   vmlinux EXPORT_SYMBOL_GPL
+-0x85963907    netdev_has_upper_dev    vmlinux EXPORT_SYMBOL
+-0x5f58f676    flex_array_get_ptr      vmlinux EXPORT_SYMBOL
+-0x3e6c012e    bio_alloc_bioset        vmlinux EXPORT_SYMBOL
+-0xb9ac0503    mali_set_user_setting   vmlinux EXPORT_SYMBOL
+-0xbd22a332    drm_pci_free    vmlinux EXPORT_SYMBOL
+-0x171addd2    ieee80211_get_hdrlen_from_skb   vmlinux EXPORT_SYMBOL
+-0xe41115b7    vfs_cancel_lock vmlinux EXPORT_SYMBOL_GPL
+-0x912c123d    pm_qos_remove_request   vmlinux EXPORT_SYMBOL_GPL
+-0x8e2d17cc    v4l2_clk_enable vmlinux EXPORT_SYMBOL
+-0xfe3150df    usb_driver_set_configuration    vmlinux EXPORT_SYMBOL_GPL
+-0x3b5bb4f2    mii_ethtool_sset        vmlinux EXPORT_SYMBOL
+-0xe9bc24c2    mii_ethtool_gset        vmlinux EXPORT_SYMBOL
+-0x62e1f48d    class_compat_create_link        vmlinux EXPORT_SYMBOL_GPL
+-0xb602c57e    nf_ct_l3proto_module_put        vmlinux EXPORT_SYMBOL_GPL
+-0xcd4b940c    release_sock    vmlinux EXPORT_SYMBOL
+-0x90e5450f    textsearch_destroy      vmlinux EXPORT_SYMBOL
+-0x50e7193a    __i2c_first_dynamic_bus_num     vmlinux EXPORT_SYMBOL_GPL
+-0xa2a8e81f    class_remove_file       vmlinux EXPORT_SYMBOL_GPL
+-0x95f56edb    drm_i2c_encoder_init    vmlinux EXPORT_SYMBOL
+-0xdd1dd3a7    snd_pcm_hw_constraint_msbits    vmlinux EXPORT_SYMBOL
+-0x23a574fd    security_secmark_relabel_packet vmlinux EXPORT_SYMBOL
+-0x3f01eca9    unmap_underlying_metadata       vmlinux EXPORT_SYMBOL
+-0x55feec9e    sync_inode      vmlinux EXPORT_SYMBOL
+-0xb859f38b    krealloc        vmlinux EXPORT_SYMBOL
+-0x9af5fc30    of_phy_connect_fixed_link       vmlinux EXPORT_SYMBOL
+-0xa2307653    v4l2_device_register_subdev_nodes       vmlinux EXPORT_SYMBOL_GPL
+-0x66e9dc03    usbnet_status_stop      vmlinux EXPORT_SYMBOL_GPL
+-0x419a9395    snd_card_create vmlinux EXPORT_SYMBOL
+-0x9edc4cdb    __invalidate_device     vmlinux EXPORT_SYMBOL
+-0x301fa826    seq_put_decimal_ull     vmlinux EXPORT_SYMBOL
+-0x8f7b5061    jack_event_handler      vmlinux EXPORT_SYMBOL_GPL
+-0xf8e6aed1    input_register_device   vmlinux EXPORT_SYMBOL
+-0xfba9b108    drm_fb_helper_fini      vmlinux EXPORT_SYMBOL
+-0x31266931    con_debug_leave vmlinux EXPORT_SYMBOL_GPL
+-0x2ba707a8    sysctl_tcp_low_latency  vmlinux EXPORT_SYMBOL
+-0x1163f0a7    blk_max_low_pfn vmlinux EXPORT_SYMBOL
+-0x94c6b808    blk_queue_free_tags     vmlinux EXPORT_SYMBOL
+-0xe0413655    elv_unregister_queue    vmlinux EXPORT_SYMBOL
+-0x3fab3ca9    register_sysctl_table   vmlinux EXPORT_SYMBOL
+-0x67b78eb3    seq_hlist_next_rcu      vmlinux EXPORT_SYMBOL
+-0x571767e3    led_classdev_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x9323826a    ipv4_redirect   vmlinux EXPORT_SYMBOL_GPL
+-0x495c96f8    posix_acl_init  vmlinux EXPORT_SYMBOL
+-0xd59c42a1    drm_idlelock_release    vmlinux EXPORT_SYMBOL
+-0x490355ba    tty_flip_buffer_push    vmlinux EXPORT_SYMBOL
+-0x3ef6c408    bio_copy_data   vmlinux EXPORT_SYMBOL
+-0x6fe3d8cf    ktime_add_safe  vmlinux EXPORT_SYMBOL_GPL
+-0xf9a482f9    msleep  vmlinux EXPORT_SYMBOL
+-0xc66b77b1    iommu_group_set_iommudata       vmlinux EXPORT_SYMBOL_GPL
+-0xd55ad93b    iommu_group_get_iommudata       vmlinux EXPORT_SYMBOL_GPL
+-0x0d0549e1    hidinput_calc_abs_res   vmlinux EXPORT_SYMBOL_GPL
+-0x07608656    uart_get_divisor        vmlinux EXPORT_SYMBOL
+-0xc8f72480    unregister_netdev       vmlinux EXPORT_SYMBOL
+-0x1ce42553    __bforget       vmlinux EXPORT_SYMBOL
+-0x8427e5bd    v4l2_event_subdev_unsubscribe   vmlinux EXPORT_SYMBOL_GPL
+-0x8e865d3c    arm_delay_ops   vmlinux EXPORT_SYMBOL
+-0x2f88c16b    inet6_add_protocol      vmlinux EXPORT_SYMBOL
+-0x9fda569e    raw_unhash_sk   vmlinux EXPORT_SYMBOL_GPL
+-0x1def6812    xt_register_table       vmlinux EXPORT_SYMBOL_GPL
+-0xe7e87d7a    set_h225_addr_hook      vmlinux EXPORT_SYMBOL_GPL
+-0xd2037371    sock_no_listen  vmlinux EXPORT_SYMBOL
+-0x33607e14    snd_soc_poweroff        vmlinux EXPORT_SYMBOL_GPL
+-0xab600421    probe_irq_off   vmlinux EXPORT_SYMBOL
+-0xfc8ace2f    input_mt_destroy_slots  vmlinux EXPORT_SYMBOL
+-0xf222f80f    usb_unpoison_anchored_urbs      vmlinux EXPORT_SYMBOL_GPL
+-0x4845cdbc    scsi_device_lookup_by_target    vmlinux EXPORT_SYMBOL
+-0x79aa04a2    get_random_bytes        vmlinux EXPORT_SYMBOL
+-0x9db44776    nfc_hci_connect_gate    vmlinux EXPORT_SYMBOL
+-0x4d2726f3    tcf_exts_destroy        vmlinux EXPORT_SYMBOL
+-0xbaa8249a    snd_ctl_activate_id     vmlinux EXPORT_SYMBOL_GPL
+-0x55ef85b4    blk_peek_request        vmlinux EXPORT_SYMBOL
+-0xc8b267ae    seq_vprintf     vmlinux EXPORT_SYMBOL
+-0xe6504df3    sdhci_get_of_property   vmlinux EXPORT_SYMBOL_GPL
+-0x3ad12077    regcache_sync_region    vmlinux EXPORT_SYMBOL_GPL
+-0x80af255f    pm_runtime_allow        vmlinux EXPORT_SYMBOL_GPL
+-0x16105b8e    do_unbind_con_driver    vmlinux EXPORT_SYMBOL_GPL
+-0xdaf4dfb3    fb_mode_option  vmlinux EXPORT_SYMBOL_GPL
+-0x1f5dd478    tcf_hash_lookup vmlinux EXPORT_SYMBOL
+-0x14965155    sock_no_poll    vmlinux EXPORT_SYMBOL
+-0xfcbe775e    blk_rq_prep_clone       vmlinux EXPORT_SYMBOL_GPL
+-0x53e6cd86    crypto_alloc_shash      vmlinux EXPORT_SYMBOL_GPL
+-0x93f84c0c    crypto_alloc_ahash      vmlinux EXPORT_SYMBOL_GPL
+-0xae1d4afd    sdio_unregister_driver  vmlinux EXPORT_SYMBOL_GPL
+-0x1b50682a    drm_mode_connector_attach_encoder       vmlinux EXPORT_SYMBOL
+-0x78bed30e    regulator_get   vmlinux EXPORT_SYMBOL_GPL
+-0xae4e6d07    inet6_register_icmp_sender      vmlinux EXPORT_SYMBOL
+-0xcd67300d    vlan_ioctl_set  vmlinux EXPORT_SYMBOL
+-0x4d9b6d35    snd_pcm_format_size     vmlinux EXPORT_SYMBOL
+-0xc11d8093    iov_shorten     vmlinux EXPORT_SYMBOL
+-0x6a037cf1    mempool_kfree   vmlinux EXPORT_SYMBOL
+-0x0cebb5a5    __ww_mutex_lock vmlinux EXPORT_SYMBOL
+-0x430e5257    of_alias_get_id vmlinux EXPORT_SYMBOL_GPL
+-0x5d9260a1    v4l2_ctrl_activate      vmlinux EXPORT_SYMBOL
+-0x17622c01    display_entity_set_state        vmlinux EXPORT_SYMBOL_GPL
+-0x26adb815    thread_notify_head      vmlinux EXPORT_SYMBOL_GPL
+-0xf0ef15b4    list_sort       vmlinux EXPORT_SYMBOL
+-0x958974d4    remove_arg_zero vmlinux EXPORT_SYMBOL
+-0x7b5c8440    vm_munmap       vmlinux EXPORT_SYMBOL
+-0x46178343    remap_pfn_range vmlinux EXPORT_SYMBOL
+-0x46608fa0    getnstimeofday  vmlinux EXPORT_SYMBOL
+-0x51a049e1    scsi_scan_target        vmlinux EXPORT_SYMBOL
+-0x61b31a8a    subsys_dev_iter_init    vmlinux EXPORT_SYMBOL_GPL
+-0x054aade6    subsys_dev_iter_exit    vmlinux EXPORT_SYMBOL_GPL
+-0x4099164a    skcipher_geniv_exit     vmlinux EXPORT_SYMBOL_GPL
+-0x9c144793    file_update_time        vmlinux EXPORT_SYMBOL
+-0x8a162c7d    bdi_unregister  vmlinux EXPORT_SYMBOL
+-0x755d68eb    iio_enum_read   vmlinux EXPORT_SYMBOL_GPL
+-0x03e593b9    vb2_wait_for_all_buffers        vmlinux EXPORT_SYMBOL_GPL
+-0xc06a30a4    phy_register_fixup      vmlinux EXPORT_SYMBOL
+-0x3c308a26    device_bind_driver      vmlinux EXPORT_SYMBOL_GPL
+-0x55010072    device_store_ulong      vmlinux EXPORT_SYMBOL_GPL
+-0x0b405d40    inet6_csk_search_req    vmlinux EXPORT_SYMBOL_GPL
+-0x7a1acc62    dev_mc_init     vmlinux EXPORT_SYMBOL
+-0x93fcc9bd    dev_uc_init     vmlinux EXPORT_SYMBOL
+-0x865029ac    __hw_addr_sync  vmlinux EXPORT_SYMBOL
+-0xb04359d9    snd_soc_bytes_info      vmlinux EXPORT_SYMBOL_GPL
+-0x11a13e31    _kstrtol        vmlinux EXPORT_SYMBOL
+-0x6e73746d    kobject_uevent_env      vmlinux EXPORT_SYMBOL_GPL
+-0x7d830ea5    mb_cache_entry_alloc    vmlinux EXPORT_SYMBOL
+-0xd702e480    _raw_read_unlock        vmlinux EXPORT_SYMBOL
+-0xfa2bcf10    init_timer_key  vmlinux EXPORT_SYMBOL
+-0xe03525ac    of_irq_map_raw  vmlinux EXPORT_SYMBOL_GPL
+-0xb39171d5    cdc_ncm_select_altsetting       vmlinux EXPORT_SYMBOL_GPL
+-0xec52c42e    scsi_setup_blk_pc_cmnd  vmlinux EXPORT_SYMBOL
+-0x337cce46    put_cmsg        vmlinux EXPORT_SYMBOL
+-0x655656dc    skb_free_datagram       vmlinux EXPORT_SYMBOL
+-0x2ad0e68c    sound_class     vmlinux EXPORT_SYMBOL
+-0x7a98596c    filp_close      vmlinux EXPORT_SYMBOL
+-0x4c39b01b    truncate_setsize        vmlinux EXPORT_SYMBOL
+-0xfd5683b9    wait_for_completion_interruptible       vmlinux EXPORT_SYMBOL
+-0xfc38a837    extcon_update_state     vmlinux EXPORT_SYMBOL_GPL
+-0xdba80fc1    of_fdt_unflatten_tree   vmlinux EXPORT_SYMBOL_GPL
+-0x3be54580    generic_readlink        vmlinux EXPORT_SYMBOL
+-0x6cee2e42    drm_object_property_get_value   vmlinux EXPORT_SYMBOL
+-0x67b27ec1    tty_std_termios vmlinux EXPORT_SYMBOL
+-0x4298b775    v7_flush_kern_cache_all vmlinux EXPORT_SYMBOL
+-0x66ac9af0    ether_setup     vmlinux EXPORT_SYMBOL
+-0xafb2d50e    __break_lease   vmlinux EXPORT_SYMBOL
+-0x9e6500de    get_task_comm   vmlinux EXPORT_SYMBOL_GPL
+-0xd5df9165    __get_vm_area   vmlinux EXPORT_SYMBOL_GPL
+-0x6b7589f4    param_set_bool  vmlinux EXPORT_SYMBOL
+-0xbfc407b4    param_ops_bint  vmlinux EXPORT_SYMBOL
+-0xadb5559d    param_ops_byte  vmlinux EXPORT_SYMBOL
+-0xd2a3a2e7    usb_deregister_device_driver    vmlinux EXPORT_SYMBOL_GPL
+-0x0264e273    usbnet_nway_reset       vmlinux EXPORT_SYMBOL_GPL
+-0xbc31af43    device_create_file      vmlinux EXPORT_SYMBOL_GPL
+-0x34bb0082    snd_soc_dapm_put_volsw  vmlinux EXPORT_SYMBOL_GPL
+-0xcec0e354    snd_soc_dapm_get_volsw  vmlinux EXPORT_SYMBOL_GPL
+-0xa3d6bc8a    would_dump      vmlinux EXPORT_SYMBOL
+-0x782cd0c9    truncate_inode_pages_range      vmlinux EXPORT_SYMBOL
+-0xefc7de8e    force_sig       vmlinux EXPORT_SYMBOL
+-0xb3b30554    fimc_find_remote_sensor vmlinux EXPORT_SYMBOL
+-0xf3be20f4    v4l2_m2m_querybuf       vmlinux EXPORT_SYMBOL_GPL
+-0x0fccafb1    drm_global_item_unref   vmlinux EXPORT_SYMBOL
+-0xe8d24f74    arm_coherent_dma_ops    vmlinux EXPORT_SYMBOL
+-0x05240ee7    percpu_counter_batch    vmlinux EXPORT_SYMBOL
+-0x5d75cd76    d_path  vmlinux EXPORT_SYMBOL
+-0x495426ee    v4l2_ctrl_get_name      vmlinux EXPORT_SYMBOL
+-0x6e89a560    regmap_irq_chip_get_base        vmlinux EXPORT_SYMBOL_GPL
+-0x587616f1    vfs_fstatat     vmlinux EXPORT_SYMBOL
+-0x162ccc0c    lg_local_lock   vmlinux EXPORT_SYMBOL
+-0x498225b6    v4l2_m2m_expbuf vmlinux EXPORT_SYMBOL_GPL
+-0x21b2c1ab    __pm_genpd_remove_callbacks     vmlinux EXPORT_SYMBOL_GPL
+-0x1516aa21    brcmf_sdio_probe        drivers/net/wireless/brcm80211/brcmfmac/brcmfmac        EXPORT_SYMBOL
+-0x36c61868    hci_free_dev    vmlinux EXPORT_SYMBOL
+-0xcfa46265    igrab   vmlinux EXPORT_SYMBOL
+-0x36150611    iio_validate_scan_mask_onehot   vmlinux EXPORT_SYMBOL_GPL
+-0x01ac01fc    usbnet_resume   vmlinux EXPORT_SYMBOL_GPL
+-0x43421b4f    sdev_evt_send   vmlinux EXPORT_SYMBOL_GPL
+-0x1fdcc615    rtnl_notify     vmlinux EXPORT_SYMBOL
+-0xe4ad075c    __rtnl_link_register    vmlinux EXPORT_SYMBOL_GPL
+-0x41366c3b    sock_recvmsg    vmlinux EXPORT_SYMBOL
+-0x3468cb4a    snd_soc_set_runtime_hwparams    vmlinux EXPORT_SYMBOL_GPL
+-0x308e4695    snd_pcm_open_substream  vmlinux EXPORT_SYMBOL
+-0x2ef9dbdc    blk_end_request_err     vmlinux EXPORT_SYMBOL_GPL
+-0x9b11d9bf    blk_end_request_all     vmlinux EXPORT_SYMBOL
+-0x2f5bf998    blk_queue_bio   vmlinux EXPORT_SYMBOL_GPL
+-0xd16712f3    crypto_check_attr_type  vmlinux EXPORT_SYMBOL_GPL
+-0x16305289    warn_slowpath_null      vmlinux EXPORT_SYMBOL
+-0xcb0288ea    ledtrig_cpu     vmlinux EXPORT_SYMBOL
+-0xe6431c3b    mmc_can_secure_erase_trim       vmlinux EXPORT_SYMBOL
+-0x916dbe7c    usb_hcd_unmap_urb_for_dma       vmlinux EXPORT_SYMBOL_GPL
+-0x8dc2569e    nf_ct_l3protos  vmlinux EXPORT_SYMBOL_GPL
+-0x1471e34e    linkwatch_fire_event    vmlinux EXPORT_SYMBOL
+-0x56db40e5    snd_device_free vmlinux EXPORT_SYMBOL
+-0xe1b524a3    fs_bio_set      vmlinux EXPORT_SYMBOL
+-0x8d522714    __rcu_read_lock vmlinux EXPORT_SYMBOL_GPL
+-0x4906a967    hid_snto32      vmlinux EXPORT_SYMBOL_GPL
+-0xfbf6bb67    watchdog_init_timeout   vmlinux EXPORT_SYMBOL_GPL
+-0xd37e13b4    regulator_set_optimum_mode      vmlinux EXPORT_SYMBOL_GPL
+-0x4fe1eddf    unregister_netevent_notifier    vmlinux EXPORT_SYMBOL_GPL
+-0x66af941c    snd_soc_debugfs_root    vmlinux EXPORT_SYMBOL_GPL
+-0x42c43759    input_mt_report_slot_state      vmlinux EXPORT_SYMBOL
+-0x8fccb56f    scsi_init_io    vmlinux EXPORT_SYMBOL
+-0x375fce7f    asoc_dma_platform_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0xa58dee99    _raw_write_unlock       vmlinux EXPORT_SYMBOL
+-0x252efd1e    sdhci_remove_host       vmlinux EXPORT_SYMBOL_GPL
+-0xb5128e67    v4l2_i2c_subdev_init    vmlinux EXPORT_SYMBOL_GPL
+-0x6d680e52    v4l2_i2c_subdev_addr    vmlinux EXPORT_SYMBOL_GPL
+-0xb56fc02f    fib_default_rule_pref   vmlinux EXPORT_SYMBOL
+-0x97359c5f    snd_pcm_period_elapsed  vmlinux EXPORT_SYMBOL
+-0x3df477d7    debugfs_create_x8       vmlinux EXPORT_SYMBOL_GPL
+-0x314d3160    kmap_to_page    vmlinux EXPORT_SYMBOL
+-0x8afbf7b1    irq_domain_xlate_onecell        vmlinux EXPORT_SYMBOL_GPL
+-0x6b264960    irq_domain_xlate_twocell        vmlinux EXPORT_SYMBOL_GPL
+-0xee3c209d    cgroup_next_descendant_pre      vmlinux EXPORT_SYMBOL_GPL
+-0x6776c27a    drm_av_sync_delay       vmlinux EXPORT_SYMBOL
+-0x0fe112dc    of_dma_controller_free  vmlinux EXPORT_SYMBOL_GPL
+-0xfccc95e9    pwm_put vmlinux EXPORT_SYMBOL_GPL
+-0xb8a5a2d7    iio_convert_raw_to_processed    vmlinux EXPORT_SYMBOL_GPL
+-0x8f7df3a7    drm_object_attach_property      vmlinux EXPORT_SYMBOL
+-0xd248fe40    uart_write_wakeup       vmlinux EXPORT_SYMBOL
+-0x0483a4c2    skb_append      vmlinux EXPORT_SYMBOL
+-0xb28d7c56    snd_soc_read    vmlinux EXPORT_SYMBOL_GPL
+-0x6f1f9555    read_cache_page_gfp     vmlinux EXPORT_SYMBOL
+-0xe12954af    pwm_can_sleep   vmlinux EXPORT_SYMBOL_GPL
+-0x333147c5    sk_stream_error vmlinux EXPORT_SYMBOL
+-0x37f30c3d    devm_request_and_ioremap        vmlinux EXPORT_SYMBOL
+-0x40d57aa3    audit_log_start vmlinux EXPORT_SYMBOL
+-0x3232306b    need_load_eval  vmlinux EXPORT_SYMBOL_GPL
+-0x27328cec    drm_fb_helper_debug_leave       vmlinux EXPORT_SYMBOL
+-0x2f4df599    arm_iommu_attach_device vmlinux EXPORT_SYMBOL_GPL
+-0x38ec6320    netdev_crit     vmlinux EXPORT_SYMBOL
+-0x7385ebdb    sysfs_create_files      vmlinux EXPORT_SYMBOL_GPL
+-0x0758ff61    sget    vmlinux EXPORT_SYMBOL
+-0xca20d111    v4l2_ctrl_cluster       vmlinux EXPORT_SYMBOL
+-0x5f754e5a    memset  vmlinux EXPORT_SYMBOL
+-0xbd70447e    ip_tunnel_setup vmlinux EXPORT_SYMBOL_GPL
+-0x2541a979    snd_soc_calc_frame_size vmlinux EXPORT_SYMBOL_GPL
+-0xdc3fcbc9    __sw_hweight8   vmlinux EXPORT_SYMBOL
+-0x02ee26c1    free_pages_exact        vmlinux EXPORT_SYMBOL
+-0x885bcec8    tasklet_hrtimer_init    vmlinux EXPORT_SYMBOL_GPL
+-0xe80bbfc6    v4l2_event_pending      vmlinux EXPORT_SYMBOL_GPL
+-0x356cb8d3    debugfs_create_atomic_t vmlinux EXPORT_SYMBOL_GPL
+-0x064db9a5    mark_mounts_for_expiry  vmlinux EXPORT_SYMBOL_GPL
+-0x8b43159b    register_cpu_notifier   vmlinux EXPORT_SYMBOL
+-0xd0d5f859    st_sensors_read_event_config    vmlinux EXPORT_SYMBOL
+-0xba490602    nci_to_errno    vmlinux EXPORT_SYMBOL
+-0x26cae22e    snd_soc_dapm_free       vmlinux EXPORT_SYMBOL_GPL
+-0x6b4f9016    d_set_d_op      vmlinux EXPORT_SYMBOL
+-0x6d340f64    tty_termios_input_baud_rate     vmlinux EXPORT_SYMBOL
+-0x0d3f57a2    _find_next_bit_le       vmlinux EXPORT_SYMBOL
+-0x74e1a843    xfrm_aalg_get_byidx     vmlinux EXPORT_SYMBOL_GPL
+-0x56b147ce    unregister_tcf_proto_ops        vmlinux EXPORT_SYMBOL
+-0xb6936ffe    _bcd2bin        vmlinux EXPORT_SYMBOL
+-0x707f5f40    vb2_fop_write   vmlinux EXPORT_SYMBOL_GPL
+-0x598cd828    udp_table       vmlinux EXPORT_SYMBOL
+-0x7d0e3e72    ida_get_new_above       vmlinux EXPORT_SYMBOL
+-0x2e2f1740    ring_buffer_record_disable_cpu  vmlinux EXPORT_SYMBOL_GPL
+-0xafe38346    mmc_erase_group_aligned vmlinux EXPORT_SYMBOL
+-0x1af8e94b    nla_put vmlinux EXPORT_SYMBOL
+-0xf23fcb99    __kfifo_in      vmlinux EXPORT_SYMBOL
+-0xf8ac3a16    revalidate_disk vmlinux EXPORT_SYMBOL
+-0xca5967e3    vm_stat vmlinux EXPORT_SYMBOL
+-0xd5b1376d    register_shrinker       vmlinux EXPORT_SYMBOL
+-0xa6c3a59e    power_supply_am_i_supplied      vmlinux EXPORT_SYMBOL_GPL
+-0x35aa9322    regcache_mark_dirty     vmlinux EXPORT_SYMBOL_GPL
+-0xbdb14b0b    transport_configure_device      vmlinux EXPORT_SYMBOL_GPL
+-0x391c8c77    drm_bl_register vmlinux EXPORT_SYMBOL_GPL
+-0x2c744386    ip_tunnel_dellink       vmlinux EXPORT_SYMBOL_GPL
+-0xc10022a2    register_sound_dsp      vmlinux EXPORT_SYMBOL
+-0x6d29349e    blk_post_runtime_suspend        vmlinux EXPORT_SYMBOL
+-0x803eda06    block_invalidatepage    vmlinux EXPORT_SYMBOL
+-0x22ba7f9f    may_umount_tree vmlinux EXPORT_SYMBOL
+-0x7a944007    rcu_idle_enter  vmlinux EXPORT_SYMBOL_GPL
+-0x3ce3f899    iio_device_register     vmlinux EXPORT_SYMBOL
+-0x624a6406    hwrng_register  vmlinux EXPORT_SYMBOL_GPL
+-0xa408cd5e    misc_register   vmlinux EXPORT_SYMBOL
+-0x636b12c8    nf_nat_need_gre vmlinux EXPORT_SYMBOL_GPL
+-0xe58ab676    ip_tunnel_init_net      vmlinux EXPORT_SYMBOL_GPL
+-0x38c6e66b    udp_lib_get_port        vmlinux EXPORT_SYMBOL
+-0x7cda3781    ip_route_input_noref    vmlinux EXPORT_SYMBOL
+-0x207ffd0a    kernel_write    vmlinux EXPORT_SYMBOL
+-0xbbabb724    tty_ldisc_ref   vmlinux EXPORT_SYMBOL_GPL
+-0x899a5d37    rtnl_af_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0x1c7f08a9    snd_soc_dapm_del_routes vmlinux EXPORT_SYMBOL_GPL
+-0xe71105e8    iget_failed     vmlinux EXPORT_SYMBOL
+-0x0fc01e9f    static_key_slow_inc     vmlinux EXPORT_SYMBOL_GPL
+-0xbfee3ad5    loop_unregister_transfer        vmlinux EXPORT_SYMBOL
+-0xaaef0fd2    class_dev_iter_exit     vmlinux EXPORT_SYMBOL_GPL
+-0xd2b18e1d    __of_phy_provider_register      vmlinux EXPORT_SYMBOL_GPL
+-0x1751de15    phy_create      vmlinux EXPORT_SYMBOL_GPL
+-0x25c677c4    mac_pton        vmlinux EXPORT_SYMBOL
+-0xc54cd128    filemap_fdatawait_range vmlinux EXPORT_SYMBOL
+-0x05afc379    mmc_cache_ctrl  vmlinux EXPORT_SYMBOL
+-0x814e4cf8    cfg80211_chandef_usable vmlinux EXPORT_SYMBOL
+-0x829865cd    inode_sub_bytes vmlinux EXPORT_SYMBOL
+-0xec602814    inode_set_bytes vmlinux EXPORT_SYMBOL
+-0x47e70229    v7_flush_user_cache_range       vmlinux EXPORT_SYMBOL
+-0x51cb6360    arp_xmit        vmlinux EXPORT_SYMBOL
+-0xc84ab6f8    __dev_getfirstbyhwtype  vmlinux EXPORT_SYMBOL
+-0xd499d564    __dev_get_by_index      vmlinux EXPORT_SYMBOL
+-0x66a67dab    flex_array_shrink       vmlinux EXPORT_SYMBOL
+-0xd41fe818    _raw_read_unlock_irqrestore     vmlinux EXPORT_SYMBOL
+-0x47fdbc4f    v4l2_ctrl_new_std       vmlinux EXPORT_SYMBOL
+-0xb2fe3cab    mdiobus_register        vmlinux EXPORT_SYMBOL
+-0xf70d473a    __inet6_lookup_established      vmlinux EXPORT_SYMBOL
+-0x8187321e    snd_timer_interrupt     vmlinux EXPORT_SYMBOL
+-0xec5d6a71    __nla_put_nohdr vmlinux EXPORT_SYMBOL
+-0xda5506a3    crypto_unregister_instance      vmlinux EXPORT_SYMBOL_GPL
+-0xfd361609    bdi_init        vmlinux EXPORT_SYMBOL
+-0xf8d88cd8    clk_get vmlinux EXPORT_SYMBOL
+-0x22df2dd3    sdio_claim_host vmlinux EXPORT_SYMBOL_GPL
+-0x40973662    sysctl_udp_mem  vmlinux EXPORT_SYMBOL
+-0x3b50ba06    cpufreq_cooling_register        vmlinux EXPORT_SYMBOL_GPL
+-0xb1c29e91    usbnet_probe    vmlinux EXPORT_SYMBOL_GPL
+-0x5e1176a3    nfc_hci_send_cmd        vmlinux EXPORT_SYMBOL
+-0x1bc8ce1b    inet_csk_accept vmlinux EXPORT_SYMBOL
+-0x35cdd9d0    inet_hash_connect       vmlinux EXPORT_SYMBOL_GPL
+-0x0334da4e    scsi_command_size_tbl   vmlinux EXPORT_SYMBOL
+-0xa843805a    get_unused_fd_flags     vmlinux EXPORT_SYMBOL
+-0xb1e25684    __trace_bputs   vmlinux EXPORT_SYMBOL_GPL
+-0xb58dcfa2    synchronize_sched_expedited     vmlinux EXPORT_SYMBOL_GPL
+-0x17cefda4    cpufreq_cooling_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0xc6fca5ad    v4l2_m2m_release        vmlinux EXPORT_SYMBOL_GPL
+-0x0614dd5a    v4l2_video_std_frame_period     vmlinux EXPORT_SYMBOL
+-0x08195a4e    generic_mii_ioctl       vmlinux EXPORT_SYMBOL
+-0xe64e4a5b    drm_select_eld  vmlinux EXPORT_SYMBOL
+-0xa3b4f14d    bt_accept_dequeue       vmlinux EXPORT_SYMBOL
+-0x8e20620c    tcf_unregister_action   vmlinux EXPORT_SYMBOL
+-0x52026cdf    security_sb_parse_opts_str      vmlinux EXPORT_SYMBOL
+-0xe82c33bd    usb_bulk_msg    vmlinux EXPORT_SYMBOL_GPL
+-0x876abdb2    xfrm_state_delete_tunnel        vmlinux EXPORT_SYMBOL
+-0xfdb4778c    sock_edemux     vmlinux EXPORT_SYMBOL
+-0x4688d7ec    pvclock_gtod_unregister_notifier        vmlinux EXPORT_SYMBOL_GPL
+-0xc6b72634    gserial_connect vmlinux EXPORT_SYMBOL_GPL
+-0x55046eb2    platform_device_add_resources   vmlinux EXPORT_SYMBOL_GPL
+-0x1b25d2b3    of_pwm_xlate_with_flags vmlinux EXPORT_SYMBOL_GPL
+-0x6e1ba077    in6_dev_finish_destroy  vmlinux EXPORT_SYMBOL
+-0xecd68a44    tcp_gro_receive vmlinux EXPORT_SYMBOL
+-0x922e5568    eth_header      vmlinux EXPORT_SYMBOL
+-0xf82ec573    rb_prev vmlinux EXPORT_SYMBOL
+-0xfe2f7b7e    jbd2_journal_init_dev   vmlinux EXPORT_SYMBOL
+-0xd4114894    bd_unlink_disk_holder   vmlinux EXPORT_SYMBOL_GPL
+-0xa9e18049    task_handoff_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x4b5366cf    down_killable   vmlinux EXPORT_SYMBOL
+-0x1129616d    scsi_rescan_device      vmlinux EXPORT_SYMBOL
+-0x9ed554b3    unregister_keyboard_notifier    vmlinux EXPORT_SYMBOL_GPL
+-0x3271e6e4    unregister_framebuffer  vmlinux EXPORT_SYMBOL
+-0x4acb9a7c    napi_gro_receive        vmlinux EXPORT_SYMBOL
+-0x38ed4ee7    netdev_master_upper_dev_get_rcu vmlinux EXPORT_SYMBOL
+-0x5ae87753    debugfs_print_regs32    vmlinux EXPORT_SYMBOL_GPL
+-0xeac5a47a    clk_notifier_register   vmlinux EXPORT_SYMBOL_GPL
+-0xdcc389f7    usb_get_phy     vmlinux EXPORT_SYMBOL_GPL
+-0x5cfbd179    phonet_stream_ops       vmlinux EXPORT_SYMBOL
+-0xd7ea7094    nf_unregister_queue_handler     vmlinux EXPORT_SYMBOL
+-0xa9b804f6    snd_soc_dapm_ignore_suspend     vmlinux EXPORT_SYMBOL_GPL
+-0xb04cf0fe    lg_local_unlock vmlinux EXPORT_SYMBOL
+-0x24eb7e32    leds_list       vmlinux EXPORT_SYMBOL_GPL
+-0xb2f2f502    dev_get_by_flags_rcu    vmlinux EXPORT_SYMBOL
+-0x996bdb64    _kstrtoul       vmlinux EXPORT_SYMBOL
+-0xd6f8cf35    __block_write_begin     vmlinux EXPORT_SYMBOL
+-0x3517383e    register_reboot_notifier        vmlinux EXPORT_SYMBOL
+-0x188a3dfb    timespec_trunc  vmlinux EXPORT_SYMBOL
+-0x7647726c    handle_sysrq    vmlinux EXPORT_SYMBOL
+-0x2a55c54a    l2cap_unregister_user   vmlinux EXPORT_SYMBOL
+-0xdaafc807    tcp_sockets_allocated   vmlinux EXPORT_SYMBOL
+-0x61618241    netlink_alloc_skb       vmlinux EXPORT_SYMBOL_GPL
+-0x883edc99    snd_soc_dapm_weak_routes        vmlinux EXPORT_SYMBOL_GPL
+-0x0b20ad4e    inode_owner_or_capable  vmlinux EXPORT_SYMBOL
+-0x5ddfdc97    generic_pipe_buf_confirm        vmlinux EXPORT_SYMBOL
+-0x27fede28    get_super_thawed        vmlinux EXPORT_SYMBOL
+-0x7ff20102    v4l2_s_ctrl     vmlinux EXPORT_SYMBOL
+-0x9745d638    drm_err vmlinux EXPORT_SYMBOL
+-0x1c1a727a    v4l2_ctrl_subdev_subscribe_event        vmlinux EXPORT_SYMBOL
+-0x157df959    usbnet_tx_timeout       vmlinux EXPORT_SYMBOL_GPL
+-0x33ca0b9d    scsi_device_quiesce     vmlinux EXPORT_SYMBOL
+-0x18a12a47    drm_modeset_unlock_all  vmlinux EXPORT_SYMBOL
+-0x59d29dab    v7_flush_kern_dcache_area       vmlinux EXPORT_SYMBOL
+-0x9ca80cdd    inet6_protos    vmlinux EXPORT_SYMBOL
+-0x58714dc9    snd_soc_jack_add_zones  vmlinux EXPORT_SYMBOL_GPL
+-0xdc9110f5    snd_pcm_hw_param_first  vmlinux EXPORT_SYMBOL
+-0xf184d189    kernel_power_off        vmlinux EXPORT_SYMBOL_GPL
+-0xc8a270a1    usb_put_function        vmlinux EXPORT_SYMBOL_GPL
+-0xdfe8f93c    display_entity_get_size vmlinux EXPORT_SYMBOL_GPL
+-0x0ef959a5    ip6t_unregister_table   vmlinux EXPORT_SYMBOL
+-0x5ee28af3    genl_register_ops       vmlinux EXPORT_SYMBOL
+-0xda91a719    snd_pcm_new     vmlinux EXPORT_SYMBOL
+-0x8731837f    debugfs_create_u64      vmlinux EXPORT_SYMBOL_GPL
+-0x0d350531    block_commit_write      vmlinux EXPORT_SYMBOL
+-0xcb62227b    con_copy_unimap vmlinux EXPORT_SYMBOL
+-0x9b90584e    tty_ldisc_ref_wait      vmlinux EXPORT_SYMBOL_GPL
+-0xf727c5be    __netdev_alloc_skb      vmlinux EXPORT_SYMBOL
+-0xf186dfad    wm_hubs_set_bias_level  vmlinux EXPORT_SYMBOL_GPL
+-0x5bc4fef5    snd_soc_get_dai_substream       vmlinux EXPORT_SYMBOL_GPL
+-0xabefee2b    _snd_pcm_lib_alloc_vmalloc_buffer       vmlinux EXPORT_SYMBOL
+-0x5a116367    perf_event_create_kernel_counter        vmlinux EXPORT_SYMBOL_GPL
+-0x0bfa3a19    rcu_idle_exit   vmlinux EXPORT_SYMBOL_GPL
+-0x90ff6c9f    nf_ct_invert_tuplepr    vmlinux EXPORT_SYMBOL_GPL
+-0xf3cd9688    snd_soc_dapm_sync       vmlinux EXPORT_SYMBOL_GPL
+-0x68fb4f69    locks_delete_block      vmlinux EXPORT_SYMBOL
+-0xdca2a7bb    dput    vmlinux EXPORT_SYMBOL
+-0x67a000fa    try_module_get  vmlinux EXPORT_SYMBOL
+-0x4790cc27    v4l2_s_ext_ctrls        vmlinux EXPORT_SYMBOL
+-0xf39c1176    tty_kref_put    vmlinux EXPORT_SYMBOL
+-0x56310925    regulator_mode_to_status        vmlinux EXPORT_SYMBOL_GPL
+-0x0825a4fe    regulator_list_voltage_linear   vmlinux EXPORT_SYMBOL_GPL
+-0x43db92ba    fb_set_suspend  vmlinux EXPORT_SYMBOL
+-0x4993cc2b    register_net_sysctl     vmlinux EXPORT_SYMBOL_GPL
+-0x8a490c90    rfkill_set_sw_state     vmlinux EXPORT_SYMBOL
+-0xaae97496    snd_soc_bulk_write_raw  vmlinux EXPORT_SYMBOL_GPL
+-0xb4dd257b    srcu_notifier_call_chain        vmlinux EXPORT_SYMBOL_GPL
+-0x4403ead3    usb_match_one_id        vmlinux EXPORT_SYMBOL_GPL
+-0x829a0b6c    screen_glyph    vmlinux EXPORT_SYMBOL_GPL
+-0xf7802486    __aeabi_uidivmod        vmlinux EXPORT_SYMBOL
+-0x4b8f110e    sk_free vmlinux EXPORT_SYMBOL
+-0x4fbbaedb    snd_soc_free_ac97_codec vmlinux EXPORT_SYMBOL_GPL
+-0xfd5566cf    scsi_is_sdev_device     vmlinux EXPORT_SYMBOL
+-0x17dc8b68    drm_vblank_pre_modeset  vmlinux EXPORT_SYMBOL
+-0x7ef39823    ieee80211_hdrlen        vmlinux EXPORT_SYMBOL
+-0xc8f36b20    kobject_init    vmlinux EXPORT_SYMBOL
+-0xb2e764e8    suspend_valid_only_mem  vmlinux EXPORT_SYMBOL_GPL
+-0xfaf9995e    sleep_on        vmlinux EXPORT_SYMBOL
+-0x42160169    flush_workqueue vmlinux EXPORT_SYMBOL_GPL
+-0xf3251e7b    v4l2_norm_to_name       vmlinux EXPORT_SYMBOL
+-0xd7b664df    regulator_list_voltage_table    vmlinux EXPORT_SYMBOL_GPL
+-0xfe13b82a    snd_soc_info_enum_ext   vmlinux EXPORT_SYMBOL_GPL
+-0x22a8b63d    bio_flush_dcache_pages  vmlinux EXPORT_SYMBOL
+-0x0c3d1edb    simple_lookup   vmlinux EXPORT_SYMBOL
+-0x4cbc159a    gether_set_dev_addr     vmlinux EXPORT_SYMBOL
+-0xdac8e102    gether_get_dev_addr     vmlinux EXPORT_SYMBOL
+-0xfa599bb2    netlink_register_notifier       vmlinux EXPORT_SYMBOL
+-0xb7e5c788    cgroup_next_descendant_post     vmlinux EXPORT_SYMBOL_GPL
+-0xd7dc295c    dm_io   vmlinux EXPORT_SYMBOL
+-0xb8698990    usb_match_id    vmlinux EXPORT_SYMBOL_GPL
+-0x91a5dbd2    drm_idlelock_take       vmlinux EXPORT_SYMBOL
+-0xba86f941    xfrm_policy_insert      vmlinux EXPORT_SYMBOL
+-0x2519a629    skb_segment     vmlinux EXPORT_SYMBOL_GPL
+-0x2f574814    blk_queue_max_segments  vmlinux EXPORT_SYMBOL
+-0xa17232f2    bio_clone_bioset        vmlinux EXPORT_SYMBOL
+-0xba2bc8de    unlock_rename   vmlinux EXPORT_SYMBOL
+-0x9820b644    warn_slowpath_fmt_taint vmlinux EXPORT_SYMBOL
+-0x184b82fb    mmc_vddrange_to_ocrmask vmlinux EXPORT_SYMBOL
+-0x0a67ddd9    dm_suspended    vmlinux EXPORT_SYMBOL_GPL
+-0xfc8bcbaf    usb_add_hcd     vmlinux EXPORT_SYMBOL_GPL
+-0x965d4e18    tcp_init_congestion_ops vmlinux EXPORT_SYMBOL_GPL
+-0xe587559a    skb_push        vmlinux EXPORT_SYMBOL
+-0x1a32c5c7    blk_run_queue_async     vmlinux EXPORT_SYMBOL
+-0x7fa439cd    simple_rmdir    vmlinux EXPORT_SYMBOL
+-0xe6790d49    alloc_file      vmlinux EXPORT_SYMBOL
+-0xe8214f7a    free_task       vmlinux EXPORT_SYMBOL
+-0x2b9e3380    samsung_dmadev_get_ops  vmlinux EXPORT_SYMBOL
+-0x8e671fe0    sdio_f0_writeb  vmlinux EXPORT_SYMBOL_GPL
+-0x919b5fa4    device_create   vmlinux EXPORT_SYMBOL_GPL
+-0x5cf4fc85    psched_ratecfg_precompute       vmlinux EXPORT_SYMBOL
+-0x96573b80    __kfifo_dma_in_finish_r vmlinux EXPORT_SYMBOL
+-0xf520f285    sysfs_get       vmlinux EXPORT_SYMBOL_GPL
+-0x543ef284    seq_hlist_start vmlinux EXPORT_SYMBOL
+-0xbfffc4e0    vb2_read        vmlinux EXPORT_SYMBOL_GPL
+-0x45f39483    i2c_del_adapter vmlinux EXPORT_SYMBOL
+-0x5838f6c9    rtc_valid_tm    vmlinux EXPORT_SYMBOL
+-0xb7a638f3    usb_register_driver     vmlinux EXPORT_SYMBOL_GPL
+-0xb83a9297    scsi_block_requests     vmlinux EXPORT_SYMBOL
+-0xd5d8b6b8    drm_dp_get_adjust_request_pre_emphasis  vmlinux EXPORT_SYMBOL
+-0x99c95fa5    unregister_sound_special        vmlinux EXPORT_SYMBOL
+-0x056b6c53    fat_dir_empty   vmlinux EXPORT_SYMBOL_GPL
+-0xb51c8891    __getblk        vmlinux EXPORT_SYMBOL
+-0x1d9658d5    cdev_alloc      vmlinux EXPORT_SYMBOL
+-0x1dd73224    st_sensors_i2c_configure        vmlinux EXPORT_SYMBOL
+-0x22379ca8    led_blink_set_oneshot   vmlinux EXPORT_SYMBOL
+-0xe7e76d97    mmc_release_host        vmlinux EXPORT_SYMBOL
+-0x6e04a077    usb_bind_phy    vmlinux EXPORT_SYMBOL_GPL
+-0x47d9cfba    sdev_disable_disk_events        vmlinux EXPORT_SYMBOL
+-0x142b8b35    drm_buffer_copy_from_user       vmlinux EXPORT_SYMBOL
+-0x55f04c21    trace_buffer_unlock_commit_regs vmlinux EXPORT_SYMBOL_GPL
+-0x8c333b2b    usb_hcd_unlink_urb_from_ep      vmlinux EXPORT_SYMBOL_GPL
+-0x1fa2251f    device_wakeup_enable    vmlinux EXPORT_SYMBOL_GPL
+-0xbbe4496d    dev_warn        vmlinux EXPORT_SYMBOL
+-0xab3d1f95    nf_ct_untracked_status_or       vmlinux EXPORT_SYMBOL_GPL
+-0x131c2452    snd_jack_set_key        vmlinux EXPORT_SYMBOL
+-0x74c134b9    __sw_hweight32  vmlinux EXPORT_SYMBOL
+-0x57674fd7    __sw_hweight16  vmlinux EXPORT_SYMBOL
+-0x9f46ced8    __sw_hweight64  vmlinux EXPORT_SYMBOL
+-0x93215e1d    __kfifo_skip_r  vmlinux EXPORT_SYMBOL
+-0x1ec4eb34    flex_array_prealloc     vmlinux EXPORT_SYMBOL
+-0x01e6b7fa    get_phy_device  vmlinux EXPORT_SYMBOL
+-0x391c17d1    wakeup_source_register  vmlinux EXPORT_SYMBOL_GPL
+-0xfe85236b    cpu_user        vmlinux EXPORT_SYMBOL
+-0x35e62033    pagevec_lookup_tag      vmlinux EXPORT_SYMBOL
+-0x34184afe    current_kernel_time     vmlinux EXPORT_SYMBOL
+-0x0eb2ceba    tcp_reno_cong_avoid     vmlinux EXPORT_SYMBOL_GPL
+-0x2fce25e3    print_tuple     vmlinux EXPORT_SYMBOL_GPL
+-0x62496fbf    snd_soc_dai_set_clkdiv  vmlinux EXPORT_SYMBOL_GPL
+-0x7505bdef    memchr_inv      vmlinux EXPORT_SYMBOL
+-0x3b21bfec    locks_copy_lock vmlinux EXPORT_SYMBOL
+-0xb47a0298    hid_dump_report vmlinux EXPORT_SYMBOL_GPL
+-0x391147d1    led_trigger_blink       vmlinux EXPORT_SYMBOL_GPL
+-0xb65a6bb8    usb_reset_device        vmlinux EXPORT_SYMBOL_GPL
+-0x007b6ccf    gnet_stats_start_copy_compat    vmlinux EXPORT_SYMBOL
+-0x7522f3ba    irq_modify_status       vmlinux EXPORT_SYMBOL_GPL
+-0xd9052a07    rtc_alarm_irq_enable    vmlinux EXPORT_SYMBOL_GPL
+-0xcb6dc422    usb_add_config_only     vmlinux EXPORT_SYMBOL_GPL
+-0xd38b2d79    inet6_del_protocol      vmlinux EXPORT_SYMBOL
+-0x98b8ddd3    xfrm_input_resume       vmlinux EXPORT_SYMBOL
+-0xf71914b4    udplite_prot    vmlinux EXPORT_SYMBOL
+-0xdc48464a    sock_create_kern        vmlinux EXPORT_SYMBOL
+-0x8260686f    bitmap_find_next_zero_area      vmlinux EXPORT_SYMBOL
+-0x354ac8ad    scsi_eh_restore_cmnd    vmlinux EXPORT_SYMBOL
+-0x6f988f59    transport_remove_device vmlinux EXPORT_SYMBOL_GPL
+-0x600f8836    drm_class_device_register       vmlinux EXPORT_SYMBOL_GPL
+-0xd589c1c3    sk_clone_lock   vmlinux EXPORT_SYMBOL_GPL
+-0xf8798032    d_find_any_alias        vmlinux EXPORT_SYMBOL
+-0x56e4cd15    ftrace_event_reg        vmlinux EXPORT_SYMBOL_GPL
+-0xab29d75c    thermal_zone_get_zone_by_name   vmlinux EXPORT_SYMBOL_GPL
+-0x2a678a13    __suspend_report_result vmlinux EXPORT_SYMBOL_GPL
+-0xe36d12fc    drm_gtf_mode    vmlinux EXPORT_SYMBOL
+-0x5a48534a    regulator_count_voltages        vmlinux EXPORT_SYMBOL_GPL
+-0x2edb3fd8    sk_attach_filter        vmlinux EXPORT_SYMBOL_GPL
+-0x8d107d70    sk_detach_filter        vmlinux EXPORT_SYMBOL_GPL
+-0x5da176fe    snd_timer_open  vmlinux EXPORT_SYMBOL
+-0xf741c793    zlib_deflateEnd vmlinux EXPORT_SYMBOL
+-0x7469fcfe    radix_tree_tagged       vmlinux EXPORT_SYMBOL
+-0x57c405a5    unload_nls      vmlinux EXPORT_SYMBOL
+-0xcaa97c6a    seq_open_private        vmlinux EXPORT_SYMBOL
+-0xf3d2b805    st_sensors_get_buffer_element   vmlinux EXPORT_SYMBOL
+-0x82286526    vb2_ioctl_create_bufs   vmlinux EXPORT_SYMBOL_GPL
+-0xfb7d95b7    fb_set_cmap     vmlinux EXPORT_SYMBOL
+-0xed46d9ec    kernel_listen   vmlinux EXPORT_SYMBOL
+-0xb1b16346    snd_jack_set_parent     vmlinux EXPORT_SYMBOL
+-0x76bf656d    __bitmap_shift_left     vmlinux EXPORT_SYMBOL
+-0x1979065a    serio_unregister_driver vmlinux EXPORT_SYMBOL
+-0x3a94c8e6    drm_modeset_lock_all    vmlinux EXPORT_SYMBOL
+-0xa093e7da    nat_rtp_rtcp_hook       vmlinux EXPORT_SYMBOL_GPL
+-0xe23ae481    blk_iopoll_complete     vmlinux EXPORT_SYMBOL
+-0x4f6172ff    crypto_chain    vmlinux EXPORT_SYMBOL_GPL
+-0xd66a562b    __scsi_device_lookup    vmlinux EXPORT_SYMBOL
+-0x9d669763    memcpy  vmlinux EXPORT_SYMBOL
+-0x15c5eea4    ip6t_do_table   vmlinux EXPORT_SYMBOL
+-0x6b6533af    bdevname        vmlinux EXPORT_SYMBOL
+-0x65d67a20    blk_start_plug  vmlinux EXPORT_SYMBOL
+-0xdd686f05    cdev_init       vmlinux EXPORT_SYMBOL
+-0xbe63ee40    request_resource        vmlinux EXPORT_SYMBOL
+-0xb2018900    inet_getname    vmlinux EXPORT_SYMBOL
+-0x01610153    nf_ct_expect_init       vmlinux EXPORT_SYMBOL_GPL
+-0x04e1b99f    snd_pcm_std_chmaps      vmlinux EXPORT_SYMBOL_GPL
+-0x24a42b51    snd_unregister_oss_device       vmlinux EXPORT_SYMBOL
+-0x85e7deb2    iov_iter_fault_in_readable      vmlinux EXPORT_SYMBOL
+-0x8f049b6c    module_mutex    vmlinux EXPORT_SYMBOL_GPL
+-0x931b242d    regcache_sync   vmlinux EXPORT_SYMBOL_GPL
+-0xb95f98d6    _memset_io      vmlinux EXPORT_SYMBOL
+-0xa98e796e    modify_user_hw_breakpoint       vmlinux EXPORT_SYMBOL_GPL
+-0xbf9bcc8d    __cap_empty_set vmlinux EXPORT_SYMBOL
+-0xfba8bb33    dm_get_mapinfo  vmlinux EXPORT_SYMBOL
+-0x988ad2a2    rndis_set_param_vendor  vmlinux EXPORT_SYMBOL
+-0xb67d6992    usb_ep_autoconfig_reset vmlinux EXPORT_SYMBOL_GPL
+-0xfbe5910d    drm_mode_config_init    vmlinux EXPORT_SYMBOL
+-0x6443df4e    videomode_from_timings  vmlinux EXPORT_SYMBOL_GPL
+-0xad059f21    ip_tunnel_changelink    vmlinux EXPORT_SYMBOL_GPL
+-0x2c7fb2d0    crypto_shoot_alg        vmlinux EXPORT_SYMBOL_GPL
+-0xac226765    iput    vmlinux EXPORT_SYMBOL
+-0x77fe4cb2    sleep_on_timeout        vmlinux EXPORT_SYMBOL
+-0x1d88a23f    platform_get_resource   vmlinux EXPORT_SYMBOL_GPL
+-0xb95beb55    drm_object_property_set_value   vmlinux EXPORT_SYMBOL
+-0x8481713b    pn_sock_unhash  vmlinux EXPORT_SYMBOL
+-0x28a82da4    snmp_mib_init   vmlinux EXPORT_SYMBOL_GPL
+-0x03fd2571    vm_unmap_ram    vmlinux EXPORT_SYMBOL
+-0x65466939    proc_doulongvec_ms_jiffies_minmax       vmlinux EXPORT_SYMBOL
+-0x23654452    input_ff_upload vmlinux EXPORT_SYMBOL_GPL
+-0x45bda0d5    system_serial_low       vmlinux EXPORT_SYMBOL
+-0xa682a886    xfrm_output     vmlinux EXPORT_SYMBOL_GPL
+-0xeea9dbaf    bitmap_bitremap vmlinux EXPORT_SYMBOL
+-0x71a50dbc    register_blkdev vmlinux EXPORT_SYMBOL
+-0x43c0e15b    fuse_sync_release       vmlinux EXPORT_SYMBOL_GPL
+-0x972213d1    of_phy_connect  vmlinux EXPORT_SYMBOL
+-0x95390328    __fimc_vidioc_querycap  vmlinux EXPORT_SYMBOL
+-0xe453b342    ipv6_select_ident       vmlinux EXPORT_SYMBOL
+-0xabca477d    nf_conntrack_alter_reply        vmlinux EXPORT_SYMBOL_GPL
+-0x72c09e90    neigh_event_ns  vmlinux EXPORT_SYMBOL
+-0x32590631    snd_soc_update_bits     vmlinux EXPORT_SYMBOL_GPL
+-0xb96df73b    elevator_change vmlinux EXPORT_SYMBOL
+-0xa30a6f34    jbd2_journal_blocks_per_page    vmlinux EXPORT_SYMBOL
+-0x6103b2f2    iterate_supers_type     vmlinux EXPORT_SYMBOL
+-0x0a311e2a    iio_read_channel_processed      vmlinux EXPORT_SYMBOL_GPL
+-0x89953a68    sdhci_free_host vmlinux EXPORT_SYMBOL_GPL
+-0xb8de0d37    dpm_for_each_dev        vmlinux EXPORT_SYMBOL_GPL
+-0xe35ba70f    drm_prime_destroy_file_private  vmlinux EXPORT_SYMBOL
+-0x1cb4683d    drm_framebuffer_lookup  vmlinux EXPORT_SYMBOL
+-0xbaa9e7e0    fb_firmware_edid        vmlinux EXPORT_SYMBOL
+-0xa2ede8b2    nf_queue_entry_get_refs vmlinux EXPORT_SYMBOL_GPL
+-0x0ff98044    jump_label_rate_limit   vmlinux EXPORT_SYMBOL_GPL
+-0x3fd9109b    v4l2_ctrl_subdev_log_status     vmlinux EXPORT_SYMBOL
+-0x78cf4589    usb_kill_anchored_urbs  vmlinux EXPORT_SYMBOL_GPL
+-0x3b79aef9    request_firmware_nowait vmlinux EXPORT_SYMBOL
+-0xab160376    create_syslog_header    vmlinux EXPORT_SYMBOL
+-0x6d42bb18    drm_gem_handle_delete   vmlinux EXPORT_SYMBOL
+-0x366d19ef    genericbl_limit_intensity       vmlinux EXPORT_SYMBOL
+-0x7380780d    cfg80211_unlink_bss     vmlinux EXPORT_SYMBOL
+-0xff6b7f32    netdev_change_features  vmlinux EXPORT_SYMBOL
+-0x5613414a    init_dummy_netdev       vmlinux EXPORT_SYMBOL_GPL
+-0xbd5cb8b9    ring_buffer_resize      vmlinux EXPORT_SYMBOL_GPL
+-0xa55e517c    ip_tunnel_xmit  vmlinux EXPORT_SYMBOL_GPL
+-0x3b870a79    dst_destroy     vmlinux EXPORT_SYMBOL
+-0xad6b883a    usbnet_get_drvinfo      vmlinux EXPORT_SYMBOL_GPL
+-0x5df7a89b    nf_ct_helper_expectfn_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0x275ef902    __init_waitqueue_head   vmlinux EXPORT_SYMBOL
+-0x472b2841    devm_usb_get_phy        vmlinux EXPORT_SYMBOL_GPL
+-0x790d8481    scsi_mode_sense vmlinux EXPORT_SYMBOL
+-0x2d89342a    scsi_show_sense_hdr     vmlinux EXPORT_SYMBOL
+-0xda7ca6cb    fb_mode_is_equal        vmlinux EXPORT_SYMBOL
+-0xdc4798d2    xfrm6_tunnel_register   vmlinux EXPORT_SYMBOL
+-0xd587e7b5    xfrm4_tunnel_register   vmlinux EXPORT_SYMBOL
+-0x360b01a3    nf_ct_get_tuple vmlinux EXPORT_SYMBOL_GPL
+-0x6c74c2ee    blk_insert_cloned_request       vmlinux EXPORT_SYMBOL_GPL
+-0x46cb2731    security_sb_set_mnt_opts        vmlinux EXPORT_SYMBOL
+-0x1b995ffb    iommu_domain_window_enable      vmlinux EXPORT_SYMBOL_GPL
+-0xa4ea04ee    of_property_read_u64    vmlinux EXPORT_SYMBOL_GPL
+-0x411e4ef5    brcmu_pktq_pdeq_tail    drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x422d82d0    brcmu_pktq_penq_head    drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x41cc94d0    brcmu_pktq_peek_tail    drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x0c6f118f    nf_nat_icmpv6_reply_translation vmlinux EXPORT_SYMBOL_GPL
+-0xa07842c6    skb_copy_datagram_from_iovec    vmlinux EXPORT_SYMBOL
+-0xc8269f94    snd_soc_params_to_frame_size    vmlinux EXPORT_SYMBOL_GPL
+-0x43eeb6cf    snd_pcm_lib_ioctl       vmlinux EXPORT_SYMBOL
+-0x9ac11b74    suspend_set_ops vmlinux EXPORT_SYMBOL_GPL
+-0xca16dbe7    regulator_enable        vmlinux EXPORT_SYMBOL_GPL
+-0xecc84eb2    dst_alloc       vmlinux EXPORT_SYMBOL
+-0xf0f5dbc2    timerqueue_iterate_next vmlinux EXPORT_SYMBOL_GPL
+-0xab4a5add    blk_put_queue   vmlinux EXPORT_SYMBOL
+-0x11bef8bd    single_release  vmlinux EXPORT_SYMBOL
+-0x7aad72c6    get_user_pages  vmlinux EXPORT_SYMBOL
+-0x6214aef2    cpufreq_unregister_notifier     vmlinux EXPORT_SYMBOL
+-0xe93e49c3    devres_free     vmlinux EXPORT_SYMBOL_GPL
+-0xd95fbe77    of_find_backlight_by_node       vmlinux EXPORT_SYMBOL
+-0xe3f553d9    ip6_append_data vmlinux EXPORT_SYMBOL_GPL
+-0xa108eb4d    sysctl_optmem_max       vmlinux EXPORT_SYMBOL
+-0xdc323ca6    jbd2_journal_destroy    vmlinux EXPORT_SYMBOL
+-0x3c7a1672    jbd2_journal_restart    vmlinux EXPORT_SYMBOL
+-0x9805d460    v4l2_device_register    vmlinux EXPORT_SYMBOL_GPL
+-0x1db6d990    display_entity_get_first        vmlinux EXPORT_SYMBOL
+-0xe57878a1    in6_pton        vmlinux EXPORT_SYMBOL
+-0xaccabc6a    in4_pton        vmlinux EXPORT_SYMBOL
+-0xd0181f4f    __bitmap_xor    vmlinux EXPORT_SYMBOL
+-0x208c317e    mnt_want_write  vmlinux EXPORT_SYMBOL_GPL
+-0xbcdedba7    of_get_mac_address      vmlinux EXPORT_SYMBOL
+-0x859bbb79    scsi_mode_select        vmlinux EXPORT_SYMBOL_GPL
+-0x48991892    cfb_copyarea    vmlinux EXPORT_SYMBOL
+-0x2455c156    __clear_user    vmlinux EXPORT_SYMBOL
+-0x42c7d35b    __dev_remove_pack       vmlinux EXPORT_SYMBOL
+-0x465cab34    secure_ipv6_port_ephemeral      vmlinux EXPORT_SYMBOL
+-0x5ddbac94    config_group_init       vmlinux EXPORT_SYMBOL
+-0x773c1fdc    posix_acl_to_xattr      vmlinux EXPORT_SYMBOL
+-0xb18429eb    suspend_device_irqs     vmlinux EXPORT_SYMBOL_GPL
+-0x50c52151    _raw_write_unlock_irq   vmlinux EXPORT_SYMBOL
+-0xf5bc65a3    iommu_unmap     vmlinux EXPORT_SYMBOL_GPL
+-0x710e2b07    tcf_hash_insert vmlinux EXPORT_SYMBOL
+-0xf13feb57    radix_tree_next_chunk   vmlinux EXPORT_SYMBOL
+-0x90a1004a    crypto_has_alg  vmlinux EXPORT_SYMBOL_GPL
+-0x8cd44e50    iget5_locked    vmlinux EXPORT_SYMBOL
+-0x3dcb88a0    irq_set_handler_data    vmlinux EXPORT_SYMBOL
+-0xaa7de358    yield_to        vmlinux EXPORT_SYMBOL_GPL
+-0xc54649ff    __starget_for_each_device       vmlinux EXPORT_SYMBOL
+-0x2bd1f745    drm_mode_config_cleanup vmlinux EXPORT_SYMBOL
+-0xa1425906    ieee80211_channel_to_frequency  vmlinux EXPORT_SYMBOL
+-0x59806cb9    sk_page_frag_refill     vmlinux EXPORT_SYMBOL
+-0xce90ef6b    debugfs_create_dir      vmlinux EXPORT_SYMBOL_GPL
+-0xa4827144    dcache_dir_lseek        vmlinux EXPORT_SYMBOL
+-0x0c2cdbf1    synchronize_sched       vmlinux EXPORT_SYMBOL_GPL
+-0x92a9c60c    time_to_tm      vmlinux EXPORT_SYMBOL
+-0x651a4139    test_taint      vmlinux EXPORT_SYMBOL
+-0x2b66e1b8    mii_check_media vmlinux EXPORT_SYMBOL
+-0xfb7d9c45    __udivsi3       vmlinux EXPORT_SYMBOL
+-0x633fafc5    netdev_printk   vmlinux EXPORT_SYMBOL
+-0xf5a691cd    invalidate_bh_lrus      vmlinux EXPORT_SYMBOL_GPL
+-0xe5524eab    of_address_to_resource  vmlinux EXPORT_SYMBOL_GPL
+-0xe22f01b0    thermal_zone_device_register    vmlinux EXPORT_SYMBOL_GPL
+-0x3fc8bae1    ipcomp_init_state       vmlinux EXPORT_SYMBOL_GPL
+-0xf5b5f1ec    xt_check_match  vmlinux EXPORT_SYMBOL_GPL
+-0x24aac4d9    crypto_aes_expand_key   vmlinux EXPORT_SYMBOL_GPL
+-0x6f798a9c    d_splice_alias  vmlinux EXPORT_SYMBOL
+-0x88196936    do_sync_read    vmlinux EXPORT_SYMBOL
+-0x4a18707e    mem_map vmlinux EXPORT_SYMBOL
+-0x0366307a    console_suspend_enabled vmlinux EXPORT_SYMBOL
+-0x204d506e    st_sensors_write_event_value    vmlinux EXPORT_SYMBOL
+-0x4c22a54d    usb_ep_autoconfig       vmlinux EXPORT_SYMBOL_GPL
+-0x32c3cb4e    class_compat_register   vmlinux EXPORT_SYMBOL_GPL
+-0x7b85f6f8    drm_mm_insert_node      vmlinux EXPORT_SYMBOL
+-0x78f9b710    nf_ct_l3proto_try_module_get    vmlinux EXPORT_SYMBOL_GPL
+-0x44594236    snd_soc_unregister_component    vmlinux EXPORT_SYMBOL_GPL
+-0x05e4e6be    register_sound_midi     vmlinux EXPORT_SYMBOL
+-0x07341a03    kobject_rename  vmlinux EXPORT_SYMBOL_GPL
+-0x35b6b772    param_ops_charp vmlinux EXPORT_SYMBOL
+-0xb4c1829e    clk_round_rate  vmlinux EXPORT_SYMBOL_GPL
+-0x1bb061cc    sdio_release_irq        vmlinux EXPORT_SYMBOL_GPL
+-0xe4c673df    mmc_wait_for_cmd        vmlinux EXPORT_SYMBOL
+-0x4d088d1f    drm_mm_replace_node     vmlinux EXPORT_SYMBOL
+-0xe24e09b0    cgroup_taskset_cur_cgroup       vmlinux EXPORT_SYMBOL_GPL
+-0x7c5cf140    cad_pid vmlinux EXPORT_SYMBOL
+-0xaea8b9a5    drm_get_encoder_name    vmlinux EXPORT_SYMBOL
+-0xe4c80097    cacheid vmlinux EXPORT_SYMBOL
+-0x5a5a94a6    kstrtou8        vmlinux EXPORT_SYMBOL
+-0x2b4aa9c9    get_task_pid    vmlinux EXPORT_SYMBOL_GPL
+-0x30f43c3b    sdhci_enable_irq_wakeups        vmlinux EXPORT_SYMBOL_GPL
+-0x3a6d4f22    rndis_free_response     vmlinux EXPORT_SYMBOL
+-0x85478a0b    inet6_hash_frag vmlinux EXPORT_SYMBOL_GPL
+-0x0efbc42d    snd_component_add       vmlinux EXPORT_SYMBOL
+-0x6605f97f    flex_array_clear        vmlinux EXPORT_SYMBOL
+-0x5a7bfe41    crypto_probing_notify   vmlinux EXPORT_SYMBOL_GPL
+-0x94fd7214    serial8250_rx_chars     vmlinux EXPORT_SYMBOL_GPL
+-0x13a6027a    ip6t_alloc_initial_table        vmlinux EXPORT_SYMBOL_GPL
+-0x03a9a7bd    netif_receive_skb       vmlinux EXPORT_SYMBOL
+-0xfb6af58d    recalc_sigpending       vmlinux EXPORT_SYMBOL
+-0x2d0ea593    spi_new_device  vmlinux EXPORT_SYMBOL_GPL
+-0xfbc4e14c    pm_runtime_enable       vmlinux EXPORT_SYMBOL_GPL
+-0xc583bf57    of_regulator_match      vmlinux EXPORT_SYMBOL_GPL
+-0xebfdcbdf    system_serial_high      vmlinux EXPORT_SYMBOL
+-0x28d7fc1f    nf_nat_mangle_udp_packet        vmlinux EXPORT_SYMBOL
+-0xf71016b7    snd_soc_dapm_get_pin_status     vmlinux EXPORT_SYMBOL_GPL
+-0xf05c8ab1    vb2_get_contig_userptr  vmlinux EXPORT_SYMBOL_GPL
+-0xd045db89    nfc_class       vmlinux EXPORT_SYMBOL
+-0x606340d3    disk_part_iter_exit     vmlinux EXPORT_SYMBOL_GPL
+-0xa1bd7822    __tracepoint_block_bio_complete vmlinux EXPORT_SYMBOL_GPL
+-0x16138f6f    follow_down_one vmlinux EXPORT_SYMBOL
+-0x7944e0fc    tracing_off     vmlinux EXPORT_SYMBOL_GPL
+-0xb1425b32    dm_table_add_target_callbacks   vmlinux EXPORT_SYMBOL_GPL
+-0xbdfb8830    anon_transport_class_register   vmlinux EXPORT_SYMBOL_GPL
+-0x911d700e    devm_phy_create vmlinux EXPORT_SYMBOL_GPL
+-0xeb908d00    raw_seq_next    vmlinux EXPORT_SYMBOL_GPL
+-0x30b265dd    ip_setsockopt   vmlinux EXPORT_SYMBOL
+-0x9f45de2c    ip_getsockopt   vmlinux EXPORT_SYMBOL
+-0x30322337    nf_ct_l3proto_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0x8106c2de    nf_ct_l4proto_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0x4b015768    snd_iprintf     vmlinux EXPORT_SYMBOL
+-0xec728ca6    blk_unprep_request      vmlinux EXPORT_SYMBOL_GPL
+-0x0bae62b1    ktime_get_monotonic_offset      vmlinux EXPORT_SYMBOL_GPL
+-0x6f8450af    tty_encode_baud_rate    vmlinux EXPORT_SYMBOL_GPL
+-0xead6a706    devm_phy_destroy        vmlinux EXPORT_SYMBOL_GPL
+-0x2cf3c356    ip6_redirect    vmlinux EXPORT_SYMBOL_GPL
+-0x2cdb55d1    ip_options_rcv_srr      vmlinux EXPORT_SYMBOL
+-0x105bdf9b    dentry_open     vmlinux EXPORT_SYMBOL
+-0x724bf4b2    i2c_bit_add_numbered_bus        vmlinux EXPORT_SYMBOL
+-0x2e09263f    usb_copy_descriptors    vmlinux EXPORT_SYMBOL_GPL
+-0xbec98305    device_register vmlinux EXPORT_SYMBOL_GPL
+-0xff519474    skb_checksum_help       vmlinux EXPORT_SYMBOL
+-0x293d87a4    unregister_netdevice_queue      vmlinux EXPORT_SYMBOL
+-0xa692560a    snd_soc_lookup_platform vmlinux EXPORT_SYMBOL_GPL
+-0x9545af6d    tasklet_init    vmlinux EXPORT_SYMBOL
+-0x87374f66    extcon_unregister_interest      vmlinux EXPORT_SYMBOL_GPL
+-0x40a27c37    scsi_dev_info_remove_list       vmlinux EXPORT_SYMBOL
+-0x42a2164f    regmap_write    vmlinux EXPORT_SYMBOL_GPL
+-0xe6f46e6e    drm_clflush_virt_range  vmlinux EXPORT_SYMBOL
+-0x17f8217b    nf_nat_setup_info       vmlinux EXPORT_SYMBOL
+-0xb3daf4bf    jbd2_journal_get_undo_access    vmlinux EXPORT_SYMBOL
+-0xe16591ab    stop_machine    vmlinux EXPORT_SYMBOL_GPL
+-0xb6261484    register_die_notifier   vmlinux EXPORT_SYMBOL_GPL
+-0x415838be    led_trigger_set_default vmlinux EXPORT_SYMBOL_GPL
+-0x843020c0    ip6_find_1stfragopt     vmlinux EXPORT_SYMBOL
+-0x062936ed    nf_ct_unlink_expect_report      vmlinux EXPORT_SYMBOL_GPL
+-0xa6d16c61    sock_no_recvmsg vmlinux EXPORT_SYMBOL
+-0x4b0ac955    hrtimer_cancel  vmlinux EXPORT_SYMBOL_GPL
+-0x3626ebf4    xt_unregister_matches   vmlinux EXPORT_SYMBOL
+-0x72ea7812    security_inode_setattr  vmlinux EXPORT_SYMBOL_GPL
+-0xfdfc0b3b    fiemap_fill_next_extent vmlinux EXPORT_SYMBOL
+-0x82d19daa    qdisc_watchdog_cancel   vmlinux EXPORT_SYMBOL
+-0xc0581ee5    crypto_shash_digest     vmlinux EXPORT_SYMBOL_GPL
+-0x78728b6b    crypto_ahash_digest     vmlinux EXPORT_SYMBOL_GPL
+-0x3de9cae1    crypto_remove_final     vmlinux EXPORT_SYMBOL_GPL
+-0x31faa864    media_entity_init       vmlinux EXPORT_SYMBOL_GPL
+-0xe827112b    rtnl_set_sk_err vmlinux EXPORT_SYMBOL
+-0x5b23591f    snd_soc_jack_new        vmlinux EXPORT_SYMBOL_GPL
+-0x7b6646bb    _raw_read_lock  vmlinux EXPORT_SYMBOL
+-0xd4669fad    complete        vmlinux EXPORT_SYMBOL
+-0x488882e7    downgrade_write vmlinux EXPORT_SYMBOL
+-0xbaac427c    get_mem_type    vmlinux EXPORT_SYMBOL
+-0xc4014b9d    ip_check_defrag vmlinux EXPORT_SYMBOL
+-0x6aaccee0    config_item_init_type_name      vmlinux EXPORT_SYMBOL
+-0x62822d05    iov_iter_single_seg_count       vmlinux EXPORT_SYMBOL
+-0xb1f1a6ea    gether_get_host_addr_u8 vmlinux EXPORT_SYMBOL
+-0xf7f652fe    dma_mmap_from_coherent  vmlinux EXPORT_SYMBOL
+-0xfa9720a0    rdev_get_dev    vmlinux EXPORT_SYMBOL_GPL
+-0x62186db5    brcmu_pkt_buf_get_skb   drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0xf7af6d75    snd_pcm_new_stream      vmlinux EXPORT_SYMBOL
+-0x17320c5c    dentry_update_name_case vmlinux EXPORT_SYMBOL
+-0x8a7d1c31    high_memory     vmlinux EXPORT_SYMBOL
+-0x0186e2de    smp_call_function_many  vmlinux EXPORT_SYMBOL
+-0xbdf098ae    scsi_test_unit_ready    vmlinux EXPORT_SYMBOL
+-0x119b50e7    elf_check_arch  vmlinux EXPORT_SYMBOL
+-0xbf6d5c21    inet6_csk_update_pmtu   vmlinux EXPORT_SYMBOL_GPL
+-0x6b9a4457    snd_soc_jack_free_gpios vmlinux EXPORT_SYMBOL_GPL
+-0xd28c735f    simple_link     vmlinux EXPORT_SYMBOL
+-0xbdd2f42a    rcu_bh_force_quiescent_state    vmlinux EXPORT_SYMBOL_GPL
+-0x7a3cd015    v4l2_ctrl_get_menu      vmlinux EXPORT_SYMBOL
+-0x97f5694d    page_cache_async_readahead      vmlinux EXPORT_SYMBOL_GPL
+-0x2b4e956e    mempool_create  vmlinux EXPORT_SYMBOL
+-0x57231f45    ring_buffer_record_on   vmlinux EXPORT_SYMBOL_GPL
+-0x8e311007    hidinput_find_field     vmlinux EXPORT_SYMBOL_GPL
+-0x7ae1ae8e    cpufreq_frequency_table_put_attr        vmlinux EXPORT_SYMBOL_GPL
+-0x6c6a4b95    scsi_remove_target      vmlinux EXPORT_SYMBOL
+-0xb6c5a973    scsi_show_result        vmlinux EXPORT_SYMBOL
+-0x1ec3bed9    hdmi_audio_infoframe_init       vmlinux EXPORT_SYMBOL
+-0x3244dece    kblockd_schedule_work   vmlinux EXPORT_SYMBOL
+-0xafac4a33    mem_section     vmlinux EXPORT_SYMBOL
+-0xfd044751    send_sig_info   vmlinux EXPORT_SYMBOL
+-0xc02cf69b    clkdev_drop     vmlinux EXPORT_SYMBOL
+-0x39c95e24    phy_init_eee    vmlinux EXPORT_SYMBOL
+-0xfc53eac8    drm_cvt_mode    vmlinux EXPORT_SYMBOL
+-0x6a5e6530    __neigh_event_send      vmlinux EXPORT_SYMBOL
+-0x6c4d4cfe    sk_stream_wait_close    vmlinux EXPORT_SYMBOL
+-0x3d1cdeca    read_cache_page_async   vmlinux EXPORT_SYMBOL
+-0xd0ee38b8    schedule_timeout_uninterruptible        vmlinux EXPORT_SYMBOL
+-0xd79b5a02    allow_signal    vmlinux EXPORT_SYMBOL
+-0xd14fa335    show_class_attr_string  vmlinux EXPORT_SYMBOL_GPL
+-0xacb2a583    ndo_dflt_fdb_add        vmlinux EXPORT_SYMBOL
+-0x49a39542    snd_timer_global_register       vmlinux EXPORT_SYMBOL
+-0x63407037    kill_anon_super vmlinux EXPORT_SYMBOL
+-0xdc2b4205    platform_get_irq        vmlinux EXPORT_SYMBOL_GPL
+-0xc777ecaa    xfrm6_rcv       vmlinux EXPORT_SYMBOL
+-0x2fee3a7e    xfrm4_rcv       vmlinux EXPORT_SYMBOL
+-0xe94fef47    nf_ct_delete_from_lists vmlinux EXPORT_SYMBOL_GPL
+-0x6d466653    snd_soc_unregister_platform     vmlinux EXPORT_SYMBOL_GPL
+-0xb61a0c3b    bt_err  vmlinux EXPORT_SYMBOL
+-0x79536600    snd_soc_dpcm_can_be_params      vmlinux EXPORT_SYMBOL_GPL
+-0x016c4bc3    cfg80211_put_bss        vmlinux EXPORT_SYMBOL
+-0x90922aec    inet_dgram_connect      vmlinux EXPORT_SYMBOL
+-0x103ea6ec    generic_pipe_buf_steal  vmlinux EXPORT_SYMBOL
+-0x5fe77756    generic_pipe_buf_unmap  vmlinux EXPORT_SYMBOL
+-0xe5d95985    param_ops_ulong vmlinux EXPORT_SYMBOL
+-0xb03c01e8    dbs_check_cpu   vmlinux EXPORT_SYMBOL_GPL
+-0xff15acd6    usb_put_function_instance       vmlinux EXPORT_SYMBOL_GPL
+-0x6406cdf0    usb_find_alt_setting    vmlinux EXPORT_SYMBOL_GPL
+-0x4626bf6d    phy_connect     vmlinux EXPORT_SYMBOL
+-0x7a9326c6    driver_unregister       vmlinux EXPORT_SYMBOL_GPL
+-0xc5570382    inet_frags_exit_net     vmlinux EXPORT_SYMBOL
+-0x08216276    kobject_get     vmlinux EXPORT_SYMBOL
+-0x006818a5    kobject_put     vmlinux EXPORT_SYMBOL
+-0x37b777df    param_set_copystring    vmlinux EXPORT_SYMBOL
+-0x54f21cff    __send_remote_softirq   vmlinux EXPORT_SYMBOL
+-0x7a925833    cpufreq_get_global_kobject      vmlinux EXPORT_SYMBOL
+-0x2c900d91    cpufreq_put_global_kobject      vmlinux EXPORT_SYMBOL
+-0xbac4a225    v4l2_ctrl_fill  vmlinux EXPORT_SYMBOL
+-0xf7e6e534    v4l2_ctrl_find  vmlinux EXPORT_SYMBOL
+-0xbc5671dc    v4l_printk_ioctl        vmlinux EXPORT_SYMBOL
+-0x17021c93    drm_i2c_encoder_commit  vmlinux EXPORT_SYMBOL
+-0x10e70fd2    display_entity_get_modes        vmlinux EXPORT_SYMBOL_GPL
+-0xf1deabf2    div64_u64       vmlinux EXPORT_SYMBOL
+-0x2488515b    vb2_put_vma     vmlinux EXPORT_SYMBOL_GPL
+-0xd2ea2134    usb_descriptor_fillbuf  vmlinux EXPORT_SYMBOL_GPL
+-0xdacd26c5    usb_scuttle_anchored_urbs       vmlinux EXPORT_SYMBOL_GPL
+-0xfc39e32f    ioport_unmap    vmlinux EXPORT_SYMBOL
+-0x348998d3    sysfs_merge_group       vmlinux EXPORT_SYMBOL_GPL
+-0xc84a0a7e    seq_hlist_start_rcu     vmlinux EXPORT_SYMBOL
+-0xdd51deeb    d_validate      vmlinux EXPORT_SYMBOL
+-0x88ea60db    __get_user_pages_fast   vmlinux EXPORT_SYMBOL_GPL
+-0xe9bff861    down_trylock    vmlinux EXPORT_SYMBOL
+-0xff9e0620    usb_reset_configuration vmlinux EXPORT_SYMBOL_GPL
+-0x00130217    pwm_free        vmlinux EXPORT_SYMBOL_GPL
+-0x8fedcd53    snd_soc_info_xr_sx      vmlinux EXPORT_SYMBOL_GPL
+-0xc256e762    __bitmap_equal  vmlinux EXPORT_SYMBOL
+-0x7d4e2276    __init_rwsem    vmlinux EXPORT_SYMBOL
+-0xee5a877d    page_zero_new_buffers   vmlinux EXPORT_SYMBOL
+-0x96710252    mntget  vmlinux EXPORT_SYMBOL
+-0xe85c78e2    mntput  vmlinux EXPORT_SYMBOL
+-0x038e97d3    fasync_helper   vmlinux EXPORT_SYMBOL
+-0xf75c7d80    wm8994_mic_detect       vmlinux EXPORT_SYMBOL_GPL
+-0x2f4113a2    dcookie_register        vmlinux EXPORT_SYMBOL_GPL
+-0xce37be95    locks_mandatory_area    vmlinux EXPORT_SYMBOL
+-0x8be294cd    iommu_domain_free       vmlinux EXPORT_SYMBOL_GPL
+-0x23b5b8d1    exynos_drm_subdrv_register      vmlinux EXPORT_SYMBOL_GPL
+-0x6867f405    inet_twsk_deschedule    vmlinux EXPORT_SYMBOL
+-0x244e2178    xt_table_unlock vmlinux EXPORT_SYMBOL_GPL
+-0x52b9d131    tcf_exts_dump_stats     vmlinux EXPORT_SYMBOL
+-0x48bb9eb5    sock_alloc_send_pskb    vmlinux EXPORT_SYMBOL
+-0x757206d5    wm_hubs_spkmix_tlv      vmlinux EXPORT_SYMBOL_GPL
+-0x0acb1a3c    __bitmap_shift_right    vmlinux EXPORT_SYMBOL
+-0xaaa918c9    ftrace_dump     vmlinux EXPORT_SYMBOL_GPL
+-0x402b8281    __request_module        vmlinux EXPORT_SYMBOL
+-0xe944ba87    st_sensors_set_axis_enable      vmlinux EXPORT_SYMBOL
+-0x822f9003    inet_register_protosw   vmlinux EXPORT_SYMBOL
+-0xbe3a4f06    __inet_inherit_port     vmlinux EXPORT_SYMBOL_GPL
+-0xb63f16de    dev_deactivate  vmlinux EXPORT_SYMBOL
+-0xa014da84    snd_soc_add_platform_controls   vmlinux EXPORT_SYMBOL_GPL
+-0xeaaee9e6    submit_bio_wait vmlinux EXPORT_SYMBOL
+-0x23fd3028    vmalloc_node    vmlinux EXPORT_SYMBOL
+-0xa58fea9d    mempool_destroy vmlinux EXPORT_SYMBOL
+-0x054e550b    kernel_halt     vmlinux EXPORT_SYMBOL_GPL
+-0xf4c770ec    v4l2_clk_disable        vmlinux EXPORT_SYMBOL
+-0xd597e74e    phy_find_first  vmlinux EXPORT_SYMBOL
+-0x50621015    xfrm6_tunnel_spi_lookup vmlinux EXPORT_SYMBOL
+-0xc0f8a5b0    set_binfmt      vmlinux EXPORT_SYMBOL
+-0x36075bb5    iommu_group_register_notifier   vmlinux EXPORT_SYMBOL_GPL
+-0x93b8b0d3    scsi_ioctl      vmlinux EXPORT_SYMBOL
+-0xd0dcdd90    drm_mm_insert_node_in_range_generic     vmlinux EXPORT_SYMBOL
+-0xb2eaff96    km_policy_expired       vmlinux EXPORT_SYMBOL
+-0xa9effda5    __first_cpu     vmlinux EXPORT_SYMBOL
+-0xc24ba3ed    elv_rb_find     vmlinux EXPORT_SYMBOL
+-0xf0619801    timekeeping_clocktai    vmlinux EXPORT_SYMBOL
+-0x9e4faeef    dm_io_client_destroy    vmlinux EXPORT_SYMBOL
+-0x95cbb942    usb_add_gadget_udc_release      vmlinux EXPORT_SYMBOL_GPL
+-0x14c3db3e    spi_unregister_master   vmlinux EXPORT_SYMBOL_GPL
+-0xbee90f2f    __kfifo_out_peek_r      vmlinux EXPORT_SYMBOL
+-0x2869ebaf    regulator_bulk_force_disable    vmlinux EXPORT_SYMBOL_GPL
+-0xa04a01bd    qdisc_class_hash_insert vmlinux EXPORT_SYMBOL
+-0x43a261a8    eth_commit_mac_addr_change      vmlinux EXPORT_SYMBOL
+-0xe5867808    dlci_ioctl_set  vmlinux EXPORT_SYMBOL
+-0xbae6da94    crypto_alg_lookup       vmlinux EXPORT_SYMBOL_GPL
+-0x330d748a    v4l2_subdev_init        vmlinux EXPORT_SYMBOL
+-0xc6ff1a7d    phonet_header_ops       vmlinux EXPORT_SYMBOL
+-0xfaefacf3    locks_free_lock vmlinux EXPORT_SYMBOL
+-0xcbfa0b41    scsi_report_device_reset        vmlinux EXPORT_SYMBOL
+-0xbe1e4cd0    scsi_print_sense        vmlinux EXPORT_SYMBOL
+-0xe87ed821    drm_mode_create_dirty_info_property     vmlinux EXPORT_SYMBOL
+-0xb6d97288    inet6_add_offload       vmlinux EXPORT_SYMBOL
+-0xa681ec81    snd_soc_jack_notifier_register  vmlinux EXPORT_SYMBOL_GPL
+-0xd64b88b6    register_sound_mixer    vmlinux EXPORT_SYMBOL
+-0x02701efc    simple_attr_release     vmlinux EXPORT_SYMBOL_GPL
+-0xf6e04730    event_storage   vmlinux EXPORT_SYMBOL_GPL
+-0x95b5af62    mmc_regulator_set_ocr   vmlinux EXPORT_SYMBOL_GPL
+-0x77e78218    regulator_allow_bypass  vmlinux EXPORT_SYMBOL_GPL
+-0xf1070592    cfg80211_wext_giwretry  vmlinux EXPORT_SYMBOL_GPL
+-0x8a0f4230    rename_lock     vmlinux EXPORT_SYMBOL
+-0xda259c5d    page_symlink_inode_operations   vmlinux EXPORT_SYMBOL
+-0x8bd0a3fd    _raw_write_unlock_bh    vmlinux EXPORT_SYMBOL
+-0x99b0f1ff    usb_submit_urb  vmlinux EXPORT_SYMBOL_GPL
+-0x1fbd16da    ip_tos2prio     vmlinux EXPORT_SYMBOL
+-0x060ea2d6    kstrtoull       vmlinux EXPORT_SYMBOL
+-0x5ac15bae    kstrtou16       vmlinux EXPORT_SYMBOL
+-0x1998d8b6    jbd2_inode_cache        vmlinux EXPORT_SYMBOL
+-0x94961283    vunmap  vmlinux EXPORT_SYMBOL
+-0x74c4a01e    write_cache_pages       vmlinux EXPORT_SYMBOL
+-0xc1ddc02b    pinctrl_register        vmlinux EXPORT_SYMBOL_GPL
+-0x0ca54fee    _test_and_set_bit       vmlinux EXPORT_SYMBOL
+-0x80dfa464    xfrm_policy_alloc       vmlinux EXPORT_SYMBOL
+-0xd04f8eb6    nf_conntrack_l4proto_tcp6       vmlinux EXPORT_SYMBOL_GPL
+-0xcf28b516    finish_open     vmlinux EXPORT_SYMBOL
+-0x10f734ff    led_blink_set   vmlinux EXPORT_SYMBOL
+-0xc9086110    dw_mci_pltfm_remove     vmlinux EXPORT_SYMBOL_GPL
+-0xe5c78a99    do_blank_screen vmlinux EXPORT_SYMBOL
+-0xf17c6528    cfg80211_remain_on_channel_expired      vmlinux EXPORT_SYMBOL
+-0x117093be    qdisc_class_hash_init   vmlinux EXPORT_SYMBOL
+-0x13e6a1a2    sk_prot_clear_portaddr_nulls    vmlinux EXPORT_SYMBOL
+-0xa2a2d730    task_current_syscall    vmlinux EXPORT_SYMBOL_GPL
+-0x4411c503    prandom_seed    vmlinux EXPORT_SYMBOL
+-0x547ba3f6    single_open_net vmlinux EXPORT_SYMBOL_GPL
+-0xb9012717    set_page_dirty_lock     vmlinux EXPORT_SYMBOL
+-0x9a37cbf4    tcp_v4_conn_request     vmlinux EXPORT_SYMBOL
+-0xc81ae040    snd_soc_codec_volatile_register vmlinux EXPORT_SYMBOL_GPL
+-0xbe52317a    blk_rq_init     vmlinux EXPORT_SYMBOL
+-0x9ef34ad4    cpufreq_frequency_table_cpuinfo vmlinux EXPORT_SYMBOL_GPL
+-0x5bcf159d    usb_get_descriptor      vmlinux EXPORT_SYMBOL_GPL
+-0xf2e5cabe    spi_async_locked        vmlinux EXPORT_SYMBOL_GPL
+-0x26e76fb8    sysctl_udp_wmem_min     vmlinux EXPORT_SYMBOL
+-0x1fb12a69    tcp_v4_syn_recv_sock    vmlinux EXPORT_SYMBOL
+-0x6d464175    __sg_free_table vmlinux EXPORT_SYMBOL
+-0x59056c08    kmem_cache_shrink       vmlinux EXPORT_SYMBOL
+-0xc3aef602    usb_put_dev     vmlinux EXPORT_SYMBOL_GPL
+-0x520a3baf    drm_vm_open_locked      vmlinux EXPORT_SYMBOL_GPL
+-0x711a004a    drm_dp_link_rate_to_bw_code     vmlinux EXPORT_SYMBOL
+-0x919029aa    __readwrite_bug vmlinux EXPORT_SYMBOL
+-0x49045426    icmp_err_convert        vmlinux EXPORT_SYMBOL
+-0xf087137d    __dynamic_pr_debug      vmlinux EXPORT_SYMBOL
+-0x1e5b03dc    pm_qos_add_notifier     vmlinux EXPORT_SYMBOL_GPL
+-0x5e9d9e1e    gov_queue_work  vmlinux EXPORT_SYMBOL_GPL
+-0x601f665f    dm_io_client_create     vmlinux EXPORT_SYMBOL
+-0x05c311c2    vb2_ioctl_prepare_buf   vmlinux EXPORT_SYMBOL_GPL
+-0x14f62d2b    mii_check_link  vmlinux EXPORT_SYMBOL
+-0x36c69db7    dma_common_mmap vmlinux EXPORT_SYMBOL
+-0x1072a394    csum_partial_copy_from_user     vmlinux EXPORT_SYMBOL
+-0x3f878645    inet_diag_dump_one_icsk vmlinux EXPORT_SYMBOL_GPL
+-0xd7b85107    tcp_hashinfo    vmlinux EXPORT_SYMBOL
+-0x2d140a58    genl_unlock     vmlinux EXPORT_SYMBOL
+-0xeed1b62f    crypto_aead_setauthsize vmlinux EXPORT_SYMBOL_GPL
+-0x5f7bdc58    fd_install      vmlinux EXPORT_SYMBOL
+-0xe11f3cbc    _raw_read_lock_bh       vmlinux EXPORT_SYMBOL
+-0x3fd55724    of_n_size_cells vmlinux EXPORT_SYMBOL
+-0xd17aae7c    hid_report_raw_event    vmlinux EXPORT_SYMBOL_GPL
+-0xe469207d    scsi_unregister vmlinux EXPORT_SYMBOL
+-0xbf5da77e    dma_buf_begin_cpu_access        vmlinux EXPORT_SYMBOL_GPL
+-0x47ed7ca1    inet6_unregister_icmp_sender    vmlinux EXPORT_SYMBOL
+-0xed8b1ab6    nf_nat_used_tuple       vmlinux EXPORT_SYMBOL
+-0x46e928cf    nf_nat_packet   vmlinux EXPORT_SYMBOL_GPL
+-0xdc854ee4    blk_init_tags   vmlinux EXPORT_SYMBOL
+-0x4b134056    vfs_fsync_range vmlinux EXPORT_SYMBOL
+-0x3ce4ca6f    disable_irq     vmlinux EXPORT_SYMBOL
+-0xdc9fa232    raw_notifier_chain_register     vmlinux EXPORT_SYMBOL_GPL
+-0x2b0d15d8    scsi_internal_device_unblock    vmlinux EXPORT_SYMBOL_GPL
+-0x09d12bc0    sysfs_remove_file       vmlinux EXPORT_SYMBOL_GPL
+-0x85a8465a    path_put        vmlinux EXPORT_SYMBOL
+-0xe0dec72b    apply_to_page_range     vmlinux EXPORT_SYMBOL_GPL
+-0xa0ceef51    out_of_line_wait_on_bit vmlinux EXPORT_SYMBOL
+-0x7f04e7d5    dm_set_target_max_io_len        vmlinux EXPORT_SYMBOL_GPL
+-0x84a26155    v4l2_ctrl_g_ctrl        vmlinux EXPORT_SYMBOL
+-0x1254f0e4    scsi_host_alloc vmlinux EXPORT_SYMBOL
+-0x0e09444b    bus_get_device_klist    vmlinux EXPORT_SYMBOL_GPL
+-0xbebc3cd2    dst_discard     vmlinux EXPORT_SYMBOL
+-0x8d25ae30    snd_soc_dapm_put_value_enum_double      vmlinux EXPORT_SYMBOL_GPL
+-0x8d02ccf1    snd_soc_dapm_get_value_enum_double      vmlinux EXPORT_SYMBOL_GPL
+-0xaa2a72bf    __iowrite64_copy        vmlinux EXPORT_SYMBOL_GPL
+-0x373d62c5    invalidate_partition    vmlinux EXPORT_SYMBOL
+-0xd217e9e6    trace_set_clr_event     vmlinux EXPORT_SYMBOL_GPL
+-0x00e86db4    kick_process    vmlinux EXPORT_SYMBOL_GPL
+-0xa625110d    kmsg_dump_rewind        vmlinux EXPORT_SYMBOL_GPL
+-0x17eb0eee    v4l2_m2m_init   vmlinux EXPORT_SYMBOL_GPL
+-0xd153a267    drm_irq_uninstall       vmlinux EXPORT_SYMBOL
+-0x6ccf7bd7    __pv_phys_offset        vmlinux EXPORT_SYMBOL
+-0x6cf45a72    sk_release_kernel       vmlinux EXPORT_SYMBOL
+-0x7cff72b3    sg_miter_stop   vmlinux EXPORT_SYMBOL
+-0x0da10ec3    security_sock_graft     vmlinux EXPORT_SYMBOL
+-0xe601743b    jbd2_journal_init_jbd_inode     vmlinux EXPORT_SYMBOL
+-0xdd3916ac    _raw_spin_unlock_bh     vmlinux EXPORT_SYMBOL
+-0xb5ab5fe9    usb_function_register   vmlinux EXPORT_SYMBOL_GPL
+-0xa20bbbd7    xt_proto_init   vmlinux EXPORT_SYMBOL_GPL
+-0x13b715e2    blk_finish_plug vmlinux EXPORT_SYMBOL
+-0x0b1beb31    vmalloc_32_user vmlinux EXPORT_SYMBOL
+-0x85dfe0aa    fget_light      vmlinux EXPORT_SYMBOL
+-0x8bebc4a8    drm_master_put  vmlinux EXPORT_SYMBOL
+-0xf073bd48    nfc_hci_target_discovered       vmlinux EXPORT_SYMBOL
+-0x878ab3ce    sysctl_tcp_adv_win_scale        vmlinux EXPORT_SYMBOL
+-0x11e11bef    ip_local_out    vmlinux EXPORT_SYMBOL_GPL
+-0xafe96047    generic_permission      vmlinux EXPORT_SYMBOL
+-0x96123b65    iio_trigger_unregister  vmlinux EXPORT_SYMBOL
+-0xf7b01b50    gether_get_host_addr_cdc        vmlinux EXPORT_SYMBOL
+-0x3324e6d2    ehci_suspend    vmlinux EXPORT_SYMBOL_GPL
+-0x7ef61596    usb_hcd_check_unlink_urb        vmlinux EXPORT_SYMBOL_GPL
+-0x7ced7048    phy_device_free vmlinux EXPORT_SYMBOL
+-0x9afda3df    regcache_cache_bypass   vmlinux EXPORT_SYMBOL_GPL
+-0xd59668e6    unlock_flocks   vmlinux EXPORT_SYMBOL_GPL
+-0xb818e055    usbnet_open     vmlinux EXPORT_SYMBOL_GPL
+-0x4683093b    snd_ctl_notify  vmlinux EXPORT_SYMBOL
+-0x9d3aa376    blk_iopoll_init vmlinux EXPORT_SYMBOL
+-0x226a674d    atomic_notifier_chain_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0x0144d325    regmap_async_complete   vmlinux EXPORT_SYMBOL_GPL
+-0x27f4cbdb    uart_get_baud_rate      vmlinux EXPORT_SYMBOL
+-0x878175c4    secpath_dup     vmlinux EXPORT_SYMBOL
+-0x7931d788    snd_pcm_hw_constraint_step      vmlinux EXPORT_SYMBOL
+-0x36170e28    set_user_nice   vmlinux EXPORT_SYMBOL
+-0x45de06d1    iio_buffer_write_length vmlinux EXPORT_SYMBOL
+-0x5babbf10    media_device_unregister_entity  vmlinux EXPORT_SYMBOL_GPL
+-0xe593d0c8    usbnet_disconnect       vmlinux EXPORT_SYMBOL_GPL
+-0xb7e8ce46    exynos_drm_subdrv_close vmlinux EXPORT_SYMBOL_GPL
+-0xc29dc1ad    drm_framebuffer_init    vmlinux EXPORT_SYMBOL
+-0x7fe1a403    cfg80211_find_ie        vmlinux EXPORT_SYMBOL
+-0xa8469c88    netdev_notify_peers     vmlinux EXPORT_SYMBOL
+-0xe81978c6    splice_direct_to_actor  vmlinux EXPORT_SYMBOL
+-0xb5cb8145    hrtimer_get_res vmlinux EXPORT_SYMBOL_GPL
+-0x9a70b0fd    nf_nat_pptp_hook_inbound        vmlinux EXPORT_SYMBOL_GPL
+-0x2b9da7a4    genl_lock       vmlinux EXPORT_SYMBOL
+-0xb72e58d6    qdisc_class_hash_grow   vmlinux EXPORT_SYMBOL
+-0x0e59e8cf    sock_setsockopt vmlinux EXPORT_SYMBOL
+-0x20df2681    ida_simple_remove       vmlinux EXPORT_SYMBOL
+-0xbdef23a2    unlock_buffer   vmlinux EXPORT_SYMBOL
+-0x3b231b68    simple_transaction_release      vmlinux EXPORT_SYMBOL
+-0xad098b64    usb_unlocked_enable_lpm vmlinux EXPORT_SYMBOL_GPL
+-0x4b05e7ed    tty_port_close_start    vmlinux EXPORT_SYMBOL
+-0x14789075    dma_find_channel        vmlinux EXPORT_SYMBOL
+-0x77c05b09    fb_find_mode    vmlinux EXPORT_SYMBOL
+-0x01010c6d    klist_add_before        vmlinux EXPORT_SYMBOL_GPL
+-0x292c29ad    nfulnl_log_packet       vmlinux EXPORT_SYMBOL_GPL
+-0x521b36b5    qdisc_put_rtab  vmlinux EXPORT_SYMBOL
+-0x69c66f79    crypto_attr_alg2        vmlinux EXPORT_SYMBOL_GPL
+-0x341dbfa3    __per_cpu_offset        vmlinux EXPORT_SYMBOL
+-0x8953f8ff    __tracepoint_kmem_cache_alloc   vmlinux EXPORT_SYMBOL
+-0x7e0ef97c    regmap_irq_get_domain   vmlinux EXPORT_SYMBOL_GPL
+-0x437ff921    subsys_find_device_by_id        vmlinux EXPORT_SYMBOL_GPL
+-0x975e0663    set_sig_addr_hook       vmlinux EXPORT_SYMBOL_GPL
+-0xe86f0da8    proto_register  vmlinux EXPORT_SYMBOL
+-0xb838d98e    event_storage_mutex     vmlinux EXPORT_SYMBOL_GPL
+-0x9ca1dc35    vb2_fop_mmap    vmlinux EXPORT_SYMBOL_GPL
+-0xde1a5959    rtc_irq_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0xbeca75ff    drm_crtc_helper_set_mode        vmlinux EXPORT_SYMBOL
+-0x65f850bc    tty_wakeup      vmlinux EXPORT_SYMBOL_GPL
+-0xf4743f88    amba_ahb_device_add     vmlinux EXPORT_SYMBOL_GPL
+-0xa994f545    check_disk_size_change  vmlinux EXPORT_SYMBOL
+-0x455293f6    down_read       vmlinux EXPORT_SYMBOL
+-0x7eaf8e7a    v4l2_detect_gtf vmlinux EXPORT_SYMBOL_GPL
+-0x53105839    v4l2_detect_cvt vmlinux EXPORT_SYMBOL_GPL
+-0x6a41ea71    v4l2_clk_get_rate       vmlinux EXPORT_SYMBOL
+-0xc50c3f79    v4l2_clk_set_rate       vmlinux EXPORT_SYMBOL
+-0x52bc9e2a    drm_plane_cleanup       vmlinux EXPORT_SYMBOL
+-0x0d4cb82a    km_report       vmlinux EXPORT_SYMBOL
+-0xcffe8e42    __napi_complete vmlinux EXPORT_SYMBOL
+-0xb17c5844    skb_copy_expand vmlinux EXPORT_SYMBOL
+-0xaaaa5788    blk_queue_softirq_done  vmlinux EXPORT_SYMBOL
+-0x43a762e5    d_lookup        vmlinux EXPORT_SYMBOL
+-0xebc525f4    iio_triggered_buffer_cleanup    vmlinux EXPORT_SYMBOL
+-0xabd0c91c    rtc_time_to_tm  vmlinux EXPORT_SYMBOL
+-0x70f3f9b2    dmam_free_coherent      vmlinux EXPORT_SYMBOL
+-0xba361646    transport_setup_device  vmlinux EXPORT_SYMBOL_GPL
+-0x950ee7d1    fb_find_logo    vmlinux EXPORT_SYMBOL_GPL
+-0x20294ce8    genl_unregister_mc_group        vmlinux EXPORT_SYMBOL
+-0x1d7aabfd    path_is_under   vmlinux EXPORT_SYMBOL
+-0x17975413    iio_map_array_register  vmlinux EXPORT_SYMBOL_GPL
+-0xf811e69d    scsi_eh_flush_done_q    vmlinux EXPORT_SYMBOL
+-0x8b95a59f    xt_hook_unlink  vmlinux EXPORT_SYMBOL_GPL
+-0x557cb7c6    skb_morph       vmlinux EXPORT_SYMBOL_GPL
+-0x02ef742b    percpu_counter_set      vmlinux EXPORT_SYMBOL
+-0x03ae21fb    mmc_erase       vmlinux EXPORT_SYMBOL
+-0x7c46233a    cpufreq_quick_get       vmlinux EXPORT_SYMBOL
+-0xa4f8a168    dm_underlying_device_busy       vmlinux EXPORT_SYMBOL_GPL
+-0x1d41eadc    v4l2_ctrl_s_ctrl        vmlinux EXPORT_SYMBOL
+-0xa11295ab    serio_unregister_port   vmlinux EXPORT_SYMBOL
+-0x11065515    drm_mode_equal  vmlinux EXPORT_SYMBOL
+-0x4c47ec15    klist_add_head  vmlinux EXPORT_SYMBOL_GPL
+-0x68a24153    snd_pcm_format_physical_width   vmlinux EXPORT_SYMBOL
+-0xb6822a33    radix_tree_gang_lookup_tag      vmlinux EXPORT_SYMBOL
+-0xdaa16b82    of_clk_get      vmlinux EXPORT_SYMBOL
+-0x5c625801    scsi_remove_host        vmlinux EXPORT_SYMBOL
+-0xa7de1327    flush_dcache_page       vmlinux EXPORT_SYMBOL
+-0x2d6507b5    _find_next_zero_bit_le  vmlinux EXPORT_SYMBOL
+-0xf26e1c06    snd_soc_suspend vmlinux EXPORT_SYMBOL_GPL
+-0xc213a12a    devm_ioremap_nocache    vmlinux EXPORT_SYMBOL
+-0xb43a5300    sync_dirty_buffer       vmlinux EXPORT_SYMBOL
+-0xd303fa4e    clk_notifier_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x496c3d67    v4l2_querymenu  vmlinux EXPORT_SYMBOL
+-0x02b44bb5    scsi_is_host_device     vmlinux EXPORT_SYMBOL
+-0x91c9a325    bt_to_errno     vmlinux EXPORT_SYMBOL
+-0x86a85b06    tcp_reno_ssthresh       vmlinux EXPORT_SYMBOL_GPL
+-0xfc5c6b3e    netlink_has_listeners   vmlinux EXPORT_SYMBOL_GPL
+-0xe075d6eb    iter_div_u64_rem        vmlinux EXPORT_SYMBOL
+-0xcf0e08ad    filter_current_check_discard    vmlinux EXPORT_SYMBOL_GPL
+-0x5afb47fc    of_irq_to_resource_table        vmlinux EXPORT_SYMBOL_GPL
+-0xf1421d13    drm_mode_sort   vmlinux EXPORT_SYMBOL
+-0xd06ec95f    dma_supported   vmlinux EXPORT_SYMBOL
+-0xf1b80226    nf_nat_seq_adjust_hook  vmlinux EXPORT_SYMBOL_GPL
+-0xf4c02b65    inode_init_once vmlinux EXPORT_SYMBOL
+-0x369fcd70    tracing_snapshot        vmlinux EXPORT_SYMBOL_GPL
+-0x73d69364    ring_buffer_change_overwrite    vmlinux EXPORT_SYMBOL_GPL
+-0x339d542a    __srcu_notifier_call_chain      vmlinux EXPORT_SYMBOL_GPL
+-0xe2d3d0b9    v4l2_ctrl_sub_ev_ops    vmlinux EXPORT_SYMBOL
+-0xee129bef    usb_alloc_urb   vmlinux EXPORT_SYMBOL_GPL
+-0x64a127a3    spi_setup       vmlinux EXPORT_SYMBOL_GPL
+-0x3a8da0aa    nf_ip6_checksum vmlinux EXPORT_SYMBOL
+-0xb46a6cbb    scsi_cmd_ioctl  vmlinux EXPORT_SYMBOL
+-0xf7d52055    iio_bus_type    vmlinux EXPORT_SYMBOL
+-0x75b9f8b8    device_move     vmlinux EXPORT_SYMBOL_GPL
+-0x34dc9b87    neigh_seq_stop  vmlinux EXPORT_SYMBOL
+-0x82b802b2    snd_soc_dai_set_pll     vmlinux EXPORT_SYMBOL_GPL
+-0x0f4c91ed    ns_to_timespec  vmlinux EXPORT_SYMBOL
+-0xca34e63d    iio_triggered_buffer_postenable vmlinux EXPORT_SYMBOL
+-0x8d3ecd41    drm_core_ioremapfree    vmlinux EXPORT_SYMBOL
+-0xed93f29e    __kunmap_atomic vmlinux EXPORT_SYMBOL
+-0xe7cd755a    nf_ct_dying_timeout     vmlinux EXPORT_SYMBOL_GPL
+-0xe5452cbf    dev_mc_del_global       vmlinux EXPORT_SYMBOL
+-0x1a77ed38    dev_mc_add_global       vmlinux EXPORT_SYMBOL
+-0x7b4901f5    snd_soc_add_platform    vmlinux EXPORT_SYMBOL_GPL
+-0xdff7c9ce    blocking_notifier_chain_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0x346127a7    drm_global_item_ref     vmlinux EXPORT_SYMBOL
+-0xf763bb6d    drm_framebuffer_cleanup vmlinux EXPORT_SYMBOL
+-0x4a6b641b    fifo_create_dflt        vmlinux EXPORT_SYMBOL
+-0x3a39f5ed    neigh_table_init        vmlinux EXPORT_SYMBOL
+-0xc7207cfe    blk_queue_segment_boundary      vmlinux EXPORT_SYMBOL
+-0x183b1236    blk_stop_queue  vmlinux EXPORT_SYMBOL
+-0x632b18ed    blkcipher_walk_virt_block       vmlinux EXPORT_SYMBOL_GPL
+-0x68ecff32    sysfs_create_link       vmlinux EXPORT_SYMBOL_GPL
+-0x2bc64f3b    task_active_pid_ns      vmlinux EXPORT_SYMBOL_GPL
+-0xda83d7a1    mmc_register_driver     vmlinux EXPORT_SYMBOL
+-0x85e9caff    exynos4x12_cpufreq_init vmlinux EXPORT_SYMBOL
+-0xf75603a3    exynos4210_cpufreq_init vmlinux EXPORT_SYMBOL
+-0x38a9c2c7    input_ff_effect_from_user       vmlinux EXPORT_SYMBOL_GPL
+-0x4f92c146    mfd_cell_enable vmlinux EXPORT_SYMBOL
+-0xeacc50bc    attribute_container_register    vmlinux EXPORT_SYMBOL_GPL
+-0x53465c39    drm_vblank_count_and_time       vmlinux EXPORT_SYMBOL
+-0xc0e23731    inetpeer_invalidate_tree        vmlinux EXPORT_SYMBOL
+-0x7d1904b2    __neigh_create  vmlinux EXPORT_SYMBOL
+-0x6d294e43    clock_t_to_jiffies      vmlinux EXPORT_SYMBOL
+-0x327bf883    of_can_translate_address        vmlinux EXPORT_SYMBOL
+-0x6232e48e    power_supply_powers     vmlinux EXPORT_SYMBOL_GPL
+-0x15b9125f    hdmi_avi_infoframe_pack vmlinux EXPORT_SYMBOL
+-0x48e7c422    fanout_mutex    vmlinux EXPORT_SYMBOL_GPL
+-0xdf050302    skb_mac_gso_segment     vmlinux EXPORT_SYMBOL
+-0x4afb74d0    snd_pcm_lib_preallocate_pages_for_all   vmlinux EXPORT_SYMBOL
+-0xf874d572    crypto_larval_alloc     vmlinux EXPORT_SYMBOL_GPL
+-0x540a73a6    seq_release     vmlinux EXPORT_SYMBOL
+-0xb3826d47    insert_inode_locked     vmlinux EXPORT_SYMBOL
+-0x1866cec2    ring_buffer_size        vmlinux EXPORT_SYMBOL_GPL
+-0x838b13e7    ring_buffer_free        vmlinux EXPORT_SYMBOL_GPL
+-0x41d8cf05    module_layout   vmlinux EXPORT_SYMBOL
+-0xdbb5a9f5    drm_ht_remove_item      vmlinux EXPORT_SYMBOL
+-0x654a5368    drm_vblank_off  vmlinux EXPORT_SYMBOL
+-0xb3e9e167    drm_vblank_get  vmlinux EXPORT_SYMBOL
+-0xa795c78d    pl330_filter    vmlinux EXPORT_SYMBOL
+-0x0335cb43    __sb_start_write        vmlinux EXPORT_SYMBOL
+-0x6955eb5f    hidinput_disconnect     vmlinux EXPORT_SYMBOL_GPL
+-0xd49dd4f4    cfg80211_cqm_txe_notify vmlinux EXPORT_SYMBOL
+-0xcc1fb551    baswap  vmlinux EXPORT_SYMBOL
+-0x653aa466    __blk_put_request       vmlinux EXPORT_SYMBOL_GPL
+-0x99401626    elv_rb_latter_request   vmlinux EXPORT_SYMBOL
+-0x0da68fbf    sysfs_create_bin_file   vmlinux EXPORT_SYMBOL_GPL
+-0x27fa66e1    nr_free_buffer_pages    vmlinux EXPORT_SYMBOL_GPL
+-0x7452437c    cgroup_taskset_next     vmlinux EXPORT_SYMBOL_GPL
+-0xd2e7fb21    mod_delayed_work_on     vmlinux EXPORT_SYMBOL_GPL
+-0x3d388324    dpm_resume_end  vmlinux EXPORT_SYMBOL_GPL
+-0xfda2fc6f    pinctrl_remove_gpio_range       vmlinux EXPORT_SYMBOL_GPL
+-0x98c9f584    klist_init      vmlinux EXPORT_SYMBOL_GPL
+-0x72e52881    xfrm_state_unregister_afinfo    vmlinux EXPORT_SYMBOL
+-0xec57ea15    snd_card_unref  vmlinux EXPORT_SYMBOL
+-0x6cdc5c6b    nla_strlcpy     vmlinux EXPORT_SYMBOL
+-0xa46f2f1b    kstrtouint      vmlinux EXPORT_SYMBOL
+-0x315c8d71    blk_init_queue_node     vmlinux EXPORT_SYMBOL
+-0x83211609    up_write        vmlinux EXPORT_SYMBOL
+-0x19610e1f    cpu_all_bits    vmlinux EXPORT_SYMBOL
+-0x4f248523    of_find_node_by_name    vmlinux EXPORT_SYMBOL
+-0x14d0738e    dm_noflush_suspending   vmlinux EXPORT_SYMBOL_GPL
+-0x488cee4b    serial8250_do_pm        vmlinux EXPORT_SYMBOL
+-0xe4e38519    tcf_hash_release        vmlinux EXPORT_SYMBOL
+-0xf1298271    free_buffer_head        vmlinux EXPORT_SYMBOL
+-0x08559b9a    fget    vmlinux EXPORT_SYMBOL
+-0x4a57b339    wait_for_completion_io_timeout  vmlinux EXPORT_SYMBOL
+-0xcccd9343    mmc_gpio_get_ro vmlinux EXPORT_SYMBOL
+-0xa3959367    mmc_gpio_get_cd vmlinux EXPORT_SYMBOL
+-0xbc3a2d91    cpufreq_cpu_put vmlinux EXPORT_SYMBOL_GPL
+-0x238dd120    cpufreq_cpu_get vmlinux EXPORT_SYMBOL_GPL
+-0xfe7c6819    scsi_target_block       vmlinux EXPORT_SYMBOL_GPL
+-0x42488405    scsi_prep_state_check   vmlinux EXPORT_SYMBOL
+-0xf4b2e991    drm_mm_put_block        vmlinux EXPORT_SYMBOL
+-0x688bd4c5    snd_ctl_boolean_mono_info       vmlinux EXPORT_SYMBOL
+-0xe1e281d6    jbd2_log_start_commit   vmlinux EXPORT_SYMBOL
+-0x9130f1c7    remove_proc_subtree     vmlinux EXPORT_SYMBOL
+-0xfa1eb910    unregister_syscore_ops  vmlinux EXPORT_SYMBOL_GPL
+-0x4d7f9839    snd_soc_of_parse_card_name      vmlinux EXPORT_SYMBOL_GPL
+-0x44e9a829    match_token     vmlinux EXPORT_SYMBOL
+-0x49b26c63    jbd2_journal_abort      vmlinux EXPORT_SYMBOL
+-0x1a323362    __ftrace_vbprintk       vmlinux EXPORT_SYMBOL_GPL
+-0x0a958ed4    down_write      vmlinux EXPORT_SYMBOL
+-0x706b3a33    cpufreq_frequency_table_get_attr        vmlinux EXPORT_SYMBOL_GPL
+-0xbdba9828    hdmi_audio_infoframe_pack       vmlinux EXPORT_SYMBOL
+-0x09c64fbd    ieee80211_frequency_to_channel  vmlinux EXPORT_SYMBOL
+-0x64d41d38    ip_route_output_flow    vmlinux EXPORT_SYMBOL_GPL
+-0xc23832c5    snd_soc_add_card_controls       vmlinux EXPORT_SYMBOL_GPL
+-0x43326227    posix_test_lock vmlinux EXPORT_SYMBOL
+-0xd7289dfe    kill_block_super        vmlinux EXPORT_SYMBOL
+-0x2b0f3b97    flush_signals   vmlinux EXPORT_SYMBOL
+-0x1b9e0ff1    scsilun_to_int  vmlinux EXPORT_SYMBOL
+-0x97a0de2c    drm_prime_pages_to_sg   vmlinux EXPORT_SYMBOL
+-0x0442abb5    __inet_stream_connect   vmlinux EXPORT_SYMBOL
+-0xc6f7d745    nf_ct_remove_expectations       vmlinux EXPORT_SYMBOL_GPL
+-0xecdea3ba    neigh_lookup_nodev      vmlinux EXPORT_SYMBOL
+-0x10c58227    kernel_setsockopt       vmlinux EXPORT_SYMBOL
+-0x8fd29b0f    kernel_getsockopt       vmlinux EXPORT_SYMBOL
+-0xed5cfaa9    kernel_sock_ioctl       vmlinux EXPORT_SYMBOL
+-0x8ffdb3b8    crc16   vmlinux EXPORT_SYMBOL
+-0xadc7f742    mb_cache_entry_insert   vmlinux EXPORT_SYMBOL
+-0x4e1e8913    kallsyms_on_each_symbol vmlinux EXPORT_SYMBOL_GPL
+-0xf82f3657    work_on_cpu     vmlinux EXPORT_SYMBOL_GPL
+-0x459e133f    v4l2_m2m_get_curr_priv  vmlinux EXPORT_SYMBOL
+-0x4dd51c13    phy_pm_runtime_allow    vmlinux EXPORT_SYMBOL_GPL
+-0xcbbaba0b    nf_tproxy_assign_sock   vmlinux EXPORT_SYMBOL_GPL
+-0x3e220367    nfnetlink_unicast       vmlinux EXPORT_SYMBOL_GPL
+-0x55504881    snd_mixer_oss_ioctl_card        vmlinux EXPORT_SYMBOL
+-0xab694444    bsearch vmlinux EXPORT_SYMBOL
+-0x662edc7c    blk_put_request vmlinux EXPORT_SYMBOL
+-0x6ca4bf88    async_synchronize_full_domain   vmlinux EXPORT_SYMBOL_GPL
+-0x12456a92    iommu_iova_to_phys      vmlinux EXPORT_SYMBOL_GPL
+-0xdc7b411a    dev_pm_qos_hide_latency_limit   vmlinux EXPORT_SYMBOL_GPL
+-0x28441b73    drm_get_last_vbltimestamp       vmlinux EXPORT_SYMBOL
+-0x83eab4ef    crypto_create_tfm       vmlinux EXPORT_SYMBOL_GPL
+-0x42e2c53b    nf_conntrack_in vmlinux EXPORT_SYMBOL_GPL
+-0x3ea1d70f    sock_queue_rcv_skb      vmlinux EXPORT_SYMBOL
+-0xe7820ad2    snd_pcm_lib_preallocate_free_for_all    vmlinux EXPORT_SYMBOL
+-0x754dac78    blk_limits_io_min       vmlinux EXPORT_SYMBOL
+-0x0cd9cfec    sysfs_remove_files      vmlinux EXPORT_SYMBOL_GPL
+-0xc237047a    mapping_tagged  vmlinux EXPORT_SYMBOL
+-0xd777c9b7    iio_device_alloc        vmlinux EXPORT_SYMBOL
+-0xd688716b    dm_kcopyd_client_create vmlinux EXPORT_SYMBOL
+-0x2502c67c    v4l2_fh_add     vmlinux EXPORT_SYMBOL_GPL
+-0x088675f7    usbnet_write_cmd_async  vmlinux EXPORT_SYMBOL_GPL
+-0xb35659de    drm_mode_remove vmlinux EXPORT_SYMBOL
+-0x16acff8a    devm_of_pwm_get vmlinux EXPORT_SYMBOL_GPL
+-0xd2bd22d2    s3c_gpio_getpull        vmlinux EXPORT_SYMBOL
+-0x5fbecd25    s3c_gpio_setpull        vmlinux EXPORT_SYMBOL
+-0x67c2fa54    __copy_to_user  vmlinux EXPORT_SYMBOL
+-0x7c6a49ce    unix_table_lock vmlinux EXPORT_SYMBOL_GPL
+-0x38d60861    put_disk        vmlinux EXPORT_SYMBOL
+-0x871bcaa4    irq_find_host   vmlinux EXPORT_SYMBOL_GPL
+-0xd9605d4c    add_timer       vmlinux EXPORT_SYMBOL
+-0xea97fb5e    usbhid_set_leds vmlinux EXPORT_SYMBOL_GPL
+-0x70915b51    serio_interrupt vmlinux EXPORT_SYMBOL
+-0x92a772c3    usbnet_purge_paused_rxq vmlinux EXPORT_SYMBOL_GPL
+-0xf6bb4729    color_table     vmlinux EXPORT_SYMBOL
+-0x8c637d43    irq_cpu_rmap_add        vmlinux EXPORT_SYMBOL
+-0x9ba7089d    argv_split      vmlinux EXPORT_SYMBOL
+-0x34f3484e    security_tun_dev_attach_queue   vmlinux EXPORT_SYMBOL
+-0x1a1431fd    _raw_spin_unlock_irq    vmlinux EXPORT_SYMBOL
+-0x7c08f605    hid_allocate_device     vmlinux EXPORT_SYMBOL_GPL
+-0xe5a8e6b5    spi_sync        vmlinux EXPORT_SYMBOL_GPL
+-0xcc69f0f8    dma_sync_wait   vmlinux EXPORT_SYMBOL
+-0x43e33157    blk_queue_max_hw_sectors        vmlinux EXPORT_SYMBOL
+-0x8ea0cdd5    drm_add_modes_noedid    vmlinux EXPORT_SYMBOL
+-0x9a8318ef    v7_coherent_kern_range  vmlinux EXPORT_SYMBOL
+-0x5de3ad52    cfg80211_ref_bss        vmlinux EXPORT_SYMBOL
+-0xdc1b2765    crypto_aes_set_key      vmlinux EXPORT_SYMBOL_GPL
+-0x5086ac3a    alg_test        vmlinux EXPORT_SYMBOL_GPL
+-0x9c35fb24    jbd2__journal_restart   vmlinux EXPORT_SYMBOL
+-0xbef43296    console_conditional_schedule    vmlinux EXPORT_SYMBOL
+-0xa71c1b98    bus_set_iommu   vmlinux EXPORT_SYMBOL_GPL
+-0x8e801428    bus_create_file vmlinux EXPORT_SYMBOL_GPL
+-0x8fc34c2d    drm_warn_on_modeset_not_all_locked      vmlinux EXPORT_SYMBOL
+-0x2e0a06e3    snd_unregister_device   vmlinux EXPORT_SYMBOL
+-0x9caaf6cf    blkdev_issue_discard    vmlinux EXPORT_SYMBOL
+-0x3e6444e8    crypto_unregister_pcomp vmlinux EXPORT_SYMBOL_GPL
+-0xc1d19fdd    debugfs_create_symlink  vmlinux EXPORT_SYMBOL_GPL
+-0x9bd7640e    fat_detach      vmlinux EXPORT_SYMBOL_GPL
+-0x698a899f    ring_buffer_peek        vmlinux EXPORT_SYMBOL_GPL
+-0xe2e7840d    regmap_init_mmio_clk    vmlinux EXPORT_SYMBOL_GPL
+-0xe556d687    xt_request_find_match   vmlinux EXPORT_SYMBOL_GPL
+-0xcf25e6b2    xattr_getsecurity       vmlinux EXPORT_SYMBOL_GPL
+-0x6228c21f    smp_call_function_single        vmlinux EXPORT_SYMBOL
+-0x5f324ec1    drm_ioctl       vmlinux EXPORT_SYMBOL
+-0x4d9b652b    rb_erase        vmlinux EXPORT_SYMBOL
+-0xcc71d484    drm_mode_duplicate      vmlinux EXPORT_SYMBOL
+-0x2b02560b    devm_pwm_put    vmlinux EXPORT_SYMBOL_GPL
+-0x3659d5ac    devm_phy_get    vmlinux EXPORT_SYMBOL_GPL
+-0xaafdc258    strcasecmp      vmlinux EXPORT_SYMBOL
+-0xc296567b    save_mount_options      vmlinux EXPORT_SYMBOL
+-0xbade32c7    clockevents_register_device     vmlinux EXPORT_SYMBOL_GPL
+-0xfb8a84a4    drm_mm_get_block_range_generic  vmlinux EXPORT_SYMBOL
+-0x058b582a    vt_get_leds     vmlinux EXPORT_SYMBOL_GPL
+-0xb2a0603e    nci_recv_frame  vmlinux EXPORT_SYMBOL
+-0xc0240dd4    nf_conntrack_set_hashsize       vmlinux EXPORT_SYMBOL_GPL
+-0x45c8cd86    ifla_policy     vmlinux EXPORT_SYMBOL
+-0xd251d7b0    security_socket_getpeersec_dgram        vmlinux EXPORT_SYMBOL
+-0xf05e203c    set_blocksize   vmlinux EXPORT_SYMBOL
+-0xc1c995a0    block_page_mkwrite      vmlinux EXPORT_SYMBOL
+-0x85b9e216    set_timer_slack vmlinux EXPORT_SYMBOL_GPL
+-0x2665c0a3    vb2_qbuf        vmlinux EXPORT_SYMBOL_GPL
+-0x9abe8d18    video_usercopy  vmlinux EXPORT_SYMBOL
+-0x1d93e603    tty_unthrottle  vmlinux EXPORT_SYMBOL
+-0x1142511d    crypto_spawn_tfm        vmlinux EXPORT_SYMBOL_GPL
+-0xeb9ddf6d    security_inode_notifysecctx     vmlinux EXPORT_SYMBOL
+-0x68df960a    generic_error_remove_page       vmlinux EXPORT_SYMBOL
+-0x7000dc34    class_compat_remove_link        vmlinux EXPORT_SYMBOL_GPL
+-0x816dee03    uart_unregister_driver  vmlinux EXPORT_SYMBOL
+-0x0acf7679    dma_issue_pending_all   vmlinux EXPORT_SYMBOL
+-0x8792d764    l2cap_conn_get  vmlinux EXPORT_SYMBOL
+-0xcf2890b2    ipv6_chk_prefix vmlinux EXPORT_SYMBOL
+-0x616ff33b    ip6_dst_lookup_flow     vmlinux EXPORT_SYMBOL_GPL
+-0x3e963d19    inet_csk_search_req     vmlinux EXPORT_SYMBOL_GPL
+-0xdd632e58    inet_unhash     vmlinux EXPORT_SYMBOL_GPL
+-0x98e40edf    nf_ct_nat_offset        vmlinux EXPORT_SYMBOL_GPL
+-0x0a7ed556    blk_execute_rq  vmlinux EXPORT_SYMBOL
+-0x44408a4a    mdio_bus_type   vmlinux EXPORT_SYMBOL
+-0xac74a2a9    ip6_xmit        vmlinux EXPORT_SYMBOL
+-0x411d75db    ip_tunnel_init  vmlinux EXPORT_SYMBOL_GPL
+-0x7a442539    tcf_exts_dump   vmlinux EXPORT_SYMBOL
+-0x13307fde    vsscanf vmlinux EXPORT_SYMBOL
+-0xcc368515    jbd2_journal_unlock_updates     vmlinux EXPORT_SYMBOL
+-0x21bfb720    seq_open_net    vmlinux EXPORT_SYMBOL_GPL
+-0x82d79b51    sysctl_vfs_cache_pressure       vmlinux EXPORT_SYMBOL_GPL
+-0x04486e88    rcu_batches_completed   vmlinux EXPORT_SYMBOL_GPL
+-0x7c1372e8    panic   vmlinux EXPORT_SYMBOL
+-0x9808f34e    dev_pm_qos_expose_flags vmlinux EXPORT_SYMBOL_GPL
+-0x544b5ea8    pwm_disable     vmlinux EXPORT_SYMBOL_GPL
+-0x5c265cba    sg_init_one     vmlinux EXPORT_SYMBOL
+-0x12da5bb2    __kmalloc       vmlinux EXPORT_SYMBOL
+-0x28d6861d    __vmalloc       vmlinux EXPORT_SYMBOL
+-0x5db7b0d3    led_trigger_remove      vmlinux EXPORT_SYMBOL_GPL
+-0x83b38ee6    kobject_init_and_add    vmlinux EXPORT_SYMBOL_GPL
+-0x757cdadf    usbnet_get_ethernet_addr        vmlinux EXPORT_SYMBOL_GPL
+-0x43a286d1    drm_prime_remove_buf_handle     vmlinux EXPORT_SYMBOL
+-0xea8ddd89    __ip_select_ident       vmlinux EXPORT_SYMBOL
+-0x1f984870    skb_gro_receive vmlinux EXPORT_SYMBOL_GPL
+-0x48f8aa53    flock_lock_file_wait    vmlinux EXPORT_SYMBOL
+-0x05e067d7    __media_entity_remove_links     vmlinux EXPORT_SYMBOL_GPL
+-0xe7cb87e4    xt_find_match   vmlinux EXPORT_SYMBOL
+-0x9d62c35b    nfq_ct_hook     vmlinux EXPORT_SYMBOL_GPL
+-0xe12b4adb    __skb_warn_lro_forwarding       vmlinux EXPORT_SYMBOL
+-0x471eeac6    snd_soc_platform_write  vmlinux EXPORT_SYMBOL_GPL
+-0x71c90087    memcmp  vmlinux EXPORT_SYMBOL
+-0x4881d505    idr_for_each    vmlinux EXPORT_SYMBOL
+-0x79b33953    shash_ahash_digest      vmlinux EXPORT_SYMBOL_GPL
+-0xcf1d92aa    locks_init_lock vmlinux EXPORT_SYMBOL
+-0x11cfbadb    bio_add_pc_page vmlinux EXPORT_SYMBOL
+-0x2917e251    split_page      vmlinux EXPORT_SYMBOL_GPL
+-0xda53403f    v4l2_m2m_ctx_init       vmlinux EXPORT_SYMBOL_GPL
+-0x4f4d910e    regmap_init     vmlinux EXPORT_SYMBOL_GPL
+-0xb2a9634b    regmap_exit     vmlinux EXPORT_SYMBOL_GPL
+-0xe16838c2    drm_mm_search_free_in_range_generic     vmlinux EXPORT_SYMBOL
+-0xf05ffa15    fb_var_to_videomode     vmlinux EXPORT_SYMBOL
+-0xab707907    inet6_del_offload       vmlinux EXPORT_SYMBOL
+-0x13e229c2    nf_ct_helper_expectfn_find_by_name      vmlinux EXPORT_SYMBOL_GPL
+-0x1f0547c1    netif_stacked_transfer_operstate        vmlinux EXPORT_SYMBOL
+-0xd435e67a    snd_card_set_id vmlinux EXPORT_SYMBOL
+-0xc7236f77    d_alloc_name    vmlinux EXPORT_SYMBOL
+-0x2f3857e2    _raw_write_lock_irqsave vmlinux EXPORT_SYMBOL
+-0x37c199e6    serio_reconnect vmlinux EXPORT_SYMBOL
+-0x6754f715    drm_fb_helper_fill_fix  vmlinux EXPORT_SYMBOL
+-0xc6df7ef6    cont_write_begin        vmlinux EXPORT_SYMBOL
+-0x1c97e3ec    vfs_readdir     vmlinux EXPORT_SYMBOL
+-0xbdd295f0    trace_vprintk   vmlinux EXPORT_SYMBOL_GPL
+-0x8faa4598    of_translate_address    vmlinux EXPORT_SYMBOL
+-0x0699040f    drm_encoder_cleanup     vmlinux EXPORT_SYMBOL
+-0x7f8c7b48    dma_async_memcpy_buf_to_buf     vmlinux EXPORT_SYMBOL
+-0x1ed85a8d    pinctrl_dev_get_drvdata vmlinux EXPORT_SYMBOL_GPL
+-0x881039d0    zlib_inflate    vmlinux EXPORT_SYMBOL
+-0x3771b461    crc_ccitt       vmlinux EXPORT_SYMBOL
+-0xa43b1297    vscnprintf      vmlinux EXPORT_SYMBOL
+-0x166e361d    blk_recount_segments    vmlinux EXPORT_SYMBOL
+-0x887ece4a    simple_statfs   vmlinux EXPORT_SYMBOL
+-0x617643a2    param_set_long  vmlinux EXPORT_SYMBOL
+-0x6c69a9be    xfrm6_tunnel_deregister vmlinux EXPORT_SYMBOL
+-0x3b850073    km_policy_notify        vmlinux EXPORT_SYMBOL
+-0x10cc1e43    xfrm4_tunnel_deregister vmlinux EXPORT_SYMBOL
+-0xc0f95b9e    ip_mc_join_group        vmlinux EXPORT_SYMBOL
+-0xdb760f52    __kfifo_free    vmlinux EXPORT_SYMBOL
+-0x3a288321    configfs_undepend_item  vmlinux EXPORT_SYMBOL
+-0x2cc83b45    usb_string      vmlinux EXPORT_SYMBOL_GPL
+-0x98442d13    inet_csk_reqsk_queue_hash_add   vmlinux EXPORT_SYMBOL_GPL
+-0x8d33679f    nf_ct_unexpect_related  vmlinux EXPORT_SYMBOL_GPL
+-0xe6e1c5fe    uuid_be_gen     vmlinux EXPORT_SYMBOL_GPL
+-0x289ea691    debugfs_remove  vmlinux EXPORT_SYMBOL_GPL
+-0xbb4e9599    lease_modify    vmlinux EXPORT_SYMBOL
+-0x2fb6e20e    drop_nlink      vmlinux EXPORT_SYMBOL
+-0xdfaa6b6b    v4l2_ctrl_radio_filter  vmlinux EXPORT_SYMBOL
+-0xa3675712    xfrm_dst_ifdown vmlinux EXPORT_SYMBOL
+-0x0d9bae4b    nf_nat_l4proto_nlattr_to_range  vmlinux EXPORT_SYMBOL_GPL
+-0xc17f8f83    neigh_seq_start vmlinux EXPORT_SYMBOL
+-0x6e7943ec    iommu_group_id  vmlinux EXPORT_SYMBOL_GPL
+-0x1aef1e27    eth_header_cache_update vmlinux EXPORT_SYMBOL
+-0xd800dc59    snd_pcm_hw_constraint_ratdens   vmlinux EXPORT_SYMBOL
+-0xd1157735    release_and_free_resource       vmlinux EXPORT_SYMBOL
+-0xb31526ee    sg_copy_from_buffer     vmlinux EXPORT_SYMBOL
+-0x73e20c1c    strlcpy vmlinux EXPORT_SYMBOL
+-0x328a05f1    strncpy vmlinux EXPORT_SYMBOL
+-0x8abacc47    get_max_files   vmlinux EXPORT_SYMBOL_GPL
+-0xae0f6b4e    regulator_unregister_notifier   vmlinux EXPORT_SYMBOL_GPL
+-0x386f5a4e    tcf_em_tree_destroy     vmlinux EXPORT_SYMBOL
+-0x97b4500c    __tracepoint_kmem_cache_free    vmlinux EXPORT_SYMBOL
+-0x4a69690c    scsi_release_buffers    vmlinux EXPORT_SYMBOL
+-0xf195c682    fb_invert_cmaps vmlinux EXPORT_SYMBOL
+-0xab156bb5    kern_mount_data vmlinux EXPORT_SYMBOL_GPL
+-0x1902f934    __init_kthread_worker   vmlinux EXPORT_SYMBOL_GPL
+-0xdac0df4a    driver_create_file      vmlinux EXPORT_SYMBOL_GPL
+-0x083eb21c    rfkill_unregister       vmlinux EXPORT_SYMBOL
+-0x3e52c876    blk_requeue_request     vmlinux EXPORT_SYMBOL
+-0xdca5d880    insert_inode_locked4    vmlinux EXPORT_SYMBOL
+-0x41482d8b    strndup_user    vmlinux EXPORT_SYMBOL
+-0xddd58dc0    ring_buffer_reset       vmlinux EXPORT_SYMBOL_GPL
+-0x6b172795    media_entity_graph_walk_next    vmlinux EXPORT_SYMBOL_GPL
+-0x0591a4d1    usb_ep_autoconfig_ss    vmlinux EXPORT_SYMBOL_GPL
+-0x4b076147    uncache_firmware        vmlinux EXPORT_SYMBOL_GPL
+-0x098b71c6    fb_dealloc_cmap vmlinux EXPORT_SYMBOL
+-0x83d1444a    crypto_init_spawn       vmlinux EXPORT_SYMBOL_GPL
+-0x60061dd7    mount_nodev     vmlinux EXPORT_SYMBOL
+-0x7bb32751    pagevec_lookup  vmlinux EXPORT_SYMBOL
+-0x47b6a10f    ftrace_print_symbols_seq        vmlinux EXPORT_SYMBOL
+-0x8664f62e    cpufreq_update_policy   vmlinux EXPORT_SYMBOL
+-0x29f39077    pwmchip_remove  vmlinux EXPORT_SYMBOL_GPL
+-0x905baf48    xfrm_find_acq   vmlinux EXPORT_SYMBOL
+-0x9487bc19    eth_mac_addr    vmlinux EXPORT_SYMBOL
+-0xad1ed84c    unregister_hw_breakpoint        vmlinux EXPORT_SYMBOL_GPL
+-0x993805c1    scsi_scan_host  vmlinux EXPORT_SYMBOL
+-0x7a77dfe4    scsi_setup_fs_cmnd      vmlinux EXPORT_SYMBOL
+-0xbbc9fd6e    cfg80211_wext_siwfrag   vmlinux EXPORT_SYMBOL_GPL
+-0x82c82c32    cfg80211_wext_giwfrag   vmlinux EXPORT_SYMBOL_GPL
+-0xe80dd06a    tcp_sendpage    vmlinux EXPORT_SYMBOL
+-0x47b3f862    radix_tree_lookup_slot  vmlinux EXPORT_SYMBOL
+-0x91621d6a    allocate_resource       vmlinux EXPORT_SYMBOL
+-0xb98a0185    rtc_tm_to_time  vmlinux EXPORT_SYMBOL
+-0xe5883bd9    class_compat_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x7bf9c108    serial8250_rx_dma       vmlinux EXPORT_SYMBOL_GPL
+-0xc7856a3d    inet6addr_notifier_call_chain   vmlinux EXPORT_SYMBOL
+-0xc08647ff    ring_buffer_bytes_cpu   vmlinux EXPORT_SYMBOL_GPL
+-0xcbbf0a6f    audit_log_task_context  vmlinux EXPORT_SYMBOL
+-0x0a0ab757    pm_schedule_suspend     vmlinux EXPORT_SYMBOL_GPL
+-0x617ae32f    of_get_display_timings  vmlinux EXPORT_SYMBOL_GPL
+-0xe442a492    splice_from_pipe_feed   vmlinux EXPORT_SYMBOL
+-0xf9a054b5    __round_jiffies vmlinux EXPORT_SYMBOL_GPL
+-0x38e20383    hid_alloc_report_buf    vmlinux EXPORT_SYMBOL_GPL
+-0x626ffd48    spi_write_then_read     vmlinux EXPORT_SYMBOL_GPL
+-0x7b5fc447    pinctrl_lookup_state    vmlinux EXPORT_SYMBOL_GPL
+-0x8c49e9fe    cfg80211_conn_failed    vmlinux EXPORT_SYMBOL
+-0x03c06156    bitmap_fold     vmlinux EXPORT_SYMBOL
+-0x04d5a096    security_sb_clone_mnt_opts      vmlinux EXPORT_SYMBOL
+-0x424b2fdf    vfs_rmdir       vmlinux EXPORT_SYMBOL
+-0x52856d8e    generic_shutdown_super  vmlinux EXPORT_SYMBOL
+-0xbd10541e    css_lookup      vmlinux EXPORT_SYMBOL_GPL
+-0x37e74642    get_jiffies_64  vmlinux EXPORT_SYMBOL
+-0xb8117014    cfg80211_rx_spurious_frame      vmlinux EXPORT_SYMBOL
+-0x790c2d9c    netdev_master_upper_dev_link    vmlinux EXPORT_SYMBOL
+-0x02a6ce5a    crc16_table     vmlinux EXPORT_SYMBOL
+-0xe280ea92    init_buffer     vmlinux EXPORT_SYMBOL
+-0xf21e1f9b    disable_percpu_irq      vmlinux EXPORT_SYMBOL_GPL
+-0xb5ae5758    scsi_track_queue_full   vmlinux EXPORT_SYMBOL
+-0xa26b1ba8    exynos_drm_device_register      vmlinux EXPORT_SYMBOL_GPL
+-0xbe55cd3e    __sock_recv_ts_and_drops        vmlinux EXPORT_SYMBOL_GPL
+-0xcedd3329    jbd2__journal_start     vmlinux EXPORT_SYMBOL
+-0x838a3169    pm_qos_request_active   vmlinux EXPORT_SYMBOL_GPL
+-0xbf7fd2f5    schedule_timeout_killable       vmlinux EXPORT_SYMBOL
+-0xd9c4cec4    sock_no_getname vmlinux EXPORT_SYMBOL
+-0x24678be3    snd_pcm_lib_readv       vmlinux EXPORT_SYMBOL
+-0x292a0b74    vfs_link        vmlinux EXPORT_SYMBOL
+-0x85050965    __irq_alloc_descs       vmlinux EXPORT_SYMBOL_GPL
+-0xe3e7dba0    from_kuid_munged        vmlinux EXPORT_SYMBOL
+-0x582bb484    call_usermodehelper_setup       vmlinux EXPORT_SYMBOL
+-0xe52c5e63    v4l2_event_subscribe    vmlinux EXPORT_SYMBOL_GPL
+-0xcd0fc417    drm_ht_just_insert_please       vmlinux EXPORT_SYMBOL
+-0xdacbc24d    netlink_rcv_skb vmlinux EXPORT_SYMBOL
+-0x33d23d14    sk_unattached_filter_create     vmlinux EXPORT_SYMBOL_GPL
+-0x1f07ae8f    crypto_alloc_pcomp      vmlinux EXPORT_SYMBOL_GPL
+-0x2447533c    ktime_get_real  vmlinux EXPORT_SYMBOL_GPL
+-0x68869bae    panic_notifier_list     vmlinux EXPORT_SYMBOL
+-0xdae1eb6a    of_clk_src_onecell_get  vmlinux EXPORT_SYMBOL_GPL
+-0x3444d892    phy_driver_unregister   vmlinux EXPORT_SYMBOL
+-0x107b31ec    __xfrm_state_delete     vmlinux EXPORT_SYMBOL
+-0x4e6165cf    d_delete        vmlinux EXPORT_SYMBOL
+-0x5f0e672b    find_get_pages_tag      vmlinux EXPORT_SYMBOL
+-0xc8fd727e    mod_timer       vmlinux EXPORT_SYMBOL
+-0xd2fe47b1    rndis_set_host_mac      vmlinux EXPORT_SYMBOL
+-0xd768e985    regulator_has_full_constraints  vmlinux EXPORT_SYMBOL_GPL
+-0x82f776b7    gpio_export     vmlinux EXPORT_SYMBOL_GPL
+-0xdf401846    idr_remove      vmlinux EXPORT_SYMBOL
+-0x29baff70    ida_remove      vmlinux EXPORT_SYMBOL
+-0x220b4b23    mnt_set_expiry  vmlinux EXPORT_SYMBOL
+-0x3dd9c200    use_mm  vmlinux EXPORT_SYMBOL_GPL
+-0x2d41e6f5    __trace_puts    vmlinux EXPORT_SYMBOL_GPL
+-0x5143c678    param_get_invbool       vmlinux EXPORT_SYMBOL
+-0x914a1c17    ip_tunnel_newlink       vmlinux EXPORT_SYMBOL_GPL
+-0xc5b6b555    genl_notify     vmlinux EXPORT_SYMBOL
+-0xada52470    wm_hubs_hpl_mux vmlinux EXPORT_SYMBOL_GPL
+-0x9393c812    add_page_wait_queue     vmlinux EXPORT_SYMBOL_GPL
+-0xb16abad2    devm_rtc_device_register        vmlinux EXPORT_SYMBOL_GPL
+-0xbd92ef65    devres_destroy  vmlinux EXPORT_SYMBOL_GPL
+-0x1297fa08    tty_hangup      vmlinux EXPORT_SYMBOL
+-0x580c94d2    seq_put_decimal_ll      vmlinux EXPORT_SYMBOL
+-0xb22596e0    devm_rtc_device_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0x1b95d5c1    mdiobus_read    vmlinux EXPORT_SYMBOL
+-0xea59b757    pm_runtime_forbid       vmlinux EXPORT_SYMBOL_GPL
+-0x30e74134    tty_termios_copy_hw     vmlinux EXPORT_SYMBOL
+-0x4455e1b3    regulator_disable_deferred      vmlinux EXPORT_SYMBOL_GPL
+-0x8e322129    dma_release_channel     vmlinux EXPORT_SYMBOL_GPL
+-0xcfd9a2c0    des_ekey        vmlinux EXPORT_SYMBOL_GPL
+-0x66c78bd2    irq_domain_remove       vmlinux EXPORT_SYMBOL_GPL
+-0x640c2da8    devm_clk_get    vmlinux EXPORT_SYMBOL
+-0xd02c73c7    drm_dp_link_train_clock_recovery_delay  vmlinux EXPORT_SYMBOL
+-0x2be0f12d    dql_completed   vmlinux EXPORT_SYMBOL
+-0xad3f5f91    read_cache_page vmlinux EXPORT_SYMBOL
+-0x4ca90996    rndis_signal_disconnect vmlinux EXPORT_SYMBOL
+-0x917229dc    drm_irq_install vmlinux EXPORT_SYMBOL
+-0x787bcffe    con_is_bound    vmlinux EXPORT_SYMBOL
+-0xefb6eb3f    dev_change_flags        vmlinux EXPORT_SYMBOL
+-0x0e352145    __skb_gso_segment       vmlinux EXPORT_SYMBOL
+-0xa5d14a5e    xfrm_state_walk vmlinux EXPORT_SYMBOL
+-0x6a0ae2ec    nla_put_nohdr   vmlinux EXPORT_SYMBOL
+-0x0411124a    pid_nr_ns       vmlinux EXPORT_SYMBOL_GPL
+-0x2133271d    phy_scan_fixups vmlinux EXPORT_SYMBOL
+-0x64d233c8    ioremap_page    vmlinux EXPORT_SYMBOL
+-0x8fea24bd    bt_sock_unregister      vmlinux EXPORT_SYMBOL
+-0x16c3cf65    napi_gro_flush  vmlinux EXPORT_SYMBOL
+-0xf001dc80    irq_domain_add_linear   vmlinux EXPORT_SYMBOL_GPL
+-0xec069709    scsi_set_medium_removal vmlinux EXPORT_SYMBOL
+-0xc0a98385    profile_pc      vmlinux EXPORT_SYMBOL
+-0x79a2f120    snd_timer_resolution    vmlinux EXPORT_SYMBOL
+-0x46c67b94    jbd2_journal_wipe       vmlinux EXPORT_SYMBOL
+-0x444f1735    cpu_pm_register_notifier        vmlinux EXPORT_SYMBOL_GPL
+-0xcc85fcb6    async_schedule  vmlinux EXPORT_SYMBOL_GPL
+-0x9caf61d6    __nla_put       vmlinux EXPORT_SYMBOL
+-0x4c2ae700    strnstr vmlinux EXPORT_SYMBOL
+-0x07bf12c5    perf_pmu_migrate_context        vmlinux EXPORT_SYMBOL_GPL
+-0x4268de2e    __css_put       vmlinux EXPORT_SYMBOL_GPL
+-0x32fdb1ea    usb_block_urb   vmlinux EXPORT_SYMBOL_GPL
+-0xd76e3ec9    fb_set_var      vmlinux EXPORT_SYMBOL
+-0x7c0643d0    inet_diag_register      vmlinux EXPORT_SYMBOL_GPL
+-0x598542b2    _raw_spin_lock_irqsave  vmlinux EXPORT_SYMBOL
+-0xd468cd0b    sdhci_pltfm_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0x44f93f86    vb2_ops_wait_finish     vmlinux EXPORT_SYMBOL_GPL
+-0x5be57447    dma_buf_kmap_atomic     vmlinux EXPORT_SYMBOL_GPL
+-0xfac68eba    arm_elf_read_implies_exec       vmlinux EXPORT_SYMBOL
+-0xca1e6f11    tcp_done        vmlinux EXPORT_SYMBOL_GPL
+-0x885f07c4    snd_pcm_hw_rule_add     vmlinux EXPORT_SYMBOL
+-0xb1c0c1c2    async_schedule_domain   vmlinux EXPORT_SYMBOL_GPL
+-0x65497c9a    wm8994_bulk_write       vmlinux EXPORT_SYMBOL_GPL
+-0x2fb6de5d    add_device_randomness   vmlinux EXPORT_SYMBOL
+-0xda8af7ad    fb_find_nearest_mode    vmlinux EXPORT_SYMBOL
+-0x0a575945    xfrm_count_pfkey_auth_supported vmlinux EXPORT_SYMBOL_GPL
+-0x3b91f3af    snd_free_pages  vmlinux EXPORT_SYMBOL
+-0xdf2278c1    snd_card_file_remove    vmlinux EXPORT_SYMBOL
+-0xc848d220    blk_free_tags   vmlinux EXPORT_SYMBOL
+-0xff492454    security_inode_getsecctx        vmlinux EXPORT_SYMBOL
+-0xce46e140    ktime_get_ts    vmlinux EXPORT_SYMBOL_GPL
+-0x3b0d157a    v4l2_m2m_ioctl_querybuf vmlinux EXPORT_SYMBOL_GPL
+-0x054177ad    usb_init_urb    vmlinux EXPORT_SYMBOL_GPL
+-0x1ad1f2e7    _memcpy_fromio  vmlinux EXPORT_SYMBOL
+-0x95dbe078    __get_user_2    vmlinux EXPORT_SYMBOL
+-0xb9acd3d9    __put_user_2    vmlinux EXPORT_SYMBOL
+-0xf3797152    snd_interval_ratnum     vmlinux EXPORT_SYMBOL
+-0x9d2edcd6    map_vm_area     vmlinux EXPORT_SYMBOL_GPL
+-0xbfd8d187    balloon_page_enqueue    vmlinux EXPORT_SYMBOL_GPL
+-0xb7e3198c    balloon_page_dequeue    vmlinux EXPORT_SYMBOL_GPL
+-0x0084e86d    unregister_shrinker     vmlinux EXPORT_SYMBOL
+-0x23424fab    usb_hcd_unmap_urb_setup_for_dma vmlinux EXPORT_SYMBOL_GPL
+-0x6c06c6f7    scsi_device_get vmlinux EXPORT_SYMBOL
+-0x970b4c98    scsi_device_put vmlinux EXPORT_SYMBOL
+-0x66109b05    __pm_runtime_set_status vmlinux EXPORT_SYMBOL_GPL
+-0x6d134a2a    drm_prime_sg_to_page_addr_arrays        vmlinux EXPORT_SYMBOL
+-0xbce458b3    drm_framebuffer_reference       vmlinux EXPORT_SYMBOL
+-0xa773e935    ipv6_dev_get_saddr      vmlinux EXPORT_SYMBOL
+-0x38308727    xfrm_policy_flush       vmlinux EXPORT_SYMBOL
+-0x6ebf58d8    skb_tx_error    vmlinux EXPORT_SYMBOL
+-0xea793efe    snd_soc_cache_sync      vmlinux EXPORT_SYMBOL_GPL
+-0xb8aa2342    __check_region  vmlinux EXPORT_SYMBOL
+-0x99638333    mmc_set_blocklen        vmlinux EXPORT_SYMBOL
+-0xc5e4da95    pn_sock_hash    vmlinux EXPORT_SYMBOL
+-0xf6388c56    sysctl_ip_default_ttl   vmlinux EXPORT_SYMBOL
+-0x0e7c2436    napi_gro_frags  vmlinux EXPORT_SYMBOL
+-0x217dda13    flex_array_get  vmlinux EXPORT_SYMBOL
+-0x09437748    ring_buffer_read_events_cpu     vmlinux EXPORT_SYMBOL_GPL
+-0xb974ccc1    inet_diag_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0x0423031f    sock_sendmsg    vmlinux EXPORT_SYMBOL
+-0xade88e76    snd_malloc_pages        vmlinux EXPORT_SYMBOL
+-0x7ca50cfa    disk_get_part   vmlinux EXPORT_SYMBOL_GPL
+-0xfed4d591    cfg80211_find_vendor_ie vmlinux EXPORT_SYMBOL
+-0xe45ee6f0    netlink_kernel_release  vmlinux EXPORT_SYMBOL
+-0xf310e4d9    __sock_create   vmlinux EXPORT_SYMBOL
+-0x4153512b    snd_hwdep_new   vmlinux EXPORT_SYMBOL
+-0x1afae5e7    down_interruptible      vmlinux EXPORT_SYMBOL
+-0x2051f1d8    rtc_set_mmss    vmlinux EXPORT_SYMBOL_GPL
+-0x23dfa3ab    netif_carrier_off       vmlinux EXPORT_SYMBOL
+-0x10895a2a    lease_get_mtime vmlinux EXPORT_SYMBOL
+-0x7cd8f487    sb_set_blocksize        vmlinux EXPORT_SYMBOL
+-0x0effeb6c    srcu_barrier    vmlinux EXPORT_SYMBOL_GPL
+-0xf3de55df    mmc_request_done        vmlinux EXPORT_SYMBOL
+-0x46074c17    sdev_evt_alloc  vmlinux EXPORT_SYMBOL_GPL
+-0x17077530    pinctrl_force_default   vmlinux EXPORT_SYMBOL_GPL
+-0x0d40713a    snd_ctl_boolean_stereo_info     vmlinux EXPORT_SYMBOL
+-0x3744cf36    vmalloc_to_pfn  vmlinux EXPORT_SYMBOL
+-0xc783b0e1    get_task_mm     vmlinux EXPORT_SYMBOL_GPL
+-0xa8950567    sdio_writew     vmlinux EXPORT_SYMBOL_GPL
+-0xca443371    inet_csk_prepare_forced_close   vmlinux EXPORT_SYMBOL
+-0x252f76b5    snd_soc_default_readable_register       vmlinux EXPORT_SYMBOL_GPL
+-0x551bd071    __rb_erase_color        vmlinux EXPORT_SYMBOL
+-0xfff8d451    fuse_request_send       vmlinux EXPORT_SYMBOL_GPL
+-0x88b5647c    trace_clock_local       vmlinux EXPORT_SYMBOL_GPL
+-0x683928de    nf_ct_expect_put        vmlinux EXPORT_SYMBOL_GPL
+-0x7c96bf14    register_tcf_proto_ops  vmlinux EXPORT_SYMBOL
+-0x76aea351    crypto_unregister_alg   vmlinux EXPORT_SYMBOL_GPL
+-0x5c24f853    dump_write      vmlinux EXPORT_SYMBOL
+-0x89485687    iommu_group_put vmlinux EXPORT_SYMBOL_GPL
+-0x00f4d0cf    iommu_group_get vmlinux EXPORT_SYMBOL_GPL
+-0xb4626765    v4l2_ctrl_new_custom    vmlinux EXPORT_SYMBOL
+-0x511746c1    dump_fpu        vmlinux EXPORT_SYMBOL
+-0x28927989    qdisc_watchdog_schedule_ns      vmlinux EXPORT_SYMBOL
+-0x57fec35a    fuse_conn_get   vmlinux EXPORT_SYMBOL_GPL
+-0xff3f1877    filp_open       vmlinux EXPORT_SYMBOL
+-0x7cb7e8a5    generic_file_aio_write  vmlinux EXPORT_SYMBOL
+-0x1d9317d8    smpboot_register_percpu_thread  vmlinux EXPORT_SYMBOL_GPL
+-0x426362dc    __class_create  vmlinux EXPORT_SYMBOL_GPL
+-0xebd6ff6e    xfrm6_prepare_output    vmlinux EXPORT_SYMBOL
+-0x7c30b8c7    xfrm_calg_get_byname    vmlinux EXPORT_SYMBOL_GPL
+-0xf23624a6    xfrm4_prepare_output    vmlinux EXPORT_SYMBOL
+-0x6e88e56f    snd_pcm_link_rwlock     vmlinux EXPORT_SYMBOL
+-0x2ebe3135    cpu_is_hotpluggable     vmlinux EXPORT_SYMBOL_GPL
+-0xd3dbfbc4    _find_first_zero_bit_le vmlinux EXPORT_SYMBOL
+-0x949f7fd6    snd_soc_unregister_codec        vmlinux EXPORT_SYMBOL_GPL
+-0x66b5d30a    get_disk        vmlinux EXPORT_SYMBOL
+-0xd5c3ad66    blk_pm_runtime_init     vmlinux EXPORT_SYMBOL
+-0x55737546    __free_pages    vmlinux EXPORT_SYMBOL
+-0xfa012fe7    tracepoint_probe_register       vmlinux EXPORT_SYMBOL_GPL
+-0xf8802492    print_stack_trace       vmlinux EXPORT_SYMBOL_GPL
+-0x50601122    of_property_match_string        vmlinux EXPORT_SYMBOL_GPL
+-0x70fde9b2    vb2_reqbufs     vmlinux EXPORT_SYMBOL_GPL
+-0x9b680a42    ump_dd_reference_release        vmlinux EXPORT_SYMBOL
+-0x13d5d619    cfg80211_crit_proto_stopped     vmlinux EXPORT_SYMBOL
+-0xd5a7d477    inet_bind       vmlinux EXPORT_SYMBOL
+-0xc5495840    nf_nat_amanda_hook      vmlinux EXPORT_SYMBOL_GPL
+-0xe08e58c9    qdisc_watchdog_init     vmlinux EXPORT_SYMBOL
+-0xe447fb89    __register_binfmt       vmlinux EXPORT_SYMBOL
+-0xbd3321ae    power_supply_class      vmlinux EXPORT_SYMBOL_GPL
+-0x0ce6d0b9    usb_gadget_probe_driver vmlinux EXPORT_SYMBOL_GPL
+-0xae544f3a    usb_hcd_end_port_resume vmlinux EXPORT_SYMBOL_GPL
+-0x8fd8a453    pm_genpd_dev_need_restore       vmlinux EXPORT_SYMBOL_GPL
+-0x7b95ab7d    class_find_device       vmlinux EXPORT_SYMBOL_GPL
+-0x21455002    xfrm_init_state vmlinux EXPORT_SYMBOL
+-0xf06e724d    snd_pcm_debug_name      vmlinux EXPORT_SYMBOL
+-0x89ca47bf    kstrtos8_from_user      vmlinux EXPORT_SYMBOL
+-0x68d0d389    crypto_init_spawn2      vmlinux EXPORT_SYMBOL_GPL
+-0x01c6cb0c    cpu_cluster_pm_enter    vmlinux EXPORT_SYMBOL_GPL
+-0xd1efa60f    st_accel_common_remove  vmlinux EXPORT_SYMBOL
+-0xf398c9eb    vb2_create_bufs vmlinux EXPORT_SYMBOL_GPL
+-0xc385cb58    perf_num_counters       vmlinux EXPORT_SYMBOL_GPL
+-0x87634adf    xfrm_user_policy        vmlinux EXPORT_SYMBOL
+-0xe0741a0a    netif_napi_add  vmlinux EXPORT_SYMBOL
+-0xf12cddd6    skb_split       vmlinux EXPORT_SYMBOL
+-0xdee12a28    input_grab_device       vmlinux EXPORT_SYMBOL
+-0x95e73973    tty_port_block_til_ready        vmlinux EXPORT_SYMBOL
+-0x53a3e486    regulator_get_current_limit     vmlinux EXPORT_SYMBOL_GPL
+-0x5dd18380    regulator_get_init_drvdata      vmlinux EXPORT_SYMBOL_GPL
+-0x8467a73f    netlink_broadcast       vmlinux EXPORT_SYMBOL
+-0x6d1a8997    block_write_full_page_endio     vmlinux EXPORT_SYMBOL
+-0x197519cc    shmem_file_setup        vmlinux EXPORT_SYMBOL_GPL
+-0x8b8059bd    in_group_p      vmlinux EXPORT_SYMBOL
+-0xc631580a    console_unlock  vmlinux EXPORT_SYMBOL
+-0xe8400441    of_property_read_string_index   vmlinux EXPORT_SYMBOL_GPL
+-0x0343bdf1    __i2c_board_list        vmlinux EXPORT_SYMBOL_GPL
+-0xa5dd6fae    arm_pm_restart  vmlinux EXPORT_SYMBOL_GPL
+-0x97fe8a2d    udp_sendmsg     vmlinux EXPORT_SYMBOL
+-0x35fbd6a1    __kfifo_dma_out_prepare_r       vmlinux EXPORT_SYMBOL
+-0xa3e220e7    elv_rb_former_request   vmlinux EXPORT_SYMBOL
+-0xdf76bbeb    iio_pollfunc_store_time vmlinux EXPORT_SYMBOL
+-0xfc30d3a1    mmc_start_req   vmlinux EXPORT_SYMBOL
+-0xf53d4c26    qdisc_class_hash_destroy        vmlinux EXPORT_SYMBOL
+-0x5e61da38    snd_timer_stop  vmlinux EXPORT_SYMBOL
+-0xa6e1a69d    kick_all_cpus_sync      vmlinux EXPORT_SYMBOL_GPL
+-0x68cb9861    sdio_register_driver    vmlinux EXPORT_SYMBOL_GPL
+-0xb575c1a1    usb_kill_urb    vmlinux EXPORT_SYMBOL_GPL
+-0x8ab265d2    usb_get_intf    vmlinux EXPORT_SYMBOL_GPL
+-0xdbd7794d    cfg80211_ready_on_channel       vmlinux EXPORT_SYMBOL
+-0xff112bd5    proc_get_parent_data    vmlinux EXPORT_SYMBOL_GPL
+-0x0bec8a3d    audit_log       vmlinux EXPORT_SYMBOL
+-0x5d9521f8    set_security_override_from_ctx  vmlinux EXPORT_SYMBOL
+-0x235d1d10    drm_gem_prime_import    vmlinux EXPORT_SYMBOL
+-0x7da24ff0    drm_helper_encoder_in_use       vmlinux EXPORT_SYMBOL
+-0x6f3c606d    nfc_hci_register_device vmlinux EXPORT_SYMBOL
+-0xf447e205    ip_tunnel_uninit        vmlinux EXPORT_SYMBOL_GPL
+-0x5055493c    sk_wait_data    vmlinux EXPORT_SYMBOL
+-0xb1b87423    crypto_remove_spawns    vmlinux EXPORT_SYMBOL_GPL
+-0x4fd4e89d    ring_buffer_empty_cpu   vmlinux EXPORT_SYMBOL_GPL
+-0xaa4704e1    usb_autopm_put_interface_no_suspend     vmlinux EXPORT_SYMBOL_GPL
+-0x50e28c07    drm_edid_to_sad vmlinux EXPORT_SYMBOL
+-0x6d57e7f8    drm_edid_to_eld vmlinux EXPORT_SYMBOL
+-0x3fe12ddc    xt_replace_table        vmlinux EXPORT_SYMBOL_GPL
+-0x9c3737fc    __percpu_counter_init   vmlinux EXPORT_SYMBOL
+-0xf846506f    irq_set_affinity_notifier       vmlinux EXPORT_SYMBOL_GPL
+-0x469a0b25    inet_hashinfo_init      vmlinux EXPORT_SYMBOL_GPL
+-0x3fbf68bd    ipv4_sk_redirect        vmlinux EXPORT_SYMBOL_GPL
+-0x151bc10b    end_buffer_read_sync    vmlinux EXPORT_SYMBOL
+-0xb013af25    set_cpus_allowed_ptr    vmlinux EXPORT_SYMBOL_GPL
+-0x227badd6    mod_timer_pinned        vmlinux EXPORT_SYMBOL
+-0xf37cfbf5    dm_dispatch_request     vmlinux EXPORT_SYMBOL_GPL
+-0x1d96bf04    input_mt_report_pointer_emulation       vmlinux EXPORT_SYMBOL
+-0x94289922    mali_pmu_powerdown      vmlinux EXPORT_SYMBOL
+-0xe9d6e0bd    pwm_request     vmlinux EXPORT_SYMBOL_GPL
+-0xd66a2750    tcf_em_tree_dump        vmlinux EXPORT_SYMBOL
+-0x790c22d3    neigh_for_each  vmlinux EXPORT_SYMBOL
+-0x3ed096c1    sg_miter_next   vmlinux EXPORT_SYMBOL
+-0x96b878b6    crypto_init_shash_spawn vmlinux EXPORT_SYMBOL_GPL
+-0x1fd19684    crypto_init_ahash_spawn vmlinux EXPORT_SYMBOL_GPL
+-0xedc85914    posix_timers_register_clock     vmlinux EXPORT_SYMBOL_GPL
+-0xc702156b    param_get_ushort        vmlinux EXPORT_SYMBOL
+-0x65bca4ff    vb2_plane_cookie        vmlinux EXPORT_SYMBOL_GPL
+-0x294a6993    rtc_initialize_alarm    vmlinux EXPORT_SYMBOL_GPL
+-0x6971447a    rtc_month_days  vmlinux EXPORT_SYMBOL
+-0x7e64181d    usb_calc_bus_time       vmlinux EXPORT_SYMBOL_GPL
+-0x5f1f36bc    drm_calc_vbltimestamp_from_scanoutpos   vmlinux EXPORT_SYMBOL
+-0xe0af2dc1    regulator_is_enabled_regmap     vmlinux EXPORT_SYMBOL_GPL
+-0x57c3621e    skb_pull        vmlinux EXPORT_SYMBOL
+-0xeb0a7f4c    clk_register    vmlinux EXPORT_SYMBOL_GPL
+-0xabc6dd63    cpufreq_sysfs_create_file       vmlinux EXPORT_SYMBOL
+-0x1eee0a80    usb_find_interface      vmlinux EXPORT_SYMBOL_GPL
+-0xb524d8dc    amba_find_device        vmlinux EXPORT_SYMBOL
+-0x8574ca6c    gpio_request_array      vmlinux EXPORT_SYMBOL_GPL
+-0x93d2422d    snmp_mib_free   vmlinux EXPORT_SYMBOL_GPL
+-0x5d51bcf7    scatterwalk_start       vmlinux EXPORT_SYMBOL_GPL
+-0x417e3755    sysfs_put       vmlinux EXPORT_SYMBOL_GPL
+-0x2ba54bff    irq_remove_generic_chip vmlinux EXPORT_SYMBOL_GPL
+-0x420c729a    vb2_fop_poll    vmlinux EXPORT_SYMBOL_GPL
+-0xe6d23987    phy_start_interrupts    vmlinux EXPORT_SYMBOL
+-0x1fb1615f    spi_master_resume       vmlinux EXPORT_SYMBOL_GPL
+-0xcd721bb7    scsi_get_vpd_page       vmlinux EXPORT_SYMBOL_GPL
+-0xac2bd611    pm_generic_restore_noirq        vmlinux EXPORT_SYMBOL_GPL
+-0xe0b7aa47    drm_i2c_encoder_dpms    vmlinux EXPORT_SYMBOL
+-0x9dfdf722    gpio_free_array vmlinux EXPORT_SYMBOL_GPL
+-0x7345660c    xfrm_state_check_expire vmlinux EXPORT_SYMBOL
+-0xd5dba10e    sock_diag_unregister_inet_compat        vmlinux EXPORT_SYMBOL_GPL
+-0xfd719be0    netdev_boot_setup_check vmlinux EXPORT_SYMBOL
+-0xa9c6e543    sock_i_uid      vmlinux EXPORT_SYMBOL
+-0x2dfe841c    sock_i_ino      vmlinux EXPORT_SYMBOL
+-0x4bc2dc22    seq_bitmap      vmlinux EXPORT_SYMBOL
+-0x4b8e839a    cpufreq_global_kobject  vmlinux EXPORT_SYMBOL
+-0xc12cf8f8    v4l2_ctrl_replace       vmlinux EXPORT_SYMBOL
+-0xf3dd036d    regulator_set_voltage_time      vmlinux EXPORT_SYMBOL_GPL
+-0x88826167    ip_build_and_send_pkt   vmlinux EXPORT_SYMBOL_GPL
+-0xd09ce8d0    register_gifconf        vmlinux EXPORT_SYMBOL
+-0xaa6901ac    __kfifo_out_r   vmlinux EXPORT_SYMBOL
+-0x64f7667b    crypto_rng_type vmlinux EXPORT_SYMBOL_GPL
+-0x457594fa    crypto_alg_list vmlinux EXPORT_SYMBOL_GPL
+-0x665b8183    sync_inode_metadata     vmlinux EXPORT_SYMBOL
+-0x03026722    mempool_alloc   vmlinux EXPORT_SYMBOL
+-0x0034f927    unregister_wide_hw_breakpoint   vmlinux EXPORT_SYMBOL_GPL
+-0x86f6b99d    synchronize_rcu_expedited       vmlinux EXPORT_SYMBOL_GPL
+-0xec4d9e3a    clk_get_sys     vmlinux EXPORT_SYMBOL
+-0x1b6b3f33    cpufreq_unregister_driver       vmlinux EXPORT_SYMBOL_GPL
+-0x56ca80ea    drm_mode_validate_clocks        vmlinux EXPORT_SYMBOL
+-0xa66a1f63    drm_rmmap_locked        vmlinux EXPORT_SYMBOL
+-0x6b07a31b    regulator_get_voltage_sel_regmap        vmlinux EXPORT_SYMBOL_GPL
+-0x5107f9ce    gpiochip_find   vmlinux EXPORT_SYMBOL_GPL
+-0x05365f80    cfg80211_cac_event      vmlinux EXPORT_SYMBOL
+-0xc05ac2c8    cfg80211_classify8021d  vmlinux EXPORT_SYMBOL
+-0x92be9264    snd_soc_register_platform       vmlinux EXPORT_SYMBOL_GPL
+-0xfaf79bc2    __srcu_read_lock        vmlinux EXPORT_SYMBOL_GPL
+-0xada5e980    media_entity_pipeline_start     vmlinux EXPORT_SYMBOL_GPL
+-0x74fbf451    drm_mm_init_scan_with_range     vmlinux EXPORT_SYMBOL
+-0xd03c7700    secure_ipv4_port_ephemeral      vmlinux EXPORT_SYMBOL_GPL
+-0x9c9ec2a0    proc_dointvec_minmax    vmlinux EXPORT_SYMBOL
+-0x8d772b8c    v4l2_clk_get    vmlinux EXPORT_SYMBOL
+-0x32680bfc    usb_function_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x6dd8ac23    dev_uc_add_excl vmlinux EXPORT_SYMBOL
+-0xced0fa87    dev_mc_add_excl vmlinux EXPORT_SYMBOL
+-0x51cc09c6    kmalloc_caches  vmlinux EXPORT_SYMBOL
+-0x3ef23944    i2c_bus_type    vmlinux EXPORT_SYMBOL_GPL
+-0x015f6d7d    kmap    vmlinux EXPORT_SYMBOL
+-0x0b9a5c65    icmpv6_send     vmlinux EXPORT_SYMBOL
+-0x6625c30d    blk_queue_make_request  vmlinux EXPORT_SYMBOL
+-0x25dd3b83    sysfs_add_link_to_group vmlinux EXPORT_SYMBOL_GPL
+-0x472d363a    truncate_pagecache_range        vmlinux EXPORT_SYMBOL
+-0x0bf3e830    put_page        vmlinux EXPORT_SYMBOL
+-0x74954462    timecounter_read        vmlinux EXPORT_SYMBOL_GPL
+-0x3aa9f288    iio_channel_get vmlinux EXPORT_SYMBOL_GPL
+-0x1fd6672b    video_device_release_empty      vmlinux EXPORT_SYMBOL
+-0x931dcc9d    usbnet_pause_rx vmlinux EXPORT_SYMBOL_GPL
+-0x4c83a264    do_take_over_console    vmlinux EXPORT_SYMBOL_GPL
+-0xe2dd67e5    regulator_set_current_limit     vmlinux EXPORT_SYMBOL_GPL
+-0xb23f3373    nf_conntrack_lock       vmlinux EXPORT_SYMBOL_GPL
+-0xebfa66fa    security_inode_setsecctx        vmlinux EXPORT_SYMBOL
+-0x819ed3be    vfs_getattr     vmlinux EXPORT_SYMBOL
+-0x2fad0dbe    led_classdev_resume     vmlinux EXPORT_SYMBOL_GPL
+-0xbc497919    rtc_device_register     vmlinux EXPORT_SYMBOL_GPL
+-0xd58c665a    input_reset_device      vmlinux EXPORT_SYMBOL
+-0x34c728d0    tty_ldisc_deref vmlinux EXPORT_SYMBOL_GPL
+-0xfb28827b    inet_del_protocol       vmlinux EXPORT_SYMBOL
+-0x95587915    neigh_update    vmlinux EXPORT_SYMBOL
+-0xc9b8c308    __kfifo_dma_out_prepare vmlinux EXPORT_SYMBOL
+-0xd9b9b70a    put_io_context  vmlinux EXPORT_SYMBOL
+-0xac7726b4    blk_queue_io_min        vmlinux EXPORT_SYMBOL
+-0xcf807506    nobh_truncate_page      vmlinux EXPORT_SYMBOL
+-0x43ec231b    iio_device_free vmlinux EXPORT_SYMBOL
+-0x95ae5064    phy_stop        vmlinux EXPORT_SYMBOL
+-0xb69d1c51    spi_bitbang_start       vmlinux EXPORT_SYMBOL_GPL
+-0x87876bed    drm_kms_helper_poll_enable      vmlinux EXPORT_SYMBOL
+-0x045072cd    nf_ct_port_nla_policy   vmlinux EXPORT_SYMBOL_GPL
+-0x4be7fb63    up      vmlinux EXPORT_SYMBOL
+-0xf8a32b55    icmp_send       vmlinux EXPORT_SYMBOL
+-0x69f7d81d    path_get        vmlinux EXPORT_SYMBOL
+-0xd715763b    iov_iter_copy_from_user_atomic  vmlinux EXPORT_SYMBOL
+-0xc7b9fe08    drm_property_create_bitmask     vmlinux EXPORT_SYMBOL
+-0x671a649b    xfrm_state_update       vmlinux EXPORT_SYMBOL
+-0xce3c5240    crypto_grab_aead        vmlinux EXPORT_SYMBOL_GPL
+-0xb590822d    hrtimer_start   vmlinux EXPORT_SYMBOL_GPL
+-0xaebe783e    get_pid_task    vmlinux EXPORT_SYMBOL_GPL
+-0xa8bcfa1a    usb_deregister_dev      vmlinux EXPORT_SYMBOL_GPL
+-0xc398c5f3    usb_hcd_is_primary_hcd  vmlinux EXPORT_SYMBOL_GPL
+-0x7c45fec1    pm_generic_resume_noirq vmlinux EXPORT_SYMBOL_GPL
+-0x6c702af7    sysctl_udp_rmem_min     vmlinux EXPORT_SYMBOL
+-0x9b3122cd    dev_open        vmlinux EXPORT_SYMBOL
+-0x7ee7a9f8    lock_sock_fast  vmlinux EXPORT_SYMBOL
+-0xc3b7e3fb    snd_cards       vmlinux EXPORT_SYMBOL
+-0x82bbf933    ilookup vmlinux EXPORT_SYMBOL
+-0x4302d0eb    free_pages      vmlinux EXPORT_SYMBOL
+-0xefc91531    irq_create_of_mapping   vmlinux EXPORT_SYMBOL_GPL
+-0xb90f9844    sdhci_resume_host       vmlinux EXPORT_SYMBOL_GPL
+-0x8ec22c0b    nat_q931_hook   vmlinux EXPORT_SYMBOL_GPL
+-0x03592ea0    security_unix_stream_connect    vmlinux EXPORT_SYMBOL
+-0x4397c48f    generic_file_fsync      vmlinux EXPORT_SYMBOL
+-0x5154c361    unlock_new_inode        vmlinux EXPORT_SYMBOL
+-0xa9b83487    __f_setown      vmlinux EXPORT_SYMBOL
+-0x9ccb1788    irq_create_direct_mapping       vmlinux EXPORT_SYMBOL_GPL
+-0xf82f16b3    execute_in_process_context      vmlinux EXPORT_SYMBOL_GPL
+-0xcd06de19    mdiobus_free    vmlinux EXPORT_SYMBOL
+-0xfd99623a    ip_frag_ecn_table       vmlinux EXPORT_SYMBOL
+-0x17ee142e    xt_find_table_lock      vmlinux EXPORT_SYMBOL_GPL
+-0x62737e1d    sock_unregister vmlinux EXPORT_SYMBOL
+-0x67095031    kset_register   vmlinux EXPORT_SYMBOL
+-0x84ffea8b    idr_preload     vmlinux EXPORT_SYMBOL
+-0xd29fb507    fput    vmlinux EXPORT_SYMBOL
+-0xe3d6f284    fb_find_mode_cvt        vmlinux EXPORT_SYMBOL
+-0x14d4a9c5    _change_bit     vmlinux EXPORT_SYMBOL
+-0x54411a42    posix_timer_event       vmlinux EXPORT_SYMBOL_GPL
+-0x2a79ac13    clkdev_add      vmlinux EXPORT_SYMBOL
+-0x3d6f446b    platform_device_alloc   vmlinux EXPORT_SYMBOL_GPL
+-0xf85bebf9    dev_printk_emit vmlinux EXPORT_SYMBOL
+-0xde36a037    ip6_frag_init   vmlinux EXPORT_SYMBOL
+-0x31e23d78    __fsnotify_parent       vmlinux EXPORT_SYMBOL_GPL
+-0xdea4fcaa    pm_qos_add_request      vmlinux EXPORT_SYMBOL_GPL
+-0x1976aa06    param_ops_bool  vmlinux EXPORT_SYMBOL
+-0x98ba0e88    pm_generic_suspend_noirq        vmlinux EXPORT_SYMBOL_GPL
+-0xecefd1b6    display_entity_get_params       vmlinux EXPORT_SYMBOL_GPL
+-0xdfb5c1e5    add_disk        vmlinux EXPORT_SYMBOL
+-0x5754706e    media_entity_get        vmlinux EXPORT_SYMBOL_GPL
+-0xbd008b38    media_entity_put        vmlinux EXPORT_SYMBOL_GPL
+-0x5d1e2494    usb_ep0_reinit  vmlinux EXPORT_SYMBOL_GPL
+-0x0ae4b94c    drm_ht_remove   vmlinux EXPORT_SYMBOL
+-0x6ab922b2    regulator_get_drvdata   vmlinux EXPORT_SYMBOL_GPL
+-0x4432d365    __udp6_lib_lookup       vmlinux EXPORT_SYMBOL_GPL
+-0x08696053    inet_shutdown   vmlinux EXPORT_SYMBOL
+-0x52212010    __tracepoint_block_bio_remap    vmlinux EXPORT_SYMBOL_GPL
+-0xc29afc9a    posix_lock_file_wait    vmlinux EXPORT_SYMBOL
+-0x01fd453e    usbhid_lookup_quirk     vmlinux EXPORT_SYMBOL_GPL
+-0x90705b7f    syscon_node_to_regmap   vmlinux EXPORT_SYMBOL_GPL
+-0xf72d56a2    regulator_set_voltage_sel_regmap        vmlinux EXPORT_SYMBOL_GPL
+-0xa308e150    nfc_hci_disconnect_gate vmlinux EXPORT_SYMBOL
+-0x7707c1b0    xt_unregister_table     vmlinux EXPORT_SYMBOL_GPL
+-0x4e830a3e    strnicmp        vmlinux EXPORT_SYMBOL
+-0x48f2cf7c    vmalloc_to_page vmlinux EXPORT_SYMBOL
+-0x3dca446d    drm_handle_vblank       vmlinux EXPORT_SYMBOL
+-0x22ca070b    uart_remove_one_port    vmlinux EXPORT_SYMBOL
+-0x1d027e4b    snd_pcm_format_signed   vmlinux EXPORT_SYMBOL
+-0x3535ae4a    blk_update_request      vmlinux EXPORT_SYMBOL_GPL
+-0x02649054    security_sock_rcv_skb   vmlinux EXPORT_SYMBOL
+-0x547077ec    __wake_up_bit   vmlinux EXPORT_SYMBOL
+-0x1c5541bd    cpufreq_boost_enabled   vmlinux EXPORT_SYMBOL_GPL
+-0x6d186427    usb_get_hcd     vmlinux EXPORT_SYMBOL_GPL
+-0x8eff9111    drm_ht_find_item        vmlinux EXPORT_SYMBOL
+-0xd9d18f03    fbcon_set_bitops        vmlinux EXPORT_SYMBOL
+-0xfaea036f    sock_release    vmlinux EXPORT_SYMBOL
+-0xa414882d    add_wait_queue_exclusive        vmlinux EXPORT_SYMBOL
+-0x06e80ae6    s3c_adc_register        vmlinux EXPORT_SYMBOL_GPL
+-0x63805ac9    usb_hcd_giveback_urb    vmlinux EXPORT_SYMBOL_GPL
+-0xf8d54998    ump_dd_handle_create_from_phys_blocks   vmlinux EXPORT_SYMBOL
+-0x44242685    drm_prime_gem_destroy   vmlinux EXPORT_SYMBOL
+-0x4faff87a    drm_i2c_encoder_mode_fixup      vmlinux EXPORT_SYMBOL
+-0x0f995f4e    tty_port_tty_wakeup     vmlinux EXPORT_SYMBOL_GPL
+-0x91b2790d    regulator_map_voltage_ascend    vmlinux EXPORT_SYMBOL_GPL
+-0x0e29d022    nf_nat_icmp_reply_translation   vmlinux EXPORT_SYMBOL_GPL
+-0x75811312    crc_ccitt_table vmlinux EXPORT_SYMBOL
+-0xe9eb0c04    d_add_ci        vmlinux EXPORT_SYMBOL
+-0x4c55b4df    led_trigger_rename_static       vmlinux EXPORT_SYMBOL_GPL
+-0x6f344bb9    v4l2_calc_aspect_ratio  vmlinux EXPORT_SYMBOL_GPL
+-0xc4f83bea    drm_debugfs_create_files        vmlinux EXPORT_SYMBOL
+-0x9ae51e43    tty_register_device_attr        vmlinux EXPORT_SYMBOL_GPL
+-0x80c70b19    phys_mem_access_prot    vmlinux EXPORT_SYMBOL
+-0x17770200    __skb_checksum_complete_head    vmlinux EXPORT_SYMBOL
+-0x1eeb848e    __percpu_counter_sum    vmlinux EXPORT_SYMBOL
+-0xd74289f9    __percpu_counter_add    vmlinux EXPORT_SYMBOL
+-0xa77a369d    idr_init        vmlinux EXPORT_SYMBOL
+-0x8e5c580a    ida_init        vmlinux EXPORT_SYMBOL
+-0xb99d677c    mpage_readpage  vmlinux EXPORT_SYMBOL
+-0x70bc17d7    inode_wait      vmlinux EXPORT_SYMBOL
+-0xd6ee688f    vmalloc vmlinux EXPORT_SYMBOL
+-0xf31b3fd1    workqueue_set_max_active        vmlinux EXPORT_SYMBOL_GPL
+-0x9745c52a    of_fixed_clk_setup      vmlinux EXPORT_SYMBOL_GPL
+-0xbfd6a20b    phy_ethtool_set_wol     vmlinux EXPORT_SYMBOL
+-0x64004900    phy_ethtool_get_wol     vmlinux EXPORT_SYMBOL
+-0x28492539    spi_bitbang_transfer    vmlinux EXPORT_SYMBOL_GPL
+-0x6552f2d8    unlink_framebuffer      vmlinux EXPORT_SYMBOL
+-0xbdf2580d    __raw_readsl    vmlinux EXPORT_SYMBOL
+-0xabe519d2    blk_queue_io_opt        vmlinux EXPORT_SYMBOL
+-0x05b2af42    bdgrab  vmlinux EXPORT_SYMBOL
+-0xd4c14632    system_unbound_wq       vmlinux EXPORT_SYMBOL_GPL
+-0x098859e1    usbnet_cdc_status       vmlinux EXPORT_SYMBOL_GPL
+-0xd1bd52ba    tty_port_raise_dtr_rts  vmlinux EXPORT_SYMBOL
+-0x4ea1f5a2    drm_gem_object_free     vmlinux EXPORT_SYMBOL
+-0x86d53c76    mb_cache_entry_find_first       vmlinux EXPORT_SYMBOL
+-0xf0b9f940    usb_function_activate   vmlinux EXPORT_SYMBOL_GPL
+-0x9d2ee507    scsi_adjust_queue_depth vmlinux EXPORT_SYMBOL
+-0x4bca6b0c    drm_get_edid    vmlinux EXPORT_SYMBOL
+-0x4a5d2ace    tcp_unregister_congestion_control       vmlinux EXPORT_SYMBOL_GPL
+-0x0274dc2b    netif_get_num_default_rss_queues        vmlinux EXPORT_SYMBOL
+-0x53be6f80    bio_split       vmlinux EXPORT_SYMBOL
+-0x1fc0da41    lock_rename     vmlinux EXPORT_SYMBOL
+-0xbe421975    __locks_copy_lock       vmlinux EXPORT_SYMBOL
+-0x69e3cb9f    mutex_lock_killable     vmlinux EXPORT_SYMBOL
+-0x9c612795    v4l2_chip_match_i2c_client      vmlinux EXPORT_SYMBOL
+-0xd2f84424    i2c_bit_add_bus vmlinux EXPORT_SYMBOL
+-0x421cdcbd    usb_function_deactivate vmlinux EXPORT_SYMBOL_GPL
+-0x63a86872    class_destroy   vmlinux EXPORT_SYMBOL_GPL
+-0x231d4001    fb_edid_add_monspecs    vmlinux EXPORT_SYMBOL
+-0xb01a37d3    gpiochip_remove vmlinux EXPORT_SYMBOL_GPL
+-0xcc2b7257    tcp_check_req   vmlinux EXPORT_SYMBOL
+-0x16270acd    tcp_init_sock   vmlinux EXPORT_SYMBOL
+-0x143dc3b0    netlink_unicast vmlinux EXPORT_SYMBOL
+-0x8452993c    neigh_sysctl_register   vmlinux EXPORT_SYMBOL
+-0xce602df6    cgroup_is_descendant    vmlinux EXPORT_SYMBOL_GPL
+-0xdddba0ab    exynos_g2d_get_ver_ioctl        vmlinux EXPORT_SYMBOL_GPL
+-0xf2c642ed    tty_port_tty_hangup     vmlinux EXPORT_SYMBOL_GPL
+-0x7d086e6f    snd_soc_put_volsw_range vmlinux EXPORT_SYMBOL_GPL
+-0xaf23bb74    snd_soc_get_volsw_range vmlinux EXPORT_SYMBOL_GPL
+-0x01b2facc    snd_timer_start vmlinux EXPORT_SYMBOL
+-0x1e693956    set_nlink       vmlinux EXPORT_SYMBOL
+-0xdcb0349b    sys_close       vmlinux EXPORT_SYMBOL
+-0xaf348da7    cpu_pm_exit     vmlinux EXPORT_SYMBOL_GPL
+-0x77d1afb4    kill_pgrp       vmlinux EXPORT_SYMBOL
+-0x3b9d009a    drm_format_plane_cpp    vmlinux EXPORT_SYMBOL
+-0x2acd3e60    fat_build_inode vmlinux EXPORT_SYMBOL_GPL
+-0x0f3ef271    seq_read        vmlinux EXPORT_SYMBOL
+-0x712fb5a8    is_bad_inode    vmlinux EXPORT_SYMBOL
+-0x253bdb78    param_get_int   vmlinux EXPORT_SYMBOL
+-0xd35fa891    st_sensors_write_event_config   vmlinux EXPORT_SYMBOL
+-0x203bef91    device_wakeup_disable   vmlinux EXPORT_SYMBOL_GPL
+-0xd454eabb    tcf_hash_new_index      vmlinux EXPORT_SYMBOL
+-0x235e7e6a    shash_ahash_finup       vmlinux EXPORT_SYMBOL_GPL
+-0x60384c87    start_tty       vmlinux EXPORT_SYMBOL
+-0x6513a3fa    fb_get_color_depth      vmlinux EXPORT_SYMBOL
+-0x7ffc8718    gpio_set_debounce       vmlinux EXPORT_SYMBOL_GPL
+-0x6c95cbd5    phonet_proto_register   vmlinux EXPORT_SYMBOL
+-0xa01cac38    nf_ct_get_tuplepr       vmlinux EXPORT_SYMBOL_GPL
+-0x3e872db6    __netdev_pick_tx        vmlinux EXPORT_SYMBOL
+-0x981f509d    skb_free_datagram_locked        vmlinux EXPORT_SYMBOL
+-0x93e0379d    kernel_sock_shutdown    vmlinux EXPORT_SYMBOL
+-0x878eae99    snd_pcm_add_chmap_ctls  vmlinux EXPORT_SYMBOL_GPL
+-0xd454865d    snd_pcm_notify  vmlinux EXPORT_SYMBOL
+-0xa735db59    prandom_u32     vmlinux EXPORT_SYMBOL
+-0x8e864a86    posix_acl_chmod vmlinux EXPORT_SYMBOL
+-0xf9910a86    notify_change   vmlinux EXPORT_SYMBOL
+-0x423b589c    follow_up       vmlinux EXPORT_SYMBOL
+-0xa577a850    param_get_short vmlinux EXPORT_SYMBOL
+-0x24b55d2b    of_find_i2c_adapter_by_node     vmlinux EXPORT_SYMBOL
+-0x6d0f1f89    dm_table_get_mode       vmlinux EXPORT_SYMBOL
+-0x2ca4ebcd    regulator_set_drvdata   vmlinux EXPORT_SYMBOL_GPL
+-0x02196324    __aeabi_idiv    vmlinux EXPORT_SYMBOL
+-0xf0e3bec8    nf_log_bind_pf  vmlinux EXPORT_SYMBOL
+-0xd12698d0    skb_copy_and_csum_datagram_iovec        vmlinux EXPORT_SYMBOL
+-0xd23bebab    sock_no_ioctl   vmlinux EXPORT_SYMBOL
+-0xf401a5f4    get_user_pages_fast     vmlinux EXPORT_SYMBOL_GPL
+-0xca85d8cf    tracepoint_probe_update_all     vmlinux EXPORT_SYMBOL_GPL
+-0x54740eb7    get_cpu_idle_time       vmlinux EXPORT_SYMBOL_GPL
+-0x2a3aa678    _test_and_clear_bit     vmlinux EXPORT_SYMBOL
+-0x694967d9    nf_conntrack_find_get   vmlinux EXPORT_SYMBOL_GPL
+-0x19a2badf    snd_soc_codec_set_sysclk        vmlinux EXPORT_SYMBOL_GPL
+-0x93a2419d    simple_empty    vmlinux EXPORT_SYMBOL
+-0x68a13545    vm_mmap vmlinux EXPORT_SYMBOL
+-0x224190b8    shmem_read_mapping_page_gfp     vmlinux EXPORT_SYMBOL_GPL
+-0xd859f1d5    dw_mci_pltfm_register   vmlinux EXPORT_SYMBOL_GPL
+-0xc955c267    serio_unregister_child_port     vmlinux EXPORT_SYMBOL
+-0xcbee09f7    scsi_remove_device      vmlinux EXPORT_SYMBOL
+-0xcd579f54    xfrm_cfg_mutex  vmlinux EXPORT_SYMBOL
+-0xb63be252    __sk_mem_schedule       vmlinux EXPORT_SYMBOL
+-0xcde172ac    radix_tree_gang_lookup_tag_slot vmlinux EXPORT_SYMBOL
+-0x61860fe5    blk_queue_merge_bvec    vmlinux EXPORT_SYMBOL
+-0xd223c00d    fuse_file_poll  vmlinux EXPORT_SYMBOL_GPL
+-0x4b6e004b    mnt_want_write_file     vmlinux EXPORT_SYMBOL_GPL
+-0x11ad8ba6    __hid_register_driver   vmlinux EXPORT_SYMBOL_GPL
+-0x3d8ed8f5    hid_disconnect  vmlinux EXPORT_SYMBOL_GPL
+-0x70cf032f    usb_hcd_irq     vmlinux EXPORT_SYMBOL_GPL
+-0xc0a9a9a1    hci_register_cb vmlinux EXPORT_SYMBOL
+-0x83b21051    ip_ct_attach    vmlinux EXPORT_SYMBOL
+-0x24eb8d39    dev_set_mtu     vmlinux EXPORT_SYMBOL
+-0xbd5c42d9    crypto_unregister_template      vmlinux EXPORT_SYMBOL_GPL
+-0x2deda4a1    security_sk_classify_flow       vmlinux EXPORT_SYMBOL
+-0xe694a9ce    bd_link_disk_holder     vmlinux EXPORT_SYMBOL_GPL
+-0xf1a33551    usb_string_ids_tab      vmlinux EXPORT_SYMBOL_GPL
+-0x565b6892    uuid_le_gen     vmlinux EXPORT_SYMBOL_GPL
+-0x68956406    static_key_slow_dec     vmlinux EXPORT_SYMBOL_GPL
+-0x335c570f    enable_percpu_irq       vmlinux EXPORT_SYMBOL_GPL
+-0x02e1a3ed    should_remove_suid      vmlinux EXPORT_SYMBOL
+-0x0626da5f    od_unregister_powersave_bias_handler    vmlinux EXPORT_SYMBOL_GPL
+-0x4dcfd46b    scsi_free_host_dev      vmlinux EXPORT_SYMBOL
+-0xfec445a3    driver_register vmlinux EXPORT_SYMBOL_GPL
+-0x3d1b2e32    find_lock_page  vmlinux EXPORT_SYMBOL
+-0x92ea202d    srcu_notifier_chain_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0xdb9d11d6    iio_buffer_store_enable vmlinux EXPORT_SYMBOL
+-0x2ceca451    input_ff_create vmlinux EXPORT_SYMBOL_GPL
+-0x6e3d17ac    device_destroy  vmlinux EXPORT_SYMBOL_GPL
+-0xb8d2fd38    wiphy_register  vmlinux EXPORT_SYMBOL
+-0xfa4d8a1f    unregister_pernet_device        vmlinux EXPORT_SYMBOL_GPL
+-0x4c86184b    remove_wait_queue       vmlinux EXPORT_SYMBOL
+-0x4845c423    param_array_ops vmlinux EXPORT_SYMBOL
+-0x2cd6eb8b    input_ff_destroy        vmlinux EXPORT_SYMBOL_GPL
+-0xb9500ec7    mfd_cell_disable        vmlinux EXPORT_SYMBOL
+-0x1a2759ff    platform_get_irq_byname vmlinux EXPORT_SYMBOL_GPL
+-0x8daf9344    napi_get_frags  vmlinux EXPORT_SYMBOL
+-0x60c805dd    sk_stream_write_space   vmlinux EXPORT_SYMBOL
+-0x570e3195    scsi_verify_blk_ioctl   vmlinux EXPORT_SYMBOL
+-0xecbe66b8    sysfs_notify_dirent     vmlinux EXPORT_SYMBOL_GPL
+-0x158df5f3    kill_bdev       vmlinux EXPORT_SYMBOL
+-0x3eb2b460    v4l2_event_unsubscribe  vmlinux EXPORT_SYMBOL_GPL
+-0x8e38bb44    ipv6_dup_options        vmlinux EXPORT_SYMBOL_GPL
+-0xe306f9d8    cgroup_attach_task_all  vmlinux EXPORT_SYMBOL_GPL
+-0x6b06fdce    delayed_work_timer_fn   vmlinux EXPORT_SYMBOL
+-0x8104c3bb    phy_register_fixup_for_id       vmlinux EXPORT_SYMBOL
+-0x46d3b28c    __div0  vmlinux EXPORT_SYMBOL
+-0x7ead817c    __idr_pre_get   vmlinux EXPORT_SYMBOL
+-0x6cc299a1    zap_vma_ptes    vmlinux EXPORT_SYMBOL_GPL
+-0x1f0972cb    drm_fasync      vmlinux EXPORT_SYMBOL
+-0x35c653fb    xfrm_policy_bysel_ctx   vmlinux EXPORT_SYMBOL
+-0x8e81d5af    tcp_sendmsg     vmlinux EXPORT_SYMBOL
+-0xf9ebc368    snd_soc_new_ac97_codec  vmlinux EXPORT_SYMBOL_GPL
+-0x4528c501    elv_rb_del      vmlinux EXPORT_SYMBOL
+-0x056bf03a    elv_rb_add      vmlinux EXPORT_SYMBOL
+-0x5b2c1c77    init_user_ns    vmlinux EXPORT_SYMBOL_GPL
+-0x0b5996ef    st_sensors_sysfs_sampling_frequency_avail       vmlinux EXPORT_SYMBOL
+-0x3a17a800    vb2_dqbuf       vmlinux EXPORT_SYMBOL_GPL
+-0xe55de32d    i2c_smbus_write_word_data       vmlinux EXPORT_SYMBOL
+-0xd1c2d294    ip_mc_leave_group       vmlinux EXPORT_SYMBOL
+-0x05843ade    netif_skb_features      vmlinux EXPORT_SYMBOL
+-0x00632780    work_busy       vmlinux EXPORT_SYMBOL_GPL
+-0x06d2c86e    pm_runtime_set_memalloc_noio    vmlinux EXPORT_SYMBOL_GPL
+-0x97c6c5dd    drm_pci_exit    vmlinux EXPORT_SYMBOL
+-0x1a1938a1    drm_pci_init    vmlinux EXPORT_SYMBOL
+-0xf7a0d470    __sk_mem_reclaim        vmlinux EXPORT_SYMBOL
+-0xc4f45210    d_prune_aliases vmlinux EXPORT_SYMBOL
+-0x498d293a    trace_buffer_unlock_commit      vmlinux EXPORT_SYMBOL_GPL
+-0x12a38747    usleep_range    vmlinux EXPORT_SYMBOL
+-0xef409b74    kmsg_dump_get_line      vmlinux EXPORT_SYMBOL_GPL
+-0xdd3202eb    lcd_device_unregister   vmlinux EXPORT_SYMBOL
+-0x1fa2ae70    tcf_hash_check  vmlinux EXPORT_SYMBOL
+-0xa43b9539    memcpy_fromiovecend     vmlinux EXPORT_SYMBOL
+-0x4b4f96c3    blk_make_request        vmlinux EXPORT_SYMBOL
+-0xe290713d    __pagevec_release       vmlinux EXPORT_SYMBOL
+-0x1e047854    warn_slowpath_fmt       vmlinux EXPORT_SYMBOL
+-0xbca701eb    vb2_ioctl_expbuf        vmlinux EXPORT_SYMBOL_GPL
+-0x01508e49    cfg80211_cqm_rssi_notify        vmlinux EXPORT_SYMBOL
+-0xff3e2712    nla_reserve_nohdr       vmlinux EXPORT_SYMBOL
+-0xc442fa87    ilookup5        vmlinux EXPORT_SYMBOL
+-0x1650bf27    rcutorture_record_progress      vmlinux EXPORT_SYMBOL_GPL
+-0x3507a132    _raw_spin_lock_irq      vmlinux EXPORT_SYMBOL
+-0x1b24bd6e    prepare_creds   vmlinux EXPORT_SYMBOL
+-0x97c03a7e    mutex_unlock    vmlinux EXPORT_SYMBOL
+-0x5bf35318    hid_unregister_driver   vmlinux EXPORT_SYMBOL_GPL
+-0xd989fc54    usb_autopm_put_interface        vmlinux EXPORT_SYMBOL_GPL
+-0x64d3db1a    dev_addr_flush  vmlinux EXPORT_SYMBOL
+-0x6d92d23c    snd_dma_reserve_buf     vmlinux EXPORT_SYMBOL
+-0x83a476ce    bitmap_scnlistprintf    vmlinux EXPORT_SYMBOL
+-0x61660b0f    thermal_notify_framework        vmlinux EXPORT_SYMBOL_GPL
+-0x1e925a2f    drm_unplug_dev  vmlinux EXPORT_SYMBOL
+-0xef76af89    wiphy_rfkill_set_hw_state       vmlinux EXPORT_SYMBOL
+-0x920aacca    nl_table_lock   vmlinux EXPORT_SYMBOL_GPL
+-0x69b0b6dd    blkdev_get_by_dev       vmlinux EXPORT_SYMBOL
+-0xd87601cc    ring_buffer_unlock_commit       vmlinux EXPORT_SYMBOL_GPL
+-0xee7e7bbe    simple_fill_super       vmlinux EXPORT_SYMBOL
+-0xf8fffd67    have_submounts  vmlinux EXPORT_SYMBOL
+-0x07cc4a5d    printk_timed_ratelimit  vmlinux EXPORT_SYMBOL
+-0x274944b3    sock_queue_err_skb      vmlinux EXPORT_SYMBOL
+-0x7b03f66f    snd_add_device_sysfs_file       vmlinux EXPORT_SYMBOL
+-0x1f8db7f9    ring_buffer_overrun_cpu vmlinux EXPORT_SYMBOL_GPL
+-0x0faef0ed    __tasklet_schedule      vmlinux EXPORT_SYMBOL
+-0x8ec68aa9    dev_load        vmlinux EXPORT_SYMBOL
+-0xf4f14de6    rtnl_trylock    vmlinux EXPORT_SYMBOL
+-0xac0ba8c1    blk_iopoll_disable      vmlinux EXPORT_SYMBOL
+-0x1bb201ff    debugfs_create_u16      vmlinux EXPORT_SYMBOL_GPL
+-0xcae7b03f    bio_add_page    vmlinux EXPORT_SYMBOL
+-0x61af42e6    init_pid_ns     vmlinux EXPORT_SYMBOL_GPL
+-0x3c420cae    v4l2_m2m_buf_queue      vmlinux EXPORT_SYMBOL_GPL
+-0x0fa2a45e    __memzero       vmlinux EXPORT_SYMBOL
+-0x674c71f7    ipt_unregister_table    vmlinux EXPORT_SYMBOL
+-0x77ecac9f    zlib_inflateEnd vmlinux EXPORT_SYMBOL
+-0x7ca5798f    contig_page_data        vmlinux EXPORT_SYMBOL
+-0x3b66dc5f    vb2_buffer_done vmlinux EXPORT_SYMBOL_GPL
+-0x07b291d1    usb_unlink_anchored_urbs        vmlinux EXPORT_SYMBOL_GPL
+-0x06fbba42    usbnet_write_cmd        vmlinux EXPORT_SYMBOL_GPL
+-0xc6b4b7b5    inet_frag_evictor       vmlinux EXPORT_SYMBOL
+-0x9d44f8f6    xt_unregister_target    vmlinux EXPORT_SYMBOL
+-0x0dca487b    led_trigger_show        vmlinux EXPORT_SYMBOL_GPL
+-0xb423dba1    console_blanked vmlinux EXPORT_SYMBOL
+-0x23679939    __iowrite32_copy        vmlinux EXPORT_SYMBOL_GPL
+-0x38361fbf    config_group_init_type_name     vmlinux EXPORT_SYMBOL
+-0x668fe138    __sb_end_write  vmlinux EXPORT_SYMBOL
+-0xd67296c6    from_kgid       vmlinux EXPORT_SYMBOL
+-0x2fd8e085    sdhci_pltfm_clk_get_max_clock   vmlinux EXPORT_SYMBOL_GPL
+-0x4222235b    v4l2_fh_is_singular     vmlinux EXPORT_SYMBOL_GPL
+-0x27cbc081    nf_conntrack_unregister_notifier        vmlinux EXPORT_SYMBOL_GPL
+-0x638eeb4d    fib_rules_register      vmlinux EXPORT_SYMBOL_GPL
+-0xfaf98462    bitrev32        vmlinux EXPORT_SYMBOL
+-0x0399203b    simple_transaction_read vmlinux EXPORT_SYMBOL
+-0x8a99a016    mempool_free_slab       vmlinux EXPORT_SYMBOL
+-0x41c72de9    generic_setxattr        vmlinux EXPORT_SYMBOL
+-0x75d94810    generic_getxattr        vmlinux EXPORT_SYMBOL
+-0xe384a102    usb_speed_string        vmlinux EXPORT_SYMBOL_GPL
+-0xf70fecd0    pm_generic_resume_early vmlinux EXPORT_SYMBOL_GPL
+-0x48cb14ac    pm_generic_thaw vmlinux EXPORT_SYMBOL_GPL
+-0x1d061186    cfg80211_connect_result vmlinux EXPORT_SYMBOL
+-0xdd8800ff    jbd2_journal_set_features       vmlinux EXPORT_SYMBOL
+-0xdadafdd7    mpage_readpages vmlinux EXPORT_SYMBOL
+-0x4045c494    filter_match_preds      vmlinux EXPORT_SYMBOL_GPL
+-0x5482fcef    usbnet_start_xmit       vmlinux EXPORT_SYMBOL_GPL
+-0x9e074139    __pm_runtime_resume     vmlinux EXPORT_SYMBOL_GPL
+-0x4df119fa    __bitmap_parse  vmlinux EXPORT_SYMBOL
+-0x2cfc8703    __wait_on_buffer        vmlinux EXPORT_SYMBOL
+-0x4a8907de    cancel_delayed_work_sync        vmlinux EXPORT_SYMBOL
+-0x4c5566c5    extcon_set_cable_state  vmlinux EXPORT_SYMBOL_GPL
+-0x1114ede2    extcon_get_cable_state  vmlinux EXPORT_SYMBOL_GPL
+-0xcac8aaf3    i2c_unlock_adapter      vmlinux EXPORT_SYMBOL_GPL
+-0xc3107f52    regmap_raw_read vmlinux EXPORT_SYMBOL_GPL
+-0x6b807a5f    gpio_sysfs_set_active_low       vmlinux EXPORT_SYMBOL_GPL
+-0xad4d490d    sock_create     vmlinux EXPORT_SYMBOL
+-0x1bcfb1fa    debugfs_create_x32      vmlinux EXPORT_SYMBOL_GPL
+-0xb0440408    bprm_change_interp      vmlinux EXPORT_SYMBOL
+-0xbf7f05c3    kill_litter_super       vmlinux EXPORT_SYMBOL
+-0xcb34aaf6    iommu_domain_window_disable     vmlinux EXPORT_SYMBOL_GPL
+-0x7c9e0f69    clk_add_alias   vmlinux EXPORT_SYMBOL
+-0xad84bef8    dm_table_event  vmlinux EXPORT_SYMBOL
+-0xc91b3468    class_dev_iter_next     vmlinux EXPORT_SYMBOL_GPL
+-0x64038eb3    inet_proto_csum_replace4        vmlinux EXPORT_SYMBOL
+-0xb6e03027    neigh_direct_output     vmlinux EXPORT_SYMBOL
+-0xce9a717b    blk_rq_check_limits     vmlinux EXPORT_SYMBOL_GPL
+-0x75bda77a    seq_hlist_next  vmlinux EXPORT_SYMBOL
+-0xb9c24bba    account_page_dirtied    vmlinux EXPORT_SYMBOL
+-0xde037eaa    __lock_page_killable    vmlinux EXPORT_SYMBOL_GPL
+-0x73c2d5f0    usb_free_urb    vmlinux EXPORT_SYMBOL_GPL
+-0x9faa8d4a    tty_prepare_flip_string_flags   vmlinux EXPORT_SYMBOL_GPL
+-0xb8de9394    tty_prepare_flip_string vmlinux EXPORT_SYMBOL_GPL
+-0x4db0cbcf    fib_rules_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0x5fe6f617    skb_copy_bits   vmlinux EXPORT_SYMBOL
+-0x71bf6cf0    __blk_end_request_all   vmlinux EXPORT_SYMBOL
+-0xede99a14    crypto_register_ahash   vmlinux EXPORT_SYMBOL_GPL
+-0xbdb3fd8c    sysfs_remove_link       vmlinux EXPORT_SYMBOL_GPL
+-0x8924eb1e    rcu_force_quiescent_state       vmlinux EXPORT_SYMBOL_GPL
+-0xe77924e8    drm_match_cea_mode      vmlinux EXPORT_SYMBOL
+-0x189868d7    get_random_bytes_arch   vmlinux EXPORT_SYMBOL
+-0x3aeef779    tcp_make_synack vmlinux EXPORT_SYMBOL
+-0xc1c0b09b    snd_soc_add_codec_controls      vmlinux EXPORT_SYMBOL_GPL
+-0xcc402882    find_get_page   vmlinux EXPORT_SYMBOL
+-0x7d59dd46    pm_wq   vmlinux EXPORT_SYMBOL_GPL
+-0x9a47820d    hrtimer_forward vmlinux EXPORT_SYMBOL_GPL
+-0xa1f0ebea    bit_waitqueue   vmlinux EXPORT_SYMBOL
+-0x52bd048a    iio_get_channel_type    vmlinux EXPORT_SYMBOL_GPL
+-0x37b330b1    mii_check_gmii_support  vmlinux EXPORT_SYMBOL
+-0x964bc3de    dma_async_device_register       vmlinux EXPORT_SYMBOL
+-0x0adc9704    display_timings_release vmlinux EXPORT_SYMBOL_GPL
+-0xe6c818f2    sock_common_recvmsg     vmlinux EXPORT_SYMBOL
+-0xb62a00b3    mem_cgroup_subsys       vmlinux EXPORT_SYMBOL
+-0x64652950    __video_register_device vmlinux EXPORT_SYMBOL
+-0x9572f9d0    inet_csk_addr2sockaddr  vmlinux EXPORT_SYMBOL_GPL
+-0xeda0d76e    gen_estimator_active    vmlinux EXPORT_SYMBOL
+-0x8251bcc3    bitmap_release_region   vmlinux EXPORT_SYMBOL
+-0x5567c227    kernel_cpustat  vmlinux EXPORT_SYMBOL
+-0x9133fe16    vb2_write       vmlinux EXPORT_SYMBOL_GPL
+-0x9bb89701    cfg80211_roamed vmlinux EXPORT_SYMBOL
+-0x5eb03c4c    ip_mc_inc_group vmlinux EXPORT_SYMBOL
+-0x06438115    tcp_orphan_count        vmlinux EXPORT_SYMBOL_GPL
+-0x43804ba2    fat_attach      vmlinux EXPORT_SYMBOL_GPL
+-0x30788c84    sysfs_remove_bin_file   vmlinux EXPORT_SYMBOL_GPL
+-0xb11bad4f    register_wide_hw_breakpoint     vmlinux EXPORT_SYMBOL_GPL
+-0xbd8b253c    tcf_exts_validate       vmlinux EXPORT_SYMBOL
+-0xb81960ca    snprintf        vmlinux EXPORT_SYMBOL
+-0x7cae600c    get_io_context  vmlinux EXPORT_SYMBOL
+-0x70bb651d    __tracepoint_block_rq_remap     vmlinux EXPORT_SYMBOL_GPL
+-0x9be42ea4    proc_mkdir_mode vmlinux EXPORT_SYMBOL
+-0xf0701cc6    tag_pages_for_writeback vmlinux EXPORT_SYMBOL
+-0x3cf525fb    hid_dump_device vmlinux EXPORT_SYMBOL_GPL
+-0x219e9575    wakeup_source_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0xff43d5b5    cfg80211_check_station_change   vmlinux EXPORT_SYMBOL
+-0x2296c00d    crypto_attr_u32 vmlinux EXPORT_SYMBOL_GPL
+-0x710eaf23    PDE_DATA        vmlinux EXPORT_SYMBOL
+-0xc1fac3b3    __bread vmlinux EXPORT_SYMBOL
+-0x55af945f    follow_pfn      vmlinux EXPORT_SYMBOL
+-0x275ae863    make_kuid       vmlinux EXPORT_SYMBOL
+-0x54d8b7ba    hrtimer_init    vmlinux EXPORT_SYMBOL_GPL
+-0x7c8f0303    dma_buf_export_named    vmlinux EXPORT_SYMBOL_GPL
+-0x079f8b38    devm_kzalloc    vmlinux EXPORT_SYMBOL_GPL
+-0x9ddbb3f6    tty_port_link_device    vmlinux EXPORT_SYMBOL_GPL
+-0x9e8d08a7    pinctrl_find_and_add_gpio_range vmlinux EXPORT_SYMBOL_GPL
+-0x9ceb163c    memcpy_toiovec  vmlinux EXPORT_SYMBOL
+-0x44c38935    v4l2_subdev_g_ext_ctrls vmlinux EXPORT_SYMBOL
+-0xc5fab8f0    v4l2_subdev_s_ext_ctrls vmlinux EXPORT_SYMBOL
+-0x4cf092e4    scsi_report_opcode      vmlinux EXPORT_SYMBOL
+-0x1b6314fd    in_aton vmlinux EXPORT_SYMBOL
+-0x1027ae8c    neigh_resolve_output    vmlinux EXPORT_SYMBOL
+-0xc492c2d9    snd_card_register       vmlinux EXPORT_SYMBOL
+-0xa3018431    posix_unblock_lock      vmlinux EXPORT_SYMBOL
+-0xf3d6e3aa    __mnt_is_readonly       vmlinux EXPORT_SYMBOL_GPL
+-0x87984b16    __tracepoint_cpu_idle   vmlinux EXPORT_SYMBOL_GPL
+-0x89205531    cfb_imageblit   vmlinux EXPORT_SYMBOL
+-0x3bbf46ea    vga_base        vmlinux EXPORT_SYMBOL
+-0x6fea34fd    tcp_close       vmlinux EXPORT_SYMBOL
+-0x7bd5c87c    inet_add_offload        vmlinux EXPORT_SYMBOL
+-0x024ea18c    nf_nat_irc_hook vmlinux EXPORT_SYMBOL_GPL
+-0x18d1ab6f    nf_nat_ftp_hook vmlinux EXPORT_SYMBOL_GPL
+-0xeb780f0e    nfq_ct_nat_hook vmlinux EXPORT_SYMBOL_GPL
+-0x06277150    __scm_send      vmlinux EXPORT_SYMBOL
+-0xc49eea50    skb_try_coalesce        vmlinux EXPORT_SYMBOL
+-0xec007de7    snd_soc_dapm_new_controls       vmlinux EXPORT_SYMBOL_GPL
+-0xa07ed110    xz_dec_init     vmlinux EXPORT_SYMBOL
+-0x3dd4d3a7    bprintf vmlinux EXPORT_SYMBOL_GPL
+-0xa4a0aeb8    try_to_free_buffers     vmlinux EXPORT_SYMBOL
+-0xe9f098a6    wait_iff_congested      vmlinux EXPORT_SYMBOL
+-0xcb5bf3f1    __put_cred      vmlinux EXPORT_SYMBOL
+-0x3f80e476    get_thermal_instance    vmlinux EXPORT_SYMBOL
+-0xb6979f60    usb_register_dev        vmlinux EXPORT_SYMBOL_GPL
+-0xe0d8227f    scsi_dma_map    vmlinux EXPORT_SYMBOL
+-0xa5de5bb1    blk_queue_bypass_start  vmlinux EXPORT_SYMBOL_GPL
+-0xb9617f29    dm_path_uevent  vmlinux EXPORT_SYMBOL_GPL
+-0xd909cae6    serial8250_clear_and_reinit_fifos       vmlinux EXPORT_SYMBOL_GPL
+-0x755da9a0    register_framebuffer    vmlinux EXPORT_SYMBOL
+-0x9ed685ee    iov_iter_advance        vmlinux EXPORT_SYMBOL
+-0xf86a3a9f    clk_gate_ops    vmlinux EXPORT_SYMBOL_GPL
+-0xfcc9ce6a    mmc_of_parse    vmlinux EXPORT_SYMBOL
+-0xb486e84e    mfd_remove_devices      vmlinux EXPORT_SYMBOL
+-0xc5a484ac    pm_generic_suspend_late vmlinux EXPORT_SYMBOL_GPL
+-0x3cd06035    add_input_randomness    vmlinux EXPORT_SYMBOL_GPL
+-0xf50d8f59    regulator_enable_regmap vmlinux EXPORT_SYMBOL_GPL
+-0x09774d0b    pinctrl_force_sleep     vmlinux EXPORT_SYMBOL_GPL
+-0xc7c3c6d2    ip6_tnl_dst_reset       vmlinux EXPORT_SYMBOL_GPL
+-0x225d0386    nf_ct_l4proto_pernet_register   vmlinux EXPORT_SYMBOL_GPL
+-0xf7d31a5d    nf_ct_l3proto_pernet_register   vmlinux EXPORT_SYMBOL_GPL
+-0x8401c62f    scsi_unblock_requests   vmlinux EXPORT_SYMBOL
+-0x8ca1a1dc    device_remove_bin_file  vmlinux EXPORT_SYMBOL_GPL
+-0xccb1ba6b    of_get_drm_display_mode vmlinux EXPORT_SYMBOL_GPL
+-0xe3f48cba    tty_port_free_xmit_buf  vmlinux EXPORT_SYMBOL
+-0xec1b043e    regulator_suspend_prepare       vmlinux EXPORT_SYMBOL_GPL
+-0xecbda9c5    display_entity_get      vmlinux EXPORT_SYMBOL_GPL
+-0x13b89dee    pinctrl_request_gpio    vmlinux EXPORT_SYMBOL_GPL
+-0xdcb3410a    nf_ct_deliver_cached_events     vmlinux EXPORT_SYMBOL_GPL
+-0x32ddd5b6    call_rcu        vmlinux EXPORT_SYMBOL_GPL
+-0xf1267848    usb_composite_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0x877509c0    crypto_nivaead_type     vmlinux EXPORT_SYMBOL_GPL
+-0x9263cf47    bdi_writeout_inc        vmlinux EXPORT_SYMBOL_GPL
+-0x26f6b499    iio_str_to_fixpoint     vmlinux EXPORT_SYMBOL_GPL
+-0x7267db00    hwrng_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0x19cbf31d    xfrm6_rcv_spi   vmlinux EXPORT_SYMBOL
+-0xe5a42822    ip_tunnel_change_mtu    vmlinux EXPORT_SYMBOL_GPL
+-0xf236a5de    tcf_exts_change vmlinux EXPORT_SYMBOL
+-0x058b95e3    snd_pcm_release_substream       vmlinux EXPORT_SYMBOL
+-0x9a6e183a    __idr_remove_all        vmlinux EXPORT_SYMBOL
+-0x7b9bf08e    disk_stack_limits       vmlinux EXPORT_SYMBOL
+-0x9879932b    crypto_register_notifier        vmlinux EXPORT_SYMBOL_GPL
+-0xd220cf8a    jiffies_to_timespec     vmlinux EXPORT_SYMBOL
+-0xce4f758e    dma_release_from_coherent       vmlinux EXPORT_SYMBOL
+-0xe238b99e    pskb_put        vmlinux EXPORT_SYMBOL_GPL
+-0xe11dd614    fib_table_lookup        vmlinux EXPORT_SYMBOL_GPL
+-0x3862b0a7    snd_soc_bytes_put       vmlinux EXPORT_SYMBOL_GPL
+-0xa5ed8e2c    inc_nlink       vmlinux EXPORT_SYMBOL
+-0xf43bdbf8    smpboot_unregister_percpu_thread        vmlinux EXPORT_SYMBOL_GPL
+-0x8a1ab4ee    timeval_to_jiffies      vmlinux EXPORT_SYMBOL
+-0x39375395    i2c_master_send vmlinux EXPORT_SYMBOL
+-0x3a517b2b    device_reprobe  vmlinux EXPORT_SYMBOL_GPL
+-0xb22e34bd    wiphy_free      vmlinux EXPORT_SYMBOL
+-0x76a01893    __netlink_dump_start    vmlinux EXPORT_SYMBOL
+-0xa96c3c3b    dev_kfree_skb_any       vmlinux EXPORT_SYMBOL
+-0xfdaeced1    snd_ctl_new1    vmlinux EXPORT_SYMBOL
+-0xb4f57a24    security_task_getsecid  vmlinux EXPORT_SYMBOL
+-0x09d71f87    seq_open        vmlinux EXPORT_SYMBOL
+-0x29a73c29    mnt_drop_write  vmlinux EXPORT_SYMBOL_GPL
+-0xbcdd5b99    iommu_group_set_name    vmlinux EXPORT_SYMBOL_GPL
+-0x7e394c4e    sysctl_local_reserved_ports     vmlinux EXPORT_SYMBOL
+-0x094bac5f    simple_readpage vmlinux EXPORT_SYMBOL
+-0x5a39720e    __lock_page     vmlinux EXPORT_SYMBOL
+-0xb140d14c    ring_buffer_read        vmlinux EXPORT_SYMBOL_GPL
+-0xf499fdb2    rcu_barrier_bh  vmlinux EXPORT_SYMBOL_GPL
+-0x03d9fff7    synchronize_srcu_expedited      vmlinux EXPORT_SYMBOL_GPL
+-0x1c0ae7d7    drm_mm_init_scan        vmlinux EXPORT_SYMBOL
+-0x8320bea8    __umodsi3       vmlinux EXPORT_SYMBOL
+-0xc3706dce    tcp_cong_avoid_ai       vmlinux EXPORT_SYMBOL_GPL
+-0xab6bde28    sysctl_max_syn_backlog  vmlinux EXPORT_SYMBOL
+-0x5d90d2ce    blk_delay_queue vmlinux EXPORT_SYMBOL
+-0xefdd70ce    security_secid_to_secctx        vmlinux EXPORT_SYMBOL
+-0x77d67659    follow_down     vmlinux EXPORT_SYMBOL
+-0x083eb1cc    __generic_file_aio_write        vmlinux EXPORT_SYMBOL
+-0x46646afc    filemap_write_and_wait_range    vmlinux EXPORT_SYMBOL
+-0xc72c4abb    usb_altnum_to_altsetting        vmlinux EXPORT_SYMBOL_GPL
+-0x0a98333a    snd_soc_dpcm_get_substream      vmlinux EXPORT_SYMBOL_GPL
+-0x360b1afe    probe_irq_mask  vmlinux EXPORT_SYMBOL
+-0x8f2154e4    cfg80211_rx_mgmt        vmlinux EXPORT_SYMBOL
+-0xafa574d0    snd_soc_jack_notifier_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0x93af86c9    get_write_access        vmlinux EXPORT_SYMBOL
+-0x2350c4a6    invalidate_mapping_pages        vmlinux EXPORT_SYMBOL
+-0x84c6c77a    genphy_read_status      vmlinux EXPORT_SYMBOL
+-0x96fb7fef    drm_mode_create_dithering_property      vmlinux EXPORT_SYMBOL
+-0xef56f51e    redraw_screen   vmlinux EXPORT_SYMBOL
+-0x2394545f    tty_unregister_driver   vmlinux EXPORT_SYMBOL
+-0xf3bf0bce    __bitmap_complement     vmlinux EXPORT_SYMBOL
+-0xe2e8065e    memdup_user     vmlinux EXPORT_SYMBOL
+-0x3bdd0f94    v4l2_prio_change        vmlinux EXPORT_SYMBOL
+-0x7ab9b430    drm_poll        vmlinux EXPORT_SYMBOL
+-0x760d494e    pinctrl_find_gpio_range_from_pin        vmlinux EXPORT_SYMBOL_GPL
+-0xcca27eeb    del_timer       vmlinux EXPORT_SYMBOL
+-0x39e773af    thermal_cooling_device_unregister       vmlinux EXPORT_SYMBOL_GPL
+-0xcba9dbcf    dma_get_required_mask   vmlinux EXPORT_SYMBOL_GPL
+-0x2fb1d233    nf_log_unbind_pf        vmlinux EXPORT_SYMBOL
+-0x460f7531    wait_rcu_gp     vmlinux EXPORT_SYMBOL_GPL
+-0x9bfaf424    usb_get_current_frame_number    vmlinux EXPORT_SYMBOL_GPL
+-0xad9bbf9f    hci_suspend_dev vmlinux EXPORT_SYMBOL
+-0x56c5a136    tcp_v4_send_check       vmlinux EXPORT_SYMBOL
+-0x0a4862b9    nf_ct_expect_find_get   vmlinux EXPORT_SYMBOL_GPL
+-0x30e3e930    dev_close       vmlinux EXPORT_SYMBOL
+-0xc3e46db4    snd_pcm_lib_free_pages  vmlinux EXPORT_SYMBOL
+-0x3b735a2b    __mark_inode_dirty      vmlinux EXPORT_SYMBOL
+-0x91437bc9    dma_buf_put     vmlinux EXPORT_SYMBOL_GPL
+-0x8e09c957    dma_buf_get     vmlinux EXPORT_SYMBOL_GPL
+-0x98aba977    ip6_update_pmtu vmlinux EXPORT_SYMBOL_GPL
+-0x019daa72    noop_qdisc      vmlinux EXPORT_SYMBOL
+-0x240646b9    sock_alloc_send_skb     vmlinux EXPORT_SYMBOL
+-0x871f2cb1    snd_soc_dapm_nc_pin     vmlinux EXPORT_SYMBOL_GPL
+-0x97440f69    snd_card_disconnect     vmlinux EXPORT_SYMBOL
+-0xd9ce8f0c    strnlen vmlinux EXPORT_SYMBOL
+-0xe7c9dbc0    unregister_filesystem   vmlinux EXPORT_SYMBOL
+-0x4abbe3c2    vm_brk  vmlinux EXPORT_SYMBOL
+-0x2439abc9    irq_domain_add_simple   vmlinux EXPORT_SYMBOL_GPL
+-0xd418e1c0    adjust_resource vmlinux EXPORT_SYMBOL
+-0x31c0c2d1    dm_put  vmlinux EXPORT_SYMBOL_GPL
+-0x140e371b    v4l2_of_get_remote_port_parent  vmlinux EXPORT_SYMBOL
+-0x3adbd595    v4l2_field_names        vmlinux EXPORT_SYMBOL
+-0xdcece020    xfrm_state_insert       vmlinux EXPORT_SYMBOL
+-0xf8fe3d0b    kmsg_dump_register      vmlinux EXPORT_SYMBOL_GPL
+-0x40728a63    xt_find_revision        vmlinux EXPORT_SYMBOL_GPL
+-0xcb534ec9    __destroy_inode vmlinux EXPORT_SYMBOL
+-0xea1f5b88    samsung_rev     vmlinux EXPORT_SYMBOL
+-0xd3dd145a    tcp_is_cwnd_limited     vmlinux EXPORT_SYMBOL_GPL
+-0x392697b4    nf_conntrack_l3proto_generic    vmlinux EXPORT_SYMBOL_GPL
+-0x2549013a    snd_soc_dai_set_channel_map     vmlinux EXPORT_SYMBOL_GPL
+-0x421e53cf    blk_rq_unmap_user       vmlinux EXPORT_SYMBOL
+-0xacf1d33d    crypto_mod_get  vmlinux EXPORT_SYMBOL_GPL
+-0x0bc477a2    irq_set_irq_type        vmlinux EXPORT_SYMBOL
+-0xce2840e7    irq_set_irq_wake        vmlinux EXPORT_SYMBOL
+-0x2650d835    sysctl_ip_early_demux   vmlinux EXPORT_SYMBOL
+-0x07e472e5    __remove_inode_hash     vmlinux EXPORT_SYMBOL
+-0x82b7cda8    __lru_cache_add vmlinux EXPORT_SYMBOL
+-0x457b77ca    of_fixed_factor_clk_setup       vmlinux EXPORT_SYMBOL_GPL
+-0x840b929e    v4l2_device_unregister_subdev   vmlinux EXPORT_SYMBOL_GPL
+-0x6128b5fc    __printk_ratelimit      vmlinux EXPORT_SYMBOL
+-0xcc1f1c3d    inet_twdr_hangman       vmlinux EXPORT_SYMBOL_GPL
+-0x71faed49    __blk_end_request_cur   vmlinux EXPORT_SYMBOL
+-0xab5cbfa1    __blk_end_request_err   vmlinux EXPORT_SYMBOL_GPL
+-0xb2682405    utf8_to_utf32   vmlinux EXPORT_SYMBOL
+-0x9621849f    ring_buffer_event_data  vmlinux EXPORT_SYMBOL_GPL
+-0x2761c400    pm_generic_restore_early        vmlinux EXPORT_SYMBOL_GPL
+-0x36d31f9e    crypto_sha1_update      vmlinux EXPORT_SYMBOL
+-0x8798e453    __tracepoint_kfree      vmlinux EXPORT_SYMBOL
+-0x247ba373    override_creds  vmlinux EXPORT_SYMBOL
+-0x131db64a    system_long_wq  vmlinux EXPORT_SYMBOL_GPL
+-0xc0d26387    kmsg_dump_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0x6b132713    __clk_register  vmlinux EXPORT_SYMBOL_GPL
+-0x5292f4ea    scsi_prep_return        vmlinux EXPORT_SYMBOL
+-0x34a13791    __pm_runtime_disable    vmlinux EXPORT_SYMBOL_GPL
+-0xa10db0ce    phy_pm_runtime_get_sync vmlinux EXPORT_SYMBOL_GPL
+-0x1b62df19    arm_iommu_create_mapping        vmlinux EXPORT_SYMBOL_GPL
+-0x606d0b09    secure_tcpv6_sequence_number    vmlinux EXPORT_SYMBOL
+-0xa75bc594    blkdev_issue_zeroout    vmlinux EXPORT_SYMBOL
+-0x8f12669a    irq_linear_revmap       vmlinux EXPORT_SYMBOL_GPL
+-0x938244d0    handle_level_irq        vmlinux EXPORT_SYMBOL_GPL
+-0xb336e1d2    extcon_set_cable_state_ vmlinux EXPORT_SYMBOL_GPL
+-0x067ef5d5    extcon_get_cable_state_ vmlinux EXPORT_SYMBOL_GPL
+-0x8d22bb58    iommu_group_alloc       vmlinux EXPORT_SYMBOL_GPL
+-0xa7e20df3    clk_mux_ops     vmlinux EXPORT_SYMBOL_GPL
+-0x7f9eeaae    input_register_handle   vmlinux EXPORT_SYMBOL
+-0x6cc78c5c    set_irq_flags   vmlinux EXPORT_SYMBOL_GPL
+-0xc781bd9f    rfkill_resume_polling   vmlinux EXPORT_SYMBOL
+-0x982e6b6d    ieee80211_radiotap_iterator_init        vmlinux EXPORT_SYMBOL
+-0xf30fda27    lzo1x_decompress_safe   vmlinux EXPORT_SYMBOL_GPL
+-0x42b364ef    scatterwalk_done        vmlinux EXPORT_SYMBOL_GPL
+-0x2158c0d7    kern_unmount    vmlinux EXPORT_SYMBOL
+-0xd31ccb06    of_machine_is_compatible        vmlinux EXPORT_SYMBOL
+-0xd6d49c42    sdio_writesb    vmlinux EXPORT_SYMBOL_GPL
+-0xe6fa2163    v4l2_async_notifier_unregister  vmlinux EXPORT_SYMBOL
+-0x20234f83    nla_append      vmlinux EXPORT_SYMBOL
+-0x4cf41ed3    skcipher_geniv_free     vmlinux EXPORT_SYMBOL_GPL
+-0x4bc07110    jbd2_journal_lock_updates       vmlinux EXPORT_SYMBOL
+-0xf37671d2    vfs_llseek      vmlinux EXPORT_SYMBOL
+-0x8720876b    __page_file_index       vmlinux EXPORT_SYMBOL_GPL
+-0x609d9c25    __irq_set_handler       vmlinux EXPORT_SYMBOL_GPL
+-0x2d17a0e1    cgroup_taskset_size     vmlinux EXPORT_SYMBOL_GPL
+-0xabe27502    v4l2_ctrl_query_fill    vmlinux EXPORT_SYMBOL
+-0x5b1a060c    usb_control_msg vmlinux EXPORT_SYMBOL_GPL
+-0xe59c5ea4    snd_dma_free_pages      vmlinux EXPORT_SYMBOL
+-0x85541e31    iterate_fd      vmlinux EXPORT_SYMBOL
+-0x7ceaf0d5    generic_handle_irq      vmlinux EXPORT_SYMBOL_GPL
+-0x46feb099    dm_read_arg     vmlinux EXPORT_SYMBOL
+-0xe8125c91    dev_set_drvdata vmlinux EXPORT_SYMBOL
+-0x8d60d310    dev_get_drvdata vmlinux EXPORT_SYMBOL
+-0x84510ec6    bt_sock_unlink  vmlinux EXPORT_SYMBOL
+-0x14f626f7    snd_soc_dapm_add_routes vmlinux EXPORT_SYMBOL_GPL
+-0x5d1c1bac    blocking_notifier_chain_cond_register   vmlinux EXPORT_SYMBOL_GPL
+-0xefd5b1f1    nfc_hci_disconnect_all_gates    vmlinux EXPORT_SYMBOL
+-0x009c0acf    __xfrm_state_destroy    vmlinux EXPORT_SYMBOL
+-0x256e5691    bfifo_qdisc_ops vmlinux EXPORT_SYMBOL
+-0x1f8544b8    panic_timeout   vmlinux EXPORT_SYMBOL_GPL
+-0x5b4e379c    of_prop_next_u32        vmlinux EXPORT_SYMBOL_GPL
+-0x8106095a    v4l2_prio_max   vmlinux EXPORT_SYMBOL
+-0xfff74a32    usb_unpoison_urb        vmlinux EXPORT_SYMBOL_GPL
+-0xc532db16    tty_port_init   vmlinux EXPORT_SYMBOL
+-0xa20ce1b8    net_msg_warn    vmlinux EXPORT_SYMBOL
+-0x2aa97a28    __sock_recv_timestamp   vmlinux EXPORT_SYMBOL_GPL
+-0x6225637e    md5_transform   vmlinux EXPORT_SYMBOL
+-0xa3301b08    noop_fsync      vmlinux EXPORT_SYMBOL
+-0x31ab0e28    extcon_dev_unregister   vmlinux EXPORT_SYMBOL_GPL
+-0xc5176fe9    usb_hcd_resume_root_hub vmlinux EXPORT_SYMBOL_GPL
+-0x13bdb1fd    cfg80211_ibss_joined    vmlinux EXPORT_SYMBOL
+-0x587763dd    blkdev_issue_write_same vmlinux EXPORT_SYMBOL
+-0x627b7988    crypto_hash_walk_first  vmlinux EXPORT_SYMBOL_GPL
+-0x85d438aa    scsi_add_host_with_dma  vmlinux EXPORT_SYMBOL
+-0x2b26ce97    devres_remove_group     vmlinux EXPORT_SYMBOL_GPL
+-0x8e007d5e    inet_sendpage   vmlinux EXPORT_SYMBOL
+-0xbb713e6d    sk_filter_release_rcu   vmlinux EXPORT_SYMBOL
+-0xf1dc9acb    dev_get_by_index_rcu    vmlinux EXPORT_SYMBOL
+-0x5364397d    dev_set_allmulti        vmlinux EXPORT_SYMBOL
+-0xd20a4e9e    snd_ctl_remove_id       vmlinux EXPORT_SYMBOL
+-0xea10655a    __bitmap_intersects     vmlinux EXPORT_SYMBOL
+-0xf313da4e    sha_transform   vmlinux EXPORT_SYMBOL
+-0x9b6eb137    ksize   vmlinux EXPORT_SYMBOL
+-0x38869d88    kstat   vmlinux EXPORT_SYMBOL
+-0x43caf714    mmc_can_erase   vmlinux EXPORT_SYMBOL
+-0xa42810a9    i2c_add_adapter vmlinux EXPORT_SYMBOL
+-0xaf5ddb02    input_mt_report_finger_count    vmlinux EXPORT_SYMBOL
+-0x3a09b033    drm_mmap        vmlinux EXPORT_SYMBOL
+-0xcc16f79c    drm_kms_helper_poll_fini        vmlinux EXPORT_SYMBOL
+-0xe707d823    __aeabi_uidiv   vmlinux EXPORT_SYMBOL
+-0xcd2a33d7    hci_conn_security       vmlinux EXPORT_SYMBOL
+-0xd456425d    kobject_set_name        vmlinux EXPORT_SYMBOL
+-0x60642a60    shmem_truncate_range    vmlinux EXPORT_SYMBOL_GPL
+-0xa3e7c113    ring_buffer_iter_peek   vmlinux EXPORT_SYMBOL_GPL
+-0xa5efbf4c    async_synchronize_full  vmlinux EXPORT_SYMBOL_GPL
+-0x3ac75973    dm_send_uevents vmlinux EXPORT_SYMBOL_GPL
+-0x47f757de    elf_platform    vmlinux EXPORT_SYMBOL
+-0x48994b32    bt_debugfs      vmlinux EXPORT_SYMBOL_GPL
+-0xc3f4c43b    set_device_ro   vmlinux EXPORT_SYMBOL
+-0xbb038ce4    perf_unregister_guest_info_callbacks    vmlinux EXPORT_SYMBOL_GPL
+-0x8cc44150    of_clk_src_simple_get   vmlinux EXPORT_SYMBOL_GPL
+-0x09378170    shash_attr_alg  vmlinux EXPORT_SYMBOL_GPL
+-0x63eb9355    panic_blink     vmlinux EXPORT_SYMBOL
+-0x37df5b58    usb_anchor_urb  vmlinux EXPORT_SYMBOL_GPL
+-0x665ccdb6    __sync_dirty_buffer     vmlinux EXPORT_SYMBOL
+-0xb370f2b0    kmap_high       vmlinux EXPORT_SYMBOL
+-0xc3042166    cancel_dirty_page       vmlinux EXPORT_SYMBOL
+-0xf4fc2d6c    __ring_buffer_alloc     vmlinux EXPORT_SYMBOL_GPL
+-0x82072614    tasklet_kill    vmlinux EXPORT_SYMBOL
+-0x653cd720    exynos_g2d_set_cmdlist_ioctl    vmlinux EXPORT_SYMBOL_GPL
+-0xa2a78b0e    blk_post_runtime_resume vmlinux EXPORT_SYMBOL
+-0xf7f02ddf    bio_endio       vmlinux EXPORT_SYMBOL
+-0x269b337f    account_page_redirty    vmlinux EXPORT_SYMBOL
+-0x85c7f674    ring_buffer_normalize_time_stamp        vmlinux EXPORT_SYMBOL_GPL
+-0xf4597085    i2c_use_client  vmlinux EXPORT_SYMBOL
+-0x2da746c5    scsi_print_command      vmlinux EXPORT_SYMBOL
+-0xd0e73a87    amba_driver_register    vmlinux EXPORT_SYMBOL
+-0x3810da45    nf_ct_expect_unregister_notifier        vmlinux EXPORT_SYMBOL_GPL
+-0x50b236e9    eth_prepare_mac_addr_change     vmlinux EXPORT_SYMBOL
+-0xd32c0bf4    sk_stop_timer   vmlinux EXPORT_SYMBOL
+-0xffdb82bc    sg_free_table   vmlinux EXPORT_SYMBOL
+-0xfcbba27f    locks_remove_posix      vmlinux EXPORT_SYMBOL
+-0xb0b85f47    ring_buffer_iter_reset  vmlinux EXPORT_SYMBOL_GPL
+-0x43b0c9c3    preempt_schedule        vmlinux EXPORT_SYMBOL
+-0x7c010229    of_platform_bus_probe   vmlinux EXPORT_SYMBOL
+-0xf74656ab    regulator_can_change_voltage    vmlinux EXPORT_SYMBOL_GPL
+-0x5d5b5a16    radix_tree_delete       vmlinux EXPORT_SYMBOL
+-0x4b37f24f    of_extcon_get_extcon_dev        vmlinux EXPORT_SYMBOL_GPL
+-0x728be72e    pm_generic_thaw_noirq   vmlinux EXPORT_SYMBOL_GPL
+-0x94de4a33    tcp_slow_start  vmlinux EXPORT_SYMBOL_GPL
+-0x4a73178a    dev_activate    vmlinux EXPORT_SYMBOL
+-0x7649cfce    __pneigh_lookup vmlinux EXPORT_SYMBOL_GPL
+-0xaafcd87b    devm_iounmap    vmlinux EXPORT_SYMBOL
+-0x3bfc99a5    devm_ioremap    vmlinux EXPORT_SYMBOL
+-0x5541ea93    on_each_cpu     vmlinux EXPORT_SYMBOL
+-0x176af8ec    cdc_ncm_rx_verify_ndp16 vmlinux EXPORT_SYMBOL_GPL
+-0x572d7fe7    pn544_hci_remove        vmlinux EXPORT_SYMBOL
+-0x74e5ff1a    udpv6_encap_enable      vmlinux EXPORT_SYMBOL
+-0x7a08f61d    snd_pcm_set_sync        vmlinux EXPORT_SYMBOL
+-0x164b50d3    nla_reserve     vmlinux EXPORT_SYMBOL
+-0x08758d9c    bioset_create   vmlinux EXPORT_SYMBOL
+-0x08365975    drm_gem_object_lookup   vmlinux EXPORT_SYMBOL
+-0x862b9816    cpu_topology    vmlinux EXPORT_SYMBOL_GPL
+-0x3722cf9f    rtnl_put_cacheinfo      vmlinux EXPORT_SYMBOL_GPL
+-0xea124bd1    gcd     vmlinux EXPORT_SYMBOL_GPL
+-0xce3e95d0    ihold   vmlinux EXPORT_SYMBOL
+-0xd11031b4    names_cachep    vmlinux EXPORT_SYMBOL
+-0x8890cade    invalidate_inode_pages2_range   vmlinux EXPORT_SYMBOL_GPL
+-0x83130f62    cancel_delayed_work     vmlinux EXPORT_SYMBOL
+-0xcbc428db    __cpufreq_driver_target vmlinux EXPORT_SYMBOL_GPL
+-0xd6233445    xfrm_policy_register_afinfo     vmlinux EXPORT_SYMBOL
+-0xc8afb46b    snd_info_create_card_entry      vmlinux EXPORT_SYMBOL
+-0xb7850524    crypto_unregister_shashes       vmlinux EXPORT_SYMBOL_GPL
+-0x4acc9be5    dentry_path_raw vmlinux EXPORT_SYMBOL
+-0x475ea860    xfrm_sad_getinfo        vmlinux EXPORT_SYMBOL
+-0x9429e18f    netif_napi_del  vmlinux EXPORT_SYMBOL
+-0x03a3ce75    crypto_register_alg     vmlinux EXPORT_SYMBOL_GPL
+-0x1a3e0511    debugfs_rename  vmlinux EXPORT_SYMBOL_GPL
+-0xb69186d9    simple_open     vmlinux EXPORT_SYMBOL
+-0xe513ed5c    single_open     vmlinux EXPORT_SYMBOL
+-0x9072472b    page_follow_link_light  vmlinux EXPORT_SYMBOL
+-0xdbbd4688    __page_file_mapping     vmlinux EXPORT_SYMBOL_GPL
+-0x0f751aea    input_event_from_user   vmlinux EXPORT_SYMBOL_GPL
+-0x4484a5a4    wait_for_device_probe   vmlinux EXPORT_SYMBOL_GPL
+-0xd53e17fd    tty_port_put    vmlinux EXPORT_SYMBOL
+-0xa1b759ce    fb_add_videomode        vmlinux EXPORT_SYMBOL
+-0x3c831441    arm_check_condition     vmlinux EXPORT_SYMBOL_GPL
+-0x44fa52dd    brcmu_pktq_mdeq drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x471d6f83    brcmu_pktq_mlen drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x6af410ae    cfg80211_send_disassoc  vmlinux EXPORT_SYMBOL
+-0x1baa3892    xfrm6_find_1stfragopt   vmlinux EXPORT_SYMBOL
+-0x198788b4    snd_lookup_oss_minor_data       vmlinux EXPORT_SYMBOL
+-0x4a3ea5c0    snd_request_card        vmlinux EXPORT_SYMBOL
+-0x56451890    register_ftrace_event   vmlinux EXPORT_SYMBOL_GPL
+-0x4ae313f9    kthread_stop    vmlinux EXPORT_SYMBOL
+-0x1438fff0    st_sensors_sysfs_scale_avail    vmlinux EXPORT_SYMBOL
+-0x31178006    clk_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0x083c2cbe    of_get_next_parent      vmlinux EXPORT_SYMBOL
+-0xfef96e23    __scsi_print_command    vmlinux EXPORT_SYMBOL
+-0x670cff67    drm_helper_disable_unused_functions     vmlinux EXPORT_SYMBOL
+-0xe7048594    cfg80211_chandef_create vmlinux EXPORT_SYMBOL
+-0x020d1750    cfg80211_tdls_oper_request      vmlinux EXPORT_SYMBOL
+-0xbec63ca7    security_inode_create   vmlinux EXPORT_SYMBOL_GPL
+-0xfe72e11b    dm_register_target      vmlinux EXPORT_SYMBOL
+-0xaa4a7797    hex2bin vmlinux EXPORT_SYMBOL
+-0xe924fd45    crypto_default_rng      vmlinux EXPORT_SYMBOL_GPL
+-0xddab6b08    d_make_root     vmlinux EXPORT_SYMBOL
+-0xa3b40cfd    hid_register_report     vmlinux EXPORT_SYMBOL_GPL
+-0xcda04a5b    v4l2_prio_close vmlinux EXPORT_SYMBOL
+-0x2e12216c    rtc_set_alarm   vmlinux EXPORT_SYMBOL_GPL
+-0xaefe5034    __scsi_get_command      vmlinux EXPORT_SYMBOL_GPL
+-0x31547da3    __scsi_put_command      vmlinux EXPORT_SYMBOL
+-0x0fa5f996    inet_csk_listen_start   vmlinux EXPORT_SYMBOL_GPL
+-0xfcc2a43c    utf32_to_utf8   vmlinux EXPORT_SYMBOL
+-0xeef161aa    groups_free     vmlinux EXPORT_SYMBOL
+-0xc5a25ce7    cleanup_srcu_struct     vmlinux EXPORT_SYMBOL_GPL
+-0xac1a55be    unregister_reboot_notifier      vmlinux EXPORT_SYMBOL
+-0x4557930f    regmap_update_bits_check        vmlinux EXPORT_SYMBOL_GPL
+-0x0e0eb67f    ip6_flush_pending_frames        vmlinux EXPORT_SYMBOL_GPL
+-0xb670b4cf    tcf_destroy_chain       vmlinux EXPORT_SYMBOL
+-0x5fa48b4e    generic_file_remap_pages        vmlinux EXPORT_SYMBOL
+-0xe13fa8ed    regmap_register_patch   vmlinux EXPORT_SYMBOL_GPL
+-0x18c77c17    tty_perform_flush       vmlinux EXPORT_SYMBOL_GPL
+-0x5ece6555    debugfs_remove_recursive        vmlinux EXPORT_SYMBOL_GPL
+-0x1fcf4d4b    _raw_read_unlock_bh     vmlinux EXPORT_SYMBOL
+-0x04cabed9    rfkill_register vmlinux EXPORT_SYMBOL
+-0x774a552a    cfg80211_send_deauth    vmlinux EXPORT_SYMBOL
+-0xc1691764    neigh_parms_alloc       vmlinux EXPORT_SYMBOL
+-0x75fac20b    mount_single    vmlinux EXPORT_SYMBOL
+-0x9ecc6a7a    interruptible_sleep_on  vmlinux EXPORT_SYMBOL
+-0x19a304ba    usb_disabled    vmlinux EXPORT_SYMBOL_GPL
+-0x48f20051    __ip_route_output_key   vmlinux EXPORT_SYMBOL_GPL
+-0x5e7f4920    snd_pcm_format_set_silence      vmlinux EXPORT_SYMBOL
+-0x9ef5a297    blk_queue_invalidate_tags       vmlinux EXPORT_SYMBOL
+-0xffb6db4a    remove_irq      vmlinux EXPORT_SYMBOL_GPL
+-0x93a6e0b2    io_schedule     vmlinux EXPORT_SYMBOL
+-0xa604bba5    cpufreq_notify_transition       vmlinux EXPORT_SYMBOL_GPL
+-0xb9c425de    register_syscore_ops    vmlinux EXPORT_SYMBOL_GPL
+-0x7317fc49    disk_part_iter_next     vmlinux EXPORT_SYMBOL_GPL
+-0xc4c6c770    block_write_end vmlinux EXPORT_SYMBOL
+-0x437e0be6    pid_vnr vmlinux EXPORT_SYMBOL_GPL
+-0xcb476f4a    cfb_fillrect    vmlinux EXPORT_SYMBOL
+-0xc6241aec    cfg80211_roamed_bss     vmlinux EXPORT_SYMBOL
+-0x44336387    __xfrm_decode_session   vmlinux EXPORT_SYMBOL
+-0xf803fe39    bitmap_set      vmlinux EXPORT_SYMBOL
+-0x1bbcbb78    __pagevec_lru_add       vmlinux EXPORT_SYMBOL
+-0xd1b2db37    tracepoint_probe_register_noupdate      vmlinux EXPORT_SYMBOL_GPL
+-0x230e0698    __clocksource_updatefreq_scale  vmlinux EXPORT_SYMBOL_GPL
+-0xd8004073    sdhci_runtime_resume_host       vmlinux EXPORT_SYMBOL_GPL
+-0x04369954    devm_regmap_init        vmlinux EXPORT_SYMBOL_GPL
+-0xa2a36526    tty_port_lower_dtr_rts  vmlinux EXPORT_SYMBOL
+-0xf369df34    wiphy_rfkill_stop_polling       vmlinux EXPORT_SYMBOL
+-0x253ec879    netlink_set_err vmlinux EXPORT_SYMBOL
+-0x71d7bf40    alloc_netdev_mqs        vmlinux EXPORT_SYMBOL
+-0x336154ca    rcutorture_record_test_transition       vmlinux EXPORT_SYMBOL_GPL
+-0x1aa1c9f2    make_kprojid    vmlinux EXPORT_SYMBOL
+-0xa42a123d    bus_register_notifier   vmlinux EXPORT_SYMBOL_GPL
+-0xd2cf977d    gpiochip_add    vmlinux EXPORT_SYMBOL_GPL
+-0xd3c40b56    inet_listen     vmlinux EXPORT_SYMBOL
+-0xfdc9a24f    __dst_destroy_metrics_generic   vmlinux EXPORT_SYMBOL
+-0x44e276d8    skb_queue_purge vmlinux EXPORT_SYMBOL
+-0x588eccde    get_unmapped_area       vmlinux EXPORT_SYMBOL
+-0x0f29f7c9    add_to_page_cache_lru   vmlinux EXPORT_SYMBOL_GPL
+-0xb7d4b252    iommu_present   vmlinux EXPORT_SYMBOL_GPL
+-0x01c483a9    v4l2_get_timestamp      vmlinux EXPORT_SYMBOL_GPL
+-0xbf041102    register_vt_notifier    vmlinux EXPORT_SYMBOL_GPL
+-0xf85885d1    nci_unregister_device   vmlinux EXPORT_SYMBOL
+-0x07b52e38    rtnl_unregister vmlinux EXPORT_SYMBOL_GPL
+-0xe3bc40f6    dpcm_be_dai_trigger     vmlinux EXPORT_SYMBOL_GPL
+-0xfbed2f3c    snd_soc_info_volsw_range        vmlinux EXPORT_SYMBOL_GPL
+-0x9545974d    blk_rq_map_user vmlinux EXPORT_SYMBOL
+-0x693ca44e    jbd2_journal_clear_features     vmlinux EXPORT_SYMBOL
+-0x538410d3    generic_pipe_buf_release        vmlinux EXPORT_SYMBOL
+-0x8878cfa6    gether_cleanup  vmlinux EXPORT_SYMBOL
+-0xc1c72997    platform_bus_type       vmlinux EXPORT_SYMBOL_GPL
+-0x2c61162c    drm_fb_helper_check_var vmlinux EXPORT_SYMBOL
+-0x7a8cea07    bt_accept_unlink        vmlinux EXPORT_SYMBOL
+-0x61812beb    nf_ct_gre_keymap_add    vmlinux EXPORT_SYMBOL_GPL
+-0xcf596042    d_find_alias    vmlinux EXPORT_SYMBOL
+-0x81d10f5f    trace_seq_putc  vmlinux EXPORT_SYMBOL
+-0x760a0f4f    yield   vmlinux EXPORT_SYMBOL
+-0xac472389    iio_buffer_register     vmlinux EXPORT_SYMBOL
+-0x5dd590c3    sdhci_pltfm_pmops       vmlinux EXPORT_SYMBOL_GPL
+-0x0c5b9900    xt_check_target vmlinux EXPORT_SYMBOL_GPL
+-0xb67c64fd    __tracepoint_kfree_skb  vmlinux EXPORT_SYMBOL_GPL
+-0xd6c2e04b    __tracepoint_napi_poll  vmlinux EXPORT_SYMBOL_GPL
+-0x01bb81cc    netdev_upper_dev_unlink vmlinux EXPORT_SYMBOL
+-0x5bb9daec    __sg_page_iter_start    vmlinux EXPORT_SYMBOL
+-0xac3d64d9    fsstack_copy_attr_all   vmlinux EXPORT_SYMBOL_GPL
+-0xda48e711    sdio_claim_irq  vmlinux EXPORT_SYMBOL_GPL
+-0x1dc36131    fb_destroy_modedb       vmlinux EXPORT_SYMBOL
+-0xca2159d7    udp6_lib_lookup vmlinux EXPORT_SYMBOL_GPL
+-0xbf58f5e7    xfrm_init_replay        vmlinux EXPORT_SYMBOL
+-0xfb74be78    udp4_lib_lookup vmlinux EXPORT_SYMBOL_GPL
+-0x419cfeed    __nf_ct_try_assign_helper       vmlinux EXPORT_SYMBOL_GPL
+-0x610dbc32    genl_unregister_ops     vmlinux EXPORT_SYMBOL
+-0x9e2000a7    memcpy_toiovecend       vmlinux EXPORT_SYMBOL
+-0x3fc5d39f    snd_jack_report vmlinux EXPORT_SYMBOL
+-0x93949c2a    inode_sb_list_add       vmlinux EXPORT_SYMBOL_GPL
+-0x3d4ee67b    inode_init_always       vmlinux EXPORT_SYMBOL
+-0x38883d79    d_invalidate    vmlinux EXPORT_SYMBOL
+-0xa0b04675    vmalloc_32      vmlinux EXPORT_SYMBOL
+-0xedca9389    pid_task        vmlinux EXPORT_SYMBOL
+-0xc1c2b8e5    scsi_command_normalize_sense    vmlinux EXPORT_SYMBOL
+-0x4d0d163d    copy_page       vmlinux EXPORT_SYMBOL
+-0xe0becdbc    set_h245_addr_hook      vmlinux EXPORT_SYMBOL_GPL
+-0xd9a79782    seq_print_acct  vmlinux EXPORT_SYMBOL_GPL
+-0xbc9f30d7    textsearch_unregister   vmlinux EXPORT_SYMBOL
+-0xf54c51a2    dma_pool_free   vmlinux EXPORT_SYMBOL
+-0x32fd447a    monotonic_to_bootbased  vmlinux EXPORT_SYMBOL_GPL
+-0x45a6be13    cpufreq_sysfs_remove_file       vmlinux EXPORT_SYMBOL
+-0x9a5723c8    input_register_handler  vmlinux EXPORT_SYMBOL
+-0x0f618e15    drm_class_device_unregister     vmlinux EXPORT_SYMBOL_GPL
+-0xbae73813    inet6_csk_bind_conflict vmlinux EXPORT_SYMBOL_GPL
+-0xa35de80f    ipv4_config     vmlinux EXPORT_SYMBOL
+-0x7411b488    netif_carrier_on        vmlinux EXPORT_SYMBOL
+-0x1212d241    fib_rules_lookup        vmlinux EXPORT_SYMBOL_GPL
+-0xb0b847ac    __bitmap_full   vmlinux EXPORT_SYMBOL
+-0x4059792f    print_hex_dump  vmlinux EXPORT_SYMBOL
+-0x99d40bce    cfg80211_del_sta        vmlinux EXPORT_SYMBOL
+-0xe8068f48    ip6_route_output        vmlinux EXPORT_SYMBOL
+-0xb57e5e86    __dst_free      vmlinux EXPORT_SYMBOL
+-0x9fb986a9    inode_newsize_ok        vmlinux EXPORT_SYMBOL
+-0xf39a1727    dev_pm_qos_add_notifier vmlinux EXPORT_SYMBOL_GPL
+-0xbb6297fd    drm_mode_group_init_legacy_group        vmlinux EXPORT_SYMBOL
+-0xd3ce735a    drm_crtc_helper_set_config      vmlinux EXPORT_SYMBOL
+-0xa68b2c0b    pn_sock_get_port        vmlinux EXPORT_SYMBOL
+-0x04797338    inet_csk_destroy_sock   vmlinux EXPORT_SYMBOL
+-0x050e881c    inet_peer_base_init     vmlinux EXPORT_SYMBOL_GPL
+-0x84b183ae    strncmp vmlinux EXPORT_SYMBOL
+-0xb6f24459    crypto_register_shashes vmlinux EXPORT_SYMBOL_GPL
+-0x1e26be3b    get_anon_bdev   vmlinux EXPORT_SYMBOL
+-0x6b29a1fa    ring_buffer_event_length        vmlinux EXPORT_SYMBOL_GPL
+-0x5634e278    __clk_get_flags vmlinux EXPORT_SYMBOL_GPL
+-0x2e1ca751    clk_put vmlinux EXPORT_SYMBOL
+-0xf474a207    usb_gadget_config_buf   vmlinux EXPORT_SYMBOL_GPL
+-0x20838fc5    __pm_runtime_idle       vmlinux EXPORT_SYMBOL_GPL
+-0x062de44d    sock_kfree_s    vmlinux EXPORT_SYMBOL
+-0x3796bdcc    snd_pcm_format_little_endian    vmlinux EXPORT_SYMBOL
+-0xa34f1ef5    crc32_le        vmlinux EXPORT_SYMBOL
+-0xf54bd49b    lcm     vmlinux EXPORT_SYMBOL_GPL
+-0x13354608    scatterwalk_map_and_copy        vmlinux EXPORT_SYMBOL_GPL
+-0xf2bec139    empty_aops      vmlinux EXPORT_SYMBOL
+-0x45755a66    __task_pid_nr_ns        vmlinux EXPORT_SYMBOL
+-0xcbc23c9a    ethtool_op_get_link     vmlinux EXPORT_SYMBOL
+-0x5735fbd5    read_cache_pages        vmlinux EXPORT_SYMBOL
+-0x4aadeb9a    ring_buffer_alloc_read_page     vmlinux EXPORT_SYMBOL_GPL
+-0x2f3f62cd    v4l2_try_ext_ctrls      vmlinux EXPORT_SYMBOL
+-0x5d12e48f    input_event_to_user     vmlinux EXPORT_SYMBOL_GPL
+-0x6947468c    input_unregister_device vmlinux EXPORT_SYMBOL
+-0x91600a8e    usb_string_id   vmlinux EXPORT_SYMBOL_GPL
+-0xcc924d52    regulator_disable_regmap        vmlinux EXPORT_SYMBOL_GPL
+-0x3a4402b4    ip_generic_getfrag      vmlinux EXPORT_SYMBOL
+-0x6308d2cf    call_netdevice_notifiers        vmlinux EXPORT_SYMBOL
+-0xc02df0b8    snd_soc_pm_ops  vmlinux EXPORT_SYMBOL_GPL
+-0xf9436986    crypto_dequeue_request  vmlinux EXPORT_SYMBOL_GPL
+-0xb6555d54    crypto_enqueue_request  vmlinux EXPORT_SYMBOL_GPL
+-0x6c2dc956    fat_add_entries vmlinux EXPORT_SYMBOL_GPL
+-0xb7fc7a60    thaw_bdev       vmlinux EXPORT_SYMBOL
+-0x99a170f8    kmem_cache_alloc_trace  vmlinux EXPORT_SYMBOL
+-0x06f22ca2    irq_create_mapping      vmlinux EXPORT_SYMBOL_GPL
+-0x992e5dbd    mii_nway_restart        vmlinux EXPORT_SYMBOL
+-0xa6a0a273    max77693_write_reg      vmlinux EXPORT_SYMBOL_GPL
+-0xa6b21ef2    dpm_suspend_end vmlinux EXPORT_SYMBOL_GPL
+-0x27f9262d    sk_run_filter   vmlinux EXPORT_SYMBOL
+-0x8bfe698b    netdev_rx_csum_fault    vmlinux EXPORT_SYMBOL
+-0x9e61bb05    set_freezable   vmlinux EXPORT_SYMBOL
+-0xd5418207    devres_release_group    vmlinux EXPORT_SYMBOL_GPL
+-0x45669e2c    drm_fb_helper_restore_fbdev_mode        vmlinux EXPORT_SYMBOL
+-0x93fcb0ed    bt_sock_reclassify_lock vmlinux EXPORT_SYMBOL
+-0xb6d8be2d    ipv6_push_nfrag_opts    vmlinux EXPORT_SYMBOL
+-0x8cdb54d7    ipt_register_table      vmlinux EXPORT_SYMBOL
+-0xcc0aef97    neigh_sysctl_unregister vmlinux EXPORT_SYMBOL
+-0xe56a9336    snd_pcm_format_width    vmlinux EXPORT_SYMBOL
+-0x9077c297    blk_abort_request       vmlinux EXPORT_SYMBOL_GPL
+-0x6ed8eb1f    extcon_register_notifier        vmlinux EXPORT_SYMBOL_GPL
+-0xc9561772    fb_destroy_modelist     vmlinux EXPORT_SYMBOL_GPL
+-0xf494fae4    tcp_peer_is_proven      vmlinux EXPORT_SYMBOL_GPL
+-0xdc70cab5    __scm_destroy   vmlinux EXPORT_SYMBOL
+-0xfb2acf00    snd_mixer_oss_notify_callback   vmlinux EXPORT_SYMBOL
+-0x3a016c77    d_move  vmlinux EXPORT_SYMBOL
+-0x5091b823    ring_buffer_read_start  vmlinux EXPORT_SYMBOL_GPL
+-0x171751ed    sdio_writeb_readb       vmlinux EXPORT_SYMBOL_GPL
+-0x3d94fdae    usb_put_phy     vmlinux EXPORT_SYMBOL_GPL
+-0xfbf7bde5    drm_crtc_cleanup        vmlinux EXPORT_SYMBOL
+-0x52aaee97    amba_ahb_device_add_res vmlinux EXPORT_SYMBOL_GPL
+-0xd0706e35    phy_pm_runtime_put      vmlinux EXPORT_SYMBOL_GPL
+-0x0ff178f6    __aeabi_idivmod vmlinux EXPORT_SYMBOL
+-0xfb11005b    ipcomp_destroy  vmlinux EXPORT_SYMBOL_GPL
+-0x6f81b189    dev_addr_del_multiple   vmlinux EXPORT_SYMBOL
+-0xf5ce8c40    touch_atime     vmlinux EXPORT_SYMBOL
+-0x53614269    get_cpu_idle_time_us    vmlinux EXPORT_SYMBOL_GPL
+-0x61c243fc    mod_timer_pending       vmlinux EXPORT_SYMBOL
+-0xf821b501    device_set_wakeup_capable       vmlinux EXPORT_SYMBOL_GPL
+-0x80bbfeb1    s3c_gpio_cfgall_range   vmlinux EXPORT_SYMBOL_GPL
+-0x10081d73    s3c_gpio_cfgpin_range   vmlinux EXPORT_SYMBOL_GPL
+-0x75464443    phonet_proto_unregister vmlinux EXPORT_SYMBOL
+-0x7d6fed76    rtnl_configure_link     vmlinux EXPORT_SYMBOL
+-0x8c844510    sock_wmalloc    vmlinux EXPORT_SYMBOL
+-0xbaf75338    snd_soc_codec_writable_register vmlinux EXPORT_SYMBOL_GPL
+-0x1e6d26a8    strstr  vmlinux EXPORT_SYMBOL
+-0xea6f9ca2    task_user_regset_view   vmlinux EXPORT_SYMBOL_GPL
+-0x4de17ab3    usb_state_string        vmlinux EXPORT_SYMBOL_GPL
+-0x349cba85    strchr  vmlinux EXPORT_SYMBOL
+-0xb83a0cc6    perf_event_disable      vmlinux EXPORT_SYMBOL_GPL
+-0x3b5965e0    inet_csk_listen_stop    vmlinux EXPORT_SYMBOL_GPL
+-0x6be59bed    kobject_create_and_add  vmlinux EXPORT_SYMBOL_GPL
+-0xdced71ac    setup_new_exec  vmlinux EXPORT_SYMBOL
+-0xdb8a1b3f    usermodehelper_read_trylock     vmlinux EXPORT_SYMBOL_GPL
+-0x7c9ad2eb    usb_wait_anchor_empty_timeout   vmlinux EXPORT_SYMBOL_GPL
+-0xf2fca922    uart_parse_options      vmlinux EXPORT_SYMBOL_GPL
+-0x7f63b31e    _memcpy_toio    vmlinux EXPORT_SYMBOL
+-0x3e3fcdf2    xfrm_state_lookup_byaddr        vmlinux EXPORT_SYMBOL
+-0x2b538790    pskb_expand_head        vmlinux EXPORT_SYMBOL
+-0xdb67d9bb    of_i2c_register_devices vmlinux EXPORT_SYMBOL
+-0x9f7314d6    wakeup_source_prepare   vmlinux EXPORT_SYMBOL_GPL
+-0x2a828cb7    drm_noop        vmlinux EXPORT_SYMBOL
+-0x3d3c540f    elf_hwcap       vmlinux EXPORT_SYMBOL
+-0xa045219b    fuse_do_ioctl   vmlinux EXPORT_SYMBOL_GPL
+-0x8fa5cf61    pm_qos_update_request   vmlinux EXPORT_SYMBOL_GPL
+-0x73514fba    i2c_release_client      vmlinux EXPORT_SYMBOL
+-0x168db450    take_over_console       vmlinux EXPORT_SYMBOL
+-0x0aa13d05    __raw_readsw    vmlinux EXPORT_SYMBOL
+-0x816a1ee5    rtnl_link_register      vmlinux EXPORT_SYMBOL_GPL
+-0x9fd1a952    sk_set_memalloc vmlinux EXPORT_SYMBOL_GPL
+-0x8605ed02    lock_may_write  vmlinux EXPORT_SYMBOL
+-0xb24e73ff    bh_submit_read  vmlinux EXPORT_SYMBOL
+-0x455db47d    dma_mark_declared_memory_occupied       vmlinux EXPORT_SYMBOL
+-0x1a65f4ad    __arm_ioremap_pfn       vmlinux EXPORT_SYMBOL
+-0x955e8436    eth_change_mtu  vmlinux EXPORT_SYMBOL
+-0xa300e599    eth_header_parse        vmlinux EXPORT_SYMBOL
+-0x42977ad4    __hw_addr_del_multiple  vmlinux EXPORT_SYMBOL
+-0xf57de517    bdev_stack_limits       vmlinux EXPORT_SYMBOL
+-0x25bed5a1    static_key_slow_dec_deferred    vmlinux EXPORT_SYMBOL_GPL
+-0xd2aaeb4e    kmsg_dump_get_buffer    vmlinux EXPORT_SYMBOL_GPL
+-0xedb320d6    nf_nat_pptp_hook_exp_gre        vmlinux EXPORT_SYMBOL_GPL
+-0xdc0a9f66    sock_wake_async vmlinux EXPORT_SYMBOL
+-0x68e05d57    getrawmonotonic vmlinux EXPORT_SYMBOL
+-0xee715ef8    lg_global_unlock        vmlinux EXPORT_SYMBOL
+-0xbebb2820    crypto_register_algs    vmlinux EXPORT_SYMBOL_GPL
+-0xccc2bc05    fat_free_clusters       vmlinux EXPORT_SYMBOL_GPL
+-0xde99c012    jbd2_complete_transaction       vmlinux EXPORT_SYMBOL
+-0x60599993    __set_page_dirty_buffers        vmlinux EXPORT_SYMBOL
+-0x8b775d3a    __wake_up_locked        vmlinux EXPORT_SYMBOL_GPL
+-0x93eb18c6    of_platform_device_create       vmlinux EXPORT_SYMBOL
+-0x9e5bfa34    bt_sock_poll    vmlinux EXPORT_SYMBOL
+-0x7e98f5ff    sock_prot_inuse_add     vmlinux EXPORT_SYMBOL_GPL
+-0xf9e73082    scnprintf       vmlinux EXPORT_SYMBOL
+-0xa1b4cc6a    aead_geniv_exit vmlinux EXPORT_SYMBOL_GPL
+-0xa7001f92    mod_zone_page_state     vmlinux EXPORT_SYMBOL
+-0x92e79788    perf_event_refresh      vmlinux EXPORT_SYMBOL_GPL
+-0x77e7babf    usb_hcd_platform_shutdown       vmlinux EXPORT_SYMBOL_GPL
+-0x6d4d6df5    s3c_gpio_cfgpin vmlinux EXPORT_SYMBOL
+-0x7f250a18    tcf_register_action     vmlinux EXPORT_SYMBOL
+-0x41852af3    blk_add_request_payload vmlinux EXPORT_SYMBOL_GPL
+-0x8bf05477    pm_runtime_autosuspend_expiration       vmlinux EXPORT_SYMBOL_GPL
+-0xea25f714    rtnl_link_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0x5f75b2b7    snd_soc_dapm_enable_pin vmlinux EXPORT_SYMBOL_GPL
+-0x87879778    copy_strings_kernel     vmlinux EXPORT_SYMBOL
+-0x731b81f1    __wait_on_bit   vmlinux EXPORT_SYMBOL
+-0x18838e93    hrtimer_get_remaining   vmlinux EXPORT_SYMBOL_GPL
+-0x0be4ca5a    extcon_set_state        vmlinux EXPORT_SYMBOL_GPL
+-0xacdf7eb6    led_trigger_register_simple     vmlinux EXPORT_SYMBOL_GPL
+-0x20645642    drm_debug       vmlinux EXPORT_SYMBOL
+-0x5f41d1f8    rdev_get_id     vmlinux EXPORT_SYMBOL_GPL
+-0xf6f440a6    tcp_enter_memory_pressure       vmlinux EXPORT_SYMBOL
+-0x3b9a9d19    skb_add_rx_frag vmlinux EXPORT_SYMBOL
+-0x32b2bc89    snd_soc_write   vmlinux EXPORT_SYMBOL_GPL
+-0x5b44d926    snd_soc_get_xr_sx       vmlinux EXPORT_SYMBOL_GPL
+-0xf1395b13    snd_soc_put_xr_sx       vmlinux EXPORT_SYMBOL_GPL
+-0x4982a57f    probe_kernel_write      vmlinux EXPORT_SYMBOL_GPL
+-0x811dc334    usb_unregister_notify   vmlinux EXPORT_SYMBOL_GPL
+-0xa6f7283b    arp_create      vmlinux EXPORT_SYMBOL
+-0x660b5392    jbd2_journal_get_create_access  vmlinux EXPORT_SYMBOL
+-0x99dd4a27    no_llseek       vmlinux EXPORT_SYMBOL
+-0x72532806    _raw_read_unlock_irq    vmlinux EXPORT_SYMBOL
+-0xe4719990    rt_mutex_timed_lock     vmlinux EXPORT_SYMBOL_GPL
+-0xb5d9454c    printk_emit     vmlinux EXPORT_SYMBOL
+-0x801e5a15    st_sensors_check_device_support vmlinux EXPORT_SYMBOL
+-0xeec77f6d    iio_map_array_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0x6390efda    of_modalias_node        vmlinux EXPORT_SYMBOL_GPL
+-0x7ac03539    tty_port_alloc_xmit_buf vmlinux EXPORT_SYMBOL
+-0x5cebb76e    vfs_truncate    vmlinux EXPORT_SYMBOL_GPL
+-0xfc52a8aa    mmc_gpio_request_cd     vmlinux EXPORT_SYMBOL
+-0xf7a4e432    mmc_gpio_request_ro     vmlinux EXPORT_SYMBOL
+-0x74d52889    rtc_irq_set_freq        vmlinux EXPORT_SYMBOL_GPL
+-0x8e9efd84    dma_declare_coherent_memory     vmlinux EXPORT_SYMBOL
+-0xfcfa03ff    fb_videomode_to_modelist        vmlinux EXPORT_SYMBOL
+-0x789c0277    nfc_unregister_device   vmlinux EXPORT_SYMBOL
+-0x48744ce2    lro_receive_frags       vmlinux EXPORT_SYMBOL
+-0xf6851d5f    register_sysctl_paths   vmlinux EXPORT_SYMBOL
+-0x90a4a466    generic_show_options    vmlinux EXPORT_SYMBOL
+-0x74dd4a76    pagecache_write_begin   vmlinux EXPORT_SYMBOL
+-0x7b42b5d4    drm_mode_copy   vmlinux EXPORT_SYMBOL
+-0x6a7c03c7    asoc_dma_platform_register      vmlinux EXPORT_SYMBOL_GPL
+-0xc6cbbc89    capable vmlinux EXPORT_SYMBOL
+-0xd07125d9    spi_finalize_current_message    vmlinux EXPORT_SYMBOL_GPL
+-0xf5514ce6    dev_pm_qos_add_request  vmlinux EXPORT_SYMBOL_GPL
+-0xb316e246    nf_afinfo       vmlinux EXPORT_SYMBOL
+-0x4ef5bcf4    perf_swevent_get_recursion_context      vmlinux EXPORT_SYMBOL_GPL
+-0xab7e3362    irq_find_mapping        vmlinux EXPORT_SYMBOL_GPL
+-0xbcf89ab6    __wake_up_sync  vmlinux EXPORT_SYMBOL_GPL
+-0xc8b57c27    autoremove_wake_function        vmlinux EXPORT_SYMBOL
+-0x36aa3266    hid_debug_event vmlinux EXPORT_SYMBOL_GPL
+-0x9ed21fce    mmc_can_trim    vmlinux EXPORT_SYMBOL
+-0x5658ad69    v4l2_async_register_subdev      vmlinux EXPORT_SYMBOL
+-0x99781445    input_set_capability    vmlinux EXPORT_SYMBOL
+-0xf3343f80    drm_mode_create_tv_properties   vmlinux EXPORT_SYMBOL
+-0x69fefbb6    nf_ct_port_tuple_to_nlattr      vmlinux EXPORT_SYMBOL_GPL
+-0xd9a9bb30    getname vmlinux EXPORT_SYMBOL
+-0xe7ffe877    pcpu_base_addr  vmlinux EXPORT_SYMBOL_GPL
+-0x131e7ee8    drm_fb_helper_hotplug_event     vmlinux EXPORT_SYMBOL
+-0x983f0520    drm_fb_helper_initial_config    vmlinux EXPORT_SYMBOL
+-0x469972c2    give_up_console vmlinux EXPORT_SYMBOL
+-0x300573d1    nf_conntrack_helper_register    vmlinux EXPORT_SYMBOL_GPL
+-0x2597c27d    snd_seq_root    vmlinux EXPORT_SYMBOL
+-0x9a11a0fc    crypto_attr_alg_name    vmlinux EXPORT_SYMBOL_GPL
+-0xa0f2a42b    debugfs_create_regset32 vmlinux EXPORT_SYMBOL_GPL
+-0x3e08c129    drm_mode_find_dmt       vmlinux EXPORT_SYMBOL
+-0xbc8b0f41    xfrm_calg_get_byid      vmlinux EXPORT_SYMBOL_GPL
+-0xf20dabd8    free_irq        vmlinux EXPORT_SYMBOL
+-0x9073a3d4    usb_hc_died     vmlinux EXPORT_SYMBOL_GPL
+-0xe61a6d2f    gpio_unexport   vmlinux EXPORT_SYMBOL_GPL
+-0xdf58d91e    pinctrl_dev_get_name    vmlinux EXPORT_SYMBOL_GPL
+-0x4c3b5878    ieee80211_get_response_rate     vmlinux EXPORT_SYMBOL
+-0xa6b9609a    jbd2_journal_init_inode vmlinux EXPORT_SYMBOL
+-0xe91ef2b5    deactivate_locked_super vmlinux EXPORT_SYMBOL
+-0x0280cf55    filemap_fdatawait       vmlinux EXPORT_SYMBOL
+-0x134178d9    v4l2_m2m_fop_mmap       vmlinux EXPORT_SYMBOL_GPL
+-0x9091c717    netdev_class_create_file        vmlinux EXPORT_SYMBOL
+-0x4f816e9b    snd_pcm_format_big_endian       vmlinux EXPORT_SYMBOL
+-0x09d44df9    in_lock_functions       vmlinux EXPORT_SYMBOL
+-0x509817cf    vprintk_emit    vmlinux EXPORT_SYMBOL
+-0x4c571d12    cfg80211_cqm_pktloss_notify     vmlinux EXPORT_SYMBOL
+-0x8b260b7f    ip6_tnl_xmit_ctl        vmlinux EXPORT_SYMBOL_GPL
+-0x7b9e609a    ip6_sk_update_pmtu      vmlinux EXPORT_SYMBOL_GPL
+-0x199db92b    netdev_rx_handler_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0x4cdf24a6    skb_copy_datagram_const_iovec   vmlinux EXPORT_SYMBOL
+-0xb994401f    kernel_getpeername      vmlinux EXPORT_SYMBOL
+-0x7b10e656    sysfs_chmod_file        vmlinux EXPORT_SYMBOL_GPL
+-0x55d7c934    find_module     vmlinux EXPORT_SYMBOL_GPL
+-0x548b482c    rt_mutex_lock   vmlinux EXPORT_SYMBOL_GPL
+-0x39533602    media_entity_graph_walk_start   vmlinux EXPORT_SYMBOL_GPL
+-0x51ef2459    platform_driver_probe   vmlinux EXPORT_SYMBOL_GPL
+-0xeb93a8ee    serial8250_do_set_termios       vmlinux EXPORT_SYMBOL
+-0x8afc7ce3    __devm_of_phy_provider_register vmlinux EXPORT_SYMBOL_GPL
+-0x548fedb9    skb_complete_wifi_ack   vmlinux EXPORT_SYMBOL_GPL
+-0x11f7ed4c    hex_to_bin      vmlinux EXPORT_SYMBOL
+-0x9aeecd64    simple_pin_fs   vmlinux EXPORT_SYMBOL
+-0x5635a60a    vmalloc_user    vmlinux EXPORT_SYMBOL
+-0xd36ab13e    posix_clock_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0x1fe9f800    unregister_cpu_notifier vmlinux EXPORT_SYMBOL
+-0xb59a9548    vb2_expbuf      vmlinux EXPORT_SYMBOL_GPL
+-0xf6eb0d71    input_event     vmlinux EXPORT_SYMBOL
+-0xfc3a261f    dev_get_regmap  vmlinux EXPORT_SYMBOL_GPL
+-0x89d145ed    pin_config_get  vmlinux EXPORT_SYMBOL
+-0xc54fc2d7    devm_pinctrl_put        vmlinux EXPORT_SYMBOL_GPL
+-0x9671e047    devm_pinctrl_get        vmlinux EXPORT_SYMBOL_GPL
+-0x4d45d89e    udp_memory_allocated    vmlinux EXPORT_SYMBOL
+-0x3e8b4fda    tc_classify     vmlinux EXPORT_SYMBOL
+-0x98509e55    sock_no_sendpage        vmlinux EXPORT_SYMBOL
+-0x7bd6700d    blk_pre_runtime_suspend vmlinux EXPORT_SYMBOL
+-0x6444b7bb    iio_read_channel_raw    vmlinux EXPORT_SYMBOL_GPL
+-0x70120108    thermal_generate_netlink_event  vmlinux EXPORT_SYMBOL_GPL
+-0x800e4ffa    __muldi3        vmlinux EXPORT_SYMBOL
+-0x4c1182cb    bitmap_scnprintf        vmlinux EXPORT_SYMBOL
+-0xd7b4599b    __idr_get_new_above     vmlinux EXPORT_SYMBOL
+-0x368dc456    proc_create_data        vmlinux EXPORT_SYMBOL
+-0x4d405db8    param_ops_string        vmlinux EXPORT_SYMBOL
+-0xdd021b6b    get_current_tty vmlinux EXPORT_SYMBOL_GPL
+-0xabbaaf4c    kernel_getsockname      vmlinux EXPORT_SYMBOL
+-0x5caf4413    kernel_sendmsg  vmlinux EXPORT_SYMBOL
+-0x3971b4df    snd_ecards_limit        vmlinux EXPORT_SYMBOL
+-0xd77a5aa5    __bitmap_and    vmlinux EXPORT_SYMBOL
+-0xfac05b29    unregister_gadget_item  vmlinux EXPORT_SYMBOL
+-0x268930d0    uart_register_driver    vmlinux EXPORT_SYMBOL
+-0xace7ae5c    xfrm_alloc_spi  vmlinux EXPORT_SYMBOL
+-0x0a4a1a2f    blk_rq_err_bytes        vmlinux EXPORT_SYMBOL_GPL
+-0x6d414f53    crypto_blkcipher_type   vmlinux EXPORT_SYMBOL_GPL
+-0x2ffe9a6b    crypto_givcipher_type   vmlinux EXPORT_SYMBOL_GPL
+-0xe5ddcbd8    nfc_targets_found       vmlinux EXPORT_SYMBOL
+-0x028f3057    nf_log_packet   vmlinux EXPORT_SYMBOL
+-0xc8949349    qdisc_tree_decrease_qlen        vmlinux EXPORT_SYMBOL
+-0x7d16c025    dev_remove_pack vmlinux EXPORT_SYMBOL
+-0xf88eb7f2    rq_flush_dcache_pages   vmlinux EXPORT_SYMBOL_GPL
+-0x2d8764e5    blkcipher_walk_virt     vmlinux EXPORT_SYMBOL_GPL
+-0x5fce0dc6    posix_lock_file vmlinux EXPORT_SYMBOL
+-0x71a672ef    dmam_pool_destroy       vmlinux EXPORT_SYMBOL
+-0x3832da09    set_page_dirty  vmlinux EXPORT_SYMBOL
+-0xe4937b31    i2c_bit_algo    vmlinux EXPORT_SYMBOL
+-0x2c256e1f    input_scancode_to_scalar        vmlinux EXPORT_SYMBOL
+-0x758978d2    spi_get_next_queued_message     vmlinux EXPORT_SYMBOL_GPL
+-0xde9360ba    totalram_pages  vmlinux EXPORT_SYMBOL
+-0xacc53440    video_device_alloc      vmlinux EXPORT_SYMBOL
+-0x331f6073    udp_disconnect  vmlinux EXPORT_SYMBOL
+-0x8a5c060e    nf_conntrack_l4proto_udp4       vmlinux EXPORT_SYMBOL_GPL
+-0x492ab82c    dev_uc_unsync   vmlinux EXPORT_SYMBOL
+-0xb1615d69    dev_mc_unsync   vmlinux EXPORT_SYMBOL
+-0xa73acb8d    dump_seek       vmlinux EXPORT_SYMBOL
+-0xea63afac    usb_free_streams        vmlinux EXPORT_SYMBOL_GPL
+-0x0fb8623c    regcache_cache_only     vmlinux EXPORT_SYMBOL_GPL
+-0xb89f40b3    __register_chrdev       vmlinux EXPORT_SYMBOL
+-0x4ed5e0d7    v4l2_chip_match_host    vmlinux EXPORT_SYMBOL
+-0x78272b1e    bus_get_kset    vmlinux EXPORT_SYMBOL_GPL
+-0x87c0bce8    net_dma_find_channel    vmlinux EXPORT_SYMBOL
+-0xc31f408b    __display_entity_register       vmlinux EXPORT_SYMBOL_GPL
+-0x5b1cfbcd    of_get_fb_videomode     vmlinux EXPORT_SYMBOL_GPL
+-0xe6775a2f    fb_show_logo    vmlinux EXPORT_SYMBOL
+-0xa290f4a9    fb_pan_display  vmlinux EXPORT_SYMBOL
+-0x61c2dac6    kstrtoll_from_user      vmlinux EXPORT_SYMBOL
+-0x83904bc7    st_sensors_deallocate_trigger   vmlinux EXPORT_SYMBOL
+-0x7bc41c7c    rtc_class_close vmlinux EXPORT_SYMBOL_GPL
+-0x218b226c    sec_bulk_write  vmlinux EXPORT_SYMBOL_GPL
+-0xf09de776    get_random_int  vmlinux EXPORT_SYMBOL
+-0x5a937d99    blk_queue_stack_limits  vmlinux EXPORT_SYMBOL
+-0x174b7df6    free_vm_area    vmlinux EXPORT_SYMBOL_GPL
+-0x8ffa3ccd    devres_alloc    vmlinux EXPORT_SYMBOL_GPL
+-0x956a91ba    gpio_get_value_cansleep vmlinux EXPORT_SYMBOL_GPL
+-0x92886ef2    udp_lib_setsockopt      vmlinux EXPORT_SYMBOL
+-0xc4a35da7    udp_lib_getsockopt      vmlinux EXPORT_SYMBOL
+-0xdb1ed3be    nf_conntrack_free       vmlinux EXPORT_SYMBOL_GPL
+-0x96898769    sysfs_format_mac        vmlinux EXPORT_SYMBOL
+-0x15604324    sk_send_sigurg  vmlinux EXPORT_SYMBOL
+-0x8fca87b8    proc_set_size   vmlinux EXPORT_SYMBOL
+-0x4b5fd49e    dm_kcopyd_do_callback   vmlinux EXPORT_SYMBOL
+-0x289bc356    mdiobus_alloc_size      vmlinux EXPORT_SYMBOL
+-0xf36e7280    spi_bus_lock    vmlinux EXPORT_SYMBOL_GPL
+-0x0c060ece    cfg80211_sched_scan_stopped     vmlinux EXPORT_SYMBOL
+-0xab2289f2    drop_super      vmlinux EXPORT_SYMBOL
+-0x27e1a049    printk  vmlinux EXPORT_SYMBOL
+-0x3194878b    pm_generic_poweroff_noirq       vmlinux EXPORT_SYMBOL_GPL
+-0x688f09be    dev_crit        vmlinux EXPORT_SYMBOL
+-0xfd94d6cb    drm_get_connector_status_name   vmlinux EXPORT_SYMBOL
+-0xbdef1e6b    drm_gem_object_release  vmlinux EXPORT_SYMBOL
+-0x36fa2c4a    cfg80211_get_bss        vmlinux EXPORT_SYMBOL
+-0xef2e65fd    sk_alloc        vmlinux EXPORT_SYMBOL
+-0x096e7523    try_to_release_page     vmlinux EXPORT_SYMBOL
+-0xa61b1477    tracepoint_iter_start   vmlinux EXPORT_SYMBOL_GPL
+-0x9d05f6c4    ktime_get_clocktai      vmlinux EXPORT_SYMBOL
+-0x6a87a478    synchronize_srcu        vmlinux EXPORT_SYMBOL_GPL
+-0xa3afa3ce    bus_unregister_notifier vmlinux EXPORT_SYMBOL_GPL
+-0xbe001c53    drm_property_add_enum   vmlinux EXPORT_SYMBOL
+-0x48c2a99d    drm_helper_resume_force_mode    vmlinux EXPORT_SYMBOL
+-0x1258d9d9    regulator_disable       vmlinux EXPORT_SYMBOL_GPL
+-0x1b3261e0    klist_iter_init vmlinux EXPORT_SYMBOL_GPL
+-0xaeec4fd1    hci_conn_switch_role    vmlinux EXPORT_SYMBOL
+-0x8809bdee    kobject_add     vmlinux EXPORT_SYMBOL
+-0x10138352    tracing_on      vmlinux EXPORT_SYMBOL_GPL
+-0x39aa4754    dma_buf_mmap    vmlinux EXPORT_SYMBOL_GPL
+-0x58c6fc51    dma_buf_kmap    vmlinux EXPORT_SYMBOL_GPL
+-0x299bbc21    dma_buf_vmap    vmlinux EXPORT_SYMBOL_GPL
+-0x5a2579f9    platform_driver_register        vmlinux EXPORT_SYMBOL_GPL
+-0xa8d6809d    drm_dp_bw_code_to_link_rate     vmlinux EXPORT_SYMBOL
+-0xfd86731b    drm_fb_helper_init      vmlinux EXPORT_SYMBOL
+-0xd4880725    __video_source_register vmlinux EXPORT_SYMBOL_GPL
+-0xe08f4a3d    devm_of_phy_provider_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x61634f05    lock_flocks     vmlinux EXPORT_SYMBOL_GPL
+-0x3843f6b8    queue_kthread_work      vmlinux EXPORT_SYMBOL_GPL
+-0x8e332478    thermal_zone_get_temp   vmlinux EXPORT_SYMBOL_GPL
+-0xdd64085c    platform_driver_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0xaa6f23ad    rfkill_get_led_trigger_name     vmlinux EXPORT_SYMBOL
+-0x9cab34a6    rfkill_set_led_trigger_name     vmlinux EXPORT_SYMBOL
+-0x23b075bd    gnet_stats_copy_queue   vmlinux EXPORT_SYMBOL
+-0x12e85778    kstrtol_from_user       vmlinux EXPORT_SYMBOL
+-0x331504fa    simple_dir_operations   vmlinux EXPORT_SYMBOL
+-0x3eabdee4    of_match_device vmlinux EXPORT_SYMBOL
+-0x610e908e    hid_ignore      vmlinux EXPORT_SYMBOL_GPL
+-0x3838d3de    usb_get_urb     vmlinux EXPORT_SYMBOL_GPL
+-0xd400a944    cfg80211_gtk_rekey_notify       vmlinux EXPORT_SYMBOL
+-0x6403e338    tcp_memory_pressure     vmlinux EXPORT_SYMBOL
+-0x23a650aa    setattr_copy    vmlinux EXPORT_SYMBOL
+-0x6b6b3081    iommu_domain_has_cap    vmlinux EXPORT_SYMBOL_GPL
+-0xdd9fe08e    nfc_hci_driver_failure  vmlinux EXPORT_SYMBOL
+-0x091cae50    cfg80211_probe_status   vmlinux EXPORT_SYMBOL
+-0xa5e8f497    inet_frags_fini vmlinux EXPORT_SYMBOL
+-0xff048999    snd_register_oss_device vmlinux EXPORT_SYMBOL
+-0x24a94b26    snd_info_get_line       vmlinux EXPORT_SYMBOL
+-0x7ba9873c    elv_dispatch_sort       vmlinux EXPORT_SYMBOL
+-0x1471fd44    elv_add_request vmlinux EXPORT_SYMBOL
+-0x9be7bde4    security_tun_dev_attach vmlinux EXPORT_SYMBOL
+-0xf346231f    seq_list_start_head     vmlinux EXPORT_SYMBOL
+-0x65d9e877    cpufreq_register_notifier       vmlinux EXPORT_SYMBOL
+-0x399ed296    v4l2_subdev_link_validate_default       vmlinux EXPORT_SYMBOL_GPL
+-0xfb974dd4    v4l2_ctrl_auto_cluster  vmlinux EXPORT_SYMBOL
+-0xd9097364    v4l2_event_dequeue      vmlinux EXPORT_SYMBOL_GPL
+-0xd9a8b315    scsi_queue_work vmlinux EXPORT_SYMBOL_GPL
+-0xf564412a    __aeabi_ulcmp   vmlinux EXPORT_SYMBOL
+-0x67e6edc4    netif_device_attach     vmlinux EXPORT_SYMBOL
+-0x6c3962d5    netif_device_detach     vmlinux EXPORT_SYMBOL
+-0x7464ec66    netdev_set_default_ethtool_ops  vmlinux EXPORT_SYMBOL_GPL
+-0x08cf6c97    snd_soc_dai_digital_mute        vmlinux EXPORT_SYMBOL_GPL
+-0x47628784    simple_attr_read        vmlinux EXPORT_SYMBOL_GPL
+-0xe4bad1e4    sdhci_pltfm_init        vmlinux EXPORT_SYMBOL_GPL
+-0xe3b2bc37    gether_connect  vmlinux EXPORT_SYMBOL
+-0x2fe1cc7e    device_rename   vmlinux EXPORT_SYMBOL_GPL
+-0xc147be94    drm_i2c_encoder_restore vmlinux EXPORT_SYMBOL
+-0x56f369aa    kernel_bind     vmlinux EXPORT_SYMBOL
+-0xcd279169    nla_find        vmlinux EXPORT_SYMBOL
+-0x5cdf6de2    kernel_read     vmlinux EXPORT_SYMBOL
+-0xfcc43f3f    vfs_read        vmlinux EXPORT_SYMBOL
+-0xc8add232    ring_buffer_record_disable      vmlinux EXPORT_SYMBOL_GPL
+-0xf2e84b50    __devm_release_region   vmlinux EXPORT_SYMBOL
+-0xd4292ec2    dev_notice      vmlinux EXPORT_SYMBOL
+-0x02e6e099    drm_mode_width  vmlinux EXPORT_SYMBOL
+-0xcc248d26    serial8250_suspend_port vmlinux EXPORT_SYMBOL
+-0x4e6e8ea7    fg_console      vmlinux EXPORT_SYMBOL
+-0xbb9cc562    fl6_merge_options       vmlinux EXPORT_SYMBOL_GPL
+-0x20bf8fa2    __inet_hash_nolisten    vmlinux EXPORT_SYMBOL_GPL
+-0x9fb3dd30    memcpy_fromiovec        vmlinux EXPORT_SYMBOL
+-0x9cde26bf    blk_queue_prep_rq       vmlinux EXPORT_SYMBOL
+-0x262f20a8    local_clock     vmlinux EXPORT_SYMBOL_GPL
+-0x7ebf0ef8    __nf_nat_l4proto_find   vmlinux EXPORT_SYMBOL_GPL
+-0x503bc70a    drm_gem_prime_export    vmlinux EXPORT_SYMBOL
+-0x8d6f81b4    __div64_32      vmlinux EXPORT_SYMBOL
+-0x93fca811    __get_free_pages        vmlinux EXPORT_SYMBOL
+-0xbb189cad    disallow_signal vmlinux EXPORT_SYMBOL
+-0xefe5a9bf    usbnet_resume_rx        vmlinux EXPORT_SYMBOL_GPL
+-0x1c4116bc    __class_register        vmlinux EXPORT_SYMBOL_GPL
+-0x72cae0c9    nfc_driver_failure      vmlinux EXPORT_SYMBOL
+-0xc3d70f22    rawv6_mh_filter_register        vmlinux EXPORT_SYMBOL
+-0xdbcd416e    sysctl_ip_nonlocal_bind vmlinux EXPORT_SYMBOL
+-0xa675804c    utf8s_to_utf16s vmlinux EXPORT_SYMBOL
+-0xb4b97c90    pvclock_gtod_register_notifier  vmlinux EXPORT_SYMBOL_GPL
+-0xdf9d0875    ns_capable      vmlinux EXPORT_SYMBOL
+-0x13ba72ba    usb_free_coherent       vmlinux EXPORT_SYMBOL_GPL
+-0x4671c723    rawv6_mh_filter_unregister      vmlinux EXPORT_SYMBOL
+-0x5855bb11    blk_queue_resize_tags   vmlinux EXPORT_SYMBOL
+-0x5159ff6c    mmc_fixup_device        vmlinux EXPORT_SYMBOL
+-0x186b8590    ipv4_specific   vmlinux EXPORT_SYMBOL
+-0x9d5e9b60    nf_ct_l3proto_find_get  vmlinux EXPORT_SYMBOL_GPL
+-0x3f2c16f1    nf_ct_l4proto_find_get  vmlinux EXPORT_SYMBOL_GPL
+-0xe20a528d    nf_queue_entry_release_refs     vmlinux EXPORT_SYMBOL_GPL
+-0x4335fafb    proto_unregister        vmlinux EXPORT_SYMBOL
+-0x5762296f    fuse_conn_kill  vmlinux EXPORT_SYMBOL_GPL
+-0xe473e06d    __fsnotify_inode_delete vmlinux EXPORT_SYMBOL_GPL
+-0xe2ed7067    i2c_new_dummy   vmlinux EXPORT_SYMBOL_GPL
+-0x3cac21b9    regulator_sync_voltage  vmlinux EXPORT_SYMBOL_GPL
+-0x71e7aab0    from_kprojid_munged     vmlinux EXPORT_SYMBOL
+-0x3ca7e128    tty_unlock_pair vmlinux EXPORT_SYMBOL
+-0x146d2f0c    rtnl_af_register        vmlinux EXPORT_SYMBOL_GPL
+-0x97ecf37c    kunmap_high     vmlinux EXPORT_SYMBOL
+-0x4470a79b    param_ops_long  vmlinux EXPORT_SYMBOL
+-0x45bd9efd    dm_table_put    vmlinux EXPORT_SYMBOL
+-0xf2a353ac    v4l2_i2c_tuner_addrs    vmlinux EXPORT_SYMBOL_GPL
+-0xc7fd39bb    drm_dp_channel_eq_ok    vmlinux EXPORT_SYMBOL
+-0xa0472547    inet_csk_update_pmtu    vmlinux EXPORT_SYMBOL_GPL
+-0xacf4d843    match_strdup    vmlinux EXPORT_SYMBOL
+-0x870bf928    radix_tree_lookup       vmlinux EXPORT_SYMBOL
+-0x4672e88b    __crypto_dequeue_request        vmlinux EXPORT_SYMBOL_GPL
+-0x7b0f1ab3    ring_buffer_free_read_page      vmlinux EXPORT_SYMBOL_GPL
+-0x9745b34c    rt_mutex_unlock vmlinux EXPORT_SYMBOL_GPL
+-0xac745cfe    s3c_adc_read    vmlinux EXPORT_SYMBOL_GPL
+-0x4dc817ff    usb_composite_overwrite_options vmlinux EXPORT_SYMBOL_GPL
+-0xcd8ff108    neigh_seq_next  vmlinux EXPORT_SYMBOL
+-0xb4062ffd    vfs_rename      vmlinux EXPORT_SYMBOL
+-0xdc4ed03b    generic_ro_fops vmlinux EXPORT_SYMBOL
+-0x1300b437    nci_register_device     vmlinux EXPORT_SYMBOL
+-0xbcfcecc3    user_path_create        vmlinux EXPORT_SYMBOL
+-0xcf71a180    kthread_bind    vmlinux EXPORT_SYMBOL
+-0x4571f8be    usb_string_ids_n        vmlinux EXPORT_SYMBOL_GPL
+-0xf1ea24f2    ipv6_setsockopt vmlinux EXPORT_SYMBOL
+-0x2d97bed6    dm_kcopyd_zero  vmlinux EXPORT_SYMBOL
+-0xa1f5edea    drm_property_destroy    vmlinux EXPORT_SYMBOL
+-0x3548305a    inet_frag_find  vmlinux EXPORT_SYMBOL
+-0xf937428d    inetdev_by_index        vmlinux EXPORT_SYMBOL
+-0x33f234ad    __sk_backlog_rcv        vmlinux EXPORT_SYMBOL
+-0xb0fbdabc    crypto_lookup_skcipher  vmlinux EXPORT_SYMBOL_GPL
+-0xdf0f75c6    eventfd_signal  vmlinux EXPORT_SYMBOL_GPL
+-0x21f678b9    clocksource_unregister  vmlinux EXPORT_SYMBOL
+-0xe3b5bb1e    usb_poison_anchored_urbs        vmlinux EXPORT_SYMBOL_GPL
+-0x36003409    nfc_hci_send_event      vmlinux EXPORT_SYMBOL
+-0xd26c8ac5    bt_sock_wait_state      vmlinux EXPORT_SYMBOL
+-0x8bd1c81c    fifo_set_limit  vmlinux EXPORT_SYMBOL
+-0xe630ebe9    snd_soc_get_pcm_runtime vmlinux EXPORT_SYMBOL_GPL
+-0x9f7af994    writeback_in_progress   vmlinux EXPORT_SYMBOL
+-0x94048818    filemap_fdatawrite      vmlinux EXPORT_SYMBOL
+-0x9cc4f70a    register_pm_notifier    vmlinux EXPORT_SYMBOL_GPL
+-0xdf6f4023    phy_drivers_unregister  vmlinux EXPORT_SYMBOL
+-0x4cc1d9d6    con_debug_enter vmlinux EXPORT_SYMBOL_GPL
+-0x807d2b2c    xt_recseq       vmlinux EXPORT_SYMBOL_GPL
+-0x089e2060    __ethtool_get_settings  vmlinux EXPORT_SYMBOL
+-0xcdd9e311    dev_add_offload vmlinux EXPORT_SYMBOL
+-0x90ac3102    dev_base_lock   vmlinux EXPORT_SYMBOL
+-0xfcc256a6    css_id  vmlinux EXPORT_SYMBOL_GPL
+-0x2e7be112    _raw_read_lock_irqsave  vmlinux EXPORT_SYMBOL
+-0x284633c4    devm_clk_register       vmlinux EXPORT_SYMBOL_GPL
+-0x440982c5    usb_del_gadget_udc      vmlinux EXPORT_SYMBOL_GPL
+-0x0d7b25d8    drm_i2c_encoder_destroy vmlinux EXPORT_SYMBOL
+-0xd25d4f74    console_blank_hook      vmlinux EXPORT_SYMBOL
+-0x968b41f8    nfc_hci_unregister_device       vmlinux EXPORT_SYMBOL
+-0x71917221    xt_request_find_target  vmlinux EXPORT_SYMBOL_GPL
+-0x14ccc8d6    sg_scsi_ioctl   vmlinux EXPORT_SYMBOL_GPL
+-0xc22a3091    vm_unmap_aliases        vmlinux EXPORT_SYMBOL_GPL
+-0x936d3888    dm_kill_unmapped_request        vmlinux EXPORT_SYMBOL_GPL
+-0x56f3f495    vb2_querybuf    vmlinux EXPORT_SYMBOL
+-0xcd773fe8    gnet_stats_finish_copy  vmlinux EXPORT_SYMBOL
+-0x75ffa405    blk_fetch_request       vmlinux EXPORT_SYMBOL
+-0xc51700fb    free_inode_nonrcu       vmlinux EXPORT_SYMBOL
+-0x87471cdc    dma_pool_create vmlinux EXPORT_SYMBOL
+-0x4b34fbf5    block_all_signals       vmlinux EXPORT_SYMBOL
+-0x1910bed7    v4l2_m2m_next_buf       vmlinux EXPORT_SYMBOL_GPL
+-0xda6389c8    scsi_get_device_flags_keyed     vmlinux EXPORT_SYMBOL
+-0x384fda7f    device_show_int vmlinux EXPORT_SYMBOL_GPL
+-0x853ce11c    uart_handle_cts_change  vmlinux EXPORT_SYMBOL_GPL
+-0x2167989c    uart_handle_dcd_change  vmlinux EXPORT_SYMBOL_GPL
+-0x832c7303    cfg80211_chandef_compatible     vmlinux EXPORT_SYMBOL
+-0xb5aa7165    dma_pool_destroy        vmlinux EXPORT_SYMBOL
+-0x3a81993a    irq_create_strict_mappings      vmlinux EXPORT_SYMBOL_GPL
+-0xf7951d2a    sdio_writeb     vmlinux EXPORT_SYMBOL_GPL
+-0x73286449    gether_set_gadget       vmlinux EXPORT_SYMBOL
+-0x0958f0a1    gether_disconnect       vmlinux EXPORT_SYMBOL
+-0xc7141639    tty_name        vmlinux EXPORT_SYMBOL
+-0x52e54a99    udp6_csum_init  vmlinux EXPORT_SYMBOL
+-0x20c95ebb    __dev_remove_offload    vmlinux EXPORT_SYMBOL
+-0xff6104d0    snd_pcm_rate_bit_to_rate        vmlinux EXPORT_SYMBOL
+-0xcfa8d57b    sysfs_get_dirent        vmlinux EXPORT_SYMBOL_GPL
+-0x8e0d66f4    __tracepoint_kmalloc    vmlinux EXPORT_SYMBOL
+-0x3bfcc1f8    perf_event_release_kernel       vmlinux EXPORT_SYMBOL_GPL
+-0x8c03d20c    destroy_workqueue       vmlinux EXPORT_SYMBOL_GPL
+-0x7e36685b    of_dev_put      vmlinux EXPORT_SYMBOL
+-0x379d3e07    of_dev_get      vmlinux EXPORT_SYMBOL
+-0xf494f618    mmc_regulator_get_ocrmask       vmlinux EXPORT_SYMBOL_GPL
+-0xd9fb5e67    power_supply_register   vmlinux EXPORT_SYMBOL_GPL
+-0x3697b3a2    usb_assign_descriptors  vmlinux EXPORT_SYMBOL_GPL
+-0x6789d290    serial8250_register_8250_port   vmlinux EXPORT_SYMBOL
+-0xa34d0cc4    inet6_csk_reqsk_queue_hash_add  vmlinux EXPORT_SYMBOL_GPL
+-0x81de8eb2    inet_twsk_put   vmlinux EXPORT_SYMBOL_GPL
+-0x687019ad    fib_default_rule_add    vmlinux EXPORT_SYMBOL
+-0x8eef430a    fat_get_dotdot_entry    vmlinux EXPORT_SYMBOL_GPL
+-0x2a3f1eb3    check_disk_change       vmlinux EXPORT_SYMBOL
+-0xd5325933    default_file_splice_read        vmlinux EXPORT_SYMBOL
+-0xd83215e5    writeback_inodes_sb     vmlinux EXPORT_SYMBOL
+-0x506cc085    tracepoint_iter_stop    vmlinux EXPORT_SYMBOL_GPL
+-0xe200d2d5    param_get_uint  vmlinux EXPORT_SYMBOL
+-0x79cb0ce1    pm_generic_runtime_suspend      vmlinux EXPORT_SYMBOL_GPL
+-0x364477d8    do_SAK  vmlinux EXPORT_SYMBOL
+-0x8d9c96ee    elv_register    vmlinux EXPORT_SYMBOL_GPL
+-0x0c77c871    page_put_link   vmlinux EXPORT_SYMBOL
+-0x8f03ba03    release_pages   vmlinux EXPORT_SYMBOL
+-0xa4a39c18    v4l2_m2m_streamon       vmlinux EXPORT_SYMBOL_GPL
+-0xa2d6eedc    bt_sock_stream_recvmsg  vmlinux EXPORT_SYMBOL
+-0xb1bed25d    dpm_resume_start        vmlinux EXPORT_SYMBOL_GPL
+-0x10291853    devm_regulator_put      vmlinux EXPORT_SYMBOL_GPL
+-0xcf618a57    cfg80211_calculate_bitrate      vmlinux EXPORT_SYMBOL
+-0xa9f48f53    km_state_expired        vmlinux EXPORT_SYMBOL
+-0x6417850b    qdisc_list_del  vmlinux EXPORT_SYMBOL
+-0xb0e10781    get_option      vmlinux EXPORT_SYMBOL
+-0x6a3d6744    drm_property_create     vmlinux EXPORT_SYMBOL
+-0x60352082    register_inet6addr_notifier     vmlinux EXPORT_SYMBOL
+-0x7cabb84d    inet_accept     vmlinux EXPORT_SYMBOL
+-0x49b07aec    tcp_select_initial_window       vmlinux EXPORT_SYMBOL
+-0xd41766d2    nf_ct_gre_keymap_destroy        vmlinux EXPORT_SYMBOL_GPL
+-0x0b225b92    register_pernet_device  vmlinux EXPORT_SYMBOL_GPL
+-0xe697d108    __blk_iopoll_complete   vmlinux EXPORT_SYMBOL
+-0xa1c76e0a    _cond_resched   vmlinux EXPORT_SYMBOL
+-0x22e1ae6f    up_read vmlinux EXPORT_SYMBOL
+-0x9fbe4605    class_for_each_device   vmlinux EXPORT_SYMBOL_GPL
+-0x4c1e4dba    unbind_con_driver       vmlinux EXPORT_SYMBOL
+-0x352cbaad    empty_zero_page vmlinux EXPORT_SYMBOL
+-0x66f6b51b    nfnetlink_subsys_register       vmlinux EXPORT_SYMBOL_GPL
+-0x2de03b66    ndo_dflt_bridge_getlink vmlinux EXPORT_SYMBOL
+-0x1f404818    __pskb_pull_tail        vmlinux EXPORT_SYMBOL
+-0x848618a1    snd_pcm_lib_free_vmalloc_buffer vmlinux EXPORT_SYMBOL
+-0x11575bf3    bioset_free     vmlinux EXPORT_SYMBOL
+-0x2acf0feb    vfs_fstat       vmlinux EXPORT_SYMBOL
+-0x0c45fc96    vfs_lstat       vmlinux EXPORT_SYMBOL
+-0x20bc3470    orderly_poweroff        vmlinux EXPORT_SYMBOL_GPL
+-0xd0c74120    cpufreq_frequency_table_verify  vmlinux EXPORT_SYMBOL_GPL
+-0x93af794b    dev_alert       vmlinux EXPORT_SYMBOL
+-0x96cd86f2    tty_wait_until_sent     vmlinux EXPORT_SYMBOL
+-0x4384f1be    gether_setup_name       vmlinux EXPORT_SYMBOL
+-0xa598e29c    vesa_modes      vmlinux EXPORT_SYMBOL
+-0x4ead0283    pn_skb_send     vmlinux EXPORT_SYMBOL
+-0xc01a92eb    __netif_schedule        vmlinux EXPORT_SYMBOL
+-0xd42d86c0    generic_fh_to_parent    vmlinux EXPORT_SYMBOL_GPL
+-0x9eaba82f    generic_fillattr        vmlinux EXPORT_SYMBOL
+-0x183fa88b    mempool_alloc_slab      vmlinux EXPORT_SYMBOL
+-0x5d0b1892    param_set_invbool       vmlinux EXPORT_SYMBOL
+-0xe103ee04    gpio_export_link        vmlinux EXPORT_SYMBOL_GPL
+-0x24bfaf10    d_instantiate_unique    vmlinux EXPORT_SYMBOL
+-0xd6b8e852    request_threaded_irq    vmlinux EXPORT_SYMBOL
+-0x18bd76a4    _raw_spin_trylock       vmlinux EXPORT_SYMBOL
+-0xc2ffd5d5    iio_trigger_alloc       vmlinux EXPORT_SYMBOL
+-0xa749c072    i2c_register_driver     vmlinux EXPORT_SYMBOL
+-0x6ea05e17    of_phy_provider_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0xc359fb65    abort   vmlinux EXPORT_SYMBOL
+-0x9f0f5d05    cfg80211_send_unprot_disassoc   vmlinux EXPORT_SYMBOL
+-0xc575c737    debug_locks_off vmlinux EXPORT_SYMBOL_GPL
+-0xab2f97aa    jbd2_journal_forget     vmlinux EXPORT_SYMBOL
+-0xffea14aa    mutex_lock_interruptible        vmlinux EXPORT_SYMBOL
+-0xdb9cfd07    skb_clone       vmlinux EXPORT_SYMBOL
+-0x0cdd5fd1    crypto_find_alg vmlinux EXPORT_SYMBOL_GPL
+-0x076aff85    set_task_ioprio vmlinux EXPORT_SYMBOL_GPL
+-0x773522a8    setup_arg_pages vmlinux EXPORT_SYMBOL
+-0x430348ff    input_get_keycode       vmlinux EXPORT_SYMBOL
+-0x3c50bfc9    regmap_can_raw_write    vmlinux EXPORT_SYMBOL_GPL
+-0x8209afe6    wakeup_source_destroy   vmlinux EXPORT_SYMBOL_GPL
+-0x0487f831    fb_find_best_display    vmlinux EXPORT_SYMBOL
+-0x83dab696    inode_dio_wait  vmlinux EXPORT_SYMBOL
+-0xa3a19433    of_get_regulator_init_data      vmlinux EXPORT_SYMBOL_GPL
+-0x43ca0eb7    amba_request_regions    vmlinux EXPORT_SYMBOL
+-0xc34efe27    snmp_fold_field vmlinux EXPORT_SYMBOL_GPL
+-0x3e48e980    tcp_init_xmit_timers    vmlinux EXPORT_SYMBOL
+-0x267c8e5b    snd_soc_register_card   vmlinux EXPORT_SYMBOL_GPL
+-0x2d13dc4b    jbd2_journal_start      vmlinux EXPORT_SYMBOL
+-0xd67364f7    eventfd_ctx_fdget       vmlinux EXPORT_SYMBOL_GPL
+-0xaefaecb4    phy_ethtool_gset        vmlinux EXPORT_SYMBOL
+-0x86dded2c    phy_ethtool_sset        vmlinux EXPORT_SYMBOL
+-0x1b15cf75    drm_encoder_init        vmlinux EXPORT_SYMBOL
+-0x540ef2af    vfs_lock_file   vmlinux EXPORT_SYMBOL_GPL
+-0x56fcacd4    bio_uncopy_user vmlinux EXPORT_SYMBOL
+-0x9401ec10    make_bad_inode  vmlinux EXPORT_SYMBOL
+-0x8ec007a4    __d_drop        vmlinux EXPORT_SYMBOL
+-0x7f39e9f3    __mmdrop        vmlinux EXPORT_SYMBOL_GPL
+-0x731e1d9d    thermal_zone_device_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0x31528994    __i2c_transfer  vmlinux EXPORT_SYMBOL
+-0x33dbfd93    tcp_memory_allocated    vmlinux EXPORT_SYMBOL
+-0xa8232c78    strtobool       vmlinux EXPORT_SYMBOL
+-0xbe744811    jbd2_journal_force_commit_nested        vmlinux EXPORT_SYMBOL
+-0xce03751f    seq_release_private     vmlinux EXPORT_SYMBOL
+-0xd788742d    perf_trace_buf_prepare  vmlinux EXPORT_SYMBOL_GPL
+-0x269f017e    st_sensors_set_dataready_irq    vmlinux EXPORT_SYMBOL
+-0x379ea057    hid_check_keys_pressed  vmlinux EXPORT_SYMBOL_GPL
+-0xe19a7489    scsi_bus_type   vmlinux EXPORT_SYMBOL_GPL
+-0x11f13f3f    snd_ctl_remove  vmlinux EXPORT_SYMBOL
+-0xb7a5a52f    writeback_inodes_sb_nr  vmlinux EXPORT_SYMBOL
+-0x8efefdc1    vfs_removexattr vmlinux EXPORT_SYMBOL_GPL
+-0xbd7c9ac7    find_symbol     vmlinux EXPORT_SYMBOL_GPL
+-0xc6ca6078    __mutex_init    vmlinux EXPORT_SYMBOL
+-0xe8349cd8    uart_console_write      vmlinux EXPORT_SYMBOL_GPL
+-0x2e5810c6    __aeabi_unwind_cpp_pr1  vmlinux EXPORT_SYMBOL
+-0x80f711c7    jbd2_journal_check_used_features        vmlinux EXPORT_SYMBOL
+-0xcd91b127    system_highpri_wq       vmlinux EXPORT_SYMBOL_GPL
+-0x5d2137b0    sdio_readsb     vmlinux EXPORT_SYMBOL_GPL
+-0x6883e0d5    rtc_set_time    vmlinux EXPORT_SYMBOL_GPL
+-0xf753d6ff    drm_i2c_encoder_mode_set        vmlinux EXPORT_SYMBOL
+-0x0b0d888b    icmpv6_err_convert      vmlinux EXPORT_SYMBOL
+-0x908cb3fc    vfs_readv       vmlinux EXPORT_SYMBOL
+-0x3e467689    do_sync_write   vmlinux EXPORT_SYMBOL
+-0xe01edb1a    vb2_plane_vaddr vmlinux EXPORT_SYMBOL_GPL
+-0xff9c7899    fb_get_mode     vmlinux EXPORT_SYMBOL
+-0x63923641    crypto_shash_setkey     vmlinux EXPORT_SYMBOL_GPL
+-0x66c159c0    crypto_ahash_setkey     vmlinux EXPORT_SYMBOL_GPL
+-0xb2c17922    search_binary_handler   vmlinux EXPORT_SYMBOL
+-0x07438699    rt_mutex_trylock        vmlinux EXPORT_SYMBOL_GPL
+-0x559b763f    mmc_detect_change       vmlinux EXPORT_SYMBOL
+-0xed2c3cec    drm_debugfs_remove_files        vmlinux EXPORT_SYMBOL
+-0xea5c6ccb    rtnl_link_get_net       vmlinux EXPORT_SYMBOL
+-0x420c7411    ahash_attr_alg  vmlinux EXPORT_SYMBOL_GPL
+-0xc690866c    irq_work_queue  vmlinux EXPORT_SYMBOL_GPL
+-0x22640142    sdio_readw      vmlinux EXPORT_SYMBOL_GPL
+-0x246e1a87    sdio_readl      vmlinux EXPORT_SYMBOL_GPL
+-0xafb35b17    sdio_readb      vmlinux EXPORT_SYMBOL_GPL
+-0x713125bd    cpufreq_freq_attr_scaling_available_freqs       vmlinux EXPORT_SYMBOL_GPL
+-0xd7095481    usb_remove_phy  vmlinux EXPORT_SYMBOL_GPL
+-0x76d878f8    usb_remove_hcd  vmlinux EXPORT_SYMBOL_GPL
+-0x7e543e70    device_store_bool       vmlinux EXPORT_SYMBOL_GPL
+-0x407136b1    __put_user_8    vmlinux EXPORT_SYMBOL
+-0x1567020f    tcp_disconnect  vmlinux EXPORT_SYMBOL
+-0x1f615e38    bio_pair_release        vmlinux EXPORT_SYMBOL
+-0x2469810f    __rcu_read_unlock       vmlinux EXPORT_SYMBOL_GPL
+-0xea51d53a    extcon_get_extcon_dev   vmlinux EXPORT_SYMBOL_GPL
+-0x52c47236    put_device      vmlinux EXPORT_SYMBOL_GPL
+-0x194eadaa    drm_edid_header_is_valid        vmlinux EXPORT_SYMBOL
+-0x7d89e34a    drm_gtf_mode_complex    vmlinux EXPORT_SYMBOL
+-0x75c2b9f1    memalloc_socks  vmlinux EXPORT_SYMBOL_GPL
+-0xb10dfa5a    register_filesystem     vmlinux EXPORT_SYMBOL
+-0x758a782e    blk_fill_rwbs   vmlinux EXPORT_SYMBOL_GPL
+-0xba497f13    loops_per_jiffy vmlinux EXPORT_SYMBOL
+-0xc657abdc    v4l2_ctrl_subscribe_event       vmlinux EXPORT_SYMBOL
+-0xc7472c0b    devm_input_allocate_device      vmlinux EXPORT_SYMBOL
+-0xdb2c2fbf    spi_alloc_device        vmlinux EXPORT_SYMBOL_GPL
+-0xa33be4ce    inet_confirm_addr       vmlinux EXPORT_SYMBOL
+-0x48eb98d1    eth_validate_addr       vmlinux EXPORT_SYMBOL
+-0xc5718627    sg_copy_to_buffer       vmlinux EXPORT_SYMBOL
+-0x7ab88a45    system_freezing_cnt     vmlinux EXPORT_SYMBOL
+-0x7d0db45c    jiffies_to_clock_t      vmlinux EXPORT_SYMBOL
+-0x2c208607    power_supply_is_system_supplied vmlinux EXPORT_SYMBOL_GPL
+-0xc9422c05    devm_usb_get_phy_dev    vmlinux EXPORT_SYMBOL_GPL
+-0xba3a6941    drm_getsarea    vmlinux EXPORT_SYMBOL
+-0x1ffe8e3f    nfc_register_device     vmlinux EXPORT_SYMBOL
+-0x0478373c    generic_make_request    vmlinux EXPORT_SYMBOL
+-0x0b9a91be    generic_file_llseek_size        vmlinux EXPORT_SYMBOL
+-0x1c87a811    __round_jiffies_up      vmlinux EXPORT_SYMBOL_GPL
+-0x93d6ad2c    usb_debug_root  vmlinux EXPORT_SYMBOL_GPL
+-0xd3ce47fe    drm_mode_crtc_set_gamma_size    vmlinux EXPORT_SYMBOL
+-0xbe16ad70    drm_addbufs_pci vmlinux EXPORT_SYMBOL
+-0xd5dae19f    regulator_get_exclusive vmlinux EXPORT_SYMBOL_GPL
+-0x02124474    ip_send_check   vmlinux EXPORT_SYMBOL
+-0x628cbfaa    rtmsg_ifinfo    vmlinux EXPORT_SYMBOL
+-0xb0d3bca5    __rtnl_register vmlinux EXPORT_SYMBOL_GPL
+-0x23b9d6e2    mangle_path     vmlinux EXPORT_SYMBOL
+-0xe7c52663    v4l2_m2m_create_bufs    vmlinux EXPORT_SYMBOL_GPL
+-0x63625aaa    usb_composite_setup_continue    vmlinux EXPORT_SYMBOL_GPL
+-0x41f53df0    anon_inode_getfd        vmlinux EXPORT_SYMBOL_GPL
+-0x24d5ba21    filemap_flush   vmlinux EXPORT_SYMBOL
+-0xb49f6bea    iio_enum_write  vmlinux EXPORT_SYMBOL_GPL
+-0x1bfbfeeb    mc1n2_set_mclk_source   vmlinux EXPORT_SYMBOL
+-0x95e6e500    blk_stack_limits        vmlinux EXPORT_SYMBOL
+-0xeb46c362    fuse_conn_init  vmlinux EXPORT_SYMBOL_GPL
+-0x0e9003db    pm_generic_freeze_late  vmlinux EXPORT_SYMBOL_GPL
+-0xf2fa6c7e    drm_gem_vm_close        vmlinux EXPORT_SYMBOL
+-0x5bbc0a12    __fib_lookup    vmlinux EXPORT_SYMBOL_GPL
+-0x1dd6e42b    tcp_set_state   vmlinux EXPORT_SYMBOL_GPL
+-0xa77d88f6    strnlen_user    vmlinux EXPORT_SYMBOL
+-0x191ef206    i2c_smbus_read_i2c_block_data   vmlinux EXPORT_SYMBOL
+-0x52b992dc    drm_kms_helper_poll_disable     vmlinux EXPORT_SYMBOL
+-0x6fc997a4    tty_mutex       vmlinux EXPORT_SYMBOL
+-0x3973c5f8    kunmap  vmlinux EXPORT_SYMBOL
+-0xb28f5ef1    xt_free_table_info      vmlinux EXPORT_SYMBOL
+-0x1d0b568b    mnt_pin vmlinux EXPORT_SYMBOL
+-0x50ba53b9    set_create_files_as     vmlinux EXPORT_SYMBOL
+-0xcbd3dbd0    serial8250_modem_status vmlinux EXPORT_SYMBOL_GPL
+-0xe38dd51c    dev_get_by_name vmlinux EXPORT_SYMBOL
+-0x69458fd5    snd_dma_alloc_pages_fallback    vmlinux EXPORT_SYMBOL
+-0xb3fda4b7    __page_symlink  vmlinux EXPORT_SYMBOL
+-0x400fb79c    install_exec_creds      vmlinux EXPORT_SYMBOL
+-0xbed3ae54    sched_setscheduler      vmlinux EXPORT_SYMBOL_GPL
+-0xeb923e09    power_supply_set_battery_charged        vmlinux EXPORT_SYMBOL_GPL
+-0xfdab6de3    unregister_sound_midi   vmlinux EXPORT_SYMBOL
+-0x30a80826    __kfifo_from_user       vmlinux EXPORT_SYMBOL
+-0x6923ce63    irq_work_sync   vmlinux EXPORT_SYMBOL_GPL
+-0xe7197773    drm_ht_insert_item      vmlinux EXPORT_SYMBOL
+-0xdf75f3c9    ipcomp_input    vmlinux EXPORT_SYMBOL_GPL
+-0xac966a6d    udp_prot        vmlinux EXPORT_SYMBOL
+-0xc6531cd4    inet_putpeer    vmlinux EXPORT_SYMBOL_GPL
+-0xe2b955e2    nat_h245_hook   vmlinux EXPORT_SYMBOL_GPL
+-0xf34732f2    netif_set_xps_queue     vmlinux EXPORT_SYMBOL
+-0x7681d145    snd_ctl_register_ioctl  vmlinux EXPORT_SYMBOL
+-0xaae48971    mmc_card_sleep  vmlinux EXPORT_SYMBOL
+-0x58fe6474    v4l2_m2m_ioctl_qbuf     vmlinux EXPORT_SYMBOL_GPL
+-0x00d1d0d0    i2c_adapter_type        vmlinux EXPORT_SYMBOL_GPL
+-0xb971ebca    rndis_get_next_response vmlinux EXPORT_SYMBOL
+-0xc88b565d    inet6_sk_rebuild_header vmlinux EXPORT_SYMBOL_GPL
+-0x83a4c277    mb_cache_shrink vmlinux EXPORT_SYMBOL
+-0xf1e98c74    avenrun vmlinux EXPORT_SYMBOL
+-0x1318fa1c    __ww_mutex_lock_interruptible   vmlinux EXPORT_SYMBOL
+-0x2d3385d3    system_wq       vmlinux EXPORT_SYMBOL
+-0x94e4e64e    v4l2_event_queue        vmlinux EXPORT_SYMBOL_GPL
+-0x76fd0937    device_init_wakeup      vmlinux EXPORT_SYMBOL_GPL
+-0x40a6f522    __arm_ioremap   vmlinux EXPORT_SYMBOL
+-0xc2165d85    __arm_iounmap   vmlinux EXPORT_SYMBOL
+-0xaf50e76d    elf_set_personality     vmlinux EXPORT_SYMBOL
+-0xd9f8f32d    nf_ct_extend_register   vmlinux EXPORT_SYMBOL_GPL
+-0x6ceb8cf4    mark_page_accessed      vmlinux EXPORT_SYMBOL
+-0x17f36c02    mmc_calc_max_discard    vmlinux EXPORT_SYMBOL
+-0x0d45c48f    v4l2_clk_register       vmlinux EXPORT_SYMBOL
+-0x123959a1    v4l2_type_names vmlinux EXPORT_SYMBOL
+-0x02a18c74    nf_conntrack_destroy    vmlinux EXPORT_SYMBOL
+-0x679f4b6b    scsi_report_bus_reset   vmlinux EXPORT_SYMBOL
+-0xf8224b12    mali_get_user_setting   vmlinux EXPORT_SYMBOL
+-0x3c93ad98    tty_port_install        vmlinux EXPORT_SYMBOL_GPL
+-0x63fb81e4    brcmu_pktq_penq drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x723a1683    brcmu_pktq_pdeq drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0xfa595453    ip6_sk_dst_lookup_flow  vmlinux EXPORT_SYMBOL_GPL
+-0xa76f7e50    snd_dma_get_reserved_buf        vmlinux EXPORT_SYMBOL
+-0x61ed1c8e    cdev_add        vmlinux EXPORT_SYMBOL
+-0x69447467    ring_buffer_write       vmlinux EXPORT_SYMBOL_GPL
+-0xfcd7bc0b    ring_buffer_empty       vmlinux EXPORT_SYMBOL_GPL
+-0x82939ebd    rcu_batches_completed_sched     vmlinux EXPORT_SYMBOL_GPL
+-0x9e44b9b7    of_get_next_available_child     vmlinux EXPORT_SYMBOL
+-0x1010f1ee    hid_output_report       vmlinux EXPORT_SYMBOL_GPL
+-0x59e5070d    __do_div64      vmlinux EXPORT_SYMBOL
+-0xa2d91fcc    xfrm_input      vmlinux EXPORT_SYMBOL
+-0x07a62853    dev_mc_add      vmlinux EXPORT_SYMBOL
+-0x40908b29    dev_mc_del      vmlinux EXPORT_SYMBOL
+-0x2eed048e    dev_uc_add      vmlinux EXPORT_SYMBOL
+-0x69dba7f4    dev_uc_del      vmlinux EXPORT_SYMBOL
+-0x15361516    register_pernet_subsys  vmlinux EXPORT_SYMBOL_GPL
+-0x915be34a    snd_timer_new   vmlinux EXPORT_SYMBOL
+-0x3c45a56f    blk_queue_update_dma_pad        vmlinux EXPORT_SYMBOL
+-0x069d40a0    blkdev_get_by_path      vmlinux EXPORT_SYMBOL
+-0xa440bdfe    open_exec       vmlinux EXPORT_SYMBOL
+-0x374682ce    rtc_update_irq  vmlinux EXPORT_SYMBOL_GPL
+-0xba2d0719    drm_mode_hsync  vmlinux EXPORT_SYMBOL
+-0x2d7a787f    drm_dp_clock_recovery_ok        vmlinux EXPORT_SYMBOL
+-0xd59b2bb0    fb_blank        vmlinux EXPORT_SYMBOL
+-0x0b48677a    __kfifo_init    vmlinux EXPORT_SYMBOL
+-0x249c96e2    mb_cache_entry_find_next        vmlinux EXPORT_SYMBOL
+-0xaee2539e    inode_init_owner        vmlinux EXPORT_SYMBOL
+-0x7b24ccb3    file_ns_capable vmlinux EXPORT_SYMBOL
+-0x37c0412f    cpu_subsys      vmlinux EXPORT_SYMBOL_GPL
+-0x9993bf08    rt_mutex_destroy        vmlinux EXPORT_SYMBOL_GPL
+-0xd4034828    system_freezable_wq     vmlinux EXPORT_SYMBOL_GPL
+-0x9963a089    queue_delayed_work_on   vmlinux EXPORT_SYMBOL
+-0x1284891b    iio_trigger_notify_done vmlinux EXPORT_SYMBOL
+-0x03212586    v4l2_m2m_streamoff      vmlinux EXPORT_SYMBOL_GPL
+-0x5b19634d    div_s64_rem     vmlinux EXPORT_SYMBOL
+-0xb110bb66    __set_page_dirty_nobuffers      vmlinux EXPORT_SYMBOL
+-0xd7d79132    put_online_cpus vmlinux EXPORT_SYMBOL_GPL
+-0x121e3c12    devres_open_group       vmlinux EXPORT_SYMBOL_GPL
+-0x8eae4744    __nf_ct_kill_acct       vmlinux EXPORT_SYMBOL_GPL
+-0xcf88625f    mempool_create_node     vmlinux EXPORT_SYMBOL
+-0x222fa684    lg_global_lock  vmlinux EXPORT_SYMBOL
+-0x7cb2eca1    find_get_pid    vmlinux EXPORT_SYMBOL_GPL
+-0x971ad8d8    usbnet_unlink_rx_urbs   vmlinux EXPORT_SYMBOL_GPL
+-0xa551b417    devm_pwm_get    vmlinux EXPORT_SYMBOL_GPL
+-0xb138607d    dev_set_promiscuity     vmlinux EXPORT_SYMBOL
+-0xc8ca31af    timed_output_dev_register       vmlinux EXPORT_SYMBOL_GPL
+-0x2967cbf7    dm_get_rq_mapinfo       vmlinux EXPORT_SYMBOL_GPL
+-0x07013243    scsi_bios_ptable        vmlinux EXPORT_SYMBOL
+-0x9780e683    pm_generic_resume       vmlinux EXPORT_SYMBOL_GPL
+-0x3074f033    drm_order       vmlinux EXPORT_SYMBOL
+-0xa87f4ece    neigh_connected_output  vmlinux EXPORT_SYMBOL
+-0xe9f7149c    zlib_deflate_workspacesize      vmlinux EXPORT_SYMBOL
+-0x2d03c10d    posix_acl_create        vmlinux EXPORT_SYMBOL
+-0xbe254e92    param_set_ushort        vmlinux EXPORT_SYMBOL
+-0xf0ca36cf    drm_prime_init_file_private     vmlinux EXPORT_SYMBOL
+-0xb001e18c    drm_plane_init  vmlinux EXPORT_SYMBOL
+-0xb2922319    bt_sock_recvmsg vmlinux EXPORT_SYMBOL
+-0xe7f38f6d    udp_flush_pending_frames        vmlinux EXPORT_SYMBOL
+-0xf0726368    dev_get_stats   vmlinux EXPORT_SYMBOL
+-0xd3f7e5cc    snd_soc_default_volatile_register       vmlinux EXPORT_SYMBOL_GPL
+-0x92c5fcb5    snd_timer_notify        vmlinux EXPORT_SYMBOL
+-0x86fb9b05    bitmap_parse_user       vmlinux EXPORT_SYMBOL
+-0x01000e51    schedule        vmlinux EXPORT_SYMBOL
+-0xbd597aa3    usb_add_function        vmlinux EXPORT_SYMBOL_GPL
+-0x460e4737    pm_generic_poweroff     vmlinux EXPORT_SYMBOL_GPL
+-0x6920e885    nlmsg_notify    vmlinux EXPORT_SYMBOL
+-0x247a1d7a    ww_mutex_unlock vmlinux EXPORT_SYMBOL
+-0x1498f6af    mmput   vmlinux EXPORT_SYMBOL_GPL
+-0x709eb78b    init_task       vmlinux EXPORT_SYMBOL
+-0x3052a0ee    watchdog_unregister_device      vmlinux EXPORT_SYMBOL_GPL
+-0x80eaa56e    drm_i2c_encoder_save    vmlinux EXPORT_SYMBOL
+-0xe540813f    drm_property_create_enum        vmlinux EXPORT_SYMBOL
+-0x6c642207    drm_get_connector_name  vmlinux EXPORT_SYMBOL
+-0x42151efa    balloon_devinfo_alloc   vmlinux EXPORT_SYMBOL_GPL
+-0xfa544711    video_devdata   vmlinux EXPORT_SYMBOL
+-0x8e9618cd    wakeup_source_create    vmlinux EXPORT_SYMBOL_GPL
+-0x72f12e79    drm_probe_ddc   vmlinux EXPORT_SYMBOL
+-0x89d66811    build_ehash_secret      vmlinux EXPORT_SYMBOL
+-0xf4329926    __inet_twsk_hashdance   vmlinux EXPORT_SYMBOL_GPL
+-0xd0e13603    gnet_stats_copy_app     vmlinux EXPORT_SYMBOL
+-0x1b015d25    bitmap_parselist        vmlinux EXPORT_SYMBOL
+-0xf91bf3db    __insert_inode_hash     vmlinux EXPORT_SYMBOL
+-0x308b733a    getboottime     vmlinux EXPORT_SYMBOL_GPL
+-0x69f04aa3    revert_creds    vmlinux EXPORT_SYMBOL
+-0xdf929370    fs_overflowgid  vmlinux EXPORT_SYMBOL
+-0xa1177bf1    i2c_verify_client       vmlinux EXPORT_SYMBOL
+-0x0e5358d0    input_allocate_device   vmlinux EXPORT_SYMBOL
+-0x4fed4ee0    pm_runtime_barrier      vmlinux EXPORT_SYMBOL_GPL
+-0xb939d297    dev_printk      vmlinux EXPORT_SYMBOL
+-0x090849e3    phy_power_on    vmlinux EXPORT_SYMBOL_GPL
+-0x47416e14    cpu_rmap_add    vmlinux EXPORT_SYMBOL
+-0x08fbaf94    xfrm_policy_walk        vmlinux EXPORT_SYMBOL
+-0x774846b4    nf_log_unset    vmlinux EXPORT_SYMBOL
+-0x00aaf0d4    wm_hubs_add_analogue_routes     vmlinux EXPORT_SYMBOL_GPL
+-0xe9d7e477    snd_card_proc_new       vmlinux EXPORT_SYMBOL
+-0x97de2b83    debug_locks_silent      vmlinux EXPORT_SYMBOL_GPL
+-0x3e452a00    blocking_notifier_call_chain    vmlinux EXPORT_SYMBOL_GPL
+-0xae83dc8c    spi_bitbang_setup_transfer      vmlinux EXPORT_SYMBOL_GPL
+-0x8d871961    cpu_tlb vmlinux EXPORT_SYMBOL
+-0xfe694f5b    regmap_read     vmlinux EXPORT_SYMBOL_GPL
+-0x594bf15b    ioport_map      vmlinux EXPORT_SYMBOL
+-0x2d3abae7    __skb_checksum_complete vmlinux EXPORT_SYMBOL
+-0xb5a459dc    unregister_blkdev       vmlinux EXPORT_SYMBOL
+-0xd0a8eac3    write_inode_now vmlinux EXPORT_SYMBOL
+-0x7d3a11d4    tty_lock        vmlinux EXPORT_SYMBOL
+-0xa6dea12e    regulator_register      vmlinux EXPORT_SYMBOL_GPL
+-0x0ce021b8    ieee80211_amsdu_to_8023s        vmlinux EXPORT_SYMBOL
+-0xe0088286    fat_search_long vmlinux EXPORT_SYMBOL_GPL
+-0x08ca5b31    seq_path        vmlinux EXPORT_SYMBOL
+-0xcc5005fe    msleep_interruptible    vmlinux EXPORT_SYMBOL
+-0x2f0d9053    usb_otg_state_string    vmlinux EXPORT_SYMBOL_GPL
+-0xf2997713    tty_termios_hw_change   vmlinux EXPORT_SYMBOL
+-0x53893194    dev_addr_add    vmlinux EXPORT_SYMBOL
+-0x0dd3fd84    netdev_err      vmlinux EXPORT_SYMBOL
+-0x62849ac7    dev_valid_name  vmlinux EXPORT_SYMBOL
+-0x193466be    kfree_skb_partial       vmlinux EXPORT_SYMBOL
+-0xd2a941d4    sg_init_table   vmlinux EXPORT_SYMBOL
+-0x5642793a    radix_tree_tag_clear    vmlinux EXPORT_SYMBOL
+-0xc3bb6d9e    blk_pre_runtime_resume  vmlinux EXPORT_SYMBOL
+-0xd3a7747d    fsnotify        vmlinux EXPORT_SYMBOL_GPL
+-0x4f3b569c    generic_file_open       vmlinux EXPORT_SYMBOL
+-0xc87c1f84    ktime_get       vmlinux EXPORT_SYMBOL_GPL
+-0x89bbafc6    usb_register_notify     vmlinux EXPORT_SYMBOL_GPL
+-0x19ac480a    cfg80211_new_sta        vmlinux EXPORT_SYMBOL
+-0xd18ba458    generic_cont_expand_simple      vmlinux EXPORT_SYMBOL
+-0x5cf6467f    d_instantiate   vmlinux EXPORT_SYMBOL
+-0xd1ef6f16    genphy_update_link      vmlinux EXPORT_SYMBOL
+-0x4a77677a    nfc_hci_recv_frame      vmlinux EXPORT_SYMBOL
+-0xc2a19d85    register_sound_special_device   vmlinux EXPORT_SYMBOL
+-0x5b3060c4    blk_queue_rq_timed_out  vmlinux EXPORT_SYMBOL_GPL
+-0x2cbfd99b    vb2_queue_init  vmlinux EXPORT_SYMBOL_GPL
+-0x955d725c    drm_mm_scan_remove_block        vmlinux EXPORT_SYMBOL
+-0x6d346792    pin_config_group_get    vmlinux EXPORT_SYMBOL
+-0xf82a1863    pin_config_group_set    vmlinux EXPORT_SYMBOL
+-0x08c473b7    xt_alloc_table_info     vmlinux EXPORT_SYMBOL
+-0xb7b61546    crc32_be        vmlinux EXPORT_SYMBOL
+-0x26520970    vm_memory_committed     vmlinux EXPORT_SYMBOL_GPL
+-0xcf283b4f    iommu_domain_alloc      vmlinux EXPORT_SYMBOL_GPL
+-0x52ffd07f    xfrm_output_resume      vmlinux EXPORT_SYMBOL_GPL
+-0x4c21e163    skb_find_text   vmlinux EXPORT_SYMBOL
+-0x5279b639    current_fs_time vmlinux EXPORT_SYMBOL
+-0x04cc0a21    i2c_unregister_device   vmlinux EXPORT_SYMBOL_GPL
+-0x13fc56de    drm_helper_crtc_in_use  vmlinux EXPORT_SYMBOL
+-0x6d399587    regulator_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0x6b037ba6    nf_nat_l4proto_unregister       vmlinux EXPORT_SYMBOL_GPL
+-0x8231a8bd    nf_nat_l3proto_unregister       vmlinux EXPORT_SYMBOL_GPL
+-0x6350314b    tcf_hash_create vmlinux EXPORT_SYMBOL
+-0xf339287c    skb_queue_tail  vmlinux EXPORT_SYMBOL
+-0x5409775b    free_irq_cpu_rmap       vmlinux EXPORT_SYMBOL
+-0x65771426    crypto_lookup_template  vmlinux EXPORT_SYMBOL_GPL
+-0xd61347c6    register_sysctl vmlinux EXPORT_SYMBOL
+-0xd8c37e37    vfs_test_lock   vmlinux EXPORT_SYMBOL_GPL
+-0x952664c5    do_exit vmlinux EXPORT_SYMBOL_GPL
+-0xcb07e4af    tcf_hash_destroy        vmlinux EXPORT_SYMBOL
+-0x78953de6    mark_buffer_dirty_inode vmlinux EXPORT_SYMBOL
+-0x3109b751    cpu_clock       vmlinux EXPORT_SYMBOL_GPL
+-0xdf842e2b    drm_vblank_cleanup      vmlinux EXPORT_SYMBOL
+-0x57810201    ip_tunnel_lookup        vmlinux EXPORT_SYMBOL_GPL
+-0xb1c3a01a    oops_in_progress        vmlinux EXPORT_SYMBOL
+-0x0fca29c0    dev_pm_qos_remove_request       vmlinux EXPORT_SYMBOL_GPL
+-0xc407a137    dma_wait_for_async_tx   vmlinux EXPORT_SYMBOL_GPL
+-0x046a9d1b    backlight_device_register       vmlinux EXPORT_SYMBOL
+-0x2a36b31a    nf_ct_helper_log        vmlinux EXPORT_SYMBOL_GPL
+-0xb442919d    blk_get_backing_dev_info        vmlinux EXPORT_SYMBOL
+-0x0ed2f3b5    elevator_init   vmlinux EXPORT_SYMBOL
+-0x21bda10a    kill_fasync     vmlinux EXPORT_SYMBOL
+-0x622dacba    tick_nohz_idle_enter    vmlinux EXPORT_SYMBOL_GPL
+-0xdd4a5569    param_get_byte  vmlinux EXPORT_SYMBOL
+-0x764d38f1    tty_insert_flip_string_fixed_flag       vmlinux EXPORT_SYMBOL
+-0xcf5bc354    tty_register_ldisc      vmlinux EXPORT_SYMBOL
+-0x88f68355    tty_throttle    vmlinux EXPORT_SYMBOL
+-0x335e720e    tty_check_change        vmlinux EXPORT_SYMBOL
+-0x1d5568cb    dev_disable_lro vmlinux EXPORT_SYMBOL
+-0xb2be6e92    netdev_stats_to_stats64 vmlinux EXPORT_SYMBOL
+-0x728261ca    kblockd_schedule_delayed_work   vmlinux EXPORT_SYMBOL
+-0x5c959646    debugfs_create_u8       vmlinux EXPORT_SYMBOL_GPL
+-0x0c150d31    cgroup_taskset_first    vmlinux EXPORT_SYMBOL_GPL
+-0xec690544    attribute_container_classdev_to_container       vmlinux EXPORT_SYMBOL_GPL
+-0xda1613df    drm_put_dev     vmlinux EXPORT_SYMBOL
+-0x157667da    drm_gem_vm_open vmlinux EXPORT_SYMBOL
+-0x8ad8d79e    drm_fb_helper_setcmap   vmlinux EXPORT_SYMBOL
+-0x5550f136    snd_soc_dapm_info_pin_switch    vmlinux EXPORT_SYMBOL_GPL
+-0xcb08eeba    drm_core_ioremap        vmlinux EXPORT_SYMBOL
+-0x6aba167a    regulator_list_voltage  vmlinux EXPORT_SYMBOL_GPL
+-0x1b0ac272    __tracepoint_kmalloc_node       vmlinux EXPORT_SYMBOL
+-0xd62c833f    schedule_timeout        vmlinux EXPORT_SYMBOL
+-0x432fd7f6    __gpio_set_value        vmlinux EXPORT_SYMBOL_GPL
+-0x6c8d5ae8    __gpio_get_value        vmlinux EXPORT_SYMBOL_GPL
+-0x65ccb6f0    call_netevent_notifiers vmlinux EXPORT_SYMBOL_GPL
+-0x4a7fb243    percpu_counter_compare  vmlinux EXPORT_SYMBOL
+-0xced58760    crypto_alloc_base       vmlinux EXPORT_SYMBOL_GPL
+-0xfcf2f8c0    aio_put_req     vmlinux EXPORT_SYMBOL
+-0x6f3a36eb    dw_mci_pltfm_pmops      vmlinux EXPORT_SYMBOL_GPL
+-0xe6c3ebb0    __raw_writesw   vmlinux EXPORT_SYMBOL
+-0x51908eb8    __raw_writesl   vmlinux EXPORT_SYMBOL
+-0x75fee7fd    __raw_writesb   vmlinux EXPORT_SYMBOL
+-0xef35b0c3    cfg80211_report_wowlan_wakeup   vmlinux EXPORT_SYMBOL
+-0x99591a7a    ipv6_ext_hdr    vmlinux EXPORT_SYMBOL
+-0x65396d44    neigh_destroy   vmlinux EXPORT_SYMBOL
+-0x405b485b    netdev_warn     vmlinux EXPORT_SYMBOL
+-0xf45f8934    blk_end_request_cur     vmlinux EXPORT_SYMBOL
+-0x9a682368    replace_mount_options   vmlinux EXPORT_SYMBOL
+-0x5a7c0586    hid_validate_values     vmlinux EXPORT_SYMBOL_GPL
+-0x88618588    mmc_wait_for_app_cmd    vmlinux EXPORT_SYMBOL
+-0xccbbfe3b    v4l2_fh_del     vmlinux EXPORT_SYMBOL_GPL
+-0xcefcd99a    serial8250_unregister_port      vmlinux EXPORT_SYMBOL
+-0x0bed6399    __xfrm_policy_check     vmlinux EXPORT_SYMBOL
+-0xf1947b5c    snd_ctl_rename_id       vmlinux EXPORT_SYMBOL
+-0xb9220639    blk_lld_busy    vmlinux EXPORT_SYMBOL_GPL
+-0x4178eee3    blk_sync_queue  vmlinux EXPORT_SYMBOL
+-0x32b0e045    usbnet_get_link vmlinux EXPORT_SYMBOL_GPL
+-0xd578f42c    fat_alloc_new_dir       vmlinux EXPORT_SYMBOL_GPL
+-0x0eacb23a    simple_write_end        vmlinux EXPORT_SYMBOL
+-0xcbee20b2    get_cpu_iowait_time_us  vmlinux EXPORT_SYMBOL_GPL
+-0xea01bd2a    st_sensors_init_sensor  vmlinux EXPORT_SYMBOL
+-0xb7433944    hid_open_report vmlinux EXPORT_SYMBOL_GPL
+-0x2d339a62    scsi_schedule_eh        vmlinux EXPORT_SYMBOL_GPL
+-0xc6544448    pm_runtime_irq_safe     vmlinux EXPORT_SYMBOL_GPL
+-0xa5afacf6    class_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0xedf69cd6    drm_gem_private_object_init     vmlinux EXPORT_SYMBOL
+-0x999c3148    __raw_readsb    vmlinux EXPORT_SYMBOL
+-0xfb268a5f    ip_mc_rejoin_groups     vmlinux EXPORT_SYMBOL
+-0xafe4c25e    netdev_update_features  vmlinux EXPORT_SYMBOL
+-0xd75c79df    smp_call_function       vmlinux EXPORT_SYMBOL
+-0xef6c3f70    round_jiffies_up_relative       vmlinux EXPORT_SYMBOL_GPL
+-0x64420947    spi_async       vmlinux EXPORT_SYMBOL_GPL
+-0xe62c2cf6    regmap_raw_write_async  vmlinux EXPORT_SYMBOL_GPL
+-0x226a057d    eth_header_cache        vmlinux EXPORT_SYMBOL
+-0xb9d025c9    llist_del_first vmlinux EXPORT_SYMBOL_GPL
+-0xb678366f    int_sqrt        vmlinux EXPORT_SYMBOL
+-0x9d28f747    dec_zone_page_state     vmlinux EXPORT_SYMBOL
+-0x0799aca4    local_bh_enable vmlinux EXPORT_SYMBOL
+-0x8d07023c    i2c_smbus_read_byte_data        vmlinux EXPORT_SYMBOL
+-0xca5dbc50    scsi_print_sense_hdr    vmlinux EXPORT_SYMBOL
+-0x3da076a8    scsi_host_lookup        vmlinux EXPORT_SYMBOL
+-0xf54ff64f    uart_set_options        vmlinux EXPORT_SYMBOL_GPL
+-0x47ff399f    regulator_is_supported_voltage  vmlinux EXPORT_SYMBOL_GPL
+-0x585469ee    of_get_videomode        vmlinux EXPORT_SYMBOL_GPL
+-0x852786a9    phy_get vmlinux EXPORT_SYMBOL_GPL
+-0xaf8aa518    system_rev      vmlinux EXPORT_SYMBOL
+-0x6c3d2a02    tcp_syn_flood_action    vmlinux EXPORT_SYMBOL
+-0xf38bcdf3    nf_conntrack_max        vmlinux EXPORT_SYMBOL_GPL
+-0x44de5177    snd_pcm_suspend vmlinux EXPORT_SYMBOL
+-0xb23ef570    blk_bio_map_sg  vmlinux EXPORT_SYMBOL
+-0x4c5e7289    config_item_get vmlinux EXPORT_SYMBOL
+-0xea12473b    config_item_put vmlinux EXPORT_SYMBOL
+-0xbe68ef11    mnt_drop_write_file     vmlinux EXPORT_SYMBOL
+-0x381144a9    __tracepoint_module_get vmlinux EXPORT_SYMBOL
+-0xc5fdef94    call_usermodehelper     vmlinux EXPORT_SYMBOL
+-0x1eb9516e    round_jiffies_relative  vmlinux EXPORT_SYMBOL_GPL
+-0x7cc035a7    __ucmpdi2       vmlinux EXPORT_SYMBOL
+-0xe42e1f70    klist_iter_init_node    vmlinux EXPORT_SYMBOL_GPL
+-0x5c440c21    hci_conn_check_secure   vmlinux EXPORT_SYMBOL
+-0x5b34d4b0    snd_soc_codec_readable_register vmlinux EXPORT_SYMBOL_GPL
+-0x0634100a    bitmap_parselist_user   vmlinux EXPORT_SYMBOL
+-0x5b72009f    ida_simple_get  vmlinux EXPORT_SYMBOL
+-0x11a6ce4b    blk_queue_update_dma_alignment  vmlinux EXPORT_SYMBOL
+-0x3e0dd939    blk_start_request       vmlinux EXPORT_SYMBOL
+-0x51749fc8    _raw_read_lock_irq      vmlinux EXPORT_SYMBOL
+-0x757bbc48    hrtimer_try_to_cancel   vmlinux EXPORT_SYMBOL_GPL
+-0x70899e95    v4l2_m2m_buf_remove     vmlinux EXPORT_SYMBOL_GPL
+-0x5f96a661    v4l2_ctrl_check vmlinux EXPORT_SYMBOL
+-0x42bf1c34    video_unregister_device vmlinux EXPORT_SYMBOL
+-0xcd914413    drm_get_minor   vmlinux EXPORT_SYMBOL
+-0xa0e5202d    nf_register_hook        vmlinux EXPORT_SYMBOL
+-0x86d5e343    __dev_get_by_name       vmlinux EXPORT_SYMBOL
+-0x2cc749f6    skb_copy_and_csum_dev   vmlinux EXPORT_SYMBOL
+-0x9613509a    idr_replace     vmlinux EXPORT_SYMBOL
+-0x82acfb70    blk_iopoll_sched        vmlinux EXPORT_SYMBOL
+-0x2c7db649    irq_dispose_mapping     vmlinux EXPORT_SYMBOL_GPL
+-0x530b1e98    pm_suspend      vmlinux EXPORT_SYMBOL
+-0xae69b1c1    usermodehelper_read_unlock      vmlinux EXPORT_SYMBOL_GPL
+-0x39f4b0d2    s3c_adc_release vmlinux EXPORT_SYMBOL_GPL
+-0xc2f16e25    input_unregister_handle vmlinux EXPORT_SYMBOL
+-0x67326732    usb_hcd_map_urb_for_dma vmlinux EXPORT_SYMBOL_GPL
+-0xd125790d    drm_hdmi_avi_infoframe_from_display_mode        vmlinux EXPORT_SYMBOL
+-0xe10a472d    drm_mm_pre_get  vmlinux EXPORT_SYMBOL
+-0xf082ddf3    register_netdev vmlinux EXPORT_SYMBOL
+-0x935b5da0    snd_timer_continue      vmlinux EXPORT_SYMBOL
+-0xcc37f55c    blk_limits_io_opt       vmlinux EXPORT_SYMBOL
+-0xd4c5def3    inet_twsk_purge vmlinux EXPORT_SYMBOL_GPL
+-0x9e9f1714    __bitmap_andnot vmlinux EXPORT_SYMBOL
+-0x737de5e9    radix_tree_tag_get      vmlinux EXPORT_SYMBOL
+-0xed1e0a03    posix_acl_from_xattr    vmlinux EXPORT_SYMBOL
+-0x5256cd6e    clear_nlink     vmlinux EXPORT_SYMBOL
+-0xc9f0ae5d    nf_xfrm_me_harder       vmlinux EXPORT_SYMBOL
+-0x4751c2af    dev_loopback_xmit       vmlinux EXPORT_SYMBOL
+-0x74bd982c    skb_seq_read    vmlinux EXPORT_SYMBOL
+-0x798c5110    snd_soc_platform_trigger        vmlinux EXPORT_SYMBOL_GPL
+-0x5362ae46    config_item_init        vmlinux EXPORT_SYMBOL
+-0x83c8a355    param_set_int   vmlinux EXPORT_SYMBOL
+-0x8099b954    i2c_transfer    vmlinux EXPORT_SYMBOL
+-0x61e262f1    scsi_device_lookup      vmlinux EXPORT_SYMBOL
+-0xfbb86a51    drm_i2c_encoder_prepare vmlinux EXPORT_SYMBOL
+-0x4090c0fe    snd_card_file_add       vmlinux EXPORT_SYMBOL
+-0x559879f5    crypto_drop_spawn       vmlinux EXPORT_SYMBOL_GPL
+-0x27c2197f    param_set_short vmlinux EXPORT_SYMBOL
+-0xcc4c1be7    nf_nat_tftp_hook        vmlinux EXPORT_SYMBOL_GPL
+-0xc9a3b093    get_h225_addr   vmlinux EXPORT_SYMBOL_GPL
+-0x59e9d996    skb_pad vmlinux EXPORT_SYMBOL
+-0x77bc13a0    strim   vmlinux EXPORT_SYMBOL
+-0x4c2a94b4    shash_register_instance vmlinux EXPORT_SYMBOL_GPL
+-0x33c77d65    seq_write       vmlinux EXPORT_SYMBOL
+-0x44aec3a4    generic_file_llseek     vmlinux EXPORT_SYMBOL
+-0x12d60b5f    v4l2_ctrl_handler_free  vmlinux EXPORT_SYMBOL
+-0x19f0c50a    ip6_tnl_parse_tlv_enc_lim       vmlinux EXPORT_SYMBOL
+-0x1cea8d0a    snd_soc_dapm_new_widgets        vmlinux EXPORT_SYMBOL_GPL
+-0xe1f4606d    snd_info_create_module_entry    vmlinux EXPORT_SYMBOL
+-0x999e8297    vfree   vmlinux EXPORT_SYMBOL
+-0x841575f5    wait_on_page_bit        vmlinux EXPORT_SYMBOL
+-0x51205d4b    mutex_lock      vmlinux EXPORT_SYMBOL
+-0xe97c74fd    rtc_update_irq_enable   vmlinux EXPORT_SYMBOL_GPL
+-0x849722db    dma_request_slave_channel       vmlinux EXPORT_SYMBOL_GPL
+-0x120b336a    __rb_insert_augmented   vmlinux EXPORT_SYMBOL
+-0x6359b128    elv_rq_merge_ok vmlinux EXPORT_SYMBOL
+-0xee3496c3    dma_pool_alloc  vmlinux EXPORT_SYMBOL
+-0xa835f402    mmc_detect_card_removed vmlinux EXPORT_SYMBOL
+-0xbe1b0b72    scsi_get_host_dev       vmlinux EXPORT_SYMBOL
+-0xaf4e166f    dma_async_memcpy_pg_to_pg       vmlinux EXPORT_SYMBOL
+-0xe34d76a6    l2cap_is_socket vmlinux EXPORT_SYMBOL
+-0xd875e3e2    ip6_route_lookup        vmlinux EXPORT_SYMBOL_GPL
+-0xd58c5fcb    tcp_v4_do_rcv   vmlinux EXPORT_SYMBOL
+-0x3413b5de    blk_dump_rq_flags       vmlinux EXPORT_SYMBOL
+-0xc8449f3c    sysfs_create_group      vmlinux EXPORT_SYMBOL_GPL
+-0xf3e42ab4    get_device      vmlinux EXPORT_SYMBOL_GPL
+-0xf147dcb2    hdmi_spd_infoframe_init vmlinux EXPORT_SYMBOL
+-0x1776281f    xfrm_unregister_mode    vmlinux EXPORT_SYMBOL
+-0x4737cc63    consume_skb     vmlinux EXPORT_SYMBOL
+-0x72081296    extcon_find_cable_index vmlinux EXPORT_SYMBOL_GPL
+-0x641d5fb6    usbnet_status_start     vmlinux EXPORT_SYMBOL_GPL
+-0x8f2c5edc    scsi_add_device vmlinux EXPORT_SYMBOL
+-0x8652db9f    __pm_stay_awake vmlinux EXPORT_SYMBOL_GPL
+-0xb9d3a88c    tcf_action_dump_1       vmlinux EXPORT_SYMBOL
+-0xb6f19e98    snd_pcm_lib_get_vmalloc_page    vmlinux EXPORT_SYMBOL
+-0x29e5e6f3    poll_schedule_timeout   vmlinux EXPORT_SYMBOL
+-0x99f58330    lg_local_lock_cpu       vmlinux EXPORT_SYMBOL
+-0x58862e69    v4l2_m2m_ioctl_streamon vmlinux EXPORT_SYMBOL_GPL
+-0xa340fae0    i2c_add_numbered_adapter        vmlinux EXPORT_SYMBOL_GPL
+-0x806c2801    usb_unanchor_urb        vmlinux EXPORT_SYMBOL_GPL
+-0x485b3745    dma_get_slave_channel   vmlinux EXPORT_SYMBOL_GPL
+-0x1d0a43c3    phy_power_off   vmlinux EXPORT_SYMBOL_GPL
+-0x0fd14a9d    tcp_prot        vmlinux EXPORT_SYMBOL
+-0x4bfdc9e2    textsearch_prepare      vmlinux EXPORT_SYMBOL
+-0x988958ef    fuse_direct_io  vmlinux EXPORT_SYMBOL_GPL
+-0x996c4d30    proc_dointvec_ms_jiffies        vmlinux EXPORT_SYMBOL
+-0x785d494b    rndis_msg_parser        vmlinux EXPORT_SYMBOL
+-0xcea853d2    root_device_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0xf13f5821    inet_frag_kill  vmlinux EXPORT_SYMBOL
+-0x8f4f1272    simple_setattr  vmlinux EXPORT_SYMBOL
+-0x9c0dba49    simple_getattr  vmlinux EXPORT_SYMBOL
+-0x2232a8a5    mempool_free    vmlinux EXPORT_SYMBOL
+-0xc72ca946    v4l2_fh_release vmlinux EXPORT_SYMBOL_GPL
+-0x2a0afd5e    videomode_from_timing   vmlinux EXPORT_SYMBOL_GPL
+-0xaf157b0c    nfc_dep_link_is_up      vmlinux EXPORT_SYMBOL
+-0x20efc937    tcf_em_tree_validate    vmlinux EXPORT_SYMBOL
+-0xd05683cc    cred_to_ucred   vmlinux EXPORT_SYMBOL_GPL
+-0xa1ac0050    sock_tx_timestamp       vmlinux EXPORT_SYMBOL
+-0x48bd992d    bdget_disk      vmlinux EXPORT_SYMBOL
+-0x50985501    configfs_register_subsystem     vmlinux EXPORT_SYMBOL
+-0x041a8568    attribute_container_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0x3de4b634    driver_for_each_device  vmlinux EXPORT_SYMBOL_GPL
+-0xc1984867    drm_vblank_put  vmlinux EXPORT_SYMBOL
+-0xc8c20253    tcp_rcv_state_process   vmlinux EXPORT_SYMBOL
+-0x280525ed    skb_to_sgvec    vmlinux EXPORT_SYMBOL_GPL
+-0x20c55ae0    sscanf  vmlinux EXPORT_SYMBOL
+-0xe3dd61a6    __breadahead    vmlinux EXPORT_SYMBOL
+-0x1b42a36f    vb2_dma_contig_init_ctx vmlinux EXPORT_SYMBOL_GPL
+-0xc326f752    v4l2_g_ctrl     vmlinux EXPORT_SYMBOL
+-0x3adca4e5    pfifo_fast_ops  vmlinux EXPORT_SYMBOL
+-0x67677183    snd_pcm_hw_constraint_integer   vmlinux EXPORT_SYMBOL
+-0x1fab5905    wait_for_completion     vmlinux EXPORT_SYMBOL
+-0x0b972255    led_classdev_suspend    vmlinux EXPORT_SYMBOL_GPL
+-0xd617281d    wm8994_set_bits vmlinux EXPORT_SYMBOL_GPL
+-0x4ad196c8    wm8994_reg_read vmlinux EXPORT_SYMBOL_GPL
+-0xb3f0ca49    platform_device_register_full   vmlinux EXPORT_SYMBOL_GPL
+-0x13bfa97e    devm_gpio_free  vmlinux EXPORT_SYMBOL
+-0xe5646321    dev_get_by_name_rcu     vmlinux EXPORT_SYMBOL
+-0x8fed35b2    snd_soc_dpcm_can_be_free_stop   vmlinux EXPORT_SYMBOL_GPL
+-0x30a4f4ca    bstr_printf     vmlinux EXPORT_SYMBOL_GPL
+-0x72350130    ___ratelimit    vmlinux EXPORT_SYMBOL
+-0x0e5d4fe1    i2c_smbus_write_byte_data       vmlinux EXPORT_SYMBOL
+-0xe7d93ea1    usb_unlink_urb  vmlinux EXPORT_SYMBOL_GPL
+-0xaf141636    __nf_nat_mangle_tcp_packet      vmlinux EXPORT_SYMBOL
+-0x584e1dcb    wm_hubs_add_analogue_controls   vmlinux EXPORT_SYMBOL_GPL
+-0x15e14e37    snd_dma_alloc_pages     vmlinux EXPORT_SYMBOL
+-0x3a26ed11    sched_clock     vmlinux EXPORT_SYMBOL_GPL
+-0x6f5d8c04    iio_device_unregister   vmlinux EXPORT_SYMBOL
+-0x9e672ff6    scsi_kmap_atomic_sg     vmlinux EXPORT_SYMBOL
+-0xe8d95e86    platform_device_add_data        vmlinux EXPORT_SYMBOL_GPL
+-0x1fcece42    inet_twdr_twcal_tick    vmlinux EXPORT_SYMBOL_GPL
+-0xd1f0ea5e    sk_unattached_filter_destroy    vmlinux EXPORT_SYMBOL_GPL
+-0xdb647fcf    sock_create_lite        vmlinux EXPORT_SYMBOL
+-0x82b125fb    mmc_hw_reset_check      vmlinux EXPORT_SYMBOL
+-0x45db3821    drm_gem_create_mmap_offset      vmlinux EXPORT_SYMBOL
+-0x4eca00d2    nfc_proto_register      vmlinux EXPORT_SYMBOL
+-0x8b69cf06    d_obtain_alias  vmlinux EXPORT_SYMBOL
+-0xc7462fc5    cpufreq_unregister_governor     vmlinux EXPORT_SYMBOL_GPL
+-0xc7280d53    v4l2_g_ext_ctrls        vmlinux EXPORT_SYMBOL
+-0xb3b58737    ip6_datagram_connect    vmlinux EXPORT_SYMBOL_GPL
+-0x365bf841    ip4_datagram_connect    vmlinux EXPORT_SYMBOL
+-0x4a8cb865    tcp_timewait_state_process      vmlinux EXPORT_SYMBOL
+-0xa34e2838    nf_conntrack_helper_try_module_get      vmlinux EXPORT_SYMBOL_GPL
+-0x26dcd9ac    security_inode_init_security    vmlinux EXPORT_SYMBOL
+-0xd705b4c7    schedule_hrtimeout      vmlinux EXPORT_SYMBOL_GPL
+-0x44643b93    __aeabi_lmul    vmlinux EXPORT_SYMBOL
+-0x824efa53    nobh_writepage  vmlinux EXPORT_SYMBOL
+-0x78eb3b6d    clear_page_dirty_for_io vmlinux EXPORT_SYMBOL
+-0xad6bf99a    srcu_init_notifier_head vmlinux EXPORT_SYMBOL_GPL
+-0x9a1fc4b4    jiffies_to_timeval      vmlinux EXPORT_SYMBOL
+-0xf1823632    clk_disable     vmlinux EXPORT_SYMBOL_GPL
+-0x69da85e3    v4l2_ctrl_poll  vmlinux EXPORT_SYMBOL
+-0xdcd7d2a3    starget_for_each_device vmlinux EXPORT_SYMBOL
+-0x4dd58b53    subsys_interface_register       vmlinux EXPORT_SYMBOL_GPL
+-0xf3916987    global_cursor_default   vmlinux EXPORT_SYMBOL
+-0x3d2b2b9f    tcp_reno_min_cwnd       vmlinux EXPORT_SYMBOL_GPL
+-0xf3bd26cd    vfs_follow_link vmlinux EXPORT_SYMBOL
+-0xc11bd00f    tracepoint_probe_unregister     vmlinux EXPORT_SYMBOL_GPL
+-0xb5532b8b    spi_bitbang_stop        vmlinux EXPORT_SYMBOL_GPL
+-0x4deb10c3    tty_schedule_flip       vmlinux EXPORT_SYMBOL
+-0x2dc227f8    brcmu_d11_attach        drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0xc009330d    sysfs_rename_link       vmlinux EXPORT_SYMBOL_GPL
+-0xce0b9b59    max77693_read_reg       vmlinux EXPORT_SYMBOL_GPL
+-0xc0c44856    tty_devnum      vmlinux EXPORT_SYMBOL
+-0x4f391d0e    nla_parse       vmlinux EXPORT_SYMBOL
+-0xc39a1e2a    write_dirty_buffer      vmlinux EXPORT_SYMBOL
+-0xc8a154f9    noop_llseek     vmlinux EXPORT_SYMBOL
+-0xc65d3eed    ring_buffer_entries_cpu vmlinux EXPORT_SYMBOL_GPL
+-0x16807034    iommu_group_for_each_dev        vmlinux EXPORT_SYMBOL_GPL
+-0x76829e1b    nfc_proto_unregister    vmlinux EXPORT_SYMBOL
+-0x21ac8b77    iommu_group_get_by_id   vmlinux EXPORT_SYMBOL_GPL
+-0x60601d69    input_free_device       vmlinux EXPORT_SYMBOL
+-0x3a03067b    regulator_notifier_call_chain   vmlinux EXPORT_SYMBOL_GPL
+-0x3e9110fa    __hw_addr_unsync        vmlinux EXPORT_SYMBOL
+-0x7d11c268    jiffies vmlinux EXPORT_SYMBOL
+-0x3987712e    iio_read_channel_scale  vmlinux EXPORT_SYMBOL_GPL
+-0x7deff673    dm_consume_args vmlinux EXPORT_SYMBOL
+-0xc092d57b    i2c_verify_adapter      vmlinux EXPORT_SYMBOL
+-0x2e7a4300    drm_rgb_quant_range_selectable  vmlinux EXPORT_SYMBOL
+-0x594e1317    __modsi3        vmlinux EXPORT_SYMBOL
+-0x211331fa    __divsi3        vmlinux EXPORT_SYMBOL
+-0xa3482467    dev_queue_xmit  vmlinux EXPORT_SYMBOL
+-0x13d0adf7    __kfifo_out     vmlinux EXPORT_SYMBOL
+-0xe06141e9    security_sk_clone       vmlinux EXPORT_SYMBOL
+-0x75d5b827    proc_mkdir      vmlinux EXPORT_SYMBOL
+-0x6f6ac78c    dummy_irq_chip  vmlinux EXPORT_SYMBOL_GPL
+-0x3efb35c9    get_online_cpus vmlinux EXPORT_SYMBOL_GPL
+-0x5907773b    of_device_alloc vmlinux EXPORT_SYMBOL
+-0x1c00411e    blk_rq_map_sg   vmlinux EXPORT_SYMBOL
+-0x09cf1b46    proc_dointvec_jiffies   vmlinux EXPORT_SYMBOL
+-0x5db2254a    devm_usb_get_phy_by_phandle     vmlinux EXPORT_SYMBOL_GPL
+-0x85caf365    usb_hcd_start_port_resume       vmlinux EXPORT_SYMBOL_GPL
+-0x0a469d23    mfd_clone_cell  vmlinux EXPORT_SYMBOL
+-0x93e85c29    dmam_free_noncoherent   vmlinux EXPORT_SYMBOL
+-0x241ab4c2    phy_destroy     vmlinux EXPORT_SYMBOL_GPL
+-0x408b2c52    __napi_schedule vmlinux EXPORT_SYMBOL
+-0xc911f7d5    dev_change_carrier      vmlinux EXPORT_SYMBOL
+-0xbfaa31e1    sk_stream_wait_memory   vmlinux EXPORT_SYMBOL
+-0x0d3cb182    kstrtos16_from_user     vmlinux EXPORT_SYMBOL
+-0x9f2bdaac    __bitmap_or     vmlinux EXPORT_SYMBOL
+-0xae729e59    security_req_classify_flow      vmlinux EXPORT_SYMBOL
+-0x273cbba4    get_dcookie     vmlinux EXPORT_SYMBOL_GPL
+-0x9b7510d1    trace_event_raw_init    vmlinux EXPORT_SYMBOL_GPL
+-0xb24585bc    usb_set_interface       vmlinux EXPORT_SYMBOL_GPL
+-0x08cbe96c    tty_unlock      vmlinux EXPORT_SYMBOL
+-0x07e3f668    netlink_broadcast_filtered      vmlinux EXPORT_SYMBOL
+-0x4761f17c    register_netevent_notifier      vmlinux EXPORT_SYMBOL_GPL
+-0xc7ec6c27    strspn  vmlinux EXPORT_SYMBOL
+-0x97255bdf    strlen  vmlinux EXPORT_SYMBOL
+-0xcdb399d4    cgroup_rightmost_descendant     vmlinux EXPORT_SYMBOL_GPL
+-0x4bc7787e    iio_trigger_register    vmlinux EXPORT_SYMBOL
+-0x05d7e32a    pm_generic_runtime_idle vmlinux EXPORT_SYMBOL_GPL
+-0xcb0b5e8e    of_display_timings_exist        vmlinux EXPORT_SYMBOL_GPL
+-0xdb68bbad    rfkill_destroy  vmlinux EXPORT_SYMBOL
+-0x2e6a04e3    hci_recv_frame  vmlinux EXPORT_SYMBOL
+-0xedbaee5e    nla_strcmp      vmlinux EXPORT_SYMBOL
+-0x26bb950b    __kfifo_from_user_r     vmlinux EXPORT_SYMBOL
+-0xca2ff6df    crypto_ahash_type       vmlinux EXPORT_SYMBOL_GPL
+-0x2c41c751    v4l2_m2m_ctx_release    vmlinux EXPORT_SYMBOL_GPL
+-0x99213409    scsi_allocate_command   vmlinux EXPORT_SYMBOL
+-0x6827603e    skb_trim        vmlinux EXPORT_SYMBOL
+-0x5cca80cf    perf_tp_event   vmlinux EXPORT_SYMBOL_GPL
+-0xa6961e25    vb2_common_vm_ops       vmlinux EXPORT_SYMBOL_GPL
+-0x72856c9e    v4l2_m2m_ioctl_expbuf   vmlinux EXPORT_SYMBOL_GPL
+-0xb8acff80    usb_enable_autosuspend  vmlinux EXPORT_SYMBOL_GPL
+-0x403f9529    gpio_request_one        vmlinux EXPORT_SYMBOL_GPL
+-0x06d549e6    pinctrl_free_gpio       vmlinux EXPORT_SYMBOL_GPL
+-0x02ae8433    xfrm_policy_delete      vmlinux EXPORT_SYMBOL
+-0x6e71c6be    inet_frags_init vmlinux EXPORT_SYMBOL
+-0x4e3567f7    match_int       vmlinux EXPORT_SYMBOL
+-0x054434d6    radix_tree_tag_set      vmlinux EXPORT_SYMBOL
+-0x31f956eb    blk_queue_lld_busy      vmlinux EXPORT_SYMBOL_GPL
+-0x26565c84    shash_free_instance     vmlinux EXPORT_SYMBOL_GPL
+-0x38668bab    debugfs_create_x64      vmlinux EXPORT_SYMBOL_GPL
+-0xbf1f9a9b    bdi_setup_and_register  vmlinux EXPORT_SYMBOL
+-0xfc64abed    power_supply_changed    vmlinux EXPORT_SYMBOL_GPL
+-0x19326753    rtc_irq_register        vmlinux EXPORT_SYMBOL_GPL
+-0xaf3cc095    nfc_hci_free_device     vmlinux EXPORT_SYMBOL
+-0x86f38980    skb_cow_data    vmlinux EXPORT_SYMBOL_GPL
+-0xe0c0d2af    snd_pcm_kernel_ioctl    vmlinux EXPORT_SYMBOL
+-0xdfb01a80    cpu_v7_dcache_clean_area        vmlinux EXPORT_SYMBOL
+-0x1879fcbd    bridge_tunnel_header    vmlinux EXPORT_SYMBOL
+-0x9a011a6b    l2cap_conn_put  vmlinux EXPORT_SYMBOL
+-0x6b3ee85a    ip4_datagram_release_cb vmlinux EXPORT_SYMBOL_GPL
+-0xdd07d415    snd_card_free_when_closed       vmlinux EXPORT_SYMBOL
+-0x868acba5    get_options     vmlinux EXPORT_SYMBOL
+-0xa2409544    setup_irq       vmlinux EXPORT_SYMBOL_GPL
+-0x567b73f9    i2c_get_adapter vmlinux EXPORT_SYMBOL
+-0x7a4e7297    drm_edid_block_valid    vmlinux EXPORT_SYMBOL
+-0x2ec524ad    __kfifo_in_r    vmlinux EXPORT_SYMBOL
+-0x66f9da32    bh_uptodate_or_lock     vmlinux EXPORT_SYMBOL
+-0xf9ffcd69    input_unregister_handler        vmlinux EXPORT_SYMBOL
+-0x51dce73b    xfrm_state_walk_init    vmlinux EXPORT_SYMBOL
+-0x113554e9    __skb_dst_set_noref     vmlinux EXPORT_SYMBOL
+-0x3c9d1211    string_get_size vmlinux EXPORT_SYMBOL
+-0xe654362e    fat_fill_super  vmlinux EXPORT_SYMBOL_GPL
+-0xea5a46e7    register_exec_domain    vmlinux EXPORT_SYMBOL
+-0xaf473214    iio_channel_get_all     vmlinux EXPORT_SYMBOL_GPL
+-0xf8a9d6b2    rtc_read_alarm  vmlinux EXPORT_SYMBOL_GPL
+-0xa0c8e0ed    usbnet_set_settings     vmlinux EXPORT_SYMBOL_GPL
+-0x170bb6a9    usbnet_get_settings     vmlinux EXPORT_SYMBOL_GPL
+-0xe0701fe6    fl6_sock_lookup vmlinux EXPORT_SYMBOL_GPL
+-0x9330cb9f    sg_alloc_table  vmlinux EXPORT_SYMBOL
+-0x5873f4c0    handle_simple_irq       vmlinux EXPORT_SYMBOL_GPL
+-0xf27977e2    async_synchronize_cookie_domain vmlinux EXPORT_SYMBOL_GPL
+-0xcf732e49    call_usermodehelper_exec        vmlinux EXPORT_SYMBOL
+-0xd789a39d    cpufreq_governor_dbs    vmlinux EXPORT_SYMBOL_GPL
+-0x4ff0c84f    of_mdio_find_bus        vmlinux EXPORT_SYMBOL
+-0xe7a664c4    nf_hooks        vmlinux EXPORT_SYMBOL
+-0xd366806d    snd_info_free_entry     vmlinux EXPORT_SYMBOL
+-0xbcac6160    pm_qos_remove_notifier  vmlinux EXPORT_SYMBOL_GPL
+-0x698d1e98    v4l2_ctrl_handler_init_class    vmlinux EXPORT_SYMBOL
+-0x79c0d5a3    drm_gem_prime_fd_to_handle      vmlinux EXPORT_SYMBOL
+-0xff1e9dd8    seq_list_start  vmlinux EXPORT_SYMBOL
+-0x01accd73    __clk_get_name  vmlinux EXPORT_SYMBOL_GPL
+-0x3e92b3d3    power_supply_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x71590103    drm_release     vmlinux EXPORT_SYMBOL
+-0x0b9e5852    xfrm_aead_get_byname    vmlinux EXPORT_SYMBOL_GPL
+-0xb7b856bf    km_state_notify vmlinux EXPORT_SYMBOL
+-0x3f5b1415    nf_ct_port_nlattr_to_tuple      vmlinux EXPORT_SYMBOL_GPL
+-0x98b6628a    snd_pcm_set_ops vmlinux EXPORT_SYMBOL
+-0x1ea06663    _raw_write_lock vmlinux EXPORT_SYMBOL
+-0x44dd3d8d    completion_done vmlinux EXPORT_SYMBOL
+-0xa1eabd87    drm_mode_list_concat    vmlinux EXPORT_SYMBOL
+-0x581ed292    drm_mm_get_block_generic        vmlinux EXPORT_SYMBOL
+-0xefa98e30    dma_run_dependencies    vmlinux EXPORT_SYMBOL_GPL
+-0xe8bea3bc    qdisc_put_stab  vmlinux EXPORT_SYMBOL
+-0x2247cba2    seq_printf      vmlinux EXPORT_SYMBOL
+-0x7e646f56    media_entity_remove_links       vmlinux EXPORT_SYMBOL_GPL
+-0xa0e05fb1    drm_connector_cleanup   vmlinux EXPORT_SYMBOL
+-0xb1cf44df    fb_find_best_mode       vmlinux EXPORT_SYMBOL
+-0x0b742fd7    simple_strtol   vmlinux EXPORT_SYMBOL
+-0xd709e32c    ilookup5_nowait vmlinux EXPORT_SYMBOL
+-0x25865b31    mmc_free_host   vmlinux EXPORT_SYMBOL
+-0x054063e9    devres_release  vmlinux EXPORT_SYMBOL_GPL
+-0xc9b2045b    drm_mode_validate_size  vmlinux EXPORT_SYMBOL
+-0xac6855b0    gen_kill_estimator      vmlinux EXPORT_SYMBOL
+-0xc32b07a0    blk_queue_alignment_offset      vmlinux EXPORT_SYMBOL
+-0x630c9194    fuse_dev_operations     vmlinux EXPORT_SYMBOL_GPL
+-0xa4824580    devm_add_action vmlinux EXPORT_SYMBOL_GPL
+-0xd8fe5b35    drm_mm_init     vmlinux EXPORT_SYMBOL
+-0x9b9b05b4    __bio_clone     vmlinux EXPORT_SYMBOL
+-0x5fda0227    vfs_stat        vmlinux EXPORT_SYMBOL
+-0xa0fbac79    wake_up_bit     vmlinux EXPORT_SYMBOL
+-0x796fc5ce    scsi_get_sense_info_fld vmlinux EXPORT_SYMBOL
+-0x699ffdcd    nf_conntrack_flush_report       vmlinux EXPORT_SYMBOL_GPL
+-0x89e6edac    snd_pcm_lib_malloc_pages        vmlinux EXPORT_SYMBOL
+-0x48034724    zlib_deflateReset       vmlinux EXPORT_SYMBOL
+-0xcdca3691    nr_irqs vmlinux EXPORT_SYMBOL_GPL
+-0xcff6b676    _raw_spin_trylock_bh    vmlinux EXPORT_SYMBOL
+-0xca45efbc    drm_format_horz_chroma_subsampling      vmlinux EXPORT_SYMBOL
+-0xb6f4cc92    tty_do_resize   vmlinux EXPORT_SYMBOL
+-0x51e77c97    pfn_valid       vmlinux EXPORT_SYMBOL
+-0xa2446605    jbd2_journal_set_triggers       vmlinux EXPORT_SYMBOL
+-0xebbb44c8    f_setown        vmlinux EXPORT_SYMBOL
+-0xdfef3371    v4l2_m2m_ioctl_streamoff        vmlinux EXPORT_SYMBOL_GPL
+-0x56c8799d    scsi_kunmap_atomic_sg   vmlinux EXPORT_SYMBOL
+-0xaae1593e    scsi_block_when_processing_errors       vmlinux EXPORT_SYMBOL
+-0xe330bf1f    ip6_dst_hoplimit        vmlinux EXPORT_SYMBOL
+-0xf8996ee4    arp_invalidate  vmlinux EXPORT_SYMBOL
+-0x6d27ef64    __bitmap_empty  vmlinux EXPORT_SYMBOL
+-0xbfa789ca    elv_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0x06ae2b19    mmc_can_sanitize        vmlinux EXPORT_SYMBOL
+-0xdd3dc2ce    usb_clear_halt  vmlinux EXPORT_SYMBOL_GPL
+-0xfe0b2aae    amba_device_unregister  vmlinux EXPORT_SYMBOL
+-0xc3771b21    of_pwm_get      vmlinux EXPORT_SYMBOL_GPL
+-0x21b7d56d    dev_mc_sync_multiple    vmlinux EXPORT_SYMBOL
+-0x1dfc5292    dev_uc_sync_multiple    vmlinux EXPORT_SYMBOL
+-0xde7da8e3    submit_bh       vmlinux EXPORT_SYMBOL
+-0xc15d05d9    mnt_clone_write vmlinux EXPORT_SYMBOL_GPL
+-0x25fa84a3    page_mkclean    vmlinux EXPORT_SYMBOL_GPL
+-0x405c1144    get_seconds     vmlinux EXPORT_SYMBOL
+-0xf0f1246c    kvasprintf      vmlinux EXPORT_SYMBOL
+-0xa5526619    rb_insert_color vmlinux EXPORT_SYMBOL
+-0x7bb12a75    v4l2_m2m_get_vq vmlinux EXPORT_SYMBOL
+-0x5819c8aa    usb_anchor_empty        vmlinux EXPORT_SYMBOL_GPL
+-0x4e3d273c    __xfrm_init_state       vmlinux EXPORT_SYMBOL
+-0xa2a69edc    __module_text_address   vmlinux EXPORT_SYMBOL_GPL
+-0x66d87d38    symbol_put_addr vmlinux EXPORT_SYMBOL_GPL
+-0xe45cc839    hrtimer_start_range_ns  vmlinux EXPORT_SYMBOL_GPL
+-0xd3e6f60d    cpu_possible_mask       vmlinux EXPORT_SYMBOL
+-0x52451ffe    hid_dump_field  vmlinux EXPORT_SYMBOL_GPL
+-0xbd5a9986    drm_helper_probe_single_connector_modes vmlinux EXPORT_SYMBOL
+-0xb694ce34    tcf_hash_search vmlinux EXPORT_SYMBOL
+-0xaaefb815    d_alloc vmlinux EXPORT_SYMBOL
+-0xaca38c86    unuse_mm        vmlinux EXPORT_SYMBOL_GPL
+-0x5de3d7af    __alloc_pages_nodemask  vmlinux EXPORT_SYMBOL
+-0xe2142ad8    i2c_smbus_read_word_data        vmlinux EXPORT_SYMBOL
+-0xbfe4cfe6    tty_buffer_request_room vmlinux EXPORT_SYMBOL_GPL
+-0xa6089679    elv_abort_queue vmlinux EXPORT_SYMBOL
+-0x918ad429    ring_buffer_lock_reserve        vmlinux EXPORT_SYMBOL_GPL
+-0xdc461430    irq_set_affinity_hint   vmlinux EXPORT_SYMBOL_GPL
+-0x37258879    iio_channel_release     vmlinux EXPORT_SYMBOL_GPL
+-0x1a082d69    max77693_update_reg     vmlinux EXPORT_SYMBOL_GPL
+-0x4b0bd573    wiphy_unregister        vmlinux EXPORT_SYMBOL
+-0x575d8c47    inet_sk_rx_dst_set      vmlinux EXPORT_SYMBOL
+-0x3c6f5a97    snd_soc_register_component      vmlinux EXPORT_SYMBOL_GPL
+-0xb9e03943    blk_execute_rq_nowait   vmlinux EXPORT_SYMBOL_GPL
+-0x15f571ec    blk_set_stacking_limits vmlinux EXPORT_SYMBOL
+-0x721585fd    security_inode_mkdir    vmlinux EXPORT_SYMBOL_GPL
+-0xbf16ef9a    clk_get_rate    vmlinux EXPORT_SYMBOL_GPL
+-0x22b79dae    clk_set_rate    vmlinux EXPORT_SYMBOL_GPL
+-0x0dbd0e20    of_property_read_u8_array       vmlinux EXPORT_SYMBOL_GPL
+-0xe6fce6f2    v4l2_ctrl_merge vmlinux EXPORT_SYMBOL
+-0x12f1d8d3    dev_err vmlinux EXPORT_SYMBOL
+-0x1c3e0368    drm_gem_object_handle_free      vmlinux EXPORT_SYMBOL
+-0xfda9ed46    udp_proc_register       vmlinux EXPORT_SYMBOL
+-0xccf2974f    kernel_sendpage vmlinux EXPORT_SYMBOL
+-0x4b77922a    delete_from_page_cache  vmlinux EXPORT_SYMBOL
+-0x3f5b67d5    wait_for_completion_killable    vmlinux EXPORT_SYMBOL
+-0xa62fb61a    usb_gstrings_attach     vmlinux EXPORT_SYMBOL_GPL
+-0x5cabdced    dev_pm_qos_remove_global_notifier       vmlinux EXPORT_SYMBOL_GPL
+-0x27b864a9    s5p_gpio_get_drvstr     vmlinux EXPORT_SYMBOL
+-0xc828d2a3    s5p_gpio_set_drvstr     vmlinux EXPORT_SYMBOL
+-0xd9cf81bd    cfg80211_send_assoc_timeout     vmlinux EXPORT_SYMBOL
+-0x693c3961    nf_ct_helper_hash       vmlinux EXPORT_SYMBOL_GPL
+-0x487ef8ba    snd_soc_dai_set_sysclk  vmlinux EXPORT_SYMBOL_GPL
+-0x50c89f23    __alloc_percpu  vmlinux EXPORT_SYMBOL_GPL
+-0x09469482    kfree_call_rcu  vmlinux EXPORT_SYMBOL_GPL
+-0x177d5d5e    uart_insert_char        vmlinux EXPORT_SYMBOL_GPL
+-0xb17c2f9b    clear_inode     vmlinux EXPORT_SYMBOL
+-0x3b733a7c    led_trigger_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0x16000a3c    dm_device_name  vmlinux EXPORT_SYMBOL_GPL
+-0x0465ca31    scsi_cmd_get_serial     vmlinux EXPORT_SYMBOL
+-0x0f52944d    drm_helper_hpd_irq_event        vmlinux EXPORT_SYMBOL
+-0x99517682    udp_encap_enable        vmlinux EXPORT_SYMBOL
+-0x1e43dec1    neigh_parms_release     vmlinux EXPORT_SYMBOL
+-0x572e85d4    blk_lookup_devt vmlinux EXPORT_SYMBOL
+-0xf7bb06b2    crypto_grab_skcipher    vmlinux EXPORT_SYMBOL_GPL
+-0xe953b21f    get_next_ino    vmlinux EXPORT_SYMBOL
+-0xdb225b82    pm_vt_switch_required   vmlinux EXPORT_SYMBOL
+-0xe1a4b69f    mmc_card_awake  vmlinux EXPORT_SYMBOL
+-0x33234a30    usb_hcd_link_urb_to_ep  vmlinux EXPORT_SYMBOL_GPL
+-0xb61a0dba    dmam_release_declared_memory    vmlinux EXPORT_SYMBOL
+-0x6865b5f6    device_release_driver   vmlinux EXPORT_SYMBOL_GPL
+-0x920accbd    ump_dd_secure_id_get    vmlinux EXPORT_SYMBOL
+-0xffb94ef0    _test_and_change_bit    vmlinux EXPORT_SYMBOL
+-0xb7a1ff6d    tcp_prequeue    vmlinux EXPORT_SYMBOL
+-0xce3ca308    copy_from_user_toio     vmlinux EXPORT_SYMBOL
+-0xd08137e8    vfs_setlease    vmlinux EXPORT_SYMBOL_GPL
+-0x89eabc8c    from_kgid_munged        vmlinux EXPORT_SYMBOL
+-0x40d04664    console_trylock vmlinux EXPORT_SYMBOL
+-0x0955d1f2    iommu_attach_device     vmlinux EXPORT_SYMBOL_GPL
+-0x9cf3e94a    dm_kcopyd_copy  vmlinux EXPORT_SYMBOL
+-0x1cec399d    v4l2_m2m_ioctl_create_bufs      vmlinux EXPORT_SYMBOL_GPL
+-0x8cae11ac    usb_alloc_streams       vmlinux EXPORT_SYMBOL_GPL
+-0xd3299096    scsi_register_interface vmlinux EXPORT_SYMBOL
+-0x885369a2    dma_common_get_sgtable  vmlinux EXPORT_SYMBOL
+-0x2251d13d    blk_queue_dma_pad       vmlinux EXPORT_SYMBOL
+-0x07cf9099    wait_for_completion_timeout     vmlinux EXPORT_SYMBOL
+-0x0efcbb1b    set_current_groups      vmlinux EXPORT_SYMBOL
+-0xea9b0ab7    v4l2_ctrl_add_handler   vmlinux EXPORT_SYMBOL
+-0x79aaab2b    i2c_smbus_read_block_data       vmlinux EXPORT_SYMBOL
+-0x964ff64a    usb_put_intf    vmlinux EXPORT_SYMBOL_GPL
+-0x9f97bf25    xfrm6_input_addr        vmlinux EXPORT_SYMBOL
+-0x81db6ebb    xz_dec_reset    vmlinux EXPORT_SYMBOL
+-0x661601de    sprint_symbol   vmlinux EXPORT_SYMBOL_GPL
+-0x1e59773c    st_gyro_common_remove   vmlinux EXPORT_SYMBOL
+-0x921e453c    drm_get_platform_dev    vmlinux EXPORT_SYMBOL
+-0x720b245e    update_region   vmlinux EXPORT_SYMBOL
+-0x2bda5922    hci_get_route   vmlinux EXPORT_SYMBOL
+-0xaa939a8b    tcf_em_unregister       vmlinux EXPORT_SYMBOL
+-0x590cf866    scm_fp_dup      vmlinux EXPORT_SYMBOL
+-0x2ce98559    kcrypto_wq      vmlinux EXPORT_SYMBOL_GPL
+-0x5351af17    shrink_dcache_parent    vmlinux EXPORT_SYMBOL
+-0x1ad83009    trace_seq_vprintf       vmlinux EXPORT_SYMBOL_GPL
+-0x8fcafa61    led_stop_software_blink vmlinux EXPORT_SYMBOL_GPL
+-0xd4a7943a    mmc_card_can_sleep      vmlinux EXPORT_SYMBOL
+-0x52f378a8    devres_remove   vmlinux EXPORT_SYMBOL_GPL
+-0x6288b8b9    serial8250_release_dma  vmlinux EXPORT_SYMBOL_GPL
+-0x63556dea    tty_vhangup     vmlinux EXPORT_SYMBOL
+-0x75c8a11c    inet_twdr_twkill_work   vmlinux EXPORT_SYMBOL_GPL
+-0x609f1c7e    synchronize_net vmlinux EXPORT_SYMBOL
+-0x6091797f    synchronize_rcu vmlinux EXPORT_SYMBOL_GPL
+-0x42825ce2    rcu_scheduler_active    vmlinux EXPORT_SYMBOL_GPL
+-0xe523ad75    synchronize_irq vmlinux EXPORT_SYMBOL
+-0xb77b0159    v4l2_prio_init  vmlinux EXPORT_SYMBOL
+-0x840dd143    rndis_deregister        vmlinux EXPORT_SYMBOL
+-0x7464ea38    dev_pm_qos_add_global_notifier  vmlinux EXPORT_SYMBOL_GPL
+-0xd325a885    bus_for_each_dev        vmlinux EXPORT_SYMBOL_GPL
+-0x3ec3d061    bus_for_each_drv        vmlinux EXPORT_SYMBOL_GPL
+-0xb2823478    pneigh_lookup   vmlinux EXPORT_SYMBOL
+-0x7037aaf0    kern_path_create        vmlinux EXPORT_SYMBOL
+-0x85061b76    _raw_write_lock_bh      vmlinux EXPORT_SYMBOL
+-0xb90cbedf    v4l2_of_get_next_endpoint       vmlinux EXPORT_SYMBOL
+-0x9d2ed0a8    snd_timer_close vmlinux EXPORT_SYMBOL
+-0x1057d320    blk_queue_find_tag      vmlinux EXPORT_SYMBOL
+-0x1e3a88fb    trace_seq_printf        vmlinux EXPORT_SYMBOL_GPL
+-0x4bc62a81    audit_enabled   vmlinux EXPORT_SYMBOL_GPL
+-0x39461d6a    in_egroup_p     vmlinux EXPORT_SYMBOL
+-0xccefabad    drm_mode_create_scaling_mode_property   vmlinux EXPORT_SYMBOL
+-0x43384bd9    drm_buffer_alloc        vmlinux EXPORT_SYMBOL
+-0x184e6c85    radix_tree_gang_lookup_slot     vmlinux EXPORT_SYMBOL
+-0xdf347b52    sec_reg_read    vmlinux EXPORT_SYMBOL_GPL
+-0x409873e3    tty_termios_baud_rate   vmlinux EXPORT_SYMBOL
+-0x07a890c8    fb_alloc_cmap   vmlinux EXPORT_SYMBOL
+-0x7d04aaa6    nf_conntrack_broadcast_help     vmlinux EXPORT_SYMBOL_GPL
+-0x5cdc7a62    skb_append_datato_frags vmlinux EXPORT_SYMBOL
+-0x9e0c711d    vzalloc_node    vmlinux EXPORT_SYMBOL
+-0x7f24de73    jiffies_to_usecs        vmlinux EXPORT_SYMBOL
+-0x37befc70    jiffies_to_msecs        vmlinux EXPORT_SYMBOL
+-0xe9807d5b    input_mt_sync_frame     vmlinux EXPORT_SYMBOL
+-0x0c0c8520    release_firmware        vmlinux EXPORT_SYMBOL
+-0x442aa46d    tcp_child_process       vmlinux EXPORT_SYMBOL
+-0x67663177    sock_diag_put_filterinfo        vmlinux EXPORT_SYMBOL
+-0xa250c838    param_get_charp vmlinux EXPORT_SYMBOL
+-0xf0b613ad    __pm_runtime_suspend    vmlinux EXPORT_SYMBOL_GPL
+-0x1a770ac3    drm_detect_hdmi_monitor vmlinux EXPORT_SYMBOL
+-0x70d7e40d    prepare_binprm  vmlinux EXPORT_SYMBOL
+-0x36d7b11a    of_find_matching_node_and_match vmlinux EXPORT_SYMBOL
+-0x8e30ad82    mdiobus_write   vmlinux EXPORT_SYMBOL
+-0xeb6173b8    tty_port_destroy        vmlinux EXPORT_SYMBOL
+-0x6c0154da    tcp_v4_destroy_sock     vmlinux EXPORT_SYMBOL
+-0x5afe3100    snd_soc_add_dai_controls        vmlinux EXPORT_SYMBOL_GPL
+-0xdf2c2742    rb_last vmlinux EXPORT_SYMBOL
+-0x7ab3ca18    eventfd_ctx_read        vmlinux EXPORT_SYMBOL_GPL
+-0xeb32e3af    mount_bdev      vmlinux EXPORT_SYMBOL
+-0xe6fbe430    can_do_mlock    vmlinux EXPORT_SYMBOL
+-0x60a13e90    rcu_barrier     vmlinux EXPORT_SYMBOL_GPL
+-0xdf60cc27    __print_symbol  vmlinux EXPORT_SYMBOL
+-0xa2a2031e    ehci_setup      vmlinux EXPORT_SYMBOL_GPL
+-0x686f8200    ndisc_mc_map    vmlinux EXPORT_SYMBOL
+-0xab8647cf    nf_ct_helper_expectfn_find_by_symbol    vmlinux EXPORT_SYMBOL_GPL
+-0x91715312    sprintf vmlinux EXPORT_SYMBOL
+-0xda3d10a8    security_tun_dev_open   vmlinux EXPORT_SYMBOL
+-0xa4a91e54    simple_unlink   vmlinux EXPORT_SYMBOL
+-0xf377a0b5    simple_attr_write       vmlinux EXPORT_SYMBOL_GPL
+-0x97263968    generic_listxattr       vmlinux EXPORT_SYMBOL
+-0x53c9394f    v4l2_ctrl_query_menu    vmlinux EXPORT_SYMBOL
+-0xf6ebc03b    net_ratelimit   vmlinux EXPORT_SYMBOL
+-0x3977cbea    dev_addr_init   vmlinux EXPORT_SYMBOL
+-0x2789cd4f    snd_soc_put_strobe      vmlinux EXPORT_SYMBOL_GPL
+-0x719074ee    snd_soc_get_strobe      vmlinux EXPORT_SYMBOL_GPL
+-0xdace599d    shash_ahash_update      vmlinux EXPORT_SYMBOL_GPL
+-0x7add44b5    posix_acl_valid vmlinux EXPORT_SYMBOL
+-0xe8fbe1c9    invalidate_inode_buffers        vmlinux EXPORT_SYMBOL
+-0x5442b464    media_device_register_entity    vmlinux EXPORT_SYMBOL_GPL
+-0xa279bad0    usb_add_config  vmlinux EXPORT_SYMBOL_GPL
+-0x1d77b0f8    unix_socket_table       vmlinux EXPORT_SYMBOL_GPL
+-0x7932f1fc    ip_tunnel_ioctl vmlinux EXPORT_SYMBOL_GPL
+-0x153b7ac0    nl_table        vmlinux EXPORT_SYMBOL_GPL
+-0xfdfcdc90    crypto_shash_update     vmlinux EXPORT_SYMBOL_GPL
+-0xa376521b    find_vma        vmlinux EXPORT_SYMBOL
+-0xe57f0426    vb2_dma_contig_cleanup_ctx      vmlinux EXPORT_SYMBOL_GPL
+-0x0f53690e    usb_autopm_get_interface_async  vmlinux EXPORT_SYMBOL_GPL
+-0xe97e3624    scsi_register   vmlinux EXPORT_SYMBOL
+-0x07d4567b    max8997_write_reg       vmlinux EXPORT_SYMBOL_GPL
+-0x24f2d831    regulator_register_notifier     vmlinux EXPORT_SYMBOL_GPL
+-0x85ab9275    nf_ct_extend_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x7721fbd2    kernel_connect  vmlinux EXPORT_SYMBOL
+-0x3095e489    single_open_size        vmlinux EXPORT_SYMBOL
+-0x54ff695a    inet_stream_connect     vmlinux EXPORT_SYMBOL
+-0xa05c03df    mempool_kmalloc vmlinux EXPORT_SYMBOL
+-0xd6df7b3f    dma_buf_end_cpu_access  vmlinux EXPORT_SYMBOL_GPL
+-0x2d5eac78    qdisc_warn_nonwc        vmlinux EXPORT_SYMBOL
+-0x7bc477d0    splice_from_pipe_begin  vmlinux EXPORT_SYMBOL
+-0xfd6293c2    boot_tvec_bases vmlinux EXPORT_SYMBOL
+-0x6d662533    _find_first_bit_le      vmlinux EXPORT_SYMBOL
+-0xd41f3207    netdev_class_remove_file        vmlinux EXPORT_SYMBOL
+-0xdf48a0eb    flex_array_put  vmlinux EXPORT_SYMBOL
+-0xcf048d93    blk_queue_physical_block_size   vmlinux EXPORT_SYMBOL
+-0xd5790350    dio_end_io      vmlinux EXPORT_SYMBOL_GPL
+-0xc0bf6ead    timecounter_cyc2time    vmlinux EXPORT_SYMBOL_GPL
+-0x303087f1    v4l2_queryctrl  vmlinux EXPORT_SYMBOL
+-0x506691f1    sock_diag_check_cookie  vmlinux EXPORT_SYMBOL_GPL
+-0x307c2fd0    generic_check_addressable       vmlinux EXPORT_SYMBOL
+-0x40b313d1    perf_event_read_value   vmlinux EXPORT_SYMBOL_GPL
+-0x04482cdb    __refrigerator  vmlinux EXPORT_SYMBOL
+-0x7cb1ae69    cpu_down        vmlinux EXPORT_SYMBOL
+-0xc9aca11e    v4l2_ctrl_handler_log_status    vmlinux EXPORT_SYMBOL
+-0xb7f77027    rtc_tm_to_ktime vmlinux EXPORT_SYMBOL_GPL
+-0x70c8201b    tty_lock_pair   vmlinux EXPORT_SYMBOL
+-0x1565add4    inet6_csk_addr2sockaddr vmlinux EXPORT_SYMBOL_GPL
+-0x72a112d9    netdev_refcnt_read      vmlinux EXPORT_SYMBOL
+-0xacc6730b    __blk_end_request       vmlinux EXPORT_SYMBOL
+-0xbe54542c    input_mt_init_slots     vmlinux EXPORT_SYMBOL
+-0xca3920b5    usb_disable_lpm vmlinux EXPORT_SYMBOL_GPL
+-0x0cd967c3    usb_disable_ltm vmlinux EXPORT_SYMBOL_GPL
+-0x3b66b0c1    __pm_wakeup_event       vmlinux EXPORT_SYMBOL_GPL
+-0x0f480178    devres_close_group      vmlinux EXPORT_SYMBOL_GPL
+-0xf0bd9740    drm_mode_parse_command_line_for_connector       vmlinux EXPORT_SYMBOL
+-0x12c6276a    drm_buffer_read_object  vmlinux EXPORT_SYMBOL
+-0xc3b93bba    klist_next      vmlinux EXPORT_SYMBOL_GPL
+-0x3d342d92    tcp_rcv_established     vmlinux EXPORT_SYMBOL
+-0x540c6f94    inet_getpeer    vmlinux EXPORT_SYMBOL_GPL
+-0x153c8015    ipv4_update_pmtu        vmlinux EXPORT_SYMBOL_GPL
+-0x0c4bfb03    xt_unregister_targets   vmlinux EXPORT_SYMBOL
+-0x5cd7eb9b    wm_hubs_dcs_done        vmlinux EXPORT_SYMBOL_GPL
+-0xd7e56a4e    simple_strtoll  vmlinux EXPORT_SYMBOL
+-0x20000329    simple_strtoul  vmlinux EXPORT_SYMBOL
+-0x9e784e44    balance_dirty_pages_ratelimited vmlinux EXPORT_SYMBOL
+-0x11195d33    usb_enable_lpm  vmlinux EXPORT_SYMBOL_GPL
+-0xd7f91a45    usb_enable_ltm  vmlinux EXPORT_SYMBOL_GPL
+-0x39e2b6d2    spi_alloc_master        vmlinux EXPORT_SYMBOL_GPL
+-0x82eb671b    scsi_prep_fn    vmlinux EXPORT_SYMBOL
+-0x4473fccc    nf_register_afinfo      vmlinux EXPORT_SYMBOL_GPL
+-0xd1e13a97    net_ns_type_operations  vmlinux EXPORT_SYMBOL_GPL
+-0x1bf69c17    proc_symlink    vmlinux EXPORT_SYMBOL
+-0x651c3828    usb_add_phy_dev vmlinux EXPORT_SYMBOL_GPL
+-0xf571b062    drm_addmap      vmlinux EXPORT_SYMBOL
+-0xb41150b4    pwm_enable      vmlinux EXPORT_SYMBOL_GPL
+-0x8c52195f    __rtnl_link_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0xe2cb9278    snd_soc_dai_set_tdm_slot        vmlinux EXPORT_SYMBOL_GPL
+-0x4de34a07    cpu_rmap_put    vmlinux EXPORT_SYMBOL
+-0xb51797f0    blk_queue_dma_alignment vmlinux EXPORT_SYMBOL
+-0xdab3304e    remap_vmalloc_range     vmlinux EXPORT_SYMBOL
+-0x5113c626    noop_backing_dev_info   vmlinux EXPORT_SYMBOL_GPL
+-0xd985dc99    mempool_free_pages      vmlinux EXPORT_SYMBOL
+-0xfcec0987    enable_irq      vmlinux EXPORT_SYMBOL
+-0x1e7bbcb3    kernel_restart  vmlinux EXPORT_SYMBOL_GPL
+-0xa26c3f65    mmc_gpio_free_cd        vmlinux EXPORT_SYMBOL
+-0x6461806d    max8997_bulk_write      vmlinux EXPORT_SYMBOL_GPL
+-0x2ff9c227    filemap_page_mkwrite    vmlinux EXPORT_SYMBOL
+-0xd2917bd3    v4l2_m2m_fop_poll       vmlinux EXPORT_SYMBOL_GPL
+-0xc11159cc    drm_mode_create vmlinux EXPORT_SYMBOL
+-0xdd27fa87    memchr  vmlinux EXPORT_SYMBOL
+-0x10329729    inet6_release   vmlinux EXPORT_SYMBOL
+-0xc18ac88d    nf_ct_expect_hsize      vmlinux EXPORT_SYMBOL_GPL
+-0x005e9828    vfs_kern_mount  vmlinux EXPORT_SYMBOL_GPL
+-0xd5bd7dac    ring_buffer_record_enable_cpu   vmlinux EXPORT_SYMBOL_GPL
+-0x00cf4a7f    of_get_parent   vmlinux EXPORT_SYMBOL
+-0xd6097597    v4l2_ctrl_new_int_menu  vmlinux EXPORT_SYMBOL
+-0x3cdbf719    drm_mode_destroy        vmlinux EXPORT_SYMBOL
+-0xb03e9a0f    nfc_set_remote_general_bytes    vmlinux EXPORT_SYMBOL
+-0x2059c814    sock_diag_register      vmlinux EXPORT_SYMBOL_GPL
+-0x315c65fd    zlib_deflateInit2       vmlinux EXPORT_SYMBOL
+-0x1ab8c624    submit_bio      vmlinux EXPORT_SYMBOL
+-0xd070d52e    alloc_page_buffers      vmlinux EXPORT_SYMBOL_GPL
+-0x622c7922    register_oom_notifier   vmlinux EXPORT_SYMBOL_GPL
+-0xe806f5a2    trace_event_buffer_lock_reserve vmlinux EXPORT_SYMBOL_GPL
+-0xcfc68341    synchronize_rcu_bh      vmlinux EXPORT_SYMBOL_GPL
+-0x549525ef    handle_nested_irq       vmlinux EXPORT_SYMBOL_GPL
+-0x20421305    on_each_cpu_mask        vmlinux EXPORT_SYMBOL
+-0xa1bb9fb1    spi_bus_type    vmlinux EXPORT_SYMBOL_GPL
+-0x8a627eb3    anon_transport_class_unregister vmlinux EXPORT_SYMBOL_GPL
+-0xd8525ea7    fl6_update_dst  vmlinux EXPORT_SYMBOL_GPL
+-0xbac1a16b    tcp_valid_rtt_meas      vmlinux EXPORT_SYMBOL
+-0xb67cd6f1    neigh_lookup    vmlinux EXPORT_SYMBOL
+-0xc2c639ae    debugfs_create_u32_array        vmlinux EXPORT_SYMBOL_GPL
+-0xd4a33b98    mmc_remove_host vmlinux EXPORT_SYMBOL
+-0x1f65abdf    usb_put_hcd     vmlinux EXPORT_SYMBOL_GPL
+-0x2ef63ad6    scsi_dev_info_list_del_keyed    vmlinux EXPORT_SYMBOL
+-0x0bf18882    tcp_mtup_init   vmlinux EXPORT_SYMBOL
+-0x0ea07ec7    kstrtou8_from_user      vmlinux EXPORT_SYMBOL
+-0x973d0f9e    kstrtoul_from_user      vmlinux EXPORT_SYMBOL
+-0x7c8db884    devm_clk_unregister     vmlinux EXPORT_SYMBOL_GPL
+-0x46066e5b    perf_pmu_name   vmlinux EXPORT_SYMBOL_GPL
+-0x951ac153    snd_soc_jack_report     vmlinux EXPORT_SYMBOL_GPL
+-0x7c1464a6    snd_soc_dapm_get_enum_double    vmlinux EXPORT_SYMBOL_GPL
+-0xd36af700    snd_soc_dapm_put_enum_double    vmlinux EXPORT_SYMBOL_GPL
+-0x222e7ce2    sysfs_streq     vmlinux EXPORT_SYMBOL
+-0xca72b2e9    alloc_buffer_head       vmlinux EXPORT_SYMBOL
+-0x364d71cb    iio_scan_mask_set       vmlinux EXPORT_SYMBOL_GPL
+-0x813f3de4    v4l2_find_nearest_format        vmlinux EXPORT_SYMBOL_GPL
+-0xb37a0603    drm_dp_link_train_channel_eq_delay      vmlinux EXPORT_SYMBOL
+-0x1fe912f1    netdev_alloc_frag       vmlinux EXPORT_SYMBOL
+-0x7bdee655    usbnet_get_endpoints    vmlinux EXPORT_SYMBOL_GPL
+-0x589e4569    syscon_regmap_lookup_by_pdevname        vmlinux EXPORT_SYMBOL_GPL
+-0x60506751    unmap_kernel_range_noflush      vmlinux EXPORT_SYMBOL_GPL
+-0x224b5740    device_remove_file      vmlinux EXPORT_SYMBOL_GPL
+-0x1b8822d8    pinctrl_gpio_direction_output   vmlinux EXPORT_SYMBOL_GPL
+-0x985e0b7d    ipv6_skip_exthdr        vmlinux EXPORT_SYMBOL
+-0xa0e33feb    ip_options_compile      vmlinux EXPORT_SYMBOL
+-0x289c3714    nf_ct_alloc_hashtable   vmlinux EXPORT_SYMBOL_GPL
+-0xc33e401a    sock_diag_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0xba86c38e    aio_complete    vmlinux EXPORT_SYMBOL
+-0x03bd889d    param_get_ulong vmlinux EXPORT_SYMBOL
+-0xa4ca666e    kill_pid        vmlinux EXPORT_SYMBOL
+-0xe56cb560    rt6_lookup      vmlinux EXPORT_SYMBOL
+-0xc8fb75a8    unix_outq_len   vmlinux EXPORT_SYMBOL_GPL
+-0xd5c5ff75    inet_frags_init_net     vmlinux EXPORT_SYMBOL
+-0x64999478    congestion_wait vmlinux EXPORT_SYMBOL
+-0x59eae699    ring_buffer_read_prepare        vmlinux EXPORT_SYMBOL_GPL
+-0xa23061f8    mmc_read_bkops_status   vmlinux EXPORT_SYMBOL
+-0xa1c46bd3    spi_bitbang_cleanup     vmlinux EXPORT_SYMBOL_GPL
+-0x4d126acf    device_store_int        vmlinux EXPORT_SYMBOL_GPL
+-0x5b546bbb    drm_gem_mmap    vmlinux EXPORT_SYMBOL
+-0xd37d6496    hci_recv_fragment       vmlinux EXPORT_SYMBOL
+-0x1c86d31e    ip_tunnel_delete_net    vmlinux EXPORT_SYMBOL_GPL
+-0x9684e8c6    blk_queue_dma_drain     vmlinux EXPORT_SYMBOL_GPL
+-0xf89e28e9    config_item_set_name    vmlinux EXPORT_SYMBOL
+-0x9d8331c0    ring_buffer_read_page   vmlinux EXPORT_SYMBOL_GPL
+-0x572d0104    _raw_write_unlock_irqrestore    vmlinux EXPORT_SYMBOL
+-0x8e7894bd    __atomic_notifier_call_chain    vmlinux EXPORT_SYMBOL_GPL
+-0xb202dbc6    i2c_del_driver  vmlinux EXPORT_SYMBOL
+-0x057ce975    hex_dump_to_buffer      vmlinux EXPORT_SYMBOL
+-0xe09f5fdd    file_ra_state_init      vmlinux EXPORT_SYMBOL_GPL
+-0x011c93d4    v4l2_m2m_reqbufs        vmlinux EXPORT_SYMBOL_GPL
+-0x5b185975    __dma_request_channel   vmlinux EXPORT_SYMBOL_GPL
+-0xe02299ef    nfc_hci_send_response   vmlinux EXPORT_SYMBOL
+-0xe8beb828    crypto_larval_kill      vmlinux EXPORT_SYMBOL_GPL
+-0x8704eb06    irq_set_default_host    vmlinux EXPORT_SYMBOL_GPL
+-0x7ac1d551    vb2_prepare_buf vmlinux EXPORT_SYMBOL_GPL
+-0xfcab3072    media_entity_cleanup    vmlinux EXPORT_SYMBOL_GPL
+-0x75d69d69    usb_alloc_coherent      vmlinux EXPORT_SYMBOL_GPL
+-0x2f3857a0    xfrm_register_mode      vmlinux EXPORT_SYMBOL
+-0x09c1fbfd    inet_csk_get_port       vmlinux EXPORT_SYMBOL_GPL
+-0x1e6fd62f    kiocb_set_cancel_fn     vmlinux EXPORT_SYMBOL
+-0xb20a8d04    mmc_flush_cache vmlinux EXPORT_SYMBOL
+-0xb321b21c    i2c_clients_command     vmlinux EXPORT_SYMBOL
+-0xd77c0bc8    klist_remove    vmlinux EXPORT_SYMBOL_GPL
+-0x8cfe5489    dev_get_flags   vmlinux EXPORT_SYMBOL
+-0x8022b19a    crypto_sha256_update    vmlinux EXPORT_SYMBOL
+-0x0adfab73    __wait_on_bit_lock      vmlinux EXPORT_SYMBOL
+-0x4a169d0b    usb_get_status  vmlinux EXPORT_SYMBOL_GPL
+-0xe5122890    flow_cache_genid        vmlinux EXPORT_SYMBOL
+-0x31cef011    gen_new_estimator       vmlinux EXPORT_SYMBOL
+-0xbb6bebbd    crypto_alg_mod_lookup   vmlinux EXPORT_SYMBOL_GPL
+-0xe208f5c9    freeze_super    vmlinux EXPORT_SYMBOL
+-0xbf5b2016    __devm_request_region   vmlinux EXPORT_SYMBOL
+-0x7cd6f042    cpufreq_get_current_driver      vmlinux EXPORT_SYMBOL_GPL
+-0x946f789a    input_class     vmlinux EXPORT_SYMBOL_GPL
+-0x33abb76e    usb_remove_function     vmlinux EXPORT_SYMBOL_GPL
+-0x54c41f03    __cfg80211_send_disassoc        vmlinux EXPORT_SYMBOL
+-0x886bcea3    hid_connect     vmlinux EXPORT_SYMBOL_GPL
+-0x1d4cf31c    mmc_set_data_timeout    vmlinux EXPORT_SYMBOL
+-0x020bb7c4    v4l2_m2m_qbuf   vmlinux EXPORT_SYMBOL_GPL
+-0xf5ef842e    v4l_bound_align_image   vmlinux EXPORT_SYMBOL_GPL
+-0x628c65bc    usb_set_device_state    vmlinux EXPORT_SYMBOL_GPL
+-0x1d182b56    scsi_autopm_get_device  vmlinux EXPORT_SYMBOL_GPL
+-0xa8b77259    scsi_autopm_put_device  vmlinux EXPORT_SYMBOL_GPL
+-0x2641488c    scsi_eh_finish_cmd      vmlinux EXPORT_SYMBOL
+-0x773650a0    vc_cons vmlinux EXPORT_SYMBOL
+-0x6d203b02    dma_async_device_unregister     vmlinux EXPORT_SYMBOL
+-0x18c2227f    cpu_rmap_update vmlinux EXPORT_SYMBOL
+-0xdd0a2ba2    strlcat vmlinux EXPORT_SYMBOL
+-0xd627480b    strncat vmlinux EXPORT_SYMBOL
+-0x0dd47f83    blk_queue_max_discard_sectors   vmlinux EXPORT_SYMBOL
+-0xb3f7646e    kthread_should_stop     vmlinux EXPORT_SYMBOL
+-0x8d335f49    mmc_can_reset   vmlinux EXPORT_SYMBOL
+-0x474576c2    v4l2_ctrl_new_std_menu  vmlinux EXPORT_SYMBOL
+-0x735d80ef    drm_add_edid_modes      vmlinux EXPORT_SYMBOL
+-0xbfdbe956    nfnetlink_set_err       vmlinux EXPORT_SYMBOL_GPL
+-0xc0891ac5    netdev_notice   vmlinux EXPORT_SYMBOL
+-0x03b5c8d0    blk_rq_map_kern vmlinux EXPORT_SYMBOL
+-0x20f6c302    sync_mapping_buffers    vmlinux EXPORT_SYMBOL
+-0x5610de90    pm_generic_freeze_noirq vmlinux EXPORT_SYMBOL_GPL
+-0x33186585    drm_prime_lookup_buf_handle     vmlinux EXPORT_SYMBOL
+-0x5c746654    bt_sock_register        vmlinux EXPORT_SYMBOL
+-0x1f2ca4fa    fat_scan        vmlinux EXPORT_SYMBOL_GPL
+-0x4ade2e74    inode_change_ok vmlinux EXPORT_SYMBOL
+-0x2b2264c1    __scsi_add_device       vmlinux EXPORT_SYMBOL
+-0x3a8903bb    datagram_poll   vmlinux EXPORT_SYMBOL
+-0x75767b6f    snd_pcm_hw_constraint_minmax    vmlinux EXPORT_SYMBOL
+-0xe623e6db    blk_queue_end_tag       vmlinux EXPORT_SYMBOL
+-0x1e9edfb7    seq_hlist_start_head_rcu        vmlinux EXPORT_SYMBOL
+-0x69d38ed9    __scsi_print_sense      vmlinux EXPORT_SYMBOL
+-0xc6de7303    __tty_alloc_driver      vmlinux EXPORT_SYMBOL
+-0xcdb5f930    __tcf_em_tree_match     vmlinux EXPORT_SYMBOL
+-0x7a0a2470    dev_uc_flush    vmlinux EXPORT_SYMBOL
+-0x6c8f0d30    dev_mc_flush    vmlinux EXPORT_SYMBOL
+-0x067d8d35    security_release_secctx vmlinux EXPORT_SYMBOL
+-0xb10e668e    jbd2_journal_check_available_features   vmlinux EXPORT_SYMBOL
+-0xe2e8ac87    flush_old_exec  vmlinux EXPORT_SYMBOL
+-0x00c4dc87    timecounter_init        vmlinux EXPORT_SYMBOL_GPL
+-0xeb793d66    media_device_register   vmlinux EXPORT_SYMBOL_GPL
+-0x694be42a    usb_show_dynids vmlinux EXPORT_SYMBOL_GPL
+-0xdf3ec432    drm_gem_object_alloc    vmlinux EXPORT_SYMBOL
+-0xa3d3ab7e    inet_addr_type  vmlinux EXPORT_SYMBOL
+-0x97a2e370    inet_recvmsg    vmlinux EXPORT_SYMBOL
+-0x0b59390b    __tracepoint_rpm_suspend        vmlinux EXPORT_SYMBOL_GPL
+-0xa4701e9e    timekeeping_inject_offset       vmlinux EXPORT_SYMBOL
+-0x1f54f1b4    do_trace_rcu_torture_read       vmlinux EXPORT_SYMBOL_GPL
+-0x6275fa23    mdiobus_unregister      vmlinux EXPORT_SYMBOL
+-0x639399b9    ump_dd_phys_block_count_get     vmlinux EXPORT_SYMBOL
+-0x6812cf8d    __tracepoint_rpm_idle   vmlinux EXPORT_SYMBOL_GPL
+-0xaa90f5bc    phy_detach      vmlinux EXPORT_SYMBOL
+-0x8ded75c5    mii_link_ok     vmlinux EXPORT_SYMBOL
+-0xa6dd4938    cfg80211_inform_bss_frame       vmlinux EXPORT_SYMBOL
+-0xd4cc3c98    bt_procfs_cleanup       vmlinux EXPORT_SYMBOL
+-0xd856b532    tcp_proc_register       vmlinux EXPORT_SYMBOL
+-0xb86a648c    nf_conntrack_l4proto_udp6       vmlinux EXPORT_SYMBOL_GPL
+-0x2c81ec75    __irq_regs      vmlinux EXPORT_SYMBOL
+-0x3f182756    generic_write_sync      vmlinux EXPORT_SYMBOL
+-0x48bd4a65    wakeup_source_remove    vmlinux EXPORT_SYMBOL_GPL
+-0x027c2c52    stop_tty        vmlinux EXPORT_SYMBOL
+-0xc18578ed    process_srcu    vmlinux EXPORT_SYMBOL_GPL
+-0xf3cf07b0    sdio_writel     vmlinux EXPORT_SYMBOL_GPL
+-0x9b54326d    xfrm_policy_destroy     vmlinux EXPORT_SYMBOL
+-0x667cc3f3    inet_del_offload        vmlinux EXPORT_SYMBOL
+-0xbc9cfb6e    jbd2_journal_stop       vmlinux EXPORT_SYMBOL
+-0x43aec82a    sdhci_pltfm_register    vmlinux EXPORT_SYMBOL_GPL
+-0x1db8867b    sdio_memcpy_toio        vmlinux EXPORT_SYMBOL_GPL
+-0x48499aa5    neigh_ifdown    vmlinux EXPORT_SYMBOL
+-0x4b53ee2c    snd_pcm_hw_constraint_ratnums   vmlinux EXPORT_SYMBOL
+-0x9650df0b    snd_ctl_replace vmlinux EXPORT_SYMBOL
+-0x6c1ce5ce    strcspn vmlinux EXPORT_SYMBOL
+-0xa68698f6    jbd2_journal_extend     vmlinux EXPORT_SYMBOL
+-0x7eb6d1eb    thermal_zone_unbind_cooling_device      vmlinux EXPORT_SYMBOL_GPL
+-0x81328587    blkdev_aio_write        vmlinux EXPORT_SYMBOL_GPL
+-0xf8bec8e3    seq_bitmap_list vmlinux EXPORT_SYMBOL
+-0xaec655c7    alloc_pages_exact       vmlinux EXPORT_SYMBOL
+-0x6ce5ade9    hid_parse_report        vmlinux EXPORT_SYMBOL_GPL
+-0x66f7b07e    ehci_resume     vmlinux EXPORT_SYMBOL_GPL
+-0x95c578a0    ioremap_page_range      vmlinux EXPORT_SYMBOL_GPL
+-0x498dcb5e    drm_ut_debug_printk     vmlinux EXPORT_SYMBOL
+-0x6c1f6c7e    drm_rmmap       vmlinux EXPORT_SYMBOL
+-0x8b55de97    devm_regulator_bulk_get vmlinux EXPORT_SYMBOL_GPL
+-0x8190aef3    register_sound_special  vmlinux EXPORT_SYMBOL
+-0x6c255d20    __nla_reserve   vmlinux EXPORT_SYMBOL
+-0x29537c9e    alloc_chrdev_region     vmlinux EXPORT_SYMBOL
+-0x05273827    inc_zone_page_state     vmlinux EXPORT_SYMBOL
+-0xc665d6d7    of_parse_phandle_with_args      vmlinux EXPORT_SYMBOL
+-0x01f7b595    usbnet_skb_return       vmlinux EXPORT_SYMBOL_GPL
+-0x0740687f    arp_find        vmlinux EXPORT_SYMBOL
+-0x269fbd1b    nf_ct_iterate_cleanup   vmlinux EXPORT_SYMBOL_GPL
+-0x22ce6bb8    skb_checksum    vmlinux EXPORT_SYMBOL
+-0x669f1bc1    kfree_skb_list  vmlinux EXPORT_SYMBOL
+-0xca9360b5    rb_next vmlinux EXPORT_SYMBOL
+-0x3c010e48    inode_permission        vmlinux EXPORT_SYMBOL
+-0xba34ed58    buffer_migrate_page     vmlinux EXPORT_SYMBOL
+-0x1cfb04fa    finish_wait     vmlinux EXPORT_SYMBOL
+-0xcb0b79fb    max8997_read_reg        vmlinux EXPORT_SYMBOL_GPL
+-0x564f1dca    klist_add_after vmlinux EXPORT_SYMBOL_GPL
+-0x4cbbd171    __bitmap_weight vmlinux EXPORT_SYMBOL
+-0x61b7b126    simple_strtoull vmlinux EXPORT_SYMBOL
+-0x528c709d    simple_read_from_buffer vmlinux EXPORT_SYMBOL
+-0x10c9d678    irq_domain_simple_ops   vmlinux EXPORT_SYMBOL_GPL
+-0x5d8d802b    clockevent_delta2ns     vmlinux EXPORT_SYMBOL_GPL
+-0xe8731295    gether_get_ifname       vmlinux EXPORT_SYMBOL
+-0x8619c1c9    phy_start_aneg  vmlinux EXPORT_SYMBOL
+-0x2a1c0adc    scsi_print_result       vmlinux EXPORT_SYMBOL
+-0x6eb85693    nf_defrag_ipv6_enable   vmlinux EXPORT_SYMBOL_GPL
+-0x6b6c3d10    nf_defrag_ipv4_enable   vmlinux EXPORT_SYMBOL_GPL
+-0xa681fe88    generate_random_uuid    vmlinux EXPORT_SYMBOL
+-0x3147857d    default_red     vmlinux EXPORT_SYMBOL
+-0xff9ca065    fb_edid_to_monspecs     vmlinux EXPORT_SYMBOL
+-0x22e14acd    gpiochip_add_pin_range  vmlinux EXPORT_SYMBOL_GPL
+-0xad1bb027    nf_ct_free_hashtable    vmlinux EXPORT_SYMBOL_GPL
+-0xaf509095    get_net_ns_by_pid       vmlinux EXPORT_SYMBOL_GPL
+-0xcff75292    vfs_statfs      vmlinux EXPORT_SYMBOL
+-0x2756ceb6    mmc_power_save_host     vmlinux EXPORT_SYMBOL
+-0x438610bd    security_tun_dev_alloc_security vmlinux EXPORT_SYMBOL
+-0xb1d9068c    ip6_datagram_send_ctl   vmlinux EXPORT_SYMBOL_GPL
+-0x365c213d    udp_ioctl       vmlinux EXPORT_SYMBOL
+-0x53877b9f    __nla_reserve_nohdr     vmlinux EXPORT_SYMBOL
+-0xd64146c4    __get_page_tail vmlinux EXPORT_SYMBOL
+-0x9b1bc5fa    i2c_new_probed_device   vmlinux EXPORT_SYMBOL_GPL
+-0x3c787bd5    rtnetlink_put_metrics   vmlinux EXPORT_SYMBOL
+-0xcb5c97f9    blk_queue_max_write_same_sectors        vmlinux EXPORT_SYMBOL
+-0x3b909e7e    may_umount      vmlinux EXPORT_SYMBOL
+-0x0c8099b1    v4l2_spi_new_subdev     vmlinux EXPORT_SYMBOL_GPL
+-0xd00b0085    v4l2_ctrl_handler_setup vmlinux EXPORT_SYMBOL
+-0xea10212a    int_to_scsilun  vmlinux EXPORT_SYMBOL
+-0xcb0944d8    pwm_set_chip_data       vmlinux EXPORT_SYMBOL_GPL
+-0xde5846c4    pwm_get_chip_data       vmlinux EXPORT_SYMBOL_GPL
+-0x915917a3    block_read_full_page    vmlinux EXPORT_SYMBOL
+-0xe5d61b91    console_drivers vmlinux EXPORT_SYMBOL_GPL
+-0xb776298b    iommu_detach_device     vmlinux EXPORT_SYMBOL_GPL
+-0xeb711ae7    snd_soc_params_to_bclk  vmlinux EXPORT_SYMBOL_GPL
+-0x90ed601f    mmc_hw_reset    vmlinux EXPORT_SYMBOL
+-0x1cbd340b    cdc_ncm_unbind  vmlinux EXPORT_SYMBOL_GPL
+-0x9caab5b6    __scsi_alloc_queue      vmlinux EXPORT_SYMBOL
+-0x2506e85a    bus_sort_breadthfirst   vmlinux EXPORT_SYMBOL_GPL
+-0xd6769f27    ipt_alloc_initial_table vmlinux EXPORT_SYMBOL_GPL
+-0x439fe23e    tcp_v4_connect  vmlinux EXPORT_SYMBOL
+-0x02de3eaf    tcp_sync_mss    vmlinux EXPORT_SYMBOL
+-0x4be85a03    memweight       vmlinux EXPORT_SYMBOL
+-0x93021b18    jbd2_journal_ack_err    vmlinux EXPORT_SYMBOL
+-0xd0c05159    emergency_restart       vmlinux EXPORT_SYMBOL_GPL
+-0x3ff62317    local_bh_disable        vmlinux EXPORT_SYMBOL
+-0xd88781bd    regmap_raw_write        vmlinux EXPORT_SYMBOL_GPL
+-0xada38534    regulator_bulk_disable  vmlinux EXPORT_SYMBOL_GPL
+-0x2ad4daf6    tcp_death_row   vmlinux EXPORT_SYMBOL_GPL
+-0x87751cba    netdev_upper_dev_link   vmlinux EXPORT_SYMBOL
+-0xe187693c    kstrtouint_from_user    vmlinux EXPORT_SYMBOL
+-0xbe797e8f    bio_get_nr_vecs vmlinux EXPORT_SYMBOL
+-0x2373352a    clk_fixed_factor_ops    vmlinux EXPORT_SYMBOL_GPL
+-0xccbee9bd    mmc_set_blockcount      vmlinux EXPORT_SYMBOL
+-0x9ebb3718    v4l2_clk_unregister     vmlinux EXPORT_SYMBOL
+-0xe28ade94    serio_rescan    vmlinux EXPORT_SYMBOL
+-0x1b5c713f    drm_send_vblank_event   vmlinux EXPORT_SYMBOL
+-0xa257d9cd    framebuffer_alloc       vmlinux EXPORT_SYMBOL
+-0x0916cc54    xfrm_policy_byid        vmlinux EXPORT_SYMBOL
+-0x07319ef1    ahash_register_instance vmlinux EXPORT_SYMBOL_GPL
+-0x11c55999    load_nls_default        vmlinux EXPORT_SYMBOL
+-0xcae08d66    nonseekable_open        vmlinux EXPORT_SYMBOL
+-0x3651150d    kmem_cache_create       vmlinux EXPORT_SYMBOL
+-0xfd26424e    cpufreq_driver_target   vmlinux EXPORT_SYMBOL_GPL
+-0x66adff69    vb2_fop_read    vmlinux EXPORT_SYMBOL_GPL
+-0x09a5b743    amba_apb_device_add     vmlinux EXPORT_SYMBOL_GPL
+-0x475100c2    inet_get_local_port_range       vmlinux EXPORT_SYMBOL
+-0x8c1e0ffe    __seq_open_private      vmlinux EXPORT_SYMBOL
+-0xd60c8ab0    seq_escape      vmlinux EXPORT_SYMBOL
+-0xc81ec7cb    phy_get_eee_err vmlinux EXPORT_SYMBOL
+-0x00778770    xfrm_ealg_get_byname    vmlinux EXPORT_SYMBOL_GPL
+-0x5bc722fb    sock_alloc_file vmlinux EXPORT_SYMBOL
+-0xddf821b8    page_address    vmlinux EXPORT_SYMBOL
+-0x9771ccf0    of_mdiobus_register     vmlinux EXPORT_SYMBOL
+-0x5eb24829    dm_shift_arg    vmlinux EXPORT_SYMBOL
+-0x119e8920    v4l2_async_unregister_subdev    vmlinux EXPORT_SYMBOL
+-0x7bc3e7c1    xfrm_lookup     vmlinux EXPORT_SYMBOL
+-0xae0410db    skb_store_bits  vmlinux EXPORT_SYMBOL
+-0xf86deaaa    page_cache_sync_readahead       vmlinux EXPORT_SYMBOL_GPL
+-0x7681946c    unregister_pm_notifier  vmlinux EXPORT_SYMBOL_GPL
+-0x3d98d961    inet_unregister_protosw vmlinux EXPORT_SYMBOL
+-0x82108639    snd_soc_get_volsw       vmlinux EXPORT_SYMBOL_GPL
+-0x286d040c    snd_soc_put_volsw       vmlinux EXPORT_SYMBOL_GPL
+-0x371c0db7    blk_queue_bypass_end    vmlinux EXPORT_SYMBOL_GPL
+-0x8589f760    mb_cache_entry_free     vmlinux EXPORT_SYMBOL
+-0x87a795d4    i2c_probe_func_quick_read       vmlinux EXPORT_SYMBOL_GPL
+-0xb05661a7    i2c_smbus_read_byte     vmlinux EXPORT_SYMBOL
+-0x167977e6    platform_create_bundle  vmlinux EXPORT_SYMBOL_GPL
+-0xb626c977    _dev_info       vmlinux EXPORT_SYMBOL
+-0x0d5db696    arm_iommu_detach_device vmlinux EXPORT_SYMBOL_GPL
+-0x001f6379    blkcipher_walk_phys     vmlinux EXPORT_SYMBOL_GPL
+-0x3dfc897c    seq_hlist_start_head    vmlinux EXPORT_SYMBOL
+-0xc34ff0bb    clocksource_change_rating       vmlinux EXPORT_SYMBOL
+-0x5ace7e88    devres_for_each_res     vmlinux EXPORT_SYMBOL_GPL
+-0xd4390384    __ieee80211_get_channel vmlinux EXPORT_SYMBOL
+-0xe55e04a1    ip6_tnl_rcv_ctl vmlinux EXPORT_SYMBOL_GPL
+-0xa389a49a    profile_event_register  vmlinux EXPORT_SYMBOL_GPL
+-0x5ef37944    sdio_set_block_size     vmlinux EXPORT_SYMBOL_GPL
+-0x9924c496    __usb_get_extra_descriptor      vmlinux EXPORT_SYMBOL_GPL
+-0xcfa57ce1    __nf_conntrack_helper_find      vmlinux EXPORT_SYMBOL_GPL
+-0x5460c8d8    fsnotify_get_cookie     vmlinux EXPORT_SYMBOL_GPL
+-0xf5f58a7b    gether_register_netdev  vmlinux EXPORT_SYMBOL
+-0xe774e9e4    register_netdevice      vmlinux EXPORT_SYMBOL
+-0x9209f545    blkdev_put      vmlinux EXPORT_SYMBOL
+-0x6a1c9c55    blkdev_get      vmlinux EXPORT_SYMBOL
+-0x4d0cbb95    finish_no_open  vmlinux EXPORT_SYMBOL
+-0xa1ef69b9    unregister_ftrace_event vmlinux EXPORT_SYMBOL_GPL
+-0x09d6a08d    v4l2_device_disconnect  vmlinux EXPORT_SYMBOL_GPL
+-0x613a7741    scsi_finish_command     vmlinux EXPORT_SYMBOL
+-0x11f447ce    __gpio_to_irq   vmlinux EXPORT_SYMBOL_GPL
+-0xb8a9ab06    hci_unregister_cb       vmlinux EXPORT_SYMBOL
+-0xca0741ee    nf_nat_l4proto_register vmlinux EXPORT_SYMBOL_GPL
+-0x70f09a3d    nf_nat_l3proto_register vmlinux EXPORT_SYMBOL_GPL
+-0x10447797    build_skb       vmlinux EXPORT_SYMBOL
+-0xf2b1ac8e    __getnstimeofday        vmlinux EXPORT_SYMBOL
+-0x8923ab21    get_tz_trend    vmlinux EXPORT_SYMBOL
+-0x450e1fb7    gs_alloc_req    vmlinux EXPORT_SYMBOL_GPL
+-0x176df204    tcp_get_info    vmlinux EXPORT_SYMBOL_GPL
+-0x4c2a5480    __alloc_skb     vmlinux EXPORT_SYMBOL
+-0x90814050    snd_soc_cache_write     vmlinux EXPORT_SYMBOL_GPL
+-0xa4ba4393    snd_soc_dai_set_fmt     vmlinux EXPORT_SYMBOL_GPL
+-0x2d98d3e7    jbd2_journal_begin_ordered_truncate     vmlinux EXPORT_SYMBOL
+-0x5b79185b    jbd2_trans_will_send_data_barrier       vmlinux EXPORT_SYMBOL
+-0xc200914d    mutex_trylock   vmlinux EXPORT_SYMBOL
+-0xe24d3a97    jiffies_64      vmlinux EXPORT_SYMBOL
+-0x7eb7b3f8    of_get_dma_window       vmlinux EXPORT_SYMBOL_GPL
+-0xc5c9bb41    regmap_get_val_bytes    vmlinux EXPORT_SYMBOL_GPL
+-0x8226642f    __gpio_cansleep vmlinux EXPORT_SYMBOL_GPL
+-0x6def2db2    half_md4_transform      vmlinux EXPORT_SYMBOL
+-0xb835b3e4    radix_tree_prev_hole    vmlinux EXPORT_SYMBOL
+-0xbed06655    dcache_readdir  vmlinux EXPORT_SYMBOL
+-0x980c6433    inode_add_bytes vmlinux EXPORT_SYMBOL
+-0xdc092d5b    thaw_super      vmlinux EXPORT_SYMBOL
+-0x1ef192c5    generic_file_mmap       vmlinux EXPORT_SYMBOL
+-0x9075cea3    abort_creds     vmlinux EXPORT_SYMBOL
+-0x4ef8e23f    led_set_brightness      vmlinux EXPORT_SYMBOL
+-0x48a5b067    __machine_arch_type     vmlinux EXPORT_SYMBOL
+-0x4188d439    neigh_rand_reach_time   vmlinux EXPORT_SYMBOL
+-0x7eef21b4    dev_forward_skb vmlinux EXPORT_SYMBOL_GPL
+-0x5825f0e7    sock_common_getsockopt  vmlinux EXPORT_SYMBOL
+-0x2de67218    sock_common_setsockopt  vmlinux EXPORT_SYMBOL
+-0x65408378    zlib_inflate_blob       vmlinux EXPORT_SYMBOL
+-0xc6d9568b    try_to_writeback_inodes_sb      vmlinux EXPORT_SYMBOL
+-0x5ad87de6    vfs_mknod       vmlinux EXPORT_SYMBOL
+-0x6f5c943e    rndis_add_hdr   vmlinux EXPORT_SYMBOL
+-0x6a91e934    drm_mode_create_dvi_i_properties        vmlinux EXPORT_SYMBOL
+-0x3eb37b9d    drm_ht_create   vmlinux EXPORT_SYMBOL
+-0xcdf8626d    n_tty_inherit_ops       vmlinux EXPORT_SYMBOL_GPL
+-0x65d6d0f0    gpio_direction_input    vmlinux EXPORT_SYMBOL_GPL
+-0x74acd28a    nfc_hci_set_clientdata  vmlinux EXPORT_SYMBOL
+-0x6c6a3e69    nfc_hci_get_clientdata  vmlinux EXPORT_SYMBOL
+-0x8e235e9b    cfg80211_disconnected   vmlinux EXPORT_SYMBOL
+-0x2d6b040a    cfg80211_send_rx_auth   vmlinux EXPORT_SYMBOL
+-0x987f5e85    skb_dequeue     vmlinux EXPORT_SYMBOL
+-0x413461c0    filemap_write_and_wait  vmlinux EXPORT_SYMBOL
+-0x27bbf221    disable_irq_nosync      vmlinux EXPORT_SYMBOL
+-0x00000000    softirq_work_list       vmlinux EXPORT_SYMBOL
+-0x8c298b56    vb2_ioctl_querybuf      vmlinux EXPORT_SYMBOL_GPL
+-0x94d7075a    usb_gadget_get_string   vmlinux EXPORT_SYMBOL_GPL
+-0x19ef30a6    usbnet_manage_power     vmlinux EXPORT_SYMBOL
+-0x967e7ec8    inet_rtx_syn_ack        vmlinux EXPORT_SYMBOL
+-0x9b9e05f9    alloc_cpu_rmap  vmlinux EXPORT_SYMBOL
+-0xa7f92105    add_uevent_var  vmlinux EXPORT_SYMBOL_GPL
+-0x6e6c5939    dma_buf_kunmap_atomic   vmlinux EXPORT_SYMBOL_GPL
+-0x3723eb08    __pm_relax      vmlinux EXPORT_SYMBOL_GPL
+-0x1ae74b3a    drm_framebuffer_unregister_private      vmlinux EXPORT_SYMBOL
+-0xf7584a9c    find_font       vmlinux EXPORT_SYMBOL
+-0x88e316d7    netdev_features_change  vmlinux EXPORT_SYMBOL
+-0xf19e9355    cpu_online_mask vmlinux EXPORT_SYMBOL
+-0xaa8195e9    media_entity_remote_pad vmlinux EXPORT_SYMBOL_GPL
+-0x19ec698c    platform_get_resource_byname    vmlinux EXPORT_SYMBOL_GPL
+-0x62813e5c    nf_ct_port_nlattr_tuple_size    vmlinux EXPORT_SYMBOL_GPL
+-0x4ff4a58a    nfnetlink_alloc_skb     vmlinux EXPORT_SYMBOL_GPL
+-0xeed3635b    proc_dostring   vmlinux EXPORT_SYMBOL
+-0xb54533f7    usecs_to_jiffies        vmlinux EXPORT_SYMBOL
+-0x0b56117f    of_find_node_by_path    vmlinux EXPORT_SYMBOL
+-0xcc4b84da    of_find_node_by_type    vmlinux EXPORT_SYMBOL
+-0xf9fd4da3    phy_start       vmlinux EXPORT_SYMBOL
+-0x5ea42ad5    devres_find     vmlinux EXPORT_SYMBOL_GPL
+-0x598a2261    drm_mode_probed_add     vmlinux EXPORT_SYMBOL
+-0xc35b2a18    xt_hook_link    vmlinux EXPORT_SYMBOL_GPL
+-0xc1c24fbc    genlmsg_put     vmlinux EXPORT_SYMBOL
+-0xf177aba7    sysfs_schedule_callback vmlinux EXPORT_SYMBOL_GPL
+-0xabcaa577    free_anon_bdev  vmlinux EXPORT_SYMBOL
+-0x6d289788    pwm_set_polarity        vmlinux EXPORT_SYMBOL_GPL
+-0x2546de76    raw_hash_sk     vmlinux EXPORT_SYMBOL_GPL
+-0xa2ef34d7    rps_sock_flow_table     vmlinux EXPORT_SYMBOL
+-0x3730910b    skb_insert      vmlinux EXPORT_SYMBOL
+-0xb8b7395a    snd_compress_new        vmlinux EXPORT_SYMBOL_GPL
+-0x1c132024    request_any_context_irq vmlinux EXPORT_SYMBOL_GPL
+-0x5aba52ab    iio_trigger_poll        vmlinux EXPORT_SYMBOL
+-0xe9b6f3f3    dev_emerg       vmlinux EXPORT_SYMBOL
+-0xfacd2e14    pgprot_user     vmlinux EXPORT_SYMBOL
+-0x0a0786de    udplite_table   vmlinux EXPORT_SYMBOL
+-0xd9bbcf52    tc_classify_compat      vmlinux EXPORT_SYMBOL
+-0x72f15b74    blk_queue_max_segment_size      vmlinux EXPORT_SYMBOL
+-0x544aab61    klist_add_tail  vmlinux EXPORT_SYMBOL_GPL
+-0x490434ad    dev_kfree_skb_irq       vmlinux EXPORT_SYMBOL
+-0xdb3a9b04    jbd2_journal_file_inode vmlinux EXPORT_SYMBOL
+-0x6e9dd606    __symbol_put    vmlinux EXPORT_SYMBOL
+-0x40a2d1dd    dm_table_get_size       vmlinux EXPORT_SYMBOL
+-0xceee316a    gether_set_host_addr    vmlinux EXPORT_SYMBOL
+-0x32f81723    gether_get_host_addr    vmlinux EXPORT_SYMBOL
+-0xae387af1    usb_gadget_unmap_request        vmlinux EXPORT_SYMBOL_GPL
+-0x8dfb019d    drm_buffer_free vmlinux EXPORT_SYMBOL
+-0x600683d3    do_unblank_screen       vmlinux EXPORT_SYMBOL
+-0xc1ebf6fe    get_kernel_page vmlinux EXPORT_SYMBOL_GPL
+-0x9b388444    get_zeroed_page vmlinux EXPORT_SYMBOL
+-0x53b69429    vb2_streamon    vmlinux EXPORT_SYMBOL_GPL
+-0x211aedde    genphy_restart_aneg     vmlinux EXPORT_SYMBOL
+-0xebdba37a    ndo_dflt_fdb_dump       vmlinux EXPORT_SYMBOL
+-0x604ef7b4    snd_pcm_lib_read        vmlinux EXPORT_SYMBOL
+-0x60541cbf    st_sensors_set_odr      vmlinux EXPORT_SYMBOL
+-0xe53d1faa    of_translate_dma_address        vmlinux EXPORT_SYMBOL
+-0xaf05b91b    of_device_is_available  vmlinux EXPORT_SYMBOL
+-0x1a426d0c    input_close_device      vmlinux EXPORT_SYMBOL
+-0xe720411b    rtnl_create_link        vmlinux EXPORT_SYMBOL
+-0x650f8603    snd_pcm_format_silence_64       vmlinux EXPORT_SYMBOL
+-0x7164c04b    address_space_init_once vmlinux EXPORT_SYMBOL
+-0xfda0dbe8    ftrace_print_hex_seq    vmlinux EXPORT_SYMBOL
+-0x2c988955    prepare_to_wait_exclusive       vmlinux EXPORT_SYMBOL
+-0x9c3206d8    v4l2_device_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0xd5c2bed3    phy_connect_direct      vmlinux EXPORT_SYMBOL
+-0xed2b0677    drm_mode_connector_update_edid_property vmlinux EXPORT_SYMBOL
+-0xbf17b32e    tty_insert_flip_string_flags    vmlinux EXPORT_SYMBOL
+-0xadc9ed27    bt_sock_ioctl   vmlinux EXPORT_SYMBOL
+-0x33ea8640    inet_dev_addr_type      vmlinux EXPORT_SYMBOL
+-0xd265ad57    tcf_action_exec vmlinux EXPORT_SYMBOL
+-0xec8d9205    snd_soc_register_codec  vmlinux EXPORT_SYMBOL_GPL
+-0x5e8ff943    debugfs_create_size_t   vmlinux EXPORT_SYMBOL_GPL
+-0x5b968338    remove_proc_entry       vmlinux EXPORT_SYMBOL
+-0x4717eaaf    platform_device_add     vmlinux EXPORT_SYMBOL_GPL
+-0x44a0c113    drm_mode_height vmlinux EXPORT_SYMBOL
+-0xe219d715    ipv6_opt_accepted       vmlinux EXPORT_SYMBOL_GPL
+-0x503ed988    xfrm_spd_getinfo        vmlinux EXPORT_SYMBOL
+-0x1fd1fabe    arpt_register_table     vmlinux EXPORT_SYMBOL
+-0xf9ed2e31    block_is_partially_uptodate     vmlinux EXPORT_SYMBOL
+-0xd9ecb670    ring_buffer_overruns    vmlinux EXPORT_SYMBOL_GPL
+-0x5e911cf3    exynos_g2d_exec_ioctl   vmlinux EXPORT_SYMBOL_GPL
+-0xbf69cda1    drm_connector_unplug_all        vmlinux EXPORT_SYMBOL
+-0xafe3eb1b    alloc_etherdev_mqs      vmlinux EXPORT_SYMBOL
+-0x39bf9301    _snd_pcm_hw_param_setempty      vmlinux EXPORT_SYMBOL
+-0xd81836ce    uart_resume_port        vmlinux EXPORT_SYMBOL
+-0x46931864    nfc_tm_data_received    vmlinux EXPORT_SYMBOL
+-0xfac8865f    sysctl_wmem_max vmlinux EXPORT_SYMBOL
+-0xb05fc310    sysctl_rmem_max vmlinux EXPORT_SYMBOL
+-0xe9b673fa    dapm_mark_io_dirty      vmlinux EXPORT_SYMBOL_GPL
+-0xbf0046d7    ahash_free_instance     vmlinux EXPORT_SYMBOL_GPL
+-0x825a0923    jbd2_journal_errno      vmlinux EXPORT_SYMBOL
+-0x03cb2c1a    bdi_register_dev        vmlinux EXPORT_SYMBOL
+-0x018f7433    pm_relax        vmlinux EXPORT_SYMBOL_GPL
+-0x63e0cc67    pagecache_write_end     vmlinux EXPORT_SYMBOL
+-0x8a04b9fe    tracepoint_iter_reset   vmlinux EXPORT_SYMBOL_GPL
+-0x5cf53ce2    input_free_minor        vmlinux EXPORT_SYMBOL
+-0x17bfef6c    drm_clflush_pages       vmlinux EXPORT_SYMBOL
+-0x5f14861d    pwm_get vmlinux EXPORT_SYMBOL_GPL
+-0xb8a5d4ee    cfg80211_ft_event       vmlinux EXPORT_SYMBOL
+-0xb9da2997    snmp_fold_field64       vmlinux EXPORT_SYMBOL_GPL
+-0x87925ca6    kstrtoint_from_user     vmlinux EXPORT_SYMBOL
+-0x6e891ea0    clk_unprepare   vmlinux EXPORT_SYMBOL_GPL
+-0x3d41904f    of_get_next_child       vmlinux EXPORT_SYMBOL
+-0x687835e7    hidinput_get_led_field  vmlinux EXPORT_SYMBOL_GPL
+-0x36859243    hid_resolv_usage        vmlinux EXPORT_SYMBOL_GPL
+-0x995dedd6    sdio_f0_readb   vmlinux EXPORT_SYMBOL_GPL
+-0x19f5809b    dm_ratelimit_state      vmlinux EXPORT_SYMBOL
+-0xe684f045    v4l2_subdev_try_ext_ctrls       vmlinux EXPORT_SYMBOL
+-0x41f62b69    spi_register_master     vmlinux EXPORT_SYMBOL_GPL
+-0x49428bcb    drm_read        vmlinux EXPORT_SYMBOL
+-0xb12cbacb    fb_unregister_client    vmlinux EXPORT_SYMBOL
+-0x7c53b814    xfrm_inner_extract_output       vmlinux EXPORT_SYMBOL_GPL
+-0x86dd59c8    inet_csk_init_xmit_timers       vmlinux EXPORT_SYMBOL
+-0x51e297e3    __nf_ct_l4proto_find    vmlinux EXPORT_SYMBOL_GPL
+-0x1b52db1c    probe_kernel_read       vmlinux EXPORT_SYMBOL_GPL
+-0xd4e65e28    irq_set_chip_and_handler_name   vmlinux EXPORT_SYMBOL_GPL
+-0x9c7a3b79    drm_fb_helper_debug_enter       vmlinux EXPORT_SYMBOL
+-0xc25d1133    vfs_readlink    vmlinux EXPORT_SYMBOL
+-0x7e9efe8e    complete_and_exit       vmlinux EXPORT_SYMBOL
+-0xd8d64478    v4l2_ctrl_new_std_menu_items    vmlinux EXPORT_SYMBOL
+-0xb6652875    gserial_free_line       vmlinux EXPORT_SYMBOL_GPL
+-0xd4adf602    dev_pm_get_subsys_data  vmlinux EXPORT_SYMBOL_GPL
+-0x1f335345    dev_pm_put_subsys_data  vmlinux EXPORT_SYMBOL_GPL
+-0x30399f8a    transport_add_device    vmlinux EXPORT_SYMBOL_GPL
+-0x44c2d1be    drm_mode_prune_invalid  vmlinux EXPORT_SYMBOL
+-0x3e9d6f44    cfg80211_unregister_wdev        vmlinux EXPORT_SYMBOL
+-0xfb5bb3ee    inet6_lookup    vmlinux EXPORT_SYMBOL_GPL
+-0x535cfa1f    sysfs_remove_group      vmlinux EXPORT_SYMBOL_GPL
+-0x795b1ab0    sysfs_remove_file_from_group    vmlinux EXPORT_SYMBOL_GPL
+-0x9aca444b    get_monotonic_boottime  vmlinux EXPORT_SYMBOL_GPL
+-0x91aec064    down_read_trylock       vmlinux EXPORT_SYMBOL
+-0x87e148ee    v4l2_m2m_poll   vmlinux EXPORT_SYMBOL_GPL
+-0xfcb34391    scsi_execute_req_flags  vmlinux EXPORT_SYMBOL
+-0x19391863    regmap_reinit_cache     vmlinux EXPORT_SYMBOL_GPL
+-0xff6878cf    fb_default_cmap vmlinux EXPORT_SYMBOL
+-0x38524c14    cpufreq_register_driver vmlinux EXPORT_SYMBOL_GPL
+-0x4ca0e0e5    v4l2_ctrl_modify_range  vmlinux EXPORT_SYMBOL
+-0x4f6f28fb    serial8250_handle_irq   vmlinux EXPORT_SYMBOL_GPL
+-0x7b56a1b0    nf_nat_set_seq_adjust   vmlinux EXPORT_SYMBOL_GPL
+-0x63df94bc    nf_nat_tcp_seq_adjust   vmlinux EXPORT_SYMBOL_GPL
+-0x8ffb22a4    nf_setsockopt   vmlinux EXPORT_SYMBOL
+-0xefd0fb67    nf_getsockopt   vmlinux EXPORT_SYMBOL
+-0x579e0bf5    rtnl_unregister_all     vmlinux EXPORT_SYMBOL_GPL
+-0x87e5d976    netif_rx_ni     vmlinux EXPORT_SYMBOL
+-0xe27cea7b    alloc_disk      vmlinux EXPORT_SYMBOL
+-0x1f867001    blk_rq_map_user_iov     vmlinux EXPORT_SYMBOL
+-0xa3829135    ioc_lookup_icq  vmlinux EXPORT_SYMBOL
+-0xd2ce469a    seq_puts        vmlinux EXPORT_SYMBOL
+-0xf29942b3    seq_putc        vmlinux EXPORT_SYMBOL
+-0xf268be24    dw_mci_remove   vmlinux EXPORT_SYMBOL
+-0xb7ef4006    i2c_smbus_xfer  vmlinux EXPORT_SYMBOL
+-0xb8a16d46    dev_pm_qos_remove_notifier      vmlinux EXPORT_SYMBOL_GPL
+-0x37afc4f0    device_attach   vmlinux EXPORT_SYMBOL_GPL
+-0x581e8240    tty_port_open   vmlinux EXPORT_SYMBOL
+-0xa4583858    snd_pcm_hw_param_last   vmlinux EXPORT_SYMBOL
+-0x43497fcc    part_round_stats        vmlinux EXPORT_SYMBOL_GPL
+-0x0cd23659    d_genocide      vmlinux EXPORT_SYMBOL
+-0x328995b5    tracing_generic_entry_update    vmlinux EXPORT_SYMBOL_GPL
+-0xfe24d1c7    __module_put_and_exit   vmlinux EXPORT_SYMBOL
+-0x43a53735    __alloc_workqueue_key   vmlinux EXPORT_SYMBOL_GPL
+-0x2a902f32    usb_create_shared_hcd   vmlinux EXPORT_SYMBOL_GPL
+-0xdbdbb6e7    uart_update_timeout     vmlinux EXPORT_SYMBOL
+-0xf71617c1    cfg80211_report_obss_beacon     vmlinux EXPORT_SYMBOL
+-0x3e5d6dc3    snd_soc_put_value_enum_double   vmlinux EXPORT_SYMBOL_GPL
+-0xef67a6d3    snd_soc_get_value_enum_double   vmlinux EXPORT_SYMBOL_GPL
+-0x81b69e41    snd_ctl_enum_info       vmlinux EXPORT_SYMBOL
+-0xb2b94674    __crc32c_le     vmlinux EXPORT_SYMBOL
+-0xc61cc06d    elv_dispatch_add_tail   vmlinux EXPORT_SYMBOL
+-0x85e0bce2    end_buffer_write_sync   vmlinux EXPORT_SYMBOL
+-0x3cc671ae    d_drop  vmlinux EXPORT_SYMBOL
+-0x7469f641    d_rehash        vmlinux EXPORT_SYMBOL
+-0xddcebac8    file_open_root  vmlinux EXPORT_SYMBOL
+-0x310308c3    flush_kthread_work      vmlinux EXPORT_SYMBOL_GPL
+-0x40f07981    __ashldi3       vmlinux EXPORT_SYMBOL
+-0x88e83ca7    snd_soc_dpcm_be_set_state       vmlinux EXPORT_SYMBOL_GPL
+-0x5eca39b9    snd_soc_dpcm_be_get_state       vmlinux EXPORT_SYMBOL_GPL
+-0x6b1b67d3    __bdevname      vmlinux EXPORT_SYMBOL
+-0xe4315493    vfs_write       vmlinux EXPORT_SYMBOL
+-0x99fab0b8    __mmc_claim_host        vmlinux EXPORT_SYMBOL
+-0x2c8e9ced    usb_poison_urb  vmlinux EXPORT_SYMBOL_GPL
+-0x33a8a5f0    netif_rx        vmlinux EXPORT_SYMBOL
+-0x1d54bb24    snd_pcm_hw_refine       vmlinux EXPORT_SYMBOL
+-0x955b0e2e    kthread_worker_fn       vmlinux EXPORT_SYMBOL_GPL
+-0x276ad369    dm_set_device_limits    vmlinux EXPORT_SYMBOL_GPL
+-0x9e61f179    xfrm_stateonly_find     vmlinux EXPORT_SYMBOL
+-0x972bcca5    usb_create_hcd  vmlinux EXPORT_SYMBOL_GPL
+-0x72ea7b2d    scsi_device_type        vmlinux EXPORT_SYMBOL
+-0x318cadb1    reciprocal_value        vmlinux EXPORT_SYMBOL
+-0x22f77bec    unregister_binfmt       vmlinux EXPORT_SYMBOL
+-0xafceeb25    alloc_vm_area   vmlinux EXPORT_SYMBOL_GPL
+-0xcfe980c6    make_kgid       vmlinux EXPORT_SYMBOL
+-0xb71fb74f    _raw_read_trylock       vmlinux EXPORT_SYMBOL
+-0x9dadbb88    cpufreq_boost_supported vmlinux EXPORT_SYMBOL_GPL
+-0xab9e471e    usb_autopm_get_interface_no_resume      vmlinux EXPORT_SYMBOL_GPL
+-0x42453e50    sk_reset_txq    vmlinux EXPORT_SYMBOL
+-0x05d48045    sock_no_accept  vmlinux EXPORT_SYMBOL
+-0xb511dcf5    set_groups      vmlinux EXPORT_SYMBOL
+-0x5f0abc76    pinctrl_dev_get_devname vmlinux EXPORT_SYMBOL_GPL
+-0xec25f967    klist_del       vmlinux EXPORT_SYMBOL_GPL
+-0x530ed62b    tcf_generic_walker      vmlinux EXPORT_SYMBOL
+-0xacd392a0    sock_diag_register_inet_compat  vmlinux EXPORT_SYMBOL_GPL
+-0x2509c465    dev_remove_offload      vmlinux EXPORT_SYMBOL
+-0x8ee1a28d    elevator_exit   vmlinux EXPORT_SYMBOL
+-0xcd357308    __lock_buffer   vmlinux EXPORT_SYMBOL
+-0xd85139d2    mmc_unregister_driver   vmlinux EXPORT_SYMBOL
+-0xb53559bb    brcmu_pktq_pflush       drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0xbb0ab47b    debug_locks     vmlinux EXPORT_SYMBOL_GPL
+-0x56b2a97f    ablkcipher_walk_done    vmlinux EXPORT_SYMBOL_GPL
+-0xd3630b88    ablkcipher_walk_phys    vmlinux EXPORT_SYMBOL_GPL
+-0x3116987e    aead_geniv_alloc        vmlinux EXPORT_SYMBOL_GPL
+-0x20a789ac    irq_set_chip_data       vmlinux EXPORT_SYMBOL
+-0xeda65ce1    dma_release_declared_memory     vmlinux EXPORT_SYMBOL
+-0xa984aab8    cfg80211_scan_done      vmlinux EXPORT_SYMBOL
+-0x254c40cf    inet6_csk_xmit  vmlinux EXPORT_SYMBOL_GPL
+-0xca805e0b    tcp_ioctl       vmlinux EXPORT_SYMBOL
+-0x4ebc74b2    vfs_symlink     vmlinux EXPORT_SYMBOL
+-0xefcf3143    wait_for_completion_io  vmlinux EXPORT_SYMBOL
+-0xa9efcc8b    find_vpid       vmlinux EXPORT_SYMBOL_GPL
+-0xd273b1b1    __round_jiffies_up_relative     vmlinux EXPORT_SYMBOL_GPL
+-0xb8973764    iommu_attach_group      vmlinux EXPORT_SYMBOL_GPL
+-0x5d550c4d    scsi_sd_probe_domain    vmlinux EXPORT_SYMBOL
+-0x52f9bd8e    registered_fb   vmlinux EXPORT_SYMBOL
+-0xe67d81ba    strlen_user     vmlinux EXPORT_SYMBOL
+-0x480f1913    unmap_mapping_range     vmlinux EXPORT_SYMBOL
+-0x8b618d08    overflowuid     vmlinux EXPORT_SYMBOL
+-0x7171121c    overflowgid     vmlinux EXPORT_SYMBOL
+-0xb3514b24    cfg80211_radar_event    vmlinux EXPORT_SYMBOL
+-0xf06154af    inet_select_addr        vmlinux EXPORT_SYMBOL
+-0x340854b4    dev_getbyhwaddr_rcu     vmlinux EXPORT_SYMBOL
+-0x4ce033c8    skb_flow_dissect        vmlinux EXPORT_SYMBOL
+-0x465757c3    cpu_present_mask        vmlinux EXPORT_SYMBOL
+-0xb3a37086    dma_async_tx_descriptor_init    vmlinux EXPORT_SYMBOL
+-0x955eec37    wireless_send_event     vmlinux EXPORT_SYMBOL
+-0x7954e502    ipv6_recv_error vmlinux EXPORT_SYMBOL_GPL
+-0xcebcfddd    snd_soc_get_enum_double vmlinux EXPORT_SYMBOL_GPL
+-0x1c9728c6    snd_soc_put_enum_double vmlinux EXPORT_SYMBOL_GPL
+-0xb4711532    get_task_io_context     vmlinux EXPORT_SYMBOL
+-0x6cce08e5    dcache_dir_close        vmlinux EXPORT_SYMBOL
+-0x3e884f4b    vm_get_page_prot        vmlinux EXPORT_SYMBOL
+-0x20886a16    v4l2_subdev_g_ctrl      vmlinux EXPORT_SYMBOL
+-0xd56dcf8e    v4l2_subdev_s_ctrl      vmlinux EXPORT_SYMBOL
+-0x0465a073    regmap_reg_in_ranges    vmlinux EXPORT_SYMBOL_GPL
+-0x74bc0dea    extcon_register_interest        vmlinux EXPORT_SYMBOL_GPL
+-0x59c427c5    rtc_irq_set_state       vmlinux EXPORT_SYMBOL_GPL
+-0x3302f88f    phy_driver_register     vmlinux EXPORT_SYMBOL
+-0x848dd958    scsi_dma_unmap  vmlinux EXPORT_SYMBOL
+-0xfbc74f64    __copy_from_user        vmlinux EXPORT_SYMBOL
+-0xc9bb229b    inet_put_port   vmlinux EXPORT_SYMBOL
+-0x73ac2c51    nf_conntrack_register_notifier  vmlinux EXPORT_SYMBOL_GPL
+-0xbdca8444    sock_no_connect vmlinux EXPORT_SYMBOL
+-0xe85a9fd3    cpu_cluster_pm_exit     vmlinux EXPORT_SYMBOL_GPL
+-0xcb466063    wait_for_completion_killable_timeout    vmlinux EXPORT_SYMBOL
+-0x9205953f    send_remote_softirq     vmlinux EXPORT_SYMBOL
+-0x1852156d    phy_print_status        vmlinux EXPORT_SYMBOL
+-0x486517f6    pinctrl_select_state    vmlinux EXPORT_SYMBOL_GPL
+-0xfec26b4f    skcipher_geniv_alloc    vmlinux EXPORT_SYMBOL_GPL
+-0x24094dc0    xfrm_garbage_collect    vmlinux EXPORT_SYMBOL
+-0x6e224a7a    need_conntrack  vmlinux EXPORT_SYMBOL_GPL
+-0x4a358252    __bitmap_subset vmlinux EXPORT_SYMBOL
+-0x785d8ef0    ftrace_raw_output_prep  vmlinux EXPORT_SYMBOL
+-0x697c5d0d    tracing_snapshot_alloc  vmlinux EXPORT_SYMBOL_GPL
+-0x0e6da44a    set_normalized_timespec vmlinux EXPORT_SYMBOL
+-0x789aafbd    iommu_map       vmlinux EXPORT_SYMBOL_GPL
+-0x3a5f1e17    cfg80211_chandef_valid  vmlinux EXPORT_SYMBOL
+-0xa11c9c1a    eth_type_trans  vmlinux EXPORT_SYMBOL
+-0xe0f1fc5d    debugfs_create_blob     vmlinux EXPORT_SYMBOL_GPL
+-0xd0f2dba2    mb_cache_entry_get      vmlinux EXPORT_SYMBOL
+-0x233ed03d    vm_insert_mixed vmlinux EXPORT_SYMBOL
+-0xa96bca8e    send_sig        vmlinux EXPORT_SYMBOL
+-0x97cdf185    iio_buffer_read_length  vmlinux EXPORT_SYMBOL
+-0x58d1070a    of_get_address  vmlinux EXPORT_SYMBOL
+-0x620868cc    tcp_shutdown    vmlinux EXPORT_SYMBOL
+-0x602c96f0    copy_to_user_fromio     vmlinux EXPORT_SYMBOL
+-0x6d31e93b    tracepoint_iter_next    vmlinux EXPORT_SYMBOL_GPL
+-0xe8b53ecc    down_write_trylock      vmlinux EXPORT_SYMBOL
+-0x8bfe8c57    param_set_uint  vmlinux EXPORT_SYMBOL
+-0x39422b14    usbnet_change_mtu       vmlinux EXPORT_SYMBOL_GPL
+-0x4bd9c5ed    scsi_nonblockable_ioctl vmlinux EXPORT_SYMBOL
+-0xcd319eaa    drm_vblank_count        vmlinux EXPORT_SYMBOL
+-0x58413099    ipv6_fixup_options      vmlinux EXPORT_SYMBOL_GPL
+-0xf389fe60    __hw_addr_init  vmlinux EXPORT_SYMBOL
+-0x199ed0cd    net_disable_timestamp   vmlinux EXPORT_SYMBOL
+-0x5ad8bb47    sdio_set_host_pm_flags  vmlinux EXPORT_SYMBOL_GPL
+-0xdbbdaaf8    gether_get_qmult        vmlinux EXPORT_SYMBOL
+-0x3d6846fc    gether_set_qmult        vmlinux EXPORT_SYMBOL
+-0x14b14b7a    usb_get_function        vmlinux EXPORT_SYMBOL_GPL
+-0x28fca1f1    pwmchip_add     vmlinux EXPORT_SYMBOL_GPL
+-0xfbbedefd    of_prop_next_string     vmlinux EXPORT_SYMBOL_GPL
+-0x4afe9a77    scsi_partsize   vmlinux EXPORT_SYMBOL
+-0x14f875ce    devm_regmap_init_mmio_clk       vmlinux EXPORT_SYMBOL_GPL
+-0x695aa696    __genl_register_family  vmlinux EXPORT_SYMBOL
+-0x36bd681b    groups_alloc    vmlinux EXPORT_SYMBOL
+-0x6a5b121d    of_find_device_by_node  vmlinux EXPORT_SYMBOL
+-0x0dd989e3    vb2_streamoff   vmlinux EXPORT_SYMBOL_GPL
+-0xa82de4f7    drm_pci_alloc   vmlinux EXPORT_SYMBOL
+-0xdf54a8f7    netlink_unregister_notifier     vmlinux EXPORT_SYMBOL
+-0xc4388843    dapm_regulator_event    vmlinux EXPORT_SYMBOL_GPL
+-0x7a6fa714    __dynamic_dev_dbg       vmlinux EXPORT_SYMBOL
+-0xfa4d00bd    simple_release_fs       vmlinux EXPORT_SYMBOL
+-0xf473ffaf    down    vmlinux EXPORT_SYMBOL
+-0xac6539ec    cm_notify_event vmlinux EXPORT_SYMBOL_GPL
+-0xf49484e8    blk_end_request vmlinux EXPORT_SYMBOL
+-0xb72a3fdb    drm_sysfs_connector_add vmlinux EXPORT_SYMBOL
+-0x76cf47f6    __aeabi_llsl    vmlinux EXPORT_SYMBOL
+-0x0573e568    inet_diag_dump_icsk     vmlinux EXPORT_SYMBOL_GPL
+-0xc6a360e4    skb_put vmlinux EXPORT_SYMBOL
+-0xf76b0a59    read_current_timer      vmlinux EXPORT_SYMBOL_GPL
+-0xf1d6f94c    v4l2_m2m_ioctl_reqbufs  vmlinux EXPORT_SYMBOL_GPL
+-0x5411bf06    scsi_host_put   vmlinux EXPORT_SYMBOL
+-0xbca0b4fd    nfc_hci_sak_to_protocol vmlinux EXPORT_SYMBOL
+-0x37386cac    nf_conntrack_hash_rnd   vmlinux EXPORT_SYMBOL_GPL
+-0xdb065657    nfnl_unlock     vmlinux EXPORT_SYMBOL_GPL
+-0xc5bd3b96    ethtool_op_get_ts_info  vmlinux EXPORT_SYMBOL
+-0x5f8ed047    configfs_depend_item    vmlinux EXPORT_SYMBOL
+-0x77fa6486    generic_block_fiemap    vmlinux EXPORT_SYMBOL
+-0xc7bcbc8d    add_wait_queue  vmlinux EXPORT_SYMBOL
+-0x046c1f16    param_ops_invbool       vmlinux EXPORT_SYMBOL
+-0x4fe5c427    pinctrl_put     vmlinux EXPORT_SYMBOL_GPL
+-0x547101cd    pinctrl_get     vmlinux EXPORT_SYMBOL_GPL
+-0xdcc5846a    brcmu_pktq_flush        drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x4075ad18    dev_add_pack    vmlinux EXPORT_SYMBOL
+-0x0a3131f6    strnchr vmlinux EXPORT_SYMBOL
+-0xd20bf6ba    dcookie_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0x9e2be04d    vb2_poll        vmlinux EXPORT_SYMBOL_GPL
+-0xa8f0aba7    usb_hub_clear_tt_buffer vmlinux EXPORT_SYMBOL_GPL
+-0x2698ff67    drm_helper_connector_dpms       vmlinux EXPORT_SYMBOL
+-0x48d34903    arm_dma_ops     vmlinux EXPORT_SYMBOL
+-0x9f984513    strrchr vmlinux EXPORT_SYMBOL
+-0x7afa89fc    vsnprintf       vmlinux EXPORT_SYMBOL
+-0x7fe32873    rb_replace_node vmlinux EXPORT_SYMBOL
+-0x6ff607b6    crypto_get_default_rng  vmlinux EXPORT_SYMBOL_GPL
+-0x668402aa    crypto_put_default_rng  vmlinux EXPORT_SYMBOL_GPL
+-0x850ff7d2    crypto_mod_put  vmlinux EXPORT_SYMBOL_GPL
+-0x1db21259    mount_pseudo    vmlinux EXPORT_SYMBOL
+-0x304ec72b    _raw_write_trylock      vmlinux EXPORT_SYMBOL
+-0x4205ad24    cancel_work_sync        vmlinux EXPORT_SYMBOL_GPL
+-0x99cdc86b    sysctl_tcp_reordering   vmlinux EXPORT_SYMBOL
+-0x19d94b34    nf_ct_gre_keymap_flush  vmlinux EXPORT_SYMBOL
+-0x356bcd72    nf_log_set      vmlinux EXPORT_SYMBOL
+-0xd9e69bb2    dapm_reg_event  vmlinux EXPORT_SYMBOL_GPL
+-0xb2959203    snd_pcm_hw_constraint_pow2      vmlinux EXPORT_SYMBOL
+-0x9754ec10    radix_tree_preload      vmlinux EXPORT_SYMBOL
+-0xc8cd27b8    blkdev_ioctl    vmlinux EXPORT_SYMBOL_GPL
+-0xd11c0dc1    __kernel_param_unlock   vmlinux EXPORT_SYMBOL
+-0xcda686ec    input_set_keycode       vmlinux EXPORT_SYMBOL
+-0xc69c2d23    subsys_virtual_register vmlinux EXPORT_SYMBOL_GPL
+-0x4eb8fe91    drm_gem_free_mmap_offset        vmlinux EXPORT_SYMBOL
+-0x61cdf6e6    nfc_hci_allocate_device vmlinux EXPORT_SYMBOL
+-0x2dda642f    __dynamic_netdev_dbg    vmlinux EXPORT_SYMBOL
+-0x890dc2ed    idr_alloc_cyclic        vmlinux EXPORT_SYMBOL
+-0x5cf6db68    crypto_register_instance        vmlinux EXPORT_SYMBOL_GPL
+-0x93bd657f    crypto_alloc_tfm        vmlinux EXPORT_SYMBOL_GPL
+-0x9c48a3ba    bdi_destroy     vmlinux EXPORT_SYMBOL
+-0x29047f1a    __i2c_board_lock        vmlinux EXPORT_SYMBOL_GPL
+-0x02e49d29    tty_ldisc_flush vmlinux EXPORT_SYMBOL_GPL
+-0xb06d489b    skb_tstamp_tx   vmlinux EXPORT_SYMBOL_GPL
+-0xe66452ab    dql_init        vmlinux EXPORT_SYMBOL
+-0x69e27c7a    bitmap_copy_le  vmlinux EXPORT_SYMBOL
+-0x4dec6038    memscan vmlinux EXPORT_SYMBOL
+-0xa9148d85    mark_buffer_dirty       vmlinux EXPORT_SYMBOL
+-0x304b568f    get_super       vmlinux EXPORT_SYMBOL
+-0x00801678    flush_scheduled_work    vmlinux EXPORT_SYMBOL
+-0xb6115ca3    tty_set_operations      vmlinux EXPORT_SYMBOL
+-0x6d6cb9ad    ieee80211_operating_class_to_band       vmlinux EXPORT_SYMBOL
+-0x32e1f29c    skb_copy_and_csum_bits  vmlinux EXPORT_SYMBOL
+-0x776c599d    idma_reg_addr_init      vmlinux EXPORT_SYMBOL_GPL
+-0xef9f2dc8    ll_rw_block     vmlinux EXPORT_SYMBOL
+-0x13014091    block_write_begin       vmlinux EXPORT_SYMBOL
+-0x93226faa    irq_domain_associate_many       vmlinux EXPORT_SYMBOL_GPL
+-0x756a4248    st_sensors_read_info_raw        vmlinux EXPORT_SYMBOL
+-0x04339915    iio_update_buffers      vmlinux EXPORT_SYMBOL_GPL
+-0x55784228    regmap_irq_get_virq     vmlinux EXPORT_SYMBOL_GPL
+-0xbc25aac9    ump_dd_phys_blocks_get  vmlinux EXPORT_SYMBOL
+-0xe1761617    security_inet_conn_request      vmlinux EXPORT_SYMBOL
+-0x1268f357    resume_device_irqs      vmlinux EXPORT_SYMBOL_GPL
+-0xbe2e3b75    kstrtos8        vmlinux EXPORT_SYMBOL
+-0x124f2056    crypto_get_attr_type    vmlinux EXPORT_SYMBOL_GPL
+-0x2fc54b62    nfnetlink_send  vmlinux EXPORT_SYMBOL_GPL
+-0x9479479b    wm_hubs_hpr_mux vmlinux EXPORT_SYMBOL_GPL
+-0x49e22268    snd_soc_info_volsw_s8   vmlinux EXPORT_SYMBOL_GPL
+-0x329aef1b    crypto_alloc_aead       vmlinux EXPORT_SYMBOL_GPL
+-0x851d17d2    crypto_spawn_tfm2       vmlinux EXPORT_SYMBOL_GPL
+-0xce6a9d9a    trace_current_buffer_discard_commit     vmlinux EXPORT_SYMBOL_GPL
+-0x50fad434    round_jiffies_up        vmlinux EXPORT_SYMBOL_GPL
+-0xf7f16b3f    input_get_new_minor     vmlinux EXPORT_SYMBOL
+-0x26c90ea4    scsi_eh_get_sense       vmlinux EXPORT_SYMBOL_GPL
+-0x75e49326    device_create_bin_file  vmlinux EXPORT_SYMBOL_GPL
+-0x113c622e    dev_set_mac_address     vmlinux EXPORT_SYMBOL
+-0xe13ad642    sk_receive_skb  vmlinux EXPORT_SYMBOL
+-0xf5c05914    generic_segment_checks  vmlinux EXPORT_SYMBOL
+-0xd0f36f0d    audit_log_format        vmlinux EXPORT_SYMBOL
+-0xdbaf59ef    v4l2_m2m_mmap   vmlinux EXPORT_SYMBOL
+-0xde520229    serio_open      vmlinux EXPORT_SYMBOL
+-0xc5714a65    spi_master_suspend      vmlinux EXPORT_SYMBOL_GPL
+-0x22b325d5    kd_mksound      vmlinux EXPORT_SYMBOL
+-0x6d2fc5a6    net_namespace_list      vmlinux EXPORT_SYMBOL_GPL
+-0x9f6381e8    sock_register   vmlinux EXPORT_SYMBOL
+-0xf1806da9    idr_find_slowpath       vmlinux EXPORT_SYMBOL
+-0x5ae5be44    lg_lock_init    vmlinux EXPORT_SYMBOL
+-0x2d307e05    vb2_ioctl_qbuf  vmlinux EXPORT_SYMBOL_GPL
+-0xaad6c827    serio_close     vmlinux EXPORT_SYMBOL
+-0x8b092f05    loop_register_transfer  vmlinux EXPORT_SYMBOL
+-0x3c967a5a    device_set_wakeup_enable        vmlinux EXPORT_SYMBOL_GPL
+-0xc34b9b1f    regulator_get_bypass_regmap     vmlinux EXPORT_SYMBOL_GPL
+-0xde9cc521    pinctrl_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0xd1c5bc52    __cfg80211_send_deauth  vmlinux EXPORT_SYMBOL
+-0x126ad73c    inet6_register_protosw  vmlinux EXPORT_SYMBOL
+-0x5ce3b588    nfnl_lock       vmlinux EXPORT_SYMBOL_GPL
+-0xdc197993    netif_set_real_num_tx_queues    vmlinux EXPORT_SYMBOL
+-0xd4d07dc9    netif_set_real_num_rx_queues    vmlinux EXPORT_SYMBOL
+-0xbdc3f3e4    dev_set_group   vmlinux EXPORT_SYMBOL
+-0xb4176982    proc_remove     vmlinux EXPORT_SYMBOL
+-0x663e9182    end_buffer_async_write  vmlinux EXPORT_SYMBOL
+-0x3d517179    phy_register_fixup_for_uid      vmlinux EXPORT_SYMBOL
+-0xb4709322    scsi_dev_info_add_list  vmlinux EXPORT_SYMBOL
+-0x9dd34b62    drm_mm_insert_node_in_range     vmlinux EXPORT_SYMBOL
+-0x69b18f43    rfc1042_header  vmlinux EXPORT_SYMBOL
+-0x50097088    security_tun_dev_free_security  vmlinux EXPORT_SYMBOL
+-0x050c08c1    vfs_writev      vmlinux EXPORT_SYMBOL
+-0xd6b5a293    iio_buffer_init vmlinux EXPORT_SYMBOL
+-0x811e0359    sdio_get_host_pm_caps   vmlinux EXPORT_SYMBOL_GPL
+-0x9062c322    ring_buffer_consume     vmlinux EXPORT_SYMBOL_GPL
+-0x1c5b1f28    irq_free_descs  vmlinux EXPORT_SYMBOL_GPL
+-0xf2791baa    cgroup_unload_subsys    vmlinux EXPORT_SYMBOL_GPL
+-0xe43274bc    proc_dointvec   vmlinux EXPORT_SYMBOL
+-0xe8948e95    mmc_stop_bkops  vmlinux EXPORT_SYMBOL
+-0xa2a5fd77    inet_ehash_secret       vmlinux EXPORT_SYMBOL
+-0x2363e5bf    __inet_lookup_established       vmlinux EXPORT_SYMBOL_GPL
+-0x3eeb1d5e    netdev_alert    vmlinux EXPORT_SYMBOL
+-0x26ad413b    netdev_has_any_upper_dev        vmlinux EXPORT_SYMBOL
+-0x7604b234    udp_lib_rehash  vmlinux EXPORT_SYMBOL
+-0x5e5d53d3    udp_lib_unhash  vmlinux EXPORT_SYMBOL
+-0x2b12925d    cpumask_next_and        vmlinux EXPORT_SYMBOL
+-0x05495392    hid_debug       vmlinux EXPORT_SYMBOL_GPL
+-0x1d1ca867    pm_stay_awake   vmlinux EXPORT_SYMBOL_GPL
+-0x8c1a19df    device_show_ulong       vmlinux EXPORT_SYMBOL_GPL
+-0x46940ff4    set_ras_addr_hook       vmlinux EXPORT_SYMBOL_GPL
+-0x6088da85    nf_hook_slow    vmlinux EXPORT_SYMBOL
+-0xce5ac24f    zlib_inflate_workspacesize      vmlinux EXPORT_SYMBOL
+-0x2e73d9a1    v4l2_chip_ident_i2c_client      vmlinux EXPORT_SYMBOL
+-0x3783cdae    drm_open        vmlinux EXPORT_SYMBOL
+-0x5404b1e7    tcp_recvmsg     vmlinux EXPORT_SYMBOL
+-0x47b90df9    snd_pcm_limit_hw_rates  vmlinux EXPORT_SYMBOL
+-0x63baba6b    irq_alloc_generic_chip  vmlinux EXPORT_SYMBOL_GPL
+-0xace5c0fc    usb_bus_list    vmlinux EXPORT_SYMBOL_GPL
+-0xe8b63ace    radix_tree_range_tag_if_tagged  vmlinux EXPORT_SYMBOL
+-0x8d8b6353    proc_dointvec_userhz_jiffies    vmlinux EXPORT_SYMBOL
+-0x7ec5c02b    console_start   vmlinux EXPORT_SYMBOL
+-0x1a1aebf8    s3c_adc_start   vmlinux EXPORT_SYMBOL_GPL
+-0xffc6c87a    drm_detect_monitor_audio        vmlinux EXPORT_SYMBOL
+-0xe1371ad4    tcp_simple_retransmit   vmlinux EXPORT_SYMBOL
+-0x0f18b144    inet_csk_bind_conflict  vmlinux EXPORT_SYMBOL_GPL
+-0x708e56bd    xt_register_match       vmlinux EXPORT_SYMBOL
+-0xf3526269    proc_set_user   vmlinux EXPORT_SYMBOL
+-0x752dff9d    anon_inode_getfile      vmlinux EXPORT_SYMBOL_GPL
+-0xcd10fb11    simple_dir_inode_operations     vmlinux EXPORT_SYMBOL
+-0x708bd95d    irq_domain_xlate_onetwocell     vmlinux EXPORT_SYMBOL_GPL
+-0x122043a8    of_find_node_with_property      vmlinux EXPORT_SYMBOL
+-0xb3453966    vb2_fop_release vmlinux EXPORT_SYMBOL_GPL
+-0x59dddb40    ump_dd_reference_add    vmlinux EXPORT_SYMBOL
+-0xe8bcc079    snd_soc_codec_set_cache_io      vmlinux EXPORT_SYMBOL_GPL
+-0x67ae5cfb    dmam_pool_create        vmlinux EXPORT_SYMBOL
+-0x1e7f65cb    vb2_mmap        vmlinux EXPORT_SYMBOL_GPL
+-0xb33ff162    __find_get_block        vmlinux EXPORT_SYMBOL
+-0x23a997f4    dcache_dir_open vmlinux EXPORT_SYMBOL
+-0x3f4547a7    put_unused_fd   vmlinux EXPORT_SYMBOL
+-0xd2555f19    jiffies_64_to_clock_t   vmlinux EXPORT_SYMBOL
+-0xef969c64    input_mt_get_slot_by_key        vmlinux EXPORT_SYMBOL
+-0x2b547fec    genphy_suspend  vmlinux EXPORT_SYMBOL
+-0x0a04ac5b    subsys_system_register  vmlinux EXPORT_SYMBOL_GPL
+-0x919a5e62    inet6_lookup_listener   vmlinux EXPORT_SYMBOL_GPL
+-0xece784c2    rb_first        vmlinux EXPORT_SYMBOL
+-0xc72e1233    __trace_bprintk vmlinux EXPORT_SYMBOL_GPL
+-0x6a5ecb18    unregister_module_notifier      vmlinux EXPORT_SYMBOL
+-0x19f115c3    flush_delayed_work      vmlinux EXPORT_SYMBOL
+-0xf82f5060    usbnet_read_cmd vmlinux EXPORT_SYMBOL_GPL
+-0xf3e09d59    dev_pm_qos_expose_latency_limit vmlinux EXPORT_SYMBOL_GPL
+-0xfc4cb906    exynos_drm_subdrv_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0x04911106    of_dma_simple_xlate     vmlinux EXPORT_SYMBOL_GPL
+-0x7211e749    nf_conntrack_hash_check_insert  vmlinux EXPORT_SYMBOL_GPL
+-0x68b80336    zero_fill_bio   vmlinux EXPORT_SYMBOL
+-0xe83fad56    mmc_switch      vmlinux EXPORT_SYMBOL_GPL
+-0xa5a8337c    scsi_cmd_print_sense_hdr        vmlinux EXPORT_SYMBOL
+-0x8b08c5c1    unix_peer_get   vmlinux EXPORT_SYMBOL_GPL
+-0xef3b173b    audit_log_task_info     vmlinux EXPORT_SYMBOL
+-0xacc26098    iio_read_const_attr     vmlinux EXPORT_SYMBOL
+-0x47d7d62e    mmc_resume_host vmlinux EXPORT_SYMBOL
+-0x323758b8    v4l2_spi_subdev_init    vmlinux EXPORT_SYMBOL_GPL
+-0xbaa5b6b2    bus_register    vmlinux EXPORT_SYMBOL_GPL
+-0xf39ab86b    tcp_syn_ack_timeout     vmlinux EXPORT_SYMBOL
+-0xe73dda41    __nf_ct_ext_add_length  vmlinux EXPORT_SYMBOL
+-0xc4ff89ae    nf_log_unregister       vmlinux EXPORT_SYMBOL
+-0xd8e38717    d_hash_and_lookup       vmlinux EXPORT_SYMBOL
+-0x63193a50    generic_file_buffered_write     vmlinux EXPORT_SYMBOL
+-0xcce7df45    iio_alloc_pollfunc      vmlinux EXPORT_SYMBOL_GPL
+-0x24b0f90c    of_clk_get_by_name      vmlinux EXPORT_SYMBOL
+-0x3fb35146    mmc_alloc_host  vmlinux EXPORT_SYMBOL
+-0xe6099979    scsi_eh_ready_devs      vmlinux EXPORT_SYMBOL_GPL
+-0x986e6135    fb_pad_unaligned_buffer vmlinux EXPORT_SYMBOL
+-0xc1c2dd09    __hw_addr_flush vmlinux EXPORT_SYMBOL
+-0xae249a24    snd_register_device_for_dev     vmlinux EXPORT_SYMBOL
+-0xea054b22    nla_policy_len  vmlinux EXPORT_SYMBOL
+-0xd92afabe    bitmap_clear    vmlinux EXPORT_SYMBOL
+-0x80f48353    fsync_bdev      vmlinux EXPORT_SYMBOL
+-0x71930ed3    of_property_read_string vmlinux EXPORT_SYMBOL_GPL
+-0x570f339b    thermal_cooling_device_register vmlinux EXPORT_SYMBOL_GPL
+-0xcfcdd86a    input_open_device       vmlinux EXPORT_SYMBOL
+-0x84ac53cc    drm_fb_helper_single_add_all_connectors vmlinux EXPORT_SYMBOL
+-0x0e3edf75    regulator_set_bypass_regmap     vmlinux EXPORT_SYMBOL_GPL
+-0xfe990052    gpio_free       vmlinux EXPORT_SYMBOL_GPL
+-0x0b63a348    cfg80211_wext_giwrange  vmlinux EXPORT_SYMBOL_GPL
+-0x6d815a8f    ip6_dst_lookup  vmlinux EXPORT_SYMBOL_GPL
+-0x40a9b349    vzalloc vmlinux EXPORT_SYMBOL
+-0xc2f9c045    timespec_to_jiffies     vmlinux EXPORT_SYMBOL
+-0x54159824    iio_push_event  vmlinux EXPORT_SYMBOL
+-0x94f95b4e    i2c_new_device  vmlinux EXPORT_SYMBOL_GPL
+-0xe04e6d60    device_for_each_child   vmlinux EXPORT_SYMBOL_GPL
+-0x5eafb8e9    drm_mode_set_name       vmlinux EXPORT_SYMBOL
+-0x3b0a974f    arm_iommu_release_mapping       vmlinux EXPORT_SYMBOL_GPL
+-0xed76ba4a    hci_resume_dev  vmlinux EXPORT_SYMBOL
+-0x9cfaab5e    media_device_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x5783d440    pm_generic_poweroff_late        vmlinux EXPORT_SYMBOL_GPL
+-0x59c8991b    nci_allocate_device     vmlinux EXPORT_SYMBOL
+-0x11089ac7    _ctype  vmlinux EXPORT_SYMBOL
+-0x66d480cb    blk_get_queue   vmlinux EXPORT_SYMBOL
+-0x60b78a66    bd_set_size     vmlinux EXPORT_SYMBOL
+-0x71f34013    __mem_cgroup_count_vm_event     vmlinux EXPORT_SYMBOL
+-0x2d45b494    pm_vt_switch_unregister vmlinux EXPORT_SYMBOL
+-0xca7d8764    kthread_freezable_should_stop   vmlinux EXPORT_SYMBOL_GPL
+-0x03b3002e    st_sensors_enable_events        vmlinux EXPORT_SYMBOL
+-0xfc937fcb    usb_add_gadget_udc      vmlinux EXPORT_SYMBOL_GPL
+-0x420323e6    i2c_dp_aux_add_bus      vmlinux EXPORT_SYMBOL
+-0xd6ef94db    udp_proc_unregister     vmlinux EXPORT_SYMBOL
+-0x37f614b7    __kfifo_len_r   vmlinux EXPORT_SYMBOL
+-0xac6e0f5a    power_supply_get_by_name        vmlinux EXPORT_SYMBOL_GPL
+-0x86047552    inet_sk_rebuild_header  vmlinux EXPORT_SYMBOL
+-0x3c878c55    skb_copy        vmlinux EXPORT_SYMBOL
+-0xe5b6e62e    snd_pcm_stop    vmlinux EXPORT_SYMBOL
+-0x7593d385    div64_s64       vmlinux EXPORT_SYMBOL
+-0x27864d57    memparse        vmlinux EXPORT_SYMBOL
+-0xe8f9c617    block_truncate_page     vmlinux EXPORT_SYMBOL
+-0xbc036e9e    generic_write_checks    vmlinux EXPORT_SYMBOL
+-0x4f68e5c9    do_gettimeofday vmlinux EXPORT_SYMBOL
+-0xa6715115    do_settimeofday vmlinux EXPORT_SYMBOL
+-0xd9efbe4c    input_inject_event      vmlinux EXPORT_SYMBOL
+-0x3dc565d9    drm_mm_insert_node_generic      vmlinux EXPORT_SYMBOL
+-0x0c58a8cd    netdev_increment_features       vmlinux EXPORT_SYMBOL
+-0xb3c487b6    uart_match_port vmlinux EXPORT_SYMBOL
+-0x208f2017    brcmu_pktq_pdeq_match   drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0xbc455bde    cfg80211_pmksa_candidate_notify vmlinux EXPORT_SYMBOL
+-0x3bef03b9    flow_cache_lookup       vmlinux EXPORT_SYMBOL
+-0x5002ec2f    __splice_from_pipe      vmlinux EXPORT_SYMBOL
+-0x863c552c    cache_firmware  vmlinux EXPORT_SYMBOL_GPL
+-0xe5274b72    unregister_net_sysctl_table     vmlinux EXPORT_SYMBOL_GPL
+-0xa197b1ff    ieee80211_get_mesh_hdrlen       vmlinux EXPORT_SYMBOL
+-0x3a9592df    __nf_ct_ext_destroy     vmlinux EXPORT_SYMBOL
+-0xa2c640f9    sysfs_add_file_to_group vmlinux EXPORT_SYMBOL_GPL
+-0x487d9343    param_ops_ushort        vmlinux EXPORT_SYMBOL
+-0x58804ca9    sdio_align_size vmlinux EXPORT_SYMBOL_GPL
+-0xa09e1f4c    cpufreq_register_governor       vmlinux EXPORT_SYMBOL_GPL
+-0x8ee7279a    ump_dd_size_get vmlinux EXPORT_SYMBOL
+-0xfb858f46    tty_write_room  vmlinux EXPORT_SYMBOL
+-0x3d715445    dev_trans_start vmlinux EXPORT_SYMBOL
+-0xa381944f    dql_reset       vmlinux EXPORT_SYMBOL
+-0x8f99ae4c    blk_register_region     vmlinux EXPORT_SYMBOL
+-0xa8242495    bio_put vmlinux EXPORT_SYMBOL
+-0x488d1fd7    task_tgid_nr_ns vmlinux EXPORT_SYMBOL
+-0xc8d55b31    usb_unlocked_disable_lpm        vmlinux EXPORT_SYMBOL_GPL
+-0x10ee20bb    default_blu     vmlinux EXPORT_SYMBOL
+-0x57575f08    dmaengine_put   vmlinux EXPORT_SYMBOL
+-0x60577ee3    ip6_expire_frag_queue   vmlinux EXPORT_SYMBOL
+-0xdb5d34e0    rcu_batches_completed_preempt   vmlinux EXPORT_SYMBOL_GPL
+-0xec6f4d80    each_symbol_section     vmlinux EXPORT_SYMBOL_GPL
+-0xea6e3003    of_find_compatible_node vmlinux EXPORT_SYMBOL
+-0x0d95dc3b    video_ioctl2    vmlinux EXPORT_SYMBOL
+-0x26156aad    input_alloc_absinfo     vmlinux EXPORT_SYMBOL
+-0x244b53b3    scsi_is_target_device   vmlinux EXPORT_SYMBOL
+-0xd0cf28c6    sk_dst_check    vmlinux EXPORT_SYMBOL
+-0xa5dd45f3    prandom_bytes_state     vmlinux EXPORT_SYMBOL
+-0x6a76f3ac    blk_iopoll_enable       vmlinux EXPORT_SYMBOL
+-0x17e1907b    inode_needs_sync        vmlinux EXPORT_SYMBOL
+-0x9c6ac1ed    grab_cache_page_nowait  vmlinux EXPORT_SYMBOL
+-0xe7a81967    audit_log_secctx        vmlinux EXPORT_SYMBOL
+-0x2babe81f    __wake_up_sync_key      vmlinux EXPORT_SYMBOL_GPL
+-0x4adaf0f3    v4l2_ctrl_query_menu_valid_items        vmlinux EXPORT_SYMBOL
+-0xcb6f482d    dev_getfirstbyhwtype    vmlinux EXPORT_SYMBOL
+-0xb23df37e    wake_up_process vmlinux EXPORT_SYMBOL
+-0x25820c64    fs_overflowuid  vmlinux EXPORT_SYMBOL
+-0x24ddf922    scsi_internal_device_block      vmlinux EXPORT_SYMBOL_GPL
+-0x1079ac8f    drm_framebuffer_remove  vmlinux EXPORT_SYMBOL
+-0x160f2f7e    of_phy_simple_xlate     vmlinux EXPORT_SYMBOL_GPL
+-0xe669c8a2    __nf_ct_refresh_acct    vmlinux EXPORT_SYMBOL_GPL
+-0xa2f20d05    skb_dequeue_tail        vmlinux EXPORT_SYMBOL
+-0x19a025aa    __get_user_pages        vmlinux EXPORT_SYMBOL
+-0x286acd69    free_css_id     vmlinux EXPORT_SYMBOL_GPL
+-0x404c4f08    __module_address        vmlinux EXPORT_SYMBOL_GPL
+-0x195d329a    hidinput_count_leds     vmlinux EXPORT_SYMBOL_GPL
+-0x280c859a    input_ff_erase  vmlinux EXPORT_SYMBOL_GPL
+-0x886d02da    scsi_target_resume      vmlinux EXPORT_SYMBOL
+-0x8f31e347    inet_stream_ops vmlinux EXPORT_SYMBOL
+-0x9b0dcfa2    qdisc_reset     vmlinux EXPORT_SYMBOL
+-0xd2da1048    register_netdevice_notifier     vmlinux EXPORT_SYMBOL
+-0x1b5fff19    blk_complete_request    vmlinux EXPORT_SYMBOL
+-0x808ec1a3    crypto_alg_tested       vmlinux EXPORT_SYMBOL_GPL
+-0xda920cd9    bio_unmap_user  vmlinux EXPORT_SYMBOL
+-0xe769232e    sprint_symbol_no_offset vmlinux EXPORT_SYMBOL_GPL
+-0x2b7a6de8    syscon_regmap_lookup_by_phandle vmlinux EXPORT_SYMBOL_GPL
+-0x9728e93f    of_dma_controller_register      vmlinux EXPORT_SYMBOL_GPL
+-0x1b61c5b3    pwm_config      vmlinux EXPORT_SYMBOL_GPL
+-0x39bdf0f0    nci_free_device vmlinux EXPORT_SYMBOL
+-0xe3a306b5    udp_seq_open    vmlinux EXPORT_SYMBOL
+-0x38c97d50    idr_get_next    vmlinux EXPORT_SYMBOL
+-0xeaacc92f    fail_migrate_page       vmlinux EXPORT_SYMBOL
+-0x4cdb3178    ns_to_timeval   vmlinux EXPORT_SYMBOL
+-0xc78d0953    ehci_init_driver        vmlinux EXPORT_SYMBOL_GPL
+-0xcd6ff125    nf_ct_expect_register_notifier  vmlinux EXPORT_SYMBOL_GPL
+-0x721b1851    skip_spaces     vmlinux EXPORT_SYMBOL
+-0x0c0c015e    ring_buffer_swap_cpu    vmlinux EXPORT_SYMBOL_GPL
+-0x76d451c4    add_taint       vmlinux EXPORT_SYMBOL
+-0x1c2596ba    regmap_async_complete_cb        vmlinux EXPORT_SYMBOL_GPL
+-0x60a32ea9    pm_power_off    vmlinux EXPORT_SYMBOL
+-0x2b911208    __neigh_for_each_release        vmlinux EXPORT_SYMBOL
+-0x0bc7e6ff    blk_queue_init_tags     vmlinux EXPORT_SYMBOL
+-0xa666946b    bdget   vmlinux EXPORT_SYMBOL
+-0x885a4cc9    bdput   vmlinux EXPORT_SYMBOL
+-0x2517dbbb    fsstack_copy_inode_size vmlinux EXPORT_SYMBOL_GPL
+-0x7d4ed855    iio_trigger_poll_chained        vmlinux EXPORT_SYMBOL
+-0x561e4b77    irq_of_parse_and_map    vmlinux EXPORT_SYMBOL_GPL
+-0x308efc55    spi_busnum_to_master    vmlinux EXPORT_SYMBOL_GPL
+-0xe862c4b7    dpm_suspend_start       vmlinux EXPORT_SYMBOL_GPL
+-0xd728282d    device_initialize       vmlinux EXPORT_SYMBOL_GPL
+-0xf6b77868    nf_conntrack_untracked  vmlinux EXPORT_SYMBOL
+-0xed9f8e6d    kstrtos16       vmlinux EXPORT_SYMBOL
+-0xfb32b30f    ring_buffer_read_prepare_sync   vmlinux EXPORT_SYMBOL_GPL
+-0x846bcc01    dm_table_get    vmlinux EXPORT_SYMBOL
+-0x1416333b    tcf_em_register vmlinux EXPORT_SYMBOL
+-0x19546cac    snd_soc_cache_read      vmlinux EXPORT_SYMBOL_GPL
+-0xfd2f4f20    snd_soc_info_volsw_ext  vmlinux EXPORT_SYMBOL_GPL
+-0x6c749afe    __tracepoint_block_unplug       vmlinux EXPORT_SYMBOL_GPL
+-0x9c86ede0    fs_kobj vmlinux EXPORT_SYMBOL_GPL
+-0x796c2d48    dm_get_md       vmlinux EXPORT_SYMBOL_GPL
+-0xf8fbb4f0    __bad_xchg      vmlinux EXPORT_SYMBOL
+-0xc40f284c    nf_ct_helper_hsize      vmlinux EXPORT_SYMBOL_GPL
+-0x24428be5    strncpy_from_user       vmlinux EXPORT_SYMBOL
+-0x6d74d462    crypto_alloc_ablkcipher vmlinux EXPORT_SYMBOL_GPL
+-0x0b96efa8    bio_init        vmlinux EXPORT_SYMBOL
+-0x7278d328    all_vm_events   vmlinux EXPORT_SYMBOL_GPL
+-0x41814cb8    dirty_writeback_interval        vmlinux EXPORT_SYMBOL_GPL
+-0x1c32da2a    iio_enum_available_read vmlinux EXPORT_SYMBOL_GPL
+-0xcda91c46    drm_mode_debug_printmodeline    vmlinux EXPORT_SYMBOL
+-0xa9cae71a    inet6_hash_connect      vmlinux EXPORT_SYMBOL_GPL
+-0x92f5d840    gnet_stats_copy_rate_est        vmlinux EXPORT_SYMBOL
+-0x17f61c70    skb_partial_csum_set    vmlinux EXPORT_SYMBOL_GPL
+-0xb86cf818    create_empty_buffers    vmlinux EXPORT_SYMBOL
+-0x26332c2f    init_special_inode      vmlinux EXPORT_SYMBOL
+-0xd0720a17    on_each_cpu_cond        vmlinux EXPORT_SYMBOL
+-0x870713f0    iommu_detach_group      vmlinux EXPORT_SYMBOL_GPL
+-0x00c8b1c1    sdio_enable_func        vmlinux EXPORT_SYMBOL_GPL
+-0x22f907ec    pm_runtime_no_callbacks vmlinux EXPORT_SYMBOL_GPL
+-0x8d4234e8    subsys_dev_iter_next    vmlinux EXPORT_SYMBOL_GPL
+-0x706fc943    mali_pmu_powerup        vmlinux EXPORT_SYMBOL
+-0xf24fbd54    cfg80211_mgmt_tx_status vmlinux EXPORT_SYMBOL
+-0xa8bae0ab    inet_frag_destroy       vmlinux EXPORT_SYMBOL
+-0xca1aff2d    ipv4_sk_update_pmtu     vmlinux EXPORT_SYMBOL_GPL
+-0x539973c5    skb_make_writable       vmlinux EXPORT_SYMBOL
+-0x2eeceb42    sk_chk_filter   vmlinux EXPORT_SYMBOL
+-0x8f595b11    snd_major       vmlinux EXPORT_SYMBOL
+-0xf8433bfd    pipe_to_file    vmlinux EXPORT_SYMBOL
+-0x0dc1d65b    __dec_zone_page_state   vmlinux EXPORT_SYMBOL
+-0x95ce193b    __inc_zone_page_state   vmlinux EXPORT_SYMBOL
+-0x736c2d7c    __mod_zone_page_state   vmlinux EXPORT_SYMBOL
+-0xab6babaf    pm_qos_request  vmlinux EXPORT_SYMBOL_GPL
+-0xeed6cc4b    flush_kthread_worker    vmlinux EXPORT_SYMBOL_GPL
+-0xa5cef8ad    release_resource        vmlinux EXPORT_SYMBOL
+-0x4584b8a3    iio_push_to_buffers     vmlinux EXPORT_SYMBOL_GPL
+-0xc79bcd36    dm_vcalloc      vmlinux EXPORT_SYMBOL
+-0xa7dd8c46    ump_dd_phys_block_get   vmlinux EXPORT_SYMBOL
+-0x83bd3297    brioctl_set     vmlinux EXPORT_SYMBOL
+-0x09e913c1    snd_pcm_alt_chmaps      vmlinux EXPORT_SYMBOL_GPL
+-0xbf33e600    vm_insert_pfn   vmlinux EXPORT_SYMBOL
+-0xda050109    irq_domain_add_nomap    vmlinux EXPORT_SYMBOL_GPL
+-0xfcaa04a0    out_of_line_wait_on_bit_lock    vmlinux EXPORT_SYMBOL
+-0xa7bb71ae    input_set_abs_params    vmlinux EXPORT_SYMBOL
+-0x22f9a7f4    spi_bus_unlock  vmlinux EXPORT_SYMBOL_GPL
+-0x2ea5ad9c    device_schedule_callback_owner  vmlinux EXPORT_SYMBOL_GPL
+-0x4c511235    drm_edid_is_valid       vmlinux EXPORT_SYMBOL
+-0x3939f8f0    rfkill_pause_polling    vmlinux EXPORT_SYMBOL
+-0xebc7bcd9    xfrm_state_alloc        vmlinux EXPORT_SYMBOL
+-0x85670f1d    rtnl_is_locked  vmlinux EXPORT_SYMBOL
+-0x726d45d3    fat_remove_entries      vmlinux EXPORT_SYMBOL_GPL
+-0xd963ea55    page_symlink    vmlinux EXPORT_SYMBOL
+-0xa26d9b4f    workqueue_congested     vmlinux EXPORT_SYMBOL_GPL
+-0xf7cd6b11    freq_reg_info   vmlinux EXPORT_SYMBOL
+-0x764dafa5    __xfrm_route_forward    vmlinux EXPORT_SYMBOL
+-0xd317cce2    snd_soc_put_volsw_sx    vmlinux EXPORT_SYMBOL_GPL
+-0x587ba0c8    snd_soc_get_volsw_s8    vmlinux EXPORT_SYMBOL_GPL
+-0x5dda7051    snd_soc_put_volsw_s8    vmlinux EXPORT_SYMBOL_GPL
+-0xd6b61c7b    snd_soc_get_volsw_sx    vmlinux EXPORT_SYMBOL_GPL
+-0x9f0664bf    dm_get_queue_limits     vmlinux EXPORT_SYMBOL_GPL
+-0x0364983f    gen_replace_estimator   vmlinux EXPORT_SYMBOL
+-0x2f03fc4b    security_secmark_refcount_inc   vmlinux EXPORT_SYMBOL
+-0x19bd383b    security_secmark_refcount_dec   vmlinux EXPORT_SYMBOL
+-0xc22b50ad    param_set_bint  vmlinux EXPORT_SYMBOL
+-0x21315700    param_get_bool  vmlinux EXPORT_SYMBOL
+-0x3eae292f    param_set_byte  vmlinux EXPORT_SYMBOL
+-0xcea1a019    dw_mci_suspend  vmlinux EXPORT_SYMBOL
+-0x8657c2d4    spi_bitbang_setup       vmlinux EXPORT_SYMBOL_GPL
+-0xb13fbb9a    scsi_target_unblock     vmlinux EXPORT_SYMBOL_GPL
+-0xbf3a015f    brcmf_sdio_remove       drivers/net/wireless/brcm80211/brcmfmac/brcmfmac        EXPORT_SYMBOL
+-0xeb1c3628    nf_ipv6_ops     vmlinux EXPORT_SYMBOL_GPL
+-0x9fdecc31    unregister_netdevice_many       vmlinux EXPORT_SYMBOL
+-0x75308bb0    blk_queue_logical_block_size    vmlinux EXPORT_SYMBOL
+-0x2fe50bdf    init_srcu_struct        vmlinux EXPORT_SYMBOL_GPL
+-0xfba64859    rtc_device_unregister   vmlinux EXPORT_SYMBOL_GPL
+-0xbd10afa1    drm_platform_init       vmlinux EXPORT_SYMBOL
+-0xa1ceb496    drm_platform_exit       vmlinux EXPORT_SYMBOL
+-0xd10d7d37    arp_tbl vmlinux EXPORT_SYMBOL
+-0x9aa6cefb    __skb_recv_datagram     vmlinux EXPORT_SYMBOL
+-0x0430401c    snd_soc_remove_platform vmlinux EXPORT_SYMBOL_GPL
+-0xfe7c4287    nr_cpu_ids      vmlinux EXPORT_SYMBOL
+-0x18b6fa40    v4l2_ctrl_add_ctrl      vmlinux EXPORT_SYMBOL
+-0xb21d34e2    phy_attach      vmlinux EXPORT_SYMBOL
+-0x67f7fd01    gpiochip_remove_pin_ranges      vmlinux EXPORT_SYMBOL_GPL
+-0x5c9284a0    processor_id    vmlinux EXPORT_SYMBOL
+-0x688e3c72    tcp_splice_read vmlinux EXPORT_SYMBOL
+-0x9f7f32fe    xt_unregister_match     vmlinux EXPORT_SYMBOL
+-0x2822f8fe    irq_setup_generic_chip  vmlinux EXPORT_SYMBOL_GPL
+-0x8763d790    pm_genpd_syscore_switch vmlinux EXPORT_SYMBOL_GPL
+-0xc898f9f7    css_depth       vmlinux EXPORT_SYMBOL_GPL
+-0x95d97984    devm_regmap_init_spi    vmlinux EXPORT_SYMBOL_GPL
+-0x32108723    devm_regmap_init_i2c    vmlinux EXPORT_SYMBOL_GPL
+-0x824028e1    drm_master_get  vmlinux EXPORT_SYMBOL
+-0x36e360e3    __hw_addr_add_multiple  vmlinux EXPORT_SYMBOL
+-0x92e42550    snd_soc_jack_add_gpios  vmlinux EXPORT_SYMBOL_GPL
+-0x9552bd34    crypto_unregister_algs  vmlinux EXPORT_SYMBOL_GPL
+-0x70bd3119    simple_transaction_set  vmlinux EXPORT_SYMBOL
+-0x5cf1e7e1    simple_transaction_get  vmlinux EXPORT_SYMBOL
+-0x86b57862    find_pid_ns     vmlinux EXPORT_SYMBOL_GPL
+-0x0b59c21c    st_gyro_common_probe    vmlinux EXPORT_SYMBOL
+-0x3a4c6000    of_irq_to_resource      vmlinux EXPORT_SYMBOL_GPL
+-0xcbc9557f    unregister_sysrq_key    vmlinux EXPORT_SYMBOL
+-0xd85ac634    regulator_put   vmlinux EXPORT_SYMBOL_GPL
+-0x56e75d47    klist_node_attached     vmlinux EXPORT_SYMBOL_GPL
+-0xf0d6c49d    rfkill_alloc    vmlinux EXPORT_SYMBOL
+-0xe118d3ca    __nf_conntrack_find     vmlinux EXPORT_SYMBOL_GPL
+-0x67fa9d64    __nlmsg_put     vmlinux EXPORT_SYMBOL
+-0xc5f839f2    lock_sock_nested        vmlinux EXPORT_SYMBOL
+-0x92b57248    flush_work      vmlinux EXPORT_SYMBOL_GPL
+-0x63aecd53    hid_add_device  vmlinux EXPORT_SYMBOL_GPL
+-0x870e11ef    sdio_disable_func       vmlinux EXPORT_SYMBOL_GPL
+-0xd6c99af7    devm_usb_put_phy        vmlinux EXPORT_SYMBOL_GPL
+-0x60652b23    usbnet_cdc_bind vmlinux EXPORT_SYMBOL_GPL
+-0x0f1fd032    scsi_free_command       vmlinux EXPORT_SYMBOL
+-0x150d593e    platform_add_devices    vmlinux EXPORT_SYMBOL_GPL
+-0xdc2235fd    device_show_bool        vmlinux EXPORT_SYMBOL_GPL
+-0xe800ece3    __mmc_switch    vmlinux EXPORT_SYMBOL_GPL
+-0x8650b7ba    usb_deregister  vmlinux EXPORT_SYMBOL_GPL
+-0x83a82050    phy_ethtool_get_eee     vmlinux EXPORT_SYMBOL
+-0xccb94d1a    phy_ethtool_set_eee     vmlinux EXPORT_SYMBOL
+-0x1a81168a    drm_mm_dump_table       vmlinux EXPORT_SYMBOL
+-0x04cda566    snd_interval_refine     vmlinux EXPORT_SYMBOL
+-0x6b2dc060    dump_stack      vmlinux EXPORT_SYMBOL
+-0x23476dca    crypto_alloc_instance   vmlinux EXPORT_SYMBOL_GPL
+-0x31cd11aa    mpage_writepage vmlinux EXPORT_SYMBOL
+-0xa219c44e    try_to_writeback_inodes_sb_nr   vmlinux EXPORT_SYMBOL
+-0xd942d353    ring_buffer_record_off  vmlinux EXPORT_SYMBOL_GPL
+-0x178768e1    set_security_override   vmlinux EXPORT_SYMBOL
+-0x7930d225    of_device_is_compatible vmlinux EXPORT_SYMBOL
+-0xa1fb703c    drm_mm_remove_node      vmlinux EXPORT_SYMBOL
+-0x3fce0784    rdev_get_drvdata        vmlinux EXPORT_SYMBOL_GPL
+-0x193f9832    nfc_allocate_device     vmlinux EXPORT_SYMBOL
+-0xcefba9ae    raw_seq_start   vmlinux EXPORT_SYMBOL_GPL
+-0x353b4dcf    nfnetlink_subsys_unregister     vmlinux EXPORT_SYMBOL_GPL
+-0x1db53c10    dst_cow_metrics_generic vmlinux EXPORT_SYMBOL
+-0x884c205c    mount_ns        vmlinux EXPORT_SYMBOL
+-0x26b0e339    sdhci_disable_irq_wakeups       vmlinux EXPORT_SYMBOL_GPL
+-0x69e3154c    rtc_read_time   vmlinux EXPORT_SYMBOL_GPL
+-0xde6ff4ec    usb_get_function_instance       vmlinux EXPORT_SYMBOL_GPL
+-0x0c29207f    netdev_master_upper_dev_get     vmlinux EXPORT_SYMBOL
+-0x62d34ec2    kobject_del     vmlinux EXPORT_SYMBOL
+-0x7489664f    crypto_unregister_shash vmlinux EXPORT_SYMBOL_GPL
+-0x5ca7f0f8    crypto_unregister_ahash vmlinux EXPORT_SYMBOL_GPL
+-0x86a4889a    kmalloc_order_trace     vmlinux EXPORT_SYMBOL
+-0x0698cb23    drm_core_reclaim_buffers        vmlinux EXPORT_SYMBOL
+-0x94478b76    nat_callforwarding_hook vmlinux EXPORT_SYMBOL_GPL
+-0x6e4b8906    snd_ctl_find_numid      vmlinux EXPORT_SYMBOL
+-0xb6a68816    find_last_bit   vmlinux EXPORT_SYMBOL
+-0xc8d47bdb    inode_dio_done  vmlinux EXPORT_SYMBOL
+-0xb9ca066f    poll_initwait   vmlinux EXPORT_SYMBOL
+-0x193d48e0    trace_current_buffer_unlock_commit      vmlinux EXPORT_SYMBOL_GPL
+-0x46a36032    unregister_console      vmlinux EXPORT_SYMBOL
+-0xd0fbc335    vb2_get_vma     vmlinux EXPORT_SYMBOL_GPL
+-0x6ebd302d    usb_reset_endpoint      vmlinux EXPORT_SYMBOL_GPL
+-0x38a4f7ae    drm_format_num_planes   vmlinux EXPORT_SYMBOL
+-0xc414c422    drm_vblank_offdelay     vmlinux EXPORT_SYMBOL
+-0x96554810    register_keyboard_notifier      vmlinux EXPORT_SYMBOL_GPL
+-0x2ec0f25c    nf_ct_helper_ext_add    vmlinux EXPORT_SYMBOL_GPL
+-0xe745ec59    aead_geniv_free vmlinux EXPORT_SYMBOL_GPL
+-0xd8e484f0    register_chrdev_region  vmlinux EXPORT_SYMBOL
+-0xc58b6dd5    led_trigger_unregister_simple   vmlinux EXPORT_SYMBOL_GPL
+-0x068f1d12    phy_disconnect  vmlinux EXPORT_SYMBOL
+-0x9c518b55    regmap_update_bits      vmlinux EXPORT_SYMBOL_GPL
+-0xc63f1b81    ieee80211_radiotap_iterator_next        vmlinux EXPORT_SYMBOL
+-0x9744e080    inet_csk_reqsk_queue_prune      vmlinux EXPORT_SYMBOL_GPL
+-0xb9ff0fd7    netdev_state_change     vmlinux EXPORT_SYMBOL
+-0x310917fe    sort    vmlinux EXPORT_SYMBOL
+-0xa8fef7bb    security_unix_may_send  vmlinux EXPORT_SYMBOL
+-0x541bd60a    irq_work_run    vmlinux EXPORT_SYMBOL_GPL
+-0x6c49c4f2    clockevents_notify      vmlinux EXPORT_SYMBOL_GPL
+-0xe208ea98    hci_recv_stream_fragment        vmlinux EXPORT_SYMBOL
+-0xe6c68334    ddebug_remove_module    vmlinux EXPORT_SYMBOL_GPL
+-0xf8ae0cbf    kern_path       vmlinux EXPORT_SYMBOL
+-0x6e9dd7bc    usb_sg_cancel   vmlinux EXPORT_SYMBOL_GPL
+-0x7c05fd17    nf_register_queue_handler       vmlinux EXPORT_SYMBOL
+-0x2a8db409    snd_soc_dai_set_tristate        vmlinux EXPORT_SYMBOL_GPL
+-0x29b1c366    __sg_alloc_table        vmlinux EXPORT_SYMBOL
+-0x9c3889f4    shrink_dcache_sb        vmlinux EXPORT_SYMBOL
+-0x15692c87    param_ops_int   vmlinux EXPORT_SYMBOL
+-0xd04e04f7    iio_update_demux        vmlinux EXPORT_SYMBOL_GPL
+-0x105a7a58    dma_alloc_from_coherent vmlinux EXPORT_SYMBOL
+-0xe4309905    syscore_resume  vmlinux EXPORT_SYMBOL_GPL
+-0xab482a65    blkdev_issue_flush      vmlinux EXPORT_SYMBOL
+-0x499043d3    crypto_init_queue       vmlinux EXPORT_SYMBOL_GPL
+-0xca871be2    default_backing_dev_info        vmlinux EXPORT_SYMBOL_GPL
+-0x3d5120d1    st_accel_common_probe   vmlinux EXPORT_SYMBOL
+-0x44f5e8b5    of_allnodes     vmlinux EXPORT_SYMBOL
+-0xf563353a    v4l2_subdev_link_validate       vmlinux EXPORT_SYMBOL_GPL
+-0x011cf028    regulator_suspend_finish        vmlinux EXPORT_SYMBOL_GPL
+-0x1b88e3fa    find_inode_number       vmlinux EXPORT_SYMBOL
+-0xb2d307de    param_ops_short vmlinux EXPORT_SYMBOL
+-0x0b586662    drm_gem_object_init     vmlinux EXPORT_SYMBOL
+-0xaad6d92f    rfkill_init_sw_state    vmlinux EXPORT_SYMBOL
+-0x4f4d4dc8    hci_unregister_dev      vmlinux EXPORT_SYMBOL
+-0xa6970398    __kfifo_to_user_r       vmlinux EXPORT_SYMBOL
+-0xf7f92f26    st_sensors_set_enable   vmlinux EXPORT_SYMBOL
+-0x236bcb52    unregister_con_driver   vmlinux EXPORT_SYMBOL
+-0x39898017    amba_device_put vmlinux EXPORT_SYMBOL_GPL
+-0x8d28fc98    amba_device_add vmlinux EXPORT_SYMBOL_GPL
+-0x3169d518    softnet_data    vmlinux EXPORT_SYMBOL
+-0x5fc56a46    _raw_spin_unlock        vmlinux EXPORT_SYMBOL
+-0xfe5d4bb2    sys_tz  vmlinux EXPORT_SYMBOL
+-0x81ced62d    ip6_sk_redirect vmlinux EXPORT_SYMBOL_GPL
+-0x9ffa3a75    netdev_max_backlog      vmlinux EXPORT_SYMBOL
+-0xfa237e15    __skb_tx_hash   vmlinux EXPORT_SYMBOL
+-0x1b701804    blk_init_queue  vmlinux EXPORT_SYMBOL
+-0x474d3122    unlock_page     vmlinux EXPORT_SYMBOL
+-0x4f98d766    cpu_pm_unregister_notifier      vmlinux EXPORT_SYMBOL_GPL
+-0x76963409    lock_fb_info    vmlinux EXPORT_SYMBOL
+-0x11e2ec12    flex_array_free_parts   vmlinux EXPORT_SYMBOL
+-0x5ecb52ac    sdio_memcpy_fromio      vmlinux EXPORT_SYMBOL_GPL
+-0xa4480afe    drm_sysfs_hotplug_event vmlinux EXPORT_SYMBOL
+-0xeaab7f82    lcd_device_register     vmlinux EXPORT_SYMBOL
+-0x0c12eee9    xfrm_unregister_type    vmlinux EXPORT_SYMBOL
+-0x297f1a00    nf_ip_checksum  vmlinux EXPORT_SYMBOL
+-0xd14bc4d9    sock_diag_save_cookie   vmlinux EXPORT_SYMBOL_GPL
+-0xdd810ba9    snd_info_register       vmlinux EXPORT_SYMBOL
+-0x773a9c94    blk_iopoll_enabled      vmlinux EXPORT_SYMBOL
+-0xd704f458    jbd2_log_wait_commit    vmlinux EXPORT_SYMBOL
+-0x22e82b9e    hrtimer_init_sleeper    vmlinux EXPORT_SYMBOL_GPL
+-0x437e0518    eth_rebuild_header      vmlinux EXPORT_SYMBOL
+-0x47fb2e90    neigh_compat_output     vmlinux EXPORT_SYMBOL
+-0x0283dfe3    _snd_pcm_hw_params_any  vmlinux EXPORT_SYMBOL
+-0xe2407fb6    user_path_at    vmlinux EXPORT_SYMBOL
+-0x35d93ce8    cgroup_add_cftypes      vmlinux EXPORT_SYMBOL_GPL
+-0x4ac62273    module_put      vmlinux EXPORT_SYMBOL
+-0x2459bbcc    console_set_on_cmdline  vmlinux EXPORT_SYMBOL
+-0xbec530ad    max8997_update_reg      vmlinux EXPORT_SYMBOL_GPL
+-0x3255972d    hdmi_vendor_infoframe_pack      vmlinux EXPORT_SYMBOL
+-0x8da61397    ip_tunnel_rcv   vmlinux EXPORT_SYMBOL_GPL
+-0x3c44f68c    inode_get_bytes vmlinux EXPORT_SYMBOL
+-0xd85cd67e    __wake_up       vmlinux EXPORT_SYMBOL
+-0xcefe5c3b    usb_get_from_anchor     vmlinux EXPORT_SYMBOL_GPL
+-0x9a858808    genphy_resume   vmlinux EXPORT_SYMBOL
+-0x606ae2bc    drm_mm_debug_table      vmlinux EXPORT_SYMBOL
+-0xed636ddf    nf_conntrack_helper_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0xc7a1840e    llist_add_batch vmlinux EXPORT_SYMBOL_GPL
+-0x2787db00    vbin_printf     vmlinux EXPORT_SYMBOL_GPL
+-0xfe59fc1b    security_d_instantiate  vmlinux EXPORT_SYMBOL
+-0x6b8286e4    bio_reset       vmlinux EXPORT_SYMBOL
+-0x86414ad5    vfs_mkdir       vmlinux EXPORT_SYMBOL
+-0x87b883c7    i2c_for_each_dev        vmlinux EXPORT_SYMBOL_GPL
+-0x26f81b6a    dev_driver_string       vmlinux EXPORT_SYMBOL
+-0x1c787b32    eventfd_ctx_fileget     vmlinux EXPORT_SYMBOL_GPL
+-0x01139ffc    max_mapnr       vmlinux EXPORT_SYMBOL
+-0xec17ebb0    of_match_node   vmlinux EXPORT_SYMBOL
+-0x69ce0071    usb_driver_claim_interface      vmlinux EXPORT_SYMBOL_GPL
+-0x9cfd56c5    scsi_print_status       vmlinux EXPORT_SYMBOL
+-0xdce6abcd    drm_gem_prime_handle_to_fd      vmlinux EXPORT_SYMBOL
+-0x020f03b7    drm_sysfs_connector_remove      vmlinux EXPORT_SYMBOL
+-0x2a8aa04e    pinctrl_add_gpio_range  vmlinux EXPORT_SYMBOL_GPL
+-0x981dcc58    eventfd_fget    vmlinux EXPORT_SYMBOL_GPL
+-0x7c995f04    dget_parent     vmlinux EXPORT_SYMBOL
+-0x9a932b80    of_find_i2c_device_by_node      vmlinux EXPORT_SYMBOL
+-0x2b460363    led_trigger_set vmlinux EXPORT_SYMBOL_GPL
+-0x107733e3    wiphy_new       vmlinux EXPORT_SYMBOL
+-0xd7b7598e    snd_pcm_mmap_data       vmlinux EXPORT_SYMBOL
+-0x4e1636f1    mb_cache_create vmlinux EXPORT_SYMBOL
+-0x70bec618    iunique vmlinux EXPORT_SYMBOL
+-0x121d958a    unregister_die_notifier vmlinux EXPORT_SYMBOL_GPL
+-0xbef4c852    hid_dump_input  vmlinux EXPORT_SYMBOL_GPL
+-0x55423fc4    dm_requeue_unmapped_request     vmlinux EXPORT_SYMBOL_GPL
+-0x2e67fc27    matrix_keypad_build_keymap      vmlinux EXPORT_SYMBOL
+-0xe7c7c6b0    usb_disable_autosuspend vmlinux EXPORT_SYMBOL_GPL
+-0x783194cd    usb_get_dev     vmlinux EXPORT_SYMBOL_GPL
+-0x5614b010    xfrm_policy_walk_done   vmlinux EXPORT_SYMBOL
+-0x6d5a6c10    inet_dgram_ops  vmlinux EXPORT_SYMBOL
+-0x42e7ca3d    blk_alloc_queue vmlinux EXPORT_SYMBOL
+-0xfdbd0a9b    mb_cache_destroy        vmlinux EXPORT_SYMBOL
+-0x59cbc3ca    input_release_device    vmlinux EXPORT_SYMBOL
+-0xd0e5d6d2    scsi_put_command        vmlinux EXPORT_SYMBOL
+-0x480dca40    sec_reg_update  vmlinux EXPORT_SYMBOL_GPL
+-0x28a73d8e    snd_soc_unregister_card vmlinux EXPORT_SYMBOL_GPL
+-0x05fc144e    get_gendisk     vmlinux EXPORT_SYMBOL
+-0xfef8a166    trace_current_buffer_lock_reserve       vmlinux EXPORT_SYMBOL_GPL
+-0x7dccc294    proc_doulongvec_minmax  vmlinux EXPORT_SYMBOL
+-0x92c0c538    ieee80211_bss_get_ie    vmlinux EXPORT_SYMBOL
+-0x386ec802    tcp_proc_unregister     vmlinux EXPORT_SYMBOL
+-0xb327256f    simple_attr_open        vmlinux EXPORT_SYMBOL_GPL
+-0x56e9103b    cpu_pm_enter    vmlinux EXPORT_SYMBOL_GPL
+-0x1e48b59d    __css_tryget    vmlinux EXPORT_SYMBOL_GPL
+-0xbcbaa80a    __wake_up_locked_key    vmlinux EXPORT_SYMBOL_GPL
+-0x2d1b02d2    usermodehelper_read_lock_wait   vmlinux EXPORT_SYMBOL_GPL
+-0x72bfae4f    hwmon_device_register   vmlinux EXPORT_SYMBOL_GPL
+-0x3db7f213    v4l2_of_get_remote_port vmlinux EXPORT_SYMBOL
+-0x5de3f132    usb_interface_id        vmlinux EXPORT_SYMBOL_GPL
+-0x9ca5592b    usb_store_new_id        vmlinux EXPORT_SYMBOL_GPL
+-0x90fb0fa6    sdev_evt_send_simple    vmlinux EXPORT_SYMBOL_GPL
+-0x25892d59    drm_vblank_post_modeset vmlinux EXPORT_SYMBOL
+-0x8ecafd4a    drm_fb_helper_blank     vmlinux EXPORT_SYMBOL
+-0x590d45c1    sk_clear_memalloc       vmlinux EXPORT_SYMBOL_GPL
+-0x4578f528    __kfifo_to_user vmlinux EXPORT_SYMBOL
+-0xf7ddfd4e    done_path_create        vmlinux EXPORT_SYMBOL
+-0x85c10896    rcu_batches_completed_bh        vmlinux EXPORT_SYMBOL_GPL
+-0x036dd11a    cgroup_path     vmlinux EXPORT_SYMBOL_GPL
+-0xcc7fa952    local_bh_enable_ip      vmlinux EXPORT_SYMBOL
+-0xa90054ee    rndis_uninit    vmlinux EXPORT_SYMBOL
+-0x15407a03    usb_root_hub_lost_power vmlinux EXPORT_SYMBOL_GPL
+-0x06fc143d    xfrm4_rcv_encap vmlinux EXPORT_SYMBOL
+-0xa0c5538e    udp_poll        vmlinux EXPORT_SYMBOL
+-0xd9f41f16    skb_copy_ubufs  vmlinux EXPORT_SYMBOL_GPL
+-0xc83b4d5b    posix_acl_from_mode     vmlinux EXPORT_SYMBOL
+-0x51ef33b8    kstrndup        vmlinux EXPORT_SYMBOL
+-0x0bed814c    irq_set_chip    vmlinux EXPORT_SYMBOL
+-0xd0f6cf25    console_stop    vmlinux EXPORT_SYMBOL
+-0xd955eb7d    iommu_group_remove_device       vmlinux EXPORT_SYMBOL_GPL
+-0xfb5dc251    gserial_disconnect      vmlinux EXPORT_SYMBOL_GPL
+-0x42252607    inet6_getname   vmlinux EXPORT_SYMBOL
+-0xe65b1e97    nf_conntrack_tuple_taken        vmlinux EXPORT_SYMBOL_GPL
+-0x7abbee1e    wm_hubs_handle_analogue_pdata   vmlinux EXPORT_SYMBOL_GPL
+-0x06dceffb    snd_soc_of_parse_daifmt vmlinux EXPORT_SYMBOL_GPL
+-0xf4439247    snd_device_register     vmlinux EXPORT_SYMBOL
+-0xebcea57f    evict_bh_lrus   vmlinux EXPORT_SYMBOL_GPL
+-0x9714253c    mfd_add_devices vmlinux EXPORT_SYMBOL
+-0x26256356    drm_mode_equal_no_clocks        vmlinux EXPORT_SYMBOL
+-0x1be7f7c8    debugfs_create_file     vmlinux EXPORT_SYMBOL_GPL
+-0xdbb607c7    new_inode       vmlinux EXPORT_SYMBOL
+-0xa576c92e    drm_mode_config_reset   vmlinux EXPORT_SYMBOL
+-0x832ca829    snd_ctl_find_id vmlinux EXPORT_SYMBOL
+-0x65dccf13    xz_dec_end      vmlinux EXPORT_SYMBOL
+-0xf9348cbc    xz_dec_run      vmlinux EXPORT_SYMBOL
+-0xe0b13336    argv_free       vmlinux EXPORT_SYMBOL
+-0x8815b870    jbd2_journal_clear_err  vmlinux EXPORT_SYMBOL
+-0x861359ed    of_get_phy_mode vmlinux EXPORT_SYMBOL_GPL
+-0x28a2ed02    scsi_build_sense_buffer vmlinux EXPORT_SYMBOL
+-0x86240fb6    tty_port_close  vmlinux EXPORT_SYMBOL
+-0x8d3e24c6    genl_unregister_family  vmlinux EXPORT_SYMBOL
+-0x9d0d6206    unregister_netdevice_notifier   vmlinux EXPORT_SYMBOL
+-0x18640d1b    mmc_suspend_host        vmlinux EXPORT_SYMBOL
+-0x9082ce2b    tty_register_driver     vmlinux EXPORT_SYMBOL
+-0x71f65175    hdmi_spd_infoframe_pack vmlinux EXPORT_SYMBOL
+-0x3d6f0d06    ndo_dflt_fdb_del        vmlinux EXPORT_SYMBOL
+-0xaeefbeed    kset_unregister vmlinux EXPORT_SYMBOL
+-0xa498b92e    debugfs_create_u32      vmlinux EXPORT_SYMBOL_GPL
+-0x7ed8eb88    sdio_release_host       vmlinux EXPORT_SYMBOL_GPL
+-0xd1e4eed4    v4l2_fh_init    vmlinux EXPORT_SYMBOL_GPL
+-0x5b42ed42    v4l2_fh_exit    vmlinux EXPORT_SYMBOL_GPL
+-0x5947abbe    max77693_bulk_write     vmlinux EXPORT_SYMBOL_GPL
+-0x7afa1fc2    driver_remove_file      vmlinux EXPORT_SYMBOL_GPL
+-0xacefc84d    netdev_rx_handler_register      vmlinux EXPORT_SYMBOL_GPL
+-0xd2e829b5    jbd2_journal_release_jbd_inode  vmlinux EXPORT_SYMBOL
+-0xcd343f41    mmc_gpio_free_ro        vmlinux EXPORT_SYMBOL
+-0x26f37f1a    inet_csk_reset_keepalive_timer  vmlinux EXPORT_SYMBOL
+-0x49603fb8    security_sb_copy_data   vmlinux EXPORT_SYMBOL
+-0x53326531    mempool_alloc_pages     vmlinux EXPORT_SYMBOL
+-0x2b49351d    trace_define_field      vmlinux EXPORT_SYMBOL_GPL
+-0x47939e0d    __tasklet_hi_schedule   vmlinux EXPORT_SYMBOL
+-0x78c5a239    clk_prepare     vmlinux EXPORT_SYMBOL_GPL
+-0x1a36f8fd    udc_attach_driver       vmlinux EXPORT_SYMBOL_GPL
+-0xcb56fc45    dev_vprintk_emit        vmlinux EXPORT_SYMBOL
+-0xed2817be    arp_send        vmlinux EXPORT_SYMBOL
+-0x7d903146    xt_register_matches     vmlinux EXPORT_SYMBOL
+-0x3ed63055    zlib_inflateReset       vmlinux EXPORT_SYMBOL
+-0x281823c5    __kfifo_out_peek        vmlinux EXPORT_SYMBOL
+-0xb19760c3    bitmap_onto     vmlinux EXPORT_SYMBOL
+-0xaf9b8476    cdev_del        vmlinux EXPORT_SYMBOL
+-0xbc8da552    tcp_seq_open    vmlinux EXPORT_SYMBOL
+-0x35224ff2    pneigh_enqueue  vmlinux EXPORT_SYMBOL
+-0x0d2e0ab9    dev_alloc_name  vmlinux EXPORT_SYMBOL
+-0xebd8aaa8    iov_iter_copy_from_user vmlinux EXPORT_SYMBOL
+-0x134dc23b    v4l2_m2m_dqbuf  vmlinux EXPORT_SYMBOL_GPL
+-0x1cfa672b    soft_cursor     vmlinux EXPORT_SYMBOL
+-0xac8f37b2    outer_cache     vmlinux EXPORT_SYMBOL
+-0x744bfef9    generic_fh_to_dentry    vmlinux EXPORT_SYMBOL_GPL
+-0xa3225eb1    try_to_del_timer_sync   vmlinux EXPORT_SYMBOL
+-0x6a1733eb    iommu_group_unregister_notifier vmlinux EXPORT_SYMBOL_GPL
+-0xc84dae86    matrix_keypad_parse_of_params   vmlinux EXPORT_SYMBOL_GPL
+-0x404403a9    usb_free_all_descriptors        vmlinux EXPORT_SYMBOL_GPL
+-0x50eca283    ipcomp_output   vmlinux EXPORT_SYMBOL_GPL
+-0xe482d673    nf_ct_expect_related_report     vmlinux EXPORT_SYMBOL_GPL
+-0x26e58975    __pskb_copy     vmlinux EXPORT_SYMBOL
+-0xd3dcab0b    flex_array_alloc        vmlinux EXPORT_SYMBOL
+-0x247f1878    blk_queue_bounce        vmlinux EXPORT_SYMBOL
+-0x97b13dad    __clocksource_register_scale    vmlinux EXPORT_SYMBOL_GPL
+-0xdc73e48f    dm_unregister_target    vmlinux EXPORT_SYMBOL
+-0xfe0f06c0    tty_init_termios        vmlinux EXPORT_SYMBOL_GPL
+-0xb8356d30    dma_async_memcpy_buf_to_pg      vmlinux EXPORT_SYMBOL
+-0xd8d3cf00    read_dev_sector vmlinux EXPORT_SYMBOL
+-0x220669c4    scsi_cmd_blk_ioctl      vmlinux EXPORT_SYMBOL
+-0x03c91b88    crypto_alloc_instance2  vmlinux EXPORT_SYMBOL_GPL
+-0x4d9c0e6d    jbd2_journal_revoke     vmlinux EXPORT_SYMBOL
+-0xaca5e909    config_group_find_item  vmlinux EXPORT_SYMBOL
+-0xe01ba49b    iio_kfifo_allocate      vmlinux EXPORT_SYMBOL
+-0xe170917a    timed_output_dev_unregister     vmlinux EXPORT_SYMBOL_GPL
+-0x4f689046    brcmu_pkt_buf_free_skb  drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x932f03cb    security_old_inode_init_security        vmlinux EXPORT_SYMBOL
+-0xa4e5092b    debugfs_create_x16      vmlinux EXPORT_SYMBOL_GPL
+-0x1826f089    __tracepoint_kmem_cache_alloc_node      vmlinux EXPORT_SYMBOL
+-0xd81de62c    ring_buffer_record_enable       vmlinux EXPORT_SYMBOL_GPL
+-0xc7fe94dd    usb_ifnum_to_if vmlinux EXPORT_SYMBOL_GPL
+-0xc2af811e    inet6_destroy_sock      vmlinux EXPORT_SYMBOL_GPL
+-0x061651be    strcat  vmlinux EXPORT_SYMBOL
+-0xb39ec138    mb_cache_entry_release  vmlinux EXPORT_SYMBOL
+-0x51d559d1    _raw_spin_unlock_irqrestore     vmlinux EXPORT_SYMBOL
+-0xa6eb0e39    phy_device_create       vmlinux EXPORT_SYMBOL
+-0xf92c66be    drm_mm_search_free_generic      vmlinux EXPORT_SYMBOL
+-0x97270fcf    crypto_register_shash   vmlinux EXPORT_SYMBOL_GPL
+-0x495f2be4    jbd2_journal_get_write_access   vmlinux EXPORT_SYMBOL
+-0x3826f483    jbd2_journal_invalidatepage     vmlinux EXPORT_SYMBOL
+-0xd8a12f4d    iio_scan_mask_query     vmlinux EXPORT_SYMBOL_GPL
+-0x09b069ea    v4l2_ctrl_log_status    vmlinux EXPORT_SYMBOL
+-0x0a513c7c    usb_gadget_unregister_driver    vmlinux EXPORT_SYMBOL_GPL
+-0x39ef8cc9    dma_buf_kunmap  vmlinux EXPORT_SYMBOL_GPL
+-0xd28b5dda    dma_buf_vunmap  vmlinux EXPORT_SYMBOL_GPL
+-0x3fcf2826    inet6_unregister_protosw        vmlinux EXPORT_SYMBOL
+-0x551c3633    nf_nat_l4proto_unique_tuple     vmlinux EXPORT_SYMBOL_GPL
+-0x86700640    nf_register_hooks       vmlinux EXPORT_SYMBOL
+-0x44e94d6c    pfifo_qdisc_ops vmlinux EXPORT_SYMBOL
+-0xf202c5cb    radix_tree_insert       vmlinux EXPORT_SYMBOL
+-0x24ffe755    vfs_listxattr   vmlinux EXPORT_SYMBOL_GPL
+-0x52428cc8    parent_mem_cgroup       vmlinux EXPORT_SYMBOL
+-0x9d59c0f2    find_get_pages_contig   vmlinux EXPORT_SYMBOL
+-0x80f3268f    __trace_printk  vmlinux EXPORT_SYMBOL_GPL
+-0x22a27a85    st_sensors_spi_configure        vmlinux EXPORT_SYMBOL
+-0x7880c781    dm_kcopyd_prepare_callback      vmlinux EXPORT_SYMBOL
+-0xc53f0876    vb2_dma_contig_memops   vmlinux EXPORT_SYMBOL_GPL
+-0x388f9128    xfrm_state_walk_done    vmlinux EXPORT_SYMBOL
+-0x6d6888a7    qdisc_create_dflt       vmlinux EXPORT_SYMBOL
+-0x194ccf46    bmap    vmlinux EXPORT_SYMBOL
+-0xe2fae716    kmemdup vmlinux EXPORT_SYMBOL
+-0x07ed48c3    __blocking_notifier_call_chain  vmlinux EXPORT_SYMBOL_GPL
+-0x074d7047    st_sensors_trigger_handler      vmlinux EXPORT_SYMBOL
+-0x33883929    clk_divider_ops vmlinux EXPORT_SYMBOL_GPL
+-0xe2b92059    v4l2_video_std_construct        vmlinux EXPORT_SYMBOL
+-0x06ea1593    usbnet_defer_kevent     vmlinux EXPORT_SYMBOL_GPL
+-0x6650ad3e    uart_add_one_port       vmlinux EXPORT_SYMBOL
+-0x5dda183c    snd_soc_dapm_disable_pin        vmlinux EXPORT_SYMBOL_GPL
+-0x7a188791    prandom_bytes   vmlinux EXPORT_SYMBOL
+-0xc25a61ec    drm_mode_set_crtcinfo   vmlinux EXPORT_SYMBOL
+-0xcb1beab5    drm_mode_vrefresh       vmlinux EXPORT_SYMBOL
+-0x4a94168c    tcp_register_congestion_control vmlinux EXPORT_SYMBOL_GPL
+-0x4f5836c8    tcp_release_cb  vmlinux EXPORT_SYMBOL
+-0x2f366d34    tcp_gro_complete        vmlinux EXPORT_SYMBOL
+-0x1eba8ee6    nf_conntrack_alloc      vmlinux EXPORT_SYMBOL_GPL
+-0x28a903c8    timerqueue_add  vmlinux EXPORT_SYMBOL_GPL
+-0x96cea50b    sync_filesystem vmlinux EXPORT_SYMBOL_GPL
+-0x68c0685a    media_entity_setup_link vmlinux EXPORT_SYMBOL_GPL
+-0x69b83c18    usb_get_phy_dev vmlinux EXPORT_SYMBOL_GPL
+-0x7e6bf1b2    dma_buf_fd      vmlinux EXPORT_SYMBOL_GPL
+-0x4d974b9c    register_sysrq_key      vmlinux EXPORT_SYMBOL
+-0xf79531f4    tcp_connect     vmlinux EXPORT_SYMBOL
+-0x3f45ea36    neigh_table_clear       vmlinux EXPORT_SYMBOL
+-0xf6de842c    clk_get_parent  vmlinux EXPORT_SYMBOL_GPL
+-0x4782eebf    clk_set_parent  vmlinux EXPORT_SYMBOL_GPL
+-0x45a20c5a    of_phy_find_device      vmlinux EXPORT_SYMBOL
+-0xcbbedfcb    led_trigger_event       vmlinux EXPORT_SYMBOL_GPL
+-0x69281b40    thermal_zone_bind_cooling_device        vmlinux EXPORT_SYMBOL_GPL
+-0xe122af95    xfrm_aalg_get_byname    vmlinux EXPORT_SYMBOL_GPL
+-0x74b1375e    xfrm_state_flush        vmlinux EXPORT_SYMBOL
+-0x94098ff8    snd_interval_list       vmlinux EXPORT_SYMBOL
+-0x64f01d42    fuse_put_request        vmlinux EXPORT_SYMBOL_GPL
+-0x1811ac2f    fat_flush_inodes        vmlinux EXPORT_SYMBOL_GPL
+-0x73198f14    mmc_align_data_size     vmlinux EXPORT_SYMBOL
+-0xa70df32d    drm_fb_helper_fill_var  vmlinux EXPORT_SYMBOL
+-0x209e95ea    xfrm_find_acq_byseq     vmlinux EXPORT_SYMBOL
+-0x4b9e2d58    xfrm_policy_unregister_afinfo   vmlinux EXPORT_SYMBOL
+-0x461a1d6a    __rtnl_af_register      vmlinux EXPORT_SYMBOL_GPL
+-0x09c55cec    schedule_timeout_interruptible  vmlinux EXPORT_SYMBOL
+-0xf512c668    iio_trigger_free        vmlinux EXPORT_SYMBOL
+-0xdac28b43    dw_mci_resume   vmlinux EXPORT_SYMBOL
+-0x361e2bcc    save_stack_trace        vmlinux EXPORT_SYMBOL_GPL
+-0x25e6af56    snd_compress_register   vmlinux EXPORT_SYMBOL_GPL
+-0x1ace138d    bitmap_allocate_region  vmlinux EXPORT_SYMBOL
+-0x250113b4    memory_read_from_buffer vmlinux EXPORT_SYMBOL
+-0x4ae22649    iommu_set_fault_handler vmlinux EXPORT_SYMBOL_GPL
+-0x3ca38e3a    rndis_signal_connect    vmlinux EXPORT_SYMBOL
+-0x9d01b017    dma_buf_attach  vmlinux EXPORT_SYMBOL_GPL
+-0x3930a5b6    dma_buf_detach  vmlinux EXPORT_SYMBOL_GPL
+-0x2aec4354    hci_alloc_dev   vmlinux EXPORT_SYMBOL
+-0xbb5d343d    xfrm_get_acqseq vmlinux EXPORT_SYMBOL
+-0x4082abfe    __scsi_iterate_devices  vmlinux EXPORT_SYMBOL
+-0x6b6d7375    drm_timestamp_precision vmlinux EXPORT_SYMBOL
+-0x7ffcb57f    ip6_tnl_get_cap vmlinux EXPORT_SYMBOL
+-0xccc812c3    dapm_clock_event        vmlinux EXPORT_SYMBOL_GPL
+-0x1a47bf65    blk_queue_bounce_limit  vmlinux EXPORT_SYMBOL
+-0xcc13c782    vb2_ioctl_streamon      vmlinux EXPORT_SYMBOL_GPL
+-0x8afddc98    spi_register_driver     vmlinux EXPORT_SYMBOL_GPL
+-0x17ae6853    platform_bus    vmlinux EXPORT_SYMBOL_GPL
+-0x72ac0290    exynos_drm_device_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0xf71ca112    skb_abort_seq_read      vmlinux EXPORT_SYMBOL
+-0x18bbe186    snd_soc_cnew    vmlinux EXPORT_SYMBOL_GPL
+-0x2b0ba2b0    scsi_sense_desc_find    vmlinux EXPORT_SYMBOL
+-0x8de13715    drm_format_vert_chroma_subsampling      vmlinux EXPORT_SYMBOL
+-0x06fe3b14    default_grn     vmlinux EXPORT_SYMBOL
+-0xee683d16    inet6_ioctl     vmlinux EXPORT_SYMBOL
+-0x47252a20    tcp_getsockopt  vmlinux EXPORT_SYMBOL
+-0x7027c3ad    tcp_setsockopt  vmlinux EXPORT_SYMBOL
+-0xb7f74966    rtnl_unicast    vmlinux EXPORT_SYMBOL
+-0x525971d4    snd_soc_update_bits_locked      vmlinux EXPORT_SYMBOL_GPL
+-0x6ef8fcd8    snd_pcm_format_linear   vmlinux EXPORT_SYMBOL
+-0x8f8f6e19    alloc_disk_node vmlinux EXPORT_SYMBOL
+-0x71c445f5    fuse_get_req    vmlinux EXPORT_SYMBOL_GPL
+-0xc41cff79    dequeue_signal  vmlinux EXPORT_SYMBOL_GPL
+-0x5d9d3491    v4l_match_dv_timings    vmlinux EXPORT_SYMBOL_GPL
+-0x829a8cac    drm_property_create_range       vmlinux EXPORT_SYMBOL
+-0xf3189246    __rtnl_af_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0x0d7e8390    crypto_ablkcipher_type  vmlinux EXPORT_SYMBOL_GPL
+-0xaf8e1608    ip6t_register_table     vmlinux EXPORT_SYMBOL
+-0xb1a1e40e    crypto_tfm_in_queue     vmlinux EXPORT_SYMBOL_GPL
+-0xc73f3f9a    fget_raw        vmlinux EXPORT_SYMBOL
+-0x71008581    atomic_notifier_call_chain      vmlinux EXPORT_SYMBOL_GPL
+-0x12bf1d5c    usbnet_device_suggests_idle     vmlinux EXPORT_SYMBOL
+-0x79b993ef    cfg80211_send_unprot_deauth     vmlinux EXPORT_SYMBOL
+-0xdacc53b2    spi_add_device  vmlinux EXPORT_SYMBOL_GPL
+-0xf5a5c913    backlight_device_unregister     vmlinux EXPORT_SYMBOL
+-0xadce320f    pinctrl_add_gpio_ranges vmlinux EXPORT_SYMBOL_GPL
+-0x0f8342e1    phy_pm_runtime_forbid   vmlinux EXPORT_SYMBOL_GPL
+-0xc0763484    rfkill_blocked  vmlinux EXPORT_SYMBOL
+-0xb0bad0e8    ip6_push_pending_frames vmlinux EXPORT_SYMBOL_GPL
+-0xfc02b7ad    sysctl_tcp_wmem vmlinux EXPORT_SYMBOL
+-0xac782342    nf_unregister_hook      vmlinux EXPORT_SYMBOL
+-0xa08421e0    dev_change_net_namespace        vmlinux EXPORT_SYMBOL_GPL
+-0x47c6d038    blk_queue_flush_queueable       vmlinux EXPORT_SYMBOL_GPL
+-0x2db8f309    blk_queue_rq_timeout    vmlinux EXPORT_SYMBOL_GPL
+-0x6fb277a1    flush_kernel_dcache_page        vmlinux EXPORT_SYMBOL
+-0x1d633e6a    tcp_twsk_destructor     vmlinux EXPORT_SYMBOL_GPL
+-0x7611866b    scm_detach_fds  vmlinux EXPORT_SYMBOL
+-0xd3b02cea    put_pid vmlinux EXPORT_SYMBOL_GPL
+-0xed20e404    iio_dealloc_pollfunc    vmlinux EXPORT_SYMBOL_GPL
+-0xba706bd7    samsung_pwm_lock        vmlinux EXPORT_SYMBOL
+-0x158b7724    media_entity_create_link        vmlinux EXPORT_SYMBOL_GPL
+-0x1172ce54    rtc_ktime_to_tm vmlinux EXPORT_SYMBOL_GPL
+-0xa286a234    snd_pcm_format_name     vmlinux EXPORT_SYMBOL_GPL
+-0xc7e39bca    ring_buffer_dropped_events_cpu  vmlinux EXPORT_SYMBOL_GPL
+-0xaa957320    posix_clock_register    vmlinux EXPORT_SYMBOL_GPL
+-0xad46dec2    of_count_phandle_with_args      vmlinux EXPORT_SYMBOL
+-0x7120d717    regmap_bulk_read        vmlinux EXPORT_SYMBOL_GPL
+-0xca56dea4    driver_find_device      vmlinux EXPORT_SYMBOL_GPL
+-0x9c9d19e7    blk_get_request vmlinux EXPORT_SYMBOL
+-0x2c790eff    usbnet_read_cmd_nopm    vmlinux EXPORT_SYMBOL_GPL
+-0xbb99125c    get_default_font        vmlinux EXPORT_SYMBOL
+-0x6e5cf115    cfg80211_inform_bss     vmlinux EXPORT_SYMBOL
+-0xce7a55c1    xfrm_ealg_get_byid      vmlinux EXPORT_SYMBOL_GPL
+-0x0cc1e40f    crypto_it_tab   vmlinux EXPORT_SYMBOL_GPL
+-0x3dc916b6    crypto_fl_tab   vmlinux EXPORT_SYMBOL_GPL
+-0x40d46b21    crypto_ft_tab   vmlinux EXPORT_SYMBOL_GPL
+-0x71dc9998    crypto_il_tab   vmlinux EXPORT_SYMBOL_GPL
+-0x837d0f0a    down_timeout    vmlinux EXPORT_SYMBOL
+-0x2cd7dd71    __cpufreq_driver_getavg vmlinux EXPORT_SYMBOL_GPL
+-0xee6b71c4    syscon_regmap_lookup_by_compatible      vmlinux EXPORT_SYMBOL_GPL
+-0xae77b400    device_pm_wait_for_dev  vmlinux EXPORT_SYMBOL_GPL
+-0x1d5a2494    nfnetlink_has_listeners vmlinux EXPORT_SYMBOL_GPL
+-0x3bd1b1f6    msecs_to_jiffies        vmlinux EXPORT_SYMBOL
+-0xfb09f255    cpufreq_frequency_table_target  vmlinux EXPORT_SYMBOL_GPL
+-0xb52e203b    snd_pcm_suspend_all     vmlinux EXPORT_SYMBOL
+-0xc1ec3550    blkdev_fsync    vmlinux EXPORT_SYMBOL
+-0x0ebe6f54    lookup_one_len  vmlinux EXPORT_SYMBOL
+-0x151404f6    misc_deregister vmlinux EXPORT_SYMBOL
+-0xb2856c71    inet6_bind      vmlinux EXPORT_SYMBOL
+-0xf68285c0    register_inetaddr_notifier      vmlinux EXPORT_SYMBOL
+-0x7afc9d8a    unregister_sound_mixer  vmlinux EXPORT_SYMBOL
+-0xd5d80496    atomic_dec_and_mutex_lock       vmlinux EXPORT_SYMBOL
+-0x4351577a    fb_parse_edid   vmlinux EXPORT_SYMBOL
+-0x68beb163    nf_ct_l3proto_pernet_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x7751fba7    nf_ct_l4proto_pernet_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x5cbe0b31    snd_pcm_lib_write       vmlinux EXPORT_SYMBOL
+-0x6cecc98a    devres_get      vmlinux EXPORT_SYMBOL_GPL
+-0x20925954    devres_add      vmlinux EXPORT_SYMBOL_GPL
+-0x99a9dfa6    ieee80211_data_to_8023  vmlinux EXPORT_SYMBOL
+-0x21036b2c    bt_accept_enqueue       vmlinux EXPORT_SYMBOL
+-0x0cd5a88b    sync_inodes_sb  vmlinux EXPORT_SYMBOL
+-0x7485e15e    unregister_chrdev_region        vmlinux EXPORT_SYMBOL
+-0x7e8ad403    generic_writepages      vmlinux EXPORT_SYMBOL
+-0x07cf3227    clk_fixed_rate_ops      vmlinux EXPORT_SYMBOL_GPL
+-0xf5463be8    led_trigger_blink_oneshot       vmlinux EXPORT_SYMBOL_GPL
+-0xdbf18207    v4l2_device_register_subdev     vmlinux EXPORT_SYMBOL_GPL
+-0x131a5ed7    regmap_del_irq_chip     vmlinux EXPORT_SYMBOL_GPL
+-0xb09c8d37    regmap_add_irq_chip     vmlinux EXPORT_SYMBOL_GPL
+-0x26f0453a    blk_set_default_limits  vmlinux EXPORT_SYMBOL
+-0xf21f8a44    blk_init_allocated_queue        vmlinux EXPORT_SYMBOL
+-0x60df1e3b    posix_acl_equiv_mode    vmlinux EXPORT_SYMBOL
+-0xc131c5dd    usb_add_phy     vmlinux EXPORT_SYMBOL_GPL
+-0x211c5b26    cdc_ncm_bind_common     vmlinux EXPORT_SYMBOL_GPL
+-0x61f6939e    drm_i2c_encoder_detect  vmlinux EXPORT_SYMBOL
+-0xd9f310b2    gpiochip_is_requested   vmlinux EXPORT_SYMBOL_GPL
+-0xb9639d32    rtnl_register   vmlinux EXPORT_SYMBOL_GPL
+-0xf2254dc3    sock_from_file  vmlinux EXPORT_SYMBOL
+-0x0f5455e2    snd_soc_info_enum_double        vmlinux EXPORT_SYMBOL_GPL
+-0xdd89a6bf    lookup_bdev     vmlinux EXPORT_SYMBOL
+-0x55704318    clockevents_config_and_register vmlinux EXPORT_SYMBOL_GPL
+-0x2fd8cba9    freeze_wake     vmlinux EXPORT_SYMBOL_GPL
+-0x071b7eea    irq_stat        vmlinux EXPORT_SYMBOL
+-0x7a8ca627    xfrm_count_pfkey_enc_supported  vmlinux EXPORT_SYMBOL_GPL
+-0x1ff2a733    raw_seq_stop    vmlinux EXPORT_SYMBOL_GPL
+-0x85b825e7    gnet_stats_copy_basic   vmlinux EXPORT_SYMBOL
+-0x0cfefe1e    percpu_counter_destroy  vmlinux EXPORT_SYMBOL
+-0x02ea69e2    vm_map_ram      vmlinux EXPORT_SYMBOL
+-0x36eb3583    filemap_fdatawrite_range        vmlinux EXPORT_SYMBOL
+-0xb977cf42    inet_sendmsg    vmlinux EXPORT_SYMBOL
+-0xddbcead7    ip_cmsg_recv    vmlinux EXPORT_SYMBOL
+-0xb9a64b20    elevator_alloc  vmlinux EXPORT_SYMBOL
+-0xbcaf3971    crypto_alg_sem  vmlinux EXPORT_SYMBOL_GPL
+-0xe71dab2c    bio_sector_offset       vmlinux EXPORT_SYMBOL
+-0x2c44797e    hidinput_report_event   vmlinux EXPORT_SYMBOL_GPL
+-0x5d9e8570    drm_display_mode_from_videomode vmlinux EXPORT_SYMBOL_GPL
+-0x2b8e67cd    fuse_get_req_for_background     vmlinux EXPORT_SYMBOL_GPL
+-0x2b1c6816    extcon_dev_register     vmlinux EXPORT_SYMBOL_GPL
+-0xdef26358    dw_mci_probe    vmlinux EXPORT_SYMBOL
+-0xcbde0d9d    inverse_translate       vmlinux EXPORT_SYMBOL_GPL
+-0x056ee730    ipv6_hash_secret        vmlinux EXPORT_SYMBOL
+-0xfe029963    unregister_inetaddr_notifier    vmlinux EXPORT_SYMBOL
+-0x650a6767    prandom_u32_state       vmlinux EXPORT_SYMBOL
+-0x4148a5ff    get_kernel_pages        vmlinux EXPORT_SYMBOL_GPL
+-0x24d3448d    perf_event_enable       vmlinux EXPORT_SYMBOL_GPL
+-0x1c5a04e0    irq_domain_generate_simple      vmlinux EXPORT_SYMBOL_GPL
+-0xb7b4232a    unregister_exec_domain  vmlinux EXPORT_SYMBOL
+-0xd6f86c04    amba_release_regions    vmlinux EXPORT_SYMBOL
+-0x89d5538d    fb_pad_aligned_buffer   vmlinux EXPORT_SYMBOL
+-0x93237692    nobh_write_begin        vmlinux EXPORT_SYMBOL
+-0x920eb90c    interruptible_sleep_on_timeout  vmlinux EXPORT_SYMBOL
+-0x3a36ce8c    od_register_powersave_bias_handler      vmlinux EXPORT_SYMBOL_GPL
+-0x946b8b6c    netlink_ack     vmlinux EXPORT_SYMBOL
+-0x1000be5b    sock_no_bind    vmlinux EXPORT_SYMBOL
+-0x1e5479ed    sock_get_timestamp      vmlinux EXPORT_SYMBOL
+-0x4211c3c1    zlib_inflateInit2       vmlinux EXPORT_SYMBOL
+-0x2486141e    bio_alloc_pages vmlinux EXPORT_SYMBOL
+-0x62fd6207    param_set_charp vmlinux EXPORT_SYMBOL
+-0x0862d814    v4l2_event_unsubscribe_all      vmlinux EXPORT_SYMBOL_GPL
+-0x2f10e618    v4l2_event_queue_fh     vmlinux EXPORT_SYMBOL_GPL
+-0x6bdcfd99    qdisc_class_hash_remove vmlinux EXPORT_SYMBOL
+-0xf070e888    __put_net       vmlinux EXPORT_SYMBOL_GPL
+-0x8df3789f    snd_oss_info_register   vmlinux EXPORT_SYMBOL
+-0x68c73797    fuse_request_alloc      vmlinux EXPORT_SYMBOL_GPL
+-0x2342f1ae    v4l2_prio_open  vmlinux EXPORT_SYMBOL
+-0x4ddaa6ea    dmam_alloc_noncoherent  vmlinux EXPORT_SYMBOL
+-0x7dfdf9a1    transport_destroy_device        vmlinux EXPORT_SYMBOL_GPL
+-0x8c510862    drm_find_cea_extension  vmlinux EXPORT_SYMBOL
+-0x7c0267ee    serial8250_tx_chars     vmlinux EXPORT_SYMBOL_GPL
+-0x6879e81d    display_entity_put      vmlinux EXPORT_SYMBOL_GPL
+-0xf19a455d    lro_flush_pkt   vmlinux EXPORT_SYMBOL
+-0xbf8ba54a    vprintk vmlinux EXPORT_SYMBOL
+-0x7bd1de14    thermal_cdev_update     vmlinux EXPORT_SYMBOL
+-0x2631d719    tty_unregister_device   vmlinux EXPORT_SYMBOL
+-0xa7e7f050    __udp4_lib_lookup       vmlinux EXPORT_SYMBOL_GPL
+-0x2e2ce9e0    sysctl_tcp_syncookies   vmlinux EXPORT_SYMBOL
+-0xd5a8fd58    tcp_poll        vmlinux EXPORT_SYMBOL
+-0x3f74afb9    nf_ct_l3proto_register  vmlinux EXPORT_SYMBOL_GPL
+-0xb4998fd0    nf_ct_l4proto_register  vmlinux EXPORT_SYMBOL_GPL
+-0x2482e688    vsprintf        vmlinux EXPORT_SYMBOL
+-0x59e4b703    generic_splice_sendpage vmlinux EXPORT_SYMBOL
+-0x1795a16b    __genl_register_family_with_ops vmlinux EXPORT_SYMBOL
+-0xcb469d2b    ddebug_add_module       vmlinux EXPORT_SYMBOL_GPL
+-0xa2d83f8b    grab_cache_page_write_begin     vmlinux EXPORT_SYMBOL
+-0x8c930a68    rt_mutex_lock_interruptible     vmlinux EXPORT_SYMBOL_GPL
+-0xcc0871f2    attribute_container_find_class_device   vmlinux EXPORT_SYMBOL_GPL
+-0x13b52797    pwm_request_from_chip   vmlinux EXPORT_SYMBOL_GPL
+-0x28118cb6    __get_user_1    vmlinux EXPORT_SYMBOL
+-0xbb72d4fe    __put_user_1    vmlinux EXPORT_SYMBOL
+-0x0cae232b    utf16s_to_utf8s vmlinux EXPORT_SYMBOL
+-0x617a218d    __cond_resched_lock     vmlinux EXPORT_SYMBOL
+-0x44224883    __put_task_struct       vmlinux EXPORT_SYMBOL_GPL
+-0xbc65845b    class_create_file       vmlinux EXPORT_SYMBOL_GPL
+-0xe459c49b    unregister_pernet_subsys        vmlinux EXPORT_SYMBOL_GPL
+-0xd882a162    wait_on_sync_kiocb      vmlinux EXPORT_SYMBOL
+-0x28acb0e5    simple_write_begin      vmlinux EXPORT_SYMBOL
+-0x5c1cb07e    redirty_page_for_writepage      vmlinux EXPORT_SYMBOL
+-0x6070a6fb    bdi_set_max_ratio       vmlinux EXPORT_SYMBOL
+-0xfee43a69    drm_dp_get_adjust_request_voltage       vmlinux EXPORT_SYMBOL
+-0x8ffe7e89    nf_conntrack_htable_size        vmlinux EXPORT_SYMBOL_GPL
+-0x79c527b0    netdev_emerg    vmlinux EXPORT_SYMBOL
+-0x0bc7142a    sk_stream_kill_queues   vmlinux EXPORT_SYMBOL
+-0xeb37101c    audit_log_end   vmlinux EXPORT_SYMBOL
+-0xc3577d50    dev_set_name    vmlinux EXPORT_SYMBOL_GPL
+-0x6d40a921    need_ipv4_conntrack     vmlinux EXPORT_SYMBOL_GPL
+-0x6b98f5bd    __sk_dst_check  vmlinux EXPORT_SYMBOL
+-0x003ed69a    __kfifo_dma_in_prepare  vmlinux EXPORT_SYMBOL
+-0xd27b25dd    blk_check_plugged       vmlinux EXPORT_SYMBOL
+-0x9e093f78    elv_register_queue      vmlinux EXPORT_SYMBOL
+-0x716265c7    debugfs_initialized     vmlinux EXPORT_SYMBOL_GPL
+-0x8e19dd86    of_platform_populate    vmlinux EXPORT_SYMBOL_GPL
+-0x2a4ee199    v4l2_m2m_job_finish     vmlinux EXPORT_SYMBOL
+-0x8c62225c    usb_queue_reset_device  vmlinux EXPORT_SYMBOL_GPL
+-0x1e837252    drm_mm_scan_add_block   vmlinux EXPORT_SYMBOL
+-0x6c9424d9    snd_pcm_lib_preallocate_pages   vmlinux EXPORT_SYMBOL
+-0x4c759827    byte_rev_table  vmlinux EXPORT_SYMBOL_GPL
+-0xdf7090e0    __elv_add_request       vmlinux EXPORT_SYMBOL
+-0x911010cb    skcipher_geniv_init     vmlinux EXPORT_SYMBOL_GPL
+-0x9bd700dd    set_bh_page     vmlinux EXPORT_SYMBOL
+-0x13a2a2e3    free_user_ns    vmlinux EXPORT_SYMBOL
+-0x4fe8770d    usb_interrupt_msg       vmlinux EXPORT_SYMBOL_GPL
+-0x0d7dd3fc    pm_generic_runtime_resume       vmlinux EXPORT_SYMBOL_GPL
+-0x3df0b6c5    bus_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0x131f636c    nf_nat_l4proto_in_range vmlinux EXPORT_SYMBOL_GPL
+-0xe6643a60    snd_soc_dpcm_be_can_update      vmlinux EXPORT_SYMBOL_GPL
+-0x059c8bf5    snd_soc_dpcm_fe_can_update      vmlinux EXPORT_SYMBOL_GPL
+-0xe914e41e    strcpy  vmlinux EXPORT_SYMBOL
+-0x27235c89    crypto_destroy_tfm      vmlinux EXPORT_SYMBOL_GPL
+-0xe44b1603    sysfs_remove_link_from_group    vmlinux EXPORT_SYMBOL_GPL
+-0x1dff6af1    filemap_fault   vmlinux EXPORT_SYMBOL
+-0xb1d9aabd    lg_local_unlock_cpu     vmlinux EXPORT_SYMBOL
+-0x59d9c8d7    jack_get_data   vmlinux EXPORT_SYMBOL_GPL
+-0x7a91726b    clkdev_alloc    vmlinux EXPORT_SYMBOL
+-0x6138cad8    nfc_tm_deactivated      vmlinux EXPORT_SYMBOL
+-0xe50e65bf    blocking_notifier_chain_register        vmlinux EXPORT_SYMBOL_GPL
+-0x9acf72e4    rndis_set_param_medium  vmlinux EXPORT_SYMBOL
+-0x677428bf    sdev_enable_disk_events vmlinux EXPORT_SYMBOL
+-0x45ef1157    tty_pair_get_tty        vmlinux EXPORT_SYMBOL
+-0x4338e523    tty_pair_get_pty        vmlinux EXPORT_SYMBOL
+-0x51c0d211    fb_get_buffer_offset    vmlinux EXPORT_SYMBOL
+-0xe7f26347    skb_unlink      vmlinux EXPORT_SYMBOL
+-0xc3f69ac2    crypto_register_template        vmlinux EXPORT_SYMBOL_GPL
+-0x00fe8031    fuse_abort_conn vmlinux EXPORT_SYMBOL_GPL
+-0x3dc45692    vm_iomap_memory vmlinux EXPORT_SYMBOL
+-0xc41f0516    node_states     vmlinux EXPORT_SYMBOL
+-0x6a5fb566    rcu_sched_force_quiescent_state vmlinux EXPORT_SYMBOL_GPL
+-0xc89e91fb    irq_setup_alt_chip      vmlinux EXPORT_SYMBOL_GPL
+-0xe8a39d68    vb2_ioctl_streamoff     vmlinux EXPORT_SYMBOL_GPL
+-0xb2e5ae4a    snd_lookup_minor_data   vmlinux EXPORT_SYMBOL
+-0xaafd1f6c    iio_triggered_buffer_setup      vmlinux EXPORT_SYMBOL
+-0x4b17b645    of_property_read_u16_array      vmlinux EXPORT_SYMBOL_GPL
+-0xdac11bae    of_property_read_u32_array      vmlinux EXPORT_SYMBOL_GPL
+-0x5641485b    tty_termios_encode_baud_rate    vmlinux EXPORT_SYMBOL_GPL
+-0x85d549dc    s3c_gpio_getcfg vmlinux EXPORT_SYMBOL
+-0x1189692c    inet_csk_delete_keepalive_timer vmlinux EXPORT_SYMBOL
+-0xbec25473    of_parse_phandle        vmlinux EXPORT_SYMBOL
+-0x53f0b470    dev_pm_qos_add_ancestor_request vmlinux EXPORT_SYMBOL_GPL
+-0x0ddc826c    drm_fb_helper_set_par   vmlinux EXPORT_SYMBOL
+-0x64bb0960    cfg80211_wext_giwmode   vmlinux EXPORT_SYMBOL_GPL
+-0xd4cc3fbd    cfg80211_wext_giwname   vmlinux EXPORT_SYMBOL_GPL
+-0x8697617d    cfg80211_wext_siwmode   vmlinux EXPORT_SYMBOL_GPL
+-0xe3643cca    cfg80211_send_auth_timeout      vmlinux EXPORT_SYMBOL
+-0x377db989    xfrm_state_register_afinfo      vmlinux EXPORT_SYMBOL
+-0x2cdca56b    usb_register_device_driver      vmlinux EXPORT_SYMBOL_GPL
+-0x7f9066b4    subsys_interface_unregister     vmlinux EXPORT_SYMBOL_GPL
+-0xfbc8e9a2    regulatory_hint vmlinux EXPORT_SYMBOL
+-0xbdf0ff3a    wiphy_rfkill_start_polling      vmlinux EXPORT_SYMBOL
+-0x74631c0e    inet_ioctl      vmlinux EXPORT_SYMBOL
+-0x5cbe31bd    snd_soc_dapm_mixer_update_power vmlinux EXPORT_SYMBOL_GPL
+-0x5a3c2afd    kobject_get_path        vmlinux EXPORT_SYMBOL_GPL
+-0xd8ce7e67    clocksource_register    vmlinux EXPORT_SYMBOL
+-0x802c194a    of_device_register      vmlinux EXPORT_SYMBOL
+-0x0c8c9e99    scsi_show_extd_sense    vmlinux EXPORT_SYMBOL
+-0x2155f85c    bt_sock_link    vmlinux EXPORT_SYMBOL
+-0x0ccfae80    xt_register_target      vmlinux EXPORT_SYMBOL
+-0x6f20960a    full_name_hash  vmlinux EXPORT_SYMBOL
+-0xcded9074    phy_drivers_register    vmlinux EXPORT_SYMBOL
+-0xae5ba460    ping_prot       vmlinux EXPORT_SYMBOL
+-0x814e7730    nf_ct_destroy   vmlinux EXPORT_SYMBOL
+-0xe8279caa    nf_unregister_hooks     vmlinux EXPORT_SYMBOL
+-0x8810ad5e    crypto_xor      vmlinux EXPORT_SYMBOL_GPL
+-0x45bf1ff3    crypto_inc      vmlinux EXPORT_SYMBOL_GPL
+-0x5ac71347    wait_for_stable_page    vmlinux EXPORT_SYMBOL_GPL
+-0xe07ca631    cpu_bit_bitmap  vmlinux EXPORT_SYMBOL_GPL
+-0x9c5bf378    pm_generic_freeze       vmlinux EXPORT_SYMBOL_GPL
+-0x50bd1b27    device_create_vargs     vmlinux EXPORT_SYMBOL_GPL
+-0x30775773    drm_bl_unregister       vmlinux EXPORT_SYMBOL_GPL
+-0xf4f3abb6    tty_port_hangup vmlinux EXPORT_SYMBOL
+-0xca0bdf70    framebuffer_release     vmlinux EXPORT_SYMBOL
+-0x86743fc9    touch_buffer    vmlinux EXPORT_SYMBOL
+-0x5671b6e0    iio_triggered_buffer_predisable vmlinux EXPORT_SYMBOL
+-0x2eb9cd44    brcmu_pktq_init drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x77c7a73e    wiphy_apply_custom_regulatory   vmlinux EXPORT_SYMBOL
+-0xd796d321    fat_getattr     vmlinux EXPORT_SYMBOL_GPL
+-0x41e95f70    fat_setattr     vmlinux EXPORT_SYMBOL_GPL
+-0x2750ffee    generic_read_dir        vmlinux EXPORT_SYMBOL
+-0x00c3b7ed    dentry_unhash   vmlinux EXPORT_SYMBOL
+-0xe007de41    kallsyms_lookup_name    vmlinux EXPORT_SYMBOL_GPL
+-0x43f23311    dm_table_get_md vmlinux EXPORT_SYMBOL
+-0x9db747a3    usb_hcd_poll_rh_status  vmlinux EXPORT_SYMBOL_GPL
+-0xfd1cd45b    dev_pm_qos_hide_flags   vmlinux EXPORT_SYMBOL_GPL
+-0xe15b1685    device_find_child       vmlinux EXPORT_SYMBOL_GPL
+-0x1a022e5e    truncate_pagecache      vmlinux EXPORT_SYMBOL
+-0x26b71fb4    ring_buffer_time_stamp  vmlinux EXPORT_SYMBOL_GPL
+-0x4e6a500f    phy_pm_runtime_get      vmlinux EXPORT_SYMBOL_GPL
+-0x056bb269    xfrm_ealg_get_byidx     vmlinux EXPORT_SYMBOL_GPL
+-0x094585f4    sock_no_shutdown        vmlinux EXPORT_SYMBOL
+-0x0a5ea478    __generic_block_fiemap  vmlinux EXPORT_SYMBOL
+-0xb1acbcce    rcu_barrier_sched       vmlinux EXPORT_SYMBOL_GPL
+-0x3924dd56    try_wait_for_completion vmlinux EXPORT_SYMBOL
+-0x8f7014a1    param_set_ulong vmlinux EXPORT_SYMBOL
+-0xee2d0fc7    _local_bh_enable        vmlinux EXPORT_SYMBOL
+-0x34e8e0a0    of_device_unregister    vmlinux EXPORT_SYMBOL
+-0xbed3ee5e    watchdog_register_device        vmlinux EXPORT_SYMBOL_GPL
+-0x16244fe5    v4l2_prio_check vmlinux EXPORT_SYMBOL
+-0x324a8332    vc_resize       vmlinux EXPORT_SYMBOL
+-0xb410d84f    phy_put vmlinux EXPORT_SYMBOL_GPL
+-0xa41b1e49    phy_pm_runtime_put_sync vmlinux EXPORT_SYMBOL_GPL
+-0xb3d5242c    nf_ct_expect_alloc      vmlinux EXPORT_SYMBOL_GPL
+-0xbdfe32cf    sysfs_unmerge_group     vmlinux EXPORT_SYMBOL_GPL
+-0xdb04cacc    tracepoint_probe_unregister_noupdate    vmlinux EXPORT_SYMBOL_GPL
+-0x481ce6ce    cpu_active_mask vmlinux EXPORT_SYMBOL
+-0x78f47a5c    drm_kms_helper_poll_init        vmlinux EXPORT_SYMBOL
+-0x62827bec    security_secctx_to_secid        vmlinux EXPORT_SYMBOL
+-0xcb97ad8c    bus_find_device_by_name vmlinux EXPORT_SYMBOL_GPL
+-0x427dce2d    drm_put_minor   vmlinux EXPORT_SYMBOL
+-0xf7b743b5    drm_calc_timestamping_constants vmlinux EXPORT_SYMBOL
+-0x62746f06    video_source_unregister vmlinux EXPORT_SYMBOL_GPL
+-0xacde6340    inet_peer_xrlim_allow   vmlinux EXPORT_SYMBOL
+-0xd4b0b600    nf_ct_attach    vmlinux EXPORT_SYMBOL
+-0x3e1314f1    snd_timer_global_free   vmlinux EXPORT_SYMBOL
+-0xd37725bb    register_user_hw_breakpoint     vmlinux EXPORT_SYMBOL_GPL
+-0x4f741917    devm_phy_put    vmlinux EXPORT_SYMBOL_GPL
+-0xe5ed5467    xfrm_policy_walk_init   vmlinux EXPORT_SYMBOL
+-0xfd6eefb8    nf_nat_decode_session_hook      vmlinux EXPORT_SYMBOL
+-0x82627707    snd_pcm_lib_writev      vmlinux EXPORT_SYMBOL
+-0x28b2dd21    textsearch_register     vmlinux EXPORT_SYMBOL
+-0x74baf17a    tracing_is_on   vmlinux EXPORT_SYMBOL_GPL
+-0x381a798a    setup_max_cpus  vmlinux EXPORT_SYMBOL
+-0xf442e8f8    commit_creds    vmlinux EXPORT_SYMBOL
+-0xab598227    driver_attach   vmlinux EXPORT_SYMBOL_GPL
+-0xa1d5de65    drm_mode_connector_list_update  vmlinux EXPORT_SYMBOL
+-0xf3f5690b    __nf_ct_expect_find     vmlinux EXPORT_SYMBOL_GPL
+-0xad0413d4    match_hex       vmlinux EXPORT_SYMBOL
+-0xbfdbee53    usbnet_generic_cdc_bind vmlinux EXPORT_SYMBOL_GPL
+-0x329edb99    platform_device_register        vmlinux EXPORT_SYMBOL_GPL
+-0x80d68d3e    fb_register_client      vmlinux EXPORT_SYMBOL
+-0x3638b44e    __inet_lookup_listener  vmlinux EXPORT_SYMBOL_GPL
+-0x89636597    nf_unregister_sockopt   vmlinux EXPORT_SYMBOL
+-0xadac214f    __skb_get_rxhash        vmlinux EXPORT_SYMBOL
+-0x10ae54ba    skb_realloc_headroom    vmlinux EXPORT_SYMBOL
+-0xdaa5b6fe    generic_pipe_buf_get    vmlinux EXPORT_SYMBOL
+-0x461fff7e    generic_pipe_buf_map    vmlinux EXPORT_SYMBOL
+-0x36f9cd94    rcu_is_cpu_idle vmlinux EXPORT_SYMBOL
+-0x4102e3db    media_entity_find_link  vmlinux EXPORT_SYMBOL_GPL
+-0xcd0e7389    platform_device_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0xf86dc7d7    serial8250_set_isa_configurator vmlinux EXPORT_SYMBOL
+-0xbe1c5d4d    ipv6_find_hdr   vmlinux EXPORT_SYMBOL
+-0xc6ed2b40    jbd2_journal_dirty_metadata     vmlinux EXPORT_SYMBOL
+-0x77df0847    __set_personality       vmlinux EXPORT_SYMBOL
+-0x92c6523d    tty_port_close_end      vmlinux EXPORT_SYMBOL
+-0x78843287    blkcipher_walk_done     vmlinux EXPORT_SYMBOL_GPL
+-0x96f90809    page_readlink   vmlinux EXPORT_SYMBOL
+-0xc7c4f4ed    account_page_writeback  vmlinux EXPORT_SYMBOL
+-0xa1edf7f3    drm_core_ioremap_wc     vmlinux EXPORT_SYMBOL
+-0x08ad3fc2    register_con_driver     vmlinux EXPORT_SYMBOL
+-0x676bbc0f    _set_bit        vmlinux EXPORT_SYMBOL
+-0xd46c9ca5    nf_unregister_afinfo    vmlinux EXPORT_SYMBOL_GPL
+-0xf5eb86ea    blk_verify_command      vmlinux EXPORT_SYMBOL
+-0xc499ae1e    kstrdup vmlinux EXPORT_SYMBOL
+-0x2aa1ad41    _raw_write_lock_irq     vmlinux EXPORT_SYMBOL
+-0xb5b7345d    freezing_slow_path      vmlinux EXPORT_SYMBOL
+-0xe505e34f    mmc_start_bkops vmlinux EXPORT_SYMBOL
+-0x1dd571e6    fb_copy_cmap    vmlinux EXPORT_SYMBOL
+-0x0d4d7a32    _atomic_dec_and_lock    vmlinux EXPORT_SYMBOL
+-0x11c9185c    of_iomap        vmlinux EXPORT_SYMBOL
+-0xf918f7de    xfrm_register_km        vmlinux EXPORT_SYMBOL
+-0xde4bc28c    ip_mc_dec_group vmlinux EXPORT_SYMBOL
+-0x03f12ac0    snd_soc_dapm_mux_update_power   vmlinux EXPORT_SYMBOL_GPL
+-0x733c3b54    kasprintf       vmlinux EXPORT_SYMBOL
+-0x8aaa8b57    simple_rename   vmlinux EXPORT_SYMBOL
+-0x512579ee    vfs_setxattr    vmlinux EXPORT_SYMBOL_GPL
+-0x3d8f75d6    vfs_getxattr    vmlinux EXPORT_SYMBOL_GPL
+-0xcb7131fb    fb_get_options  vmlinux EXPORT_SYMBOL
+-0xd49c7d00    phy_init        vmlinux EXPORT_SYMBOL_GPL
+-0xf8c54a02    sock_init_data  vmlinux EXPORT_SYMBOL
+-0x1209a558    snd_ctl_free_one        vmlinux EXPORT_SYMBOL
+-0xe02eb6d0    ring_buffer_commit_overrun_cpu  vmlinux EXPORT_SYMBOL_GPL
+-0x3a536bd7    ring_buffer_read_finish vmlinux EXPORT_SYMBOL_GPL
+-0x9c0bd51f    _raw_spin_lock  vmlinux EXPORT_SYMBOL
+-0xcf7c760d    mmc_send_ext_csd        vmlinux EXPORT_SYMBOL_GPL
+-0x0f7cb7fa    tty_set_termios vmlinux EXPORT_SYMBOL_GPL
+-0x86ffe7d1    ip_queue_xmit   vmlinux EXPORT_SYMBOL
+-0xc30b3a36    scatterwalk_map vmlinux EXPORT_SYMBOL_GPL
+-0x23532c4d    ftrace_print_flags_seq  vmlinux EXPORT_SYMBOL
+-0x3500818d    v4l2_fh_open    vmlinux EXPORT_SYMBOL_GPL
+-0xadc7d94a    class_dev_iter_init     vmlinux EXPORT_SYMBOL_GPL
+-0xb95ec685    km_query        vmlinux EXPORT_SYMBOL
+-0xf569d921    inet_release    vmlinux EXPORT_SYMBOL
+-0x4251ff78    nf_ct_helper_expectfn_register  vmlinux EXPORT_SYMBOL_GPL
+-0xa3f35bf5    rwsem_is_locked vmlinux EXPORT_SYMBOL
+-0x518c4113    blk_queue_start_tag     vmlinux EXPORT_SYMBOL
+-0x299f45b9    jbd2_journal_force_commit       vmlinux EXPORT_SYMBOL
+-0x373db350    kstrtoint       vmlinux EXPORT_SYMBOL
+-0xfffad96c    call_srcu       vmlinux EXPORT_SYMBOL_GPL
+-0x4806c9d5    drm_connector_init      vmlinux EXPORT_SYMBOL
+-0x9fce80db    fb_notifier_call_chain  vmlinux EXPORT_SYMBOL_GPL
+-0x856629e7    __tracepoint_rpm_return_int     vmlinux EXPORT_SYMBOL_GPL
+-0x8f6cee77    __round_jiffies_relative        vmlinux EXPORT_SYMBOL_GPL
+-0xb992cdc2    cpufreq_get_policy      vmlinux EXPORT_SYMBOL
+-0x9a7784ef    v4l2_device_put vmlinux EXPORT_SYMBOL_GPL
+-0xab2d53fe    wm8994_reg_write        vmlinux EXPORT_SYMBOL_GPL
+-0xa7c124ba    inet_frag_maybe_warn_overflow   vmlinux EXPORT_SYMBOL
+-0x81cbdbae    inet_twsk_alloc vmlinux EXPORT_SYMBOL_GPL
+-0x037a0cba    kfree   vmlinux EXPORT_SYMBOL
+-0xfb0c30cd    __rt_mutex_init vmlinux EXPORT_SYMBOL_GPL
+-0x578a9e0d    kill_pid_info_as_cred   vmlinux EXPORT_SYMBOL_GPL
+-0xa8ca80b5    __serio_register_driver vmlinux EXPORT_SYMBOL
+-0x182a39a6    max8997_bulk_read       vmlinux EXPORT_SYMBOL_GPL
+-0x2fd9648c    pm_genpd_add_callbacks  vmlinux EXPORT_SYMBOL_GPL
+-0xc5c2a452    tty_put_char    vmlinux EXPORT_SYMBOL_GPL
+-0x49b60948    xfrm_state_delete       vmlinux EXPORT_SYMBOL
+-0x0693c220    nf_register_sockopt     vmlinux EXPORT_SYMBOL
+-0x8c9e0cae    sock_kmalloc    vmlinux EXPORT_SYMBOL
+-0xb9638db4    snd_pcm_rate_to_rate_bit        vmlinux EXPORT_SYMBOL
+-0xf3b3adff    cgroup_load_subsys      vmlinux EXPORT_SYMBOL_GPL
+-0x75911fdf    ip_tunnel_get_stats64   vmlinux EXPORT_SYMBOL_GPL
+-0xe7d4daac    seq_list_next   vmlinux EXPORT_SYMBOL
+-0x2fe252cc    unregister_inet6addr_notifier   vmlinux EXPORT_SYMBOL
+-0xa06df9e1    __kfifo_dma_out_finish_r        vmlinux EXPORT_SYMBOL
+-0x01e0e788    st_sensors_allocate_trigger     vmlinux EXPORT_SYMBOL
+-0xcdd15087    of_irq_map_one  vmlinux EXPORT_SYMBOL_GPL
+-0xea97422f    vb2_queue_release       vmlinux EXPORT_SYMBOL_GPL
+-0xb37c3615    cfg80211_rx_unexpected_4addr_frame      vmlinux EXPORT_SYMBOL
+-0xbc2271b2    ipv6_chk_addr   vmlinux EXPORT_SYMBOL
+-0x9e9ab99d    __blkdev_driver_ioctl   vmlinux EXPORT_SYMBOL_GPL
+-0x54f3cc64    blk_alloc_queue_node    vmlinux EXPORT_SYMBOL
+-0xd20b9da2    iio_buffer_unregister   vmlinux EXPORT_SYMBOL
+-0xa8f8abd2    v4l2_ctrl_g_ctrl_int64  vmlinux EXPORT_SYMBOL
+-0xc2aa0765    dev_pm_qos_flags        vmlinux EXPORT_SYMBOL_GPL
+-0xf5f14859    uart_suspend_port       vmlinux EXPORT_SYMBOL
+-0xe7722171    flex_array_free vmlinux EXPORT_SYMBOL
+-0xa27aead4    blk_queue_flush vmlinux EXPORT_SYMBOL_GPL
+-0x713c83fa    bio_phys_segments       vmlinux EXPORT_SYMBOL
+-0xdaa57ec3    totalhigh_pages vmlinux EXPORT_SYMBOL
+-0x2a2a7a3b    rndis_set_param_dev     vmlinux EXPORT_SYMBOL
+-0x54fd2e8d    scsi_device_resume      vmlinux EXPORT_SYMBOL
+-0x7a060e19    ipv6_find_tlv   vmlinux EXPORT_SYMBOL_GPL
+-0x8fe6ac1e    neigh_changeaddr        vmlinux EXPORT_SYMBOL
+-0xa38c2c00    snd_soc_jack_get_type   vmlinux EXPORT_SYMBOL_GPL
+-0x710c73b6    crypto_unregister_notifier      vmlinux EXPORT_SYMBOL_GPL
+-0xda0c24cc    invalidate_inode_pages2 vmlinux EXPORT_SYMBOL_GPL
+-0x72741f25    trace_vbprintk  vmlinux EXPORT_SYMBOL_GPL
+-0xccb0efda    do_unregister_con_driver        vmlinux EXPORT_SYMBOL_GPL
+-0xa120d33c    tty_unregister_ldisc    vmlinux EXPORT_SYMBOL
+-0xd644f377    tty_standard_install    vmlinux EXPORT_SYMBOL_GPL
+-0x31222024    amba_apb_device_add_res vmlinux EXPORT_SYMBOL_GPL
+-0xf8299259    cfg80211_michael_mic_failure    vmlinux EXPORT_SYMBOL
+-0xbe53b873    ipt_do_table    vmlinux EXPORT_SYMBOL
+-0xc96046ab    kmem_cache_destroy      vmlinux EXPORT_SYMBOL
+-0x79105e99    add_to_page_cache_locked        vmlinux EXPORT_SYMBOL
+-0x4e109192    ring_buffer_entries     vmlinux EXPORT_SYMBOL_GPL
+-0x82a5e5e7    led_classdev_register   vmlinux EXPORT_SYMBOL_GPL
+-0xd952a550    vb2_ioctl_reqbufs       vmlinux EXPORT_SYMBOL_GPL
+-0xcb929a3c    scsi_calculate_bounce_limit     vmlinux EXPORT_SYMBOL
+-0x33746f3f    xfrm_prepare_input      vmlinux EXPORT_SYMBOL
+-0xd1dc81ae    xt_find_target  vmlinux EXPORT_SYMBOL
+-0x92f468ad    drm_mode_object_find    vmlinux EXPORT_SYMBOL
+-0x5a268d54    drm_clflush_sg  vmlinux EXPORT_SYMBOL
+-0x827cc6a1    pptp_msg_name   vmlinux EXPORT_SYMBOL
+-0xd4433787    vm_event_states vmlinux EXPORT_SYMBOL
+-0x488b605d    __module_get    vmlinux EXPORT_SYMBOL
+-0x081f3afb    complete_all    vmlinux EXPORT_SYMBOL
+-0x9bce482f    __release_region        vmlinux EXPORT_SYMBOL
+-0xd007f03b    phy_mii_ioctl   vmlinux EXPORT_SYMBOL
+-0x5ef79e43    exynos_drm_subdrv_open  vmlinux EXPORT_SYMBOL_GPL
+-0x34b60845    nfc_alloc_recv_skb      vmlinux EXPORT_SYMBOL
+-0x075af6c0    cfg80211_reg_can_beacon vmlinux EXPORT_SYMBOL
+-0x347013de    nla_validate    vmlinux EXPORT_SYMBOL
+-0x70f6100f    bdi_register    vmlinux EXPORT_SYMBOL
+-0xcf54ea93    async_unregister_domain vmlinux EXPORT_SYMBOL_GPL
+-0xb6efaccd    rndis_rm_hdr    vmlinux EXPORT_SYMBOL
+-0x5ed040b0    pm_set_vt_switch        vmlinux EXPORT_SYMBOL
+-0x3ad0517a    tty_free_termios        vmlinux EXPORT_SYMBOL
+-0x5fa643a3    amba_device_alloc       vmlinux EXPORT_SYMBOL_GPL
+-0x73abc38f    inet_csk_clear_xmit_timers      vmlinux EXPORT_SYMBOL
+-0x52e3e4a5    snd_pcm_hw_param_value  vmlinux EXPORT_SYMBOL
+-0x7129e5f8    hex_asc vmlinux EXPORT_SYMBOL
+-0xa0973520    fat_time_unix2fat       vmlinux EXPORT_SYMBOL_GPL
+-0x522a28d0    mmc_regulator_get_supply        vmlinux EXPORT_SYMBOL_GPL
+-0xac84055a    nf_nat_follow_master    vmlinux EXPORT_SYMBOL
+-0x2aa0e4fc    strncasecmp     vmlinux EXPORT_SYMBOL
+-0x9d5dfdfe    fuse_dev_release        vmlinux EXPORT_SYMBOL_GPL
+-0xf54fdd41    default_llseek  vmlinux EXPORT_SYMBOL
+-0xebec57c4    ring_buffer_oldest_event_ts     vmlinux EXPORT_SYMBOL_GPL
+-0x329318c8    iio_channel_release_all vmlinux EXPORT_SYMBOL_GPL
+-0xfc9a70ae    tty_get_pgrp    vmlinux EXPORT_SYMBOL_GPL
+-0xdbf66d36    tcp_read_sock   vmlinux EXPORT_SYMBOL
+-0xc18db9a3    snd_jack_new    vmlinux EXPORT_SYMBOL
+-0x5df2ea54    sdhci_pltfm_free        vmlinux EXPORT_SYMBOL_GPL
+-0x137901ef    ip_fragment     vmlinux EXPORT_SYMBOL
+-0x815b5dd4    match_octal     vmlinux EXPORT_SYMBOL
+-0x6b475280    bio_map_kern    vmlinux EXPORT_SYMBOL
+-0x3abac74c    scsi_eh_prep_cmnd       vmlinux EXPORT_SYMBOL
+-0xd162929f    tty_port_register_device_attr   vmlinux EXPORT_SYMBOL_GPL
+-0x296f9f79    xt_register_targets     vmlinux EXPORT_SYMBOL
+-0x27000b29    crc32c  vmlinux EXPORT_SYMBOL
+-0x2956cef1    vfs_fsync       vmlinux EXPORT_SYMBOL
+-0x18ae03d3    poll_freewait   vmlinux EXPORT_SYMBOL
+-0x40c7247c    si_meminfo      vmlinux EXPORT_SYMBOL
+-0x0034e52c    kthread_create_on_node  vmlinux EXPORT_SYMBOL
+-0xeecb608e    i2c_smbus_write_byte    vmlinux EXPORT_SYMBOL
+-0x907ada97    scsi_register_driver    vmlinux EXPORT_SYMBOL
+-0x7cc1b7fd    max77693_bulk_read      vmlinux EXPORT_SYMBOL_GPL
+-0x3274b08e    hdmi_avi_infoframe_init vmlinux EXPORT_SYMBOL
+-0xde8c763d    cpu_v7_set_pte_ext      vmlinux EXPORT_SYMBOL
+-0x2294b28a    snd_timer_pause vmlinux EXPORT_SYMBOL
+-0x5e95b1cd    current_umask   vmlinux EXPORT_SYMBOL
+-0xd2091a52    get_fs_type     vmlinux EXPORT_SYMBOL
+-0x94893493    ref_module      vmlinux EXPORT_SYMBOL_GPL
+-0x657ca634    iommu_domain_get_attr   vmlinux EXPORT_SYMBOL_GPL
+-0x6b758637    iommu_domain_set_attr   vmlinux EXPORT_SYMBOL_GPL
+-0xe835dcde    nf_nat_pptp_hook_outbound       vmlinux EXPORT_SYMBOL_GPL
+-0x3ac1fef9    drm_mode_legacy_fb_format       vmlinux EXPORT_SYMBOL
+-0x7cc88e22    tty_driver_kref_put     vmlinux EXPORT_SYMBOL
+-0x24fc46b6    regulator_bulk_free     vmlinux EXPORT_SYMBOL_GPL
+-0x776bea60    ip6_tnl_dst_check       vmlinux EXPORT_SYMBOL_GPL
+-0x80690fc4    sock_prot_inuse_get     vmlinux EXPORT_SYMBOL_GPL
+-0xb8aa9e8f    aead_geniv_init vmlinux EXPORT_SYMBOL_GPL
+-0x35bac202    generic_write_end       vmlinux EXPORT_SYMBOL
+-0x59e2743e    call_rcu_bh     vmlinux EXPORT_SYMBOL_GPL
+-0x639f9176    devm_request_threaded_irq       vmlinux EXPORT_SYMBOL
+-0x67955ce6    profile_hits    vmlinux EXPORT_SYMBOL_GPL
+-0xa53a0240    usb_wakeup_notification vmlinux EXPORT_SYMBOL_GPL
+-0xf5e3c0cf    scsi_host_set_state     vmlinux EXPORT_SYMBOL
+-0x31b21f37    nat_t120_hook   vmlinux EXPORT_SYMBOL_GPL
+-0xcd083b10    unregister_sound_dsp    vmlinux EXPORT_SYMBOL
+-0xda529e9e    blk_start_queue vmlinux EXPORT_SYMBOL
+-0xd84ce699    bio_copy_user   vmlinux EXPORT_SYMBOL
+-0x7a4497db    kzfree  vmlinux EXPORT_SYMBOL
+-0x91bbc6b9    genphy_config_aneg      vmlinux EXPORT_SYMBOL
+-0x1c251434    of_mm_gpiochip_add      vmlinux EXPORT_SYMBOL
+-0x8e10854d    inet_sk_diag_fill       vmlinux EXPORT_SYMBOL_GPL
+-0x07d2ea7a    arpt_unregister_table   vmlinux EXPORT_SYMBOL
+-0x2c038769    sk_filter       vmlinux EXPORT_SYMBOL
+-0x57e267af    generic_removexattr     vmlinux EXPORT_SYMBOL
+-0x643b400e    deactivate_super        vmlinux EXPORT_SYMBOL
+-0xcf241a0c    vmap    vmlinux EXPORT_SYMBOL
+-0x31f0bb78    __kmap_atomic_idx       vmlinux EXPORT_SYMBOL
+-0x4e32f63f    devm_clk_put    vmlinux EXPORT_SYMBOL
+-0x77f2c351    v4l2_ctrl_s_ctrl_int64  vmlinux EXPORT_SYMBOL
+-0xed9fdd16    gether_setup_name_default       vmlinux EXPORT_SYMBOL
+-0x6f572dd2    devm_remove_action      vmlinux EXPORT_SYMBOL_GPL
+-0xa8f59416    gpio_direction_output   vmlinux EXPORT_SYMBOL_GPL
+diff --git a/abi-checker/sample/LICENSE b/abi-checker/sample/LICENSE
+deleted file mode 100644
+index 63fabc1..0000000
+--- a/abi-checker/sample/LICENSE
++++ /dev/null
+@@ -1,848 +0,0 @@
+-Copyright (C) 2007-2011 David Zeuthen <zeuthen@gmail.com>
+-Copyright (C) 2007-2011 Red Hat, Inc.
+-All Rights Reserved.
+-
+-The source code for the udisks daemon and command-line tools are
+-licensed to you under the GNU General Public License. Either version 2
+-of the License, or (at your option) any later version.
+-
+-The source code for the libudisks2 dynamic library is licensed to you
+-under the GNU Library General Public License. Either version 2 of the
+-License, or (at your option) any later version.
+-
+-Each file is marked with copyright and licensing headers.
+-
+-The GPLv2 and LGPLv2 licenses are included below.
+-
+--- BEGIN GPLv2+ License ---
+-
+-                    GNU GENERAL PUBLIC LICENSE
+-                       Version 2, June 1991
+-
+- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+- 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+-
+- Everyone is permitted to copy and distribute verbatim copies
+- of this license document, but changing it is not allowed.
+-
+-                            Preamble
+-
+-  The licenses for most software are designed to take away your
+-freedom to share and change it.  By contrast, the GNU General Public
+-License is intended to guarantee your freedom to share and change free
+-software--to make sure the software is free for all its users.  This
+-General Public License applies to most of the Free Software
+-Foundation's software and to any other program whose authors commit to
+-using it.  (Some other Free Software Foundation software is covered by
+-the GNU Library General Public License instead.)  You can apply it to
+-your programs, too.
+-
+-  When we speak of free software, we are referring to freedom, not
+-price.  Our General Public Licenses are designed to make sure that you
+-have the freedom to distribute copies of free software (and charge for
+-this service if you wish), that you receive source code or can get it
+-if you want it, that you can change the software or use pieces of it
+-in new free programs; and that you know you can do these things.
+-
+-  To protect your rights, we need to make restrictions that forbid
+-anyone to deny you these rights or to ask you to surrender the rights.
+-These restrictions translate to certain responsibilities for you if you
+-distribute copies of the software, or if you modify it.
+-
+-  For example, if you distribute copies of such a program, whether
+-gratis or for a fee, you must give the recipients all the rights that
+-you have.  You must make sure that they, too, receive or can get the
+-source code.  And you must show them these terms so they know their
+-rights.
+-
+-  We protect your rights with two steps: (1) copyright the software, and
+-(2) offer you this license which gives you legal permission to copy,
+-distribute and/or modify the software.
+-
+-  Also, for each author's protection and ours, we want to make certain
+-that everyone understands that there is no warranty for this free
+-software.  If the software is modified by someone else and passed on, we
+-want its recipients to know that what they have is not the original, so
+-that any problems introduced by others will not reflect on the original
+-authors' reputations.
+-
+-  Finally, any free program is threatened constantly by software
+-patents.  We wish to avoid the danger that redistributors of a free
+-program will individually obtain patent licenses, in effect making the
+-program proprietary.  To prevent this, we have made it clear that any
+-patent must be licensed for everyone's free use or not licensed at all.
+-
+-  The precise terms and conditions for copying, distribution and
+-modification follow.
+-
+-                    GNU GENERAL PUBLIC LICENSE
+-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+-
+-  0. This License applies to any program or other work which contains
+-a notice placed by the copyright holder saying it may be distributed
+-under the terms of this General Public License.  The "Program", below,
+-refers to any such program or work, and a "work based on the Program"
+-means either the Program or any derivative work under copyright law:
+-that is to say, a work containing the Program or a portion of it,
+-either verbatim or with modifications and/or translated into another
+-language.  (Hereinafter, translation is included without limitation in
+-the term "modification".)  Each licensee is addressed as "you".
+-
+-Activities other than copying, distribution and modification are not
+-covered by this License; they are outside its scope.  The act of
+-running the Program is not restricted, and the output from the Program
+-is covered only if its contents constitute a work based on the
+-Program (independent of having been made by running the Program).
+-Whether that is true depends on what the Program does.
+-
+-  1. You may copy and distribute verbatim copies of the Program's
+-source code as you receive it, in any medium, provided that you
+-conspicuously and appropriately publish on each copy an appropriate
+-copyright notice and disclaimer of warranty; keep intact all the
+-notices that refer to this License and to the absence of any warranty;
+-and give any other recipients of the Program a copy of this License
+-along with the Program.
+-
+-You may charge a fee for the physical act of transferring a copy, and
+-you may at your option offer warranty protection in exchange for a fee.
+-
+-  2. You may modify your copy or copies of the Program or any portion
+-of it, thus forming a work based on the Program, and copy and
+-distribute such modifications or work under the terms of Section 1
+-above, provided that you also meet all of these conditions:
+-
+-    a) You must cause the modified files to carry prominent notices
+-    stating that you changed the files and the date of any change.
+-
+-    b) You must cause any work that you distribute or publish, that in
+-    whole or in part contains or is derived from the Program or any
+-    part thereof, to be licensed as a whole at no charge to all third
+-    parties under the terms of this License.
+-
+-    c) If the modified program normally reads commands interactively
+-    when run, you must cause it, when started running for such
+-    interactive use in the most ordinary way, to print or display an
+-    announcement including an appropriate copyright notice and a
+-    notice that there is no warranty (or else, saying that you provide
+-    a warranty) and that users may redistribute the program under
+-    these conditions, and telling the user how to view a copy of this
+-    License.  (Exception: if the Program itself is interactive but
+-    does not normally print such an announcement, your work based on
+-    the Program is not required to print an announcement.)
+-
+-These requirements apply to the modified work as a whole.  If
+-identifiable sections of that work are not derived from the Program,
+-and can be reasonably considered independent and separate works in
+-themselves, then this License, and its terms, do not apply to those
+-sections when you distribute them as separate works.  But when you
+-distribute the same sections as part of a whole which is a work based
+-on the Program, the distribution of the whole must be on the terms of
+-this License, whose permissions for other licensees extend to the
+-entire whole, and thus to each and every part regardless of who wrote it.
+-
+-Thus, it is not the intent of this section to claim rights or contest
+-your rights to work written entirely by you; rather, the intent is to
+-exercise the right to control the distribution of derivative or
+-collective works based on the Program.
+-
+-In addition, mere aggregation of another work not based on the Program
+-with the Program (or with a work based on the Program) on a volume of
+-a storage or distribution medium does not bring the other work under
+-the scope of this License.
+-
+-  3. You may copy and distribute the Program (or a work based on it,
+-under Section 2) in object code or executable form under the terms of
+-Sections 1 and 2 above provided that you also do one of the following:
+-
+-    a) Accompany it with the complete corresponding machine-readable
+-    source code, which must be distributed under the terms of Sections
+-    1 and 2 above on a medium customarily used for software interchange; or,
+-
+-    b) Accompany it with a written offer, valid for at least three
+-    years, to give any third party, for a charge no more than your
+-    cost of physically performing source distribution, a complete
+-    machine-readable copy of the corresponding source code, to be
+-    distributed under the terms of Sections 1 and 2 above on a medium
+-    customarily used for software interchange; or,
+-
+-    c) Accompany it with the information you received as to the offer
+-    to distribute corresponding source code.  (This alternative is
+-    allowed only for noncommercial distribution and only if you
+-    received the program in object code or executable form with such
+-    an offer, in accord with Subsection b above.)
+-
+-The source code for a work means the preferred form of the work for
+-making modifications to it.  For an executable work, complete source
+-code means all the source code for all modules it contains, plus any
+-associated interface definition files, plus the scripts used to
+-control compilation and installation of the executable.  However, as a
+-special exception, the source code distributed need not include
+-anything that is normally distributed (in either source or binary
+-form) with the major components (compiler, kernel, and so on) of the
+-operating system on which the executable runs, unless that component
+-itself accompanies the executable.
+-
+-If distribution of executable or object code is made by offering
+-access to copy from a designated place, then offering equivalent
+-access to copy the source code from the same place counts as
+-distribution of the source code, even though third parties are not
+-compelled to copy the source along with the object code.
+-
+-  4. You may not copy, modify, sublicense, or distribute the Program
+-except as expressly provided under this License.  Any attempt
+-otherwise to copy, modify, sublicense or distribute the Program is
+-void, and will automatically terminate your rights under this License.
+-However, parties who have received copies, or rights, from you under
+-this License will not have their licenses terminated so long as such
+-parties remain in full compliance.
+-
+-  5. You are not required to accept this License, since you have not
+-signed it.  However, nothing else grants you permission to modify or
+-distribute the Program or its derivative works.  These actions are
+-prohibited by law if you do not accept this License.  Therefore, by
+-modifying or distributing the Program (or any work based on the
+-Program), you indicate your acceptance of this License to do so, and
+-all its terms and conditions for copying, distributing or modifying
+-the Program or works based on it.
+-
+-  6. Each time you redistribute the Program (or any work based on the
+-Program), the recipient automatically receives a license from the
+-original licensor to copy, distribute or modify the Program subject to
+-these terms and conditions.  You may not impose any further
+-restrictions on the recipients' exercise of the rights granted herein.
+-You are not responsible for enforcing compliance by third parties to
+-this License.
+-
+-  7. If, as a consequence of a court judgment or allegation of patent
+-infringement or for any other reason (not limited to patent issues),
+-conditions are imposed on you (whether by court order, agreement or
+-otherwise) that contradict the conditions of this License, they do not
+-excuse you from the conditions of this License.  If you cannot
+-distribute so as to satisfy simultaneously your obligations under this
+-License and any other pertinent obligations, then as a consequence you
+-may not distribute the Program at all.  For example, if a patent
+-license would not permit royalty-free redistribution of the Program by
+-all those who receive copies directly or indirectly through you, then
+-the only way you could satisfy both it and this License would be to
+-refrain entirely from distribution of the Program.
+-
+-If any portion of this section is held invalid or unenforceable under
+-any particular circumstance, the balance of the section is intended to
+-apply and the section as a whole is intended to apply in other
+-circumstances.
+-
+-It is not the purpose of this section to induce you to infringe any
+-patents or other property right claims or to contest validity of any
+-such claims; this section has the sole purpose of protecting the
+-integrity of the free software distribution system, which is
+-implemented by public license practices.  Many people have made
+-generous contributions to the wide range of software distributed
+-through that system in reliance on consistent application of that
+-system; it is up to the author/donor to decide if he or she is willing
+-to distribute software through any other system and a licensee cannot
+-impose that choice.
+-
+-This section is intended to make thoroughly clear what is believed to
+-be a consequence of the rest of this License.
+-
+-  8. If the distribution and/or use of the Program is restricted in
+-certain countries either by patents or by copyrighted interfaces, the
+-original copyright holder who places the Program under this License
+-may add an explicit geographical distribution limitation excluding
+-those countries, so that distribution is permitted only in or among
+-countries not thus excluded.  In such case, this License incorporates
+-the limitation as if written in the body of this License.
+-
+-  9. The Free Software Foundation may publish revised and/or new versions
+-of the General Public License from time to time.  Such new versions will
+-be similar in spirit to the present version, but may differ in detail to
+-address new problems or concerns.
+-
+-Each version is given a distinguishing version number.  If the Program
+-specifies a version number of this License which applies to it and "any
+-later version", you have the option of following the terms and conditions
+-either of that version or of any later version published by the Free
+-Software Foundation.  If the Program does not specify a version number of
+-this License, you may choose any version ever published by the Free Software
+-Foundation.
+-
+-  10. If you wish to incorporate parts of the Program into other free
+-programs whose distribution conditions are different, write to the author
+-to ask for permission.  For software which is copyrighted by the Free
+-Software Foundation, write to the Free Software Foundation; we sometimes
+-make exceptions for this.  Our decision will be guided by the two goals
+-of preserving the free status of all derivatives of our free software and
+-of promoting the sharing and reuse of software generally.
+-
+-                            NO WARRANTY
+-
+-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+-REPAIR OR CORRECTION.
+-
+-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+-POSSIBILITY OF SUCH DAMAGES.
+-
+-                     END OF TERMS AND CONDITIONS
+-
+-            How to Apply These Terms to Your New Programs
+-
+-  If you develop a new program, and you want it to be of the greatest
+-possible use to the public, the best way to achieve this is to make it
+-free software which everyone can redistribute and change under these terms.
+-
+-  To do so, attach the following notices to the program.  It is safest
+-to attach them to the start of each source file to most effectively
+-convey the exclusion of warranty; and each file should have at least
+-the "copyright" line and a pointer to where the full notice is found.
+-
+-    <one line to give the program's name and a brief idea of what it does.>
+-    Copyright (C) <year>  <name of author>
+-
+-    This program is free software; you can redistribute it and/or modify
+-    it under the terms of the GNU General Public License as published by
+-    the Free Software Foundation; either version 2 of the License, or
+-    (at your option) any later version.
+-
+-    This program is distributed in the hope that it will be useful,
+-    but WITHOUT ANY WARRANTY; without even the implied warranty of
+-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-    GNU General Public License for more details.
+-
+-    You should have received a copy of the GNU General Public License
+-    along with this program; if not, write to the Free Software
+-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+-
+-
+-Also add information on how to contact you by electronic and paper mail.
+-
+-If the program is interactive, make it output a short notice like this
+-when it starts in an interactive mode:
+-
+-    Gnomovision version 69, Copyright (C) year name of author
+-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+-    This is free software, and you are welcome to redistribute it
+-    under certain conditions; type `show c' for details.
+-
+-The hypothetical commands `show w' and `show c' should show the appropriate
+-parts of the General Public License.  Of course, the commands you use may
+-be called something other than `show w' and `show c'; they could even be
+-mouse-clicks or menu items--whatever suits your program.
+-
+-You should also get your employer (if you work as a programmer) or your
+-school, if any, to sign a "copyright disclaimer" for the program, if
+-necessary.  Here is a sample; alter the names:
+-
+-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+-
+-  <signature of Ty Coon>, 1 April 1989
+-  Ty Coon, President of Vice
+-
+-This General Public License does not permit incorporating your program into
+-proprietary programs.  If your program is a subroutine library, you may
+-consider it more useful to permit linking proprietary applications with the
+-library.  If this is what you want to do, use the GNU Library General
+-Public License instead of this License.
+-
+--- END GPLv2+ License ---
+-
+--- BEGIN LGPLv2+ License ---
+-
+-                  GNU LIBRARY GENERAL PUBLIC LICENSE
+-                       Version 2, June 1991
+-
+- Copyright (C) 1991 Free Software Foundation, Inc.
+-                    59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+- Everyone is permitted to copy and distribute verbatim copies
+- of this license document, but changing it is not allowed.
+-
+-[This is the first released version of the library GPL.  It is
+- numbered 2 because it goes with version 2 of the ordinary GPL.]
+-
+-                            Preamble
+-
+-  The licenses for most software are designed to take away your
+-freedom to share and change it.  By contrast, the GNU General Public
+-Licenses are intended to guarantee your freedom to share and change
+-free software--to make sure the software is free for all its users.
+-
+-  This license, the Library General Public License, applies to some
+-specially designated Free Software Foundation software, and to any
+-other libraries whose authors decide to use it.  You can use it for
+-your libraries, too.
+-
+-  When we speak of free software, we are referring to freedom, not
+-price.  Our General Public Licenses are designed to make sure that you
+-have the freedom to distribute copies of free software (and charge for
+-this service if you wish), that you receive source code or can get it
+-if you want it, that you can change the software or use pieces of it
+-in new free programs; and that you know you can do these things.
+-
+-  To protect your rights, we need to make restrictions that forbid
+-anyone to deny you these rights or to ask you to surrender the rights.
+-These restrictions translate to certain responsibilities for you if
+-you distribute copies of the library, or if you modify it.
+-
+-  For example, if you distribute copies of the library, whether gratis
+-or for a fee, you must give the recipients all the rights that we gave
+-you.  You must make sure that they, too, receive or can get the source
+-code.  If you link a program with the library, you must provide
+-complete object files to the recipients so that they can relink them
+-with the library, after making changes to the library and recompiling
+-it.  And you must show them these terms so they know their rights.
+-
+-  Our method of protecting your rights has two steps: (1) copyright
+-the library, and (2) offer you this license which gives you legal
+-permission to copy, distribute and/or modify the library.
+-
+-  Also, for each distributor's protection, we want to make certain
+-that everyone understands that there is no warranty for this free
+-library.  If the library is modified by someone else and passed on, we
+-want its recipients to know that what they have is not the original
+-version, so that any problems introduced by others will not reflect on
+-the original authors' reputations.
+-
+-  Finally, any free program is threatened constantly by software
+-patents.  We wish to avoid the danger that companies distributing free
+-software will individually obtain patent licenses, thus in effect
+-transforming the program into proprietary software.  To prevent this,
+-we have made it clear that any patent must be licensed for everyone's
+-free use or not licensed at all.
+-
+-  Most GNU software, including some libraries, is covered by the ordinary
+-GNU General Public License, which was designed for utility programs.  This
+-license, the GNU Library General Public License, applies to certain
+-designated libraries.  This license is quite different from the ordinary
+-one; be sure to read it in full, and don't assume that anything in it is
+-the same as in the ordinary license.
+-
+-  The reason we have a separate public license for some libraries is that
+-they blur the distinction we usually make between modifying or adding to a
+-program and simply using it.  Linking a program with a library, without
+-changing the library, is in some sense simply using the library, and is
+-analogous to running a utility program or application program.  However, in
+-a textual and legal sense, the linked executable is a combined work, a
+-derivative of the original library, and the ordinary General Public License
+-treats it as such.
+-
+-  Because of this blurred distinction, using the ordinary General
+-Public License for libraries did not effectively promote software
+-sharing, because most developers did not use the libraries.  We
+-concluded that weaker conditions might promote sharing better.
+-
+-  However, unrestricted linking of non-free programs would deprive the
+-users of those programs of all benefit from the free status of the
+-libraries themselves.  This Library General Public License is intended to
+-permit developers of non-free programs to use free libraries, while
+-preserving your freedom as a user of such programs to change the free
+-libraries that are incorporated in them.  (We have not seen how to achieve
+-this as regards changes in header files, but we have achieved it as regards
+-changes in the actual functions of the Library.)  The hope is that this
+-will lead to faster development of free libraries.
+-
+-  The precise terms and conditions for copying, distribution and
+-modification follow.  Pay close attention to the difference between a
+-"work based on the library" and a "work that uses the library".  The
+-former contains code derived from the library, while the latter only
+-works together with the library.
+-
+-  Note that it is possible for a library to be covered by the ordinary
+-General Public License rather than by this special one.
+-
+-                  GNU LIBRARY GENERAL PUBLIC LICENSE
+-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+-
+-  0. This License Agreement applies to any software library which
+-contains a notice placed by the copyright holder or other authorized
+-party saying it may be distributed under the terms of this Library
+-General Public License (also called "this License").  Each licensee is
+-addressed as "you".
+-
+-  A "library" means a collection of software functions and/or data
+-prepared so as to be conveniently linked with application programs
+-(which use some of those functions and data) to form executables.
+-
+-  The "Library", below, refers to any such software library or work
+-which has been distributed under these terms.  A "work based on the
+-Library" means either the Library or any derivative work under
+-copyright law: that is to say, a work containing the Library or a
+-portion of it, either verbatim or with modifications and/or translated
+-straightforwardly into another language.  (Hereinafter, translation is
+-included without limitation in the term "modification".)
+-
+-  "Source code" for a work means the preferred form of the work for
+-making modifications to it.  For a library, complete source code means
+-all the source code for all modules it contains, plus any associated
+-interface definition files, plus the scripts used to control compilation
+-and installation of the library.
+-
+-  Activities other than copying, distribution and modification are not
+-covered by this License; they are outside its scope.  The act of
+-running a program using the Library is not restricted, and output from
+-such a program is covered only if its contents constitute a work based
+-on the Library (independent of the use of the Library in a tool for
+-writing it).  Whether that is true depends on what the Library does
+-and what the program that uses the Library does.
+-
+-  1. You may copy and distribute verbatim copies of the Library's
+-complete source code as you receive it, in any medium, provided that
+-you conspicuously and appropriately publish on each copy an
+-appropriate copyright notice and disclaimer of warranty; keep intact
+-all the notices that refer to this License and to the absence of any
+-warranty; and distribute a copy of this License along with the
+-Library.
+-
+-  You may charge a fee for the physical act of transferring a copy,
+-and you may at your option offer warranty protection in exchange for a
+-fee.
+-
+-  2. You may modify your copy or copies of the Library or any portion
+-of it, thus forming a work based on the Library, and copy and
+-distribute such modifications or work under the terms of Section 1
+-above, provided that you also meet all of these conditions:
+-
+-    a) The modified work must itself be a software library.
+-
+-    b) You must cause the files modified to carry prominent notices
+-    stating that you changed the files and the date of any change.
+-
+-    c) You must cause the whole of the work to be licensed at no
+-    charge to all third parties under the terms of this License.
+-
+-    d) If a facility in the modified Library refers to a function or a
+-    table of data to be supplied by an application program that uses
+-    the facility, other than as an argument passed when the facility
+-    is invoked, then you must make a good faith effort to ensure that,
+-    in the event an application does not supply such function or
+-    table, the facility still operates, and performs whatever part of
+-    its purpose remains meaningful.
+-
+-    (For example, a function in a library to compute square roots has
+-    a purpose that is entirely well-defined independent of the
+-    application.  Therefore, Subsection 2d requires that any
+-    application-supplied function or table used by this function must
+-    be optional: if the application does not supply it, the square
+-    root function must still compute square roots.)
+-
+-These requirements apply to the modified work as a whole.  If
+-identifiable sections of that work are not derived from the Library,
+-and can be reasonably considered independent and separate works in
+-themselves, then this License, and its terms, do not apply to those
+-sections when you distribute them as separate works.  But when you
+-distribute the same sections as part of a whole which is a work based
+-on the Library, the distribution of the whole must be on the terms of
+-this License, whose permissions for other licensees extend to the
+-entire whole, and thus to each and every part regardless of who wrote
+-it.
+-
+-Thus, it is not the intent of this section to claim rights or contest
+-your rights to work written entirely by you; rather, the intent is to
+-exercise the right to control the distribution of derivative or
+-collective works based on the Library.
+-
+-In addition, mere aggregation of another work not based on the Library
+-with the Library (or with a work based on the Library) on a volume of
+-a storage or distribution medium does not bring the other work under
+-the scope of this License.
+-
+-  3. You may opt to apply the terms of the ordinary GNU General Public
+-License instead of this License to a given copy of the Library.  To do
+-this, you must alter all the notices that refer to this License, so
+-that they refer to the ordinary GNU General Public License, version 2,
+-instead of to this License.  (If a newer version than version 2 of the
+-ordinary GNU General Public License has appeared, then you can specify
+-that version instead if you wish.)  Do not make any other change in
+-these notices.
+-
+-  Once this change is made in a given copy, it is irreversible for
+-that copy, so the ordinary GNU General Public License applies to all
+-subsequent copies and derivative works made from that copy.
+-
+-  This option is useful when you wish to copy part of the code of
+-the Library into a program that is not a library.
+-
+-  4. You may copy and distribute the Library (or a portion or
+-derivative of it, under Section 2) in object code or executable form
+-under the terms of Sections 1 and 2 above provided that you accompany
+-it with the complete corresponding machine-readable source code, which
+-must be distributed under the terms of Sections 1 and 2 above on a
+-medium customarily used for software interchange.
+-
+-  If distribution of object code is made by offering access to copy
+-from a designated place, then offering equivalent access to copy the
+-source code from the same place satisfies the requirement to
+-distribute the source code, even though third parties are not
+-compelled to copy the source along with the object code.
+-
+-  5. A program that contains no derivative of any portion of the
+-Library, but is designed to work with the Library by being compiled or
+-linked with it, is called a "work that uses the Library".  Such a
+-work, in isolation, is not a derivative work of the Library, and
+-therefore falls outside the scope of this License.
+-
+-  However, linking a "work that uses the Library" with the Library
+-creates an executable that is a derivative of the Library (because it
+-contains portions of the Library), rather than a "work that uses the
+-library".  The executable is therefore covered by this License.
+-Section 6 states terms for distribution of such executables.
+-
+-  When a "work that uses the Library" uses material from a header file
+-that is part of the Library, the object code for the work may be a
+-derivative work of the Library even though the source code is not.
+-Whether this is true is especially significant if the work can be
+-linked without the Library, or if the work is itself a library.  The
+-threshold for this to be true is not precisely defined by law.
+-
+-  If such an object file uses only numerical parameters, data
+-structure layouts and accessors, and small macros and small inline
+-functions (ten lines or less in length), then the use of the object
+-file is unrestricted, regardless of whether it is legally a derivative
+-work.  (Executables containing this object code plus portions of the
+-Library will still fall under Section 6.)
+-
+-  Otherwise, if the work is a derivative of the Library, you may
+-distribute the object code for the work under the terms of Section 6.
+-Any executables containing that work also fall under Section 6,
+-whether or not they are linked directly with the Library itself.
+-
+-  6. As an exception to the Sections above, you may also compile or
+-link a "work that uses the Library" with the Library to produce a
+-work containing portions of the Library, and distribute that work
+-under terms of your choice, provided that the terms permit
+-modification of the work for the customer's own use and reverse
+-engineering for debugging such modifications.
+-
+-  You must give prominent notice with each copy of the work that the
+-Library is used in it and that the Library and its use are covered by
+-this License.  You must supply a copy of this License.  If the work
+-during execution displays copyright notices, you must include the
+-copyright notice for the Library among them, as well as a reference
+-directing the user to the copy of this License.  Also, you must do one
+-of these things:
+-
+-    a) Accompany the work with the complete corresponding
+-    machine-readable source code for the Library including whatever
+-    changes were used in the work (which must be distributed under
+-    Sections 1 and 2 above); and, if the work is an executable linked
+-    with the Library, with the complete machine-readable "work that
+-    uses the Library", as object code and/or source code, so that the
+-    user can modify the Library and then relink to produce a modified
+-    executable containing the modified Library.  (It is understood
+-    that the user who changes the contents of definitions files in the
+-    Library will not necessarily be able to recompile the application
+-    to use the modified definitions.)
+-
+-    b) Accompany the work with a written offer, valid for at
+-    least three years, to give the same user the materials
+-    specified in Subsection 6a, above, for a charge no more
+-    than the cost of performing this distribution.
+-
+-    c) If distribution of the work is made by offering access to copy
+-    from a designated place, offer equivalent access to copy the above
+-    specified materials from the same place.
+-
+-    d) Verify that the user has already received a copy of these
+-    materials or that you have already sent this user a copy.
+-
+-  For an executable, the required form of the "work that uses the
+-Library" must include any data and utility programs needed for
+-reproducing the executable from it.  However, as a special exception,
+-the source code distributed need not include anything that is normally
+-distributed (in either source or binary form) with the major
+-components (compiler, kernel, and so on) of the operating system on
+-which the executable runs, unless that component itself accompanies
+-the executable.
+-
+-  It may happen that this requirement contradicts the license
+-restrictions of other proprietary libraries that do not normally
+-accompany the operating system.  Such a contradiction means you cannot
+-use both them and the Library together in an executable that you
+-distribute.
+-
+-  7. You may place library facilities that are a work based on the
+-Library side-by-side in a single library together with other library
+-facilities not covered by this License, and distribute such a combined
+-library, provided that the separate distribution of the work based on
+-the Library and of the other library facilities is otherwise
+-permitted, and provided that you do these two things:
+-
+-    a) Accompany the combined library with a copy of the same work
+-    based on the Library, uncombined with any other library
+-    facilities.  This must be distributed under the terms of the
+-    Sections above.
+-
+-    b) Give prominent notice with the combined library of the fact
+-    that part of it is a work based on the Library, and explaining
+-    where to find the accompanying uncombined form of the same work.
+-
+-  8. You may not copy, modify, sublicense, link with, or distribute
+-the Library except as expressly provided under this License.  Any
+-attempt otherwise to copy, modify, sublicense, link with, or
+-distribute the Library is void, and will automatically terminate your
+-rights under this License.  However, parties who have received copies,
+-or rights, from you under this License will not have their licenses
+-terminated so long as such parties remain in full compliance.
+-
+-  9. You are not required to accept this License, since you have not
+-signed it.  However, nothing else grants you permission to modify or
+-distribute the Library or its derivative works.  These actions are
+-prohibited by law if you do not accept this License.  Therefore, by
+-modifying or distributing the Library (or any work based on the
+-Library), you indicate your acceptance of this License to do so, and
+-all its terms and conditions for copying, distributing or modifying
+-the Library or works based on it.
+-
+-  10. Each time you redistribute the Library (or any work based on the
+-Library), the recipient automatically receives a license from the
+-original licensor to copy, distribute, link with or modify the Library
+-subject to these terms and conditions.  You may not impose any further
+-restrictions on the recipients' exercise of the rights granted herein.
+-You are not responsible for enforcing compliance by third parties to
+-this License.
+-
+-  11. If, as a consequence of a court judgment or allegation of patent
+-infringement or for any other reason (not limited to patent issues),
+-conditions are imposed on you (whether by court order, agreement or
+-otherwise) that contradict the conditions of this License, they do not
+-excuse you from the conditions of this License.  If you cannot
+-distribute so as to satisfy simultaneously your obligations under this
+-License and any other pertinent obligations, then as a consequence you
+-may not distribute the Library at all.  For example, if a patent
+-license would not permit royalty-free redistribution of the Library by
+-all those who receive copies directly or indirectly through you, then
+-the only way you could satisfy both it and this License would be to
+-refrain entirely from distribution of the Library.
+-
+-If any portion of this section is held invalid or unenforceable under any
+-particular circumstance, the balance of the section is intended to apply,
+-and the section as a whole is intended to apply in other circumstances.
+-
+-It is not the purpose of this section to induce you to infringe any
+-patents or other property right claims or to contest validity of any
+-such claims; this section has the sole purpose of protecting the
+-integrity of the free software distribution system which is
+-implemented by public license practices.  Many people have made
+-generous contributions to the wide range of software distributed
+-through that system in reliance on consistent application of that
+-system; it is up to the author/donor to decide if he or she is willing
+-to distribute software through any other system and a licensee cannot
+-impose that choice.
+-
+-This section is intended to make thoroughly clear what is believed to
+-be a consequence of the rest of this License.
+-
+-  12. If the distribution and/or use of the Library is restricted in
+-certain countries either by patents or by copyrighted interfaces, the
+-original copyright holder who places the Library under this License may add
+-an explicit geographical distribution limitation excluding those countries,
+-so that distribution is permitted only in or among countries not thus
+-excluded.  In such case, this License incorporates the limitation as if
+-written in the body of this License.
+-
+-  13. The Free Software Foundation may publish revised and/or new
+-versions of the Library General Public License from time to time.
+-Such new versions will be similar in spirit to the present version,
+-but may differ in detail to address new problems or concerns.
+-
+-Each version is given a distinguishing version number.  If the Library
+-specifies a version number of this License which applies to it and
+-"any later version", you have the option of following the terms and
+-conditions either of that version or of any later version published by
+-the Free Software Foundation.  If the Library does not specify a
+-license version number, you may choose any version ever published by
+-the Free Software Foundation.
+-
+-  14. If you wish to incorporate parts of the Library into other free
+-programs whose distribution conditions are incompatible with these,
+-write to the author to ask for permission.  For software which is
+-copyrighted by the Free Software Foundation, write to the Free
+-Software Foundation; we sometimes make exceptions for this.  Our
+-decision will be guided by the two goals of preserving the free status
+-of all derivatives of our free software and of promoting the sharing
+-and reuse of software generally.
+-
+-                            NO WARRANTY
+-
+-  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+-
+-  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+-DAMAGES.
+-
+-                     END OF TERMS AND CONDITIONS
+-
+-           How to Apply These Terms to Your New Libraries
+-
+-  If you develop a new library, and you want it to be of the greatest
+-possible use to the public, we recommend making it free software that
+-everyone can redistribute and change.  You can do so by permitting
+-redistribution under these terms (or, alternatively, under the terms of the
+-ordinary General Public License).
+-
+-  To apply these terms, attach the following notices to the library.  It is
+-safest to attach them to the start of each source file to most effectively
+-convey the exclusion of warranty; and each file should have at least the
+-"copyright" line and a pointer to where the full notice is found.
+-
+-    <one line to give the library's name and a brief idea of what it does.>
+-    Copyright (C) <year>  <name of author>
+-
+-    This library is free software; you can redistribute it and/or
+-    modify it under the terms of the GNU Library General Public
+-    License as published by the Free Software Foundation; either
+-    version 2 of the License, or (at your option) any later version.
+-
+-    This library 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
+-    Library General Public License for more details.
+-
+-    You should have received a copy of the GNU Library General Public
+-    License along with this library; if not, write to the
+-    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-    Boston, MA  02111-1307  USA.
+-
+-Also add information on how to contact you by electronic and paper mail.
+-
+-You should also get your employer (if you work as a programmer) or your
+-school, if any, to sign a "copyright disclaimer" for the library, if
+-necessary.  Here is a sample; alter the names:
+-
+-  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+-  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+-
+-  <signature of Ty Coon>, 1 April 1990
+-  Ty Coon, President of Vice
+-
+-That's all there is to it!
+-
+--- END LGPLv2+ License ---
+diff --git a/abi-checker/sample/Makefile b/abi-checker/sample/Makefile
+deleted file mode 100644
+index 4759f3c..0000000
+--- a/abi-checker/sample/Makefile
++++ /dev/null
+@@ -1,12 +0,0 @@
+-obj-m = sample_module.o
+-
+-all:
+-      make -C /usr/src/linux-kernel-build-3.10.19-tizen_defconfig.1 M=$(PWD) modules
+-
+-install:
+-      make -C /usr/src/linux-kernel-build-3.10.19-tizen_defconfig.1 M=$(PWD) modules_install
+-
+-clean:
+-      make -C /usr/src/linux-kernel-build-3.10.19-tizen_defconfig.1 M=$(PWD) clean
+-      
+-
+diff --git a/abi-checker/sample/packaging/udisks-automount-agent.spec.txt b/abi-checker/sample/packaging/udisks-automount-agent.spec.txt
+deleted file mode 100644
+index bca8416..0000000
+--- a/abi-checker/sample/packaging/udisks-automount-agent.spec.txt
++++ /dev/null
+@@ -1,53 +0,0 @@
+-%define debug_package %{nil}
+-Name:       sample-module
+-Summary:    Test sample kernel module 2
+-Version:    0.1.0
+-Release:    1
+-Group:      Base/Device Management
+-License:    GPL-2.0
+-Source0:    %{name}-%{version}.tar.gz
+-BuildRequires: linux-kernel-sources
+-BuildRequires: linux-kernel-headers
+-BuildRequires: linux-kernel-build
+-BuildRequires: linux-kernel-abi-tools
+-BuildRequires: linux-kernel-abi-devel
+-
+-Requires: linux-kernel-uImage
+-
+-%package source
+-Summary: Debug sample-kernel-module-2
+-Group: Base/Device Management
+-
+-%description source
+-Debug and sources sample-kernel-module-2
+-
+-%description
+-TIZEN simple kernel module.  
+-
+-%prep
+-%setup -q
+-
+-%build
+-make %{?jobs:-j%jobs}
+-# Create ABI/API dump fingerprint file
+-/usr/local/bin/abi-module-dumper sample_module_2.ko sample_module_2.abidump
+-
+-%install
+-mkdir -p %{_builddir}/lib/modules/3.10.19-tizen_defconfig.1/
+-make INSTALL_MOD_PATH=%{buildroot}  install
+-cp sample_module_2.abidump %{buildroot}/lib/modules/3.10.19-tizen_defconfig.1/extra/
+-
+-%post
+-# list comptible kerel ABI/API versions
+-/usr/local/bin/abi-module-kernels-list /lib/modules/3.10.19-tizen_defconfig.1/extra/sample_module_2.abidump
+-
+-# Test module ABI/API with the kernel ABI/API
+-/usr/local/bin/abi-module-checker /lib/modules/3.10.19-tizen_defconfig.1/extra/sample_module_2.abidump
+-
+-%files
+-/lib/modules/3.10.19-tizen_defconfig.1/extra/
+-%license LICENSE
+-
+-%files source
+-/usr/src/debug/sample-kernel-module-2-0.1.0/sample_module_2.c
+-/usr/src/debug/sample-kernel-module-2-0.1.0/sample_module_2.mod.c
+diff --git a/abi-checker/sample/sample_module.c b/abi-checker/sample/sample_module.c
+deleted file mode 100644
+index b95a7af..0000000
+--- a/abi-checker/sample/sample_module.c
++++ /dev/null
+@@ -1,107 +0,0 @@
+-#include <linux/module.h>
+-#include <linux/kernel.h>
+-#include <asm/uaccess.h>
+-#include <linux/init.h>
+-#include <linux/fs.h>
+-
+-#define DEVICE_NAME "sample_module"
+-#define TEST_MSG_BUFF_LEN     1024
+-
+-extern int snd_timer_pause;
+-
+-static unsigned int majorNumber = 0;
+-
+-static char message[TEST_MSG_BUFF_LEN + 1];
+-
+-static ssize_t device_write(struct file *filp, const char *buff, size_t len, loff_t *off)
+-{
+-      printk(KERN_ALERT "Empty write operation. %d\n", snd_timer_pause);
+-      return 0;
+-}
+-
+-static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t * offset)
+-{
+-      int bytes_read = 0;
+-
+-      /*
+-       * Copy message
+-       */
+-      for(bytes_read = 0; bytes_read < (length - 1) && bytes_read < TEST_MSG_BUFF_LEN; bytes_read ++)
+-              put_user(message[bytes_read], buffer + bytes_read );
+-      put_user('\0', buffer + bytes_read );
+-
+-      return bytes_read + 1;
+-}
+-
+-static int device_open(struct inode *inode, struct file *file)
+-{
+-      static int counter = 0;
+-
+-      printk( "Open device, count = %d\n", counter++ );
+-
+-      try_module_get( THIS_MODULE );
+-      return 0;
+-}
+-
+-static int device_release(struct inode *inode, struct file *file)
+-{
+-      printk("Release device\n");
+-
+-      module_put( THIS_MODULE );
+-      return 0;
+-}
+-
+-struct file_operations fileOperations =
+-{
+-      read:    device_read,
+-      write:   device_write,
+-      open:    device_open,
+-      release: device_release
+-};
+-
+-static int __init test_module_init( void )
+-{
+-      int i;
+-      int j;
+-
+-      printk(KERN_ALERT "Test kernel module 2 - enter\n");
+-
+-      /*
+-       * Init test message
+-       */
+-      for(i = 0; i < TEST_MSG_BUFF_LEN;)
+-      {
+-              for(j = 0; j < 10 && i < TEST_MSG_BUFF_LEN; j ++, i ++ )
+-              {
+-                      message[i] = '0' + j;
+-                      message[i + 1] = '\0';
+-              }
+-      }
+-
+-      /*
+-       * Register device
+-       */
+-      majorNumber = register_chrdev(0, DEVICE_NAME, &fileOperations);
+-      if (majorNumber < 0)
+-      {
+-                printk(KERN_ALERT "Blad rejestrowania urzadzenia => [%d]\n", majorNumber );
+-                return majorNumber;
+-      }
+-
+-      return 0;
+-}
+-
+-static void __exit test_module_exit(void)
+-{
+-      printk(KERN_ALERT "Test kernel module 2 - exit\n");
+-
+-      unregister_chrdev(majorNumber, DEVICE_NAME);
+-}
+-
+-module_init(test_module_init);
+-module_exit(test_module_exit);
+-
+-MODULE_LICENSE("GPL");
+-MODULE_AUTHOR("Jacek Pielaszkiewicz");        /* Who wrote this module? */
+-MODULE_DESCRIPTION("Sample test kernel module.");     /* What does this module do */
+-MODULE_SUPPORTED_DEVICE("sample_test_module_2");
+diff --git a/abi-checker/src/Makefile b/abi-checker/src/Makefile
+deleted file mode 100644
+index b020bc6..0000000
+--- a/abi-checker/src/Makefile
++++ /dev/null
+@@ -1,31 +0,0 @@
+-PROGRAM = abi-checker
+-GCC = gcc
+-LDD = gcc
+-
+-CFLAGS = $(shell pkg-config --cflags glib-2.0 libelf) -I.
+-
+-LDFLAGS = $(shell pkg-config --libs glib-2.0 libelf)
+-
+-SRC = kernel_abi_checker.c kernel_abi_checker_elf.c
+-
+-HEADER = kernel_abi_checker.h
+-
+-DEST_DIR = /usr/local/bin
+-
+-OBJECTS = kernel_abi_checker.o kernel_abi_checker_elf.o
+-
+-all : $(PROGRAM)
+-
+-.c.o : $(HEADER)
+-      $(GCC) -c $(CFLAGS) $< -o $@
+-
+-$(PROGRAM) : $(OBJECTS)
+-      $(LDD) $(OBJECTS) -o $@ $(LDFLAGS)
+-
+-install :
+-      mkdir -p $(DEST_DIR)
+-      cp $(PROGRAM) $(DEST_DIR)
+-
+-clean :
+-      rm -f $(PROGRAM)
+-      rm -f $(OBJECTS)
+diff --git a/abi-checker/src/abi-module-checker b/abi-checker/src/abi-module-checker
+deleted file mode 100755
+index 78e5a89..0000000
+--- a/abi-checker/src/abi-module-checker
++++ /dev/null
+@@ -1,29 +0,0 @@
+-#!/bin/sh
+-
+-echo ""
+-echo "Module ABI/API checker"
+-echo ""
+-echo ""
+-
+-if [ "${#}" != "1"  ]
+-then
+-      echo ""
+-      echo "ERROR: "
+-      echo "       Usage: ${0} _module_abi_fingerprint_"
+-      echo ""
+-      exit 1
+-fi
+-
+-kerne_abi_file="/boot/abi/current"
+-
+-if [ ! -f "${1}" -o ! -f "${kerne_abi_file}" ]
+-then
+-      echo ""
+-      echo "ERROR: Please check \"${1}\", \"${kerne_abi_file}\" files"
+-      echo ""
+-      exit 1
+-fi
+-
+-/usr/local/bin/abi-checker "test-module" "${kerne_abi_file}" "${1}"
+-
+-exit ${?}
+diff --git a/abi-checker/src/abi-module-dumper b/abi-checker/src/abi-module-dumper
+deleted file mode 100755
+index 783e02a..0000000
+--- a/abi-checker/src/abi-module-dumper
++++ /dev/null
+@@ -1,38 +0,0 @@
+-#!/bin/sh
+-
+-echo ""
+-echo "Module ABI/API fingerprint file generation"
+-echo ""
+-echo ""
+-
+-if [ "${#}" != "2"  ]
+-then
+-      echo ""
+-      echo "ERROR: "
+-      echo "       Usage: ${0} _module_ko_file_ _output_file_"
+-      echo ""
+-      exit 1
+-fi
+-
+-kerne_abi_file="/boot/abi/current"
+-
+-if [ ! -f "${kerne_abi_file}" ]
+-then
+-      echo ""
+-      echo "ERROR: Please check ${kerne_abi_file} file"
+-      echo "       Check if linux-kernel-uImage package is installed in development environment."
+-      echo ""
+-      exit 1
+-fi
+-
+-if [ ! -f "${1}" ]
+-then
+-      echo "ERROR: Please check input file ${1}"
+-      echo ""
+-      exit 1
+-      
+-fi
+-
+-/usr/local/bin/abi-checker "dump-module" "${kerne_abi_file}" "${1}" "${2}"
+-
+-exit ${?}
+diff --git a/abi-checker/src/abi-module-kernels-list b/abi-checker/src/abi-module-kernels-list
+deleted file mode 100755
+index 12105e1..0000000
+--- a/abi-checker/src/abi-module-kernels-list
++++ /dev/null
+@@ -1,31 +0,0 @@
+-#!/bin/sh
+-
+-echo ""
+-echo "List all comatible kernels."
+-echo ""
+-
+-if [ "${#}" != 1  ]
+-then
+-      echo ""
+-      echo "ERROR: "
+-      echo "       Usage: ${0} _module_fingerprint_"
+-      echo ""
+-      exit 1
+-fi
+-
+-#
+-# Check all historical abi kernel files
+-#
+-for file in /boot/abi/abi_*
+-do
+-      filename=`basename ${file}`
+-      version=`echo ${filename} | awk -F _ '{ print $2 }'`
+-      abi=`echo ${filename} | awk -F _ '{ print $3 }'`
+-
+-      /usr/local/bin/abi-checker "test-module" "${file}" "${1}" 2> /dev/null > /dev/null
+-      if [ "${?}" = "0" ]
+-      then
+-              echo "        Kernel:${version}, ABI/API:${abi} .... compatible"
+-      fi
+-done
+-
+diff --git a/abi-checker/src/build_api_kernel_checker.sh b/abi-checker/src/build_api_kernel_checker.sh
+deleted file mode 100755
+index d9e348b..0000000
+--- a/abi-checker/src/build_api_kernel_checker.sh
++++ /dev/null
+@@ -1,24 +0,0 @@
+-#!/bin/sh
+-
+-# Find abi_version file
+-ksymver=`find ../.. -name "Module.symvers"`
+-
+-# compare abi fingerprint file with kernel abi file
+-./abi-checker test-kernel "${ksymver}" "../data/abi_${1}_${2}"
+-rc="${?}"
+-
+-# Test result
+-if [ ${rc} != "0" ]
+-then
+-      echo ""
+-      echo "----------------------------------------------------------------------------------------------------------------------------"
+-      echo ""
+-      echo "The kernel ABI/API has changed. Please update kernel version and add a new abi-checker/data/abi_VERSION_ABIVER file "
+-      echo "(example abi-checker/data/abi_${1}_${2} )."
+-      echo "The kernel sources build will abort."
+-      echo ""
+-      echo ""
+-      exit 1
+-fi
+-
+-exit 0
+diff --git a/abi-checker/src/kernel_abi_checker.c b/abi-checker/src/kernel_abi_checker.c
+deleted file mode 100644
+index da396e1..0000000
+--- a/abi-checker/src/kernel_abi_checker.c
++++ /dev/null
+@@ -1,834 +0,0 @@
+-/*
+- * Build command
+- *
+- * gcc `pkg-config --cflags glib-2.0` kernel_abi_checker.c kernel_abi_checker_elf.c -lglib-2.0 -lelf
+- */
+-
+-#include <stdio.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <glib.h>
+-
+-#include "kernel_abi_checker.h"
+-
+-/*
+- * Functions write single record into ouptu symver file
+- */
+-int writeKernelSymbolsFile( FILE *ptr, char *symbolNameCrc, char *symbolName, char *symbolModule, char *flag )
+-{
+-      return fprintf( ptr, "%s\t%s\t%s\t%s\n", symbolNameCrc, symbolName, symbolModule, flag );
+-}
+-
+-/*
+- * Function open *symver file
+- */
+-FILE *getFile( char *fileName )
+-{
+-      FILE *fPtr = fopen( fileName, "r" );
+-
+-      if( fPtr == (FILE *)NULL )
+-      {
+-              PRINT_ERROR( "Canniot open : %s\n", fileName );
+-              return (FILE *)NULL;
+-      }
+-
+-      return fPtr;
+-}
+-
+-FILE *getOutputFile( char *fileName )
+-{
+-      FILE *fPtr = fopen( fileName, "w" );
+-
+-      if( fPtr == (FILE *)NULL )
+-      {
+-              PRINT_ERROR( "Canniot open : %s\n", fileName );
+-              return (FILE *)NULL;
+-      }
+-
+-      return fPtr;
+-}
+-
+-void releaseFile( FILE *fptr )
+-{
+-      if( fptr != (FILE *)NULL )
+-              fclose( fptr );
+-}
+-
+-void freeHashElement( gpointer data )
+-{
+-      free( (void *)data );
+-}
+-
+-/*
+- * Function creates hash table
+- */
+-GHashTable *createHashTable( void )
+-{
+-      return g_hash_table_new_full( g_str_hash, g_str_equal, NULL, freeHashElement );
+-}
+-
+-/*
+- * Function destroy hash table
+- */
+-void destroyHashTable( GHashTable *tab )
+-{
+-      if( tab != (GHashTable *)NULL )
+-              g_hash_table_destroy( tab );
+-}
+-
+-/*
+- * Function read i mput file.
+- * Function return single KernelSymbol structure.
+- *
+- * Return (KernelSymbol *)-1 - if errora
+-          (KernelSymbol *)NULL - eof
+- *
+- */
+-
+-KernelSymbol *readFileLine( FILE *fptr )
+-{
+-      KernelSymbol *symbolPtr = (KernelSymbol *)NULL;
+-      char inputLine[_LINE_LENGTH_ + 1];
+-      char *crcPtr;
+-      char *symNamePtr;
+-      char *moduleNamePtr;
+-      char *flag;
+-      char *ptr;
+-      int len;
+-      int i;
+-
+-      memset( inputLine, 0, sizeof( inputLine ) );
+-      ptr = fgets( inputLine, _LINE_LENGTH_, fptr );
+-      if( ptr == (char *) NULL )
+-              return (KernelSymbol *)NULL;
+-
+-      i = 0;
+-
+-      /* CRC */
+-      crcPtr = inputLine + i;
+-      for( ;inputLine[i] != '\0' && inputLine[i] != '\t' && i < _LINE_LENGTH_; i ++ );
+-
+-      if( i >= _LINE_LENGTH_ )
+-      {
+-              PRINT_ERROR( "Incorect input record format : \"%s\"\n", inputLine );
+-              return (KernelSymbol *)-1;
+-      }
+-      inputLine[i] = '\0';
+-      i++;
+-
+-      /* Symbol name */
+-      symNamePtr = inputLine + i;
+-
+-      for( ;inputLine[i] != '\0' && inputLine[i] != '\t' && i < _LINE_LENGTH_; i ++ );
+-      if( i >= _LINE_LENGTH_ )
+-      {
+-              PRINT_ERROR( "Incorect input record format : \"%s\"\n", inputLine );
+-              return (KernelSymbol *)-1;
+-      }
+-      inputLine[i] = '\0';
+-      i ++;
+-
+-      /* Module name */
+-      moduleNamePtr = inputLine + i;
+-
+-
+-      for( ;inputLine[i] != '\0' && inputLine[i] != '\t' && i < _LINE_LENGTH_; i ++ );
+-      if( i >= _LINE_LENGTH_ )
+-      {
+-              PRINT_ERROR( "Incorect input record format : \"%s\"\n", inputLine );
+-              return (KernelSymbol *)-1;
+-      }
+-      inputLine[i] = '\0';
+-      i ++;
+-
+-      /* Flag */
+-      flag = inputLine + i;
+-
+-
+-      len = strlen( flag );
+-      flag[len ==  0 ? 0 : len -1] = '\0';
+-
+-      /* Allocate new KernelSymbol */
+-      symbolPtr = (KernelSymbol *)malloc( sizeof( KernelSymbol ) );
+-      if( symbolPtr == (KernelSymbol *)NULL )
+-              return (KernelSymbol *)-1;
+-
+-      for( i = 0; moduleNamePtr[i] != '\0' && moduleNamePtr[i] != '\n'; i ++ );
+-      moduleNamePtr[i] = '\0';
+-
+-      /* Polulate output structure */
+-      strncpy( symbolPtr -> symbolName, symNamePtr, KERNEL_SYMBOL_NAME_LENGTH );
+-      strncpy( symbolPtr -> symbolNameCrc, crcPtr, KERNEL_SYMBOL_NAME_CRC );
+-      strncpy( symbolPtr -> symbolModule, moduleNamePtr, KERNEL_SYMBOL_MODULE );
+-      strncpy( symbolPtr -> flag, flag, KERNEL_SYMBOL_FLAG );
+-      symbolPtr -> status = KERNEL_SYMBOL_STATUS_NO_TESTED;
+-
+-      /* Return KernModule structure */
+-      return symbolPtr;
+-}
+-
+-/*
+- * Function adds single kernel symbol into hashtable.
+- * Functions assumes that hash table is correctlly allocated.
+- *
+- * Returns:
+- * -1 - duplicated key
+- *  0 - success
+- */
+-
+-int addKernelSymboltoHashBase( void *s, char *key, GHashTable *tab )
+-{
+-      void *testSym;
+-
+-      /* Check duplicates */
+-      testSym = (void *)g_hash_table_lookup( tab, key );
+-      if( testSym != (void *)NULL )
+-              return -1;
+-
+-      /* Add new symbol into hash table */
+-      g_hash_table_insert( tab, key, s );
+-      return 0;
+-}
+-
+-int addKernelSymboltoHash( KernelSymbol *s, GHashTable *tab )
+-{
+-      return addKernelSymboltoHashBase( (void *)s, s -> symbolName, tab );
+-}
+-
+-int readFile( FILE *fptr, GHashTable *tab )
+-{
+-        KernelSymbol *sym = (KernelSymbol *)NULL;
+-        while( 1 == 1 )
+-        {
+-                sym = readFileLine( fptr );
+-              if( sym == (KernelSymbol *)NULL )
+-              {
+-                      /* Koniec pliku */
+-                      break;
+-              }
+-
+-              if( sym == (KernelSymbol *)-1 )
+-              {
+-                      /* Error */
+-                      return -1;
+-              }
+-
+-              if( addKernelSymboltoHash( sym, tab ) < 0 )
+-              {
+-                      /* Error - duplicated value */
+-                      return -1;
+-              }
+-        }
+-
+-      /* Success */
+-      return 0;
+-}
+-
+-GHashTable *procesInputFile( char *name )
+-{
+-      GHashTable *hashTable = (GHashTable *)NULL;
+-      FILE *fptr = (FILE *)NULL;
+-
+-      /* Open input file */
+-      fptr = getFile( name );
+-      if( fptr == (FILE *)NULL )
+-              return (GHashTable *)NULL;
+-
+-      /* Create hash table for current symver */
+-      hashTable = createHashTable();
+-      if( hashTable == (GHashTable *)NULL )
+-      {
+-              PRINT_ERROR( "Error creating hash table \n" );
+-              releaseFile( fptr );
+-              return (GHashTable *)NULL;
+-      }
+-
+-      /* Read and create current hash table */
+-      if( readFile( fptr, hashTable ) != 0 )
+-      {
+-              PRINT_ERROR( "Error reading %s\n", name );
+-              destroyHashTable( hashTable );
+-              releaseFile( fptr );
+-              return (GHashTable *)NULL;
+-      }
+-
+-      /* Close input file */
+-      releaseFile( fptr );
+-
+-      return hashTable;
+-}
+-
+-typedef struct _foreachHashData_
+-{
+-      KernelSymbolStatistics *stat;
+-      GHashTable *curr;
+-      GHashTable *new;
+-} _foreachHashData_;
+-
+-void calculateStatistics_1( gpointer key_, gpointer value_, gpointer user_data_ )
+-{
+-      KernelSymbol *value = (KernelSymbol *)value_;
+-      _foreachHashData_ *user_data = (_foreachHashData_ *)user_data_;
+-      KernelSymbol *newSym;
+-
+-      /* Update current hash table symbols count */
+-      user_data -> stat -> symver_current_count ++;
+-
+-      /* Search for symbol in new hash table */
+-      newSym = (KernelSymbol *)g_hash_table_lookup( user_data -> new, key_ );
+-
+-      if( newSym == (KernelSymbol *)NULL )
+-      {
+-              /* Symbol was removed */
+-
+-              /* Set status */
+-              value -> status = KERNEL_SYMBOL_STATUS_REMOVED;
+-
+-              user_data -> stat -> removed_symbols_count ++;
+-              return;
+-      }
+-
+-      newSym -> status = KERNEL_SYMBOL_STATUS_VIEWED;
+-
+-      if( strcmp( value -> symbolNameCrc, newSym -> symbolNameCrc ) == 0 )
+-      {
+-              user_data -> stat -> no_changed_symbols_count ++;
+-              value -> status = KERNEL_SYMBOL_STATUS_NO_CHANGES;
+-      }
+-      else
+-      {
+-              user_data -> stat -> changed_symbols_count ++;
+-              value -> status = KERNEL_SYMBOL_STATUS_CHANGED;
+-      }
+-}
+-
+-void calculateStatistics_2( gpointer key_, gpointer value_, gpointer user_data_ )
+-{
+-      KernelSymbol *value = (KernelSymbol *)value_;
+-      _foreachHashData_ *user_data = (_foreachHashData_ *)user_data_;
+-
+-      /* Update current hash table symbols count */
+-      user_data -> stat -> symver_new_count ++;
+-
+-      if( value -> status == KERNEL_SYMBOL_STATUS_NO_TESTED )
+-      {
+-              user_data -> stat -> new_symbols_count ++;
+-              value -> status = KERNEL_SYMBOL_STATUS_NEW;
+-      }
+-}
+-
+-void collectStatistics( GHashTable *curr, GHashTable *new, KernelSymbolStatistics *statistics )
+-{
+-      _foreachHashData_ foreachdata;
+-
+-      /* Init foreach data */
+-      memset( (void *)statistics, 0, sizeof( KernelSymbolStatistics ) );
+-      foreachdata.stat = statistics;
+-      foreachdata.curr = curr;
+-      foreachdata.new = new;
+-
+-      /* Scan current hash table */
+-      g_hash_table_foreach( curr, calculateStatistics_1, (gpointer)&foreachdata );
+-
+-      /* Scan new hash table */
+-      g_hash_table_foreach( new, calculateStatistics_2, (gpointer)&foreachdata );
+-}
+-
+-void reportSymbolsDetails( gpointer key_, gpointer value_, gpointer user_data_ )
+-{
+-      KernelSymbol *value = (KernelSymbol *)value_;
+-
+-      switch( *((int *)user_data_) )
+-      {
+-      case 0 :        /* New */
+-              if( value -> status == KERNEL_SYMBOL_STATUS_NEW )
+-                      PRINT_INFO_RAW( "\t| NEW     | %40s | %10s | %s\n", value -> symbolName, value -> symbolNameCrc, value -> symbolModule );
+-              break;
+-
+-      case 1 :        /* Changed */
+-              if( value -> status == KERNEL_SYMBOL_STATUS_CHANGED )
+-                      PRINT_INFO_RAW( "\t| CHANGED | %40s | %10s | %s\n", value -> symbolName, value -> symbolNameCrc, value -> symbolModule );
+-              break;
+-
+-      case 2 :        /* Removed */
+-              if( value -> status == KERNEL_SYMBOL_STATUS_REMOVED )
+-                      PRINT_INFO_RAW( "\t| REMOVED | %40s | %10s | %s\n", value -> symbolName, value -> symbolNameCrc, value -> symbolModule );
+-              break;
+-      }
+-}
+-//[CHANGED]         cfg80211_send_rx_assoc         0x80e54114                  vmlinux
+-
+-void listChangedSymbols( GHashTable *curr, GHashTable *new, KernelSymbolStatistics *statistics )
+-{
+-      int mode = 0;
+-      int printFooter = 0;
+-
+-      if( statistics -> new_symbols_count == 0 && statistics -> changed_symbols_count == 0 && statistics -> removed_symbols_count == 0 )
+-              return;
+-
+-      PRINT_INFO_RAW( "\n" );
+-
+-      PRINT_INFO_RAW( "\tNew symbols in kernel\n" );
+-      PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
+-      PRINT_INFO_RAW( "\t| Change  |                 Linux kernel symbol name |        CRC | Module name \n" );
+-      PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
+-
+-      if( statistics -> new_symbols_count != 0 && new != (GHashTable *)NULL )
+-      {
+-              mode = 0;
+-              g_hash_table_foreach( new, reportSymbolsDetails, (gpointer)&mode );
+-              printFooter = 1;
+-      }
+-
+-      if( statistics -> changed_symbols_count != 0 && curr != (GHashTable *)NULL )
+-      {
+-              if( statistics -> new_symbols_count != 0 )
+-                      PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
+-
+-              mode = 1;
+-              g_hash_table_foreach( curr, reportSymbolsDetails, (gpointer)&mode );
+-              printFooter = 1;
+-      }
+-
+-      if( statistics -> removed_symbols_count != 0 && curr != (GHashTable *)NULL )
+-      {
+-              if( statistics -> new_symbols_count != 0 || statistics -> changed_symbols_count != 0 )
+-                      PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
+-
+-              mode = 2;
+-              g_hash_table_foreach( curr, reportSymbolsDetails, (gpointer)&mode );
+-              printFooter = 1;
+-      }
+-
+-      if( printFooter == 1 )
+-              PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
+-}
+-
+-void reportsStatistics( GHashTable *curr, GHashTable *new, KernelSymbolStatistics *statistics )
+-{
+-      listChangedSymbols( curr, new, statistics );
+-
+-      PRINT_INFO_RAW( "\n" );
+-      PRINT_INFO_RAW( "\tKernel symbols version statistics \n" );
+-      PRINT_INFO_RAW( "\t-------------------------------------------------\n" );
+-      PRINT_INFO_RAW( "\tSymbols in actual kernel/module . %d\n", statistics -> symver_current_count );
+-      if( new != (GHashTable *)NULL )
+-              PRINT_INFO_RAW( "\tSymbols in new kernel/module .... %d\n", statistics -> symver_new_count );
+-      PRINT_INFO_RAW( "\tNew symbols ..................... %d\n", statistics -> new_symbols_count );
+-      PRINT_INFO_RAW( "\tRemoved symbols ................. %d\n", statistics -> removed_symbols_count );
+-      PRINT_INFO_RAW( "\tChanged symbols ................. %d\n", statistics -> changed_symbols_count );
+-      PRINT_INFO_RAW( "\tUnchanged symbols ............... %d\n", statistics -> no_changed_symbols_count );
+-      PRINT_INFO_RAW( "\n" );
+-}
+-
+-void printUsage( char *progName, int type )
+-{
+-      switch( type )
+-      {
+-      case 0 :
+-              PRINT_INFO_RAW( "\tUsage: %s test-kernel in_symver_file_1 in_symver_file_2\n", progName );
+-              break;
+-
+-      case 1 :
+-              PRINT_INFO_RAW( "\tUsage: %s build-list in_module_symbols_file in_kernel_symver_file outt_module_symver_file\n", progName );
+-              break;
+-
+-      case 2 :
+-              PRINT_INFO_RAW( "\tUsage: %s dump-module kernel_symver_file ko_module_file output_module_symver_file\n", progName );
+-              break;
+-
+-      case 4 :
+-              PRINT_INFO_RAW( "\tUsage: %s test-module kernel_symver_file ko_module_file \n", progName );
+-              break;
+-
+-      default :
+-              PRINT_INFO_RAW( "\tUsage: %s test|build-list file1 file2 [output_file] \n", progName );
+-              break;
+-      }
+-}
+-
+-/*
+- * Function parses input parameters and return.
+- * Return:
+- *            -1 - error
+- *             0 - test mode  - the program will compare two symver files
+- *             1 - build mode - for given module sybmbols file and kernel symver creates files
+- *                              with list kernel symbols used by the module.
+- */
+-int parsInputParameters( int argc, char **argv, char **f1, char **f2, char **f3 )
+-{
+-      char *toolName = argv[0];
+-
+-      if( argc < 2 )
+-      {
+-              printUsage( toolName, -1 );
+-              return -1;
+-      }
+-
+-      if( strcmp( argv[1], "test-kernel" ) == 0 )
+-      {
+-              /* Test mode */
+-              if( argc < 4 )
+-              {
+-                      printUsage( toolName, 0 );
+-                      return -1;
+-              }
+-              *f1 = argv[2];
+-              *f2 = argv[3];
+-              *f3 = (char *)NULL;
+-
+-              return 0;
+-
+-      }
+-      else
+-      if( strcmp( argv[1], "build-list" ) == 0 )
+-      {
+-              /* Build mode */
+-              if( argc < 5 )
+-              {
+-                      printUsage( toolName, 1 );
+-                      return -1;
+-              }
+-              *f1 = argv[2];
+-              *f2 = argv[3];
+-              *f3 = argv[4];
+-
+-              return 1;
+-      }
+-      else
+-      if( strcmp( argv[1], "dump-module" ) == 0 )
+-      {
+-              /* Build mode */
+-              if( argc < 5 )
+-              {
+-                      printUsage( toolName, 2 );
+-                      return -1;
+-              }
+-              *f1 = argv[2];
+-              *f2 = argv[3];
+-              *f3 = argv[4];
+-
+-              return 2;
+-      }
+-      else
+-      if( strcmp( argv[1], "usage" ) == 0 )
+-      {
+-              return 3;
+-      }
+-      else
+-      if( strcmp( argv[1], "test-module" ) == 0 )
+-      {
+-              /* Test mode */
+-              if( argc < 4 )
+-              {
+-                      printUsage( toolName, 4 );
+-                      return -1;
+-              }
+-              *f1 = argv[2];
+-              *f2 = argv[3];
+-              *f3 = (char *)NULL;
+-
+-              return 4;
+-      }
+-
+-
+-      printUsage( toolName, -1 );
+-      return -1;
+-}
+-
+-int testKernel( char *f1, char *f2 )
+-{
+-      GHashTable *curr_hashTable = (GHashTable *)NULL;
+-      GHashTable *new_hashTable = (GHashTable *)NULL;
+-      KernelSymbolStatistics statistics;
+-
+-      /*
+-       * ----------------------------------------------
+-       * Read current symver file
+-       * ----------------------------------------------
+-       */
+-      curr_hashTable = procesInputFile( f1 );
+-      if( curr_hashTable == (GHashTable *)NULL )
+-      {
+-              PRINT_ERROR( "Error read input \"%s\" file.\n", f1 );
+-              return 1;
+-      }
+-
+-      /*
+-       * ----------------------------------------------
+-       * Read new symver file
+-       * ----------------------------------------------
+-      */
+-      new_hashTable = procesInputFile( f2 );
+-      if( new_hashTable == (GHashTable *)NULL )
+-      {
+-              destroyHashTable( curr_hashTable );
+-              PRINT_ERROR( "Error read input \"%s\" file.\n", f2 );
+-        return 1;
+-      }
+-
+-      /*
+-       * ----------------------------------------------
+-       * Compute statistics
+-       * ----------------------------------------------
+-       */
+-      collectStatistics( curr_hashTable, new_hashTable, &statistics );
+-
+-      /*
+-       * ---------------------------------------------
+-       * Report changes
+-       * ---------------------------------------------
+-       */
+-      reportsStatistics( curr_hashTable, new_hashTable, &statistics );
+-
+-      /*
+-       * --------------------------------------------
+-       * Free hash tables
+-       * --------------------------------------------
+-       */
+-      destroyHashTable( curr_hashTable );
+-      destroyHashTable( new_hashTable );
+-
+-      if( statistics.changed_symbols_count != 0 || statistics.removed_symbols_count != 0 || statistics.new_symbols_count != 0 )
+-              return 2;
+-
+-      return 0;
+-}
+-
+-void collectStatisticsModule( GHashTable *curr, GHashTable *module, KernelSymbolStatistics *statistics )
+-{
+-      _foreachHashData_ foreachdata;
+-
+-      /* Init foreach data */
+-      memset( (void *)statistics, 0, sizeof( KernelSymbolStatistics ) );
+-      foreachdata.stat = statistics;
+-      foreachdata.curr = module;
+-      foreachdata.new = curr;
+-
+-      /* Scan current hash table */
+-      g_hash_table_foreach( module, calculateStatistics_1, (gpointer)&foreachdata );
+-}
+-
+-
+-int testModule( char *f1, char *f2 )
+-{
+-      GHashTable *curr_hashTable = (GHashTable *)NULL;
+-      GHashTable *module_hashTable = (GHashTable *)NULL;
+-      KernelSymbolStatistics statistics;
+-
+-      /*
+-       * ----------------------------------------------
+-       * Read current symver file
+-       * ----------------------------------------------
+-       */
+-      curr_hashTable = procesInputFile( f1 );
+-      if( curr_hashTable == (GHashTable *)NULL )
+-      {
+-              PRINT_ERROR( "Error read input \"%s\" file.\n", f1 );
+-              return 1;
+-      }
+-
+-      /*
+-       * ----------------------------------------------
+-       * Read module symbols
+-       * ----------------------------------------------
+-      */
+-      module_hashTable = procesInputFile( f2 );
+-      if( module_hashTable == (GHashTable *)NULL )
+-      {
+-              destroyHashTable( curr_hashTable );
+-              PRINT_ERROR( "Error read input \"%s\" file.\n", f2 );
+-              return 1;
+-      }
+-
+-      /*
+-       * ----------------------------------------------
+-       * Compute statistics
+-       * ----------------------------------------------
+-       */
+-      collectStatisticsModule( curr_hashTable, module_hashTable, &statistics );
+-
+-      /*
+-       * ---------------------------------------------
+-       * Report changes
+-       * ---------------------------------------------
+-       */
+-      reportsStatistics( module_hashTable, (GHashTable *)NULL, &statistics );
+-
+-      /*
+-       * --------------------------------------------
+-       * Free hash tables
+-       * --------------------------------------------
+-       */
+-      destroyHashTable( curr_hashTable );
+-      destroyHashTable( module_hashTable );
+-
+-      if( statistics.changed_symbols_count != 0 || statistics.removed_symbols_count != 0 )
+-              return 2;
+-
+-      return 0;
+-}
+-
+-int buildListMode( char *f1, char *f2, char *f3 )
+-{
+-      GHashTable *curr_hashTable = (GHashTable *)NULL;
+-      char inputLine[_LINE_LENGTH_ + 1];
+-      FILE *symListFptr = (FILE *)NULL;
+-      FILE *outFptr = (FILE *)NULL;
+-      KernelSymbol *kSym;
+-      int size;
+-
+-      /*
+-       * ----------------------------------------------
+-       * Read current symver file
+-       * ----------------------------------------------
+-       */
+-      curr_hashTable = procesInputFile( f1 );
+-      if( curr_hashTable == (GHashTable *)NULL )
+-      {
+-              PRINT_ERROR( "Error read input \"%s\" file.\n", f1 );
+-              return 1;
+-      }
+-
+-      /*
+-       * Open files
+-       */
+-      outFptr = getOutputFile( f3 );
+-      symListFptr = getFile( f2 );
+-
+-      if( symListFptr == (FILE *)NULL || outFptr == (FILE *)NULL )
+-      {
+-              destroyHashTable( curr_hashTable );
+-              releaseFile( symListFptr );
+-              releaseFile( outFptr );
+-              PRINT_ERROR( "Error open files : \"%s\", \"%s\".\n", f2, f3 );
+-              return 1;
+-      }
+-
+-      while( fgets( inputLine, _LINE_LENGTH_, symListFptr ) )
+-      {
+-              size = strlen( inputLine );
+-              inputLine[size == 0 ? 0 :size - 1] = '\0';
+-
+-              /* Search for symbol in new hash table */
+-              kSym = (KernelSymbol *)g_hash_table_lookup( curr_hashTable, inputLine );
+-
+-              if( kSym != (KernelSymbol *)NULL )
+-                      writeKernelSymbolsFile( outFptr, kSym -> symbolNameCrc, kSym -> symbolName, kSym -> symbolModule, kSym -> flag );
+-      }
+-
+-      destroyHashTable( curr_hashTable );
+-      releaseFile( symListFptr );
+-      releaseFile( outFptr );
+-
+-      return 0;
+-}
+-
+-int callDumpModuleSymbols( char *f1, char *f2, char *f3 )
+-{
+-      GHashTable *curr_hashTable = (GHashTable *)NULL;
+-      GHashTable *module_hashTable = (GHashTable *)NULL;
+-
+-      /*
+-       * ----------------------------------------------
+-       * Read current symver file
+-       * ----------------------------------------------
+-       */
+-      curr_hashTable = procesInputFile( f1 );
+-      if( curr_hashTable == (GHashTable *)NULL )
+-      {
+-              PRINT_ERROR( "Error read input \"%s\" file.\n", f1 );
+-              return 1;
+-      }
+-
+-      /*
+-       * ----------------------------------------------
+-       * Read kernel module *.ko file
+-       * ----------------------------------------------
+-       */
+-      module_hashTable = readEfl( f2 );
+-      if( module_hashTable == (GHashTable *)NULL )
+-      {
+-              PRINT_ERROR( "Error read input \"%s\" file.\n", f2 );
+-              destroyHashTable( curr_hashTable );
+-              return 1;
+-      }
+-
+-      /*
+-       * Dump module symbols into output file
+-       */
+-      if( dumpModuleSymbols( f3, module_hashTable, curr_hashTable ) < 0 )
+-      {
+-              PRINT_ERROR( "Error creating dump file \"%s\"\n", f3 );
+-              destroyHashTable( curr_hashTable );
+-              return 1;
+-      }
+-
+-      /*
+-       * Free hash tables
+-       */
+-      destroyHashTable( module_hashTable );
+-      destroyHashTable( curr_hashTable );
+-
+-      return 0;
+-}
+-
+-int printUsageInfo( char *f1 )
+-{
+-      PRINT_INFO_RAW( "\n" );
+-      PRINT_INFO_RAW( "\tProgram usage\n" );
+-      PRINT_INFO_RAW( "\t-----------------------------------------------\n" );
+-      PRINT_INFO_RAW( "\n" );
+-      printUsage( f1, 0 );
+-      printUsage( f1, 1 );
+-      printUsage( f1, 2 );
+-
+-      return 0;
+-}
+-
+-int main(int argc, char** argv)
+-{
+-      char *f1 = (char *)NULL;
+-      char *f2 = (char *)NULL;
+-      char *f3 = (char *)NULL;
+-      int rc = -1;
+-
+-      int mode = parsInputParameters( argc, argv, &f1, &f2, &f3 );
+-
+-      switch( mode )
+-      {
+-      case 0 :
+-              rc = testKernel( f1, f2 );
+-              break;
+-
+-      case 1 :
+-              rc = buildListMode( f1, f2, f3 );
+-              break;
+-
+-      case 2 :
+-              rc = callDumpModuleSymbols( f1, f2, f3 );
+-              break;
+-
+-      case 3 :
+-              rc = printUsageInfo( argv[0] );
+-              break;
+-
+-      case 4 :
+-              rc = testModule( f1, f2 );
+-              break;
+-      }
+-
+-      PRINT_INFO_RAW( "\n" );
+-
+-      if( rc == 2 )
+-              PRINT_INFO_RAW( "\tChanges !!!\n" );
+-      else
+-      if( rc == 1 )
+-              PRINT_INFO_RAW( "\tError !!!\n" );
+-      else
+-              PRINT_INFO_RAW( "\tDone\n" );
+-
+-      PRINT_INFO_RAW( "\n" );
+-
+-      return ( rc != 0 ) ? 1 : 0;
+-}
+diff --git a/abi-checker/src/kernel_abi_checker.h b/abi-checker/src/kernel_abi_checker.h
+deleted file mode 100644
+index 8df231e..0000000
+--- a/abi-checker/src/kernel_abi_checker.h
++++ /dev/null
+@@ -1,62 +0,0 @@
+-#ifndef _kernel_abi_checker_h_
+-#define _kernel_abi_checker_h_
+-
+-#include <stdio.h>
+-#include <glib.h>
+-
+-/*
+- * Definitions
+- */
+-#define KERNEL_SYMBOL_NAME_LENGTH     64
+-#define KERNEL_SYMBOL_NAME_CRC                32
+-#define KERNEL_SYMBOL_MODULE          256
+-#define KERNEL_SYMBOL_FLAG                    256
+-
+-#define KERNEL_SYMBOL_STATUS_NO_TESTED        0
+-#define KERNEL_SYMBOL_STATUS_NO_CHANGES       1
+-#define KERNEL_SYMBOL_STATUS_NEW              2
+-#define KERNEL_SYMBOL_STATUS_REMOVED  3
+-#define KERNEL_SYMBOL_STATUS_CHANGED  4
+-#define KERNEL_SYMBOL_STATUS_VIEWED           5
+-
+-#define _LINE_LENGTH_ 4096
+-
+-/*
+- * Data types
+- */
+-typedef struct KernelSymbol
+-{
+-      char symbolName[KERNEL_SYMBOL_NAME_LENGTH + 1];
+-      char symbolNameCrc[KERNEL_SYMBOL_NAME_CRC + 1];
+-      char symbolModule[KERNEL_SYMBOL_MODULE + 1];
+-      char flag[KERNEL_SYMBOL_FLAG + 1];
+-      int status;
+-
+-} KernelSymbol;
+-
+-typedef struct KernelSymbolStatistics
+-{
+-      int symver_current_count;
+-      int symver_new_count;
+-
+-      int new_symbols_count;
+-      int removed_symbols_count;
+-      int changed_symbols_count;
+-      int no_changed_symbols_count;
+-
+-} KernelSymbolStatistics;
+-
+-extern int writeKernelSymbolsFile( FILE *, char *, char *, char *, char * );
+-extern int addKernelSymboltoHashBase( void *, char *, GHashTable * );
+-extern int dumpModuleSymbols( char *, GHashTable *, GHashTable * );
+-extern void destroyHashTable( GHashTable * );
+-extern GHashTable *createHashTable( void );
+-extern FILE *getOutputFile( char * );
+-extern void releaseFile( FILE * );
+-GHashTable *readEfl( char * );
+-
+-#define PRINT_ERROR(...)  do { fprintf( stderr, "ERROR : " ); fprintf( stderr, __VA_ARGS__ ); } while( 0 )
+-#define PRINT_INFO_RAW(...)   do { fprintf( stdout, __VA_ARGS__ ); } while( 0 )
+-#define PRINT_INFO(...)   do { fprintf( stderr, "INFO  : " ); fprintf( stdout, __VA_ARGS__ ); } while( 0 )
+-
+-#endif
+diff --git a/abi-checker/src/kernel_abi_checker_elf.c b/abi-checker/src/kernel_abi_checker_elf.c
+deleted file mode 100644
+index 6f4f28c..0000000
+--- a/abi-checker/src/kernel_abi_checker_elf.c
++++ /dev/null
+@@ -1,172 +0,0 @@
+-#include "kernel_abi_checker.h"
+-
+-#include <sys/types.h>
+-#include <sys/stat.h>
+-#include <unistd.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <libelf.h>
+-#include <stdio.h>
+-#include <fcntl.h>
+-#include <gelf.h>
+-
+-GHashTable *readEfl( char *file )
+-{
+-      GHashTable *outputHashTable = (GHashTable *)NULL;
+-      Elf_Data *edata = (Elf_Data *)NULL;
+-      Elf_Scn *scn = (Elf_Scn *)NULL;
+-      char *base_ptr = (char *)NULL;
+-      char *sname = (char *)NULL;
+-      Elf *elf = (Elf *)NULL;
+-      struct stat elf_stats;
+-      int symbol_count;
+-      GElf_Shdr shdr;
+-      GElf_Sym sym;
+-      int size;
+-      int fd;
+-      int i;
+-
+-      fd = open( file, O_RDONLY );
+-      if( fd < 0 )
+-      {
+-              PRINT_ERROR( "Cannot open efl file : %s\n", file );
+-              return (GHashTable *)NULL;
+-      }
+-
+-      if( ( fstat( fd, &elf_stats ) ) )
+-      {
+-              PRINT_ERROR( "Cannot stat efl file : %s\n", file );
+-              close(fd );
+-              return (GHashTable *)NULL;
+-      }
+-
+-      base_ptr = (char *) malloc( elf_stats.st_size );
+-      if( base_ptr == (char *)NULL )
+-      {
+-              PRINT_ERROR( "Memory allocation error.\n" );
+-              close( fd );
+-              return (GHashTable *)NULL;
+-      }
+-
+-      if( ( read( fd, base_ptr, elf_stats.st_size ) ) < elf_stats.st_size )
+-      {
+-              PRINT_ERROR( "Cannot read input efl file : %s\n", file );
+-        free( base_ptr );
+-        close( fd );
+-              return (GHashTable *)NULL;
+-      }
+-      free( base_ptr );
+-
+-      /* Create output hash table */
+-      outputHashTable = createHashTable();
+-      if( outputHashTable == (GHashTable *)NULL )
+-      {
+-              PRINT_ERROR( "Memory allocation for hash table error : %s\n", file );
+-        free( base_ptr );
+-        close( fd );
+-              return (GHashTable *)NULL;
+-      }
+-
+-      if( elf_version( EV_CURRENT ) == EV_NONE )
+-              fprintf( stderr, "WARNING Elf Library is out of date!\n" );
+-
+-      // Iterate through section headers again this time well stop when we find symbols
+-      elf = elf_begin( fd, ELF_C_READ, NULL );
+-
+-      while( ( scn = elf_nextscn( elf, scn ) ) != (Elf_Scn *)NULL )
+-      {
+-              gelf_getshdr( scn, &shdr );
+-
+-              // When we find a section header marked SHT_SYMTAB stop and get symbols
+-              if(shdr.sh_type == SHT_SYMTAB)
+-              {
+-                      // edata points to our symbol table
+-                      edata = elf_getdata(scn, edata);
+-
+-                      symbol_count = shdr.sh_size / shdr.sh_entsize;
+-
+-                      for( i = 0; i < symbol_count; i++ )
+-                      {
+-                              /* Get symbol */
+-                              gelf_getsym( edata, i, &sym );
+-
+-                              /* Get symbol name length */
+-                              size = strlen( elf_strptr( elf, shdr.sh_link, sym.st_name ) );
+-                              if( size != 0 )
+-                              {
+-                                      /* allocate memory for symbol name */
+-                                      sname = (char *)malloc( sizeof( char ) * ( size + 1 ) );
+-                                      if( sname == (char *)NULL )
+-                                      {
+-                                              PRINT_ERROR( "Memory allocation for hash table error : %s\n", file );
+-                                              destroyHashTable( outputHashTable );
+-                                      close( fd );
+-                                              return (GHashTable *)NULL;
+-                                      }
+-
+-                                      strcpy( sname, elf_strptr( elf, shdr.sh_link, sym.st_name ) );
+-
+-                                      // Add symbol to hash
+-                                      if( addKernelSymboltoHashBase( (void *)sname, sname, outputHashTable ) < 0 )
+-                                      {
+-                                              // If duplicated key free memory
+-                                              free( sname );
+-                                      }
+-
+-                              }
+-                      }
+-              }
+-      }
+-
+-      /* Close file */
+-      close( fd );
+-
+-      /* Return hash table */
+-      return outputHashTable;
+-}
+-
+-/*
+- * Private user data definition.
+- */
+-
+-typedef struct _efl_user_data_
+-{
+-      GHashTable *kernelHash;
+-      FILE *outFilePtr;
+-} _efl_user_data_;
+-
+-
+-void dumpModuleSymbolsIteration( gpointer key_, gpointer value_, gpointer user_data_ )
+-{
+-      char *key = (char *)key_;
+-      _efl_user_data_ *user_data = (_efl_user_data_ *)user_data_;
+-      KernelSymbol *ptr = (KernelSymbol *)NULL;
+-
+-      ptr = (KernelSymbol *)g_hash_table_lookup( user_data -> kernelHash, key );
+-      if( ptr != (void *)NULL )
+-              writeKernelSymbolsFile( user_data -> outFilePtr, ptr -> symbolNameCrc, ptr -> symbolName, ptr -> symbolModule, ptr -> flag );
+-}
+-
+-/*
+- * Function dumps into output files kernel symbols that
+- * are use in the module
+- */
+-int dumpModuleSymbols( char *outoutFile, GHashTable *moduleSymbols, GHashTable *kernelSymbols )
+-{
+-      FILE *outputFilePtr = getOutputFile( outoutFile );
+-      _efl_user_data_ userData;
+-
+-      if( outputFilePtr == (FILE *)NULL )
+-              return -1;
+-
+-      userData.outFilePtr = outputFilePtr;
+-      userData.kernelHash = kernelSymbols;
+-
+-      /* Loob module symbols */
+-      g_hash_table_foreach( moduleSymbols, dumpModuleSymbolsIteration, (gpointer)&userData );
+-
+-      /* Close output file */
+-      releaseFile( outputFilePtr );
+-
+-      return 0;
+-}
+diff --git a/packaging/linux-kernel.spec b/packaging/linux-kernel.spec
+index 485f06e..0bbbfa5 100644
+--- a/packaging/linux-kernel.spec
++++ b/packaging/linux-kernel.spec
+@@ -92,7 +92,7 @@ Linux kernel uImage
+ %build
+ # 0. Build abi checker
+-make -C abi-checker/src
++make -C tools/abi-checker/src
+ # 1. Create main build directory
+ rm -rf %{kernel_build_dir}
+@@ -112,7 +112,7 @@ make EXTRAVERSION="-%{build_id}" O=%{kernel_build_dir}/linux-kernel-build-%{vers
+ %if %{with abidev}
+ echo "No linuks kernel ABI/API checks"
+ %else
+-( cd abi-checker/src; chmod 755 build_api_kernel_checker.sh; ./build_api_kernel_checker.sh "%{version}" "%{abiver}" )
++( cd tools/abi-checker/src; chmod 755 build_api_kernel_checker.sh; ./build_api_kernel_checker.sh "%{version}" "%{abiver}" )
+ %endif
+ make EXTRAVERSION="-%{build_id}" O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} uImage %{?jobs:-j%jobs}
+@@ -146,17 +146,17 @@ make INSTALL_PATH=%{buildroot}/boot INSTALL_MOD_PATH=%{buildroot} O=%{kernel_bui
+ make INSTALL_PATH=%{buildroot} INSTALL_MOD_PATH=%{buildroot} O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} INSTALL_HDR_PATH=%{buildroot}/usr headers_install
+ # 4.1 Install ABI/API tools
+-cp abi-checker/src/abi-checker %{buildroot}/usr/local/bin
+-cp abi-checker/src/abi-module-checker %{buildroot}/usr/local/bin
+-cp abi-checker/src/abi-module-dumper %{buildroot}/usr/local/bin
+-cp abi-checker/src/abi-module-kernels-list %{buildroot}/usr/local/bin
++cp tools/abi-checker/src/abi-checker %{buildroot}/usr/local/bin
++cp tools/abi-checker/src/abi-module-checker %{buildroot}/usr/local/bin
++cp tools/abi-checker/src/abi-module-dumper %{buildroot}/usr/local/bin
++cp tools/abi-checker/src/abi-module-kernels-list %{buildroot}/usr/local/bin
+ chmod 755 %{buildroot}/usr/local/bin/*
+ # 4.2 Install abi_%{version} file
+ %if %{with abidev}
+ find ../.. -name "Module.symvers" -exec cp {} %{buildroot}/boot/abi/abi_devel \;
+ %else
+-cp abi-checker/data/abi* %{buildroot}/boot/abi/.
++cp tools/abi-checker/data/abi* %{buildroot}/boot/abi/.
+ ln -sf /boot/abi/abi_%{version}_%{abiver} %{buildroot}/boot/abi/current
+ %endif
+@@ -183,7 +183,7 @@ rm -rf %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}/%{kernel
+ rm -f  %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}/source
+ rm -f  %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/source
+-rm -rf %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}/abi-checker
++rm -rf %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}/tools/abi-checker
+ rm -rf %{buildroot}/System.map*
+ rm -rf %{buildroot}/vmlinux*
+diff --git a/tools/abi-checker/data/abi_3.10.19_1 b/tools/abi-checker/data/abi_3.10.19_1
+new file mode 100644
+index 0000000..eea3455
+--- /dev/null
++++ b/tools/abi-checker/data/abi_3.10.19_1
+@@ -0,0 +1,6900 @@
++0x80e54114    cfg80211_send_rx_assoc  vmlinux EXPORT_SYMBOL
++0xd4dd4a5f    ipv6_chk_custom_prefix  vmlinux EXPORT_SYMBOL
++0x765592d7    generic_file_splice_write       vmlinux EXPORT_SYMBOL
++0x74f78b5f    set_anon_super  vmlinux EXPORT_SYMBOL
++0x88ea56ef    kmem_cache_alloc        vmlinux EXPORT_SYMBOL
++0x149d22ae    replace_page_cache_page vmlinux EXPORT_SYMBOL_GPL
++0x70523a7a    __cond_resched_softirq  vmlinux EXPORT_SYMBOL
++0x55417264    unregister_vt_notifier  vmlinux EXPORT_SYMBOL_GPL
++0xc2ea8e64    snd_soc_platform_read   vmlinux EXPORT_SYMBOL_GPL
++0x0a2487e0    unblock_all_signals     vmlinux EXPORT_SYMBOL
++0x260cf8f8    of_get_property vmlinux EXPORT_SYMBOL
++0x6ac315b3    v4l2_m2m_ioctl_dqbuf    vmlinux EXPORT_SYMBOL_GPL
++0x5c421d9d    i2c_put_adapter vmlinux EXPORT_SYMBOL
++0x4d8e0b9c    rtc_class_open  vmlinux EXPORT_SYMBOL_GPL
++0x96cd2b04    scsi_sense_key_string   vmlinux EXPORT_SYMBOL
++0xedf10a85    request_firmware        vmlinux EXPORT_SYMBOL
++0x70230d35    __hci_cmd_sync  vmlinux EXPORT_SYMBOL
++0x79dc2bec    dev_uc_sync     vmlinux EXPORT_SYMBOL
++0xeb396e95    dev_mc_sync     vmlinux EXPORT_SYMBOL
++0x80ca5026    _bin2bcd        vmlinux EXPORT_SYMBOL
++0xfbaaf01e    console_lock    vmlinux EXPORT_SYMBOL
++0xdf5311f6    hwmon_device_unregister vmlinux EXPORT_SYMBOL_GPL
++0xe113bbbc    csum_partial    vmlinux EXPORT_SYMBOL
++0x1ef4f43e    cfg80211_wext_siwscan   vmlinux EXPORT_SYMBOL_GPL
++0xb343d54f    cfg80211_wext_giwscan   vmlinux EXPORT_SYMBOL_GPL
++0xc068440e    __kfifo_alloc   vmlinux EXPORT_SYMBOL
++0x376eb932    kmap_atomic     vmlinux EXPORT_SYMBOL
++0xaadff4e7    nf_log_register vmlinux EXPORT_SYMBOL
++0xc8276a79    nf_hooks_needed vmlinux EXPORT_SYMBOL
++0x1b17e06c    kstrtoll        vmlinux EXPORT_SYMBOL
++0xa7d57242    scsi_execute    vmlinux EXPORT_SYMBOL
++0x9b757ebd    raw_seq_open    vmlinux EXPORT_SYMBOL_GPL
++0x1b479d00    snd_soc_of_parse_audio_routing  vmlinux EXPORT_SYMBOL_GPL
++0x3b2785b0    crypto_hash_walk_done   vmlinux EXPORT_SYMBOL_GPL
++0xa1d55e90    _raw_spin_lock_bh       vmlinux EXPORT_SYMBOL
++0xdd391eff    profile_event_unregister        vmlinux EXPORT_SYMBOL_GPL
++0xa724257f    init_uts_ns     vmlinux EXPORT_SYMBOL_GPL
++0xc97d1140    cpufreq_cooling_get_level       vmlinux EXPORT_SYMBOL_GPL
++0x5898fd79    device_add      vmlinux EXPORT_SYMBOL_GPL
++0x5081d0b3    device_del      vmlinux EXPORT_SYMBOL_GPL
++0x37246b6e    __inet6_hash    vmlinux EXPORT_SYMBOL
++0xad3a5766    dst_release     vmlinux EXPORT_SYMBOL
++0x1e254a30    sock_no_mmap    vmlinux EXPORT_SYMBOL
++0x854e1c0b    sg_nents        vmlinux EXPORT_SYMBOL
++0xb4c753a2    disk_map_sector_rcu     vmlinux EXPORT_SYMBOL_GPL
++0x942da6f0    sysfs_update_group      vmlinux EXPORT_SYMBOL_GPL
++0xa38602cd    drain_workqueue vmlinux EXPORT_SYMBOL_GPL
++0xd4b5f202    led_trigger_store       vmlinux EXPORT_SYMBOL_GPL
++0x80104269    tcp_initialize_rcv_mss  vmlinux EXPORT_SYMBOL
++0x54e6fcdd    net_enable_timestamp    vmlinux EXPORT_SYMBOL
++0xeb32f5c3    sockfd_lookup   vmlinux EXPORT_SYMBOL
++0x02aa8f04    snd_soc_dapm_get_pin_switch     vmlinux EXPORT_SYMBOL_GPL
++0x762265ad    snd_soc_dapm_put_pin_switch     vmlinux EXPORT_SYMBOL_GPL
++0xb0ffda2f    blk_limits_max_hw_sectors       vmlinux EXPORT_SYMBOL
++0x7cd8695d    directly_mappable_cdev_bdi      vmlinux EXPORT_SYMBOL
++0x6bc3fbc0    __unregister_chrdev     vmlinux EXPORT_SYMBOL
++0x6bb86c7d    srcu_notifier_chain_register    vmlinux EXPORT_SYMBOL_GPL
++0x4b661f3f    v4l2_ctrl_grab  vmlinux EXPORT_SYMBOL
++0xd2bbf775    fb_validate_mode        vmlinux EXPORT_SYMBOL
++0xe8d75b12    nfc_target_lost vmlinux EXPORT_SYMBOL
++0xb2d299a9    dev_graft_qdisc vmlinux EXPORT_SYMBOL
++0xa851973a    raw_notifier_call_chain vmlinux EXPORT_SYMBOL_GPL
++0x138709ec    scsi_get_command        vmlinux EXPORT_SYMBOL
++0x174afb1a    __sg_page_iter_next     vmlinux EXPORT_SYMBOL
++0x30cada8f    radix_tree_next_hole    vmlinux EXPORT_SYMBOL
++0xc0412578    scsi_target_quiesce     vmlinux EXPORT_SYMBOL
++0xd7a5d2f8    transport_class_register        vmlinux EXPORT_SYMBOL_GPL
++0xd2335101    drm_fb_get_bpp_depth    vmlinux EXPORT_SYMBOL
++0xa9a33fdf    jbd2_journal_try_to_free_buffers        vmlinux EXPORT_SYMBOL
++0xffd5a395    default_wake_function   vmlinux EXPORT_SYMBOL
++0xd6cb49e3    dm_put_device   vmlinux EXPORT_SYMBOL
++0xb6e1e07d    dm_get_device   vmlinux EXPORT_SYMBOL
++0x1f9218e9    input_handler_for_each_handle   vmlinux EXPORT_SYMBOL
++0x560c6863    transport_class_unregister      vmlinux EXPORT_SYMBOL_GPL
++0x65f3ad9a    fb_videomode_to_var     vmlinux EXPORT_SYMBOL
++0x79ad634c    nfc_hci_send_cmd_async  vmlinux EXPORT_SYMBOL
++0x6bbf9530    mount_subtree   vmlinux EXPORT_SYMBOL
++0x8f22ce41    iget_locked     vmlinux EXPORT_SYMBOL
++0x6fba7c75    sdhci_runtime_suspend_host      vmlinux EXPORT_SYMBOL_GPL
++0x7f923f2a    v4l2_of_parse_endpoint  vmlinux EXPORT_SYMBOL
++0xaa2d0ca7    input_mt_assign_slots   vmlinux EXPORT_SYMBOL
++0x167fd723    drm_mm_clean    vmlinux EXPORT_SYMBOL
++0x9733c21d    sock_get_timestampns    vmlinux EXPORT_SYMBOL
++0xf42e571f    snd_soc_dapm_put_enum_virt      vmlinux EXPORT_SYMBOL_GPL
++0xcd16649c    snd_soc_dapm_get_enum_virt      vmlinux EXPORT_SYMBOL_GPL
++0x38cb130f    iommu_group_add_device  vmlinux EXPORT_SYMBOL_GPL
++0xe90d597e    class_interface_register        vmlinux EXPORT_SYMBOL_GPL
++0x49ebacbd    _clear_bit      vmlinux EXPORT_SYMBOL
++0x853b6dce    nfc_tm_activated        vmlinux EXPORT_SYMBOL
++0xc617f82c    unregister_oom_notifier vmlinux EXPORT_SYMBOL_GPL
++0x8da9fa20    spi_get_device_id       vmlinux EXPORT_SYMBOL_GPL
++0x882f44c1    class_interface_unregister      vmlinux EXPORT_SYMBOL_GPL
++0x03757c9b    of_get_named_gpio_flags vmlinux EXPORT_SYMBOL
++0x1b68aba6    pin_config_set  vmlinux EXPORT_SYMBOL
++0x7505e34c    snd_power_wait  vmlinux EXPORT_SYMBOL
++0x44366cfc    simple_write_to_buffer  vmlinux EXPORT_SYMBOL
++0x3fec6133    read_code       vmlinux EXPORT_SYMBOL
++0xf7bb3a63    __srcu_read_unlock      vmlinux EXPORT_SYMBOL_GPL
++0xc2e587d1    reset_devices   vmlinux EXPORT_SYMBOL
++0x07b991fc    iio_kfifo_free  vmlinux EXPORT_SYMBOL
++0x36c38507    tty_register_device     vmlinux EXPORT_SYMBOL
++0xa5a633b9    sg_last vmlinux EXPORT_SYMBOL
++0x62c4e40d    __blk_run_queue vmlinux EXPORT_SYMBOL
++0x3eaf291d    param_get_string        vmlinux EXPORT_SYMBOL
++0x95cb929c    of_find_all_nodes       vmlinux EXPORT_SYMBOL
++0xc2c5a45e    mmc_app_cmd     vmlinux EXPORT_SYMBOL_GPL
++0xfa388487    usb_bus_list_lock       vmlinux EXPORT_SYMBOL_GPL
++0xdbbaeb6e    regulator_map_voltage_linear    vmlinux EXPORT_SYMBOL_GPL
++0x99bb8806    memmove vmlinux EXPORT_SYMBOL
++0x9e6e25f9    jbd2_journal_start_commit       vmlinux EXPORT_SYMBOL
++0x4c0f005a    __block_page_mkwrite    vmlinux EXPORT_SYMBOL
++0x76d3cd60    laptop_mode     vmlinux EXPORT_SYMBOL
++0x8fd01dea    generic_file_direct_write       vmlinux EXPORT_SYMBOL
++0xa1f38f97    end_page_writeback      vmlinux EXPORT_SYMBOL
++0xa75312bc    call_rcu_sched  vmlinux EXPORT_SYMBOL_GPL
++0xb67b2219    cm_suspend_again        vmlinux EXPORT_SYMBOL_GPL
++0x80311392    dmam_declare_coherent_memory    vmlinux EXPORT_SYMBOL
++0xf2e8c6fe    skb_recv_datagram       vmlinux EXPORT_SYMBOL
++0x4325cade    snd_soc_jack_add_pins   vmlinux EXPORT_SYMBOL_GPL
++0x69cadac1    d_alloc_pseudo  vmlinux EXPORT_SYMBOL
++0x871c0a7e    fiemap_check_flags      vmlinux EXPORT_SYMBOL
++0xd0804fe2    generic_file_readonly_mmap      vmlinux EXPORT_SYMBOL
++0xd06524ba    raw_notifier_chain_unregister   vmlinux EXPORT_SYMBOL_GPL
++0x26448a56    usbnet_cdc_unbind       vmlinux EXPORT_SYMBOL_GPL
++0x0bbae511    return_address  vmlinux EXPORT_SYMBOL_GPL
++0x0d542439    __ipv6_addr_type        vmlinux EXPORT_SYMBOL
++0xcf470397    unregister_qdisc        vmlinux EXPORT_SYMBOL
++0x66a8c67c    crypto_shash_finup      vmlinux EXPORT_SYMBOL_GPL
++0x5647361d    crypto_shash_final      vmlinux EXPORT_SYMBOL_GPL
++0xf1c942f4    crypto_ahash_finup      vmlinux EXPORT_SYMBOL_GPL
++0x17209ab0    crypto_ahash_final      vmlinux EXPORT_SYMBOL_GPL
++0x8da17b42    scatterwalk_copychunks  vmlinux EXPORT_SYMBOL_GPL
++0xd766d6a2    sdhci_suspend_host      vmlinux EXPORT_SYMBOL_GPL
++0x9b05a0c7    usb_autopm_get_interface        vmlinux EXPORT_SYMBOL_GPL
++0x8eff5a5b    phy_device_register     vmlinux EXPORT_SYMBOL
++0xa2101833    sock_diag_put_meminfo   vmlinux EXPORT_SYMBOL_GPL
++0xc8339e24    string_unescape vmlinux EXPORT_SYMBOL
++0xeb55a931    __kfifo_max_r   vmlinux EXPORT_SYMBOL
++0xe6511495    vm_insert_page  vmlinux EXPORT_SYMBOL
++0x4396b273    irq_domain_add_legacy   vmlinux EXPORT_SYMBOL_GPL
++0x24fdb0df    register_console        vmlinux EXPORT_SYMBOL
++0x6ac76b42    pin_is_valid    vmlinux EXPORT_SYMBOL_GPL
++0xe279ec34    nf_conntrack_l4proto_tcp4       vmlinux EXPORT_SYMBOL_GPL
++0x512ce34d    sock_no_socketpair      vmlinux EXPORT_SYMBOL
++0x236032ef    input_ff_event  vmlinux EXPORT_SYMBOL_GPL
++0x1e5431bd    devm_gpio_request       vmlinux EXPORT_SYMBOL
++0x86383d16    arpt_do_table   vmlinux EXPORT_SYMBOL
++0x3c89040c    dev_addr_del    vmlinux EXPORT_SYMBOL
++0xd900e010    gnet_stats_start_copy   vmlinux EXPORT_SYMBOL
++0x33f0768c    cpufreq_quick_get_max   vmlinux EXPORT_SYMBOL
++0xa88a70b0    tcp_tso_segment vmlinux EXPORT_SYMBOL
++0xa652c4ef    __kfifo_dma_in_prepare_r        vmlinux EXPORT_SYMBOL
++0xdfb895e4    __fat_fs_error  vmlinux EXPORT_SYMBOL_GPL
++0x00438c43    bio_copy_kern   vmlinux EXPORT_SYMBOL
++0xe0878bfe    __krealloc      vmlinux EXPORT_SYMBOL
++0xa849b57b    devm_free_irq   vmlinux EXPORT_SYMBOL
++0x995d1071    prof_on vmlinux EXPORT_SYMBOL_GPL
++0x3328c21e    task_nice       vmlinux EXPORT_SYMBOL
++0x84109a46    i2c_lock_adapter        vmlinux EXPORT_SYMBOL_GPL
++0x76f824bb    usb_gadget_set_state    vmlinux EXPORT_SYMBOL_GPL
++0x702c11cd    platform_device_del     vmlinux EXPORT_SYMBOL_GPL
++0xccfe749d    platform_device_put     vmlinux EXPORT_SYMBOL_GPL
++0x6499c2c3    kernel_accept   vmlinux EXPORT_SYMBOL
++0x0147e076    kset_create_and_add     vmlinux EXPORT_SYMBOL_GPL
++0xf60d1625    mm_kobj vmlinux EXPORT_SYMBOL_GPL
++0x66561d40    set_bdi_congested       vmlinux EXPORT_SYMBOL
++0xa064fc2f    gs_free_req     vmlinux EXPORT_SYMBOL_GPL
++0xaf70f0bf    xt_proto_fini   vmlinux EXPORT_SYMBOL_GPL
++0xc1e7bf31    devm_ioremap_resource   vmlinux EXPORT_SYMBOL
++0x71d3571b    sg_miter_start  vmlinux EXPORT_SYMBOL
++0xc5894dbd    blk_queue_unprep_rq     vmlinux EXPORT_SYMBOL
++0x159c0774    lock_may_read   vmlinux EXPORT_SYMBOL
++0x56d697ce    cpu_up  vmlinux EXPORT_SYMBOL_GPL
++0xba406d79    usb_gadget_map_request  vmlinux EXPORT_SYMBOL_GPL
++0xe2b9dcc5    wakeup_source_drop      vmlinux EXPORT_SYMBOL_GPL
++0x19011c29    driver_find     vmlinux EXPORT_SYMBOL_GPL
++0x13031824    devm_gpio_request_one   vmlinux EXPORT_SYMBOL
++0x91db6962    snd_card_free   vmlinux EXPORT_SYMBOL
++0x157b3f69    load_nls        vmlinux EXPORT_SYMBOL
++0xffe5318c    dma_buf_map_attachment  vmlinux EXPORT_SYMBOL_GPL
++0x10030de6    tty_mode_ioctl  vmlinux EXPORT_SYMBOL_GPL
++0x00109670    fb_class        vmlinux EXPORT_SYMBOL
++0x97999817    rfkill_set_hw_state     vmlinux EXPORT_SYMBOL
++0x6597fe84    crypto_lookup_aead      vmlinux EXPORT_SYMBOL_GPL
++0xd7b4b67a    bio_advance     vmlinux EXPORT_SYMBOL
++0x4b8408ef    from_kuid       vmlinux EXPORT_SYMBOL
++0xb65bd3fc    add_timer_on    vmlinux EXPORT_SYMBOL_GPL
++0x4859b8bb    rtc_year_days   vmlinux EXPORT_SYMBOL
++0xa064f393    ehci_cf_port_reset_rwsem        vmlinux EXPORT_SYMBOL_GPL
++0x0c65e73c    scsi_normalize_sense    vmlinux EXPORT_SYMBOL
++0x8e84b481    __pm_runtime_use_autosuspend    vmlinux EXPORT_SYMBOL_GPL
++0xab2495da    drm_mode_connector_detach_encoder       vmlinux EXPORT_SYMBOL
++0xbb11cfba    klist_iter_exit vmlinux EXPORT_SYMBOL_GPL
++0x84044a12    ip6_local_out   vmlinux EXPORT_SYMBOL_GPL
++0xc80b5684    snd_compress_deregister vmlinux EXPORT_SYMBOL_GPL
++0x215ebd78    bitrev16        vmlinux EXPORT_SYMBOL
++0x390def22    kstrtou16_from_user     vmlinux EXPORT_SYMBOL
++0x9a74417e    kstrtoull_from_user     vmlinux EXPORT_SYMBOL
++0x6949942d    pm_runtime_set_autosuspend_delay        vmlinux EXPORT_SYMBOL_GPL
++0xfb6eedf9    power_group_name        vmlinux EXPORT_SYMBOL_GPL
++0x7752eabc    snd_pcm_new_internal    vmlinux EXPORT_SYMBOL
++0x59cdb28e    crypto_aead_type        vmlinux EXPORT_SYMBOL_GPL
++0xeadf5b18    jbd2_journal_load       vmlinux EXPORT_SYMBOL
++0xcd6a7390    v4l2_i2c_new_subdev     vmlinux EXPORT_SYMBOL_GPL
++0x997574ce    device_unregister       vmlinux EXPORT_SYMBOL_GPL
++0xedbfb39a    serial8250_request_dma  vmlinux EXPORT_SYMBOL_GPL
++0x19a156ad    xfrm_state_add  vmlinux EXPORT_SYMBOL
++0x4d4a6141    __netlink_kernel_create vmlinux EXPORT_SYMBOL
++0x3ad82802    of_property_read_u32_index      vmlinux EXPORT_SYMBOL_GPL
++0x96b53df6    mmc_cleanup_queue       vmlinux EXPORT_SYMBOL
++0x7b9ee22c    v4l2_ctrl_notify        vmlinux EXPORT_SYMBOL
++0xda3a7ca9    regulator_is_enabled    vmlinux EXPORT_SYMBOL_GPL
++0x137def66    nf_ct_l4proto_put       vmlinux EXPORT_SYMBOL_GPL
++0x7efdb4fb    nf_ct_l3proto_put       vmlinux EXPORT_SYMBOL_GPL
++0x9948898e    dapm_mark_dirty vmlinux EXPORT_SYMBOL_GPL
++0x2484d571    single_release_net      vmlinux EXPORT_SYMBOL_GPL
++0x5612133a    I_BDEV  vmlinux EXPORT_SYMBOL
++0x7729cbdd    task_handoff_register   vmlinux EXPORT_SYMBOL_GPL
++0x19353b86    scsicam_bios_param      vmlinux EXPORT_SYMBOL
++0xb6a76b8e    pn544_hci_probe vmlinux EXPORT_SYMBOL
++0x476c3efa    drm_fill_in_dev vmlinux EXPORT_SYMBOL
++0x4f1cd128    security_tun_dev_create vmlinux EXPORT_SYMBOL
++0x76f29bbf    seq_release_net vmlinux EXPORT_SYMBOL_GPL
++0x980420fb    tty_port_tty_set        vmlinux EXPORT_SYMBOL
++0xc215715c    tty_port_tty_get        vmlinux EXPORT_SYMBOL
++0xa8c74dc5    devm_regulator_get      vmlinux EXPORT_SYMBOL_GPL
++0x3441c3d6    gpio_set_value_cansleep vmlinux EXPORT_SYMBOL_GPL
++0xcd68dc1d    nfc_get_local_general_bytes     vmlinux EXPORT_SYMBOL
++0xf617c0a1    inet_csk_route_child_sock       vmlinux EXPORT_SYMBOL_GPL
++0xfce4d2e1    vfs_path_lookup vmlinux EXPORT_SYMBOL
++0x326314e4    find_or_create_page     vmlinux EXPORT_SYMBOL
++0x65bbbc78    schedule_hrtimeout_range        vmlinux EXPORT_SYMBOL_GPL
++0x8d7b0a28    phy_stop_interrupts     vmlinux EXPORT_SYMBOL
++0xe9e87de1    crypto_register_pcomp   vmlinux EXPORT_SYMBOL_GPL
++0x2d7966fb    jbd2_journal_flush      vmlinux EXPORT_SYMBOL
++0x1c4e8441    invalidate_bdev vmlinux EXPORT_SYMBOL
++0x9aeacb87    ring_buffer_iter_empty  vmlinux EXPORT_SYMBOL_GPL
++0x49eb1c4a    put_pid_ns      vmlinux EXPORT_SYMBOL_GPL
++0xb7e67f9a    iio_sw_buffer_preenable vmlinux EXPORT_SYMBOL
++0xeae6b2cc    usb_sg_init     vmlinux EXPORT_SYMBOL_GPL
++0x2f33a47d    usb_sg_wait     vmlinux EXPORT_SYMBOL_GPL
++0xba136537    scsi_reset_provider     vmlinux EXPORT_SYMBOL
++0xa9170094    drm_kms_helper_hotplug_event    vmlinux EXPORT_SYMBOL
++0xb007d3b8    tcp_twsk_unique vmlinux EXPORT_SYMBOL_GPL
++0xd35091f2    netdev_info     vmlinux EXPORT_SYMBOL
++0x3517b864    kobject_uevent  vmlinux EXPORT_SYMBOL_GPL
++0x82a5ee54    mmc_try_claim_host      vmlinux EXPORT_SYMBOL
++0x11267875    scsi_extd_sense_format  vmlinux EXPORT_SYMBOL
++0x4f56540f    pm_wakeup_event vmlinux EXPORT_SYMBOL_GPL
++0x6c61ce70    num_registered_fb       vmlinux EXPORT_SYMBOL
++0xcc2f1602    st_sensors_sysfs_get_sampling_frequency vmlinux EXPORT_SYMBOL
++0x0bf95cc0    st_sensors_sysfs_set_sampling_frequency vmlinux EXPORT_SYMBOL
++0xa73fc98f    of_n_addr_cells vmlinux EXPORT_SYMBOL
++0xaf5c2852    wakeup_source_add       vmlinux EXPORT_SYMBOL_GPL
++0xc27732b1    snd_pcm_lib_default_mmap        vmlinux EXPORT_SYMBOL_GPL
++0x3ca17104    __snd_printk    vmlinux EXPORT_SYMBOL_GPL
++0xa6a59f23    blk_cleanup_queue       vmlinux EXPORT_SYMBOL
++0xec3364ec    generic_setlease        vmlinux EXPORT_SYMBOL
++0x440d8a62    tty_hung_up_p   vmlinux EXPORT_SYMBOL
++0xfa2e4ead    ip6_tnl_dst_store       vmlinux EXPORT_SYMBOL_GPL
++0x5a0647c1    ipv6_getsockopt vmlinux EXPORT_SYMBOL
++0x329bbbde    timerqueue_del  vmlinux EXPORT_SYMBOL_GPL
++0x34161524    st_sensors_read_event_value     vmlinux EXPORT_SYMBOL
++0x3e16c1b5    v4l2_clk_put    vmlinux EXPORT_SYMBOL
++0xdc047fc4    scsi_dev_info_list_add_keyed    vmlinux EXPORT_SYMBOL
++0xdc97af2e    syscore_suspend vmlinux EXPORT_SYMBOL_GPL
++0xaebbf521    cfg80211_ch_switch_notify       vmlinux EXPORT_SYMBOL
++0x4fdb4cdf    proc_mkdir_data vmlinux EXPORT_SYMBOL_GPL
++0x8ffad455    mpage_writepages        vmlinux EXPORT_SYMBOL
++0x258f05ac    write_one_page  vmlinux EXPORT_SYMBOL
++0x32b31a8c    ktime_get_boottime      vmlinux EXPORT_SYMBOL_GPL
++0x15892417    async_synchronize_cookie        vmlinux EXPORT_SYMBOL_GPL
++0x5a596330    v4l2_i2c_new_subdev_board       vmlinux EXPORT_SYMBOL_GPL
++0xbd05974a    usb_driver_release_interface    vmlinux EXPORT_SYMBOL_GPL
++0xce190a28    cfg80211_notify_new_peer_candidate      vmlinux EXPORT_SYMBOL
++0x23c45e2a    inet_add_protocol       vmlinux EXPORT_SYMBOL
++0xe19c66e3    sync_blockdev   vmlinux EXPORT_SYMBOL
++0xd36667e2    nobh_write_end  vmlinux EXPORT_SYMBOL
++0x815a1805    n_tty_ioctl_helper      vmlinux EXPORT_SYMBOL
++0xedd9106d    __ashrdi3       vmlinux EXPORT_SYMBOL
++0xff67b37f    __lshrdi3       vmlinux EXPORT_SYMBOL
++0x85b5e625    rfkill_set_states       vmlinux EXPORT_SYMBOL
++0x6e720ff2    rtnl_unlock     vmlinux EXPORT_SYMBOL
++0x4c02a5f2    sock_rfree      vmlinux EXPORT_SYMBOL
++0xe252485d    kernel_recvmsg  vmlinux EXPORT_SYMBOL
++0x0693eedb    disk_part_iter_init     vmlinux EXPORT_SYMBOL_GPL
++0x4019ac2a    freeze_bdev     vmlinux EXPORT_SYMBOL
++0x9f1c66aa    srcu_batches_completed  vmlinux EXPORT_SYMBOL_GPL
++0xa6ec6db0    sdhci_alloc_host        vmlinux EXPORT_SYMBOL_GPL
++0x0bfba95f    usb_hub_find_child      vmlinux EXPORT_SYMBOL_GPL
++0x9f83d040    __root_device_register  vmlinux EXPORT_SYMBOL_GPL
++0x63b124fc    drm_bl_dpms     vmlinux EXPORT_SYMBOL_GPL
++0xb35f8f7f    __hci_cmd_sync_ev       vmlinux EXPORT_SYMBOL
++0xe177ecc2    skb_kill_datagram       vmlinux EXPORT_SYMBOL
++0x985c6297    kfree_skb       vmlinux EXPORT_SYMBOL
++0xdcb83c11    kernel_kobj     vmlinux EXPORT_SYMBOL_GPL
++0x1bb5fc26    atomic_notifier_chain_register  vmlinux EXPORT_SYMBOL_GPL
++0xab1d6cc1    param_get_long  vmlinux EXPORT_SYMBOL
++0x75d68801    inet_twsk_schedule      vmlinux EXPORT_SYMBOL_GPL
++0x68b83ac6    posix_acl_alloc vmlinux EXPORT_SYMBOL
++0x306b23a8    drm_mm_takedown vmlinux EXPORT_SYMBOL
++0x698be398    regulator_get_voltage   vmlinux EXPORT_SYMBOL_GPL
++0xc8bed9c5    amba_driver_unregister  vmlinux EXPORT_SYMBOL
++0x1db7dc40    pgprot_kernel   vmlinux EXPORT_SYMBOL
++0x19e03378    cfg80211_get_p2p_attr   vmlinux EXPORT_SYMBOL
++0x44a5de9b    nfnetlink_parse_nat_setup_hook  vmlinux EXPORT_SYMBOL_GPL
++0x52d047db    skb_copy_datagram_iovec vmlinux EXPORT_SYMBOL
++0x731f351a    __kfree_skb     vmlinux EXPORT_SYMBOL
++0xd544b6fe    fuse_do_open    vmlinux EXPORT_SYMBOL_GPL
++0xd98f64fc    tty_port_register_device        vmlinux EXPORT_SYMBOL_GPL
++0xfd305341    walk_stackframe vmlinux EXPORT_SYMBOL
++0x58378f4a    snd_soc_dapm_force_enable_pin   vmlinux EXPORT_SYMBOL_GPL
++0x31b31f5c    csum_partial_copy_nocheck       vmlinux EXPORT_SYMBOL
++0xeea82d10    ip_defrag       vmlinux EXPORT_SYMBOL
++0xd75abd53    register_qdisc  vmlinux EXPORT_SYMBOL
++0xe4bf323c    snd_soc_test_bits       vmlinux EXPORT_SYMBOL_GPL
++0x5d891a64    idr_destroy     vmlinux EXPORT_SYMBOL
++0xeb9e7cdd    ida_destroy     vmlinux EXPORT_SYMBOL
++0x302b0f11    generic_file_aio_read   vmlinux EXPORT_SYMBOL
++0x3fe00f7d    mmc_can_discard vmlinux EXPORT_SYMBOL
++0x51246a07    mmc_interrupt_hpi       vmlinux EXPORT_SYMBOL
++0xce55bca9    scsi_flush_work vmlinux EXPORT_SYMBOL_GPL
++0x3ca53f5d    arpt_alloc_initial_table        vmlinux EXPORT_SYMBOL_GPL
++0x3ab45d33    free_netdev     vmlinux EXPORT_SYMBOL
++0xc9ec4e21    free_percpu     vmlinux EXPORT_SYMBOL_GPL
++0x431fd1f6    v4l2_subdev_queryctrl   vmlinux EXPORT_SYMBOL
++0x7c0f2bb5    drm_mm_create_block     vmlinux EXPORT_SYMBOL
++0x3fa79dd5    ip6_datagram_recv_ctl   vmlinux EXPORT_SYMBOL_GPL
++0xd56d7aae    sk_setup_caps   vmlinux EXPORT_SYMBOL_GPL
++0x668da8d5    zlib_inflateIncomp      vmlinux EXPORT_SYMBOL
++0xe0f99a2f    ida_pre_get     vmlinux EXPORT_SYMBOL
++0xf932015f    __raw_notifier_call_chain       vmlinux EXPORT_SYMBOL_GPL
++0x4d3c153f    sigprocmask     vmlinux EXPORT_SYMBOL
++0xd1974639    spi_sync_locked vmlinux EXPORT_SYMBOL_GPL
++0xdcbd7c06    scsi_host_get   vmlinux EXPORT_SYMBOL
++0x8ccc342d    drm_helper_move_panel_connectors_to_head        vmlinux EXPORT_SYMBOL
++0x98578bb6    regulator_bulk_get      vmlinux EXPORT_SYMBOL_GPL
++0x85ddc629    sk_stream_wait_connect  vmlinux EXPORT_SYMBOL
++0x4db49a03    vb2_ioctl_dqbuf vmlinux EXPORT_SYMBOL_GPL
++0xf720d75c    drm_vblank_init vmlinux EXPORT_SYMBOL
++0x8d551bef    sysctl_tcp_rmem vmlinux EXPORT_SYMBOL
++0x6c8c2ae7    sock_no_sendmsg vmlinux EXPORT_SYMBOL
++0x3b1b7e9f    snd_soc_bytes_get       vmlinux EXPORT_SYMBOL_GPL
++0xf74dae0f    idr_alloc       vmlinux EXPORT_SYMBOL_GPL
++0x7c666ca1    jbd2_journal_update_sb_errno    vmlinux EXPORT_SYMBOL
++0x98d00f33    vfs_unlink      vmlinux EXPORT_SYMBOL
++0x9ee85355    extcon_unregister_notifier      vmlinux EXPORT_SYMBOL_GPL
++0xf9e3887b    i2c_master_recv vmlinux EXPORT_SYMBOL
++0xaff711f1    drm_global_mutex        vmlinux EXPORT_SYMBOL
++0x62c5828a    nfc_hci_set_param       vmlinux EXPORT_SYMBOL
++0x52512e8e    nfc_hci_get_param       vmlinux EXPORT_SYMBOL
++0x4c90a5a9    lro_flush_all   vmlinux EXPORT_SYMBOL
++0xc5116125    pipe_unlock     vmlinux EXPORT_SYMBOL
++0x2d6bcdcb    iio_trigger_generic_data_rdy_poll       vmlinux EXPORT_SYMBOL
++0x48c6db53    of_get_child_by_name    vmlinux EXPORT_SYMBOL
++0x4379f0a6    genlmsg_multicast_allns vmlinux EXPORT_SYMBOL
++0x43e32587    __sock_recv_wifi_status vmlinux EXPORT_SYMBOL_GPL
++0x83a5ae2e    __tracepoint_rpm_resume vmlinux EXPORT_SYMBOL_GPL
++0xb2d48a2e    queue_work_on   vmlinux EXPORT_SYMBOL
++0x59d8223a    ioport_resource vmlinux EXPORT_SYMBOL
++0x73a25185    pm_generic_restore      vmlinux EXPORT_SYMBOL_GPL
++0x401ad827    bus_rescan_devices      vmlinux EXPORT_SYMBOL_GPL
++0x3b4e8e6c    serial8250_tx_dma       vmlinux EXPORT_SYMBOL_GPL
++0xba9f64c5    put_tty_driver  vmlinux EXPORT_SYMBOL
++0xa46a0fcf    backlight_force_update  vmlinux EXPORT_SYMBOL
++0xc7a4fbed    rtnl_lock       vmlinux EXPORT_SYMBOL
++0x27b3484e    debugfs_create_bool     vmlinux EXPORT_SYMBOL_GPL
++0x3691702f    generic_file_splice_read        vmlinux EXPORT_SYMBOL
++0xdd2efc0f    ring_buffer_reset_cpu   vmlinux EXPORT_SYMBOL_GPL
++0x2c1d69dc    prepare_kernel_cred     vmlinux EXPORT_SYMBOL
++0x897473df    mktime  vmlinux EXPORT_SYMBOL
++0xa8721b97    system_state    vmlinux EXPORT_SYMBOL
++0x2b768df3    iio_buffer_show_enable  vmlinux EXPORT_SYMBOL
++0xc3070585    xfrm6_tunnel_alloc_spi  vmlinux EXPORT_SYMBOL
++0x6e583bdd    udp_push_pending_frames vmlinux EXPORT_SYMBOL
++0xead6dbe6    splice_from_pipe_next   vmlinux EXPORT_SYMBOL
++0x6d044c26    param_ops_uint  vmlinux EXPORT_SYMBOL
++0x6f0036d9    del_timer_sync  vmlinux EXPORT_SYMBOL
++0xc9db98ec    hidinput_connect        vmlinux EXPORT_SYMBOL_GPL
++0xa3a75748    sec_bulk_read   vmlinux EXPORT_SYMBOL_GPL
++0x7c640527    bt_info vmlinux EXPORT_SYMBOL
++0x00e8097b    csum_partial_copy_fromiovecend  vmlinux EXPORT_SYMBOL
++0x098ef076    wm_hubs_vmid_ena        vmlinux EXPORT_SYMBOL_GPL
++0xc29591b4    drm_framebuffer_unreference     vmlinux EXPORT_SYMBOL
++0xdbfa4d5b    con_set_default_unimap  vmlinux EXPORT_SYMBOL
++0x08b75c5b    inet_diag_bc_sk vmlinux EXPORT_SYMBOL_GPL
++0x3dea553f    __qdisc_calculate_pkt_len       vmlinux EXPORT_SYMBOL
++0xab5f8242    dev_get_by_index        vmlinux EXPORT_SYMBOL
++0x3e9d0c22    wm8958_mic_detect       vmlinux EXPORT_SYMBOL_GPL
++0x462a2e75    match_strlcpy   vmlinux EXPORT_SYMBOL
++0xf768dabc    ioctl_by_bdev   vmlinux EXPORT_SYMBOL
++0x426b04e4    dma_buf_unmap_attachment        vmlinux EXPORT_SYMBOL_GPL
++0x27146b38    init_net        vmlinux EXPORT_SYMBOL
++0x9fe06761    wm_hubs_update_class_w  vmlinux EXPORT_SYMBOL_GPL
++0x8978d687    textsearch_find_continuous      vmlinux EXPORT_SYMBOL
++0xf7b12aee    __next_cpu      vmlinux EXPORT_SYMBOL
++0x96905151    crypto_larval_lookup    vmlinux EXPORT_SYMBOL_GPL
++0xb14bfc6b    __crypto_alloc_tfm      vmlinux EXPORT_SYMBOL_GPL
++0x3ca95bb3    configfs_unregister_subsystem   vmlinux EXPORT_SYMBOL
++0xd820c283    eventfd_ctx_remove_wait_queue   vmlinux EXPORT_SYMBOL_GPL
++0x699d1d6a    generic_delete_inode    vmlinux EXPORT_SYMBOL
++0xb5f17edf    perf_register_guest_info_callbacks      vmlinux EXPORT_SYMBOL_GPL
++0x1d209e24    mmc_power_restore_host  vmlinux EXPORT_SYMBOL
++0x8c66045e    cpufreq_freq_attr_scaling_boost_freqs   vmlinux EXPORT_SYMBOL_GPL
++0x6114d8a4    regulator_force_disable vmlinux EXPORT_SYMBOL_GPL
++0x7e606130    snd_soc_calc_bclk       vmlinux EXPORT_SYMBOL_GPL
++0xac480322    nf_nat_pptp_hook_expectfn       vmlinux EXPORT_SYMBOL_GPL
++0x7f19e69f    blk_run_queue   vmlinux EXPORT_SYMBOL
++0x98dbc3bc    mmc_wait_for_req        vmlinux EXPORT_SYMBOL
++0xa0d2b347    regmap_init_spi vmlinux EXPORT_SYMBOL_GPL
++0xff7a8968    regmap_init_i2c vmlinux EXPORT_SYMBOL_GPL
++0x98cc564a    regulator_set_voltage   vmlinux EXPORT_SYMBOL_GPL
++0xcd63c845    __aeabi_lasr    vmlinux EXPORT_SYMBOL
++0x8a4fa83b    __aeabi_llsr    vmlinux EXPORT_SYMBOL
++0x78cfc117    hci_register_dev        vmlinux EXPORT_SYMBOL
++0xd458f195    __secpath_destroy       vmlinux EXPORT_SYMBOL
++0xaf64ad0d    zlib_deflate    vmlinux EXPORT_SYMBOL
++0x24fdac79    wake_bit_function       vmlinux EXPORT_SYMBOL
++0x864f4a52    of_clk_add_provider     vmlinux EXPORT_SYMBOL_GPL
++0x1de054d5    of_clk_del_provider     vmlinux EXPORT_SYMBOL_GPL
++0x42c8e001    v4l2_ctrl_next  vmlinux EXPORT_SYMBOL
++0x1e95b9ac    i2c_smbus_write_i2c_block_data  vmlinux EXPORT_SYMBOL
++0xc61c11c2    inet_csk_route_req      vmlinux EXPORT_SYMBOL_GPL
++0xed597524    qdisc_get_rtab  vmlinux EXPORT_SYMBOL
++0x9a633fbd    fuse_request_send_background    vmlinux EXPORT_SYMBOL_GPL
++0x578e47c8    locks_release_private   vmlinux EXPORT_SYMBOL_GPL
++0x40ce485b    mempool_resize  vmlinux EXPORT_SYMBOL
++0xc60f75ec    __ftrace_vprintk        vmlinux EXPORT_SYMBOL_GPL
++0xb88fb22f    hid_set_field   vmlinux EXPORT_SYMBOL_GPL
++0xd954e4a7    bus_remove_file vmlinux EXPORT_SYMBOL_GPL
++0x6172f515    xfrm_unregister_km      vmlinux EXPORT_SYMBOL
++0xc5e4258e    in_dev_finish_destroy   vmlinux EXPORT_SYMBOL
++0xe094ef39    sg_next vmlinux EXPORT_SYMBOL
++0x6b4be175    bio_map_user    vmlinux EXPORT_SYMBOL
++0x0b07abe2    unshare_fs_struct       vmlinux EXPORT_SYMBOL_GPL
++0x2ef6b5bf    smp_call_function_any   vmlinux EXPORT_SYMBOL_GPL
++0xd0fb7cd4    __tasklet_hi_schedule_first     vmlinux EXPORT_SYMBOL
++0xe35c5285    of_find_node_by_phandle vmlinux EXPORT_SYMBOL
++0x55724b35    hid_destroy_device      vmlinux EXPORT_SYMBOL_GPL
++0x85ad5803    cfg80211_wext_siwrts    vmlinux EXPORT_SYMBOL_GPL
++0x87cfc6e0    cfg80211_wext_giwrts    vmlinux EXPORT_SYMBOL_GPL
++0xd1b091c0    unix_inq_len    vmlinux EXPORT_SYMBOL_GPL
++0xc4d21124    __nf_conntrack_confirm  vmlinux EXPORT_SYMBOL_GPL
++0x452a56c2    __brelse        vmlinux EXPORT_SYMBOL
++0xbddeca9d    pipe_lock       vmlinux EXPORT_SYMBOL
++0x33bfdca2    gserial_alloc_line      vmlinux EXPORT_SYMBOL_GPL
++0x4edb7421    config_ep_by_speed      vmlinux EXPORT_SYMBOL_GPL
++0xa473e3d4    usbnet_suspend  vmlinux EXPORT_SYMBOL_GPL
++0x06521223    mdiobus_scan    vmlinux EXPORT_SYMBOL
++0xed8f1a2b    dmam_alloc_coherent     vmlinux EXPORT_SYMBOL
++0x9535ce7b    tty_port_carrier_raised vmlinux EXPORT_SYMBOL
++0x71280d73    regulator_set_voltage_time_sel  vmlinux EXPORT_SYMBOL_GPL
++0x1e314b21    regulator_use_dummy_regulator   vmlinux EXPORT_SYMBOL_GPL
++0x347fd4b3    eventfd_ctx_get vmlinux EXPORT_SYMBOL_GPL
++0x941f2aaa    eventfd_ctx_put vmlinux EXPORT_SYMBOL_GPL
++0xf9d18552    mark_buffer_async_write vmlinux EXPORT_SYMBOL
++0x6c6cdd4d    wait_for_completion_interruptible_timeout       vmlinux EXPORT_SYMBOL
++0xe5525b81    scsi_device_set_state   vmlinux EXPORT_SYMBOL
++0x28e23139    xfrm_probe_algs vmlinux EXPORT_SYMBOL_GPL
++0x9a9ff422    ip_route_me_harder      vmlinux EXPORT_SYMBOL
++0xb7cbbafa    inet_sock_destruct      vmlinux EXPORT_SYMBOL
++0xf26e8a56    nf_reinject     vmlinux EXPORT_SYMBOL
++0x3a9b6fb9    blk_unregister_region   vmlinux EXPORT_SYMBOL
++0x2a2c3036    unregister_nls  vmlinux EXPORT_SYMBOL
++0x5358fc36    ring_buffer_discard_commit      vmlinux EXPORT_SYMBOL_GPL
++0x555621fa    clk_enable      vmlinux EXPORT_SYMBOL_GPL
++0xf25af73c    mmc_add_host    vmlinux EXPORT_SYMBOL
++0x4b02b5ca    dev_pm_qos_update_request       vmlinux EXPORT_SYMBOL_GPL
++0xe11c3bb2    tty_chars_in_buffer     vmlinux EXPORT_SYMBOL
++0x4e60ec09    __serio_register_port   vmlinux EXPORT_SYMBOL
++0xc17515d7    usb_hcds_loaded vmlinux EXPORT_SYMBOL_GPL
++0xadfe5127    usbnet_write_cmd_nopm   vmlinux EXPORT_SYMBOL_GPL
++0x9c6c1c9c    phy_exit        vmlinux EXPORT_SYMBOL_GPL
++0x44da5d0f    __csum_ipv6_magic       vmlinux EXPORT_SYMBOL
++0x2ef42c91    l2cap_register_user     vmlinux EXPORT_SYMBOL
++0xa83b115e    skb_pull_rcsum  vmlinux EXPORT_SYMBOL_GPL
++0xbaa490f8    snd_ctl_unregister_ioctl        vmlinux EXPORT_SYMBOL
++0xe3df2eb1    v4l2_async_notifier_register    vmlinux EXPORT_SYMBOL
++0x950c4994    __scsi_device_lookup_by_target  vmlinux EXPORT_SYMBOL
++0xed3baf1d    tcp_fetch_timewait_stamp        vmlinux EXPORT_SYMBOL_GPL
++0xebdbe48c    radix_tree_gang_lookup  vmlinux EXPORT_SYMBOL
++0xc00b1f1e    register_nls    vmlinux EXPORT_SYMBOL
++0x62543231    locks_alloc_lock        vmlinux EXPORT_SYMBOL_GPL
++0x6585e310    alloc_pages_exact_nid   vmlinux EXPORT_SYMBOL
++0xb121390a    probe_irq_on    vmlinux EXPORT_SYMBOL
++0xc58f706b    usbnet_get_msglevel     vmlinux EXPORT_SYMBOL_GPL
++0x1007becd    usbnet_set_msglevel     vmlinux EXPORT_SYMBOL_GPL
++0xb9eb9d79    pm_generic_suspend      vmlinux EXPORT_SYMBOL_GPL
++0xca860514    xfrm_state_lookup       vmlinux EXPORT_SYMBOL
++0x795598eb    tcp_parse_options       vmlinux EXPORT_SYMBOL
++0x17a3ce1e    rps_may_expire_flow     vmlinux EXPORT_SYMBOL
++0x7b3d29ac    i2c_smbus_write_block_data      vmlinux EXPORT_SYMBOL
++0x8164b1cc    ump_dd_handle_create_from_secure_id     vmlinux EXPORT_SYMBOL
++0x7f04682a    of_gpio_simple_xlate    vmlinux EXPORT_SYMBOL
++0xefd6cf06    __aeabi_unwind_cpp_pr0  vmlinux EXPORT_SYMBOL
++0xb7ba76c7    __aeabi_unwind_cpp_pr2  vmlinux EXPORT_SYMBOL
++0x43f0af31    snd_soc_codec_set_pll   vmlinux EXPORT_SYMBOL_GPL
++0x6e46b07b    module_refcount vmlinux EXPORT_SYMBOL
++0x455348d7    usb_composite_probe     vmlinux EXPORT_SYMBOL_GPL
++0x0e8110c3    sec_reg_write   vmlinux EXPORT_SYMBOL_GPL
++0xba0edce6    inet_ctl_sock_create    vmlinux EXPORT_SYMBOL_GPL
++0x8454f899    dev_addr_add_multiple   vmlinux EXPORT_SYMBOL
++0x62e4112b    _submit_bh      vmlinux EXPORT_SYMBOL_GPL
++0x715622e2    handle_edge_irq vmlinux EXPORT_SYMBOL
++0x0e639705    usbnet_link_change      vmlinux EXPORT_SYMBOL
++0x8043eb8c    firmware_kobj   vmlinux EXPORT_SYMBOL_GPL
++0x130bf78b    drm_mode_create_from_cmdline_mode       vmlinux EXPORT_SYMBOL
++0xbdd37f04    usb_autopm_put_interface_async  vmlinux EXPORT_SYMBOL_GPL
++0x63c46f03    usb_lock_device_for_reset       vmlinux EXPORT_SYMBOL_GPL
++0x1bc5eebe    pinctrl_gpio_direction_input    vmlinux EXPORT_SYMBOL_GPL
++0x519b061e    genl_register_mc_group  vmlinux EXPORT_SYMBOL
++0xf81e0907    ___pskb_trim    vmlinux EXPORT_SYMBOL
++0xd352e668    snd_timer_global_new    vmlinux EXPORT_SYMBOL
++0x85df9b6c    strsep  vmlinux EXPORT_SYMBOL
++0xe2d5255a    strcmp  vmlinux EXPORT_SYMBOL
++0x788fe103    iomem_resource  vmlinux EXPORT_SYMBOL
++0xe7a9a6a0    tty_driver_flush_buffer vmlinux EXPORT_SYMBOL
++0xd648e564    fb_match_mode   vmlinux EXPORT_SYMBOL
++0xbc10dd97    __put_user_4    vmlinux EXPORT_SYMBOL
++0x353e3fa5    __get_user_4    vmlinux EXPORT_SYMBOL
++0xe50ad8a8    snd_ctl_add     vmlinux EXPORT_SYMBOL
++0x6323f87b    mnt_unpin       vmlinux EXPORT_SYMBOL
++0xbb524006    vfs_create      vmlinux EXPORT_SYMBOL
++0x2f47d8c7    cpufreq_frequency_get_table     vmlinux EXPORT_SYMBOL_GPL
++0xda44cb37    setup_charger_manager   vmlinux EXPORT_SYMBOL_GPL
++0x01ab74a6    devm_kfree      vmlinux EXPORT_SYMBOL_GPL
++0x153be8a8    drm_fb_helper_pan_display       vmlinux EXPORT_SYMBOL
++0xc676a007    __ablkcipher_walk_complete      vmlinux EXPORT_SYMBOL_GPL
++0x868bf31d    sb_min_blocksize        vmlinux EXPORT_SYMBOL
++0xaf5f7994    remove_conflicting_framebuffers vmlinux EXPORT_SYMBOL
++0x49e5aa17    bt_procfs_init  vmlinux EXPORT_SYMBOL
++0xf353a698    register_module_notifier        vmlinux EXPORT_SYMBOL
++0x154c6338    dm_kcopyd_client_destroy        vmlinux EXPORT_SYMBOL
++0xdd4cc94f    v4l2_device_set_name    vmlinux EXPORT_SYMBOL_GPL
++0x703189d7    regulator_get_mode      vmlinux EXPORT_SYMBOL_GPL
++0x43028a27    nfc_hci_result_to_errno vmlinux EXPORT_SYMBOL
++0x0551f0ce    tick_nohz_idle_exit     vmlinux EXPORT_SYMBOL_GPL
++0xc7208c3a    serial8250_resume_port  vmlinux EXPORT_SYMBOL
++0xe91355f8    inet_csk_clone_lock     vmlinux EXPORT_SYMBOL_GPL
++0xe912da6b    unregister_sysctl_table vmlinux EXPORT_SYMBOL
++0xaf91d89f    __kernel_param_lock     vmlinux EXPORT_SYMBOL
++0x31cdd70c    hid_input_report        vmlinux EXPORT_SYMBOL_GPL
++0xd73ee981    cdc_ncm_fill_tx_frame   vmlinux EXPORT_SYMBOL_GPL
++0xa01c6bfd    del_gendisk     vmlinux EXPORT_SYMBOL
++0x4d74d134    block_write_full_page   vmlinux EXPORT_SYMBOL
++0x43632d7d    of_find_property        vmlinux EXPORT_SYMBOL
++0xa76550fa    xfrm_register_type      vmlinux EXPORT_SYMBOL
++0xde08bdaf    nf_ct_invert_tuple      vmlinux EXPORT_SYMBOL_GPL
++0xa61aa028    snd_pcm_format_unsigned vmlinux EXPORT_SYMBOL
++0x0b51f3e2    fat_sync_inode  vmlinux EXPORT_SYMBOL_GPL
++0xb3e441b1    clear_bdi_congested     vmlinux EXPORT_SYMBOL
++0x9305f8e6    cpufreq_get     vmlinux EXPORT_SYMBOL
++0x8708f581    usbnet_stop     vmlinux EXPORT_SYMBOL_GPL
++0x581e0fb1    sock_no_setsockopt      vmlinux EXPORT_SYMBOL
++0xdf40231d    sock_no_getsockopt      vmlinux EXPORT_SYMBOL
++0xa3355ffa    snd_soc_default_writable_register       vmlinux EXPORT_SYMBOL_GPL
++0xb8ba4a80    __blockdev_direct_IO    vmlinux EXPORT_SYMBOL
++0x4f70015c    splice_from_pipe_end    vmlinux EXPORT_SYMBOL
++0x93658a27    migrate_page    vmlinux EXPORT_SYMBOL
++0x2e45e488    rcu_note_context_switch vmlinux EXPORT_SYMBOL_GPL
++0xf0d68ed6    clk_register_clkdevs    vmlinux EXPORT_SYMBOL
++0xec58fd46    ip6_route_me_harder     vmlinux EXPORT_SYMBOL
++0xccec571a    thermal_zone_device_update      vmlinux EXPORT_SYMBOL_GPL
++0x011c6bf0    regulator_map_voltage_iterate   vmlinux EXPORT_SYMBOL_GPL
++0x44eabd85    km_new_mapping  vmlinux EXPORT_SYMBOL
++0x4469fe89    lro_receive_skb vmlinux EXPORT_SYMBOL
++0x6d54f969    napi_complete   vmlinux EXPORT_SYMBOL
++0xb740018f    snd_device_new  vmlinux EXPORT_SYMBOL
++0xab363caa    generic_block_bmap      vmlinux EXPORT_SYMBOL
++0x868784cb    __symbol_get    vmlinux EXPORT_SYMBOL_GPL
++0x142a8be4    of_clk_get_parent_name  vmlinux EXPORT_SYMBOL_GPL
++0x991484c4    of_property_count_strings       vmlinux EXPORT_SYMBOL_GPL
++0x5f3c8f5c    mmc_assume_removable    vmlinux EXPORT_SYMBOL
++0xf9c1f53f    pm_generic_thaw_early   vmlinux EXPORT_SYMBOL_GPL
++0x47229b5c    gpio_request    vmlinux EXPORT_SYMBOL_GPL
++0x517deb22    __ip_dev_find   vmlinux EXPORT_SYMBOL
++0x815fe221    snd_pcm_hw_constraint_list      vmlinux EXPORT_SYMBOL
++0xbe0e5118    nla_memcmp      vmlinux EXPORT_SYMBOL
++0xf1db1704    nla_memcpy      vmlinux EXPORT_SYMBOL
++0x1f77b093    file_remove_suid        vmlinux EXPORT_SYMBOL
++0xfd6794fe    d_materialise_unique    vmlinux EXPORT_SYMBOL_GPL
++0x26622a2b    kmem_cache_free vmlinux EXPORT_SYMBOL
++0x7aab19fb    vb2_ops_wait_prepare    vmlinux EXPORT_SYMBOL_GPL
++0x5d22b406    rndis_register  vmlinux EXPORT_SYMBOL
++0xd25dc9c5    cdc_ncm_rx_verify_nth16 vmlinux EXPORT_SYMBOL_GPL
++0x8299a21a    ieee80211_data_from_8023        vmlinux EXPORT_SYMBOL
++0x499cb58c    prepare_to_wait vmlinux EXPORT_SYMBOL
++0xadf42bd5    __request_region        vmlinux EXPORT_SYMBOL
++0x9f560253    get_cpu_device  vmlinux EXPORT_SYMBOL_GPL
++0x923b1276    dmaengine_get   vmlinux EXPORT_SYMBOL
++0x56d9b1de    amba_device_register    vmlinux EXPORT_SYMBOL
++0x6fa16209    bdev_read_only  vmlinux EXPORT_SYMBOL
++0xf0009fee    put_pages_list  vmlinux EXPORT_SYMBOL
++0xdf73013e    from_kprojid    vmlinux EXPORT_SYMBOL
++0x2609451c    sock_wfree      vmlinux EXPORT_SYMBOL
++0x0de80eba    snd_soc_info_volsw      vmlinux EXPORT_SYMBOL_GPL
++0xd7f77051    test_set_page_writeback vmlinux EXPORT_SYMBOL
++0xa734a3e9    abort_exclusive_wait    vmlinux EXPORT_SYMBOL
++0x091eb9b4    round_jiffies   vmlinux EXPORT_SYMBOL_GPL
++0x99429b47    display_entity_unregister       vmlinux EXPORT_SYMBOL_GPL
++0x40d0b751    qdisc_destroy   vmlinux EXPORT_SYMBOL
++0x16445cb3    inet_proto_csum_replace16       vmlinux EXPORT_SYMBOL
++0x5594be03    bitmap_remap    vmlinux EXPORT_SYMBOL
++0x7fe04a49    truncate_inode_pages    vmlinux EXPORT_SYMBOL
++0x42f865b4    fb_videomode_from_videomode     vmlinux EXPORT_SYMBOL_GPL
++0x0422fe4a    inet_csk_timer_bug_msg  vmlinux EXPORT_SYMBOL
++0x1b0c9510    sysfs_notify    vmlinux EXPORT_SYMBOL_GPL
++0x0948cde9    num_physpages   vmlinux EXPORT_SYMBOL
++0x7818fe23    input_flush_device      vmlinux EXPORT_SYMBOL
++0x2da17677    regmap_bulk_write       vmlinux EXPORT_SYMBOL_GPL
++0x03ba39b0    v7_flush_user_cache_all vmlinux EXPORT_SYMBOL
++0x9d0403b2    inet_hash       vmlinux EXPORT_SYMBOL_GPL
++0x9a1dfd65    strpbrk vmlinux EXPORT_SYMBOL
++0xa040153b    sysfs_create_file       vmlinux EXPORT_SYMBOL_GPL
++0x99cbae17    seq_lseek       vmlinux EXPORT_SYMBOL
++0x092c2a7a    irq_domain_add_tree     vmlinux EXPORT_SYMBOL_GPL
++0x23a42148    media_entity_pipeline_stop      vmlinux EXPORT_SYMBOL_GPL
++0xd87b6687    ip6_frag_match  vmlinux EXPORT_SYMBOL
++0x9e6d79f8    snd_info_get_str        vmlinux EXPORT_SYMBOL
++0x1551dc51    bitmap_find_free_region vmlinux EXPORT_SYMBOL
++0x9f491e5d    ftrace_print_symbols_seq_u64    vmlinux EXPORT_SYMBOL
++0x9b6bedb6    sdhci_add_host  vmlinux EXPORT_SYMBOL_GPL
++0x928f84b5    drm_crtc_init   vmlinux EXPORT_SYMBOL
++0x56b63670    lzo1x_1_compress        vmlinux EXPORT_SYMBOL_GPL
++0x637d3d6a    set_disk_ro     vmlinux EXPORT_SYMBOL
++0x5053e2a6    leds_list_lock  vmlinux EXPORT_SYMBOL_GPL
++0x19fc7f60    regulator_set_mode      vmlinux EXPORT_SYMBOL_GPL
++0x7e703a3d    snd_soc_limit_volume    vmlinux EXPORT_SYMBOL_GPL
++0x3bdbf275    sg_alloc_table_from_pages       vmlinux EXPORT_SYMBOL
++0xb87bf605    blk_rq_unprep_clone     vmlinux EXPORT_SYMBOL_GPL
++0xe04f7caa    dm_read_arg_group       vmlinux EXPORT_SYMBOL
++0xb26725f8    bus_find_device vmlinux EXPORT_SYMBOL_GPL
++0x7ff32312    drm_gem_handle_create   vmlinux EXPORT_SYMBOL
++0xcd7edbe9    cfg80211_sched_scan_results     vmlinux EXPORT_SYMBOL
++0x92dbc6c1    xfrm_aalg_get_byid      vmlinux EXPORT_SYMBOL_GPL
++0x6fb14f17    tcp_create_openreq_child        vmlinux EXPORT_SYMBOL
++0x2f368d4c    sk_common_release       vmlinux EXPORT_SYMBOL
++0xd60281a9    st_sensors_set_fullscale_by_gain        vmlinux EXPORT_SYMBOL
++0x228bec81    led_trigger_register    vmlinux EXPORT_SYMBOL_GPL
++0x28c52e3f    video_device_release    vmlinux EXPORT_SYMBOL
++0x3faac56f    drm_mode_set_config_internal    vmlinux EXPORT_SYMBOL
++0xf86d3493    skb_queue_head  vmlinux EXPORT_SYMBOL
++0x5fd1e756    skb_prepare_seq_read    vmlinux EXPORT_SYMBOL
++0x02ff8c3e    sk_reset_timer  vmlinux EXPORT_SYMBOL
++0xb08f47ec    snd_soc_resume  vmlinux EXPORT_SYMBOL_GPL
++0x0f055dad    snd_pcm_hw_rule_noresample      vmlinux EXPORT_SYMBOL
++0x9529f10a    fuse_conn_put   vmlinux EXPORT_SYMBOL_GPL
++0xf6bb8bf1    irq_get_irq_data        vmlinux EXPORT_SYMBOL_GPL
++0x02c3c736    v4l2_subdev_querymenu   vmlinux EXPORT_SYMBOL
++0xfb42deb3    drm_helper_mode_fill_fb_struct  vmlinux EXPORT_SYMBOL
++0x4920a692    regulator_bulk_enable   vmlinux EXPORT_SYMBOL_GPL
++0x85963907    netdev_has_upper_dev    vmlinux EXPORT_SYMBOL
++0x5f58f676    flex_array_get_ptr      vmlinux EXPORT_SYMBOL
++0x3e6c012e    bio_alloc_bioset        vmlinux EXPORT_SYMBOL
++0xb9ac0503    mali_set_user_setting   vmlinux EXPORT_SYMBOL
++0xbd22a332    drm_pci_free    vmlinux EXPORT_SYMBOL
++0x171addd2    ieee80211_get_hdrlen_from_skb   vmlinux EXPORT_SYMBOL
++0xe41115b7    vfs_cancel_lock vmlinux EXPORT_SYMBOL_GPL
++0x912c123d    pm_qos_remove_request   vmlinux EXPORT_SYMBOL_GPL
++0x8e2d17cc    v4l2_clk_enable vmlinux EXPORT_SYMBOL
++0xfe3150df    usb_driver_set_configuration    vmlinux EXPORT_SYMBOL_GPL
++0x3b5bb4f2    mii_ethtool_sset        vmlinux EXPORT_SYMBOL
++0xe9bc24c2    mii_ethtool_gset        vmlinux EXPORT_SYMBOL
++0x62e1f48d    class_compat_create_link        vmlinux EXPORT_SYMBOL_GPL
++0xb602c57e    nf_ct_l3proto_module_put        vmlinux EXPORT_SYMBOL_GPL
++0xcd4b940c    release_sock    vmlinux EXPORT_SYMBOL
++0x90e5450f    textsearch_destroy      vmlinux EXPORT_SYMBOL
++0x50e7193a    __i2c_first_dynamic_bus_num     vmlinux EXPORT_SYMBOL_GPL
++0xa2a8e81f    class_remove_file       vmlinux EXPORT_SYMBOL_GPL
++0x95f56edb    drm_i2c_encoder_init    vmlinux EXPORT_SYMBOL
++0xdd1dd3a7    snd_pcm_hw_constraint_msbits    vmlinux EXPORT_SYMBOL
++0x23a574fd    security_secmark_relabel_packet vmlinux EXPORT_SYMBOL
++0x3f01eca9    unmap_underlying_metadata       vmlinux EXPORT_SYMBOL
++0x55feec9e    sync_inode      vmlinux EXPORT_SYMBOL
++0xb859f38b    krealloc        vmlinux EXPORT_SYMBOL
++0x9af5fc30    of_phy_connect_fixed_link       vmlinux EXPORT_SYMBOL
++0xa2307653    v4l2_device_register_subdev_nodes       vmlinux EXPORT_SYMBOL_GPL
++0x66e9dc03    usbnet_status_stop      vmlinux EXPORT_SYMBOL_GPL
++0x419a9395    snd_card_create vmlinux EXPORT_SYMBOL
++0x9edc4cdb    __invalidate_device     vmlinux EXPORT_SYMBOL
++0x301fa826    seq_put_decimal_ull     vmlinux EXPORT_SYMBOL
++0x8f7b5061    jack_event_handler      vmlinux EXPORT_SYMBOL_GPL
++0xf8e6aed1    input_register_device   vmlinux EXPORT_SYMBOL
++0xfba9b108    drm_fb_helper_fini      vmlinux EXPORT_SYMBOL
++0x31266931    con_debug_leave vmlinux EXPORT_SYMBOL_GPL
++0x2ba707a8    sysctl_tcp_low_latency  vmlinux EXPORT_SYMBOL
++0x1163f0a7    blk_max_low_pfn vmlinux EXPORT_SYMBOL
++0x94c6b808    blk_queue_free_tags     vmlinux EXPORT_SYMBOL
++0xe0413655    elv_unregister_queue    vmlinux EXPORT_SYMBOL
++0x3fab3ca9    register_sysctl_table   vmlinux EXPORT_SYMBOL
++0x67b78eb3    seq_hlist_next_rcu      vmlinux EXPORT_SYMBOL
++0x571767e3    led_classdev_unregister vmlinux EXPORT_SYMBOL_GPL
++0x9323826a    ipv4_redirect   vmlinux EXPORT_SYMBOL_GPL
++0x495c96f8    posix_acl_init  vmlinux EXPORT_SYMBOL
++0xd59c42a1    drm_idlelock_release    vmlinux EXPORT_SYMBOL
++0x490355ba    tty_flip_buffer_push    vmlinux EXPORT_SYMBOL
++0x3ef6c408    bio_copy_data   vmlinux EXPORT_SYMBOL
++0x6fe3d8cf    ktime_add_safe  vmlinux EXPORT_SYMBOL_GPL
++0xf9a482f9    msleep  vmlinux EXPORT_SYMBOL
++0xc66b77b1    iommu_group_set_iommudata       vmlinux EXPORT_SYMBOL_GPL
++0xd55ad93b    iommu_group_get_iommudata       vmlinux EXPORT_SYMBOL_GPL
++0x0d0549e1    hidinput_calc_abs_res   vmlinux EXPORT_SYMBOL_GPL
++0x07608656    uart_get_divisor        vmlinux EXPORT_SYMBOL
++0xc8f72480    unregister_netdev       vmlinux EXPORT_SYMBOL
++0x1ce42553    __bforget       vmlinux EXPORT_SYMBOL
++0x8427e5bd    v4l2_event_subdev_unsubscribe   vmlinux EXPORT_SYMBOL_GPL
++0x8e865d3c    arm_delay_ops   vmlinux EXPORT_SYMBOL
++0x2f88c16b    inet6_add_protocol      vmlinux EXPORT_SYMBOL
++0x9fda569e    raw_unhash_sk   vmlinux EXPORT_SYMBOL_GPL
++0x1def6812    xt_register_table       vmlinux EXPORT_SYMBOL_GPL
++0xe7e87d7a    set_h225_addr_hook      vmlinux EXPORT_SYMBOL_GPL
++0xd2037371    sock_no_listen  vmlinux EXPORT_SYMBOL
++0x33607e14    snd_soc_poweroff        vmlinux EXPORT_SYMBOL_GPL
++0xab600421    probe_irq_off   vmlinux EXPORT_SYMBOL
++0xfc8ace2f    input_mt_destroy_slots  vmlinux EXPORT_SYMBOL
++0xf222f80f    usb_unpoison_anchored_urbs      vmlinux EXPORT_SYMBOL_GPL
++0x4845cdbc    scsi_device_lookup_by_target    vmlinux EXPORT_SYMBOL
++0x79aa04a2    get_random_bytes        vmlinux EXPORT_SYMBOL
++0x9db44776    nfc_hci_connect_gate    vmlinux EXPORT_SYMBOL
++0x4d2726f3    tcf_exts_destroy        vmlinux EXPORT_SYMBOL
++0xbaa8249a    snd_ctl_activate_id     vmlinux EXPORT_SYMBOL_GPL
++0x55ef85b4    blk_peek_request        vmlinux EXPORT_SYMBOL
++0xc8b267ae    seq_vprintf     vmlinux EXPORT_SYMBOL
++0xe6504df3    sdhci_get_of_property   vmlinux EXPORT_SYMBOL_GPL
++0x3ad12077    regcache_sync_region    vmlinux EXPORT_SYMBOL_GPL
++0x80af255f    pm_runtime_allow        vmlinux EXPORT_SYMBOL_GPL
++0x16105b8e    do_unbind_con_driver    vmlinux EXPORT_SYMBOL_GPL
++0xdaf4dfb3    fb_mode_option  vmlinux EXPORT_SYMBOL_GPL
++0x1f5dd478    tcf_hash_lookup vmlinux EXPORT_SYMBOL
++0x14965155    sock_no_poll    vmlinux EXPORT_SYMBOL
++0xfcbe775e    blk_rq_prep_clone       vmlinux EXPORT_SYMBOL_GPL
++0x53e6cd86    crypto_alloc_shash      vmlinux EXPORT_SYMBOL_GPL
++0x93f84c0c    crypto_alloc_ahash      vmlinux EXPORT_SYMBOL_GPL
++0xae1d4afd    sdio_unregister_driver  vmlinux EXPORT_SYMBOL_GPL
++0x1b50682a    drm_mode_connector_attach_encoder       vmlinux EXPORT_SYMBOL
++0x78bed30e    regulator_get   vmlinux EXPORT_SYMBOL_GPL
++0xae4e6d07    inet6_register_icmp_sender      vmlinux EXPORT_SYMBOL
++0xcd67300d    vlan_ioctl_set  vmlinux EXPORT_SYMBOL
++0x4d9b6d35    snd_pcm_format_size     vmlinux EXPORT_SYMBOL
++0xc11d8093    iov_shorten     vmlinux EXPORT_SYMBOL
++0x6a037cf1    mempool_kfree   vmlinux EXPORT_SYMBOL
++0x0cebb5a5    __ww_mutex_lock vmlinux EXPORT_SYMBOL
++0x430e5257    of_alias_get_id vmlinux EXPORT_SYMBOL_GPL
++0x5d9260a1    v4l2_ctrl_activate      vmlinux EXPORT_SYMBOL
++0x17622c01    display_entity_set_state        vmlinux EXPORT_SYMBOL_GPL
++0x26adb815    thread_notify_head      vmlinux EXPORT_SYMBOL_GPL
++0xf0ef15b4    list_sort       vmlinux EXPORT_SYMBOL
++0x958974d4    remove_arg_zero vmlinux EXPORT_SYMBOL
++0x7b5c8440    vm_munmap       vmlinux EXPORT_SYMBOL
++0x46178343    remap_pfn_range vmlinux EXPORT_SYMBOL
++0x46608fa0    getnstimeofday  vmlinux EXPORT_SYMBOL
++0x51a049e1    scsi_scan_target        vmlinux EXPORT_SYMBOL
++0x61b31a8a    subsys_dev_iter_init    vmlinux EXPORT_SYMBOL_GPL
++0x054aade6    subsys_dev_iter_exit    vmlinux EXPORT_SYMBOL_GPL
++0x4099164a    skcipher_geniv_exit     vmlinux EXPORT_SYMBOL_GPL
++0x9c144793    file_update_time        vmlinux EXPORT_SYMBOL
++0x8a162c7d    bdi_unregister  vmlinux EXPORT_SYMBOL
++0x755d68eb    iio_enum_read   vmlinux EXPORT_SYMBOL_GPL
++0x03e593b9    vb2_wait_for_all_buffers        vmlinux EXPORT_SYMBOL_GPL
++0xc06a30a4    phy_register_fixup      vmlinux EXPORT_SYMBOL
++0x3c308a26    device_bind_driver      vmlinux EXPORT_SYMBOL_GPL
++0x55010072    device_store_ulong      vmlinux EXPORT_SYMBOL_GPL
++0x0b405d40    inet6_csk_search_req    vmlinux EXPORT_SYMBOL_GPL
++0x7a1acc62    dev_mc_init     vmlinux EXPORT_SYMBOL
++0x93fcc9bd    dev_uc_init     vmlinux EXPORT_SYMBOL
++0x865029ac    __hw_addr_sync  vmlinux EXPORT_SYMBOL
++0xb04359d9    snd_soc_bytes_info      vmlinux EXPORT_SYMBOL_GPL
++0x11a13e31    _kstrtol        vmlinux EXPORT_SYMBOL
++0x6e73746d    kobject_uevent_env      vmlinux EXPORT_SYMBOL_GPL
++0x7d830ea5    mb_cache_entry_alloc    vmlinux EXPORT_SYMBOL
++0xd702e480    _raw_read_unlock        vmlinux EXPORT_SYMBOL
++0xfa2bcf10    init_timer_key  vmlinux EXPORT_SYMBOL
++0xe03525ac    of_irq_map_raw  vmlinux EXPORT_SYMBOL_GPL
++0xb39171d5    cdc_ncm_select_altsetting       vmlinux EXPORT_SYMBOL_GPL
++0xec52c42e    scsi_setup_blk_pc_cmnd  vmlinux EXPORT_SYMBOL
++0x337cce46    put_cmsg        vmlinux EXPORT_SYMBOL
++0x655656dc    skb_free_datagram       vmlinux EXPORT_SYMBOL
++0x2ad0e68c    sound_class     vmlinux EXPORT_SYMBOL
++0x7a98596c    filp_close      vmlinux EXPORT_SYMBOL
++0x4c39b01b    truncate_setsize        vmlinux EXPORT_SYMBOL
++0xfd5683b9    wait_for_completion_interruptible       vmlinux EXPORT_SYMBOL
++0xfc38a837    extcon_update_state     vmlinux EXPORT_SYMBOL_GPL
++0xdba80fc1    of_fdt_unflatten_tree   vmlinux EXPORT_SYMBOL_GPL
++0x3be54580    generic_readlink        vmlinux EXPORT_SYMBOL
++0x6cee2e42    drm_object_property_get_value   vmlinux EXPORT_SYMBOL
++0x67b27ec1    tty_std_termios vmlinux EXPORT_SYMBOL
++0x4298b775    v7_flush_kern_cache_all vmlinux EXPORT_SYMBOL
++0x66ac9af0    ether_setup     vmlinux EXPORT_SYMBOL
++0xafb2d50e    __break_lease   vmlinux EXPORT_SYMBOL
++0x9e6500de    get_task_comm   vmlinux EXPORT_SYMBOL_GPL
++0xd5df9165    __get_vm_area   vmlinux EXPORT_SYMBOL_GPL
++0x6b7589f4    param_set_bool  vmlinux EXPORT_SYMBOL
++0xbfc407b4    param_ops_bint  vmlinux EXPORT_SYMBOL
++0xadb5559d    param_ops_byte  vmlinux EXPORT_SYMBOL
++0xd2a3a2e7    usb_deregister_device_driver    vmlinux EXPORT_SYMBOL_GPL
++0x0264e273    usbnet_nway_reset       vmlinux EXPORT_SYMBOL_GPL
++0xbc31af43    device_create_file      vmlinux EXPORT_SYMBOL_GPL
++0x34bb0082    snd_soc_dapm_put_volsw  vmlinux EXPORT_SYMBOL_GPL
++0xcec0e354    snd_soc_dapm_get_volsw  vmlinux EXPORT_SYMBOL_GPL
++0xa3d6bc8a    would_dump      vmlinux EXPORT_SYMBOL
++0x782cd0c9    truncate_inode_pages_range      vmlinux EXPORT_SYMBOL
++0xefc7de8e    force_sig       vmlinux EXPORT_SYMBOL
++0xb3b30554    fimc_find_remote_sensor vmlinux EXPORT_SYMBOL
++0xf3be20f4    v4l2_m2m_querybuf       vmlinux EXPORT_SYMBOL_GPL
++0x0fccafb1    drm_global_item_unref   vmlinux EXPORT_SYMBOL
++0xe8d24f74    arm_coherent_dma_ops    vmlinux EXPORT_SYMBOL
++0x05240ee7    percpu_counter_batch    vmlinux EXPORT_SYMBOL
++0x5d75cd76    d_path  vmlinux EXPORT_SYMBOL
++0x495426ee    v4l2_ctrl_get_name      vmlinux EXPORT_SYMBOL
++0x6e89a560    regmap_irq_chip_get_base        vmlinux EXPORT_SYMBOL_GPL
++0x587616f1    vfs_fstatat     vmlinux EXPORT_SYMBOL
++0x162ccc0c    lg_local_lock   vmlinux EXPORT_SYMBOL
++0x498225b6    v4l2_m2m_expbuf vmlinux EXPORT_SYMBOL_GPL
++0x21b2c1ab    __pm_genpd_remove_callbacks     vmlinux EXPORT_SYMBOL_GPL
++0x1516aa21    brcmf_sdio_probe        drivers/net/wireless/brcm80211/brcmfmac/brcmfmac        EXPORT_SYMBOL
++0x36c61868    hci_free_dev    vmlinux EXPORT_SYMBOL
++0xcfa46265    igrab   vmlinux EXPORT_SYMBOL
++0x36150611    iio_validate_scan_mask_onehot   vmlinux EXPORT_SYMBOL_GPL
++0x01ac01fc    usbnet_resume   vmlinux EXPORT_SYMBOL_GPL
++0x43421b4f    sdev_evt_send   vmlinux EXPORT_SYMBOL_GPL
++0x1fdcc615    rtnl_notify     vmlinux EXPORT_SYMBOL
++0xe4ad075c    __rtnl_link_register    vmlinux EXPORT_SYMBOL_GPL
++0x41366c3b    sock_recvmsg    vmlinux EXPORT_SYMBOL
++0x3468cb4a    snd_soc_set_runtime_hwparams    vmlinux EXPORT_SYMBOL_GPL
++0x308e4695    snd_pcm_open_substream  vmlinux EXPORT_SYMBOL
++0x2ef9dbdc    blk_end_request_err     vmlinux EXPORT_SYMBOL_GPL
++0x9b11d9bf    blk_end_request_all     vmlinux EXPORT_SYMBOL
++0x2f5bf998    blk_queue_bio   vmlinux EXPORT_SYMBOL_GPL
++0xd16712f3    crypto_check_attr_type  vmlinux EXPORT_SYMBOL_GPL
++0x16305289    warn_slowpath_null      vmlinux EXPORT_SYMBOL
++0xcb0288ea    ledtrig_cpu     vmlinux EXPORT_SYMBOL
++0xe6431c3b    mmc_can_secure_erase_trim       vmlinux EXPORT_SYMBOL
++0x916dbe7c    usb_hcd_unmap_urb_for_dma       vmlinux EXPORT_SYMBOL_GPL
++0x8dc2569e    nf_ct_l3protos  vmlinux EXPORT_SYMBOL_GPL
++0x1471e34e    linkwatch_fire_event    vmlinux EXPORT_SYMBOL
++0x56db40e5    snd_device_free vmlinux EXPORT_SYMBOL
++0xe1b524a3    fs_bio_set      vmlinux EXPORT_SYMBOL
++0x8d522714    __rcu_read_lock vmlinux EXPORT_SYMBOL_GPL
++0x4906a967    hid_snto32      vmlinux EXPORT_SYMBOL_GPL
++0xfbf6bb67    watchdog_init_timeout   vmlinux EXPORT_SYMBOL_GPL
++0xd37e13b4    regulator_set_optimum_mode      vmlinux EXPORT_SYMBOL_GPL
++0x4fe1eddf    unregister_netevent_notifier    vmlinux EXPORT_SYMBOL_GPL
++0x66af941c    snd_soc_debugfs_root    vmlinux EXPORT_SYMBOL_GPL
++0x42c43759    input_mt_report_slot_state      vmlinux EXPORT_SYMBOL
++0x8fccb56f    scsi_init_io    vmlinux EXPORT_SYMBOL
++0x375fce7f    asoc_dma_platform_unregister    vmlinux EXPORT_SYMBOL_GPL
++0xa58dee99    _raw_write_unlock       vmlinux EXPORT_SYMBOL
++0x252efd1e    sdhci_remove_host       vmlinux EXPORT_SYMBOL_GPL
++0xb5128e67    v4l2_i2c_subdev_init    vmlinux EXPORT_SYMBOL_GPL
++0x6d680e52    v4l2_i2c_subdev_addr    vmlinux EXPORT_SYMBOL_GPL
++0xb56fc02f    fib_default_rule_pref   vmlinux EXPORT_SYMBOL
++0x97359c5f    snd_pcm_period_elapsed  vmlinux EXPORT_SYMBOL
++0x3df477d7    debugfs_create_x8       vmlinux EXPORT_SYMBOL_GPL
++0x314d3160    kmap_to_page    vmlinux EXPORT_SYMBOL
++0x8afbf7b1    irq_domain_xlate_onecell        vmlinux EXPORT_SYMBOL_GPL
++0x6b264960    irq_domain_xlate_twocell        vmlinux EXPORT_SYMBOL_GPL
++0xee3c209d    cgroup_next_descendant_pre      vmlinux EXPORT_SYMBOL_GPL
++0x6776c27a    drm_av_sync_delay       vmlinux EXPORT_SYMBOL
++0x0fe112dc    of_dma_controller_free  vmlinux EXPORT_SYMBOL_GPL
++0xfccc95e9    pwm_put vmlinux EXPORT_SYMBOL_GPL
++0xb8a5a2d7    iio_convert_raw_to_processed    vmlinux EXPORT_SYMBOL_GPL
++0x8f7df3a7    drm_object_attach_property      vmlinux EXPORT_SYMBOL
++0xd248fe40    uart_write_wakeup       vmlinux EXPORT_SYMBOL
++0x0483a4c2    skb_append      vmlinux EXPORT_SYMBOL
++0xb28d7c56    snd_soc_read    vmlinux EXPORT_SYMBOL_GPL
++0x6f1f9555    read_cache_page_gfp     vmlinux EXPORT_SYMBOL
++0xe12954af    pwm_can_sleep   vmlinux EXPORT_SYMBOL_GPL
++0x333147c5    sk_stream_error vmlinux EXPORT_SYMBOL
++0x37f30c3d    devm_request_and_ioremap        vmlinux EXPORT_SYMBOL
++0x40d57aa3    audit_log_start vmlinux EXPORT_SYMBOL
++0x3232306b    need_load_eval  vmlinux EXPORT_SYMBOL_GPL
++0x27328cec    drm_fb_helper_debug_leave       vmlinux EXPORT_SYMBOL
++0x2f4df599    arm_iommu_attach_device vmlinux EXPORT_SYMBOL_GPL
++0x38ec6320    netdev_crit     vmlinux EXPORT_SYMBOL
++0x7385ebdb    sysfs_create_files      vmlinux EXPORT_SYMBOL_GPL
++0x0758ff61    sget    vmlinux EXPORT_SYMBOL
++0xca20d111    v4l2_ctrl_cluster       vmlinux EXPORT_SYMBOL
++0x5f754e5a    memset  vmlinux EXPORT_SYMBOL
++0xbd70447e    ip_tunnel_setup vmlinux EXPORT_SYMBOL_GPL
++0x2541a979    snd_soc_calc_frame_size vmlinux EXPORT_SYMBOL_GPL
++0xdc3fcbc9    __sw_hweight8   vmlinux EXPORT_SYMBOL
++0x02ee26c1    free_pages_exact        vmlinux EXPORT_SYMBOL
++0x885bcec8    tasklet_hrtimer_init    vmlinux EXPORT_SYMBOL_GPL
++0xe80bbfc6    v4l2_event_pending      vmlinux EXPORT_SYMBOL_GPL
++0x356cb8d3    debugfs_create_atomic_t vmlinux EXPORT_SYMBOL_GPL
++0x064db9a5    mark_mounts_for_expiry  vmlinux EXPORT_SYMBOL_GPL
++0x8b43159b    register_cpu_notifier   vmlinux EXPORT_SYMBOL
++0xd0d5f859    st_sensors_read_event_config    vmlinux EXPORT_SYMBOL
++0xba490602    nci_to_errno    vmlinux EXPORT_SYMBOL
++0x26cae22e    snd_soc_dapm_free       vmlinux EXPORT_SYMBOL_GPL
++0x6b4f9016    d_set_d_op      vmlinux EXPORT_SYMBOL
++0x6d340f64    tty_termios_input_baud_rate     vmlinux EXPORT_SYMBOL
++0x0d3f57a2    _find_next_bit_le       vmlinux EXPORT_SYMBOL
++0x74e1a843    xfrm_aalg_get_byidx     vmlinux EXPORT_SYMBOL_GPL
++0x56b147ce    unregister_tcf_proto_ops        vmlinux EXPORT_SYMBOL
++0xb6936ffe    _bcd2bin        vmlinux EXPORT_SYMBOL
++0x707f5f40    vb2_fop_write   vmlinux EXPORT_SYMBOL_GPL
++0x598cd828    udp_table       vmlinux EXPORT_SYMBOL
++0x7d0e3e72    ida_get_new_above       vmlinux EXPORT_SYMBOL
++0x2e2f1740    ring_buffer_record_disable_cpu  vmlinux EXPORT_SYMBOL_GPL
++0xafe38346    mmc_erase_group_aligned vmlinux EXPORT_SYMBOL
++0x1af8e94b    nla_put vmlinux EXPORT_SYMBOL
++0xf23fcb99    __kfifo_in      vmlinux EXPORT_SYMBOL
++0xf8ac3a16    revalidate_disk vmlinux EXPORT_SYMBOL
++0xca5967e3    vm_stat vmlinux EXPORT_SYMBOL
++0xd5b1376d    register_shrinker       vmlinux EXPORT_SYMBOL
++0xa6c3a59e    power_supply_am_i_supplied      vmlinux EXPORT_SYMBOL_GPL
++0x35aa9322    regcache_mark_dirty     vmlinux EXPORT_SYMBOL_GPL
++0xbdb14b0b    transport_configure_device      vmlinux EXPORT_SYMBOL_GPL
++0x391c8c77    drm_bl_register vmlinux EXPORT_SYMBOL_GPL
++0x2c744386    ip_tunnel_dellink       vmlinux EXPORT_SYMBOL_GPL
++0xc10022a2    register_sound_dsp      vmlinux EXPORT_SYMBOL
++0x6d29349e    blk_post_runtime_suspend        vmlinux EXPORT_SYMBOL
++0x803eda06    block_invalidatepage    vmlinux EXPORT_SYMBOL
++0x22ba7f9f    may_umount_tree vmlinux EXPORT_SYMBOL
++0x7a944007    rcu_idle_enter  vmlinux EXPORT_SYMBOL_GPL
++0x3ce3f899    iio_device_register     vmlinux EXPORT_SYMBOL
++0x624a6406    hwrng_register  vmlinux EXPORT_SYMBOL_GPL
++0xa408cd5e    misc_register   vmlinux EXPORT_SYMBOL
++0x636b12c8    nf_nat_need_gre vmlinux EXPORT_SYMBOL_GPL
++0xe58ab676    ip_tunnel_init_net      vmlinux EXPORT_SYMBOL_GPL
++0x38c6e66b    udp_lib_get_port        vmlinux EXPORT_SYMBOL
++0x7cda3781    ip_route_input_noref    vmlinux EXPORT_SYMBOL
++0x207ffd0a    kernel_write    vmlinux EXPORT_SYMBOL
++0xbbabb724    tty_ldisc_ref   vmlinux EXPORT_SYMBOL_GPL
++0x899a5d37    rtnl_af_unregister      vmlinux EXPORT_SYMBOL_GPL
++0x1c7f08a9    snd_soc_dapm_del_routes vmlinux EXPORT_SYMBOL_GPL
++0xe71105e8    iget_failed     vmlinux EXPORT_SYMBOL
++0x0fc01e9f    static_key_slow_inc     vmlinux EXPORT_SYMBOL_GPL
++0xbfee3ad5    loop_unregister_transfer        vmlinux EXPORT_SYMBOL
++0xaaef0fd2    class_dev_iter_exit     vmlinux EXPORT_SYMBOL_GPL
++0xd2b18e1d    __of_phy_provider_register      vmlinux EXPORT_SYMBOL_GPL
++0x1751de15    phy_create      vmlinux EXPORT_SYMBOL_GPL
++0x25c677c4    mac_pton        vmlinux EXPORT_SYMBOL
++0xc54cd128    filemap_fdatawait_range vmlinux EXPORT_SYMBOL
++0x05afc379    mmc_cache_ctrl  vmlinux EXPORT_SYMBOL
++0x814e4cf8    cfg80211_chandef_usable vmlinux EXPORT_SYMBOL
++0x829865cd    inode_sub_bytes vmlinux EXPORT_SYMBOL
++0xec602814    inode_set_bytes vmlinux EXPORT_SYMBOL
++0x47e70229    v7_flush_user_cache_range       vmlinux EXPORT_SYMBOL
++0x51cb6360    arp_xmit        vmlinux EXPORT_SYMBOL
++0xc84ab6f8    __dev_getfirstbyhwtype  vmlinux EXPORT_SYMBOL
++0xd499d564    __dev_get_by_index      vmlinux EXPORT_SYMBOL
++0x66a67dab    flex_array_shrink       vmlinux EXPORT_SYMBOL
++0xd41fe818    _raw_read_unlock_irqrestore     vmlinux EXPORT_SYMBOL
++0x47fdbc4f    v4l2_ctrl_new_std       vmlinux EXPORT_SYMBOL
++0xb2fe3cab    mdiobus_register        vmlinux EXPORT_SYMBOL
++0xf70d473a    __inet6_lookup_established      vmlinux EXPORT_SYMBOL
++0x8187321e    snd_timer_interrupt     vmlinux EXPORT_SYMBOL
++0xec5d6a71    __nla_put_nohdr vmlinux EXPORT_SYMBOL
++0xda5506a3    crypto_unregister_instance      vmlinux EXPORT_SYMBOL_GPL
++0xfd361609    bdi_init        vmlinux EXPORT_SYMBOL
++0xf8d88cd8    clk_get vmlinux EXPORT_SYMBOL
++0x22df2dd3    sdio_claim_host vmlinux EXPORT_SYMBOL_GPL
++0x40973662    sysctl_udp_mem  vmlinux EXPORT_SYMBOL
++0x3b50ba06    cpufreq_cooling_register        vmlinux EXPORT_SYMBOL_GPL
++0xb1c29e91    usbnet_probe    vmlinux EXPORT_SYMBOL_GPL
++0x5e1176a3    nfc_hci_send_cmd        vmlinux EXPORT_SYMBOL
++0x1bc8ce1b    inet_csk_accept vmlinux EXPORT_SYMBOL
++0x35cdd9d0    inet_hash_connect       vmlinux EXPORT_SYMBOL_GPL
++0x0334da4e    scsi_command_size_tbl   vmlinux EXPORT_SYMBOL
++0xa843805a    get_unused_fd_flags     vmlinux EXPORT_SYMBOL
++0xb1e25684    __trace_bputs   vmlinux EXPORT_SYMBOL_GPL
++0xb58dcfa2    synchronize_sched_expedited     vmlinux EXPORT_SYMBOL_GPL
++0x17cefda4    cpufreq_cooling_unregister      vmlinux EXPORT_SYMBOL_GPL
++0xc6fca5ad    v4l2_m2m_release        vmlinux EXPORT_SYMBOL_GPL
++0x0614dd5a    v4l2_video_std_frame_period     vmlinux EXPORT_SYMBOL
++0x08195a4e    generic_mii_ioctl       vmlinux EXPORT_SYMBOL
++0xe64e4a5b    drm_select_eld  vmlinux EXPORT_SYMBOL
++0xa3b4f14d    bt_accept_dequeue       vmlinux EXPORT_SYMBOL
++0x8e20620c    tcf_unregister_action   vmlinux EXPORT_SYMBOL
++0x52026cdf    security_sb_parse_opts_str      vmlinux EXPORT_SYMBOL
++0xe82c33bd    usb_bulk_msg    vmlinux EXPORT_SYMBOL_GPL
++0x876abdb2    xfrm_state_delete_tunnel        vmlinux EXPORT_SYMBOL
++0xfdb4778c    sock_edemux     vmlinux EXPORT_SYMBOL
++0x4688d7ec    pvclock_gtod_unregister_notifier        vmlinux EXPORT_SYMBOL_GPL
++0xc6b72634    gserial_connect vmlinux EXPORT_SYMBOL_GPL
++0x55046eb2    platform_device_add_resources   vmlinux EXPORT_SYMBOL_GPL
++0x1b25d2b3    of_pwm_xlate_with_flags vmlinux EXPORT_SYMBOL_GPL
++0x6e1ba077    in6_dev_finish_destroy  vmlinux EXPORT_SYMBOL
++0xecd68a44    tcp_gro_receive vmlinux EXPORT_SYMBOL
++0x922e5568    eth_header      vmlinux EXPORT_SYMBOL
++0xf82ec573    rb_prev vmlinux EXPORT_SYMBOL
++0xfe2f7b7e    jbd2_journal_init_dev   vmlinux EXPORT_SYMBOL
++0xd4114894    bd_unlink_disk_holder   vmlinux EXPORT_SYMBOL_GPL
++0xa9e18049    task_handoff_unregister vmlinux EXPORT_SYMBOL_GPL
++0x4b5366cf    down_killable   vmlinux EXPORT_SYMBOL
++0x1129616d    scsi_rescan_device      vmlinux EXPORT_SYMBOL
++0x9ed554b3    unregister_keyboard_notifier    vmlinux EXPORT_SYMBOL_GPL
++0x3271e6e4    unregister_framebuffer  vmlinux EXPORT_SYMBOL
++0x4acb9a7c    napi_gro_receive        vmlinux EXPORT_SYMBOL
++0x38ed4ee7    netdev_master_upper_dev_get_rcu vmlinux EXPORT_SYMBOL
++0x5ae87753    debugfs_print_regs32    vmlinux EXPORT_SYMBOL_GPL
++0xeac5a47a    clk_notifier_register   vmlinux EXPORT_SYMBOL_GPL
++0xdcc389f7    usb_get_phy     vmlinux EXPORT_SYMBOL_GPL
++0x5cfbd179    phonet_stream_ops       vmlinux EXPORT_SYMBOL
++0xd7ea7094    nf_unregister_queue_handler     vmlinux EXPORT_SYMBOL
++0xa9b804f6    snd_soc_dapm_ignore_suspend     vmlinux EXPORT_SYMBOL_GPL
++0xb04cf0fe    lg_local_unlock vmlinux EXPORT_SYMBOL
++0x24eb7e32    leds_list       vmlinux EXPORT_SYMBOL_GPL
++0xb2f2f502    dev_get_by_flags_rcu    vmlinux EXPORT_SYMBOL
++0x996bdb64    _kstrtoul       vmlinux EXPORT_SYMBOL
++0xd6f8cf35    __block_write_begin     vmlinux EXPORT_SYMBOL
++0x3517383e    register_reboot_notifier        vmlinux EXPORT_SYMBOL
++0x188a3dfb    timespec_trunc  vmlinux EXPORT_SYMBOL
++0x7647726c    handle_sysrq    vmlinux EXPORT_SYMBOL
++0x2a55c54a    l2cap_unregister_user   vmlinux EXPORT_SYMBOL
++0xdaafc807    tcp_sockets_allocated   vmlinux EXPORT_SYMBOL
++0x61618241    netlink_alloc_skb       vmlinux EXPORT_SYMBOL_GPL
++0x883edc99    snd_soc_dapm_weak_routes        vmlinux EXPORT_SYMBOL_GPL
++0x0b20ad4e    inode_owner_or_capable  vmlinux EXPORT_SYMBOL
++0x5ddfdc97    generic_pipe_buf_confirm        vmlinux EXPORT_SYMBOL
++0x27fede28    get_super_thawed        vmlinux EXPORT_SYMBOL
++0x7ff20102    v4l2_s_ctrl     vmlinux EXPORT_SYMBOL
++0x9745d638    drm_err vmlinux EXPORT_SYMBOL
++0x1c1a727a    v4l2_ctrl_subdev_subscribe_event        vmlinux EXPORT_SYMBOL
++0x157df959    usbnet_tx_timeout       vmlinux EXPORT_SYMBOL_GPL
++0x33ca0b9d    scsi_device_quiesce     vmlinux EXPORT_SYMBOL
++0x18a12a47    drm_modeset_unlock_all  vmlinux EXPORT_SYMBOL
++0x59d29dab    v7_flush_kern_dcache_area       vmlinux EXPORT_SYMBOL
++0x9ca80cdd    inet6_protos    vmlinux EXPORT_SYMBOL
++0x58714dc9    snd_soc_jack_add_zones  vmlinux EXPORT_SYMBOL_GPL
++0xdc9110f5    snd_pcm_hw_param_first  vmlinux EXPORT_SYMBOL
++0xf184d189    kernel_power_off        vmlinux EXPORT_SYMBOL_GPL
++0xc8a270a1    usb_put_function        vmlinux EXPORT_SYMBOL_GPL
++0xdfe8f93c    display_entity_get_size vmlinux EXPORT_SYMBOL_GPL
++0x0ef959a5    ip6t_unregister_table   vmlinux EXPORT_SYMBOL
++0x5ee28af3    genl_register_ops       vmlinux EXPORT_SYMBOL
++0xda91a719    snd_pcm_new     vmlinux EXPORT_SYMBOL
++0x8731837f    debugfs_create_u64      vmlinux EXPORT_SYMBOL_GPL
++0x0d350531    block_commit_write      vmlinux EXPORT_SYMBOL
++0xcb62227b    con_copy_unimap vmlinux EXPORT_SYMBOL
++0x9b90584e    tty_ldisc_ref_wait      vmlinux EXPORT_SYMBOL_GPL
++0xf727c5be    __netdev_alloc_skb      vmlinux EXPORT_SYMBOL
++0xf186dfad    wm_hubs_set_bias_level  vmlinux EXPORT_SYMBOL_GPL
++0x5bc4fef5    snd_soc_get_dai_substream       vmlinux EXPORT_SYMBOL_GPL
++0xabefee2b    _snd_pcm_lib_alloc_vmalloc_buffer       vmlinux EXPORT_SYMBOL
++0x5a116367    perf_event_create_kernel_counter        vmlinux EXPORT_SYMBOL_GPL
++0x0bfa3a19    rcu_idle_exit   vmlinux EXPORT_SYMBOL_GPL
++0x90ff6c9f    nf_ct_invert_tuplepr    vmlinux EXPORT_SYMBOL_GPL
++0xf3cd9688    snd_soc_dapm_sync       vmlinux EXPORT_SYMBOL_GPL
++0x68fb4f69    locks_delete_block      vmlinux EXPORT_SYMBOL
++0xdca2a7bb    dput    vmlinux EXPORT_SYMBOL
++0x67a000fa    try_module_get  vmlinux EXPORT_SYMBOL
++0x4790cc27    v4l2_s_ext_ctrls        vmlinux EXPORT_SYMBOL
++0xf39c1176    tty_kref_put    vmlinux EXPORT_SYMBOL
++0x56310925    regulator_mode_to_status        vmlinux EXPORT_SYMBOL_GPL
++0x0825a4fe    regulator_list_voltage_linear   vmlinux EXPORT_SYMBOL_GPL
++0x43db92ba    fb_set_suspend  vmlinux EXPORT_SYMBOL
++0x4993cc2b    register_net_sysctl     vmlinux EXPORT_SYMBOL_GPL
++0x8a490c90    rfkill_set_sw_state     vmlinux EXPORT_SYMBOL
++0xaae97496    snd_soc_bulk_write_raw  vmlinux EXPORT_SYMBOL_GPL
++0xb4dd257b    srcu_notifier_call_chain        vmlinux EXPORT_SYMBOL_GPL
++0x4403ead3    usb_match_one_id        vmlinux EXPORT_SYMBOL_GPL
++0x829a0b6c    screen_glyph    vmlinux EXPORT_SYMBOL_GPL
++0xf7802486    __aeabi_uidivmod        vmlinux EXPORT_SYMBOL
++0x4b8f110e    sk_free vmlinux EXPORT_SYMBOL
++0x4fbbaedb    snd_soc_free_ac97_codec vmlinux EXPORT_SYMBOL_GPL
++0xfd5566cf    scsi_is_sdev_device     vmlinux EXPORT_SYMBOL
++0x17dc8b68    drm_vblank_pre_modeset  vmlinux EXPORT_SYMBOL
++0x7ef39823    ieee80211_hdrlen        vmlinux EXPORT_SYMBOL
++0xc8f36b20    kobject_init    vmlinux EXPORT_SYMBOL
++0xb2e764e8    suspend_valid_only_mem  vmlinux EXPORT_SYMBOL_GPL
++0xfaf9995e    sleep_on        vmlinux EXPORT_SYMBOL
++0x42160169    flush_workqueue vmlinux EXPORT_SYMBOL_GPL
++0xf3251e7b    v4l2_norm_to_name       vmlinux EXPORT_SYMBOL
++0xd7b664df    regulator_list_voltage_table    vmlinux EXPORT_SYMBOL_GPL
++0xfe13b82a    snd_soc_info_enum_ext   vmlinux EXPORT_SYMBOL_GPL
++0x22a8b63d    bio_flush_dcache_pages  vmlinux EXPORT_SYMBOL
++0x0c3d1edb    simple_lookup   vmlinux EXPORT_SYMBOL
++0x4cbc159a    gether_set_dev_addr     vmlinux EXPORT_SYMBOL
++0xdac8e102    gether_get_dev_addr     vmlinux EXPORT_SYMBOL
++0xfa599bb2    netlink_register_notifier       vmlinux EXPORT_SYMBOL
++0xb7e5c788    cgroup_next_descendant_post     vmlinux EXPORT_SYMBOL_GPL
++0xd7dc295c    dm_io   vmlinux EXPORT_SYMBOL
++0xb8698990    usb_match_id    vmlinux EXPORT_SYMBOL_GPL
++0x91a5dbd2    drm_idlelock_take       vmlinux EXPORT_SYMBOL
++0xba86f941    xfrm_policy_insert      vmlinux EXPORT_SYMBOL
++0x2519a629    skb_segment     vmlinux EXPORT_SYMBOL_GPL
++0x2f574814    blk_queue_max_segments  vmlinux EXPORT_SYMBOL
++0xa17232f2    bio_clone_bioset        vmlinux EXPORT_SYMBOL
++0xba2bc8de    unlock_rename   vmlinux EXPORT_SYMBOL
++0x9820b644    warn_slowpath_fmt_taint vmlinux EXPORT_SYMBOL
++0x184b82fb    mmc_vddrange_to_ocrmask vmlinux EXPORT_SYMBOL
++0x0a67ddd9    dm_suspended    vmlinux EXPORT_SYMBOL_GPL
++0xfc8bcbaf    usb_add_hcd     vmlinux EXPORT_SYMBOL_GPL
++0x965d4e18    tcp_init_congestion_ops vmlinux EXPORT_SYMBOL_GPL
++0xe587559a    skb_push        vmlinux EXPORT_SYMBOL
++0x1a32c5c7    blk_run_queue_async     vmlinux EXPORT_SYMBOL
++0x7fa439cd    simple_rmdir    vmlinux EXPORT_SYMBOL
++0xe6790d49    alloc_file      vmlinux EXPORT_SYMBOL
++0xe8214f7a    free_task       vmlinux EXPORT_SYMBOL
++0x2b9e3380    samsung_dmadev_get_ops  vmlinux EXPORT_SYMBOL
++0x8e671fe0    sdio_f0_writeb  vmlinux EXPORT_SYMBOL_GPL
++0x919b5fa4    device_create   vmlinux EXPORT_SYMBOL_GPL
++0x5cf4fc85    psched_ratecfg_precompute       vmlinux EXPORT_SYMBOL
++0x96573b80    __kfifo_dma_in_finish_r vmlinux EXPORT_SYMBOL
++0xf520f285    sysfs_get       vmlinux EXPORT_SYMBOL_GPL
++0x543ef284    seq_hlist_start vmlinux EXPORT_SYMBOL
++0xbfffc4e0    vb2_read        vmlinux EXPORT_SYMBOL_GPL
++0x45f39483    i2c_del_adapter vmlinux EXPORT_SYMBOL
++0x5838f6c9    rtc_valid_tm    vmlinux EXPORT_SYMBOL
++0xb7a638f3    usb_register_driver     vmlinux EXPORT_SYMBOL_GPL
++0xb83a9297    scsi_block_requests     vmlinux EXPORT_SYMBOL
++0xd5d8b6b8    drm_dp_get_adjust_request_pre_emphasis  vmlinux EXPORT_SYMBOL
++0x99c95fa5    unregister_sound_special        vmlinux EXPORT_SYMBOL
++0x056b6c53    fat_dir_empty   vmlinux EXPORT_SYMBOL_GPL
++0xb51c8891    __getblk        vmlinux EXPORT_SYMBOL
++0x1d9658d5    cdev_alloc      vmlinux EXPORT_SYMBOL
++0x1dd73224    st_sensors_i2c_configure        vmlinux EXPORT_SYMBOL
++0x22379ca8    led_blink_set_oneshot   vmlinux EXPORT_SYMBOL
++0xe7e76d97    mmc_release_host        vmlinux EXPORT_SYMBOL
++0x6e04a077    usb_bind_phy    vmlinux EXPORT_SYMBOL_GPL
++0x47d9cfba    sdev_disable_disk_events        vmlinux EXPORT_SYMBOL
++0x142b8b35    drm_buffer_copy_from_user       vmlinux EXPORT_SYMBOL
++0x55f04c21    trace_buffer_unlock_commit_regs vmlinux EXPORT_SYMBOL_GPL
++0x8c333b2b    usb_hcd_unlink_urb_from_ep      vmlinux EXPORT_SYMBOL_GPL
++0x1fa2251f    device_wakeup_enable    vmlinux EXPORT_SYMBOL_GPL
++0xbbe4496d    dev_warn        vmlinux EXPORT_SYMBOL
++0xab3d1f95    nf_ct_untracked_status_or       vmlinux EXPORT_SYMBOL_GPL
++0x131c2452    snd_jack_set_key        vmlinux EXPORT_SYMBOL
++0x74c134b9    __sw_hweight32  vmlinux EXPORT_SYMBOL
++0x57674fd7    __sw_hweight16  vmlinux EXPORT_SYMBOL
++0x9f46ced8    __sw_hweight64  vmlinux EXPORT_SYMBOL
++0x93215e1d    __kfifo_skip_r  vmlinux EXPORT_SYMBOL
++0x1ec4eb34    flex_array_prealloc     vmlinux EXPORT_SYMBOL
++0x01e6b7fa    get_phy_device  vmlinux EXPORT_SYMBOL
++0x391c17d1    wakeup_source_register  vmlinux EXPORT_SYMBOL_GPL
++0xfe85236b    cpu_user        vmlinux EXPORT_SYMBOL
++0x35e62033    pagevec_lookup_tag      vmlinux EXPORT_SYMBOL
++0x34184afe    current_kernel_time     vmlinux EXPORT_SYMBOL
++0x0eb2ceba    tcp_reno_cong_avoid     vmlinux EXPORT_SYMBOL_GPL
++0x2fce25e3    print_tuple     vmlinux EXPORT_SYMBOL_GPL
++0x62496fbf    snd_soc_dai_set_clkdiv  vmlinux EXPORT_SYMBOL_GPL
++0x7505bdef    memchr_inv      vmlinux EXPORT_SYMBOL
++0x3b21bfec    locks_copy_lock vmlinux EXPORT_SYMBOL
++0xb47a0298    hid_dump_report vmlinux EXPORT_SYMBOL_GPL
++0x391147d1    led_trigger_blink       vmlinux EXPORT_SYMBOL_GPL
++0xb65a6bb8    usb_reset_device        vmlinux EXPORT_SYMBOL_GPL
++0x007b6ccf    gnet_stats_start_copy_compat    vmlinux EXPORT_SYMBOL
++0x7522f3ba    irq_modify_status       vmlinux EXPORT_SYMBOL_GPL
++0xd9052a07    rtc_alarm_irq_enable    vmlinux EXPORT_SYMBOL_GPL
++0xcb6dc422    usb_add_config_only     vmlinux EXPORT_SYMBOL_GPL
++0xd38b2d79    inet6_del_protocol      vmlinux EXPORT_SYMBOL
++0x98b8ddd3    xfrm_input_resume       vmlinux EXPORT_SYMBOL
++0xf71914b4    udplite_prot    vmlinux EXPORT_SYMBOL
++0xdc48464a    sock_create_kern        vmlinux EXPORT_SYMBOL
++0x8260686f    bitmap_find_next_zero_area      vmlinux EXPORT_SYMBOL
++0x354ac8ad    scsi_eh_restore_cmnd    vmlinux EXPORT_SYMBOL
++0x6f988f59    transport_remove_device vmlinux EXPORT_SYMBOL_GPL
++0x600f8836    drm_class_device_register       vmlinux EXPORT_SYMBOL_GPL
++0xd589c1c3    sk_clone_lock   vmlinux EXPORT_SYMBOL_GPL
++0xf8798032    d_find_any_alias        vmlinux EXPORT_SYMBOL
++0x56e4cd15    ftrace_event_reg        vmlinux EXPORT_SYMBOL_GPL
++0xab29d75c    thermal_zone_get_zone_by_name   vmlinux EXPORT_SYMBOL_GPL
++0x2a678a13    __suspend_report_result vmlinux EXPORT_SYMBOL_GPL
++0xe36d12fc    drm_gtf_mode    vmlinux EXPORT_SYMBOL
++0x5a48534a    regulator_count_voltages        vmlinux EXPORT_SYMBOL_GPL
++0x2edb3fd8    sk_attach_filter        vmlinux EXPORT_SYMBOL_GPL
++0x8d107d70    sk_detach_filter        vmlinux EXPORT_SYMBOL_GPL
++0x5da176fe    snd_timer_open  vmlinux EXPORT_SYMBOL
++0xf741c793    zlib_deflateEnd vmlinux EXPORT_SYMBOL
++0x7469fcfe    radix_tree_tagged       vmlinux EXPORT_SYMBOL
++0x57c405a5    unload_nls      vmlinux EXPORT_SYMBOL
++0xcaa97c6a    seq_open_private        vmlinux EXPORT_SYMBOL
++0xf3d2b805    st_sensors_get_buffer_element   vmlinux EXPORT_SYMBOL
++0x82286526    vb2_ioctl_create_bufs   vmlinux EXPORT_SYMBOL_GPL
++0xfb7d95b7    fb_set_cmap     vmlinux EXPORT_SYMBOL
++0xed46d9ec    kernel_listen   vmlinux EXPORT_SYMBOL
++0xb1b16346    snd_jack_set_parent     vmlinux EXPORT_SYMBOL
++0x76bf656d    __bitmap_shift_left     vmlinux EXPORT_SYMBOL
++0x1979065a    serio_unregister_driver vmlinux EXPORT_SYMBOL
++0x3a94c8e6    drm_modeset_lock_all    vmlinux EXPORT_SYMBOL
++0xa093e7da    nat_rtp_rtcp_hook       vmlinux EXPORT_SYMBOL_GPL
++0xe23ae481    blk_iopoll_complete     vmlinux EXPORT_SYMBOL
++0x4f6172ff    crypto_chain    vmlinux EXPORT_SYMBOL_GPL
++0xd66a562b    __scsi_device_lookup    vmlinux EXPORT_SYMBOL
++0x9d669763    memcpy  vmlinux EXPORT_SYMBOL
++0x15c5eea4    ip6t_do_table   vmlinux EXPORT_SYMBOL
++0x6b6533af    bdevname        vmlinux EXPORT_SYMBOL
++0x65d67a20    blk_start_plug  vmlinux EXPORT_SYMBOL
++0xdd686f05    cdev_init       vmlinux EXPORT_SYMBOL
++0xbe63ee40    request_resource        vmlinux EXPORT_SYMBOL
++0xb2018900    inet_getname    vmlinux EXPORT_SYMBOL
++0x01610153    nf_ct_expect_init       vmlinux EXPORT_SYMBOL_GPL
++0x04e1b99f    snd_pcm_std_chmaps      vmlinux EXPORT_SYMBOL_GPL
++0x24a42b51    snd_unregister_oss_device       vmlinux EXPORT_SYMBOL
++0x85e7deb2    iov_iter_fault_in_readable      vmlinux EXPORT_SYMBOL
++0x8f049b6c    module_mutex    vmlinux EXPORT_SYMBOL_GPL
++0x931b242d    regcache_sync   vmlinux EXPORT_SYMBOL_GPL
++0xb95f98d6    _memset_io      vmlinux EXPORT_SYMBOL
++0xa98e796e    modify_user_hw_breakpoint       vmlinux EXPORT_SYMBOL_GPL
++0xbf9bcc8d    __cap_empty_set vmlinux EXPORT_SYMBOL
++0xfba8bb33    dm_get_mapinfo  vmlinux EXPORT_SYMBOL
++0x988ad2a2    rndis_set_param_vendor  vmlinux EXPORT_SYMBOL
++0xb67d6992    usb_ep_autoconfig_reset vmlinux EXPORT_SYMBOL_GPL
++0xfbe5910d    drm_mode_config_init    vmlinux EXPORT_SYMBOL
++0x6443df4e    videomode_from_timings  vmlinux EXPORT_SYMBOL_GPL
++0xad059f21    ip_tunnel_changelink    vmlinux EXPORT_SYMBOL_GPL
++0x2c7fb2d0    crypto_shoot_alg        vmlinux EXPORT_SYMBOL_GPL
++0xac226765    iput    vmlinux EXPORT_SYMBOL
++0x77fe4cb2    sleep_on_timeout        vmlinux EXPORT_SYMBOL
++0x1d88a23f    platform_get_resource   vmlinux EXPORT_SYMBOL_GPL
++0xb95beb55    drm_object_property_set_value   vmlinux EXPORT_SYMBOL
++0x8481713b    pn_sock_unhash  vmlinux EXPORT_SYMBOL
++0x28a82da4    snmp_mib_init   vmlinux EXPORT_SYMBOL_GPL
++0x03fd2571    vm_unmap_ram    vmlinux EXPORT_SYMBOL
++0x65466939    proc_doulongvec_ms_jiffies_minmax       vmlinux EXPORT_SYMBOL
++0x23654452    input_ff_upload vmlinux EXPORT_SYMBOL_GPL
++0x45bda0d5    system_serial_low       vmlinux EXPORT_SYMBOL
++0xa682a886    xfrm_output     vmlinux EXPORT_SYMBOL_GPL
++0xeea9dbaf    bitmap_bitremap vmlinux EXPORT_SYMBOL
++0x71a50dbc    register_blkdev vmlinux EXPORT_SYMBOL
++0x43c0e15b    fuse_sync_release       vmlinux EXPORT_SYMBOL_GPL
++0x972213d1    of_phy_connect  vmlinux EXPORT_SYMBOL
++0x95390328    __fimc_vidioc_querycap  vmlinux EXPORT_SYMBOL
++0xe453b342    ipv6_select_ident       vmlinux EXPORT_SYMBOL
++0xabca477d    nf_conntrack_alter_reply        vmlinux EXPORT_SYMBOL_GPL
++0x72c09e90    neigh_event_ns  vmlinux EXPORT_SYMBOL
++0x32590631    snd_soc_update_bits     vmlinux EXPORT_SYMBOL_GPL
++0xb96df73b    elevator_change vmlinux EXPORT_SYMBOL
++0xa30a6f34    jbd2_journal_blocks_per_page    vmlinux EXPORT_SYMBOL
++0x6103b2f2    iterate_supers_type     vmlinux EXPORT_SYMBOL
++0x0a311e2a    iio_read_channel_processed      vmlinux EXPORT_SYMBOL_GPL
++0x89953a68    sdhci_free_host vmlinux EXPORT_SYMBOL_GPL
++0xb8de0d37    dpm_for_each_dev        vmlinux EXPORT_SYMBOL_GPL
++0xe35ba70f    drm_prime_destroy_file_private  vmlinux EXPORT_SYMBOL
++0x1cb4683d    drm_framebuffer_lookup  vmlinux EXPORT_SYMBOL
++0xbaa9e7e0    fb_firmware_edid        vmlinux EXPORT_SYMBOL
++0xa2ede8b2    nf_queue_entry_get_refs vmlinux EXPORT_SYMBOL_GPL
++0x0ff98044    jump_label_rate_limit   vmlinux EXPORT_SYMBOL_GPL
++0x3fd9109b    v4l2_ctrl_subdev_log_status     vmlinux EXPORT_SYMBOL
++0x78cf4589    usb_kill_anchored_urbs  vmlinux EXPORT_SYMBOL_GPL
++0x3b79aef9    request_firmware_nowait vmlinux EXPORT_SYMBOL
++0xab160376    create_syslog_header    vmlinux EXPORT_SYMBOL
++0x6d42bb18    drm_gem_handle_delete   vmlinux EXPORT_SYMBOL
++0x366d19ef    genericbl_limit_intensity       vmlinux EXPORT_SYMBOL
++0x7380780d    cfg80211_unlink_bss     vmlinux EXPORT_SYMBOL
++0xff6b7f32    netdev_change_features  vmlinux EXPORT_SYMBOL
++0x5613414a    init_dummy_netdev       vmlinux EXPORT_SYMBOL_GPL
++0xbd5cb8b9    ring_buffer_resize      vmlinux EXPORT_SYMBOL_GPL
++0xa55e517c    ip_tunnel_xmit  vmlinux EXPORT_SYMBOL_GPL
++0x3b870a79    dst_destroy     vmlinux EXPORT_SYMBOL
++0xad6b883a    usbnet_get_drvinfo      vmlinux EXPORT_SYMBOL_GPL
++0x5df7a89b    nf_ct_helper_expectfn_unregister        vmlinux EXPORT_SYMBOL_GPL
++0x275ef902    __init_waitqueue_head   vmlinux EXPORT_SYMBOL
++0x472b2841    devm_usb_get_phy        vmlinux EXPORT_SYMBOL_GPL
++0x790d8481    scsi_mode_sense vmlinux EXPORT_SYMBOL
++0x2d89342a    scsi_show_sense_hdr     vmlinux EXPORT_SYMBOL
++0xda7ca6cb    fb_mode_is_equal        vmlinux EXPORT_SYMBOL
++0xdc4798d2    xfrm6_tunnel_register   vmlinux EXPORT_SYMBOL
++0xd587e7b5    xfrm4_tunnel_register   vmlinux EXPORT_SYMBOL
++0x360b01a3    nf_ct_get_tuple vmlinux EXPORT_SYMBOL_GPL
++0x6c74c2ee    blk_insert_cloned_request       vmlinux EXPORT_SYMBOL_GPL
++0x46cb2731    security_sb_set_mnt_opts        vmlinux EXPORT_SYMBOL
++0x1b995ffb    iommu_domain_window_enable      vmlinux EXPORT_SYMBOL_GPL
++0xa4ea04ee    of_property_read_u64    vmlinux EXPORT_SYMBOL_GPL
++0x411e4ef5    brcmu_pktq_pdeq_tail    drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x422d82d0    brcmu_pktq_penq_head    drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x41cc94d0    brcmu_pktq_peek_tail    drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x0c6f118f    nf_nat_icmpv6_reply_translation vmlinux EXPORT_SYMBOL_GPL
++0xa07842c6    skb_copy_datagram_from_iovec    vmlinux EXPORT_SYMBOL
++0xc8269f94    snd_soc_params_to_frame_size    vmlinux EXPORT_SYMBOL_GPL
++0x43eeb6cf    snd_pcm_lib_ioctl       vmlinux EXPORT_SYMBOL
++0x9ac11b74    suspend_set_ops vmlinux EXPORT_SYMBOL_GPL
++0xca16dbe7    regulator_enable        vmlinux EXPORT_SYMBOL_GPL
++0xecc84eb2    dst_alloc       vmlinux EXPORT_SYMBOL
++0xf0f5dbc2    timerqueue_iterate_next vmlinux EXPORT_SYMBOL_GPL
++0xab4a5add    blk_put_queue   vmlinux EXPORT_SYMBOL
++0x11bef8bd    single_release  vmlinux EXPORT_SYMBOL
++0x7aad72c6    get_user_pages  vmlinux EXPORT_SYMBOL
++0x6214aef2    cpufreq_unregister_notifier     vmlinux EXPORT_SYMBOL
++0xe93e49c3    devres_free     vmlinux EXPORT_SYMBOL_GPL
++0xd95fbe77    of_find_backlight_by_node       vmlinux EXPORT_SYMBOL
++0xe3f553d9    ip6_append_data vmlinux EXPORT_SYMBOL_GPL
++0xa108eb4d    sysctl_optmem_max       vmlinux EXPORT_SYMBOL
++0xdc323ca6    jbd2_journal_destroy    vmlinux EXPORT_SYMBOL
++0x3c7a1672    jbd2_journal_restart    vmlinux EXPORT_SYMBOL
++0x9805d460    v4l2_device_register    vmlinux EXPORT_SYMBOL_GPL
++0x1db6d990    display_entity_get_first        vmlinux EXPORT_SYMBOL
++0xe57878a1    in6_pton        vmlinux EXPORT_SYMBOL
++0xaccabc6a    in4_pton        vmlinux EXPORT_SYMBOL
++0xd0181f4f    __bitmap_xor    vmlinux EXPORT_SYMBOL
++0x208c317e    mnt_want_write  vmlinux EXPORT_SYMBOL_GPL
++0xbcdedba7    of_get_mac_address      vmlinux EXPORT_SYMBOL
++0x859bbb79    scsi_mode_select        vmlinux EXPORT_SYMBOL_GPL
++0x48991892    cfb_copyarea    vmlinux EXPORT_SYMBOL
++0x2455c156    __clear_user    vmlinux EXPORT_SYMBOL
++0x42c7d35b    __dev_remove_pack       vmlinux EXPORT_SYMBOL
++0x465cab34    secure_ipv6_port_ephemeral      vmlinux EXPORT_SYMBOL
++0x5ddbac94    config_group_init       vmlinux EXPORT_SYMBOL
++0x773c1fdc    posix_acl_to_xattr      vmlinux EXPORT_SYMBOL
++0xb18429eb    suspend_device_irqs     vmlinux EXPORT_SYMBOL_GPL
++0x50c52151    _raw_write_unlock_irq   vmlinux EXPORT_SYMBOL
++0xf5bc65a3    iommu_unmap     vmlinux EXPORT_SYMBOL_GPL
++0x710e2b07    tcf_hash_insert vmlinux EXPORT_SYMBOL
++0xf13feb57    radix_tree_next_chunk   vmlinux EXPORT_SYMBOL
++0x90a1004a    crypto_has_alg  vmlinux EXPORT_SYMBOL_GPL
++0x8cd44e50    iget5_locked    vmlinux EXPORT_SYMBOL
++0x3dcb88a0    irq_set_handler_data    vmlinux EXPORT_SYMBOL
++0xaa7de358    yield_to        vmlinux EXPORT_SYMBOL_GPL
++0xc54649ff    __starget_for_each_device       vmlinux EXPORT_SYMBOL
++0x2bd1f745    drm_mode_config_cleanup vmlinux EXPORT_SYMBOL
++0xa1425906    ieee80211_channel_to_frequency  vmlinux EXPORT_SYMBOL
++0x59806cb9    sk_page_frag_refill     vmlinux EXPORT_SYMBOL
++0xce90ef6b    debugfs_create_dir      vmlinux EXPORT_SYMBOL_GPL
++0xa4827144    dcache_dir_lseek        vmlinux EXPORT_SYMBOL
++0x0c2cdbf1    synchronize_sched       vmlinux EXPORT_SYMBOL_GPL
++0x92a9c60c    time_to_tm      vmlinux EXPORT_SYMBOL
++0x651a4139    test_taint      vmlinux EXPORT_SYMBOL
++0x2b66e1b8    mii_check_media vmlinux EXPORT_SYMBOL
++0xfb7d9c45    __udivsi3       vmlinux EXPORT_SYMBOL
++0x633fafc5    netdev_printk   vmlinux EXPORT_SYMBOL
++0xf5a691cd    invalidate_bh_lrus      vmlinux EXPORT_SYMBOL_GPL
++0xe5524eab    of_address_to_resource  vmlinux EXPORT_SYMBOL_GPL
++0xe22f01b0    thermal_zone_device_register    vmlinux EXPORT_SYMBOL_GPL
++0x3fc8bae1    ipcomp_init_state       vmlinux EXPORT_SYMBOL_GPL
++0xf5b5f1ec    xt_check_match  vmlinux EXPORT_SYMBOL_GPL
++0x24aac4d9    crypto_aes_expand_key   vmlinux EXPORT_SYMBOL_GPL
++0x6f798a9c    d_splice_alias  vmlinux EXPORT_SYMBOL
++0x88196936    do_sync_read    vmlinux EXPORT_SYMBOL
++0x4a18707e    mem_map vmlinux EXPORT_SYMBOL
++0x0366307a    console_suspend_enabled vmlinux EXPORT_SYMBOL
++0x204d506e    st_sensors_write_event_value    vmlinux EXPORT_SYMBOL
++0x4c22a54d    usb_ep_autoconfig       vmlinux EXPORT_SYMBOL_GPL
++0x32c3cb4e    class_compat_register   vmlinux EXPORT_SYMBOL_GPL
++0x7b85f6f8    drm_mm_insert_node      vmlinux EXPORT_SYMBOL
++0x78f9b710    nf_ct_l3proto_try_module_get    vmlinux EXPORT_SYMBOL_GPL
++0x44594236    snd_soc_unregister_component    vmlinux EXPORT_SYMBOL_GPL
++0x05e4e6be    register_sound_midi     vmlinux EXPORT_SYMBOL
++0x07341a03    kobject_rename  vmlinux EXPORT_SYMBOL_GPL
++0x35b6b772    param_ops_charp vmlinux EXPORT_SYMBOL
++0xb4c1829e    clk_round_rate  vmlinux EXPORT_SYMBOL_GPL
++0x1bb061cc    sdio_release_irq        vmlinux EXPORT_SYMBOL_GPL
++0xe4c673df    mmc_wait_for_cmd        vmlinux EXPORT_SYMBOL
++0x4d088d1f    drm_mm_replace_node     vmlinux EXPORT_SYMBOL
++0xe24e09b0    cgroup_taskset_cur_cgroup       vmlinux EXPORT_SYMBOL_GPL
++0x7c5cf140    cad_pid vmlinux EXPORT_SYMBOL
++0xaea8b9a5    drm_get_encoder_name    vmlinux EXPORT_SYMBOL
++0xe4c80097    cacheid vmlinux EXPORT_SYMBOL
++0x5a5a94a6    kstrtou8        vmlinux EXPORT_SYMBOL
++0x2b4aa9c9    get_task_pid    vmlinux EXPORT_SYMBOL_GPL
++0x30f43c3b    sdhci_enable_irq_wakeups        vmlinux EXPORT_SYMBOL_GPL
++0x3a6d4f22    rndis_free_response     vmlinux EXPORT_SYMBOL
++0x85478a0b    inet6_hash_frag vmlinux EXPORT_SYMBOL_GPL
++0x0efbc42d    snd_component_add       vmlinux EXPORT_SYMBOL
++0x6605f97f    flex_array_clear        vmlinux EXPORT_SYMBOL
++0x5a7bfe41    crypto_probing_notify   vmlinux EXPORT_SYMBOL_GPL
++0x94fd7214    serial8250_rx_chars     vmlinux EXPORT_SYMBOL_GPL
++0x13a6027a    ip6t_alloc_initial_table        vmlinux EXPORT_SYMBOL_GPL
++0x03a9a7bd    netif_receive_skb       vmlinux EXPORT_SYMBOL
++0xfb6af58d    recalc_sigpending       vmlinux EXPORT_SYMBOL
++0x2d0ea593    spi_new_device  vmlinux EXPORT_SYMBOL_GPL
++0xfbc4e14c    pm_runtime_enable       vmlinux EXPORT_SYMBOL_GPL
++0xc583bf57    of_regulator_match      vmlinux EXPORT_SYMBOL_GPL
++0xebfdcbdf    system_serial_high      vmlinux EXPORT_SYMBOL
++0x28d7fc1f    nf_nat_mangle_udp_packet        vmlinux EXPORT_SYMBOL
++0xf71016b7    snd_soc_dapm_get_pin_status     vmlinux EXPORT_SYMBOL_GPL
++0xf05c8ab1    vb2_get_contig_userptr  vmlinux EXPORT_SYMBOL_GPL
++0xd045db89    nfc_class       vmlinux EXPORT_SYMBOL
++0x606340d3    disk_part_iter_exit     vmlinux EXPORT_SYMBOL_GPL
++0xa1bd7822    __tracepoint_block_bio_complete vmlinux EXPORT_SYMBOL_GPL
++0x16138f6f    follow_down_one vmlinux EXPORT_SYMBOL
++0x7944e0fc    tracing_off     vmlinux EXPORT_SYMBOL_GPL
++0xb1425b32    dm_table_add_target_callbacks   vmlinux EXPORT_SYMBOL_GPL
++0xbdfb8830    anon_transport_class_register   vmlinux EXPORT_SYMBOL_GPL
++0x911d700e    devm_phy_create vmlinux EXPORT_SYMBOL_GPL
++0xeb908d00    raw_seq_next    vmlinux EXPORT_SYMBOL_GPL
++0x30b265dd    ip_setsockopt   vmlinux EXPORT_SYMBOL
++0x9f45de2c    ip_getsockopt   vmlinux EXPORT_SYMBOL
++0x30322337    nf_ct_l3proto_unregister        vmlinux EXPORT_SYMBOL_GPL
++0x8106c2de    nf_ct_l4proto_unregister        vmlinux EXPORT_SYMBOL_GPL
++0x4b015768    snd_iprintf     vmlinux EXPORT_SYMBOL
++0xec728ca6    blk_unprep_request      vmlinux EXPORT_SYMBOL_GPL
++0x0bae62b1    ktime_get_monotonic_offset      vmlinux EXPORT_SYMBOL_GPL
++0x6f8450af    tty_encode_baud_rate    vmlinux EXPORT_SYMBOL_GPL
++0xead6a706    devm_phy_destroy        vmlinux EXPORT_SYMBOL_GPL
++0x2cf3c356    ip6_redirect    vmlinux EXPORT_SYMBOL_GPL
++0x2cdb55d1    ip_options_rcv_srr      vmlinux EXPORT_SYMBOL
++0x105bdf9b    dentry_open     vmlinux EXPORT_SYMBOL
++0x724bf4b2    i2c_bit_add_numbered_bus        vmlinux EXPORT_SYMBOL
++0x2e09263f    usb_copy_descriptors    vmlinux EXPORT_SYMBOL_GPL
++0xbec98305    device_register vmlinux EXPORT_SYMBOL_GPL
++0xff519474    skb_checksum_help       vmlinux EXPORT_SYMBOL
++0x293d87a4    unregister_netdevice_queue      vmlinux EXPORT_SYMBOL
++0xa692560a    snd_soc_lookup_platform vmlinux EXPORT_SYMBOL_GPL
++0x9545af6d    tasklet_init    vmlinux EXPORT_SYMBOL
++0x87374f66    extcon_unregister_interest      vmlinux EXPORT_SYMBOL_GPL
++0x40a27c37    scsi_dev_info_remove_list       vmlinux EXPORT_SYMBOL
++0x42a2164f    regmap_write    vmlinux EXPORT_SYMBOL_GPL
++0xe6f46e6e    drm_clflush_virt_range  vmlinux EXPORT_SYMBOL
++0x17f8217b    nf_nat_setup_info       vmlinux EXPORT_SYMBOL
++0xb3daf4bf    jbd2_journal_get_undo_access    vmlinux EXPORT_SYMBOL
++0xe16591ab    stop_machine    vmlinux EXPORT_SYMBOL_GPL
++0xb6261484    register_die_notifier   vmlinux EXPORT_SYMBOL_GPL
++0x415838be    led_trigger_set_default vmlinux EXPORT_SYMBOL_GPL
++0x843020c0    ip6_find_1stfragopt     vmlinux EXPORT_SYMBOL
++0x062936ed    nf_ct_unlink_expect_report      vmlinux EXPORT_SYMBOL_GPL
++0xa6d16c61    sock_no_recvmsg vmlinux EXPORT_SYMBOL
++0x4b0ac955    hrtimer_cancel  vmlinux EXPORT_SYMBOL_GPL
++0x3626ebf4    xt_unregister_matches   vmlinux EXPORT_SYMBOL
++0x72ea7812    security_inode_setattr  vmlinux EXPORT_SYMBOL_GPL
++0xfdfc0b3b    fiemap_fill_next_extent vmlinux EXPORT_SYMBOL
++0x82d19daa    qdisc_watchdog_cancel   vmlinux EXPORT_SYMBOL
++0xc0581ee5    crypto_shash_digest     vmlinux EXPORT_SYMBOL_GPL
++0x78728b6b    crypto_ahash_digest     vmlinux EXPORT_SYMBOL_GPL
++0x3de9cae1    crypto_remove_final     vmlinux EXPORT_SYMBOL_GPL
++0x31faa864    media_entity_init       vmlinux EXPORT_SYMBOL_GPL
++0xe827112b    rtnl_set_sk_err vmlinux EXPORT_SYMBOL
++0x5b23591f    snd_soc_jack_new        vmlinux EXPORT_SYMBOL_GPL
++0x7b6646bb    _raw_read_lock  vmlinux EXPORT_SYMBOL
++0xd4669fad    complete        vmlinux EXPORT_SYMBOL
++0x488882e7    downgrade_write vmlinux EXPORT_SYMBOL
++0xbaac427c    get_mem_type    vmlinux EXPORT_SYMBOL
++0xc4014b9d    ip_check_defrag vmlinux EXPORT_SYMBOL
++0x6aaccee0    config_item_init_type_name      vmlinux EXPORT_SYMBOL
++0x62822d05    iov_iter_single_seg_count       vmlinux EXPORT_SYMBOL
++0xb1f1a6ea    gether_get_host_addr_u8 vmlinux EXPORT_SYMBOL
++0xf7f652fe    dma_mmap_from_coherent  vmlinux EXPORT_SYMBOL
++0xfa9720a0    rdev_get_dev    vmlinux EXPORT_SYMBOL_GPL
++0x62186db5    brcmu_pkt_buf_get_skb   drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0xf7af6d75    snd_pcm_new_stream      vmlinux EXPORT_SYMBOL
++0x17320c5c    dentry_update_name_case vmlinux EXPORT_SYMBOL
++0x8a7d1c31    high_memory     vmlinux EXPORT_SYMBOL
++0x0186e2de    smp_call_function_many  vmlinux EXPORT_SYMBOL
++0xbdf098ae    scsi_test_unit_ready    vmlinux EXPORT_SYMBOL
++0x119b50e7    elf_check_arch  vmlinux EXPORT_SYMBOL
++0xbf6d5c21    inet6_csk_update_pmtu   vmlinux EXPORT_SYMBOL_GPL
++0x6b9a4457    snd_soc_jack_free_gpios vmlinux EXPORT_SYMBOL_GPL
++0xd28c735f    simple_link     vmlinux EXPORT_SYMBOL
++0xbdd2f42a    rcu_bh_force_quiescent_state    vmlinux EXPORT_SYMBOL_GPL
++0x7a3cd015    v4l2_ctrl_get_menu      vmlinux EXPORT_SYMBOL
++0x97f5694d    page_cache_async_readahead      vmlinux EXPORT_SYMBOL_GPL
++0x2b4e956e    mempool_create  vmlinux EXPORT_SYMBOL
++0x57231f45    ring_buffer_record_on   vmlinux EXPORT_SYMBOL_GPL
++0x8e311007    hidinput_find_field     vmlinux EXPORT_SYMBOL_GPL
++0x7ae1ae8e    cpufreq_frequency_table_put_attr        vmlinux EXPORT_SYMBOL_GPL
++0x6c6a4b95    scsi_remove_target      vmlinux EXPORT_SYMBOL
++0xb6c5a973    scsi_show_result        vmlinux EXPORT_SYMBOL
++0x1ec3bed9    hdmi_audio_infoframe_init       vmlinux EXPORT_SYMBOL
++0x3244dece    kblockd_schedule_work   vmlinux EXPORT_SYMBOL
++0xafac4a33    mem_section     vmlinux EXPORT_SYMBOL
++0xfd044751    send_sig_info   vmlinux EXPORT_SYMBOL
++0xc02cf69b    clkdev_drop     vmlinux EXPORT_SYMBOL
++0x39c95e24    phy_init_eee    vmlinux EXPORT_SYMBOL
++0xfc53eac8    drm_cvt_mode    vmlinux EXPORT_SYMBOL
++0x6a5e6530    __neigh_event_send      vmlinux EXPORT_SYMBOL
++0x6c4d4cfe    sk_stream_wait_close    vmlinux EXPORT_SYMBOL
++0x3d1cdeca    read_cache_page_async   vmlinux EXPORT_SYMBOL
++0xd0ee38b8    schedule_timeout_uninterruptible        vmlinux EXPORT_SYMBOL
++0xd79b5a02    allow_signal    vmlinux EXPORT_SYMBOL
++0xd14fa335    show_class_attr_string  vmlinux EXPORT_SYMBOL_GPL
++0xacb2a583    ndo_dflt_fdb_add        vmlinux EXPORT_SYMBOL
++0x49a39542    snd_timer_global_register       vmlinux EXPORT_SYMBOL
++0x63407037    kill_anon_super vmlinux EXPORT_SYMBOL
++0xdc2b4205    platform_get_irq        vmlinux EXPORT_SYMBOL_GPL
++0xc777ecaa    xfrm6_rcv       vmlinux EXPORT_SYMBOL
++0x2fee3a7e    xfrm4_rcv       vmlinux EXPORT_SYMBOL
++0xe94fef47    nf_ct_delete_from_lists vmlinux EXPORT_SYMBOL_GPL
++0x6d466653    snd_soc_unregister_platform     vmlinux EXPORT_SYMBOL_GPL
++0xb61a0c3b    bt_err  vmlinux EXPORT_SYMBOL
++0x79536600    snd_soc_dpcm_can_be_params      vmlinux EXPORT_SYMBOL_GPL
++0x016c4bc3    cfg80211_put_bss        vmlinux EXPORT_SYMBOL
++0x90922aec    inet_dgram_connect      vmlinux EXPORT_SYMBOL
++0x103ea6ec    generic_pipe_buf_steal  vmlinux EXPORT_SYMBOL
++0x5fe77756    generic_pipe_buf_unmap  vmlinux EXPORT_SYMBOL
++0xe5d95985    param_ops_ulong vmlinux EXPORT_SYMBOL
++0xb03c01e8    dbs_check_cpu   vmlinux EXPORT_SYMBOL_GPL
++0xff15acd6    usb_put_function_instance       vmlinux EXPORT_SYMBOL_GPL
++0x6406cdf0    usb_find_alt_setting    vmlinux EXPORT_SYMBOL_GPL
++0x4626bf6d    phy_connect     vmlinux EXPORT_SYMBOL
++0x7a9326c6    driver_unregister       vmlinux EXPORT_SYMBOL_GPL
++0xc5570382    inet_frags_exit_net     vmlinux EXPORT_SYMBOL
++0x08216276    kobject_get     vmlinux EXPORT_SYMBOL
++0x006818a5    kobject_put     vmlinux EXPORT_SYMBOL
++0x37b777df    param_set_copystring    vmlinux EXPORT_SYMBOL
++0x54f21cff    __send_remote_softirq   vmlinux EXPORT_SYMBOL
++0x7a925833    cpufreq_get_global_kobject      vmlinux EXPORT_SYMBOL
++0x2c900d91    cpufreq_put_global_kobject      vmlinux EXPORT_SYMBOL
++0xbac4a225    v4l2_ctrl_fill  vmlinux EXPORT_SYMBOL
++0xf7e6e534    v4l2_ctrl_find  vmlinux EXPORT_SYMBOL
++0xbc5671dc    v4l_printk_ioctl        vmlinux EXPORT_SYMBOL
++0x17021c93    drm_i2c_encoder_commit  vmlinux EXPORT_SYMBOL
++0x10e70fd2    display_entity_get_modes        vmlinux EXPORT_SYMBOL_GPL
++0xf1deabf2    div64_u64       vmlinux EXPORT_SYMBOL
++0x2488515b    vb2_put_vma     vmlinux EXPORT_SYMBOL_GPL
++0xd2ea2134    usb_descriptor_fillbuf  vmlinux EXPORT_SYMBOL_GPL
++0xdacd26c5    usb_scuttle_anchored_urbs       vmlinux EXPORT_SYMBOL_GPL
++0xfc39e32f    ioport_unmap    vmlinux EXPORT_SYMBOL
++0x348998d3    sysfs_merge_group       vmlinux EXPORT_SYMBOL_GPL
++0xc84a0a7e    seq_hlist_start_rcu     vmlinux EXPORT_SYMBOL
++0xdd51deeb    d_validate      vmlinux EXPORT_SYMBOL
++0x88ea60db    __get_user_pages_fast   vmlinux EXPORT_SYMBOL_GPL
++0xe9bff861    down_trylock    vmlinux EXPORT_SYMBOL
++0xff9e0620    usb_reset_configuration vmlinux EXPORT_SYMBOL_GPL
++0x00130217    pwm_free        vmlinux EXPORT_SYMBOL_GPL
++0x8fedcd53    snd_soc_info_xr_sx      vmlinux EXPORT_SYMBOL_GPL
++0xc256e762    __bitmap_equal  vmlinux EXPORT_SYMBOL
++0x7d4e2276    __init_rwsem    vmlinux EXPORT_SYMBOL
++0xee5a877d    page_zero_new_buffers   vmlinux EXPORT_SYMBOL
++0x96710252    mntget  vmlinux EXPORT_SYMBOL
++0xe85c78e2    mntput  vmlinux EXPORT_SYMBOL
++0x038e97d3    fasync_helper   vmlinux EXPORT_SYMBOL
++0xf75c7d80    wm8994_mic_detect       vmlinux EXPORT_SYMBOL_GPL
++0x2f4113a2    dcookie_register        vmlinux EXPORT_SYMBOL_GPL
++0xce37be95    locks_mandatory_area    vmlinux EXPORT_SYMBOL
++0x8be294cd    iommu_domain_free       vmlinux EXPORT_SYMBOL_GPL
++0x23b5b8d1    exynos_drm_subdrv_register      vmlinux EXPORT_SYMBOL_GPL
++0x6867f405    inet_twsk_deschedule    vmlinux EXPORT_SYMBOL
++0x244e2178    xt_table_unlock vmlinux EXPORT_SYMBOL_GPL
++0x52b9d131    tcf_exts_dump_stats     vmlinux EXPORT_SYMBOL
++0x48bb9eb5    sock_alloc_send_pskb    vmlinux EXPORT_SYMBOL
++0x757206d5    wm_hubs_spkmix_tlv      vmlinux EXPORT_SYMBOL_GPL
++0x0acb1a3c    __bitmap_shift_right    vmlinux EXPORT_SYMBOL
++0xaaa918c9    ftrace_dump     vmlinux EXPORT_SYMBOL_GPL
++0x402b8281    __request_module        vmlinux EXPORT_SYMBOL
++0xe944ba87    st_sensors_set_axis_enable      vmlinux EXPORT_SYMBOL
++0x822f9003    inet_register_protosw   vmlinux EXPORT_SYMBOL
++0xbe3a4f06    __inet_inherit_port     vmlinux EXPORT_SYMBOL_GPL
++0xb63f16de    dev_deactivate  vmlinux EXPORT_SYMBOL
++0xa014da84    snd_soc_add_platform_controls   vmlinux EXPORT_SYMBOL_GPL
++0xeaaee9e6    submit_bio_wait vmlinux EXPORT_SYMBOL
++0x23fd3028    vmalloc_node    vmlinux EXPORT_SYMBOL
++0xa58fea9d    mempool_destroy vmlinux EXPORT_SYMBOL
++0x054e550b    kernel_halt     vmlinux EXPORT_SYMBOL_GPL
++0xf4c770ec    v4l2_clk_disable        vmlinux EXPORT_SYMBOL
++0xd597e74e    phy_find_first  vmlinux EXPORT_SYMBOL
++0x50621015    xfrm6_tunnel_spi_lookup vmlinux EXPORT_SYMBOL
++0xc0f8a5b0    set_binfmt      vmlinux EXPORT_SYMBOL
++0x36075bb5    iommu_group_register_notifier   vmlinux EXPORT_SYMBOL_GPL
++0x93b8b0d3    scsi_ioctl      vmlinux EXPORT_SYMBOL
++0xd0dcdd90    drm_mm_insert_node_in_range_generic     vmlinux EXPORT_SYMBOL
++0xb2eaff96    km_policy_expired       vmlinux EXPORT_SYMBOL
++0xa9effda5    __first_cpu     vmlinux EXPORT_SYMBOL
++0xc24ba3ed    elv_rb_find     vmlinux EXPORT_SYMBOL
++0xf0619801    timekeeping_clocktai    vmlinux EXPORT_SYMBOL
++0x9e4faeef    dm_io_client_destroy    vmlinux EXPORT_SYMBOL
++0x95cbb942    usb_add_gadget_udc_release      vmlinux EXPORT_SYMBOL_GPL
++0x14c3db3e    spi_unregister_master   vmlinux EXPORT_SYMBOL_GPL
++0xbee90f2f    __kfifo_out_peek_r      vmlinux EXPORT_SYMBOL
++0x2869ebaf    regulator_bulk_force_disable    vmlinux EXPORT_SYMBOL_GPL
++0xa04a01bd    qdisc_class_hash_insert vmlinux EXPORT_SYMBOL
++0x43a261a8    eth_commit_mac_addr_change      vmlinux EXPORT_SYMBOL
++0xe5867808    dlci_ioctl_set  vmlinux EXPORT_SYMBOL
++0xbae6da94    crypto_alg_lookup       vmlinux EXPORT_SYMBOL_GPL
++0x330d748a    v4l2_subdev_init        vmlinux EXPORT_SYMBOL
++0xc6ff1a7d    phonet_header_ops       vmlinux EXPORT_SYMBOL
++0xfaefacf3    locks_free_lock vmlinux EXPORT_SYMBOL
++0xcbfa0b41    scsi_report_device_reset        vmlinux EXPORT_SYMBOL
++0xbe1e4cd0    scsi_print_sense        vmlinux EXPORT_SYMBOL
++0xe87ed821    drm_mode_create_dirty_info_property     vmlinux EXPORT_SYMBOL
++0xb6d97288    inet6_add_offload       vmlinux EXPORT_SYMBOL
++0xa681ec81    snd_soc_jack_notifier_register  vmlinux EXPORT_SYMBOL_GPL
++0xd64b88b6    register_sound_mixer    vmlinux EXPORT_SYMBOL
++0x02701efc    simple_attr_release     vmlinux EXPORT_SYMBOL_GPL
++0xf6e04730    event_storage   vmlinux EXPORT_SYMBOL_GPL
++0x95b5af62    mmc_regulator_set_ocr   vmlinux EXPORT_SYMBOL_GPL
++0x77e78218    regulator_allow_bypass  vmlinux EXPORT_SYMBOL_GPL
++0xf1070592    cfg80211_wext_giwretry  vmlinux EXPORT_SYMBOL_GPL
++0x8a0f4230    rename_lock     vmlinux EXPORT_SYMBOL
++0xda259c5d    page_symlink_inode_operations   vmlinux EXPORT_SYMBOL
++0x8bd0a3fd    _raw_write_unlock_bh    vmlinux EXPORT_SYMBOL
++0x99b0f1ff    usb_submit_urb  vmlinux EXPORT_SYMBOL_GPL
++0x1fbd16da    ip_tos2prio     vmlinux EXPORT_SYMBOL
++0x060ea2d6    kstrtoull       vmlinux EXPORT_SYMBOL
++0x5ac15bae    kstrtou16       vmlinux EXPORT_SYMBOL
++0x1998d8b6    jbd2_inode_cache        vmlinux EXPORT_SYMBOL
++0x94961283    vunmap  vmlinux EXPORT_SYMBOL
++0x74c4a01e    write_cache_pages       vmlinux EXPORT_SYMBOL
++0xc1ddc02b    pinctrl_register        vmlinux EXPORT_SYMBOL_GPL
++0x0ca54fee    _test_and_set_bit       vmlinux EXPORT_SYMBOL
++0x80dfa464    xfrm_policy_alloc       vmlinux EXPORT_SYMBOL
++0xd04f8eb6    nf_conntrack_l4proto_tcp6       vmlinux EXPORT_SYMBOL_GPL
++0xcf28b516    finish_open     vmlinux EXPORT_SYMBOL
++0x10f734ff    led_blink_set   vmlinux EXPORT_SYMBOL
++0xc9086110    dw_mci_pltfm_remove     vmlinux EXPORT_SYMBOL_GPL
++0xe5c78a99    do_blank_screen vmlinux EXPORT_SYMBOL
++0xf17c6528    cfg80211_remain_on_channel_expired      vmlinux EXPORT_SYMBOL
++0x117093be    qdisc_class_hash_init   vmlinux EXPORT_SYMBOL
++0x13e6a1a2    sk_prot_clear_portaddr_nulls    vmlinux EXPORT_SYMBOL
++0xa2a2d730    task_current_syscall    vmlinux EXPORT_SYMBOL_GPL
++0x4411c503    prandom_seed    vmlinux EXPORT_SYMBOL
++0x547ba3f6    single_open_net vmlinux EXPORT_SYMBOL_GPL
++0xb9012717    set_page_dirty_lock     vmlinux EXPORT_SYMBOL
++0x9a37cbf4    tcp_v4_conn_request     vmlinux EXPORT_SYMBOL
++0xc81ae040    snd_soc_codec_volatile_register vmlinux EXPORT_SYMBOL_GPL
++0xbe52317a    blk_rq_init     vmlinux EXPORT_SYMBOL
++0x9ef34ad4    cpufreq_frequency_table_cpuinfo vmlinux EXPORT_SYMBOL_GPL
++0x5bcf159d    usb_get_descriptor      vmlinux EXPORT_SYMBOL_GPL
++0xf2e5cabe    spi_async_locked        vmlinux EXPORT_SYMBOL_GPL
++0x26e76fb8    sysctl_udp_wmem_min     vmlinux EXPORT_SYMBOL
++0x1fb12a69    tcp_v4_syn_recv_sock    vmlinux EXPORT_SYMBOL
++0x6d464175    __sg_free_table vmlinux EXPORT_SYMBOL
++0x59056c08    kmem_cache_shrink       vmlinux EXPORT_SYMBOL
++0xc3aef602    usb_put_dev     vmlinux EXPORT_SYMBOL_GPL
++0x520a3baf    drm_vm_open_locked      vmlinux EXPORT_SYMBOL_GPL
++0x711a004a    drm_dp_link_rate_to_bw_code     vmlinux EXPORT_SYMBOL
++0x919029aa    __readwrite_bug vmlinux EXPORT_SYMBOL
++0x49045426    icmp_err_convert        vmlinux EXPORT_SYMBOL
++0xf087137d    __dynamic_pr_debug      vmlinux EXPORT_SYMBOL
++0x1e5b03dc    pm_qos_add_notifier     vmlinux EXPORT_SYMBOL_GPL
++0x5e9d9e1e    gov_queue_work  vmlinux EXPORT_SYMBOL_GPL
++0x601f665f    dm_io_client_create     vmlinux EXPORT_SYMBOL
++0x05c311c2    vb2_ioctl_prepare_buf   vmlinux EXPORT_SYMBOL_GPL
++0x14f62d2b    mii_check_link  vmlinux EXPORT_SYMBOL
++0x36c69db7    dma_common_mmap vmlinux EXPORT_SYMBOL
++0x1072a394    csum_partial_copy_from_user     vmlinux EXPORT_SYMBOL
++0x3f878645    inet_diag_dump_one_icsk vmlinux EXPORT_SYMBOL_GPL
++0xd7b85107    tcp_hashinfo    vmlinux EXPORT_SYMBOL
++0x2d140a58    genl_unlock     vmlinux EXPORT_SYMBOL
++0xeed1b62f    crypto_aead_setauthsize vmlinux EXPORT_SYMBOL_GPL
++0x5f7bdc58    fd_install      vmlinux EXPORT_SYMBOL
++0xe11f3cbc    _raw_read_lock_bh       vmlinux EXPORT_SYMBOL
++0x3fd55724    of_n_size_cells vmlinux EXPORT_SYMBOL
++0xd17aae7c    hid_report_raw_event    vmlinux EXPORT_SYMBOL_GPL
++0xe469207d    scsi_unregister vmlinux EXPORT_SYMBOL
++0xbf5da77e    dma_buf_begin_cpu_access        vmlinux EXPORT_SYMBOL_GPL
++0x47ed7ca1    inet6_unregister_icmp_sender    vmlinux EXPORT_SYMBOL
++0xed8b1ab6    nf_nat_used_tuple       vmlinux EXPORT_SYMBOL
++0x46e928cf    nf_nat_packet   vmlinux EXPORT_SYMBOL_GPL
++0xdc854ee4    blk_init_tags   vmlinux EXPORT_SYMBOL
++0x4b134056    vfs_fsync_range vmlinux EXPORT_SYMBOL
++0x3ce4ca6f    disable_irq     vmlinux EXPORT_SYMBOL
++0xdc9fa232    raw_notifier_chain_register     vmlinux EXPORT_SYMBOL_GPL
++0x2b0d15d8    scsi_internal_device_unblock    vmlinux EXPORT_SYMBOL_GPL
++0x09d12bc0    sysfs_remove_file       vmlinux EXPORT_SYMBOL_GPL
++0x85a8465a    path_put        vmlinux EXPORT_SYMBOL
++0xe0dec72b    apply_to_page_range     vmlinux EXPORT_SYMBOL_GPL
++0xa0ceef51    out_of_line_wait_on_bit vmlinux EXPORT_SYMBOL
++0x7f04e7d5    dm_set_target_max_io_len        vmlinux EXPORT_SYMBOL_GPL
++0x84a26155    v4l2_ctrl_g_ctrl        vmlinux EXPORT_SYMBOL
++0x1254f0e4    scsi_host_alloc vmlinux EXPORT_SYMBOL
++0x0e09444b    bus_get_device_klist    vmlinux EXPORT_SYMBOL_GPL
++0xbebc3cd2    dst_discard     vmlinux EXPORT_SYMBOL
++0x8d25ae30    snd_soc_dapm_put_value_enum_double      vmlinux EXPORT_SYMBOL_GPL
++0x8d02ccf1    snd_soc_dapm_get_value_enum_double      vmlinux EXPORT_SYMBOL_GPL
++0xaa2a72bf    __iowrite64_copy        vmlinux EXPORT_SYMBOL_GPL
++0x373d62c5    invalidate_partition    vmlinux EXPORT_SYMBOL
++0xd217e9e6    trace_set_clr_event     vmlinux EXPORT_SYMBOL_GPL
++0x00e86db4    kick_process    vmlinux EXPORT_SYMBOL_GPL
++0xa625110d    kmsg_dump_rewind        vmlinux EXPORT_SYMBOL_GPL
++0x17eb0eee    v4l2_m2m_init   vmlinux EXPORT_SYMBOL_GPL
++0xd153a267    drm_irq_uninstall       vmlinux EXPORT_SYMBOL
++0x6ccf7bd7    __pv_phys_offset        vmlinux EXPORT_SYMBOL
++0x6cf45a72    sk_release_kernel       vmlinux EXPORT_SYMBOL
++0x7cff72b3    sg_miter_stop   vmlinux EXPORT_SYMBOL
++0x0da10ec3    security_sock_graft     vmlinux EXPORT_SYMBOL
++0xe601743b    jbd2_journal_init_jbd_inode     vmlinux EXPORT_SYMBOL
++0xdd3916ac    _raw_spin_unlock_bh     vmlinux EXPORT_SYMBOL
++0xb5ab5fe9    usb_function_register   vmlinux EXPORT_SYMBOL_GPL
++0xa20bbbd7    xt_proto_init   vmlinux EXPORT_SYMBOL_GPL
++0x13b715e2    blk_finish_plug vmlinux EXPORT_SYMBOL
++0x0b1beb31    vmalloc_32_user vmlinux EXPORT_SYMBOL
++0x85dfe0aa    fget_light      vmlinux EXPORT_SYMBOL
++0x8bebc4a8    drm_master_put  vmlinux EXPORT_SYMBOL
++0xf073bd48    nfc_hci_target_discovered       vmlinux EXPORT_SYMBOL
++0x878ab3ce    sysctl_tcp_adv_win_scale        vmlinux EXPORT_SYMBOL
++0x11e11bef    ip_local_out    vmlinux EXPORT_SYMBOL_GPL
++0xafe96047    generic_permission      vmlinux EXPORT_SYMBOL
++0x96123b65    iio_trigger_unregister  vmlinux EXPORT_SYMBOL
++0xf7b01b50    gether_get_host_addr_cdc        vmlinux EXPORT_SYMBOL
++0x3324e6d2    ehci_suspend    vmlinux EXPORT_SYMBOL_GPL
++0x7ef61596    usb_hcd_check_unlink_urb        vmlinux EXPORT_SYMBOL_GPL
++0x7ced7048    phy_device_free vmlinux EXPORT_SYMBOL
++0x9afda3df    regcache_cache_bypass   vmlinux EXPORT_SYMBOL_GPL
++0xd59668e6    unlock_flocks   vmlinux EXPORT_SYMBOL_GPL
++0xb818e055    usbnet_open     vmlinux EXPORT_SYMBOL_GPL
++0x4683093b    snd_ctl_notify  vmlinux EXPORT_SYMBOL
++0x9d3aa376    blk_iopoll_init vmlinux EXPORT_SYMBOL
++0x226a674d    atomic_notifier_chain_unregister        vmlinux EXPORT_SYMBOL_GPL
++0x0144d325    regmap_async_complete   vmlinux EXPORT_SYMBOL_GPL
++0x27f4cbdb    uart_get_baud_rate      vmlinux EXPORT_SYMBOL
++0x878175c4    secpath_dup     vmlinux EXPORT_SYMBOL
++0x7931d788    snd_pcm_hw_constraint_step      vmlinux EXPORT_SYMBOL
++0x36170e28    set_user_nice   vmlinux EXPORT_SYMBOL
++0x45de06d1    iio_buffer_write_length vmlinux EXPORT_SYMBOL
++0x5babbf10    media_device_unregister_entity  vmlinux EXPORT_SYMBOL_GPL
++0xe593d0c8    usbnet_disconnect       vmlinux EXPORT_SYMBOL_GPL
++0xb7e8ce46    exynos_drm_subdrv_close vmlinux EXPORT_SYMBOL_GPL
++0xc29dc1ad    drm_framebuffer_init    vmlinux EXPORT_SYMBOL
++0x7fe1a403    cfg80211_find_ie        vmlinux EXPORT_SYMBOL
++0xa8469c88    netdev_notify_peers     vmlinux EXPORT_SYMBOL
++0xe81978c6    splice_direct_to_actor  vmlinux EXPORT_SYMBOL
++0xb5cb8145    hrtimer_get_res vmlinux EXPORT_SYMBOL_GPL
++0x9a70b0fd    nf_nat_pptp_hook_inbound        vmlinux EXPORT_SYMBOL_GPL
++0x2b9da7a4    genl_lock       vmlinux EXPORT_SYMBOL
++0xb72e58d6    qdisc_class_hash_grow   vmlinux EXPORT_SYMBOL
++0x0e59e8cf    sock_setsockopt vmlinux EXPORT_SYMBOL
++0x20df2681    ida_simple_remove       vmlinux EXPORT_SYMBOL
++0xbdef23a2    unlock_buffer   vmlinux EXPORT_SYMBOL
++0x3b231b68    simple_transaction_release      vmlinux EXPORT_SYMBOL
++0xad098b64    usb_unlocked_enable_lpm vmlinux EXPORT_SYMBOL_GPL
++0x4b05e7ed    tty_port_close_start    vmlinux EXPORT_SYMBOL
++0x14789075    dma_find_channel        vmlinux EXPORT_SYMBOL
++0x77c05b09    fb_find_mode    vmlinux EXPORT_SYMBOL
++0x01010c6d    klist_add_before        vmlinux EXPORT_SYMBOL_GPL
++0x292c29ad    nfulnl_log_packet       vmlinux EXPORT_SYMBOL_GPL
++0x521b36b5    qdisc_put_rtab  vmlinux EXPORT_SYMBOL
++0x69c66f79    crypto_attr_alg2        vmlinux EXPORT_SYMBOL_GPL
++0x341dbfa3    __per_cpu_offset        vmlinux EXPORT_SYMBOL
++0x8953f8ff    __tracepoint_kmem_cache_alloc   vmlinux EXPORT_SYMBOL
++0x7e0ef97c    regmap_irq_get_domain   vmlinux EXPORT_SYMBOL_GPL
++0x437ff921    subsys_find_device_by_id        vmlinux EXPORT_SYMBOL_GPL
++0x975e0663    set_sig_addr_hook       vmlinux EXPORT_SYMBOL_GPL
++0xe86f0da8    proto_register  vmlinux EXPORT_SYMBOL
++0xb838d98e    event_storage_mutex     vmlinux EXPORT_SYMBOL_GPL
++0x9ca1dc35    vb2_fop_mmap    vmlinux EXPORT_SYMBOL_GPL
++0xde1a5959    rtc_irq_unregister      vmlinux EXPORT_SYMBOL_GPL
++0xbeca75ff    drm_crtc_helper_set_mode        vmlinux EXPORT_SYMBOL
++0x65f850bc    tty_wakeup      vmlinux EXPORT_SYMBOL_GPL
++0xf4743f88    amba_ahb_device_add     vmlinux EXPORT_SYMBOL_GPL
++0xa994f545    check_disk_size_change  vmlinux EXPORT_SYMBOL
++0x455293f6    down_read       vmlinux EXPORT_SYMBOL
++0x7eaf8e7a    v4l2_detect_gtf vmlinux EXPORT_SYMBOL_GPL
++0x53105839    v4l2_detect_cvt vmlinux EXPORT_SYMBOL_GPL
++0x6a41ea71    v4l2_clk_get_rate       vmlinux EXPORT_SYMBOL
++0xc50c3f79    v4l2_clk_set_rate       vmlinux EXPORT_SYMBOL
++0x52bc9e2a    drm_plane_cleanup       vmlinux EXPORT_SYMBOL
++0x0d4cb82a    km_report       vmlinux EXPORT_SYMBOL
++0xcffe8e42    __napi_complete vmlinux EXPORT_SYMBOL
++0xb17c5844    skb_copy_expand vmlinux EXPORT_SYMBOL
++0xaaaa5788    blk_queue_softirq_done  vmlinux EXPORT_SYMBOL
++0x43a762e5    d_lookup        vmlinux EXPORT_SYMBOL
++0xebc525f4    iio_triggered_buffer_cleanup    vmlinux EXPORT_SYMBOL
++0xabd0c91c    rtc_time_to_tm  vmlinux EXPORT_SYMBOL
++0x70f3f9b2    dmam_free_coherent      vmlinux EXPORT_SYMBOL
++0xba361646    transport_setup_device  vmlinux EXPORT_SYMBOL_GPL
++0x950ee7d1    fb_find_logo    vmlinux EXPORT_SYMBOL_GPL
++0x20294ce8    genl_unregister_mc_group        vmlinux EXPORT_SYMBOL
++0x1d7aabfd    path_is_under   vmlinux EXPORT_SYMBOL
++0x17975413    iio_map_array_register  vmlinux EXPORT_SYMBOL_GPL
++0xf811e69d    scsi_eh_flush_done_q    vmlinux EXPORT_SYMBOL
++0x8b95a59f    xt_hook_unlink  vmlinux EXPORT_SYMBOL_GPL
++0x557cb7c6    skb_morph       vmlinux EXPORT_SYMBOL_GPL
++0x02ef742b    percpu_counter_set      vmlinux EXPORT_SYMBOL
++0x03ae21fb    mmc_erase       vmlinux EXPORT_SYMBOL
++0x7c46233a    cpufreq_quick_get       vmlinux EXPORT_SYMBOL
++0xa4f8a168    dm_underlying_device_busy       vmlinux EXPORT_SYMBOL_GPL
++0x1d41eadc    v4l2_ctrl_s_ctrl        vmlinux EXPORT_SYMBOL
++0xa11295ab    serio_unregister_port   vmlinux EXPORT_SYMBOL
++0x11065515    drm_mode_equal  vmlinux EXPORT_SYMBOL
++0x4c47ec15    klist_add_head  vmlinux EXPORT_SYMBOL_GPL
++0x68a24153    snd_pcm_format_physical_width   vmlinux EXPORT_SYMBOL
++0xb6822a33    radix_tree_gang_lookup_tag      vmlinux EXPORT_SYMBOL
++0xdaa16b82    of_clk_get      vmlinux EXPORT_SYMBOL
++0x5c625801    scsi_remove_host        vmlinux EXPORT_SYMBOL
++0xa7de1327    flush_dcache_page       vmlinux EXPORT_SYMBOL
++0x2d6507b5    _find_next_zero_bit_le  vmlinux EXPORT_SYMBOL
++0xf26e1c06    snd_soc_suspend vmlinux EXPORT_SYMBOL_GPL
++0xc213a12a    devm_ioremap_nocache    vmlinux EXPORT_SYMBOL
++0xb43a5300    sync_dirty_buffer       vmlinux EXPORT_SYMBOL
++0xd303fa4e    clk_notifier_unregister vmlinux EXPORT_SYMBOL_GPL
++0x496c3d67    v4l2_querymenu  vmlinux EXPORT_SYMBOL
++0x02b44bb5    scsi_is_host_device     vmlinux EXPORT_SYMBOL
++0x91c9a325    bt_to_errno     vmlinux EXPORT_SYMBOL
++0x86a85b06    tcp_reno_ssthresh       vmlinux EXPORT_SYMBOL_GPL
++0xfc5c6b3e    netlink_has_listeners   vmlinux EXPORT_SYMBOL_GPL
++0xe075d6eb    iter_div_u64_rem        vmlinux EXPORT_SYMBOL
++0xcf0e08ad    filter_current_check_discard    vmlinux EXPORT_SYMBOL_GPL
++0x5afb47fc    of_irq_to_resource_table        vmlinux EXPORT_SYMBOL_GPL
++0xf1421d13    drm_mode_sort   vmlinux EXPORT_SYMBOL
++0xd06ec95f    dma_supported   vmlinux EXPORT_SYMBOL
++0xf1b80226    nf_nat_seq_adjust_hook  vmlinux EXPORT_SYMBOL_GPL
++0xf4c02b65    inode_init_once vmlinux EXPORT_SYMBOL
++0x369fcd70    tracing_snapshot        vmlinux EXPORT_SYMBOL_GPL
++0x73d69364    ring_buffer_change_overwrite    vmlinux EXPORT_SYMBOL_GPL
++0x339d542a    __srcu_notifier_call_chain      vmlinux EXPORT_SYMBOL_GPL
++0xe2d3d0b9    v4l2_ctrl_sub_ev_ops    vmlinux EXPORT_SYMBOL
++0xee129bef    usb_alloc_urb   vmlinux EXPORT_SYMBOL_GPL
++0x64a127a3    spi_setup       vmlinux EXPORT_SYMBOL_GPL
++0x3a8da0aa    nf_ip6_checksum vmlinux EXPORT_SYMBOL
++0xb46a6cbb    scsi_cmd_ioctl  vmlinux EXPORT_SYMBOL
++0xf7d52055    iio_bus_type    vmlinux EXPORT_SYMBOL
++0x75b9f8b8    device_move     vmlinux EXPORT_SYMBOL_GPL
++0x34dc9b87    neigh_seq_stop  vmlinux EXPORT_SYMBOL
++0x82b802b2    snd_soc_dai_set_pll     vmlinux EXPORT_SYMBOL_GPL
++0x0f4c91ed    ns_to_timespec  vmlinux EXPORT_SYMBOL
++0xca34e63d    iio_triggered_buffer_postenable vmlinux EXPORT_SYMBOL
++0x8d3ecd41    drm_core_ioremapfree    vmlinux EXPORT_SYMBOL
++0xed93f29e    __kunmap_atomic vmlinux EXPORT_SYMBOL
++0xe7cd755a    nf_ct_dying_timeout     vmlinux EXPORT_SYMBOL_GPL
++0xe5452cbf    dev_mc_del_global       vmlinux EXPORT_SYMBOL
++0x1a77ed38    dev_mc_add_global       vmlinux EXPORT_SYMBOL
++0x7b4901f5    snd_soc_add_platform    vmlinux EXPORT_SYMBOL_GPL
++0xdff7c9ce    blocking_notifier_chain_unregister      vmlinux EXPORT_SYMBOL_GPL
++0x346127a7    drm_global_item_ref     vmlinux EXPORT_SYMBOL
++0xf763bb6d    drm_framebuffer_cleanup vmlinux EXPORT_SYMBOL
++0x4a6b641b    fifo_create_dflt        vmlinux EXPORT_SYMBOL
++0x3a39f5ed    neigh_table_init        vmlinux EXPORT_SYMBOL
++0xc7207cfe    blk_queue_segment_boundary      vmlinux EXPORT_SYMBOL
++0x183b1236    blk_stop_queue  vmlinux EXPORT_SYMBOL
++0x632b18ed    blkcipher_walk_virt_block       vmlinux EXPORT_SYMBOL_GPL
++0x68ecff32    sysfs_create_link       vmlinux EXPORT_SYMBOL_GPL
++0x2bc64f3b    task_active_pid_ns      vmlinux EXPORT_SYMBOL_GPL
++0xda83d7a1    mmc_register_driver     vmlinux EXPORT_SYMBOL
++0x85e9caff    exynos4x12_cpufreq_init vmlinux EXPORT_SYMBOL
++0xf75603a3    exynos4210_cpufreq_init vmlinux EXPORT_SYMBOL
++0x38a9c2c7    input_ff_effect_from_user       vmlinux EXPORT_SYMBOL_GPL
++0x4f92c146    mfd_cell_enable vmlinux EXPORT_SYMBOL
++0xeacc50bc    attribute_container_register    vmlinux EXPORT_SYMBOL_GPL
++0x53465c39    drm_vblank_count_and_time       vmlinux EXPORT_SYMBOL
++0xc0e23731    inetpeer_invalidate_tree        vmlinux EXPORT_SYMBOL
++0x7d1904b2    __neigh_create  vmlinux EXPORT_SYMBOL
++0x6d294e43    clock_t_to_jiffies      vmlinux EXPORT_SYMBOL
++0x327bf883    of_can_translate_address        vmlinux EXPORT_SYMBOL
++0x6232e48e    power_supply_powers     vmlinux EXPORT_SYMBOL_GPL
++0x15b9125f    hdmi_avi_infoframe_pack vmlinux EXPORT_SYMBOL
++0x48e7c422    fanout_mutex    vmlinux EXPORT_SYMBOL_GPL
++0xdf050302    skb_mac_gso_segment     vmlinux EXPORT_SYMBOL
++0x4afb74d0    snd_pcm_lib_preallocate_pages_for_all   vmlinux EXPORT_SYMBOL
++0xf874d572    crypto_larval_alloc     vmlinux EXPORT_SYMBOL_GPL
++0x540a73a6    seq_release     vmlinux EXPORT_SYMBOL
++0xb3826d47    insert_inode_locked     vmlinux EXPORT_SYMBOL
++0x1866cec2    ring_buffer_size        vmlinux EXPORT_SYMBOL_GPL
++0x838b13e7    ring_buffer_free        vmlinux EXPORT_SYMBOL_GPL
++0x41d8cf05    module_layout   vmlinux EXPORT_SYMBOL
++0xdbb5a9f5    drm_ht_remove_item      vmlinux EXPORT_SYMBOL
++0x654a5368    drm_vblank_off  vmlinux EXPORT_SYMBOL
++0xb3e9e167    drm_vblank_get  vmlinux EXPORT_SYMBOL
++0xa795c78d    pl330_filter    vmlinux EXPORT_SYMBOL
++0x0335cb43    __sb_start_write        vmlinux EXPORT_SYMBOL
++0x6955eb5f    hidinput_disconnect     vmlinux EXPORT_SYMBOL_GPL
++0xd49dd4f4    cfg80211_cqm_txe_notify vmlinux EXPORT_SYMBOL
++0xcc1fb551    baswap  vmlinux EXPORT_SYMBOL
++0x653aa466    __blk_put_request       vmlinux EXPORT_SYMBOL_GPL
++0x99401626    elv_rb_latter_request   vmlinux EXPORT_SYMBOL
++0x0da68fbf    sysfs_create_bin_file   vmlinux EXPORT_SYMBOL_GPL
++0x27fa66e1    nr_free_buffer_pages    vmlinux EXPORT_SYMBOL_GPL
++0x7452437c    cgroup_taskset_next     vmlinux EXPORT_SYMBOL_GPL
++0xd2e7fb21    mod_delayed_work_on     vmlinux EXPORT_SYMBOL_GPL
++0x3d388324    dpm_resume_end  vmlinux EXPORT_SYMBOL_GPL
++0xfda2fc6f    pinctrl_remove_gpio_range       vmlinux EXPORT_SYMBOL_GPL
++0x98c9f584    klist_init      vmlinux EXPORT_SYMBOL_GPL
++0x72e52881    xfrm_state_unregister_afinfo    vmlinux EXPORT_SYMBOL
++0xec57ea15    snd_card_unref  vmlinux EXPORT_SYMBOL
++0x6cdc5c6b    nla_strlcpy     vmlinux EXPORT_SYMBOL
++0xa46f2f1b    kstrtouint      vmlinux EXPORT_SYMBOL
++0x315c8d71    blk_init_queue_node     vmlinux EXPORT_SYMBOL
++0x83211609    up_write        vmlinux EXPORT_SYMBOL
++0x19610e1f    cpu_all_bits    vmlinux EXPORT_SYMBOL
++0x4f248523    of_find_node_by_name    vmlinux EXPORT_SYMBOL
++0x14d0738e    dm_noflush_suspending   vmlinux EXPORT_SYMBOL_GPL
++0x488cee4b    serial8250_do_pm        vmlinux EXPORT_SYMBOL
++0xe4e38519    tcf_hash_release        vmlinux EXPORT_SYMBOL
++0xf1298271    free_buffer_head        vmlinux EXPORT_SYMBOL
++0x08559b9a    fget    vmlinux EXPORT_SYMBOL
++0x4a57b339    wait_for_completion_io_timeout  vmlinux EXPORT_SYMBOL
++0xcccd9343    mmc_gpio_get_ro vmlinux EXPORT_SYMBOL
++0xa3959367    mmc_gpio_get_cd vmlinux EXPORT_SYMBOL
++0xbc3a2d91    cpufreq_cpu_put vmlinux EXPORT_SYMBOL_GPL
++0x238dd120    cpufreq_cpu_get vmlinux EXPORT_SYMBOL_GPL
++0xfe7c6819    scsi_target_block       vmlinux EXPORT_SYMBOL_GPL
++0x42488405    scsi_prep_state_check   vmlinux EXPORT_SYMBOL
++0xf4b2e991    drm_mm_put_block        vmlinux EXPORT_SYMBOL
++0x688bd4c5    snd_ctl_boolean_mono_info       vmlinux EXPORT_SYMBOL
++0xe1e281d6    jbd2_log_start_commit   vmlinux EXPORT_SYMBOL
++0x9130f1c7    remove_proc_subtree     vmlinux EXPORT_SYMBOL
++0xfa1eb910    unregister_syscore_ops  vmlinux EXPORT_SYMBOL_GPL
++0x4d7f9839    snd_soc_of_parse_card_name      vmlinux EXPORT_SYMBOL_GPL
++0x44e9a829    match_token     vmlinux EXPORT_SYMBOL
++0x49b26c63    jbd2_journal_abort      vmlinux EXPORT_SYMBOL
++0x1a323362    __ftrace_vbprintk       vmlinux EXPORT_SYMBOL_GPL
++0x0a958ed4    down_write      vmlinux EXPORT_SYMBOL
++0x706b3a33    cpufreq_frequency_table_get_attr        vmlinux EXPORT_SYMBOL_GPL
++0xbdba9828    hdmi_audio_infoframe_pack       vmlinux EXPORT_SYMBOL
++0x09c64fbd    ieee80211_frequency_to_channel  vmlinux EXPORT_SYMBOL
++0x64d41d38    ip_route_output_flow    vmlinux EXPORT_SYMBOL_GPL
++0xc23832c5    snd_soc_add_card_controls       vmlinux EXPORT_SYMBOL_GPL
++0x43326227    posix_test_lock vmlinux EXPORT_SYMBOL
++0xd7289dfe    kill_block_super        vmlinux EXPORT_SYMBOL
++0x2b0f3b97    flush_signals   vmlinux EXPORT_SYMBOL
++0x1b9e0ff1    scsilun_to_int  vmlinux EXPORT_SYMBOL
++0x97a0de2c    drm_prime_pages_to_sg   vmlinux EXPORT_SYMBOL
++0x0442abb5    __inet_stream_connect   vmlinux EXPORT_SYMBOL
++0xc6f7d745    nf_ct_remove_expectations       vmlinux EXPORT_SYMBOL_GPL
++0xecdea3ba    neigh_lookup_nodev      vmlinux EXPORT_SYMBOL
++0x10c58227    kernel_setsockopt       vmlinux EXPORT_SYMBOL
++0x8fd29b0f    kernel_getsockopt       vmlinux EXPORT_SYMBOL
++0xed5cfaa9    kernel_sock_ioctl       vmlinux EXPORT_SYMBOL
++0x8ffdb3b8    crc16   vmlinux EXPORT_SYMBOL
++0xadc7f742    mb_cache_entry_insert   vmlinux EXPORT_SYMBOL
++0x4e1e8913    kallsyms_on_each_symbol vmlinux EXPORT_SYMBOL_GPL
++0xf82f3657    work_on_cpu     vmlinux EXPORT_SYMBOL_GPL
++0x459e133f    v4l2_m2m_get_curr_priv  vmlinux EXPORT_SYMBOL
++0x4dd51c13    phy_pm_runtime_allow    vmlinux EXPORT_SYMBOL_GPL
++0xcbbaba0b    nf_tproxy_assign_sock   vmlinux EXPORT_SYMBOL_GPL
++0x3e220367    nfnetlink_unicast       vmlinux EXPORT_SYMBOL_GPL
++0x55504881    snd_mixer_oss_ioctl_card        vmlinux EXPORT_SYMBOL
++0xab694444    bsearch vmlinux EXPORT_SYMBOL
++0x662edc7c    blk_put_request vmlinux EXPORT_SYMBOL
++0x6ca4bf88    async_synchronize_full_domain   vmlinux EXPORT_SYMBOL_GPL
++0x12456a92    iommu_iova_to_phys      vmlinux EXPORT_SYMBOL_GPL
++0xdc7b411a    dev_pm_qos_hide_latency_limit   vmlinux EXPORT_SYMBOL_GPL
++0x28441b73    drm_get_last_vbltimestamp       vmlinux EXPORT_SYMBOL
++0x83eab4ef    crypto_create_tfm       vmlinux EXPORT_SYMBOL_GPL
++0x42e2c53b    nf_conntrack_in vmlinux EXPORT_SYMBOL_GPL
++0x3ea1d70f    sock_queue_rcv_skb      vmlinux EXPORT_SYMBOL
++0xe7820ad2    snd_pcm_lib_preallocate_free_for_all    vmlinux EXPORT_SYMBOL
++0x754dac78    blk_limits_io_min       vmlinux EXPORT_SYMBOL
++0x0cd9cfec    sysfs_remove_files      vmlinux EXPORT_SYMBOL_GPL
++0xc237047a    mapping_tagged  vmlinux EXPORT_SYMBOL
++0xd777c9b7    iio_device_alloc        vmlinux EXPORT_SYMBOL
++0xd688716b    dm_kcopyd_client_create vmlinux EXPORT_SYMBOL
++0x2502c67c    v4l2_fh_add     vmlinux EXPORT_SYMBOL_GPL
++0x088675f7    usbnet_write_cmd_async  vmlinux EXPORT_SYMBOL_GPL
++0xb35659de    drm_mode_remove vmlinux EXPORT_SYMBOL
++0x16acff8a    devm_of_pwm_get vmlinux EXPORT_SYMBOL_GPL
++0xd2bd22d2    s3c_gpio_getpull        vmlinux EXPORT_SYMBOL
++0x5fbecd25    s3c_gpio_setpull        vmlinux EXPORT_SYMBOL
++0x67c2fa54    __copy_to_user  vmlinux EXPORT_SYMBOL
++0x7c6a49ce    unix_table_lock vmlinux EXPORT_SYMBOL_GPL
++0x38d60861    put_disk        vmlinux EXPORT_SYMBOL
++0x871bcaa4    irq_find_host   vmlinux EXPORT_SYMBOL_GPL
++0xd9605d4c    add_timer       vmlinux EXPORT_SYMBOL
++0xea97fb5e    usbhid_set_leds vmlinux EXPORT_SYMBOL_GPL
++0x70915b51    serio_interrupt vmlinux EXPORT_SYMBOL
++0x92a772c3    usbnet_purge_paused_rxq vmlinux EXPORT_SYMBOL_GPL
++0xf6bb4729    color_table     vmlinux EXPORT_SYMBOL
++0x8c637d43    irq_cpu_rmap_add        vmlinux EXPORT_SYMBOL
++0x9ba7089d    argv_split      vmlinux EXPORT_SYMBOL
++0x34f3484e    security_tun_dev_attach_queue   vmlinux EXPORT_SYMBOL
++0x1a1431fd    _raw_spin_unlock_irq    vmlinux EXPORT_SYMBOL
++0x7c08f605    hid_allocate_device     vmlinux EXPORT_SYMBOL_GPL
++0xe5a8e6b5    spi_sync        vmlinux EXPORT_SYMBOL_GPL
++0xcc69f0f8    dma_sync_wait   vmlinux EXPORT_SYMBOL
++0x43e33157    blk_queue_max_hw_sectors        vmlinux EXPORT_SYMBOL
++0x8ea0cdd5    drm_add_modes_noedid    vmlinux EXPORT_SYMBOL
++0x9a8318ef    v7_coherent_kern_range  vmlinux EXPORT_SYMBOL
++0x5de3ad52    cfg80211_ref_bss        vmlinux EXPORT_SYMBOL
++0xdc1b2765    crypto_aes_set_key      vmlinux EXPORT_SYMBOL_GPL
++0x5086ac3a    alg_test        vmlinux EXPORT_SYMBOL_GPL
++0x9c35fb24    jbd2__journal_restart   vmlinux EXPORT_SYMBOL
++0xbef43296    console_conditional_schedule    vmlinux EXPORT_SYMBOL
++0xa71c1b98    bus_set_iommu   vmlinux EXPORT_SYMBOL_GPL
++0x8e801428    bus_create_file vmlinux EXPORT_SYMBOL_GPL
++0x8fc34c2d    drm_warn_on_modeset_not_all_locked      vmlinux EXPORT_SYMBOL
++0x2e0a06e3    snd_unregister_device   vmlinux EXPORT_SYMBOL
++0x9caaf6cf    blkdev_issue_discard    vmlinux EXPORT_SYMBOL
++0x3e6444e8    crypto_unregister_pcomp vmlinux EXPORT_SYMBOL_GPL
++0xc1d19fdd    debugfs_create_symlink  vmlinux EXPORT_SYMBOL_GPL
++0x9bd7640e    fat_detach      vmlinux EXPORT_SYMBOL_GPL
++0x698a899f    ring_buffer_peek        vmlinux EXPORT_SYMBOL_GPL
++0xe2e7840d    regmap_init_mmio_clk    vmlinux EXPORT_SYMBOL_GPL
++0xe556d687    xt_request_find_match   vmlinux EXPORT_SYMBOL_GPL
++0xcf25e6b2    xattr_getsecurity       vmlinux EXPORT_SYMBOL_GPL
++0x6228c21f    smp_call_function_single        vmlinux EXPORT_SYMBOL
++0x5f324ec1    drm_ioctl       vmlinux EXPORT_SYMBOL
++0x4d9b652b    rb_erase        vmlinux EXPORT_SYMBOL
++0xcc71d484    drm_mode_duplicate      vmlinux EXPORT_SYMBOL
++0x2b02560b    devm_pwm_put    vmlinux EXPORT_SYMBOL_GPL
++0x3659d5ac    devm_phy_get    vmlinux EXPORT_SYMBOL_GPL
++0xaafdc258    strcasecmp      vmlinux EXPORT_SYMBOL
++0xc296567b    save_mount_options      vmlinux EXPORT_SYMBOL
++0xbade32c7    clockevents_register_device     vmlinux EXPORT_SYMBOL_GPL
++0xfb8a84a4    drm_mm_get_block_range_generic  vmlinux EXPORT_SYMBOL
++0x058b582a    vt_get_leds     vmlinux EXPORT_SYMBOL_GPL
++0xb2a0603e    nci_recv_frame  vmlinux EXPORT_SYMBOL
++0xc0240dd4    nf_conntrack_set_hashsize       vmlinux EXPORT_SYMBOL_GPL
++0x45c8cd86    ifla_policy     vmlinux EXPORT_SYMBOL
++0xd251d7b0    security_socket_getpeersec_dgram        vmlinux EXPORT_SYMBOL
++0xf05e203c    set_blocksize   vmlinux EXPORT_SYMBOL
++0xc1c995a0    block_page_mkwrite      vmlinux EXPORT_SYMBOL
++0x85b9e216    set_timer_slack vmlinux EXPORT_SYMBOL_GPL
++0x2665c0a3    vb2_qbuf        vmlinux EXPORT_SYMBOL_GPL
++0x9abe8d18    video_usercopy  vmlinux EXPORT_SYMBOL
++0x1d93e603    tty_unthrottle  vmlinux EXPORT_SYMBOL
++0x1142511d    crypto_spawn_tfm        vmlinux EXPORT_SYMBOL_GPL
++0xeb9ddf6d    security_inode_notifysecctx     vmlinux EXPORT_SYMBOL
++0x68df960a    generic_error_remove_page       vmlinux EXPORT_SYMBOL
++0x7000dc34    class_compat_remove_link        vmlinux EXPORT_SYMBOL_GPL
++0x816dee03    uart_unregister_driver  vmlinux EXPORT_SYMBOL
++0x0acf7679    dma_issue_pending_all   vmlinux EXPORT_SYMBOL
++0x8792d764    l2cap_conn_get  vmlinux EXPORT_SYMBOL
++0xcf2890b2    ipv6_chk_prefix vmlinux EXPORT_SYMBOL
++0x616ff33b    ip6_dst_lookup_flow     vmlinux EXPORT_SYMBOL_GPL
++0x3e963d19    inet_csk_search_req     vmlinux EXPORT_SYMBOL_GPL
++0xdd632e58    inet_unhash     vmlinux EXPORT_SYMBOL_GPL
++0x98e40edf    nf_ct_nat_offset        vmlinux EXPORT_SYMBOL_GPL
++0x0a7ed556    blk_execute_rq  vmlinux EXPORT_SYMBOL
++0x44408a4a    mdio_bus_type   vmlinux EXPORT_SYMBOL
++0xac74a2a9    ip6_xmit        vmlinux EXPORT_SYMBOL
++0x411d75db    ip_tunnel_init  vmlinux EXPORT_SYMBOL_GPL
++0x7a442539    tcf_exts_dump   vmlinux EXPORT_SYMBOL
++0x13307fde    vsscanf vmlinux EXPORT_SYMBOL
++0xcc368515    jbd2_journal_unlock_updates     vmlinux EXPORT_SYMBOL
++0x21bfb720    seq_open_net    vmlinux EXPORT_SYMBOL_GPL
++0x82d79b51    sysctl_vfs_cache_pressure       vmlinux EXPORT_SYMBOL_GPL
++0x04486e88    rcu_batches_completed   vmlinux EXPORT_SYMBOL_GPL
++0x7c1372e8    panic   vmlinux EXPORT_SYMBOL
++0x9808f34e    dev_pm_qos_expose_flags vmlinux EXPORT_SYMBOL_GPL
++0x544b5ea8    pwm_disable     vmlinux EXPORT_SYMBOL_GPL
++0x5c265cba    sg_init_one     vmlinux EXPORT_SYMBOL
++0x12da5bb2    __kmalloc       vmlinux EXPORT_SYMBOL
++0x28d6861d    __vmalloc       vmlinux EXPORT_SYMBOL
++0x5db7b0d3    led_trigger_remove      vmlinux EXPORT_SYMBOL_GPL
++0x83b38ee6    kobject_init_and_add    vmlinux EXPORT_SYMBOL_GPL
++0x757cdadf    usbnet_get_ethernet_addr        vmlinux EXPORT_SYMBOL_GPL
++0x43a286d1    drm_prime_remove_buf_handle     vmlinux EXPORT_SYMBOL
++0xea8ddd89    __ip_select_ident       vmlinux EXPORT_SYMBOL
++0x1f984870    skb_gro_receive vmlinux EXPORT_SYMBOL_GPL
++0x48f8aa53    flock_lock_file_wait    vmlinux EXPORT_SYMBOL
++0x05e067d7    __media_entity_remove_links     vmlinux EXPORT_SYMBOL_GPL
++0xe7cb87e4    xt_find_match   vmlinux EXPORT_SYMBOL
++0x9d62c35b    nfq_ct_hook     vmlinux EXPORT_SYMBOL_GPL
++0xe12b4adb    __skb_warn_lro_forwarding       vmlinux EXPORT_SYMBOL
++0x471eeac6    snd_soc_platform_write  vmlinux EXPORT_SYMBOL_GPL
++0x71c90087    memcmp  vmlinux EXPORT_SYMBOL
++0x4881d505    idr_for_each    vmlinux EXPORT_SYMBOL
++0x79b33953    shash_ahash_digest      vmlinux EXPORT_SYMBOL_GPL
++0xcf1d92aa    locks_init_lock vmlinux EXPORT_SYMBOL
++0x11cfbadb    bio_add_pc_page vmlinux EXPORT_SYMBOL
++0x2917e251    split_page      vmlinux EXPORT_SYMBOL_GPL
++0xda53403f    v4l2_m2m_ctx_init       vmlinux EXPORT_SYMBOL_GPL
++0x4f4d910e    regmap_init     vmlinux EXPORT_SYMBOL_GPL
++0xb2a9634b    regmap_exit     vmlinux EXPORT_SYMBOL_GPL
++0xe16838c2    drm_mm_search_free_in_range_generic     vmlinux EXPORT_SYMBOL
++0xf05ffa15    fb_var_to_videomode     vmlinux EXPORT_SYMBOL
++0xab707907    inet6_del_offload       vmlinux EXPORT_SYMBOL
++0x13e229c2    nf_ct_helper_expectfn_find_by_name      vmlinux EXPORT_SYMBOL_GPL
++0x1f0547c1    netif_stacked_transfer_operstate        vmlinux EXPORT_SYMBOL
++0xd435e67a    snd_card_set_id vmlinux EXPORT_SYMBOL
++0xc7236f77    d_alloc_name    vmlinux EXPORT_SYMBOL
++0x2f3857e2    _raw_write_lock_irqsave vmlinux EXPORT_SYMBOL
++0x37c199e6    serio_reconnect vmlinux EXPORT_SYMBOL
++0x6754f715    drm_fb_helper_fill_fix  vmlinux EXPORT_SYMBOL
++0xc6df7ef6    cont_write_begin        vmlinux EXPORT_SYMBOL
++0x1c97e3ec    vfs_readdir     vmlinux EXPORT_SYMBOL
++0xbdd295f0    trace_vprintk   vmlinux EXPORT_SYMBOL_GPL
++0x8faa4598    of_translate_address    vmlinux EXPORT_SYMBOL
++0x0699040f    drm_encoder_cleanup     vmlinux EXPORT_SYMBOL
++0x7f8c7b48    dma_async_memcpy_buf_to_buf     vmlinux EXPORT_SYMBOL
++0x1ed85a8d    pinctrl_dev_get_drvdata vmlinux EXPORT_SYMBOL_GPL
++0x881039d0    zlib_inflate    vmlinux EXPORT_SYMBOL
++0x3771b461    crc_ccitt       vmlinux EXPORT_SYMBOL
++0xa43b1297    vscnprintf      vmlinux EXPORT_SYMBOL
++0x166e361d    blk_recount_segments    vmlinux EXPORT_SYMBOL
++0x887ece4a    simple_statfs   vmlinux EXPORT_SYMBOL
++0x617643a2    param_set_long  vmlinux EXPORT_SYMBOL
++0x6c69a9be    xfrm6_tunnel_deregister vmlinux EXPORT_SYMBOL
++0x3b850073    km_policy_notify        vmlinux EXPORT_SYMBOL
++0x10cc1e43    xfrm4_tunnel_deregister vmlinux EXPORT_SYMBOL
++0xc0f95b9e    ip_mc_join_group        vmlinux EXPORT_SYMBOL
++0xdb760f52    __kfifo_free    vmlinux EXPORT_SYMBOL
++0x3a288321    configfs_undepend_item  vmlinux EXPORT_SYMBOL
++0x2cc83b45    usb_string      vmlinux EXPORT_SYMBOL_GPL
++0x98442d13    inet_csk_reqsk_queue_hash_add   vmlinux EXPORT_SYMBOL_GPL
++0x8d33679f    nf_ct_unexpect_related  vmlinux EXPORT_SYMBOL_GPL
++0xe6e1c5fe    uuid_be_gen     vmlinux EXPORT_SYMBOL_GPL
++0x289ea691    debugfs_remove  vmlinux EXPORT_SYMBOL_GPL
++0xbb4e9599    lease_modify    vmlinux EXPORT_SYMBOL
++0x2fb6e20e    drop_nlink      vmlinux EXPORT_SYMBOL
++0xdfaa6b6b    v4l2_ctrl_radio_filter  vmlinux EXPORT_SYMBOL
++0xa3675712    xfrm_dst_ifdown vmlinux EXPORT_SYMBOL
++0x0d9bae4b    nf_nat_l4proto_nlattr_to_range  vmlinux EXPORT_SYMBOL_GPL
++0xc17f8f83    neigh_seq_start vmlinux EXPORT_SYMBOL
++0x6e7943ec    iommu_group_id  vmlinux EXPORT_SYMBOL_GPL
++0x1aef1e27    eth_header_cache_update vmlinux EXPORT_SYMBOL
++0xd800dc59    snd_pcm_hw_constraint_ratdens   vmlinux EXPORT_SYMBOL
++0xd1157735    release_and_free_resource       vmlinux EXPORT_SYMBOL
++0xb31526ee    sg_copy_from_buffer     vmlinux EXPORT_SYMBOL
++0x73e20c1c    strlcpy vmlinux EXPORT_SYMBOL
++0x328a05f1    strncpy vmlinux EXPORT_SYMBOL
++0x8abacc47    get_max_files   vmlinux EXPORT_SYMBOL_GPL
++0xae0f6b4e    regulator_unregister_notifier   vmlinux EXPORT_SYMBOL_GPL
++0x386f5a4e    tcf_em_tree_destroy     vmlinux EXPORT_SYMBOL
++0x97b4500c    __tracepoint_kmem_cache_free    vmlinux EXPORT_SYMBOL
++0x4a69690c    scsi_release_buffers    vmlinux EXPORT_SYMBOL
++0xf195c682    fb_invert_cmaps vmlinux EXPORT_SYMBOL
++0xab156bb5    kern_mount_data vmlinux EXPORT_SYMBOL_GPL
++0x1902f934    __init_kthread_worker   vmlinux EXPORT_SYMBOL_GPL
++0xdac0df4a    driver_create_file      vmlinux EXPORT_SYMBOL_GPL
++0x083eb21c    rfkill_unregister       vmlinux EXPORT_SYMBOL
++0x3e52c876    blk_requeue_request     vmlinux EXPORT_SYMBOL
++0xdca5d880    insert_inode_locked4    vmlinux EXPORT_SYMBOL
++0x41482d8b    strndup_user    vmlinux EXPORT_SYMBOL
++0xddd58dc0    ring_buffer_reset       vmlinux EXPORT_SYMBOL_GPL
++0x6b172795    media_entity_graph_walk_next    vmlinux EXPORT_SYMBOL_GPL
++0x0591a4d1    usb_ep_autoconfig_ss    vmlinux EXPORT_SYMBOL_GPL
++0x4b076147    uncache_firmware        vmlinux EXPORT_SYMBOL_GPL
++0x098b71c6    fb_dealloc_cmap vmlinux EXPORT_SYMBOL
++0x83d1444a    crypto_init_spawn       vmlinux EXPORT_SYMBOL_GPL
++0x60061dd7    mount_nodev     vmlinux EXPORT_SYMBOL
++0x7bb32751    pagevec_lookup  vmlinux EXPORT_SYMBOL
++0x47b6a10f    ftrace_print_symbols_seq        vmlinux EXPORT_SYMBOL
++0x8664f62e    cpufreq_update_policy   vmlinux EXPORT_SYMBOL
++0x29f39077    pwmchip_remove  vmlinux EXPORT_SYMBOL_GPL
++0x905baf48    xfrm_find_acq   vmlinux EXPORT_SYMBOL
++0x9487bc19    eth_mac_addr    vmlinux EXPORT_SYMBOL
++0xad1ed84c    unregister_hw_breakpoint        vmlinux EXPORT_SYMBOL_GPL
++0x993805c1    scsi_scan_host  vmlinux EXPORT_SYMBOL
++0x7a77dfe4    scsi_setup_fs_cmnd      vmlinux EXPORT_SYMBOL
++0xbbc9fd6e    cfg80211_wext_siwfrag   vmlinux EXPORT_SYMBOL_GPL
++0x82c82c32    cfg80211_wext_giwfrag   vmlinux EXPORT_SYMBOL_GPL
++0xe80dd06a    tcp_sendpage    vmlinux EXPORT_SYMBOL
++0x47b3f862    radix_tree_lookup_slot  vmlinux EXPORT_SYMBOL
++0x91621d6a    allocate_resource       vmlinux EXPORT_SYMBOL
++0xb98a0185    rtc_tm_to_time  vmlinux EXPORT_SYMBOL
++0xe5883bd9    class_compat_unregister vmlinux EXPORT_SYMBOL_GPL
++0x7bf9c108    serial8250_rx_dma       vmlinux EXPORT_SYMBOL_GPL
++0xc7856a3d    inet6addr_notifier_call_chain   vmlinux EXPORT_SYMBOL
++0xc08647ff    ring_buffer_bytes_cpu   vmlinux EXPORT_SYMBOL_GPL
++0xcbbf0a6f    audit_log_task_context  vmlinux EXPORT_SYMBOL
++0x0a0ab757    pm_schedule_suspend     vmlinux EXPORT_SYMBOL_GPL
++0x617ae32f    of_get_display_timings  vmlinux EXPORT_SYMBOL_GPL
++0xe442a492    splice_from_pipe_feed   vmlinux EXPORT_SYMBOL
++0xf9a054b5    __round_jiffies vmlinux EXPORT_SYMBOL_GPL
++0x38e20383    hid_alloc_report_buf    vmlinux EXPORT_SYMBOL_GPL
++0x626ffd48    spi_write_then_read     vmlinux EXPORT_SYMBOL_GPL
++0x7b5fc447    pinctrl_lookup_state    vmlinux EXPORT_SYMBOL_GPL
++0x8c49e9fe    cfg80211_conn_failed    vmlinux EXPORT_SYMBOL
++0x03c06156    bitmap_fold     vmlinux EXPORT_SYMBOL
++0x04d5a096    security_sb_clone_mnt_opts      vmlinux EXPORT_SYMBOL
++0x424b2fdf    vfs_rmdir       vmlinux EXPORT_SYMBOL
++0x52856d8e    generic_shutdown_super  vmlinux EXPORT_SYMBOL
++0xbd10541e    css_lookup      vmlinux EXPORT_SYMBOL_GPL
++0x37e74642    get_jiffies_64  vmlinux EXPORT_SYMBOL
++0xb8117014    cfg80211_rx_spurious_frame      vmlinux EXPORT_SYMBOL
++0x790c2d9c    netdev_master_upper_dev_link    vmlinux EXPORT_SYMBOL
++0x02a6ce5a    crc16_table     vmlinux EXPORT_SYMBOL
++0xe280ea92    init_buffer     vmlinux EXPORT_SYMBOL
++0xf21e1f9b    disable_percpu_irq      vmlinux EXPORT_SYMBOL_GPL
++0xb5ae5758    scsi_track_queue_full   vmlinux EXPORT_SYMBOL
++0xa26b1ba8    exynos_drm_device_register      vmlinux EXPORT_SYMBOL_GPL
++0xbe55cd3e    __sock_recv_ts_and_drops        vmlinux EXPORT_SYMBOL_GPL
++0xcedd3329    jbd2__journal_start     vmlinux EXPORT_SYMBOL
++0x838a3169    pm_qos_request_active   vmlinux EXPORT_SYMBOL_GPL
++0xbf7fd2f5    schedule_timeout_killable       vmlinux EXPORT_SYMBOL
++0xd9c4cec4    sock_no_getname vmlinux EXPORT_SYMBOL
++0x24678be3    snd_pcm_lib_readv       vmlinux EXPORT_SYMBOL
++0x292a0b74    vfs_link        vmlinux EXPORT_SYMBOL
++0x85050965    __irq_alloc_descs       vmlinux EXPORT_SYMBOL_GPL
++0xe3e7dba0    from_kuid_munged        vmlinux EXPORT_SYMBOL
++0x582bb484    call_usermodehelper_setup       vmlinux EXPORT_SYMBOL
++0xe52c5e63    v4l2_event_subscribe    vmlinux EXPORT_SYMBOL_GPL
++0xcd0fc417    drm_ht_just_insert_please       vmlinux EXPORT_SYMBOL
++0xdacbc24d    netlink_rcv_skb vmlinux EXPORT_SYMBOL
++0x33d23d14    sk_unattached_filter_create     vmlinux EXPORT_SYMBOL_GPL
++0x1f07ae8f    crypto_alloc_pcomp      vmlinux EXPORT_SYMBOL_GPL
++0x2447533c    ktime_get_real  vmlinux EXPORT_SYMBOL_GPL
++0x68869bae    panic_notifier_list     vmlinux EXPORT_SYMBOL
++0xdae1eb6a    of_clk_src_onecell_get  vmlinux EXPORT_SYMBOL_GPL
++0x3444d892    phy_driver_unregister   vmlinux EXPORT_SYMBOL
++0x107b31ec    __xfrm_state_delete     vmlinux EXPORT_SYMBOL
++0x4e6165cf    d_delete        vmlinux EXPORT_SYMBOL
++0x5f0e672b    find_get_pages_tag      vmlinux EXPORT_SYMBOL
++0xc8fd727e    mod_timer       vmlinux EXPORT_SYMBOL
++0xd2fe47b1    rndis_set_host_mac      vmlinux EXPORT_SYMBOL
++0xd768e985    regulator_has_full_constraints  vmlinux EXPORT_SYMBOL_GPL
++0x82f776b7    gpio_export     vmlinux EXPORT_SYMBOL_GPL
++0xdf401846    idr_remove      vmlinux EXPORT_SYMBOL
++0x29baff70    ida_remove      vmlinux EXPORT_SYMBOL
++0x220b4b23    mnt_set_expiry  vmlinux EXPORT_SYMBOL
++0x3dd9c200    use_mm  vmlinux EXPORT_SYMBOL_GPL
++0x2d41e6f5    __trace_puts    vmlinux EXPORT_SYMBOL_GPL
++0x5143c678    param_get_invbool       vmlinux EXPORT_SYMBOL
++0x914a1c17    ip_tunnel_newlink       vmlinux EXPORT_SYMBOL_GPL
++0xc5b6b555    genl_notify     vmlinux EXPORT_SYMBOL
++0xada52470    wm_hubs_hpl_mux vmlinux EXPORT_SYMBOL_GPL
++0x9393c812    add_page_wait_queue     vmlinux EXPORT_SYMBOL_GPL
++0xb16abad2    devm_rtc_device_register        vmlinux EXPORT_SYMBOL_GPL
++0xbd92ef65    devres_destroy  vmlinux EXPORT_SYMBOL_GPL
++0x1297fa08    tty_hangup      vmlinux EXPORT_SYMBOL
++0x580c94d2    seq_put_decimal_ll      vmlinux EXPORT_SYMBOL
++0xb22596e0    devm_rtc_device_unregister      vmlinux EXPORT_SYMBOL_GPL
++0x1b95d5c1    mdiobus_read    vmlinux EXPORT_SYMBOL
++0xea59b757    pm_runtime_forbid       vmlinux EXPORT_SYMBOL_GPL
++0x30e74134    tty_termios_copy_hw     vmlinux EXPORT_SYMBOL
++0x4455e1b3    regulator_disable_deferred      vmlinux EXPORT_SYMBOL_GPL
++0x8e322129    dma_release_channel     vmlinux EXPORT_SYMBOL_GPL
++0xcfd9a2c0    des_ekey        vmlinux EXPORT_SYMBOL_GPL
++0x66c78bd2    irq_domain_remove       vmlinux EXPORT_SYMBOL_GPL
++0x640c2da8    devm_clk_get    vmlinux EXPORT_SYMBOL
++0xd02c73c7    drm_dp_link_train_clock_recovery_delay  vmlinux EXPORT_SYMBOL
++0x2be0f12d    dql_completed   vmlinux EXPORT_SYMBOL
++0xad3f5f91    read_cache_page vmlinux EXPORT_SYMBOL
++0x4ca90996    rndis_signal_disconnect vmlinux EXPORT_SYMBOL
++0x917229dc    drm_irq_install vmlinux EXPORT_SYMBOL
++0x787bcffe    con_is_bound    vmlinux EXPORT_SYMBOL
++0xefb6eb3f    dev_change_flags        vmlinux EXPORT_SYMBOL
++0x0e352145    __skb_gso_segment       vmlinux EXPORT_SYMBOL
++0xa5d14a5e    xfrm_state_walk vmlinux EXPORT_SYMBOL
++0x6a0ae2ec    nla_put_nohdr   vmlinux EXPORT_SYMBOL
++0x0411124a    pid_nr_ns       vmlinux EXPORT_SYMBOL_GPL
++0x2133271d    phy_scan_fixups vmlinux EXPORT_SYMBOL
++0x64d233c8    ioremap_page    vmlinux EXPORT_SYMBOL
++0x8fea24bd    bt_sock_unregister      vmlinux EXPORT_SYMBOL
++0x16c3cf65    napi_gro_flush  vmlinux EXPORT_SYMBOL
++0xf001dc80    irq_domain_add_linear   vmlinux EXPORT_SYMBOL_GPL
++0xec069709    scsi_set_medium_removal vmlinux EXPORT_SYMBOL
++0xc0a98385    profile_pc      vmlinux EXPORT_SYMBOL
++0x79a2f120    snd_timer_resolution    vmlinux EXPORT_SYMBOL
++0x46c67b94    jbd2_journal_wipe       vmlinux EXPORT_SYMBOL
++0x444f1735    cpu_pm_register_notifier        vmlinux EXPORT_SYMBOL_GPL
++0xcc85fcb6    async_schedule  vmlinux EXPORT_SYMBOL_GPL
++0x9caf61d6    __nla_put       vmlinux EXPORT_SYMBOL
++0x4c2ae700    strnstr vmlinux EXPORT_SYMBOL
++0x07bf12c5    perf_pmu_migrate_context        vmlinux EXPORT_SYMBOL_GPL
++0x4268de2e    __css_put       vmlinux EXPORT_SYMBOL_GPL
++0x32fdb1ea    usb_block_urb   vmlinux EXPORT_SYMBOL_GPL
++0xd76e3ec9    fb_set_var      vmlinux EXPORT_SYMBOL
++0x7c0643d0    inet_diag_register      vmlinux EXPORT_SYMBOL_GPL
++0x598542b2    _raw_spin_lock_irqsave  vmlinux EXPORT_SYMBOL
++0xd468cd0b    sdhci_pltfm_unregister  vmlinux EXPORT_SYMBOL_GPL
++0x44f93f86    vb2_ops_wait_finish     vmlinux EXPORT_SYMBOL_GPL
++0x5be57447    dma_buf_kmap_atomic     vmlinux EXPORT_SYMBOL_GPL
++0xfac68eba    arm_elf_read_implies_exec       vmlinux EXPORT_SYMBOL
++0xca1e6f11    tcp_done        vmlinux EXPORT_SYMBOL_GPL
++0x885f07c4    snd_pcm_hw_rule_add     vmlinux EXPORT_SYMBOL
++0xb1c0c1c2    async_schedule_domain   vmlinux EXPORT_SYMBOL_GPL
++0x65497c9a    wm8994_bulk_write       vmlinux EXPORT_SYMBOL_GPL
++0x2fb6de5d    add_device_randomness   vmlinux EXPORT_SYMBOL
++0xda8af7ad    fb_find_nearest_mode    vmlinux EXPORT_SYMBOL
++0x0a575945    xfrm_count_pfkey_auth_supported vmlinux EXPORT_SYMBOL_GPL
++0x3b91f3af    snd_free_pages  vmlinux EXPORT_SYMBOL
++0xdf2278c1    snd_card_file_remove    vmlinux EXPORT_SYMBOL
++0xc848d220    blk_free_tags   vmlinux EXPORT_SYMBOL
++0xff492454    security_inode_getsecctx        vmlinux EXPORT_SYMBOL
++0xce46e140    ktime_get_ts    vmlinux EXPORT_SYMBOL_GPL
++0x3b0d157a    v4l2_m2m_ioctl_querybuf vmlinux EXPORT_SYMBOL_GPL
++0x054177ad    usb_init_urb    vmlinux EXPORT_SYMBOL_GPL
++0x1ad1f2e7    _memcpy_fromio  vmlinux EXPORT_SYMBOL
++0x95dbe078    __get_user_2    vmlinux EXPORT_SYMBOL
++0xb9acd3d9    __put_user_2    vmlinux EXPORT_SYMBOL
++0xf3797152    snd_interval_ratnum     vmlinux EXPORT_SYMBOL
++0x9d2edcd6    map_vm_area     vmlinux EXPORT_SYMBOL_GPL
++0xbfd8d187    balloon_page_enqueue    vmlinux EXPORT_SYMBOL_GPL
++0xb7e3198c    balloon_page_dequeue    vmlinux EXPORT_SYMBOL_GPL
++0x0084e86d    unregister_shrinker     vmlinux EXPORT_SYMBOL
++0x23424fab    usb_hcd_unmap_urb_setup_for_dma vmlinux EXPORT_SYMBOL_GPL
++0x6c06c6f7    scsi_device_get vmlinux EXPORT_SYMBOL
++0x970b4c98    scsi_device_put vmlinux EXPORT_SYMBOL
++0x66109b05    __pm_runtime_set_status vmlinux EXPORT_SYMBOL_GPL
++0x6d134a2a    drm_prime_sg_to_page_addr_arrays        vmlinux EXPORT_SYMBOL
++0xbce458b3    drm_framebuffer_reference       vmlinux EXPORT_SYMBOL
++0xa773e935    ipv6_dev_get_saddr      vmlinux EXPORT_SYMBOL
++0x38308727    xfrm_policy_flush       vmlinux EXPORT_SYMBOL
++0x6ebf58d8    skb_tx_error    vmlinux EXPORT_SYMBOL
++0xea793efe    snd_soc_cache_sync      vmlinux EXPORT_SYMBOL_GPL
++0xb8aa2342    __check_region  vmlinux EXPORT_SYMBOL
++0x99638333    mmc_set_blocklen        vmlinux EXPORT_SYMBOL
++0xc5e4da95    pn_sock_hash    vmlinux EXPORT_SYMBOL
++0xf6388c56    sysctl_ip_default_ttl   vmlinux EXPORT_SYMBOL
++0x0e7c2436    napi_gro_frags  vmlinux EXPORT_SYMBOL
++0x217dda13    flex_array_get  vmlinux EXPORT_SYMBOL
++0x09437748    ring_buffer_read_events_cpu     vmlinux EXPORT_SYMBOL_GPL
++0xb974ccc1    inet_diag_unregister    vmlinux EXPORT_SYMBOL_GPL
++0x0423031f    sock_sendmsg    vmlinux EXPORT_SYMBOL
++0xade88e76    snd_malloc_pages        vmlinux EXPORT_SYMBOL
++0x7ca50cfa    disk_get_part   vmlinux EXPORT_SYMBOL_GPL
++0xfed4d591    cfg80211_find_vendor_ie vmlinux EXPORT_SYMBOL
++0xe45ee6f0    netlink_kernel_release  vmlinux EXPORT_SYMBOL
++0xf310e4d9    __sock_create   vmlinux EXPORT_SYMBOL
++0x4153512b    snd_hwdep_new   vmlinux EXPORT_SYMBOL
++0x1afae5e7    down_interruptible      vmlinux EXPORT_SYMBOL
++0x2051f1d8    rtc_set_mmss    vmlinux EXPORT_SYMBOL_GPL
++0x23dfa3ab    netif_carrier_off       vmlinux EXPORT_SYMBOL
++0x10895a2a    lease_get_mtime vmlinux EXPORT_SYMBOL
++0x7cd8f487    sb_set_blocksize        vmlinux EXPORT_SYMBOL
++0x0effeb6c    srcu_barrier    vmlinux EXPORT_SYMBOL_GPL
++0xf3de55df    mmc_request_done        vmlinux EXPORT_SYMBOL
++0x46074c17    sdev_evt_alloc  vmlinux EXPORT_SYMBOL_GPL
++0x17077530    pinctrl_force_default   vmlinux EXPORT_SYMBOL_GPL
++0x0d40713a    snd_ctl_boolean_stereo_info     vmlinux EXPORT_SYMBOL
++0x3744cf36    vmalloc_to_pfn  vmlinux EXPORT_SYMBOL
++0xc783b0e1    get_task_mm     vmlinux EXPORT_SYMBOL_GPL
++0xa8950567    sdio_writew     vmlinux EXPORT_SYMBOL_GPL
++0xca443371    inet_csk_prepare_forced_close   vmlinux EXPORT_SYMBOL
++0x252f76b5    snd_soc_default_readable_register       vmlinux EXPORT_SYMBOL_GPL
++0x551bd071    __rb_erase_color        vmlinux EXPORT_SYMBOL
++0xfff8d451    fuse_request_send       vmlinux EXPORT_SYMBOL_GPL
++0x88b5647c    trace_clock_local       vmlinux EXPORT_SYMBOL_GPL
++0x683928de    nf_ct_expect_put        vmlinux EXPORT_SYMBOL_GPL
++0x7c96bf14    register_tcf_proto_ops  vmlinux EXPORT_SYMBOL
++0x76aea351    crypto_unregister_alg   vmlinux EXPORT_SYMBOL_GPL
++0x5c24f853    dump_write      vmlinux EXPORT_SYMBOL
++0x89485687    iommu_group_put vmlinux EXPORT_SYMBOL_GPL
++0x00f4d0cf    iommu_group_get vmlinux EXPORT_SYMBOL_GPL
++0xb4626765    v4l2_ctrl_new_custom    vmlinux EXPORT_SYMBOL
++0x511746c1    dump_fpu        vmlinux EXPORT_SYMBOL
++0x28927989    qdisc_watchdog_schedule_ns      vmlinux EXPORT_SYMBOL
++0x57fec35a    fuse_conn_get   vmlinux EXPORT_SYMBOL_GPL
++0xff3f1877    filp_open       vmlinux EXPORT_SYMBOL
++0x7cb7e8a5    generic_file_aio_write  vmlinux EXPORT_SYMBOL
++0x1d9317d8    smpboot_register_percpu_thread  vmlinux EXPORT_SYMBOL_GPL
++0x426362dc    __class_create  vmlinux EXPORT_SYMBOL_GPL
++0xebd6ff6e    xfrm6_prepare_output    vmlinux EXPORT_SYMBOL
++0x7c30b8c7    xfrm_calg_get_byname    vmlinux EXPORT_SYMBOL_GPL
++0xf23624a6    xfrm4_prepare_output    vmlinux EXPORT_SYMBOL
++0x6e88e56f    snd_pcm_link_rwlock     vmlinux EXPORT_SYMBOL
++0x2ebe3135    cpu_is_hotpluggable     vmlinux EXPORT_SYMBOL_GPL
++0xd3dbfbc4    _find_first_zero_bit_le vmlinux EXPORT_SYMBOL
++0x949f7fd6    snd_soc_unregister_codec        vmlinux EXPORT_SYMBOL_GPL
++0x66b5d30a    get_disk        vmlinux EXPORT_SYMBOL
++0xd5c3ad66    blk_pm_runtime_init     vmlinux EXPORT_SYMBOL
++0x55737546    __free_pages    vmlinux EXPORT_SYMBOL
++0xfa012fe7    tracepoint_probe_register       vmlinux EXPORT_SYMBOL_GPL
++0xf8802492    print_stack_trace       vmlinux EXPORT_SYMBOL_GPL
++0x50601122    of_property_match_string        vmlinux EXPORT_SYMBOL_GPL
++0x70fde9b2    vb2_reqbufs     vmlinux EXPORT_SYMBOL_GPL
++0x9b680a42    ump_dd_reference_release        vmlinux EXPORT_SYMBOL
++0x13d5d619    cfg80211_crit_proto_stopped     vmlinux EXPORT_SYMBOL
++0xd5a7d477    inet_bind       vmlinux EXPORT_SYMBOL
++0xc5495840    nf_nat_amanda_hook      vmlinux EXPORT_SYMBOL_GPL
++0xe08e58c9    qdisc_watchdog_init     vmlinux EXPORT_SYMBOL
++0xe447fb89    __register_binfmt       vmlinux EXPORT_SYMBOL
++0xbd3321ae    power_supply_class      vmlinux EXPORT_SYMBOL_GPL
++0x0ce6d0b9    usb_gadget_probe_driver vmlinux EXPORT_SYMBOL_GPL
++0xae544f3a    usb_hcd_end_port_resume vmlinux EXPORT_SYMBOL_GPL
++0x8fd8a453    pm_genpd_dev_need_restore       vmlinux EXPORT_SYMBOL_GPL
++0x7b95ab7d    class_find_device       vmlinux EXPORT_SYMBOL_GPL
++0x21455002    xfrm_init_state vmlinux EXPORT_SYMBOL
++0xf06e724d    snd_pcm_debug_name      vmlinux EXPORT_SYMBOL
++0x89ca47bf    kstrtos8_from_user      vmlinux EXPORT_SYMBOL
++0x68d0d389    crypto_init_spawn2      vmlinux EXPORT_SYMBOL_GPL
++0x01c6cb0c    cpu_cluster_pm_enter    vmlinux EXPORT_SYMBOL_GPL
++0xd1efa60f    st_accel_common_remove  vmlinux EXPORT_SYMBOL
++0xf398c9eb    vb2_create_bufs vmlinux EXPORT_SYMBOL_GPL
++0xc385cb58    perf_num_counters       vmlinux EXPORT_SYMBOL_GPL
++0x87634adf    xfrm_user_policy        vmlinux EXPORT_SYMBOL
++0xe0741a0a    netif_napi_add  vmlinux EXPORT_SYMBOL
++0xf12cddd6    skb_split       vmlinux EXPORT_SYMBOL
++0xdee12a28    input_grab_device       vmlinux EXPORT_SYMBOL
++0x95e73973    tty_port_block_til_ready        vmlinux EXPORT_SYMBOL
++0x53a3e486    regulator_get_current_limit     vmlinux EXPORT_SYMBOL_GPL
++0x5dd18380    regulator_get_init_drvdata      vmlinux EXPORT_SYMBOL_GPL
++0x8467a73f    netlink_broadcast       vmlinux EXPORT_SYMBOL
++0x6d1a8997    block_write_full_page_endio     vmlinux EXPORT_SYMBOL
++0x197519cc    shmem_file_setup        vmlinux EXPORT_SYMBOL_GPL
++0x8b8059bd    in_group_p      vmlinux EXPORT_SYMBOL
++0xc631580a    console_unlock  vmlinux EXPORT_SYMBOL
++0xe8400441    of_property_read_string_index   vmlinux EXPORT_SYMBOL_GPL
++0x0343bdf1    __i2c_board_list        vmlinux EXPORT_SYMBOL_GPL
++0xa5dd6fae    arm_pm_restart  vmlinux EXPORT_SYMBOL_GPL
++0x97fe8a2d    udp_sendmsg     vmlinux EXPORT_SYMBOL
++0x35fbd6a1    __kfifo_dma_out_prepare_r       vmlinux EXPORT_SYMBOL
++0xa3e220e7    elv_rb_former_request   vmlinux EXPORT_SYMBOL
++0xdf76bbeb    iio_pollfunc_store_time vmlinux EXPORT_SYMBOL
++0xfc30d3a1    mmc_start_req   vmlinux EXPORT_SYMBOL
++0xf53d4c26    qdisc_class_hash_destroy        vmlinux EXPORT_SYMBOL
++0x5e61da38    snd_timer_stop  vmlinux EXPORT_SYMBOL
++0xa6e1a69d    kick_all_cpus_sync      vmlinux EXPORT_SYMBOL_GPL
++0x68cb9861    sdio_register_driver    vmlinux EXPORT_SYMBOL_GPL
++0xb575c1a1    usb_kill_urb    vmlinux EXPORT_SYMBOL_GPL
++0x8ab265d2    usb_get_intf    vmlinux EXPORT_SYMBOL_GPL
++0xdbd7794d    cfg80211_ready_on_channel       vmlinux EXPORT_SYMBOL
++0xff112bd5    proc_get_parent_data    vmlinux EXPORT_SYMBOL_GPL
++0x0bec8a3d    audit_log       vmlinux EXPORT_SYMBOL
++0x5d9521f8    set_security_override_from_ctx  vmlinux EXPORT_SYMBOL
++0x235d1d10    drm_gem_prime_import    vmlinux EXPORT_SYMBOL
++0x7da24ff0    drm_helper_encoder_in_use       vmlinux EXPORT_SYMBOL
++0x6f3c606d    nfc_hci_register_device vmlinux EXPORT_SYMBOL
++0xf447e205    ip_tunnel_uninit        vmlinux EXPORT_SYMBOL_GPL
++0x5055493c    sk_wait_data    vmlinux EXPORT_SYMBOL
++0xb1b87423    crypto_remove_spawns    vmlinux EXPORT_SYMBOL_GPL
++0x4fd4e89d    ring_buffer_empty_cpu   vmlinux EXPORT_SYMBOL_GPL
++0xaa4704e1    usb_autopm_put_interface_no_suspend     vmlinux EXPORT_SYMBOL_GPL
++0x50e28c07    drm_edid_to_sad vmlinux EXPORT_SYMBOL
++0x6d57e7f8    drm_edid_to_eld vmlinux EXPORT_SYMBOL
++0x3fe12ddc    xt_replace_table        vmlinux EXPORT_SYMBOL_GPL
++0x9c3737fc    __percpu_counter_init   vmlinux EXPORT_SYMBOL
++0xf846506f    irq_set_affinity_notifier       vmlinux EXPORT_SYMBOL_GPL
++0x469a0b25    inet_hashinfo_init      vmlinux EXPORT_SYMBOL_GPL
++0x3fbf68bd    ipv4_sk_redirect        vmlinux EXPORT_SYMBOL_GPL
++0x151bc10b    end_buffer_read_sync    vmlinux EXPORT_SYMBOL
++0xb013af25    set_cpus_allowed_ptr    vmlinux EXPORT_SYMBOL_GPL
++0x227badd6    mod_timer_pinned        vmlinux EXPORT_SYMBOL
++0xf37cfbf5    dm_dispatch_request     vmlinux EXPORT_SYMBOL_GPL
++0x1d96bf04    input_mt_report_pointer_emulation       vmlinux EXPORT_SYMBOL
++0x94289922    mali_pmu_powerdown      vmlinux EXPORT_SYMBOL
++0xe9d6e0bd    pwm_request     vmlinux EXPORT_SYMBOL_GPL
++0xd66a2750    tcf_em_tree_dump        vmlinux EXPORT_SYMBOL
++0x790c22d3    neigh_for_each  vmlinux EXPORT_SYMBOL
++0x3ed096c1    sg_miter_next   vmlinux EXPORT_SYMBOL
++0x96b878b6    crypto_init_shash_spawn vmlinux EXPORT_SYMBOL_GPL
++0x1fd19684    crypto_init_ahash_spawn vmlinux EXPORT_SYMBOL_GPL
++0xedc85914    posix_timers_register_clock     vmlinux EXPORT_SYMBOL_GPL
++0xc702156b    param_get_ushort        vmlinux EXPORT_SYMBOL
++0x65bca4ff    vb2_plane_cookie        vmlinux EXPORT_SYMBOL_GPL
++0x294a6993    rtc_initialize_alarm    vmlinux EXPORT_SYMBOL_GPL
++0x6971447a    rtc_month_days  vmlinux EXPORT_SYMBOL
++0x7e64181d    usb_calc_bus_time       vmlinux EXPORT_SYMBOL_GPL
++0x5f1f36bc    drm_calc_vbltimestamp_from_scanoutpos   vmlinux EXPORT_SYMBOL
++0xe0af2dc1    regulator_is_enabled_regmap     vmlinux EXPORT_SYMBOL_GPL
++0x57c3621e    skb_pull        vmlinux EXPORT_SYMBOL
++0xeb0a7f4c    clk_register    vmlinux EXPORT_SYMBOL_GPL
++0xabc6dd63    cpufreq_sysfs_create_file       vmlinux EXPORT_SYMBOL
++0x1eee0a80    usb_find_interface      vmlinux EXPORT_SYMBOL_GPL
++0xb524d8dc    amba_find_device        vmlinux EXPORT_SYMBOL
++0x8574ca6c    gpio_request_array      vmlinux EXPORT_SYMBOL_GPL
++0x93d2422d    snmp_mib_free   vmlinux EXPORT_SYMBOL_GPL
++0x5d51bcf7    scatterwalk_start       vmlinux EXPORT_SYMBOL_GPL
++0x417e3755    sysfs_put       vmlinux EXPORT_SYMBOL_GPL
++0x2ba54bff    irq_remove_generic_chip vmlinux EXPORT_SYMBOL_GPL
++0x420c729a    vb2_fop_poll    vmlinux EXPORT_SYMBOL_GPL
++0xe6d23987    phy_start_interrupts    vmlinux EXPORT_SYMBOL
++0x1fb1615f    spi_master_resume       vmlinux EXPORT_SYMBOL_GPL
++0xcd721bb7    scsi_get_vpd_page       vmlinux EXPORT_SYMBOL_GPL
++0xac2bd611    pm_generic_restore_noirq        vmlinux EXPORT_SYMBOL_GPL
++0xe0b7aa47    drm_i2c_encoder_dpms    vmlinux EXPORT_SYMBOL
++0x9dfdf722    gpio_free_array vmlinux EXPORT_SYMBOL_GPL
++0x7345660c    xfrm_state_check_expire vmlinux EXPORT_SYMBOL
++0xd5dba10e    sock_diag_unregister_inet_compat        vmlinux EXPORT_SYMBOL_GPL
++0xfd719be0    netdev_boot_setup_check vmlinux EXPORT_SYMBOL
++0xa9c6e543    sock_i_uid      vmlinux EXPORT_SYMBOL
++0x2dfe841c    sock_i_ino      vmlinux EXPORT_SYMBOL
++0x4bc2dc22    seq_bitmap      vmlinux EXPORT_SYMBOL
++0x4b8e839a    cpufreq_global_kobject  vmlinux EXPORT_SYMBOL
++0xc12cf8f8    v4l2_ctrl_replace       vmlinux EXPORT_SYMBOL
++0xf3dd036d    regulator_set_voltage_time      vmlinux EXPORT_SYMBOL_GPL
++0x88826167    ip_build_and_send_pkt   vmlinux EXPORT_SYMBOL_GPL
++0xd09ce8d0    register_gifconf        vmlinux EXPORT_SYMBOL
++0xaa6901ac    __kfifo_out_r   vmlinux EXPORT_SYMBOL
++0x64f7667b    crypto_rng_type vmlinux EXPORT_SYMBOL_GPL
++0x457594fa    crypto_alg_list vmlinux EXPORT_SYMBOL_GPL
++0x665b8183    sync_inode_metadata     vmlinux EXPORT_SYMBOL
++0x03026722    mempool_alloc   vmlinux EXPORT_SYMBOL
++0x0034f927    unregister_wide_hw_breakpoint   vmlinux EXPORT_SYMBOL_GPL
++0x86f6b99d    synchronize_rcu_expedited       vmlinux EXPORT_SYMBOL_GPL
++0xec4d9e3a    clk_get_sys     vmlinux EXPORT_SYMBOL
++0x1b6b3f33    cpufreq_unregister_driver       vmlinux EXPORT_SYMBOL_GPL
++0x56ca80ea    drm_mode_validate_clocks        vmlinux EXPORT_SYMBOL
++0xa66a1f63    drm_rmmap_locked        vmlinux EXPORT_SYMBOL
++0x6b07a31b    regulator_get_voltage_sel_regmap        vmlinux EXPORT_SYMBOL_GPL
++0x5107f9ce    gpiochip_find   vmlinux EXPORT_SYMBOL_GPL
++0x05365f80    cfg80211_cac_event      vmlinux EXPORT_SYMBOL
++0xc05ac2c8    cfg80211_classify8021d  vmlinux EXPORT_SYMBOL
++0x92be9264    snd_soc_register_platform       vmlinux EXPORT_SYMBOL_GPL
++0xfaf79bc2    __srcu_read_lock        vmlinux EXPORT_SYMBOL_GPL
++0xada5e980    media_entity_pipeline_start     vmlinux EXPORT_SYMBOL_GPL
++0x74fbf451    drm_mm_init_scan_with_range     vmlinux EXPORT_SYMBOL
++0xd03c7700    secure_ipv4_port_ephemeral      vmlinux EXPORT_SYMBOL_GPL
++0x9c9ec2a0    proc_dointvec_minmax    vmlinux EXPORT_SYMBOL
++0x8d772b8c    v4l2_clk_get    vmlinux EXPORT_SYMBOL
++0x32680bfc    usb_function_unregister vmlinux EXPORT_SYMBOL_GPL
++0x6dd8ac23    dev_uc_add_excl vmlinux EXPORT_SYMBOL
++0xced0fa87    dev_mc_add_excl vmlinux EXPORT_SYMBOL
++0x51cc09c6    kmalloc_caches  vmlinux EXPORT_SYMBOL
++0x3ef23944    i2c_bus_type    vmlinux EXPORT_SYMBOL_GPL
++0x015f6d7d    kmap    vmlinux EXPORT_SYMBOL
++0x0b9a5c65    icmpv6_send     vmlinux EXPORT_SYMBOL
++0x6625c30d    blk_queue_make_request  vmlinux EXPORT_SYMBOL
++0x25dd3b83    sysfs_add_link_to_group vmlinux EXPORT_SYMBOL_GPL
++0x472d363a    truncate_pagecache_range        vmlinux EXPORT_SYMBOL
++0x0bf3e830    put_page        vmlinux EXPORT_SYMBOL
++0x74954462    timecounter_read        vmlinux EXPORT_SYMBOL_GPL
++0x3aa9f288    iio_channel_get vmlinux EXPORT_SYMBOL_GPL
++0x1fd6672b    video_device_release_empty      vmlinux EXPORT_SYMBOL
++0x931dcc9d    usbnet_pause_rx vmlinux EXPORT_SYMBOL_GPL
++0x4c83a264    do_take_over_console    vmlinux EXPORT_SYMBOL_GPL
++0xe2dd67e5    regulator_set_current_limit     vmlinux EXPORT_SYMBOL_GPL
++0xb23f3373    nf_conntrack_lock       vmlinux EXPORT_SYMBOL_GPL
++0xebfa66fa    security_inode_setsecctx        vmlinux EXPORT_SYMBOL
++0x819ed3be    vfs_getattr     vmlinux EXPORT_SYMBOL
++0x2fad0dbe    led_classdev_resume     vmlinux EXPORT_SYMBOL_GPL
++0xbc497919    rtc_device_register     vmlinux EXPORT_SYMBOL_GPL
++0xd58c665a    input_reset_device      vmlinux EXPORT_SYMBOL
++0x34c728d0    tty_ldisc_deref vmlinux EXPORT_SYMBOL_GPL
++0xfb28827b    inet_del_protocol       vmlinux EXPORT_SYMBOL
++0x95587915    neigh_update    vmlinux EXPORT_SYMBOL
++0xc9b8c308    __kfifo_dma_out_prepare vmlinux EXPORT_SYMBOL
++0xd9b9b70a    put_io_context  vmlinux EXPORT_SYMBOL
++0xac7726b4    blk_queue_io_min        vmlinux EXPORT_SYMBOL
++0xcf807506    nobh_truncate_page      vmlinux EXPORT_SYMBOL
++0x43ec231b    iio_device_free vmlinux EXPORT_SYMBOL
++0x95ae5064    phy_stop        vmlinux EXPORT_SYMBOL
++0xb69d1c51    spi_bitbang_start       vmlinux EXPORT_SYMBOL_GPL
++0x87876bed    drm_kms_helper_poll_enable      vmlinux EXPORT_SYMBOL
++0x045072cd    nf_ct_port_nla_policy   vmlinux EXPORT_SYMBOL_GPL
++0x4be7fb63    up      vmlinux EXPORT_SYMBOL
++0xf8a32b55    icmp_send       vmlinux EXPORT_SYMBOL
++0x69f7d81d    path_get        vmlinux EXPORT_SYMBOL
++0xd715763b    iov_iter_copy_from_user_atomic  vmlinux EXPORT_SYMBOL
++0xc7b9fe08    drm_property_create_bitmask     vmlinux EXPORT_SYMBOL
++0x671a649b    xfrm_state_update       vmlinux EXPORT_SYMBOL
++0xce3c5240    crypto_grab_aead        vmlinux EXPORT_SYMBOL_GPL
++0xb590822d    hrtimer_start   vmlinux EXPORT_SYMBOL_GPL
++0xaebe783e    get_pid_task    vmlinux EXPORT_SYMBOL_GPL
++0xa8bcfa1a    usb_deregister_dev      vmlinux EXPORT_SYMBOL_GPL
++0xc398c5f3    usb_hcd_is_primary_hcd  vmlinux EXPORT_SYMBOL_GPL
++0x7c45fec1    pm_generic_resume_noirq vmlinux EXPORT_SYMBOL_GPL
++0x6c702af7    sysctl_udp_rmem_min     vmlinux EXPORT_SYMBOL
++0x9b3122cd    dev_open        vmlinux EXPORT_SYMBOL
++0x7ee7a9f8    lock_sock_fast  vmlinux EXPORT_SYMBOL
++0xc3b7e3fb    snd_cards       vmlinux EXPORT_SYMBOL
++0x82bbf933    ilookup vmlinux EXPORT_SYMBOL
++0x4302d0eb    free_pages      vmlinux EXPORT_SYMBOL
++0xefc91531    irq_create_of_mapping   vmlinux EXPORT_SYMBOL_GPL
++0xb90f9844    sdhci_resume_host       vmlinux EXPORT_SYMBOL_GPL
++0x8ec22c0b    nat_q931_hook   vmlinux EXPORT_SYMBOL_GPL
++0x03592ea0    security_unix_stream_connect    vmlinux EXPORT_SYMBOL
++0x4397c48f    generic_file_fsync      vmlinux EXPORT_SYMBOL
++0x5154c361    unlock_new_inode        vmlinux EXPORT_SYMBOL
++0xa9b83487    __f_setown      vmlinux EXPORT_SYMBOL
++0x9ccb1788    irq_create_direct_mapping       vmlinux EXPORT_SYMBOL_GPL
++0xf82f16b3    execute_in_process_context      vmlinux EXPORT_SYMBOL_GPL
++0xcd06de19    mdiobus_free    vmlinux EXPORT_SYMBOL
++0xfd99623a    ip_frag_ecn_table       vmlinux EXPORT_SYMBOL
++0x17ee142e    xt_find_table_lock      vmlinux EXPORT_SYMBOL_GPL
++0x62737e1d    sock_unregister vmlinux EXPORT_SYMBOL
++0x67095031    kset_register   vmlinux EXPORT_SYMBOL
++0x84ffea8b    idr_preload     vmlinux EXPORT_SYMBOL
++0xd29fb507    fput    vmlinux EXPORT_SYMBOL
++0xe3d6f284    fb_find_mode_cvt        vmlinux EXPORT_SYMBOL
++0x14d4a9c5    _change_bit     vmlinux EXPORT_SYMBOL
++0x54411a42    posix_timer_event       vmlinux EXPORT_SYMBOL_GPL
++0x2a79ac13    clkdev_add      vmlinux EXPORT_SYMBOL
++0x3d6f446b    platform_device_alloc   vmlinux EXPORT_SYMBOL_GPL
++0xf85bebf9    dev_printk_emit vmlinux EXPORT_SYMBOL
++0xde36a037    ip6_frag_init   vmlinux EXPORT_SYMBOL
++0x31e23d78    __fsnotify_parent       vmlinux EXPORT_SYMBOL_GPL
++0xdea4fcaa    pm_qos_add_request      vmlinux EXPORT_SYMBOL_GPL
++0x1976aa06    param_ops_bool  vmlinux EXPORT_SYMBOL
++0x98ba0e88    pm_generic_suspend_noirq        vmlinux EXPORT_SYMBOL_GPL
++0xecefd1b6    display_entity_get_params       vmlinux EXPORT_SYMBOL_GPL
++0xdfb5c1e5    add_disk        vmlinux EXPORT_SYMBOL
++0x5754706e    media_entity_get        vmlinux EXPORT_SYMBOL_GPL
++0xbd008b38    media_entity_put        vmlinux EXPORT_SYMBOL_GPL
++0x5d1e2494    usb_ep0_reinit  vmlinux EXPORT_SYMBOL_GPL
++0x0ae4b94c    drm_ht_remove   vmlinux EXPORT_SYMBOL
++0x6ab922b2    regulator_get_drvdata   vmlinux EXPORT_SYMBOL_GPL
++0x4432d365    __udp6_lib_lookup       vmlinux EXPORT_SYMBOL_GPL
++0x08696053    inet_shutdown   vmlinux EXPORT_SYMBOL
++0x52212010    __tracepoint_block_bio_remap    vmlinux EXPORT_SYMBOL_GPL
++0xc29afc9a    posix_lock_file_wait    vmlinux EXPORT_SYMBOL
++0x01fd453e    usbhid_lookup_quirk     vmlinux EXPORT_SYMBOL_GPL
++0x90705b7f    syscon_node_to_regmap   vmlinux EXPORT_SYMBOL_GPL
++0xf72d56a2    regulator_set_voltage_sel_regmap        vmlinux EXPORT_SYMBOL_GPL
++0xa308e150    nfc_hci_disconnect_gate vmlinux EXPORT_SYMBOL
++0x7707c1b0    xt_unregister_table     vmlinux EXPORT_SYMBOL_GPL
++0x4e830a3e    strnicmp        vmlinux EXPORT_SYMBOL
++0x48f2cf7c    vmalloc_to_page vmlinux EXPORT_SYMBOL
++0x3dca446d    drm_handle_vblank       vmlinux EXPORT_SYMBOL
++0x22ca070b    uart_remove_one_port    vmlinux EXPORT_SYMBOL
++0x1d027e4b    snd_pcm_format_signed   vmlinux EXPORT_SYMBOL
++0x3535ae4a    blk_update_request      vmlinux EXPORT_SYMBOL_GPL
++0x02649054    security_sock_rcv_skb   vmlinux EXPORT_SYMBOL
++0x547077ec    __wake_up_bit   vmlinux EXPORT_SYMBOL
++0x1c5541bd    cpufreq_boost_enabled   vmlinux EXPORT_SYMBOL_GPL
++0x6d186427    usb_get_hcd     vmlinux EXPORT_SYMBOL_GPL
++0x8eff9111    drm_ht_find_item        vmlinux EXPORT_SYMBOL
++0xd9d18f03    fbcon_set_bitops        vmlinux EXPORT_SYMBOL
++0xfaea036f    sock_release    vmlinux EXPORT_SYMBOL
++0xa414882d    add_wait_queue_exclusive        vmlinux EXPORT_SYMBOL
++0x06e80ae6    s3c_adc_register        vmlinux EXPORT_SYMBOL_GPL
++0x63805ac9    usb_hcd_giveback_urb    vmlinux EXPORT_SYMBOL_GPL
++0xf8d54998    ump_dd_handle_create_from_phys_blocks   vmlinux EXPORT_SYMBOL
++0x44242685    drm_prime_gem_destroy   vmlinux EXPORT_SYMBOL
++0x4faff87a    drm_i2c_encoder_mode_fixup      vmlinux EXPORT_SYMBOL
++0x0f995f4e    tty_port_tty_wakeup     vmlinux EXPORT_SYMBOL_GPL
++0x91b2790d    regulator_map_voltage_ascend    vmlinux EXPORT_SYMBOL_GPL
++0x0e29d022    nf_nat_icmp_reply_translation   vmlinux EXPORT_SYMBOL_GPL
++0x75811312    crc_ccitt_table vmlinux EXPORT_SYMBOL
++0xe9eb0c04    d_add_ci        vmlinux EXPORT_SYMBOL
++0x4c55b4df    led_trigger_rename_static       vmlinux EXPORT_SYMBOL_GPL
++0x6f344bb9    v4l2_calc_aspect_ratio  vmlinux EXPORT_SYMBOL_GPL
++0xc4f83bea    drm_debugfs_create_files        vmlinux EXPORT_SYMBOL
++0x9ae51e43    tty_register_device_attr        vmlinux EXPORT_SYMBOL_GPL
++0x80c70b19    phys_mem_access_prot    vmlinux EXPORT_SYMBOL
++0x17770200    __skb_checksum_complete_head    vmlinux EXPORT_SYMBOL
++0x1eeb848e    __percpu_counter_sum    vmlinux EXPORT_SYMBOL
++0xd74289f9    __percpu_counter_add    vmlinux EXPORT_SYMBOL
++0xa77a369d    idr_init        vmlinux EXPORT_SYMBOL
++0x8e5c580a    ida_init        vmlinux EXPORT_SYMBOL
++0xb99d677c    mpage_readpage  vmlinux EXPORT_SYMBOL
++0x70bc17d7    inode_wait      vmlinux EXPORT_SYMBOL
++0xd6ee688f    vmalloc vmlinux EXPORT_SYMBOL
++0xf31b3fd1    workqueue_set_max_active        vmlinux EXPORT_SYMBOL_GPL
++0x9745c52a    of_fixed_clk_setup      vmlinux EXPORT_SYMBOL_GPL
++0xbfd6a20b    phy_ethtool_set_wol     vmlinux EXPORT_SYMBOL
++0x64004900    phy_ethtool_get_wol     vmlinux EXPORT_SYMBOL
++0x28492539    spi_bitbang_transfer    vmlinux EXPORT_SYMBOL_GPL
++0x6552f2d8    unlink_framebuffer      vmlinux EXPORT_SYMBOL
++0xbdf2580d    __raw_readsl    vmlinux EXPORT_SYMBOL
++0xabe519d2    blk_queue_io_opt        vmlinux EXPORT_SYMBOL
++0x05b2af42    bdgrab  vmlinux EXPORT_SYMBOL
++0xd4c14632    system_unbound_wq       vmlinux EXPORT_SYMBOL_GPL
++0x098859e1    usbnet_cdc_status       vmlinux EXPORT_SYMBOL_GPL
++0xd1bd52ba    tty_port_raise_dtr_rts  vmlinux EXPORT_SYMBOL
++0x4ea1f5a2    drm_gem_object_free     vmlinux EXPORT_SYMBOL
++0x86d53c76    mb_cache_entry_find_first       vmlinux EXPORT_SYMBOL
++0xf0b9f940    usb_function_activate   vmlinux EXPORT_SYMBOL_GPL
++0x9d2ee507    scsi_adjust_queue_depth vmlinux EXPORT_SYMBOL
++0x4bca6b0c    drm_get_edid    vmlinux EXPORT_SYMBOL
++0x4a5d2ace    tcp_unregister_congestion_control       vmlinux EXPORT_SYMBOL_GPL
++0x0274dc2b    netif_get_num_default_rss_queues        vmlinux EXPORT_SYMBOL
++0x53be6f80    bio_split       vmlinux EXPORT_SYMBOL
++0x1fc0da41    lock_rename     vmlinux EXPORT_SYMBOL
++0xbe421975    __locks_copy_lock       vmlinux EXPORT_SYMBOL
++0x69e3cb9f    mutex_lock_killable     vmlinux EXPORT_SYMBOL
++0x9c612795    v4l2_chip_match_i2c_client      vmlinux EXPORT_SYMBOL
++0xd2f84424    i2c_bit_add_bus vmlinux EXPORT_SYMBOL
++0x421cdcbd    usb_function_deactivate vmlinux EXPORT_SYMBOL_GPL
++0x63a86872    class_destroy   vmlinux EXPORT_SYMBOL_GPL
++0x231d4001    fb_edid_add_monspecs    vmlinux EXPORT_SYMBOL
++0xb01a37d3    gpiochip_remove vmlinux EXPORT_SYMBOL_GPL
++0xcc2b7257    tcp_check_req   vmlinux EXPORT_SYMBOL
++0x16270acd    tcp_init_sock   vmlinux EXPORT_SYMBOL
++0x143dc3b0    netlink_unicast vmlinux EXPORT_SYMBOL
++0x8452993c    neigh_sysctl_register   vmlinux EXPORT_SYMBOL
++0xce602df6    cgroup_is_descendant    vmlinux EXPORT_SYMBOL_GPL
++0xdddba0ab    exynos_g2d_get_ver_ioctl        vmlinux EXPORT_SYMBOL_GPL
++0xf2c642ed    tty_port_tty_hangup     vmlinux EXPORT_SYMBOL_GPL
++0x7d086e6f    snd_soc_put_volsw_range vmlinux EXPORT_SYMBOL_GPL
++0xaf23bb74    snd_soc_get_volsw_range vmlinux EXPORT_SYMBOL_GPL
++0x01b2facc    snd_timer_start vmlinux EXPORT_SYMBOL
++0x1e693956    set_nlink       vmlinux EXPORT_SYMBOL
++0xdcb0349b    sys_close       vmlinux EXPORT_SYMBOL
++0xaf348da7    cpu_pm_exit     vmlinux EXPORT_SYMBOL_GPL
++0x77d1afb4    kill_pgrp       vmlinux EXPORT_SYMBOL
++0x3b9d009a    drm_format_plane_cpp    vmlinux EXPORT_SYMBOL
++0x2acd3e60    fat_build_inode vmlinux EXPORT_SYMBOL_GPL
++0x0f3ef271    seq_read        vmlinux EXPORT_SYMBOL
++0x712fb5a8    is_bad_inode    vmlinux EXPORT_SYMBOL
++0x253bdb78    param_get_int   vmlinux EXPORT_SYMBOL
++0xd35fa891    st_sensors_write_event_config   vmlinux EXPORT_SYMBOL
++0x203bef91    device_wakeup_disable   vmlinux EXPORT_SYMBOL_GPL
++0xd454eabb    tcf_hash_new_index      vmlinux EXPORT_SYMBOL
++0x235e7e6a    shash_ahash_finup       vmlinux EXPORT_SYMBOL_GPL
++0x60384c87    start_tty       vmlinux EXPORT_SYMBOL
++0x6513a3fa    fb_get_color_depth      vmlinux EXPORT_SYMBOL
++0x7ffc8718    gpio_set_debounce       vmlinux EXPORT_SYMBOL_GPL
++0x6c95cbd5    phonet_proto_register   vmlinux EXPORT_SYMBOL
++0xa01cac38    nf_ct_get_tuplepr       vmlinux EXPORT_SYMBOL_GPL
++0x3e872db6    __netdev_pick_tx        vmlinux EXPORT_SYMBOL
++0x981f509d    skb_free_datagram_locked        vmlinux EXPORT_SYMBOL
++0x93e0379d    kernel_sock_shutdown    vmlinux EXPORT_SYMBOL
++0x878eae99    snd_pcm_add_chmap_ctls  vmlinux EXPORT_SYMBOL_GPL
++0xd454865d    snd_pcm_notify  vmlinux EXPORT_SYMBOL
++0xa735db59    prandom_u32     vmlinux EXPORT_SYMBOL
++0x8e864a86    posix_acl_chmod vmlinux EXPORT_SYMBOL
++0xf9910a86    notify_change   vmlinux EXPORT_SYMBOL
++0x423b589c    follow_up       vmlinux EXPORT_SYMBOL
++0xa577a850    param_get_short vmlinux EXPORT_SYMBOL
++0x24b55d2b    of_find_i2c_adapter_by_node     vmlinux EXPORT_SYMBOL
++0x6d0f1f89    dm_table_get_mode       vmlinux EXPORT_SYMBOL
++0x2ca4ebcd    regulator_set_drvdata   vmlinux EXPORT_SYMBOL_GPL
++0x02196324    __aeabi_idiv    vmlinux EXPORT_SYMBOL
++0xf0e3bec8    nf_log_bind_pf  vmlinux EXPORT_SYMBOL
++0xd12698d0    skb_copy_and_csum_datagram_iovec        vmlinux EXPORT_SYMBOL
++0xd23bebab    sock_no_ioctl   vmlinux EXPORT_SYMBOL
++0xf401a5f4    get_user_pages_fast     vmlinux EXPORT_SYMBOL_GPL
++0xca85d8cf    tracepoint_probe_update_all     vmlinux EXPORT_SYMBOL_GPL
++0x54740eb7    get_cpu_idle_time       vmlinux EXPORT_SYMBOL_GPL
++0x2a3aa678    _test_and_clear_bit     vmlinux EXPORT_SYMBOL
++0x694967d9    nf_conntrack_find_get   vmlinux EXPORT_SYMBOL_GPL
++0x19a2badf    snd_soc_codec_set_sysclk        vmlinux EXPORT_SYMBOL_GPL
++0x93a2419d    simple_empty    vmlinux EXPORT_SYMBOL
++0x68a13545    vm_mmap vmlinux EXPORT_SYMBOL
++0x224190b8    shmem_read_mapping_page_gfp     vmlinux EXPORT_SYMBOL_GPL
++0xd859f1d5    dw_mci_pltfm_register   vmlinux EXPORT_SYMBOL_GPL
++0xc955c267    serio_unregister_child_port     vmlinux EXPORT_SYMBOL
++0xcbee09f7    scsi_remove_device      vmlinux EXPORT_SYMBOL
++0xcd579f54    xfrm_cfg_mutex  vmlinux EXPORT_SYMBOL
++0xb63be252    __sk_mem_schedule       vmlinux EXPORT_SYMBOL
++0xcde172ac    radix_tree_gang_lookup_tag_slot vmlinux EXPORT_SYMBOL
++0x61860fe5    blk_queue_merge_bvec    vmlinux EXPORT_SYMBOL
++0xd223c00d    fuse_file_poll  vmlinux EXPORT_SYMBOL_GPL
++0x4b6e004b    mnt_want_write_file     vmlinux EXPORT_SYMBOL_GPL
++0x11ad8ba6    __hid_register_driver   vmlinux EXPORT_SYMBOL_GPL
++0x3d8ed8f5    hid_disconnect  vmlinux EXPORT_SYMBOL_GPL
++0x70cf032f    usb_hcd_irq     vmlinux EXPORT_SYMBOL_GPL
++0xc0a9a9a1    hci_register_cb vmlinux EXPORT_SYMBOL
++0x83b21051    ip_ct_attach    vmlinux EXPORT_SYMBOL
++0x24eb8d39    dev_set_mtu     vmlinux EXPORT_SYMBOL
++0xbd5c42d9    crypto_unregister_template      vmlinux EXPORT_SYMBOL_GPL
++0x2deda4a1    security_sk_classify_flow       vmlinux EXPORT_SYMBOL
++0xe694a9ce    bd_link_disk_holder     vmlinux EXPORT_SYMBOL_GPL
++0xf1a33551    usb_string_ids_tab      vmlinux EXPORT_SYMBOL_GPL
++0x565b6892    uuid_le_gen     vmlinux EXPORT_SYMBOL_GPL
++0x68956406    static_key_slow_dec     vmlinux EXPORT_SYMBOL_GPL
++0x335c570f    enable_percpu_irq       vmlinux EXPORT_SYMBOL_GPL
++0x02e1a3ed    should_remove_suid      vmlinux EXPORT_SYMBOL
++0x0626da5f    od_unregister_powersave_bias_handler    vmlinux EXPORT_SYMBOL_GPL
++0x4dcfd46b    scsi_free_host_dev      vmlinux EXPORT_SYMBOL
++0xfec445a3    driver_register vmlinux EXPORT_SYMBOL_GPL
++0x3d1b2e32    find_lock_page  vmlinux EXPORT_SYMBOL
++0x92ea202d    srcu_notifier_chain_unregister  vmlinux EXPORT_SYMBOL_GPL
++0xdb9d11d6    iio_buffer_store_enable vmlinux EXPORT_SYMBOL
++0x2ceca451    input_ff_create vmlinux EXPORT_SYMBOL_GPL
++0x6e3d17ac    device_destroy  vmlinux EXPORT_SYMBOL_GPL
++0xb8d2fd38    wiphy_register  vmlinux EXPORT_SYMBOL
++0xfa4d8a1f    unregister_pernet_device        vmlinux EXPORT_SYMBOL_GPL
++0x4c86184b    remove_wait_queue       vmlinux EXPORT_SYMBOL
++0x4845c423    param_array_ops vmlinux EXPORT_SYMBOL
++0x2cd6eb8b    input_ff_destroy        vmlinux EXPORT_SYMBOL_GPL
++0xb9500ec7    mfd_cell_disable        vmlinux EXPORT_SYMBOL
++0x1a2759ff    platform_get_irq_byname vmlinux EXPORT_SYMBOL_GPL
++0x8daf9344    napi_get_frags  vmlinux EXPORT_SYMBOL
++0x60c805dd    sk_stream_write_space   vmlinux EXPORT_SYMBOL
++0x570e3195    scsi_verify_blk_ioctl   vmlinux EXPORT_SYMBOL
++0xecbe66b8    sysfs_notify_dirent     vmlinux EXPORT_SYMBOL_GPL
++0x158df5f3    kill_bdev       vmlinux EXPORT_SYMBOL
++0x3eb2b460    v4l2_event_unsubscribe  vmlinux EXPORT_SYMBOL_GPL
++0x8e38bb44    ipv6_dup_options        vmlinux EXPORT_SYMBOL_GPL
++0xe306f9d8    cgroup_attach_task_all  vmlinux EXPORT_SYMBOL_GPL
++0x6b06fdce    delayed_work_timer_fn   vmlinux EXPORT_SYMBOL
++0x8104c3bb    phy_register_fixup_for_id       vmlinux EXPORT_SYMBOL
++0x46d3b28c    __div0  vmlinux EXPORT_SYMBOL
++0x7ead817c    __idr_pre_get   vmlinux EXPORT_SYMBOL
++0x6cc299a1    zap_vma_ptes    vmlinux EXPORT_SYMBOL_GPL
++0x1f0972cb    drm_fasync      vmlinux EXPORT_SYMBOL
++0x35c653fb    xfrm_policy_bysel_ctx   vmlinux EXPORT_SYMBOL
++0x8e81d5af    tcp_sendmsg     vmlinux EXPORT_SYMBOL
++0xf9ebc368    snd_soc_new_ac97_codec  vmlinux EXPORT_SYMBOL_GPL
++0x4528c501    elv_rb_del      vmlinux EXPORT_SYMBOL
++0x056bf03a    elv_rb_add      vmlinux EXPORT_SYMBOL
++0x5b2c1c77    init_user_ns    vmlinux EXPORT_SYMBOL_GPL
++0x0b5996ef    st_sensors_sysfs_sampling_frequency_avail       vmlinux EXPORT_SYMBOL
++0x3a17a800    vb2_dqbuf       vmlinux EXPORT_SYMBOL_GPL
++0xe55de32d    i2c_smbus_write_word_data       vmlinux EXPORT_SYMBOL
++0xd1c2d294    ip_mc_leave_group       vmlinux EXPORT_SYMBOL
++0x05843ade    netif_skb_features      vmlinux EXPORT_SYMBOL
++0x00632780    work_busy       vmlinux EXPORT_SYMBOL_GPL
++0x06d2c86e    pm_runtime_set_memalloc_noio    vmlinux EXPORT_SYMBOL_GPL
++0x97c6c5dd    drm_pci_exit    vmlinux EXPORT_SYMBOL
++0x1a1938a1    drm_pci_init    vmlinux EXPORT_SYMBOL
++0xf7a0d470    __sk_mem_reclaim        vmlinux EXPORT_SYMBOL
++0xc4f45210    d_prune_aliases vmlinux EXPORT_SYMBOL
++0x498d293a    trace_buffer_unlock_commit      vmlinux EXPORT_SYMBOL_GPL
++0x12a38747    usleep_range    vmlinux EXPORT_SYMBOL
++0xef409b74    kmsg_dump_get_line      vmlinux EXPORT_SYMBOL_GPL
++0xdd3202eb    lcd_device_unregister   vmlinux EXPORT_SYMBOL
++0x1fa2ae70    tcf_hash_check  vmlinux EXPORT_SYMBOL
++0xa43b9539    memcpy_fromiovecend     vmlinux EXPORT_SYMBOL
++0x4b4f96c3    blk_make_request        vmlinux EXPORT_SYMBOL
++0xe290713d    __pagevec_release       vmlinux EXPORT_SYMBOL
++0x1e047854    warn_slowpath_fmt       vmlinux EXPORT_SYMBOL
++0xbca701eb    vb2_ioctl_expbuf        vmlinux EXPORT_SYMBOL_GPL
++0x01508e49    cfg80211_cqm_rssi_notify        vmlinux EXPORT_SYMBOL
++0xff3e2712    nla_reserve_nohdr       vmlinux EXPORT_SYMBOL
++0xc442fa87    ilookup5        vmlinux EXPORT_SYMBOL
++0x1650bf27    rcutorture_record_progress      vmlinux EXPORT_SYMBOL_GPL
++0x3507a132    _raw_spin_lock_irq      vmlinux EXPORT_SYMBOL
++0x1b24bd6e    prepare_creds   vmlinux EXPORT_SYMBOL
++0x97c03a7e    mutex_unlock    vmlinux EXPORT_SYMBOL
++0x5bf35318    hid_unregister_driver   vmlinux EXPORT_SYMBOL_GPL
++0xd989fc54    usb_autopm_put_interface        vmlinux EXPORT_SYMBOL_GPL
++0x64d3db1a    dev_addr_flush  vmlinux EXPORT_SYMBOL
++0x6d92d23c    snd_dma_reserve_buf     vmlinux EXPORT_SYMBOL
++0x83a476ce    bitmap_scnlistprintf    vmlinux EXPORT_SYMBOL
++0x61660b0f    thermal_notify_framework        vmlinux EXPORT_SYMBOL_GPL
++0x1e925a2f    drm_unplug_dev  vmlinux EXPORT_SYMBOL
++0xef76af89    wiphy_rfkill_set_hw_state       vmlinux EXPORT_SYMBOL
++0x920aacca    nl_table_lock   vmlinux EXPORT_SYMBOL_GPL
++0x69b0b6dd    blkdev_get_by_dev       vmlinux EXPORT_SYMBOL
++0xd87601cc    ring_buffer_unlock_commit       vmlinux EXPORT_SYMBOL_GPL
++0xee7e7bbe    simple_fill_super       vmlinux EXPORT_SYMBOL
++0xf8fffd67    have_submounts  vmlinux EXPORT_SYMBOL
++0x07cc4a5d    printk_timed_ratelimit  vmlinux EXPORT_SYMBOL
++0x274944b3    sock_queue_err_skb      vmlinux EXPORT_SYMBOL
++0x7b03f66f    snd_add_device_sysfs_file       vmlinux EXPORT_SYMBOL
++0x1f8db7f9    ring_buffer_overrun_cpu vmlinux EXPORT_SYMBOL_GPL
++0x0faef0ed    __tasklet_schedule      vmlinux EXPORT_SYMBOL
++0x8ec68aa9    dev_load        vmlinux EXPORT_SYMBOL
++0xf4f14de6    rtnl_trylock    vmlinux EXPORT_SYMBOL
++0xac0ba8c1    blk_iopoll_disable      vmlinux EXPORT_SYMBOL
++0x1bb201ff    debugfs_create_u16      vmlinux EXPORT_SYMBOL_GPL
++0xcae7b03f    bio_add_page    vmlinux EXPORT_SYMBOL
++0x61af42e6    init_pid_ns     vmlinux EXPORT_SYMBOL_GPL
++0x3c420cae    v4l2_m2m_buf_queue      vmlinux EXPORT_SYMBOL_GPL
++0x0fa2a45e    __memzero       vmlinux EXPORT_SYMBOL
++0x674c71f7    ipt_unregister_table    vmlinux EXPORT_SYMBOL
++0x77ecac9f    zlib_inflateEnd vmlinux EXPORT_SYMBOL
++0x7ca5798f    contig_page_data        vmlinux EXPORT_SYMBOL
++0x3b66dc5f    vb2_buffer_done vmlinux EXPORT_SYMBOL_GPL
++0x07b291d1    usb_unlink_anchored_urbs        vmlinux EXPORT_SYMBOL_GPL
++0x06fbba42    usbnet_write_cmd        vmlinux EXPORT_SYMBOL_GPL
++0xc6b4b7b5    inet_frag_evictor       vmlinux EXPORT_SYMBOL
++0x9d44f8f6    xt_unregister_target    vmlinux EXPORT_SYMBOL
++0x0dca487b    led_trigger_show        vmlinux EXPORT_SYMBOL_GPL
++0xb423dba1    console_blanked vmlinux EXPORT_SYMBOL
++0x23679939    __iowrite32_copy        vmlinux EXPORT_SYMBOL_GPL
++0x38361fbf    config_group_init_type_name     vmlinux EXPORT_SYMBOL
++0x668fe138    __sb_end_write  vmlinux EXPORT_SYMBOL
++0xd67296c6    from_kgid       vmlinux EXPORT_SYMBOL
++0x2fd8e085    sdhci_pltfm_clk_get_max_clock   vmlinux EXPORT_SYMBOL_GPL
++0x4222235b    v4l2_fh_is_singular     vmlinux EXPORT_SYMBOL_GPL
++0x27cbc081    nf_conntrack_unregister_notifier        vmlinux EXPORT_SYMBOL_GPL
++0x638eeb4d    fib_rules_register      vmlinux EXPORT_SYMBOL_GPL
++0xfaf98462    bitrev32        vmlinux EXPORT_SYMBOL
++0x0399203b    simple_transaction_read vmlinux EXPORT_SYMBOL
++0x8a99a016    mempool_free_slab       vmlinux EXPORT_SYMBOL
++0x41c72de9    generic_setxattr        vmlinux EXPORT_SYMBOL
++0x75d94810    generic_getxattr        vmlinux EXPORT_SYMBOL
++0xe384a102    usb_speed_string        vmlinux EXPORT_SYMBOL_GPL
++0xf70fecd0    pm_generic_resume_early vmlinux EXPORT_SYMBOL_GPL
++0x48cb14ac    pm_generic_thaw vmlinux EXPORT_SYMBOL_GPL
++0x1d061186    cfg80211_connect_result vmlinux EXPORT_SYMBOL
++0xdd8800ff    jbd2_journal_set_features       vmlinux EXPORT_SYMBOL
++0xdadafdd7    mpage_readpages vmlinux EXPORT_SYMBOL
++0x4045c494    filter_match_preds      vmlinux EXPORT_SYMBOL_GPL
++0x5482fcef    usbnet_start_xmit       vmlinux EXPORT_SYMBOL_GPL
++0x9e074139    __pm_runtime_resume     vmlinux EXPORT_SYMBOL_GPL
++0x4df119fa    __bitmap_parse  vmlinux EXPORT_SYMBOL
++0x2cfc8703    __wait_on_buffer        vmlinux EXPORT_SYMBOL
++0x4a8907de    cancel_delayed_work_sync        vmlinux EXPORT_SYMBOL
++0x4c5566c5    extcon_set_cable_state  vmlinux EXPORT_SYMBOL_GPL
++0x1114ede2    extcon_get_cable_state  vmlinux EXPORT_SYMBOL_GPL
++0xcac8aaf3    i2c_unlock_adapter      vmlinux EXPORT_SYMBOL_GPL
++0xc3107f52    regmap_raw_read vmlinux EXPORT_SYMBOL_GPL
++0x6b807a5f    gpio_sysfs_set_active_low       vmlinux EXPORT_SYMBOL_GPL
++0xad4d490d    sock_create     vmlinux EXPORT_SYMBOL
++0x1bcfb1fa    debugfs_create_x32      vmlinux EXPORT_SYMBOL_GPL
++0xb0440408    bprm_change_interp      vmlinux EXPORT_SYMBOL
++0xbf7f05c3    kill_litter_super       vmlinux EXPORT_SYMBOL
++0xcb34aaf6    iommu_domain_window_disable     vmlinux EXPORT_SYMBOL_GPL
++0x7c9e0f69    clk_add_alias   vmlinux EXPORT_SYMBOL
++0xad84bef8    dm_table_event  vmlinux EXPORT_SYMBOL
++0xc91b3468    class_dev_iter_next     vmlinux EXPORT_SYMBOL_GPL
++0x64038eb3    inet_proto_csum_replace4        vmlinux EXPORT_SYMBOL
++0xb6e03027    neigh_direct_output     vmlinux EXPORT_SYMBOL
++0xce9a717b    blk_rq_check_limits     vmlinux EXPORT_SYMBOL_GPL
++0x75bda77a    seq_hlist_next  vmlinux EXPORT_SYMBOL
++0xb9c24bba    account_page_dirtied    vmlinux EXPORT_SYMBOL
++0xde037eaa    __lock_page_killable    vmlinux EXPORT_SYMBOL_GPL
++0x73c2d5f0    usb_free_urb    vmlinux EXPORT_SYMBOL_GPL
++0x9faa8d4a    tty_prepare_flip_string_flags   vmlinux EXPORT_SYMBOL_GPL
++0xb8de9394    tty_prepare_flip_string vmlinux EXPORT_SYMBOL_GPL
++0x4db0cbcf    fib_rules_unregister    vmlinux EXPORT_SYMBOL_GPL
++0x5fe6f617    skb_copy_bits   vmlinux EXPORT_SYMBOL
++0x71bf6cf0    __blk_end_request_all   vmlinux EXPORT_SYMBOL
++0xede99a14    crypto_register_ahash   vmlinux EXPORT_SYMBOL_GPL
++0xbdb3fd8c    sysfs_remove_link       vmlinux EXPORT_SYMBOL_GPL
++0x8924eb1e    rcu_force_quiescent_state       vmlinux EXPORT_SYMBOL_GPL
++0xe77924e8    drm_match_cea_mode      vmlinux EXPORT_SYMBOL
++0x189868d7    get_random_bytes_arch   vmlinux EXPORT_SYMBOL
++0x3aeef779    tcp_make_synack vmlinux EXPORT_SYMBOL
++0xc1c0b09b    snd_soc_add_codec_controls      vmlinux EXPORT_SYMBOL_GPL
++0xcc402882    find_get_page   vmlinux EXPORT_SYMBOL
++0x7d59dd46    pm_wq   vmlinux EXPORT_SYMBOL_GPL
++0x9a47820d    hrtimer_forward vmlinux EXPORT_SYMBOL_GPL
++0xa1f0ebea    bit_waitqueue   vmlinux EXPORT_SYMBOL
++0x52bd048a    iio_get_channel_type    vmlinux EXPORT_SYMBOL_GPL
++0x37b330b1    mii_check_gmii_support  vmlinux EXPORT_SYMBOL
++0x964bc3de    dma_async_device_register       vmlinux EXPORT_SYMBOL
++0x0adc9704    display_timings_release vmlinux EXPORT_SYMBOL_GPL
++0xe6c818f2    sock_common_recvmsg     vmlinux EXPORT_SYMBOL
++0xb62a00b3    mem_cgroup_subsys       vmlinux EXPORT_SYMBOL
++0x64652950    __video_register_device vmlinux EXPORT_SYMBOL
++0x9572f9d0    inet_csk_addr2sockaddr  vmlinux EXPORT_SYMBOL_GPL
++0xeda0d76e    gen_estimator_active    vmlinux EXPORT_SYMBOL
++0x8251bcc3    bitmap_release_region   vmlinux EXPORT_SYMBOL
++0x5567c227    kernel_cpustat  vmlinux EXPORT_SYMBOL
++0x9133fe16    vb2_write       vmlinux EXPORT_SYMBOL_GPL
++0x9bb89701    cfg80211_roamed vmlinux EXPORT_SYMBOL
++0x5eb03c4c    ip_mc_inc_group vmlinux EXPORT_SYMBOL
++0x06438115    tcp_orphan_count        vmlinux EXPORT_SYMBOL_GPL
++0x43804ba2    fat_attach      vmlinux EXPORT_SYMBOL_GPL
++0x30788c84    sysfs_remove_bin_file   vmlinux EXPORT_SYMBOL_GPL
++0xb11bad4f    register_wide_hw_breakpoint     vmlinux EXPORT_SYMBOL_GPL
++0xbd8b253c    tcf_exts_validate       vmlinux EXPORT_SYMBOL
++0xb81960ca    snprintf        vmlinux EXPORT_SYMBOL
++0x7cae600c    get_io_context  vmlinux EXPORT_SYMBOL
++0x70bb651d    __tracepoint_block_rq_remap     vmlinux EXPORT_SYMBOL_GPL
++0x9be42ea4    proc_mkdir_mode vmlinux EXPORT_SYMBOL
++0xf0701cc6    tag_pages_for_writeback vmlinux EXPORT_SYMBOL
++0x3cf525fb    hid_dump_device vmlinux EXPORT_SYMBOL_GPL
++0x219e9575    wakeup_source_unregister        vmlinux EXPORT_SYMBOL_GPL
++0xff43d5b5    cfg80211_check_station_change   vmlinux EXPORT_SYMBOL
++0x2296c00d    crypto_attr_u32 vmlinux EXPORT_SYMBOL_GPL
++0x710eaf23    PDE_DATA        vmlinux EXPORT_SYMBOL
++0xc1fac3b3    __bread vmlinux EXPORT_SYMBOL
++0x55af945f    follow_pfn      vmlinux EXPORT_SYMBOL
++0x275ae863    make_kuid       vmlinux EXPORT_SYMBOL
++0x54d8b7ba    hrtimer_init    vmlinux EXPORT_SYMBOL_GPL
++0x7c8f0303    dma_buf_export_named    vmlinux EXPORT_SYMBOL_GPL
++0x079f8b38    devm_kzalloc    vmlinux EXPORT_SYMBOL_GPL
++0x9ddbb3f6    tty_port_link_device    vmlinux EXPORT_SYMBOL_GPL
++0x9e8d08a7    pinctrl_find_and_add_gpio_range vmlinux EXPORT_SYMBOL_GPL
++0x9ceb163c    memcpy_toiovec  vmlinux EXPORT_SYMBOL
++0x44c38935    v4l2_subdev_g_ext_ctrls vmlinux EXPORT_SYMBOL
++0xc5fab8f0    v4l2_subdev_s_ext_ctrls vmlinux EXPORT_SYMBOL
++0x4cf092e4    scsi_report_opcode      vmlinux EXPORT_SYMBOL
++0x1b6314fd    in_aton vmlinux EXPORT_SYMBOL
++0x1027ae8c    neigh_resolve_output    vmlinux EXPORT_SYMBOL
++0xc492c2d9    snd_card_register       vmlinux EXPORT_SYMBOL
++0xa3018431    posix_unblock_lock      vmlinux EXPORT_SYMBOL
++0xf3d6e3aa    __mnt_is_readonly       vmlinux EXPORT_SYMBOL_GPL
++0x87984b16    __tracepoint_cpu_idle   vmlinux EXPORT_SYMBOL_GPL
++0x89205531    cfb_imageblit   vmlinux EXPORT_SYMBOL
++0x3bbf46ea    vga_base        vmlinux EXPORT_SYMBOL
++0x6fea34fd    tcp_close       vmlinux EXPORT_SYMBOL
++0x7bd5c87c    inet_add_offload        vmlinux EXPORT_SYMBOL
++0x024ea18c    nf_nat_irc_hook vmlinux EXPORT_SYMBOL_GPL
++0x18d1ab6f    nf_nat_ftp_hook vmlinux EXPORT_SYMBOL_GPL
++0xeb780f0e    nfq_ct_nat_hook vmlinux EXPORT_SYMBOL_GPL
++0x06277150    __scm_send      vmlinux EXPORT_SYMBOL
++0xc49eea50    skb_try_coalesce        vmlinux EXPORT_SYMBOL
++0xec007de7    snd_soc_dapm_new_controls       vmlinux EXPORT_SYMBOL_GPL
++0xa07ed110    xz_dec_init     vmlinux EXPORT_SYMBOL
++0x3dd4d3a7    bprintf vmlinux EXPORT_SYMBOL_GPL
++0xa4a0aeb8    try_to_free_buffers     vmlinux EXPORT_SYMBOL
++0xe9f098a6    wait_iff_congested      vmlinux EXPORT_SYMBOL
++0xcb5bf3f1    __put_cred      vmlinux EXPORT_SYMBOL
++0x3f80e476    get_thermal_instance    vmlinux EXPORT_SYMBOL
++0xb6979f60    usb_register_dev        vmlinux EXPORT_SYMBOL_GPL
++0xe0d8227f    scsi_dma_map    vmlinux EXPORT_SYMBOL
++0xa5de5bb1    blk_queue_bypass_start  vmlinux EXPORT_SYMBOL_GPL
++0xb9617f29    dm_path_uevent  vmlinux EXPORT_SYMBOL_GPL
++0xd909cae6    serial8250_clear_and_reinit_fifos       vmlinux EXPORT_SYMBOL_GPL
++0x755da9a0    register_framebuffer    vmlinux EXPORT_SYMBOL
++0x9ed685ee    iov_iter_advance        vmlinux EXPORT_SYMBOL
++0xf86a3a9f    clk_gate_ops    vmlinux EXPORT_SYMBOL_GPL
++0xfcc9ce6a    mmc_of_parse    vmlinux EXPORT_SYMBOL
++0xb486e84e    mfd_remove_devices      vmlinux EXPORT_SYMBOL
++0xc5a484ac    pm_generic_suspend_late vmlinux EXPORT_SYMBOL_GPL
++0x3cd06035    add_input_randomness    vmlinux EXPORT_SYMBOL_GPL
++0xf50d8f59    regulator_enable_regmap vmlinux EXPORT_SYMBOL_GPL
++0x09774d0b    pinctrl_force_sleep     vmlinux EXPORT_SYMBOL_GPL
++0xc7c3c6d2    ip6_tnl_dst_reset       vmlinux EXPORT_SYMBOL_GPL
++0x225d0386    nf_ct_l4proto_pernet_register   vmlinux EXPORT_SYMBOL_GPL
++0xf7d31a5d    nf_ct_l3proto_pernet_register   vmlinux EXPORT_SYMBOL_GPL
++0x8401c62f    scsi_unblock_requests   vmlinux EXPORT_SYMBOL
++0x8ca1a1dc    device_remove_bin_file  vmlinux EXPORT_SYMBOL_GPL
++0xccb1ba6b    of_get_drm_display_mode vmlinux EXPORT_SYMBOL_GPL
++0xe3f48cba    tty_port_free_xmit_buf  vmlinux EXPORT_SYMBOL
++0xec1b043e    regulator_suspend_prepare       vmlinux EXPORT_SYMBOL_GPL
++0xecbda9c5    display_entity_get      vmlinux EXPORT_SYMBOL_GPL
++0x13b89dee    pinctrl_request_gpio    vmlinux EXPORT_SYMBOL_GPL
++0xdcb3410a    nf_ct_deliver_cached_events     vmlinux EXPORT_SYMBOL_GPL
++0x32ddd5b6    call_rcu        vmlinux EXPORT_SYMBOL_GPL
++0xf1267848    usb_composite_unregister        vmlinux EXPORT_SYMBOL_GPL
++0x877509c0    crypto_nivaead_type     vmlinux EXPORT_SYMBOL_GPL
++0x9263cf47    bdi_writeout_inc        vmlinux EXPORT_SYMBOL_GPL
++0x26f6b499    iio_str_to_fixpoint     vmlinux EXPORT_SYMBOL_GPL
++0x7267db00    hwrng_unregister        vmlinux EXPORT_SYMBOL_GPL
++0x19cbf31d    xfrm6_rcv_spi   vmlinux EXPORT_SYMBOL
++0xe5a42822    ip_tunnel_change_mtu    vmlinux EXPORT_SYMBOL_GPL
++0xf236a5de    tcf_exts_change vmlinux EXPORT_SYMBOL
++0x058b95e3    snd_pcm_release_substream       vmlinux EXPORT_SYMBOL
++0x9a6e183a    __idr_remove_all        vmlinux EXPORT_SYMBOL
++0x7b9bf08e    disk_stack_limits       vmlinux EXPORT_SYMBOL
++0x9879932b    crypto_register_notifier        vmlinux EXPORT_SYMBOL_GPL
++0xd220cf8a    jiffies_to_timespec     vmlinux EXPORT_SYMBOL
++0xce4f758e    dma_release_from_coherent       vmlinux EXPORT_SYMBOL
++0xe238b99e    pskb_put        vmlinux EXPORT_SYMBOL_GPL
++0xe11dd614    fib_table_lookup        vmlinux EXPORT_SYMBOL_GPL
++0x3862b0a7    snd_soc_bytes_put       vmlinux EXPORT_SYMBOL_GPL
++0xa5ed8e2c    inc_nlink       vmlinux EXPORT_SYMBOL
++0xf43bdbf8    smpboot_unregister_percpu_thread        vmlinux EXPORT_SYMBOL_GPL
++0x8a1ab4ee    timeval_to_jiffies      vmlinux EXPORT_SYMBOL
++0x39375395    i2c_master_send vmlinux EXPORT_SYMBOL
++0x3a517b2b    device_reprobe  vmlinux EXPORT_SYMBOL_GPL
++0xb22e34bd    wiphy_free      vmlinux EXPORT_SYMBOL
++0x76a01893    __netlink_dump_start    vmlinux EXPORT_SYMBOL
++0xa96c3c3b    dev_kfree_skb_any       vmlinux EXPORT_SYMBOL
++0xfdaeced1    snd_ctl_new1    vmlinux EXPORT_SYMBOL
++0xb4f57a24    security_task_getsecid  vmlinux EXPORT_SYMBOL
++0x09d71f87    seq_open        vmlinux EXPORT_SYMBOL
++0x29a73c29    mnt_drop_write  vmlinux EXPORT_SYMBOL_GPL
++0xbcdd5b99    iommu_group_set_name    vmlinux EXPORT_SYMBOL_GPL
++0x7e394c4e    sysctl_local_reserved_ports     vmlinux EXPORT_SYMBOL
++0x094bac5f    simple_readpage vmlinux EXPORT_SYMBOL
++0x5a39720e    __lock_page     vmlinux EXPORT_SYMBOL
++0xb140d14c    ring_buffer_read        vmlinux EXPORT_SYMBOL_GPL
++0xf499fdb2    rcu_barrier_bh  vmlinux EXPORT_SYMBOL_GPL
++0x03d9fff7    synchronize_srcu_expedited      vmlinux EXPORT_SYMBOL_GPL
++0x1c0ae7d7    drm_mm_init_scan        vmlinux EXPORT_SYMBOL
++0x8320bea8    __umodsi3       vmlinux EXPORT_SYMBOL
++0xc3706dce    tcp_cong_avoid_ai       vmlinux EXPORT_SYMBOL_GPL
++0xab6bde28    sysctl_max_syn_backlog  vmlinux EXPORT_SYMBOL
++0x5d90d2ce    blk_delay_queue vmlinux EXPORT_SYMBOL
++0xefdd70ce    security_secid_to_secctx        vmlinux EXPORT_SYMBOL
++0x77d67659    follow_down     vmlinux EXPORT_SYMBOL
++0x083eb1cc    __generic_file_aio_write        vmlinux EXPORT_SYMBOL
++0x46646afc    filemap_write_and_wait_range    vmlinux EXPORT_SYMBOL
++0xc72c4abb    usb_altnum_to_altsetting        vmlinux EXPORT_SYMBOL_GPL
++0x0a98333a    snd_soc_dpcm_get_substream      vmlinux EXPORT_SYMBOL_GPL
++0x360b1afe    probe_irq_mask  vmlinux EXPORT_SYMBOL
++0x8f2154e4    cfg80211_rx_mgmt        vmlinux EXPORT_SYMBOL
++0xafa574d0    snd_soc_jack_notifier_unregister        vmlinux EXPORT_SYMBOL_GPL
++0x93af86c9    get_write_access        vmlinux EXPORT_SYMBOL
++0x2350c4a6    invalidate_mapping_pages        vmlinux EXPORT_SYMBOL
++0x84c6c77a    genphy_read_status      vmlinux EXPORT_SYMBOL
++0x96fb7fef    drm_mode_create_dithering_property      vmlinux EXPORT_SYMBOL
++0xef56f51e    redraw_screen   vmlinux EXPORT_SYMBOL
++0x2394545f    tty_unregister_driver   vmlinux EXPORT_SYMBOL
++0xf3bf0bce    __bitmap_complement     vmlinux EXPORT_SYMBOL
++0xe2e8065e    memdup_user     vmlinux EXPORT_SYMBOL
++0x3bdd0f94    v4l2_prio_change        vmlinux EXPORT_SYMBOL
++0x7ab9b430    drm_poll        vmlinux EXPORT_SYMBOL
++0x760d494e    pinctrl_find_gpio_range_from_pin        vmlinux EXPORT_SYMBOL_GPL
++0xcca27eeb    del_timer       vmlinux EXPORT_SYMBOL
++0x39e773af    thermal_cooling_device_unregister       vmlinux EXPORT_SYMBOL_GPL
++0xcba9dbcf    dma_get_required_mask   vmlinux EXPORT_SYMBOL_GPL
++0x2fb1d233    nf_log_unbind_pf        vmlinux EXPORT_SYMBOL
++0x460f7531    wait_rcu_gp     vmlinux EXPORT_SYMBOL_GPL
++0x9bfaf424    usb_get_current_frame_number    vmlinux EXPORT_SYMBOL_GPL
++0xad9bbf9f    hci_suspend_dev vmlinux EXPORT_SYMBOL
++0x56c5a136    tcp_v4_send_check       vmlinux EXPORT_SYMBOL
++0x0a4862b9    nf_ct_expect_find_get   vmlinux EXPORT_SYMBOL_GPL
++0x30e3e930    dev_close       vmlinux EXPORT_SYMBOL
++0xc3e46db4    snd_pcm_lib_free_pages  vmlinux EXPORT_SYMBOL
++0x3b735a2b    __mark_inode_dirty      vmlinux EXPORT_SYMBOL
++0x91437bc9    dma_buf_put     vmlinux EXPORT_SYMBOL_GPL
++0x8e09c957    dma_buf_get     vmlinux EXPORT_SYMBOL_GPL
++0x98aba977    ip6_update_pmtu vmlinux EXPORT_SYMBOL_GPL
++0x019daa72    noop_qdisc      vmlinux EXPORT_SYMBOL
++0x240646b9    sock_alloc_send_skb     vmlinux EXPORT_SYMBOL
++0x871f2cb1    snd_soc_dapm_nc_pin     vmlinux EXPORT_SYMBOL_GPL
++0x97440f69    snd_card_disconnect     vmlinux EXPORT_SYMBOL
++0xd9ce8f0c    strnlen vmlinux EXPORT_SYMBOL
++0xe7c9dbc0    unregister_filesystem   vmlinux EXPORT_SYMBOL
++0x4abbe3c2    vm_brk  vmlinux EXPORT_SYMBOL
++0x2439abc9    irq_domain_add_simple   vmlinux EXPORT_SYMBOL_GPL
++0xd418e1c0    adjust_resource vmlinux EXPORT_SYMBOL
++0x31c0c2d1    dm_put  vmlinux EXPORT_SYMBOL_GPL
++0x140e371b    v4l2_of_get_remote_port_parent  vmlinux EXPORT_SYMBOL
++0x3adbd595    v4l2_field_names        vmlinux EXPORT_SYMBOL
++0xdcece020    xfrm_state_insert       vmlinux EXPORT_SYMBOL
++0xf8fe3d0b    kmsg_dump_register      vmlinux EXPORT_SYMBOL_GPL
++0x40728a63    xt_find_revision        vmlinux EXPORT_SYMBOL_GPL
++0xcb534ec9    __destroy_inode vmlinux EXPORT_SYMBOL
++0xea1f5b88    samsung_rev     vmlinux EXPORT_SYMBOL
++0xd3dd145a    tcp_is_cwnd_limited     vmlinux EXPORT_SYMBOL_GPL
++0x392697b4    nf_conntrack_l3proto_generic    vmlinux EXPORT_SYMBOL_GPL
++0x2549013a    snd_soc_dai_set_channel_map     vmlinux EXPORT_SYMBOL_GPL
++0x421e53cf    blk_rq_unmap_user       vmlinux EXPORT_SYMBOL
++0xacf1d33d    crypto_mod_get  vmlinux EXPORT_SYMBOL_GPL
++0x0bc477a2    irq_set_irq_type        vmlinux EXPORT_SYMBOL
++0xce2840e7    irq_set_irq_wake        vmlinux EXPORT_SYMBOL
++0x2650d835    sysctl_ip_early_demux   vmlinux EXPORT_SYMBOL
++0x07e472e5    __remove_inode_hash     vmlinux EXPORT_SYMBOL
++0x82b7cda8    __lru_cache_add vmlinux EXPORT_SYMBOL
++0x457b77ca    of_fixed_factor_clk_setup       vmlinux EXPORT_SYMBOL_GPL
++0x840b929e    v4l2_device_unregister_subdev   vmlinux EXPORT_SYMBOL_GPL
++0x6128b5fc    __printk_ratelimit      vmlinux EXPORT_SYMBOL
++0xcc1f1c3d    inet_twdr_hangman       vmlinux EXPORT_SYMBOL_GPL
++0x71faed49    __blk_end_request_cur   vmlinux EXPORT_SYMBOL
++0xab5cbfa1    __blk_end_request_err   vmlinux EXPORT_SYMBOL_GPL
++0xb2682405    utf8_to_utf32   vmlinux EXPORT_SYMBOL
++0x9621849f    ring_buffer_event_data  vmlinux EXPORT_SYMBOL_GPL
++0x2761c400    pm_generic_restore_early        vmlinux EXPORT_SYMBOL_GPL
++0x36d31f9e    crypto_sha1_update      vmlinux EXPORT_SYMBOL
++0x8798e453    __tracepoint_kfree      vmlinux EXPORT_SYMBOL
++0x247ba373    override_creds  vmlinux EXPORT_SYMBOL
++0x131db64a    system_long_wq  vmlinux EXPORT_SYMBOL_GPL
++0xc0d26387    kmsg_dump_unregister    vmlinux EXPORT_SYMBOL_GPL
++0x6b132713    __clk_register  vmlinux EXPORT_SYMBOL_GPL
++0x5292f4ea    scsi_prep_return        vmlinux EXPORT_SYMBOL
++0x34a13791    __pm_runtime_disable    vmlinux EXPORT_SYMBOL_GPL
++0xa10db0ce    phy_pm_runtime_get_sync vmlinux EXPORT_SYMBOL_GPL
++0x1b62df19    arm_iommu_create_mapping        vmlinux EXPORT_SYMBOL_GPL
++0x606d0b09    secure_tcpv6_sequence_number    vmlinux EXPORT_SYMBOL
++0xa75bc594    blkdev_issue_zeroout    vmlinux EXPORT_SYMBOL
++0x8f12669a    irq_linear_revmap       vmlinux EXPORT_SYMBOL_GPL
++0x938244d0    handle_level_irq        vmlinux EXPORT_SYMBOL_GPL
++0xb336e1d2    extcon_set_cable_state_ vmlinux EXPORT_SYMBOL_GPL
++0x067ef5d5    extcon_get_cable_state_ vmlinux EXPORT_SYMBOL_GPL
++0x8d22bb58    iommu_group_alloc       vmlinux EXPORT_SYMBOL_GPL
++0xa7e20df3    clk_mux_ops     vmlinux EXPORT_SYMBOL_GPL
++0x7f9eeaae    input_register_handle   vmlinux EXPORT_SYMBOL
++0x6cc78c5c    set_irq_flags   vmlinux EXPORT_SYMBOL_GPL
++0xc781bd9f    rfkill_resume_polling   vmlinux EXPORT_SYMBOL
++0x982e6b6d    ieee80211_radiotap_iterator_init        vmlinux EXPORT_SYMBOL
++0xf30fda27    lzo1x_decompress_safe   vmlinux EXPORT_SYMBOL_GPL
++0x42b364ef    scatterwalk_done        vmlinux EXPORT_SYMBOL_GPL
++0x2158c0d7    kern_unmount    vmlinux EXPORT_SYMBOL
++0xd31ccb06    of_machine_is_compatible        vmlinux EXPORT_SYMBOL
++0xd6d49c42    sdio_writesb    vmlinux EXPORT_SYMBOL_GPL
++0xe6fa2163    v4l2_async_notifier_unregister  vmlinux EXPORT_SYMBOL
++0x20234f83    nla_append      vmlinux EXPORT_SYMBOL
++0x4cf41ed3    skcipher_geniv_free     vmlinux EXPORT_SYMBOL_GPL
++0x4bc07110    jbd2_journal_lock_updates       vmlinux EXPORT_SYMBOL
++0xf37671d2    vfs_llseek      vmlinux EXPORT_SYMBOL
++0x8720876b    __page_file_index       vmlinux EXPORT_SYMBOL_GPL
++0x609d9c25    __irq_set_handler       vmlinux EXPORT_SYMBOL_GPL
++0x2d17a0e1    cgroup_taskset_size     vmlinux EXPORT_SYMBOL_GPL
++0xabe27502    v4l2_ctrl_query_fill    vmlinux EXPORT_SYMBOL
++0x5b1a060c    usb_control_msg vmlinux EXPORT_SYMBOL_GPL
++0xe59c5ea4    snd_dma_free_pages      vmlinux EXPORT_SYMBOL
++0x85541e31    iterate_fd      vmlinux EXPORT_SYMBOL
++0x7ceaf0d5    generic_handle_irq      vmlinux EXPORT_SYMBOL_GPL
++0x46feb099    dm_read_arg     vmlinux EXPORT_SYMBOL
++0xe8125c91    dev_set_drvdata vmlinux EXPORT_SYMBOL
++0x8d60d310    dev_get_drvdata vmlinux EXPORT_SYMBOL
++0x84510ec6    bt_sock_unlink  vmlinux EXPORT_SYMBOL
++0x14f626f7    snd_soc_dapm_add_routes vmlinux EXPORT_SYMBOL_GPL
++0x5d1c1bac    blocking_notifier_chain_cond_register   vmlinux EXPORT_SYMBOL_GPL
++0xefd5b1f1    nfc_hci_disconnect_all_gates    vmlinux EXPORT_SYMBOL
++0x009c0acf    __xfrm_state_destroy    vmlinux EXPORT_SYMBOL
++0x256e5691    bfifo_qdisc_ops vmlinux EXPORT_SYMBOL
++0x1f8544b8    panic_timeout   vmlinux EXPORT_SYMBOL_GPL
++0x5b4e379c    of_prop_next_u32        vmlinux EXPORT_SYMBOL_GPL
++0x8106095a    v4l2_prio_max   vmlinux EXPORT_SYMBOL
++0xfff74a32    usb_unpoison_urb        vmlinux EXPORT_SYMBOL_GPL
++0xc532db16    tty_port_init   vmlinux EXPORT_SYMBOL
++0xa20ce1b8    net_msg_warn    vmlinux EXPORT_SYMBOL
++0x2aa97a28    __sock_recv_timestamp   vmlinux EXPORT_SYMBOL_GPL
++0x6225637e    md5_transform   vmlinux EXPORT_SYMBOL
++0xa3301b08    noop_fsync      vmlinux EXPORT_SYMBOL
++0x31ab0e28    extcon_dev_unregister   vmlinux EXPORT_SYMBOL_GPL
++0xc5176fe9    usb_hcd_resume_root_hub vmlinux EXPORT_SYMBOL_GPL
++0x13bdb1fd    cfg80211_ibss_joined    vmlinux EXPORT_SYMBOL
++0x587763dd    blkdev_issue_write_same vmlinux EXPORT_SYMBOL
++0x627b7988    crypto_hash_walk_first  vmlinux EXPORT_SYMBOL_GPL
++0x85d438aa    scsi_add_host_with_dma  vmlinux EXPORT_SYMBOL
++0x2b26ce97    devres_remove_group     vmlinux EXPORT_SYMBOL_GPL
++0x8e007d5e    inet_sendpage   vmlinux EXPORT_SYMBOL
++0xbb713e6d    sk_filter_release_rcu   vmlinux EXPORT_SYMBOL
++0xf1dc9acb    dev_get_by_index_rcu    vmlinux EXPORT_SYMBOL
++0x5364397d    dev_set_allmulti        vmlinux EXPORT_SYMBOL
++0xd20a4e9e    snd_ctl_remove_id       vmlinux EXPORT_SYMBOL
++0xea10655a    __bitmap_intersects     vmlinux EXPORT_SYMBOL
++0xf313da4e    sha_transform   vmlinux EXPORT_SYMBOL
++0x9b6eb137    ksize   vmlinux EXPORT_SYMBOL
++0x38869d88    kstat   vmlinux EXPORT_SYMBOL
++0x43caf714    mmc_can_erase   vmlinux EXPORT_SYMBOL
++0xa42810a9    i2c_add_adapter vmlinux EXPORT_SYMBOL
++0xaf5ddb02    input_mt_report_finger_count    vmlinux EXPORT_SYMBOL
++0x3a09b033    drm_mmap        vmlinux EXPORT_SYMBOL
++0xcc16f79c    drm_kms_helper_poll_fini        vmlinux EXPORT_SYMBOL
++0xe707d823    __aeabi_uidiv   vmlinux EXPORT_SYMBOL
++0xcd2a33d7    hci_conn_security       vmlinux EXPORT_SYMBOL
++0xd456425d    kobject_set_name        vmlinux EXPORT_SYMBOL
++0x60642a60    shmem_truncate_range    vmlinux EXPORT_SYMBOL_GPL
++0xa3e7c113    ring_buffer_iter_peek   vmlinux EXPORT_SYMBOL_GPL
++0xa5efbf4c    async_synchronize_full  vmlinux EXPORT_SYMBOL_GPL
++0x3ac75973    dm_send_uevents vmlinux EXPORT_SYMBOL_GPL
++0x47f757de    elf_platform    vmlinux EXPORT_SYMBOL
++0x48994b32    bt_debugfs      vmlinux EXPORT_SYMBOL_GPL
++0xc3f4c43b    set_device_ro   vmlinux EXPORT_SYMBOL
++0xbb038ce4    perf_unregister_guest_info_callbacks    vmlinux EXPORT_SYMBOL_GPL
++0x8cc44150    of_clk_src_simple_get   vmlinux EXPORT_SYMBOL_GPL
++0x09378170    shash_attr_alg  vmlinux EXPORT_SYMBOL_GPL
++0x63eb9355    panic_blink     vmlinux EXPORT_SYMBOL
++0x37df5b58    usb_anchor_urb  vmlinux EXPORT_SYMBOL_GPL
++0x665ccdb6    __sync_dirty_buffer     vmlinux EXPORT_SYMBOL
++0xb370f2b0    kmap_high       vmlinux EXPORT_SYMBOL
++0xc3042166    cancel_dirty_page       vmlinux EXPORT_SYMBOL
++0xf4fc2d6c    __ring_buffer_alloc     vmlinux EXPORT_SYMBOL_GPL
++0x82072614    tasklet_kill    vmlinux EXPORT_SYMBOL
++0x653cd720    exynos_g2d_set_cmdlist_ioctl    vmlinux EXPORT_SYMBOL_GPL
++0xa2a78b0e    blk_post_runtime_resume vmlinux EXPORT_SYMBOL
++0xf7f02ddf    bio_endio       vmlinux EXPORT_SYMBOL
++0x269b337f    account_page_redirty    vmlinux EXPORT_SYMBOL
++0x85c7f674    ring_buffer_normalize_time_stamp        vmlinux EXPORT_SYMBOL_GPL
++0xf4597085    i2c_use_client  vmlinux EXPORT_SYMBOL
++0x2da746c5    scsi_print_command      vmlinux EXPORT_SYMBOL
++0xd0e73a87    amba_driver_register    vmlinux EXPORT_SYMBOL
++0x3810da45    nf_ct_expect_unregister_notifier        vmlinux EXPORT_SYMBOL_GPL
++0x50b236e9    eth_prepare_mac_addr_change     vmlinux EXPORT_SYMBOL
++0xd32c0bf4    sk_stop_timer   vmlinux EXPORT_SYMBOL
++0xffdb82bc    sg_free_table   vmlinux EXPORT_SYMBOL
++0xfcbba27f    locks_remove_posix      vmlinux EXPORT_SYMBOL
++0xb0b85f47    ring_buffer_iter_reset  vmlinux EXPORT_SYMBOL_GPL
++0x43b0c9c3    preempt_schedule        vmlinux EXPORT_SYMBOL
++0x7c010229    of_platform_bus_probe   vmlinux EXPORT_SYMBOL
++0xf74656ab    regulator_can_change_voltage    vmlinux EXPORT_SYMBOL_GPL
++0x5d5b5a16    radix_tree_delete       vmlinux EXPORT_SYMBOL
++0x4b37f24f    of_extcon_get_extcon_dev        vmlinux EXPORT_SYMBOL_GPL
++0x728be72e    pm_generic_thaw_noirq   vmlinux EXPORT_SYMBOL_GPL
++0x94de4a33    tcp_slow_start  vmlinux EXPORT_SYMBOL_GPL
++0x4a73178a    dev_activate    vmlinux EXPORT_SYMBOL
++0x7649cfce    __pneigh_lookup vmlinux EXPORT_SYMBOL_GPL
++0xaafcd87b    devm_iounmap    vmlinux EXPORT_SYMBOL
++0x3bfc99a5    devm_ioremap    vmlinux EXPORT_SYMBOL
++0x5541ea93    on_each_cpu     vmlinux EXPORT_SYMBOL
++0x176af8ec    cdc_ncm_rx_verify_ndp16 vmlinux EXPORT_SYMBOL_GPL
++0x572d7fe7    pn544_hci_remove        vmlinux EXPORT_SYMBOL
++0x74e5ff1a    udpv6_encap_enable      vmlinux EXPORT_SYMBOL
++0x7a08f61d    snd_pcm_set_sync        vmlinux EXPORT_SYMBOL
++0x164b50d3    nla_reserve     vmlinux EXPORT_SYMBOL
++0x08758d9c    bioset_create   vmlinux EXPORT_SYMBOL
++0x08365975    drm_gem_object_lookup   vmlinux EXPORT_SYMBOL
++0x862b9816    cpu_topology    vmlinux EXPORT_SYMBOL_GPL
++0x3722cf9f    rtnl_put_cacheinfo      vmlinux EXPORT_SYMBOL_GPL
++0xea124bd1    gcd     vmlinux EXPORT_SYMBOL_GPL
++0xce3e95d0    ihold   vmlinux EXPORT_SYMBOL
++0xd11031b4    names_cachep    vmlinux EXPORT_SYMBOL
++0x8890cade    invalidate_inode_pages2_range   vmlinux EXPORT_SYMBOL_GPL
++0x83130f62    cancel_delayed_work     vmlinux EXPORT_SYMBOL
++0xcbc428db    __cpufreq_driver_target vmlinux EXPORT_SYMBOL_GPL
++0xd6233445    xfrm_policy_register_afinfo     vmlinux EXPORT_SYMBOL
++0xc8afb46b    snd_info_create_card_entry      vmlinux EXPORT_SYMBOL
++0xb7850524    crypto_unregister_shashes       vmlinux EXPORT_SYMBOL_GPL
++0x4acc9be5    dentry_path_raw vmlinux EXPORT_SYMBOL
++0x475ea860    xfrm_sad_getinfo        vmlinux EXPORT_SYMBOL
++0x9429e18f    netif_napi_del  vmlinux EXPORT_SYMBOL
++0x03a3ce75    crypto_register_alg     vmlinux EXPORT_SYMBOL_GPL
++0x1a3e0511    debugfs_rename  vmlinux EXPORT_SYMBOL_GPL
++0xb69186d9    simple_open     vmlinux EXPORT_SYMBOL
++0xe513ed5c    single_open     vmlinux EXPORT_SYMBOL
++0x9072472b    page_follow_link_light  vmlinux EXPORT_SYMBOL
++0xdbbd4688    __page_file_mapping     vmlinux EXPORT_SYMBOL_GPL
++0x0f751aea    input_event_from_user   vmlinux EXPORT_SYMBOL_GPL
++0x4484a5a4    wait_for_device_probe   vmlinux EXPORT_SYMBOL_GPL
++0xd53e17fd    tty_port_put    vmlinux EXPORT_SYMBOL
++0xa1b759ce    fb_add_videomode        vmlinux EXPORT_SYMBOL
++0x3c831441    arm_check_condition     vmlinux EXPORT_SYMBOL_GPL
++0x44fa52dd    brcmu_pktq_mdeq drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x471d6f83    brcmu_pktq_mlen drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x6af410ae    cfg80211_send_disassoc  vmlinux EXPORT_SYMBOL
++0x1baa3892    xfrm6_find_1stfragopt   vmlinux EXPORT_SYMBOL
++0x198788b4    snd_lookup_oss_minor_data       vmlinux EXPORT_SYMBOL
++0x4a3ea5c0    snd_request_card        vmlinux EXPORT_SYMBOL
++0x56451890    register_ftrace_event   vmlinux EXPORT_SYMBOL_GPL
++0x4ae313f9    kthread_stop    vmlinux EXPORT_SYMBOL
++0x1438fff0    st_sensors_sysfs_scale_avail    vmlinux EXPORT_SYMBOL
++0x31178006    clk_unregister  vmlinux EXPORT_SYMBOL_GPL
++0x083c2cbe    of_get_next_parent      vmlinux EXPORT_SYMBOL
++0xfef96e23    __scsi_print_command    vmlinux EXPORT_SYMBOL
++0x670cff67    drm_helper_disable_unused_functions     vmlinux EXPORT_SYMBOL
++0xe7048594    cfg80211_chandef_create vmlinux EXPORT_SYMBOL
++0x020d1750    cfg80211_tdls_oper_request      vmlinux EXPORT_SYMBOL
++0xbec63ca7    security_inode_create   vmlinux EXPORT_SYMBOL_GPL
++0xfe72e11b    dm_register_target      vmlinux EXPORT_SYMBOL
++0xaa4a7797    hex2bin vmlinux EXPORT_SYMBOL
++0xe924fd45    crypto_default_rng      vmlinux EXPORT_SYMBOL_GPL
++0xddab6b08    d_make_root     vmlinux EXPORT_SYMBOL
++0xa3b40cfd    hid_register_report     vmlinux EXPORT_SYMBOL_GPL
++0xcda04a5b    v4l2_prio_close vmlinux EXPORT_SYMBOL
++0x2e12216c    rtc_set_alarm   vmlinux EXPORT_SYMBOL_GPL
++0xaefe5034    __scsi_get_command      vmlinux EXPORT_SYMBOL_GPL
++0x31547da3    __scsi_put_command      vmlinux EXPORT_SYMBOL
++0x0fa5f996    inet_csk_listen_start   vmlinux EXPORT_SYMBOL_GPL
++0xfcc2a43c    utf32_to_utf8   vmlinux EXPORT_SYMBOL
++0xeef161aa    groups_free     vmlinux EXPORT_SYMBOL
++0xc5a25ce7    cleanup_srcu_struct     vmlinux EXPORT_SYMBOL_GPL
++0xac1a55be    unregister_reboot_notifier      vmlinux EXPORT_SYMBOL
++0x4557930f    regmap_update_bits_check        vmlinux EXPORT_SYMBOL_GPL
++0x0e0eb67f    ip6_flush_pending_frames        vmlinux EXPORT_SYMBOL_GPL
++0xb670b4cf    tcf_destroy_chain       vmlinux EXPORT_SYMBOL
++0x5fa48b4e    generic_file_remap_pages        vmlinux EXPORT_SYMBOL
++0xe13fa8ed    regmap_register_patch   vmlinux EXPORT_SYMBOL_GPL
++0x18c77c17    tty_perform_flush       vmlinux EXPORT_SYMBOL_GPL
++0x5ece6555    debugfs_remove_recursive        vmlinux EXPORT_SYMBOL_GPL
++0x1fcf4d4b    _raw_read_unlock_bh     vmlinux EXPORT_SYMBOL
++0x04cabed9    rfkill_register vmlinux EXPORT_SYMBOL
++0x774a552a    cfg80211_send_deauth    vmlinux EXPORT_SYMBOL
++0xc1691764    neigh_parms_alloc       vmlinux EXPORT_SYMBOL
++0x75fac20b    mount_single    vmlinux EXPORT_SYMBOL
++0x9ecc6a7a    interruptible_sleep_on  vmlinux EXPORT_SYMBOL
++0x19a304ba    usb_disabled    vmlinux EXPORT_SYMBOL_GPL
++0x48f20051    __ip_route_output_key   vmlinux EXPORT_SYMBOL_GPL
++0x5e7f4920    snd_pcm_format_set_silence      vmlinux EXPORT_SYMBOL
++0x9ef5a297    blk_queue_invalidate_tags       vmlinux EXPORT_SYMBOL
++0xffb6db4a    remove_irq      vmlinux EXPORT_SYMBOL_GPL
++0x93a6e0b2    io_schedule     vmlinux EXPORT_SYMBOL
++0xa604bba5    cpufreq_notify_transition       vmlinux EXPORT_SYMBOL_GPL
++0xb9c425de    register_syscore_ops    vmlinux EXPORT_SYMBOL_GPL
++0x7317fc49    disk_part_iter_next     vmlinux EXPORT_SYMBOL_GPL
++0xc4c6c770    block_write_end vmlinux EXPORT_SYMBOL
++0x437e0be6    pid_vnr vmlinux EXPORT_SYMBOL_GPL
++0xcb476f4a    cfb_fillrect    vmlinux EXPORT_SYMBOL
++0xc6241aec    cfg80211_roamed_bss     vmlinux EXPORT_SYMBOL
++0x44336387    __xfrm_decode_session   vmlinux EXPORT_SYMBOL
++0xf803fe39    bitmap_set      vmlinux EXPORT_SYMBOL
++0x1bbcbb78    __pagevec_lru_add       vmlinux EXPORT_SYMBOL
++0xd1b2db37    tracepoint_probe_register_noupdate      vmlinux EXPORT_SYMBOL_GPL
++0x230e0698    __clocksource_updatefreq_scale  vmlinux EXPORT_SYMBOL_GPL
++0xd8004073    sdhci_runtime_resume_host       vmlinux EXPORT_SYMBOL_GPL
++0x04369954    devm_regmap_init        vmlinux EXPORT_SYMBOL_GPL
++0xa2a36526    tty_port_lower_dtr_rts  vmlinux EXPORT_SYMBOL
++0xf369df34    wiphy_rfkill_stop_polling       vmlinux EXPORT_SYMBOL
++0x253ec879    netlink_set_err vmlinux EXPORT_SYMBOL
++0x71d7bf40    alloc_netdev_mqs        vmlinux EXPORT_SYMBOL
++0x336154ca    rcutorture_record_test_transition       vmlinux EXPORT_SYMBOL_GPL
++0x1aa1c9f2    make_kprojid    vmlinux EXPORT_SYMBOL
++0xa42a123d    bus_register_notifier   vmlinux EXPORT_SYMBOL_GPL
++0xd2cf977d    gpiochip_add    vmlinux EXPORT_SYMBOL_GPL
++0xd3c40b56    inet_listen     vmlinux EXPORT_SYMBOL
++0xfdc9a24f    __dst_destroy_metrics_generic   vmlinux EXPORT_SYMBOL
++0x44e276d8    skb_queue_purge vmlinux EXPORT_SYMBOL
++0x588eccde    get_unmapped_area       vmlinux EXPORT_SYMBOL
++0x0f29f7c9    add_to_page_cache_lru   vmlinux EXPORT_SYMBOL_GPL
++0xb7d4b252    iommu_present   vmlinux EXPORT_SYMBOL_GPL
++0x01c483a9    v4l2_get_timestamp      vmlinux EXPORT_SYMBOL_GPL
++0xbf041102    register_vt_notifier    vmlinux EXPORT_SYMBOL_GPL
++0xf85885d1    nci_unregister_device   vmlinux EXPORT_SYMBOL
++0x07b52e38    rtnl_unregister vmlinux EXPORT_SYMBOL_GPL
++0xe3bc40f6    dpcm_be_dai_trigger     vmlinux EXPORT_SYMBOL_GPL
++0xfbed2f3c    snd_soc_info_volsw_range        vmlinux EXPORT_SYMBOL_GPL
++0x9545974d    blk_rq_map_user vmlinux EXPORT_SYMBOL
++0x693ca44e    jbd2_journal_clear_features     vmlinux EXPORT_SYMBOL
++0x538410d3    generic_pipe_buf_release        vmlinux EXPORT_SYMBOL
++0x8878cfa6    gether_cleanup  vmlinux EXPORT_SYMBOL
++0xc1c72997    platform_bus_type       vmlinux EXPORT_SYMBOL_GPL
++0x2c61162c    drm_fb_helper_check_var vmlinux EXPORT_SYMBOL
++0x7a8cea07    bt_accept_unlink        vmlinux EXPORT_SYMBOL
++0x61812beb    nf_ct_gre_keymap_add    vmlinux EXPORT_SYMBOL_GPL
++0xcf596042    d_find_alias    vmlinux EXPORT_SYMBOL
++0x81d10f5f    trace_seq_putc  vmlinux EXPORT_SYMBOL
++0x760a0f4f    yield   vmlinux EXPORT_SYMBOL
++0xac472389    iio_buffer_register     vmlinux EXPORT_SYMBOL
++0x5dd590c3    sdhci_pltfm_pmops       vmlinux EXPORT_SYMBOL_GPL
++0x0c5b9900    xt_check_target vmlinux EXPORT_SYMBOL_GPL
++0xb67c64fd    __tracepoint_kfree_skb  vmlinux EXPORT_SYMBOL_GPL
++0xd6c2e04b    __tracepoint_napi_poll  vmlinux EXPORT_SYMBOL_GPL
++0x01bb81cc    netdev_upper_dev_unlink vmlinux EXPORT_SYMBOL
++0x5bb9daec    __sg_page_iter_start    vmlinux EXPORT_SYMBOL
++0xac3d64d9    fsstack_copy_attr_all   vmlinux EXPORT_SYMBOL_GPL
++0xda48e711    sdio_claim_irq  vmlinux EXPORT_SYMBOL_GPL
++0x1dc36131    fb_destroy_modedb       vmlinux EXPORT_SYMBOL
++0xca2159d7    udp6_lib_lookup vmlinux EXPORT_SYMBOL_GPL
++0xbf58f5e7    xfrm_init_replay        vmlinux EXPORT_SYMBOL
++0xfb74be78    udp4_lib_lookup vmlinux EXPORT_SYMBOL_GPL
++0x419cfeed    __nf_ct_try_assign_helper       vmlinux EXPORT_SYMBOL_GPL
++0x610dbc32    genl_unregister_ops     vmlinux EXPORT_SYMBOL
++0x9e2000a7    memcpy_toiovecend       vmlinux EXPORT_SYMBOL
++0x3fc5d39f    snd_jack_report vmlinux EXPORT_SYMBOL
++0x93949c2a    inode_sb_list_add       vmlinux EXPORT_SYMBOL_GPL
++0x3d4ee67b    inode_init_always       vmlinux EXPORT_SYMBOL
++0x38883d79    d_invalidate    vmlinux EXPORT_SYMBOL
++0xa0b04675    vmalloc_32      vmlinux EXPORT_SYMBOL
++0xedca9389    pid_task        vmlinux EXPORT_SYMBOL
++0xc1c2b8e5    scsi_command_normalize_sense    vmlinux EXPORT_SYMBOL
++0x4d0d163d    copy_page       vmlinux EXPORT_SYMBOL
++0xe0becdbc    set_h245_addr_hook      vmlinux EXPORT_SYMBOL_GPL
++0xd9a79782    seq_print_acct  vmlinux EXPORT_SYMBOL_GPL
++0xbc9f30d7    textsearch_unregister   vmlinux EXPORT_SYMBOL
++0xf54c51a2    dma_pool_free   vmlinux EXPORT_SYMBOL
++0x32fd447a    monotonic_to_bootbased  vmlinux EXPORT_SYMBOL_GPL
++0x45a6be13    cpufreq_sysfs_remove_file       vmlinux EXPORT_SYMBOL
++0x9a5723c8    input_register_handler  vmlinux EXPORT_SYMBOL
++0x0f618e15    drm_class_device_unregister     vmlinux EXPORT_SYMBOL_GPL
++0xbae73813    inet6_csk_bind_conflict vmlinux EXPORT_SYMBOL_GPL
++0xa35de80f    ipv4_config     vmlinux EXPORT_SYMBOL
++0x7411b488    netif_carrier_on        vmlinux EXPORT_SYMBOL
++0x1212d241    fib_rules_lookup        vmlinux EXPORT_SYMBOL_GPL
++0xb0b847ac    __bitmap_full   vmlinux EXPORT_SYMBOL
++0x4059792f    print_hex_dump  vmlinux EXPORT_SYMBOL
++0x99d40bce    cfg80211_del_sta        vmlinux EXPORT_SYMBOL
++0xe8068f48    ip6_route_output        vmlinux EXPORT_SYMBOL
++0xb57e5e86    __dst_free      vmlinux EXPORT_SYMBOL
++0x9fb986a9    inode_newsize_ok        vmlinux EXPORT_SYMBOL
++0xf39a1727    dev_pm_qos_add_notifier vmlinux EXPORT_SYMBOL_GPL
++0xbb6297fd    drm_mode_group_init_legacy_group        vmlinux EXPORT_SYMBOL
++0xd3ce735a    drm_crtc_helper_set_config      vmlinux EXPORT_SYMBOL
++0xa68b2c0b    pn_sock_get_port        vmlinux EXPORT_SYMBOL
++0x04797338    inet_csk_destroy_sock   vmlinux EXPORT_SYMBOL
++0x050e881c    inet_peer_base_init     vmlinux EXPORT_SYMBOL_GPL
++0x84b183ae    strncmp vmlinux EXPORT_SYMBOL
++0xb6f24459    crypto_register_shashes vmlinux EXPORT_SYMBOL_GPL
++0x1e26be3b    get_anon_bdev   vmlinux EXPORT_SYMBOL
++0x6b29a1fa    ring_buffer_event_length        vmlinux EXPORT_SYMBOL_GPL
++0x5634e278    __clk_get_flags vmlinux EXPORT_SYMBOL_GPL
++0x2e1ca751    clk_put vmlinux EXPORT_SYMBOL
++0xf474a207    usb_gadget_config_buf   vmlinux EXPORT_SYMBOL_GPL
++0x20838fc5    __pm_runtime_idle       vmlinux EXPORT_SYMBOL_GPL
++0x062de44d    sock_kfree_s    vmlinux EXPORT_SYMBOL
++0x3796bdcc    snd_pcm_format_little_endian    vmlinux EXPORT_SYMBOL
++0xa34f1ef5    crc32_le        vmlinux EXPORT_SYMBOL
++0xf54bd49b    lcm     vmlinux EXPORT_SYMBOL_GPL
++0x13354608    scatterwalk_map_and_copy        vmlinux EXPORT_SYMBOL_GPL
++0xf2bec139    empty_aops      vmlinux EXPORT_SYMBOL
++0x45755a66    __task_pid_nr_ns        vmlinux EXPORT_SYMBOL
++0xcbc23c9a    ethtool_op_get_link     vmlinux EXPORT_SYMBOL
++0x5735fbd5    read_cache_pages        vmlinux EXPORT_SYMBOL
++0x4aadeb9a    ring_buffer_alloc_read_page     vmlinux EXPORT_SYMBOL_GPL
++0x2f3f62cd    v4l2_try_ext_ctrls      vmlinux EXPORT_SYMBOL
++0x5d12e48f    input_event_to_user     vmlinux EXPORT_SYMBOL_GPL
++0x6947468c    input_unregister_device vmlinux EXPORT_SYMBOL
++0x91600a8e    usb_string_id   vmlinux EXPORT_SYMBOL_GPL
++0xcc924d52    regulator_disable_regmap        vmlinux EXPORT_SYMBOL_GPL
++0x3a4402b4    ip_generic_getfrag      vmlinux EXPORT_SYMBOL
++0x6308d2cf    call_netdevice_notifiers        vmlinux EXPORT_SYMBOL
++0xc02df0b8    snd_soc_pm_ops  vmlinux EXPORT_SYMBOL_GPL
++0xf9436986    crypto_dequeue_request  vmlinux EXPORT_SYMBOL_GPL
++0xb6555d54    crypto_enqueue_request  vmlinux EXPORT_SYMBOL_GPL
++0x6c2dc956    fat_add_entries vmlinux EXPORT_SYMBOL_GPL
++0xb7fc7a60    thaw_bdev       vmlinux EXPORT_SYMBOL
++0x99a170f8    kmem_cache_alloc_trace  vmlinux EXPORT_SYMBOL
++0x06f22ca2    irq_create_mapping      vmlinux EXPORT_SYMBOL_GPL
++0x992e5dbd    mii_nway_restart        vmlinux EXPORT_SYMBOL
++0xa6a0a273    max77693_write_reg      vmlinux EXPORT_SYMBOL_GPL
++0xa6b21ef2    dpm_suspend_end vmlinux EXPORT_SYMBOL_GPL
++0x27f9262d    sk_run_filter   vmlinux EXPORT_SYMBOL
++0x8bfe698b    netdev_rx_csum_fault    vmlinux EXPORT_SYMBOL
++0x9e61bb05    set_freezable   vmlinux EXPORT_SYMBOL
++0xd5418207    devres_release_group    vmlinux EXPORT_SYMBOL_GPL
++0x45669e2c    drm_fb_helper_restore_fbdev_mode        vmlinux EXPORT_SYMBOL
++0x93fcb0ed    bt_sock_reclassify_lock vmlinux EXPORT_SYMBOL
++0xb6d8be2d    ipv6_push_nfrag_opts    vmlinux EXPORT_SYMBOL
++0x8cdb54d7    ipt_register_table      vmlinux EXPORT_SYMBOL
++0xcc0aef97    neigh_sysctl_unregister vmlinux EXPORT_SYMBOL
++0xe56a9336    snd_pcm_format_width    vmlinux EXPORT_SYMBOL
++0x9077c297    blk_abort_request       vmlinux EXPORT_SYMBOL_GPL
++0x6ed8eb1f    extcon_register_notifier        vmlinux EXPORT_SYMBOL_GPL
++0xc9561772    fb_destroy_modelist     vmlinux EXPORT_SYMBOL_GPL
++0xf494fae4    tcp_peer_is_proven      vmlinux EXPORT_SYMBOL_GPL
++0xdc70cab5    __scm_destroy   vmlinux EXPORT_SYMBOL
++0xfb2acf00    snd_mixer_oss_notify_callback   vmlinux EXPORT_SYMBOL
++0x3a016c77    d_move  vmlinux EXPORT_SYMBOL
++0x5091b823    ring_buffer_read_start  vmlinux EXPORT_SYMBOL_GPL
++0x171751ed    sdio_writeb_readb       vmlinux EXPORT_SYMBOL_GPL
++0x3d94fdae    usb_put_phy     vmlinux EXPORT_SYMBOL_GPL
++0xfbf7bde5    drm_crtc_cleanup        vmlinux EXPORT_SYMBOL
++0x52aaee97    amba_ahb_device_add_res vmlinux EXPORT_SYMBOL_GPL
++0xd0706e35    phy_pm_runtime_put      vmlinux EXPORT_SYMBOL_GPL
++0x0ff178f6    __aeabi_idivmod vmlinux EXPORT_SYMBOL
++0xfb11005b    ipcomp_destroy  vmlinux EXPORT_SYMBOL_GPL
++0x6f81b189    dev_addr_del_multiple   vmlinux EXPORT_SYMBOL
++0xf5ce8c40    touch_atime     vmlinux EXPORT_SYMBOL
++0x53614269    get_cpu_idle_time_us    vmlinux EXPORT_SYMBOL_GPL
++0x61c243fc    mod_timer_pending       vmlinux EXPORT_SYMBOL
++0xf821b501    device_set_wakeup_capable       vmlinux EXPORT_SYMBOL_GPL
++0x80bbfeb1    s3c_gpio_cfgall_range   vmlinux EXPORT_SYMBOL_GPL
++0x10081d73    s3c_gpio_cfgpin_range   vmlinux EXPORT_SYMBOL_GPL
++0x75464443    phonet_proto_unregister vmlinux EXPORT_SYMBOL
++0x7d6fed76    rtnl_configure_link     vmlinux EXPORT_SYMBOL
++0x8c844510    sock_wmalloc    vmlinux EXPORT_SYMBOL
++0xbaf75338    snd_soc_codec_writable_register vmlinux EXPORT_SYMBOL_GPL
++0x1e6d26a8    strstr  vmlinux EXPORT_SYMBOL
++0xea6f9ca2    task_user_regset_view   vmlinux EXPORT_SYMBOL_GPL
++0x4de17ab3    usb_state_string        vmlinux EXPORT_SYMBOL_GPL
++0x349cba85    strchr  vmlinux EXPORT_SYMBOL
++0xb83a0cc6    perf_event_disable      vmlinux EXPORT_SYMBOL_GPL
++0x3b5965e0    inet_csk_listen_stop    vmlinux EXPORT_SYMBOL_GPL
++0x6be59bed    kobject_create_and_add  vmlinux EXPORT_SYMBOL_GPL
++0xdced71ac    setup_new_exec  vmlinux EXPORT_SYMBOL
++0xdb8a1b3f    usermodehelper_read_trylock     vmlinux EXPORT_SYMBOL_GPL
++0x7c9ad2eb    usb_wait_anchor_empty_timeout   vmlinux EXPORT_SYMBOL_GPL
++0xf2fca922    uart_parse_options      vmlinux EXPORT_SYMBOL_GPL
++0x7f63b31e    _memcpy_toio    vmlinux EXPORT_SYMBOL
++0x3e3fcdf2    xfrm_state_lookup_byaddr        vmlinux EXPORT_SYMBOL
++0x2b538790    pskb_expand_head        vmlinux EXPORT_SYMBOL
++0xdb67d9bb    of_i2c_register_devices vmlinux EXPORT_SYMBOL
++0x9f7314d6    wakeup_source_prepare   vmlinux EXPORT_SYMBOL_GPL
++0x2a828cb7    drm_noop        vmlinux EXPORT_SYMBOL
++0x3d3c540f    elf_hwcap       vmlinux EXPORT_SYMBOL
++0xa045219b    fuse_do_ioctl   vmlinux EXPORT_SYMBOL_GPL
++0x8fa5cf61    pm_qos_update_request   vmlinux EXPORT_SYMBOL_GPL
++0x73514fba    i2c_release_client      vmlinux EXPORT_SYMBOL
++0x168db450    take_over_console       vmlinux EXPORT_SYMBOL
++0x0aa13d05    __raw_readsw    vmlinux EXPORT_SYMBOL
++0x816a1ee5    rtnl_link_register      vmlinux EXPORT_SYMBOL_GPL
++0x9fd1a952    sk_set_memalloc vmlinux EXPORT_SYMBOL_GPL
++0x8605ed02    lock_may_write  vmlinux EXPORT_SYMBOL
++0xb24e73ff    bh_submit_read  vmlinux EXPORT_SYMBOL
++0x455db47d    dma_mark_declared_memory_occupied       vmlinux EXPORT_SYMBOL
++0x1a65f4ad    __arm_ioremap_pfn       vmlinux EXPORT_SYMBOL
++0x955e8436    eth_change_mtu  vmlinux EXPORT_SYMBOL
++0xa300e599    eth_header_parse        vmlinux EXPORT_SYMBOL
++0x42977ad4    __hw_addr_del_multiple  vmlinux EXPORT_SYMBOL
++0xf57de517    bdev_stack_limits       vmlinux EXPORT_SYMBOL
++0x25bed5a1    static_key_slow_dec_deferred    vmlinux EXPORT_SYMBOL_GPL
++0xd2aaeb4e    kmsg_dump_get_buffer    vmlinux EXPORT_SYMBOL_GPL
++0xedb320d6    nf_nat_pptp_hook_exp_gre        vmlinux EXPORT_SYMBOL_GPL
++0xdc0a9f66    sock_wake_async vmlinux EXPORT_SYMBOL
++0x68e05d57    getrawmonotonic vmlinux EXPORT_SYMBOL
++0xee715ef8    lg_global_unlock        vmlinux EXPORT_SYMBOL
++0xbebb2820    crypto_register_algs    vmlinux EXPORT_SYMBOL_GPL
++0xccc2bc05    fat_free_clusters       vmlinux EXPORT_SYMBOL_GPL
++0xde99c012    jbd2_complete_transaction       vmlinux EXPORT_SYMBOL
++0x60599993    __set_page_dirty_buffers        vmlinux EXPORT_SYMBOL
++0x8b775d3a    __wake_up_locked        vmlinux EXPORT_SYMBOL_GPL
++0x93eb18c6    of_platform_device_create       vmlinux EXPORT_SYMBOL
++0x9e5bfa34    bt_sock_poll    vmlinux EXPORT_SYMBOL
++0x7e98f5ff    sock_prot_inuse_add     vmlinux EXPORT_SYMBOL_GPL
++0xf9e73082    scnprintf       vmlinux EXPORT_SYMBOL
++0xa1b4cc6a    aead_geniv_exit vmlinux EXPORT_SYMBOL_GPL
++0xa7001f92    mod_zone_page_state     vmlinux EXPORT_SYMBOL
++0x92e79788    perf_event_refresh      vmlinux EXPORT_SYMBOL_GPL
++0x77e7babf    usb_hcd_platform_shutdown       vmlinux EXPORT_SYMBOL_GPL
++0x6d4d6df5    s3c_gpio_cfgpin vmlinux EXPORT_SYMBOL
++0x7f250a18    tcf_register_action     vmlinux EXPORT_SYMBOL
++0x41852af3    blk_add_request_payload vmlinux EXPORT_SYMBOL_GPL
++0x8bf05477    pm_runtime_autosuspend_expiration       vmlinux EXPORT_SYMBOL_GPL
++0xea25f714    rtnl_link_unregister    vmlinux EXPORT_SYMBOL_GPL
++0x5f75b2b7    snd_soc_dapm_enable_pin vmlinux EXPORT_SYMBOL_GPL
++0x87879778    copy_strings_kernel     vmlinux EXPORT_SYMBOL
++0x731b81f1    __wait_on_bit   vmlinux EXPORT_SYMBOL
++0x18838e93    hrtimer_get_remaining   vmlinux EXPORT_SYMBOL_GPL
++0x0be4ca5a    extcon_set_state        vmlinux EXPORT_SYMBOL_GPL
++0xacdf7eb6    led_trigger_register_simple     vmlinux EXPORT_SYMBOL_GPL
++0x20645642    drm_debug       vmlinux EXPORT_SYMBOL
++0x5f41d1f8    rdev_get_id     vmlinux EXPORT_SYMBOL_GPL
++0xf6f440a6    tcp_enter_memory_pressure       vmlinux EXPORT_SYMBOL
++0x3b9a9d19    skb_add_rx_frag vmlinux EXPORT_SYMBOL
++0x32b2bc89    snd_soc_write   vmlinux EXPORT_SYMBOL_GPL
++0x5b44d926    snd_soc_get_xr_sx       vmlinux EXPORT_SYMBOL_GPL
++0xf1395b13    snd_soc_put_xr_sx       vmlinux EXPORT_SYMBOL_GPL
++0x4982a57f    probe_kernel_write      vmlinux EXPORT_SYMBOL_GPL
++0x811dc334    usb_unregister_notify   vmlinux EXPORT_SYMBOL_GPL
++0xa6f7283b    arp_create      vmlinux EXPORT_SYMBOL
++0x660b5392    jbd2_journal_get_create_access  vmlinux EXPORT_SYMBOL
++0x99dd4a27    no_llseek       vmlinux EXPORT_SYMBOL
++0x72532806    _raw_read_unlock_irq    vmlinux EXPORT_SYMBOL
++0xe4719990    rt_mutex_timed_lock     vmlinux EXPORT_SYMBOL_GPL
++0xb5d9454c    printk_emit     vmlinux EXPORT_SYMBOL
++0x801e5a15    st_sensors_check_device_support vmlinux EXPORT_SYMBOL
++0xeec77f6d    iio_map_array_unregister        vmlinux EXPORT_SYMBOL_GPL
++0x6390efda    of_modalias_node        vmlinux EXPORT_SYMBOL_GPL
++0x7ac03539    tty_port_alloc_xmit_buf vmlinux EXPORT_SYMBOL
++0x5cebb76e    vfs_truncate    vmlinux EXPORT_SYMBOL_GPL
++0xfc52a8aa    mmc_gpio_request_cd     vmlinux EXPORT_SYMBOL
++0xf7a4e432    mmc_gpio_request_ro     vmlinux EXPORT_SYMBOL
++0x74d52889    rtc_irq_set_freq        vmlinux EXPORT_SYMBOL_GPL
++0x8e9efd84    dma_declare_coherent_memory     vmlinux EXPORT_SYMBOL
++0xfcfa03ff    fb_videomode_to_modelist        vmlinux EXPORT_SYMBOL
++0x789c0277    nfc_unregister_device   vmlinux EXPORT_SYMBOL
++0x48744ce2    lro_receive_frags       vmlinux EXPORT_SYMBOL
++0xf6851d5f    register_sysctl_paths   vmlinux EXPORT_SYMBOL
++0x90a4a466    generic_show_options    vmlinux EXPORT_SYMBOL
++0x74dd4a76    pagecache_write_begin   vmlinux EXPORT_SYMBOL
++0x7b42b5d4    drm_mode_copy   vmlinux EXPORT_SYMBOL
++0x6a7c03c7    asoc_dma_platform_register      vmlinux EXPORT_SYMBOL_GPL
++0xc6cbbc89    capable vmlinux EXPORT_SYMBOL
++0xd07125d9    spi_finalize_current_message    vmlinux EXPORT_SYMBOL_GPL
++0xf5514ce6    dev_pm_qos_add_request  vmlinux EXPORT_SYMBOL_GPL
++0xb316e246    nf_afinfo       vmlinux EXPORT_SYMBOL
++0x4ef5bcf4    perf_swevent_get_recursion_context      vmlinux EXPORT_SYMBOL_GPL
++0xab7e3362    irq_find_mapping        vmlinux EXPORT_SYMBOL_GPL
++0xbcf89ab6    __wake_up_sync  vmlinux EXPORT_SYMBOL_GPL
++0xc8b57c27    autoremove_wake_function        vmlinux EXPORT_SYMBOL
++0x36aa3266    hid_debug_event vmlinux EXPORT_SYMBOL_GPL
++0x9ed21fce    mmc_can_trim    vmlinux EXPORT_SYMBOL
++0x5658ad69    v4l2_async_register_subdev      vmlinux EXPORT_SYMBOL
++0x99781445    input_set_capability    vmlinux EXPORT_SYMBOL
++0xf3343f80    drm_mode_create_tv_properties   vmlinux EXPORT_SYMBOL
++0x69fefbb6    nf_ct_port_tuple_to_nlattr      vmlinux EXPORT_SYMBOL_GPL
++0xd9a9bb30    getname vmlinux EXPORT_SYMBOL
++0xe7ffe877    pcpu_base_addr  vmlinux EXPORT_SYMBOL_GPL
++0x131e7ee8    drm_fb_helper_hotplug_event     vmlinux EXPORT_SYMBOL
++0x983f0520    drm_fb_helper_initial_config    vmlinux EXPORT_SYMBOL
++0x469972c2    give_up_console vmlinux EXPORT_SYMBOL
++0x300573d1    nf_conntrack_helper_register    vmlinux EXPORT_SYMBOL_GPL
++0x2597c27d    snd_seq_root    vmlinux EXPORT_SYMBOL
++0x9a11a0fc    crypto_attr_alg_name    vmlinux EXPORT_SYMBOL_GPL
++0xa0f2a42b    debugfs_create_regset32 vmlinux EXPORT_SYMBOL_GPL
++0x3e08c129    drm_mode_find_dmt       vmlinux EXPORT_SYMBOL
++0xbc8b0f41    xfrm_calg_get_byid      vmlinux EXPORT_SYMBOL_GPL
++0xf20dabd8    free_irq        vmlinux EXPORT_SYMBOL
++0x9073a3d4    usb_hc_died     vmlinux EXPORT_SYMBOL_GPL
++0xe61a6d2f    gpio_unexport   vmlinux EXPORT_SYMBOL_GPL
++0xdf58d91e    pinctrl_dev_get_name    vmlinux EXPORT_SYMBOL_GPL
++0x4c3b5878    ieee80211_get_response_rate     vmlinux EXPORT_SYMBOL
++0xa6b9609a    jbd2_journal_init_inode vmlinux EXPORT_SYMBOL
++0xe91ef2b5    deactivate_locked_super vmlinux EXPORT_SYMBOL
++0x0280cf55    filemap_fdatawait       vmlinux EXPORT_SYMBOL
++0x134178d9    v4l2_m2m_fop_mmap       vmlinux EXPORT_SYMBOL_GPL
++0x9091c717    netdev_class_create_file        vmlinux EXPORT_SYMBOL
++0x4f816e9b    snd_pcm_format_big_endian       vmlinux EXPORT_SYMBOL
++0x09d44df9    in_lock_functions       vmlinux EXPORT_SYMBOL
++0x509817cf    vprintk_emit    vmlinux EXPORT_SYMBOL
++0x4c571d12    cfg80211_cqm_pktloss_notify     vmlinux EXPORT_SYMBOL
++0x8b260b7f    ip6_tnl_xmit_ctl        vmlinux EXPORT_SYMBOL_GPL
++0x7b9e609a    ip6_sk_update_pmtu      vmlinux EXPORT_SYMBOL_GPL
++0x199db92b    netdev_rx_handler_unregister    vmlinux EXPORT_SYMBOL_GPL
++0x4cdf24a6    skb_copy_datagram_const_iovec   vmlinux EXPORT_SYMBOL
++0xb994401f    kernel_getpeername      vmlinux EXPORT_SYMBOL
++0x7b10e656    sysfs_chmod_file        vmlinux EXPORT_SYMBOL_GPL
++0x55d7c934    find_module     vmlinux EXPORT_SYMBOL_GPL
++0x548b482c    rt_mutex_lock   vmlinux EXPORT_SYMBOL_GPL
++0x39533602    media_entity_graph_walk_start   vmlinux EXPORT_SYMBOL_GPL
++0x51ef2459    platform_driver_probe   vmlinux EXPORT_SYMBOL_GPL
++0xeb93a8ee    serial8250_do_set_termios       vmlinux EXPORT_SYMBOL
++0x8afc7ce3    __devm_of_phy_provider_register vmlinux EXPORT_SYMBOL_GPL
++0x548fedb9    skb_complete_wifi_ack   vmlinux EXPORT_SYMBOL_GPL
++0x11f7ed4c    hex_to_bin      vmlinux EXPORT_SYMBOL
++0x9aeecd64    simple_pin_fs   vmlinux EXPORT_SYMBOL
++0x5635a60a    vmalloc_user    vmlinux EXPORT_SYMBOL
++0xd36ab13e    posix_clock_unregister  vmlinux EXPORT_SYMBOL_GPL
++0x1fe9f800    unregister_cpu_notifier vmlinux EXPORT_SYMBOL
++0xb59a9548    vb2_expbuf      vmlinux EXPORT_SYMBOL_GPL
++0xf6eb0d71    input_event     vmlinux EXPORT_SYMBOL
++0xfc3a261f    dev_get_regmap  vmlinux EXPORT_SYMBOL_GPL
++0x89d145ed    pin_config_get  vmlinux EXPORT_SYMBOL
++0xc54fc2d7    devm_pinctrl_put        vmlinux EXPORT_SYMBOL_GPL
++0x9671e047    devm_pinctrl_get        vmlinux EXPORT_SYMBOL_GPL
++0x4d45d89e    udp_memory_allocated    vmlinux EXPORT_SYMBOL
++0x3e8b4fda    tc_classify     vmlinux EXPORT_SYMBOL
++0x98509e55    sock_no_sendpage        vmlinux EXPORT_SYMBOL
++0x7bd6700d    blk_pre_runtime_suspend vmlinux EXPORT_SYMBOL
++0x6444b7bb    iio_read_channel_raw    vmlinux EXPORT_SYMBOL_GPL
++0x70120108    thermal_generate_netlink_event  vmlinux EXPORT_SYMBOL_GPL
++0x800e4ffa    __muldi3        vmlinux EXPORT_SYMBOL
++0x4c1182cb    bitmap_scnprintf        vmlinux EXPORT_SYMBOL
++0xd7b4599b    __idr_get_new_above     vmlinux EXPORT_SYMBOL
++0x368dc456    proc_create_data        vmlinux EXPORT_SYMBOL
++0x4d405db8    param_ops_string        vmlinux EXPORT_SYMBOL
++0xdd021b6b    get_current_tty vmlinux EXPORT_SYMBOL_GPL
++0xabbaaf4c    kernel_getsockname      vmlinux EXPORT_SYMBOL
++0x5caf4413    kernel_sendmsg  vmlinux EXPORT_SYMBOL
++0x3971b4df    snd_ecards_limit        vmlinux EXPORT_SYMBOL
++0xd77a5aa5    __bitmap_and    vmlinux EXPORT_SYMBOL
++0xfac05b29    unregister_gadget_item  vmlinux EXPORT_SYMBOL
++0x268930d0    uart_register_driver    vmlinux EXPORT_SYMBOL
++0xace7ae5c    xfrm_alloc_spi  vmlinux EXPORT_SYMBOL
++0x0a4a1a2f    blk_rq_err_bytes        vmlinux EXPORT_SYMBOL_GPL
++0x6d414f53    crypto_blkcipher_type   vmlinux EXPORT_SYMBOL_GPL
++0x2ffe9a6b    crypto_givcipher_type   vmlinux EXPORT_SYMBOL_GPL
++0xe5ddcbd8    nfc_targets_found       vmlinux EXPORT_SYMBOL
++0x028f3057    nf_log_packet   vmlinux EXPORT_SYMBOL
++0xc8949349    qdisc_tree_decrease_qlen        vmlinux EXPORT_SYMBOL
++0x7d16c025    dev_remove_pack vmlinux EXPORT_SYMBOL
++0xf88eb7f2    rq_flush_dcache_pages   vmlinux EXPORT_SYMBOL_GPL
++0x2d8764e5    blkcipher_walk_virt     vmlinux EXPORT_SYMBOL_GPL
++0x5fce0dc6    posix_lock_file vmlinux EXPORT_SYMBOL
++0x71a672ef    dmam_pool_destroy       vmlinux EXPORT_SYMBOL
++0x3832da09    set_page_dirty  vmlinux EXPORT_SYMBOL
++0xe4937b31    i2c_bit_algo    vmlinux EXPORT_SYMBOL
++0x2c256e1f    input_scancode_to_scalar        vmlinux EXPORT_SYMBOL
++0x758978d2    spi_get_next_queued_message     vmlinux EXPORT_SYMBOL_GPL
++0xde9360ba    totalram_pages  vmlinux EXPORT_SYMBOL
++0xacc53440    video_device_alloc      vmlinux EXPORT_SYMBOL
++0x331f6073    udp_disconnect  vmlinux EXPORT_SYMBOL
++0x8a5c060e    nf_conntrack_l4proto_udp4       vmlinux EXPORT_SYMBOL_GPL
++0x492ab82c    dev_uc_unsync   vmlinux EXPORT_SYMBOL
++0xb1615d69    dev_mc_unsync   vmlinux EXPORT_SYMBOL
++0xa73acb8d    dump_seek       vmlinux EXPORT_SYMBOL
++0xea63afac    usb_free_streams        vmlinux EXPORT_SYMBOL_GPL
++0x0fb8623c    regcache_cache_only     vmlinux EXPORT_SYMBOL_GPL
++0xb89f40b3    __register_chrdev       vmlinux EXPORT_SYMBOL
++0x4ed5e0d7    v4l2_chip_match_host    vmlinux EXPORT_SYMBOL
++0x78272b1e    bus_get_kset    vmlinux EXPORT_SYMBOL_GPL
++0x87c0bce8    net_dma_find_channel    vmlinux EXPORT_SYMBOL
++0xc31f408b    __display_entity_register       vmlinux EXPORT_SYMBOL_GPL
++0x5b1cfbcd    of_get_fb_videomode     vmlinux EXPORT_SYMBOL_GPL
++0xe6775a2f    fb_show_logo    vmlinux EXPORT_SYMBOL
++0xa290f4a9    fb_pan_display  vmlinux EXPORT_SYMBOL
++0x61c2dac6    kstrtoll_from_user      vmlinux EXPORT_SYMBOL
++0x83904bc7    st_sensors_deallocate_trigger   vmlinux EXPORT_SYMBOL
++0x7bc41c7c    rtc_class_close vmlinux EXPORT_SYMBOL_GPL
++0x218b226c    sec_bulk_write  vmlinux EXPORT_SYMBOL_GPL
++0xf09de776    get_random_int  vmlinux EXPORT_SYMBOL
++0x5a937d99    blk_queue_stack_limits  vmlinux EXPORT_SYMBOL
++0x174b7df6    free_vm_area    vmlinux EXPORT_SYMBOL_GPL
++0x8ffa3ccd    devres_alloc    vmlinux EXPORT_SYMBOL_GPL
++0x956a91ba    gpio_get_value_cansleep vmlinux EXPORT_SYMBOL_GPL
++0x92886ef2    udp_lib_setsockopt      vmlinux EXPORT_SYMBOL
++0xc4a35da7    udp_lib_getsockopt      vmlinux EXPORT_SYMBOL
++0xdb1ed3be    nf_conntrack_free       vmlinux EXPORT_SYMBOL_GPL
++0x96898769    sysfs_format_mac        vmlinux EXPORT_SYMBOL
++0x15604324    sk_send_sigurg  vmlinux EXPORT_SYMBOL
++0x8fca87b8    proc_set_size   vmlinux EXPORT_SYMBOL
++0x4b5fd49e    dm_kcopyd_do_callback   vmlinux EXPORT_SYMBOL
++0x289bc356    mdiobus_alloc_size      vmlinux EXPORT_SYMBOL
++0xf36e7280    spi_bus_lock    vmlinux EXPORT_SYMBOL_GPL
++0x0c060ece    cfg80211_sched_scan_stopped     vmlinux EXPORT_SYMBOL
++0xab2289f2    drop_super      vmlinux EXPORT_SYMBOL
++0x27e1a049    printk  vmlinux EXPORT_SYMBOL
++0x3194878b    pm_generic_poweroff_noirq       vmlinux EXPORT_SYMBOL_GPL
++0x688f09be    dev_crit        vmlinux EXPORT_SYMBOL
++0xfd94d6cb    drm_get_connector_status_name   vmlinux EXPORT_SYMBOL
++0xbdef1e6b    drm_gem_object_release  vmlinux EXPORT_SYMBOL
++0x36fa2c4a    cfg80211_get_bss        vmlinux EXPORT_SYMBOL
++0xef2e65fd    sk_alloc        vmlinux EXPORT_SYMBOL
++0x096e7523    try_to_release_page     vmlinux EXPORT_SYMBOL
++0xa61b1477    tracepoint_iter_start   vmlinux EXPORT_SYMBOL_GPL
++0x9d05f6c4    ktime_get_clocktai      vmlinux EXPORT_SYMBOL
++0x6a87a478    synchronize_srcu        vmlinux EXPORT_SYMBOL_GPL
++0xa3afa3ce    bus_unregister_notifier vmlinux EXPORT_SYMBOL_GPL
++0xbe001c53    drm_property_add_enum   vmlinux EXPORT_SYMBOL
++0x48c2a99d    drm_helper_resume_force_mode    vmlinux EXPORT_SYMBOL
++0x1258d9d9    regulator_disable       vmlinux EXPORT_SYMBOL_GPL
++0x1b3261e0    klist_iter_init vmlinux EXPORT_SYMBOL_GPL
++0xaeec4fd1    hci_conn_switch_role    vmlinux EXPORT_SYMBOL
++0x8809bdee    kobject_add     vmlinux EXPORT_SYMBOL
++0x10138352    tracing_on      vmlinux EXPORT_SYMBOL_GPL
++0x39aa4754    dma_buf_mmap    vmlinux EXPORT_SYMBOL_GPL
++0x58c6fc51    dma_buf_kmap    vmlinux EXPORT_SYMBOL_GPL
++0x299bbc21    dma_buf_vmap    vmlinux EXPORT_SYMBOL_GPL
++0x5a2579f9    platform_driver_register        vmlinux EXPORT_SYMBOL_GPL
++0xa8d6809d    drm_dp_bw_code_to_link_rate     vmlinux EXPORT_SYMBOL
++0xfd86731b    drm_fb_helper_init      vmlinux EXPORT_SYMBOL
++0xd4880725    __video_source_register vmlinux EXPORT_SYMBOL_GPL
++0xe08f4a3d    devm_of_phy_provider_unregister vmlinux EXPORT_SYMBOL_GPL
++0x61634f05    lock_flocks     vmlinux EXPORT_SYMBOL_GPL
++0x3843f6b8    queue_kthread_work      vmlinux EXPORT_SYMBOL_GPL
++0x8e332478    thermal_zone_get_temp   vmlinux EXPORT_SYMBOL_GPL
++0xdd64085c    platform_driver_unregister      vmlinux EXPORT_SYMBOL_GPL
++0xaa6f23ad    rfkill_get_led_trigger_name     vmlinux EXPORT_SYMBOL
++0x9cab34a6    rfkill_set_led_trigger_name     vmlinux EXPORT_SYMBOL
++0x23b075bd    gnet_stats_copy_queue   vmlinux EXPORT_SYMBOL
++0x12e85778    kstrtol_from_user       vmlinux EXPORT_SYMBOL
++0x331504fa    simple_dir_operations   vmlinux EXPORT_SYMBOL
++0x3eabdee4    of_match_device vmlinux EXPORT_SYMBOL
++0x610e908e    hid_ignore      vmlinux EXPORT_SYMBOL_GPL
++0x3838d3de    usb_get_urb     vmlinux EXPORT_SYMBOL_GPL
++0xd400a944    cfg80211_gtk_rekey_notify       vmlinux EXPORT_SYMBOL
++0x6403e338    tcp_memory_pressure     vmlinux EXPORT_SYMBOL
++0x23a650aa    setattr_copy    vmlinux EXPORT_SYMBOL
++0x6b6b3081    iommu_domain_has_cap    vmlinux EXPORT_SYMBOL_GPL
++0xdd9fe08e    nfc_hci_driver_failure  vmlinux EXPORT_SYMBOL
++0x091cae50    cfg80211_probe_status   vmlinux EXPORT_SYMBOL
++0xa5e8f497    inet_frags_fini vmlinux EXPORT_SYMBOL
++0xff048999    snd_register_oss_device vmlinux EXPORT_SYMBOL
++0x24a94b26    snd_info_get_line       vmlinux EXPORT_SYMBOL
++0x7ba9873c    elv_dispatch_sort       vmlinux EXPORT_SYMBOL
++0x1471fd44    elv_add_request vmlinux EXPORT_SYMBOL
++0x9be7bde4    security_tun_dev_attach vmlinux EXPORT_SYMBOL
++0xf346231f    seq_list_start_head     vmlinux EXPORT_SYMBOL
++0x65d9e877    cpufreq_register_notifier       vmlinux EXPORT_SYMBOL
++0x399ed296    v4l2_subdev_link_validate_default       vmlinux EXPORT_SYMBOL_GPL
++0xfb974dd4    v4l2_ctrl_auto_cluster  vmlinux EXPORT_SYMBOL
++0xd9097364    v4l2_event_dequeue      vmlinux EXPORT_SYMBOL_GPL
++0xd9a8b315    scsi_queue_work vmlinux EXPORT_SYMBOL_GPL
++0xf564412a    __aeabi_ulcmp   vmlinux EXPORT_SYMBOL
++0x67e6edc4    netif_device_attach     vmlinux EXPORT_SYMBOL
++0x6c3962d5    netif_device_detach     vmlinux EXPORT_SYMBOL
++0x7464ec66    netdev_set_default_ethtool_ops  vmlinux EXPORT_SYMBOL_GPL
++0x08cf6c97    snd_soc_dai_digital_mute        vmlinux EXPORT_SYMBOL_GPL
++0x47628784    simple_attr_read        vmlinux EXPORT_SYMBOL_GPL
++0xe4bad1e4    sdhci_pltfm_init        vmlinux EXPORT_SYMBOL_GPL
++0xe3b2bc37    gether_connect  vmlinux EXPORT_SYMBOL
++0x2fe1cc7e    device_rename   vmlinux EXPORT_SYMBOL_GPL
++0xc147be94    drm_i2c_encoder_restore vmlinux EXPORT_SYMBOL
++0x56f369aa    kernel_bind     vmlinux EXPORT_SYMBOL
++0xcd279169    nla_find        vmlinux EXPORT_SYMBOL
++0x5cdf6de2    kernel_read     vmlinux EXPORT_SYMBOL
++0xfcc43f3f    vfs_read        vmlinux EXPORT_SYMBOL
++0xc8add232    ring_buffer_record_disable      vmlinux EXPORT_SYMBOL_GPL
++0xf2e84b50    __devm_release_region   vmlinux EXPORT_SYMBOL
++0xd4292ec2    dev_notice      vmlinux EXPORT_SYMBOL
++0x02e6e099    drm_mode_width  vmlinux EXPORT_SYMBOL
++0xcc248d26    serial8250_suspend_port vmlinux EXPORT_SYMBOL
++0x4e6e8ea7    fg_console      vmlinux EXPORT_SYMBOL
++0xbb9cc562    fl6_merge_options       vmlinux EXPORT_SYMBOL_GPL
++0x20bf8fa2    __inet_hash_nolisten    vmlinux EXPORT_SYMBOL_GPL
++0x9fb3dd30    memcpy_fromiovec        vmlinux EXPORT_SYMBOL
++0x9cde26bf    blk_queue_prep_rq       vmlinux EXPORT_SYMBOL
++0x262f20a8    local_clock     vmlinux EXPORT_SYMBOL_GPL
++0x7ebf0ef8    __nf_nat_l4proto_find   vmlinux EXPORT_SYMBOL_GPL
++0x503bc70a    drm_gem_prime_export    vmlinux EXPORT_SYMBOL
++0x8d6f81b4    __div64_32      vmlinux EXPORT_SYMBOL
++0x93fca811    __get_free_pages        vmlinux EXPORT_SYMBOL
++0xbb189cad    disallow_signal vmlinux EXPORT_SYMBOL
++0xefe5a9bf    usbnet_resume_rx        vmlinux EXPORT_SYMBOL_GPL
++0x1c4116bc    __class_register        vmlinux EXPORT_SYMBOL_GPL
++0x72cae0c9    nfc_driver_failure      vmlinux EXPORT_SYMBOL
++0xc3d70f22    rawv6_mh_filter_register        vmlinux EXPORT_SYMBOL
++0xdbcd416e    sysctl_ip_nonlocal_bind vmlinux EXPORT_SYMBOL
++0xa675804c    utf8s_to_utf16s vmlinux EXPORT_SYMBOL
++0xb4b97c90    pvclock_gtod_register_notifier  vmlinux EXPORT_SYMBOL_GPL
++0xdf9d0875    ns_capable      vmlinux EXPORT_SYMBOL
++0x13ba72ba    usb_free_coherent       vmlinux EXPORT_SYMBOL_GPL
++0x4671c723    rawv6_mh_filter_unregister      vmlinux EXPORT_SYMBOL
++0x5855bb11    blk_queue_resize_tags   vmlinux EXPORT_SYMBOL
++0x5159ff6c    mmc_fixup_device        vmlinux EXPORT_SYMBOL
++0x186b8590    ipv4_specific   vmlinux EXPORT_SYMBOL
++0x9d5e9b60    nf_ct_l3proto_find_get  vmlinux EXPORT_SYMBOL_GPL
++0x3f2c16f1    nf_ct_l4proto_find_get  vmlinux EXPORT_SYMBOL_GPL
++0xe20a528d    nf_queue_entry_release_refs     vmlinux EXPORT_SYMBOL_GPL
++0x4335fafb    proto_unregister        vmlinux EXPORT_SYMBOL
++0x5762296f    fuse_conn_kill  vmlinux EXPORT_SYMBOL_GPL
++0xe473e06d    __fsnotify_inode_delete vmlinux EXPORT_SYMBOL_GPL
++0xe2ed7067    i2c_new_dummy   vmlinux EXPORT_SYMBOL_GPL
++0x3cac21b9    regulator_sync_voltage  vmlinux EXPORT_SYMBOL_GPL
++0x71e7aab0    from_kprojid_munged     vmlinux EXPORT_SYMBOL
++0x3ca7e128    tty_unlock_pair vmlinux EXPORT_SYMBOL
++0x146d2f0c    rtnl_af_register        vmlinux EXPORT_SYMBOL_GPL
++0x97ecf37c    kunmap_high     vmlinux EXPORT_SYMBOL
++0x4470a79b    param_ops_long  vmlinux EXPORT_SYMBOL
++0x45bd9efd    dm_table_put    vmlinux EXPORT_SYMBOL
++0xf2a353ac    v4l2_i2c_tuner_addrs    vmlinux EXPORT_SYMBOL_GPL
++0xc7fd39bb    drm_dp_channel_eq_ok    vmlinux EXPORT_SYMBOL
++0xa0472547    inet_csk_update_pmtu    vmlinux EXPORT_SYMBOL_GPL
++0xacf4d843    match_strdup    vmlinux EXPORT_SYMBOL
++0x870bf928    radix_tree_lookup       vmlinux EXPORT_SYMBOL
++0x4672e88b    __crypto_dequeue_request        vmlinux EXPORT_SYMBOL_GPL
++0x7b0f1ab3    ring_buffer_free_read_page      vmlinux EXPORT_SYMBOL_GPL
++0x9745b34c    rt_mutex_unlock vmlinux EXPORT_SYMBOL_GPL
++0xac745cfe    s3c_adc_read    vmlinux EXPORT_SYMBOL_GPL
++0x4dc817ff    usb_composite_overwrite_options vmlinux EXPORT_SYMBOL_GPL
++0xcd8ff108    neigh_seq_next  vmlinux EXPORT_SYMBOL
++0xb4062ffd    vfs_rename      vmlinux EXPORT_SYMBOL
++0xdc4ed03b    generic_ro_fops vmlinux EXPORT_SYMBOL
++0x1300b437    nci_register_device     vmlinux EXPORT_SYMBOL
++0xbcfcecc3    user_path_create        vmlinux EXPORT_SYMBOL
++0xcf71a180    kthread_bind    vmlinux EXPORT_SYMBOL
++0x4571f8be    usb_string_ids_n        vmlinux EXPORT_SYMBOL_GPL
++0xf1ea24f2    ipv6_setsockopt vmlinux EXPORT_SYMBOL
++0x2d97bed6    dm_kcopyd_zero  vmlinux EXPORT_SYMBOL
++0xa1f5edea    drm_property_destroy    vmlinux EXPORT_SYMBOL
++0x3548305a    inet_frag_find  vmlinux EXPORT_SYMBOL
++0xf937428d    inetdev_by_index        vmlinux EXPORT_SYMBOL
++0x33f234ad    __sk_backlog_rcv        vmlinux EXPORT_SYMBOL
++0xb0fbdabc    crypto_lookup_skcipher  vmlinux EXPORT_SYMBOL_GPL
++0xdf0f75c6    eventfd_signal  vmlinux EXPORT_SYMBOL_GPL
++0x21f678b9    clocksource_unregister  vmlinux EXPORT_SYMBOL
++0xe3b5bb1e    usb_poison_anchored_urbs        vmlinux EXPORT_SYMBOL_GPL
++0x36003409    nfc_hci_send_event      vmlinux EXPORT_SYMBOL
++0xd26c8ac5    bt_sock_wait_state      vmlinux EXPORT_SYMBOL
++0x8bd1c81c    fifo_set_limit  vmlinux EXPORT_SYMBOL
++0xe630ebe9    snd_soc_get_pcm_runtime vmlinux EXPORT_SYMBOL_GPL
++0x9f7af994    writeback_in_progress   vmlinux EXPORT_SYMBOL
++0x94048818    filemap_fdatawrite      vmlinux EXPORT_SYMBOL
++0x9cc4f70a    register_pm_notifier    vmlinux EXPORT_SYMBOL_GPL
++0xdf6f4023    phy_drivers_unregister  vmlinux EXPORT_SYMBOL
++0x4cc1d9d6    con_debug_enter vmlinux EXPORT_SYMBOL_GPL
++0x807d2b2c    xt_recseq       vmlinux EXPORT_SYMBOL_GPL
++0x089e2060    __ethtool_get_settings  vmlinux EXPORT_SYMBOL
++0xcdd9e311    dev_add_offload vmlinux EXPORT_SYMBOL
++0x90ac3102    dev_base_lock   vmlinux EXPORT_SYMBOL
++0xfcc256a6    css_id  vmlinux EXPORT_SYMBOL_GPL
++0x2e7be112    _raw_read_lock_irqsave  vmlinux EXPORT_SYMBOL
++0x284633c4    devm_clk_register       vmlinux EXPORT_SYMBOL_GPL
++0x440982c5    usb_del_gadget_udc      vmlinux EXPORT_SYMBOL_GPL
++0x0d7b25d8    drm_i2c_encoder_destroy vmlinux EXPORT_SYMBOL
++0xd25d4f74    console_blank_hook      vmlinux EXPORT_SYMBOL
++0x968b41f8    nfc_hci_unregister_device       vmlinux EXPORT_SYMBOL
++0x71917221    xt_request_find_target  vmlinux EXPORT_SYMBOL_GPL
++0x14ccc8d6    sg_scsi_ioctl   vmlinux EXPORT_SYMBOL_GPL
++0xc22a3091    vm_unmap_aliases        vmlinux EXPORT_SYMBOL_GPL
++0x936d3888    dm_kill_unmapped_request        vmlinux EXPORT_SYMBOL_GPL
++0x56f3f495    vb2_querybuf    vmlinux EXPORT_SYMBOL
++0xcd773fe8    gnet_stats_finish_copy  vmlinux EXPORT_SYMBOL
++0x75ffa405    blk_fetch_request       vmlinux EXPORT_SYMBOL
++0xc51700fb    free_inode_nonrcu       vmlinux EXPORT_SYMBOL
++0x87471cdc    dma_pool_create vmlinux EXPORT_SYMBOL
++0x4b34fbf5    block_all_signals       vmlinux EXPORT_SYMBOL
++0x1910bed7    v4l2_m2m_next_buf       vmlinux EXPORT_SYMBOL_GPL
++0xda6389c8    scsi_get_device_flags_keyed     vmlinux EXPORT_SYMBOL
++0x384fda7f    device_show_int vmlinux EXPORT_SYMBOL_GPL
++0x853ce11c    uart_handle_cts_change  vmlinux EXPORT_SYMBOL_GPL
++0x2167989c    uart_handle_dcd_change  vmlinux EXPORT_SYMBOL_GPL
++0x832c7303    cfg80211_chandef_compatible     vmlinux EXPORT_SYMBOL
++0xb5aa7165    dma_pool_destroy        vmlinux EXPORT_SYMBOL
++0x3a81993a    irq_create_strict_mappings      vmlinux EXPORT_SYMBOL_GPL
++0xf7951d2a    sdio_writeb     vmlinux EXPORT_SYMBOL_GPL
++0x73286449    gether_set_gadget       vmlinux EXPORT_SYMBOL
++0x0958f0a1    gether_disconnect       vmlinux EXPORT_SYMBOL
++0xc7141639    tty_name        vmlinux EXPORT_SYMBOL
++0x52e54a99    udp6_csum_init  vmlinux EXPORT_SYMBOL
++0x20c95ebb    __dev_remove_offload    vmlinux EXPORT_SYMBOL
++0xff6104d0    snd_pcm_rate_bit_to_rate        vmlinux EXPORT_SYMBOL
++0xcfa8d57b    sysfs_get_dirent        vmlinux EXPORT_SYMBOL_GPL
++0x8e0d66f4    __tracepoint_kmalloc    vmlinux EXPORT_SYMBOL
++0x3bfcc1f8    perf_event_release_kernel       vmlinux EXPORT_SYMBOL_GPL
++0x8c03d20c    destroy_workqueue       vmlinux EXPORT_SYMBOL_GPL
++0x7e36685b    of_dev_put      vmlinux EXPORT_SYMBOL
++0x379d3e07    of_dev_get      vmlinux EXPORT_SYMBOL
++0xf494f618    mmc_regulator_get_ocrmask       vmlinux EXPORT_SYMBOL_GPL
++0xd9fb5e67    power_supply_register   vmlinux EXPORT_SYMBOL_GPL
++0x3697b3a2    usb_assign_descriptors  vmlinux EXPORT_SYMBOL_GPL
++0x6789d290    serial8250_register_8250_port   vmlinux EXPORT_SYMBOL
++0xa34d0cc4    inet6_csk_reqsk_queue_hash_add  vmlinux EXPORT_SYMBOL_GPL
++0x81de8eb2    inet_twsk_put   vmlinux EXPORT_SYMBOL_GPL
++0x687019ad    fib_default_rule_add    vmlinux EXPORT_SYMBOL
++0x8eef430a    fat_get_dotdot_entry    vmlinux EXPORT_SYMBOL_GPL
++0x2a3f1eb3    check_disk_change       vmlinux EXPORT_SYMBOL
++0xd5325933    default_file_splice_read        vmlinux EXPORT_SYMBOL
++0xd83215e5    writeback_inodes_sb     vmlinux EXPORT_SYMBOL
++0x506cc085    tracepoint_iter_stop    vmlinux EXPORT_SYMBOL_GPL
++0xe200d2d5    param_get_uint  vmlinux EXPORT_SYMBOL
++0x79cb0ce1    pm_generic_runtime_suspend      vmlinux EXPORT_SYMBOL_GPL
++0x364477d8    do_SAK  vmlinux EXPORT_SYMBOL
++0x8d9c96ee    elv_register    vmlinux EXPORT_SYMBOL_GPL
++0x0c77c871    page_put_link   vmlinux EXPORT_SYMBOL
++0x8f03ba03    release_pages   vmlinux EXPORT_SYMBOL
++0xa4a39c18    v4l2_m2m_streamon       vmlinux EXPORT_SYMBOL_GPL
++0xa2d6eedc    bt_sock_stream_recvmsg  vmlinux EXPORT_SYMBOL
++0xb1bed25d    dpm_resume_start        vmlinux EXPORT_SYMBOL_GPL
++0x10291853    devm_regulator_put      vmlinux EXPORT_SYMBOL_GPL
++0xcf618a57    cfg80211_calculate_bitrate      vmlinux EXPORT_SYMBOL
++0xa9f48f53    km_state_expired        vmlinux EXPORT_SYMBOL
++0x6417850b    qdisc_list_del  vmlinux EXPORT_SYMBOL
++0xb0e10781    get_option      vmlinux EXPORT_SYMBOL
++0x6a3d6744    drm_property_create     vmlinux EXPORT_SYMBOL
++0x60352082    register_inet6addr_notifier     vmlinux EXPORT_SYMBOL
++0x7cabb84d    inet_accept     vmlinux EXPORT_SYMBOL
++0x49b07aec    tcp_select_initial_window       vmlinux EXPORT_SYMBOL
++0xd41766d2    nf_ct_gre_keymap_destroy        vmlinux EXPORT_SYMBOL_GPL
++0x0b225b92    register_pernet_device  vmlinux EXPORT_SYMBOL_GPL
++0xe697d108    __blk_iopoll_complete   vmlinux EXPORT_SYMBOL
++0xa1c76e0a    _cond_resched   vmlinux EXPORT_SYMBOL
++0x22e1ae6f    up_read vmlinux EXPORT_SYMBOL
++0x9fbe4605    class_for_each_device   vmlinux EXPORT_SYMBOL_GPL
++0x4c1e4dba    unbind_con_driver       vmlinux EXPORT_SYMBOL
++0x352cbaad    empty_zero_page vmlinux EXPORT_SYMBOL
++0x66f6b51b    nfnetlink_subsys_register       vmlinux EXPORT_SYMBOL_GPL
++0x2de03b66    ndo_dflt_bridge_getlink vmlinux EXPORT_SYMBOL
++0x1f404818    __pskb_pull_tail        vmlinux EXPORT_SYMBOL
++0x848618a1    snd_pcm_lib_free_vmalloc_buffer vmlinux EXPORT_SYMBOL
++0x11575bf3    bioset_free     vmlinux EXPORT_SYMBOL
++0x2acf0feb    vfs_fstat       vmlinux EXPORT_SYMBOL
++0x0c45fc96    vfs_lstat       vmlinux EXPORT_SYMBOL
++0x20bc3470    orderly_poweroff        vmlinux EXPORT_SYMBOL_GPL
++0xd0c74120    cpufreq_frequency_table_verify  vmlinux EXPORT_SYMBOL_GPL
++0x93af794b    dev_alert       vmlinux EXPORT_SYMBOL
++0x96cd86f2    tty_wait_until_sent     vmlinux EXPORT_SYMBOL
++0x4384f1be    gether_setup_name       vmlinux EXPORT_SYMBOL
++0xa598e29c    vesa_modes      vmlinux EXPORT_SYMBOL
++0x4ead0283    pn_skb_send     vmlinux EXPORT_SYMBOL
++0xc01a92eb    __netif_schedule        vmlinux EXPORT_SYMBOL
++0xd42d86c0    generic_fh_to_parent    vmlinux EXPORT_SYMBOL_GPL
++0x9eaba82f    generic_fillattr        vmlinux EXPORT_SYMBOL
++0x183fa88b    mempool_alloc_slab      vmlinux EXPORT_SYMBOL
++0x5d0b1892    param_set_invbool       vmlinux EXPORT_SYMBOL
++0xe103ee04    gpio_export_link        vmlinux EXPORT_SYMBOL_GPL
++0x24bfaf10    d_instantiate_unique    vmlinux EXPORT_SYMBOL
++0xd6b8e852    request_threaded_irq    vmlinux EXPORT_SYMBOL
++0x18bd76a4    _raw_spin_trylock       vmlinux EXPORT_SYMBOL
++0xc2ffd5d5    iio_trigger_alloc       vmlinux EXPORT_SYMBOL
++0xa749c072    i2c_register_driver     vmlinux EXPORT_SYMBOL
++0x6ea05e17    of_phy_provider_unregister      vmlinux EXPORT_SYMBOL_GPL
++0xc359fb65    abort   vmlinux EXPORT_SYMBOL
++0x9f0f5d05    cfg80211_send_unprot_disassoc   vmlinux EXPORT_SYMBOL
++0xc575c737    debug_locks_off vmlinux EXPORT_SYMBOL_GPL
++0xab2f97aa    jbd2_journal_forget     vmlinux EXPORT_SYMBOL
++0xffea14aa    mutex_lock_interruptible        vmlinux EXPORT_SYMBOL
++0xdb9cfd07    skb_clone       vmlinux EXPORT_SYMBOL
++0x0cdd5fd1    crypto_find_alg vmlinux EXPORT_SYMBOL_GPL
++0x076aff85    set_task_ioprio vmlinux EXPORT_SYMBOL_GPL
++0x773522a8    setup_arg_pages vmlinux EXPORT_SYMBOL
++0x430348ff    input_get_keycode       vmlinux EXPORT_SYMBOL
++0x3c50bfc9    regmap_can_raw_write    vmlinux EXPORT_SYMBOL_GPL
++0x8209afe6    wakeup_source_destroy   vmlinux EXPORT_SYMBOL_GPL
++0x0487f831    fb_find_best_display    vmlinux EXPORT_SYMBOL
++0x83dab696    inode_dio_wait  vmlinux EXPORT_SYMBOL
++0xa3a19433    of_get_regulator_init_data      vmlinux EXPORT_SYMBOL_GPL
++0x43ca0eb7    amba_request_regions    vmlinux EXPORT_SYMBOL
++0xc34efe27    snmp_fold_field vmlinux EXPORT_SYMBOL_GPL
++0x3e48e980    tcp_init_xmit_timers    vmlinux EXPORT_SYMBOL
++0x267c8e5b    snd_soc_register_card   vmlinux EXPORT_SYMBOL_GPL
++0x2d13dc4b    jbd2_journal_start      vmlinux EXPORT_SYMBOL
++0xd67364f7    eventfd_ctx_fdget       vmlinux EXPORT_SYMBOL_GPL
++0xaefaecb4    phy_ethtool_gset        vmlinux EXPORT_SYMBOL
++0x86dded2c    phy_ethtool_sset        vmlinux EXPORT_SYMBOL
++0x1b15cf75    drm_encoder_init        vmlinux EXPORT_SYMBOL
++0x540ef2af    vfs_lock_file   vmlinux EXPORT_SYMBOL_GPL
++0x56fcacd4    bio_uncopy_user vmlinux EXPORT_SYMBOL
++0x9401ec10    make_bad_inode  vmlinux EXPORT_SYMBOL
++0x8ec007a4    __d_drop        vmlinux EXPORT_SYMBOL
++0x7f39e9f3    __mmdrop        vmlinux EXPORT_SYMBOL_GPL
++0x731e1d9d    thermal_zone_device_unregister  vmlinux EXPORT_SYMBOL_GPL
++0x31528994    __i2c_transfer  vmlinux EXPORT_SYMBOL
++0x33dbfd93    tcp_memory_allocated    vmlinux EXPORT_SYMBOL
++0xa8232c78    strtobool       vmlinux EXPORT_SYMBOL
++0xbe744811    jbd2_journal_force_commit_nested        vmlinux EXPORT_SYMBOL
++0xce03751f    seq_release_private     vmlinux EXPORT_SYMBOL
++0xd788742d    perf_trace_buf_prepare  vmlinux EXPORT_SYMBOL_GPL
++0x269f017e    st_sensors_set_dataready_irq    vmlinux EXPORT_SYMBOL
++0x379ea057    hid_check_keys_pressed  vmlinux EXPORT_SYMBOL_GPL
++0xe19a7489    scsi_bus_type   vmlinux EXPORT_SYMBOL_GPL
++0x11f13f3f    snd_ctl_remove  vmlinux EXPORT_SYMBOL
++0xb7a5a52f    writeback_inodes_sb_nr  vmlinux EXPORT_SYMBOL
++0x8efefdc1    vfs_removexattr vmlinux EXPORT_SYMBOL_GPL
++0xbd7c9ac7    find_symbol     vmlinux EXPORT_SYMBOL_GPL
++0xc6ca6078    __mutex_init    vmlinux EXPORT_SYMBOL
++0xe8349cd8    uart_console_write      vmlinux EXPORT_SYMBOL_GPL
++0x2e5810c6    __aeabi_unwind_cpp_pr1  vmlinux EXPORT_SYMBOL
++0x80f711c7    jbd2_journal_check_used_features        vmlinux EXPORT_SYMBOL
++0xcd91b127    system_highpri_wq       vmlinux EXPORT_SYMBOL_GPL
++0x5d2137b0    sdio_readsb     vmlinux EXPORT_SYMBOL_GPL
++0x6883e0d5    rtc_set_time    vmlinux EXPORT_SYMBOL_GPL
++0xf753d6ff    drm_i2c_encoder_mode_set        vmlinux EXPORT_SYMBOL
++0x0b0d888b    icmpv6_err_convert      vmlinux EXPORT_SYMBOL
++0x908cb3fc    vfs_readv       vmlinux EXPORT_SYMBOL
++0x3e467689    do_sync_write   vmlinux EXPORT_SYMBOL
++0xe01edb1a    vb2_plane_vaddr vmlinux EXPORT_SYMBOL_GPL
++0xff9c7899    fb_get_mode     vmlinux EXPORT_SYMBOL
++0x63923641    crypto_shash_setkey     vmlinux EXPORT_SYMBOL_GPL
++0x66c159c0    crypto_ahash_setkey     vmlinux EXPORT_SYMBOL_GPL
++0xb2c17922    search_binary_handler   vmlinux EXPORT_SYMBOL
++0x07438699    rt_mutex_trylock        vmlinux EXPORT_SYMBOL_GPL
++0x559b763f    mmc_detect_change       vmlinux EXPORT_SYMBOL
++0xed2c3cec    drm_debugfs_remove_files        vmlinux EXPORT_SYMBOL
++0xea5c6ccb    rtnl_link_get_net       vmlinux EXPORT_SYMBOL
++0x420c7411    ahash_attr_alg  vmlinux EXPORT_SYMBOL_GPL
++0xc690866c    irq_work_queue  vmlinux EXPORT_SYMBOL_GPL
++0x22640142    sdio_readw      vmlinux EXPORT_SYMBOL_GPL
++0x246e1a87    sdio_readl      vmlinux EXPORT_SYMBOL_GPL
++0xafb35b17    sdio_readb      vmlinux EXPORT_SYMBOL_GPL
++0x713125bd    cpufreq_freq_attr_scaling_available_freqs       vmlinux EXPORT_SYMBOL_GPL
++0xd7095481    usb_remove_phy  vmlinux EXPORT_SYMBOL_GPL
++0x76d878f8    usb_remove_hcd  vmlinux EXPORT_SYMBOL_GPL
++0x7e543e70    device_store_bool       vmlinux EXPORT_SYMBOL_GPL
++0x407136b1    __put_user_8    vmlinux EXPORT_SYMBOL
++0x1567020f    tcp_disconnect  vmlinux EXPORT_SYMBOL
++0x1f615e38    bio_pair_release        vmlinux EXPORT_SYMBOL
++0x2469810f    __rcu_read_unlock       vmlinux EXPORT_SYMBOL_GPL
++0xea51d53a    extcon_get_extcon_dev   vmlinux EXPORT_SYMBOL_GPL
++0x52c47236    put_device      vmlinux EXPORT_SYMBOL_GPL
++0x194eadaa    drm_edid_header_is_valid        vmlinux EXPORT_SYMBOL
++0x7d89e34a    drm_gtf_mode_complex    vmlinux EXPORT_SYMBOL
++0x75c2b9f1    memalloc_socks  vmlinux EXPORT_SYMBOL_GPL
++0xb10dfa5a    register_filesystem     vmlinux EXPORT_SYMBOL
++0x758a782e    blk_fill_rwbs   vmlinux EXPORT_SYMBOL_GPL
++0xba497f13    loops_per_jiffy vmlinux EXPORT_SYMBOL
++0xc657abdc    v4l2_ctrl_subscribe_event       vmlinux EXPORT_SYMBOL
++0xc7472c0b    devm_input_allocate_device      vmlinux EXPORT_SYMBOL
++0xdb2c2fbf    spi_alloc_device        vmlinux EXPORT_SYMBOL_GPL
++0xa33be4ce    inet_confirm_addr       vmlinux EXPORT_SYMBOL
++0x48eb98d1    eth_validate_addr       vmlinux EXPORT_SYMBOL
++0xc5718627    sg_copy_to_buffer       vmlinux EXPORT_SYMBOL
++0x7ab88a45    system_freezing_cnt     vmlinux EXPORT_SYMBOL
++0x7d0db45c    jiffies_to_clock_t      vmlinux EXPORT_SYMBOL
++0x2c208607    power_supply_is_system_supplied vmlinux EXPORT_SYMBOL_GPL
++0xc9422c05    devm_usb_get_phy_dev    vmlinux EXPORT_SYMBOL_GPL
++0xba3a6941    drm_getsarea    vmlinux EXPORT_SYMBOL
++0x1ffe8e3f    nfc_register_device     vmlinux EXPORT_SYMBOL
++0x0478373c    generic_make_request    vmlinux EXPORT_SYMBOL
++0x0b9a91be    generic_file_llseek_size        vmlinux EXPORT_SYMBOL
++0x1c87a811    __round_jiffies_up      vmlinux EXPORT_SYMBOL_GPL
++0x93d6ad2c    usb_debug_root  vmlinux EXPORT_SYMBOL_GPL
++0xd3ce47fe    drm_mode_crtc_set_gamma_size    vmlinux EXPORT_SYMBOL
++0xbe16ad70    drm_addbufs_pci vmlinux EXPORT_SYMBOL
++0xd5dae19f    regulator_get_exclusive vmlinux EXPORT_SYMBOL_GPL
++0x02124474    ip_send_check   vmlinux EXPORT_SYMBOL
++0x628cbfaa    rtmsg_ifinfo    vmlinux EXPORT_SYMBOL
++0xb0d3bca5    __rtnl_register vmlinux EXPORT_SYMBOL_GPL
++0x23b9d6e2    mangle_path     vmlinux EXPORT_SYMBOL
++0xe7c52663    v4l2_m2m_create_bufs    vmlinux EXPORT_SYMBOL_GPL
++0x63625aaa    usb_composite_setup_continue    vmlinux EXPORT_SYMBOL_GPL
++0x41f53df0    anon_inode_getfd        vmlinux EXPORT_SYMBOL_GPL
++0x24d5ba21    filemap_flush   vmlinux EXPORT_SYMBOL
++0xb49f6bea    iio_enum_write  vmlinux EXPORT_SYMBOL_GPL
++0x1bfbfeeb    mc1n2_set_mclk_source   vmlinux EXPORT_SYMBOL
++0x95e6e500    blk_stack_limits        vmlinux EXPORT_SYMBOL
++0xeb46c362    fuse_conn_init  vmlinux EXPORT_SYMBOL_GPL
++0x0e9003db    pm_generic_freeze_late  vmlinux EXPORT_SYMBOL_GPL
++0xf2fa6c7e    drm_gem_vm_close        vmlinux EXPORT_SYMBOL
++0x5bbc0a12    __fib_lookup    vmlinux EXPORT_SYMBOL_GPL
++0x1dd6e42b    tcp_set_state   vmlinux EXPORT_SYMBOL_GPL
++0xa77d88f6    strnlen_user    vmlinux EXPORT_SYMBOL
++0x191ef206    i2c_smbus_read_i2c_block_data   vmlinux EXPORT_SYMBOL
++0x52b992dc    drm_kms_helper_poll_disable     vmlinux EXPORT_SYMBOL
++0x6fc997a4    tty_mutex       vmlinux EXPORT_SYMBOL
++0x3973c5f8    kunmap  vmlinux EXPORT_SYMBOL
++0xb28f5ef1    xt_free_table_info      vmlinux EXPORT_SYMBOL
++0x1d0b568b    mnt_pin vmlinux EXPORT_SYMBOL
++0x50ba53b9    set_create_files_as     vmlinux EXPORT_SYMBOL
++0xcbd3dbd0    serial8250_modem_status vmlinux EXPORT_SYMBOL_GPL
++0xe38dd51c    dev_get_by_name vmlinux EXPORT_SYMBOL
++0x69458fd5    snd_dma_alloc_pages_fallback    vmlinux EXPORT_SYMBOL
++0xb3fda4b7    __page_symlink  vmlinux EXPORT_SYMBOL
++0x400fb79c    install_exec_creds      vmlinux EXPORT_SYMBOL
++0xbed3ae54    sched_setscheduler      vmlinux EXPORT_SYMBOL_GPL
++0xeb923e09    power_supply_set_battery_charged        vmlinux EXPORT_SYMBOL_GPL
++0xfdab6de3    unregister_sound_midi   vmlinux EXPORT_SYMBOL
++0x30a80826    __kfifo_from_user       vmlinux EXPORT_SYMBOL
++0x6923ce63    irq_work_sync   vmlinux EXPORT_SYMBOL_GPL
++0xe7197773    drm_ht_insert_item      vmlinux EXPORT_SYMBOL
++0xdf75f3c9    ipcomp_input    vmlinux EXPORT_SYMBOL_GPL
++0xac966a6d    udp_prot        vmlinux EXPORT_SYMBOL
++0xc6531cd4    inet_putpeer    vmlinux EXPORT_SYMBOL_GPL
++0xe2b955e2    nat_h245_hook   vmlinux EXPORT_SYMBOL_GPL
++0xf34732f2    netif_set_xps_queue     vmlinux EXPORT_SYMBOL
++0x7681d145    snd_ctl_register_ioctl  vmlinux EXPORT_SYMBOL
++0xaae48971    mmc_card_sleep  vmlinux EXPORT_SYMBOL
++0x58fe6474    v4l2_m2m_ioctl_qbuf     vmlinux EXPORT_SYMBOL_GPL
++0x00d1d0d0    i2c_adapter_type        vmlinux EXPORT_SYMBOL_GPL
++0xb971ebca    rndis_get_next_response vmlinux EXPORT_SYMBOL
++0xc88b565d    inet6_sk_rebuild_header vmlinux EXPORT_SYMBOL_GPL
++0x83a4c277    mb_cache_shrink vmlinux EXPORT_SYMBOL
++0xf1e98c74    avenrun vmlinux EXPORT_SYMBOL
++0x1318fa1c    __ww_mutex_lock_interruptible   vmlinux EXPORT_SYMBOL
++0x2d3385d3    system_wq       vmlinux EXPORT_SYMBOL
++0x94e4e64e    v4l2_event_queue        vmlinux EXPORT_SYMBOL_GPL
++0x76fd0937    device_init_wakeup      vmlinux EXPORT_SYMBOL_GPL
++0x40a6f522    __arm_ioremap   vmlinux EXPORT_SYMBOL
++0xc2165d85    __arm_iounmap   vmlinux EXPORT_SYMBOL
++0xaf50e76d    elf_set_personality     vmlinux EXPORT_SYMBOL
++0xd9f8f32d    nf_ct_extend_register   vmlinux EXPORT_SYMBOL_GPL
++0x6ceb8cf4    mark_page_accessed      vmlinux EXPORT_SYMBOL
++0x17f36c02    mmc_calc_max_discard    vmlinux EXPORT_SYMBOL
++0x0d45c48f    v4l2_clk_register       vmlinux EXPORT_SYMBOL
++0x123959a1    v4l2_type_names vmlinux EXPORT_SYMBOL
++0x02a18c74    nf_conntrack_destroy    vmlinux EXPORT_SYMBOL
++0x679f4b6b    scsi_report_bus_reset   vmlinux EXPORT_SYMBOL
++0xf8224b12    mali_get_user_setting   vmlinux EXPORT_SYMBOL
++0x3c93ad98    tty_port_install        vmlinux EXPORT_SYMBOL_GPL
++0x63fb81e4    brcmu_pktq_penq drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x723a1683    brcmu_pktq_pdeq drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0xfa595453    ip6_sk_dst_lookup_flow  vmlinux EXPORT_SYMBOL_GPL
++0xa76f7e50    snd_dma_get_reserved_buf        vmlinux EXPORT_SYMBOL
++0x61ed1c8e    cdev_add        vmlinux EXPORT_SYMBOL
++0x69447467    ring_buffer_write       vmlinux EXPORT_SYMBOL_GPL
++0xfcd7bc0b    ring_buffer_empty       vmlinux EXPORT_SYMBOL_GPL
++0x82939ebd    rcu_batches_completed_sched     vmlinux EXPORT_SYMBOL_GPL
++0x9e44b9b7    of_get_next_available_child     vmlinux EXPORT_SYMBOL
++0x1010f1ee    hid_output_report       vmlinux EXPORT_SYMBOL_GPL
++0x59e5070d    __do_div64      vmlinux EXPORT_SYMBOL
++0xa2d91fcc    xfrm_input      vmlinux EXPORT_SYMBOL
++0x07a62853    dev_mc_add      vmlinux EXPORT_SYMBOL
++0x40908b29    dev_mc_del      vmlinux EXPORT_SYMBOL
++0x2eed048e    dev_uc_add      vmlinux EXPORT_SYMBOL
++0x69dba7f4    dev_uc_del      vmlinux EXPORT_SYMBOL
++0x15361516    register_pernet_subsys  vmlinux EXPORT_SYMBOL_GPL
++0x915be34a    snd_timer_new   vmlinux EXPORT_SYMBOL
++0x3c45a56f    blk_queue_update_dma_pad        vmlinux EXPORT_SYMBOL
++0x069d40a0    blkdev_get_by_path      vmlinux EXPORT_SYMBOL
++0xa440bdfe    open_exec       vmlinux EXPORT_SYMBOL
++0x374682ce    rtc_update_irq  vmlinux EXPORT_SYMBOL_GPL
++0xba2d0719    drm_mode_hsync  vmlinux EXPORT_SYMBOL
++0x2d7a787f    drm_dp_clock_recovery_ok        vmlinux EXPORT_SYMBOL
++0xd59b2bb0    fb_blank        vmlinux EXPORT_SYMBOL
++0x0b48677a    __kfifo_init    vmlinux EXPORT_SYMBOL
++0x249c96e2    mb_cache_entry_find_next        vmlinux EXPORT_SYMBOL
++0xaee2539e    inode_init_owner        vmlinux EXPORT_SYMBOL
++0x7b24ccb3    file_ns_capable vmlinux EXPORT_SYMBOL
++0x37c0412f    cpu_subsys      vmlinux EXPORT_SYMBOL_GPL
++0x9993bf08    rt_mutex_destroy        vmlinux EXPORT_SYMBOL_GPL
++0xd4034828    system_freezable_wq     vmlinux EXPORT_SYMBOL_GPL
++0x9963a089    queue_delayed_work_on   vmlinux EXPORT_SYMBOL
++0x1284891b    iio_trigger_notify_done vmlinux EXPORT_SYMBOL
++0x03212586    v4l2_m2m_streamoff      vmlinux EXPORT_SYMBOL_GPL
++0x5b19634d    div_s64_rem     vmlinux EXPORT_SYMBOL
++0xb110bb66    __set_page_dirty_nobuffers      vmlinux EXPORT_SYMBOL
++0xd7d79132    put_online_cpus vmlinux EXPORT_SYMBOL_GPL
++0x121e3c12    devres_open_group       vmlinux EXPORT_SYMBOL_GPL
++0x8eae4744    __nf_ct_kill_acct       vmlinux EXPORT_SYMBOL_GPL
++0xcf88625f    mempool_create_node     vmlinux EXPORT_SYMBOL
++0x222fa684    lg_global_lock  vmlinux EXPORT_SYMBOL
++0x7cb2eca1    find_get_pid    vmlinux EXPORT_SYMBOL_GPL
++0x971ad8d8    usbnet_unlink_rx_urbs   vmlinux EXPORT_SYMBOL_GPL
++0xa551b417    devm_pwm_get    vmlinux EXPORT_SYMBOL_GPL
++0xb138607d    dev_set_promiscuity     vmlinux EXPORT_SYMBOL
++0xc8ca31af    timed_output_dev_register       vmlinux EXPORT_SYMBOL_GPL
++0x2967cbf7    dm_get_rq_mapinfo       vmlinux EXPORT_SYMBOL_GPL
++0x07013243    scsi_bios_ptable        vmlinux EXPORT_SYMBOL
++0x9780e683    pm_generic_resume       vmlinux EXPORT_SYMBOL_GPL
++0x3074f033    drm_order       vmlinux EXPORT_SYMBOL
++0xa87f4ece    neigh_connected_output  vmlinux EXPORT_SYMBOL
++0xe9f7149c    zlib_deflate_workspacesize      vmlinux EXPORT_SYMBOL
++0x2d03c10d    posix_acl_create        vmlinux EXPORT_SYMBOL
++0xbe254e92    param_set_ushort        vmlinux EXPORT_SYMBOL
++0xf0ca36cf    drm_prime_init_file_private     vmlinux EXPORT_SYMBOL
++0xb001e18c    drm_plane_init  vmlinux EXPORT_SYMBOL
++0xb2922319    bt_sock_recvmsg vmlinux EXPORT_SYMBOL
++0xe7f38f6d    udp_flush_pending_frames        vmlinux EXPORT_SYMBOL
++0xf0726368    dev_get_stats   vmlinux EXPORT_SYMBOL
++0xd3f7e5cc    snd_soc_default_volatile_register       vmlinux EXPORT_SYMBOL_GPL
++0x92c5fcb5    snd_timer_notify        vmlinux EXPORT_SYMBOL
++0x86fb9b05    bitmap_parse_user       vmlinux EXPORT_SYMBOL
++0x01000e51    schedule        vmlinux EXPORT_SYMBOL
++0xbd597aa3    usb_add_function        vmlinux EXPORT_SYMBOL_GPL
++0x460e4737    pm_generic_poweroff     vmlinux EXPORT_SYMBOL_GPL
++0x6920e885    nlmsg_notify    vmlinux EXPORT_SYMBOL
++0x247a1d7a    ww_mutex_unlock vmlinux EXPORT_SYMBOL
++0x1498f6af    mmput   vmlinux EXPORT_SYMBOL_GPL
++0x709eb78b    init_task       vmlinux EXPORT_SYMBOL
++0x3052a0ee    watchdog_unregister_device      vmlinux EXPORT_SYMBOL_GPL
++0x80eaa56e    drm_i2c_encoder_save    vmlinux EXPORT_SYMBOL
++0xe540813f    drm_property_create_enum        vmlinux EXPORT_SYMBOL
++0x6c642207    drm_get_connector_name  vmlinux EXPORT_SYMBOL
++0x42151efa    balloon_devinfo_alloc   vmlinux EXPORT_SYMBOL_GPL
++0xfa544711    video_devdata   vmlinux EXPORT_SYMBOL
++0x8e9618cd    wakeup_source_create    vmlinux EXPORT_SYMBOL_GPL
++0x72f12e79    drm_probe_ddc   vmlinux EXPORT_SYMBOL
++0x89d66811    build_ehash_secret      vmlinux EXPORT_SYMBOL
++0xf4329926    __inet_twsk_hashdance   vmlinux EXPORT_SYMBOL_GPL
++0xd0e13603    gnet_stats_copy_app     vmlinux EXPORT_SYMBOL
++0x1b015d25    bitmap_parselist        vmlinux EXPORT_SYMBOL
++0xf91bf3db    __insert_inode_hash     vmlinux EXPORT_SYMBOL
++0x308b733a    getboottime     vmlinux EXPORT_SYMBOL_GPL
++0x69f04aa3    revert_creds    vmlinux EXPORT_SYMBOL
++0xdf929370    fs_overflowgid  vmlinux EXPORT_SYMBOL
++0xa1177bf1    i2c_verify_client       vmlinux EXPORT_SYMBOL
++0x0e5358d0    input_allocate_device   vmlinux EXPORT_SYMBOL
++0x4fed4ee0    pm_runtime_barrier      vmlinux EXPORT_SYMBOL_GPL
++0xb939d297    dev_printk      vmlinux EXPORT_SYMBOL
++0x090849e3    phy_power_on    vmlinux EXPORT_SYMBOL_GPL
++0x47416e14    cpu_rmap_add    vmlinux EXPORT_SYMBOL
++0x08fbaf94    xfrm_policy_walk        vmlinux EXPORT_SYMBOL
++0x774846b4    nf_log_unset    vmlinux EXPORT_SYMBOL
++0x00aaf0d4    wm_hubs_add_analogue_routes     vmlinux EXPORT_SYMBOL_GPL
++0xe9d7e477    snd_card_proc_new       vmlinux EXPORT_SYMBOL
++0x97de2b83    debug_locks_silent      vmlinux EXPORT_SYMBOL_GPL
++0x3e452a00    blocking_notifier_call_chain    vmlinux EXPORT_SYMBOL_GPL
++0xae83dc8c    spi_bitbang_setup_transfer      vmlinux EXPORT_SYMBOL_GPL
++0x8d871961    cpu_tlb vmlinux EXPORT_SYMBOL
++0xfe694f5b    regmap_read     vmlinux EXPORT_SYMBOL_GPL
++0x594bf15b    ioport_map      vmlinux EXPORT_SYMBOL
++0x2d3abae7    __skb_checksum_complete vmlinux EXPORT_SYMBOL
++0xb5a459dc    unregister_blkdev       vmlinux EXPORT_SYMBOL
++0xd0a8eac3    write_inode_now vmlinux EXPORT_SYMBOL
++0x7d3a11d4    tty_lock        vmlinux EXPORT_SYMBOL
++0xa6dea12e    regulator_register      vmlinux EXPORT_SYMBOL_GPL
++0x0ce021b8    ieee80211_amsdu_to_8023s        vmlinux EXPORT_SYMBOL
++0xe0088286    fat_search_long vmlinux EXPORT_SYMBOL_GPL
++0x08ca5b31    seq_path        vmlinux EXPORT_SYMBOL
++0xcc5005fe    msleep_interruptible    vmlinux EXPORT_SYMBOL
++0x2f0d9053    usb_otg_state_string    vmlinux EXPORT_SYMBOL_GPL
++0xf2997713    tty_termios_hw_change   vmlinux EXPORT_SYMBOL
++0x53893194    dev_addr_add    vmlinux EXPORT_SYMBOL
++0x0dd3fd84    netdev_err      vmlinux EXPORT_SYMBOL
++0x62849ac7    dev_valid_name  vmlinux EXPORT_SYMBOL
++0x193466be    kfree_skb_partial       vmlinux EXPORT_SYMBOL
++0xd2a941d4    sg_init_table   vmlinux EXPORT_SYMBOL
++0x5642793a    radix_tree_tag_clear    vmlinux EXPORT_SYMBOL
++0xc3bb6d9e    blk_pre_runtime_resume  vmlinux EXPORT_SYMBOL
++0xd3a7747d    fsnotify        vmlinux EXPORT_SYMBOL_GPL
++0x4f3b569c    generic_file_open       vmlinux EXPORT_SYMBOL
++0xc87c1f84    ktime_get       vmlinux EXPORT_SYMBOL_GPL
++0x89bbafc6    usb_register_notify     vmlinux EXPORT_SYMBOL_GPL
++0x19ac480a    cfg80211_new_sta        vmlinux EXPORT_SYMBOL
++0xd18ba458    generic_cont_expand_simple      vmlinux EXPORT_SYMBOL
++0x5cf6467f    d_instantiate   vmlinux EXPORT_SYMBOL
++0xd1ef6f16    genphy_update_link      vmlinux EXPORT_SYMBOL
++0x4a77677a    nfc_hci_recv_frame      vmlinux EXPORT_SYMBOL
++0xc2a19d85    register_sound_special_device   vmlinux EXPORT_SYMBOL
++0x5b3060c4    blk_queue_rq_timed_out  vmlinux EXPORT_SYMBOL_GPL
++0x2cbfd99b    vb2_queue_init  vmlinux EXPORT_SYMBOL_GPL
++0x955d725c    drm_mm_scan_remove_block        vmlinux EXPORT_SYMBOL
++0x6d346792    pin_config_group_get    vmlinux EXPORT_SYMBOL
++0xf82a1863    pin_config_group_set    vmlinux EXPORT_SYMBOL
++0x08c473b7    xt_alloc_table_info     vmlinux EXPORT_SYMBOL
++0xb7b61546    crc32_be        vmlinux EXPORT_SYMBOL
++0x26520970    vm_memory_committed     vmlinux EXPORT_SYMBOL_GPL
++0xcf283b4f    iommu_domain_alloc      vmlinux EXPORT_SYMBOL_GPL
++0x52ffd07f    xfrm_output_resume      vmlinux EXPORT_SYMBOL_GPL
++0x4c21e163    skb_find_text   vmlinux EXPORT_SYMBOL
++0x5279b639    current_fs_time vmlinux EXPORT_SYMBOL
++0x04cc0a21    i2c_unregister_device   vmlinux EXPORT_SYMBOL_GPL
++0x13fc56de    drm_helper_crtc_in_use  vmlinux EXPORT_SYMBOL
++0x6d399587    regulator_unregister    vmlinux EXPORT_SYMBOL_GPL
++0x6b037ba6    nf_nat_l4proto_unregister       vmlinux EXPORT_SYMBOL_GPL
++0x8231a8bd    nf_nat_l3proto_unregister       vmlinux EXPORT_SYMBOL_GPL
++0x6350314b    tcf_hash_create vmlinux EXPORT_SYMBOL
++0xf339287c    skb_queue_tail  vmlinux EXPORT_SYMBOL
++0x5409775b    free_irq_cpu_rmap       vmlinux EXPORT_SYMBOL
++0x65771426    crypto_lookup_template  vmlinux EXPORT_SYMBOL_GPL
++0xd61347c6    register_sysctl vmlinux EXPORT_SYMBOL
++0xd8c37e37    vfs_test_lock   vmlinux EXPORT_SYMBOL_GPL
++0x952664c5    do_exit vmlinux EXPORT_SYMBOL_GPL
++0xcb07e4af    tcf_hash_destroy        vmlinux EXPORT_SYMBOL
++0x78953de6    mark_buffer_dirty_inode vmlinux EXPORT_SYMBOL
++0x3109b751    cpu_clock       vmlinux EXPORT_SYMBOL_GPL
++0xdf842e2b    drm_vblank_cleanup      vmlinux EXPORT_SYMBOL
++0x57810201    ip_tunnel_lookup        vmlinux EXPORT_SYMBOL_GPL
++0xb1c3a01a    oops_in_progress        vmlinux EXPORT_SYMBOL
++0x0fca29c0    dev_pm_qos_remove_request       vmlinux EXPORT_SYMBOL_GPL
++0xc407a137    dma_wait_for_async_tx   vmlinux EXPORT_SYMBOL_GPL
++0x046a9d1b    backlight_device_register       vmlinux EXPORT_SYMBOL
++0x2a36b31a    nf_ct_helper_log        vmlinux EXPORT_SYMBOL_GPL
++0xb442919d    blk_get_backing_dev_info        vmlinux EXPORT_SYMBOL
++0x0ed2f3b5    elevator_init   vmlinux EXPORT_SYMBOL
++0x21bda10a    kill_fasync     vmlinux EXPORT_SYMBOL
++0x622dacba    tick_nohz_idle_enter    vmlinux EXPORT_SYMBOL_GPL
++0xdd4a5569    param_get_byte  vmlinux EXPORT_SYMBOL
++0x764d38f1    tty_insert_flip_string_fixed_flag       vmlinux EXPORT_SYMBOL
++0xcf5bc354    tty_register_ldisc      vmlinux EXPORT_SYMBOL
++0x88f68355    tty_throttle    vmlinux EXPORT_SYMBOL
++0x335e720e    tty_check_change        vmlinux EXPORT_SYMBOL
++0x1d5568cb    dev_disable_lro vmlinux EXPORT_SYMBOL
++0xb2be6e92    netdev_stats_to_stats64 vmlinux EXPORT_SYMBOL
++0x728261ca    kblockd_schedule_delayed_work   vmlinux EXPORT_SYMBOL
++0x5c959646    debugfs_create_u8       vmlinux EXPORT_SYMBOL_GPL
++0x0c150d31    cgroup_taskset_first    vmlinux EXPORT_SYMBOL_GPL
++0xec690544    attribute_container_classdev_to_container       vmlinux EXPORT_SYMBOL_GPL
++0xda1613df    drm_put_dev     vmlinux EXPORT_SYMBOL
++0x157667da    drm_gem_vm_open vmlinux EXPORT_SYMBOL
++0x8ad8d79e    drm_fb_helper_setcmap   vmlinux EXPORT_SYMBOL
++0x5550f136    snd_soc_dapm_info_pin_switch    vmlinux EXPORT_SYMBOL_GPL
++0xcb08eeba    drm_core_ioremap        vmlinux EXPORT_SYMBOL
++0x6aba167a    regulator_list_voltage  vmlinux EXPORT_SYMBOL_GPL
++0x1b0ac272    __tracepoint_kmalloc_node       vmlinux EXPORT_SYMBOL
++0xd62c833f    schedule_timeout        vmlinux EXPORT_SYMBOL
++0x432fd7f6    __gpio_set_value        vmlinux EXPORT_SYMBOL_GPL
++0x6c8d5ae8    __gpio_get_value        vmlinux EXPORT_SYMBOL_GPL
++0x65ccb6f0    call_netevent_notifiers vmlinux EXPORT_SYMBOL_GPL
++0x4a7fb243    percpu_counter_compare  vmlinux EXPORT_SYMBOL
++0xced58760    crypto_alloc_base       vmlinux EXPORT_SYMBOL_GPL
++0xfcf2f8c0    aio_put_req     vmlinux EXPORT_SYMBOL
++0x6f3a36eb    dw_mci_pltfm_pmops      vmlinux EXPORT_SYMBOL_GPL
++0xe6c3ebb0    __raw_writesw   vmlinux EXPORT_SYMBOL
++0x51908eb8    __raw_writesl   vmlinux EXPORT_SYMBOL
++0x75fee7fd    __raw_writesb   vmlinux EXPORT_SYMBOL
++0xef35b0c3    cfg80211_report_wowlan_wakeup   vmlinux EXPORT_SYMBOL
++0x99591a7a    ipv6_ext_hdr    vmlinux EXPORT_SYMBOL
++0x65396d44    neigh_destroy   vmlinux EXPORT_SYMBOL
++0x405b485b    netdev_warn     vmlinux EXPORT_SYMBOL
++0xf45f8934    blk_end_request_cur     vmlinux EXPORT_SYMBOL
++0x9a682368    replace_mount_options   vmlinux EXPORT_SYMBOL
++0x5a7c0586    hid_validate_values     vmlinux EXPORT_SYMBOL_GPL
++0x88618588    mmc_wait_for_app_cmd    vmlinux EXPORT_SYMBOL
++0xccbbfe3b    v4l2_fh_del     vmlinux EXPORT_SYMBOL_GPL
++0xcefcd99a    serial8250_unregister_port      vmlinux EXPORT_SYMBOL
++0x0bed6399    __xfrm_policy_check     vmlinux EXPORT_SYMBOL
++0xf1947b5c    snd_ctl_rename_id       vmlinux EXPORT_SYMBOL
++0xb9220639    blk_lld_busy    vmlinux EXPORT_SYMBOL_GPL
++0x4178eee3    blk_sync_queue  vmlinux EXPORT_SYMBOL
++0x32b0e045    usbnet_get_link vmlinux EXPORT_SYMBOL_GPL
++0xd578f42c    fat_alloc_new_dir       vmlinux EXPORT_SYMBOL_GPL
++0x0eacb23a    simple_write_end        vmlinux EXPORT_SYMBOL
++0xcbee20b2    get_cpu_iowait_time_us  vmlinux EXPORT_SYMBOL_GPL
++0xea01bd2a    st_sensors_init_sensor  vmlinux EXPORT_SYMBOL
++0xb7433944    hid_open_report vmlinux EXPORT_SYMBOL_GPL
++0x2d339a62    scsi_schedule_eh        vmlinux EXPORT_SYMBOL_GPL
++0xc6544448    pm_runtime_irq_safe     vmlinux EXPORT_SYMBOL_GPL
++0xa5afacf6    class_unregister        vmlinux EXPORT_SYMBOL_GPL
++0xedf69cd6    drm_gem_private_object_init     vmlinux EXPORT_SYMBOL
++0x999c3148    __raw_readsb    vmlinux EXPORT_SYMBOL
++0xfb268a5f    ip_mc_rejoin_groups     vmlinux EXPORT_SYMBOL
++0xafe4c25e    netdev_update_features  vmlinux EXPORT_SYMBOL
++0xd75c79df    smp_call_function       vmlinux EXPORT_SYMBOL
++0xef6c3f70    round_jiffies_up_relative       vmlinux EXPORT_SYMBOL_GPL
++0x64420947    spi_async       vmlinux EXPORT_SYMBOL_GPL
++0xe62c2cf6    regmap_raw_write_async  vmlinux EXPORT_SYMBOL_GPL
++0x226a057d    eth_header_cache        vmlinux EXPORT_SYMBOL
++0xb9d025c9    llist_del_first vmlinux EXPORT_SYMBOL_GPL
++0xb678366f    int_sqrt        vmlinux EXPORT_SYMBOL
++0x9d28f747    dec_zone_page_state     vmlinux EXPORT_SYMBOL
++0x0799aca4    local_bh_enable vmlinux EXPORT_SYMBOL
++0x8d07023c    i2c_smbus_read_byte_data        vmlinux EXPORT_SYMBOL
++0xca5dbc50    scsi_print_sense_hdr    vmlinux EXPORT_SYMBOL
++0x3da076a8    scsi_host_lookup        vmlinux EXPORT_SYMBOL
++0xf54ff64f    uart_set_options        vmlinux EXPORT_SYMBOL_GPL
++0x47ff399f    regulator_is_supported_voltage  vmlinux EXPORT_SYMBOL_GPL
++0x585469ee    of_get_videomode        vmlinux EXPORT_SYMBOL_GPL
++0x852786a9    phy_get vmlinux EXPORT_SYMBOL_GPL
++0xaf8aa518    system_rev      vmlinux EXPORT_SYMBOL
++0x6c3d2a02    tcp_syn_flood_action    vmlinux EXPORT_SYMBOL
++0xf38bcdf3    nf_conntrack_max        vmlinux EXPORT_SYMBOL_GPL
++0x44de5177    snd_pcm_suspend vmlinux EXPORT_SYMBOL
++0xb23ef570    blk_bio_map_sg  vmlinux EXPORT_SYMBOL
++0x4c5e7289    config_item_get vmlinux EXPORT_SYMBOL
++0xea12473b    config_item_put vmlinux EXPORT_SYMBOL
++0xbe68ef11    mnt_drop_write_file     vmlinux EXPORT_SYMBOL
++0x381144a9    __tracepoint_module_get vmlinux EXPORT_SYMBOL
++0xc5fdef94    call_usermodehelper     vmlinux EXPORT_SYMBOL
++0x1eb9516e    round_jiffies_relative  vmlinux EXPORT_SYMBOL_GPL
++0x7cc035a7    __ucmpdi2       vmlinux EXPORT_SYMBOL
++0xe42e1f70    klist_iter_init_node    vmlinux EXPORT_SYMBOL_GPL
++0x5c440c21    hci_conn_check_secure   vmlinux EXPORT_SYMBOL
++0x5b34d4b0    snd_soc_codec_readable_register vmlinux EXPORT_SYMBOL_GPL
++0x0634100a    bitmap_parselist_user   vmlinux EXPORT_SYMBOL
++0x5b72009f    ida_simple_get  vmlinux EXPORT_SYMBOL
++0x11a6ce4b    blk_queue_update_dma_alignment  vmlinux EXPORT_SYMBOL
++0x3e0dd939    blk_start_request       vmlinux EXPORT_SYMBOL
++0x51749fc8    _raw_read_lock_irq      vmlinux EXPORT_SYMBOL
++0x757bbc48    hrtimer_try_to_cancel   vmlinux EXPORT_SYMBOL_GPL
++0x70899e95    v4l2_m2m_buf_remove     vmlinux EXPORT_SYMBOL_GPL
++0x5f96a661    v4l2_ctrl_check vmlinux EXPORT_SYMBOL
++0x42bf1c34    video_unregister_device vmlinux EXPORT_SYMBOL
++0xcd914413    drm_get_minor   vmlinux EXPORT_SYMBOL
++0xa0e5202d    nf_register_hook        vmlinux EXPORT_SYMBOL
++0x86d5e343    __dev_get_by_name       vmlinux EXPORT_SYMBOL
++0x2cc749f6    skb_copy_and_csum_dev   vmlinux EXPORT_SYMBOL
++0x9613509a    idr_replace     vmlinux EXPORT_SYMBOL
++0x82acfb70    blk_iopoll_sched        vmlinux EXPORT_SYMBOL
++0x2c7db649    irq_dispose_mapping     vmlinux EXPORT_SYMBOL_GPL
++0x530b1e98    pm_suspend      vmlinux EXPORT_SYMBOL
++0xae69b1c1    usermodehelper_read_unlock      vmlinux EXPORT_SYMBOL_GPL
++0x39f4b0d2    s3c_adc_release vmlinux EXPORT_SYMBOL_GPL
++0xc2f16e25    input_unregister_handle vmlinux EXPORT_SYMBOL
++0x67326732    usb_hcd_map_urb_for_dma vmlinux EXPORT_SYMBOL_GPL
++0xd125790d    drm_hdmi_avi_infoframe_from_display_mode        vmlinux EXPORT_SYMBOL
++0xe10a472d    drm_mm_pre_get  vmlinux EXPORT_SYMBOL
++0xf082ddf3    register_netdev vmlinux EXPORT_SYMBOL
++0x935b5da0    snd_timer_continue      vmlinux EXPORT_SYMBOL
++0xcc37f55c    blk_limits_io_opt       vmlinux EXPORT_SYMBOL
++0xd4c5def3    inet_twsk_purge vmlinux EXPORT_SYMBOL_GPL
++0x9e9f1714    __bitmap_andnot vmlinux EXPORT_SYMBOL
++0x737de5e9    radix_tree_tag_get      vmlinux EXPORT_SYMBOL
++0xed1e0a03    posix_acl_from_xattr    vmlinux EXPORT_SYMBOL
++0x5256cd6e    clear_nlink     vmlinux EXPORT_SYMBOL
++0xc9f0ae5d    nf_xfrm_me_harder       vmlinux EXPORT_SYMBOL
++0x4751c2af    dev_loopback_xmit       vmlinux EXPORT_SYMBOL
++0x74bd982c    skb_seq_read    vmlinux EXPORT_SYMBOL
++0x798c5110    snd_soc_platform_trigger        vmlinux EXPORT_SYMBOL_GPL
++0x5362ae46    config_item_init        vmlinux EXPORT_SYMBOL
++0x83c8a355    param_set_int   vmlinux EXPORT_SYMBOL
++0x8099b954    i2c_transfer    vmlinux EXPORT_SYMBOL
++0x61e262f1    scsi_device_lookup      vmlinux EXPORT_SYMBOL
++0xfbb86a51    drm_i2c_encoder_prepare vmlinux EXPORT_SYMBOL
++0x4090c0fe    snd_card_file_add       vmlinux EXPORT_SYMBOL
++0x559879f5    crypto_drop_spawn       vmlinux EXPORT_SYMBOL_GPL
++0x27c2197f    param_set_short vmlinux EXPORT_SYMBOL
++0xcc4c1be7    nf_nat_tftp_hook        vmlinux EXPORT_SYMBOL_GPL
++0xc9a3b093    get_h225_addr   vmlinux EXPORT_SYMBOL_GPL
++0x59e9d996    skb_pad vmlinux EXPORT_SYMBOL
++0x77bc13a0    strim   vmlinux EXPORT_SYMBOL
++0x4c2a94b4    shash_register_instance vmlinux EXPORT_SYMBOL_GPL
++0x33c77d65    seq_write       vmlinux EXPORT_SYMBOL
++0x44aec3a4    generic_file_llseek     vmlinux EXPORT_SYMBOL
++0x12d60b5f    v4l2_ctrl_handler_free  vmlinux EXPORT_SYMBOL
++0x19f0c50a    ip6_tnl_parse_tlv_enc_lim       vmlinux EXPORT_SYMBOL
++0x1cea8d0a    snd_soc_dapm_new_widgets        vmlinux EXPORT_SYMBOL_GPL
++0xe1f4606d    snd_info_create_module_entry    vmlinux EXPORT_SYMBOL
++0x999e8297    vfree   vmlinux EXPORT_SYMBOL
++0x841575f5    wait_on_page_bit        vmlinux EXPORT_SYMBOL
++0x51205d4b    mutex_lock      vmlinux EXPORT_SYMBOL
++0xe97c74fd    rtc_update_irq_enable   vmlinux EXPORT_SYMBOL_GPL
++0x849722db    dma_request_slave_channel       vmlinux EXPORT_SYMBOL_GPL
++0x120b336a    __rb_insert_augmented   vmlinux EXPORT_SYMBOL
++0x6359b128    elv_rq_merge_ok vmlinux EXPORT_SYMBOL
++0xee3496c3    dma_pool_alloc  vmlinux EXPORT_SYMBOL
++0xa835f402    mmc_detect_card_removed vmlinux EXPORT_SYMBOL
++0xbe1b0b72    scsi_get_host_dev       vmlinux EXPORT_SYMBOL
++0xaf4e166f    dma_async_memcpy_pg_to_pg       vmlinux EXPORT_SYMBOL
++0xe34d76a6    l2cap_is_socket vmlinux EXPORT_SYMBOL
++0xd875e3e2    ip6_route_lookup        vmlinux EXPORT_SYMBOL_GPL
++0xd58c5fcb    tcp_v4_do_rcv   vmlinux EXPORT_SYMBOL
++0x3413b5de    blk_dump_rq_flags       vmlinux EXPORT_SYMBOL
++0xc8449f3c    sysfs_create_group      vmlinux EXPORT_SYMBOL_GPL
++0xf3e42ab4    get_device      vmlinux EXPORT_SYMBOL_GPL
++0xf147dcb2    hdmi_spd_infoframe_init vmlinux EXPORT_SYMBOL
++0x1776281f    xfrm_unregister_mode    vmlinux EXPORT_SYMBOL
++0x4737cc63    consume_skb     vmlinux EXPORT_SYMBOL
++0x72081296    extcon_find_cable_index vmlinux EXPORT_SYMBOL_GPL
++0x641d5fb6    usbnet_status_start     vmlinux EXPORT_SYMBOL_GPL
++0x8f2c5edc    scsi_add_device vmlinux EXPORT_SYMBOL
++0x8652db9f    __pm_stay_awake vmlinux EXPORT_SYMBOL_GPL
++0xb9d3a88c    tcf_action_dump_1       vmlinux EXPORT_SYMBOL
++0xb6f19e98    snd_pcm_lib_get_vmalloc_page    vmlinux EXPORT_SYMBOL
++0x29e5e6f3    poll_schedule_timeout   vmlinux EXPORT_SYMBOL
++0x99f58330    lg_local_lock_cpu       vmlinux EXPORT_SYMBOL
++0x58862e69    v4l2_m2m_ioctl_streamon vmlinux EXPORT_SYMBOL_GPL
++0xa340fae0    i2c_add_numbered_adapter        vmlinux EXPORT_SYMBOL_GPL
++0x806c2801    usb_unanchor_urb        vmlinux EXPORT_SYMBOL_GPL
++0x485b3745    dma_get_slave_channel   vmlinux EXPORT_SYMBOL_GPL
++0x1d0a43c3    phy_power_off   vmlinux EXPORT_SYMBOL_GPL
++0x0fd14a9d    tcp_prot        vmlinux EXPORT_SYMBOL
++0x4bfdc9e2    textsearch_prepare      vmlinux EXPORT_SYMBOL
++0x988958ef    fuse_direct_io  vmlinux EXPORT_SYMBOL_GPL
++0x996c4d30    proc_dointvec_ms_jiffies        vmlinux EXPORT_SYMBOL
++0x785d494b    rndis_msg_parser        vmlinux EXPORT_SYMBOL
++0xcea853d2    root_device_unregister  vmlinux EXPORT_SYMBOL_GPL
++0xf13f5821    inet_frag_kill  vmlinux EXPORT_SYMBOL
++0x8f4f1272    simple_setattr  vmlinux EXPORT_SYMBOL
++0x9c0dba49    simple_getattr  vmlinux EXPORT_SYMBOL
++0x2232a8a5    mempool_free    vmlinux EXPORT_SYMBOL
++0xc72ca946    v4l2_fh_release vmlinux EXPORT_SYMBOL_GPL
++0x2a0afd5e    videomode_from_timing   vmlinux EXPORT_SYMBOL_GPL
++0xaf157b0c    nfc_dep_link_is_up      vmlinux EXPORT_SYMBOL
++0x20efc937    tcf_em_tree_validate    vmlinux EXPORT_SYMBOL
++0xd05683cc    cred_to_ucred   vmlinux EXPORT_SYMBOL_GPL
++0xa1ac0050    sock_tx_timestamp       vmlinux EXPORT_SYMBOL
++0x48bd992d    bdget_disk      vmlinux EXPORT_SYMBOL
++0x50985501    configfs_register_subsystem     vmlinux EXPORT_SYMBOL
++0x041a8568    attribute_container_unregister  vmlinux EXPORT_SYMBOL_GPL
++0x3de4b634    driver_for_each_device  vmlinux EXPORT_SYMBOL_GPL
++0xc1984867    drm_vblank_put  vmlinux EXPORT_SYMBOL
++0xc8c20253    tcp_rcv_state_process   vmlinux EXPORT_SYMBOL
++0x280525ed    skb_to_sgvec    vmlinux EXPORT_SYMBOL_GPL
++0x20c55ae0    sscanf  vmlinux EXPORT_SYMBOL
++0xe3dd61a6    __breadahead    vmlinux EXPORT_SYMBOL
++0x1b42a36f    vb2_dma_contig_init_ctx vmlinux EXPORT_SYMBOL_GPL
++0xc326f752    v4l2_g_ctrl     vmlinux EXPORT_SYMBOL
++0x3adca4e5    pfifo_fast_ops  vmlinux EXPORT_SYMBOL
++0x67677183    snd_pcm_hw_constraint_integer   vmlinux EXPORT_SYMBOL
++0x1fab5905    wait_for_completion     vmlinux EXPORT_SYMBOL
++0x0b972255    led_classdev_suspend    vmlinux EXPORT_SYMBOL_GPL
++0xd617281d    wm8994_set_bits vmlinux EXPORT_SYMBOL_GPL
++0x4ad196c8    wm8994_reg_read vmlinux EXPORT_SYMBOL_GPL
++0xb3f0ca49    platform_device_register_full   vmlinux EXPORT_SYMBOL_GPL
++0x13bfa97e    devm_gpio_free  vmlinux EXPORT_SYMBOL
++0xe5646321    dev_get_by_name_rcu     vmlinux EXPORT_SYMBOL
++0x8fed35b2    snd_soc_dpcm_can_be_free_stop   vmlinux EXPORT_SYMBOL_GPL
++0x30a4f4ca    bstr_printf     vmlinux EXPORT_SYMBOL_GPL
++0x72350130    ___ratelimit    vmlinux EXPORT_SYMBOL
++0x0e5d4fe1    i2c_smbus_write_byte_data       vmlinux EXPORT_SYMBOL
++0xe7d93ea1    usb_unlink_urb  vmlinux EXPORT_SYMBOL_GPL
++0xaf141636    __nf_nat_mangle_tcp_packet      vmlinux EXPORT_SYMBOL
++0x584e1dcb    wm_hubs_add_analogue_controls   vmlinux EXPORT_SYMBOL_GPL
++0x15e14e37    snd_dma_alloc_pages     vmlinux EXPORT_SYMBOL
++0x3a26ed11    sched_clock     vmlinux EXPORT_SYMBOL_GPL
++0x6f5d8c04    iio_device_unregister   vmlinux EXPORT_SYMBOL
++0x9e672ff6    scsi_kmap_atomic_sg     vmlinux EXPORT_SYMBOL
++0xe8d95e86    platform_device_add_data        vmlinux EXPORT_SYMBOL_GPL
++0x1fcece42    inet_twdr_twcal_tick    vmlinux EXPORT_SYMBOL_GPL
++0xd1f0ea5e    sk_unattached_filter_destroy    vmlinux EXPORT_SYMBOL_GPL
++0xdb647fcf    sock_create_lite        vmlinux EXPORT_SYMBOL
++0x82b125fb    mmc_hw_reset_check      vmlinux EXPORT_SYMBOL
++0x45db3821    drm_gem_create_mmap_offset      vmlinux EXPORT_SYMBOL
++0x4eca00d2    nfc_proto_register      vmlinux EXPORT_SYMBOL
++0x8b69cf06    d_obtain_alias  vmlinux EXPORT_SYMBOL
++0xc7462fc5    cpufreq_unregister_governor     vmlinux EXPORT_SYMBOL_GPL
++0xc7280d53    v4l2_g_ext_ctrls        vmlinux EXPORT_SYMBOL
++0xb3b58737    ip6_datagram_connect    vmlinux EXPORT_SYMBOL_GPL
++0x365bf841    ip4_datagram_connect    vmlinux EXPORT_SYMBOL
++0x4a8cb865    tcp_timewait_state_process      vmlinux EXPORT_SYMBOL
++0xa34e2838    nf_conntrack_helper_try_module_get      vmlinux EXPORT_SYMBOL_GPL
++0x26dcd9ac    security_inode_init_security    vmlinux EXPORT_SYMBOL
++0xd705b4c7    schedule_hrtimeout      vmlinux EXPORT_SYMBOL_GPL
++0x44643b93    __aeabi_lmul    vmlinux EXPORT_SYMBOL
++0x824efa53    nobh_writepage  vmlinux EXPORT_SYMBOL
++0x78eb3b6d    clear_page_dirty_for_io vmlinux EXPORT_SYMBOL
++0xad6bf99a    srcu_init_notifier_head vmlinux EXPORT_SYMBOL_GPL
++0x9a1fc4b4    jiffies_to_timeval      vmlinux EXPORT_SYMBOL
++0xf1823632    clk_disable     vmlinux EXPORT_SYMBOL_GPL
++0x69da85e3    v4l2_ctrl_poll  vmlinux EXPORT_SYMBOL
++0xdcd7d2a3    starget_for_each_device vmlinux EXPORT_SYMBOL
++0x4dd58b53    subsys_interface_register       vmlinux EXPORT_SYMBOL_GPL
++0xf3916987    global_cursor_default   vmlinux EXPORT_SYMBOL
++0x3d2b2b9f    tcp_reno_min_cwnd       vmlinux EXPORT_SYMBOL_GPL
++0xf3bd26cd    vfs_follow_link vmlinux EXPORT_SYMBOL
++0xc11bd00f    tracepoint_probe_unregister     vmlinux EXPORT_SYMBOL_GPL
++0xb5532b8b    spi_bitbang_stop        vmlinux EXPORT_SYMBOL_GPL
++0x4deb10c3    tty_schedule_flip       vmlinux EXPORT_SYMBOL
++0x2dc227f8    brcmu_d11_attach        drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0xc009330d    sysfs_rename_link       vmlinux EXPORT_SYMBOL_GPL
++0xce0b9b59    max77693_read_reg       vmlinux EXPORT_SYMBOL_GPL
++0xc0c44856    tty_devnum      vmlinux EXPORT_SYMBOL
++0x4f391d0e    nla_parse       vmlinux EXPORT_SYMBOL
++0xc39a1e2a    write_dirty_buffer      vmlinux EXPORT_SYMBOL
++0xc8a154f9    noop_llseek     vmlinux EXPORT_SYMBOL
++0xc65d3eed    ring_buffer_entries_cpu vmlinux EXPORT_SYMBOL_GPL
++0x16807034    iommu_group_for_each_dev        vmlinux EXPORT_SYMBOL_GPL
++0x76829e1b    nfc_proto_unregister    vmlinux EXPORT_SYMBOL
++0x21ac8b77    iommu_group_get_by_id   vmlinux EXPORT_SYMBOL_GPL
++0x60601d69    input_free_device       vmlinux EXPORT_SYMBOL
++0x3a03067b    regulator_notifier_call_chain   vmlinux EXPORT_SYMBOL_GPL
++0x3e9110fa    __hw_addr_unsync        vmlinux EXPORT_SYMBOL
++0x7d11c268    jiffies vmlinux EXPORT_SYMBOL
++0x3987712e    iio_read_channel_scale  vmlinux EXPORT_SYMBOL_GPL
++0x7deff673    dm_consume_args vmlinux EXPORT_SYMBOL
++0xc092d57b    i2c_verify_adapter      vmlinux EXPORT_SYMBOL
++0x2e7a4300    drm_rgb_quant_range_selectable  vmlinux EXPORT_SYMBOL
++0x594e1317    __modsi3        vmlinux EXPORT_SYMBOL
++0x211331fa    __divsi3        vmlinux EXPORT_SYMBOL
++0xa3482467    dev_queue_xmit  vmlinux EXPORT_SYMBOL
++0x13d0adf7    __kfifo_out     vmlinux EXPORT_SYMBOL
++0xe06141e9    security_sk_clone       vmlinux EXPORT_SYMBOL
++0x75d5b827    proc_mkdir      vmlinux EXPORT_SYMBOL
++0x6f6ac78c    dummy_irq_chip  vmlinux EXPORT_SYMBOL_GPL
++0x3efb35c9    get_online_cpus vmlinux EXPORT_SYMBOL_GPL
++0x5907773b    of_device_alloc vmlinux EXPORT_SYMBOL
++0x1c00411e    blk_rq_map_sg   vmlinux EXPORT_SYMBOL
++0x09cf1b46    proc_dointvec_jiffies   vmlinux EXPORT_SYMBOL
++0x5db2254a    devm_usb_get_phy_by_phandle     vmlinux EXPORT_SYMBOL_GPL
++0x85caf365    usb_hcd_start_port_resume       vmlinux EXPORT_SYMBOL_GPL
++0x0a469d23    mfd_clone_cell  vmlinux EXPORT_SYMBOL
++0x93e85c29    dmam_free_noncoherent   vmlinux EXPORT_SYMBOL
++0x241ab4c2    phy_destroy     vmlinux EXPORT_SYMBOL_GPL
++0x408b2c52    __napi_schedule vmlinux EXPORT_SYMBOL
++0xc911f7d5    dev_change_carrier      vmlinux EXPORT_SYMBOL
++0xbfaa31e1    sk_stream_wait_memory   vmlinux EXPORT_SYMBOL
++0x0d3cb182    kstrtos16_from_user     vmlinux EXPORT_SYMBOL
++0x9f2bdaac    __bitmap_or     vmlinux EXPORT_SYMBOL
++0xae729e59    security_req_classify_flow      vmlinux EXPORT_SYMBOL
++0x273cbba4    get_dcookie     vmlinux EXPORT_SYMBOL_GPL
++0x9b7510d1    trace_event_raw_init    vmlinux EXPORT_SYMBOL_GPL
++0xb24585bc    usb_set_interface       vmlinux EXPORT_SYMBOL_GPL
++0x08cbe96c    tty_unlock      vmlinux EXPORT_SYMBOL
++0x07e3f668    netlink_broadcast_filtered      vmlinux EXPORT_SYMBOL
++0x4761f17c    register_netevent_notifier      vmlinux EXPORT_SYMBOL_GPL
++0xc7ec6c27    strspn  vmlinux EXPORT_SYMBOL
++0x97255bdf    strlen  vmlinux EXPORT_SYMBOL
++0xcdb399d4    cgroup_rightmost_descendant     vmlinux EXPORT_SYMBOL_GPL
++0x4bc7787e    iio_trigger_register    vmlinux EXPORT_SYMBOL
++0x05d7e32a    pm_generic_runtime_idle vmlinux EXPORT_SYMBOL_GPL
++0xcb0b5e8e    of_display_timings_exist        vmlinux EXPORT_SYMBOL_GPL
++0xdb68bbad    rfkill_destroy  vmlinux EXPORT_SYMBOL
++0x2e6a04e3    hci_recv_frame  vmlinux EXPORT_SYMBOL
++0xedbaee5e    nla_strcmp      vmlinux EXPORT_SYMBOL
++0x26bb950b    __kfifo_from_user_r     vmlinux EXPORT_SYMBOL
++0xca2ff6df    crypto_ahash_type       vmlinux EXPORT_SYMBOL_GPL
++0x2c41c751    v4l2_m2m_ctx_release    vmlinux EXPORT_SYMBOL_GPL
++0x99213409    scsi_allocate_command   vmlinux EXPORT_SYMBOL
++0x6827603e    skb_trim        vmlinux EXPORT_SYMBOL
++0x5cca80cf    perf_tp_event   vmlinux EXPORT_SYMBOL_GPL
++0xa6961e25    vb2_common_vm_ops       vmlinux EXPORT_SYMBOL_GPL
++0x72856c9e    v4l2_m2m_ioctl_expbuf   vmlinux EXPORT_SYMBOL_GPL
++0xb8acff80    usb_enable_autosuspend  vmlinux EXPORT_SYMBOL_GPL
++0x403f9529    gpio_request_one        vmlinux EXPORT_SYMBOL_GPL
++0x06d549e6    pinctrl_free_gpio       vmlinux EXPORT_SYMBOL_GPL
++0x02ae8433    xfrm_policy_delete      vmlinux EXPORT_SYMBOL
++0x6e71c6be    inet_frags_init vmlinux EXPORT_SYMBOL
++0x4e3567f7    match_int       vmlinux EXPORT_SYMBOL
++0x054434d6    radix_tree_tag_set      vmlinux EXPORT_SYMBOL
++0x31f956eb    blk_queue_lld_busy      vmlinux EXPORT_SYMBOL_GPL
++0x26565c84    shash_free_instance     vmlinux EXPORT_SYMBOL_GPL
++0x38668bab    debugfs_create_x64      vmlinux EXPORT_SYMBOL_GPL
++0xbf1f9a9b    bdi_setup_and_register  vmlinux EXPORT_SYMBOL
++0xfc64abed    power_supply_changed    vmlinux EXPORT_SYMBOL_GPL
++0x19326753    rtc_irq_register        vmlinux EXPORT_SYMBOL_GPL
++0xaf3cc095    nfc_hci_free_device     vmlinux EXPORT_SYMBOL
++0x86f38980    skb_cow_data    vmlinux EXPORT_SYMBOL_GPL
++0xe0c0d2af    snd_pcm_kernel_ioctl    vmlinux EXPORT_SYMBOL
++0xdfb01a80    cpu_v7_dcache_clean_area        vmlinux EXPORT_SYMBOL
++0x1879fcbd    bridge_tunnel_header    vmlinux EXPORT_SYMBOL
++0x9a011a6b    l2cap_conn_put  vmlinux EXPORT_SYMBOL
++0x6b3ee85a    ip4_datagram_release_cb vmlinux EXPORT_SYMBOL_GPL
++0xdd07d415    snd_card_free_when_closed       vmlinux EXPORT_SYMBOL
++0x868acba5    get_options     vmlinux EXPORT_SYMBOL
++0xa2409544    setup_irq       vmlinux EXPORT_SYMBOL_GPL
++0x567b73f9    i2c_get_adapter vmlinux EXPORT_SYMBOL
++0x7a4e7297    drm_edid_block_valid    vmlinux EXPORT_SYMBOL
++0x2ec524ad    __kfifo_in_r    vmlinux EXPORT_SYMBOL
++0x66f9da32    bh_uptodate_or_lock     vmlinux EXPORT_SYMBOL
++0xf9ffcd69    input_unregister_handler        vmlinux EXPORT_SYMBOL
++0x51dce73b    xfrm_state_walk_init    vmlinux EXPORT_SYMBOL
++0x113554e9    __skb_dst_set_noref     vmlinux EXPORT_SYMBOL
++0x3c9d1211    string_get_size vmlinux EXPORT_SYMBOL
++0xe654362e    fat_fill_super  vmlinux EXPORT_SYMBOL_GPL
++0xea5a46e7    register_exec_domain    vmlinux EXPORT_SYMBOL
++0xaf473214    iio_channel_get_all     vmlinux EXPORT_SYMBOL_GPL
++0xf8a9d6b2    rtc_read_alarm  vmlinux EXPORT_SYMBOL_GPL
++0xa0c8e0ed    usbnet_set_settings     vmlinux EXPORT_SYMBOL_GPL
++0x170bb6a9    usbnet_get_settings     vmlinux EXPORT_SYMBOL_GPL
++0xe0701fe6    fl6_sock_lookup vmlinux EXPORT_SYMBOL_GPL
++0x9330cb9f    sg_alloc_table  vmlinux EXPORT_SYMBOL
++0x5873f4c0    handle_simple_irq       vmlinux EXPORT_SYMBOL_GPL
++0xf27977e2    async_synchronize_cookie_domain vmlinux EXPORT_SYMBOL_GPL
++0xcf732e49    call_usermodehelper_exec        vmlinux EXPORT_SYMBOL
++0xd789a39d    cpufreq_governor_dbs    vmlinux EXPORT_SYMBOL_GPL
++0x4ff0c84f    of_mdio_find_bus        vmlinux EXPORT_SYMBOL
++0xe7a664c4    nf_hooks        vmlinux EXPORT_SYMBOL
++0xd366806d    snd_info_free_entry     vmlinux EXPORT_SYMBOL
++0xbcac6160    pm_qos_remove_notifier  vmlinux EXPORT_SYMBOL_GPL
++0x698d1e98    v4l2_ctrl_handler_init_class    vmlinux EXPORT_SYMBOL
++0x79c0d5a3    drm_gem_prime_fd_to_handle      vmlinux EXPORT_SYMBOL
++0xff1e9dd8    seq_list_start  vmlinux EXPORT_SYMBOL
++0x01accd73    __clk_get_name  vmlinux EXPORT_SYMBOL_GPL
++0x3e92b3d3    power_supply_unregister vmlinux EXPORT_SYMBOL_GPL
++0x71590103    drm_release     vmlinux EXPORT_SYMBOL
++0x0b9e5852    xfrm_aead_get_byname    vmlinux EXPORT_SYMBOL_GPL
++0xb7b856bf    km_state_notify vmlinux EXPORT_SYMBOL
++0x3f5b1415    nf_ct_port_nlattr_to_tuple      vmlinux EXPORT_SYMBOL_GPL
++0x98b6628a    snd_pcm_set_ops vmlinux EXPORT_SYMBOL
++0x1ea06663    _raw_write_lock vmlinux EXPORT_SYMBOL
++0x44dd3d8d    completion_done vmlinux EXPORT_SYMBOL
++0xa1eabd87    drm_mode_list_concat    vmlinux EXPORT_SYMBOL
++0x581ed292    drm_mm_get_block_generic        vmlinux EXPORT_SYMBOL
++0xefa98e30    dma_run_dependencies    vmlinux EXPORT_SYMBOL_GPL
++0xe8bea3bc    qdisc_put_stab  vmlinux EXPORT_SYMBOL
++0x2247cba2    seq_printf      vmlinux EXPORT_SYMBOL
++0x7e646f56    media_entity_remove_links       vmlinux EXPORT_SYMBOL_GPL
++0xa0e05fb1    drm_connector_cleanup   vmlinux EXPORT_SYMBOL
++0xb1cf44df    fb_find_best_mode       vmlinux EXPORT_SYMBOL
++0x0b742fd7    simple_strtol   vmlinux EXPORT_SYMBOL
++0xd709e32c    ilookup5_nowait vmlinux EXPORT_SYMBOL
++0x25865b31    mmc_free_host   vmlinux EXPORT_SYMBOL
++0x054063e9    devres_release  vmlinux EXPORT_SYMBOL_GPL
++0xc9b2045b    drm_mode_validate_size  vmlinux EXPORT_SYMBOL
++0xac6855b0    gen_kill_estimator      vmlinux EXPORT_SYMBOL
++0xc32b07a0    blk_queue_alignment_offset      vmlinux EXPORT_SYMBOL
++0x630c9194    fuse_dev_operations     vmlinux EXPORT_SYMBOL_GPL
++0xa4824580    devm_add_action vmlinux EXPORT_SYMBOL_GPL
++0xd8fe5b35    drm_mm_init     vmlinux EXPORT_SYMBOL
++0x9b9b05b4    __bio_clone     vmlinux EXPORT_SYMBOL
++0x5fda0227    vfs_stat        vmlinux EXPORT_SYMBOL
++0xa0fbac79    wake_up_bit     vmlinux EXPORT_SYMBOL
++0x796fc5ce    scsi_get_sense_info_fld vmlinux EXPORT_SYMBOL
++0x699ffdcd    nf_conntrack_flush_report       vmlinux EXPORT_SYMBOL_GPL
++0x89e6edac    snd_pcm_lib_malloc_pages        vmlinux EXPORT_SYMBOL
++0x48034724    zlib_deflateReset       vmlinux EXPORT_SYMBOL
++0xcdca3691    nr_irqs vmlinux EXPORT_SYMBOL_GPL
++0xcff6b676    _raw_spin_trylock_bh    vmlinux EXPORT_SYMBOL
++0xca45efbc    drm_format_horz_chroma_subsampling      vmlinux EXPORT_SYMBOL
++0xb6f4cc92    tty_do_resize   vmlinux EXPORT_SYMBOL
++0x51e77c97    pfn_valid       vmlinux EXPORT_SYMBOL
++0xa2446605    jbd2_journal_set_triggers       vmlinux EXPORT_SYMBOL
++0xebbb44c8    f_setown        vmlinux EXPORT_SYMBOL
++0xdfef3371    v4l2_m2m_ioctl_streamoff        vmlinux EXPORT_SYMBOL_GPL
++0x56c8799d    scsi_kunmap_atomic_sg   vmlinux EXPORT_SYMBOL
++0xaae1593e    scsi_block_when_processing_errors       vmlinux EXPORT_SYMBOL
++0xe330bf1f    ip6_dst_hoplimit        vmlinux EXPORT_SYMBOL
++0xf8996ee4    arp_invalidate  vmlinux EXPORT_SYMBOL
++0x6d27ef64    __bitmap_empty  vmlinux EXPORT_SYMBOL
++0xbfa789ca    elv_unregister  vmlinux EXPORT_SYMBOL_GPL
++0x06ae2b19    mmc_can_sanitize        vmlinux EXPORT_SYMBOL
++0xdd3dc2ce    usb_clear_halt  vmlinux EXPORT_SYMBOL_GPL
++0xfe0b2aae    amba_device_unregister  vmlinux EXPORT_SYMBOL
++0xc3771b21    of_pwm_get      vmlinux EXPORT_SYMBOL_GPL
++0x21b7d56d    dev_mc_sync_multiple    vmlinux EXPORT_SYMBOL
++0x1dfc5292    dev_uc_sync_multiple    vmlinux EXPORT_SYMBOL
++0xde7da8e3    submit_bh       vmlinux EXPORT_SYMBOL
++0xc15d05d9    mnt_clone_write vmlinux EXPORT_SYMBOL_GPL
++0x25fa84a3    page_mkclean    vmlinux EXPORT_SYMBOL_GPL
++0x405c1144    get_seconds     vmlinux EXPORT_SYMBOL
++0xf0f1246c    kvasprintf      vmlinux EXPORT_SYMBOL
++0xa5526619    rb_insert_color vmlinux EXPORT_SYMBOL
++0x7bb12a75    v4l2_m2m_get_vq vmlinux EXPORT_SYMBOL
++0x5819c8aa    usb_anchor_empty        vmlinux EXPORT_SYMBOL_GPL
++0x4e3d273c    __xfrm_init_state       vmlinux EXPORT_SYMBOL
++0xa2a69edc    __module_text_address   vmlinux EXPORT_SYMBOL_GPL
++0x66d87d38    symbol_put_addr vmlinux EXPORT_SYMBOL_GPL
++0xe45cc839    hrtimer_start_range_ns  vmlinux EXPORT_SYMBOL_GPL
++0xd3e6f60d    cpu_possible_mask       vmlinux EXPORT_SYMBOL
++0x52451ffe    hid_dump_field  vmlinux EXPORT_SYMBOL_GPL
++0xbd5a9986    drm_helper_probe_single_connector_modes vmlinux EXPORT_SYMBOL
++0xb694ce34    tcf_hash_search vmlinux EXPORT_SYMBOL
++0xaaefb815    d_alloc vmlinux EXPORT_SYMBOL
++0xaca38c86    unuse_mm        vmlinux EXPORT_SYMBOL_GPL
++0x5de3d7af    __alloc_pages_nodemask  vmlinux EXPORT_SYMBOL
++0xe2142ad8    i2c_smbus_read_word_data        vmlinux EXPORT_SYMBOL
++0xbfe4cfe6    tty_buffer_request_room vmlinux EXPORT_SYMBOL_GPL
++0xa6089679    elv_abort_queue vmlinux EXPORT_SYMBOL
++0x918ad429    ring_buffer_lock_reserve        vmlinux EXPORT_SYMBOL_GPL
++0xdc461430    irq_set_affinity_hint   vmlinux EXPORT_SYMBOL_GPL
++0x37258879    iio_channel_release     vmlinux EXPORT_SYMBOL_GPL
++0x1a082d69    max77693_update_reg     vmlinux EXPORT_SYMBOL_GPL
++0x4b0bd573    wiphy_unregister        vmlinux EXPORT_SYMBOL
++0x575d8c47    inet_sk_rx_dst_set      vmlinux EXPORT_SYMBOL
++0x3c6f5a97    snd_soc_register_component      vmlinux EXPORT_SYMBOL_GPL
++0xb9e03943    blk_execute_rq_nowait   vmlinux EXPORT_SYMBOL_GPL
++0x15f571ec    blk_set_stacking_limits vmlinux EXPORT_SYMBOL
++0x721585fd    security_inode_mkdir    vmlinux EXPORT_SYMBOL_GPL
++0xbf16ef9a    clk_get_rate    vmlinux EXPORT_SYMBOL_GPL
++0x22b79dae    clk_set_rate    vmlinux EXPORT_SYMBOL_GPL
++0x0dbd0e20    of_property_read_u8_array       vmlinux EXPORT_SYMBOL_GPL
++0xe6fce6f2    v4l2_ctrl_merge vmlinux EXPORT_SYMBOL
++0x12f1d8d3    dev_err vmlinux EXPORT_SYMBOL
++0x1c3e0368    drm_gem_object_handle_free      vmlinux EXPORT_SYMBOL
++0xfda9ed46    udp_proc_register       vmlinux EXPORT_SYMBOL
++0xccf2974f    kernel_sendpage vmlinux EXPORT_SYMBOL
++0x4b77922a    delete_from_page_cache  vmlinux EXPORT_SYMBOL
++0x3f5b67d5    wait_for_completion_killable    vmlinux EXPORT_SYMBOL
++0xa62fb61a    usb_gstrings_attach     vmlinux EXPORT_SYMBOL_GPL
++0x5cabdced    dev_pm_qos_remove_global_notifier       vmlinux EXPORT_SYMBOL_GPL
++0x27b864a9    s5p_gpio_get_drvstr     vmlinux EXPORT_SYMBOL
++0xc828d2a3    s5p_gpio_set_drvstr     vmlinux EXPORT_SYMBOL
++0xd9cf81bd    cfg80211_send_assoc_timeout     vmlinux EXPORT_SYMBOL
++0x693c3961    nf_ct_helper_hash       vmlinux EXPORT_SYMBOL_GPL
++0x487ef8ba    snd_soc_dai_set_sysclk  vmlinux EXPORT_SYMBOL_GPL
++0x50c89f23    __alloc_percpu  vmlinux EXPORT_SYMBOL_GPL
++0x09469482    kfree_call_rcu  vmlinux EXPORT_SYMBOL_GPL
++0x177d5d5e    uart_insert_char        vmlinux EXPORT_SYMBOL_GPL
++0xb17c2f9b    clear_inode     vmlinux EXPORT_SYMBOL
++0x3b733a7c    led_trigger_unregister  vmlinux EXPORT_SYMBOL_GPL
++0x16000a3c    dm_device_name  vmlinux EXPORT_SYMBOL_GPL
++0x0465ca31    scsi_cmd_get_serial     vmlinux EXPORT_SYMBOL
++0x0f52944d    drm_helper_hpd_irq_event        vmlinux EXPORT_SYMBOL
++0x99517682    udp_encap_enable        vmlinux EXPORT_SYMBOL
++0x1e43dec1    neigh_parms_release     vmlinux EXPORT_SYMBOL
++0x572e85d4    blk_lookup_devt vmlinux EXPORT_SYMBOL
++0xf7bb06b2    crypto_grab_skcipher    vmlinux EXPORT_SYMBOL_GPL
++0xe953b21f    get_next_ino    vmlinux EXPORT_SYMBOL
++0xdb225b82    pm_vt_switch_required   vmlinux EXPORT_SYMBOL
++0xe1a4b69f    mmc_card_awake  vmlinux EXPORT_SYMBOL
++0x33234a30    usb_hcd_link_urb_to_ep  vmlinux EXPORT_SYMBOL_GPL
++0xb61a0dba    dmam_release_declared_memory    vmlinux EXPORT_SYMBOL
++0x6865b5f6    device_release_driver   vmlinux EXPORT_SYMBOL_GPL
++0x920accbd    ump_dd_secure_id_get    vmlinux EXPORT_SYMBOL
++0xffb94ef0    _test_and_change_bit    vmlinux EXPORT_SYMBOL
++0xb7a1ff6d    tcp_prequeue    vmlinux EXPORT_SYMBOL
++0xce3ca308    copy_from_user_toio     vmlinux EXPORT_SYMBOL
++0xd08137e8    vfs_setlease    vmlinux EXPORT_SYMBOL_GPL
++0x89eabc8c    from_kgid_munged        vmlinux EXPORT_SYMBOL
++0x40d04664    console_trylock vmlinux EXPORT_SYMBOL
++0x0955d1f2    iommu_attach_device     vmlinux EXPORT_SYMBOL_GPL
++0x9cf3e94a    dm_kcopyd_copy  vmlinux EXPORT_SYMBOL
++0x1cec399d    v4l2_m2m_ioctl_create_bufs      vmlinux EXPORT_SYMBOL_GPL
++0x8cae11ac    usb_alloc_streams       vmlinux EXPORT_SYMBOL_GPL
++0xd3299096    scsi_register_interface vmlinux EXPORT_SYMBOL
++0x885369a2    dma_common_get_sgtable  vmlinux EXPORT_SYMBOL
++0x2251d13d    blk_queue_dma_pad       vmlinux EXPORT_SYMBOL
++0x07cf9099    wait_for_completion_timeout     vmlinux EXPORT_SYMBOL
++0x0efcbb1b    set_current_groups      vmlinux EXPORT_SYMBOL
++0xea9b0ab7    v4l2_ctrl_add_handler   vmlinux EXPORT_SYMBOL
++0x79aaab2b    i2c_smbus_read_block_data       vmlinux EXPORT_SYMBOL
++0x964ff64a    usb_put_intf    vmlinux EXPORT_SYMBOL_GPL
++0x9f97bf25    xfrm6_input_addr        vmlinux EXPORT_SYMBOL
++0x81db6ebb    xz_dec_reset    vmlinux EXPORT_SYMBOL
++0x661601de    sprint_symbol   vmlinux EXPORT_SYMBOL_GPL
++0x1e59773c    st_gyro_common_remove   vmlinux EXPORT_SYMBOL
++0x921e453c    drm_get_platform_dev    vmlinux EXPORT_SYMBOL
++0x720b245e    update_region   vmlinux EXPORT_SYMBOL
++0x2bda5922    hci_get_route   vmlinux EXPORT_SYMBOL
++0xaa939a8b    tcf_em_unregister       vmlinux EXPORT_SYMBOL
++0x590cf866    scm_fp_dup      vmlinux EXPORT_SYMBOL
++0x2ce98559    kcrypto_wq      vmlinux EXPORT_SYMBOL_GPL
++0x5351af17    shrink_dcache_parent    vmlinux EXPORT_SYMBOL
++0x1ad83009    trace_seq_vprintf       vmlinux EXPORT_SYMBOL_GPL
++0x8fcafa61    led_stop_software_blink vmlinux EXPORT_SYMBOL_GPL
++0xd4a7943a    mmc_card_can_sleep      vmlinux EXPORT_SYMBOL
++0x52f378a8    devres_remove   vmlinux EXPORT_SYMBOL_GPL
++0x6288b8b9    serial8250_release_dma  vmlinux EXPORT_SYMBOL_GPL
++0x63556dea    tty_vhangup     vmlinux EXPORT_SYMBOL
++0x75c8a11c    inet_twdr_twkill_work   vmlinux EXPORT_SYMBOL_GPL
++0x609f1c7e    synchronize_net vmlinux EXPORT_SYMBOL
++0x6091797f    synchronize_rcu vmlinux EXPORT_SYMBOL_GPL
++0x42825ce2    rcu_scheduler_active    vmlinux EXPORT_SYMBOL_GPL
++0xe523ad75    synchronize_irq vmlinux EXPORT_SYMBOL
++0xb77b0159    v4l2_prio_init  vmlinux EXPORT_SYMBOL
++0x840dd143    rndis_deregister        vmlinux EXPORT_SYMBOL
++0x7464ea38    dev_pm_qos_add_global_notifier  vmlinux EXPORT_SYMBOL_GPL
++0xd325a885    bus_for_each_dev        vmlinux EXPORT_SYMBOL_GPL
++0x3ec3d061    bus_for_each_drv        vmlinux EXPORT_SYMBOL_GPL
++0xb2823478    pneigh_lookup   vmlinux EXPORT_SYMBOL
++0x7037aaf0    kern_path_create        vmlinux EXPORT_SYMBOL
++0x85061b76    _raw_write_lock_bh      vmlinux EXPORT_SYMBOL
++0xb90cbedf    v4l2_of_get_next_endpoint       vmlinux EXPORT_SYMBOL
++0x9d2ed0a8    snd_timer_close vmlinux EXPORT_SYMBOL
++0x1057d320    blk_queue_find_tag      vmlinux EXPORT_SYMBOL
++0x1e3a88fb    trace_seq_printf        vmlinux EXPORT_SYMBOL_GPL
++0x4bc62a81    audit_enabled   vmlinux EXPORT_SYMBOL_GPL
++0x39461d6a    in_egroup_p     vmlinux EXPORT_SYMBOL
++0xccefabad    drm_mode_create_scaling_mode_property   vmlinux EXPORT_SYMBOL
++0x43384bd9    drm_buffer_alloc        vmlinux EXPORT_SYMBOL
++0x184e6c85    radix_tree_gang_lookup_slot     vmlinux EXPORT_SYMBOL
++0xdf347b52    sec_reg_read    vmlinux EXPORT_SYMBOL_GPL
++0x409873e3    tty_termios_baud_rate   vmlinux EXPORT_SYMBOL
++0x07a890c8    fb_alloc_cmap   vmlinux EXPORT_SYMBOL
++0x7d04aaa6    nf_conntrack_broadcast_help     vmlinux EXPORT_SYMBOL_GPL
++0x5cdc7a62    skb_append_datato_frags vmlinux EXPORT_SYMBOL
++0x9e0c711d    vzalloc_node    vmlinux EXPORT_SYMBOL
++0x7f24de73    jiffies_to_usecs        vmlinux EXPORT_SYMBOL
++0x37befc70    jiffies_to_msecs        vmlinux EXPORT_SYMBOL
++0xe9807d5b    input_mt_sync_frame     vmlinux EXPORT_SYMBOL
++0x0c0c8520    release_firmware        vmlinux EXPORT_SYMBOL
++0x442aa46d    tcp_child_process       vmlinux EXPORT_SYMBOL
++0x67663177    sock_diag_put_filterinfo        vmlinux EXPORT_SYMBOL
++0xa250c838    param_get_charp vmlinux EXPORT_SYMBOL
++0xf0b613ad    __pm_runtime_suspend    vmlinux EXPORT_SYMBOL_GPL
++0x1a770ac3    drm_detect_hdmi_monitor vmlinux EXPORT_SYMBOL
++0x70d7e40d    prepare_binprm  vmlinux EXPORT_SYMBOL
++0x36d7b11a    of_find_matching_node_and_match vmlinux EXPORT_SYMBOL
++0x8e30ad82    mdiobus_write   vmlinux EXPORT_SYMBOL
++0xeb6173b8    tty_port_destroy        vmlinux EXPORT_SYMBOL
++0x6c0154da    tcp_v4_destroy_sock     vmlinux EXPORT_SYMBOL
++0x5afe3100    snd_soc_add_dai_controls        vmlinux EXPORT_SYMBOL_GPL
++0xdf2c2742    rb_last vmlinux EXPORT_SYMBOL
++0x7ab3ca18    eventfd_ctx_read        vmlinux EXPORT_SYMBOL_GPL
++0xeb32e3af    mount_bdev      vmlinux EXPORT_SYMBOL
++0xe6fbe430    can_do_mlock    vmlinux EXPORT_SYMBOL
++0x60a13e90    rcu_barrier     vmlinux EXPORT_SYMBOL_GPL
++0xdf60cc27    __print_symbol  vmlinux EXPORT_SYMBOL
++0xa2a2031e    ehci_setup      vmlinux EXPORT_SYMBOL_GPL
++0x686f8200    ndisc_mc_map    vmlinux EXPORT_SYMBOL
++0xab8647cf    nf_ct_helper_expectfn_find_by_symbol    vmlinux EXPORT_SYMBOL_GPL
++0x91715312    sprintf vmlinux EXPORT_SYMBOL
++0xda3d10a8    security_tun_dev_open   vmlinux EXPORT_SYMBOL
++0xa4a91e54    simple_unlink   vmlinux EXPORT_SYMBOL
++0xf377a0b5    simple_attr_write       vmlinux EXPORT_SYMBOL_GPL
++0x97263968    generic_listxattr       vmlinux EXPORT_SYMBOL
++0x53c9394f    v4l2_ctrl_query_menu    vmlinux EXPORT_SYMBOL
++0xf6ebc03b    net_ratelimit   vmlinux EXPORT_SYMBOL
++0x3977cbea    dev_addr_init   vmlinux EXPORT_SYMBOL
++0x2789cd4f    snd_soc_put_strobe      vmlinux EXPORT_SYMBOL_GPL
++0x719074ee    snd_soc_get_strobe      vmlinux EXPORT_SYMBOL_GPL
++0xdace599d    shash_ahash_update      vmlinux EXPORT_SYMBOL_GPL
++0x7add44b5    posix_acl_valid vmlinux EXPORT_SYMBOL
++0xe8fbe1c9    invalidate_inode_buffers        vmlinux EXPORT_SYMBOL
++0x5442b464    media_device_register_entity    vmlinux EXPORT_SYMBOL_GPL
++0xa279bad0    usb_add_config  vmlinux EXPORT_SYMBOL_GPL
++0x1d77b0f8    unix_socket_table       vmlinux EXPORT_SYMBOL_GPL
++0x7932f1fc    ip_tunnel_ioctl vmlinux EXPORT_SYMBOL_GPL
++0x153b7ac0    nl_table        vmlinux EXPORT_SYMBOL_GPL
++0xfdfcdc90    crypto_shash_update     vmlinux EXPORT_SYMBOL_GPL
++0xa376521b    find_vma        vmlinux EXPORT_SYMBOL
++0xe57f0426    vb2_dma_contig_cleanup_ctx      vmlinux EXPORT_SYMBOL_GPL
++0x0f53690e    usb_autopm_get_interface_async  vmlinux EXPORT_SYMBOL_GPL
++0xe97e3624    scsi_register   vmlinux EXPORT_SYMBOL
++0x07d4567b    max8997_write_reg       vmlinux EXPORT_SYMBOL_GPL
++0x24f2d831    regulator_register_notifier     vmlinux EXPORT_SYMBOL_GPL
++0x85ab9275    nf_ct_extend_unregister vmlinux EXPORT_SYMBOL_GPL
++0x7721fbd2    kernel_connect  vmlinux EXPORT_SYMBOL
++0x3095e489    single_open_size        vmlinux EXPORT_SYMBOL
++0x54ff695a    inet_stream_connect     vmlinux EXPORT_SYMBOL
++0xa05c03df    mempool_kmalloc vmlinux EXPORT_SYMBOL
++0xd6df7b3f    dma_buf_end_cpu_access  vmlinux EXPORT_SYMBOL_GPL
++0x2d5eac78    qdisc_warn_nonwc        vmlinux EXPORT_SYMBOL
++0x7bc477d0    splice_from_pipe_begin  vmlinux EXPORT_SYMBOL
++0xfd6293c2    boot_tvec_bases vmlinux EXPORT_SYMBOL
++0x6d662533    _find_first_bit_le      vmlinux EXPORT_SYMBOL
++0xd41f3207    netdev_class_remove_file        vmlinux EXPORT_SYMBOL
++0xdf48a0eb    flex_array_put  vmlinux EXPORT_SYMBOL
++0xcf048d93    blk_queue_physical_block_size   vmlinux EXPORT_SYMBOL
++0xd5790350    dio_end_io      vmlinux EXPORT_SYMBOL_GPL
++0xc0bf6ead    timecounter_cyc2time    vmlinux EXPORT_SYMBOL_GPL
++0x303087f1    v4l2_queryctrl  vmlinux EXPORT_SYMBOL
++0x506691f1    sock_diag_check_cookie  vmlinux EXPORT_SYMBOL_GPL
++0x307c2fd0    generic_check_addressable       vmlinux EXPORT_SYMBOL
++0x40b313d1    perf_event_read_value   vmlinux EXPORT_SYMBOL_GPL
++0x04482cdb    __refrigerator  vmlinux EXPORT_SYMBOL
++0x7cb1ae69    cpu_down        vmlinux EXPORT_SYMBOL
++0xc9aca11e    v4l2_ctrl_handler_log_status    vmlinux EXPORT_SYMBOL
++0xb7f77027    rtc_tm_to_ktime vmlinux EXPORT_SYMBOL_GPL
++0x70c8201b    tty_lock_pair   vmlinux EXPORT_SYMBOL
++0x1565add4    inet6_csk_addr2sockaddr vmlinux EXPORT_SYMBOL_GPL
++0x72a112d9    netdev_refcnt_read      vmlinux EXPORT_SYMBOL
++0xacc6730b    __blk_end_request       vmlinux EXPORT_SYMBOL
++0xbe54542c    input_mt_init_slots     vmlinux EXPORT_SYMBOL
++0xca3920b5    usb_disable_lpm vmlinux EXPORT_SYMBOL_GPL
++0x0cd967c3    usb_disable_ltm vmlinux EXPORT_SYMBOL_GPL
++0x3b66b0c1    __pm_wakeup_event       vmlinux EXPORT_SYMBOL_GPL
++0x0f480178    devres_close_group      vmlinux EXPORT_SYMBOL_GPL
++0xf0bd9740    drm_mode_parse_command_line_for_connector       vmlinux EXPORT_SYMBOL
++0x12c6276a    drm_buffer_read_object  vmlinux EXPORT_SYMBOL
++0xc3b93bba    klist_next      vmlinux EXPORT_SYMBOL_GPL
++0x3d342d92    tcp_rcv_established     vmlinux EXPORT_SYMBOL
++0x540c6f94    inet_getpeer    vmlinux EXPORT_SYMBOL_GPL
++0x153c8015    ipv4_update_pmtu        vmlinux EXPORT_SYMBOL_GPL
++0x0c4bfb03    xt_unregister_targets   vmlinux EXPORT_SYMBOL
++0x5cd7eb9b    wm_hubs_dcs_done        vmlinux EXPORT_SYMBOL_GPL
++0xd7e56a4e    simple_strtoll  vmlinux EXPORT_SYMBOL
++0x20000329    simple_strtoul  vmlinux EXPORT_SYMBOL
++0x9e784e44    balance_dirty_pages_ratelimited vmlinux EXPORT_SYMBOL
++0x11195d33    usb_enable_lpm  vmlinux EXPORT_SYMBOL_GPL
++0xd7f91a45    usb_enable_ltm  vmlinux EXPORT_SYMBOL_GPL
++0x39e2b6d2    spi_alloc_master        vmlinux EXPORT_SYMBOL_GPL
++0x82eb671b    scsi_prep_fn    vmlinux EXPORT_SYMBOL
++0x4473fccc    nf_register_afinfo      vmlinux EXPORT_SYMBOL_GPL
++0xd1e13a97    net_ns_type_operations  vmlinux EXPORT_SYMBOL_GPL
++0x1bf69c17    proc_symlink    vmlinux EXPORT_SYMBOL
++0x651c3828    usb_add_phy_dev vmlinux EXPORT_SYMBOL_GPL
++0xf571b062    drm_addmap      vmlinux EXPORT_SYMBOL
++0xb41150b4    pwm_enable      vmlinux EXPORT_SYMBOL_GPL
++0x8c52195f    __rtnl_link_unregister  vmlinux EXPORT_SYMBOL_GPL
++0xe2cb9278    snd_soc_dai_set_tdm_slot        vmlinux EXPORT_SYMBOL_GPL
++0x4de34a07    cpu_rmap_put    vmlinux EXPORT_SYMBOL
++0xb51797f0    blk_queue_dma_alignment vmlinux EXPORT_SYMBOL
++0xdab3304e    remap_vmalloc_range     vmlinux EXPORT_SYMBOL
++0x5113c626    noop_backing_dev_info   vmlinux EXPORT_SYMBOL_GPL
++0xd985dc99    mempool_free_pages      vmlinux EXPORT_SYMBOL
++0xfcec0987    enable_irq      vmlinux EXPORT_SYMBOL
++0x1e7bbcb3    kernel_restart  vmlinux EXPORT_SYMBOL_GPL
++0xa26c3f65    mmc_gpio_free_cd        vmlinux EXPORT_SYMBOL
++0x6461806d    max8997_bulk_write      vmlinux EXPORT_SYMBOL_GPL
++0x2ff9c227    filemap_page_mkwrite    vmlinux EXPORT_SYMBOL
++0xd2917bd3    v4l2_m2m_fop_poll       vmlinux EXPORT_SYMBOL_GPL
++0xc11159cc    drm_mode_create vmlinux EXPORT_SYMBOL
++0xdd27fa87    memchr  vmlinux EXPORT_SYMBOL
++0x10329729    inet6_release   vmlinux EXPORT_SYMBOL
++0xc18ac88d    nf_ct_expect_hsize      vmlinux EXPORT_SYMBOL_GPL
++0x005e9828    vfs_kern_mount  vmlinux EXPORT_SYMBOL_GPL
++0xd5bd7dac    ring_buffer_record_enable_cpu   vmlinux EXPORT_SYMBOL_GPL
++0x00cf4a7f    of_get_parent   vmlinux EXPORT_SYMBOL
++0xd6097597    v4l2_ctrl_new_int_menu  vmlinux EXPORT_SYMBOL
++0x3cdbf719    drm_mode_destroy        vmlinux EXPORT_SYMBOL
++0xb03e9a0f    nfc_set_remote_general_bytes    vmlinux EXPORT_SYMBOL
++0x2059c814    sock_diag_register      vmlinux EXPORT_SYMBOL_GPL
++0x315c65fd    zlib_deflateInit2       vmlinux EXPORT_SYMBOL
++0x1ab8c624    submit_bio      vmlinux EXPORT_SYMBOL
++0xd070d52e    alloc_page_buffers      vmlinux EXPORT_SYMBOL_GPL
++0x622c7922    register_oom_notifier   vmlinux EXPORT_SYMBOL_GPL
++0xe806f5a2    trace_event_buffer_lock_reserve vmlinux EXPORT_SYMBOL_GPL
++0xcfc68341    synchronize_rcu_bh      vmlinux EXPORT_SYMBOL_GPL
++0x549525ef    handle_nested_irq       vmlinux EXPORT_SYMBOL_GPL
++0x20421305    on_each_cpu_mask        vmlinux EXPORT_SYMBOL
++0xa1bb9fb1    spi_bus_type    vmlinux EXPORT_SYMBOL_GPL
++0x8a627eb3    anon_transport_class_unregister vmlinux EXPORT_SYMBOL_GPL
++0xd8525ea7    fl6_update_dst  vmlinux EXPORT_SYMBOL_GPL
++0xbac1a16b    tcp_valid_rtt_meas      vmlinux EXPORT_SYMBOL
++0xb67cd6f1    neigh_lookup    vmlinux EXPORT_SYMBOL
++0xc2c639ae    debugfs_create_u32_array        vmlinux EXPORT_SYMBOL_GPL
++0xd4a33b98    mmc_remove_host vmlinux EXPORT_SYMBOL
++0x1f65abdf    usb_put_hcd     vmlinux EXPORT_SYMBOL_GPL
++0x2ef63ad6    scsi_dev_info_list_del_keyed    vmlinux EXPORT_SYMBOL
++0x0bf18882    tcp_mtup_init   vmlinux EXPORT_SYMBOL
++0x0ea07ec7    kstrtou8_from_user      vmlinux EXPORT_SYMBOL
++0x973d0f9e    kstrtoul_from_user      vmlinux EXPORT_SYMBOL
++0x7c8db884    devm_clk_unregister     vmlinux EXPORT_SYMBOL_GPL
++0x46066e5b    perf_pmu_name   vmlinux EXPORT_SYMBOL_GPL
++0x951ac153    snd_soc_jack_report     vmlinux EXPORT_SYMBOL_GPL
++0x7c1464a6    snd_soc_dapm_get_enum_double    vmlinux EXPORT_SYMBOL_GPL
++0xd36af700    snd_soc_dapm_put_enum_double    vmlinux EXPORT_SYMBOL_GPL
++0x222e7ce2    sysfs_streq     vmlinux EXPORT_SYMBOL
++0xca72b2e9    alloc_buffer_head       vmlinux EXPORT_SYMBOL
++0x364d71cb    iio_scan_mask_set       vmlinux EXPORT_SYMBOL_GPL
++0x813f3de4    v4l2_find_nearest_format        vmlinux EXPORT_SYMBOL_GPL
++0xb37a0603    drm_dp_link_train_channel_eq_delay      vmlinux EXPORT_SYMBOL
++0x1fe912f1    netdev_alloc_frag       vmlinux EXPORT_SYMBOL
++0x7bdee655    usbnet_get_endpoints    vmlinux EXPORT_SYMBOL_GPL
++0x589e4569    syscon_regmap_lookup_by_pdevname        vmlinux EXPORT_SYMBOL_GPL
++0x60506751    unmap_kernel_range_noflush      vmlinux EXPORT_SYMBOL_GPL
++0x224b5740    device_remove_file      vmlinux EXPORT_SYMBOL_GPL
++0x1b8822d8    pinctrl_gpio_direction_output   vmlinux EXPORT_SYMBOL_GPL
++0x985e0b7d    ipv6_skip_exthdr        vmlinux EXPORT_SYMBOL
++0xa0e33feb    ip_options_compile      vmlinux EXPORT_SYMBOL
++0x289c3714    nf_ct_alloc_hashtable   vmlinux EXPORT_SYMBOL_GPL
++0xc33e401a    sock_diag_unregister    vmlinux EXPORT_SYMBOL_GPL
++0xba86c38e    aio_complete    vmlinux EXPORT_SYMBOL
++0x03bd889d    param_get_ulong vmlinux EXPORT_SYMBOL
++0xa4ca666e    kill_pid        vmlinux EXPORT_SYMBOL
++0xe56cb560    rt6_lookup      vmlinux EXPORT_SYMBOL
++0xc8fb75a8    unix_outq_len   vmlinux EXPORT_SYMBOL_GPL
++0xd5c5ff75    inet_frags_init_net     vmlinux EXPORT_SYMBOL
++0x64999478    congestion_wait vmlinux EXPORT_SYMBOL
++0x59eae699    ring_buffer_read_prepare        vmlinux EXPORT_SYMBOL_GPL
++0xa23061f8    mmc_read_bkops_status   vmlinux EXPORT_SYMBOL
++0xa1c46bd3    spi_bitbang_cleanup     vmlinux EXPORT_SYMBOL_GPL
++0x4d126acf    device_store_int        vmlinux EXPORT_SYMBOL_GPL
++0x5b546bbb    drm_gem_mmap    vmlinux EXPORT_SYMBOL
++0xd37d6496    hci_recv_fragment       vmlinux EXPORT_SYMBOL
++0x1c86d31e    ip_tunnel_delete_net    vmlinux EXPORT_SYMBOL_GPL
++0x9684e8c6    blk_queue_dma_drain     vmlinux EXPORT_SYMBOL_GPL
++0xf89e28e9    config_item_set_name    vmlinux EXPORT_SYMBOL
++0x9d8331c0    ring_buffer_read_page   vmlinux EXPORT_SYMBOL_GPL
++0x572d0104    _raw_write_unlock_irqrestore    vmlinux EXPORT_SYMBOL
++0x8e7894bd    __atomic_notifier_call_chain    vmlinux EXPORT_SYMBOL_GPL
++0xb202dbc6    i2c_del_driver  vmlinux EXPORT_SYMBOL
++0x057ce975    hex_dump_to_buffer      vmlinux EXPORT_SYMBOL
++0xe09f5fdd    file_ra_state_init      vmlinux EXPORT_SYMBOL_GPL
++0x011c93d4    v4l2_m2m_reqbufs        vmlinux EXPORT_SYMBOL_GPL
++0x5b185975    __dma_request_channel   vmlinux EXPORT_SYMBOL_GPL
++0xe02299ef    nfc_hci_send_response   vmlinux EXPORT_SYMBOL
++0xe8beb828    crypto_larval_kill      vmlinux EXPORT_SYMBOL_GPL
++0x8704eb06    irq_set_default_host    vmlinux EXPORT_SYMBOL_GPL
++0x7ac1d551    vb2_prepare_buf vmlinux EXPORT_SYMBOL_GPL
++0xfcab3072    media_entity_cleanup    vmlinux EXPORT_SYMBOL_GPL
++0x75d69d69    usb_alloc_coherent      vmlinux EXPORT_SYMBOL_GPL
++0x2f3857a0    xfrm_register_mode      vmlinux EXPORT_SYMBOL
++0x09c1fbfd    inet_csk_get_port       vmlinux EXPORT_SYMBOL_GPL
++0x1e6fd62f    kiocb_set_cancel_fn     vmlinux EXPORT_SYMBOL
++0xb20a8d04    mmc_flush_cache vmlinux EXPORT_SYMBOL
++0xb321b21c    i2c_clients_command     vmlinux EXPORT_SYMBOL
++0xd77c0bc8    klist_remove    vmlinux EXPORT_SYMBOL_GPL
++0x8cfe5489    dev_get_flags   vmlinux EXPORT_SYMBOL
++0x8022b19a    crypto_sha256_update    vmlinux EXPORT_SYMBOL
++0x0adfab73    __wait_on_bit_lock      vmlinux EXPORT_SYMBOL
++0x4a169d0b    usb_get_status  vmlinux EXPORT_SYMBOL_GPL
++0xe5122890    flow_cache_genid        vmlinux EXPORT_SYMBOL
++0x31cef011    gen_new_estimator       vmlinux EXPORT_SYMBOL
++0xbb6bebbd    crypto_alg_mod_lookup   vmlinux EXPORT_SYMBOL_GPL
++0xe208f5c9    freeze_super    vmlinux EXPORT_SYMBOL
++0xbf5b2016    __devm_request_region   vmlinux EXPORT_SYMBOL
++0x7cd6f042    cpufreq_get_current_driver      vmlinux EXPORT_SYMBOL_GPL
++0x946f789a    input_class     vmlinux EXPORT_SYMBOL_GPL
++0x33abb76e    usb_remove_function     vmlinux EXPORT_SYMBOL_GPL
++0x54c41f03    __cfg80211_send_disassoc        vmlinux EXPORT_SYMBOL
++0x886bcea3    hid_connect     vmlinux EXPORT_SYMBOL_GPL
++0x1d4cf31c    mmc_set_data_timeout    vmlinux EXPORT_SYMBOL
++0x020bb7c4    v4l2_m2m_qbuf   vmlinux EXPORT_SYMBOL_GPL
++0xf5ef842e    v4l_bound_align_image   vmlinux EXPORT_SYMBOL_GPL
++0x628c65bc    usb_set_device_state    vmlinux EXPORT_SYMBOL_GPL
++0x1d182b56    scsi_autopm_get_device  vmlinux EXPORT_SYMBOL_GPL
++0xa8b77259    scsi_autopm_put_device  vmlinux EXPORT_SYMBOL_GPL
++0x2641488c    scsi_eh_finish_cmd      vmlinux EXPORT_SYMBOL
++0x773650a0    vc_cons vmlinux EXPORT_SYMBOL
++0x6d203b02    dma_async_device_unregister     vmlinux EXPORT_SYMBOL
++0x18c2227f    cpu_rmap_update vmlinux EXPORT_SYMBOL
++0xdd0a2ba2    strlcat vmlinux EXPORT_SYMBOL
++0xd627480b    strncat vmlinux EXPORT_SYMBOL
++0x0dd47f83    blk_queue_max_discard_sectors   vmlinux EXPORT_SYMBOL
++0xb3f7646e    kthread_should_stop     vmlinux EXPORT_SYMBOL
++0x8d335f49    mmc_can_reset   vmlinux EXPORT_SYMBOL
++0x474576c2    v4l2_ctrl_new_std_menu  vmlinux EXPORT_SYMBOL
++0x735d80ef    drm_add_edid_modes      vmlinux EXPORT_SYMBOL
++0xbfdbe956    nfnetlink_set_err       vmlinux EXPORT_SYMBOL_GPL
++0xc0891ac5    netdev_notice   vmlinux EXPORT_SYMBOL
++0x03b5c8d0    blk_rq_map_kern vmlinux EXPORT_SYMBOL
++0x20f6c302    sync_mapping_buffers    vmlinux EXPORT_SYMBOL
++0x5610de90    pm_generic_freeze_noirq vmlinux EXPORT_SYMBOL_GPL
++0x33186585    drm_prime_lookup_buf_handle     vmlinux EXPORT_SYMBOL
++0x5c746654    bt_sock_register        vmlinux EXPORT_SYMBOL
++0x1f2ca4fa    fat_scan        vmlinux EXPORT_SYMBOL_GPL
++0x4ade2e74    inode_change_ok vmlinux EXPORT_SYMBOL
++0x2b2264c1    __scsi_add_device       vmlinux EXPORT_SYMBOL
++0x3a8903bb    datagram_poll   vmlinux EXPORT_SYMBOL
++0x75767b6f    snd_pcm_hw_constraint_minmax    vmlinux EXPORT_SYMBOL
++0xe623e6db    blk_queue_end_tag       vmlinux EXPORT_SYMBOL
++0x1e9edfb7    seq_hlist_start_head_rcu        vmlinux EXPORT_SYMBOL
++0x69d38ed9    __scsi_print_sense      vmlinux EXPORT_SYMBOL
++0xc6de7303    __tty_alloc_driver      vmlinux EXPORT_SYMBOL
++0xcdb5f930    __tcf_em_tree_match     vmlinux EXPORT_SYMBOL
++0x7a0a2470    dev_uc_flush    vmlinux EXPORT_SYMBOL
++0x6c8f0d30    dev_mc_flush    vmlinux EXPORT_SYMBOL
++0x067d8d35    security_release_secctx vmlinux EXPORT_SYMBOL
++0xb10e668e    jbd2_journal_check_available_features   vmlinux EXPORT_SYMBOL
++0xe2e8ac87    flush_old_exec  vmlinux EXPORT_SYMBOL
++0x00c4dc87    timecounter_init        vmlinux EXPORT_SYMBOL_GPL
++0xeb793d66    media_device_register   vmlinux EXPORT_SYMBOL_GPL
++0x694be42a    usb_show_dynids vmlinux EXPORT_SYMBOL_GPL
++0xdf3ec432    drm_gem_object_alloc    vmlinux EXPORT_SYMBOL
++0xa3d3ab7e    inet_addr_type  vmlinux EXPORT_SYMBOL
++0x97a2e370    inet_recvmsg    vmlinux EXPORT_SYMBOL
++0x0b59390b    __tracepoint_rpm_suspend        vmlinux EXPORT_SYMBOL_GPL
++0xa4701e9e    timekeeping_inject_offset       vmlinux EXPORT_SYMBOL
++0x1f54f1b4    do_trace_rcu_torture_read       vmlinux EXPORT_SYMBOL_GPL
++0x6275fa23    mdiobus_unregister      vmlinux EXPORT_SYMBOL
++0x639399b9    ump_dd_phys_block_count_get     vmlinux EXPORT_SYMBOL
++0x6812cf8d    __tracepoint_rpm_idle   vmlinux EXPORT_SYMBOL_GPL
++0xaa90f5bc    phy_detach      vmlinux EXPORT_SYMBOL
++0x8ded75c5    mii_link_ok     vmlinux EXPORT_SYMBOL
++0xa6dd4938    cfg80211_inform_bss_frame       vmlinux EXPORT_SYMBOL
++0xd4cc3c98    bt_procfs_cleanup       vmlinux EXPORT_SYMBOL
++0xd856b532    tcp_proc_register       vmlinux EXPORT_SYMBOL
++0xb86a648c    nf_conntrack_l4proto_udp6       vmlinux EXPORT_SYMBOL_GPL
++0x2c81ec75    __irq_regs      vmlinux EXPORT_SYMBOL
++0x3f182756    generic_write_sync      vmlinux EXPORT_SYMBOL
++0x48bd4a65    wakeup_source_remove    vmlinux EXPORT_SYMBOL_GPL
++0x027c2c52    stop_tty        vmlinux EXPORT_SYMBOL
++0xc18578ed    process_srcu    vmlinux EXPORT_SYMBOL_GPL
++0xf3cf07b0    sdio_writel     vmlinux EXPORT_SYMBOL_GPL
++0x9b54326d    xfrm_policy_destroy     vmlinux EXPORT_SYMBOL
++0x667cc3f3    inet_del_offload        vmlinux EXPORT_SYMBOL
++0xbc9cfb6e    jbd2_journal_stop       vmlinux EXPORT_SYMBOL
++0x43aec82a    sdhci_pltfm_register    vmlinux EXPORT_SYMBOL_GPL
++0x1db8867b    sdio_memcpy_toio        vmlinux EXPORT_SYMBOL_GPL
++0x48499aa5    neigh_ifdown    vmlinux EXPORT_SYMBOL
++0x4b53ee2c    snd_pcm_hw_constraint_ratnums   vmlinux EXPORT_SYMBOL
++0x9650df0b    snd_ctl_replace vmlinux EXPORT_SYMBOL
++0x6c1ce5ce    strcspn vmlinux EXPORT_SYMBOL
++0xa68698f6    jbd2_journal_extend     vmlinux EXPORT_SYMBOL
++0x7eb6d1eb    thermal_zone_unbind_cooling_device      vmlinux EXPORT_SYMBOL_GPL
++0x81328587    blkdev_aio_write        vmlinux EXPORT_SYMBOL_GPL
++0xf8bec8e3    seq_bitmap_list vmlinux EXPORT_SYMBOL
++0xaec655c7    alloc_pages_exact       vmlinux EXPORT_SYMBOL
++0x6ce5ade9    hid_parse_report        vmlinux EXPORT_SYMBOL_GPL
++0x66f7b07e    ehci_resume     vmlinux EXPORT_SYMBOL_GPL
++0x95c578a0    ioremap_page_range      vmlinux EXPORT_SYMBOL_GPL
++0x498dcb5e    drm_ut_debug_printk     vmlinux EXPORT_SYMBOL
++0x6c1f6c7e    drm_rmmap       vmlinux EXPORT_SYMBOL
++0x8b55de97    devm_regulator_bulk_get vmlinux EXPORT_SYMBOL_GPL
++0x8190aef3    register_sound_special  vmlinux EXPORT_SYMBOL
++0x6c255d20    __nla_reserve   vmlinux EXPORT_SYMBOL
++0x29537c9e    alloc_chrdev_region     vmlinux EXPORT_SYMBOL
++0x05273827    inc_zone_page_state     vmlinux EXPORT_SYMBOL
++0xc665d6d7    of_parse_phandle_with_args      vmlinux EXPORT_SYMBOL
++0x01f7b595    usbnet_skb_return       vmlinux EXPORT_SYMBOL_GPL
++0x0740687f    arp_find        vmlinux EXPORT_SYMBOL
++0x269fbd1b    nf_ct_iterate_cleanup   vmlinux EXPORT_SYMBOL_GPL
++0x22ce6bb8    skb_checksum    vmlinux EXPORT_SYMBOL
++0x669f1bc1    kfree_skb_list  vmlinux EXPORT_SYMBOL
++0xca9360b5    rb_next vmlinux EXPORT_SYMBOL
++0x3c010e48    inode_permission        vmlinux EXPORT_SYMBOL
++0xba34ed58    buffer_migrate_page     vmlinux EXPORT_SYMBOL
++0x1cfb04fa    finish_wait     vmlinux EXPORT_SYMBOL
++0xcb0b79fb    max8997_read_reg        vmlinux EXPORT_SYMBOL_GPL
++0x564f1dca    klist_add_after vmlinux EXPORT_SYMBOL_GPL
++0x4cbbd171    __bitmap_weight vmlinux EXPORT_SYMBOL
++0x61b7b126    simple_strtoull vmlinux EXPORT_SYMBOL
++0x528c709d    simple_read_from_buffer vmlinux EXPORT_SYMBOL
++0x10c9d678    irq_domain_simple_ops   vmlinux EXPORT_SYMBOL_GPL
++0x5d8d802b    clockevent_delta2ns     vmlinux EXPORT_SYMBOL_GPL
++0xe8731295    gether_get_ifname       vmlinux EXPORT_SYMBOL
++0x8619c1c9    phy_start_aneg  vmlinux EXPORT_SYMBOL
++0x2a1c0adc    scsi_print_result       vmlinux EXPORT_SYMBOL
++0x6eb85693    nf_defrag_ipv6_enable   vmlinux EXPORT_SYMBOL_GPL
++0x6b6c3d10    nf_defrag_ipv4_enable   vmlinux EXPORT_SYMBOL_GPL
++0xa681fe88    generate_random_uuid    vmlinux EXPORT_SYMBOL
++0x3147857d    default_red     vmlinux EXPORT_SYMBOL
++0xff9ca065    fb_edid_to_monspecs     vmlinux EXPORT_SYMBOL
++0x22e14acd    gpiochip_add_pin_range  vmlinux EXPORT_SYMBOL_GPL
++0xad1bb027    nf_ct_free_hashtable    vmlinux EXPORT_SYMBOL_GPL
++0xaf509095    get_net_ns_by_pid       vmlinux EXPORT_SYMBOL_GPL
++0xcff75292    vfs_statfs      vmlinux EXPORT_SYMBOL
++0x2756ceb6    mmc_power_save_host     vmlinux EXPORT_SYMBOL
++0x438610bd    security_tun_dev_alloc_security vmlinux EXPORT_SYMBOL
++0xb1d9068c    ip6_datagram_send_ctl   vmlinux EXPORT_SYMBOL_GPL
++0x365c213d    udp_ioctl       vmlinux EXPORT_SYMBOL
++0x53877b9f    __nla_reserve_nohdr     vmlinux EXPORT_SYMBOL
++0xd64146c4    __get_page_tail vmlinux EXPORT_SYMBOL
++0x9b1bc5fa    i2c_new_probed_device   vmlinux EXPORT_SYMBOL_GPL
++0x3c787bd5    rtnetlink_put_metrics   vmlinux EXPORT_SYMBOL
++0xcb5c97f9    blk_queue_max_write_same_sectors        vmlinux EXPORT_SYMBOL
++0x3b909e7e    may_umount      vmlinux EXPORT_SYMBOL
++0x0c8099b1    v4l2_spi_new_subdev     vmlinux EXPORT_SYMBOL_GPL
++0xd00b0085    v4l2_ctrl_handler_setup vmlinux EXPORT_SYMBOL
++0xea10212a    int_to_scsilun  vmlinux EXPORT_SYMBOL
++0xcb0944d8    pwm_set_chip_data       vmlinux EXPORT_SYMBOL_GPL
++0xde5846c4    pwm_get_chip_data       vmlinux EXPORT_SYMBOL_GPL
++0x915917a3    block_read_full_page    vmlinux EXPORT_SYMBOL
++0xe5d61b91    console_drivers vmlinux EXPORT_SYMBOL_GPL
++0xb776298b    iommu_detach_device     vmlinux EXPORT_SYMBOL_GPL
++0xeb711ae7    snd_soc_params_to_bclk  vmlinux EXPORT_SYMBOL_GPL
++0x90ed601f    mmc_hw_reset    vmlinux EXPORT_SYMBOL
++0x1cbd340b    cdc_ncm_unbind  vmlinux EXPORT_SYMBOL_GPL
++0x9caab5b6    __scsi_alloc_queue      vmlinux EXPORT_SYMBOL
++0x2506e85a    bus_sort_breadthfirst   vmlinux EXPORT_SYMBOL_GPL
++0xd6769f27    ipt_alloc_initial_table vmlinux EXPORT_SYMBOL_GPL
++0x439fe23e    tcp_v4_connect  vmlinux EXPORT_SYMBOL
++0x02de3eaf    tcp_sync_mss    vmlinux EXPORT_SYMBOL
++0x4be85a03    memweight       vmlinux EXPORT_SYMBOL
++0x93021b18    jbd2_journal_ack_err    vmlinux EXPORT_SYMBOL
++0xd0c05159    emergency_restart       vmlinux EXPORT_SYMBOL_GPL
++0x3ff62317    local_bh_disable        vmlinux EXPORT_SYMBOL
++0xd88781bd    regmap_raw_write        vmlinux EXPORT_SYMBOL_GPL
++0xada38534    regulator_bulk_disable  vmlinux EXPORT_SYMBOL_GPL
++0x2ad4daf6    tcp_death_row   vmlinux EXPORT_SYMBOL_GPL
++0x87751cba    netdev_upper_dev_link   vmlinux EXPORT_SYMBOL
++0xe187693c    kstrtouint_from_user    vmlinux EXPORT_SYMBOL
++0xbe797e8f    bio_get_nr_vecs vmlinux EXPORT_SYMBOL
++0x2373352a    clk_fixed_factor_ops    vmlinux EXPORT_SYMBOL_GPL
++0xccbee9bd    mmc_set_blockcount      vmlinux EXPORT_SYMBOL
++0x9ebb3718    v4l2_clk_unregister     vmlinux EXPORT_SYMBOL
++0xe28ade94    serio_rescan    vmlinux EXPORT_SYMBOL
++0x1b5c713f    drm_send_vblank_event   vmlinux EXPORT_SYMBOL
++0xa257d9cd    framebuffer_alloc       vmlinux EXPORT_SYMBOL
++0x0916cc54    xfrm_policy_byid        vmlinux EXPORT_SYMBOL
++0x07319ef1    ahash_register_instance vmlinux EXPORT_SYMBOL_GPL
++0x11c55999    load_nls_default        vmlinux EXPORT_SYMBOL
++0xcae08d66    nonseekable_open        vmlinux EXPORT_SYMBOL
++0x3651150d    kmem_cache_create       vmlinux EXPORT_SYMBOL
++0xfd26424e    cpufreq_driver_target   vmlinux EXPORT_SYMBOL_GPL
++0x66adff69    vb2_fop_read    vmlinux EXPORT_SYMBOL_GPL
++0x09a5b743    amba_apb_device_add     vmlinux EXPORT_SYMBOL_GPL
++0x475100c2    inet_get_local_port_range       vmlinux EXPORT_SYMBOL
++0x8c1e0ffe    __seq_open_private      vmlinux EXPORT_SYMBOL
++0xd60c8ab0    seq_escape      vmlinux EXPORT_SYMBOL
++0xc81ec7cb    phy_get_eee_err vmlinux EXPORT_SYMBOL
++0x00778770    xfrm_ealg_get_byname    vmlinux EXPORT_SYMBOL_GPL
++0x5bc722fb    sock_alloc_file vmlinux EXPORT_SYMBOL
++0xddf821b8    page_address    vmlinux EXPORT_SYMBOL
++0x9771ccf0    of_mdiobus_register     vmlinux EXPORT_SYMBOL
++0x5eb24829    dm_shift_arg    vmlinux EXPORT_SYMBOL
++0x119e8920    v4l2_async_unregister_subdev    vmlinux EXPORT_SYMBOL
++0x7bc3e7c1    xfrm_lookup     vmlinux EXPORT_SYMBOL
++0xae0410db    skb_store_bits  vmlinux EXPORT_SYMBOL
++0xf86deaaa    page_cache_sync_readahead       vmlinux EXPORT_SYMBOL_GPL
++0x7681946c    unregister_pm_notifier  vmlinux EXPORT_SYMBOL_GPL
++0x3d98d961    inet_unregister_protosw vmlinux EXPORT_SYMBOL
++0x82108639    snd_soc_get_volsw       vmlinux EXPORT_SYMBOL_GPL
++0x286d040c    snd_soc_put_volsw       vmlinux EXPORT_SYMBOL_GPL
++0x371c0db7    blk_queue_bypass_end    vmlinux EXPORT_SYMBOL_GPL
++0x8589f760    mb_cache_entry_free     vmlinux EXPORT_SYMBOL
++0x87a795d4    i2c_probe_func_quick_read       vmlinux EXPORT_SYMBOL_GPL
++0xb05661a7    i2c_smbus_read_byte     vmlinux EXPORT_SYMBOL
++0x167977e6    platform_create_bundle  vmlinux EXPORT_SYMBOL_GPL
++0xb626c977    _dev_info       vmlinux EXPORT_SYMBOL
++0x0d5db696    arm_iommu_detach_device vmlinux EXPORT_SYMBOL_GPL
++0x001f6379    blkcipher_walk_phys     vmlinux EXPORT_SYMBOL_GPL
++0x3dfc897c    seq_hlist_start_head    vmlinux EXPORT_SYMBOL
++0xc34ff0bb    clocksource_change_rating       vmlinux EXPORT_SYMBOL
++0x5ace7e88    devres_for_each_res     vmlinux EXPORT_SYMBOL_GPL
++0xd4390384    __ieee80211_get_channel vmlinux EXPORT_SYMBOL
++0xe55e04a1    ip6_tnl_rcv_ctl vmlinux EXPORT_SYMBOL_GPL
++0xa389a49a    profile_event_register  vmlinux EXPORT_SYMBOL_GPL
++0x5ef37944    sdio_set_block_size     vmlinux EXPORT_SYMBOL_GPL
++0x9924c496    __usb_get_extra_descriptor      vmlinux EXPORT_SYMBOL_GPL
++0xcfa57ce1    __nf_conntrack_helper_find      vmlinux EXPORT_SYMBOL_GPL
++0x5460c8d8    fsnotify_get_cookie     vmlinux EXPORT_SYMBOL_GPL
++0xf5f58a7b    gether_register_netdev  vmlinux EXPORT_SYMBOL
++0xe774e9e4    register_netdevice      vmlinux EXPORT_SYMBOL
++0x9209f545    blkdev_put      vmlinux EXPORT_SYMBOL
++0x6a1c9c55    blkdev_get      vmlinux EXPORT_SYMBOL
++0x4d0cbb95    finish_no_open  vmlinux EXPORT_SYMBOL
++0xa1ef69b9    unregister_ftrace_event vmlinux EXPORT_SYMBOL_GPL
++0x09d6a08d    v4l2_device_disconnect  vmlinux EXPORT_SYMBOL_GPL
++0x613a7741    scsi_finish_command     vmlinux EXPORT_SYMBOL
++0x11f447ce    __gpio_to_irq   vmlinux EXPORT_SYMBOL_GPL
++0xb8a9ab06    hci_unregister_cb       vmlinux EXPORT_SYMBOL
++0xca0741ee    nf_nat_l4proto_register vmlinux EXPORT_SYMBOL_GPL
++0x70f09a3d    nf_nat_l3proto_register vmlinux EXPORT_SYMBOL_GPL
++0x10447797    build_skb       vmlinux EXPORT_SYMBOL
++0xf2b1ac8e    __getnstimeofday        vmlinux EXPORT_SYMBOL
++0x8923ab21    get_tz_trend    vmlinux EXPORT_SYMBOL
++0x450e1fb7    gs_alloc_req    vmlinux EXPORT_SYMBOL_GPL
++0x176df204    tcp_get_info    vmlinux EXPORT_SYMBOL_GPL
++0x4c2a5480    __alloc_skb     vmlinux EXPORT_SYMBOL
++0x90814050    snd_soc_cache_write     vmlinux EXPORT_SYMBOL_GPL
++0xa4ba4393    snd_soc_dai_set_fmt     vmlinux EXPORT_SYMBOL_GPL
++0x2d98d3e7    jbd2_journal_begin_ordered_truncate     vmlinux EXPORT_SYMBOL
++0x5b79185b    jbd2_trans_will_send_data_barrier       vmlinux EXPORT_SYMBOL
++0xc200914d    mutex_trylock   vmlinux EXPORT_SYMBOL
++0xe24d3a97    jiffies_64      vmlinux EXPORT_SYMBOL
++0x7eb7b3f8    of_get_dma_window       vmlinux EXPORT_SYMBOL_GPL
++0xc5c9bb41    regmap_get_val_bytes    vmlinux EXPORT_SYMBOL_GPL
++0x8226642f    __gpio_cansleep vmlinux EXPORT_SYMBOL_GPL
++0x6def2db2    half_md4_transform      vmlinux EXPORT_SYMBOL
++0xb835b3e4    radix_tree_prev_hole    vmlinux EXPORT_SYMBOL
++0xbed06655    dcache_readdir  vmlinux EXPORT_SYMBOL
++0x980c6433    inode_add_bytes vmlinux EXPORT_SYMBOL
++0xdc092d5b    thaw_super      vmlinux EXPORT_SYMBOL
++0x1ef192c5    generic_file_mmap       vmlinux EXPORT_SYMBOL
++0x9075cea3    abort_creds     vmlinux EXPORT_SYMBOL
++0x4ef8e23f    led_set_brightness      vmlinux EXPORT_SYMBOL
++0x48a5b067    __machine_arch_type     vmlinux EXPORT_SYMBOL
++0x4188d439    neigh_rand_reach_time   vmlinux EXPORT_SYMBOL
++0x7eef21b4    dev_forward_skb vmlinux EXPORT_SYMBOL_GPL
++0x5825f0e7    sock_common_getsockopt  vmlinux EXPORT_SYMBOL
++0x2de67218    sock_common_setsockopt  vmlinux EXPORT_SYMBOL
++0x65408378    zlib_inflate_blob       vmlinux EXPORT_SYMBOL
++0xc6d9568b    try_to_writeback_inodes_sb      vmlinux EXPORT_SYMBOL
++0x5ad87de6    vfs_mknod       vmlinux EXPORT_SYMBOL
++0x6f5c943e    rndis_add_hdr   vmlinux EXPORT_SYMBOL
++0x6a91e934    drm_mode_create_dvi_i_properties        vmlinux EXPORT_SYMBOL
++0x3eb37b9d    drm_ht_create   vmlinux EXPORT_SYMBOL
++0xcdf8626d    n_tty_inherit_ops       vmlinux EXPORT_SYMBOL_GPL
++0x65d6d0f0    gpio_direction_input    vmlinux EXPORT_SYMBOL_GPL
++0x74acd28a    nfc_hci_set_clientdata  vmlinux EXPORT_SYMBOL
++0x6c6a3e69    nfc_hci_get_clientdata  vmlinux EXPORT_SYMBOL
++0x8e235e9b    cfg80211_disconnected   vmlinux EXPORT_SYMBOL
++0x2d6b040a    cfg80211_send_rx_auth   vmlinux EXPORT_SYMBOL
++0x987f5e85    skb_dequeue     vmlinux EXPORT_SYMBOL
++0x413461c0    filemap_write_and_wait  vmlinux EXPORT_SYMBOL
++0x27bbf221    disable_irq_nosync      vmlinux EXPORT_SYMBOL
++0x00000000    softirq_work_list       vmlinux EXPORT_SYMBOL
++0x8c298b56    vb2_ioctl_querybuf      vmlinux EXPORT_SYMBOL_GPL
++0x94d7075a    usb_gadget_get_string   vmlinux EXPORT_SYMBOL_GPL
++0x19ef30a6    usbnet_manage_power     vmlinux EXPORT_SYMBOL
++0x967e7ec8    inet_rtx_syn_ack        vmlinux EXPORT_SYMBOL
++0x9b9e05f9    alloc_cpu_rmap  vmlinux EXPORT_SYMBOL
++0xa7f92105    add_uevent_var  vmlinux EXPORT_SYMBOL_GPL
++0x6e6c5939    dma_buf_kunmap_atomic   vmlinux EXPORT_SYMBOL_GPL
++0x3723eb08    __pm_relax      vmlinux EXPORT_SYMBOL_GPL
++0x1ae74b3a    drm_framebuffer_unregister_private      vmlinux EXPORT_SYMBOL
++0xf7584a9c    find_font       vmlinux EXPORT_SYMBOL
++0x88e316d7    netdev_features_change  vmlinux EXPORT_SYMBOL
++0xf19e9355    cpu_online_mask vmlinux EXPORT_SYMBOL
++0xaa8195e9    media_entity_remote_pad vmlinux EXPORT_SYMBOL_GPL
++0x19ec698c    platform_get_resource_byname    vmlinux EXPORT_SYMBOL_GPL
++0x62813e5c    nf_ct_port_nlattr_tuple_size    vmlinux EXPORT_SYMBOL_GPL
++0x4ff4a58a    nfnetlink_alloc_skb     vmlinux EXPORT_SYMBOL_GPL
++0xeed3635b    proc_dostring   vmlinux EXPORT_SYMBOL
++0xb54533f7    usecs_to_jiffies        vmlinux EXPORT_SYMBOL
++0x0b56117f    of_find_node_by_path    vmlinux EXPORT_SYMBOL
++0xcc4b84da    of_find_node_by_type    vmlinux EXPORT_SYMBOL
++0xf9fd4da3    phy_start       vmlinux EXPORT_SYMBOL
++0x5ea42ad5    devres_find     vmlinux EXPORT_SYMBOL_GPL
++0x598a2261    drm_mode_probed_add     vmlinux EXPORT_SYMBOL
++0xc35b2a18    xt_hook_link    vmlinux EXPORT_SYMBOL_GPL
++0xc1c24fbc    genlmsg_put     vmlinux EXPORT_SYMBOL
++0xf177aba7    sysfs_schedule_callback vmlinux EXPORT_SYMBOL_GPL
++0xabcaa577    free_anon_bdev  vmlinux EXPORT_SYMBOL
++0x6d289788    pwm_set_polarity        vmlinux EXPORT_SYMBOL_GPL
++0x2546de76    raw_hash_sk     vmlinux EXPORT_SYMBOL_GPL
++0xa2ef34d7    rps_sock_flow_table     vmlinux EXPORT_SYMBOL
++0x3730910b    skb_insert      vmlinux EXPORT_SYMBOL
++0xb8b7395a    snd_compress_new        vmlinux EXPORT_SYMBOL_GPL
++0x1c132024    request_any_context_irq vmlinux EXPORT_SYMBOL_GPL
++0x5aba52ab    iio_trigger_poll        vmlinux EXPORT_SYMBOL
++0xe9b6f3f3    dev_emerg       vmlinux EXPORT_SYMBOL
++0xfacd2e14    pgprot_user     vmlinux EXPORT_SYMBOL
++0x0a0786de    udplite_table   vmlinux EXPORT_SYMBOL
++0xd9bbcf52    tc_classify_compat      vmlinux EXPORT_SYMBOL
++0x72f15b74    blk_queue_max_segment_size      vmlinux EXPORT_SYMBOL
++0x544aab61    klist_add_tail  vmlinux EXPORT_SYMBOL_GPL
++0x490434ad    dev_kfree_skb_irq       vmlinux EXPORT_SYMBOL
++0xdb3a9b04    jbd2_journal_file_inode vmlinux EXPORT_SYMBOL
++0x6e9dd606    __symbol_put    vmlinux EXPORT_SYMBOL
++0x40a2d1dd    dm_table_get_size       vmlinux EXPORT_SYMBOL
++0xceee316a    gether_set_host_addr    vmlinux EXPORT_SYMBOL
++0x32f81723    gether_get_host_addr    vmlinux EXPORT_SYMBOL
++0xae387af1    usb_gadget_unmap_request        vmlinux EXPORT_SYMBOL_GPL
++0x8dfb019d    drm_buffer_free vmlinux EXPORT_SYMBOL
++0x600683d3    do_unblank_screen       vmlinux EXPORT_SYMBOL
++0xc1ebf6fe    get_kernel_page vmlinux EXPORT_SYMBOL_GPL
++0x9b388444    get_zeroed_page vmlinux EXPORT_SYMBOL
++0x53b69429    vb2_streamon    vmlinux EXPORT_SYMBOL_GPL
++0x211aedde    genphy_restart_aneg     vmlinux EXPORT_SYMBOL
++0xebdba37a    ndo_dflt_fdb_dump       vmlinux EXPORT_SYMBOL
++0x604ef7b4    snd_pcm_lib_read        vmlinux EXPORT_SYMBOL
++0x60541cbf    st_sensors_set_odr      vmlinux EXPORT_SYMBOL
++0xe53d1faa    of_translate_dma_address        vmlinux EXPORT_SYMBOL
++0xaf05b91b    of_device_is_available  vmlinux EXPORT_SYMBOL
++0x1a426d0c    input_close_device      vmlinux EXPORT_SYMBOL
++0xe720411b    rtnl_create_link        vmlinux EXPORT_SYMBOL
++0x650f8603    snd_pcm_format_silence_64       vmlinux EXPORT_SYMBOL
++0x7164c04b    address_space_init_once vmlinux EXPORT_SYMBOL
++0xfda0dbe8    ftrace_print_hex_seq    vmlinux EXPORT_SYMBOL
++0x2c988955    prepare_to_wait_exclusive       vmlinux EXPORT_SYMBOL
++0x9c3206d8    v4l2_device_unregister  vmlinux EXPORT_SYMBOL_GPL
++0xd5c2bed3    phy_connect_direct      vmlinux EXPORT_SYMBOL
++0xed2b0677    drm_mode_connector_update_edid_property vmlinux EXPORT_SYMBOL
++0xbf17b32e    tty_insert_flip_string_flags    vmlinux EXPORT_SYMBOL
++0xadc9ed27    bt_sock_ioctl   vmlinux EXPORT_SYMBOL
++0x33ea8640    inet_dev_addr_type      vmlinux EXPORT_SYMBOL
++0xd265ad57    tcf_action_exec vmlinux EXPORT_SYMBOL
++0xec8d9205    snd_soc_register_codec  vmlinux EXPORT_SYMBOL_GPL
++0x5e8ff943    debugfs_create_size_t   vmlinux EXPORT_SYMBOL_GPL
++0x5b968338    remove_proc_entry       vmlinux EXPORT_SYMBOL
++0x4717eaaf    platform_device_add     vmlinux EXPORT_SYMBOL_GPL
++0x44a0c113    drm_mode_height vmlinux EXPORT_SYMBOL
++0xe219d715    ipv6_opt_accepted       vmlinux EXPORT_SYMBOL_GPL
++0x503ed988    xfrm_spd_getinfo        vmlinux EXPORT_SYMBOL
++0x1fd1fabe    arpt_register_table     vmlinux EXPORT_SYMBOL
++0xf9ed2e31    block_is_partially_uptodate     vmlinux EXPORT_SYMBOL
++0xd9ecb670    ring_buffer_overruns    vmlinux EXPORT_SYMBOL_GPL
++0x5e911cf3    exynos_g2d_exec_ioctl   vmlinux EXPORT_SYMBOL_GPL
++0xbf69cda1    drm_connector_unplug_all        vmlinux EXPORT_SYMBOL
++0xafe3eb1b    alloc_etherdev_mqs      vmlinux EXPORT_SYMBOL
++0x39bf9301    _snd_pcm_hw_param_setempty      vmlinux EXPORT_SYMBOL
++0xd81836ce    uart_resume_port        vmlinux EXPORT_SYMBOL
++0x46931864    nfc_tm_data_received    vmlinux EXPORT_SYMBOL
++0xfac8865f    sysctl_wmem_max vmlinux EXPORT_SYMBOL
++0xb05fc310    sysctl_rmem_max vmlinux EXPORT_SYMBOL
++0xe9b673fa    dapm_mark_io_dirty      vmlinux EXPORT_SYMBOL_GPL
++0xbf0046d7    ahash_free_instance     vmlinux EXPORT_SYMBOL_GPL
++0x825a0923    jbd2_journal_errno      vmlinux EXPORT_SYMBOL
++0x03cb2c1a    bdi_register_dev        vmlinux EXPORT_SYMBOL
++0x018f7433    pm_relax        vmlinux EXPORT_SYMBOL_GPL
++0x63e0cc67    pagecache_write_end     vmlinux EXPORT_SYMBOL
++0x8a04b9fe    tracepoint_iter_reset   vmlinux EXPORT_SYMBOL_GPL
++0x5cf53ce2    input_free_minor        vmlinux EXPORT_SYMBOL
++0x17bfef6c    drm_clflush_pages       vmlinux EXPORT_SYMBOL
++0x5f14861d    pwm_get vmlinux EXPORT_SYMBOL_GPL
++0xb8a5d4ee    cfg80211_ft_event       vmlinux EXPORT_SYMBOL
++0xb9da2997    snmp_fold_field64       vmlinux EXPORT_SYMBOL_GPL
++0x87925ca6    kstrtoint_from_user     vmlinux EXPORT_SYMBOL
++0x6e891ea0    clk_unprepare   vmlinux EXPORT_SYMBOL_GPL
++0x3d41904f    of_get_next_child       vmlinux EXPORT_SYMBOL
++0x687835e7    hidinput_get_led_field  vmlinux EXPORT_SYMBOL_GPL
++0x36859243    hid_resolv_usage        vmlinux EXPORT_SYMBOL_GPL
++0x995dedd6    sdio_f0_readb   vmlinux EXPORT_SYMBOL_GPL
++0x19f5809b    dm_ratelimit_state      vmlinux EXPORT_SYMBOL
++0xe684f045    v4l2_subdev_try_ext_ctrls       vmlinux EXPORT_SYMBOL
++0x41f62b69    spi_register_master     vmlinux EXPORT_SYMBOL_GPL
++0x49428bcb    drm_read        vmlinux EXPORT_SYMBOL
++0xb12cbacb    fb_unregister_client    vmlinux EXPORT_SYMBOL
++0x7c53b814    xfrm_inner_extract_output       vmlinux EXPORT_SYMBOL_GPL
++0x86dd59c8    inet_csk_init_xmit_timers       vmlinux EXPORT_SYMBOL
++0x51e297e3    __nf_ct_l4proto_find    vmlinux EXPORT_SYMBOL_GPL
++0x1b52db1c    probe_kernel_read       vmlinux EXPORT_SYMBOL_GPL
++0xd4e65e28    irq_set_chip_and_handler_name   vmlinux EXPORT_SYMBOL_GPL
++0x9c7a3b79    drm_fb_helper_debug_enter       vmlinux EXPORT_SYMBOL
++0xc25d1133    vfs_readlink    vmlinux EXPORT_SYMBOL
++0x7e9efe8e    complete_and_exit       vmlinux EXPORT_SYMBOL
++0xd8d64478    v4l2_ctrl_new_std_menu_items    vmlinux EXPORT_SYMBOL
++0xb6652875    gserial_free_line       vmlinux EXPORT_SYMBOL_GPL
++0xd4adf602    dev_pm_get_subsys_data  vmlinux EXPORT_SYMBOL_GPL
++0x1f335345    dev_pm_put_subsys_data  vmlinux EXPORT_SYMBOL_GPL
++0x30399f8a    transport_add_device    vmlinux EXPORT_SYMBOL_GPL
++0x44c2d1be    drm_mode_prune_invalid  vmlinux EXPORT_SYMBOL
++0x3e9d6f44    cfg80211_unregister_wdev        vmlinux EXPORT_SYMBOL
++0xfb5bb3ee    inet6_lookup    vmlinux EXPORT_SYMBOL_GPL
++0x535cfa1f    sysfs_remove_group      vmlinux EXPORT_SYMBOL_GPL
++0x795b1ab0    sysfs_remove_file_from_group    vmlinux EXPORT_SYMBOL_GPL
++0x9aca444b    get_monotonic_boottime  vmlinux EXPORT_SYMBOL_GPL
++0x91aec064    down_read_trylock       vmlinux EXPORT_SYMBOL
++0x87e148ee    v4l2_m2m_poll   vmlinux EXPORT_SYMBOL_GPL
++0xfcb34391    scsi_execute_req_flags  vmlinux EXPORT_SYMBOL
++0x19391863    regmap_reinit_cache     vmlinux EXPORT_SYMBOL_GPL
++0xff6878cf    fb_default_cmap vmlinux EXPORT_SYMBOL
++0x38524c14    cpufreq_register_driver vmlinux EXPORT_SYMBOL_GPL
++0x4ca0e0e5    v4l2_ctrl_modify_range  vmlinux EXPORT_SYMBOL
++0x4f6f28fb    serial8250_handle_irq   vmlinux EXPORT_SYMBOL_GPL
++0x7b56a1b0    nf_nat_set_seq_adjust   vmlinux EXPORT_SYMBOL_GPL
++0x63df94bc    nf_nat_tcp_seq_adjust   vmlinux EXPORT_SYMBOL_GPL
++0x8ffb22a4    nf_setsockopt   vmlinux EXPORT_SYMBOL
++0xefd0fb67    nf_getsockopt   vmlinux EXPORT_SYMBOL
++0x579e0bf5    rtnl_unregister_all     vmlinux EXPORT_SYMBOL_GPL
++0x87e5d976    netif_rx_ni     vmlinux EXPORT_SYMBOL
++0xe27cea7b    alloc_disk      vmlinux EXPORT_SYMBOL
++0x1f867001    blk_rq_map_user_iov     vmlinux EXPORT_SYMBOL
++0xa3829135    ioc_lookup_icq  vmlinux EXPORT_SYMBOL
++0xd2ce469a    seq_puts        vmlinux EXPORT_SYMBOL
++0xf29942b3    seq_putc        vmlinux EXPORT_SYMBOL
++0xf268be24    dw_mci_remove   vmlinux EXPORT_SYMBOL
++0xb7ef4006    i2c_smbus_xfer  vmlinux EXPORT_SYMBOL
++0xb8a16d46    dev_pm_qos_remove_notifier      vmlinux EXPORT_SYMBOL_GPL
++0x37afc4f0    device_attach   vmlinux EXPORT_SYMBOL_GPL
++0x581e8240    tty_port_open   vmlinux EXPORT_SYMBOL
++0xa4583858    snd_pcm_hw_param_last   vmlinux EXPORT_SYMBOL
++0x43497fcc    part_round_stats        vmlinux EXPORT_SYMBOL_GPL
++0x0cd23659    d_genocide      vmlinux EXPORT_SYMBOL
++0x328995b5    tracing_generic_entry_update    vmlinux EXPORT_SYMBOL_GPL
++0xfe24d1c7    __module_put_and_exit   vmlinux EXPORT_SYMBOL
++0x43a53735    __alloc_workqueue_key   vmlinux EXPORT_SYMBOL_GPL
++0x2a902f32    usb_create_shared_hcd   vmlinux EXPORT_SYMBOL_GPL
++0xdbdbb6e7    uart_update_timeout     vmlinux EXPORT_SYMBOL
++0xf71617c1    cfg80211_report_obss_beacon     vmlinux EXPORT_SYMBOL
++0x3e5d6dc3    snd_soc_put_value_enum_double   vmlinux EXPORT_SYMBOL_GPL
++0xef67a6d3    snd_soc_get_value_enum_double   vmlinux EXPORT_SYMBOL_GPL
++0x81b69e41    snd_ctl_enum_info       vmlinux EXPORT_SYMBOL
++0xb2b94674    __crc32c_le     vmlinux EXPORT_SYMBOL
++0xc61cc06d    elv_dispatch_add_tail   vmlinux EXPORT_SYMBOL
++0x85e0bce2    end_buffer_write_sync   vmlinux EXPORT_SYMBOL
++0x3cc671ae    d_drop  vmlinux EXPORT_SYMBOL
++0x7469f641    d_rehash        vmlinux EXPORT_SYMBOL
++0xddcebac8    file_open_root  vmlinux EXPORT_SYMBOL
++0x310308c3    flush_kthread_work      vmlinux EXPORT_SYMBOL_GPL
++0x40f07981    __ashldi3       vmlinux EXPORT_SYMBOL
++0x88e83ca7    snd_soc_dpcm_be_set_state       vmlinux EXPORT_SYMBOL_GPL
++0x5eca39b9    snd_soc_dpcm_be_get_state       vmlinux EXPORT_SYMBOL_GPL
++0x6b1b67d3    __bdevname      vmlinux EXPORT_SYMBOL
++0xe4315493    vfs_write       vmlinux EXPORT_SYMBOL
++0x99fab0b8    __mmc_claim_host        vmlinux EXPORT_SYMBOL
++0x2c8e9ced    usb_poison_urb  vmlinux EXPORT_SYMBOL_GPL
++0x33a8a5f0    netif_rx        vmlinux EXPORT_SYMBOL
++0x1d54bb24    snd_pcm_hw_refine       vmlinux EXPORT_SYMBOL
++0x955b0e2e    kthread_worker_fn       vmlinux EXPORT_SYMBOL_GPL
++0x276ad369    dm_set_device_limits    vmlinux EXPORT_SYMBOL_GPL
++0x9e61f179    xfrm_stateonly_find     vmlinux EXPORT_SYMBOL
++0x972bcca5    usb_create_hcd  vmlinux EXPORT_SYMBOL_GPL
++0x72ea7b2d    scsi_device_type        vmlinux EXPORT_SYMBOL
++0x318cadb1    reciprocal_value        vmlinux EXPORT_SYMBOL
++0x22f77bec    unregister_binfmt       vmlinux EXPORT_SYMBOL
++0xafceeb25    alloc_vm_area   vmlinux EXPORT_SYMBOL_GPL
++0xcfe980c6    make_kgid       vmlinux EXPORT_SYMBOL
++0xb71fb74f    _raw_read_trylock       vmlinux EXPORT_SYMBOL
++0x9dadbb88    cpufreq_boost_supported vmlinux EXPORT_SYMBOL_GPL
++0xab9e471e    usb_autopm_get_interface_no_resume      vmlinux EXPORT_SYMBOL_GPL
++0x42453e50    sk_reset_txq    vmlinux EXPORT_SYMBOL
++0x05d48045    sock_no_accept  vmlinux EXPORT_SYMBOL
++0xb511dcf5    set_groups      vmlinux EXPORT_SYMBOL
++0x5f0abc76    pinctrl_dev_get_devname vmlinux EXPORT_SYMBOL_GPL
++0xec25f967    klist_del       vmlinux EXPORT_SYMBOL_GPL
++0x530ed62b    tcf_generic_walker      vmlinux EXPORT_SYMBOL
++0xacd392a0    sock_diag_register_inet_compat  vmlinux EXPORT_SYMBOL_GPL
++0x2509c465    dev_remove_offload      vmlinux EXPORT_SYMBOL
++0x8ee1a28d    elevator_exit   vmlinux EXPORT_SYMBOL
++0xcd357308    __lock_buffer   vmlinux EXPORT_SYMBOL
++0xd85139d2    mmc_unregister_driver   vmlinux EXPORT_SYMBOL
++0xb53559bb    brcmu_pktq_pflush       drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0xbb0ab47b    debug_locks     vmlinux EXPORT_SYMBOL_GPL
++0x56b2a97f    ablkcipher_walk_done    vmlinux EXPORT_SYMBOL_GPL
++0xd3630b88    ablkcipher_walk_phys    vmlinux EXPORT_SYMBOL_GPL
++0x3116987e    aead_geniv_alloc        vmlinux EXPORT_SYMBOL_GPL
++0x20a789ac    irq_set_chip_data       vmlinux EXPORT_SYMBOL
++0xeda65ce1    dma_release_declared_memory     vmlinux EXPORT_SYMBOL
++0xa984aab8    cfg80211_scan_done      vmlinux EXPORT_SYMBOL
++0x254c40cf    inet6_csk_xmit  vmlinux EXPORT_SYMBOL_GPL
++0xca805e0b    tcp_ioctl       vmlinux EXPORT_SYMBOL
++0x4ebc74b2    vfs_symlink     vmlinux EXPORT_SYMBOL
++0xefcf3143    wait_for_completion_io  vmlinux EXPORT_SYMBOL
++0xa9efcc8b    find_vpid       vmlinux EXPORT_SYMBOL_GPL
++0xd273b1b1    __round_jiffies_up_relative     vmlinux EXPORT_SYMBOL_GPL
++0xb8973764    iommu_attach_group      vmlinux EXPORT_SYMBOL_GPL
++0x5d550c4d    scsi_sd_probe_domain    vmlinux EXPORT_SYMBOL
++0x52f9bd8e    registered_fb   vmlinux EXPORT_SYMBOL
++0xe67d81ba    strlen_user     vmlinux EXPORT_SYMBOL
++0x480f1913    unmap_mapping_range     vmlinux EXPORT_SYMBOL
++0x8b618d08    overflowuid     vmlinux EXPORT_SYMBOL
++0x7171121c    overflowgid     vmlinux EXPORT_SYMBOL
++0xb3514b24    cfg80211_radar_event    vmlinux EXPORT_SYMBOL
++0xf06154af    inet_select_addr        vmlinux EXPORT_SYMBOL
++0x340854b4    dev_getbyhwaddr_rcu     vmlinux EXPORT_SYMBOL
++0x4ce033c8    skb_flow_dissect        vmlinux EXPORT_SYMBOL
++0x465757c3    cpu_present_mask        vmlinux EXPORT_SYMBOL
++0xb3a37086    dma_async_tx_descriptor_init    vmlinux EXPORT_SYMBOL
++0x955eec37    wireless_send_event     vmlinux EXPORT_SYMBOL
++0x7954e502    ipv6_recv_error vmlinux EXPORT_SYMBOL_GPL
++0xcebcfddd    snd_soc_get_enum_double vmlinux EXPORT_SYMBOL_GPL
++0x1c9728c6    snd_soc_put_enum_double vmlinux EXPORT_SYMBOL_GPL
++0xb4711532    get_task_io_context     vmlinux EXPORT_SYMBOL
++0x6cce08e5    dcache_dir_close        vmlinux EXPORT_SYMBOL
++0x3e884f4b    vm_get_page_prot        vmlinux EXPORT_SYMBOL
++0x20886a16    v4l2_subdev_g_ctrl      vmlinux EXPORT_SYMBOL
++0xd56dcf8e    v4l2_subdev_s_ctrl      vmlinux EXPORT_SYMBOL
++0x0465a073    regmap_reg_in_ranges    vmlinux EXPORT_SYMBOL_GPL
++0x74bc0dea    extcon_register_interest        vmlinux EXPORT_SYMBOL_GPL
++0x59c427c5    rtc_irq_set_state       vmlinux EXPORT_SYMBOL_GPL
++0x3302f88f    phy_driver_register     vmlinux EXPORT_SYMBOL
++0x848dd958    scsi_dma_unmap  vmlinux EXPORT_SYMBOL
++0xfbc74f64    __copy_from_user        vmlinux EXPORT_SYMBOL
++0xc9bb229b    inet_put_port   vmlinux EXPORT_SYMBOL
++0x73ac2c51    nf_conntrack_register_notifier  vmlinux EXPORT_SYMBOL_GPL
++0xbdca8444    sock_no_connect vmlinux EXPORT_SYMBOL
++0xe85a9fd3    cpu_cluster_pm_exit     vmlinux EXPORT_SYMBOL_GPL
++0xcb466063    wait_for_completion_killable_timeout    vmlinux EXPORT_SYMBOL
++0x9205953f    send_remote_softirq     vmlinux EXPORT_SYMBOL
++0x1852156d    phy_print_status        vmlinux EXPORT_SYMBOL
++0x486517f6    pinctrl_select_state    vmlinux EXPORT_SYMBOL_GPL
++0xfec26b4f    skcipher_geniv_alloc    vmlinux EXPORT_SYMBOL_GPL
++0x24094dc0    xfrm_garbage_collect    vmlinux EXPORT_SYMBOL
++0x6e224a7a    need_conntrack  vmlinux EXPORT_SYMBOL_GPL
++0x4a358252    __bitmap_subset vmlinux EXPORT_SYMBOL
++0x785d8ef0    ftrace_raw_output_prep  vmlinux EXPORT_SYMBOL
++0x697c5d0d    tracing_snapshot_alloc  vmlinux EXPORT_SYMBOL_GPL
++0x0e6da44a    set_normalized_timespec vmlinux EXPORT_SYMBOL
++0x789aafbd    iommu_map       vmlinux EXPORT_SYMBOL_GPL
++0x3a5f1e17    cfg80211_chandef_valid  vmlinux EXPORT_SYMBOL
++0xa11c9c1a    eth_type_trans  vmlinux EXPORT_SYMBOL
++0xe0f1fc5d    debugfs_create_blob     vmlinux EXPORT_SYMBOL_GPL
++0xd0f2dba2    mb_cache_entry_get      vmlinux EXPORT_SYMBOL
++0x233ed03d    vm_insert_mixed vmlinux EXPORT_SYMBOL
++0xa96bca8e    send_sig        vmlinux EXPORT_SYMBOL
++0x97cdf185    iio_buffer_read_length  vmlinux EXPORT_SYMBOL
++0x58d1070a    of_get_address  vmlinux EXPORT_SYMBOL
++0x620868cc    tcp_shutdown    vmlinux EXPORT_SYMBOL
++0x602c96f0    copy_to_user_fromio     vmlinux EXPORT_SYMBOL
++0x6d31e93b    tracepoint_iter_next    vmlinux EXPORT_SYMBOL_GPL
++0xe8b53ecc    down_write_trylock      vmlinux EXPORT_SYMBOL
++0x8bfe8c57    param_set_uint  vmlinux EXPORT_SYMBOL
++0x39422b14    usbnet_change_mtu       vmlinux EXPORT_SYMBOL_GPL
++0x4bd9c5ed    scsi_nonblockable_ioctl vmlinux EXPORT_SYMBOL
++0xcd319eaa    drm_vblank_count        vmlinux EXPORT_SYMBOL
++0x58413099    ipv6_fixup_options      vmlinux EXPORT_SYMBOL_GPL
++0xf389fe60    __hw_addr_init  vmlinux EXPORT_SYMBOL
++0x199ed0cd    net_disable_timestamp   vmlinux EXPORT_SYMBOL
++0x5ad8bb47    sdio_set_host_pm_flags  vmlinux EXPORT_SYMBOL_GPL
++0xdbbdaaf8    gether_get_qmult        vmlinux EXPORT_SYMBOL
++0x3d6846fc    gether_set_qmult        vmlinux EXPORT_SYMBOL
++0x14b14b7a    usb_get_function        vmlinux EXPORT_SYMBOL_GPL
++0x28fca1f1    pwmchip_add     vmlinux EXPORT_SYMBOL_GPL
++0xfbbedefd    of_prop_next_string     vmlinux EXPORT_SYMBOL_GPL
++0x4afe9a77    scsi_partsize   vmlinux EXPORT_SYMBOL
++0x14f875ce    devm_regmap_init_mmio_clk       vmlinux EXPORT_SYMBOL_GPL
++0x695aa696    __genl_register_family  vmlinux EXPORT_SYMBOL
++0x36bd681b    groups_alloc    vmlinux EXPORT_SYMBOL
++0x6a5b121d    of_find_device_by_node  vmlinux EXPORT_SYMBOL
++0x0dd989e3    vb2_streamoff   vmlinux EXPORT_SYMBOL_GPL
++0xa82de4f7    drm_pci_alloc   vmlinux EXPORT_SYMBOL
++0xdf54a8f7    netlink_unregister_notifier     vmlinux EXPORT_SYMBOL
++0xc4388843    dapm_regulator_event    vmlinux EXPORT_SYMBOL_GPL
++0x7a6fa714    __dynamic_dev_dbg       vmlinux EXPORT_SYMBOL
++0xfa4d00bd    simple_release_fs       vmlinux EXPORT_SYMBOL
++0xf473ffaf    down    vmlinux EXPORT_SYMBOL
++0xac6539ec    cm_notify_event vmlinux EXPORT_SYMBOL_GPL
++0xf49484e8    blk_end_request vmlinux EXPORT_SYMBOL
++0xb72a3fdb    drm_sysfs_connector_add vmlinux EXPORT_SYMBOL
++0x76cf47f6    __aeabi_llsl    vmlinux EXPORT_SYMBOL
++0x0573e568    inet_diag_dump_icsk     vmlinux EXPORT_SYMBOL_GPL
++0xc6a360e4    skb_put vmlinux EXPORT_SYMBOL
++0xf76b0a59    read_current_timer      vmlinux EXPORT_SYMBOL_GPL
++0xf1d6f94c    v4l2_m2m_ioctl_reqbufs  vmlinux EXPORT_SYMBOL_GPL
++0x5411bf06    scsi_host_put   vmlinux EXPORT_SYMBOL
++0xbca0b4fd    nfc_hci_sak_to_protocol vmlinux EXPORT_SYMBOL
++0x37386cac    nf_conntrack_hash_rnd   vmlinux EXPORT_SYMBOL_GPL
++0xdb065657    nfnl_unlock     vmlinux EXPORT_SYMBOL_GPL
++0xc5bd3b96    ethtool_op_get_ts_info  vmlinux EXPORT_SYMBOL
++0x5f8ed047    configfs_depend_item    vmlinux EXPORT_SYMBOL
++0x77fa6486    generic_block_fiemap    vmlinux EXPORT_SYMBOL
++0xc7bcbc8d    add_wait_queue  vmlinux EXPORT_SYMBOL
++0x046c1f16    param_ops_invbool       vmlinux EXPORT_SYMBOL
++0x4fe5c427    pinctrl_put     vmlinux EXPORT_SYMBOL_GPL
++0x547101cd    pinctrl_get     vmlinux EXPORT_SYMBOL_GPL
++0xdcc5846a    brcmu_pktq_flush        drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x4075ad18    dev_add_pack    vmlinux EXPORT_SYMBOL
++0x0a3131f6    strnchr vmlinux EXPORT_SYMBOL
++0xd20bf6ba    dcookie_unregister      vmlinux EXPORT_SYMBOL_GPL
++0x9e2be04d    vb2_poll        vmlinux EXPORT_SYMBOL_GPL
++0xa8f0aba7    usb_hub_clear_tt_buffer vmlinux EXPORT_SYMBOL_GPL
++0x2698ff67    drm_helper_connector_dpms       vmlinux EXPORT_SYMBOL
++0x48d34903    arm_dma_ops     vmlinux EXPORT_SYMBOL
++0x9f984513    strrchr vmlinux EXPORT_SYMBOL
++0x7afa89fc    vsnprintf       vmlinux EXPORT_SYMBOL
++0x7fe32873    rb_replace_node vmlinux EXPORT_SYMBOL
++0x6ff607b6    crypto_get_default_rng  vmlinux EXPORT_SYMBOL_GPL
++0x668402aa    crypto_put_default_rng  vmlinux EXPORT_SYMBOL_GPL
++0x850ff7d2    crypto_mod_put  vmlinux EXPORT_SYMBOL_GPL
++0x1db21259    mount_pseudo    vmlinux EXPORT_SYMBOL
++0x304ec72b    _raw_write_trylock      vmlinux EXPORT_SYMBOL
++0x4205ad24    cancel_work_sync        vmlinux EXPORT_SYMBOL_GPL
++0x99cdc86b    sysctl_tcp_reordering   vmlinux EXPORT_SYMBOL
++0x19d94b34    nf_ct_gre_keymap_flush  vmlinux EXPORT_SYMBOL
++0x356bcd72    nf_log_set      vmlinux EXPORT_SYMBOL
++0xd9e69bb2    dapm_reg_event  vmlinux EXPORT_SYMBOL_GPL
++0xb2959203    snd_pcm_hw_constraint_pow2      vmlinux EXPORT_SYMBOL
++0x9754ec10    radix_tree_preload      vmlinux EXPORT_SYMBOL
++0xc8cd27b8    blkdev_ioctl    vmlinux EXPORT_SYMBOL_GPL
++0xd11c0dc1    __kernel_param_unlock   vmlinux EXPORT_SYMBOL
++0xcda686ec    input_set_keycode       vmlinux EXPORT_SYMBOL
++0xc69c2d23    subsys_virtual_register vmlinux EXPORT_SYMBOL_GPL
++0x4eb8fe91    drm_gem_free_mmap_offset        vmlinux EXPORT_SYMBOL
++0x61cdf6e6    nfc_hci_allocate_device vmlinux EXPORT_SYMBOL
++0x2dda642f    __dynamic_netdev_dbg    vmlinux EXPORT_SYMBOL
++0x890dc2ed    idr_alloc_cyclic        vmlinux EXPORT_SYMBOL
++0x5cf6db68    crypto_register_instance        vmlinux EXPORT_SYMBOL_GPL
++0x93bd657f    crypto_alloc_tfm        vmlinux EXPORT_SYMBOL_GPL
++0x9c48a3ba    bdi_destroy     vmlinux EXPORT_SYMBOL
++0x29047f1a    __i2c_board_lock        vmlinux EXPORT_SYMBOL_GPL
++0x02e49d29    tty_ldisc_flush vmlinux EXPORT_SYMBOL_GPL
++0xb06d489b    skb_tstamp_tx   vmlinux EXPORT_SYMBOL_GPL
++0xe66452ab    dql_init        vmlinux EXPORT_SYMBOL
++0x69e27c7a    bitmap_copy_le  vmlinux EXPORT_SYMBOL
++0x4dec6038    memscan vmlinux EXPORT_SYMBOL
++0xa9148d85    mark_buffer_dirty       vmlinux EXPORT_SYMBOL
++0x304b568f    get_super       vmlinux EXPORT_SYMBOL
++0x00801678    flush_scheduled_work    vmlinux EXPORT_SYMBOL
++0xb6115ca3    tty_set_operations      vmlinux EXPORT_SYMBOL
++0x6d6cb9ad    ieee80211_operating_class_to_band       vmlinux EXPORT_SYMBOL
++0x32e1f29c    skb_copy_and_csum_bits  vmlinux EXPORT_SYMBOL
++0x776c599d    idma_reg_addr_init      vmlinux EXPORT_SYMBOL_GPL
++0xef9f2dc8    ll_rw_block     vmlinux EXPORT_SYMBOL
++0x13014091    block_write_begin       vmlinux EXPORT_SYMBOL
++0x93226faa    irq_domain_associate_many       vmlinux EXPORT_SYMBOL_GPL
++0x756a4248    st_sensors_read_info_raw        vmlinux EXPORT_SYMBOL
++0x04339915    iio_update_buffers      vmlinux EXPORT_SYMBOL_GPL
++0x55784228    regmap_irq_get_virq     vmlinux EXPORT_SYMBOL_GPL
++0xbc25aac9    ump_dd_phys_blocks_get  vmlinux EXPORT_SYMBOL
++0xe1761617    security_inet_conn_request      vmlinux EXPORT_SYMBOL
++0x1268f357    resume_device_irqs      vmlinux EXPORT_SYMBOL_GPL
++0xbe2e3b75    kstrtos8        vmlinux EXPORT_SYMBOL
++0x124f2056    crypto_get_attr_type    vmlinux EXPORT_SYMBOL_GPL
++0x2fc54b62    nfnetlink_send  vmlinux EXPORT_SYMBOL_GPL
++0x9479479b    wm_hubs_hpr_mux vmlinux EXPORT_SYMBOL_GPL
++0x49e22268    snd_soc_info_volsw_s8   vmlinux EXPORT_SYMBOL_GPL
++0x329aef1b    crypto_alloc_aead       vmlinux EXPORT_SYMBOL_GPL
++0x851d17d2    crypto_spawn_tfm2       vmlinux EXPORT_SYMBOL_GPL
++0xce6a9d9a    trace_current_buffer_discard_commit     vmlinux EXPORT_SYMBOL_GPL
++0x50fad434    round_jiffies_up        vmlinux EXPORT_SYMBOL_GPL
++0xf7f16b3f    input_get_new_minor     vmlinux EXPORT_SYMBOL
++0x26c90ea4    scsi_eh_get_sense       vmlinux EXPORT_SYMBOL_GPL
++0x75e49326    device_create_bin_file  vmlinux EXPORT_SYMBOL_GPL
++0x113c622e    dev_set_mac_address     vmlinux EXPORT_SYMBOL
++0xe13ad642    sk_receive_skb  vmlinux EXPORT_SYMBOL
++0xf5c05914    generic_segment_checks  vmlinux EXPORT_SYMBOL
++0xd0f36f0d    audit_log_format        vmlinux EXPORT_SYMBOL
++0xdbaf59ef    v4l2_m2m_mmap   vmlinux EXPORT_SYMBOL
++0xde520229    serio_open      vmlinux EXPORT_SYMBOL
++0xc5714a65    spi_master_suspend      vmlinux EXPORT_SYMBOL_GPL
++0x22b325d5    kd_mksound      vmlinux EXPORT_SYMBOL
++0x6d2fc5a6    net_namespace_list      vmlinux EXPORT_SYMBOL_GPL
++0x9f6381e8    sock_register   vmlinux EXPORT_SYMBOL
++0xf1806da9    idr_find_slowpath       vmlinux EXPORT_SYMBOL
++0x5ae5be44    lg_lock_init    vmlinux EXPORT_SYMBOL
++0x2d307e05    vb2_ioctl_qbuf  vmlinux EXPORT_SYMBOL_GPL
++0xaad6c827    serio_close     vmlinux EXPORT_SYMBOL
++0x8b092f05    loop_register_transfer  vmlinux EXPORT_SYMBOL
++0x3c967a5a    device_set_wakeup_enable        vmlinux EXPORT_SYMBOL_GPL
++0xc34b9b1f    regulator_get_bypass_regmap     vmlinux EXPORT_SYMBOL_GPL
++0xde9cc521    pinctrl_unregister      vmlinux EXPORT_SYMBOL_GPL
++0xd1c5bc52    __cfg80211_send_deauth  vmlinux EXPORT_SYMBOL
++0x126ad73c    inet6_register_protosw  vmlinux EXPORT_SYMBOL
++0x5ce3b588    nfnl_lock       vmlinux EXPORT_SYMBOL_GPL
++0xdc197993    netif_set_real_num_tx_queues    vmlinux EXPORT_SYMBOL
++0xd4d07dc9    netif_set_real_num_rx_queues    vmlinux EXPORT_SYMBOL
++0xbdc3f3e4    dev_set_group   vmlinux EXPORT_SYMBOL
++0xb4176982    proc_remove     vmlinux EXPORT_SYMBOL
++0x663e9182    end_buffer_async_write  vmlinux EXPORT_SYMBOL
++0x3d517179    phy_register_fixup_for_uid      vmlinux EXPORT_SYMBOL
++0xb4709322    scsi_dev_info_add_list  vmlinux EXPORT_SYMBOL
++0x9dd34b62    drm_mm_insert_node_in_range     vmlinux EXPORT_SYMBOL
++0x69b18f43    rfc1042_header  vmlinux EXPORT_SYMBOL
++0x50097088    security_tun_dev_free_security  vmlinux EXPORT_SYMBOL
++0x050c08c1    vfs_writev      vmlinux EXPORT_SYMBOL
++0xd6b5a293    iio_buffer_init vmlinux EXPORT_SYMBOL
++0x811e0359    sdio_get_host_pm_caps   vmlinux EXPORT_SYMBOL_GPL
++0x9062c322    ring_buffer_consume     vmlinux EXPORT_SYMBOL_GPL
++0x1c5b1f28    irq_free_descs  vmlinux EXPORT_SYMBOL_GPL
++0xf2791baa    cgroup_unload_subsys    vmlinux EXPORT_SYMBOL_GPL
++0xe43274bc    proc_dointvec   vmlinux EXPORT_SYMBOL
++0xe8948e95    mmc_stop_bkops  vmlinux EXPORT_SYMBOL
++0xa2a5fd77    inet_ehash_secret       vmlinux EXPORT_SYMBOL
++0x2363e5bf    __inet_lookup_established       vmlinux EXPORT_SYMBOL_GPL
++0x3eeb1d5e    netdev_alert    vmlinux EXPORT_SYMBOL
++0x26ad413b    netdev_has_any_upper_dev        vmlinux EXPORT_SYMBOL
++0x7604b234    udp_lib_rehash  vmlinux EXPORT_SYMBOL
++0x5e5d53d3    udp_lib_unhash  vmlinux EXPORT_SYMBOL
++0x2b12925d    cpumask_next_and        vmlinux EXPORT_SYMBOL
++0x05495392    hid_debug       vmlinux EXPORT_SYMBOL_GPL
++0x1d1ca867    pm_stay_awake   vmlinux EXPORT_SYMBOL_GPL
++0x8c1a19df    device_show_ulong       vmlinux EXPORT_SYMBOL_GPL
++0x46940ff4    set_ras_addr_hook       vmlinux EXPORT_SYMBOL_GPL
++0x6088da85    nf_hook_slow    vmlinux EXPORT_SYMBOL
++0xce5ac24f    zlib_inflate_workspacesize      vmlinux EXPORT_SYMBOL
++0x2e73d9a1    v4l2_chip_ident_i2c_client      vmlinux EXPORT_SYMBOL
++0x3783cdae    drm_open        vmlinux EXPORT_SYMBOL
++0x5404b1e7    tcp_recvmsg     vmlinux EXPORT_SYMBOL
++0x47b90df9    snd_pcm_limit_hw_rates  vmlinux EXPORT_SYMBOL
++0x63baba6b    irq_alloc_generic_chip  vmlinux EXPORT_SYMBOL_GPL
++0xace5c0fc    usb_bus_list    vmlinux EXPORT_SYMBOL_GPL
++0xe8b63ace    radix_tree_range_tag_if_tagged  vmlinux EXPORT_SYMBOL
++0x8d8b6353    proc_dointvec_userhz_jiffies    vmlinux EXPORT_SYMBOL
++0x7ec5c02b    console_start   vmlinux EXPORT_SYMBOL
++0x1a1aebf8    s3c_adc_start   vmlinux EXPORT_SYMBOL_GPL
++0xffc6c87a    drm_detect_monitor_audio        vmlinux EXPORT_SYMBOL
++0xe1371ad4    tcp_simple_retransmit   vmlinux EXPORT_SYMBOL
++0x0f18b144    inet_csk_bind_conflict  vmlinux EXPORT_SYMBOL_GPL
++0x708e56bd    xt_register_match       vmlinux EXPORT_SYMBOL
++0xf3526269    proc_set_user   vmlinux EXPORT_SYMBOL
++0x752dff9d    anon_inode_getfile      vmlinux EXPORT_SYMBOL_GPL
++0xcd10fb11    simple_dir_inode_operations     vmlinux EXPORT_SYMBOL
++0x708bd95d    irq_domain_xlate_onetwocell     vmlinux EXPORT_SYMBOL_GPL
++0x122043a8    of_find_node_with_property      vmlinux EXPORT_SYMBOL
++0xb3453966    vb2_fop_release vmlinux EXPORT_SYMBOL_GPL
++0x59dddb40    ump_dd_reference_add    vmlinux EXPORT_SYMBOL
++0xe8bcc079    snd_soc_codec_set_cache_io      vmlinux EXPORT_SYMBOL_GPL
++0x67ae5cfb    dmam_pool_create        vmlinux EXPORT_SYMBOL
++0x1e7f65cb    vb2_mmap        vmlinux EXPORT_SYMBOL_GPL
++0xb33ff162    __find_get_block        vmlinux EXPORT_SYMBOL
++0x23a997f4    dcache_dir_open vmlinux EXPORT_SYMBOL
++0x3f4547a7    put_unused_fd   vmlinux EXPORT_SYMBOL
++0xd2555f19    jiffies_64_to_clock_t   vmlinux EXPORT_SYMBOL
++0xef969c64    input_mt_get_slot_by_key        vmlinux EXPORT_SYMBOL
++0x2b547fec    genphy_suspend  vmlinux EXPORT_SYMBOL
++0x0a04ac5b    subsys_system_register  vmlinux EXPORT_SYMBOL_GPL
++0x919a5e62    inet6_lookup_listener   vmlinux EXPORT_SYMBOL_GPL
++0xece784c2    rb_first        vmlinux EXPORT_SYMBOL
++0xc72e1233    __trace_bprintk vmlinux EXPORT_SYMBOL_GPL
++0x6a5ecb18    unregister_module_notifier      vmlinux EXPORT_SYMBOL
++0x19f115c3    flush_delayed_work      vmlinux EXPORT_SYMBOL
++0xf82f5060    usbnet_read_cmd vmlinux EXPORT_SYMBOL_GPL
++0xf3e09d59    dev_pm_qos_expose_latency_limit vmlinux EXPORT_SYMBOL_GPL
++0xfc4cb906    exynos_drm_subdrv_unregister    vmlinux EXPORT_SYMBOL_GPL
++0x04911106    of_dma_simple_xlate     vmlinux EXPORT_SYMBOL_GPL
++0x7211e749    nf_conntrack_hash_check_insert  vmlinux EXPORT_SYMBOL_GPL
++0x68b80336    zero_fill_bio   vmlinux EXPORT_SYMBOL
++0xe83fad56    mmc_switch      vmlinux EXPORT_SYMBOL_GPL
++0xa5a8337c    scsi_cmd_print_sense_hdr        vmlinux EXPORT_SYMBOL
++0x8b08c5c1    unix_peer_get   vmlinux EXPORT_SYMBOL_GPL
++0xef3b173b    audit_log_task_info     vmlinux EXPORT_SYMBOL
++0xacc26098    iio_read_const_attr     vmlinux EXPORT_SYMBOL
++0x47d7d62e    mmc_resume_host vmlinux EXPORT_SYMBOL
++0x323758b8    v4l2_spi_subdev_init    vmlinux EXPORT_SYMBOL_GPL
++0xbaa5b6b2    bus_register    vmlinux EXPORT_SYMBOL_GPL
++0xf39ab86b    tcp_syn_ack_timeout     vmlinux EXPORT_SYMBOL
++0xe73dda41    __nf_ct_ext_add_length  vmlinux EXPORT_SYMBOL
++0xc4ff89ae    nf_log_unregister       vmlinux EXPORT_SYMBOL
++0xd8e38717    d_hash_and_lookup       vmlinux EXPORT_SYMBOL
++0x63193a50    generic_file_buffered_write     vmlinux EXPORT_SYMBOL
++0xcce7df45    iio_alloc_pollfunc      vmlinux EXPORT_SYMBOL_GPL
++0x24b0f90c    of_clk_get_by_name      vmlinux EXPORT_SYMBOL
++0x3fb35146    mmc_alloc_host  vmlinux EXPORT_SYMBOL
++0xe6099979    scsi_eh_ready_devs      vmlinux EXPORT_SYMBOL_GPL
++0x986e6135    fb_pad_unaligned_buffer vmlinux EXPORT_SYMBOL
++0xc1c2dd09    __hw_addr_flush vmlinux EXPORT_SYMBOL
++0xae249a24    snd_register_device_for_dev     vmlinux EXPORT_SYMBOL
++0xea054b22    nla_policy_len  vmlinux EXPORT_SYMBOL
++0xd92afabe    bitmap_clear    vmlinux EXPORT_SYMBOL
++0x80f48353    fsync_bdev      vmlinux EXPORT_SYMBOL
++0x71930ed3    of_property_read_string vmlinux EXPORT_SYMBOL_GPL
++0x570f339b    thermal_cooling_device_register vmlinux EXPORT_SYMBOL_GPL
++0xcfcdd86a    input_open_device       vmlinux EXPORT_SYMBOL
++0x84ac53cc    drm_fb_helper_single_add_all_connectors vmlinux EXPORT_SYMBOL
++0x0e3edf75    regulator_set_bypass_regmap     vmlinux EXPORT_SYMBOL_GPL
++0xfe990052    gpio_free       vmlinux EXPORT_SYMBOL_GPL
++0x0b63a348    cfg80211_wext_giwrange  vmlinux EXPORT_SYMBOL_GPL
++0x6d815a8f    ip6_dst_lookup  vmlinux EXPORT_SYMBOL_GPL
++0x40a9b349    vzalloc vmlinux EXPORT_SYMBOL
++0xc2f9c045    timespec_to_jiffies     vmlinux EXPORT_SYMBOL
++0x54159824    iio_push_event  vmlinux EXPORT_SYMBOL
++0x94f95b4e    i2c_new_device  vmlinux EXPORT_SYMBOL_GPL
++0xe04e6d60    device_for_each_child   vmlinux EXPORT_SYMBOL_GPL
++0x5eafb8e9    drm_mode_set_name       vmlinux EXPORT_SYMBOL
++0x3b0a974f    arm_iommu_release_mapping       vmlinux EXPORT_SYMBOL_GPL
++0xed76ba4a    hci_resume_dev  vmlinux EXPORT_SYMBOL
++0x9cfaab5e    media_device_unregister vmlinux EXPORT_SYMBOL_GPL
++0x5783d440    pm_generic_poweroff_late        vmlinux EXPORT_SYMBOL_GPL
++0x59c8991b    nci_allocate_device     vmlinux EXPORT_SYMBOL
++0x11089ac7    _ctype  vmlinux EXPORT_SYMBOL
++0x66d480cb    blk_get_queue   vmlinux EXPORT_SYMBOL
++0x60b78a66    bd_set_size     vmlinux EXPORT_SYMBOL
++0x71f34013    __mem_cgroup_count_vm_event     vmlinux EXPORT_SYMBOL
++0x2d45b494    pm_vt_switch_unregister vmlinux EXPORT_SYMBOL
++0xca7d8764    kthread_freezable_should_stop   vmlinux EXPORT_SYMBOL_GPL
++0x03b3002e    st_sensors_enable_events        vmlinux EXPORT_SYMBOL
++0xfc937fcb    usb_add_gadget_udc      vmlinux EXPORT_SYMBOL_GPL
++0x420323e6    i2c_dp_aux_add_bus      vmlinux EXPORT_SYMBOL
++0xd6ef94db    udp_proc_unregister     vmlinux EXPORT_SYMBOL
++0x37f614b7    __kfifo_len_r   vmlinux EXPORT_SYMBOL
++0xac6e0f5a    power_supply_get_by_name        vmlinux EXPORT_SYMBOL_GPL
++0x86047552    inet_sk_rebuild_header  vmlinux EXPORT_SYMBOL
++0x3c878c55    skb_copy        vmlinux EXPORT_SYMBOL
++0xe5b6e62e    snd_pcm_stop    vmlinux EXPORT_SYMBOL
++0x7593d385    div64_s64       vmlinux EXPORT_SYMBOL
++0x27864d57    memparse        vmlinux EXPORT_SYMBOL
++0xe8f9c617    block_truncate_page     vmlinux EXPORT_SYMBOL
++0xbc036e9e    generic_write_checks    vmlinux EXPORT_SYMBOL
++0x4f68e5c9    do_gettimeofday vmlinux EXPORT_SYMBOL
++0xa6715115    do_settimeofday vmlinux EXPORT_SYMBOL
++0xd9efbe4c    input_inject_event      vmlinux EXPORT_SYMBOL
++0x3dc565d9    drm_mm_insert_node_generic      vmlinux EXPORT_SYMBOL
++0x0c58a8cd    netdev_increment_features       vmlinux EXPORT_SYMBOL
++0xb3c487b6    uart_match_port vmlinux EXPORT_SYMBOL
++0x208f2017    brcmu_pktq_pdeq_match   drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0xbc455bde    cfg80211_pmksa_candidate_notify vmlinux EXPORT_SYMBOL
++0x3bef03b9    flow_cache_lookup       vmlinux EXPORT_SYMBOL
++0x5002ec2f    __splice_from_pipe      vmlinux EXPORT_SYMBOL
++0x863c552c    cache_firmware  vmlinux EXPORT_SYMBOL_GPL
++0xe5274b72    unregister_net_sysctl_table     vmlinux EXPORT_SYMBOL_GPL
++0xa197b1ff    ieee80211_get_mesh_hdrlen       vmlinux EXPORT_SYMBOL
++0x3a9592df    __nf_ct_ext_destroy     vmlinux EXPORT_SYMBOL
++0xa2c640f9    sysfs_add_file_to_group vmlinux EXPORT_SYMBOL_GPL
++0x487d9343    param_ops_ushort        vmlinux EXPORT_SYMBOL
++0x58804ca9    sdio_align_size vmlinux EXPORT_SYMBOL_GPL
++0xa09e1f4c    cpufreq_register_governor       vmlinux EXPORT_SYMBOL_GPL
++0x8ee7279a    ump_dd_size_get vmlinux EXPORT_SYMBOL
++0xfb858f46    tty_write_room  vmlinux EXPORT_SYMBOL
++0x3d715445    dev_trans_start vmlinux EXPORT_SYMBOL
++0xa381944f    dql_reset       vmlinux EXPORT_SYMBOL
++0x8f99ae4c    blk_register_region     vmlinux EXPORT_SYMBOL
++0xa8242495    bio_put vmlinux EXPORT_SYMBOL
++0x488d1fd7    task_tgid_nr_ns vmlinux EXPORT_SYMBOL
++0xc8d55b31    usb_unlocked_disable_lpm        vmlinux EXPORT_SYMBOL_GPL
++0x10ee20bb    default_blu     vmlinux EXPORT_SYMBOL
++0x57575f08    dmaengine_put   vmlinux EXPORT_SYMBOL
++0x60577ee3    ip6_expire_frag_queue   vmlinux EXPORT_SYMBOL
++0xdb5d34e0    rcu_batches_completed_preempt   vmlinux EXPORT_SYMBOL_GPL
++0xec6f4d80    each_symbol_section     vmlinux EXPORT_SYMBOL_GPL
++0xea6e3003    of_find_compatible_node vmlinux EXPORT_SYMBOL
++0x0d95dc3b    video_ioctl2    vmlinux EXPORT_SYMBOL
++0x26156aad    input_alloc_absinfo     vmlinux EXPORT_SYMBOL
++0x244b53b3    scsi_is_target_device   vmlinux EXPORT_SYMBOL
++0xd0cf28c6    sk_dst_check    vmlinux EXPORT_SYMBOL
++0xa5dd45f3    prandom_bytes_state     vmlinux EXPORT_SYMBOL
++0x6a76f3ac    blk_iopoll_enable       vmlinux EXPORT_SYMBOL
++0x17e1907b    inode_needs_sync        vmlinux EXPORT_SYMBOL
++0x9c6ac1ed    grab_cache_page_nowait  vmlinux EXPORT_SYMBOL
++0xe7a81967    audit_log_secctx        vmlinux EXPORT_SYMBOL
++0x2babe81f    __wake_up_sync_key      vmlinux EXPORT_SYMBOL_GPL
++0x4adaf0f3    v4l2_ctrl_query_menu_valid_items        vmlinux EXPORT_SYMBOL
++0xcb6f482d    dev_getfirstbyhwtype    vmlinux EXPORT_SYMBOL
++0xb23df37e    wake_up_process vmlinux EXPORT_SYMBOL
++0x25820c64    fs_overflowuid  vmlinux EXPORT_SYMBOL
++0x24ddf922    scsi_internal_device_block      vmlinux EXPORT_SYMBOL_GPL
++0x1079ac8f    drm_framebuffer_remove  vmlinux EXPORT_SYMBOL
++0x160f2f7e    of_phy_simple_xlate     vmlinux EXPORT_SYMBOL_GPL
++0xe669c8a2    __nf_ct_refresh_acct    vmlinux EXPORT_SYMBOL_GPL
++0xa2f20d05    skb_dequeue_tail        vmlinux EXPORT_SYMBOL
++0x19a025aa    __get_user_pages        vmlinux EXPORT_SYMBOL
++0x286acd69    free_css_id     vmlinux EXPORT_SYMBOL_GPL
++0x404c4f08    __module_address        vmlinux EXPORT_SYMBOL_GPL
++0x195d329a    hidinput_count_leds     vmlinux EXPORT_SYMBOL_GPL
++0x280c859a    input_ff_erase  vmlinux EXPORT_SYMBOL_GPL
++0x886d02da    scsi_target_resume      vmlinux EXPORT_SYMBOL
++0x8f31e347    inet_stream_ops vmlinux EXPORT_SYMBOL
++0x9b0dcfa2    qdisc_reset     vmlinux EXPORT_SYMBOL
++0xd2da1048    register_netdevice_notifier     vmlinux EXPORT_SYMBOL
++0x1b5fff19    blk_complete_request    vmlinux EXPORT_SYMBOL
++0x808ec1a3    crypto_alg_tested       vmlinux EXPORT_SYMBOL_GPL
++0xda920cd9    bio_unmap_user  vmlinux EXPORT_SYMBOL
++0xe769232e    sprint_symbol_no_offset vmlinux EXPORT_SYMBOL_GPL
++0x2b7a6de8    syscon_regmap_lookup_by_phandle vmlinux EXPORT_SYMBOL_GPL
++0x9728e93f    of_dma_controller_register      vmlinux EXPORT_SYMBOL_GPL
++0x1b61c5b3    pwm_config      vmlinux EXPORT_SYMBOL_GPL
++0x39bdf0f0    nci_free_device vmlinux EXPORT_SYMBOL
++0xe3a306b5    udp_seq_open    vmlinux EXPORT_SYMBOL
++0x38c97d50    idr_get_next    vmlinux EXPORT_SYMBOL
++0xeaacc92f    fail_migrate_page       vmlinux EXPORT_SYMBOL
++0x4cdb3178    ns_to_timeval   vmlinux EXPORT_SYMBOL
++0xc78d0953    ehci_init_driver        vmlinux EXPORT_SYMBOL_GPL
++0xcd6ff125    nf_ct_expect_register_notifier  vmlinux EXPORT_SYMBOL_GPL
++0x721b1851    skip_spaces     vmlinux EXPORT_SYMBOL
++0x0c0c015e    ring_buffer_swap_cpu    vmlinux EXPORT_SYMBOL_GPL
++0x76d451c4    add_taint       vmlinux EXPORT_SYMBOL
++0x1c2596ba    regmap_async_complete_cb        vmlinux EXPORT_SYMBOL_GPL
++0x60a32ea9    pm_power_off    vmlinux EXPORT_SYMBOL
++0x2b911208    __neigh_for_each_release        vmlinux EXPORT_SYMBOL
++0x0bc7e6ff    blk_queue_init_tags     vmlinux EXPORT_SYMBOL
++0xa666946b    bdget   vmlinux EXPORT_SYMBOL
++0x885a4cc9    bdput   vmlinux EXPORT_SYMBOL
++0x2517dbbb    fsstack_copy_inode_size vmlinux EXPORT_SYMBOL_GPL
++0x7d4ed855    iio_trigger_poll_chained        vmlinux EXPORT_SYMBOL
++0x561e4b77    irq_of_parse_and_map    vmlinux EXPORT_SYMBOL_GPL
++0x308efc55    spi_busnum_to_master    vmlinux EXPORT_SYMBOL_GPL
++0xe862c4b7    dpm_suspend_start       vmlinux EXPORT_SYMBOL_GPL
++0xd728282d    device_initialize       vmlinux EXPORT_SYMBOL_GPL
++0xf6b77868    nf_conntrack_untracked  vmlinux EXPORT_SYMBOL
++0xed9f8e6d    kstrtos16       vmlinux EXPORT_SYMBOL
++0xfb32b30f    ring_buffer_read_prepare_sync   vmlinux EXPORT_SYMBOL_GPL
++0x846bcc01    dm_table_get    vmlinux EXPORT_SYMBOL
++0x1416333b    tcf_em_register vmlinux EXPORT_SYMBOL
++0x19546cac    snd_soc_cache_read      vmlinux EXPORT_SYMBOL_GPL
++0xfd2f4f20    snd_soc_info_volsw_ext  vmlinux EXPORT_SYMBOL_GPL
++0x6c749afe    __tracepoint_block_unplug       vmlinux EXPORT_SYMBOL_GPL
++0x9c86ede0    fs_kobj vmlinux EXPORT_SYMBOL_GPL
++0x796c2d48    dm_get_md       vmlinux EXPORT_SYMBOL_GPL
++0xf8fbb4f0    __bad_xchg      vmlinux EXPORT_SYMBOL
++0xc40f284c    nf_ct_helper_hsize      vmlinux EXPORT_SYMBOL_GPL
++0x24428be5    strncpy_from_user       vmlinux EXPORT_SYMBOL
++0x6d74d462    crypto_alloc_ablkcipher vmlinux EXPORT_SYMBOL_GPL
++0x0b96efa8    bio_init        vmlinux EXPORT_SYMBOL
++0x7278d328    all_vm_events   vmlinux EXPORT_SYMBOL_GPL
++0x41814cb8    dirty_writeback_interval        vmlinux EXPORT_SYMBOL_GPL
++0x1c32da2a    iio_enum_available_read vmlinux EXPORT_SYMBOL_GPL
++0xcda91c46    drm_mode_debug_printmodeline    vmlinux EXPORT_SYMBOL
++0xa9cae71a    inet6_hash_connect      vmlinux EXPORT_SYMBOL_GPL
++0x92f5d840    gnet_stats_copy_rate_est        vmlinux EXPORT_SYMBOL
++0x17f61c70    skb_partial_csum_set    vmlinux EXPORT_SYMBOL_GPL
++0xb86cf818    create_empty_buffers    vmlinux EXPORT_SYMBOL
++0x26332c2f    init_special_inode      vmlinux EXPORT_SYMBOL
++0xd0720a17    on_each_cpu_cond        vmlinux EXPORT_SYMBOL
++0x870713f0    iommu_detach_group      vmlinux EXPORT_SYMBOL_GPL
++0x00c8b1c1    sdio_enable_func        vmlinux EXPORT_SYMBOL_GPL
++0x22f907ec    pm_runtime_no_callbacks vmlinux EXPORT_SYMBOL_GPL
++0x8d4234e8    subsys_dev_iter_next    vmlinux EXPORT_SYMBOL_GPL
++0x706fc943    mali_pmu_powerup        vmlinux EXPORT_SYMBOL
++0xf24fbd54    cfg80211_mgmt_tx_status vmlinux EXPORT_SYMBOL
++0xa8bae0ab    inet_frag_destroy       vmlinux EXPORT_SYMBOL
++0xca1aff2d    ipv4_sk_update_pmtu     vmlinux EXPORT_SYMBOL_GPL
++0x539973c5    skb_make_writable       vmlinux EXPORT_SYMBOL
++0x2eeceb42    sk_chk_filter   vmlinux EXPORT_SYMBOL
++0x8f595b11    snd_major       vmlinux EXPORT_SYMBOL
++0xf8433bfd    pipe_to_file    vmlinux EXPORT_SYMBOL
++0x0dc1d65b    __dec_zone_page_state   vmlinux EXPORT_SYMBOL
++0x95ce193b    __inc_zone_page_state   vmlinux EXPORT_SYMBOL
++0x736c2d7c    __mod_zone_page_state   vmlinux EXPORT_SYMBOL
++0xab6babaf    pm_qos_request  vmlinux EXPORT_SYMBOL_GPL
++0xeed6cc4b    flush_kthread_worker    vmlinux EXPORT_SYMBOL_GPL
++0xa5cef8ad    release_resource        vmlinux EXPORT_SYMBOL
++0x4584b8a3    iio_push_to_buffers     vmlinux EXPORT_SYMBOL_GPL
++0xc79bcd36    dm_vcalloc      vmlinux EXPORT_SYMBOL
++0xa7dd8c46    ump_dd_phys_block_get   vmlinux EXPORT_SYMBOL
++0x83bd3297    brioctl_set     vmlinux EXPORT_SYMBOL
++0x09e913c1    snd_pcm_alt_chmaps      vmlinux EXPORT_SYMBOL_GPL
++0xbf33e600    vm_insert_pfn   vmlinux EXPORT_SYMBOL
++0xda050109    irq_domain_add_nomap    vmlinux EXPORT_SYMBOL_GPL
++0xfcaa04a0    out_of_line_wait_on_bit_lock    vmlinux EXPORT_SYMBOL
++0xa7bb71ae    input_set_abs_params    vmlinux EXPORT_SYMBOL
++0x22f9a7f4    spi_bus_unlock  vmlinux EXPORT_SYMBOL_GPL
++0x2ea5ad9c    device_schedule_callback_owner  vmlinux EXPORT_SYMBOL_GPL
++0x4c511235    drm_edid_is_valid       vmlinux EXPORT_SYMBOL
++0x3939f8f0    rfkill_pause_polling    vmlinux EXPORT_SYMBOL
++0xebc7bcd9    xfrm_state_alloc        vmlinux EXPORT_SYMBOL
++0x85670f1d    rtnl_is_locked  vmlinux EXPORT_SYMBOL
++0x726d45d3    fat_remove_entries      vmlinux EXPORT_SYMBOL_GPL
++0xd963ea55    page_symlink    vmlinux EXPORT_SYMBOL
++0xa26d9b4f    workqueue_congested     vmlinux EXPORT_SYMBOL_GPL
++0xf7cd6b11    freq_reg_info   vmlinux EXPORT_SYMBOL
++0x764dafa5    __xfrm_route_forward    vmlinux EXPORT_SYMBOL
++0xd317cce2    snd_soc_put_volsw_sx    vmlinux EXPORT_SYMBOL_GPL
++0x587ba0c8    snd_soc_get_volsw_s8    vmlinux EXPORT_SYMBOL_GPL
++0x5dda7051    snd_soc_put_volsw_s8    vmlinux EXPORT_SYMBOL_GPL
++0xd6b61c7b    snd_soc_get_volsw_sx    vmlinux EXPORT_SYMBOL_GPL
++0x9f0664bf    dm_get_queue_limits     vmlinux EXPORT_SYMBOL_GPL
++0x0364983f    gen_replace_estimator   vmlinux EXPORT_SYMBOL
++0x2f03fc4b    security_secmark_refcount_inc   vmlinux EXPORT_SYMBOL
++0x19bd383b    security_secmark_refcount_dec   vmlinux EXPORT_SYMBOL
++0xc22b50ad    param_set_bint  vmlinux EXPORT_SYMBOL
++0x21315700    param_get_bool  vmlinux EXPORT_SYMBOL
++0x3eae292f    param_set_byte  vmlinux EXPORT_SYMBOL
++0xcea1a019    dw_mci_suspend  vmlinux EXPORT_SYMBOL
++0x8657c2d4    spi_bitbang_setup       vmlinux EXPORT_SYMBOL_GPL
++0xb13fbb9a    scsi_target_unblock     vmlinux EXPORT_SYMBOL_GPL
++0xbf3a015f    brcmf_sdio_remove       drivers/net/wireless/brcm80211/brcmfmac/brcmfmac        EXPORT_SYMBOL
++0xeb1c3628    nf_ipv6_ops     vmlinux EXPORT_SYMBOL_GPL
++0x9fdecc31    unregister_netdevice_many       vmlinux EXPORT_SYMBOL
++0x75308bb0    blk_queue_logical_block_size    vmlinux EXPORT_SYMBOL
++0x2fe50bdf    init_srcu_struct        vmlinux EXPORT_SYMBOL_GPL
++0xfba64859    rtc_device_unregister   vmlinux EXPORT_SYMBOL_GPL
++0xbd10afa1    drm_platform_init       vmlinux EXPORT_SYMBOL
++0xa1ceb496    drm_platform_exit       vmlinux EXPORT_SYMBOL
++0xd10d7d37    arp_tbl vmlinux EXPORT_SYMBOL
++0x9aa6cefb    __skb_recv_datagram     vmlinux EXPORT_SYMBOL
++0x0430401c    snd_soc_remove_platform vmlinux EXPORT_SYMBOL_GPL
++0xfe7c4287    nr_cpu_ids      vmlinux EXPORT_SYMBOL
++0x18b6fa40    v4l2_ctrl_add_ctrl      vmlinux EXPORT_SYMBOL
++0xb21d34e2    phy_attach      vmlinux EXPORT_SYMBOL
++0x67f7fd01    gpiochip_remove_pin_ranges      vmlinux EXPORT_SYMBOL_GPL
++0x5c9284a0    processor_id    vmlinux EXPORT_SYMBOL
++0x688e3c72    tcp_splice_read vmlinux EXPORT_SYMBOL
++0x9f7f32fe    xt_unregister_match     vmlinux EXPORT_SYMBOL
++0x2822f8fe    irq_setup_generic_chip  vmlinux EXPORT_SYMBOL_GPL
++0x8763d790    pm_genpd_syscore_switch vmlinux EXPORT_SYMBOL_GPL
++0xc898f9f7    css_depth       vmlinux EXPORT_SYMBOL_GPL
++0x95d97984    devm_regmap_init_spi    vmlinux EXPORT_SYMBOL_GPL
++0x32108723    devm_regmap_init_i2c    vmlinux EXPORT_SYMBOL_GPL
++0x824028e1    drm_master_get  vmlinux EXPORT_SYMBOL
++0x36e360e3    __hw_addr_add_multiple  vmlinux EXPORT_SYMBOL
++0x92e42550    snd_soc_jack_add_gpios  vmlinux EXPORT_SYMBOL_GPL
++0x9552bd34    crypto_unregister_algs  vmlinux EXPORT_SYMBOL_GPL
++0x70bd3119    simple_transaction_set  vmlinux EXPORT_SYMBOL
++0x5cf1e7e1    simple_transaction_get  vmlinux EXPORT_SYMBOL
++0x86b57862    find_pid_ns     vmlinux EXPORT_SYMBOL_GPL
++0x0b59c21c    st_gyro_common_probe    vmlinux EXPORT_SYMBOL
++0x3a4c6000    of_irq_to_resource      vmlinux EXPORT_SYMBOL_GPL
++0xcbc9557f    unregister_sysrq_key    vmlinux EXPORT_SYMBOL
++0xd85ac634    regulator_put   vmlinux EXPORT_SYMBOL_GPL
++0x56e75d47    klist_node_attached     vmlinux EXPORT_SYMBOL_GPL
++0xf0d6c49d    rfkill_alloc    vmlinux EXPORT_SYMBOL
++0xe118d3ca    __nf_conntrack_find     vmlinux EXPORT_SYMBOL_GPL
++0x67fa9d64    __nlmsg_put     vmlinux EXPORT_SYMBOL
++0xc5f839f2    lock_sock_nested        vmlinux EXPORT_SYMBOL
++0x92b57248    flush_work      vmlinux EXPORT_SYMBOL_GPL
++0x63aecd53    hid_add_device  vmlinux EXPORT_SYMBOL_GPL
++0x870e11ef    sdio_disable_func       vmlinux EXPORT_SYMBOL_GPL
++0xd6c99af7    devm_usb_put_phy        vmlinux EXPORT_SYMBOL_GPL
++0x60652b23    usbnet_cdc_bind vmlinux EXPORT_SYMBOL_GPL
++0x0f1fd032    scsi_free_command       vmlinux EXPORT_SYMBOL
++0x150d593e    platform_add_devices    vmlinux EXPORT_SYMBOL_GPL
++0xdc2235fd    device_show_bool        vmlinux EXPORT_SYMBOL_GPL
++0xe800ece3    __mmc_switch    vmlinux EXPORT_SYMBOL_GPL
++0x8650b7ba    usb_deregister  vmlinux EXPORT_SYMBOL_GPL
++0x83a82050    phy_ethtool_get_eee     vmlinux EXPORT_SYMBOL
++0xccb94d1a    phy_ethtool_set_eee     vmlinux EXPORT_SYMBOL
++0x1a81168a    drm_mm_dump_table       vmlinux EXPORT_SYMBOL
++0x04cda566    snd_interval_refine     vmlinux EXPORT_SYMBOL
++0x6b2dc060    dump_stack      vmlinux EXPORT_SYMBOL
++0x23476dca    crypto_alloc_instance   vmlinux EXPORT_SYMBOL_GPL
++0x31cd11aa    mpage_writepage vmlinux EXPORT_SYMBOL
++0xa219c44e    try_to_writeback_inodes_sb_nr   vmlinux EXPORT_SYMBOL
++0xd942d353    ring_buffer_record_off  vmlinux EXPORT_SYMBOL_GPL
++0x178768e1    set_security_override   vmlinux EXPORT_SYMBOL
++0x7930d225    of_device_is_compatible vmlinux EXPORT_SYMBOL
++0xa1fb703c    drm_mm_remove_node      vmlinux EXPORT_SYMBOL
++0x3fce0784    rdev_get_drvdata        vmlinux EXPORT_SYMBOL_GPL
++0x193f9832    nfc_allocate_device     vmlinux EXPORT_SYMBOL
++0xcefba9ae    raw_seq_start   vmlinux EXPORT_SYMBOL_GPL
++0x353b4dcf    nfnetlink_subsys_unregister     vmlinux EXPORT_SYMBOL_GPL
++0x1db53c10    dst_cow_metrics_generic vmlinux EXPORT_SYMBOL
++0x884c205c    mount_ns        vmlinux EXPORT_SYMBOL
++0x26b0e339    sdhci_disable_irq_wakeups       vmlinux EXPORT_SYMBOL_GPL
++0x69e3154c    rtc_read_time   vmlinux EXPORT_SYMBOL_GPL
++0xde6ff4ec    usb_get_function_instance       vmlinux EXPORT_SYMBOL_GPL
++0x0c29207f    netdev_master_upper_dev_get     vmlinux EXPORT_SYMBOL
++0x62d34ec2    kobject_del     vmlinux EXPORT_SYMBOL
++0x7489664f    crypto_unregister_shash vmlinux EXPORT_SYMBOL_GPL
++0x5ca7f0f8    crypto_unregister_ahash vmlinux EXPORT_SYMBOL_GPL
++0x86a4889a    kmalloc_order_trace     vmlinux EXPORT_SYMBOL
++0x0698cb23    drm_core_reclaim_buffers        vmlinux EXPORT_SYMBOL
++0x94478b76    nat_callforwarding_hook vmlinux EXPORT_SYMBOL_GPL
++0x6e4b8906    snd_ctl_find_numid      vmlinux EXPORT_SYMBOL
++0xb6a68816    find_last_bit   vmlinux EXPORT_SYMBOL
++0xc8d47bdb    inode_dio_done  vmlinux EXPORT_SYMBOL
++0xb9ca066f    poll_initwait   vmlinux EXPORT_SYMBOL
++0x193d48e0    trace_current_buffer_unlock_commit      vmlinux EXPORT_SYMBOL_GPL
++0x46a36032    unregister_console      vmlinux EXPORT_SYMBOL
++0xd0fbc335    vb2_get_vma     vmlinux EXPORT_SYMBOL_GPL
++0x6ebd302d    usb_reset_endpoint      vmlinux EXPORT_SYMBOL_GPL
++0x38a4f7ae    drm_format_num_planes   vmlinux EXPORT_SYMBOL
++0xc414c422    drm_vblank_offdelay     vmlinux EXPORT_SYMBOL
++0x96554810    register_keyboard_notifier      vmlinux EXPORT_SYMBOL_GPL
++0x2ec0f25c    nf_ct_helper_ext_add    vmlinux EXPORT_SYMBOL_GPL
++0xe745ec59    aead_geniv_free vmlinux EXPORT_SYMBOL_GPL
++0xd8e484f0    register_chrdev_region  vmlinux EXPORT_SYMBOL
++0xc58b6dd5    led_trigger_unregister_simple   vmlinux EXPORT_SYMBOL_GPL
++0x068f1d12    phy_disconnect  vmlinux EXPORT_SYMBOL
++0x9c518b55    regmap_update_bits      vmlinux EXPORT_SYMBOL_GPL
++0xc63f1b81    ieee80211_radiotap_iterator_next        vmlinux EXPORT_SYMBOL
++0x9744e080    inet_csk_reqsk_queue_prune      vmlinux EXPORT_SYMBOL_GPL
++0xb9ff0fd7    netdev_state_change     vmlinux EXPORT_SYMBOL
++0x310917fe    sort    vmlinux EXPORT_SYMBOL
++0xa8fef7bb    security_unix_may_send  vmlinux EXPORT_SYMBOL
++0x541bd60a    irq_work_run    vmlinux EXPORT_SYMBOL_GPL
++0x6c49c4f2    clockevents_notify      vmlinux EXPORT_SYMBOL_GPL
++0xe208ea98    hci_recv_stream_fragment        vmlinux EXPORT_SYMBOL
++0xe6c68334    ddebug_remove_module    vmlinux EXPORT_SYMBOL_GPL
++0xf8ae0cbf    kern_path       vmlinux EXPORT_SYMBOL
++0x6e9dd7bc    usb_sg_cancel   vmlinux EXPORT_SYMBOL_GPL
++0x7c05fd17    nf_register_queue_handler       vmlinux EXPORT_SYMBOL
++0x2a8db409    snd_soc_dai_set_tristate        vmlinux EXPORT_SYMBOL_GPL
++0x29b1c366    __sg_alloc_table        vmlinux EXPORT_SYMBOL
++0x9c3889f4    shrink_dcache_sb        vmlinux EXPORT_SYMBOL
++0x15692c87    param_ops_int   vmlinux EXPORT_SYMBOL
++0xd04e04f7    iio_update_demux        vmlinux EXPORT_SYMBOL_GPL
++0x105a7a58    dma_alloc_from_coherent vmlinux EXPORT_SYMBOL
++0xe4309905    syscore_resume  vmlinux EXPORT_SYMBOL_GPL
++0xab482a65    blkdev_issue_flush      vmlinux EXPORT_SYMBOL
++0x499043d3    crypto_init_queue       vmlinux EXPORT_SYMBOL_GPL
++0xca871be2    default_backing_dev_info        vmlinux EXPORT_SYMBOL_GPL
++0x3d5120d1    st_accel_common_probe   vmlinux EXPORT_SYMBOL
++0x44f5e8b5    of_allnodes     vmlinux EXPORT_SYMBOL
++0xf563353a    v4l2_subdev_link_validate       vmlinux EXPORT_SYMBOL_GPL
++0x011cf028    regulator_suspend_finish        vmlinux EXPORT_SYMBOL_GPL
++0x1b88e3fa    find_inode_number       vmlinux EXPORT_SYMBOL
++0xb2d307de    param_ops_short vmlinux EXPORT_SYMBOL
++0x0b586662    drm_gem_object_init     vmlinux EXPORT_SYMBOL
++0xaad6d92f    rfkill_init_sw_state    vmlinux EXPORT_SYMBOL
++0x4f4d4dc8    hci_unregister_dev      vmlinux EXPORT_SYMBOL
++0xa6970398    __kfifo_to_user_r       vmlinux EXPORT_SYMBOL
++0xf7f92f26    st_sensors_set_enable   vmlinux EXPORT_SYMBOL
++0x236bcb52    unregister_con_driver   vmlinux EXPORT_SYMBOL
++0x39898017    amba_device_put vmlinux EXPORT_SYMBOL_GPL
++0x8d28fc98    amba_device_add vmlinux EXPORT_SYMBOL_GPL
++0x3169d518    softnet_data    vmlinux EXPORT_SYMBOL
++0x5fc56a46    _raw_spin_unlock        vmlinux EXPORT_SYMBOL
++0xfe5d4bb2    sys_tz  vmlinux EXPORT_SYMBOL
++0x81ced62d    ip6_sk_redirect vmlinux EXPORT_SYMBOL_GPL
++0x9ffa3a75    netdev_max_backlog      vmlinux EXPORT_SYMBOL
++0xfa237e15    __skb_tx_hash   vmlinux EXPORT_SYMBOL
++0x1b701804    blk_init_queue  vmlinux EXPORT_SYMBOL
++0x474d3122    unlock_page     vmlinux EXPORT_SYMBOL
++0x4f98d766    cpu_pm_unregister_notifier      vmlinux EXPORT_SYMBOL_GPL
++0x76963409    lock_fb_info    vmlinux EXPORT_SYMBOL
++0x11e2ec12    flex_array_free_parts   vmlinux EXPORT_SYMBOL
++0x5ecb52ac    sdio_memcpy_fromio      vmlinux EXPORT_SYMBOL_GPL
++0xa4480afe    drm_sysfs_hotplug_event vmlinux EXPORT_SYMBOL
++0xeaab7f82    lcd_device_register     vmlinux EXPORT_SYMBOL
++0x0c12eee9    xfrm_unregister_type    vmlinux EXPORT_SYMBOL
++0x297f1a00    nf_ip_checksum  vmlinux EXPORT_SYMBOL
++0xd14bc4d9    sock_diag_save_cookie   vmlinux EXPORT_SYMBOL_GPL
++0xdd810ba9    snd_info_register       vmlinux EXPORT_SYMBOL
++0x773a9c94    blk_iopoll_enabled      vmlinux EXPORT_SYMBOL
++0xd704f458    jbd2_log_wait_commit    vmlinux EXPORT_SYMBOL
++0x22e82b9e    hrtimer_init_sleeper    vmlinux EXPORT_SYMBOL_GPL
++0x437e0518    eth_rebuild_header      vmlinux EXPORT_SYMBOL
++0x47fb2e90    neigh_compat_output     vmlinux EXPORT_SYMBOL
++0x0283dfe3    _snd_pcm_hw_params_any  vmlinux EXPORT_SYMBOL
++0xe2407fb6    user_path_at    vmlinux EXPORT_SYMBOL
++0x35d93ce8    cgroup_add_cftypes      vmlinux EXPORT_SYMBOL_GPL
++0x4ac62273    module_put      vmlinux EXPORT_SYMBOL
++0x2459bbcc    console_set_on_cmdline  vmlinux EXPORT_SYMBOL
++0xbec530ad    max8997_update_reg      vmlinux EXPORT_SYMBOL_GPL
++0x3255972d    hdmi_vendor_infoframe_pack      vmlinux EXPORT_SYMBOL
++0x8da61397    ip_tunnel_rcv   vmlinux EXPORT_SYMBOL_GPL
++0x3c44f68c    inode_get_bytes vmlinux EXPORT_SYMBOL
++0xd85cd67e    __wake_up       vmlinux EXPORT_SYMBOL
++0xcefe5c3b    usb_get_from_anchor     vmlinux EXPORT_SYMBOL_GPL
++0x9a858808    genphy_resume   vmlinux EXPORT_SYMBOL
++0x606ae2bc    drm_mm_debug_table      vmlinux EXPORT_SYMBOL
++0xed636ddf    nf_conntrack_helper_unregister  vmlinux EXPORT_SYMBOL_GPL
++0xc7a1840e    llist_add_batch vmlinux EXPORT_SYMBOL_GPL
++0x2787db00    vbin_printf     vmlinux EXPORT_SYMBOL_GPL
++0xfe59fc1b    security_d_instantiate  vmlinux EXPORT_SYMBOL
++0x6b8286e4    bio_reset       vmlinux EXPORT_SYMBOL
++0x86414ad5    vfs_mkdir       vmlinux EXPORT_SYMBOL
++0x87b883c7    i2c_for_each_dev        vmlinux EXPORT_SYMBOL_GPL
++0x26f81b6a    dev_driver_string       vmlinux EXPORT_SYMBOL
++0x1c787b32    eventfd_ctx_fileget     vmlinux EXPORT_SYMBOL_GPL
++0x01139ffc    max_mapnr       vmlinux EXPORT_SYMBOL
++0xec17ebb0    of_match_node   vmlinux EXPORT_SYMBOL
++0x69ce0071    usb_driver_claim_interface      vmlinux EXPORT_SYMBOL_GPL
++0x9cfd56c5    scsi_print_status       vmlinux EXPORT_SYMBOL
++0xdce6abcd    drm_gem_prime_handle_to_fd      vmlinux EXPORT_SYMBOL
++0x020f03b7    drm_sysfs_connector_remove      vmlinux EXPORT_SYMBOL
++0x2a8aa04e    pinctrl_add_gpio_range  vmlinux EXPORT_SYMBOL_GPL
++0x981dcc58    eventfd_fget    vmlinux EXPORT_SYMBOL_GPL
++0x7c995f04    dget_parent     vmlinux EXPORT_SYMBOL
++0x9a932b80    of_find_i2c_device_by_node      vmlinux EXPORT_SYMBOL
++0x2b460363    led_trigger_set vmlinux EXPORT_SYMBOL_GPL
++0x107733e3    wiphy_new       vmlinux EXPORT_SYMBOL
++0xd7b7598e    snd_pcm_mmap_data       vmlinux EXPORT_SYMBOL
++0x4e1636f1    mb_cache_create vmlinux EXPORT_SYMBOL
++0x70bec618    iunique vmlinux EXPORT_SYMBOL
++0x121d958a    unregister_die_notifier vmlinux EXPORT_SYMBOL_GPL
++0xbef4c852    hid_dump_input  vmlinux EXPORT_SYMBOL_GPL
++0x55423fc4    dm_requeue_unmapped_request     vmlinux EXPORT_SYMBOL_GPL
++0x2e67fc27    matrix_keypad_build_keymap      vmlinux EXPORT_SYMBOL
++0xe7c7c6b0    usb_disable_autosuspend vmlinux EXPORT_SYMBOL_GPL
++0x783194cd    usb_get_dev     vmlinux EXPORT_SYMBOL_GPL
++0x5614b010    xfrm_policy_walk_done   vmlinux EXPORT_SYMBOL
++0x6d5a6c10    inet_dgram_ops  vmlinux EXPORT_SYMBOL
++0x42e7ca3d    blk_alloc_queue vmlinux EXPORT_SYMBOL
++0xfdbd0a9b    mb_cache_destroy        vmlinux EXPORT_SYMBOL
++0x59cbc3ca    input_release_device    vmlinux EXPORT_SYMBOL
++0xd0e5d6d2    scsi_put_command        vmlinux EXPORT_SYMBOL
++0x480dca40    sec_reg_update  vmlinux EXPORT_SYMBOL_GPL
++0x28a73d8e    snd_soc_unregister_card vmlinux EXPORT_SYMBOL_GPL
++0x05fc144e    get_gendisk     vmlinux EXPORT_SYMBOL
++0xfef8a166    trace_current_buffer_lock_reserve       vmlinux EXPORT_SYMBOL_GPL
++0x7dccc294    proc_doulongvec_minmax  vmlinux EXPORT_SYMBOL
++0x92c0c538    ieee80211_bss_get_ie    vmlinux EXPORT_SYMBOL
++0x386ec802    tcp_proc_unregister     vmlinux EXPORT_SYMBOL
++0xb327256f    simple_attr_open        vmlinux EXPORT_SYMBOL_GPL
++0x56e9103b    cpu_pm_enter    vmlinux EXPORT_SYMBOL_GPL
++0x1e48b59d    __css_tryget    vmlinux EXPORT_SYMBOL_GPL
++0xbcbaa80a    __wake_up_locked_key    vmlinux EXPORT_SYMBOL_GPL
++0x2d1b02d2    usermodehelper_read_lock_wait   vmlinux EXPORT_SYMBOL_GPL
++0x72bfae4f    hwmon_device_register   vmlinux EXPORT_SYMBOL_GPL
++0x3db7f213    v4l2_of_get_remote_port vmlinux EXPORT_SYMBOL
++0x5de3f132    usb_interface_id        vmlinux EXPORT_SYMBOL_GPL
++0x9ca5592b    usb_store_new_id        vmlinux EXPORT_SYMBOL_GPL
++0x90fb0fa6    sdev_evt_send_simple    vmlinux EXPORT_SYMBOL_GPL
++0x25892d59    drm_vblank_post_modeset vmlinux EXPORT_SYMBOL
++0x8ecafd4a    drm_fb_helper_blank     vmlinux EXPORT_SYMBOL
++0x590d45c1    sk_clear_memalloc       vmlinux EXPORT_SYMBOL_GPL
++0x4578f528    __kfifo_to_user vmlinux EXPORT_SYMBOL
++0xf7ddfd4e    done_path_create        vmlinux EXPORT_SYMBOL
++0x85c10896    rcu_batches_completed_bh        vmlinux EXPORT_SYMBOL_GPL
++0x036dd11a    cgroup_path     vmlinux EXPORT_SYMBOL_GPL
++0xcc7fa952    local_bh_enable_ip      vmlinux EXPORT_SYMBOL
++0xa90054ee    rndis_uninit    vmlinux EXPORT_SYMBOL
++0x15407a03    usb_root_hub_lost_power vmlinux EXPORT_SYMBOL_GPL
++0x06fc143d    xfrm4_rcv_encap vmlinux EXPORT_SYMBOL
++0xa0c5538e    udp_poll        vmlinux EXPORT_SYMBOL
++0xd9f41f16    skb_copy_ubufs  vmlinux EXPORT_SYMBOL_GPL
++0xc83b4d5b    posix_acl_from_mode     vmlinux EXPORT_SYMBOL
++0x51ef33b8    kstrndup        vmlinux EXPORT_SYMBOL
++0x0bed814c    irq_set_chip    vmlinux EXPORT_SYMBOL
++0xd0f6cf25    console_stop    vmlinux EXPORT_SYMBOL
++0xd955eb7d    iommu_group_remove_device       vmlinux EXPORT_SYMBOL_GPL
++0xfb5dc251    gserial_disconnect      vmlinux EXPORT_SYMBOL_GPL
++0x42252607    inet6_getname   vmlinux EXPORT_SYMBOL
++0xe65b1e97    nf_conntrack_tuple_taken        vmlinux EXPORT_SYMBOL_GPL
++0x7abbee1e    wm_hubs_handle_analogue_pdata   vmlinux EXPORT_SYMBOL_GPL
++0x06dceffb    snd_soc_of_parse_daifmt vmlinux EXPORT_SYMBOL_GPL
++0xf4439247    snd_device_register     vmlinux EXPORT_SYMBOL
++0xebcea57f    evict_bh_lrus   vmlinux EXPORT_SYMBOL_GPL
++0x9714253c    mfd_add_devices vmlinux EXPORT_SYMBOL
++0x26256356    drm_mode_equal_no_clocks        vmlinux EXPORT_SYMBOL
++0x1be7f7c8    debugfs_create_file     vmlinux EXPORT_SYMBOL_GPL
++0xdbb607c7    new_inode       vmlinux EXPORT_SYMBOL
++0xa576c92e    drm_mode_config_reset   vmlinux EXPORT_SYMBOL
++0x832ca829    snd_ctl_find_id vmlinux EXPORT_SYMBOL
++0x65dccf13    xz_dec_end      vmlinux EXPORT_SYMBOL
++0xf9348cbc    xz_dec_run      vmlinux EXPORT_SYMBOL
++0xe0b13336    argv_free       vmlinux EXPORT_SYMBOL
++0x8815b870    jbd2_journal_clear_err  vmlinux EXPORT_SYMBOL
++0x861359ed    of_get_phy_mode vmlinux EXPORT_SYMBOL_GPL
++0x28a2ed02    scsi_build_sense_buffer vmlinux EXPORT_SYMBOL
++0x86240fb6    tty_port_close  vmlinux EXPORT_SYMBOL
++0x8d3e24c6    genl_unregister_family  vmlinux EXPORT_SYMBOL
++0x9d0d6206    unregister_netdevice_notifier   vmlinux EXPORT_SYMBOL
++0x18640d1b    mmc_suspend_host        vmlinux EXPORT_SYMBOL
++0x9082ce2b    tty_register_driver     vmlinux EXPORT_SYMBOL
++0x71f65175    hdmi_spd_infoframe_pack vmlinux EXPORT_SYMBOL
++0x3d6f0d06    ndo_dflt_fdb_del        vmlinux EXPORT_SYMBOL
++0xaeefbeed    kset_unregister vmlinux EXPORT_SYMBOL
++0xa498b92e    debugfs_create_u32      vmlinux EXPORT_SYMBOL_GPL
++0x7ed8eb88    sdio_release_host       vmlinux EXPORT_SYMBOL_GPL
++0xd1e4eed4    v4l2_fh_init    vmlinux EXPORT_SYMBOL_GPL
++0x5b42ed42    v4l2_fh_exit    vmlinux EXPORT_SYMBOL_GPL
++0x5947abbe    max77693_bulk_write     vmlinux EXPORT_SYMBOL_GPL
++0x7afa1fc2    driver_remove_file      vmlinux EXPORT_SYMBOL_GPL
++0xacefc84d    netdev_rx_handler_register      vmlinux EXPORT_SYMBOL_GPL
++0xd2e829b5    jbd2_journal_release_jbd_inode  vmlinux EXPORT_SYMBOL
++0xcd343f41    mmc_gpio_free_ro        vmlinux EXPORT_SYMBOL
++0x26f37f1a    inet_csk_reset_keepalive_timer  vmlinux EXPORT_SYMBOL
++0x49603fb8    security_sb_copy_data   vmlinux EXPORT_SYMBOL
++0x53326531    mempool_alloc_pages     vmlinux EXPORT_SYMBOL
++0x2b49351d    trace_define_field      vmlinux EXPORT_SYMBOL_GPL
++0x47939e0d    __tasklet_hi_schedule   vmlinux EXPORT_SYMBOL
++0x78c5a239    clk_prepare     vmlinux EXPORT_SYMBOL_GPL
++0x1a36f8fd    udc_attach_driver       vmlinux EXPORT_SYMBOL_GPL
++0xcb56fc45    dev_vprintk_emit        vmlinux EXPORT_SYMBOL
++0xed2817be    arp_send        vmlinux EXPORT_SYMBOL
++0x7d903146    xt_register_matches     vmlinux EXPORT_SYMBOL
++0x3ed63055    zlib_inflateReset       vmlinux EXPORT_SYMBOL
++0x281823c5    __kfifo_out_peek        vmlinux EXPORT_SYMBOL
++0xb19760c3    bitmap_onto     vmlinux EXPORT_SYMBOL
++0xaf9b8476    cdev_del        vmlinux EXPORT_SYMBOL
++0xbc8da552    tcp_seq_open    vmlinux EXPORT_SYMBOL
++0x35224ff2    pneigh_enqueue  vmlinux EXPORT_SYMBOL
++0x0d2e0ab9    dev_alloc_name  vmlinux EXPORT_SYMBOL
++0xebd8aaa8    iov_iter_copy_from_user vmlinux EXPORT_SYMBOL
++0x134dc23b    v4l2_m2m_dqbuf  vmlinux EXPORT_SYMBOL_GPL
++0x1cfa672b    soft_cursor     vmlinux EXPORT_SYMBOL
++0xac8f37b2    outer_cache     vmlinux EXPORT_SYMBOL
++0x744bfef9    generic_fh_to_dentry    vmlinux EXPORT_SYMBOL_GPL
++0xa3225eb1    try_to_del_timer_sync   vmlinux EXPORT_SYMBOL
++0x6a1733eb    iommu_group_unregister_notifier vmlinux EXPORT_SYMBOL_GPL
++0xc84dae86    matrix_keypad_parse_of_params   vmlinux EXPORT_SYMBOL_GPL
++0x404403a9    usb_free_all_descriptors        vmlinux EXPORT_SYMBOL_GPL
++0x50eca283    ipcomp_output   vmlinux EXPORT_SYMBOL_GPL
++0xe482d673    nf_ct_expect_related_report     vmlinux EXPORT_SYMBOL_GPL
++0x26e58975    __pskb_copy     vmlinux EXPORT_SYMBOL
++0xd3dcab0b    flex_array_alloc        vmlinux EXPORT_SYMBOL
++0x247f1878    blk_queue_bounce        vmlinux EXPORT_SYMBOL
++0x97b13dad    __clocksource_register_scale    vmlinux EXPORT_SYMBOL_GPL
++0xdc73e48f    dm_unregister_target    vmlinux EXPORT_SYMBOL
++0xfe0f06c0    tty_init_termios        vmlinux EXPORT_SYMBOL_GPL
++0xb8356d30    dma_async_memcpy_buf_to_pg      vmlinux EXPORT_SYMBOL
++0xd8d3cf00    read_dev_sector vmlinux EXPORT_SYMBOL
++0x220669c4    scsi_cmd_blk_ioctl      vmlinux EXPORT_SYMBOL
++0x03c91b88    crypto_alloc_instance2  vmlinux EXPORT_SYMBOL_GPL
++0x4d9c0e6d    jbd2_journal_revoke     vmlinux EXPORT_SYMBOL
++0xaca5e909    config_group_find_item  vmlinux EXPORT_SYMBOL
++0xe01ba49b    iio_kfifo_allocate      vmlinux EXPORT_SYMBOL
++0xe170917a    timed_output_dev_unregister     vmlinux EXPORT_SYMBOL_GPL
++0x4f689046    brcmu_pkt_buf_free_skb  drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x932f03cb    security_old_inode_init_security        vmlinux EXPORT_SYMBOL
++0xa4e5092b    debugfs_create_x16      vmlinux EXPORT_SYMBOL_GPL
++0x1826f089    __tracepoint_kmem_cache_alloc_node      vmlinux EXPORT_SYMBOL
++0xd81de62c    ring_buffer_record_enable       vmlinux EXPORT_SYMBOL_GPL
++0xc7fe94dd    usb_ifnum_to_if vmlinux EXPORT_SYMBOL_GPL
++0xc2af811e    inet6_destroy_sock      vmlinux EXPORT_SYMBOL_GPL
++0x061651be    strcat  vmlinux EXPORT_SYMBOL
++0xb39ec138    mb_cache_entry_release  vmlinux EXPORT_SYMBOL
++0x51d559d1    _raw_spin_unlock_irqrestore     vmlinux EXPORT_SYMBOL
++0xa6eb0e39    phy_device_create       vmlinux EXPORT_SYMBOL
++0xf92c66be    drm_mm_search_free_generic      vmlinux EXPORT_SYMBOL
++0x97270fcf    crypto_register_shash   vmlinux EXPORT_SYMBOL_GPL
++0x495f2be4    jbd2_journal_get_write_access   vmlinux EXPORT_SYMBOL
++0x3826f483    jbd2_journal_invalidatepage     vmlinux EXPORT_SYMBOL
++0xd8a12f4d    iio_scan_mask_query     vmlinux EXPORT_SYMBOL_GPL
++0x09b069ea    v4l2_ctrl_log_status    vmlinux EXPORT_SYMBOL
++0x0a513c7c    usb_gadget_unregister_driver    vmlinux EXPORT_SYMBOL_GPL
++0x39ef8cc9    dma_buf_kunmap  vmlinux EXPORT_SYMBOL_GPL
++0xd28b5dda    dma_buf_vunmap  vmlinux EXPORT_SYMBOL_GPL
++0x3fcf2826    inet6_unregister_protosw        vmlinux EXPORT_SYMBOL
++0x551c3633    nf_nat_l4proto_unique_tuple     vmlinux EXPORT_SYMBOL_GPL
++0x86700640    nf_register_hooks       vmlinux EXPORT_SYMBOL
++0x44e94d6c    pfifo_qdisc_ops vmlinux EXPORT_SYMBOL
++0xf202c5cb    radix_tree_insert       vmlinux EXPORT_SYMBOL
++0x24ffe755    vfs_listxattr   vmlinux EXPORT_SYMBOL_GPL
++0x52428cc8    parent_mem_cgroup       vmlinux EXPORT_SYMBOL
++0x9d59c0f2    find_get_pages_contig   vmlinux EXPORT_SYMBOL
++0x80f3268f    __trace_printk  vmlinux EXPORT_SYMBOL_GPL
++0x22a27a85    st_sensors_spi_configure        vmlinux EXPORT_SYMBOL
++0x7880c781    dm_kcopyd_prepare_callback      vmlinux EXPORT_SYMBOL
++0xc53f0876    vb2_dma_contig_memops   vmlinux EXPORT_SYMBOL_GPL
++0x388f9128    xfrm_state_walk_done    vmlinux EXPORT_SYMBOL
++0x6d6888a7    qdisc_create_dflt       vmlinux EXPORT_SYMBOL
++0x194ccf46    bmap    vmlinux EXPORT_SYMBOL
++0xe2fae716    kmemdup vmlinux EXPORT_SYMBOL
++0x07ed48c3    __blocking_notifier_call_chain  vmlinux EXPORT_SYMBOL_GPL
++0x074d7047    st_sensors_trigger_handler      vmlinux EXPORT_SYMBOL
++0x33883929    clk_divider_ops vmlinux EXPORT_SYMBOL_GPL
++0xe2b92059    v4l2_video_std_construct        vmlinux EXPORT_SYMBOL
++0x06ea1593    usbnet_defer_kevent     vmlinux EXPORT_SYMBOL_GPL
++0x6650ad3e    uart_add_one_port       vmlinux EXPORT_SYMBOL
++0x5dda183c    snd_soc_dapm_disable_pin        vmlinux EXPORT_SYMBOL_GPL
++0x7a188791    prandom_bytes   vmlinux EXPORT_SYMBOL
++0xc25a61ec    drm_mode_set_crtcinfo   vmlinux EXPORT_SYMBOL
++0xcb1beab5    drm_mode_vrefresh       vmlinux EXPORT_SYMBOL
++0x4a94168c    tcp_register_congestion_control vmlinux EXPORT_SYMBOL_GPL
++0x4f5836c8    tcp_release_cb  vmlinux EXPORT_SYMBOL
++0x2f366d34    tcp_gro_complete        vmlinux EXPORT_SYMBOL
++0x1eba8ee6    nf_conntrack_alloc      vmlinux EXPORT_SYMBOL_GPL
++0x28a903c8    timerqueue_add  vmlinux EXPORT_SYMBOL_GPL
++0x96cea50b    sync_filesystem vmlinux EXPORT_SYMBOL_GPL
++0x68c0685a    media_entity_setup_link vmlinux EXPORT_SYMBOL_GPL
++0x69b83c18    usb_get_phy_dev vmlinux EXPORT_SYMBOL_GPL
++0x7e6bf1b2    dma_buf_fd      vmlinux EXPORT_SYMBOL_GPL
++0x4d974b9c    register_sysrq_key      vmlinux EXPORT_SYMBOL
++0xf79531f4    tcp_connect     vmlinux EXPORT_SYMBOL
++0x3f45ea36    neigh_table_clear       vmlinux EXPORT_SYMBOL
++0xf6de842c    clk_get_parent  vmlinux EXPORT_SYMBOL_GPL
++0x4782eebf    clk_set_parent  vmlinux EXPORT_SYMBOL_GPL
++0x45a20c5a    of_phy_find_device      vmlinux EXPORT_SYMBOL
++0xcbbedfcb    led_trigger_event       vmlinux EXPORT_SYMBOL_GPL
++0x69281b40    thermal_zone_bind_cooling_device        vmlinux EXPORT_SYMBOL_GPL
++0xe122af95    xfrm_aalg_get_byname    vmlinux EXPORT_SYMBOL_GPL
++0x74b1375e    xfrm_state_flush        vmlinux EXPORT_SYMBOL
++0x94098ff8    snd_interval_list       vmlinux EXPORT_SYMBOL
++0x64f01d42    fuse_put_request        vmlinux EXPORT_SYMBOL_GPL
++0x1811ac2f    fat_flush_inodes        vmlinux EXPORT_SYMBOL_GPL
++0x73198f14    mmc_align_data_size     vmlinux EXPORT_SYMBOL
++0xa70df32d    drm_fb_helper_fill_var  vmlinux EXPORT_SYMBOL
++0x209e95ea    xfrm_find_acq_byseq     vmlinux EXPORT_SYMBOL
++0x4b9e2d58    xfrm_policy_unregister_afinfo   vmlinux EXPORT_SYMBOL
++0x461a1d6a    __rtnl_af_register      vmlinux EXPORT_SYMBOL_GPL
++0x09c55cec    schedule_timeout_interruptible  vmlinux EXPORT_SYMBOL
++0xf512c668    iio_trigger_free        vmlinux EXPORT_SYMBOL
++0xdac28b43    dw_mci_resume   vmlinux EXPORT_SYMBOL
++0x361e2bcc    save_stack_trace        vmlinux EXPORT_SYMBOL_GPL
++0x25e6af56    snd_compress_register   vmlinux EXPORT_SYMBOL_GPL
++0x1ace138d    bitmap_allocate_region  vmlinux EXPORT_SYMBOL
++0x250113b4    memory_read_from_buffer vmlinux EXPORT_SYMBOL
++0x4ae22649    iommu_set_fault_handler vmlinux EXPORT_SYMBOL_GPL
++0x3ca38e3a    rndis_signal_connect    vmlinux EXPORT_SYMBOL
++0x9d01b017    dma_buf_attach  vmlinux EXPORT_SYMBOL_GPL
++0x3930a5b6    dma_buf_detach  vmlinux EXPORT_SYMBOL_GPL
++0x2aec4354    hci_alloc_dev   vmlinux EXPORT_SYMBOL
++0xbb5d343d    xfrm_get_acqseq vmlinux EXPORT_SYMBOL
++0x4082abfe    __scsi_iterate_devices  vmlinux EXPORT_SYMBOL
++0x6b6d7375    drm_timestamp_precision vmlinux EXPORT_SYMBOL
++0x7ffcb57f    ip6_tnl_get_cap vmlinux EXPORT_SYMBOL
++0xccc812c3    dapm_clock_event        vmlinux EXPORT_SYMBOL_GPL
++0x1a47bf65    blk_queue_bounce_limit  vmlinux EXPORT_SYMBOL
++0xcc13c782    vb2_ioctl_streamon      vmlinux EXPORT_SYMBOL_GPL
++0x8afddc98    spi_register_driver     vmlinux EXPORT_SYMBOL_GPL
++0x17ae6853    platform_bus    vmlinux EXPORT_SYMBOL_GPL
++0x72ac0290    exynos_drm_device_unregister    vmlinux EXPORT_SYMBOL_GPL
++0xf71ca112    skb_abort_seq_read      vmlinux EXPORT_SYMBOL
++0x18bbe186    snd_soc_cnew    vmlinux EXPORT_SYMBOL_GPL
++0x2b0ba2b0    scsi_sense_desc_find    vmlinux EXPORT_SYMBOL
++0x8de13715    drm_format_vert_chroma_subsampling      vmlinux EXPORT_SYMBOL
++0x06fe3b14    default_grn     vmlinux EXPORT_SYMBOL
++0xee683d16    inet6_ioctl     vmlinux EXPORT_SYMBOL
++0x47252a20    tcp_getsockopt  vmlinux EXPORT_SYMBOL
++0x7027c3ad    tcp_setsockopt  vmlinux EXPORT_SYMBOL
++0xb7f74966    rtnl_unicast    vmlinux EXPORT_SYMBOL
++0x525971d4    snd_soc_update_bits_locked      vmlinux EXPORT_SYMBOL_GPL
++0x6ef8fcd8    snd_pcm_format_linear   vmlinux EXPORT_SYMBOL
++0x8f8f6e19    alloc_disk_node vmlinux EXPORT_SYMBOL
++0x71c445f5    fuse_get_req    vmlinux EXPORT_SYMBOL_GPL
++0xc41cff79    dequeue_signal  vmlinux EXPORT_SYMBOL_GPL
++0x5d9d3491    v4l_match_dv_timings    vmlinux EXPORT_SYMBOL_GPL
++0x829a8cac    drm_property_create_range       vmlinux EXPORT_SYMBOL
++0xf3189246    __rtnl_af_unregister    vmlinux EXPORT_SYMBOL_GPL
++0x0d7e8390    crypto_ablkcipher_type  vmlinux EXPORT_SYMBOL_GPL
++0xaf8e1608    ip6t_register_table     vmlinux EXPORT_SYMBOL
++0xb1a1e40e    crypto_tfm_in_queue     vmlinux EXPORT_SYMBOL_GPL
++0xc73f3f9a    fget_raw        vmlinux EXPORT_SYMBOL
++0x71008581    atomic_notifier_call_chain      vmlinux EXPORT_SYMBOL_GPL
++0x12bf1d5c    usbnet_device_suggests_idle     vmlinux EXPORT_SYMBOL
++0x79b993ef    cfg80211_send_unprot_deauth     vmlinux EXPORT_SYMBOL
++0xdacc53b2    spi_add_device  vmlinux EXPORT_SYMBOL_GPL
++0xf5a5c913    backlight_device_unregister     vmlinux EXPORT_SYMBOL
++0xadce320f    pinctrl_add_gpio_ranges vmlinux EXPORT_SYMBOL_GPL
++0x0f8342e1    phy_pm_runtime_forbid   vmlinux EXPORT_SYMBOL_GPL
++0xc0763484    rfkill_blocked  vmlinux EXPORT_SYMBOL
++0xb0bad0e8    ip6_push_pending_frames vmlinux EXPORT_SYMBOL_GPL
++0xfc02b7ad    sysctl_tcp_wmem vmlinux EXPORT_SYMBOL
++0xac782342    nf_unregister_hook      vmlinux EXPORT_SYMBOL
++0xa08421e0    dev_change_net_namespace        vmlinux EXPORT_SYMBOL_GPL
++0x47c6d038    blk_queue_flush_queueable       vmlinux EXPORT_SYMBOL_GPL
++0x2db8f309    blk_queue_rq_timeout    vmlinux EXPORT_SYMBOL_GPL
++0x6fb277a1    flush_kernel_dcache_page        vmlinux EXPORT_SYMBOL
++0x1d633e6a    tcp_twsk_destructor     vmlinux EXPORT_SYMBOL_GPL
++0x7611866b    scm_detach_fds  vmlinux EXPORT_SYMBOL
++0xd3b02cea    put_pid vmlinux EXPORT_SYMBOL_GPL
++0xed20e404    iio_dealloc_pollfunc    vmlinux EXPORT_SYMBOL_GPL
++0xba706bd7    samsung_pwm_lock        vmlinux EXPORT_SYMBOL
++0x158b7724    media_entity_create_link        vmlinux EXPORT_SYMBOL_GPL
++0x1172ce54    rtc_ktime_to_tm vmlinux EXPORT_SYMBOL_GPL
++0xa286a234    snd_pcm_format_name     vmlinux EXPORT_SYMBOL_GPL
++0xc7e39bca    ring_buffer_dropped_events_cpu  vmlinux EXPORT_SYMBOL_GPL
++0xaa957320    posix_clock_register    vmlinux EXPORT_SYMBOL_GPL
++0xad46dec2    of_count_phandle_with_args      vmlinux EXPORT_SYMBOL
++0x7120d717    regmap_bulk_read        vmlinux EXPORT_SYMBOL_GPL
++0xca56dea4    driver_find_device      vmlinux EXPORT_SYMBOL_GPL
++0x9c9d19e7    blk_get_request vmlinux EXPORT_SYMBOL
++0x2c790eff    usbnet_read_cmd_nopm    vmlinux EXPORT_SYMBOL_GPL
++0xbb99125c    get_default_font        vmlinux EXPORT_SYMBOL
++0x6e5cf115    cfg80211_inform_bss     vmlinux EXPORT_SYMBOL
++0xce7a55c1    xfrm_ealg_get_byid      vmlinux EXPORT_SYMBOL_GPL
++0x0cc1e40f    crypto_it_tab   vmlinux EXPORT_SYMBOL_GPL
++0x3dc916b6    crypto_fl_tab   vmlinux EXPORT_SYMBOL_GPL
++0x40d46b21    crypto_ft_tab   vmlinux EXPORT_SYMBOL_GPL
++0x71dc9998    crypto_il_tab   vmlinux EXPORT_SYMBOL_GPL
++0x837d0f0a    down_timeout    vmlinux EXPORT_SYMBOL
++0x2cd7dd71    __cpufreq_driver_getavg vmlinux EXPORT_SYMBOL_GPL
++0xee6b71c4    syscon_regmap_lookup_by_compatible      vmlinux EXPORT_SYMBOL_GPL
++0xae77b400    device_pm_wait_for_dev  vmlinux EXPORT_SYMBOL_GPL
++0x1d5a2494    nfnetlink_has_listeners vmlinux EXPORT_SYMBOL_GPL
++0x3bd1b1f6    msecs_to_jiffies        vmlinux EXPORT_SYMBOL
++0xfb09f255    cpufreq_frequency_table_target  vmlinux EXPORT_SYMBOL_GPL
++0xb52e203b    snd_pcm_suspend_all     vmlinux EXPORT_SYMBOL
++0xc1ec3550    blkdev_fsync    vmlinux EXPORT_SYMBOL
++0x0ebe6f54    lookup_one_len  vmlinux EXPORT_SYMBOL
++0x151404f6    misc_deregister vmlinux EXPORT_SYMBOL
++0xb2856c71    inet6_bind      vmlinux EXPORT_SYMBOL
++0xf68285c0    register_inetaddr_notifier      vmlinux EXPORT_SYMBOL
++0x7afc9d8a    unregister_sound_mixer  vmlinux EXPORT_SYMBOL
++0xd5d80496    atomic_dec_and_mutex_lock       vmlinux EXPORT_SYMBOL
++0x4351577a    fb_parse_edid   vmlinux EXPORT_SYMBOL
++0x68beb163    nf_ct_l3proto_pernet_unregister vmlinux EXPORT_SYMBOL_GPL
++0x7751fba7    nf_ct_l4proto_pernet_unregister vmlinux EXPORT_SYMBOL_GPL
++0x5cbe0b31    snd_pcm_lib_write       vmlinux EXPORT_SYMBOL
++0x6cecc98a    devres_get      vmlinux EXPORT_SYMBOL_GPL
++0x20925954    devres_add      vmlinux EXPORT_SYMBOL_GPL
++0x99a9dfa6    ieee80211_data_to_8023  vmlinux EXPORT_SYMBOL
++0x21036b2c    bt_accept_enqueue       vmlinux EXPORT_SYMBOL
++0x0cd5a88b    sync_inodes_sb  vmlinux EXPORT_SYMBOL
++0x7485e15e    unregister_chrdev_region        vmlinux EXPORT_SYMBOL
++0x7e8ad403    generic_writepages      vmlinux EXPORT_SYMBOL
++0x07cf3227    clk_fixed_rate_ops      vmlinux EXPORT_SYMBOL_GPL
++0xf5463be8    led_trigger_blink_oneshot       vmlinux EXPORT_SYMBOL_GPL
++0xdbf18207    v4l2_device_register_subdev     vmlinux EXPORT_SYMBOL_GPL
++0x131a5ed7    regmap_del_irq_chip     vmlinux EXPORT_SYMBOL_GPL
++0xb09c8d37    regmap_add_irq_chip     vmlinux EXPORT_SYMBOL_GPL
++0x26f0453a    blk_set_default_limits  vmlinux EXPORT_SYMBOL
++0xf21f8a44    blk_init_allocated_queue        vmlinux EXPORT_SYMBOL
++0x60df1e3b    posix_acl_equiv_mode    vmlinux EXPORT_SYMBOL
++0xc131c5dd    usb_add_phy     vmlinux EXPORT_SYMBOL_GPL
++0x211c5b26    cdc_ncm_bind_common     vmlinux EXPORT_SYMBOL_GPL
++0x61f6939e    drm_i2c_encoder_detect  vmlinux EXPORT_SYMBOL
++0xd9f310b2    gpiochip_is_requested   vmlinux EXPORT_SYMBOL_GPL
++0xb9639d32    rtnl_register   vmlinux EXPORT_SYMBOL_GPL
++0xf2254dc3    sock_from_file  vmlinux EXPORT_SYMBOL
++0x0f5455e2    snd_soc_info_enum_double        vmlinux EXPORT_SYMBOL_GPL
++0xdd89a6bf    lookup_bdev     vmlinux EXPORT_SYMBOL
++0x55704318    clockevents_config_and_register vmlinux EXPORT_SYMBOL_GPL
++0x2fd8cba9    freeze_wake     vmlinux EXPORT_SYMBOL_GPL
++0x071b7eea    irq_stat        vmlinux EXPORT_SYMBOL
++0x7a8ca627    xfrm_count_pfkey_enc_supported  vmlinux EXPORT_SYMBOL_GPL
++0x1ff2a733    raw_seq_stop    vmlinux EXPORT_SYMBOL_GPL
++0x85b825e7    gnet_stats_copy_basic   vmlinux EXPORT_SYMBOL
++0x0cfefe1e    percpu_counter_destroy  vmlinux EXPORT_SYMBOL
++0x02ea69e2    vm_map_ram      vmlinux EXPORT_SYMBOL
++0x36eb3583    filemap_fdatawrite_range        vmlinux EXPORT_SYMBOL
++0xb977cf42    inet_sendmsg    vmlinux EXPORT_SYMBOL
++0xddbcead7    ip_cmsg_recv    vmlinux EXPORT_SYMBOL
++0xb9a64b20    elevator_alloc  vmlinux EXPORT_SYMBOL
++0xbcaf3971    crypto_alg_sem  vmlinux EXPORT_SYMBOL_GPL
++0xe71dab2c    bio_sector_offset       vmlinux EXPORT_SYMBOL
++0x2c44797e    hidinput_report_event   vmlinux EXPORT_SYMBOL_GPL
++0x5d9e8570    drm_display_mode_from_videomode vmlinux EXPORT_SYMBOL_GPL
++0x2b8e67cd    fuse_get_req_for_background     vmlinux EXPORT_SYMBOL_GPL
++0x2b1c6816    extcon_dev_register     vmlinux EXPORT_SYMBOL_GPL
++0xdef26358    dw_mci_probe    vmlinux EXPORT_SYMBOL
++0xcbde0d9d    inverse_translate       vmlinux EXPORT_SYMBOL_GPL
++0x056ee730    ipv6_hash_secret        vmlinux EXPORT_SYMBOL
++0xfe029963    unregister_inetaddr_notifier    vmlinux EXPORT_SYMBOL
++0x650a6767    prandom_u32_state       vmlinux EXPORT_SYMBOL
++0x4148a5ff    get_kernel_pages        vmlinux EXPORT_SYMBOL_GPL
++0x24d3448d    perf_event_enable       vmlinux EXPORT_SYMBOL_GPL
++0x1c5a04e0    irq_domain_generate_simple      vmlinux EXPORT_SYMBOL_GPL
++0xb7b4232a    unregister_exec_domain  vmlinux EXPORT_SYMBOL
++0xd6f86c04    amba_release_regions    vmlinux EXPORT_SYMBOL
++0x89d5538d    fb_pad_aligned_buffer   vmlinux EXPORT_SYMBOL
++0x93237692    nobh_write_begin        vmlinux EXPORT_SYMBOL
++0x920eb90c    interruptible_sleep_on_timeout  vmlinux EXPORT_SYMBOL
++0x3a36ce8c    od_register_powersave_bias_handler      vmlinux EXPORT_SYMBOL_GPL
++0x946b8b6c    netlink_ack     vmlinux EXPORT_SYMBOL
++0x1000be5b    sock_no_bind    vmlinux EXPORT_SYMBOL
++0x1e5479ed    sock_get_timestamp      vmlinux EXPORT_SYMBOL
++0x4211c3c1    zlib_inflateInit2       vmlinux EXPORT_SYMBOL
++0x2486141e    bio_alloc_pages vmlinux EXPORT_SYMBOL
++0x62fd6207    param_set_charp vmlinux EXPORT_SYMBOL
++0x0862d814    v4l2_event_unsubscribe_all      vmlinux EXPORT_SYMBOL_GPL
++0x2f10e618    v4l2_event_queue_fh     vmlinux EXPORT_SYMBOL_GPL
++0x6bdcfd99    qdisc_class_hash_remove vmlinux EXPORT_SYMBOL
++0xf070e888    __put_net       vmlinux EXPORT_SYMBOL_GPL
++0x8df3789f    snd_oss_info_register   vmlinux EXPORT_SYMBOL
++0x68c73797    fuse_request_alloc      vmlinux EXPORT_SYMBOL_GPL
++0x2342f1ae    v4l2_prio_open  vmlinux EXPORT_SYMBOL
++0x4ddaa6ea    dmam_alloc_noncoherent  vmlinux EXPORT_SYMBOL
++0x7dfdf9a1    transport_destroy_device        vmlinux EXPORT_SYMBOL_GPL
++0x8c510862    drm_find_cea_extension  vmlinux EXPORT_SYMBOL
++0x7c0267ee    serial8250_tx_chars     vmlinux EXPORT_SYMBOL_GPL
++0x6879e81d    display_entity_put      vmlinux EXPORT_SYMBOL_GPL
++0xf19a455d    lro_flush_pkt   vmlinux EXPORT_SYMBOL
++0xbf8ba54a    vprintk vmlinux EXPORT_SYMBOL
++0x7bd1de14    thermal_cdev_update     vmlinux EXPORT_SYMBOL
++0x2631d719    tty_unregister_device   vmlinux EXPORT_SYMBOL
++0xa7e7f050    __udp4_lib_lookup       vmlinux EXPORT_SYMBOL_GPL
++0x2e2ce9e0    sysctl_tcp_syncookies   vmlinux EXPORT_SYMBOL
++0xd5a8fd58    tcp_poll        vmlinux EXPORT_SYMBOL
++0x3f74afb9    nf_ct_l3proto_register  vmlinux EXPORT_SYMBOL_GPL
++0xb4998fd0    nf_ct_l4proto_register  vmlinux EXPORT_SYMBOL_GPL
++0x2482e688    vsprintf        vmlinux EXPORT_SYMBOL
++0x59e4b703    generic_splice_sendpage vmlinux EXPORT_SYMBOL
++0x1795a16b    __genl_register_family_with_ops vmlinux EXPORT_SYMBOL
++0xcb469d2b    ddebug_add_module       vmlinux EXPORT_SYMBOL_GPL
++0xa2d83f8b    grab_cache_page_write_begin     vmlinux EXPORT_SYMBOL
++0x8c930a68    rt_mutex_lock_interruptible     vmlinux EXPORT_SYMBOL_GPL
++0xcc0871f2    attribute_container_find_class_device   vmlinux EXPORT_SYMBOL_GPL
++0x13b52797    pwm_request_from_chip   vmlinux EXPORT_SYMBOL_GPL
++0x28118cb6    __get_user_1    vmlinux EXPORT_SYMBOL
++0xbb72d4fe    __put_user_1    vmlinux EXPORT_SYMBOL
++0x0cae232b    utf16s_to_utf8s vmlinux EXPORT_SYMBOL
++0x617a218d    __cond_resched_lock     vmlinux EXPORT_SYMBOL
++0x44224883    __put_task_struct       vmlinux EXPORT_SYMBOL_GPL
++0xbc65845b    class_create_file       vmlinux EXPORT_SYMBOL_GPL
++0xe459c49b    unregister_pernet_subsys        vmlinux EXPORT_SYMBOL_GPL
++0xd882a162    wait_on_sync_kiocb      vmlinux EXPORT_SYMBOL
++0x28acb0e5    simple_write_begin      vmlinux EXPORT_SYMBOL
++0x5c1cb07e    redirty_page_for_writepage      vmlinux EXPORT_SYMBOL
++0x6070a6fb    bdi_set_max_ratio       vmlinux EXPORT_SYMBOL
++0xfee43a69    drm_dp_get_adjust_request_voltage       vmlinux EXPORT_SYMBOL
++0x8ffe7e89    nf_conntrack_htable_size        vmlinux EXPORT_SYMBOL_GPL
++0x79c527b0    netdev_emerg    vmlinux EXPORT_SYMBOL
++0x0bc7142a    sk_stream_kill_queues   vmlinux EXPORT_SYMBOL
++0xeb37101c    audit_log_end   vmlinux EXPORT_SYMBOL
++0xc3577d50    dev_set_name    vmlinux EXPORT_SYMBOL_GPL
++0x6d40a921    need_ipv4_conntrack     vmlinux EXPORT_SYMBOL_GPL
++0x6b98f5bd    __sk_dst_check  vmlinux EXPORT_SYMBOL
++0x003ed69a    __kfifo_dma_in_prepare  vmlinux EXPORT_SYMBOL
++0xd27b25dd    blk_check_plugged       vmlinux EXPORT_SYMBOL
++0x9e093f78    elv_register_queue      vmlinux EXPORT_SYMBOL
++0x716265c7    debugfs_initialized     vmlinux EXPORT_SYMBOL_GPL
++0x8e19dd86    of_platform_populate    vmlinux EXPORT_SYMBOL_GPL
++0x2a4ee199    v4l2_m2m_job_finish     vmlinux EXPORT_SYMBOL
++0x8c62225c    usb_queue_reset_device  vmlinux EXPORT_SYMBOL_GPL
++0x1e837252    drm_mm_scan_add_block   vmlinux EXPORT_SYMBOL
++0x6c9424d9    snd_pcm_lib_preallocate_pages   vmlinux EXPORT_SYMBOL
++0x4c759827    byte_rev_table  vmlinux EXPORT_SYMBOL_GPL
++0xdf7090e0    __elv_add_request       vmlinux EXPORT_SYMBOL
++0x911010cb    skcipher_geniv_init     vmlinux EXPORT_SYMBOL_GPL
++0x9bd700dd    set_bh_page     vmlinux EXPORT_SYMBOL
++0x13a2a2e3    free_user_ns    vmlinux EXPORT_SYMBOL
++0x4fe8770d    usb_interrupt_msg       vmlinux EXPORT_SYMBOL_GPL
++0x0d7dd3fc    pm_generic_runtime_resume       vmlinux EXPORT_SYMBOL_GPL
++0x3df0b6c5    bus_unregister  vmlinux EXPORT_SYMBOL_GPL
++0x131f636c    nf_nat_l4proto_in_range vmlinux EXPORT_SYMBOL_GPL
++0xe6643a60    snd_soc_dpcm_be_can_update      vmlinux EXPORT_SYMBOL_GPL
++0x059c8bf5    snd_soc_dpcm_fe_can_update      vmlinux EXPORT_SYMBOL_GPL
++0xe914e41e    strcpy  vmlinux EXPORT_SYMBOL
++0x27235c89    crypto_destroy_tfm      vmlinux EXPORT_SYMBOL_GPL
++0xe44b1603    sysfs_remove_link_from_group    vmlinux EXPORT_SYMBOL_GPL
++0x1dff6af1    filemap_fault   vmlinux EXPORT_SYMBOL
++0xb1d9aabd    lg_local_unlock_cpu     vmlinux EXPORT_SYMBOL
++0x59d9c8d7    jack_get_data   vmlinux EXPORT_SYMBOL_GPL
++0x7a91726b    clkdev_alloc    vmlinux EXPORT_SYMBOL
++0x6138cad8    nfc_tm_deactivated      vmlinux EXPORT_SYMBOL
++0xe50e65bf    blocking_notifier_chain_register        vmlinux EXPORT_SYMBOL_GPL
++0x9acf72e4    rndis_set_param_medium  vmlinux EXPORT_SYMBOL
++0x677428bf    sdev_enable_disk_events vmlinux EXPORT_SYMBOL
++0x45ef1157    tty_pair_get_tty        vmlinux EXPORT_SYMBOL
++0x4338e523    tty_pair_get_pty        vmlinux EXPORT_SYMBOL
++0x51c0d211    fb_get_buffer_offset    vmlinux EXPORT_SYMBOL
++0xe7f26347    skb_unlink      vmlinux EXPORT_SYMBOL
++0xc3f69ac2    crypto_register_template        vmlinux EXPORT_SYMBOL_GPL
++0x00fe8031    fuse_abort_conn vmlinux EXPORT_SYMBOL_GPL
++0x3dc45692    vm_iomap_memory vmlinux EXPORT_SYMBOL
++0xc41f0516    node_states     vmlinux EXPORT_SYMBOL
++0x6a5fb566    rcu_sched_force_quiescent_state vmlinux EXPORT_SYMBOL_GPL
++0xc89e91fb    irq_setup_alt_chip      vmlinux EXPORT_SYMBOL_GPL
++0xe8a39d68    vb2_ioctl_streamoff     vmlinux EXPORT_SYMBOL_GPL
++0xb2e5ae4a    snd_lookup_minor_data   vmlinux EXPORT_SYMBOL
++0xaafd1f6c    iio_triggered_buffer_setup      vmlinux EXPORT_SYMBOL
++0x4b17b645    of_property_read_u16_array      vmlinux EXPORT_SYMBOL_GPL
++0xdac11bae    of_property_read_u32_array      vmlinux EXPORT_SYMBOL_GPL
++0x5641485b    tty_termios_encode_baud_rate    vmlinux EXPORT_SYMBOL_GPL
++0x85d549dc    s3c_gpio_getcfg vmlinux EXPORT_SYMBOL
++0x1189692c    inet_csk_delete_keepalive_timer vmlinux EXPORT_SYMBOL
++0xbec25473    of_parse_phandle        vmlinux EXPORT_SYMBOL
++0x53f0b470    dev_pm_qos_add_ancestor_request vmlinux EXPORT_SYMBOL_GPL
++0x0ddc826c    drm_fb_helper_set_par   vmlinux EXPORT_SYMBOL
++0x64bb0960    cfg80211_wext_giwmode   vmlinux EXPORT_SYMBOL_GPL
++0xd4cc3fbd    cfg80211_wext_giwname   vmlinux EXPORT_SYMBOL_GPL
++0x8697617d    cfg80211_wext_siwmode   vmlinux EXPORT_SYMBOL_GPL
++0xe3643cca    cfg80211_send_auth_timeout      vmlinux EXPORT_SYMBOL
++0x377db989    xfrm_state_register_afinfo      vmlinux EXPORT_SYMBOL
++0x2cdca56b    usb_register_device_driver      vmlinux EXPORT_SYMBOL_GPL
++0x7f9066b4    subsys_interface_unregister     vmlinux EXPORT_SYMBOL_GPL
++0xfbc8e9a2    regulatory_hint vmlinux EXPORT_SYMBOL
++0xbdf0ff3a    wiphy_rfkill_start_polling      vmlinux EXPORT_SYMBOL
++0x74631c0e    inet_ioctl      vmlinux EXPORT_SYMBOL
++0x5cbe31bd    snd_soc_dapm_mixer_update_power vmlinux EXPORT_SYMBOL_GPL
++0x5a3c2afd    kobject_get_path        vmlinux EXPORT_SYMBOL_GPL
++0xd8ce7e67    clocksource_register    vmlinux EXPORT_SYMBOL
++0x802c194a    of_device_register      vmlinux EXPORT_SYMBOL
++0x0c8c9e99    scsi_show_extd_sense    vmlinux EXPORT_SYMBOL
++0x2155f85c    bt_sock_link    vmlinux EXPORT_SYMBOL
++0x0ccfae80    xt_register_target      vmlinux EXPORT_SYMBOL
++0x6f20960a    full_name_hash  vmlinux EXPORT_SYMBOL
++0xcded9074    phy_drivers_register    vmlinux EXPORT_SYMBOL
++0xae5ba460    ping_prot       vmlinux EXPORT_SYMBOL
++0x814e7730    nf_ct_destroy   vmlinux EXPORT_SYMBOL
++0xe8279caa    nf_unregister_hooks     vmlinux EXPORT_SYMBOL
++0x8810ad5e    crypto_xor      vmlinux EXPORT_SYMBOL_GPL
++0x45bf1ff3    crypto_inc      vmlinux EXPORT_SYMBOL_GPL
++0x5ac71347    wait_for_stable_page    vmlinux EXPORT_SYMBOL_GPL
++0xe07ca631    cpu_bit_bitmap  vmlinux EXPORT_SYMBOL_GPL
++0x9c5bf378    pm_generic_freeze       vmlinux EXPORT_SYMBOL_GPL
++0x50bd1b27    device_create_vargs     vmlinux EXPORT_SYMBOL_GPL
++0x30775773    drm_bl_unregister       vmlinux EXPORT_SYMBOL_GPL
++0xf4f3abb6    tty_port_hangup vmlinux EXPORT_SYMBOL
++0xca0bdf70    framebuffer_release     vmlinux EXPORT_SYMBOL
++0x86743fc9    touch_buffer    vmlinux EXPORT_SYMBOL
++0x5671b6e0    iio_triggered_buffer_predisable vmlinux EXPORT_SYMBOL
++0x2eb9cd44    brcmu_pktq_init drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x77c7a73e    wiphy_apply_custom_regulatory   vmlinux EXPORT_SYMBOL
++0xd796d321    fat_getattr     vmlinux EXPORT_SYMBOL_GPL
++0x41e95f70    fat_setattr     vmlinux EXPORT_SYMBOL_GPL
++0x2750ffee    generic_read_dir        vmlinux EXPORT_SYMBOL
++0x00c3b7ed    dentry_unhash   vmlinux EXPORT_SYMBOL
++0xe007de41    kallsyms_lookup_name    vmlinux EXPORT_SYMBOL_GPL
++0x43f23311    dm_table_get_md vmlinux EXPORT_SYMBOL
++0x9db747a3    usb_hcd_poll_rh_status  vmlinux EXPORT_SYMBOL_GPL
++0xfd1cd45b    dev_pm_qos_hide_flags   vmlinux EXPORT_SYMBOL_GPL
++0xe15b1685    device_find_child       vmlinux EXPORT_SYMBOL_GPL
++0x1a022e5e    truncate_pagecache      vmlinux EXPORT_SYMBOL
++0x26b71fb4    ring_buffer_time_stamp  vmlinux EXPORT_SYMBOL_GPL
++0x4e6a500f    phy_pm_runtime_get      vmlinux EXPORT_SYMBOL_GPL
++0x056bb269    xfrm_ealg_get_byidx     vmlinux EXPORT_SYMBOL_GPL
++0x094585f4    sock_no_shutdown        vmlinux EXPORT_SYMBOL
++0x0a5ea478    __generic_block_fiemap  vmlinux EXPORT_SYMBOL
++0xb1acbcce    rcu_barrier_sched       vmlinux EXPORT_SYMBOL_GPL
++0x3924dd56    try_wait_for_completion vmlinux EXPORT_SYMBOL
++0x8f7014a1    param_set_ulong vmlinux EXPORT_SYMBOL
++0xee2d0fc7    _local_bh_enable        vmlinux EXPORT_SYMBOL
++0x34e8e0a0    of_device_unregister    vmlinux EXPORT_SYMBOL
++0xbed3ee5e    watchdog_register_device        vmlinux EXPORT_SYMBOL_GPL
++0x16244fe5    v4l2_prio_check vmlinux EXPORT_SYMBOL
++0x324a8332    vc_resize       vmlinux EXPORT_SYMBOL
++0xb410d84f    phy_put vmlinux EXPORT_SYMBOL_GPL
++0xa41b1e49    phy_pm_runtime_put_sync vmlinux EXPORT_SYMBOL_GPL
++0xb3d5242c    nf_ct_expect_alloc      vmlinux EXPORT_SYMBOL_GPL
++0xbdfe32cf    sysfs_unmerge_group     vmlinux EXPORT_SYMBOL_GPL
++0xdb04cacc    tracepoint_probe_unregister_noupdate    vmlinux EXPORT_SYMBOL_GPL
++0x481ce6ce    cpu_active_mask vmlinux EXPORT_SYMBOL
++0x78f47a5c    drm_kms_helper_poll_init        vmlinux EXPORT_SYMBOL
++0x62827bec    security_secctx_to_secid        vmlinux EXPORT_SYMBOL
++0xcb97ad8c    bus_find_device_by_name vmlinux EXPORT_SYMBOL_GPL
++0x427dce2d    drm_put_minor   vmlinux EXPORT_SYMBOL
++0xf7b743b5    drm_calc_timestamping_constants vmlinux EXPORT_SYMBOL
++0x62746f06    video_source_unregister vmlinux EXPORT_SYMBOL_GPL
++0xacde6340    inet_peer_xrlim_allow   vmlinux EXPORT_SYMBOL
++0xd4b0b600    nf_ct_attach    vmlinux EXPORT_SYMBOL
++0x3e1314f1    snd_timer_global_free   vmlinux EXPORT_SYMBOL
++0xd37725bb    register_user_hw_breakpoint     vmlinux EXPORT_SYMBOL_GPL
++0x4f741917    devm_phy_put    vmlinux EXPORT_SYMBOL_GPL
++0xe5ed5467    xfrm_policy_walk_init   vmlinux EXPORT_SYMBOL
++0xfd6eefb8    nf_nat_decode_session_hook      vmlinux EXPORT_SYMBOL
++0x82627707    snd_pcm_lib_writev      vmlinux EXPORT_SYMBOL
++0x28b2dd21    textsearch_register     vmlinux EXPORT_SYMBOL
++0x74baf17a    tracing_is_on   vmlinux EXPORT_SYMBOL_GPL
++0x381a798a    setup_max_cpus  vmlinux EXPORT_SYMBOL
++0xf442e8f8    commit_creds    vmlinux EXPORT_SYMBOL
++0xab598227    driver_attach   vmlinux EXPORT_SYMBOL_GPL
++0xa1d5de65    drm_mode_connector_list_update  vmlinux EXPORT_SYMBOL
++0xf3f5690b    __nf_ct_expect_find     vmlinux EXPORT_SYMBOL_GPL
++0xad0413d4    match_hex       vmlinux EXPORT_SYMBOL
++0xbfdbee53    usbnet_generic_cdc_bind vmlinux EXPORT_SYMBOL_GPL
++0x329edb99    platform_device_register        vmlinux EXPORT_SYMBOL_GPL
++0x80d68d3e    fb_register_client      vmlinux EXPORT_SYMBOL
++0x3638b44e    __inet_lookup_listener  vmlinux EXPORT_SYMBOL_GPL
++0x89636597    nf_unregister_sockopt   vmlinux EXPORT_SYMBOL
++0xadac214f    __skb_get_rxhash        vmlinux EXPORT_SYMBOL
++0x10ae54ba    skb_realloc_headroom    vmlinux EXPORT_SYMBOL
++0xdaa5b6fe    generic_pipe_buf_get    vmlinux EXPORT_SYMBOL
++0x461fff7e    generic_pipe_buf_map    vmlinux EXPORT_SYMBOL
++0x36f9cd94    rcu_is_cpu_idle vmlinux EXPORT_SYMBOL
++0x4102e3db    media_entity_find_link  vmlinux EXPORT_SYMBOL_GPL
++0xcd0e7389    platform_device_unregister      vmlinux EXPORT_SYMBOL_GPL
++0xf86dc7d7    serial8250_set_isa_configurator vmlinux EXPORT_SYMBOL
++0xbe1c5d4d    ipv6_find_hdr   vmlinux EXPORT_SYMBOL
++0xc6ed2b40    jbd2_journal_dirty_metadata     vmlinux EXPORT_SYMBOL
++0x77df0847    __set_personality       vmlinux EXPORT_SYMBOL
++0x92c6523d    tty_port_close_end      vmlinux EXPORT_SYMBOL
++0x78843287    blkcipher_walk_done     vmlinux EXPORT_SYMBOL_GPL
++0x96f90809    page_readlink   vmlinux EXPORT_SYMBOL
++0xc7c4f4ed    account_page_writeback  vmlinux EXPORT_SYMBOL
++0xa1edf7f3    drm_core_ioremap_wc     vmlinux EXPORT_SYMBOL
++0x08ad3fc2    register_con_driver     vmlinux EXPORT_SYMBOL
++0x676bbc0f    _set_bit        vmlinux EXPORT_SYMBOL
++0xd46c9ca5    nf_unregister_afinfo    vmlinux EXPORT_SYMBOL_GPL
++0xf5eb86ea    blk_verify_command      vmlinux EXPORT_SYMBOL
++0xc499ae1e    kstrdup vmlinux EXPORT_SYMBOL
++0x2aa1ad41    _raw_write_lock_irq     vmlinux EXPORT_SYMBOL
++0xb5b7345d    freezing_slow_path      vmlinux EXPORT_SYMBOL
++0xe505e34f    mmc_start_bkops vmlinux EXPORT_SYMBOL
++0x1dd571e6    fb_copy_cmap    vmlinux EXPORT_SYMBOL
++0x0d4d7a32    _atomic_dec_and_lock    vmlinux EXPORT_SYMBOL
++0x11c9185c    of_iomap        vmlinux EXPORT_SYMBOL
++0xf918f7de    xfrm_register_km        vmlinux EXPORT_SYMBOL
++0xde4bc28c    ip_mc_dec_group vmlinux EXPORT_SYMBOL
++0x03f12ac0    snd_soc_dapm_mux_update_power   vmlinux EXPORT_SYMBOL_GPL
++0x733c3b54    kasprintf       vmlinux EXPORT_SYMBOL
++0x8aaa8b57    simple_rename   vmlinux EXPORT_SYMBOL
++0x512579ee    vfs_setxattr    vmlinux EXPORT_SYMBOL_GPL
++0x3d8f75d6    vfs_getxattr    vmlinux EXPORT_SYMBOL_GPL
++0xcb7131fb    fb_get_options  vmlinux EXPORT_SYMBOL
++0xd49c7d00    phy_init        vmlinux EXPORT_SYMBOL_GPL
++0xf8c54a02    sock_init_data  vmlinux EXPORT_SYMBOL
++0x1209a558    snd_ctl_free_one        vmlinux EXPORT_SYMBOL
++0xe02eb6d0    ring_buffer_commit_overrun_cpu  vmlinux EXPORT_SYMBOL_GPL
++0x3a536bd7    ring_buffer_read_finish vmlinux EXPORT_SYMBOL_GPL
++0x9c0bd51f    _raw_spin_lock  vmlinux EXPORT_SYMBOL
++0xcf7c760d    mmc_send_ext_csd        vmlinux EXPORT_SYMBOL_GPL
++0x0f7cb7fa    tty_set_termios vmlinux EXPORT_SYMBOL_GPL
++0x86ffe7d1    ip_queue_xmit   vmlinux EXPORT_SYMBOL
++0xc30b3a36    scatterwalk_map vmlinux EXPORT_SYMBOL_GPL
++0x23532c4d    ftrace_print_flags_seq  vmlinux EXPORT_SYMBOL
++0x3500818d    v4l2_fh_open    vmlinux EXPORT_SYMBOL_GPL
++0xadc7d94a    class_dev_iter_init     vmlinux EXPORT_SYMBOL_GPL
++0xb95ec685    km_query        vmlinux EXPORT_SYMBOL
++0xf569d921    inet_release    vmlinux EXPORT_SYMBOL
++0x4251ff78    nf_ct_helper_expectfn_register  vmlinux EXPORT_SYMBOL_GPL
++0xa3f35bf5    rwsem_is_locked vmlinux EXPORT_SYMBOL
++0x518c4113    blk_queue_start_tag     vmlinux EXPORT_SYMBOL
++0x299f45b9    jbd2_journal_force_commit       vmlinux EXPORT_SYMBOL
++0x373db350    kstrtoint       vmlinux EXPORT_SYMBOL
++0xfffad96c    call_srcu       vmlinux EXPORT_SYMBOL_GPL
++0x4806c9d5    drm_connector_init      vmlinux EXPORT_SYMBOL
++0x9fce80db    fb_notifier_call_chain  vmlinux EXPORT_SYMBOL_GPL
++0x856629e7    __tracepoint_rpm_return_int     vmlinux EXPORT_SYMBOL_GPL
++0x8f6cee77    __round_jiffies_relative        vmlinux EXPORT_SYMBOL_GPL
++0xb992cdc2    cpufreq_get_policy      vmlinux EXPORT_SYMBOL
++0x9a7784ef    v4l2_device_put vmlinux EXPORT_SYMBOL_GPL
++0xab2d53fe    wm8994_reg_write        vmlinux EXPORT_SYMBOL_GPL
++0xa7c124ba    inet_frag_maybe_warn_overflow   vmlinux EXPORT_SYMBOL
++0x81cbdbae    inet_twsk_alloc vmlinux EXPORT_SYMBOL_GPL
++0x037a0cba    kfree   vmlinux EXPORT_SYMBOL
++0xfb0c30cd    __rt_mutex_init vmlinux EXPORT_SYMBOL_GPL
++0x578a9e0d    kill_pid_info_as_cred   vmlinux EXPORT_SYMBOL_GPL
++0xa8ca80b5    __serio_register_driver vmlinux EXPORT_SYMBOL
++0x182a39a6    max8997_bulk_read       vmlinux EXPORT_SYMBOL_GPL
++0x2fd9648c    pm_genpd_add_callbacks  vmlinux EXPORT_SYMBOL_GPL
++0xc5c2a452    tty_put_char    vmlinux EXPORT_SYMBOL_GPL
++0x49b60948    xfrm_state_delete       vmlinux EXPORT_SYMBOL
++0x0693c220    nf_register_sockopt     vmlinux EXPORT_SYMBOL
++0x8c9e0cae    sock_kmalloc    vmlinux EXPORT_SYMBOL
++0xb9638db4    snd_pcm_rate_to_rate_bit        vmlinux EXPORT_SYMBOL
++0xf3b3adff    cgroup_load_subsys      vmlinux EXPORT_SYMBOL_GPL
++0x75911fdf    ip_tunnel_get_stats64   vmlinux EXPORT_SYMBOL_GPL
++0xe7d4daac    seq_list_next   vmlinux EXPORT_SYMBOL
++0x2fe252cc    unregister_inet6addr_notifier   vmlinux EXPORT_SYMBOL
++0xa06df9e1    __kfifo_dma_out_finish_r        vmlinux EXPORT_SYMBOL
++0x01e0e788    st_sensors_allocate_trigger     vmlinux EXPORT_SYMBOL
++0xcdd15087    of_irq_map_one  vmlinux EXPORT_SYMBOL_GPL
++0xea97422f    vb2_queue_release       vmlinux EXPORT_SYMBOL_GPL
++0xb37c3615    cfg80211_rx_unexpected_4addr_frame      vmlinux EXPORT_SYMBOL
++0xbc2271b2    ipv6_chk_addr   vmlinux EXPORT_SYMBOL
++0x9e9ab99d    __blkdev_driver_ioctl   vmlinux EXPORT_SYMBOL_GPL
++0x54f3cc64    blk_alloc_queue_node    vmlinux EXPORT_SYMBOL
++0xd20b9da2    iio_buffer_unregister   vmlinux EXPORT_SYMBOL
++0xa8f8abd2    v4l2_ctrl_g_ctrl_int64  vmlinux EXPORT_SYMBOL
++0xc2aa0765    dev_pm_qos_flags        vmlinux EXPORT_SYMBOL_GPL
++0xf5f14859    uart_suspend_port       vmlinux EXPORT_SYMBOL
++0xe7722171    flex_array_free vmlinux EXPORT_SYMBOL
++0xa27aead4    blk_queue_flush vmlinux EXPORT_SYMBOL_GPL
++0x713c83fa    bio_phys_segments       vmlinux EXPORT_SYMBOL
++0xdaa57ec3    totalhigh_pages vmlinux EXPORT_SYMBOL
++0x2a2a7a3b    rndis_set_param_dev     vmlinux EXPORT_SYMBOL
++0x54fd2e8d    scsi_device_resume      vmlinux EXPORT_SYMBOL
++0x7a060e19    ipv6_find_tlv   vmlinux EXPORT_SYMBOL_GPL
++0x8fe6ac1e    neigh_changeaddr        vmlinux EXPORT_SYMBOL
++0xa38c2c00    snd_soc_jack_get_type   vmlinux EXPORT_SYMBOL_GPL
++0x710c73b6    crypto_unregister_notifier      vmlinux EXPORT_SYMBOL_GPL
++0xda0c24cc    invalidate_inode_pages2 vmlinux EXPORT_SYMBOL_GPL
++0x72741f25    trace_vbprintk  vmlinux EXPORT_SYMBOL_GPL
++0xccb0efda    do_unregister_con_driver        vmlinux EXPORT_SYMBOL_GPL
++0xa120d33c    tty_unregister_ldisc    vmlinux EXPORT_SYMBOL
++0xd644f377    tty_standard_install    vmlinux EXPORT_SYMBOL_GPL
++0x31222024    amba_apb_device_add_res vmlinux EXPORT_SYMBOL_GPL
++0xf8299259    cfg80211_michael_mic_failure    vmlinux EXPORT_SYMBOL
++0xbe53b873    ipt_do_table    vmlinux EXPORT_SYMBOL
++0xc96046ab    kmem_cache_destroy      vmlinux EXPORT_SYMBOL
++0x79105e99    add_to_page_cache_locked        vmlinux EXPORT_SYMBOL
++0x4e109192    ring_buffer_entries     vmlinux EXPORT_SYMBOL_GPL
++0x82a5e5e7    led_classdev_register   vmlinux EXPORT_SYMBOL_GPL
++0xd952a550    vb2_ioctl_reqbufs       vmlinux EXPORT_SYMBOL_GPL
++0xcb929a3c    scsi_calculate_bounce_limit     vmlinux EXPORT_SYMBOL
++0x33746f3f    xfrm_prepare_input      vmlinux EXPORT_SYMBOL
++0xd1dc81ae    xt_find_target  vmlinux EXPORT_SYMBOL
++0x92f468ad    drm_mode_object_find    vmlinux EXPORT_SYMBOL
++0x5a268d54    drm_clflush_sg  vmlinux EXPORT_SYMBOL
++0x827cc6a1    pptp_msg_name   vmlinux EXPORT_SYMBOL
++0xd4433787    vm_event_states vmlinux EXPORT_SYMBOL
++0x488b605d    __module_get    vmlinux EXPORT_SYMBOL
++0x081f3afb    complete_all    vmlinux EXPORT_SYMBOL
++0x9bce482f    __release_region        vmlinux EXPORT_SYMBOL
++0xd007f03b    phy_mii_ioctl   vmlinux EXPORT_SYMBOL
++0x5ef79e43    exynos_drm_subdrv_open  vmlinux EXPORT_SYMBOL_GPL
++0x34b60845    nfc_alloc_recv_skb      vmlinux EXPORT_SYMBOL
++0x075af6c0    cfg80211_reg_can_beacon vmlinux EXPORT_SYMBOL
++0x347013de    nla_validate    vmlinux EXPORT_SYMBOL
++0x70f6100f    bdi_register    vmlinux EXPORT_SYMBOL
++0xcf54ea93    async_unregister_domain vmlinux EXPORT_SYMBOL_GPL
++0xb6efaccd    rndis_rm_hdr    vmlinux EXPORT_SYMBOL
++0x5ed040b0    pm_set_vt_switch        vmlinux EXPORT_SYMBOL
++0x3ad0517a    tty_free_termios        vmlinux EXPORT_SYMBOL
++0x5fa643a3    amba_device_alloc       vmlinux EXPORT_SYMBOL_GPL
++0x73abc38f    inet_csk_clear_xmit_timers      vmlinux EXPORT_SYMBOL
++0x52e3e4a5    snd_pcm_hw_param_value  vmlinux EXPORT_SYMBOL
++0x7129e5f8    hex_asc vmlinux EXPORT_SYMBOL
++0xa0973520    fat_time_unix2fat       vmlinux EXPORT_SYMBOL_GPL
++0x522a28d0    mmc_regulator_get_supply        vmlinux EXPORT_SYMBOL_GPL
++0xac84055a    nf_nat_follow_master    vmlinux EXPORT_SYMBOL
++0x2aa0e4fc    strncasecmp     vmlinux EXPORT_SYMBOL
++0x9d5dfdfe    fuse_dev_release        vmlinux EXPORT_SYMBOL_GPL
++0xf54fdd41    default_llseek  vmlinux EXPORT_SYMBOL
++0xebec57c4    ring_buffer_oldest_event_ts     vmlinux EXPORT_SYMBOL_GPL
++0x329318c8    iio_channel_release_all vmlinux EXPORT_SYMBOL_GPL
++0xfc9a70ae    tty_get_pgrp    vmlinux EXPORT_SYMBOL_GPL
++0xdbf66d36    tcp_read_sock   vmlinux EXPORT_SYMBOL
++0xc18db9a3    snd_jack_new    vmlinux EXPORT_SYMBOL
++0x5df2ea54    sdhci_pltfm_free        vmlinux EXPORT_SYMBOL_GPL
++0x137901ef    ip_fragment     vmlinux EXPORT_SYMBOL
++0x815b5dd4    match_octal     vmlinux EXPORT_SYMBOL
++0x6b475280    bio_map_kern    vmlinux EXPORT_SYMBOL
++0x3abac74c    scsi_eh_prep_cmnd       vmlinux EXPORT_SYMBOL
++0xd162929f    tty_port_register_device_attr   vmlinux EXPORT_SYMBOL_GPL
++0x296f9f79    xt_register_targets     vmlinux EXPORT_SYMBOL
++0x27000b29    crc32c  vmlinux EXPORT_SYMBOL
++0x2956cef1    vfs_fsync       vmlinux EXPORT_SYMBOL
++0x18ae03d3    poll_freewait   vmlinux EXPORT_SYMBOL
++0x40c7247c    si_meminfo      vmlinux EXPORT_SYMBOL
++0x0034e52c    kthread_create_on_node  vmlinux EXPORT_SYMBOL
++0xeecb608e    i2c_smbus_write_byte    vmlinux EXPORT_SYMBOL
++0x907ada97    scsi_register_driver    vmlinux EXPORT_SYMBOL
++0x7cc1b7fd    max77693_bulk_read      vmlinux EXPORT_SYMBOL_GPL
++0x3274b08e    hdmi_avi_infoframe_init vmlinux EXPORT_SYMBOL
++0xde8c763d    cpu_v7_set_pte_ext      vmlinux EXPORT_SYMBOL
++0x2294b28a    snd_timer_pause vmlinux EXPORT_SYMBOL
++0x5e95b1cd    current_umask   vmlinux EXPORT_SYMBOL
++0xd2091a52    get_fs_type     vmlinux EXPORT_SYMBOL
++0x94893493    ref_module      vmlinux EXPORT_SYMBOL_GPL
++0x657ca634    iommu_domain_get_attr   vmlinux EXPORT_SYMBOL_GPL
++0x6b758637    iommu_domain_set_attr   vmlinux EXPORT_SYMBOL_GPL
++0xe835dcde    nf_nat_pptp_hook_outbound       vmlinux EXPORT_SYMBOL_GPL
++0x3ac1fef9    drm_mode_legacy_fb_format       vmlinux EXPORT_SYMBOL
++0x7cc88e22    tty_driver_kref_put     vmlinux EXPORT_SYMBOL
++0x24fc46b6    regulator_bulk_free     vmlinux EXPORT_SYMBOL_GPL
++0x776bea60    ip6_tnl_dst_check       vmlinux EXPORT_SYMBOL_GPL
++0x80690fc4    sock_prot_inuse_get     vmlinux EXPORT_SYMBOL_GPL
++0xb8aa9e8f    aead_geniv_init vmlinux EXPORT_SYMBOL_GPL
++0x35bac202    generic_write_end       vmlinux EXPORT_SYMBOL
++0x59e2743e    call_rcu_bh     vmlinux EXPORT_SYMBOL_GPL
++0x639f9176    devm_request_threaded_irq       vmlinux EXPORT_SYMBOL
++0x67955ce6    profile_hits    vmlinux EXPORT_SYMBOL_GPL
++0xa53a0240    usb_wakeup_notification vmlinux EXPORT_SYMBOL_GPL
++0xf5e3c0cf    scsi_host_set_state     vmlinux EXPORT_SYMBOL
++0x31b21f37    nat_t120_hook   vmlinux EXPORT_SYMBOL_GPL
++0xcd083b10    unregister_sound_dsp    vmlinux EXPORT_SYMBOL
++0xda529e9e    blk_start_queue vmlinux EXPORT_SYMBOL
++0xd84ce699    bio_copy_user   vmlinux EXPORT_SYMBOL
++0x7a4497db    kzfree  vmlinux EXPORT_SYMBOL
++0x91bbc6b9    genphy_config_aneg      vmlinux EXPORT_SYMBOL
++0x1c251434    of_mm_gpiochip_add      vmlinux EXPORT_SYMBOL
++0x8e10854d    inet_sk_diag_fill       vmlinux EXPORT_SYMBOL_GPL
++0x07d2ea7a    arpt_unregister_table   vmlinux EXPORT_SYMBOL
++0x2c038769    sk_filter       vmlinux EXPORT_SYMBOL
++0x57e267af    generic_removexattr     vmlinux EXPORT_SYMBOL
++0x643b400e    deactivate_super        vmlinux EXPORT_SYMBOL
++0xcf241a0c    vmap    vmlinux EXPORT_SYMBOL
++0x31f0bb78    __kmap_atomic_idx       vmlinux EXPORT_SYMBOL
++0x4e32f63f    devm_clk_put    vmlinux EXPORT_SYMBOL
++0x77f2c351    v4l2_ctrl_s_ctrl_int64  vmlinux EXPORT_SYMBOL
++0xed9fdd16    gether_setup_name_default       vmlinux EXPORT_SYMBOL
++0x6f572dd2    devm_remove_action      vmlinux EXPORT_SYMBOL_GPL
++0xa8f59416    gpio_direction_output   vmlinux EXPORT_SYMBOL_GPL
+diff --git a/tools/abi-checker/sample/LICENSE b/tools/abi-checker/sample/LICENSE
+new file mode 100644
+index 0000000..63fabc1
+--- /dev/null
++++ b/tools/abi-checker/sample/LICENSE
+@@ -0,0 +1,848 @@
++Copyright (C) 2007-2011 David Zeuthen <zeuthen@gmail.com>
++Copyright (C) 2007-2011 Red Hat, Inc.
++All Rights Reserved.
++
++The source code for the udisks daemon and command-line tools are
++licensed to you under the GNU General Public License. Either version 2
++of the License, or (at your option) any later version.
++
++The source code for the libudisks2 dynamic library is licensed to you
++under the GNU Library General Public License. Either version 2 of the
++License, or (at your option) any later version.
++
++Each file is marked with copyright and licensing headers.
++
++The GPLv2 and LGPLv2 licenses are included below.
++
++-- BEGIN GPLv2+ License ---
++
++                    GNU GENERAL PUBLIC LICENSE
++                       Version 2, June 1991
++
++ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
++ 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++
++ Everyone is permitted to copy and distribute verbatim copies
++ of this license document, but changing it is not allowed.
++
++                            Preamble
++
++  The licenses for most software are designed to take away your
++freedom to share and change it.  By contrast, the GNU General Public
++License is intended to guarantee your freedom to share and change free
++software--to make sure the software is free for all its users.  This
++General Public License applies to most of the Free Software
++Foundation's software and to any other program whose authors commit to
++using it.  (Some other Free Software Foundation software is covered by
++the GNU Library General Public License instead.)  You can apply it to
++your programs, too.
++
++  When we speak of free software, we are referring to freedom, not
++price.  Our General Public Licenses are designed to make sure that you
++have the freedom to distribute copies of free software (and charge for
++this service if you wish), that you receive source code or can get it
++if you want it, that you can change the software or use pieces of it
++in new free programs; and that you know you can do these things.
++
++  To protect your rights, we need to make restrictions that forbid
++anyone to deny you these rights or to ask you to surrender the rights.
++These restrictions translate to certain responsibilities for you if you
++distribute copies of the software, or if you modify it.
++
++  For example, if you distribute copies of such a program, whether
++gratis or for a fee, you must give the recipients all the rights that
++you have.  You must make sure that they, too, receive or can get the
++source code.  And you must show them these terms so they know their
++rights.
++
++  We protect your rights with two steps: (1) copyright the software, and
++(2) offer you this license which gives you legal permission to copy,
++distribute and/or modify the software.
++
++  Also, for each author's protection and ours, we want to make certain
++that everyone understands that there is no warranty for this free
++software.  If the software is modified by someone else and passed on, we
++want its recipients to know that what they have is not the original, so
++that any problems introduced by others will not reflect on the original
++authors' reputations.
++
++  Finally, any free program is threatened constantly by software
++patents.  We wish to avoid the danger that redistributors of a free
++program will individually obtain patent licenses, in effect making the
++program proprietary.  To prevent this, we have made it clear that any
++patent must be licensed for everyone's free use or not licensed at all.
++
++  The precise terms and conditions for copying, distribution and
++modification follow.
++
++                    GNU GENERAL PUBLIC LICENSE
++   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
++
++  0. This License applies to any program or other work which contains
++a notice placed by the copyright holder saying it may be distributed
++under the terms of this General Public License.  The "Program", below,
++refers to any such program or work, and a "work based on the Program"
++means either the Program or any derivative work under copyright law:
++that is to say, a work containing the Program or a portion of it,
++either verbatim or with modifications and/or translated into another
++language.  (Hereinafter, translation is included without limitation in
++the term "modification".)  Each licensee is addressed as "you".
++
++Activities other than copying, distribution and modification are not
++covered by this License; they are outside its scope.  The act of
++running the Program is not restricted, and the output from the Program
++is covered only if its contents constitute a work based on the
++Program (independent of having been made by running the Program).
++Whether that is true depends on what the Program does.
++
++  1. You may copy and distribute verbatim copies of the Program's
++source code as you receive it, in any medium, provided that you
++conspicuously and appropriately publish on each copy an appropriate
++copyright notice and disclaimer of warranty; keep intact all the
++notices that refer to this License and to the absence of any warranty;
++and give any other recipients of the Program a copy of this License
++along with the Program.
++
++You may charge a fee for the physical act of transferring a copy, and
++you may at your option offer warranty protection in exchange for a fee.
++
++  2. You may modify your copy or copies of the Program or any portion
++of it, thus forming a work based on the Program, and copy and
++distribute such modifications or work under the terms of Section 1
++above, provided that you also meet all of these conditions:
++
++    a) You must cause the modified files to carry prominent notices
++    stating that you changed the files and the date of any change.
++
++    b) You must cause any work that you distribute or publish, that in
++    whole or in part contains or is derived from the Program or any
++    part thereof, to be licensed as a whole at no charge to all third
++    parties under the terms of this License.
++
++    c) If the modified program normally reads commands interactively
++    when run, you must cause it, when started running for such
++    interactive use in the most ordinary way, to print or display an
++    announcement including an appropriate copyright notice and a
++    notice that there is no warranty (or else, saying that you provide
++    a warranty) and that users may redistribute the program under
++    these conditions, and telling the user how to view a copy of this
++    License.  (Exception: if the Program itself is interactive but
++    does not normally print such an announcement, your work based on
++    the Program is not required to print an announcement.)
++
++These requirements apply to the modified work as a whole.  If
++identifiable sections of that work are not derived from the Program,
++and can be reasonably considered independent and separate works in
++themselves, then this License, and its terms, do not apply to those
++sections when you distribute them as separate works.  But when you
++distribute the same sections as part of a whole which is a work based
++on the Program, the distribution of the whole must be on the terms of
++this License, whose permissions for other licensees extend to the
++entire whole, and thus to each and every part regardless of who wrote it.
++
++Thus, it is not the intent of this section to claim rights or contest
++your rights to work written entirely by you; rather, the intent is to
++exercise the right to control the distribution of derivative or
++collective works based on the Program.
++
++In addition, mere aggregation of another work not based on the Program
++with the Program (or with a work based on the Program) on a volume of
++a storage or distribution medium does not bring the other work under
++the scope of this License.
++
++  3. You may copy and distribute the Program (or a work based on it,
++under Section 2) in object code or executable form under the terms of
++Sections 1 and 2 above provided that you also do one of the following:
++
++    a) Accompany it with the complete corresponding machine-readable
++    source code, which must be distributed under the terms of Sections
++    1 and 2 above on a medium customarily used for software interchange; or,
++
++    b) Accompany it with a written offer, valid for at least three
++    years, to give any third party, for a charge no more than your
++    cost of physically performing source distribution, a complete
++    machine-readable copy of the corresponding source code, to be
++    distributed under the terms of Sections 1 and 2 above on a medium
++    customarily used for software interchange; or,
++
++    c) Accompany it with the information you received as to the offer
++    to distribute corresponding source code.  (This alternative is
++    allowed only for noncommercial distribution and only if you
++    received the program in object code or executable form with such
++    an offer, in accord with Subsection b above.)
++
++The source code for a work means the preferred form of the work for
++making modifications to it.  For an executable work, complete source
++code means all the source code for all modules it contains, plus any
++associated interface definition files, plus the scripts used to
++control compilation and installation of the executable.  However, as a
++special exception, the source code distributed need not include
++anything that is normally distributed (in either source or binary
++form) with the major components (compiler, kernel, and so on) of the
++operating system on which the executable runs, unless that component
++itself accompanies the executable.
++
++If distribution of executable or object code is made by offering
++access to copy from a designated place, then offering equivalent
++access to copy the source code from the same place counts as
++distribution of the source code, even though third parties are not
++compelled to copy the source along with the object code.
++
++  4. You may not copy, modify, sublicense, or distribute the Program
++except as expressly provided under this License.  Any attempt
++otherwise to copy, modify, sublicense or distribute the Program is
++void, and will automatically terminate your rights under this License.
++However, parties who have received copies, or rights, from you under
++this License will not have their licenses terminated so long as such
++parties remain in full compliance.
++
++  5. You are not required to accept this License, since you have not
++signed it.  However, nothing else grants you permission to modify or
++distribute the Program or its derivative works.  These actions are
++prohibited by law if you do not accept this License.  Therefore, by
++modifying or distributing the Program (or any work based on the
++Program), you indicate your acceptance of this License to do so, and
++all its terms and conditions for copying, distributing or modifying
++the Program or works based on it.
++
++  6. Each time you redistribute the Program (or any work based on the
++Program), the recipient automatically receives a license from the
++original licensor to copy, distribute or modify the Program subject to
++these terms and conditions.  You may not impose any further
++restrictions on the recipients' exercise of the rights granted herein.
++You are not responsible for enforcing compliance by third parties to
++this License.
++
++  7. If, as a consequence of a court judgment or allegation of patent
++infringement or for any other reason (not limited to patent issues),
++conditions are imposed on you (whether by court order, agreement or
++otherwise) that contradict the conditions of this License, they do not
++excuse you from the conditions of this License.  If you cannot
++distribute so as to satisfy simultaneously your obligations under this
++License and any other pertinent obligations, then as a consequence you
++may not distribute the Program at all.  For example, if a patent
++license would not permit royalty-free redistribution of the Program by
++all those who receive copies directly or indirectly through you, then
++the only way you could satisfy both it and this License would be to
++refrain entirely from distribution of the Program.
++
++If any portion of this section is held invalid or unenforceable under
++any particular circumstance, the balance of the section is intended to
++apply and the section as a whole is intended to apply in other
++circumstances.
++
++It is not the purpose of this section to induce you to infringe any
++patents or other property right claims or to contest validity of any
++such claims; this section has the sole purpose of protecting the
++integrity of the free software distribution system, which is
++implemented by public license practices.  Many people have made
++generous contributions to the wide range of software distributed
++through that system in reliance on consistent application of that
++system; it is up to the author/donor to decide if he or she is willing
++to distribute software through any other system and a licensee cannot
++impose that choice.
++
++This section is intended to make thoroughly clear what is believed to
++be a consequence of the rest of this License.
++
++  8. If the distribution and/or use of the Program is restricted in
++certain countries either by patents or by copyrighted interfaces, the
++original copyright holder who places the Program under this License
++may add an explicit geographical distribution limitation excluding
++those countries, so that distribution is permitted only in or among
++countries not thus excluded.  In such case, this License incorporates
++the limitation as if written in the body of this License.
++
++  9. The Free Software Foundation may publish revised and/or new versions
++of the General Public License from time to time.  Such new versions will
++be similar in spirit to the present version, but may differ in detail to
++address new problems or concerns.
++
++Each version is given a distinguishing version number.  If the Program
++specifies a version number of this License which applies to it and "any
++later version", you have the option of following the terms and conditions
++either of that version or of any later version published by the Free
++Software Foundation.  If the Program does not specify a version number of
++this License, you may choose any version ever published by the Free Software
++Foundation.
++
++  10. If you wish to incorporate parts of the Program into other free
++programs whose distribution conditions are different, write to the author
++to ask for permission.  For software which is copyrighted by the Free
++Software Foundation, write to the Free Software Foundation; we sometimes
++make exceptions for this.  Our decision will be guided by the two goals
++of preserving the free status of all derivatives of our free software and
++of promoting the sharing and reuse of software generally.
++
++                            NO WARRANTY
++
++  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
++FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
++OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
++PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
++OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
++TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
++PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
++REPAIR OR CORRECTION.
++
++  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
++WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
++REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
++INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
++OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
++TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
++YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
++PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
++POSSIBILITY OF SUCH DAMAGES.
++
++                     END OF TERMS AND CONDITIONS
++
++            How to Apply These Terms to Your New Programs
++
++  If you develop a new program, and you want it to be of the greatest
++possible use to the public, the best way to achieve this is to make it
++free software which everyone can redistribute and change under these terms.
++
++  To do so, attach the following notices to the program.  It is safest
++to attach them to the start of each source file to most effectively
++convey the exclusion of warranty; and each file should have at least
++the "copyright" line and a pointer to where the full notice is found.
++
++    <one line to give the program's name and a brief idea of what it does.>
++    Copyright (C) <year>  <name of author>
++
++    This program is free software; you can redistribute it and/or modify
++    it under the terms of the GNU General Public License as published by
++    the Free Software Foundation; either version 2 of the License, or
++    (at your option) any later version.
++
++    This program is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++    GNU General Public License for more details.
++
++    You should have received a copy of the GNU General Public License
++    along with this program; if not, write to the Free Software
++    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++
++
++Also add information on how to contact you by electronic and paper mail.
++
++If the program is interactive, make it output a short notice like this
++when it starts in an interactive mode:
++
++    Gnomovision version 69, Copyright (C) year name of author
++    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
++    This is free software, and you are welcome to redistribute it
++    under certain conditions; type `show c' for details.
++
++The hypothetical commands `show w' and `show c' should show the appropriate
++parts of the General Public License.  Of course, the commands you use may
++be called something other than `show w' and `show c'; they could even be
++mouse-clicks or menu items--whatever suits your program.
++
++You should also get your employer (if you work as a programmer) or your
++school, if any, to sign a "copyright disclaimer" for the program, if
++necessary.  Here is a sample; alter the names:
++
++  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
++  `Gnomovision' (which makes passes at compilers) written by James Hacker.
++
++  <signature of Ty Coon>, 1 April 1989
++  Ty Coon, President of Vice
++
++This General Public License does not permit incorporating your program into
++proprietary programs.  If your program is a subroutine library, you may
++consider it more useful to permit linking proprietary applications with the
++library.  If this is what you want to do, use the GNU Library General
++Public License instead of this License.
++
++-- END GPLv2+ License ---
++
++-- BEGIN LGPLv2+ License ---
++
++                  GNU LIBRARY GENERAL PUBLIC LICENSE
++                       Version 2, June 1991
++
++ Copyright (C) 1991 Free Software Foundation, Inc.
++                    59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ Everyone is permitted to copy and distribute verbatim copies
++ of this license document, but changing it is not allowed.
++
++[This is the first released version of the library GPL.  It is
++ numbered 2 because it goes with version 2 of the ordinary GPL.]
++
++                            Preamble
++
++  The licenses for most software are designed to take away your
++freedom to share and change it.  By contrast, the GNU General Public
++Licenses are intended to guarantee your freedom to share and change
++free software--to make sure the software is free for all its users.
++
++  This license, the Library General Public License, applies to some
++specially designated Free Software Foundation software, and to any
++other libraries whose authors decide to use it.  You can use it for
++your libraries, too.
++
++  When we speak of free software, we are referring to freedom, not
++price.  Our General Public Licenses are designed to make sure that you
++have the freedom to distribute copies of free software (and charge for
++this service if you wish), that you receive source code or can get it
++if you want it, that you can change the software or use pieces of it
++in new free programs; and that you know you can do these things.
++
++  To protect your rights, we need to make restrictions that forbid
++anyone to deny you these rights or to ask you to surrender the rights.
++These restrictions translate to certain responsibilities for you if
++you distribute copies of the library, or if you modify it.
++
++  For example, if you distribute copies of the library, whether gratis
++or for a fee, you must give the recipients all the rights that we gave
++you.  You must make sure that they, too, receive or can get the source
++code.  If you link a program with the library, you must provide
++complete object files to the recipients so that they can relink them
++with the library, after making changes to the library and recompiling
++it.  And you must show them these terms so they know their rights.
++
++  Our method of protecting your rights has two steps: (1) copyright
++the library, and (2) offer you this license which gives you legal
++permission to copy, distribute and/or modify the library.
++
++  Also, for each distributor's protection, we want to make certain
++that everyone understands that there is no warranty for this free
++library.  If the library is modified by someone else and passed on, we
++want its recipients to know that what they have is not the original
++version, so that any problems introduced by others will not reflect on
++the original authors' reputations.
++
++  Finally, any free program is threatened constantly by software
++patents.  We wish to avoid the danger that companies distributing free
++software will individually obtain patent licenses, thus in effect
++transforming the program into proprietary software.  To prevent this,
++we have made it clear that any patent must be licensed for everyone's
++free use or not licensed at all.
++
++  Most GNU software, including some libraries, is covered by the ordinary
++GNU General Public License, which was designed for utility programs.  This
++license, the GNU Library General Public License, applies to certain
++designated libraries.  This license is quite different from the ordinary
++one; be sure to read it in full, and don't assume that anything in it is
++the same as in the ordinary license.
++
++  The reason we have a separate public license for some libraries is that
++they blur the distinction we usually make between modifying or adding to a
++program and simply using it.  Linking a program with a library, without
++changing the library, is in some sense simply using the library, and is
++analogous to running a utility program or application program.  However, in
++a textual and legal sense, the linked executable is a combined work, a
++derivative of the original library, and the ordinary General Public License
++treats it as such.
++
++  Because of this blurred distinction, using the ordinary General
++Public License for libraries did not effectively promote software
++sharing, because most developers did not use the libraries.  We
++concluded that weaker conditions might promote sharing better.
++
++  However, unrestricted linking of non-free programs would deprive the
++users of those programs of all benefit from the free status of the
++libraries themselves.  This Library General Public License is intended to
++permit developers of non-free programs to use free libraries, while
++preserving your freedom as a user of such programs to change the free
++libraries that are incorporated in them.  (We have not seen how to achieve
++this as regards changes in header files, but we have achieved it as regards
++changes in the actual functions of the Library.)  The hope is that this
++will lead to faster development of free libraries.
++
++  The precise terms and conditions for copying, distribution and
++modification follow.  Pay close attention to the difference between a
++"work based on the library" and a "work that uses the library".  The
++former contains code derived from the library, while the latter only
++works together with the library.
++
++  Note that it is possible for a library to be covered by the ordinary
++General Public License rather than by this special one.
++
++                  GNU LIBRARY GENERAL PUBLIC LICENSE
++   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
++
++  0. This License Agreement applies to any software library which
++contains a notice placed by the copyright holder or other authorized
++party saying it may be distributed under the terms of this Library
++General Public License (also called "this License").  Each licensee is
++addressed as "you".
++
++  A "library" means a collection of software functions and/or data
++prepared so as to be conveniently linked with application programs
++(which use some of those functions and data) to form executables.
++
++  The "Library", below, refers to any such software library or work
++which has been distributed under these terms.  A "work based on the
++Library" means either the Library or any derivative work under
++copyright law: that is to say, a work containing the Library or a
++portion of it, either verbatim or with modifications and/or translated
++straightforwardly into another language.  (Hereinafter, translation is
++included without limitation in the term "modification".)
++
++  "Source code" for a work means the preferred form of the work for
++making modifications to it.  For a library, complete source code means
++all the source code for all modules it contains, plus any associated
++interface definition files, plus the scripts used to control compilation
++and installation of the library.
++
++  Activities other than copying, distribution and modification are not
++covered by this License; they are outside its scope.  The act of
++running a program using the Library is not restricted, and output from
++such a program is covered only if its contents constitute a work based
++on the Library (independent of the use of the Library in a tool for
++writing it).  Whether that is true depends on what the Library does
++and what the program that uses the Library does.
++
++  1. You may copy and distribute verbatim copies of the Library's
++complete source code as you receive it, in any medium, provided that
++you conspicuously and appropriately publish on each copy an
++appropriate copyright notice and disclaimer of warranty; keep intact
++all the notices that refer to this License and to the absence of any
++warranty; and distribute a copy of this License along with the
++Library.
++
++  You may charge a fee for the physical act of transferring a copy,
++and you may at your option offer warranty protection in exchange for a
++fee.
++
++  2. You may modify your copy or copies of the Library or any portion
++of it, thus forming a work based on the Library, and copy and
++distribute such modifications or work under the terms of Section 1
++above, provided that you also meet all of these conditions:
++
++    a) The modified work must itself be a software library.
++
++    b) You must cause the files modified to carry prominent notices
++    stating that you changed the files and the date of any change.
++
++    c) You must cause the whole of the work to be licensed at no
++    charge to all third parties under the terms of this License.
++
++    d) If a facility in the modified Library refers to a function or a
++    table of data to be supplied by an application program that uses
++    the facility, other than as an argument passed when the facility
++    is invoked, then you must make a good faith effort to ensure that,
++    in the event an application does not supply such function or
++    table, the facility still operates, and performs whatever part of
++    its purpose remains meaningful.
++
++    (For example, a function in a library to compute square roots has
++    a purpose that is entirely well-defined independent of the
++    application.  Therefore, Subsection 2d requires that any
++    application-supplied function or table used by this function must
++    be optional: if the application does not supply it, the square
++    root function must still compute square roots.)
++
++These requirements apply to the modified work as a whole.  If
++identifiable sections of that work are not derived from the Library,
++and can be reasonably considered independent and separate works in
++themselves, then this License, and its terms, do not apply to those
++sections when you distribute them as separate works.  But when you
++distribute the same sections as part of a whole which is a work based
++on the Library, the distribution of the whole must be on the terms of
++this License, whose permissions for other licensees extend to the
++entire whole, and thus to each and every part regardless of who wrote
++it.
++
++Thus, it is not the intent of this section to claim rights or contest
++your rights to work written entirely by you; rather, the intent is to
++exercise the right to control the distribution of derivative or
++collective works based on the Library.
++
++In addition, mere aggregation of another work not based on the Library
++with the Library (or with a work based on the Library) on a volume of
++a storage or distribution medium does not bring the other work under
++the scope of this License.
++
++  3. You may opt to apply the terms of the ordinary GNU General Public
++License instead of this License to a given copy of the Library.  To do
++this, you must alter all the notices that refer to this License, so
++that they refer to the ordinary GNU General Public License, version 2,
++instead of to this License.  (If a newer version than version 2 of the
++ordinary GNU General Public License has appeared, then you can specify
++that version instead if you wish.)  Do not make any other change in
++these notices.
++
++  Once this change is made in a given copy, it is irreversible for
++that copy, so the ordinary GNU General Public License applies to all
++subsequent copies and derivative works made from that copy.
++
++  This option is useful when you wish to copy part of the code of
++the Library into a program that is not a library.
++
++  4. You may copy and distribute the Library (or a portion or
++derivative of it, under Section 2) in object code or executable form
++under the terms of Sections 1 and 2 above provided that you accompany
++it with the complete corresponding machine-readable source code, which
++must be distributed under the terms of Sections 1 and 2 above on a
++medium customarily used for software interchange.
++
++  If distribution of object code is made by offering access to copy
++from a designated place, then offering equivalent access to copy the
++source code from the same place satisfies the requirement to
++distribute the source code, even though third parties are not
++compelled to copy the source along with the object code.
++
++  5. A program that contains no derivative of any portion of the
++Library, but is designed to work with the Library by being compiled or
++linked with it, is called a "work that uses the Library".  Such a
++work, in isolation, is not a derivative work of the Library, and
++therefore falls outside the scope of this License.
++
++  However, linking a "work that uses the Library" with the Library
++creates an executable that is a derivative of the Library (because it
++contains portions of the Library), rather than a "work that uses the
++library".  The executable is therefore covered by this License.
++Section 6 states terms for distribution of such executables.
++
++  When a "work that uses the Library" uses material from a header file
++that is part of the Library, the object code for the work may be a
++derivative work of the Library even though the source code is not.
++Whether this is true is especially significant if the work can be
++linked without the Library, or if the work is itself a library.  The
++threshold for this to be true is not precisely defined by law.
++
++  If such an object file uses only numerical parameters, data
++structure layouts and accessors, and small macros and small inline
++functions (ten lines or less in length), then the use of the object
++file is unrestricted, regardless of whether it is legally a derivative
++work.  (Executables containing this object code plus portions of the
++Library will still fall under Section 6.)
++
++  Otherwise, if the work is a derivative of the Library, you may
++distribute the object code for the work under the terms of Section 6.
++Any executables containing that work also fall under Section 6,
++whether or not they are linked directly with the Library itself.
++
++  6. As an exception to the Sections above, you may also compile or
++link a "work that uses the Library" with the Library to produce a
++work containing portions of the Library, and distribute that work
++under terms of your choice, provided that the terms permit
++modification of the work for the customer's own use and reverse
++engineering for debugging such modifications.
++
++  You must give prominent notice with each copy of the work that the
++Library is used in it and that the Library and its use are covered by
++this License.  You must supply a copy of this License.  If the work
++during execution displays copyright notices, you must include the
++copyright notice for the Library among them, as well as a reference
++directing the user to the copy of this License.  Also, you must do one
++of these things:
++
++    a) Accompany the work with the complete corresponding
++    machine-readable source code for the Library including whatever
++    changes were used in the work (which must be distributed under
++    Sections 1 and 2 above); and, if the work is an executable linked
++    with the Library, with the complete machine-readable "work that
++    uses the Library", as object code and/or source code, so that the
++    user can modify the Library and then relink to produce a modified
++    executable containing the modified Library.  (It is understood
++    that the user who changes the contents of definitions files in the
++    Library will not necessarily be able to recompile the application
++    to use the modified definitions.)
++
++    b) Accompany the work with a written offer, valid for at
++    least three years, to give the same user the materials
++    specified in Subsection 6a, above, for a charge no more
++    than the cost of performing this distribution.
++
++    c) If distribution of the work is made by offering access to copy
++    from a designated place, offer equivalent access to copy the above
++    specified materials from the same place.
++
++    d) Verify that the user has already received a copy of these
++    materials or that you have already sent this user a copy.
++
++  For an executable, the required form of the "work that uses the
++Library" must include any data and utility programs needed for
++reproducing the executable from it.  However, as a special exception,
++the source code distributed need not include anything that is normally
++distributed (in either source or binary form) with the major
++components (compiler, kernel, and so on) of the operating system on
++which the executable runs, unless that component itself accompanies
++the executable.
++
++  It may happen that this requirement contradicts the license
++restrictions of other proprietary libraries that do not normally
++accompany the operating system.  Such a contradiction means you cannot
++use both them and the Library together in an executable that you
++distribute.
++
++  7. You may place library facilities that are a work based on the
++Library side-by-side in a single library together with other library
++facilities not covered by this License, and distribute such a combined
++library, provided that the separate distribution of the work based on
++the Library and of the other library facilities is otherwise
++permitted, and provided that you do these two things:
++
++    a) Accompany the combined library with a copy of the same work
++    based on the Library, uncombined with any other library
++    facilities.  This must be distributed under the terms of the
++    Sections above.
++
++    b) Give prominent notice with the combined library of the fact
++    that part of it is a work based on the Library, and explaining
++    where to find the accompanying uncombined form of the same work.
++
++  8. You may not copy, modify, sublicense, link with, or distribute
++the Library except as expressly provided under this License.  Any
++attempt otherwise to copy, modify, sublicense, link with, or
++distribute the Library is void, and will automatically terminate your
++rights under this License.  However, parties who have received copies,
++or rights, from you under this License will not have their licenses
++terminated so long as such parties remain in full compliance.
++
++  9. You are not required to accept this License, since you have not
++signed it.  However, nothing else grants you permission to modify or
++distribute the Library or its derivative works.  These actions are
++prohibited by law if you do not accept this License.  Therefore, by
++modifying or distributing the Library (or any work based on the
++Library), you indicate your acceptance of this License to do so, and
++all its terms and conditions for copying, distributing or modifying
++the Library or works based on it.
++
++  10. Each time you redistribute the Library (or any work based on the
++Library), the recipient automatically receives a license from the
++original licensor to copy, distribute, link with or modify the Library
++subject to these terms and conditions.  You may not impose any further
++restrictions on the recipients' exercise of the rights granted herein.
++You are not responsible for enforcing compliance by third parties to
++this License.
++
++  11. If, as a consequence of a court judgment or allegation of patent
++infringement or for any other reason (not limited to patent issues),
++conditions are imposed on you (whether by court order, agreement or
++otherwise) that contradict the conditions of this License, they do not
++excuse you from the conditions of this License.  If you cannot
++distribute so as to satisfy simultaneously your obligations under this
++License and any other pertinent obligations, then as a consequence you
++may not distribute the Library at all.  For example, if a patent
++license would not permit royalty-free redistribution of the Library by
++all those who receive copies directly or indirectly through you, then
++the only way you could satisfy both it and this License would be to
++refrain entirely from distribution of the Library.
++
++If any portion of this section is held invalid or unenforceable under any
++particular circumstance, the balance of the section is intended to apply,
++and the section as a whole is intended to apply in other circumstances.
++
++It is not the purpose of this section to induce you to infringe any
++patents or other property right claims or to contest validity of any
++such claims; this section has the sole purpose of protecting the
++integrity of the free software distribution system which is
++implemented by public license practices.  Many people have made
++generous contributions to the wide range of software distributed
++through that system in reliance on consistent application of that
++system; it is up to the author/donor to decide if he or she is willing
++to distribute software through any other system and a licensee cannot
++impose that choice.
++
++This section is intended to make thoroughly clear what is believed to
++be a consequence of the rest of this License.
++
++  12. If the distribution and/or use of the Library is restricted in
++certain countries either by patents or by copyrighted interfaces, the
++original copyright holder who places the Library under this License may add
++an explicit geographical distribution limitation excluding those countries,
++so that distribution is permitted only in or among countries not thus
++excluded.  In such case, this License incorporates the limitation as if
++written in the body of this License.
++
++  13. The Free Software Foundation may publish revised and/or new
++versions of the Library General Public License from time to time.
++Such new versions will be similar in spirit to the present version,
++but may differ in detail to address new problems or concerns.
++
++Each version is given a distinguishing version number.  If the Library
++specifies a version number of this License which applies to it and
++"any later version", you have the option of following the terms and
++conditions either of that version or of any later version published by
++the Free Software Foundation.  If the Library does not specify a
++license version number, you may choose any version ever published by
++the Free Software Foundation.
++
++  14. If you wish to incorporate parts of the Library into other free
++programs whose distribution conditions are incompatible with these,
++write to the author to ask for permission.  For software which is
++copyrighted by the Free Software Foundation, write to the Free
++Software Foundation; we sometimes make exceptions for this.  Our
++decision will be guided by the two goals of preserving the free status
++of all derivatives of our free software and of promoting the sharing
++and reuse of software generally.
++
++                            NO WARRANTY
++
++  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
++WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
++EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
++OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
++KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
++IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
++LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
++THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
++
++  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
++WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
++AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
++FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
++CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
++LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
++RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
++FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
++SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
++DAMAGES.
++
++                     END OF TERMS AND CONDITIONS
++
++           How to Apply These Terms to Your New Libraries
++
++  If you develop a new library, and you want it to be of the greatest
++possible use to the public, we recommend making it free software that
++everyone can redistribute and change.  You can do so by permitting
++redistribution under these terms (or, alternatively, under the terms of the
++ordinary General Public License).
++
++  To apply these terms, attach the following notices to the library.  It is
++safest to attach them to the start of each source file to most effectively
++convey the exclusion of warranty; and each file should have at least the
++"copyright" line and a pointer to where the full notice is found.
++
++    <one line to give the library's name and a brief idea of what it does.>
++    Copyright (C) <year>  <name of author>
++
++    This library is free software; you can redistribute it and/or
++    modify it under the terms of the GNU Library General Public
++    License as published by the Free Software Foundation; either
++    version 2 of the License, or (at your option) any later version.
++
++    This library 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
++    Library General Public License for more details.
++
++    You should have received a copy of the GNU Library General Public
++    License along with this library; if not, write to the
++    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++    Boston, MA  02111-1307  USA.
++
++Also add information on how to contact you by electronic and paper mail.
++
++You should also get your employer (if you work as a programmer) or your
++school, if any, to sign a "copyright disclaimer" for the library, if
++necessary.  Here is a sample; alter the names:
++
++  Yoyodyne, Inc., hereby disclaims all copyright interest in the
++  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
++
++  <signature of Ty Coon>, 1 April 1990
++  Ty Coon, President of Vice
++
++That's all there is to it!
++
++-- END LGPLv2+ License ---
+diff --git a/tools/abi-checker/sample/Makefile b/tools/abi-checker/sample/Makefile
+new file mode 100644
+index 0000000..4759f3c
+--- /dev/null
++++ b/tools/abi-checker/sample/Makefile
+@@ -0,0 +1,12 @@
++obj-m = sample_module.o
++
++all:
++      make -C /usr/src/linux-kernel-build-3.10.19-tizen_defconfig.1 M=$(PWD) modules
++
++install:
++      make -C /usr/src/linux-kernel-build-3.10.19-tizen_defconfig.1 M=$(PWD) modules_install
++
++clean:
++      make -C /usr/src/linux-kernel-build-3.10.19-tizen_defconfig.1 M=$(PWD) clean
++      
++
+diff --git a/tools/abi-checker/sample/packaging/sample-module.spec.txt b/tools/abi-checker/sample/packaging/sample-module.spec.txt
+new file mode 100644
+index 0000000..bca8416
+--- /dev/null
++++ b/tools/abi-checker/sample/packaging/sample-module.spec.txt
+@@ -0,0 +1,53 @@
++%define debug_package %{nil}
++Name:       sample-module
++Summary:    Test sample kernel module 2
++Version:    0.1.0
++Release:    1
++Group:      Base/Device Management
++License:    GPL-2.0
++Source0:    %{name}-%{version}.tar.gz
++BuildRequires: linux-kernel-sources
++BuildRequires: linux-kernel-headers
++BuildRequires: linux-kernel-build
++BuildRequires: linux-kernel-abi-tools
++BuildRequires: linux-kernel-abi-devel
++
++Requires: linux-kernel-uImage
++
++%package source
++Summary: Debug sample-kernel-module-2
++Group: Base/Device Management
++
++%description source
++Debug and sources sample-kernel-module-2
++
++%description
++TIZEN simple kernel module.  
++
++%prep
++%setup -q
++
++%build
++make %{?jobs:-j%jobs}
++# Create ABI/API dump fingerprint file
++/usr/local/bin/abi-module-dumper sample_module_2.ko sample_module_2.abidump
++
++%install
++mkdir -p %{_builddir}/lib/modules/3.10.19-tizen_defconfig.1/
++make INSTALL_MOD_PATH=%{buildroot}  install
++cp sample_module_2.abidump %{buildroot}/lib/modules/3.10.19-tizen_defconfig.1/extra/
++
++%post
++# list comptible kerel ABI/API versions
++/usr/local/bin/abi-module-kernels-list /lib/modules/3.10.19-tizen_defconfig.1/extra/sample_module_2.abidump
++
++# Test module ABI/API with the kernel ABI/API
++/usr/local/bin/abi-module-checker /lib/modules/3.10.19-tizen_defconfig.1/extra/sample_module_2.abidump
++
++%files
++/lib/modules/3.10.19-tizen_defconfig.1/extra/
++%license LICENSE
++
++%files source
++/usr/src/debug/sample-kernel-module-2-0.1.0/sample_module_2.c
++/usr/src/debug/sample-kernel-module-2-0.1.0/sample_module_2.mod.c
+diff --git a/tools/abi-checker/sample/sample_module.c b/tools/abi-checker/sample/sample_module.c
+new file mode 100644
+index 0000000..b95a7af
+--- /dev/null
++++ b/tools/abi-checker/sample/sample_module.c
+@@ -0,0 +1,107 @@
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <asm/uaccess.h>
++#include <linux/init.h>
++#include <linux/fs.h>
++
++#define DEVICE_NAME "sample_module"
++#define TEST_MSG_BUFF_LEN     1024
++
++extern int snd_timer_pause;
++
++static unsigned int majorNumber = 0;
++
++static char message[TEST_MSG_BUFF_LEN + 1];
++
++static ssize_t device_write(struct file *filp, const char *buff, size_t len, loff_t *off)
++{
++      printk(KERN_ALERT "Empty write operation. %d\n", snd_timer_pause);
++      return 0;
++}
++
++static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t * offset)
++{
++      int bytes_read = 0;
++
++      /*
++       * Copy message
++       */
++      for(bytes_read = 0; bytes_read < (length - 1) && bytes_read < TEST_MSG_BUFF_LEN; bytes_read ++)
++              put_user(message[bytes_read], buffer + bytes_read );
++      put_user('\0', buffer + bytes_read );
++
++      return bytes_read + 1;
++}
++
++static int device_open(struct inode *inode, struct file *file)
++{
++      static int counter = 0;
++
++      printk( "Open device, count = %d\n", counter++ );
++
++      try_module_get( THIS_MODULE );
++      return 0;
++}
++
++static int device_release(struct inode *inode, struct file *file)
++{
++      printk("Release device\n");
++
++      module_put( THIS_MODULE );
++      return 0;
++}
++
++struct file_operations fileOperations =
++{
++      read:    device_read,
++      write:   device_write,
++      open:    device_open,
++      release: device_release
++};
++
++static int __init test_module_init( void )
++{
++      int i;
++      int j;
++
++      printk(KERN_ALERT "Test kernel module 2 - enter\n");
++
++      /*
++       * Init test message
++       */
++      for(i = 0; i < TEST_MSG_BUFF_LEN;)
++      {
++              for(j = 0; j < 10 && i < TEST_MSG_BUFF_LEN; j ++, i ++ )
++              {
++                      message[i] = '0' + j;
++                      message[i + 1] = '\0';
++              }
++      }
++
++      /*
++       * Register device
++       */
++      majorNumber = register_chrdev(0, DEVICE_NAME, &fileOperations);
++      if (majorNumber < 0)
++      {
++                printk(KERN_ALERT "Blad rejestrowania urzadzenia => [%d]\n", majorNumber );
++                return majorNumber;
++      }
++
++      return 0;
++}
++
++static void __exit test_module_exit(void)
++{
++      printk(KERN_ALERT "Test kernel module 2 - exit\n");
++
++      unregister_chrdev(majorNumber, DEVICE_NAME);
++}
++
++module_init(test_module_init);
++module_exit(test_module_exit);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Jacek Pielaszkiewicz");        /* Who wrote this module? */
++MODULE_DESCRIPTION("Sample test kernel module.");     /* What does this module do */
++MODULE_SUPPORTED_DEVICE("sample_test_module_2");
+diff --git a/tools/abi-checker/src/Makefile b/tools/abi-checker/src/Makefile
+new file mode 100644
+index 0000000..b020bc6
+--- /dev/null
++++ b/tools/abi-checker/src/Makefile
+@@ -0,0 +1,31 @@
++PROGRAM = abi-checker
++GCC = gcc
++LDD = gcc
++
++CFLAGS = $(shell pkg-config --cflags glib-2.0 libelf) -I.
++
++LDFLAGS = $(shell pkg-config --libs glib-2.0 libelf)
++
++SRC = kernel_abi_checker.c kernel_abi_checker_elf.c
++
++HEADER = kernel_abi_checker.h
++
++DEST_DIR = /usr/local/bin
++
++OBJECTS = kernel_abi_checker.o kernel_abi_checker_elf.o
++
++all : $(PROGRAM)
++
++.c.o : $(HEADER)
++      $(GCC) -c $(CFLAGS) $< -o $@
++
++$(PROGRAM) : $(OBJECTS)
++      $(LDD) $(OBJECTS) -o $@ $(LDFLAGS)
++
++install :
++      mkdir -p $(DEST_DIR)
++      cp $(PROGRAM) $(DEST_DIR)
++
++clean :
++      rm -f $(PROGRAM)
++      rm -f $(OBJECTS)
+diff --git a/tools/abi-checker/src/abi-module-checker b/tools/abi-checker/src/abi-module-checker
+new file mode 100755
+index 0000000..2666fbd
+--- /dev/null
++++ b/tools/abi-checker/src/abi-module-checker
+@@ -0,0 +1,43 @@
++#!/bin/sh
++
++echo ""
++echo "Module ABI/API checker"
++echo ""
++echo ""
++
++if [ "${#}" != "1"  ]
++then
++      echo ""
++      echo "ERROR: "
++      echo "       Usage: ${0} _module_abi_fingerprint_"
++      echo ""
++      exit 1
++fi
++
++kerne_abi_file="/boot/abi/current"
++
++if [ ! -f "${1}" -o ! -f "${kerne_abi_file}" ]
++then
++      echo ""
++      echo "ERROR: Please check \"${1}\", \"${kerne_abi_file}\" files"
++      echo ""
++      exit 1
++fi
++
++ABI_TOOL_LOCATION="/usr/local/bin"
++ABI_TOOL_NAME="abi-checker"
++ABI_TOOL="${ABI_TOOL_LOCATION}/${ABI_TOOL_NAME}"
++
++if [ -x "${ABI_TOOL}" ]
++then
++      CMD="${ABI_TOOL}"
++elif [ -x "./${ABI_TOOL_NAME}" ]
++then
++      CMD="./${ABI_TOOL_NAME}"
++else
++      CMD="${ABI_TOOL_NAME}"
++fi
++
++"${CMD}" "test-module" "${kerne_abi_file}" "${1}"
++
++exit ${?}
+diff --git a/tools/abi-checker/src/abi-module-dumper b/tools/abi-checker/src/abi-module-dumper
+new file mode 100755
+index 0000000..3af55fb
+--- /dev/null
++++ b/tools/abi-checker/src/abi-module-dumper
+@@ -0,0 +1,51 @@
++#!/bin/sh
++
++echo ""
++echo "Module ABI/API fingerprint file generation"
++echo ""
++echo ""
++
++if [ "${#}" != "2"  ]
++then
++      echo ""
++      echo "ERROR: "
++      echo "       Usage: ${0} _module_ko_file_ _output_file_"
++      echo ""
++      exit 1
++fi
++
++kerne_abi_file="/boot/abi/current"
++
++if [ ! -f "${kerne_abi_file}" ]
++then
++      echo ""
++      echo "ERROR: Please check ${kerne_abi_file} file"
++      echo "       Check if linux-kernel-uImage package is installed in development environment."
++      echo ""
++      exit 1
++fi
++
++if [ ! -f "${1}" ]
++then
++      echo "ERROR: Please check input file ${1}"
++      echo ""
++      exit 1
++fi
++
++ABI_TOOL_LOCATION="/usr/local/bin"
++ABI_TOOL_NAME="abi-checker"
++ABI_TOOL="${ABI_TOOL_LOCATION}/${ABI_TOOL_NAME}"
++
++if [ -x "${ABI_TOOL}" ]
++then
++        CMD="${ABI_TOOL}"
++elif [ -x "./${ABI_TOOL_NAME}" ]
++then
++        CMD="./${ABI_TOOL_NAME}"
++else
++        CMD="${ABI_TOOL_NAME}"
++fi
++
++"${CMD}" "dump-module" "${kerne_abi_file}" "${1}" "${2}"
++
++exit ${?}
+diff --git a/tools/abi-checker/src/abi-module-kernels-list b/tools/abi-checker/src/abi-module-kernels-list
+new file mode 100755
+index 0000000..e07f523
+--- /dev/null
++++ b/tools/abi-checker/src/abi-module-kernels-list
+@@ -0,0 +1,45 @@
++#!/bin/sh
++
++echo ""
++echo "List all comatible kernels."
++echo ""
++
++if [ "${#}" != 1  ]
++then
++      echo ""
++      echo "ERROR: "
++      echo "       Usage: ${0} _module_fingerprint_"
++      echo ""
++      exit 1
++fi
++
++ABI_TOOL_LOCATION="/usr/local/bin"
++ABI_TOOL_NAME="abi-checker"
++ABI_TOOL="${ABI_TOOL_LOCATION}/${ABI_TOOL_NAME}"
++
++if [ -x "${ABI_TOOL}" ]
++then
++        CMD="${ABI_TOOL}"
++elif [ -x "./${ABI_TOOL_NAME}" ]
++then
++        CMD="./${ABI_TOOL_NAME}"
++else
++        CMD="${ABI_TOOL_NAME}"
++fi
++
++#
++# Check all historical abi kernel files
++#
++for file in /boot/abi/abi_*
++do
++      filename=`basename ${file}`
++      version=`echo ${filename} | awk -F _ '{ print $2 }'`
++      abi=`echo ${filename} | awk -F _ '{ print $3 }'`
++
++      "${CMD}" "test-module" "${file}" "${1}" 2> /dev/null > /dev/null
++      if [ "${?}" = "0" ]
++      then
++              echo "        Kernel:${version}, ABI/API:${abi} .... compatible"
++      fi
++done
++
+diff --git a/tools/abi-checker/src/build_api_kernel_checker.sh b/tools/abi-checker/src/build_api_kernel_checker.sh
+new file mode 100755
+index 0000000..52693f8
+--- /dev/null
++++ b/tools/abi-checker/src/build_api_kernel_checker.sh
+@@ -0,0 +1,38 @@
++#!/bin/sh
++
++# Find abi_version file
++ksymver=`find ../../.. -name "Module.symvers"`
++
++ABI_TOOL_LOCATION="/usr/local/bin"
++ABI_TOOL_NAME="abi-checker"
++ABI_TOOL="${ABI_TOOL_LOCATION}/${ABI_TOOL_NAME}"
++
++if [ -x "${ABI_TOOL}" ]
++then
++        CMD="${ABI_TOOL}"
++elif [ -x "./${ABI_TOOL_NAME}" ]
++then
++        CMD="./${ABI_TOOL_NAME}"
++else
++        CMD="${ABI_TOOL_NAME}"
++fi
++
++# compare abi fingerprint file with kernel abi file
++"${CMD}" test-kernel "${ksymver}" "../data/abi_${1}_${2}"
++rc="${?}"
++
++# Test result
++if [ ${rc} != "0" ]
++then
++      echo ""
++      echo "----------------------------------------------------------------------------------------------------------------------------"
++      echo ""
++      echo "The kernel ABI/API has changed. Please update kernel version and add a new tools/abi-checker/data/abi_VERSION_ABIVER file "
++      echo "(example tools/abi-checker/data/abi_${1}_${2} )."
++      echo "The kernel sources build will abort."
++      echo ""
++      echo ""
++      exit 1
++fi
++
++exit 0
+diff --git a/tools/abi-checker/src/kernel_abi_checker.c b/tools/abi-checker/src/kernel_abi_checker.c
+new file mode 100644
+index 0000000..da396e1
+--- /dev/null
++++ b/tools/abi-checker/src/kernel_abi_checker.c
+@@ -0,0 +1,834 @@
++/*
++ * Build command
++ *
++ * gcc `pkg-config --cflags glib-2.0` kernel_abi_checker.c kernel_abi_checker_elf.c -lglib-2.0 -lelf
++ */
++
++#include <stdio.h>
++#include <string.h>
++#include <stdlib.h>
++#include <glib.h>
++
++#include "kernel_abi_checker.h"
++
++/*
++ * Functions write single record into ouptu symver file
++ */
++int writeKernelSymbolsFile( FILE *ptr, char *symbolNameCrc, char *symbolName, char *symbolModule, char *flag )
++{
++      return fprintf( ptr, "%s\t%s\t%s\t%s\n", symbolNameCrc, symbolName, symbolModule, flag );
++}
++
++/*
++ * Function open *symver file
++ */
++FILE *getFile( char *fileName )
++{
++      FILE *fPtr = fopen( fileName, "r" );
++
++      if( fPtr == (FILE *)NULL )
++      {
++              PRINT_ERROR( "Canniot open : %s\n", fileName );
++              return (FILE *)NULL;
++      }
++
++      return fPtr;
++}
++
++FILE *getOutputFile( char *fileName )
++{
++      FILE *fPtr = fopen( fileName, "w" );
++
++      if( fPtr == (FILE *)NULL )
++      {
++              PRINT_ERROR( "Canniot open : %s\n", fileName );
++              return (FILE *)NULL;
++      }
++
++      return fPtr;
++}
++
++void releaseFile( FILE *fptr )
++{
++      if( fptr != (FILE *)NULL )
++              fclose( fptr );
++}
++
++void freeHashElement( gpointer data )
++{
++      free( (void *)data );
++}
++
++/*
++ * Function creates hash table
++ */
++GHashTable *createHashTable( void )
++{
++      return g_hash_table_new_full( g_str_hash, g_str_equal, NULL, freeHashElement );
++}
++
++/*
++ * Function destroy hash table
++ */
++void destroyHashTable( GHashTable *tab )
++{
++      if( tab != (GHashTable *)NULL )
++              g_hash_table_destroy( tab );
++}
++
++/*
++ * Function read i mput file.
++ * Function return single KernelSymbol structure.
++ *
++ * Return (KernelSymbol *)-1 - if errora
++          (KernelSymbol *)NULL - eof
++ *
++ */
++
++KernelSymbol *readFileLine( FILE *fptr )
++{
++      KernelSymbol *symbolPtr = (KernelSymbol *)NULL;
++      char inputLine[_LINE_LENGTH_ + 1];
++      char *crcPtr;
++      char *symNamePtr;
++      char *moduleNamePtr;
++      char *flag;
++      char *ptr;
++      int len;
++      int i;
++
++      memset( inputLine, 0, sizeof( inputLine ) );
++      ptr = fgets( inputLine, _LINE_LENGTH_, fptr );
++      if( ptr == (char *) NULL )
++              return (KernelSymbol *)NULL;
++
++      i = 0;
++
++      /* CRC */
++      crcPtr = inputLine + i;
++      for( ;inputLine[i] != '\0' && inputLine[i] != '\t' && i < _LINE_LENGTH_; i ++ );
++
++      if( i >= _LINE_LENGTH_ )
++      {
++              PRINT_ERROR( "Incorect input record format : \"%s\"\n", inputLine );
++              return (KernelSymbol *)-1;
++      }
++      inputLine[i] = '\0';
++      i++;
++
++      /* Symbol name */
++      symNamePtr = inputLine + i;
++
++      for( ;inputLine[i] != '\0' && inputLine[i] != '\t' && i < _LINE_LENGTH_; i ++ );
++      if( i >= _LINE_LENGTH_ )
++      {
++              PRINT_ERROR( "Incorect input record format : \"%s\"\n", inputLine );
++              return (KernelSymbol *)-1;
++      }
++      inputLine[i] = '\0';
++      i ++;
++
++      /* Module name */
++      moduleNamePtr = inputLine + i;
++
++
++      for( ;inputLine[i] != '\0' && inputLine[i] != '\t' && i < _LINE_LENGTH_; i ++ );
++      if( i >= _LINE_LENGTH_ )
++      {
++              PRINT_ERROR( "Incorect input record format : \"%s\"\n", inputLine );
++              return (KernelSymbol *)-1;
++      }
++      inputLine[i] = '\0';
++      i ++;
++
++      /* Flag */
++      flag = inputLine + i;
++
++
++      len = strlen( flag );
++      flag[len ==  0 ? 0 : len -1] = '\0';
++
++      /* Allocate new KernelSymbol */
++      symbolPtr = (KernelSymbol *)malloc( sizeof( KernelSymbol ) );
++      if( symbolPtr == (KernelSymbol *)NULL )
++              return (KernelSymbol *)-1;
++
++      for( i = 0; moduleNamePtr[i] != '\0' && moduleNamePtr[i] != '\n'; i ++ );
++      moduleNamePtr[i] = '\0';
++
++      /* Polulate output structure */
++      strncpy( symbolPtr -> symbolName, symNamePtr, KERNEL_SYMBOL_NAME_LENGTH );
++      strncpy( symbolPtr -> symbolNameCrc, crcPtr, KERNEL_SYMBOL_NAME_CRC );
++      strncpy( symbolPtr -> symbolModule, moduleNamePtr, KERNEL_SYMBOL_MODULE );
++      strncpy( symbolPtr -> flag, flag, KERNEL_SYMBOL_FLAG );
++      symbolPtr -> status = KERNEL_SYMBOL_STATUS_NO_TESTED;
++
++      /* Return KernModule structure */
++      return symbolPtr;
++}
++
++/*
++ * Function adds single kernel symbol into hashtable.
++ * Functions assumes that hash table is correctlly allocated.
++ *
++ * Returns:
++ * -1 - duplicated key
++ *  0 - success
++ */
++
++int addKernelSymboltoHashBase( void *s, char *key, GHashTable *tab )
++{
++      void *testSym;
++
++      /* Check duplicates */
++      testSym = (void *)g_hash_table_lookup( tab, key );
++      if( testSym != (void *)NULL )
++              return -1;
++
++      /* Add new symbol into hash table */
++      g_hash_table_insert( tab, key, s );
++      return 0;
++}
++
++int addKernelSymboltoHash( KernelSymbol *s, GHashTable *tab )
++{
++      return addKernelSymboltoHashBase( (void *)s, s -> symbolName, tab );
++}
++
++int readFile( FILE *fptr, GHashTable *tab )
++{
++        KernelSymbol *sym = (KernelSymbol *)NULL;
++        while( 1 == 1 )
++        {
++                sym = readFileLine( fptr );
++              if( sym == (KernelSymbol *)NULL )
++              {
++                      /* Koniec pliku */
++                      break;
++              }
++
++              if( sym == (KernelSymbol *)-1 )
++              {
++                      /* Error */
++                      return -1;
++              }
++
++              if( addKernelSymboltoHash( sym, tab ) < 0 )
++              {
++                      /* Error - duplicated value */
++                      return -1;
++              }
++        }
++
++      /* Success */
++      return 0;
++}
++
++GHashTable *procesInputFile( char *name )
++{
++      GHashTable *hashTable = (GHashTable *)NULL;
++      FILE *fptr = (FILE *)NULL;
++
++      /* Open input file */
++      fptr = getFile( name );
++      if( fptr == (FILE *)NULL )
++              return (GHashTable *)NULL;
++
++      /* Create hash table for current symver */
++      hashTable = createHashTable();
++      if( hashTable == (GHashTable *)NULL )
++      {
++              PRINT_ERROR( "Error creating hash table \n" );
++              releaseFile( fptr );
++              return (GHashTable *)NULL;
++      }
++
++      /* Read and create current hash table */
++      if( readFile( fptr, hashTable ) != 0 )
++      {
++              PRINT_ERROR( "Error reading %s\n", name );
++              destroyHashTable( hashTable );
++              releaseFile( fptr );
++              return (GHashTable *)NULL;
++      }
++
++      /* Close input file */
++      releaseFile( fptr );
++
++      return hashTable;
++}
++
++typedef struct _foreachHashData_
++{
++      KernelSymbolStatistics *stat;
++      GHashTable *curr;
++      GHashTable *new;
++} _foreachHashData_;
++
++void calculateStatistics_1( gpointer key_, gpointer value_, gpointer user_data_ )
++{
++      KernelSymbol *value = (KernelSymbol *)value_;
++      _foreachHashData_ *user_data = (_foreachHashData_ *)user_data_;
++      KernelSymbol *newSym;
++
++      /* Update current hash table symbols count */
++      user_data -> stat -> symver_current_count ++;
++
++      /* Search for symbol in new hash table */
++      newSym = (KernelSymbol *)g_hash_table_lookup( user_data -> new, key_ );
++
++      if( newSym == (KernelSymbol *)NULL )
++      {
++              /* Symbol was removed */
++
++              /* Set status */
++              value -> status = KERNEL_SYMBOL_STATUS_REMOVED;
++
++              user_data -> stat -> removed_symbols_count ++;
++              return;
++      }
++
++      newSym -> status = KERNEL_SYMBOL_STATUS_VIEWED;
++
++      if( strcmp( value -> symbolNameCrc, newSym -> symbolNameCrc ) == 0 )
++      {
++              user_data -> stat -> no_changed_symbols_count ++;
++              value -> status = KERNEL_SYMBOL_STATUS_NO_CHANGES;
++      }
++      else
++      {
++              user_data -> stat -> changed_symbols_count ++;
++              value -> status = KERNEL_SYMBOL_STATUS_CHANGED;
++      }
++}
++
++void calculateStatistics_2( gpointer key_, gpointer value_, gpointer user_data_ )
++{
++      KernelSymbol *value = (KernelSymbol *)value_;
++      _foreachHashData_ *user_data = (_foreachHashData_ *)user_data_;
++
++      /* Update current hash table symbols count */
++      user_data -> stat -> symver_new_count ++;
++
++      if( value -> status == KERNEL_SYMBOL_STATUS_NO_TESTED )
++      {
++              user_data -> stat -> new_symbols_count ++;
++              value -> status = KERNEL_SYMBOL_STATUS_NEW;
++      }
++}
++
++void collectStatistics( GHashTable *curr, GHashTable *new, KernelSymbolStatistics *statistics )
++{
++      _foreachHashData_ foreachdata;
++
++      /* Init foreach data */
++      memset( (void *)statistics, 0, sizeof( KernelSymbolStatistics ) );
++      foreachdata.stat = statistics;
++      foreachdata.curr = curr;
++      foreachdata.new = new;
++
++      /* Scan current hash table */
++      g_hash_table_foreach( curr, calculateStatistics_1, (gpointer)&foreachdata );
++
++      /* Scan new hash table */
++      g_hash_table_foreach( new, calculateStatistics_2, (gpointer)&foreachdata );
++}
++
++void reportSymbolsDetails( gpointer key_, gpointer value_, gpointer user_data_ )
++{
++      KernelSymbol *value = (KernelSymbol *)value_;
++
++      switch( *((int *)user_data_) )
++      {
++      case 0 :        /* New */
++              if( value -> status == KERNEL_SYMBOL_STATUS_NEW )
++                      PRINT_INFO_RAW( "\t| NEW     | %40s | %10s | %s\n", value -> symbolName, value -> symbolNameCrc, value -> symbolModule );
++              break;
++
++      case 1 :        /* Changed */
++              if( value -> status == KERNEL_SYMBOL_STATUS_CHANGED )
++                      PRINT_INFO_RAW( "\t| CHANGED | %40s | %10s | %s\n", value -> symbolName, value -> symbolNameCrc, value -> symbolModule );
++              break;
++
++      case 2 :        /* Removed */
++              if( value -> status == KERNEL_SYMBOL_STATUS_REMOVED )
++                      PRINT_INFO_RAW( "\t| REMOVED | %40s | %10s | %s\n", value -> symbolName, value -> symbolNameCrc, value -> symbolModule );
++              break;
++      }
++}
++//[CHANGED]         cfg80211_send_rx_assoc         0x80e54114                  vmlinux
++
++void listChangedSymbols( GHashTable *curr, GHashTable *new, KernelSymbolStatistics *statistics )
++{
++      int mode = 0;
++      int printFooter = 0;
++
++      if( statistics -> new_symbols_count == 0 && statistics -> changed_symbols_count == 0 && statistics -> removed_symbols_count == 0 )
++              return;
++
++      PRINT_INFO_RAW( "\n" );
++
++      PRINT_INFO_RAW( "\tNew symbols in kernel\n" );
++      PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
++      PRINT_INFO_RAW( "\t| Change  |                 Linux kernel symbol name |        CRC | Module name \n" );
++      PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
++
++      if( statistics -> new_symbols_count != 0 && new != (GHashTable *)NULL )
++      {
++              mode = 0;
++              g_hash_table_foreach( new, reportSymbolsDetails, (gpointer)&mode );
++              printFooter = 1;
++      }
++
++      if( statistics -> changed_symbols_count != 0 && curr != (GHashTable *)NULL )
++      {
++              if( statistics -> new_symbols_count != 0 )
++                      PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
++
++              mode = 1;
++              g_hash_table_foreach( curr, reportSymbolsDetails, (gpointer)&mode );
++              printFooter = 1;
++      }
++
++      if( statistics -> removed_symbols_count != 0 && curr != (GHashTable *)NULL )
++      {
++              if( statistics -> new_symbols_count != 0 || statistics -> changed_symbols_count != 0 )
++                      PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
++
++              mode = 2;
++              g_hash_table_foreach( curr, reportSymbolsDetails, (gpointer)&mode );
++              printFooter = 1;
++      }
++
++      if( printFooter == 1 )
++              PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
++}
++
++void reportsStatistics( GHashTable *curr, GHashTable *new, KernelSymbolStatistics *statistics )
++{
++      listChangedSymbols( curr, new, statistics );
++
++      PRINT_INFO_RAW( "\n" );
++      PRINT_INFO_RAW( "\tKernel symbols version statistics \n" );
++      PRINT_INFO_RAW( "\t-------------------------------------------------\n" );
++      PRINT_INFO_RAW( "\tSymbols in actual kernel/module . %d\n", statistics -> symver_current_count );
++      if( new != (GHashTable *)NULL )
++              PRINT_INFO_RAW( "\tSymbols in new kernel/module .... %d\n", statistics -> symver_new_count );
++      PRINT_INFO_RAW( "\tNew symbols ..................... %d\n", statistics -> new_symbols_count );
++      PRINT_INFO_RAW( "\tRemoved symbols ................. %d\n", statistics -> removed_symbols_count );
++      PRINT_INFO_RAW( "\tChanged symbols ................. %d\n", statistics -> changed_symbols_count );
++      PRINT_INFO_RAW( "\tUnchanged symbols ............... %d\n", statistics -> no_changed_symbols_count );
++      PRINT_INFO_RAW( "\n" );
++}
++
++void printUsage( char *progName, int type )
++{
++      switch( type )
++      {
++      case 0 :
++              PRINT_INFO_RAW( "\tUsage: %s test-kernel in_symver_file_1 in_symver_file_2\n", progName );
++              break;
++
++      case 1 :
++              PRINT_INFO_RAW( "\tUsage: %s build-list in_module_symbols_file in_kernel_symver_file outt_module_symver_file\n", progName );
++              break;
++
++      case 2 :
++              PRINT_INFO_RAW( "\tUsage: %s dump-module kernel_symver_file ko_module_file output_module_symver_file\n", progName );
++              break;
++
++      case 4 :
++              PRINT_INFO_RAW( "\tUsage: %s test-module kernel_symver_file ko_module_file \n", progName );
++              break;
++
++      default :
++              PRINT_INFO_RAW( "\tUsage: %s test|build-list file1 file2 [output_file] \n", progName );
++              break;
++      }
++}
++
++/*
++ * Function parses input parameters and return.
++ * Return:
++ *            -1 - error
++ *             0 - test mode  - the program will compare two symver files
++ *             1 - build mode - for given module sybmbols file and kernel symver creates files
++ *                              with list kernel symbols used by the module.
++ */
++int parsInputParameters( int argc, char **argv, char **f1, char **f2, char **f3 )
++{
++      char *toolName = argv[0];
++
++      if( argc < 2 )
++      {
++              printUsage( toolName, -1 );
++              return -1;
++      }
++
++      if( strcmp( argv[1], "test-kernel" ) == 0 )
++      {
++              /* Test mode */
++              if( argc < 4 )
++              {
++                      printUsage( toolName, 0 );
++                      return -1;
++              }
++              *f1 = argv[2];
++              *f2 = argv[3];
++              *f3 = (char *)NULL;
++
++              return 0;
++
++      }
++      else
++      if( strcmp( argv[1], "build-list" ) == 0 )
++      {
++              /* Build mode */
++              if( argc < 5 )
++              {
++                      printUsage( toolName, 1 );
++                      return -1;
++              }
++              *f1 = argv[2];
++              *f2 = argv[3];
++              *f3 = argv[4];
++
++              return 1;
++      }
++      else
++      if( strcmp( argv[1], "dump-module" ) == 0 )
++      {
++              /* Build mode */
++              if( argc < 5 )
++              {
++                      printUsage( toolName, 2 );
++                      return -1;
++              }
++              *f1 = argv[2];
++              *f2 = argv[3];
++              *f3 = argv[4];
++
++              return 2;
++      }
++      else
++      if( strcmp( argv[1], "usage" ) == 0 )
++      {
++              return 3;
++      }
++      else
++      if( strcmp( argv[1], "test-module" ) == 0 )
++      {
++              /* Test mode */
++              if( argc < 4 )
++              {
++                      printUsage( toolName, 4 );
++                      return -1;
++              }
++              *f1 = argv[2];
++              *f2 = argv[3];
++              *f3 = (char *)NULL;
++
++              return 4;
++      }
++
++
++      printUsage( toolName, -1 );
++      return -1;
++}
++
++int testKernel( char *f1, char *f2 )
++{
++      GHashTable *curr_hashTable = (GHashTable *)NULL;
++      GHashTable *new_hashTable = (GHashTable *)NULL;
++      KernelSymbolStatistics statistics;
++
++      /*
++       * ----------------------------------------------
++       * Read current symver file
++       * ----------------------------------------------
++       */
++      curr_hashTable = procesInputFile( f1 );
++      if( curr_hashTable == (GHashTable *)NULL )
++      {
++              PRINT_ERROR( "Error read input \"%s\" file.\n", f1 );
++              return 1;
++      }
++
++      /*
++       * ----------------------------------------------
++       * Read new symver file
++       * ----------------------------------------------
++      */
++      new_hashTable = procesInputFile( f2 );
++      if( new_hashTable == (GHashTable *)NULL )
++      {
++              destroyHashTable( curr_hashTable );
++              PRINT_ERROR( "Error read input \"%s\" file.\n", f2 );
++        return 1;
++      }
++
++      /*
++       * ----------------------------------------------
++       * Compute statistics
++       * ----------------------------------------------
++       */
++      collectStatistics( curr_hashTable, new_hashTable, &statistics );
++
++      /*
++       * ---------------------------------------------
++       * Report changes
++       * ---------------------------------------------
++       */
++      reportsStatistics( curr_hashTable, new_hashTable, &statistics );
++
++      /*
++       * --------------------------------------------
++       * Free hash tables
++       * --------------------------------------------
++       */
++      destroyHashTable( curr_hashTable );
++      destroyHashTable( new_hashTable );
++
++      if( statistics.changed_symbols_count != 0 || statistics.removed_symbols_count != 0 || statistics.new_symbols_count != 0 )
++              return 2;
++
++      return 0;
++}
++
++void collectStatisticsModule( GHashTable *curr, GHashTable *module, KernelSymbolStatistics *statistics )
++{
++      _foreachHashData_ foreachdata;
++
++      /* Init foreach data */
++      memset( (void *)statistics, 0, sizeof( KernelSymbolStatistics ) );
++      foreachdata.stat = statistics;
++      foreachdata.curr = module;
++      foreachdata.new = curr;
++
++      /* Scan current hash table */
++      g_hash_table_foreach( module, calculateStatistics_1, (gpointer)&foreachdata );
++}
++
++
++int testModule( char *f1, char *f2 )
++{
++      GHashTable *curr_hashTable = (GHashTable *)NULL;
++      GHashTable *module_hashTable = (GHashTable *)NULL;
++      KernelSymbolStatistics statistics;
++
++      /*
++       * ----------------------------------------------
++       * Read current symver file
++       * ----------------------------------------------
++       */
++      curr_hashTable = procesInputFile( f1 );
++      if( curr_hashTable == (GHashTable *)NULL )
++      {
++              PRINT_ERROR( "Error read input \"%s\" file.\n", f1 );
++              return 1;
++      }
++
++      /*
++       * ----------------------------------------------
++       * Read module symbols
++       * ----------------------------------------------
++      */
++      module_hashTable = procesInputFile( f2 );
++      if( module_hashTable == (GHashTable *)NULL )
++      {
++              destroyHashTable( curr_hashTable );
++              PRINT_ERROR( "Error read input \"%s\" file.\n", f2 );
++              return 1;
++      }
++
++      /*
++       * ----------------------------------------------
++       * Compute statistics
++       * ----------------------------------------------
++       */
++      collectStatisticsModule( curr_hashTable, module_hashTable, &statistics );
++
++      /*
++       * ---------------------------------------------
++       * Report changes
++       * ---------------------------------------------
++       */
++      reportsStatistics( module_hashTable, (GHashTable *)NULL, &statistics );
++
++      /*
++       * --------------------------------------------
++       * Free hash tables
++       * --------------------------------------------
++       */
++      destroyHashTable( curr_hashTable );
++      destroyHashTable( module_hashTable );
++
++      if( statistics.changed_symbols_count != 0 || statistics.removed_symbols_count != 0 )
++              return 2;
++
++      return 0;
++}
++
++int buildListMode( char *f1, char *f2, char *f3 )
++{
++      GHashTable *curr_hashTable = (GHashTable *)NULL;
++      char inputLine[_LINE_LENGTH_ + 1];
++      FILE *symListFptr = (FILE *)NULL;
++      FILE *outFptr = (FILE *)NULL;
++      KernelSymbol *kSym;
++      int size;
++
++      /*
++       * ----------------------------------------------
++       * Read current symver file
++       * ----------------------------------------------
++       */
++      curr_hashTable = procesInputFile( f1 );
++      if( curr_hashTable == (GHashTable *)NULL )
++      {
++              PRINT_ERROR( "Error read input \"%s\" file.\n", f1 );
++              return 1;
++      }
++
++      /*
++       * Open files
++       */
++      outFptr = getOutputFile( f3 );
++      symListFptr = getFile( f2 );
++
++      if( symListFptr == (FILE *)NULL || outFptr == (FILE *)NULL )
++      {
++              destroyHashTable( curr_hashTable );
++              releaseFile( symListFptr );
++              releaseFile( outFptr );
++              PRINT_ERROR( "Error open files : \"%s\", \"%s\".\n", f2, f3 );
++              return 1;
++      }
++
++      while( fgets( inputLine, _LINE_LENGTH_, symListFptr ) )
++      {
++              size = strlen( inputLine );
++              inputLine[size == 0 ? 0 :size - 1] = '\0';
++
++              /* Search for symbol in new hash table */
++              kSym = (KernelSymbol *)g_hash_table_lookup( curr_hashTable, inputLine );
++
++              if( kSym != (KernelSymbol *)NULL )
++                      writeKernelSymbolsFile( outFptr, kSym -> symbolNameCrc, kSym -> symbolName, kSym -> symbolModule, kSym -> flag );
++      }
++
++      destroyHashTable( curr_hashTable );
++      releaseFile( symListFptr );
++      releaseFile( outFptr );
++
++      return 0;
++}
++
++int callDumpModuleSymbols( char *f1, char *f2, char *f3 )
++{
++      GHashTable *curr_hashTable = (GHashTable *)NULL;
++      GHashTable *module_hashTable = (GHashTable *)NULL;
++
++      /*
++       * ----------------------------------------------
++       * Read current symver file
++       * ----------------------------------------------
++       */
++      curr_hashTable = procesInputFile( f1 );
++      if( curr_hashTable == (GHashTable *)NULL )
++      {
++              PRINT_ERROR( "Error read input \"%s\" file.\n", f1 );
++              return 1;
++      }
++
++      /*
++       * ----------------------------------------------
++       * Read kernel module *.ko file
++       * ----------------------------------------------
++       */
++      module_hashTable = readEfl( f2 );
++      if( module_hashTable == (GHashTable *)NULL )
++      {
++              PRINT_ERROR( "Error read input \"%s\" file.\n", f2 );
++              destroyHashTable( curr_hashTable );
++              return 1;
++      }
++
++      /*
++       * Dump module symbols into output file
++       */
++      if( dumpModuleSymbols( f3, module_hashTable, curr_hashTable ) < 0 )
++      {
++              PRINT_ERROR( "Error creating dump file \"%s\"\n", f3 );
++              destroyHashTable( curr_hashTable );
++              return 1;
++      }
++
++      /*
++       * Free hash tables
++       */
++      destroyHashTable( module_hashTable );
++      destroyHashTable( curr_hashTable );
++
++      return 0;
++}
++
++int printUsageInfo( char *f1 )
++{
++      PRINT_INFO_RAW( "\n" );
++      PRINT_INFO_RAW( "\tProgram usage\n" );
++      PRINT_INFO_RAW( "\t-----------------------------------------------\n" );
++      PRINT_INFO_RAW( "\n" );
++      printUsage( f1, 0 );
++      printUsage( f1, 1 );
++      printUsage( f1, 2 );
++
++      return 0;
++}
++
++int main(int argc, char** argv)
++{
++      char *f1 = (char *)NULL;
++      char *f2 = (char *)NULL;
++      char *f3 = (char *)NULL;
++      int rc = -1;
++
++      int mode = parsInputParameters( argc, argv, &f1, &f2, &f3 );
++
++      switch( mode )
++      {
++      case 0 :
++              rc = testKernel( f1, f2 );
++              break;
++
++      case 1 :
++              rc = buildListMode( f1, f2, f3 );
++              break;
++
++      case 2 :
++              rc = callDumpModuleSymbols( f1, f2, f3 );
++              break;
++
++      case 3 :
++              rc = printUsageInfo( argv[0] );
++              break;
++
++      case 4 :
++              rc = testModule( f1, f2 );
++              break;
++      }
++
++      PRINT_INFO_RAW( "\n" );
++
++      if( rc == 2 )
++              PRINT_INFO_RAW( "\tChanges !!!\n" );
++      else
++      if( rc == 1 )
++              PRINT_INFO_RAW( "\tError !!!\n" );
++      else
++              PRINT_INFO_RAW( "\tDone\n" );
++
++      PRINT_INFO_RAW( "\n" );
++
++      return ( rc != 0 ) ? 1 : 0;
++}
+diff --git a/tools/abi-checker/src/kernel_abi_checker.h b/tools/abi-checker/src/kernel_abi_checker.h
+new file mode 100644
+index 0000000..8df231e
+--- /dev/null
++++ b/tools/abi-checker/src/kernel_abi_checker.h
+@@ -0,0 +1,62 @@
++#ifndef _kernel_abi_checker_h_
++#define _kernel_abi_checker_h_
++
++#include <stdio.h>
++#include <glib.h>
++
++/*
++ * Definitions
++ */
++#define KERNEL_SYMBOL_NAME_LENGTH     64
++#define KERNEL_SYMBOL_NAME_CRC                32
++#define KERNEL_SYMBOL_MODULE          256
++#define KERNEL_SYMBOL_FLAG                    256
++
++#define KERNEL_SYMBOL_STATUS_NO_TESTED        0
++#define KERNEL_SYMBOL_STATUS_NO_CHANGES       1
++#define KERNEL_SYMBOL_STATUS_NEW              2
++#define KERNEL_SYMBOL_STATUS_REMOVED  3
++#define KERNEL_SYMBOL_STATUS_CHANGED  4
++#define KERNEL_SYMBOL_STATUS_VIEWED           5
++
++#define _LINE_LENGTH_ 4096
++
++/*
++ * Data types
++ */
++typedef struct KernelSymbol
++{
++      char symbolName[KERNEL_SYMBOL_NAME_LENGTH + 1];
++      char symbolNameCrc[KERNEL_SYMBOL_NAME_CRC + 1];
++      char symbolModule[KERNEL_SYMBOL_MODULE + 1];
++      char flag[KERNEL_SYMBOL_FLAG + 1];
++      int status;
++
++} KernelSymbol;
++
++typedef struct KernelSymbolStatistics
++{
++      int symver_current_count;
++      int symver_new_count;
++
++      int new_symbols_count;
++      int removed_symbols_count;
++      int changed_symbols_count;
++      int no_changed_symbols_count;
++
++} KernelSymbolStatistics;
++
++extern int writeKernelSymbolsFile( FILE *, char *, char *, char *, char * );
++extern int addKernelSymboltoHashBase( void *, char *, GHashTable * );
++extern int dumpModuleSymbols( char *, GHashTable *, GHashTable * );
++extern void destroyHashTable( GHashTable * );
++extern GHashTable *createHashTable( void );
++extern FILE *getOutputFile( char * );
++extern void releaseFile( FILE * );
++GHashTable *readEfl( char * );
++
++#define PRINT_ERROR(...)  do { fprintf( stderr, "ERROR : " ); fprintf( stderr, __VA_ARGS__ ); } while( 0 )
++#define PRINT_INFO_RAW(...)   do { fprintf( stdout, __VA_ARGS__ ); } while( 0 )
++#define PRINT_INFO(...)   do { fprintf( stderr, "INFO  : " ); fprintf( stdout, __VA_ARGS__ ); } while( 0 )
++
++#endif
+diff --git a/tools/abi-checker/src/kernel_abi_checker_elf.c b/tools/abi-checker/src/kernel_abi_checker_elf.c
+new file mode 100644
+index 0000000..6f4f28c
+--- /dev/null
++++ b/tools/abi-checker/src/kernel_abi_checker_elf.c
+@@ -0,0 +1,172 @@
++#include "kernel_abi_checker.h"
++
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <unistd.h>
++#include <string.h>
++#include <stdlib.h>
++#include <libelf.h>
++#include <stdio.h>
++#include <fcntl.h>
++#include <gelf.h>
++
++GHashTable *readEfl( char *file )
++{
++      GHashTable *outputHashTable = (GHashTable *)NULL;
++      Elf_Data *edata = (Elf_Data *)NULL;
++      Elf_Scn *scn = (Elf_Scn *)NULL;
++      char *base_ptr = (char *)NULL;
++      char *sname = (char *)NULL;
++      Elf *elf = (Elf *)NULL;
++      struct stat elf_stats;
++      int symbol_count;
++      GElf_Shdr shdr;
++      GElf_Sym sym;
++      int size;
++      int fd;
++      int i;
++
++      fd = open( file, O_RDONLY );
++      if( fd < 0 )
++      {
++              PRINT_ERROR( "Cannot open efl file : %s\n", file );
++              return (GHashTable *)NULL;
++      }
++
++      if( ( fstat( fd, &elf_stats ) ) )
++      {
++              PRINT_ERROR( "Cannot stat efl file : %s\n", file );
++              close(fd );
++              return (GHashTable *)NULL;
++      }
++
++      base_ptr = (char *) malloc( elf_stats.st_size );
++      if( base_ptr == (char *)NULL )
++      {
++              PRINT_ERROR( "Memory allocation error.\n" );
++              close( fd );
++              return (GHashTable *)NULL;
++      }
++
++      if( ( read( fd, base_ptr, elf_stats.st_size ) ) < elf_stats.st_size )
++      {
++              PRINT_ERROR( "Cannot read input efl file : %s\n", file );
++        free( base_ptr );
++        close( fd );
++              return (GHashTable *)NULL;
++      }
++      free( base_ptr );
++
++      /* Create output hash table */
++      outputHashTable = createHashTable();
++      if( outputHashTable == (GHashTable *)NULL )
++      {
++              PRINT_ERROR( "Memory allocation for hash table error : %s\n", file );
++        free( base_ptr );
++        close( fd );
++              return (GHashTable *)NULL;
++      }
++
++      if( elf_version( EV_CURRENT ) == EV_NONE )
++              fprintf( stderr, "WARNING Elf Library is out of date!\n" );
++
++      // Iterate through section headers again this time well stop when we find symbols
++      elf = elf_begin( fd, ELF_C_READ, NULL );
++
++      while( ( scn = elf_nextscn( elf, scn ) ) != (Elf_Scn *)NULL )
++      {
++              gelf_getshdr( scn, &shdr );
++
++              // When we find a section header marked SHT_SYMTAB stop and get symbols
++              if(shdr.sh_type == SHT_SYMTAB)
++              {
++                      // edata points to our symbol table
++                      edata = elf_getdata(scn, edata);
++
++                      symbol_count = shdr.sh_size / shdr.sh_entsize;
++
++                      for( i = 0; i < symbol_count; i++ )
++                      {
++                              /* Get symbol */
++                              gelf_getsym( edata, i, &sym );
++
++                              /* Get symbol name length */
++                              size = strlen( elf_strptr( elf, shdr.sh_link, sym.st_name ) );
++                              if( size != 0 )
++                              {
++                                      /* allocate memory for symbol name */
++                                      sname = (char *)malloc( sizeof( char ) * ( size + 1 ) );
++                                      if( sname == (char *)NULL )
++                                      {
++                                              PRINT_ERROR( "Memory allocation for hash table error : %s\n", file );
++                                              destroyHashTable( outputHashTable );
++                                      close( fd );
++                                              return (GHashTable *)NULL;
++                                      }
++
++                                      strcpy( sname, elf_strptr( elf, shdr.sh_link, sym.st_name ) );
++
++                                      // Add symbol to hash
++                                      if( addKernelSymboltoHashBase( (void *)sname, sname, outputHashTable ) < 0 )
++                                      {
++                                              // If duplicated key free memory
++                                              free( sname );
++                                      }
++
++                              }
++                      }
++              }
++      }
++
++      /* Close file */
++      close( fd );
++
++      /* Return hash table */
++      return outputHashTable;
++}
++
++/*
++ * Private user data definition.
++ */
++
++typedef struct _efl_user_data_
++{
++      GHashTable *kernelHash;
++      FILE *outFilePtr;
++} _efl_user_data_;
++
++
++void dumpModuleSymbolsIteration( gpointer key_, gpointer value_, gpointer user_data_ )
++{
++      char *key = (char *)key_;
++      _efl_user_data_ *user_data = (_efl_user_data_ *)user_data_;
++      KernelSymbol *ptr = (KernelSymbol *)NULL;
++
++      ptr = (KernelSymbol *)g_hash_table_lookup( user_data -> kernelHash, key );
++      if( ptr != (void *)NULL )
++              writeKernelSymbolsFile( user_data -> outFilePtr, ptr -> symbolNameCrc, ptr -> symbolName, ptr -> symbolModule, ptr -> flag );
++}
++
++/*
++ * Function dumps into output files kernel symbols that
++ * are use in the module
++ */
++int dumpModuleSymbols( char *outoutFile, GHashTable *moduleSymbols, GHashTable *kernelSymbols )
++{
++      FILE *outputFilePtr = getOutputFile( outoutFile );
++      _efl_user_data_ userData;
++
++      if( outputFilePtr == (FILE *)NULL )
++              return -1;
++
++      userData.outFilePtr = outputFilePtr;
++      userData.kernelHash = kernelSymbols;
++
++      /* Loob module symbols */
++      g_hash_table_foreach( moduleSymbols, dumpModuleSymbolsIteration, (gpointer)&userData );
++
++      /* Close output file */
++      releaseFile( outputFilePtr );
++
++      return 0;
++}
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1061-Smack-Make-the-syslog-control-configurable.patch b/patches.tizen/1061-Smack-Make-the-syslog-control-configurable.patch
new file mode 100644 (file)
index 0000000..99075fe
--- /dev/null
@@ -0,0 +1,256 @@
+From f7d3c63dce376039d33ee71e3c5c39f2e281987c Mon Sep 17 00:00:00 2001
+From: Casey Schaufler <casey@schaufler-ca.com>
+Date: Mon, 23 Dec 2013 11:07:10 -0800
+Subject: [PATCH 1061/1302] Smack: Make the syslog control configurable
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The syslog control requires that the calling proccess
+have the floor ("_") Smack label. Tizen does not run any
+processes except for kernel helpers with the floor label.
+This changes allows the admin to configure a specific
+label for syslog. The default value is the star ("*")
+label, effectively removing the restriction. The value
+can be set using smackfs/syslog for anyone who wants
+a more restrictive behavior.
+
+Change-Id: Ia4270bf8864bd8342e585bbdd4791fb8359e8916
+Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
+Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ security/smack/smack.h     |   5 ++-
+ security/smack/smack_lsm.c |   4 +-
+ security/smack/smackfs.c   | 103 +++++++++++++++++++++++++++++++++++++++++----
+ 3 files changed, 99 insertions(+), 13 deletions(-)
+
+diff --git a/security/smack/smack.h b/security/smack/smack.h
+index 364cc64..d072fd3 100644
+--- a/security/smack/smack.h
++++ b/security/smack/smack.h
+@@ -241,7 +241,8 @@ u32 smack_to_secid(const char *);
+ extern int smack_cipso_direct;
+ extern int smack_cipso_mapped;
+ extern struct smack_known *smack_net_ambient;
+-extern char *smack_onlycap;
++extern struct smack_known *smack_onlycap;
++extern struct smack_known *smack_syslog_label;
+ extern const char *smack_cipso_option;
+ extern struct smack_known smack_known_floor;
+@@ -312,7 +313,7 @@ static inline int smack_privileged(int cap)
+       if (!capable(cap))
+               return 0;
+-      if (smack_onlycap == NULL || smack_onlycap == skp->smk_known)
++      if (smack_onlycap == NULL || smack_onlycap == skp)
+               return 1;
+       return 0;
+ }
+diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
+index 3f01cf5..cdbf92b 100644
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -219,8 +219,6 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
+  * smack_syslog - Smack approval on syslog
+  * @type: message type
+  *
+- * Require that the task has the floor label
+- *
+  * Returns 0 on success, error code otherwise.
+  */
+ static int smack_syslog(int typefrom_file)
+@@ -231,7 +229,7 @@ static int smack_syslog(int typefrom_file)
+       if (smack_privileged(CAP_MAC_OVERRIDE))
+               return 0;
+-       if (skp != &smack_known_floor)
++       if (smack_syslog_label != NULL && smack_syslog_label != skp)
+               rc = -EACCES;
+       return rc;
+diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
+index 160aa08..bd5c6e1 100644
+--- a/security/smack/smackfs.c
++++ b/security/smack/smackfs.c
+@@ -52,6 +52,7 @@ enum smk_inos {
+       SMK_CIPSO2      = 17,   /* load long label -> CIPSO mapping */
+       SMK_REVOKE_SUBJ = 18,   /* set rules with subject label to '-' */
+       SMK_CHANGE_RULE = 19,   /* change or add rules (long labels) */
++      SMK_SYSLOG      = 20,   /* change syslog label) */
+ };
+ /*
+@@ -59,6 +60,7 @@ enum smk_inos {
+  */
+ static DEFINE_MUTEX(smack_cipso_lock);
+ static DEFINE_MUTEX(smack_ambient_lock);
++static DEFINE_MUTEX(smack_syslog_lock);
+ static DEFINE_MUTEX(smk_netlbladdr_lock);
+ /*
+@@ -90,7 +92,13 @@ int smack_cipso_mapped = SMACK_CIPSO_MAPPED_DEFAULT;
+  * everyone. It is expected that the hat (^) label
+  * will be used if any label is used.
+  */
+-char *smack_onlycap;
++struct smack_known *smack_onlycap;
++
++/*
++ * If this value is set restrict syslog use to the label specified.
++ * It can be reset via smackfs/syslog
++ */
++struct smack_known *smack_syslog_label;
+ /*
+  * Certain IP addresses may be designated as single label hosts.
+@@ -1603,7 +1611,7 @@ static const struct file_operations smk_ambient_ops = {
+ };
+ /**
+- * smk_read_onlycap - read() for /smack/onlycap
++ * smk_read_onlycap - read() for smackfs/onlycap
+  * @filp: file pointer, not actually used
+  * @buf: where to put the result
+  * @cn: maximum to send along
+@@ -1622,7 +1630,7 @@ static ssize_t smk_read_onlycap(struct file *filp, char __user *buf,
+               return 0;
+       if (smack_onlycap != NULL)
+-              smack = smack_onlycap;
++              smack = smack_onlycap->smk_known;
+       asize = strlen(smack) + 1;
+@@ -1633,7 +1641,7 @@ static ssize_t smk_read_onlycap(struct file *filp, char __user *buf,
+ }
+ /**
+- * smk_write_onlycap - write() for /smack/onlycap
++ * smk_write_onlycap - write() for smackfs/onlycap
+  * @file: file pointer, not actually used
+  * @buf: where to get the data from
+  * @count: bytes sent
+@@ -1656,7 +1664,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
+        * explicitly for clarity. The smk_access() implementation
+        * would use smk_access(smack_onlycap, MAY_WRITE)
+        */
+-      if (smack_onlycap != NULL && smack_onlycap != skp->smk_known)
++      if (smack_onlycap != NULL && smack_onlycap != skp)
+               return -EPERM;
+       data = kzalloc(count, GFP_KERNEL);
+@@ -1676,7 +1684,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
+       if (copy_from_user(data, buf, count) != 0)
+               rc = -EFAULT;
+       else
+-              smack_onlycap = smk_import(data, count);
++              smack_onlycap = smk_import_entry(data, count);
+       kfree(data);
+       return rc;
+@@ -2158,12 +2166,89 @@ static const struct file_operations smk_change_rule_ops = {
+ };
+ /**
+- * smk_fill_super - fill the /smackfs superblock
++ * smk_read_syslog - read() for smackfs/syslog
++ * @filp: file pointer, not actually used
++ * @buf: where to put the result
++ * @cn: maximum to send along
++ * @ppos: where to start
++ *
++ * Returns number of bytes read or error code, as appropriate
++ */
++static ssize_t smk_read_syslog(struct file *filp, char __user *buf,
++                              size_t cn, loff_t *ppos)
++{
++      struct smack_known *skp;
++      ssize_t rc = -EINVAL;
++      int asize;
++
++      if (*ppos != 0)
++              return 0;
++
++      if (smack_syslog_label == NULL)
++              skp = &smack_known_star;
++      else
++              skp = smack_syslog_label;
++
++      asize = strlen(skp->smk_known) + 1;
++
++      if (cn >= asize)
++              rc = simple_read_from_buffer(buf, cn, ppos, skp->smk_known,
++                                              asize);
++
++      return rc;
++}
++
++/**
++ * smk_write_syslog - write() for smackfs/syslog
++ * @file: file pointer, not actually used
++ * @buf: where to get the data from
++ * @count: bytes sent
++ * @ppos: where to start
++ *
++ * Returns number of bytes written or error code, as appropriate
++ */
++static ssize_t smk_write_syslog(struct file *file, const char __user *buf,
++                              size_t count, loff_t *ppos)
++{
++      char *data;
++      struct smack_known *skp;
++      int rc = count;
++
++      if (!smack_privileged(CAP_MAC_ADMIN))
++              return -EPERM;
++
++      data = kzalloc(count, GFP_KERNEL);
++      if (data == NULL)
++              return -ENOMEM;
++
++      if (copy_from_user(data, buf, count) != 0)
++              rc = -EFAULT;
++      else {
++              skp = smk_import_entry(data, count);
++              if (skp == NULL)
++                      rc = -EINVAL;
++              else
++                      smack_syslog_label = smk_import_entry(data, count);
++      }
++
++      kfree(data);
++      return rc;
++}
++
++static const struct file_operations smk_syslog_ops = {
++      .read           = smk_read_syslog,
++      .write          = smk_write_syslog,
++      .llseek         = default_llseek,
++};
++
++
++/**
++ * smk_fill_super - fill the smackfs superblock
+  * @sb: the empty superblock
+  * @data: unused
+  * @silent: unused
+  *
+- * Fill in the well known entries for /smack
++ * Fill in the well known entries for the smack filesystem
+  *
+  * Returns 0 on success, an error code on failure
+  */
+@@ -2208,6 +2293,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
+                       S_IRUGO|S_IWUSR},
+               [SMK_CHANGE_RULE] = {
+                       "change-rule", &smk_change_rule_ops, S_IRUGO|S_IWUSR},
++              [SMK_SYSLOG] = {
++                      "syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR},
+               /* last one */
+                       {""}
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1062-Smack-change-rule-cap-check.patch b/patches.tizen/1062-Smack-change-rule-cap-check.patch
new file mode 100644 (file)
index 0000000..655d3b4
--- /dev/null
@@ -0,0 +1,37 @@
+From 60c0fd53836a0193633745fdb5c1048e61ad4d6b Mon Sep 17 00:00:00 2001
+From: Casey Schaufler <casey@schaufler-ca.com>
+Date: Thu, 19 Dec 2013 13:23:26 -0800
+Subject: [PATCH 1062/1302] Smack: change rule cap check
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+smk_write_change_rule() is calling capable rather than
+the more correct smack_privileged(). This allows for setting
+rules in violation of the onlycap facility. This is the
+simple repair.
+
+Change-Id: Icb5321b5b5355d64b0b029d9131cf60b5e97d356
+Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
+Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ security/smack/smackfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
+index bd5c6e1..6d8b8e7 100644
+--- a/security/smack/smackfs.c
++++ b/security/smack/smackfs.c
+@@ -2151,7 +2151,7 @@ static ssize_t smk_write_change_rule(struct file *file, const char __user *buf,
+       /*
+        * Must have privilege.
+        */
+-      if (!capable(CAP_MAC_ADMIN))
++      if (!smack_privileged(CAP_MAC_ADMIN))
+               return -EPERM;
+       return smk_write_rules_list(file, buf, count, ppos, NULL, NULL,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1063-Revert-abi-checker-tool-directory-location-update.patch b/patches.tizen/1063-Revert-abi-checker-tool-directory-location-update.patch
new file mode 100644 (file)
index 0000000..dfc514b
--- /dev/null
@@ -0,0 +1,18756 @@
+From 84dc869f6217ee9ee69d058ae61d337cac8219f4 Mon Sep 17 00:00:00 2001
+From: Jacek Pielaszkiewicz <j.pielaszkie@samsung.com>
+Date: Thu, 2 Jan 2014 22:21:59 -0800
+Subject: [PATCH 1063/1302] Revert "abi-checker - tool directory location
+ update."
+
+This reverts commit 952c6d9596e18f9df43174f513ce84ebe7cd6ca2.
+
+Change-Id: Id6f4bd3d4e76c3a07fb8cdf121745c17e59b7a2a
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/abi-checker.txt                      |  132 -
+ abi-checker/data/abi_3.10.19_1                     | 6900 ++++++++++++++++++++
+ abi-checker/sample/LICENSE                         |  848 +++
+ abi-checker/sample/Makefile                        |   12 +
+ .../packaging/udisks-automount-agent.spec.txt      |   53 +
+ abi-checker/sample/sample_module.c                 |  107 +
+ abi-checker/src/Makefile                           |   31 +
+ abi-checker/src/abi-module-checker                 |   29 +
+ abi-checker/src/abi-module-dumper                  |   38 +
+ abi-checker/src/abi-module-kernels-list            |   31 +
+ abi-checker/src/build_api_kernel_checker.sh        |   24 +
+ abi-checker/src/kernel_abi_checker.c               |  834 +++
+ abi-checker/src/kernel_abi_checker.h               |   62 +
+ abi-checker/src/kernel_abi_checker_elf.c           |  172 +
+ packaging/linux-kernel.spec                        |   16 +-
+ tools/abi-checker/data/abi_3.10.19_1               | 6900 --------------------
+ tools/abi-checker/sample/LICENSE                   |  848 ---
+ tools/abi-checker/sample/Makefile                  |   12 -
+ .../sample/packaging/sample-module.spec.txt        |   53 -
+ tools/abi-checker/sample/sample_module.c           |  107 -
+ tools/abi-checker/src/Makefile                     |   31 -
+ tools/abi-checker/src/abi-module-checker           |   43 -
+ tools/abi-checker/src/abi-module-dumper            |   51 -
+ tools/abi-checker/src/abi-module-kernels-list      |   45 -
+ tools/abi-checker/src/build_api_kernel_checker.sh  |   38 -
+ tools/abi-checker/src/kernel_abi_checker.c         |  834 ---
+ tools/abi-checker/src/kernel_abi_checker.h         |   62 -
+ tools/abi-checker/src/kernel_abi_checker_elf.c     |  172 -
+ 28 files changed, 9149 insertions(+), 9336 deletions(-)
+ delete mode 100644 Documentation/abi-checker.txt
+ create mode 100644 abi-checker/data/abi_3.10.19_1
+ create mode 100644 abi-checker/sample/LICENSE
+ create mode 100644 abi-checker/sample/Makefile
+ create mode 100644 abi-checker/sample/packaging/udisks-automount-agent.spec.txt
+ create mode 100644 abi-checker/sample/sample_module.c
+ create mode 100644 abi-checker/src/Makefile
+ create mode 100755 abi-checker/src/abi-module-checker
+ create mode 100755 abi-checker/src/abi-module-dumper
+ create mode 100755 abi-checker/src/abi-module-kernels-list
+ create mode 100755 abi-checker/src/build_api_kernel_checker.sh
+ create mode 100644 abi-checker/src/kernel_abi_checker.c
+ create mode 100644 abi-checker/src/kernel_abi_checker.h
+ create mode 100644 abi-checker/src/kernel_abi_checker_elf.c
+ delete mode 100644 tools/abi-checker/data/abi_3.10.19_1
+ delete mode 100644 tools/abi-checker/sample/LICENSE
+ delete mode 100644 tools/abi-checker/sample/Makefile
+ delete mode 100644 tools/abi-checker/sample/packaging/sample-module.spec.txt
+ delete mode 100644 tools/abi-checker/sample/sample_module.c
+ delete mode 100644 tools/abi-checker/src/Makefile
+ delete mode 100755 tools/abi-checker/src/abi-module-checker
+ delete mode 100755 tools/abi-checker/src/abi-module-dumper
+ delete mode 100755 tools/abi-checker/src/abi-module-kernels-list
+ delete mode 100755 tools/abi-checker/src/build_api_kernel_checker.sh
+ delete mode 100644 tools/abi-checker/src/kernel_abi_checker.c
+ delete mode 100644 tools/abi-checker/src/kernel_abi_checker.h
+ delete mode 100644 tools/abi-checker/src/kernel_abi_checker_elf.c
+
+diff --git a/Documentation/abi-checker.txt b/Documentation/abi-checker.txt
+deleted file mode 100644
+index 57caa21..0000000
+--- a/Documentation/abi-checker.txt
++++ /dev/null
+@@ -1,132 +0,0 @@
+-
+-                       Linux kernel ABI/API checker
+---------------------------------------------------------------------------
+-
+-I. Introduction
+-===============
+-
+-   "abi-checker" is a simple set of tools to:
+-- test changes in Linux kernel API/ABI.
+-- test compatibility kernel module wth kernel
+-- creates dump for external kernel modules with list of kernel symbols
+-  used by the module.
+-
+-
+-II. Application/scripts
+-=======================
+-
+-1. abi-checker
+-
+-   The application can be run in the following modes:
+-   - "test-kernel" - in the mode compares two Module.symvers files.
+-                   In case if some changes have been detected the
+-                   application creates report containg list of changed symbols
+-                   (added/changed/removed). Additionally summary ireport with
+-                   total number symbols, itotal number changed/modified/removed
+-                   symbols is created.
+-
+-                   Usage:
+-                     abi-checker test-kernel file1 file2
+-
+-                   Return values:
+-                     0 - if Module.symvers are identical
+-                     1 - if some changes have been detected.
+-
+-   - "build-list" - in the mode the applications creates file containing linux kernel
+-                   symbols uses by the module.
+-                   As input the application expect:
+-                   - kernel Module.symvers file
+-                   - module symbols file - each line of the file has
+-                     name of the module symbol.
+-
+-                   As output the application creates file in format like "Modules.symvers".
+-
+-                   Usage:
+-                     abi-checker build-list Module.symvers kernel_symbols_file output_file
+-
+-                   Return:
+-                     0 - success
+-                     1 - any error
+-
+-   - "dump-module" - in the mode the application directly extracts from *.ko file
+-                   symbols and creates file in format like Module.symvers containing list
+-                   of kernel symbols used by the module.
+-
+-                   Usage:
+-                     abi-checker dump-module Module.symvers module_ko_file output_file
+-
+-                   Return:
+-                     0 - success
+-                     1 - any error
+-
+-   - "test-module" - in the mode the application compares kernel "Module.symvers" file
+-                   with external module "Module.symvers" file. In case of any differences
+-                   list of changed/removed symbols is reported. Additionally summary info
+-                   with numer total number symbols, total number changed/modified/removed
+-                   symbols is created also.
+-
+-                   Usage:
+-                     abi-checker test-module kernel_Module.symvers module_Module.symvers
+-
+-                   Return:
+-                     0 - if all module symbols are identical with kernel symbols
+-                     1 - if some changes have been detected.
+-
+-2. abi-module-checker - helper script. It simplify API/API checks for kernel module. Internally
+-                  the script call abi-checker in "test-module" mode. The script assumes that in
+-                  /boot/abi directory is present ABI/API repository for linux kernel.
+-
+-                  Usage:
+-                    abi-module-checker kernel_module_abi_file
+-
+-                  Return:
+-                    0 - if module API/ABI file is compatible with current kernel
+-                    1 - in case if module is not compatible with current kernel or error
+-
+-3. abi-module-dumper - helper script. It simplify ABI/API module dump file creation. The script
+-                  assumes that in /boot/abi directory is present ABI/API repository for linux kernel.
+-
+-                  Usage:
+-                    abi-module-dumper _module_ko_file_ _output_file_
+-
+-                  Return:
+-                    0 - success
+-                    1 - any error
+-
+-4. abi-module-kernels-list - helper script. The script reporst all kernel version compatible
+-                  with the given kernel module. The script assumes that in /boot/abi directory
+-                  is present ABI/API repository for linux kernel.
+-
+-                  Usage:
+-                    abi-module-kernels-list _module_abi_file_
+-
+-                  Return:
+-                    0 - success
+-                    1 - any error
+-
+-III. Module.symvers file format
+-===============================
+-
+-   Each line of the Module.symvers file has the folloing format:
+-
+-      symbol_name<tab>symbol_crc<tab>module_name<tab>additiona_info
+-
+-Example:
+-      ...
+-      0x27e1a049      printk  vmlinux EXPORT_SYMBOL
+-      0xf85bebf9      dev_printk_emit vmlinux EXPORT_SYMBOL
+-      ...
+-
+-IV. Kernel ABI/API repository
+-=============================
+-
+-   The ABI/API repository is located in /boot/abi direcotry. The repository contains list of all
+-ABI/API versions (also for historical kernel versions).
+-   The repository contains list of files which names are in format abi_${KERNELVERSION}_${ABIVERSION}.
+-ABI/API file for current kernel version is marked by current symbolic link.
+-
+-V. Kernel ABI/API repository
+-============================
+-
+-   Directory tools/abi-checker/data ABI/API Module.symvers for current and older kernel version.
+-Module.symvers for current kernel version is indicated by current symbolic link.
+diff --git a/abi-checker/data/abi_3.10.19_1 b/abi-checker/data/abi_3.10.19_1
+new file mode 100644
+index 0000000..eea3455
+--- /dev/null
++++ b/abi-checker/data/abi_3.10.19_1
+@@ -0,0 +1,6900 @@
++0x80e54114    cfg80211_send_rx_assoc  vmlinux EXPORT_SYMBOL
++0xd4dd4a5f    ipv6_chk_custom_prefix  vmlinux EXPORT_SYMBOL
++0x765592d7    generic_file_splice_write       vmlinux EXPORT_SYMBOL
++0x74f78b5f    set_anon_super  vmlinux EXPORT_SYMBOL
++0x88ea56ef    kmem_cache_alloc        vmlinux EXPORT_SYMBOL
++0x149d22ae    replace_page_cache_page vmlinux EXPORT_SYMBOL_GPL
++0x70523a7a    __cond_resched_softirq  vmlinux EXPORT_SYMBOL
++0x55417264    unregister_vt_notifier  vmlinux EXPORT_SYMBOL_GPL
++0xc2ea8e64    snd_soc_platform_read   vmlinux EXPORT_SYMBOL_GPL
++0x0a2487e0    unblock_all_signals     vmlinux EXPORT_SYMBOL
++0x260cf8f8    of_get_property vmlinux EXPORT_SYMBOL
++0x6ac315b3    v4l2_m2m_ioctl_dqbuf    vmlinux EXPORT_SYMBOL_GPL
++0x5c421d9d    i2c_put_adapter vmlinux EXPORT_SYMBOL
++0x4d8e0b9c    rtc_class_open  vmlinux EXPORT_SYMBOL_GPL
++0x96cd2b04    scsi_sense_key_string   vmlinux EXPORT_SYMBOL
++0xedf10a85    request_firmware        vmlinux EXPORT_SYMBOL
++0x70230d35    __hci_cmd_sync  vmlinux EXPORT_SYMBOL
++0x79dc2bec    dev_uc_sync     vmlinux EXPORT_SYMBOL
++0xeb396e95    dev_mc_sync     vmlinux EXPORT_SYMBOL
++0x80ca5026    _bin2bcd        vmlinux EXPORT_SYMBOL
++0xfbaaf01e    console_lock    vmlinux EXPORT_SYMBOL
++0xdf5311f6    hwmon_device_unregister vmlinux EXPORT_SYMBOL_GPL
++0xe113bbbc    csum_partial    vmlinux EXPORT_SYMBOL
++0x1ef4f43e    cfg80211_wext_siwscan   vmlinux EXPORT_SYMBOL_GPL
++0xb343d54f    cfg80211_wext_giwscan   vmlinux EXPORT_SYMBOL_GPL
++0xc068440e    __kfifo_alloc   vmlinux EXPORT_SYMBOL
++0x376eb932    kmap_atomic     vmlinux EXPORT_SYMBOL
++0xaadff4e7    nf_log_register vmlinux EXPORT_SYMBOL
++0xc8276a79    nf_hooks_needed vmlinux EXPORT_SYMBOL
++0x1b17e06c    kstrtoll        vmlinux EXPORT_SYMBOL
++0xa7d57242    scsi_execute    vmlinux EXPORT_SYMBOL
++0x9b757ebd    raw_seq_open    vmlinux EXPORT_SYMBOL_GPL
++0x1b479d00    snd_soc_of_parse_audio_routing  vmlinux EXPORT_SYMBOL_GPL
++0x3b2785b0    crypto_hash_walk_done   vmlinux EXPORT_SYMBOL_GPL
++0xa1d55e90    _raw_spin_lock_bh       vmlinux EXPORT_SYMBOL
++0xdd391eff    profile_event_unregister        vmlinux EXPORT_SYMBOL_GPL
++0xa724257f    init_uts_ns     vmlinux EXPORT_SYMBOL_GPL
++0xc97d1140    cpufreq_cooling_get_level       vmlinux EXPORT_SYMBOL_GPL
++0x5898fd79    device_add      vmlinux EXPORT_SYMBOL_GPL
++0x5081d0b3    device_del      vmlinux EXPORT_SYMBOL_GPL
++0x37246b6e    __inet6_hash    vmlinux EXPORT_SYMBOL
++0xad3a5766    dst_release     vmlinux EXPORT_SYMBOL
++0x1e254a30    sock_no_mmap    vmlinux EXPORT_SYMBOL
++0x854e1c0b    sg_nents        vmlinux EXPORT_SYMBOL
++0xb4c753a2    disk_map_sector_rcu     vmlinux EXPORT_SYMBOL_GPL
++0x942da6f0    sysfs_update_group      vmlinux EXPORT_SYMBOL_GPL
++0xa38602cd    drain_workqueue vmlinux EXPORT_SYMBOL_GPL
++0xd4b5f202    led_trigger_store       vmlinux EXPORT_SYMBOL_GPL
++0x80104269    tcp_initialize_rcv_mss  vmlinux EXPORT_SYMBOL
++0x54e6fcdd    net_enable_timestamp    vmlinux EXPORT_SYMBOL
++0xeb32f5c3    sockfd_lookup   vmlinux EXPORT_SYMBOL
++0x02aa8f04    snd_soc_dapm_get_pin_switch     vmlinux EXPORT_SYMBOL_GPL
++0x762265ad    snd_soc_dapm_put_pin_switch     vmlinux EXPORT_SYMBOL_GPL
++0xb0ffda2f    blk_limits_max_hw_sectors       vmlinux EXPORT_SYMBOL
++0x7cd8695d    directly_mappable_cdev_bdi      vmlinux EXPORT_SYMBOL
++0x6bc3fbc0    __unregister_chrdev     vmlinux EXPORT_SYMBOL
++0x6bb86c7d    srcu_notifier_chain_register    vmlinux EXPORT_SYMBOL_GPL
++0x4b661f3f    v4l2_ctrl_grab  vmlinux EXPORT_SYMBOL
++0xd2bbf775    fb_validate_mode        vmlinux EXPORT_SYMBOL
++0xe8d75b12    nfc_target_lost vmlinux EXPORT_SYMBOL
++0xb2d299a9    dev_graft_qdisc vmlinux EXPORT_SYMBOL
++0xa851973a    raw_notifier_call_chain vmlinux EXPORT_SYMBOL_GPL
++0x138709ec    scsi_get_command        vmlinux EXPORT_SYMBOL
++0x174afb1a    __sg_page_iter_next     vmlinux EXPORT_SYMBOL
++0x30cada8f    radix_tree_next_hole    vmlinux EXPORT_SYMBOL
++0xc0412578    scsi_target_quiesce     vmlinux EXPORT_SYMBOL
++0xd7a5d2f8    transport_class_register        vmlinux EXPORT_SYMBOL_GPL
++0xd2335101    drm_fb_get_bpp_depth    vmlinux EXPORT_SYMBOL
++0xa9a33fdf    jbd2_journal_try_to_free_buffers        vmlinux EXPORT_SYMBOL
++0xffd5a395    default_wake_function   vmlinux EXPORT_SYMBOL
++0xd6cb49e3    dm_put_device   vmlinux EXPORT_SYMBOL
++0xb6e1e07d    dm_get_device   vmlinux EXPORT_SYMBOL
++0x1f9218e9    input_handler_for_each_handle   vmlinux EXPORT_SYMBOL
++0x560c6863    transport_class_unregister      vmlinux EXPORT_SYMBOL_GPL
++0x65f3ad9a    fb_videomode_to_var     vmlinux EXPORT_SYMBOL
++0x79ad634c    nfc_hci_send_cmd_async  vmlinux EXPORT_SYMBOL
++0x6bbf9530    mount_subtree   vmlinux EXPORT_SYMBOL
++0x8f22ce41    iget_locked     vmlinux EXPORT_SYMBOL
++0x6fba7c75    sdhci_runtime_suspend_host      vmlinux EXPORT_SYMBOL_GPL
++0x7f923f2a    v4l2_of_parse_endpoint  vmlinux EXPORT_SYMBOL
++0xaa2d0ca7    input_mt_assign_slots   vmlinux EXPORT_SYMBOL
++0x167fd723    drm_mm_clean    vmlinux EXPORT_SYMBOL
++0x9733c21d    sock_get_timestampns    vmlinux EXPORT_SYMBOL
++0xf42e571f    snd_soc_dapm_put_enum_virt      vmlinux EXPORT_SYMBOL_GPL
++0xcd16649c    snd_soc_dapm_get_enum_virt      vmlinux EXPORT_SYMBOL_GPL
++0x38cb130f    iommu_group_add_device  vmlinux EXPORT_SYMBOL_GPL
++0xe90d597e    class_interface_register        vmlinux EXPORT_SYMBOL_GPL
++0x49ebacbd    _clear_bit      vmlinux EXPORT_SYMBOL
++0x853b6dce    nfc_tm_activated        vmlinux EXPORT_SYMBOL
++0xc617f82c    unregister_oom_notifier vmlinux EXPORT_SYMBOL_GPL
++0x8da9fa20    spi_get_device_id       vmlinux EXPORT_SYMBOL_GPL
++0x882f44c1    class_interface_unregister      vmlinux EXPORT_SYMBOL_GPL
++0x03757c9b    of_get_named_gpio_flags vmlinux EXPORT_SYMBOL
++0x1b68aba6    pin_config_set  vmlinux EXPORT_SYMBOL
++0x7505e34c    snd_power_wait  vmlinux EXPORT_SYMBOL
++0x44366cfc    simple_write_to_buffer  vmlinux EXPORT_SYMBOL
++0x3fec6133    read_code       vmlinux EXPORT_SYMBOL
++0xf7bb3a63    __srcu_read_unlock      vmlinux EXPORT_SYMBOL_GPL
++0xc2e587d1    reset_devices   vmlinux EXPORT_SYMBOL
++0x07b991fc    iio_kfifo_free  vmlinux EXPORT_SYMBOL
++0x36c38507    tty_register_device     vmlinux EXPORT_SYMBOL
++0xa5a633b9    sg_last vmlinux EXPORT_SYMBOL
++0x62c4e40d    __blk_run_queue vmlinux EXPORT_SYMBOL
++0x3eaf291d    param_get_string        vmlinux EXPORT_SYMBOL
++0x95cb929c    of_find_all_nodes       vmlinux EXPORT_SYMBOL
++0xc2c5a45e    mmc_app_cmd     vmlinux EXPORT_SYMBOL_GPL
++0xfa388487    usb_bus_list_lock       vmlinux EXPORT_SYMBOL_GPL
++0xdbbaeb6e    regulator_map_voltage_linear    vmlinux EXPORT_SYMBOL_GPL
++0x99bb8806    memmove vmlinux EXPORT_SYMBOL
++0x9e6e25f9    jbd2_journal_start_commit       vmlinux EXPORT_SYMBOL
++0x4c0f005a    __block_page_mkwrite    vmlinux EXPORT_SYMBOL
++0x76d3cd60    laptop_mode     vmlinux EXPORT_SYMBOL
++0x8fd01dea    generic_file_direct_write       vmlinux EXPORT_SYMBOL
++0xa1f38f97    end_page_writeback      vmlinux EXPORT_SYMBOL
++0xa75312bc    call_rcu_sched  vmlinux EXPORT_SYMBOL_GPL
++0xb67b2219    cm_suspend_again        vmlinux EXPORT_SYMBOL_GPL
++0x80311392    dmam_declare_coherent_memory    vmlinux EXPORT_SYMBOL
++0xf2e8c6fe    skb_recv_datagram       vmlinux EXPORT_SYMBOL
++0x4325cade    snd_soc_jack_add_pins   vmlinux EXPORT_SYMBOL_GPL
++0x69cadac1    d_alloc_pseudo  vmlinux EXPORT_SYMBOL
++0x871c0a7e    fiemap_check_flags      vmlinux EXPORT_SYMBOL
++0xd0804fe2    generic_file_readonly_mmap      vmlinux EXPORT_SYMBOL
++0xd06524ba    raw_notifier_chain_unregister   vmlinux EXPORT_SYMBOL_GPL
++0x26448a56    usbnet_cdc_unbind       vmlinux EXPORT_SYMBOL_GPL
++0x0bbae511    return_address  vmlinux EXPORT_SYMBOL_GPL
++0x0d542439    __ipv6_addr_type        vmlinux EXPORT_SYMBOL
++0xcf470397    unregister_qdisc        vmlinux EXPORT_SYMBOL
++0x66a8c67c    crypto_shash_finup      vmlinux EXPORT_SYMBOL_GPL
++0x5647361d    crypto_shash_final      vmlinux EXPORT_SYMBOL_GPL
++0xf1c942f4    crypto_ahash_finup      vmlinux EXPORT_SYMBOL_GPL
++0x17209ab0    crypto_ahash_final      vmlinux EXPORT_SYMBOL_GPL
++0x8da17b42    scatterwalk_copychunks  vmlinux EXPORT_SYMBOL_GPL
++0xd766d6a2    sdhci_suspend_host      vmlinux EXPORT_SYMBOL_GPL
++0x9b05a0c7    usb_autopm_get_interface        vmlinux EXPORT_SYMBOL_GPL
++0x8eff5a5b    phy_device_register     vmlinux EXPORT_SYMBOL
++0xa2101833    sock_diag_put_meminfo   vmlinux EXPORT_SYMBOL_GPL
++0xc8339e24    string_unescape vmlinux EXPORT_SYMBOL
++0xeb55a931    __kfifo_max_r   vmlinux EXPORT_SYMBOL
++0xe6511495    vm_insert_page  vmlinux EXPORT_SYMBOL
++0x4396b273    irq_domain_add_legacy   vmlinux EXPORT_SYMBOL_GPL
++0x24fdb0df    register_console        vmlinux EXPORT_SYMBOL
++0x6ac76b42    pin_is_valid    vmlinux EXPORT_SYMBOL_GPL
++0xe279ec34    nf_conntrack_l4proto_tcp4       vmlinux EXPORT_SYMBOL_GPL
++0x512ce34d    sock_no_socketpair      vmlinux EXPORT_SYMBOL
++0x236032ef    input_ff_event  vmlinux EXPORT_SYMBOL_GPL
++0x1e5431bd    devm_gpio_request       vmlinux EXPORT_SYMBOL
++0x86383d16    arpt_do_table   vmlinux EXPORT_SYMBOL
++0x3c89040c    dev_addr_del    vmlinux EXPORT_SYMBOL
++0xd900e010    gnet_stats_start_copy   vmlinux EXPORT_SYMBOL
++0x33f0768c    cpufreq_quick_get_max   vmlinux EXPORT_SYMBOL
++0xa88a70b0    tcp_tso_segment vmlinux EXPORT_SYMBOL
++0xa652c4ef    __kfifo_dma_in_prepare_r        vmlinux EXPORT_SYMBOL
++0xdfb895e4    __fat_fs_error  vmlinux EXPORT_SYMBOL_GPL
++0x00438c43    bio_copy_kern   vmlinux EXPORT_SYMBOL
++0xe0878bfe    __krealloc      vmlinux EXPORT_SYMBOL
++0xa849b57b    devm_free_irq   vmlinux EXPORT_SYMBOL
++0x995d1071    prof_on vmlinux EXPORT_SYMBOL_GPL
++0x3328c21e    task_nice       vmlinux EXPORT_SYMBOL
++0x84109a46    i2c_lock_adapter        vmlinux EXPORT_SYMBOL_GPL
++0x76f824bb    usb_gadget_set_state    vmlinux EXPORT_SYMBOL_GPL
++0x702c11cd    platform_device_del     vmlinux EXPORT_SYMBOL_GPL
++0xccfe749d    platform_device_put     vmlinux EXPORT_SYMBOL_GPL
++0x6499c2c3    kernel_accept   vmlinux EXPORT_SYMBOL
++0x0147e076    kset_create_and_add     vmlinux EXPORT_SYMBOL_GPL
++0xf60d1625    mm_kobj vmlinux EXPORT_SYMBOL_GPL
++0x66561d40    set_bdi_congested       vmlinux EXPORT_SYMBOL
++0xa064fc2f    gs_free_req     vmlinux EXPORT_SYMBOL_GPL
++0xaf70f0bf    xt_proto_fini   vmlinux EXPORT_SYMBOL_GPL
++0xc1e7bf31    devm_ioremap_resource   vmlinux EXPORT_SYMBOL
++0x71d3571b    sg_miter_start  vmlinux EXPORT_SYMBOL
++0xc5894dbd    blk_queue_unprep_rq     vmlinux EXPORT_SYMBOL
++0x159c0774    lock_may_read   vmlinux EXPORT_SYMBOL
++0x56d697ce    cpu_up  vmlinux EXPORT_SYMBOL_GPL
++0xba406d79    usb_gadget_map_request  vmlinux EXPORT_SYMBOL_GPL
++0xe2b9dcc5    wakeup_source_drop      vmlinux EXPORT_SYMBOL_GPL
++0x19011c29    driver_find     vmlinux EXPORT_SYMBOL_GPL
++0x13031824    devm_gpio_request_one   vmlinux EXPORT_SYMBOL
++0x91db6962    snd_card_free   vmlinux EXPORT_SYMBOL
++0x157b3f69    load_nls        vmlinux EXPORT_SYMBOL
++0xffe5318c    dma_buf_map_attachment  vmlinux EXPORT_SYMBOL_GPL
++0x10030de6    tty_mode_ioctl  vmlinux EXPORT_SYMBOL_GPL
++0x00109670    fb_class        vmlinux EXPORT_SYMBOL
++0x97999817    rfkill_set_hw_state     vmlinux EXPORT_SYMBOL
++0x6597fe84    crypto_lookup_aead      vmlinux EXPORT_SYMBOL_GPL
++0xd7b4b67a    bio_advance     vmlinux EXPORT_SYMBOL
++0x4b8408ef    from_kuid       vmlinux EXPORT_SYMBOL
++0xb65bd3fc    add_timer_on    vmlinux EXPORT_SYMBOL_GPL
++0x4859b8bb    rtc_year_days   vmlinux EXPORT_SYMBOL
++0xa064f393    ehci_cf_port_reset_rwsem        vmlinux EXPORT_SYMBOL_GPL
++0x0c65e73c    scsi_normalize_sense    vmlinux EXPORT_SYMBOL
++0x8e84b481    __pm_runtime_use_autosuspend    vmlinux EXPORT_SYMBOL_GPL
++0xab2495da    drm_mode_connector_detach_encoder       vmlinux EXPORT_SYMBOL
++0xbb11cfba    klist_iter_exit vmlinux EXPORT_SYMBOL_GPL
++0x84044a12    ip6_local_out   vmlinux EXPORT_SYMBOL_GPL
++0xc80b5684    snd_compress_deregister vmlinux EXPORT_SYMBOL_GPL
++0x215ebd78    bitrev16        vmlinux EXPORT_SYMBOL
++0x390def22    kstrtou16_from_user     vmlinux EXPORT_SYMBOL
++0x9a74417e    kstrtoull_from_user     vmlinux EXPORT_SYMBOL
++0x6949942d    pm_runtime_set_autosuspend_delay        vmlinux EXPORT_SYMBOL_GPL
++0xfb6eedf9    power_group_name        vmlinux EXPORT_SYMBOL_GPL
++0x7752eabc    snd_pcm_new_internal    vmlinux EXPORT_SYMBOL
++0x59cdb28e    crypto_aead_type        vmlinux EXPORT_SYMBOL_GPL
++0xeadf5b18    jbd2_journal_load       vmlinux EXPORT_SYMBOL
++0xcd6a7390    v4l2_i2c_new_subdev     vmlinux EXPORT_SYMBOL_GPL
++0x997574ce    device_unregister       vmlinux EXPORT_SYMBOL_GPL
++0xedbfb39a    serial8250_request_dma  vmlinux EXPORT_SYMBOL_GPL
++0x19a156ad    xfrm_state_add  vmlinux EXPORT_SYMBOL
++0x4d4a6141    __netlink_kernel_create vmlinux EXPORT_SYMBOL
++0x3ad82802    of_property_read_u32_index      vmlinux EXPORT_SYMBOL_GPL
++0x96b53df6    mmc_cleanup_queue       vmlinux EXPORT_SYMBOL
++0x7b9ee22c    v4l2_ctrl_notify        vmlinux EXPORT_SYMBOL
++0xda3a7ca9    regulator_is_enabled    vmlinux EXPORT_SYMBOL_GPL
++0x137def66    nf_ct_l4proto_put       vmlinux EXPORT_SYMBOL_GPL
++0x7efdb4fb    nf_ct_l3proto_put       vmlinux EXPORT_SYMBOL_GPL
++0x9948898e    dapm_mark_dirty vmlinux EXPORT_SYMBOL_GPL
++0x2484d571    single_release_net      vmlinux EXPORT_SYMBOL_GPL
++0x5612133a    I_BDEV  vmlinux EXPORT_SYMBOL
++0x7729cbdd    task_handoff_register   vmlinux EXPORT_SYMBOL_GPL
++0x19353b86    scsicam_bios_param      vmlinux EXPORT_SYMBOL
++0xb6a76b8e    pn544_hci_probe vmlinux EXPORT_SYMBOL
++0x476c3efa    drm_fill_in_dev vmlinux EXPORT_SYMBOL
++0x4f1cd128    security_tun_dev_create vmlinux EXPORT_SYMBOL
++0x76f29bbf    seq_release_net vmlinux EXPORT_SYMBOL_GPL
++0x980420fb    tty_port_tty_set        vmlinux EXPORT_SYMBOL
++0xc215715c    tty_port_tty_get        vmlinux EXPORT_SYMBOL
++0xa8c74dc5    devm_regulator_get      vmlinux EXPORT_SYMBOL_GPL
++0x3441c3d6    gpio_set_value_cansleep vmlinux EXPORT_SYMBOL_GPL
++0xcd68dc1d    nfc_get_local_general_bytes     vmlinux EXPORT_SYMBOL
++0xf617c0a1    inet_csk_route_child_sock       vmlinux EXPORT_SYMBOL_GPL
++0xfce4d2e1    vfs_path_lookup vmlinux EXPORT_SYMBOL
++0x326314e4    find_or_create_page     vmlinux EXPORT_SYMBOL
++0x65bbbc78    schedule_hrtimeout_range        vmlinux EXPORT_SYMBOL_GPL
++0x8d7b0a28    phy_stop_interrupts     vmlinux EXPORT_SYMBOL
++0xe9e87de1    crypto_register_pcomp   vmlinux EXPORT_SYMBOL_GPL
++0x2d7966fb    jbd2_journal_flush      vmlinux EXPORT_SYMBOL
++0x1c4e8441    invalidate_bdev vmlinux EXPORT_SYMBOL
++0x9aeacb87    ring_buffer_iter_empty  vmlinux EXPORT_SYMBOL_GPL
++0x49eb1c4a    put_pid_ns      vmlinux EXPORT_SYMBOL_GPL
++0xb7e67f9a    iio_sw_buffer_preenable vmlinux EXPORT_SYMBOL
++0xeae6b2cc    usb_sg_init     vmlinux EXPORT_SYMBOL_GPL
++0x2f33a47d    usb_sg_wait     vmlinux EXPORT_SYMBOL_GPL
++0xba136537    scsi_reset_provider     vmlinux EXPORT_SYMBOL
++0xa9170094    drm_kms_helper_hotplug_event    vmlinux EXPORT_SYMBOL
++0xb007d3b8    tcp_twsk_unique vmlinux EXPORT_SYMBOL_GPL
++0xd35091f2    netdev_info     vmlinux EXPORT_SYMBOL
++0x3517b864    kobject_uevent  vmlinux EXPORT_SYMBOL_GPL
++0x82a5ee54    mmc_try_claim_host      vmlinux EXPORT_SYMBOL
++0x11267875    scsi_extd_sense_format  vmlinux EXPORT_SYMBOL
++0x4f56540f    pm_wakeup_event vmlinux EXPORT_SYMBOL_GPL
++0x6c61ce70    num_registered_fb       vmlinux EXPORT_SYMBOL
++0xcc2f1602    st_sensors_sysfs_get_sampling_frequency vmlinux EXPORT_SYMBOL
++0x0bf95cc0    st_sensors_sysfs_set_sampling_frequency vmlinux EXPORT_SYMBOL
++0xa73fc98f    of_n_addr_cells vmlinux EXPORT_SYMBOL
++0xaf5c2852    wakeup_source_add       vmlinux EXPORT_SYMBOL_GPL
++0xc27732b1    snd_pcm_lib_default_mmap        vmlinux EXPORT_SYMBOL_GPL
++0x3ca17104    __snd_printk    vmlinux EXPORT_SYMBOL_GPL
++0xa6a59f23    blk_cleanup_queue       vmlinux EXPORT_SYMBOL
++0xec3364ec    generic_setlease        vmlinux EXPORT_SYMBOL
++0x440d8a62    tty_hung_up_p   vmlinux EXPORT_SYMBOL
++0xfa2e4ead    ip6_tnl_dst_store       vmlinux EXPORT_SYMBOL_GPL
++0x5a0647c1    ipv6_getsockopt vmlinux EXPORT_SYMBOL
++0x329bbbde    timerqueue_del  vmlinux EXPORT_SYMBOL_GPL
++0x34161524    st_sensors_read_event_value     vmlinux EXPORT_SYMBOL
++0x3e16c1b5    v4l2_clk_put    vmlinux EXPORT_SYMBOL
++0xdc047fc4    scsi_dev_info_list_add_keyed    vmlinux EXPORT_SYMBOL
++0xdc97af2e    syscore_suspend vmlinux EXPORT_SYMBOL_GPL
++0xaebbf521    cfg80211_ch_switch_notify       vmlinux EXPORT_SYMBOL
++0x4fdb4cdf    proc_mkdir_data vmlinux EXPORT_SYMBOL_GPL
++0x8ffad455    mpage_writepages        vmlinux EXPORT_SYMBOL
++0x258f05ac    write_one_page  vmlinux EXPORT_SYMBOL
++0x32b31a8c    ktime_get_boottime      vmlinux EXPORT_SYMBOL_GPL
++0x15892417    async_synchronize_cookie        vmlinux EXPORT_SYMBOL_GPL
++0x5a596330    v4l2_i2c_new_subdev_board       vmlinux EXPORT_SYMBOL_GPL
++0xbd05974a    usb_driver_release_interface    vmlinux EXPORT_SYMBOL_GPL
++0xce190a28    cfg80211_notify_new_peer_candidate      vmlinux EXPORT_SYMBOL
++0x23c45e2a    inet_add_protocol       vmlinux EXPORT_SYMBOL
++0xe19c66e3    sync_blockdev   vmlinux EXPORT_SYMBOL
++0xd36667e2    nobh_write_end  vmlinux EXPORT_SYMBOL
++0x815a1805    n_tty_ioctl_helper      vmlinux EXPORT_SYMBOL
++0xedd9106d    __ashrdi3       vmlinux EXPORT_SYMBOL
++0xff67b37f    __lshrdi3       vmlinux EXPORT_SYMBOL
++0x85b5e625    rfkill_set_states       vmlinux EXPORT_SYMBOL
++0x6e720ff2    rtnl_unlock     vmlinux EXPORT_SYMBOL
++0x4c02a5f2    sock_rfree      vmlinux EXPORT_SYMBOL
++0xe252485d    kernel_recvmsg  vmlinux EXPORT_SYMBOL
++0x0693eedb    disk_part_iter_init     vmlinux EXPORT_SYMBOL_GPL
++0x4019ac2a    freeze_bdev     vmlinux EXPORT_SYMBOL
++0x9f1c66aa    srcu_batches_completed  vmlinux EXPORT_SYMBOL_GPL
++0xa6ec6db0    sdhci_alloc_host        vmlinux EXPORT_SYMBOL_GPL
++0x0bfba95f    usb_hub_find_child      vmlinux EXPORT_SYMBOL_GPL
++0x9f83d040    __root_device_register  vmlinux EXPORT_SYMBOL_GPL
++0x63b124fc    drm_bl_dpms     vmlinux EXPORT_SYMBOL_GPL
++0xb35f8f7f    __hci_cmd_sync_ev       vmlinux EXPORT_SYMBOL
++0xe177ecc2    skb_kill_datagram       vmlinux EXPORT_SYMBOL
++0x985c6297    kfree_skb       vmlinux EXPORT_SYMBOL
++0xdcb83c11    kernel_kobj     vmlinux EXPORT_SYMBOL_GPL
++0x1bb5fc26    atomic_notifier_chain_register  vmlinux EXPORT_SYMBOL_GPL
++0xab1d6cc1    param_get_long  vmlinux EXPORT_SYMBOL
++0x75d68801    inet_twsk_schedule      vmlinux EXPORT_SYMBOL_GPL
++0x68b83ac6    posix_acl_alloc vmlinux EXPORT_SYMBOL
++0x306b23a8    drm_mm_takedown vmlinux EXPORT_SYMBOL
++0x698be398    regulator_get_voltage   vmlinux EXPORT_SYMBOL_GPL
++0xc8bed9c5    amba_driver_unregister  vmlinux EXPORT_SYMBOL
++0x1db7dc40    pgprot_kernel   vmlinux EXPORT_SYMBOL
++0x19e03378    cfg80211_get_p2p_attr   vmlinux EXPORT_SYMBOL
++0x44a5de9b    nfnetlink_parse_nat_setup_hook  vmlinux EXPORT_SYMBOL_GPL
++0x52d047db    skb_copy_datagram_iovec vmlinux EXPORT_SYMBOL
++0x731f351a    __kfree_skb     vmlinux EXPORT_SYMBOL
++0xd544b6fe    fuse_do_open    vmlinux EXPORT_SYMBOL_GPL
++0xd98f64fc    tty_port_register_device        vmlinux EXPORT_SYMBOL_GPL
++0xfd305341    walk_stackframe vmlinux EXPORT_SYMBOL
++0x58378f4a    snd_soc_dapm_force_enable_pin   vmlinux EXPORT_SYMBOL_GPL
++0x31b31f5c    csum_partial_copy_nocheck       vmlinux EXPORT_SYMBOL
++0xeea82d10    ip_defrag       vmlinux EXPORT_SYMBOL
++0xd75abd53    register_qdisc  vmlinux EXPORT_SYMBOL
++0xe4bf323c    snd_soc_test_bits       vmlinux EXPORT_SYMBOL_GPL
++0x5d891a64    idr_destroy     vmlinux EXPORT_SYMBOL
++0xeb9e7cdd    ida_destroy     vmlinux EXPORT_SYMBOL
++0x302b0f11    generic_file_aio_read   vmlinux EXPORT_SYMBOL
++0x3fe00f7d    mmc_can_discard vmlinux EXPORT_SYMBOL
++0x51246a07    mmc_interrupt_hpi       vmlinux EXPORT_SYMBOL
++0xce55bca9    scsi_flush_work vmlinux EXPORT_SYMBOL_GPL
++0x3ca53f5d    arpt_alloc_initial_table        vmlinux EXPORT_SYMBOL_GPL
++0x3ab45d33    free_netdev     vmlinux EXPORT_SYMBOL
++0xc9ec4e21    free_percpu     vmlinux EXPORT_SYMBOL_GPL
++0x431fd1f6    v4l2_subdev_queryctrl   vmlinux EXPORT_SYMBOL
++0x7c0f2bb5    drm_mm_create_block     vmlinux EXPORT_SYMBOL
++0x3fa79dd5    ip6_datagram_recv_ctl   vmlinux EXPORT_SYMBOL_GPL
++0xd56d7aae    sk_setup_caps   vmlinux EXPORT_SYMBOL_GPL
++0x668da8d5    zlib_inflateIncomp      vmlinux EXPORT_SYMBOL
++0xe0f99a2f    ida_pre_get     vmlinux EXPORT_SYMBOL
++0xf932015f    __raw_notifier_call_chain       vmlinux EXPORT_SYMBOL_GPL
++0x4d3c153f    sigprocmask     vmlinux EXPORT_SYMBOL
++0xd1974639    spi_sync_locked vmlinux EXPORT_SYMBOL_GPL
++0xdcbd7c06    scsi_host_get   vmlinux EXPORT_SYMBOL
++0x8ccc342d    drm_helper_move_panel_connectors_to_head        vmlinux EXPORT_SYMBOL
++0x98578bb6    regulator_bulk_get      vmlinux EXPORT_SYMBOL_GPL
++0x85ddc629    sk_stream_wait_connect  vmlinux EXPORT_SYMBOL
++0x4db49a03    vb2_ioctl_dqbuf vmlinux EXPORT_SYMBOL_GPL
++0xf720d75c    drm_vblank_init vmlinux EXPORT_SYMBOL
++0x8d551bef    sysctl_tcp_rmem vmlinux EXPORT_SYMBOL
++0x6c8c2ae7    sock_no_sendmsg vmlinux EXPORT_SYMBOL
++0x3b1b7e9f    snd_soc_bytes_get       vmlinux EXPORT_SYMBOL_GPL
++0xf74dae0f    idr_alloc       vmlinux EXPORT_SYMBOL_GPL
++0x7c666ca1    jbd2_journal_update_sb_errno    vmlinux EXPORT_SYMBOL
++0x98d00f33    vfs_unlink      vmlinux EXPORT_SYMBOL
++0x9ee85355    extcon_unregister_notifier      vmlinux EXPORT_SYMBOL_GPL
++0xf9e3887b    i2c_master_recv vmlinux EXPORT_SYMBOL
++0xaff711f1    drm_global_mutex        vmlinux EXPORT_SYMBOL
++0x62c5828a    nfc_hci_set_param       vmlinux EXPORT_SYMBOL
++0x52512e8e    nfc_hci_get_param       vmlinux EXPORT_SYMBOL
++0x4c90a5a9    lro_flush_all   vmlinux EXPORT_SYMBOL
++0xc5116125    pipe_unlock     vmlinux EXPORT_SYMBOL
++0x2d6bcdcb    iio_trigger_generic_data_rdy_poll       vmlinux EXPORT_SYMBOL
++0x48c6db53    of_get_child_by_name    vmlinux EXPORT_SYMBOL
++0x4379f0a6    genlmsg_multicast_allns vmlinux EXPORT_SYMBOL
++0x43e32587    __sock_recv_wifi_status vmlinux EXPORT_SYMBOL_GPL
++0x83a5ae2e    __tracepoint_rpm_resume vmlinux EXPORT_SYMBOL_GPL
++0xb2d48a2e    queue_work_on   vmlinux EXPORT_SYMBOL
++0x59d8223a    ioport_resource vmlinux EXPORT_SYMBOL
++0x73a25185    pm_generic_restore      vmlinux EXPORT_SYMBOL_GPL
++0x401ad827    bus_rescan_devices      vmlinux EXPORT_SYMBOL_GPL
++0x3b4e8e6c    serial8250_tx_dma       vmlinux EXPORT_SYMBOL_GPL
++0xba9f64c5    put_tty_driver  vmlinux EXPORT_SYMBOL
++0xa46a0fcf    backlight_force_update  vmlinux EXPORT_SYMBOL
++0xc7a4fbed    rtnl_lock       vmlinux EXPORT_SYMBOL
++0x27b3484e    debugfs_create_bool     vmlinux EXPORT_SYMBOL_GPL
++0x3691702f    generic_file_splice_read        vmlinux EXPORT_SYMBOL
++0xdd2efc0f    ring_buffer_reset_cpu   vmlinux EXPORT_SYMBOL_GPL
++0x2c1d69dc    prepare_kernel_cred     vmlinux EXPORT_SYMBOL
++0x897473df    mktime  vmlinux EXPORT_SYMBOL
++0xa8721b97    system_state    vmlinux EXPORT_SYMBOL
++0x2b768df3    iio_buffer_show_enable  vmlinux EXPORT_SYMBOL
++0xc3070585    xfrm6_tunnel_alloc_spi  vmlinux EXPORT_SYMBOL
++0x6e583bdd    udp_push_pending_frames vmlinux EXPORT_SYMBOL
++0xead6dbe6    splice_from_pipe_next   vmlinux EXPORT_SYMBOL
++0x6d044c26    param_ops_uint  vmlinux EXPORT_SYMBOL
++0x6f0036d9    del_timer_sync  vmlinux EXPORT_SYMBOL
++0xc9db98ec    hidinput_connect        vmlinux EXPORT_SYMBOL_GPL
++0xa3a75748    sec_bulk_read   vmlinux EXPORT_SYMBOL_GPL
++0x7c640527    bt_info vmlinux EXPORT_SYMBOL
++0x00e8097b    csum_partial_copy_fromiovecend  vmlinux EXPORT_SYMBOL
++0x098ef076    wm_hubs_vmid_ena        vmlinux EXPORT_SYMBOL_GPL
++0xc29591b4    drm_framebuffer_unreference     vmlinux EXPORT_SYMBOL
++0xdbfa4d5b    con_set_default_unimap  vmlinux EXPORT_SYMBOL
++0x08b75c5b    inet_diag_bc_sk vmlinux EXPORT_SYMBOL_GPL
++0x3dea553f    __qdisc_calculate_pkt_len       vmlinux EXPORT_SYMBOL
++0xab5f8242    dev_get_by_index        vmlinux EXPORT_SYMBOL
++0x3e9d0c22    wm8958_mic_detect       vmlinux EXPORT_SYMBOL_GPL
++0x462a2e75    match_strlcpy   vmlinux EXPORT_SYMBOL
++0xf768dabc    ioctl_by_bdev   vmlinux EXPORT_SYMBOL
++0x426b04e4    dma_buf_unmap_attachment        vmlinux EXPORT_SYMBOL_GPL
++0x27146b38    init_net        vmlinux EXPORT_SYMBOL
++0x9fe06761    wm_hubs_update_class_w  vmlinux EXPORT_SYMBOL_GPL
++0x8978d687    textsearch_find_continuous      vmlinux EXPORT_SYMBOL
++0xf7b12aee    __next_cpu      vmlinux EXPORT_SYMBOL
++0x96905151    crypto_larval_lookup    vmlinux EXPORT_SYMBOL_GPL
++0xb14bfc6b    __crypto_alloc_tfm      vmlinux EXPORT_SYMBOL_GPL
++0x3ca95bb3    configfs_unregister_subsystem   vmlinux EXPORT_SYMBOL
++0xd820c283    eventfd_ctx_remove_wait_queue   vmlinux EXPORT_SYMBOL_GPL
++0x699d1d6a    generic_delete_inode    vmlinux EXPORT_SYMBOL
++0xb5f17edf    perf_register_guest_info_callbacks      vmlinux EXPORT_SYMBOL_GPL
++0x1d209e24    mmc_power_restore_host  vmlinux EXPORT_SYMBOL
++0x8c66045e    cpufreq_freq_attr_scaling_boost_freqs   vmlinux EXPORT_SYMBOL_GPL
++0x6114d8a4    regulator_force_disable vmlinux EXPORT_SYMBOL_GPL
++0x7e606130    snd_soc_calc_bclk       vmlinux EXPORT_SYMBOL_GPL
++0xac480322    nf_nat_pptp_hook_expectfn       vmlinux EXPORT_SYMBOL_GPL
++0x7f19e69f    blk_run_queue   vmlinux EXPORT_SYMBOL
++0x98dbc3bc    mmc_wait_for_req        vmlinux EXPORT_SYMBOL
++0xa0d2b347    regmap_init_spi vmlinux EXPORT_SYMBOL_GPL
++0xff7a8968    regmap_init_i2c vmlinux EXPORT_SYMBOL_GPL
++0x98cc564a    regulator_set_voltage   vmlinux EXPORT_SYMBOL_GPL
++0xcd63c845    __aeabi_lasr    vmlinux EXPORT_SYMBOL
++0x8a4fa83b    __aeabi_llsr    vmlinux EXPORT_SYMBOL
++0x78cfc117    hci_register_dev        vmlinux EXPORT_SYMBOL
++0xd458f195    __secpath_destroy       vmlinux EXPORT_SYMBOL
++0xaf64ad0d    zlib_deflate    vmlinux EXPORT_SYMBOL
++0x24fdac79    wake_bit_function       vmlinux EXPORT_SYMBOL
++0x864f4a52    of_clk_add_provider     vmlinux EXPORT_SYMBOL_GPL
++0x1de054d5    of_clk_del_provider     vmlinux EXPORT_SYMBOL_GPL
++0x42c8e001    v4l2_ctrl_next  vmlinux EXPORT_SYMBOL
++0x1e95b9ac    i2c_smbus_write_i2c_block_data  vmlinux EXPORT_SYMBOL
++0xc61c11c2    inet_csk_route_req      vmlinux EXPORT_SYMBOL_GPL
++0xed597524    qdisc_get_rtab  vmlinux EXPORT_SYMBOL
++0x9a633fbd    fuse_request_send_background    vmlinux EXPORT_SYMBOL_GPL
++0x578e47c8    locks_release_private   vmlinux EXPORT_SYMBOL_GPL
++0x40ce485b    mempool_resize  vmlinux EXPORT_SYMBOL
++0xc60f75ec    __ftrace_vprintk        vmlinux EXPORT_SYMBOL_GPL
++0xb88fb22f    hid_set_field   vmlinux EXPORT_SYMBOL_GPL
++0xd954e4a7    bus_remove_file vmlinux EXPORT_SYMBOL_GPL
++0x6172f515    xfrm_unregister_km      vmlinux EXPORT_SYMBOL
++0xc5e4258e    in_dev_finish_destroy   vmlinux EXPORT_SYMBOL
++0xe094ef39    sg_next vmlinux EXPORT_SYMBOL
++0x6b4be175    bio_map_user    vmlinux EXPORT_SYMBOL
++0x0b07abe2    unshare_fs_struct       vmlinux EXPORT_SYMBOL_GPL
++0x2ef6b5bf    smp_call_function_any   vmlinux EXPORT_SYMBOL_GPL
++0xd0fb7cd4    __tasklet_hi_schedule_first     vmlinux EXPORT_SYMBOL
++0xe35c5285    of_find_node_by_phandle vmlinux EXPORT_SYMBOL
++0x55724b35    hid_destroy_device      vmlinux EXPORT_SYMBOL_GPL
++0x85ad5803    cfg80211_wext_siwrts    vmlinux EXPORT_SYMBOL_GPL
++0x87cfc6e0    cfg80211_wext_giwrts    vmlinux EXPORT_SYMBOL_GPL
++0xd1b091c0    unix_inq_len    vmlinux EXPORT_SYMBOL_GPL
++0xc4d21124    __nf_conntrack_confirm  vmlinux EXPORT_SYMBOL_GPL
++0x452a56c2    __brelse        vmlinux EXPORT_SYMBOL
++0xbddeca9d    pipe_lock       vmlinux EXPORT_SYMBOL
++0x33bfdca2    gserial_alloc_line      vmlinux EXPORT_SYMBOL_GPL
++0x4edb7421    config_ep_by_speed      vmlinux EXPORT_SYMBOL_GPL
++0xa473e3d4    usbnet_suspend  vmlinux EXPORT_SYMBOL_GPL
++0x06521223    mdiobus_scan    vmlinux EXPORT_SYMBOL
++0xed8f1a2b    dmam_alloc_coherent     vmlinux EXPORT_SYMBOL
++0x9535ce7b    tty_port_carrier_raised vmlinux EXPORT_SYMBOL
++0x71280d73    regulator_set_voltage_time_sel  vmlinux EXPORT_SYMBOL_GPL
++0x1e314b21    regulator_use_dummy_regulator   vmlinux EXPORT_SYMBOL_GPL
++0x347fd4b3    eventfd_ctx_get vmlinux EXPORT_SYMBOL_GPL
++0x941f2aaa    eventfd_ctx_put vmlinux EXPORT_SYMBOL_GPL
++0xf9d18552    mark_buffer_async_write vmlinux EXPORT_SYMBOL
++0x6c6cdd4d    wait_for_completion_interruptible_timeout       vmlinux EXPORT_SYMBOL
++0xe5525b81    scsi_device_set_state   vmlinux EXPORT_SYMBOL
++0x28e23139    xfrm_probe_algs vmlinux EXPORT_SYMBOL_GPL
++0x9a9ff422    ip_route_me_harder      vmlinux EXPORT_SYMBOL
++0xb7cbbafa    inet_sock_destruct      vmlinux EXPORT_SYMBOL
++0xf26e8a56    nf_reinject     vmlinux EXPORT_SYMBOL
++0x3a9b6fb9    blk_unregister_region   vmlinux EXPORT_SYMBOL
++0x2a2c3036    unregister_nls  vmlinux EXPORT_SYMBOL
++0x5358fc36    ring_buffer_discard_commit      vmlinux EXPORT_SYMBOL_GPL
++0x555621fa    clk_enable      vmlinux EXPORT_SYMBOL_GPL
++0xf25af73c    mmc_add_host    vmlinux EXPORT_SYMBOL
++0x4b02b5ca    dev_pm_qos_update_request       vmlinux EXPORT_SYMBOL_GPL
++0xe11c3bb2    tty_chars_in_buffer     vmlinux EXPORT_SYMBOL
++0x4e60ec09    __serio_register_port   vmlinux EXPORT_SYMBOL
++0xc17515d7    usb_hcds_loaded vmlinux EXPORT_SYMBOL_GPL
++0xadfe5127    usbnet_write_cmd_nopm   vmlinux EXPORT_SYMBOL_GPL
++0x9c6c1c9c    phy_exit        vmlinux EXPORT_SYMBOL_GPL
++0x44da5d0f    __csum_ipv6_magic       vmlinux EXPORT_SYMBOL
++0x2ef42c91    l2cap_register_user     vmlinux EXPORT_SYMBOL
++0xa83b115e    skb_pull_rcsum  vmlinux EXPORT_SYMBOL_GPL
++0xbaa490f8    snd_ctl_unregister_ioctl        vmlinux EXPORT_SYMBOL
++0xe3df2eb1    v4l2_async_notifier_register    vmlinux EXPORT_SYMBOL
++0x950c4994    __scsi_device_lookup_by_target  vmlinux EXPORT_SYMBOL
++0xed3baf1d    tcp_fetch_timewait_stamp        vmlinux EXPORT_SYMBOL_GPL
++0xebdbe48c    radix_tree_gang_lookup  vmlinux EXPORT_SYMBOL
++0xc00b1f1e    register_nls    vmlinux EXPORT_SYMBOL
++0x62543231    locks_alloc_lock        vmlinux EXPORT_SYMBOL_GPL
++0x6585e310    alloc_pages_exact_nid   vmlinux EXPORT_SYMBOL
++0xb121390a    probe_irq_on    vmlinux EXPORT_SYMBOL
++0xc58f706b    usbnet_get_msglevel     vmlinux EXPORT_SYMBOL_GPL
++0x1007becd    usbnet_set_msglevel     vmlinux EXPORT_SYMBOL_GPL
++0xb9eb9d79    pm_generic_suspend      vmlinux EXPORT_SYMBOL_GPL
++0xca860514    xfrm_state_lookup       vmlinux EXPORT_SYMBOL
++0x795598eb    tcp_parse_options       vmlinux EXPORT_SYMBOL
++0x17a3ce1e    rps_may_expire_flow     vmlinux EXPORT_SYMBOL
++0x7b3d29ac    i2c_smbus_write_block_data      vmlinux EXPORT_SYMBOL
++0x8164b1cc    ump_dd_handle_create_from_secure_id     vmlinux EXPORT_SYMBOL
++0x7f04682a    of_gpio_simple_xlate    vmlinux EXPORT_SYMBOL
++0xefd6cf06    __aeabi_unwind_cpp_pr0  vmlinux EXPORT_SYMBOL
++0xb7ba76c7    __aeabi_unwind_cpp_pr2  vmlinux EXPORT_SYMBOL
++0x43f0af31    snd_soc_codec_set_pll   vmlinux EXPORT_SYMBOL_GPL
++0x6e46b07b    module_refcount vmlinux EXPORT_SYMBOL
++0x455348d7    usb_composite_probe     vmlinux EXPORT_SYMBOL_GPL
++0x0e8110c3    sec_reg_write   vmlinux EXPORT_SYMBOL_GPL
++0xba0edce6    inet_ctl_sock_create    vmlinux EXPORT_SYMBOL_GPL
++0x8454f899    dev_addr_add_multiple   vmlinux EXPORT_SYMBOL
++0x62e4112b    _submit_bh      vmlinux EXPORT_SYMBOL_GPL
++0x715622e2    handle_edge_irq vmlinux EXPORT_SYMBOL
++0x0e639705    usbnet_link_change      vmlinux EXPORT_SYMBOL
++0x8043eb8c    firmware_kobj   vmlinux EXPORT_SYMBOL_GPL
++0x130bf78b    drm_mode_create_from_cmdline_mode       vmlinux EXPORT_SYMBOL
++0xbdd37f04    usb_autopm_put_interface_async  vmlinux EXPORT_SYMBOL_GPL
++0x63c46f03    usb_lock_device_for_reset       vmlinux EXPORT_SYMBOL_GPL
++0x1bc5eebe    pinctrl_gpio_direction_input    vmlinux EXPORT_SYMBOL_GPL
++0x519b061e    genl_register_mc_group  vmlinux EXPORT_SYMBOL
++0xf81e0907    ___pskb_trim    vmlinux EXPORT_SYMBOL
++0xd352e668    snd_timer_global_new    vmlinux EXPORT_SYMBOL
++0x85df9b6c    strsep  vmlinux EXPORT_SYMBOL
++0xe2d5255a    strcmp  vmlinux EXPORT_SYMBOL
++0x788fe103    iomem_resource  vmlinux EXPORT_SYMBOL
++0xe7a9a6a0    tty_driver_flush_buffer vmlinux EXPORT_SYMBOL
++0xd648e564    fb_match_mode   vmlinux EXPORT_SYMBOL
++0xbc10dd97    __put_user_4    vmlinux EXPORT_SYMBOL
++0x353e3fa5    __get_user_4    vmlinux EXPORT_SYMBOL
++0xe50ad8a8    snd_ctl_add     vmlinux EXPORT_SYMBOL
++0x6323f87b    mnt_unpin       vmlinux EXPORT_SYMBOL
++0xbb524006    vfs_create      vmlinux EXPORT_SYMBOL
++0x2f47d8c7    cpufreq_frequency_get_table     vmlinux EXPORT_SYMBOL_GPL
++0xda44cb37    setup_charger_manager   vmlinux EXPORT_SYMBOL_GPL
++0x01ab74a6    devm_kfree      vmlinux EXPORT_SYMBOL_GPL
++0x153be8a8    drm_fb_helper_pan_display       vmlinux EXPORT_SYMBOL
++0xc676a007    __ablkcipher_walk_complete      vmlinux EXPORT_SYMBOL_GPL
++0x868bf31d    sb_min_blocksize        vmlinux EXPORT_SYMBOL
++0xaf5f7994    remove_conflicting_framebuffers vmlinux EXPORT_SYMBOL
++0x49e5aa17    bt_procfs_init  vmlinux EXPORT_SYMBOL
++0xf353a698    register_module_notifier        vmlinux EXPORT_SYMBOL
++0x154c6338    dm_kcopyd_client_destroy        vmlinux EXPORT_SYMBOL
++0xdd4cc94f    v4l2_device_set_name    vmlinux EXPORT_SYMBOL_GPL
++0x703189d7    regulator_get_mode      vmlinux EXPORT_SYMBOL_GPL
++0x43028a27    nfc_hci_result_to_errno vmlinux EXPORT_SYMBOL
++0x0551f0ce    tick_nohz_idle_exit     vmlinux EXPORT_SYMBOL_GPL
++0xc7208c3a    serial8250_resume_port  vmlinux EXPORT_SYMBOL
++0xe91355f8    inet_csk_clone_lock     vmlinux EXPORT_SYMBOL_GPL
++0xe912da6b    unregister_sysctl_table vmlinux EXPORT_SYMBOL
++0xaf91d89f    __kernel_param_lock     vmlinux EXPORT_SYMBOL
++0x31cdd70c    hid_input_report        vmlinux EXPORT_SYMBOL_GPL
++0xd73ee981    cdc_ncm_fill_tx_frame   vmlinux EXPORT_SYMBOL_GPL
++0xa01c6bfd    del_gendisk     vmlinux EXPORT_SYMBOL
++0x4d74d134    block_write_full_page   vmlinux EXPORT_SYMBOL
++0x43632d7d    of_find_property        vmlinux EXPORT_SYMBOL
++0xa76550fa    xfrm_register_type      vmlinux EXPORT_SYMBOL
++0xde08bdaf    nf_ct_invert_tuple      vmlinux EXPORT_SYMBOL_GPL
++0xa61aa028    snd_pcm_format_unsigned vmlinux EXPORT_SYMBOL
++0x0b51f3e2    fat_sync_inode  vmlinux EXPORT_SYMBOL_GPL
++0xb3e441b1    clear_bdi_congested     vmlinux EXPORT_SYMBOL
++0x9305f8e6    cpufreq_get     vmlinux EXPORT_SYMBOL
++0x8708f581    usbnet_stop     vmlinux EXPORT_SYMBOL_GPL
++0x581e0fb1    sock_no_setsockopt      vmlinux EXPORT_SYMBOL
++0xdf40231d    sock_no_getsockopt      vmlinux EXPORT_SYMBOL
++0xa3355ffa    snd_soc_default_writable_register       vmlinux EXPORT_SYMBOL_GPL
++0xb8ba4a80    __blockdev_direct_IO    vmlinux EXPORT_SYMBOL
++0x4f70015c    splice_from_pipe_end    vmlinux EXPORT_SYMBOL
++0x93658a27    migrate_page    vmlinux EXPORT_SYMBOL
++0x2e45e488    rcu_note_context_switch vmlinux EXPORT_SYMBOL_GPL
++0xf0d68ed6    clk_register_clkdevs    vmlinux EXPORT_SYMBOL
++0xec58fd46    ip6_route_me_harder     vmlinux EXPORT_SYMBOL
++0xccec571a    thermal_zone_device_update      vmlinux EXPORT_SYMBOL_GPL
++0x011c6bf0    regulator_map_voltage_iterate   vmlinux EXPORT_SYMBOL_GPL
++0x44eabd85    km_new_mapping  vmlinux EXPORT_SYMBOL
++0x4469fe89    lro_receive_skb vmlinux EXPORT_SYMBOL
++0x6d54f969    napi_complete   vmlinux EXPORT_SYMBOL
++0xb740018f    snd_device_new  vmlinux EXPORT_SYMBOL
++0xab363caa    generic_block_bmap      vmlinux EXPORT_SYMBOL
++0x868784cb    __symbol_get    vmlinux EXPORT_SYMBOL_GPL
++0x142a8be4    of_clk_get_parent_name  vmlinux EXPORT_SYMBOL_GPL
++0x991484c4    of_property_count_strings       vmlinux EXPORT_SYMBOL_GPL
++0x5f3c8f5c    mmc_assume_removable    vmlinux EXPORT_SYMBOL
++0xf9c1f53f    pm_generic_thaw_early   vmlinux EXPORT_SYMBOL_GPL
++0x47229b5c    gpio_request    vmlinux EXPORT_SYMBOL_GPL
++0x517deb22    __ip_dev_find   vmlinux EXPORT_SYMBOL
++0x815fe221    snd_pcm_hw_constraint_list      vmlinux EXPORT_SYMBOL
++0xbe0e5118    nla_memcmp      vmlinux EXPORT_SYMBOL
++0xf1db1704    nla_memcpy      vmlinux EXPORT_SYMBOL
++0x1f77b093    file_remove_suid        vmlinux EXPORT_SYMBOL
++0xfd6794fe    d_materialise_unique    vmlinux EXPORT_SYMBOL_GPL
++0x26622a2b    kmem_cache_free vmlinux EXPORT_SYMBOL
++0x7aab19fb    vb2_ops_wait_prepare    vmlinux EXPORT_SYMBOL_GPL
++0x5d22b406    rndis_register  vmlinux EXPORT_SYMBOL
++0xd25dc9c5    cdc_ncm_rx_verify_nth16 vmlinux EXPORT_SYMBOL_GPL
++0x8299a21a    ieee80211_data_from_8023        vmlinux EXPORT_SYMBOL
++0x499cb58c    prepare_to_wait vmlinux EXPORT_SYMBOL
++0xadf42bd5    __request_region        vmlinux EXPORT_SYMBOL
++0x9f560253    get_cpu_device  vmlinux EXPORT_SYMBOL_GPL
++0x923b1276    dmaengine_get   vmlinux EXPORT_SYMBOL
++0x56d9b1de    amba_device_register    vmlinux EXPORT_SYMBOL
++0x6fa16209    bdev_read_only  vmlinux EXPORT_SYMBOL
++0xf0009fee    put_pages_list  vmlinux EXPORT_SYMBOL
++0xdf73013e    from_kprojid    vmlinux EXPORT_SYMBOL
++0x2609451c    sock_wfree      vmlinux EXPORT_SYMBOL
++0x0de80eba    snd_soc_info_volsw      vmlinux EXPORT_SYMBOL_GPL
++0xd7f77051    test_set_page_writeback vmlinux EXPORT_SYMBOL
++0xa734a3e9    abort_exclusive_wait    vmlinux EXPORT_SYMBOL
++0x091eb9b4    round_jiffies   vmlinux EXPORT_SYMBOL_GPL
++0x99429b47    display_entity_unregister       vmlinux EXPORT_SYMBOL_GPL
++0x40d0b751    qdisc_destroy   vmlinux EXPORT_SYMBOL
++0x16445cb3    inet_proto_csum_replace16       vmlinux EXPORT_SYMBOL
++0x5594be03    bitmap_remap    vmlinux EXPORT_SYMBOL
++0x7fe04a49    truncate_inode_pages    vmlinux EXPORT_SYMBOL
++0x42f865b4    fb_videomode_from_videomode     vmlinux EXPORT_SYMBOL_GPL
++0x0422fe4a    inet_csk_timer_bug_msg  vmlinux EXPORT_SYMBOL
++0x1b0c9510    sysfs_notify    vmlinux EXPORT_SYMBOL_GPL
++0x0948cde9    num_physpages   vmlinux EXPORT_SYMBOL
++0x7818fe23    input_flush_device      vmlinux EXPORT_SYMBOL
++0x2da17677    regmap_bulk_write       vmlinux EXPORT_SYMBOL_GPL
++0x03ba39b0    v7_flush_user_cache_all vmlinux EXPORT_SYMBOL
++0x9d0403b2    inet_hash       vmlinux EXPORT_SYMBOL_GPL
++0x9a1dfd65    strpbrk vmlinux EXPORT_SYMBOL
++0xa040153b    sysfs_create_file       vmlinux EXPORT_SYMBOL_GPL
++0x99cbae17    seq_lseek       vmlinux EXPORT_SYMBOL
++0x092c2a7a    irq_domain_add_tree     vmlinux EXPORT_SYMBOL_GPL
++0x23a42148    media_entity_pipeline_stop      vmlinux EXPORT_SYMBOL_GPL
++0xd87b6687    ip6_frag_match  vmlinux EXPORT_SYMBOL
++0x9e6d79f8    snd_info_get_str        vmlinux EXPORT_SYMBOL
++0x1551dc51    bitmap_find_free_region vmlinux EXPORT_SYMBOL
++0x9f491e5d    ftrace_print_symbols_seq_u64    vmlinux EXPORT_SYMBOL
++0x9b6bedb6    sdhci_add_host  vmlinux EXPORT_SYMBOL_GPL
++0x928f84b5    drm_crtc_init   vmlinux EXPORT_SYMBOL
++0x56b63670    lzo1x_1_compress        vmlinux EXPORT_SYMBOL_GPL
++0x637d3d6a    set_disk_ro     vmlinux EXPORT_SYMBOL
++0x5053e2a6    leds_list_lock  vmlinux EXPORT_SYMBOL_GPL
++0x19fc7f60    regulator_set_mode      vmlinux EXPORT_SYMBOL_GPL
++0x7e703a3d    snd_soc_limit_volume    vmlinux EXPORT_SYMBOL_GPL
++0x3bdbf275    sg_alloc_table_from_pages       vmlinux EXPORT_SYMBOL
++0xb87bf605    blk_rq_unprep_clone     vmlinux EXPORT_SYMBOL_GPL
++0xe04f7caa    dm_read_arg_group       vmlinux EXPORT_SYMBOL
++0xb26725f8    bus_find_device vmlinux EXPORT_SYMBOL_GPL
++0x7ff32312    drm_gem_handle_create   vmlinux EXPORT_SYMBOL
++0xcd7edbe9    cfg80211_sched_scan_results     vmlinux EXPORT_SYMBOL
++0x92dbc6c1    xfrm_aalg_get_byid      vmlinux EXPORT_SYMBOL_GPL
++0x6fb14f17    tcp_create_openreq_child        vmlinux EXPORT_SYMBOL
++0x2f368d4c    sk_common_release       vmlinux EXPORT_SYMBOL
++0xd60281a9    st_sensors_set_fullscale_by_gain        vmlinux EXPORT_SYMBOL
++0x228bec81    led_trigger_register    vmlinux EXPORT_SYMBOL_GPL
++0x28c52e3f    video_device_release    vmlinux EXPORT_SYMBOL
++0x3faac56f    drm_mode_set_config_internal    vmlinux EXPORT_SYMBOL
++0xf86d3493    skb_queue_head  vmlinux EXPORT_SYMBOL
++0x5fd1e756    skb_prepare_seq_read    vmlinux EXPORT_SYMBOL
++0x02ff8c3e    sk_reset_timer  vmlinux EXPORT_SYMBOL
++0xb08f47ec    snd_soc_resume  vmlinux EXPORT_SYMBOL_GPL
++0x0f055dad    snd_pcm_hw_rule_noresample      vmlinux EXPORT_SYMBOL
++0x9529f10a    fuse_conn_put   vmlinux EXPORT_SYMBOL_GPL
++0xf6bb8bf1    irq_get_irq_data        vmlinux EXPORT_SYMBOL_GPL
++0x02c3c736    v4l2_subdev_querymenu   vmlinux EXPORT_SYMBOL
++0xfb42deb3    drm_helper_mode_fill_fb_struct  vmlinux EXPORT_SYMBOL
++0x4920a692    regulator_bulk_enable   vmlinux EXPORT_SYMBOL_GPL
++0x85963907    netdev_has_upper_dev    vmlinux EXPORT_SYMBOL
++0x5f58f676    flex_array_get_ptr      vmlinux EXPORT_SYMBOL
++0x3e6c012e    bio_alloc_bioset        vmlinux EXPORT_SYMBOL
++0xb9ac0503    mali_set_user_setting   vmlinux EXPORT_SYMBOL
++0xbd22a332    drm_pci_free    vmlinux EXPORT_SYMBOL
++0x171addd2    ieee80211_get_hdrlen_from_skb   vmlinux EXPORT_SYMBOL
++0xe41115b7    vfs_cancel_lock vmlinux EXPORT_SYMBOL_GPL
++0x912c123d    pm_qos_remove_request   vmlinux EXPORT_SYMBOL_GPL
++0x8e2d17cc    v4l2_clk_enable vmlinux EXPORT_SYMBOL
++0xfe3150df    usb_driver_set_configuration    vmlinux EXPORT_SYMBOL_GPL
++0x3b5bb4f2    mii_ethtool_sset        vmlinux EXPORT_SYMBOL
++0xe9bc24c2    mii_ethtool_gset        vmlinux EXPORT_SYMBOL
++0x62e1f48d    class_compat_create_link        vmlinux EXPORT_SYMBOL_GPL
++0xb602c57e    nf_ct_l3proto_module_put        vmlinux EXPORT_SYMBOL_GPL
++0xcd4b940c    release_sock    vmlinux EXPORT_SYMBOL
++0x90e5450f    textsearch_destroy      vmlinux EXPORT_SYMBOL
++0x50e7193a    __i2c_first_dynamic_bus_num     vmlinux EXPORT_SYMBOL_GPL
++0xa2a8e81f    class_remove_file       vmlinux EXPORT_SYMBOL_GPL
++0x95f56edb    drm_i2c_encoder_init    vmlinux EXPORT_SYMBOL
++0xdd1dd3a7    snd_pcm_hw_constraint_msbits    vmlinux EXPORT_SYMBOL
++0x23a574fd    security_secmark_relabel_packet vmlinux EXPORT_SYMBOL
++0x3f01eca9    unmap_underlying_metadata       vmlinux EXPORT_SYMBOL
++0x55feec9e    sync_inode      vmlinux EXPORT_SYMBOL
++0xb859f38b    krealloc        vmlinux EXPORT_SYMBOL
++0x9af5fc30    of_phy_connect_fixed_link       vmlinux EXPORT_SYMBOL
++0xa2307653    v4l2_device_register_subdev_nodes       vmlinux EXPORT_SYMBOL_GPL
++0x66e9dc03    usbnet_status_stop      vmlinux EXPORT_SYMBOL_GPL
++0x419a9395    snd_card_create vmlinux EXPORT_SYMBOL
++0x9edc4cdb    __invalidate_device     vmlinux EXPORT_SYMBOL
++0x301fa826    seq_put_decimal_ull     vmlinux EXPORT_SYMBOL
++0x8f7b5061    jack_event_handler      vmlinux EXPORT_SYMBOL_GPL
++0xf8e6aed1    input_register_device   vmlinux EXPORT_SYMBOL
++0xfba9b108    drm_fb_helper_fini      vmlinux EXPORT_SYMBOL
++0x31266931    con_debug_leave vmlinux EXPORT_SYMBOL_GPL
++0x2ba707a8    sysctl_tcp_low_latency  vmlinux EXPORT_SYMBOL
++0x1163f0a7    blk_max_low_pfn vmlinux EXPORT_SYMBOL
++0x94c6b808    blk_queue_free_tags     vmlinux EXPORT_SYMBOL
++0xe0413655    elv_unregister_queue    vmlinux EXPORT_SYMBOL
++0x3fab3ca9    register_sysctl_table   vmlinux EXPORT_SYMBOL
++0x67b78eb3    seq_hlist_next_rcu      vmlinux EXPORT_SYMBOL
++0x571767e3    led_classdev_unregister vmlinux EXPORT_SYMBOL_GPL
++0x9323826a    ipv4_redirect   vmlinux EXPORT_SYMBOL_GPL
++0x495c96f8    posix_acl_init  vmlinux EXPORT_SYMBOL
++0xd59c42a1    drm_idlelock_release    vmlinux EXPORT_SYMBOL
++0x490355ba    tty_flip_buffer_push    vmlinux EXPORT_SYMBOL
++0x3ef6c408    bio_copy_data   vmlinux EXPORT_SYMBOL
++0x6fe3d8cf    ktime_add_safe  vmlinux EXPORT_SYMBOL_GPL
++0xf9a482f9    msleep  vmlinux EXPORT_SYMBOL
++0xc66b77b1    iommu_group_set_iommudata       vmlinux EXPORT_SYMBOL_GPL
++0xd55ad93b    iommu_group_get_iommudata       vmlinux EXPORT_SYMBOL_GPL
++0x0d0549e1    hidinput_calc_abs_res   vmlinux EXPORT_SYMBOL_GPL
++0x07608656    uart_get_divisor        vmlinux EXPORT_SYMBOL
++0xc8f72480    unregister_netdev       vmlinux EXPORT_SYMBOL
++0x1ce42553    __bforget       vmlinux EXPORT_SYMBOL
++0x8427e5bd    v4l2_event_subdev_unsubscribe   vmlinux EXPORT_SYMBOL_GPL
++0x8e865d3c    arm_delay_ops   vmlinux EXPORT_SYMBOL
++0x2f88c16b    inet6_add_protocol      vmlinux EXPORT_SYMBOL
++0x9fda569e    raw_unhash_sk   vmlinux EXPORT_SYMBOL_GPL
++0x1def6812    xt_register_table       vmlinux EXPORT_SYMBOL_GPL
++0xe7e87d7a    set_h225_addr_hook      vmlinux EXPORT_SYMBOL_GPL
++0xd2037371    sock_no_listen  vmlinux EXPORT_SYMBOL
++0x33607e14    snd_soc_poweroff        vmlinux EXPORT_SYMBOL_GPL
++0xab600421    probe_irq_off   vmlinux EXPORT_SYMBOL
++0xfc8ace2f    input_mt_destroy_slots  vmlinux EXPORT_SYMBOL
++0xf222f80f    usb_unpoison_anchored_urbs      vmlinux EXPORT_SYMBOL_GPL
++0x4845cdbc    scsi_device_lookup_by_target    vmlinux EXPORT_SYMBOL
++0x79aa04a2    get_random_bytes        vmlinux EXPORT_SYMBOL
++0x9db44776    nfc_hci_connect_gate    vmlinux EXPORT_SYMBOL
++0x4d2726f3    tcf_exts_destroy        vmlinux EXPORT_SYMBOL
++0xbaa8249a    snd_ctl_activate_id     vmlinux EXPORT_SYMBOL_GPL
++0x55ef85b4    blk_peek_request        vmlinux EXPORT_SYMBOL
++0xc8b267ae    seq_vprintf     vmlinux EXPORT_SYMBOL
++0xe6504df3    sdhci_get_of_property   vmlinux EXPORT_SYMBOL_GPL
++0x3ad12077    regcache_sync_region    vmlinux EXPORT_SYMBOL_GPL
++0x80af255f    pm_runtime_allow        vmlinux EXPORT_SYMBOL_GPL
++0x16105b8e    do_unbind_con_driver    vmlinux EXPORT_SYMBOL_GPL
++0xdaf4dfb3    fb_mode_option  vmlinux EXPORT_SYMBOL_GPL
++0x1f5dd478    tcf_hash_lookup vmlinux EXPORT_SYMBOL
++0x14965155    sock_no_poll    vmlinux EXPORT_SYMBOL
++0xfcbe775e    blk_rq_prep_clone       vmlinux EXPORT_SYMBOL_GPL
++0x53e6cd86    crypto_alloc_shash      vmlinux EXPORT_SYMBOL_GPL
++0x93f84c0c    crypto_alloc_ahash      vmlinux EXPORT_SYMBOL_GPL
++0xae1d4afd    sdio_unregister_driver  vmlinux EXPORT_SYMBOL_GPL
++0x1b50682a    drm_mode_connector_attach_encoder       vmlinux EXPORT_SYMBOL
++0x78bed30e    regulator_get   vmlinux EXPORT_SYMBOL_GPL
++0xae4e6d07    inet6_register_icmp_sender      vmlinux EXPORT_SYMBOL
++0xcd67300d    vlan_ioctl_set  vmlinux EXPORT_SYMBOL
++0x4d9b6d35    snd_pcm_format_size     vmlinux EXPORT_SYMBOL
++0xc11d8093    iov_shorten     vmlinux EXPORT_SYMBOL
++0x6a037cf1    mempool_kfree   vmlinux EXPORT_SYMBOL
++0x0cebb5a5    __ww_mutex_lock vmlinux EXPORT_SYMBOL
++0x430e5257    of_alias_get_id vmlinux EXPORT_SYMBOL_GPL
++0x5d9260a1    v4l2_ctrl_activate      vmlinux EXPORT_SYMBOL
++0x17622c01    display_entity_set_state        vmlinux EXPORT_SYMBOL_GPL
++0x26adb815    thread_notify_head      vmlinux EXPORT_SYMBOL_GPL
++0xf0ef15b4    list_sort       vmlinux EXPORT_SYMBOL
++0x958974d4    remove_arg_zero vmlinux EXPORT_SYMBOL
++0x7b5c8440    vm_munmap       vmlinux EXPORT_SYMBOL
++0x46178343    remap_pfn_range vmlinux EXPORT_SYMBOL
++0x46608fa0    getnstimeofday  vmlinux EXPORT_SYMBOL
++0x51a049e1    scsi_scan_target        vmlinux EXPORT_SYMBOL
++0x61b31a8a    subsys_dev_iter_init    vmlinux EXPORT_SYMBOL_GPL
++0x054aade6    subsys_dev_iter_exit    vmlinux EXPORT_SYMBOL_GPL
++0x4099164a    skcipher_geniv_exit     vmlinux EXPORT_SYMBOL_GPL
++0x9c144793    file_update_time        vmlinux EXPORT_SYMBOL
++0x8a162c7d    bdi_unregister  vmlinux EXPORT_SYMBOL
++0x755d68eb    iio_enum_read   vmlinux EXPORT_SYMBOL_GPL
++0x03e593b9    vb2_wait_for_all_buffers        vmlinux EXPORT_SYMBOL_GPL
++0xc06a30a4    phy_register_fixup      vmlinux EXPORT_SYMBOL
++0x3c308a26    device_bind_driver      vmlinux EXPORT_SYMBOL_GPL
++0x55010072    device_store_ulong      vmlinux EXPORT_SYMBOL_GPL
++0x0b405d40    inet6_csk_search_req    vmlinux EXPORT_SYMBOL_GPL
++0x7a1acc62    dev_mc_init     vmlinux EXPORT_SYMBOL
++0x93fcc9bd    dev_uc_init     vmlinux EXPORT_SYMBOL
++0x865029ac    __hw_addr_sync  vmlinux EXPORT_SYMBOL
++0xb04359d9    snd_soc_bytes_info      vmlinux EXPORT_SYMBOL_GPL
++0x11a13e31    _kstrtol        vmlinux EXPORT_SYMBOL
++0x6e73746d    kobject_uevent_env      vmlinux EXPORT_SYMBOL_GPL
++0x7d830ea5    mb_cache_entry_alloc    vmlinux EXPORT_SYMBOL
++0xd702e480    _raw_read_unlock        vmlinux EXPORT_SYMBOL
++0xfa2bcf10    init_timer_key  vmlinux EXPORT_SYMBOL
++0xe03525ac    of_irq_map_raw  vmlinux EXPORT_SYMBOL_GPL
++0xb39171d5    cdc_ncm_select_altsetting       vmlinux EXPORT_SYMBOL_GPL
++0xec52c42e    scsi_setup_blk_pc_cmnd  vmlinux EXPORT_SYMBOL
++0x337cce46    put_cmsg        vmlinux EXPORT_SYMBOL
++0x655656dc    skb_free_datagram       vmlinux EXPORT_SYMBOL
++0x2ad0e68c    sound_class     vmlinux EXPORT_SYMBOL
++0x7a98596c    filp_close      vmlinux EXPORT_SYMBOL
++0x4c39b01b    truncate_setsize        vmlinux EXPORT_SYMBOL
++0xfd5683b9    wait_for_completion_interruptible       vmlinux EXPORT_SYMBOL
++0xfc38a837    extcon_update_state     vmlinux EXPORT_SYMBOL_GPL
++0xdba80fc1    of_fdt_unflatten_tree   vmlinux EXPORT_SYMBOL_GPL
++0x3be54580    generic_readlink        vmlinux EXPORT_SYMBOL
++0x6cee2e42    drm_object_property_get_value   vmlinux EXPORT_SYMBOL
++0x67b27ec1    tty_std_termios vmlinux EXPORT_SYMBOL
++0x4298b775    v7_flush_kern_cache_all vmlinux EXPORT_SYMBOL
++0x66ac9af0    ether_setup     vmlinux EXPORT_SYMBOL
++0xafb2d50e    __break_lease   vmlinux EXPORT_SYMBOL
++0x9e6500de    get_task_comm   vmlinux EXPORT_SYMBOL_GPL
++0xd5df9165    __get_vm_area   vmlinux EXPORT_SYMBOL_GPL
++0x6b7589f4    param_set_bool  vmlinux EXPORT_SYMBOL
++0xbfc407b4    param_ops_bint  vmlinux EXPORT_SYMBOL
++0xadb5559d    param_ops_byte  vmlinux EXPORT_SYMBOL
++0xd2a3a2e7    usb_deregister_device_driver    vmlinux EXPORT_SYMBOL_GPL
++0x0264e273    usbnet_nway_reset       vmlinux EXPORT_SYMBOL_GPL
++0xbc31af43    device_create_file      vmlinux EXPORT_SYMBOL_GPL
++0x34bb0082    snd_soc_dapm_put_volsw  vmlinux EXPORT_SYMBOL_GPL
++0xcec0e354    snd_soc_dapm_get_volsw  vmlinux EXPORT_SYMBOL_GPL
++0xa3d6bc8a    would_dump      vmlinux EXPORT_SYMBOL
++0x782cd0c9    truncate_inode_pages_range      vmlinux EXPORT_SYMBOL
++0xefc7de8e    force_sig       vmlinux EXPORT_SYMBOL
++0xb3b30554    fimc_find_remote_sensor vmlinux EXPORT_SYMBOL
++0xf3be20f4    v4l2_m2m_querybuf       vmlinux EXPORT_SYMBOL_GPL
++0x0fccafb1    drm_global_item_unref   vmlinux EXPORT_SYMBOL
++0xe8d24f74    arm_coherent_dma_ops    vmlinux EXPORT_SYMBOL
++0x05240ee7    percpu_counter_batch    vmlinux EXPORT_SYMBOL
++0x5d75cd76    d_path  vmlinux EXPORT_SYMBOL
++0x495426ee    v4l2_ctrl_get_name      vmlinux EXPORT_SYMBOL
++0x6e89a560    regmap_irq_chip_get_base        vmlinux EXPORT_SYMBOL_GPL
++0x587616f1    vfs_fstatat     vmlinux EXPORT_SYMBOL
++0x162ccc0c    lg_local_lock   vmlinux EXPORT_SYMBOL
++0x498225b6    v4l2_m2m_expbuf vmlinux EXPORT_SYMBOL_GPL
++0x21b2c1ab    __pm_genpd_remove_callbacks     vmlinux EXPORT_SYMBOL_GPL
++0x1516aa21    brcmf_sdio_probe        drivers/net/wireless/brcm80211/brcmfmac/brcmfmac        EXPORT_SYMBOL
++0x36c61868    hci_free_dev    vmlinux EXPORT_SYMBOL
++0xcfa46265    igrab   vmlinux EXPORT_SYMBOL
++0x36150611    iio_validate_scan_mask_onehot   vmlinux EXPORT_SYMBOL_GPL
++0x01ac01fc    usbnet_resume   vmlinux EXPORT_SYMBOL_GPL
++0x43421b4f    sdev_evt_send   vmlinux EXPORT_SYMBOL_GPL
++0x1fdcc615    rtnl_notify     vmlinux EXPORT_SYMBOL
++0xe4ad075c    __rtnl_link_register    vmlinux EXPORT_SYMBOL_GPL
++0x41366c3b    sock_recvmsg    vmlinux EXPORT_SYMBOL
++0x3468cb4a    snd_soc_set_runtime_hwparams    vmlinux EXPORT_SYMBOL_GPL
++0x308e4695    snd_pcm_open_substream  vmlinux EXPORT_SYMBOL
++0x2ef9dbdc    blk_end_request_err     vmlinux EXPORT_SYMBOL_GPL
++0x9b11d9bf    blk_end_request_all     vmlinux EXPORT_SYMBOL
++0x2f5bf998    blk_queue_bio   vmlinux EXPORT_SYMBOL_GPL
++0xd16712f3    crypto_check_attr_type  vmlinux EXPORT_SYMBOL_GPL
++0x16305289    warn_slowpath_null      vmlinux EXPORT_SYMBOL
++0xcb0288ea    ledtrig_cpu     vmlinux EXPORT_SYMBOL
++0xe6431c3b    mmc_can_secure_erase_trim       vmlinux EXPORT_SYMBOL
++0x916dbe7c    usb_hcd_unmap_urb_for_dma       vmlinux EXPORT_SYMBOL_GPL
++0x8dc2569e    nf_ct_l3protos  vmlinux EXPORT_SYMBOL_GPL
++0x1471e34e    linkwatch_fire_event    vmlinux EXPORT_SYMBOL
++0x56db40e5    snd_device_free vmlinux EXPORT_SYMBOL
++0xe1b524a3    fs_bio_set      vmlinux EXPORT_SYMBOL
++0x8d522714    __rcu_read_lock vmlinux EXPORT_SYMBOL_GPL
++0x4906a967    hid_snto32      vmlinux EXPORT_SYMBOL_GPL
++0xfbf6bb67    watchdog_init_timeout   vmlinux EXPORT_SYMBOL_GPL
++0xd37e13b4    regulator_set_optimum_mode      vmlinux EXPORT_SYMBOL_GPL
++0x4fe1eddf    unregister_netevent_notifier    vmlinux EXPORT_SYMBOL_GPL
++0x66af941c    snd_soc_debugfs_root    vmlinux EXPORT_SYMBOL_GPL
++0x42c43759    input_mt_report_slot_state      vmlinux EXPORT_SYMBOL
++0x8fccb56f    scsi_init_io    vmlinux EXPORT_SYMBOL
++0x375fce7f    asoc_dma_platform_unregister    vmlinux EXPORT_SYMBOL_GPL
++0xa58dee99    _raw_write_unlock       vmlinux EXPORT_SYMBOL
++0x252efd1e    sdhci_remove_host       vmlinux EXPORT_SYMBOL_GPL
++0xb5128e67    v4l2_i2c_subdev_init    vmlinux EXPORT_SYMBOL_GPL
++0x6d680e52    v4l2_i2c_subdev_addr    vmlinux EXPORT_SYMBOL_GPL
++0xb56fc02f    fib_default_rule_pref   vmlinux EXPORT_SYMBOL
++0x97359c5f    snd_pcm_period_elapsed  vmlinux EXPORT_SYMBOL
++0x3df477d7    debugfs_create_x8       vmlinux EXPORT_SYMBOL_GPL
++0x314d3160    kmap_to_page    vmlinux EXPORT_SYMBOL
++0x8afbf7b1    irq_domain_xlate_onecell        vmlinux EXPORT_SYMBOL_GPL
++0x6b264960    irq_domain_xlate_twocell        vmlinux EXPORT_SYMBOL_GPL
++0xee3c209d    cgroup_next_descendant_pre      vmlinux EXPORT_SYMBOL_GPL
++0x6776c27a    drm_av_sync_delay       vmlinux EXPORT_SYMBOL
++0x0fe112dc    of_dma_controller_free  vmlinux EXPORT_SYMBOL_GPL
++0xfccc95e9    pwm_put vmlinux EXPORT_SYMBOL_GPL
++0xb8a5a2d7    iio_convert_raw_to_processed    vmlinux EXPORT_SYMBOL_GPL
++0x8f7df3a7    drm_object_attach_property      vmlinux EXPORT_SYMBOL
++0xd248fe40    uart_write_wakeup       vmlinux EXPORT_SYMBOL
++0x0483a4c2    skb_append      vmlinux EXPORT_SYMBOL
++0xb28d7c56    snd_soc_read    vmlinux EXPORT_SYMBOL_GPL
++0x6f1f9555    read_cache_page_gfp     vmlinux EXPORT_SYMBOL
++0xe12954af    pwm_can_sleep   vmlinux EXPORT_SYMBOL_GPL
++0x333147c5    sk_stream_error vmlinux EXPORT_SYMBOL
++0x37f30c3d    devm_request_and_ioremap        vmlinux EXPORT_SYMBOL
++0x40d57aa3    audit_log_start vmlinux EXPORT_SYMBOL
++0x3232306b    need_load_eval  vmlinux EXPORT_SYMBOL_GPL
++0x27328cec    drm_fb_helper_debug_leave       vmlinux EXPORT_SYMBOL
++0x2f4df599    arm_iommu_attach_device vmlinux EXPORT_SYMBOL_GPL
++0x38ec6320    netdev_crit     vmlinux EXPORT_SYMBOL
++0x7385ebdb    sysfs_create_files      vmlinux EXPORT_SYMBOL_GPL
++0x0758ff61    sget    vmlinux EXPORT_SYMBOL
++0xca20d111    v4l2_ctrl_cluster       vmlinux EXPORT_SYMBOL
++0x5f754e5a    memset  vmlinux EXPORT_SYMBOL
++0xbd70447e    ip_tunnel_setup vmlinux EXPORT_SYMBOL_GPL
++0x2541a979    snd_soc_calc_frame_size vmlinux EXPORT_SYMBOL_GPL
++0xdc3fcbc9    __sw_hweight8   vmlinux EXPORT_SYMBOL
++0x02ee26c1    free_pages_exact        vmlinux EXPORT_SYMBOL
++0x885bcec8    tasklet_hrtimer_init    vmlinux EXPORT_SYMBOL_GPL
++0xe80bbfc6    v4l2_event_pending      vmlinux EXPORT_SYMBOL_GPL
++0x356cb8d3    debugfs_create_atomic_t vmlinux EXPORT_SYMBOL_GPL
++0x064db9a5    mark_mounts_for_expiry  vmlinux EXPORT_SYMBOL_GPL
++0x8b43159b    register_cpu_notifier   vmlinux EXPORT_SYMBOL
++0xd0d5f859    st_sensors_read_event_config    vmlinux EXPORT_SYMBOL
++0xba490602    nci_to_errno    vmlinux EXPORT_SYMBOL
++0x26cae22e    snd_soc_dapm_free       vmlinux EXPORT_SYMBOL_GPL
++0x6b4f9016    d_set_d_op      vmlinux EXPORT_SYMBOL
++0x6d340f64    tty_termios_input_baud_rate     vmlinux EXPORT_SYMBOL
++0x0d3f57a2    _find_next_bit_le       vmlinux EXPORT_SYMBOL
++0x74e1a843    xfrm_aalg_get_byidx     vmlinux EXPORT_SYMBOL_GPL
++0x56b147ce    unregister_tcf_proto_ops        vmlinux EXPORT_SYMBOL
++0xb6936ffe    _bcd2bin        vmlinux EXPORT_SYMBOL
++0x707f5f40    vb2_fop_write   vmlinux EXPORT_SYMBOL_GPL
++0x598cd828    udp_table       vmlinux EXPORT_SYMBOL
++0x7d0e3e72    ida_get_new_above       vmlinux EXPORT_SYMBOL
++0x2e2f1740    ring_buffer_record_disable_cpu  vmlinux EXPORT_SYMBOL_GPL
++0xafe38346    mmc_erase_group_aligned vmlinux EXPORT_SYMBOL
++0x1af8e94b    nla_put vmlinux EXPORT_SYMBOL
++0xf23fcb99    __kfifo_in      vmlinux EXPORT_SYMBOL
++0xf8ac3a16    revalidate_disk vmlinux EXPORT_SYMBOL
++0xca5967e3    vm_stat vmlinux EXPORT_SYMBOL
++0xd5b1376d    register_shrinker       vmlinux EXPORT_SYMBOL
++0xa6c3a59e    power_supply_am_i_supplied      vmlinux EXPORT_SYMBOL_GPL
++0x35aa9322    regcache_mark_dirty     vmlinux EXPORT_SYMBOL_GPL
++0xbdb14b0b    transport_configure_device      vmlinux EXPORT_SYMBOL_GPL
++0x391c8c77    drm_bl_register vmlinux EXPORT_SYMBOL_GPL
++0x2c744386    ip_tunnel_dellink       vmlinux EXPORT_SYMBOL_GPL
++0xc10022a2    register_sound_dsp      vmlinux EXPORT_SYMBOL
++0x6d29349e    blk_post_runtime_suspend        vmlinux EXPORT_SYMBOL
++0x803eda06    block_invalidatepage    vmlinux EXPORT_SYMBOL
++0x22ba7f9f    may_umount_tree vmlinux EXPORT_SYMBOL
++0x7a944007    rcu_idle_enter  vmlinux EXPORT_SYMBOL_GPL
++0x3ce3f899    iio_device_register     vmlinux EXPORT_SYMBOL
++0x624a6406    hwrng_register  vmlinux EXPORT_SYMBOL_GPL
++0xa408cd5e    misc_register   vmlinux EXPORT_SYMBOL
++0x636b12c8    nf_nat_need_gre vmlinux EXPORT_SYMBOL_GPL
++0xe58ab676    ip_tunnel_init_net      vmlinux EXPORT_SYMBOL_GPL
++0x38c6e66b    udp_lib_get_port        vmlinux EXPORT_SYMBOL
++0x7cda3781    ip_route_input_noref    vmlinux EXPORT_SYMBOL
++0x207ffd0a    kernel_write    vmlinux EXPORT_SYMBOL
++0xbbabb724    tty_ldisc_ref   vmlinux EXPORT_SYMBOL_GPL
++0x899a5d37    rtnl_af_unregister      vmlinux EXPORT_SYMBOL_GPL
++0x1c7f08a9    snd_soc_dapm_del_routes vmlinux EXPORT_SYMBOL_GPL
++0xe71105e8    iget_failed     vmlinux EXPORT_SYMBOL
++0x0fc01e9f    static_key_slow_inc     vmlinux EXPORT_SYMBOL_GPL
++0xbfee3ad5    loop_unregister_transfer        vmlinux EXPORT_SYMBOL
++0xaaef0fd2    class_dev_iter_exit     vmlinux EXPORT_SYMBOL_GPL
++0xd2b18e1d    __of_phy_provider_register      vmlinux EXPORT_SYMBOL_GPL
++0x1751de15    phy_create      vmlinux EXPORT_SYMBOL_GPL
++0x25c677c4    mac_pton        vmlinux EXPORT_SYMBOL
++0xc54cd128    filemap_fdatawait_range vmlinux EXPORT_SYMBOL
++0x05afc379    mmc_cache_ctrl  vmlinux EXPORT_SYMBOL
++0x814e4cf8    cfg80211_chandef_usable vmlinux EXPORT_SYMBOL
++0x829865cd    inode_sub_bytes vmlinux EXPORT_SYMBOL
++0xec602814    inode_set_bytes vmlinux EXPORT_SYMBOL
++0x47e70229    v7_flush_user_cache_range       vmlinux EXPORT_SYMBOL
++0x51cb6360    arp_xmit        vmlinux EXPORT_SYMBOL
++0xc84ab6f8    __dev_getfirstbyhwtype  vmlinux EXPORT_SYMBOL
++0xd499d564    __dev_get_by_index      vmlinux EXPORT_SYMBOL
++0x66a67dab    flex_array_shrink       vmlinux EXPORT_SYMBOL
++0xd41fe818    _raw_read_unlock_irqrestore     vmlinux EXPORT_SYMBOL
++0x47fdbc4f    v4l2_ctrl_new_std       vmlinux EXPORT_SYMBOL
++0xb2fe3cab    mdiobus_register        vmlinux EXPORT_SYMBOL
++0xf70d473a    __inet6_lookup_established      vmlinux EXPORT_SYMBOL
++0x8187321e    snd_timer_interrupt     vmlinux EXPORT_SYMBOL
++0xec5d6a71    __nla_put_nohdr vmlinux EXPORT_SYMBOL
++0xda5506a3    crypto_unregister_instance      vmlinux EXPORT_SYMBOL_GPL
++0xfd361609    bdi_init        vmlinux EXPORT_SYMBOL
++0xf8d88cd8    clk_get vmlinux EXPORT_SYMBOL
++0x22df2dd3    sdio_claim_host vmlinux EXPORT_SYMBOL_GPL
++0x40973662    sysctl_udp_mem  vmlinux EXPORT_SYMBOL
++0x3b50ba06    cpufreq_cooling_register        vmlinux EXPORT_SYMBOL_GPL
++0xb1c29e91    usbnet_probe    vmlinux EXPORT_SYMBOL_GPL
++0x5e1176a3    nfc_hci_send_cmd        vmlinux EXPORT_SYMBOL
++0x1bc8ce1b    inet_csk_accept vmlinux EXPORT_SYMBOL
++0x35cdd9d0    inet_hash_connect       vmlinux EXPORT_SYMBOL_GPL
++0x0334da4e    scsi_command_size_tbl   vmlinux EXPORT_SYMBOL
++0xa843805a    get_unused_fd_flags     vmlinux EXPORT_SYMBOL
++0xb1e25684    __trace_bputs   vmlinux EXPORT_SYMBOL_GPL
++0xb58dcfa2    synchronize_sched_expedited     vmlinux EXPORT_SYMBOL_GPL
++0x17cefda4    cpufreq_cooling_unregister      vmlinux EXPORT_SYMBOL_GPL
++0xc6fca5ad    v4l2_m2m_release        vmlinux EXPORT_SYMBOL_GPL
++0x0614dd5a    v4l2_video_std_frame_period     vmlinux EXPORT_SYMBOL
++0x08195a4e    generic_mii_ioctl       vmlinux EXPORT_SYMBOL
++0xe64e4a5b    drm_select_eld  vmlinux EXPORT_SYMBOL
++0xa3b4f14d    bt_accept_dequeue       vmlinux EXPORT_SYMBOL
++0x8e20620c    tcf_unregister_action   vmlinux EXPORT_SYMBOL
++0x52026cdf    security_sb_parse_opts_str      vmlinux EXPORT_SYMBOL
++0xe82c33bd    usb_bulk_msg    vmlinux EXPORT_SYMBOL_GPL
++0x876abdb2    xfrm_state_delete_tunnel        vmlinux EXPORT_SYMBOL
++0xfdb4778c    sock_edemux     vmlinux EXPORT_SYMBOL
++0x4688d7ec    pvclock_gtod_unregister_notifier        vmlinux EXPORT_SYMBOL_GPL
++0xc6b72634    gserial_connect vmlinux EXPORT_SYMBOL_GPL
++0x55046eb2    platform_device_add_resources   vmlinux EXPORT_SYMBOL_GPL
++0x1b25d2b3    of_pwm_xlate_with_flags vmlinux EXPORT_SYMBOL_GPL
++0x6e1ba077    in6_dev_finish_destroy  vmlinux EXPORT_SYMBOL
++0xecd68a44    tcp_gro_receive vmlinux EXPORT_SYMBOL
++0x922e5568    eth_header      vmlinux EXPORT_SYMBOL
++0xf82ec573    rb_prev vmlinux EXPORT_SYMBOL
++0xfe2f7b7e    jbd2_journal_init_dev   vmlinux EXPORT_SYMBOL
++0xd4114894    bd_unlink_disk_holder   vmlinux EXPORT_SYMBOL_GPL
++0xa9e18049    task_handoff_unregister vmlinux EXPORT_SYMBOL_GPL
++0x4b5366cf    down_killable   vmlinux EXPORT_SYMBOL
++0x1129616d    scsi_rescan_device      vmlinux EXPORT_SYMBOL
++0x9ed554b3    unregister_keyboard_notifier    vmlinux EXPORT_SYMBOL_GPL
++0x3271e6e4    unregister_framebuffer  vmlinux EXPORT_SYMBOL
++0x4acb9a7c    napi_gro_receive        vmlinux EXPORT_SYMBOL
++0x38ed4ee7    netdev_master_upper_dev_get_rcu vmlinux EXPORT_SYMBOL
++0x5ae87753    debugfs_print_regs32    vmlinux EXPORT_SYMBOL_GPL
++0xeac5a47a    clk_notifier_register   vmlinux EXPORT_SYMBOL_GPL
++0xdcc389f7    usb_get_phy     vmlinux EXPORT_SYMBOL_GPL
++0x5cfbd179    phonet_stream_ops       vmlinux EXPORT_SYMBOL
++0xd7ea7094    nf_unregister_queue_handler     vmlinux EXPORT_SYMBOL
++0xa9b804f6    snd_soc_dapm_ignore_suspend     vmlinux EXPORT_SYMBOL_GPL
++0xb04cf0fe    lg_local_unlock vmlinux EXPORT_SYMBOL
++0x24eb7e32    leds_list       vmlinux EXPORT_SYMBOL_GPL
++0xb2f2f502    dev_get_by_flags_rcu    vmlinux EXPORT_SYMBOL
++0x996bdb64    _kstrtoul       vmlinux EXPORT_SYMBOL
++0xd6f8cf35    __block_write_begin     vmlinux EXPORT_SYMBOL
++0x3517383e    register_reboot_notifier        vmlinux EXPORT_SYMBOL
++0x188a3dfb    timespec_trunc  vmlinux EXPORT_SYMBOL
++0x7647726c    handle_sysrq    vmlinux EXPORT_SYMBOL
++0x2a55c54a    l2cap_unregister_user   vmlinux EXPORT_SYMBOL
++0xdaafc807    tcp_sockets_allocated   vmlinux EXPORT_SYMBOL
++0x61618241    netlink_alloc_skb       vmlinux EXPORT_SYMBOL_GPL
++0x883edc99    snd_soc_dapm_weak_routes        vmlinux EXPORT_SYMBOL_GPL
++0x0b20ad4e    inode_owner_or_capable  vmlinux EXPORT_SYMBOL
++0x5ddfdc97    generic_pipe_buf_confirm        vmlinux EXPORT_SYMBOL
++0x27fede28    get_super_thawed        vmlinux EXPORT_SYMBOL
++0x7ff20102    v4l2_s_ctrl     vmlinux EXPORT_SYMBOL
++0x9745d638    drm_err vmlinux EXPORT_SYMBOL
++0x1c1a727a    v4l2_ctrl_subdev_subscribe_event        vmlinux EXPORT_SYMBOL
++0x157df959    usbnet_tx_timeout       vmlinux EXPORT_SYMBOL_GPL
++0x33ca0b9d    scsi_device_quiesce     vmlinux EXPORT_SYMBOL
++0x18a12a47    drm_modeset_unlock_all  vmlinux EXPORT_SYMBOL
++0x59d29dab    v7_flush_kern_dcache_area       vmlinux EXPORT_SYMBOL
++0x9ca80cdd    inet6_protos    vmlinux EXPORT_SYMBOL
++0x58714dc9    snd_soc_jack_add_zones  vmlinux EXPORT_SYMBOL_GPL
++0xdc9110f5    snd_pcm_hw_param_first  vmlinux EXPORT_SYMBOL
++0xf184d189    kernel_power_off        vmlinux EXPORT_SYMBOL_GPL
++0xc8a270a1    usb_put_function        vmlinux EXPORT_SYMBOL_GPL
++0xdfe8f93c    display_entity_get_size vmlinux EXPORT_SYMBOL_GPL
++0x0ef959a5    ip6t_unregister_table   vmlinux EXPORT_SYMBOL
++0x5ee28af3    genl_register_ops       vmlinux EXPORT_SYMBOL
++0xda91a719    snd_pcm_new     vmlinux EXPORT_SYMBOL
++0x8731837f    debugfs_create_u64      vmlinux EXPORT_SYMBOL_GPL
++0x0d350531    block_commit_write      vmlinux EXPORT_SYMBOL
++0xcb62227b    con_copy_unimap vmlinux EXPORT_SYMBOL
++0x9b90584e    tty_ldisc_ref_wait      vmlinux EXPORT_SYMBOL_GPL
++0xf727c5be    __netdev_alloc_skb      vmlinux EXPORT_SYMBOL
++0xf186dfad    wm_hubs_set_bias_level  vmlinux EXPORT_SYMBOL_GPL
++0x5bc4fef5    snd_soc_get_dai_substream       vmlinux EXPORT_SYMBOL_GPL
++0xabefee2b    _snd_pcm_lib_alloc_vmalloc_buffer       vmlinux EXPORT_SYMBOL
++0x5a116367    perf_event_create_kernel_counter        vmlinux EXPORT_SYMBOL_GPL
++0x0bfa3a19    rcu_idle_exit   vmlinux EXPORT_SYMBOL_GPL
++0x90ff6c9f    nf_ct_invert_tuplepr    vmlinux EXPORT_SYMBOL_GPL
++0xf3cd9688    snd_soc_dapm_sync       vmlinux EXPORT_SYMBOL_GPL
++0x68fb4f69    locks_delete_block      vmlinux EXPORT_SYMBOL
++0xdca2a7bb    dput    vmlinux EXPORT_SYMBOL
++0x67a000fa    try_module_get  vmlinux EXPORT_SYMBOL
++0x4790cc27    v4l2_s_ext_ctrls        vmlinux EXPORT_SYMBOL
++0xf39c1176    tty_kref_put    vmlinux EXPORT_SYMBOL
++0x56310925    regulator_mode_to_status        vmlinux EXPORT_SYMBOL_GPL
++0x0825a4fe    regulator_list_voltage_linear   vmlinux EXPORT_SYMBOL_GPL
++0x43db92ba    fb_set_suspend  vmlinux EXPORT_SYMBOL
++0x4993cc2b    register_net_sysctl     vmlinux EXPORT_SYMBOL_GPL
++0x8a490c90    rfkill_set_sw_state     vmlinux EXPORT_SYMBOL
++0xaae97496    snd_soc_bulk_write_raw  vmlinux EXPORT_SYMBOL_GPL
++0xb4dd257b    srcu_notifier_call_chain        vmlinux EXPORT_SYMBOL_GPL
++0x4403ead3    usb_match_one_id        vmlinux EXPORT_SYMBOL_GPL
++0x829a0b6c    screen_glyph    vmlinux EXPORT_SYMBOL_GPL
++0xf7802486    __aeabi_uidivmod        vmlinux EXPORT_SYMBOL
++0x4b8f110e    sk_free vmlinux EXPORT_SYMBOL
++0x4fbbaedb    snd_soc_free_ac97_codec vmlinux EXPORT_SYMBOL_GPL
++0xfd5566cf    scsi_is_sdev_device     vmlinux EXPORT_SYMBOL
++0x17dc8b68    drm_vblank_pre_modeset  vmlinux EXPORT_SYMBOL
++0x7ef39823    ieee80211_hdrlen        vmlinux EXPORT_SYMBOL
++0xc8f36b20    kobject_init    vmlinux EXPORT_SYMBOL
++0xb2e764e8    suspend_valid_only_mem  vmlinux EXPORT_SYMBOL_GPL
++0xfaf9995e    sleep_on        vmlinux EXPORT_SYMBOL
++0x42160169    flush_workqueue vmlinux EXPORT_SYMBOL_GPL
++0xf3251e7b    v4l2_norm_to_name       vmlinux EXPORT_SYMBOL
++0xd7b664df    regulator_list_voltage_table    vmlinux EXPORT_SYMBOL_GPL
++0xfe13b82a    snd_soc_info_enum_ext   vmlinux EXPORT_SYMBOL_GPL
++0x22a8b63d    bio_flush_dcache_pages  vmlinux EXPORT_SYMBOL
++0x0c3d1edb    simple_lookup   vmlinux EXPORT_SYMBOL
++0x4cbc159a    gether_set_dev_addr     vmlinux EXPORT_SYMBOL
++0xdac8e102    gether_get_dev_addr     vmlinux EXPORT_SYMBOL
++0xfa599bb2    netlink_register_notifier       vmlinux EXPORT_SYMBOL
++0xb7e5c788    cgroup_next_descendant_post     vmlinux EXPORT_SYMBOL_GPL
++0xd7dc295c    dm_io   vmlinux EXPORT_SYMBOL
++0xb8698990    usb_match_id    vmlinux EXPORT_SYMBOL_GPL
++0x91a5dbd2    drm_idlelock_take       vmlinux EXPORT_SYMBOL
++0xba86f941    xfrm_policy_insert      vmlinux EXPORT_SYMBOL
++0x2519a629    skb_segment     vmlinux EXPORT_SYMBOL_GPL
++0x2f574814    blk_queue_max_segments  vmlinux EXPORT_SYMBOL
++0xa17232f2    bio_clone_bioset        vmlinux EXPORT_SYMBOL
++0xba2bc8de    unlock_rename   vmlinux EXPORT_SYMBOL
++0x9820b644    warn_slowpath_fmt_taint vmlinux EXPORT_SYMBOL
++0x184b82fb    mmc_vddrange_to_ocrmask vmlinux EXPORT_SYMBOL
++0x0a67ddd9    dm_suspended    vmlinux EXPORT_SYMBOL_GPL
++0xfc8bcbaf    usb_add_hcd     vmlinux EXPORT_SYMBOL_GPL
++0x965d4e18    tcp_init_congestion_ops vmlinux EXPORT_SYMBOL_GPL
++0xe587559a    skb_push        vmlinux EXPORT_SYMBOL
++0x1a32c5c7    blk_run_queue_async     vmlinux EXPORT_SYMBOL
++0x7fa439cd    simple_rmdir    vmlinux EXPORT_SYMBOL
++0xe6790d49    alloc_file      vmlinux EXPORT_SYMBOL
++0xe8214f7a    free_task       vmlinux EXPORT_SYMBOL
++0x2b9e3380    samsung_dmadev_get_ops  vmlinux EXPORT_SYMBOL
++0x8e671fe0    sdio_f0_writeb  vmlinux EXPORT_SYMBOL_GPL
++0x919b5fa4    device_create   vmlinux EXPORT_SYMBOL_GPL
++0x5cf4fc85    psched_ratecfg_precompute       vmlinux EXPORT_SYMBOL
++0x96573b80    __kfifo_dma_in_finish_r vmlinux EXPORT_SYMBOL
++0xf520f285    sysfs_get       vmlinux EXPORT_SYMBOL_GPL
++0x543ef284    seq_hlist_start vmlinux EXPORT_SYMBOL
++0xbfffc4e0    vb2_read        vmlinux EXPORT_SYMBOL_GPL
++0x45f39483    i2c_del_adapter vmlinux EXPORT_SYMBOL
++0x5838f6c9    rtc_valid_tm    vmlinux EXPORT_SYMBOL
++0xb7a638f3    usb_register_driver     vmlinux EXPORT_SYMBOL_GPL
++0xb83a9297    scsi_block_requests     vmlinux EXPORT_SYMBOL
++0xd5d8b6b8    drm_dp_get_adjust_request_pre_emphasis  vmlinux EXPORT_SYMBOL
++0x99c95fa5    unregister_sound_special        vmlinux EXPORT_SYMBOL
++0x056b6c53    fat_dir_empty   vmlinux EXPORT_SYMBOL_GPL
++0xb51c8891    __getblk        vmlinux EXPORT_SYMBOL
++0x1d9658d5    cdev_alloc      vmlinux EXPORT_SYMBOL
++0x1dd73224    st_sensors_i2c_configure        vmlinux EXPORT_SYMBOL
++0x22379ca8    led_blink_set_oneshot   vmlinux EXPORT_SYMBOL
++0xe7e76d97    mmc_release_host        vmlinux EXPORT_SYMBOL
++0x6e04a077    usb_bind_phy    vmlinux EXPORT_SYMBOL_GPL
++0x47d9cfba    sdev_disable_disk_events        vmlinux EXPORT_SYMBOL
++0x142b8b35    drm_buffer_copy_from_user       vmlinux EXPORT_SYMBOL
++0x55f04c21    trace_buffer_unlock_commit_regs vmlinux EXPORT_SYMBOL_GPL
++0x8c333b2b    usb_hcd_unlink_urb_from_ep      vmlinux EXPORT_SYMBOL_GPL
++0x1fa2251f    device_wakeup_enable    vmlinux EXPORT_SYMBOL_GPL
++0xbbe4496d    dev_warn        vmlinux EXPORT_SYMBOL
++0xab3d1f95    nf_ct_untracked_status_or       vmlinux EXPORT_SYMBOL_GPL
++0x131c2452    snd_jack_set_key        vmlinux EXPORT_SYMBOL
++0x74c134b9    __sw_hweight32  vmlinux EXPORT_SYMBOL
++0x57674fd7    __sw_hweight16  vmlinux EXPORT_SYMBOL
++0x9f46ced8    __sw_hweight64  vmlinux EXPORT_SYMBOL
++0x93215e1d    __kfifo_skip_r  vmlinux EXPORT_SYMBOL
++0x1ec4eb34    flex_array_prealloc     vmlinux EXPORT_SYMBOL
++0x01e6b7fa    get_phy_device  vmlinux EXPORT_SYMBOL
++0x391c17d1    wakeup_source_register  vmlinux EXPORT_SYMBOL_GPL
++0xfe85236b    cpu_user        vmlinux EXPORT_SYMBOL
++0x35e62033    pagevec_lookup_tag      vmlinux EXPORT_SYMBOL
++0x34184afe    current_kernel_time     vmlinux EXPORT_SYMBOL
++0x0eb2ceba    tcp_reno_cong_avoid     vmlinux EXPORT_SYMBOL_GPL
++0x2fce25e3    print_tuple     vmlinux EXPORT_SYMBOL_GPL
++0x62496fbf    snd_soc_dai_set_clkdiv  vmlinux EXPORT_SYMBOL_GPL
++0x7505bdef    memchr_inv      vmlinux EXPORT_SYMBOL
++0x3b21bfec    locks_copy_lock vmlinux EXPORT_SYMBOL
++0xb47a0298    hid_dump_report vmlinux EXPORT_SYMBOL_GPL
++0x391147d1    led_trigger_blink       vmlinux EXPORT_SYMBOL_GPL
++0xb65a6bb8    usb_reset_device        vmlinux EXPORT_SYMBOL_GPL
++0x007b6ccf    gnet_stats_start_copy_compat    vmlinux EXPORT_SYMBOL
++0x7522f3ba    irq_modify_status       vmlinux EXPORT_SYMBOL_GPL
++0xd9052a07    rtc_alarm_irq_enable    vmlinux EXPORT_SYMBOL_GPL
++0xcb6dc422    usb_add_config_only     vmlinux EXPORT_SYMBOL_GPL
++0xd38b2d79    inet6_del_protocol      vmlinux EXPORT_SYMBOL
++0x98b8ddd3    xfrm_input_resume       vmlinux EXPORT_SYMBOL
++0xf71914b4    udplite_prot    vmlinux EXPORT_SYMBOL
++0xdc48464a    sock_create_kern        vmlinux EXPORT_SYMBOL
++0x8260686f    bitmap_find_next_zero_area      vmlinux EXPORT_SYMBOL
++0x354ac8ad    scsi_eh_restore_cmnd    vmlinux EXPORT_SYMBOL
++0x6f988f59    transport_remove_device vmlinux EXPORT_SYMBOL_GPL
++0x600f8836    drm_class_device_register       vmlinux EXPORT_SYMBOL_GPL
++0xd589c1c3    sk_clone_lock   vmlinux EXPORT_SYMBOL_GPL
++0xf8798032    d_find_any_alias        vmlinux EXPORT_SYMBOL
++0x56e4cd15    ftrace_event_reg        vmlinux EXPORT_SYMBOL_GPL
++0xab29d75c    thermal_zone_get_zone_by_name   vmlinux EXPORT_SYMBOL_GPL
++0x2a678a13    __suspend_report_result vmlinux EXPORT_SYMBOL_GPL
++0xe36d12fc    drm_gtf_mode    vmlinux EXPORT_SYMBOL
++0x5a48534a    regulator_count_voltages        vmlinux EXPORT_SYMBOL_GPL
++0x2edb3fd8    sk_attach_filter        vmlinux EXPORT_SYMBOL_GPL
++0x8d107d70    sk_detach_filter        vmlinux EXPORT_SYMBOL_GPL
++0x5da176fe    snd_timer_open  vmlinux EXPORT_SYMBOL
++0xf741c793    zlib_deflateEnd vmlinux EXPORT_SYMBOL
++0x7469fcfe    radix_tree_tagged       vmlinux EXPORT_SYMBOL
++0x57c405a5    unload_nls      vmlinux EXPORT_SYMBOL
++0xcaa97c6a    seq_open_private        vmlinux EXPORT_SYMBOL
++0xf3d2b805    st_sensors_get_buffer_element   vmlinux EXPORT_SYMBOL
++0x82286526    vb2_ioctl_create_bufs   vmlinux EXPORT_SYMBOL_GPL
++0xfb7d95b7    fb_set_cmap     vmlinux EXPORT_SYMBOL
++0xed46d9ec    kernel_listen   vmlinux EXPORT_SYMBOL
++0xb1b16346    snd_jack_set_parent     vmlinux EXPORT_SYMBOL
++0x76bf656d    __bitmap_shift_left     vmlinux EXPORT_SYMBOL
++0x1979065a    serio_unregister_driver vmlinux EXPORT_SYMBOL
++0x3a94c8e6    drm_modeset_lock_all    vmlinux EXPORT_SYMBOL
++0xa093e7da    nat_rtp_rtcp_hook       vmlinux EXPORT_SYMBOL_GPL
++0xe23ae481    blk_iopoll_complete     vmlinux EXPORT_SYMBOL
++0x4f6172ff    crypto_chain    vmlinux EXPORT_SYMBOL_GPL
++0xd66a562b    __scsi_device_lookup    vmlinux EXPORT_SYMBOL
++0x9d669763    memcpy  vmlinux EXPORT_SYMBOL
++0x15c5eea4    ip6t_do_table   vmlinux EXPORT_SYMBOL
++0x6b6533af    bdevname        vmlinux EXPORT_SYMBOL
++0x65d67a20    blk_start_plug  vmlinux EXPORT_SYMBOL
++0xdd686f05    cdev_init       vmlinux EXPORT_SYMBOL
++0xbe63ee40    request_resource        vmlinux EXPORT_SYMBOL
++0xb2018900    inet_getname    vmlinux EXPORT_SYMBOL
++0x01610153    nf_ct_expect_init       vmlinux EXPORT_SYMBOL_GPL
++0x04e1b99f    snd_pcm_std_chmaps      vmlinux EXPORT_SYMBOL_GPL
++0x24a42b51    snd_unregister_oss_device       vmlinux EXPORT_SYMBOL
++0x85e7deb2    iov_iter_fault_in_readable      vmlinux EXPORT_SYMBOL
++0x8f049b6c    module_mutex    vmlinux EXPORT_SYMBOL_GPL
++0x931b242d    regcache_sync   vmlinux EXPORT_SYMBOL_GPL
++0xb95f98d6    _memset_io      vmlinux EXPORT_SYMBOL
++0xa98e796e    modify_user_hw_breakpoint       vmlinux EXPORT_SYMBOL_GPL
++0xbf9bcc8d    __cap_empty_set vmlinux EXPORT_SYMBOL
++0xfba8bb33    dm_get_mapinfo  vmlinux EXPORT_SYMBOL
++0x988ad2a2    rndis_set_param_vendor  vmlinux EXPORT_SYMBOL
++0xb67d6992    usb_ep_autoconfig_reset vmlinux EXPORT_SYMBOL_GPL
++0xfbe5910d    drm_mode_config_init    vmlinux EXPORT_SYMBOL
++0x6443df4e    videomode_from_timings  vmlinux EXPORT_SYMBOL_GPL
++0xad059f21    ip_tunnel_changelink    vmlinux EXPORT_SYMBOL_GPL
++0x2c7fb2d0    crypto_shoot_alg        vmlinux EXPORT_SYMBOL_GPL
++0xac226765    iput    vmlinux EXPORT_SYMBOL
++0x77fe4cb2    sleep_on_timeout        vmlinux EXPORT_SYMBOL
++0x1d88a23f    platform_get_resource   vmlinux EXPORT_SYMBOL_GPL
++0xb95beb55    drm_object_property_set_value   vmlinux EXPORT_SYMBOL
++0x8481713b    pn_sock_unhash  vmlinux EXPORT_SYMBOL
++0x28a82da4    snmp_mib_init   vmlinux EXPORT_SYMBOL_GPL
++0x03fd2571    vm_unmap_ram    vmlinux EXPORT_SYMBOL
++0x65466939    proc_doulongvec_ms_jiffies_minmax       vmlinux EXPORT_SYMBOL
++0x23654452    input_ff_upload vmlinux EXPORT_SYMBOL_GPL
++0x45bda0d5    system_serial_low       vmlinux EXPORT_SYMBOL
++0xa682a886    xfrm_output     vmlinux EXPORT_SYMBOL_GPL
++0xeea9dbaf    bitmap_bitremap vmlinux EXPORT_SYMBOL
++0x71a50dbc    register_blkdev vmlinux EXPORT_SYMBOL
++0x43c0e15b    fuse_sync_release       vmlinux EXPORT_SYMBOL_GPL
++0x972213d1    of_phy_connect  vmlinux EXPORT_SYMBOL
++0x95390328    __fimc_vidioc_querycap  vmlinux EXPORT_SYMBOL
++0xe453b342    ipv6_select_ident       vmlinux EXPORT_SYMBOL
++0xabca477d    nf_conntrack_alter_reply        vmlinux EXPORT_SYMBOL_GPL
++0x72c09e90    neigh_event_ns  vmlinux EXPORT_SYMBOL
++0x32590631    snd_soc_update_bits     vmlinux EXPORT_SYMBOL_GPL
++0xb96df73b    elevator_change vmlinux EXPORT_SYMBOL
++0xa30a6f34    jbd2_journal_blocks_per_page    vmlinux EXPORT_SYMBOL
++0x6103b2f2    iterate_supers_type     vmlinux EXPORT_SYMBOL
++0x0a311e2a    iio_read_channel_processed      vmlinux EXPORT_SYMBOL_GPL
++0x89953a68    sdhci_free_host vmlinux EXPORT_SYMBOL_GPL
++0xb8de0d37    dpm_for_each_dev        vmlinux EXPORT_SYMBOL_GPL
++0xe35ba70f    drm_prime_destroy_file_private  vmlinux EXPORT_SYMBOL
++0x1cb4683d    drm_framebuffer_lookup  vmlinux EXPORT_SYMBOL
++0xbaa9e7e0    fb_firmware_edid        vmlinux EXPORT_SYMBOL
++0xa2ede8b2    nf_queue_entry_get_refs vmlinux EXPORT_SYMBOL_GPL
++0x0ff98044    jump_label_rate_limit   vmlinux EXPORT_SYMBOL_GPL
++0x3fd9109b    v4l2_ctrl_subdev_log_status     vmlinux EXPORT_SYMBOL
++0x78cf4589    usb_kill_anchored_urbs  vmlinux EXPORT_SYMBOL_GPL
++0x3b79aef9    request_firmware_nowait vmlinux EXPORT_SYMBOL
++0xab160376    create_syslog_header    vmlinux EXPORT_SYMBOL
++0x6d42bb18    drm_gem_handle_delete   vmlinux EXPORT_SYMBOL
++0x366d19ef    genericbl_limit_intensity       vmlinux EXPORT_SYMBOL
++0x7380780d    cfg80211_unlink_bss     vmlinux EXPORT_SYMBOL
++0xff6b7f32    netdev_change_features  vmlinux EXPORT_SYMBOL
++0x5613414a    init_dummy_netdev       vmlinux EXPORT_SYMBOL_GPL
++0xbd5cb8b9    ring_buffer_resize      vmlinux EXPORT_SYMBOL_GPL
++0xa55e517c    ip_tunnel_xmit  vmlinux EXPORT_SYMBOL_GPL
++0x3b870a79    dst_destroy     vmlinux EXPORT_SYMBOL
++0xad6b883a    usbnet_get_drvinfo      vmlinux EXPORT_SYMBOL_GPL
++0x5df7a89b    nf_ct_helper_expectfn_unregister        vmlinux EXPORT_SYMBOL_GPL
++0x275ef902    __init_waitqueue_head   vmlinux EXPORT_SYMBOL
++0x472b2841    devm_usb_get_phy        vmlinux EXPORT_SYMBOL_GPL
++0x790d8481    scsi_mode_sense vmlinux EXPORT_SYMBOL
++0x2d89342a    scsi_show_sense_hdr     vmlinux EXPORT_SYMBOL
++0xda7ca6cb    fb_mode_is_equal        vmlinux EXPORT_SYMBOL
++0xdc4798d2    xfrm6_tunnel_register   vmlinux EXPORT_SYMBOL
++0xd587e7b5    xfrm4_tunnel_register   vmlinux EXPORT_SYMBOL
++0x360b01a3    nf_ct_get_tuple vmlinux EXPORT_SYMBOL_GPL
++0x6c74c2ee    blk_insert_cloned_request       vmlinux EXPORT_SYMBOL_GPL
++0x46cb2731    security_sb_set_mnt_opts        vmlinux EXPORT_SYMBOL
++0x1b995ffb    iommu_domain_window_enable      vmlinux EXPORT_SYMBOL_GPL
++0xa4ea04ee    of_property_read_u64    vmlinux EXPORT_SYMBOL_GPL
++0x411e4ef5    brcmu_pktq_pdeq_tail    drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x422d82d0    brcmu_pktq_penq_head    drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x41cc94d0    brcmu_pktq_peek_tail    drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x0c6f118f    nf_nat_icmpv6_reply_translation vmlinux EXPORT_SYMBOL_GPL
++0xa07842c6    skb_copy_datagram_from_iovec    vmlinux EXPORT_SYMBOL
++0xc8269f94    snd_soc_params_to_frame_size    vmlinux EXPORT_SYMBOL_GPL
++0x43eeb6cf    snd_pcm_lib_ioctl       vmlinux EXPORT_SYMBOL
++0x9ac11b74    suspend_set_ops vmlinux EXPORT_SYMBOL_GPL
++0xca16dbe7    regulator_enable        vmlinux EXPORT_SYMBOL_GPL
++0xecc84eb2    dst_alloc       vmlinux EXPORT_SYMBOL
++0xf0f5dbc2    timerqueue_iterate_next vmlinux EXPORT_SYMBOL_GPL
++0xab4a5add    blk_put_queue   vmlinux EXPORT_SYMBOL
++0x11bef8bd    single_release  vmlinux EXPORT_SYMBOL
++0x7aad72c6    get_user_pages  vmlinux EXPORT_SYMBOL
++0x6214aef2    cpufreq_unregister_notifier     vmlinux EXPORT_SYMBOL
++0xe93e49c3    devres_free     vmlinux EXPORT_SYMBOL_GPL
++0xd95fbe77    of_find_backlight_by_node       vmlinux EXPORT_SYMBOL
++0xe3f553d9    ip6_append_data vmlinux EXPORT_SYMBOL_GPL
++0xa108eb4d    sysctl_optmem_max       vmlinux EXPORT_SYMBOL
++0xdc323ca6    jbd2_journal_destroy    vmlinux EXPORT_SYMBOL
++0x3c7a1672    jbd2_journal_restart    vmlinux EXPORT_SYMBOL
++0x9805d460    v4l2_device_register    vmlinux EXPORT_SYMBOL_GPL
++0x1db6d990    display_entity_get_first        vmlinux EXPORT_SYMBOL
++0xe57878a1    in6_pton        vmlinux EXPORT_SYMBOL
++0xaccabc6a    in4_pton        vmlinux EXPORT_SYMBOL
++0xd0181f4f    __bitmap_xor    vmlinux EXPORT_SYMBOL
++0x208c317e    mnt_want_write  vmlinux EXPORT_SYMBOL_GPL
++0xbcdedba7    of_get_mac_address      vmlinux EXPORT_SYMBOL
++0x859bbb79    scsi_mode_select        vmlinux EXPORT_SYMBOL_GPL
++0x48991892    cfb_copyarea    vmlinux EXPORT_SYMBOL
++0x2455c156    __clear_user    vmlinux EXPORT_SYMBOL
++0x42c7d35b    __dev_remove_pack       vmlinux EXPORT_SYMBOL
++0x465cab34    secure_ipv6_port_ephemeral      vmlinux EXPORT_SYMBOL
++0x5ddbac94    config_group_init       vmlinux EXPORT_SYMBOL
++0x773c1fdc    posix_acl_to_xattr      vmlinux EXPORT_SYMBOL
++0xb18429eb    suspend_device_irqs     vmlinux EXPORT_SYMBOL_GPL
++0x50c52151    _raw_write_unlock_irq   vmlinux EXPORT_SYMBOL
++0xf5bc65a3    iommu_unmap     vmlinux EXPORT_SYMBOL_GPL
++0x710e2b07    tcf_hash_insert vmlinux EXPORT_SYMBOL
++0xf13feb57    radix_tree_next_chunk   vmlinux EXPORT_SYMBOL
++0x90a1004a    crypto_has_alg  vmlinux EXPORT_SYMBOL_GPL
++0x8cd44e50    iget5_locked    vmlinux EXPORT_SYMBOL
++0x3dcb88a0    irq_set_handler_data    vmlinux EXPORT_SYMBOL
++0xaa7de358    yield_to        vmlinux EXPORT_SYMBOL_GPL
++0xc54649ff    __starget_for_each_device       vmlinux EXPORT_SYMBOL
++0x2bd1f745    drm_mode_config_cleanup vmlinux EXPORT_SYMBOL
++0xa1425906    ieee80211_channel_to_frequency  vmlinux EXPORT_SYMBOL
++0x59806cb9    sk_page_frag_refill     vmlinux EXPORT_SYMBOL
++0xce90ef6b    debugfs_create_dir      vmlinux EXPORT_SYMBOL_GPL
++0xa4827144    dcache_dir_lseek        vmlinux EXPORT_SYMBOL
++0x0c2cdbf1    synchronize_sched       vmlinux EXPORT_SYMBOL_GPL
++0x92a9c60c    time_to_tm      vmlinux EXPORT_SYMBOL
++0x651a4139    test_taint      vmlinux EXPORT_SYMBOL
++0x2b66e1b8    mii_check_media vmlinux EXPORT_SYMBOL
++0xfb7d9c45    __udivsi3       vmlinux EXPORT_SYMBOL
++0x633fafc5    netdev_printk   vmlinux EXPORT_SYMBOL
++0xf5a691cd    invalidate_bh_lrus      vmlinux EXPORT_SYMBOL_GPL
++0xe5524eab    of_address_to_resource  vmlinux EXPORT_SYMBOL_GPL
++0xe22f01b0    thermal_zone_device_register    vmlinux EXPORT_SYMBOL_GPL
++0x3fc8bae1    ipcomp_init_state       vmlinux EXPORT_SYMBOL_GPL
++0xf5b5f1ec    xt_check_match  vmlinux EXPORT_SYMBOL_GPL
++0x24aac4d9    crypto_aes_expand_key   vmlinux EXPORT_SYMBOL_GPL
++0x6f798a9c    d_splice_alias  vmlinux EXPORT_SYMBOL
++0x88196936    do_sync_read    vmlinux EXPORT_SYMBOL
++0x4a18707e    mem_map vmlinux EXPORT_SYMBOL
++0x0366307a    console_suspend_enabled vmlinux EXPORT_SYMBOL
++0x204d506e    st_sensors_write_event_value    vmlinux EXPORT_SYMBOL
++0x4c22a54d    usb_ep_autoconfig       vmlinux EXPORT_SYMBOL_GPL
++0x32c3cb4e    class_compat_register   vmlinux EXPORT_SYMBOL_GPL
++0x7b85f6f8    drm_mm_insert_node      vmlinux EXPORT_SYMBOL
++0x78f9b710    nf_ct_l3proto_try_module_get    vmlinux EXPORT_SYMBOL_GPL
++0x44594236    snd_soc_unregister_component    vmlinux EXPORT_SYMBOL_GPL
++0x05e4e6be    register_sound_midi     vmlinux EXPORT_SYMBOL
++0x07341a03    kobject_rename  vmlinux EXPORT_SYMBOL_GPL
++0x35b6b772    param_ops_charp vmlinux EXPORT_SYMBOL
++0xb4c1829e    clk_round_rate  vmlinux EXPORT_SYMBOL_GPL
++0x1bb061cc    sdio_release_irq        vmlinux EXPORT_SYMBOL_GPL
++0xe4c673df    mmc_wait_for_cmd        vmlinux EXPORT_SYMBOL
++0x4d088d1f    drm_mm_replace_node     vmlinux EXPORT_SYMBOL
++0xe24e09b0    cgroup_taskset_cur_cgroup       vmlinux EXPORT_SYMBOL_GPL
++0x7c5cf140    cad_pid vmlinux EXPORT_SYMBOL
++0xaea8b9a5    drm_get_encoder_name    vmlinux EXPORT_SYMBOL
++0xe4c80097    cacheid vmlinux EXPORT_SYMBOL
++0x5a5a94a6    kstrtou8        vmlinux EXPORT_SYMBOL
++0x2b4aa9c9    get_task_pid    vmlinux EXPORT_SYMBOL_GPL
++0x30f43c3b    sdhci_enable_irq_wakeups        vmlinux EXPORT_SYMBOL_GPL
++0x3a6d4f22    rndis_free_response     vmlinux EXPORT_SYMBOL
++0x85478a0b    inet6_hash_frag vmlinux EXPORT_SYMBOL_GPL
++0x0efbc42d    snd_component_add       vmlinux EXPORT_SYMBOL
++0x6605f97f    flex_array_clear        vmlinux EXPORT_SYMBOL
++0x5a7bfe41    crypto_probing_notify   vmlinux EXPORT_SYMBOL_GPL
++0x94fd7214    serial8250_rx_chars     vmlinux EXPORT_SYMBOL_GPL
++0x13a6027a    ip6t_alloc_initial_table        vmlinux EXPORT_SYMBOL_GPL
++0x03a9a7bd    netif_receive_skb       vmlinux EXPORT_SYMBOL
++0xfb6af58d    recalc_sigpending       vmlinux EXPORT_SYMBOL
++0x2d0ea593    spi_new_device  vmlinux EXPORT_SYMBOL_GPL
++0xfbc4e14c    pm_runtime_enable       vmlinux EXPORT_SYMBOL_GPL
++0xc583bf57    of_regulator_match      vmlinux EXPORT_SYMBOL_GPL
++0xebfdcbdf    system_serial_high      vmlinux EXPORT_SYMBOL
++0x28d7fc1f    nf_nat_mangle_udp_packet        vmlinux EXPORT_SYMBOL
++0xf71016b7    snd_soc_dapm_get_pin_status     vmlinux EXPORT_SYMBOL_GPL
++0xf05c8ab1    vb2_get_contig_userptr  vmlinux EXPORT_SYMBOL_GPL
++0xd045db89    nfc_class       vmlinux EXPORT_SYMBOL
++0x606340d3    disk_part_iter_exit     vmlinux EXPORT_SYMBOL_GPL
++0xa1bd7822    __tracepoint_block_bio_complete vmlinux EXPORT_SYMBOL_GPL
++0x16138f6f    follow_down_one vmlinux EXPORT_SYMBOL
++0x7944e0fc    tracing_off     vmlinux EXPORT_SYMBOL_GPL
++0xb1425b32    dm_table_add_target_callbacks   vmlinux EXPORT_SYMBOL_GPL
++0xbdfb8830    anon_transport_class_register   vmlinux EXPORT_SYMBOL_GPL
++0x911d700e    devm_phy_create vmlinux EXPORT_SYMBOL_GPL
++0xeb908d00    raw_seq_next    vmlinux EXPORT_SYMBOL_GPL
++0x30b265dd    ip_setsockopt   vmlinux EXPORT_SYMBOL
++0x9f45de2c    ip_getsockopt   vmlinux EXPORT_SYMBOL
++0x30322337    nf_ct_l3proto_unregister        vmlinux EXPORT_SYMBOL_GPL
++0x8106c2de    nf_ct_l4proto_unregister        vmlinux EXPORT_SYMBOL_GPL
++0x4b015768    snd_iprintf     vmlinux EXPORT_SYMBOL
++0xec728ca6    blk_unprep_request      vmlinux EXPORT_SYMBOL_GPL
++0x0bae62b1    ktime_get_monotonic_offset      vmlinux EXPORT_SYMBOL_GPL
++0x6f8450af    tty_encode_baud_rate    vmlinux EXPORT_SYMBOL_GPL
++0xead6a706    devm_phy_destroy        vmlinux EXPORT_SYMBOL_GPL
++0x2cf3c356    ip6_redirect    vmlinux EXPORT_SYMBOL_GPL
++0x2cdb55d1    ip_options_rcv_srr      vmlinux EXPORT_SYMBOL
++0x105bdf9b    dentry_open     vmlinux EXPORT_SYMBOL
++0x724bf4b2    i2c_bit_add_numbered_bus        vmlinux EXPORT_SYMBOL
++0x2e09263f    usb_copy_descriptors    vmlinux EXPORT_SYMBOL_GPL
++0xbec98305    device_register vmlinux EXPORT_SYMBOL_GPL
++0xff519474    skb_checksum_help       vmlinux EXPORT_SYMBOL
++0x293d87a4    unregister_netdevice_queue      vmlinux EXPORT_SYMBOL
++0xa692560a    snd_soc_lookup_platform vmlinux EXPORT_SYMBOL_GPL
++0x9545af6d    tasklet_init    vmlinux EXPORT_SYMBOL
++0x87374f66    extcon_unregister_interest      vmlinux EXPORT_SYMBOL_GPL
++0x40a27c37    scsi_dev_info_remove_list       vmlinux EXPORT_SYMBOL
++0x42a2164f    regmap_write    vmlinux EXPORT_SYMBOL_GPL
++0xe6f46e6e    drm_clflush_virt_range  vmlinux EXPORT_SYMBOL
++0x17f8217b    nf_nat_setup_info       vmlinux EXPORT_SYMBOL
++0xb3daf4bf    jbd2_journal_get_undo_access    vmlinux EXPORT_SYMBOL
++0xe16591ab    stop_machine    vmlinux EXPORT_SYMBOL_GPL
++0xb6261484    register_die_notifier   vmlinux EXPORT_SYMBOL_GPL
++0x415838be    led_trigger_set_default vmlinux EXPORT_SYMBOL_GPL
++0x843020c0    ip6_find_1stfragopt     vmlinux EXPORT_SYMBOL
++0x062936ed    nf_ct_unlink_expect_report      vmlinux EXPORT_SYMBOL_GPL
++0xa6d16c61    sock_no_recvmsg vmlinux EXPORT_SYMBOL
++0x4b0ac955    hrtimer_cancel  vmlinux EXPORT_SYMBOL_GPL
++0x3626ebf4    xt_unregister_matches   vmlinux EXPORT_SYMBOL
++0x72ea7812    security_inode_setattr  vmlinux EXPORT_SYMBOL_GPL
++0xfdfc0b3b    fiemap_fill_next_extent vmlinux EXPORT_SYMBOL
++0x82d19daa    qdisc_watchdog_cancel   vmlinux EXPORT_SYMBOL
++0xc0581ee5    crypto_shash_digest     vmlinux EXPORT_SYMBOL_GPL
++0x78728b6b    crypto_ahash_digest     vmlinux EXPORT_SYMBOL_GPL
++0x3de9cae1    crypto_remove_final     vmlinux EXPORT_SYMBOL_GPL
++0x31faa864    media_entity_init       vmlinux EXPORT_SYMBOL_GPL
++0xe827112b    rtnl_set_sk_err vmlinux EXPORT_SYMBOL
++0x5b23591f    snd_soc_jack_new        vmlinux EXPORT_SYMBOL_GPL
++0x7b6646bb    _raw_read_lock  vmlinux EXPORT_SYMBOL
++0xd4669fad    complete        vmlinux EXPORT_SYMBOL
++0x488882e7    downgrade_write vmlinux EXPORT_SYMBOL
++0xbaac427c    get_mem_type    vmlinux EXPORT_SYMBOL
++0xc4014b9d    ip_check_defrag vmlinux EXPORT_SYMBOL
++0x6aaccee0    config_item_init_type_name      vmlinux EXPORT_SYMBOL
++0x62822d05    iov_iter_single_seg_count       vmlinux EXPORT_SYMBOL
++0xb1f1a6ea    gether_get_host_addr_u8 vmlinux EXPORT_SYMBOL
++0xf7f652fe    dma_mmap_from_coherent  vmlinux EXPORT_SYMBOL
++0xfa9720a0    rdev_get_dev    vmlinux EXPORT_SYMBOL_GPL
++0x62186db5    brcmu_pkt_buf_get_skb   drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0xf7af6d75    snd_pcm_new_stream      vmlinux EXPORT_SYMBOL
++0x17320c5c    dentry_update_name_case vmlinux EXPORT_SYMBOL
++0x8a7d1c31    high_memory     vmlinux EXPORT_SYMBOL
++0x0186e2de    smp_call_function_many  vmlinux EXPORT_SYMBOL
++0xbdf098ae    scsi_test_unit_ready    vmlinux EXPORT_SYMBOL
++0x119b50e7    elf_check_arch  vmlinux EXPORT_SYMBOL
++0xbf6d5c21    inet6_csk_update_pmtu   vmlinux EXPORT_SYMBOL_GPL
++0x6b9a4457    snd_soc_jack_free_gpios vmlinux EXPORT_SYMBOL_GPL
++0xd28c735f    simple_link     vmlinux EXPORT_SYMBOL
++0xbdd2f42a    rcu_bh_force_quiescent_state    vmlinux EXPORT_SYMBOL_GPL
++0x7a3cd015    v4l2_ctrl_get_menu      vmlinux EXPORT_SYMBOL
++0x97f5694d    page_cache_async_readahead      vmlinux EXPORT_SYMBOL_GPL
++0x2b4e956e    mempool_create  vmlinux EXPORT_SYMBOL
++0x57231f45    ring_buffer_record_on   vmlinux EXPORT_SYMBOL_GPL
++0x8e311007    hidinput_find_field     vmlinux EXPORT_SYMBOL_GPL
++0x7ae1ae8e    cpufreq_frequency_table_put_attr        vmlinux EXPORT_SYMBOL_GPL
++0x6c6a4b95    scsi_remove_target      vmlinux EXPORT_SYMBOL
++0xb6c5a973    scsi_show_result        vmlinux EXPORT_SYMBOL
++0x1ec3bed9    hdmi_audio_infoframe_init       vmlinux EXPORT_SYMBOL
++0x3244dece    kblockd_schedule_work   vmlinux EXPORT_SYMBOL
++0xafac4a33    mem_section     vmlinux EXPORT_SYMBOL
++0xfd044751    send_sig_info   vmlinux EXPORT_SYMBOL
++0xc02cf69b    clkdev_drop     vmlinux EXPORT_SYMBOL
++0x39c95e24    phy_init_eee    vmlinux EXPORT_SYMBOL
++0xfc53eac8    drm_cvt_mode    vmlinux EXPORT_SYMBOL
++0x6a5e6530    __neigh_event_send      vmlinux EXPORT_SYMBOL
++0x6c4d4cfe    sk_stream_wait_close    vmlinux EXPORT_SYMBOL
++0x3d1cdeca    read_cache_page_async   vmlinux EXPORT_SYMBOL
++0xd0ee38b8    schedule_timeout_uninterruptible        vmlinux EXPORT_SYMBOL
++0xd79b5a02    allow_signal    vmlinux EXPORT_SYMBOL
++0xd14fa335    show_class_attr_string  vmlinux EXPORT_SYMBOL_GPL
++0xacb2a583    ndo_dflt_fdb_add        vmlinux EXPORT_SYMBOL
++0x49a39542    snd_timer_global_register       vmlinux EXPORT_SYMBOL
++0x63407037    kill_anon_super vmlinux EXPORT_SYMBOL
++0xdc2b4205    platform_get_irq        vmlinux EXPORT_SYMBOL_GPL
++0xc777ecaa    xfrm6_rcv       vmlinux EXPORT_SYMBOL
++0x2fee3a7e    xfrm4_rcv       vmlinux EXPORT_SYMBOL
++0xe94fef47    nf_ct_delete_from_lists vmlinux EXPORT_SYMBOL_GPL
++0x6d466653    snd_soc_unregister_platform     vmlinux EXPORT_SYMBOL_GPL
++0xb61a0c3b    bt_err  vmlinux EXPORT_SYMBOL
++0x79536600    snd_soc_dpcm_can_be_params      vmlinux EXPORT_SYMBOL_GPL
++0x016c4bc3    cfg80211_put_bss        vmlinux EXPORT_SYMBOL
++0x90922aec    inet_dgram_connect      vmlinux EXPORT_SYMBOL
++0x103ea6ec    generic_pipe_buf_steal  vmlinux EXPORT_SYMBOL
++0x5fe77756    generic_pipe_buf_unmap  vmlinux EXPORT_SYMBOL
++0xe5d95985    param_ops_ulong vmlinux EXPORT_SYMBOL
++0xb03c01e8    dbs_check_cpu   vmlinux EXPORT_SYMBOL_GPL
++0xff15acd6    usb_put_function_instance       vmlinux EXPORT_SYMBOL_GPL
++0x6406cdf0    usb_find_alt_setting    vmlinux EXPORT_SYMBOL_GPL
++0x4626bf6d    phy_connect     vmlinux EXPORT_SYMBOL
++0x7a9326c6    driver_unregister       vmlinux EXPORT_SYMBOL_GPL
++0xc5570382    inet_frags_exit_net     vmlinux EXPORT_SYMBOL
++0x08216276    kobject_get     vmlinux EXPORT_SYMBOL
++0x006818a5    kobject_put     vmlinux EXPORT_SYMBOL
++0x37b777df    param_set_copystring    vmlinux EXPORT_SYMBOL
++0x54f21cff    __send_remote_softirq   vmlinux EXPORT_SYMBOL
++0x7a925833    cpufreq_get_global_kobject      vmlinux EXPORT_SYMBOL
++0x2c900d91    cpufreq_put_global_kobject      vmlinux EXPORT_SYMBOL
++0xbac4a225    v4l2_ctrl_fill  vmlinux EXPORT_SYMBOL
++0xf7e6e534    v4l2_ctrl_find  vmlinux EXPORT_SYMBOL
++0xbc5671dc    v4l_printk_ioctl        vmlinux EXPORT_SYMBOL
++0x17021c93    drm_i2c_encoder_commit  vmlinux EXPORT_SYMBOL
++0x10e70fd2    display_entity_get_modes        vmlinux EXPORT_SYMBOL_GPL
++0xf1deabf2    div64_u64       vmlinux EXPORT_SYMBOL
++0x2488515b    vb2_put_vma     vmlinux EXPORT_SYMBOL_GPL
++0xd2ea2134    usb_descriptor_fillbuf  vmlinux EXPORT_SYMBOL_GPL
++0xdacd26c5    usb_scuttle_anchored_urbs       vmlinux EXPORT_SYMBOL_GPL
++0xfc39e32f    ioport_unmap    vmlinux EXPORT_SYMBOL
++0x348998d3    sysfs_merge_group       vmlinux EXPORT_SYMBOL_GPL
++0xc84a0a7e    seq_hlist_start_rcu     vmlinux EXPORT_SYMBOL
++0xdd51deeb    d_validate      vmlinux EXPORT_SYMBOL
++0x88ea60db    __get_user_pages_fast   vmlinux EXPORT_SYMBOL_GPL
++0xe9bff861    down_trylock    vmlinux EXPORT_SYMBOL
++0xff9e0620    usb_reset_configuration vmlinux EXPORT_SYMBOL_GPL
++0x00130217    pwm_free        vmlinux EXPORT_SYMBOL_GPL
++0x8fedcd53    snd_soc_info_xr_sx      vmlinux EXPORT_SYMBOL_GPL
++0xc256e762    __bitmap_equal  vmlinux EXPORT_SYMBOL
++0x7d4e2276    __init_rwsem    vmlinux EXPORT_SYMBOL
++0xee5a877d    page_zero_new_buffers   vmlinux EXPORT_SYMBOL
++0x96710252    mntget  vmlinux EXPORT_SYMBOL
++0xe85c78e2    mntput  vmlinux EXPORT_SYMBOL
++0x038e97d3    fasync_helper   vmlinux EXPORT_SYMBOL
++0xf75c7d80    wm8994_mic_detect       vmlinux EXPORT_SYMBOL_GPL
++0x2f4113a2    dcookie_register        vmlinux EXPORT_SYMBOL_GPL
++0xce37be95    locks_mandatory_area    vmlinux EXPORT_SYMBOL
++0x8be294cd    iommu_domain_free       vmlinux EXPORT_SYMBOL_GPL
++0x23b5b8d1    exynos_drm_subdrv_register      vmlinux EXPORT_SYMBOL_GPL
++0x6867f405    inet_twsk_deschedule    vmlinux EXPORT_SYMBOL
++0x244e2178    xt_table_unlock vmlinux EXPORT_SYMBOL_GPL
++0x52b9d131    tcf_exts_dump_stats     vmlinux EXPORT_SYMBOL
++0x48bb9eb5    sock_alloc_send_pskb    vmlinux EXPORT_SYMBOL
++0x757206d5    wm_hubs_spkmix_tlv      vmlinux EXPORT_SYMBOL_GPL
++0x0acb1a3c    __bitmap_shift_right    vmlinux EXPORT_SYMBOL
++0xaaa918c9    ftrace_dump     vmlinux EXPORT_SYMBOL_GPL
++0x402b8281    __request_module        vmlinux EXPORT_SYMBOL
++0xe944ba87    st_sensors_set_axis_enable      vmlinux EXPORT_SYMBOL
++0x822f9003    inet_register_protosw   vmlinux EXPORT_SYMBOL
++0xbe3a4f06    __inet_inherit_port     vmlinux EXPORT_SYMBOL_GPL
++0xb63f16de    dev_deactivate  vmlinux EXPORT_SYMBOL
++0xa014da84    snd_soc_add_platform_controls   vmlinux EXPORT_SYMBOL_GPL
++0xeaaee9e6    submit_bio_wait vmlinux EXPORT_SYMBOL
++0x23fd3028    vmalloc_node    vmlinux EXPORT_SYMBOL
++0xa58fea9d    mempool_destroy vmlinux EXPORT_SYMBOL
++0x054e550b    kernel_halt     vmlinux EXPORT_SYMBOL_GPL
++0xf4c770ec    v4l2_clk_disable        vmlinux EXPORT_SYMBOL
++0xd597e74e    phy_find_first  vmlinux EXPORT_SYMBOL
++0x50621015    xfrm6_tunnel_spi_lookup vmlinux EXPORT_SYMBOL
++0xc0f8a5b0    set_binfmt      vmlinux EXPORT_SYMBOL
++0x36075bb5    iommu_group_register_notifier   vmlinux EXPORT_SYMBOL_GPL
++0x93b8b0d3    scsi_ioctl      vmlinux EXPORT_SYMBOL
++0xd0dcdd90    drm_mm_insert_node_in_range_generic     vmlinux EXPORT_SYMBOL
++0xb2eaff96    km_policy_expired       vmlinux EXPORT_SYMBOL
++0xa9effda5    __first_cpu     vmlinux EXPORT_SYMBOL
++0xc24ba3ed    elv_rb_find     vmlinux EXPORT_SYMBOL
++0xf0619801    timekeeping_clocktai    vmlinux EXPORT_SYMBOL
++0x9e4faeef    dm_io_client_destroy    vmlinux EXPORT_SYMBOL
++0x95cbb942    usb_add_gadget_udc_release      vmlinux EXPORT_SYMBOL_GPL
++0x14c3db3e    spi_unregister_master   vmlinux EXPORT_SYMBOL_GPL
++0xbee90f2f    __kfifo_out_peek_r      vmlinux EXPORT_SYMBOL
++0x2869ebaf    regulator_bulk_force_disable    vmlinux EXPORT_SYMBOL_GPL
++0xa04a01bd    qdisc_class_hash_insert vmlinux EXPORT_SYMBOL
++0x43a261a8    eth_commit_mac_addr_change      vmlinux EXPORT_SYMBOL
++0xe5867808    dlci_ioctl_set  vmlinux EXPORT_SYMBOL
++0xbae6da94    crypto_alg_lookup       vmlinux EXPORT_SYMBOL_GPL
++0x330d748a    v4l2_subdev_init        vmlinux EXPORT_SYMBOL
++0xc6ff1a7d    phonet_header_ops       vmlinux EXPORT_SYMBOL
++0xfaefacf3    locks_free_lock vmlinux EXPORT_SYMBOL
++0xcbfa0b41    scsi_report_device_reset        vmlinux EXPORT_SYMBOL
++0xbe1e4cd0    scsi_print_sense        vmlinux EXPORT_SYMBOL
++0xe87ed821    drm_mode_create_dirty_info_property     vmlinux EXPORT_SYMBOL
++0xb6d97288    inet6_add_offload       vmlinux EXPORT_SYMBOL
++0xa681ec81    snd_soc_jack_notifier_register  vmlinux EXPORT_SYMBOL_GPL
++0xd64b88b6    register_sound_mixer    vmlinux EXPORT_SYMBOL
++0x02701efc    simple_attr_release     vmlinux EXPORT_SYMBOL_GPL
++0xf6e04730    event_storage   vmlinux EXPORT_SYMBOL_GPL
++0x95b5af62    mmc_regulator_set_ocr   vmlinux EXPORT_SYMBOL_GPL
++0x77e78218    regulator_allow_bypass  vmlinux EXPORT_SYMBOL_GPL
++0xf1070592    cfg80211_wext_giwretry  vmlinux EXPORT_SYMBOL_GPL
++0x8a0f4230    rename_lock     vmlinux EXPORT_SYMBOL
++0xda259c5d    page_symlink_inode_operations   vmlinux EXPORT_SYMBOL
++0x8bd0a3fd    _raw_write_unlock_bh    vmlinux EXPORT_SYMBOL
++0x99b0f1ff    usb_submit_urb  vmlinux EXPORT_SYMBOL_GPL
++0x1fbd16da    ip_tos2prio     vmlinux EXPORT_SYMBOL
++0x060ea2d6    kstrtoull       vmlinux EXPORT_SYMBOL
++0x5ac15bae    kstrtou16       vmlinux EXPORT_SYMBOL
++0x1998d8b6    jbd2_inode_cache        vmlinux EXPORT_SYMBOL
++0x94961283    vunmap  vmlinux EXPORT_SYMBOL
++0x74c4a01e    write_cache_pages       vmlinux EXPORT_SYMBOL
++0xc1ddc02b    pinctrl_register        vmlinux EXPORT_SYMBOL_GPL
++0x0ca54fee    _test_and_set_bit       vmlinux EXPORT_SYMBOL
++0x80dfa464    xfrm_policy_alloc       vmlinux EXPORT_SYMBOL
++0xd04f8eb6    nf_conntrack_l4proto_tcp6       vmlinux EXPORT_SYMBOL_GPL
++0xcf28b516    finish_open     vmlinux EXPORT_SYMBOL
++0x10f734ff    led_blink_set   vmlinux EXPORT_SYMBOL
++0xc9086110    dw_mci_pltfm_remove     vmlinux EXPORT_SYMBOL_GPL
++0xe5c78a99    do_blank_screen vmlinux EXPORT_SYMBOL
++0xf17c6528    cfg80211_remain_on_channel_expired      vmlinux EXPORT_SYMBOL
++0x117093be    qdisc_class_hash_init   vmlinux EXPORT_SYMBOL
++0x13e6a1a2    sk_prot_clear_portaddr_nulls    vmlinux EXPORT_SYMBOL
++0xa2a2d730    task_current_syscall    vmlinux EXPORT_SYMBOL_GPL
++0x4411c503    prandom_seed    vmlinux EXPORT_SYMBOL
++0x547ba3f6    single_open_net vmlinux EXPORT_SYMBOL_GPL
++0xb9012717    set_page_dirty_lock     vmlinux EXPORT_SYMBOL
++0x9a37cbf4    tcp_v4_conn_request     vmlinux EXPORT_SYMBOL
++0xc81ae040    snd_soc_codec_volatile_register vmlinux EXPORT_SYMBOL_GPL
++0xbe52317a    blk_rq_init     vmlinux EXPORT_SYMBOL
++0x9ef34ad4    cpufreq_frequency_table_cpuinfo vmlinux EXPORT_SYMBOL_GPL
++0x5bcf159d    usb_get_descriptor      vmlinux EXPORT_SYMBOL_GPL
++0xf2e5cabe    spi_async_locked        vmlinux EXPORT_SYMBOL_GPL
++0x26e76fb8    sysctl_udp_wmem_min     vmlinux EXPORT_SYMBOL
++0x1fb12a69    tcp_v4_syn_recv_sock    vmlinux EXPORT_SYMBOL
++0x6d464175    __sg_free_table vmlinux EXPORT_SYMBOL
++0x59056c08    kmem_cache_shrink       vmlinux EXPORT_SYMBOL
++0xc3aef602    usb_put_dev     vmlinux EXPORT_SYMBOL_GPL
++0x520a3baf    drm_vm_open_locked      vmlinux EXPORT_SYMBOL_GPL
++0x711a004a    drm_dp_link_rate_to_bw_code     vmlinux EXPORT_SYMBOL
++0x919029aa    __readwrite_bug vmlinux EXPORT_SYMBOL
++0x49045426    icmp_err_convert        vmlinux EXPORT_SYMBOL
++0xf087137d    __dynamic_pr_debug      vmlinux EXPORT_SYMBOL
++0x1e5b03dc    pm_qos_add_notifier     vmlinux EXPORT_SYMBOL_GPL
++0x5e9d9e1e    gov_queue_work  vmlinux EXPORT_SYMBOL_GPL
++0x601f665f    dm_io_client_create     vmlinux EXPORT_SYMBOL
++0x05c311c2    vb2_ioctl_prepare_buf   vmlinux EXPORT_SYMBOL_GPL
++0x14f62d2b    mii_check_link  vmlinux EXPORT_SYMBOL
++0x36c69db7    dma_common_mmap vmlinux EXPORT_SYMBOL
++0x1072a394    csum_partial_copy_from_user     vmlinux EXPORT_SYMBOL
++0x3f878645    inet_diag_dump_one_icsk vmlinux EXPORT_SYMBOL_GPL
++0xd7b85107    tcp_hashinfo    vmlinux EXPORT_SYMBOL
++0x2d140a58    genl_unlock     vmlinux EXPORT_SYMBOL
++0xeed1b62f    crypto_aead_setauthsize vmlinux EXPORT_SYMBOL_GPL
++0x5f7bdc58    fd_install      vmlinux EXPORT_SYMBOL
++0xe11f3cbc    _raw_read_lock_bh       vmlinux EXPORT_SYMBOL
++0x3fd55724    of_n_size_cells vmlinux EXPORT_SYMBOL
++0xd17aae7c    hid_report_raw_event    vmlinux EXPORT_SYMBOL_GPL
++0xe469207d    scsi_unregister vmlinux EXPORT_SYMBOL
++0xbf5da77e    dma_buf_begin_cpu_access        vmlinux EXPORT_SYMBOL_GPL
++0x47ed7ca1    inet6_unregister_icmp_sender    vmlinux EXPORT_SYMBOL
++0xed8b1ab6    nf_nat_used_tuple       vmlinux EXPORT_SYMBOL
++0x46e928cf    nf_nat_packet   vmlinux EXPORT_SYMBOL_GPL
++0xdc854ee4    blk_init_tags   vmlinux EXPORT_SYMBOL
++0x4b134056    vfs_fsync_range vmlinux EXPORT_SYMBOL
++0x3ce4ca6f    disable_irq     vmlinux EXPORT_SYMBOL
++0xdc9fa232    raw_notifier_chain_register     vmlinux EXPORT_SYMBOL_GPL
++0x2b0d15d8    scsi_internal_device_unblock    vmlinux EXPORT_SYMBOL_GPL
++0x09d12bc0    sysfs_remove_file       vmlinux EXPORT_SYMBOL_GPL
++0x85a8465a    path_put        vmlinux EXPORT_SYMBOL
++0xe0dec72b    apply_to_page_range     vmlinux EXPORT_SYMBOL_GPL
++0xa0ceef51    out_of_line_wait_on_bit vmlinux EXPORT_SYMBOL
++0x7f04e7d5    dm_set_target_max_io_len        vmlinux EXPORT_SYMBOL_GPL
++0x84a26155    v4l2_ctrl_g_ctrl        vmlinux EXPORT_SYMBOL
++0x1254f0e4    scsi_host_alloc vmlinux EXPORT_SYMBOL
++0x0e09444b    bus_get_device_klist    vmlinux EXPORT_SYMBOL_GPL
++0xbebc3cd2    dst_discard     vmlinux EXPORT_SYMBOL
++0x8d25ae30    snd_soc_dapm_put_value_enum_double      vmlinux EXPORT_SYMBOL_GPL
++0x8d02ccf1    snd_soc_dapm_get_value_enum_double      vmlinux EXPORT_SYMBOL_GPL
++0xaa2a72bf    __iowrite64_copy        vmlinux EXPORT_SYMBOL_GPL
++0x373d62c5    invalidate_partition    vmlinux EXPORT_SYMBOL
++0xd217e9e6    trace_set_clr_event     vmlinux EXPORT_SYMBOL_GPL
++0x00e86db4    kick_process    vmlinux EXPORT_SYMBOL_GPL
++0xa625110d    kmsg_dump_rewind        vmlinux EXPORT_SYMBOL_GPL
++0x17eb0eee    v4l2_m2m_init   vmlinux EXPORT_SYMBOL_GPL
++0xd153a267    drm_irq_uninstall       vmlinux EXPORT_SYMBOL
++0x6ccf7bd7    __pv_phys_offset        vmlinux EXPORT_SYMBOL
++0x6cf45a72    sk_release_kernel       vmlinux EXPORT_SYMBOL
++0x7cff72b3    sg_miter_stop   vmlinux EXPORT_SYMBOL
++0x0da10ec3    security_sock_graft     vmlinux EXPORT_SYMBOL
++0xe601743b    jbd2_journal_init_jbd_inode     vmlinux EXPORT_SYMBOL
++0xdd3916ac    _raw_spin_unlock_bh     vmlinux EXPORT_SYMBOL
++0xb5ab5fe9    usb_function_register   vmlinux EXPORT_SYMBOL_GPL
++0xa20bbbd7    xt_proto_init   vmlinux EXPORT_SYMBOL_GPL
++0x13b715e2    blk_finish_plug vmlinux EXPORT_SYMBOL
++0x0b1beb31    vmalloc_32_user vmlinux EXPORT_SYMBOL
++0x85dfe0aa    fget_light      vmlinux EXPORT_SYMBOL
++0x8bebc4a8    drm_master_put  vmlinux EXPORT_SYMBOL
++0xf073bd48    nfc_hci_target_discovered       vmlinux EXPORT_SYMBOL
++0x878ab3ce    sysctl_tcp_adv_win_scale        vmlinux EXPORT_SYMBOL
++0x11e11bef    ip_local_out    vmlinux EXPORT_SYMBOL_GPL
++0xafe96047    generic_permission      vmlinux EXPORT_SYMBOL
++0x96123b65    iio_trigger_unregister  vmlinux EXPORT_SYMBOL
++0xf7b01b50    gether_get_host_addr_cdc        vmlinux EXPORT_SYMBOL
++0x3324e6d2    ehci_suspend    vmlinux EXPORT_SYMBOL_GPL
++0x7ef61596    usb_hcd_check_unlink_urb        vmlinux EXPORT_SYMBOL_GPL
++0x7ced7048    phy_device_free vmlinux EXPORT_SYMBOL
++0x9afda3df    regcache_cache_bypass   vmlinux EXPORT_SYMBOL_GPL
++0xd59668e6    unlock_flocks   vmlinux EXPORT_SYMBOL_GPL
++0xb818e055    usbnet_open     vmlinux EXPORT_SYMBOL_GPL
++0x4683093b    snd_ctl_notify  vmlinux EXPORT_SYMBOL
++0x9d3aa376    blk_iopoll_init vmlinux EXPORT_SYMBOL
++0x226a674d    atomic_notifier_chain_unregister        vmlinux EXPORT_SYMBOL_GPL
++0x0144d325    regmap_async_complete   vmlinux EXPORT_SYMBOL_GPL
++0x27f4cbdb    uart_get_baud_rate      vmlinux EXPORT_SYMBOL
++0x878175c4    secpath_dup     vmlinux EXPORT_SYMBOL
++0x7931d788    snd_pcm_hw_constraint_step      vmlinux EXPORT_SYMBOL
++0x36170e28    set_user_nice   vmlinux EXPORT_SYMBOL
++0x45de06d1    iio_buffer_write_length vmlinux EXPORT_SYMBOL
++0x5babbf10    media_device_unregister_entity  vmlinux EXPORT_SYMBOL_GPL
++0xe593d0c8    usbnet_disconnect       vmlinux EXPORT_SYMBOL_GPL
++0xb7e8ce46    exynos_drm_subdrv_close vmlinux EXPORT_SYMBOL_GPL
++0xc29dc1ad    drm_framebuffer_init    vmlinux EXPORT_SYMBOL
++0x7fe1a403    cfg80211_find_ie        vmlinux EXPORT_SYMBOL
++0xa8469c88    netdev_notify_peers     vmlinux EXPORT_SYMBOL
++0xe81978c6    splice_direct_to_actor  vmlinux EXPORT_SYMBOL
++0xb5cb8145    hrtimer_get_res vmlinux EXPORT_SYMBOL_GPL
++0x9a70b0fd    nf_nat_pptp_hook_inbound        vmlinux EXPORT_SYMBOL_GPL
++0x2b9da7a4    genl_lock       vmlinux EXPORT_SYMBOL
++0xb72e58d6    qdisc_class_hash_grow   vmlinux EXPORT_SYMBOL
++0x0e59e8cf    sock_setsockopt vmlinux EXPORT_SYMBOL
++0x20df2681    ida_simple_remove       vmlinux EXPORT_SYMBOL
++0xbdef23a2    unlock_buffer   vmlinux EXPORT_SYMBOL
++0x3b231b68    simple_transaction_release      vmlinux EXPORT_SYMBOL
++0xad098b64    usb_unlocked_enable_lpm vmlinux EXPORT_SYMBOL_GPL
++0x4b05e7ed    tty_port_close_start    vmlinux EXPORT_SYMBOL
++0x14789075    dma_find_channel        vmlinux EXPORT_SYMBOL
++0x77c05b09    fb_find_mode    vmlinux EXPORT_SYMBOL
++0x01010c6d    klist_add_before        vmlinux EXPORT_SYMBOL_GPL
++0x292c29ad    nfulnl_log_packet       vmlinux EXPORT_SYMBOL_GPL
++0x521b36b5    qdisc_put_rtab  vmlinux EXPORT_SYMBOL
++0x69c66f79    crypto_attr_alg2        vmlinux EXPORT_SYMBOL_GPL
++0x341dbfa3    __per_cpu_offset        vmlinux EXPORT_SYMBOL
++0x8953f8ff    __tracepoint_kmem_cache_alloc   vmlinux EXPORT_SYMBOL
++0x7e0ef97c    regmap_irq_get_domain   vmlinux EXPORT_SYMBOL_GPL
++0x437ff921    subsys_find_device_by_id        vmlinux EXPORT_SYMBOL_GPL
++0x975e0663    set_sig_addr_hook       vmlinux EXPORT_SYMBOL_GPL
++0xe86f0da8    proto_register  vmlinux EXPORT_SYMBOL
++0xb838d98e    event_storage_mutex     vmlinux EXPORT_SYMBOL_GPL
++0x9ca1dc35    vb2_fop_mmap    vmlinux EXPORT_SYMBOL_GPL
++0xde1a5959    rtc_irq_unregister      vmlinux EXPORT_SYMBOL_GPL
++0xbeca75ff    drm_crtc_helper_set_mode        vmlinux EXPORT_SYMBOL
++0x65f850bc    tty_wakeup      vmlinux EXPORT_SYMBOL_GPL
++0xf4743f88    amba_ahb_device_add     vmlinux EXPORT_SYMBOL_GPL
++0xa994f545    check_disk_size_change  vmlinux EXPORT_SYMBOL
++0x455293f6    down_read       vmlinux EXPORT_SYMBOL
++0x7eaf8e7a    v4l2_detect_gtf vmlinux EXPORT_SYMBOL_GPL
++0x53105839    v4l2_detect_cvt vmlinux EXPORT_SYMBOL_GPL
++0x6a41ea71    v4l2_clk_get_rate       vmlinux EXPORT_SYMBOL
++0xc50c3f79    v4l2_clk_set_rate       vmlinux EXPORT_SYMBOL
++0x52bc9e2a    drm_plane_cleanup       vmlinux EXPORT_SYMBOL
++0x0d4cb82a    km_report       vmlinux EXPORT_SYMBOL
++0xcffe8e42    __napi_complete vmlinux EXPORT_SYMBOL
++0xb17c5844    skb_copy_expand vmlinux EXPORT_SYMBOL
++0xaaaa5788    blk_queue_softirq_done  vmlinux EXPORT_SYMBOL
++0x43a762e5    d_lookup        vmlinux EXPORT_SYMBOL
++0xebc525f4    iio_triggered_buffer_cleanup    vmlinux EXPORT_SYMBOL
++0xabd0c91c    rtc_time_to_tm  vmlinux EXPORT_SYMBOL
++0x70f3f9b2    dmam_free_coherent      vmlinux EXPORT_SYMBOL
++0xba361646    transport_setup_device  vmlinux EXPORT_SYMBOL_GPL
++0x950ee7d1    fb_find_logo    vmlinux EXPORT_SYMBOL_GPL
++0x20294ce8    genl_unregister_mc_group        vmlinux EXPORT_SYMBOL
++0x1d7aabfd    path_is_under   vmlinux EXPORT_SYMBOL
++0x17975413    iio_map_array_register  vmlinux EXPORT_SYMBOL_GPL
++0xf811e69d    scsi_eh_flush_done_q    vmlinux EXPORT_SYMBOL
++0x8b95a59f    xt_hook_unlink  vmlinux EXPORT_SYMBOL_GPL
++0x557cb7c6    skb_morph       vmlinux EXPORT_SYMBOL_GPL
++0x02ef742b    percpu_counter_set      vmlinux EXPORT_SYMBOL
++0x03ae21fb    mmc_erase       vmlinux EXPORT_SYMBOL
++0x7c46233a    cpufreq_quick_get       vmlinux EXPORT_SYMBOL
++0xa4f8a168    dm_underlying_device_busy       vmlinux EXPORT_SYMBOL_GPL
++0x1d41eadc    v4l2_ctrl_s_ctrl        vmlinux EXPORT_SYMBOL
++0xa11295ab    serio_unregister_port   vmlinux EXPORT_SYMBOL
++0x11065515    drm_mode_equal  vmlinux EXPORT_SYMBOL
++0x4c47ec15    klist_add_head  vmlinux EXPORT_SYMBOL_GPL
++0x68a24153    snd_pcm_format_physical_width   vmlinux EXPORT_SYMBOL
++0xb6822a33    radix_tree_gang_lookup_tag      vmlinux EXPORT_SYMBOL
++0xdaa16b82    of_clk_get      vmlinux EXPORT_SYMBOL
++0x5c625801    scsi_remove_host        vmlinux EXPORT_SYMBOL
++0xa7de1327    flush_dcache_page       vmlinux EXPORT_SYMBOL
++0x2d6507b5    _find_next_zero_bit_le  vmlinux EXPORT_SYMBOL
++0xf26e1c06    snd_soc_suspend vmlinux EXPORT_SYMBOL_GPL
++0xc213a12a    devm_ioremap_nocache    vmlinux EXPORT_SYMBOL
++0xb43a5300    sync_dirty_buffer       vmlinux EXPORT_SYMBOL
++0xd303fa4e    clk_notifier_unregister vmlinux EXPORT_SYMBOL_GPL
++0x496c3d67    v4l2_querymenu  vmlinux EXPORT_SYMBOL
++0x02b44bb5    scsi_is_host_device     vmlinux EXPORT_SYMBOL
++0x91c9a325    bt_to_errno     vmlinux EXPORT_SYMBOL
++0x86a85b06    tcp_reno_ssthresh       vmlinux EXPORT_SYMBOL_GPL
++0xfc5c6b3e    netlink_has_listeners   vmlinux EXPORT_SYMBOL_GPL
++0xe075d6eb    iter_div_u64_rem        vmlinux EXPORT_SYMBOL
++0xcf0e08ad    filter_current_check_discard    vmlinux EXPORT_SYMBOL_GPL
++0x5afb47fc    of_irq_to_resource_table        vmlinux EXPORT_SYMBOL_GPL
++0xf1421d13    drm_mode_sort   vmlinux EXPORT_SYMBOL
++0xd06ec95f    dma_supported   vmlinux EXPORT_SYMBOL
++0xf1b80226    nf_nat_seq_adjust_hook  vmlinux EXPORT_SYMBOL_GPL
++0xf4c02b65    inode_init_once vmlinux EXPORT_SYMBOL
++0x369fcd70    tracing_snapshot        vmlinux EXPORT_SYMBOL_GPL
++0x73d69364    ring_buffer_change_overwrite    vmlinux EXPORT_SYMBOL_GPL
++0x339d542a    __srcu_notifier_call_chain      vmlinux EXPORT_SYMBOL_GPL
++0xe2d3d0b9    v4l2_ctrl_sub_ev_ops    vmlinux EXPORT_SYMBOL
++0xee129bef    usb_alloc_urb   vmlinux EXPORT_SYMBOL_GPL
++0x64a127a3    spi_setup       vmlinux EXPORT_SYMBOL_GPL
++0x3a8da0aa    nf_ip6_checksum vmlinux EXPORT_SYMBOL
++0xb46a6cbb    scsi_cmd_ioctl  vmlinux EXPORT_SYMBOL
++0xf7d52055    iio_bus_type    vmlinux EXPORT_SYMBOL
++0x75b9f8b8    device_move     vmlinux EXPORT_SYMBOL_GPL
++0x34dc9b87    neigh_seq_stop  vmlinux EXPORT_SYMBOL
++0x82b802b2    snd_soc_dai_set_pll     vmlinux EXPORT_SYMBOL_GPL
++0x0f4c91ed    ns_to_timespec  vmlinux EXPORT_SYMBOL
++0xca34e63d    iio_triggered_buffer_postenable vmlinux EXPORT_SYMBOL
++0x8d3ecd41    drm_core_ioremapfree    vmlinux EXPORT_SYMBOL
++0xed93f29e    __kunmap_atomic vmlinux EXPORT_SYMBOL
++0xe7cd755a    nf_ct_dying_timeout     vmlinux EXPORT_SYMBOL_GPL
++0xe5452cbf    dev_mc_del_global       vmlinux EXPORT_SYMBOL
++0x1a77ed38    dev_mc_add_global       vmlinux EXPORT_SYMBOL
++0x7b4901f5    snd_soc_add_platform    vmlinux EXPORT_SYMBOL_GPL
++0xdff7c9ce    blocking_notifier_chain_unregister      vmlinux EXPORT_SYMBOL_GPL
++0x346127a7    drm_global_item_ref     vmlinux EXPORT_SYMBOL
++0xf763bb6d    drm_framebuffer_cleanup vmlinux EXPORT_SYMBOL
++0x4a6b641b    fifo_create_dflt        vmlinux EXPORT_SYMBOL
++0x3a39f5ed    neigh_table_init        vmlinux EXPORT_SYMBOL
++0xc7207cfe    blk_queue_segment_boundary      vmlinux EXPORT_SYMBOL
++0x183b1236    blk_stop_queue  vmlinux EXPORT_SYMBOL
++0x632b18ed    blkcipher_walk_virt_block       vmlinux EXPORT_SYMBOL_GPL
++0x68ecff32    sysfs_create_link       vmlinux EXPORT_SYMBOL_GPL
++0x2bc64f3b    task_active_pid_ns      vmlinux EXPORT_SYMBOL_GPL
++0xda83d7a1    mmc_register_driver     vmlinux EXPORT_SYMBOL
++0x85e9caff    exynos4x12_cpufreq_init vmlinux EXPORT_SYMBOL
++0xf75603a3    exynos4210_cpufreq_init vmlinux EXPORT_SYMBOL
++0x38a9c2c7    input_ff_effect_from_user       vmlinux EXPORT_SYMBOL_GPL
++0x4f92c146    mfd_cell_enable vmlinux EXPORT_SYMBOL
++0xeacc50bc    attribute_container_register    vmlinux EXPORT_SYMBOL_GPL
++0x53465c39    drm_vblank_count_and_time       vmlinux EXPORT_SYMBOL
++0xc0e23731    inetpeer_invalidate_tree        vmlinux EXPORT_SYMBOL
++0x7d1904b2    __neigh_create  vmlinux EXPORT_SYMBOL
++0x6d294e43    clock_t_to_jiffies      vmlinux EXPORT_SYMBOL
++0x327bf883    of_can_translate_address        vmlinux EXPORT_SYMBOL
++0x6232e48e    power_supply_powers     vmlinux EXPORT_SYMBOL_GPL
++0x15b9125f    hdmi_avi_infoframe_pack vmlinux EXPORT_SYMBOL
++0x48e7c422    fanout_mutex    vmlinux EXPORT_SYMBOL_GPL
++0xdf050302    skb_mac_gso_segment     vmlinux EXPORT_SYMBOL
++0x4afb74d0    snd_pcm_lib_preallocate_pages_for_all   vmlinux EXPORT_SYMBOL
++0xf874d572    crypto_larval_alloc     vmlinux EXPORT_SYMBOL_GPL
++0x540a73a6    seq_release     vmlinux EXPORT_SYMBOL
++0xb3826d47    insert_inode_locked     vmlinux EXPORT_SYMBOL
++0x1866cec2    ring_buffer_size        vmlinux EXPORT_SYMBOL_GPL
++0x838b13e7    ring_buffer_free        vmlinux EXPORT_SYMBOL_GPL
++0x41d8cf05    module_layout   vmlinux EXPORT_SYMBOL
++0xdbb5a9f5    drm_ht_remove_item      vmlinux EXPORT_SYMBOL
++0x654a5368    drm_vblank_off  vmlinux EXPORT_SYMBOL
++0xb3e9e167    drm_vblank_get  vmlinux EXPORT_SYMBOL
++0xa795c78d    pl330_filter    vmlinux EXPORT_SYMBOL
++0x0335cb43    __sb_start_write        vmlinux EXPORT_SYMBOL
++0x6955eb5f    hidinput_disconnect     vmlinux EXPORT_SYMBOL_GPL
++0xd49dd4f4    cfg80211_cqm_txe_notify vmlinux EXPORT_SYMBOL
++0xcc1fb551    baswap  vmlinux EXPORT_SYMBOL
++0x653aa466    __blk_put_request       vmlinux EXPORT_SYMBOL_GPL
++0x99401626    elv_rb_latter_request   vmlinux EXPORT_SYMBOL
++0x0da68fbf    sysfs_create_bin_file   vmlinux EXPORT_SYMBOL_GPL
++0x27fa66e1    nr_free_buffer_pages    vmlinux EXPORT_SYMBOL_GPL
++0x7452437c    cgroup_taskset_next     vmlinux EXPORT_SYMBOL_GPL
++0xd2e7fb21    mod_delayed_work_on     vmlinux EXPORT_SYMBOL_GPL
++0x3d388324    dpm_resume_end  vmlinux EXPORT_SYMBOL_GPL
++0xfda2fc6f    pinctrl_remove_gpio_range       vmlinux EXPORT_SYMBOL_GPL
++0x98c9f584    klist_init      vmlinux EXPORT_SYMBOL_GPL
++0x72e52881    xfrm_state_unregister_afinfo    vmlinux EXPORT_SYMBOL
++0xec57ea15    snd_card_unref  vmlinux EXPORT_SYMBOL
++0x6cdc5c6b    nla_strlcpy     vmlinux EXPORT_SYMBOL
++0xa46f2f1b    kstrtouint      vmlinux EXPORT_SYMBOL
++0x315c8d71    blk_init_queue_node     vmlinux EXPORT_SYMBOL
++0x83211609    up_write        vmlinux EXPORT_SYMBOL
++0x19610e1f    cpu_all_bits    vmlinux EXPORT_SYMBOL
++0x4f248523    of_find_node_by_name    vmlinux EXPORT_SYMBOL
++0x14d0738e    dm_noflush_suspending   vmlinux EXPORT_SYMBOL_GPL
++0x488cee4b    serial8250_do_pm        vmlinux EXPORT_SYMBOL
++0xe4e38519    tcf_hash_release        vmlinux EXPORT_SYMBOL
++0xf1298271    free_buffer_head        vmlinux EXPORT_SYMBOL
++0x08559b9a    fget    vmlinux EXPORT_SYMBOL
++0x4a57b339    wait_for_completion_io_timeout  vmlinux EXPORT_SYMBOL
++0xcccd9343    mmc_gpio_get_ro vmlinux EXPORT_SYMBOL
++0xa3959367    mmc_gpio_get_cd vmlinux EXPORT_SYMBOL
++0xbc3a2d91    cpufreq_cpu_put vmlinux EXPORT_SYMBOL_GPL
++0x238dd120    cpufreq_cpu_get vmlinux EXPORT_SYMBOL_GPL
++0xfe7c6819    scsi_target_block       vmlinux EXPORT_SYMBOL_GPL
++0x42488405    scsi_prep_state_check   vmlinux EXPORT_SYMBOL
++0xf4b2e991    drm_mm_put_block        vmlinux EXPORT_SYMBOL
++0x688bd4c5    snd_ctl_boolean_mono_info       vmlinux EXPORT_SYMBOL
++0xe1e281d6    jbd2_log_start_commit   vmlinux EXPORT_SYMBOL
++0x9130f1c7    remove_proc_subtree     vmlinux EXPORT_SYMBOL
++0xfa1eb910    unregister_syscore_ops  vmlinux EXPORT_SYMBOL_GPL
++0x4d7f9839    snd_soc_of_parse_card_name      vmlinux EXPORT_SYMBOL_GPL
++0x44e9a829    match_token     vmlinux EXPORT_SYMBOL
++0x49b26c63    jbd2_journal_abort      vmlinux EXPORT_SYMBOL
++0x1a323362    __ftrace_vbprintk       vmlinux EXPORT_SYMBOL_GPL
++0x0a958ed4    down_write      vmlinux EXPORT_SYMBOL
++0x706b3a33    cpufreq_frequency_table_get_attr        vmlinux EXPORT_SYMBOL_GPL
++0xbdba9828    hdmi_audio_infoframe_pack       vmlinux EXPORT_SYMBOL
++0x09c64fbd    ieee80211_frequency_to_channel  vmlinux EXPORT_SYMBOL
++0x64d41d38    ip_route_output_flow    vmlinux EXPORT_SYMBOL_GPL
++0xc23832c5    snd_soc_add_card_controls       vmlinux EXPORT_SYMBOL_GPL
++0x43326227    posix_test_lock vmlinux EXPORT_SYMBOL
++0xd7289dfe    kill_block_super        vmlinux EXPORT_SYMBOL
++0x2b0f3b97    flush_signals   vmlinux EXPORT_SYMBOL
++0x1b9e0ff1    scsilun_to_int  vmlinux EXPORT_SYMBOL
++0x97a0de2c    drm_prime_pages_to_sg   vmlinux EXPORT_SYMBOL
++0x0442abb5    __inet_stream_connect   vmlinux EXPORT_SYMBOL
++0xc6f7d745    nf_ct_remove_expectations       vmlinux EXPORT_SYMBOL_GPL
++0xecdea3ba    neigh_lookup_nodev      vmlinux EXPORT_SYMBOL
++0x10c58227    kernel_setsockopt       vmlinux EXPORT_SYMBOL
++0x8fd29b0f    kernel_getsockopt       vmlinux EXPORT_SYMBOL
++0xed5cfaa9    kernel_sock_ioctl       vmlinux EXPORT_SYMBOL
++0x8ffdb3b8    crc16   vmlinux EXPORT_SYMBOL
++0xadc7f742    mb_cache_entry_insert   vmlinux EXPORT_SYMBOL
++0x4e1e8913    kallsyms_on_each_symbol vmlinux EXPORT_SYMBOL_GPL
++0xf82f3657    work_on_cpu     vmlinux EXPORT_SYMBOL_GPL
++0x459e133f    v4l2_m2m_get_curr_priv  vmlinux EXPORT_SYMBOL
++0x4dd51c13    phy_pm_runtime_allow    vmlinux EXPORT_SYMBOL_GPL
++0xcbbaba0b    nf_tproxy_assign_sock   vmlinux EXPORT_SYMBOL_GPL
++0x3e220367    nfnetlink_unicast       vmlinux EXPORT_SYMBOL_GPL
++0x55504881    snd_mixer_oss_ioctl_card        vmlinux EXPORT_SYMBOL
++0xab694444    bsearch vmlinux EXPORT_SYMBOL
++0x662edc7c    blk_put_request vmlinux EXPORT_SYMBOL
++0x6ca4bf88    async_synchronize_full_domain   vmlinux EXPORT_SYMBOL_GPL
++0x12456a92    iommu_iova_to_phys      vmlinux EXPORT_SYMBOL_GPL
++0xdc7b411a    dev_pm_qos_hide_latency_limit   vmlinux EXPORT_SYMBOL_GPL
++0x28441b73    drm_get_last_vbltimestamp       vmlinux EXPORT_SYMBOL
++0x83eab4ef    crypto_create_tfm       vmlinux EXPORT_SYMBOL_GPL
++0x42e2c53b    nf_conntrack_in vmlinux EXPORT_SYMBOL_GPL
++0x3ea1d70f    sock_queue_rcv_skb      vmlinux EXPORT_SYMBOL
++0xe7820ad2    snd_pcm_lib_preallocate_free_for_all    vmlinux EXPORT_SYMBOL
++0x754dac78    blk_limits_io_min       vmlinux EXPORT_SYMBOL
++0x0cd9cfec    sysfs_remove_files      vmlinux EXPORT_SYMBOL_GPL
++0xc237047a    mapping_tagged  vmlinux EXPORT_SYMBOL
++0xd777c9b7    iio_device_alloc        vmlinux EXPORT_SYMBOL
++0xd688716b    dm_kcopyd_client_create vmlinux EXPORT_SYMBOL
++0x2502c67c    v4l2_fh_add     vmlinux EXPORT_SYMBOL_GPL
++0x088675f7    usbnet_write_cmd_async  vmlinux EXPORT_SYMBOL_GPL
++0xb35659de    drm_mode_remove vmlinux EXPORT_SYMBOL
++0x16acff8a    devm_of_pwm_get vmlinux EXPORT_SYMBOL_GPL
++0xd2bd22d2    s3c_gpio_getpull        vmlinux EXPORT_SYMBOL
++0x5fbecd25    s3c_gpio_setpull        vmlinux EXPORT_SYMBOL
++0x67c2fa54    __copy_to_user  vmlinux EXPORT_SYMBOL
++0x7c6a49ce    unix_table_lock vmlinux EXPORT_SYMBOL_GPL
++0x38d60861    put_disk        vmlinux EXPORT_SYMBOL
++0x871bcaa4    irq_find_host   vmlinux EXPORT_SYMBOL_GPL
++0xd9605d4c    add_timer       vmlinux EXPORT_SYMBOL
++0xea97fb5e    usbhid_set_leds vmlinux EXPORT_SYMBOL_GPL
++0x70915b51    serio_interrupt vmlinux EXPORT_SYMBOL
++0x92a772c3    usbnet_purge_paused_rxq vmlinux EXPORT_SYMBOL_GPL
++0xf6bb4729    color_table     vmlinux EXPORT_SYMBOL
++0x8c637d43    irq_cpu_rmap_add        vmlinux EXPORT_SYMBOL
++0x9ba7089d    argv_split      vmlinux EXPORT_SYMBOL
++0x34f3484e    security_tun_dev_attach_queue   vmlinux EXPORT_SYMBOL
++0x1a1431fd    _raw_spin_unlock_irq    vmlinux EXPORT_SYMBOL
++0x7c08f605    hid_allocate_device     vmlinux EXPORT_SYMBOL_GPL
++0xe5a8e6b5    spi_sync        vmlinux EXPORT_SYMBOL_GPL
++0xcc69f0f8    dma_sync_wait   vmlinux EXPORT_SYMBOL
++0x43e33157    blk_queue_max_hw_sectors        vmlinux EXPORT_SYMBOL
++0x8ea0cdd5    drm_add_modes_noedid    vmlinux EXPORT_SYMBOL
++0x9a8318ef    v7_coherent_kern_range  vmlinux EXPORT_SYMBOL
++0x5de3ad52    cfg80211_ref_bss        vmlinux EXPORT_SYMBOL
++0xdc1b2765    crypto_aes_set_key      vmlinux EXPORT_SYMBOL_GPL
++0x5086ac3a    alg_test        vmlinux EXPORT_SYMBOL_GPL
++0x9c35fb24    jbd2__journal_restart   vmlinux EXPORT_SYMBOL
++0xbef43296    console_conditional_schedule    vmlinux EXPORT_SYMBOL
++0xa71c1b98    bus_set_iommu   vmlinux EXPORT_SYMBOL_GPL
++0x8e801428    bus_create_file vmlinux EXPORT_SYMBOL_GPL
++0x8fc34c2d    drm_warn_on_modeset_not_all_locked      vmlinux EXPORT_SYMBOL
++0x2e0a06e3    snd_unregister_device   vmlinux EXPORT_SYMBOL
++0x9caaf6cf    blkdev_issue_discard    vmlinux EXPORT_SYMBOL
++0x3e6444e8    crypto_unregister_pcomp vmlinux EXPORT_SYMBOL_GPL
++0xc1d19fdd    debugfs_create_symlink  vmlinux EXPORT_SYMBOL_GPL
++0x9bd7640e    fat_detach      vmlinux EXPORT_SYMBOL_GPL
++0x698a899f    ring_buffer_peek        vmlinux EXPORT_SYMBOL_GPL
++0xe2e7840d    regmap_init_mmio_clk    vmlinux EXPORT_SYMBOL_GPL
++0xe556d687    xt_request_find_match   vmlinux EXPORT_SYMBOL_GPL
++0xcf25e6b2    xattr_getsecurity       vmlinux EXPORT_SYMBOL_GPL
++0x6228c21f    smp_call_function_single        vmlinux EXPORT_SYMBOL
++0x5f324ec1    drm_ioctl       vmlinux EXPORT_SYMBOL
++0x4d9b652b    rb_erase        vmlinux EXPORT_SYMBOL
++0xcc71d484    drm_mode_duplicate      vmlinux EXPORT_SYMBOL
++0x2b02560b    devm_pwm_put    vmlinux EXPORT_SYMBOL_GPL
++0x3659d5ac    devm_phy_get    vmlinux EXPORT_SYMBOL_GPL
++0xaafdc258    strcasecmp      vmlinux EXPORT_SYMBOL
++0xc296567b    save_mount_options      vmlinux EXPORT_SYMBOL
++0xbade32c7    clockevents_register_device     vmlinux EXPORT_SYMBOL_GPL
++0xfb8a84a4    drm_mm_get_block_range_generic  vmlinux EXPORT_SYMBOL
++0x058b582a    vt_get_leds     vmlinux EXPORT_SYMBOL_GPL
++0xb2a0603e    nci_recv_frame  vmlinux EXPORT_SYMBOL
++0xc0240dd4    nf_conntrack_set_hashsize       vmlinux EXPORT_SYMBOL_GPL
++0x45c8cd86    ifla_policy     vmlinux EXPORT_SYMBOL
++0xd251d7b0    security_socket_getpeersec_dgram        vmlinux EXPORT_SYMBOL
++0xf05e203c    set_blocksize   vmlinux EXPORT_SYMBOL
++0xc1c995a0    block_page_mkwrite      vmlinux EXPORT_SYMBOL
++0x85b9e216    set_timer_slack vmlinux EXPORT_SYMBOL_GPL
++0x2665c0a3    vb2_qbuf        vmlinux EXPORT_SYMBOL_GPL
++0x9abe8d18    video_usercopy  vmlinux EXPORT_SYMBOL
++0x1d93e603    tty_unthrottle  vmlinux EXPORT_SYMBOL
++0x1142511d    crypto_spawn_tfm        vmlinux EXPORT_SYMBOL_GPL
++0xeb9ddf6d    security_inode_notifysecctx     vmlinux EXPORT_SYMBOL
++0x68df960a    generic_error_remove_page       vmlinux EXPORT_SYMBOL
++0x7000dc34    class_compat_remove_link        vmlinux EXPORT_SYMBOL_GPL
++0x816dee03    uart_unregister_driver  vmlinux EXPORT_SYMBOL
++0x0acf7679    dma_issue_pending_all   vmlinux EXPORT_SYMBOL
++0x8792d764    l2cap_conn_get  vmlinux EXPORT_SYMBOL
++0xcf2890b2    ipv6_chk_prefix vmlinux EXPORT_SYMBOL
++0x616ff33b    ip6_dst_lookup_flow     vmlinux EXPORT_SYMBOL_GPL
++0x3e963d19    inet_csk_search_req     vmlinux EXPORT_SYMBOL_GPL
++0xdd632e58    inet_unhash     vmlinux EXPORT_SYMBOL_GPL
++0x98e40edf    nf_ct_nat_offset        vmlinux EXPORT_SYMBOL_GPL
++0x0a7ed556    blk_execute_rq  vmlinux EXPORT_SYMBOL
++0x44408a4a    mdio_bus_type   vmlinux EXPORT_SYMBOL
++0xac74a2a9    ip6_xmit        vmlinux EXPORT_SYMBOL
++0x411d75db    ip_tunnel_init  vmlinux EXPORT_SYMBOL_GPL
++0x7a442539    tcf_exts_dump   vmlinux EXPORT_SYMBOL
++0x13307fde    vsscanf vmlinux EXPORT_SYMBOL
++0xcc368515    jbd2_journal_unlock_updates     vmlinux EXPORT_SYMBOL
++0x21bfb720    seq_open_net    vmlinux EXPORT_SYMBOL_GPL
++0x82d79b51    sysctl_vfs_cache_pressure       vmlinux EXPORT_SYMBOL_GPL
++0x04486e88    rcu_batches_completed   vmlinux EXPORT_SYMBOL_GPL
++0x7c1372e8    panic   vmlinux EXPORT_SYMBOL
++0x9808f34e    dev_pm_qos_expose_flags vmlinux EXPORT_SYMBOL_GPL
++0x544b5ea8    pwm_disable     vmlinux EXPORT_SYMBOL_GPL
++0x5c265cba    sg_init_one     vmlinux EXPORT_SYMBOL
++0x12da5bb2    __kmalloc       vmlinux EXPORT_SYMBOL
++0x28d6861d    __vmalloc       vmlinux EXPORT_SYMBOL
++0x5db7b0d3    led_trigger_remove      vmlinux EXPORT_SYMBOL_GPL
++0x83b38ee6    kobject_init_and_add    vmlinux EXPORT_SYMBOL_GPL
++0x757cdadf    usbnet_get_ethernet_addr        vmlinux EXPORT_SYMBOL_GPL
++0x43a286d1    drm_prime_remove_buf_handle     vmlinux EXPORT_SYMBOL
++0xea8ddd89    __ip_select_ident       vmlinux EXPORT_SYMBOL
++0x1f984870    skb_gro_receive vmlinux EXPORT_SYMBOL_GPL
++0x48f8aa53    flock_lock_file_wait    vmlinux EXPORT_SYMBOL
++0x05e067d7    __media_entity_remove_links     vmlinux EXPORT_SYMBOL_GPL
++0xe7cb87e4    xt_find_match   vmlinux EXPORT_SYMBOL
++0x9d62c35b    nfq_ct_hook     vmlinux EXPORT_SYMBOL_GPL
++0xe12b4adb    __skb_warn_lro_forwarding       vmlinux EXPORT_SYMBOL
++0x471eeac6    snd_soc_platform_write  vmlinux EXPORT_SYMBOL_GPL
++0x71c90087    memcmp  vmlinux EXPORT_SYMBOL
++0x4881d505    idr_for_each    vmlinux EXPORT_SYMBOL
++0x79b33953    shash_ahash_digest      vmlinux EXPORT_SYMBOL_GPL
++0xcf1d92aa    locks_init_lock vmlinux EXPORT_SYMBOL
++0x11cfbadb    bio_add_pc_page vmlinux EXPORT_SYMBOL
++0x2917e251    split_page      vmlinux EXPORT_SYMBOL_GPL
++0xda53403f    v4l2_m2m_ctx_init       vmlinux EXPORT_SYMBOL_GPL
++0x4f4d910e    regmap_init     vmlinux EXPORT_SYMBOL_GPL
++0xb2a9634b    regmap_exit     vmlinux EXPORT_SYMBOL_GPL
++0xe16838c2    drm_mm_search_free_in_range_generic     vmlinux EXPORT_SYMBOL
++0xf05ffa15    fb_var_to_videomode     vmlinux EXPORT_SYMBOL
++0xab707907    inet6_del_offload       vmlinux EXPORT_SYMBOL
++0x13e229c2    nf_ct_helper_expectfn_find_by_name      vmlinux EXPORT_SYMBOL_GPL
++0x1f0547c1    netif_stacked_transfer_operstate        vmlinux EXPORT_SYMBOL
++0xd435e67a    snd_card_set_id vmlinux EXPORT_SYMBOL
++0xc7236f77    d_alloc_name    vmlinux EXPORT_SYMBOL
++0x2f3857e2    _raw_write_lock_irqsave vmlinux EXPORT_SYMBOL
++0x37c199e6    serio_reconnect vmlinux EXPORT_SYMBOL
++0x6754f715    drm_fb_helper_fill_fix  vmlinux EXPORT_SYMBOL
++0xc6df7ef6    cont_write_begin        vmlinux EXPORT_SYMBOL
++0x1c97e3ec    vfs_readdir     vmlinux EXPORT_SYMBOL
++0xbdd295f0    trace_vprintk   vmlinux EXPORT_SYMBOL_GPL
++0x8faa4598    of_translate_address    vmlinux EXPORT_SYMBOL
++0x0699040f    drm_encoder_cleanup     vmlinux EXPORT_SYMBOL
++0x7f8c7b48    dma_async_memcpy_buf_to_buf     vmlinux EXPORT_SYMBOL
++0x1ed85a8d    pinctrl_dev_get_drvdata vmlinux EXPORT_SYMBOL_GPL
++0x881039d0    zlib_inflate    vmlinux EXPORT_SYMBOL
++0x3771b461    crc_ccitt       vmlinux EXPORT_SYMBOL
++0xa43b1297    vscnprintf      vmlinux EXPORT_SYMBOL
++0x166e361d    blk_recount_segments    vmlinux EXPORT_SYMBOL
++0x887ece4a    simple_statfs   vmlinux EXPORT_SYMBOL
++0x617643a2    param_set_long  vmlinux EXPORT_SYMBOL
++0x6c69a9be    xfrm6_tunnel_deregister vmlinux EXPORT_SYMBOL
++0x3b850073    km_policy_notify        vmlinux EXPORT_SYMBOL
++0x10cc1e43    xfrm4_tunnel_deregister vmlinux EXPORT_SYMBOL
++0xc0f95b9e    ip_mc_join_group        vmlinux EXPORT_SYMBOL
++0xdb760f52    __kfifo_free    vmlinux EXPORT_SYMBOL
++0x3a288321    configfs_undepend_item  vmlinux EXPORT_SYMBOL
++0x2cc83b45    usb_string      vmlinux EXPORT_SYMBOL_GPL
++0x98442d13    inet_csk_reqsk_queue_hash_add   vmlinux EXPORT_SYMBOL_GPL
++0x8d33679f    nf_ct_unexpect_related  vmlinux EXPORT_SYMBOL_GPL
++0xe6e1c5fe    uuid_be_gen     vmlinux EXPORT_SYMBOL_GPL
++0x289ea691    debugfs_remove  vmlinux EXPORT_SYMBOL_GPL
++0xbb4e9599    lease_modify    vmlinux EXPORT_SYMBOL
++0x2fb6e20e    drop_nlink      vmlinux EXPORT_SYMBOL
++0xdfaa6b6b    v4l2_ctrl_radio_filter  vmlinux EXPORT_SYMBOL
++0xa3675712    xfrm_dst_ifdown vmlinux EXPORT_SYMBOL
++0x0d9bae4b    nf_nat_l4proto_nlattr_to_range  vmlinux EXPORT_SYMBOL_GPL
++0xc17f8f83    neigh_seq_start vmlinux EXPORT_SYMBOL
++0x6e7943ec    iommu_group_id  vmlinux EXPORT_SYMBOL_GPL
++0x1aef1e27    eth_header_cache_update vmlinux EXPORT_SYMBOL
++0xd800dc59    snd_pcm_hw_constraint_ratdens   vmlinux EXPORT_SYMBOL
++0xd1157735    release_and_free_resource       vmlinux EXPORT_SYMBOL
++0xb31526ee    sg_copy_from_buffer     vmlinux EXPORT_SYMBOL
++0x73e20c1c    strlcpy vmlinux EXPORT_SYMBOL
++0x328a05f1    strncpy vmlinux EXPORT_SYMBOL
++0x8abacc47    get_max_files   vmlinux EXPORT_SYMBOL_GPL
++0xae0f6b4e    regulator_unregister_notifier   vmlinux EXPORT_SYMBOL_GPL
++0x386f5a4e    tcf_em_tree_destroy     vmlinux EXPORT_SYMBOL
++0x97b4500c    __tracepoint_kmem_cache_free    vmlinux EXPORT_SYMBOL
++0x4a69690c    scsi_release_buffers    vmlinux EXPORT_SYMBOL
++0xf195c682    fb_invert_cmaps vmlinux EXPORT_SYMBOL
++0xab156bb5    kern_mount_data vmlinux EXPORT_SYMBOL_GPL
++0x1902f934    __init_kthread_worker   vmlinux EXPORT_SYMBOL_GPL
++0xdac0df4a    driver_create_file      vmlinux EXPORT_SYMBOL_GPL
++0x083eb21c    rfkill_unregister       vmlinux EXPORT_SYMBOL
++0x3e52c876    blk_requeue_request     vmlinux EXPORT_SYMBOL
++0xdca5d880    insert_inode_locked4    vmlinux EXPORT_SYMBOL
++0x41482d8b    strndup_user    vmlinux EXPORT_SYMBOL
++0xddd58dc0    ring_buffer_reset       vmlinux EXPORT_SYMBOL_GPL
++0x6b172795    media_entity_graph_walk_next    vmlinux EXPORT_SYMBOL_GPL
++0x0591a4d1    usb_ep_autoconfig_ss    vmlinux EXPORT_SYMBOL_GPL
++0x4b076147    uncache_firmware        vmlinux EXPORT_SYMBOL_GPL
++0x098b71c6    fb_dealloc_cmap vmlinux EXPORT_SYMBOL
++0x83d1444a    crypto_init_spawn       vmlinux EXPORT_SYMBOL_GPL
++0x60061dd7    mount_nodev     vmlinux EXPORT_SYMBOL
++0x7bb32751    pagevec_lookup  vmlinux EXPORT_SYMBOL
++0x47b6a10f    ftrace_print_symbols_seq        vmlinux EXPORT_SYMBOL
++0x8664f62e    cpufreq_update_policy   vmlinux EXPORT_SYMBOL
++0x29f39077    pwmchip_remove  vmlinux EXPORT_SYMBOL_GPL
++0x905baf48    xfrm_find_acq   vmlinux EXPORT_SYMBOL
++0x9487bc19    eth_mac_addr    vmlinux EXPORT_SYMBOL
++0xad1ed84c    unregister_hw_breakpoint        vmlinux EXPORT_SYMBOL_GPL
++0x993805c1    scsi_scan_host  vmlinux EXPORT_SYMBOL
++0x7a77dfe4    scsi_setup_fs_cmnd      vmlinux EXPORT_SYMBOL
++0xbbc9fd6e    cfg80211_wext_siwfrag   vmlinux EXPORT_SYMBOL_GPL
++0x82c82c32    cfg80211_wext_giwfrag   vmlinux EXPORT_SYMBOL_GPL
++0xe80dd06a    tcp_sendpage    vmlinux EXPORT_SYMBOL
++0x47b3f862    radix_tree_lookup_slot  vmlinux EXPORT_SYMBOL
++0x91621d6a    allocate_resource       vmlinux EXPORT_SYMBOL
++0xb98a0185    rtc_tm_to_time  vmlinux EXPORT_SYMBOL
++0xe5883bd9    class_compat_unregister vmlinux EXPORT_SYMBOL_GPL
++0x7bf9c108    serial8250_rx_dma       vmlinux EXPORT_SYMBOL_GPL
++0xc7856a3d    inet6addr_notifier_call_chain   vmlinux EXPORT_SYMBOL
++0xc08647ff    ring_buffer_bytes_cpu   vmlinux EXPORT_SYMBOL_GPL
++0xcbbf0a6f    audit_log_task_context  vmlinux EXPORT_SYMBOL
++0x0a0ab757    pm_schedule_suspend     vmlinux EXPORT_SYMBOL_GPL
++0x617ae32f    of_get_display_timings  vmlinux EXPORT_SYMBOL_GPL
++0xe442a492    splice_from_pipe_feed   vmlinux EXPORT_SYMBOL
++0xf9a054b5    __round_jiffies vmlinux EXPORT_SYMBOL_GPL
++0x38e20383    hid_alloc_report_buf    vmlinux EXPORT_SYMBOL_GPL
++0x626ffd48    spi_write_then_read     vmlinux EXPORT_SYMBOL_GPL
++0x7b5fc447    pinctrl_lookup_state    vmlinux EXPORT_SYMBOL_GPL
++0x8c49e9fe    cfg80211_conn_failed    vmlinux EXPORT_SYMBOL
++0x03c06156    bitmap_fold     vmlinux EXPORT_SYMBOL
++0x04d5a096    security_sb_clone_mnt_opts      vmlinux EXPORT_SYMBOL
++0x424b2fdf    vfs_rmdir       vmlinux EXPORT_SYMBOL
++0x52856d8e    generic_shutdown_super  vmlinux EXPORT_SYMBOL
++0xbd10541e    css_lookup      vmlinux EXPORT_SYMBOL_GPL
++0x37e74642    get_jiffies_64  vmlinux EXPORT_SYMBOL
++0xb8117014    cfg80211_rx_spurious_frame      vmlinux EXPORT_SYMBOL
++0x790c2d9c    netdev_master_upper_dev_link    vmlinux EXPORT_SYMBOL
++0x02a6ce5a    crc16_table     vmlinux EXPORT_SYMBOL
++0xe280ea92    init_buffer     vmlinux EXPORT_SYMBOL
++0xf21e1f9b    disable_percpu_irq      vmlinux EXPORT_SYMBOL_GPL
++0xb5ae5758    scsi_track_queue_full   vmlinux EXPORT_SYMBOL
++0xa26b1ba8    exynos_drm_device_register      vmlinux EXPORT_SYMBOL_GPL
++0xbe55cd3e    __sock_recv_ts_and_drops        vmlinux EXPORT_SYMBOL_GPL
++0xcedd3329    jbd2__journal_start     vmlinux EXPORT_SYMBOL
++0x838a3169    pm_qos_request_active   vmlinux EXPORT_SYMBOL_GPL
++0xbf7fd2f5    schedule_timeout_killable       vmlinux EXPORT_SYMBOL
++0xd9c4cec4    sock_no_getname vmlinux EXPORT_SYMBOL
++0x24678be3    snd_pcm_lib_readv       vmlinux EXPORT_SYMBOL
++0x292a0b74    vfs_link        vmlinux EXPORT_SYMBOL
++0x85050965    __irq_alloc_descs       vmlinux EXPORT_SYMBOL_GPL
++0xe3e7dba0    from_kuid_munged        vmlinux EXPORT_SYMBOL
++0x582bb484    call_usermodehelper_setup       vmlinux EXPORT_SYMBOL
++0xe52c5e63    v4l2_event_subscribe    vmlinux EXPORT_SYMBOL_GPL
++0xcd0fc417    drm_ht_just_insert_please       vmlinux EXPORT_SYMBOL
++0xdacbc24d    netlink_rcv_skb vmlinux EXPORT_SYMBOL
++0x33d23d14    sk_unattached_filter_create     vmlinux EXPORT_SYMBOL_GPL
++0x1f07ae8f    crypto_alloc_pcomp      vmlinux EXPORT_SYMBOL_GPL
++0x2447533c    ktime_get_real  vmlinux EXPORT_SYMBOL_GPL
++0x68869bae    panic_notifier_list     vmlinux EXPORT_SYMBOL
++0xdae1eb6a    of_clk_src_onecell_get  vmlinux EXPORT_SYMBOL_GPL
++0x3444d892    phy_driver_unregister   vmlinux EXPORT_SYMBOL
++0x107b31ec    __xfrm_state_delete     vmlinux EXPORT_SYMBOL
++0x4e6165cf    d_delete        vmlinux EXPORT_SYMBOL
++0x5f0e672b    find_get_pages_tag      vmlinux EXPORT_SYMBOL
++0xc8fd727e    mod_timer       vmlinux EXPORT_SYMBOL
++0xd2fe47b1    rndis_set_host_mac      vmlinux EXPORT_SYMBOL
++0xd768e985    regulator_has_full_constraints  vmlinux EXPORT_SYMBOL_GPL
++0x82f776b7    gpio_export     vmlinux EXPORT_SYMBOL_GPL
++0xdf401846    idr_remove      vmlinux EXPORT_SYMBOL
++0x29baff70    ida_remove      vmlinux EXPORT_SYMBOL
++0x220b4b23    mnt_set_expiry  vmlinux EXPORT_SYMBOL
++0x3dd9c200    use_mm  vmlinux EXPORT_SYMBOL_GPL
++0x2d41e6f5    __trace_puts    vmlinux EXPORT_SYMBOL_GPL
++0x5143c678    param_get_invbool       vmlinux EXPORT_SYMBOL
++0x914a1c17    ip_tunnel_newlink       vmlinux EXPORT_SYMBOL_GPL
++0xc5b6b555    genl_notify     vmlinux EXPORT_SYMBOL
++0xada52470    wm_hubs_hpl_mux vmlinux EXPORT_SYMBOL_GPL
++0x9393c812    add_page_wait_queue     vmlinux EXPORT_SYMBOL_GPL
++0xb16abad2    devm_rtc_device_register        vmlinux EXPORT_SYMBOL_GPL
++0xbd92ef65    devres_destroy  vmlinux EXPORT_SYMBOL_GPL
++0x1297fa08    tty_hangup      vmlinux EXPORT_SYMBOL
++0x580c94d2    seq_put_decimal_ll      vmlinux EXPORT_SYMBOL
++0xb22596e0    devm_rtc_device_unregister      vmlinux EXPORT_SYMBOL_GPL
++0x1b95d5c1    mdiobus_read    vmlinux EXPORT_SYMBOL
++0xea59b757    pm_runtime_forbid       vmlinux EXPORT_SYMBOL_GPL
++0x30e74134    tty_termios_copy_hw     vmlinux EXPORT_SYMBOL
++0x4455e1b3    regulator_disable_deferred      vmlinux EXPORT_SYMBOL_GPL
++0x8e322129    dma_release_channel     vmlinux EXPORT_SYMBOL_GPL
++0xcfd9a2c0    des_ekey        vmlinux EXPORT_SYMBOL_GPL
++0x66c78bd2    irq_domain_remove       vmlinux EXPORT_SYMBOL_GPL
++0x640c2da8    devm_clk_get    vmlinux EXPORT_SYMBOL
++0xd02c73c7    drm_dp_link_train_clock_recovery_delay  vmlinux EXPORT_SYMBOL
++0x2be0f12d    dql_completed   vmlinux EXPORT_SYMBOL
++0xad3f5f91    read_cache_page vmlinux EXPORT_SYMBOL
++0x4ca90996    rndis_signal_disconnect vmlinux EXPORT_SYMBOL
++0x917229dc    drm_irq_install vmlinux EXPORT_SYMBOL
++0x787bcffe    con_is_bound    vmlinux EXPORT_SYMBOL
++0xefb6eb3f    dev_change_flags        vmlinux EXPORT_SYMBOL
++0x0e352145    __skb_gso_segment       vmlinux EXPORT_SYMBOL
++0xa5d14a5e    xfrm_state_walk vmlinux EXPORT_SYMBOL
++0x6a0ae2ec    nla_put_nohdr   vmlinux EXPORT_SYMBOL
++0x0411124a    pid_nr_ns       vmlinux EXPORT_SYMBOL_GPL
++0x2133271d    phy_scan_fixups vmlinux EXPORT_SYMBOL
++0x64d233c8    ioremap_page    vmlinux EXPORT_SYMBOL
++0x8fea24bd    bt_sock_unregister      vmlinux EXPORT_SYMBOL
++0x16c3cf65    napi_gro_flush  vmlinux EXPORT_SYMBOL
++0xf001dc80    irq_domain_add_linear   vmlinux EXPORT_SYMBOL_GPL
++0xec069709    scsi_set_medium_removal vmlinux EXPORT_SYMBOL
++0xc0a98385    profile_pc      vmlinux EXPORT_SYMBOL
++0x79a2f120    snd_timer_resolution    vmlinux EXPORT_SYMBOL
++0x46c67b94    jbd2_journal_wipe       vmlinux EXPORT_SYMBOL
++0x444f1735    cpu_pm_register_notifier        vmlinux EXPORT_SYMBOL_GPL
++0xcc85fcb6    async_schedule  vmlinux EXPORT_SYMBOL_GPL
++0x9caf61d6    __nla_put       vmlinux EXPORT_SYMBOL
++0x4c2ae700    strnstr vmlinux EXPORT_SYMBOL
++0x07bf12c5    perf_pmu_migrate_context        vmlinux EXPORT_SYMBOL_GPL
++0x4268de2e    __css_put       vmlinux EXPORT_SYMBOL_GPL
++0x32fdb1ea    usb_block_urb   vmlinux EXPORT_SYMBOL_GPL
++0xd76e3ec9    fb_set_var      vmlinux EXPORT_SYMBOL
++0x7c0643d0    inet_diag_register      vmlinux EXPORT_SYMBOL_GPL
++0x598542b2    _raw_spin_lock_irqsave  vmlinux EXPORT_SYMBOL
++0xd468cd0b    sdhci_pltfm_unregister  vmlinux EXPORT_SYMBOL_GPL
++0x44f93f86    vb2_ops_wait_finish     vmlinux EXPORT_SYMBOL_GPL
++0x5be57447    dma_buf_kmap_atomic     vmlinux EXPORT_SYMBOL_GPL
++0xfac68eba    arm_elf_read_implies_exec       vmlinux EXPORT_SYMBOL
++0xca1e6f11    tcp_done        vmlinux EXPORT_SYMBOL_GPL
++0x885f07c4    snd_pcm_hw_rule_add     vmlinux EXPORT_SYMBOL
++0xb1c0c1c2    async_schedule_domain   vmlinux EXPORT_SYMBOL_GPL
++0x65497c9a    wm8994_bulk_write       vmlinux EXPORT_SYMBOL_GPL
++0x2fb6de5d    add_device_randomness   vmlinux EXPORT_SYMBOL
++0xda8af7ad    fb_find_nearest_mode    vmlinux EXPORT_SYMBOL
++0x0a575945    xfrm_count_pfkey_auth_supported vmlinux EXPORT_SYMBOL_GPL
++0x3b91f3af    snd_free_pages  vmlinux EXPORT_SYMBOL
++0xdf2278c1    snd_card_file_remove    vmlinux EXPORT_SYMBOL
++0xc848d220    blk_free_tags   vmlinux EXPORT_SYMBOL
++0xff492454    security_inode_getsecctx        vmlinux EXPORT_SYMBOL
++0xce46e140    ktime_get_ts    vmlinux EXPORT_SYMBOL_GPL
++0x3b0d157a    v4l2_m2m_ioctl_querybuf vmlinux EXPORT_SYMBOL_GPL
++0x054177ad    usb_init_urb    vmlinux EXPORT_SYMBOL_GPL
++0x1ad1f2e7    _memcpy_fromio  vmlinux EXPORT_SYMBOL
++0x95dbe078    __get_user_2    vmlinux EXPORT_SYMBOL
++0xb9acd3d9    __put_user_2    vmlinux EXPORT_SYMBOL
++0xf3797152    snd_interval_ratnum     vmlinux EXPORT_SYMBOL
++0x9d2edcd6    map_vm_area     vmlinux EXPORT_SYMBOL_GPL
++0xbfd8d187    balloon_page_enqueue    vmlinux EXPORT_SYMBOL_GPL
++0xb7e3198c    balloon_page_dequeue    vmlinux EXPORT_SYMBOL_GPL
++0x0084e86d    unregister_shrinker     vmlinux EXPORT_SYMBOL
++0x23424fab    usb_hcd_unmap_urb_setup_for_dma vmlinux EXPORT_SYMBOL_GPL
++0x6c06c6f7    scsi_device_get vmlinux EXPORT_SYMBOL
++0x970b4c98    scsi_device_put vmlinux EXPORT_SYMBOL
++0x66109b05    __pm_runtime_set_status vmlinux EXPORT_SYMBOL_GPL
++0x6d134a2a    drm_prime_sg_to_page_addr_arrays        vmlinux EXPORT_SYMBOL
++0xbce458b3    drm_framebuffer_reference       vmlinux EXPORT_SYMBOL
++0xa773e935    ipv6_dev_get_saddr      vmlinux EXPORT_SYMBOL
++0x38308727    xfrm_policy_flush       vmlinux EXPORT_SYMBOL
++0x6ebf58d8    skb_tx_error    vmlinux EXPORT_SYMBOL
++0xea793efe    snd_soc_cache_sync      vmlinux EXPORT_SYMBOL_GPL
++0xb8aa2342    __check_region  vmlinux EXPORT_SYMBOL
++0x99638333    mmc_set_blocklen        vmlinux EXPORT_SYMBOL
++0xc5e4da95    pn_sock_hash    vmlinux EXPORT_SYMBOL
++0xf6388c56    sysctl_ip_default_ttl   vmlinux EXPORT_SYMBOL
++0x0e7c2436    napi_gro_frags  vmlinux EXPORT_SYMBOL
++0x217dda13    flex_array_get  vmlinux EXPORT_SYMBOL
++0x09437748    ring_buffer_read_events_cpu     vmlinux EXPORT_SYMBOL_GPL
++0xb974ccc1    inet_diag_unregister    vmlinux EXPORT_SYMBOL_GPL
++0x0423031f    sock_sendmsg    vmlinux EXPORT_SYMBOL
++0xade88e76    snd_malloc_pages        vmlinux EXPORT_SYMBOL
++0x7ca50cfa    disk_get_part   vmlinux EXPORT_SYMBOL_GPL
++0xfed4d591    cfg80211_find_vendor_ie vmlinux EXPORT_SYMBOL
++0xe45ee6f0    netlink_kernel_release  vmlinux EXPORT_SYMBOL
++0xf310e4d9    __sock_create   vmlinux EXPORT_SYMBOL
++0x4153512b    snd_hwdep_new   vmlinux EXPORT_SYMBOL
++0x1afae5e7    down_interruptible      vmlinux EXPORT_SYMBOL
++0x2051f1d8    rtc_set_mmss    vmlinux EXPORT_SYMBOL_GPL
++0x23dfa3ab    netif_carrier_off       vmlinux EXPORT_SYMBOL
++0x10895a2a    lease_get_mtime vmlinux EXPORT_SYMBOL
++0x7cd8f487    sb_set_blocksize        vmlinux EXPORT_SYMBOL
++0x0effeb6c    srcu_barrier    vmlinux EXPORT_SYMBOL_GPL
++0xf3de55df    mmc_request_done        vmlinux EXPORT_SYMBOL
++0x46074c17    sdev_evt_alloc  vmlinux EXPORT_SYMBOL_GPL
++0x17077530    pinctrl_force_default   vmlinux EXPORT_SYMBOL_GPL
++0x0d40713a    snd_ctl_boolean_stereo_info     vmlinux EXPORT_SYMBOL
++0x3744cf36    vmalloc_to_pfn  vmlinux EXPORT_SYMBOL
++0xc783b0e1    get_task_mm     vmlinux EXPORT_SYMBOL_GPL
++0xa8950567    sdio_writew     vmlinux EXPORT_SYMBOL_GPL
++0xca443371    inet_csk_prepare_forced_close   vmlinux EXPORT_SYMBOL
++0x252f76b5    snd_soc_default_readable_register       vmlinux EXPORT_SYMBOL_GPL
++0x551bd071    __rb_erase_color        vmlinux EXPORT_SYMBOL
++0xfff8d451    fuse_request_send       vmlinux EXPORT_SYMBOL_GPL
++0x88b5647c    trace_clock_local       vmlinux EXPORT_SYMBOL_GPL
++0x683928de    nf_ct_expect_put        vmlinux EXPORT_SYMBOL_GPL
++0x7c96bf14    register_tcf_proto_ops  vmlinux EXPORT_SYMBOL
++0x76aea351    crypto_unregister_alg   vmlinux EXPORT_SYMBOL_GPL
++0x5c24f853    dump_write      vmlinux EXPORT_SYMBOL
++0x89485687    iommu_group_put vmlinux EXPORT_SYMBOL_GPL
++0x00f4d0cf    iommu_group_get vmlinux EXPORT_SYMBOL_GPL
++0xb4626765    v4l2_ctrl_new_custom    vmlinux EXPORT_SYMBOL
++0x511746c1    dump_fpu        vmlinux EXPORT_SYMBOL
++0x28927989    qdisc_watchdog_schedule_ns      vmlinux EXPORT_SYMBOL
++0x57fec35a    fuse_conn_get   vmlinux EXPORT_SYMBOL_GPL
++0xff3f1877    filp_open       vmlinux EXPORT_SYMBOL
++0x7cb7e8a5    generic_file_aio_write  vmlinux EXPORT_SYMBOL
++0x1d9317d8    smpboot_register_percpu_thread  vmlinux EXPORT_SYMBOL_GPL
++0x426362dc    __class_create  vmlinux EXPORT_SYMBOL_GPL
++0xebd6ff6e    xfrm6_prepare_output    vmlinux EXPORT_SYMBOL
++0x7c30b8c7    xfrm_calg_get_byname    vmlinux EXPORT_SYMBOL_GPL
++0xf23624a6    xfrm4_prepare_output    vmlinux EXPORT_SYMBOL
++0x6e88e56f    snd_pcm_link_rwlock     vmlinux EXPORT_SYMBOL
++0x2ebe3135    cpu_is_hotpluggable     vmlinux EXPORT_SYMBOL_GPL
++0xd3dbfbc4    _find_first_zero_bit_le vmlinux EXPORT_SYMBOL
++0x949f7fd6    snd_soc_unregister_codec        vmlinux EXPORT_SYMBOL_GPL
++0x66b5d30a    get_disk        vmlinux EXPORT_SYMBOL
++0xd5c3ad66    blk_pm_runtime_init     vmlinux EXPORT_SYMBOL
++0x55737546    __free_pages    vmlinux EXPORT_SYMBOL
++0xfa012fe7    tracepoint_probe_register       vmlinux EXPORT_SYMBOL_GPL
++0xf8802492    print_stack_trace       vmlinux EXPORT_SYMBOL_GPL
++0x50601122    of_property_match_string        vmlinux EXPORT_SYMBOL_GPL
++0x70fde9b2    vb2_reqbufs     vmlinux EXPORT_SYMBOL_GPL
++0x9b680a42    ump_dd_reference_release        vmlinux EXPORT_SYMBOL
++0x13d5d619    cfg80211_crit_proto_stopped     vmlinux EXPORT_SYMBOL
++0xd5a7d477    inet_bind       vmlinux EXPORT_SYMBOL
++0xc5495840    nf_nat_amanda_hook      vmlinux EXPORT_SYMBOL_GPL
++0xe08e58c9    qdisc_watchdog_init     vmlinux EXPORT_SYMBOL
++0xe447fb89    __register_binfmt       vmlinux EXPORT_SYMBOL
++0xbd3321ae    power_supply_class      vmlinux EXPORT_SYMBOL_GPL
++0x0ce6d0b9    usb_gadget_probe_driver vmlinux EXPORT_SYMBOL_GPL
++0xae544f3a    usb_hcd_end_port_resume vmlinux EXPORT_SYMBOL_GPL
++0x8fd8a453    pm_genpd_dev_need_restore       vmlinux EXPORT_SYMBOL_GPL
++0x7b95ab7d    class_find_device       vmlinux EXPORT_SYMBOL_GPL
++0x21455002    xfrm_init_state vmlinux EXPORT_SYMBOL
++0xf06e724d    snd_pcm_debug_name      vmlinux EXPORT_SYMBOL
++0x89ca47bf    kstrtos8_from_user      vmlinux EXPORT_SYMBOL
++0x68d0d389    crypto_init_spawn2      vmlinux EXPORT_SYMBOL_GPL
++0x01c6cb0c    cpu_cluster_pm_enter    vmlinux EXPORT_SYMBOL_GPL
++0xd1efa60f    st_accel_common_remove  vmlinux EXPORT_SYMBOL
++0xf398c9eb    vb2_create_bufs vmlinux EXPORT_SYMBOL_GPL
++0xc385cb58    perf_num_counters       vmlinux EXPORT_SYMBOL_GPL
++0x87634adf    xfrm_user_policy        vmlinux EXPORT_SYMBOL
++0xe0741a0a    netif_napi_add  vmlinux EXPORT_SYMBOL
++0xf12cddd6    skb_split       vmlinux EXPORT_SYMBOL
++0xdee12a28    input_grab_device       vmlinux EXPORT_SYMBOL
++0x95e73973    tty_port_block_til_ready        vmlinux EXPORT_SYMBOL
++0x53a3e486    regulator_get_current_limit     vmlinux EXPORT_SYMBOL_GPL
++0x5dd18380    regulator_get_init_drvdata      vmlinux EXPORT_SYMBOL_GPL
++0x8467a73f    netlink_broadcast       vmlinux EXPORT_SYMBOL
++0x6d1a8997    block_write_full_page_endio     vmlinux EXPORT_SYMBOL
++0x197519cc    shmem_file_setup        vmlinux EXPORT_SYMBOL_GPL
++0x8b8059bd    in_group_p      vmlinux EXPORT_SYMBOL
++0xc631580a    console_unlock  vmlinux EXPORT_SYMBOL
++0xe8400441    of_property_read_string_index   vmlinux EXPORT_SYMBOL_GPL
++0x0343bdf1    __i2c_board_list        vmlinux EXPORT_SYMBOL_GPL
++0xa5dd6fae    arm_pm_restart  vmlinux EXPORT_SYMBOL_GPL
++0x97fe8a2d    udp_sendmsg     vmlinux EXPORT_SYMBOL
++0x35fbd6a1    __kfifo_dma_out_prepare_r       vmlinux EXPORT_SYMBOL
++0xa3e220e7    elv_rb_former_request   vmlinux EXPORT_SYMBOL
++0xdf76bbeb    iio_pollfunc_store_time vmlinux EXPORT_SYMBOL
++0xfc30d3a1    mmc_start_req   vmlinux EXPORT_SYMBOL
++0xf53d4c26    qdisc_class_hash_destroy        vmlinux EXPORT_SYMBOL
++0x5e61da38    snd_timer_stop  vmlinux EXPORT_SYMBOL
++0xa6e1a69d    kick_all_cpus_sync      vmlinux EXPORT_SYMBOL_GPL
++0x68cb9861    sdio_register_driver    vmlinux EXPORT_SYMBOL_GPL
++0xb575c1a1    usb_kill_urb    vmlinux EXPORT_SYMBOL_GPL
++0x8ab265d2    usb_get_intf    vmlinux EXPORT_SYMBOL_GPL
++0xdbd7794d    cfg80211_ready_on_channel       vmlinux EXPORT_SYMBOL
++0xff112bd5    proc_get_parent_data    vmlinux EXPORT_SYMBOL_GPL
++0x0bec8a3d    audit_log       vmlinux EXPORT_SYMBOL
++0x5d9521f8    set_security_override_from_ctx  vmlinux EXPORT_SYMBOL
++0x235d1d10    drm_gem_prime_import    vmlinux EXPORT_SYMBOL
++0x7da24ff0    drm_helper_encoder_in_use       vmlinux EXPORT_SYMBOL
++0x6f3c606d    nfc_hci_register_device vmlinux EXPORT_SYMBOL
++0xf447e205    ip_tunnel_uninit        vmlinux EXPORT_SYMBOL_GPL
++0x5055493c    sk_wait_data    vmlinux EXPORT_SYMBOL
++0xb1b87423    crypto_remove_spawns    vmlinux EXPORT_SYMBOL_GPL
++0x4fd4e89d    ring_buffer_empty_cpu   vmlinux EXPORT_SYMBOL_GPL
++0xaa4704e1    usb_autopm_put_interface_no_suspend     vmlinux EXPORT_SYMBOL_GPL
++0x50e28c07    drm_edid_to_sad vmlinux EXPORT_SYMBOL
++0x6d57e7f8    drm_edid_to_eld vmlinux EXPORT_SYMBOL
++0x3fe12ddc    xt_replace_table        vmlinux EXPORT_SYMBOL_GPL
++0x9c3737fc    __percpu_counter_init   vmlinux EXPORT_SYMBOL
++0xf846506f    irq_set_affinity_notifier       vmlinux EXPORT_SYMBOL_GPL
++0x469a0b25    inet_hashinfo_init      vmlinux EXPORT_SYMBOL_GPL
++0x3fbf68bd    ipv4_sk_redirect        vmlinux EXPORT_SYMBOL_GPL
++0x151bc10b    end_buffer_read_sync    vmlinux EXPORT_SYMBOL
++0xb013af25    set_cpus_allowed_ptr    vmlinux EXPORT_SYMBOL_GPL
++0x227badd6    mod_timer_pinned        vmlinux EXPORT_SYMBOL
++0xf37cfbf5    dm_dispatch_request     vmlinux EXPORT_SYMBOL_GPL
++0x1d96bf04    input_mt_report_pointer_emulation       vmlinux EXPORT_SYMBOL
++0x94289922    mali_pmu_powerdown      vmlinux EXPORT_SYMBOL
++0xe9d6e0bd    pwm_request     vmlinux EXPORT_SYMBOL_GPL
++0xd66a2750    tcf_em_tree_dump        vmlinux EXPORT_SYMBOL
++0x790c22d3    neigh_for_each  vmlinux EXPORT_SYMBOL
++0x3ed096c1    sg_miter_next   vmlinux EXPORT_SYMBOL
++0x96b878b6    crypto_init_shash_spawn vmlinux EXPORT_SYMBOL_GPL
++0x1fd19684    crypto_init_ahash_spawn vmlinux EXPORT_SYMBOL_GPL
++0xedc85914    posix_timers_register_clock     vmlinux EXPORT_SYMBOL_GPL
++0xc702156b    param_get_ushort        vmlinux EXPORT_SYMBOL
++0x65bca4ff    vb2_plane_cookie        vmlinux EXPORT_SYMBOL_GPL
++0x294a6993    rtc_initialize_alarm    vmlinux EXPORT_SYMBOL_GPL
++0x6971447a    rtc_month_days  vmlinux EXPORT_SYMBOL
++0x7e64181d    usb_calc_bus_time       vmlinux EXPORT_SYMBOL_GPL
++0x5f1f36bc    drm_calc_vbltimestamp_from_scanoutpos   vmlinux EXPORT_SYMBOL
++0xe0af2dc1    regulator_is_enabled_regmap     vmlinux EXPORT_SYMBOL_GPL
++0x57c3621e    skb_pull        vmlinux EXPORT_SYMBOL
++0xeb0a7f4c    clk_register    vmlinux EXPORT_SYMBOL_GPL
++0xabc6dd63    cpufreq_sysfs_create_file       vmlinux EXPORT_SYMBOL
++0x1eee0a80    usb_find_interface      vmlinux EXPORT_SYMBOL_GPL
++0xb524d8dc    amba_find_device        vmlinux EXPORT_SYMBOL
++0x8574ca6c    gpio_request_array      vmlinux EXPORT_SYMBOL_GPL
++0x93d2422d    snmp_mib_free   vmlinux EXPORT_SYMBOL_GPL
++0x5d51bcf7    scatterwalk_start       vmlinux EXPORT_SYMBOL_GPL
++0x417e3755    sysfs_put       vmlinux EXPORT_SYMBOL_GPL
++0x2ba54bff    irq_remove_generic_chip vmlinux EXPORT_SYMBOL_GPL
++0x420c729a    vb2_fop_poll    vmlinux EXPORT_SYMBOL_GPL
++0xe6d23987    phy_start_interrupts    vmlinux EXPORT_SYMBOL
++0x1fb1615f    spi_master_resume       vmlinux EXPORT_SYMBOL_GPL
++0xcd721bb7    scsi_get_vpd_page       vmlinux EXPORT_SYMBOL_GPL
++0xac2bd611    pm_generic_restore_noirq        vmlinux EXPORT_SYMBOL_GPL
++0xe0b7aa47    drm_i2c_encoder_dpms    vmlinux EXPORT_SYMBOL
++0x9dfdf722    gpio_free_array vmlinux EXPORT_SYMBOL_GPL
++0x7345660c    xfrm_state_check_expire vmlinux EXPORT_SYMBOL
++0xd5dba10e    sock_diag_unregister_inet_compat        vmlinux EXPORT_SYMBOL_GPL
++0xfd719be0    netdev_boot_setup_check vmlinux EXPORT_SYMBOL
++0xa9c6e543    sock_i_uid      vmlinux EXPORT_SYMBOL
++0x2dfe841c    sock_i_ino      vmlinux EXPORT_SYMBOL
++0x4bc2dc22    seq_bitmap      vmlinux EXPORT_SYMBOL
++0x4b8e839a    cpufreq_global_kobject  vmlinux EXPORT_SYMBOL
++0xc12cf8f8    v4l2_ctrl_replace       vmlinux EXPORT_SYMBOL
++0xf3dd036d    regulator_set_voltage_time      vmlinux EXPORT_SYMBOL_GPL
++0x88826167    ip_build_and_send_pkt   vmlinux EXPORT_SYMBOL_GPL
++0xd09ce8d0    register_gifconf        vmlinux EXPORT_SYMBOL
++0xaa6901ac    __kfifo_out_r   vmlinux EXPORT_SYMBOL
++0x64f7667b    crypto_rng_type vmlinux EXPORT_SYMBOL_GPL
++0x457594fa    crypto_alg_list vmlinux EXPORT_SYMBOL_GPL
++0x665b8183    sync_inode_metadata     vmlinux EXPORT_SYMBOL
++0x03026722    mempool_alloc   vmlinux EXPORT_SYMBOL
++0x0034f927    unregister_wide_hw_breakpoint   vmlinux EXPORT_SYMBOL_GPL
++0x86f6b99d    synchronize_rcu_expedited       vmlinux EXPORT_SYMBOL_GPL
++0xec4d9e3a    clk_get_sys     vmlinux EXPORT_SYMBOL
++0x1b6b3f33    cpufreq_unregister_driver       vmlinux EXPORT_SYMBOL_GPL
++0x56ca80ea    drm_mode_validate_clocks        vmlinux EXPORT_SYMBOL
++0xa66a1f63    drm_rmmap_locked        vmlinux EXPORT_SYMBOL
++0x6b07a31b    regulator_get_voltage_sel_regmap        vmlinux EXPORT_SYMBOL_GPL
++0x5107f9ce    gpiochip_find   vmlinux EXPORT_SYMBOL_GPL
++0x05365f80    cfg80211_cac_event      vmlinux EXPORT_SYMBOL
++0xc05ac2c8    cfg80211_classify8021d  vmlinux EXPORT_SYMBOL
++0x92be9264    snd_soc_register_platform       vmlinux EXPORT_SYMBOL_GPL
++0xfaf79bc2    __srcu_read_lock        vmlinux EXPORT_SYMBOL_GPL
++0xada5e980    media_entity_pipeline_start     vmlinux EXPORT_SYMBOL_GPL
++0x74fbf451    drm_mm_init_scan_with_range     vmlinux EXPORT_SYMBOL
++0xd03c7700    secure_ipv4_port_ephemeral      vmlinux EXPORT_SYMBOL_GPL
++0x9c9ec2a0    proc_dointvec_minmax    vmlinux EXPORT_SYMBOL
++0x8d772b8c    v4l2_clk_get    vmlinux EXPORT_SYMBOL
++0x32680bfc    usb_function_unregister vmlinux EXPORT_SYMBOL_GPL
++0x6dd8ac23    dev_uc_add_excl vmlinux EXPORT_SYMBOL
++0xced0fa87    dev_mc_add_excl vmlinux EXPORT_SYMBOL
++0x51cc09c6    kmalloc_caches  vmlinux EXPORT_SYMBOL
++0x3ef23944    i2c_bus_type    vmlinux EXPORT_SYMBOL_GPL
++0x015f6d7d    kmap    vmlinux EXPORT_SYMBOL
++0x0b9a5c65    icmpv6_send     vmlinux EXPORT_SYMBOL
++0x6625c30d    blk_queue_make_request  vmlinux EXPORT_SYMBOL
++0x25dd3b83    sysfs_add_link_to_group vmlinux EXPORT_SYMBOL_GPL
++0x472d363a    truncate_pagecache_range        vmlinux EXPORT_SYMBOL
++0x0bf3e830    put_page        vmlinux EXPORT_SYMBOL
++0x74954462    timecounter_read        vmlinux EXPORT_SYMBOL_GPL
++0x3aa9f288    iio_channel_get vmlinux EXPORT_SYMBOL_GPL
++0x1fd6672b    video_device_release_empty      vmlinux EXPORT_SYMBOL
++0x931dcc9d    usbnet_pause_rx vmlinux EXPORT_SYMBOL_GPL
++0x4c83a264    do_take_over_console    vmlinux EXPORT_SYMBOL_GPL
++0xe2dd67e5    regulator_set_current_limit     vmlinux EXPORT_SYMBOL_GPL
++0xb23f3373    nf_conntrack_lock       vmlinux EXPORT_SYMBOL_GPL
++0xebfa66fa    security_inode_setsecctx        vmlinux EXPORT_SYMBOL
++0x819ed3be    vfs_getattr     vmlinux EXPORT_SYMBOL
++0x2fad0dbe    led_classdev_resume     vmlinux EXPORT_SYMBOL_GPL
++0xbc497919    rtc_device_register     vmlinux EXPORT_SYMBOL_GPL
++0xd58c665a    input_reset_device      vmlinux EXPORT_SYMBOL
++0x34c728d0    tty_ldisc_deref vmlinux EXPORT_SYMBOL_GPL
++0xfb28827b    inet_del_protocol       vmlinux EXPORT_SYMBOL
++0x95587915    neigh_update    vmlinux EXPORT_SYMBOL
++0xc9b8c308    __kfifo_dma_out_prepare vmlinux EXPORT_SYMBOL
++0xd9b9b70a    put_io_context  vmlinux EXPORT_SYMBOL
++0xac7726b4    blk_queue_io_min        vmlinux EXPORT_SYMBOL
++0xcf807506    nobh_truncate_page      vmlinux EXPORT_SYMBOL
++0x43ec231b    iio_device_free vmlinux EXPORT_SYMBOL
++0x95ae5064    phy_stop        vmlinux EXPORT_SYMBOL
++0xb69d1c51    spi_bitbang_start       vmlinux EXPORT_SYMBOL_GPL
++0x87876bed    drm_kms_helper_poll_enable      vmlinux EXPORT_SYMBOL
++0x045072cd    nf_ct_port_nla_policy   vmlinux EXPORT_SYMBOL_GPL
++0x4be7fb63    up      vmlinux EXPORT_SYMBOL
++0xf8a32b55    icmp_send       vmlinux EXPORT_SYMBOL
++0x69f7d81d    path_get        vmlinux EXPORT_SYMBOL
++0xd715763b    iov_iter_copy_from_user_atomic  vmlinux EXPORT_SYMBOL
++0xc7b9fe08    drm_property_create_bitmask     vmlinux EXPORT_SYMBOL
++0x671a649b    xfrm_state_update       vmlinux EXPORT_SYMBOL
++0xce3c5240    crypto_grab_aead        vmlinux EXPORT_SYMBOL_GPL
++0xb590822d    hrtimer_start   vmlinux EXPORT_SYMBOL_GPL
++0xaebe783e    get_pid_task    vmlinux EXPORT_SYMBOL_GPL
++0xa8bcfa1a    usb_deregister_dev      vmlinux EXPORT_SYMBOL_GPL
++0xc398c5f3    usb_hcd_is_primary_hcd  vmlinux EXPORT_SYMBOL_GPL
++0x7c45fec1    pm_generic_resume_noirq vmlinux EXPORT_SYMBOL_GPL
++0x6c702af7    sysctl_udp_rmem_min     vmlinux EXPORT_SYMBOL
++0x9b3122cd    dev_open        vmlinux EXPORT_SYMBOL
++0x7ee7a9f8    lock_sock_fast  vmlinux EXPORT_SYMBOL
++0xc3b7e3fb    snd_cards       vmlinux EXPORT_SYMBOL
++0x82bbf933    ilookup vmlinux EXPORT_SYMBOL
++0x4302d0eb    free_pages      vmlinux EXPORT_SYMBOL
++0xefc91531    irq_create_of_mapping   vmlinux EXPORT_SYMBOL_GPL
++0xb90f9844    sdhci_resume_host       vmlinux EXPORT_SYMBOL_GPL
++0x8ec22c0b    nat_q931_hook   vmlinux EXPORT_SYMBOL_GPL
++0x03592ea0    security_unix_stream_connect    vmlinux EXPORT_SYMBOL
++0x4397c48f    generic_file_fsync      vmlinux EXPORT_SYMBOL
++0x5154c361    unlock_new_inode        vmlinux EXPORT_SYMBOL
++0xa9b83487    __f_setown      vmlinux EXPORT_SYMBOL
++0x9ccb1788    irq_create_direct_mapping       vmlinux EXPORT_SYMBOL_GPL
++0xf82f16b3    execute_in_process_context      vmlinux EXPORT_SYMBOL_GPL
++0xcd06de19    mdiobus_free    vmlinux EXPORT_SYMBOL
++0xfd99623a    ip_frag_ecn_table       vmlinux EXPORT_SYMBOL
++0x17ee142e    xt_find_table_lock      vmlinux EXPORT_SYMBOL_GPL
++0x62737e1d    sock_unregister vmlinux EXPORT_SYMBOL
++0x67095031    kset_register   vmlinux EXPORT_SYMBOL
++0x84ffea8b    idr_preload     vmlinux EXPORT_SYMBOL
++0xd29fb507    fput    vmlinux EXPORT_SYMBOL
++0xe3d6f284    fb_find_mode_cvt        vmlinux EXPORT_SYMBOL
++0x14d4a9c5    _change_bit     vmlinux EXPORT_SYMBOL
++0x54411a42    posix_timer_event       vmlinux EXPORT_SYMBOL_GPL
++0x2a79ac13    clkdev_add      vmlinux EXPORT_SYMBOL
++0x3d6f446b    platform_device_alloc   vmlinux EXPORT_SYMBOL_GPL
++0xf85bebf9    dev_printk_emit vmlinux EXPORT_SYMBOL
++0xde36a037    ip6_frag_init   vmlinux EXPORT_SYMBOL
++0x31e23d78    __fsnotify_parent       vmlinux EXPORT_SYMBOL_GPL
++0xdea4fcaa    pm_qos_add_request      vmlinux EXPORT_SYMBOL_GPL
++0x1976aa06    param_ops_bool  vmlinux EXPORT_SYMBOL
++0x98ba0e88    pm_generic_suspend_noirq        vmlinux EXPORT_SYMBOL_GPL
++0xecefd1b6    display_entity_get_params       vmlinux EXPORT_SYMBOL_GPL
++0xdfb5c1e5    add_disk        vmlinux EXPORT_SYMBOL
++0x5754706e    media_entity_get        vmlinux EXPORT_SYMBOL_GPL
++0xbd008b38    media_entity_put        vmlinux EXPORT_SYMBOL_GPL
++0x5d1e2494    usb_ep0_reinit  vmlinux EXPORT_SYMBOL_GPL
++0x0ae4b94c    drm_ht_remove   vmlinux EXPORT_SYMBOL
++0x6ab922b2    regulator_get_drvdata   vmlinux EXPORT_SYMBOL_GPL
++0x4432d365    __udp6_lib_lookup       vmlinux EXPORT_SYMBOL_GPL
++0x08696053    inet_shutdown   vmlinux EXPORT_SYMBOL
++0x52212010    __tracepoint_block_bio_remap    vmlinux EXPORT_SYMBOL_GPL
++0xc29afc9a    posix_lock_file_wait    vmlinux EXPORT_SYMBOL
++0x01fd453e    usbhid_lookup_quirk     vmlinux EXPORT_SYMBOL_GPL
++0x90705b7f    syscon_node_to_regmap   vmlinux EXPORT_SYMBOL_GPL
++0xf72d56a2    regulator_set_voltage_sel_regmap        vmlinux EXPORT_SYMBOL_GPL
++0xa308e150    nfc_hci_disconnect_gate vmlinux EXPORT_SYMBOL
++0x7707c1b0    xt_unregister_table     vmlinux EXPORT_SYMBOL_GPL
++0x4e830a3e    strnicmp        vmlinux EXPORT_SYMBOL
++0x48f2cf7c    vmalloc_to_page vmlinux EXPORT_SYMBOL
++0x3dca446d    drm_handle_vblank       vmlinux EXPORT_SYMBOL
++0x22ca070b    uart_remove_one_port    vmlinux EXPORT_SYMBOL
++0x1d027e4b    snd_pcm_format_signed   vmlinux EXPORT_SYMBOL
++0x3535ae4a    blk_update_request      vmlinux EXPORT_SYMBOL_GPL
++0x02649054    security_sock_rcv_skb   vmlinux EXPORT_SYMBOL
++0x547077ec    __wake_up_bit   vmlinux EXPORT_SYMBOL
++0x1c5541bd    cpufreq_boost_enabled   vmlinux EXPORT_SYMBOL_GPL
++0x6d186427    usb_get_hcd     vmlinux EXPORT_SYMBOL_GPL
++0x8eff9111    drm_ht_find_item        vmlinux EXPORT_SYMBOL
++0xd9d18f03    fbcon_set_bitops        vmlinux EXPORT_SYMBOL
++0xfaea036f    sock_release    vmlinux EXPORT_SYMBOL
++0xa414882d    add_wait_queue_exclusive        vmlinux EXPORT_SYMBOL
++0x06e80ae6    s3c_adc_register        vmlinux EXPORT_SYMBOL_GPL
++0x63805ac9    usb_hcd_giveback_urb    vmlinux EXPORT_SYMBOL_GPL
++0xf8d54998    ump_dd_handle_create_from_phys_blocks   vmlinux EXPORT_SYMBOL
++0x44242685    drm_prime_gem_destroy   vmlinux EXPORT_SYMBOL
++0x4faff87a    drm_i2c_encoder_mode_fixup      vmlinux EXPORT_SYMBOL
++0x0f995f4e    tty_port_tty_wakeup     vmlinux EXPORT_SYMBOL_GPL
++0x91b2790d    regulator_map_voltage_ascend    vmlinux EXPORT_SYMBOL_GPL
++0x0e29d022    nf_nat_icmp_reply_translation   vmlinux EXPORT_SYMBOL_GPL
++0x75811312    crc_ccitt_table vmlinux EXPORT_SYMBOL
++0xe9eb0c04    d_add_ci        vmlinux EXPORT_SYMBOL
++0x4c55b4df    led_trigger_rename_static       vmlinux EXPORT_SYMBOL_GPL
++0x6f344bb9    v4l2_calc_aspect_ratio  vmlinux EXPORT_SYMBOL_GPL
++0xc4f83bea    drm_debugfs_create_files        vmlinux EXPORT_SYMBOL
++0x9ae51e43    tty_register_device_attr        vmlinux EXPORT_SYMBOL_GPL
++0x80c70b19    phys_mem_access_prot    vmlinux EXPORT_SYMBOL
++0x17770200    __skb_checksum_complete_head    vmlinux EXPORT_SYMBOL
++0x1eeb848e    __percpu_counter_sum    vmlinux EXPORT_SYMBOL
++0xd74289f9    __percpu_counter_add    vmlinux EXPORT_SYMBOL
++0xa77a369d    idr_init        vmlinux EXPORT_SYMBOL
++0x8e5c580a    ida_init        vmlinux EXPORT_SYMBOL
++0xb99d677c    mpage_readpage  vmlinux EXPORT_SYMBOL
++0x70bc17d7    inode_wait      vmlinux EXPORT_SYMBOL
++0xd6ee688f    vmalloc vmlinux EXPORT_SYMBOL
++0xf31b3fd1    workqueue_set_max_active        vmlinux EXPORT_SYMBOL_GPL
++0x9745c52a    of_fixed_clk_setup      vmlinux EXPORT_SYMBOL_GPL
++0xbfd6a20b    phy_ethtool_set_wol     vmlinux EXPORT_SYMBOL
++0x64004900    phy_ethtool_get_wol     vmlinux EXPORT_SYMBOL
++0x28492539    spi_bitbang_transfer    vmlinux EXPORT_SYMBOL_GPL
++0x6552f2d8    unlink_framebuffer      vmlinux EXPORT_SYMBOL
++0xbdf2580d    __raw_readsl    vmlinux EXPORT_SYMBOL
++0xabe519d2    blk_queue_io_opt        vmlinux EXPORT_SYMBOL
++0x05b2af42    bdgrab  vmlinux EXPORT_SYMBOL
++0xd4c14632    system_unbound_wq       vmlinux EXPORT_SYMBOL_GPL
++0x098859e1    usbnet_cdc_status       vmlinux EXPORT_SYMBOL_GPL
++0xd1bd52ba    tty_port_raise_dtr_rts  vmlinux EXPORT_SYMBOL
++0x4ea1f5a2    drm_gem_object_free     vmlinux EXPORT_SYMBOL
++0x86d53c76    mb_cache_entry_find_first       vmlinux EXPORT_SYMBOL
++0xf0b9f940    usb_function_activate   vmlinux EXPORT_SYMBOL_GPL
++0x9d2ee507    scsi_adjust_queue_depth vmlinux EXPORT_SYMBOL
++0x4bca6b0c    drm_get_edid    vmlinux EXPORT_SYMBOL
++0x4a5d2ace    tcp_unregister_congestion_control       vmlinux EXPORT_SYMBOL_GPL
++0x0274dc2b    netif_get_num_default_rss_queues        vmlinux EXPORT_SYMBOL
++0x53be6f80    bio_split       vmlinux EXPORT_SYMBOL
++0x1fc0da41    lock_rename     vmlinux EXPORT_SYMBOL
++0xbe421975    __locks_copy_lock       vmlinux EXPORT_SYMBOL
++0x69e3cb9f    mutex_lock_killable     vmlinux EXPORT_SYMBOL
++0x9c612795    v4l2_chip_match_i2c_client      vmlinux EXPORT_SYMBOL
++0xd2f84424    i2c_bit_add_bus vmlinux EXPORT_SYMBOL
++0x421cdcbd    usb_function_deactivate vmlinux EXPORT_SYMBOL_GPL
++0x63a86872    class_destroy   vmlinux EXPORT_SYMBOL_GPL
++0x231d4001    fb_edid_add_monspecs    vmlinux EXPORT_SYMBOL
++0xb01a37d3    gpiochip_remove vmlinux EXPORT_SYMBOL_GPL
++0xcc2b7257    tcp_check_req   vmlinux EXPORT_SYMBOL
++0x16270acd    tcp_init_sock   vmlinux EXPORT_SYMBOL
++0x143dc3b0    netlink_unicast vmlinux EXPORT_SYMBOL
++0x8452993c    neigh_sysctl_register   vmlinux EXPORT_SYMBOL
++0xce602df6    cgroup_is_descendant    vmlinux EXPORT_SYMBOL_GPL
++0xdddba0ab    exynos_g2d_get_ver_ioctl        vmlinux EXPORT_SYMBOL_GPL
++0xf2c642ed    tty_port_tty_hangup     vmlinux EXPORT_SYMBOL_GPL
++0x7d086e6f    snd_soc_put_volsw_range vmlinux EXPORT_SYMBOL_GPL
++0xaf23bb74    snd_soc_get_volsw_range vmlinux EXPORT_SYMBOL_GPL
++0x01b2facc    snd_timer_start vmlinux EXPORT_SYMBOL
++0x1e693956    set_nlink       vmlinux EXPORT_SYMBOL
++0xdcb0349b    sys_close       vmlinux EXPORT_SYMBOL
++0xaf348da7    cpu_pm_exit     vmlinux EXPORT_SYMBOL_GPL
++0x77d1afb4    kill_pgrp       vmlinux EXPORT_SYMBOL
++0x3b9d009a    drm_format_plane_cpp    vmlinux EXPORT_SYMBOL
++0x2acd3e60    fat_build_inode vmlinux EXPORT_SYMBOL_GPL
++0x0f3ef271    seq_read        vmlinux EXPORT_SYMBOL
++0x712fb5a8    is_bad_inode    vmlinux EXPORT_SYMBOL
++0x253bdb78    param_get_int   vmlinux EXPORT_SYMBOL
++0xd35fa891    st_sensors_write_event_config   vmlinux EXPORT_SYMBOL
++0x203bef91    device_wakeup_disable   vmlinux EXPORT_SYMBOL_GPL
++0xd454eabb    tcf_hash_new_index      vmlinux EXPORT_SYMBOL
++0x235e7e6a    shash_ahash_finup       vmlinux EXPORT_SYMBOL_GPL
++0x60384c87    start_tty       vmlinux EXPORT_SYMBOL
++0x6513a3fa    fb_get_color_depth      vmlinux EXPORT_SYMBOL
++0x7ffc8718    gpio_set_debounce       vmlinux EXPORT_SYMBOL_GPL
++0x6c95cbd5    phonet_proto_register   vmlinux EXPORT_SYMBOL
++0xa01cac38    nf_ct_get_tuplepr       vmlinux EXPORT_SYMBOL_GPL
++0x3e872db6    __netdev_pick_tx        vmlinux EXPORT_SYMBOL
++0x981f509d    skb_free_datagram_locked        vmlinux EXPORT_SYMBOL
++0x93e0379d    kernel_sock_shutdown    vmlinux EXPORT_SYMBOL
++0x878eae99    snd_pcm_add_chmap_ctls  vmlinux EXPORT_SYMBOL_GPL
++0xd454865d    snd_pcm_notify  vmlinux EXPORT_SYMBOL
++0xa735db59    prandom_u32     vmlinux EXPORT_SYMBOL
++0x8e864a86    posix_acl_chmod vmlinux EXPORT_SYMBOL
++0xf9910a86    notify_change   vmlinux EXPORT_SYMBOL
++0x423b589c    follow_up       vmlinux EXPORT_SYMBOL
++0xa577a850    param_get_short vmlinux EXPORT_SYMBOL
++0x24b55d2b    of_find_i2c_adapter_by_node     vmlinux EXPORT_SYMBOL
++0x6d0f1f89    dm_table_get_mode       vmlinux EXPORT_SYMBOL
++0x2ca4ebcd    regulator_set_drvdata   vmlinux EXPORT_SYMBOL_GPL
++0x02196324    __aeabi_idiv    vmlinux EXPORT_SYMBOL
++0xf0e3bec8    nf_log_bind_pf  vmlinux EXPORT_SYMBOL
++0xd12698d0    skb_copy_and_csum_datagram_iovec        vmlinux EXPORT_SYMBOL
++0xd23bebab    sock_no_ioctl   vmlinux EXPORT_SYMBOL
++0xf401a5f4    get_user_pages_fast     vmlinux EXPORT_SYMBOL_GPL
++0xca85d8cf    tracepoint_probe_update_all     vmlinux EXPORT_SYMBOL_GPL
++0x54740eb7    get_cpu_idle_time       vmlinux EXPORT_SYMBOL_GPL
++0x2a3aa678    _test_and_clear_bit     vmlinux EXPORT_SYMBOL
++0x694967d9    nf_conntrack_find_get   vmlinux EXPORT_SYMBOL_GPL
++0x19a2badf    snd_soc_codec_set_sysclk        vmlinux EXPORT_SYMBOL_GPL
++0x93a2419d    simple_empty    vmlinux EXPORT_SYMBOL
++0x68a13545    vm_mmap vmlinux EXPORT_SYMBOL
++0x224190b8    shmem_read_mapping_page_gfp     vmlinux EXPORT_SYMBOL_GPL
++0xd859f1d5    dw_mci_pltfm_register   vmlinux EXPORT_SYMBOL_GPL
++0xc955c267    serio_unregister_child_port     vmlinux EXPORT_SYMBOL
++0xcbee09f7    scsi_remove_device      vmlinux EXPORT_SYMBOL
++0xcd579f54    xfrm_cfg_mutex  vmlinux EXPORT_SYMBOL
++0xb63be252    __sk_mem_schedule       vmlinux EXPORT_SYMBOL
++0xcde172ac    radix_tree_gang_lookup_tag_slot vmlinux EXPORT_SYMBOL
++0x61860fe5    blk_queue_merge_bvec    vmlinux EXPORT_SYMBOL
++0xd223c00d    fuse_file_poll  vmlinux EXPORT_SYMBOL_GPL
++0x4b6e004b    mnt_want_write_file     vmlinux EXPORT_SYMBOL_GPL
++0x11ad8ba6    __hid_register_driver   vmlinux EXPORT_SYMBOL_GPL
++0x3d8ed8f5    hid_disconnect  vmlinux EXPORT_SYMBOL_GPL
++0x70cf032f    usb_hcd_irq     vmlinux EXPORT_SYMBOL_GPL
++0xc0a9a9a1    hci_register_cb vmlinux EXPORT_SYMBOL
++0x83b21051    ip_ct_attach    vmlinux EXPORT_SYMBOL
++0x24eb8d39    dev_set_mtu     vmlinux EXPORT_SYMBOL
++0xbd5c42d9    crypto_unregister_template      vmlinux EXPORT_SYMBOL_GPL
++0x2deda4a1    security_sk_classify_flow       vmlinux EXPORT_SYMBOL
++0xe694a9ce    bd_link_disk_holder     vmlinux EXPORT_SYMBOL_GPL
++0xf1a33551    usb_string_ids_tab      vmlinux EXPORT_SYMBOL_GPL
++0x565b6892    uuid_le_gen     vmlinux EXPORT_SYMBOL_GPL
++0x68956406    static_key_slow_dec     vmlinux EXPORT_SYMBOL_GPL
++0x335c570f    enable_percpu_irq       vmlinux EXPORT_SYMBOL_GPL
++0x02e1a3ed    should_remove_suid      vmlinux EXPORT_SYMBOL
++0x0626da5f    od_unregister_powersave_bias_handler    vmlinux EXPORT_SYMBOL_GPL
++0x4dcfd46b    scsi_free_host_dev      vmlinux EXPORT_SYMBOL
++0xfec445a3    driver_register vmlinux EXPORT_SYMBOL_GPL
++0x3d1b2e32    find_lock_page  vmlinux EXPORT_SYMBOL
++0x92ea202d    srcu_notifier_chain_unregister  vmlinux EXPORT_SYMBOL_GPL
++0xdb9d11d6    iio_buffer_store_enable vmlinux EXPORT_SYMBOL
++0x2ceca451    input_ff_create vmlinux EXPORT_SYMBOL_GPL
++0x6e3d17ac    device_destroy  vmlinux EXPORT_SYMBOL_GPL
++0xb8d2fd38    wiphy_register  vmlinux EXPORT_SYMBOL
++0xfa4d8a1f    unregister_pernet_device        vmlinux EXPORT_SYMBOL_GPL
++0x4c86184b    remove_wait_queue       vmlinux EXPORT_SYMBOL
++0x4845c423    param_array_ops vmlinux EXPORT_SYMBOL
++0x2cd6eb8b    input_ff_destroy        vmlinux EXPORT_SYMBOL_GPL
++0xb9500ec7    mfd_cell_disable        vmlinux EXPORT_SYMBOL
++0x1a2759ff    platform_get_irq_byname vmlinux EXPORT_SYMBOL_GPL
++0x8daf9344    napi_get_frags  vmlinux EXPORT_SYMBOL
++0x60c805dd    sk_stream_write_space   vmlinux EXPORT_SYMBOL
++0x570e3195    scsi_verify_blk_ioctl   vmlinux EXPORT_SYMBOL
++0xecbe66b8    sysfs_notify_dirent     vmlinux EXPORT_SYMBOL_GPL
++0x158df5f3    kill_bdev       vmlinux EXPORT_SYMBOL
++0x3eb2b460    v4l2_event_unsubscribe  vmlinux EXPORT_SYMBOL_GPL
++0x8e38bb44    ipv6_dup_options        vmlinux EXPORT_SYMBOL_GPL
++0xe306f9d8    cgroup_attach_task_all  vmlinux EXPORT_SYMBOL_GPL
++0x6b06fdce    delayed_work_timer_fn   vmlinux EXPORT_SYMBOL
++0x8104c3bb    phy_register_fixup_for_id       vmlinux EXPORT_SYMBOL
++0x46d3b28c    __div0  vmlinux EXPORT_SYMBOL
++0x7ead817c    __idr_pre_get   vmlinux EXPORT_SYMBOL
++0x6cc299a1    zap_vma_ptes    vmlinux EXPORT_SYMBOL_GPL
++0x1f0972cb    drm_fasync      vmlinux EXPORT_SYMBOL
++0x35c653fb    xfrm_policy_bysel_ctx   vmlinux EXPORT_SYMBOL
++0x8e81d5af    tcp_sendmsg     vmlinux EXPORT_SYMBOL
++0xf9ebc368    snd_soc_new_ac97_codec  vmlinux EXPORT_SYMBOL_GPL
++0x4528c501    elv_rb_del      vmlinux EXPORT_SYMBOL
++0x056bf03a    elv_rb_add      vmlinux EXPORT_SYMBOL
++0x5b2c1c77    init_user_ns    vmlinux EXPORT_SYMBOL_GPL
++0x0b5996ef    st_sensors_sysfs_sampling_frequency_avail       vmlinux EXPORT_SYMBOL
++0x3a17a800    vb2_dqbuf       vmlinux EXPORT_SYMBOL_GPL
++0xe55de32d    i2c_smbus_write_word_data       vmlinux EXPORT_SYMBOL
++0xd1c2d294    ip_mc_leave_group       vmlinux EXPORT_SYMBOL
++0x05843ade    netif_skb_features      vmlinux EXPORT_SYMBOL
++0x00632780    work_busy       vmlinux EXPORT_SYMBOL_GPL
++0x06d2c86e    pm_runtime_set_memalloc_noio    vmlinux EXPORT_SYMBOL_GPL
++0x97c6c5dd    drm_pci_exit    vmlinux EXPORT_SYMBOL
++0x1a1938a1    drm_pci_init    vmlinux EXPORT_SYMBOL
++0xf7a0d470    __sk_mem_reclaim        vmlinux EXPORT_SYMBOL
++0xc4f45210    d_prune_aliases vmlinux EXPORT_SYMBOL
++0x498d293a    trace_buffer_unlock_commit      vmlinux EXPORT_SYMBOL_GPL
++0x12a38747    usleep_range    vmlinux EXPORT_SYMBOL
++0xef409b74    kmsg_dump_get_line      vmlinux EXPORT_SYMBOL_GPL
++0xdd3202eb    lcd_device_unregister   vmlinux EXPORT_SYMBOL
++0x1fa2ae70    tcf_hash_check  vmlinux EXPORT_SYMBOL
++0xa43b9539    memcpy_fromiovecend     vmlinux EXPORT_SYMBOL
++0x4b4f96c3    blk_make_request        vmlinux EXPORT_SYMBOL
++0xe290713d    __pagevec_release       vmlinux EXPORT_SYMBOL
++0x1e047854    warn_slowpath_fmt       vmlinux EXPORT_SYMBOL
++0xbca701eb    vb2_ioctl_expbuf        vmlinux EXPORT_SYMBOL_GPL
++0x01508e49    cfg80211_cqm_rssi_notify        vmlinux EXPORT_SYMBOL
++0xff3e2712    nla_reserve_nohdr       vmlinux EXPORT_SYMBOL
++0xc442fa87    ilookup5        vmlinux EXPORT_SYMBOL
++0x1650bf27    rcutorture_record_progress      vmlinux EXPORT_SYMBOL_GPL
++0x3507a132    _raw_spin_lock_irq      vmlinux EXPORT_SYMBOL
++0x1b24bd6e    prepare_creds   vmlinux EXPORT_SYMBOL
++0x97c03a7e    mutex_unlock    vmlinux EXPORT_SYMBOL
++0x5bf35318    hid_unregister_driver   vmlinux EXPORT_SYMBOL_GPL
++0xd989fc54    usb_autopm_put_interface        vmlinux EXPORT_SYMBOL_GPL
++0x64d3db1a    dev_addr_flush  vmlinux EXPORT_SYMBOL
++0x6d92d23c    snd_dma_reserve_buf     vmlinux EXPORT_SYMBOL
++0x83a476ce    bitmap_scnlistprintf    vmlinux EXPORT_SYMBOL
++0x61660b0f    thermal_notify_framework        vmlinux EXPORT_SYMBOL_GPL
++0x1e925a2f    drm_unplug_dev  vmlinux EXPORT_SYMBOL
++0xef76af89    wiphy_rfkill_set_hw_state       vmlinux EXPORT_SYMBOL
++0x920aacca    nl_table_lock   vmlinux EXPORT_SYMBOL_GPL
++0x69b0b6dd    blkdev_get_by_dev       vmlinux EXPORT_SYMBOL
++0xd87601cc    ring_buffer_unlock_commit       vmlinux EXPORT_SYMBOL_GPL
++0xee7e7bbe    simple_fill_super       vmlinux EXPORT_SYMBOL
++0xf8fffd67    have_submounts  vmlinux EXPORT_SYMBOL
++0x07cc4a5d    printk_timed_ratelimit  vmlinux EXPORT_SYMBOL
++0x274944b3    sock_queue_err_skb      vmlinux EXPORT_SYMBOL
++0x7b03f66f    snd_add_device_sysfs_file       vmlinux EXPORT_SYMBOL
++0x1f8db7f9    ring_buffer_overrun_cpu vmlinux EXPORT_SYMBOL_GPL
++0x0faef0ed    __tasklet_schedule      vmlinux EXPORT_SYMBOL
++0x8ec68aa9    dev_load        vmlinux EXPORT_SYMBOL
++0xf4f14de6    rtnl_trylock    vmlinux EXPORT_SYMBOL
++0xac0ba8c1    blk_iopoll_disable      vmlinux EXPORT_SYMBOL
++0x1bb201ff    debugfs_create_u16      vmlinux EXPORT_SYMBOL_GPL
++0xcae7b03f    bio_add_page    vmlinux EXPORT_SYMBOL
++0x61af42e6    init_pid_ns     vmlinux EXPORT_SYMBOL_GPL
++0x3c420cae    v4l2_m2m_buf_queue      vmlinux EXPORT_SYMBOL_GPL
++0x0fa2a45e    __memzero       vmlinux EXPORT_SYMBOL
++0x674c71f7    ipt_unregister_table    vmlinux EXPORT_SYMBOL
++0x77ecac9f    zlib_inflateEnd vmlinux EXPORT_SYMBOL
++0x7ca5798f    contig_page_data        vmlinux EXPORT_SYMBOL
++0x3b66dc5f    vb2_buffer_done vmlinux EXPORT_SYMBOL_GPL
++0x07b291d1    usb_unlink_anchored_urbs        vmlinux EXPORT_SYMBOL_GPL
++0x06fbba42    usbnet_write_cmd        vmlinux EXPORT_SYMBOL_GPL
++0xc6b4b7b5    inet_frag_evictor       vmlinux EXPORT_SYMBOL
++0x9d44f8f6    xt_unregister_target    vmlinux EXPORT_SYMBOL
++0x0dca487b    led_trigger_show        vmlinux EXPORT_SYMBOL_GPL
++0xb423dba1    console_blanked vmlinux EXPORT_SYMBOL
++0x23679939    __iowrite32_copy        vmlinux EXPORT_SYMBOL_GPL
++0x38361fbf    config_group_init_type_name     vmlinux EXPORT_SYMBOL
++0x668fe138    __sb_end_write  vmlinux EXPORT_SYMBOL
++0xd67296c6    from_kgid       vmlinux EXPORT_SYMBOL
++0x2fd8e085    sdhci_pltfm_clk_get_max_clock   vmlinux EXPORT_SYMBOL_GPL
++0x4222235b    v4l2_fh_is_singular     vmlinux EXPORT_SYMBOL_GPL
++0x27cbc081    nf_conntrack_unregister_notifier        vmlinux EXPORT_SYMBOL_GPL
++0x638eeb4d    fib_rules_register      vmlinux EXPORT_SYMBOL_GPL
++0xfaf98462    bitrev32        vmlinux EXPORT_SYMBOL
++0x0399203b    simple_transaction_read vmlinux EXPORT_SYMBOL
++0x8a99a016    mempool_free_slab       vmlinux EXPORT_SYMBOL
++0x41c72de9    generic_setxattr        vmlinux EXPORT_SYMBOL
++0x75d94810    generic_getxattr        vmlinux EXPORT_SYMBOL
++0xe384a102    usb_speed_string        vmlinux EXPORT_SYMBOL_GPL
++0xf70fecd0    pm_generic_resume_early vmlinux EXPORT_SYMBOL_GPL
++0x48cb14ac    pm_generic_thaw vmlinux EXPORT_SYMBOL_GPL
++0x1d061186    cfg80211_connect_result vmlinux EXPORT_SYMBOL
++0xdd8800ff    jbd2_journal_set_features       vmlinux EXPORT_SYMBOL
++0xdadafdd7    mpage_readpages vmlinux EXPORT_SYMBOL
++0x4045c494    filter_match_preds      vmlinux EXPORT_SYMBOL_GPL
++0x5482fcef    usbnet_start_xmit       vmlinux EXPORT_SYMBOL_GPL
++0x9e074139    __pm_runtime_resume     vmlinux EXPORT_SYMBOL_GPL
++0x4df119fa    __bitmap_parse  vmlinux EXPORT_SYMBOL
++0x2cfc8703    __wait_on_buffer        vmlinux EXPORT_SYMBOL
++0x4a8907de    cancel_delayed_work_sync        vmlinux EXPORT_SYMBOL
++0x4c5566c5    extcon_set_cable_state  vmlinux EXPORT_SYMBOL_GPL
++0x1114ede2    extcon_get_cable_state  vmlinux EXPORT_SYMBOL_GPL
++0xcac8aaf3    i2c_unlock_adapter      vmlinux EXPORT_SYMBOL_GPL
++0xc3107f52    regmap_raw_read vmlinux EXPORT_SYMBOL_GPL
++0x6b807a5f    gpio_sysfs_set_active_low       vmlinux EXPORT_SYMBOL_GPL
++0xad4d490d    sock_create     vmlinux EXPORT_SYMBOL
++0x1bcfb1fa    debugfs_create_x32      vmlinux EXPORT_SYMBOL_GPL
++0xb0440408    bprm_change_interp      vmlinux EXPORT_SYMBOL
++0xbf7f05c3    kill_litter_super       vmlinux EXPORT_SYMBOL
++0xcb34aaf6    iommu_domain_window_disable     vmlinux EXPORT_SYMBOL_GPL
++0x7c9e0f69    clk_add_alias   vmlinux EXPORT_SYMBOL
++0xad84bef8    dm_table_event  vmlinux EXPORT_SYMBOL
++0xc91b3468    class_dev_iter_next     vmlinux EXPORT_SYMBOL_GPL
++0x64038eb3    inet_proto_csum_replace4        vmlinux EXPORT_SYMBOL
++0xb6e03027    neigh_direct_output     vmlinux EXPORT_SYMBOL
++0xce9a717b    blk_rq_check_limits     vmlinux EXPORT_SYMBOL_GPL
++0x75bda77a    seq_hlist_next  vmlinux EXPORT_SYMBOL
++0xb9c24bba    account_page_dirtied    vmlinux EXPORT_SYMBOL
++0xde037eaa    __lock_page_killable    vmlinux EXPORT_SYMBOL_GPL
++0x73c2d5f0    usb_free_urb    vmlinux EXPORT_SYMBOL_GPL
++0x9faa8d4a    tty_prepare_flip_string_flags   vmlinux EXPORT_SYMBOL_GPL
++0xb8de9394    tty_prepare_flip_string vmlinux EXPORT_SYMBOL_GPL
++0x4db0cbcf    fib_rules_unregister    vmlinux EXPORT_SYMBOL_GPL
++0x5fe6f617    skb_copy_bits   vmlinux EXPORT_SYMBOL
++0x71bf6cf0    __blk_end_request_all   vmlinux EXPORT_SYMBOL
++0xede99a14    crypto_register_ahash   vmlinux EXPORT_SYMBOL_GPL
++0xbdb3fd8c    sysfs_remove_link       vmlinux EXPORT_SYMBOL_GPL
++0x8924eb1e    rcu_force_quiescent_state       vmlinux EXPORT_SYMBOL_GPL
++0xe77924e8    drm_match_cea_mode      vmlinux EXPORT_SYMBOL
++0x189868d7    get_random_bytes_arch   vmlinux EXPORT_SYMBOL
++0x3aeef779    tcp_make_synack vmlinux EXPORT_SYMBOL
++0xc1c0b09b    snd_soc_add_codec_controls      vmlinux EXPORT_SYMBOL_GPL
++0xcc402882    find_get_page   vmlinux EXPORT_SYMBOL
++0x7d59dd46    pm_wq   vmlinux EXPORT_SYMBOL_GPL
++0x9a47820d    hrtimer_forward vmlinux EXPORT_SYMBOL_GPL
++0xa1f0ebea    bit_waitqueue   vmlinux EXPORT_SYMBOL
++0x52bd048a    iio_get_channel_type    vmlinux EXPORT_SYMBOL_GPL
++0x37b330b1    mii_check_gmii_support  vmlinux EXPORT_SYMBOL
++0x964bc3de    dma_async_device_register       vmlinux EXPORT_SYMBOL
++0x0adc9704    display_timings_release vmlinux EXPORT_SYMBOL_GPL
++0xe6c818f2    sock_common_recvmsg     vmlinux EXPORT_SYMBOL
++0xb62a00b3    mem_cgroup_subsys       vmlinux EXPORT_SYMBOL
++0x64652950    __video_register_device vmlinux EXPORT_SYMBOL
++0x9572f9d0    inet_csk_addr2sockaddr  vmlinux EXPORT_SYMBOL_GPL
++0xeda0d76e    gen_estimator_active    vmlinux EXPORT_SYMBOL
++0x8251bcc3    bitmap_release_region   vmlinux EXPORT_SYMBOL
++0x5567c227    kernel_cpustat  vmlinux EXPORT_SYMBOL
++0x9133fe16    vb2_write       vmlinux EXPORT_SYMBOL_GPL
++0x9bb89701    cfg80211_roamed vmlinux EXPORT_SYMBOL
++0x5eb03c4c    ip_mc_inc_group vmlinux EXPORT_SYMBOL
++0x06438115    tcp_orphan_count        vmlinux EXPORT_SYMBOL_GPL
++0x43804ba2    fat_attach      vmlinux EXPORT_SYMBOL_GPL
++0x30788c84    sysfs_remove_bin_file   vmlinux EXPORT_SYMBOL_GPL
++0xb11bad4f    register_wide_hw_breakpoint     vmlinux EXPORT_SYMBOL_GPL
++0xbd8b253c    tcf_exts_validate       vmlinux EXPORT_SYMBOL
++0xb81960ca    snprintf        vmlinux EXPORT_SYMBOL
++0x7cae600c    get_io_context  vmlinux EXPORT_SYMBOL
++0x70bb651d    __tracepoint_block_rq_remap     vmlinux EXPORT_SYMBOL_GPL
++0x9be42ea4    proc_mkdir_mode vmlinux EXPORT_SYMBOL
++0xf0701cc6    tag_pages_for_writeback vmlinux EXPORT_SYMBOL
++0x3cf525fb    hid_dump_device vmlinux EXPORT_SYMBOL_GPL
++0x219e9575    wakeup_source_unregister        vmlinux EXPORT_SYMBOL_GPL
++0xff43d5b5    cfg80211_check_station_change   vmlinux EXPORT_SYMBOL
++0x2296c00d    crypto_attr_u32 vmlinux EXPORT_SYMBOL_GPL
++0x710eaf23    PDE_DATA        vmlinux EXPORT_SYMBOL
++0xc1fac3b3    __bread vmlinux EXPORT_SYMBOL
++0x55af945f    follow_pfn      vmlinux EXPORT_SYMBOL
++0x275ae863    make_kuid       vmlinux EXPORT_SYMBOL
++0x54d8b7ba    hrtimer_init    vmlinux EXPORT_SYMBOL_GPL
++0x7c8f0303    dma_buf_export_named    vmlinux EXPORT_SYMBOL_GPL
++0x079f8b38    devm_kzalloc    vmlinux EXPORT_SYMBOL_GPL
++0x9ddbb3f6    tty_port_link_device    vmlinux EXPORT_SYMBOL_GPL
++0x9e8d08a7    pinctrl_find_and_add_gpio_range vmlinux EXPORT_SYMBOL_GPL
++0x9ceb163c    memcpy_toiovec  vmlinux EXPORT_SYMBOL
++0x44c38935    v4l2_subdev_g_ext_ctrls vmlinux EXPORT_SYMBOL
++0xc5fab8f0    v4l2_subdev_s_ext_ctrls vmlinux EXPORT_SYMBOL
++0x4cf092e4    scsi_report_opcode      vmlinux EXPORT_SYMBOL
++0x1b6314fd    in_aton vmlinux EXPORT_SYMBOL
++0x1027ae8c    neigh_resolve_output    vmlinux EXPORT_SYMBOL
++0xc492c2d9    snd_card_register       vmlinux EXPORT_SYMBOL
++0xa3018431    posix_unblock_lock      vmlinux EXPORT_SYMBOL
++0xf3d6e3aa    __mnt_is_readonly       vmlinux EXPORT_SYMBOL_GPL
++0x87984b16    __tracepoint_cpu_idle   vmlinux EXPORT_SYMBOL_GPL
++0x89205531    cfb_imageblit   vmlinux EXPORT_SYMBOL
++0x3bbf46ea    vga_base        vmlinux EXPORT_SYMBOL
++0x6fea34fd    tcp_close       vmlinux EXPORT_SYMBOL
++0x7bd5c87c    inet_add_offload        vmlinux EXPORT_SYMBOL
++0x024ea18c    nf_nat_irc_hook vmlinux EXPORT_SYMBOL_GPL
++0x18d1ab6f    nf_nat_ftp_hook vmlinux EXPORT_SYMBOL_GPL
++0xeb780f0e    nfq_ct_nat_hook vmlinux EXPORT_SYMBOL_GPL
++0x06277150    __scm_send      vmlinux EXPORT_SYMBOL
++0xc49eea50    skb_try_coalesce        vmlinux EXPORT_SYMBOL
++0xec007de7    snd_soc_dapm_new_controls       vmlinux EXPORT_SYMBOL_GPL
++0xa07ed110    xz_dec_init     vmlinux EXPORT_SYMBOL
++0x3dd4d3a7    bprintf vmlinux EXPORT_SYMBOL_GPL
++0xa4a0aeb8    try_to_free_buffers     vmlinux EXPORT_SYMBOL
++0xe9f098a6    wait_iff_congested      vmlinux EXPORT_SYMBOL
++0xcb5bf3f1    __put_cred      vmlinux EXPORT_SYMBOL
++0x3f80e476    get_thermal_instance    vmlinux EXPORT_SYMBOL
++0xb6979f60    usb_register_dev        vmlinux EXPORT_SYMBOL_GPL
++0xe0d8227f    scsi_dma_map    vmlinux EXPORT_SYMBOL
++0xa5de5bb1    blk_queue_bypass_start  vmlinux EXPORT_SYMBOL_GPL
++0xb9617f29    dm_path_uevent  vmlinux EXPORT_SYMBOL_GPL
++0xd909cae6    serial8250_clear_and_reinit_fifos       vmlinux EXPORT_SYMBOL_GPL
++0x755da9a0    register_framebuffer    vmlinux EXPORT_SYMBOL
++0x9ed685ee    iov_iter_advance        vmlinux EXPORT_SYMBOL
++0xf86a3a9f    clk_gate_ops    vmlinux EXPORT_SYMBOL_GPL
++0xfcc9ce6a    mmc_of_parse    vmlinux EXPORT_SYMBOL
++0xb486e84e    mfd_remove_devices      vmlinux EXPORT_SYMBOL
++0xc5a484ac    pm_generic_suspend_late vmlinux EXPORT_SYMBOL_GPL
++0x3cd06035    add_input_randomness    vmlinux EXPORT_SYMBOL_GPL
++0xf50d8f59    regulator_enable_regmap vmlinux EXPORT_SYMBOL_GPL
++0x09774d0b    pinctrl_force_sleep     vmlinux EXPORT_SYMBOL_GPL
++0xc7c3c6d2    ip6_tnl_dst_reset       vmlinux EXPORT_SYMBOL_GPL
++0x225d0386    nf_ct_l4proto_pernet_register   vmlinux EXPORT_SYMBOL_GPL
++0xf7d31a5d    nf_ct_l3proto_pernet_register   vmlinux EXPORT_SYMBOL_GPL
++0x8401c62f    scsi_unblock_requests   vmlinux EXPORT_SYMBOL
++0x8ca1a1dc    device_remove_bin_file  vmlinux EXPORT_SYMBOL_GPL
++0xccb1ba6b    of_get_drm_display_mode vmlinux EXPORT_SYMBOL_GPL
++0xe3f48cba    tty_port_free_xmit_buf  vmlinux EXPORT_SYMBOL
++0xec1b043e    regulator_suspend_prepare       vmlinux EXPORT_SYMBOL_GPL
++0xecbda9c5    display_entity_get      vmlinux EXPORT_SYMBOL_GPL
++0x13b89dee    pinctrl_request_gpio    vmlinux EXPORT_SYMBOL_GPL
++0xdcb3410a    nf_ct_deliver_cached_events     vmlinux EXPORT_SYMBOL_GPL
++0x32ddd5b6    call_rcu        vmlinux EXPORT_SYMBOL_GPL
++0xf1267848    usb_composite_unregister        vmlinux EXPORT_SYMBOL_GPL
++0x877509c0    crypto_nivaead_type     vmlinux EXPORT_SYMBOL_GPL
++0x9263cf47    bdi_writeout_inc        vmlinux EXPORT_SYMBOL_GPL
++0x26f6b499    iio_str_to_fixpoint     vmlinux EXPORT_SYMBOL_GPL
++0x7267db00    hwrng_unregister        vmlinux EXPORT_SYMBOL_GPL
++0x19cbf31d    xfrm6_rcv_spi   vmlinux EXPORT_SYMBOL
++0xe5a42822    ip_tunnel_change_mtu    vmlinux EXPORT_SYMBOL_GPL
++0xf236a5de    tcf_exts_change vmlinux EXPORT_SYMBOL
++0x058b95e3    snd_pcm_release_substream       vmlinux EXPORT_SYMBOL
++0x9a6e183a    __idr_remove_all        vmlinux EXPORT_SYMBOL
++0x7b9bf08e    disk_stack_limits       vmlinux EXPORT_SYMBOL
++0x9879932b    crypto_register_notifier        vmlinux EXPORT_SYMBOL_GPL
++0xd220cf8a    jiffies_to_timespec     vmlinux EXPORT_SYMBOL
++0xce4f758e    dma_release_from_coherent       vmlinux EXPORT_SYMBOL
++0xe238b99e    pskb_put        vmlinux EXPORT_SYMBOL_GPL
++0xe11dd614    fib_table_lookup        vmlinux EXPORT_SYMBOL_GPL
++0x3862b0a7    snd_soc_bytes_put       vmlinux EXPORT_SYMBOL_GPL
++0xa5ed8e2c    inc_nlink       vmlinux EXPORT_SYMBOL
++0xf43bdbf8    smpboot_unregister_percpu_thread        vmlinux EXPORT_SYMBOL_GPL
++0x8a1ab4ee    timeval_to_jiffies      vmlinux EXPORT_SYMBOL
++0x39375395    i2c_master_send vmlinux EXPORT_SYMBOL
++0x3a517b2b    device_reprobe  vmlinux EXPORT_SYMBOL_GPL
++0xb22e34bd    wiphy_free      vmlinux EXPORT_SYMBOL
++0x76a01893    __netlink_dump_start    vmlinux EXPORT_SYMBOL
++0xa96c3c3b    dev_kfree_skb_any       vmlinux EXPORT_SYMBOL
++0xfdaeced1    snd_ctl_new1    vmlinux EXPORT_SYMBOL
++0xb4f57a24    security_task_getsecid  vmlinux EXPORT_SYMBOL
++0x09d71f87    seq_open        vmlinux EXPORT_SYMBOL
++0x29a73c29    mnt_drop_write  vmlinux EXPORT_SYMBOL_GPL
++0xbcdd5b99    iommu_group_set_name    vmlinux EXPORT_SYMBOL_GPL
++0x7e394c4e    sysctl_local_reserved_ports     vmlinux EXPORT_SYMBOL
++0x094bac5f    simple_readpage vmlinux EXPORT_SYMBOL
++0x5a39720e    __lock_page     vmlinux EXPORT_SYMBOL
++0xb140d14c    ring_buffer_read        vmlinux EXPORT_SYMBOL_GPL
++0xf499fdb2    rcu_barrier_bh  vmlinux EXPORT_SYMBOL_GPL
++0x03d9fff7    synchronize_srcu_expedited      vmlinux EXPORT_SYMBOL_GPL
++0x1c0ae7d7    drm_mm_init_scan        vmlinux EXPORT_SYMBOL
++0x8320bea8    __umodsi3       vmlinux EXPORT_SYMBOL
++0xc3706dce    tcp_cong_avoid_ai       vmlinux EXPORT_SYMBOL_GPL
++0xab6bde28    sysctl_max_syn_backlog  vmlinux EXPORT_SYMBOL
++0x5d90d2ce    blk_delay_queue vmlinux EXPORT_SYMBOL
++0xefdd70ce    security_secid_to_secctx        vmlinux EXPORT_SYMBOL
++0x77d67659    follow_down     vmlinux EXPORT_SYMBOL
++0x083eb1cc    __generic_file_aio_write        vmlinux EXPORT_SYMBOL
++0x46646afc    filemap_write_and_wait_range    vmlinux EXPORT_SYMBOL
++0xc72c4abb    usb_altnum_to_altsetting        vmlinux EXPORT_SYMBOL_GPL
++0x0a98333a    snd_soc_dpcm_get_substream      vmlinux EXPORT_SYMBOL_GPL
++0x360b1afe    probe_irq_mask  vmlinux EXPORT_SYMBOL
++0x8f2154e4    cfg80211_rx_mgmt        vmlinux EXPORT_SYMBOL
++0xafa574d0    snd_soc_jack_notifier_unregister        vmlinux EXPORT_SYMBOL_GPL
++0x93af86c9    get_write_access        vmlinux EXPORT_SYMBOL
++0x2350c4a6    invalidate_mapping_pages        vmlinux EXPORT_SYMBOL
++0x84c6c77a    genphy_read_status      vmlinux EXPORT_SYMBOL
++0x96fb7fef    drm_mode_create_dithering_property      vmlinux EXPORT_SYMBOL
++0xef56f51e    redraw_screen   vmlinux EXPORT_SYMBOL
++0x2394545f    tty_unregister_driver   vmlinux EXPORT_SYMBOL
++0xf3bf0bce    __bitmap_complement     vmlinux EXPORT_SYMBOL
++0xe2e8065e    memdup_user     vmlinux EXPORT_SYMBOL
++0x3bdd0f94    v4l2_prio_change        vmlinux EXPORT_SYMBOL
++0x7ab9b430    drm_poll        vmlinux EXPORT_SYMBOL
++0x760d494e    pinctrl_find_gpio_range_from_pin        vmlinux EXPORT_SYMBOL_GPL
++0xcca27eeb    del_timer       vmlinux EXPORT_SYMBOL
++0x39e773af    thermal_cooling_device_unregister       vmlinux EXPORT_SYMBOL_GPL
++0xcba9dbcf    dma_get_required_mask   vmlinux EXPORT_SYMBOL_GPL
++0x2fb1d233    nf_log_unbind_pf        vmlinux EXPORT_SYMBOL
++0x460f7531    wait_rcu_gp     vmlinux EXPORT_SYMBOL_GPL
++0x9bfaf424    usb_get_current_frame_number    vmlinux EXPORT_SYMBOL_GPL
++0xad9bbf9f    hci_suspend_dev vmlinux EXPORT_SYMBOL
++0x56c5a136    tcp_v4_send_check       vmlinux EXPORT_SYMBOL
++0x0a4862b9    nf_ct_expect_find_get   vmlinux EXPORT_SYMBOL_GPL
++0x30e3e930    dev_close       vmlinux EXPORT_SYMBOL
++0xc3e46db4    snd_pcm_lib_free_pages  vmlinux EXPORT_SYMBOL
++0x3b735a2b    __mark_inode_dirty      vmlinux EXPORT_SYMBOL
++0x91437bc9    dma_buf_put     vmlinux EXPORT_SYMBOL_GPL
++0x8e09c957    dma_buf_get     vmlinux EXPORT_SYMBOL_GPL
++0x98aba977    ip6_update_pmtu vmlinux EXPORT_SYMBOL_GPL
++0x019daa72    noop_qdisc      vmlinux EXPORT_SYMBOL
++0x240646b9    sock_alloc_send_skb     vmlinux EXPORT_SYMBOL
++0x871f2cb1    snd_soc_dapm_nc_pin     vmlinux EXPORT_SYMBOL_GPL
++0x97440f69    snd_card_disconnect     vmlinux EXPORT_SYMBOL
++0xd9ce8f0c    strnlen vmlinux EXPORT_SYMBOL
++0xe7c9dbc0    unregister_filesystem   vmlinux EXPORT_SYMBOL
++0x4abbe3c2    vm_brk  vmlinux EXPORT_SYMBOL
++0x2439abc9    irq_domain_add_simple   vmlinux EXPORT_SYMBOL_GPL
++0xd418e1c0    adjust_resource vmlinux EXPORT_SYMBOL
++0x31c0c2d1    dm_put  vmlinux EXPORT_SYMBOL_GPL
++0x140e371b    v4l2_of_get_remote_port_parent  vmlinux EXPORT_SYMBOL
++0x3adbd595    v4l2_field_names        vmlinux EXPORT_SYMBOL
++0xdcece020    xfrm_state_insert       vmlinux EXPORT_SYMBOL
++0xf8fe3d0b    kmsg_dump_register      vmlinux EXPORT_SYMBOL_GPL
++0x40728a63    xt_find_revision        vmlinux EXPORT_SYMBOL_GPL
++0xcb534ec9    __destroy_inode vmlinux EXPORT_SYMBOL
++0xea1f5b88    samsung_rev     vmlinux EXPORT_SYMBOL
++0xd3dd145a    tcp_is_cwnd_limited     vmlinux EXPORT_SYMBOL_GPL
++0x392697b4    nf_conntrack_l3proto_generic    vmlinux EXPORT_SYMBOL_GPL
++0x2549013a    snd_soc_dai_set_channel_map     vmlinux EXPORT_SYMBOL_GPL
++0x421e53cf    blk_rq_unmap_user       vmlinux EXPORT_SYMBOL
++0xacf1d33d    crypto_mod_get  vmlinux EXPORT_SYMBOL_GPL
++0x0bc477a2    irq_set_irq_type        vmlinux EXPORT_SYMBOL
++0xce2840e7    irq_set_irq_wake        vmlinux EXPORT_SYMBOL
++0x2650d835    sysctl_ip_early_demux   vmlinux EXPORT_SYMBOL
++0x07e472e5    __remove_inode_hash     vmlinux EXPORT_SYMBOL
++0x82b7cda8    __lru_cache_add vmlinux EXPORT_SYMBOL
++0x457b77ca    of_fixed_factor_clk_setup       vmlinux EXPORT_SYMBOL_GPL
++0x840b929e    v4l2_device_unregister_subdev   vmlinux EXPORT_SYMBOL_GPL
++0x6128b5fc    __printk_ratelimit      vmlinux EXPORT_SYMBOL
++0xcc1f1c3d    inet_twdr_hangman       vmlinux EXPORT_SYMBOL_GPL
++0x71faed49    __blk_end_request_cur   vmlinux EXPORT_SYMBOL
++0xab5cbfa1    __blk_end_request_err   vmlinux EXPORT_SYMBOL_GPL
++0xb2682405    utf8_to_utf32   vmlinux EXPORT_SYMBOL
++0x9621849f    ring_buffer_event_data  vmlinux EXPORT_SYMBOL_GPL
++0x2761c400    pm_generic_restore_early        vmlinux EXPORT_SYMBOL_GPL
++0x36d31f9e    crypto_sha1_update      vmlinux EXPORT_SYMBOL
++0x8798e453    __tracepoint_kfree      vmlinux EXPORT_SYMBOL
++0x247ba373    override_creds  vmlinux EXPORT_SYMBOL
++0x131db64a    system_long_wq  vmlinux EXPORT_SYMBOL_GPL
++0xc0d26387    kmsg_dump_unregister    vmlinux EXPORT_SYMBOL_GPL
++0x6b132713    __clk_register  vmlinux EXPORT_SYMBOL_GPL
++0x5292f4ea    scsi_prep_return        vmlinux EXPORT_SYMBOL
++0x34a13791    __pm_runtime_disable    vmlinux EXPORT_SYMBOL_GPL
++0xa10db0ce    phy_pm_runtime_get_sync vmlinux EXPORT_SYMBOL_GPL
++0x1b62df19    arm_iommu_create_mapping        vmlinux EXPORT_SYMBOL_GPL
++0x606d0b09    secure_tcpv6_sequence_number    vmlinux EXPORT_SYMBOL
++0xa75bc594    blkdev_issue_zeroout    vmlinux EXPORT_SYMBOL
++0x8f12669a    irq_linear_revmap       vmlinux EXPORT_SYMBOL_GPL
++0x938244d0    handle_level_irq        vmlinux EXPORT_SYMBOL_GPL
++0xb336e1d2    extcon_set_cable_state_ vmlinux EXPORT_SYMBOL_GPL
++0x067ef5d5    extcon_get_cable_state_ vmlinux EXPORT_SYMBOL_GPL
++0x8d22bb58    iommu_group_alloc       vmlinux EXPORT_SYMBOL_GPL
++0xa7e20df3    clk_mux_ops     vmlinux EXPORT_SYMBOL_GPL
++0x7f9eeaae    input_register_handle   vmlinux EXPORT_SYMBOL
++0x6cc78c5c    set_irq_flags   vmlinux EXPORT_SYMBOL_GPL
++0xc781bd9f    rfkill_resume_polling   vmlinux EXPORT_SYMBOL
++0x982e6b6d    ieee80211_radiotap_iterator_init        vmlinux EXPORT_SYMBOL
++0xf30fda27    lzo1x_decompress_safe   vmlinux EXPORT_SYMBOL_GPL
++0x42b364ef    scatterwalk_done        vmlinux EXPORT_SYMBOL_GPL
++0x2158c0d7    kern_unmount    vmlinux EXPORT_SYMBOL
++0xd31ccb06    of_machine_is_compatible        vmlinux EXPORT_SYMBOL
++0xd6d49c42    sdio_writesb    vmlinux EXPORT_SYMBOL_GPL
++0xe6fa2163    v4l2_async_notifier_unregister  vmlinux EXPORT_SYMBOL
++0x20234f83    nla_append      vmlinux EXPORT_SYMBOL
++0x4cf41ed3    skcipher_geniv_free     vmlinux EXPORT_SYMBOL_GPL
++0x4bc07110    jbd2_journal_lock_updates       vmlinux EXPORT_SYMBOL
++0xf37671d2    vfs_llseek      vmlinux EXPORT_SYMBOL
++0x8720876b    __page_file_index       vmlinux EXPORT_SYMBOL_GPL
++0x609d9c25    __irq_set_handler       vmlinux EXPORT_SYMBOL_GPL
++0x2d17a0e1    cgroup_taskset_size     vmlinux EXPORT_SYMBOL_GPL
++0xabe27502    v4l2_ctrl_query_fill    vmlinux EXPORT_SYMBOL
++0x5b1a060c    usb_control_msg vmlinux EXPORT_SYMBOL_GPL
++0xe59c5ea4    snd_dma_free_pages      vmlinux EXPORT_SYMBOL
++0x85541e31    iterate_fd      vmlinux EXPORT_SYMBOL
++0x7ceaf0d5    generic_handle_irq      vmlinux EXPORT_SYMBOL_GPL
++0x46feb099    dm_read_arg     vmlinux EXPORT_SYMBOL
++0xe8125c91    dev_set_drvdata vmlinux EXPORT_SYMBOL
++0x8d60d310    dev_get_drvdata vmlinux EXPORT_SYMBOL
++0x84510ec6    bt_sock_unlink  vmlinux EXPORT_SYMBOL
++0x14f626f7    snd_soc_dapm_add_routes vmlinux EXPORT_SYMBOL_GPL
++0x5d1c1bac    blocking_notifier_chain_cond_register   vmlinux EXPORT_SYMBOL_GPL
++0xefd5b1f1    nfc_hci_disconnect_all_gates    vmlinux EXPORT_SYMBOL
++0x009c0acf    __xfrm_state_destroy    vmlinux EXPORT_SYMBOL
++0x256e5691    bfifo_qdisc_ops vmlinux EXPORT_SYMBOL
++0x1f8544b8    panic_timeout   vmlinux EXPORT_SYMBOL_GPL
++0x5b4e379c    of_prop_next_u32        vmlinux EXPORT_SYMBOL_GPL
++0x8106095a    v4l2_prio_max   vmlinux EXPORT_SYMBOL
++0xfff74a32    usb_unpoison_urb        vmlinux EXPORT_SYMBOL_GPL
++0xc532db16    tty_port_init   vmlinux EXPORT_SYMBOL
++0xa20ce1b8    net_msg_warn    vmlinux EXPORT_SYMBOL
++0x2aa97a28    __sock_recv_timestamp   vmlinux EXPORT_SYMBOL_GPL
++0x6225637e    md5_transform   vmlinux EXPORT_SYMBOL
++0xa3301b08    noop_fsync      vmlinux EXPORT_SYMBOL
++0x31ab0e28    extcon_dev_unregister   vmlinux EXPORT_SYMBOL_GPL
++0xc5176fe9    usb_hcd_resume_root_hub vmlinux EXPORT_SYMBOL_GPL
++0x13bdb1fd    cfg80211_ibss_joined    vmlinux EXPORT_SYMBOL
++0x587763dd    blkdev_issue_write_same vmlinux EXPORT_SYMBOL
++0x627b7988    crypto_hash_walk_first  vmlinux EXPORT_SYMBOL_GPL
++0x85d438aa    scsi_add_host_with_dma  vmlinux EXPORT_SYMBOL
++0x2b26ce97    devres_remove_group     vmlinux EXPORT_SYMBOL_GPL
++0x8e007d5e    inet_sendpage   vmlinux EXPORT_SYMBOL
++0xbb713e6d    sk_filter_release_rcu   vmlinux EXPORT_SYMBOL
++0xf1dc9acb    dev_get_by_index_rcu    vmlinux EXPORT_SYMBOL
++0x5364397d    dev_set_allmulti        vmlinux EXPORT_SYMBOL
++0xd20a4e9e    snd_ctl_remove_id       vmlinux EXPORT_SYMBOL
++0xea10655a    __bitmap_intersects     vmlinux EXPORT_SYMBOL
++0xf313da4e    sha_transform   vmlinux EXPORT_SYMBOL
++0x9b6eb137    ksize   vmlinux EXPORT_SYMBOL
++0x38869d88    kstat   vmlinux EXPORT_SYMBOL
++0x43caf714    mmc_can_erase   vmlinux EXPORT_SYMBOL
++0xa42810a9    i2c_add_adapter vmlinux EXPORT_SYMBOL
++0xaf5ddb02    input_mt_report_finger_count    vmlinux EXPORT_SYMBOL
++0x3a09b033    drm_mmap        vmlinux EXPORT_SYMBOL
++0xcc16f79c    drm_kms_helper_poll_fini        vmlinux EXPORT_SYMBOL
++0xe707d823    __aeabi_uidiv   vmlinux EXPORT_SYMBOL
++0xcd2a33d7    hci_conn_security       vmlinux EXPORT_SYMBOL
++0xd456425d    kobject_set_name        vmlinux EXPORT_SYMBOL
++0x60642a60    shmem_truncate_range    vmlinux EXPORT_SYMBOL_GPL
++0xa3e7c113    ring_buffer_iter_peek   vmlinux EXPORT_SYMBOL_GPL
++0xa5efbf4c    async_synchronize_full  vmlinux EXPORT_SYMBOL_GPL
++0x3ac75973    dm_send_uevents vmlinux EXPORT_SYMBOL_GPL
++0x47f757de    elf_platform    vmlinux EXPORT_SYMBOL
++0x48994b32    bt_debugfs      vmlinux EXPORT_SYMBOL_GPL
++0xc3f4c43b    set_device_ro   vmlinux EXPORT_SYMBOL
++0xbb038ce4    perf_unregister_guest_info_callbacks    vmlinux EXPORT_SYMBOL_GPL
++0x8cc44150    of_clk_src_simple_get   vmlinux EXPORT_SYMBOL_GPL
++0x09378170    shash_attr_alg  vmlinux EXPORT_SYMBOL_GPL
++0x63eb9355    panic_blink     vmlinux EXPORT_SYMBOL
++0x37df5b58    usb_anchor_urb  vmlinux EXPORT_SYMBOL_GPL
++0x665ccdb6    __sync_dirty_buffer     vmlinux EXPORT_SYMBOL
++0xb370f2b0    kmap_high       vmlinux EXPORT_SYMBOL
++0xc3042166    cancel_dirty_page       vmlinux EXPORT_SYMBOL
++0xf4fc2d6c    __ring_buffer_alloc     vmlinux EXPORT_SYMBOL_GPL
++0x82072614    tasklet_kill    vmlinux EXPORT_SYMBOL
++0x653cd720    exynos_g2d_set_cmdlist_ioctl    vmlinux EXPORT_SYMBOL_GPL
++0xa2a78b0e    blk_post_runtime_resume vmlinux EXPORT_SYMBOL
++0xf7f02ddf    bio_endio       vmlinux EXPORT_SYMBOL
++0x269b337f    account_page_redirty    vmlinux EXPORT_SYMBOL
++0x85c7f674    ring_buffer_normalize_time_stamp        vmlinux EXPORT_SYMBOL_GPL
++0xf4597085    i2c_use_client  vmlinux EXPORT_SYMBOL
++0x2da746c5    scsi_print_command      vmlinux EXPORT_SYMBOL
++0xd0e73a87    amba_driver_register    vmlinux EXPORT_SYMBOL
++0x3810da45    nf_ct_expect_unregister_notifier        vmlinux EXPORT_SYMBOL_GPL
++0x50b236e9    eth_prepare_mac_addr_change     vmlinux EXPORT_SYMBOL
++0xd32c0bf4    sk_stop_timer   vmlinux EXPORT_SYMBOL
++0xffdb82bc    sg_free_table   vmlinux EXPORT_SYMBOL
++0xfcbba27f    locks_remove_posix      vmlinux EXPORT_SYMBOL
++0xb0b85f47    ring_buffer_iter_reset  vmlinux EXPORT_SYMBOL_GPL
++0x43b0c9c3    preempt_schedule        vmlinux EXPORT_SYMBOL
++0x7c010229    of_platform_bus_probe   vmlinux EXPORT_SYMBOL
++0xf74656ab    regulator_can_change_voltage    vmlinux EXPORT_SYMBOL_GPL
++0x5d5b5a16    radix_tree_delete       vmlinux EXPORT_SYMBOL
++0x4b37f24f    of_extcon_get_extcon_dev        vmlinux EXPORT_SYMBOL_GPL
++0x728be72e    pm_generic_thaw_noirq   vmlinux EXPORT_SYMBOL_GPL
++0x94de4a33    tcp_slow_start  vmlinux EXPORT_SYMBOL_GPL
++0x4a73178a    dev_activate    vmlinux EXPORT_SYMBOL
++0x7649cfce    __pneigh_lookup vmlinux EXPORT_SYMBOL_GPL
++0xaafcd87b    devm_iounmap    vmlinux EXPORT_SYMBOL
++0x3bfc99a5    devm_ioremap    vmlinux EXPORT_SYMBOL
++0x5541ea93    on_each_cpu     vmlinux EXPORT_SYMBOL
++0x176af8ec    cdc_ncm_rx_verify_ndp16 vmlinux EXPORT_SYMBOL_GPL
++0x572d7fe7    pn544_hci_remove        vmlinux EXPORT_SYMBOL
++0x74e5ff1a    udpv6_encap_enable      vmlinux EXPORT_SYMBOL
++0x7a08f61d    snd_pcm_set_sync        vmlinux EXPORT_SYMBOL
++0x164b50d3    nla_reserve     vmlinux EXPORT_SYMBOL
++0x08758d9c    bioset_create   vmlinux EXPORT_SYMBOL
++0x08365975    drm_gem_object_lookup   vmlinux EXPORT_SYMBOL
++0x862b9816    cpu_topology    vmlinux EXPORT_SYMBOL_GPL
++0x3722cf9f    rtnl_put_cacheinfo      vmlinux EXPORT_SYMBOL_GPL
++0xea124bd1    gcd     vmlinux EXPORT_SYMBOL_GPL
++0xce3e95d0    ihold   vmlinux EXPORT_SYMBOL
++0xd11031b4    names_cachep    vmlinux EXPORT_SYMBOL
++0x8890cade    invalidate_inode_pages2_range   vmlinux EXPORT_SYMBOL_GPL
++0x83130f62    cancel_delayed_work     vmlinux EXPORT_SYMBOL
++0xcbc428db    __cpufreq_driver_target vmlinux EXPORT_SYMBOL_GPL
++0xd6233445    xfrm_policy_register_afinfo     vmlinux EXPORT_SYMBOL
++0xc8afb46b    snd_info_create_card_entry      vmlinux EXPORT_SYMBOL
++0xb7850524    crypto_unregister_shashes       vmlinux EXPORT_SYMBOL_GPL
++0x4acc9be5    dentry_path_raw vmlinux EXPORT_SYMBOL
++0x475ea860    xfrm_sad_getinfo        vmlinux EXPORT_SYMBOL
++0x9429e18f    netif_napi_del  vmlinux EXPORT_SYMBOL
++0x03a3ce75    crypto_register_alg     vmlinux EXPORT_SYMBOL_GPL
++0x1a3e0511    debugfs_rename  vmlinux EXPORT_SYMBOL_GPL
++0xb69186d9    simple_open     vmlinux EXPORT_SYMBOL
++0xe513ed5c    single_open     vmlinux EXPORT_SYMBOL
++0x9072472b    page_follow_link_light  vmlinux EXPORT_SYMBOL
++0xdbbd4688    __page_file_mapping     vmlinux EXPORT_SYMBOL_GPL
++0x0f751aea    input_event_from_user   vmlinux EXPORT_SYMBOL_GPL
++0x4484a5a4    wait_for_device_probe   vmlinux EXPORT_SYMBOL_GPL
++0xd53e17fd    tty_port_put    vmlinux EXPORT_SYMBOL
++0xa1b759ce    fb_add_videomode        vmlinux EXPORT_SYMBOL
++0x3c831441    arm_check_condition     vmlinux EXPORT_SYMBOL_GPL
++0x44fa52dd    brcmu_pktq_mdeq drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x471d6f83    brcmu_pktq_mlen drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x6af410ae    cfg80211_send_disassoc  vmlinux EXPORT_SYMBOL
++0x1baa3892    xfrm6_find_1stfragopt   vmlinux EXPORT_SYMBOL
++0x198788b4    snd_lookup_oss_minor_data       vmlinux EXPORT_SYMBOL
++0x4a3ea5c0    snd_request_card        vmlinux EXPORT_SYMBOL
++0x56451890    register_ftrace_event   vmlinux EXPORT_SYMBOL_GPL
++0x4ae313f9    kthread_stop    vmlinux EXPORT_SYMBOL
++0x1438fff0    st_sensors_sysfs_scale_avail    vmlinux EXPORT_SYMBOL
++0x31178006    clk_unregister  vmlinux EXPORT_SYMBOL_GPL
++0x083c2cbe    of_get_next_parent      vmlinux EXPORT_SYMBOL
++0xfef96e23    __scsi_print_command    vmlinux EXPORT_SYMBOL
++0x670cff67    drm_helper_disable_unused_functions     vmlinux EXPORT_SYMBOL
++0xe7048594    cfg80211_chandef_create vmlinux EXPORT_SYMBOL
++0x020d1750    cfg80211_tdls_oper_request      vmlinux EXPORT_SYMBOL
++0xbec63ca7    security_inode_create   vmlinux EXPORT_SYMBOL_GPL
++0xfe72e11b    dm_register_target      vmlinux EXPORT_SYMBOL
++0xaa4a7797    hex2bin vmlinux EXPORT_SYMBOL
++0xe924fd45    crypto_default_rng      vmlinux EXPORT_SYMBOL_GPL
++0xddab6b08    d_make_root     vmlinux EXPORT_SYMBOL
++0xa3b40cfd    hid_register_report     vmlinux EXPORT_SYMBOL_GPL
++0xcda04a5b    v4l2_prio_close vmlinux EXPORT_SYMBOL
++0x2e12216c    rtc_set_alarm   vmlinux EXPORT_SYMBOL_GPL
++0xaefe5034    __scsi_get_command      vmlinux EXPORT_SYMBOL_GPL
++0x31547da3    __scsi_put_command      vmlinux EXPORT_SYMBOL
++0x0fa5f996    inet_csk_listen_start   vmlinux EXPORT_SYMBOL_GPL
++0xfcc2a43c    utf32_to_utf8   vmlinux EXPORT_SYMBOL
++0xeef161aa    groups_free     vmlinux EXPORT_SYMBOL
++0xc5a25ce7    cleanup_srcu_struct     vmlinux EXPORT_SYMBOL_GPL
++0xac1a55be    unregister_reboot_notifier      vmlinux EXPORT_SYMBOL
++0x4557930f    regmap_update_bits_check        vmlinux EXPORT_SYMBOL_GPL
++0x0e0eb67f    ip6_flush_pending_frames        vmlinux EXPORT_SYMBOL_GPL
++0xb670b4cf    tcf_destroy_chain       vmlinux EXPORT_SYMBOL
++0x5fa48b4e    generic_file_remap_pages        vmlinux EXPORT_SYMBOL
++0xe13fa8ed    regmap_register_patch   vmlinux EXPORT_SYMBOL_GPL
++0x18c77c17    tty_perform_flush       vmlinux EXPORT_SYMBOL_GPL
++0x5ece6555    debugfs_remove_recursive        vmlinux EXPORT_SYMBOL_GPL
++0x1fcf4d4b    _raw_read_unlock_bh     vmlinux EXPORT_SYMBOL
++0x04cabed9    rfkill_register vmlinux EXPORT_SYMBOL
++0x774a552a    cfg80211_send_deauth    vmlinux EXPORT_SYMBOL
++0xc1691764    neigh_parms_alloc       vmlinux EXPORT_SYMBOL
++0x75fac20b    mount_single    vmlinux EXPORT_SYMBOL
++0x9ecc6a7a    interruptible_sleep_on  vmlinux EXPORT_SYMBOL
++0x19a304ba    usb_disabled    vmlinux EXPORT_SYMBOL_GPL
++0x48f20051    __ip_route_output_key   vmlinux EXPORT_SYMBOL_GPL
++0x5e7f4920    snd_pcm_format_set_silence      vmlinux EXPORT_SYMBOL
++0x9ef5a297    blk_queue_invalidate_tags       vmlinux EXPORT_SYMBOL
++0xffb6db4a    remove_irq      vmlinux EXPORT_SYMBOL_GPL
++0x93a6e0b2    io_schedule     vmlinux EXPORT_SYMBOL
++0xa604bba5    cpufreq_notify_transition       vmlinux EXPORT_SYMBOL_GPL
++0xb9c425de    register_syscore_ops    vmlinux EXPORT_SYMBOL_GPL
++0x7317fc49    disk_part_iter_next     vmlinux EXPORT_SYMBOL_GPL
++0xc4c6c770    block_write_end vmlinux EXPORT_SYMBOL
++0x437e0be6    pid_vnr vmlinux EXPORT_SYMBOL_GPL
++0xcb476f4a    cfb_fillrect    vmlinux EXPORT_SYMBOL
++0xc6241aec    cfg80211_roamed_bss     vmlinux EXPORT_SYMBOL
++0x44336387    __xfrm_decode_session   vmlinux EXPORT_SYMBOL
++0xf803fe39    bitmap_set      vmlinux EXPORT_SYMBOL
++0x1bbcbb78    __pagevec_lru_add       vmlinux EXPORT_SYMBOL
++0xd1b2db37    tracepoint_probe_register_noupdate      vmlinux EXPORT_SYMBOL_GPL
++0x230e0698    __clocksource_updatefreq_scale  vmlinux EXPORT_SYMBOL_GPL
++0xd8004073    sdhci_runtime_resume_host       vmlinux EXPORT_SYMBOL_GPL
++0x04369954    devm_regmap_init        vmlinux EXPORT_SYMBOL_GPL
++0xa2a36526    tty_port_lower_dtr_rts  vmlinux EXPORT_SYMBOL
++0xf369df34    wiphy_rfkill_stop_polling       vmlinux EXPORT_SYMBOL
++0x253ec879    netlink_set_err vmlinux EXPORT_SYMBOL
++0x71d7bf40    alloc_netdev_mqs        vmlinux EXPORT_SYMBOL
++0x336154ca    rcutorture_record_test_transition       vmlinux EXPORT_SYMBOL_GPL
++0x1aa1c9f2    make_kprojid    vmlinux EXPORT_SYMBOL
++0xa42a123d    bus_register_notifier   vmlinux EXPORT_SYMBOL_GPL
++0xd2cf977d    gpiochip_add    vmlinux EXPORT_SYMBOL_GPL
++0xd3c40b56    inet_listen     vmlinux EXPORT_SYMBOL
++0xfdc9a24f    __dst_destroy_metrics_generic   vmlinux EXPORT_SYMBOL
++0x44e276d8    skb_queue_purge vmlinux EXPORT_SYMBOL
++0x588eccde    get_unmapped_area       vmlinux EXPORT_SYMBOL
++0x0f29f7c9    add_to_page_cache_lru   vmlinux EXPORT_SYMBOL_GPL
++0xb7d4b252    iommu_present   vmlinux EXPORT_SYMBOL_GPL
++0x01c483a9    v4l2_get_timestamp      vmlinux EXPORT_SYMBOL_GPL
++0xbf041102    register_vt_notifier    vmlinux EXPORT_SYMBOL_GPL
++0xf85885d1    nci_unregister_device   vmlinux EXPORT_SYMBOL
++0x07b52e38    rtnl_unregister vmlinux EXPORT_SYMBOL_GPL
++0xe3bc40f6    dpcm_be_dai_trigger     vmlinux EXPORT_SYMBOL_GPL
++0xfbed2f3c    snd_soc_info_volsw_range        vmlinux EXPORT_SYMBOL_GPL
++0x9545974d    blk_rq_map_user vmlinux EXPORT_SYMBOL
++0x693ca44e    jbd2_journal_clear_features     vmlinux EXPORT_SYMBOL
++0x538410d3    generic_pipe_buf_release        vmlinux EXPORT_SYMBOL
++0x8878cfa6    gether_cleanup  vmlinux EXPORT_SYMBOL
++0xc1c72997    platform_bus_type       vmlinux EXPORT_SYMBOL_GPL
++0x2c61162c    drm_fb_helper_check_var vmlinux EXPORT_SYMBOL
++0x7a8cea07    bt_accept_unlink        vmlinux EXPORT_SYMBOL
++0x61812beb    nf_ct_gre_keymap_add    vmlinux EXPORT_SYMBOL_GPL
++0xcf596042    d_find_alias    vmlinux EXPORT_SYMBOL
++0x81d10f5f    trace_seq_putc  vmlinux EXPORT_SYMBOL
++0x760a0f4f    yield   vmlinux EXPORT_SYMBOL
++0xac472389    iio_buffer_register     vmlinux EXPORT_SYMBOL
++0x5dd590c3    sdhci_pltfm_pmops       vmlinux EXPORT_SYMBOL_GPL
++0x0c5b9900    xt_check_target vmlinux EXPORT_SYMBOL_GPL
++0xb67c64fd    __tracepoint_kfree_skb  vmlinux EXPORT_SYMBOL_GPL
++0xd6c2e04b    __tracepoint_napi_poll  vmlinux EXPORT_SYMBOL_GPL
++0x01bb81cc    netdev_upper_dev_unlink vmlinux EXPORT_SYMBOL
++0x5bb9daec    __sg_page_iter_start    vmlinux EXPORT_SYMBOL
++0xac3d64d9    fsstack_copy_attr_all   vmlinux EXPORT_SYMBOL_GPL
++0xda48e711    sdio_claim_irq  vmlinux EXPORT_SYMBOL_GPL
++0x1dc36131    fb_destroy_modedb       vmlinux EXPORT_SYMBOL
++0xca2159d7    udp6_lib_lookup vmlinux EXPORT_SYMBOL_GPL
++0xbf58f5e7    xfrm_init_replay        vmlinux EXPORT_SYMBOL
++0xfb74be78    udp4_lib_lookup vmlinux EXPORT_SYMBOL_GPL
++0x419cfeed    __nf_ct_try_assign_helper       vmlinux EXPORT_SYMBOL_GPL
++0x610dbc32    genl_unregister_ops     vmlinux EXPORT_SYMBOL
++0x9e2000a7    memcpy_toiovecend       vmlinux EXPORT_SYMBOL
++0x3fc5d39f    snd_jack_report vmlinux EXPORT_SYMBOL
++0x93949c2a    inode_sb_list_add       vmlinux EXPORT_SYMBOL_GPL
++0x3d4ee67b    inode_init_always       vmlinux EXPORT_SYMBOL
++0x38883d79    d_invalidate    vmlinux EXPORT_SYMBOL
++0xa0b04675    vmalloc_32      vmlinux EXPORT_SYMBOL
++0xedca9389    pid_task        vmlinux EXPORT_SYMBOL
++0xc1c2b8e5    scsi_command_normalize_sense    vmlinux EXPORT_SYMBOL
++0x4d0d163d    copy_page       vmlinux EXPORT_SYMBOL
++0xe0becdbc    set_h245_addr_hook      vmlinux EXPORT_SYMBOL_GPL
++0xd9a79782    seq_print_acct  vmlinux EXPORT_SYMBOL_GPL
++0xbc9f30d7    textsearch_unregister   vmlinux EXPORT_SYMBOL
++0xf54c51a2    dma_pool_free   vmlinux EXPORT_SYMBOL
++0x32fd447a    monotonic_to_bootbased  vmlinux EXPORT_SYMBOL_GPL
++0x45a6be13    cpufreq_sysfs_remove_file       vmlinux EXPORT_SYMBOL
++0x9a5723c8    input_register_handler  vmlinux EXPORT_SYMBOL
++0x0f618e15    drm_class_device_unregister     vmlinux EXPORT_SYMBOL_GPL
++0xbae73813    inet6_csk_bind_conflict vmlinux EXPORT_SYMBOL_GPL
++0xa35de80f    ipv4_config     vmlinux EXPORT_SYMBOL
++0x7411b488    netif_carrier_on        vmlinux EXPORT_SYMBOL
++0x1212d241    fib_rules_lookup        vmlinux EXPORT_SYMBOL_GPL
++0xb0b847ac    __bitmap_full   vmlinux EXPORT_SYMBOL
++0x4059792f    print_hex_dump  vmlinux EXPORT_SYMBOL
++0x99d40bce    cfg80211_del_sta        vmlinux EXPORT_SYMBOL
++0xe8068f48    ip6_route_output        vmlinux EXPORT_SYMBOL
++0xb57e5e86    __dst_free      vmlinux EXPORT_SYMBOL
++0x9fb986a9    inode_newsize_ok        vmlinux EXPORT_SYMBOL
++0xf39a1727    dev_pm_qos_add_notifier vmlinux EXPORT_SYMBOL_GPL
++0xbb6297fd    drm_mode_group_init_legacy_group        vmlinux EXPORT_SYMBOL
++0xd3ce735a    drm_crtc_helper_set_config      vmlinux EXPORT_SYMBOL
++0xa68b2c0b    pn_sock_get_port        vmlinux EXPORT_SYMBOL
++0x04797338    inet_csk_destroy_sock   vmlinux EXPORT_SYMBOL
++0x050e881c    inet_peer_base_init     vmlinux EXPORT_SYMBOL_GPL
++0x84b183ae    strncmp vmlinux EXPORT_SYMBOL
++0xb6f24459    crypto_register_shashes vmlinux EXPORT_SYMBOL_GPL
++0x1e26be3b    get_anon_bdev   vmlinux EXPORT_SYMBOL
++0x6b29a1fa    ring_buffer_event_length        vmlinux EXPORT_SYMBOL_GPL
++0x5634e278    __clk_get_flags vmlinux EXPORT_SYMBOL_GPL
++0x2e1ca751    clk_put vmlinux EXPORT_SYMBOL
++0xf474a207    usb_gadget_config_buf   vmlinux EXPORT_SYMBOL_GPL
++0x20838fc5    __pm_runtime_idle       vmlinux EXPORT_SYMBOL_GPL
++0x062de44d    sock_kfree_s    vmlinux EXPORT_SYMBOL
++0x3796bdcc    snd_pcm_format_little_endian    vmlinux EXPORT_SYMBOL
++0xa34f1ef5    crc32_le        vmlinux EXPORT_SYMBOL
++0xf54bd49b    lcm     vmlinux EXPORT_SYMBOL_GPL
++0x13354608    scatterwalk_map_and_copy        vmlinux EXPORT_SYMBOL_GPL
++0xf2bec139    empty_aops      vmlinux EXPORT_SYMBOL
++0x45755a66    __task_pid_nr_ns        vmlinux EXPORT_SYMBOL
++0xcbc23c9a    ethtool_op_get_link     vmlinux EXPORT_SYMBOL
++0x5735fbd5    read_cache_pages        vmlinux EXPORT_SYMBOL
++0x4aadeb9a    ring_buffer_alloc_read_page     vmlinux EXPORT_SYMBOL_GPL
++0x2f3f62cd    v4l2_try_ext_ctrls      vmlinux EXPORT_SYMBOL
++0x5d12e48f    input_event_to_user     vmlinux EXPORT_SYMBOL_GPL
++0x6947468c    input_unregister_device vmlinux EXPORT_SYMBOL
++0x91600a8e    usb_string_id   vmlinux EXPORT_SYMBOL_GPL
++0xcc924d52    regulator_disable_regmap        vmlinux EXPORT_SYMBOL_GPL
++0x3a4402b4    ip_generic_getfrag      vmlinux EXPORT_SYMBOL
++0x6308d2cf    call_netdevice_notifiers        vmlinux EXPORT_SYMBOL
++0xc02df0b8    snd_soc_pm_ops  vmlinux EXPORT_SYMBOL_GPL
++0xf9436986    crypto_dequeue_request  vmlinux EXPORT_SYMBOL_GPL
++0xb6555d54    crypto_enqueue_request  vmlinux EXPORT_SYMBOL_GPL
++0x6c2dc956    fat_add_entries vmlinux EXPORT_SYMBOL_GPL
++0xb7fc7a60    thaw_bdev       vmlinux EXPORT_SYMBOL
++0x99a170f8    kmem_cache_alloc_trace  vmlinux EXPORT_SYMBOL
++0x06f22ca2    irq_create_mapping      vmlinux EXPORT_SYMBOL_GPL
++0x992e5dbd    mii_nway_restart        vmlinux EXPORT_SYMBOL
++0xa6a0a273    max77693_write_reg      vmlinux EXPORT_SYMBOL_GPL
++0xa6b21ef2    dpm_suspend_end vmlinux EXPORT_SYMBOL_GPL
++0x27f9262d    sk_run_filter   vmlinux EXPORT_SYMBOL
++0x8bfe698b    netdev_rx_csum_fault    vmlinux EXPORT_SYMBOL
++0x9e61bb05    set_freezable   vmlinux EXPORT_SYMBOL
++0xd5418207    devres_release_group    vmlinux EXPORT_SYMBOL_GPL
++0x45669e2c    drm_fb_helper_restore_fbdev_mode        vmlinux EXPORT_SYMBOL
++0x93fcb0ed    bt_sock_reclassify_lock vmlinux EXPORT_SYMBOL
++0xb6d8be2d    ipv6_push_nfrag_opts    vmlinux EXPORT_SYMBOL
++0x8cdb54d7    ipt_register_table      vmlinux EXPORT_SYMBOL
++0xcc0aef97    neigh_sysctl_unregister vmlinux EXPORT_SYMBOL
++0xe56a9336    snd_pcm_format_width    vmlinux EXPORT_SYMBOL
++0x9077c297    blk_abort_request       vmlinux EXPORT_SYMBOL_GPL
++0x6ed8eb1f    extcon_register_notifier        vmlinux EXPORT_SYMBOL_GPL
++0xc9561772    fb_destroy_modelist     vmlinux EXPORT_SYMBOL_GPL
++0xf494fae4    tcp_peer_is_proven      vmlinux EXPORT_SYMBOL_GPL
++0xdc70cab5    __scm_destroy   vmlinux EXPORT_SYMBOL
++0xfb2acf00    snd_mixer_oss_notify_callback   vmlinux EXPORT_SYMBOL
++0x3a016c77    d_move  vmlinux EXPORT_SYMBOL
++0x5091b823    ring_buffer_read_start  vmlinux EXPORT_SYMBOL_GPL
++0x171751ed    sdio_writeb_readb       vmlinux EXPORT_SYMBOL_GPL
++0x3d94fdae    usb_put_phy     vmlinux EXPORT_SYMBOL_GPL
++0xfbf7bde5    drm_crtc_cleanup        vmlinux EXPORT_SYMBOL
++0x52aaee97    amba_ahb_device_add_res vmlinux EXPORT_SYMBOL_GPL
++0xd0706e35    phy_pm_runtime_put      vmlinux EXPORT_SYMBOL_GPL
++0x0ff178f6    __aeabi_idivmod vmlinux EXPORT_SYMBOL
++0xfb11005b    ipcomp_destroy  vmlinux EXPORT_SYMBOL_GPL
++0x6f81b189    dev_addr_del_multiple   vmlinux EXPORT_SYMBOL
++0xf5ce8c40    touch_atime     vmlinux EXPORT_SYMBOL
++0x53614269    get_cpu_idle_time_us    vmlinux EXPORT_SYMBOL_GPL
++0x61c243fc    mod_timer_pending       vmlinux EXPORT_SYMBOL
++0xf821b501    device_set_wakeup_capable       vmlinux EXPORT_SYMBOL_GPL
++0x80bbfeb1    s3c_gpio_cfgall_range   vmlinux EXPORT_SYMBOL_GPL
++0x10081d73    s3c_gpio_cfgpin_range   vmlinux EXPORT_SYMBOL_GPL
++0x75464443    phonet_proto_unregister vmlinux EXPORT_SYMBOL
++0x7d6fed76    rtnl_configure_link     vmlinux EXPORT_SYMBOL
++0x8c844510    sock_wmalloc    vmlinux EXPORT_SYMBOL
++0xbaf75338    snd_soc_codec_writable_register vmlinux EXPORT_SYMBOL_GPL
++0x1e6d26a8    strstr  vmlinux EXPORT_SYMBOL
++0xea6f9ca2    task_user_regset_view   vmlinux EXPORT_SYMBOL_GPL
++0x4de17ab3    usb_state_string        vmlinux EXPORT_SYMBOL_GPL
++0x349cba85    strchr  vmlinux EXPORT_SYMBOL
++0xb83a0cc6    perf_event_disable      vmlinux EXPORT_SYMBOL_GPL
++0x3b5965e0    inet_csk_listen_stop    vmlinux EXPORT_SYMBOL_GPL
++0x6be59bed    kobject_create_and_add  vmlinux EXPORT_SYMBOL_GPL
++0xdced71ac    setup_new_exec  vmlinux EXPORT_SYMBOL
++0xdb8a1b3f    usermodehelper_read_trylock     vmlinux EXPORT_SYMBOL_GPL
++0x7c9ad2eb    usb_wait_anchor_empty_timeout   vmlinux EXPORT_SYMBOL_GPL
++0xf2fca922    uart_parse_options      vmlinux EXPORT_SYMBOL_GPL
++0x7f63b31e    _memcpy_toio    vmlinux EXPORT_SYMBOL
++0x3e3fcdf2    xfrm_state_lookup_byaddr        vmlinux EXPORT_SYMBOL
++0x2b538790    pskb_expand_head        vmlinux EXPORT_SYMBOL
++0xdb67d9bb    of_i2c_register_devices vmlinux EXPORT_SYMBOL
++0x9f7314d6    wakeup_source_prepare   vmlinux EXPORT_SYMBOL_GPL
++0x2a828cb7    drm_noop        vmlinux EXPORT_SYMBOL
++0x3d3c540f    elf_hwcap       vmlinux EXPORT_SYMBOL
++0xa045219b    fuse_do_ioctl   vmlinux EXPORT_SYMBOL_GPL
++0x8fa5cf61    pm_qos_update_request   vmlinux EXPORT_SYMBOL_GPL
++0x73514fba    i2c_release_client      vmlinux EXPORT_SYMBOL
++0x168db450    take_over_console       vmlinux EXPORT_SYMBOL
++0x0aa13d05    __raw_readsw    vmlinux EXPORT_SYMBOL
++0x816a1ee5    rtnl_link_register      vmlinux EXPORT_SYMBOL_GPL
++0x9fd1a952    sk_set_memalloc vmlinux EXPORT_SYMBOL_GPL
++0x8605ed02    lock_may_write  vmlinux EXPORT_SYMBOL
++0xb24e73ff    bh_submit_read  vmlinux EXPORT_SYMBOL
++0x455db47d    dma_mark_declared_memory_occupied       vmlinux EXPORT_SYMBOL
++0x1a65f4ad    __arm_ioremap_pfn       vmlinux EXPORT_SYMBOL
++0x955e8436    eth_change_mtu  vmlinux EXPORT_SYMBOL
++0xa300e599    eth_header_parse        vmlinux EXPORT_SYMBOL
++0x42977ad4    __hw_addr_del_multiple  vmlinux EXPORT_SYMBOL
++0xf57de517    bdev_stack_limits       vmlinux EXPORT_SYMBOL
++0x25bed5a1    static_key_slow_dec_deferred    vmlinux EXPORT_SYMBOL_GPL
++0xd2aaeb4e    kmsg_dump_get_buffer    vmlinux EXPORT_SYMBOL_GPL
++0xedb320d6    nf_nat_pptp_hook_exp_gre        vmlinux EXPORT_SYMBOL_GPL
++0xdc0a9f66    sock_wake_async vmlinux EXPORT_SYMBOL
++0x68e05d57    getrawmonotonic vmlinux EXPORT_SYMBOL
++0xee715ef8    lg_global_unlock        vmlinux EXPORT_SYMBOL
++0xbebb2820    crypto_register_algs    vmlinux EXPORT_SYMBOL_GPL
++0xccc2bc05    fat_free_clusters       vmlinux EXPORT_SYMBOL_GPL
++0xde99c012    jbd2_complete_transaction       vmlinux EXPORT_SYMBOL
++0x60599993    __set_page_dirty_buffers        vmlinux EXPORT_SYMBOL
++0x8b775d3a    __wake_up_locked        vmlinux EXPORT_SYMBOL_GPL
++0x93eb18c6    of_platform_device_create       vmlinux EXPORT_SYMBOL
++0x9e5bfa34    bt_sock_poll    vmlinux EXPORT_SYMBOL
++0x7e98f5ff    sock_prot_inuse_add     vmlinux EXPORT_SYMBOL_GPL
++0xf9e73082    scnprintf       vmlinux EXPORT_SYMBOL
++0xa1b4cc6a    aead_geniv_exit vmlinux EXPORT_SYMBOL_GPL
++0xa7001f92    mod_zone_page_state     vmlinux EXPORT_SYMBOL
++0x92e79788    perf_event_refresh      vmlinux EXPORT_SYMBOL_GPL
++0x77e7babf    usb_hcd_platform_shutdown       vmlinux EXPORT_SYMBOL_GPL
++0x6d4d6df5    s3c_gpio_cfgpin vmlinux EXPORT_SYMBOL
++0x7f250a18    tcf_register_action     vmlinux EXPORT_SYMBOL
++0x41852af3    blk_add_request_payload vmlinux EXPORT_SYMBOL_GPL
++0x8bf05477    pm_runtime_autosuspend_expiration       vmlinux EXPORT_SYMBOL_GPL
++0xea25f714    rtnl_link_unregister    vmlinux EXPORT_SYMBOL_GPL
++0x5f75b2b7    snd_soc_dapm_enable_pin vmlinux EXPORT_SYMBOL_GPL
++0x87879778    copy_strings_kernel     vmlinux EXPORT_SYMBOL
++0x731b81f1    __wait_on_bit   vmlinux EXPORT_SYMBOL
++0x18838e93    hrtimer_get_remaining   vmlinux EXPORT_SYMBOL_GPL
++0x0be4ca5a    extcon_set_state        vmlinux EXPORT_SYMBOL_GPL
++0xacdf7eb6    led_trigger_register_simple     vmlinux EXPORT_SYMBOL_GPL
++0x20645642    drm_debug       vmlinux EXPORT_SYMBOL
++0x5f41d1f8    rdev_get_id     vmlinux EXPORT_SYMBOL_GPL
++0xf6f440a6    tcp_enter_memory_pressure       vmlinux EXPORT_SYMBOL
++0x3b9a9d19    skb_add_rx_frag vmlinux EXPORT_SYMBOL
++0x32b2bc89    snd_soc_write   vmlinux EXPORT_SYMBOL_GPL
++0x5b44d926    snd_soc_get_xr_sx       vmlinux EXPORT_SYMBOL_GPL
++0xf1395b13    snd_soc_put_xr_sx       vmlinux EXPORT_SYMBOL_GPL
++0x4982a57f    probe_kernel_write      vmlinux EXPORT_SYMBOL_GPL
++0x811dc334    usb_unregister_notify   vmlinux EXPORT_SYMBOL_GPL
++0xa6f7283b    arp_create      vmlinux EXPORT_SYMBOL
++0x660b5392    jbd2_journal_get_create_access  vmlinux EXPORT_SYMBOL
++0x99dd4a27    no_llseek       vmlinux EXPORT_SYMBOL
++0x72532806    _raw_read_unlock_irq    vmlinux EXPORT_SYMBOL
++0xe4719990    rt_mutex_timed_lock     vmlinux EXPORT_SYMBOL_GPL
++0xb5d9454c    printk_emit     vmlinux EXPORT_SYMBOL
++0x801e5a15    st_sensors_check_device_support vmlinux EXPORT_SYMBOL
++0xeec77f6d    iio_map_array_unregister        vmlinux EXPORT_SYMBOL_GPL
++0x6390efda    of_modalias_node        vmlinux EXPORT_SYMBOL_GPL
++0x7ac03539    tty_port_alloc_xmit_buf vmlinux EXPORT_SYMBOL
++0x5cebb76e    vfs_truncate    vmlinux EXPORT_SYMBOL_GPL
++0xfc52a8aa    mmc_gpio_request_cd     vmlinux EXPORT_SYMBOL
++0xf7a4e432    mmc_gpio_request_ro     vmlinux EXPORT_SYMBOL
++0x74d52889    rtc_irq_set_freq        vmlinux EXPORT_SYMBOL_GPL
++0x8e9efd84    dma_declare_coherent_memory     vmlinux EXPORT_SYMBOL
++0xfcfa03ff    fb_videomode_to_modelist        vmlinux EXPORT_SYMBOL
++0x789c0277    nfc_unregister_device   vmlinux EXPORT_SYMBOL
++0x48744ce2    lro_receive_frags       vmlinux EXPORT_SYMBOL
++0xf6851d5f    register_sysctl_paths   vmlinux EXPORT_SYMBOL
++0x90a4a466    generic_show_options    vmlinux EXPORT_SYMBOL
++0x74dd4a76    pagecache_write_begin   vmlinux EXPORT_SYMBOL
++0x7b42b5d4    drm_mode_copy   vmlinux EXPORT_SYMBOL
++0x6a7c03c7    asoc_dma_platform_register      vmlinux EXPORT_SYMBOL_GPL
++0xc6cbbc89    capable vmlinux EXPORT_SYMBOL
++0xd07125d9    spi_finalize_current_message    vmlinux EXPORT_SYMBOL_GPL
++0xf5514ce6    dev_pm_qos_add_request  vmlinux EXPORT_SYMBOL_GPL
++0xb316e246    nf_afinfo       vmlinux EXPORT_SYMBOL
++0x4ef5bcf4    perf_swevent_get_recursion_context      vmlinux EXPORT_SYMBOL_GPL
++0xab7e3362    irq_find_mapping        vmlinux EXPORT_SYMBOL_GPL
++0xbcf89ab6    __wake_up_sync  vmlinux EXPORT_SYMBOL_GPL
++0xc8b57c27    autoremove_wake_function        vmlinux EXPORT_SYMBOL
++0x36aa3266    hid_debug_event vmlinux EXPORT_SYMBOL_GPL
++0x9ed21fce    mmc_can_trim    vmlinux EXPORT_SYMBOL
++0x5658ad69    v4l2_async_register_subdev      vmlinux EXPORT_SYMBOL
++0x99781445    input_set_capability    vmlinux EXPORT_SYMBOL
++0xf3343f80    drm_mode_create_tv_properties   vmlinux EXPORT_SYMBOL
++0x69fefbb6    nf_ct_port_tuple_to_nlattr      vmlinux EXPORT_SYMBOL_GPL
++0xd9a9bb30    getname vmlinux EXPORT_SYMBOL
++0xe7ffe877    pcpu_base_addr  vmlinux EXPORT_SYMBOL_GPL
++0x131e7ee8    drm_fb_helper_hotplug_event     vmlinux EXPORT_SYMBOL
++0x983f0520    drm_fb_helper_initial_config    vmlinux EXPORT_SYMBOL
++0x469972c2    give_up_console vmlinux EXPORT_SYMBOL
++0x300573d1    nf_conntrack_helper_register    vmlinux EXPORT_SYMBOL_GPL
++0x2597c27d    snd_seq_root    vmlinux EXPORT_SYMBOL
++0x9a11a0fc    crypto_attr_alg_name    vmlinux EXPORT_SYMBOL_GPL
++0xa0f2a42b    debugfs_create_regset32 vmlinux EXPORT_SYMBOL_GPL
++0x3e08c129    drm_mode_find_dmt       vmlinux EXPORT_SYMBOL
++0xbc8b0f41    xfrm_calg_get_byid      vmlinux EXPORT_SYMBOL_GPL
++0xf20dabd8    free_irq        vmlinux EXPORT_SYMBOL
++0x9073a3d4    usb_hc_died     vmlinux EXPORT_SYMBOL_GPL
++0xe61a6d2f    gpio_unexport   vmlinux EXPORT_SYMBOL_GPL
++0xdf58d91e    pinctrl_dev_get_name    vmlinux EXPORT_SYMBOL_GPL
++0x4c3b5878    ieee80211_get_response_rate     vmlinux EXPORT_SYMBOL
++0xa6b9609a    jbd2_journal_init_inode vmlinux EXPORT_SYMBOL
++0xe91ef2b5    deactivate_locked_super vmlinux EXPORT_SYMBOL
++0x0280cf55    filemap_fdatawait       vmlinux EXPORT_SYMBOL
++0x134178d9    v4l2_m2m_fop_mmap       vmlinux EXPORT_SYMBOL_GPL
++0x9091c717    netdev_class_create_file        vmlinux EXPORT_SYMBOL
++0x4f816e9b    snd_pcm_format_big_endian       vmlinux EXPORT_SYMBOL
++0x09d44df9    in_lock_functions       vmlinux EXPORT_SYMBOL
++0x509817cf    vprintk_emit    vmlinux EXPORT_SYMBOL
++0x4c571d12    cfg80211_cqm_pktloss_notify     vmlinux EXPORT_SYMBOL
++0x8b260b7f    ip6_tnl_xmit_ctl        vmlinux EXPORT_SYMBOL_GPL
++0x7b9e609a    ip6_sk_update_pmtu      vmlinux EXPORT_SYMBOL_GPL
++0x199db92b    netdev_rx_handler_unregister    vmlinux EXPORT_SYMBOL_GPL
++0x4cdf24a6    skb_copy_datagram_const_iovec   vmlinux EXPORT_SYMBOL
++0xb994401f    kernel_getpeername      vmlinux EXPORT_SYMBOL
++0x7b10e656    sysfs_chmod_file        vmlinux EXPORT_SYMBOL_GPL
++0x55d7c934    find_module     vmlinux EXPORT_SYMBOL_GPL
++0x548b482c    rt_mutex_lock   vmlinux EXPORT_SYMBOL_GPL
++0x39533602    media_entity_graph_walk_start   vmlinux EXPORT_SYMBOL_GPL
++0x51ef2459    platform_driver_probe   vmlinux EXPORT_SYMBOL_GPL
++0xeb93a8ee    serial8250_do_set_termios       vmlinux EXPORT_SYMBOL
++0x8afc7ce3    __devm_of_phy_provider_register vmlinux EXPORT_SYMBOL_GPL
++0x548fedb9    skb_complete_wifi_ack   vmlinux EXPORT_SYMBOL_GPL
++0x11f7ed4c    hex_to_bin      vmlinux EXPORT_SYMBOL
++0x9aeecd64    simple_pin_fs   vmlinux EXPORT_SYMBOL
++0x5635a60a    vmalloc_user    vmlinux EXPORT_SYMBOL
++0xd36ab13e    posix_clock_unregister  vmlinux EXPORT_SYMBOL_GPL
++0x1fe9f800    unregister_cpu_notifier vmlinux EXPORT_SYMBOL
++0xb59a9548    vb2_expbuf      vmlinux EXPORT_SYMBOL_GPL
++0xf6eb0d71    input_event     vmlinux EXPORT_SYMBOL
++0xfc3a261f    dev_get_regmap  vmlinux EXPORT_SYMBOL_GPL
++0x89d145ed    pin_config_get  vmlinux EXPORT_SYMBOL
++0xc54fc2d7    devm_pinctrl_put        vmlinux EXPORT_SYMBOL_GPL
++0x9671e047    devm_pinctrl_get        vmlinux EXPORT_SYMBOL_GPL
++0x4d45d89e    udp_memory_allocated    vmlinux EXPORT_SYMBOL
++0x3e8b4fda    tc_classify     vmlinux EXPORT_SYMBOL
++0x98509e55    sock_no_sendpage        vmlinux EXPORT_SYMBOL
++0x7bd6700d    blk_pre_runtime_suspend vmlinux EXPORT_SYMBOL
++0x6444b7bb    iio_read_channel_raw    vmlinux EXPORT_SYMBOL_GPL
++0x70120108    thermal_generate_netlink_event  vmlinux EXPORT_SYMBOL_GPL
++0x800e4ffa    __muldi3        vmlinux EXPORT_SYMBOL
++0x4c1182cb    bitmap_scnprintf        vmlinux EXPORT_SYMBOL
++0xd7b4599b    __idr_get_new_above     vmlinux EXPORT_SYMBOL
++0x368dc456    proc_create_data        vmlinux EXPORT_SYMBOL
++0x4d405db8    param_ops_string        vmlinux EXPORT_SYMBOL
++0xdd021b6b    get_current_tty vmlinux EXPORT_SYMBOL_GPL
++0xabbaaf4c    kernel_getsockname      vmlinux EXPORT_SYMBOL
++0x5caf4413    kernel_sendmsg  vmlinux EXPORT_SYMBOL
++0x3971b4df    snd_ecards_limit        vmlinux EXPORT_SYMBOL
++0xd77a5aa5    __bitmap_and    vmlinux EXPORT_SYMBOL
++0xfac05b29    unregister_gadget_item  vmlinux EXPORT_SYMBOL
++0x268930d0    uart_register_driver    vmlinux EXPORT_SYMBOL
++0xace7ae5c    xfrm_alloc_spi  vmlinux EXPORT_SYMBOL
++0x0a4a1a2f    blk_rq_err_bytes        vmlinux EXPORT_SYMBOL_GPL
++0x6d414f53    crypto_blkcipher_type   vmlinux EXPORT_SYMBOL_GPL
++0x2ffe9a6b    crypto_givcipher_type   vmlinux EXPORT_SYMBOL_GPL
++0xe5ddcbd8    nfc_targets_found       vmlinux EXPORT_SYMBOL
++0x028f3057    nf_log_packet   vmlinux EXPORT_SYMBOL
++0xc8949349    qdisc_tree_decrease_qlen        vmlinux EXPORT_SYMBOL
++0x7d16c025    dev_remove_pack vmlinux EXPORT_SYMBOL
++0xf88eb7f2    rq_flush_dcache_pages   vmlinux EXPORT_SYMBOL_GPL
++0x2d8764e5    blkcipher_walk_virt     vmlinux EXPORT_SYMBOL_GPL
++0x5fce0dc6    posix_lock_file vmlinux EXPORT_SYMBOL
++0x71a672ef    dmam_pool_destroy       vmlinux EXPORT_SYMBOL
++0x3832da09    set_page_dirty  vmlinux EXPORT_SYMBOL
++0xe4937b31    i2c_bit_algo    vmlinux EXPORT_SYMBOL
++0x2c256e1f    input_scancode_to_scalar        vmlinux EXPORT_SYMBOL
++0x758978d2    spi_get_next_queued_message     vmlinux EXPORT_SYMBOL_GPL
++0xde9360ba    totalram_pages  vmlinux EXPORT_SYMBOL
++0xacc53440    video_device_alloc      vmlinux EXPORT_SYMBOL
++0x331f6073    udp_disconnect  vmlinux EXPORT_SYMBOL
++0x8a5c060e    nf_conntrack_l4proto_udp4       vmlinux EXPORT_SYMBOL_GPL
++0x492ab82c    dev_uc_unsync   vmlinux EXPORT_SYMBOL
++0xb1615d69    dev_mc_unsync   vmlinux EXPORT_SYMBOL
++0xa73acb8d    dump_seek       vmlinux EXPORT_SYMBOL
++0xea63afac    usb_free_streams        vmlinux EXPORT_SYMBOL_GPL
++0x0fb8623c    regcache_cache_only     vmlinux EXPORT_SYMBOL_GPL
++0xb89f40b3    __register_chrdev       vmlinux EXPORT_SYMBOL
++0x4ed5e0d7    v4l2_chip_match_host    vmlinux EXPORT_SYMBOL
++0x78272b1e    bus_get_kset    vmlinux EXPORT_SYMBOL_GPL
++0x87c0bce8    net_dma_find_channel    vmlinux EXPORT_SYMBOL
++0xc31f408b    __display_entity_register       vmlinux EXPORT_SYMBOL_GPL
++0x5b1cfbcd    of_get_fb_videomode     vmlinux EXPORT_SYMBOL_GPL
++0xe6775a2f    fb_show_logo    vmlinux EXPORT_SYMBOL
++0xa290f4a9    fb_pan_display  vmlinux EXPORT_SYMBOL
++0x61c2dac6    kstrtoll_from_user      vmlinux EXPORT_SYMBOL
++0x83904bc7    st_sensors_deallocate_trigger   vmlinux EXPORT_SYMBOL
++0x7bc41c7c    rtc_class_close vmlinux EXPORT_SYMBOL_GPL
++0x218b226c    sec_bulk_write  vmlinux EXPORT_SYMBOL_GPL
++0xf09de776    get_random_int  vmlinux EXPORT_SYMBOL
++0x5a937d99    blk_queue_stack_limits  vmlinux EXPORT_SYMBOL
++0x174b7df6    free_vm_area    vmlinux EXPORT_SYMBOL_GPL
++0x8ffa3ccd    devres_alloc    vmlinux EXPORT_SYMBOL_GPL
++0x956a91ba    gpio_get_value_cansleep vmlinux EXPORT_SYMBOL_GPL
++0x92886ef2    udp_lib_setsockopt      vmlinux EXPORT_SYMBOL
++0xc4a35da7    udp_lib_getsockopt      vmlinux EXPORT_SYMBOL
++0xdb1ed3be    nf_conntrack_free       vmlinux EXPORT_SYMBOL_GPL
++0x96898769    sysfs_format_mac        vmlinux EXPORT_SYMBOL
++0x15604324    sk_send_sigurg  vmlinux EXPORT_SYMBOL
++0x8fca87b8    proc_set_size   vmlinux EXPORT_SYMBOL
++0x4b5fd49e    dm_kcopyd_do_callback   vmlinux EXPORT_SYMBOL
++0x289bc356    mdiobus_alloc_size      vmlinux EXPORT_SYMBOL
++0xf36e7280    spi_bus_lock    vmlinux EXPORT_SYMBOL_GPL
++0x0c060ece    cfg80211_sched_scan_stopped     vmlinux EXPORT_SYMBOL
++0xab2289f2    drop_super      vmlinux EXPORT_SYMBOL
++0x27e1a049    printk  vmlinux EXPORT_SYMBOL
++0x3194878b    pm_generic_poweroff_noirq       vmlinux EXPORT_SYMBOL_GPL
++0x688f09be    dev_crit        vmlinux EXPORT_SYMBOL
++0xfd94d6cb    drm_get_connector_status_name   vmlinux EXPORT_SYMBOL
++0xbdef1e6b    drm_gem_object_release  vmlinux EXPORT_SYMBOL
++0x36fa2c4a    cfg80211_get_bss        vmlinux EXPORT_SYMBOL
++0xef2e65fd    sk_alloc        vmlinux EXPORT_SYMBOL
++0x096e7523    try_to_release_page     vmlinux EXPORT_SYMBOL
++0xa61b1477    tracepoint_iter_start   vmlinux EXPORT_SYMBOL_GPL
++0x9d05f6c4    ktime_get_clocktai      vmlinux EXPORT_SYMBOL
++0x6a87a478    synchronize_srcu        vmlinux EXPORT_SYMBOL_GPL
++0xa3afa3ce    bus_unregister_notifier vmlinux EXPORT_SYMBOL_GPL
++0xbe001c53    drm_property_add_enum   vmlinux EXPORT_SYMBOL
++0x48c2a99d    drm_helper_resume_force_mode    vmlinux EXPORT_SYMBOL
++0x1258d9d9    regulator_disable       vmlinux EXPORT_SYMBOL_GPL
++0x1b3261e0    klist_iter_init vmlinux EXPORT_SYMBOL_GPL
++0xaeec4fd1    hci_conn_switch_role    vmlinux EXPORT_SYMBOL
++0x8809bdee    kobject_add     vmlinux EXPORT_SYMBOL
++0x10138352    tracing_on      vmlinux EXPORT_SYMBOL_GPL
++0x39aa4754    dma_buf_mmap    vmlinux EXPORT_SYMBOL_GPL
++0x58c6fc51    dma_buf_kmap    vmlinux EXPORT_SYMBOL_GPL
++0x299bbc21    dma_buf_vmap    vmlinux EXPORT_SYMBOL_GPL
++0x5a2579f9    platform_driver_register        vmlinux EXPORT_SYMBOL_GPL
++0xa8d6809d    drm_dp_bw_code_to_link_rate     vmlinux EXPORT_SYMBOL
++0xfd86731b    drm_fb_helper_init      vmlinux EXPORT_SYMBOL
++0xd4880725    __video_source_register vmlinux EXPORT_SYMBOL_GPL
++0xe08f4a3d    devm_of_phy_provider_unregister vmlinux EXPORT_SYMBOL_GPL
++0x61634f05    lock_flocks     vmlinux EXPORT_SYMBOL_GPL
++0x3843f6b8    queue_kthread_work      vmlinux EXPORT_SYMBOL_GPL
++0x8e332478    thermal_zone_get_temp   vmlinux EXPORT_SYMBOL_GPL
++0xdd64085c    platform_driver_unregister      vmlinux EXPORT_SYMBOL_GPL
++0xaa6f23ad    rfkill_get_led_trigger_name     vmlinux EXPORT_SYMBOL
++0x9cab34a6    rfkill_set_led_trigger_name     vmlinux EXPORT_SYMBOL
++0x23b075bd    gnet_stats_copy_queue   vmlinux EXPORT_SYMBOL
++0x12e85778    kstrtol_from_user       vmlinux EXPORT_SYMBOL
++0x331504fa    simple_dir_operations   vmlinux EXPORT_SYMBOL
++0x3eabdee4    of_match_device vmlinux EXPORT_SYMBOL
++0x610e908e    hid_ignore      vmlinux EXPORT_SYMBOL_GPL
++0x3838d3de    usb_get_urb     vmlinux EXPORT_SYMBOL_GPL
++0xd400a944    cfg80211_gtk_rekey_notify       vmlinux EXPORT_SYMBOL
++0x6403e338    tcp_memory_pressure     vmlinux EXPORT_SYMBOL
++0x23a650aa    setattr_copy    vmlinux EXPORT_SYMBOL
++0x6b6b3081    iommu_domain_has_cap    vmlinux EXPORT_SYMBOL_GPL
++0xdd9fe08e    nfc_hci_driver_failure  vmlinux EXPORT_SYMBOL
++0x091cae50    cfg80211_probe_status   vmlinux EXPORT_SYMBOL
++0xa5e8f497    inet_frags_fini vmlinux EXPORT_SYMBOL
++0xff048999    snd_register_oss_device vmlinux EXPORT_SYMBOL
++0x24a94b26    snd_info_get_line       vmlinux EXPORT_SYMBOL
++0x7ba9873c    elv_dispatch_sort       vmlinux EXPORT_SYMBOL
++0x1471fd44    elv_add_request vmlinux EXPORT_SYMBOL
++0x9be7bde4    security_tun_dev_attach vmlinux EXPORT_SYMBOL
++0xf346231f    seq_list_start_head     vmlinux EXPORT_SYMBOL
++0x65d9e877    cpufreq_register_notifier       vmlinux EXPORT_SYMBOL
++0x399ed296    v4l2_subdev_link_validate_default       vmlinux EXPORT_SYMBOL_GPL
++0xfb974dd4    v4l2_ctrl_auto_cluster  vmlinux EXPORT_SYMBOL
++0xd9097364    v4l2_event_dequeue      vmlinux EXPORT_SYMBOL_GPL
++0xd9a8b315    scsi_queue_work vmlinux EXPORT_SYMBOL_GPL
++0xf564412a    __aeabi_ulcmp   vmlinux EXPORT_SYMBOL
++0x67e6edc4    netif_device_attach     vmlinux EXPORT_SYMBOL
++0x6c3962d5    netif_device_detach     vmlinux EXPORT_SYMBOL
++0x7464ec66    netdev_set_default_ethtool_ops  vmlinux EXPORT_SYMBOL_GPL
++0x08cf6c97    snd_soc_dai_digital_mute        vmlinux EXPORT_SYMBOL_GPL
++0x47628784    simple_attr_read        vmlinux EXPORT_SYMBOL_GPL
++0xe4bad1e4    sdhci_pltfm_init        vmlinux EXPORT_SYMBOL_GPL
++0xe3b2bc37    gether_connect  vmlinux EXPORT_SYMBOL
++0x2fe1cc7e    device_rename   vmlinux EXPORT_SYMBOL_GPL
++0xc147be94    drm_i2c_encoder_restore vmlinux EXPORT_SYMBOL
++0x56f369aa    kernel_bind     vmlinux EXPORT_SYMBOL
++0xcd279169    nla_find        vmlinux EXPORT_SYMBOL
++0x5cdf6de2    kernel_read     vmlinux EXPORT_SYMBOL
++0xfcc43f3f    vfs_read        vmlinux EXPORT_SYMBOL
++0xc8add232    ring_buffer_record_disable      vmlinux EXPORT_SYMBOL_GPL
++0xf2e84b50    __devm_release_region   vmlinux EXPORT_SYMBOL
++0xd4292ec2    dev_notice      vmlinux EXPORT_SYMBOL
++0x02e6e099    drm_mode_width  vmlinux EXPORT_SYMBOL
++0xcc248d26    serial8250_suspend_port vmlinux EXPORT_SYMBOL
++0x4e6e8ea7    fg_console      vmlinux EXPORT_SYMBOL
++0xbb9cc562    fl6_merge_options       vmlinux EXPORT_SYMBOL_GPL
++0x20bf8fa2    __inet_hash_nolisten    vmlinux EXPORT_SYMBOL_GPL
++0x9fb3dd30    memcpy_fromiovec        vmlinux EXPORT_SYMBOL
++0x9cde26bf    blk_queue_prep_rq       vmlinux EXPORT_SYMBOL
++0x262f20a8    local_clock     vmlinux EXPORT_SYMBOL_GPL
++0x7ebf0ef8    __nf_nat_l4proto_find   vmlinux EXPORT_SYMBOL_GPL
++0x503bc70a    drm_gem_prime_export    vmlinux EXPORT_SYMBOL
++0x8d6f81b4    __div64_32      vmlinux EXPORT_SYMBOL
++0x93fca811    __get_free_pages        vmlinux EXPORT_SYMBOL
++0xbb189cad    disallow_signal vmlinux EXPORT_SYMBOL
++0xefe5a9bf    usbnet_resume_rx        vmlinux EXPORT_SYMBOL_GPL
++0x1c4116bc    __class_register        vmlinux EXPORT_SYMBOL_GPL
++0x72cae0c9    nfc_driver_failure      vmlinux EXPORT_SYMBOL
++0xc3d70f22    rawv6_mh_filter_register        vmlinux EXPORT_SYMBOL
++0xdbcd416e    sysctl_ip_nonlocal_bind vmlinux EXPORT_SYMBOL
++0xa675804c    utf8s_to_utf16s vmlinux EXPORT_SYMBOL
++0xb4b97c90    pvclock_gtod_register_notifier  vmlinux EXPORT_SYMBOL_GPL
++0xdf9d0875    ns_capable      vmlinux EXPORT_SYMBOL
++0x13ba72ba    usb_free_coherent       vmlinux EXPORT_SYMBOL_GPL
++0x4671c723    rawv6_mh_filter_unregister      vmlinux EXPORT_SYMBOL
++0x5855bb11    blk_queue_resize_tags   vmlinux EXPORT_SYMBOL
++0x5159ff6c    mmc_fixup_device        vmlinux EXPORT_SYMBOL
++0x186b8590    ipv4_specific   vmlinux EXPORT_SYMBOL
++0x9d5e9b60    nf_ct_l3proto_find_get  vmlinux EXPORT_SYMBOL_GPL
++0x3f2c16f1    nf_ct_l4proto_find_get  vmlinux EXPORT_SYMBOL_GPL
++0xe20a528d    nf_queue_entry_release_refs     vmlinux EXPORT_SYMBOL_GPL
++0x4335fafb    proto_unregister        vmlinux EXPORT_SYMBOL
++0x5762296f    fuse_conn_kill  vmlinux EXPORT_SYMBOL_GPL
++0xe473e06d    __fsnotify_inode_delete vmlinux EXPORT_SYMBOL_GPL
++0xe2ed7067    i2c_new_dummy   vmlinux EXPORT_SYMBOL_GPL
++0x3cac21b9    regulator_sync_voltage  vmlinux EXPORT_SYMBOL_GPL
++0x71e7aab0    from_kprojid_munged     vmlinux EXPORT_SYMBOL
++0x3ca7e128    tty_unlock_pair vmlinux EXPORT_SYMBOL
++0x146d2f0c    rtnl_af_register        vmlinux EXPORT_SYMBOL_GPL
++0x97ecf37c    kunmap_high     vmlinux EXPORT_SYMBOL
++0x4470a79b    param_ops_long  vmlinux EXPORT_SYMBOL
++0x45bd9efd    dm_table_put    vmlinux EXPORT_SYMBOL
++0xf2a353ac    v4l2_i2c_tuner_addrs    vmlinux EXPORT_SYMBOL_GPL
++0xc7fd39bb    drm_dp_channel_eq_ok    vmlinux EXPORT_SYMBOL
++0xa0472547    inet_csk_update_pmtu    vmlinux EXPORT_SYMBOL_GPL
++0xacf4d843    match_strdup    vmlinux EXPORT_SYMBOL
++0x870bf928    radix_tree_lookup       vmlinux EXPORT_SYMBOL
++0x4672e88b    __crypto_dequeue_request        vmlinux EXPORT_SYMBOL_GPL
++0x7b0f1ab3    ring_buffer_free_read_page      vmlinux EXPORT_SYMBOL_GPL
++0x9745b34c    rt_mutex_unlock vmlinux EXPORT_SYMBOL_GPL
++0xac745cfe    s3c_adc_read    vmlinux EXPORT_SYMBOL_GPL
++0x4dc817ff    usb_composite_overwrite_options vmlinux EXPORT_SYMBOL_GPL
++0xcd8ff108    neigh_seq_next  vmlinux EXPORT_SYMBOL
++0xb4062ffd    vfs_rename      vmlinux EXPORT_SYMBOL
++0xdc4ed03b    generic_ro_fops vmlinux EXPORT_SYMBOL
++0x1300b437    nci_register_device     vmlinux EXPORT_SYMBOL
++0xbcfcecc3    user_path_create        vmlinux EXPORT_SYMBOL
++0xcf71a180    kthread_bind    vmlinux EXPORT_SYMBOL
++0x4571f8be    usb_string_ids_n        vmlinux EXPORT_SYMBOL_GPL
++0xf1ea24f2    ipv6_setsockopt vmlinux EXPORT_SYMBOL
++0x2d97bed6    dm_kcopyd_zero  vmlinux EXPORT_SYMBOL
++0xa1f5edea    drm_property_destroy    vmlinux EXPORT_SYMBOL
++0x3548305a    inet_frag_find  vmlinux EXPORT_SYMBOL
++0xf937428d    inetdev_by_index        vmlinux EXPORT_SYMBOL
++0x33f234ad    __sk_backlog_rcv        vmlinux EXPORT_SYMBOL
++0xb0fbdabc    crypto_lookup_skcipher  vmlinux EXPORT_SYMBOL_GPL
++0xdf0f75c6    eventfd_signal  vmlinux EXPORT_SYMBOL_GPL
++0x21f678b9    clocksource_unregister  vmlinux EXPORT_SYMBOL
++0xe3b5bb1e    usb_poison_anchored_urbs        vmlinux EXPORT_SYMBOL_GPL
++0x36003409    nfc_hci_send_event      vmlinux EXPORT_SYMBOL
++0xd26c8ac5    bt_sock_wait_state      vmlinux EXPORT_SYMBOL
++0x8bd1c81c    fifo_set_limit  vmlinux EXPORT_SYMBOL
++0xe630ebe9    snd_soc_get_pcm_runtime vmlinux EXPORT_SYMBOL_GPL
++0x9f7af994    writeback_in_progress   vmlinux EXPORT_SYMBOL
++0x94048818    filemap_fdatawrite      vmlinux EXPORT_SYMBOL
++0x9cc4f70a    register_pm_notifier    vmlinux EXPORT_SYMBOL_GPL
++0xdf6f4023    phy_drivers_unregister  vmlinux EXPORT_SYMBOL
++0x4cc1d9d6    con_debug_enter vmlinux EXPORT_SYMBOL_GPL
++0x807d2b2c    xt_recseq       vmlinux EXPORT_SYMBOL_GPL
++0x089e2060    __ethtool_get_settings  vmlinux EXPORT_SYMBOL
++0xcdd9e311    dev_add_offload vmlinux EXPORT_SYMBOL
++0x90ac3102    dev_base_lock   vmlinux EXPORT_SYMBOL
++0xfcc256a6    css_id  vmlinux EXPORT_SYMBOL_GPL
++0x2e7be112    _raw_read_lock_irqsave  vmlinux EXPORT_SYMBOL
++0x284633c4    devm_clk_register       vmlinux EXPORT_SYMBOL_GPL
++0x440982c5    usb_del_gadget_udc      vmlinux EXPORT_SYMBOL_GPL
++0x0d7b25d8    drm_i2c_encoder_destroy vmlinux EXPORT_SYMBOL
++0xd25d4f74    console_blank_hook      vmlinux EXPORT_SYMBOL
++0x968b41f8    nfc_hci_unregister_device       vmlinux EXPORT_SYMBOL
++0x71917221    xt_request_find_target  vmlinux EXPORT_SYMBOL_GPL
++0x14ccc8d6    sg_scsi_ioctl   vmlinux EXPORT_SYMBOL_GPL
++0xc22a3091    vm_unmap_aliases        vmlinux EXPORT_SYMBOL_GPL
++0x936d3888    dm_kill_unmapped_request        vmlinux EXPORT_SYMBOL_GPL
++0x56f3f495    vb2_querybuf    vmlinux EXPORT_SYMBOL
++0xcd773fe8    gnet_stats_finish_copy  vmlinux EXPORT_SYMBOL
++0x75ffa405    blk_fetch_request       vmlinux EXPORT_SYMBOL
++0xc51700fb    free_inode_nonrcu       vmlinux EXPORT_SYMBOL
++0x87471cdc    dma_pool_create vmlinux EXPORT_SYMBOL
++0x4b34fbf5    block_all_signals       vmlinux EXPORT_SYMBOL
++0x1910bed7    v4l2_m2m_next_buf       vmlinux EXPORT_SYMBOL_GPL
++0xda6389c8    scsi_get_device_flags_keyed     vmlinux EXPORT_SYMBOL
++0x384fda7f    device_show_int vmlinux EXPORT_SYMBOL_GPL
++0x853ce11c    uart_handle_cts_change  vmlinux EXPORT_SYMBOL_GPL
++0x2167989c    uart_handle_dcd_change  vmlinux EXPORT_SYMBOL_GPL
++0x832c7303    cfg80211_chandef_compatible     vmlinux EXPORT_SYMBOL
++0xb5aa7165    dma_pool_destroy        vmlinux EXPORT_SYMBOL
++0x3a81993a    irq_create_strict_mappings      vmlinux EXPORT_SYMBOL_GPL
++0xf7951d2a    sdio_writeb     vmlinux EXPORT_SYMBOL_GPL
++0x73286449    gether_set_gadget       vmlinux EXPORT_SYMBOL
++0x0958f0a1    gether_disconnect       vmlinux EXPORT_SYMBOL
++0xc7141639    tty_name        vmlinux EXPORT_SYMBOL
++0x52e54a99    udp6_csum_init  vmlinux EXPORT_SYMBOL
++0x20c95ebb    __dev_remove_offload    vmlinux EXPORT_SYMBOL
++0xff6104d0    snd_pcm_rate_bit_to_rate        vmlinux EXPORT_SYMBOL
++0xcfa8d57b    sysfs_get_dirent        vmlinux EXPORT_SYMBOL_GPL
++0x8e0d66f4    __tracepoint_kmalloc    vmlinux EXPORT_SYMBOL
++0x3bfcc1f8    perf_event_release_kernel       vmlinux EXPORT_SYMBOL_GPL
++0x8c03d20c    destroy_workqueue       vmlinux EXPORT_SYMBOL_GPL
++0x7e36685b    of_dev_put      vmlinux EXPORT_SYMBOL
++0x379d3e07    of_dev_get      vmlinux EXPORT_SYMBOL
++0xf494f618    mmc_regulator_get_ocrmask       vmlinux EXPORT_SYMBOL_GPL
++0xd9fb5e67    power_supply_register   vmlinux EXPORT_SYMBOL_GPL
++0x3697b3a2    usb_assign_descriptors  vmlinux EXPORT_SYMBOL_GPL
++0x6789d290    serial8250_register_8250_port   vmlinux EXPORT_SYMBOL
++0xa34d0cc4    inet6_csk_reqsk_queue_hash_add  vmlinux EXPORT_SYMBOL_GPL
++0x81de8eb2    inet_twsk_put   vmlinux EXPORT_SYMBOL_GPL
++0x687019ad    fib_default_rule_add    vmlinux EXPORT_SYMBOL
++0x8eef430a    fat_get_dotdot_entry    vmlinux EXPORT_SYMBOL_GPL
++0x2a3f1eb3    check_disk_change       vmlinux EXPORT_SYMBOL
++0xd5325933    default_file_splice_read        vmlinux EXPORT_SYMBOL
++0xd83215e5    writeback_inodes_sb     vmlinux EXPORT_SYMBOL
++0x506cc085    tracepoint_iter_stop    vmlinux EXPORT_SYMBOL_GPL
++0xe200d2d5    param_get_uint  vmlinux EXPORT_SYMBOL
++0x79cb0ce1    pm_generic_runtime_suspend      vmlinux EXPORT_SYMBOL_GPL
++0x364477d8    do_SAK  vmlinux EXPORT_SYMBOL
++0x8d9c96ee    elv_register    vmlinux EXPORT_SYMBOL_GPL
++0x0c77c871    page_put_link   vmlinux EXPORT_SYMBOL
++0x8f03ba03    release_pages   vmlinux EXPORT_SYMBOL
++0xa4a39c18    v4l2_m2m_streamon       vmlinux EXPORT_SYMBOL_GPL
++0xa2d6eedc    bt_sock_stream_recvmsg  vmlinux EXPORT_SYMBOL
++0xb1bed25d    dpm_resume_start        vmlinux EXPORT_SYMBOL_GPL
++0x10291853    devm_regulator_put      vmlinux EXPORT_SYMBOL_GPL
++0xcf618a57    cfg80211_calculate_bitrate      vmlinux EXPORT_SYMBOL
++0xa9f48f53    km_state_expired        vmlinux EXPORT_SYMBOL
++0x6417850b    qdisc_list_del  vmlinux EXPORT_SYMBOL
++0xb0e10781    get_option      vmlinux EXPORT_SYMBOL
++0x6a3d6744    drm_property_create     vmlinux EXPORT_SYMBOL
++0x60352082    register_inet6addr_notifier     vmlinux EXPORT_SYMBOL
++0x7cabb84d    inet_accept     vmlinux EXPORT_SYMBOL
++0x49b07aec    tcp_select_initial_window       vmlinux EXPORT_SYMBOL
++0xd41766d2    nf_ct_gre_keymap_destroy        vmlinux EXPORT_SYMBOL_GPL
++0x0b225b92    register_pernet_device  vmlinux EXPORT_SYMBOL_GPL
++0xe697d108    __blk_iopoll_complete   vmlinux EXPORT_SYMBOL
++0xa1c76e0a    _cond_resched   vmlinux EXPORT_SYMBOL
++0x22e1ae6f    up_read vmlinux EXPORT_SYMBOL
++0x9fbe4605    class_for_each_device   vmlinux EXPORT_SYMBOL_GPL
++0x4c1e4dba    unbind_con_driver       vmlinux EXPORT_SYMBOL
++0x352cbaad    empty_zero_page vmlinux EXPORT_SYMBOL
++0x66f6b51b    nfnetlink_subsys_register       vmlinux EXPORT_SYMBOL_GPL
++0x2de03b66    ndo_dflt_bridge_getlink vmlinux EXPORT_SYMBOL
++0x1f404818    __pskb_pull_tail        vmlinux EXPORT_SYMBOL
++0x848618a1    snd_pcm_lib_free_vmalloc_buffer vmlinux EXPORT_SYMBOL
++0x11575bf3    bioset_free     vmlinux EXPORT_SYMBOL
++0x2acf0feb    vfs_fstat       vmlinux EXPORT_SYMBOL
++0x0c45fc96    vfs_lstat       vmlinux EXPORT_SYMBOL
++0x20bc3470    orderly_poweroff        vmlinux EXPORT_SYMBOL_GPL
++0xd0c74120    cpufreq_frequency_table_verify  vmlinux EXPORT_SYMBOL_GPL
++0x93af794b    dev_alert       vmlinux EXPORT_SYMBOL
++0x96cd86f2    tty_wait_until_sent     vmlinux EXPORT_SYMBOL
++0x4384f1be    gether_setup_name       vmlinux EXPORT_SYMBOL
++0xa598e29c    vesa_modes      vmlinux EXPORT_SYMBOL
++0x4ead0283    pn_skb_send     vmlinux EXPORT_SYMBOL
++0xc01a92eb    __netif_schedule        vmlinux EXPORT_SYMBOL
++0xd42d86c0    generic_fh_to_parent    vmlinux EXPORT_SYMBOL_GPL
++0x9eaba82f    generic_fillattr        vmlinux EXPORT_SYMBOL
++0x183fa88b    mempool_alloc_slab      vmlinux EXPORT_SYMBOL
++0x5d0b1892    param_set_invbool       vmlinux EXPORT_SYMBOL
++0xe103ee04    gpio_export_link        vmlinux EXPORT_SYMBOL_GPL
++0x24bfaf10    d_instantiate_unique    vmlinux EXPORT_SYMBOL
++0xd6b8e852    request_threaded_irq    vmlinux EXPORT_SYMBOL
++0x18bd76a4    _raw_spin_trylock       vmlinux EXPORT_SYMBOL
++0xc2ffd5d5    iio_trigger_alloc       vmlinux EXPORT_SYMBOL
++0xa749c072    i2c_register_driver     vmlinux EXPORT_SYMBOL
++0x6ea05e17    of_phy_provider_unregister      vmlinux EXPORT_SYMBOL_GPL
++0xc359fb65    abort   vmlinux EXPORT_SYMBOL
++0x9f0f5d05    cfg80211_send_unprot_disassoc   vmlinux EXPORT_SYMBOL
++0xc575c737    debug_locks_off vmlinux EXPORT_SYMBOL_GPL
++0xab2f97aa    jbd2_journal_forget     vmlinux EXPORT_SYMBOL
++0xffea14aa    mutex_lock_interruptible        vmlinux EXPORT_SYMBOL
++0xdb9cfd07    skb_clone       vmlinux EXPORT_SYMBOL
++0x0cdd5fd1    crypto_find_alg vmlinux EXPORT_SYMBOL_GPL
++0x076aff85    set_task_ioprio vmlinux EXPORT_SYMBOL_GPL
++0x773522a8    setup_arg_pages vmlinux EXPORT_SYMBOL
++0x430348ff    input_get_keycode       vmlinux EXPORT_SYMBOL
++0x3c50bfc9    regmap_can_raw_write    vmlinux EXPORT_SYMBOL_GPL
++0x8209afe6    wakeup_source_destroy   vmlinux EXPORT_SYMBOL_GPL
++0x0487f831    fb_find_best_display    vmlinux EXPORT_SYMBOL
++0x83dab696    inode_dio_wait  vmlinux EXPORT_SYMBOL
++0xa3a19433    of_get_regulator_init_data      vmlinux EXPORT_SYMBOL_GPL
++0x43ca0eb7    amba_request_regions    vmlinux EXPORT_SYMBOL
++0xc34efe27    snmp_fold_field vmlinux EXPORT_SYMBOL_GPL
++0x3e48e980    tcp_init_xmit_timers    vmlinux EXPORT_SYMBOL
++0x267c8e5b    snd_soc_register_card   vmlinux EXPORT_SYMBOL_GPL
++0x2d13dc4b    jbd2_journal_start      vmlinux EXPORT_SYMBOL
++0xd67364f7    eventfd_ctx_fdget       vmlinux EXPORT_SYMBOL_GPL
++0xaefaecb4    phy_ethtool_gset        vmlinux EXPORT_SYMBOL
++0x86dded2c    phy_ethtool_sset        vmlinux EXPORT_SYMBOL
++0x1b15cf75    drm_encoder_init        vmlinux EXPORT_SYMBOL
++0x540ef2af    vfs_lock_file   vmlinux EXPORT_SYMBOL_GPL
++0x56fcacd4    bio_uncopy_user vmlinux EXPORT_SYMBOL
++0x9401ec10    make_bad_inode  vmlinux EXPORT_SYMBOL
++0x8ec007a4    __d_drop        vmlinux EXPORT_SYMBOL
++0x7f39e9f3    __mmdrop        vmlinux EXPORT_SYMBOL_GPL
++0x731e1d9d    thermal_zone_device_unregister  vmlinux EXPORT_SYMBOL_GPL
++0x31528994    __i2c_transfer  vmlinux EXPORT_SYMBOL
++0x33dbfd93    tcp_memory_allocated    vmlinux EXPORT_SYMBOL
++0xa8232c78    strtobool       vmlinux EXPORT_SYMBOL
++0xbe744811    jbd2_journal_force_commit_nested        vmlinux EXPORT_SYMBOL
++0xce03751f    seq_release_private     vmlinux EXPORT_SYMBOL
++0xd788742d    perf_trace_buf_prepare  vmlinux EXPORT_SYMBOL_GPL
++0x269f017e    st_sensors_set_dataready_irq    vmlinux EXPORT_SYMBOL
++0x379ea057    hid_check_keys_pressed  vmlinux EXPORT_SYMBOL_GPL
++0xe19a7489    scsi_bus_type   vmlinux EXPORT_SYMBOL_GPL
++0x11f13f3f    snd_ctl_remove  vmlinux EXPORT_SYMBOL
++0xb7a5a52f    writeback_inodes_sb_nr  vmlinux EXPORT_SYMBOL
++0x8efefdc1    vfs_removexattr vmlinux EXPORT_SYMBOL_GPL
++0xbd7c9ac7    find_symbol     vmlinux EXPORT_SYMBOL_GPL
++0xc6ca6078    __mutex_init    vmlinux EXPORT_SYMBOL
++0xe8349cd8    uart_console_write      vmlinux EXPORT_SYMBOL_GPL
++0x2e5810c6    __aeabi_unwind_cpp_pr1  vmlinux EXPORT_SYMBOL
++0x80f711c7    jbd2_journal_check_used_features        vmlinux EXPORT_SYMBOL
++0xcd91b127    system_highpri_wq       vmlinux EXPORT_SYMBOL_GPL
++0x5d2137b0    sdio_readsb     vmlinux EXPORT_SYMBOL_GPL
++0x6883e0d5    rtc_set_time    vmlinux EXPORT_SYMBOL_GPL
++0xf753d6ff    drm_i2c_encoder_mode_set        vmlinux EXPORT_SYMBOL
++0x0b0d888b    icmpv6_err_convert      vmlinux EXPORT_SYMBOL
++0x908cb3fc    vfs_readv       vmlinux EXPORT_SYMBOL
++0x3e467689    do_sync_write   vmlinux EXPORT_SYMBOL
++0xe01edb1a    vb2_plane_vaddr vmlinux EXPORT_SYMBOL_GPL
++0xff9c7899    fb_get_mode     vmlinux EXPORT_SYMBOL
++0x63923641    crypto_shash_setkey     vmlinux EXPORT_SYMBOL_GPL
++0x66c159c0    crypto_ahash_setkey     vmlinux EXPORT_SYMBOL_GPL
++0xb2c17922    search_binary_handler   vmlinux EXPORT_SYMBOL
++0x07438699    rt_mutex_trylock        vmlinux EXPORT_SYMBOL_GPL
++0x559b763f    mmc_detect_change       vmlinux EXPORT_SYMBOL
++0xed2c3cec    drm_debugfs_remove_files        vmlinux EXPORT_SYMBOL
++0xea5c6ccb    rtnl_link_get_net       vmlinux EXPORT_SYMBOL
++0x420c7411    ahash_attr_alg  vmlinux EXPORT_SYMBOL_GPL
++0xc690866c    irq_work_queue  vmlinux EXPORT_SYMBOL_GPL
++0x22640142    sdio_readw      vmlinux EXPORT_SYMBOL_GPL
++0x246e1a87    sdio_readl      vmlinux EXPORT_SYMBOL_GPL
++0xafb35b17    sdio_readb      vmlinux EXPORT_SYMBOL_GPL
++0x713125bd    cpufreq_freq_attr_scaling_available_freqs       vmlinux EXPORT_SYMBOL_GPL
++0xd7095481    usb_remove_phy  vmlinux EXPORT_SYMBOL_GPL
++0x76d878f8    usb_remove_hcd  vmlinux EXPORT_SYMBOL_GPL
++0x7e543e70    device_store_bool       vmlinux EXPORT_SYMBOL_GPL
++0x407136b1    __put_user_8    vmlinux EXPORT_SYMBOL
++0x1567020f    tcp_disconnect  vmlinux EXPORT_SYMBOL
++0x1f615e38    bio_pair_release        vmlinux EXPORT_SYMBOL
++0x2469810f    __rcu_read_unlock       vmlinux EXPORT_SYMBOL_GPL
++0xea51d53a    extcon_get_extcon_dev   vmlinux EXPORT_SYMBOL_GPL
++0x52c47236    put_device      vmlinux EXPORT_SYMBOL_GPL
++0x194eadaa    drm_edid_header_is_valid        vmlinux EXPORT_SYMBOL
++0x7d89e34a    drm_gtf_mode_complex    vmlinux EXPORT_SYMBOL
++0x75c2b9f1    memalloc_socks  vmlinux EXPORT_SYMBOL_GPL
++0xb10dfa5a    register_filesystem     vmlinux EXPORT_SYMBOL
++0x758a782e    blk_fill_rwbs   vmlinux EXPORT_SYMBOL_GPL
++0xba497f13    loops_per_jiffy vmlinux EXPORT_SYMBOL
++0xc657abdc    v4l2_ctrl_subscribe_event       vmlinux EXPORT_SYMBOL
++0xc7472c0b    devm_input_allocate_device      vmlinux EXPORT_SYMBOL
++0xdb2c2fbf    spi_alloc_device        vmlinux EXPORT_SYMBOL_GPL
++0xa33be4ce    inet_confirm_addr       vmlinux EXPORT_SYMBOL
++0x48eb98d1    eth_validate_addr       vmlinux EXPORT_SYMBOL
++0xc5718627    sg_copy_to_buffer       vmlinux EXPORT_SYMBOL
++0x7ab88a45    system_freezing_cnt     vmlinux EXPORT_SYMBOL
++0x7d0db45c    jiffies_to_clock_t      vmlinux EXPORT_SYMBOL
++0x2c208607    power_supply_is_system_supplied vmlinux EXPORT_SYMBOL_GPL
++0xc9422c05    devm_usb_get_phy_dev    vmlinux EXPORT_SYMBOL_GPL
++0xba3a6941    drm_getsarea    vmlinux EXPORT_SYMBOL
++0x1ffe8e3f    nfc_register_device     vmlinux EXPORT_SYMBOL
++0x0478373c    generic_make_request    vmlinux EXPORT_SYMBOL
++0x0b9a91be    generic_file_llseek_size        vmlinux EXPORT_SYMBOL
++0x1c87a811    __round_jiffies_up      vmlinux EXPORT_SYMBOL_GPL
++0x93d6ad2c    usb_debug_root  vmlinux EXPORT_SYMBOL_GPL
++0xd3ce47fe    drm_mode_crtc_set_gamma_size    vmlinux EXPORT_SYMBOL
++0xbe16ad70    drm_addbufs_pci vmlinux EXPORT_SYMBOL
++0xd5dae19f    regulator_get_exclusive vmlinux EXPORT_SYMBOL_GPL
++0x02124474    ip_send_check   vmlinux EXPORT_SYMBOL
++0x628cbfaa    rtmsg_ifinfo    vmlinux EXPORT_SYMBOL
++0xb0d3bca5    __rtnl_register vmlinux EXPORT_SYMBOL_GPL
++0x23b9d6e2    mangle_path     vmlinux EXPORT_SYMBOL
++0xe7c52663    v4l2_m2m_create_bufs    vmlinux EXPORT_SYMBOL_GPL
++0x63625aaa    usb_composite_setup_continue    vmlinux EXPORT_SYMBOL_GPL
++0x41f53df0    anon_inode_getfd        vmlinux EXPORT_SYMBOL_GPL
++0x24d5ba21    filemap_flush   vmlinux EXPORT_SYMBOL
++0xb49f6bea    iio_enum_write  vmlinux EXPORT_SYMBOL_GPL
++0x1bfbfeeb    mc1n2_set_mclk_source   vmlinux EXPORT_SYMBOL
++0x95e6e500    blk_stack_limits        vmlinux EXPORT_SYMBOL
++0xeb46c362    fuse_conn_init  vmlinux EXPORT_SYMBOL_GPL
++0x0e9003db    pm_generic_freeze_late  vmlinux EXPORT_SYMBOL_GPL
++0xf2fa6c7e    drm_gem_vm_close        vmlinux EXPORT_SYMBOL
++0x5bbc0a12    __fib_lookup    vmlinux EXPORT_SYMBOL_GPL
++0x1dd6e42b    tcp_set_state   vmlinux EXPORT_SYMBOL_GPL
++0xa77d88f6    strnlen_user    vmlinux EXPORT_SYMBOL
++0x191ef206    i2c_smbus_read_i2c_block_data   vmlinux EXPORT_SYMBOL
++0x52b992dc    drm_kms_helper_poll_disable     vmlinux EXPORT_SYMBOL
++0x6fc997a4    tty_mutex       vmlinux EXPORT_SYMBOL
++0x3973c5f8    kunmap  vmlinux EXPORT_SYMBOL
++0xb28f5ef1    xt_free_table_info      vmlinux EXPORT_SYMBOL
++0x1d0b568b    mnt_pin vmlinux EXPORT_SYMBOL
++0x50ba53b9    set_create_files_as     vmlinux EXPORT_SYMBOL
++0xcbd3dbd0    serial8250_modem_status vmlinux EXPORT_SYMBOL_GPL
++0xe38dd51c    dev_get_by_name vmlinux EXPORT_SYMBOL
++0x69458fd5    snd_dma_alloc_pages_fallback    vmlinux EXPORT_SYMBOL
++0xb3fda4b7    __page_symlink  vmlinux EXPORT_SYMBOL
++0x400fb79c    install_exec_creds      vmlinux EXPORT_SYMBOL
++0xbed3ae54    sched_setscheduler      vmlinux EXPORT_SYMBOL_GPL
++0xeb923e09    power_supply_set_battery_charged        vmlinux EXPORT_SYMBOL_GPL
++0xfdab6de3    unregister_sound_midi   vmlinux EXPORT_SYMBOL
++0x30a80826    __kfifo_from_user       vmlinux EXPORT_SYMBOL
++0x6923ce63    irq_work_sync   vmlinux EXPORT_SYMBOL_GPL
++0xe7197773    drm_ht_insert_item      vmlinux EXPORT_SYMBOL
++0xdf75f3c9    ipcomp_input    vmlinux EXPORT_SYMBOL_GPL
++0xac966a6d    udp_prot        vmlinux EXPORT_SYMBOL
++0xc6531cd4    inet_putpeer    vmlinux EXPORT_SYMBOL_GPL
++0xe2b955e2    nat_h245_hook   vmlinux EXPORT_SYMBOL_GPL
++0xf34732f2    netif_set_xps_queue     vmlinux EXPORT_SYMBOL
++0x7681d145    snd_ctl_register_ioctl  vmlinux EXPORT_SYMBOL
++0xaae48971    mmc_card_sleep  vmlinux EXPORT_SYMBOL
++0x58fe6474    v4l2_m2m_ioctl_qbuf     vmlinux EXPORT_SYMBOL_GPL
++0x00d1d0d0    i2c_adapter_type        vmlinux EXPORT_SYMBOL_GPL
++0xb971ebca    rndis_get_next_response vmlinux EXPORT_SYMBOL
++0xc88b565d    inet6_sk_rebuild_header vmlinux EXPORT_SYMBOL_GPL
++0x83a4c277    mb_cache_shrink vmlinux EXPORT_SYMBOL
++0xf1e98c74    avenrun vmlinux EXPORT_SYMBOL
++0x1318fa1c    __ww_mutex_lock_interruptible   vmlinux EXPORT_SYMBOL
++0x2d3385d3    system_wq       vmlinux EXPORT_SYMBOL
++0x94e4e64e    v4l2_event_queue        vmlinux EXPORT_SYMBOL_GPL
++0x76fd0937    device_init_wakeup      vmlinux EXPORT_SYMBOL_GPL
++0x40a6f522    __arm_ioremap   vmlinux EXPORT_SYMBOL
++0xc2165d85    __arm_iounmap   vmlinux EXPORT_SYMBOL
++0xaf50e76d    elf_set_personality     vmlinux EXPORT_SYMBOL
++0xd9f8f32d    nf_ct_extend_register   vmlinux EXPORT_SYMBOL_GPL
++0x6ceb8cf4    mark_page_accessed      vmlinux EXPORT_SYMBOL
++0x17f36c02    mmc_calc_max_discard    vmlinux EXPORT_SYMBOL
++0x0d45c48f    v4l2_clk_register       vmlinux EXPORT_SYMBOL
++0x123959a1    v4l2_type_names vmlinux EXPORT_SYMBOL
++0x02a18c74    nf_conntrack_destroy    vmlinux EXPORT_SYMBOL
++0x679f4b6b    scsi_report_bus_reset   vmlinux EXPORT_SYMBOL
++0xf8224b12    mali_get_user_setting   vmlinux EXPORT_SYMBOL
++0x3c93ad98    tty_port_install        vmlinux EXPORT_SYMBOL_GPL
++0x63fb81e4    brcmu_pktq_penq drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x723a1683    brcmu_pktq_pdeq drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0xfa595453    ip6_sk_dst_lookup_flow  vmlinux EXPORT_SYMBOL_GPL
++0xa76f7e50    snd_dma_get_reserved_buf        vmlinux EXPORT_SYMBOL
++0x61ed1c8e    cdev_add        vmlinux EXPORT_SYMBOL
++0x69447467    ring_buffer_write       vmlinux EXPORT_SYMBOL_GPL
++0xfcd7bc0b    ring_buffer_empty       vmlinux EXPORT_SYMBOL_GPL
++0x82939ebd    rcu_batches_completed_sched     vmlinux EXPORT_SYMBOL_GPL
++0x9e44b9b7    of_get_next_available_child     vmlinux EXPORT_SYMBOL
++0x1010f1ee    hid_output_report       vmlinux EXPORT_SYMBOL_GPL
++0x59e5070d    __do_div64      vmlinux EXPORT_SYMBOL
++0xa2d91fcc    xfrm_input      vmlinux EXPORT_SYMBOL
++0x07a62853    dev_mc_add      vmlinux EXPORT_SYMBOL
++0x40908b29    dev_mc_del      vmlinux EXPORT_SYMBOL
++0x2eed048e    dev_uc_add      vmlinux EXPORT_SYMBOL
++0x69dba7f4    dev_uc_del      vmlinux EXPORT_SYMBOL
++0x15361516    register_pernet_subsys  vmlinux EXPORT_SYMBOL_GPL
++0x915be34a    snd_timer_new   vmlinux EXPORT_SYMBOL
++0x3c45a56f    blk_queue_update_dma_pad        vmlinux EXPORT_SYMBOL
++0x069d40a0    blkdev_get_by_path      vmlinux EXPORT_SYMBOL
++0xa440bdfe    open_exec       vmlinux EXPORT_SYMBOL
++0x374682ce    rtc_update_irq  vmlinux EXPORT_SYMBOL_GPL
++0xba2d0719    drm_mode_hsync  vmlinux EXPORT_SYMBOL
++0x2d7a787f    drm_dp_clock_recovery_ok        vmlinux EXPORT_SYMBOL
++0xd59b2bb0    fb_blank        vmlinux EXPORT_SYMBOL
++0x0b48677a    __kfifo_init    vmlinux EXPORT_SYMBOL
++0x249c96e2    mb_cache_entry_find_next        vmlinux EXPORT_SYMBOL
++0xaee2539e    inode_init_owner        vmlinux EXPORT_SYMBOL
++0x7b24ccb3    file_ns_capable vmlinux EXPORT_SYMBOL
++0x37c0412f    cpu_subsys      vmlinux EXPORT_SYMBOL_GPL
++0x9993bf08    rt_mutex_destroy        vmlinux EXPORT_SYMBOL_GPL
++0xd4034828    system_freezable_wq     vmlinux EXPORT_SYMBOL_GPL
++0x9963a089    queue_delayed_work_on   vmlinux EXPORT_SYMBOL
++0x1284891b    iio_trigger_notify_done vmlinux EXPORT_SYMBOL
++0x03212586    v4l2_m2m_streamoff      vmlinux EXPORT_SYMBOL_GPL
++0x5b19634d    div_s64_rem     vmlinux EXPORT_SYMBOL
++0xb110bb66    __set_page_dirty_nobuffers      vmlinux EXPORT_SYMBOL
++0xd7d79132    put_online_cpus vmlinux EXPORT_SYMBOL_GPL
++0x121e3c12    devres_open_group       vmlinux EXPORT_SYMBOL_GPL
++0x8eae4744    __nf_ct_kill_acct       vmlinux EXPORT_SYMBOL_GPL
++0xcf88625f    mempool_create_node     vmlinux EXPORT_SYMBOL
++0x222fa684    lg_global_lock  vmlinux EXPORT_SYMBOL
++0x7cb2eca1    find_get_pid    vmlinux EXPORT_SYMBOL_GPL
++0x971ad8d8    usbnet_unlink_rx_urbs   vmlinux EXPORT_SYMBOL_GPL
++0xa551b417    devm_pwm_get    vmlinux EXPORT_SYMBOL_GPL
++0xb138607d    dev_set_promiscuity     vmlinux EXPORT_SYMBOL
++0xc8ca31af    timed_output_dev_register       vmlinux EXPORT_SYMBOL_GPL
++0x2967cbf7    dm_get_rq_mapinfo       vmlinux EXPORT_SYMBOL_GPL
++0x07013243    scsi_bios_ptable        vmlinux EXPORT_SYMBOL
++0x9780e683    pm_generic_resume       vmlinux EXPORT_SYMBOL_GPL
++0x3074f033    drm_order       vmlinux EXPORT_SYMBOL
++0xa87f4ece    neigh_connected_output  vmlinux EXPORT_SYMBOL
++0xe9f7149c    zlib_deflate_workspacesize      vmlinux EXPORT_SYMBOL
++0x2d03c10d    posix_acl_create        vmlinux EXPORT_SYMBOL
++0xbe254e92    param_set_ushort        vmlinux EXPORT_SYMBOL
++0xf0ca36cf    drm_prime_init_file_private     vmlinux EXPORT_SYMBOL
++0xb001e18c    drm_plane_init  vmlinux EXPORT_SYMBOL
++0xb2922319    bt_sock_recvmsg vmlinux EXPORT_SYMBOL
++0xe7f38f6d    udp_flush_pending_frames        vmlinux EXPORT_SYMBOL
++0xf0726368    dev_get_stats   vmlinux EXPORT_SYMBOL
++0xd3f7e5cc    snd_soc_default_volatile_register       vmlinux EXPORT_SYMBOL_GPL
++0x92c5fcb5    snd_timer_notify        vmlinux EXPORT_SYMBOL
++0x86fb9b05    bitmap_parse_user       vmlinux EXPORT_SYMBOL
++0x01000e51    schedule        vmlinux EXPORT_SYMBOL
++0xbd597aa3    usb_add_function        vmlinux EXPORT_SYMBOL_GPL
++0x460e4737    pm_generic_poweroff     vmlinux EXPORT_SYMBOL_GPL
++0x6920e885    nlmsg_notify    vmlinux EXPORT_SYMBOL
++0x247a1d7a    ww_mutex_unlock vmlinux EXPORT_SYMBOL
++0x1498f6af    mmput   vmlinux EXPORT_SYMBOL_GPL
++0x709eb78b    init_task       vmlinux EXPORT_SYMBOL
++0x3052a0ee    watchdog_unregister_device      vmlinux EXPORT_SYMBOL_GPL
++0x80eaa56e    drm_i2c_encoder_save    vmlinux EXPORT_SYMBOL
++0xe540813f    drm_property_create_enum        vmlinux EXPORT_SYMBOL
++0x6c642207    drm_get_connector_name  vmlinux EXPORT_SYMBOL
++0x42151efa    balloon_devinfo_alloc   vmlinux EXPORT_SYMBOL_GPL
++0xfa544711    video_devdata   vmlinux EXPORT_SYMBOL
++0x8e9618cd    wakeup_source_create    vmlinux EXPORT_SYMBOL_GPL
++0x72f12e79    drm_probe_ddc   vmlinux EXPORT_SYMBOL
++0x89d66811    build_ehash_secret      vmlinux EXPORT_SYMBOL
++0xf4329926    __inet_twsk_hashdance   vmlinux EXPORT_SYMBOL_GPL
++0xd0e13603    gnet_stats_copy_app     vmlinux EXPORT_SYMBOL
++0x1b015d25    bitmap_parselist        vmlinux EXPORT_SYMBOL
++0xf91bf3db    __insert_inode_hash     vmlinux EXPORT_SYMBOL
++0x308b733a    getboottime     vmlinux EXPORT_SYMBOL_GPL
++0x69f04aa3    revert_creds    vmlinux EXPORT_SYMBOL
++0xdf929370    fs_overflowgid  vmlinux EXPORT_SYMBOL
++0xa1177bf1    i2c_verify_client       vmlinux EXPORT_SYMBOL
++0x0e5358d0    input_allocate_device   vmlinux EXPORT_SYMBOL
++0x4fed4ee0    pm_runtime_barrier      vmlinux EXPORT_SYMBOL_GPL
++0xb939d297    dev_printk      vmlinux EXPORT_SYMBOL
++0x090849e3    phy_power_on    vmlinux EXPORT_SYMBOL_GPL
++0x47416e14    cpu_rmap_add    vmlinux EXPORT_SYMBOL
++0x08fbaf94    xfrm_policy_walk        vmlinux EXPORT_SYMBOL
++0x774846b4    nf_log_unset    vmlinux EXPORT_SYMBOL
++0x00aaf0d4    wm_hubs_add_analogue_routes     vmlinux EXPORT_SYMBOL_GPL
++0xe9d7e477    snd_card_proc_new       vmlinux EXPORT_SYMBOL
++0x97de2b83    debug_locks_silent      vmlinux EXPORT_SYMBOL_GPL
++0x3e452a00    blocking_notifier_call_chain    vmlinux EXPORT_SYMBOL_GPL
++0xae83dc8c    spi_bitbang_setup_transfer      vmlinux EXPORT_SYMBOL_GPL
++0x8d871961    cpu_tlb vmlinux EXPORT_SYMBOL
++0xfe694f5b    regmap_read     vmlinux EXPORT_SYMBOL_GPL
++0x594bf15b    ioport_map      vmlinux EXPORT_SYMBOL
++0x2d3abae7    __skb_checksum_complete vmlinux EXPORT_SYMBOL
++0xb5a459dc    unregister_blkdev       vmlinux EXPORT_SYMBOL
++0xd0a8eac3    write_inode_now vmlinux EXPORT_SYMBOL
++0x7d3a11d4    tty_lock        vmlinux EXPORT_SYMBOL
++0xa6dea12e    regulator_register      vmlinux EXPORT_SYMBOL_GPL
++0x0ce021b8    ieee80211_amsdu_to_8023s        vmlinux EXPORT_SYMBOL
++0xe0088286    fat_search_long vmlinux EXPORT_SYMBOL_GPL
++0x08ca5b31    seq_path        vmlinux EXPORT_SYMBOL
++0xcc5005fe    msleep_interruptible    vmlinux EXPORT_SYMBOL
++0x2f0d9053    usb_otg_state_string    vmlinux EXPORT_SYMBOL_GPL
++0xf2997713    tty_termios_hw_change   vmlinux EXPORT_SYMBOL
++0x53893194    dev_addr_add    vmlinux EXPORT_SYMBOL
++0x0dd3fd84    netdev_err      vmlinux EXPORT_SYMBOL
++0x62849ac7    dev_valid_name  vmlinux EXPORT_SYMBOL
++0x193466be    kfree_skb_partial       vmlinux EXPORT_SYMBOL
++0xd2a941d4    sg_init_table   vmlinux EXPORT_SYMBOL
++0x5642793a    radix_tree_tag_clear    vmlinux EXPORT_SYMBOL
++0xc3bb6d9e    blk_pre_runtime_resume  vmlinux EXPORT_SYMBOL
++0xd3a7747d    fsnotify        vmlinux EXPORT_SYMBOL_GPL
++0x4f3b569c    generic_file_open       vmlinux EXPORT_SYMBOL
++0xc87c1f84    ktime_get       vmlinux EXPORT_SYMBOL_GPL
++0x89bbafc6    usb_register_notify     vmlinux EXPORT_SYMBOL_GPL
++0x19ac480a    cfg80211_new_sta        vmlinux EXPORT_SYMBOL
++0xd18ba458    generic_cont_expand_simple      vmlinux EXPORT_SYMBOL
++0x5cf6467f    d_instantiate   vmlinux EXPORT_SYMBOL
++0xd1ef6f16    genphy_update_link      vmlinux EXPORT_SYMBOL
++0x4a77677a    nfc_hci_recv_frame      vmlinux EXPORT_SYMBOL
++0xc2a19d85    register_sound_special_device   vmlinux EXPORT_SYMBOL
++0x5b3060c4    blk_queue_rq_timed_out  vmlinux EXPORT_SYMBOL_GPL
++0x2cbfd99b    vb2_queue_init  vmlinux EXPORT_SYMBOL_GPL
++0x955d725c    drm_mm_scan_remove_block        vmlinux EXPORT_SYMBOL
++0x6d346792    pin_config_group_get    vmlinux EXPORT_SYMBOL
++0xf82a1863    pin_config_group_set    vmlinux EXPORT_SYMBOL
++0x08c473b7    xt_alloc_table_info     vmlinux EXPORT_SYMBOL
++0xb7b61546    crc32_be        vmlinux EXPORT_SYMBOL
++0x26520970    vm_memory_committed     vmlinux EXPORT_SYMBOL_GPL
++0xcf283b4f    iommu_domain_alloc      vmlinux EXPORT_SYMBOL_GPL
++0x52ffd07f    xfrm_output_resume      vmlinux EXPORT_SYMBOL_GPL
++0x4c21e163    skb_find_text   vmlinux EXPORT_SYMBOL
++0x5279b639    current_fs_time vmlinux EXPORT_SYMBOL
++0x04cc0a21    i2c_unregister_device   vmlinux EXPORT_SYMBOL_GPL
++0x13fc56de    drm_helper_crtc_in_use  vmlinux EXPORT_SYMBOL
++0x6d399587    regulator_unregister    vmlinux EXPORT_SYMBOL_GPL
++0x6b037ba6    nf_nat_l4proto_unregister       vmlinux EXPORT_SYMBOL_GPL
++0x8231a8bd    nf_nat_l3proto_unregister       vmlinux EXPORT_SYMBOL_GPL
++0x6350314b    tcf_hash_create vmlinux EXPORT_SYMBOL
++0xf339287c    skb_queue_tail  vmlinux EXPORT_SYMBOL
++0x5409775b    free_irq_cpu_rmap       vmlinux EXPORT_SYMBOL
++0x65771426    crypto_lookup_template  vmlinux EXPORT_SYMBOL_GPL
++0xd61347c6    register_sysctl vmlinux EXPORT_SYMBOL
++0xd8c37e37    vfs_test_lock   vmlinux EXPORT_SYMBOL_GPL
++0x952664c5    do_exit vmlinux EXPORT_SYMBOL_GPL
++0xcb07e4af    tcf_hash_destroy        vmlinux EXPORT_SYMBOL
++0x78953de6    mark_buffer_dirty_inode vmlinux EXPORT_SYMBOL
++0x3109b751    cpu_clock       vmlinux EXPORT_SYMBOL_GPL
++0xdf842e2b    drm_vblank_cleanup      vmlinux EXPORT_SYMBOL
++0x57810201    ip_tunnel_lookup        vmlinux EXPORT_SYMBOL_GPL
++0xb1c3a01a    oops_in_progress        vmlinux EXPORT_SYMBOL
++0x0fca29c0    dev_pm_qos_remove_request       vmlinux EXPORT_SYMBOL_GPL
++0xc407a137    dma_wait_for_async_tx   vmlinux EXPORT_SYMBOL_GPL
++0x046a9d1b    backlight_device_register       vmlinux EXPORT_SYMBOL
++0x2a36b31a    nf_ct_helper_log        vmlinux EXPORT_SYMBOL_GPL
++0xb442919d    blk_get_backing_dev_info        vmlinux EXPORT_SYMBOL
++0x0ed2f3b5    elevator_init   vmlinux EXPORT_SYMBOL
++0x21bda10a    kill_fasync     vmlinux EXPORT_SYMBOL
++0x622dacba    tick_nohz_idle_enter    vmlinux EXPORT_SYMBOL_GPL
++0xdd4a5569    param_get_byte  vmlinux EXPORT_SYMBOL
++0x764d38f1    tty_insert_flip_string_fixed_flag       vmlinux EXPORT_SYMBOL
++0xcf5bc354    tty_register_ldisc      vmlinux EXPORT_SYMBOL
++0x88f68355    tty_throttle    vmlinux EXPORT_SYMBOL
++0x335e720e    tty_check_change        vmlinux EXPORT_SYMBOL
++0x1d5568cb    dev_disable_lro vmlinux EXPORT_SYMBOL
++0xb2be6e92    netdev_stats_to_stats64 vmlinux EXPORT_SYMBOL
++0x728261ca    kblockd_schedule_delayed_work   vmlinux EXPORT_SYMBOL
++0x5c959646    debugfs_create_u8       vmlinux EXPORT_SYMBOL_GPL
++0x0c150d31    cgroup_taskset_first    vmlinux EXPORT_SYMBOL_GPL
++0xec690544    attribute_container_classdev_to_container       vmlinux EXPORT_SYMBOL_GPL
++0xda1613df    drm_put_dev     vmlinux EXPORT_SYMBOL
++0x157667da    drm_gem_vm_open vmlinux EXPORT_SYMBOL
++0x8ad8d79e    drm_fb_helper_setcmap   vmlinux EXPORT_SYMBOL
++0x5550f136    snd_soc_dapm_info_pin_switch    vmlinux EXPORT_SYMBOL_GPL
++0xcb08eeba    drm_core_ioremap        vmlinux EXPORT_SYMBOL
++0x6aba167a    regulator_list_voltage  vmlinux EXPORT_SYMBOL_GPL
++0x1b0ac272    __tracepoint_kmalloc_node       vmlinux EXPORT_SYMBOL
++0xd62c833f    schedule_timeout        vmlinux EXPORT_SYMBOL
++0x432fd7f6    __gpio_set_value        vmlinux EXPORT_SYMBOL_GPL
++0x6c8d5ae8    __gpio_get_value        vmlinux EXPORT_SYMBOL_GPL
++0x65ccb6f0    call_netevent_notifiers vmlinux EXPORT_SYMBOL_GPL
++0x4a7fb243    percpu_counter_compare  vmlinux EXPORT_SYMBOL
++0xced58760    crypto_alloc_base       vmlinux EXPORT_SYMBOL_GPL
++0xfcf2f8c0    aio_put_req     vmlinux EXPORT_SYMBOL
++0x6f3a36eb    dw_mci_pltfm_pmops      vmlinux EXPORT_SYMBOL_GPL
++0xe6c3ebb0    __raw_writesw   vmlinux EXPORT_SYMBOL
++0x51908eb8    __raw_writesl   vmlinux EXPORT_SYMBOL
++0x75fee7fd    __raw_writesb   vmlinux EXPORT_SYMBOL
++0xef35b0c3    cfg80211_report_wowlan_wakeup   vmlinux EXPORT_SYMBOL
++0x99591a7a    ipv6_ext_hdr    vmlinux EXPORT_SYMBOL
++0x65396d44    neigh_destroy   vmlinux EXPORT_SYMBOL
++0x405b485b    netdev_warn     vmlinux EXPORT_SYMBOL
++0xf45f8934    blk_end_request_cur     vmlinux EXPORT_SYMBOL
++0x9a682368    replace_mount_options   vmlinux EXPORT_SYMBOL
++0x5a7c0586    hid_validate_values     vmlinux EXPORT_SYMBOL_GPL
++0x88618588    mmc_wait_for_app_cmd    vmlinux EXPORT_SYMBOL
++0xccbbfe3b    v4l2_fh_del     vmlinux EXPORT_SYMBOL_GPL
++0xcefcd99a    serial8250_unregister_port      vmlinux EXPORT_SYMBOL
++0x0bed6399    __xfrm_policy_check     vmlinux EXPORT_SYMBOL
++0xf1947b5c    snd_ctl_rename_id       vmlinux EXPORT_SYMBOL
++0xb9220639    blk_lld_busy    vmlinux EXPORT_SYMBOL_GPL
++0x4178eee3    blk_sync_queue  vmlinux EXPORT_SYMBOL
++0x32b0e045    usbnet_get_link vmlinux EXPORT_SYMBOL_GPL
++0xd578f42c    fat_alloc_new_dir       vmlinux EXPORT_SYMBOL_GPL
++0x0eacb23a    simple_write_end        vmlinux EXPORT_SYMBOL
++0xcbee20b2    get_cpu_iowait_time_us  vmlinux EXPORT_SYMBOL_GPL
++0xea01bd2a    st_sensors_init_sensor  vmlinux EXPORT_SYMBOL
++0xb7433944    hid_open_report vmlinux EXPORT_SYMBOL_GPL
++0x2d339a62    scsi_schedule_eh        vmlinux EXPORT_SYMBOL_GPL
++0xc6544448    pm_runtime_irq_safe     vmlinux EXPORT_SYMBOL_GPL
++0xa5afacf6    class_unregister        vmlinux EXPORT_SYMBOL_GPL
++0xedf69cd6    drm_gem_private_object_init     vmlinux EXPORT_SYMBOL
++0x999c3148    __raw_readsb    vmlinux EXPORT_SYMBOL
++0xfb268a5f    ip_mc_rejoin_groups     vmlinux EXPORT_SYMBOL
++0xafe4c25e    netdev_update_features  vmlinux EXPORT_SYMBOL
++0xd75c79df    smp_call_function       vmlinux EXPORT_SYMBOL
++0xef6c3f70    round_jiffies_up_relative       vmlinux EXPORT_SYMBOL_GPL
++0x64420947    spi_async       vmlinux EXPORT_SYMBOL_GPL
++0xe62c2cf6    regmap_raw_write_async  vmlinux EXPORT_SYMBOL_GPL
++0x226a057d    eth_header_cache        vmlinux EXPORT_SYMBOL
++0xb9d025c9    llist_del_first vmlinux EXPORT_SYMBOL_GPL
++0xb678366f    int_sqrt        vmlinux EXPORT_SYMBOL
++0x9d28f747    dec_zone_page_state     vmlinux EXPORT_SYMBOL
++0x0799aca4    local_bh_enable vmlinux EXPORT_SYMBOL
++0x8d07023c    i2c_smbus_read_byte_data        vmlinux EXPORT_SYMBOL
++0xca5dbc50    scsi_print_sense_hdr    vmlinux EXPORT_SYMBOL
++0x3da076a8    scsi_host_lookup        vmlinux EXPORT_SYMBOL
++0xf54ff64f    uart_set_options        vmlinux EXPORT_SYMBOL_GPL
++0x47ff399f    regulator_is_supported_voltage  vmlinux EXPORT_SYMBOL_GPL
++0x585469ee    of_get_videomode        vmlinux EXPORT_SYMBOL_GPL
++0x852786a9    phy_get vmlinux EXPORT_SYMBOL_GPL
++0xaf8aa518    system_rev      vmlinux EXPORT_SYMBOL
++0x6c3d2a02    tcp_syn_flood_action    vmlinux EXPORT_SYMBOL
++0xf38bcdf3    nf_conntrack_max        vmlinux EXPORT_SYMBOL_GPL
++0x44de5177    snd_pcm_suspend vmlinux EXPORT_SYMBOL
++0xb23ef570    blk_bio_map_sg  vmlinux EXPORT_SYMBOL
++0x4c5e7289    config_item_get vmlinux EXPORT_SYMBOL
++0xea12473b    config_item_put vmlinux EXPORT_SYMBOL
++0xbe68ef11    mnt_drop_write_file     vmlinux EXPORT_SYMBOL
++0x381144a9    __tracepoint_module_get vmlinux EXPORT_SYMBOL
++0xc5fdef94    call_usermodehelper     vmlinux EXPORT_SYMBOL
++0x1eb9516e    round_jiffies_relative  vmlinux EXPORT_SYMBOL_GPL
++0x7cc035a7    __ucmpdi2       vmlinux EXPORT_SYMBOL
++0xe42e1f70    klist_iter_init_node    vmlinux EXPORT_SYMBOL_GPL
++0x5c440c21    hci_conn_check_secure   vmlinux EXPORT_SYMBOL
++0x5b34d4b0    snd_soc_codec_readable_register vmlinux EXPORT_SYMBOL_GPL
++0x0634100a    bitmap_parselist_user   vmlinux EXPORT_SYMBOL
++0x5b72009f    ida_simple_get  vmlinux EXPORT_SYMBOL
++0x11a6ce4b    blk_queue_update_dma_alignment  vmlinux EXPORT_SYMBOL
++0x3e0dd939    blk_start_request       vmlinux EXPORT_SYMBOL
++0x51749fc8    _raw_read_lock_irq      vmlinux EXPORT_SYMBOL
++0x757bbc48    hrtimer_try_to_cancel   vmlinux EXPORT_SYMBOL_GPL
++0x70899e95    v4l2_m2m_buf_remove     vmlinux EXPORT_SYMBOL_GPL
++0x5f96a661    v4l2_ctrl_check vmlinux EXPORT_SYMBOL
++0x42bf1c34    video_unregister_device vmlinux EXPORT_SYMBOL
++0xcd914413    drm_get_minor   vmlinux EXPORT_SYMBOL
++0xa0e5202d    nf_register_hook        vmlinux EXPORT_SYMBOL
++0x86d5e343    __dev_get_by_name       vmlinux EXPORT_SYMBOL
++0x2cc749f6    skb_copy_and_csum_dev   vmlinux EXPORT_SYMBOL
++0x9613509a    idr_replace     vmlinux EXPORT_SYMBOL
++0x82acfb70    blk_iopoll_sched        vmlinux EXPORT_SYMBOL
++0x2c7db649    irq_dispose_mapping     vmlinux EXPORT_SYMBOL_GPL
++0x530b1e98    pm_suspend      vmlinux EXPORT_SYMBOL
++0xae69b1c1    usermodehelper_read_unlock      vmlinux EXPORT_SYMBOL_GPL
++0x39f4b0d2    s3c_adc_release vmlinux EXPORT_SYMBOL_GPL
++0xc2f16e25    input_unregister_handle vmlinux EXPORT_SYMBOL
++0x67326732    usb_hcd_map_urb_for_dma vmlinux EXPORT_SYMBOL_GPL
++0xd125790d    drm_hdmi_avi_infoframe_from_display_mode        vmlinux EXPORT_SYMBOL
++0xe10a472d    drm_mm_pre_get  vmlinux EXPORT_SYMBOL
++0xf082ddf3    register_netdev vmlinux EXPORT_SYMBOL
++0x935b5da0    snd_timer_continue      vmlinux EXPORT_SYMBOL
++0xcc37f55c    blk_limits_io_opt       vmlinux EXPORT_SYMBOL
++0xd4c5def3    inet_twsk_purge vmlinux EXPORT_SYMBOL_GPL
++0x9e9f1714    __bitmap_andnot vmlinux EXPORT_SYMBOL
++0x737de5e9    radix_tree_tag_get      vmlinux EXPORT_SYMBOL
++0xed1e0a03    posix_acl_from_xattr    vmlinux EXPORT_SYMBOL
++0x5256cd6e    clear_nlink     vmlinux EXPORT_SYMBOL
++0xc9f0ae5d    nf_xfrm_me_harder       vmlinux EXPORT_SYMBOL
++0x4751c2af    dev_loopback_xmit       vmlinux EXPORT_SYMBOL
++0x74bd982c    skb_seq_read    vmlinux EXPORT_SYMBOL
++0x798c5110    snd_soc_platform_trigger        vmlinux EXPORT_SYMBOL_GPL
++0x5362ae46    config_item_init        vmlinux EXPORT_SYMBOL
++0x83c8a355    param_set_int   vmlinux EXPORT_SYMBOL
++0x8099b954    i2c_transfer    vmlinux EXPORT_SYMBOL
++0x61e262f1    scsi_device_lookup      vmlinux EXPORT_SYMBOL
++0xfbb86a51    drm_i2c_encoder_prepare vmlinux EXPORT_SYMBOL
++0x4090c0fe    snd_card_file_add       vmlinux EXPORT_SYMBOL
++0x559879f5    crypto_drop_spawn       vmlinux EXPORT_SYMBOL_GPL
++0x27c2197f    param_set_short vmlinux EXPORT_SYMBOL
++0xcc4c1be7    nf_nat_tftp_hook        vmlinux EXPORT_SYMBOL_GPL
++0xc9a3b093    get_h225_addr   vmlinux EXPORT_SYMBOL_GPL
++0x59e9d996    skb_pad vmlinux EXPORT_SYMBOL
++0x77bc13a0    strim   vmlinux EXPORT_SYMBOL
++0x4c2a94b4    shash_register_instance vmlinux EXPORT_SYMBOL_GPL
++0x33c77d65    seq_write       vmlinux EXPORT_SYMBOL
++0x44aec3a4    generic_file_llseek     vmlinux EXPORT_SYMBOL
++0x12d60b5f    v4l2_ctrl_handler_free  vmlinux EXPORT_SYMBOL
++0x19f0c50a    ip6_tnl_parse_tlv_enc_lim       vmlinux EXPORT_SYMBOL
++0x1cea8d0a    snd_soc_dapm_new_widgets        vmlinux EXPORT_SYMBOL_GPL
++0xe1f4606d    snd_info_create_module_entry    vmlinux EXPORT_SYMBOL
++0x999e8297    vfree   vmlinux EXPORT_SYMBOL
++0x841575f5    wait_on_page_bit        vmlinux EXPORT_SYMBOL
++0x51205d4b    mutex_lock      vmlinux EXPORT_SYMBOL
++0xe97c74fd    rtc_update_irq_enable   vmlinux EXPORT_SYMBOL_GPL
++0x849722db    dma_request_slave_channel       vmlinux EXPORT_SYMBOL_GPL
++0x120b336a    __rb_insert_augmented   vmlinux EXPORT_SYMBOL
++0x6359b128    elv_rq_merge_ok vmlinux EXPORT_SYMBOL
++0xee3496c3    dma_pool_alloc  vmlinux EXPORT_SYMBOL
++0xa835f402    mmc_detect_card_removed vmlinux EXPORT_SYMBOL
++0xbe1b0b72    scsi_get_host_dev       vmlinux EXPORT_SYMBOL
++0xaf4e166f    dma_async_memcpy_pg_to_pg       vmlinux EXPORT_SYMBOL
++0xe34d76a6    l2cap_is_socket vmlinux EXPORT_SYMBOL
++0xd875e3e2    ip6_route_lookup        vmlinux EXPORT_SYMBOL_GPL
++0xd58c5fcb    tcp_v4_do_rcv   vmlinux EXPORT_SYMBOL
++0x3413b5de    blk_dump_rq_flags       vmlinux EXPORT_SYMBOL
++0xc8449f3c    sysfs_create_group      vmlinux EXPORT_SYMBOL_GPL
++0xf3e42ab4    get_device      vmlinux EXPORT_SYMBOL_GPL
++0xf147dcb2    hdmi_spd_infoframe_init vmlinux EXPORT_SYMBOL
++0x1776281f    xfrm_unregister_mode    vmlinux EXPORT_SYMBOL
++0x4737cc63    consume_skb     vmlinux EXPORT_SYMBOL
++0x72081296    extcon_find_cable_index vmlinux EXPORT_SYMBOL_GPL
++0x641d5fb6    usbnet_status_start     vmlinux EXPORT_SYMBOL_GPL
++0x8f2c5edc    scsi_add_device vmlinux EXPORT_SYMBOL
++0x8652db9f    __pm_stay_awake vmlinux EXPORT_SYMBOL_GPL
++0xb9d3a88c    tcf_action_dump_1       vmlinux EXPORT_SYMBOL
++0xb6f19e98    snd_pcm_lib_get_vmalloc_page    vmlinux EXPORT_SYMBOL
++0x29e5e6f3    poll_schedule_timeout   vmlinux EXPORT_SYMBOL
++0x99f58330    lg_local_lock_cpu       vmlinux EXPORT_SYMBOL
++0x58862e69    v4l2_m2m_ioctl_streamon vmlinux EXPORT_SYMBOL_GPL
++0xa340fae0    i2c_add_numbered_adapter        vmlinux EXPORT_SYMBOL_GPL
++0x806c2801    usb_unanchor_urb        vmlinux EXPORT_SYMBOL_GPL
++0x485b3745    dma_get_slave_channel   vmlinux EXPORT_SYMBOL_GPL
++0x1d0a43c3    phy_power_off   vmlinux EXPORT_SYMBOL_GPL
++0x0fd14a9d    tcp_prot        vmlinux EXPORT_SYMBOL
++0x4bfdc9e2    textsearch_prepare      vmlinux EXPORT_SYMBOL
++0x988958ef    fuse_direct_io  vmlinux EXPORT_SYMBOL_GPL
++0x996c4d30    proc_dointvec_ms_jiffies        vmlinux EXPORT_SYMBOL
++0x785d494b    rndis_msg_parser        vmlinux EXPORT_SYMBOL
++0xcea853d2    root_device_unregister  vmlinux EXPORT_SYMBOL_GPL
++0xf13f5821    inet_frag_kill  vmlinux EXPORT_SYMBOL
++0x8f4f1272    simple_setattr  vmlinux EXPORT_SYMBOL
++0x9c0dba49    simple_getattr  vmlinux EXPORT_SYMBOL
++0x2232a8a5    mempool_free    vmlinux EXPORT_SYMBOL
++0xc72ca946    v4l2_fh_release vmlinux EXPORT_SYMBOL_GPL
++0x2a0afd5e    videomode_from_timing   vmlinux EXPORT_SYMBOL_GPL
++0xaf157b0c    nfc_dep_link_is_up      vmlinux EXPORT_SYMBOL
++0x20efc937    tcf_em_tree_validate    vmlinux EXPORT_SYMBOL
++0xd05683cc    cred_to_ucred   vmlinux EXPORT_SYMBOL_GPL
++0xa1ac0050    sock_tx_timestamp       vmlinux EXPORT_SYMBOL
++0x48bd992d    bdget_disk      vmlinux EXPORT_SYMBOL
++0x50985501    configfs_register_subsystem     vmlinux EXPORT_SYMBOL
++0x041a8568    attribute_container_unregister  vmlinux EXPORT_SYMBOL_GPL
++0x3de4b634    driver_for_each_device  vmlinux EXPORT_SYMBOL_GPL
++0xc1984867    drm_vblank_put  vmlinux EXPORT_SYMBOL
++0xc8c20253    tcp_rcv_state_process   vmlinux EXPORT_SYMBOL
++0x280525ed    skb_to_sgvec    vmlinux EXPORT_SYMBOL_GPL
++0x20c55ae0    sscanf  vmlinux EXPORT_SYMBOL
++0xe3dd61a6    __breadahead    vmlinux EXPORT_SYMBOL
++0x1b42a36f    vb2_dma_contig_init_ctx vmlinux EXPORT_SYMBOL_GPL
++0xc326f752    v4l2_g_ctrl     vmlinux EXPORT_SYMBOL
++0x3adca4e5    pfifo_fast_ops  vmlinux EXPORT_SYMBOL
++0x67677183    snd_pcm_hw_constraint_integer   vmlinux EXPORT_SYMBOL
++0x1fab5905    wait_for_completion     vmlinux EXPORT_SYMBOL
++0x0b972255    led_classdev_suspend    vmlinux EXPORT_SYMBOL_GPL
++0xd617281d    wm8994_set_bits vmlinux EXPORT_SYMBOL_GPL
++0x4ad196c8    wm8994_reg_read vmlinux EXPORT_SYMBOL_GPL
++0xb3f0ca49    platform_device_register_full   vmlinux EXPORT_SYMBOL_GPL
++0x13bfa97e    devm_gpio_free  vmlinux EXPORT_SYMBOL
++0xe5646321    dev_get_by_name_rcu     vmlinux EXPORT_SYMBOL
++0x8fed35b2    snd_soc_dpcm_can_be_free_stop   vmlinux EXPORT_SYMBOL_GPL
++0x30a4f4ca    bstr_printf     vmlinux EXPORT_SYMBOL_GPL
++0x72350130    ___ratelimit    vmlinux EXPORT_SYMBOL
++0x0e5d4fe1    i2c_smbus_write_byte_data       vmlinux EXPORT_SYMBOL
++0xe7d93ea1    usb_unlink_urb  vmlinux EXPORT_SYMBOL_GPL
++0xaf141636    __nf_nat_mangle_tcp_packet      vmlinux EXPORT_SYMBOL
++0x584e1dcb    wm_hubs_add_analogue_controls   vmlinux EXPORT_SYMBOL_GPL
++0x15e14e37    snd_dma_alloc_pages     vmlinux EXPORT_SYMBOL
++0x3a26ed11    sched_clock     vmlinux EXPORT_SYMBOL_GPL
++0x6f5d8c04    iio_device_unregister   vmlinux EXPORT_SYMBOL
++0x9e672ff6    scsi_kmap_atomic_sg     vmlinux EXPORT_SYMBOL
++0xe8d95e86    platform_device_add_data        vmlinux EXPORT_SYMBOL_GPL
++0x1fcece42    inet_twdr_twcal_tick    vmlinux EXPORT_SYMBOL_GPL
++0xd1f0ea5e    sk_unattached_filter_destroy    vmlinux EXPORT_SYMBOL_GPL
++0xdb647fcf    sock_create_lite        vmlinux EXPORT_SYMBOL
++0x82b125fb    mmc_hw_reset_check      vmlinux EXPORT_SYMBOL
++0x45db3821    drm_gem_create_mmap_offset      vmlinux EXPORT_SYMBOL
++0x4eca00d2    nfc_proto_register      vmlinux EXPORT_SYMBOL
++0x8b69cf06    d_obtain_alias  vmlinux EXPORT_SYMBOL
++0xc7462fc5    cpufreq_unregister_governor     vmlinux EXPORT_SYMBOL_GPL
++0xc7280d53    v4l2_g_ext_ctrls        vmlinux EXPORT_SYMBOL
++0xb3b58737    ip6_datagram_connect    vmlinux EXPORT_SYMBOL_GPL
++0x365bf841    ip4_datagram_connect    vmlinux EXPORT_SYMBOL
++0x4a8cb865    tcp_timewait_state_process      vmlinux EXPORT_SYMBOL
++0xa34e2838    nf_conntrack_helper_try_module_get      vmlinux EXPORT_SYMBOL_GPL
++0x26dcd9ac    security_inode_init_security    vmlinux EXPORT_SYMBOL
++0xd705b4c7    schedule_hrtimeout      vmlinux EXPORT_SYMBOL_GPL
++0x44643b93    __aeabi_lmul    vmlinux EXPORT_SYMBOL
++0x824efa53    nobh_writepage  vmlinux EXPORT_SYMBOL
++0x78eb3b6d    clear_page_dirty_for_io vmlinux EXPORT_SYMBOL
++0xad6bf99a    srcu_init_notifier_head vmlinux EXPORT_SYMBOL_GPL
++0x9a1fc4b4    jiffies_to_timeval      vmlinux EXPORT_SYMBOL
++0xf1823632    clk_disable     vmlinux EXPORT_SYMBOL_GPL
++0x69da85e3    v4l2_ctrl_poll  vmlinux EXPORT_SYMBOL
++0xdcd7d2a3    starget_for_each_device vmlinux EXPORT_SYMBOL
++0x4dd58b53    subsys_interface_register       vmlinux EXPORT_SYMBOL_GPL
++0xf3916987    global_cursor_default   vmlinux EXPORT_SYMBOL
++0x3d2b2b9f    tcp_reno_min_cwnd       vmlinux EXPORT_SYMBOL_GPL
++0xf3bd26cd    vfs_follow_link vmlinux EXPORT_SYMBOL
++0xc11bd00f    tracepoint_probe_unregister     vmlinux EXPORT_SYMBOL_GPL
++0xb5532b8b    spi_bitbang_stop        vmlinux EXPORT_SYMBOL_GPL
++0x4deb10c3    tty_schedule_flip       vmlinux EXPORT_SYMBOL
++0x2dc227f8    brcmu_d11_attach        drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0xc009330d    sysfs_rename_link       vmlinux EXPORT_SYMBOL_GPL
++0xce0b9b59    max77693_read_reg       vmlinux EXPORT_SYMBOL_GPL
++0xc0c44856    tty_devnum      vmlinux EXPORT_SYMBOL
++0x4f391d0e    nla_parse       vmlinux EXPORT_SYMBOL
++0xc39a1e2a    write_dirty_buffer      vmlinux EXPORT_SYMBOL
++0xc8a154f9    noop_llseek     vmlinux EXPORT_SYMBOL
++0xc65d3eed    ring_buffer_entries_cpu vmlinux EXPORT_SYMBOL_GPL
++0x16807034    iommu_group_for_each_dev        vmlinux EXPORT_SYMBOL_GPL
++0x76829e1b    nfc_proto_unregister    vmlinux EXPORT_SYMBOL
++0x21ac8b77    iommu_group_get_by_id   vmlinux EXPORT_SYMBOL_GPL
++0x60601d69    input_free_device       vmlinux EXPORT_SYMBOL
++0x3a03067b    regulator_notifier_call_chain   vmlinux EXPORT_SYMBOL_GPL
++0x3e9110fa    __hw_addr_unsync        vmlinux EXPORT_SYMBOL
++0x7d11c268    jiffies vmlinux EXPORT_SYMBOL
++0x3987712e    iio_read_channel_scale  vmlinux EXPORT_SYMBOL_GPL
++0x7deff673    dm_consume_args vmlinux EXPORT_SYMBOL
++0xc092d57b    i2c_verify_adapter      vmlinux EXPORT_SYMBOL
++0x2e7a4300    drm_rgb_quant_range_selectable  vmlinux EXPORT_SYMBOL
++0x594e1317    __modsi3        vmlinux EXPORT_SYMBOL
++0x211331fa    __divsi3        vmlinux EXPORT_SYMBOL
++0xa3482467    dev_queue_xmit  vmlinux EXPORT_SYMBOL
++0x13d0adf7    __kfifo_out     vmlinux EXPORT_SYMBOL
++0xe06141e9    security_sk_clone       vmlinux EXPORT_SYMBOL
++0x75d5b827    proc_mkdir      vmlinux EXPORT_SYMBOL
++0x6f6ac78c    dummy_irq_chip  vmlinux EXPORT_SYMBOL_GPL
++0x3efb35c9    get_online_cpus vmlinux EXPORT_SYMBOL_GPL
++0x5907773b    of_device_alloc vmlinux EXPORT_SYMBOL
++0x1c00411e    blk_rq_map_sg   vmlinux EXPORT_SYMBOL
++0x09cf1b46    proc_dointvec_jiffies   vmlinux EXPORT_SYMBOL
++0x5db2254a    devm_usb_get_phy_by_phandle     vmlinux EXPORT_SYMBOL_GPL
++0x85caf365    usb_hcd_start_port_resume       vmlinux EXPORT_SYMBOL_GPL
++0x0a469d23    mfd_clone_cell  vmlinux EXPORT_SYMBOL
++0x93e85c29    dmam_free_noncoherent   vmlinux EXPORT_SYMBOL
++0x241ab4c2    phy_destroy     vmlinux EXPORT_SYMBOL_GPL
++0x408b2c52    __napi_schedule vmlinux EXPORT_SYMBOL
++0xc911f7d5    dev_change_carrier      vmlinux EXPORT_SYMBOL
++0xbfaa31e1    sk_stream_wait_memory   vmlinux EXPORT_SYMBOL
++0x0d3cb182    kstrtos16_from_user     vmlinux EXPORT_SYMBOL
++0x9f2bdaac    __bitmap_or     vmlinux EXPORT_SYMBOL
++0xae729e59    security_req_classify_flow      vmlinux EXPORT_SYMBOL
++0x273cbba4    get_dcookie     vmlinux EXPORT_SYMBOL_GPL
++0x9b7510d1    trace_event_raw_init    vmlinux EXPORT_SYMBOL_GPL
++0xb24585bc    usb_set_interface       vmlinux EXPORT_SYMBOL_GPL
++0x08cbe96c    tty_unlock      vmlinux EXPORT_SYMBOL
++0x07e3f668    netlink_broadcast_filtered      vmlinux EXPORT_SYMBOL
++0x4761f17c    register_netevent_notifier      vmlinux EXPORT_SYMBOL_GPL
++0xc7ec6c27    strspn  vmlinux EXPORT_SYMBOL
++0x97255bdf    strlen  vmlinux EXPORT_SYMBOL
++0xcdb399d4    cgroup_rightmost_descendant     vmlinux EXPORT_SYMBOL_GPL
++0x4bc7787e    iio_trigger_register    vmlinux EXPORT_SYMBOL
++0x05d7e32a    pm_generic_runtime_idle vmlinux EXPORT_SYMBOL_GPL
++0xcb0b5e8e    of_display_timings_exist        vmlinux EXPORT_SYMBOL_GPL
++0xdb68bbad    rfkill_destroy  vmlinux EXPORT_SYMBOL
++0x2e6a04e3    hci_recv_frame  vmlinux EXPORT_SYMBOL
++0xedbaee5e    nla_strcmp      vmlinux EXPORT_SYMBOL
++0x26bb950b    __kfifo_from_user_r     vmlinux EXPORT_SYMBOL
++0xca2ff6df    crypto_ahash_type       vmlinux EXPORT_SYMBOL_GPL
++0x2c41c751    v4l2_m2m_ctx_release    vmlinux EXPORT_SYMBOL_GPL
++0x99213409    scsi_allocate_command   vmlinux EXPORT_SYMBOL
++0x6827603e    skb_trim        vmlinux EXPORT_SYMBOL
++0x5cca80cf    perf_tp_event   vmlinux EXPORT_SYMBOL_GPL
++0xa6961e25    vb2_common_vm_ops       vmlinux EXPORT_SYMBOL_GPL
++0x72856c9e    v4l2_m2m_ioctl_expbuf   vmlinux EXPORT_SYMBOL_GPL
++0xb8acff80    usb_enable_autosuspend  vmlinux EXPORT_SYMBOL_GPL
++0x403f9529    gpio_request_one        vmlinux EXPORT_SYMBOL_GPL
++0x06d549e6    pinctrl_free_gpio       vmlinux EXPORT_SYMBOL_GPL
++0x02ae8433    xfrm_policy_delete      vmlinux EXPORT_SYMBOL
++0x6e71c6be    inet_frags_init vmlinux EXPORT_SYMBOL
++0x4e3567f7    match_int       vmlinux EXPORT_SYMBOL
++0x054434d6    radix_tree_tag_set      vmlinux EXPORT_SYMBOL
++0x31f956eb    blk_queue_lld_busy      vmlinux EXPORT_SYMBOL_GPL
++0x26565c84    shash_free_instance     vmlinux EXPORT_SYMBOL_GPL
++0x38668bab    debugfs_create_x64      vmlinux EXPORT_SYMBOL_GPL
++0xbf1f9a9b    bdi_setup_and_register  vmlinux EXPORT_SYMBOL
++0xfc64abed    power_supply_changed    vmlinux EXPORT_SYMBOL_GPL
++0x19326753    rtc_irq_register        vmlinux EXPORT_SYMBOL_GPL
++0xaf3cc095    nfc_hci_free_device     vmlinux EXPORT_SYMBOL
++0x86f38980    skb_cow_data    vmlinux EXPORT_SYMBOL_GPL
++0xe0c0d2af    snd_pcm_kernel_ioctl    vmlinux EXPORT_SYMBOL
++0xdfb01a80    cpu_v7_dcache_clean_area        vmlinux EXPORT_SYMBOL
++0x1879fcbd    bridge_tunnel_header    vmlinux EXPORT_SYMBOL
++0x9a011a6b    l2cap_conn_put  vmlinux EXPORT_SYMBOL
++0x6b3ee85a    ip4_datagram_release_cb vmlinux EXPORT_SYMBOL_GPL
++0xdd07d415    snd_card_free_when_closed       vmlinux EXPORT_SYMBOL
++0x868acba5    get_options     vmlinux EXPORT_SYMBOL
++0xa2409544    setup_irq       vmlinux EXPORT_SYMBOL_GPL
++0x567b73f9    i2c_get_adapter vmlinux EXPORT_SYMBOL
++0x7a4e7297    drm_edid_block_valid    vmlinux EXPORT_SYMBOL
++0x2ec524ad    __kfifo_in_r    vmlinux EXPORT_SYMBOL
++0x66f9da32    bh_uptodate_or_lock     vmlinux EXPORT_SYMBOL
++0xf9ffcd69    input_unregister_handler        vmlinux EXPORT_SYMBOL
++0x51dce73b    xfrm_state_walk_init    vmlinux EXPORT_SYMBOL
++0x113554e9    __skb_dst_set_noref     vmlinux EXPORT_SYMBOL
++0x3c9d1211    string_get_size vmlinux EXPORT_SYMBOL
++0xe654362e    fat_fill_super  vmlinux EXPORT_SYMBOL_GPL
++0xea5a46e7    register_exec_domain    vmlinux EXPORT_SYMBOL
++0xaf473214    iio_channel_get_all     vmlinux EXPORT_SYMBOL_GPL
++0xf8a9d6b2    rtc_read_alarm  vmlinux EXPORT_SYMBOL_GPL
++0xa0c8e0ed    usbnet_set_settings     vmlinux EXPORT_SYMBOL_GPL
++0x170bb6a9    usbnet_get_settings     vmlinux EXPORT_SYMBOL_GPL
++0xe0701fe6    fl6_sock_lookup vmlinux EXPORT_SYMBOL_GPL
++0x9330cb9f    sg_alloc_table  vmlinux EXPORT_SYMBOL
++0x5873f4c0    handle_simple_irq       vmlinux EXPORT_SYMBOL_GPL
++0xf27977e2    async_synchronize_cookie_domain vmlinux EXPORT_SYMBOL_GPL
++0xcf732e49    call_usermodehelper_exec        vmlinux EXPORT_SYMBOL
++0xd789a39d    cpufreq_governor_dbs    vmlinux EXPORT_SYMBOL_GPL
++0x4ff0c84f    of_mdio_find_bus        vmlinux EXPORT_SYMBOL
++0xe7a664c4    nf_hooks        vmlinux EXPORT_SYMBOL
++0xd366806d    snd_info_free_entry     vmlinux EXPORT_SYMBOL
++0xbcac6160    pm_qos_remove_notifier  vmlinux EXPORT_SYMBOL_GPL
++0x698d1e98    v4l2_ctrl_handler_init_class    vmlinux EXPORT_SYMBOL
++0x79c0d5a3    drm_gem_prime_fd_to_handle      vmlinux EXPORT_SYMBOL
++0xff1e9dd8    seq_list_start  vmlinux EXPORT_SYMBOL
++0x01accd73    __clk_get_name  vmlinux EXPORT_SYMBOL_GPL
++0x3e92b3d3    power_supply_unregister vmlinux EXPORT_SYMBOL_GPL
++0x71590103    drm_release     vmlinux EXPORT_SYMBOL
++0x0b9e5852    xfrm_aead_get_byname    vmlinux EXPORT_SYMBOL_GPL
++0xb7b856bf    km_state_notify vmlinux EXPORT_SYMBOL
++0x3f5b1415    nf_ct_port_nlattr_to_tuple      vmlinux EXPORT_SYMBOL_GPL
++0x98b6628a    snd_pcm_set_ops vmlinux EXPORT_SYMBOL
++0x1ea06663    _raw_write_lock vmlinux EXPORT_SYMBOL
++0x44dd3d8d    completion_done vmlinux EXPORT_SYMBOL
++0xa1eabd87    drm_mode_list_concat    vmlinux EXPORT_SYMBOL
++0x581ed292    drm_mm_get_block_generic        vmlinux EXPORT_SYMBOL
++0xefa98e30    dma_run_dependencies    vmlinux EXPORT_SYMBOL_GPL
++0xe8bea3bc    qdisc_put_stab  vmlinux EXPORT_SYMBOL
++0x2247cba2    seq_printf      vmlinux EXPORT_SYMBOL
++0x7e646f56    media_entity_remove_links       vmlinux EXPORT_SYMBOL_GPL
++0xa0e05fb1    drm_connector_cleanup   vmlinux EXPORT_SYMBOL
++0xb1cf44df    fb_find_best_mode       vmlinux EXPORT_SYMBOL
++0x0b742fd7    simple_strtol   vmlinux EXPORT_SYMBOL
++0xd709e32c    ilookup5_nowait vmlinux EXPORT_SYMBOL
++0x25865b31    mmc_free_host   vmlinux EXPORT_SYMBOL
++0x054063e9    devres_release  vmlinux EXPORT_SYMBOL_GPL
++0xc9b2045b    drm_mode_validate_size  vmlinux EXPORT_SYMBOL
++0xac6855b0    gen_kill_estimator      vmlinux EXPORT_SYMBOL
++0xc32b07a0    blk_queue_alignment_offset      vmlinux EXPORT_SYMBOL
++0x630c9194    fuse_dev_operations     vmlinux EXPORT_SYMBOL_GPL
++0xa4824580    devm_add_action vmlinux EXPORT_SYMBOL_GPL
++0xd8fe5b35    drm_mm_init     vmlinux EXPORT_SYMBOL
++0x9b9b05b4    __bio_clone     vmlinux EXPORT_SYMBOL
++0x5fda0227    vfs_stat        vmlinux EXPORT_SYMBOL
++0xa0fbac79    wake_up_bit     vmlinux EXPORT_SYMBOL
++0x796fc5ce    scsi_get_sense_info_fld vmlinux EXPORT_SYMBOL
++0x699ffdcd    nf_conntrack_flush_report       vmlinux EXPORT_SYMBOL_GPL
++0x89e6edac    snd_pcm_lib_malloc_pages        vmlinux EXPORT_SYMBOL
++0x48034724    zlib_deflateReset       vmlinux EXPORT_SYMBOL
++0xcdca3691    nr_irqs vmlinux EXPORT_SYMBOL_GPL
++0xcff6b676    _raw_spin_trylock_bh    vmlinux EXPORT_SYMBOL
++0xca45efbc    drm_format_horz_chroma_subsampling      vmlinux EXPORT_SYMBOL
++0xb6f4cc92    tty_do_resize   vmlinux EXPORT_SYMBOL
++0x51e77c97    pfn_valid       vmlinux EXPORT_SYMBOL
++0xa2446605    jbd2_journal_set_triggers       vmlinux EXPORT_SYMBOL
++0xebbb44c8    f_setown        vmlinux EXPORT_SYMBOL
++0xdfef3371    v4l2_m2m_ioctl_streamoff        vmlinux EXPORT_SYMBOL_GPL
++0x56c8799d    scsi_kunmap_atomic_sg   vmlinux EXPORT_SYMBOL
++0xaae1593e    scsi_block_when_processing_errors       vmlinux EXPORT_SYMBOL
++0xe330bf1f    ip6_dst_hoplimit        vmlinux EXPORT_SYMBOL
++0xf8996ee4    arp_invalidate  vmlinux EXPORT_SYMBOL
++0x6d27ef64    __bitmap_empty  vmlinux EXPORT_SYMBOL
++0xbfa789ca    elv_unregister  vmlinux EXPORT_SYMBOL_GPL
++0x06ae2b19    mmc_can_sanitize        vmlinux EXPORT_SYMBOL
++0xdd3dc2ce    usb_clear_halt  vmlinux EXPORT_SYMBOL_GPL
++0xfe0b2aae    amba_device_unregister  vmlinux EXPORT_SYMBOL
++0xc3771b21    of_pwm_get      vmlinux EXPORT_SYMBOL_GPL
++0x21b7d56d    dev_mc_sync_multiple    vmlinux EXPORT_SYMBOL
++0x1dfc5292    dev_uc_sync_multiple    vmlinux EXPORT_SYMBOL
++0xde7da8e3    submit_bh       vmlinux EXPORT_SYMBOL
++0xc15d05d9    mnt_clone_write vmlinux EXPORT_SYMBOL_GPL
++0x25fa84a3    page_mkclean    vmlinux EXPORT_SYMBOL_GPL
++0x405c1144    get_seconds     vmlinux EXPORT_SYMBOL
++0xf0f1246c    kvasprintf      vmlinux EXPORT_SYMBOL
++0xa5526619    rb_insert_color vmlinux EXPORT_SYMBOL
++0x7bb12a75    v4l2_m2m_get_vq vmlinux EXPORT_SYMBOL
++0x5819c8aa    usb_anchor_empty        vmlinux EXPORT_SYMBOL_GPL
++0x4e3d273c    __xfrm_init_state       vmlinux EXPORT_SYMBOL
++0xa2a69edc    __module_text_address   vmlinux EXPORT_SYMBOL_GPL
++0x66d87d38    symbol_put_addr vmlinux EXPORT_SYMBOL_GPL
++0xe45cc839    hrtimer_start_range_ns  vmlinux EXPORT_SYMBOL_GPL
++0xd3e6f60d    cpu_possible_mask       vmlinux EXPORT_SYMBOL
++0x52451ffe    hid_dump_field  vmlinux EXPORT_SYMBOL_GPL
++0xbd5a9986    drm_helper_probe_single_connector_modes vmlinux EXPORT_SYMBOL
++0xb694ce34    tcf_hash_search vmlinux EXPORT_SYMBOL
++0xaaefb815    d_alloc vmlinux EXPORT_SYMBOL
++0xaca38c86    unuse_mm        vmlinux EXPORT_SYMBOL_GPL
++0x5de3d7af    __alloc_pages_nodemask  vmlinux EXPORT_SYMBOL
++0xe2142ad8    i2c_smbus_read_word_data        vmlinux EXPORT_SYMBOL
++0xbfe4cfe6    tty_buffer_request_room vmlinux EXPORT_SYMBOL_GPL
++0xa6089679    elv_abort_queue vmlinux EXPORT_SYMBOL
++0x918ad429    ring_buffer_lock_reserve        vmlinux EXPORT_SYMBOL_GPL
++0xdc461430    irq_set_affinity_hint   vmlinux EXPORT_SYMBOL_GPL
++0x37258879    iio_channel_release     vmlinux EXPORT_SYMBOL_GPL
++0x1a082d69    max77693_update_reg     vmlinux EXPORT_SYMBOL_GPL
++0x4b0bd573    wiphy_unregister        vmlinux EXPORT_SYMBOL
++0x575d8c47    inet_sk_rx_dst_set      vmlinux EXPORT_SYMBOL
++0x3c6f5a97    snd_soc_register_component      vmlinux EXPORT_SYMBOL_GPL
++0xb9e03943    blk_execute_rq_nowait   vmlinux EXPORT_SYMBOL_GPL
++0x15f571ec    blk_set_stacking_limits vmlinux EXPORT_SYMBOL
++0x721585fd    security_inode_mkdir    vmlinux EXPORT_SYMBOL_GPL
++0xbf16ef9a    clk_get_rate    vmlinux EXPORT_SYMBOL_GPL
++0x22b79dae    clk_set_rate    vmlinux EXPORT_SYMBOL_GPL
++0x0dbd0e20    of_property_read_u8_array       vmlinux EXPORT_SYMBOL_GPL
++0xe6fce6f2    v4l2_ctrl_merge vmlinux EXPORT_SYMBOL
++0x12f1d8d3    dev_err vmlinux EXPORT_SYMBOL
++0x1c3e0368    drm_gem_object_handle_free      vmlinux EXPORT_SYMBOL
++0xfda9ed46    udp_proc_register       vmlinux EXPORT_SYMBOL
++0xccf2974f    kernel_sendpage vmlinux EXPORT_SYMBOL
++0x4b77922a    delete_from_page_cache  vmlinux EXPORT_SYMBOL
++0x3f5b67d5    wait_for_completion_killable    vmlinux EXPORT_SYMBOL
++0xa62fb61a    usb_gstrings_attach     vmlinux EXPORT_SYMBOL_GPL
++0x5cabdced    dev_pm_qos_remove_global_notifier       vmlinux EXPORT_SYMBOL_GPL
++0x27b864a9    s5p_gpio_get_drvstr     vmlinux EXPORT_SYMBOL
++0xc828d2a3    s5p_gpio_set_drvstr     vmlinux EXPORT_SYMBOL
++0xd9cf81bd    cfg80211_send_assoc_timeout     vmlinux EXPORT_SYMBOL
++0x693c3961    nf_ct_helper_hash       vmlinux EXPORT_SYMBOL_GPL
++0x487ef8ba    snd_soc_dai_set_sysclk  vmlinux EXPORT_SYMBOL_GPL
++0x50c89f23    __alloc_percpu  vmlinux EXPORT_SYMBOL_GPL
++0x09469482    kfree_call_rcu  vmlinux EXPORT_SYMBOL_GPL
++0x177d5d5e    uart_insert_char        vmlinux EXPORT_SYMBOL_GPL
++0xb17c2f9b    clear_inode     vmlinux EXPORT_SYMBOL
++0x3b733a7c    led_trigger_unregister  vmlinux EXPORT_SYMBOL_GPL
++0x16000a3c    dm_device_name  vmlinux EXPORT_SYMBOL_GPL
++0x0465ca31    scsi_cmd_get_serial     vmlinux EXPORT_SYMBOL
++0x0f52944d    drm_helper_hpd_irq_event        vmlinux EXPORT_SYMBOL
++0x99517682    udp_encap_enable        vmlinux EXPORT_SYMBOL
++0x1e43dec1    neigh_parms_release     vmlinux EXPORT_SYMBOL
++0x572e85d4    blk_lookup_devt vmlinux EXPORT_SYMBOL
++0xf7bb06b2    crypto_grab_skcipher    vmlinux EXPORT_SYMBOL_GPL
++0xe953b21f    get_next_ino    vmlinux EXPORT_SYMBOL
++0xdb225b82    pm_vt_switch_required   vmlinux EXPORT_SYMBOL
++0xe1a4b69f    mmc_card_awake  vmlinux EXPORT_SYMBOL
++0x33234a30    usb_hcd_link_urb_to_ep  vmlinux EXPORT_SYMBOL_GPL
++0xb61a0dba    dmam_release_declared_memory    vmlinux EXPORT_SYMBOL
++0x6865b5f6    device_release_driver   vmlinux EXPORT_SYMBOL_GPL
++0x920accbd    ump_dd_secure_id_get    vmlinux EXPORT_SYMBOL
++0xffb94ef0    _test_and_change_bit    vmlinux EXPORT_SYMBOL
++0xb7a1ff6d    tcp_prequeue    vmlinux EXPORT_SYMBOL
++0xce3ca308    copy_from_user_toio     vmlinux EXPORT_SYMBOL
++0xd08137e8    vfs_setlease    vmlinux EXPORT_SYMBOL_GPL
++0x89eabc8c    from_kgid_munged        vmlinux EXPORT_SYMBOL
++0x40d04664    console_trylock vmlinux EXPORT_SYMBOL
++0x0955d1f2    iommu_attach_device     vmlinux EXPORT_SYMBOL_GPL
++0x9cf3e94a    dm_kcopyd_copy  vmlinux EXPORT_SYMBOL
++0x1cec399d    v4l2_m2m_ioctl_create_bufs      vmlinux EXPORT_SYMBOL_GPL
++0x8cae11ac    usb_alloc_streams       vmlinux EXPORT_SYMBOL_GPL
++0xd3299096    scsi_register_interface vmlinux EXPORT_SYMBOL
++0x885369a2    dma_common_get_sgtable  vmlinux EXPORT_SYMBOL
++0x2251d13d    blk_queue_dma_pad       vmlinux EXPORT_SYMBOL
++0x07cf9099    wait_for_completion_timeout     vmlinux EXPORT_SYMBOL
++0x0efcbb1b    set_current_groups      vmlinux EXPORT_SYMBOL
++0xea9b0ab7    v4l2_ctrl_add_handler   vmlinux EXPORT_SYMBOL
++0x79aaab2b    i2c_smbus_read_block_data       vmlinux EXPORT_SYMBOL
++0x964ff64a    usb_put_intf    vmlinux EXPORT_SYMBOL_GPL
++0x9f97bf25    xfrm6_input_addr        vmlinux EXPORT_SYMBOL
++0x81db6ebb    xz_dec_reset    vmlinux EXPORT_SYMBOL
++0x661601de    sprint_symbol   vmlinux EXPORT_SYMBOL_GPL
++0x1e59773c    st_gyro_common_remove   vmlinux EXPORT_SYMBOL
++0x921e453c    drm_get_platform_dev    vmlinux EXPORT_SYMBOL
++0x720b245e    update_region   vmlinux EXPORT_SYMBOL
++0x2bda5922    hci_get_route   vmlinux EXPORT_SYMBOL
++0xaa939a8b    tcf_em_unregister       vmlinux EXPORT_SYMBOL
++0x590cf866    scm_fp_dup      vmlinux EXPORT_SYMBOL
++0x2ce98559    kcrypto_wq      vmlinux EXPORT_SYMBOL_GPL
++0x5351af17    shrink_dcache_parent    vmlinux EXPORT_SYMBOL
++0x1ad83009    trace_seq_vprintf       vmlinux EXPORT_SYMBOL_GPL
++0x8fcafa61    led_stop_software_blink vmlinux EXPORT_SYMBOL_GPL
++0xd4a7943a    mmc_card_can_sleep      vmlinux EXPORT_SYMBOL
++0x52f378a8    devres_remove   vmlinux EXPORT_SYMBOL_GPL
++0x6288b8b9    serial8250_release_dma  vmlinux EXPORT_SYMBOL_GPL
++0x63556dea    tty_vhangup     vmlinux EXPORT_SYMBOL
++0x75c8a11c    inet_twdr_twkill_work   vmlinux EXPORT_SYMBOL_GPL
++0x609f1c7e    synchronize_net vmlinux EXPORT_SYMBOL
++0x6091797f    synchronize_rcu vmlinux EXPORT_SYMBOL_GPL
++0x42825ce2    rcu_scheduler_active    vmlinux EXPORT_SYMBOL_GPL
++0xe523ad75    synchronize_irq vmlinux EXPORT_SYMBOL
++0xb77b0159    v4l2_prio_init  vmlinux EXPORT_SYMBOL
++0x840dd143    rndis_deregister        vmlinux EXPORT_SYMBOL
++0x7464ea38    dev_pm_qos_add_global_notifier  vmlinux EXPORT_SYMBOL_GPL
++0xd325a885    bus_for_each_dev        vmlinux EXPORT_SYMBOL_GPL
++0x3ec3d061    bus_for_each_drv        vmlinux EXPORT_SYMBOL_GPL
++0xb2823478    pneigh_lookup   vmlinux EXPORT_SYMBOL
++0x7037aaf0    kern_path_create        vmlinux EXPORT_SYMBOL
++0x85061b76    _raw_write_lock_bh      vmlinux EXPORT_SYMBOL
++0xb90cbedf    v4l2_of_get_next_endpoint       vmlinux EXPORT_SYMBOL
++0x9d2ed0a8    snd_timer_close vmlinux EXPORT_SYMBOL
++0x1057d320    blk_queue_find_tag      vmlinux EXPORT_SYMBOL
++0x1e3a88fb    trace_seq_printf        vmlinux EXPORT_SYMBOL_GPL
++0x4bc62a81    audit_enabled   vmlinux EXPORT_SYMBOL_GPL
++0x39461d6a    in_egroup_p     vmlinux EXPORT_SYMBOL
++0xccefabad    drm_mode_create_scaling_mode_property   vmlinux EXPORT_SYMBOL
++0x43384bd9    drm_buffer_alloc        vmlinux EXPORT_SYMBOL
++0x184e6c85    radix_tree_gang_lookup_slot     vmlinux EXPORT_SYMBOL
++0xdf347b52    sec_reg_read    vmlinux EXPORT_SYMBOL_GPL
++0x409873e3    tty_termios_baud_rate   vmlinux EXPORT_SYMBOL
++0x07a890c8    fb_alloc_cmap   vmlinux EXPORT_SYMBOL
++0x7d04aaa6    nf_conntrack_broadcast_help     vmlinux EXPORT_SYMBOL_GPL
++0x5cdc7a62    skb_append_datato_frags vmlinux EXPORT_SYMBOL
++0x9e0c711d    vzalloc_node    vmlinux EXPORT_SYMBOL
++0x7f24de73    jiffies_to_usecs        vmlinux EXPORT_SYMBOL
++0x37befc70    jiffies_to_msecs        vmlinux EXPORT_SYMBOL
++0xe9807d5b    input_mt_sync_frame     vmlinux EXPORT_SYMBOL
++0x0c0c8520    release_firmware        vmlinux EXPORT_SYMBOL
++0x442aa46d    tcp_child_process       vmlinux EXPORT_SYMBOL
++0x67663177    sock_diag_put_filterinfo        vmlinux EXPORT_SYMBOL
++0xa250c838    param_get_charp vmlinux EXPORT_SYMBOL
++0xf0b613ad    __pm_runtime_suspend    vmlinux EXPORT_SYMBOL_GPL
++0x1a770ac3    drm_detect_hdmi_monitor vmlinux EXPORT_SYMBOL
++0x70d7e40d    prepare_binprm  vmlinux EXPORT_SYMBOL
++0x36d7b11a    of_find_matching_node_and_match vmlinux EXPORT_SYMBOL
++0x8e30ad82    mdiobus_write   vmlinux EXPORT_SYMBOL
++0xeb6173b8    tty_port_destroy        vmlinux EXPORT_SYMBOL
++0x6c0154da    tcp_v4_destroy_sock     vmlinux EXPORT_SYMBOL
++0x5afe3100    snd_soc_add_dai_controls        vmlinux EXPORT_SYMBOL_GPL
++0xdf2c2742    rb_last vmlinux EXPORT_SYMBOL
++0x7ab3ca18    eventfd_ctx_read        vmlinux EXPORT_SYMBOL_GPL
++0xeb32e3af    mount_bdev      vmlinux EXPORT_SYMBOL
++0xe6fbe430    can_do_mlock    vmlinux EXPORT_SYMBOL
++0x60a13e90    rcu_barrier     vmlinux EXPORT_SYMBOL_GPL
++0xdf60cc27    __print_symbol  vmlinux EXPORT_SYMBOL
++0xa2a2031e    ehci_setup      vmlinux EXPORT_SYMBOL_GPL
++0x686f8200    ndisc_mc_map    vmlinux EXPORT_SYMBOL
++0xab8647cf    nf_ct_helper_expectfn_find_by_symbol    vmlinux EXPORT_SYMBOL_GPL
++0x91715312    sprintf vmlinux EXPORT_SYMBOL
++0xda3d10a8    security_tun_dev_open   vmlinux EXPORT_SYMBOL
++0xa4a91e54    simple_unlink   vmlinux EXPORT_SYMBOL
++0xf377a0b5    simple_attr_write       vmlinux EXPORT_SYMBOL_GPL
++0x97263968    generic_listxattr       vmlinux EXPORT_SYMBOL
++0x53c9394f    v4l2_ctrl_query_menu    vmlinux EXPORT_SYMBOL
++0xf6ebc03b    net_ratelimit   vmlinux EXPORT_SYMBOL
++0x3977cbea    dev_addr_init   vmlinux EXPORT_SYMBOL
++0x2789cd4f    snd_soc_put_strobe      vmlinux EXPORT_SYMBOL_GPL
++0x719074ee    snd_soc_get_strobe      vmlinux EXPORT_SYMBOL_GPL
++0xdace599d    shash_ahash_update      vmlinux EXPORT_SYMBOL_GPL
++0x7add44b5    posix_acl_valid vmlinux EXPORT_SYMBOL
++0xe8fbe1c9    invalidate_inode_buffers        vmlinux EXPORT_SYMBOL
++0x5442b464    media_device_register_entity    vmlinux EXPORT_SYMBOL_GPL
++0xa279bad0    usb_add_config  vmlinux EXPORT_SYMBOL_GPL
++0x1d77b0f8    unix_socket_table       vmlinux EXPORT_SYMBOL_GPL
++0x7932f1fc    ip_tunnel_ioctl vmlinux EXPORT_SYMBOL_GPL
++0x153b7ac0    nl_table        vmlinux EXPORT_SYMBOL_GPL
++0xfdfcdc90    crypto_shash_update     vmlinux EXPORT_SYMBOL_GPL
++0xa376521b    find_vma        vmlinux EXPORT_SYMBOL
++0xe57f0426    vb2_dma_contig_cleanup_ctx      vmlinux EXPORT_SYMBOL_GPL
++0x0f53690e    usb_autopm_get_interface_async  vmlinux EXPORT_SYMBOL_GPL
++0xe97e3624    scsi_register   vmlinux EXPORT_SYMBOL
++0x07d4567b    max8997_write_reg       vmlinux EXPORT_SYMBOL_GPL
++0x24f2d831    regulator_register_notifier     vmlinux EXPORT_SYMBOL_GPL
++0x85ab9275    nf_ct_extend_unregister vmlinux EXPORT_SYMBOL_GPL
++0x7721fbd2    kernel_connect  vmlinux EXPORT_SYMBOL
++0x3095e489    single_open_size        vmlinux EXPORT_SYMBOL
++0x54ff695a    inet_stream_connect     vmlinux EXPORT_SYMBOL
++0xa05c03df    mempool_kmalloc vmlinux EXPORT_SYMBOL
++0xd6df7b3f    dma_buf_end_cpu_access  vmlinux EXPORT_SYMBOL_GPL
++0x2d5eac78    qdisc_warn_nonwc        vmlinux EXPORT_SYMBOL
++0x7bc477d0    splice_from_pipe_begin  vmlinux EXPORT_SYMBOL
++0xfd6293c2    boot_tvec_bases vmlinux EXPORT_SYMBOL
++0x6d662533    _find_first_bit_le      vmlinux EXPORT_SYMBOL
++0xd41f3207    netdev_class_remove_file        vmlinux EXPORT_SYMBOL
++0xdf48a0eb    flex_array_put  vmlinux EXPORT_SYMBOL
++0xcf048d93    blk_queue_physical_block_size   vmlinux EXPORT_SYMBOL
++0xd5790350    dio_end_io      vmlinux EXPORT_SYMBOL_GPL
++0xc0bf6ead    timecounter_cyc2time    vmlinux EXPORT_SYMBOL_GPL
++0x303087f1    v4l2_queryctrl  vmlinux EXPORT_SYMBOL
++0x506691f1    sock_diag_check_cookie  vmlinux EXPORT_SYMBOL_GPL
++0x307c2fd0    generic_check_addressable       vmlinux EXPORT_SYMBOL
++0x40b313d1    perf_event_read_value   vmlinux EXPORT_SYMBOL_GPL
++0x04482cdb    __refrigerator  vmlinux EXPORT_SYMBOL
++0x7cb1ae69    cpu_down        vmlinux EXPORT_SYMBOL
++0xc9aca11e    v4l2_ctrl_handler_log_status    vmlinux EXPORT_SYMBOL
++0xb7f77027    rtc_tm_to_ktime vmlinux EXPORT_SYMBOL_GPL
++0x70c8201b    tty_lock_pair   vmlinux EXPORT_SYMBOL
++0x1565add4    inet6_csk_addr2sockaddr vmlinux EXPORT_SYMBOL_GPL
++0x72a112d9    netdev_refcnt_read      vmlinux EXPORT_SYMBOL
++0xacc6730b    __blk_end_request       vmlinux EXPORT_SYMBOL
++0xbe54542c    input_mt_init_slots     vmlinux EXPORT_SYMBOL
++0xca3920b5    usb_disable_lpm vmlinux EXPORT_SYMBOL_GPL
++0x0cd967c3    usb_disable_ltm vmlinux EXPORT_SYMBOL_GPL
++0x3b66b0c1    __pm_wakeup_event       vmlinux EXPORT_SYMBOL_GPL
++0x0f480178    devres_close_group      vmlinux EXPORT_SYMBOL_GPL
++0xf0bd9740    drm_mode_parse_command_line_for_connector       vmlinux EXPORT_SYMBOL
++0x12c6276a    drm_buffer_read_object  vmlinux EXPORT_SYMBOL
++0xc3b93bba    klist_next      vmlinux EXPORT_SYMBOL_GPL
++0x3d342d92    tcp_rcv_established     vmlinux EXPORT_SYMBOL
++0x540c6f94    inet_getpeer    vmlinux EXPORT_SYMBOL_GPL
++0x153c8015    ipv4_update_pmtu        vmlinux EXPORT_SYMBOL_GPL
++0x0c4bfb03    xt_unregister_targets   vmlinux EXPORT_SYMBOL
++0x5cd7eb9b    wm_hubs_dcs_done        vmlinux EXPORT_SYMBOL_GPL
++0xd7e56a4e    simple_strtoll  vmlinux EXPORT_SYMBOL
++0x20000329    simple_strtoul  vmlinux EXPORT_SYMBOL
++0x9e784e44    balance_dirty_pages_ratelimited vmlinux EXPORT_SYMBOL
++0x11195d33    usb_enable_lpm  vmlinux EXPORT_SYMBOL_GPL
++0xd7f91a45    usb_enable_ltm  vmlinux EXPORT_SYMBOL_GPL
++0x39e2b6d2    spi_alloc_master        vmlinux EXPORT_SYMBOL_GPL
++0x82eb671b    scsi_prep_fn    vmlinux EXPORT_SYMBOL
++0x4473fccc    nf_register_afinfo      vmlinux EXPORT_SYMBOL_GPL
++0xd1e13a97    net_ns_type_operations  vmlinux EXPORT_SYMBOL_GPL
++0x1bf69c17    proc_symlink    vmlinux EXPORT_SYMBOL
++0x651c3828    usb_add_phy_dev vmlinux EXPORT_SYMBOL_GPL
++0xf571b062    drm_addmap      vmlinux EXPORT_SYMBOL
++0xb41150b4    pwm_enable      vmlinux EXPORT_SYMBOL_GPL
++0x8c52195f    __rtnl_link_unregister  vmlinux EXPORT_SYMBOL_GPL
++0xe2cb9278    snd_soc_dai_set_tdm_slot        vmlinux EXPORT_SYMBOL_GPL
++0x4de34a07    cpu_rmap_put    vmlinux EXPORT_SYMBOL
++0xb51797f0    blk_queue_dma_alignment vmlinux EXPORT_SYMBOL
++0xdab3304e    remap_vmalloc_range     vmlinux EXPORT_SYMBOL
++0x5113c626    noop_backing_dev_info   vmlinux EXPORT_SYMBOL_GPL
++0xd985dc99    mempool_free_pages      vmlinux EXPORT_SYMBOL
++0xfcec0987    enable_irq      vmlinux EXPORT_SYMBOL
++0x1e7bbcb3    kernel_restart  vmlinux EXPORT_SYMBOL_GPL
++0xa26c3f65    mmc_gpio_free_cd        vmlinux EXPORT_SYMBOL
++0x6461806d    max8997_bulk_write      vmlinux EXPORT_SYMBOL_GPL
++0x2ff9c227    filemap_page_mkwrite    vmlinux EXPORT_SYMBOL
++0xd2917bd3    v4l2_m2m_fop_poll       vmlinux EXPORT_SYMBOL_GPL
++0xc11159cc    drm_mode_create vmlinux EXPORT_SYMBOL
++0xdd27fa87    memchr  vmlinux EXPORT_SYMBOL
++0x10329729    inet6_release   vmlinux EXPORT_SYMBOL
++0xc18ac88d    nf_ct_expect_hsize      vmlinux EXPORT_SYMBOL_GPL
++0x005e9828    vfs_kern_mount  vmlinux EXPORT_SYMBOL_GPL
++0xd5bd7dac    ring_buffer_record_enable_cpu   vmlinux EXPORT_SYMBOL_GPL
++0x00cf4a7f    of_get_parent   vmlinux EXPORT_SYMBOL
++0xd6097597    v4l2_ctrl_new_int_menu  vmlinux EXPORT_SYMBOL
++0x3cdbf719    drm_mode_destroy        vmlinux EXPORT_SYMBOL
++0xb03e9a0f    nfc_set_remote_general_bytes    vmlinux EXPORT_SYMBOL
++0x2059c814    sock_diag_register      vmlinux EXPORT_SYMBOL_GPL
++0x315c65fd    zlib_deflateInit2       vmlinux EXPORT_SYMBOL
++0x1ab8c624    submit_bio      vmlinux EXPORT_SYMBOL
++0xd070d52e    alloc_page_buffers      vmlinux EXPORT_SYMBOL_GPL
++0x622c7922    register_oom_notifier   vmlinux EXPORT_SYMBOL_GPL
++0xe806f5a2    trace_event_buffer_lock_reserve vmlinux EXPORT_SYMBOL_GPL
++0xcfc68341    synchronize_rcu_bh      vmlinux EXPORT_SYMBOL_GPL
++0x549525ef    handle_nested_irq       vmlinux EXPORT_SYMBOL_GPL
++0x20421305    on_each_cpu_mask        vmlinux EXPORT_SYMBOL
++0xa1bb9fb1    spi_bus_type    vmlinux EXPORT_SYMBOL_GPL
++0x8a627eb3    anon_transport_class_unregister vmlinux EXPORT_SYMBOL_GPL
++0xd8525ea7    fl6_update_dst  vmlinux EXPORT_SYMBOL_GPL
++0xbac1a16b    tcp_valid_rtt_meas      vmlinux EXPORT_SYMBOL
++0xb67cd6f1    neigh_lookup    vmlinux EXPORT_SYMBOL
++0xc2c639ae    debugfs_create_u32_array        vmlinux EXPORT_SYMBOL_GPL
++0xd4a33b98    mmc_remove_host vmlinux EXPORT_SYMBOL
++0x1f65abdf    usb_put_hcd     vmlinux EXPORT_SYMBOL_GPL
++0x2ef63ad6    scsi_dev_info_list_del_keyed    vmlinux EXPORT_SYMBOL
++0x0bf18882    tcp_mtup_init   vmlinux EXPORT_SYMBOL
++0x0ea07ec7    kstrtou8_from_user      vmlinux EXPORT_SYMBOL
++0x973d0f9e    kstrtoul_from_user      vmlinux EXPORT_SYMBOL
++0x7c8db884    devm_clk_unregister     vmlinux EXPORT_SYMBOL_GPL
++0x46066e5b    perf_pmu_name   vmlinux EXPORT_SYMBOL_GPL
++0x951ac153    snd_soc_jack_report     vmlinux EXPORT_SYMBOL_GPL
++0x7c1464a6    snd_soc_dapm_get_enum_double    vmlinux EXPORT_SYMBOL_GPL
++0xd36af700    snd_soc_dapm_put_enum_double    vmlinux EXPORT_SYMBOL_GPL
++0x222e7ce2    sysfs_streq     vmlinux EXPORT_SYMBOL
++0xca72b2e9    alloc_buffer_head       vmlinux EXPORT_SYMBOL
++0x364d71cb    iio_scan_mask_set       vmlinux EXPORT_SYMBOL_GPL
++0x813f3de4    v4l2_find_nearest_format        vmlinux EXPORT_SYMBOL_GPL
++0xb37a0603    drm_dp_link_train_channel_eq_delay      vmlinux EXPORT_SYMBOL
++0x1fe912f1    netdev_alloc_frag       vmlinux EXPORT_SYMBOL
++0x7bdee655    usbnet_get_endpoints    vmlinux EXPORT_SYMBOL_GPL
++0x589e4569    syscon_regmap_lookup_by_pdevname        vmlinux EXPORT_SYMBOL_GPL
++0x60506751    unmap_kernel_range_noflush      vmlinux EXPORT_SYMBOL_GPL
++0x224b5740    device_remove_file      vmlinux EXPORT_SYMBOL_GPL
++0x1b8822d8    pinctrl_gpio_direction_output   vmlinux EXPORT_SYMBOL_GPL
++0x985e0b7d    ipv6_skip_exthdr        vmlinux EXPORT_SYMBOL
++0xa0e33feb    ip_options_compile      vmlinux EXPORT_SYMBOL
++0x289c3714    nf_ct_alloc_hashtable   vmlinux EXPORT_SYMBOL_GPL
++0xc33e401a    sock_diag_unregister    vmlinux EXPORT_SYMBOL_GPL
++0xba86c38e    aio_complete    vmlinux EXPORT_SYMBOL
++0x03bd889d    param_get_ulong vmlinux EXPORT_SYMBOL
++0xa4ca666e    kill_pid        vmlinux EXPORT_SYMBOL
++0xe56cb560    rt6_lookup      vmlinux EXPORT_SYMBOL
++0xc8fb75a8    unix_outq_len   vmlinux EXPORT_SYMBOL_GPL
++0xd5c5ff75    inet_frags_init_net     vmlinux EXPORT_SYMBOL
++0x64999478    congestion_wait vmlinux EXPORT_SYMBOL
++0x59eae699    ring_buffer_read_prepare        vmlinux EXPORT_SYMBOL_GPL
++0xa23061f8    mmc_read_bkops_status   vmlinux EXPORT_SYMBOL
++0xa1c46bd3    spi_bitbang_cleanup     vmlinux EXPORT_SYMBOL_GPL
++0x4d126acf    device_store_int        vmlinux EXPORT_SYMBOL_GPL
++0x5b546bbb    drm_gem_mmap    vmlinux EXPORT_SYMBOL
++0xd37d6496    hci_recv_fragment       vmlinux EXPORT_SYMBOL
++0x1c86d31e    ip_tunnel_delete_net    vmlinux EXPORT_SYMBOL_GPL
++0x9684e8c6    blk_queue_dma_drain     vmlinux EXPORT_SYMBOL_GPL
++0xf89e28e9    config_item_set_name    vmlinux EXPORT_SYMBOL
++0x9d8331c0    ring_buffer_read_page   vmlinux EXPORT_SYMBOL_GPL
++0x572d0104    _raw_write_unlock_irqrestore    vmlinux EXPORT_SYMBOL
++0x8e7894bd    __atomic_notifier_call_chain    vmlinux EXPORT_SYMBOL_GPL
++0xb202dbc6    i2c_del_driver  vmlinux EXPORT_SYMBOL
++0x057ce975    hex_dump_to_buffer      vmlinux EXPORT_SYMBOL
++0xe09f5fdd    file_ra_state_init      vmlinux EXPORT_SYMBOL_GPL
++0x011c93d4    v4l2_m2m_reqbufs        vmlinux EXPORT_SYMBOL_GPL
++0x5b185975    __dma_request_channel   vmlinux EXPORT_SYMBOL_GPL
++0xe02299ef    nfc_hci_send_response   vmlinux EXPORT_SYMBOL
++0xe8beb828    crypto_larval_kill      vmlinux EXPORT_SYMBOL_GPL
++0x8704eb06    irq_set_default_host    vmlinux EXPORT_SYMBOL_GPL
++0x7ac1d551    vb2_prepare_buf vmlinux EXPORT_SYMBOL_GPL
++0xfcab3072    media_entity_cleanup    vmlinux EXPORT_SYMBOL_GPL
++0x75d69d69    usb_alloc_coherent      vmlinux EXPORT_SYMBOL_GPL
++0x2f3857a0    xfrm_register_mode      vmlinux EXPORT_SYMBOL
++0x09c1fbfd    inet_csk_get_port       vmlinux EXPORT_SYMBOL_GPL
++0x1e6fd62f    kiocb_set_cancel_fn     vmlinux EXPORT_SYMBOL
++0xb20a8d04    mmc_flush_cache vmlinux EXPORT_SYMBOL
++0xb321b21c    i2c_clients_command     vmlinux EXPORT_SYMBOL
++0xd77c0bc8    klist_remove    vmlinux EXPORT_SYMBOL_GPL
++0x8cfe5489    dev_get_flags   vmlinux EXPORT_SYMBOL
++0x8022b19a    crypto_sha256_update    vmlinux EXPORT_SYMBOL
++0x0adfab73    __wait_on_bit_lock      vmlinux EXPORT_SYMBOL
++0x4a169d0b    usb_get_status  vmlinux EXPORT_SYMBOL_GPL
++0xe5122890    flow_cache_genid        vmlinux EXPORT_SYMBOL
++0x31cef011    gen_new_estimator       vmlinux EXPORT_SYMBOL
++0xbb6bebbd    crypto_alg_mod_lookup   vmlinux EXPORT_SYMBOL_GPL
++0xe208f5c9    freeze_super    vmlinux EXPORT_SYMBOL
++0xbf5b2016    __devm_request_region   vmlinux EXPORT_SYMBOL
++0x7cd6f042    cpufreq_get_current_driver      vmlinux EXPORT_SYMBOL_GPL
++0x946f789a    input_class     vmlinux EXPORT_SYMBOL_GPL
++0x33abb76e    usb_remove_function     vmlinux EXPORT_SYMBOL_GPL
++0x54c41f03    __cfg80211_send_disassoc        vmlinux EXPORT_SYMBOL
++0x886bcea3    hid_connect     vmlinux EXPORT_SYMBOL_GPL
++0x1d4cf31c    mmc_set_data_timeout    vmlinux EXPORT_SYMBOL
++0x020bb7c4    v4l2_m2m_qbuf   vmlinux EXPORT_SYMBOL_GPL
++0xf5ef842e    v4l_bound_align_image   vmlinux EXPORT_SYMBOL_GPL
++0x628c65bc    usb_set_device_state    vmlinux EXPORT_SYMBOL_GPL
++0x1d182b56    scsi_autopm_get_device  vmlinux EXPORT_SYMBOL_GPL
++0xa8b77259    scsi_autopm_put_device  vmlinux EXPORT_SYMBOL_GPL
++0x2641488c    scsi_eh_finish_cmd      vmlinux EXPORT_SYMBOL
++0x773650a0    vc_cons vmlinux EXPORT_SYMBOL
++0x6d203b02    dma_async_device_unregister     vmlinux EXPORT_SYMBOL
++0x18c2227f    cpu_rmap_update vmlinux EXPORT_SYMBOL
++0xdd0a2ba2    strlcat vmlinux EXPORT_SYMBOL
++0xd627480b    strncat vmlinux EXPORT_SYMBOL
++0x0dd47f83    blk_queue_max_discard_sectors   vmlinux EXPORT_SYMBOL
++0xb3f7646e    kthread_should_stop     vmlinux EXPORT_SYMBOL
++0x8d335f49    mmc_can_reset   vmlinux EXPORT_SYMBOL
++0x474576c2    v4l2_ctrl_new_std_menu  vmlinux EXPORT_SYMBOL
++0x735d80ef    drm_add_edid_modes      vmlinux EXPORT_SYMBOL
++0xbfdbe956    nfnetlink_set_err       vmlinux EXPORT_SYMBOL_GPL
++0xc0891ac5    netdev_notice   vmlinux EXPORT_SYMBOL
++0x03b5c8d0    blk_rq_map_kern vmlinux EXPORT_SYMBOL
++0x20f6c302    sync_mapping_buffers    vmlinux EXPORT_SYMBOL
++0x5610de90    pm_generic_freeze_noirq vmlinux EXPORT_SYMBOL_GPL
++0x33186585    drm_prime_lookup_buf_handle     vmlinux EXPORT_SYMBOL
++0x5c746654    bt_sock_register        vmlinux EXPORT_SYMBOL
++0x1f2ca4fa    fat_scan        vmlinux EXPORT_SYMBOL_GPL
++0x4ade2e74    inode_change_ok vmlinux EXPORT_SYMBOL
++0x2b2264c1    __scsi_add_device       vmlinux EXPORT_SYMBOL
++0x3a8903bb    datagram_poll   vmlinux EXPORT_SYMBOL
++0x75767b6f    snd_pcm_hw_constraint_minmax    vmlinux EXPORT_SYMBOL
++0xe623e6db    blk_queue_end_tag       vmlinux EXPORT_SYMBOL
++0x1e9edfb7    seq_hlist_start_head_rcu        vmlinux EXPORT_SYMBOL
++0x69d38ed9    __scsi_print_sense      vmlinux EXPORT_SYMBOL
++0xc6de7303    __tty_alloc_driver      vmlinux EXPORT_SYMBOL
++0xcdb5f930    __tcf_em_tree_match     vmlinux EXPORT_SYMBOL
++0x7a0a2470    dev_uc_flush    vmlinux EXPORT_SYMBOL
++0x6c8f0d30    dev_mc_flush    vmlinux EXPORT_SYMBOL
++0x067d8d35    security_release_secctx vmlinux EXPORT_SYMBOL
++0xb10e668e    jbd2_journal_check_available_features   vmlinux EXPORT_SYMBOL
++0xe2e8ac87    flush_old_exec  vmlinux EXPORT_SYMBOL
++0x00c4dc87    timecounter_init        vmlinux EXPORT_SYMBOL_GPL
++0xeb793d66    media_device_register   vmlinux EXPORT_SYMBOL_GPL
++0x694be42a    usb_show_dynids vmlinux EXPORT_SYMBOL_GPL
++0xdf3ec432    drm_gem_object_alloc    vmlinux EXPORT_SYMBOL
++0xa3d3ab7e    inet_addr_type  vmlinux EXPORT_SYMBOL
++0x97a2e370    inet_recvmsg    vmlinux EXPORT_SYMBOL
++0x0b59390b    __tracepoint_rpm_suspend        vmlinux EXPORT_SYMBOL_GPL
++0xa4701e9e    timekeeping_inject_offset       vmlinux EXPORT_SYMBOL
++0x1f54f1b4    do_trace_rcu_torture_read       vmlinux EXPORT_SYMBOL_GPL
++0x6275fa23    mdiobus_unregister      vmlinux EXPORT_SYMBOL
++0x639399b9    ump_dd_phys_block_count_get     vmlinux EXPORT_SYMBOL
++0x6812cf8d    __tracepoint_rpm_idle   vmlinux EXPORT_SYMBOL_GPL
++0xaa90f5bc    phy_detach      vmlinux EXPORT_SYMBOL
++0x8ded75c5    mii_link_ok     vmlinux EXPORT_SYMBOL
++0xa6dd4938    cfg80211_inform_bss_frame       vmlinux EXPORT_SYMBOL
++0xd4cc3c98    bt_procfs_cleanup       vmlinux EXPORT_SYMBOL
++0xd856b532    tcp_proc_register       vmlinux EXPORT_SYMBOL
++0xb86a648c    nf_conntrack_l4proto_udp6       vmlinux EXPORT_SYMBOL_GPL
++0x2c81ec75    __irq_regs      vmlinux EXPORT_SYMBOL
++0x3f182756    generic_write_sync      vmlinux EXPORT_SYMBOL
++0x48bd4a65    wakeup_source_remove    vmlinux EXPORT_SYMBOL_GPL
++0x027c2c52    stop_tty        vmlinux EXPORT_SYMBOL
++0xc18578ed    process_srcu    vmlinux EXPORT_SYMBOL_GPL
++0xf3cf07b0    sdio_writel     vmlinux EXPORT_SYMBOL_GPL
++0x9b54326d    xfrm_policy_destroy     vmlinux EXPORT_SYMBOL
++0x667cc3f3    inet_del_offload        vmlinux EXPORT_SYMBOL
++0xbc9cfb6e    jbd2_journal_stop       vmlinux EXPORT_SYMBOL
++0x43aec82a    sdhci_pltfm_register    vmlinux EXPORT_SYMBOL_GPL
++0x1db8867b    sdio_memcpy_toio        vmlinux EXPORT_SYMBOL_GPL
++0x48499aa5    neigh_ifdown    vmlinux EXPORT_SYMBOL
++0x4b53ee2c    snd_pcm_hw_constraint_ratnums   vmlinux EXPORT_SYMBOL
++0x9650df0b    snd_ctl_replace vmlinux EXPORT_SYMBOL
++0x6c1ce5ce    strcspn vmlinux EXPORT_SYMBOL
++0xa68698f6    jbd2_journal_extend     vmlinux EXPORT_SYMBOL
++0x7eb6d1eb    thermal_zone_unbind_cooling_device      vmlinux EXPORT_SYMBOL_GPL
++0x81328587    blkdev_aio_write        vmlinux EXPORT_SYMBOL_GPL
++0xf8bec8e3    seq_bitmap_list vmlinux EXPORT_SYMBOL
++0xaec655c7    alloc_pages_exact       vmlinux EXPORT_SYMBOL
++0x6ce5ade9    hid_parse_report        vmlinux EXPORT_SYMBOL_GPL
++0x66f7b07e    ehci_resume     vmlinux EXPORT_SYMBOL_GPL
++0x95c578a0    ioremap_page_range      vmlinux EXPORT_SYMBOL_GPL
++0x498dcb5e    drm_ut_debug_printk     vmlinux EXPORT_SYMBOL
++0x6c1f6c7e    drm_rmmap       vmlinux EXPORT_SYMBOL
++0x8b55de97    devm_regulator_bulk_get vmlinux EXPORT_SYMBOL_GPL
++0x8190aef3    register_sound_special  vmlinux EXPORT_SYMBOL
++0x6c255d20    __nla_reserve   vmlinux EXPORT_SYMBOL
++0x29537c9e    alloc_chrdev_region     vmlinux EXPORT_SYMBOL
++0x05273827    inc_zone_page_state     vmlinux EXPORT_SYMBOL
++0xc665d6d7    of_parse_phandle_with_args      vmlinux EXPORT_SYMBOL
++0x01f7b595    usbnet_skb_return       vmlinux EXPORT_SYMBOL_GPL
++0x0740687f    arp_find        vmlinux EXPORT_SYMBOL
++0x269fbd1b    nf_ct_iterate_cleanup   vmlinux EXPORT_SYMBOL_GPL
++0x22ce6bb8    skb_checksum    vmlinux EXPORT_SYMBOL
++0x669f1bc1    kfree_skb_list  vmlinux EXPORT_SYMBOL
++0xca9360b5    rb_next vmlinux EXPORT_SYMBOL
++0x3c010e48    inode_permission        vmlinux EXPORT_SYMBOL
++0xba34ed58    buffer_migrate_page     vmlinux EXPORT_SYMBOL
++0x1cfb04fa    finish_wait     vmlinux EXPORT_SYMBOL
++0xcb0b79fb    max8997_read_reg        vmlinux EXPORT_SYMBOL_GPL
++0x564f1dca    klist_add_after vmlinux EXPORT_SYMBOL_GPL
++0x4cbbd171    __bitmap_weight vmlinux EXPORT_SYMBOL
++0x61b7b126    simple_strtoull vmlinux EXPORT_SYMBOL
++0x528c709d    simple_read_from_buffer vmlinux EXPORT_SYMBOL
++0x10c9d678    irq_domain_simple_ops   vmlinux EXPORT_SYMBOL_GPL
++0x5d8d802b    clockevent_delta2ns     vmlinux EXPORT_SYMBOL_GPL
++0xe8731295    gether_get_ifname       vmlinux EXPORT_SYMBOL
++0x8619c1c9    phy_start_aneg  vmlinux EXPORT_SYMBOL
++0x2a1c0adc    scsi_print_result       vmlinux EXPORT_SYMBOL
++0x6eb85693    nf_defrag_ipv6_enable   vmlinux EXPORT_SYMBOL_GPL
++0x6b6c3d10    nf_defrag_ipv4_enable   vmlinux EXPORT_SYMBOL_GPL
++0xa681fe88    generate_random_uuid    vmlinux EXPORT_SYMBOL
++0x3147857d    default_red     vmlinux EXPORT_SYMBOL
++0xff9ca065    fb_edid_to_monspecs     vmlinux EXPORT_SYMBOL
++0x22e14acd    gpiochip_add_pin_range  vmlinux EXPORT_SYMBOL_GPL
++0xad1bb027    nf_ct_free_hashtable    vmlinux EXPORT_SYMBOL_GPL
++0xaf509095    get_net_ns_by_pid       vmlinux EXPORT_SYMBOL_GPL
++0xcff75292    vfs_statfs      vmlinux EXPORT_SYMBOL
++0x2756ceb6    mmc_power_save_host     vmlinux EXPORT_SYMBOL
++0x438610bd    security_tun_dev_alloc_security vmlinux EXPORT_SYMBOL
++0xb1d9068c    ip6_datagram_send_ctl   vmlinux EXPORT_SYMBOL_GPL
++0x365c213d    udp_ioctl       vmlinux EXPORT_SYMBOL
++0x53877b9f    __nla_reserve_nohdr     vmlinux EXPORT_SYMBOL
++0xd64146c4    __get_page_tail vmlinux EXPORT_SYMBOL
++0x9b1bc5fa    i2c_new_probed_device   vmlinux EXPORT_SYMBOL_GPL
++0x3c787bd5    rtnetlink_put_metrics   vmlinux EXPORT_SYMBOL
++0xcb5c97f9    blk_queue_max_write_same_sectors        vmlinux EXPORT_SYMBOL
++0x3b909e7e    may_umount      vmlinux EXPORT_SYMBOL
++0x0c8099b1    v4l2_spi_new_subdev     vmlinux EXPORT_SYMBOL_GPL
++0xd00b0085    v4l2_ctrl_handler_setup vmlinux EXPORT_SYMBOL
++0xea10212a    int_to_scsilun  vmlinux EXPORT_SYMBOL
++0xcb0944d8    pwm_set_chip_data       vmlinux EXPORT_SYMBOL_GPL
++0xde5846c4    pwm_get_chip_data       vmlinux EXPORT_SYMBOL_GPL
++0x915917a3    block_read_full_page    vmlinux EXPORT_SYMBOL
++0xe5d61b91    console_drivers vmlinux EXPORT_SYMBOL_GPL
++0xb776298b    iommu_detach_device     vmlinux EXPORT_SYMBOL_GPL
++0xeb711ae7    snd_soc_params_to_bclk  vmlinux EXPORT_SYMBOL_GPL
++0x90ed601f    mmc_hw_reset    vmlinux EXPORT_SYMBOL
++0x1cbd340b    cdc_ncm_unbind  vmlinux EXPORT_SYMBOL_GPL
++0x9caab5b6    __scsi_alloc_queue      vmlinux EXPORT_SYMBOL
++0x2506e85a    bus_sort_breadthfirst   vmlinux EXPORT_SYMBOL_GPL
++0xd6769f27    ipt_alloc_initial_table vmlinux EXPORT_SYMBOL_GPL
++0x439fe23e    tcp_v4_connect  vmlinux EXPORT_SYMBOL
++0x02de3eaf    tcp_sync_mss    vmlinux EXPORT_SYMBOL
++0x4be85a03    memweight       vmlinux EXPORT_SYMBOL
++0x93021b18    jbd2_journal_ack_err    vmlinux EXPORT_SYMBOL
++0xd0c05159    emergency_restart       vmlinux EXPORT_SYMBOL_GPL
++0x3ff62317    local_bh_disable        vmlinux EXPORT_SYMBOL
++0xd88781bd    regmap_raw_write        vmlinux EXPORT_SYMBOL_GPL
++0xada38534    regulator_bulk_disable  vmlinux EXPORT_SYMBOL_GPL
++0x2ad4daf6    tcp_death_row   vmlinux EXPORT_SYMBOL_GPL
++0x87751cba    netdev_upper_dev_link   vmlinux EXPORT_SYMBOL
++0xe187693c    kstrtouint_from_user    vmlinux EXPORT_SYMBOL
++0xbe797e8f    bio_get_nr_vecs vmlinux EXPORT_SYMBOL
++0x2373352a    clk_fixed_factor_ops    vmlinux EXPORT_SYMBOL_GPL
++0xccbee9bd    mmc_set_blockcount      vmlinux EXPORT_SYMBOL
++0x9ebb3718    v4l2_clk_unregister     vmlinux EXPORT_SYMBOL
++0xe28ade94    serio_rescan    vmlinux EXPORT_SYMBOL
++0x1b5c713f    drm_send_vblank_event   vmlinux EXPORT_SYMBOL
++0xa257d9cd    framebuffer_alloc       vmlinux EXPORT_SYMBOL
++0x0916cc54    xfrm_policy_byid        vmlinux EXPORT_SYMBOL
++0x07319ef1    ahash_register_instance vmlinux EXPORT_SYMBOL_GPL
++0x11c55999    load_nls_default        vmlinux EXPORT_SYMBOL
++0xcae08d66    nonseekable_open        vmlinux EXPORT_SYMBOL
++0x3651150d    kmem_cache_create       vmlinux EXPORT_SYMBOL
++0xfd26424e    cpufreq_driver_target   vmlinux EXPORT_SYMBOL_GPL
++0x66adff69    vb2_fop_read    vmlinux EXPORT_SYMBOL_GPL
++0x09a5b743    amba_apb_device_add     vmlinux EXPORT_SYMBOL_GPL
++0x475100c2    inet_get_local_port_range       vmlinux EXPORT_SYMBOL
++0x8c1e0ffe    __seq_open_private      vmlinux EXPORT_SYMBOL
++0xd60c8ab0    seq_escape      vmlinux EXPORT_SYMBOL
++0xc81ec7cb    phy_get_eee_err vmlinux EXPORT_SYMBOL
++0x00778770    xfrm_ealg_get_byname    vmlinux EXPORT_SYMBOL_GPL
++0x5bc722fb    sock_alloc_file vmlinux EXPORT_SYMBOL
++0xddf821b8    page_address    vmlinux EXPORT_SYMBOL
++0x9771ccf0    of_mdiobus_register     vmlinux EXPORT_SYMBOL
++0x5eb24829    dm_shift_arg    vmlinux EXPORT_SYMBOL
++0x119e8920    v4l2_async_unregister_subdev    vmlinux EXPORT_SYMBOL
++0x7bc3e7c1    xfrm_lookup     vmlinux EXPORT_SYMBOL
++0xae0410db    skb_store_bits  vmlinux EXPORT_SYMBOL
++0xf86deaaa    page_cache_sync_readahead       vmlinux EXPORT_SYMBOL_GPL
++0x7681946c    unregister_pm_notifier  vmlinux EXPORT_SYMBOL_GPL
++0x3d98d961    inet_unregister_protosw vmlinux EXPORT_SYMBOL
++0x82108639    snd_soc_get_volsw       vmlinux EXPORT_SYMBOL_GPL
++0x286d040c    snd_soc_put_volsw       vmlinux EXPORT_SYMBOL_GPL
++0x371c0db7    blk_queue_bypass_end    vmlinux EXPORT_SYMBOL_GPL
++0x8589f760    mb_cache_entry_free     vmlinux EXPORT_SYMBOL
++0x87a795d4    i2c_probe_func_quick_read       vmlinux EXPORT_SYMBOL_GPL
++0xb05661a7    i2c_smbus_read_byte     vmlinux EXPORT_SYMBOL
++0x167977e6    platform_create_bundle  vmlinux EXPORT_SYMBOL_GPL
++0xb626c977    _dev_info       vmlinux EXPORT_SYMBOL
++0x0d5db696    arm_iommu_detach_device vmlinux EXPORT_SYMBOL_GPL
++0x001f6379    blkcipher_walk_phys     vmlinux EXPORT_SYMBOL_GPL
++0x3dfc897c    seq_hlist_start_head    vmlinux EXPORT_SYMBOL
++0xc34ff0bb    clocksource_change_rating       vmlinux EXPORT_SYMBOL
++0x5ace7e88    devres_for_each_res     vmlinux EXPORT_SYMBOL_GPL
++0xd4390384    __ieee80211_get_channel vmlinux EXPORT_SYMBOL
++0xe55e04a1    ip6_tnl_rcv_ctl vmlinux EXPORT_SYMBOL_GPL
++0xa389a49a    profile_event_register  vmlinux EXPORT_SYMBOL_GPL
++0x5ef37944    sdio_set_block_size     vmlinux EXPORT_SYMBOL_GPL
++0x9924c496    __usb_get_extra_descriptor      vmlinux EXPORT_SYMBOL_GPL
++0xcfa57ce1    __nf_conntrack_helper_find      vmlinux EXPORT_SYMBOL_GPL
++0x5460c8d8    fsnotify_get_cookie     vmlinux EXPORT_SYMBOL_GPL
++0xf5f58a7b    gether_register_netdev  vmlinux EXPORT_SYMBOL
++0xe774e9e4    register_netdevice      vmlinux EXPORT_SYMBOL
++0x9209f545    blkdev_put      vmlinux EXPORT_SYMBOL
++0x6a1c9c55    blkdev_get      vmlinux EXPORT_SYMBOL
++0x4d0cbb95    finish_no_open  vmlinux EXPORT_SYMBOL
++0xa1ef69b9    unregister_ftrace_event vmlinux EXPORT_SYMBOL_GPL
++0x09d6a08d    v4l2_device_disconnect  vmlinux EXPORT_SYMBOL_GPL
++0x613a7741    scsi_finish_command     vmlinux EXPORT_SYMBOL
++0x11f447ce    __gpio_to_irq   vmlinux EXPORT_SYMBOL_GPL
++0xb8a9ab06    hci_unregister_cb       vmlinux EXPORT_SYMBOL
++0xca0741ee    nf_nat_l4proto_register vmlinux EXPORT_SYMBOL_GPL
++0x70f09a3d    nf_nat_l3proto_register vmlinux EXPORT_SYMBOL_GPL
++0x10447797    build_skb       vmlinux EXPORT_SYMBOL
++0xf2b1ac8e    __getnstimeofday        vmlinux EXPORT_SYMBOL
++0x8923ab21    get_tz_trend    vmlinux EXPORT_SYMBOL
++0x450e1fb7    gs_alloc_req    vmlinux EXPORT_SYMBOL_GPL
++0x176df204    tcp_get_info    vmlinux EXPORT_SYMBOL_GPL
++0x4c2a5480    __alloc_skb     vmlinux EXPORT_SYMBOL
++0x90814050    snd_soc_cache_write     vmlinux EXPORT_SYMBOL_GPL
++0xa4ba4393    snd_soc_dai_set_fmt     vmlinux EXPORT_SYMBOL_GPL
++0x2d98d3e7    jbd2_journal_begin_ordered_truncate     vmlinux EXPORT_SYMBOL
++0x5b79185b    jbd2_trans_will_send_data_barrier       vmlinux EXPORT_SYMBOL
++0xc200914d    mutex_trylock   vmlinux EXPORT_SYMBOL
++0xe24d3a97    jiffies_64      vmlinux EXPORT_SYMBOL
++0x7eb7b3f8    of_get_dma_window       vmlinux EXPORT_SYMBOL_GPL
++0xc5c9bb41    regmap_get_val_bytes    vmlinux EXPORT_SYMBOL_GPL
++0x8226642f    __gpio_cansleep vmlinux EXPORT_SYMBOL_GPL
++0x6def2db2    half_md4_transform      vmlinux EXPORT_SYMBOL
++0xb835b3e4    radix_tree_prev_hole    vmlinux EXPORT_SYMBOL
++0xbed06655    dcache_readdir  vmlinux EXPORT_SYMBOL
++0x980c6433    inode_add_bytes vmlinux EXPORT_SYMBOL
++0xdc092d5b    thaw_super      vmlinux EXPORT_SYMBOL
++0x1ef192c5    generic_file_mmap       vmlinux EXPORT_SYMBOL
++0x9075cea3    abort_creds     vmlinux EXPORT_SYMBOL
++0x4ef8e23f    led_set_brightness      vmlinux EXPORT_SYMBOL
++0x48a5b067    __machine_arch_type     vmlinux EXPORT_SYMBOL
++0x4188d439    neigh_rand_reach_time   vmlinux EXPORT_SYMBOL
++0x7eef21b4    dev_forward_skb vmlinux EXPORT_SYMBOL_GPL
++0x5825f0e7    sock_common_getsockopt  vmlinux EXPORT_SYMBOL
++0x2de67218    sock_common_setsockopt  vmlinux EXPORT_SYMBOL
++0x65408378    zlib_inflate_blob       vmlinux EXPORT_SYMBOL
++0xc6d9568b    try_to_writeback_inodes_sb      vmlinux EXPORT_SYMBOL
++0x5ad87de6    vfs_mknod       vmlinux EXPORT_SYMBOL
++0x6f5c943e    rndis_add_hdr   vmlinux EXPORT_SYMBOL
++0x6a91e934    drm_mode_create_dvi_i_properties        vmlinux EXPORT_SYMBOL
++0x3eb37b9d    drm_ht_create   vmlinux EXPORT_SYMBOL
++0xcdf8626d    n_tty_inherit_ops       vmlinux EXPORT_SYMBOL_GPL
++0x65d6d0f0    gpio_direction_input    vmlinux EXPORT_SYMBOL_GPL
++0x74acd28a    nfc_hci_set_clientdata  vmlinux EXPORT_SYMBOL
++0x6c6a3e69    nfc_hci_get_clientdata  vmlinux EXPORT_SYMBOL
++0x8e235e9b    cfg80211_disconnected   vmlinux EXPORT_SYMBOL
++0x2d6b040a    cfg80211_send_rx_auth   vmlinux EXPORT_SYMBOL
++0x987f5e85    skb_dequeue     vmlinux EXPORT_SYMBOL
++0x413461c0    filemap_write_and_wait  vmlinux EXPORT_SYMBOL
++0x27bbf221    disable_irq_nosync      vmlinux EXPORT_SYMBOL
++0x00000000    softirq_work_list       vmlinux EXPORT_SYMBOL
++0x8c298b56    vb2_ioctl_querybuf      vmlinux EXPORT_SYMBOL_GPL
++0x94d7075a    usb_gadget_get_string   vmlinux EXPORT_SYMBOL_GPL
++0x19ef30a6    usbnet_manage_power     vmlinux EXPORT_SYMBOL
++0x967e7ec8    inet_rtx_syn_ack        vmlinux EXPORT_SYMBOL
++0x9b9e05f9    alloc_cpu_rmap  vmlinux EXPORT_SYMBOL
++0xa7f92105    add_uevent_var  vmlinux EXPORT_SYMBOL_GPL
++0x6e6c5939    dma_buf_kunmap_atomic   vmlinux EXPORT_SYMBOL_GPL
++0x3723eb08    __pm_relax      vmlinux EXPORT_SYMBOL_GPL
++0x1ae74b3a    drm_framebuffer_unregister_private      vmlinux EXPORT_SYMBOL
++0xf7584a9c    find_font       vmlinux EXPORT_SYMBOL
++0x88e316d7    netdev_features_change  vmlinux EXPORT_SYMBOL
++0xf19e9355    cpu_online_mask vmlinux EXPORT_SYMBOL
++0xaa8195e9    media_entity_remote_pad vmlinux EXPORT_SYMBOL_GPL
++0x19ec698c    platform_get_resource_byname    vmlinux EXPORT_SYMBOL_GPL
++0x62813e5c    nf_ct_port_nlattr_tuple_size    vmlinux EXPORT_SYMBOL_GPL
++0x4ff4a58a    nfnetlink_alloc_skb     vmlinux EXPORT_SYMBOL_GPL
++0xeed3635b    proc_dostring   vmlinux EXPORT_SYMBOL
++0xb54533f7    usecs_to_jiffies        vmlinux EXPORT_SYMBOL
++0x0b56117f    of_find_node_by_path    vmlinux EXPORT_SYMBOL
++0xcc4b84da    of_find_node_by_type    vmlinux EXPORT_SYMBOL
++0xf9fd4da3    phy_start       vmlinux EXPORT_SYMBOL
++0x5ea42ad5    devres_find     vmlinux EXPORT_SYMBOL_GPL
++0x598a2261    drm_mode_probed_add     vmlinux EXPORT_SYMBOL
++0xc35b2a18    xt_hook_link    vmlinux EXPORT_SYMBOL_GPL
++0xc1c24fbc    genlmsg_put     vmlinux EXPORT_SYMBOL
++0xf177aba7    sysfs_schedule_callback vmlinux EXPORT_SYMBOL_GPL
++0xabcaa577    free_anon_bdev  vmlinux EXPORT_SYMBOL
++0x6d289788    pwm_set_polarity        vmlinux EXPORT_SYMBOL_GPL
++0x2546de76    raw_hash_sk     vmlinux EXPORT_SYMBOL_GPL
++0xa2ef34d7    rps_sock_flow_table     vmlinux EXPORT_SYMBOL
++0x3730910b    skb_insert      vmlinux EXPORT_SYMBOL
++0xb8b7395a    snd_compress_new        vmlinux EXPORT_SYMBOL_GPL
++0x1c132024    request_any_context_irq vmlinux EXPORT_SYMBOL_GPL
++0x5aba52ab    iio_trigger_poll        vmlinux EXPORT_SYMBOL
++0xe9b6f3f3    dev_emerg       vmlinux EXPORT_SYMBOL
++0xfacd2e14    pgprot_user     vmlinux EXPORT_SYMBOL
++0x0a0786de    udplite_table   vmlinux EXPORT_SYMBOL
++0xd9bbcf52    tc_classify_compat      vmlinux EXPORT_SYMBOL
++0x72f15b74    blk_queue_max_segment_size      vmlinux EXPORT_SYMBOL
++0x544aab61    klist_add_tail  vmlinux EXPORT_SYMBOL_GPL
++0x490434ad    dev_kfree_skb_irq       vmlinux EXPORT_SYMBOL
++0xdb3a9b04    jbd2_journal_file_inode vmlinux EXPORT_SYMBOL
++0x6e9dd606    __symbol_put    vmlinux EXPORT_SYMBOL
++0x40a2d1dd    dm_table_get_size       vmlinux EXPORT_SYMBOL
++0xceee316a    gether_set_host_addr    vmlinux EXPORT_SYMBOL
++0x32f81723    gether_get_host_addr    vmlinux EXPORT_SYMBOL
++0xae387af1    usb_gadget_unmap_request        vmlinux EXPORT_SYMBOL_GPL
++0x8dfb019d    drm_buffer_free vmlinux EXPORT_SYMBOL
++0x600683d3    do_unblank_screen       vmlinux EXPORT_SYMBOL
++0xc1ebf6fe    get_kernel_page vmlinux EXPORT_SYMBOL_GPL
++0x9b388444    get_zeroed_page vmlinux EXPORT_SYMBOL
++0x53b69429    vb2_streamon    vmlinux EXPORT_SYMBOL_GPL
++0x211aedde    genphy_restart_aneg     vmlinux EXPORT_SYMBOL
++0xebdba37a    ndo_dflt_fdb_dump       vmlinux EXPORT_SYMBOL
++0x604ef7b4    snd_pcm_lib_read        vmlinux EXPORT_SYMBOL
++0x60541cbf    st_sensors_set_odr      vmlinux EXPORT_SYMBOL
++0xe53d1faa    of_translate_dma_address        vmlinux EXPORT_SYMBOL
++0xaf05b91b    of_device_is_available  vmlinux EXPORT_SYMBOL
++0x1a426d0c    input_close_device      vmlinux EXPORT_SYMBOL
++0xe720411b    rtnl_create_link        vmlinux EXPORT_SYMBOL
++0x650f8603    snd_pcm_format_silence_64       vmlinux EXPORT_SYMBOL
++0x7164c04b    address_space_init_once vmlinux EXPORT_SYMBOL
++0xfda0dbe8    ftrace_print_hex_seq    vmlinux EXPORT_SYMBOL
++0x2c988955    prepare_to_wait_exclusive       vmlinux EXPORT_SYMBOL
++0x9c3206d8    v4l2_device_unregister  vmlinux EXPORT_SYMBOL_GPL
++0xd5c2bed3    phy_connect_direct      vmlinux EXPORT_SYMBOL
++0xed2b0677    drm_mode_connector_update_edid_property vmlinux EXPORT_SYMBOL
++0xbf17b32e    tty_insert_flip_string_flags    vmlinux EXPORT_SYMBOL
++0xadc9ed27    bt_sock_ioctl   vmlinux EXPORT_SYMBOL
++0x33ea8640    inet_dev_addr_type      vmlinux EXPORT_SYMBOL
++0xd265ad57    tcf_action_exec vmlinux EXPORT_SYMBOL
++0xec8d9205    snd_soc_register_codec  vmlinux EXPORT_SYMBOL_GPL
++0x5e8ff943    debugfs_create_size_t   vmlinux EXPORT_SYMBOL_GPL
++0x5b968338    remove_proc_entry       vmlinux EXPORT_SYMBOL
++0x4717eaaf    platform_device_add     vmlinux EXPORT_SYMBOL_GPL
++0x44a0c113    drm_mode_height vmlinux EXPORT_SYMBOL
++0xe219d715    ipv6_opt_accepted       vmlinux EXPORT_SYMBOL_GPL
++0x503ed988    xfrm_spd_getinfo        vmlinux EXPORT_SYMBOL
++0x1fd1fabe    arpt_register_table     vmlinux EXPORT_SYMBOL
++0xf9ed2e31    block_is_partially_uptodate     vmlinux EXPORT_SYMBOL
++0xd9ecb670    ring_buffer_overruns    vmlinux EXPORT_SYMBOL_GPL
++0x5e911cf3    exynos_g2d_exec_ioctl   vmlinux EXPORT_SYMBOL_GPL
++0xbf69cda1    drm_connector_unplug_all        vmlinux EXPORT_SYMBOL
++0xafe3eb1b    alloc_etherdev_mqs      vmlinux EXPORT_SYMBOL
++0x39bf9301    _snd_pcm_hw_param_setempty      vmlinux EXPORT_SYMBOL
++0xd81836ce    uart_resume_port        vmlinux EXPORT_SYMBOL
++0x46931864    nfc_tm_data_received    vmlinux EXPORT_SYMBOL
++0xfac8865f    sysctl_wmem_max vmlinux EXPORT_SYMBOL
++0xb05fc310    sysctl_rmem_max vmlinux EXPORT_SYMBOL
++0xe9b673fa    dapm_mark_io_dirty      vmlinux EXPORT_SYMBOL_GPL
++0xbf0046d7    ahash_free_instance     vmlinux EXPORT_SYMBOL_GPL
++0x825a0923    jbd2_journal_errno      vmlinux EXPORT_SYMBOL
++0x03cb2c1a    bdi_register_dev        vmlinux EXPORT_SYMBOL
++0x018f7433    pm_relax        vmlinux EXPORT_SYMBOL_GPL
++0x63e0cc67    pagecache_write_end     vmlinux EXPORT_SYMBOL
++0x8a04b9fe    tracepoint_iter_reset   vmlinux EXPORT_SYMBOL_GPL
++0x5cf53ce2    input_free_minor        vmlinux EXPORT_SYMBOL
++0x17bfef6c    drm_clflush_pages       vmlinux EXPORT_SYMBOL
++0x5f14861d    pwm_get vmlinux EXPORT_SYMBOL_GPL
++0xb8a5d4ee    cfg80211_ft_event       vmlinux EXPORT_SYMBOL
++0xb9da2997    snmp_fold_field64       vmlinux EXPORT_SYMBOL_GPL
++0x87925ca6    kstrtoint_from_user     vmlinux EXPORT_SYMBOL
++0x6e891ea0    clk_unprepare   vmlinux EXPORT_SYMBOL_GPL
++0x3d41904f    of_get_next_child       vmlinux EXPORT_SYMBOL
++0x687835e7    hidinput_get_led_field  vmlinux EXPORT_SYMBOL_GPL
++0x36859243    hid_resolv_usage        vmlinux EXPORT_SYMBOL_GPL
++0x995dedd6    sdio_f0_readb   vmlinux EXPORT_SYMBOL_GPL
++0x19f5809b    dm_ratelimit_state      vmlinux EXPORT_SYMBOL
++0xe684f045    v4l2_subdev_try_ext_ctrls       vmlinux EXPORT_SYMBOL
++0x41f62b69    spi_register_master     vmlinux EXPORT_SYMBOL_GPL
++0x49428bcb    drm_read        vmlinux EXPORT_SYMBOL
++0xb12cbacb    fb_unregister_client    vmlinux EXPORT_SYMBOL
++0x7c53b814    xfrm_inner_extract_output       vmlinux EXPORT_SYMBOL_GPL
++0x86dd59c8    inet_csk_init_xmit_timers       vmlinux EXPORT_SYMBOL
++0x51e297e3    __nf_ct_l4proto_find    vmlinux EXPORT_SYMBOL_GPL
++0x1b52db1c    probe_kernel_read       vmlinux EXPORT_SYMBOL_GPL
++0xd4e65e28    irq_set_chip_and_handler_name   vmlinux EXPORT_SYMBOL_GPL
++0x9c7a3b79    drm_fb_helper_debug_enter       vmlinux EXPORT_SYMBOL
++0xc25d1133    vfs_readlink    vmlinux EXPORT_SYMBOL
++0x7e9efe8e    complete_and_exit       vmlinux EXPORT_SYMBOL
++0xd8d64478    v4l2_ctrl_new_std_menu_items    vmlinux EXPORT_SYMBOL
++0xb6652875    gserial_free_line       vmlinux EXPORT_SYMBOL_GPL
++0xd4adf602    dev_pm_get_subsys_data  vmlinux EXPORT_SYMBOL_GPL
++0x1f335345    dev_pm_put_subsys_data  vmlinux EXPORT_SYMBOL_GPL
++0x30399f8a    transport_add_device    vmlinux EXPORT_SYMBOL_GPL
++0x44c2d1be    drm_mode_prune_invalid  vmlinux EXPORT_SYMBOL
++0x3e9d6f44    cfg80211_unregister_wdev        vmlinux EXPORT_SYMBOL
++0xfb5bb3ee    inet6_lookup    vmlinux EXPORT_SYMBOL_GPL
++0x535cfa1f    sysfs_remove_group      vmlinux EXPORT_SYMBOL_GPL
++0x795b1ab0    sysfs_remove_file_from_group    vmlinux EXPORT_SYMBOL_GPL
++0x9aca444b    get_monotonic_boottime  vmlinux EXPORT_SYMBOL_GPL
++0x91aec064    down_read_trylock       vmlinux EXPORT_SYMBOL
++0x87e148ee    v4l2_m2m_poll   vmlinux EXPORT_SYMBOL_GPL
++0xfcb34391    scsi_execute_req_flags  vmlinux EXPORT_SYMBOL
++0x19391863    regmap_reinit_cache     vmlinux EXPORT_SYMBOL_GPL
++0xff6878cf    fb_default_cmap vmlinux EXPORT_SYMBOL
++0x38524c14    cpufreq_register_driver vmlinux EXPORT_SYMBOL_GPL
++0x4ca0e0e5    v4l2_ctrl_modify_range  vmlinux EXPORT_SYMBOL
++0x4f6f28fb    serial8250_handle_irq   vmlinux EXPORT_SYMBOL_GPL
++0x7b56a1b0    nf_nat_set_seq_adjust   vmlinux EXPORT_SYMBOL_GPL
++0x63df94bc    nf_nat_tcp_seq_adjust   vmlinux EXPORT_SYMBOL_GPL
++0x8ffb22a4    nf_setsockopt   vmlinux EXPORT_SYMBOL
++0xefd0fb67    nf_getsockopt   vmlinux EXPORT_SYMBOL
++0x579e0bf5    rtnl_unregister_all     vmlinux EXPORT_SYMBOL_GPL
++0x87e5d976    netif_rx_ni     vmlinux EXPORT_SYMBOL
++0xe27cea7b    alloc_disk      vmlinux EXPORT_SYMBOL
++0x1f867001    blk_rq_map_user_iov     vmlinux EXPORT_SYMBOL
++0xa3829135    ioc_lookup_icq  vmlinux EXPORT_SYMBOL
++0xd2ce469a    seq_puts        vmlinux EXPORT_SYMBOL
++0xf29942b3    seq_putc        vmlinux EXPORT_SYMBOL
++0xf268be24    dw_mci_remove   vmlinux EXPORT_SYMBOL
++0xb7ef4006    i2c_smbus_xfer  vmlinux EXPORT_SYMBOL
++0xb8a16d46    dev_pm_qos_remove_notifier      vmlinux EXPORT_SYMBOL_GPL
++0x37afc4f0    device_attach   vmlinux EXPORT_SYMBOL_GPL
++0x581e8240    tty_port_open   vmlinux EXPORT_SYMBOL
++0xa4583858    snd_pcm_hw_param_last   vmlinux EXPORT_SYMBOL
++0x43497fcc    part_round_stats        vmlinux EXPORT_SYMBOL_GPL
++0x0cd23659    d_genocide      vmlinux EXPORT_SYMBOL
++0x328995b5    tracing_generic_entry_update    vmlinux EXPORT_SYMBOL_GPL
++0xfe24d1c7    __module_put_and_exit   vmlinux EXPORT_SYMBOL
++0x43a53735    __alloc_workqueue_key   vmlinux EXPORT_SYMBOL_GPL
++0x2a902f32    usb_create_shared_hcd   vmlinux EXPORT_SYMBOL_GPL
++0xdbdbb6e7    uart_update_timeout     vmlinux EXPORT_SYMBOL
++0xf71617c1    cfg80211_report_obss_beacon     vmlinux EXPORT_SYMBOL
++0x3e5d6dc3    snd_soc_put_value_enum_double   vmlinux EXPORT_SYMBOL_GPL
++0xef67a6d3    snd_soc_get_value_enum_double   vmlinux EXPORT_SYMBOL_GPL
++0x81b69e41    snd_ctl_enum_info       vmlinux EXPORT_SYMBOL
++0xb2b94674    __crc32c_le     vmlinux EXPORT_SYMBOL
++0xc61cc06d    elv_dispatch_add_tail   vmlinux EXPORT_SYMBOL
++0x85e0bce2    end_buffer_write_sync   vmlinux EXPORT_SYMBOL
++0x3cc671ae    d_drop  vmlinux EXPORT_SYMBOL
++0x7469f641    d_rehash        vmlinux EXPORT_SYMBOL
++0xddcebac8    file_open_root  vmlinux EXPORT_SYMBOL
++0x310308c3    flush_kthread_work      vmlinux EXPORT_SYMBOL_GPL
++0x40f07981    __ashldi3       vmlinux EXPORT_SYMBOL
++0x88e83ca7    snd_soc_dpcm_be_set_state       vmlinux EXPORT_SYMBOL_GPL
++0x5eca39b9    snd_soc_dpcm_be_get_state       vmlinux EXPORT_SYMBOL_GPL
++0x6b1b67d3    __bdevname      vmlinux EXPORT_SYMBOL
++0xe4315493    vfs_write       vmlinux EXPORT_SYMBOL
++0x99fab0b8    __mmc_claim_host        vmlinux EXPORT_SYMBOL
++0x2c8e9ced    usb_poison_urb  vmlinux EXPORT_SYMBOL_GPL
++0x33a8a5f0    netif_rx        vmlinux EXPORT_SYMBOL
++0x1d54bb24    snd_pcm_hw_refine       vmlinux EXPORT_SYMBOL
++0x955b0e2e    kthread_worker_fn       vmlinux EXPORT_SYMBOL_GPL
++0x276ad369    dm_set_device_limits    vmlinux EXPORT_SYMBOL_GPL
++0x9e61f179    xfrm_stateonly_find     vmlinux EXPORT_SYMBOL
++0x972bcca5    usb_create_hcd  vmlinux EXPORT_SYMBOL_GPL
++0x72ea7b2d    scsi_device_type        vmlinux EXPORT_SYMBOL
++0x318cadb1    reciprocal_value        vmlinux EXPORT_SYMBOL
++0x22f77bec    unregister_binfmt       vmlinux EXPORT_SYMBOL
++0xafceeb25    alloc_vm_area   vmlinux EXPORT_SYMBOL_GPL
++0xcfe980c6    make_kgid       vmlinux EXPORT_SYMBOL
++0xb71fb74f    _raw_read_trylock       vmlinux EXPORT_SYMBOL
++0x9dadbb88    cpufreq_boost_supported vmlinux EXPORT_SYMBOL_GPL
++0xab9e471e    usb_autopm_get_interface_no_resume      vmlinux EXPORT_SYMBOL_GPL
++0x42453e50    sk_reset_txq    vmlinux EXPORT_SYMBOL
++0x05d48045    sock_no_accept  vmlinux EXPORT_SYMBOL
++0xb511dcf5    set_groups      vmlinux EXPORT_SYMBOL
++0x5f0abc76    pinctrl_dev_get_devname vmlinux EXPORT_SYMBOL_GPL
++0xec25f967    klist_del       vmlinux EXPORT_SYMBOL_GPL
++0x530ed62b    tcf_generic_walker      vmlinux EXPORT_SYMBOL
++0xacd392a0    sock_diag_register_inet_compat  vmlinux EXPORT_SYMBOL_GPL
++0x2509c465    dev_remove_offload      vmlinux EXPORT_SYMBOL
++0x8ee1a28d    elevator_exit   vmlinux EXPORT_SYMBOL
++0xcd357308    __lock_buffer   vmlinux EXPORT_SYMBOL
++0xd85139d2    mmc_unregister_driver   vmlinux EXPORT_SYMBOL
++0xb53559bb    brcmu_pktq_pflush       drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0xbb0ab47b    debug_locks     vmlinux EXPORT_SYMBOL_GPL
++0x56b2a97f    ablkcipher_walk_done    vmlinux EXPORT_SYMBOL_GPL
++0xd3630b88    ablkcipher_walk_phys    vmlinux EXPORT_SYMBOL_GPL
++0x3116987e    aead_geniv_alloc        vmlinux EXPORT_SYMBOL_GPL
++0x20a789ac    irq_set_chip_data       vmlinux EXPORT_SYMBOL
++0xeda65ce1    dma_release_declared_memory     vmlinux EXPORT_SYMBOL
++0xa984aab8    cfg80211_scan_done      vmlinux EXPORT_SYMBOL
++0x254c40cf    inet6_csk_xmit  vmlinux EXPORT_SYMBOL_GPL
++0xca805e0b    tcp_ioctl       vmlinux EXPORT_SYMBOL
++0x4ebc74b2    vfs_symlink     vmlinux EXPORT_SYMBOL
++0xefcf3143    wait_for_completion_io  vmlinux EXPORT_SYMBOL
++0xa9efcc8b    find_vpid       vmlinux EXPORT_SYMBOL_GPL
++0xd273b1b1    __round_jiffies_up_relative     vmlinux EXPORT_SYMBOL_GPL
++0xb8973764    iommu_attach_group      vmlinux EXPORT_SYMBOL_GPL
++0x5d550c4d    scsi_sd_probe_domain    vmlinux EXPORT_SYMBOL
++0x52f9bd8e    registered_fb   vmlinux EXPORT_SYMBOL
++0xe67d81ba    strlen_user     vmlinux EXPORT_SYMBOL
++0x480f1913    unmap_mapping_range     vmlinux EXPORT_SYMBOL
++0x8b618d08    overflowuid     vmlinux EXPORT_SYMBOL
++0x7171121c    overflowgid     vmlinux EXPORT_SYMBOL
++0xb3514b24    cfg80211_radar_event    vmlinux EXPORT_SYMBOL
++0xf06154af    inet_select_addr        vmlinux EXPORT_SYMBOL
++0x340854b4    dev_getbyhwaddr_rcu     vmlinux EXPORT_SYMBOL
++0x4ce033c8    skb_flow_dissect        vmlinux EXPORT_SYMBOL
++0x465757c3    cpu_present_mask        vmlinux EXPORT_SYMBOL
++0xb3a37086    dma_async_tx_descriptor_init    vmlinux EXPORT_SYMBOL
++0x955eec37    wireless_send_event     vmlinux EXPORT_SYMBOL
++0x7954e502    ipv6_recv_error vmlinux EXPORT_SYMBOL_GPL
++0xcebcfddd    snd_soc_get_enum_double vmlinux EXPORT_SYMBOL_GPL
++0x1c9728c6    snd_soc_put_enum_double vmlinux EXPORT_SYMBOL_GPL
++0xb4711532    get_task_io_context     vmlinux EXPORT_SYMBOL
++0x6cce08e5    dcache_dir_close        vmlinux EXPORT_SYMBOL
++0x3e884f4b    vm_get_page_prot        vmlinux EXPORT_SYMBOL
++0x20886a16    v4l2_subdev_g_ctrl      vmlinux EXPORT_SYMBOL
++0xd56dcf8e    v4l2_subdev_s_ctrl      vmlinux EXPORT_SYMBOL
++0x0465a073    regmap_reg_in_ranges    vmlinux EXPORT_SYMBOL_GPL
++0x74bc0dea    extcon_register_interest        vmlinux EXPORT_SYMBOL_GPL
++0x59c427c5    rtc_irq_set_state       vmlinux EXPORT_SYMBOL_GPL
++0x3302f88f    phy_driver_register     vmlinux EXPORT_SYMBOL
++0x848dd958    scsi_dma_unmap  vmlinux EXPORT_SYMBOL
++0xfbc74f64    __copy_from_user        vmlinux EXPORT_SYMBOL
++0xc9bb229b    inet_put_port   vmlinux EXPORT_SYMBOL
++0x73ac2c51    nf_conntrack_register_notifier  vmlinux EXPORT_SYMBOL_GPL
++0xbdca8444    sock_no_connect vmlinux EXPORT_SYMBOL
++0xe85a9fd3    cpu_cluster_pm_exit     vmlinux EXPORT_SYMBOL_GPL
++0xcb466063    wait_for_completion_killable_timeout    vmlinux EXPORT_SYMBOL
++0x9205953f    send_remote_softirq     vmlinux EXPORT_SYMBOL
++0x1852156d    phy_print_status        vmlinux EXPORT_SYMBOL
++0x486517f6    pinctrl_select_state    vmlinux EXPORT_SYMBOL_GPL
++0xfec26b4f    skcipher_geniv_alloc    vmlinux EXPORT_SYMBOL_GPL
++0x24094dc0    xfrm_garbage_collect    vmlinux EXPORT_SYMBOL
++0x6e224a7a    need_conntrack  vmlinux EXPORT_SYMBOL_GPL
++0x4a358252    __bitmap_subset vmlinux EXPORT_SYMBOL
++0x785d8ef0    ftrace_raw_output_prep  vmlinux EXPORT_SYMBOL
++0x697c5d0d    tracing_snapshot_alloc  vmlinux EXPORT_SYMBOL_GPL
++0x0e6da44a    set_normalized_timespec vmlinux EXPORT_SYMBOL
++0x789aafbd    iommu_map       vmlinux EXPORT_SYMBOL_GPL
++0x3a5f1e17    cfg80211_chandef_valid  vmlinux EXPORT_SYMBOL
++0xa11c9c1a    eth_type_trans  vmlinux EXPORT_SYMBOL
++0xe0f1fc5d    debugfs_create_blob     vmlinux EXPORT_SYMBOL_GPL
++0xd0f2dba2    mb_cache_entry_get      vmlinux EXPORT_SYMBOL
++0x233ed03d    vm_insert_mixed vmlinux EXPORT_SYMBOL
++0xa96bca8e    send_sig        vmlinux EXPORT_SYMBOL
++0x97cdf185    iio_buffer_read_length  vmlinux EXPORT_SYMBOL
++0x58d1070a    of_get_address  vmlinux EXPORT_SYMBOL
++0x620868cc    tcp_shutdown    vmlinux EXPORT_SYMBOL
++0x602c96f0    copy_to_user_fromio     vmlinux EXPORT_SYMBOL
++0x6d31e93b    tracepoint_iter_next    vmlinux EXPORT_SYMBOL_GPL
++0xe8b53ecc    down_write_trylock      vmlinux EXPORT_SYMBOL
++0x8bfe8c57    param_set_uint  vmlinux EXPORT_SYMBOL
++0x39422b14    usbnet_change_mtu       vmlinux EXPORT_SYMBOL_GPL
++0x4bd9c5ed    scsi_nonblockable_ioctl vmlinux EXPORT_SYMBOL
++0xcd319eaa    drm_vblank_count        vmlinux EXPORT_SYMBOL
++0x58413099    ipv6_fixup_options      vmlinux EXPORT_SYMBOL_GPL
++0xf389fe60    __hw_addr_init  vmlinux EXPORT_SYMBOL
++0x199ed0cd    net_disable_timestamp   vmlinux EXPORT_SYMBOL
++0x5ad8bb47    sdio_set_host_pm_flags  vmlinux EXPORT_SYMBOL_GPL
++0xdbbdaaf8    gether_get_qmult        vmlinux EXPORT_SYMBOL
++0x3d6846fc    gether_set_qmult        vmlinux EXPORT_SYMBOL
++0x14b14b7a    usb_get_function        vmlinux EXPORT_SYMBOL_GPL
++0x28fca1f1    pwmchip_add     vmlinux EXPORT_SYMBOL_GPL
++0xfbbedefd    of_prop_next_string     vmlinux EXPORT_SYMBOL_GPL
++0x4afe9a77    scsi_partsize   vmlinux EXPORT_SYMBOL
++0x14f875ce    devm_regmap_init_mmio_clk       vmlinux EXPORT_SYMBOL_GPL
++0x695aa696    __genl_register_family  vmlinux EXPORT_SYMBOL
++0x36bd681b    groups_alloc    vmlinux EXPORT_SYMBOL
++0x6a5b121d    of_find_device_by_node  vmlinux EXPORT_SYMBOL
++0x0dd989e3    vb2_streamoff   vmlinux EXPORT_SYMBOL_GPL
++0xa82de4f7    drm_pci_alloc   vmlinux EXPORT_SYMBOL
++0xdf54a8f7    netlink_unregister_notifier     vmlinux EXPORT_SYMBOL
++0xc4388843    dapm_regulator_event    vmlinux EXPORT_SYMBOL_GPL
++0x7a6fa714    __dynamic_dev_dbg       vmlinux EXPORT_SYMBOL
++0xfa4d00bd    simple_release_fs       vmlinux EXPORT_SYMBOL
++0xf473ffaf    down    vmlinux EXPORT_SYMBOL
++0xac6539ec    cm_notify_event vmlinux EXPORT_SYMBOL_GPL
++0xf49484e8    blk_end_request vmlinux EXPORT_SYMBOL
++0xb72a3fdb    drm_sysfs_connector_add vmlinux EXPORT_SYMBOL
++0x76cf47f6    __aeabi_llsl    vmlinux EXPORT_SYMBOL
++0x0573e568    inet_diag_dump_icsk     vmlinux EXPORT_SYMBOL_GPL
++0xc6a360e4    skb_put vmlinux EXPORT_SYMBOL
++0xf76b0a59    read_current_timer      vmlinux EXPORT_SYMBOL_GPL
++0xf1d6f94c    v4l2_m2m_ioctl_reqbufs  vmlinux EXPORT_SYMBOL_GPL
++0x5411bf06    scsi_host_put   vmlinux EXPORT_SYMBOL
++0xbca0b4fd    nfc_hci_sak_to_protocol vmlinux EXPORT_SYMBOL
++0x37386cac    nf_conntrack_hash_rnd   vmlinux EXPORT_SYMBOL_GPL
++0xdb065657    nfnl_unlock     vmlinux EXPORT_SYMBOL_GPL
++0xc5bd3b96    ethtool_op_get_ts_info  vmlinux EXPORT_SYMBOL
++0x5f8ed047    configfs_depend_item    vmlinux EXPORT_SYMBOL
++0x77fa6486    generic_block_fiemap    vmlinux EXPORT_SYMBOL
++0xc7bcbc8d    add_wait_queue  vmlinux EXPORT_SYMBOL
++0x046c1f16    param_ops_invbool       vmlinux EXPORT_SYMBOL
++0x4fe5c427    pinctrl_put     vmlinux EXPORT_SYMBOL_GPL
++0x547101cd    pinctrl_get     vmlinux EXPORT_SYMBOL_GPL
++0xdcc5846a    brcmu_pktq_flush        drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x4075ad18    dev_add_pack    vmlinux EXPORT_SYMBOL
++0x0a3131f6    strnchr vmlinux EXPORT_SYMBOL
++0xd20bf6ba    dcookie_unregister      vmlinux EXPORT_SYMBOL_GPL
++0x9e2be04d    vb2_poll        vmlinux EXPORT_SYMBOL_GPL
++0xa8f0aba7    usb_hub_clear_tt_buffer vmlinux EXPORT_SYMBOL_GPL
++0x2698ff67    drm_helper_connector_dpms       vmlinux EXPORT_SYMBOL
++0x48d34903    arm_dma_ops     vmlinux EXPORT_SYMBOL
++0x9f984513    strrchr vmlinux EXPORT_SYMBOL
++0x7afa89fc    vsnprintf       vmlinux EXPORT_SYMBOL
++0x7fe32873    rb_replace_node vmlinux EXPORT_SYMBOL
++0x6ff607b6    crypto_get_default_rng  vmlinux EXPORT_SYMBOL_GPL
++0x668402aa    crypto_put_default_rng  vmlinux EXPORT_SYMBOL_GPL
++0x850ff7d2    crypto_mod_put  vmlinux EXPORT_SYMBOL_GPL
++0x1db21259    mount_pseudo    vmlinux EXPORT_SYMBOL
++0x304ec72b    _raw_write_trylock      vmlinux EXPORT_SYMBOL
++0x4205ad24    cancel_work_sync        vmlinux EXPORT_SYMBOL_GPL
++0x99cdc86b    sysctl_tcp_reordering   vmlinux EXPORT_SYMBOL
++0x19d94b34    nf_ct_gre_keymap_flush  vmlinux EXPORT_SYMBOL
++0x356bcd72    nf_log_set      vmlinux EXPORT_SYMBOL
++0xd9e69bb2    dapm_reg_event  vmlinux EXPORT_SYMBOL_GPL
++0xb2959203    snd_pcm_hw_constraint_pow2      vmlinux EXPORT_SYMBOL
++0x9754ec10    radix_tree_preload      vmlinux EXPORT_SYMBOL
++0xc8cd27b8    blkdev_ioctl    vmlinux EXPORT_SYMBOL_GPL
++0xd11c0dc1    __kernel_param_unlock   vmlinux EXPORT_SYMBOL
++0xcda686ec    input_set_keycode       vmlinux EXPORT_SYMBOL
++0xc69c2d23    subsys_virtual_register vmlinux EXPORT_SYMBOL_GPL
++0x4eb8fe91    drm_gem_free_mmap_offset        vmlinux EXPORT_SYMBOL
++0x61cdf6e6    nfc_hci_allocate_device vmlinux EXPORT_SYMBOL
++0x2dda642f    __dynamic_netdev_dbg    vmlinux EXPORT_SYMBOL
++0x890dc2ed    idr_alloc_cyclic        vmlinux EXPORT_SYMBOL
++0x5cf6db68    crypto_register_instance        vmlinux EXPORT_SYMBOL_GPL
++0x93bd657f    crypto_alloc_tfm        vmlinux EXPORT_SYMBOL_GPL
++0x9c48a3ba    bdi_destroy     vmlinux EXPORT_SYMBOL
++0x29047f1a    __i2c_board_lock        vmlinux EXPORT_SYMBOL_GPL
++0x02e49d29    tty_ldisc_flush vmlinux EXPORT_SYMBOL_GPL
++0xb06d489b    skb_tstamp_tx   vmlinux EXPORT_SYMBOL_GPL
++0xe66452ab    dql_init        vmlinux EXPORT_SYMBOL
++0x69e27c7a    bitmap_copy_le  vmlinux EXPORT_SYMBOL
++0x4dec6038    memscan vmlinux EXPORT_SYMBOL
++0xa9148d85    mark_buffer_dirty       vmlinux EXPORT_SYMBOL
++0x304b568f    get_super       vmlinux EXPORT_SYMBOL
++0x00801678    flush_scheduled_work    vmlinux EXPORT_SYMBOL
++0xb6115ca3    tty_set_operations      vmlinux EXPORT_SYMBOL
++0x6d6cb9ad    ieee80211_operating_class_to_band       vmlinux EXPORT_SYMBOL
++0x32e1f29c    skb_copy_and_csum_bits  vmlinux EXPORT_SYMBOL
++0x776c599d    idma_reg_addr_init      vmlinux EXPORT_SYMBOL_GPL
++0xef9f2dc8    ll_rw_block     vmlinux EXPORT_SYMBOL
++0x13014091    block_write_begin       vmlinux EXPORT_SYMBOL
++0x93226faa    irq_domain_associate_many       vmlinux EXPORT_SYMBOL_GPL
++0x756a4248    st_sensors_read_info_raw        vmlinux EXPORT_SYMBOL
++0x04339915    iio_update_buffers      vmlinux EXPORT_SYMBOL_GPL
++0x55784228    regmap_irq_get_virq     vmlinux EXPORT_SYMBOL_GPL
++0xbc25aac9    ump_dd_phys_blocks_get  vmlinux EXPORT_SYMBOL
++0xe1761617    security_inet_conn_request      vmlinux EXPORT_SYMBOL
++0x1268f357    resume_device_irqs      vmlinux EXPORT_SYMBOL_GPL
++0xbe2e3b75    kstrtos8        vmlinux EXPORT_SYMBOL
++0x124f2056    crypto_get_attr_type    vmlinux EXPORT_SYMBOL_GPL
++0x2fc54b62    nfnetlink_send  vmlinux EXPORT_SYMBOL_GPL
++0x9479479b    wm_hubs_hpr_mux vmlinux EXPORT_SYMBOL_GPL
++0x49e22268    snd_soc_info_volsw_s8   vmlinux EXPORT_SYMBOL_GPL
++0x329aef1b    crypto_alloc_aead       vmlinux EXPORT_SYMBOL_GPL
++0x851d17d2    crypto_spawn_tfm2       vmlinux EXPORT_SYMBOL_GPL
++0xce6a9d9a    trace_current_buffer_discard_commit     vmlinux EXPORT_SYMBOL_GPL
++0x50fad434    round_jiffies_up        vmlinux EXPORT_SYMBOL_GPL
++0xf7f16b3f    input_get_new_minor     vmlinux EXPORT_SYMBOL
++0x26c90ea4    scsi_eh_get_sense       vmlinux EXPORT_SYMBOL_GPL
++0x75e49326    device_create_bin_file  vmlinux EXPORT_SYMBOL_GPL
++0x113c622e    dev_set_mac_address     vmlinux EXPORT_SYMBOL
++0xe13ad642    sk_receive_skb  vmlinux EXPORT_SYMBOL
++0xf5c05914    generic_segment_checks  vmlinux EXPORT_SYMBOL
++0xd0f36f0d    audit_log_format        vmlinux EXPORT_SYMBOL
++0xdbaf59ef    v4l2_m2m_mmap   vmlinux EXPORT_SYMBOL
++0xde520229    serio_open      vmlinux EXPORT_SYMBOL
++0xc5714a65    spi_master_suspend      vmlinux EXPORT_SYMBOL_GPL
++0x22b325d5    kd_mksound      vmlinux EXPORT_SYMBOL
++0x6d2fc5a6    net_namespace_list      vmlinux EXPORT_SYMBOL_GPL
++0x9f6381e8    sock_register   vmlinux EXPORT_SYMBOL
++0xf1806da9    idr_find_slowpath       vmlinux EXPORT_SYMBOL
++0x5ae5be44    lg_lock_init    vmlinux EXPORT_SYMBOL
++0x2d307e05    vb2_ioctl_qbuf  vmlinux EXPORT_SYMBOL_GPL
++0xaad6c827    serio_close     vmlinux EXPORT_SYMBOL
++0x8b092f05    loop_register_transfer  vmlinux EXPORT_SYMBOL
++0x3c967a5a    device_set_wakeup_enable        vmlinux EXPORT_SYMBOL_GPL
++0xc34b9b1f    regulator_get_bypass_regmap     vmlinux EXPORT_SYMBOL_GPL
++0xde9cc521    pinctrl_unregister      vmlinux EXPORT_SYMBOL_GPL
++0xd1c5bc52    __cfg80211_send_deauth  vmlinux EXPORT_SYMBOL
++0x126ad73c    inet6_register_protosw  vmlinux EXPORT_SYMBOL
++0x5ce3b588    nfnl_lock       vmlinux EXPORT_SYMBOL_GPL
++0xdc197993    netif_set_real_num_tx_queues    vmlinux EXPORT_SYMBOL
++0xd4d07dc9    netif_set_real_num_rx_queues    vmlinux EXPORT_SYMBOL
++0xbdc3f3e4    dev_set_group   vmlinux EXPORT_SYMBOL
++0xb4176982    proc_remove     vmlinux EXPORT_SYMBOL
++0x663e9182    end_buffer_async_write  vmlinux EXPORT_SYMBOL
++0x3d517179    phy_register_fixup_for_uid      vmlinux EXPORT_SYMBOL
++0xb4709322    scsi_dev_info_add_list  vmlinux EXPORT_SYMBOL
++0x9dd34b62    drm_mm_insert_node_in_range     vmlinux EXPORT_SYMBOL
++0x69b18f43    rfc1042_header  vmlinux EXPORT_SYMBOL
++0x50097088    security_tun_dev_free_security  vmlinux EXPORT_SYMBOL
++0x050c08c1    vfs_writev      vmlinux EXPORT_SYMBOL
++0xd6b5a293    iio_buffer_init vmlinux EXPORT_SYMBOL
++0x811e0359    sdio_get_host_pm_caps   vmlinux EXPORT_SYMBOL_GPL
++0x9062c322    ring_buffer_consume     vmlinux EXPORT_SYMBOL_GPL
++0x1c5b1f28    irq_free_descs  vmlinux EXPORT_SYMBOL_GPL
++0xf2791baa    cgroup_unload_subsys    vmlinux EXPORT_SYMBOL_GPL
++0xe43274bc    proc_dointvec   vmlinux EXPORT_SYMBOL
++0xe8948e95    mmc_stop_bkops  vmlinux EXPORT_SYMBOL
++0xa2a5fd77    inet_ehash_secret       vmlinux EXPORT_SYMBOL
++0x2363e5bf    __inet_lookup_established       vmlinux EXPORT_SYMBOL_GPL
++0x3eeb1d5e    netdev_alert    vmlinux EXPORT_SYMBOL
++0x26ad413b    netdev_has_any_upper_dev        vmlinux EXPORT_SYMBOL
++0x7604b234    udp_lib_rehash  vmlinux EXPORT_SYMBOL
++0x5e5d53d3    udp_lib_unhash  vmlinux EXPORT_SYMBOL
++0x2b12925d    cpumask_next_and        vmlinux EXPORT_SYMBOL
++0x05495392    hid_debug       vmlinux EXPORT_SYMBOL_GPL
++0x1d1ca867    pm_stay_awake   vmlinux EXPORT_SYMBOL_GPL
++0x8c1a19df    device_show_ulong       vmlinux EXPORT_SYMBOL_GPL
++0x46940ff4    set_ras_addr_hook       vmlinux EXPORT_SYMBOL_GPL
++0x6088da85    nf_hook_slow    vmlinux EXPORT_SYMBOL
++0xce5ac24f    zlib_inflate_workspacesize      vmlinux EXPORT_SYMBOL
++0x2e73d9a1    v4l2_chip_ident_i2c_client      vmlinux EXPORT_SYMBOL
++0x3783cdae    drm_open        vmlinux EXPORT_SYMBOL
++0x5404b1e7    tcp_recvmsg     vmlinux EXPORT_SYMBOL
++0x47b90df9    snd_pcm_limit_hw_rates  vmlinux EXPORT_SYMBOL
++0x63baba6b    irq_alloc_generic_chip  vmlinux EXPORT_SYMBOL_GPL
++0xace5c0fc    usb_bus_list    vmlinux EXPORT_SYMBOL_GPL
++0xe8b63ace    radix_tree_range_tag_if_tagged  vmlinux EXPORT_SYMBOL
++0x8d8b6353    proc_dointvec_userhz_jiffies    vmlinux EXPORT_SYMBOL
++0x7ec5c02b    console_start   vmlinux EXPORT_SYMBOL
++0x1a1aebf8    s3c_adc_start   vmlinux EXPORT_SYMBOL_GPL
++0xffc6c87a    drm_detect_monitor_audio        vmlinux EXPORT_SYMBOL
++0xe1371ad4    tcp_simple_retransmit   vmlinux EXPORT_SYMBOL
++0x0f18b144    inet_csk_bind_conflict  vmlinux EXPORT_SYMBOL_GPL
++0x708e56bd    xt_register_match       vmlinux EXPORT_SYMBOL
++0xf3526269    proc_set_user   vmlinux EXPORT_SYMBOL
++0x752dff9d    anon_inode_getfile      vmlinux EXPORT_SYMBOL_GPL
++0xcd10fb11    simple_dir_inode_operations     vmlinux EXPORT_SYMBOL
++0x708bd95d    irq_domain_xlate_onetwocell     vmlinux EXPORT_SYMBOL_GPL
++0x122043a8    of_find_node_with_property      vmlinux EXPORT_SYMBOL
++0xb3453966    vb2_fop_release vmlinux EXPORT_SYMBOL_GPL
++0x59dddb40    ump_dd_reference_add    vmlinux EXPORT_SYMBOL
++0xe8bcc079    snd_soc_codec_set_cache_io      vmlinux EXPORT_SYMBOL_GPL
++0x67ae5cfb    dmam_pool_create        vmlinux EXPORT_SYMBOL
++0x1e7f65cb    vb2_mmap        vmlinux EXPORT_SYMBOL_GPL
++0xb33ff162    __find_get_block        vmlinux EXPORT_SYMBOL
++0x23a997f4    dcache_dir_open vmlinux EXPORT_SYMBOL
++0x3f4547a7    put_unused_fd   vmlinux EXPORT_SYMBOL
++0xd2555f19    jiffies_64_to_clock_t   vmlinux EXPORT_SYMBOL
++0xef969c64    input_mt_get_slot_by_key        vmlinux EXPORT_SYMBOL
++0x2b547fec    genphy_suspend  vmlinux EXPORT_SYMBOL
++0x0a04ac5b    subsys_system_register  vmlinux EXPORT_SYMBOL_GPL
++0x919a5e62    inet6_lookup_listener   vmlinux EXPORT_SYMBOL_GPL
++0xece784c2    rb_first        vmlinux EXPORT_SYMBOL
++0xc72e1233    __trace_bprintk vmlinux EXPORT_SYMBOL_GPL
++0x6a5ecb18    unregister_module_notifier      vmlinux EXPORT_SYMBOL
++0x19f115c3    flush_delayed_work      vmlinux EXPORT_SYMBOL
++0xf82f5060    usbnet_read_cmd vmlinux EXPORT_SYMBOL_GPL
++0xf3e09d59    dev_pm_qos_expose_latency_limit vmlinux EXPORT_SYMBOL_GPL
++0xfc4cb906    exynos_drm_subdrv_unregister    vmlinux EXPORT_SYMBOL_GPL
++0x04911106    of_dma_simple_xlate     vmlinux EXPORT_SYMBOL_GPL
++0x7211e749    nf_conntrack_hash_check_insert  vmlinux EXPORT_SYMBOL_GPL
++0x68b80336    zero_fill_bio   vmlinux EXPORT_SYMBOL
++0xe83fad56    mmc_switch      vmlinux EXPORT_SYMBOL_GPL
++0xa5a8337c    scsi_cmd_print_sense_hdr        vmlinux EXPORT_SYMBOL
++0x8b08c5c1    unix_peer_get   vmlinux EXPORT_SYMBOL_GPL
++0xef3b173b    audit_log_task_info     vmlinux EXPORT_SYMBOL
++0xacc26098    iio_read_const_attr     vmlinux EXPORT_SYMBOL
++0x47d7d62e    mmc_resume_host vmlinux EXPORT_SYMBOL
++0x323758b8    v4l2_spi_subdev_init    vmlinux EXPORT_SYMBOL_GPL
++0xbaa5b6b2    bus_register    vmlinux EXPORT_SYMBOL_GPL
++0xf39ab86b    tcp_syn_ack_timeout     vmlinux EXPORT_SYMBOL
++0xe73dda41    __nf_ct_ext_add_length  vmlinux EXPORT_SYMBOL
++0xc4ff89ae    nf_log_unregister       vmlinux EXPORT_SYMBOL
++0xd8e38717    d_hash_and_lookup       vmlinux EXPORT_SYMBOL
++0x63193a50    generic_file_buffered_write     vmlinux EXPORT_SYMBOL
++0xcce7df45    iio_alloc_pollfunc      vmlinux EXPORT_SYMBOL_GPL
++0x24b0f90c    of_clk_get_by_name      vmlinux EXPORT_SYMBOL
++0x3fb35146    mmc_alloc_host  vmlinux EXPORT_SYMBOL
++0xe6099979    scsi_eh_ready_devs      vmlinux EXPORT_SYMBOL_GPL
++0x986e6135    fb_pad_unaligned_buffer vmlinux EXPORT_SYMBOL
++0xc1c2dd09    __hw_addr_flush vmlinux EXPORT_SYMBOL
++0xae249a24    snd_register_device_for_dev     vmlinux EXPORT_SYMBOL
++0xea054b22    nla_policy_len  vmlinux EXPORT_SYMBOL
++0xd92afabe    bitmap_clear    vmlinux EXPORT_SYMBOL
++0x80f48353    fsync_bdev      vmlinux EXPORT_SYMBOL
++0x71930ed3    of_property_read_string vmlinux EXPORT_SYMBOL_GPL
++0x570f339b    thermal_cooling_device_register vmlinux EXPORT_SYMBOL_GPL
++0xcfcdd86a    input_open_device       vmlinux EXPORT_SYMBOL
++0x84ac53cc    drm_fb_helper_single_add_all_connectors vmlinux EXPORT_SYMBOL
++0x0e3edf75    regulator_set_bypass_regmap     vmlinux EXPORT_SYMBOL_GPL
++0xfe990052    gpio_free       vmlinux EXPORT_SYMBOL_GPL
++0x0b63a348    cfg80211_wext_giwrange  vmlinux EXPORT_SYMBOL_GPL
++0x6d815a8f    ip6_dst_lookup  vmlinux EXPORT_SYMBOL_GPL
++0x40a9b349    vzalloc vmlinux EXPORT_SYMBOL
++0xc2f9c045    timespec_to_jiffies     vmlinux EXPORT_SYMBOL
++0x54159824    iio_push_event  vmlinux EXPORT_SYMBOL
++0x94f95b4e    i2c_new_device  vmlinux EXPORT_SYMBOL_GPL
++0xe04e6d60    device_for_each_child   vmlinux EXPORT_SYMBOL_GPL
++0x5eafb8e9    drm_mode_set_name       vmlinux EXPORT_SYMBOL
++0x3b0a974f    arm_iommu_release_mapping       vmlinux EXPORT_SYMBOL_GPL
++0xed76ba4a    hci_resume_dev  vmlinux EXPORT_SYMBOL
++0x9cfaab5e    media_device_unregister vmlinux EXPORT_SYMBOL_GPL
++0x5783d440    pm_generic_poweroff_late        vmlinux EXPORT_SYMBOL_GPL
++0x59c8991b    nci_allocate_device     vmlinux EXPORT_SYMBOL
++0x11089ac7    _ctype  vmlinux EXPORT_SYMBOL
++0x66d480cb    blk_get_queue   vmlinux EXPORT_SYMBOL
++0x60b78a66    bd_set_size     vmlinux EXPORT_SYMBOL
++0x71f34013    __mem_cgroup_count_vm_event     vmlinux EXPORT_SYMBOL
++0x2d45b494    pm_vt_switch_unregister vmlinux EXPORT_SYMBOL
++0xca7d8764    kthread_freezable_should_stop   vmlinux EXPORT_SYMBOL_GPL
++0x03b3002e    st_sensors_enable_events        vmlinux EXPORT_SYMBOL
++0xfc937fcb    usb_add_gadget_udc      vmlinux EXPORT_SYMBOL_GPL
++0x420323e6    i2c_dp_aux_add_bus      vmlinux EXPORT_SYMBOL
++0xd6ef94db    udp_proc_unregister     vmlinux EXPORT_SYMBOL
++0x37f614b7    __kfifo_len_r   vmlinux EXPORT_SYMBOL
++0xac6e0f5a    power_supply_get_by_name        vmlinux EXPORT_SYMBOL_GPL
++0x86047552    inet_sk_rebuild_header  vmlinux EXPORT_SYMBOL
++0x3c878c55    skb_copy        vmlinux EXPORT_SYMBOL
++0xe5b6e62e    snd_pcm_stop    vmlinux EXPORT_SYMBOL
++0x7593d385    div64_s64       vmlinux EXPORT_SYMBOL
++0x27864d57    memparse        vmlinux EXPORT_SYMBOL
++0xe8f9c617    block_truncate_page     vmlinux EXPORT_SYMBOL
++0xbc036e9e    generic_write_checks    vmlinux EXPORT_SYMBOL
++0x4f68e5c9    do_gettimeofday vmlinux EXPORT_SYMBOL
++0xa6715115    do_settimeofday vmlinux EXPORT_SYMBOL
++0xd9efbe4c    input_inject_event      vmlinux EXPORT_SYMBOL
++0x3dc565d9    drm_mm_insert_node_generic      vmlinux EXPORT_SYMBOL
++0x0c58a8cd    netdev_increment_features       vmlinux EXPORT_SYMBOL
++0xb3c487b6    uart_match_port vmlinux EXPORT_SYMBOL
++0x208f2017    brcmu_pktq_pdeq_match   drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0xbc455bde    cfg80211_pmksa_candidate_notify vmlinux EXPORT_SYMBOL
++0x3bef03b9    flow_cache_lookup       vmlinux EXPORT_SYMBOL
++0x5002ec2f    __splice_from_pipe      vmlinux EXPORT_SYMBOL
++0x863c552c    cache_firmware  vmlinux EXPORT_SYMBOL_GPL
++0xe5274b72    unregister_net_sysctl_table     vmlinux EXPORT_SYMBOL_GPL
++0xa197b1ff    ieee80211_get_mesh_hdrlen       vmlinux EXPORT_SYMBOL
++0x3a9592df    __nf_ct_ext_destroy     vmlinux EXPORT_SYMBOL
++0xa2c640f9    sysfs_add_file_to_group vmlinux EXPORT_SYMBOL_GPL
++0x487d9343    param_ops_ushort        vmlinux EXPORT_SYMBOL
++0x58804ca9    sdio_align_size vmlinux EXPORT_SYMBOL_GPL
++0xa09e1f4c    cpufreq_register_governor       vmlinux EXPORT_SYMBOL_GPL
++0x8ee7279a    ump_dd_size_get vmlinux EXPORT_SYMBOL
++0xfb858f46    tty_write_room  vmlinux EXPORT_SYMBOL
++0x3d715445    dev_trans_start vmlinux EXPORT_SYMBOL
++0xa381944f    dql_reset       vmlinux EXPORT_SYMBOL
++0x8f99ae4c    blk_register_region     vmlinux EXPORT_SYMBOL
++0xa8242495    bio_put vmlinux EXPORT_SYMBOL
++0x488d1fd7    task_tgid_nr_ns vmlinux EXPORT_SYMBOL
++0xc8d55b31    usb_unlocked_disable_lpm        vmlinux EXPORT_SYMBOL_GPL
++0x10ee20bb    default_blu     vmlinux EXPORT_SYMBOL
++0x57575f08    dmaengine_put   vmlinux EXPORT_SYMBOL
++0x60577ee3    ip6_expire_frag_queue   vmlinux EXPORT_SYMBOL
++0xdb5d34e0    rcu_batches_completed_preempt   vmlinux EXPORT_SYMBOL_GPL
++0xec6f4d80    each_symbol_section     vmlinux EXPORT_SYMBOL_GPL
++0xea6e3003    of_find_compatible_node vmlinux EXPORT_SYMBOL
++0x0d95dc3b    video_ioctl2    vmlinux EXPORT_SYMBOL
++0x26156aad    input_alloc_absinfo     vmlinux EXPORT_SYMBOL
++0x244b53b3    scsi_is_target_device   vmlinux EXPORT_SYMBOL
++0xd0cf28c6    sk_dst_check    vmlinux EXPORT_SYMBOL
++0xa5dd45f3    prandom_bytes_state     vmlinux EXPORT_SYMBOL
++0x6a76f3ac    blk_iopoll_enable       vmlinux EXPORT_SYMBOL
++0x17e1907b    inode_needs_sync        vmlinux EXPORT_SYMBOL
++0x9c6ac1ed    grab_cache_page_nowait  vmlinux EXPORT_SYMBOL
++0xe7a81967    audit_log_secctx        vmlinux EXPORT_SYMBOL
++0x2babe81f    __wake_up_sync_key      vmlinux EXPORT_SYMBOL_GPL
++0x4adaf0f3    v4l2_ctrl_query_menu_valid_items        vmlinux EXPORT_SYMBOL
++0xcb6f482d    dev_getfirstbyhwtype    vmlinux EXPORT_SYMBOL
++0xb23df37e    wake_up_process vmlinux EXPORT_SYMBOL
++0x25820c64    fs_overflowuid  vmlinux EXPORT_SYMBOL
++0x24ddf922    scsi_internal_device_block      vmlinux EXPORT_SYMBOL_GPL
++0x1079ac8f    drm_framebuffer_remove  vmlinux EXPORT_SYMBOL
++0x160f2f7e    of_phy_simple_xlate     vmlinux EXPORT_SYMBOL_GPL
++0xe669c8a2    __nf_ct_refresh_acct    vmlinux EXPORT_SYMBOL_GPL
++0xa2f20d05    skb_dequeue_tail        vmlinux EXPORT_SYMBOL
++0x19a025aa    __get_user_pages        vmlinux EXPORT_SYMBOL
++0x286acd69    free_css_id     vmlinux EXPORT_SYMBOL_GPL
++0x404c4f08    __module_address        vmlinux EXPORT_SYMBOL_GPL
++0x195d329a    hidinput_count_leds     vmlinux EXPORT_SYMBOL_GPL
++0x280c859a    input_ff_erase  vmlinux EXPORT_SYMBOL_GPL
++0x886d02da    scsi_target_resume      vmlinux EXPORT_SYMBOL
++0x8f31e347    inet_stream_ops vmlinux EXPORT_SYMBOL
++0x9b0dcfa2    qdisc_reset     vmlinux EXPORT_SYMBOL
++0xd2da1048    register_netdevice_notifier     vmlinux EXPORT_SYMBOL
++0x1b5fff19    blk_complete_request    vmlinux EXPORT_SYMBOL
++0x808ec1a3    crypto_alg_tested       vmlinux EXPORT_SYMBOL_GPL
++0xda920cd9    bio_unmap_user  vmlinux EXPORT_SYMBOL
++0xe769232e    sprint_symbol_no_offset vmlinux EXPORT_SYMBOL_GPL
++0x2b7a6de8    syscon_regmap_lookup_by_phandle vmlinux EXPORT_SYMBOL_GPL
++0x9728e93f    of_dma_controller_register      vmlinux EXPORT_SYMBOL_GPL
++0x1b61c5b3    pwm_config      vmlinux EXPORT_SYMBOL_GPL
++0x39bdf0f0    nci_free_device vmlinux EXPORT_SYMBOL
++0xe3a306b5    udp_seq_open    vmlinux EXPORT_SYMBOL
++0x38c97d50    idr_get_next    vmlinux EXPORT_SYMBOL
++0xeaacc92f    fail_migrate_page       vmlinux EXPORT_SYMBOL
++0x4cdb3178    ns_to_timeval   vmlinux EXPORT_SYMBOL
++0xc78d0953    ehci_init_driver        vmlinux EXPORT_SYMBOL_GPL
++0xcd6ff125    nf_ct_expect_register_notifier  vmlinux EXPORT_SYMBOL_GPL
++0x721b1851    skip_spaces     vmlinux EXPORT_SYMBOL
++0x0c0c015e    ring_buffer_swap_cpu    vmlinux EXPORT_SYMBOL_GPL
++0x76d451c4    add_taint       vmlinux EXPORT_SYMBOL
++0x1c2596ba    regmap_async_complete_cb        vmlinux EXPORT_SYMBOL_GPL
++0x60a32ea9    pm_power_off    vmlinux EXPORT_SYMBOL
++0x2b911208    __neigh_for_each_release        vmlinux EXPORT_SYMBOL
++0x0bc7e6ff    blk_queue_init_tags     vmlinux EXPORT_SYMBOL
++0xa666946b    bdget   vmlinux EXPORT_SYMBOL
++0x885a4cc9    bdput   vmlinux EXPORT_SYMBOL
++0x2517dbbb    fsstack_copy_inode_size vmlinux EXPORT_SYMBOL_GPL
++0x7d4ed855    iio_trigger_poll_chained        vmlinux EXPORT_SYMBOL
++0x561e4b77    irq_of_parse_and_map    vmlinux EXPORT_SYMBOL_GPL
++0x308efc55    spi_busnum_to_master    vmlinux EXPORT_SYMBOL_GPL
++0xe862c4b7    dpm_suspend_start       vmlinux EXPORT_SYMBOL_GPL
++0xd728282d    device_initialize       vmlinux EXPORT_SYMBOL_GPL
++0xf6b77868    nf_conntrack_untracked  vmlinux EXPORT_SYMBOL
++0xed9f8e6d    kstrtos16       vmlinux EXPORT_SYMBOL
++0xfb32b30f    ring_buffer_read_prepare_sync   vmlinux EXPORT_SYMBOL_GPL
++0x846bcc01    dm_table_get    vmlinux EXPORT_SYMBOL
++0x1416333b    tcf_em_register vmlinux EXPORT_SYMBOL
++0x19546cac    snd_soc_cache_read      vmlinux EXPORT_SYMBOL_GPL
++0xfd2f4f20    snd_soc_info_volsw_ext  vmlinux EXPORT_SYMBOL_GPL
++0x6c749afe    __tracepoint_block_unplug       vmlinux EXPORT_SYMBOL_GPL
++0x9c86ede0    fs_kobj vmlinux EXPORT_SYMBOL_GPL
++0x796c2d48    dm_get_md       vmlinux EXPORT_SYMBOL_GPL
++0xf8fbb4f0    __bad_xchg      vmlinux EXPORT_SYMBOL
++0xc40f284c    nf_ct_helper_hsize      vmlinux EXPORT_SYMBOL_GPL
++0x24428be5    strncpy_from_user       vmlinux EXPORT_SYMBOL
++0x6d74d462    crypto_alloc_ablkcipher vmlinux EXPORT_SYMBOL_GPL
++0x0b96efa8    bio_init        vmlinux EXPORT_SYMBOL
++0x7278d328    all_vm_events   vmlinux EXPORT_SYMBOL_GPL
++0x41814cb8    dirty_writeback_interval        vmlinux EXPORT_SYMBOL_GPL
++0x1c32da2a    iio_enum_available_read vmlinux EXPORT_SYMBOL_GPL
++0xcda91c46    drm_mode_debug_printmodeline    vmlinux EXPORT_SYMBOL
++0xa9cae71a    inet6_hash_connect      vmlinux EXPORT_SYMBOL_GPL
++0x92f5d840    gnet_stats_copy_rate_est        vmlinux EXPORT_SYMBOL
++0x17f61c70    skb_partial_csum_set    vmlinux EXPORT_SYMBOL_GPL
++0xb86cf818    create_empty_buffers    vmlinux EXPORT_SYMBOL
++0x26332c2f    init_special_inode      vmlinux EXPORT_SYMBOL
++0xd0720a17    on_each_cpu_cond        vmlinux EXPORT_SYMBOL
++0x870713f0    iommu_detach_group      vmlinux EXPORT_SYMBOL_GPL
++0x00c8b1c1    sdio_enable_func        vmlinux EXPORT_SYMBOL_GPL
++0x22f907ec    pm_runtime_no_callbacks vmlinux EXPORT_SYMBOL_GPL
++0x8d4234e8    subsys_dev_iter_next    vmlinux EXPORT_SYMBOL_GPL
++0x706fc943    mali_pmu_powerup        vmlinux EXPORT_SYMBOL
++0xf24fbd54    cfg80211_mgmt_tx_status vmlinux EXPORT_SYMBOL
++0xa8bae0ab    inet_frag_destroy       vmlinux EXPORT_SYMBOL
++0xca1aff2d    ipv4_sk_update_pmtu     vmlinux EXPORT_SYMBOL_GPL
++0x539973c5    skb_make_writable       vmlinux EXPORT_SYMBOL
++0x2eeceb42    sk_chk_filter   vmlinux EXPORT_SYMBOL
++0x8f595b11    snd_major       vmlinux EXPORT_SYMBOL
++0xf8433bfd    pipe_to_file    vmlinux EXPORT_SYMBOL
++0x0dc1d65b    __dec_zone_page_state   vmlinux EXPORT_SYMBOL
++0x95ce193b    __inc_zone_page_state   vmlinux EXPORT_SYMBOL
++0x736c2d7c    __mod_zone_page_state   vmlinux EXPORT_SYMBOL
++0xab6babaf    pm_qos_request  vmlinux EXPORT_SYMBOL_GPL
++0xeed6cc4b    flush_kthread_worker    vmlinux EXPORT_SYMBOL_GPL
++0xa5cef8ad    release_resource        vmlinux EXPORT_SYMBOL
++0x4584b8a3    iio_push_to_buffers     vmlinux EXPORT_SYMBOL_GPL
++0xc79bcd36    dm_vcalloc      vmlinux EXPORT_SYMBOL
++0xa7dd8c46    ump_dd_phys_block_get   vmlinux EXPORT_SYMBOL
++0x83bd3297    brioctl_set     vmlinux EXPORT_SYMBOL
++0x09e913c1    snd_pcm_alt_chmaps      vmlinux EXPORT_SYMBOL_GPL
++0xbf33e600    vm_insert_pfn   vmlinux EXPORT_SYMBOL
++0xda050109    irq_domain_add_nomap    vmlinux EXPORT_SYMBOL_GPL
++0xfcaa04a0    out_of_line_wait_on_bit_lock    vmlinux EXPORT_SYMBOL
++0xa7bb71ae    input_set_abs_params    vmlinux EXPORT_SYMBOL
++0x22f9a7f4    spi_bus_unlock  vmlinux EXPORT_SYMBOL_GPL
++0x2ea5ad9c    device_schedule_callback_owner  vmlinux EXPORT_SYMBOL_GPL
++0x4c511235    drm_edid_is_valid       vmlinux EXPORT_SYMBOL
++0x3939f8f0    rfkill_pause_polling    vmlinux EXPORT_SYMBOL
++0xebc7bcd9    xfrm_state_alloc        vmlinux EXPORT_SYMBOL
++0x85670f1d    rtnl_is_locked  vmlinux EXPORT_SYMBOL
++0x726d45d3    fat_remove_entries      vmlinux EXPORT_SYMBOL_GPL
++0xd963ea55    page_symlink    vmlinux EXPORT_SYMBOL
++0xa26d9b4f    workqueue_congested     vmlinux EXPORT_SYMBOL_GPL
++0xf7cd6b11    freq_reg_info   vmlinux EXPORT_SYMBOL
++0x764dafa5    __xfrm_route_forward    vmlinux EXPORT_SYMBOL
++0xd317cce2    snd_soc_put_volsw_sx    vmlinux EXPORT_SYMBOL_GPL
++0x587ba0c8    snd_soc_get_volsw_s8    vmlinux EXPORT_SYMBOL_GPL
++0x5dda7051    snd_soc_put_volsw_s8    vmlinux EXPORT_SYMBOL_GPL
++0xd6b61c7b    snd_soc_get_volsw_sx    vmlinux EXPORT_SYMBOL_GPL
++0x9f0664bf    dm_get_queue_limits     vmlinux EXPORT_SYMBOL_GPL
++0x0364983f    gen_replace_estimator   vmlinux EXPORT_SYMBOL
++0x2f03fc4b    security_secmark_refcount_inc   vmlinux EXPORT_SYMBOL
++0x19bd383b    security_secmark_refcount_dec   vmlinux EXPORT_SYMBOL
++0xc22b50ad    param_set_bint  vmlinux EXPORT_SYMBOL
++0x21315700    param_get_bool  vmlinux EXPORT_SYMBOL
++0x3eae292f    param_set_byte  vmlinux EXPORT_SYMBOL
++0xcea1a019    dw_mci_suspend  vmlinux EXPORT_SYMBOL
++0x8657c2d4    spi_bitbang_setup       vmlinux EXPORT_SYMBOL_GPL
++0xb13fbb9a    scsi_target_unblock     vmlinux EXPORT_SYMBOL_GPL
++0xbf3a015f    brcmf_sdio_remove       drivers/net/wireless/brcm80211/brcmfmac/brcmfmac        EXPORT_SYMBOL
++0xeb1c3628    nf_ipv6_ops     vmlinux EXPORT_SYMBOL_GPL
++0x9fdecc31    unregister_netdevice_many       vmlinux EXPORT_SYMBOL
++0x75308bb0    blk_queue_logical_block_size    vmlinux EXPORT_SYMBOL
++0x2fe50bdf    init_srcu_struct        vmlinux EXPORT_SYMBOL_GPL
++0xfba64859    rtc_device_unregister   vmlinux EXPORT_SYMBOL_GPL
++0xbd10afa1    drm_platform_init       vmlinux EXPORT_SYMBOL
++0xa1ceb496    drm_platform_exit       vmlinux EXPORT_SYMBOL
++0xd10d7d37    arp_tbl vmlinux EXPORT_SYMBOL
++0x9aa6cefb    __skb_recv_datagram     vmlinux EXPORT_SYMBOL
++0x0430401c    snd_soc_remove_platform vmlinux EXPORT_SYMBOL_GPL
++0xfe7c4287    nr_cpu_ids      vmlinux EXPORT_SYMBOL
++0x18b6fa40    v4l2_ctrl_add_ctrl      vmlinux EXPORT_SYMBOL
++0xb21d34e2    phy_attach      vmlinux EXPORT_SYMBOL
++0x67f7fd01    gpiochip_remove_pin_ranges      vmlinux EXPORT_SYMBOL_GPL
++0x5c9284a0    processor_id    vmlinux EXPORT_SYMBOL
++0x688e3c72    tcp_splice_read vmlinux EXPORT_SYMBOL
++0x9f7f32fe    xt_unregister_match     vmlinux EXPORT_SYMBOL
++0x2822f8fe    irq_setup_generic_chip  vmlinux EXPORT_SYMBOL_GPL
++0x8763d790    pm_genpd_syscore_switch vmlinux EXPORT_SYMBOL_GPL
++0xc898f9f7    css_depth       vmlinux EXPORT_SYMBOL_GPL
++0x95d97984    devm_regmap_init_spi    vmlinux EXPORT_SYMBOL_GPL
++0x32108723    devm_regmap_init_i2c    vmlinux EXPORT_SYMBOL_GPL
++0x824028e1    drm_master_get  vmlinux EXPORT_SYMBOL
++0x36e360e3    __hw_addr_add_multiple  vmlinux EXPORT_SYMBOL
++0x92e42550    snd_soc_jack_add_gpios  vmlinux EXPORT_SYMBOL_GPL
++0x9552bd34    crypto_unregister_algs  vmlinux EXPORT_SYMBOL_GPL
++0x70bd3119    simple_transaction_set  vmlinux EXPORT_SYMBOL
++0x5cf1e7e1    simple_transaction_get  vmlinux EXPORT_SYMBOL
++0x86b57862    find_pid_ns     vmlinux EXPORT_SYMBOL_GPL
++0x0b59c21c    st_gyro_common_probe    vmlinux EXPORT_SYMBOL
++0x3a4c6000    of_irq_to_resource      vmlinux EXPORT_SYMBOL_GPL
++0xcbc9557f    unregister_sysrq_key    vmlinux EXPORT_SYMBOL
++0xd85ac634    regulator_put   vmlinux EXPORT_SYMBOL_GPL
++0x56e75d47    klist_node_attached     vmlinux EXPORT_SYMBOL_GPL
++0xf0d6c49d    rfkill_alloc    vmlinux EXPORT_SYMBOL
++0xe118d3ca    __nf_conntrack_find     vmlinux EXPORT_SYMBOL_GPL
++0x67fa9d64    __nlmsg_put     vmlinux EXPORT_SYMBOL
++0xc5f839f2    lock_sock_nested        vmlinux EXPORT_SYMBOL
++0x92b57248    flush_work      vmlinux EXPORT_SYMBOL_GPL
++0x63aecd53    hid_add_device  vmlinux EXPORT_SYMBOL_GPL
++0x870e11ef    sdio_disable_func       vmlinux EXPORT_SYMBOL_GPL
++0xd6c99af7    devm_usb_put_phy        vmlinux EXPORT_SYMBOL_GPL
++0x60652b23    usbnet_cdc_bind vmlinux EXPORT_SYMBOL_GPL
++0x0f1fd032    scsi_free_command       vmlinux EXPORT_SYMBOL
++0x150d593e    platform_add_devices    vmlinux EXPORT_SYMBOL_GPL
++0xdc2235fd    device_show_bool        vmlinux EXPORT_SYMBOL_GPL
++0xe800ece3    __mmc_switch    vmlinux EXPORT_SYMBOL_GPL
++0x8650b7ba    usb_deregister  vmlinux EXPORT_SYMBOL_GPL
++0x83a82050    phy_ethtool_get_eee     vmlinux EXPORT_SYMBOL
++0xccb94d1a    phy_ethtool_set_eee     vmlinux EXPORT_SYMBOL
++0x1a81168a    drm_mm_dump_table       vmlinux EXPORT_SYMBOL
++0x04cda566    snd_interval_refine     vmlinux EXPORT_SYMBOL
++0x6b2dc060    dump_stack      vmlinux EXPORT_SYMBOL
++0x23476dca    crypto_alloc_instance   vmlinux EXPORT_SYMBOL_GPL
++0x31cd11aa    mpage_writepage vmlinux EXPORT_SYMBOL
++0xa219c44e    try_to_writeback_inodes_sb_nr   vmlinux EXPORT_SYMBOL
++0xd942d353    ring_buffer_record_off  vmlinux EXPORT_SYMBOL_GPL
++0x178768e1    set_security_override   vmlinux EXPORT_SYMBOL
++0x7930d225    of_device_is_compatible vmlinux EXPORT_SYMBOL
++0xa1fb703c    drm_mm_remove_node      vmlinux EXPORT_SYMBOL
++0x3fce0784    rdev_get_drvdata        vmlinux EXPORT_SYMBOL_GPL
++0x193f9832    nfc_allocate_device     vmlinux EXPORT_SYMBOL
++0xcefba9ae    raw_seq_start   vmlinux EXPORT_SYMBOL_GPL
++0x353b4dcf    nfnetlink_subsys_unregister     vmlinux EXPORT_SYMBOL_GPL
++0x1db53c10    dst_cow_metrics_generic vmlinux EXPORT_SYMBOL
++0x884c205c    mount_ns        vmlinux EXPORT_SYMBOL
++0x26b0e339    sdhci_disable_irq_wakeups       vmlinux EXPORT_SYMBOL_GPL
++0x69e3154c    rtc_read_time   vmlinux EXPORT_SYMBOL_GPL
++0xde6ff4ec    usb_get_function_instance       vmlinux EXPORT_SYMBOL_GPL
++0x0c29207f    netdev_master_upper_dev_get     vmlinux EXPORT_SYMBOL
++0x62d34ec2    kobject_del     vmlinux EXPORT_SYMBOL
++0x7489664f    crypto_unregister_shash vmlinux EXPORT_SYMBOL_GPL
++0x5ca7f0f8    crypto_unregister_ahash vmlinux EXPORT_SYMBOL_GPL
++0x86a4889a    kmalloc_order_trace     vmlinux EXPORT_SYMBOL
++0x0698cb23    drm_core_reclaim_buffers        vmlinux EXPORT_SYMBOL
++0x94478b76    nat_callforwarding_hook vmlinux EXPORT_SYMBOL_GPL
++0x6e4b8906    snd_ctl_find_numid      vmlinux EXPORT_SYMBOL
++0xb6a68816    find_last_bit   vmlinux EXPORT_SYMBOL
++0xc8d47bdb    inode_dio_done  vmlinux EXPORT_SYMBOL
++0xb9ca066f    poll_initwait   vmlinux EXPORT_SYMBOL
++0x193d48e0    trace_current_buffer_unlock_commit      vmlinux EXPORT_SYMBOL_GPL
++0x46a36032    unregister_console      vmlinux EXPORT_SYMBOL
++0xd0fbc335    vb2_get_vma     vmlinux EXPORT_SYMBOL_GPL
++0x6ebd302d    usb_reset_endpoint      vmlinux EXPORT_SYMBOL_GPL
++0x38a4f7ae    drm_format_num_planes   vmlinux EXPORT_SYMBOL
++0xc414c422    drm_vblank_offdelay     vmlinux EXPORT_SYMBOL
++0x96554810    register_keyboard_notifier      vmlinux EXPORT_SYMBOL_GPL
++0x2ec0f25c    nf_ct_helper_ext_add    vmlinux EXPORT_SYMBOL_GPL
++0xe745ec59    aead_geniv_free vmlinux EXPORT_SYMBOL_GPL
++0xd8e484f0    register_chrdev_region  vmlinux EXPORT_SYMBOL
++0xc58b6dd5    led_trigger_unregister_simple   vmlinux EXPORT_SYMBOL_GPL
++0x068f1d12    phy_disconnect  vmlinux EXPORT_SYMBOL
++0x9c518b55    regmap_update_bits      vmlinux EXPORT_SYMBOL_GPL
++0xc63f1b81    ieee80211_radiotap_iterator_next        vmlinux EXPORT_SYMBOL
++0x9744e080    inet_csk_reqsk_queue_prune      vmlinux EXPORT_SYMBOL_GPL
++0xb9ff0fd7    netdev_state_change     vmlinux EXPORT_SYMBOL
++0x310917fe    sort    vmlinux EXPORT_SYMBOL
++0xa8fef7bb    security_unix_may_send  vmlinux EXPORT_SYMBOL
++0x541bd60a    irq_work_run    vmlinux EXPORT_SYMBOL_GPL
++0x6c49c4f2    clockevents_notify      vmlinux EXPORT_SYMBOL_GPL
++0xe208ea98    hci_recv_stream_fragment        vmlinux EXPORT_SYMBOL
++0xe6c68334    ddebug_remove_module    vmlinux EXPORT_SYMBOL_GPL
++0xf8ae0cbf    kern_path       vmlinux EXPORT_SYMBOL
++0x6e9dd7bc    usb_sg_cancel   vmlinux EXPORT_SYMBOL_GPL
++0x7c05fd17    nf_register_queue_handler       vmlinux EXPORT_SYMBOL
++0x2a8db409    snd_soc_dai_set_tristate        vmlinux EXPORT_SYMBOL_GPL
++0x29b1c366    __sg_alloc_table        vmlinux EXPORT_SYMBOL
++0x9c3889f4    shrink_dcache_sb        vmlinux EXPORT_SYMBOL
++0x15692c87    param_ops_int   vmlinux EXPORT_SYMBOL
++0xd04e04f7    iio_update_demux        vmlinux EXPORT_SYMBOL_GPL
++0x105a7a58    dma_alloc_from_coherent vmlinux EXPORT_SYMBOL
++0xe4309905    syscore_resume  vmlinux EXPORT_SYMBOL_GPL
++0xab482a65    blkdev_issue_flush      vmlinux EXPORT_SYMBOL
++0x499043d3    crypto_init_queue       vmlinux EXPORT_SYMBOL_GPL
++0xca871be2    default_backing_dev_info        vmlinux EXPORT_SYMBOL_GPL
++0x3d5120d1    st_accel_common_probe   vmlinux EXPORT_SYMBOL
++0x44f5e8b5    of_allnodes     vmlinux EXPORT_SYMBOL
++0xf563353a    v4l2_subdev_link_validate       vmlinux EXPORT_SYMBOL_GPL
++0x011cf028    regulator_suspend_finish        vmlinux EXPORT_SYMBOL_GPL
++0x1b88e3fa    find_inode_number       vmlinux EXPORT_SYMBOL
++0xb2d307de    param_ops_short vmlinux EXPORT_SYMBOL
++0x0b586662    drm_gem_object_init     vmlinux EXPORT_SYMBOL
++0xaad6d92f    rfkill_init_sw_state    vmlinux EXPORT_SYMBOL
++0x4f4d4dc8    hci_unregister_dev      vmlinux EXPORT_SYMBOL
++0xa6970398    __kfifo_to_user_r       vmlinux EXPORT_SYMBOL
++0xf7f92f26    st_sensors_set_enable   vmlinux EXPORT_SYMBOL
++0x236bcb52    unregister_con_driver   vmlinux EXPORT_SYMBOL
++0x39898017    amba_device_put vmlinux EXPORT_SYMBOL_GPL
++0x8d28fc98    amba_device_add vmlinux EXPORT_SYMBOL_GPL
++0x3169d518    softnet_data    vmlinux EXPORT_SYMBOL
++0x5fc56a46    _raw_spin_unlock        vmlinux EXPORT_SYMBOL
++0xfe5d4bb2    sys_tz  vmlinux EXPORT_SYMBOL
++0x81ced62d    ip6_sk_redirect vmlinux EXPORT_SYMBOL_GPL
++0x9ffa3a75    netdev_max_backlog      vmlinux EXPORT_SYMBOL
++0xfa237e15    __skb_tx_hash   vmlinux EXPORT_SYMBOL
++0x1b701804    blk_init_queue  vmlinux EXPORT_SYMBOL
++0x474d3122    unlock_page     vmlinux EXPORT_SYMBOL
++0x4f98d766    cpu_pm_unregister_notifier      vmlinux EXPORT_SYMBOL_GPL
++0x76963409    lock_fb_info    vmlinux EXPORT_SYMBOL
++0x11e2ec12    flex_array_free_parts   vmlinux EXPORT_SYMBOL
++0x5ecb52ac    sdio_memcpy_fromio      vmlinux EXPORT_SYMBOL_GPL
++0xa4480afe    drm_sysfs_hotplug_event vmlinux EXPORT_SYMBOL
++0xeaab7f82    lcd_device_register     vmlinux EXPORT_SYMBOL
++0x0c12eee9    xfrm_unregister_type    vmlinux EXPORT_SYMBOL
++0x297f1a00    nf_ip_checksum  vmlinux EXPORT_SYMBOL
++0xd14bc4d9    sock_diag_save_cookie   vmlinux EXPORT_SYMBOL_GPL
++0xdd810ba9    snd_info_register       vmlinux EXPORT_SYMBOL
++0x773a9c94    blk_iopoll_enabled      vmlinux EXPORT_SYMBOL
++0xd704f458    jbd2_log_wait_commit    vmlinux EXPORT_SYMBOL
++0x22e82b9e    hrtimer_init_sleeper    vmlinux EXPORT_SYMBOL_GPL
++0x437e0518    eth_rebuild_header      vmlinux EXPORT_SYMBOL
++0x47fb2e90    neigh_compat_output     vmlinux EXPORT_SYMBOL
++0x0283dfe3    _snd_pcm_hw_params_any  vmlinux EXPORT_SYMBOL
++0xe2407fb6    user_path_at    vmlinux EXPORT_SYMBOL
++0x35d93ce8    cgroup_add_cftypes      vmlinux EXPORT_SYMBOL_GPL
++0x4ac62273    module_put      vmlinux EXPORT_SYMBOL
++0x2459bbcc    console_set_on_cmdline  vmlinux EXPORT_SYMBOL
++0xbec530ad    max8997_update_reg      vmlinux EXPORT_SYMBOL_GPL
++0x3255972d    hdmi_vendor_infoframe_pack      vmlinux EXPORT_SYMBOL
++0x8da61397    ip_tunnel_rcv   vmlinux EXPORT_SYMBOL_GPL
++0x3c44f68c    inode_get_bytes vmlinux EXPORT_SYMBOL
++0xd85cd67e    __wake_up       vmlinux EXPORT_SYMBOL
++0xcefe5c3b    usb_get_from_anchor     vmlinux EXPORT_SYMBOL_GPL
++0x9a858808    genphy_resume   vmlinux EXPORT_SYMBOL
++0x606ae2bc    drm_mm_debug_table      vmlinux EXPORT_SYMBOL
++0xed636ddf    nf_conntrack_helper_unregister  vmlinux EXPORT_SYMBOL_GPL
++0xc7a1840e    llist_add_batch vmlinux EXPORT_SYMBOL_GPL
++0x2787db00    vbin_printf     vmlinux EXPORT_SYMBOL_GPL
++0xfe59fc1b    security_d_instantiate  vmlinux EXPORT_SYMBOL
++0x6b8286e4    bio_reset       vmlinux EXPORT_SYMBOL
++0x86414ad5    vfs_mkdir       vmlinux EXPORT_SYMBOL
++0x87b883c7    i2c_for_each_dev        vmlinux EXPORT_SYMBOL_GPL
++0x26f81b6a    dev_driver_string       vmlinux EXPORT_SYMBOL
++0x1c787b32    eventfd_ctx_fileget     vmlinux EXPORT_SYMBOL_GPL
++0x01139ffc    max_mapnr       vmlinux EXPORT_SYMBOL
++0xec17ebb0    of_match_node   vmlinux EXPORT_SYMBOL
++0x69ce0071    usb_driver_claim_interface      vmlinux EXPORT_SYMBOL_GPL
++0x9cfd56c5    scsi_print_status       vmlinux EXPORT_SYMBOL
++0xdce6abcd    drm_gem_prime_handle_to_fd      vmlinux EXPORT_SYMBOL
++0x020f03b7    drm_sysfs_connector_remove      vmlinux EXPORT_SYMBOL
++0x2a8aa04e    pinctrl_add_gpio_range  vmlinux EXPORT_SYMBOL_GPL
++0x981dcc58    eventfd_fget    vmlinux EXPORT_SYMBOL_GPL
++0x7c995f04    dget_parent     vmlinux EXPORT_SYMBOL
++0x9a932b80    of_find_i2c_device_by_node      vmlinux EXPORT_SYMBOL
++0x2b460363    led_trigger_set vmlinux EXPORT_SYMBOL_GPL
++0x107733e3    wiphy_new       vmlinux EXPORT_SYMBOL
++0xd7b7598e    snd_pcm_mmap_data       vmlinux EXPORT_SYMBOL
++0x4e1636f1    mb_cache_create vmlinux EXPORT_SYMBOL
++0x70bec618    iunique vmlinux EXPORT_SYMBOL
++0x121d958a    unregister_die_notifier vmlinux EXPORT_SYMBOL_GPL
++0xbef4c852    hid_dump_input  vmlinux EXPORT_SYMBOL_GPL
++0x55423fc4    dm_requeue_unmapped_request     vmlinux EXPORT_SYMBOL_GPL
++0x2e67fc27    matrix_keypad_build_keymap      vmlinux EXPORT_SYMBOL
++0xe7c7c6b0    usb_disable_autosuspend vmlinux EXPORT_SYMBOL_GPL
++0x783194cd    usb_get_dev     vmlinux EXPORT_SYMBOL_GPL
++0x5614b010    xfrm_policy_walk_done   vmlinux EXPORT_SYMBOL
++0x6d5a6c10    inet_dgram_ops  vmlinux EXPORT_SYMBOL
++0x42e7ca3d    blk_alloc_queue vmlinux EXPORT_SYMBOL
++0xfdbd0a9b    mb_cache_destroy        vmlinux EXPORT_SYMBOL
++0x59cbc3ca    input_release_device    vmlinux EXPORT_SYMBOL
++0xd0e5d6d2    scsi_put_command        vmlinux EXPORT_SYMBOL
++0x480dca40    sec_reg_update  vmlinux EXPORT_SYMBOL_GPL
++0x28a73d8e    snd_soc_unregister_card vmlinux EXPORT_SYMBOL_GPL
++0x05fc144e    get_gendisk     vmlinux EXPORT_SYMBOL
++0xfef8a166    trace_current_buffer_lock_reserve       vmlinux EXPORT_SYMBOL_GPL
++0x7dccc294    proc_doulongvec_minmax  vmlinux EXPORT_SYMBOL
++0x92c0c538    ieee80211_bss_get_ie    vmlinux EXPORT_SYMBOL
++0x386ec802    tcp_proc_unregister     vmlinux EXPORT_SYMBOL
++0xb327256f    simple_attr_open        vmlinux EXPORT_SYMBOL_GPL
++0x56e9103b    cpu_pm_enter    vmlinux EXPORT_SYMBOL_GPL
++0x1e48b59d    __css_tryget    vmlinux EXPORT_SYMBOL_GPL
++0xbcbaa80a    __wake_up_locked_key    vmlinux EXPORT_SYMBOL_GPL
++0x2d1b02d2    usermodehelper_read_lock_wait   vmlinux EXPORT_SYMBOL_GPL
++0x72bfae4f    hwmon_device_register   vmlinux EXPORT_SYMBOL_GPL
++0x3db7f213    v4l2_of_get_remote_port vmlinux EXPORT_SYMBOL
++0x5de3f132    usb_interface_id        vmlinux EXPORT_SYMBOL_GPL
++0x9ca5592b    usb_store_new_id        vmlinux EXPORT_SYMBOL_GPL
++0x90fb0fa6    sdev_evt_send_simple    vmlinux EXPORT_SYMBOL_GPL
++0x25892d59    drm_vblank_post_modeset vmlinux EXPORT_SYMBOL
++0x8ecafd4a    drm_fb_helper_blank     vmlinux EXPORT_SYMBOL
++0x590d45c1    sk_clear_memalloc       vmlinux EXPORT_SYMBOL_GPL
++0x4578f528    __kfifo_to_user vmlinux EXPORT_SYMBOL
++0xf7ddfd4e    done_path_create        vmlinux EXPORT_SYMBOL
++0x85c10896    rcu_batches_completed_bh        vmlinux EXPORT_SYMBOL_GPL
++0x036dd11a    cgroup_path     vmlinux EXPORT_SYMBOL_GPL
++0xcc7fa952    local_bh_enable_ip      vmlinux EXPORT_SYMBOL
++0xa90054ee    rndis_uninit    vmlinux EXPORT_SYMBOL
++0x15407a03    usb_root_hub_lost_power vmlinux EXPORT_SYMBOL_GPL
++0x06fc143d    xfrm4_rcv_encap vmlinux EXPORT_SYMBOL
++0xa0c5538e    udp_poll        vmlinux EXPORT_SYMBOL
++0xd9f41f16    skb_copy_ubufs  vmlinux EXPORT_SYMBOL_GPL
++0xc83b4d5b    posix_acl_from_mode     vmlinux EXPORT_SYMBOL
++0x51ef33b8    kstrndup        vmlinux EXPORT_SYMBOL
++0x0bed814c    irq_set_chip    vmlinux EXPORT_SYMBOL
++0xd0f6cf25    console_stop    vmlinux EXPORT_SYMBOL
++0xd955eb7d    iommu_group_remove_device       vmlinux EXPORT_SYMBOL_GPL
++0xfb5dc251    gserial_disconnect      vmlinux EXPORT_SYMBOL_GPL
++0x42252607    inet6_getname   vmlinux EXPORT_SYMBOL
++0xe65b1e97    nf_conntrack_tuple_taken        vmlinux EXPORT_SYMBOL_GPL
++0x7abbee1e    wm_hubs_handle_analogue_pdata   vmlinux EXPORT_SYMBOL_GPL
++0x06dceffb    snd_soc_of_parse_daifmt vmlinux EXPORT_SYMBOL_GPL
++0xf4439247    snd_device_register     vmlinux EXPORT_SYMBOL
++0xebcea57f    evict_bh_lrus   vmlinux EXPORT_SYMBOL_GPL
++0x9714253c    mfd_add_devices vmlinux EXPORT_SYMBOL
++0x26256356    drm_mode_equal_no_clocks        vmlinux EXPORT_SYMBOL
++0x1be7f7c8    debugfs_create_file     vmlinux EXPORT_SYMBOL_GPL
++0xdbb607c7    new_inode       vmlinux EXPORT_SYMBOL
++0xa576c92e    drm_mode_config_reset   vmlinux EXPORT_SYMBOL
++0x832ca829    snd_ctl_find_id vmlinux EXPORT_SYMBOL
++0x65dccf13    xz_dec_end      vmlinux EXPORT_SYMBOL
++0xf9348cbc    xz_dec_run      vmlinux EXPORT_SYMBOL
++0xe0b13336    argv_free       vmlinux EXPORT_SYMBOL
++0x8815b870    jbd2_journal_clear_err  vmlinux EXPORT_SYMBOL
++0x861359ed    of_get_phy_mode vmlinux EXPORT_SYMBOL_GPL
++0x28a2ed02    scsi_build_sense_buffer vmlinux EXPORT_SYMBOL
++0x86240fb6    tty_port_close  vmlinux EXPORT_SYMBOL
++0x8d3e24c6    genl_unregister_family  vmlinux EXPORT_SYMBOL
++0x9d0d6206    unregister_netdevice_notifier   vmlinux EXPORT_SYMBOL
++0x18640d1b    mmc_suspend_host        vmlinux EXPORT_SYMBOL
++0x9082ce2b    tty_register_driver     vmlinux EXPORT_SYMBOL
++0x71f65175    hdmi_spd_infoframe_pack vmlinux EXPORT_SYMBOL
++0x3d6f0d06    ndo_dflt_fdb_del        vmlinux EXPORT_SYMBOL
++0xaeefbeed    kset_unregister vmlinux EXPORT_SYMBOL
++0xa498b92e    debugfs_create_u32      vmlinux EXPORT_SYMBOL_GPL
++0x7ed8eb88    sdio_release_host       vmlinux EXPORT_SYMBOL_GPL
++0xd1e4eed4    v4l2_fh_init    vmlinux EXPORT_SYMBOL_GPL
++0x5b42ed42    v4l2_fh_exit    vmlinux EXPORT_SYMBOL_GPL
++0x5947abbe    max77693_bulk_write     vmlinux EXPORT_SYMBOL_GPL
++0x7afa1fc2    driver_remove_file      vmlinux EXPORT_SYMBOL_GPL
++0xacefc84d    netdev_rx_handler_register      vmlinux EXPORT_SYMBOL_GPL
++0xd2e829b5    jbd2_journal_release_jbd_inode  vmlinux EXPORT_SYMBOL
++0xcd343f41    mmc_gpio_free_ro        vmlinux EXPORT_SYMBOL
++0x26f37f1a    inet_csk_reset_keepalive_timer  vmlinux EXPORT_SYMBOL
++0x49603fb8    security_sb_copy_data   vmlinux EXPORT_SYMBOL
++0x53326531    mempool_alloc_pages     vmlinux EXPORT_SYMBOL
++0x2b49351d    trace_define_field      vmlinux EXPORT_SYMBOL_GPL
++0x47939e0d    __tasklet_hi_schedule   vmlinux EXPORT_SYMBOL
++0x78c5a239    clk_prepare     vmlinux EXPORT_SYMBOL_GPL
++0x1a36f8fd    udc_attach_driver       vmlinux EXPORT_SYMBOL_GPL
++0xcb56fc45    dev_vprintk_emit        vmlinux EXPORT_SYMBOL
++0xed2817be    arp_send        vmlinux EXPORT_SYMBOL
++0x7d903146    xt_register_matches     vmlinux EXPORT_SYMBOL
++0x3ed63055    zlib_inflateReset       vmlinux EXPORT_SYMBOL
++0x281823c5    __kfifo_out_peek        vmlinux EXPORT_SYMBOL
++0xb19760c3    bitmap_onto     vmlinux EXPORT_SYMBOL
++0xaf9b8476    cdev_del        vmlinux EXPORT_SYMBOL
++0xbc8da552    tcp_seq_open    vmlinux EXPORT_SYMBOL
++0x35224ff2    pneigh_enqueue  vmlinux EXPORT_SYMBOL
++0x0d2e0ab9    dev_alloc_name  vmlinux EXPORT_SYMBOL
++0xebd8aaa8    iov_iter_copy_from_user vmlinux EXPORT_SYMBOL
++0x134dc23b    v4l2_m2m_dqbuf  vmlinux EXPORT_SYMBOL_GPL
++0x1cfa672b    soft_cursor     vmlinux EXPORT_SYMBOL
++0xac8f37b2    outer_cache     vmlinux EXPORT_SYMBOL
++0x744bfef9    generic_fh_to_dentry    vmlinux EXPORT_SYMBOL_GPL
++0xa3225eb1    try_to_del_timer_sync   vmlinux EXPORT_SYMBOL
++0x6a1733eb    iommu_group_unregister_notifier vmlinux EXPORT_SYMBOL_GPL
++0xc84dae86    matrix_keypad_parse_of_params   vmlinux EXPORT_SYMBOL_GPL
++0x404403a9    usb_free_all_descriptors        vmlinux EXPORT_SYMBOL_GPL
++0x50eca283    ipcomp_output   vmlinux EXPORT_SYMBOL_GPL
++0xe482d673    nf_ct_expect_related_report     vmlinux EXPORT_SYMBOL_GPL
++0x26e58975    __pskb_copy     vmlinux EXPORT_SYMBOL
++0xd3dcab0b    flex_array_alloc        vmlinux EXPORT_SYMBOL
++0x247f1878    blk_queue_bounce        vmlinux EXPORT_SYMBOL
++0x97b13dad    __clocksource_register_scale    vmlinux EXPORT_SYMBOL_GPL
++0xdc73e48f    dm_unregister_target    vmlinux EXPORT_SYMBOL
++0xfe0f06c0    tty_init_termios        vmlinux EXPORT_SYMBOL_GPL
++0xb8356d30    dma_async_memcpy_buf_to_pg      vmlinux EXPORT_SYMBOL
++0xd8d3cf00    read_dev_sector vmlinux EXPORT_SYMBOL
++0x220669c4    scsi_cmd_blk_ioctl      vmlinux EXPORT_SYMBOL
++0x03c91b88    crypto_alloc_instance2  vmlinux EXPORT_SYMBOL_GPL
++0x4d9c0e6d    jbd2_journal_revoke     vmlinux EXPORT_SYMBOL
++0xaca5e909    config_group_find_item  vmlinux EXPORT_SYMBOL
++0xe01ba49b    iio_kfifo_allocate      vmlinux EXPORT_SYMBOL
++0xe170917a    timed_output_dev_unregister     vmlinux EXPORT_SYMBOL_GPL
++0x4f689046    brcmu_pkt_buf_free_skb  drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x932f03cb    security_old_inode_init_security        vmlinux EXPORT_SYMBOL
++0xa4e5092b    debugfs_create_x16      vmlinux EXPORT_SYMBOL_GPL
++0x1826f089    __tracepoint_kmem_cache_alloc_node      vmlinux EXPORT_SYMBOL
++0xd81de62c    ring_buffer_record_enable       vmlinux EXPORT_SYMBOL_GPL
++0xc7fe94dd    usb_ifnum_to_if vmlinux EXPORT_SYMBOL_GPL
++0xc2af811e    inet6_destroy_sock      vmlinux EXPORT_SYMBOL_GPL
++0x061651be    strcat  vmlinux EXPORT_SYMBOL
++0xb39ec138    mb_cache_entry_release  vmlinux EXPORT_SYMBOL
++0x51d559d1    _raw_spin_unlock_irqrestore     vmlinux EXPORT_SYMBOL
++0xa6eb0e39    phy_device_create       vmlinux EXPORT_SYMBOL
++0xf92c66be    drm_mm_search_free_generic      vmlinux EXPORT_SYMBOL
++0x97270fcf    crypto_register_shash   vmlinux EXPORT_SYMBOL_GPL
++0x495f2be4    jbd2_journal_get_write_access   vmlinux EXPORT_SYMBOL
++0x3826f483    jbd2_journal_invalidatepage     vmlinux EXPORT_SYMBOL
++0xd8a12f4d    iio_scan_mask_query     vmlinux EXPORT_SYMBOL_GPL
++0x09b069ea    v4l2_ctrl_log_status    vmlinux EXPORT_SYMBOL
++0x0a513c7c    usb_gadget_unregister_driver    vmlinux EXPORT_SYMBOL_GPL
++0x39ef8cc9    dma_buf_kunmap  vmlinux EXPORT_SYMBOL_GPL
++0xd28b5dda    dma_buf_vunmap  vmlinux EXPORT_SYMBOL_GPL
++0x3fcf2826    inet6_unregister_protosw        vmlinux EXPORT_SYMBOL
++0x551c3633    nf_nat_l4proto_unique_tuple     vmlinux EXPORT_SYMBOL_GPL
++0x86700640    nf_register_hooks       vmlinux EXPORT_SYMBOL
++0x44e94d6c    pfifo_qdisc_ops vmlinux EXPORT_SYMBOL
++0xf202c5cb    radix_tree_insert       vmlinux EXPORT_SYMBOL
++0x24ffe755    vfs_listxattr   vmlinux EXPORT_SYMBOL_GPL
++0x52428cc8    parent_mem_cgroup       vmlinux EXPORT_SYMBOL
++0x9d59c0f2    find_get_pages_contig   vmlinux EXPORT_SYMBOL
++0x80f3268f    __trace_printk  vmlinux EXPORT_SYMBOL_GPL
++0x22a27a85    st_sensors_spi_configure        vmlinux EXPORT_SYMBOL
++0x7880c781    dm_kcopyd_prepare_callback      vmlinux EXPORT_SYMBOL
++0xc53f0876    vb2_dma_contig_memops   vmlinux EXPORT_SYMBOL_GPL
++0x388f9128    xfrm_state_walk_done    vmlinux EXPORT_SYMBOL
++0x6d6888a7    qdisc_create_dflt       vmlinux EXPORT_SYMBOL
++0x194ccf46    bmap    vmlinux EXPORT_SYMBOL
++0xe2fae716    kmemdup vmlinux EXPORT_SYMBOL
++0x07ed48c3    __blocking_notifier_call_chain  vmlinux EXPORT_SYMBOL_GPL
++0x074d7047    st_sensors_trigger_handler      vmlinux EXPORT_SYMBOL
++0x33883929    clk_divider_ops vmlinux EXPORT_SYMBOL_GPL
++0xe2b92059    v4l2_video_std_construct        vmlinux EXPORT_SYMBOL
++0x06ea1593    usbnet_defer_kevent     vmlinux EXPORT_SYMBOL_GPL
++0x6650ad3e    uart_add_one_port       vmlinux EXPORT_SYMBOL
++0x5dda183c    snd_soc_dapm_disable_pin        vmlinux EXPORT_SYMBOL_GPL
++0x7a188791    prandom_bytes   vmlinux EXPORT_SYMBOL
++0xc25a61ec    drm_mode_set_crtcinfo   vmlinux EXPORT_SYMBOL
++0xcb1beab5    drm_mode_vrefresh       vmlinux EXPORT_SYMBOL
++0x4a94168c    tcp_register_congestion_control vmlinux EXPORT_SYMBOL_GPL
++0x4f5836c8    tcp_release_cb  vmlinux EXPORT_SYMBOL
++0x2f366d34    tcp_gro_complete        vmlinux EXPORT_SYMBOL
++0x1eba8ee6    nf_conntrack_alloc      vmlinux EXPORT_SYMBOL_GPL
++0x28a903c8    timerqueue_add  vmlinux EXPORT_SYMBOL_GPL
++0x96cea50b    sync_filesystem vmlinux EXPORT_SYMBOL_GPL
++0x68c0685a    media_entity_setup_link vmlinux EXPORT_SYMBOL_GPL
++0x69b83c18    usb_get_phy_dev vmlinux EXPORT_SYMBOL_GPL
++0x7e6bf1b2    dma_buf_fd      vmlinux EXPORT_SYMBOL_GPL
++0x4d974b9c    register_sysrq_key      vmlinux EXPORT_SYMBOL
++0xf79531f4    tcp_connect     vmlinux EXPORT_SYMBOL
++0x3f45ea36    neigh_table_clear       vmlinux EXPORT_SYMBOL
++0xf6de842c    clk_get_parent  vmlinux EXPORT_SYMBOL_GPL
++0x4782eebf    clk_set_parent  vmlinux EXPORT_SYMBOL_GPL
++0x45a20c5a    of_phy_find_device      vmlinux EXPORT_SYMBOL
++0xcbbedfcb    led_trigger_event       vmlinux EXPORT_SYMBOL_GPL
++0x69281b40    thermal_zone_bind_cooling_device        vmlinux EXPORT_SYMBOL_GPL
++0xe122af95    xfrm_aalg_get_byname    vmlinux EXPORT_SYMBOL_GPL
++0x74b1375e    xfrm_state_flush        vmlinux EXPORT_SYMBOL
++0x94098ff8    snd_interval_list       vmlinux EXPORT_SYMBOL
++0x64f01d42    fuse_put_request        vmlinux EXPORT_SYMBOL_GPL
++0x1811ac2f    fat_flush_inodes        vmlinux EXPORT_SYMBOL_GPL
++0x73198f14    mmc_align_data_size     vmlinux EXPORT_SYMBOL
++0xa70df32d    drm_fb_helper_fill_var  vmlinux EXPORT_SYMBOL
++0x209e95ea    xfrm_find_acq_byseq     vmlinux EXPORT_SYMBOL
++0x4b9e2d58    xfrm_policy_unregister_afinfo   vmlinux EXPORT_SYMBOL
++0x461a1d6a    __rtnl_af_register      vmlinux EXPORT_SYMBOL_GPL
++0x09c55cec    schedule_timeout_interruptible  vmlinux EXPORT_SYMBOL
++0xf512c668    iio_trigger_free        vmlinux EXPORT_SYMBOL
++0xdac28b43    dw_mci_resume   vmlinux EXPORT_SYMBOL
++0x361e2bcc    save_stack_trace        vmlinux EXPORT_SYMBOL_GPL
++0x25e6af56    snd_compress_register   vmlinux EXPORT_SYMBOL_GPL
++0x1ace138d    bitmap_allocate_region  vmlinux EXPORT_SYMBOL
++0x250113b4    memory_read_from_buffer vmlinux EXPORT_SYMBOL
++0x4ae22649    iommu_set_fault_handler vmlinux EXPORT_SYMBOL_GPL
++0x3ca38e3a    rndis_signal_connect    vmlinux EXPORT_SYMBOL
++0x9d01b017    dma_buf_attach  vmlinux EXPORT_SYMBOL_GPL
++0x3930a5b6    dma_buf_detach  vmlinux EXPORT_SYMBOL_GPL
++0x2aec4354    hci_alloc_dev   vmlinux EXPORT_SYMBOL
++0xbb5d343d    xfrm_get_acqseq vmlinux EXPORT_SYMBOL
++0x4082abfe    __scsi_iterate_devices  vmlinux EXPORT_SYMBOL
++0x6b6d7375    drm_timestamp_precision vmlinux EXPORT_SYMBOL
++0x7ffcb57f    ip6_tnl_get_cap vmlinux EXPORT_SYMBOL
++0xccc812c3    dapm_clock_event        vmlinux EXPORT_SYMBOL_GPL
++0x1a47bf65    blk_queue_bounce_limit  vmlinux EXPORT_SYMBOL
++0xcc13c782    vb2_ioctl_streamon      vmlinux EXPORT_SYMBOL_GPL
++0x8afddc98    spi_register_driver     vmlinux EXPORT_SYMBOL_GPL
++0x17ae6853    platform_bus    vmlinux EXPORT_SYMBOL_GPL
++0x72ac0290    exynos_drm_device_unregister    vmlinux EXPORT_SYMBOL_GPL
++0xf71ca112    skb_abort_seq_read      vmlinux EXPORT_SYMBOL
++0x18bbe186    snd_soc_cnew    vmlinux EXPORT_SYMBOL_GPL
++0x2b0ba2b0    scsi_sense_desc_find    vmlinux EXPORT_SYMBOL
++0x8de13715    drm_format_vert_chroma_subsampling      vmlinux EXPORT_SYMBOL
++0x06fe3b14    default_grn     vmlinux EXPORT_SYMBOL
++0xee683d16    inet6_ioctl     vmlinux EXPORT_SYMBOL
++0x47252a20    tcp_getsockopt  vmlinux EXPORT_SYMBOL
++0x7027c3ad    tcp_setsockopt  vmlinux EXPORT_SYMBOL
++0xb7f74966    rtnl_unicast    vmlinux EXPORT_SYMBOL
++0x525971d4    snd_soc_update_bits_locked      vmlinux EXPORT_SYMBOL_GPL
++0x6ef8fcd8    snd_pcm_format_linear   vmlinux EXPORT_SYMBOL
++0x8f8f6e19    alloc_disk_node vmlinux EXPORT_SYMBOL
++0x71c445f5    fuse_get_req    vmlinux EXPORT_SYMBOL_GPL
++0xc41cff79    dequeue_signal  vmlinux EXPORT_SYMBOL_GPL
++0x5d9d3491    v4l_match_dv_timings    vmlinux EXPORT_SYMBOL_GPL
++0x829a8cac    drm_property_create_range       vmlinux EXPORT_SYMBOL
++0xf3189246    __rtnl_af_unregister    vmlinux EXPORT_SYMBOL_GPL
++0x0d7e8390    crypto_ablkcipher_type  vmlinux EXPORT_SYMBOL_GPL
++0xaf8e1608    ip6t_register_table     vmlinux EXPORT_SYMBOL
++0xb1a1e40e    crypto_tfm_in_queue     vmlinux EXPORT_SYMBOL_GPL
++0xc73f3f9a    fget_raw        vmlinux EXPORT_SYMBOL
++0x71008581    atomic_notifier_call_chain      vmlinux EXPORT_SYMBOL_GPL
++0x12bf1d5c    usbnet_device_suggests_idle     vmlinux EXPORT_SYMBOL
++0x79b993ef    cfg80211_send_unprot_deauth     vmlinux EXPORT_SYMBOL
++0xdacc53b2    spi_add_device  vmlinux EXPORT_SYMBOL_GPL
++0xf5a5c913    backlight_device_unregister     vmlinux EXPORT_SYMBOL
++0xadce320f    pinctrl_add_gpio_ranges vmlinux EXPORT_SYMBOL_GPL
++0x0f8342e1    phy_pm_runtime_forbid   vmlinux EXPORT_SYMBOL_GPL
++0xc0763484    rfkill_blocked  vmlinux EXPORT_SYMBOL
++0xb0bad0e8    ip6_push_pending_frames vmlinux EXPORT_SYMBOL_GPL
++0xfc02b7ad    sysctl_tcp_wmem vmlinux EXPORT_SYMBOL
++0xac782342    nf_unregister_hook      vmlinux EXPORT_SYMBOL
++0xa08421e0    dev_change_net_namespace        vmlinux EXPORT_SYMBOL_GPL
++0x47c6d038    blk_queue_flush_queueable       vmlinux EXPORT_SYMBOL_GPL
++0x2db8f309    blk_queue_rq_timeout    vmlinux EXPORT_SYMBOL_GPL
++0x6fb277a1    flush_kernel_dcache_page        vmlinux EXPORT_SYMBOL
++0x1d633e6a    tcp_twsk_destructor     vmlinux EXPORT_SYMBOL_GPL
++0x7611866b    scm_detach_fds  vmlinux EXPORT_SYMBOL
++0xd3b02cea    put_pid vmlinux EXPORT_SYMBOL_GPL
++0xed20e404    iio_dealloc_pollfunc    vmlinux EXPORT_SYMBOL_GPL
++0xba706bd7    samsung_pwm_lock        vmlinux EXPORT_SYMBOL
++0x158b7724    media_entity_create_link        vmlinux EXPORT_SYMBOL_GPL
++0x1172ce54    rtc_ktime_to_tm vmlinux EXPORT_SYMBOL_GPL
++0xa286a234    snd_pcm_format_name     vmlinux EXPORT_SYMBOL_GPL
++0xc7e39bca    ring_buffer_dropped_events_cpu  vmlinux EXPORT_SYMBOL_GPL
++0xaa957320    posix_clock_register    vmlinux EXPORT_SYMBOL_GPL
++0xad46dec2    of_count_phandle_with_args      vmlinux EXPORT_SYMBOL
++0x7120d717    regmap_bulk_read        vmlinux EXPORT_SYMBOL_GPL
++0xca56dea4    driver_find_device      vmlinux EXPORT_SYMBOL_GPL
++0x9c9d19e7    blk_get_request vmlinux EXPORT_SYMBOL
++0x2c790eff    usbnet_read_cmd_nopm    vmlinux EXPORT_SYMBOL_GPL
++0xbb99125c    get_default_font        vmlinux EXPORT_SYMBOL
++0x6e5cf115    cfg80211_inform_bss     vmlinux EXPORT_SYMBOL
++0xce7a55c1    xfrm_ealg_get_byid      vmlinux EXPORT_SYMBOL_GPL
++0x0cc1e40f    crypto_it_tab   vmlinux EXPORT_SYMBOL_GPL
++0x3dc916b6    crypto_fl_tab   vmlinux EXPORT_SYMBOL_GPL
++0x40d46b21    crypto_ft_tab   vmlinux EXPORT_SYMBOL_GPL
++0x71dc9998    crypto_il_tab   vmlinux EXPORT_SYMBOL_GPL
++0x837d0f0a    down_timeout    vmlinux EXPORT_SYMBOL
++0x2cd7dd71    __cpufreq_driver_getavg vmlinux EXPORT_SYMBOL_GPL
++0xee6b71c4    syscon_regmap_lookup_by_compatible      vmlinux EXPORT_SYMBOL_GPL
++0xae77b400    device_pm_wait_for_dev  vmlinux EXPORT_SYMBOL_GPL
++0x1d5a2494    nfnetlink_has_listeners vmlinux EXPORT_SYMBOL_GPL
++0x3bd1b1f6    msecs_to_jiffies        vmlinux EXPORT_SYMBOL
++0xfb09f255    cpufreq_frequency_table_target  vmlinux EXPORT_SYMBOL_GPL
++0xb52e203b    snd_pcm_suspend_all     vmlinux EXPORT_SYMBOL
++0xc1ec3550    blkdev_fsync    vmlinux EXPORT_SYMBOL
++0x0ebe6f54    lookup_one_len  vmlinux EXPORT_SYMBOL
++0x151404f6    misc_deregister vmlinux EXPORT_SYMBOL
++0xb2856c71    inet6_bind      vmlinux EXPORT_SYMBOL
++0xf68285c0    register_inetaddr_notifier      vmlinux EXPORT_SYMBOL
++0x7afc9d8a    unregister_sound_mixer  vmlinux EXPORT_SYMBOL
++0xd5d80496    atomic_dec_and_mutex_lock       vmlinux EXPORT_SYMBOL
++0x4351577a    fb_parse_edid   vmlinux EXPORT_SYMBOL
++0x68beb163    nf_ct_l3proto_pernet_unregister vmlinux EXPORT_SYMBOL_GPL
++0x7751fba7    nf_ct_l4proto_pernet_unregister vmlinux EXPORT_SYMBOL_GPL
++0x5cbe0b31    snd_pcm_lib_write       vmlinux EXPORT_SYMBOL
++0x6cecc98a    devres_get      vmlinux EXPORT_SYMBOL_GPL
++0x20925954    devres_add      vmlinux EXPORT_SYMBOL_GPL
++0x99a9dfa6    ieee80211_data_to_8023  vmlinux EXPORT_SYMBOL
++0x21036b2c    bt_accept_enqueue       vmlinux EXPORT_SYMBOL
++0x0cd5a88b    sync_inodes_sb  vmlinux EXPORT_SYMBOL
++0x7485e15e    unregister_chrdev_region        vmlinux EXPORT_SYMBOL
++0x7e8ad403    generic_writepages      vmlinux EXPORT_SYMBOL
++0x07cf3227    clk_fixed_rate_ops      vmlinux EXPORT_SYMBOL_GPL
++0xf5463be8    led_trigger_blink_oneshot       vmlinux EXPORT_SYMBOL_GPL
++0xdbf18207    v4l2_device_register_subdev     vmlinux EXPORT_SYMBOL_GPL
++0x131a5ed7    regmap_del_irq_chip     vmlinux EXPORT_SYMBOL_GPL
++0xb09c8d37    regmap_add_irq_chip     vmlinux EXPORT_SYMBOL_GPL
++0x26f0453a    blk_set_default_limits  vmlinux EXPORT_SYMBOL
++0xf21f8a44    blk_init_allocated_queue        vmlinux EXPORT_SYMBOL
++0x60df1e3b    posix_acl_equiv_mode    vmlinux EXPORT_SYMBOL
++0xc131c5dd    usb_add_phy     vmlinux EXPORT_SYMBOL_GPL
++0x211c5b26    cdc_ncm_bind_common     vmlinux EXPORT_SYMBOL_GPL
++0x61f6939e    drm_i2c_encoder_detect  vmlinux EXPORT_SYMBOL
++0xd9f310b2    gpiochip_is_requested   vmlinux EXPORT_SYMBOL_GPL
++0xb9639d32    rtnl_register   vmlinux EXPORT_SYMBOL_GPL
++0xf2254dc3    sock_from_file  vmlinux EXPORT_SYMBOL
++0x0f5455e2    snd_soc_info_enum_double        vmlinux EXPORT_SYMBOL_GPL
++0xdd89a6bf    lookup_bdev     vmlinux EXPORT_SYMBOL
++0x55704318    clockevents_config_and_register vmlinux EXPORT_SYMBOL_GPL
++0x2fd8cba9    freeze_wake     vmlinux EXPORT_SYMBOL_GPL
++0x071b7eea    irq_stat        vmlinux EXPORT_SYMBOL
++0x7a8ca627    xfrm_count_pfkey_enc_supported  vmlinux EXPORT_SYMBOL_GPL
++0x1ff2a733    raw_seq_stop    vmlinux EXPORT_SYMBOL_GPL
++0x85b825e7    gnet_stats_copy_basic   vmlinux EXPORT_SYMBOL
++0x0cfefe1e    percpu_counter_destroy  vmlinux EXPORT_SYMBOL
++0x02ea69e2    vm_map_ram      vmlinux EXPORT_SYMBOL
++0x36eb3583    filemap_fdatawrite_range        vmlinux EXPORT_SYMBOL
++0xb977cf42    inet_sendmsg    vmlinux EXPORT_SYMBOL
++0xddbcead7    ip_cmsg_recv    vmlinux EXPORT_SYMBOL
++0xb9a64b20    elevator_alloc  vmlinux EXPORT_SYMBOL
++0xbcaf3971    crypto_alg_sem  vmlinux EXPORT_SYMBOL_GPL
++0xe71dab2c    bio_sector_offset       vmlinux EXPORT_SYMBOL
++0x2c44797e    hidinput_report_event   vmlinux EXPORT_SYMBOL_GPL
++0x5d9e8570    drm_display_mode_from_videomode vmlinux EXPORT_SYMBOL_GPL
++0x2b8e67cd    fuse_get_req_for_background     vmlinux EXPORT_SYMBOL_GPL
++0x2b1c6816    extcon_dev_register     vmlinux EXPORT_SYMBOL_GPL
++0xdef26358    dw_mci_probe    vmlinux EXPORT_SYMBOL
++0xcbde0d9d    inverse_translate       vmlinux EXPORT_SYMBOL_GPL
++0x056ee730    ipv6_hash_secret        vmlinux EXPORT_SYMBOL
++0xfe029963    unregister_inetaddr_notifier    vmlinux EXPORT_SYMBOL
++0x650a6767    prandom_u32_state       vmlinux EXPORT_SYMBOL
++0x4148a5ff    get_kernel_pages        vmlinux EXPORT_SYMBOL_GPL
++0x24d3448d    perf_event_enable       vmlinux EXPORT_SYMBOL_GPL
++0x1c5a04e0    irq_domain_generate_simple      vmlinux EXPORT_SYMBOL_GPL
++0xb7b4232a    unregister_exec_domain  vmlinux EXPORT_SYMBOL
++0xd6f86c04    amba_release_regions    vmlinux EXPORT_SYMBOL
++0x89d5538d    fb_pad_aligned_buffer   vmlinux EXPORT_SYMBOL
++0x93237692    nobh_write_begin        vmlinux EXPORT_SYMBOL
++0x920eb90c    interruptible_sleep_on_timeout  vmlinux EXPORT_SYMBOL
++0x3a36ce8c    od_register_powersave_bias_handler      vmlinux EXPORT_SYMBOL_GPL
++0x946b8b6c    netlink_ack     vmlinux EXPORT_SYMBOL
++0x1000be5b    sock_no_bind    vmlinux EXPORT_SYMBOL
++0x1e5479ed    sock_get_timestamp      vmlinux EXPORT_SYMBOL
++0x4211c3c1    zlib_inflateInit2       vmlinux EXPORT_SYMBOL
++0x2486141e    bio_alloc_pages vmlinux EXPORT_SYMBOL
++0x62fd6207    param_set_charp vmlinux EXPORT_SYMBOL
++0x0862d814    v4l2_event_unsubscribe_all      vmlinux EXPORT_SYMBOL_GPL
++0x2f10e618    v4l2_event_queue_fh     vmlinux EXPORT_SYMBOL_GPL
++0x6bdcfd99    qdisc_class_hash_remove vmlinux EXPORT_SYMBOL
++0xf070e888    __put_net       vmlinux EXPORT_SYMBOL_GPL
++0x8df3789f    snd_oss_info_register   vmlinux EXPORT_SYMBOL
++0x68c73797    fuse_request_alloc      vmlinux EXPORT_SYMBOL_GPL
++0x2342f1ae    v4l2_prio_open  vmlinux EXPORT_SYMBOL
++0x4ddaa6ea    dmam_alloc_noncoherent  vmlinux EXPORT_SYMBOL
++0x7dfdf9a1    transport_destroy_device        vmlinux EXPORT_SYMBOL_GPL
++0x8c510862    drm_find_cea_extension  vmlinux EXPORT_SYMBOL
++0x7c0267ee    serial8250_tx_chars     vmlinux EXPORT_SYMBOL_GPL
++0x6879e81d    display_entity_put      vmlinux EXPORT_SYMBOL_GPL
++0xf19a455d    lro_flush_pkt   vmlinux EXPORT_SYMBOL
++0xbf8ba54a    vprintk vmlinux EXPORT_SYMBOL
++0x7bd1de14    thermal_cdev_update     vmlinux EXPORT_SYMBOL
++0x2631d719    tty_unregister_device   vmlinux EXPORT_SYMBOL
++0xa7e7f050    __udp4_lib_lookup       vmlinux EXPORT_SYMBOL_GPL
++0x2e2ce9e0    sysctl_tcp_syncookies   vmlinux EXPORT_SYMBOL
++0xd5a8fd58    tcp_poll        vmlinux EXPORT_SYMBOL
++0x3f74afb9    nf_ct_l3proto_register  vmlinux EXPORT_SYMBOL_GPL
++0xb4998fd0    nf_ct_l4proto_register  vmlinux EXPORT_SYMBOL_GPL
++0x2482e688    vsprintf        vmlinux EXPORT_SYMBOL
++0x59e4b703    generic_splice_sendpage vmlinux EXPORT_SYMBOL
++0x1795a16b    __genl_register_family_with_ops vmlinux EXPORT_SYMBOL
++0xcb469d2b    ddebug_add_module       vmlinux EXPORT_SYMBOL_GPL
++0xa2d83f8b    grab_cache_page_write_begin     vmlinux EXPORT_SYMBOL
++0x8c930a68    rt_mutex_lock_interruptible     vmlinux EXPORT_SYMBOL_GPL
++0xcc0871f2    attribute_container_find_class_device   vmlinux EXPORT_SYMBOL_GPL
++0x13b52797    pwm_request_from_chip   vmlinux EXPORT_SYMBOL_GPL
++0x28118cb6    __get_user_1    vmlinux EXPORT_SYMBOL
++0xbb72d4fe    __put_user_1    vmlinux EXPORT_SYMBOL
++0x0cae232b    utf16s_to_utf8s vmlinux EXPORT_SYMBOL
++0x617a218d    __cond_resched_lock     vmlinux EXPORT_SYMBOL
++0x44224883    __put_task_struct       vmlinux EXPORT_SYMBOL_GPL
++0xbc65845b    class_create_file       vmlinux EXPORT_SYMBOL_GPL
++0xe459c49b    unregister_pernet_subsys        vmlinux EXPORT_SYMBOL_GPL
++0xd882a162    wait_on_sync_kiocb      vmlinux EXPORT_SYMBOL
++0x28acb0e5    simple_write_begin      vmlinux EXPORT_SYMBOL
++0x5c1cb07e    redirty_page_for_writepage      vmlinux EXPORT_SYMBOL
++0x6070a6fb    bdi_set_max_ratio       vmlinux EXPORT_SYMBOL
++0xfee43a69    drm_dp_get_adjust_request_voltage       vmlinux EXPORT_SYMBOL
++0x8ffe7e89    nf_conntrack_htable_size        vmlinux EXPORT_SYMBOL_GPL
++0x79c527b0    netdev_emerg    vmlinux EXPORT_SYMBOL
++0x0bc7142a    sk_stream_kill_queues   vmlinux EXPORT_SYMBOL
++0xeb37101c    audit_log_end   vmlinux EXPORT_SYMBOL
++0xc3577d50    dev_set_name    vmlinux EXPORT_SYMBOL_GPL
++0x6d40a921    need_ipv4_conntrack     vmlinux EXPORT_SYMBOL_GPL
++0x6b98f5bd    __sk_dst_check  vmlinux EXPORT_SYMBOL
++0x003ed69a    __kfifo_dma_in_prepare  vmlinux EXPORT_SYMBOL
++0xd27b25dd    blk_check_plugged       vmlinux EXPORT_SYMBOL
++0x9e093f78    elv_register_queue      vmlinux EXPORT_SYMBOL
++0x716265c7    debugfs_initialized     vmlinux EXPORT_SYMBOL_GPL
++0x8e19dd86    of_platform_populate    vmlinux EXPORT_SYMBOL_GPL
++0x2a4ee199    v4l2_m2m_job_finish     vmlinux EXPORT_SYMBOL
++0x8c62225c    usb_queue_reset_device  vmlinux EXPORT_SYMBOL_GPL
++0x1e837252    drm_mm_scan_add_block   vmlinux EXPORT_SYMBOL
++0x6c9424d9    snd_pcm_lib_preallocate_pages   vmlinux EXPORT_SYMBOL
++0x4c759827    byte_rev_table  vmlinux EXPORT_SYMBOL_GPL
++0xdf7090e0    __elv_add_request       vmlinux EXPORT_SYMBOL
++0x911010cb    skcipher_geniv_init     vmlinux EXPORT_SYMBOL_GPL
++0x9bd700dd    set_bh_page     vmlinux EXPORT_SYMBOL
++0x13a2a2e3    free_user_ns    vmlinux EXPORT_SYMBOL
++0x4fe8770d    usb_interrupt_msg       vmlinux EXPORT_SYMBOL_GPL
++0x0d7dd3fc    pm_generic_runtime_resume       vmlinux EXPORT_SYMBOL_GPL
++0x3df0b6c5    bus_unregister  vmlinux EXPORT_SYMBOL_GPL
++0x131f636c    nf_nat_l4proto_in_range vmlinux EXPORT_SYMBOL_GPL
++0xe6643a60    snd_soc_dpcm_be_can_update      vmlinux EXPORT_SYMBOL_GPL
++0x059c8bf5    snd_soc_dpcm_fe_can_update      vmlinux EXPORT_SYMBOL_GPL
++0xe914e41e    strcpy  vmlinux EXPORT_SYMBOL
++0x27235c89    crypto_destroy_tfm      vmlinux EXPORT_SYMBOL_GPL
++0xe44b1603    sysfs_remove_link_from_group    vmlinux EXPORT_SYMBOL_GPL
++0x1dff6af1    filemap_fault   vmlinux EXPORT_SYMBOL
++0xb1d9aabd    lg_local_unlock_cpu     vmlinux EXPORT_SYMBOL
++0x59d9c8d7    jack_get_data   vmlinux EXPORT_SYMBOL_GPL
++0x7a91726b    clkdev_alloc    vmlinux EXPORT_SYMBOL
++0x6138cad8    nfc_tm_deactivated      vmlinux EXPORT_SYMBOL
++0xe50e65bf    blocking_notifier_chain_register        vmlinux EXPORT_SYMBOL_GPL
++0x9acf72e4    rndis_set_param_medium  vmlinux EXPORT_SYMBOL
++0x677428bf    sdev_enable_disk_events vmlinux EXPORT_SYMBOL
++0x45ef1157    tty_pair_get_tty        vmlinux EXPORT_SYMBOL
++0x4338e523    tty_pair_get_pty        vmlinux EXPORT_SYMBOL
++0x51c0d211    fb_get_buffer_offset    vmlinux EXPORT_SYMBOL
++0xe7f26347    skb_unlink      vmlinux EXPORT_SYMBOL
++0xc3f69ac2    crypto_register_template        vmlinux EXPORT_SYMBOL_GPL
++0x00fe8031    fuse_abort_conn vmlinux EXPORT_SYMBOL_GPL
++0x3dc45692    vm_iomap_memory vmlinux EXPORT_SYMBOL
++0xc41f0516    node_states     vmlinux EXPORT_SYMBOL
++0x6a5fb566    rcu_sched_force_quiescent_state vmlinux EXPORT_SYMBOL_GPL
++0xc89e91fb    irq_setup_alt_chip      vmlinux EXPORT_SYMBOL_GPL
++0xe8a39d68    vb2_ioctl_streamoff     vmlinux EXPORT_SYMBOL_GPL
++0xb2e5ae4a    snd_lookup_minor_data   vmlinux EXPORT_SYMBOL
++0xaafd1f6c    iio_triggered_buffer_setup      vmlinux EXPORT_SYMBOL
++0x4b17b645    of_property_read_u16_array      vmlinux EXPORT_SYMBOL_GPL
++0xdac11bae    of_property_read_u32_array      vmlinux EXPORT_SYMBOL_GPL
++0x5641485b    tty_termios_encode_baud_rate    vmlinux EXPORT_SYMBOL_GPL
++0x85d549dc    s3c_gpio_getcfg vmlinux EXPORT_SYMBOL
++0x1189692c    inet_csk_delete_keepalive_timer vmlinux EXPORT_SYMBOL
++0xbec25473    of_parse_phandle        vmlinux EXPORT_SYMBOL
++0x53f0b470    dev_pm_qos_add_ancestor_request vmlinux EXPORT_SYMBOL_GPL
++0x0ddc826c    drm_fb_helper_set_par   vmlinux EXPORT_SYMBOL
++0x64bb0960    cfg80211_wext_giwmode   vmlinux EXPORT_SYMBOL_GPL
++0xd4cc3fbd    cfg80211_wext_giwname   vmlinux EXPORT_SYMBOL_GPL
++0x8697617d    cfg80211_wext_siwmode   vmlinux EXPORT_SYMBOL_GPL
++0xe3643cca    cfg80211_send_auth_timeout      vmlinux EXPORT_SYMBOL
++0x377db989    xfrm_state_register_afinfo      vmlinux EXPORT_SYMBOL
++0x2cdca56b    usb_register_device_driver      vmlinux EXPORT_SYMBOL_GPL
++0x7f9066b4    subsys_interface_unregister     vmlinux EXPORT_SYMBOL_GPL
++0xfbc8e9a2    regulatory_hint vmlinux EXPORT_SYMBOL
++0xbdf0ff3a    wiphy_rfkill_start_polling      vmlinux EXPORT_SYMBOL
++0x74631c0e    inet_ioctl      vmlinux EXPORT_SYMBOL
++0x5cbe31bd    snd_soc_dapm_mixer_update_power vmlinux EXPORT_SYMBOL_GPL
++0x5a3c2afd    kobject_get_path        vmlinux EXPORT_SYMBOL_GPL
++0xd8ce7e67    clocksource_register    vmlinux EXPORT_SYMBOL
++0x802c194a    of_device_register      vmlinux EXPORT_SYMBOL
++0x0c8c9e99    scsi_show_extd_sense    vmlinux EXPORT_SYMBOL
++0x2155f85c    bt_sock_link    vmlinux EXPORT_SYMBOL
++0x0ccfae80    xt_register_target      vmlinux EXPORT_SYMBOL
++0x6f20960a    full_name_hash  vmlinux EXPORT_SYMBOL
++0xcded9074    phy_drivers_register    vmlinux EXPORT_SYMBOL
++0xae5ba460    ping_prot       vmlinux EXPORT_SYMBOL
++0x814e7730    nf_ct_destroy   vmlinux EXPORT_SYMBOL
++0xe8279caa    nf_unregister_hooks     vmlinux EXPORT_SYMBOL
++0x8810ad5e    crypto_xor      vmlinux EXPORT_SYMBOL_GPL
++0x45bf1ff3    crypto_inc      vmlinux EXPORT_SYMBOL_GPL
++0x5ac71347    wait_for_stable_page    vmlinux EXPORT_SYMBOL_GPL
++0xe07ca631    cpu_bit_bitmap  vmlinux EXPORT_SYMBOL_GPL
++0x9c5bf378    pm_generic_freeze       vmlinux EXPORT_SYMBOL_GPL
++0x50bd1b27    device_create_vargs     vmlinux EXPORT_SYMBOL_GPL
++0x30775773    drm_bl_unregister       vmlinux EXPORT_SYMBOL_GPL
++0xf4f3abb6    tty_port_hangup vmlinux EXPORT_SYMBOL
++0xca0bdf70    framebuffer_release     vmlinux EXPORT_SYMBOL
++0x86743fc9    touch_buffer    vmlinux EXPORT_SYMBOL
++0x5671b6e0    iio_triggered_buffer_predisable vmlinux EXPORT_SYMBOL
++0x2eb9cd44    brcmu_pktq_init drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
++0x77c7a73e    wiphy_apply_custom_regulatory   vmlinux EXPORT_SYMBOL
++0xd796d321    fat_getattr     vmlinux EXPORT_SYMBOL_GPL
++0x41e95f70    fat_setattr     vmlinux EXPORT_SYMBOL_GPL
++0x2750ffee    generic_read_dir        vmlinux EXPORT_SYMBOL
++0x00c3b7ed    dentry_unhash   vmlinux EXPORT_SYMBOL
++0xe007de41    kallsyms_lookup_name    vmlinux EXPORT_SYMBOL_GPL
++0x43f23311    dm_table_get_md vmlinux EXPORT_SYMBOL
++0x9db747a3    usb_hcd_poll_rh_status  vmlinux EXPORT_SYMBOL_GPL
++0xfd1cd45b    dev_pm_qos_hide_flags   vmlinux EXPORT_SYMBOL_GPL
++0xe15b1685    device_find_child       vmlinux EXPORT_SYMBOL_GPL
++0x1a022e5e    truncate_pagecache      vmlinux EXPORT_SYMBOL
++0x26b71fb4    ring_buffer_time_stamp  vmlinux EXPORT_SYMBOL_GPL
++0x4e6a500f    phy_pm_runtime_get      vmlinux EXPORT_SYMBOL_GPL
++0x056bb269    xfrm_ealg_get_byidx     vmlinux EXPORT_SYMBOL_GPL
++0x094585f4    sock_no_shutdown        vmlinux EXPORT_SYMBOL
++0x0a5ea478    __generic_block_fiemap  vmlinux EXPORT_SYMBOL
++0xb1acbcce    rcu_barrier_sched       vmlinux EXPORT_SYMBOL_GPL
++0x3924dd56    try_wait_for_completion vmlinux EXPORT_SYMBOL
++0x8f7014a1    param_set_ulong vmlinux EXPORT_SYMBOL
++0xee2d0fc7    _local_bh_enable        vmlinux EXPORT_SYMBOL
++0x34e8e0a0    of_device_unregister    vmlinux EXPORT_SYMBOL
++0xbed3ee5e    watchdog_register_device        vmlinux EXPORT_SYMBOL_GPL
++0x16244fe5    v4l2_prio_check vmlinux EXPORT_SYMBOL
++0x324a8332    vc_resize       vmlinux EXPORT_SYMBOL
++0xb410d84f    phy_put vmlinux EXPORT_SYMBOL_GPL
++0xa41b1e49    phy_pm_runtime_put_sync vmlinux EXPORT_SYMBOL_GPL
++0xb3d5242c    nf_ct_expect_alloc      vmlinux EXPORT_SYMBOL_GPL
++0xbdfe32cf    sysfs_unmerge_group     vmlinux EXPORT_SYMBOL_GPL
++0xdb04cacc    tracepoint_probe_unregister_noupdate    vmlinux EXPORT_SYMBOL_GPL
++0x481ce6ce    cpu_active_mask vmlinux EXPORT_SYMBOL
++0x78f47a5c    drm_kms_helper_poll_init        vmlinux EXPORT_SYMBOL
++0x62827bec    security_secctx_to_secid        vmlinux EXPORT_SYMBOL
++0xcb97ad8c    bus_find_device_by_name vmlinux EXPORT_SYMBOL_GPL
++0x427dce2d    drm_put_minor   vmlinux EXPORT_SYMBOL
++0xf7b743b5    drm_calc_timestamping_constants vmlinux EXPORT_SYMBOL
++0x62746f06    video_source_unregister vmlinux EXPORT_SYMBOL_GPL
++0xacde6340    inet_peer_xrlim_allow   vmlinux EXPORT_SYMBOL
++0xd4b0b600    nf_ct_attach    vmlinux EXPORT_SYMBOL
++0x3e1314f1    snd_timer_global_free   vmlinux EXPORT_SYMBOL
++0xd37725bb    register_user_hw_breakpoint     vmlinux EXPORT_SYMBOL_GPL
++0x4f741917    devm_phy_put    vmlinux EXPORT_SYMBOL_GPL
++0xe5ed5467    xfrm_policy_walk_init   vmlinux EXPORT_SYMBOL
++0xfd6eefb8    nf_nat_decode_session_hook      vmlinux EXPORT_SYMBOL
++0x82627707    snd_pcm_lib_writev      vmlinux EXPORT_SYMBOL
++0x28b2dd21    textsearch_register     vmlinux EXPORT_SYMBOL
++0x74baf17a    tracing_is_on   vmlinux EXPORT_SYMBOL_GPL
++0x381a798a    setup_max_cpus  vmlinux EXPORT_SYMBOL
++0xf442e8f8    commit_creds    vmlinux EXPORT_SYMBOL
++0xab598227    driver_attach   vmlinux EXPORT_SYMBOL_GPL
++0xa1d5de65    drm_mode_connector_list_update  vmlinux EXPORT_SYMBOL
++0xf3f5690b    __nf_ct_expect_find     vmlinux EXPORT_SYMBOL_GPL
++0xad0413d4    match_hex       vmlinux EXPORT_SYMBOL
++0xbfdbee53    usbnet_generic_cdc_bind vmlinux EXPORT_SYMBOL_GPL
++0x329edb99    platform_device_register        vmlinux EXPORT_SYMBOL_GPL
++0x80d68d3e    fb_register_client      vmlinux EXPORT_SYMBOL
++0x3638b44e    __inet_lookup_listener  vmlinux EXPORT_SYMBOL_GPL
++0x89636597    nf_unregister_sockopt   vmlinux EXPORT_SYMBOL
++0xadac214f    __skb_get_rxhash        vmlinux EXPORT_SYMBOL
++0x10ae54ba    skb_realloc_headroom    vmlinux EXPORT_SYMBOL
++0xdaa5b6fe    generic_pipe_buf_get    vmlinux EXPORT_SYMBOL
++0x461fff7e    generic_pipe_buf_map    vmlinux EXPORT_SYMBOL
++0x36f9cd94    rcu_is_cpu_idle vmlinux EXPORT_SYMBOL
++0x4102e3db    media_entity_find_link  vmlinux EXPORT_SYMBOL_GPL
++0xcd0e7389    platform_device_unregister      vmlinux EXPORT_SYMBOL_GPL
++0xf86dc7d7    serial8250_set_isa_configurator vmlinux EXPORT_SYMBOL
++0xbe1c5d4d    ipv6_find_hdr   vmlinux EXPORT_SYMBOL
++0xc6ed2b40    jbd2_journal_dirty_metadata     vmlinux EXPORT_SYMBOL
++0x77df0847    __set_personality       vmlinux EXPORT_SYMBOL
++0x92c6523d    tty_port_close_end      vmlinux EXPORT_SYMBOL
++0x78843287    blkcipher_walk_done     vmlinux EXPORT_SYMBOL_GPL
++0x96f90809    page_readlink   vmlinux EXPORT_SYMBOL
++0xc7c4f4ed    account_page_writeback  vmlinux EXPORT_SYMBOL
++0xa1edf7f3    drm_core_ioremap_wc     vmlinux EXPORT_SYMBOL
++0x08ad3fc2    register_con_driver     vmlinux EXPORT_SYMBOL
++0x676bbc0f    _set_bit        vmlinux EXPORT_SYMBOL
++0xd46c9ca5    nf_unregister_afinfo    vmlinux EXPORT_SYMBOL_GPL
++0xf5eb86ea    blk_verify_command      vmlinux EXPORT_SYMBOL
++0xc499ae1e    kstrdup vmlinux EXPORT_SYMBOL
++0x2aa1ad41    _raw_write_lock_irq     vmlinux EXPORT_SYMBOL
++0xb5b7345d    freezing_slow_path      vmlinux EXPORT_SYMBOL
++0xe505e34f    mmc_start_bkops vmlinux EXPORT_SYMBOL
++0x1dd571e6    fb_copy_cmap    vmlinux EXPORT_SYMBOL
++0x0d4d7a32    _atomic_dec_and_lock    vmlinux EXPORT_SYMBOL
++0x11c9185c    of_iomap        vmlinux EXPORT_SYMBOL
++0xf918f7de    xfrm_register_km        vmlinux EXPORT_SYMBOL
++0xde4bc28c    ip_mc_dec_group vmlinux EXPORT_SYMBOL
++0x03f12ac0    snd_soc_dapm_mux_update_power   vmlinux EXPORT_SYMBOL_GPL
++0x733c3b54    kasprintf       vmlinux EXPORT_SYMBOL
++0x8aaa8b57    simple_rename   vmlinux EXPORT_SYMBOL
++0x512579ee    vfs_setxattr    vmlinux EXPORT_SYMBOL_GPL
++0x3d8f75d6    vfs_getxattr    vmlinux EXPORT_SYMBOL_GPL
++0xcb7131fb    fb_get_options  vmlinux EXPORT_SYMBOL
++0xd49c7d00    phy_init        vmlinux EXPORT_SYMBOL_GPL
++0xf8c54a02    sock_init_data  vmlinux EXPORT_SYMBOL
++0x1209a558    snd_ctl_free_one        vmlinux EXPORT_SYMBOL
++0xe02eb6d0    ring_buffer_commit_overrun_cpu  vmlinux EXPORT_SYMBOL_GPL
++0x3a536bd7    ring_buffer_read_finish vmlinux EXPORT_SYMBOL_GPL
++0x9c0bd51f    _raw_spin_lock  vmlinux EXPORT_SYMBOL
++0xcf7c760d    mmc_send_ext_csd        vmlinux EXPORT_SYMBOL_GPL
++0x0f7cb7fa    tty_set_termios vmlinux EXPORT_SYMBOL_GPL
++0x86ffe7d1    ip_queue_xmit   vmlinux EXPORT_SYMBOL
++0xc30b3a36    scatterwalk_map vmlinux EXPORT_SYMBOL_GPL
++0x23532c4d    ftrace_print_flags_seq  vmlinux EXPORT_SYMBOL
++0x3500818d    v4l2_fh_open    vmlinux EXPORT_SYMBOL_GPL
++0xadc7d94a    class_dev_iter_init     vmlinux EXPORT_SYMBOL_GPL
++0xb95ec685    km_query        vmlinux EXPORT_SYMBOL
++0xf569d921    inet_release    vmlinux EXPORT_SYMBOL
++0x4251ff78    nf_ct_helper_expectfn_register  vmlinux EXPORT_SYMBOL_GPL
++0xa3f35bf5    rwsem_is_locked vmlinux EXPORT_SYMBOL
++0x518c4113    blk_queue_start_tag     vmlinux EXPORT_SYMBOL
++0x299f45b9    jbd2_journal_force_commit       vmlinux EXPORT_SYMBOL
++0x373db350    kstrtoint       vmlinux EXPORT_SYMBOL
++0xfffad96c    call_srcu       vmlinux EXPORT_SYMBOL_GPL
++0x4806c9d5    drm_connector_init      vmlinux EXPORT_SYMBOL
++0x9fce80db    fb_notifier_call_chain  vmlinux EXPORT_SYMBOL_GPL
++0x856629e7    __tracepoint_rpm_return_int     vmlinux EXPORT_SYMBOL_GPL
++0x8f6cee77    __round_jiffies_relative        vmlinux EXPORT_SYMBOL_GPL
++0xb992cdc2    cpufreq_get_policy      vmlinux EXPORT_SYMBOL
++0x9a7784ef    v4l2_device_put vmlinux EXPORT_SYMBOL_GPL
++0xab2d53fe    wm8994_reg_write        vmlinux EXPORT_SYMBOL_GPL
++0xa7c124ba    inet_frag_maybe_warn_overflow   vmlinux EXPORT_SYMBOL
++0x81cbdbae    inet_twsk_alloc vmlinux EXPORT_SYMBOL_GPL
++0x037a0cba    kfree   vmlinux EXPORT_SYMBOL
++0xfb0c30cd    __rt_mutex_init vmlinux EXPORT_SYMBOL_GPL
++0x578a9e0d    kill_pid_info_as_cred   vmlinux EXPORT_SYMBOL_GPL
++0xa8ca80b5    __serio_register_driver vmlinux EXPORT_SYMBOL
++0x182a39a6    max8997_bulk_read       vmlinux EXPORT_SYMBOL_GPL
++0x2fd9648c    pm_genpd_add_callbacks  vmlinux EXPORT_SYMBOL_GPL
++0xc5c2a452    tty_put_char    vmlinux EXPORT_SYMBOL_GPL
++0x49b60948    xfrm_state_delete       vmlinux EXPORT_SYMBOL
++0x0693c220    nf_register_sockopt     vmlinux EXPORT_SYMBOL
++0x8c9e0cae    sock_kmalloc    vmlinux EXPORT_SYMBOL
++0xb9638db4    snd_pcm_rate_to_rate_bit        vmlinux EXPORT_SYMBOL
++0xf3b3adff    cgroup_load_subsys      vmlinux EXPORT_SYMBOL_GPL
++0x75911fdf    ip_tunnel_get_stats64   vmlinux EXPORT_SYMBOL_GPL
++0xe7d4daac    seq_list_next   vmlinux EXPORT_SYMBOL
++0x2fe252cc    unregister_inet6addr_notifier   vmlinux EXPORT_SYMBOL
++0xa06df9e1    __kfifo_dma_out_finish_r        vmlinux EXPORT_SYMBOL
++0x01e0e788    st_sensors_allocate_trigger     vmlinux EXPORT_SYMBOL
++0xcdd15087    of_irq_map_one  vmlinux EXPORT_SYMBOL_GPL
++0xea97422f    vb2_queue_release       vmlinux EXPORT_SYMBOL_GPL
++0xb37c3615    cfg80211_rx_unexpected_4addr_frame      vmlinux EXPORT_SYMBOL
++0xbc2271b2    ipv6_chk_addr   vmlinux EXPORT_SYMBOL
++0x9e9ab99d    __blkdev_driver_ioctl   vmlinux EXPORT_SYMBOL_GPL
++0x54f3cc64    blk_alloc_queue_node    vmlinux EXPORT_SYMBOL
++0xd20b9da2    iio_buffer_unregister   vmlinux EXPORT_SYMBOL
++0xa8f8abd2    v4l2_ctrl_g_ctrl_int64  vmlinux EXPORT_SYMBOL
++0xc2aa0765    dev_pm_qos_flags        vmlinux EXPORT_SYMBOL_GPL
++0xf5f14859    uart_suspend_port       vmlinux EXPORT_SYMBOL
++0xe7722171    flex_array_free vmlinux EXPORT_SYMBOL
++0xa27aead4    blk_queue_flush vmlinux EXPORT_SYMBOL_GPL
++0x713c83fa    bio_phys_segments       vmlinux EXPORT_SYMBOL
++0xdaa57ec3    totalhigh_pages vmlinux EXPORT_SYMBOL
++0x2a2a7a3b    rndis_set_param_dev     vmlinux EXPORT_SYMBOL
++0x54fd2e8d    scsi_device_resume      vmlinux EXPORT_SYMBOL
++0x7a060e19    ipv6_find_tlv   vmlinux EXPORT_SYMBOL_GPL
++0x8fe6ac1e    neigh_changeaddr        vmlinux EXPORT_SYMBOL
++0xa38c2c00    snd_soc_jack_get_type   vmlinux EXPORT_SYMBOL_GPL
++0x710c73b6    crypto_unregister_notifier      vmlinux EXPORT_SYMBOL_GPL
++0xda0c24cc    invalidate_inode_pages2 vmlinux EXPORT_SYMBOL_GPL
++0x72741f25    trace_vbprintk  vmlinux EXPORT_SYMBOL_GPL
++0xccb0efda    do_unregister_con_driver        vmlinux EXPORT_SYMBOL_GPL
++0xa120d33c    tty_unregister_ldisc    vmlinux EXPORT_SYMBOL
++0xd644f377    tty_standard_install    vmlinux EXPORT_SYMBOL_GPL
++0x31222024    amba_apb_device_add_res vmlinux EXPORT_SYMBOL_GPL
++0xf8299259    cfg80211_michael_mic_failure    vmlinux EXPORT_SYMBOL
++0xbe53b873    ipt_do_table    vmlinux EXPORT_SYMBOL
++0xc96046ab    kmem_cache_destroy      vmlinux EXPORT_SYMBOL
++0x79105e99    add_to_page_cache_locked        vmlinux EXPORT_SYMBOL
++0x4e109192    ring_buffer_entries     vmlinux EXPORT_SYMBOL_GPL
++0x82a5e5e7    led_classdev_register   vmlinux EXPORT_SYMBOL_GPL
++0xd952a550    vb2_ioctl_reqbufs       vmlinux EXPORT_SYMBOL_GPL
++0xcb929a3c    scsi_calculate_bounce_limit     vmlinux EXPORT_SYMBOL
++0x33746f3f    xfrm_prepare_input      vmlinux EXPORT_SYMBOL
++0xd1dc81ae    xt_find_target  vmlinux EXPORT_SYMBOL
++0x92f468ad    drm_mode_object_find    vmlinux EXPORT_SYMBOL
++0x5a268d54    drm_clflush_sg  vmlinux EXPORT_SYMBOL
++0x827cc6a1    pptp_msg_name   vmlinux EXPORT_SYMBOL
++0xd4433787    vm_event_states vmlinux EXPORT_SYMBOL
++0x488b605d    __module_get    vmlinux EXPORT_SYMBOL
++0x081f3afb    complete_all    vmlinux EXPORT_SYMBOL
++0x9bce482f    __release_region        vmlinux EXPORT_SYMBOL
++0xd007f03b    phy_mii_ioctl   vmlinux EXPORT_SYMBOL
++0x5ef79e43    exynos_drm_subdrv_open  vmlinux EXPORT_SYMBOL_GPL
++0x34b60845    nfc_alloc_recv_skb      vmlinux EXPORT_SYMBOL
++0x075af6c0    cfg80211_reg_can_beacon vmlinux EXPORT_SYMBOL
++0x347013de    nla_validate    vmlinux EXPORT_SYMBOL
++0x70f6100f    bdi_register    vmlinux EXPORT_SYMBOL
++0xcf54ea93    async_unregister_domain vmlinux EXPORT_SYMBOL_GPL
++0xb6efaccd    rndis_rm_hdr    vmlinux EXPORT_SYMBOL
++0x5ed040b0    pm_set_vt_switch        vmlinux EXPORT_SYMBOL
++0x3ad0517a    tty_free_termios        vmlinux EXPORT_SYMBOL
++0x5fa643a3    amba_device_alloc       vmlinux EXPORT_SYMBOL_GPL
++0x73abc38f    inet_csk_clear_xmit_timers      vmlinux EXPORT_SYMBOL
++0x52e3e4a5    snd_pcm_hw_param_value  vmlinux EXPORT_SYMBOL
++0x7129e5f8    hex_asc vmlinux EXPORT_SYMBOL
++0xa0973520    fat_time_unix2fat       vmlinux EXPORT_SYMBOL_GPL
++0x522a28d0    mmc_regulator_get_supply        vmlinux EXPORT_SYMBOL_GPL
++0xac84055a    nf_nat_follow_master    vmlinux EXPORT_SYMBOL
++0x2aa0e4fc    strncasecmp     vmlinux EXPORT_SYMBOL
++0x9d5dfdfe    fuse_dev_release        vmlinux EXPORT_SYMBOL_GPL
++0xf54fdd41    default_llseek  vmlinux EXPORT_SYMBOL
++0xebec57c4    ring_buffer_oldest_event_ts     vmlinux EXPORT_SYMBOL_GPL
++0x329318c8    iio_channel_release_all vmlinux EXPORT_SYMBOL_GPL
++0xfc9a70ae    tty_get_pgrp    vmlinux EXPORT_SYMBOL_GPL
++0xdbf66d36    tcp_read_sock   vmlinux EXPORT_SYMBOL
++0xc18db9a3    snd_jack_new    vmlinux EXPORT_SYMBOL
++0x5df2ea54    sdhci_pltfm_free        vmlinux EXPORT_SYMBOL_GPL
++0x137901ef    ip_fragment     vmlinux EXPORT_SYMBOL
++0x815b5dd4    match_octal     vmlinux EXPORT_SYMBOL
++0x6b475280    bio_map_kern    vmlinux EXPORT_SYMBOL
++0x3abac74c    scsi_eh_prep_cmnd       vmlinux EXPORT_SYMBOL
++0xd162929f    tty_port_register_device_attr   vmlinux EXPORT_SYMBOL_GPL
++0x296f9f79    xt_register_targets     vmlinux EXPORT_SYMBOL
++0x27000b29    crc32c  vmlinux EXPORT_SYMBOL
++0x2956cef1    vfs_fsync       vmlinux EXPORT_SYMBOL
++0x18ae03d3    poll_freewait   vmlinux EXPORT_SYMBOL
++0x40c7247c    si_meminfo      vmlinux EXPORT_SYMBOL
++0x0034e52c    kthread_create_on_node  vmlinux EXPORT_SYMBOL
++0xeecb608e    i2c_smbus_write_byte    vmlinux EXPORT_SYMBOL
++0x907ada97    scsi_register_driver    vmlinux EXPORT_SYMBOL
++0x7cc1b7fd    max77693_bulk_read      vmlinux EXPORT_SYMBOL_GPL
++0x3274b08e    hdmi_avi_infoframe_init vmlinux EXPORT_SYMBOL
++0xde8c763d    cpu_v7_set_pte_ext      vmlinux EXPORT_SYMBOL
++0x2294b28a    snd_timer_pause vmlinux EXPORT_SYMBOL
++0x5e95b1cd    current_umask   vmlinux EXPORT_SYMBOL
++0xd2091a52    get_fs_type     vmlinux EXPORT_SYMBOL
++0x94893493    ref_module      vmlinux EXPORT_SYMBOL_GPL
++0x657ca634    iommu_domain_get_attr   vmlinux EXPORT_SYMBOL_GPL
++0x6b758637    iommu_domain_set_attr   vmlinux EXPORT_SYMBOL_GPL
++0xe835dcde    nf_nat_pptp_hook_outbound       vmlinux EXPORT_SYMBOL_GPL
++0x3ac1fef9    drm_mode_legacy_fb_format       vmlinux EXPORT_SYMBOL
++0x7cc88e22    tty_driver_kref_put     vmlinux EXPORT_SYMBOL
++0x24fc46b6    regulator_bulk_free     vmlinux EXPORT_SYMBOL_GPL
++0x776bea60    ip6_tnl_dst_check       vmlinux EXPORT_SYMBOL_GPL
++0x80690fc4    sock_prot_inuse_get     vmlinux EXPORT_SYMBOL_GPL
++0xb8aa9e8f    aead_geniv_init vmlinux EXPORT_SYMBOL_GPL
++0x35bac202    generic_write_end       vmlinux EXPORT_SYMBOL
++0x59e2743e    call_rcu_bh     vmlinux EXPORT_SYMBOL_GPL
++0x639f9176    devm_request_threaded_irq       vmlinux EXPORT_SYMBOL
++0x67955ce6    profile_hits    vmlinux EXPORT_SYMBOL_GPL
++0xa53a0240    usb_wakeup_notification vmlinux EXPORT_SYMBOL_GPL
++0xf5e3c0cf    scsi_host_set_state     vmlinux EXPORT_SYMBOL
++0x31b21f37    nat_t120_hook   vmlinux EXPORT_SYMBOL_GPL
++0xcd083b10    unregister_sound_dsp    vmlinux EXPORT_SYMBOL
++0xda529e9e    blk_start_queue vmlinux EXPORT_SYMBOL
++0xd84ce699    bio_copy_user   vmlinux EXPORT_SYMBOL
++0x7a4497db    kzfree  vmlinux EXPORT_SYMBOL
++0x91bbc6b9    genphy_config_aneg      vmlinux EXPORT_SYMBOL
++0x1c251434    of_mm_gpiochip_add      vmlinux EXPORT_SYMBOL
++0x8e10854d    inet_sk_diag_fill       vmlinux EXPORT_SYMBOL_GPL
++0x07d2ea7a    arpt_unregister_table   vmlinux EXPORT_SYMBOL
++0x2c038769    sk_filter       vmlinux EXPORT_SYMBOL
++0x57e267af    generic_removexattr     vmlinux EXPORT_SYMBOL
++0x643b400e    deactivate_super        vmlinux EXPORT_SYMBOL
++0xcf241a0c    vmap    vmlinux EXPORT_SYMBOL
++0x31f0bb78    __kmap_atomic_idx       vmlinux EXPORT_SYMBOL
++0x4e32f63f    devm_clk_put    vmlinux EXPORT_SYMBOL
++0x77f2c351    v4l2_ctrl_s_ctrl_int64  vmlinux EXPORT_SYMBOL
++0xed9fdd16    gether_setup_name_default       vmlinux EXPORT_SYMBOL
++0x6f572dd2    devm_remove_action      vmlinux EXPORT_SYMBOL_GPL
++0xa8f59416    gpio_direction_output   vmlinux EXPORT_SYMBOL_GPL
+diff --git a/abi-checker/sample/LICENSE b/abi-checker/sample/LICENSE
+new file mode 100644
+index 0000000..63fabc1
+--- /dev/null
++++ b/abi-checker/sample/LICENSE
+@@ -0,0 +1,848 @@
++Copyright (C) 2007-2011 David Zeuthen <zeuthen@gmail.com>
++Copyright (C) 2007-2011 Red Hat, Inc.
++All Rights Reserved.
++
++The source code for the udisks daemon and command-line tools are
++licensed to you under the GNU General Public License. Either version 2
++of the License, or (at your option) any later version.
++
++The source code for the libudisks2 dynamic library is licensed to you
++under the GNU Library General Public License. Either version 2 of the
++License, or (at your option) any later version.
++
++Each file is marked with copyright and licensing headers.
++
++The GPLv2 and LGPLv2 licenses are included below.
++
++-- BEGIN GPLv2+ License ---
++
++                    GNU GENERAL PUBLIC LICENSE
++                       Version 2, June 1991
++
++ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
++ 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++
++ Everyone is permitted to copy and distribute verbatim copies
++ of this license document, but changing it is not allowed.
++
++                            Preamble
++
++  The licenses for most software are designed to take away your
++freedom to share and change it.  By contrast, the GNU General Public
++License is intended to guarantee your freedom to share and change free
++software--to make sure the software is free for all its users.  This
++General Public License applies to most of the Free Software
++Foundation's software and to any other program whose authors commit to
++using it.  (Some other Free Software Foundation software is covered by
++the GNU Library General Public License instead.)  You can apply it to
++your programs, too.
++
++  When we speak of free software, we are referring to freedom, not
++price.  Our General Public Licenses are designed to make sure that you
++have the freedom to distribute copies of free software (and charge for
++this service if you wish), that you receive source code or can get it
++if you want it, that you can change the software or use pieces of it
++in new free programs; and that you know you can do these things.
++
++  To protect your rights, we need to make restrictions that forbid
++anyone to deny you these rights or to ask you to surrender the rights.
++These restrictions translate to certain responsibilities for you if you
++distribute copies of the software, or if you modify it.
++
++  For example, if you distribute copies of such a program, whether
++gratis or for a fee, you must give the recipients all the rights that
++you have.  You must make sure that they, too, receive or can get the
++source code.  And you must show them these terms so they know their
++rights.
++
++  We protect your rights with two steps: (1) copyright the software, and
++(2) offer you this license which gives you legal permission to copy,
++distribute and/or modify the software.
++
++  Also, for each author's protection and ours, we want to make certain
++that everyone understands that there is no warranty for this free
++software.  If the software is modified by someone else and passed on, we
++want its recipients to know that what they have is not the original, so
++that any problems introduced by others will not reflect on the original
++authors' reputations.
++
++  Finally, any free program is threatened constantly by software
++patents.  We wish to avoid the danger that redistributors of a free
++program will individually obtain patent licenses, in effect making the
++program proprietary.  To prevent this, we have made it clear that any
++patent must be licensed for everyone's free use or not licensed at all.
++
++  The precise terms and conditions for copying, distribution and
++modification follow.
++
++                    GNU GENERAL PUBLIC LICENSE
++   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
++
++  0. This License applies to any program or other work which contains
++a notice placed by the copyright holder saying it may be distributed
++under the terms of this General Public License.  The "Program", below,
++refers to any such program or work, and a "work based on the Program"
++means either the Program or any derivative work under copyright law:
++that is to say, a work containing the Program or a portion of it,
++either verbatim or with modifications and/or translated into another
++language.  (Hereinafter, translation is included without limitation in
++the term "modification".)  Each licensee is addressed as "you".
++
++Activities other than copying, distribution and modification are not
++covered by this License; they are outside its scope.  The act of
++running the Program is not restricted, and the output from the Program
++is covered only if its contents constitute a work based on the
++Program (independent of having been made by running the Program).
++Whether that is true depends on what the Program does.
++
++  1. You may copy and distribute verbatim copies of the Program's
++source code as you receive it, in any medium, provided that you
++conspicuously and appropriately publish on each copy an appropriate
++copyright notice and disclaimer of warranty; keep intact all the
++notices that refer to this License and to the absence of any warranty;
++and give any other recipients of the Program a copy of this License
++along with the Program.
++
++You may charge a fee for the physical act of transferring a copy, and
++you may at your option offer warranty protection in exchange for a fee.
++
++  2. You may modify your copy or copies of the Program or any portion
++of it, thus forming a work based on the Program, and copy and
++distribute such modifications or work under the terms of Section 1
++above, provided that you also meet all of these conditions:
++
++    a) You must cause the modified files to carry prominent notices
++    stating that you changed the files and the date of any change.
++
++    b) You must cause any work that you distribute or publish, that in
++    whole or in part contains or is derived from the Program or any
++    part thereof, to be licensed as a whole at no charge to all third
++    parties under the terms of this License.
++
++    c) If the modified program normally reads commands interactively
++    when run, you must cause it, when started running for such
++    interactive use in the most ordinary way, to print or display an
++    announcement including an appropriate copyright notice and a
++    notice that there is no warranty (or else, saying that you provide
++    a warranty) and that users may redistribute the program under
++    these conditions, and telling the user how to view a copy of this
++    License.  (Exception: if the Program itself is interactive but
++    does not normally print such an announcement, your work based on
++    the Program is not required to print an announcement.)
++
++These requirements apply to the modified work as a whole.  If
++identifiable sections of that work are not derived from the Program,
++and can be reasonably considered independent and separate works in
++themselves, then this License, and its terms, do not apply to those
++sections when you distribute them as separate works.  But when you
++distribute the same sections as part of a whole which is a work based
++on the Program, the distribution of the whole must be on the terms of
++this License, whose permissions for other licensees extend to the
++entire whole, and thus to each and every part regardless of who wrote it.
++
++Thus, it is not the intent of this section to claim rights or contest
++your rights to work written entirely by you; rather, the intent is to
++exercise the right to control the distribution of derivative or
++collective works based on the Program.
++
++In addition, mere aggregation of another work not based on the Program
++with the Program (or with a work based on the Program) on a volume of
++a storage or distribution medium does not bring the other work under
++the scope of this License.
++
++  3. You may copy and distribute the Program (or a work based on it,
++under Section 2) in object code or executable form under the terms of
++Sections 1 and 2 above provided that you also do one of the following:
++
++    a) Accompany it with the complete corresponding machine-readable
++    source code, which must be distributed under the terms of Sections
++    1 and 2 above on a medium customarily used for software interchange; or,
++
++    b) Accompany it with a written offer, valid for at least three
++    years, to give any third party, for a charge no more than your
++    cost of physically performing source distribution, a complete
++    machine-readable copy of the corresponding source code, to be
++    distributed under the terms of Sections 1 and 2 above on a medium
++    customarily used for software interchange; or,
++
++    c) Accompany it with the information you received as to the offer
++    to distribute corresponding source code.  (This alternative is
++    allowed only for noncommercial distribution and only if you
++    received the program in object code or executable form with such
++    an offer, in accord with Subsection b above.)
++
++The source code for a work means the preferred form of the work for
++making modifications to it.  For an executable work, complete source
++code means all the source code for all modules it contains, plus any
++associated interface definition files, plus the scripts used to
++control compilation and installation of the executable.  However, as a
++special exception, the source code distributed need not include
++anything that is normally distributed (in either source or binary
++form) with the major components (compiler, kernel, and so on) of the
++operating system on which the executable runs, unless that component
++itself accompanies the executable.
++
++If distribution of executable or object code is made by offering
++access to copy from a designated place, then offering equivalent
++access to copy the source code from the same place counts as
++distribution of the source code, even though third parties are not
++compelled to copy the source along with the object code.
++
++  4. You may not copy, modify, sublicense, or distribute the Program
++except as expressly provided under this License.  Any attempt
++otherwise to copy, modify, sublicense or distribute the Program is
++void, and will automatically terminate your rights under this License.
++However, parties who have received copies, or rights, from you under
++this License will not have their licenses terminated so long as such
++parties remain in full compliance.
++
++  5. You are not required to accept this License, since you have not
++signed it.  However, nothing else grants you permission to modify or
++distribute the Program or its derivative works.  These actions are
++prohibited by law if you do not accept this License.  Therefore, by
++modifying or distributing the Program (or any work based on the
++Program), you indicate your acceptance of this License to do so, and
++all its terms and conditions for copying, distributing or modifying
++the Program or works based on it.
++
++  6. Each time you redistribute the Program (or any work based on the
++Program), the recipient automatically receives a license from the
++original licensor to copy, distribute or modify the Program subject to
++these terms and conditions.  You may not impose any further
++restrictions on the recipients' exercise of the rights granted herein.
++You are not responsible for enforcing compliance by third parties to
++this License.
++
++  7. If, as a consequence of a court judgment or allegation of patent
++infringement or for any other reason (not limited to patent issues),
++conditions are imposed on you (whether by court order, agreement or
++otherwise) that contradict the conditions of this License, they do not
++excuse you from the conditions of this License.  If you cannot
++distribute so as to satisfy simultaneously your obligations under this
++License and any other pertinent obligations, then as a consequence you
++may not distribute the Program at all.  For example, if a patent
++license would not permit royalty-free redistribution of the Program by
++all those who receive copies directly or indirectly through you, then
++the only way you could satisfy both it and this License would be to
++refrain entirely from distribution of the Program.
++
++If any portion of this section is held invalid or unenforceable under
++any particular circumstance, the balance of the section is intended to
++apply and the section as a whole is intended to apply in other
++circumstances.
++
++It is not the purpose of this section to induce you to infringe any
++patents or other property right claims or to contest validity of any
++such claims; this section has the sole purpose of protecting the
++integrity of the free software distribution system, which is
++implemented by public license practices.  Many people have made
++generous contributions to the wide range of software distributed
++through that system in reliance on consistent application of that
++system; it is up to the author/donor to decide if he or she is willing
++to distribute software through any other system and a licensee cannot
++impose that choice.
++
++This section is intended to make thoroughly clear what is believed to
++be a consequence of the rest of this License.
++
++  8. If the distribution and/or use of the Program is restricted in
++certain countries either by patents or by copyrighted interfaces, the
++original copyright holder who places the Program under this License
++may add an explicit geographical distribution limitation excluding
++those countries, so that distribution is permitted only in or among
++countries not thus excluded.  In such case, this License incorporates
++the limitation as if written in the body of this License.
++
++  9. The Free Software Foundation may publish revised and/or new versions
++of the General Public License from time to time.  Such new versions will
++be similar in spirit to the present version, but may differ in detail to
++address new problems or concerns.
++
++Each version is given a distinguishing version number.  If the Program
++specifies a version number of this License which applies to it and "any
++later version", you have the option of following the terms and conditions
++either of that version or of any later version published by the Free
++Software Foundation.  If the Program does not specify a version number of
++this License, you may choose any version ever published by the Free Software
++Foundation.
++
++  10. If you wish to incorporate parts of the Program into other free
++programs whose distribution conditions are different, write to the author
++to ask for permission.  For software which is copyrighted by the Free
++Software Foundation, write to the Free Software Foundation; we sometimes
++make exceptions for this.  Our decision will be guided by the two goals
++of preserving the free status of all derivatives of our free software and
++of promoting the sharing and reuse of software generally.
++
++                            NO WARRANTY
++
++  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
++FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
++OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
++PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
++OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
++TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
++PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
++REPAIR OR CORRECTION.
++
++  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
++WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
++REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
++INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
++OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
++TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
++YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
++PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
++POSSIBILITY OF SUCH DAMAGES.
++
++                     END OF TERMS AND CONDITIONS
++
++            How to Apply These Terms to Your New Programs
++
++  If you develop a new program, and you want it to be of the greatest
++possible use to the public, the best way to achieve this is to make it
++free software which everyone can redistribute and change under these terms.
++
++  To do so, attach the following notices to the program.  It is safest
++to attach them to the start of each source file to most effectively
++convey the exclusion of warranty; and each file should have at least
++the "copyright" line and a pointer to where the full notice is found.
++
++    <one line to give the program's name and a brief idea of what it does.>
++    Copyright (C) <year>  <name of author>
++
++    This program is free software; you can redistribute it and/or modify
++    it under the terms of the GNU General Public License as published by
++    the Free Software Foundation; either version 2 of the License, or
++    (at your option) any later version.
++
++    This program is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++    GNU General Public License for more details.
++
++    You should have received a copy of the GNU General Public License
++    along with this program; if not, write to the Free Software
++    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++
++
++Also add information on how to contact you by electronic and paper mail.
++
++If the program is interactive, make it output a short notice like this
++when it starts in an interactive mode:
++
++    Gnomovision version 69, Copyright (C) year name of author
++    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
++    This is free software, and you are welcome to redistribute it
++    under certain conditions; type `show c' for details.
++
++The hypothetical commands `show w' and `show c' should show the appropriate
++parts of the General Public License.  Of course, the commands you use may
++be called something other than `show w' and `show c'; they could even be
++mouse-clicks or menu items--whatever suits your program.
++
++You should also get your employer (if you work as a programmer) or your
++school, if any, to sign a "copyright disclaimer" for the program, if
++necessary.  Here is a sample; alter the names:
++
++  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
++  `Gnomovision' (which makes passes at compilers) written by James Hacker.
++
++  <signature of Ty Coon>, 1 April 1989
++  Ty Coon, President of Vice
++
++This General Public License does not permit incorporating your program into
++proprietary programs.  If your program is a subroutine library, you may
++consider it more useful to permit linking proprietary applications with the
++library.  If this is what you want to do, use the GNU Library General
++Public License instead of this License.
++
++-- END GPLv2+ License ---
++
++-- BEGIN LGPLv2+ License ---
++
++                  GNU LIBRARY GENERAL PUBLIC LICENSE
++                       Version 2, June 1991
++
++ Copyright (C) 1991 Free Software Foundation, Inc.
++                    59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ Everyone is permitted to copy and distribute verbatim copies
++ of this license document, but changing it is not allowed.
++
++[This is the first released version of the library GPL.  It is
++ numbered 2 because it goes with version 2 of the ordinary GPL.]
++
++                            Preamble
++
++  The licenses for most software are designed to take away your
++freedom to share and change it.  By contrast, the GNU General Public
++Licenses are intended to guarantee your freedom to share and change
++free software--to make sure the software is free for all its users.
++
++  This license, the Library General Public License, applies to some
++specially designated Free Software Foundation software, and to any
++other libraries whose authors decide to use it.  You can use it for
++your libraries, too.
++
++  When we speak of free software, we are referring to freedom, not
++price.  Our General Public Licenses are designed to make sure that you
++have the freedom to distribute copies of free software (and charge for
++this service if you wish), that you receive source code or can get it
++if you want it, that you can change the software or use pieces of it
++in new free programs; and that you know you can do these things.
++
++  To protect your rights, we need to make restrictions that forbid
++anyone to deny you these rights or to ask you to surrender the rights.
++These restrictions translate to certain responsibilities for you if
++you distribute copies of the library, or if you modify it.
++
++  For example, if you distribute copies of the library, whether gratis
++or for a fee, you must give the recipients all the rights that we gave
++you.  You must make sure that they, too, receive or can get the source
++code.  If you link a program with the library, you must provide
++complete object files to the recipients so that they can relink them
++with the library, after making changes to the library and recompiling
++it.  And you must show them these terms so they know their rights.
++
++  Our method of protecting your rights has two steps: (1) copyright
++the library, and (2) offer you this license which gives you legal
++permission to copy, distribute and/or modify the library.
++
++  Also, for each distributor's protection, we want to make certain
++that everyone understands that there is no warranty for this free
++library.  If the library is modified by someone else and passed on, we
++want its recipients to know that what they have is not the original
++version, so that any problems introduced by others will not reflect on
++the original authors' reputations.
++
++  Finally, any free program is threatened constantly by software
++patents.  We wish to avoid the danger that companies distributing free
++software will individually obtain patent licenses, thus in effect
++transforming the program into proprietary software.  To prevent this,
++we have made it clear that any patent must be licensed for everyone's
++free use or not licensed at all.
++
++  Most GNU software, including some libraries, is covered by the ordinary
++GNU General Public License, which was designed for utility programs.  This
++license, the GNU Library General Public License, applies to certain
++designated libraries.  This license is quite different from the ordinary
++one; be sure to read it in full, and don't assume that anything in it is
++the same as in the ordinary license.
++
++  The reason we have a separate public license for some libraries is that
++they blur the distinction we usually make between modifying or adding to a
++program and simply using it.  Linking a program with a library, without
++changing the library, is in some sense simply using the library, and is
++analogous to running a utility program or application program.  However, in
++a textual and legal sense, the linked executable is a combined work, a
++derivative of the original library, and the ordinary General Public License
++treats it as such.
++
++  Because of this blurred distinction, using the ordinary General
++Public License for libraries did not effectively promote software
++sharing, because most developers did not use the libraries.  We
++concluded that weaker conditions might promote sharing better.
++
++  However, unrestricted linking of non-free programs would deprive the
++users of those programs of all benefit from the free status of the
++libraries themselves.  This Library General Public License is intended to
++permit developers of non-free programs to use free libraries, while
++preserving your freedom as a user of such programs to change the free
++libraries that are incorporated in them.  (We have not seen how to achieve
++this as regards changes in header files, but we have achieved it as regards
++changes in the actual functions of the Library.)  The hope is that this
++will lead to faster development of free libraries.
++
++  The precise terms and conditions for copying, distribution and
++modification follow.  Pay close attention to the difference between a
++"work based on the library" and a "work that uses the library".  The
++former contains code derived from the library, while the latter only
++works together with the library.
++
++  Note that it is possible for a library to be covered by the ordinary
++General Public License rather than by this special one.
++
++                  GNU LIBRARY GENERAL PUBLIC LICENSE
++   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
++
++  0. This License Agreement applies to any software library which
++contains a notice placed by the copyright holder or other authorized
++party saying it may be distributed under the terms of this Library
++General Public License (also called "this License").  Each licensee is
++addressed as "you".
++
++  A "library" means a collection of software functions and/or data
++prepared so as to be conveniently linked with application programs
++(which use some of those functions and data) to form executables.
++
++  The "Library", below, refers to any such software library or work
++which has been distributed under these terms.  A "work based on the
++Library" means either the Library or any derivative work under
++copyright law: that is to say, a work containing the Library or a
++portion of it, either verbatim or with modifications and/or translated
++straightforwardly into another language.  (Hereinafter, translation is
++included without limitation in the term "modification".)
++
++  "Source code" for a work means the preferred form of the work for
++making modifications to it.  For a library, complete source code means
++all the source code for all modules it contains, plus any associated
++interface definition files, plus the scripts used to control compilation
++and installation of the library.
++
++  Activities other than copying, distribution and modification are not
++covered by this License; they are outside its scope.  The act of
++running a program using the Library is not restricted, and output from
++such a program is covered only if its contents constitute a work based
++on the Library (independent of the use of the Library in a tool for
++writing it).  Whether that is true depends on what the Library does
++and what the program that uses the Library does.
++
++  1. You may copy and distribute verbatim copies of the Library's
++complete source code as you receive it, in any medium, provided that
++you conspicuously and appropriately publish on each copy an
++appropriate copyright notice and disclaimer of warranty; keep intact
++all the notices that refer to this License and to the absence of any
++warranty; and distribute a copy of this License along with the
++Library.
++
++  You may charge a fee for the physical act of transferring a copy,
++and you may at your option offer warranty protection in exchange for a
++fee.
++
++  2. You may modify your copy or copies of the Library or any portion
++of it, thus forming a work based on the Library, and copy and
++distribute such modifications or work under the terms of Section 1
++above, provided that you also meet all of these conditions:
++
++    a) The modified work must itself be a software library.
++
++    b) You must cause the files modified to carry prominent notices
++    stating that you changed the files and the date of any change.
++
++    c) You must cause the whole of the work to be licensed at no
++    charge to all third parties under the terms of this License.
++
++    d) If a facility in the modified Library refers to a function or a
++    table of data to be supplied by an application program that uses
++    the facility, other than as an argument passed when the facility
++    is invoked, then you must make a good faith effort to ensure that,
++    in the event an application does not supply such function or
++    table, the facility still operates, and performs whatever part of
++    its purpose remains meaningful.
++
++    (For example, a function in a library to compute square roots has
++    a purpose that is entirely well-defined independent of the
++    application.  Therefore, Subsection 2d requires that any
++    application-supplied function or table used by this function must
++    be optional: if the application does not supply it, the square
++    root function must still compute square roots.)
++
++These requirements apply to the modified work as a whole.  If
++identifiable sections of that work are not derived from the Library,
++and can be reasonably considered independent and separate works in
++themselves, then this License, and its terms, do not apply to those
++sections when you distribute them as separate works.  But when you
++distribute the same sections as part of a whole which is a work based
++on the Library, the distribution of the whole must be on the terms of
++this License, whose permissions for other licensees extend to the
++entire whole, and thus to each and every part regardless of who wrote
++it.
++
++Thus, it is not the intent of this section to claim rights or contest
++your rights to work written entirely by you; rather, the intent is to
++exercise the right to control the distribution of derivative or
++collective works based on the Library.
++
++In addition, mere aggregation of another work not based on the Library
++with the Library (or with a work based on the Library) on a volume of
++a storage or distribution medium does not bring the other work under
++the scope of this License.
++
++  3. You may opt to apply the terms of the ordinary GNU General Public
++License instead of this License to a given copy of the Library.  To do
++this, you must alter all the notices that refer to this License, so
++that they refer to the ordinary GNU General Public License, version 2,
++instead of to this License.  (If a newer version than version 2 of the
++ordinary GNU General Public License has appeared, then you can specify
++that version instead if you wish.)  Do not make any other change in
++these notices.
++
++  Once this change is made in a given copy, it is irreversible for
++that copy, so the ordinary GNU General Public License applies to all
++subsequent copies and derivative works made from that copy.
++
++  This option is useful when you wish to copy part of the code of
++the Library into a program that is not a library.
++
++  4. You may copy and distribute the Library (or a portion or
++derivative of it, under Section 2) in object code or executable form
++under the terms of Sections 1 and 2 above provided that you accompany
++it with the complete corresponding machine-readable source code, which
++must be distributed under the terms of Sections 1 and 2 above on a
++medium customarily used for software interchange.
++
++  If distribution of object code is made by offering access to copy
++from a designated place, then offering equivalent access to copy the
++source code from the same place satisfies the requirement to
++distribute the source code, even though third parties are not
++compelled to copy the source along with the object code.
++
++  5. A program that contains no derivative of any portion of the
++Library, but is designed to work with the Library by being compiled or
++linked with it, is called a "work that uses the Library".  Such a
++work, in isolation, is not a derivative work of the Library, and
++therefore falls outside the scope of this License.
++
++  However, linking a "work that uses the Library" with the Library
++creates an executable that is a derivative of the Library (because it
++contains portions of the Library), rather than a "work that uses the
++library".  The executable is therefore covered by this License.
++Section 6 states terms for distribution of such executables.
++
++  When a "work that uses the Library" uses material from a header file
++that is part of the Library, the object code for the work may be a
++derivative work of the Library even though the source code is not.
++Whether this is true is especially significant if the work can be
++linked without the Library, or if the work is itself a library.  The
++threshold for this to be true is not precisely defined by law.
++
++  If such an object file uses only numerical parameters, data
++structure layouts and accessors, and small macros and small inline
++functions (ten lines or less in length), then the use of the object
++file is unrestricted, regardless of whether it is legally a derivative
++work.  (Executables containing this object code plus portions of the
++Library will still fall under Section 6.)
++
++  Otherwise, if the work is a derivative of the Library, you may
++distribute the object code for the work under the terms of Section 6.
++Any executables containing that work also fall under Section 6,
++whether or not they are linked directly with the Library itself.
++
++  6. As an exception to the Sections above, you may also compile or
++link a "work that uses the Library" with the Library to produce a
++work containing portions of the Library, and distribute that work
++under terms of your choice, provided that the terms permit
++modification of the work for the customer's own use and reverse
++engineering for debugging such modifications.
++
++  You must give prominent notice with each copy of the work that the
++Library is used in it and that the Library and its use are covered by
++this License.  You must supply a copy of this License.  If the work
++during execution displays copyright notices, you must include the
++copyright notice for the Library among them, as well as a reference
++directing the user to the copy of this License.  Also, you must do one
++of these things:
++
++    a) Accompany the work with the complete corresponding
++    machine-readable source code for the Library including whatever
++    changes were used in the work (which must be distributed under
++    Sections 1 and 2 above); and, if the work is an executable linked
++    with the Library, with the complete machine-readable "work that
++    uses the Library", as object code and/or source code, so that the
++    user can modify the Library and then relink to produce a modified
++    executable containing the modified Library.  (It is understood
++    that the user who changes the contents of definitions files in the
++    Library will not necessarily be able to recompile the application
++    to use the modified definitions.)
++
++    b) Accompany the work with a written offer, valid for at
++    least three years, to give the same user the materials
++    specified in Subsection 6a, above, for a charge no more
++    than the cost of performing this distribution.
++
++    c) If distribution of the work is made by offering access to copy
++    from a designated place, offer equivalent access to copy the above
++    specified materials from the same place.
++
++    d) Verify that the user has already received a copy of these
++    materials or that you have already sent this user a copy.
++
++  For an executable, the required form of the "work that uses the
++Library" must include any data and utility programs needed for
++reproducing the executable from it.  However, as a special exception,
++the source code distributed need not include anything that is normally
++distributed (in either source or binary form) with the major
++components (compiler, kernel, and so on) of the operating system on
++which the executable runs, unless that component itself accompanies
++the executable.
++
++  It may happen that this requirement contradicts the license
++restrictions of other proprietary libraries that do not normally
++accompany the operating system.  Such a contradiction means you cannot
++use both them and the Library together in an executable that you
++distribute.
++
++  7. You may place library facilities that are a work based on the
++Library side-by-side in a single library together with other library
++facilities not covered by this License, and distribute such a combined
++library, provided that the separate distribution of the work based on
++the Library and of the other library facilities is otherwise
++permitted, and provided that you do these two things:
++
++    a) Accompany the combined library with a copy of the same work
++    based on the Library, uncombined with any other library
++    facilities.  This must be distributed under the terms of the
++    Sections above.
++
++    b) Give prominent notice with the combined library of the fact
++    that part of it is a work based on the Library, and explaining
++    where to find the accompanying uncombined form of the same work.
++
++  8. You may not copy, modify, sublicense, link with, or distribute
++the Library except as expressly provided under this License.  Any
++attempt otherwise to copy, modify, sublicense, link with, or
++distribute the Library is void, and will automatically terminate your
++rights under this License.  However, parties who have received copies,
++or rights, from you under this License will not have their licenses
++terminated so long as such parties remain in full compliance.
++
++  9. You are not required to accept this License, since you have not
++signed it.  However, nothing else grants you permission to modify or
++distribute the Library or its derivative works.  These actions are
++prohibited by law if you do not accept this License.  Therefore, by
++modifying or distributing the Library (or any work based on the
++Library), you indicate your acceptance of this License to do so, and
++all its terms and conditions for copying, distributing or modifying
++the Library or works based on it.
++
++  10. Each time you redistribute the Library (or any work based on the
++Library), the recipient automatically receives a license from the
++original licensor to copy, distribute, link with or modify the Library
++subject to these terms and conditions.  You may not impose any further
++restrictions on the recipients' exercise of the rights granted herein.
++You are not responsible for enforcing compliance by third parties to
++this License.
++
++  11. If, as a consequence of a court judgment or allegation of patent
++infringement or for any other reason (not limited to patent issues),
++conditions are imposed on you (whether by court order, agreement or
++otherwise) that contradict the conditions of this License, they do not
++excuse you from the conditions of this License.  If you cannot
++distribute so as to satisfy simultaneously your obligations under this
++License and any other pertinent obligations, then as a consequence you
++may not distribute the Library at all.  For example, if a patent
++license would not permit royalty-free redistribution of the Library by
++all those who receive copies directly or indirectly through you, then
++the only way you could satisfy both it and this License would be to
++refrain entirely from distribution of the Library.
++
++If any portion of this section is held invalid or unenforceable under any
++particular circumstance, the balance of the section is intended to apply,
++and the section as a whole is intended to apply in other circumstances.
++
++It is not the purpose of this section to induce you to infringe any
++patents or other property right claims or to contest validity of any
++such claims; this section has the sole purpose of protecting the
++integrity of the free software distribution system which is
++implemented by public license practices.  Many people have made
++generous contributions to the wide range of software distributed
++through that system in reliance on consistent application of that
++system; it is up to the author/donor to decide if he or she is willing
++to distribute software through any other system and a licensee cannot
++impose that choice.
++
++This section is intended to make thoroughly clear what is believed to
++be a consequence of the rest of this License.
++
++  12. If the distribution and/or use of the Library is restricted in
++certain countries either by patents or by copyrighted interfaces, the
++original copyright holder who places the Library under this License may add
++an explicit geographical distribution limitation excluding those countries,
++so that distribution is permitted only in or among countries not thus
++excluded.  In such case, this License incorporates the limitation as if
++written in the body of this License.
++
++  13. The Free Software Foundation may publish revised and/or new
++versions of the Library General Public License from time to time.
++Such new versions will be similar in spirit to the present version,
++but may differ in detail to address new problems or concerns.
++
++Each version is given a distinguishing version number.  If the Library
++specifies a version number of this License which applies to it and
++"any later version", you have the option of following the terms and
++conditions either of that version or of any later version published by
++the Free Software Foundation.  If the Library does not specify a
++license version number, you may choose any version ever published by
++the Free Software Foundation.
++
++  14. If you wish to incorporate parts of the Library into other free
++programs whose distribution conditions are incompatible with these,
++write to the author to ask for permission.  For software which is
++copyrighted by the Free Software Foundation, write to the Free
++Software Foundation; we sometimes make exceptions for this.  Our
++decision will be guided by the two goals of preserving the free status
++of all derivatives of our free software and of promoting the sharing
++and reuse of software generally.
++
++                            NO WARRANTY
++
++  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
++WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
++EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
++OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
++KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
++IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
++LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
++THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
++
++  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
++WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
++AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
++FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
++CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
++LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
++RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
++FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
++SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
++DAMAGES.
++
++                     END OF TERMS AND CONDITIONS
++
++           How to Apply These Terms to Your New Libraries
++
++  If you develop a new library, and you want it to be of the greatest
++possible use to the public, we recommend making it free software that
++everyone can redistribute and change.  You can do so by permitting
++redistribution under these terms (or, alternatively, under the terms of the
++ordinary General Public License).
++
++  To apply these terms, attach the following notices to the library.  It is
++safest to attach them to the start of each source file to most effectively
++convey the exclusion of warranty; and each file should have at least the
++"copyright" line and a pointer to where the full notice is found.
++
++    <one line to give the library's name and a brief idea of what it does.>
++    Copyright (C) <year>  <name of author>
++
++    This library is free software; you can redistribute it and/or
++    modify it under the terms of the GNU Library General Public
++    License as published by the Free Software Foundation; either
++    version 2 of the License, or (at your option) any later version.
++
++    This library 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
++    Library General Public License for more details.
++
++    You should have received a copy of the GNU Library General Public
++    License along with this library; if not, write to the
++    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++    Boston, MA  02111-1307  USA.
++
++Also add information on how to contact you by electronic and paper mail.
++
++You should also get your employer (if you work as a programmer) or your
++school, if any, to sign a "copyright disclaimer" for the library, if
++necessary.  Here is a sample; alter the names:
++
++  Yoyodyne, Inc., hereby disclaims all copyright interest in the
++  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
++
++  <signature of Ty Coon>, 1 April 1990
++  Ty Coon, President of Vice
++
++That's all there is to it!
++
++-- END LGPLv2+ License ---
+diff --git a/abi-checker/sample/Makefile b/abi-checker/sample/Makefile
+new file mode 100644
+index 0000000..4759f3c
+--- /dev/null
++++ b/abi-checker/sample/Makefile
+@@ -0,0 +1,12 @@
++obj-m = sample_module.o
++
++all:
++      make -C /usr/src/linux-kernel-build-3.10.19-tizen_defconfig.1 M=$(PWD) modules
++
++install:
++      make -C /usr/src/linux-kernel-build-3.10.19-tizen_defconfig.1 M=$(PWD) modules_install
++
++clean:
++      make -C /usr/src/linux-kernel-build-3.10.19-tizen_defconfig.1 M=$(PWD) clean
++      
++
+diff --git a/abi-checker/sample/packaging/udisks-automount-agent.spec.txt b/abi-checker/sample/packaging/udisks-automount-agent.spec.txt
+new file mode 100644
+index 0000000..bca8416
+--- /dev/null
++++ b/abi-checker/sample/packaging/udisks-automount-agent.spec.txt
+@@ -0,0 +1,53 @@
++%define debug_package %{nil}
++Name:       sample-module
++Summary:    Test sample kernel module 2
++Version:    0.1.0
++Release:    1
++Group:      Base/Device Management
++License:    GPL-2.0
++Source0:    %{name}-%{version}.tar.gz
++BuildRequires: linux-kernel-sources
++BuildRequires: linux-kernel-headers
++BuildRequires: linux-kernel-build
++BuildRequires: linux-kernel-abi-tools
++BuildRequires: linux-kernel-abi-devel
++
++Requires: linux-kernel-uImage
++
++%package source
++Summary: Debug sample-kernel-module-2
++Group: Base/Device Management
++
++%description source
++Debug and sources sample-kernel-module-2
++
++%description
++TIZEN simple kernel module.  
++
++%prep
++%setup -q
++
++%build
++make %{?jobs:-j%jobs}
++# Create ABI/API dump fingerprint file
++/usr/local/bin/abi-module-dumper sample_module_2.ko sample_module_2.abidump
++
++%install
++mkdir -p %{_builddir}/lib/modules/3.10.19-tizen_defconfig.1/
++make INSTALL_MOD_PATH=%{buildroot}  install
++cp sample_module_2.abidump %{buildroot}/lib/modules/3.10.19-tizen_defconfig.1/extra/
++
++%post
++# list comptible kerel ABI/API versions
++/usr/local/bin/abi-module-kernels-list /lib/modules/3.10.19-tizen_defconfig.1/extra/sample_module_2.abidump
++
++# Test module ABI/API with the kernel ABI/API
++/usr/local/bin/abi-module-checker /lib/modules/3.10.19-tizen_defconfig.1/extra/sample_module_2.abidump
++
++%files
++/lib/modules/3.10.19-tizen_defconfig.1/extra/
++%license LICENSE
++
++%files source
++/usr/src/debug/sample-kernel-module-2-0.1.0/sample_module_2.c
++/usr/src/debug/sample-kernel-module-2-0.1.0/sample_module_2.mod.c
+diff --git a/abi-checker/sample/sample_module.c b/abi-checker/sample/sample_module.c
+new file mode 100644
+index 0000000..b95a7af
+--- /dev/null
++++ b/abi-checker/sample/sample_module.c
+@@ -0,0 +1,107 @@
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <asm/uaccess.h>
++#include <linux/init.h>
++#include <linux/fs.h>
++
++#define DEVICE_NAME "sample_module"
++#define TEST_MSG_BUFF_LEN     1024
++
++extern int snd_timer_pause;
++
++static unsigned int majorNumber = 0;
++
++static char message[TEST_MSG_BUFF_LEN + 1];
++
++static ssize_t device_write(struct file *filp, const char *buff, size_t len, loff_t *off)
++{
++      printk(KERN_ALERT "Empty write operation. %d\n", snd_timer_pause);
++      return 0;
++}
++
++static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t * offset)
++{
++      int bytes_read = 0;
++
++      /*
++       * Copy message
++       */
++      for(bytes_read = 0; bytes_read < (length - 1) && bytes_read < TEST_MSG_BUFF_LEN; bytes_read ++)
++              put_user(message[bytes_read], buffer + bytes_read );
++      put_user('\0', buffer + bytes_read );
++
++      return bytes_read + 1;
++}
++
++static int device_open(struct inode *inode, struct file *file)
++{
++      static int counter = 0;
++
++      printk( "Open device, count = %d\n", counter++ );
++
++      try_module_get( THIS_MODULE );
++      return 0;
++}
++
++static int device_release(struct inode *inode, struct file *file)
++{
++      printk("Release device\n");
++
++      module_put( THIS_MODULE );
++      return 0;
++}
++
++struct file_operations fileOperations =
++{
++      read:    device_read,
++      write:   device_write,
++      open:    device_open,
++      release: device_release
++};
++
++static int __init test_module_init( void )
++{
++      int i;
++      int j;
++
++      printk(KERN_ALERT "Test kernel module 2 - enter\n");
++
++      /*
++       * Init test message
++       */
++      for(i = 0; i < TEST_MSG_BUFF_LEN;)
++      {
++              for(j = 0; j < 10 && i < TEST_MSG_BUFF_LEN; j ++, i ++ )
++              {
++                      message[i] = '0' + j;
++                      message[i + 1] = '\0';
++              }
++      }
++
++      /*
++       * Register device
++       */
++      majorNumber = register_chrdev(0, DEVICE_NAME, &fileOperations);
++      if (majorNumber < 0)
++      {
++                printk(KERN_ALERT "Blad rejestrowania urzadzenia => [%d]\n", majorNumber );
++                return majorNumber;
++      }
++
++      return 0;
++}
++
++static void __exit test_module_exit(void)
++{
++      printk(KERN_ALERT "Test kernel module 2 - exit\n");
++
++      unregister_chrdev(majorNumber, DEVICE_NAME);
++}
++
++module_init(test_module_init);
++module_exit(test_module_exit);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Jacek Pielaszkiewicz");        /* Who wrote this module? */
++MODULE_DESCRIPTION("Sample test kernel module.");     /* What does this module do */
++MODULE_SUPPORTED_DEVICE("sample_test_module_2");
+diff --git a/abi-checker/src/Makefile b/abi-checker/src/Makefile
+new file mode 100644
+index 0000000..b020bc6
+--- /dev/null
++++ b/abi-checker/src/Makefile
+@@ -0,0 +1,31 @@
++PROGRAM = abi-checker
++GCC = gcc
++LDD = gcc
++
++CFLAGS = $(shell pkg-config --cflags glib-2.0 libelf) -I.
++
++LDFLAGS = $(shell pkg-config --libs glib-2.0 libelf)
++
++SRC = kernel_abi_checker.c kernel_abi_checker_elf.c
++
++HEADER = kernel_abi_checker.h
++
++DEST_DIR = /usr/local/bin
++
++OBJECTS = kernel_abi_checker.o kernel_abi_checker_elf.o
++
++all : $(PROGRAM)
++
++.c.o : $(HEADER)
++      $(GCC) -c $(CFLAGS) $< -o $@
++
++$(PROGRAM) : $(OBJECTS)
++      $(LDD) $(OBJECTS) -o $@ $(LDFLAGS)
++
++install :
++      mkdir -p $(DEST_DIR)
++      cp $(PROGRAM) $(DEST_DIR)
++
++clean :
++      rm -f $(PROGRAM)
++      rm -f $(OBJECTS)
+diff --git a/abi-checker/src/abi-module-checker b/abi-checker/src/abi-module-checker
+new file mode 100755
+index 0000000..78e5a89
+--- /dev/null
++++ b/abi-checker/src/abi-module-checker
+@@ -0,0 +1,29 @@
++#!/bin/sh
++
++echo ""
++echo "Module ABI/API checker"
++echo ""
++echo ""
++
++if [ "${#}" != "1"  ]
++then
++      echo ""
++      echo "ERROR: "
++      echo "       Usage: ${0} _module_abi_fingerprint_"
++      echo ""
++      exit 1
++fi
++
++kerne_abi_file="/boot/abi/current"
++
++if [ ! -f "${1}" -o ! -f "${kerne_abi_file}" ]
++then
++      echo ""
++      echo "ERROR: Please check \"${1}\", \"${kerne_abi_file}\" files"
++      echo ""
++      exit 1
++fi
++
++/usr/local/bin/abi-checker "test-module" "${kerne_abi_file}" "${1}"
++
++exit ${?}
+diff --git a/abi-checker/src/abi-module-dumper b/abi-checker/src/abi-module-dumper
+new file mode 100755
+index 0000000..783e02a
+--- /dev/null
++++ b/abi-checker/src/abi-module-dumper
+@@ -0,0 +1,38 @@
++#!/bin/sh
++
++echo ""
++echo "Module ABI/API fingerprint file generation"
++echo ""
++echo ""
++
++if [ "${#}" != "2"  ]
++then
++      echo ""
++      echo "ERROR: "
++      echo "       Usage: ${0} _module_ko_file_ _output_file_"
++      echo ""
++      exit 1
++fi
++
++kerne_abi_file="/boot/abi/current"
++
++if [ ! -f "${kerne_abi_file}" ]
++then
++      echo ""
++      echo "ERROR: Please check ${kerne_abi_file} file"
++      echo "       Check if linux-kernel-uImage package is installed in development environment."
++      echo ""
++      exit 1
++fi
++
++if [ ! -f "${1}" ]
++then
++      echo "ERROR: Please check input file ${1}"
++      echo ""
++      exit 1
++      
++fi
++
++/usr/local/bin/abi-checker "dump-module" "${kerne_abi_file}" "${1}" "${2}"
++
++exit ${?}
+diff --git a/abi-checker/src/abi-module-kernels-list b/abi-checker/src/abi-module-kernels-list
+new file mode 100755
+index 0000000..12105e1
+--- /dev/null
++++ b/abi-checker/src/abi-module-kernels-list
+@@ -0,0 +1,31 @@
++#!/bin/sh
++
++echo ""
++echo "List all comatible kernels."
++echo ""
++
++if [ "${#}" != 1  ]
++then
++      echo ""
++      echo "ERROR: "
++      echo "       Usage: ${0} _module_fingerprint_"
++      echo ""
++      exit 1
++fi
++
++#
++# Check all historical abi kernel files
++#
++for file in /boot/abi/abi_*
++do
++      filename=`basename ${file}`
++      version=`echo ${filename} | awk -F _ '{ print $2 }'`
++      abi=`echo ${filename} | awk -F _ '{ print $3 }'`
++
++      /usr/local/bin/abi-checker "test-module" "${file}" "${1}" 2> /dev/null > /dev/null
++      if [ "${?}" = "0" ]
++      then
++              echo "        Kernel:${version}, ABI/API:${abi} .... compatible"
++      fi
++done
++
+diff --git a/abi-checker/src/build_api_kernel_checker.sh b/abi-checker/src/build_api_kernel_checker.sh
+new file mode 100755
+index 0000000..d9e348b
+--- /dev/null
++++ b/abi-checker/src/build_api_kernel_checker.sh
+@@ -0,0 +1,24 @@
++#!/bin/sh
++
++# Find abi_version file
++ksymver=`find ../.. -name "Module.symvers"`
++
++# compare abi fingerprint file with kernel abi file
++./abi-checker test-kernel "${ksymver}" "../data/abi_${1}_${2}"
++rc="${?}"
++
++# Test result
++if [ ${rc} != "0" ]
++then
++      echo ""
++      echo "----------------------------------------------------------------------------------------------------------------------------"
++      echo ""
++      echo "The kernel ABI/API has changed. Please update kernel version and add a new abi-checker/data/abi_VERSION_ABIVER file "
++      echo "(example abi-checker/data/abi_${1}_${2} )."
++      echo "The kernel sources build will abort."
++      echo ""
++      echo ""
++      exit 1
++fi
++
++exit 0
+diff --git a/abi-checker/src/kernel_abi_checker.c b/abi-checker/src/kernel_abi_checker.c
+new file mode 100644
+index 0000000..da396e1
+--- /dev/null
++++ b/abi-checker/src/kernel_abi_checker.c
+@@ -0,0 +1,834 @@
++/*
++ * Build command
++ *
++ * gcc `pkg-config --cflags glib-2.0` kernel_abi_checker.c kernel_abi_checker_elf.c -lglib-2.0 -lelf
++ */
++
++#include <stdio.h>
++#include <string.h>
++#include <stdlib.h>
++#include <glib.h>
++
++#include "kernel_abi_checker.h"
++
++/*
++ * Functions write single record into ouptu symver file
++ */
++int writeKernelSymbolsFile( FILE *ptr, char *symbolNameCrc, char *symbolName, char *symbolModule, char *flag )
++{
++      return fprintf( ptr, "%s\t%s\t%s\t%s\n", symbolNameCrc, symbolName, symbolModule, flag );
++}
++
++/*
++ * Function open *symver file
++ */
++FILE *getFile( char *fileName )
++{
++      FILE *fPtr = fopen( fileName, "r" );
++
++      if( fPtr == (FILE *)NULL )
++      {
++              PRINT_ERROR( "Canniot open : %s\n", fileName );
++              return (FILE *)NULL;
++      }
++
++      return fPtr;
++}
++
++FILE *getOutputFile( char *fileName )
++{
++      FILE *fPtr = fopen( fileName, "w" );
++
++      if( fPtr == (FILE *)NULL )
++      {
++              PRINT_ERROR( "Canniot open : %s\n", fileName );
++              return (FILE *)NULL;
++      }
++
++      return fPtr;
++}
++
++void releaseFile( FILE *fptr )
++{
++      if( fptr != (FILE *)NULL )
++              fclose( fptr );
++}
++
++void freeHashElement( gpointer data )
++{
++      free( (void *)data );
++}
++
++/*
++ * Function creates hash table
++ */
++GHashTable *createHashTable( void )
++{
++      return g_hash_table_new_full( g_str_hash, g_str_equal, NULL, freeHashElement );
++}
++
++/*
++ * Function destroy hash table
++ */
++void destroyHashTable( GHashTable *tab )
++{
++      if( tab != (GHashTable *)NULL )
++              g_hash_table_destroy( tab );
++}
++
++/*
++ * Function read i mput file.
++ * Function return single KernelSymbol structure.
++ *
++ * Return (KernelSymbol *)-1 - if errora
++          (KernelSymbol *)NULL - eof
++ *
++ */
++
++KernelSymbol *readFileLine( FILE *fptr )
++{
++      KernelSymbol *symbolPtr = (KernelSymbol *)NULL;
++      char inputLine[_LINE_LENGTH_ + 1];
++      char *crcPtr;
++      char *symNamePtr;
++      char *moduleNamePtr;
++      char *flag;
++      char *ptr;
++      int len;
++      int i;
++
++      memset( inputLine, 0, sizeof( inputLine ) );
++      ptr = fgets( inputLine, _LINE_LENGTH_, fptr );
++      if( ptr == (char *) NULL )
++              return (KernelSymbol *)NULL;
++
++      i = 0;
++
++      /* CRC */
++      crcPtr = inputLine + i;
++      for( ;inputLine[i] != '\0' && inputLine[i] != '\t' && i < _LINE_LENGTH_; i ++ );
++
++      if( i >= _LINE_LENGTH_ )
++      {
++              PRINT_ERROR( "Incorect input record format : \"%s\"\n", inputLine );
++              return (KernelSymbol *)-1;
++      }
++      inputLine[i] = '\0';
++      i++;
++
++      /* Symbol name */
++      symNamePtr = inputLine + i;
++
++      for( ;inputLine[i] != '\0' && inputLine[i] != '\t' && i < _LINE_LENGTH_; i ++ );
++      if( i >= _LINE_LENGTH_ )
++      {
++              PRINT_ERROR( "Incorect input record format : \"%s\"\n", inputLine );
++              return (KernelSymbol *)-1;
++      }
++      inputLine[i] = '\0';
++      i ++;
++
++      /* Module name */
++      moduleNamePtr = inputLine + i;
++
++
++      for( ;inputLine[i] != '\0' && inputLine[i] != '\t' && i < _LINE_LENGTH_; i ++ );
++      if( i >= _LINE_LENGTH_ )
++      {
++              PRINT_ERROR( "Incorect input record format : \"%s\"\n", inputLine );
++              return (KernelSymbol *)-1;
++      }
++      inputLine[i] = '\0';
++      i ++;
++
++      /* Flag */
++      flag = inputLine + i;
++
++
++      len = strlen( flag );
++      flag[len ==  0 ? 0 : len -1] = '\0';
++
++      /* Allocate new KernelSymbol */
++      symbolPtr = (KernelSymbol *)malloc( sizeof( KernelSymbol ) );
++      if( symbolPtr == (KernelSymbol *)NULL )
++              return (KernelSymbol *)-1;
++
++      for( i = 0; moduleNamePtr[i] != '\0' && moduleNamePtr[i] != '\n'; i ++ );
++      moduleNamePtr[i] = '\0';
++
++      /* Polulate output structure */
++      strncpy( symbolPtr -> symbolName, symNamePtr, KERNEL_SYMBOL_NAME_LENGTH );
++      strncpy( symbolPtr -> symbolNameCrc, crcPtr, KERNEL_SYMBOL_NAME_CRC );
++      strncpy( symbolPtr -> symbolModule, moduleNamePtr, KERNEL_SYMBOL_MODULE );
++      strncpy( symbolPtr -> flag, flag, KERNEL_SYMBOL_FLAG );
++      symbolPtr -> status = KERNEL_SYMBOL_STATUS_NO_TESTED;
++
++      /* Return KernModule structure */
++      return symbolPtr;
++}
++
++/*
++ * Function adds single kernel symbol into hashtable.
++ * Functions assumes that hash table is correctlly allocated.
++ *
++ * Returns:
++ * -1 - duplicated key
++ *  0 - success
++ */
++
++int addKernelSymboltoHashBase( void *s, char *key, GHashTable *tab )
++{
++      void *testSym;
++
++      /* Check duplicates */
++      testSym = (void *)g_hash_table_lookup( tab, key );
++      if( testSym != (void *)NULL )
++              return -1;
++
++      /* Add new symbol into hash table */
++      g_hash_table_insert( tab, key, s );
++      return 0;
++}
++
++int addKernelSymboltoHash( KernelSymbol *s, GHashTable *tab )
++{
++      return addKernelSymboltoHashBase( (void *)s, s -> symbolName, tab );
++}
++
++int readFile( FILE *fptr, GHashTable *tab )
++{
++        KernelSymbol *sym = (KernelSymbol *)NULL;
++        while( 1 == 1 )
++        {
++                sym = readFileLine( fptr );
++              if( sym == (KernelSymbol *)NULL )
++              {
++                      /* Koniec pliku */
++                      break;
++              }
++
++              if( sym == (KernelSymbol *)-1 )
++              {
++                      /* Error */
++                      return -1;
++              }
++
++              if( addKernelSymboltoHash( sym, tab ) < 0 )
++              {
++                      /* Error - duplicated value */
++                      return -1;
++              }
++        }
++
++      /* Success */
++      return 0;
++}
++
++GHashTable *procesInputFile( char *name )
++{
++      GHashTable *hashTable = (GHashTable *)NULL;
++      FILE *fptr = (FILE *)NULL;
++
++      /* Open input file */
++      fptr = getFile( name );
++      if( fptr == (FILE *)NULL )
++              return (GHashTable *)NULL;
++
++      /* Create hash table for current symver */
++      hashTable = createHashTable();
++      if( hashTable == (GHashTable *)NULL )
++      {
++              PRINT_ERROR( "Error creating hash table \n" );
++              releaseFile( fptr );
++              return (GHashTable *)NULL;
++      }
++
++      /* Read and create current hash table */
++      if( readFile( fptr, hashTable ) != 0 )
++      {
++              PRINT_ERROR( "Error reading %s\n", name );
++              destroyHashTable( hashTable );
++              releaseFile( fptr );
++              return (GHashTable *)NULL;
++      }
++
++      /* Close input file */
++      releaseFile( fptr );
++
++      return hashTable;
++}
++
++typedef struct _foreachHashData_
++{
++      KernelSymbolStatistics *stat;
++      GHashTable *curr;
++      GHashTable *new;
++} _foreachHashData_;
++
++void calculateStatistics_1( gpointer key_, gpointer value_, gpointer user_data_ )
++{
++      KernelSymbol *value = (KernelSymbol *)value_;
++      _foreachHashData_ *user_data = (_foreachHashData_ *)user_data_;
++      KernelSymbol *newSym;
++
++      /* Update current hash table symbols count */
++      user_data -> stat -> symver_current_count ++;
++
++      /* Search for symbol in new hash table */
++      newSym = (KernelSymbol *)g_hash_table_lookup( user_data -> new, key_ );
++
++      if( newSym == (KernelSymbol *)NULL )
++      {
++              /* Symbol was removed */
++
++              /* Set status */
++              value -> status = KERNEL_SYMBOL_STATUS_REMOVED;
++
++              user_data -> stat -> removed_symbols_count ++;
++              return;
++      }
++
++      newSym -> status = KERNEL_SYMBOL_STATUS_VIEWED;
++
++      if( strcmp( value -> symbolNameCrc, newSym -> symbolNameCrc ) == 0 )
++      {
++              user_data -> stat -> no_changed_symbols_count ++;
++              value -> status = KERNEL_SYMBOL_STATUS_NO_CHANGES;
++      }
++      else
++      {
++              user_data -> stat -> changed_symbols_count ++;
++              value -> status = KERNEL_SYMBOL_STATUS_CHANGED;
++      }
++}
++
++void calculateStatistics_2( gpointer key_, gpointer value_, gpointer user_data_ )
++{
++      KernelSymbol *value = (KernelSymbol *)value_;
++      _foreachHashData_ *user_data = (_foreachHashData_ *)user_data_;
++
++      /* Update current hash table symbols count */
++      user_data -> stat -> symver_new_count ++;
++
++      if( value -> status == KERNEL_SYMBOL_STATUS_NO_TESTED )
++      {
++              user_data -> stat -> new_symbols_count ++;
++              value -> status = KERNEL_SYMBOL_STATUS_NEW;
++      }
++}
++
++void collectStatistics( GHashTable *curr, GHashTable *new, KernelSymbolStatistics *statistics )
++{
++      _foreachHashData_ foreachdata;
++
++      /* Init foreach data */
++      memset( (void *)statistics, 0, sizeof( KernelSymbolStatistics ) );
++      foreachdata.stat = statistics;
++      foreachdata.curr = curr;
++      foreachdata.new = new;
++
++      /* Scan current hash table */
++      g_hash_table_foreach( curr, calculateStatistics_1, (gpointer)&foreachdata );
++
++      /* Scan new hash table */
++      g_hash_table_foreach( new, calculateStatistics_2, (gpointer)&foreachdata );
++}
++
++void reportSymbolsDetails( gpointer key_, gpointer value_, gpointer user_data_ )
++{
++      KernelSymbol *value = (KernelSymbol *)value_;
++
++      switch( *((int *)user_data_) )
++      {
++      case 0 :        /* New */
++              if( value -> status == KERNEL_SYMBOL_STATUS_NEW )
++                      PRINT_INFO_RAW( "\t| NEW     | %40s | %10s | %s\n", value -> symbolName, value -> symbolNameCrc, value -> symbolModule );
++              break;
++
++      case 1 :        /* Changed */
++              if( value -> status == KERNEL_SYMBOL_STATUS_CHANGED )
++                      PRINT_INFO_RAW( "\t| CHANGED | %40s | %10s | %s\n", value -> symbolName, value -> symbolNameCrc, value -> symbolModule );
++              break;
++
++      case 2 :        /* Removed */
++              if( value -> status == KERNEL_SYMBOL_STATUS_REMOVED )
++                      PRINT_INFO_RAW( "\t| REMOVED | %40s | %10s | %s\n", value -> symbolName, value -> symbolNameCrc, value -> symbolModule );
++              break;
++      }
++}
++//[CHANGED]         cfg80211_send_rx_assoc         0x80e54114                  vmlinux
++
++void listChangedSymbols( GHashTable *curr, GHashTable *new, KernelSymbolStatistics *statistics )
++{
++      int mode = 0;
++      int printFooter = 0;
++
++      if( statistics -> new_symbols_count == 0 && statistics -> changed_symbols_count == 0 && statistics -> removed_symbols_count == 0 )
++              return;
++
++      PRINT_INFO_RAW( "\n" );
++
++      PRINT_INFO_RAW( "\tNew symbols in kernel\n" );
++      PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
++      PRINT_INFO_RAW( "\t| Change  |                 Linux kernel symbol name |        CRC | Module name \n" );
++      PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
++
++      if( statistics -> new_symbols_count != 0 && new != (GHashTable *)NULL )
++      {
++              mode = 0;
++              g_hash_table_foreach( new, reportSymbolsDetails, (gpointer)&mode );
++              printFooter = 1;
++      }
++
++      if( statistics -> changed_symbols_count != 0 && curr != (GHashTable *)NULL )
++      {
++              if( statistics -> new_symbols_count != 0 )
++                      PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
++
++              mode = 1;
++              g_hash_table_foreach( curr, reportSymbolsDetails, (gpointer)&mode );
++              printFooter = 1;
++      }
++
++      if( statistics -> removed_symbols_count != 0 && curr != (GHashTable *)NULL )
++      {
++              if( statistics -> new_symbols_count != 0 || statistics -> changed_symbols_count != 0 )
++                      PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
++
++              mode = 2;
++              g_hash_table_foreach( curr, reportSymbolsDetails, (gpointer)&mode );
++              printFooter = 1;
++      }
++
++      if( printFooter == 1 )
++              PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
++}
++
++void reportsStatistics( GHashTable *curr, GHashTable *new, KernelSymbolStatistics *statistics )
++{
++      listChangedSymbols( curr, new, statistics );
++
++      PRINT_INFO_RAW( "\n" );
++      PRINT_INFO_RAW( "\tKernel symbols version statistics \n" );
++      PRINT_INFO_RAW( "\t-------------------------------------------------\n" );
++      PRINT_INFO_RAW( "\tSymbols in actual kernel/module . %d\n", statistics -> symver_current_count );
++      if( new != (GHashTable *)NULL )
++              PRINT_INFO_RAW( "\tSymbols in new kernel/module .... %d\n", statistics -> symver_new_count );
++      PRINT_INFO_RAW( "\tNew symbols ..................... %d\n", statistics -> new_symbols_count );
++      PRINT_INFO_RAW( "\tRemoved symbols ................. %d\n", statistics -> removed_symbols_count );
++      PRINT_INFO_RAW( "\tChanged symbols ................. %d\n", statistics -> changed_symbols_count );
++      PRINT_INFO_RAW( "\tUnchanged symbols ............... %d\n", statistics -> no_changed_symbols_count );
++      PRINT_INFO_RAW( "\n" );
++}
++
++void printUsage( char *progName, int type )
++{
++      switch( type )
++      {
++      case 0 :
++              PRINT_INFO_RAW( "\tUsage: %s test-kernel in_symver_file_1 in_symver_file_2\n", progName );
++              break;
++
++      case 1 :
++              PRINT_INFO_RAW( "\tUsage: %s build-list in_module_symbols_file in_kernel_symver_file outt_module_symver_file\n", progName );
++              break;
++
++      case 2 :
++              PRINT_INFO_RAW( "\tUsage: %s dump-module kernel_symver_file ko_module_file output_module_symver_file\n", progName );
++              break;
++
++      case 4 :
++              PRINT_INFO_RAW( "\tUsage: %s test-module kernel_symver_file ko_module_file \n", progName );
++              break;
++
++      default :
++              PRINT_INFO_RAW( "\tUsage: %s test|build-list file1 file2 [output_file] \n", progName );
++              break;
++      }
++}
++
++/*
++ * Function parses input parameters and return.
++ * Return:
++ *            -1 - error
++ *             0 - test mode  - the program will compare two symver files
++ *             1 - build mode - for given module sybmbols file and kernel symver creates files
++ *                              with list kernel symbols used by the module.
++ */
++int parsInputParameters( int argc, char **argv, char **f1, char **f2, char **f3 )
++{
++      char *toolName = argv[0];
++
++      if( argc < 2 )
++      {
++              printUsage( toolName, -1 );
++              return -1;
++      }
++
++      if( strcmp( argv[1], "test-kernel" ) == 0 )
++      {
++              /* Test mode */
++              if( argc < 4 )
++              {
++                      printUsage( toolName, 0 );
++                      return -1;
++              }
++              *f1 = argv[2];
++              *f2 = argv[3];
++              *f3 = (char *)NULL;
++
++              return 0;
++
++      }
++      else
++      if( strcmp( argv[1], "build-list" ) == 0 )
++      {
++              /* Build mode */
++              if( argc < 5 )
++              {
++                      printUsage( toolName, 1 );
++                      return -1;
++              }
++              *f1 = argv[2];
++              *f2 = argv[3];
++              *f3 = argv[4];
++
++              return 1;
++      }
++      else
++      if( strcmp( argv[1], "dump-module" ) == 0 )
++      {
++              /* Build mode */
++              if( argc < 5 )
++              {
++                      printUsage( toolName, 2 );
++                      return -1;
++              }
++              *f1 = argv[2];
++              *f2 = argv[3];
++              *f3 = argv[4];
++
++              return 2;
++      }
++      else
++      if( strcmp( argv[1], "usage" ) == 0 )
++      {
++              return 3;
++      }
++      else
++      if( strcmp( argv[1], "test-module" ) == 0 )
++      {
++              /* Test mode */
++              if( argc < 4 )
++              {
++                      printUsage( toolName, 4 );
++                      return -1;
++              }
++              *f1 = argv[2];
++              *f2 = argv[3];
++              *f3 = (char *)NULL;
++
++              return 4;
++      }
++
++
++      printUsage( toolName, -1 );
++      return -1;
++}
++
++int testKernel( char *f1, char *f2 )
++{
++      GHashTable *curr_hashTable = (GHashTable *)NULL;
++      GHashTable *new_hashTable = (GHashTable *)NULL;
++      KernelSymbolStatistics statistics;
++
++      /*
++       * ----------------------------------------------
++       * Read current symver file
++       * ----------------------------------------------
++       */
++      curr_hashTable = procesInputFile( f1 );
++      if( curr_hashTable == (GHashTable *)NULL )
++      {
++              PRINT_ERROR( "Error read input \"%s\" file.\n", f1 );
++              return 1;
++      }
++
++      /*
++       * ----------------------------------------------
++       * Read new symver file
++       * ----------------------------------------------
++      */
++      new_hashTable = procesInputFile( f2 );
++      if( new_hashTable == (GHashTable *)NULL )
++      {
++              destroyHashTable( curr_hashTable );
++              PRINT_ERROR( "Error read input \"%s\" file.\n", f2 );
++        return 1;
++      }
++
++      /*
++       * ----------------------------------------------
++       * Compute statistics
++       * ----------------------------------------------
++       */
++      collectStatistics( curr_hashTable, new_hashTable, &statistics );
++
++      /*
++       * ---------------------------------------------
++       * Report changes
++       * ---------------------------------------------
++       */
++      reportsStatistics( curr_hashTable, new_hashTable, &statistics );
++
++      /*
++       * --------------------------------------------
++       * Free hash tables
++       * --------------------------------------------
++       */
++      destroyHashTable( curr_hashTable );
++      destroyHashTable( new_hashTable );
++
++      if( statistics.changed_symbols_count != 0 || statistics.removed_symbols_count != 0 || statistics.new_symbols_count != 0 )
++              return 2;
++
++      return 0;
++}
++
++void collectStatisticsModule( GHashTable *curr, GHashTable *module, KernelSymbolStatistics *statistics )
++{
++      _foreachHashData_ foreachdata;
++
++      /* Init foreach data */
++      memset( (void *)statistics, 0, sizeof( KernelSymbolStatistics ) );
++      foreachdata.stat = statistics;
++      foreachdata.curr = module;
++      foreachdata.new = curr;
++
++      /* Scan current hash table */
++      g_hash_table_foreach( module, calculateStatistics_1, (gpointer)&foreachdata );
++}
++
++
++int testModule( char *f1, char *f2 )
++{
++      GHashTable *curr_hashTable = (GHashTable *)NULL;
++      GHashTable *module_hashTable = (GHashTable *)NULL;
++      KernelSymbolStatistics statistics;
++
++      /*
++       * ----------------------------------------------
++       * Read current symver file
++       * ----------------------------------------------
++       */
++      curr_hashTable = procesInputFile( f1 );
++      if( curr_hashTable == (GHashTable *)NULL )
++      {
++              PRINT_ERROR( "Error read input \"%s\" file.\n", f1 );
++              return 1;
++      }
++
++      /*
++       * ----------------------------------------------
++       * Read module symbols
++       * ----------------------------------------------
++      */
++      module_hashTable = procesInputFile( f2 );
++      if( module_hashTable == (GHashTable *)NULL )
++      {
++              destroyHashTable( curr_hashTable );
++              PRINT_ERROR( "Error read input \"%s\" file.\n", f2 );
++              return 1;
++      }
++
++      /*
++       * ----------------------------------------------
++       * Compute statistics
++       * ----------------------------------------------
++       */
++      collectStatisticsModule( curr_hashTable, module_hashTable, &statistics );
++
++      /*
++       * ---------------------------------------------
++       * Report changes
++       * ---------------------------------------------
++       */
++      reportsStatistics( module_hashTable, (GHashTable *)NULL, &statistics );
++
++      /*
++       * --------------------------------------------
++       * Free hash tables
++       * --------------------------------------------
++       */
++      destroyHashTable( curr_hashTable );
++      destroyHashTable( module_hashTable );
++
++      if( statistics.changed_symbols_count != 0 || statistics.removed_symbols_count != 0 )
++              return 2;
++
++      return 0;
++}
++
++int buildListMode( char *f1, char *f2, char *f3 )
++{
++      GHashTable *curr_hashTable = (GHashTable *)NULL;
++      char inputLine[_LINE_LENGTH_ + 1];
++      FILE *symListFptr = (FILE *)NULL;
++      FILE *outFptr = (FILE *)NULL;
++      KernelSymbol *kSym;
++      int size;
++
++      /*
++       * ----------------------------------------------
++       * Read current symver file
++       * ----------------------------------------------
++       */
++      curr_hashTable = procesInputFile( f1 );
++      if( curr_hashTable == (GHashTable *)NULL )
++      {
++              PRINT_ERROR( "Error read input \"%s\" file.\n", f1 );
++              return 1;
++      }
++
++      /*
++       * Open files
++       */
++      outFptr = getOutputFile( f3 );
++      symListFptr = getFile( f2 );
++
++      if( symListFptr == (FILE *)NULL || outFptr == (FILE *)NULL )
++      {
++              destroyHashTable( curr_hashTable );
++              releaseFile( symListFptr );
++              releaseFile( outFptr );
++              PRINT_ERROR( "Error open files : \"%s\", \"%s\".\n", f2, f3 );
++              return 1;
++      }
++
++      while( fgets( inputLine, _LINE_LENGTH_, symListFptr ) )
++      {
++              size = strlen( inputLine );
++              inputLine[size == 0 ? 0 :size - 1] = '\0';
++
++              /* Search for symbol in new hash table */
++              kSym = (KernelSymbol *)g_hash_table_lookup( curr_hashTable, inputLine );
++
++              if( kSym != (KernelSymbol *)NULL )
++                      writeKernelSymbolsFile( outFptr, kSym -> symbolNameCrc, kSym -> symbolName, kSym -> symbolModule, kSym -> flag );
++      }
++
++      destroyHashTable( curr_hashTable );
++      releaseFile( symListFptr );
++      releaseFile( outFptr );
++
++      return 0;
++}
++
++int callDumpModuleSymbols( char *f1, char *f2, char *f3 )
++{
++      GHashTable *curr_hashTable = (GHashTable *)NULL;
++      GHashTable *module_hashTable = (GHashTable *)NULL;
++
++      /*
++       * ----------------------------------------------
++       * Read current symver file
++       * ----------------------------------------------
++       */
++      curr_hashTable = procesInputFile( f1 );
++      if( curr_hashTable == (GHashTable *)NULL )
++      {
++              PRINT_ERROR( "Error read input \"%s\" file.\n", f1 );
++              return 1;
++      }
++
++      /*
++       * ----------------------------------------------
++       * Read kernel module *.ko file
++       * ----------------------------------------------
++       */
++      module_hashTable = readEfl( f2 );
++      if( module_hashTable == (GHashTable *)NULL )
++      {
++              PRINT_ERROR( "Error read input \"%s\" file.\n", f2 );
++              destroyHashTable( curr_hashTable );
++              return 1;
++      }
++
++      /*
++       * Dump module symbols into output file
++       */
++      if( dumpModuleSymbols( f3, module_hashTable, curr_hashTable ) < 0 )
++      {
++              PRINT_ERROR( "Error creating dump file \"%s\"\n", f3 );
++              destroyHashTable( curr_hashTable );
++              return 1;
++      }
++
++      /*
++       * Free hash tables
++       */
++      destroyHashTable( module_hashTable );
++      destroyHashTable( curr_hashTable );
++
++      return 0;
++}
++
++int printUsageInfo( char *f1 )
++{
++      PRINT_INFO_RAW( "\n" );
++      PRINT_INFO_RAW( "\tProgram usage\n" );
++      PRINT_INFO_RAW( "\t-----------------------------------------------\n" );
++      PRINT_INFO_RAW( "\n" );
++      printUsage( f1, 0 );
++      printUsage( f1, 1 );
++      printUsage( f1, 2 );
++
++      return 0;
++}
++
++int main(int argc, char** argv)
++{
++      char *f1 = (char *)NULL;
++      char *f2 = (char *)NULL;
++      char *f3 = (char *)NULL;
++      int rc = -1;
++
++      int mode = parsInputParameters( argc, argv, &f1, &f2, &f3 );
++
++      switch( mode )
++      {
++      case 0 :
++              rc = testKernel( f1, f2 );
++              break;
++
++      case 1 :
++              rc = buildListMode( f1, f2, f3 );
++              break;
++
++      case 2 :
++              rc = callDumpModuleSymbols( f1, f2, f3 );
++              break;
++
++      case 3 :
++              rc = printUsageInfo( argv[0] );
++              break;
++
++      case 4 :
++              rc = testModule( f1, f2 );
++              break;
++      }
++
++      PRINT_INFO_RAW( "\n" );
++
++      if( rc == 2 )
++              PRINT_INFO_RAW( "\tChanges !!!\n" );
++      else
++      if( rc == 1 )
++              PRINT_INFO_RAW( "\tError !!!\n" );
++      else
++              PRINT_INFO_RAW( "\tDone\n" );
++
++      PRINT_INFO_RAW( "\n" );
++
++      return ( rc != 0 ) ? 1 : 0;
++}
+diff --git a/abi-checker/src/kernel_abi_checker.h b/abi-checker/src/kernel_abi_checker.h
+new file mode 100644
+index 0000000..8df231e
+--- /dev/null
++++ b/abi-checker/src/kernel_abi_checker.h
+@@ -0,0 +1,62 @@
++#ifndef _kernel_abi_checker_h_
++#define _kernel_abi_checker_h_
++
++#include <stdio.h>
++#include <glib.h>
++
++/*
++ * Definitions
++ */
++#define KERNEL_SYMBOL_NAME_LENGTH     64
++#define KERNEL_SYMBOL_NAME_CRC                32
++#define KERNEL_SYMBOL_MODULE          256
++#define KERNEL_SYMBOL_FLAG                    256
++
++#define KERNEL_SYMBOL_STATUS_NO_TESTED        0
++#define KERNEL_SYMBOL_STATUS_NO_CHANGES       1
++#define KERNEL_SYMBOL_STATUS_NEW              2
++#define KERNEL_SYMBOL_STATUS_REMOVED  3
++#define KERNEL_SYMBOL_STATUS_CHANGED  4
++#define KERNEL_SYMBOL_STATUS_VIEWED           5
++
++#define _LINE_LENGTH_ 4096
++
++/*
++ * Data types
++ */
++typedef struct KernelSymbol
++{
++      char symbolName[KERNEL_SYMBOL_NAME_LENGTH + 1];
++      char symbolNameCrc[KERNEL_SYMBOL_NAME_CRC + 1];
++      char symbolModule[KERNEL_SYMBOL_MODULE + 1];
++      char flag[KERNEL_SYMBOL_FLAG + 1];
++      int status;
++
++} KernelSymbol;
++
++typedef struct KernelSymbolStatistics
++{
++      int symver_current_count;
++      int symver_new_count;
++
++      int new_symbols_count;
++      int removed_symbols_count;
++      int changed_symbols_count;
++      int no_changed_symbols_count;
++
++} KernelSymbolStatistics;
++
++extern int writeKernelSymbolsFile( FILE *, char *, char *, char *, char * );
++extern int addKernelSymboltoHashBase( void *, char *, GHashTable * );
++extern int dumpModuleSymbols( char *, GHashTable *, GHashTable * );
++extern void destroyHashTable( GHashTable * );
++extern GHashTable *createHashTable( void );
++extern FILE *getOutputFile( char * );
++extern void releaseFile( FILE * );
++GHashTable *readEfl( char * );
++
++#define PRINT_ERROR(...)  do { fprintf( stderr, "ERROR : " ); fprintf( stderr, __VA_ARGS__ ); } while( 0 )
++#define PRINT_INFO_RAW(...)   do { fprintf( stdout, __VA_ARGS__ ); } while( 0 )
++#define PRINT_INFO(...)   do { fprintf( stderr, "INFO  : " ); fprintf( stdout, __VA_ARGS__ ); } while( 0 )
++
++#endif
+diff --git a/abi-checker/src/kernel_abi_checker_elf.c b/abi-checker/src/kernel_abi_checker_elf.c
+new file mode 100644
+index 0000000..6f4f28c
+--- /dev/null
++++ b/abi-checker/src/kernel_abi_checker_elf.c
+@@ -0,0 +1,172 @@
++#include "kernel_abi_checker.h"
++
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <unistd.h>
++#include <string.h>
++#include <stdlib.h>
++#include <libelf.h>
++#include <stdio.h>
++#include <fcntl.h>
++#include <gelf.h>
++
++GHashTable *readEfl( char *file )
++{
++      GHashTable *outputHashTable = (GHashTable *)NULL;
++      Elf_Data *edata = (Elf_Data *)NULL;
++      Elf_Scn *scn = (Elf_Scn *)NULL;
++      char *base_ptr = (char *)NULL;
++      char *sname = (char *)NULL;
++      Elf *elf = (Elf *)NULL;
++      struct stat elf_stats;
++      int symbol_count;
++      GElf_Shdr shdr;
++      GElf_Sym sym;
++      int size;
++      int fd;
++      int i;
++
++      fd = open( file, O_RDONLY );
++      if( fd < 0 )
++      {
++              PRINT_ERROR( "Cannot open efl file : %s\n", file );
++              return (GHashTable *)NULL;
++      }
++
++      if( ( fstat( fd, &elf_stats ) ) )
++      {
++              PRINT_ERROR( "Cannot stat efl file : %s\n", file );
++              close(fd );
++              return (GHashTable *)NULL;
++      }
++
++      base_ptr = (char *) malloc( elf_stats.st_size );
++      if( base_ptr == (char *)NULL )
++      {
++              PRINT_ERROR( "Memory allocation error.\n" );
++              close( fd );
++              return (GHashTable *)NULL;
++      }
++
++      if( ( read( fd, base_ptr, elf_stats.st_size ) ) < elf_stats.st_size )
++      {
++              PRINT_ERROR( "Cannot read input efl file : %s\n", file );
++        free( base_ptr );
++        close( fd );
++              return (GHashTable *)NULL;
++      }
++      free( base_ptr );
++
++      /* Create output hash table */
++      outputHashTable = createHashTable();
++      if( outputHashTable == (GHashTable *)NULL )
++      {
++              PRINT_ERROR( "Memory allocation for hash table error : %s\n", file );
++        free( base_ptr );
++        close( fd );
++              return (GHashTable *)NULL;
++      }
++
++      if( elf_version( EV_CURRENT ) == EV_NONE )
++              fprintf( stderr, "WARNING Elf Library is out of date!\n" );
++
++      // Iterate through section headers again this time well stop when we find symbols
++      elf = elf_begin( fd, ELF_C_READ, NULL );
++
++      while( ( scn = elf_nextscn( elf, scn ) ) != (Elf_Scn *)NULL )
++      {
++              gelf_getshdr( scn, &shdr );
++
++              // When we find a section header marked SHT_SYMTAB stop and get symbols
++              if(shdr.sh_type == SHT_SYMTAB)
++              {
++                      // edata points to our symbol table
++                      edata = elf_getdata(scn, edata);
++
++                      symbol_count = shdr.sh_size / shdr.sh_entsize;
++
++                      for( i = 0; i < symbol_count; i++ )
++                      {
++                              /* Get symbol */
++                              gelf_getsym( edata, i, &sym );
++
++                              /* Get symbol name length */
++                              size = strlen( elf_strptr( elf, shdr.sh_link, sym.st_name ) );
++                              if( size != 0 )
++                              {
++                                      /* allocate memory for symbol name */
++                                      sname = (char *)malloc( sizeof( char ) * ( size + 1 ) );
++                                      if( sname == (char *)NULL )
++                                      {
++                                              PRINT_ERROR( "Memory allocation for hash table error : %s\n", file );
++                                              destroyHashTable( outputHashTable );
++                                      close( fd );
++                                              return (GHashTable *)NULL;
++                                      }
++
++                                      strcpy( sname, elf_strptr( elf, shdr.sh_link, sym.st_name ) );
++
++                                      // Add symbol to hash
++                                      if( addKernelSymboltoHashBase( (void *)sname, sname, outputHashTable ) < 0 )
++                                      {
++                                              // If duplicated key free memory
++                                              free( sname );
++                                      }
++
++                              }
++                      }
++              }
++      }
++
++      /* Close file */
++      close( fd );
++
++      /* Return hash table */
++      return outputHashTable;
++}
++
++/*
++ * Private user data definition.
++ */
++
++typedef struct _efl_user_data_
++{
++      GHashTable *kernelHash;
++      FILE *outFilePtr;
++} _efl_user_data_;
++
++
++void dumpModuleSymbolsIteration( gpointer key_, gpointer value_, gpointer user_data_ )
++{
++      char *key = (char *)key_;
++      _efl_user_data_ *user_data = (_efl_user_data_ *)user_data_;
++      KernelSymbol *ptr = (KernelSymbol *)NULL;
++
++      ptr = (KernelSymbol *)g_hash_table_lookup( user_data -> kernelHash, key );
++      if( ptr != (void *)NULL )
++              writeKernelSymbolsFile( user_data -> outFilePtr, ptr -> symbolNameCrc, ptr -> symbolName, ptr -> symbolModule, ptr -> flag );
++}
++
++/*
++ * Function dumps into output files kernel symbols that
++ * are use in the module
++ */
++int dumpModuleSymbols( char *outoutFile, GHashTable *moduleSymbols, GHashTable *kernelSymbols )
++{
++      FILE *outputFilePtr = getOutputFile( outoutFile );
++      _efl_user_data_ userData;
++
++      if( outputFilePtr == (FILE *)NULL )
++              return -1;
++
++      userData.outFilePtr = outputFilePtr;
++      userData.kernelHash = kernelSymbols;
++
++      /* Loob module symbols */
++      g_hash_table_foreach( moduleSymbols, dumpModuleSymbolsIteration, (gpointer)&userData );
++
++      /* Close output file */
++      releaseFile( outputFilePtr );
++
++      return 0;
++}
+diff --git a/packaging/linux-kernel.spec b/packaging/linux-kernel.spec
+index 0bbbfa5..485f06e 100644
+--- a/packaging/linux-kernel.spec
++++ b/packaging/linux-kernel.spec
+@@ -92,7 +92,7 @@ Linux kernel uImage
+ %build
+ # 0. Build abi checker
+-make -C tools/abi-checker/src
++make -C abi-checker/src
+ # 1. Create main build directory
+ rm -rf %{kernel_build_dir}
+@@ -112,7 +112,7 @@ make EXTRAVERSION="-%{build_id}" O=%{kernel_build_dir}/linux-kernel-build-%{vers
+ %if %{with abidev}
+ echo "No linuks kernel ABI/API checks"
+ %else
+-( cd tools/abi-checker/src; chmod 755 build_api_kernel_checker.sh; ./build_api_kernel_checker.sh "%{version}" "%{abiver}" )
++( cd abi-checker/src; chmod 755 build_api_kernel_checker.sh; ./build_api_kernel_checker.sh "%{version}" "%{abiver}" )
+ %endif
+ make EXTRAVERSION="-%{build_id}" O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} uImage %{?jobs:-j%jobs}
+@@ -146,17 +146,17 @@ make INSTALL_PATH=%{buildroot}/boot INSTALL_MOD_PATH=%{buildroot} O=%{kernel_bui
+ make INSTALL_PATH=%{buildroot} INSTALL_MOD_PATH=%{buildroot} O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} INSTALL_HDR_PATH=%{buildroot}/usr headers_install
+ # 4.1 Install ABI/API tools
+-cp tools/abi-checker/src/abi-checker %{buildroot}/usr/local/bin
+-cp tools/abi-checker/src/abi-module-checker %{buildroot}/usr/local/bin
+-cp tools/abi-checker/src/abi-module-dumper %{buildroot}/usr/local/bin
+-cp tools/abi-checker/src/abi-module-kernels-list %{buildroot}/usr/local/bin
++cp abi-checker/src/abi-checker %{buildroot}/usr/local/bin
++cp abi-checker/src/abi-module-checker %{buildroot}/usr/local/bin
++cp abi-checker/src/abi-module-dumper %{buildroot}/usr/local/bin
++cp abi-checker/src/abi-module-kernels-list %{buildroot}/usr/local/bin
+ chmod 755 %{buildroot}/usr/local/bin/*
+ # 4.2 Install abi_%{version} file
+ %if %{with abidev}
+ find ../.. -name "Module.symvers" -exec cp {} %{buildroot}/boot/abi/abi_devel \;
+ %else
+-cp tools/abi-checker/data/abi* %{buildroot}/boot/abi/.
++cp abi-checker/data/abi* %{buildroot}/boot/abi/.
+ ln -sf /boot/abi/abi_%{version}_%{abiver} %{buildroot}/boot/abi/current
+ %endif
+@@ -183,7 +183,7 @@ rm -rf %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}/%{kernel
+ rm -f  %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}/source
+ rm -f  %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/source
+-rm -rf %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}/tools/abi-checker
++rm -rf %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}/abi-checker
+ rm -rf %{buildroot}/System.map*
+ rm -rf %{buildroot}/vmlinux*
+diff --git a/tools/abi-checker/data/abi_3.10.19_1 b/tools/abi-checker/data/abi_3.10.19_1
+deleted file mode 100644
+index eea3455..0000000
+--- a/tools/abi-checker/data/abi_3.10.19_1
++++ /dev/null
+@@ -1,6900 +0,0 @@
+-0x80e54114    cfg80211_send_rx_assoc  vmlinux EXPORT_SYMBOL
+-0xd4dd4a5f    ipv6_chk_custom_prefix  vmlinux EXPORT_SYMBOL
+-0x765592d7    generic_file_splice_write       vmlinux EXPORT_SYMBOL
+-0x74f78b5f    set_anon_super  vmlinux EXPORT_SYMBOL
+-0x88ea56ef    kmem_cache_alloc        vmlinux EXPORT_SYMBOL
+-0x149d22ae    replace_page_cache_page vmlinux EXPORT_SYMBOL_GPL
+-0x70523a7a    __cond_resched_softirq  vmlinux EXPORT_SYMBOL
+-0x55417264    unregister_vt_notifier  vmlinux EXPORT_SYMBOL_GPL
+-0xc2ea8e64    snd_soc_platform_read   vmlinux EXPORT_SYMBOL_GPL
+-0x0a2487e0    unblock_all_signals     vmlinux EXPORT_SYMBOL
+-0x260cf8f8    of_get_property vmlinux EXPORT_SYMBOL
+-0x6ac315b3    v4l2_m2m_ioctl_dqbuf    vmlinux EXPORT_SYMBOL_GPL
+-0x5c421d9d    i2c_put_adapter vmlinux EXPORT_SYMBOL
+-0x4d8e0b9c    rtc_class_open  vmlinux EXPORT_SYMBOL_GPL
+-0x96cd2b04    scsi_sense_key_string   vmlinux EXPORT_SYMBOL
+-0xedf10a85    request_firmware        vmlinux EXPORT_SYMBOL
+-0x70230d35    __hci_cmd_sync  vmlinux EXPORT_SYMBOL
+-0x79dc2bec    dev_uc_sync     vmlinux EXPORT_SYMBOL
+-0xeb396e95    dev_mc_sync     vmlinux EXPORT_SYMBOL
+-0x80ca5026    _bin2bcd        vmlinux EXPORT_SYMBOL
+-0xfbaaf01e    console_lock    vmlinux EXPORT_SYMBOL
+-0xdf5311f6    hwmon_device_unregister vmlinux EXPORT_SYMBOL_GPL
+-0xe113bbbc    csum_partial    vmlinux EXPORT_SYMBOL
+-0x1ef4f43e    cfg80211_wext_siwscan   vmlinux EXPORT_SYMBOL_GPL
+-0xb343d54f    cfg80211_wext_giwscan   vmlinux EXPORT_SYMBOL_GPL
+-0xc068440e    __kfifo_alloc   vmlinux EXPORT_SYMBOL
+-0x376eb932    kmap_atomic     vmlinux EXPORT_SYMBOL
+-0xaadff4e7    nf_log_register vmlinux EXPORT_SYMBOL
+-0xc8276a79    nf_hooks_needed vmlinux EXPORT_SYMBOL
+-0x1b17e06c    kstrtoll        vmlinux EXPORT_SYMBOL
+-0xa7d57242    scsi_execute    vmlinux EXPORT_SYMBOL
+-0x9b757ebd    raw_seq_open    vmlinux EXPORT_SYMBOL_GPL
+-0x1b479d00    snd_soc_of_parse_audio_routing  vmlinux EXPORT_SYMBOL_GPL
+-0x3b2785b0    crypto_hash_walk_done   vmlinux EXPORT_SYMBOL_GPL
+-0xa1d55e90    _raw_spin_lock_bh       vmlinux EXPORT_SYMBOL
+-0xdd391eff    profile_event_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0xa724257f    init_uts_ns     vmlinux EXPORT_SYMBOL_GPL
+-0xc97d1140    cpufreq_cooling_get_level       vmlinux EXPORT_SYMBOL_GPL
+-0x5898fd79    device_add      vmlinux EXPORT_SYMBOL_GPL
+-0x5081d0b3    device_del      vmlinux EXPORT_SYMBOL_GPL
+-0x37246b6e    __inet6_hash    vmlinux EXPORT_SYMBOL
+-0xad3a5766    dst_release     vmlinux EXPORT_SYMBOL
+-0x1e254a30    sock_no_mmap    vmlinux EXPORT_SYMBOL
+-0x854e1c0b    sg_nents        vmlinux EXPORT_SYMBOL
+-0xb4c753a2    disk_map_sector_rcu     vmlinux EXPORT_SYMBOL_GPL
+-0x942da6f0    sysfs_update_group      vmlinux EXPORT_SYMBOL_GPL
+-0xa38602cd    drain_workqueue vmlinux EXPORT_SYMBOL_GPL
+-0xd4b5f202    led_trigger_store       vmlinux EXPORT_SYMBOL_GPL
+-0x80104269    tcp_initialize_rcv_mss  vmlinux EXPORT_SYMBOL
+-0x54e6fcdd    net_enable_timestamp    vmlinux EXPORT_SYMBOL
+-0xeb32f5c3    sockfd_lookup   vmlinux EXPORT_SYMBOL
+-0x02aa8f04    snd_soc_dapm_get_pin_switch     vmlinux EXPORT_SYMBOL_GPL
+-0x762265ad    snd_soc_dapm_put_pin_switch     vmlinux EXPORT_SYMBOL_GPL
+-0xb0ffda2f    blk_limits_max_hw_sectors       vmlinux EXPORT_SYMBOL
+-0x7cd8695d    directly_mappable_cdev_bdi      vmlinux EXPORT_SYMBOL
+-0x6bc3fbc0    __unregister_chrdev     vmlinux EXPORT_SYMBOL
+-0x6bb86c7d    srcu_notifier_chain_register    vmlinux EXPORT_SYMBOL_GPL
+-0x4b661f3f    v4l2_ctrl_grab  vmlinux EXPORT_SYMBOL
+-0xd2bbf775    fb_validate_mode        vmlinux EXPORT_SYMBOL
+-0xe8d75b12    nfc_target_lost vmlinux EXPORT_SYMBOL
+-0xb2d299a9    dev_graft_qdisc vmlinux EXPORT_SYMBOL
+-0xa851973a    raw_notifier_call_chain vmlinux EXPORT_SYMBOL_GPL
+-0x138709ec    scsi_get_command        vmlinux EXPORT_SYMBOL
+-0x174afb1a    __sg_page_iter_next     vmlinux EXPORT_SYMBOL
+-0x30cada8f    radix_tree_next_hole    vmlinux EXPORT_SYMBOL
+-0xc0412578    scsi_target_quiesce     vmlinux EXPORT_SYMBOL
+-0xd7a5d2f8    transport_class_register        vmlinux EXPORT_SYMBOL_GPL
+-0xd2335101    drm_fb_get_bpp_depth    vmlinux EXPORT_SYMBOL
+-0xa9a33fdf    jbd2_journal_try_to_free_buffers        vmlinux EXPORT_SYMBOL
+-0xffd5a395    default_wake_function   vmlinux EXPORT_SYMBOL
+-0xd6cb49e3    dm_put_device   vmlinux EXPORT_SYMBOL
+-0xb6e1e07d    dm_get_device   vmlinux EXPORT_SYMBOL
+-0x1f9218e9    input_handler_for_each_handle   vmlinux EXPORT_SYMBOL
+-0x560c6863    transport_class_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0x65f3ad9a    fb_videomode_to_var     vmlinux EXPORT_SYMBOL
+-0x79ad634c    nfc_hci_send_cmd_async  vmlinux EXPORT_SYMBOL
+-0x6bbf9530    mount_subtree   vmlinux EXPORT_SYMBOL
+-0x8f22ce41    iget_locked     vmlinux EXPORT_SYMBOL
+-0x6fba7c75    sdhci_runtime_suspend_host      vmlinux EXPORT_SYMBOL_GPL
+-0x7f923f2a    v4l2_of_parse_endpoint  vmlinux EXPORT_SYMBOL
+-0xaa2d0ca7    input_mt_assign_slots   vmlinux EXPORT_SYMBOL
+-0x167fd723    drm_mm_clean    vmlinux EXPORT_SYMBOL
+-0x9733c21d    sock_get_timestampns    vmlinux EXPORT_SYMBOL
+-0xf42e571f    snd_soc_dapm_put_enum_virt      vmlinux EXPORT_SYMBOL_GPL
+-0xcd16649c    snd_soc_dapm_get_enum_virt      vmlinux EXPORT_SYMBOL_GPL
+-0x38cb130f    iommu_group_add_device  vmlinux EXPORT_SYMBOL_GPL
+-0xe90d597e    class_interface_register        vmlinux EXPORT_SYMBOL_GPL
+-0x49ebacbd    _clear_bit      vmlinux EXPORT_SYMBOL
+-0x853b6dce    nfc_tm_activated        vmlinux EXPORT_SYMBOL
+-0xc617f82c    unregister_oom_notifier vmlinux EXPORT_SYMBOL_GPL
+-0x8da9fa20    spi_get_device_id       vmlinux EXPORT_SYMBOL_GPL
+-0x882f44c1    class_interface_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0x03757c9b    of_get_named_gpio_flags vmlinux EXPORT_SYMBOL
+-0x1b68aba6    pin_config_set  vmlinux EXPORT_SYMBOL
+-0x7505e34c    snd_power_wait  vmlinux EXPORT_SYMBOL
+-0x44366cfc    simple_write_to_buffer  vmlinux EXPORT_SYMBOL
+-0x3fec6133    read_code       vmlinux EXPORT_SYMBOL
+-0xf7bb3a63    __srcu_read_unlock      vmlinux EXPORT_SYMBOL_GPL
+-0xc2e587d1    reset_devices   vmlinux EXPORT_SYMBOL
+-0x07b991fc    iio_kfifo_free  vmlinux EXPORT_SYMBOL
+-0x36c38507    tty_register_device     vmlinux EXPORT_SYMBOL
+-0xa5a633b9    sg_last vmlinux EXPORT_SYMBOL
+-0x62c4e40d    __blk_run_queue vmlinux EXPORT_SYMBOL
+-0x3eaf291d    param_get_string        vmlinux EXPORT_SYMBOL
+-0x95cb929c    of_find_all_nodes       vmlinux EXPORT_SYMBOL
+-0xc2c5a45e    mmc_app_cmd     vmlinux EXPORT_SYMBOL_GPL
+-0xfa388487    usb_bus_list_lock       vmlinux EXPORT_SYMBOL_GPL
+-0xdbbaeb6e    regulator_map_voltage_linear    vmlinux EXPORT_SYMBOL_GPL
+-0x99bb8806    memmove vmlinux EXPORT_SYMBOL
+-0x9e6e25f9    jbd2_journal_start_commit       vmlinux EXPORT_SYMBOL
+-0x4c0f005a    __block_page_mkwrite    vmlinux EXPORT_SYMBOL
+-0x76d3cd60    laptop_mode     vmlinux EXPORT_SYMBOL
+-0x8fd01dea    generic_file_direct_write       vmlinux EXPORT_SYMBOL
+-0xa1f38f97    end_page_writeback      vmlinux EXPORT_SYMBOL
+-0xa75312bc    call_rcu_sched  vmlinux EXPORT_SYMBOL_GPL
+-0xb67b2219    cm_suspend_again        vmlinux EXPORT_SYMBOL_GPL
+-0x80311392    dmam_declare_coherent_memory    vmlinux EXPORT_SYMBOL
+-0xf2e8c6fe    skb_recv_datagram       vmlinux EXPORT_SYMBOL
+-0x4325cade    snd_soc_jack_add_pins   vmlinux EXPORT_SYMBOL_GPL
+-0x69cadac1    d_alloc_pseudo  vmlinux EXPORT_SYMBOL
+-0x871c0a7e    fiemap_check_flags      vmlinux EXPORT_SYMBOL
+-0xd0804fe2    generic_file_readonly_mmap      vmlinux EXPORT_SYMBOL
+-0xd06524ba    raw_notifier_chain_unregister   vmlinux EXPORT_SYMBOL_GPL
+-0x26448a56    usbnet_cdc_unbind       vmlinux EXPORT_SYMBOL_GPL
+-0x0bbae511    return_address  vmlinux EXPORT_SYMBOL_GPL
+-0x0d542439    __ipv6_addr_type        vmlinux EXPORT_SYMBOL
+-0xcf470397    unregister_qdisc        vmlinux EXPORT_SYMBOL
+-0x66a8c67c    crypto_shash_finup      vmlinux EXPORT_SYMBOL_GPL
+-0x5647361d    crypto_shash_final      vmlinux EXPORT_SYMBOL_GPL
+-0xf1c942f4    crypto_ahash_finup      vmlinux EXPORT_SYMBOL_GPL
+-0x17209ab0    crypto_ahash_final      vmlinux EXPORT_SYMBOL_GPL
+-0x8da17b42    scatterwalk_copychunks  vmlinux EXPORT_SYMBOL_GPL
+-0xd766d6a2    sdhci_suspend_host      vmlinux EXPORT_SYMBOL_GPL
+-0x9b05a0c7    usb_autopm_get_interface        vmlinux EXPORT_SYMBOL_GPL
+-0x8eff5a5b    phy_device_register     vmlinux EXPORT_SYMBOL
+-0xa2101833    sock_diag_put_meminfo   vmlinux EXPORT_SYMBOL_GPL
+-0xc8339e24    string_unescape vmlinux EXPORT_SYMBOL
+-0xeb55a931    __kfifo_max_r   vmlinux EXPORT_SYMBOL
+-0xe6511495    vm_insert_page  vmlinux EXPORT_SYMBOL
+-0x4396b273    irq_domain_add_legacy   vmlinux EXPORT_SYMBOL_GPL
+-0x24fdb0df    register_console        vmlinux EXPORT_SYMBOL
+-0x6ac76b42    pin_is_valid    vmlinux EXPORT_SYMBOL_GPL
+-0xe279ec34    nf_conntrack_l4proto_tcp4       vmlinux EXPORT_SYMBOL_GPL
+-0x512ce34d    sock_no_socketpair      vmlinux EXPORT_SYMBOL
+-0x236032ef    input_ff_event  vmlinux EXPORT_SYMBOL_GPL
+-0x1e5431bd    devm_gpio_request       vmlinux EXPORT_SYMBOL
+-0x86383d16    arpt_do_table   vmlinux EXPORT_SYMBOL
+-0x3c89040c    dev_addr_del    vmlinux EXPORT_SYMBOL
+-0xd900e010    gnet_stats_start_copy   vmlinux EXPORT_SYMBOL
+-0x33f0768c    cpufreq_quick_get_max   vmlinux EXPORT_SYMBOL
+-0xa88a70b0    tcp_tso_segment vmlinux EXPORT_SYMBOL
+-0xa652c4ef    __kfifo_dma_in_prepare_r        vmlinux EXPORT_SYMBOL
+-0xdfb895e4    __fat_fs_error  vmlinux EXPORT_SYMBOL_GPL
+-0x00438c43    bio_copy_kern   vmlinux EXPORT_SYMBOL
+-0xe0878bfe    __krealloc      vmlinux EXPORT_SYMBOL
+-0xa849b57b    devm_free_irq   vmlinux EXPORT_SYMBOL
+-0x995d1071    prof_on vmlinux EXPORT_SYMBOL_GPL
+-0x3328c21e    task_nice       vmlinux EXPORT_SYMBOL
+-0x84109a46    i2c_lock_adapter        vmlinux EXPORT_SYMBOL_GPL
+-0x76f824bb    usb_gadget_set_state    vmlinux EXPORT_SYMBOL_GPL
+-0x702c11cd    platform_device_del     vmlinux EXPORT_SYMBOL_GPL
+-0xccfe749d    platform_device_put     vmlinux EXPORT_SYMBOL_GPL
+-0x6499c2c3    kernel_accept   vmlinux EXPORT_SYMBOL
+-0x0147e076    kset_create_and_add     vmlinux EXPORT_SYMBOL_GPL
+-0xf60d1625    mm_kobj vmlinux EXPORT_SYMBOL_GPL
+-0x66561d40    set_bdi_congested       vmlinux EXPORT_SYMBOL
+-0xa064fc2f    gs_free_req     vmlinux EXPORT_SYMBOL_GPL
+-0xaf70f0bf    xt_proto_fini   vmlinux EXPORT_SYMBOL_GPL
+-0xc1e7bf31    devm_ioremap_resource   vmlinux EXPORT_SYMBOL
+-0x71d3571b    sg_miter_start  vmlinux EXPORT_SYMBOL
+-0xc5894dbd    blk_queue_unprep_rq     vmlinux EXPORT_SYMBOL
+-0x159c0774    lock_may_read   vmlinux EXPORT_SYMBOL
+-0x56d697ce    cpu_up  vmlinux EXPORT_SYMBOL_GPL
+-0xba406d79    usb_gadget_map_request  vmlinux EXPORT_SYMBOL_GPL
+-0xe2b9dcc5    wakeup_source_drop      vmlinux EXPORT_SYMBOL_GPL
+-0x19011c29    driver_find     vmlinux EXPORT_SYMBOL_GPL
+-0x13031824    devm_gpio_request_one   vmlinux EXPORT_SYMBOL
+-0x91db6962    snd_card_free   vmlinux EXPORT_SYMBOL
+-0x157b3f69    load_nls        vmlinux EXPORT_SYMBOL
+-0xffe5318c    dma_buf_map_attachment  vmlinux EXPORT_SYMBOL_GPL
+-0x10030de6    tty_mode_ioctl  vmlinux EXPORT_SYMBOL_GPL
+-0x00109670    fb_class        vmlinux EXPORT_SYMBOL
+-0x97999817    rfkill_set_hw_state     vmlinux EXPORT_SYMBOL
+-0x6597fe84    crypto_lookup_aead      vmlinux EXPORT_SYMBOL_GPL
+-0xd7b4b67a    bio_advance     vmlinux EXPORT_SYMBOL
+-0x4b8408ef    from_kuid       vmlinux EXPORT_SYMBOL
+-0xb65bd3fc    add_timer_on    vmlinux EXPORT_SYMBOL_GPL
+-0x4859b8bb    rtc_year_days   vmlinux EXPORT_SYMBOL
+-0xa064f393    ehci_cf_port_reset_rwsem        vmlinux EXPORT_SYMBOL_GPL
+-0x0c65e73c    scsi_normalize_sense    vmlinux EXPORT_SYMBOL
+-0x8e84b481    __pm_runtime_use_autosuspend    vmlinux EXPORT_SYMBOL_GPL
+-0xab2495da    drm_mode_connector_detach_encoder       vmlinux EXPORT_SYMBOL
+-0xbb11cfba    klist_iter_exit vmlinux EXPORT_SYMBOL_GPL
+-0x84044a12    ip6_local_out   vmlinux EXPORT_SYMBOL_GPL
+-0xc80b5684    snd_compress_deregister vmlinux EXPORT_SYMBOL_GPL
+-0x215ebd78    bitrev16        vmlinux EXPORT_SYMBOL
+-0x390def22    kstrtou16_from_user     vmlinux EXPORT_SYMBOL
+-0x9a74417e    kstrtoull_from_user     vmlinux EXPORT_SYMBOL
+-0x6949942d    pm_runtime_set_autosuspend_delay        vmlinux EXPORT_SYMBOL_GPL
+-0xfb6eedf9    power_group_name        vmlinux EXPORT_SYMBOL_GPL
+-0x7752eabc    snd_pcm_new_internal    vmlinux EXPORT_SYMBOL
+-0x59cdb28e    crypto_aead_type        vmlinux EXPORT_SYMBOL_GPL
+-0xeadf5b18    jbd2_journal_load       vmlinux EXPORT_SYMBOL
+-0xcd6a7390    v4l2_i2c_new_subdev     vmlinux EXPORT_SYMBOL_GPL
+-0x997574ce    device_unregister       vmlinux EXPORT_SYMBOL_GPL
+-0xedbfb39a    serial8250_request_dma  vmlinux EXPORT_SYMBOL_GPL
+-0x19a156ad    xfrm_state_add  vmlinux EXPORT_SYMBOL
+-0x4d4a6141    __netlink_kernel_create vmlinux EXPORT_SYMBOL
+-0x3ad82802    of_property_read_u32_index      vmlinux EXPORT_SYMBOL_GPL
+-0x96b53df6    mmc_cleanup_queue       vmlinux EXPORT_SYMBOL
+-0x7b9ee22c    v4l2_ctrl_notify        vmlinux EXPORT_SYMBOL
+-0xda3a7ca9    regulator_is_enabled    vmlinux EXPORT_SYMBOL_GPL
+-0x137def66    nf_ct_l4proto_put       vmlinux EXPORT_SYMBOL_GPL
+-0x7efdb4fb    nf_ct_l3proto_put       vmlinux EXPORT_SYMBOL_GPL
+-0x9948898e    dapm_mark_dirty vmlinux EXPORT_SYMBOL_GPL
+-0x2484d571    single_release_net      vmlinux EXPORT_SYMBOL_GPL
+-0x5612133a    I_BDEV  vmlinux EXPORT_SYMBOL
+-0x7729cbdd    task_handoff_register   vmlinux EXPORT_SYMBOL_GPL
+-0x19353b86    scsicam_bios_param      vmlinux EXPORT_SYMBOL
+-0xb6a76b8e    pn544_hci_probe vmlinux EXPORT_SYMBOL
+-0x476c3efa    drm_fill_in_dev vmlinux EXPORT_SYMBOL
+-0x4f1cd128    security_tun_dev_create vmlinux EXPORT_SYMBOL
+-0x76f29bbf    seq_release_net vmlinux EXPORT_SYMBOL_GPL
+-0x980420fb    tty_port_tty_set        vmlinux EXPORT_SYMBOL
+-0xc215715c    tty_port_tty_get        vmlinux EXPORT_SYMBOL
+-0xa8c74dc5    devm_regulator_get      vmlinux EXPORT_SYMBOL_GPL
+-0x3441c3d6    gpio_set_value_cansleep vmlinux EXPORT_SYMBOL_GPL
+-0xcd68dc1d    nfc_get_local_general_bytes     vmlinux EXPORT_SYMBOL
+-0xf617c0a1    inet_csk_route_child_sock       vmlinux EXPORT_SYMBOL_GPL
+-0xfce4d2e1    vfs_path_lookup vmlinux EXPORT_SYMBOL
+-0x326314e4    find_or_create_page     vmlinux EXPORT_SYMBOL
+-0x65bbbc78    schedule_hrtimeout_range        vmlinux EXPORT_SYMBOL_GPL
+-0x8d7b0a28    phy_stop_interrupts     vmlinux EXPORT_SYMBOL
+-0xe9e87de1    crypto_register_pcomp   vmlinux EXPORT_SYMBOL_GPL
+-0x2d7966fb    jbd2_journal_flush      vmlinux EXPORT_SYMBOL
+-0x1c4e8441    invalidate_bdev vmlinux EXPORT_SYMBOL
+-0x9aeacb87    ring_buffer_iter_empty  vmlinux EXPORT_SYMBOL_GPL
+-0x49eb1c4a    put_pid_ns      vmlinux EXPORT_SYMBOL_GPL
+-0xb7e67f9a    iio_sw_buffer_preenable vmlinux EXPORT_SYMBOL
+-0xeae6b2cc    usb_sg_init     vmlinux EXPORT_SYMBOL_GPL
+-0x2f33a47d    usb_sg_wait     vmlinux EXPORT_SYMBOL_GPL
+-0xba136537    scsi_reset_provider     vmlinux EXPORT_SYMBOL
+-0xa9170094    drm_kms_helper_hotplug_event    vmlinux EXPORT_SYMBOL
+-0xb007d3b8    tcp_twsk_unique vmlinux EXPORT_SYMBOL_GPL
+-0xd35091f2    netdev_info     vmlinux EXPORT_SYMBOL
+-0x3517b864    kobject_uevent  vmlinux EXPORT_SYMBOL_GPL
+-0x82a5ee54    mmc_try_claim_host      vmlinux EXPORT_SYMBOL
+-0x11267875    scsi_extd_sense_format  vmlinux EXPORT_SYMBOL
+-0x4f56540f    pm_wakeup_event vmlinux EXPORT_SYMBOL_GPL
+-0x6c61ce70    num_registered_fb       vmlinux EXPORT_SYMBOL
+-0xcc2f1602    st_sensors_sysfs_get_sampling_frequency vmlinux EXPORT_SYMBOL
+-0x0bf95cc0    st_sensors_sysfs_set_sampling_frequency vmlinux EXPORT_SYMBOL
+-0xa73fc98f    of_n_addr_cells vmlinux EXPORT_SYMBOL
+-0xaf5c2852    wakeup_source_add       vmlinux EXPORT_SYMBOL_GPL
+-0xc27732b1    snd_pcm_lib_default_mmap        vmlinux EXPORT_SYMBOL_GPL
+-0x3ca17104    __snd_printk    vmlinux EXPORT_SYMBOL_GPL
+-0xa6a59f23    blk_cleanup_queue       vmlinux EXPORT_SYMBOL
+-0xec3364ec    generic_setlease        vmlinux EXPORT_SYMBOL
+-0x440d8a62    tty_hung_up_p   vmlinux EXPORT_SYMBOL
+-0xfa2e4ead    ip6_tnl_dst_store       vmlinux EXPORT_SYMBOL_GPL
+-0x5a0647c1    ipv6_getsockopt vmlinux EXPORT_SYMBOL
+-0x329bbbde    timerqueue_del  vmlinux EXPORT_SYMBOL_GPL
+-0x34161524    st_sensors_read_event_value     vmlinux EXPORT_SYMBOL
+-0x3e16c1b5    v4l2_clk_put    vmlinux EXPORT_SYMBOL
+-0xdc047fc4    scsi_dev_info_list_add_keyed    vmlinux EXPORT_SYMBOL
+-0xdc97af2e    syscore_suspend vmlinux EXPORT_SYMBOL_GPL
+-0xaebbf521    cfg80211_ch_switch_notify       vmlinux EXPORT_SYMBOL
+-0x4fdb4cdf    proc_mkdir_data vmlinux EXPORT_SYMBOL_GPL
+-0x8ffad455    mpage_writepages        vmlinux EXPORT_SYMBOL
+-0x258f05ac    write_one_page  vmlinux EXPORT_SYMBOL
+-0x32b31a8c    ktime_get_boottime      vmlinux EXPORT_SYMBOL_GPL
+-0x15892417    async_synchronize_cookie        vmlinux EXPORT_SYMBOL_GPL
+-0x5a596330    v4l2_i2c_new_subdev_board       vmlinux EXPORT_SYMBOL_GPL
+-0xbd05974a    usb_driver_release_interface    vmlinux EXPORT_SYMBOL_GPL
+-0xce190a28    cfg80211_notify_new_peer_candidate      vmlinux EXPORT_SYMBOL
+-0x23c45e2a    inet_add_protocol       vmlinux EXPORT_SYMBOL
+-0xe19c66e3    sync_blockdev   vmlinux EXPORT_SYMBOL
+-0xd36667e2    nobh_write_end  vmlinux EXPORT_SYMBOL
+-0x815a1805    n_tty_ioctl_helper      vmlinux EXPORT_SYMBOL
+-0xedd9106d    __ashrdi3       vmlinux EXPORT_SYMBOL
+-0xff67b37f    __lshrdi3       vmlinux EXPORT_SYMBOL
+-0x85b5e625    rfkill_set_states       vmlinux EXPORT_SYMBOL
+-0x6e720ff2    rtnl_unlock     vmlinux EXPORT_SYMBOL
+-0x4c02a5f2    sock_rfree      vmlinux EXPORT_SYMBOL
+-0xe252485d    kernel_recvmsg  vmlinux EXPORT_SYMBOL
+-0x0693eedb    disk_part_iter_init     vmlinux EXPORT_SYMBOL_GPL
+-0x4019ac2a    freeze_bdev     vmlinux EXPORT_SYMBOL
+-0x9f1c66aa    srcu_batches_completed  vmlinux EXPORT_SYMBOL_GPL
+-0xa6ec6db0    sdhci_alloc_host        vmlinux EXPORT_SYMBOL_GPL
+-0x0bfba95f    usb_hub_find_child      vmlinux EXPORT_SYMBOL_GPL
+-0x9f83d040    __root_device_register  vmlinux EXPORT_SYMBOL_GPL
+-0x63b124fc    drm_bl_dpms     vmlinux EXPORT_SYMBOL_GPL
+-0xb35f8f7f    __hci_cmd_sync_ev       vmlinux EXPORT_SYMBOL
+-0xe177ecc2    skb_kill_datagram       vmlinux EXPORT_SYMBOL
+-0x985c6297    kfree_skb       vmlinux EXPORT_SYMBOL
+-0xdcb83c11    kernel_kobj     vmlinux EXPORT_SYMBOL_GPL
+-0x1bb5fc26    atomic_notifier_chain_register  vmlinux EXPORT_SYMBOL_GPL
+-0xab1d6cc1    param_get_long  vmlinux EXPORT_SYMBOL
+-0x75d68801    inet_twsk_schedule      vmlinux EXPORT_SYMBOL_GPL
+-0x68b83ac6    posix_acl_alloc vmlinux EXPORT_SYMBOL
+-0x306b23a8    drm_mm_takedown vmlinux EXPORT_SYMBOL
+-0x698be398    regulator_get_voltage   vmlinux EXPORT_SYMBOL_GPL
+-0xc8bed9c5    amba_driver_unregister  vmlinux EXPORT_SYMBOL
+-0x1db7dc40    pgprot_kernel   vmlinux EXPORT_SYMBOL
+-0x19e03378    cfg80211_get_p2p_attr   vmlinux EXPORT_SYMBOL
+-0x44a5de9b    nfnetlink_parse_nat_setup_hook  vmlinux EXPORT_SYMBOL_GPL
+-0x52d047db    skb_copy_datagram_iovec vmlinux EXPORT_SYMBOL
+-0x731f351a    __kfree_skb     vmlinux EXPORT_SYMBOL
+-0xd544b6fe    fuse_do_open    vmlinux EXPORT_SYMBOL_GPL
+-0xd98f64fc    tty_port_register_device        vmlinux EXPORT_SYMBOL_GPL
+-0xfd305341    walk_stackframe vmlinux EXPORT_SYMBOL
+-0x58378f4a    snd_soc_dapm_force_enable_pin   vmlinux EXPORT_SYMBOL_GPL
+-0x31b31f5c    csum_partial_copy_nocheck       vmlinux EXPORT_SYMBOL
+-0xeea82d10    ip_defrag       vmlinux EXPORT_SYMBOL
+-0xd75abd53    register_qdisc  vmlinux EXPORT_SYMBOL
+-0xe4bf323c    snd_soc_test_bits       vmlinux EXPORT_SYMBOL_GPL
+-0x5d891a64    idr_destroy     vmlinux EXPORT_SYMBOL
+-0xeb9e7cdd    ida_destroy     vmlinux EXPORT_SYMBOL
+-0x302b0f11    generic_file_aio_read   vmlinux EXPORT_SYMBOL
+-0x3fe00f7d    mmc_can_discard vmlinux EXPORT_SYMBOL
+-0x51246a07    mmc_interrupt_hpi       vmlinux EXPORT_SYMBOL
+-0xce55bca9    scsi_flush_work vmlinux EXPORT_SYMBOL_GPL
+-0x3ca53f5d    arpt_alloc_initial_table        vmlinux EXPORT_SYMBOL_GPL
+-0x3ab45d33    free_netdev     vmlinux EXPORT_SYMBOL
+-0xc9ec4e21    free_percpu     vmlinux EXPORT_SYMBOL_GPL
+-0x431fd1f6    v4l2_subdev_queryctrl   vmlinux EXPORT_SYMBOL
+-0x7c0f2bb5    drm_mm_create_block     vmlinux EXPORT_SYMBOL
+-0x3fa79dd5    ip6_datagram_recv_ctl   vmlinux EXPORT_SYMBOL_GPL
+-0xd56d7aae    sk_setup_caps   vmlinux EXPORT_SYMBOL_GPL
+-0x668da8d5    zlib_inflateIncomp      vmlinux EXPORT_SYMBOL
+-0xe0f99a2f    ida_pre_get     vmlinux EXPORT_SYMBOL
+-0xf932015f    __raw_notifier_call_chain       vmlinux EXPORT_SYMBOL_GPL
+-0x4d3c153f    sigprocmask     vmlinux EXPORT_SYMBOL
+-0xd1974639    spi_sync_locked vmlinux EXPORT_SYMBOL_GPL
+-0xdcbd7c06    scsi_host_get   vmlinux EXPORT_SYMBOL
+-0x8ccc342d    drm_helper_move_panel_connectors_to_head        vmlinux EXPORT_SYMBOL
+-0x98578bb6    regulator_bulk_get      vmlinux EXPORT_SYMBOL_GPL
+-0x85ddc629    sk_stream_wait_connect  vmlinux EXPORT_SYMBOL
+-0x4db49a03    vb2_ioctl_dqbuf vmlinux EXPORT_SYMBOL_GPL
+-0xf720d75c    drm_vblank_init vmlinux EXPORT_SYMBOL
+-0x8d551bef    sysctl_tcp_rmem vmlinux EXPORT_SYMBOL
+-0x6c8c2ae7    sock_no_sendmsg vmlinux EXPORT_SYMBOL
+-0x3b1b7e9f    snd_soc_bytes_get       vmlinux EXPORT_SYMBOL_GPL
+-0xf74dae0f    idr_alloc       vmlinux EXPORT_SYMBOL_GPL
+-0x7c666ca1    jbd2_journal_update_sb_errno    vmlinux EXPORT_SYMBOL
+-0x98d00f33    vfs_unlink      vmlinux EXPORT_SYMBOL
+-0x9ee85355    extcon_unregister_notifier      vmlinux EXPORT_SYMBOL_GPL
+-0xf9e3887b    i2c_master_recv vmlinux EXPORT_SYMBOL
+-0xaff711f1    drm_global_mutex        vmlinux EXPORT_SYMBOL
+-0x62c5828a    nfc_hci_set_param       vmlinux EXPORT_SYMBOL
+-0x52512e8e    nfc_hci_get_param       vmlinux EXPORT_SYMBOL
+-0x4c90a5a9    lro_flush_all   vmlinux EXPORT_SYMBOL
+-0xc5116125    pipe_unlock     vmlinux EXPORT_SYMBOL
+-0x2d6bcdcb    iio_trigger_generic_data_rdy_poll       vmlinux EXPORT_SYMBOL
+-0x48c6db53    of_get_child_by_name    vmlinux EXPORT_SYMBOL
+-0x4379f0a6    genlmsg_multicast_allns vmlinux EXPORT_SYMBOL
+-0x43e32587    __sock_recv_wifi_status vmlinux EXPORT_SYMBOL_GPL
+-0x83a5ae2e    __tracepoint_rpm_resume vmlinux EXPORT_SYMBOL_GPL
+-0xb2d48a2e    queue_work_on   vmlinux EXPORT_SYMBOL
+-0x59d8223a    ioport_resource vmlinux EXPORT_SYMBOL
+-0x73a25185    pm_generic_restore      vmlinux EXPORT_SYMBOL_GPL
+-0x401ad827    bus_rescan_devices      vmlinux EXPORT_SYMBOL_GPL
+-0x3b4e8e6c    serial8250_tx_dma       vmlinux EXPORT_SYMBOL_GPL
+-0xba9f64c5    put_tty_driver  vmlinux EXPORT_SYMBOL
+-0xa46a0fcf    backlight_force_update  vmlinux EXPORT_SYMBOL
+-0xc7a4fbed    rtnl_lock       vmlinux EXPORT_SYMBOL
+-0x27b3484e    debugfs_create_bool     vmlinux EXPORT_SYMBOL_GPL
+-0x3691702f    generic_file_splice_read        vmlinux EXPORT_SYMBOL
+-0xdd2efc0f    ring_buffer_reset_cpu   vmlinux EXPORT_SYMBOL_GPL
+-0x2c1d69dc    prepare_kernel_cred     vmlinux EXPORT_SYMBOL
+-0x897473df    mktime  vmlinux EXPORT_SYMBOL
+-0xa8721b97    system_state    vmlinux EXPORT_SYMBOL
+-0x2b768df3    iio_buffer_show_enable  vmlinux EXPORT_SYMBOL
+-0xc3070585    xfrm6_tunnel_alloc_spi  vmlinux EXPORT_SYMBOL
+-0x6e583bdd    udp_push_pending_frames vmlinux EXPORT_SYMBOL
+-0xead6dbe6    splice_from_pipe_next   vmlinux EXPORT_SYMBOL
+-0x6d044c26    param_ops_uint  vmlinux EXPORT_SYMBOL
+-0x6f0036d9    del_timer_sync  vmlinux EXPORT_SYMBOL
+-0xc9db98ec    hidinput_connect        vmlinux EXPORT_SYMBOL_GPL
+-0xa3a75748    sec_bulk_read   vmlinux EXPORT_SYMBOL_GPL
+-0x7c640527    bt_info vmlinux EXPORT_SYMBOL
+-0x00e8097b    csum_partial_copy_fromiovecend  vmlinux EXPORT_SYMBOL
+-0x098ef076    wm_hubs_vmid_ena        vmlinux EXPORT_SYMBOL_GPL
+-0xc29591b4    drm_framebuffer_unreference     vmlinux EXPORT_SYMBOL
+-0xdbfa4d5b    con_set_default_unimap  vmlinux EXPORT_SYMBOL
+-0x08b75c5b    inet_diag_bc_sk vmlinux EXPORT_SYMBOL_GPL
+-0x3dea553f    __qdisc_calculate_pkt_len       vmlinux EXPORT_SYMBOL
+-0xab5f8242    dev_get_by_index        vmlinux EXPORT_SYMBOL
+-0x3e9d0c22    wm8958_mic_detect       vmlinux EXPORT_SYMBOL_GPL
+-0x462a2e75    match_strlcpy   vmlinux EXPORT_SYMBOL
+-0xf768dabc    ioctl_by_bdev   vmlinux EXPORT_SYMBOL
+-0x426b04e4    dma_buf_unmap_attachment        vmlinux EXPORT_SYMBOL_GPL
+-0x27146b38    init_net        vmlinux EXPORT_SYMBOL
+-0x9fe06761    wm_hubs_update_class_w  vmlinux EXPORT_SYMBOL_GPL
+-0x8978d687    textsearch_find_continuous      vmlinux EXPORT_SYMBOL
+-0xf7b12aee    __next_cpu      vmlinux EXPORT_SYMBOL
+-0x96905151    crypto_larval_lookup    vmlinux EXPORT_SYMBOL_GPL
+-0xb14bfc6b    __crypto_alloc_tfm      vmlinux EXPORT_SYMBOL_GPL
+-0x3ca95bb3    configfs_unregister_subsystem   vmlinux EXPORT_SYMBOL
+-0xd820c283    eventfd_ctx_remove_wait_queue   vmlinux EXPORT_SYMBOL_GPL
+-0x699d1d6a    generic_delete_inode    vmlinux EXPORT_SYMBOL
+-0xb5f17edf    perf_register_guest_info_callbacks      vmlinux EXPORT_SYMBOL_GPL
+-0x1d209e24    mmc_power_restore_host  vmlinux EXPORT_SYMBOL
+-0x8c66045e    cpufreq_freq_attr_scaling_boost_freqs   vmlinux EXPORT_SYMBOL_GPL
+-0x6114d8a4    regulator_force_disable vmlinux EXPORT_SYMBOL_GPL
+-0x7e606130    snd_soc_calc_bclk       vmlinux EXPORT_SYMBOL_GPL
+-0xac480322    nf_nat_pptp_hook_expectfn       vmlinux EXPORT_SYMBOL_GPL
+-0x7f19e69f    blk_run_queue   vmlinux EXPORT_SYMBOL
+-0x98dbc3bc    mmc_wait_for_req        vmlinux EXPORT_SYMBOL
+-0xa0d2b347    regmap_init_spi vmlinux EXPORT_SYMBOL_GPL
+-0xff7a8968    regmap_init_i2c vmlinux EXPORT_SYMBOL_GPL
+-0x98cc564a    regulator_set_voltage   vmlinux EXPORT_SYMBOL_GPL
+-0xcd63c845    __aeabi_lasr    vmlinux EXPORT_SYMBOL
+-0x8a4fa83b    __aeabi_llsr    vmlinux EXPORT_SYMBOL
+-0x78cfc117    hci_register_dev        vmlinux EXPORT_SYMBOL
+-0xd458f195    __secpath_destroy       vmlinux EXPORT_SYMBOL
+-0xaf64ad0d    zlib_deflate    vmlinux EXPORT_SYMBOL
+-0x24fdac79    wake_bit_function       vmlinux EXPORT_SYMBOL
+-0x864f4a52    of_clk_add_provider     vmlinux EXPORT_SYMBOL_GPL
+-0x1de054d5    of_clk_del_provider     vmlinux EXPORT_SYMBOL_GPL
+-0x42c8e001    v4l2_ctrl_next  vmlinux EXPORT_SYMBOL
+-0x1e95b9ac    i2c_smbus_write_i2c_block_data  vmlinux EXPORT_SYMBOL
+-0xc61c11c2    inet_csk_route_req      vmlinux EXPORT_SYMBOL_GPL
+-0xed597524    qdisc_get_rtab  vmlinux EXPORT_SYMBOL
+-0x9a633fbd    fuse_request_send_background    vmlinux EXPORT_SYMBOL_GPL
+-0x578e47c8    locks_release_private   vmlinux EXPORT_SYMBOL_GPL
+-0x40ce485b    mempool_resize  vmlinux EXPORT_SYMBOL
+-0xc60f75ec    __ftrace_vprintk        vmlinux EXPORT_SYMBOL_GPL
+-0xb88fb22f    hid_set_field   vmlinux EXPORT_SYMBOL_GPL
+-0xd954e4a7    bus_remove_file vmlinux EXPORT_SYMBOL_GPL
+-0x6172f515    xfrm_unregister_km      vmlinux EXPORT_SYMBOL
+-0xc5e4258e    in_dev_finish_destroy   vmlinux EXPORT_SYMBOL
+-0xe094ef39    sg_next vmlinux EXPORT_SYMBOL
+-0x6b4be175    bio_map_user    vmlinux EXPORT_SYMBOL
+-0x0b07abe2    unshare_fs_struct       vmlinux EXPORT_SYMBOL_GPL
+-0x2ef6b5bf    smp_call_function_any   vmlinux EXPORT_SYMBOL_GPL
+-0xd0fb7cd4    __tasklet_hi_schedule_first     vmlinux EXPORT_SYMBOL
+-0xe35c5285    of_find_node_by_phandle vmlinux EXPORT_SYMBOL
+-0x55724b35    hid_destroy_device      vmlinux EXPORT_SYMBOL_GPL
+-0x85ad5803    cfg80211_wext_siwrts    vmlinux EXPORT_SYMBOL_GPL
+-0x87cfc6e0    cfg80211_wext_giwrts    vmlinux EXPORT_SYMBOL_GPL
+-0xd1b091c0    unix_inq_len    vmlinux EXPORT_SYMBOL_GPL
+-0xc4d21124    __nf_conntrack_confirm  vmlinux EXPORT_SYMBOL_GPL
+-0x452a56c2    __brelse        vmlinux EXPORT_SYMBOL
+-0xbddeca9d    pipe_lock       vmlinux EXPORT_SYMBOL
+-0x33bfdca2    gserial_alloc_line      vmlinux EXPORT_SYMBOL_GPL
+-0x4edb7421    config_ep_by_speed      vmlinux EXPORT_SYMBOL_GPL
+-0xa473e3d4    usbnet_suspend  vmlinux EXPORT_SYMBOL_GPL
+-0x06521223    mdiobus_scan    vmlinux EXPORT_SYMBOL
+-0xed8f1a2b    dmam_alloc_coherent     vmlinux EXPORT_SYMBOL
+-0x9535ce7b    tty_port_carrier_raised vmlinux EXPORT_SYMBOL
+-0x71280d73    regulator_set_voltage_time_sel  vmlinux EXPORT_SYMBOL_GPL
+-0x1e314b21    regulator_use_dummy_regulator   vmlinux EXPORT_SYMBOL_GPL
+-0x347fd4b3    eventfd_ctx_get vmlinux EXPORT_SYMBOL_GPL
+-0x941f2aaa    eventfd_ctx_put vmlinux EXPORT_SYMBOL_GPL
+-0xf9d18552    mark_buffer_async_write vmlinux EXPORT_SYMBOL
+-0x6c6cdd4d    wait_for_completion_interruptible_timeout       vmlinux EXPORT_SYMBOL
+-0xe5525b81    scsi_device_set_state   vmlinux EXPORT_SYMBOL
+-0x28e23139    xfrm_probe_algs vmlinux EXPORT_SYMBOL_GPL
+-0x9a9ff422    ip_route_me_harder      vmlinux EXPORT_SYMBOL
+-0xb7cbbafa    inet_sock_destruct      vmlinux EXPORT_SYMBOL
+-0xf26e8a56    nf_reinject     vmlinux EXPORT_SYMBOL
+-0x3a9b6fb9    blk_unregister_region   vmlinux EXPORT_SYMBOL
+-0x2a2c3036    unregister_nls  vmlinux EXPORT_SYMBOL
+-0x5358fc36    ring_buffer_discard_commit      vmlinux EXPORT_SYMBOL_GPL
+-0x555621fa    clk_enable      vmlinux EXPORT_SYMBOL_GPL
+-0xf25af73c    mmc_add_host    vmlinux EXPORT_SYMBOL
+-0x4b02b5ca    dev_pm_qos_update_request       vmlinux EXPORT_SYMBOL_GPL
+-0xe11c3bb2    tty_chars_in_buffer     vmlinux EXPORT_SYMBOL
+-0x4e60ec09    __serio_register_port   vmlinux EXPORT_SYMBOL
+-0xc17515d7    usb_hcds_loaded vmlinux EXPORT_SYMBOL_GPL
+-0xadfe5127    usbnet_write_cmd_nopm   vmlinux EXPORT_SYMBOL_GPL
+-0x9c6c1c9c    phy_exit        vmlinux EXPORT_SYMBOL_GPL
+-0x44da5d0f    __csum_ipv6_magic       vmlinux EXPORT_SYMBOL
+-0x2ef42c91    l2cap_register_user     vmlinux EXPORT_SYMBOL
+-0xa83b115e    skb_pull_rcsum  vmlinux EXPORT_SYMBOL_GPL
+-0xbaa490f8    snd_ctl_unregister_ioctl        vmlinux EXPORT_SYMBOL
+-0xe3df2eb1    v4l2_async_notifier_register    vmlinux EXPORT_SYMBOL
+-0x950c4994    __scsi_device_lookup_by_target  vmlinux EXPORT_SYMBOL
+-0xed3baf1d    tcp_fetch_timewait_stamp        vmlinux EXPORT_SYMBOL_GPL
+-0xebdbe48c    radix_tree_gang_lookup  vmlinux EXPORT_SYMBOL
+-0xc00b1f1e    register_nls    vmlinux EXPORT_SYMBOL
+-0x62543231    locks_alloc_lock        vmlinux EXPORT_SYMBOL_GPL
+-0x6585e310    alloc_pages_exact_nid   vmlinux EXPORT_SYMBOL
+-0xb121390a    probe_irq_on    vmlinux EXPORT_SYMBOL
+-0xc58f706b    usbnet_get_msglevel     vmlinux EXPORT_SYMBOL_GPL
+-0x1007becd    usbnet_set_msglevel     vmlinux EXPORT_SYMBOL_GPL
+-0xb9eb9d79    pm_generic_suspend      vmlinux EXPORT_SYMBOL_GPL
+-0xca860514    xfrm_state_lookup       vmlinux EXPORT_SYMBOL
+-0x795598eb    tcp_parse_options       vmlinux EXPORT_SYMBOL
+-0x17a3ce1e    rps_may_expire_flow     vmlinux EXPORT_SYMBOL
+-0x7b3d29ac    i2c_smbus_write_block_data      vmlinux EXPORT_SYMBOL
+-0x8164b1cc    ump_dd_handle_create_from_secure_id     vmlinux EXPORT_SYMBOL
+-0x7f04682a    of_gpio_simple_xlate    vmlinux EXPORT_SYMBOL
+-0xefd6cf06    __aeabi_unwind_cpp_pr0  vmlinux EXPORT_SYMBOL
+-0xb7ba76c7    __aeabi_unwind_cpp_pr2  vmlinux EXPORT_SYMBOL
+-0x43f0af31    snd_soc_codec_set_pll   vmlinux EXPORT_SYMBOL_GPL
+-0x6e46b07b    module_refcount vmlinux EXPORT_SYMBOL
+-0x455348d7    usb_composite_probe     vmlinux EXPORT_SYMBOL_GPL
+-0x0e8110c3    sec_reg_write   vmlinux EXPORT_SYMBOL_GPL
+-0xba0edce6    inet_ctl_sock_create    vmlinux EXPORT_SYMBOL_GPL
+-0x8454f899    dev_addr_add_multiple   vmlinux EXPORT_SYMBOL
+-0x62e4112b    _submit_bh      vmlinux EXPORT_SYMBOL_GPL
+-0x715622e2    handle_edge_irq vmlinux EXPORT_SYMBOL
+-0x0e639705    usbnet_link_change      vmlinux EXPORT_SYMBOL
+-0x8043eb8c    firmware_kobj   vmlinux EXPORT_SYMBOL_GPL
+-0x130bf78b    drm_mode_create_from_cmdline_mode       vmlinux EXPORT_SYMBOL
+-0xbdd37f04    usb_autopm_put_interface_async  vmlinux EXPORT_SYMBOL_GPL
+-0x63c46f03    usb_lock_device_for_reset       vmlinux EXPORT_SYMBOL_GPL
+-0x1bc5eebe    pinctrl_gpio_direction_input    vmlinux EXPORT_SYMBOL_GPL
+-0x519b061e    genl_register_mc_group  vmlinux EXPORT_SYMBOL
+-0xf81e0907    ___pskb_trim    vmlinux EXPORT_SYMBOL
+-0xd352e668    snd_timer_global_new    vmlinux EXPORT_SYMBOL
+-0x85df9b6c    strsep  vmlinux EXPORT_SYMBOL
+-0xe2d5255a    strcmp  vmlinux EXPORT_SYMBOL
+-0x788fe103    iomem_resource  vmlinux EXPORT_SYMBOL
+-0xe7a9a6a0    tty_driver_flush_buffer vmlinux EXPORT_SYMBOL
+-0xd648e564    fb_match_mode   vmlinux EXPORT_SYMBOL
+-0xbc10dd97    __put_user_4    vmlinux EXPORT_SYMBOL
+-0x353e3fa5    __get_user_4    vmlinux EXPORT_SYMBOL
+-0xe50ad8a8    snd_ctl_add     vmlinux EXPORT_SYMBOL
+-0x6323f87b    mnt_unpin       vmlinux EXPORT_SYMBOL
+-0xbb524006    vfs_create      vmlinux EXPORT_SYMBOL
+-0x2f47d8c7    cpufreq_frequency_get_table     vmlinux EXPORT_SYMBOL_GPL
+-0xda44cb37    setup_charger_manager   vmlinux EXPORT_SYMBOL_GPL
+-0x01ab74a6    devm_kfree      vmlinux EXPORT_SYMBOL_GPL
+-0x153be8a8    drm_fb_helper_pan_display       vmlinux EXPORT_SYMBOL
+-0xc676a007    __ablkcipher_walk_complete      vmlinux EXPORT_SYMBOL_GPL
+-0x868bf31d    sb_min_blocksize        vmlinux EXPORT_SYMBOL
+-0xaf5f7994    remove_conflicting_framebuffers vmlinux EXPORT_SYMBOL
+-0x49e5aa17    bt_procfs_init  vmlinux EXPORT_SYMBOL
+-0xf353a698    register_module_notifier        vmlinux EXPORT_SYMBOL
+-0x154c6338    dm_kcopyd_client_destroy        vmlinux EXPORT_SYMBOL
+-0xdd4cc94f    v4l2_device_set_name    vmlinux EXPORT_SYMBOL_GPL
+-0x703189d7    regulator_get_mode      vmlinux EXPORT_SYMBOL_GPL
+-0x43028a27    nfc_hci_result_to_errno vmlinux EXPORT_SYMBOL
+-0x0551f0ce    tick_nohz_idle_exit     vmlinux EXPORT_SYMBOL_GPL
+-0xc7208c3a    serial8250_resume_port  vmlinux EXPORT_SYMBOL
+-0xe91355f8    inet_csk_clone_lock     vmlinux EXPORT_SYMBOL_GPL
+-0xe912da6b    unregister_sysctl_table vmlinux EXPORT_SYMBOL
+-0xaf91d89f    __kernel_param_lock     vmlinux EXPORT_SYMBOL
+-0x31cdd70c    hid_input_report        vmlinux EXPORT_SYMBOL_GPL
+-0xd73ee981    cdc_ncm_fill_tx_frame   vmlinux EXPORT_SYMBOL_GPL
+-0xa01c6bfd    del_gendisk     vmlinux EXPORT_SYMBOL
+-0x4d74d134    block_write_full_page   vmlinux EXPORT_SYMBOL
+-0x43632d7d    of_find_property        vmlinux EXPORT_SYMBOL
+-0xa76550fa    xfrm_register_type      vmlinux EXPORT_SYMBOL
+-0xde08bdaf    nf_ct_invert_tuple      vmlinux EXPORT_SYMBOL_GPL
+-0xa61aa028    snd_pcm_format_unsigned vmlinux EXPORT_SYMBOL
+-0x0b51f3e2    fat_sync_inode  vmlinux EXPORT_SYMBOL_GPL
+-0xb3e441b1    clear_bdi_congested     vmlinux EXPORT_SYMBOL
+-0x9305f8e6    cpufreq_get     vmlinux EXPORT_SYMBOL
+-0x8708f581    usbnet_stop     vmlinux EXPORT_SYMBOL_GPL
+-0x581e0fb1    sock_no_setsockopt      vmlinux EXPORT_SYMBOL
+-0xdf40231d    sock_no_getsockopt      vmlinux EXPORT_SYMBOL
+-0xa3355ffa    snd_soc_default_writable_register       vmlinux EXPORT_SYMBOL_GPL
+-0xb8ba4a80    __blockdev_direct_IO    vmlinux EXPORT_SYMBOL
+-0x4f70015c    splice_from_pipe_end    vmlinux EXPORT_SYMBOL
+-0x93658a27    migrate_page    vmlinux EXPORT_SYMBOL
+-0x2e45e488    rcu_note_context_switch vmlinux EXPORT_SYMBOL_GPL
+-0xf0d68ed6    clk_register_clkdevs    vmlinux EXPORT_SYMBOL
+-0xec58fd46    ip6_route_me_harder     vmlinux EXPORT_SYMBOL
+-0xccec571a    thermal_zone_device_update      vmlinux EXPORT_SYMBOL_GPL
+-0x011c6bf0    regulator_map_voltage_iterate   vmlinux EXPORT_SYMBOL_GPL
+-0x44eabd85    km_new_mapping  vmlinux EXPORT_SYMBOL
+-0x4469fe89    lro_receive_skb vmlinux EXPORT_SYMBOL
+-0x6d54f969    napi_complete   vmlinux EXPORT_SYMBOL
+-0xb740018f    snd_device_new  vmlinux EXPORT_SYMBOL
+-0xab363caa    generic_block_bmap      vmlinux EXPORT_SYMBOL
+-0x868784cb    __symbol_get    vmlinux EXPORT_SYMBOL_GPL
+-0x142a8be4    of_clk_get_parent_name  vmlinux EXPORT_SYMBOL_GPL
+-0x991484c4    of_property_count_strings       vmlinux EXPORT_SYMBOL_GPL
+-0x5f3c8f5c    mmc_assume_removable    vmlinux EXPORT_SYMBOL
+-0xf9c1f53f    pm_generic_thaw_early   vmlinux EXPORT_SYMBOL_GPL
+-0x47229b5c    gpio_request    vmlinux EXPORT_SYMBOL_GPL
+-0x517deb22    __ip_dev_find   vmlinux EXPORT_SYMBOL
+-0x815fe221    snd_pcm_hw_constraint_list      vmlinux EXPORT_SYMBOL
+-0xbe0e5118    nla_memcmp      vmlinux EXPORT_SYMBOL
+-0xf1db1704    nla_memcpy      vmlinux EXPORT_SYMBOL
+-0x1f77b093    file_remove_suid        vmlinux EXPORT_SYMBOL
+-0xfd6794fe    d_materialise_unique    vmlinux EXPORT_SYMBOL_GPL
+-0x26622a2b    kmem_cache_free vmlinux EXPORT_SYMBOL
+-0x7aab19fb    vb2_ops_wait_prepare    vmlinux EXPORT_SYMBOL_GPL
+-0x5d22b406    rndis_register  vmlinux EXPORT_SYMBOL
+-0xd25dc9c5    cdc_ncm_rx_verify_nth16 vmlinux EXPORT_SYMBOL_GPL
+-0x8299a21a    ieee80211_data_from_8023        vmlinux EXPORT_SYMBOL
+-0x499cb58c    prepare_to_wait vmlinux EXPORT_SYMBOL
+-0xadf42bd5    __request_region        vmlinux EXPORT_SYMBOL
+-0x9f560253    get_cpu_device  vmlinux EXPORT_SYMBOL_GPL
+-0x923b1276    dmaengine_get   vmlinux EXPORT_SYMBOL
+-0x56d9b1de    amba_device_register    vmlinux EXPORT_SYMBOL
+-0x6fa16209    bdev_read_only  vmlinux EXPORT_SYMBOL
+-0xf0009fee    put_pages_list  vmlinux EXPORT_SYMBOL
+-0xdf73013e    from_kprojid    vmlinux EXPORT_SYMBOL
+-0x2609451c    sock_wfree      vmlinux EXPORT_SYMBOL
+-0x0de80eba    snd_soc_info_volsw      vmlinux EXPORT_SYMBOL_GPL
+-0xd7f77051    test_set_page_writeback vmlinux EXPORT_SYMBOL
+-0xa734a3e9    abort_exclusive_wait    vmlinux EXPORT_SYMBOL
+-0x091eb9b4    round_jiffies   vmlinux EXPORT_SYMBOL_GPL
+-0x99429b47    display_entity_unregister       vmlinux EXPORT_SYMBOL_GPL
+-0x40d0b751    qdisc_destroy   vmlinux EXPORT_SYMBOL
+-0x16445cb3    inet_proto_csum_replace16       vmlinux EXPORT_SYMBOL
+-0x5594be03    bitmap_remap    vmlinux EXPORT_SYMBOL
+-0x7fe04a49    truncate_inode_pages    vmlinux EXPORT_SYMBOL
+-0x42f865b4    fb_videomode_from_videomode     vmlinux EXPORT_SYMBOL_GPL
+-0x0422fe4a    inet_csk_timer_bug_msg  vmlinux EXPORT_SYMBOL
+-0x1b0c9510    sysfs_notify    vmlinux EXPORT_SYMBOL_GPL
+-0x0948cde9    num_physpages   vmlinux EXPORT_SYMBOL
+-0x7818fe23    input_flush_device      vmlinux EXPORT_SYMBOL
+-0x2da17677    regmap_bulk_write       vmlinux EXPORT_SYMBOL_GPL
+-0x03ba39b0    v7_flush_user_cache_all vmlinux EXPORT_SYMBOL
+-0x9d0403b2    inet_hash       vmlinux EXPORT_SYMBOL_GPL
+-0x9a1dfd65    strpbrk vmlinux EXPORT_SYMBOL
+-0xa040153b    sysfs_create_file       vmlinux EXPORT_SYMBOL_GPL
+-0x99cbae17    seq_lseek       vmlinux EXPORT_SYMBOL
+-0x092c2a7a    irq_domain_add_tree     vmlinux EXPORT_SYMBOL_GPL
+-0x23a42148    media_entity_pipeline_stop      vmlinux EXPORT_SYMBOL_GPL
+-0xd87b6687    ip6_frag_match  vmlinux EXPORT_SYMBOL
+-0x9e6d79f8    snd_info_get_str        vmlinux EXPORT_SYMBOL
+-0x1551dc51    bitmap_find_free_region vmlinux EXPORT_SYMBOL
+-0x9f491e5d    ftrace_print_symbols_seq_u64    vmlinux EXPORT_SYMBOL
+-0x9b6bedb6    sdhci_add_host  vmlinux EXPORT_SYMBOL_GPL
+-0x928f84b5    drm_crtc_init   vmlinux EXPORT_SYMBOL
+-0x56b63670    lzo1x_1_compress        vmlinux EXPORT_SYMBOL_GPL
+-0x637d3d6a    set_disk_ro     vmlinux EXPORT_SYMBOL
+-0x5053e2a6    leds_list_lock  vmlinux EXPORT_SYMBOL_GPL
+-0x19fc7f60    regulator_set_mode      vmlinux EXPORT_SYMBOL_GPL
+-0x7e703a3d    snd_soc_limit_volume    vmlinux EXPORT_SYMBOL_GPL
+-0x3bdbf275    sg_alloc_table_from_pages       vmlinux EXPORT_SYMBOL
+-0xb87bf605    blk_rq_unprep_clone     vmlinux EXPORT_SYMBOL_GPL
+-0xe04f7caa    dm_read_arg_group       vmlinux EXPORT_SYMBOL
+-0xb26725f8    bus_find_device vmlinux EXPORT_SYMBOL_GPL
+-0x7ff32312    drm_gem_handle_create   vmlinux EXPORT_SYMBOL
+-0xcd7edbe9    cfg80211_sched_scan_results     vmlinux EXPORT_SYMBOL
+-0x92dbc6c1    xfrm_aalg_get_byid      vmlinux EXPORT_SYMBOL_GPL
+-0x6fb14f17    tcp_create_openreq_child        vmlinux EXPORT_SYMBOL
+-0x2f368d4c    sk_common_release       vmlinux EXPORT_SYMBOL
+-0xd60281a9    st_sensors_set_fullscale_by_gain        vmlinux EXPORT_SYMBOL
+-0x228bec81    led_trigger_register    vmlinux EXPORT_SYMBOL_GPL
+-0x28c52e3f    video_device_release    vmlinux EXPORT_SYMBOL
+-0x3faac56f    drm_mode_set_config_internal    vmlinux EXPORT_SYMBOL
+-0xf86d3493    skb_queue_head  vmlinux EXPORT_SYMBOL
+-0x5fd1e756    skb_prepare_seq_read    vmlinux EXPORT_SYMBOL
+-0x02ff8c3e    sk_reset_timer  vmlinux EXPORT_SYMBOL
+-0xb08f47ec    snd_soc_resume  vmlinux EXPORT_SYMBOL_GPL
+-0x0f055dad    snd_pcm_hw_rule_noresample      vmlinux EXPORT_SYMBOL
+-0x9529f10a    fuse_conn_put   vmlinux EXPORT_SYMBOL_GPL
+-0xf6bb8bf1    irq_get_irq_data        vmlinux EXPORT_SYMBOL_GPL
+-0x02c3c736    v4l2_subdev_querymenu   vmlinux EXPORT_SYMBOL
+-0xfb42deb3    drm_helper_mode_fill_fb_struct  vmlinux EXPORT_SYMBOL
+-0x4920a692    regulator_bulk_enable   vmlinux EXPORT_SYMBOL_GPL
+-0x85963907    netdev_has_upper_dev    vmlinux EXPORT_SYMBOL
+-0x5f58f676    flex_array_get_ptr      vmlinux EXPORT_SYMBOL
+-0x3e6c012e    bio_alloc_bioset        vmlinux EXPORT_SYMBOL
+-0xb9ac0503    mali_set_user_setting   vmlinux EXPORT_SYMBOL
+-0xbd22a332    drm_pci_free    vmlinux EXPORT_SYMBOL
+-0x171addd2    ieee80211_get_hdrlen_from_skb   vmlinux EXPORT_SYMBOL
+-0xe41115b7    vfs_cancel_lock vmlinux EXPORT_SYMBOL_GPL
+-0x912c123d    pm_qos_remove_request   vmlinux EXPORT_SYMBOL_GPL
+-0x8e2d17cc    v4l2_clk_enable vmlinux EXPORT_SYMBOL
+-0xfe3150df    usb_driver_set_configuration    vmlinux EXPORT_SYMBOL_GPL
+-0x3b5bb4f2    mii_ethtool_sset        vmlinux EXPORT_SYMBOL
+-0xe9bc24c2    mii_ethtool_gset        vmlinux EXPORT_SYMBOL
+-0x62e1f48d    class_compat_create_link        vmlinux EXPORT_SYMBOL_GPL
+-0xb602c57e    nf_ct_l3proto_module_put        vmlinux EXPORT_SYMBOL_GPL
+-0xcd4b940c    release_sock    vmlinux EXPORT_SYMBOL
+-0x90e5450f    textsearch_destroy      vmlinux EXPORT_SYMBOL
+-0x50e7193a    __i2c_first_dynamic_bus_num     vmlinux EXPORT_SYMBOL_GPL
+-0xa2a8e81f    class_remove_file       vmlinux EXPORT_SYMBOL_GPL
+-0x95f56edb    drm_i2c_encoder_init    vmlinux EXPORT_SYMBOL
+-0xdd1dd3a7    snd_pcm_hw_constraint_msbits    vmlinux EXPORT_SYMBOL
+-0x23a574fd    security_secmark_relabel_packet vmlinux EXPORT_SYMBOL
+-0x3f01eca9    unmap_underlying_metadata       vmlinux EXPORT_SYMBOL
+-0x55feec9e    sync_inode      vmlinux EXPORT_SYMBOL
+-0xb859f38b    krealloc        vmlinux EXPORT_SYMBOL
+-0x9af5fc30    of_phy_connect_fixed_link       vmlinux EXPORT_SYMBOL
+-0xa2307653    v4l2_device_register_subdev_nodes       vmlinux EXPORT_SYMBOL_GPL
+-0x66e9dc03    usbnet_status_stop      vmlinux EXPORT_SYMBOL_GPL
+-0x419a9395    snd_card_create vmlinux EXPORT_SYMBOL
+-0x9edc4cdb    __invalidate_device     vmlinux EXPORT_SYMBOL
+-0x301fa826    seq_put_decimal_ull     vmlinux EXPORT_SYMBOL
+-0x8f7b5061    jack_event_handler      vmlinux EXPORT_SYMBOL_GPL
+-0xf8e6aed1    input_register_device   vmlinux EXPORT_SYMBOL
+-0xfba9b108    drm_fb_helper_fini      vmlinux EXPORT_SYMBOL
+-0x31266931    con_debug_leave vmlinux EXPORT_SYMBOL_GPL
+-0x2ba707a8    sysctl_tcp_low_latency  vmlinux EXPORT_SYMBOL
+-0x1163f0a7    blk_max_low_pfn vmlinux EXPORT_SYMBOL
+-0x94c6b808    blk_queue_free_tags     vmlinux EXPORT_SYMBOL
+-0xe0413655    elv_unregister_queue    vmlinux EXPORT_SYMBOL
+-0x3fab3ca9    register_sysctl_table   vmlinux EXPORT_SYMBOL
+-0x67b78eb3    seq_hlist_next_rcu      vmlinux EXPORT_SYMBOL
+-0x571767e3    led_classdev_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x9323826a    ipv4_redirect   vmlinux EXPORT_SYMBOL_GPL
+-0x495c96f8    posix_acl_init  vmlinux EXPORT_SYMBOL
+-0xd59c42a1    drm_idlelock_release    vmlinux EXPORT_SYMBOL
+-0x490355ba    tty_flip_buffer_push    vmlinux EXPORT_SYMBOL
+-0x3ef6c408    bio_copy_data   vmlinux EXPORT_SYMBOL
+-0x6fe3d8cf    ktime_add_safe  vmlinux EXPORT_SYMBOL_GPL
+-0xf9a482f9    msleep  vmlinux EXPORT_SYMBOL
+-0xc66b77b1    iommu_group_set_iommudata       vmlinux EXPORT_SYMBOL_GPL
+-0xd55ad93b    iommu_group_get_iommudata       vmlinux EXPORT_SYMBOL_GPL
+-0x0d0549e1    hidinput_calc_abs_res   vmlinux EXPORT_SYMBOL_GPL
+-0x07608656    uart_get_divisor        vmlinux EXPORT_SYMBOL
+-0xc8f72480    unregister_netdev       vmlinux EXPORT_SYMBOL
+-0x1ce42553    __bforget       vmlinux EXPORT_SYMBOL
+-0x8427e5bd    v4l2_event_subdev_unsubscribe   vmlinux EXPORT_SYMBOL_GPL
+-0x8e865d3c    arm_delay_ops   vmlinux EXPORT_SYMBOL
+-0x2f88c16b    inet6_add_protocol      vmlinux EXPORT_SYMBOL
+-0x9fda569e    raw_unhash_sk   vmlinux EXPORT_SYMBOL_GPL
+-0x1def6812    xt_register_table       vmlinux EXPORT_SYMBOL_GPL
+-0xe7e87d7a    set_h225_addr_hook      vmlinux EXPORT_SYMBOL_GPL
+-0xd2037371    sock_no_listen  vmlinux EXPORT_SYMBOL
+-0x33607e14    snd_soc_poweroff        vmlinux EXPORT_SYMBOL_GPL
+-0xab600421    probe_irq_off   vmlinux EXPORT_SYMBOL
+-0xfc8ace2f    input_mt_destroy_slots  vmlinux EXPORT_SYMBOL
+-0xf222f80f    usb_unpoison_anchored_urbs      vmlinux EXPORT_SYMBOL_GPL
+-0x4845cdbc    scsi_device_lookup_by_target    vmlinux EXPORT_SYMBOL
+-0x79aa04a2    get_random_bytes        vmlinux EXPORT_SYMBOL
+-0x9db44776    nfc_hci_connect_gate    vmlinux EXPORT_SYMBOL
+-0x4d2726f3    tcf_exts_destroy        vmlinux EXPORT_SYMBOL
+-0xbaa8249a    snd_ctl_activate_id     vmlinux EXPORT_SYMBOL_GPL
+-0x55ef85b4    blk_peek_request        vmlinux EXPORT_SYMBOL
+-0xc8b267ae    seq_vprintf     vmlinux EXPORT_SYMBOL
+-0xe6504df3    sdhci_get_of_property   vmlinux EXPORT_SYMBOL_GPL
+-0x3ad12077    regcache_sync_region    vmlinux EXPORT_SYMBOL_GPL
+-0x80af255f    pm_runtime_allow        vmlinux EXPORT_SYMBOL_GPL
+-0x16105b8e    do_unbind_con_driver    vmlinux EXPORT_SYMBOL_GPL
+-0xdaf4dfb3    fb_mode_option  vmlinux EXPORT_SYMBOL_GPL
+-0x1f5dd478    tcf_hash_lookup vmlinux EXPORT_SYMBOL
+-0x14965155    sock_no_poll    vmlinux EXPORT_SYMBOL
+-0xfcbe775e    blk_rq_prep_clone       vmlinux EXPORT_SYMBOL_GPL
+-0x53e6cd86    crypto_alloc_shash      vmlinux EXPORT_SYMBOL_GPL
+-0x93f84c0c    crypto_alloc_ahash      vmlinux EXPORT_SYMBOL_GPL
+-0xae1d4afd    sdio_unregister_driver  vmlinux EXPORT_SYMBOL_GPL
+-0x1b50682a    drm_mode_connector_attach_encoder       vmlinux EXPORT_SYMBOL
+-0x78bed30e    regulator_get   vmlinux EXPORT_SYMBOL_GPL
+-0xae4e6d07    inet6_register_icmp_sender      vmlinux EXPORT_SYMBOL
+-0xcd67300d    vlan_ioctl_set  vmlinux EXPORT_SYMBOL
+-0x4d9b6d35    snd_pcm_format_size     vmlinux EXPORT_SYMBOL
+-0xc11d8093    iov_shorten     vmlinux EXPORT_SYMBOL
+-0x6a037cf1    mempool_kfree   vmlinux EXPORT_SYMBOL
+-0x0cebb5a5    __ww_mutex_lock vmlinux EXPORT_SYMBOL
+-0x430e5257    of_alias_get_id vmlinux EXPORT_SYMBOL_GPL
+-0x5d9260a1    v4l2_ctrl_activate      vmlinux EXPORT_SYMBOL
+-0x17622c01    display_entity_set_state        vmlinux EXPORT_SYMBOL_GPL
+-0x26adb815    thread_notify_head      vmlinux EXPORT_SYMBOL_GPL
+-0xf0ef15b4    list_sort       vmlinux EXPORT_SYMBOL
+-0x958974d4    remove_arg_zero vmlinux EXPORT_SYMBOL
+-0x7b5c8440    vm_munmap       vmlinux EXPORT_SYMBOL
+-0x46178343    remap_pfn_range vmlinux EXPORT_SYMBOL
+-0x46608fa0    getnstimeofday  vmlinux EXPORT_SYMBOL
+-0x51a049e1    scsi_scan_target        vmlinux EXPORT_SYMBOL
+-0x61b31a8a    subsys_dev_iter_init    vmlinux EXPORT_SYMBOL_GPL
+-0x054aade6    subsys_dev_iter_exit    vmlinux EXPORT_SYMBOL_GPL
+-0x4099164a    skcipher_geniv_exit     vmlinux EXPORT_SYMBOL_GPL
+-0x9c144793    file_update_time        vmlinux EXPORT_SYMBOL
+-0x8a162c7d    bdi_unregister  vmlinux EXPORT_SYMBOL
+-0x755d68eb    iio_enum_read   vmlinux EXPORT_SYMBOL_GPL
+-0x03e593b9    vb2_wait_for_all_buffers        vmlinux EXPORT_SYMBOL_GPL
+-0xc06a30a4    phy_register_fixup      vmlinux EXPORT_SYMBOL
+-0x3c308a26    device_bind_driver      vmlinux EXPORT_SYMBOL_GPL
+-0x55010072    device_store_ulong      vmlinux EXPORT_SYMBOL_GPL
+-0x0b405d40    inet6_csk_search_req    vmlinux EXPORT_SYMBOL_GPL
+-0x7a1acc62    dev_mc_init     vmlinux EXPORT_SYMBOL
+-0x93fcc9bd    dev_uc_init     vmlinux EXPORT_SYMBOL
+-0x865029ac    __hw_addr_sync  vmlinux EXPORT_SYMBOL
+-0xb04359d9    snd_soc_bytes_info      vmlinux EXPORT_SYMBOL_GPL
+-0x11a13e31    _kstrtol        vmlinux EXPORT_SYMBOL
+-0x6e73746d    kobject_uevent_env      vmlinux EXPORT_SYMBOL_GPL
+-0x7d830ea5    mb_cache_entry_alloc    vmlinux EXPORT_SYMBOL
+-0xd702e480    _raw_read_unlock        vmlinux EXPORT_SYMBOL
+-0xfa2bcf10    init_timer_key  vmlinux EXPORT_SYMBOL
+-0xe03525ac    of_irq_map_raw  vmlinux EXPORT_SYMBOL_GPL
+-0xb39171d5    cdc_ncm_select_altsetting       vmlinux EXPORT_SYMBOL_GPL
+-0xec52c42e    scsi_setup_blk_pc_cmnd  vmlinux EXPORT_SYMBOL
+-0x337cce46    put_cmsg        vmlinux EXPORT_SYMBOL
+-0x655656dc    skb_free_datagram       vmlinux EXPORT_SYMBOL
+-0x2ad0e68c    sound_class     vmlinux EXPORT_SYMBOL
+-0x7a98596c    filp_close      vmlinux EXPORT_SYMBOL
+-0x4c39b01b    truncate_setsize        vmlinux EXPORT_SYMBOL
+-0xfd5683b9    wait_for_completion_interruptible       vmlinux EXPORT_SYMBOL
+-0xfc38a837    extcon_update_state     vmlinux EXPORT_SYMBOL_GPL
+-0xdba80fc1    of_fdt_unflatten_tree   vmlinux EXPORT_SYMBOL_GPL
+-0x3be54580    generic_readlink        vmlinux EXPORT_SYMBOL
+-0x6cee2e42    drm_object_property_get_value   vmlinux EXPORT_SYMBOL
+-0x67b27ec1    tty_std_termios vmlinux EXPORT_SYMBOL
+-0x4298b775    v7_flush_kern_cache_all vmlinux EXPORT_SYMBOL
+-0x66ac9af0    ether_setup     vmlinux EXPORT_SYMBOL
+-0xafb2d50e    __break_lease   vmlinux EXPORT_SYMBOL
+-0x9e6500de    get_task_comm   vmlinux EXPORT_SYMBOL_GPL
+-0xd5df9165    __get_vm_area   vmlinux EXPORT_SYMBOL_GPL
+-0x6b7589f4    param_set_bool  vmlinux EXPORT_SYMBOL
+-0xbfc407b4    param_ops_bint  vmlinux EXPORT_SYMBOL
+-0xadb5559d    param_ops_byte  vmlinux EXPORT_SYMBOL
+-0xd2a3a2e7    usb_deregister_device_driver    vmlinux EXPORT_SYMBOL_GPL
+-0x0264e273    usbnet_nway_reset       vmlinux EXPORT_SYMBOL_GPL
+-0xbc31af43    device_create_file      vmlinux EXPORT_SYMBOL_GPL
+-0x34bb0082    snd_soc_dapm_put_volsw  vmlinux EXPORT_SYMBOL_GPL
+-0xcec0e354    snd_soc_dapm_get_volsw  vmlinux EXPORT_SYMBOL_GPL
+-0xa3d6bc8a    would_dump      vmlinux EXPORT_SYMBOL
+-0x782cd0c9    truncate_inode_pages_range      vmlinux EXPORT_SYMBOL
+-0xefc7de8e    force_sig       vmlinux EXPORT_SYMBOL
+-0xb3b30554    fimc_find_remote_sensor vmlinux EXPORT_SYMBOL
+-0xf3be20f4    v4l2_m2m_querybuf       vmlinux EXPORT_SYMBOL_GPL
+-0x0fccafb1    drm_global_item_unref   vmlinux EXPORT_SYMBOL
+-0xe8d24f74    arm_coherent_dma_ops    vmlinux EXPORT_SYMBOL
+-0x05240ee7    percpu_counter_batch    vmlinux EXPORT_SYMBOL
+-0x5d75cd76    d_path  vmlinux EXPORT_SYMBOL
+-0x495426ee    v4l2_ctrl_get_name      vmlinux EXPORT_SYMBOL
+-0x6e89a560    regmap_irq_chip_get_base        vmlinux EXPORT_SYMBOL_GPL
+-0x587616f1    vfs_fstatat     vmlinux EXPORT_SYMBOL
+-0x162ccc0c    lg_local_lock   vmlinux EXPORT_SYMBOL
+-0x498225b6    v4l2_m2m_expbuf vmlinux EXPORT_SYMBOL_GPL
+-0x21b2c1ab    __pm_genpd_remove_callbacks     vmlinux EXPORT_SYMBOL_GPL
+-0x1516aa21    brcmf_sdio_probe        drivers/net/wireless/brcm80211/brcmfmac/brcmfmac        EXPORT_SYMBOL
+-0x36c61868    hci_free_dev    vmlinux EXPORT_SYMBOL
+-0xcfa46265    igrab   vmlinux EXPORT_SYMBOL
+-0x36150611    iio_validate_scan_mask_onehot   vmlinux EXPORT_SYMBOL_GPL
+-0x01ac01fc    usbnet_resume   vmlinux EXPORT_SYMBOL_GPL
+-0x43421b4f    sdev_evt_send   vmlinux EXPORT_SYMBOL_GPL
+-0x1fdcc615    rtnl_notify     vmlinux EXPORT_SYMBOL
+-0xe4ad075c    __rtnl_link_register    vmlinux EXPORT_SYMBOL_GPL
+-0x41366c3b    sock_recvmsg    vmlinux EXPORT_SYMBOL
+-0x3468cb4a    snd_soc_set_runtime_hwparams    vmlinux EXPORT_SYMBOL_GPL
+-0x308e4695    snd_pcm_open_substream  vmlinux EXPORT_SYMBOL
+-0x2ef9dbdc    blk_end_request_err     vmlinux EXPORT_SYMBOL_GPL
+-0x9b11d9bf    blk_end_request_all     vmlinux EXPORT_SYMBOL
+-0x2f5bf998    blk_queue_bio   vmlinux EXPORT_SYMBOL_GPL
+-0xd16712f3    crypto_check_attr_type  vmlinux EXPORT_SYMBOL_GPL
+-0x16305289    warn_slowpath_null      vmlinux EXPORT_SYMBOL
+-0xcb0288ea    ledtrig_cpu     vmlinux EXPORT_SYMBOL
+-0xe6431c3b    mmc_can_secure_erase_trim       vmlinux EXPORT_SYMBOL
+-0x916dbe7c    usb_hcd_unmap_urb_for_dma       vmlinux EXPORT_SYMBOL_GPL
+-0x8dc2569e    nf_ct_l3protos  vmlinux EXPORT_SYMBOL_GPL
+-0x1471e34e    linkwatch_fire_event    vmlinux EXPORT_SYMBOL
+-0x56db40e5    snd_device_free vmlinux EXPORT_SYMBOL
+-0xe1b524a3    fs_bio_set      vmlinux EXPORT_SYMBOL
+-0x8d522714    __rcu_read_lock vmlinux EXPORT_SYMBOL_GPL
+-0x4906a967    hid_snto32      vmlinux EXPORT_SYMBOL_GPL
+-0xfbf6bb67    watchdog_init_timeout   vmlinux EXPORT_SYMBOL_GPL
+-0xd37e13b4    regulator_set_optimum_mode      vmlinux EXPORT_SYMBOL_GPL
+-0x4fe1eddf    unregister_netevent_notifier    vmlinux EXPORT_SYMBOL_GPL
+-0x66af941c    snd_soc_debugfs_root    vmlinux EXPORT_SYMBOL_GPL
+-0x42c43759    input_mt_report_slot_state      vmlinux EXPORT_SYMBOL
+-0x8fccb56f    scsi_init_io    vmlinux EXPORT_SYMBOL
+-0x375fce7f    asoc_dma_platform_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0xa58dee99    _raw_write_unlock       vmlinux EXPORT_SYMBOL
+-0x252efd1e    sdhci_remove_host       vmlinux EXPORT_SYMBOL_GPL
+-0xb5128e67    v4l2_i2c_subdev_init    vmlinux EXPORT_SYMBOL_GPL
+-0x6d680e52    v4l2_i2c_subdev_addr    vmlinux EXPORT_SYMBOL_GPL
+-0xb56fc02f    fib_default_rule_pref   vmlinux EXPORT_SYMBOL
+-0x97359c5f    snd_pcm_period_elapsed  vmlinux EXPORT_SYMBOL
+-0x3df477d7    debugfs_create_x8       vmlinux EXPORT_SYMBOL_GPL
+-0x314d3160    kmap_to_page    vmlinux EXPORT_SYMBOL
+-0x8afbf7b1    irq_domain_xlate_onecell        vmlinux EXPORT_SYMBOL_GPL
+-0x6b264960    irq_domain_xlate_twocell        vmlinux EXPORT_SYMBOL_GPL
+-0xee3c209d    cgroup_next_descendant_pre      vmlinux EXPORT_SYMBOL_GPL
+-0x6776c27a    drm_av_sync_delay       vmlinux EXPORT_SYMBOL
+-0x0fe112dc    of_dma_controller_free  vmlinux EXPORT_SYMBOL_GPL
+-0xfccc95e9    pwm_put vmlinux EXPORT_SYMBOL_GPL
+-0xb8a5a2d7    iio_convert_raw_to_processed    vmlinux EXPORT_SYMBOL_GPL
+-0x8f7df3a7    drm_object_attach_property      vmlinux EXPORT_SYMBOL
+-0xd248fe40    uart_write_wakeup       vmlinux EXPORT_SYMBOL
+-0x0483a4c2    skb_append      vmlinux EXPORT_SYMBOL
+-0xb28d7c56    snd_soc_read    vmlinux EXPORT_SYMBOL_GPL
+-0x6f1f9555    read_cache_page_gfp     vmlinux EXPORT_SYMBOL
+-0xe12954af    pwm_can_sleep   vmlinux EXPORT_SYMBOL_GPL
+-0x333147c5    sk_stream_error vmlinux EXPORT_SYMBOL
+-0x37f30c3d    devm_request_and_ioremap        vmlinux EXPORT_SYMBOL
+-0x40d57aa3    audit_log_start vmlinux EXPORT_SYMBOL
+-0x3232306b    need_load_eval  vmlinux EXPORT_SYMBOL_GPL
+-0x27328cec    drm_fb_helper_debug_leave       vmlinux EXPORT_SYMBOL
+-0x2f4df599    arm_iommu_attach_device vmlinux EXPORT_SYMBOL_GPL
+-0x38ec6320    netdev_crit     vmlinux EXPORT_SYMBOL
+-0x7385ebdb    sysfs_create_files      vmlinux EXPORT_SYMBOL_GPL
+-0x0758ff61    sget    vmlinux EXPORT_SYMBOL
+-0xca20d111    v4l2_ctrl_cluster       vmlinux EXPORT_SYMBOL
+-0x5f754e5a    memset  vmlinux EXPORT_SYMBOL
+-0xbd70447e    ip_tunnel_setup vmlinux EXPORT_SYMBOL_GPL
+-0x2541a979    snd_soc_calc_frame_size vmlinux EXPORT_SYMBOL_GPL
+-0xdc3fcbc9    __sw_hweight8   vmlinux EXPORT_SYMBOL
+-0x02ee26c1    free_pages_exact        vmlinux EXPORT_SYMBOL
+-0x885bcec8    tasklet_hrtimer_init    vmlinux EXPORT_SYMBOL_GPL
+-0xe80bbfc6    v4l2_event_pending      vmlinux EXPORT_SYMBOL_GPL
+-0x356cb8d3    debugfs_create_atomic_t vmlinux EXPORT_SYMBOL_GPL
+-0x064db9a5    mark_mounts_for_expiry  vmlinux EXPORT_SYMBOL_GPL
+-0x8b43159b    register_cpu_notifier   vmlinux EXPORT_SYMBOL
+-0xd0d5f859    st_sensors_read_event_config    vmlinux EXPORT_SYMBOL
+-0xba490602    nci_to_errno    vmlinux EXPORT_SYMBOL
+-0x26cae22e    snd_soc_dapm_free       vmlinux EXPORT_SYMBOL_GPL
+-0x6b4f9016    d_set_d_op      vmlinux EXPORT_SYMBOL
+-0x6d340f64    tty_termios_input_baud_rate     vmlinux EXPORT_SYMBOL
+-0x0d3f57a2    _find_next_bit_le       vmlinux EXPORT_SYMBOL
+-0x74e1a843    xfrm_aalg_get_byidx     vmlinux EXPORT_SYMBOL_GPL
+-0x56b147ce    unregister_tcf_proto_ops        vmlinux EXPORT_SYMBOL
+-0xb6936ffe    _bcd2bin        vmlinux EXPORT_SYMBOL
+-0x707f5f40    vb2_fop_write   vmlinux EXPORT_SYMBOL_GPL
+-0x598cd828    udp_table       vmlinux EXPORT_SYMBOL
+-0x7d0e3e72    ida_get_new_above       vmlinux EXPORT_SYMBOL
+-0x2e2f1740    ring_buffer_record_disable_cpu  vmlinux EXPORT_SYMBOL_GPL
+-0xafe38346    mmc_erase_group_aligned vmlinux EXPORT_SYMBOL
+-0x1af8e94b    nla_put vmlinux EXPORT_SYMBOL
+-0xf23fcb99    __kfifo_in      vmlinux EXPORT_SYMBOL
+-0xf8ac3a16    revalidate_disk vmlinux EXPORT_SYMBOL
+-0xca5967e3    vm_stat vmlinux EXPORT_SYMBOL
+-0xd5b1376d    register_shrinker       vmlinux EXPORT_SYMBOL
+-0xa6c3a59e    power_supply_am_i_supplied      vmlinux EXPORT_SYMBOL_GPL
+-0x35aa9322    regcache_mark_dirty     vmlinux EXPORT_SYMBOL_GPL
+-0xbdb14b0b    transport_configure_device      vmlinux EXPORT_SYMBOL_GPL
+-0x391c8c77    drm_bl_register vmlinux EXPORT_SYMBOL_GPL
+-0x2c744386    ip_tunnel_dellink       vmlinux EXPORT_SYMBOL_GPL
+-0xc10022a2    register_sound_dsp      vmlinux EXPORT_SYMBOL
+-0x6d29349e    blk_post_runtime_suspend        vmlinux EXPORT_SYMBOL
+-0x803eda06    block_invalidatepage    vmlinux EXPORT_SYMBOL
+-0x22ba7f9f    may_umount_tree vmlinux EXPORT_SYMBOL
+-0x7a944007    rcu_idle_enter  vmlinux EXPORT_SYMBOL_GPL
+-0x3ce3f899    iio_device_register     vmlinux EXPORT_SYMBOL
+-0x624a6406    hwrng_register  vmlinux EXPORT_SYMBOL_GPL
+-0xa408cd5e    misc_register   vmlinux EXPORT_SYMBOL
+-0x636b12c8    nf_nat_need_gre vmlinux EXPORT_SYMBOL_GPL
+-0xe58ab676    ip_tunnel_init_net      vmlinux EXPORT_SYMBOL_GPL
+-0x38c6e66b    udp_lib_get_port        vmlinux EXPORT_SYMBOL
+-0x7cda3781    ip_route_input_noref    vmlinux EXPORT_SYMBOL
+-0x207ffd0a    kernel_write    vmlinux EXPORT_SYMBOL
+-0xbbabb724    tty_ldisc_ref   vmlinux EXPORT_SYMBOL_GPL
+-0x899a5d37    rtnl_af_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0x1c7f08a9    snd_soc_dapm_del_routes vmlinux EXPORT_SYMBOL_GPL
+-0xe71105e8    iget_failed     vmlinux EXPORT_SYMBOL
+-0x0fc01e9f    static_key_slow_inc     vmlinux EXPORT_SYMBOL_GPL
+-0xbfee3ad5    loop_unregister_transfer        vmlinux EXPORT_SYMBOL
+-0xaaef0fd2    class_dev_iter_exit     vmlinux EXPORT_SYMBOL_GPL
+-0xd2b18e1d    __of_phy_provider_register      vmlinux EXPORT_SYMBOL_GPL
+-0x1751de15    phy_create      vmlinux EXPORT_SYMBOL_GPL
+-0x25c677c4    mac_pton        vmlinux EXPORT_SYMBOL
+-0xc54cd128    filemap_fdatawait_range vmlinux EXPORT_SYMBOL
+-0x05afc379    mmc_cache_ctrl  vmlinux EXPORT_SYMBOL
+-0x814e4cf8    cfg80211_chandef_usable vmlinux EXPORT_SYMBOL
+-0x829865cd    inode_sub_bytes vmlinux EXPORT_SYMBOL
+-0xec602814    inode_set_bytes vmlinux EXPORT_SYMBOL
+-0x47e70229    v7_flush_user_cache_range       vmlinux EXPORT_SYMBOL
+-0x51cb6360    arp_xmit        vmlinux EXPORT_SYMBOL
+-0xc84ab6f8    __dev_getfirstbyhwtype  vmlinux EXPORT_SYMBOL
+-0xd499d564    __dev_get_by_index      vmlinux EXPORT_SYMBOL
+-0x66a67dab    flex_array_shrink       vmlinux EXPORT_SYMBOL
+-0xd41fe818    _raw_read_unlock_irqrestore     vmlinux EXPORT_SYMBOL
+-0x47fdbc4f    v4l2_ctrl_new_std       vmlinux EXPORT_SYMBOL
+-0xb2fe3cab    mdiobus_register        vmlinux EXPORT_SYMBOL
+-0xf70d473a    __inet6_lookup_established      vmlinux EXPORT_SYMBOL
+-0x8187321e    snd_timer_interrupt     vmlinux EXPORT_SYMBOL
+-0xec5d6a71    __nla_put_nohdr vmlinux EXPORT_SYMBOL
+-0xda5506a3    crypto_unregister_instance      vmlinux EXPORT_SYMBOL_GPL
+-0xfd361609    bdi_init        vmlinux EXPORT_SYMBOL
+-0xf8d88cd8    clk_get vmlinux EXPORT_SYMBOL
+-0x22df2dd3    sdio_claim_host vmlinux EXPORT_SYMBOL_GPL
+-0x40973662    sysctl_udp_mem  vmlinux EXPORT_SYMBOL
+-0x3b50ba06    cpufreq_cooling_register        vmlinux EXPORT_SYMBOL_GPL
+-0xb1c29e91    usbnet_probe    vmlinux EXPORT_SYMBOL_GPL
+-0x5e1176a3    nfc_hci_send_cmd        vmlinux EXPORT_SYMBOL
+-0x1bc8ce1b    inet_csk_accept vmlinux EXPORT_SYMBOL
+-0x35cdd9d0    inet_hash_connect       vmlinux EXPORT_SYMBOL_GPL
+-0x0334da4e    scsi_command_size_tbl   vmlinux EXPORT_SYMBOL
+-0xa843805a    get_unused_fd_flags     vmlinux EXPORT_SYMBOL
+-0xb1e25684    __trace_bputs   vmlinux EXPORT_SYMBOL_GPL
+-0xb58dcfa2    synchronize_sched_expedited     vmlinux EXPORT_SYMBOL_GPL
+-0x17cefda4    cpufreq_cooling_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0xc6fca5ad    v4l2_m2m_release        vmlinux EXPORT_SYMBOL_GPL
+-0x0614dd5a    v4l2_video_std_frame_period     vmlinux EXPORT_SYMBOL
+-0x08195a4e    generic_mii_ioctl       vmlinux EXPORT_SYMBOL
+-0xe64e4a5b    drm_select_eld  vmlinux EXPORT_SYMBOL
+-0xa3b4f14d    bt_accept_dequeue       vmlinux EXPORT_SYMBOL
+-0x8e20620c    tcf_unregister_action   vmlinux EXPORT_SYMBOL
+-0x52026cdf    security_sb_parse_opts_str      vmlinux EXPORT_SYMBOL
+-0xe82c33bd    usb_bulk_msg    vmlinux EXPORT_SYMBOL_GPL
+-0x876abdb2    xfrm_state_delete_tunnel        vmlinux EXPORT_SYMBOL
+-0xfdb4778c    sock_edemux     vmlinux EXPORT_SYMBOL
+-0x4688d7ec    pvclock_gtod_unregister_notifier        vmlinux EXPORT_SYMBOL_GPL
+-0xc6b72634    gserial_connect vmlinux EXPORT_SYMBOL_GPL
+-0x55046eb2    platform_device_add_resources   vmlinux EXPORT_SYMBOL_GPL
+-0x1b25d2b3    of_pwm_xlate_with_flags vmlinux EXPORT_SYMBOL_GPL
+-0x6e1ba077    in6_dev_finish_destroy  vmlinux EXPORT_SYMBOL
+-0xecd68a44    tcp_gro_receive vmlinux EXPORT_SYMBOL
+-0x922e5568    eth_header      vmlinux EXPORT_SYMBOL
+-0xf82ec573    rb_prev vmlinux EXPORT_SYMBOL
+-0xfe2f7b7e    jbd2_journal_init_dev   vmlinux EXPORT_SYMBOL
+-0xd4114894    bd_unlink_disk_holder   vmlinux EXPORT_SYMBOL_GPL
+-0xa9e18049    task_handoff_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x4b5366cf    down_killable   vmlinux EXPORT_SYMBOL
+-0x1129616d    scsi_rescan_device      vmlinux EXPORT_SYMBOL
+-0x9ed554b3    unregister_keyboard_notifier    vmlinux EXPORT_SYMBOL_GPL
+-0x3271e6e4    unregister_framebuffer  vmlinux EXPORT_SYMBOL
+-0x4acb9a7c    napi_gro_receive        vmlinux EXPORT_SYMBOL
+-0x38ed4ee7    netdev_master_upper_dev_get_rcu vmlinux EXPORT_SYMBOL
+-0x5ae87753    debugfs_print_regs32    vmlinux EXPORT_SYMBOL_GPL
+-0xeac5a47a    clk_notifier_register   vmlinux EXPORT_SYMBOL_GPL
+-0xdcc389f7    usb_get_phy     vmlinux EXPORT_SYMBOL_GPL
+-0x5cfbd179    phonet_stream_ops       vmlinux EXPORT_SYMBOL
+-0xd7ea7094    nf_unregister_queue_handler     vmlinux EXPORT_SYMBOL
+-0xa9b804f6    snd_soc_dapm_ignore_suspend     vmlinux EXPORT_SYMBOL_GPL
+-0xb04cf0fe    lg_local_unlock vmlinux EXPORT_SYMBOL
+-0x24eb7e32    leds_list       vmlinux EXPORT_SYMBOL_GPL
+-0xb2f2f502    dev_get_by_flags_rcu    vmlinux EXPORT_SYMBOL
+-0x996bdb64    _kstrtoul       vmlinux EXPORT_SYMBOL
+-0xd6f8cf35    __block_write_begin     vmlinux EXPORT_SYMBOL
+-0x3517383e    register_reboot_notifier        vmlinux EXPORT_SYMBOL
+-0x188a3dfb    timespec_trunc  vmlinux EXPORT_SYMBOL
+-0x7647726c    handle_sysrq    vmlinux EXPORT_SYMBOL
+-0x2a55c54a    l2cap_unregister_user   vmlinux EXPORT_SYMBOL
+-0xdaafc807    tcp_sockets_allocated   vmlinux EXPORT_SYMBOL
+-0x61618241    netlink_alloc_skb       vmlinux EXPORT_SYMBOL_GPL
+-0x883edc99    snd_soc_dapm_weak_routes        vmlinux EXPORT_SYMBOL_GPL
+-0x0b20ad4e    inode_owner_or_capable  vmlinux EXPORT_SYMBOL
+-0x5ddfdc97    generic_pipe_buf_confirm        vmlinux EXPORT_SYMBOL
+-0x27fede28    get_super_thawed        vmlinux EXPORT_SYMBOL
+-0x7ff20102    v4l2_s_ctrl     vmlinux EXPORT_SYMBOL
+-0x9745d638    drm_err vmlinux EXPORT_SYMBOL
+-0x1c1a727a    v4l2_ctrl_subdev_subscribe_event        vmlinux EXPORT_SYMBOL
+-0x157df959    usbnet_tx_timeout       vmlinux EXPORT_SYMBOL_GPL
+-0x33ca0b9d    scsi_device_quiesce     vmlinux EXPORT_SYMBOL
+-0x18a12a47    drm_modeset_unlock_all  vmlinux EXPORT_SYMBOL
+-0x59d29dab    v7_flush_kern_dcache_area       vmlinux EXPORT_SYMBOL
+-0x9ca80cdd    inet6_protos    vmlinux EXPORT_SYMBOL
+-0x58714dc9    snd_soc_jack_add_zones  vmlinux EXPORT_SYMBOL_GPL
+-0xdc9110f5    snd_pcm_hw_param_first  vmlinux EXPORT_SYMBOL
+-0xf184d189    kernel_power_off        vmlinux EXPORT_SYMBOL_GPL
+-0xc8a270a1    usb_put_function        vmlinux EXPORT_SYMBOL_GPL
+-0xdfe8f93c    display_entity_get_size vmlinux EXPORT_SYMBOL_GPL
+-0x0ef959a5    ip6t_unregister_table   vmlinux EXPORT_SYMBOL
+-0x5ee28af3    genl_register_ops       vmlinux EXPORT_SYMBOL
+-0xda91a719    snd_pcm_new     vmlinux EXPORT_SYMBOL
+-0x8731837f    debugfs_create_u64      vmlinux EXPORT_SYMBOL_GPL
+-0x0d350531    block_commit_write      vmlinux EXPORT_SYMBOL
+-0xcb62227b    con_copy_unimap vmlinux EXPORT_SYMBOL
+-0x9b90584e    tty_ldisc_ref_wait      vmlinux EXPORT_SYMBOL_GPL
+-0xf727c5be    __netdev_alloc_skb      vmlinux EXPORT_SYMBOL
+-0xf186dfad    wm_hubs_set_bias_level  vmlinux EXPORT_SYMBOL_GPL
+-0x5bc4fef5    snd_soc_get_dai_substream       vmlinux EXPORT_SYMBOL_GPL
+-0xabefee2b    _snd_pcm_lib_alloc_vmalloc_buffer       vmlinux EXPORT_SYMBOL
+-0x5a116367    perf_event_create_kernel_counter        vmlinux EXPORT_SYMBOL_GPL
+-0x0bfa3a19    rcu_idle_exit   vmlinux EXPORT_SYMBOL_GPL
+-0x90ff6c9f    nf_ct_invert_tuplepr    vmlinux EXPORT_SYMBOL_GPL
+-0xf3cd9688    snd_soc_dapm_sync       vmlinux EXPORT_SYMBOL_GPL
+-0x68fb4f69    locks_delete_block      vmlinux EXPORT_SYMBOL
+-0xdca2a7bb    dput    vmlinux EXPORT_SYMBOL
+-0x67a000fa    try_module_get  vmlinux EXPORT_SYMBOL
+-0x4790cc27    v4l2_s_ext_ctrls        vmlinux EXPORT_SYMBOL
+-0xf39c1176    tty_kref_put    vmlinux EXPORT_SYMBOL
+-0x56310925    regulator_mode_to_status        vmlinux EXPORT_SYMBOL_GPL
+-0x0825a4fe    regulator_list_voltage_linear   vmlinux EXPORT_SYMBOL_GPL
+-0x43db92ba    fb_set_suspend  vmlinux EXPORT_SYMBOL
+-0x4993cc2b    register_net_sysctl     vmlinux EXPORT_SYMBOL_GPL
+-0x8a490c90    rfkill_set_sw_state     vmlinux EXPORT_SYMBOL
+-0xaae97496    snd_soc_bulk_write_raw  vmlinux EXPORT_SYMBOL_GPL
+-0xb4dd257b    srcu_notifier_call_chain        vmlinux EXPORT_SYMBOL_GPL
+-0x4403ead3    usb_match_one_id        vmlinux EXPORT_SYMBOL_GPL
+-0x829a0b6c    screen_glyph    vmlinux EXPORT_SYMBOL_GPL
+-0xf7802486    __aeabi_uidivmod        vmlinux EXPORT_SYMBOL
+-0x4b8f110e    sk_free vmlinux EXPORT_SYMBOL
+-0x4fbbaedb    snd_soc_free_ac97_codec vmlinux EXPORT_SYMBOL_GPL
+-0xfd5566cf    scsi_is_sdev_device     vmlinux EXPORT_SYMBOL
+-0x17dc8b68    drm_vblank_pre_modeset  vmlinux EXPORT_SYMBOL
+-0x7ef39823    ieee80211_hdrlen        vmlinux EXPORT_SYMBOL
+-0xc8f36b20    kobject_init    vmlinux EXPORT_SYMBOL
+-0xb2e764e8    suspend_valid_only_mem  vmlinux EXPORT_SYMBOL_GPL
+-0xfaf9995e    sleep_on        vmlinux EXPORT_SYMBOL
+-0x42160169    flush_workqueue vmlinux EXPORT_SYMBOL_GPL
+-0xf3251e7b    v4l2_norm_to_name       vmlinux EXPORT_SYMBOL
+-0xd7b664df    regulator_list_voltage_table    vmlinux EXPORT_SYMBOL_GPL
+-0xfe13b82a    snd_soc_info_enum_ext   vmlinux EXPORT_SYMBOL_GPL
+-0x22a8b63d    bio_flush_dcache_pages  vmlinux EXPORT_SYMBOL
+-0x0c3d1edb    simple_lookup   vmlinux EXPORT_SYMBOL
+-0x4cbc159a    gether_set_dev_addr     vmlinux EXPORT_SYMBOL
+-0xdac8e102    gether_get_dev_addr     vmlinux EXPORT_SYMBOL
+-0xfa599bb2    netlink_register_notifier       vmlinux EXPORT_SYMBOL
+-0xb7e5c788    cgroup_next_descendant_post     vmlinux EXPORT_SYMBOL_GPL
+-0xd7dc295c    dm_io   vmlinux EXPORT_SYMBOL
+-0xb8698990    usb_match_id    vmlinux EXPORT_SYMBOL_GPL
+-0x91a5dbd2    drm_idlelock_take       vmlinux EXPORT_SYMBOL
+-0xba86f941    xfrm_policy_insert      vmlinux EXPORT_SYMBOL
+-0x2519a629    skb_segment     vmlinux EXPORT_SYMBOL_GPL
+-0x2f574814    blk_queue_max_segments  vmlinux EXPORT_SYMBOL
+-0xa17232f2    bio_clone_bioset        vmlinux EXPORT_SYMBOL
+-0xba2bc8de    unlock_rename   vmlinux EXPORT_SYMBOL
+-0x9820b644    warn_slowpath_fmt_taint vmlinux EXPORT_SYMBOL
+-0x184b82fb    mmc_vddrange_to_ocrmask vmlinux EXPORT_SYMBOL
+-0x0a67ddd9    dm_suspended    vmlinux EXPORT_SYMBOL_GPL
+-0xfc8bcbaf    usb_add_hcd     vmlinux EXPORT_SYMBOL_GPL
+-0x965d4e18    tcp_init_congestion_ops vmlinux EXPORT_SYMBOL_GPL
+-0xe587559a    skb_push        vmlinux EXPORT_SYMBOL
+-0x1a32c5c7    blk_run_queue_async     vmlinux EXPORT_SYMBOL
+-0x7fa439cd    simple_rmdir    vmlinux EXPORT_SYMBOL
+-0xe6790d49    alloc_file      vmlinux EXPORT_SYMBOL
+-0xe8214f7a    free_task       vmlinux EXPORT_SYMBOL
+-0x2b9e3380    samsung_dmadev_get_ops  vmlinux EXPORT_SYMBOL
+-0x8e671fe0    sdio_f0_writeb  vmlinux EXPORT_SYMBOL_GPL
+-0x919b5fa4    device_create   vmlinux EXPORT_SYMBOL_GPL
+-0x5cf4fc85    psched_ratecfg_precompute       vmlinux EXPORT_SYMBOL
+-0x96573b80    __kfifo_dma_in_finish_r vmlinux EXPORT_SYMBOL
+-0xf520f285    sysfs_get       vmlinux EXPORT_SYMBOL_GPL
+-0x543ef284    seq_hlist_start vmlinux EXPORT_SYMBOL
+-0xbfffc4e0    vb2_read        vmlinux EXPORT_SYMBOL_GPL
+-0x45f39483    i2c_del_adapter vmlinux EXPORT_SYMBOL
+-0x5838f6c9    rtc_valid_tm    vmlinux EXPORT_SYMBOL
+-0xb7a638f3    usb_register_driver     vmlinux EXPORT_SYMBOL_GPL
+-0xb83a9297    scsi_block_requests     vmlinux EXPORT_SYMBOL
+-0xd5d8b6b8    drm_dp_get_adjust_request_pre_emphasis  vmlinux EXPORT_SYMBOL
+-0x99c95fa5    unregister_sound_special        vmlinux EXPORT_SYMBOL
+-0x056b6c53    fat_dir_empty   vmlinux EXPORT_SYMBOL_GPL
+-0xb51c8891    __getblk        vmlinux EXPORT_SYMBOL
+-0x1d9658d5    cdev_alloc      vmlinux EXPORT_SYMBOL
+-0x1dd73224    st_sensors_i2c_configure        vmlinux EXPORT_SYMBOL
+-0x22379ca8    led_blink_set_oneshot   vmlinux EXPORT_SYMBOL
+-0xe7e76d97    mmc_release_host        vmlinux EXPORT_SYMBOL
+-0x6e04a077    usb_bind_phy    vmlinux EXPORT_SYMBOL_GPL
+-0x47d9cfba    sdev_disable_disk_events        vmlinux EXPORT_SYMBOL
+-0x142b8b35    drm_buffer_copy_from_user       vmlinux EXPORT_SYMBOL
+-0x55f04c21    trace_buffer_unlock_commit_regs vmlinux EXPORT_SYMBOL_GPL
+-0x8c333b2b    usb_hcd_unlink_urb_from_ep      vmlinux EXPORT_SYMBOL_GPL
+-0x1fa2251f    device_wakeup_enable    vmlinux EXPORT_SYMBOL_GPL
+-0xbbe4496d    dev_warn        vmlinux EXPORT_SYMBOL
+-0xab3d1f95    nf_ct_untracked_status_or       vmlinux EXPORT_SYMBOL_GPL
+-0x131c2452    snd_jack_set_key        vmlinux EXPORT_SYMBOL
+-0x74c134b9    __sw_hweight32  vmlinux EXPORT_SYMBOL
+-0x57674fd7    __sw_hweight16  vmlinux EXPORT_SYMBOL
+-0x9f46ced8    __sw_hweight64  vmlinux EXPORT_SYMBOL
+-0x93215e1d    __kfifo_skip_r  vmlinux EXPORT_SYMBOL
+-0x1ec4eb34    flex_array_prealloc     vmlinux EXPORT_SYMBOL
+-0x01e6b7fa    get_phy_device  vmlinux EXPORT_SYMBOL
+-0x391c17d1    wakeup_source_register  vmlinux EXPORT_SYMBOL_GPL
+-0xfe85236b    cpu_user        vmlinux EXPORT_SYMBOL
+-0x35e62033    pagevec_lookup_tag      vmlinux EXPORT_SYMBOL
+-0x34184afe    current_kernel_time     vmlinux EXPORT_SYMBOL
+-0x0eb2ceba    tcp_reno_cong_avoid     vmlinux EXPORT_SYMBOL_GPL
+-0x2fce25e3    print_tuple     vmlinux EXPORT_SYMBOL_GPL
+-0x62496fbf    snd_soc_dai_set_clkdiv  vmlinux EXPORT_SYMBOL_GPL
+-0x7505bdef    memchr_inv      vmlinux EXPORT_SYMBOL
+-0x3b21bfec    locks_copy_lock vmlinux EXPORT_SYMBOL
+-0xb47a0298    hid_dump_report vmlinux EXPORT_SYMBOL_GPL
+-0x391147d1    led_trigger_blink       vmlinux EXPORT_SYMBOL_GPL
+-0xb65a6bb8    usb_reset_device        vmlinux EXPORT_SYMBOL_GPL
+-0x007b6ccf    gnet_stats_start_copy_compat    vmlinux EXPORT_SYMBOL
+-0x7522f3ba    irq_modify_status       vmlinux EXPORT_SYMBOL_GPL
+-0xd9052a07    rtc_alarm_irq_enable    vmlinux EXPORT_SYMBOL_GPL
+-0xcb6dc422    usb_add_config_only     vmlinux EXPORT_SYMBOL_GPL
+-0xd38b2d79    inet6_del_protocol      vmlinux EXPORT_SYMBOL
+-0x98b8ddd3    xfrm_input_resume       vmlinux EXPORT_SYMBOL
+-0xf71914b4    udplite_prot    vmlinux EXPORT_SYMBOL
+-0xdc48464a    sock_create_kern        vmlinux EXPORT_SYMBOL
+-0x8260686f    bitmap_find_next_zero_area      vmlinux EXPORT_SYMBOL
+-0x354ac8ad    scsi_eh_restore_cmnd    vmlinux EXPORT_SYMBOL
+-0x6f988f59    transport_remove_device vmlinux EXPORT_SYMBOL_GPL
+-0x600f8836    drm_class_device_register       vmlinux EXPORT_SYMBOL_GPL
+-0xd589c1c3    sk_clone_lock   vmlinux EXPORT_SYMBOL_GPL
+-0xf8798032    d_find_any_alias        vmlinux EXPORT_SYMBOL
+-0x56e4cd15    ftrace_event_reg        vmlinux EXPORT_SYMBOL_GPL
+-0xab29d75c    thermal_zone_get_zone_by_name   vmlinux EXPORT_SYMBOL_GPL
+-0x2a678a13    __suspend_report_result vmlinux EXPORT_SYMBOL_GPL
+-0xe36d12fc    drm_gtf_mode    vmlinux EXPORT_SYMBOL
+-0x5a48534a    regulator_count_voltages        vmlinux EXPORT_SYMBOL_GPL
+-0x2edb3fd8    sk_attach_filter        vmlinux EXPORT_SYMBOL_GPL
+-0x8d107d70    sk_detach_filter        vmlinux EXPORT_SYMBOL_GPL
+-0x5da176fe    snd_timer_open  vmlinux EXPORT_SYMBOL
+-0xf741c793    zlib_deflateEnd vmlinux EXPORT_SYMBOL
+-0x7469fcfe    radix_tree_tagged       vmlinux EXPORT_SYMBOL
+-0x57c405a5    unload_nls      vmlinux EXPORT_SYMBOL
+-0xcaa97c6a    seq_open_private        vmlinux EXPORT_SYMBOL
+-0xf3d2b805    st_sensors_get_buffer_element   vmlinux EXPORT_SYMBOL
+-0x82286526    vb2_ioctl_create_bufs   vmlinux EXPORT_SYMBOL_GPL
+-0xfb7d95b7    fb_set_cmap     vmlinux EXPORT_SYMBOL
+-0xed46d9ec    kernel_listen   vmlinux EXPORT_SYMBOL
+-0xb1b16346    snd_jack_set_parent     vmlinux EXPORT_SYMBOL
+-0x76bf656d    __bitmap_shift_left     vmlinux EXPORT_SYMBOL
+-0x1979065a    serio_unregister_driver vmlinux EXPORT_SYMBOL
+-0x3a94c8e6    drm_modeset_lock_all    vmlinux EXPORT_SYMBOL
+-0xa093e7da    nat_rtp_rtcp_hook       vmlinux EXPORT_SYMBOL_GPL
+-0xe23ae481    blk_iopoll_complete     vmlinux EXPORT_SYMBOL
+-0x4f6172ff    crypto_chain    vmlinux EXPORT_SYMBOL_GPL
+-0xd66a562b    __scsi_device_lookup    vmlinux EXPORT_SYMBOL
+-0x9d669763    memcpy  vmlinux EXPORT_SYMBOL
+-0x15c5eea4    ip6t_do_table   vmlinux EXPORT_SYMBOL
+-0x6b6533af    bdevname        vmlinux EXPORT_SYMBOL
+-0x65d67a20    blk_start_plug  vmlinux EXPORT_SYMBOL
+-0xdd686f05    cdev_init       vmlinux EXPORT_SYMBOL
+-0xbe63ee40    request_resource        vmlinux EXPORT_SYMBOL
+-0xb2018900    inet_getname    vmlinux EXPORT_SYMBOL
+-0x01610153    nf_ct_expect_init       vmlinux EXPORT_SYMBOL_GPL
+-0x04e1b99f    snd_pcm_std_chmaps      vmlinux EXPORT_SYMBOL_GPL
+-0x24a42b51    snd_unregister_oss_device       vmlinux EXPORT_SYMBOL
+-0x85e7deb2    iov_iter_fault_in_readable      vmlinux EXPORT_SYMBOL
+-0x8f049b6c    module_mutex    vmlinux EXPORT_SYMBOL_GPL
+-0x931b242d    regcache_sync   vmlinux EXPORT_SYMBOL_GPL
+-0xb95f98d6    _memset_io      vmlinux EXPORT_SYMBOL
+-0xa98e796e    modify_user_hw_breakpoint       vmlinux EXPORT_SYMBOL_GPL
+-0xbf9bcc8d    __cap_empty_set vmlinux EXPORT_SYMBOL
+-0xfba8bb33    dm_get_mapinfo  vmlinux EXPORT_SYMBOL
+-0x988ad2a2    rndis_set_param_vendor  vmlinux EXPORT_SYMBOL
+-0xb67d6992    usb_ep_autoconfig_reset vmlinux EXPORT_SYMBOL_GPL
+-0xfbe5910d    drm_mode_config_init    vmlinux EXPORT_SYMBOL
+-0x6443df4e    videomode_from_timings  vmlinux EXPORT_SYMBOL_GPL
+-0xad059f21    ip_tunnel_changelink    vmlinux EXPORT_SYMBOL_GPL
+-0x2c7fb2d0    crypto_shoot_alg        vmlinux EXPORT_SYMBOL_GPL
+-0xac226765    iput    vmlinux EXPORT_SYMBOL
+-0x77fe4cb2    sleep_on_timeout        vmlinux EXPORT_SYMBOL
+-0x1d88a23f    platform_get_resource   vmlinux EXPORT_SYMBOL_GPL
+-0xb95beb55    drm_object_property_set_value   vmlinux EXPORT_SYMBOL
+-0x8481713b    pn_sock_unhash  vmlinux EXPORT_SYMBOL
+-0x28a82da4    snmp_mib_init   vmlinux EXPORT_SYMBOL_GPL
+-0x03fd2571    vm_unmap_ram    vmlinux EXPORT_SYMBOL
+-0x65466939    proc_doulongvec_ms_jiffies_minmax       vmlinux EXPORT_SYMBOL
+-0x23654452    input_ff_upload vmlinux EXPORT_SYMBOL_GPL
+-0x45bda0d5    system_serial_low       vmlinux EXPORT_SYMBOL
+-0xa682a886    xfrm_output     vmlinux EXPORT_SYMBOL_GPL
+-0xeea9dbaf    bitmap_bitremap vmlinux EXPORT_SYMBOL
+-0x71a50dbc    register_blkdev vmlinux EXPORT_SYMBOL
+-0x43c0e15b    fuse_sync_release       vmlinux EXPORT_SYMBOL_GPL
+-0x972213d1    of_phy_connect  vmlinux EXPORT_SYMBOL
+-0x95390328    __fimc_vidioc_querycap  vmlinux EXPORT_SYMBOL
+-0xe453b342    ipv6_select_ident       vmlinux EXPORT_SYMBOL
+-0xabca477d    nf_conntrack_alter_reply        vmlinux EXPORT_SYMBOL_GPL
+-0x72c09e90    neigh_event_ns  vmlinux EXPORT_SYMBOL
+-0x32590631    snd_soc_update_bits     vmlinux EXPORT_SYMBOL_GPL
+-0xb96df73b    elevator_change vmlinux EXPORT_SYMBOL
+-0xa30a6f34    jbd2_journal_blocks_per_page    vmlinux EXPORT_SYMBOL
+-0x6103b2f2    iterate_supers_type     vmlinux EXPORT_SYMBOL
+-0x0a311e2a    iio_read_channel_processed      vmlinux EXPORT_SYMBOL_GPL
+-0x89953a68    sdhci_free_host vmlinux EXPORT_SYMBOL_GPL
+-0xb8de0d37    dpm_for_each_dev        vmlinux EXPORT_SYMBOL_GPL
+-0xe35ba70f    drm_prime_destroy_file_private  vmlinux EXPORT_SYMBOL
+-0x1cb4683d    drm_framebuffer_lookup  vmlinux EXPORT_SYMBOL
+-0xbaa9e7e0    fb_firmware_edid        vmlinux EXPORT_SYMBOL
+-0xa2ede8b2    nf_queue_entry_get_refs vmlinux EXPORT_SYMBOL_GPL
+-0x0ff98044    jump_label_rate_limit   vmlinux EXPORT_SYMBOL_GPL
+-0x3fd9109b    v4l2_ctrl_subdev_log_status     vmlinux EXPORT_SYMBOL
+-0x78cf4589    usb_kill_anchored_urbs  vmlinux EXPORT_SYMBOL_GPL
+-0x3b79aef9    request_firmware_nowait vmlinux EXPORT_SYMBOL
+-0xab160376    create_syslog_header    vmlinux EXPORT_SYMBOL
+-0x6d42bb18    drm_gem_handle_delete   vmlinux EXPORT_SYMBOL
+-0x366d19ef    genericbl_limit_intensity       vmlinux EXPORT_SYMBOL
+-0x7380780d    cfg80211_unlink_bss     vmlinux EXPORT_SYMBOL
+-0xff6b7f32    netdev_change_features  vmlinux EXPORT_SYMBOL
+-0x5613414a    init_dummy_netdev       vmlinux EXPORT_SYMBOL_GPL
+-0xbd5cb8b9    ring_buffer_resize      vmlinux EXPORT_SYMBOL_GPL
+-0xa55e517c    ip_tunnel_xmit  vmlinux EXPORT_SYMBOL_GPL
+-0x3b870a79    dst_destroy     vmlinux EXPORT_SYMBOL
+-0xad6b883a    usbnet_get_drvinfo      vmlinux EXPORT_SYMBOL_GPL
+-0x5df7a89b    nf_ct_helper_expectfn_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0x275ef902    __init_waitqueue_head   vmlinux EXPORT_SYMBOL
+-0x472b2841    devm_usb_get_phy        vmlinux EXPORT_SYMBOL_GPL
+-0x790d8481    scsi_mode_sense vmlinux EXPORT_SYMBOL
+-0x2d89342a    scsi_show_sense_hdr     vmlinux EXPORT_SYMBOL
+-0xda7ca6cb    fb_mode_is_equal        vmlinux EXPORT_SYMBOL
+-0xdc4798d2    xfrm6_tunnel_register   vmlinux EXPORT_SYMBOL
+-0xd587e7b5    xfrm4_tunnel_register   vmlinux EXPORT_SYMBOL
+-0x360b01a3    nf_ct_get_tuple vmlinux EXPORT_SYMBOL_GPL
+-0x6c74c2ee    blk_insert_cloned_request       vmlinux EXPORT_SYMBOL_GPL
+-0x46cb2731    security_sb_set_mnt_opts        vmlinux EXPORT_SYMBOL
+-0x1b995ffb    iommu_domain_window_enable      vmlinux EXPORT_SYMBOL_GPL
+-0xa4ea04ee    of_property_read_u64    vmlinux EXPORT_SYMBOL_GPL
+-0x411e4ef5    brcmu_pktq_pdeq_tail    drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x422d82d0    brcmu_pktq_penq_head    drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x41cc94d0    brcmu_pktq_peek_tail    drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x0c6f118f    nf_nat_icmpv6_reply_translation vmlinux EXPORT_SYMBOL_GPL
+-0xa07842c6    skb_copy_datagram_from_iovec    vmlinux EXPORT_SYMBOL
+-0xc8269f94    snd_soc_params_to_frame_size    vmlinux EXPORT_SYMBOL_GPL
+-0x43eeb6cf    snd_pcm_lib_ioctl       vmlinux EXPORT_SYMBOL
+-0x9ac11b74    suspend_set_ops vmlinux EXPORT_SYMBOL_GPL
+-0xca16dbe7    regulator_enable        vmlinux EXPORT_SYMBOL_GPL
+-0xecc84eb2    dst_alloc       vmlinux EXPORT_SYMBOL
+-0xf0f5dbc2    timerqueue_iterate_next vmlinux EXPORT_SYMBOL_GPL
+-0xab4a5add    blk_put_queue   vmlinux EXPORT_SYMBOL
+-0x11bef8bd    single_release  vmlinux EXPORT_SYMBOL
+-0x7aad72c6    get_user_pages  vmlinux EXPORT_SYMBOL
+-0x6214aef2    cpufreq_unregister_notifier     vmlinux EXPORT_SYMBOL
+-0xe93e49c3    devres_free     vmlinux EXPORT_SYMBOL_GPL
+-0xd95fbe77    of_find_backlight_by_node       vmlinux EXPORT_SYMBOL
+-0xe3f553d9    ip6_append_data vmlinux EXPORT_SYMBOL_GPL
+-0xa108eb4d    sysctl_optmem_max       vmlinux EXPORT_SYMBOL
+-0xdc323ca6    jbd2_journal_destroy    vmlinux EXPORT_SYMBOL
+-0x3c7a1672    jbd2_journal_restart    vmlinux EXPORT_SYMBOL
+-0x9805d460    v4l2_device_register    vmlinux EXPORT_SYMBOL_GPL
+-0x1db6d990    display_entity_get_first        vmlinux EXPORT_SYMBOL
+-0xe57878a1    in6_pton        vmlinux EXPORT_SYMBOL
+-0xaccabc6a    in4_pton        vmlinux EXPORT_SYMBOL
+-0xd0181f4f    __bitmap_xor    vmlinux EXPORT_SYMBOL
+-0x208c317e    mnt_want_write  vmlinux EXPORT_SYMBOL_GPL
+-0xbcdedba7    of_get_mac_address      vmlinux EXPORT_SYMBOL
+-0x859bbb79    scsi_mode_select        vmlinux EXPORT_SYMBOL_GPL
+-0x48991892    cfb_copyarea    vmlinux EXPORT_SYMBOL
+-0x2455c156    __clear_user    vmlinux EXPORT_SYMBOL
+-0x42c7d35b    __dev_remove_pack       vmlinux EXPORT_SYMBOL
+-0x465cab34    secure_ipv6_port_ephemeral      vmlinux EXPORT_SYMBOL
+-0x5ddbac94    config_group_init       vmlinux EXPORT_SYMBOL
+-0x773c1fdc    posix_acl_to_xattr      vmlinux EXPORT_SYMBOL
+-0xb18429eb    suspend_device_irqs     vmlinux EXPORT_SYMBOL_GPL
+-0x50c52151    _raw_write_unlock_irq   vmlinux EXPORT_SYMBOL
+-0xf5bc65a3    iommu_unmap     vmlinux EXPORT_SYMBOL_GPL
+-0x710e2b07    tcf_hash_insert vmlinux EXPORT_SYMBOL
+-0xf13feb57    radix_tree_next_chunk   vmlinux EXPORT_SYMBOL
+-0x90a1004a    crypto_has_alg  vmlinux EXPORT_SYMBOL_GPL
+-0x8cd44e50    iget5_locked    vmlinux EXPORT_SYMBOL
+-0x3dcb88a0    irq_set_handler_data    vmlinux EXPORT_SYMBOL
+-0xaa7de358    yield_to        vmlinux EXPORT_SYMBOL_GPL
+-0xc54649ff    __starget_for_each_device       vmlinux EXPORT_SYMBOL
+-0x2bd1f745    drm_mode_config_cleanup vmlinux EXPORT_SYMBOL
+-0xa1425906    ieee80211_channel_to_frequency  vmlinux EXPORT_SYMBOL
+-0x59806cb9    sk_page_frag_refill     vmlinux EXPORT_SYMBOL
+-0xce90ef6b    debugfs_create_dir      vmlinux EXPORT_SYMBOL_GPL
+-0xa4827144    dcache_dir_lseek        vmlinux EXPORT_SYMBOL
+-0x0c2cdbf1    synchronize_sched       vmlinux EXPORT_SYMBOL_GPL
+-0x92a9c60c    time_to_tm      vmlinux EXPORT_SYMBOL
+-0x651a4139    test_taint      vmlinux EXPORT_SYMBOL
+-0x2b66e1b8    mii_check_media vmlinux EXPORT_SYMBOL
+-0xfb7d9c45    __udivsi3       vmlinux EXPORT_SYMBOL
+-0x633fafc5    netdev_printk   vmlinux EXPORT_SYMBOL
+-0xf5a691cd    invalidate_bh_lrus      vmlinux EXPORT_SYMBOL_GPL
+-0xe5524eab    of_address_to_resource  vmlinux EXPORT_SYMBOL_GPL
+-0xe22f01b0    thermal_zone_device_register    vmlinux EXPORT_SYMBOL_GPL
+-0x3fc8bae1    ipcomp_init_state       vmlinux EXPORT_SYMBOL_GPL
+-0xf5b5f1ec    xt_check_match  vmlinux EXPORT_SYMBOL_GPL
+-0x24aac4d9    crypto_aes_expand_key   vmlinux EXPORT_SYMBOL_GPL
+-0x6f798a9c    d_splice_alias  vmlinux EXPORT_SYMBOL
+-0x88196936    do_sync_read    vmlinux EXPORT_SYMBOL
+-0x4a18707e    mem_map vmlinux EXPORT_SYMBOL
+-0x0366307a    console_suspend_enabled vmlinux EXPORT_SYMBOL
+-0x204d506e    st_sensors_write_event_value    vmlinux EXPORT_SYMBOL
+-0x4c22a54d    usb_ep_autoconfig       vmlinux EXPORT_SYMBOL_GPL
+-0x32c3cb4e    class_compat_register   vmlinux EXPORT_SYMBOL_GPL
+-0x7b85f6f8    drm_mm_insert_node      vmlinux EXPORT_SYMBOL
+-0x78f9b710    nf_ct_l3proto_try_module_get    vmlinux EXPORT_SYMBOL_GPL
+-0x44594236    snd_soc_unregister_component    vmlinux EXPORT_SYMBOL_GPL
+-0x05e4e6be    register_sound_midi     vmlinux EXPORT_SYMBOL
+-0x07341a03    kobject_rename  vmlinux EXPORT_SYMBOL_GPL
+-0x35b6b772    param_ops_charp vmlinux EXPORT_SYMBOL
+-0xb4c1829e    clk_round_rate  vmlinux EXPORT_SYMBOL_GPL
+-0x1bb061cc    sdio_release_irq        vmlinux EXPORT_SYMBOL_GPL
+-0xe4c673df    mmc_wait_for_cmd        vmlinux EXPORT_SYMBOL
+-0x4d088d1f    drm_mm_replace_node     vmlinux EXPORT_SYMBOL
+-0xe24e09b0    cgroup_taskset_cur_cgroup       vmlinux EXPORT_SYMBOL_GPL
+-0x7c5cf140    cad_pid vmlinux EXPORT_SYMBOL
+-0xaea8b9a5    drm_get_encoder_name    vmlinux EXPORT_SYMBOL
+-0xe4c80097    cacheid vmlinux EXPORT_SYMBOL
+-0x5a5a94a6    kstrtou8        vmlinux EXPORT_SYMBOL
+-0x2b4aa9c9    get_task_pid    vmlinux EXPORT_SYMBOL_GPL
+-0x30f43c3b    sdhci_enable_irq_wakeups        vmlinux EXPORT_SYMBOL_GPL
+-0x3a6d4f22    rndis_free_response     vmlinux EXPORT_SYMBOL
+-0x85478a0b    inet6_hash_frag vmlinux EXPORT_SYMBOL_GPL
+-0x0efbc42d    snd_component_add       vmlinux EXPORT_SYMBOL
+-0x6605f97f    flex_array_clear        vmlinux EXPORT_SYMBOL
+-0x5a7bfe41    crypto_probing_notify   vmlinux EXPORT_SYMBOL_GPL
+-0x94fd7214    serial8250_rx_chars     vmlinux EXPORT_SYMBOL_GPL
+-0x13a6027a    ip6t_alloc_initial_table        vmlinux EXPORT_SYMBOL_GPL
+-0x03a9a7bd    netif_receive_skb       vmlinux EXPORT_SYMBOL
+-0xfb6af58d    recalc_sigpending       vmlinux EXPORT_SYMBOL
+-0x2d0ea593    spi_new_device  vmlinux EXPORT_SYMBOL_GPL
+-0xfbc4e14c    pm_runtime_enable       vmlinux EXPORT_SYMBOL_GPL
+-0xc583bf57    of_regulator_match      vmlinux EXPORT_SYMBOL_GPL
+-0xebfdcbdf    system_serial_high      vmlinux EXPORT_SYMBOL
+-0x28d7fc1f    nf_nat_mangle_udp_packet        vmlinux EXPORT_SYMBOL
+-0xf71016b7    snd_soc_dapm_get_pin_status     vmlinux EXPORT_SYMBOL_GPL
+-0xf05c8ab1    vb2_get_contig_userptr  vmlinux EXPORT_SYMBOL_GPL
+-0xd045db89    nfc_class       vmlinux EXPORT_SYMBOL
+-0x606340d3    disk_part_iter_exit     vmlinux EXPORT_SYMBOL_GPL
+-0xa1bd7822    __tracepoint_block_bio_complete vmlinux EXPORT_SYMBOL_GPL
+-0x16138f6f    follow_down_one vmlinux EXPORT_SYMBOL
+-0x7944e0fc    tracing_off     vmlinux EXPORT_SYMBOL_GPL
+-0xb1425b32    dm_table_add_target_callbacks   vmlinux EXPORT_SYMBOL_GPL
+-0xbdfb8830    anon_transport_class_register   vmlinux EXPORT_SYMBOL_GPL
+-0x911d700e    devm_phy_create vmlinux EXPORT_SYMBOL_GPL
+-0xeb908d00    raw_seq_next    vmlinux EXPORT_SYMBOL_GPL
+-0x30b265dd    ip_setsockopt   vmlinux EXPORT_SYMBOL
+-0x9f45de2c    ip_getsockopt   vmlinux EXPORT_SYMBOL
+-0x30322337    nf_ct_l3proto_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0x8106c2de    nf_ct_l4proto_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0x4b015768    snd_iprintf     vmlinux EXPORT_SYMBOL
+-0xec728ca6    blk_unprep_request      vmlinux EXPORT_SYMBOL_GPL
+-0x0bae62b1    ktime_get_monotonic_offset      vmlinux EXPORT_SYMBOL_GPL
+-0x6f8450af    tty_encode_baud_rate    vmlinux EXPORT_SYMBOL_GPL
+-0xead6a706    devm_phy_destroy        vmlinux EXPORT_SYMBOL_GPL
+-0x2cf3c356    ip6_redirect    vmlinux EXPORT_SYMBOL_GPL
+-0x2cdb55d1    ip_options_rcv_srr      vmlinux EXPORT_SYMBOL
+-0x105bdf9b    dentry_open     vmlinux EXPORT_SYMBOL
+-0x724bf4b2    i2c_bit_add_numbered_bus        vmlinux EXPORT_SYMBOL
+-0x2e09263f    usb_copy_descriptors    vmlinux EXPORT_SYMBOL_GPL
+-0xbec98305    device_register vmlinux EXPORT_SYMBOL_GPL
+-0xff519474    skb_checksum_help       vmlinux EXPORT_SYMBOL
+-0x293d87a4    unregister_netdevice_queue      vmlinux EXPORT_SYMBOL
+-0xa692560a    snd_soc_lookup_platform vmlinux EXPORT_SYMBOL_GPL
+-0x9545af6d    tasklet_init    vmlinux EXPORT_SYMBOL
+-0x87374f66    extcon_unregister_interest      vmlinux EXPORT_SYMBOL_GPL
+-0x40a27c37    scsi_dev_info_remove_list       vmlinux EXPORT_SYMBOL
+-0x42a2164f    regmap_write    vmlinux EXPORT_SYMBOL_GPL
+-0xe6f46e6e    drm_clflush_virt_range  vmlinux EXPORT_SYMBOL
+-0x17f8217b    nf_nat_setup_info       vmlinux EXPORT_SYMBOL
+-0xb3daf4bf    jbd2_journal_get_undo_access    vmlinux EXPORT_SYMBOL
+-0xe16591ab    stop_machine    vmlinux EXPORT_SYMBOL_GPL
+-0xb6261484    register_die_notifier   vmlinux EXPORT_SYMBOL_GPL
+-0x415838be    led_trigger_set_default vmlinux EXPORT_SYMBOL_GPL
+-0x843020c0    ip6_find_1stfragopt     vmlinux EXPORT_SYMBOL
+-0x062936ed    nf_ct_unlink_expect_report      vmlinux EXPORT_SYMBOL_GPL
+-0xa6d16c61    sock_no_recvmsg vmlinux EXPORT_SYMBOL
+-0x4b0ac955    hrtimer_cancel  vmlinux EXPORT_SYMBOL_GPL
+-0x3626ebf4    xt_unregister_matches   vmlinux EXPORT_SYMBOL
+-0x72ea7812    security_inode_setattr  vmlinux EXPORT_SYMBOL_GPL
+-0xfdfc0b3b    fiemap_fill_next_extent vmlinux EXPORT_SYMBOL
+-0x82d19daa    qdisc_watchdog_cancel   vmlinux EXPORT_SYMBOL
+-0xc0581ee5    crypto_shash_digest     vmlinux EXPORT_SYMBOL_GPL
+-0x78728b6b    crypto_ahash_digest     vmlinux EXPORT_SYMBOL_GPL
+-0x3de9cae1    crypto_remove_final     vmlinux EXPORT_SYMBOL_GPL
+-0x31faa864    media_entity_init       vmlinux EXPORT_SYMBOL_GPL
+-0xe827112b    rtnl_set_sk_err vmlinux EXPORT_SYMBOL
+-0x5b23591f    snd_soc_jack_new        vmlinux EXPORT_SYMBOL_GPL
+-0x7b6646bb    _raw_read_lock  vmlinux EXPORT_SYMBOL
+-0xd4669fad    complete        vmlinux EXPORT_SYMBOL
+-0x488882e7    downgrade_write vmlinux EXPORT_SYMBOL
+-0xbaac427c    get_mem_type    vmlinux EXPORT_SYMBOL
+-0xc4014b9d    ip_check_defrag vmlinux EXPORT_SYMBOL
+-0x6aaccee0    config_item_init_type_name      vmlinux EXPORT_SYMBOL
+-0x62822d05    iov_iter_single_seg_count       vmlinux EXPORT_SYMBOL
+-0xb1f1a6ea    gether_get_host_addr_u8 vmlinux EXPORT_SYMBOL
+-0xf7f652fe    dma_mmap_from_coherent  vmlinux EXPORT_SYMBOL
+-0xfa9720a0    rdev_get_dev    vmlinux EXPORT_SYMBOL_GPL
+-0x62186db5    brcmu_pkt_buf_get_skb   drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0xf7af6d75    snd_pcm_new_stream      vmlinux EXPORT_SYMBOL
+-0x17320c5c    dentry_update_name_case vmlinux EXPORT_SYMBOL
+-0x8a7d1c31    high_memory     vmlinux EXPORT_SYMBOL
+-0x0186e2de    smp_call_function_many  vmlinux EXPORT_SYMBOL
+-0xbdf098ae    scsi_test_unit_ready    vmlinux EXPORT_SYMBOL
+-0x119b50e7    elf_check_arch  vmlinux EXPORT_SYMBOL
+-0xbf6d5c21    inet6_csk_update_pmtu   vmlinux EXPORT_SYMBOL_GPL
+-0x6b9a4457    snd_soc_jack_free_gpios vmlinux EXPORT_SYMBOL_GPL
+-0xd28c735f    simple_link     vmlinux EXPORT_SYMBOL
+-0xbdd2f42a    rcu_bh_force_quiescent_state    vmlinux EXPORT_SYMBOL_GPL
+-0x7a3cd015    v4l2_ctrl_get_menu      vmlinux EXPORT_SYMBOL
+-0x97f5694d    page_cache_async_readahead      vmlinux EXPORT_SYMBOL_GPL
+-0x2b4e956e    mempool_create  vmlinux EXPORT_SYMBOL
+-0x57231f45    ring_buffer_record_on   vmlinux EXPORT_SYMBOL_GPL
+-0x8e311007    hidinput_find_field     vmlinux EXPORT_SYMBOL_GPL
+-0x7ae1ae8e    cpufreq_frequency_table_put_attr        vmlinux EXPORT_SYMBOL_GPL
+-0x6c6a4b95    scsi_remove_target      vmlinux EXPORT_SYMBOL
+-0xb6c5a973    scsi_show_result        vmlinux EXPORT_SYMBOL
+-0x1ec3bed9    hdmi_audio_infoframe_init       vmlinux EXPORT_SYMBOL
+-0x3244dece    kblockd_schedule_work   vmlinux EXPORT_SYMBOL
+-0xafac4a33    mem_section     vmlinux EXPORT_SYMBOL
+-0xfd044751    send_sig_info   vmlinux EXPORT_SYMBOL
+-0xc02cf69b    clkdev_drop     vmlinux EXPORT_SYMBOL
+-0x39c95e24    phy_init_eee    vmlinux EXPORT_SYMBOL
+-0xfc53eac8    drm_cvt_mode    vmlinux EXPORT_SYMBOL
+-0x6a5e6530    __neigh_event_send      vmlinux EXPORT_SYMBOL
+-0x6c4d4cfe    sk_stream_wait_close    vmlinux EXPORT_SYMBOL
+-0x3d1cdeca    read_cache_page_async   vmlinux EXPORT_SYMBOL
+-0xd0ee38b8    schedule_timeout_uninterruptible        vmlinux EXPORT_SYMBOL
+-0xd79b5a02    allow_signal    vmlinux EXPORT_SYMBOL
+-0xd14fa335    show_class_attr_string  vmlinux EXPORT_SYMBOL_GPL
+-0xacb2a583    ndo_dflt_fdb_add        vmlinux EXPORT_SYMBOL
+-0x49a39542    snd_timer_global_register       vmlinux EXPORT_SYMBOL
+-0x63407037    kill_anon_super vmlinux EXPORT_SYMBOL
+-0xdc2b4205    platform_get_irq        vmlinux EXPORT_SYMBOL_GPL
+-0xc777ecaa    xfrm6_rcv       vmlinux EXPORT_SYMBOL
+-0x2fee3a7e    xfrm4_rcv       vmlinux EXPORT_SYMBOL
+-0xe94fef47    nf_ct_delete_from_lists vmlinux EXPORT_SYMBOL_GPL
+-0x6d466653    snd_soc_unregister_platform     vmlinux EXPORT_SYMBOL_GPL
+-0xb61a0c3b    bt_err  vmlinux EXPORT_SYMBOL
+-0x79536600    snd_soc_dpcm_can_be_params      vmlinux EXPORT_SYMBOL_GPL
+-0x016c4bc3    cfg80211_put_bss        vmlinux EXPORT_SYMBOL
+-0x90922aec    inet_dgram_connect      vmlinux EXPORT_SYMBOL
+-0x103ea6ec    generic_pipe_buf_steal  vmlinux EXPORT_SYMBOL
+-0x5fe77756    generic_pipe_buf_unmap  vmlinux EXPORT_SYMBOL
+-0xe5d95985    param_ops_ulong vmlinux EXPORT_SYMBOL
+-0xb03c01e8    dbs_check_cpu   vmlinux EXPORT_SYMBOL_GPL
+-0xff15acd6    usb_put_function_instance       vmlinux EXPORT_SYMBOL_GPL
+-0x6406cdf0    usb_find_alt_setting    vmlinux EXPORT_SYMBOL_GPL
+-0x4626bf6d    phy_connect     vmlinux EXPORT_SYMBOL
+-0x7a9326c6    driver_unregister       vmlinux EXPORT_SYMBOL_GPL
+-0xc5570382    inet_frags_exit_net     vmlinux EXPORT_SYMBOL
+-0x08216276    kobject_get     vmlinux EXPORT_SYMBOL
+-0x006818a5    kobject_put     vmlinux EXPORT_SYMBOL
+-0x37b777df    param_set_copystring    vmlinux EXPORT_SYMBOL
+-0x54f21cff    __send_remote_softirq   vmlinux EXPORT_SYMBOL
+-0x7a925833    cpufreq_get_global_kobject      vmlinux EXPORT_SYMBOL
+-0x2c900d91    cpufreq_put_global_kobject      vmlinux EXPORT_SYMBOL
+-0xbac4a225    v4l2_ctrl_fill  vmlinux EXPORT_SYMBOL
+-0xf7e6e534    v4l2_ctrl_find  vmlinux EXPORT_SYMBOL
+-0xbc5671dc    v4l_printk_ioctl        vmlinux EXPORT_SYMBOL
+-0x17021c93    drm_i2c_encoder_commit  vmlinux EXPORT_SYMBOL
+-0x10e70fd2    display_entity_get_modes        vmlinux EXPORT_SYMBOL_GPL
+-0xf1deabf2    div64_u64       vmlinux EXPORT_SYMBOL
+-0x2488515b    vb2_put_vma     vmlinux EXPORT_SYMBOL_GPL
+-0xd2ea2134    usb_descriptor_fillbuf  vmlinux EXPORT_SYMBOL_GPL
+-0xdacd26c5    usb_scuttle_anchored_urbs       vmlinux EXPORT_SYMBOL_GPL
+-0xfc39e32f    ioport_unmap    vmlinux EXPORT_SYMBOL
+-0x348998d3    sysfs_merge_group       vmlinux EXPORT_SYMBOL_GPL
+-0xc84a0a7e    seq_hlist_start_rcu     vmlinux EXPORT_SYMBOL
+-0xdd51deeb    d_validate      vmlinux EXPORT_SYMBOL
+-0x88ea60db    __get_user_pages_fast   vmlinux EXPORT_SYMBOL_GPL
+-0xe9bff861    down_trylock    vmlinux EXPORT_SYMBOL
+-0xff9e0620    usb_reset_configuration vmlinux EXPORT_SYMBOL_GPL
+-0x00130217    pwm_free        vmlinux EXPORT_SYMBOL_GPL
+-0x8fedcd53    snd_soc_info_xr_sx      vmlinux EXPORT_SYMBOL_GPL
+-0xc256e762    __bitmap_equal  vmlinux EXPORT_SYMBOL
+-0x7d4e2276    __init_rwsem    vmlinux EXPORT_SYMBOL
+-0xee5a877d    page_zero_new_buffers   vmlinux EXPORT_SYMBOL
+-0x96710252    mntget  vmlinux EXPORT_SYMBOL
+-0xe85c78e2    mntput  vmlinux EXPORT_SYMBOL
+-0x038e97d3    fasync_helper   vmlinux EXPORT_SYMBOL
+-0xf75c7d80    wm8994_mic_detect       vmlinux EXPORT_SYMBOL_GPL
+-0x2f4113a2    dcookie_register        vmlinux EXPORT_SYMBOL_GPL
+-0xce37be95    locks_mandatory_area    vmlinux EXPORT_SYMBOL
+-0x8be294cd    iommu_domain_free       vmlinux EXPORT_SYMBOL_GPL
+-0x23b5b8d1    exynos_drm_subdrv_register      vmlinux EXPORT_SYMBOL_GPL
+-0x6867f405    inet_twsk_deschedule    vmlinux EXPORT_SYMBOL
+-0x244e2178    xt_table_unlock vmlinux EXPORT_SYMBOL_GPL
+-0x52b9d131    tcf_exts_dump_stats     vmlinux EXPORT_SYMBOL
+-0x48bb9eb5    sock_alloc_send_pskb    vmlinux EXPORT_SYMBOL
+-0x757206d5    wm_hubs_spkmix_tlv      vmlinux EXPORT_SYMBOL_GPL
+-0x0acb1a3c    __bitmap_shift_right    vmlinux EXPORT_SYMBOL
+-0xaaa918c9    ftrace_dump     vmlinux EXPORT_SYMBOL_GPL
+-0x402b8281    __request_module        vmlinux EXPORT_SYMBOL
+-0xe944ba87    st_sensors_set_axis_enable      vmlinux EXPORT_SYMBOL
+-0x822f9003    inet_register_protosw   vmlinux EXPORT_SYMBOL
+-0xbe3a4f06    __inet_inherit_port     vmlinux EXPORT_SYMBOL_GPL
+-0xb63f16de    dev_deactivate  vmlinux EXPORT_SYMBOL
+-0xa014da84    snd_soc_add_platform_controls   vmlinux EXPORT_SYMBOL_GPL
+-0xeaaee9e6    submit_bio_wait vmlinux EXPORT_SYMBOL
+-0x23fd3028    vmalloc_node    vmlinux EXPORT_SYMBOL
+-0xa58fea9d    mempool_destroy vmlinux EXPORT_SYMBOL
+-0x054e550b    kernel_halt     vmlinux EXPORT_SYMBOL_GPL
+-0xf4c770ec    v4l2_clk_disable        vmlinux EXPORT_SYMBOL
+-0xd597e74e    phy_find_first  vmlinux EXPORT_SYMBOL
+-0x50621015    xfrm6_tunnel_spi_lookup vmlinux EXPORT_SYMBOL
+-0xc0f8a5b0    set_binfmt      vmlinux EXPORT_SYMBOL
+-0x36075bb5    iommu_group_register_notifier   vmlinux EXPORT_SYMBOL_GPL
+-0x93b8b0d3    scsi_ioctl      vmlinux EXPORT_SYMBOL
+-0xd0dcdd90    drm_mm_insert_node_in_range_generic     vmlinux EXPORT_SYMBOL
+-0xb2eaff96    km_policy_expired       vmlinux EXPORT_SYMBOL
+-0xa9effda5    __first_cpu     vmlinux EXPORT_SYMBOL
+-0xc24ba3ed    elv_rb_find     vmlinux EXPORT_SYMBOL
+-0xf0619801    timekeeping_clocktai    vmlinux EXPORT_SYMBOL
+-0x9e4faeef    dm_io_client_destroy    vmlinux EXPORT_SYMBOL
+-0x95cbb942    usb_add_gadget_udc_release      vmlinux EXPORT_SYMBOL_GPL
+-0x14c3db3e    spi_unregister_master   vmlinux EXPORT_SYMBOL_GPL
+-0xbee90f2f    __kfifo_out_peek_r      vmlinux EXPORT_SYMBOL
+-0x2869ebaf    regulator_bulk_force_disable    vmlinux EXPORT_SYMBOL_GPL
+-0xa04a01bd    qdisc_class_hash_insert vmlinux EXPORT_SYMBOL
+-0x43a261a8    eth_commit_mac_addr_change      vmlinux EXPORT_SYMBOL
+-0xe5867808    dlci_ioctl_set  vmlinux EXPORT_SYMBOL
+-0xbae6da94    crypto_alg_lookup       vmlinux EXPORT_SYMBOL_GPL
+-0x330d748a    v4l2_subdev_init        vmlinux EXPORT_SYMBOL
+-0xc6ff1a7d    phonet_header_ops       vmlinux EXPORT_SYMBOL
+-0xfaefacf3    locks_free_lock vmlinux EXPORT_SYMBOL
+-0xcbfa0b41    scsi_report_device_reset        vmlinux EXPORT_SYMBOL
+-0xbe1e4cd0    scsi_print_sense        vmlinux EXPORT_SYMBOL
+-0xe87ed821    drm_mode_create_dirty_info_property     vmlinux EXPORT_SYMBOL
+-0xb6d97288    inet6_add_offload       vmlinux EXPORT_SYMBOL
+-0xa681ec81    snd_soc_jack_notifier_register  vmlinux EXPORT_SYMBOL_GPL
+-0xd64b88b6    register_sound_mixer    vmlinux EXPORT_SYMBOL
+-0x02701efc    simple_attr_release     vmlinux EXPORT_SYMBOL_GPL
+-0xf6e04730    event_storage   vmlinux EXPORT_SYMBOL_GPL
+-0x95b5af62    mmc_regulator_set_ocr   vmlinux EXPORT_SYMBOL_GPL
+-0x77e78218    regulator_allow_bypass  vmlinux EXPORT_SYMBOL_GPL
+-0xf1070592    cfg80211_wext_giwretry  vmlinux EXPORT_SYMBOL_GPL
+-0x8a0f4230    rename_lock     vmlinux EXPORT_SYMBOL
+-0xda259c5d    page_symlink_inode_operations   vmlinux EXPORT_SYMBOL
+-0x8bd0a3fd    _raw_write_unlock_bh    vmlinux EXPORT_SYMBOL
+-0x99b0f1ff    usb_submit_urb  vmlinux EXPORT_SYMBOL_GPL
+-0x1fbd16da    ip_tos2prio     vmlinux EXPORT_SYMBOL
+-0x060ea2d6    kstrtoull       vmlinux EXPORT_SYMBOL
+-0x5ac15bae    kstrtou16       vmlinux EXPORT_SYMBOL
+-0x1998d8b6    jbd2_inode_cache        vmlinux EXPORT_SYMBOL
+-0x94961283    vunmap  vmlinux EXPORT_SYMBOL
+-0x74c4a01e    write_cache_pages       vmlinux EXPORT_SYMBOL
+-0xc1ddc02b    pinctrl_register        vmlinux EXPORT_SYMBOL_GPL
+-0x0ca54fee    _test_and_set_bit       vmlinux EXPORT_SYMBOL
+-0x80dfa464    xfrm_policy_alloc       vmlinux EXPORT_SYMBOL
+-0xd04f8eb6    nf_conntrack_l4proto_tcp6       vmlinux EXPORT_SYMBOL_GPL
+-0xcf28b516    finish_open     vmlinux EXPORT_SYMBOL
+-0x10f734ff    led_blink_set   vmlinux EXPORT_SYMBOL
+-0xc9086110    dw_mci_pltfm_remove     vmlinux EXPORT_SYMBOL_GPL
+-0xe5c78a99    do_blank_screen vmlinux EXPORT_SYMBOL
+-0xf17c6528    cfg80211_remain_on_channel_expired      vmlinux EXPORT_SYMBOL
+-0x117093be    qdisc_class_hash_init   vmlinux EXPORT_SYMBOL
+-0x13e6a1a2    sk_prot_clear_portaddr_nulls    vmlinux EXPORT_SYMBOL
+-0xa2a2d730    task_current_syscall    vmlinux EXPORT_SYMBOL_GPL
+-0x4411c503    prandom_seed    vmlinux EXPORT_SYMBOL
+-0x547ba3f6    single_open_net vmlinux EXPORT_SYMBOL_GPL
+-0xb9012717    set_page_dirty_lock     vmlinux EXPORT_SYMBOL
+-0x9a37cbf4    tcp_v4_conn_request     vmlinux EXPORT_SYMBOL
+-0xc81ae040    snd_soc_codec_volatile_register vmlinux EXPORT_SYMBOL_GPL
+-0xbe52317a    blk_rq_init     vmlinux EXPORT_SYMBOL
+-0x9ef34ad4    cpufreq_frequency_table_cpuinfo vmlinux EXPORT_SYMBOL_GPL
+-0x5bcf159d    usb_get_descriptor      vmlinux EXPORT_SYMBOL_GPL
+-0xf2e5cabe    spi_async_locked        vmlinux EXPORT_SYMBOL_GPL
+-0x26e76fb8    sysctl_udp_wmem_min     vmlinux EXPORT_SYMBOL
+-0x1fb12a69    tcp_v4_syn_recv_sock    vmlinux EXPORT_SYMBOL
+-0x6d464175    __sg_free_table vmlinux EXPORT_SYMBOL
+-0x59056c08    kmem_cache_shrink       vmlinux EXPORT_SYMBOL
+-0xc3aef602    usb_put_dev     vmlinux EXPORT_SYMBOL_GPL
+-0x520a3baf    drm_vm_open_locked      vmlinux EXPORT_SYMBOL_GPL
+-0x711a004a    drm_dp_link_rate_to_bw_code     vmlinux EXPORT_SYMBOL
+-0x919029aa    __readwrite_bug vmlinux EXPORT_SYMBOL
+-0x49045426    icmp_err_convert        vmlinux EXPORT_SYMBOL
+-0xf087137d    __dynamic_pr_debug      vmlinux EXPORT_SYMBOL
+-0x1e5b03dc    pm_qos_add_notifier     vmlinux EXPORT_SYMBOL_GPL
+-0x5e9d9e1e    gov_queue_work  vmlinux EXPORT_SYMBOL_GPL
+-0x601f665f    dm_io_client_create     vmlinux EXPORT_SYMBOL
+-0x05c311c2    vb2_ioctl_prepare_buf   vmlinux EXPORT_SYMBOL_GPL
+-0x14f62d2b    mii_check_link  vmlinux EXPORT_SYMBOL
+-0x36c69db7    dma_common_mmap vmlinux EXPORT_SYMBOL
+-0x1072a394    csum_partial_copy_from_user     vmlinux EXPORT_SYMBOL
+-0x3f878645    inet_diag_dump_one_icsk vmlinux EXPORT_SYMBOL_GPL
+-0xd7b85107    tcp_hashinfo    vmlinux EXPORT_SYMBOL
+-0x2d140a58    genl_unlock     vmlinux EXPORT_SYMBOL
+-0xeed1b62f    crypto_aead_setauthsize vmlinux EXPORT_SYMBOL_GPL
+-0x5f7bdc58    fd_install      vmlinux EXPORT_SYMBOL
+-0xe11f3cbc    _raw_read_lock_bh       vmlinux EXPORT_SYMBOL
+-0x3fd55724    of_n_size_cells vmlinux EXPORT_SYMBOL
+-0xd17aae7c    hid_report_raw_event    vmlinux EXPORT_SYMBOL_GPL
+-0xe469207d    scsi_unregister vmlinux EXPORT_SYMBOL
+-0xbf5da77e    dma_buf_begin_cpu_access        vmlinux EXPORT_SYMBOL_GPL
+-0x47ed7ca1    inet6_unregister_icmp_sender    vmlinux EXPORT_SYMBOL
+-0xed8b1ab6    nf_nat_used_tuple       vmlinux EXPORT_SYMBOL
+-0x46e928cf    nf_nat_packet   vmlinux EXPORT_SYMBOL_GPL
+-0xdc854ee4    blk_init_tags   vmlinux EXPORT_SYMBOL
+-0x4b134056    vfs_fsync_range vmlinux EXPORT_SYMBOL
+-0x3ce4ca6f    disable_irq     vmlinux EXPORT_SYMBOL
+-0xdc9fa232    raw_notifier_chain_register     vmlinux EXPORT_SYMBOL_GPL
+-0x2b0d15d8    scsi_internal_device_unblock    vmlinux EXPORT_SYMBOL_GPL
+-0x09d12bc0    sysfs_remove_file       vmlinux EXPORT_SYMBOL_GPL
+-0x85a8465a    path_put        vmlinux EXPORT_SYMBOL
+-0xe0dec72b    apply_to_page_range     vmlinux EXPORT_SYMBOL_GPL
+-0xa0ceef51    out_of_line_wait_on_bit vmlinux EXPORT_SYMBOL
+-0x7f04e7d5    dm_set_target_max_io_len        vmlinux EXPORT_SYMBOL_GPL
+-0x84a26155    v4l2_ctrl_g_ctrl        vmlinux EXPORT_SYMBOL
+-0x1254f0e4    scsi_host_alloc vmlinux EXPORT_SYMBOL
+-0x0e09444b    bus_get_device_klist    vmlinux EXPORT_SYMBOL_GPL
+-0xbebc3cd2    dst_discard     vmlinux EXPORT_SYMBOL
+-0x8d25ae30    snd_soc_dapm_put_value_enum_double      vmlinux EXPORT_SYMBOL_GPL
+-0x8d02ccf1    snd_soc_dapm_get_value_enum_double      vmlinux EXPORT_SYMBOL_GPL
+-0xaa2a72bf    __iowrite64_copy        vmlinux EXPORT_SYMBOL_GPL
+-0x373d62c5    invalidate_partition    vmlinux EXPORT_SYMBOL
+-0xd217e9e6    trace_set_clr_event     vmlinux EXPORT_SYMBOL_GPL
+-0x00e86db4    kick_process    vmlinux EXPORT_SYMBOL_GPL
+-0xa625110d    kmsg_dump_rewind        vmlinux EXPORT_SYMBOL_GPL
+-0x17eb0eee    v4l2_m2m_init   vmlinux EXPORT_SYMBOL_GPL
+-0xd153a267    drm_irq_uninstall       vmlinux EXPORT_SYMBOL
+-0x6ccf7bd7    __pv_phys_offset        vmlinux EXPORT_SYMBOL
+-0x6cf45a72    sk_release_kernel       vmlinux EXPORT_SYMBOL
+-0x7cff72b3    sg_miter_stop   vmlinux EXPORT_SYMBOL
+-0x0da10ec3    security_sock_graft     vmlinux EXPORT_SYMBOL
+-0xe601743b    jbd2_journal_init_jbd_inode     vmlinux EXPORT_SYMBOL
+-0xdd3916ac    _raw_spin_unlock_bh     vmlinux EXPORT_SYMBOL
+-0xb5ab5fe9    usb_function_register   vmlinux EXPORT_SYMBOL_GPL
+-0xa20bbbd7    xt_proto_init   vmlinux EXPORT_SYMBOL_GPL
+-0x13b715e2    blk_finish_plug vmlinux EXPORT_SYMBOL
+-0x0b1beb31    vmalloc_32_user vmlinux EXPORT_SYMBOL
+-0x85dfe0aa    fget_light      vmlinux EXPORT_SYMBOL
+-0x8bebc4a8    drm_master_put  vmlinux EXPORT_SYMBOL
+-0xf073bd48    nfc_hci_target_discovered       vmlinux EXPORT_SYMBOL
+-0x878ab3ce    sysctl_tcp_adv_win_scale        vmlinux EXPORT_SYMBOL
+-0x11e11bef    ip_local_out    vmlinux EXPORT_SYMBOL_GPL
+-0xafe96047    generic_permission      vmlinux EXPORT_SYMBOL
+-0x96123b65    iio_trigger_unregister  vmlinux EXPORT_SYMBOL
+-0xf7b01b50    gether_get_host_addr_cdc        vmlinux EXPORT_SYMBOL
+-0x3324e6d2    ehci_suspend    vmlinux EXPORT_SYMBOL_GPL
+-0x7ef61596    usb_hcd_check_unlink_urb        vmlinux EXPORT_SYMBOL_GPL
+-0x7ced7048    phy_device_free vmlinux EXPORT_SYMBOL
+-0x9afda3df    regcache_cache_bypass   vmlinux EXPORT_SYMBOL_GPL
+-0xd59668e6    unlock_flocks   vmlinux EXPORT_SYMBOL_GPL
+-0xb818e055    usbnet_open     vmlinux EXPORT_SYMBOL_GPL
+-0x4683093b    snd_ctl_notify  vmlinux EXPORT_SYMBOL
+-0x9d3aa376    blk_iopoll_init vmlinux EXPORT_SYMBOL
+-0x226a674d    atomic_notifier_chain_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0x0144d325    regmap_async_complete   vmlinux EXPORT_SYMBOL_GPL
+-0x27f4cbdb    uart_get_baud_rate      vmlinux EXPORT_SYMBOL
+-0x878175c4    secpath_dup     vmlinux EXPORT_SYMBOL
+-0x7931d788    snd_pcm_hw_constraint_step      vmlinux EXPORT_SYMBOL
+-0x36170e28    set_user_nice   vmlinux EXPORT_SYMBOL
+-0x45de06d1    iio_buffer_write_length vmlinux EXPORT_SYMBOL
+-0x5babbf10    media_device_unregister_entity  vmlinux EXPORT_SYMBOL_GPL
+-0xe593d0c8    usbnet_disconnect       vmlinux EXPORT_SYMBOL_GPL
+-0xb7e8ce46    exynos_drm_subdrv_close vmlinux EXPORT_SYMBOL_GPL
+-0xc29dc1ad    drm_framebuffer_init    vmlinux EXPORT_SYMBOL
+-0x7fe1a403    cfg80211_find_ie        vmlinux EXPORT_SYMBOL
+-0xa8469c88    netdev_notify_peers     vmlinux EXPORT_SYMBOL
+-0xe81978c6    splice_direct_to_actor  vmlinux EXPORT_SYMBOL
+-0xb5cb8145    hrtimer_get_res vmlinux EXPORT_SYMBOL_GPL
+-0x9a70b0fd    nf_nat_pptp_hook_inbound        vmlinux EXPORT_SYMBOL_GPL
+-0x2b9da7a4    genl_lock       vmlinux EXPORT_SYMBOL
+-0xb72e58d6    qdisc_class_hash_grow   vmlinux EXPORT_SYMBOL
+-0x0e59e8cf    sock_setsockopt vmlinux EXPORT_SYMBOL
+-0x20df2681    ida_simple_remove       vmlinux EXPORT_SYMBOL
+-0xbdef23a2    unlock_buffer   vmlinux EXPORT_SYMBOL
+-0x3b231b68    simple_transaction_release      vmlinux EXPORT_SYMBOL
+-0xad098b64    usb_unlocked_enable_lpm vmlinux EXPORT_SYMBOL_GPL
+-0x4b05e7ed    tty_port_close_start    vmlinux EXPORT_SYMBOL
+-0x14789075    dma_find_channel        vmlinux EXPORT_SYMBOL
+-0x77c05b09    fb_find_mode    vmlinux EXPORT_SYMBOL
+-0x01010c6d    klist_add_before        vmlinux EXPORT_SYMBOL_GPL
+-0x292c29ad    nfulnl_log_packet       vmlinux EXPORT_SYMBOL_GPL
+-0x521b36b5    qdisc_put_rtab  vmlinux EXPORT_SYMBOL
+-0x69c66f79    crypto_attr_alg2        vmlinux EXPORT_SYMBOL_GPL
+-0x341dbfa3    __per_cpu_offset        vmlinux EXPORT_SYMBOL
+-0x8953f8ff    __tracepoint_kmem_cache_alloc   vmlinux EXPORT_SYMBOL
+-0x7e0ef97c    regmap_irq_get_domain   vmlinux EXPORT_SYMBOL_GPL
+-0x437ff921    subsys_find_device_by_id        vmlinux EXPORT_SYMBOL_GPL
+-0x975e0663    set_sig_addr_hook       vmlinux EXPORT_SYMBOL_GPL
+-0xe86f0da8    proto_register  vmlinux EXPORT_SYMBOL
+-0xb838d98e    event_storage_mutex     vmlinux EXPORT_SYMBOL_GPL
+-0x9ca1dc35    vb2_fop_mmap    vmlinux EXPORT_SYMBOL_GPL
+-0xde1a5959    rtc_irq_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0xbeca75ff    drm_crtc_helper_set_mode        vmlinux EXPORT_SYMBOL
+-0x65f850bc    tty_wakeup      vmlinux EXPORT_SYMBOL_GPL
+-0xf4743f88    amba_ahb_device_add     vmlinux EXPORT_SYMBOL_GPL
+-0xa994f545    check_disk_size_change  vmlinux EXPORT_SYMBOL
+-0x455293f6    down_read       vmlinux EXPORT_SYMBOL
+-0x7eaf8e7a    v4l2_detect_gtf vmlinux EXPORT_SYMBOL_GPL
+-0x53105839    v4l2_detect_cvt vmlinux EXPORT_SYMBOL_GPL
+-0x6a41ea71    v4l2_clk_get_rate       vmlinux EXPORT_SYMBOL
+-0xc50c3f79    v4l2_clk_set_rate       vmlinux EXPORT_SYMBOL
+-0x52bc9e2a    drm_plane_cleanup       vmlinux EXPORT_SYMBOL
+-0x0d4cb82a    km_report       vmlinux EXPORT_SYMBOL
+-0xcffe8e42    __napi_complete vmlinux EXPORT_SYMBOL
+-0xb17c5844    skb_copy_expand vmlinux EXPORT_SYMBOL
+-0xaaaa5788    blk_queue_softirq_done  vmlinux EXPORT_SYMBOL
+-0x43a762e5    d_lookup        vmlinux EXPORT_SYMBOL
+-0xebc525f4    iio_triggered_buffer_cleanup    vmlinux EXPORT_SYMBOL
+-0xabd0c91c    rtc_time_to_tm  vmlinux EXPORT_SYMBOL
+-0x70f3f9b2    dmam_free_coherent      vmlinux EXPORT_SYMBOL
+-0xba361646    transport_setup_device  vmlinux EXPORT_SYMBOL_GPL
+-0x950ee7d1    fb_find_logo    vmlinux EXPORT_SYMBOL_GPL
+-0x20294ce8    genl_unregister_mc_group        vmlinux EXPORT_SYMBOL
+-0x1d7aabfd    path_is_under   vmlinux EXPORT_SYMBOL
+-0x17975413    iio_map_array_register  vmlinux EXPORT_SYMBOL_GPL
+-0xf811e69d    scsi_eh_flush_done_q    vmlinux EXPORT_SYMBOL
+-0x8b95a59f    xt_hook_unlink  vmlinux EXPORT_SYMBOL_GPL
+-0x557cb7c6    skb_morph       vmlinux EXPORT_SYMBOL_GPL
+-0x02ef742b    percpu_counter_set      vmlinux EXPORT_SYMBOL
+-0x03ae21fb    mmc_erase       vmlinux EXPORT_SYMBOL
+-0x7c46233a    cpufreq_quick_get       vmlinux EXPORT_SYMBOL
+-0xa4f8a168    dm_underlying_device_busy       vmlinux EXPORT_SYMBOL_GPL
+-0x1d41eadc    v4l2_ctrl_s_ctrl        vmlinux EXPORT_SYMBOL
+-0xa11295ab    serio_unregister_port   vmlinux EXPORT_SYMBOL
+-0x11065515    drm_mode_equal  vmlinux EXPORT_SYMBOL
+-0x4c47ec15    klist_add_head  vmlinux EXPORT_SYMBOL_GPL
+-0x68a24153    snd_pcm_format_physical_width   vmlinux EXPORT_SYMBOL
+-0xb6822a33    radix_tree_gang_lookup_tag      vmlinux EXPORT_SYMBOL
+-0xdaa16b82    of_clk_get      vmlinux EXPORT_SYMBOL
+-0x5c625801    scsi_remove_host        vmlinux EXPORT_SYMBOL
+-0xa7de1327    flush_dcache_page       vmlinux EXPORT_SYMBOL
+-0x2d6507b5    _find_next_zero_bit_le  vmlinux EXPORT_SYMBOL
+-0xf26e1c06    snd_soc_suspend vmlinux EXPORT_SYMBOL_GPL
+-0xc213a12a    devm_ioremap_nocache    vmlinux EXPORT_SYMBOL
+-0xb43a5300    sync_dirty_buffer       vmlinux EXPORT_SYMBOL
+-0xd303fa4e    clk_notifier_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x496c3d67    v4l2_querymenu  vmlinux EXPORT_SYMBOL
+-0x02b44bb5    scsi_is_host_device     vmlinux EXPORT_SYMBOL
+-0x91c9a325    bt_to_errno     vmlinux EXPORT_SYMBOL
+-0x86a85b06    tcp_reno_ssthresh       vmlinux EXPORT_SYMBOL_GPL
+-0xfc5c6b3e    netlink_has_listeners   vmlinux EXPORT_SYMBOL_GPL
+-0xe075d6eb    iter_div_u64_rem        vmlinux EXPORT_SYMBOL
+-0xcf0e08ad    filter_current_check_discard    vmlinux EXPORT_SYMBOL_GPL
+-0x5afb47fc    of_irq_to_resource_table        vmlinux EXPORT_SYMBOL_GPL
+-0xf1421d13    drm_mode_sort   vmlinux EXPORT_SYMBOL
+-0xd06ec95f    dma_supported   vmlinux EXPORT_SYMBOL
+-0xf1b80226    nf_nat_seq_adjust_hook  vmlinux EXPORT_SYMBOL_GPL
+-0xf4c02b65    inode_init_once vmlinux EXPORT_SYMBOL
+-0x369fcd70    tracing_snapshot        vmlinux EXPORT_SYMBOL_GPL
+-0x73d69364    ring_buffer_change_overwrite    vmlinux EXPORT_SYMBOL_GPL
+-0x339d542a    __srcu_notifier_call_chain      vmlinux EXPORT_SYMBOL_GPL
+-0xe2d3d0b9    v4l2_ctrl_sub_ev_ops    vmlinux EXPORT_SYMBOL
+-0xee129bef    usb_alloc_urb   vmlinux EXPORT_SYMBOL_GPL
+-0x64a127a3    spi_setup       vmlinux EXPORT_SYMBOL_GPL
+-0x3a8da0aa    nf_ip6_checksum vmlinux EXPORT_SYMBOL
+-0xb46a6cbb    scsi_cmd_ioctl  vmlinux EXPORT_SYMBOL
+-0xf7d52055    iio_bus_type    vmlinux EXPORT_SYMBOL
+-0x75b9f8b8    device_move     vmlinux EXPORT_SYMBOL_GPL
+-0x34dc9b87    neigh_seq_stop  vmlinux EXPORT_SYMBOL
+-0x82b802b2    snd_soc_dai_set_pll     vmlinux EXPORT_SYMBOL_GPL
+-0x0f4c91ed    ns_to_timespec  vmlinux EXPORT_SYMBOL
+-0xca34e63d    iio_triggered_buffer_postenable vmlinux EXPORT_SYMBOL
+-0x8d3ecd41    drm_core_ioremapfree    vmlinux EXPORT_SYMBOL
+-0xed93f29e    __kunmap_atomic vmlinux EXPORT_SYMBOL
+-0xe7cd755a    nf_ct_dying_timeout     vmlinux EXPORT_SYMBOL_GPL
+-0xe5452cbf    dev_mc_del_global       vmlinux EXPORT_SYMBOL
+-0x1a77ed38    dev_mc_add_global       vmlinux EXPORT_SYMBOL
+-0x7b4901f5    snd_soc_add_platform    vmlinux EXPORT_SYMBOL_GPL
+-0xdff7c9ce    blocking_notifier_chain_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0x346127a7    drm_global_item_ref     vmlinux EXPORT_SYMBOL
+-0xf763bb6d    drm_framebuffer_cleanup vmlinux EXPORT_SYMBOL
+-0x4a6b641b    fifo_create_dflt        vmlinux EXPORT_SYMBOL
+-0x3a39f5ed    neigh_table_init        vmlinux EXPORT_SYMBOL
+-0xc7207cfe    blk_queue_segment_boundary      vmlinux EXPORT_SYMBOL
+-0x183b1236    blk_stop_queue  vmlinux EXPORT_SYMBOL
+-0x632b18ed    blkcipher_walk_virt_block       vmlinux EXPORT_SYMBOL_GPL
+-0x68ecff32    sysfs_create_link       vmlinux EXPORT_SYMBOL_GPL
+-0x2bc64f3b    task_active_pid_ns      vmlinux EXPORT_SYMBOL_GPL
+-0xda83d7a1    mmc_register_driver     vmlinux EXPORT_SYMBOL
+-0x85e9caff    exynos4x12_cpufreq_init vmlinux EXPORT_SYMBOL
+-0xf75603a3    exynos4210_cpufreq_init vmlinux EXPORT_SYMBOL
+-0x38a9c2c7    input_ff_effect_from_user       vmlinux EXPORT_SYMBOL_GPL
+-0x4f92c146    mfd_cell_enable vmlinux EXPORT_SYMBOL
+-0xeacc50bc    attribute_container_register    vmlinux EXPORT_SYMBOL_GPL
+-0x53465c39    drm_vblank_count_and_time       vmlinux EXPORT_SYMBOL
+-0xc0e23731    inetpeer_invalidate_tree        vmlinux EXPORT_SYMBOL
+-0x7d1904b2    __neigh_create  vmlinux EXPORT_SYMBOL
+-0x6d294e43    clock_t_to_jiffies      vmlinux EXPORT_SYMBOL
+-0x327bf883    of_can_translate_address        vmlinux EXPORT_SYMBOL
+-0x6232e48e    power_supply_powers     vmlinux EXPORT_SYMBOL_GPL
+-0x15b9125f    hdmi_avi_infoframe_pack vmlinux EXPORT_SYMBOL
+-0x48e7c422    fanout_mutex    vmlinux EXPORT_SYMBOL_GPL
+-0xdf050302    skb_mac_gso_segment     vmlinux EXPORT_SYMBOL
+-0x4afb74d0    snd_pcm_lib_preallocate_pages_for_all   vmlinux EXPORT_SYMBOL
+-0xf874d572    crypto_larval_alloc     vmlinux EXPORT_SYMBOL_GPL
+-0x540a73a6    seq_release     vmlinux EXPORT_SYMBOL
+-0xb3826d47    insert_inode_locked     vmlinux EXPORT_SYMBOL
+-0x1866cec2    ring_buffer_size        vmlinux EXPORT_SYMBOL_GPL
+-0x838b13e7    ring_buffer_free        vmlinux EXPORT_SYMBOL_GPL
+-0x41d8cf05    module_layout   vmlinux EXPORT_SYMBOL
+-0xdbb5a9f5    drm_ht_remove_item      vmlinux EXPORT_SYMBOL
+-0x654a5368    drm_vblank_off  vmlinux EXPORT_SYMBOL
+-0xb3e9e167    drm_vblank_get  vmlinux EXPORT_SYMBOL
+-0xa795c78d    pl330_filter    vmlinux EXPORT_SYMBOL
+-0x0335cb43    __sb_start_write        vmlinux EXPORT_SYMBOL
+-0x6955eb5f    hidinput_disconnect     vmlinux EXPORT_SYMBOL_GPL
+-0xd49dd4f4    cfg80211_cqm_txe_notify vmlinux EXPORT_SYMBOL
+-0xcc1fb551    baswap  vmlinux EXPORT_SYMBOL
+-0x653aa466    __blk_put_request       vmlinux EXPORT_SYMBOL_GPL
+-0x99401626    elv_rb_latter_request   vmlinux EXPORT_SYMBOL
+-0x0da68fbf    sysfs_create_bin_file   vmlinux EXPORT_SYMBOL_GPL
+-0x27fa66e1    nr_free_buffer_pages    vmlinux EXPORT_SYMBOL_GPL
+-0x7452437c    cgroup_taskset_next     vmlinux EXPORT_SYMBOL_GPL
+-0xd2e7fb21    mod_delayed_work_on     vmlinux EXPORT_SYMBOL_GPL
+-0x3d388324    dpm_resume_end  vmlinux EXPORT_SYMBOL_GPL
+-0xfda2fc6f    pinctrl_remove_gpio_range       vmlinux EXPORT_SYMBOL_GPL
+-0x98c9f584    klist_init      vmlinux EXPORT_SYMBOL_GPL
+-0x72e52881    xfrm_state_unregister_afinfo    vmlinux EXPORT_SYMBOL
+-0xec57ea15    snd_card_unref  vmlinux EXPORT_SYMBOL
+-0x6cdc5c6b    nla_strlcpy     vmlinux EXPORT_SYMBOL
+-0xa46f2f1b    kstrtouint      vmlinux EXPORT_SYMBOL
+-0x315c8d71    blk_init_queue_node     vmlinux EXPORT_SYMBOL
+-0x83211609    up_write        vmlinux EXPORT_SYMBOL
+-0x19610e1f    cpu_all_bits    vmlinux EXPORT_SYMBOL
+-0x4f248523    of_find_node_by_name    vmlinux EXPORT_SYMBOL
+-0x14d0738e    dm_noflush_suspending   vmlinux EXPORT_SYMBOL_GPL
+-0x488cee4b    serial8250_do_pm        vmlinux EXPORT_SYMBOL
+-0xe4e38519    tcf_hash_release        vmlinux EXPORT_SYMBOL
+-0xf1298271    free_buffer_head        vmlinux EXPORT_SYMBOL
+-0x08559b9a    fget    vmlinux EXPORT_SYMBOL
+-0x4a57b339    wait_for_completion_io_timeout  vmlinux EXPORT_SYMBOL
+-0xcccd9343    mmc_gpio_get_ro vmlinux EXPORT_SYMBOL
+-0xa3959367    mmc_gpio_get_cd vmlinux EXPORT_SYMBOL
+-0xbc3a2d91    cpufreq_cpu_put vmlinux EXPORT_SYMBOL_GPL
+-0x238dd120    cpufreq_cpu_get vmlinux EXPORT_SYMBOL_GPL
+-0xfe7c6819    scsi_target_block       vmlinux EXPORT_SYMBOL_GPL
+-0x42488405    scsi_prep_state_check   vmlinux EXPORT_SYMBOL
+-0xf4b2e991    drm_mm_put_block        vmlinux EXPORT_SYMBOL
+-0x688bd4c5    snd_ctl_boolean_mono_info       vmlinux EXPORT_SYMBOL
+-0xe1e281d6    jbd2_log_start_commit   vmlinux EXPORT_SYMBOL
+-0x9130f1c7    remove_proc_subtree     vmlinux EXPORT_SYMBOL
+-0xfa1eb910    unregister_syscore_ops  vmlinux EXPORT_SYMBOL_GPL
+-0x4d7f9839    snd_soc_of_parse_card_name      vmlinux EXPORT_SYMBOL_GPL
+-0x44e9a829    match_token     vmlinux EXPORT_SYMBOL
+-0x49b26c63    jbd2_journal_abort      vmlinux EXPORT_SYMBOL
+-0x1a323362    __ftrace_vbprintk       vmlinux EXPORT_SYMBOL_GPL
+-0x0a958ed4    down_write      vmlinux EXPORT_SYMBOL
+-0x706b3a33    cpufreq_frequency_table_get_attr        vmlinux EXPORT_SYMBOL_GPL
+-0xbdba9828    hdmi_audio_infoframe_pack       vmlinux EXPORT_SYMBOL
+-0x09c64fbd    ieee80211_frequency_to_channel  vmlinux EXPORT_SYMBOL
+-0x64d41d38    ip_route_output_flow    vmlinux EXPORT_SYMBOL_GPL
+-0xc23832c5    snd_soc_add_card_controls       vmlinux EXPORT_SYMBOL_GPL
+-0x43326227    posix_test_lock vmlinux EXPORT_SYMBOL
+-0xd7289dfe    kill_block_super        vmlinux EXPORT_SYMBOL
+-0x2b0f3b97    flush_signals   vmlinux EXPORT_SYMBOL
+-0x1b9e0ff1    scsilun_to_int  vmlinux EXPORT_SYMBOL
+-0x97a0de2c    drm_prime_pages_to_sg   vmlinux EXPORT_SYMBOL
+-0x0442abb5    __inet_stream_connect   vmlinux EXPORT_SYMBOL
+-0xc6f7d745    nf_ct_remove_expectations       vmlinux EXPORT_SYMBOL_GPL
+-0xecdea3ba    neigh_lookup_nodev      vmlinux EXPORT_SYMBOL
+-0x10c58227    kernel_setsockopt       vmlinux EXPORT_SYMBOL
+-0x8fd29b0f    kernel_getsockopt       vmlinux EXPORT_SYMBOL
+-0xed5cfaa9    kernel_sock_ioctl       vmlinux EXPORT_SYMBOL
+-0x8ffdb3b8    crc16   vmlinux EXPORT_SYMBOL
+-0xadc7f742    mb_cache_entry_insert   vmlinux EXPORT_SYMBOL
+-0x4e1e8913    kallsyms_on_each_symbol vmlinux EXPORT_SYMBOL_GPL
+-0xf82f3657    work_on_cpu     vmlinux EXPORT_SYMBOL_GPL
+-0x459e133f    v4l2_m2m_get_curr_priv  vmlinux EXPORT_SYMBOL
+-0x4dd51c13    phy_pm_runtime_allow    vmlinux EXPORT_SYMBOL_GPL
+-0xcbbaba0b    nf_tproxy_assign_sock   vmlinux EXPORT_SYMBOL_GPL
+-0x3e220367    nfnetlink_unicast       vmlinux EXPORT_SYMBOL_GPL
+-0x55504881    snd_mixer_oss_ioctl_card        vmlinux EXPORT_SYMBOL
+-0xab694444    bsearch vmlinux EXPORT_SYMBOL
+-0x662edc7c    blk_put_request vmlinux EXPORT_SYMBOL
+-0x6ca4bf88    async_synchronize_full_domain   vmlinux EXPORT_SYMBOL_GPL
+-0x12456a92    iommu_iova_to_phys      vmlinux EXPORT_SYMBOL_GPL
+-0xdc7b411a    dev_pm_qos_hide_latency_limit   vmlinux EXPORT_SYMBOL_GPL
+-0x28441b73    drm_get_last_vbltimestamp       vmlinux EXPORT_SYMBOL
+-0x83eab4ef    crypto_create_tfm       vmlinux EXPORT_SYMBOL_GPL
+-0x42e2c53b    nf_conntrack_in vmlinux EXPORT_SYMBOL_GPL
+-0x3ea1d70f    sock_queue_rcv_skb      vmlinux EXPORT_SYMBOL
+-0xe7820ad2    snd_pcm_lib_preallocate_free_for_all    vmlinux EXPORT_SYMBOL
+-0x754dac78    blk_limits_io_min       vmlinux EXPORT_SYMBOL
+-0x0cd9cfec    sysfs_remove_files      vmlinux EXPORT_SYMBOL_GPL
+-0xc237047a    mapping_tagged  vmlinux EXPORT_SYMBOL
+-0xd777c9b7    iio_device_alloc        vmlinux EXPORT_SYMBOL
+-0xd688716b    dm_kcopyd_client_create vmlinux EXPORT_SYMBOL
+-0x2502c67c    v4l2_fh_add     vmlinux EXPORT_SYMBOL_GPL
+-0x088675f7    usbnet_write_cmd_async  vmlinux EXPORT_SYMBOL_GPL
+-0xb35659de    drm_mode_remove vmlinux EXPORT_SYMBOL
+-0x16acff8a    devm_of_pwm_get vmlinux EXPORT_SYMBOL_GPL
+-0xd2bd22d2    s3c_gpio_getpull        vmlinux EXPORT_SYMBOL
+-0x5fbecd25    s3c_gpio_setpull        vmlinux EXPORT_SYMBOL
+-0x67c2fa54    __copy_to_user  vmlinux EXPORT_SYMBOL
+-0x7c6a49ce    unix_table_lock vmlinux EXPORT_SYMBOL_GPL
+-0x38d60861    put_disk        vmlinux EXPORT_SYMBOL
+-0x871bcaa4    irq_find_host   vmlinux EXPORT_SYMBOL_GPL
+-0xd9605d4c    add_timer       vmlinux EXPORT_SYMBOL
+-0xea97fb5e    usbhid_set_leds vmlinux EXPORT_SYMBOL_GPL
+-0x70915b51    serio_interrupt vmlinux EXPORT_SYMBOL
+-0x92a772c3    usbnet_purge_paused_rxq vmlinux EXPORT_SYMBOL_GPL
+-0xf6bb4729    color_table     vmlinux EXPORT_SYMBOL
+-0x8c637d43    irq_cpu_rmap_add        vmlinux EXPORT_SYMBOL
+-0x9ba7089d    argv_split      vmlinux EXPORT_SYMBOL
+-0x34f3484e    security_tun_dev_attach_queue   vmlinux EXPORT_SYMBOL
+-0x1a1431fd    _raw_spin_unlock_irq    vmlinux EXPORT_SYMBOL
+-0x7c08f605    hid_allocate_device     vmlinux EXPORT_SYMBOL_GPL
+-0xe5a8e6b5    spi_sync        vmlinux EXPORT_SYMBOL_GPL
+-0xcc69f0f8    dma_sync_wait   vmlinux EXPORT_SYMBOL
+-0x43e33157    blk_queue_max_hw_sectors        vmlinux EXPORT_SYMBOL
+-0x8ea0cdd5    drm_add_modes_noedid    vmlinux EXPORT_SYMBOL
+-0x9a8318ef    v7_coherent_kern_range  vmlinux EXPORT_SYMBOL
+-0x5de3ad52    cfg80211_ref_bss        vmlinux EXPORT_SYMBOL
+-0xdc1b2765    crypto_aes_set_key      vmlinux EXPORT_SYMBOL_GPL
+-0x5086ac3a    alg_test        vmlinux EXPORT_SYMBOL_GPL
+-0x9c35fb24    jbd2__journal_restart   vmlinux EXPORT_SYMBOL
+-0xbef43296    console_conditional_schedule    vmlinux EXPORT_SYMBOL
+-0xa71c1b98    bus_set_iommu   vmlinux EXPORT_SYMBOL_GPL
+-0x8e801428    bus_create_file vmlinux EXPORT_SYMBOL_GPL
+-0x8fc34c2d    drm_warn_on_modeset_not_all_locked      vmlinux EXPORT_SYMBOL
+-0x2e0a06e3    snd_unregister_device   vmlinux EXPORT_SYMBOL
+-0x9caaf6cf    blkdev_issue_discard    vmlinux EXPORT_SYMBOL
+-0x3e6444e8    crypto_unregister_pcomp vmlinux EXPORT_SYMBOL_GPL
+-0xc1d19fdd    debugfs_create_symlink  vmlinux EXPORT_SYMBOL_GPL
+-0x9bd7640e    fat_detach      vmlinux EXPORT_SYMBOL_GPL
+-0x698a899f    ring_buffer_peek        vmlinux EXPORT_SYMBOL_GPL
+-0xe2e7840d    regmap_init_mmio_clk    vmlinux EXPORT_SYMBOL_GPL
+-0xe556d687    xt_request_find_match   vmlinux EXPORT_SYMBOL_GPL
+-0xcf25e6b2    xattr_getsecurity       vmlinux EXPORT_SYMBOL_GPL
+-0x6228c21f    smp_call_function_single        vmlinux EXPORT_SYMBOL
+-0x5f324ec1    drm_ioctl       vmlinux EXPORT_SYMBOL
+-0x4d9b652b    rb_erase        vmlinux EXPORT_SYMBOL
+-0xcc71d484    drm_mode_duplicate      vmlinux EXPORT_SYMBOL
+-0x2b02560b    devm_pwm_put    vmlinux EXPORT_SYMBOL_GPL
+-0x3659d5ac    devm_phy_get    vmlinux EXPORT_SYMBOL_GPL
+-0xaafdc258    strcasecmp      vmlinux EXPORT_SYMBOL
+-0xc296567b    save_mount_options      vmlinux EXPORT_SYMBOL
+-0xbade32c7    clockevents_register_device     vmlinux EXPORT_SYMBOL_GPL
+-0xfb8a84a4    drm_mm_get_block_range_generic  vmlinux EXPORT_SYMBOL
+-0x058b582a    vt_get_leds     vmlinux EXPORT_SYMBOL_GPL
+-0xb2a0603e    nci_recv_frame  vmlinux EXPORT_SYMBOL
+-0xc0240dd4    nf_conntrack_set_hashsize       vmlinux EXPORT_SYMBOL_GPL
+-0x45c8cd86    ifla_policy     vmlinux EXPORT_SYMBOL
+-0xd251d7b0    security_socket_getpeersec_dgram        vmlinux EXPORT_SYMBOL
+-0xf05e203c    set_blocksize   vmlinux EXPORT_SYMBOL
+-0xc1c995a0    block_page_mkwrite      vmlinux EXPORT_SYMBOL
+-0x85b9e216    set_timer_slack vmlinux EXPORT_SYMBOL_GPL
+-0x2665c0a3    vb2_qbuf        vmlinux EXPORT_SYMBOL_GPL
+-0x9abe8d18    video_usercopy  vmlinux EXPORT_SYMBOL
+-0x1d93e603    tty_unthrottle  vmlinux EXPORT_SYMBOL
+-0x1142511d    crypto_spawn_tfm        vmlinux EXPORT_SYMBOL_GPL
+-0xeb9ddf6d    security_inode_notifysecctx     vmlinux EXPORT_SYMBOL
+-0x68df960a    generic_error_remove_page       vmlinux EXPORT_SYMBOL
+-0x7000dc34    class_compat_remove_link        vmlinux EXPORT_SYMBOL_GPL
+-0x816dee03    uart_unregister_driver  vmlinux EXPORT_SYMBOL
+-0x0acf7679    dma_issue_pending_all   vmlinux EXPORT_SYMBOL
+-0x8792d764    l2cap_conn_get  vmlinux EXPORT_SYMBOL
+-0xcf2890b2    ipv6_chk_prefix vmlinux EXPORT_SYMBOL
+-0x616ff33b    ip6_dst_lookup_flow     vmlinux EXPORT_SYMBOL_GPL
+-0x3e963d19    inet_csk_search_req     vmlinux EXPORT_SYMBOL_GPL
+-0xdd632e58    inet_unhash     vmlinux EXPORT_SYMBOL_GPL
+-0x98e40edf    nf_ct_nat_offset        vmlinux EXPORT_SYMBOL_GPL
+-0x0a7ed556    blk_execute_rq  vmlinux EXPORT_SYMBOL
+-0x44408a4a    mdio_bus_type   vmlinux EXPORT_SYMBOL
+-0xac74a2a9    ip6_xmit        vmlinux EXPORT_SYMBOL
+-0x411d75db    ip_tunnel_init  vmlinux EXPORT_SYMBOL_GPL
+-0x7a442539    tcf_exts_dump   vmlinux EXPORT_SYMBOL
+-0x13307fde    vsscanf vmlinux EXPORT_SYMBOL
+-0xcc368515    jbd2_journal_unlock_updates     vmlinux EXPORT_SYMBOL
+-0x21bfb720    seq_open_net    vmlinux EXPORT_SYMBOL_GPL
+-0x82d79b51    sysctl_vfs_cache_pressure       vmlinux EXPORT_SYMBOL_GPL
+-0x04486e88    rcu_batches_completed   vmlinux EXPORT_SYMBOL_GPL
+-0x7c1372e8    panic   vmlinux EXPORT_SYMBOL
+-0x9808f34e    dev_pm_qos_expose_flags vmlinux EXPORT_SYMBOL_GPL
+-0x544b5ea8    pwm_disable     vmlinux EXPORT_SYMBOL_GPL
+-0x5c265cba    sg_init_one     vmlinux EXPORT_SYMBOL
+-0x12da5bb2    __kmalloc       vmlinux EXPORT_SYMBOL
+-0x28d6861d    __vmalloc       vmlinux EXPORT_SYMBOL
+-0x5db7b0d3    led_trigger_remove      vmlinux EXPORT_SYMBOL_GPL
+-0x83b38ee6    kobject_init_and_add    vmlinux EXPORT_SYMBOL_GPL
+-0x757cdadf    usbnet_get_ethernet_addr        vmlinux EXPORT_SYMBOL_GPL
+-0x43a286d1    drm_prime_remove_buf_handle     vmlinux EXPORT_SYMBOL
+-0xea8ddd89    __ip_select_ident       vmlinux EXPORT_SYMBOL
+-0x1f984870    skb_gro_receive vmlinux EXPORT_SYMBOL_GPL
+-0x48f8aa53    flock_lock_file_wait    vmlinux EXPORT_SYMBOL
+-0x05e067d7    __media_entity_remove_links     vmlinux EXPORT_SYMBOL_GPL
+-0xe7cb87e4    xt_find_match   vmlinux EXPORT_SYMBOL
+-0x9d62c35b    nfq_ct_hook     vmlinux EXPORT_SYMBOL_GPL
+-0xe12b4adb    __skb_warn_lro_forwarding       vmlinux EXPORT_SYMBOL
+-0x471eeac6    snd_soc_platform_write  vmlinux EXPORT_SYMBOL_GPL
+-0x71c90087    memcmp  vmlinux EXPORT_SYMBOL
+-0x4881d505    idr_for_each    vmlinux EXPORT_SYMBOL
+-0x79b33953    shash_ahash_digest      vmlinux EXPORT_SYMBOL_GPL
+-0xcf1d92aa    locks_init_lock vmlinux EXPORT_SYMBOL
+-0x11cfbadb    bio_add_pc_page vmlinux EXPORT_SYMBOL
+-0x2917e251    split_page      vmlinux EXPORT_SYMBOL_GPL
+-0xda53403f    v4l2_m2m_ctx_init       vmlinux EXPORT_SYMBOL_GPL
+-0x4f4d910e    regmap_init     vmlinux EXPORT_SYMBOL_GPL
+-0xb2a9634b    regmap_exit     vmlinux EXPORT_SYMBOL_GPL
+-0xe16838c2    drm_mm_search_free_in_range_generic     vmlinux EXPORT_SYMBOL
+-0xf05ffa15    fb_var_to_videomode     vmlinux EXPORT_SYMBOL
+-0xab707907    inet6_del_offload       vmlinux EXPORT_SYMBOL
+-0x13e229c2    nf_ct_helper_expectfn_find_by_name      vmlinux EXPORT_SYMBOL_GPL
+-0x1f0547c1    netif_stacked_transfer_operstate        vmlinux EXPORT_SYMBOL
+-0xd435e67a    snd_card_set_id vmlinux EXPORT_SYMBOL
+-0xc7236f77    d_alloc_name    vmlinux EXPORT_SYMBOL
+-0x2f3857e2    _raw_write_lock_irqsave vmlinux EXPORT_SYMBOL
+-0x37c199e6    serio_reconnect vmlinux EXPORT_SYMBOL
+-0x6754f715    drm_fb_helper_fill_fix  vmlinux EXPORT_SYMBOL
+-0xc6df7ef6    cont_write_begin        vmlinux EXPORT_SYMBOL
+-0x1c97e3ec    vfs_readdir     vmlinux EXPORT_SYMBOL
+-0xbdd295f0    trace_vprintk   vmlinux EXPORT_SYMBOL_GPL
+-0x8faa4598    of_translate_address    vmlinux EXPORT_SYMBOL
+-0x0699040f    drm_encoder_cleanup     vmlinux EXPORT_SYMBOL
+-0x7f8c7b48    dma_async_memcpy_buf_to_buf     vmlinux EXPORT_SYMBOL
+-0x1ed85a8d    pinctrl_dev_get_drvdata vmlinux EXPORT_SYMBOL_GPL
+-0x881039d0    zlib_inflate    vmlinux EXPORT_SYMBOL
+-0x3771b461    crc_ccitt       vmlinux EXPORT_SYMBOL
+-0xa43b1297    vscnprintf      vmlinux EXPORT_SYMBOL
+-0x166e361d    blk_recount_segments    vmlinux EXPORT_SYMBOL
+-0x887ece4a    simple_statfs   vmlinux EXPORT_SYMBOL
+-0x617643a2    param_set_long  vmlinux EXPORT_SYMBOL
+-0x6c69a9be    xfrm6_tunnel_deregister vmlinux EXPORT_SYMBOL
+-0x3b850073    km_policy_notify        vmlinux EXPORT_SYMBOL
+-0x10cc1e43    xfrm4_tunnel_deregister vmlinux EXPORT_SYMBOL
+-0xc0f95b9e    ip_mc_join_group        vmlinux EXPORT_SYMBOL
+-0xdb760f52    __kfifo_free    vmlinux EXPORT_SYMBOL
+-0x3a288321    configfs_undepend_item  vmlinux EXPORT_SYMBOL
+-0x2cc83b45    usb_string      vmlinux EXPORT_SYMBOL_GPL
+-0x98442d13    inet_csk_reqsk_queue_hash_add   vmlinux EXPORT_SYMBOL_GPL
+-0x8d33679f    nf_ct_unexpect_related  vmlinux EXPORT_SYMBOL_GPL
+-0xe6e1c5fe    uuid_be_gen     vmlinux EXPORT_SYMBOL_GPL
+-0x289ea691    debugfs_remove  vmlinux EXPORT_SYMBOL_GPL
+-0xbb4e9599    lease_modify    vmlinux EXPORT_SYMBOL
+-0x2fb6e20e    drop_nlink      vmlinux EXPORT_SYMBOL
+-0xdfaa6b6b    v4l2_ctrl_radio_filter  vmlinux EXPORT_SYMBOL
+-0xa3675712    xfrm_dst_ifdown vmlinux EXPORT_SYMBOL
+-0x0d9bae4b    nf_nat_l4proto_nlattr_to_range  vmlinux EXPORT_SYMBOL_GPL
+-0xc17f8f83    neigh_seq_start vmlinux EXPORT_SYMBOL
+-0x6e7943ec    iommu_group_id  vmlinux EXPORT_SYMBOL_GPL
+-0x1aef1e27    eth_header_cache_update vmlinux EXPORT_SYMBOL
+-0xd800dc59    snd_pcm_hw_constraint_ratdens   vmlinux EXPORT_SYMBOL
+-0xd1157735    release_and_free_resource       vmlinux EXPORT_SYMBOL
+-0xb31526ee    sg_copy_from_buffer     vmlinux EXPORT_SYMBOL
+-0x73e20c1c    strlcpy vmlinux EXPORT_SYMBOL
+-0x328a05f1    strncpy vmlinux EXPORT_SYMBOL
+-0x8abacc47    get_max_files   vmlinux EXPORT_SYMBOL_GPL
+-0xae0f6b4e    regulator_unregister_notifier   vmlinux EXPORT_SYMBOL_GPL
+-0x386f5a4e    tcf_em_tree_destroy     vmlinux EXPORT_SYMBOL
+-0x97b4500c    __tracepoint_kmem_cache_free    vmlinux EXPORT_SYMBOL
+-0x4a69690c    scsi_release_buffers    vmlinux EXPORT_SYMBOL
+-0xf195c682    fb_invert_cmaps vmlinux EXPORT_SYMBOL
+-0xab156bb5    kern_mount_data vmlinux EXPORT_SYMBOL_GPL
+-0x1902f934    __init_kthread_worker   vmlinux EXPORT_SYMBOL_GPL
+-0xdac0df4a    driver_create_file      vmlinux EXPORT_SYMBOL_GPL
+-0x083eb21c    rfkill_unregister       vmlinux EXPORT_SYMBOL
+-0x3e52c876    blk_requeue_request     vmlinux EXPORT_SYMBOL
+-0xdca5d880    insert_inode_locked4    vmlinux EXPORT_SYMBOL
+-0x41482d8b    strndup_user    vmlinux EXPORT_SYMBOL
+-0xddd58dc0    ring_buffer_reset       vmlinux EXPORT_SYMBOL_GPL
+-0x6b172795    media_entity_graph_walk_next    vmlinux EXPORT_SYMBOL_GPL
+-0x0591a4d1    usb_ep_autoconfig_ss    vmlinux EXPORT_SYMBOL_GPL
+-0x4b076147    uncache_firmware        vmlinux EXPORT_SYMBOL_GPL
+-0x098b71c6    fb_dealloc_cmap vmlinux EXPORT_SYMBOL
+-0x83d1444a    crypto_init_spawn       vmlinux EXPORT_SYMBOL_GPL
+-0x60061dd7    mount_nodev     vmlinux EXPORT_SYMBOL
+-0x7bb32751    pagevec_lookup  vmlinux EXPORT_SYMBOL
+-0x47b6a10f    ftrace_print_symbols_seq        vmlinux EXPORT_SYMBOL
+-0x8664f62e    cpufreq_update_policy   vmlinux EXPORT_SYMBOL
+-0x29f39077    pwmchip_remove  vmlinux EXPORT_SYMBOL_GPL
+-0x905baf48    xfrm_find_acq   vmlinux EXPORT_SYMBOL
+-0x9487bc19    eth_mac_addr    vmlinux EXPORT_SYMBOL
+-0xad1ed84c    unregister_hw_breakpoint        vmlinux EXPORT_SYMBOL_GPL
+-0x993805c1    scsi_scan_host  vmlinux EXPORT_SYMBOL
+-0x7a77dfe4    scsi_setup_fs_cmnd      vmlinux EXPORT_SYMBOL
+-0xbbc9fd6e    cfg80211_wext_siwfrag   vmlinux EXPORT_SYMBOL_GPL
+-0x82c82c32    cfg80211_wext_giwfrag   vmlinux EXPORT_SYMBOL_GPL
+-0xe80dd06a    tcp_sendpage    vmlinux EXPORT_SYMBOL
+-0x47b3f862    radix_tree_lookup_slot  vmlinux EXPORT_SYMBOL
+-0x91621d6a    allocate_resource       vmlinux EXPORT_SYMBOL
+-0xb98a0185    rtc_tm_to_time  vmlinux EXPORT_SYMBOL
+-0xe5883bd9    class_compat_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x7bf9c108    serial8250_rx_dma       vmlinux EXPORT_SYMBOL_GPL
+-0xc7856a3d    inet6addr_notifier_call_chain   vmlinux EXPORT_SYMBOL
+-0xc08647ff    ring_buffer_bytes_cpu   vmlinux EXPORT_SYMBOL_GPL
+-0xcbbf0a6f    audit_log_task_context  vmlinux EXPORT_SYMBOL
+-0x0a0ab757    pm_schedule_suspend     vmlinux EXPORT_SYMBOL_GPL
+-0x617ae32f    of_get_display_timings  vmlinux EXPORT_SYMBOL_GPL
+-0xe442a492    splice_from_pipe_feed   vmlinux EXPORT_SYMBOL
+-0xf9a054b5    __round_jiffies vmlinux EXPORT_SYMBOL_GPL
+-0x38e20383    hid_alloc_report_buf    vmlinux EXPORT_SYMBOL_GPL
+-0x626ffd48    spi_write_then_read     vmlinux EXPORT_SYMBOL_GPL
+-0x7b5fc447    pinctrl_lookup_state    vmlinux EXPORT_SYMBOL_GPL
+-0x8c49e9fe    cfg80211_conn_failed    vmlinux EXPORT_SYMBOL
+-0x03c06156    bitmap_fold     vmlinux EXPORT_SYMBOL
+-0x04d5a096    security_sb_clone_mnt_opts      vmlinux EXPORT_SYMBOL
+-0x424b2fdf    vfs_rmdir       vmlinux EXPORT_SYMBOL
+-0x52856d8e    generic_shutdown_super  vmlinux EXPORT_SYMBOL
+-0xbd10541e    css_lookup      vmlinux EXPORT_SYMBOL_GPL
+-0x37e74642    get_jiffies_64  vmlinux EXPORT_SYMBOL
+-0xb8117014    cfg80211_rx_spurious_frame      vmlinux EXPORT_SYMBOL
+-0x790c2d9c    netdev_master_upper_dev_link    vmlinux EXPORT_SYMBOL
+-0x02a6ce5a    crc16_table     vmlinux EXPORT_SYMBOL
+-0xe280ea92    init_buffer     vmlinux EXPORT_SYMBOL
+-0xf21e1f9b    disable_percpu_irq      vmlinux EXPORT_SYMBOL_GPL
+-0xb5ae5758    scsi_track_queue_full   vmlinux EXPORT_SYMBOL
+-0xa26b1ba8    exynos_drm_device_register      vmlinux EXPORT_SYMBOL_GPL
+-0xbe55cd3e    __sock_recv_ts_and_drops        vmlinux EXPORT_SYMBOL_GPL
+-0xcedd3329    jbd2__journal_start     vmlinux EXPORT_SYMBOL
+-0x838a3169    pm_qos_request_active   vmlinux EXPORT_SYMBOL_GPL
+-0xbf7fd2f5    schedule_timeout_killable       vmlinux EXPORT_SYMBOL
+-0xd9c4cec4    sock_no_getname vmlinux EXPORT_SYMBOL
+-0x24678be3    snd_pcm_lib_readv       vmlinux EXPORT_SYMBOL
+-0x292a0b74    vfs_link        vmlinux EXPORT_SYMBOL
+-0x85050965    __irq_alloc_descs       vmlinux EXPORT_SYMBOL_GPL
+-0xe3e7dba0    from_kuid_munged        vmlinux EXPORT_SYMBOL
+-0x582bb484    call_usermodehelper_setup       vmlinux EXPORT_SYMBOL
+-0xe52c5e63    v4l2_event_subscribe    vmlinux EXPORT_SYMBOL_GPL
+-0xcd0fc417    drm_ht_just_insert_please       vmlinux EXPORT_SYMBOL
+-0xdacbc24d    netlink_rcv_skb vmlinux EXPORT_SYMBOL
+-0x33d23d14    sk_unattached_filter_create     vmlinux EXPORT_SYMBOL_GPL
+-0x1f07ae8f    crypto_alloc_pcomp      vmlinux EXPORT_SYMBOL_GPL
+-0x2447533c    ktime_get_real  vmlinux EXPORT_SYMBOL_GPL
+-0x68869bae    panic_notifier_list     vmlinux EXPORT_SYMBOL
+-0xdae1eb6a    of_clk_src_onecell_get  vmlinux EXPORT_SYMBOL_GPL
+-0x3444d892    phy_driver_unregister   vmlinux EXPORT_SYMBOL
+-0x107b31ec    __xfrm_state_delete     vmlinux EXPORT_SYMBOL
+-0x4e6165cf    d_delete        vmlinux EXPORT_SYMBOL
+-0x5f0e672b    find_get_pages_tag      vmlinux EXPORT_SYMBOL
+-0xc8fd727e    mod_timer       vmlinux EXPORT_SYMBOL
+-0xd2fe47b1    rndis_set_host_mac      vmlinux EXPORT_SYMBOL
+-0xd768e985    regulator_has_full_constraints  vmlinux EXPORT_SYMBOL_GPL
+-0x82f776b7    gpio_export     vmlinux EXPORT_SYMBOL_GPL
+-0xdf401846    idr_remove      vmlinux EXPORT_SYMBOL
+-0x29baff70    ida_remove      vmlinux EXPORT_SYMBOL
+-0x220b4b23    mnt_set_expiry  vmlinux EXPORT_SYMBOL
+-0x3dd9c200    use_mm  vmlinux EXPORT_SYMBOL_GPL
+-0x2d41e6f5    __trace_puts    vmlinux EXPORT_SYMBOL_GPL
+-0x5143c678    param_get_invbool       vmlinux EXPORT_SYMBOL
+-0x914a1c17    ip_tunnel_newlink       vmlinux EXPORT_SYMBOL_GPL
+-0xc5b6b555    genl_notify     vmlinux EXPORT_SYMBOL
+-0xada52470    wm_hubs_hpl_mux vmlinux EXPORT_SYMBOL_GPL
+-0x9393c812    add_page_wait_queue     vmlinux EXPORT_SYMBOL_GPL
+-0xb16abad2    devm_rtc_device_register        vmlinux EXPORT_SYMBOL_GPL
+-0xbd92ef65    devres_destroy  vmlinux EXPORT_SYMBOL_GPL
+-0x1297fa08    tty_hangup      vmlinux EXPORT_SYMBOL
+-0x580c94d2    seq_put_decimal_ll      vmlinux EXPORT_SYMBOL
+-0xb22596e0    devm_rtc_device_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0x1b95d5c1    mdiobus_read    vmlinux EXPORT_SYMBOL
+-0xea59b757    pm_runtime_forbid       vmlinux EXPORT_SYMBOL_GPL
+-0x30e74134    tty_termios_copy_hw     vmlinux EXPORT_SYMBOL
+-0x4455e1b3    regulator_disable_deferred      vmlinux EXPORT_SYMBOL_GPL
+-0x8e322129    dma_release_channel     vmlinux EXPORT_SYMBOL_GPL
+-0xcfd9a2c0    des_ekey        vmlinux EXPORT_SYMBOL_GPL
+-0x66c78bd2    irq_domain_remove       vmlinux EXPORT_SYMBOL_GPL
+-0x640c2da8    devm_clk_get    vmlinux EXPORT_SYMBOL
+-0xd02c73c7    drm_dp_link_train_clock_recovery_delay  vmlinux EXPORT_SYMBOL
+-0x2be0f12d    dql_completed   vmlinux EXPORT_SYMBOL
+-0xad3f5f91    read_cache_page vmlinux EXPORT_SYMBOL
+-0x4ca90996    rndis_signal_disconnect vmlinux EXPORT_SYMBOL
+-0x917229dc    drm_irq_install vmlinux EXPORT_SYMBOL
+-0x787bcffe    con_is_bound    vmlinux EXPORT_SYMBOL
+-0xefb6eb3f    dev_change_flags        vmlinux EXPORT_SYMBOL
+-0x0e352145    __skb_gso_segment       vmlinux EXPORT_SYMBOL
+-0xa5d14a5e    xfrm_state_walk vmlinux EXPORT_SYMBOL
+-0x6a0ae2ec    nla_put_nohdr   vmlinux EXPORT_SYMBOL
+-0x0411124a    pid_nr_ns       vmlinux EXPORT_SYMBOL_GPL
+-0x2133271d    phy_scan_fixups vmlinux EXPORT_SYMBOL
+-0x64d233c8    ioremap_page    vmlinux EXPORT_SYMBOL
+-0x8fea24bd    bt_sock_unregister      vmlinux EXPORT_SYMBOL
+-0x16c3cf65    napi_gro_flush  vmlinux EXPORT_SYMBOL
+-0xf001dc80    irq_domain_add_linear   vmlinux EXPORT_SYMBOL_GPL
+-0xec069709    scsi_set_medium_removal vmlinux EXPORT_SYMBOL
+-0xc0a98385    profile_pc      vmlinux EXPORT_SYMBOL
+-0x79a2f120    snd_timer_resolution    vmlinux EXPORT_SYMBOL
+-0x46c67b94    jbd2_journal_wipe       vmlinux EXPORT_SYMBOL
+-0x444f1735    cpu_pm_register_notifier        vmlinux EXPORT_SYMBOL_GPL
+-0xcc85fcb6    async_schedule  vmlinux EXPORT_SYMBOL_GPL
+-0x9caf61d6    __nla_put       vmlinux EXPORT_SYMBOL
+-0x4c2ae700    strnstr vmlinux EXPORT_SYMBOL
+-0x07bf12c5    perf_pmu_migrate_context        vmlinux EXPORT_SYMBOL_GPL
+-0x4268de2e    __css_put       vmlinux EXPORT_SYMBOL_GPL
+-0x32fdb1ea    usb_block_urb   vmlinux EXPORT_SYMBOL_GPL
+-0xd76e3ec9    fb_set_var      vmlinux EXPORT_SYMBOL
+-0x7c0643d0    inet_diag_register      vmlinux EXPORT_SYMBOL_GPL
+-0x598542b2    _raw_spin_lock_irqsave  vmlinux EXPORT_SYMBOL
+-0xd468cd0b    sdhci_pltfm_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0x44f93f86    vb2_ops_wait_finish     vmlinux EXPORT_SYMBOL_GPL
+-0x5be57447    dma_buf_kmap_atomic     vmlinux EXPORT_SYMBOL_GPL
+-0xfac68eba    arm_elf_read_implies_exec       vmlinux EXPORT_SYMBOL
+-0xca1e6f11    tcp_done        vmlinux EXPORT_SYMBOL_GPL
+-0x885f07c4    snd_pcm_hw_rule_add     vmlinux EXPORT_SYMBOL
+-0xb1c0c1c2    async_schedule_domain   vmlinux EXPORT_SYMBOL_GPL
+-0x65497c9a    wm8994_bulk_write       vmlinux EXPORT_SYMBOL_GPL
+-0x2fb6de5d    add_device_randomness   vmlinux EXPORT_SYMBOL
+-0xda8af7ad    fb_find_nearest_mode    vmlinux EXPORT_SYMBOL
+-0x0a575945    xfrm_count_pfkey_auth_supported vmlinux EXPORT_SYMBOL_GPL
+-0x3b91f3af    snd_free_pages  vmlinux EXPORT_SYMBOL
+-0xdf2278c1    snd_card_file_remove    vmlinux EXPORT_SYMBOL
+-0xc848d220    blk_free_tags   vmlinux EXPORT_SYMBOL
+-0xff492454    security_inode_getsecctx        vmlinux EXPORT_SYMBOL
+-0xce46e140    ktime_get_ts    vmlinux EXPORT_SYMBOL_GPL
+-0x3b0d157a    v4l2_m2m_ioctl_querybuf vmlinux EXPORT_SYMBOL_GPL
+-0x054177ad    usb_init_urb    vmlinux EXPORT_SYMBOL_GPL
+-0x1ad1f2e7    _memcpy_fromio  vmlinux EXPORT_SYMBOL
+-0x95dbe078    __get_user_2    vmlinux EXPORT_SYMBOL
+-0xb9acd3d9    __put_user_2    vmlinux EXPORT_SYMBOL
+-0xf3797152    snd_interval_ratnum     vmlinux EXPORT_SYMBOL
+-0x9d2edcd6    map_vm_area     vmlinux EXPORT_SYMBOL_GPL
+-0xbfd8d187    balloon_page_enqueue    vmlinux EXPORT_SYMBOL_GPL
+-0xb7e3198c    balloon_page_dequeue    vmlinux EXPORT_SYMBOL_GPL
+-0x0084e86d    unregister_shrinker     vmlinux EXPORT_SYMBOL
+-0x23424fab    usb_hcd_unmap_urb_setup_for_dma vmlinux EXPORT_SYMBOL_GPL
+-0x6c06c6f7    scsi_device_get vmlinux EXPORT_SYMBOL
+-0x970b4c98    scsi_device_put vmlinux EXPORT_SYMBOL
+-0x66109b05    __pm_runtime_set_status vmlinux EXPORT_SYMBOL_GPL
+-0x6d134a2a    drm_prime_sg_to_page_addr_arrays        vmlinux EXPORT_SYMBOL
+-0xbce458b3    drm_framebuffer_reference       vmlinux EXPORT_SYMBOL
+-0xa773e935    ipv6_dev_get_saddr      vmlinux EXPORT_SYMBOL
+-0x38308727    xfrm_policy_flush       vmlinux EXPORT_SYMBOL
+-0x6ebf58d8    skb_tx_error    vmlinux EXPORT_SYMBOL
+-0xea793efe    snd_soc_cache_sync      vmlinux EXPORT_SYMBOL_GPL
+-0xb8aa2342    __check_region  vmlinux EXPORT_SYMBOL
+-0x99638333    mmc_set_blocklen        vmlinux EXPORT_SYMBOL
+-0xc5e4da95    pn_sock_hash    vmlinux EXPORT_SYMBOL
+-0xf6388c56    sysctl_ip_default_ttl   vmlinux EXPORT_SYMBOL
+-0x0e7c2436    napi_gro_frags  vmlinux EXPORT_SYMBOL
+-0x217dda13    flex_array_get  vmlinux EXPORT_SYMBOL
+-0x09437748    ring_buffer_read_events_cpu     vmlinux EXPORT_SYMBOL_GPL
+-0xb974ccc1    inet_diag_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0x0423031f    sock_sendmsg    vmlinux EXPORT_SYMBOL
+-0xade88e76    snd_malloc_pages        vmlinux EXPORT_SYMBOL
+-0x7ca50cfa    disk_get_part   vmlinux EXPORT_SYMBOL_GPL
+-0xfed4d591    cfg80211_find_vendor_ie vmlinux EXPORT_SYMBOL
+-0xe45ee6f0    netlink_kernel_release  vmlinux EXPORT_SYMBOL
+-0xf310e4d9    __sock_create   vmlinux EXPORT_SYMBOL
+-0x4153512b    snd_hwdep_new   vmlinux EXPORT_SYMBOL
+-0x1afae5e7    down_interruptible      vmlinux EXPORT_SYMBOL
+-0x2051f1d8    rtc_set_mmss    vmlinux EXPORT_SYMBOL_GPL
+-0x23dfa3ab    netif_carrier_off       vmlinux EXPORT_SYMBOL
+-0x10895a2a    lease_get_mtime vmlinux EXPORT_SYMBOL
+-0x7cd8f487    sb_set_blocksize        vmlinux EXPORT_SYMBOL
+-0x0effeb6c    srcu_barrier    vmlinux EXPORT_SYMBOL_GPL
+-0xf3de55df    mmc_request_done        vmlinux EXPORT_SYMBOL
+-0x46074c17    sdev_evt_alloc  vmlinux EXPORT_SYMBOL_GPL
+-0x17077530    pinctrl_force_default   vmlinux EXPORT_SYMBOL_GPL
+-0x0d40713a    snd_ctl_boolean_stereo_info     vmlinux EXPORT_SYMBOL
+-0x3744cf36    vmalloc_to_pfn  vmlinux EXPORT_SYMBOL
+-0xc783b0e1    get_task_mm     vmlinux EXPORT_SYMBOL_GPL
+-0xa8950567    sdio_writew     vmlinux EXPORT_SYMBOL_GPL
+-0xca443371    inet_csk_prepare_forced_close   vmlinux EXPORT_SYMBOL
+-0x252f76b5    snd_soc_default_readable_register       vmlinux EXPORT_SYMBOL_GPL
+-0x551bd071    __rb_erase_color        vmlinux EXPORT_SYMBOL
+-0xfff8d451    fuse_request_send       vmlinux EXPORT_SYMBOL_GPL
+-0x88b5647c    trace_clock_local       vmlinux EXPORT_SYMBOL_GPL
+-0x683928de    nf_ct_expect_put        vmlinux EXPORT_SYMBOL_GPL
+-0x7c96bf14    register_tcf_proto_ops  vmlinux EXPORT_SYMBOL
+-0x76aea351    crypto_unregister_alg   vmlinux EXPORT_SYMBOL_GPL
+-0x5c24f853    dump_write      vmlinux EXPORT_SYMBOL
+-0x89485687    iommu_group_put vmlinux EXPORT_SYMBOL_GPL
+-0x00f4d0cf    iommu_group_get vmlinux EXPORT_SYMBOL_GPL
+-0xb4626765    v4l2_ctrl_new_custom    vmlinux EXPORT_SYMBOL
+-0x511746c1    dump_fpu        vmlinux EXPORT_SYMBOL
+-0x28927989    qdisc_watchdog_schedule_ns      vmlinux EXPORT_SYMBOL
+-0x57fec35a    fuse_conn_get   vmlinux EXPORT_SYMBOL_GPL
+-0xff3f1877    filp_open       vmlinux EXPORT_SYMBOL
+-0x7cb7e8a5    generic_file_aio_write  vmlinux EXPORT_SYMBOL
+-0x1d9317d8    smpboot_register_percpu_thread  vmlinux EXPORT_SYMBOL_GPL
+-0x426362dc    __class_create  vmlinux EXPORT_SYMBOL_GPL
+-0xebd6ff6e    xfrm6_prepare_output    vmlinux EXPORT_SYMBOL
+-0x7c30b8c7    xfrm_calg_get_byname    vmlinux EXPORT_SYMBOL_GPL
+-0xf23624a6    xfrm4_prepare_output    vmlinux EXPORT_SYMBOL
+-0x6e88e56f    snd_pcm_link_rwlock     vmlinux EXPORT_SYMBOL
+-0x2ebe3135    cpu_is_hotpluggable     vmlinux EXPORT_SYMBOL_GPL
+-0xd3dbfbc4    _find_first_zero_bit_le vmlinux EXPORT_SYMBOL
+-0x949f7fd6    snd_soc_unregister_codec        vmlinux EXPORT_SYMBOL_GPL
+-0x66b5d30a    get_disk        vmlinux EXPORT_SYMBOL
+-0xd5c3ad66    blk_pm_runtime_init     vmlinux EXPORT_SYMBOL
+-0x55737546    __free_pages    vmlinux EXPORT_SYMBOL
+-0xfa012fe7    tracepoint_probe_register       vmlinux EXPORT_SYMBOL_GPL
+-0xf8802492    print_stack_trace       vmlinux EXPORT_SYMBOL_GPL
+-0x50601122    of_property_match_string        vmlinux EXPORT_SYMBOL_GPL
+-0x70fde9b2    vb2_reqbufs     vmlinux EXPORT_SYMBOL_GPL
+-0x9b680a42    ump_dd_reference_release        vmlinux EXPORT_SYMBOL
+-0x13d5d619    cfg80211_crit_proto_stopped     vmlinux EXPORT_SYMBOL
+-0xd5a7d477    inet_bind       vmlinux EXPORT_SYMBOL
+-0xc5495840    nf_nat_amanda_hook      vmlinux EXPORT_SYMBOL_GPL
+-0xe08e58c9    qdisc_watchdog_init     vmlinux EXPORT_SYMBOL
+-0xe447fb89    __register_binfmt       vmlinux EXPORT_SYMBOL
+-0xbd3321ae    power_supply_class      vmlinux EXPORT_SYMBOL_GPL
+-0x0ce6d0b9    usb_gadget_probe_driver vmlinux EXPORT_SYMBOL_GPL
+-0xae544f3a    usb_hcd_end_port_resume vmlinux EXPORT_SYMBOL_GPL
+-0x8fd8a453    pm_genpd_dev_need_restore       vmlinux EXPORT_SYMBOL_GPL
+-0x7b95ab7d    class_find_device       vmlinux EXPORT_SYMBOL_GPL
+-0x21455002    xfrm_init_state vmlinux EXPORT_SYMBOL
+-0xf06e724d    snd_pcm_debug_name      vmlinux EXPORT_SYMBOL
+-0x89ca47bf    kstrtos8_from_user      vmlinux EXPORT_SYMBOL
+-0x68d0d389    crypto_init_spawn2      vmlinux EXPORT_SYMBOL_GPL
+-0x01c6cb0c    cpu_cluster_pm_enter    vmlinux EXPORT_SYMBOL_GPL
+-0xd1efa60f    st_accel_common_remove  vmlinux EXPORT_SYMBOL
+-0xf398c9eb    vb2_create_bufs vmlinux EXPORT_SYMBOL_GPL
+-0xc385cb58    perf_num_counters       vmlinux EXPORT_SYMBOL_GPL
+-0x87634adf    xfrm_user_policy        vmlinux EXPORT_SYMBOL
+-0xe0741a0a    netif_napi_add  vmlinux EXPORT_SYMBOL
+-0xf12cddd6    skb_split       vmlinux EXPORT_SYMBOL
+-0xdee12a28    input_grab_device       vmlinux EXPORT_SYMBOL
+-0x95e73973    tty_port_block_til_ready        vmlinux EXPORT_SYMBOL
+-0x53a3e486    regulator_get_current_limit     vmlinux EXPORT_SYMBOL_GPL
+-0x5dd18380    regulator_get_init_drvdata      vmlinux EXPORT_SYMBOL_GPL
+-0x8467a73f    netlink_broadcast       vmlinux EXPORT_SYMBOL
+-0x6d1a8997    block_write_full_page_endio     vmlinux EXPORT_SYMBOL
+-0x197519cc    shmem_file_setup        vmlinux EXPORT_SYMBOL_GPL
+-0x8b8059bd    in_group_p      vmlinux EXPORT_SYMBOL
+-0xc631580a    console_unlock  vmlinux EXPORT_SYMBOL
+-0xe8400441    of_property_read_string_index   vmlinux EXPORT_SYMBOL_GPL
+-0x0343bdf1    __i2c_board_list        vmlinux EXPORT_SYMBOL_GPL
+-0xa5dd6fae    arm_pm_restart  vmlinux EXPORT_SYMBOL_GPL
+-0x97fe8a2d    udp_sendmsg     vmlinux EXPORT_SYMBOL
+-0x35fbd6a1    __kfifo_dma_out_prepare_r       vmlinux EXPORT_SYMBOL
+-0xa3e220e7    elv_rb_former_request   vmlinux EXPORT_SYMBOL
+-0xdf76bbeb    iio_pollfunc_store_time vmlinux EXPORT_SYMBOL
+-0xfc30d3a1    mmc_start_req   vmlinux EXPORT_SYMBOL
+-0xf53d4c26    qdisc_class_hash_destroy        vmlinux EXPORT_SYMBOL
+-0x5e61da38    snd_timer_stop  vmlinux EXPORT_SYMBOL
+-0xa6e1a69d    kick_all_cpus_sync      vmlinux EXPORT_SYMBOL_GPL
+-0x68cb9861    sdio_register_driver    vmlinux EXPORT_SYMBOL_GPL
+-0xb575c1a1    usb_kill_urb    vmlinux EXPORT_SYMBOL_GPL
+-0x8ab265d2    usb_get_intf    vmlinux EXPORT_SYMBOL_GPL
+-0xdbd7794d    cfg80211_ready_on_channel       vmlinux EXPORT_SYMBOL
+-0xff112bd5    proc_get_parent_data    vmlinux EXPORT_SYMBOL_GPL
+-0x0bec8a3d    audit_log       vmlinux EXPORT_SYMBOL
+-0x5d9521f8    set_security_override_from_ctx  vmlinux EXPORT_SYMBOL
+-0x235d1d10    drm_gem_prime_import    vmlinux EXPORT_SYMBOL
+-0x7da24ff0    drm_helper_encoder_in_use       vmlinux EXPORT_SYMBOL
+-0x6f3c606d    nfc_hci_register_device vmlinux EXPORT_SYMBOL
+-0xf447e205    ip_tunnel_uninit        vmlinux EXPORT_SYMBOL_GPL
+-0x5055493c    sk_wait_data    vmlinux EXPORT_SYMBOL
+-0xb1b87423    crypto_remove_spawns    vmlinux EXPORT_SYMBOL_GPL
+-0x4fd4e89d    ring_buffer_empty_cpu   vmlinux EXPORT_SYMBOL_GPL
+-0xaa4704e1    usb_autopm_put_interface_no_suspend     vmlinux EXPORT_SYMBOL_GPL
+-0x50e28c07    drm_edid_to_sad vmlinux EXPORT_SYMBOL
+-0x6d57e7f8    drm_edid_to_eld vmlinux EXPORT_SYMBOL
+-0x3fe12ddc    xt_replace_table        vmlinux EXPORT_SYMBOL_GPL
+-0x9c3737fc    __percpu_counter_init   vmlinux EXPORT_SYMBOL
+-0xf846506f    irq_set_affinity_notifier       vmlinux EXPORT_SYMBOL_GPL
+-0x469a0b25    inet_hashinfo_init      vmlinux EXPORT_SYMBOL_GPL
+-0x3fbf68bd    ipv4_sk_redirect        vmlinux EXPORT_SYMBOL_GPL
+-0x151bc10b    end_buffer_read_sync    vmlinux EXPORT_SYMBOL
+-0xb013af25    set_cpus_allowed_ptr    vmlinux EXPORT_SYMBOL_GPL
+-0x227badd6    mod_timer_pinned        vmlinux EXPORT_SYMBOL
+-0xf37cfbf5    dm_dispatch_request     vmlinux EXPORT_SYMBOL_GPL
+-0x1d96bf04    input_mt_report_pointer_emulation       vmlinux EXPORT_SYMBOL
+-0x94289922    mali_pmu_powerdown      vmlinux EXPORT_SYMBOL
+-0xe9d6e0bd    pwm_request     vmlinux EXPORT_SYMBOL_GPL
+-0xd66a2750    tcf_em_tree_dump        vmlinux EXPORT_SYMBOL
+-0x790c22d3    neigh_for_each  vmlinux EXPORT_SYMBOL
+-0x3ed096c1    sg_miter_next   vmlinux EXPORT_SYMBOL
+-0x96b878b6    crypto_init_shash_spawn vmlinux EXPORT_SYMBOL_GPL
+-0x1fd19684    crypto_init_ahash_spawn vmlinux EXPORT_SYMBOL_GPL
+-0xedc85914    posix_timers_register_clock     vmlinux EXPORT_SYMBOL_GPL
+-0xc702156b    param_get_ushort        vmlinux EXPORT_SYMBOL
+-0x65bca4ff    vb2_plane_cookie        vmlinux EXPORT_SYMBOL_GPL
+-0x294a6993    rtc_initialize_alarm    vmlinux EXPORT_SYMBOL_GPL
+-0x6971447a    rtc_month_days  vmlinux EXPORT_SYMBOL
+-0x7e64181d    usb_calc_bus_time       vmlinux EXPORT_SYMBOL_GPL
+-0x5f1f36bc    drm_calc_vbltimestamp_from_scanoutpos   vmlinux EXPORT_SYMBOL
+-0xe0af2dc1    regulator_is_enabled_regmap     vmlinux EXPORT_SYMBOL_GPL
+-0x57c3621e    skb_pull        vmlinux EXPORT_SYMBOL
+-0xeb0a7f4c    clk_register    vmlinux EXPORT_SYMBOL_GPL
+-0xabc6dd63    cpufreq_sysfs_create_file       vmlinux EXPORT_SYMBOL
+-0x1eee0a80    usb_find_interface      vmlinux EXPORT_SYMBOL_GPL
+-0xb524d8dc    amba_find_device        vmlinux EXPORT_SYMBOL
+-0x8574ca6c    gpio_request_array      vmlinux EXPORT_SYMBOL_GPL
+-0x93d2422d    snmp_mib_free   vmlinux EXPORT_SYMBOL_GPL
+-0x5d51bcf7    scatterwalk_start       vmlinux EXPORT_SYMBOL_GPL
+-0x417e3755    sysfs_put       vmlinux EXPORT_SYMBOL_GPL
+-0x2ba54bff    irq_remove_generic_chip vmlinux EXPORT_SYMBOL_GPL
+-0x420c729a    vb2_fop_poll    vmlinux EXPORT_SYMBOL_GPL
+-0xe6d23987    phy_start_interrupts    vmlinux EXPORT_SYMBOL
+-0x1fb1615f    spi_master_resume       vmlinux EXPORT_SYMBOL_GPL
+-0xcd721bb7    scsi_get_vpd_page       vmlinux EXPORT_SYMBOL_GPL
+-0xac2bd611    pm_generic_restore_noirq        vmlinux EXPORT_SYMBOL_GPL
+-0xe0b7aa47    drm_i2c_encoder_dpms    vmlinux EXPORT_SYMBOL
+-0x9dfdf722    gpio_free_array vmlinux EXPORT_SYMBOL_GPL
+-0x7345660c    xfrm_state_check_expire vmlinux EXPORT_SYMBOL
+-0xd5dba10e    sock_diag_unregister_inet_compat        vmlinux EXPORT_SYMBOL_GPL
+-0xfd719be0    netdev_boot_setup_check vmlinux EXPORT_SYMBOL
+-0xa9c6e543    sock_i_uid      vmlinux EXPORT_SYMBOL
+-0x2dfe841c    sock_i_ino      vmlinux EXPORT_SYMBOL
+-0x4bc2dc22    seq_bitmap      vmlinux EXPORT_SYMBOL
+-0x4b8e839a    cpufreq_global_kobject  vmlinux EXPORT_SYMBOL
+-0xc12cf8f8    v4l2_ctrl_replace       vmlinux EXPORT_SYMBOL
+-0xf3dd036d    regulator_set_voltage_time      vmlinux EXPORT_SYMBOL_GPL
+-0x88826167    ip_build_and_send_pkt   vmlinux EXPORT_SYMBOL_GPL
+-0xd09ce8d0    register_gifconf        vmlinux EXPORT_SYMBOL
+-0xaa6901ac    __kfifo_out_r   vmlinux EXPORT_SYMBOL
+-0x64f7667b    crypto_rng_type vmlinux EXPORT_SYMBOL_GPL
+-0x457594fa    crypto_alg_list vmlinux EXPORT_SYMBOL_GPL
+-0x665b8183    sync_inode_metadata     vmlinux EXPORT_SYMBOL
+-0x03026722    mempool_alloc   vmlinux EXPORT_SYMBOL
+-0x0034f927    unregister_wide_hw_breakpoint   vmlinux EXPORT_SYMBOL_GPL
+-0x86f6b99d    synchronize_rcu_expedited       vmlinux EXPORT_SYMBOL_GPL
+-0xec4d9e3a    clk_get_sys     vmlinux EXPORT_SYMBOL
+-0x1b6b3f33    cpufreq_unregister_driver       vmlinux EXPORT_SYMBOL_GPL
+-0x56ca80ea    drm_mode_validate_clocks        vmlinux EXPORT_SYMBOL
+-0xa66a1f63    drm_rmmap_locked        vmlinux EXPORT_SYMBOL
+-0x6b07a31b    regulator_get_voltage_sel_regmap        vmlinux EXPORT_SYMBOL_GPL
+-0x5107f9ce    gpiochip_find   vmlinux EXPORT_SYMBOL_GPL
+-0x05365f80    cfg80211_cac_event      vmlinux EXPORT_SYMBOL
+-0xc05ac2c8    cfg80211_classify8021d  vmlinux EXPORT_SYMBOL
+-0x92be9264    snd_soc_register_platform       vmlinux EXPORT_SYMBOL_GPL
+-0xfaf79bc2    __srcu_read_lock        vmlinux EXPORT_SYMBOL_GPL
+-0xada5e980    media_entity_pipeline_start     vmlinux EXPORT_SYMBOL_GPL
+-0x74fbf451    drm_mm_init_scan_with_range     vmlinux EXPORT_SYMBOL
+-0xd03c7700    secure_ipv4_port_ephemeral      vmlinux EXPORT_SYMBOL_GPL
+-0x9c9ec2a0    proc_dointvec_minmax    vmlinux EXPORT_SYMBOL
+-0x8d772b8c    v4l2_clk_get    vmlinux EXPORT_SYMBOL
+-0x32680bfc    usb_function_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x6dd8ac23    dev_uc_add_excl vmlinux EXPORT_SYMBOL
+-0xced0fa87    dev_mc_add_excl vmlinux EXPORT_SYMBOL
+-0x51cc09c6    kmalloc_caches  vmlinux EXPORT_SYMBOL
+-0x3ef23944    i2c_bus_type    vmlinux EXPORT_SYMBOL_GPL
+-0x015f6d7d    kmap    vmlinux EXPORT_SYMBOL
+-0x0b9a5c65    icmpv6_send     vmlinux EXPORT_SYMBOL
+-0x6625c30d    blk_queue_make_request  vmlinux EXPORT_SYMBOL
+-0x25dd3b83    sysfs_add_link_to_group vmlinux EXPORT_SYMBOL_GPL
+-0x472d363a    truncate_pagecache_range        vmlinux EXPORT_SYMBOL
+-0x0bf3e830    put_page        vmlinux EXPORT_SYMBOL
+-0x74954462    timecounter_read        vmlinux EXPORT_SYMBOL_GPL
+-0x3aa9f288    iio_channel_get vmlinux EXPORT_SYMBOL_GPL
+-0x1fd6672b    video_device_release_empty      vmlinux EXPORT_SYMBOL
+-0x931dcc9d    usbnet_pause_rx vmlinux EXPORT_SYMBOL_GPL
+-0x4c83a264    do_take_over_console    vmlinux EXPORT_SYMBOL_GPL
+-0xe2dd67e5    regulator_set_current_limit     vmlinux EXPORT_SYMBOL_GPL
+-0xb23f3373    nf_conntrack_lock       vmlinux EXPORT_SYMBOL_GPL
+-0xebfa66fa    security_inode_setsecctx        vmlinux EXPORT_SYMBOL
+-0x819ed3be    vfs_getattr     vmlinux EXPORT_SYMBOL
+-0x2fad0dbe    led_classdev_resume     vmlinux EXPORT_SYMBOL_GPL
+-0xbc497919    rtc_device_register     vmlinux EXPORT_SYMBOL_GPL
+-0xd58c665a    input_reset_device      vmlinux EXPORT_SYMBOL
+-0x34c728d0    tty_ldisc_deref vmlinux EXPORT_SYMBOL_GPL
+-0xfb28827b    inet_del_protocol       vmlinux EXPORT_SYMBOL
+-0x95587915    neigh_update    vmlinux EXPORT_SYMBOL
+-0xc9b8c308    __kfifo_dma_out_prepare vmlinux EXPORT_SYMBOL
+-0xd9b9b70a    put_io_context  vmlinux EXPORT_SYMBOL
+-0xac7726b4    blk_queue_io_min        vmlinux EXPORT_SYMBOL
+-0xcf807506    nobh_truncate_page      vmlinux EXPORT_SYMBOL
+-0x43ec231b    iio_device_free vmlinux EXPORT_SYMBOL
+-0x95ae5064    phy_stop        vmlinux EXPORT_SYMBOL
+-0xb69d1c51    spi_bitbang_start       vmlinux EXPORT_SYMBOL_GPL
+-0x87876bed    drm_kms_helper_poll_enable      vmlinux EXPORT_SYMBOL
+-0x045072cd    nf_ct_port_nla_policy   vmlinux EXPORT_SYMBOL_GPL
+-0x4be7fb63    up      vmlinux EXPORT_SYMBOL
+-0xf8a32b55    icmp_send       vmlinux EXPORT_SYMBOL
+-0x69f7d81d    path_get        vmlinux EXPORT_SYMBOL
+-0xd715763b    iov_iter_copy_from_user_atomic  vmlinux EXPORT_SYMBOL
+-0xc7b9fe08    drm_property_create_bitmask     vmlinux EXPORT_SYMBOL
+-0x671a649b    xfrm_state_update       vmlinux EXPORT_SYMBOL
+-0xce3c5240    crypto_grab_aead        vmlinux EXPORT_SYMBOL_GPL
+-0xb590822d    hrtimer_start   vmlinux EXPORT_SYMBOL_GPL
+-0xaebe783e    get_pid_task    vmlinux EXPORT_SYMBOL_GPL
+-0xa8bcfa1a    usb_deregister_dev      vmlinux EXPORT_SYMBOL_GPL
+-0xc398c5f3    usb_hcd_is_primary_hcd  vmlinux EXPORT_SYMBOL_GPL
+-0x7c45fec1    pm_generic_resume_noirq vmlinux EXPORT_SYMBOL_GPL
+-0x6c702af7    sysctl_udp_rmem_min     vmlinux EXPORT_SYMBOL
+-0x9b3122cd    dev_open        vmlinux EXPORT_SYMBOL
+-0x7ee7a9f8    lock_sock_fast  vmlinux EXPORT_SYMBOL
+-0xc3b7e3fb    snd_cards       vmlinux EXPORT_SYMBOL
+-0x82bbf933    ilookup vmlinux EXPORT_SYMBOL
+-0x4302d0eb    free_pages      vmlinux EXPORT_SYMBOL
+-0xefc91531    irq_create_of_mapping   vmlinux EXPORT_SYMBOL_GPL
+-0xb90f9844    sdhci_resume_host       vmlinux EXPORT_SYMBOL_GPL
+-0x8ec22c0b    nat_q931_hook   vmlinux EXPORT_SYMBOL_GPL
+-0x03592ea0    security_unix_stream_connect    vmlinux EXPORT_SYMBOL
+-0x4397c48f    generic_file_fsync      vmlinux EXPORT_SYMBOL
+-0x5154c361    unlock_new_inode        vmlinux EXPORT_SYMBOL
+-0xa9b83487    __f_setown      vmlinux EXPORT_SYMBOL
+-0x9ccb1788    irq_create_direct_mapping       vmlinux EXPORT_SYMBOL_GPL
+-0xf82f16b3    execute_in_process_context      vmlinux EXPORT_SYMBOL_GPL
+-0xcd06de19    mdiobus_free    vmlinux EXPORT_SYMBOL
+-0xfd99623a    ip_frag_ecn_table       vmlinux EXPORT_SYMBOL
+-0x17ee142e    xt_find_table_lock      vmlinux EXPORT_SYMBOL_GPL
+-0x62737e1d    sock_unregister vmlinux EXPORT_SYMBOL
+-0x67095031    kset_register   vmlinux EXPORT_SYMBOL
+-0x84ffea8b    idr_preload     vmlinux EXPORT_SYMBOL
+-0xd29fb507    fput    vmlinux EXPORT_SYMBOL
+-0xe3d6f284    fb_find_mode_cvt        vmlinux EXPORT_SYMBOL
+-0x14d4a9c5    _change_bit     vmlinux EXPORT_SYMBOL
+-0x54411a42    posix_timer_event       vmlinux EXPORT_SYMBOL_GPL
+-0x2a79ac13    clkdev_add      vmlinux EXPORT_SYMBOL
+-0x3d6f446b    platform_device_alloc   vmlinux EXPORT_SYMBOL_GPL
+-0xf85bebf9    dev_printk_emit vmlinux EXPORT_SYMBOL
+-0xde36a037    ip6_frag_init   vmlinux EXPORT_SYMBOL
+-0x31e23d78    __fsnotify_parent       vmlinux EXPORT_SYMBOL_GPL
+-0xdea4fcaa    pm_qos_add_request      vmlinux EXPORT_SYMBOL_GPL
+-0x1976aa06    param_ops_bool  vmlinux EXPORT_SYMBOL
+-0x98ba0e88    pm_generic_suspend_noirq        vmlinux EXPORT_SYMBOL_GPL
+-0xecefd1b6    display_entity_get_params       vmlinux EXPORT_SYMBOL_GPL
+-0xdfb5c1e5    add_disk        vmlinux EXPORT_SYMBOL
+-0x5754706e    media_entity_get        vmlinux EXPORT_SYMBOL_GPL
+-0xbd008b38    media_entity_put        vmlinux EXPORT_SYMBOL_GPL
+-0x5d1e2494    usb_ep0_reinit  vmlinux EXPORT_SYMBOL_GPL
+-0x0ae4b94c    drm_ht_remove   vmlinux EXPORT_SYMBOL
+-0x6ab922b2    regulator_get_drvdata   vmlinux EXPORT_SYMBOL_GPL
+-0x4432d365    __udp6_lib_lookup       vmlinux EXPORT_SYMBOL_GPL
+-0x08696053    inet_shutdown   vmlinux EXPORT_SYMBOL
+-0x52212010    __tracepoint_block_bio_remap    vmlinux EXPORT_SYMBOL_GPL
+-0xc29afc9a    posix_lock_file_wait    vmlinux EXPORT_SYMBOL
+-0x01fd453e    usbhid_lookup_quirk     vmlinux EXPORT_SYMBOL_GPL
+-0x90705b7f    syscon_node_to_regmap   vmlinux EXPORT_SYMBOL_GPL
+-0xf72d56a2    regulator_set_voltage_sel_regmap        vmlinux EXPORT_SYMBOL_GPL
+-0xa308e150    nfc_hci_disconnect_gate vmlinux EXPORT_SYMBOL
+-0x7707c1b0    xt_unregister_table     vmlinux EXPORT_SYMBOL_GPL
+-0x4e830a3e    strnicmp        vmlinux EXPORT_SYMBOL
+-0x48f2cf7c    vmalloc_to_page vmlinux EXPORT_SYMBOL
+-0x3dca446d    drm_handle_vblank       vmlinux EXPORT_SYMBOL
+-0x22ca070b    uart_remove_one_port    vmlinux EXPORT_SYMBOL
+-0x1d027e4b    snd_pcm_format_signed   vmlinux EXPORT_SYMBOL
+-0x3535ae4a    blk_update_request      vmlinux EXPORT_SYMBOL_GPL
+-0x02649054    security_sock_rcv_skb   vmlinux EXPORT_SYMBOL
+-0x547077ec    __wake_up_bit   vmlinux EXPORT_SYMBOL
+-0x1c5541bd    cpufreq_boost_enabled   vmlinux EXPORT_SYMBOL_GPL
+-0x6d186427    usb_get_hcd     vmlinux EXPORT_SYMBOL_GPL
+-0x8eff9111    drm_ht_find_item        vmlinux EXPORT_SYMBOL
+-0xd9d18f03    fbcon_set_bitops        vmlinux EXPORT_SYMBOL
+-0xfaea036f    sock_release    vmlinux EXPORT_SYMBOL
+-0xa414882d    add_wait_queue_exclusive        vmlinux EXPORT_SYMBOL
+-0x06e80ae6    s3c_adc_register        vmlinux EXPORT_SYMBOL_GPL
+-0x63805ac9    usb_hcd_giveback_urb    vmlinux EXPORT_SYMBOL_GPL
+-0xf8d54998    ump_dd_handle_create_from_phys_blocks   vmlinux EXPORT_SYMBOL
+-0x44242685    drm_prime_gem_destroy   vmlinux EXPORT_SYMBOL
+-0x4faff87a    drm_i2c_encoder_mode_fixup      vmlinux EXPORT_SYMBOL
+-0x0f995f4e    tty_port_tty_wakeup     vmlinux EXPORT_SYMBOL_GPL
+-0x91b2790d    regulator_map_voltage_ascend    vmlinux EXPORT_SYMBOL_GPL
+-0x0e29d022    nf_nat_icmp_reply_translation   vmlinux EXPORT_SYMBOL_GPL
+-0x75811312    crc_ccitt_table vmlinux EXPORT_SYMBOL
+-0xe9eb0c04    d_add_ci        vmlinux EXPORT_SYMBOL
+-0x4c55b4df    led_trigger_rename_static       vmlinux EXPORT_SYMBOL_GPL
+-0x6f344bb9    v4l2_calc_aspect_ratio  vmlinux EXPORT_SYMBOL_GPL
+-0xc4f83bea    drm_debugfs_create_files        vmlinux EXPORT_SYMBOL
+-0x9ae51e43    tty_register_device_attr        vmlinux EXPORT_SYMBOL_GPL
+-0x80c70b19    phys_mem_access_prot    vmlinux EXPORT_SYMBOL
+-0x17770200    __skb_checksum_complete_head    vmlinux EXPORT_SYMBOL
+-0x1eeb848e    __percpu_counter_sum    vmlinux EXPORT_SYMBOL
+-0xd74289f9    __percpu_counter_add    vmlinux EXPORT_SYMBOL
+-0xa77a369d    idr_init        vmlinux EXPORT_SYMBOL
+-0x8e5c580a    ida_init        vmlinux EXPORT_SYMBOL
+-0xb99d677c    mpage_readpage  vmlinux EXPORT_SYMBOL
+-0x70bc17d7    inode_wait      vmlinux EXPORT_SYMBOL
+-0xd6ee688f    vmalloc vmlinux EXPORT_SYMBOL
+-0xf31b3fd1    workqueue_set_max_active        vmlinux EXPORT_SYMBOL_GPL
+-0x9745c52a    of_fixed_clk_setup      vmlinux EXPORT_SYMBOL_GPL
+-0xbfd6a20b    phy_ethtool_set_wol     vmlinux EXPORT_SYMBOL
+-0x64004900    phy_ethtool_get_wol     vmlinux EXPORT_SYMBOL
+-0x28492539    spi_bitbang_transfer    vmlinux EXPORT_SYMBOL_GPL
+-0x6552f2d8    unlink_framebuffer      vmlinux EXPORT_SYMBOL
+-0xbdf2580d    __raw_readsl    vmlinux EXPORT_SYMBOL
+-0xabe519d2    blk_queue_io_opt        vmlinux EXPORT_SYMBOL
+-0x05b2af42    bdgrab  vmlinux EXPORT_SYMBOL
+-0xd4c14632    system_unbound_wq       vmlinux EXPORT_SYMBOL_GPL
+-0x098859e1    usbnet_cdc_status       vmlinux EXPORT_SYMBOL_GPL
+-0xd1bd52ba    tty_port_raise_dtr_rts  vmlinux EXPORT_SYMBOL
+-0x4ea1f5a2    drm_gem_object_free     vmlinux EXPORT_SYMBOL
+-0x86d53c76    mb_cache_entry_find_first       vmlinux EXPORT_SYMBOL
+-0xf0b9f940    usb_function_activate   vmlinux EXPORT_SYMBOL_GPL
+-0x9d2ee507    scsi_adjust_queue_depth vmlinux EXPORT_SYMBOL
+-0x4bca6b0c    drm_get_edid    vmlinux EXPORT_SYMBOL
+-0x4a5d2ace    tcp_unregister_congestion_control       vmlinux EXPORT_SYMBOL_GPL
+-0x0274dc2b    netif_get_num_default_rss_queues        vmlinux EXPORT_SYMBOL
+-0x53be6f80    bio_split       vmlinux EXPORT_SYMBOL
+-0x1fc0da41    lock_rename     vmlinux EXPORT_SYMBOL
+-0xbe421975    __locks_copy_lock       vmlinux EXPORT_SYMBOL
+-0x69e3cb9f    mutex_lock_killable     vmlinux EXPORT_SYMBOL
+-0x9c612795    v4l2_chip_match_i2c_client      vmlinux EXPORT_SYMBOL
+-0xd2f84424    i2c_bit_add_bus vmlinux EXPORT_SYMBOL
+-0x421cdcbd    usb_function_deactivate vmlinux EXPORT_SYMBOL_GPL
+-0x63a86872    class_destroy   vmlinux EXPORT_SYMBOL_GPL
+-0x231d4001    fb_edid_add_monspecs    vmlinux EXPORT_SYMBOL
+-0xb01a37d3    gpiochip_remove vmlinux EXPORT_SYMBOL_GPL
+-0xcc2b7257    tcp_check_req   vmlinux EXPORT_SYMBOL
+-0x16270acd    tcp_init_sock   vmlinux EXPORT_SYMBOL
+-0x143dc3b0    netlink_unicast vmlinux EXPORT_SYMBOL
+-0x8452993c    neigh_sysctl_register   vmlinux EXPORT_SYMBOL
+-0xce602df6    cgroup_is_descendant    vmlinux EXPORT_SYMBOL_GPL
+-0xdddba0ab    exynos_g2d_get_ver_ioctl        vmlinux EXPORT_SYMBOL_GPL
+-0xf2c642ed    tty_port_tty_hangup     vmlinux EXPORT_SYMBOL_GPL
+-0x7d086e6f    snd_soc_put_volsw_range vmlinux EXPORT_SYMBOL_GPL
+-0xaf23bb74    snd_soc_get_volsw_range vmlinux EXPORT_SYMBOL_GPL
+-0x01b2facc    snd_timer_start vmlinux EXPORT_SYMBOL
+-0x1e693956    set_nlink       vmlinux EXPORT_SYMBOL
+-0xdcb0349b    sys_close       vmlinux EXPORT_SYMBOL
+-0xaf348da7    cpu_pm_exit     vmlinux EXPORT_SYMBOL_GPL
+-0x77d1afb4    kill_pgrp       vmlinux EXPORT_SYMBOL
+-0x3b9d009a    drm_format_plane_cpp    vmlinux EXPORT_SYMBOL
+-0x2acd3e60    fat_build_inode vmlinux EXPORT_SYMBOL_GPL
+-0x0f3ef271    seq_read        vmlinux EXPORT_SYMBOL
+-0x712fb5a8    is_bad_inode    vmlinux EXPORT_SYMBOL
+-0x253bdb78    param_get_int   vmlinux EXPORT_SYMBOL
+-0xd35fa891    st_sensors_write_event_config   vmlinux EXPORT_SYMBOL
+-0x203bef91    device_wakeup_disable   vmlinux EXPORT_SYMBOL_GPL
+-0xd454eabb    tcf_hash_new_index      vmlinux EXPORT_SYMBOL
+-0x235e7e6a    shash_ahash_finup       vmlinux EXPORT_SYMBOL_GPL
+-0x60384c87    start_tty       vmlinux EXPORT_SYMBOL
+-0x6513a3fa    fb_get_color_depth      vmlinux EXPORT_SYMBOL
+-0x7ffc8718    gpio_set_debounce       vmlinux EXPORT_SYMBOL_GPL
+-0x6c95cbd5    phonet_proto_register   vmlinux EXPORT_SYMBOL
+-0xa01cac38    nf_ct_get_tuplepr       vmlinux EXPORT_SYMBOL_GPL
+-0x3e872db6    __netdev_pick_tx        vmlinux EXPORT_SYMBOL
+-0x981f509d    skb_free_datagram_locked        vmlinux EXPORT_SYMBOL
+-0x93e0379d    kernel_sock_shutdown    vmlinux EXPORT_SYMBOL
+-0x878eae99    snd_pcm_add_chmap_ctls  vmlinux EXPORT_SYMBOL_GPL
+-0xd454865d    snd_pcm_notify  vmlinux EXPORT_SYMBOL
+-0xa735db59    prandom_u32     vmlinux EXPORT_SYMBOL
+-0x8e864a86    posix_acl_chmod vmlinux EXPORT_SYMBOL
+-0xf9910a86    notify_change   vmlinux EXPORT_SYMBOL
+-0x423b589c    follow_up       vmlinux EXPORT_SYMBOL
+-0xa577a850    param_get_short vmlinux EXPORT_SYMBOL
+-0x24b55d2b    of_find_i2c_adapter_by_node     vmlinux EXPORT_SYMBOL
+-0x6d0f1f89    dm_table_get_mode       vmlinux EXPORT_SYMBOL
+-0x2ca4ebcd    regulator_set_drvdata   vmlinux EXPORT_SYMBOL_GPL
+-0x02196324    __aeabi_idiv    vmlinux EXPORT_SYMBOL
+-0xf0e3bec8    nf_log_bind_pf  vmlinux EXPORT_SYMBOL
+-0xd12698d0    skb_copy_and_csum_datagram_iovec        vmlinux EXPORT_SYMBOL
+-0xd23bebab    sock_no_ioctl   vmlinux EXPORT_SYMBOL
+-0xf401a5f4    get_user_pages_fast     vmlinux EXPORT_SYMBOL_GPL
+-0xca85d8cf    tracepoint_probe_update_all     vmlinux EXPORT_SYMBOL_GPL
+-0x54740eb7    get_cpu_idle_time       vmlinux EXPORT_SYMBOL_GPL
+-0x2a3aa678    _test_and_clear_bit     vmlinux EXPORT_SYMBOL
+-0x694967d9    nf_conntrack_find_get   vmlinux EXPORT_SYMBOL_GPL
+-0x19a2badf    snd_soc_codec_set_sysclk        vmlinux EXPORT_SYMBOL_GPL
+-0x93a2419d    simple_empty    vmlinux EXPORT_SYMBOL
+-0x68a13545    vm_mmap vmlinux EXPORT_SYMBOL
+-0x224190b8    shmem_read_mapping_page_gfp     vmlinux EXPORT_SYMBOL_GPL
+-0xd859f1d5    dw_mci_pltfm_register   vmlinux EXPORT_SYMBOL_GPL
+-0xc955c267    serio_unregister_child_port     vmlinux EXPORT_SYMBOL
+-0xcbee09f7    scsi_remove_device      vmlinux EXPORT_SYMBOL
+-0xcd579f54    xfrm_cfg_mutex  vmlinux EXPORT_SYMBOL
+-0xb63be252    __sk_mem_schedule       vmlinux EXPORT_SYMBOL
+-0xcde172ac    radix_tree_gang_lookup_tag_slot vmlinux EXPORT_SYMBOL
+-0x61860fe5    blk_queue_merge_bvec    vmlinux EXPORT_SYMBOL
+-0xd223c00d    fuse_file_poll  vmlinux EXPORT_SYMBOL_GPL
+-0x4b6e004b    mnt_want_write_file     vmlinux EXPORT_SYMBOL_GPL
+-0x11ad8ba6    __hid_register_driver   vmlinux EXPORT_SYMBOL_GPL
+-0x3d8ed8f5    hid_disconnect  vmlinux EXPORT_SYMBOL_GPL
+-0x70cf032f    usb_hcd_irq     vmlinux EXPORT_SYMBOL_GPL
+-0xc0a9a9a1    hci_register_cb vmlinux EXPORT_SYMBOL
+-0x83b21051    ip_ct_attach    vmlinux EXPORT_SYMBOL
+-0x24eb8d39    dev_set_mtu     vmlinux EXPORT_SYMBOL
+-0xbd5c42d9    crypto_unregister_template      vmlinux EXPORT_SYMBOL_GPL
+-0x2deda4a1    security_sk_classify_flow       vmlinux EXPORT_SYMBOL
+-0xe694a9ce    bd_link_disk_holder     vmlinux EXPORT_SYMBOL_GPL
+-0xf1a33551    usb_string_ids_tab      vmlinux EXPORT_SYMBOL_GPL
+-0x565b6892    uuid_le_gen     vmlinux EXPORT_SYMBOL_GPL
+-0x68956406    static_key_slow_dec     vmlinux EXPORT_SYMBOL_GPL
+-0x335c570f    enable_percpu_irq       vmlinux EXPORT_SYMBOL_GPL
+-0x02e1a3ed    should_remove_suid      vmlinux EXPORT_SYMBOL
+-0x0626da5f    od_unregister_powersave_bias_handler    vmlinux EXPORT_SYMBOL_GPL
+-0x4dcfd46b    scsi_free_host_dev      vmlinux EXPORT_SYMBOL
+-0xfec445a3    driver_register vmlinux EXPORT_SYMBOL_GPL
+-0x3d1b2e32    find_lock_page  vmlinux EXPORT_SYMBOL
+-0x92ea202d    srcu_notifier_chain_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0xdb9d11d6    iio_buffer_store_enable vmlinux EXPORT_SYMBOL
+-0x2ceca451    input_ff_create vmlinux EXPORT_SYMBOL_GPL
+-0x6e3d17ac    device_destroy  vmlinux EXPORT_SYMBOL_GPL
+-0xb8d2fd38    wiphy_register  vmlinux EXPORT_SYMBOL
+-0xfa4d8a1f    unregister_pernet_device        vmlinux EXPORT_SYMBOL_GPL
+-0x4c86184b    remove_wait_queue       vmlinux EXPORT_SYMBOL
+-0x4845c423    param_array_ops vmlinux EXPORT_SYMBOL
+-0x2cd6eb8b    input_ff_destroy        vmlinux EXPORT_SYMBOL_GPL
+-0xb9500ec7    mfd_cell_disable        vmlinux EXPORT_SYMBOL
+-0x1a2759ff    platform_get_irq_byname vmlinux EXPORT_SYMBOL_GPL
+-0x8daf9344    napi_get_frags  vmlinux EXPORT_SYMBOL
+-0x60c805dd    sk_stream_write_space   vmlinux EXPORT_SYMBOL
+-0x570e3195    scsi_verify_blk_ioctl   vmlinux EXPORT_SYMBOL
+-0xecbe66b8    sysfs_notify_dirent     vmlinux EXPORT_SYMBOL_GPL
+-0x158df5f3    kill_bdev       vmlinux EXPORT_SYMBOL
+-0x3eb2b460    v4l2_event_unsubscribe  vmlinux EXPORT_SYMBOL_GPL
+-0x8e38bb44    ipv6_dup_options        vmlinux EXPORT_SYMBOL_GPL
+-0xe306f9d8    cgroup_attach_task_all  vmlinux EXPORT_SYMBOL_GPL
+-0x6b06fdce    delayed_work_timer_fn   vmlinux EXPORT_SYMBOL
+-0x8104c3bb    phy_register_fixup_for_id       vmlinux EXPORT_SYMBOL
+-0x46d3b28c    __div0  vmlinux EXPORT_SYMBOL
+-0x7ead817c    __idr_pre_get   vmlinux EXPORT_SYMBOL
+-0x6cc299a1    zap_vma_ptes    vmlinux EXPORT_SYMBOL_GPL
+-0x1f0972cb    drm_fasync      vmlinux EXPORT_SYMBOL
+-0x35c653fb    xfrm_policy_bysel_ctx   vmlinux EXPORT_SYMBOL
+-0x8e81d5af    tcp_sendmsg     vmlinux EXPORT_SYMBOL
+-0xf9ebc368    snd_soc_new_ac97_codec  vmlinux EXPORT_SYMBOL_GPL
+-0x4528c501    elv_rb_del      vmlinux EXPORT_SYMBOL
+-0x056bf03a    elv_rb_add      vmlinux EXPORT_SYMBOL
+-0x5b2c1c77    init_user_ns    vmlinux EXPORT_SYMBOL_GPL
+-0x0b5996ef    st_sensors_sysfs_sampling_frequency_avail       vmlinux EXPORT_SYMBOL
+-0x3a17a800    vb2_dqbuf       vmlinux EXPORT_SYMBOL_GPL
+-0xe55de32d    i2c_smbus_write_word_data       vmlinux EXPORT_SYMBOL
+-0xd1c2d294    ip_mc_leave_group       vmlinux EXPORT_SYMBOL
+-0x05843ade    netif_skb_features      vmlinux EXPORT_SYMBOL
+-0x00632780    work_busy       vmlinux EXPORT_SYMBOL_GPL
+-0x06d2c86e    pm_runtime_set_memalloc_noio    vmlinux EXPORT_SYMBOL_GPL
+-0x97c6c5dd    drm_pci_exit    vmlinux EXPORT_SYMBOL
+-0x1a1938a1    drm_pci_init    vmlinux EXPORT_SYMBOL
+-0xf7a0d470    __sk_mem_reclaim        vmlinux EXPORT_SYMBOL
+-0xc4f45210    d_prune_aliases vmlinux EXPORT_SYMBOL
+-0x498d293a    trace_buffer_unlock_commit      vmlinux EXPORT_SYMBOL_GPL
+-0x12a38747    usleep_range    vmlinux EXPORT_SYMBOL
+-0xef409b74    kmsg_dump_get_line      vmlinux EXPORT_SYMBOL_GPL
+-0xdd3202eb    lcd_device_unregister   vmlinux EXPORT_SYMBOL
+-0x1fa2ae70    tcf_hash_check  vmlinux EXPORT_SYMBOL
+-0xa43b9539    memcpy_fromiovecend     vmlinux EXPORT_SYMBOL
+-0x4b4f96c3    blk_make_request        vmlinux EXPORT_SYMBOL
+-0xe290713d    __pagevec_release       vmlinux EXPORT_SYMBOL
+-0x1e047854    warn_slowpath_fmt       vmlinux EXPORT_SYMBOL
+-0xbca701eb    vb2_ioctl_expbuf        vmlinux EXPORT_SYMBOL_GPL
+-0x01508e49    cfg80211_cqm_rssi_notify        vmlinux EXPORT_SYMBOL
+-0xff3e2712    nla_reserve_nohdr       vmlinux EXPORT_SYMBOL
+-0xc442fa87    ilookup5        vmlinux EXPORT_SYMBOL
+-0x1650bf27    rcutorture_record_progress      vmlinux EXPORT_SYMBOL_GPL
+-0x3507a132    _raw_spin_lock_irq      vmlinux EXPORT_SYMBOL
+-0x1b24bd6e    prepare_creds   vmlinux EXPORT_SYMBOL
+-0x97c03a7e    mutex_unlock    vmlinux EXPORT_SYMBOL
+-0x5bf35318    hid_unregister_driver   vmlinux EXPORT_SYMBOL_GPL
+-0xd989fc54    usb_autopm_put_interface        vmlinux EXPORT_SYMBOL_GPL
+-0x64d3db1a    dev_addr_flush  vmlinux EXPORT_SYMBOL
+-0x6d92d23c    snd_dma_reserve_buf     vmlinux EXPORT_SYMBOL
+-0x83a476ce    bitmap_scnlistprintf    vmlinux EXPORT_SYMBOL
+-0x61660b0f    thermal_notify_framework        vmlinux EXPORT_SYMBOL_GPL
+-0x1e925a2f    drm_unplug_dev  vmlinux EXPORT_SYMBOL
+-0xef76af89    wiphy_rfkill_set_hw_state       vmlinux EXPORT_SYMBOL
+-0x920aacca    nl_table_lock   vmlinux EXPORT_SYMBOL_GPL
+-0x69b0b6dd    blkdev_get_by_dev       vmlinux EXPORT_SYMBOL
+-0xd87601cc    ring_buffer_unlock_commit       vmlinux EXPORT_SYMBOL_GPL
+-0xee7e7bbe    simple_fill_super       vmlinux EXPORT_SYMBOL
+-0xf8fffd67    have_submounts  vmlinux EXPORT_SYMBOL
+-0x07cc4a5d    printk_timed_ratelimit  vmlinux EXPORT_SYMBOL
+-0x274944b3    sock_queue_err_skb      vmlinux EXPORT_SYMBOL
+-0x7b03f66f    snd_add_device_sysfs_file       vmlinux EXPORT_SYMBOL
+-0x1f8db7f9    ring_buffer_overrun_cpu vmlinux EXPORT_SYMBOL_GPL
+-0x0faef0ed    __tasklet_schedule      vmlinux EXPORT_SYMBOL
+-0x8ec68aa9    dev_load        vmlinux EXPORT_SYMBOL
+-0xf4f14de6    rtnl_trylock    vmlinux EXPORT_SYMBOL
+-0xac0ba8c1    blk_iopoll_disable      vmlinux EXPORT_SYMBOL
+-0x1bb201ff    debugfs_create_u16      vmlinux EXPORT_SYMBOL_GPL
+-0xcae7b03f    bio_add_page    vmlinux EXPORT_SYMBOL
+-0x61af42e6    init_pid_ns     vmlinux EXPORT_SYMBOL_GPL
+-0x3c420cae    v4l2_m2m_buf_queue      vmlinux EXPORT_SYMBOL_GPL
+-0x0fa2a45e    __memzero       vmlinux EXPORT_SYMBOL
+-0x674c71f7    ipt_unregister_table    vmlinux EXPORT_SYMBOL
+-0x77ecac9f    zlib_inflateEnd vmlinux EXPORT_SYMBOL
+-0x7ca5798f    contig_page_data        vmlinux EXPORT_SYMBOL
+-0x3b66dc5f    vb2_buffer_done vmlinux EXPORT_SYMBOL_GPL
+-0x07b291d1    usb_unlink_anchored_urbs        vmlinux EXPORT_SYMBOL_GPL
+-0x06fbba42    usbnet_write_cmd        vmlinux EXPORT_SYMBOL_GPL
+-0xc6b4b7b5    inet_frag_evictor       vmlinux EXPORT_SYMBOL
+-0x9d44f8f6    xt_unregister_target    vmlinux EXPORT_SYMBOL
+-0x0dca487b    led_trigger_show        vmlinux EXPORT_SYMBOL_GPL
+-0xb423dba1    console_blanked vmlinux EXPORT_SYMBOL
+-0x23679939    __iowrite32_copy        vmlinux EXPORT_SYMBOL_GPL
+-0x38361fbf    config_group_init_type_name     vmlinux EXPORT_SYMBOL
+-0x668fe138    __sb_end_write  vmlinux EXPORT_SYMBOL
+-0xd67296c6    from_kgid       vmlinux EXPORT_SYMBOL
+-0x2fd8e085    sdhci_pltfm_clk_get_max_clock   vmlinux EXPORT_SYMBOL_GPL
+-0x4222235b    v4l2_fh_is_singular     vmlinux EXPORT_SYMBOL_GPL
+-0x27cbc081    nf_conntrack_unregister_notifier        vmlinux EXPORT_SYMBOL_GPL
+-0x638eeb4d    fib_rules_register      vmlinux EXPORT_SYMBOL_GPL
+-0xfaf98462    bitrev32        vmlinux EXPORT_SYMBOL
+-0x0399203b    simple_transaction_read vmlinux EXPORT_SYMBOL
+-0x8a99a016    mempool_free_slab       vmlinux EXPORT_SYMBOL
+-0x41c72de9    generic_setxattr        vmlinux EXPORT_SYMBOL
+-0x75d94810    generic_getxattr        vmlinux EXPORT_SYMBOL
+-0xe384a102    usb_speed_string        vmlinux EXPORT_SYMBOL_GPL
+-0xf70fecd0    pm_generic_resume_early vmlinux EXPORT_SYMBOL_GPL
+-0x48cb14ac    pm_generic_thaw vmlinux EXPORT_SYMBOL_GPL
+-0x1d061186    cfg80211_connect_result vmlinux EXPORT_SYMBOL
+-0xdd8800ff    jbd2_journal_set_features       vmlinux EXPORT_SYMBOL
+-0xdadafdd7    mpage_readpages vmlinux EXPORT_SYMBOL
+-0x4045c494    filter_match_preds      vmlinux EXPORT_SYMBOL_GPL
+-0x5482fcef    usbnet_start_xmit       vmlinux EXPORT_SYMBOL_GPL
+-0x9e074139    __pm_runtime_resume     vmlinux EXPORT_SYMBOL_GPL
+-0x4df119fa    __bitmap_parse  vmlinux EXPORT_SYMBOL
+-0x2cfc8703    __wait_on_buffer        vmlinux EXPORT_SYMBOL
+-0x4a8907de    cancel_delayed_work_sync        vmlinux EXPORT_SYMBOL
+-0x4c5566c5    extcon_set_cable_state  vmlinux EXPORT_SYMBOL_GPL
+-0x1114ede2    extcon_get_cable_state  vmlinux EXPORT_SYMBOL_GPL
+-0xcac8aaf3    i2c_unlock_adapter      vmlinux EXPORT_SYMBOL_GPL
+-0xc3107f52    regmap_raw_read vmlinux EXPORT_SYMBOL_GPL
+-0x6b807a5f    gpio_sysfs_set_active_low       vmlinux EXPORT_SYMBOL_GPL
+-0xad4d490d    sock_create     vmlinux EXPORT_SYMBOL
+-0x1bcfb1fa    debugfs_create_x32      vmlinux EXPORT_SYMBOL_GPL
+-0xb0440408    bprm_change_interp      vmlinux EXPORT_SYMBOL
+-0xbf7f05c3    kill_litter_super       vmlinux EXPORT_SYMBOL
+-0xcb34aaf6    iommu_domain_window_disable     vmlinux EXPORT_SYMBOL_GPL
+-0x7c9e0f69    clk_add_alias   vmlinux EXPORT_SYMBOL
+-0xad84bef8    dm_table_event  vmlinux EXPORT_SYMBOL
+-0xc91b3468    class_dev_iter_next     vmlinux EXPORT_SYMBOL_GPL
+-0x64038eb3    inet_proto_csum_replace4        vmlinux EXPORT_SYMBOL
+-0xb6e03027    neigh_direct_output     vmlinux EXPORT_SYMBOL
+-0xce9a717b    blk_rq_check_limits     vmlinux EXPORT_SYMBOL_GPL
+-0x75bda77a    seq_hlist_next  vmlinux EXPORT_SYMBOL
+-0xb9c24bba    account_page_dirtied    vmlinux EXPORT_SYMBOL
+-0xde037eaa    __lock_page_killable    vmlinux EXPORT_SYMBOL_GPL
+-0x73c2d5f0    usb_free_urb    vmlinux EXPORT_SYMBOL_GPL
+-0x9faa8d4a    tty_prepare_flip_string_flags   vmlinux EXPORT_SYMBOL_GPL
+-0xb8de9394    tty_prepare_flip_string vmlinux EXPORT_SYMBOL_GPL
+-0x4db0cbcf    fib_rules_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0x5fe6f617    skb_copy_bits   vmlinux EXPORT_SYMBOL
+-0x71bf6cf0    __blk_end_request_all   vmlinux EXPORT_SYMBOL
+-0xede99a14    crypto_register_ahash   vmlinux EXPORT_SYMBOL_GPL
+-0xbdb3fd8c    sysfs_remove_link       vmlinux EXPORT_SYMBOL_GPL
+-0x8924eb1e    rcu_force_quiescent_state       vmlinux EXPORT_SYMBOL_GPL
+-0xe77924e8    drm_match_cea_mode      vmlinux EXPORT_SYMBOL
+-0x189868d7    get_random_bytes_arch   vmlinux EXPORT_SYMBOL
+-0x3aeef779    tcp_make_synack vmlinux EXPORT_SYMBOL
+-0xc1c0b09b    snd_soc_add_codec_controls      vmlinux EXPORT_SYMBOL_GPL
+-0xcc402882    find_get_page   vmlinux EXPORT_SYMBOL
+-0x7d59dd46    pm_wq   vmlinux EXPORT_SYMBOL_GPL
+-0x9a47820d    hrtimer_forward vmlinux EXPORT_SYMBOL_GPL
+-0xa1f0ebea    bit_waitqueue   vmlinux EXPORT_SYMBOL
+-0x52bd048a    iio_get_channel_type    vmlinux EXPORT_SYMBOL_GPL
+-0x37b330b1    mii_check_gmii_support  vmlinux EXPORT_SYMBOL
+-0x964bc3de    dma_async_device_register       vmlinux EXPORT_SYMBOL
+-0x0adc9704    display_timings_release vmlinux EXPORT_SYMBOL_GPL
+-0xe6c818f2    sock_common_recvmsg     vmlinux EXPORT_SYMBOL
+-0xb62a00b3    mem_cgroup_subsys       vmlinux EXPORT_SYMBOL
+-0x64652950    __video_register_device vmlinux EXPORT_SYMBOL
+-0x9572f9d0    inet_csk_addr2sockaddr  vmlinux EXPORT_SYMBOL_GPL
+-0xeda0d76e    gen_estimator_active    vmlinux EXPORT_SYMBOL
+-0x8251bcc3    bitmap_release_region   vmlinux EXPORT_SYMBOL
+-0x5567c227    kernel_cpustat  vmlinux EXPORT_SYMBOL
+-0x9133fe16    vb2_write       vmlinux EXPORT_SYMBOL_GPL
+-0x9bb89701    cfg80211_roamed vmlinux EXPORT_SYMBOL
+-0x5eb03c4c    ip_mc_inc_group vmlinux EXPORT_SYMBOL
+-0x06438115    tcp_orphan_count        vmlinux EXPORT_SYMBOL_GPL
+-0x43804ba2    fat_attach      vmlinux EXPORT_SYMBOL_GPL
+-0x30788c84    sysfs_remove_bin_file   vmlinux EXPORT_SYMBOL_GPL
+-0xb11bad4f    register_wide_hw_breakpoint     vmlinux EXPORT_SYMBOL_GPL
+-0xbd8b253c    tcf_exts_validate       vmlinux EXPORT_SYMBOL
+-0xb81960ca    snprintf        vmlinux EXPORT_SYMBOL
+-0x7cae600c    get_io_context  vmlinux EXPORT_SYMBOL
+-0x70bb651d    __tracepoint_block_rq_remap     vmlinux EXPORT_SYMBOL_GPL
+-0x9be42ea4    proc_mkdir_mode vmlinux EXPORT_SYMBOL
+-0xf0701cc6    tag_pages_for_writeback vmlinux EXPORT_SYMBOL
+-0x3cf525fb    hid_dump_device vmlinux EXPORT_SYMBOL_GPL
+-0x219e9575    wakeup_source_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0xff43d5b5    cfg80211_check_station_change   vmlinux EXPORT_SYMBOL
+-0x2296c00d    crypto_attr_u32 vmlinux EXPORT_SYMBOL_GPL
+-0x710eaf23    PDE_DATA        vmlinux EXPORT_SYMBOL
+-0xc1fac3b3    __bread vmlinux EXPORT_SYMBOL
+-0x55af945f    follow_pfn      vmlinux EXPORT_SYMBOL
+-0x275ae863    make_kuid       vmlinux EXPORT_SYMBOL
+-0x54d8b7ba    hrtimer_init    vmlinux EXPORT_SYMBOL_GPL
+-0x7c8f0303    dma_buf_export_named    vmlinux EXPORT_SYMBOL_GPL
+-0x079f8b38    devm_kzalloc    vmlinux EXPORT_SYMBOL_GPL
+-0x9ddbb3f6    tty_port_link_device    vmlinux EXPORT_SYMBOL_GPL
+-0x9e8d08a7    pinctrl_find_and_add_gpio_range vmlinux EXPORT_SYMBOL_GPL
+-0x9ceb163c    memcpy_toiovec  vmlinux EXPORT_SYMBOL
+-0x44c38935    v4l2_subdev_g_ext_ctrls vmlinux EXPORT_SYMBOL
+-0xc5fab8f0    v4l2_subdev_s_ext_ctrls vmlinux EXPORT_SYMBOL
+-0x4cf092e4    scsi_report_opcode      vmlinux EXPORT_SYMBOL
+-0x1b6314fd    in_aton vmlinux EXPORT_SYMBOL
+-0x1027ae8c    neigh_resolve_output    vmlinux EXPORT_SYMBOL
+-0xc492c2d9    snd_card_register       vmlinux EXPORT_SYMBOL
+-0xa3018431    posix_unblock_lock      vmlinux EXPORT_SYMBOL
+-0xf3d6e3aa    __mnt_is_readonly       vmlinux EXPORT_SYMBOL_GPL
+-0x87984b16    __tracepoint_cpu_idle   vmlinux EXPORT_SYMBOL_GPL
+-0x89205531    cfb_imageblit   vmlinux EXPORT_SYMBOL
+-0x3bbf46ea    vga_base        vmlinux EXPORT_SYMBOL
+-0x6fea34fd    tcp_close       vmlinux EXPORT_SYMBOL
+-0x7bd5c87c    inet_add_offload        vmlinux EXPORT_SYMBOL
+-0x024ea18c    nf_nat_irc_hook vmlinux EXPORT_SYMBOL_GPL
+-0x18d1ab6f    nf_nat_ftp_hook vmlinux EXPORT_SYMBOL_GPL
+-0xeb780f0e    nfq_ct_nat_hook vmlinux EXPORT_SYMBOL_GPL
+-0x06277150    __scm_send      vmlinux EXPORT_SYMBOL
+-0xc49eea50    skb_try_coalesce        vmlinux EXPORT_SYMBOL
+-0xec007de7    snd_soc_dapm_new_controls       vmlinux EXPORT_SYMBOL_GPL
+-0xa07ed110    xz_dec_init     vmlinux EXPORT_SYMBOL
+-0x3dd4d3a7    bprintf vmlinux EXPORT_SYMBOL_GPL
+-0xa4a0aeb8    try_to_free_buffers     vmlinux EXPORT_SYMBOL
+-0xe9f098a6    wait_iff_congested      vmlinux EXPORT_SYMBOL
+-0xcb5bf3f1    __put_cred      vmlinux EXPORT_SYMBOL
+-0x3f80e476    get_thermal_instance    vmlinux EXPORT_SYMBOL
+-0xb6979f60    usb_register_dev        vmlinux EXPORT_SYMBOL_GPL
+-0xe0d8227f    scsi_dma_map    vmlinux EXPORT_SYMBOL
+-0xa5de5bb1    blk_queue_bypass_start  vmlinux EXPORT_SYMBOL_GPL
+-0xb9617f29    dm_path_uevent  vmlinux EXPORT_SYMBOL_GPL
+-0xd909cae6    serial8250_clear_and_reinit_fifos       vmlinux EXPORT_SYMBOL_GPL
+-0x755da9a0    register_framebuffer    vmlinux EXPORT_SYMBOL
+-0x9ed685ee    iov_iter_advance        vmlinux EXPORT_SYMBOL
+-0xf86a3a9f    clk_gate_ops    vmlinux EXPORT_SYMBOL_GPL
+-0xfcc9ce6a    mmc_of_parse    vmlinux EXPORT_SYMBOL
+-0xb486e84e    mfd_remove_devices      vmlinux EXPORT_SYMBOL
+-0xc5a484ac    pm_generic_suspend_late vmlinux EXPORT_SYMBOL_GPL
+-0x3cd06035    add_input_randomness    vmlinux EXPORT_SYMBOL_GPL
+-0xf50d8f59    regulator_enable_regmap vmlinux EXPORT_SYMBOL_GPL
+-0x09774d0b    pinctrl_force_sleep     vmlinux EXPORT_SYMBOL_GPL
+-0xc7c3c6d2    ip6_tnl_dst_reset       vmlinux EXPORT_SYMBOL_GPL
+-0x225d0386    nf_ct_l4proto_pernet_register   vmlinux EXPORT_SYMBOL_GPL
+-0xf7d31a5d    nf_ct_l3proto_pernet_register   vmlinux EXPORT_SYMBOL_GPL
+-0x8401c62f    scsi_unblock_requests   vmlinux EXPORT_SYMBOL
+-0x8ca1a1dc    device_remove_bin_file  vmlinux EXPORT_SYMBOL_GPL
+-0xccb1ba6b    of_get_drm_display_mode vmlinux EXPORT_SYMBOL_GPL
+-0xe3f48cba    tty_port_free_xmit_buf  vmlinux EXPORT_SYMBOL
+-0xec1b043e    regulator_suspend_prepare       vmlinux EXPORT_SYMBOL_GPL
+-0xecbda9c5    display_entity_get      vmlinux EXPORT_SYMBOL_GPL
+-0x13b89dee    pinctrl_request_gpio    vmlinux EXPORT_SYMBOL_GPL
+-0xdcb3410a    nf_ct_deliver_cached_events     vmlinux EXPORT_SYMBOL_GPL
+-0x32ddd5b6    call_rcu        vmlinux EXPORT_SYMBOL_GPL
+-0xf1267848    usb_composite_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0x877509c0    crypto_nivaead_type     vmlinux EXPORT_SYMBOL_GPL
+-0x9263cf47    bdi_writeout_inc        vmlinux EXPORT_SYMBOL_GPL
+-0x26f6b499    iio_str_to_fixpoint     vmlinux EXPORT_SYMBOL_GPL
+-0x7267db00    hwrng_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0x19cbf31d    xfrm6_rcv_spi   vmlinux EXPORT_SYMBOL
+-0xe5a42822    ip_tunnel_change_mtu    vmlinux EXPORT_SYMBOL_GPL
+-0xf236a5de    tcf_exts_change vmlinux EXPORT_SYMBOL
+-0x058b95e3    snd_pcm_release_substream       vmlinux EXPORT_SYMBOL
+-0x9a6e183a    __idr_remove_all        vmlinux EXPORT_SYMBOL
+-0x7b9bf08e    disk_stack_limits       vmlinux EXPORT_SYMBOL
+-0x9879932b    crypto_register_notifier        vmlinux EXPORT_SYMBOL_GPL
+-0xd220cf8a    jiffies_to_timespec     vmlinux EXPORT_SYMBOL
+-0xce4f758e    dma_release_from_coherent       vmlinux EXPORT_SYMBOL
+-0xe238b99e    pskb_put        vmlinux EXPORT_SYMBOL_GPL
+-0xe11dd614    fib_table_lookup        vmlinux EXPORT_SYMBOL_GPL
+-0x3862b0a7    snd_soc_bytes_put       vmlinux EXPORT_SYMBOL_GPL
+-0xa5ed8e2c    inc_nlink       vmlinux EXPORT_SYMBOL
+-0xf43bdbf8    smpboot_unregister_percpu_thread        vmlinux EXPORT_SYMBOL_GPL
+-0x8a1ab4ee    timeval_to_jiffies      vmlinux EXPORT_SYMBOL
+-0x39375395    i2c_master_send vmlinux EXPORT_SYMBOL
+-0x3a517b2b    device_reprobe  vmlinux EXPORT_SYMBOL_GPL
+-0xb22e34bd    wiphy_free      vmlinux EXPORT_SYMBOL
+-0x76a01893    __netlink_dump_start    vmlinux EXPORT_SYMBOL
+-0xa96c3c3b    dev_kfree_skb_any       vmlinux EXPORT_SYMBOL
+-0xfdaeced1    snd_ctl_new1    vmlinux EXPORT_SYMBOL
+-0xb4f57a24    security_task_getsecid  vmlinux EXPORT_SYMBOL
+-0x09d71f87    seq_open        vmlinux EXPORT_SYMBOL
+-0x29a73c29    mnt_drop_write  vmlinux EXPORT_SYMBOL_GPL
+-0xbcdd5b99    iommu_group_set_name    vmlinux EXPORT_SYMBOL_GPL
+-0x7e394c4e    sysctl_local_reserved_ports     vmlinux EXPORT_SYMBOL
+-0x094bac5f    simple_readpage vmlinux EXPORT_SYMBOL
+-0x5a39720e    __lock_page     vmlinux EXPORT_SYMBOL
+-0xb140d14c    ring_buffer_read        vmlinux EXPORT_SYMBOL_GPL
+-0xf499fdb2    rcu_barrier_bh  vmlinux EXPORT_SYMBOL_GPL
+-0x03d9fff7    synchronize_srcu_expedited      vmlinux EXPORT_SYMBOL_GPL
+-0x1c0ae7d7    drm_mm_init_scan        vmlinux EXPORT_SYMBOL
+-0x8320bea8    __umodsi3       vmlinux EXPORT_SYMBOL
+-0xc3706dce    tcp_cong_avoid_ai       vmlinux EXPORT_SYMBOL_GPL
+-0xab6bde28    sysctl_max_syn_backlog  vmlinux EXPORT_SYMBOL
+-0x5d90d2ce    blk_delay_queue vmlinux EXPORT_SYMBOL
+-0xefdd70ce    security_secid_to_secctx        vmlinux EXPORT_SYMBOL
+-0x77d67659    follow_down     vmlinux EXPORT_SYMBOL
+-0x083eb1cc    __generic_file_aio_write        vmlinux EXPORT_SYMBOL
+-0x46646afc    filemap_write_and_wait_range    vmlinux EXPORT_SYMBOL
+-0xc72c4abb    usb_altnum_to_altsetting        vmlinux EXPORT_SYMBOL_GPL
+-0x0a98333a    snd_soc_dpcm_get_substream      vmlinux EXPORT_SYMBOL_GPL
+-0x360b1afe    probe_irq_mask  vmlinux EXPORT_SYMBOL
+-0x8f2154e4    cfg80211_rx_mgmt        vmlinux EXPORT_SYMBOL
+-0xafa574d0    snd_soc_jack_notifier_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0x93af86c9    get_write_access        vmlinux EXPORT_SYMBOL
+-0x2350c4a6    invalidate_mapping_pages        vmlinux EXPORT_SYMBOL
+-0x84c6c77a    genphy_read_status      vmlinux EXPORT_SYMBOL
+-0x96fb7fef    drm_mode_create_dithering_property      vmlinux EXPORT_SYMBOL
+-0xef56f51e    redraw_screen   vmlinux EXPORT_SYMBOL
+-0x2394545f    tty_unregister_driver   vmlinux EXPORT_SYMBOL
+-0xf3bf0bce    __bitmap_complement     vmlinux EXPORT_SYMBOL
+-0xe2e8065e    memdup_user     vmlinux EXPORT_SYMBOL
+-0x3bdd0f94    v4l2_prio_change        vmlinux EXPORT_SYMBOL
+-0x7ab9b430    drm_poll        vmlinux EXPORT_SYMBOL
+-0x760d494e    pinctrl_find_gpio_range_from_pin        vmlinux EXPORT_SYMBOL_GPL
+-0xcca27eeb    del_timer       vmlinux EXPORT_SYMBOL
+-0x39e773af    thermal_cooling_device_unregister       vmlinux EXPORT_SYMBOL_GPL
+-0xcba9dbcf    dma_get_required_mask   vmlinux EXPORT_SYMBOL_GPL
+-0x2fb1d233    nf_log_unbind_pf        vmlinux EXPORT_SYMBOL
+-0x460f7531    wait_rcu_gp     vmlinux EXPORT_SYMBOL_GPL
+-0x9bfaf424    usb_get_current_frame_number    vmlinux EXPORT_SYMBOL_GPL
+-0xad9bbf9f    hci_suspend_dev vmlinux EXPORT_SYMBOL
+-0x56c5a136    tcp_v4_send_check       vmlinux EXPORT_SYMBOL
+-0x0a4862b9    nf_ct_expect_find_get   vmlinux EXPORT_SYMBOL_GPL
+-0x30e3e930    dev_close       vmlinux EXPORT_SYMBOL
+-0xc3e46db4    snd_pcm_lib_free_pages  vmlinux EXPORT_SYMBOL
+-0x3b735a2b    __mark_inode_dirty      vmlinux EXPORT_SYMBOL
+-0x91437bc9    dma_buf_put     vmlinux EXPORT_SYMBOL_GPL
+-0x8e09c957    dma_buf_get     vmlinux EXPORT_SYMBOL_GPL
+-0x98aba977    ip6_update_pmtu vmlinux EXPORT_SYMBOL_GPL
+-0x019daa72    noop_qdisc      vmlinux EXPORT_SYMBOL
+-0x240646b9    sock_alloc_send_skb     vmlinux EXPORT_SYMBOL
+-0x871f2cb1    snd_soc_dapm_nc_pin     vmlinux EXPORT_SYMBOL_GPL
+-0x97440f69    snd_card_disconnect     vmlinux EXPORT_SYMBOL
+-0xd9ce8f0c    strnlen vmlinux EXPORT_SYMBOL
+-0xe7c9dbc0    unregister_filesystem   vmlinux EXPORT_SYMBOL
+-0x4abbe3c2    vm_brk  vmlinux EXPORT_SYMBOL
+-0x2439abc9    irq_domain_add_simple   vmlinux EXPORT_SYMBOL_GPL
+-0xd418e1c0    adjust_resource vmlinux EXPORT_SYMBOL
+-0x31c0c2d1    dm_put  vmlinux EXPORT_SYMBOL_GPL
+-0x140e371b    v4l2_of_get_remote_port_parent  vmlinux EXPORT_SYMBOL
+-0x3adbd595    v4l2_field_names        vmlinux EXPORT_SYMBOL
+-0xdcece020    xfrm_state_insert       vmlinux EXPORT_SYMBOL
+-0xf8fe3d0b    kmsg_dump_register      vmlinux EXPORT_SYMBOL_GPL
+-0x40728a63    xt_find_revision        vmlinux EXPORT_SYMBOL_GPL
+-0xcb534ec9    __destroy_inode vmlinux EXPORT_SYMBOL
+-0xea1f5b88    samsung_rev     vmlinux EXPORT_SYMBOL
+-0xd3dd145a    tcp_is_cwnd_limited     vmlinux EXPORT_SYMBOL_GPL
+-0x392697b4    nf_conntrack_l3proto_generic    vmlinux EXPORT_SYMBOL_GPL
+-0x2549013a    snd_soc_dai_set_channel_map     vmlinux EXPORT_SYMBOL_GPL
+-0x421e53cf    blk_rq_unmap_user       vmlinux EXPORT_SYMBOL
+-0xacf1d33d    crypto_mod_get  vmlinux EXPORT_SYMBOL_GPL
+-0x0bc477a2    irq_set_irq_type        vmlinux EXPORT_SYMBOL
+-0xce2840e7    irq_set_irq_wake        vmlinux EXPORT_SYMBOL
+-0x2650d835    sysctl_ip_early_demux   vmlinux EXPORT_SYMBOL
+-0x07e472e5    __remove_inode_hash     vmlinux EXPORT_SYMBOL
+-0x82b7cda8    __lru_cache_add vmlinux EXPORT_SYMBOL
+-0x457b77ca    of_fixed_factor_clk_setup       vmlinux EXPORT_SYMBOL_GPL
+-0x840b929e    v4l2_device_unregister_subdev   vmlinux EXPORT_SYMBOL_GPL
+-0x6128b5fc    __printk_ratelimit      vmlinux EXPORT_SYMBOL
+-0xcc1f1c3d    inet_twdr_hangman       vmlinux EXPORT_SYMBOL_GPL
+-0x71faed49    __blk_end_request_cur   vmlinux EXPORT_SYMBOL
+-0xab5cbfa1    __blk_end_request_err   vmlinux EXPORT_SYMBOL_GPL
+-0xb2682405    utf8_to_utf32   vmlinux EXPORT_SYMBOL
+-0x9621849f    ring_buffer_event_data  vmlinux EXPORT_SYMBOL_GPL
+-0x2761c400    pm_generic_restore_early        vmlinux EXPORT_SYMBOL_GPL
+-0x36d31f9e    crypto_sha1_update      vmlinux EXPORT_SYMBOL
+-0x8798e453    __tracepoint_kfree      vmlinux EXPORT_SYMBOL
+-0x247ba373    override_creds  vmlinux EXPORT_SYMBOL
+-0x131db64a    system_long_wq  vmlinux EXPORT_SYMBOL_GPL
+-0xc0d26387    kmsg_dump_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0x6b132713    __clk_register  vmlinux EXPORT_SYMBOL_GPL
+-0x5292f4ea    scsi_prep_return        vmlinux EXPORT_SYMBOL
+-0x34a13791    __pm_runtime_disable    vmlinux EXPORT_SYMBOL_GPL
+-0xa10db0ce    phy_pm_runtime_get_sync vmlinux EXPORT_SYMBOL_GPL
+-0x1b62df19    arm_iommu_create_mapping        vmlinux EXPORT_SYMBOL_GPL
+-0x606d0b09    secure_tcpv6_sequence_number    vmlinux EXPORT_SYMBOL
+-0xa75bc594    blkdev_issue_zeroout    vmlinux EXPORT_SYMBOL
+-0x8f12669a    irq_linear_revmap       vmlinux EXPORT_SYMBOL_GPL
+-0x938244d0    handle_level_irq        vmlinux EXPORT_SYMBOL_GPL
+-0xb336e1d2    extcon_set_cable_state_ vmlinux EXPORT_SYMBOL_GPL
+-0x067ef5d5    extcon_get_cable_state_ vmlinux EXPORT_SYMBOL_GPL
+-0x8d22bb58    iommu_group_alloc       vmlinux EXPORT_SYMBOL_GPL
+-0xa7e20df3    clk_mux_ops     vmlinux EXPORT_SYMBOL_GPL
+-0x7f9eeaae    input_register_handle   vmlinux EXPORT_SYMBOL
+-0x6cc78c5c    set_irq_flags   vmlinux EXPORT_SYMBOL_GPL
+-0xc781bd9f    rfkill_resume_polling   vmlinux EXPORT_SYMBOL
+-0x982e6b6d    ieee80211_radiotap_iterator_init        vmlinux EXPORT_SYMBOL
+-0xf30fda27    lzo1x_decompress_safe   vmlinux EXPORT_SYMBOL_GPL
+-0x42b364ef    scatterwalk_done        vmlinux EXPORT_SYMBOL_GPL
+-0x2158c0d7    kern_unmount    vmlinux EXPORT_SYMBOL
+-0xd31ccb06    of_machine_is_compatible        vmlinux EXPORT_SYMBOL
+-0xd6d49c42    sdio_writesb    vmlinux EXPORT_SYMBOL_GPL
+-0xe6fa2163    v4l2_async_notifier_unregister  vmlinux EXPORT_SYMBOL
+-0x20234f83    nla_append      vmlinux EXPORT_SYMBOL
+-0x4cf41ed3    skcipher_geniv_free     vmlinux EXPORT_SYMBOL_GPL
+-0x4bc07110    jbd2_journal_lock_updates       vmlinux EXPORT_SYMBOL
+-0xf37671d2    vfs_llseek      vmlinux EXPORT_SYMBOL
+-0x8720876b    __page_file_index       vmlinux EXPORT_SYMBOL_GPL
+-0x609d9c25    __irq_set_handler       vmlinux EXPORT_SYMBOL_GPL
+-0x2d17a0e1    cgroup_taskset_size     vmlinux EXPORT_SYMBOL_GPL
+-0xabe27502    v4l2_ctrl_query_fill    vmlinux EXPORT_SYMBOL
+-0x5b1a060c    usb_control_msg vmlinux EXPORT_SYMBOL_GPL
+-0xe59c5ea4    snd_dma_free_pages      vmlinux EXPORT_SYMBOL
+-0x85541e31    iterate_fd      vmlinux EXPORT_SYMBOL
+-0x7ceaf0d5    generic_handle_irq      vmlinux EXPORT_SYMBOL_GPL
+-0x46feb099    dm_read_arg     vmlinux EXPORT_SYMBOL
+-0xe8125c91    dev_set_drvdata vmlinux EXPORT_SYMBOL
+-0x8d60d310    dev_get_drvdata vmlinux EXPORT_SYMBOL
+-0x84510ec6    bt_sock_unlink  vmlinux EXPORT_SYMBOL
+-0x14f626f7    snd_soc_dapm_add_routes vmlinux EXPORT_SYMBOL_GPL
+-0x5d1c1bac    blocking_notifier_chain_cond_register   vmlinux EXPORT_SYMBOL_GPL
+-0xefd5b1f1    nfc_hci_disconnect_all_gates    vmlinux EXPORT_SYMBOL
+-0x009c0acf    __xfrm_state_destroy    vmlinux EXPORT_SYMBOL
+-0x256e5691    bfifo_qdisc_ops vmlinux EXPORT_SYMBOL
+-0x1f8544b8    panic_timeout   vmlinux EXPORT_SYMBOL_GPL
+-0x5b4e379c    of_prop_next_u32        vmlinux EXPORT_SYMBOL_GPL
+-0x8106095a    v4l2_prio_max   vmlinux EXPORT_SYMBOL
+-0xfff74a32    usb_unpoison_urb        vmlinux EXPORT_SYMBOL_GPL
+-0xc532db16    tty_port_init   vmlinux EXPORT_SYMBOL
+-0xa20ce1b8    net_msg_warn    vmlinux EXPORT_SYMBOL
+-0x2aa97a28    __sock_recv_timestamp   vmlinux EXPORT_SYMBOL_GPL
+-0x6225637e    md5_transform   vmlinux EXPORT_SYMBOL
+-0xa3301b08    noop_fsync      vmlinux EXPORT_SYMBOL
+-0x31ab0e28    extcon_dev_unregister   vmlinux EXPORT_SYMBOL_GPL
+-0xc5176fe9    usb_hcd_resume_root_hub vmlinux EXPORT_SYMBOL_GPL
+-0x13bdb1fd    cfg80211_ibss_joined    vmlinux EXPORT_SYMBOL
+-0x587763dd    blkdev_issue_write_same vmlinux EXPORT_SYMBOL
+-0x627b7988    crypto_hash_walk_first  vmlinux EXPORT_SYMBOL_GPL
+-0x85d438aa    scsi_add_host_with_dma  vmlinux EXPORT_SYMBOL
+-0x2b26ce97    devres_remove_group     vmlinux EXPORT_SYMBOL_GPL
+-0x8e007d5e    inet_sendpage   vmlinux EXPORT_SYMBOL
+-0xbb713e6d    sk_filter_release_rcu   vmlinux EXPORT_SYMBOL
+-0xf1dc9acb    dev_get_by_index_rcu    vmlinux EXPORT_SYMBOL
+-0x5364397d    dev_set_allmulti        vmlinux EXPORT_SYMBOL
+-0xd20a4e9e    snd_ctl_remove_id       vmlinux EXPORT_SYMBOL
+-0xea10655a    __bitmap_intersects     vmlinux EXPORT_SYMBOL
+-0xf313da4e    sha_transform   vmlinux EXPORT_SYMBOL
+-0x9b6eb137    ksize   vmlinux EXPORT_SYMBOL
+-0x38869d88    kstat   vmlinux EXPORT_SYMBOL
+-0x43caf714    mmc_can_erase   vmlinux EXPORT_SYMBOL
+-0xa42810a9    i2c_add_adapter vmlinux EXPORT_SYMBOL
+-0xaf5ddb02    input_mt_report_finger_count    vmlinux EXPORT_SYMBOL
+-0x3a09b033    drm_mmap        vmlinux EXPORT_SYMBOL
+-0xcc16f79c    drm_kms_helper_poll_fini        vmlinux EXPORT_SYMBOL
+-0xe707d823    __aeabi_uidiv   vmlinux EXPORT_SYMBOL
+-0xcd2a33d7    hci_conn_security       vmlinux EXPORT_SYMBOL
+-0xd456425d    kobject_set_name        vmlinux EXPORT_SYMBOL
+-0x60642a60    shmem_truncate_range    vmlinux EXPORT_SYMBOL_GPL
+-0xa3e7c113    ring_buffer_iter_peek   vmlinux EXPORT_SYMBOL_GPL
+-0xa5efbf4c    async_synchronize_full  vmlinux EXPORT_SYMBOL_GPL
+-0x3ac75973    dm_send_uevents vmlinux EXPORT_SYMBOL_GPL
+-0x47f757de    elf_platform    vmlinux EXPORT_SYMBOL
+-0x48994b32    bt_debugfs      vmlinux EXPORT_SYMBOL_GPL
+-0xc3f4c43b    set_device_ro   vmlinux EXPORT_SYMBOL
+-0xbb038ce4    perf_unregister_guest_info_callbacks    vmlinux EXPORT_SYMBOL_GPL
+-0x8cc44150    of_clk_src_simple_get   vmlinux EXPORT_SYMBOL_GPL
+-0x09378170    shash_attr_alg  vmlinux EXPORT_SYMBOL_GPL
+-0x63eb9355    panic_blink     vmlinux EXPORT_SYMBOL
+-0x37df5b58    usb_anchor_urb  vmlinux EXPORT_SYMBOL_GPL
+-0x665ccdb6    __sync_dirty_buffer     vmlinux EXPORT_SYMBOL
+-0xb370f2b0    kmap_high       vmlinux EXPORT_SYMBOL
+-0xc3042166    cancel_dirty_page       vmlinux EXPORT_SYMBOL
+-0xf4fc2d6c    __ring_buffer_alloc     vmlinux EXPORT_SYMBOL_GPL
+-0x82072614    tasklet_kill    vmlinux EXPORT_SYMBOL
+-0x653cd720    exynos_g2d_set_cmdlist_ioctl    vmlinux EXPORT_SYMBOL_GPL
+-0xa2a78b0e    blk_post_runtime_resume vmlinux EXPORT_SYMBOL
+-0xf7f02ddf    bio_endio       vmlinux EXPORT_SYMBOL
+-0x269b337f    account_page_redirty    vmlinux EXPORT_SYMBOL
+-0x85c7f674    ring_buffer_normalize_time_stamp        vmlinux EXPORT_SYMBOL_GPL
+-0xf4597085    i2c_use_client  vmlinux EXPORT_SYMBOL
+-0x2da746c5    scsi_print_command      vmlinux EXPORT_SYMBOL
+-0xd0e73a87    amba_driver_register    vmlinux EXPORT_SYMBOL
+-0x3810da45    nf_ct_expect_unregister_notifier        vmlinux EXPORT_SYMBOL_GPL
+-0x50b236e9    eth_prepare_mac_addr_change     vmlinux EXPORT_SYMBOL
+-0xd32c0bf4    sk_stop_timer   vmlinux EXPORT_SYMBOL
+-0xffdb82bc    sg_free_table   vmlinux EXPORT_SYMBOL
+-0xfcbba27f    locks_remove_posix      vmlinux EXPORT_SYMBOL
+-0xb0b85f47    ring_buffer_iter_reset  vmlinux EXPORT_SYMBOL_GPL
+-0x43b0c9c3    preempt_schedule        vmlinux EXPORT_SYMBOL
+-0x7c010229    of_platform_bus_probe   vmlinux EXPORT_SYMBOL
+-0xf74656ab    regulator_can_change_voltage    vmlinux EXPORT_SYMBOL_GPL
+-0x5d5b5a16    radix_tree_delete       vmlinux EXPORT_SYMBOL
+-0x4b37f24f    of_extcon_get_extcon_dev        vmlinux EXPORT_SYMBOL_GPL
+-0x728be72e    pm_generic_thaw_noirq   vmlinux EXPORT_SYMBOL_GPL
+-0x94de4a33    tcp_slow_start  vmlinux EXPORT_SYMBOL_GPL
+-0x4a73178a    dev_activate    vmlinux EXPORT_SYMBOL
+-0x7649cfce    __pneigh_lookup vmlinux EXPORT_SYMBOL_GPL
+-0xaafcd87b    devm_iounmap    vmlinux EXPORT_SYMBOL
+-0x3bfc99a5    devm_ioremap    vmlinux EXPORT_SYMBOL
+-0x5541ea93    on_each_cpu     vmlinux EXPORT_SYMBOL
+-0x176af8ec    cdc_ncm_rx_verify_ndp16 vmlinux EXPORT_SYMBOL_GPL
+-0x572d7fe7    pn544_hci_remove        vmlinux EXPORT_SYMBOL
+-0x74e5ff1a    udpv6_encap_enable      vmlinux EXPORT_SYMBOL
+-0x7a08f61d    snd_pcm_set_sync        vmlinux EXPORT_SYMBOL
+-0x164b50d3    nla_reserve     vmlinux EXPORT_SYMBOL
+-0x08758d9c    bioset_create   vmlinux EXPORT_SYMBOL
+-0x08365975    drm_gem_object_lookup   vmlinux EXPORT_SYMBOL
+-0x862b9816    cpu_topology    vmlinux EXPORT_SYMBOL_GPL
+-0x3722cf9f    rtnl_put_cacheinfo      vmlinux EXPORT_SYMBOL_GPL
+-0xea124bd1    gcd     vmlinux EXPORT_SYMBOL_GPL
+-0xce3e95d0    ihold   vmlinux EXPORT_SYMBOL
+-0xd11031b4    names_cachep    vmlinux EXPORT_SYMBOL
+-0x8890cade    invalidate_inode_pages2_range   vmlinux EXPORT_SYMBOL_GPL
+-0x83130f62    cancel_delayed_work     vmlinux EXPORT_SYMBOL
+-0xcbc428db    __cpufreq_driver_target vmlinux EXPORT_SYMBOL_GPL
+-0xd6233445    xfrm_policy_register_afinfo     vmlinux EXPORT_SYMBOL
+-0xc8afb46b    snd_info_create_card_entry      vmlinux EXPORT_SYMBOL
+-0xb7850524    crypto_unregister_shashes       vmlinux EXPORT_SYMBOL_GPL
+-0x4acc9be5    dentry_path_raw vmlinux EXPORT_SYMBOL
+-0x475ea860    xfrm_sad_getinfo        vmlinux EXPORT_SYMBOL
+-0x9429e18f    netif_napi_del  vmlinux EXPORT_SYMBOL
+-0x03a3ce75    crypto_register_alg     vmlinux EXPORT_SYMBOL_GPL
+-0x1a3e0511    debugfs_rename  vmlinux EXPORT_SYMBOL_GPL
+-0xb69186d9    simple_open     vmlinux EXPORT_SYMBOL
+-0xe513ed5c    single_open     vmlinux EXPORT_SYMBOL
+-0x9072472b    page_follow_link_light  vmlinux EXPORT_SYMBOL
+-0xdbbd4688    __page_file_mapping     vmlinux EXPORT_SYMBOL_GPL
+-0x0f751aea    input_event_from_user   vmlinux EXPORT_SYMBOL_GPL
+-0x4484a5a4    wait_for_device_probe   vmlinux EXPORT_SYMBOL_GPL
+-0xd53e17fd    tty_port_put    vmlinux EXPORT_SYMBOL
+-0xa1b759ce    fb_add_videomode        vmlinux EXPORT_SYMBOL
+-0x3c831441    arm_check_condition     vmlinux EXPORT_SYMBOL_GPL
+-0x44fa52dd    brcmu_pktq_mdeq drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x471d6f83    brcmu_pktq_mlen drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x6af410ae    cfg80211_send_disassoc  vmlinux EXPORT_SYMBOL
+-0x1baa3892    xfrm6_find_1stfragopt   vmlinux EXPORT_SYMBOL
+-0x198788b4    snd_lookup_oss_minor_data       vmlinux EXPORT_SYMBOL
+-0x4a3ea5c0    snd_request_card        vmlinux EXPORT_SYMBOL
+-0x56451890    register_ftrace_event   vmlinux EXPORT_SYMBOL_GPL
+-0x4ae313f9    kthread_stop    vmlinux EXPORT_SYMBOL
+-0x1438fff0    st_sensors_sysfs_scale_avail    vmlinux EXPORT_SYMBOL
+-0x31178006    clk_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0x083c2cbe    of_get_next_parent      vmlinux EXPORT_SYMBOL
+-0xfef96e23    __scsi_print_command    vmlinux EXPORT_SYMBOL
+-0x670cff67    drm_helper_disable_unused_functions     vmlinux EXPORT_SYMBOL
+-0xe7048594    cfg80211_chandef_create vmlinux EXPORT_SYMBOL
+-0x020d1750    cfg80211_tdls_oper_request      vmlinux EXPORT_SYMBOL
+-0xbec63ca7    security_inode_create   vmlinux EXPORT_SYMBOL_GPL
+-0xfe72e11b    dm_register_target      vmlinux EXPORT_SYMBOL
+-0xaa4a7797    hex2bin vmlinux EXPORT_SYMBOL
+-0xe924fd45    crypto_default_rng      vmlinux EXPORT_SYMBOL_GPL
+-0xddab6b08    d_make_root     vmlinux EXPORT_SYMBOL
+-0xa3b40cfd    hid_register_report     vmlinux EXPORT_SYMBOL_GPL
+-0xcda04a5b    v4l2_prio_close vmlinux EXPORT_SYMBOL
+-0x2e12216c    rtc_set_alarm   vmlinux EXPORT_SYMBOL_GPL
+-0xaefe5034    __scsi_get_command      vmlinux EXPORT_SYMBOL_GPL
+-0x31547da3    __scsi_put_command      vmlinux EXPORT_SYMBOL
+-0x0fa5f996    inet_csk_listen_start   vmlinux EXPORT_SYMBOL_GPL
+-0xfcc2a43c    utf32_to_utf8   vmlinux EXPORT_SYMBOL
+-0xeef161aa    groups_free     vmlinux EXPORT_SYMBOL
+-0xc5a25ce7    cleanup_srcu_struct     vmlinux EXPORT_SYMBOL_GPL
+-0xac1a55be    unregister_reboot_notifier      vmlinux EXPORT_SYMBOL
+-0x4557930f    regmap_update_bits_check        vmlinux EXPORT_SYMBOL_GPL
+-0x0e0eb67f    ip6_flush_pending_frames        vmlinux EXPORT_SYMBOL_GPL
+-0xb670b4cf    tcf_destroy_chain       vmlinux EXPORT_SYMBOL
+-0x5fa48b4e    generic_file_remap_pages        vmlinux EXPORT_SYMBOL
+-0xe13fa8ed    regmap_register_patch   vmlinux EXPORT_SYMBOL_GPL
+-0x18c77c17    tty_perform_flush       vmlinux EXPORT_SYMBOL_GPL
+-0x5ece6555    debugfs_remove_recursive        vmlinux EXPORT_SYMBOL_GPL
+-0x1fcf4d4b    _raw_read_unlock_bh     vmlinux EXPORT_SYMBOL
+-0x04cabed9    rfkill_register vmlinux EXPORT_SYMBOL
+-0x774a552a    cfg80211_send_deauth    vmlinux EXPORT_SYMBOL
+-0xc1691764    neigh_parms_alloc       vmlinux EXPORT_SYMBOL
+-0x75fac20b    mount_single    vmlinux EXPORT_SYMBOL
+-0x9ecc6a7a    interruptible_sleep_on  vmlinux EXPORT_SYMBOL
+-0x19a304ba    usb_disabled    vmlinux EXPORT_SYMBOL_GPL
+-0x48f20051    __ip_route_output_key   vmlinux EXPORT_SYMBOL_GPL
+-0x5e7f4920    snd_pcm_format_set_silence      vmlinux EXPORT_SYMBOL
+-0x9ef5a297    blk_queue_invalidate_tags       vmlinux EXPORT_SYMBOL
+-0xffb6db4a    remove_irq      vmlinux EXPORT_SYMBOL_GPL
+-0x93a6e0b2    io_schedule     vmlinux EXPORT_SYMBOL
+-0xa604bba5    cpufreq_notify_transition       vmlinux EXPORT_SYMBOL_GPL
+-0xb9c425de    register_syscore_ops    vmlinux EXPORT_SYMBOL_GPL
+-0x7317fc49    disk_part_iter_next     vmlinux EXPORT_SYMBOL_GPL
+-0xc4c6c770    block_write_end vmlinux EXPORT_SYMBOL
+-0x437e0be6    pid_vnr vmlinux EXPORT_SYMBOL_GPL
+-0xcb476f4a    cfb_fillrect    vmlinux EXPORT_SYMBOL
+-0xc6241aec    cfg80211_roamed_bss     vmlinux EXPORT_SYMBOL
+-0x44336387    __xfrm_decode_session   vmlinux EXPORT_SYMBOL
+-0xf803fe39    bitmap_set      vmlinux EXPORT_SYMBOL
+-0x1bbcbb78    __pagevec_lru_add       vmlinux EXPORT_SYMBOL
+-0xd1b2db37    tracepoint_probe_register_noupdate      vmlinux EXPORT_SYMBOL_GPL
+-0x230e0698    __clocksource_updatefreq_scale  vmlinux EXPORT_SYMBOL_GPL
+-0xd8004073    sdhci_runtime_resume_host       vmlinux EXPORT_SYMBOL_GPL
+-0x04369954    devm_regmap_init        vmlinux EXPORT_SYMBOL_GPL
+-0xa2a36526    tty_port_lower_dtr_rts  vmlinux EXPORT_SYMBOL
+-0xf369df34    wiphy_rfkill_stop_polling       vmlinux EXPORT_SYMBOL
+-0x253ec879    netlink_set_err vmlinux EXPORT_SYMBOL
+-0x71d7bf40    alloc_netdev_mqs        vmlinux EXPORT_SYMBOL
+-0x336154ca    rcutorture_record_test_transition       vmlinux EXPORT_SYMBOL_GPL
+-0x1aa1c9f2    make_kprojid    vmlinux EXPORT_SYMBOL
+-0xa42a123d    bus_register_notifier   vmlinux EXPORT_SYMBOL_GPL
+-0xd2cf977d    gpiochip_add    vmlinux EXPORT_SYMBOL_GPL
+-0xd3c40b56    inet_listen     vmlinux EXPORT_SYMBOL
+-0xfdc9a24f    __dst_destroy_metrics_generic   vmlinux EXPORT_SYMBOL
+-0x44e276d8    skb_queue_purge vmlinux EXPORT_SYMBOL
+-0x588eccde    get_unmapped_area       vmlinux EXPORT_SYMBOL
+-0x0f29f7c9    add_to_page_cache_lru   vmlinux EXPORT_SYMBOL_GPL
+-0xb7d4b252    iommu_present   vmlinux EXPORT_SYMBOL_GPL
+-0x01c483a9    v4l2_get_timestamp      vmlinux EXPORT_SYMBOL_GPL
+-0xbf041102    register_vt_notifier    vmlinux EXPORT_SYMBOL_GPL
+-0xf85885d1    nci_unregister_device   vmlinux EXPORT_SYMBOL
+-0x07b52e38    rtnl_unregister vmlinux EXPORT_SYMBOL_GPL
+-0xe3bc40f6    dpcm_be_dai_trigger     vmlinux EXPORT_SYMBOL_GPL
+-0xfbed2f3c    snd_soc_info_volsw_range        vmlinux EXPORT_SYMBOL_GPL
+-0x9545974d    blk_rq_map_user vmlinux EXPORT_SYMBOL
+-0x693ca44e    jbd2_journal_clear_features     vmlinux EXPORT_SYMBOL
+-0x538410d3    generic_pipe_buf_release        vmlinux EXPORT_SYMBOL
+-0x8878cfa6    gether_cleanup  vmlinux EXPORT_SYMBOL
+-0xc1c72997    platform_bus_type       vmlinux EXPORT_SYMBOL_GPL
+-0x2c61162c    drm_fb_helper_check_var vmlinux EXPORT_SYMBOL
+-0x7a8cea07    bt_accept_unlink        vmlinux EXPORT_SYMBOL
+-0x61812beb    nf_ct_gre_keymap_add    vmlinux EXPORT_SYMBOL_GPL
+-0xcf596042    d_find_alias    vmlinux EXPORT_SYMBOL
+-0x81d10f5f    trace_seq_putc  vmlinux EXPORT_SYMBOL
+-0x760a0f4f    yield   vmlinux EXPORT_SYMBOL
+-0xac472389    iio_buffer_register     vmlinux EXPORT_SYMBOL
+-0x5dd590c3    sdhci_pltfm_pmops       vmlinux EXPORT_SYMBOL_GPL
+-0x0c5b9900    xt_check_target vmlinux EXPORT_SYMBOL_GPL
+-0xb67c64fd    __tracepoint_kfree_skb  vmlinux EXPORT_SYMBOL_GPL
+-0xd6c2e04b    __tracepoint_napi_poll  vmlinux EXPORT_SYMBOL_GPL
+-0x01bb81cc    netdev_upper_dev_unlink vmlinux EXPORT_SYMBOL
+-0x5bb9daec    __sg_page_iter_start    vmlinux EXPORT_SYMBOL
+-0xac3d64d9    fsstack_copy_attr_all   vmlinux EXPORT_SYMBOL_GPL
+-0xda48e711    sdio_claim_irq  vmlinux EXPORT_SYMBOL_GPL
+-0x1dc36131    fb_destroy_modedb       vmlinux EXPORT_SYMBOL
+-0xca2159d7    udp6_lib_lookup vmlinux EXPORT_SYMBOL_GPL
+-0xbf58f5e7    xfrm_init_replay        vmlinux EXPORT_SYMBOL
+-0xfb74be78    udp4_lib_lookup vmlinux EXPORT_SYMBOL_GPL
+-0x419cfeed    __nf_ct_try_assign_helper       vmlinux EXPORT_SYMBOL_GPL
+-0x610dbc32    genl_unregister_ops     vmlinux EXPORT_SYMBOL
+-0x9e2000a7    memcpy_toiovecend       vmlinux EXPORT_SYMBOL
+-0x3fc5d39f    snd_jack_report vmlinux EXPORT_SYMBOL
+-0x93949c2a    inode_sb_list_add       vmlinux EXPORT_SYMBOL_GPL
+-0x3d4ee67b    inode_init_always       vmlinux EXPORT_SYMBOL
+-0x38883d79    d_invalidate    vmlinux EXPORT_SYMBOL
+-0xa0b04675    vmalloc_32      vmlinux EXPORT_SYMBOL
+-0xedca9389    pid_task        vmlinux EXPORT_SYMBOL
+-0xc1c2b8e5    scsi_command_normalize_sense    vmlinux EXPORT_SYMBOL
+-0x4d0d163d    copy_page       vmlinux EXPORT_SYMBOL
+-0xe0becdbc    set_h245_addr_hook      vmlinux EXPORT_SYMBOL_GPL
+-0xd9a79782    seq_print_acct  vmlinux EXPORT_SYMBOL_GPL
+-0xbc9f30d7    textsearch_unregister   vmlinux EXPORT_SYMBOL
+-0xf54c51a2    dma_pool_free   vmlinux EXPORT_SYMBOL
+-0x32fd447a    monotonic_to_bootbased  vmlinux EXPORT_SYMBOL_GPL
+-0x45a6be13    cpufreq_sysfs_remove_file       vmlinux EXPORT_SYMBOL
+-0x9a5723c8    input_register_handler  vmlinux EXPORT_SYMBOL
+-0x0f618e15    drm_class_device_unregister     vmlinux EXPORT_SYMBOL_GPL
+-0xbae73813    inet6_csk_bind_conflict vmlinux EXPORT_SYMBOL_GPL
+-0xa35de80f    ipv4_config     vmlinux EXPORT_SYMBOL
+-0x7411b488    netif_carrier_on        vmlinux EXPORT_SYMBOL
+-0x1212d241    fib_rules_lookup        vmlinux EXPORT_SYMBOL_GPL
+-0xb0b847ac    __bitmap_full   vmlinux EXPORT_SYMBOL
+-0x4059792f    print_hex_dump  vmlinux EXPORT_SYMBOL
+-0x99d40bce    cfg80211_del_sta        vmlinux EXPORT_SYMBOL
+-0xe8068f48    ip6_route_output        vmlinux EXPORT_SYMBOL
+-0xb57e5e86    __dst_free      vmlinux EXPORT_SYMBOL
+-0x9fb986a9    inode_newsize_ok        vmlinux EXPORT_SYMBOL
+-0xf39a1727    dev_pm_qos_add_notifier vmlinux EXPORT_SYMBOL_GPL
+-0xbb6297fd    drm_mode_group_init_legacy_group        vmlinux EXPORT_SYMBOL
+-0xd3ce735a    drm_crtc_helper_set_config      vmlinux EXPORT_SYMBOL
+-0xa68b2c0b    pn_sock_get_port        vmlinux EXPORT_SYMBOL
+-0x04797338    inet_csk_destroy_sock   vmlinux EXPORT_SYMBOL
+-0x050e881c    inet_peer_base_init     vmlinux EXPORT_SYMBOL_GPL
+-0x84b183ae    strncmp vmlinux EXPORT_SYMBOL
+-0xb6f24459    crypto_register_shashes vmlinux EXPORT_SYMBOL_GPL
+-0x1e26be3b    get_anon_bdev   vmlinux EXPORT_SYMBOL
+-0x6b29a1fa    ring_buffer_event_length        vmlinux EXPORT_SYMBOL_GPL
+-0x5634e278    __clk_get_flags vmlinux EXPORT_SYMBOL_GPL
+-0x2e1ca751    clk_put vmlinux EXPORT_SYMBOL
+-0xf474a207    usb_gadget_config_buf   vmlinux EXPORT_SYMBOL_GPL
+-0x20838fc5    __pm_runtime_idle       vmlinux EXPORT_SYMBOL_GPL
+-0x062de44d    sock_kfree_s    vmlinux EXPORT_SYMBOL
+-0x3796bdcc    snd_pcm_format_little_endian    vmlinux EXPORT_SYMBOL
+-0xa34f1ef5    crc32_le        vmlinux EXPORT_SYMBOL
+-0xf54bd49b    lcm     vmlinux EXPORT_SYMBOL_GPL
+-0x13354608    scatterwalk_map_and_copy        vmlinux EXPORT_SYMBOL_GPL
+-0xf2bec139    empty_aops      vmlinux EXPORT_SYMBOL
+-0x45755a66    __task_pid_nr_ns        vmlinux EXPORT_SYMBOL
+-0xcbc23c9a    ethtool_op_get_link     vmlinux EXPORT_SYMBOL
+-0x5735fbd5    read_cache_pages        vmlinux EXPORT_SYMBOL
+-0x4aadeb9a    ring_buffer_alloc_read_page     vmlinux EXPORT_SYMBOL_GPL
+-0x2f3f62cd    v4l2_try_ext_ctrls      vmlinux EXPORT_SYMBOL
+-0x5d12e48f    input_event_to_user     vmlinux EXPORT_SYMBOL_GPL
+-0x6947468c    input_unregister_device vmlinux EXPORT_SYMBOL
+-0x91600a8e    usb_string_id   vmlinux EXPORT_SYMBOL_GPL
+-0xcc924d52    regulator_disable_regmap        vmlinux EXPORT_SYMBOL_GPL
+-0x3a4402b4    ip_generic_getfrag      vmlinux EXPORT_SYMBOL
+-0x6308d2cf    call_netdevice_notifiers        vmlinux EXPORT_SYMBOL
+-0xc02df0b8    snd_soc_pm_ops  vmlinux EXPORT_SYMBOL_GPL
+-0xf9436986    crypto_dequeue_request  vmlinux EXPORT_SYMBOL_GPL
+-0xb6555d54    crypto_enqueue_request  vmlinux EXPORT_SYMBOL_GPL
+-0x6c2dc956    fat_add_entries vmlinux EXPORT_SYMBOL_GPL
+-0xb7fc7a60    thaw_bdev       vmlinux EXPORT_SYMBOL
+-0x99a170f8    kmem_cache_alloc_trace  vmlinux EXPORT_SYMBOL
+-0x06f22ca2    irq_create_mapping      vmlinux EXPORT_SYMBOL_GPL
+-0x992e5dbd    mii_nway_restart        vmlinux EXPORT_SYMBOL
+-0xa6a0a273    max77693_write_reg      vmlinux EXPORT_SYMBOL_GPL
+-0xa6b21ef2    dpm_suspend_end vmlinux EXPORT_SYMBOL_GPL
+-0x27f9262d    sk_run_filter   vmlinux EXPORT_SYMBOL
+-0x8bfe698b    netdev_rx_csum_fault    vmlinux EXPORT_SYMBOL
+-0x9e61bb05    set_freezable   vmlinux EXPORT_SYMBOL
+-0xd5418207    devres_release_group    vmlinux EXPORT_SYMBOL_GPL
+-0x45669e2c    drm_fb_helper_restore_fbdev_mode        vmlinux EXPORT_SYMBOL
+-0x93fcb0ed    bt_sock_reclassify_lock vmlinux EXPORT_SYMBOL
+-0xb6d8be2d    ipv6_push_nfrag_opts    vmlinux EXPORT_SYMBOL
+-0x8cdb54d7    ipt_register_table      vmlinux EXPORT_SYMBOL
+-0xcc0aef97    neigh_sysctl_unregister vmlinux EXPORT_SYMBOL
+-0xe56a9336    snd_pcm_format_width    vmlinux EXPORT_SYMBOL
+-0x9077c297    blk_abort_request       vmlinux EXPORT_SYMBOL_GPL
+-0x6ed8eb1f    extcon_register_notifier        vmlinux EXPORT_SYMBOL_GPL
+-0xc9561772    fb_destroy_modelist     vmlinux EXPORT_SYMBOL_GPL
+-0xf494fae4    tcp_peer_is_proven      vmlinux EXPORT_SYMBOL_GPL
+-0xdc70cab5    __scm_destroy   vmlinux EXPORT_SYMBOL
+-0xfb2acf00    snd_mixer_oss_notify_callback   vmlinux EXPORT_SYMBOL
+-0x3a016c77    d_move  vmlinux EXPORT_SYMBOL
+-0x5091b823    ring_buffer_read_start  vmlinux EXPORT_SYMBOL_GPL
+-0x171751ed    sdio_writeb_readb       vmlinux EXPORT_SYMBOL_GPL
+-0x3d94fdae    usb_put_phy     vmlinux EXPORT_SYMBOL_GPL
+-0xfbf7bde5    drm_crtc_cleanup        vmlinux EXPORT_SYMBOL
+-0x52aaee97    amba_ahb_device_add_res vmlinux EXPORT_SYMBOL_GPL
+-0xd0706e35    phy_pm_runtime_put      vmlinux EXPORT_SYMBOL_GPL
+-0x0ff178f6    __aeabi_idivmod vmlinux EXPORT_SYMBOL
+-0xfb11005b    ipcomp_destroy  vmlinux EXPORT_SYMBOL_GPL
+-0x6f81b189    dev_addr_del_multiple   vmlinux EXPORT_SYMBOL
+-0xf5ce8c40    touch_atime     vmlinux EXPORT_SYMBOL
+-0x53614269    get_cpu_idle_time_us    vmlinux EXPORT_SYMBOL_GPL
+-0x61c243fc    mod_timer_pending       vmlinux EXPORT_SYMBOL
+-0xf821b501    device_set_wakeup_capable       vmlinux EXPORT_SYMBOL_GPL
+-0x80bbfeb1    s3c_gpio_cfgall_range   vmlinux EXPORT_SYMBOL_GPL
+-0x10081d73    s3c_gpio_cfgpin_range   vmlinux EXPORT_SYMBOL_GPL
+-0x75464443    phonet_proto_unregister vmlinux EXPORT_SYMBOL
+-0x7d6fed76    rtnl_configure_link     vmlinux EXPORT_SYMBOL
+-0x8c844510    sock_wmalloc    vmlinux EXPORT_SYMBOL
+-0xbaf75338    snd_soc_codec_writable_register vmlinux EXPORT_SYMBOL_GPL
+-0x1e6d26a8    strstr  vmlinux EXPORT_SYMBOL
+-0xea6f9ca2    task_user_regset_view   vmlinux EXPORT_SYMBOL_GPL
+-0x4de17ab3    usb_state_string        vmlinux EXPORT_SYMBOL_GPL
+-0x349cba85    strchr  vmlinux EXPORT_SYMBOL
+-0xb83a0cc6    perf_event_disable      vmlinux EXPORT_SYMBOL_GPL
+-0x3b5965e0    inet_csk_listen_stop    vmlinux EXPORT_SYMBOL_GPL
+-0x6be59bed    kobject_create_and_add  vmlinux EXPORT_SYMBOL_GPL
+-0xdced71ac    setup_new_exec  vmlinux EXPORT_SYMBOL
+-0xdb8a1b3f    usermodehelper_read_trylock     vmlinux EXPORT_SYMBOL_GPL
+-0x7c9ad2eb    usb_wait_anchor_empty_timeout   vmlinux EXPORT_SYMBOL_GPL
+-0xf2fca922    uart_parse_options      vmlinux EXPORT_SYMBOL_GPL
+-0x7f63b31e    _memcpy_toio    vmlinux EXPORT_SYMBOL
+-0x3e3fcdf2    xfrm_state_lookup_byaddr        vmlinux EXPORT_SYMBOL
+-0x2b538790    pskb_expand_head        vmlinux EXPORT_SYMBOL
+-0xdb67d9bb    of_i2c_register_devices vmlinux EXPORT_SYMBOL
+-0x9f7314d6    wakeup_source_prepare   vmlinux EXPORT_SYMBOL_GPL
+-0x2a828cb7    drm_noop        vmlinux EXPORT_SYMBOL
+-0x3d3c540f    elf_hwcap       vmlinux EXPORT_SYMBOL
+-0xa045219b    fuse_do_ioctl   vmlinux EXPORT_SYMBOL_GPL
+-0x8fa5cf61    pm_qos_update_request   vmlinux EXPORT_SYMBOL_GPL
+-0x73514fba    i2c_release_client      vmlinux EXPORT_SYMBOL
+-0x168db450    take_over_console       vmlinux EXPORT_SYMBOL
+-0x0aa13d05    __raw_readsw    vmlinux EXPORT_SYMBOL
+-0x816a1ee5    rtnl_link_register      vmlinux EXPORT_SYMBOL_GPL
+-0x9fd1a952    sk_set_memalloc vmlinux EXPORT_SYMBOL_GPL
+-0x8605ed02    lock_may_write  vmlinux EXPORT_SYMBOL
+-0xb24e73ff    bh_submit_read  vmlinux EXPORT_SYMBOL
+-0x455db47d    dma_mark_declared_memory_occupied       vmlinux EXPORT_SYMBOL
+-0x1a65f4ad    __arm_ioremap_pfn       vmlinux EXPORT_SYMBOL
+-0x955e8436    eth_change_mtu  vmlinux EXPORT_SYMBOL
+-0xa300e599    eth_header_parse        vmlinux EXPORT_SYMBOL
+-0x42977ad4    __hw_addr_del_multiple  vmlinux EXPORT_SYMBOL
+-0xf57de517    bdev_stack_limits       vmlinux EXPORT_SYMBOL
+-0x25bed5a1    static_key_slow_dec_deferred    vmlinux EXPORT_SYMBOL_GPL
+-0xd2aaeb4e    kmsg_dump_get_buffer    vmlinux EXPORT_SYMBOL_GPL
+-0xedb320d6    nf_nat_pptp_hook_exp_gre        vmlinux EXPORT_SYMBOL_GPL
+-0xdc0a9f66    sock_wake_async vmlinux EXPORT_SYMBOL
+-0x68e05d57    getrawmonotonic vmlinux EXPORT_SYMBOL
+-0xee715ef8    lg_global_unlock        vmlinux EXPORT_SYMBOL
+-0xbebb2820    crypto_register_algs    vmlinux EXPORT_SYMBOL_GPL
+-0xccc2bc05    fat_free_clusters       vmlinux EXPORT_SYMBOL_GPL
+-0xde99c012    jbd2_complete_transaction       vmlinux EXPORT_SYMBOL
+-0x60599993    __set_page_dirty_buffers        vmlinux EXPORT_SYMBOL
+-0x8b775d3a    __wake_up_locked        vmlinux EXPORT_SYMBOL_GPL
+-0x93eb18c6    of_platform_device_create       vmlinux EXPORT_SYMBOL
+-0x9e5bfa34    bt_sock_poll    vmlinux EXPORT_SYMBOL
+-0x7e98f5ff    sock_prot_inuse_add     vmlinux EXPORT_SYMBOL_GPL
+-0xf9e73082    scnprintf       vmlinux EXPORT_SYMBOL
+-0xa1b4cc6a    aead_geniv_exit vmlinux EXPORT_SYMBOL_GPL
+-0xa7001f92    mod_zone_page_state     vmlinux EXPORT_SYMBOL
+-0x92e79788    perf_event_refresh      vmlinux EXPORT_SYMBOL_GPL
+-0x77e7babf    usb_hcd_platform_shutdown       vmlinux EXPORT_SYMBOL_GPL
+-0x6d4d6df5    s3c_gpio_cfgpin vmlinux EXPORT_SYMBOL
+-0x7f250a18    tcf_register_action     vmlinux EXPORT_SYMBOL
+-0x41852af3    blk_add_request_payload vmlinux EXPORT_SYMBOL_GPL
+-0x8bf05477    pm_runtime_autosuspend_expiration       vmlinux EXPORT_SYMBOL_GPL
+-0xea25f714    rtnl_link_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0x5f75b2b7    snd_soc_dapm_enable_pin vmlinux EXPORT_SYMBOL_GPL
+-0x87879778    copy_strings_kernel     vmlinux EXPORT_SYMBOL
+-0x731b81f1    __wait_on_bit   vmlinux EXPORT_SYMBOL
+-0x18838e93    hrtimer_get_remaining   vmlinux EXPORT_SYMBOL_GPL
+-0x0be4ca5a    extcon_set_state        vmlinux EXPORT_SYMBOL_GPL
+-0xacdf7eb6    led_trigger_register_simple     vmlinux EXPORT_SYMBOL_GPL
+-0x20645642    drm_debug       vmlinux EXPORT_SYMBOL
+-0x5f41d1f8    rdev_get_id     vmlinux EXPORT_SYMBOL_GPL
+-0xf6f440a6    tcp_enter_memory_pressure       vmlinux EXPORT_SYMBOL
+-0x3b9a9d19    skb_add_rx_frag vmlinux EXPORT_SYMBOL
+-0x32b2bc89    snd_soc_write   vmlinux EXPORT_SYMBOL_GPL
+-0x5b44d926    snd_soc_get_xr_sx       vmlinux EXPORT_SYMBOL_GPL
+-0xf1395b13    snd_soc_put_xr_sx       vmlinux EXPORT_SYMBOL_GPL
+-0x4982a57f    probe_kernel_write      vmlinux EXPORT_SYMBOL_GPL
+-0x811dc334    usb_unregister_notify   vmlinux EXPORT_SYMBOL_GPL
+-0xa6f7283b    arp_create      vmlinux EXPORT_SYMBOL
+-0x660b5392    jbd2_journal_get_create_access  vmlinux EXPORT_SYMBOL
+-0x99dd4a27    no_llseek       vmlinux EXPORT_SYMBOL
+-0x72532806    _raw_read_unlock_irq    vmlinux EXPORT_SYMBOL
+-0xe4719990    rt_mutex_timed_lock     vmlinux EXPORT_SYMBOL_GPL
+-0xb5d9454c    printk_emit     vmlinux EXPORT_SYMBOL
+-0x801e5a15    st_sensors_check_device_support vmlinux EXPORT_SYMBOL
+-0xeec77f6d    iio_map_array_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0x6390efda    of_modalias_node        vmlinux EXPORT_SYMBOL_GPL
+-0x7ac03539    tty_port_alloc_xmit_buf vmlinux EXPORT_SYMBOL
+-0x5cebb76e    vfs_truncate    vmlinux EXPORT_SYMBOL_GPL
+-0xfc52a8aa    mmc_gpio_request_cd     vmlinux EXPORT_SYMBOL
+-0xf7a4e432    mmc_gpio_request_ro     vmlinux EXPORT_SYMBOL
+-0x74d52889    rtc_irq_set_freq        vmlinux EXPORT_SYMBOL_GPL
+-0x8e9efd84    dma_declare_coherent_memory     vmlinux EXPORT_SYMBOL
+-0xfcfa03ff    fb_videomode_to_modelist        vmlinux EXPORT_SYMBOL
+-0x789c0277    nfc_unregister_device   vmlinux EXPORT_SYMBOL
+-0x48744ce2    lro_receive_frags       vmlinux EXPORT_SYMBOL
+-0xf6851d5f    register_sysctl_paths   vmlinux EXPORT_SYMBOL
+-0x90a4a466    generic_show_options    vmlinux EXPORT_SYMBOL
+-0x74dd4a76    pagecache_write_begin   vmlinux EXPORT_SYMBOL
+-0x7b42b5d4    drm_mode_copy   vmlinux EXPORT_SYMBOL
+-0x6a7c03c7    asoc_dma_platform_register      vmlinux EXPORT_SYMBOL_GPL
+-0xc6cbbc89    capable vmlinux EXPORT_SYMBOL
+-0xd07125d9    spi_finalize_current_message    vmlinux EXPORT_SYMBOL_GPL
+-0xf5514ce6    dev_pm_qos_add_request  vmlinux EXPORT_SYMBOL_GPL
+-0xb316e246    nf_afinfo       vmlinux EXPORT_SYMBOL
+-0x4ef5bcf4    perf_swevent_get_recursion_context      vmlinux EXPORT_SYMBOL_GPL
+-0xab7e3362    irq_find_mapping        vmlinux EXPORT_SYMBOL_GPL
+-0xbcf89ab6    __wake_up_sync  vmlinux EXPORT_SYMBOL_GPL
+-0xc8b57c27    autoremove_wake_function        vmlinux EXPORT_SYMBOL
+-0x36aa3266    hid_debug_event vmlinux EXPORT_SYMBOL_GPL
+-0x9ed21fce    mmc_can_trim    vmlinux EXPORT_SYMBOL
+-0x5658ad69    v4l2_async_register_subdev      vmlinux EXPORT_SYMBOL
+-0x99781445    input_set_capability    vmlinux EXPORT_SYMBOL
+-0xf3343f80    drm_mode_create_tv_properties   vmlinux EXPORT_SYMBOL
+-0x69fefbb6    nf_ct_port_tuple_to_nlattr      vmlinux EXPORT_SYMBOL_GPL
+-0xd9a9bb30    getname vmlinux EXPORT_SYMBOL
+-0xe7ffe877    pcpu_base_addr  vmlinux EXPORT_SYMBOL_GPL
+-0x131e7ee8    drm_fb_helper_hotplug_event     vmlinux EXPORT_SYMBOL
+-0x983f0520    drm_fb_helper_initial_config    vmlinux EXPORT_SYMBOL
+-0x469972c2    give_up_console vmlinux EXPORT_SYMBOL
+-0x300573d1    nf_conntrack_helper_register    vmlinux EXPORT_SYMBOL_GPL
+-0x2597c27d    snd_seq_root    vmlinux EXPORT_SYMBOL
+-0x9a11a0fc    crypto_attr_alg_name    vmlinux EXPORT_SYMBOL_GPL
+-0xa0f2a42b    debugfs_create_regset32 vmlinux EXPORT_SYMBOL_GPL
+-0x3e08c129    drm_mode_find_dmt       vmlinux EXPORT_SYMBOL
+-0xbc8b0f41    xfrm_calg_get_byid      vmlinux EXPORT_SYMBOL_GPL
+-0xf20dabd8    free_irq        vmlinux EXPORT_SYMBOL
+-0x9073a3d4    usb_hc_died     vmlinux EXPORT_SYMBOL_GPL
+-0xe61a6d2f    gpio_unexport   vmlinux EXPORT_SYMBOL_GPL
+-0xdf58d91e    pinctrl_dev_get_name    vmlinux EXPORT_SYMBOL_GPL
+-0x4c3b5878    ieee80211_get_response_rate     vmlinux EXPORT_SYMBOL
+-0xa6b9609a    jbd2_journal_init_inode vmlinux EXPORT_SYMBOL
+-0xe91ef2b5    deactivate_locked_super vmlinux EXPORT_SYMBOL
+-0x0280cf55    filemap_fdatawait       vmlinux EXPORT_SYMBOL
+-0x134178d9    v4l2_m2m_fop_mmap       vmlinux EXPORT_SYMBOL_GPL
+-0x9091c717    netdev_class_create_file        vmlinux EXPORT_SYMBOL
+-0x4f816e9b    snd_pcm_format_big_endian       vmlinux EXPORT_SYMBOL
+-0x09d44df9    in_lock_functions       vmlinux EXPORT_SYMBOL
+-0x509817cf    vprintk_emit    vmlinux EXPORT_SYMBOL
+-0x4c571d12    cfg80211_cqm_pktloss_notify     vmlinux EXPORT_SYMBOL
+-0x8b260b7f    ip6_tnl_xmit_ctl        vmlinux EXPORT_SYMBOL_GPL
+-0x7b9e609a    ip6_sk_update_pmtu      vmlinux EXPORT_SYMBOL_GPL
+-0x199db92b    netdev_rx_handler_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0x4cdf24a6    skb_copy_datagram_const_iovec   vmlinux EXPORT_SYMBOL
+-0xb994401f    kernel_getpeername      vmlinux EXPORT_SYMBOL
+-0x7b10e656    sysfs_chmod_file        vmlinux EXPORT_SYMBOL_GPL
+-0x55d7c934    find_module     vmlinux EXPORT_SYMBOL_GPL
+-0x548b482c    rt_mutex_lock   vmlinux EXPORT_SYMBOL_GPL
+-0x39533602    media_entity_graph_walk_start   vmlinux EXPORT_SYMBOL_GPL
+-0x51ef2459    platform_driver_probe   vmlinux EXPORT_SYMBOL_GPL
+-0xeb93a8ee    serial8250_do_set_termios       vmlinux EXPORT_SYMBOL
+-0x8afc7ce3    __devm_of_phy_provider_register vmlinux EXPORT_SYMBOL_GPL
+-0x548fedb9    skb_complete_wifi_ack   vmlinux EXPORT_SYMBOL_GPL
+-0x11f7ed4c    hex_to_bin      vmlinux EXPORT_SYMBOL
+-0x9aeecd64    simple_pin_fs   vmlinux EXPORT_SYMBOL
+-0x5635a60a    vmalloc_user    vmlinux EXPORT_SYMBOL
+-0xd36ab13e    posix_clock_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0x1fe9f800    unregister_cpu_notifier vmlinux EXPORT_SYMBOL
+-0xb59a9548    vb2_expbuf      vmlinux EXPORT_SYMBOL_GPL
+-0xf6eb0d71    input_event     vmlinux EXPORT_SYMBOL
+-0xfc3a261f    dev_get_regmap  vmlinux EXPORT_SYMBOL_GPL
+-0x89d145ed    pin_config_get  vmlinux EXPORT_SYMBOL
+-0xc54fc2d7    devm_pinctrl_put        vmlinux EXPORT_SYMBOL_GPL
+-0x9671e047    devm_pinctrl_get        vmlinux EXPORT_SYMBOL_GPL
+-0x4d45d89e    udp_memory_allocated    vmlinux EXPORT_SYMBOL
+-0x3e8b4fda    tc_classify     vmlinux EXPORT_SYMBOL
+-0x98509e55    sock_no_sendpage        vmlinux EXPORT_SYMBOL
+-0x7bd6700d    blk_pre_runtime_suspend vmlinux EXPORT_SYMBOL
+-0x6444b7bb    iio_read_channel_raw    vmlinux EXPORT_SYMBOL_GPL
+-0x70120108    thermal_generate_netlink_event  vmlinux EXPORT_SYMBOL_GPL
+-0x800e4ffa    __muldi3        vmlinux EXPORT_SYMBOL
+-0x4c1182cb    bitmap_scnprintf        vmlinux EXPORT_SYMBOL
+-0xd7b4599b    __idr_get_new_above     vmlinux EXPORT_SYMBOL
+-0x368dc456    proc_create_data        vmlinux EXPORT_SYMBOL
+-0x4d405db8    param_ops_string        vmlinux EXPORT_SYMBOL
+-0xdd021b6b    get_current_tty vmlinux EXPORT_SYMBOL_GPL
+-0xabbaaf4c    kernel_getsockname      vmlinux EXPORT_SYMBOL
+-0x5caf4413    kernel_sendmsg  vmlinux EXPORT_SYMBOL
+-0x3971b4df    snd_ecards_limit        vmlinux EXPORT_SYMBOL
+-0xd77a5aa5    __bitmap_and    vmlinux EXPORT_SYMBOL
+-0xfac05b29    unregister_gadget_item  vmlinux EXPORT_SYMBOL
+-0x268930d0    uart_register_driver    vmlinux EXPORT_SYMBOL
+-0xace7ae5c    xfrm_alloc_spi  vmlinux EXPORT_SYMBOL
+-0x0a4a1a2f    blk_rq_err_bytes        vmlinux EXPORT_SYMBOL_GPL
+-0x6d414f53    crypto_blkcipher_type   vmlinux EXPORT_SYMBOL_GPL
+-0x2ffe9a6b    crypto_givcipher_type   vmlinux EXPORT_SYMBOL_GPL
+-0xe5ddcbd8    nfc_targets_found       vmlinux EXPORT_SYMBOL
+-0x028f3057    nf_log_packet   vmlinux EXPORT_SYMBOL
+-0xc8949349    qdisc_tree_decrease_qlen        vmlinux EXPORT_SYMBOL
+-0x7d16c025    dev_remove_pack vmlinux EXPORT_SYMBOL
+-0xf88eb7f2    rq_flush_dcache_pages   vmlinux EXPORT_SYMBOL_GPL
+-0x2d8764e5    blkcipher_walk_virt     vmlinux EXPORT_SYMBOL_GPL
+-0x5fce0dc6    posix_lock_file vmlinux EXPORT_SYMBOL
+-0x71a672ef    dmam_pool_destroy       vmlinux EXPORT_SYMBOL
+-0x3832da09    set_page_dirty  vmlinux EXPORT_SYMBOL
+-0xe4937b31    i2c_bit_algo    vmlinux EXPORT_SYMBOL
+-0x2c256e1f    input_scancode_to_scalar        vmlinux EXPORT_SYMBOL
+-0x758978d2    spi_get_next_queued_message     vmlinux EXPORT_SYMBOL_GPL
+-0xde9360ba    totalram_pages  vmlinux EXPORT_SYMBOL
+-0xacc53440    video_device_alloc      vmlinux EXPORT_SYMBOL
+-0x331f6073    udp_disconnect  vmlinux EXPORT_SYMBOL
+-0x8a5c060e    nf_conntrack_l4proto_udp4       vmlinux EXPORT_SYMBOL_GPL
+-0x492ab82c    dev_uc_unsync   vmlinux EXPORT_SYMBOL
+-0xb1615d69    dev_mc_unsync   vmlinux EXPORT_SYMBOL
+-0xa73acb8d    dump_seek       vmlinux EXPORT_SYMBOL
+-0xea63afac    usb_free_streams        vmlinux EXPORT_SYMBOL_GPL
+-0x0fb8623c    regcache_cache_only     vmlinux EXPORT_SYMBOL_GPL
+-0xb89f40b3    __register_chrdev       vmlinux EXPORT_SYMBOL
+-0x4ed5e0d7    v4l2_chip_match_host    vmlinux EXPORT_SYMBOL
+-0x78272b1e    bus_get_kset    vmlinux EXPORT_SYMBOL_GPL
+-0x87c0bce8    net_dma_find_channel    vmlinux EXPORT_SYMBOL
+-0xc31f408b    __display_entity_register       vmlinux EXPORT_SYMBOL_GPL
+-0x5b1cfbcd    of_get_fb_videomode     vmlinux EXPORT_SYMBOL_GPL
+-0xe6775a2f    fb_show_logo    vmlinux EXPORT_SYMBOL
+-0xa290f4a9    fb_pan_display  vmlinux EXPORT_SYMBOL
+-0x61c2dac6    kstrtoll_from_user      vmlinux EXPORT_SYMBOL
+-0x83904bc7    st_sensors_deallocate_trigger   vmlinux EXPORT_SYMBOL
+-0x7bc41c7c    rtc_class_close vmlinux EXPORT_SYMBOL_GPL
+-0x218b226c    sec_bulk_write  vmlinux EXPORT_SYMBOL_GPL
+-0xf09de776    get_random_int  vmlinux EXPORT_SYMBOL
+-0x5a937d99    blk_queue_stack_limits  vmlinux EXPORT_SYMBOL
+-0x174b7df6    free_vm_area    vmlinux EXPORT_SYMBOL_GPL
+-0x8ffa3ccd    devres_alloc    vmlinux EXPORT_SYMBOL_GPL
+-0x956a91ba    gpio_get_value_cansleep vmlinux EXPORT_SYMBOL_GPL
+-0x92886ef2    udp_lib_setsockopt      vmlinux EXPORT_SYMBOL
+-0xc4a35da7    udp_lib_getsockopt      vmlinux EXPORT_SYMBOL
+-0xdb1ed3be    nf_conntrack_free       vmlinux EXPORT_SYMBOL_GPL
+-0x96898769    sysfs_format_mac        vmlinux EXPORT_SYMBOL
+-0x15604324    sk_send_sigurg  vmlinux EXPORT_SYMBOL
+-0x8fca87b8    proc_set_size   vmlinux EXPORT_SYMBOL
+-0x4b5fd49e    dm_kcopyd_do_callback   vmlinux EXPORT_SYMBOL
+-0x289bc356    mdiobus_alloc_size      vmlinux EXPORT_SYMBOL
+-0xf36e7280    spi_bus_lock    vmlinux EXPORT_SYMBOL_GPL
+-0x0c060ece    cfg80211_sched_scan_stopped     vmlinux EXPORT_SYMBOL
+-0xab2289f2    drop_super      vmlinux EXPORT_SYMBOL
+-0x27e1a049    printk  vmlinux EXPORT_SYMBOL
+-0x3194878b    pm_generic_poweroff_noirq       vmlinux EXPORT_SYMBOL_GPL
+-0x688f09be    dev_crit        vmlinux EXPORT_SYMBOL
+-0xfd94d6cb    drm_get_connector_status_name   vmlinux EXPORT_SYMBOL
+-0xbdef1e6b    drm_gem_object_release  vmlinux EXPORT_SYMBOL
+-0x36fa2c4a    cfg80211_get_bss        vmlinux EXPORT_SYMBOL
+-0xef2e65fd    sk_alloc        vmlinux EXPORT_SYMBOL
+-0x096e7523    try_to_release_page     vmlinux EXPORT_SYMBOL
+-0xa61b1477    tracepoint_iter_start   vmlinux EXPORT_SYMBOL_GPL
+-0x9d05f6c4    ktime_get_clocktai      vmlinux EXPORT_SYMBOL
+-0x6a87a478    synchronize_srcu        vmlinux EXPORT_SYMBOL_GPL
+-0xa3afa3ce    bus_unregister_notifier vmlinux EXPORT_SYMBOL_GPL
+-0xbe001c53    drm_property_add_enum   vmlinux EXPORT_SYMBOL
+-0x48c2a99d    drm_helper_resume_force_mode    vmlinux EXPORT_SYMBOL
+-0x1258d9d9    regulator_disable       vmlinux EXPORT_SYMBOL_GPL
+-0x1b3261e0    klist_iter_init vmlinux EXPORT_SYMBOL_GPL
+-0xaeec4fd1    hci_conn_switch_role    vmlinux EXPORT_SYMBOL
+-0x8809bdee    kobject_add     vmlinux EXPORT_SYMBOL
+-0x10138352    tracing_on      vmlinux EXPORT_SYMBOL_GPL
+-0x39aa4754    dma_buf_mmap    vmlinux EXPORT_SYMBOL_GPL
+-0x58c6fc51    dma_buf_kmap    vmlinux EXPORT_SYMBOL_GPL
+-0x299bbc21    dma_buf_vmap    vmlinux EXPORT_SYMBOL_GPL
+-0x5a2579f9    platform_driver_register        vmlinux EXPORT_SYMBOL_GPL
+-0xa8d6809d    drm_dp_bw_code_to_link_rate     vmlinux EXPORT_SYMBOL
+-0xfd86731b    drm_fb_helper_init      vmlinux EXPORT_SYMBOL
+-0xd4880725    __video_source_register vmlinux EXPORT_SYMBOL_GPL
+-0xe08f4a3d    devm_of_phy_provider_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x61634f05    lock_flocks     vmlinux EXPORT_SYMBOL_GPL
+-0x3843f6b8    queue_kthread_work      vmlinux EXPORT_SYMBOL_GPL
+-0x8e332478    thermal_zone_get_temp   vmlinux EXPORT_SYMBOL_GPL
+-0xdd64085c    platform_driver_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0xaa6f23ad    rfkill_get_led_trigger_name     vmlinux EXPORT_SYMBOL
+-0x9cab34a6    rfkill_set_led_trigger_name     vmlinux EXPORT_SYMBOL
+-0x23b075bd    gnet_stats_copy_queue   vmlinux EXPORT_SYMBOL
+-0x12e85778    kstrtol_from_user       vmlinux EXPORT_SYMBOL
+-0x331504fa    simple_dir_operations   vmlinux EXPORT_SYMBOL
+-0x3eabdee4    of_match_device vmlinux EXPORT_SYMBOL
+-0x610e908e    hid_ignore      vmlinux EXPORT_SYMBOL_GPL
+-0x3838d3de    usb_get_urb     vmlinux EXPORT_SYMBOL_GPL
+-0xd400a944    cfg80211_gtk_rekey_notify       vmlinux EXPORT_SYMBOL
+-0x6403e338    tcp_memory_pressure     vmlinux EXPORT_SYMBOL
+-0x23a650aa    setattr_copy    vmlinux EXPORT_SYMBOL
+-0x6b6b3081    iommu_domain_has_cap    vmlinux EXPORT_SYMBOL_GPL
+-0xdd9fe08e    nfc_hci_driver_failure  vmlinux EXPORT_SYMBOL
+-0x091cae50    cfg80211_probe_status   vmlinux EXPORT_SYMBOL
+-0xa5e8f497    inet_frags_fini vmlinux EXPORT_SYMBOL
+-0xff048999    snd_register_oss_device vmlinux EXPORT_SYMBOL
+-0x24a94b26    snd_info_get_line       vmlinux EXPORT_SYMBOL
+-0x7ba9873c    elv_dispatch_sort       vmlinux EXPORT_SYMBOL
+-0x1471fd44    elv_add_request vmlinux EXPORT_SYMBOL
+-0x9be7bde4    security_tun_dev_attach vmlinux EXPORT_SYMBOL
+-0xf346231f    seq_list_start_head     vmlinux EXPORT_SYMBOL
+-0x65d9e877    cpufreq_register_notifier       vmlinux EXPORT_SYMBOL
+-0x399ed296    v4l2_subdev_link_validate_default       vmlinux EXPORT_SYMBOL_GPL
+-0xfb974dd4    v4l2_ctrl_auto_cluster  vmlinux EXPORT_SYMBOL
+-0xd9097364    v4l2_event_dequeue      vmlinux EXPORT_SYMBOL_GPL
+-0xd9a8b315    scsi_queue_work vmlinux EXPORT_SYMBOL_GPL
+-0xf564412a    __aeabi_ulcmp   vmlinux EXPORT_SYMBOL
+-0x67e6edc4    netif_device_attach     vmlinux EXPORT_SYMBOL
+-0x6c3962d5    netif_device_detach     vmlinux EXPORT_SYMBOL
+-0x7464ec66    netdev_set_default_ethtool_ops  vmlinux EXPORT_SYMBOL_GPL
+-0x08cf6c97    snd_soc_dai_digital_mute        vmlinux EXPORT_SYMBOL_GPL
+-0x47628784    simple_attr_read        vmlinux EXPORT_SYMBOL_GPL
+-0xe4bad1e4    sdhci_pltfm_init        vmlinux EXPORT_SYMBOL_GPL
+-0xe3b2bc37    gether_connect  vmlinux EXPORT_SYMBOL
+-0x2fe1cc7e    device_rename   vmlinux EXPORT_SYMBOL_GPL
+-0xc147be94    drm_i2c_encoder_restore vmlinux EXPORT_SYMBOL
+-0x56f369aa    kernel_bind     vmlinux EXPORT_SYMBOL
+-0xcd279169    nla_find        vmlinux EXPORT_SYMBOL
+-0x5cdf6de2    kernel_read     vmlinux EXPORT_SYMBOL
+-0xfcc43f3f    vfs_read        vmlinux EXPORT_SYMBOL
+-0xc8add232    ring_buffer_record_disable      vmlinux EXPORT_SYMBOL_GPL
+-0xf2e84b50    __devm_release_region   vmlinux EXPORT_SYMBOL
+-0xd4292ec2    dev_notice      vmlinux EXPORT_SYMBOL
+-0x02e6e099    drm_mode_width  vmlinux EXPORT_SYMBOL
+-0xcc248d26    serial8250_suspend_port vmlinux EXPORT_SYMBOL
+-0x4e6e8ea7    fg_console      vmlinux EXPORT_SYMBOL
+-0xbb9cc562    fl6_merge_options       vmlinux EXPORT_SYMBOL_GPL
+-0x20bf8fa2    __inet_hash_nolisten    vmlinux EXPORT_SYMBOL_GPL
+-0x9fb3dd30    memcpy_fromiovec        vmlinux EXPORT_SYMBOL
+-0x9cde26bf    blk_queue_prep_rq       vmlinux EXPORT_SYMBOL
+-0x262f20a8    local_clock     vmlinux EXPORT_SYMBOL_GPL
+-0x7ebf0ef8    __nf_nat_l4proto_find   vmlinux EXPORT_SYMBOL_GPL
+-0x503bc70a    drm_gem_prime_export    vmlinux EXPORT_SYMBOL
+-0x8d6f81b4    __div64_32      vmlinux EXPORT_SYMBOL
+-0x93fca811    __get_free_pages        vmlinux EXPORT_SYMBOL
+-0xbb189cad    disallow_signal vmlinux EXPORT_SYMBOL
+-0xefe5a9bf    usbnet_resume_rx        vmlinux EXPORT_SYMBOL_GPL
+-0x1c4116bc    __class_register        vmlinux EXPORT_SYMBOL_GPL
+-0x72cae0c9    nfc_driver_failure      vmlinux EXPORT_SYMBOL
+-0xc3d70f22    rawv6_mh_filter_register        vmlinux EXPORT_SYMBOL
+-0xdbcd416e    sysctl_ip_nonlocal_bind vmlinux EXPORT_SYMBOL
+-0xa675804c    utf8s_to_utf16s vmlinux EXPORT_SYMBOL
+-0xb4b97c90    pvclock_gtod_register_notifier  vmlinux EXPORT_SYMBOL_GPL
+-0xdf9d0875    ns_capable      vmlinux EXPORT_SYMBOL
+-0x13ba72ba    usb_free_coherent       vmlinux EXPORT_SYMBOL_GPL
+-0x4671c723    rawv6_mh_filter_unregister      vmlinux EXPORT_SYMBOL
+-0x5855bb11    blk_queue_resize_tags   vmlinux EXPORT_SYMBOL
+-0x5159ff6c    mmc_fixup_device        vmlinux EXPORT_SYMBOL
+-0x186b8590    ipv4_specific   vmlinux EXPORT_SYMBOL
+-0x9d5e9b60    nf_ct_l3proto_find_get  vmlinux EXPORT_SYMBOL_GPL
+-0x3f2c16f1    nf_ct_l4proto_find_get  vmlinux EXPORT_SYMBOL_GPL
+-0xe20a528d    nf_queue_entry_release_refs     vmlinux EXPORT_SYMBOL_GPL
+-0x4335fafb    proto_unregister        vmlinux EXPORT_SYMBOL
+-0x5762296f    fuse_conn_kill  vmlinux EXPORT_SYMBOL_GPL
+-0xe473e06d    __fsnotify_inode_delete vmlinux EXPORT_SYMBOL_GPL
+-0xe2ed7067    i2c_new_dummy   vmlinux EXPORT_SYMBOL_GPL
+-0x3cac21b9    regulator_sync_voltage  vmlinux EXPORT_SYMBOL_GPL
+-0x71e7aab0    from_kprojid_munged     vmlinux EXPORT_SYMBOL
+-0x3ca7e128    tty_unlock_pair vmlinux EXPORT_SYMBOL
+-0x146d2f0c    rtnl_af_register        vmlinux EXPORT_SYMBOL_GPL
+-0x97ecf37c    kunmap_high     vmlinux EXPORT_SYMBOL
+-0x4470a79b    param_ops_long  vmlinux EXPORT_SYMBOL
+-0x45bd9efd    dm_table_put    vmlinux EXPORT_SYMBOL
+-0xf2a353ac    v4l2_i2c_tuner_addrs    vmlinux EXPORT_SYMBOL_GPL
+-0xc7fd39bb    drm_dp_channel_eq_ok    vmlinux EXPORT_SYMBOL
+-0xa0472547    inet_csk_update_pmtu    vmlinux EXPORT_SYMBOL_GPL
+-0xacf4d843    match_strdup    vmlinux EXPORT_SYMBOL
+-0x870bf928    radix_tree_lookup       vmlinux EXPORT_SYMBOL
+-0x4672e88b    __crypto_dequeue_request        vmlinux EXPORT_SYMBOL_GPL
+-0x7b0f1ab3    ring_buffer_free_read_page      vmlinux EXPORT_SYMBOL_GPL
+-0x9745b34c    rt_mutex_unlock vmlinux EXPORT_SYMBOL_GPL
+-0xac745cfe    s3c_adc_read    vmlinux EXPORT_SYMBOL_GPL
+-0x4dc817ff    usb_composite_overwrite_options vmlinux EXPORT_SYMBOL_GPL
+-0xcd8ff108    neigh_seq_next  vmlinux EXPORT_SYMBOL
+-0xb4062ffd    vfs_rename      vmlinux EXPORT_SYMBOL
+-0xdc4ed03b    generic_ro_fops vmlinux EXPORT_SYMBOL
+-0x1300b437    nci_register_device     vmlinux EXPORT_SYMBOL
+-0xbcfcecc3    user_path_create        vmlinux EXPORT_SYMBOL
+-0xcf71a180    kthread_bind    vmlinux EXPORT_SYMBOL
+-0x4571f8be    usb_string_ids_n        vmlinux EXPORT_SYMBOL_GPL
+-0xf1ea24f2    ipv6_setsockopt vmlinux EXPORT_SYMBOL
+-0x2d97bed6    dm_kcopyd_zero  vmlinux EXPORT_SYMBOL
+-0xa1f5edea    drm_property_destroy    vmlinux EXPORT_SYMBOL
+-0x3548305a    inet_frag_find  vmlinux EXPORT_SYMBOL
+-0xf937428d    inetdev_by_index        vmlinux EXPORT_SYMBOL
+-0x33f234ad    __sk_backlog_rcv        vmlinux EXPORT_SYMBOL
+-0xb0fbdabc    crypto_lookup_skcipher  vmlinux EXPORT_SYMBOL_GPL
+-0xdf0f75c6    eventfd_signal  vmlinux EXPORT_SYMBOL_GPL
+-0x21f678b9    clocksource_unregister  vmlinux EXPORT_SYMBOL
+-0xe3b5bb1e    usb_poison_anchored_urbs        vmlinux EXPORT_SYMBOL_GPL
+-0x36003409    nfc_hci_send_event      vmlinux EXPORT_SYMBOL
+-0xd26c8ac5    bt_sock_wait_state      vmlinux EXPORT_SYMBOL
+-0x8bd1c81c    fifo_set_limit  vmlinux EXPORT_SYMBOL
+-0xe630ebe9    snd_soc_get_pcm_runtime vmlinux EXPORT_SYMBOL_GPL
+-0x9f7af994    writeback_in_progress   vmlinux EXPORT_SYMBOL
+-0x94048818    filemap_fdatawrite      vmlinux EXPORT_SYMBOL
+-0x9cc4f70a    register_pm_notifier    vmlinux EXPORT_SYMBOL_GPL
+-0xdf6f4023    phy_drivers_unregister  vmlinux EXPORT_SYMBOL
+-0x4cc1d9d6    con_debug_enter vmlinux EXPORT_SYMBOL_GPL
+-0x807d2b2c    xt_recseq       vmlinux EXPORT_SYMBOL_GPL
+-0x089e2060    __ethtool_get_settings  vmlinux EXPORT_SYMBOL
+-0xcdd9e311    dev_add_offload vmlinux EXPORT_SYMBOL
+-0x90ac3102    dev_base_lock   vmlinux EXPORT_SYMBOL
+-0xfcc256a6    css_id  vmlinux EXPORT_SYMBOL_GPL
+-0x2e7be112    _raw_read_lock_irqsave  vmlinux EXPORT_SYMBOL
+-0x284633c4    devm_clk_register       vmlinux EXPORT_SYMBOL_GPL
+-0x440982c5    usb_del_gadget_udc      vmlinux EXPORT_SYMBOL_GPL
+-0x0d7b25d8    drm_i2c_encoder_destroy vmlinux EXPORT_SYMBOL
+-0xd25d4f74    console_blank_hook      vmlinux EXPORT_SYMBOL
+-0x968b41f8    nfc_hci_unregister_device       vmlinux EXPORT_SYMBOL
+-0x71917221    xt_request_find_target  vmlinux EXPORT_SYMBOL_GPL
+-0x14ccc8d6    sg_scsi_ioctl   vmlinux EXPORT_SYMBOL_GPL
+-0xc22a3091    vm_unmap_aliases        vmlinux EXPORT_SYMBOL_GPL
+-0x936d3888    dm_kill_unmapped_request        vmlinux EXPORT_SYMBOL_GPL
+-0x56f3f495    vb2_querybuf    vmlinux EXPORT_SYMBOL
+-0xcd773fe8    gnet_stats_finish_copy  vmlinux EXPORT_SYMBOL
+-0x75ffa405    blk_fetch_request       vmlinux EXPORT_SYMBOL
+-0xc51700fb    free_inode_nonrcu       vmlinux EXPORT_SYMBOL
+-0x87471cdc    dma_pool_create vmlinux EXPORT_SYMBOL
+-0x4b34fbf5    block_all_signals       vmlinux EXPORT_SYMBOL
+-0x1910bed7    v4l2_m2m_next_buf       vmlinux EXPORT_SYMBOL_GPL
+-0xda6389c8    scsi_get_device_flags_keyed     vmlinux EXPORT_SYMBOL
+-0x384fda7f    device_show_int vmlinux EXPORT_SYMBOL_GPL
+-0x853ce11c    uart_handle_cts_change  vmlinux EXPORT_SYMBOL_GPL
+-0x2167989c    uart_handle_dcd_change  vmlinux EXPORT_SYMBOL_GPL
+-0x832c7303    cfg80211_chandef_compatible     vmlinux EXPORT_SYMBOL
+-0xb5aa7165    dma_pool_destroy        vmlinux EXPORT_SYMBOL
+-0x3a81993a    irq_create_strict_mappings      vmlinux EXPORT_SYMBOL_GPL
+-0xf7951d2a    sdio_writeb     vmlinux EXPORT_SYMBOL_GPL
+-0x73286449    gether_set_gadget       vmlinux EXPORT_SYMBOL
+-0x0958f0a1    gether_disconnect       vmlinux EXPORT_SYMBOL
+-0xc7141639    tty_name        vmlinux EXPORT_SYMBOL
+-0x52e54a99    udp6_csum_init  vmlinux EXPORT_SYMBOL
+-0x20c95ebb    __dev_remove_offload    vmlinux EXPORT_SYMBOL
+-0xff6104d0    snd_pcm_rate_bit_to_rate        vmlinux EXPORT_SYMBOL
+-0xcfa8d57b    sysfs_get_dirent        vmlinux EXPORT_SYMBOL_GPL
+-0x8e0d66f4    __tracepoint_kmalloc    vmlinux EXPORT_SYMBOL
+-0x3bfcc1f8    perf_event_release_kernel       vmlinux EXPORT_SYMBOL_GPL
+-0x8c03d20c    destroy_workqueue       vmlinux EXPORT_SYMBOL_GPL
+-0x7e36685b    of_dev_put      vmlinux EXPORT_SYMBOL
+-0x379d3e07    of_dev_get      vmlinux EXPORT_SYMBOL
+-0xf494f618    mmc_regulator_get_ocrmask       vmlinux EXPORT_SYMBOL_GPL
+-0xd9fb5e67    power_supply_register   vmlinux EXPORT_SYMBOL_GPL
+-0x3697b3a2    usb_assign_descriptors  vmlinux EXPORT_SYMBOL_GPL
+-0x6789d290    serial8250_register_8250_port   vmlinux EXPORT_SYMBOL
+-0xa34d0cc4    inet6_csk_reqsk_queue_hash_add  vmlinux EXPORT_SYMBOL_GPL
+-0x81de8eb2    inet_twsk_put   vmlinux EXPORT_SYMBOL_GPL
+-0x687019ad    fib_default_rule_add    vmlinux EXPORT_SYMBOL
+-0x8eef430a    fat_get_dotdot_entry    vmlinux EXPORT_SYMBOL_GPL
+-0x2a3f1eb3    check_disk_change       vmlinux EXPORT_SYMBOL
+-0xd5325933    default_file_splice_read        vmlinux EXPORT_SYMBOL
+-0xd83215e5    writeback_inodes_sb     vmlinux EXPORT_SYMBOL
+-0x506cc085    tracepoint_iter_stop    vmlinux EXPORT_SYMBOL_GPL
+-0xe200d2d5    param_get_uint  vmlinux EXPORT_SYMBOL
+-0x79cb0ce1    pm_generic_runtime_suspend      vmlinux EXPORT_SYMBOL_GPL
+-0x364477d8    do_SAK  vmlinux EXPORT_SYMBOL
+-0x8d9c96ee    elv_register    vmlinux EXPORT_SYMBOL_GPL
+-0x0c77c871    page_put_link   vmlinux EXPORT_SYMBOL
+-0x8f03ba03    release_pages   vmlinux EXPORT_SYMBOL
+-0xa4a39c18    v4l2_m2m_streamon       vmlinux EXPORT_SYMBOL_GPL
+-0xa2d6eedc    bt_sock_stream_recvmsg  vmlinux EXPORT_SYMBOL
+-0xb1bed25d    dpm_resume_start        vmlinux EXPORT_SYMBOL_GPL
+-0x10291853    devm_regulator_put      vmlinux EXPORT_SYMBOL_GPL
+-0xcf618a57    cfg80211_calculate_bitrate      vmlinux EXPORT_SYMBOL
+-0xa9f48f53    km_state_expired        vmlinux EXPORT_SYMBOL
+-0x6417850b    qdisc_list_del  vmlinux EXPORT_SYMBOL
+-0xb0e10781    get_option      vmlinux EXPORT_SYMBOL
+-0x6a3d6744    drm_property_create     vmlinux EXPORT_SYMBOL
+-0x60352082    register_inet6addr_notifier     vmlinux EXPORT_SYMBOL
+-0x7cabb84d    inet_accept     vmlinux EXPORT_SYMBOL
+-0x49b07aec    tcp_select_initial_window       vmlinux EXPORT_SYMBOL
+-0xd41766d2    nf_ct_gre_keymap_destroy        vmlinux EXPORT_SYMBOL_GPL
+-0x0b225b92    register_pernet_device  vmlinux EXPORT_SYMBOL_GPL
+-0xe697d108    __blk_iopoll_complete   vmlinux EXPORT_SYMBOL
+-0xa1c76e0a    _cond_resched   vmlinux EXPORT_SYMBOL
+-0x22e1ae6f    up_read vmlinux EXPORT_SYMBOL
+-0x9fbe4605    class_for_each_device   vmlinux EXPORT_SYMBOL_GPL
+-0x4c1e4dba    unbind_con_driver       vmlinux EXPORT_SYMBOL
+-0x352cbaad    empty_zero_page vmlinux EXPORT_SYMBOL
+-0x66f6b51b    nfnetlink_subsys_register       vmlinux EXPORT_SYMBOL_GPL
+-0x2de03b66    ndo_dflt_bridge_getlink vmlinux EXPORT_SYMBOL
+-0x1f404818    __pskb_pull_tail        vmlinux EXPORT_SYMBOL
+-0x848618a1    snd_pcm_lib_free_vmalloc_buffer vmlinux EXPORT_SYMBOL
+-0x11575bf3    bioset_free     vmlinux EXPORT_SYMBOL
+-0x2acf0feb    vfs_fstat       vmlinux EXPORT_SYMBOL
+-0x0c45fc96    vfs_lstat       vmlinux EXPORT_SYMBOL
+-0x20bc3470    orderly_poweroff        vmlinux EXPORT_SYMBOL_GPL
+-0xd0c74120    cpufreq_frequency_table_verify  vmlinux EXPORT_SYMBOL_GPL
+-0x93af794b    dev_alert       vmlinux EXPORT_SYMBOL
+-0x96cd86f2    tty_wait_until_sent     vmlinux EXPORT_SYMBOL
+-0x4384f1be    gether_setup_name       vmlinux EXPORT_SYMBOL
+-0xa598e29c    vesa_modes      vmlinux EXPORT_SYMBOL
+-0x4ead0283    pn_skb_send     vmlinux EXPORT_SYMBOL
+-0xc01a92eb    __netif_schedule        vmlinux EXPORT_SYMBOL
+-0xd42d86c0    generic_fh_to_parent    vmlinux EXPORT_SYMBOL_GPL
+-0x9eaba82f    generic_fillattr        vmlinux EXPORT_SYMBOL
+-0x183fa88b    mempool_alloc_slab      vmlinux EXPORT_SYMBOL
+-0x5d0b1892    param_set_invbool       vmlinux EXPORT_SYMBOL
+-0xe103ee04    gpio_export_link        vmlinux EXPORT_SYMBOL_GPL
+-0x24bfaf10    d_instantiate_unique    vmlinux EXPORT_SYMBOL
+-0xd6b8e852    request_threaded_irq    vmlinux EXPORT_SYMBOL
+-0x18bd76a4    _raw_spin_trylock       vmlinux EXPORT_SYMBOL
+-0xc2ffd5d5    iio_trigger_alloc       vmlinux EXPORT_SYMBOL
+-0xa749c072    i2c_register_driver     vmlinux EXPORT_SYMBOL
+-0x6ea05e17    of_phy_provider_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0xc359fb65    abort   vmlinux EXPORT_SYMBOL
+-0x9f0f5d05    cfg80211_send_unprot_disassoc   vmlinux EXPORT_SYMBOL
+-0xc575c737    debug_locks_off vmlinux EXPORT_SYMBOL_GPL
+-0xab2f97aa    jbd2_journal_forget     vmlinux EXPORT_SYMBOL
+-0xffea14aa    mutex_lock_interruptible        vmlinux EXPORT_SYMBOL
+-0xdb9cfd07    skb_clone       vmlinux EXPORT_SYMBOL
+-0x0cdd5fd1    crypto_find_alg vmlinux EXPORT_SYMBOL_GPL
+-0x076aff85    set_task_ioprio vmlinux EXPORT_SYMBOL_GPL
+-0x773522a8    setup_arg_pages vmlinux EXPORT_SYMBOL
+-0x430348ff    input_get_keycode       vmlinux EXPORT_SYMBOL
+-0x3c50bfc9    regmap_can_raw_write    vmlinux EXPORT_SYMBOL_GPL
+-0x8209afe6    wakeup_source_destroy   vmlinux EXPORT_SYMBOL_GPL
+-0x0487f831    fb_find_best_display    vmlinux EXPORT_SYMBOL
+-0x83dab696    inode_dio_wait  vmlinux EXPORT_SYMBOL
+-0xa3a19433    of_get_regulator_init_data      vmlinux EXPORT_SYMBOL_GPL
+-0x43ca0eb7    amba_request_regions    vmlinux EXPORT_SYMBOL
+-0xc34efe27    snmp_fold_field vmlinux EXPORT_SYMBOL_GPL
+-0x3e48e980    tcp_init_xmit_timers    vmlinux EXPORT_SYMBOL
+-0x267c8e5b    snd_soc_register_card   vmlinux EXPORT_SYMBOL_GPL
+-0x2d13dc4b    jbd2_journal_start      vmlinux EXPORT_SYMBOL
+-0xd67364f7    eventfd_ctx_fdget       vmlinux EXPORT_SYMBOL_GPL
+-0xaefaecb4    phy_ethtool_gset        vmlinux EXPORT_SYMBOL
+-0x86dded2c    phy_ethtool_sset        vmlinux EXPORT_SYMBOL
+-0x1b15cf75    drm_encoder_init        vmlinux EXPORT_SYMBOL
+-0x540ef2af    vfs_lock_file   vmlinux EXPORT_SYMBOL_GPL
+-0x56fcacd4    bio_uncopy_user vmlinux EXPORT_SYMBOL
+-0x9401ec10    make_bad_inode  vmlinux EXPORT_SYMBOL
+-0x8ec007a4    __d_drop        vmlinux EXPORT_SYMBOL
+-0x7f39e9f3    __mmdrop        vmlinux EXPORT_SYMBOL_GPL
+-0x731e1d9d    thermal_zone_device_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0x31528994    __i2c_transfer  vmlinux EXPORT_SYMBOL
+-0x33dbfd93    tcp_memory_allocated    vmlinux EXPORT_SYMBOL
+-0xa8232c78    strtobool       vmlinux EXPORT_SYMBOL
+-0xbe744811    jbd2_journal_force_commit_nested        vmlinux EXPORT_SYMBOL
+-0xce03751f    seq_release_private     vmlinux EXPORT_SYMBOL
+-0xd788742d    perf_trace_buf_prepare  vmlinux EXPORT_SYMBOL_GPL
+-0x269f017e    st_sensors_set_dataready_irq    vmlinux EXPORT_SYMBOL
+-0x379ea057    hid_check_keys_pressed  vmlinux EXPORT_SYMBOL_GPL
+-0xe19a7489    scsi_bus_type   vmlinux EXPORT_SYMBOL_GPL
+-0x11f13f3f    snd_ctl_remove  vmlinux EXPORT_SYMBOL
+-0xb7a5a52f    writeback_inodes_sb_nr  vmlinux EXPORT_SYMBOL
+-0x8efefdc1    vfs_removexattr vmlinux EXPORT_SYMBOL_GPL
+-0xbd7c9ac7    find_symbol     vmlinux EXPORT_SYMBOL_GPL
+-0xc6ca6078    __mutex_init    vmlinux EXPORT_SYMBOL
+-0xe8349cd8    uart_console_write      vmlinux EXPORT_SYMBOL_GPL
+-0x2e5810c6    __aeabi_unwind_cpp_pr1  vmlinux EXPORT_SYMBOL
+-0x80f711c7    jbd2_journal_check_used_features        vmlinux EXPORT_SYMBOL
+-0xcd91b127    system_highpri_wq       vmlinux EXPORT_SYMBOL_GPL
+-0x5d2137b0    sdio_readsb     vmlinux EXPORT_SYMBOL_GPL
+-0x6883e0d5    rtc_set_time    vmlinux EXPORT_SYMBOL_GPL
+-0xf753d6ff    drm_i2c_encoder_mode_set        vmlinux EXPORT_SYMBOL
+-0x0b0d888b    icmpv6_err_convert      vmlinux EXPORT_SYMBOL
+-0x908cb3fc    vfs_readv       vmlinux EXPORT_SYMBOL
+-0x3e467689    do_sync_write   vmlinux EXPORT_SYMBOL
+-0xe01edb1a    vb2_plane_vaddr vmlinux EXPORT_SYMBOL_GPL
+-0xff9c7899    fb_get_mode     vmlinux EXPORT_SYMBOL
+-0x63923641    crypto_shash_setkey     vmlinux EXPORT_SYMBOL_GPL
+-0x66c159c0    crypto_ahash_setkey     vmlinux EXPORT_SYMBOL_GPL
+-0xb2c17922    search_binary_handler   vmlinux EXPORT_SYMBOL
+-0x07438699    rt_mutex_trylock        vmlinux EXPORT_SYMBOL_GPL
+-0x559b763f    mmc_detect_change       vmlinux EXPORT_SYMBOL
+-0xed2c3cec    drm_debugfs_remove_files        vmlinux EXPORT_SYMBOL
+-0xea5c6ccb    rtnl_link_get_net       vmlinux EXPORT_SYMBOL
+-0x420c7411    ahash_attr_alg  vmlinux EXPORT_SYMBOL_GPL
+-0xc690866c    irq_work_queue  vmlinux EXPORT_SYMBOL_GPL
+-0x22640142    sdio_readw      vmlinux EXPORT_SYMBOL_GPL
+-0x246e1a87    sdio_readl      vmlinux EXPORT_SYMBOL_GPL
+-0xafb35b17    sdio_readb      vmlinux EXPORT_SYMBOL_GPL
+-0x713125bd    cpufreq_freq_attr_scaling_available_freqs       vmlinux EXPORT_SYMBOL_GPL
+-0xd7095481    usb_remove_phy  vmlinux EXPORT_SYMBOL_GPL
+-0x76d878f8    usb_remove_hcd  vmlinux EXPORT_SYMBOL_GPL
+-0x7e543e70    device_store_bool       vmlinux EXPORT_SYMBOL_GPL
+-0x407136b1    __put_user_8    vmlinux EXPORT_SYMBOL
+-0x1567020f    tcp_disconnect  vmlinux EXPORT_SYMBOL
+-0x1f615e38    bio_pair_release        vmlinux EXPORT_SYMBOL
+-0x2469810f    __rcu_read_unlock       vmlinux EXPORT_SYMBOL_GPL
+-0xea51d53a    extcon_get_extcon_dev   vmlinux EXPORT_SYMBOL_GPL
+-0x52c47236    put_device      vmlinux EXPORT_SYMBOL_GPL
+-0x194eadaa    drm_edid_header_is_valid        vmlinux EXPORT_SYMBOL
+-0x7d89e34a    drm_gtf_mode_complex    vmlinux EXPORT_SYMBOL
+-0x75c2b9f1    memalloc_socks  vmlinux EXPORT_SYMBOL_GPL
+-0xb10dfa5a    register_filesystem     vmlinux EXPORT_SYMBOL
+-0x758a782e    blk_fill_rwbs   vmlinux EXPORT_SYMBOL_GPL
+-0xba497f13    loops_per_jiffy vmlinux EXPORT_SYMBOL
+-0xc657abdc    v4l2_ctrl_subscribe_event       vmlinux EXPORT_SYMBOL
+-0xc7472c0b    devm_input_allocate_device      vmlinux EXPORT_SYMBOL
+-0xdb2c2fbf    spi_alloc_device        vmlinux EXPORT_SYMBOL_GPL
+-0xa33be4ce    inet_confirm_addr       vmlinux EXPORT_SYMBOL
+-0x48eb98d1    eth_validate_addr       vmlinux EXPORT_SYMBOL
+-0xc5718627    sg_copy_to_buffer       vmlinux EXPORT_SYMBOL
+-0x7ab88a45    system_freezing_cnt     vmlinux EXPORT_SYMBOL
+-0x7d0db45c    jiffies_to_clock_t      vmlinux EXPORT_SYMBOL
+-0x2c208607    power_supply_is_system_supplied vmlinux EXPORT_SYMBOL_GPL
+-0xc9422c05    devm_usb_get_phy_dev    vmlinux EXPORT_SYMBOL_GPL
+-0xba3a6941    drm_getsarea    vmlinux EXPORT_SYMBOL
+-0x1ffe8e3f    nfc_register_device     vmlinux EXPORT_SYMBOL
+-0x0478373c    generic_make_request    vmlinux EXPORT_SYMBOL
+-0x0b9a91be    generic_file_llseek_size        vmlinux EXPORT_SYMBOL
+-0x1c87a811    __round_jiffies_up      vmlinux EXPORT_SYMBOL_GPL
+-0x93d6ad2c    usb_debug_root  vmlinux EXPORT_SYMBOL_GPL
+-0xd3ce47fe    drm_mode_crtc_set_gamma_size    vmlinux EXPORT_SYMBOL
+-0xbe16ad70    drm_addbufs_pci vmlinux EXPORT_SYMBOL
+-0xd5dae19f    regulator_get_exclusive vmlinux EXPORT_SYMBOL_GPL
+-0x02124474    ip_send_check   vmlinux EXPORT_SYMBOL
+-0x628cbfaa    rtmsg_ifinfo    vmlinux EXPORT_SYMBOL
+-0xb0d3bca5    __rtnl_register vmlinux EXPORT_SYMBOL_GPL
+-0x23b9d6e2    mangle_path     vmlinux EXPORT_SYMBOL
+-0xe7c52663    v4l2_m2m_create_bufs    vmlinux EXPORT_SYMBOL_GPL
+-0x63625aaa    usb_composite_setup_continue    vmlinux EXPORT_SYMBOL_GPL
+-0x41f53df0    anon_inode_getfd        vmlinux EXPORT_SYMBOL_GPL
+-0x24d5ba21    filemap_flush   vmlinux EXPORT_SYMBOL
+-0xb49f6bea    iio_enum_write  vmlinux EXPORT_SYMBOL_GPL
+-0x1bfbfeeb    mc1n2_set_mclk_source   vmlinux EXPORT_SYMBOL
+-0x95e6e500    blk_stack_limits        vmlinux EXPORT_SYMBOL
+-0xeb46c362    fuse_conn_init  vmlinux EXPORT_SYMBOL_GPL
+-0x0e9003db    pm_generic_freeze_late  vmlinux EXPORT_SYMBOL_GPL
+-0xf2fa6c7e    drm_gem_vm_close        vmlinux EXPORT_SYMBOL
+-0x5bbc0a12    __fib_lookup    vmlinux EXPORT_SYMBOL_GPL
+-0x1dd6e42b    tcp_set_state   vmlinux EXPORT_SYMBOL_GPL
+-0xa77d88f6    strnlen_user    vmlinux EXPORT_SYMBOL
+-0x191ef206    i2c_smbus_read_i2c_block_data   vmlinux EXPORT_SYMBOL
+-0x52b992dc    drm_kms_helper_poll_disable     vmlinux EXPORT_SYMBOL
+-0x6fc997a4    tty_mutex       vmlinux EXPORT_SYMBOL
+-0x3973c5f8    kunmap  vmlinux EXPORT_SYMBOL
+-0xb28f5ef1    xt_free_table_info      vmlinux EXPORT_SYMBOL
+-0x1d0b568b    mnt_pin vmlinux EXPORT_SYMBOL
+-0x50ba53b9    set_create_files_as     vmlinux EXPORT_SYMBOL
+-0xcbd3dbd0    serial8250_modem_status vmlinux EXPORT_SYMBOL_GPL
+-0xe38dd51c    dev_get_by_name vmlinux EXPORT_SYMBOL
+-0x69458fd5    snd_dma_alloc_pages_fallback    vmlinux EXPORT_SYMBOL
+-0xb3fda4b7    __page_symlink  vmlinux EXPORT_SYMBOL
+-0x400fb79c    install_exec_creds      vmlinux EXPORT_SYMBOL
+-0xbed3ae54    sched_setscheduler      vmlinux EXPORT_SYMBOL_GPL
+-0xeb923e09    power_supply_set_battery_charged        vmlinux EXPORT_SYMBOL_GPL
+-0xfdab6de3    unregister_sound_midi   vmlinux EXPORT_SYMBOL
+-0x30a80826    __kfifo_from_user       vmlinux EXPORT_SYMBOL
+-0x6923ce63    irq_work_sync   vmlinux EXPORT_SYMBOL_GPL
+-0xe7197773    drm_ht_insert_item      vmlinux EXPORT_SYMBOL
+-0xdf75f3c9    ipcomp_input    vmlinux EXPORT_SYMBOL_GPL
+-0xac966a6d    udp_prot        vmlinux EXPORT_SYMBOL
+-0xc6531cd4    inet_putpeer    vmlinux EXPORT_SYMBOL_GPL
+-0xe2b955e2    nat_h245_hook   vmlinux EXPORT_SYMBOL_GPL
+-0xf34732f2    netif_set_xps_queue     vmlinux EXPORT_SYMBOL
+-0x7681d145    snd_ctl_register_ioctl  vmlinux EXPORT_SYMBOL
+-0xaae48971    mmc_card_sleep  vmlinux EXPORT_SYMBOL
+-0x58fe6474    v4l2_m2m_ioctl_qbuf     vmlinux EXPORT_SYMBOL_GPL
+-0x00d1d0d0    i2c_adapter_type        vmlinux EXPORT_SYMBOL_GPL
+-0xb971ebca    rndis_get_next_response vmlinux EXPORT_SYMBOL
+-0xc88b565d    inet6_sk_rebuild_header vmlinux EXPORT_SYMBOL_GPL
+-0x83a4c277    mb_cache_shrink vmlinux EXPORT_SYMBOL
+-0xf1e98c74    avenrun vmlinux EXPORT_SYMBOL
+-0x1318fa1c    __ww_mutex_lock_interruptible   vmlinux EXPORT_SYMBOL
+-0x2d3385d3    system_wq       vmlinux EXPORT_SYMBOL
+-0x94e4e64e    v4l2_event_queue        vmlinux EXPORT_SYMBOL_GPL
+-0x76fd0937    device_init_wakeup      vmlinux EXPORT_SYMBOL_GPL
+-0x40a6f522    __arm_ioremap   vmlinux EXPORT_SYMBOL
+-0xc2165d85    __arm_iounmap   vmlinux EXPORT_SYMBOL
+-0xaf50e76d    elf_set_personality     vmlinux EXPORT_SYMBOL
+-0xd9f8f32d    nf_ct_extend_register   vmlinux EXPORT_SYMBOL_GPL
+-0x6ceb8cf4    mark_page_accessed      vmlinux EXPORT_SYMBOL
+-0x17f36c02    mmc_calc_max_discard    vmlinux EXPORT_SYMBOL
+-0x0d45c48f    v4l2_clk_register       vmlinux EXPORT_SYMBOL
+-0x123959a1    v4l2_type_names vmlinux EXPORT_SYMBOL
+-0x02a18c74    nf_conntrack_destroy    vmlinux EXPORT_SYMBOL
+-0x679f4b6b    scsi_report_bus_reset   vmlinux EXPORT_SYMBOL
+-0xf8224b12    mali_get_user_setting   vmlinux EXPORT_SYMBOL
+-0x3c93ad98    tty_port_install        vmlinux EXPORT_SYMBOL_GPL
+-0x63fb81e4    brcmu_pktq_penq drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x723a1683    brcmu_pktq_pdeq drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0xfa595453    ip6_sk_dst_lookup_flow  vmlinux EXPORT_SYMBOL_GPL
+-0xa76f7e50    snd_dma_get_reserved_buf        vmlinux EXPORT_SYMBOL
+-0x61ed1c8e    cdev_add        vmlinux EXPORT_SYMBOL
+-0x69447467    ring_buffer_write       vmlinux EXPORT_SYMBOL_GPL
+-0xfcd7bc0b    ring_buffer_empty       vmlinux EXPORT_SYMBOL_GPL
+-0x82939ebd    rcu_batches_completed_sched     vmlinux EXPORT_SYMBOL_GPL
+-0x9e44b9b7    of_get_next_available_child     vmlinux EXPORT_SYMBOL
+-0x1010f1ee    hid_output_report       vmlinux EXPORT_SYMBOL_GPL
+-0x59e5070d    __do_div64      vmlinux EXPORT_SYMBOL
+-0xa2d91fcc    xfrm_input      vmlinux EXPORT_SYMBOL
+-0x07a62853    dev_mc_add      vmlinux EXPORT_SYMBOL
+-0x40908b29    dev_mc_del      vmlinux EXPORT_SYMBOL
+-0x2eed048e    dev_uc_add      vmlinux EXPORT_SYMBOL
+-0x69dba7f4    dev_uc_del      vmlinux EXPORT_SYMBOL
+-0x15361516    register_pernet_subsys  vmlinux EXPORT_SYMBOL_GPL
+-0x915be34a    snd_timer_new   vmlinux EXPORT_SYMBOL
+-0x3c45a56f    blk_queue_update_dma_pad        vmlinux EXPORT_SYMBOL
+-0x069d40a0    blkdev_get_by_path      vmlinux EXPORT_SYMBOL
+-0xa440bdfe    open_exec       vmlinux EXPORT_SYMBOL
+-0x374682ce    rtc_update_irq  vmlinux EXPORT_SYMBOL_GPL
+-0xba2d0719    drm_mode_hsync  vmlinux EXPORT_SYMBOL
+-0x2d7a787f    drm_dp_clock_recovery_ok        vmlinux EXPORT_SYMBOL
+-0xd59b2bb0    fb_blank        vmlinux EXPORT_SYMBOL
+-0x0b48677a    __kfifo_init    vmlinux EXPORT_SYMBOL
+-0x249c96e2    mb_cache_entry_find_next        vmlinux EXPORT_SYMBOL
+-0xaee2539e    inode_init_owner        vmlinux EXPORT_SYMBOL
+-0x7b24ccb3    file_ns_capable vmlinux EXPORT_SYMBOL
+-0x37c0412f    cpu_subsys      vmlinux EXPORT_SYMBOL_GPL
+-0x9993bf08    rt_mutex_destroy        vmlinux EXPORT_SYMBOL_GPL
+-0xd4034828    system_freezable_wq     vmlinux EXPORT_SYMBOL_GPL
+-0x9963a089    queue_delayed_work_on   vmlinux EXPORT_SYMBOL
+-0x1284891b    iio_trigger_notify_done vmlinux EXPORT_SYMBOL
+-0x03212586    v4l2_m2m_streamoff      vmlinux EXPORT_SYMBOL_GPL
+-0x5b19634d    div_s64_rem     vmlinux EXPORT_SYMBOL
+-0xb110bb66    __set_page_dirty_nobuffers      vmlinux EXPORT_SYMBOL
+-0xd7d79132    put_online_cpus vmlinux EXPORT_SYMBOL_GPL
+-0x121e3c12    devres_open_group       vmlinux EXPORT_SYMBOL_GPL
+-0x8eae4744    __nf_ct_kill_acct       vmlinux EXPORT_SYMBOL_GPL
+-0xcf88625f    mempool_create_node     vmlinux EXPORT_SYMBOL
+-0x222fa684    lg_global_lock  vmlinux EXPORT_SYMBOL
+-0x7cb2eca1    find_get_pid    vmlinux EXPORT_SYMBOL_GPL
+-0x971ad8d8    usbnet_unlink_rx_urbs   vmlinux EXPORT_SYMBOL_GPL
+-0xa551b417    devm_pwm_get    vmlinux EXPORT_SYMBOL_GPL
+-0xb138607d    dev_set_promiscuity     vmlinux EXPORT_SYMBOL
+-0xc8ca31af    timed_output_dev_register       vmlinux EXPORT_SYMBOL_GPL
+-0x2967cbf7    dm_get_rq_mapinfo       vmlinux EXPORT_SYMBOL_GPL
+-0x07013243    scsi_bios_ptable        vmlinux EXPORT_SYMBOL
+-0x9780e683    pm_generic_resume       vmlinux EXPORT_SYMBOL_GPL
+-0x3074f033    drm_order       vmlinux EXPORT_SYMBOL
+-0xa87f4ece    neigh_connected_output  vmlinux EXPORT_SYMBOL
+-0xe9f7149c    zlib_deflate_workspacesize      vmlinux EXPORT_SYMBOL
+-0x2d03c10d    posix_acl_create        vmlinux EXPORT_SYMBOL
+-0xbe254e92    param_set_ushort        vmlinux EXPORT_SYMBOL
+-0xf0ca36cf    drm_prime_init_file_private     vmlinux EXPORT_SYMBOL
+-0xb001e18c    drm_plane_init  vmlinux EXPORT_SYMBOL
+-0xb2922319    bt_sock_recvmsg vmlinux EXPORT_SYMBOL
+-0xe7f38f6d    udp_flush_pending_frames        vmlinux EXPORT_SYMBOL
+-0xf0726368    dev_get_stats   vmlinux EXPORT_SYMBOL
+-0xd3f7e5cc    snd_soc_default_volatile_register       vmlinux EXPORT_SYMBOL_GPL
+-0x92c5fcb5    snd_timer_notify        vmlinux EXPORT_SYMBOL
+-0x86fb9b05    bitmap_parse_user       vmlinux EXPORT_SYMBOL
+-0x01000e51    schedule        vmlinux EXPORT_SYMBOL
+-0xbd597aa3    usb_add_function        vmlinux EXPORT_SYMBOL_GPL
+-0x460e4737    pm_generic_poweroff     vmlinux EXPORT_SYMBOL_GPL
+-0x6920e885    nlmsg_notify    vmlinux EXPORT_SYMBOL
+-0x247a1d7a    ww_mutex_unlock vmlinux EXPORT_SYMBOL
+-0x1498f6af    mmput   vmlinux EXPORT_SYMBOL_GPL
+-0x709eb78b    init_task       vmlinux EXPORT_SYMBOL
+-0x3052a0ee    watchdog_unregister_device      vmlinux EXPORT_SYMBOL_GPL
+-0x80eaa56e    drm_i2c_encoder_save    vmlinux EXPORT_SYMBOL
+-0xe540813f    drm_property_create_enum        vmlinux EXPORT_SYMBOL
+-0x6c642207    drm_get_connector_name  vmlinux EXPORT_SYMBOL
+-0x42151efa    balloon_devinfo_alloc   vmlinux EXPORT_SYMBOL_GPL
+-0xfa544711    video_devdata   vmlinux EXPORT_SYMBOL
+-0x8e9618cd    wakeup_source_create    vmlinux EXPORT_SYMBOL_GPL
+-0x72f12e79    drm_probe_ddc   vmlinux EXPORT_SYMBOL
+-0x89d66811    build_ehash_secret      vmlinux EXPORT_SYMBOL
+-0xf4329926    __inet_twsk_hashdance   vmlinux EXPORT_SYMBOL_GPL
+-0xd0e13603    gnet_stats_copy_app     vmlinux EXPORT_SYMBOL
+-0x1b015d25    bitmap_parselist        vmlinux EXPORT_SYMBOL
+-0xf91bf3db    __insert_inode_hash     vmlinux EXPORT_SYMBOL
+-0x308b733a    getboottime     vmlinux EXPORT_SYMBOL_GPL
+-0x69f04aa3    revert_creds    vmlinux EXPORT_SYMBOL
+-0xdf929370    fs_overflowgid  vmlinux EXPORT_SYMBOL
+-0xa1177bf1    i2c_verify_client       vmlinux EXPORT_SYMBOL
+-0x0e5358d0    input_allocate_device   vmlinux EXPORT_SYMBOL
+-0x4fed4ee0    pm_runtime_barrier      vmlinux EXPORT_SYMBOL_GPL
+-0xb939d297    dev_printk      vmlinux EXPORT_SYMBOL
+-0x090849e3    phy_power_on    vmlinux EXPORT_SYMBOL_GPL
+-0x47416e14    cpu_rmap_add    vmlinux EXPORT_SYMBOL
+-0x08fbaf94    xfrm_policy_walk        vmlinux EXPORT_SYMBOL
+-0x774846b4    nf_log_unset    vmlinux EXPORT_SYMBOL
+-0x00aaf0d4    wm_hubs_add_analogue_routes     vmlinux EXPORT_SYMBOL_GPL
+-0xe9d7e477    snd_card_proc_new       vmlinux EXPORT_SYMBOL
+-0x97de2b83    debug_locks_silent      vmlinux EXPORT_SYMBOL_GPL
+-0x3e452a00    blocking_notifier_call_chain    vmlinux EXPORT_SYMBOL_GPL
+-0xae83dc8c    spi_bitbang_setup_transfer      vmlinux EXPORT_SYMBOL_GPL
+-0x8d871961    cpu_tlb vmlinux EXPORT_SYMBOL
+-0xfe694f5b    regmap_read     vmlinux EXPORT_SYMBOL_GPL
+-0x594bf15b    ioport_map      vmlinux EXPORT_SYMBOL
+-0x2d3abae7    __skb_checksum_complete vmlinux EXPORT_SYMBOL
+-0xb5a459dc    unregister_blkdev       vmlinux EXPORT_SYMBOL
+-0xd0a8eac3    write_inode_now vmlinux EXPORT_SYMBOL
+-0x7d3a11d4    tty_lock        vmlinux EXPORT_SYMBOL
+-0xa6dea12e    regulator_register      vmlinux EXPORT_SYMBOL_GPL
+-0x0ce021b8    ieee80211_amsdu_to_8023s        vmlinux EXPORT_SYMBOL
+-0xe0088286    fat_search_long vmlinux EXPORT_SYMBOL_GPL
+-0x08ca5b31    seq_path        vmlinux EXPORT_SYMBOL
+-0xcc5005fe    msleep_interruptible    vmlinux EXPORT_SYMBOL
+-0x2f0d9053    usb_otg_state_string    vmlinux EXPORT_SYMBOL_GPL
+-0xf2997713    tty_termios_hw_change   vmlinux EXPORT_SYMBOL
+-0x53893194    dev_addr_add    vmlinux EXPORT_SYMBOL
+-0x0dd3fd84    netdev_err      vmlinux EXPORT_SYMBOL
+-0x62849ac7    dev_valid_name  vmlinux EXPORT_SYMBOL
+-0x193466be    kfree_skb_partial       vmlinux EXPORT_SYMBOL
+-0xd2a941d4    sg_init_table   vmlinux EXPORT_SYMBOL
+-0x5642793a    radix_tree_tag_clear    vmlinux EXPORT_SYMBOL
+-0xc3bb6d9e    blk_pre_runtime_resume  vmlinux EXPORT_SYMBOL
+-0xd3a7747d    fsnotify        vmlinux EXPORT_SYMBOL_GPL
+-0x4f3b569c    generic_file_open       vmlinux EXPORT_SYMBOL
+-0xc87c1f84    ktime_get       vmlinux EXPORT_SYMBOL_GPL
+-0x89bbafc6    usb_register_notify     vmlinux EXPORT_SYMBOL_GPL
+-0x19ac480a    cfg80211_new_sta        vmlinux EXPORT_SYMBOL
+-0xd18ba458    generic_cont_expand_simple      vmlinux EXPORT_SYMBOL
+-0x5cf6467f    d_instantiate   vmlinux EXPORT_SYMBOL
+-0xd1ef6f16    genphy_update_link      vmlinux EXPORT_SYMBOL
+-0x4a77677a    nfc_hci_recv_frame      vmlinux EXPORT_SYMBOL
+-0xc2a19d85    register_sound_special_device   vmlinux EXPORT_SYMBOL
+-0x5b3060c4    blk_queue_rq_timed_out  vmlinux EXPORT_SYMBOL_GPL
+-0x2cbfd99b    vb2_queue_init  vmlinux EXPORT_SYMBOL_GPL
+-0x955d725c    drm_mm_scan_remove_block        vmlinux EXPORT_SYMBOL
+-0x6d346792    pin_config_group_get    vmlinux EXPORT_SYMBOL
+-0xf82a1863    pin_config_group_set    vmlinux EXPORT_SYMBOL
+-0x08c473b7    xt_alloc_table_info     vmlinux EXPORT_SYMBOL
+-0xb7b61546    crc32_be        vmlinux EXPORT_SYMBOL
+-0x26520970    vm_memory_committed     vmlinux EXPORT_SYMBOL_GPL
+-0xcf283b4f    iommu_domain_alloc      vmlinux EXPORT_SYMBOL_GPL
+-0x52ffd07f    xfrm_output_resume      vmlinux EXPORT_SYMBOL_GPL
+-0x4c21e163    skb_find_text   vmlinux EXPORT_SYMBOL
+-0x5279b639    current_fs_time vmlinux EXPORT_SYMBOL
+-0x04cc0a21    i2c_unregister_device   vmlinux EXPORT_SYMBOL_GPL
+-0x13fc56de    drm_helper_crtc_in_use  vmlinux EXPORT_SYMBOL
+-0x6d399587    regulator_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0x6b037ba6    nf_nat_l4proto_unregister       vmlinux EXPORT_SYMBOL_GPL
+-0x8231a8bd    nf_nat_l3proto_unregister       vmlinux EXPORT_SYMBOL_GPL
+-0x6350314b    tcf_hash_create vmlinux EXPORT_SYMBOL
+-0xf339287c    skb_queue_tail  vmlinux EXPORT_SYMBOL
+-0x5409775b    free_irq_cpu_rmap       vmlinux EXPORT_SYMBOL
+-0x65771426    crypto_lookup_template  vmlinux EXPORT_SYMBOL_GPL
+-0xd61347c6    register_sysctl vmlinux EXPORT_SYMBOL
+-0xd8c37e37    vfs_test_lock   vmlinux EXPORT_SYMBOL_GPL
+-0x952664c5    do_exit vmlinux EXPORT_SYMBOL_GPL
+-0xcb07e4af    tcf_hash_destroy        vmlinux EXPORT_SYMBOL
+-0x78953de6    mark_buffer_dirty_inode vmlinux EXPORT_SYMBOL
+-0x3109b751    cpu_clock       vmlinux EXPORT_SYMBOL_GPL
+-0xdf842e2b    drm_vblank_cleanup      vmlinux EXPORT_SYMBOL
+-0x57810201    ip_tunnel_lookup        vmlinux EXPORT_SYMBOL_GPL
+-0xb1c3a01a    oops_in_progress        vmlinux EXPORT_SYMBOL
+-0x0fca29c0    dev_pm_qos_remove_request       vmlinux EXPORT_SYMBOL_GPL
+-0xc407a137    dma_wait_for_async_tx   vmlinux EXPORT_SYMBOL_GPL
+-0x046a9d1b    backlight_device_register       vmlinux EXPORT_SYMBOL
+-0x2a36b31a    nf_ct_helper_log        vmlinux EXPORT_SYMBOL_GPL
+-0xb442919d    blk_get_backing_dev_info        vmlinux EXPORT_SYMBOL
+-0x0ed2f3b5    elevator_init   vmlinux EXPORT_SYMBOL
+-0x21bda10a    kill_fasync     vmlinux EXPORT_SYMBOL
+-0x622dacba    tick_nohz_idle_enter    vmlinux EXPORT_SYMBOL_GPL
+-0xdd4a5569    param_get_byte  vmlinux EXPORT_SYMBOL
+-0x764d38f1    tty_insert_flip_string_fixed_flag       vmlinux EXPORT_SYMBOL
+-0xcf5bc354    tty_register_ldisc      vmlinux EXPORT_SYMBOL
+-0x88f68355    tty_throttle    vmlinux EXPORT_SYMBOL
+-0x335e720e    tty_check_change        vmlinux EXPORT_SYMBOL
+-0x1d5568cb    dev_disable_lro vmlinux EXPORT_SYMBOL
+-0xb2be6e92    netdev_stats_to_stats64 vmlinux EXPORT_SYMBOL
+-0x728261ca    kblockd_schedule_delayed_work   vmlinux EXPORT_SYMBOL
+-0x5c959646    debugfs_create_u8       vmlinux EXPORT_SYMBOL_GPL
+-0x0c150d31    cgroup_taskset_first    vmlinux EXPORT_SYMBOL_GPL
+-0xec690544    attribute_container_classdev_to_container       vmlinux EXPORT_SYMBOL_GPL
+-0xda1613df    drm_put_dev     vmlinux EXPORT_SYMBOL
+-0x157667da    drm_gem_vm_open vmlinux EXPORT_SYMBOL
+-0x8ad8d79e    drm_fb_helper_setcmap   vmlinux EXPORT_SYMBOL
+-0x5550f136    snd_soc_dapm_info_pin_switch    vmlinux EXPORT_SYMBOL_GPL
+-0xcb08eeba    drm_core_ioremap        vmlinux EXPORT_SYMBOL
+-0x6aba167a    regulator_list_voltage  vmlinux EXPORT_SYMBOL_GPL
+-0x1b0ac272    __tracepoint_kmalloc_node       vmlinux EXPORT_SYMBOL
+-0xd62c833f    schedule_timeout        vmlinux EXPORT_SYMBOL
+-0x432fd7f6    __gpio_set_value        vmlinux EXPORT_SYMBOL_GPL
+-0x6c8d5ae8    __gpio_get_value        vmlinux EXPORT_SYMBOL_GPL
+-0x65ccb6f0    call_netevent_notifiers vmlinux EXPORT_SYMBOL_GPL
+-0x4a7fb243    percpu_counter_compare  vmlinux EXPORT_SYMBOL
+-0xced58760    crypto_alloc_base       vmlinux EXPORT_SYMBOL_GPL
+-0xfcf2f8c0    aio_put_req     vmlinux EXPORT_SYMBOL
+-0x6f3a36eb    dw_mci_pltfm_pmops      vmlinux EXPORT_SYMBOL_GPL
+-0xe6c3ebb0    __raw_writesw   vmlinux EXPORT_SYMBOL
+-0x51908eb8    __raw_writesl   vmlinux EXPORT_SYMBOL
+-0x75fee7fd    __raw_writesb   vmlinux EXPORT_SYMBOL
+-0xef35b0c3    cfg80211_report_wowlan_wakeup   vmlinux EXPORT_SYMBOL
+-0x99591a7a    ipv6_ext_hdr    vmlinux EXPORT_SYMBOL
+-0x65396d44    neigh_destroy   vmlinux EXPORT_SYMBOL
+-0x405b485b    netdev_warn     vmlinux EXPORT_SYMBOL
+-0xf45f8934    blk_end_request_cur     vmlinux EXPORT_SYMBOL
+-0x9a682368    replace_mount_options   vmlinux EXPORT_SYMBOL
+-0x5a7c0586    hid_validate_values     vmlinux EXPORT_SYMBOL_GPL
+-0x88618588    mmc_wait_for_app_cmd    vmlinux EXPORT_SYMBOL
+-0xccbbfe3b    v4l2_fh_del     vmlinux EXPORT_SYMBOL_GPL
+-0xcefcd99a    serial8250_unregister_port      vmlinux EXPORT_SYMBOL
+-0x0bed6399    __xfrm_policy_check     vmlinux EXPORT_SYMBOL
+-0xf1947b5c    snd_ctl_rename_id       vmlinux EXPORT_SYMBOL
+-0xb9220639    blk_lld_busy    vmlinux EXPORT_SYMBOL_GPL
+-0x4178eee3    blk_sync_queue  vmlinux EXPORT_SYMBOL
+-0x32b0e045    usbnet_get_link vmlinux EXPORT_SYMBOL_GPL
+-0xd578f42c    fat_alloc_new_dir       vmlinux EXPORT_SYMBOL_GPL
+-0x0eacb23a    simple_write_end        vmlinux EXPORT_SYMBOL
+-0xcbee20b2    get_cpu_iowait_time_us  vmlinux EXPORT_SYMBOL_GPL
+-0xea01bd2a    st_sensors_init_sensor  vmlinux EXPORT_SYMBOL
+-0xb7433944    hid_open_report vmlinux EXPORT_SYMBOL_GPL
+-0x2d339a62    scsi_schedule_eh        vmlinux EXPORT_SYMBOL_GPL
+-0xc6544448    pm_runtime_irq_safe     vmlinux EXPORT_SYMBOL_GPL
+-0xa5afacf6    class_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0xedf69cd6    drm_gem_private_object_init     vmlinux EXPORT_SYMBOL
+-0x999c3148    __raw_readsb    vmlinux EXPORT_SYMBOL
+-0xfb268a5f    ip_mc_rejoin_groups     vmlinux EXPORT_SYMBOL
+-0xafe4c25e    netdev_update_features  vmlinux EXPORT_SYMBOL
+-0xd75c79df    smp_call_function       vmlinux EXPORT_SYMBOL
+-0xef6c3f70    round_jiffies_up_relative       vmlinux EXPORT_SYMBOL_GPL
+-0x64420947    spi_async       vmlinux EXPORT_SYMBOL_GPL
+-0xe62c2cf6    regmap_raw_write_async  vmlinux EXPORT_SYMBOL_GPL
+-0x226a057d    eth_header_cache        vmlinux EXPORT_SYMBOL
+-0xb9d025c9    llist_del_first vmlinux EXPORT_SYMBOL_GPL
+-0xb678366f    int_sqrt        vmlinux EXPORT_SYMBOL
+-0x9d28f747    dec_zone_page_state     vmlinux EXPORT_SYMBOL
+-0x0799aca4    local_bh_enable vmlinux EXPORT_SYMBOL
+-0x8d07023c    i2c_smbus_read_byte_data        vmlinux EXPORT_SYMBOL
+-0xca5dbc50    scsi_print_sense_hdr    vmlinux EXPORT_SYMBOL
+-0x3da076a8    scsi_host_lookup        vmlinux EXPORT_SYMBOL
+-0xf54ff64f    uart_set_options        vmlinux EXPORT_SYMBOL_GPL
+-0x47ff399f    regulator_is_supported_voltage  vmlinux EXPORT_SYMBOL_GPL
+-0x585469ee    of_get_videomode        vmlinux EXPORT_SYMBOL_GPL
+-0x852786a9    phy_get vmlinux EXPORT_SYMBOL_GPL
+-0xaf8aa518    system_rev      vmlinux EXPORT_SYMBOL
+-0x6c3d2a02    tcp_syn_flood_action    vmlinux EXPORT_SYMBOL
+-0xf38bcdf3    nf_conntrack_max        vmlinux EXPORT_SYMBOL_GPL
+-0x44de5177    snd_pcm_suspend vmlinux EXPORT_SYMBOL
+-0xb23ef570    blk_bio_map_sg  vmlinux EXPORT_SYMBOL
+-0x4c5e7289    config_item_get vmlinux EXPORT_SYMBOL
+-0xea12473b    config_item_put vmlinux EXPORT_SYMBOL
+-0xbe68ef11    mnt_drop_write_file     vmlinux EXPORT_SYMBOL
+-0x381144a9    __tracepoint_module_get vmlinux EXPORT_SYMBOL
+-0xc5fdef94    call_usermodehelper     vmlinux EXPORT_SYMBOL
+-0x1eb9516e    round_jiffies_relative  vmlinux EXPORT_SYMBOL_GPL
+-0x7cc035a7    __ucmpdi2       vmlinux EXPORT_SYMBOL
+-0xe42e1f70    klist_iter_init_node    vmlinux EXPORT_SYMBOL_GPL
+-0x5c440c21    hci_conn_check_secure   vmlinux EXPORT_SYMBOL
+-0x5b34d4b0    snd_soc_codec_readable_register vmlinux EXPORT_SYMBOL_GPL
+-0x0634100a    bitmap_parselist_user   vmlinux EXPORT_SYMBOL
+-0x5b72009f    ida_simple_get  vmlinux EXPORT_SYMBOL
+-0x11a6ce4b    blk_queue_update_dma_alignment  vmlinux EXPORT_SYMBOL
+-0x3e0dd939    blk_start_request       vmlinux EXPORT_SYMBOL
+-0x51749fc8    _raw_read_lock_irq      vmlinux EXPORT_SYMBOL
+-0x757bbc48    hrtimer_try_to_cancel   vmlinux EXPORT_SYMBOL_GPL
+-0x70899e95    v4l2_m2m_buf_remove     vmlinux EXPORT_SYMBOL_GPL
+-0x5f96a661    v4l2_ctrl_check vmlinux EXPORT_SYMBOL
+-0x42bf1c34    video_unregister_device vmlinux EXPORT_SYMBOL
+-0xcd914413    drm_get_minor   vmlinux EXPORT_SYMBOL
+-0xa0e5202d    nf_register_hook        vmlinux EXPORT_SYMBOL
+-0x86d5e343    __dev_get_by_name       vmlinux EXPORT_SYMBOL
+-0x2cc749f6    skb_copy_and_csum_dev   vmlinux EXPORT_SYMBOL
+-0x9613509a    idr_replace     vmlinux EXPORT_SYMBOL
+-0x82acfb70    blk_iopoll_sched        vmlinux EXPORT_SYMBOL
+-0x2c7db649    irq_dispose_mapping     vmlinux EXPORT_SYMBOL_GPL
+-0x530b1e98    pm_suspend      vmlinux EXPORT_SYMBOL
+-0xae69b1c1    usermodehelper_read_unlock      vmlinux EXPORT_SYMBOL_GPL
+-0x39f4b0d2    s3c_adc_release vmlinux EXPORT_SYMBOL_GPL
+-0xc2f16e25    input_unregister_handle vmlinux EXPORT_SYMBOL
+-0x67326732    usb_hcd_map_urb_for_dma vmlinux EXPORT_SYMBOL_GPL
+-0xd125790d    drm_hdmi_avi_infoframe_from_display_mode        vmlinux EXPORT_SYMBOL
+-0xe10a472d    drm_mm_pre_get  vmlinux EXPORT_SYMBOL
+-0xf082ddf3    register_netdev vmlinux EXPORT_SYMBOL
+-0x935b5da0    snd_timer_continue      vmlinux EXPORT_SYMBOL
+-0xcc37f55c    blk_limits_io_opt       vmlinux EXPORT_SYMBOL
+-0xd4c5def3    inet_twsk_purge vmlinux EXPORT_SYMBOL_GPL
+-0x9e9f1714    __bitmap_andnot vmlinux EXPORT_SYMBOL
+-0x737de5e9    radix_tree_tag_get      vmlinux EXPORT_SYMBOL
+-0xed1e0a03    posix_acl_from_xattr    vmlinux EXPORT_SYMBOL
+-0x5256cd6e    clear_nlink     vmlinux EXPORT_SYMBOL
+-0xc9f0ae5d    nf_xfrm_me_harder       vmlinux EXPORT_SYMBOL
+-0x4751c2af    dev_loopback_xmit       vmlinux EXPORT_SYMBOL
+-0x74bd982c    skb_seq_read    vmlinux EXPORT_SYMBOL
+-0x798c5110    snd_soc_platform_trigger        vmlinux EXPORT_SYMBOL_GPL
+-0x5362ae46    config_item_init        vmlinux EXPORT_SYMBOL
+-0x83c8a355    param_set_int   vmlinux EXPORT_SYMBOL
+-0x8099b954    i2c_transfer    vmlinux EXPORT_SYMBOL
+-0x61e262f1    scsi_device_lookup      vmlinux EXPORT_SYMBOL
+-0xfbb86a51    drm_i2c_encoder_prepare vmlinux EXPORT_SYMBOL
+-0x4090c0fe    snd_card_file_add       vmlinux EXPORT_SYMBOL
+-0x559879f5    crypto_drop_spawn       vmlinux EXPORT_SYMBOL_GPL
+-0x27c2197f    param_set_short vmlinux EXPORT_SYMBOL
+-0xcc4c1be7    nf_nat_tftp_hook        vmlinux EXPORT_SYMBOL_GPL
+-0xc9a3b093    get_h225_addr   vmlinux EXPORT_SYMBOL_GPL
+-0x59e9d996    skb_pad vmlinux EXPORT_SYMBOL
+-0x77bc13a0    strim   vmlinux EXPORT_SYMBOL
+-0x4c2a94b4    shash_register_instance vmlinux EXPORT_SYMBOL_GPL
+-0x33c77d65    seq_write       vmlinux EXPORT_SYMBOL
+-0x44aec3a4    generic_file_llseek     vmlinux EXPORT_SYMBOL
+-0x12d60b5f    v4l2_ctrl_handler_free  vmlinux EXPORT_SYMBOL
+-0x19f0c50a    ip6_tnl_parse_tlv_enc_lim       vmlinux EXPORT_SYMBOL
+-0x1cea8d0a    snd_soc_dapm_new_widgets        vmlinux EXPORT_SYMBOL_GPL
+-0xe1f4606d    snd_info_create_module_entry    vmlinux EXPORT_SYMBOL
+-0x999e8297    vfree   vmlinux EXPORT_SYMBOL
+-0x841575f5    wait_on_page_bit        vmlinux EXPORT_SYMBOL
+-0x51205d4b    mutex_lock      vmlinux EXPORT_SYMBOL
+-0xe97c74fd    rtc_update_irq_enable   vmlinux EXPORT_SYMBOL_GPL
+-0x849722db    dma_request_slave_channel       vmlinux EXPORT_SYMBOL_GPL
+-0x120b336a    __rb_insert_augmented   vmlinux EXPORT_SYMBOL
+-0x6359b128    elv_rq_merge_ok vmlinux EXPORT_SYMBOL
+-0xee3496c3    dma_pool_alloc  vmlinux EXPORT_SYMBOL
+-0xa835f402    mmc_detect_card_removed vmlinux EXPORT_SYMBOL
+-0xbe1b0b72    scsi_get_host_dev       vmlinux EXPORT_SYMBOL
+-0xaf4e166f    dma_async_memcpy_pg_to_pg       vmlinux EXPORT_SYMBOL
+-0xe34d76a6    l2cap_is_socket vmlinux EXPORT_SYMBOL
+-0xd875e3e2    ip6_route_lookup        vmlinux EXPORT_SYMBOL_GPL
+-0xd58c5fcb    tcp_v4_do_rcv   vmlinux EXPORT_SYMBOL
+-0x3413b5de    blk_dump_rq_flags       vmlinux EXPORT_SYMBOL
+-0xc8449f3c    sysfs_create_group      vmlinux EXPORT_SYMBOL_GPL
+-0xf3e42ab4    get_device      vmlinux EXPORT_SYMBOL_GPL
+-0xf147dcb2    hdmi_spd_infoframe_init vmlinux EXPORT_SYMBOL
+-0x1776281f    xfrm_unregister_mode    vmlinux EXPORT_SYMBOL
+-0x4737cc63    consume_skb     vmlinux EXPORT_SYMBOL
+-0x72081296    extcon_find_cable_index vmlinux EXPORT_SYMBOL_GPL
+-0x641d5fb6    usbnet_status_start     vmlinux EXPORT_SYMBOL_GPL
+-0x8f2c5edc    scsi_add_device vmlinux EXPORT_SYMBOL
+-0x8652db9f    __pm_stay_awake vmlinux EXPORT_SYMBOL_GPL
+-0xb9d3a88c    tcf_action_dump_1       vmlinux EXPORT_SYMBOL
+-0xb6f19e98    snd_pcm_lib_get_vmalloc_page    vmlinux EXPORT_SYMBOL
+-0x29e5e6f3    poll_schedule_timeout   vmlinux EXPORT_SYMBOL
+-0x99f58330    lg_local_lock_cpu       vmlinux EXPORT_SYMBOL
+-0x58862e69    v4l2_m2m_ioctl_streamon vmlinux EXPORT_SYMBOL_GPL
+-0xa340fae0    i2c_add_numbered_adapter        vmlinux EXPORT_SYMBOL_GPL
+-0x806c2801    usb_unanchor_urb        vmlinux EXPORT_SYMBOL_GPL
+-0x485b3745    dma_get_slave_channel   vmlinux EXPORT_SYMBOL_GPL
+-0x1d0a43c3    phy_power_off   vmlinux EXPORT_SYMBOL_GPL
+-0x0fd14a9d    tcp_prot        vmlinux EXPORT_SYMBOL
+-0x4bfdc9e2    textsearch_prepare      vmlinux EXPORT_SYMBOL
+-0x988958ef    fuse_direct_io  vmlinux EXPORT_SYMBOL_GPL
+-0x996c4d30    proc_dointvec_ms_jiffies        vmlinux EXPORT_SYMBOL
+-0x785d494b    rndis_msg_parser        vmlinux EXPORT_SYMBOL
+-0xcea853d2    root_device_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0xf13f5821    inet_frag_kill  vmlinux EXPORT_SYMBOL
+-0x8f4f1272    simple_setattr  vmlinux EXPORT_SYMBOL
+-0x9c0dba49    simple_getattr  vmlinux EXPORT_SYMBOL
+-0x2232a8a5    mempool_free    vmlinux EXPORT_SYMBOL
+-0xc72ca946    v4l2_fh_release vmlinux EXPORT_SYMBOL_GPL
+-0x2a0afd5e    videomode_from_timing   vmlinux EXPORT_SYMBOL_GPL
+-0xaf157b0c    nfc_dep_link_is_up      vmlinux EXPORT_SYMBOL
+-0x20efc937    tcf_em_tree_validate    vmlinux EXPORT_SYMBOL
+-0xd05683cc    cred_to_ucred   vmlinux EXPORT_SYMBOL_GPL
+-0xa1ac0050    sock_tx_timestamp       vmlinux EXPORT_SYMBOL
+-0x48bd992d    bdget_disk      vmlinux EXPORT_SYMBOL
+-0x50985501    configfs_register_subsystem     vmlinux EXPORT_SYMBOL
+-0x041a8568    attribute_container_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0x3de4b634    driver_for_each_device  vmlinux EXPORT_SYMBOL_GPL
+-0xc1984867    drm_vblank_put  vmlinux EXPORT_SYMBOL
+-0xc8c20253    tcp_rcv_state_process   vmlinux EXPORT_SYMBOL
+-0x280525ed    skb_to_sgvec    vmlinux EXPORT_SYMBOL_GPL
+-0x20c55ae0    sscanf  vmlinux EXPORT_SYMBOL
+-0xe3dd61a6    __breadahead    vmlinux EXPORT_SYMBOL
+-0x1b42a36f    vb2_dma_contig_init_ctx vmlinux EXPORT_SYMBOL_GPL
+-0xc326f752    v4l2_g_ctrl     vmlinux EXPORT_SYMBOL
+-0x3adca4e5    pfifo_fast_ops  vmlinux EXPORT_SYMBOL
+-0x67677183    snd_pcm_hw_constraint_integer   vmlinux EXPORT_SYMBOL
+-0x1fab5905    wait_for_completion     vmlinux EXPORT_SYMBOL
+-0x0b972255    led_classdev_suspend    vmlinux EXPORT_SYMBOL_GPL
+-0xd617281d    wm8994_set_bits vmlinux EXPORT_SYMBOL_GPL
+-0x4ad196c8    wm8994_reg_read vmlinux EXPORT_SYMBOL_GPL
+-0xb3f0ca49    platform_device_register_full   vmlinux EXPORT_SYMBOL_GPL
+-0x13bfa97e    devm_gpio_free  vmlinux EXPORT_SYMBOL
+-0xe5646321    dev_get_by_name_rcu     vmlinux EXPORT_SYMBOL
+-0x8fed35b2    snd_soc_dpcm_can_be_free_stop   vmlinux EXPORT_SYMBOL_GPL
+-0x30a4f4ca    bstr_printf     vmlinux EXPORT_SYMBOL_GPL
+-0x72350130    ___ratelimit    vmlinux EXPORT_SYMBOL
+-0x0e5d4fe1    i2c_smbus_write_byte_data       vmlinux EXPORT_SYMBOL
+-0xe7d93ea1    usb_unlink_urb  vmlinux EXPORT_SYMBOL_GPL
+-0xaf141636    __nf_nat_mangle_tcp_packet      vmlinux EXPORT_SYMBOL
+-0x584e1dcb    wm_hubs_add_analogue_controls   vmlinux EXPORT_SYMBOL_GPL
+-0x15e14e37    snd_dma_alloc_pages     vmlinux EXPORT_SYMBOL
+-0x3a26ed11    sched_clock     vmlinux EXPORT_SYMBOL_GPL
+-0x6f5d8c04    iio_device_unregister   vmlinux EXPORT_SYMBOL
+-0x9e672ff6    scsi_kmap_atomic_sg     vmlinux EXPORT_SYMBOL
+-0xe8d95e86    platform_device_add_data        vmlinux EXPORT_SYMBOL_GPL
+-0x1fcece42    inet_twdr_twcal_tick    vmlinux EXPORT_SYMBOL_GPL
+-0xd1f0ea5e    sk_unattached_filter_destroy    vmlinux EXPORT_SYMBOL_GPL
+-0xdb647fcf    sock_create_lite        vmlinux EXPORT_SYMBOL
+-0x82b125fb    mmc_hw_reset_check      vmlinux EXPORT_SYMBOL
+-0x45db3821    drm_gem_create_mmap_offset      vmlinux EXPORT_SYMBOL
+-0x4eca00d2    nfc_proto_register      vmlinux EXPORT_SYMBOL
+-0x8b69cf06    d_obtain_alias  vmlinux EXPORT_SYMBOL
+-0xc7462fc5    cpufreq_unregister_governor     vmlinux EXPORT_SYMBOL_GPL
+-0xc7280d53    v4l2_g_ext_ctrls        vmlinux EXPORT_SYMBOL
+-0xb3b58737    ip6_datagram_connect    vmlinux EXPORT_SYMBOL_GPL
+-0x365bf841    ip4_datagram_connect    vmlinux EXPORT_SYMBOL
+-0x4a8cb865    tcp_timewait_state_process      vmlinux EXPORT_SYMBOL
+-0xa34e2838    nf_conntrack_helper_try_module_get      vmlinux EXPORT_SYMBOL_GPL
+-0x26dcd9ac    security_inode_init_security    vmlinux EXPORT_SYMBOL
+-0xd705b4c7    schedule_hrtimeout      vmlinux EXPORT_SYMBOL_GPL
+-0x44643b93    __aeabi_lmul    vmlinux EXPORT_SYMBOL
+-0x824efa53    nobh_writepage  vmlinux EXPORT_SYMBOL
+-0x78eb3b6d    clear_page_dirty_for_io vmlinux EXPORT_SYMBOL
+-0xad6bf99a    srcu_init_notifier_head vmlinux EXPORT_SYMBOL_GPL
+-0x9a1fc4b4    jiffies_to_timeval      vmlinux EXPORT_SYMBOL
+-0xf1823632    clk_disable     vmlinux EXPORT_SYMBOL_GPL
+-0x69da85e3    v4l2_ctrl_poll  vmlinux EXPORT_SYMBOL
+-0xdcd7d2a3    starget_for_each_device vmlinux EXPORT_SYMBOL
+-0x4dd58b53    subsys_interface_register       vmlinux EXPORT_SYMBOL_GPL
+-0xf3916987    global_cursor_default   vmlinux EXPORT_SYMBOL
+-0x3d2b2b9f    tcp_reno_min_cwnd       vmlinux EXPORT_SYMBOL_GPL
+-0xf3bd26cd    vfs_follow_link vmlinux EXPORT_SYMBOL
+-0xc11bd00f    tracepoint_probe_unregister     vmlinux EXPORT_SYMBOL_GPL
+-0xb5532b8b    spi_bitbang_stop        vmlinux EXPORT_SYMBOL_GPL
+-0x4deb10c3    tty_schedule_flip       vmlinux EXPORT_SYMBOL
+-0x2dc227f8    brcmu_d11_attach        drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0xc009330d    sysfs_rename_link       vmlinux EXPORT_SYMBOL_GPL
+-0xce0b9b59    max77693_read_reg       vmlinux EXPORT_SYMBOL_GPL
+-0xc0c44856    tty_devnum      vmlinux EXPORT_SYMBOL
+-0x4f391d0e    nla_parse       vmlinux EXPORT_SYMBOL
+-0xc39a1e2a    write_dirty_buffer      vmlinux EXPORT_SYMBOL
+-0xc8a154f9    noop_llseek     vmlinux EXPORT_SYMBOL
+-0xc65d3eed    ring_buffer_entries_cpu vmlinux EXPORT_SYMBOL_GPL
+-0x16807034    iommu_group_for_each_dev        vmlinux EXPORT_SYMBOL_GPL
+-0x76829e1b    nfc_proto_unregister    vmlinux EXPORT_SYMBOL
+-0x21ac8b77    iommu_group_get_by_id   vmlinux EXPORT_SYMBOL_GPL
+-0x60601d69    input_free_device       vmlinux EXPORT_SYMBOL
+-0x3a03067b    regulator_notifier_call_chain   vmlinux EXPORT_SYMBOL_GPL
+-0x3e9110fa    __hw_addr_unsync        vmlinux EXPORT_SYMBOL
+-0x7d11c268    jiffies vmlinux EXPORT_SYMBOL
+-0x3987712e    iio_read_channel_scale  vmlinux EXPORT_SYMBOL_GPL
+-0x7deff673    dm_consume_args vmlinux EXPORT_SYMBOL
+-0xc092d57b    i2c_verify_adapter      vmlinux EXPORT_SYMBOL
+-0x2e7a4300    drm_rgb_quant_range_selectable  vmlinux EXPORT_SYMBOL
+-0x594e1317    __modsi3        vmlinux EXPORT_SYMBOL
+-0x211331fa    __divsi3        vmlinux EXPORT_SYMBOL
+-0xa3482467    dev_queue_xmit  vmlinux EXPORT_SYMBOL
+-0x13d0adf7    __kfifo_out     vmlinux EXPORT_SYMBOL
+-0xe06141e9    security_sk_clone       vmlinux EXPORT_SYMBOL
+-0x75d5b827    proc_mkdir      vmlinux EXPORT_SYMBOL
+-0x6f6ac78c    dummy_irq_chip  vmlinux EXPORT_SYMBOL_GPL
+-0x3efb35c9    get_online_cpus vmlinux EXPORT_SYMBOL_GPL
+-0x5907773b    of_device_alloc vmlinux EXPORT_SYMBOL
+-0x1c00411e    blk_rq_map_sg   vmlinux EXPORT_SYMBOL
+-0x09cf1b46    proc_dointvec_jiffies   vmlinux EXPORT_SYMBOL
+-0x5db2254a    devm_usb_get_phy_by_phandle     vmlinux EXPORT_SYMBOL_GPL
+-0x85caf365    usb_hcd_start_port_resume       vmlinux EXPORT_SYMBOL_GPL
+-0x0a469d23    mfd_clone_cell  vmlinux EXPORT_SYMBOL
+-0x93e85c29    dmam_free_noncoherent   vmlinux EXPORT_SYMBOL
+-0x241ab4c2    phy_destroy     vmlinux EXPORT_SYMBOL_GPL
+-0x408b2c52    __napi_schedule vmlinux EXPORT_SYMBOL
+-0xc911f7d5    dev_change_carrier      vmlinux EXPORT_SYMBOL
+-0xbfaa31e1    sk_stream_wait_memory   vmlinux EXPORT_SYMBOL
+-0x0d3cb182    kstrtos16_from_user     vmlinux EXPORT_SYMBOL
+-0x9f2bdaac    __bitmap_or     vmlinux EXPORT_SYMBOL
+-0xae729e59    security_req_classify_flow      vmlinux EXPORT_SYMBOL
+-0x273cbba4    get_dcookie     vmlinux EXPORT_SYMBOL_GPL
+-0x9b7510d1    trace_event_raw_init    vmlinux EXPORT_SYMBOL_GPL
+-0xb24585bc    usb_set_interface       vmlinux EXPORT_SYMBOL_GPL
+-0x08cbe96c    tty_unlock      vmlinux EXPORT_SYMBOL
+-0x07e3f668    netlink_broadcast_filtered      vmlinux EXPORT_SYMBOL
+-0x4761f17c    register_netevent_notifier      vmlinux EXPORT_SYMBOL_GPL
+-0xc7ec6c27    strspn  vmlinux EXPORT_SYMBOL
+-0x97255bdf    strlen  vmlinux EXPORT_SYMBOL
+-0xcdb399d4    cgroup_rightmost_descendant     vmlinux EXPORT_SYMBOL_GPL
+-0x4bc7787e    iio_trigger_register    vmlinux EXPORT_SYMBOL
+-0x05d7e32a    pm_generic_runtime_idle vmlinux EXPORT_SYMBOL_GPL
+-0xcb0b5e8e    of_display_timings_exist        vmlinux EXPORT_SYMBOL_GPL
+-0xdb68bbad    rfkill_destroy  vmlinux EXPORT_SYMBOL
+-0x2e6a04e3    hci_recv_frame  vmlinux EXPORT_SYMBOL
+-0xedbaee5e    nla_strcmp      vmlinux EXPORT_SYMBOL
+-0x26bb950b    __kfifo_from_user_r     vmlinux EXPORT_SYMBOL
+-0xca2ff6df    crypto_ahash_type       vmlinux EXPORT_SYMBOL_GPL
+-0x2c41c751    v4l2_m2m_ctx_release    vmlinux EXPORT_SYMBOL_GPL
+-0x99213409    scsi_allocate_command   vmlinux EXPORT_SYMBOL
+-0x6827603e    skb_trim        vmlinux EXPORT_SYMBOL
+-0x5cca80cf    perf_tp_event   vmlinux EXPORT_SYMBOL_GPL
+-0xa6961e25    vb2_common_vm_ops       vmlinux EXPORT_SYMBOL_GPL
+-0x72856c9e    v4l2_m2m_ioctl_expbuf   vmlinux EXPORT_SYMBOL_GPL
+-0xb8acff80    usb_enable_autosuspend  vmlinux EXPORT_SYMBOL_GPL
+-0x403f9529    gpio_request_one        vmlinux EXPORT_SYMBOL_GPL
+-0x06d549e6    pinctrl_free_gpio       vmlinux EXPORT_SYMBOL_GPL
+-0x02ae8433    xfrm_policy_delete      vmlinux EXPORT_SYMBOL
+-0x6e71c6be    inet_frags_init vmlinux EXPORT_SYMBOL
+-0x4e3567f7    match_int       vmlinux EXPORT_SYMBOL
+-0x054434d6    radix_tree_tag_set      vmlinux EXPORT_SYMBOL
+-0x31f956eb    blk_queue_lld_busy      vmlinux EXPORT_SYMBOL_GPL
+-0x26565c84    shash_free_instance     vmlinux EXPORT_SYMBOL_GPL
+-0x38668bab    debugfs_create_x64      vmlinux EXPORT_SYMBOL_GPL
+-0xbf1f9a9b    bdi_setup_and_register  vmlinux EXPORT_SYMBOL
+-0xfc64abed    power_supply_changed    vmlinux EXPORT_SYMBOL_GPL
+-0x19326753    rtc_irq_register        vmlinux EXPORT_SYMBOL_GPL
+-0xaf3cc095    nfc_hci_free_device     vmlinux EXPORT_SYMBOL
+-0x86f38980    skb_cow_data    vmlinux EXPORT_SYMBOL_GPL
+-0xe0c0d2af    snd_pcm_kernel_ioctl    vmlinux EXPORT_SYMBOL
+-0xdfb01a80    cpu_v7_dcache_clean_area        vmlinux EXPORT_SYMBOL
+-0x1879fcbd    bridge_tunnel_header    vmlinux EXPORT_SYMBOL
+-0x9a011a6b    l2cap_conn_put  vmlinux EXPORT_SYMBOL
+-0x6b3ee85a    ip4_datagram_release_cb vmlinux EXPORT_SYMBOL_GPL
+-0xdd07d415    snd_card_free_when_closed       vmlinux EXPORT_SYMBOL
+-0x868acba5    get_options     vmlinux EXPORT_SYMBOL
+-0xa2409544    setup_irq       vmlinux EXPORT_SYMBOL_GPL
+-0x567b73f9    i2c_get_adapter vmlinux EXPORT_SYMBOL
+-0x7a4e7297    drm_edid_block_valid    vmlinux EXPORT_SYMBOL
+-0x2ec524ad    __kfifo_in_r    vmlinux EXPORT_SYMBOL
+-0x66f9da32    bh_uptodate_or_lock     vmlinux EXPORT_SYMBOL
+-0xf9ffcd69    input_unregister_handler        vmlinux EXPORT_SYMBOL
+-0x51dce73b    xfrm_state_walk_init    vmlinux EXPORT_SYMBOL
+-0x113554e9    __skb_dst_set_noref     vmlinux EXPORT_SYMBOL
+-0x3c9d1211    string_get_size vmlinux EXPORT_SYMBOL
+-0xe654362e    fat_fill_super  vmlinux EXPORT_SYMBOL_GPL
+-0xea5a46e7    register_exec_domain    vmlinux EXPORT_SYMBOL
+-0xaf473214    iio_channel_get_all     vmlinux EXPORT_SYMBOL_GPL
+-0xf8a9d6b2    rtc_read_alarm  vmlinux EXPORT_SYMBOL_GPL
+-0xa0c8e0ed    usbnet_set_settings     vmlinux EXPORT_SYMBOL_GPL
+-0x170bb6a9    usbnet_get_settings     vmlinux EXPORT_SYMBOL_GPL
+-0xe0701fe6    fl6_sock_lookup vmlinux EXPORT_SYMBOL_GPL
+-0x9330cb9f    sg_alloc_table  vmlinux EXPORT_SYMBOL
+-0x5873f4c0    handle_simple_irq       vmlinux EXPORT_SYMBOL_GPL
+-0xf27977e2    async_synchronize_cookie_domain vmlinux EXPORT_SYMBOL_GPL
+-0xcf732e49    call_usermodehelper_exec        vmlinux EXPORT_SYMBOL
+-0xd789a39d    cpufreq_governor_dbs    vmlinux EXPORT_SYMBOL_GPL
+-0x4ff0c84f    of_mdio_find_bus        vmlinux EXPORT_SYMBOL
+-0xe7a664c4    nf_hooks        vmlinux EXPORT_SYMBOL
+-0xd366806d    snd_info_free_entry     vmlinux EXPORT_SYMBOL
+-0xbcac6160    pm_qos_remove_notifier  vmlinux EXPORT_SYMBOL_GPL
+-0x698d1e98    v4l2_ctrl_handler_init_class    vmlinux EXPORT_SYMBOL
+-0x79c0d5a3    drm_gem_prime_fd_to_handle      vmlinux EXPORT_SYMBOL
+-0xff1e9dd8    seq_list_start  vmlinux EXPORT_SYMBOL
+-0x01accd73    __clk_get_name  vmlinux EXPORT_SYMBOL_GPL
+-0x3e92b3d3    power_supply_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x71590103    drm_release     vmlinux EXPORT_SYMBOL
+-0x0b9e5852    xfrm_aead_get_byname    vmlinux EXPORT_SYMBOL_GPL
+-0xb7b856bf    km_state_notify vmlinux EXPORT_SYMBOL
+-0x3f5b1415    nf_ct_port_nlattr_to_tuple      vmlinux EXPORT_SYMBOL_GPL
+-0x98b6628a    snd_pcm_set_ops vmlinux EXPORT_SYMBOL
+-0x1ea06663    _raw_write_lock vmlinux EXPORT_SYMBOL
+-0x44dd3d8d    completion_done vmlinux EXPORT_SYMBOL
+-0xa1eabd87    drm_mode_list_concat    vmlinux EXPORT_SYMBOL
+-0x581ed292    drm_mm_get_block_generic        vmlinux EXPORT_SYMBOL
+-0xefa98e30    dma_run_dependencies    vmlinux EXPORT_SYMBOL_GPL
+-0xe8bea3bc    qdisc_put_stab  vmlinux EXPORT_SYMBOL
+-0x2247cba2    seq_printf      vmlinux EXPORT_SYMBOL
+-0x7e646f56    media_entity_remove_links       vmlinux EXPORT_SYMBOL_GPL
+-0xa0e05fb1    drm_connector_cleanup   vmlinux EXPORT_SYMBOL
+-0xb1cf44df    fb_find_best_mode       vmlinux EXPORT_SYMBOL
+-0x0b742fd7    simple_strtol   vmlinux EXPORT_SYMBOL
+-0xd709e32c    ilookup5_nowait vmlinux EXPORT_SYMBOL
+-0x25865b31    mmc_free_host   vmlinux EXPORT_SYMBOL
+-0x054063e9    devres_release  vmlinux EXPORT_SYMBOL_GPL
+-0xc9b2045b    drm_mode_validate_size  vmlinux EXPORT_SYMBOL
+-0xac6855b0    gen_kill_estimator      vmlinux EXPORT_SYMBOL
+-0xc32b07a0    blk_queue_alignment_offset      vmlinux EXPORT_SYMBOL
+-0x630c9194    fuse_dev_operations     vmlinux EXPORT_SYMBOL_GPL
+-0xa4824580    devm_add_action vmlinux EXPORT_SYMBOL_GPL
+-0xd8fe5b35    drm_mm_init     vmlinux EXPORT_SYMBOL
+-0x9b9b05b4    __bio_clone     vmlinux EXPORT_SYMBOL
+-0x5fda0227    vfs_stat        vmlinux EXPORT_SYMBOL
+-0xa0fbac79    wake_up_bit     vmlinux EXPORT_SYMBOL
+-0x796fc5ce    scsi_get_sense_info_fld vmlinux EXPORT_SYMBOL
+-0x699ffdcd    nf_conntrack_flush_report       vmlinux EXPORT_SYMBOL_GPL
+-0x89e6edac    snd_pcm_lib_malloc_pages        vmlinux EXPORT_SYMBOL
+-0x48034724    zlib_deflateReset       vmlinux EXPORT_SYMBOL
+-0xcdca3691    nr_irqs vmlinux EXPORT_SYMBOL_GPL
+-0xcff6b676    _raw_spin_trylock_bh    vmlinux EXPORT_SYMBOL
+-0xca45efbc    drm_format_horz_chroma_subsampling      vmlinux EXPORT_SYMBOL
+-0xb6f4cc92    tty_do_resize   vmlinux EXPORT_SYMBOL
+-0x51e77c97    pfn_valid       vmlinux EXPORT_SYMBOL
+-0xa2446605    jbd2_journal_set_triggers       vmlinux EXPORT_SYMBOL
+-0xebbb44c8    f_setown        vmlinux EXPORT_SYMBOL
+-0xdfef3371    v4l2_m2m_ioctl_streamoff        vmlinux EXPORT_SYMBOL_GPL
+-0x56c8799d    scsi_kunmap_atomic_sg   vmlinux EXPORT_SYMBOL
+-0xaae1593e    scsi_block_when_processing_errors       vmlinux EXPORT_SYMBOL
+-0xe330bf1f    ip6_dst_hoplimit        vmlinux EXPORT_SYMBOL
+-0xf8996ee4    arp_invalidate  vmlinux EXPORT_SYMBOL
+-0x6d27ef64    __bitmap_empty  vmlinux EXPORT_SYMBOL
+-0xbfa789ca    elv_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0x06ae2b19    mmc_can_sanitize        vmlinux EXPORT_SYMBOL
+-0xdd3dc2ce    usb_clear_halt  vmlinux EXPORT_SYMBOL_GPL
+-0xfe0b2aae    amba_device_unregister  vmlinux EXPORT_SYMBOL
+-0xc3771b21    of_pwm_get      vmlinux EXPORT_SYMBOL_GPL
+-0x21b7d56d    dev_mc_sync_multiple    vmlinux EXPORT_SYMBOL
+-0x1dfc5292    dev_uc_sync_multiple    vmlinux EXPORT_SYMBOL
+-0xde7da8e3    submit_bh       vmlinux EXPORT_SYMBOL
+-0xc15d05d9    mnt_clone_write vmlinux EXPORT_SYMBOL_GPL
+-0x25fa84a3    page_mkclean    vmlinux EXPORT_SYMBOL_GPL
+-0x405c1144    get_seconds     vmlinux EXPORT_SYMBOL
+-0xf0f1246c    kvasprintf      vmlinux EXPORT_SYMBOL
+-0xa5526619    rb_insert_color vmlinux EXPORT_SYMBOL
+-0x7bb12a75    v4l2_m2m_get_vq vmlinux EXPORT_SYMBOL
+-0x5819c8aa    usb_anchor_empty        vmlinux EXPORT_SYMBOL_GPL
+-0x4e3d273c    __xfrm_init_state       vmlinux EXPORT_SYMBOL
+-0xa2a69edc    __module_text_address   vmlinux EXPORT_SYMBOL_GPL
+-0x66d87d38    symbol_put_addr vmlinux EXPORT_SYMBOL_GPL
+-0xe45cc839    hrtimer_start_range_ns  vmlinux EXPORT_SYMBOL_GPL
+-0xd3e6f60d    cpu_possible_mask       vmlinux EXPORT_SYMBOL
+-0x52451ffe    hid_dump_field  vmlinux EXPORT_SYMBOL_GPL
+-0xbd5a9986    drm_helper_probe_single_connector_modes vmlinux EXPORT_SYMBOL
+-0xb694ce34    tcf_hash_search vmlinux EXPORT_SYMBOL
+-0xaaefb815    d_alloc vmlinux EXPORT_SYMBOL
+-0xaca38c86    unuse_mm        vmlinux EXPORT_SYMBOL_GPL
+-0x5de3d7af    __alloc_pages_nodemask  vmlinux EXPORT_SYMBOL
+-0xe2142ad8    i2c_smbus_read_word_data        vmlinux EXPORT_SYMBOL
+-0xbfe4cfe6    tty_buffer_request_room vmlinux EXPORT_SYMBOL_GPL
+-0xa6089679    elv_abort_queue vmlinux EXPORT_SYMBOL
+-0x918ad429    ring_buffer_lock_reserve        vmlinux EXPORT_SYMBOL_GPL
+-0xdc461430    irq_set_affinity_hint   vmlinux EXPORT_SYMBOL_GPL
+-0x37258879    iio_channel_release     vmlinux EXPORT_SYMBOL_GPL
+-0x1a082d69    max77693_update_reg     vmlinux EXPORT_SYMBOL_GPL
+-0x4b0bd573    wiphy_unregister        vmlinux EXPORT_SYMBOL
+-0x575d8c47    inet_sk_rx_dst_set      vmlinux EXPORT_SYMBOL
+-0x3c6f5a97    snd_soc_register_component      vmlinux EXPORT_SYMBOL_GPL
+-0xb9e03943    blk_execute_rq_nowait   vmlinux EXPORT_SYMBOL_GPL
+-0x15f571ec    blk_set_stacking_limits vmlinux EXPORT_SYMBOL
+-0x721585fd    security_inode_mkdir    vmlinux EXPORT_SYMBOL_GPL
+-0xbf16ef9a    clk_get_rate    vmlinux EXPORT_SYMBOL_GPL
+-0x22b79dae    clk_set_rate    vmlinux EXPORT_SYMBOL_GPL
+-0x0dbd0e20    of_property_read_u8_array       vmlinux EXPORT_SYMBOL_GPL
+-0xe6fce6f2    v4l2_ctrl_merge vmlinux EXPORT_SYMBOL
+-0x12f1d8d3    dev_err vmlinux EXPORT_SYMBOL
+-0x1c3e0368    drm_gem_object_handle_free      vmlinux EXPORT_SYMBOL
+-0xfda9ed46    udp_proc_register       vmlinux EXPORT_SYMBOL
+-0xccf2974f    kernel_sendpage vmlinux EXPORT_SYMBOL
+-0x4b77922a    delete_from_page_cache  vmlinux EXPORT_SYMBOL
+-0x3f5b67d5    wait_for_completion_killable    vmlinux EXPORT_SYMBOL
+-0xa62fb61a    usb_gstrings_attach     vmlinux EXPORT_SYMBOL_GPL
+-0x5cabdced    dev_pm_qos_remove_global_notifier       vmlinux EXPORT_SYMBOL_GPL
+-0x27b864a9    s5p_gpio_get_drvstr     vmlinux EXPORT_SYMBOL
+-0xc828d2a3    s5p_gpio_set_drvstr     vmlinux EXPORT_SYMBOL
+-0xd9cf81bd    cfg80211_send_assoc_timeout     vmlinux EXPORT_SYMBOL
+-0x693c3961    nf_ct_helper_hash       vmlinux EXPORT_SYMBOL_GPL
+-0x487ef8ba    snd_soc_dai_set_sysclk  vmlinux EXPORT_SYMBOL_GPL
+-0x50c89f23    __alloc_percpu  vmlinux EXPORT_SYMBOL_GPL
+-0x09469482    kfree_call_rcu  vmlinux EXPORT_SYMBOL_GPL
+-0x177d5d5e    uart_insert_char        vmlinux EXPORT_SYMBOL_GPL
+-0xb17c2f9b    clear_inode     vmlinux EXPORT_SYMBOL
+-0x3b733a7c    led_trigger_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0x16000a3c    dm_device_name  vmlinux EXPORT_SYMBOL_GPL
+-0x0465ca31    scsi_cmd_get_serial     vmlinux EXPORT_SYMBOL
+-0x0f52944d    drm_helper_hpd_irq_event        vmlinux EXPORT_SYMBOL
+-0x99517682    udp_encap_enable        vmlinux EXPORT_SYMBOL
+-0x1e43dec1    neigh_parms_release     vmlinux EXPORT_SYMBOL
+-0x572e85d4    blk_lookup_devt vmlinux EXPORT_SYMBOL
+-0xf7bb06b2    crypto_grab_skcipher    vmlinux EXPORT_SYMBOL_GPL
+-0xe953b21f    get_next_ino    vmlinux EXPORT_SYMBOL
+-0xdb225b82    pm_vt_switch_required   vmlinux EXPORT_SYMBOL
+-0xe1a4b69f    mmc_card_awake  vmlinux EXPORT_SYMBOL
+-0x33234a30    usb_hcd_link_urb_to_ep  vmlinux EXPORT_SYMBOL_GPL
+-0xb61a0dba    dmam_release_declared_memory    vmlinux EXPORT_SYMBOL
+-0x6865b5f6    device_release_driver   vmlinux EXPORT_SYMBOL_GPL
+-0x920accbd    ump_dd_secure_id_get    vmlinux EXPORT_SYMBOL
+-0xffb94ef0    _test_and_change_bit    vmlinux EXPORT_SYMBOL
+-0xb7a1ff6d    tcp_prequeue    vmlinux EXPORT_SYMBOL
+-0xce3ca308    copy_from_user_toio     vmlinux EXPORT_SYMBOL
+-0xd08137e8    vfs_setlease    vmlinux EXPORT_SYMBOL_GPL
+-0x89eabc8c    from_kgid_munged        vmlinux EXPORT_SYMBOL
+-0x40d04664    console_trylock vmlinux EXPORT_SYMBOL
+-0x0955d1f2    iommu_attach_device     vmlinux EXPORT_SYMBOL_GPL
+-0x9cf3e94a    dm_kcopyd_copy  vmlinux EXPORT_SYMBOL
+-0x1cec399d    v4l2_m2m_ioctl_create_bufs      vmlinux EXPORT_SYMBOL_GPL
+-0x8cae11ac    usb_alloc_streams       vmlinux EXPORT_SYMBOL_GPL
+-0xd3299096    scsi_register_interface vmlinux EXPORT_SYMBOL
+-0x885369a2    dma_common_get_sgtable  vmlinux EXPORT_SYMBOL
+-0x2251d13d    blk_queue_dma_pad       vmlinux EXPORT_SYMBOL
+-0x07cf9099    wait_for_completion_timeout     vmlinux EXPORT_SYMBOL
+-0x0efcbb1b    set_current_groups      vmlinux EXPORT_SYMBOL
+-0xea9b0ab7    v4l2_ctrl_add_handler   vmlinux EXPORT_SYMBOL
+-0x79aaab2b    i2c_smbus_read_block_data       vmlinux EXPORT_SYMBOL
+-0x964ff64a    usb_put_intf    vmlinux EXPORT_SYMBOL_GPL
+-0x9f97bf25    xfrm6_input_addr        vmlinux EXPORT_SYMBOL
+-0x81db6ebb    xz_dec_reset    vmlinux EXPORT_SYMBOL
+-0x661601de    sprint_symbol   vmlinux EXPORT_SYMBOL_GPL
+-0x1e59773c    st_gyro_common_remove   vmlinux EXPORT_SYMBOL
+-0x921e453c    drm_get_platform_dev    vmlinux EXPORT_SYMBOL
+-0x720b245e    update_region   vmlinux EXPORT_SYMBOL
+-0x2bda5922    hci_get_route   vmlinux EXPORT_SYMBOL
+-0xaa939a8b    tcf_em_unregister       vmlinux EXPORT_SYMBOL
+-0x590cf866    scm_fp_dup      vmlinux EXPORT_SYMBOL
+-0x2ce98559    kcrypto_wq      vmlinux EXPORT_SYMBOL_GPL
+-0x5351af17    shrink_dcache_parent    vmlinux EXPORT_SYMBOL
+-0x1ad83009    trace_seq_vprintf       vmlinux EXPORT_SYMBOL_GPL
+-0x8fcafa61    led_stop_software_blink vmlinux EXPORT_SYMBOL_GPL
+-0xd4a7943a    mmc_card_can_sleep      vmlinux EXPORT_SYMBOL
+-0x52f378a8    devres_remove   vmlinux EXPORT_SYMBOL_GPL
+-0x6288b8b9    serial8250_release_dma  vmlinux EXPORT_SYMBOL_GPL
+-0x63556dea    tty_vhangup     vmlinux EXPORT_SYMBOL
+-0x75c8a11c    inet_twdr_twkill_work   vmlinux EXPORT_SYMBOL_GPL
+-0x609f1c7e    synchronize_net vmlinux EXPORT_SYMBOL
+-0x6091797f    synchronize_rcu vmlinux EXPORT_SYMBOL_GPL
+-0x42825ce2    rcu_scheduler_active    vmlinux EXPORT_SYMBOL_GPL
+-0xe523ad75    synchronize_irq vmlinux EXPORT_SYMBOL
+-0xb77b0159    v4l2_prio_init  vmlinux EXPORT_SYMBOL
+-0x840dd143    rndis_deregister        vmlinux EXPORT_SYMBOL
+-0x7464ea38    dev_pm_qos_add_global_notifier  vmlinux EXPORT_SYMBOL_GPL
+-0xd325a885    bus_for_each_dev        vmlinux EXPORT_SYMBOL_GPL
+-0x3ec3d061    bus_for_each_drv        vmlinux EXPORT_SYMBOL_GPL
+-0xb2823478    pneigh_lookup   vmlinux EXPORT_SYMBOL
+-0x7037aaf0    kern_path_create        vmlinux EXPORT_SYMBOL
+-0x85061b76    _raw_write_lock_bh      vmlinux EXPORT_SYMBOL
+-0xb90cbedf    v4l2_of_get_next_endpoint       vmlinux EXPORT_SYMBOL
+-0x9d2ed0a8    snd_timer_close vmlinux EXPORT_SYMBOL
+-0x1057d320    blk_queue_find_tag      vmlinux EXPORT_SYMBOL
+-0x1e3a88fb    trace_seq_printf        vmlinux EXPORT_SYMBOL_GPL
+-0x4bc62a81    audit_enabled   vmlinux EXPORT_SYMBOL_GPL
+-0x39461d6a    in_egroup_p     vmlinux EXPORT_SYMBOL
+-0xccefabad    drm_mode_create_scaling_mode_property   vmlinux EXPORT_SYMBOL
+-0x43384bd9    drm_buffer_alloc        vmlinux EXPORT_SYMBOL
+-0x184e6c85    radix_tree_gang_lookup_slot     vmlinux EXPORT_SYMBOL
+-0xdf347b52    sec_reg_read    vmlinux EXPORT_SYMBOL_GPL
+-0x409873e3    tty_termios_baud_rate   vmlinux EXPORT_SYMBOL
+-0x07a890c8    fb_alloc_cmap   vmlinux EXPORT_SYMBOL
+-0x7d04aaa6    nf_conntrack_broadcast_help     vmlinux EXPORT_SYMBOL_GPL
+-0x5cdc7a62    skb_append_datato_frags vmlinux EXPORT_SYMBOL
+-0x9e0c711d    vzalloc_node    vmlinux EXPORT_SYMBOL
+-0x7f24de73    jiffies_to_usecs        vmlinux EXPORT_SYMBOL
+-0x37befc70    jiffies_to_msecs        vmlinux EXPORT_SYMBOL
+-0xe9807d5b    input_mt_sync_frame     vmlinux EXPORT_SYMBOL
+-0x0c0c8520    release_firmware        vmlinux EXPORT_SYMBOL
+-0x442aa46d    tcp_child_process       vmlinux EXPORT_SYMBOL
+-0x67663177    sock_diag_put_filterinfo        vmlinux EXPORT_SYMBOL
+-0xa250c838    param_get_charp vmlinux EXPORT_SYMBOL
+-0xf0b613ad    __pm_runtime_suspend    vmlinux EXPORT_SYMBOL_GPL
+-0x1a770ac3    drm_detect_hdmi_monitor vmlinux EXPORT_SYMBOL
+-0x70d7e40d    prepare_binprm  vmlinux EXPORT_SYMBOL
+-0x36d7b11a    of_find_matching_node_and_match vmlinux EXPORT_SYMBOL
+-0x8e30ad82    mdiobus_write   vmlinux EXPORT_SYMBOL
+-0xeb6173b8    tty_port_destroy        vmlinux EXPORT_SYMBOL
+-0x6c0154da    tcp_v4_destroy_sock     vmlinux EXPORT_SYMBOL
+-0x5afe3100    snd_soc_add_dai_controls        vmlinux EXPORT_SYMBOL_GPL
+-0xdf2c2742    rb_last vmlinux EXPORT_SYMBOL
+-0x7ab3ca18    eventfd_ctx_read        vmlinux EXPORT_SYMBOL_GPL
+-0xeb32e3af    mount_bdev      vmlinux EXPORT_SYMBOL
+-0xe6fbe430    can_do_mlock    vmlinux EXPORT_SYMBOL
+-0x60a13e90    rcu_barrier     vmlinux EXPORT_SYMBOL_GPL
+-0xdf60cc27    __print_symbol  vmlinux EXPORT_SYMBOL
+-0xa2a2031e    ehci_setup      vmlinux EXPORT_SYMBOL_GPL
+-0x686f8200    ndisc_mc_map    vmlinux EXPORT_SYMBOL
+-0xab8647cf    nf_ct_helper_expectfn_find_by_symbol    vmlinux EXPORT_SYMBOL_GPL
+-0x91715312    sprintf vmlinux EXPORT_SYMBOL
+-0xda3d10a8    security_tun_dev_open   vmlinux EXPORT_SYMBOL
+-0xa4a91e54    simple_unlink   vmlinux EXPORT_SYMBOL
+-0xf377a0b5    simple_attr_write       vmlinux EXPORT_SYMBOL_GPL
+-0x97263968    generic_listxattr       vmlinux EXPORT_SYMBOL
+-0x53c9394f    v4l2_ctrl_query_menu    vmlinux EXPORT_SYMBOL
+-0xf6ebc03b    net_ratelimit   vmlinux EXPORT_SYMBOL
+-0x3977cbea    dev_addr_init   vmlinux EXPORT_SYMBOL
+-0x2789cd4f    snd_soc_put_strobe      vmlinux EXPORT_SYMBOL_GPL
+-0x719074ee    snd_soc_get_strobe      vmlinux EXPORT_SYMBOL_GPL
+-0xdace599d    shash_ahash_update      vmlinux EXPORT_SYMBOL_GPL
+-0x7add44b5    posix_acl_valid vmlinux EXPORT_SYMBOL
+-0xe8fbe1c9    invalidate_inode_buffers        vmlinux EXPORT_SYMBOL
+-0x5442b464    media_device_register_entity    vmlinux EXPORT_SYMBOL_GPL
+-0xa279bad0    usb_add_config  vmlinux EXPORT_SYMBOL_GPL
+-0x1d77b0f8    unix_socket_table       vmlinux EXPORT_SYMBOL_GPL
+-0x7932f1fc    ip_tunnel_ioctl vmlinux EXPORT_SYMBOL_GPL
+-0x153b7ac0    nl_table        vmlinux EXPORT_SYMBOL_GPL
+-0xfdfcdc90    crypto_shash_update     vmlinux EXPORT_SYMBOL_GPL
+-0xa376521b    find_vma        vmlinux EXPORT_SYMBOL
+-0xe57f0426    vb2_dma_contig_cleanup_ctx      vmlinux EXPORT_SYMBOL_GPL
+-0x0f53690e    usb_autopm_get_interface_async  vmlinux EXPORT_SYMBOL_GPL
+-0xe97e3624    scsi_register   vmlinux EXPORT_SYMBOL
+-0x07d4567b    max8997_write_reg       vmlinux EXPORT_SYMBOL_GPL
+-0x24f2d831    regulator_register_notifier     vmlinux EXPORT_SYMBOL_GPL
+-0x85ab9275    nf_ct_extend_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x7721fbd2    kernel_connect  vmlinux EXPORT_SYMBOL
+-0x3095e489    single_open_size        vmlinux EXPORT_SYMBOL
+-0x54ff695a    inet_stream_connect     vmlinux EXPORT_SYMBOL
+-0xa05c03df    mempool_kmalloc vmlinux EXPORT_SYMBOL
+-0xd6df7b3f    dma_buf_end_cpu_access  vmlinux EXPORT_SYMBOL_GPL
+-0x2d5eac78    qdisc_warn_nonwc        vmlinux EXPORT_SYMBOL
+-0x7bc477d0    splice_from_pipe_begin  vmlinux EXPORT_SYMBOL
+-0xfd6293c2    boot_tvec_bases vmlinux EXPORT_SYMBOL
+-0x6d662533    _find_first_bit_le      vmlinux EXPORT_SYMBOL
+-0xd41f3207    netdev_class_remove_file        vmlinux EXPORT_SYMBOL
+-0xdf48a0eb    flex_array_put  vmlinux EXPORT_SYMBOL
+-0xcf048d93    blk_queue_physical_block_size   vmlinux EXPORT_SYMBOL
+-0xd5790350    dio_end_io      vmlinux EXPORT_SYMBOL_GPL
+-0xc0bf6ead    timecounter_cyc2time    vmlinux EXPORT_SYMBOL_GPL
+-0x303087f1    v4l2_queryctrl  vmlinux EXPORT_SYMBOL
+-0x506691f1    sock_diag_check_cookie  vmlinux EXPORT_SYMBOL_GPL
+-0x307c2fd0    generic_check_addressable       vmlinux EXPORT_SYMBOL
+-0x40b313d1    perf_event_read_value   vmlinux EXPORT_SYMBOL_GPL
+-0x04482cdb    __refrigerator  vmlinux EXPORT_SYMBOL
+-0x7cb1ae69    cpu_down        vmlinux EXPORT_SYMBOL
+-0xc9aca11e    v4l2_ctrl_handler_log_status    vmlinux EXPORT_SYMBOL
+-0xb7f77027    rtc_tm_to_ktime vmlinux EXPORT_SYMBOL_GPL
+-0x70c8201b    tty_lock_pair   vmlinux EXPORT_SYMBOL
+-0x1565add4    inet6_csk_addr2sockaddr vmlinux EXPORT_SYMBOL_GPL
+-0x72a112d9    netdev_refcnt_read      vmlinux EXPORT_SYMBOL
+-0xacc6730b    __blk_end_request       vmlinux EXPORT_SYMBOL
+-0xbe54542c    input_mt_init_slots     vmlinux EXPORT_SYMBOL
+-0xca3920b5    usb_disable_lpm vmlinux EXPORT_SYMBOL_GPL
+-0x0cd967c3    usb_disable_ltm vmlinux EXPORT_SYMBOL_GPL
+-0x3b66b0c1    __pm_wakeup_event       vmlinux EXPORT_SYMBOL_GPL
+-0x0f480178    devres_close_group      vmlinux EXPORT_SYMBOL_GPL
+-0xf0bd9740    drm_mode_parse_command_line_for_connector       vmlinux EXPORT_SYMBOL
+-0x12c6276a    drm_buffer_read_object  vmlinux EXPORT_SYMBOL
+-0xc3b93bba    klist_next      vmlinux EXPORT_SYMBOL_GPL
+-0x3d342d92    tcp_rcv_established     vmlinux EXPORT_SYMBOL
+-0x540c6f94    inet_getpeer    vmlinux EXPORT_SYMBOL_GPL
+-0x153c8015    ipv4_update_pmtu        vmlinux EXPORT_SYMBOL_GPL
+-0x0c4bfb03    xt_unregister_targets   vmlinux EXPORT_SYMBOL
+-0x5cd7eb9b    wm_hubs_dcs_done        vmlinux EXPORT_SYMBOL_GPL
+-0xd7e56a4e    simple_strtoll  vmlinux EXPORT_SYMBOL
+-0x20000329    simple_strtoul  vmlinux EXPORT_SYMBOL
+-0x9e784e44    balance_dirty_pages_ratelimited vmlinux EXPORT_SYMBOL
+-0x11195d33    usb_enable_lpm  vmlinux EXPORT_SYMBOL_GPL
+-0xd7f91a45    usb_enable_ltm  vmlinux EXPORT_SYMBOL_GPL
+-0x39e2b6d2    spi_alloc_master        vmlinux EXPORT_SYMBOL_GPL
+-0x82eb671b    scsi_prep_fn    vmlinux EXPORT_SYMBOL
+-0x4473fccc    nf_register_afinfo      vmlinux EXPORT_SYMBOL_GPL
+-0xd1e13a97    net_ns_type_operations  vmlinux EXPORT_SYMBOL_GPL
+-0x1bf69c17    proc_symlink    vmlinux EXPORT_SYMBOL
+-0x651c3828    usb_add_phy_dev vmlinux EXPORT_SYMBOL_GPL
+-0xf571b062    drm_addmap      vmlinux EXPORT_SYMBOL
+-0xb41150b4    pwm_enable      vmlinux EXPORT_SYMBOL_GPL
+-0x8c52195f    __rtnl_link_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0xe2cb9278    snd_soc_dai_set_tdm_slot        vmlinux EXPORT_SYMBOL_GPL
+-0x4de34a07    cpu_rmap_put    vmlinux EXPORT_SYMBOL
+-0xb51797f0    blk_queue_dma_alignment vmlinux EXPORT_SYMBOL
+-0xdab3304e    remap_vmalloc_range     vmlinux EXPORT_SYMBOL
+-0x5113c626    noop_backing_dev_info   vmlinux EXPORT_SYMBOL_GPL
+-0xd985dc99    mempool_free_pages      vmlinux EXPORT_SYMBOL
+-0xfcec0987    enable_irq      vmlinux EXPORT_SYMBOL
+-0x1e7bbcb3    kernel_restart  vmlinux EXPORT_SYMBOL_GPL
+-0xa26c3f65    mmc_gpio_free_cd        vmlinux EXPORT_SYMBOL
+-0x6461806d    max8997_bulk_write      vmlinux EXPORT_SYMBOL_GPL
+-0x2ff9c227    filemap_page_mkwrite    vmlinux EXPORT_SYMBOL
+-0xd2917bd3    v4l2_m2m_fop_poll       vmlinux EXPORT_SYMBOL_GPL
+-0xc11159cc    drm_mode_create vmlinux EXPORT_SYMBOL
+-0xdd27fa87    memchr  vmlinux EXPORT_SYMBOL
+-0x10329729    inet6_release   vmlinux EXPORT_SYMBOL
+-0xc18ac88d    nf_ct_expect_hsize      vmlinux EXPORT_SYMBOL_GPL
+-0x005e9828    vfs_kern_mount  vmlinux EXPORT_SYMBOL_GPL
+-0xd5bd7dac    ring_buffer_record_enable_cpu   vmlinux EXPORT_SYMBOL_GPL
+-0x00cf4a7f    of_get_parent   vmlinux EXPORT_SYMBOL
+-0xd6097597    v4l2_ctrl_new_int_menu  vmlinux EXPORT_SYMBOL
+-0x3cdbf719    drm_mode_destroy        vmlinux EXPORT_SYMBOL
+-0xb03e9a0f    nfc_set_remote_general_bytes    vmlinux EXPORT_SYMBOL
+-0x2059c814    sock_diag_register      vmlinux EXPORT_SYMBOL_GPL
+-0x315c65fd    zlib_deflateInit2       vmlinux EXPORT_SYMBOL
+-0x1ab8c624    submit_bio      vmlinux EXPORT_SYMBOL
+-0xd070d52e    alloc_page_buffers      vmlinux EXPORT_SYMBOL_GPL
+-0x622c7922    register_oom_notifier   vmlinux EXPORT_SYMBOL_GPL
+-0xe806f5a2    trace_event_buffer_lock_reserve vmlinux EXPORT_SYMBOL_GPL
+-0xcfc68341    synchronize_rcu_bh      vmlinux EXPORT_SYMBOL_GPL
+-0x549525ef    handle_nested_irq       vmlinux EXPORT_SYMBOL_GPL
+-0x20421305    on_each_cpu_mask        vmlinux EXPORT_SYMBOL
+-0xa1bb9fb1    spi_bus_type    vmlinux EXPORT_SYMBOL_GPL
+-0x8a627eb3    anon_transport_class_unregister vmlinux EXPORT_SYMBOL_GPL
+-0xd8525ea7    fl6_update_dst  vmlinux EXPORT_SYMBOL_GPL
+-0xbac1a16b    tcp_valid_rtt_meas      vmlinux EXPORT_SYMBOL
+-0xb67cd6f1    neigh_lookup    vmlinux EXPORT_SYMBOL
+-0xc2c639ae    debugfs_create_u32_array        vmlinux EXPORT_SYMBOL_GPL
+-0xd4a33b98    mmc_remove_host vmlinux EXPORT_SYMBOL
+-0x1f65abdf    usb_put_hcd     vmlinux EXPORT_SYMBOL_GPL
+-0x2ef63ad6    scsi_dev_info_list_del_keyed    vmlinux EXPORT_SYMBOL
+-0x0bf18882    tcp_mtup_init   vmlinux EXPORT_SYMBOL
+-0x0ea07ec7    kstrtou8_from_user      vmlinux EXPORT_SYMBOL
+-0x973d0f9e    kstrtoul_from_user      vmlinux EXPORT_SYMBOL
+-0x7c8db884    devm_clk_unregister     vmlinux EXPORT_SYMBOL_GPL
+-0x46066e5b    perf_pmu_name   vmlinux EXPORT_SYMBOL_GPL
+-0x951ac153    snd_soc_jack_report     vmlinux EXPORT_SYMBOL_GPL
+-0x7c1464a6    snd_soc_dapm_get_enum_double    vmlinux EXPORT_SYMBOL_GPL
+-0xd36af700    snd_soc_dapm_put_enum_double    vmlinux EXPORT_SYMBOL_GPL
+-0x222e7ce2    sysfs_streq     vmlinux EXPORT_SYMBOL
+-0xca72b2e9    alloc_buffer_head       vmlinux EXPORT_SYMBOL
+-0x364d71cb    iio_scan_mask_set       vmlinux EXPORT_SYMBOL_GPL
+-0x813f3de4    v4l2_find_nearest_format        vmlinux EXPORT_SYMBOL_GPL
+-0xb37a0603    drm_dp_link_train_channel_eq_delay      vmlinux EXPORT_SYMBOL
+-0x1fe912f1    netdev_alloc_frag       vmlinux EXPORT_SYMBOL
+-0x7bdee655    usbnet_get_endpoints    vmlinux EXPORT_SYMBOL_GPL
+-0x589e4569    syscon_regmap_lookup_by_pdevname        vmlinux EXPORT_SYMBOL_GPL
+-0x60506751    unmap_kernel_range_noflush      vmlinux EXPORT_SYMBOL_GPL
+-0x224b5740    device_remove_file      vmlinux EXPORT_SYMBOL_GPL
+-0x1b8822d8    pinctrl_gpio_direction_output   vmlinux EXPORT_SYMBOL_GPL
+-0x985e0b7d    ipv6_skip_exthdr        vmlinux EXPORT_SYMBOL
+-0xa0e33feb    ip_options_compile      vmlinux EXPORT_SYMBOL
+-0x289c3714    nf_ct_alloc_hashtable   vmlinux EXPORT_SYMBOL_GPL
+-0xc33e401a    sock_diag_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0xba86c38e    aio_complete    vmlinux EXPORT_SYMBOL
+-0x03bd889d    param_get_ulong vmlinux EXPORT_SYMBOL
+-0xa4ca666e    kill_pid        vmlinux EXPORT_SYMBOL
+-0xe56cb560    rt6_lookup      vmlinux EXPORT_SYMBOL
+-0xc8fb75a8    unix_outq_len   vmlinux EXPORT_SYMBOL_GPL
+-0xd5c5ff75    inet_frags_init_net     vmlinux EXPORT_SYMBOL
+-0x64999478    congestion_wait vmlinux EXPORT_SYMBOL
+-0x59eae699    ring_buffer_read_prepare        vmlinux EXPORT_SYMBOL_GPL
+-0xa23061f8    mmc_read_bkops_status   vmlinux EXPORT_SYMBOL
+-0xa1c46bd3    spi_bitbang_cleanup     vmlinux EXPORT_SYMBOL_GPL
+-0x4d126acf    device_store_int        vmlinux EXPORT_SYMBOL_GPL
+-0x5b546bbb    drm_gem_mmap    vmlinux EXPORT_SYMBOL
+-0xd37d6496    hci_recv_fragment       vmlinux EXPORT_SYMBOL
+-0x1c86d31e    ip_tunnel_delete_net    vmlinux EXPORT_SYMBOL_GPL
+-0x9684e8c6    blk_queue_dma_drain     vmlinux EXPORT_SYMBOL_GPL
+-0xf89e28e9    config_item_set_name    vmlinux EXPORT_SYMBOL
+-0x9d8331c0    ring_buffer_read_page   vmlinux EXPORT_SYMBOL_GPL
+-0x572d0104    _raw_write_unlock_irqrestore    vmlinux EXPORT_SYMBOL
+-0x8e7894bd    __atomic_notifier_call_chain    vmlinux EXPORT_SYMBOL_GPL
+-0xb202dbc6    i2c_del_driver  vmlinux EXPORT_SYMBOL
+-0x057ce975    hex_dump_to_buffer      vmlinux EXPORT_SYMBOL
+-0xe09f5fdd    file_ra_state_init      vmlinux EXPORT_SYMBOL_GPL
+-0x011c93d4    v4l2_m2m_reqbufs        vmlinux EXPORT_SYMBOL_GPL
+-0x5b185975    __dma_request_channel   vmlinux EXPORT_SYMBOL_GPL
+-0xe02299ef    nfc_hci_send_response   vmlinux EXPORT_SYMBOL
+-0xe8beb828    crypto_larval_kill      vmlinux EXPORT_SYMBOL_GPL
+-0x8704eb06    irq_set_default_host    vmlinux EXPORT_SYMBOL_GPL
+-0x7ac1d551    vb2_prepare_buf vmlinux EXPORT_SYMBOL_GPL
+-0xfcab3072    media_entity_cleanup    vmlinux EXPORT_SYMBOL_GPL
+-0x75d69d69    usb_alloc_coherent      vmlinux EXPORT_SYMBOL_GPL
+-0x2f3857a0    xfrm_register_mode      vmlinux EXPORT_SYMBOL
+-0x09c1fbfd    inet_csk_get_port       vmlinux EXPORT_SYMBOL_GPL
+-0x1e6fd62f    kiocb_set_cancel_fn     vmlinux EXPORT_SYMBOL
+-0xb20a8d04    mmc_flush_cache vmlinux EXPORT_SYMBOL
+-0xb321b21c    i2c_clients_command     vmlinux EXPORT_SYMBOL
+-0xd77c0bc8    klist_remove    vmlinux EXPORT_SYMBOL_GPL
+-0x8cfe5489    dev_get_flags   vmlinux EXPORT_SYMBOL
+-0x8022b19a    crypto_sha256_update    vmlinux EXPORT_SYMBOL
+-0x0adfab73    __wait_on_bit_lock      vmlinux EXPORT_SYMBOL
+-0x4a169d0b    usb_get_status  vmlinux EXPORT_SYMBOL_GPL
+-0xe5122890    flow_cache_genid        vmlinux EXPORT_SYMBOL
+-0x31cef011    gen_new_estimator       vmlinux EXPORT_SYMBOL
+-0xbb6bebbd    crypto_alg_mod_lookup   vmlinux EXPORT_SYMBOL_GPL
+-0xe208f5c9    freeze_super    vmlinux EXPORT_SYMBOL
+-0xbf5b2016    __devm_request_region   vmlinux EXPORT_SYMBOL
+-0x7cd6f042    cpufreq_get_current_driver      vmlinux EXPORT_SYMBOL_GPL
+-0x946f789a    input_class     vmlinux EXPORT_SYMBOL_GPL
+-0x33abb76e    usb_remove_function     vmlinux EXPORT_SYMBOL_GPL
+-0x54c41f03    __cfg80211_send_disassoc        vmlinux EXPORT_SYMBOL
+-0x886bcea3    hid_connect     vmlinux EXPORT_SYMBOL_GPL
+-0x1d4cf31c    mmc_set_data_timeout    vmlinux EXPORT_SYMBOL
+-0x020bb7c4    v4l2_m2m_qbuf   vmlinux EXPORT_SYMBOL_GPL
+-0xf5ef842e    v4l_bound_align_image   vmlinux EXPORT_SYMBOL_GPL
+-0x628c65bc    usb_set_device_state    vmlinux EXPORT_SYMBOL_GPL
+-0x1d182b56    scsi_autopm_get_device  vmlinux EXPORT_SYMBOL_GPL
+-0xa8b77259    scsi_autopm_put_device  vmlinux EXPORT_SYMBOL_GPL
+-0x2641488c    scsi_eh_finish_cmd      vmlinux EXPORT_SYMBOL
+-0x773650a0    vc_cons vmlinux EXPORT_SYMBOL
+-0x6d203b02    dma_async_device_unregister     vmlinux EXPORT_SYMBOL
+-0x18c2227f    cpu_rmap_update vmlinux EXPORT_SYMBOL
+-0xdd0a2ba2    strlcat vmlinux EXPORT_SYMBOL
+-0xd627480b    strncat vmlinux EXPORT_SYMBOL
+-0x0dd47f83    blk_queue_max_discard_sectors   vmlinux EXPORT_SYMBOL
+-0xb3f7646e    kthread_should_stop     vmlinux EXPORT_SYMBOL
+-0x8d335f49    mmc_can_reset   vmlinux EXPORT_SYMBOL
+-0x474576c2    v4l2_ctrl_new_std_menu  vmlinux EXPORT_SYMBOL
+-0x735d80ef    drm_add_edid_modes      vmlinux EXPORT_SYMBOL
+-0xbfdbe956    nfnetlink_set_err       vmlinux EXPORT_SYMBOL_GPL
+-0xc0891ac5    netdev_notice   vmlinux EXPORT_SYMBOL
+-0x03b5c8d0    blk_rq_map_kern vmlinux EXPORT_SYMBOL
+-0x20f6c302    sync_mapping_buffers    vmlinux EXPORT_SYMBOL
+-0x5610de90    pm_generic_freeze_noirq vmlinux EXPORT_SYMBOL_GPL
+-0x33186585    drm_prime_lookup_buf_handle     vmlinux EXPORT_SYMBOL
+-0x5c746654    bt_sock_register        vmlinux EXPORT_SYMBOL
+-0x1f2ca4fa    fat_scan        vmlinux EXPORT_SYMBOL_GPL
+-0x4ade2e74    inode_change_ok vmlinux EXPORT_SYMBOL
+-0x2b2264c1    __scsi_add_device       vmlinux EXPORT_SYMBOL
+-0x3a8903bb    datagram_poll   vmlinux EXPORT_SYMBOL
+-0x75767b6f    snd_pcm_hw_constraint_minmax    vmlinux EXPORT_SYMBOL
+-0xe623e6db    blk_queue_end_tag       vmlinux EXPORT_SYMBOL
+-0x1e9edfb7    seq_hlist_start_head_rcu        vmlinux EXPORT_SYMBOL
+-0x69d38ed9    __scsi_print_sense      vmlinux EXPORT_SYMBOL
+-0xc6de7303    __tty_alloc_driver      vmlinux EXPORT_SYMBOL
+-0xcdb5f930    __tcf_em_tree_match     vmlinux EXPORT_SYMBOL
+-0x7a0a2470    dev_uc_flush    vmlinux EXPORT_SYMBOL
+-0x6c8f0d30    dev_mc_flush    vmlinux EXPORT_SYMBOL
+-0x067d8d35    security_release_secctx vmlinux EXPORT_SYMBOL
+-0xb10e668e    jbd2_journal_check_available_features   vmlinux EXPORT_SYMBOL
+-0xe2e8ac87    flush_old_exec  vmlinux EXPORT_SYMBOL
+-0x00c4dc87    timecounter_init        vmlinux EXPORT_SYMBOL_GPL
+-0xeb793d66    media_device_register   vmlinux EXPORT_SYMBOL_GPL
+-0x694be42a    usb_show_dynids vmlinux EXPORT_SYMBOL_GPL
+-0xdf3ec432    drm_gem_object_alloc    vmlinux EXPORT_SYMBOL
+-0xa3d3ab7e    inet_addr_type  vmlinux EXPORT_SYMBOL
+-0x97a2e370    inet_recvmsg    vmlinux EXPORT_SYMBOL
+-0x0b59390b    __tracepoint_rpm_suspend        vmlinux EXPORT_SYMBOL_GPL
+-0xa4701e9e    timekeeping_inject_offset       vmlinux EXPORT_SYMBOL
+-0x1f54f1b4    do_trace_rcu_torture_read       vmlinux EXPORT_SYMBOL_GPL
+-0x6275fa23    mdiobus_unregister      vmlinux EXPORT_SYMBOL
+-0x639399b9    ump_dd_phys_block_count_get     vmlinux EXPORT_SYMBOL
+-0x6812cf8d    __tracepoint_rpm_idle   vmlinux EXPORT_SYMBOL_GPL
+-0xaa90f5bc    phy_detach      vmlinux EXPORT_SYMBOL
+-0x8ded75c5    mii_link_ok     vmlinux EXPORT_SYMBOL
+-0xa6dd4938    cfg80211_inform_bss_frame       vmlinux EXPORT_SYMBOL
+-0xd4cc3c98    bt_procfs_cleanup       vmlinux EXPORT_SYMBOL
+-0xd856b532    tcp_proc_register       vmlinux EXPORT_SYMBOL
+-0xb86a648c    nf_conntrack_l4proto_udp6       vmlinux EXPORT_SYMBOL_GPL
+-0x2c81ec75    __irq_regs      vmlinux EXPORT_SYMBOL
+-0x3f182756    generic_write_sync      vmlinux EXPORT_SYMBOL
+-0x48bd4a65    wakeup_source_remove    vmlinux EXPORT_SYMBOL_GPL
+-0x027c2c52    stop_tty        vmlinux EXPORT_SYMBOL
+-0xc18578ed    process_srcu    vmlinux EXPORT_SYMBOL_GPL
+-0xf3cf07b0    sdio_writel     vmlinux EXPORT_SYMBOL_GPL
+-0x9b54326d    xfrm_policy_destroy     vmlinux EXPORT_SYMBOL
+-0x667cc3f3    inet_del_offload        vmlinux EXPORT_SYMBOL
+-0xbc9cfb6e    jbd2_journal_stop       vmlinux EXPORT_SYMBOL
+-0x43aec82a    sdhci_pltfm_register    vmlinux EXPORT_SYMBOL_GPL
+-0x1db8867b    sdio_memcpy_toio        vmlinux EXPORT_SYMBOL_GPL
+-0x48499aa5    neigh_ifdown    vmlinux EXPORT_SYMBOL
+-0x4b53ee2c    snd_pcm_hw_constraint_ratnums   vmlinux EXPORT_SYMBOL
+-0x9650df0b    snd_ctl_replace vmlinux EXPORT_SYMBOL
+-0x6c1ce5ce    strcspn vmlinux EXPORT_SYMBOL
+-0xa68698f6    jbd2_journal_extend     vmlinux EXPORT_SYMBOL
+-0x7eb6d1eb    thermal_zone_unbind_cooling_device      vmlinux EXPORT_SYMBOL_GPL
+-0x81328587    blkdev_aio_write        vmlinux EXPORT_SYMBOL_GPL
+-0xf8bec8e3    seq_bitmap_list vmlinux EXPORT_SYMBOL
+-0xaec655c7    alloc_pages_exact       vmlinux EXPORT_SYMBOL
+-0x6ce5ade9    hid_parse_report        vmlinux EXPORT_SYMBOL_GPL
+-0x66f7b07e    ehci_resume     vmlinux EXPORT_SYMBOL_GPL
+-0x95c578a0    ioremap_page_range      vmlinux EXPORT_SYMBOL_GPL
+-0x498dcb5e    drm_ut_debug_printk     vmlinux EXPORT_SYMBOL
+-0x6c1f6c7e    drm_rmmap       vmlinux EXPORT_SYMBOL
+-0x8b55de97    devm_regulator_bulk_get vmlinux EXPORT_SYMBOL_GPL
+-0x8190aef3    register_sound_special  vmlinux EXPORT_SYMBOL
+-0x6c255d20    __nla_reserve   vmlinux EXPORT_SYMBOL
+-0x29537c9e    alloc_chrdev_region     vmlinux EXPORT_SYMBOL
+-0x05273827    inc_zone_page_state     vmlinux EXPORT_SYMBOL
+-0xc665d6d7    of_parse_phandle_with_args      vmlinux EXPORT_SYMBOL
+-0x01f7b595    usbnet_skb_return       vmlinux EXPORT_SYMBOL_GPL
+-0x0740687f    arp_find        vmlinux EXPORT_SYMBOL
+-0x269fbd1b    nf_ct_iterate_cleanup   vmlinux EXPORT_SYMBOL_GPL
+-0x22ce6bb8    skb_checksum    vmlinux EXPORT_SYMBOL
+-0x669f1bc1    kfree_skb_list  vmlinux EXPORT_SYMBOL
+-0xca9360b5    rb_next vmlinux EXPORT_SYMBOL
+-0x3c010e48    inode_permission        vmlinux EXPORT_SYMBOL
+-0xba34ed58    buffer_migrate_page     vmlinux EXPORT_SYMBOL
+-0x1cfb04fa    finish_wait     vmlinux EXPORT_SYMBOL
+-0xcb0b79fb    max8997_read_reg        vmlinux EXPORT_SYMBOL_GPL
+-0x564f1dca    klist_add_after vmlinux EXPORT_SYMBOL_GPL
+-0x4cbbd171    __bitmap_weight vmlinux EXPORT_SYMBOL
+-0x61b7b126    simple_strtoull vmlinux EXPORT_SYMBOL
+-0x528c709d    simple_read_from_buffer vmlinux EXPORT_SYMBOL
+-0x10c9d678    irq_domain_simple_ops   vmlinux EXPORT_SYMBOL_GPL
+-0x5d8d802b    clockevent_delta2ns     vmlinux EXPORT_SYMBOL_GPL
+-0xe8731295    gether_get_ifname       vmlinux EXPORT_SYMBOL
+-0x8619c1c9    phy_start_aneg  vmlinux EXPORT_SYMBOL
+-0x2a1c0adc    scsi_print_result       vmlinux EXPORT_SYMBOL
+-0x6eb85693    nf_defrag_ipv6_enable   vmlinux EXPORT_SYMBOL_GPL
+-0x6b6c3d10    nf_defrag_ipv4_enable   vmlinux EXPORT_SYMBOL_GPL
+-0xa681fe88    generate_random_uuid    vmlinux EXPORT_SYMBOL
+-0x3147857d    default_red     vmlinux EXPORT_SYMBOL
+-0xff9ca065    fb_edid_to_monspecs     vmlinux EXPORT_SYMBOL
+-0x22e14acd    gpiochip_add_pin_range  vmlinux EXPORT_SYMBOL_GPL
+-0xad1bb027    nf_ct_free_hashtable    vmlinux EXPORT_SYMBOL_GPL
+-0xaf509095    get_net_ns_by_pid       vmlinux EXPORT_SYMBOL_GPL
+-0xcff75292    vfs_statfs      vmlinux EXPORT_SYMBOL
+-0x2756ceb6    mmc_power_save_host     vmlinux EXPORT_SYMBOL
+-0x438610bd    security_tun_dev_alloc_security vmlinux EXPORT_SYMBOL
+-0xb1d9068c    ip6_datagram_send_ctl   vmlinux EXPORT_SYMBOL_GPL
+-0x365c213d    udp_ioctl       vmlinux EXPORT_SYMBOL
+-0x53877b9f    __nla_reserve_nohdr     vmlinux EXPORT_SYMBOL
+-0xd64146c4    __get_page_tail vmlinux EXPORT_SYMBOL
+-0x9b1bc5fa    i2c_new_probed_device   vmlinux EXPORT_SYMBOL_GPL
+-0x3c787bd5    rtnetlink_put_metrics   vmlinux EXPORT_SYMBOL
+-0xcb5c97f9    blk_queue_max_write_same_sectors        vmlinux EXPORT_SYMBOL
+-0x3b909e7e    may_umount      vmlinux EXPORT_SYMBOL
+-0x0c8099b1    v4l2_spi_new_subdev     vmlinux EXPORT_SYMBOL_GPL
+-0xd00b0085    v4l2_ctrl_handler_setup vmlinux EXPORT_SYMBOL
+-0xea10212a    int_to_scsilun  vmlinux EXPORT_SYMBOL
+-0xcb0944d8    pwm_set_chip_data       vmlinux EXPORT_SYMBOL_GPL
+-0xde5846c4    pwm_get_chip_data       vmlinux EXPORT_SYMBOL_GPL
+-0x915917a3    block_read_full_page    vmlinux EXPORT_SYMBOL
+-0xe5d61b91    console_drivers vmlinux EXPORT_SYMBOL_GPL
+-0xb776298b    iommu_detach_device     vmlinux EXPORT_SYMBOL_GPL
+-0xeb711ae7    snd_soc_params_to_bclk  vmlinux EXPORT_SYMBOL_GPL
+-0x90ed601f    mmc_hw_reset    vmlinux EXPORT_SYMBOL
+-0x1cbd340b    cdc_ncm_unbind  vmlinux EXPORT_SYMBOL_GPL
+-0x9caab5b6    __scsi_alloc_queue      vmlinux EXPORT_SYMBOL
+-0x2506e85a    bus_sort_breadthfirst   vmlinux EXPORT_SYMBOL_GPL
+-0xd6769f27    ipt_alloc_initial_table vmlinux EXPORT_SYMBOL_GPL
+-0x439fe23e    tcp_v4_connect  vmlinux EXPORT_SYMBOL
+-0x02de3eaf    tcp_sync_mss    vmlinux EXPORT_SYMBOL
+-0x4be85a03    memweight       vmlinux EXPORT_SYMBOL
+-0x93021b18    jbd2_journal_ack_err    vmlinux EXPORT_SYMBOL
+-0xd0c05159    emergency_restart       vmlinux EXPORT_SYMBOL_GPL
+-0x3ff62317    local_bh_disable        vmlinux EXPORT_SYMBOL
+-0xd88781bd    regmap_raw_write        vmlinux EXPORT_SYMBOL_GPL
+-0xada38534    regulator_bulk_disable  vmlinux EXPORT_SYMBOL_GPL
+-0x2ad4daf6    tcp_death_row   vmlinux EXPORT_SYMBOL_GPL
+-0x87751cba    netdev_upper_dev_link   vmlinux EXPORT_SYMBOL
+-0xe187693c    kstrtouint_from_user    vmlinux EXPORT_SYMBOL
+-0xbe797e8f    bio_get_nr_vecs vmlinux EXPORT_SYMBOL
+-0x2373352a    clk_fixed_factor_ops    vmlinux EXPORT_SYMBOL_GPL
+-0xccbee9bd    mmc_set_blockcount      vmlinux EXPORT_SYMBOL
+-0x9ebb3718    v4l2_clk_unregister     vmlinux EXPORT_SYMBOL
+-0xe28ade94    serio_rescan    vmlinux EXPORT_SYMBOL
+-0x1b5c713f    drm_send_vblank_event   vmlinux EXPORT_SYMBOL
+-0xa257d9cd    framebuffer_alloc       vmlinux EXPORT_SYMBOL
+-0x0916cc54    xfrm_policy_byid        vmlinux EXPORT_SYMBOL
+-0x07319ef1    ahash_register_instance vmlinux EXPORT_SYMBOL_GPL
+-0x11c55999    load_nls_default        vmlinux EXPORT_SYMBOL
+-0xcae08d66    nonseekable_open        vmlinux EXPORT_SYMBOL
+-0x3651150d    kmem_cache_create       vmlinux EXPORT_SYMBOL
+-0xfd26424e    cpufreq_driver_target   vmlinux EXPORT_SYMBOL_GPL
+-0x66adff69    vb2_fop_read    vmlinux EXPORT_SYMBOL_GPL
+-0x09a5b743    amba_apb_device_add     vmlinux EXPORT_SYMBOL_GPL
+-0x475100c2    inet_get_local_port_range       vmlinux EXPORT_SYMBOL
+-0x8c1e0ffe    __seq_open_private      vmlinux EXPORT_SYMBOL
+-0xd60c8ab0    seq_escape      vmlinux EXPORT_SYMBOL
+-0xc81ec7cb    phy_get_eee_err vmlinux EXPORT_SYMBOL
+-0x00778770    xfrm_ealg_get_byname    vmlinux EXPORT_SYMBOL_GPL
+-0x5bc722fb    sock_alloc_file vmlinux EXPORT_SYMBOL
+-0xddf821b8    page_address    vmlinux EXPORT_SYMBOL
+-0x9771ccf0    of_mdiobus_register     vmlinux EXPORT_SYMBOL
+-0x5eb24829    dm_shift_arg    vmlinux EXPORT_SYMBOL
+-0x119e8920    v4l2_async_unregister_subdev    vmlinux EXPORT_SYMBOL
+-0x7bc3e7c1    xfrm_lookup     vmlinux EXPORT_SYMBOL
+-0xae0410db    skb_store_bits  vmlinux EXPORT_SYMBOL
+-0xf86deaaa    page_cache_sync_readahead       vmlinux EXPORT_SYMBOL_GPL
+-0x7681946c    unregister_pm_notifier  vmlinux EXPORT_SYMBOL_GPL
+-0x3d98d961    inet_unregister_protosw vmlinux EXPORT_SYMBOL
+-0x82108639    snd_soc_get_volsw       vmlinux EXPORT_SYMBOL_GPL
+-0x286d040c    snd_soc_put_volsw       vmlinux EXPORT_SYMBOL_GPL
+-0x371c0db7    blk_queue_bypass_end    vmlinux EXPORT_SYMBOL_GPL
+-0x8589f760    mb_cache_entry_free     vmlinux EXPORT_SYMBOL
+-0x87a795d4    i2c_probe_func_quick_read       vmlinux EXPORT_SYMBOL_GPL
+-0xb05661a7    i2c_smbus_read_byte     vmlinux EXPORT_SYMBOL
+-0x167977e6    platform_create_bundle  vmlinux EXPORT_SYMBOL_GPL
+-0xb626c977    _dev_info       vmlinux EXPORT_SYMBOL
+-0x0d5db696    arm_iommu_detach_device vmlinux EXPORT_SYMBOL_GPL
+-0x001f6379    blkcipher_walk_phys     vmlinux EXPORT_SYMBOL_GPL
+-0x3dfc897c    seq_hlist_start_head    vmlinux EXPORT_SYMBOL
+-0xc34ff0bb    clocksource_change_rating       vmlinux EXPORT_SYMBOL
+-0x5ace7e88    devres_for_each_res     vmlinux EXPORT_SYMBOL_GPL
+-0xd4390384    __ieee80211_get_channel vmlinux EXPORT_SYMBOL
+-0xe55e04a1    ip6_tnl_rcv_ctl vmlinux EXPORT_SYMBOL_GPL
+-0xa389a49a    profile_event_register  vmlinux EXPORT_SYMBOL_GPL
+-0x5ef37944    sdio_set_block_size     vmlinux EXPORT_SYMBOL_GPL
+-0x9924c496    __usb_get_extra_descriptor      vmlinux EXPORT_SYMBOL_GPL
+-0xcfa57ce1    __nf_conntrack_helper_find      vmlinux EXPORT_SYMBOL_GPL
+-0x5460c8d8    fsnotify_get_cookie     vmlinux EXPORT_SYMBOL_GPL
+-0xf5f58a7b    gether_register_netdev  vmlinux EXPORT_SYMBOL
+-0xe774e9e4    register_netdevice      vmlinux EXPORT_SYMBOL
+-0x9209f545    blkdev_put      vmlinux EXPORT_SYMBOL
+-0x6a1c9c55    blkdev_get      vmlinux EXPORT_SYMBOL
+-0x4d0cbb95    finish_no_open  vmlinux EXPORT_SYMBOL
+-0xa1ef69b9    unregister_ftrace_event vmlinux EXPORT_SYMBOL_GPL
+-0x09d6a08d    v4l2_device_disconnect  vmlinux EXPORT_SYMBOL_GPL
+-0x613a7741    scsi_finish_command     vmlinux EXPORT_SYMBOL
+-0x11f447ce    __gpio_to_irq   vmlinux EXPORT_SYMBOL_GPL
+-0xb8a9ab06    hci_unregister_cb       vmlinux EXPORT_SYMBOL
+-0xca0741ee    nf_nat_l4proto_register vmlinux EXPORT_SYMBOL_GPL
+-0x70f09a3d    nf_nat_l3proto_register vmlinux EXPORT_SYMBOL_GPL
+-0x10447797    build_skb       vmlinux EXPORT_SYMBOL
+-0xf2b1ac8e    __getnstimeofday        vmlinux EXPORT_SYMBOL
+-0x8923ab21    get_tz_trend    vmlinux EXPORT_SYMBOL
+-0x450e1fb7    gs_alloc_req    vmlinux EXPORT_SYMBOL_GPL
+-0x176df204    tcp_get_info    vmlinux EXPORT_SYMBOL_GPL
+-0x4c2a5480    __alloc_skb     vmlinux EXPORT_SYMBOL
+-0x90814050    snd_soc_cache_write     vmlinux EXPORT_SYMBOL_GPL
+-0xa4ba4393    snd_soc_dai_set_fmt     vmlinux EXPORT_SYMBOL_GPL
+-0x2d98d3e7    jbd2_journal_begin_ordered_truncate     vmlinux EXPORT_SYMBOL
+-0x5b79185b    jbd2_trans_will_send_data_barrier       vmlinux EXPORT_SYMBOL
+-0xc200914d    mutex_trylock   vmlinux EXPORT_SYMBOL
+-0xe24d3a97    jiffies_64      vmlinux EXPORT_SYMBOL
+-0x7eb7b3f8    of_get_dma_window       vmlinux EXPORT_SYMBOL_GPL
+-0xc5c9bb41    regmap_get_val_bytes    vmlinux EXPORT_SYMBOL_GPL
+-0x8226642f    __gpio_cansleep vmlinux EXPORT_SYMBOL_GPL
+-0x6def2db2    half_md4_transform      vmlinux EXPORT_SYMBOL
+-0xb835b3e4    radix_tree_prev_hole    vmlinux EXPORT_SYMBOL
+-0xbed06655    dcache_readdir  vmlinux EXPORT_SYMBOL
+-0x980c6433    inode_add_bytes vmlinux EXPORT_SYMBOL
+-0xdc092d5b    thaw_super      vmlinux EXPORT_SYMBOL
+-0x1ef192c5    generic_file_mmap       vmlinux EXPORT_SYMBOL
+-0x9075cea3    abort_creds     vmlinux EXPORT_SYMBOL
+-0x4ef8e23f    led_set_brightness      vmlinux EXPORT_SYMBOL
+-0x48a5b067    __machine_arch_type     vmlinux EXPORT_SYMBOL
+-0x4188d439    neigh_rand_reach_time   vmlinux EXPORT_SYMBOL
+-0x7eef21b4    dev_forward_skb vmlinux EXPORT_SYMBOL_GPL
+-0x5825f0e7    sock_common_getsockopt  vmlinux EXPORT_SYMBOL
+-0x2de67218    sock_common_setsockopt  vmlinux EXPORT_SYMBOL
+-0x65408378    zlib_inflate_blob       vmlinux EXPORT_SYMBOL
+-0xc6d9568b    try_to_writeback_inodes_sb      vmlinux EXPORT_SYMBOL
+-0x5ad87de6    vfs_mknod       vmlinux EXPORT_SYMBOL
+-0x6f5c943e    rndis_add_hdr   vmlinux EXPORT_SYMBOL
+-0x6a91e934    drm_mode_create_dvi_i_properties        vmlinux EXPORT_SYMBOL
+-0x3eb37b9d    drm_ht_create   vmlinux EXPORT_SYMBOL
+-0xcdf8626d    n_tty_inherit_ops       vmlinux EXPORT_SYMBOL_GPL
+-0x65d6d0f0    gpio_direction_input    vmlinux EXPORT_SYMBOL_GPL
+-0x74acd28a    nfc_hci_set_clientdata  vmlinux EXPORT_SYMBOL
+-0x6c6a3e69    nfc_hci_get_clientdata  vmlinux EXPORT_SYMBOL
+-0x8e235e9b    cfg80211_disconnected   vmlinux EXPORT_SYMBOL
+-0x2d6b040a    cfg80211_send_rx_auth   vmlinux EXPORT_SYMBOL
+-0x987f5e85    skb_dequeue     vmlinux EXPORT_SYMBOL
+-0x413461c0    filemap_write_and_wait  vmlinux EXPORT_SYMBOL
+-0x27bbf221    disable_irq_nosync      vmlinux EXPORT_SYMBOL
+-0x00000000    softirq_work_list       vmlinux EXPORT_SYMBOL
+-0x8c298b56    vb2_ioctl_querybuf      vmlinux EXPORT_SYMBOL_GPL
+-0x94d7075a    usb_gadget_get_string   vmlinux EXPORT_SYMBOL_GPL
+-0x19ef30a6    usbnet_manage_power     vmlinux EXPORT_SYMBOL
+-0x967e7ec8    inet_rtx_syn_ack        vmlinux EXPORT_SYMBOL
+-0x9b9e05f9    alloc_cpu_rmap  vmlinux EXPORT_SYMBOL
+-0xa7f92105    add_uevent_var  vmlinux EXPORT_SYMBOL_GPL
+-0x6e6c5939    dma_buf_kunmap_atomic   vmlinux EXPORT_SYMBOL_GPL
+-0x3723eb08    __pm_relax      vmlinux EXPORT_SYMBOL_GPL
+-0x1ae74b3a    drm_framebuffer_unregister_private      vmlinux EXPORT_SYMBOL
+-0xf7584a9c    find_font       vmlinux EXPORT_SYMBOL
+-0x88e316d7    netdev_features_change  vmlinux EXPORT_SYMBOL
+-0xf19e9355    cpu_online_mask vmlinux EXPORT_SYMBOL
+-0xaa8195e9    media_entity_remote_pad vmlinux EXPORT_SYMBOL_GPL
+-0x19ec698c    platform_get_resource_byname    vmlinux EXPORT_SYMBOL_GPL
+-0x62813e5c    nf_ct_port_nlattr_tuple_size    vmlinux EXPORT_SYMBOL_GPL
+-0x4ff4a58a    nfnetlink_alloc_skb     vmlinux EXPORT_SYMBOL_GPL
+-0xeed3635b    proc_dostring   vmlinux EXPORT_SYMBOL
+-0xb54533f7    usecs_to_jiffies        vmlinux EXPORT_SYMBOL
+-0x0b56117f    of_find_node_by_path    vmlinux EXPORT_SYMBOL
+-0xcc4b84da    of_find_node_by_type    vmlinux EXPORT_SYMBOL
+-0xf9fd4da3    phy_start       vmlinux EXPORT_SYMBOL
+-0x5ea42ad5    devres_find     vmlinux EXPORT_SYMBOL_GPL
+-0x598a2261    drm_mode_probed_add     vmlinux EXPORT_SYMBOL
+-0xc35b2a18    xt_hook_link    vmlinux EXPORT_SYMBOL_GPL
+-0xc1c24fbc    genlmsg_put     vmlinux EXPORT_SYMBOL
+-0xf177aba7    sysfs_schedule_callback vmlinux EXPORT_SYMBOL_GPL
+-0xabcaa577    free_anon_bdev  vmlinux EXPORT_SYMBOL
+-0x6d289788    pwm_set_polarity        vmlinux EXPORT_SYMBOL_GPL
+-0x2546de76    raw_hash_sk     vmlinux EXPORT_SYMBOL_GPL
+-0xa2ef34d7    rps_sock_flow_table     vmlinux EXPORT_SYMBOL
+-0x3730910b    skb_insert      vmlinux EXPORT_SYMBOL
+-0xb8b7395a    snd_compress_new        vmlinux EXPORT_SYMBOL_GPL
+-0x1c132024    request_any_context_irq vmlinux EXPORT_SYMBOL_GPL
+-0x5aba52ab    iio_trigger_poll        vmlinux EXPORT_SYMBOL
+-0xe9b6f3f3    dev_emerg       vmlinux EXPORT_SYMBOL
+-0xfacd2e14    pgprot_user     vmlinux EXPORT_SYMBOL
+-0x0a0786de    udplite_table   vmlinux EXPORT_SYMBOL
+-0xd9bbcf52    tc_classify_compat      vmlinux EXPORT_SYMBOL
+-0x72f15b74    blk_queue_max_segment_size      vmlinux EXPORT_SYMBOL
+-0x544aab61    klist_add_tail  vmlinux EXPORT_SYMBOL_GPL
+-0x490434ad    dev_kfree_skb_irq       vmlinux EXPORT_SYMBOL
+-0xdb3a9b04    jbd2_journal_file_inode vmlinux EXPORT_SYMBOL
+-0x6e9dd606    __symbol_put    vmlinux EXPORT_SYMBOL
+-0x40a2d1dd    dm_table_get_size       vmlinux EXPORT_SYMBOL
+-0xceee316a    gether_set_host_addr    vmlinux EXPORT_SYMBOL
+-0x32f81723    gether_get_host_addr    vmlinux EXPORT_SYMBOL
+-0xae387af1    usb_gadget_unmap_request        vmlinux EXPORT_SYMBOL_GPL
+-0x8dfb019d    drm_buffer_free vmlinux EXPORT_SYMBOL
+-0x600683d3    do_unblank_screen       vmlinux EXPORT_SYMBOL
+-0xc1ebf6fe    get_kernel_page vmlinux EXPORT_SYMBOL_GPL
+-0x9b388444    get_zeroed_page vmlinux EXPORT_SYMBOL
+-0x53b69429    vb2_streamon    vmlinux EXPORT_SYMBOL_GPL
+-0x211aedde    genphy_restart_aneg     vmlinux EXPORT_SYMBOL
+-0xebdba37a    ndo_dflt_fdb_dump       vmlinux EXPORT_SYMBOL
+-0x604ef7b4    snd_pcm_lib_read        vmlinux EXPORT_SYMBOL
+-0x60541cbf    st_sensors_set_odr      vmlinux EXPORT_SYMBOL
+-0xe53d1faa    of_translate_dma_address        vmlinux EXPORT_SYMBOL
+-0xaf05b91b    of_device_is_available  vmlinux EXPORT_SYMBOL
+-0x1a426d0c    input_close_device      vmlinux EXPORT_SYMBOL
+-0xe720411b    rtnl_create_link        vmlinux EXPORT_SYMBOL
+-0x650f8603    snd_pcm_format_silence_64       vmlinux EXPORT_SYMBOL
+-0x7164c04b    address_space_init_once vmlinux EXPORT_SYMBOL
+-0xfda0dbe8    ftrace_print_hex_seq    vmlinux EXPORT_SYMBOL
+-0x2c988955    prepare_to_wait_exclusive       vmlinux EXPORT_SYMBOL
+-0x9c3206d8    v4l2_device_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0xd5c2bed3    phy_connect_direct      vmlinux EXPORT_SYMBOL
+-0xed2b0677    drm_mode_connector_update_edid_property vmlinux EXPORT_SYMBOL
+-0xbf17b32e    tty_insert_flip_string_flags    vmlinux EXPORT_SYMBOL
+-0xadc9ed27    bt_sock_ioctl   vmlinux EXPORT_SYMBOL
+-0x33ea8640    inet_dev_addr_type      vmlinux EXPORT_SYMBOL
+-0xd265ad57    tcf_action_exec vmlinux EXPORT_SYMBOL
+-0xec8d9205    snd_soc_register_codec  vmlinux EXPORT_SYMBOL_GPL
+-0x5e8ff943    debugfs_create_size_t   vmlinux EXPORT_SYMBOL_GPL
+-0x5b968338    remove_proc_entry       vmlinux EXPORT_SYMBOL
+-0x4717eaaf    platform_device_add     vmlinux EXPORT_SYMBOL_GPL
+-0x44a0c113    drm_mode_height vmlinux EXPORT_SYMBOL
+-0xe219d715    ipv6_opt_accepted       vmlinux EXPORT_SYMBOL_GPL
+-0x503ed988    xfrm_spd_getinfo        vmlinux EXPORT_SYMBOL
+-0x1fd1fabe    arpt_register_table     vmlinux EXPORT_SYMBOL
+-0xf9ed2e31    block_is_partially_uptodate     vmlinux EXPORT_SYMBOL
+-0xd9ecb670    ring_buffer_overruns    vmlinux EXPORT_SYMBOL_GPL
+-0x5e911cf3    exynos_g2d_exec_ioctl   vmlinux EXPORT_SYMBOL_GPL
+-0xbf69cda1    drm_connector_unplug_all        vmlinux EXPORT_SYMBOL
+-0xafe3eb1b    alloc_etherdev_mqs      vmlinux EXPORT_SYMBOL
+-0x39bf9301    _snd_pcm_hw_param_setempty      vmlinux EXPORT_SYMBOL
+-0xd81836ce    uart_resume_port        vmlinux EXPORT_SYMBOL
+-0x46931864    nfc_tm_data_received    vmlinux EXPORT_SYMBOL
+-0xfac8865f    sysctl_wmem_max vmlinux EXPORT_SYMBOL
+-0xb05fc310    sysctl_rmem_max vmlinux EXPORT_SYMBOL
+-0xe9b673fa    dapm_mark_io_dirty      vmlinux EXPORT_SYMBOL_GPL
+-0xbf0046d7    ahash_free_instance     vmlinux EXPORT_SYMBOL_GPL
+-0x825a0923    jbd2_journal_errno      vmlinux EXPORT_SYMBOL
+-0x03cb2c1a    bdi_register_dev        vmlinux EXPORT_SYMBOL
+-0x018f7433    pm_relax        vmlinux EXPORT_SYMBOL_GPL
+-0x63e0cc67    pagecache_write_end     vmlinux EXPORT_SYMBOL
+-0x8a04b9fe    tracepoint_iter_reset   vmlinux EXPORT_SYMBOL_GPL
+-0x5cf53ce2    input_free_minor        vmlinux EXPORT_SYMBOL
+-0x17bfef6c    drm_clflush_pages       vmlinux EXPORT_SYMBOL
+-0x5f14861d    pwm_get vmlinux EXPORT_SYMBOL_GPL
+-0xb8a5d4ee    cfg80211_ft_event       vmlinux EXPORT_SYMBOL
+-0xb9da2997    snmp_fold_field64       vmlinux EXPORT_SYMBOL_GPL
+-0x87925ca6    kstrtoint_from_user     vmlinux EXPORT_SYMBOL
+-0x6e891ea0    clk_unprepare   vmlinux EXPORT_SYMBOL_GPL
+-0x3d41904f    of_get_next_child       vmlinux EXPORT_SYMBOL
+-0x687835e7    hidinput_get_led_field  vmlinux EXPORT_SYMBOL_GPL
+-0x36859243    hid_resolv_usage        vmlinux EXPORT_SYMBOL_GPL
+-0x995dedd6    sdio_f0_readb   vmlinux EXPORT_SYMBOL_GPL
+-0x19f5809b    dm_ratelimit_state      vmlinux EXPORT_SYMBOL
+-0xe684f045    v4l2_subdev_try_ext_ctrls       vmlinux EXPORT_SYMBOL
+-0x41f62b69    spi_register_master     vmlinux EXPORT_SYMBOL_GPL
+-0x49428bcb    drm_read        vmlinux EXPORT_SYMBOL
+-0xb12cbacb    fb_unregister_client    vmlinux EXPORT_SYMBOL
+-0x7c53b814    xfrm_inner_extract_output       vmlinux EXPORT_SYMBOL_GPL
+-0x86dd59c8    inet_csk_init_xmit_timers       vmlinux EXPORT_SYMBOL
+-0x51e297e3    __nf_ct_l4proto_find    vmlinux EXPORT_SYMBOL_GPL
+-0x1b52db1c    probe_kernel_read       vmlinux EXPORT_SYMBOL_GPL
+-0xd4e65e28    irq_set_chip_and_handler_name   vmlinux EXPORT_SYMBOL_GPL
+-0x9c7a3b79    drm_fb_helper_debug_enter       vmlinux EXPORT_SYMBOL
+-0xc25d1133    vfs_readlink    vmlinux EXPORT_SYMBOL
+-0x7e9efe8e    complete_and_exit       vmlinux EXPORT_SYMBOL
+-0xd8d64478    v4l2_ctrl_new_std_menu_items    vmlinux EXPORT_SYMBOL
+-0xb6652875    gserial_free_line       vmlinux EXPORT_SYMBOL_GPL
+-0xd4adf602    dev_pm_get_subsys_data  vmlinux EXPORT_SYMBOL_GPL
+-0x1f335345    dev_pm_put_subsys_data  vmlinux EXPORT_SYMBOL_GPL
+-0x30399f8a    transport_add_device    vmlinux EXPORT_SYMBOL_GPL
+-0x44c2d1be    drm_mode_prune_invalid  vmlinux EXPORT_SYMBOL
+-0x3e9d6f44    cfg80211_unregister_wdev        vmlinux EXPORT_SYMBOL
+-0xfb5bb3ee    inet6_lookup    vmlinux EXPORT_SYMBOL_GPL
+-0x535cfa1f    sysfs_remove_group      vmlinux EXPORT_SYMBOL_GPL
+-0x795b1ab0    sysfs_remove_file_from_group    vmlinux EXPORT_SYMBOL_GPL
+-0x9aca444b    get_monotonic_boottime  vmlinux EXPORT_SYMBOL_GPL
+-0x91aec064    down_read_trylock       vmlinux EXPORT_SYMBOL
+-0x87e148ee    v4l2_m2m_poll   vmlinux EXPORT_SYMBOL_GPL
+-0xfcb34391    scsi_execute_req_flags  vmlinux EXPORT_SYMBOL
+-0x19391863    regmap_reinit_cache     vmlinux EXPORT_SYMBOL_GPL
+-0xff6878cf    fb_default_cmap vmlinux EXPORT_SYMBOL
+-0x38524c14    cpufreq_register_driver vmlinux EXPORT_SYMBOL_GPL
+-0x4ca0e0e5    v4l2_ctrl_modify_range  vmlinux EXPORT_SYMBOL
+-0x4f6f28fb    serial8250_handle_irq   vmlinux EXPORT_SYMBOL_GPL
+-0x7b56a1b0    nf_nat_set_seq_adjust   vmlinux EXPORT_SYMBOL_GPL
+-0x63df94bc    nf_nat_tcp_seq_adjust   vmlinux EXPORT_SYMBOL_GPL
+-0x8ffb22a4    nf_setsockopt   vmlinux EXPORT_SYMBOL
+-0xefd0fb67    nf_getsockopt   vmlinux EXPORT_SYMBOL
+-0x579e0bf5    rtnl_unregister_all     vmlinux EXPORT_SYMBOL_GPL
+-0x87e5d976    netif_rx_ni     vmlinux EXPORT_SYMBOL
+-0xe27cea7b    alloc_disk      vmlinux EXPORT_SYMBOL
+-0x1f867001    blk_rq_map_user_iov     vmlinux EXPORT_SYMBOL
+-0xa3829135    ioc_lookup_icq  vmlinux EXPORT_SYMBOL
+-0xd2ce469a    seq_puts        vmlinux EXPORT_SYMBOL
+-0xf29942b3    seq_putc        vmlinux EXPORT_SYMBOL
+-0xf268be24    dw_mci_remove   vmlinux EXPORT_SYMBOL
+-0xb7ef4006    i2c_smbus_xfer  vmlinux EXPORT_SYMBOL
+-0xb8a16d46    dev_pm_qos_remove_notifier      vmlinux EXPORT_SYMBOL_GPL
+-0x37afc4f0    device_attach   vmlinux EXPORT_SYMBOL_GPL
+-0x581e8240    tty_port_open   vmlinux EXPORT_SYMBOL
+-0xa4583858    snd_pcm_hw_param_last   vmlinux EXPORT_SYMBOL
+-0x43497fcc    part_round_stats        vmlinux EXPORT_SYMBOL_GPL
+-0x0cd23659    d_genocide      vmlinux EXPORT_SYMBOL
+-0x328995b5    tracing_generic_entry_update    vmlinux EXPORT_SYMBOL_GPL
+-0xfe24d1c7    __module_put_and_exit   vmlinux EXPORT_SYMBOL
+-0x43a53735    __alloc_workqueue_key   vmlinux EXPORT_SYMBOL_GPL
+-0x2a902f32    usb_create_shared_hcd   vmlinux EXPORT_SYMBOL_GPL
+-0xdbdbb6e7    uart_update_timeout     vmlinux EXPORT_SYMBOL
+-0xf71617c1    cfg80211_report_obss_beacon     vmlinux EXPORT_SYMBOL
+-0x3e5d6dc3    snd_soc_put_value_enum_double   vmlinux EXPORT_SYMBOL_GPL
+-0xef67a6d3    snd_soc_get_value_enum_double   vmlinux EXPORT_SYMBOL_GPL
+-0x81b69e41    snd_ctl_enum_info       vmlinux EXPORT_SYMBOL
+-0xb2b94674    __crc32c_le     vmlinux EXPORT_SYMBOL
+-0xc61cc06d    elv_dispatch_add_tail   vmlinux EXPORT_SYMBOL
+-0x85e0bce2    end_buffer_write_sync   vmlinux EXPORT_SYMBOL
+-0x3cc671ae    d_drop  vmlinux EXPORT_SYMBOL
+-0x7469f641    d_rehash        vmlinux EXPORT_SYMBOL
+-0xddcebac8    file_open_root  vmlinux EXPORT_SYMBOL
+-0x310308c3    flush_kthread_work      vmlinux EXPORT_SYMBOL_GPL
+-0x40f07981    __ashldi3       vmlinux EXPORT_SYMBOL
+-0x88e83ca7    snd_soc_dpcm_be_set_state       vmlinux EXPORT_SYMBOL_GPL
+-0x5eca39b9    snd_soc_dpcm_be_get_state       vmlinux EXPORT_SYMBOL_GPL
+-0x6b1b67d3    __bdevname      vmlinux EXPORT_SYMBOL
+-0xe4315493    vfs_write       vmlinux EXPORT_SYMBOL
+-0x99fab0b8    __mmc_claim_host        vmlinux EXPORT_SYMBOL
+-0x2c8e9ced    usb_poison_urb  vmlinux EXPORT_SYMBOL_GPL
+-0x33a8a5f0    netif_rx        vmlinux EXPORT_SYMBOL
+-0x1d54bb24    snd_pcm_hw_refine       vmlinux EXPORT_SYMBOL
+-0x955b0e2e    kthread_worker_fn       vmlinux EXPORT_SYMBOL_GPL
+-0x276ad369    dm_set_device_limits    vmlinux EXPORT_SYMBOL_GPL
+-0x9e61f179    xfrm_stateonly_find     vmlinux EXPORT_SYMBOL
+-0x972bcca5    usb_create_hcd  vmlinux EXPORT_SYMBOL_GPL
+-0x72ea7b2d    scsi_device_type        vmlinux EXPORT_SYMBOL
+-0x318cadb1    reciprocal_value        vmlinux EXPORT_SYMBOL
+-0x22f77bec    unregister_binfmt       vmlinux EXPORT_SYMBOL
+-0xafceeb25    alloc_vm_area   vmlinux EXPORT_SYMBOL_GPL
+-0xcfe980c6    make_kgid       vmlinux EXPORT_SYMBOL
+-0xb71fb74f    _raw_read_trylock       vmlinux EXPORT_SYMBOL
+-0x9dadbb88    cpufreq_boost_supported vmlinux EXPORT_SYMBOL_GPL
+-0xab9e471e    usb_autopm_get_interface_no_resume      vmlinux EXPORT_SYMBOL_GPL
+-0x42453e50    sk_reset_txq    vmlinux EXPORT_SYMBOL
+-0x05d48045    sock_no_accept  vmlinux EXPORT_SYMBOL
+-0xb511dcf5    set_groups      vmlinux EXPORT_SYMBOL
+-0x5f0abc76    pinctrl_dev_get_devname vmlinux EXPORT_SYMBOL_GPL
+-0xec25f967    klist_del       vmlinux EXPORT_SYMBOL_GPL
+-0x530ed62b    tcf_generic_walker      vmlinux EXPORT_SYMBOL
+-0xacd392a0    sock_diag_register_inet_compat  vmlinux EXPORT_SYMBOL_GPL
+-0x2509c465    dev_remove_offload      vmlinux EXPORT_SYMBOL
+-0x8ee1a28d    elevator_exit   vmlinux EXPORT_SYMBOL
+-0xcd357308    __lock_buffer   vmlinux EXPORT_SYMBOL
+-0xd85139d2    mmc_unregister_driver   vmlinux EXPORT_SYMBOL
+-0xb53559bb    brcmu_pktq_pflush       drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0xbb0ab47b    debug_locks     vmlinux EXPORT_SYMBOL_GPL
+-0x56b2a97f    ablkcipher_walk_done    vmlinux EXPORT_SYMBOL_GPL
+-0xd3630b88    ablkcipher_walk_phys    vmlinux EXPORT_SYMBOL_GPL
+-0x3116987e    aead_geniv_alloc        vmlinux EXPORT_SYMBOL_GPL
+-0x20a789ac    irq_set_chip_data       vmlinux EXPORT_SYMBOL
+-0xeda65ce1    dma_release_declared_memory     vmlinux EXPORT_SYMBOL
+-0xa984aab8    cfg80211_scan_done      vmlinux EXPORT_SYMBOL
+-0x254c40cf    inet6_csk_xmit  vmlinux EXPORT_SYMBOL_GPL
+-0xca805e0b    tcp_ioctl       vmlinux EXPORT_SYMBOL
+-0x4ebc74b2    vfs_symlink     vmlinux EXPORT_SYMBOL
+-0xefcf3143    wait_for_completion_io  vmlinux EXPORT_SYMBOL
+-0xa9efcc8b    find_vpid       vmlinux EXPORT_SYMBOL_GPL
+-0xd273b1b1    __round_jiffies_up_relative     vmlinux EXPORT_SYMBOL_GPL
+-0xb8973764    iommu_attach_group      vmlinux EXPORT_SYMBOL_GPL
+-0x5d550c4d    scsi_sd_probe_domain    vmlinux EXPORT_SYMBOL
+-0x52f9bd8e    registered_fb   vmlinux EXPORT_SYMBOL
+-0xe67d81ba    strlen_user     vmlinux EXPORT_SYMBOL
+-0x480f1913    unmap_mapping_range     vmlinux EXPORT_SYMBOL
+-0x8b618d08    overflowuid     vmlinux EXPORT_SYMBOL
+-0x7171121c    overflowgid     vmlinux EXPORT_SYMBOL
+-0xb3514b24    cfg80211_radar_event    vmlinux EXPORT_SYMBOL
+-0xf06154af    inet_select_addr        vmlinux EXPORT_SYMBOL
+-0x340854b4    dev_getbyhwaddr_rcu     vmlinux EXPORT_SYMBOL
+-0x4ce033c8    skb_flow_dissect        vmlinux EXPORT_SYMBOL
+-0x465757c3    cpu_present_mask        vmlinux EXPORT_SYMBOL
+-0xb3a37086    dma_async_tx_descriptor_init    vmlinux EXPORT_SYMBOL
+-0x955eec37    wireless_send_event     vmlinux EXPORT_SYMBOL
+-0x7954e502    ipv6_recv_error vmlinux EXPORT_SYMBOL_GPL
+-0xcebcfddd    snd_soc_get_enum_double vmlinux EXPORT_SYMBOL_GPL
+-0x1c9728c6    snd_soc_put_enum_double vmlinux EXPORT_SYMBOL_GPL
+-0xb4711532    get_task_io_context     vmlinux EXPORT_SYMBOL
+-0x6cce08e5    dcache_dir_close        vmlinux EXPORT_SYMBOL
+-0x3e884f4b    vm_get_page_prot        vmlinux EXPORT_SYMBOL
+-0x20886a16    v4l2_subdev_g_ctrl      vmlinux EXPORT_SYMBOL
+-0xd56dcf8e    v4l2_subdev_s_ctrl      vmlinux EXPORT_SYMBOL
+-0x0465a073    regmap_reg_in_ranges    vmlinux EXPORT_SYMBOL_GPL
+-0x74bc0dea    extcon_register_interest        vmlinux EXPORT_SYMBOL_GPL
+-0x59c427c5    rtc_irq_set_state       vmlinux EXPORT_SYMBOL_GPL
+-0x3302f88f    phy_driver_register     vmlinux EXPORT_SYMBOL
+-0x848dd958    scsi_dma_unmap  vmlinux EXPORT_SYMBOL
+-0xfbc74f64    __copy_from_user        vmlinux EXPORT_SYMBOL
+-0xc9bb229b    inet_put_port   vmlinux EXPORT_SYMBOL
+-0x73ac2c51    nf_conntrack_register_notifier  vmlinux EXPORT_SYMBOL_GPL
+-0xbdca8444    sock_no_connect vmlinux EXPORT_SYMBOL
+-0xe85a9fd3    cpu_cluster_pm_exit     vmlinux EXPORT_SYMBOL_GPL
+-0xcb466063    wait_for_completion_killable_timeout    vmlinux EXPORT_SYMBOL
+-0x9205953f    send_remote_softirq     vmlinux EXPORT_SYMBOL
+-0x1852156d    phy_print_status        vmlinux EXPORT_SYMBOL
+-0x486517f6    pinctrl_select_state    vmlinux EXPORT_SYMBOL_GPL
+-0xfec26b4f    skcipher_geniv_alloc    vmlinux EXPORT_SYMBOL_GPL
+-0x24094dc0    xfrm_garbage_collect    vmlinux EXPORT_SYMBOL
+-0x6e224a7a    need_conntrack  vmlinux EXPORT_SYMBOL_GPL
+-0x4a358252    __bitmap_subset vmlinux EXPORT_SYMBOL
+-0x785d8ef0    ftrace_raw_output_prep  vmlinux EXPORT_SYMBOL
+-0x697c5d0d    tracing_snapshot_alloc  vmlinux EXPORT_SYMBOL_GPL
+-0x0e6da44a    set_normalized_timespec vmlinux EXPORT_SYMBOL
+-0x789aafbd    iommu_map       vmlinux EXPORT_SYMBOL_GPL
+-0x3a5f1e17    cfg80211_chandef_valid  vmlinux EXPORT_SYMBOL
+-0xa11c9c1a    eth_type_trans  vmlinux EXPORT_SYMBOL
+-0xe0f1fc5d    debugfs_create_blob     vmlinux EXPORT_SYMBOL_GPL
+-0xd0f2dba2    mb_cache_entry_get      vmlinux EXPORT_SYMBOL
+-0x233ed03d    vm_insert_mixed vmlinux EXPORT_SYMBOL
+-0xa96bca8e    send_sig        vmlinux EXPORT_SYMBOL
+-0x97cdf185    iio_buffer_read_length  vmlinux EXPORT_SYMBOL
+-0x58d1070a    of_get_address  vmlinux EXPORT_SYMBOL
+-0x620868cc    tcp_shutdown    vmlinux EXPORT_SYMBOL
+-0x602c96f0    copy_to_user_fromio     vmlinux EXPORT_SYMBOL
+-0x6d31e93b    tracepoint_iter_next    vmlinux EXPORT_SYMBOL_GPL
+-0xe8b53ecc    down_write_trylock      vmlinux EXPORT_SYMBOL
+-0x8bfe8c57    param_set_uint  vmlinux EXPORT_SYMBOL
+-0x39422b14    usbnet_change_mtu       vmlinux EXPORT_SYMBOL_GPL
+-0x4bd9c5ed    scsi_nonblockable_ioctl vmlinux EXPORT_SYMBOL
+-0xcd319eaa    drm_vblank_count        vmlinux EXPORT_SYMBOL
+-0x58413099    ipv6_fixup_options      vmlinux EXPORT_SYMBOL_GPL
+-0xf389fe60    __hw_addr_init  vmlinux EXPORT_SYMBOL
+-0x199ed0cd    net_disable_timestamp   vmlinux EXPORT_SYMBOL
+-0x5ad8bb47    sdio_set_host_pm_flags  vmlinux EXPORT_SYMBOL_GPL
+-0xdbbdaaf8    gether_get_qmult        vmlinux EXPORT_SYMBOL
+-0x3d6846fc    gether_set_qmult        vmlinux EXPORT_SYMBOL
+-0x14b14b7a    usb_get_function        vmlinux EXPORT_SYMBOL_GPL
+-0x28fca1f1    pwmchip_add     vmlinux EXPORT_SYMBOL_GPL
+-0xfbbedefd    of_prop_next_string     vmlinux EXPORT_SYMBOL_GPL
+-0x4afe9a77    scsi_partsize   vmlinux EXPORT_SYMBOL
+-0x14f875ce    devm_regmap_init_mmio_clk       vmlinux EXPORT_SYMBOL_GPL
+-0x695aa696    __genl_register_family  vmlinux EXPORT_SYMBOL
+-0x36bd681b    groups_alloc    vmlinux EXPORT_SYMBOL
+-0x6a5b121d    of_find_device_by_node  vmlinux EXPORT_SYMBOL
+-0x0dd989e3    vb2_streamoff   vmlinux EXPORT_SYMBOL_GPL
+-0xa82de4f7    drm_pci_alloc   vmlinux EXPORT_SYMBOL
+-0xdf54a8f7    netlink_unregister_notifier     vmlinux EXPORT_SYMBOL
+-0xc4388843    dapm_regulator_event    vmlinux EXPORT_SYMBOL_GPL
+-0x7a6fa714    __dynamic_dev_dbg       vmlinux EXPORT_SYMBOL
+-0xfa4d00bd    simple_release_fs       vmlinux EXPORT_SYMBOL
+-0xf473ffaf    down    vmlinux EXPORT_SYMBOL
+-0xac6539ec    cm_notify_event vmlinux EXPORT_SYMBOL_GPL
+-0xf49484e8    blk_end_request vmlinux EXPORT_SYMBOL
+-0xb72a3fdb    drm_sysfs_connector_add vmlinux EXPORT_SYMBOL
+-0x76cf47f6    __aeabi_llsl    vmlinux EXPORT_SYMBOL
+-0x0573e568    inet_diag_dump_icsk     vmlinux EXPORT_SYMBOL_GPL
+-0xc6a360e4    skb_put vmlinux EXPORT_SYMBOL
+-0xf76b0a59    read_current_timer      vmlinux EXPORT_SYMBOL_GPL
+-0xf1d6f94c    v4l2_m2m_ioctl_reqbufs  vmlinux EXPORT_SYMBOL_GPL
+-0x5411bf06    scsi_host_put   vmlinux EXPORT_SYMBOL
+-0xbca0b4fd    nfc_hci_sak_to_protocol vmlinux EXPORT_SYMBOL
+-0x37386cac    nf_conntrack_hash_rnd   vmlinux EXPORT_SYMBOL_GPL
+-0xdb065657    nfnl_unlock     vmlinux EXPORT_SYMBOL_GPL
+-0xc5bd3b96    ethtool_op_get_ts_info  vmlinux EXPORT_SYMBOL
+-0x5f8ed047    configfs_depend_item    vmlinux EXPORT_SYMBOL
+-0x77fa6486    generic_block_fiemap    vmlinux EXPORT_SYMBOL
+-0xc7bcbc8d    add_wait_queue  vmlinux EXPORT_SYMBOL
+-0x046c1f16    param_ops_invbool       vmlinux EXPORT_SYMBOL
+-0x4fe5c427    pinctrl_put     vmlinux EXPORT_SYMBOL_GPL
+-0x547101cd    pinctrl_get     vmlinux EXPORT_SYMBOL_GPL
+-0xdcc5846a    brcmu_pktq_flush        drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x4075ad18    dev_add_pack    vmlinux EXPORT_SYMBOL
+-0x0a3131f6    strnchr vmlinux EXPORT_SYMBOL
+-0xd20bf6ba    dcookie_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0x9e2be04d    vb2_poll        vmlinux EXPORT_SYMBOL_GPL
+-0xa8f0aba7    usb_hub_clear_tt_buffer vmlinux EXPORT_SYMBOL_GPL
+-0x2698ff67    drm_helper_connector_dpms       vmlinux EXPORT_SYMBOL
+-0x48d34903    arm_dma_ops     vmlinux EXPORT_SYMBOL
+-0x9f984513    strrchr vmlinux EXPORT_SYMBOL
+-0x7afa89fc    vsnprintf       vmlinux EXPORT_SYMBOL
+-0x7fe32873    rb_replace_node vmlinux EXPORT_SYMBOL
+-0x6ff607b6    crypto_get_default_rng  vmlinux EXPORT_SYMBOL_GPL
+-0x668402aa    crypto_put_default_rng  vmlinux EXPORT_SYMBOL_GPL
+-0x850ff7d2    crypto_mod_put  vmlinux EXPORT_SYMBOL_GPL
+-0x1db21259    mount_pseudo    vmlinux EXPORT_SYMBOL
+-0x304ec72b    _raw_write_trylock      vmlinux EXPORT_SYMBOL
+-0x4205ad24    cancel_work_sync        vmlinux EXPORT_SYMBOL_GPL
+-0x99cdc86b    sysctl_tcp_reordering   vmlinux EXPORT_SYMBOL
+-0x19d94b34    nf_ct_gre_keymap_flush  vmlinux EXPORT_SYMBOL
+-0x356bcd72    nf_log_set      vmlinux EXPORT_SYMBOL
+-0xd9e69bb2    dapm_reg_event  vmlinux EXPORT_SYMBOL_GPL
+-0xb2959203    snd_pcm_hw_constraint_pow2      vmlinux EXPORT_SYMBOL
+-0x9754ec10    radix_tree_preload      vmlinux EXPORT_SYMBOL
+-0xc8cd27b8    blkdev_ioctl    vmlinux EXPORT_SYMBOL_GPL
+-0xd11c0dc1    __kernel_param_unlock   vmlinux EXPORT_SYMBOL
+-0xcda686ec    input_set_keycode       vmlinux EXPORT_SYMBOL
+-0xc69c2d23    subsys_virtual_register vmlinux EXPORT_SYMBOL_GPL
+-0x4eb8fe91    drm_gem_free_mmap_offset        vmlinux EXPORT_SYMBOL
+-0x61cdf6e6    nfc_hci_allocate_device vmlinux EXPORT_SYMBOL
+-0x2dda642f    __dynamic_netdev_dbg    vmlinux EXPORT_SYMBOL
+-0x890dc2ed    idr_alloc_cyclic        vmlinux EXPORT_SYMBOL
+-0x5cf6db68    crypto_register_instance        vmlinux EXPORT_SYMBOL_GPL
+-0x93bd657f    crypto_alloc_tfm        vmlinux EXPORT_SYMBOL_GPL
+-0x9c48a3ba    bdi_destroy     vmlinux EXPORT_SYMBOL
+-0x29047f1a    __i2c_board_lock        vmlinux EXPORT_SYMBOL_GPL
+-0x02e49d29    tty_ldisc_flush vmlinux EXPORT_SYMBOL_GPL
+-0xb06d489b    skb_tstamp_tx   vmlinux EXPORT_SYMBOL_GPL
+-0xe66452ab    dql_init        vmlinux EXPORT_SYMBOL
+-0x69e27c7a    bitmap_copy_le  vmlinux EXPORT_SYMBOL
+-0x4dec6038    memscan vmlinux EXPORT_SYMBOL
+-0xa9148d85    mark_buffer_dirty       vmlinux EXPORT_SYMBOL
+-0x304b568f    get_super       vmlinux EXPORT_SYMBOL
+-0x00801678    flush_scheduled_work    vmlinux EXPORT_SYMBOL
+-0xb6115ca3    tty_set_operations      vmlinux EXPORT_SYMBOL
+-0x6d6cb9ad    ieee80211_operating_class_to_band       vmlinux EXPORT_SYMBOL
+-0x32e1f29c    skb_copy_and_csum_bits  vmlinux EXPORT_SYMBOL
+-0x776c599d    idma_reg_addr_init      vmlinux EXPORT_SYMBOL_GPL
+-0xef9f2dc8    ll_rw_block     vmlinux EXPORT_SYMBOL
+-0x13014091    block_write_begin       vmlinux EXPORT_SYMBOL
+-0x93226faa    irq_domain_associate_many       vmlinux EXPORT_SYMBOL_GPL
+-0x756a4248    st_sensors_read_info_raw        vmlinux EXPORT_SYMBOL
+-0x04339915    iio_update_buffers      vmlinux EXPORT_SYMBOL_GPL
+-0x55784228    regmap_irq_get_virq     vmlinux EXPORT_SYMBOL_GPL
+-0xbc25aac9    ump_dd_phys_blocks_get  vmlinux EXPORT_SYMBOL
+-0xe1761617    security_inet_conn_request      vmlinux EXPORT_SYMBOL
+-0x1268f357    resume_device_irqs      vmlinux EXPORT_SYMBOL_GPL
+-0xbe2e3b75    kstrtos8        vmlinux EXPORT_SYMBOL
+-0x124f2056    crypto_get_attr_type    vmlinux EXPORT_SYMBOL_GPL
+-0x2fc54b62    nfnetlink_send  vmlinux EXPORT_SYMBOL_GPL
+-0x9479479b    wm_hubs_hpr_mux vmlinux EXPORT_SYMBOL_GPL
+-0x49e22268    snd_soc_info_volsw_s8   vmlinux EXPORT_SYMBOL_GPL
+-0x329aef1b    crypto_alloc_aead       vmlinux EXPORT_SYMBOL_GPL
+-0x851d17d2    crypto_spawn_tfm2       vmlinux EXPORT_SYMBOL_GPL
+-0xce6a9d9a    trace_current_buffer_discard_commit     vmlinux EXPORT_SYMBOL_GPL
+-0x50fad434    round_jiffies_up        vmlinux EXPORT_SYMBOL_GPL
+-0xf7f16b3f    input_get_new_minor     vmlinux EXPORT_SYMBOL
+-0x26c90ea4    scsi_eh_get_sense       vmlinux EXPORT_SYMBOL_GPL
+-0x75e49326    device_create_bin_file  vmlinux EXPORT_SYMBOL_GPL
+-0x113c622e    dev_set_mac_address     vmlinux EXPORT_SYMBOL
+-0xe13ad642    sk_receive_skb  vmlinux EXPORT_SYMBOL
+-0xf5c05914    generic_segment_checks  vmlinux EXPORT_SYMBOL
+-0xd0f36f0d    audit_log_format        vmlinux EXPORT_SYMBOL
+-0xdbaf59ef    v4l2_m2m_mmap   vmlinux EXPORT_SYMBOL
+-0xde520229    serio_open      vmlinux EXPORT_SYMBOL
+-0xc5714a65    spi_master_suspend      vmlinux EXPORT_SYMBOL_GPL
+-0x22b325d5    kd_mksound      vmlinux EXPORT_SYMBOL
+-0x6d2fc5a6    net_namespace_list      vmlinux EXPORT_SYMBOL_GPL
+-0x9f6381e8    sock_register   vmlinux EXPORT_SYMBOL
+-0xf1806da9    idr_find_slowpath       vmlinux EXPORT_SYMBOL
+-0x5ae5be44    lg_lock_init    vmlinux EXPORT_SYMBOL
+-0x2d307e05    vb2_ioctl_qbuf  vmlinux EXPORT_SYMBOL_GPL
+-0xaad6c827    serio_close     vmlinux EXPORT_SYMBOL
+-0x8b092f05    loop_register_transfer  vmlinux EXPORT_SYMBOL
+-0x3c967a5a    device_set_wakeup_enable        vmlinux EXPORT_SYMBOL_GPL
+-0xc34b9b1f    regulator_get_bypass_regmap     vmlinux EXPORT_SYMBOL_GPL
+-0xde9cc521    pinctrl_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0xd1c5bc52    __cfg80211_send_deauth  vmlinux EXPORT_SYMBOL
+-0x126ad73c    inet6_register_protosw  vmlinux EXPORT_SYMBOL
+-0x5ce3b588    nfnl_lock       vmlinux EXPORT_SYMBOL_GPL
+-0xdc197993    netif_set_real_num_tx_queues    vmlinux EXPORT_SYMBOL
+-0xd4d07dc9    netif_set_real_num_rx_queues    vmlinux EXPORT_SYMBOL
+-0xbdc3f3e4    dev_set_group   vmlinux EXPORT_SYMBOL
+-0xb4176982    proc_remove     vmlinux EXPORT_SYMBOL
+-0x663e9182    end_buffer_async_write  vmlinux EXPORT_SYMBOL
+-0x3d517179    phy_register_fixup_for_uid      vmlinux EXPORT_SYMBOL
+-0xb4709322    scsi_dev_info_add_list  vmlinux EXPORT_SYMBOL
+-0x9dd34b62    drm_mm_insert_node_in_range     vmlinux EXPORT_SYMBOL
+-0x69b18f43    rfc1042_header  vmlinux EXPORT_SYMBOL
+-0x50097088    security_tun_dev_free_security  vmlinux EXPORT_SYMBOL
+-0x050c08c1    vfs_writev      vmlinux EXPORT_SYMBOL
+-0xd6b5a293    iio_buffer_init vmlinux EXPORT_SYMBOL
+-0x811e0359    sdio_get_host_pm_caps   vmlinux EXPORT_SYMBOL_GPL
+-0x9062c322    ring_buffer_consume     vmlinux EXPORT_SYMBOL_GPL
+-0x1c5b1f28    irq_free_descs  vmlinux EXPORT_SYMBOL_GPL
+-0xf2791baa    cgroup_unload_subsys    vmlinux EXPORT_SYMBOL_GPL
+-0xe43274bc    proc_dointvec   vmlinux EXPORT_SYMBOL
+-0xe8948e95    mmc_stop_bkops  vmlinux EXPORT_SYMBOL
+-0xa2a5fd77    inet_ehash_secret       vmlinux EXPORT_SYMBOL
+-0x2363e5bf    __inet_lookup_established       vmlinux EXPORT_SYMBOL_GPL
+-0x3eeb1d5e    netdev_alert    vmlinux EXPORT_SYMBOL
+-0x26ad413b    netdev_has_any_upper_dev        vmlinux EXPORT_SYMBOL
+-0x7604b234    udp_lib_rehash  vmlinux EXPORT_SYMBOL
+-0x5e5d53d3    udp_lib_unhash  vmlinux EXPORT_SYMBOL
+-0x2b12925d    cpumask_next_and        vmlinux EXPORT_SYMBOL
+-0x05495392    hid_debug       vmlinux EXPORT_SYMBOL_GPL
+-0x1d1ca867    pm_stay_awake   vmlinux EXPORT_SYMBOL_GPL
+-0x8c1a19df    device_show_ulong       vmlinux EXPORT_SYMBOL_GPL
+-0x46940ff4    set_ras_addr_hook       vmlinux EXPORT_SYMBOL_GPL
+-0x6088da85    nf_hook_slow    vmlinux EXPORT_SYMBOL
+-0xce5ac24f    zlib_inflate_workspacesize      vmlinux EXPORT_SYMBOL
+-0x2e73d9a1    v4l2_chip_ident_i2c_client      vmlinux EXPORT_SYMBOL
+-0x3783cdae    drm_open        vmlinux EXPORT_SYMBOL
+-0x5404b1e7    tcp_recvmsg     vmlinux EXPORT_SYMBOL
+-0x47b90df9    snd_pcm_limit_hw_rates  vmlinux EXPORT_SYMBOL
+-0x63baba6b    irq_alloc_generic_chip  vmlinux EXPORT_SYMBOL_GPL
+-0xace5c0fc    usb_bus_list    vmlinux EXPORT_SYMBOL_GPL
+-0xe8b63ace    radix_tree_range_tag_if_tagged  vmlinux EXPORT_SYMBOL
+-0x8d8b6353    proc_dointvec_userhz_jiffies    vmlinux EXPORT_SYMBOL
+-0x7ec5c02b    console_start   vmlinux EXPORT_SYMBOL
+-0x1a1aebf8    s3c_adc_start   vmlinux EXPORT_SYMBOL_GPL
+-0xffc6c87a    drm_detect_monitor_audio        vmlinux EXPORT_SYMBOL
+-0xe1371ad4    tcp_simple_retransmit   vmlinux EXPORT_SYMBOL
+-0x0f18b144    inet_csk_bind_conflict  vmlinux EXPORT_SYMBOL_GPL
+-0x708e56bd    xt_register_match       vmlinux EXPORT_SYMBOL
+-0xf3526269    proc_set_user   vmlinux EXPORT_SYMBOL
+-0x752dff9d    anon_inode_getfile      vmlinux EXPORT_SYMBOL_GPL
+-0xcd10fb11    simple_dir_inode_operations     vmlinux EXPORT_SYMBOL
+-0x708bd95d    irq_domain_xlate_onetwocell     vmlinux EXPORT_SYMBOL_GPL
+-0x122043a8    of_find_node_with_property      vmlinux EXPORT_SYMBOL
+-0xb3453966    vb2_fop_release vmlinux EXPORT_SYMBOL_GPL
+-0x59dddb40    ump_dd_reference_add    vmlinux EXPORT_SYMBOL
+-0xe8bcc079    snd_soc_codec_set_cache_io      vmlinux EXPORT_SYMBOL_GPL
+-0x67ae5cfb    dmam_pool_create        vmlinux EXPORT_SYMBOL
+-0x1e7f65cb    vb2_mmap        vmlinux EXPORT_SYMBOL_GPL
+-0xb33ff162    __find_get_block        vmlinux EXPORT_SYMBOL
+-0x23a997f4    dcache_dir_open vmlinux EXPORT_SYMBOL
+-0x3f4547a7    put_unused_fd   vmlinux EXPORT_SYMBOL
+-0xd2555f19    jiffies_64_to_clock_t   vmlinux EXPORT_SYMBOL
+-0xef969c64    input_mt_get_slot_by_key        vmlinux EXPORT_SYMBOL
+-0x2b547fec    genphy_suspend  vmlinux EXPORT_SYMBOL
+-0x0a04ac5b    subsys_system_register  vmlinux EXPORT_SYMBOL_GPL
+-0x919a5e62    inet6_lookup_listener   vmlinux EXPORT_SYMBOL_GPL
+-0xece784c2    rb_first        vmlinux EXPORT_SYMBOL
+-0xc72e1233    __trace_bprintk vmlinux EXPORT_SYMBOL_GPL
+-0x6a5ecb18    unregister_module_notifier      vmlinux EXPORT_SYMBOL
+-0x19f115c3    flush_delayed_work      vmlinux EXPORT_SYMBOL
+-0xf82f5060    usbnet_read_cmd vmlinux EXPORT_SYMBOL_GPL
+-0xf3e09d59    dev_pm_qos_expose_latency_limit vmlinux EXPORT_SYMBOL_GPL
+-0xfc4cb906    exynos_drm_subdrv_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0x04911106    of_dma_simple_xlate     vmlinux EXPORT_SYMBOL_GPL
+-0x7211e749    nf_conntrack_hash_check_insert  vmlinux EXPORT_SYMBOL_GPL
+-0x68b80336    zero_fill_bio   vmlinux EXPORT_SYMBOL
+-0xe83fad56    mmc_switch      vmlinux EXPORT_SYMBOL_GPL
+-0xa5a8337c    scsi_cmd_print_sense_hdr        vmlinux EXPORT_SYMBOL
+-0x8b08c5c1    unix_peer_get   vmlinux EXPORT_SYMBOL_GPL
+-0xef3b173b    audit_log_task_info     vmlinux EXPORT_SYMBOL
+-0xacc26098    iio_read_const_attr     vmlinux EXPORT_SYMBOL
+-0x47d7d62e    mmc_resume_host vmlinux EXPORT_SYMBOL
+-0x323758b8    v4l2_spi_subdev_init    vmlinux EXPORT_SYMBOL_GPL
+-0xbaa5b6b2    bus_register    vmlinux EXPORT_SYMBOL_GPL
+-0xf39ab86b    tcp_syn_ack_timeout     vmlinux EXPORT_SYMBOL
+-0xe73dda41    __nf_ct_ext_add_length  vmlinux EXPORT_SYMBOL
+-0xc4ff89ae    nf_log_unregister       vmlinux EXPORT_SYMBOL
+-0xd8e38717    d_hash_and_lookup       vmlinux EXPORT_SYMBOL
+-0x63193a50    generic_file_buffered_write     vmlinux EXPORT_SYMBOL
+-0xcce7df45    iio_alloc_pollfunc      vmlinux EXPORT_SYMBOL_GPL
+-0x24b0f90c    of_clk_get_by_name      vmlinux EXPORT_SYMBOL
+-0x3fb35146    mmc_alloc_host  vmlinux EXPORT_SYMBOL
+-0xe6099979    scsi_eh_ready_devs      vmlinux EXPORT_SYMBOL_GPL
+-0x986e6135    fb_pad_unaligned_buffer vmlinux EXPORT_SYMBOL
+-0xc1c2dd09    __hw_addr_flush vmlinux EXPORT_SYMBOL
+-0xae249a24    snd_register_device_for_dev     vmlinux EXPORT_SYMBOL
+-0xea054b22    nla_policy_len  vmlinux EXPORT_SYMBOL
+-0xd92afabe    bitmap_clear    vmlinux EXPORT_SYMBOL
+-0x80f48353    fsync_bdev      vmlinux EXPORT_SYMBOL
+-0x71930ed3    of_property_read_string vmlinux EXPORT_SYMBOL_GPL
+-0x570f339b    thermal_cooling_device_register vmlinux EXPORT_SYMBOL_GPL
+-0xcfcdd86a    input_open_device       vmlinux EXPORT_SYMBOL
+-0x84ac53cc    drm_fb_helper_single_add_all_connectors vmlinux EXPORT_SYMBOL
+-0x0e3edf75    regulator_set_bypass_regmap     vmlinux EXPORT_SYMBOL_GPL
+-0xfe990052    gpio_free       vmlinux EXPORT_SYMBOL_GPL
+-0x0b63a348    cfg80211_wext_giwrange  vmlinux EXPORT_SYMBOL_GPL
+-0x6d815a8f    ip6_dst_lookup  vmlinux EXPORT_SYMBOL_GPL
+-0x40a9b349    vzalloc vmlinux EXPORT_SYMBOL
+-0xc2f9c045    timespec_to_jiffies     vmlinux EXPORT_SYMBOL
+-0x54159824    iio_push_event  vmlinux EXPORT_SYMBOL
+-0x94f95b4e    i2c_new_device  vmlinux EXPORT_SYMBOL_GPL
+-0xe04e6d60    device_for_each_child   vmlinux EXPORT_SYMBOL_GPL
+-0x5eafb8e9    drm_mode_set_name       vmlinux EXPORT_SYMBOL
+-0x3b0a974f    arm_iommu_release_mapping       vmlinux EXPORT_SYMBOL_GPL
+-0xed76ba4a    hci_resume_dev  vmlinux EXPORT_SYMBOL
+-0x9cfaab5e    media_device_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x5783d440    pm_generic_poweroff_late        vmlinux EXPORT_SYMBOL_GPL
+-0x59c8991b    nci_allocate_device     vmlinux EXPORT_SYMBOL
+-0x11089ac7    _ctype  vmlinux EXPORT_SYMBOL
+-0x66d480cb    blk_get_queue   vmlinux EXPORT_SYMBOL
+-0x60b78a66    bd_set_size     vmlinux EXPORT_SYMBOL
+-0x71f34013    __mem_cgroup_count_vm_event     vmlinux EXPORT_SYMBOL
+-0x2d45b494    pm_vt_switch_unregister vmlinux EXPORT_SYMBOL
+-0xca7d8764    kthread_freezable_should_stop   vmlinux EXPORT_SYMBOL_GPL
+-0x03b3002e    st_sensors_enable_events        vmlinux EXPORT_SYMBOL
+-0xfc937fcb    usb_add_gadget_udc      vmlinux EXPORT_SYMBOL_GPL
+-0x420323e6    i2c_dp_aux_add_bus      vmlinux EXPORT_SYMBOL
+-0xd6ef94db    udp_proc_unregister     vmlinux EXPORT_SYMBOL
+-0x37f614b7    __kfifo_len_r   vmlinux EXPORT_SYMBOL
+-0xac6e0f5a    power_supply_get_by_name        vmlinux EXPORT_SYMBOL_GPL
+-0x86047552    inet_sk_rebuild_header  vmlinux EXPORT_SYMBOL
+-0x3c878c55    skb_copy        vmlinux EXPORT_SYMBOL
+-0xe5b6e62e    snd_pcm_stop    vmlinux EXPORT_SYMBOL
+-0x7593d385    div64_s64       vmlinux EXPORT_SYMBOL
+-0x27864d57    memparse        vmlinux EXPORT_SYMBOL
+-0xe8f9c617    block_truncate_page     vmlinux EXPORT_SYMBOL
+-0xbc036e9e    generic_write_checks    vmlinux EXPORT_SYMBOL
+-0x4f68e5c9    do_gettimeofday vmlinux EXPORT_SYMBOL
+-0xa6715115    do_settimeofday vmlinux EXPORT_SYMBOL
+-0xd9efbe4c    input_inject_event      vmlinux EXPORT_SYMBOL
+-0x3dc565d9    drm_mm_insert_node_generic      vmlinux EXPORT_SYMBOL
+-0x0c58a8cd    netdev_increment_features       vmlinux EXPORT_SYMBOL
+-0xb3c487b6    uart_match_port vmlinux EXPORT_SYMBOL
+-0x208f2017    brcmu_pktq_pdeq_match   drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0xbc455bde    cfg80211_pmksa_candidate_notify vmlinux EXPORT_SYMBOL
+-0x3bef03b9    flow_cache_lookup       vmlinux EXPORT_SYMBOL
+-0x5002ec2f    __splice_from_pipe      vmlinux EXPORT_SYMBOL
+-0x863c552c    cache_firmware  vmlinux EXPORT_SYMBOL_GPL
+-0xe5274b72    unregister_net_sysctl_table     vmlinux EXPORT_SYMBOL_GPL
+-0xa197b1ff    ieee80211_get_mesh_hdrlen       vmlinux EXPORT_SYMBOL
+-0x3a9592df    __nf_ct_ext_destroy     vmlinux EXPORT_SYMBOL
+-0xa2c640f9    sysfs_add_file_to_group vmlinux EXPORT_SYMBOL_GPL
+-0x487d9343    param_ops_ushort        vmlinux EXPORT_SYMBOL
+-0x58804ca9    sdio_align_size vmlinux EXPORT_SYMBOL_GPL
+-0xa09e1f4c    cpufreq_register_governor       vmlinux EXPORT_SYMBOL_GPL
+-0x8ee7279a    ump_dd_size_get vmlinux EXPORT_SYMBOL
+-0xfb858f46    tty_write_room  vmlinux EXPORT_SYMBOL
+-0x3d715445    dev_trans_start vmlinux EXPORT_SYMBOL
+-0xa381944f    dql_reset       vmlinux EXPORT_SYMBOL
+-0x8f99ae4c    blk_register_region     vmlinux EXPORT_SYMBOL
+-0xa8242495    bio_put vmlinux EXPORT_SYMBOL
+-0x488d1fd7    task_tgid_nr_ns vmlinux EXPORT_SYMBOL
+-0xc8d55b31    usb_unlocked_disable_lpm        vmlinux EXPORT_SYMBOL_GPL
+-0x10ee20bb    default_blu     vmlinux EXPORT_SYMBOL
+-0x57575f08    dmaengine_put   vmlinux EXPORT_SYMBOL
+-0x60577ee3    ip6_expire_frag_queue   vmlinux EXPORT_SYMBOL
+-0xdb5d34e0    rcu_batches_completed_preempt   vmlinux EXPORT_SYMBOL_GPL
+-0xec6f4d80    each_symbol_section     vmlinux EXPORT_SYMBOL_GPL
+-0xea6e3003    of_find_compatible_node vmlinux EXPORT_SYMBOL
+-0x0d95dc3b    video_ioctl2    vmlinux EXPORT_SYMBOL
+-0x26156aad    input_alloc_absinfo     vmlinux EXPORT_SYMBOL
+-0x244b53b3    scsi_is_target_device   vmlinux EXPORT_SYMBOL
+-0xd0cf28c6    sk_dst_check    vmlinux EXPORT_SYMBOL
+-0xa5dd45f3    prandom_bytes_state     vmlinux EXPORT_SYMBOL
+-0x6a76f3ac    blk_iopoll_enable       vmlinux EXPORT_SYMBOL
+-0x17e1907b    inode_needs_sync        vmlinux EXPORT_SYMBOL
+-0x9c6ac1ed    grab_cache_page_nowait  vmlinux EXPORT_SYMBOL
+-0xe7a81967    audit_log_secctx        vmlinux EXPORT_SYMBOL
+-0x2babe81f    __wake_up_sync_key      vmlinux EXPORT_SYMBOL_GPL
+-0x4adaf0f3    v4l2_ctrl_query_menu_valid_items        vmlinux EXPORT_SYMBOL
+-0xcb6f482d    dev_getfirstbyhwtype    vmlinux EXPORT_SYMBOL
+-0xb23df37e    wake_up_process vmlinux EXPORT_SYMBOL
+-0x25820c64    fs_overflowuid  vmlinux EXPORT_SYMBOL
+-0x24ddf922    scsi_internal_device_block      vmlinux EXPORT_SYMBOL_GPL
+-0x1079ac8f    drm_framebuffer_remove  vmlinux EXPORT_SYMBOL
+-0x160f2f7e    of_phy_simple_xlate     vmlinux EXPORT_SYMBOL_GPL
+-0xe669c8a2    __nf_ct_refresh_acct    vmlinux EXPORT_SYMBOL_GPL
+-0xa2f20d05    skb_dequeue_tail        vmlinux EXPORT_SYMBOL
+-0x19a025aa    __get_user_pages        vmlinux EXPORT_SYMBOL
+-0x286acd69    free_css_id     vmlinux EXPORT_SYMBOL_GPL
+-0x404c4f08    __module_address        vmlinux EXPORT_SYMBOL_GPL
+-0x195d329a    hidinput_count_leds     vmlinux EXPORT_SYMBOL_GPL
+-0x280c859a    input_ff_erase  vmlinux EXPORT_SYMBOL_GPL
+-0x886d02da    scsi_target_resume      vmlinux EXPORT_SYMBOL
+-0x8f31e347    inet_stream_ops vmlinux EXPORT_SYMBOL
+-0x9b0dcfa2    qdisc_reset     vmlinux EXPORT_SYMBOL
+-0xd2da1048    register_netdevice_notifier     vmlinux EXPORT_SYMBOL
+-0x1b5fff19    blk_complete_request    vmlinux EXPORT_SYMBOL
+-0x808ec1a3    crypto_alg_tested       vmlinux EXPORT_SYMBOL_GPL
+-0xda920cd9    bio_unmap_user  vmlinux EXPORT_SYMBOL
+-0xe769232e    sprint_symbol_no_offset vmlinux EXPORT_SYMBOL_GPL
+-0x2b7a6de8    syscon_regmap_lookup_by_phandle vmlinux EXPORT_SYMBOL_GPL
+-0x9728e93f    of_dma_controller_register      vmlinux EXPORT_SYMBOL_GPL
+-0x1b61c5b3    pwm_config      vmlinux EXPORT_SYMBOL_GPL
+-0x39bdf0f0    nci_free_device vmlinux EXPORT_SYMBOL
+-0xe3a306b5    udp_seq_open    vmlinux EXPORT_SYMBOL
+-0x38c97d50    idr_get_next    vmlinux EXPORT_SYMBOL
+-0xeaacc92f    fail_migrate_page       vmlinux EXPORT_SYMBOL
+-0x4cdb3178    ns_to_timeval   vmlinux EXPORT_SYMBOL
+-0xc78d0953    ehci_init_driver        vmlinux EXPORT_SYMBOL_GPL
+-0xcd6ff125    nf_ct_expect_register_notifier  vmlinux EXPORT_SYMBOL_GPL
+-0x721b1851    skip_spaces     vmlinux EXPORT_SYMBOL
+-0x0c0c015e    ring_buffer_swap_cpu    vmlinux EXPORT_SYMBOL_GPL
+-0x76d451c4    add_taint       vmlinux EXPORT_SYMBOL
+-0x1c2596ba    regmap_async_complete_cb        vmlinux EXPORT_SYMBOL_GPL
+-0x60a32ea9    pm_power_off    vmlinux EXPORT_SYMBOL
+-0x2b911208    __neigh_for_each_release        vmlinux EXPORT_SYMBOL
+-0x0bc7e6ff    blk_queue_init_tags     vmlinux EXPORT_SYMBOL
+-0xa666946b    bdget   vmlinux EXPORT_SYMBOL
+-0x885a4cc9    bdput   vmlinux EXPORT_SYMBOL
+-0x2517dbbb    fsstack_copy_inode_size vmlinux EXPORT_SYMBOL_GPL
+-0x7d4ed855    iio_trigger_poll_chained        vmlinux EXPORT_SYMBOL
+-0x561e4b77    irq_of_parse_and_map    vmlinux EXPORT_SYMBOL_GPL
+-0x308efc55    spi_busnum_to_master    vmlinux EXPORT_SYMBOL_GPL
+-0xe862c4b7    dpm_suspend_start       vmlinux EXPORT_SYMBOL_GPL
+-0xd728282d    device_initialize       vmlinux EXPORT_SYMBOL_GPL
+-0xf6b77868    nf_conntrack_untracked  vmlinux EXPORT_SYMBOL
+-0xed9f8e6d    kstrtos16       vmlinux EXPORT_SYMBOL
+-0xfb32b30f    ring_buffer_read_prepare_sync   vmlinux EXPORT_SYMBOL_GPL
+-0x846bcc01    dm_table_get    vmlinux EXPORT_SYMBOL
+-0x1416333b    tcf_em_register vmlinux EXPORT_SYMBOL
+-0x19546cac    snd_soc_cache_read      vmlinux EXPORT_SYMBOL_GPL
+-0xfd2f4f20    snd_soc_info_volsw_ext  vmlinux EXPORT_SYMBOL_GPL
+-0x6c749afe    __tracepoint_block_unplug       vmlinux EXPORT_SYMBOL_GPL
+-0x9c86ede0    fs_kobj vmlinux EXPORT_SYMBOL_GPL
+-0x796c2d48    dm_get_md       vmlinux EXPORT_SYMBOL_GPL
+-0xf8fbb4f0    __bad_xchg      vmlinux EXPORT_SYMBOL
+-0xc40f284c    nf_ct_helper_hsize      vmlinux EXPORT_SYMBOL_GPL
+-0x24428be5    strncpy_from_user       vmlinux EXPORT_SYMBOL
+-0x6d74d462    crypto_alloc_ablkcipher vmlinux EXPORT_SYMBOL_GPL
+-0x0b96efa8    bio_init        vmlinux EXPORT_SYMBOL
+-0x7278d328    all_vm_events   vmlinux EXPORT_SYMBOL_GPL
+-0x41814cb8    dirty_writeback_interval        vmlinux EXPORT_SYMBOL_GPL
+-0x1c32da2a    iio_enum_available_read vmlinux EXPORT_SYMBOL_GPL
+-0xcda91c46    drm_mode_debug_printmodeline    vmlinux EXPORT_SYMBOL
+-0xa9cae71a    inet6_hash_connect      vmlinux EXPORT_SYMBOL_GPL
+-0x92f5d840    gnet_stats_copy_rate_est        vmlinux EXPORT_SYMBOL
+-0x17f61c70    skb_partial_csum_set    vmlinux EXPORT_SYMBOL_GPL
+-0xb86cf818    create_empty_buffers    vmlinux EXPORT_SYMBOL
+-0x26332c2f    init_special_inode      vmlinux EXPORT_SYMBOL
+-0xd0720a17    on_each_cpu_cond        vmlinux EXPORT_SYMBOL
+-0x870713f0    iommu_detach_group      vmlinux EXPORT_SYMBOL_GPL
+-0x00c8b1c1    sdio_enable_func        vmlinux EXPORT_SYMBOL_GPL
+-0x22f907ec    pm_runtime_no_callbacks vmlinux EXPORT_SYMBOL_GPL
+-0x8d4234e8    subsys_dev_iter_next    vmlinux EXPORT_SYMBOL_GPL
+-0x706fc943    mali_pmu_powerup        vmlinux EXPORT_SYMBOL
+-0xf24fbd54    cfg80211_mgmt_tx_status vmlinux EXPORT_SYMBOL
+-0xa8bae0ab    inet_frag_destroy       vmlinux EXPORT_SYMBOL
+-0xca1aff2d    ipv4_sk_update_pmtu     vmlinux EXPORT_SYMBOL_GPL
+-0x539973c5    skb_make_writable       vmlinux EXPORT_SYMBOL
+-0x2eeceb42    sk_chk_filter   vmlinux EXPORT_SYMBOL
+-0x8f595b11    snd_major       vmlinux EXPORT_SYMBOL
+-0xf8433bfd    pipe_to_file    vmlinux EXPORT_SYMBOL
+-0x0dc1d65b    __dec_zone_page_state   vmlinux EXPORT_SYMBOL
+-0x95ce193b    __inc_zone_page_state   vmlinux EXPORT_SYMBOL
+-0x736c2d7c    __mod_zone_page_state   vmlinux EXPORT_SYMBOL
+-0xab6babaf    pm_qos_request  vmlinux EXPORT_SYMBOL_GPL
+-0xeed6cc4b    flush_kthread_worker    vmlinux EXPORT_SYMBOL_GPL
+-0xa5cef8ad    release_resource        vmlinux EXPORT_SYMBOL
+-0x4584b8a3    iio_push_to_buffers     vmlinux EXPORT_SYMBOL_GPL
+-0xc79bcd36    dm_vcalloc      vmlinux EXPORT_SYMBOL
+-0xa7dd8c46    ump_dd_phys_block_get   vmlinux EXPORT_SYMBOL
+-0x83bd3297    brioctl_set     vmlinux EXPORT_SYMBOL
+-0x09e913c1    snd_pcm_alt_chmaps      vmlinux EXPORT_SYMBOL_GPL
+-0xbf33e600    vm_insert_pfn   vmlinux EXPORT_SYMBOL
+-0xda050109    irq_domain_add_nomap    vmlinux EXPORT_SYMBOL_GPL
+-0xfcaa04a0    out_of_line_wait_on_bit_lock    vmlinux EXPORT_SYMBOL
+-0xa7bb71ae    input_set_abs_params    vmlinux EXPORT_SYMBOL
+-0x22f9a7f4    spi_bus_unlock  vmlinux EXPORT_SYMBOL_GPL
+-0x2ea5ad9c    device_schedule_callback_owner  vmlinux EXPORT_SYMBOL_GPL
+-0x4c511235    drm_edid_is_valid       vmlinux EXPORT_SYMBOL
+-0x3939f8f0    rfkill_pause_polling    vmlinux EXPORT_SYMBOL
+-0xebc7bcd9    xfrm_state_alloc        vmlinux EXPORT_SYMBOL
+-0x85670f1d    rtnl_is_locked  vmlinux EXPORT_SYMBOL
+-0x726d45d3    fat_remove_entries      vmlinux EXPORT_SYMBOL_GPL
+-0xd963ea55    page_symlink    vmlinux EXPORT_SYMBOL
+-0xa26d9b4f    workqueue_congested     vmlinux EXPORT_SYMBOL_GPL
+-0xf7cd6b11    freq_reg_info   vmlinux EXPORT_SYMBOL
+-0x764dafa5    __xfrm_route_forward    vmlinux EXPORT_SYMBOL
+-0xd317cce2    snd_soc_put_volsw_sx    vmlinux EXPORT_SYMBOL_GPL
+-0x587ba0c8    snd_soc_get_volsw_s8    vmlinux EXPORT_SYMBOL_GPL
+-0x5dda7051    snd_soc_put_volsw_s8    vmlinux EXPORT_SYMBOL_GPL
+-0xd6b61c7b    snd_soc_get_volsw_sx    vmlinux EXPORT_SYMBOL_GPL
+-0x9f0664bf    dm_get_queue_limits     vmlinux EXPORT_SYMBOL_GPL
+-0x0364983f    gen_replace_estimator   vmlinux EXPORT_SYMBOL
+-0x2f03fc4b    security_secmark_refcount_inc   vmlinux EXPORT_SYMBOL
+-0x19bd383b    security_secmark_refcount_dec   vmlinux EXPORT_SYMBOL
+-0xc22b50ad    param_set_bint  vmlinux EXPORT_SYMBOL
+-0x21315700    param_get_bool  vmlinux EXPORT_SYMBOL
+-0x3eae292f    param_set_byte  vmlinux EXPORT_SYMBOL
+-0xcea1a019    dw_mci_suspend  vmlinux EXPORT_SYMBOL
+-0x8657c2d4    spi_bitbang_setup       vmlinux EXPORT_SYMBOL_GPL
+-0xb13fbb9a    scsi_target_unblock     vmlinux EXPORT_SYMBOL_GPL
+-0xbf3a015f    brcmf_sdio_remove       drivers/net/wireless/brcm80211/brcmfmac/brcmfmac        EXPORT_SYMBOL
+-0xeb1c3628    nf_ipv6_ops     vmlinux EXPORT_SYMBOL_GPL
+-0x9fdecc31    unregister_netdevice_many       vmlinux EXPORT_SYMBOL
+-0x75308bb0    blk_queue_logical_block_size    vmlinux EXPORT_SYMBOL
+-0x2fe50bdf    init_srcu_struct        vmlinux EXPORT_SYMBOL_GPL
+-0xfba64859    rtc_device_unregister   vmlinux EXPORT_SYMBOL_GPL
+-0xbd10afa1    drm_platform_init       vmlinux EXPORT_SYMBOL
+-0xa1ceb496    drm_platform_exit       vmlinux EXPORT_SYMBOL
+-0xd10d7d37    arp_tbl vmlinux EXPORT_SYMBOL
+-0x9aa6cefb    __skb_recv_datagram     vmlinux EXPORT_SYMBOL
+-0x0430401c    snd_soc_remove_platform vmlinux EXPORT_SYMBOL_GPL
+-0xfe7c4287    nr_cpu_ids      vmlinux EXPORT_SYMBOL
+-0x18b6fa40    v4l2_ctrl_add_ctrl      vmlinux EXPORT_SYMBOL
+-0xb21d34e2    phy_attach      vmlinux EXPORT_SYMBOL
+-0x67f7fd01    gpiochip_remove_pin_ranges      vmlinux EXPORT_SYMBOL_GPL
+-0x5c9284a0    processor_id    vmlinux EXPORT_SYMBOL
+-0x688e3c72    tcp_splice_read vmlinux EXPORT_SYMBOL
+-0x9f7f32fe    xt_unregister_match     vmlinux EXPORT_SYMBOL
+-0x2822f8fe    irq_setup_generic_chip  vmlinux EXPORT_SYMBOL_GPL
+-0x8763d790    pm_genpd_syscore_switch vmlinux EXPORT_SYMBOL_GPL
+-0xc898f9f7    css_depth       vmlinux EXPORT_SYMBOL_GPL
+-0x95d97984    devm_regmap_init_spi    vmlinux EXPORT_SYMBOL_GPL
+-0x32108723    devm_regmap_init_i2c    vmlinux EXPORT_SYMBOL_GPL
+-0x824028e1    drm_master_get  vmlinux EXPORT_SYMBOL
+-0x36e360e3    __hw_addr_add_multiple  vmlinux EXPORT_SYMBOL
+-0x92e42550    snd_soc_jack_add_gpios  vmlinux EXPORT_SYMBOL_GPL
+-0x9552bd34    crypto_unregister_algs  vmlinux EXPORT_SYMBOL_GPL
+-0x70bd3119    simple_transaction_set  vmlinux EXPORT_SYMBOL
+-0x5cf1e7e1    simple_transaction_get  vmlinux EXPORT_SYMBOL
+-0x86b57862    find_pid_ns     vmlinux EXPORT_SYMBOL_GPL
+-0x0b59c21c    st_gyro_common_probe    vmlinux EXPORT_SYMBOL
+-0x3a4c6000    of_irq_to_resource      vmlinux EXPORT_SYMBOL_GPL
+-0xcbc9557f    unregister_sysrq_key    vmlinux EXPORT_SYMBOL
+-0xd85ac634    regulator_put   vmlinux EXPORT_SYMBOL_GPL
+-0x56e75d47    klist_node_attached     vmlinux EXPORT_SYMBOL_GPL
+-0xf0d6c49d    rfkill_alloc    vmlinux EXPORT_SYMBOL
+-0xe118d3ca    __nf_conntrack_find     vmlinux EXPORT_SYMBOL_GPL
+-0x67fa9d64    __nlmsg_put     vmlinux EXPORT_SYMBOL
+-0xc5f839f2    lock_sock_nested        vmlinux EXPORT_SYMBOL
+-0x92b57248    flush_work      vmlinux EXPORT_SYMBOL_GPL
+-0x63aecd53    hid_add_device  vmlinux EXPORT_SYMBOL_GPL
+-0x870e11ef    sdio_disable_func       vmlinux EXPORT_SYMBOL_GPL
+-0xd6c99af7    devm_usb_put_phy        vmlinux EXPORT_SYMBOL_GPL
+-0x60652b23    usbnet_cdc_bind vmlinux EXPORT_SYMBOL_GPL
+-0x0f1fd032    scsi_free_command       vmlinux EXPORT_SYMBOL
+-0x150d593e    platform_add_devices    vmlinux EXPORT_SYMBOL_GPL
+-0xdc2235fd    device_show_bool        vmlinux EXPORT_SYMBOL_GPL
+-0xe800ece3    __mmc_switch    vmlinux EXPORT_SYMBOL_GPL
+-0x8650b7ba    usb_deregister  vmlinux EXPORT_SYMBOL_GPL
+-0x83a82050    phy_ethtool_get_eee     vmlinux EXPORT_SYMBOL
+-0xccb94d1a    phy_ethtool_set_eee     vmlinux EXPORT_SYMBOL
+-0x1a81168a    drm_mm_dump_table       vmlinux EXPORT_SYMBOL
+-0x04cda566    snd_interval_refine     vmlinux EXPORT_SYMBOL
+-0x6b2dc060    dump_stack      vmlinux EXPORT_SYMBOL
+-0x23476dca    crypto_alloc_instance   vmlinux EXPORT_SYMBOL_GPL
+-0x31cd11aa    mpage_writepage vmlinux EXPORT_SYMBOL
+-0xa219c44e    try_to_writeback_inodes_sb_nr   vmlinux EXPORT_SYMBOL
+-0xd942d353    ring_buffer_record_off  vmlinux EXPORT_SYMBOL_GPL
+-0x178768e1    set_security_override   vmlinux EXPORT_SYMBOL
+-0x7930d225    of_device_is_compatible vmlinux EXPORT_SYMBOL
+-0xa1fb703c    drm_mm_remove_node      vmlinux EXPORT_SYMBOL
+-0x3fce0784    rdev_get_drvdata        vmlinux EXPORT_SYMBOL_GPL
+-0x193f9832    nfc_allocate_device     vmlinux EXPORT_SYMBOL
+-0xcefba9ae    raw_seq_start   vmlinux EXPORT_SYMBOL_GPL
+-0x353b4dcf    nfnetlink_subsys_unregister     vmlinux EXPORT_SYMBOL_GPL
+-0x1db53c10    dst_cow_metrics_generic vmlinux EXPORT_SYMBOL
+-0x884c205c    mount_ns        vmlinux EXPORT_SYMBOL
+-0x26b0e339    sdhci_disable_irq_wakeups       vmlinux EXPORT_SYMBOL_GPL
+-0x69e3154c    rtc_read_time   vmlinux EXPORT_SYMBOL_GPL
+-0xde6ff4ec    usb_get_function_instance       vmlinux EXPORT_SYMBOL_GPL
+-0x0c29207f    netdev_master_upper_dev_get     vmlinux EXPORT_SYMBOL
+-0x62d34ec2    kobject_del     vmlinux EXPORT_SYMBOL
+-0x7489664f    crypto_unregister_shash vmlinux EXPORT_SYMBOL_GPL
+-0x5ca7f0f8    crypto_unregister_ahash vmlinux EXPORT_SYMBOL_GPL
+-0x86a4889a    kmalloc_order_trace     vmlinux EXPORT_SYMBOL
+-0x0698cb23    drm_core_reclaim_buffers        vmlinux EXPORT_SYMBOL
+-0x94478b76    nat_callforwarding_hook vmlinux EXPORT_SYMBOL_GPL
+-0x6e4b8906    snd_ctl_find_numid      vmlinux EXPORT_SYMBOL
+-0xb6a68816    find_last_bit   vmlinux EXPORT_SYMBOL
+-0xc8d47bdb    inode_dio_done  vmlinux EXPORT_SYMBOL
+-0xb9ca066f    poll_initwait   vmlinux EXPORT_SYMBOL
+-0x193d48e0    trace_current_buffer_unlock_commit      vmlinux EXPORT_SYMBOL_GPL
+-0x46a36032    unregister_console      vmlinux EXPORT_SYMBOL
+-0xd0fbc335    vb2_get_vma     vmlinux EXPORT_SYMBOL_GPL
+-0x6ebd302d    usb_reset_endpoint      vmlinux EXPORT_SYMBOL_GPL
+-0x38a4f7ae    drm_format_num_planes   vmlinux EXPORT_SYMBOL
+-0xc414c422    drm_vblank_offdelay     vmlinux EXPORT_SYMBOL
+-0x96554810    register_keyboard_notifier      vmlinux EXPORT_SYMBOL_GPL
+-0x2ec0f25c    nf_ct_helper_ext_add    vmlinux EXPORT_SYMBOL_GPL
+-0xe745ec59    aead_geniv_free vmlinux EXPORT_SYMBOL_GPL
+-0xd8e484f0    register_chrdev_region  vmlinux EXPORT_SYMBOL
+-0xc58b6dd5    led_trigger_unregister_simple   vmlinux EXPORT_SYMBOL_GPL
+-0x068f1d12    phy_disconnect  vmlinux EXPORT_SYMBOL
+-0x9c518b55    regmap_update_bits      vmlinux EXPORT_SYMBOL_GPL
+-0xc63f1b81    ieee80211_radiotap_iterator_next        vmlinux EXPORT_SYMBOL
+-0x9744e080    inet_csk_reqsk_queue_prune      vmlinux EXPORT_SYMBOL_GPL
+-0xb9ff0fd7    netdev_state_change     vmlinux EXPORT_SYMBOL
+-0x310917fe    sort    vmlinux EXPORT_SYMBOL
+-0xa8fef7bb    security_unix_may_send  vmlinux EXPORT_SYMBOL
+-0x541bd60a    irq_work_run    vmlinux EXPORT_SYMBOL_GPL
+-0x6c49c4f2    clockevents_notify      vmlinux EXPORT_SYMBOL_GPL
+-0xe208ea98    hci_recv_stream_fragment        vmlinux EXPORT_SYMBOL
+-0xe6c68334    ddebug_remove_module    vmlinux EXPORT_SYMBOL_GPL
+-0xf8ae0cbf    kern_path       vmlinux EXPORT_SYMBOL
+-0x6e9dd7bc    usb_sg_cancel   vmlinux EXPORT_SYMBOL_GPL
+-0x7c05fd17    nf_register_queue_handler       vmlinux EXPORT_SYMBOL
+-0x2a8db409    snd_soc_dai_set_tristate        vmlinux EXPORT_SYMBOL_GPL
+-0x29b1c366    __sg_alloc_table        vmlinux EXPORT_SYMBOL
+-0x9c3889f4    shrink_dcache_sb        vmlinux EXPORT_SYMBOL
+-0x15692c87    param_ops_int   vmlinux EXPORT_SYMBOL
+-0xd04e04f7    iio_update_demux        vmlinux EXPORT_SYMBOL_GPL
+-0x105a7a58    dma_alloc_from_coherent vmlinux EXPORT_SYMBOL
+-0xe4309905    syscore_resume  vmlinux EXPORT_SYMBOL_GPL
+-0xab482a65    blkdev_issue_flush      vmlinux EXPORT_SYMBOL
+-0x499043d3    crypto_init_queue       vmlinux EXPORT_SYMBOL_GPL
+-0xca871be2    default_backing_dev_info        vmlinux EXPORT_SYMBOL_GPL
+-0x3d5120d1    st_accel_common_probe   vmlinux EXPORT_SYMBOL
+-0x44f5e8b5    of_allnodes     vmlinux EXPORT_SYMBOL
+-0xf563353a    v4l2_subdev_link_validate       vmlinux EXPORT_SYMBOL_GPL
+-0x011cf028    regulator_suspend_finish        vmlinux EXPORT_SYMBOL_GPL
+-0x1b88e3fa    find_inode_number       vmlinux EXPORT_SYMBOL
+-0xb2d307de    param_ops_short vmlinux EXPORT_SYMBOL
+-0x0b586662    drm_gem_object_init     vmlinux EXPORT_SYMBOL
+-0xaad6d92f    rfkill_init_sw_state    vmlinux EXPORT_SYMBOL
+-0x4f4d4dc8    hci_unregister_dev      vmlinux EXPORT_SYMBOL
+-0xa6970398    __kfifo_to_user_r       vmlinux EXPORT_SYMBOL
+-0xf7f92f26    st_sensors_set_enable   vmlinux EXPORT_SYMBOL
+-0x236bcb52    unregister_con_driver   vmlinux EXPORT_SYMBOL
+-0x39898017    amba_device_put vmlinux EXPORT_SYMBOL_GPL
+-0x8d28fc98    amba_device_add vmlinux EXPORT_SYMBOL_GPL
+-0x3169d518    softnet_data    vmlinux EXPORT_SYMBOL
+-0x5fc56a46    _raw_spin_unlock        vmlinux EXPORT_SYMBOL
+-0xfe5d4bb2    sys_tz  vmlinux EXPORT_SYMBOL
+-0x81ced62d    ip6_sk_redirect vmlinux EXPORT_SYMBOL_GPL
+-0x9ffa3a75    netdev_max_backlog      vmlinux EXPORT_SYMBOL
+-0xfa237e15    __skb_tx_hash   vmlinux EXPORT_SYMBOL
+-0x1b701804    blk_init_queue  vmlinux EXPORT_SYMBOL
+-0x474d3122    unlock_page     vmlinux EXPORT_SYMBOL
+-0x4f98d766    cpu_pm_unregister_notifier      vmlinux EXPORT_SYMBOL_GPL
+-0x76963409    lock_fb_info    vmlinux EXPORT_SYMBOL
+-0x11e2ec12    flex_array_free_parts   vmlinux EXPORT_SYMBOL
+-0x5ecb52ac    sdio_memcpy_fromio      vmlinux EXPORT_SYMBOL_GPL
+-0xa4480afe    drm_sysfs_hotplug_event vmlinux EXPORT_SYMBOL
+-0xeaab7f82    lcd_device_register     vmlinux EXPORT_SYMBOL
+-0x0c12eee9    xfrm_unregister_type    vmlinux EXPORT_SYMBOL
+-0x297f1a00    nf_ip_checksum  vmlinux EXPORT_SYMBOL
+-0xd14bc4d9    sock_diag_save_cookie   vmlinux EXPORT_SYMBOL_GPL
+-0xdd810ba9    snd_info_register       vmlinux EXPORT_SYMBOL
+-0x773a9c94    blk_iopoll_enabled      vmlinux EXPORT_SYMBOL
+-0xd704f458    jbd2_log_wait_commit    vmlinux EXPORT_SYMBOL
+-0x22e82b9e    hrtimer_init_sleeper    vmlinux EXPORT_SYMBOL_GPL
+-0x437e0518    eth_rebuild_header      vmlinux EXPORT_SYMBOL
+-0x47fb2e90    neigh_compat_output     vmlinux EXPORT_SYMBOL
+-0x0283dfe3    _snd_pcm_hw_params_any  vmlinux EXPORT_SYMBOL
+-0xe2407fb6    user_path_at    vmlinux EXPORT_SYMBOL
+-0x35d93ce8    cgroup_add_cftypes      vmlinux EXPORT_SYMBOL_GPL
+-0x4ac62273    module_put      vmlinux EXPORT_SYMBOL
+-0x2459bbcc    console_set_on_cmdline  vmlinux EXPORT_SYMBOL
+-0xbec530ad    max8997_update_reg      vmlinux EXPORT_SYMBOL_GPL
+-0x3255972d    hdmi_vendor_infoframe_pack      vmlinux EXPORT_SYMBOL
+-0x8da61397    ip_tunnel_rcv   vmlinux EXPORT_SYMBOL_GPL
+-0x3c44f68c    inode_get_bytes vmlinux EXPORT_SYMBOL
+-0xd85cd67e    __wake_up       vmlinux EXPORT_SYMBOL
+-0xcefe5c3b    usb_get_from_anchor     vmlinux EXPORT_SYMBOL_GPL
+-0x9a858808    genphy_resume   vmlinux EXPORT_SYMBOL
+-0x606ae2bc    drm_mm_debug_table      vmlinux EXPORT_SYMBOL
+-0xed636ddf    nf_conntrack_helper_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0xc7a1840e    llist_add_batch vmlinux EXPORT_SYMBOL_GPL
+-0x2787db00    vbin_printf     vmlinux EXPORT_SYMBOL_GPL
+-0xfe59fc1b    security_d_instantiate  vmlinux EXPORT_SYMBOL
+-0x6b8286e4    bio_reset       vmlinux EXPORT_SYMBOL
+-0x86414ad5    vfs_mkdir       vmlinux EXPORT_SYMBOL
+-0x87b883c7    i2c_for_each_dev        vmlinux EXPORT_SYMBOL_GPL
+-0x26f81b6a    dev_driver_string       vmlinux EXPORT_SYMBOL
+-0x1c787b32    eventfd_ctx_fileget     vmlinux EXPORT_SYMBOL_GPL
+-0x01139ffc    max_mapnr       vmlinux EXPORT_SYMBOL
+-0xec17ebb0    of_match_node   vmlinux EXPORT_SYMBOL
+-0x69ce0071    usb_driver_claim_interface      vmlinux EXPORT_SYMBOL_GPL
+-0x9cfd56c5    scsi_print_status       vmlinux EXPORT_SYMBOL
+-0xdce6abcd    drm_gem_prime_handle_to_fd      vmlinux EXPORT_SYMBOL
+-0x020f03b7    drm_sysfs_connector_remove      vmlinux EXPORT_SYMBOL
+-0x2a8aa04e    pinctrl_add_gpio_range  vmlinux EXPORT_SYMBOL_GPL
+-0x981dcc58    eventfd_fget    vmlinux EXPORT_SYMBOL_GPL
+-0x7c995f04    dget_parent     vmlinux EXPORT_SYMBOL
+-0x9a932b80    of_find_i2c_device_by_node      vmlinux EXPORT_SYMBOL
+-0x2b460363    led_trigger_set vmlinux EXPORT_SYMBOL_GPL
+-0x107733e3    wiphy_new       vmlinux EXPORT_SYMBOL
+-0xd7b7598e    snd_pcm_mmap_data       vmlinux EXPORT_SYMBOL
+-0x4e1636f1    mb_cache_create vmlinux EXPORT_SYMBOL
+-0x70bec618    iunique vmlinux EXPORT_SYMBOL
+-0x121d958a    unregister_die_notifier vmlinux EXPORT_SYMBOL_GPL
+-0xbef4c852    hid_dump_input  vmlinux EXPORT_SYMBOL_GPL
+-0x55423fc4    dm_requeue_unmapped_request     vmlinux EXPORT_SYMBOL_GPL
+-0x2e67fc27    matrix_keypad_build_keymap      vmlinux EXPORT_SYMBOL
+-0xe7c7c6b0    usb_disable_autosuspend vmlinux EXPORT_SYMBOL_GPL
+-0x783194cd    usb_get_dev     vmlinux EXPORT_SYMBOL_GPL
+-0x5614b010    xfrm_policy_walk_done   vmlinux EXPORT_SYMBOL
+-0x6d5a6c10    inet_dgram_ops  vmlinux EXPORT_SYMBOL
+-0x42e7ca3d    blk_alloc_queue vmlinux EXPORT_SYMBOL
+-0xfdbd0a9b    mb_cache_destroy        vmlinux EXPORT_SYMBOL
+-0x59cbc3ca    input_release_device    vmlinux EXPORT_SYMBOL
+-0xd0e5d6d2    scsi_put_command        vmlinux EXPORT_SYMBOL
+-0x480dca40    sec_reg_update  vmlinux EXPORT_SYMBOL_GPL
+-0x28a73d8e    snd_soc_unregister_card vmlinux EXPORT_SYMBOL_GPL
+-0x05fc144e    get_gendisk     vmlinux EXPORT_SYMBOL
+-0xfef8a166    trace_current_buffer_lock_reserve       vmlinux EXPORT_SYMBOL_GPL
+-0x7dccc294    proc_doulongvec_minmax  vmlinux EXPORT_SYMBOL
+-0x92c0c538    ieee80211_bss_get_ie    vmlinux EXPORT_SYMBOL
+-0x386ec802    tcp_proc_unregister     vmlinux EXPORT_SYMBOL
+-0xb327256f    simple_attr_open        vmlinux EXPORT_SYMBOL_GPL
+-0x56e9103b    cpu_pm_enter    vmlinux EXPORT_SYMBOL_GPL
+-0x1e48b59d    __css_tryget    vmlinux EXPORT_SYMBOL_GPL
+-0xbcbaa80a    __wake_up_locked_key    vmlinux EXPORT_SYMBOL_GPL
+-0x2d1b02d2    usermodehelper_read_lock_wait   vmlinux EXPORT_SYMBOL_GPL
+-0x72bfae4f    hwmon_device_register   vmlinux EXPORT_SYMBOL_GPL
+-0x3db7f213    v4l2_of_get_remote_port vmlinux EXPORT_SYMBOL
+-0x5de3f132    usb_interface_id        vmlinux EXPORT_SYMBOL_GPL
+-0x9ca5592b    usb_store_new_id        vmlinux EXPORT_SYMBOL_GPL
+-0x90fb0fa6    sdev_evt_send_simple    vmlinux EXPORT_SYMBOL_GPL
+-0x25892d59    drm_vblank_post_modeset vmlinux EXPORT_SYMBOL
+-0x8ecafd4a    drm_fb_helper_blank     vmlinux EXPORT_SYMBOL
+-0x590d45c1    sk_clear_memalloc       vmlinux EXPORT_SYMBOL_GPL
+-0x4578f528    __kfifo_to_user vmlinux EXPORT_SYMBOL
+-0xf7ddfd4e    done_path_create        vmlinux EXPORT_SYMBOL
+-0x85c10896    rcu_batches_completed_bh        vmlinux EXPORT_SYMBOL_GPL
+-0x036dd11a    cgroup_path     vmlinux EXPORT_SYMBOL_GPL
+-0xcc7fa952    local_bh_enable_ip      vmlinux EXPORT_SYMBOL
+-0xa90054ee    rndis_uninit    vmlinux EXPORT_SYMBOL
+-0x15407a03    usb_root_hub_lost_power vmlinux EXPORT_SYMBOL_GPL
+-0x06fc143d    xfrm4_rcv_encap vmlinux EXPORT_SYMBOL
+-0xa0c5538e    udp_poll        vmlinux EXPORT_SYMBOL
+-0xd9f41f16    skb_copy_ubufs  vmlinux EXPORT_SYMBOL_GPL
+-0xc83b4d5b    posix_acl_from_mode     vmlinux EXPORT_SYMBOL
+-0x51ef33b8    kstrndup        vmlinux EXPORT_SYMBOL
+-0x0bed814c    irq_set_chip    vmlinux EXPORT_SYMBOL
+-0xd0f6cf25    console_stop    vmlinux EXPORT_SYMBOL
+-0xd955eb7d    iommu_group_remove_device       vmlinux EXPORT_SYMBOL_GPL
+-0xfb5dc251    gserial_disconnect      vmlinux EXPORT_SYMBOL_GPL
+-0x42252607    inet6_getname   vmlinux EXPORT_SYMBOL
+-0xe65b1e97    nf_conntrack_tuple_taken        vmlinux EXPORT_SYMBOL_GPL
+-0x7abbee1e    wm_hubs_handle_analogue_pdata   vmlinux EXPORT_SYMBOL_GPL
+-0x06dceffb    snd_soc_of_parse_daifmt vmlinux EXPORT_SYMBOL_GPL
+-0xf4439247    snd_device_register     vmlinux EXPORT_SYMBOL
+-0xebcea57f    evict_bh_lrus   vmlinux EXPORT_SYMBOL_GPL
+-0x9714253c    mfd_add_devices vmlinux EXPORT_SYMBOL
+-0x26256356    drm_mode_equal_no_clocks        vmlinux EXPORT_SYMBOL
+-0x1be7f7c8    debugfs_create_file     vmlinux EXPORT_SYMBOL_GPL
+-0xdbb607c7    new_inode       vmlinux EXPORT_SYMBOL
+-0xa576c92e    drm_mode_config_reset   vmlinux EXPORT_SYMBOL
+-0x832ca829    snd_ctl_find_id vmlinux EXPORT_SYMBOL
+-0x65dccf13    xz_dec_end      vmlinux EXPORT_SYMBOL
+-0xf9348cbc    xz_dec_run      vmlinux EXPORT_SYMBOL
+-0xe0b13336    argv_free       vmlinux EXPORT_SYMBOL
+-0x8815b870    jbd2_journal_clear_err  vmlinux EXPORT_SYMBOL
+-0x861359ed    of_get_phy_mode vmlinux EXPORT_SYMBOL_GPL
+-0x28a2ed02    scsi_build_sense_buffer vmlinux EXPORT_SYMBOL
+-0x86240fb6    tty_port_close  vmlinux EXPORT_SYMBOL
+-0x8d3e24c6    genl_unregister_family  vmlinux EXPORT_SYMBOL
+-0x9d0d6206    unregister_netdevice_notifier   vmlinux EXPORT_SYMBOL
+-0x18640d1b    mmc_suspend_host        vmlinux EXPORT_SYMBOL
+-0x9082ce2b    tty_register_driver     vmlinux EXPORT_SYMBOL
+-0x71f65175    hdmi_spd_infoframe_pack vmlinux EXPORT_SYMBOL
+-0x3d6f0d06    ndo_dflt_fdb_del        vmlinux EXPORT_SYMBOL
+-0xaeefbeed    kset_unregister vmlinux EXPORT_SYMBOL
+-0xa498b92e    debugfs_create_u32      vmlinux EXPORT_SYMBOL_GPL
+-0x7ed8eb88    sdio_release_host       vmlinux EXPORT_SYMBOL_GPL
+-0xd1e4eed4    v4l2_fh_init    vmlinux EXPORT_SYMBOL_GPL
+-0x5b42ed42    v4l2_fh_exit    vmlinux EXPORT_SYMBOL_GPL
+-0x5947abbe    max77693_bulk_write     vmlinux EXPORT_SYMBOL_GPL
+-0x7afa1fc2    driver_remove_file      vmlinux EXPORT_SYMBOL_GPL
+-0xacefc84d    netdev_rx_handler_register      vmlinux EXPORT_SYMBOL_GPL
+-0xd2e829b5    jbd2_journal_release_jbd_inode  vmlinux EXPORT_SYMBOL
+-0xcd343f41    mmc_gpio_free_ro        vmlinux EXPORT_SYMBOL
+-0x26f37f1a    inet_csk_reset_keepalive_timer  vmlinux EXPORT_SYMBOL
+-0x49603fb8    security_sb_copy_data   vmlinux EXPORT_SYMBOL
+-0x53326531    mempool_alloc_pages     vmlinux EXPORT_SYMBOL
+-0x2b49351d    trace_define_field      vmlinux EXPORT_SYMBOL_GPL
+-0x47939e0d    __tasklet_hi_schedule   vmlinux EXPORT_SYMBOL
+-0x78c5a239    clk_prepare     vmlinux EXPORT_SYMBOL_GPL
+-0x1a36f8fd    udc_attach_driver       vmlinux EXPORT_SYMBOL_GPL
+-0xcb56fc45    dev_vprintk_emit        vmlinux EXPORT_SYMBOL
+-0xed2817be    arp_send        vmlinux EXPORT_SYMBOL
+-0x7d903146    xt_register_matches     vmlinux EXPORT_SYMBOL
+-0x3ed63055    zlib_inflateReset       vmlinux EXPORT_SYMBOL
+-0x281823c5    __kfifo_out_peek        vmlinux EXPORT_SYMBOL
+-0xb19760c3    bitmap_onto     vmlinux EXPORT_SYMBOL
+-0xaf9b8476    cdev_del        vmlinux EXPORT_SYMBOL
+-0xbc8da552    tcp_seq_open    vmlinux EXPORT_SYMBOL
+-0x35224ff2    pneigh_enqueue  vmlinux EXPORT_SYMBOL
+-0x0d2e0ab9    dev_alloc_name  vmlinux EXPORT_SYMBOL
+-0xebd8aaa8    iov_iter_copy_from_user vmlinux EXPORT_SYMBOL
+-0x134dc23b    v4l2_m2m_dqbuf  vmlinux EXPORT_SYMBOL_GPL
+-0x1cfa672b    soft_cursor     vmlinux EXPORT_SYMBOL
+-0xac8f37b2    outer_cache     vmlinux EXPORT_SYMBOL
+-0x744bfef9    generic_fh_to_dentry    vmlinux EXPORT_SYMBOL_GPL
+-0xa3225eb1    try_to_del_timer_sync   vmlinux EXPORT_SYMBOL
+-0x6a1733eb    iommu_group_unregister_notifier vmlinux EXPORT_SYMBOL_GPL
+-0xc84dae86    matrix_keypad_parse_of_params   vmlinux EXPORT_SYMBOL_GPL
+-0x404403a9    usb_free_all_descriptors        vmlinux EXPORT_SYMBOL_GPL
+-0x50eca283    ipcomp_output   vmlinux EXPORT_SYMBOL_GPL
+-0xe482d673    nf_ct_expect_related_report     vmlinux EXPORT_SYMBOL_GPL
+-0x26e58975    __pskb_copy     vmlinux EXPORT_SYMBOL
+-0xd3dcab0b    flex_array_alloc        vmlinux EXPORT_SYMBOL
+-0x247f1878    blk_queue_bounce        vmlinux EXPORT_SYMBOL
+-0x97b13dad    __clocksource_register_scale    vmlinux EXPORT_SYMBOL_GPL
+-0xdc73e48f    dm_unregister_target    vmlinux EXPORT_SYMBOL
+-0xfe0f06c0    tty_init_termios        vmlinux EXPORT_SYMBOL_GPL
+-0xb8356d30    dma_async_memcpy_buf_to_pg      vmlinux EXPORT_SYMBOL
+-0xd8d3cf00    read_dev_sector vmlinux EXPORT_SYMBOL
+-0x220669c4    scsi_cmd_blk_ioctl      vmlinux EXPORT_SYMBOL
+-0x03c91b88    crypto_alloc_instance2  vmlinux EXPORT_SYMBOL_GPL
+-0x4d9c0e6d    jbd2_journal_revoke     vmlinux EXPORT_SYMBOL
+-0xaca5e909    config_group_find_item  vmlinux EXPORT_SYMBOL
+-0xe01ba49b    iio_kfifo_allocate      vmlinux EXPORT_SYMBOL
+-0xe170917a    timed_output_dev_unregister     vmlinux EXPORT_SYMBOL_GPL
+-0x4f689046    brcmu_pkt_buf_free_skb  drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x932f03cb    security_old_inode_init_security        vmlinux EXPORT_SYMBOL
+-0xa4e5092b    debugfs_create_x16      vmlinux EXPORT_SYMBOL_GPL
+-0x1826f089    __tracepoint_kmem_cache_alloc_node      vmlinux EXPORT_SYMBOL
+-0xd81de62c    ring_buffer_record_enable       vmlinux EXPORT_SYMBOL_GPL
+-0xc7fe94dd    usb_ifnum_to_if vmlinux EXPORT_SYMBOL_GPL
+-0xc2af811e    inet6_destroy_sock      vmlinux EXPORT_SYMBOL_GPL
+-0x061651be    strcat  vmlinux EXPORT_SYMBOL
+-0xb39ec138    mb_cache_entry_release  vmlinux EXPORT_SYMBOL
+-0x51d559d1    _raw_spin_unlock_irqrestore     vmlinux EXPORT_SYMBOL
+-0xa6eb0e39    phy_device_create       vmlinux EXPORT_SYMBOL
+-0xf92c66be    drm_mm_search_free_generic      vmlinux EXPORT_SYMBOL
+-0x97270fcf    crypto_register_shash   vmlinux EXPORT_SYMBOL_GPL
+-0x495f2be4    jbd2_journal_get_write_access   vmlinux EXPORT_SYMBOL
+-0x3826f483    jbd2_journal_invalidatepage     vmlinux EXPORT_SYMBOL
+-0xd8a12f4d    iio_scan_mask_query     vmlinux EXPORT_SYMBOL_GPL
+-0x09b069ea    v4l2_ctrl_log_status    vmlinux EXPORT_SYMBOL
+-0x0a513c7c    usb_gadget_unregister_driver    vmlinux EXPORT_SYMBOL_GPL
+-0x39ef8cc9    dma_buf_kunmap  vmlinux EXPORT_SYMBOL_GPL
+-0xd28b5dda    dma_buf_vunmap  vmlinux EXPORT_SYMBOL_GPL
+-0x3fcf2826    inet6_unregister_protosw        vmlinux EXPORT_SYMBOL
+-0x551c3633    nf_nat_l4proto_unique_tuple     vmlinux EXPORT_SYMBOL_GPL
+-0x86700640    nf_register_hooks       vmlinux EXPORT_SYMBOL
+-0x44e94d6c    pfifo_qdisc_ops vmlinux EXPORT_SYMBOL
+-0xf202c5cb    radix_tree_insert       vmlinux EXPORT_SYMBOL
+-0x24ffe755    vfs_listxattr   vmlinux EXPORT_SYMBOL_GPL
+-0x52428cc8    parent_mem_cgroup       vmlinux EXPORT_SYMBOL
+-0x9d59c0f2    find_get_pages_contig   vmlinux EXPORT_SYMBOL
+-0x80f3268f    __trace_printk  vmlinux EXPORT_SYMBOL_GPL
+-0x22a27a85    st_sensors_spi_configure        vmlinux EXPORT_SYMBOL
+-0x7880c781    dm_kcopyd_prepare_callback      vmlinux EXPORT_SYMBOL
+-0xc53f0876    vb2_dma_contig_memops   vmlinux EXPORT_SYMBOL_GPL
+-0x388f9128    xfrm_state_walk_done    vmlinux EXPORT_SYMBOL
+-0x6d6888a7    qdisc_create_dflt       vmlinux EXPORT_SYMBOL
+-0x194ccf46    bmap    vmlinux EXPORT_SYMBOL
+-0xe2fae716    kmemdup vmlinux EXPORT_SYMBOL
+-0x07ed48c3    __blocking_notifier_call_chain  vmlinux EXPORT_SYMBOL_GPL
+-0x074d7047    st_sensors_trigger_handler      vmlinux EXPORT_SYMBOL
+-0x33883929    clk_divider_ops vmlinux EXPORT_SYMBOL_GPL
+-0xe2b92059    v4l2_video_std_construct        vmlinux EXPORT_SYMBOL
+-0x06ea1593    usbnet_defer_kevent     vmlinux EXPORT_SYMBOL_GPL
+-0x6650ad3e    uart_add_one_port       vmlinux EXPORT_SYMBOL
+-0x5dda183c    snd_soc_dapm_disable_pin        vmlinux EXPORT_SYMBOL_GPL
+-0x7a188791    prandom_bytes   vmlinux EXPORT_SYMBOL
+-0xc25a61ec    drm_mode_set_crtcinfo   vmlinux EXPORT_SYMBOL
+-0xcb1beab5    drm_mode_vrefresh       vmlinux EXPORT_SYMBOL
+-0x4a94168c    tcp_register_congestion_control vmlinux EXPORT_SYMBOL_GPL
+-0x4f5836c8    tcp_release_cb  vmlinux EXPORT_SYMBOL
+-0x2f366d34    tcp_gro_complete        vmlinux EXPORT_SYMBOL
+-0x1eba8ee6    nf_conntrack_alloc      vmlinux EXPORT_SYMBOL_GPL
+-0x28a903c8    timerqueue_add  vmlinux EXPORT_SYMBOL_GPL
+-0x96cea50b    sync_filesystem vmlinux EXPORT_SYMBOL_GPL
+-0x68c0685a    media_entity_setup_link vmlinux EXPORT_SYMBOL_GPL
+-0x69b83c18    usb_get_phy_dev vmlinux EXPORT_SYMBOL_GPL
+-0x7e6bf1b2    dma_buf_fd      vmlinux EXPORT_SYMBOL_GPL
+-0x4d974b9c    register_sysrq_key      vmlinux EXPORT_SYMBOL
+-0xf79531f4    tcp_connect     vmlinux EXPORT_SYMBOL
+-0x3f45ea36    neigh_table_clear       vmlinux EXPORT_SYMBOL
+-0xf6de842c    clk_get_parent  vmlinux EXPORT_SYMBOL_GPL
+-0x4782eebf    clk_set_parent  vmlinux EXPORT_SYMBOL_GPL
+-0x45a20c5a    of_phy_find_device      vmlinux EXPORT_SYMBOL
+-0xcbbedfcb    led_trigger_event       vmlinux EXPORT_SYMBOL_GPL
+-0x69281b40    thermal_zone_bind_cooling_device        vmlinux EXPORT_SYMBOL_GPL
+-0xe122af95    xfrm_aalg_get_byname    vmlinux EXPORT_SYMBOL_GPL
+-0x74b1375e    xfrm_state_flush        vmlinux EXPORT_SYMBOL
+-0x94098ff8    snd_interval_list       vmlinux EXPORT_SYMBOL
+-0x64f01d42    fuse_put_request        vmlinux EXPORT_SYMBOL_GPL
+-0x1811ac2f    fat_flush_inodes        vmlinux EXPORT_SYMBOL_GPL
+-0x73198f14    mmc_align_data_size     vmlinux EXPORT_SYMBOL
+-0xa70df32d    drm_fb_helper_fill_var  vmlinux EXPORT_SYMBOL
+-0x209e95ea    xfrm_find_acq_byseq     vmlinux EXPORT_SYMBOL
+-0x4b9e2d58    xfrm_policy_unregister_afinfo   vmlinux EXPORT_SYMBOL
+-0x461a1d6a    __rtnl_af_register      vmlinux EXPORT_SYMBOL_GPL
+-0x09c55cec    schedule_timeout_interruptible  vmlinux EXPORT_SYMBOL
+-0xf512c668    iio_trigger_free        vmlinux EXPORT_SYMBOL
+-0xdac28b43    dw_mci_resume   vmlinux EXPORT_SYMBOL
+-0x361e2bcc    save_stack_trace        vmlinux EXPORT_SYMBOL_GPL
+-0x25e6af56    snd_compress_register   vmlinux EXPORT_SYMBOL_GPL
+-0x1ace138d    bitmap_allocate_region  vmlinux EXPORT_SYMBOL
+-0x250113b4    memory_read_from_buffer vmlinux EXPORT_SYMBOL
+-0x4ae22649    iommu_set_fault_handler vmlinux EXPORT_SYMBOL_GPL
+-0x3ca38e3a    rndis_signal_connect    vmlinux EXPORT_SYMBOL
+-0x9d01b017    dma_buf_attach  vmlinux EXPORT_SYMBOL_GPL
+-0x3930a5b6    dma_buf_detach  vmlinux EXPORT_SYMBOL_GPL
+-0x2aec4354    hci_alloc_dev   vmlinux EXPORT_SYMBOL
+-0xbb5d343d    xfrm_get_acqseq vmlinux EXPORT_SYMBOL
+-0x4082abfe    __scsi_iterate_devices  vmlinux EXPORT_SYMBOL
+-0x6b6d7375    drm_timestamp_precision vmlinux EXPORT_SYMBOL
+-0x7ffcb57f    ip6_tnl_get_cap vmlinux EXPORT_SYMBOL
+-0xccc812c3    dapm_clock_event        vmlinux EXPORT_SYMBOL_GPL
+-0x1a47bf65    blk_queue_bounce_limit  vmlinux EXPORT_SYMBOL
+-0xcc13c782    vb2_ioctl_streamon      vmlinux EXPORT_SYMBOL_GPL
+-0x8afddc98    spi_register_driver     vmlinux EXPORT_SYMBOL_GPL
+-0x17ae6853    platform_bus    vmlinux EXPORT_SYMBOL_GPL
+-0x72ac0290    exynos_drm_device_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0xf71ca112    skb_abort_seq_read      vmlinux EXPORT_SYMBOL
+-0x18bbe186    snd_soc_cnew    vmlinux EXPORT_SYMBOL_GPL
+-0x2b0ba2b0    scsi_sense_desc_find    vmlinux EXPORT_SYMBOL
+-0x8de13715    drm_format_vert_chroma_subsampling      vmlinux EXPORT_SYMBOL
+-0x06fe3b14    default_grn     vmlinux EXPORT_SYMBOL
+-0xee683d16    inet6_ioctl     vmlinux EXPORT_SYMBOL
+-0x47252a20    tcp_getsockopt  vmlinux EXPORT_SYMBOL
+-0x7027c3ad    tcp_setsockopt  vmlinux EXPORT_SYMBOL
+-0xb7f74966    rtnl_unicast    vmlinux EXPORT_SYMBOL
+-0x525971d4    snd_soc_update_bits_locked      vmlinux EXPORT_SYMBOL_GPL
+-0x6ef8fcd8    snd_pcm_format_linear   vmlinux EXPORT_SYMBOL
+-0x8f8f6e19    alloc_disk_node vmlinux EXPORT_SYMBOL
+-0x71c445f5    fuse_get_req    vmlinux EXPORT_SYMBOL_GPL
+-0xc41cff79    dequeue_signal  vmlinux EXPORT_SYMBOL_GPL
+-0x5d9d3491    v4l_match_dv_timings    vmlinux EXPORT_SYMBOL_GPL
+-0x829a8cac    drm_property_create_range       vmlinux EXPORT_SYMBOL
+-0xf3189246    __rtnl_af_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0x0d7e8390    crypto_ablkcipher_type  vmlinux EXPORT_SYMBOL_GPL
+-0xaf8e1608    ip6t_register_table     vmlinux EXPORT_SYMBOL
+-0xb1a1e40e    crypto_tfm_in_queue     vmlinux EXPORT_SYMBOL_GPL
+-0xc73f3f9a    fget_raw        vmlinux EXPORT_SYMBOL
+-0x71008581    atomic_notifier_call_chain      vmlinux EXPORT_SYMBOL_GPL
+-0x12bf1d5c    usbnet_device_suggests_idle     vmlinux EXPORT_SYMBOL
+-0x79b993ef    cfg80211_send_unprot_deauth     vmlinux EXPORT_SYMBOL
+-0xdacc53b2    spi_add_device  vmlinux EXPORT_SYMBOL_GPL
+-0xf5a5c913    backlight_device_unregister     vmlinux EXPORT_SYMBOL
+-0xadce320f    pinctrl_add_gpio_ranges vmlinux EXPORT_SYMBOL_GPL
+-0x0f8342e1    phy_pm_runtime_forbid   vmlinux EXPORT_SYMBOL_GPL
+-0xc0763484    rfkill_blocked  vmlinux EXPORT_SYMBOL
+-0xb0bad0e8    ip6_push_pending_frames vmlinux EXPORT_SYMBOL_GPL
+-0xfc02b7ad    sysctl_tcp_wmem vmlinux EXPORT_SYMBOL
+-0xac782342    nf_unregister_hook      vmlinux EXPORT_SYMBOL
+-0xa08421e0    dev_change_net_namespace        vmlinux EXPORT_SYMBOL_GPL
+-0x47c6d038    blk_queue_flush_queueable       vmlinux EXPORT_SYMBOL_GPL
+-0x2db8f309    blk_queue_rq_timeout    vmlinux EXPORT_SYMBOL_GPL
+-0x6fb277a1    flush_kernel_dcache_page        vmlinux EXPORT_SYMBOL
+-0x1d633e6a    tcp_twsk_destructor     vmlinux EXPORT_SYMBOL_GPL
+-0x7611866b    scm_detach_fds  vmlinux EXPORT_SYMBOL
+-0xd3b02cea    put_pid vmlinux EXPORT_SYMBOL_GPL
+-0xed20e404    iio_dealloc_pollfunc    vmlinux EXPORT_SYMBOL_GPL
+-0xba706bd7    samsung_pwm_lock        vmlinux EXPORT_SYMBOL
+-0x158b7724    media_entity_create_link        vmlinux EXPORT_SYMBOL_GPL
+-0x1172ce54    rtc_ktime_to_tm vmlinux EXPORT_SYMBOL_GPL
+-0xa286a234    snd_pcm_format_name     vmlinux EXPORT_SYMBOL_GPL
+-0xc7e39bca    ring_buffer_dropped_events_cpu  vmlinux EXPORT_SYMBOL_GPL
+-0xaa957320    posix_clock_register    vmlinux EXPORT_SYMBOL_GPL
+-0xad46dec2    of_count_phandle_with_args      vmlinux EXPORT_SYMBOL
+-0x7120d717    regmap_bulk_read        vmlinux EXPORT_SYMBOL_GPL
+-0xca56dea4    driver_find_device      vmlinux EXPORT_SYMBOL_GPL
+-0x9c9d19e7    blk_get_request vmlinux EXPORT_SYMBOL
+-0x2c790eff    usbnet_read_cmd_nopm    vmlinux EXPORT_SYMBOL_GPL
+-0xbb99125c    get_default_font        vmlinux EXPORT_SYMBOL
+-0x6e5cf115    cfg80211_inform_bss     vmlinux EXPORT_SYMBOL
+-0xce7a55c1    xfrm_ealg_get_byid      vmlinux EXPORT_SYMBOL_GPL
+-0x0cc1e40f    crypto_it_tab   vmlinux EXPORT_SYMBOL_GPL
+-0x3dc916b6    crypto_fl_tab   vmlinux EXPORT_SYMBOL_GPL
+-0x40d46b21    crypto_ft_tab   vmlinux EXPORT_SYMBOL_GPL
+-0x71dc9998    crypto_il_tab   vmlinux EXPORT_SYMBOL_GPL
+-0x837d0f0a    down_timeout    vmlinux EXPORT_SYMBOL
+-0x2cd7dd71    __cpufreq_driver_getavg vmlinux EXPORT_SYMBOL_GPL
+-0xee6b71c4    syscon_regmap_lookup_by_compatible      vmlinux EXPORT_SYMBOL_GPL
+-0xae77b400    device_pm_wait_for_dev  vmlinux EXPORT_SYMBOL_GPL
+-0x1d5a2494    nfnetlink_has_listeners vmlinux EXPORT_SYMBOL_GPL
+-0x3bd1b1f6    msecs_to_jiffies        vmlinux EXPORT_SYMBOL
+-0xfb09f255    cpufreq_frequency_table_target  vmlinux EXPORT_SYMBOL_GPL
+-0xb52e203b    snd_pcm_suspend_all     vmlinux EXPORT_SYMBOL
+-0xc1ec3550    blkdev_fsync    vmlinux EXPORT_SYMBOL
+-0x0ebe6f54    lookup_one_len  vmlinux EXPORT_SYMBOL
+-0x151404f6    misc_deregister vmlinux EXPORT_SYMBOL
+-0xb2856c71    inet6_bind      vmlinux EXPORT_SYMBOL
+-0xf68285c0    register_inetaddr_notifier      vmlinux EXPORT_SYMBOL
+-0x7afc9d8a    unregister_sound_mixer  vmlinux EXPORT_SYMBOL
+-0xd5d80496    atomic_dec_and_mutex_lock       vmlinux EXPORT_SYMBOL
+-0x4351577a    fb_parse_edid   vmlinux EXPORT_SYMBOL
+-0x68beb163    nf_ct_l3proto_pernet_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x7751fba7    nf_ct_l4proto_pernet_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x5cbe0b31    snd_pcm_lib_write       vmlinux EXPORT_SYMBOL
+-0x6cecc98a    devres_get      vmlinux EXPORT_SYMBOL_GPL
+-0x20925954    devres_add      vmlinux EXPORT_SYMBOL_GPL
+-0x99a9dfa6    ieee80211_data_to_8023  vmlinux EXPORT_SYMBOL
+-0x21036b2c    bt_accept_enqueue       vmlinux EXPORT_SYMBOL
+-0x0cd5a88b    sync_inodes_sb  vmlinux EXPORT_SYMBOL
+-0x7485e15e    unregister_chrdev_region        vmlinux EXPORT_SYMBOL
+-0x7e8ad403    generic_writepages      vmlinux EXPORT_SYMBOL
+-0x07cf3227    clk_fixed_rate_ops      vmlinux EXPORT_SYMBOL_GPL
+-0xf5463be8    led_trigger_blink_oneshot       vmlinux EXPORT_SYMBOL_GPL
+-0xdbf18207    v4l2_device_register_subdev     vmlinux EXPORT_SYMBOL_GPL
+-0x131a5ed7    regmap_del_irq_chip     vmlinux EXPORT_SYMBOL_GPL
+-0xb09c8d37    regmap_add_irq_chip     vmlinux EXPORT_SYMBOL_GPL
+-0x26f0453a    blk_set_default_limits  vmlinux EXPORT_SYMBOL
+-0xf21f8a44    blk_init_allocated_queue        vmlinux EXPORT_SYMBOL
+-0x60df1e3b    posix_acl_equiv_mode    vmlinux EXPORT_SYMBOL
+-0xc131c5dd    usb_add_phy     vmlinux EXPORT_SYMBOL_GPL
+-0x211c5b26    cdc_ncm_bind_common     vmlinux EXPORT_SYMBOL_GPL
+-0x61f6939e    drm_i2c_encoder_detect  vmlinux EXPORT_SYMBOL
+-0xd9f310b2    gpiochip_is_requested   vmlinux EXPORT_SYMBOL_GPL
+-0xb9639d32    rtnl_register   vmlinux EXPORT_SYMBOL_GPL
+-0xf2254dc3    sock_from_file  vmlinux EXPORT_SYMBOL
+-0x0f5455e2    snd_soc_info_enum_double        vmlinux EXPORT_SYMBOL_GPL
+-0xdd89a6bf    lookup_bdev     vmlinux EXPORT_SYMBOL
+-0x55704318    clockevents_config_and_register vmlinux EXPORT_SYMBOL_GPL
+-0x2fd8cba9    freeze_wake     vmlinux EXPORT_SYMBOL_GPL
+-0x071b7eea    irq_stat        vmlinux EXPORT_SYMBOL
+-0x7a8ca627    xfrm_count_pfkey_enc_supported  vmlinux EXPORT_SYMBOL_GPL
+-0x1ff2a733    raw_seq_stop    vmlinux EXPORT_SYMBOL_GPL
+-0x85b825e7    gnet_stats_copy_basic   vmlinux EXPORT_SYMBOL
+-0x0cfefe1e    percpu_counter_destroy  vmlinux EXPORT_SYMBOL
+-0x02ea69e2    vm_map_ram      vmlinux EXPORT_SYMBOL
+-0x36eb3583    filemap_fdatawrite_range        vmlinux EXPORT_SYMBOL
+-0xb977cf42    inet_sendmsg    vmlinux EXPORT_SYMBOL
+-0xddbcead7    ip_cmsg_recv    vmlinux EXPORT_SYMBOL
+-0xb9a64b20    elevator_alloc  vmlinux EXPORT_SYMBOL
+-0xbcaf3971    crypto_alg_sem  vmlinux EXPORT_SYMBOL_GPL
+-0xe71dab2c    bio_sector_offset       vmlinux EXPORT_SYMBOL
+-0x2c44797e    hidinput_report_event   vmlinux EXPORT_SYMBOL_GPL
+-0x5d9e8570    drm_display_mode_from_videomode vmlinux EXPORT_SYMBOL_GPL
+-0x2b8e67cd    fuse_get_req_for_background     vmlinux EXPORT_SYMBOL_GPL
+-0x2b1c6816    extcon_dev_register     vmlinux EXPORT_SYMBOL_GPL
+-0xdef26358    dw_mci_probe    vmlinux EXPORT_SYMBOL
+-0xcbde0d9d    inverse_translate       vmlinux EXPORT_SYMBOL_GPL
+-0x056ee730    ipv6_hash_secret        vmlinux EXPORT_SYMBOL
+-0xfe029963    unregister_inetaddr_notifier    vmlinux EXPORT_SYMBOL
+-0x650a6767    prandom_u32_state       vmlinux EXPORT_SYMBOL
+-0x4148a5ff    get_kernel_pages        vmlinux EXPORT_SYMBOL_GPL
+-0x24d3448d    perf_event_enable       vmlinux EXPORT_SYMBOL_GPL
+-0x1c5a04e0    irq_domain_generate_simple      vmlinux EXPORT_SYMBOL_GPL
+-0xb7b4232a    unregister_exec_domain  vmlinux EXPORT_SYMBOL
+-0xd6f86c04    amba_release_regions    vmlinux EXPORT_SYMBOL
+-0x89d5538d    fb_pad_aligned_buffer   vmlinux EXPORT_SYMBOL
+-0x93237692    nobh_write_begin        vmlinux EXPORT_SYMBOL
+-0x920eb90c    interruptible_sleep_on_timeout  vmlinux EXPORT_SYMBOL
+-0x3a36ce8c    od_register_powersave_bias_handler      vmlinux EXPORT_SYMBOL_GPL
+-0x946b8b6c    netlink_ack     vmlinux EXPORT_SYMBOL
+-0x1000be5b    sock_no_bind    vmlinux EXPORT_SYMBOL
+-0x1e5479ed    sock_get_timestamp      vmlinux EXPORT_SYMBOL
+-0x4211c3c1    zlib_inflateInit2       vmlinux EXPORT_SYMBOL
+-0x2486141e    bio_alloc_pages vmlinux EXPORT_SYMBOL
+-0x62fd6207    param_set_charp vmlinux EXPORT_SYMBOL
+-0x0862d814    v4l2_event_unsubscribe_all      vmlinux EXPORT_SYMBOL_GPL
+-0x2f10e618    v4l2_event_queue_fh     vmlinux EXPORT_SYMBOL_GPL
+-0x6bdcfd99    qdisc_class_hash_remove vmlinux EXPORT_SYMBOL
+-0xf070e888    __put_net       vmlinux EXPORT_SYMBOL_GPL
+-0x8df3789f    snd_oss_info_register   vmlinux EXPORT_SYMBOL
+-0x68c73797    fuse_request_alloc      vmlinux EXPORT_SYMBOL_GPL
+-0x2342f1ae    v4l2_prio_open  vmlinux EXPORT_SYMBOL
+-0x4ddaa6ea    dmam_alloc_noncoherent  vmlinux EXPORT_SYMBOL
+-0x7dfdf9a1    transport_destroy_device        vmlinux EXPORT_SYMBOL_GPL
+-0x8c510862    drm_find_cea_extension  vmlinux EXPORT_SYMBOL
+-0x7c0267ee    serial8250_tx_chars     vmlinux EXPORT_SYMBOL_GPL
+-0x6879e81d    display_entity_put      vmlinux EXPORT_SYMBOL_GPL
+-0xf19a455d    lro_flush_pkt   vmlinux EXPORT_SYMBOL
+-0xbf8ba54a    vprintk vmlinux EXPORT_SYMBOL
+-0x7bd1de14    thermal_cdev_update     vmlinux EXPORT_SYMBOL
+-0x2631d719    tty_unregister_device   vmlinux EXPORT_SYMBOL
+-0xa7e7f050    __udp4_lib_lookup       vmlinux EXPORT_SYMBOL_GPL
+-0x2e2ce9e0    sysctl_tcp_syncookies   vmlinux EXPORT_SYMBOL
+-0xd5a8fd58    tcp_poll        vmlinux EXPORT_SYMBOL
+-0x3f74afb9    nf_ct_l3proto_register  vmlinux EXPORT_SYMBOL_GPL
+-0xb4998fd0    nf_ct_l4proto_register  vmlinux EXPORT_SYMBOL_GPL
+-0x2482e688    vsprintf        vmlinux EXPORT_SYMBOL
+-0x59e4b703    generic_splice_sendpage vmlinux EXPORT_SYMBOL
+-0x1795a16b    __genl_register_family_with_ops vmlinux EXPORT_SYMBOL
+-0xcb469d2b    ddebug_add_module       vmlinux EXPORT_SYMBOL_GPL
+-0xa2d83f8b    grab_cache_page_write_begin     vmlinux EXPORT_SYMBOL
+-0x8c930a68    rt_mutex_lock_interruptible     vmlinux EXPORT_SYMBOL_GPL
+-0xcc0871f2    attribute_container_find_class_device   vmlinux EXPORT_SYMBOL_GPL
+-0x13b52797    pwm_request_from_chip   vmlinux EXPORT_SYMBOL_GPL
+-0x28118cb6    __get_user_1    vmlinux EXPORT_SYMBOL
+-0xbb72d4fe    __put_user_1    vmlinux EXPORT_SYMBOL
+-0x0cae232b    utf16s_to_utf8s vmlinux EXPORT_SYMBOL
+-0x617a218d    __cond_resched_lock     vmlinux EXPORT_SYMBOL
+-0x44224883    __put_task_struct       vmlinux EXPORT_SYMBOL_GPL
+-0xbc65845b    class_create_file       vmlinux EXPORT_SYMBOL_GPL
+-0xe459c49b    unregister_pernet_subsys        vmlinux EXPORT_SYMBOL_GPL
+-0xd882a162    wait_on_sync_kiocb      vmlinux EXPORT_SYMBOL
+-0x28acb0e5    simple_write_begin      vmlinux EXPORT_SYMBOL
+-0x5c1cb07e    redirty_page_for_writepage      vmlinux EXPORT_SYMBOL
+-0x6070a6fb    bdi_set_max_ratio       vmlinux EXPORT_SYMBOL
+-0xfee43a69    drm_dp_get_adjust_request_voltage       vmlinux EXPORT_SYMBOL
+-0x8ffe7e89    nf_conntrack_htable_size        vmlinux EXPORT_SYMBOL_GPL
+-0x79c527b0    netdev_emerg    vmlinux EXPORT_SYMBOL
+-0x0bc7142a    sk_stream_kill_queues   vmlinux EXPORT_SYMBOL
+-0xeb37101c    audit_log_end   vmlinux EXPORT_SYMBOL
+-0xc3577d50    dev_set_name    vmlinux EXPORT_SYMBOL_GPL
+-0x6d40a921    need_ipv4_conntrack     vmlinux EXPORT_SYMBOL_GPL
+-0x6b98f5bd    __sk_dst_check  vmlinux EXPORT_SYMBOL
+-0x003ed69a    __kfifo_dma_in_prepare  vmlinux EXPORT_SYMBOL
+-0xd27b25dd    blk_check_plugged       vmlinux EXPORT_SYMBOL
+-0x9e093f78    elv_register_queue      vmlinux EXPORT_SYMBOL
+-0x716265c7    debugfs_initialized     vmlinux EXPORT_SYMBOL_GPL
+-0x8e19dd86    of_platform_populate    vmlinux EXPORT_SYMBOL_GPL
+-0x2a4ee199    v4l2_m2m_job_finish     vmlinux EXPORT_SYMBOL
+-0x8c62225c    usb_queue_reset_device  vmlinux EXPORT_SYMBOL_GPL
+-0x1e837252    drm_mm_scan_add_block   vmlinux EXPORT_SYMBOL
+-0x6c9424d9    snd_pcm_lib_preallocate_pages   vmlinux EXPORT_SYMBOL
+-0x4c759827    byte_rev_table  vmlinux EXPORT_SYMBOL_GPL
+-0xdf7090e0    __elv_add_request       vmlinux EXPORT_SYMBOL
+-0x911010cb    skcipher_geniv_init     vmlinux EXPORT_SYMBOL_GPL
+-0x9bd700dd    set_bh_page     vmlinux EXPORT_SYMBOL
+-0x13a2a2e3    free_user_ns    vmlinux EXPORT_SYMBOL
+-0x4fe8770d    usb_interrupt_msg       vmlinux EXPORT_SYMBOL_GPL
+-0x0d7dd3fc    pm_generic_runtime_resume       vmlinux EXPORT_SYMBOL_GPL
+-0x3df0b6c5    bus_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0x131f636c    nf_nat_l4proto_in_range vmlinux EXPORT_SYMBOL_GPL
+-0xe6643a60    snd_soc_dpcm_be_can_update      vmlinux EXPORT_SYMBOL_GPL
+-0x059c8bf5    snd_soc_dpcm_fe_can_update      vmlinux EXPORT_SYMBOL_GPL
+-0xe914e41e    strcpy  vmlinux EXPORT_SYMBOL
+-0x27235c89    crypto_destroy_tfm      vmlinux EXPORT_SYMBOL_GPL
+-0xe44b1603    sysfs_remove_link_from_group    vmlinux EXPORT_SYMBOL_GPL
+-0x1dff6af1    filemap_fault   vmlinux EXPORT_SYMBOL
+-0xb1d9aabd    lg_local_unlock_cpu     vmlinux EXPORT_SYMBOL
+-0x59d9c8d7    jack_get_data   vmlinux EXPORT_SYMBOL_GPL
+-0x7a91726b    clkdev_alloc    vmlinux EXPORT_SYMBOL
+-0x6138cad8    nfc_tm_deactivated      vmlinux EXPORT_SYMBOL
+-0xe50e65bf    blocking_notifier_chain_register        vmlinux EXPORT_SYMBOL_GPL
+-0x9acf72e4    rndis_set_param_medium  vmlinux EXPORT_SYMBOL
+-0x677428bf    sdev_enable_disk_events vmlinux EXPORT_SYMBOL
+-0x45ef1157    tty_pair_get_tty        vmlinux EXPORT_SYMBOL
+-0x4338e523    tty_pair_get_pty        vmlinux EXPORT_SYMBOL
+-0x51c0d211    fb_get_buffer_offset    vmlinux EXPORT_SYMBOL
+-0xe7f26347    skb_unlink      vmlinux EXPORT_SYMBOL
+-0xc3f69ac2    crypto_register_template        vmlinux EXPORT_SYMBOL_GPL
+-0x00fe8031    fuse_abort_conn vmlinux EXPORT_SYMBOL_GPL
+-0x3dc45692    vm_iomap_memory vmlinux EXPORT_SYMBOL
+-0xc41f0516    node_states     vmlinux EXPORT_SYMBOL
+-0x6a5fb566    rcu_sched_force_quiescent_state vmlinux EXPORT_SYMBOL_GPL
+-0xc89e91fb    irq_setup_alt_chip      vmlinux EXPORT_SYMBOL_GPL
+-0xe8a39d68    vb2_ioctl_streamoff     vmlinux EXPORT_SYMBOL_GPL
+-0xb2e5ae4a    snd_lookup_minor_data   vmlinux EXPORT_SYMBOL
+-0xaafd1f6c    iio_triggered_buffer_setup      vmlinux EXPORT_SYMBOL
+-0x4b17b645    of_property_read_u16_array      vmlinux EXPORT_SYMBOL_GPL
+-0xdac11bae    of_property_read_u32_array      vmlinux EXPORT_SYMBOL_GPL
+-0x5641485b    tty_termios_encode_baud_rate    vmlinux EXPORT_SYMBOL_GPL
+-0x85d549dc    s3c_gpio_getcfg vmlinux EXPORT_SYMBOL
+-0x1189692c    inet_csk_delete_keepalive_timer vmlinux EXPORT_SYMBOL
+-0xbec25473    of_parse_phandle        vmlinux EXPORT_SYMBOL
+-0x53f0b470    dev_pm_qos_add_ancestor_request vmlinux EXPORT_SYMBOL_GPL
+-0x0ddc826c    drm_fb_helper_set_par   vmlinux EXPORT_SYMBOL
+-0x64bb0960    cfg80211_wext_giwmode   vmlinux EXPORT_SYMBOL_GPL
+-0xd4cc3fbd    cfg80211_wext_giwname   vmlinux EXPORT_SYMBOL_GPL
+-0x8697617d    cfg80211_wext_siwmode   vmlinux EXPORT_SYMBOL_GPL
+-0xe3643cca    cfg80211_send_auth_timeout      vmlinux EXPORT_SYMBOL
+-0x377db989    xfrm_state_register_afinfo      vmlinux EXPORT_SYMBOL
+-0x2cdca56b    usb_register_device_driver      vmlinux EXPORT_SYMBOL_GPL
+-0x7f9066b4    subsys_interface_unregister     vmlinux EXPORT_SYMBOL_GPL
+-0xfbc8e9a2    regulatory_hint vmlinux EXPORT_SYMBOL
+-0xbdf0ff3a    wiphy_rfkill_start_polling      vmlinux EXPORT_SYMBOL
+-0x74631c0e    inet_ioctl      vmlinux EXPORT_SYMBOL
+-0x5cbe31bd    snd_soc_dapm_mixer_update_power vmlinux EXPORT_SYMBOL_GPL
+-0x5a3c2afd    kobject_get_path        vmlinux EXPORT_SYMBOL_GPL
+-0xd8ce7e67    clocksource_register    vmlinux EXPORT_SYMBOL
+-0x802c194a    of_device_register      vmlinux EXPORT_SYMBOL
+-0x0c8c9e99    scsi_show_extd_sense    vmlinux EXPORT_SYMBOL
+-0x2155f85c    bt_sock_link    vmlinux EXPORT_SYMBOL
+-0x0ccfae80    xt_register_target      vmlinux EXPORT_SYMBOL
+-0x6f20960a    full_name_hash  vmlinux EXPORT_SYMBOL
+-0xcded9074    phy_drivers_register    vmlinux EXPORT_SYMBOL
+-0xae5ba460    ping_prot       vmlinux EXPORT_SYMBOL
+-0x814e7730    nf_ct_destroy   vmlinux EXPORT_SYMBOL
+-0xe8279caa    nf_unregister_hooks     vmlinux EXPORT_SYMBOL
+-0x8810ad5e    crypto_xor      vmlinux EXPORT_SYMBOL_GPL
+-0x45bf1ff3    crypto_inc      vmlinux EXPORT_SYMBOL_GPL
+-0x5ac71347    wait_for_stable_page    vmlinux EXPORT_SYMBOL_GPL
+-0xe07ca631    cpu_bit_bitmap  vmlinux EXPORT_SYMBOL_GPL
+-0x9c5bf378    pm_generic_freeze       vmlinux EXPORT_SYMBOL_GPL
+-0x50bd1b27    device_create_vargs     vmlinux EXPORT_SYMBOL_GPL
+-0x30775773    drm_bl_unregister       vmlinux EXPORT_SYMBOL_GPL
+-0xf4f3abb6    tty_port_hangup vmlinux EXPORT_SYMBOL
+-0xca0bdf70    framebuffer_release     vmlinux EXPORT_SYMBOL
+-0x86743fc9    touch_buffer    vmlinux EXPORT_SYMBOL
+-0x5671b6e0    iio_triggered_buffer_predisable vmlinux EXPORT_SYMBOL
+-0x2eb9cd44    brcmu_pktq_init drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x77c7a73e    wiphy_apply_custom_regulatory   vmlinux EXPORT_SYMBOL
+-0xd796d321    fat_getattr     vmlinux EXPORT_SYMBOL_GPL
+-0x41e95f70    fat_setattr     vmlinux EXPORT_SYMBOL_GPL
+-0x2750ffee    generic_read_dir        vmlinux EXPORT_SYMBOL
+-0x00c3b7ed    dentry_unhash   vmlinux EXPORT_SYMBOL
+-0xe007de41    kallsyms_lookup_name    vmlinux EXPORT_SYMBOL_GPL
+-0x43f23311    dm_table_get_md vmlinux EXPORT_SYMBOL
+-0x9db747a3    usb_hcd_poll_rh_status  vmlinux EXPORT_SYMBOL_GPL
+-0xfd1cd45b    dev_pm_qos_hide_flags   vmlinux EXPORT_SYMBOL_GPL
+-0xe15b1685    device_find_child       vmlinux EXPORT_SYMBOL_GPL
+-0x1a022e5e    truncate_pagecache      vmlinux EXPORT_SYMBOL
+-0x26b71fb4    ring_buffer_time_stamp  vmlinux EXPORT_SYMBOL_GPL
+-0x4e6a500f    phy_pm_runtime_get      vmlinux EXPORT_SYMBOL_GPL
+-0x056bb269    xfrm_ealg_get_byidx     vmlinux EXPORT_SYMBOL_GPL
+-0x094585f4    sock_no_shutdown        vmlinux EXPORT_SYMBOL
+-0x0a5ea478    __generic_block_fiemap  vmlinux EXPORT_SYMBOL
+-0xb1acbcce    rcu_barrier_sched       vmlinux EXPORT_SYMBOL_GPL
+-0x3924dd56    try_wait_for_completion vmlinux EXPORT_SYMBOL
+-0x8f7014a1    param_set_ulong vmlinux EXPORT_SYMBOL
+-0xee2d0fc7    _local_bh_enable        vmlinux EXPORT_SYMBOL
+-0x34e8e0a0    of_device_unregister    vmlinux EXPORT_SYMBOL
+-0xbed3ee5e    watchdog_register_device        vmlinux EXPORT_SYMBOL_GPL
+-0x16244fe5    v4l2_prio_check vmlinux EXPORT_SYMBOL
+-0x324a8332    vc_resize       vmlinux EXPORT_SYMBOL
+-0xb410d84f    phy_put vmlinux EXPORT_SYMBOL_GPL
+-0xa41b1e49    phy_pm_runtime_put_sync vmlinux EXPORT_SYMBOL_GPL
+-0xb3d5242c    nf_ct_expect_alloc      vmlinux EXPORT_SYMBOL_GPL
+-0xbdfe32cf    sysfs_unmerge_group     vmlinux EXPORT_SYMBOL_GPL
+-0xdb04cacc    tracepoint_probe_unregister_noupdate    vmlinux EXPORT_SYMBOL_GPL
+-0x481ce6ce    cpu_active_mask vmlinux EXPORT_SYMBOL
+-0x78f47a5c    drm_kms_helper_poll_init        vmlinux EXPORT_SYMBOL
+-0x62827bec    security_secctx_to_secid        vmlinux EXPORT_SYMBOL
+-0xcb97ad8c    bus_find_device_by_name vmlinux EXPORT_SYMBOL_GPL
+-0x427dce2d    drm_put_minor   vmlinux EXPORT_SYMBOL
+-0xf7b743b5    drm_calc_timestamping_constants vmlinux EXPORT_SYMBOL
+-0x62746f06    video_source_unregister vmlinux EXPORT_SYMBOL_GPL
+-0xacde6340    inet_peer_xrlim_allow   vmlinux EXPORT_SYMBOL
+-0xd4b0b600    nf_ct_attach    vmlinux EXPORT_SYMBOL
+-0x3e1314f1    snd_timer_global_free   vmlinux EXPORT_SYMBOL
+-0xd37725bb    register_user_hw_breakpoint     vmlinux EXPORT_SYMBOL_GPL
+-0x4f741917    devm_phy_put    vmlinux EXPORT_SYMBOL_GPL
+-0xe5ed5467    xfrm_policy_walk_init   vmlinux EXPORT_SYMBOL
+-0xfd6eefb8    nf_nat_decode_session_hook      vmlinux EXPORT_SYMBOL
+-0x82627707    snd_pcm_lib_writev      vmlinux EXPORT_SYMBOL
+-0x28b2dd21    textsearch_register     vmlinux EXPORT_SYMBOL
+-0x74baf17a    tracing_is_on   vmlinux EXPORT_SYMBOL_GPL
+-0x381a798a    setup_max_cpus  vmlinux EXPORT_SYMBOL
+-0xf442e8f8    commit_creds    vmlinux EXPORT_SYMBOL
+-0xab598227    driver_attach   vmlinux EXPORT_SYMBOL_GPL
+-0xa1d5de65    drm_mode_connector_list_update  vmlinux EXPORT_SYMBOL
+-0xf3f5690b    __nf_ct_expect_find     vmlinux EXPORT_SYMBOL_GPL
+-0xad0413d4    match_hex       vmlinux EXPORT_SYMBOL
+-0xbfdbee53    usbnet_generic_cdc_bind vmlinux EXPORT_SYMBOL_GPL
+-0x329edb99    platform_device_register        vmlinux EXPORT_SYMBOL_GPL
+-0x80d68d3e    fb_register_client      vmlinux EXPORT_SYMBOL
+-0x3638b44e    __inet_lookup_listener  vmlinux EXPORT_SYMBOL_GPL
+-0x89636597    nf_unregister_sockopt   vmlinux EXPORT_SYMBOL
+-0xadac214f    __skb_get_rxhash        vmlinux EXPORT_SYMBOL
+-0x10ae54ba    skb_realloc_headroom    vmlinux EXPORT_SYMBOL
+-0xdaa5b6fe    generic_pipe_buf_get    vmlinux EXPORT_SYMBOL
+-0x461fff7e    generic_pipe_buf_map    vmlinux EXPORT_SYMBOL
+-0x36f9cd94    rcu_is_cpu_idle vmlinux EXPORT_SYMBOL
+-0x4102e3db    media_entity_find_link  vmlinux EXPORT_SYMBOL_GPL
+-0xcd0e7389    platform_device_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0xf86dc7d7    serial8250_set_isa_configurator vmlinux EXPORT_SYMBOL
+-0xbe1c5d4d    ipv6_find_hdr   vmlinux EXPORT_SYMBOL
+-0xc6ed2b40    jbd2_journal_dirty_metadata     vmlinux EXPORT_SYMBOL
+-0x77df0847    __set_personality       vmlinux EXPORT_SYMBOL
+-0x92c6523d    tty_port_close_end      vmlinux EXPORT_SYMBOL
+-0x78843287    blkcipher_walk_done     vmlinux EXPORT_SYMBOL_GPL
+-0x96f90809    page_readlink   vmlinux EXPORT_SYMBOL
+-0xc7c4f4ed    account_page_writeback  vmlinux EXPORT_SYMBOL
+-0xa1edf7f3    drm_core_ioremap_wc     vmlinux EXPORT_SYMBOL
+-0x08ad3fc2    register_con_driver     vmlinux EXPORT_SYMBOL
+-0x676bbc0f    _set_bit        vmlinux EXPORT_SYMBOL
+-0xd46c9ca5    nf_unregister_afinfo    vmlinux EXPORT_SYMBOL_GPL
+-0xf5eb86ea    blk_verify_command      vmlinux EXPORT_SYMBOL
+-0xc499ae1e    kstrdup vmlinux EXPORT_SYMBOL
+-0x2aa1ad41    _raw_write_lock_irq     vmlinux EXPORT_SYMBOL
+-0xb5b7345d    freezing_slow_path      vmlinux EXPORT_SYMBOL
+-0xe505e34f    mmc_start_bkops vmlinux EXPORT_SYMBOL
+-0x1dd571e6    fb_copy_cmap    vmlinux EXPORT_SYMBOL
+-0x0d4d7a32    _atomic_dec_and_lock    vmlinux EXPORT_SYMBOL
+-0x11c9185c    of_iomap        vmlinux EXPORT_SYMBOL
+-0xf918f7de    xfrm_register_km        vmlinux EXPORT_SYMBOL
+-0xde4bc28c    ip_mc_dec_group vmlinux EXPORT_SYMBOL
+-0x03f12ac0    snd_soc_dapm_mux_update_power   vmlinux EXPORT_SYMBOL_GPL
+-0x733c3b54    kasprintf       vmlinux EXPORT_SYMBOL
+-0x8aaa8b57    simple_rename   vmlinux EXPORT_SYMBOL
+-0x512579ee    vfs_setxattr    vmlinux EXPORT_SYMBOL_GPL
+-0x3d8f75d6    vfs_getxattr    vmlinux EXPORT_SYMBOL_GPL
+-0xcb7131fb    fb_get_options  vmlinux EXPORT_SYMBOL
+-0xd49c7d00    phy_init        vmlinux EXPORT_SYMBOL_GPL
+-0xf8c54a02    sock_init_data  vmlinux EXPORT_SYMBOL
+-0x1209a558    snd_ctl_free_one        vmlinux EXPORT_SYMBOL
+-0xe02eb6d0    ring_buffer_commit_overrun_cpu  vmlinux EXPORT_SYMBOL_GPL
+-0x3a536bd7    ring_buffer_read_finish vmlinux EXPORT_SYMBOL_GPL
+-0x9c0bd51f    _raw_spin_lock  vmlinux EXPORT_SYMBOL
+-0xcf7c760d    mmc_send_ext_csd        vmlinux EXPORT_SYMBOL_GPL
+-0x0f7cb7fa    tty_set_termios vmlinux EXPORT_SYMBOL_GPL
+-0x86ffe7d1    ip_queue_xmit   vmlinux EXPORT_SYMBOL
+-0xc30b3a36    scatterwalk_map vmlinux EXPORT_SYMBOL_GPL
+-0x23532c4d    ftrace_print_flags_seq  vmlinux EXPORT_SYMBOL
+-0x3500818d    v4l2_fh_open    vmlinux EXPORT_SYMBOL_GPL
+-0xadc7d94a    class_dev_iter_init     vmlinux EXPORT_SYMBOL_GPL
+-0xb95ec685    km_query        vmlinux EXPORT_SYMBOL
+-0xf569d921    inet_release    vmlinux EXPORT_SYMBOL
+-0x4251ff78    nf_ct_helper_expectfn_register  vmlinux EXPORT_SYMBOL_GPL
+-0xa3f35bf5    rwsem_is_locked vmlinux EXPORT_SYMBOL
+-0x518c4113    blk_queue_start_tag     vmlinux EXPORT_SYMBOL
+-0x299f45b9    jbd2_journal_force_commit       vmlinux EXPORT_SYMBOL
+-0x373db350    kstrtoint       vmlinux EXPORT_SYMBOL
+-0xfffad96c    call_srcu       vmlinux EXPORT_SYMBOL_GPL
+-0x4806c9d5    drm_connector_init      vmlinux EXPORT_SYMBOL
+-0x9fce80db    fb_notifier_call_chain  vmlinux EXPORT_SYMBOL_GPL
+-0x856629e7    __tracepoint_rpm_return_int     vmlinux EXPORT_SYMBOL_GPL
+-0x8f6cee77    __round_jiffies_relative        vmlinux EXPORT_SYMBOL_GPL
+-0xb992cdc2    cpufreq_get_policy      vmlinux EXPORT_SYMBOL
+-0x9a7784ef    v4l2_device_put vmlinux EXPORT_SYMBOL_GPL
+-0xab2d53fe    wm8994_reg_write        vmlinux EXPORT_SYMBOL_GPL
+-0xa7c124ba    inet_frag_maybe_warn_overflow   vmlinux EXPORT_SYMBOL
+-0x81cbdbae    inet_twsk_alloc vmlinux EXPORT_SYMBOL_GPL
+-0x037a0cba    kfree   vmlinux EXPORT_SYMBOL
+-0xfb0c30cd    __rt_mutex_init vmlinux EXPORT_SYMBOL_GPL
+-0x578a9e0d    kill_pid_info_as_cred   vmlinux EXPORT_SYMBOL_GPL
+-0xa8ca80b5    __serio_register_driver vmlinux EXPORT_SYMBOL
+-0x182a39a6    max8997_bulk_read       vmlinux EXPORT_SYMBOL_GPL
+-0x2fd9648c    pm_genpd_add_callbacks  vmlinux EXPORT_SYMBOL_GPL
+-0xc5c2a452    tty_put_char    vmlinux EXPORT_SYMBOL_GPL
+-0x49b60948    xfrm_state_delete       vmlinux EXPORT_SYMBOL
+-0x0693c220    nf_register_sockopt     vmlinux EXPORT_SYMBOL
+-0x8c9e0cae    sock_kmalloc    vmlinux EXPORT_SYMBOL
+-0xb9638db4    snd_pcm_rate_to_rate_bit        vmlinux EXPORT_SYMBOL
+-0xf3b3adff    cgroup_load_subsys      vmlinux EXPORT_SYMBOL_GPL
+-0x75911fdf    ip_tunnel_get_stats64   vmlinux EXPORT_SYMBOL_GPL
+-0xe7d4daac    seq_list_next   vmlinux EXPORT_SYMBOL
+-0x2fe252cc    unregister_inet6addr_notifier   vmlinux EXPORT_SYMBOL
+-0xa06df9e1    __kfifo_dma_out_finish_r        vmlinux EXPORT_SYMBOL
+-0x01e0e788    st_sensors_allocate_trigger     vmlinux EXPORT_SYMBOL
+-0xcdd15087    of_irq_map_one  vmlinux EXPORT_SYMBOL_GPL
+-0xea97422f    vb2_queue_release       vmlinux EXPORT_SYMBOL_GPL
+-0xb37c3615    cfg80211_rx_unexpected_4addr_frame      vmlinux EXPORT_SYMBOL
+-0xbc2271b2    ipv6_chk_addr   vmlinux EXPORT_SYMBOL
+-0x9e9ab99d    __blkdev_driver_ioctl   vmlinux EXPORT_SYMBOL_GPL
+-0x54f3cc64    blk_alloc_queue_node    vmlinux EXPORT_SYMBOL
+-0xd20b9da2    iio_buffer_unregister   vmlinux EXPORT_SYMBOL
+-0xa8f8abd2    v4l2_ctrl_g_ctrl_int64  vmlinux EXPORT_SYMBOL
+-0xc2aa0765    dev_pm_qos_flags        vmlinux EXPORT_SYMBOL_GPL
+-0xf5f14859    uart_suspend_port       vmlinux EXPORT_SYMBOL
+-0xe7722171    flex_array_free vmlinux EXPORT_SYMBOL
+-0xa27aead4    blk_queue_flush vmlinux EXPORT_SYMBOL_GPL
+-0x713c83fa    bio_phys_segments       vmlinux EXPORT_SYMBOL
+-0xdaa57ec3    totalhigh_pages vmlinux EXPORT_SYMBOL
+-0x2a2a7a3b    rndis_set_param_dev     vmlinux EXPORT_SYMBOL
+-0x54fd2e8d    scsi_device_resume      vmlinux EXPORT_SYMBOL
+-0x7a060e19    ipv6_find_tlv   vmlinux EXPORT_SYMBOL_GPL
+-0x8fe6ac1e    neigh_changeaddr        vmlinux EXPORT_SYMBOL
+-0xa38c2c00    snd_soc_jack_get_type   vmlinux EXPORT_SYMBOL_GPL
+-0x710c73b6    crypto_unregister_notifier      vmlinux EXPORT_SYMBOL_GPL
+-0xda0c24cc    invalidate_inode_pages2 vmlinux EXPORT_SYMBOL_GPL
+-0x72741f25    trace_vbprintk  vmlinux EXPORT_SYMBOL_GPL
+-0xccb0efda    do_unregister_con_driver        vmlinux EXPORT_SYMBOL_GPL
+-0xa120d33c    tty_unregister_ldisc    vmlinux EXPORT_SYMBOL
+-0xd644f377    tty_standard_install    vmlinux EXPORT_SYMBOL_GPL
+-0x31222024    amba_apb_device_add_res vmlinux EXPORT_SYMBOL_GPL
+-0xf8299259    cfg80211_michael_mic_failure    vmlinux EXPORT_SYMBOL
+-0xbe53b873    ipt_do_table    vmlinux EXPORT_SYMBOL
+-0xc96046ab    kmem_cache_destroy      vmlinux EXPORT_SYMBOL
+-0x79105e99    add_to_page_cache_locked        vmlinux EXPORT_SYMBOL
+-0x4e109192    ring_buffer_entries     vmlinux EXPORT_SYMBOL_GPL
+-0x82a5e5e7    led_classdev_register   vmlinux EXPORT_SYMBOL_GPL
+-0xd952a550    vb2_ioctl_reqbufs       vmlinux EXPORT_SYMBOL_GPL
+-0xcb929a3c    scsi_calculate_bounce_limit     vmlinux EXPORT_SYMBOL
+-0x33746f3f    xfrm_prepare_input      vmlinux EXPORT_SYMBOL
+-0xd1dc81ae    xt_find_target  vmlinux EXPORT_SYMBOL
+-0x92f468ad    drm_mode_object_find    vmlinux EXPORT_SYMBOL
+-0x5a268d54    drm_clflush_sg  vmlinux EXPORT_SYMBOL
+-0x827cc6a1    pptp_msg_name   vmlinux EXPORT_SYMBOL
+-0xd4433787    vm_event_states vmlinux EXPORT_SYMBOL
+-0x488b605d    __module_get    vmlinux EXPORT_SYMBOL
+-0x081f3afb    complete_all    vmlinux EXPORT_SYMBOL
+-0x9bce482f    __release_region        vmlinux EXPORT_SYMBOL
+-0xd007f03b    phy_mii_ioctl   vmlinux EXPORT_SYMBOL
+-0x5ef79e43    exynos_drm_subdrv_open  vmlinux EXPORT_SYMBOL_GPL
+-0x34b60845    nfc_alloc_recv_skb      vmlinux EXPORT_SYMBOL
+-0x075af6c0    cfg80211_reg_can_beacon vmlinux EXPORT_SYMBOL
+-0x347013de    nla_validate    vmlinux EXPORT_SYMBOL
+-0x70f6100f    bdi_register    vmlinux EXPORT_SYMBOL
+-0xcf54ea93    async_unregister_domain vmlinux EXPORT_SYMBOL_GPL
+-0xb6efaccd    rndis_rm_hdr    vmlinux EXPORT_SYMBOL
+-0x5ed040b0    pm_set_vt_switch        vmlinux EXPORT_SYMBOL
+-0x3ad0517a    tty_free_termios        vmlinux EXPORT_SYMBOL
+-0x5fa643a3    amba_device_alloc       vmlinux EXPORT_SYMBOL_GPL
+-0x73abc38f    inet_csk_clear_xmit_timers      vmlinux EXPORT_SYMBOL
+-0x52e3e4a5    snd_pcm_hw_param_value  vmlinux EXPORT_SYMBOL
+-0x7129e5f8    hex_asc vmlinux EXPORT_SYMBOL
+-0xa0973520    fat_time_unix2fat       vmlinux EXPORT_SYMBOL_GPL
+-0x522a28d0    mmc_regulator_get_supply        vmlinux EXPORT_SYMBOL_GPL
+-0xac84055a    nf_nat_follow_master    vmlinux EXPORT_SYMBOL
+-0x2aa0e4fc    strncasecmp     vmlinux EXPORT_SYMBOL
+-0x9d5dfdfe    fuse_dev_release        vmlinux EXPORT_SYMBOL_GPL
+-0xf54fdd41    default_llseek  vmlinux EXPORT_SYMBOL
+-0xebec57c4    ring_buffer_oldest_event_ts     vmlinux EXPORT_SYMBOL_GPL
+-0x329318c8    iio_channel_release_all vmlinux EXPORT_SYMBOL_GPL
+-0xfc9a70ae    tty_get_pgrp    vmlinux EXPORT_SYMBOL_GPL
+-0xdbf66d36    tcp_read_sock   vmlinux EXPORT_SYMBOL
+-0xc18db9a3    snd_jack_new    vmlinux EXPORT_SYMBOL
+-0x5df2ea54    sdhci_pltfm_free        vmlinux EXPORT_SYMBOL_GPL
+-0x137901ef    ip_fragment     vmlinux EXPORT_SYMBOL
+-0x815b5dd4    match_octal     vmlinux EXPORT_SYMBOL
+-0x6b475280    bio_map_kern    vmlinux EXPORT_SYMBOL
+-0x3abac74c    scsi_eh_prep_cmnd       vmlinux EXPORT_SYMBOL
+-0xd162929f    tty_port_register_device_attr   vmlinux EXPORT_SYMBOL_GPL
+-0x296f9f79    xt_register_targets     vmlinux EXPORT_SYMBOL
+-0x27000b29    crc32c  vmlinux EXPORT_SYMBOL
+-0x2956cef1    vfs_fsync       vmlinux EXPORT_SYMBOL
+-0x18ae03d3    poll_freewait   vmlinux EXPORT_SYMBOL
+-0x40c7247c    si_meminfo      vmlinux EXPORT_SYMBOL
+-0x0034e52c    kthread_create_on_node  vmlinux EXPORT_SYMBOL
+-0xeecb608e    i2c_smbus_write_byte    vmlinux EXPORT_SYMBOL
+-0x907ada97    scsi_register_driver    vmlinux EXPORT_SYMBOL
+-0x7cc1b7fd    max77693_bulk_read      vmlinux EXPORT_SYMBOL_GPL
+-0x3274b08e    hdmi_avi_infoframe_init vmlinux EXPORT_SYMBOL
+-0xde8c763d    cpu_v7_set_pte_ext      vmlinux EXPORT_SYMBOL
+-0x2294b28a    snd_timer_pause vmlinux EXPORT_SYMBOL
+-0x5e95b1cd    current_umask   vmlinux EXPORT_SYMBOL
+-0xd2091a52    get_fs_type     vmlinux EXPORT_SYMBOL
+-0x94893493    ref_module      vmlinux EXPORT_SYMBOL_GPL
+-0x657ca634    iommu_domain_get_attr   vmlinux EXPORT_SYMBOL_GPL
+-0x6b758637    iommu_domain_set_attr   vmlinux EXPORT_SYMBOL_GPL
+-0xe835dcde    nf_nat_pptp_hook_outbound       vmlinux EXPORT_SYMBOL_GPL
+-0x3ac1fef9    drm_mode_legacy_fb_format       vmlinux EXPORT_SYMBOL
+-0x7cc88e22    tty_driver_kref_put     vmlinux EXPORT_SYMBOL
+-0x24fc46b6    regulator_bulk_free     vmlinux EXPORT_SYMBOL_GPL
+-0x776bea60    ip6_tnl_dst_check       vmlinux EXPORT_SYMBOL_GPL
+-0x80690fc4    sock_prot_inuse_get     vmlinux EXPORT_SYMBOL_GPL
+-0xb8aa9e8f    aead_geniv_init vmlinux EXPORT_SYMBOL_GPL
+-0x35bac202    generic_write_end       vmlinux EXPORT_SYMBOL
+-0x59e2743e    call_rcu_bh     vmlinux EXPORT_SYMBOL_GPL
+-0x639f9176    devm_request_threaded_irq       vmlinux EXPORT_SYMBOL
+-0x67955ce6    profile_hits    vmlinux EXPORT_SYMBOL_GPL
+-0xa53a0240    usb_wakeup_notification vmlinux EXPORT_SYMBOL_GPL
+-0xf5e3c0cf    scsi_host_set_state     vmlinux EXPORT_SYMBOL
+-0x31b21f37    nat_t120_hook   vmlinux EXPORT_SYMBOL_GPL
+-0xcd083b10    unregister_sound_dsp    vmlinux EXPORT_SYMBOL
+-0xda529e9e    blk_start_queue vmlinux EXPORT_SYMBOL
+-0xd84ce699    bio_copy_user   vmlinux EXPORT_SYMBOL
+-0x7a4497db    kzfree  vmlinux EXPORT_SYMBOL
+-0x91bbc6b9    genphy_config_aneg      vmlinux EXPORT_SYMBOL
+-0x1c251434    of_mm_gpiochip_add      vmlinux EXPORT_SYMBOL
+-0x8e10854d    inet_sk_diag_fill       vmlinux EXPORT_SYMBOL_GPL
+-0x07d2ea7a    arpt_unregister_table   vmlinux EXPORT_SYMBOL
+-0x2c038769    sk_filter       vmlinux EXPORT_SYMBOL
+-0x57e267af    generic_removexattr     vmlinux EXPORT_SYMBOL
+-0x643b400e    deactivate_super        vmlinux EXPORT_SYMBOL
+-0xcf241a0c    vmap    vmlinux EXPORT_SYMBOL
+-0x31f0bb78    __kmap_atomic_idx       vmlinux EXPORT_SYMBOL
+-0x4e32f63f    devm_clk_put    vmlinux EXPORT_SYMBOL
+-0x77f2c351    v4l2_ctrl_s_ctrl_int64  vmlinux EXPORT_SYMBOL
+-0xed9fdd16    gether_setup_name_default       vmlinux EXPORT_SYMBOL
+-0x6f572dd2    devm_remove_action      vmlinux EXPORT_SYMBOL_GPL
+-0xa8f59416    gpio_direction_output   vmlinux EXPORT_SYMBOL_GPL
+diff --git a/tools/abi-checker/sample/LICENSE b/tools/abi-checker/sample/LICENSE
+deleted file mode 100644
+index 63fabc1..0000000
+--- a/tools/abi-checker/sample/LICENSE
++++ /dev/null
+@@ -1,848 +0,0 @@
+-Copyright (C) 2007-2011 David Zeuthen <zeuthen@gmail.com>
+-Copyright (C) 2007-2011 Red Hat, Inc.
+-All Rights Reserved.
+-
+-The source code for the udisks daemon and command-line tools are
+-licensed to you under the GNU General Public License. Either version 2
+-of the License, or (at your option) any later version.
+-
+-The source code for the libudisks2 dynamic library is licensed to you
+-under the GNU Library General Public License. Either version 2 of the
+-License, or (at your option) any later version.
+-
+-Each file is marked with copyright and licensing headers.
+-
+-The GPLv2 and LGPLv2 licenses are included below.
+-
+--- BEGIN GPLv2+ License ---
+-
+-                    GNU GENERAL PUBLIC LICENSE
+-                       Version 2, June 1991
+-
+- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+- 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+-
+- Everyone is permitted to copy and distribute verbatim copies
+- of this license document, but changing it is not allowed.
+-
+-                            Preamble
+-
+-  The licenses for most software are designed to take away your
+-freedom to share and change it.  By contrast, the GNU General Public
+-License is intended to guarantee your freedom to share and change free
+-software--to make sure the software is free for all its users.  This
+-General Public License applies to most of the Free Software
+-Foundation's software and to any other program whose authors commit to
+-using it.  (Some other Free Software Foundation software is covered by
+-the GNU Library General Public License instead.)  You can apply it to
+-your programs, too.
+-
+-  When we speak of free software, we are referring to freedom, not
+-price.  Our General Public Licenses are designed to make sure that you
+-have the freedom to distribute copies of free software (and charge for
+-this service if you wish), that you receive source code or can get it
+-if you want it, that you can change the software or use pieces of it
+-in new free programs; and that you know you can do these things.
+-
+-  To protect your rights, we need to make restrictions that forbid
+-anyone to deny you these rights or to ask you to surrender the rights.
+-These restrictions translate to certain responsibilities for you if you
+-distribute copies of the software, or if you modify it.
+-
+-  For example, if you distribute copies of such a program, whether
+-gratis or for a fee, you must give the recipients all the rights that
+-you have.  You must make sure that they, too, receive or can get the
+-source code.  And you must show them these terms so they know their
+-rights.
+-
+-  We protect your rights with two steps: (1) copyright the software, and
+-(2) offer you this license which gives you legal permission to copy,
+-distribute and/or modify the software.
+-
+-  Also, for each author's protection and ours, we want to make certain
+-that everyone understands that there is no warranty for this free
+-software.  If the software is modified by someone else and passed on, we
+-want its recipients to know that what they have is not the original, so
+-that any problems introduced by others will not reflect on the original
+-authors' reputations.
+-
+-  Finally, any free program is threatened constantly by software
+-patents.  We wish to avoid the danger that redistributors of a free
+-program will individually obtain patent licenses, in effect making the
+-program proprietary.  To prevent this, we have made it clear that any
+-patent must be licensed for everyone's free use or not licensed at all.
+-
+-  The precise terms and conditions for copying, distribution and
+-modification follow.
+-
+-                    GNU GENERAL PUBLIC LICENSE
+-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+-
+-  0. This License applies to any program or other work which contains
+-a notice placed by the copyright holder saying it may be distributed
+-under the terms of this General Public License.  The "Program", below,
+-refers to any such program or work, and a "work based on the Program"
+-means either the Program or any derivative work under copyright law:
+-that is to say, a work containing the Program or a portion of it,
+-either verbatim or with modifications and/or translated into another
+-language.  (Hereinafter, translation is included without limitation in
+-the term "modification".)  Each licensee is addressed as "you".
+-
+-Activities other than copying, distribution and modification are not
+-covered by this License; they are outside its scope.  The act of
+-running the Program is not restricted, and the output from the Program
+-is covered only if its contents constitute a work based on the
+-Program (independent of having been made by running the Program).
+-Whether that is true depends on what the Program does.
+-
+-  1. You may copy and distribute verbatim copies of the Program's
+-source code as you receive it, in any medium, provided that you
+-conspicuously and appropriately publish on each copy an appropriate
+-copyright notice and disclaimer of warranty; keep intact all the
+-notices that refer to this License and to the absence of any warranty;
+-and give any other recipients of the Program a copy of this License
+-along with the Program.
+-
+-You may charge a fee for the physical act of transferring a copy, and
+-you may at your option offer warranty protection in exchange for a fee.
+-
+-  2. You may modify your copy or copies of the Program or any portion
+-of it, thus forming a work based on the Program, and copy and
+-distribute such modifications or work under the terms of Section 1
+-above, provided that you also meet all of these conditions:
+-
+-    a) You must cause the modified files to carry prominent notices
+-    stating that you changed the files and the date of any change.
+-
+-    b) You must cause any work that you distribute or publish, that in
+-    whole or in part contains or is derived from the Program or any
+-    part thereof, to be licensed as a whole at no charge to all third
+-    parties under the terms of this License.
+-
+-    c) If the modified program normally reads commands interactively
+-    when run, you must cause it, when started running for such
+-    interactive use in the most ordinary way, to print or display an
+-    announcement including an appropriate copyright notice and a
+-    notice that there is no warranty (or else, saying that you provide
+-    a warranty) and that users may redistribute the program under
+-    these conditions, and telling the user how to view a copy of this
+-    License.  (Exception: if the Program itself is interactive but
+-    does not normally print such an announcement, your work based on
+-    the Program is not required to print an announcement.)
+-
+-These requirements apply to the modified work as a whole.  If
+-identifiable sections of that work are not derived from the Program,
+-and can be reasonably considered independent and separate works in
+-themselves, then this License, and its terms, do not apply to those
+-sections when you distribute them as separate works.  But when you
+-distribute the same sections as part of a whole which is a work based
+-on the Program, the distribution of the whole must be on the terms of
+-this License, whose permissions for other licensees extend to the
+-entire whole, and thus to each and every part regardless of who wrote it.
+-
+-Thus, it is not the intent of this section to claim rights or contest
+-your rights to work written entirely by you; rather, the intent is to
+-exercise the right to control the distribution of derivative or
+-collective works based on the Program.
+-
+-In addition, mere aggregation of another work not based on the Program
+-with the Program (or with a work based on the Program) on a volume of
+-a storage or distribution medium does not bring the other work under
+-the scope of this License.
+-
+-  3. You may copy and distribute the Program (or a work based on it,
+-under Section 2) in object code or executable form under the terms of
+-Sections 1 and 2 above provided that you also do one of the following:
+-
+-    a) Accompany it with the complete corresponding machine-readable
+-    source code, which must be distributed under the terms of Sections
+-    1 and 2 above on a medium customarily used for software interchange; or,
+-
+-    b) Accompany it with a written offer, valid for at least three
+-    years, to give any third party, for a charge no more than your
+-    cost of physically performing source distribution, a complete
+-    machine-readable copy of the corresponding source code, to be
+-    distributed under the terms of Sections 1 and 2 above on a medium
+-    customarily used for software interchange; or,
+-
+-    c) Accompany it with the information you received as to the offer
+-    to distribute corresponding source code.  (This alternative is
+-    allowed only for noncommercial distribution and only if you
+-    received the program in object code or executable form with such
+-    an offer, in accord with Subsection b above.)
+-
+-The source code for a work means the preferred form of the work for
+-making modifications to it.  For an executable work, complete source
+-code means all the source code for all modules it contains, plus any
+-associated interface definition files, plus the scripts used to
+-control compilation and installation of the executable.  However, as a
+-special exception, the source code distributed need not include
+-anything that is normally distributed (in either source or binary
+-form) with the major components (compiler, kernel, and so on) of the
+-operating system on which the executable runs, unless that component
+-itself accompanies the executable.
+-
+-If distribution of executable or object code is made by offering
+-access to copy from a designated place, then offering equivalent
+-access to copy the source code from the same place counts as
+-distribution of the source code, even though third parties are not
+-compelled to copy the source along with the object code.
+-
+-  4. You may not copy, modify, sublicense, or distribute the Program
+-except as expressly provided under this License.  Any attempt
+-otherwise to copy, modify, sublicense or distribute the Program is
+-void, and will automatically terminate your rights under this License.
+-However, parties who have received copies, or rights, from you under
+-this License will not have their licenses terminated so long as such
+-parties remain in full compliance.
+-
+-  5. You are not required to accept this License, since you have not
+-signed it.  However, nothing else grants you permission to modify or
+-distribute the Program or its derivative works.  These actions are
+-prohibited by law if you do not accept this License.  Therefore, by
+-modifying or distributing the Program (or any work based on the
+-Program), you indicate your acceptance of this License to do so, and
+-all its terms and conditions for copying, distributing or modifying
+-the Program or works based on it.
+-
+-  6. Each time you redistribute the Program (or any work based on the
+-Program), the recipient automatically receives a license from the
+-original licensor to copy, distribute or modify the Program subject to
+-these terms and conditions.  You may not impose any further
+-restrictions on the recipients' exercise of the rights granted herein.
+-You are not responsible for enforcing compliance by third parties to
+-this License.
+-
+-  7. If, as a consequence of a court judgment or allegation of patent
+-infringement or for any other reason (not limited to patent issues),
+-conditions are imposed on you (whether by court order, agreement or
+-otherwise) that contradict the conditions of this License, they do not
+-excuse you from the conditions of this License.  If you cannot
+-distribute so as to satisfy simultaneously your obligations under this
+-License and any other pertinent obligations, then as a consequence you
+-may not distribute the Program at all.  For example, if a patent
+-license would not permit royalty-free redistribution of the Program by
+-all those who receive copies directly or indirectly through you, then
+-the only way you could satisfy both it and this License would be to
+-refrain entirely from distribution of the Program.
+-
+-If any portion of this section is held invalid or unenforceable under
+-any particular circumstance, the balance of the section is intended to
+-apply and the section as a whole is intended to apply in other
+-circumstances.
+-
+-It is not the purpose of this section to induce you to infringe any
+-patents or other property right claims or to contest validity of any
+-such claims; this section has the sole purpose of protecting the
+-integrity of the free software distribution system, which is
+-implemented by public license practices.  Many people have made
+-generous contributions to the wide range of software distributed
+-through that system in reliance on consistent application of that
+-system; it is up to the author/donor to decide if he or she is willing
+-to distribute software through any other system and a licensee cannot
+-impose that choice.
+-
+-This section is intended to make thoroughly clear what is believed to
+-be a consequence of the rest of this License.
+-
+-  8. If the distribution and/or use of the Program is restricted in
+-certain countries either by patents or by copyrighted interfaces, the
+-original copyright holder who places the Program under this License
+-may add an explicit geographical distribution limitation excluding
+-those countries, so that distribution is permitted only in or among
+-countries not thus excluded.  In such case, this License incorporates
+-the limitation as if written in the body of this License.
+-
+-  9. The Free Software Foundation may publish revised and/or new versions
+-of the General Public License from time to time.  Such new versions will
+-be similar in spirit to the present version, but may differ in detail to
+-address new problems or concerns.
+-
+-Each version is given a distinguishing version number.  If the Program
+-specifies a version number of this License which applies to it and "any
+-later version", you have the option of following the terms and conditions
+-either of that version or of any later version published by the Free
+-Software Foundation.  If the Program does not specify a version number of
+-this License, you may choose any version ever published by the Free Software
+-Foundation.
+-
+-  10. If you wish to incorporate parts of the Program into other free
+-programs whose distribution conditions are different, write to the author
+-to ask for permission.  For software which is copyrighted by the Free
+-Software Foundation, write to the Free Software Foundation; we sometimes
+-make exceptions for this.  Our decision will be guided by the two goals
+-of preserving the free status of all derivatives of our free software and
+-of promoting the sharing and reuse of software generally.
+-
+-                            NO WARRANTY
+-
+-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+-REPAIR OR CORRECTION.
+-
+-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+-POSSIBILITY OF SUCH DAMAGES.
+-
+-                     END OF TERMS AND CONDITIONS
+-
+-            How to Apply These Terms to Your New Programs
+-
+-  If you develop a new program, and you want it to be of the greatest
+-possible use to the public, the best way to achieve this is to make it
+-free software which everyone can redistribute and change under these terms.
+-
+-  To do so, attach the following notices to the program.  It is safest
+-to attach them to the start of each source file to most effectively
+-convey the exclusion of warranty; and each file should have at least
+-the "copyright" line and a pointer to where the full notice is found.
+-
+-    <one line to give the program's name and a brief idea of what it does.>
+-    Copyright (C) <year>  <name of author>
+-
+-    This program is free software; you can redistribute it and/or modify
+-    it under the terms of the GNU General Public License as published by
+-    the Free Software Foundation; either version 2 of the License, or
+-    (at your option) any later version.
+-
+-    This program is distributed in the hope that it will be useful,
+-    but WITHOUT ANY WARRANTY; without even the implied warranty of
+-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-    GNU General Public License for more details.
+-
+-    You should have received a copy of the GNU General Public License
+-    along with this program; if not, write to the Free Software
+-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+-
+-
+-Also add information on how to contact you by electronic and paper mail.
+-
+-If the program is interactive, make it output a short notice like this
+-when it starts in an interactive mode:
+-
+-    Gnomovision version 69, Copyright (C) year name of author
+-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+-    This is free software, and you are welcome to redistribute it
+-    under certain conditions; type `show c' for details.
+-
+-The hypothetical commands `show w' and `show c' should show the appropriate
+-parts of the General Public License.  Of course, the commands you use may
+-be called something other than `show w' and `show c'; they could even be
+-mouse-clicks or menu items--whatever suits your program.
+-
+-You should also get your employer (if you work as a programmer) or your
+-school, if any, to sign a "copyright disclaimer" for the program, if
+-necessary.  Here is a sample; alter the names:
+-
+-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+-
+-  <signature of Ty Coon>, 1 April 1989
+-  Ty Coon, President of Vice
+-
+-This General Public License does not permit incorporating your program into
+-proprietary programs.  If your program is a subroutine library, you may
+-consider it more useful to permit linking proprietary applications with the
+-library.  If this is what you want to do, use the GNU Library General
+-Public License instead of this License.
+-
+--- END GPLv2+ License ---
+-
+--- BEGIN LGPLv2+ License ---
+-
+-                  GNU LIBRARY GENERAL PUBLIC LICENSE
+-                       Version 2, June 1991
+-
+- Copyright (C) 1991 Free Software Foundation, Inc.
+-                    59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+- Everyone is permitted to copy and distribute verbatim copies
+- of this license document, but changing it is not allowed.
+-
+-[This is the first released version of the library GPL.  It is
+- numbered 2 because it goes with version 2 of the ordinary GPL.]
+-
+-                            Preamble
+-
+-  The licenses for most software are designed to take away your
+-freedom to share and change it.  By contrast, the GNU General Public
+-Licenses are intended to guarantee your freedom to share and change
+-free software--to make sure the software is free for all its users.
+-
+-  This license, the Library General Public License, applies to some
+-specially designated Free Software Foundation software, and to any
+-other libraries whose authors decide to use it.  You can use it for
+-your libraries, too.
+-
+-  When we speak of free software, we are referring to freedom, not
+-price.  Our General Public Licenses are designed to make sure that you
+-have the freedom to distribute copies of free software (and charge for
+-this service if you wish), that you receive source code or can get it
+-if you want it, that you can change the software or use pieces of it
+-in new free programs; and that you know you can do these things.
+-
+-  To protect your rights, we need to make restrictions that forbid
+-anyone to deny you these rights or to ask you to surrender the rights.
+-These restrictions translate to certain responsibilities for you if
+-you distribute copies of the library, or if you modify it.
+-
+-  For example, if you distribute copies of the library, whether gratis
+-or for a fee, you must give the recipients all the rights that we gave
+-you.  You must make sure that they, too, receive or can get the source
+-code.  If you link a program with the library, you must provide
+-complete object files to the recipients so that they can relink them
+-with the library, after making changes to the library and recompiling
+-it.  And you must show them these terms so they know their rights.
+-
+-  Our method of protecting your rights has two steps: (1) copyright
+-the library, and (2) offer you this license which gives you legal
+-permission to copy, distribute and/or modify the library.
+-
+-  Also, for each distributor's protection, we want to make certain
+-that everyone understands that there is no warranty for this free
+-library.  If the library is modified by someone else and passed on, we
+-want its recipients to know that what they have is not the original
+-version, so that any problems introduced by others will not reflect on
+-the original authors' reputations.
+-
+-  Finally, any free program is threatened constantly by software
+-patents.  We wish to avoid the danger that companies distributing free
+-software will individually obtain patent licenses, thus in effect
+-transforming the program into proprietary software.  To prevent this,
+-we have made it clear that any patent must be licensed for everyone's
+-free use or not licensed at all.
+-
+-  Most GNU software, including some libraries, is covered by the ordinary
+-GNU General Public License, which was designed for utility programs.  This
+-license, the GNU Library General Public License, applies to certain
+-designated libraries.  This license is quite different from the ordinary
+-one; be sure to read it in full, and don't assume that anything in it is
+-the same as in the ordinary license.
+-
+-  The reason we have a separate public license for some libraries is that
+-they blur the distinction we usually make between modifying or adding to a
+-program and simply using it.  Linking a program with a library, without
+-changing the library, is in some sense simply using the library, and is
+-analogous to running a utility program or application program.  However, in
+-a textual and legal sense, the linked executable is a combined work, a
+-derivative of the original library, and the ordinary General Public License
+-treats it as such.
+-
+-  Because of this blurred distinction, using the ordinary General
+-Public License for libraries did not effectively promote software
+-sharing, because most developers did not use the libraries.  We
+-concluded that weaker conditions might promote sharing better.
+-
+-  However, unrestricted linking of non-free programs would deprive the
+-users of those programs of all benefit from the free status of the
+-libraries themselves.  This Library General Public License is intended to
+-permit developers of non-free programs to use free libraries, while
+-preserving your freedom as a user of such programs to change the free
+-libraries that are incorporated in them.  (We have not seen how to achieve
+-this as regards changes in header files, but we have achieved it as regards
+-changes in the actual functions of the Library.)  The hope is that this
+-will lead to faster development of free libraries.
+-
+-  The precise terms and conditions for copying, distribution and
+-modification follow.  Pay close attention to the difference between a
+-"work based on the library" and a "work that uses the library".  The
+-former contains code derived from the library, while the latter only
+-works together with the library.
+-
+-  Note that it is possible for a library to be covered by the ordinary
+-General Public License rather than by this special one.
+-
+-                  GNU LIBRARY GENERAL PUBLIC LICENSE
+-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+-
+-  0. This License Agreement applies to any software library which
+-contains a notice placed by the copyright holder or other authorized
+-party saying it may be distributed under the terms of this Library
+-General Public License (also called "this License").  Each licensee is
+-addressed as "you".
+-
+-  A "library" means a collection of software functions and/or data
+-prepared so as to be conveniently linked with application programs
+-(which use some of those functions and data) to form executables.
+-
+-  The "Library", below, refers to any such software library or work
+-which has been distributed under these terms.  A "work based on the
+-Library" means either the Library or any derivative work under
+-copyright law: that is to say, a work containing the Library or a
+-portion of it, either verbatim or with modifications and/or translated
+-straightforwardly into another language.  (Hereinafter, translation is
+-included without limitation in the term "modification".)
+-
+-  "Source code" for a work means the preferred form of the work for
+-making modifications to it.  For a library, complete source code means
+-all the source code for all modules it contains, plus any associated
+-interface definition files, plus the scripts used to control compilation
+-and installation of the library.
+-
+-  Activities other than copying, distribution and modification are not
+-covered by this License; they are outside its scope.  The act of
+-running a program using the Library is not restricted, and output from
+-such a program is covered only if its contents constitute a work based
+-on the Library (independent of the use of the Library in a tool for
+-writing it).  Whether that is true depends on what the Library does
+-and what the program that uses the Library does.
+-
+-  1. You may copy and distribute verbatim copies of the Library's
+-complete source code as you receive it, in any medium, provided that
+-you conspicuously and appropriately publish on each copy an
+-appropriate copyright notice and disclaimer of warranty; keep intact
+-all the notices that refer to this License and to the absence of any
+-warranty; and distribute a copy of this License along with the
+-Library.
+-
+-  You may charge a fee for the physical act of transferring a copy,
+-and you may at your option offer warranty protection in exchange for a
+-fee.
+-
+-  2. You may modify your copy or copies of the Library or any portion
+-of it, thus forming a work based on the Library, and copy and
+-distribute such modifications or work under the terms of Section 1
+-above, provided that you also meet all of these conditions:
+-
+-    a) The modified work must itself be a software library.
+-
+-    b) You must cause the files modified to carry prominent notices
+-    stating that you changed the files and the date of any change.
+-
+-    c) You must cause the whole of the work to be licensed at no
+-    charge to all third parties under the terms of this License.
+-
+-    d) If a facility in the modified Library refers to a function or a
+-    table of data to be supplied by an application program that uses
+-    the facility, other than as an argument passed when the facility
+-    is invoked, then you must make a good faith effort to ensure that,
+-    in the event an application does not supply such function or
+-    table, the facility still operates, and performs whatever part of
+-    its purpose remains meaningful.
+-
+-    (For example, a function in a library to compute square roots has
+-    a purpose that is entirely well-defined independent of the
+-    application.  Therefore, Subsection 2d requires that any
+-    application-supplied function or table used by this function must
+-    be optional: if the application does not supply it, the square
+-    root function must still compute square roots.)
+-
+-These requirements apply to the modified work as a whole.  If
+-identifiable sections of that work are not derived from the Library,
+-and can be reasonably considered independent and separate works in
+-themselves, then this License, and its terms, do not apply to those
+-sections when you distribute them as separate works.  But when you
+-distribute the same sections as part of a whole which is a work based
+-on the Library, the distribution of the whole must be on the terms of
+-this License, whose permissions for other licensees extend to the
+-entire whole, and thus to each and every part regardless of who wrote
+-it.
+-
+-Thus, it is not the intent of this section to claim rights or contest
+-your rights to work written entirely by you; rather, the intent is to
+-exercise the right to control the distribution of derivative or
+-collective works based on the Library.
+-
+-In addition, mere aggregation of another work not based on the Library
+-with the Library (or with a work based on the Library) on a volume of
+-a storage or distribution medium does not bring the other work under
+-the scope of this License.
+-
+-  3. You may opt to apply the terms of the ordinary GNU General Public
+-License instead of this License to a given copy of the Library.  To do
+-this, you must alter all the notices that refer to this License, so
+-that they refer to the ordinary GNU General Public License, version 2,
+-instead of to this License.  (If a newer version than version 2 of the
+-ordinary GNU General Public License has appeared, then you can specify
+-that version instead if you wish.)  Do not make any other change in
+-these notices.
+-
+-  Once this change is made in a given copy, it is irreversible for
+-that copy, so the ordinary GNU General Public License applies to all
+-subsequent copies and derivative works made from that copy.
+-
+-  This option is useful when you wish to copy part of the code of
+-the Library into a program that is not a library.
+-
+-  4. You may copy and distribute the Library (or a portion or
+-derivative of it, under Section 2) in object code or executable form
+-under the terms of Sections 1 and 2 above provided that you accompany
+-it with the complete corresponding machine-readable source code, which
+-must be distributed under the terms of Sections 1 and 2 above on a
+-medium customarily used for software interchange.
+-
+-  If distribution of object code is made by offering access to copy
+-from a designated place, then offering equivalent access to copy the
+-source code from the same place satisfies the requirement to
+-distribute the source code, even though third parties are not
+-compelled to copy the source along with the object code.
+-
+-  5. A program that contains no derivative of any portion of the
+-Library, but is designed to work with the Library by being compiled or
+-linked with it, is called a "work that uses the Library".  Such a
+-work, in isolation, is not a derivative work of the Library, and
+-therefore falls outside the scope of this License.
+-
+-  However, linking a "work that uses the Library" with the Library
+-creates an executable that is a derivative of the Library (because it
+-contains portions of the Library), rather than a "work that uses the
+-library".  The executable is therefore covered by this License.
+-Section 6 states terms for distribution of such executables.
+-
+-  When a "work that uses the Library" uses material from a header file
+-that is part of the Library, the object code for the work may be a
+-derivative work of the Library even though the source code is not.
+-Whether this is true is especially significant if the work can be
+-linked without the Library, or if the work is itself a library.  The
+-threshold for this to be true is not precisely defined by law.
+-
+-  If such an object file uses only numerical parameters, data
+-structure layouts and accessors, and small macros and small inline
+-functions (ten lines or less in length), then the use of the object
+-file is unrestricted, regardless of whether it is legally a derivative
+-work.  (Executables containing this object code plus portions of the
+-Library will still fall under Section 6.)
+-
+-  Otherwise, if the work is a derivative of the Library, you may
+-distribute the object code for the work under the terms of Section 6.
+-Any executables containing that work also fall under Section 6,
+-whether or not they are linked directly with the Library itself.
+-
+-  6. As an exception to the Sections above, you may also compile or
+-link a "work that uses the Library" with the Library to produce a
+-work containing portions of the Library, and distribute that work
+-under terms of your choice, provided that the terms permit
+-modification of the work for the customer's own use and reverse
+-engineering for debugging such modifications.
+-
+-  You must give prominent notice with each copy of the work that the
+-Library is used in it and that the Library and its use are covered by
+-this License.  You must supply a copy of this License.  If the work
+-during execution displays copyright notices, you must include the
+-copyright notice for the Library among them, as well as a reference
+-directing the user to the copy of this License.  Also, you must do one
+-of these things:
+-
+-    a) Accompany the work with the complete corresponding
+-    machine-readable source code for the Library including whatever
+-    changes were used in the work (which must be distributed under
+-    Sections 1 and 2 above); and, if the work is an executable linked
+-    with the Library, with the complete machine-readable "work that
+-    uses the Library", as object code and/or source code, so that the
+-    user can modify the Library and then relink to produce a modified
+-    executable containing the modified Library.  (It is understood
+-    that the user who changes the contents of definitions files in the
+-    Library will not necessarily be able to recompile the application
+-    to use the modified definitions.)
+-
+-    b) Accompany the work with a written offer, valid for at
+-    least three years, to give the same user the materials
+-    specified in Subsection 6a, above, for a charge no more
+-    than the cost of performing this distribution.
+-
+-    c) If distribution of the work is made by offering access to copy
+-    from a designated place, offer equivalent access to copy the above
+-    specified materials from the same place.
+-
+-    d) Verify that the user has already received a copy of these
+-    materials or that you have already sent this user a copy.
+-
+-  For an executable, the required form of the "work that uses the
+-Library" must include any data and utility programs needed for
+-reproducing the executable from it.  However, as a special exception,
+-the source code distributed need not include anything that is normally
+-distributed (in either source or binary form) with the major
+-components (compiler, kernel, and so on) of the operating system on
+-which the executable runs, unless that component itself accompanies
+-the executable.
+-
+-  It may happen that this requirement contradicts the license
+-restrictions of other proprietary libraries that do not normally
+-accompany the operating system.  Such a contradiction means you cannot
+-use both them and the Library together in an executable that you
+-distribute.
+-
+-  7. You may place library facilities that are a work based on the
+-Library side-by-side in a single library together with other library
+-facilities not covered by this License, and distribute such a combined
+-library, provided that the separate distribution of the work based on
+-the Library and of the other library facilities is otherwise
+-permitted, and provided that you do these two things:
+-
+-    a) Accompany the combined library with a copy of the same work
+-    based on the Library, uncombined with any other library
+-    facilities.  This must be distributed under the terms of the
+-    Sections above.
+-
+-    b) Give prominent notice with the combined library of the fact
+-    that part of it is a work based on the Library, and explaining
+-    where to find the accompanying uncombined form of the same work.
+-
+-  8. You may not copy, modify, sublicense, link with, or distribute
+-the Library except as expressly provided under this License.  Any
+-attempt otherwise to copy, modify, sublicense, link with, or
+-distribute the Library is void, and will automatically terminate your
+-rights under this License.  However, parties who have received copies,
+-or rights, from you under this License will not have their licenses
+-terminated so long as such parties remain in full compliance.
+-
+-  9. You are not required to accept this License, since you have not
+-signed it.  However, nothing else grants you permission to modify or
+-distribute the Library or its derivative works.  These actions are
+-prohibited by law if you do not accept this License.  Therefore, by
+-modifying or distributing the Library (or any work based on the
+-Library), you indicate your acceptance of this License to do so, and
+-all its terms and conditions for copying, distributing or modifying
+-the Library or works based on it.
+-
+-  10. Each time you redistribute the Library (or any work based on the
+-Library), the recipient automatically receives a license from the
+-original licensor to copy, distribute, link with or modify the Library
+-subject to these terms and conditions.  You may not impose any further
+-restrictions on the recipients' exercise of the rights granted herein.
+-You are not responsible for enforcing compliance by third parties to
+-this License.
+-
+-  11. If, as a consequence of a court judgment or allegation of patent
+-infringement or for any other reason (not limited to patent issues),
+-conditions are imposed on you (whether by court order, agreement or
+-otherwise) that contradict the conditions of this License, they do not
+-excuse you from the conditions of this License.  If you cannot
+-distribute so as to satisfy simultaneously your obligations under this
+-License and any other pertinent obligations, then as a consequence you
+-may not distribute the Library at all.  For example, if a patent
+-license would not permit royalty-free redistribution of the Library by
+-all those who receive copies directly or indirectly through you, then
+-the only way you could satisfy both it and this License would be to
+-refrain entirely from distribution of the Library.
+-
+-If any portion of this section is held invalid or unenforceable under any
+-particular circumstance, the balance of the section is intended to apply,
+-and the section as a whole is intended to apply in other circumstances.
+-
+-It is not the purpose of this section to induce you to infringe any
+-patents or other property right claims or to contest validity of any
+-such claims; this section has the sole purpose of protecting the
+-integrity of the free software distribution system which is
+-implemented by public license practices.  Many people have made
+-generous contributions to the wide range of software distributed
+-through that system in reliance on consistent application of that
+-system; it is up to the author/donor to decide if he or she is willing
+-to distribute software through any other system and a licensee cannot
+-impose that choice.
+-
+-This section is intended to make thoroughly clear what is believed to
+-be a consequence of the rest of this License.
+-
+-  12. If the distribution and/or use of the Library is restricted in
+-certain countries either by patents or by copyrighted interfaces, the
+-original copyright holder who places the Library under this License may add
+-an explicit geographical distribution limitation excluding those countries,
+-so that distribution is permitted only in or among countries not thus
+-excluded.  In such case, this License incorporates the limitation as if
+-written in the body of this License.
+-
+-  13. The Free Software Foundation may publish revised and/or new
+-versions of the Library General Public License from time to time.
+-Such new versions will be similar in spirit to the present version,
+-but may differ in detail to address new problems or concerns.
+-
+-Each version is given a distinguishing version number.  If the Library
+-specifies a version number of this License which applies to it and
+-"any later version", you have the option of following the terms and
+-conditions either of that version or of any later version published by
+-the Free Software Foundation.  If the Library does not specify a
+-license version number, you may choose any version ever published by
+-the Free Software Foundation.
+-
+-  14. If you wish to incorporate parts of the Library into other free
+-programs whose distribution conditions are incompatible with these,
+-write to the author to ask for permission.  For software which is
+-copyrighted by the Free Software Foundation, write to the Free
+-Software Foundation; we sometimes make exceptions for this.  Our
+-decision will be guided by the two goals of preserving the free status
+-of all derivatives of our free software and of promoting the sharing
+-and reuse of software generally.
+-
+-                            NO WARRANTY
+-
+-  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+-
+-  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+-DAMAGES.
+-
+-                     END OF TERMS AND CONDITIONS
+-
+-           How to Apply These Terms to Your New Libraries
+-
+-  If you develop a new library, and you want it to be of the greatest
+-possible use to the public, we recommend making it free software that
+-everyone can redistribute and change.  You can do so by permitting
+-redistribution under these terms (or, alternatively, under the terms of the
+-ordinary General Public License).
+-
+-  To apply these terms, attach the following notices to the library.  It is
+-safest to attach them to the start of each source file to most effectively
+-convey the exclusion of warranty; and each file should have at least the
+-"copyright" line and a pointer to where the full notice is found.
+-
+-    <one line to give the library's name and a brief idea of what it does.>
+-    Copyright (C) <year>  <name of author>
+-
+-    This library is free software; you can redistribute it and/or
+-    modify it under the terms of the GNU Library General Public
+-    License as published by the Free Software Foundation; either
+-    version 2 of the License, or (at your option) any later version.
+-
+-    This library 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
+-    Library General Public License for more details.
+-
+-    You should have received a copy of the GNU Library General Public
+-    License along with this library; if not, write to the
+-    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-    Boston, MA  02111-1307  USA.
+-
+-Also add information on how to contact you by electronic and paper mail.
+-
+-You should also get your employer (if you work as a programmer) or your
+-school, if any, to sign a "copyright disclaimer" for the library, if
+-necessary.  Here is a sample; alter the names:
+-
+-  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+-  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+-
+-  <signature of Ty Coon>, 1 April 1990
+-  Ty Coon, President of Vice
+-
+-That's all there is to it!
+-
+--- END LGPLv2+ License ---
+diff --git a/tools/abi-checker/sample/Makefile b/tools/abi-checker/sample/Makefile
+deleted file mode 100644
+index 4759f3c..0000000
+--- a/tools/abi-checker/sample/Makefile
++++ /dev/null
+@@ -1,12 +0,0 @@
+-obj-m = sample_module.o
+-
+-all:
+-      make -C /usr/src/linux-kernel-build-3.10.19-tizen_defconfig.1 M=$(PWD) modules
+-
+-install:
+-      make -C /usr/src/linux-kernel-build-3.10.19-tizen_defconfig.1 M=$(PWD) modules_install
+-
+-clean:
+-      make -C /usr/src/linux-kernel-build-3.10.19-tizen_defconfig.1 M=$(PWD) clean
+-      
+-
+diff --git a/tools/abi-checker/sample/packaging/sample-module.spec.txt b/tools/abi-checker/sample/packaging/sample-module.spec.txt
+deleted file mode 100644
+index bca8416..0000000
+--- a/tools/abi-checker/sample/packaging/sample-module.spec.txt
++++ /dev/null
+@@ -1,53 +0,0 @@
+-%define debug_package %{nil}
+-Name:       sample-module
+-Summary:    Test sample kernel module 2
+-Version:    0.1.0
+-Release:    1
+-Group:      Base/Device Management
+-License:    GPL-2.0
+-Source0:    %{name}-%{version}.tar.gz
+-BuildRequires: linux-kernel-sources
+-BuildRequires: linux-kernel-headers
+-BuildRequires: linux-kernel-build
+-BuildRequires: linux-kernel-abi-tools
+-BuildRequires: linux-kernel-abi-devel
+-
+-Requires: linux-kernel-uImage
+-
+-%package source
+-Summary: Debug sample-kernel-module-2
+-Group: Base/Device Management
+-
+-%description source
+-Debug and sources sample-kernel-module-2
+-
+-%description
+-TIZEN simple kernel module.  
+-
+-%prep
+-%setup -q
+-
+-%build
+-make %{?jobs:-j%jobs}
+-# Create ABI/API dump fingerprint file
+-/usr/local/bin/abi-module-dumper sample_module_2.ko sample_module_2.abidump
+-
+-%install
+-mkdir -p %{_builddir}/lib/modules/3.10.19-tizen_defconfig.1/
+-make INSTALL_MOD_PATH=%{buildroot}  install
+-cp sample_module_2.abidump %{buildroot}/lib/modules/3.10.19-tizen_defconfig.1/extra/
+-
+-%post
+-# list comptible kerel ABI/API versions
+-/usr/local/bin/abi-module-kernels-list /lib/modules/3.10.19-tizen_defconfig.1/extra/sample_module_2.abidump
+-
+-# Test module ABI/API with the kernel ABI/API
+-/usr/local/bin/abi-module-checker /lib/modules/3.10.19-tizen_defconfig.1/extra/sample_module_2.abidump
+-
+-%files
+-/lib/modules/3.10.19-tizen_defconfig.1/extra/
+-%license LICENSE
+-
+-%files source
+-/usr/src/debug/sample-kernel-module-2-0.1.0/sample_module_2.c
+-/usr/src/debug/sample-kernel-module-2-0.1.0/sample_module_2.mod.c
+diff --git a/tools/abi-checker/sample/sample_module.c b/tools/abi-checker/sample/sample_module.c
+deleted file mode 100644
+index b95a7af..0000000
+--- a/tools/abi-checker/sample/sample_module.c
++++ /dev/null
+@@ -1,107 +0,0 @@
+-#include <linux/module.h>
+-#include <linux/kernel.h>
+-#include <asm/uaccess.h>
+-#include <linux/init.h>
+-#include <linux/fs.h>
+-
+-#define DEVICE_NAME "sample_module"
+-#define TEST_MSG_BUFF_LEN     1024
+-
+-extern int snd_timer_pause;
+-
+-static unsigned int majorNumber = 0;
+-
+-static char message[TEST_MSG_BUFF_LEN + 1];
+-
+-static ssize_t device_write(struct file *filp, const char *buff, size_t len, loff_t *off)
+-{
+-      printk(KERN_ALERT "Empty write operation. %d\n", snd_timer_pause);
+-      return 0;
+-}
+-
+-static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t * offset)
+-{
+-      int bytes_read = 0;
+-
+-      /*
+-       * Copy message
+-       */
+-      for(bytes_read = 0; bytes_read < (length - 1) && bytes_read < TEST_MSG_BUFF_LEN; bytes_read ++)
+-              put_user(message[bytes_read], buffer + bytes_read );
+-      put_user('\0', buffer + bytes_read );
+-
+-      return bytes_read + 1;
+-}
+-
+-static int device_open(struct inode *inode, struct file *file)
+-{
+-      static int counter = 0;
+-
+-      printk( "Open device, count = %d\n", counter++ );
+-
+-      try_module_get( THIS_MODULE );
+-      return 0;
+-}
+-
+-static int device_release(struct inode *inode, struct file *file)
+-{
+-      printk("Release device\n");
+-
+-      module_put( THIS_MODULE );
+-      return 0;
+-}
+-
+-struct file_operations fileOperations =
+-{
+-      read:    device_read,
+-      write:   device_write,
+-      open:    device_open,
+-      release: device_release
+-};
+-
+-static int __init test_module_init( void )
+-{
+-      int i;
+-      int j;
+-
+-      printk(KERN_ALERT "Test kernel module 2 - enter\n");
+-
+-      /*
+-       * Init test message
+-       */
+-      for(i = 0; i < TEST_MSG_BUFF_LEN;)
+-      {
+-              for(j = 0; j < 10 && i < TEST_MSG_BUFF_LEN; j ++, i ++ )
+-              {
+-                      message[i] = '0' + j;
+-                      message[i + 1] = '\0';
+-              }
+-      }
+-
+-      /*
+-       * Register device
+-       */
+-      majorNumber = register_chrdev(0, DEVICE_NAME, &fileOperations);
+-      if (majorNumber < 0)
+-      {
+-                printk(KERN_ALERT "Blad rejestrowania urzadzenia => [%d]\n", majorNumber );
+-                return majorNumber;
+-      }
+-
+-      return 0;
+-}
+-
+-static void __exit test_module_exit(void)
+-{
+-      printk(KERN_ALERT "Test kernel module 2 - exit\n");
+-
+-      unregister_chrdev(majorNumber, DEVICE_NAME);
+-}
+-
+-module_init(test_module_init);
+-module_exit(test_module_exit);
+-
+-MODULE_LICENSE("GPL");
+-MODULE_AUTHOR("Jacek Pielaszkiewicz");        /* Who wrote this module? */
+-MODULE_DESCRIPTION("Sample test kernel module.");     /* What does this module do */
+-MODULE_SUPPORTED_DEVICE("sample_test_module_2");
+diff --git a/tools/abi-checker/src/Makefile b/tools/abi-checker/src/Makefile
+deleted file mode 100644
+index b020bc6..0000000
+--- a/tools/abi-checker/src/Makefile
++++ /dev/null
+@@ -1,31 +0,0 @@
+-PROGRAM = abi-checker
+-GCC = gcc
+-LDD = gcc
+-
+-CFLAGS = $(shell pkg-config --cflags glib-2.0 libelf) -I.
+-
+-LDFLAGS = $(shell pkg-config --libs glib-2.0 libelf)
+-
+-SRC = kernel_abi_checker.c kernel_abi_checker_elf.c
+-
+-HEADER = kernel_abi_checker.h
+-
+-DEST_DIR = /usr/local/bin
+-
+-OBJECTS = kernel_abi_checker.o kernel_abi_checker_elf.o
+-
+-all : $(PROGRAM)
+-
+-.c.o : $(HEADER)
+-      $(GCC) -c $(CFLAGS) $< -o $@
+-
+-$(PROGRAM) : $(OBJECTS)
+-      $(LDD) $(OBJECTS) -o $@ $(LDFLAGS)
+-
+-install :
+-      mkdir -p $(DEST_DIR)
+-      cp $(PROGRAM) $(DEST_DIR)
+-
+-clean :
+-      rm -f $(PROGRAM)
+-      rm -f $(OBJECTS)
+diff --git a/tools/abi-checker/src/abi-module-checker b/tools/abi-checker/src/abi-module-checker
+deleted file mode 100755
+index 2666fbd..0000000
+--- a/tools/abi-checker/src/abi-module-checker
++++ /dev/null
+@@ -1,43 +0,0 @@
+-#!/bin/sh
+-
+-echo ""
+-echo "Module ABI/API checker"
+-echo ""
+-echo ""
+-
+-if [ "${#}" != "1"  ]
+-then
+-      echo ""
+-      echo "ERROR: "
+-      echo "       Usage: ${0} _module_abi_fingerprint_"
+-      echo ""
+-      exit 1
+-fi
+-
+-kerne_abi_file="/boot/abi/current"
+-
+-if [ ! -f "${1}" -o ! -f "${kerne_abi_file}" ]
+-then
+-      echo ""
+-      echo "ERROR: Please check \"${1}\", \"${kerne_abi_file}\" files"
+-      echo ""
+-      exit 1
+-fi
+-
+-ABI_TOOL_LOCATION="/usr/local/bin"
+-ABI_TOOL_NAME="abi-checker"
+-ABI_TOOL="${ABI_TOOL_LOCATION}/${ABI_TOOL_NAME}"
+-
+-if [ -x "${ABI_TOOL}" ]
+-then
+-      CMD="${ABI_TOOL}"
+-elif [ -x "./${ABI_TOOL_NAME}" ]
+-then
+-      CMD="./${ABI_TOOL_NAME}"
+-else
+-      CMD="${ABI_TOOL_NAME}"
+-fi
+-
+-"${CMD}" "test-module" "${kerne_abi_file}" "${1}"
+-
+-exit ${?}
+diff --git a/tools/abi-checker/src/abi-module-dumper b/tools/abi-checker/src/abi-module-dumper
+deleted file mode 100755
+index 3af55fb..0000000
+--- a/tools/abi-checker/src/abi-module-dumper
++++ /dev/null
+@@ -1,51 +0,0 @@
+-#!/bin/sh
+-
+-echo ""
+-echo "Module ABI/API fingerprint file generation"
+-echo ""
+-echo ""
+-
+-if [ "${#}" != "2"  ]
+-then
+-      echo ""
+-      echo "ERROR: "
+-      echo "       Usage: ${0} _module_ko_file_ _output_file_"
+-      echo ""
+-      exit 1
+-fi
+-
+-kerne_abi_file="/boot/abi/current"
+-
+-if [ ! -f "${kerne_abi_file}" ]
+-then
+-      echo ""
+-      echo "ERROR: Please check ${kerne_abi_file} file"
+-      echo "       Check if linux-kernel-uImage package is installed in development environment."
+-      echo ""
+-      exit 1
+-fi
+-
+-if [ ! -f "${1}" ]
+-then
+-      echo "ERROR: Please check input file ${1}"
+-      echo ""
+-      exit 1
+-fi
+-
+-ABI_TOOL_LOCATION="/usr/local/bin"
+-ABI_TOOL_NAME="abi-checker"
+-ABI_TOOL="${ABI_TOOL_LOCATION}/${ABI_TOOL_NAME}"
+-
+-if [ -x "${ABI_TOOL}" ]
+-then
+-        CMD="${ABI_TOOL}"
+-elif [ -x "./${ABI_TOOL_NAME}" ]
+-then
+-        CMD="./${ABI_TOOL_NAME}"
+-else
+-        CMD="${ABI_TOOL_NAME}"
+-fi
+-
+-"${CMD}" "dump-module" "${kerne_abi_file}" "${1}" "${2}"
+-
+-exit ${?}
+diff --git a/tools/abi-checker/src/abi-module-kernels-list b/tools/abi-checker/src/abi-module-kernels-list
+deleted file mode 100755
+index e07f523..0000000
+--- a/tools/abi-checker/src/abi-module-kernels-list
++++ /dev/null
+@@ -1,45 +0,0 @@
+-#!/bin/sh
+-
+-echo ""
+-echo "List all comatible kernels."
+-echo ""
+-
+-if [ "${#}" != 1  ]
+-then
+-      echo ""
+-      echo "ERROR: "
+-      echo "       Usage: ${0} _module_fingerprint_"
+-      echo ""
+-      exit 1
+-fi
+-
+-ABI_TOOL_LOCATION="/usr/local/bin"
+-ABI_TOOL_NAME="abi-checker"
+-ABI_TOOL="${ABI_TOOL_LOCATION}/${ABI_TOOL_NAME}"
+-
+-if [ -x "${ABI_TOOL}" ]
+-then
+-        CMD="${ABI_TOOL}"
+-elif [ -x "./${ABI_TOOL_NAME}" ]
+-then
+-        CMD="./${ABI_TOOL_NAME}"
+-else
+-        CMD="${ABI_TOOL_NAME}"
+-fi
+-
+-#
+-# Check all historical abi kernel files
+-#
+-for file in /boot/abi/abi_*
+-do
+-      filename=`basename ${file}`
+-      version=`echo ${filename} | awk -F _ '{ print $2 }'`
+-      abi=`echo ${filename} | awk -F _ '{ print $3 }'`
+-
+-      "${CMD}" "test-module" "${file}" "${1}" 2> /dev/null > /dev/null
+-      if [ "${?}" = "0" ]
+-      then
+-              echo "        Kernel:${version}, ABI/API:${abi} .... compatible"
+-      fi
+-done
+-
+diff --git a/tools/abi-checker/src/build_api_kernel_checker.sh b/tools/abi-checker/src/build_api_kernel_checker.sh
+deleted file mode 100755
+index 52693f8..0000000
+--- a/tools/abi-checker/src/build_api_kernel_checker.sh
++++ /dev/null
+@@ -1,38 +0,0 @@
+-#!/bin/sh
+-
+-# Find abi_version file
+-ksymver=`find ../../.. -name "Module.symvers"`
+-
+-ABI_TOOL_LOCATION="/usr/local/bin"
+-ABI_TOOL_NAME="abi-checker"
+-ABI_TOOL="${ABI_TOOL_LOCATION}/${ABI_TOOL_NAME}"
+-
+-if [ -x "${ABI_TOOL}" ]
+-then
+-        CMD="${ABI_TOOL}"
+-elif [ -x "./${ABI_TOOL_NAME}" ]
+-then
+-        CMD="./${ABI_TOOL_NAME}"
+-else
+-        CMD="${ABI_TOOL_NAME}"
+-fi
+-
+-# compare abi fingerprint file with kernel abi file
+-"${CMD}" test-kernel "${ksymver}" "../data/abi_${1}_${2}"
+-rc="${?}"
+-
+-# Test result
+-if [ ${rc} != "0" ]
+-then
+-      echo ""
+-      echo "----------------------------------------------------------------------------------------------------------------------------"
+-      echo ""
+-      echo "The kernel ABI/API has changed. Please update kernel version and add a new tools/abi-checker/data/abi_VERSION_ABIVER file "
+-      echo "(example tools/abi-checker/data/abi_${1}_${2} )."
+-      echo "The kernel sources build will abort."
+-      echo ""
+-      echo ""
+-      exit 1
+-fi
+-
+-exit 0
+diff --git a/tools/abi-checker/src/kernel_abi_checker.c b/tools/abi-checker/src/kernel_abi_checker.c
+deleted file mode 100644
+index da396e1..0000000
+--- a/tools/abi-checker/src/kernel_abi_checker.c
++++ /dev/null
+@@ -1,834 +0,0 @@
+-/*
+- * Build command
+- *
+- * gcc `pkg-config --cflags glib-2.0` kernel_abi_checker.c kernel_abi_checker_elf.c -lglib-2.0 -lelf
+- */
+-
+-#include <stdio.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <glib.h>
+-
+-#include "kernel_abi_checker.h"
+-
+-/*
+- * Functions write single record into ouptu symver file
+- */
+-int writeKernelSymbolsFile( FILE *ptr, char *symbolNameCrc, char *symbolName, char *symbolModule, char *flag )
+-{
+-      return fprintf( ptr, "%s\t%s\t%s\t%s\n", symbolNameCrc, symbolName, symbolModule, flag );
+-}
+-
+-/*
+- * Function open *symver file
+- */
+-FILE *getFile( char *fileName )
+-{
+-      FILE *fPtr = fopen( fileName, "r" );
+-
+-      if( fPtr == (FILE *)NULL )
+-      {
+-              PRINT_ERROR( "Canniot open : %s\n", fileName );
+-              return (FILE *)NULL;
+-      }
+-
+-      return fPtr;
+-}
+-
+-FILE *getOutputFile( char *fileName )
+-{
+-      FILE *fPtr = fopen( fileName, "w" );
+-
+-      if( fPtr == (FILE *)NULL )
+-      {
+-              PRINT_ERROR( "Canniot open : %s\n", fileName );
+-              return (FILE *)NULL;
+-      }
+-
+-      return fPtr;
+-}
+-
+-void releaseFile( FILE *fptr )
+-{
+-      if( fptr != (FILE *)NULL )
+-              fclose( fptr );
+-}
+-
+-void freeHashElement( gpointer data )
+-{
+-      free( (void *)data );
+-}
+-
+-/*
+- * Function creates hash table
+- */
+-GHashTable *createHashTable( void )
+-{
+-      return g_hash_table_new_full( g_str_hash, g_str_equal, NULL, freeHashElement );
+-}
+-
+-/*
+- * Function destroy hash table
+- */
+-void destroyHashTable( GHashTable *tab )
+-{
+-      if( tab != (GHashTable *)NULL )
+-              g_hash_table_destroy( tab );
+-}
+-
+-/*
+- * Function read i mput file.
+- * Function return single KernelSymbol structure.
+- *
+- * Return (KernelSymbol *)-1 - if errora
+-          (KernelSymbol *)NULL - eof
+- *
+- */
+-
+-KernelSymbol *readFileLine( FILE *fptr )
+-{
+-      KernelSymbol *symbolPtr = (KernelSymbol *)NULL;
+-      char inputLine[_LINE_LENGTH_ + 1];
+-      char *crcPtr;
+-      char *symNamePtr;
+-      char *moduleNamePtr;
+-      char *flag;
+-      char *ptr;
+-      int len;
+-      int i;
+-
+-      memset( inputLine, 0, sizeof( inputLine ) );
+-      ptr = fgets( inputLine, _LINE_LENGTH_, fptr );
+-      if( ptr == (char *) NULL )
+-              return (KernelSymbol *)NULL;
+-
+-      i = 0;
+-
+-      /* CRC */
+-      crcPtr = inputLine + i;
+-      for( ;inputLine[i] != '\0' && inputLine[i] != '\t' && i < _LINE_LENGTH_; i ++ );
+-
+-      if( i >= _LINE_LENGTH_ )
+-      {
+-              PRINT_ERROR( "Incorect input record format : \"%s\"\n", inputLine );
+-              return (KernelSymbol *)-1;
+-      }
+-      inputLine[i] = '\0';
+-      i++;
+-
+-      /* Symbol name */
+-      symNamePtr = inputLine + i;
+-
+-      for( ;inputLine[i] != '\0' && inputLine[i] != '\t' && i < _LINE_LENGTH_; i ++ );
+-      if( i >= _LINE_LENGTH_ )
+-      {
+-              PRINT_ERROR( "Incorect input record format : \"%s\"\n", inputLine );
+-              return (KernelSymbol *)-1;
+-      }
+-      inputLine[i] = '\0';
+-      i ++;
+-
+-      /* Module name */
+-      moduleNamePtr = inputLine + i;
+-
+-
+-      for( ;inputLine[i] != '\0' && inputLine[i] != '\t' && i < _LINE_LENGTH_; i ++ );
+-      if( i >= _LINE_LENGTH_ )
+-      {
+-              PRINT_ERROR( "Incorect input record format : \"%s\"\n", inputLine );
+-              return (KernelSymbol *)-1;
+-      }
+-      inputLine[i] = '\0';
+-      i ++;
+-
+-      /* Flag */
+-      flag = inputLine + i;
+-
+-
+-      len = strlen( flag );
+-      flag[len ==  0 ? 0 : len -1] = '\0';
+-
+-      /* Allocate new KernelSymbol */
+-      symbolPtr = (KernelSymbol *)malloc( sizeof( KernelSymbol ) );
+-      if( symbolPtr == (KernelSymbol *)NULL )
+-              return (KernelSymbol *)-1;
+-
+-      for( i = 0; moduleNamePtr[i] != '\0' && moduleNamePtr[i] != '\n'; i ++ );
+-      moduleNamePtr[i] = '\0';
+-
+-      /* Polulate output structure */
+-      strncpy( symbolPtr -> symbolName, symNamePtr, KERNEL_SYMBOL_NAME_LENGTH );
+-      strncpy( symbolPtr -> symbolNameCrc, crcPtr, KERNEL_SYMBOL_NAME_CRC );
+-      strncpy( symbolPtr -> symbolModule, moduleNamePtr, KERNEL_SYMBOL_MODULE );
+-      strncpy( symbolPtr -> flag, flag, KERNEL_SYMBOL_FLAG );
+-      symbolPtr -> status = KERNEL_SYMBOL_STATUS_NO_TESTED;
+-
+-      /* Return KernModule structure */
+-      return symbolPtr;
+-}
+-
+-/*
+- * Function adds single kernel symbol into hashtable.
+- * Functions assumes that hash table is correctlly allocated.
+- *
+- * Returns:
+- * -1 - duplicated key
+- *  0 - success
+- */
+-
+-int addKernelSymboltoHashBase( void *s, char *key, GHashTable *tab )
+-{
+-      void *testSym;
+-
+-      /* Check duplicates */
+-      testSym = (void *)g_hash_table_lookup( tab, key );
+-      if( testSym != (void *)NULL )
+-              return -1;
+-
+-      /* Add new symbol into hash table */
+-      g_hash_table_insert( tab, key, s );
+-      return 0;
+-}
+-
+-int addKernelSymboltoHash( KernelSymbol *s, GHashTable *tab )
+-{
+-      return addKernelSymboltoHashBase( (void *)s, s -> symbolName, tab );
+-}
+-
+-int readFile( FILE *fptr, GHashTable *tab )
+-{
+-        KernelSymbol *sym = (KernelSymbol *)NULL;
+-        while( 1 == 1 )
+-        {
+-                sym = readFileLine( fptr );
+-              if( sym == (KernelSymbol *)NULL )
+-              {
+-                      /* Koniec pliku */
+-                      break;
+-              }
+-
+-              if( sym == (KernelSymbol *)-1 )
+-              {
+-                      /* Error */
+-                      return -1;
+-              }
+-
+-              if( addKernelSymboltoHash( sym, tab ) < 0 )
+-              {
+-                      /* Error - duplicated value */
+-                      return -1;
+-              }
+-        }
+-
+-      /* Success */
+-      return 0;
+-}
+-
+-GHashTable *procesInputFile( char *name )
+-{
+-      GHashTable *hashTable = (GHashTable *)NULL;
+-      FILE *fptr = (FILE *)NULL;
+-
+-      /* Open input file */
+-      fptr = getFile( name );
+-      if( fptr == (FILE *)NULL )
+-              return (GHashTable *)NULL;
+-
+-      /* Create hash table for current symver */
+-      hashTable = createHashTable();
+-      if( hashTable == (GHashTable *)NULL )
+-      {
+-              PRINT_ERROR( "Error creating hash table \n" );
+-              releaseFile( fptr );
+-              return (GHashTable *)NULL;
+-      }
+-
+-      /* Read and create current hash table */
+-      if( readFile( fptr, hashTable ) != 0 )
+-      {
+-              PRINT_ERROR( "Error reading %s\n", name );
+-              destroyHashTable( hashTable );
+-              releaseFile( fptr );
+-              return (GHashTable *)NULL;
+-      }
+-
+-      /* Close input file */
+-      releaseFile( fptr );
+-
+-      return hashTable;
+-}
+-
+-typedef struct _foreachHashData_
+-{
+-      KernelSymbolStatistics *stat;
+-      GHashTable *curr;
+-      GHashTable *new;
+-} _foreachHashData_;
+-
+-void calculateStatistics_1( gpointer key_, gpointer value_, gpointer user_data_ )
+-{
+-      KernelSymbol *value = (KernelSymbol *)value_;
+-      _foreachHashData_ *user_data = (_foreachHashData_ *)user_data_;
+-      KernelSymbol *newSym;
+-
+-      /* Update current hash table symbols count */
+-      user_data -> stat -> symver_current_count ++;
+-
+-      /* Search for symbol in new hash table */
+-      newSym = (KernelSymbol *)g_hash_table_lookup( user_data -> new, key_ );
+-
+-      if( newSym == (KernelSymbol *)NULL )
+-      {
+-              /* Symbol was removed */
+-
+-              /* Set status */
+-              value -> status = KERNEL_SYMBOL_STATUS_REMOVED;
+-
+-              user_data -> stat -> removed_symbols_count ++;
+-              return;
+-      }
+-
+-      newSym -> status = KERNEL_SYMBOL_STATUS_VIEWED;
+-
+-      if( strcmp( value -> symbolNameCrc, newSym -> symbolNameCrc ) == 0 )
+-      {
+-              user_data -> stat -> no_changed_symbols_count ++;
+-              value -> status = KERNEL_SYMBOL_STATUS_NO_CHANGES;
+-      }
+-      else
+-      {
+-              user_data -> stat -> changed_symbols_count ++;
+-              value -> status = KERNEL_SYMBOL_STATUS_CHANGED;
+-      }
+-}
+-
+-void calculateStatistics_2( gpointer key_, gpointer value_, gpointer user_data_ )
+-{
+-      KernelSymbol *value = (KernelSymbol *)value_;
+-      _foreachHashData_ *user_data = (_foreachHashData_ *)user_data_;
+-
+-      /* Update current hash table symbols count */
+-      user_data -> stat -> symver_new_count ++;
+-
+-      if( value -> status == KERNEL_SYMBOL_STATUS_NO_TESTED )
+-      {
+-              user_data -> stat -> new_symbols_count ++;
+-              value -> status = KERNEL_SYMBOL_STATUS_NEW;
+-      }
+-}
+-
+-void collectStatistics( GHashTable *curr, GHashTable *new, KernelSymbolStatistics *statistics )
+-{
+-      _foreachHashData_ foreachdata;
+-
+-      /* Init foreach data */
+-      memset( (void *)statistics, 0, sizeof( KernelSymbolStatistics ) );
+-      foreachdata.stat = statistics;
+-      foreachdata.curr = curr;
+-      foreachdata.new = new;
+-
+-      /* Scan current hash table */
+-      g_hash_table_foreach( curr, calculateStatistics_1, (gpointer)&foreachdata );
+-
+-      /* Scan new hash table */
+-      g_hash_table_foreach( new, calculateStatistics_2, (gpointer)&foreachdata );
+-}
+-
+-void reportSymbolsDetails( gpointer key_, gpointer value_, gpointer user_data_ )
+-{
+-      KernelSymbol *value = (KernelSymbol *)value_;
+-
+-      switch( *((int *)user_data_) )
+-      {
+-      case 0 :        /* New */
+-              if( value -> status == KERNEL_SYMBOL_STATUS_NEW )
+-                      PRINT_INFO_RAW( "\t| NEW     | %40s | %10s | %s\n", value -> symbolName, value -> symbolNameCrc, value -> symbolModule );
+-              break;
+-
+-      case 1 :        /* Changed */
+-              if( value -> status == KERNEL_SYMBOL_STATUS_CHANGED )
+-                      PRINT_INFO_RAW( "\t| CHANGED | %40s | %10s | %s\n", value -> symbolName, value -> symbolNameCrc, value -> symbolModule );
+-              break;
+-
+-      case 2 :        /* Removed */
+-              if( value -> status == KERNEL_SYMBOL_STATUS_REMOVED )
+-                      PRINT_INFO_RAW( "\t| REMOVED | %40s | %10s | %s\n", value -> symbolName, value -> symbolNameCrc, value -> symbolModule );
+-              break;
+-      }
+-}
+-//[CHANGED]         cfg80211_send_rx_assoc         0x80e54114                  vmlinux
+-
+-void listChangedSymbols( GHashTable *curr, GHashTable *new, KernelSymbolStatistics *statistics )
+-{
+-      int mode = 0;
+-      int printFooter = 0;
+-
+-      if( statistics -> new_symbols_count == 0 && statistics -> changed_symbols_count == 0 && statistics -> removed_symbols_count == 0 )
+-              return;
+-
+-      PRINT_INFO_RAW( "\n" );
+-
+-      PRINT_INFO_RAW( "\tNew symbols in kernel\n" );
+-      PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
+-      PRINT_INFO_RAW( "\t| Change  |                 Linux kernel symbol name |        CRC | Module name \n" );
+-      PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
+-
+-      if( statistics -> new_symbols_count != 0 && new != (GHashTable *)NULL )
+-      {
+-              mode = 0;
+-              g_hash_table_foreach( new, reportSymbolsDetails, (gpointer)&mode );
+-              printFooter = 1;
+-      }
+-
+-      if( statistics -> changed_symbols_count != 0 && curr != (GHashTable *)NULL )
+-      {
+-              if( statistics -> new_symbols_count != 0 )
+-                      PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
+-
+-              mode = 1;
+-              g_hash_table_foreach( curr, reportSymbolsDetails, (gpointer)&mode );
+-              printFooter = 1;
+-      }
+-
+-      if( statistics -> removed_symbols_count != 0 && curr != (GHashTable *)NULL )
+-      {
+-              if( statistics -> new_symbols_count != 0 || statistics -> changed_symbols_count != 0 )
+-                      PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
+-
+-              mode = 2;
+-              g_hash_table_foreach( curr, reportSymbolsDetails, (gpointer)&mode );
+-              printFooter = 1;
+-      }
+-
+-      if( printFooter == 1 )
+-              PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
+-}
+-
+-void reportsStatistics( GHashTable *curr, GHashTable *new, KernelSymbolStatistics *statistics )
+-{
+-      listChangedSymbols( curr, new, statistics );
+-
+-      PRINT_INFO_RAW( "\n" );
+-      PRINT_INFO_RAW( "\tKernel symbols version statistics \n" );
+-      PRINT_INFO_RAW( "\t-------------------------------------------------\n" );
+-      PRINT_INFO_RAW( "\tSymbols in actual kernel/module . %d\n", statistics -> symver_current_count );
+-      if( new != (GHashTable *)NULL )
+-              PRINT_INFO_RAW( "\tSymbols in new kernel/module .... %d\n", statistics -> symver_new_count );
+-      PRINT_INFO_RAW( "\tNew symbols ..................... %d\n", statistics -> new_symbols_count );
+-      PRINT_INFO_RAW( "\tRemoved symbols ................. %d\n", statistics -> removed_symbols_count );
+-      PRINT_INFO_RAW( "\tChanged symbols ................. %d\n", statistics -> changed_symbols_count );
+-      PRINT_INFO_RAW( "\tUnchanged symbols ............... %d\n", statistics -> no_changed_symbols_count );
+-      PRINT_INFO_RAW( "\n" );
+-}
+-
+-void printUsage( char *progName, int type )
+-{
+-      switch( type )
+-      {
+-      case 0 :
+-              PRINT_INFO_RAW( "\tUsage: %s test-kernel in_symver_file_1 in_symver_file_2\n", progName );
+-              break;
+-
+-      case 1 :
+-              PRINT_INFO_RAW( "\tUsage: %s build-list in_module_symbols_file in_kernel_symver_file outt_module_symver_file\n", progName );
+-              break;
+-
+-      case 2 :
+-              PRINT_INFO_RAW( "\tUsage: %s dump-module kernel_symver_file ko_module_file output_module_symver_file\n", progName );
+-              break;
+-
+-      case 4 :
+-              PRINT_INFO_RAW( "\tUsage: %s test-module kernel_symver_file ko_module_file \n", progName );
+-              break;
+-
+-      default :
+-              PRINT_INFO_RAW( "\tUsage: %s test|build-list file1 file2 [output_file] \n", progName );
+-              break;
+-      }
+-}
+-
+-/*
+- * Function parses input parameters and return.
+- * Return:
+- *            -1 - error
+- *             0 - test mode  - the program will compare two symver files
+- *             1 - build mode - for given module sybmbols file and kernel symver creates files
+- *                              with list kernel symbols used by the module.
+- */
+-int parsInputParameters( int argc, char **argv, char **f1, char **f2, char **f3 )
+-{
+-      char *toolName = argv[0];
+-
+-      if( argc < 2 )
+-      {
+-              printUsage( toolName, -1 );
+-              return -1;
+-      }
+-
+-      if( strcmp( argv[1], "test-kernel" ) == 0 )
+-      {
+-              /* Test mode */
+-              if( argc < 4 )
+-              {
+-                      printUsage( toolName, 0 );
+-                      return -1;
+-              }
+-              *f1 = argv[2];
+-              *f2 = argv[3];
+-              *f3 = (char *)NULL;
+-
+-              return 0;
+-
+-      }
+-      else
+-      if( strcmp( argv[1], "build-list" ) == 0 )
+-      {
+-              /* Build mode */
+-              if( argc < 5 )
+-              {
+-                      printUsage( toolName, 1 );
+-                      return -1;
+-              }
+-              *f1 = argv[2];
+-              *f2 = argv[3];
+-              *f3 = argv[4];
+-
+-              return 1;
+-      }
+-      else
+-      if( strcmp( argv[1], "dump-module" ) == 0 )
+-      {
+-              /* Build mode */
+-              if( argc < 5 )
+-              {
+-                      printUsage( toolName, 2 );
+-                      return -1;
+-              }
+-              *f1 = argv[2];
+-              *f2 = argv[3];
+-              *f3 = argv[4];
+-
+-              return 2;
+-      }
+-      else
+-      if( strcmp( argv[1], "usage" ) == 0 )
+-      {
+-              return 3;
+-      }
+-      else
+-      if( strcmp( argv[1], "test-module" ) == 0 )
+-      {
+-              /* Test mode */
+-              if( argc < 4 )
+-              {
+-                      printUsage( toolName, 4 );
+-                      return -1;
+-              }
+-              *f1 = argv[2];
+-              *f2 = argv[3];
+-              *f3 = (char *)NULL;
+-
+-              return 4;
+-      }
+-
+-
+-      printUsage( toolName, -1 );
+-      return -1;
+-}
+-
+-int testKernel( char *f1, char *f2 )
+-{
+-      GHashTable *curr_hashTable = (GHashTable *)NULL;
+-      GHashTable *new_hashTable = (GHashTable *)NULL;
+-      KernelSymbolStatistics statistics;
+-
+-      /*
+-       * ----------------------------------------------
+-       * Read current symver file
+-       * ----------------------------------------------
+-       */
+-      curr_hashTable = procesInputFile( f1 );
+-      if( curr_hashTable == (GHashTable *)NULL )
+-      {
+-              PRINT_ERROR( "Error read input \"%s\" file.\n", f1 );
+-              return 1;
+-      }
+-
+-      /*
+-       * ----------------------------------------------
+-       * Read new symver file
+-       * ----------------------------------------------
+-      */
+-      new_hashTable = procesInputFile( f2 );
+-      if( new_hashTable == (GHashTable *)NULL )
+-      {
+-              destroyHashTable( curr_hashTable );
+-              PRINT_ERROR( "Error read input \"%s\" file.\n", f2 );
+-        return 1;
+-      }
+-
+-      /*
+-       * ----------------------------------------------
+-       * Compute statistics
+-       * ----------------------------------------------
+-       */
+-      collectStatistics( curr_hashTable, new_hashTable, &statistics );
+-
+-      /*
+-       * ---------------------------------------------
+-       * Report changes
+-       * ---------------------------------------------
+-       */
+-      reportsStatistics( curr_hashTable, new_hashTable, &statistics );
+-
+-      /*
+-       * --------------------------------------------
+-       * Free hash tables
+-       * --------------------------------------------
+-       */
+-      destroyHashTable( curr_hashTable );
+-      destroyHashTable( new_hashTable );
+-
+-      if( statistics.changed_symbols_count != 0 || statistics.removed_symbols_count != 0 || statistics.new_symbols_count != 0 )
+-              return 2;
+-
+-      return 0;
+-}
+-
+-void collectStatisticsModule( GHashTable *curr, GHashTable *module, KernelSymbolStatistics *statistics )
+-{
+-      _foreachHashData_ foreachdata;
+-
+-      /* Init foreach data */
+-      memset( (void *)statistics, 0, sizeof( KernelSymbolStatistics ) );
+-      foreachdata.stat = statistics;
+-      foreachdata.curr = module;
+-      foreachdata.new = curr;
+-
+-      /* Scan current hash table */
+-      g_hash_table_foreach( module, calculateStatistics_1, (gpointer)&foreachdata );
+-}
+-
+-
+-int testModule( char *f1, char *f2 )
+-{
+-      GHashTable *curr_hashTable = (GHashTable *)NULL;
+-      GHashTable *module_hashTable = (GHashTable *)NULL;
+-      KernelSymbolStatistics statistics;
+-
+-      /*
+-       * ----------------------------------------------
+-       * Read current symver file
+-       * ----------------------------------------------
+-       */
+-      curr_hashTable = procesInputFile( f1 );
+-      if( curr_hashTable == (GHashTable *)NULL )
+-      {
+-              PRINT_ERROR( "Error read input \"%s\" file.\n", f1 );
+-              return 1;
+-      }
+-
+-      /*
+-       * ----------------------------------------------
+-       * Read module symbols
+-       * ----------------------------------------------
+-      */
+-      module_hashTable = procesInputFile( f2 );
+-      if( module_hashTable == (GHashTable *)NULL )
+-      {
+-              destroyHashTable( curr_hashTable );
+-              PRINT_ERROR( "Error read input \"%s\" file.\n", f2 );
+-              return 1;
+-      }
+-
+-      /*
+-       * ----------------------------------------------
+-       * Compute statistics
+-       * ----------------------------------------------
+-       */
+-      collectStatisticsModule( curr_hashTable, module_hashTable, &statistics );
+-
+-      /*
+-       * ---------------------------------------------
+-       * Report changes
+-       * ---------------------------------------------
+-       */
+-      reportsStatistics( module_hashTable, (GHashTable *)NULL, &statistics );
+-
+-      /*
+-       * --------------------------------------------
+-       * Free hash tables
+-       * --------------------------------------------
+-       */
+-      destroyHashTable( curr_hashTable );
+-      destroyHashTable( module_hashTable );
+-
+-      if( statistics.changed_symbols_count != 0 || statistics.removed_symbols_count != 0 )
+-              return 2;
+-
+-      return 0;
+-}
+-
+-int buildListMode( char *f1, char *f2, char *f3 )
+-{
+-      GHashTable *curr_hashTable = (GHashTable *)NULL;
+-      char inputLine[_LINE_LENGTH_ + 1];
+-      FILE *symListFptr = (FILE *)NULL;
+-      FILE *outFptr = (FILE *)NULL;
+-      KernelSymbol *kSym;
+-      int size;
+-
+-      /*
+-       * ----------------------------------------------
+-       * Read current symver file
+-       * ----------------------------------------------
+-       */
+-      curr_hashTable = procesInputFile( f1 );
+-      if( curr_hashTable == (GHashTable *)NULL )
+-      {
+-              PRINT_ERROR( "Error read input \"%s\" file.\n", f1 );
+-              return 1;
+-      }
+-
+-      /*
+-       * Open files
+-       */
+-      outFptr = getOutputFile( f3 );
+-      symListFptr = getFile( f2 );
+-
+-      if( symListFptr == (FILE *)NULL || outFptr == (FILE *)NULL )
+-      {
+-              destroyHashTable( curr_hashTable );
+-              releaseFile( symListFptr );
+-              releaseFile( outFptr );
+-              PRINT_ERROR( "Error open files : \"%s\", \"%s\".\n", f2, f3 );
+-              return 1;
+-      }
+-
+-      while( fgets( inputLine, _LINE_LENGTH_, symListFptr ) )
+-      {
+-              size = strlen( inputLine );
+-              inputLine[size == 0 ? 0 :size - 1] = '\0';
+-
+-              /* Search for symbol in new hash table */
+-              kSym = (KernelSymbol *)g_hash_table_lookup( curr_hashTable, inputLine );
+-
+-              if( kSym != (KernelSymbol *)NULL )
+-                      writeKernelSymbolsFile( outFptr, kSym -> symbolNameCrc, kSym -> symbolName, kSym -> symbolModule, kSym -> flag );
+-      }
+-
+-      destroyHashTable( curr_hashTable );
+-      releaseFile( symListFptr );
+-      releaseFile( outFptr );
+-
+-      return 0;
+-}
+-
+-int callDumpModuleSymbols( char *f1, char *f2, char *f3 )
+-{
+-      GHashTable *curr_hashTable = (GHashTable *)NULL;
+-      GHashTable *module_hashTable = (GHashTable *)NULL;
+-
+-      /*
+-       * ----------------------------------------------
+-       * Read current symver file
+-       * ----------------------------------------------
+-       */
+-      curr_hashTable = procesInputFile( f1 );
+-      if( curr_hashTable == (GHashTable *)NULL )
+-      {
+-              PRINT_ERROR( "Error read input \"%s\" file.\n", f1 );
+-              return 1;
+-      }
+-
+-      /*
+-       * ----------------------------------------------
+-       * Read kernel module *.ko file
+-       * ----------------------------------------------
+-       */
+-      module_hashTable = readEfl( f2 );
+-      if( module_hashTable == (GHashTable *)NULL )
+-      {
+-              PRINT_ERROR( "Error read input \"%s\" file.\n", f2 );
+-              destroyHashTable( curr_hashTable );
+-              return 1;
+-      }
+-
+-      /*
+-       * Dump module symbols into output file
+-       */
+-      if( dumpModuleSymbols( f3, module_hashTable, curr_hashTable ) < 0 )
+-      {
+-              PRINT_ERROR( "Error creating dump file \"%s\"\n", f3 );
+-              destroyHashTable( curr_hashTable );
+-              return 1;
+-      }
+-
+-      /*
+-       * Free hash tables
+-       */
+-      destroyHashTable( module_hashTable );
+-      destroyHashTable( curr_hashTable );
+-
+-      return 0;
+-}
+-
+-int printUsageInfo( char *f1 )
+-{
+-      PRINT_INFO_RAW( "\n" );
+-      PRINT_INFO_RAW( "\tProgram usage\n" );
+-      PRINT_INFO_RAW( "\t-----------------------------------------------\n" );
+-      PRINT_INFO_RAW( "\n" );
+-      printUsage( f1, 0 );
+-      printUsage( f1, 1 );
+-      printUsage( f1, 2 );
+-
+-      return 0;
+-}
+-
+-int main(int argc, char** argv)
+-{
+-      char *f1 = (char *)NULL;
+-      char *f2 = (char *)NULL;
+-      char *f3 = (char *)NULL;
+-      int rc = -1;
+-
+-      int mode = parsInputParameters( argc, argv, &f1, &f2, &f3 );
+-
+-      switch( mode )
+-      {
+-      case 0 :
+-              rc = testKernel( f1, f2 );
+-              break;
+-
+-      case 1 :
+-              rc = buildListMode( f1, f2, f3 );
+-              break;
+-
+-      case 2 :
+-              rc = callDumpModuleSymbols( f1, f2, f3 );
+-              break;
+-
+-      case 3 :
+-              rc = printUsageInfo( argv[0] );
+-              break;
+-
+-      case 4 :
+-              rc = testModule( f1, f2 );
+-              break;
+-      }
+-
+-      PRINT_INFO_RAW( "\n" );
+-
+-      if( rc == 2 )
+-              PRINT_INFO_RAW( "\tChanges !!!\n" );
+-      else
+-      if( rc == 1 )
+-              PRINT_INFO_RAW( "\tError !!!\n" );
+-      else
+-              PRINT_INFO_RAW( "\tDone\n" );
+-
+-      PRINT_INFO_RAW( "\n" );
+-
+-      return ( rc != 0 ) ? 1 : 0;
+-}
+diff --git a/tools/abi-checker/src/kernel_abi_checker.h b/tools/abi-checker/src/kernel_abi_checker.h
+deleted file mode 100644
+index 8df231e..0000000
+--- a/tools/abi-checker/src/kernel_abi_checker.h
++++ /dev/null
+@@ -1,62 +0,0 @@
+-#ifndef _kernel_abi_checker_h_
+-#define _kernel_abi_checker_h_
+-
+-#include <stdio.h>
+-#include <glib.h>
+-
+-/*
+- * Definitions
+- */
+-#define KERNEL_SYMBOL_NAME_LENGTH     64
+-#define KERNEL_SYMBOL_NAME_CRC                32
+-#define KERNEL_SYMBOL_MODULE          256
+-#define KERNEL_SYMBOL_FLAG                    256
+-
+-#define KERNEL_SYMBOL_STATUS_NO_TESTED        0
+-#define KERNEL_SYMBOL_STATUS_NO_CHANGES       1
+-#define KERNEL_SYMBOL_STATUS_NEW              2
+-#define KERNEL_SYMBOL_STATUS_REMOVED  3
+-#define KERNEL_SYMBOL_STATUS_CHANGED  4
+-#define KERNEL_SYMBOL_STATUS_VIEWED           5
+-
+-#define _LINE_LENGTH_ 4096
+-
+-/*
+- * Data types
+- */
+-typedef struct KernelSymbol
+-{
+-      char symbolName[KERNEL_SYMBOL_NAME_LENGTH + 1];
+-      char symbolNameCrc[KERNEL_SYMBOL_NAME_CRC + 1];
+-      char symbolModule[KERNEL_SYMBOL_MODULE + 1];
+-      char flag[KERNEL_SYMBOL_FLAG + 1];
+-      int status;
+-
+-} KernelSymbol;
+-
+-typedef struct KernelSymbolStatistics
+-{
+-      int symver_current_count;
+-      int symver_new_count;
+-
+-      int new_symbols_count;
+-      int removed_symbols_count;
+-      int changed_symbols_count;
+-      int no_changed_symbols_count;
+-
+-} KernelSymbolStatistics;
+-
+-extern int writeKernelSymbolsFile( FILE *, char *, char *, char *, char * );
+-extern int addKernelSymboltoHashBase( void *, char *, GHashTable * );
+-extern int dumpModuleSymbols( char *, GHashTable *, GHashTable * );
+-extern void destroyHashTable( GHashTable * );
+-extern GHashTable *createHashTable( void );
+-extern FILE *getOutputFile( char * );
+-extern void releaseFile( FILE * );
+-GHashTable *readEfl( char * );
+-
+-#define PRINT_ERROR(...)  do { fprintf( stderr, "ERROR : " ); fprintf( stderr, __VA_ARGS__ ); } while( 0 )
+-#define PRINT_INFO_RAW(...)   do { fprintf( stdout, __VA_ARGS__ ); } while( 0 )
+-#define PRINT_INFO(...)   do { fprintf( stderr, "INFO  : " ); fprintf( stdout, __VA_ARGS__ ); } while( 0 )
+-
+-#endif
+diff --git a/tools/abi-checker/src/kernel_abi_checker_elf.c b/tools/abi-checker/src/kernel_abi_checker_elf.c
+deleted file mode 100644
+index 6f4f28c..0000000
+--- a/tools/abi-checker/src/kernel_abi_checker_elf.c
++++ /dev/null
+@@ -1,172 +0,0 @@
+-#include "kernel_abi_checker.h"
+-
+-#include <sys/types.h>
+-#include <sys/stat.h>
+-#include <unistd.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <libelf.h>
+-#include <stdio.h>
+-#include <fcntl.h>
+-#include <gelf.h>
+-
+-GHashTable *readEfl( char *file )
+-{
+-      GHashTable *outputHashTable = (GHashTable *)NULL;
+-      Elf_Data *edata = (Elf_Data *)NULL;
+-      Elf_Scn *scn = (Elf_Scn *)NULL;
+-      char *base_ptr = (char *)NULL;
+-      char *sname = (char *)NULL;
+-      Elf *elf = (Elf *)NULL;
+-      struct stat elf_stats;
+-      int symbol_count;
+-      GElf_Shdr shdr;
+-      GElf_Sym sym;
+-      int size;
+-      int fd;
+-      int i;
+-
+-      fd = open( file, O_RDONLY );
+-      if( fd < 0 )
+-      {
+-              PRINT_ERROR( "Cannot open efl file : %s\n", file );
+-              return (GHashTable *)NULL;
+-      }
+-
+-      if( ( fstat( fd, &elf_stats ) ) )
+-      {
+-              PRINT_ERROR( "Cannot stat efl file : %s\n", file );
+-              close(fd );
+-              return (GHashTable *)NULL;
+-      }
+-
+-      base_ptr = (char *) malloc( elf_stats.st_size );
+-      if( base_ptr == (char *)NULL )
+-      {
+-              PRINT_ERROR( "Memory allocation error.\n" );
+-              close( fd );
+-              return (GHashTable *)NULL;
+-      }
+-
+-      if( ( read( fd, base_ptr, elf_stats.st_size ) ) < elf_stats.st_size )
+-      {
+-              PRINT_ERROR( "Cannot read input efl file : %s\n", file );
+-        free( base_ptr );
+-        close( fd );
+-              return (GHashTable *)NULL;
+-      }
+-      free( base_ptr );
+-
+-      /* Create output hash table */
+-      outputHashTable = createHashTable();
+-      if( outputHashTable == (GHashTable *)NULL )
+-      {
+-              PRINT_ERROR( "Memory allocation for hash table error : %s\n", file );
+-        free( base_ptr );
+-        close( fd );
+-              return (GHashTable *)NULL;
+-      }
+-
+-      if( elf_version( EV_CURRENT ) == EV_NONE )
+-              fprintf( stderr, "WARNING Elf Library is out of date!\n" );
+-
+-      // Iterate through section headers again this time well stop when we find symbols
+-      elf = elf_begin( fd, ELF_C_READ, NULL );
+-
+-      while( ( scn = elf_nextscn( elf, scn ) ) != (Elf_Scn *)NULL )
+-      {
+-              gelf_getshdr( scn, &shdr );
+-
+-              // When we find a section header marked SHT_SYMTAB stop and get symbols
+-              if(shdr.sh_type == SHT_SYMTAB)
+-              {
+-                      // edata points to our symbol table
+-                      edata = elf_getdata(scn, edata);
+-
+-                      symbol_count = shdr.sh_size / shdr.sh_entsize;
+-
+-                      for( i = 0; i < symbol_count; i++ )
+-                      {
+-                              /* Get symbol */
+-                              gelf_getsym( edata, i, &sym );
+-
+-                              /* Get symbol name length */
+-                              size = strlen( elf_strptr( elf, shdr.sh_link, sym.st_name ) );
+-                              if( size != 0 )
+-                              {
+-                                      /* allocate memory for symbol name */
+-                                      sname = (char *)malloc( sizeof( char ) * ( size + 1 ) );
+-                                      if( sname == (char *)NULL )
+-                                      {
+-                                              PRINT_ERROR( "Memory allocation for hash table error : %s\n", file );
+-                                              destroyHashTable( outputHashTable );
+-                                      close( fd );
+-                                              return (GHashTable *)NULL;
+-                                      }
+-
+-                                      strcpy( sname, elf_strptr( elf, shdr.sh_link, sym.st_name ) );
+-
+-                                      // Add symbol to hash
+-                                      if( addKernelSymboltoHashBase( (void *)sname, sname, outputHashTable ) < 0 )
+-                                      {
+-                                              // If duplicated key free memory
+-                                              free( sname );
+-                                      }
+-
+-                              }
+-                      }
+-              }
+-      }
+-
+-      /* Close file */
+-      close( fd );
+-
+-      /* Return hash table */
+-      return outputHashTable;
+-}
+-
+-/*
+- * Private user data definition.
+- */
+-
+-typedef struct _efl_user_data_
+-{
+-      GHashTable *kernelHash;
+-      FILE *outFilePtr;
+-} _efl_user_data_;
+-
+-
+-void dumpModuleSymbolsIteration( gpointer key_, gpointer value_, gpointer user_data_ )
+-{
+-      char *key = (char *)key_;
+-      _efl_user_data_ *user_data = (_efl_user_data_ *)user_data_;
+-      KernelSymbol *ptr = (KernelSymbol *)NULL;
+-
+-      ptr = (KernelSymbol *)g_hash_table_lookup( user_data -> kernelHash, key );
+-      if( ptr != (void *)NULL )
+-              writeKernelSymbolsFile( user_data -> outFilePtr, ptr -> symbolNameCrc, ptr -> symbolName, ptr -> symbolModule, ptr -> flag );
+-}
+-
+-/*
+- * Function dumps into output files kernel symbols that
+- * are use in the module
+- */
+-int dumpModuleSymbols( char *outoutFile, GHashTable *moduleSymbols, GHashTable *kernelSymbols )
+-{
+-      FILE *outputFilePtr = getOutputFile( outoutFile );
+-      _efl_user_data_ userData;
+-
+-      if( outputFilePtr == (FILE *)NULL )
+-              return -1;
+-
+-      userData.outFilePtr = outputFilePtr;
+-      userData.kernelHash = kernelSymbols;
+-
+-      /* Loob module symbols */
+-      g_hash_table_foreach( moduleSymbols, dumpModuleSymbolsIteration, (gpointer)&userData );
+-
+-      /* Close output file */
+-      releaseFile( outputFilePtr );
+-
+-      return 0;
+-}
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1064-Revert-linux-kernel-and-linux-kernel-modules-ABI-nex.patch b/patches.tizen/1064-Revert-linux-kernel-and-linux-kernel-modules-ABI-nex.patch
new file mode 100644 (file)
index 0000000..ed344d8
--- /dev/null
@@ -0,0 +1,1268 @@
+From 209e7b321fe6779a8d0ee1f18279c1a9578d2ed3 Mon Sep 17 00:00:00 2001
+From: Jacek Pielaszkiewicz <j.pielaszkie@samsung.com>
+Date: Thu, 2 Jan 2014 22:22:38 -0800
+Subject: [PATCH 1064/1302] Revert "linux-kernel and linux kernel modules ABI -
+ next changes"
+
+This reverts commit 45fe7044915b03bc6444102e55e45cccf4a4455d.
+
+Change-Id: Ie479df1039134b1fcd89bc942c61d6669c51faf0
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ abi-checker/sample/LICENSE                         | 848 ---------------------
+ abi-checker/sample/Makefile                        |  12 -
+ .../packaging/udisks-automount-agent.spec.txt      |  53 --
+ abi-checker/sample/sample_module.c                 | 107 ---
+ abi-checker/src/abi-module-checker                 |  29 -
+ abi-checker/src/abi-module-dumper                  |  38 -
+ abi-checker/src/abi-module-kernels-list            |  31 -
+ abi-checker/src/kernel_abi_checker.c               |   2 +-
+ packaging/linux-kernel.spec                        |  19 -
+ 9 files changed, 1 insertion(+), 1138 deletions(-)
+ delete mode 100644 abi-checker/sample/LICENSE
+ delete mode 100644 abi-checker/sample/Makefile
+ delete mode 100644 abi-checker/sample/packaging/udisks-automount-agent.spec.txt
+ delete mode 100644 abi-checker/sample/sample_module.c
+ delete mode 100755 abi-checker/src/abi-module-checker
+ delete mode 100755 abi-checker/src/abi-module-dumper
+ delete mode 100755 abi-checker/src/abi-module-kernels-list
+
+diff --git a/abi-checker/sample/LICENSE b/abi-checker/sample/LICENSE
+deleted file mode 100644
+index 63fabc1..0000000
+--- a/abi-checker/sample/LICENSE
++++ /dev/null
+@@ -1,848 +0,0 @@
+-Copyright (C) 2007-2011 David Zeuthen <zeuthen@gmail.com>
+-Copyright (C) 2007-2011 Red Hat, Inc.
+-All Rights Reserved.
+-
+-The source code for the udisks daemon and command-line tools are
+-licensed to you under the GNU General Public License. Either version 2
+-of the License, or (at your option) any later version.
+-
+-The source code for the libudisks2 dynamic library is licensed to you
+-under the GNU Library General Public License. Either version 2 of the
+-License, or (at your option) any later version.
+-
+-Each file is marked with copyright and licensing headers.
+-
+-The GPLv2 and LGPLv2 licenses are included below.
+-
+--- BEGIN GPLv2+ License ---
+-
+-                    GNU GENERAL PUBLIC LICENSE
+-                       Version 2, June 1991
+-
+- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+- 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+-
+- Everyone is permitted to copy and distribute verbatim copies
+- of this license document, but changing it is not allowed.
+-
+-                            Preamble
+-
+-  The licenses for most software are designed to take away your
+-freedom to share and change it.  By contrast, the GNU General Public
+-License is intended to guarantee your freedom to share and change free
+-software--to make sure the software is free for all its users.  This
+-General Public License applies to most of the Free Software
+-Foundation's software and to any other program whose authors commit to
+-using it.  (Some other Free Software Foundation software is covered by
+-the GNU Library General Public License instead.)  You can apply it to
+-your programs, too.
+-
+-  When we speak of free software, we are referring to freedom, not
+-price.  Our General Public Licenses are designed to make sure that you
+-have the freedom to distribute copies of free software (and charge for
+-this service if you wish), that you receive source code or can get it
+-if you want it, that you can change the software or use pieces of it
+-in new free programs; and that you know you can do these things.
+-
+-  To protect your rights, we need to make restrictions that forbid
+-anyone to deny you these rights or to ask you to surrender the rights.
+-These restrictions translate to certain responsibilities for you if you
+-distribute copies of the software, or if you modify it.
+-
+-  For example, if you distribute copies of such a program, whether
+-gratis or for a fee, you must give the recipients all the rights that
+-you have.  You must make sure that they, too, receive or can get the
+-source code.  And you must show them these terms so they know their
+-rights.
+-
+-  We protect your rights with two steps: (1) copyright the software, and
+-(2) offer you this license which gives you legal permission to copy,
+-distribute and/or modify the software.
+-
+-  Also, for each author's protection and ours, we want to make certain
+-that everyone understands that there is no warranty for this free
+-software.  If the software is modified by someone else and passed on, we
+-want its recipients to know that what they have is not the original, so
+-that any problems introduced by others will not reflect on the original
+-authors' reputations.
+-
+-  Finally, any free program is threatened constantly by software
+-patents.  We wish to avoid the danger that redistributors of a free
+-program will individually obtain patent licenses, in effect making the
+-program proprietary.  To prevent this, we have made it clear that any
+-patent must be licensed for everyone's free use or not licensed at all.
+-
+-  The precise terms and conditions for copying, distribution and
+-modification follow.
+-
+-                    GNU GENERAL PUBLIC LICENSE
+-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+-
+-  0. This License applies to any program or other work which contains
+-a notice placed by the copyright holder saying it may be distributed
+-under the terms of this General Public License.  The "Program", below,
+-refers to any such program or work, and a "work based on the Program"
+-means either the Program or any derivative work under copyright law:
+-that is to say, a work containing the Program or a portion of it,
+-either verbatim or with modifications and/or translated into another
+-language.  (Hereinafter, translation is included without limitation in
+-the term "modification".)  Each licensee is addressed as "you".
+-
+-Activities other than copying, distribution and modification are not
+-covered by this License; they are outside its scope.  The act of
+-running the Program is not restricted, and the output from the Program
+-is covered only if its contents constitute a work based on the
+-Program (independent of having been made by running the Program).
+-Whether that is true depends on what the Program does.
+-
+-  1. You may copy and distribute verbatim copies of the Program's
+-source code as you receive it, in any medium, provided that you
+-conspicuously and appropriately publish on each copy an appropriate
+-copyright notice and disclaimer of warranty; keep intact all the
+-notices that refer to this License and to the absence of any warranty;
+-and give any other recipients of the Program a copy of this License
+-along with the Program.
+-
+-You may charge a fee for the physical act of transferring a copy, and
+-you may at your option offer warranty protection in exchange for a fee.
+-
+-  2. You may modify your copy or copies of the Program or any portion
+-of it, thus forming a work based on the Program, and copy and
+-distribute such modifications or work under the terms of Section 1
+-above, provided that you also meet all of these conditions:
+-
+-    a) You must cause the modified files to carry prominent notices
+-    stating that you changed the files and the date of any change.
+-
+-    b) You must cause any work that you distribute or publish, that in
+-    whole or in part contains or is derived from the Program or any
+-    part thereof, to be licensed as a whole at no charge to all third
+-    parties under the terms of this License.
+-
+-    c) If the modified program normally reads commands interactively
+-    when run, you must cause it, when started running for such
+-    interactive use in the most ordinary way, to print or display an
+-    announcement including an appropriate copyright notice and a
+-    notice that there is no warranty (or else, saying that you provide
+-    a warranty) and that users may redistribute the program under
+-    these conditions, and telling the user how to view a copy of this
+-    License.  (Exception: if the Program itself is interactive but
+-    does not normally print such an announcement, your work based on
+-    the Program is not required to print an announcement.)
+-
+-These requirements apply to the modified work as a whole.  If
+-identifiable sections of that work are not derived from the Program,
+-and can be reasonably considered independent and separate works in
+-themselves, then this License, and its terms, do not apply to those
+-sections when you distribute them as separate works.  But when you
+-distribute the same sections as part of a whole which is a work based
+-on the Program, the distribution of the whole must be on the terms of
+-this License, whose permissions for other licensees extend to the
+-entire whole, and thus to each and every part regardless of who wrote it.
+-
+-Thus, it is not the intent of this section to claim rights or contest
+-your rights to work written entirely by you; rather, the intent is to
+-exercise the right to control the distribution of derivative or
+-collective works based on the Program.
+-
+-In addition, mere aggregation of another work not based on the Program
+-with the Program (or with a work based on the Program) on a volume of
+-a storage or distribution medium does not bring the other work under
+-the scope of this License.
+-
+-  3. You may copy and distribute the Program (or a work based on it,
+-under Section 2) in object code or executable form under the terms of
+-Sections 1 and 2 above provided that you also do one of the following:
+-
+-    a) Accompany it with the complete corresponding machine-readable
+-    source code, which must be distributed under the terms of Sections
+-    1 and 2 above on a medium customarily used for software interchange; or,
+-
+-    b) Accompany it with a written offer, valid for at least three
+-    years, to give any third party, for a charge no more than your
+-    cost of physically performing source distribution, a complete
+-    machine-readable copy of the corresponding source code, to be
+-    distributed under the terms of Sections 1 and 2 above on a medium
+-    customarily used for software interchange; or,
+-
+-    c) Accompany it with the information you received as to the offer
+-    to distribute corresponding source code.  (This alternative is
+-    allowed only for noncommercial distribution and only if you
+-    received the program in object code or executable form with such
+-    an offer, in accord with Subsection b above.)
+-
+-The source code for a work means the preferred form of the work for
+-making modifications to it.  For an executable work, complete source
+-code means all the source code for all modules it contains, plus any
+-associated interface definition files, plus the scripts used to
+-control compilation and installation of the executable.  However, as a
+-special exception, the source code distributed need not include
+-anything that is normally distributed (in either source or binary
+-form) with the major components (compiler, kernel, and so on) of the
+-operating system on which the executable runs, unless that component
+-itself accompanies the executable.
+-
+-If distribution of executable or object code is made by offering
+-access to copy from a designated place, then offering equivalent
+-access to copy the source code from the same place counts as
+-distribution of the source code, even though third parties are not
+-compelled to copy the source along with the object code.
+-
+-  4. You may not copy, modify, sublicense, or distribute the Program
+-except as expressly provided under this License.  Any attempt
+-otherwise to copy, modify, sublicense or distribute the Program is
+-void, and will automatically terminate your rights under this License.
+-However, parties who have received copies, or rights, from you under
+-this License will not have their licenses terminated so long as such
+-parties remain in full compliance.
+-
+-  5. You are not required to accept this License, since you have not
+-signed it.  However, nothing else grants you permission to modify or
+-distribute the Program or its derivative works.  These actions are
+-prohibited by law if you do not accept this License.  Therefore, by
+-modifying or distributing the Program (or any work based on the
+-Program), you indicate your acceptance of this License to do so, and
+-all its terms and conditions for copying, distributing or modifying
+-the Program or works based on it.
+-
+-  6. Each time you redistribute the Program (or any work based on the
+-Program), the recipient automatically receives a license from the
+-original licensor to copy, distribute or modify the Program subject to
+-these terms and conditions.  You may not impose any further
+-restrictions on the recipients' exercise of the rights granted herein.
+-You are not responsible for enforcing compliance by third parties to
+-this License.
+-
+-  7. If, as a consequence of a court judgment or allegation of patent
+-infringement or for any other reason (not limited to patent issues),
+-conditions are imposed on you (whether by court order, agreement or
+-otherwise) that contradict the conditions of this License, they do not
+-excuse you from the conditions of this License.  If you cannot
+-distribute so as to satisfy simultaneously your obligations under this
+-License and any other pertinent obligations, then as a consequence you
+-may not distribute the Program at all.  For example, if a patent
+-license would not permit royalty-free redistribution of the Program by
+-all those who receive copies directly or indirectly through you, then
+-the only way you could satisfy both it and this License would be to
+-refrain entirely from distribution of the Program.
+-
+-If any portion of this section is held invalid or unenforceable under
+-any particular circumstance, the balance of the section is intended to
+-apply and the section as a whole is intended to apply in other
+-circumstances.
+-
+-It is not the purpose of this section to induce you to infringe any
+-patents or other property right claims or to contest validity of any
+-such claims; this section has the sole purpose of protecting the
+-integrity of the free software distribution system, which is
+-implemented by public license practices.  Many people have made
+-generous contributions to the wide range of software distributed
+-through that system in reliance on consistent application of that
+-system; it is up to the author/donor to decide if he or she is willing
+-to distribute software through any other system and a licensee cannot
+-impose that choice.
+-
+-This section is intended to make thoroughly clear what is believed to
+-be a consequence of the rest of this License.
+-
+-  8. If the distribution and/or use of the Program is restricted in
+-certain countries either by patents or by copyrighted interfaces, the
+-original copyright holder who places the Program under this License
+-may add an explicit geographical distribution limitation excluding
+-those countries, so that distribution is permitted only in or among
+-countries not thus excluded.  In such case, this License incorporates
+-the limitation as if written in the body of this License.
+-
+-  9. The Free Software Foundation may publish revised and/or new versions
+-of the General Public License from time to time.  Such new versions will
+-be similar in spirit to the present version, but may differ in detail to
+-address new problems or concerns.
+-
+-Each version is given a distinguishing version number.  If the Program
+-specifies a version number of this License which applies to it and "any
+-later version", you have the option of following the terms and conditions
+-either of that version or of any later version published by the Free
+-Software Foundation.  If the Program does not specify a version number of
+-this License, you may choose any version ever published by the Free Software
+-Foundation.
+-
+-  10. If you wish to incorporate parts of the Program into other free
+-programs whose distribution conditions are different, write to the author
+-to ask for permission.  For software which is copyrighted by the Free
+-Software Foundation, write to the Free Software Foundation; we sometimes
+-make exceptions for this.  Our decision will be guided by the two goals
+-of preserving the free status of all derivatives of our free software and
+-of promoting the sharing and reuse of software generally.
+-
+-                            NO WARRANTY
+-
+-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+-REPAIR OR CORRECTION.
+-
+-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+-POSSIBILITY OF SUCH DAMAGES.
+-
+-                     END OF TERMS AND CONDITIONS
+-
+-            How to Apply These Terms to Your New Programs
+-
+-  If you develop a new program, and you want it to be of the greatest
+-possible use to the public, the best way to achieve this is to make it
+-free software which everyone can redistribute and change under these terms.
+-
+-  To do so, attach the following notices to the program.  It is safest
+-to attach them to the start of each source file to most effectively
+-convey the exclusion of warranty; and each file should have at least
+-the "copyright" line and a pointer to where the full notice is found.
+-
+-    <one line to give the program's name and a brief idea of what it does.>
+-    Copyright (C) <year>  <name of author>
+-
+-    This program is free software; you can redistribute it and/or modify
+-    it under the terms of the GNU General Public License as published by
+-    the Free Software Foundation; either version 2 of the License, or
+-    (at your option) any later version.
+-
+-    This program is distributed in the hope that it will be useful,
+-    but WITHOUT ANY WARRANTY; without even the implied warranty of
+-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-    GNU General Public License for more details.
+-
+-    You should have received a copy of the GNU General Public License
+-    along with this program; if not, write to the Free Software
+-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+-
+-
+-Also add information on how to contact you by electronic and paper mail.
+-
+-If the program is interactive, make it output a short notice like this
+-when it starts in an interactive mode:
+-
+-    Gnomovision version 69, Copyright (C) year name of author
+-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+-    This is free software, and you are welcome to redistribute it
+-    under certain conditions; type `show c' for details.
+-
+-The hypothetical commands `show w' and `show c' should show the appropriate
+-parts of the General Public License.  Of course, the commands you use may
+-be called something other than `show w' and `show c'; they could even be
+-mouse-clicks or menu items--whatever suits your program.
+-
+-You should also get your employer (if you work as a programmer) or your
+-school, if any, to sign a "copyright disclaimer" for the program, if
+-necessary.  Here is a sample; alter the names:
+-
+-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+-
+-  <signature of Ty Coon>, 1 April 1989
+-  Ty Coon, President of Vice
+-
+-This General Public License does not permit incorporating your program into
+-proprietary programs.  If your program is a subroutine library, you may
+-consider it more useful to permit linking proprietary applications with the
+-library.  If this is what you want to do, use the GNU Library General
+-Public License instead of this License.
+-
+--- END GPLv2+ License ---
+-
+--- BEGIN LGPLv2+ License ---
+-
+-                  GNU LIBRARY GENERAL PUBLIC LICENSE
+-                       Version 2, June 1991
+-
+- Copyright (C) 1991 Free Software Foundation, Inc.
+-                    59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+- Everyone is permitted to copy and distribute verbatim copies
+- of this license document, but changing it is not allowed.
+-
+-[This is the first released version of the library GPL.  It is
+- numbered 2 because it goes with version 2 of the ordinary GPL.]
+-
+-                            Preamble
+-
+-  The licenses for most software are designed to take away your
+-freedom to share and change it.  By contrast, the GNU General Public
+-Licenses are intended to guarantee your freedom to share and change
+-free software--to make sure the software is free for all its users.
+-
+-  This license, the Library General Public License, applies to some
+-specially designated Free Software Foundation software, and to any
+-other libraries whose authors decide to use it.  You can use it for
+-your libraries, too.
+-
+-  When we speak of free software, we are referring to freedom, not
+-price.  Our General Public Licenses are designed to make sure that you
+-have the freedom to distribute copies of free software (and charge for
+-this service if you wish), that you receive source code or can get it
+-if you want it, that you can change the software or use pieces of it
+-in new free programs; and that you know you can do these things.
+-
+-  To protect your rights, we need to make restrictions that forbid
+-anyone to deny you these rights or to ask you to surrender the rights.
+-These restrictions translate to certain responsibilities for you if
+-you distribute copies of the library, or if you modify it.
+-
+-  For example, if you distribute copies of the library, whether gratis
+-or for a fee, you must give the recipients all the rights that we gave
+-you.  You must make sure that they, too, receive or can get the source
+-code.  If you link a program with the library, you must provide
+-complete object files to the recipients so that they can relink them
+-with the library, after making changes to the library and recompiling
+-it.  And you must show them these terms so they know their rights.
+-
+-  Our method of protecting your rights has two steps: (1) copyright
+-the library, and (2) offer you this license which gives you legal
+-permission to copy, distribute and/or modify the library.
+-
+-  Also, for each distributor's protection, we want to make certain
+-that everyone understands that there is no warranty for this free
+-library.  If the library is modified by someone else and passed on, we
+-want its recipients to know that what they have is not the original
+-version, so that any problems introduced by others will not reflect on
+-the original authors' reputations.
+-
+-  Finally, any free program is threatened constantly by software
+-patents.  We wish to avoid the danger that companies distributing free
+-software will individually obtain patent licenses, thus in effect
+-transforming the program into proprietary software.  To prevent this,
+-we have made it clear that any patent must be licensed for everyone's
+-free use or not licensed at all.
+-
+-  Most GNU software, including some libraries, is covered by the ordinary
+-GNU General Public License, which was designed for utility programs.  This
+-license, the GNU Library General Public License, applies to certain
+-designated libraries.  This license is quite different from the ordinary
+-one; be sure to read it in full, and don't assume that anything in it is
+-the same as in the ordinary license.
+-
+-  The reason we have a separate public license for some libraries is that
+-they blur the distinction we usually make between modifying or adding to a
+-program and simply using it.  Linking a program with a library, without
+-changing the library, is in some sense simply using the library, and is
+-analogous to running a utility program or application program.  However, in
+-a textual and legal sense, the linked executable is a combined work, a
+-derivative of the original library, and the ordinary General Public License
+-treats it as such.
+-
+-  Because of this blurred distinction, using the ordinary General
+-Public License for libraries did not effectively promote software
+-sharing, because most developers did not use the libraries.  We
+-concluded that weaker conditions might promote sharing better.
+-
+-  However, unrestricted linking of non-free programs would deprive the
+-users of those programs of all benefit from the free status of the
+-libraries themselves.  This Library General Public License is intended to
+-permit developers of non-free programs to use free libraries, while
+-preserving your freedom as a user of such programs to change the free
+-libraries that are incorporated in them.  (We have not seen how to achieve
+-this as regards changes in header files, but we have achieved it as regards
+-changes in the actual functions of the Library.)  The hope is that this
+-will lead to faster development of free libraries.
+-
+-  The precise terms and conditions for copying, distribution and
+-modification follow.  Pay close attention to the difference between a
+-"work based on the library" and a "work that uses the library".  The
+-former contains code derived from the library, while the latter only
+-works together with the library.
+-
+-  Note that it is possible for a library to be covered by the ordinary
+-General Public License rather than by this special one.
+-
+-                  GNU LIBRARY GENERAL PUBLIC LICENSE
+-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+-
+-  0. This License Agreement applies to any software library which
+-contains a notice placed by the copyright holder or other authorized
+-party saying it may be distributed under the terms of this Library
+-General Public License (also called "this License").  Each licensee is
+-addressed as "you".
+-
+-  A "library" means a collection of software functions and/or data
+-prepared so as to be conveniently linked with application programs
+-(which use some of those functions and data) to form executables.
+-
+-  The "Library", below, refers to any such software library or work
+-which has been distributed under these terms.  A "work based on the
+-Library" means either the Library or any derivative work under
+-copyright law: that is to say, a work containing the Library or a
+-portion of it, either verbatim or with modifications and/or translated
+-straightforwardly into another language.  (Hereinafter, translation is
+-included without limitation in the term "modification".)
+-
+-  "Source code" for a work means the preferred form of the work for
+-making modifications to it.  For a library, complete source code means
+-all the source code for all modules it contains, plus any associated
+-interface definition files, plus the scripts used to control compilation
+-and installation of the library.
+-
+-  Activities other than copying, distribution and modification are not
+-covered by this License; they are outside its scope.  The act of
+-running a program using the Library is not restricted, and output from
+-such a program is covered only if its contents constitute a work based
+-on the Library (independent of the use of the Library in a tool for
+-writing it).  Whether that is true depends on what the Library does
+-and what the program that uses the Library does.
+-
+-  1. You may copy and distribute verbatim copies of the Library's
+-complete source code as you receive it, in any medium, provided that
+-you conspicuously and appropriately publish on each copy an
+-appropriate copyright notice and disclaimer of warranty; keep intact
+-all the notices that refer to this License and to the absence of any
+-warranty; and distribute a copy of this License along with the
+-Library.
+-
+-  You may charge a fee for the physical act of transferring a copy,
+-and you may at your option offer warranty protection in exchange for a
+-fee.
+-
+-  2. You may modify your copy or copies of the Library or any portion
+-of it, thus forming a work based on the Library, and copy and
+-distribute such modifications or work under the terms of Section 1
+-above, provided that you also meet all of these conditions:
+-
+-    a) The modified work must itself be a software library.
+-
+-    b) You must cause the files modified to carry prominent notices
+-    stating that you changed the files and the date of any change.
+-
+-    c) You must cause the whole of the work to be licensed at no
+-    charge to all third parties under the terms of this License.
+-
+-    d) If a facility in the modified Library refers to a function or a
+-    table of data to be supplied by an application program that uses
+-    the facility, other than as an argument passed when the facility
+-    is invoked, then you must make a good faith effort to ensure that,
+-    in the event an application does not supply such function or
+-    table, the facility still operates, and performs whatever part of
+-    its purpose remains meaningful.
+-
+-    (For example, a function in a library to compute square roots has
+-    a purpose that is entirely well-defined independent of the
+-    application.  Therefore, Subsection 2d requires that any
+-    application-supplied function or table used by this function must
+-    be optional: if the application does not supply it, the square
+-    root function must still compute square roots.)
+-
+-These requirements apply to the modified work as a whole.  If
+-identifiable sections of that work are not derived from the Library,
+-and can be reasonably considered independent and separate works in
+-themselves, then this License, and its terms, do not apply to those
+-sections when you distribute them as separate works.  But when you
+-distribute the same sections as part of a whole which is a work based
+-on the Library, the distribution of the whole must be on the terms of
+-this License, whose permissions for other licensees extend to the
+-entire whole, and thus to each and every part regardless of who wrote
+-it.
+-
+-Thus, it is not the intent of this section to claim rights or contest
+-your rights to work written entirely by you; rather, the intent is to
+-exercise the right to control the distribution of derivative or
+-collective works based on the Library.
+-
+-In addition, mere aggregation of another work not based on the Library
+-with the Library (or with a work based on the Library) on a volume of
+-a storage or distribution medium does not bring the other work under
+-the scope of this License.
+-
+-  3. You may opt to apply the terms of the ordinary GNU General Public
+-License instead of this License to a given copy of the Library.  To do
+-this, you must alter all the notices that refer to this License, so
+-that they refer to the ordinary GNU General Public License, version 2,
+-instead of to this License.  (If a newer version than version 2 of the
+-ordinary GNU General Public License has appeared, then you can specify
+-that version instead if you wish.)  Do not make any other change in
+-these notices.
+-
+-  Once this change is made in a given copy, it is irreversible for
+-that copy, so the ordinary GNU General Public License applies to all
+-subsequent copies and derivative works made from that copy.
+-
+-  This option is useful when you wish to copy part of the code of
+-the Library into a program that is not a library.
+-
+-  4. You may copy and distribute the Library (or a portion or
+-derivative of it, under Section 2) in object code or executable form
+-under the terms of Sections 1 and 2 above provided that you accompany
+-it with the complete corresponding machine-readable source code, which
+-must be distributed under the terms of Sections 1 and 2 above on a
+-medium customarily used for software interchange.
+-
+-  If distribution of object code is made by offering access to copy
+-from a designated place, then offering equivalent access to copy the
+-source code from the same place satisfies the requirement to
+-distribute the source code, even though third parties are not
+-compelled to copy the source along with the object code.
+-
+-  5. A program that contains no derivative of any portion of the
+-Library, but is designed to work with the Library by being compiled or
+-linked with it, is called a "work that uses the Library".  Such a
+-work, in isolation, is not a derivative work of the Library, and
+-therefore falls outside the scope of this License.
+-
+-  However, linking a "work that uses the Library" with the Library
+-creates an executable that is a derivative of the Library (because it
+-contains portions of the Library), rather than a "work that uses the
+-library".  The executable is therefore covered by this License.
+-Section 6 states terms for distribution of such executables.
+-
+-  When a "work that uses the Library" uses material from a header file
+-that is part of the Library, the object code for the work may be a
+-derivative work of the Library even though the source code is not.
+-Whether this is true is especially significant if the work can be
+-linked without the Library, or if the work is itself a library.  The
+-threshold for this to be true is not precisely defined by law.
+-
+-  If such an object file uses only numerical parameters, data
+-structure layouts and accessors, and small macros and small inline
+-functions (ten lines or less in length), then the use of the object
+-file is unrestricted, regardless of whether it is legally a derivative
+-work.  (Executables containing this object code plus portions of the
+-Library will still fall under Section 6.)
+-
+-  Otherwise, if the work is a derivative of the Library, you may
+-distribute the object code for the work under the terms of Section 6.
+-Any executables containing that work also fall under Section 6,
+-whether or not they are linked directly with the Library itself.
+-
+-  6. As an exception to the Sections above, you may also compile or
+-link a "work that uses the Library" with the Library to produce a
+-work containing portions of the Library, and distribute that work
+-under terms of your choice, provided that the terms permit
+-modification of the work for the customer's own use and reverse
+-engineering for debugging such modifications.
+-
+-  You must give prominent notice with each copy of the work that the
+-Library is used in it and that the Library and its use are covered by
+-this License.  You must supply a copy of this License.  If the work
+-during execution displays copyright notices, you must include the
+-copyright notice for the Library among them, as well as a reference
+-directing the user to the copy of this License.  Also, you must do one
+-of these things:
+-
+-    a) Accompany the work with the complete corresponding
+-    machine-readable source code for the Library including whatever
+-    changes were used in the work (which must be distributed under
+-    Sections 1 and 2 above); and, if the work is an executable linked
+-    with the Library, with the complete machine-readable "work that
+-    uses the Library", as object code and/or source code, so that the
+-    user can modify the Library and then relink to produce a modified
+-    executable containing the modified Library.  (It is understood
+-    that the user who changes the contents of definitions files in the
+-    Library will not necessarily be able to recompile the application
+-    to use the modified definitions.)
+-
+-    b) Accompany the work with a written offer, valid for at
+-    least three years, to give the same user the materials
+-    specified in Subsection 6a, above, for a charge no more
+-    than the cost of performing this distribution.
+-
+-    c) If distribution of the work is made by offering access to copy
+-    from a designated place, offer equivalent access to copy the above
+-    specified materials from the same place.
+-
+-    d) Verify that the user has already received a copy of these
+-    materials or that you have already sent this user a copy.
+-
+-  For an executable, the required form of the "work that uses the
+-Library" must include any data and utility programs needed for
+-reproducing the executable from it.  However, as a special exception,
+-the source code distributed need not include anything that is normally
+-distributed (in either source or binary form) with the major
+-components (compiler, kernel, and so on) of the operating system on
+-which the executable runs, unless that component itself accompanies
+-the executable.
+-
+-  It may happen that this requirement contradicts the license
+-restrictions of other proprietary libraries that do not normally
+-accompany the operating system.  Such a contradiction means you cannot
+-use both them and the Library together in an executable that you
+-distribute.
+-
+-  7. You may place library facilities that are a work based on the
+-Library side-by-side in a single library together with other library
+-facilities not covered by this License, and distribute such a combined
+-library, provided that the separate distribution of the work based on
+-the Library and of the other library facilities is otherwise
+-permitted, and provided that you do these two things:
+-
+-    a) Accompany the combined library with a copy of the same work
+-    based on the Library, uncombined with any other library
+-    facilities.  This must be distributed under the terms of the
+-    Sections above.
+-
+-    b) Give prominent notice with the combined library of the fact
+-    that part of it is a work based on the Library, and explaining
+-    where to find the accompanying uncombined form of the same work.
+-
+-  8. You may not copy, modify, sublicense, link with, or distribute
+-the Library except as expressly provided under this License.  Any
+-attempt otherwise to copy, modify, sublicense, link with, or
+-distribute the Library is void, and will automatically terminate your
+-rights under this License.  However, parties who have received copies,
+-or rights, from you under this License will not have their licenses
+-terminated so long as such parties remain in full compliance.
+-
+-  9. You are not required to accept this License, since you have not
+-signed it.  However, nothing else grants you permission to modify or
+-distribute the Library or its derivative works.  These actions are
+-prohibited by law if you do not accept this License.  Therefore, by
+-modifying or distributing the Library (or any work based on the
+-Library), you indicate your acceptance of this License to do so, and
+-all its terms and conditions for copying, distributing or modifying
+-the Library or works based on it.
+-
+-  10. Each time you redistribute the Library (or any work based on the
+-Library), the recipient automatically receives a license from the
+-original licensor to copy, distribute, link with or modify the Library
+-subject to these terms and conditions.  You may not impose any further
+-restrictions on the recipients' exercise of the rights granted herein.
+-You are not responsible for enforcing compliance by third parties to
+-this License.
+-
+-  11. If, as a consequence of a court judgment or allegation of patent
+-infringement or for any other reason (not limited to patent issues),
+-conditions are imposed on you (whether by court order, agreement or
+-otherwise) that contradict the conditions of this License, they do not
+-excuse you from the conditions of this License.  If you cannot
+-distribute so as to satisfy simultaneously your obligations under this
+-License and any other pertinent obligations, then as a consequence you
+-may not distribute the Library at all.  For example, if a patent
+-license would not permit royalty-free redistribution of the Library by
+-all those who receive copies directly or indirectly through you, then
+-the only way you could satisfy both it and this License would be to
+-refrain entirely from distribution of the Library.
+-
+-If any portion of this section is held invalid or unenforceable under any
+-particular circumstance, the balance of the section is intended to apply,
+-and the section as a whole is intended to apply in other circumstances.
+-
+-It is not the purpose of this section to induce you to infringe any
+-patents or other property right claims or to contest validity of any
+-such claims; this section has the sole purpose of protecting the
+-integrity of the free software distribution system which is
+-implemented by public license practices.  Many people have made
+-generous contributions to the wide range of software distributed
+-through that system in reliance on consistent application of that
+-system; it is up to the author/donor to decide if he or she is willing
+-to distribute software through any other system and a licensee cannot
+-impose that choice.
+-
+-This section is intended to make thoroughly clear what is believed to
+-be a consequence of the rest of this License.
+-
+-  12. If the distribution and/or use of the Library is restricted in
+-certain countries either by patents or by copyrighted interfaces, the
+-original copyright holder who places the Library under this License may add
+-an explicit geographical distribution limitation excluding those countries,
+-so that distribution is permitted only in or among countries not thus
+-excluded.  In such case, this License incorporates the limitation as if
+-written in the body of this License.
+-
+-  13. The Free Software Foundation may publish revised and/or new
+-versions of the Library General Public License from time to time.
+-Such new versions will be similar in spirit to the present version,
+-but may differ in detail to address new problems or concerns.
+-
+-Each version is given a distinguishing version number.  If the Library
+-specifies a version number of this License which applies to it and
+-"any later version", you have the option of following the terms and
+-conditions either of that version or of any later version published by
+-the Free Software Foundation.  If the Library does not specify a
+-license version number, you may choose any version ever published by
+-the Free Software Foundation.
+-
+-  14. If you wish to incorporate parts of the Library into other free
+-programs whose distribution conditions are incompatible with these,
+-write to the author to ask for permission.  For software which is
+-copyrighted by the Free Software Foundation, write to the Free
+-Software Foundation; we sometimes make exceptions for this.  Our
+-decision will be guided by the two goals of preserving the free status
+-of all derivatives of our free software and of promoting the sharing
+-and reuse of software generally.
+-
+-                            NO WARRANTY
+-
+-  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+-
+-  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+-DAMAGES.
+-
+-                     END OF TERMS AND CONDITIONS
+-
+-           How to Apply These Terms to Your New Libraries
+-
+-  If you develop a new library, and you want it to be of the greatest
+-possible use to the public, we recommend making it free software that
+-everyone can redistribute and change.  You can do so by permitting
+-redistribution under these terms (or, alternatively, under the terms of the
+-ordinary General Public License).
+-
+-  To apply these terms, attach the following notices to the library.  It is
+-safest to attach them to the start of each source file to most effectively
+-convey the exclusion of warranty; and each file should have at least the
+-"copyright" line and a pointer to where the full notice is found.
+-
+-    <one line to give the library's name and a brief idea of what it does.>
+-    Copyright (C) <year>  <name of author>
+-
+-    This library is free software; you can redistribute it and/or
+-    modify it under the terms of the GNU Library General Public
+-    License as published by the Free Software Foundation; either
+-    version 2 of the License, or (at your option) any later version.
+-
+-    This library 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
+-    Library General Public License for more details.
+-
+-    You should have received a copy of the GNU Library General Public
+-    License along with this library; if not, write to the
+-    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-    Boston, MA  02111-1307  USA.
+-
+-Also add information on how to contact you by electronic and paper mail.
+-
+-You should also get your employer (if you work as a programmer) or your
+-school, if any, to sign a "copyright disclaimer" for the library, if
+-necessary.  Here is a sample; alter the names:
+-
+-  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+-  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+-
+-  <signature of Ty Coon>, 1 April 1990
+-  Ty Coon, President of Vice
+-
+-That's all there is to it!
+-
+--- END LGPLv2+ License ---
+diff --git a/abi-checker/sample/Makefile b/abi-checker/sample/Makefile
+deleted file mode 100644
+index 4759f3c..0000000
+--- a/abi-checker/sample/Makefile
++++ /dev/null
+@@ -1,12 +0,0 @@
+-obj-m = sample_module.o
+-
+-all:
+-      make -C /usr/src/linux-kernel-build-3.10.19-tizen_defconfig.1 M=$(PWD) modules
+-
+-install:
+-      make -C /usr/src/linux-kernel-build-3.10.19-tizen_defconfig.1 M=$(PWD) modules_install
+-
+-clean:
+-      make -C /usr/src/linux-kernel-build-3.10.19-tizen_defconfig.1 M=$(PWD) clean
+-      
+-
+diff --git a/abi-checker/sample/packaging/udisks-automount-agent.spec.txt b/abi-checker/sample/packaging/udisks-automount-agent.spec.txt
+deleted file mode 100644
+index bca8416..0000000
+--- a/abi-checker/sample/packaging/udisks-automount-agent.spec.txt
++++ /dev/null
+@@ -1,53 +0,0 @@
+-%define debug_package %{nil}
+-Name:       sample-module
+-Summary:    Test sample kernel module 2
+-Version:    0.1.0
+-Release:    1
+-Group:      Base/Device Management
+-License:    GPL-2.0
+-Source0:    %{name}-%{version}.tar.gz
+-BuildRequires: linux-kernel-sources
+-BuildRequires: linux-kernel-headers
+-BuildRequires: linux-kernel-build
+-BuildRequires: linux-kernel-abi-tools
+-BuildRequires: linux-kernel-abi-devel
+-
+-Requires: linux-kernel-uImage
+-
+-%package source
+-Summary: Debug sample-kernel-module-2
+-Group: Base/Device Management
+-
+-%description source
+-Debug and sources sample-kernel-module-2
+-
+-%description
+-TIZEN simple kernel module.  
+-
+-%prep
+-%setup -q
+-
+-%build
+-make %{?jobs:-j%jobs}
+-# Create ABI/API dump fingerprint file
+-/usr/local/bin/abi-module-dumper sample_module_2.ko sample_module_2.abidump
+-
+-%install
+-mkdir -p %{_builddir}/lib/modules/3.10.19-tizen_defconfig.1/
+-make INSTALL_MOD_PATH=%{buildroot}  install
+-cp sample_module_2.abidump %{buildroot}/lib/modules/3.10.19-tizen_defconfig.1/extra/
+-
+-%post
+-# list comptible kerel ABI/API versions
+-/usr/local/bin/abi-module-kernels-list /lib/modules/3.10.19-tizen_defconfig.1/extra/sample_module_2.abidump
+-
+-# Test module ABI/API with the kernel ABI/API
+-/usr/local/bin/abi-module-checker /lib/modules/3.10.19-tizen_defconfig.1/extra/sample_module_2.abidump
+-
+-%files
+-/lib/modules/3.10.19-tizen_defconfig.1/extra/
+-%license LICENSE
+-
+-%files source
+-/usr/src/debug/sample-kernel-module-2-0.1.0/sample_module_2.c
+-/usr/src/debug/sample-kernel-module-2-0.1.0/sample_module_2.mod.c
+diff --git a/abi-checker/sample/sample_module.c b/abi-checker/sample/sample_module.c
+deleted file mode 100644
+index b95a7af..0000000
+--- a/abi-checker/sample/sample_module.c
++++ /dev/null
+@@ -1,107 +0,0 @@
+-#include <linux/module.h>
+-#include <linux/kernel.h>
+-#include <asm/uaccess.h>
+-#include <linux/init.h>
+-#include <linux/fs.h>
+-
+-#define DEVICE_NAME "sample_module"
+-#define TEST_MSG_BUFF_LEN     1024
+-
+-extern int snd_timer_pause;
+-
+-static unsigned int majorNumber = 0;
+-
+-static char message[TEST_MSG_BUFF_LEN + 1];
+-
+-static ssize_t device_write(struct file *filp, const char *buff, size_t len, loff_t *off)
+-{
+-      printk(KERN_ALERT "Empty write operation. %d\n", snd_timer_pause);
+-      return 0;
+-}
+-
+-static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t * offset)
+-{
+-      int bytes_read = 0;
+-
+-      /*
+-       * Copy message
+-       */
+-      for(bytes_read = 0; bytes_read < (length - 1) && bytes_read < TEST_MSG_BUFF_LEN; bytes_read ++)
+-              put_user(message[bytes_read], buffer + bytes_read );
+-      put_user('\0', buffer + bytes_read );
+-
+-      return bytes_read + 1;
+-}
+-
+-static int device_open(struct inode *inode, struct file *file)
+-{
+-      static int counter = 0;
+-
+-      printk( "Open device, count = %d\n", counter++ );
+-
+-      try_module_get( THIS_MODULE );
+-      return 0;
+-}
+-
+-static int device_release(struct inode *inode, struct file *file)
+-{
+-      printk("Release device\n");
+-
+-      module_put( THIS_MODULE );
+-      return 0;
+-}
+-
+-struct file_operations fileOperations =
+-{
+-      read:    device_read,
+-      write:   device_write,
+-      open:    device_open,
+-      release: device_release
+-};
+-
+-static int __init test_module_init( void )
+-{
+-      int i;
+-      int j;
+-
+-      printk(KERN_ALERT "Test kernel module 2 - enter\n");
+-
+-      /*
+-       * Init test message
+-       */
+-      for(i = 0; i < TEST_MSG_BUFF_LEN;)
+-      {
+-              for(j = 0; j < 10 && i < TEST_MSG_BUFF_LEN; j ++, i ++ )
+-              {
+-                      message[i] = '0' + j;
+-                      message[i + 1] = '\0';
+-              }
+-      }
+-
+-      /*
+-       * Register device
+-       */
+-      majorNumber = register_chrdev(0, DEVICE_NAME, &fileOperations);
+-      if (majorNumber < 0)
+-      {
+-                printk(KERN_ALERT "Blad rejestrowania urzadzenia => [%d]\n", majorNumber );
+-                return majorNumber;
+-      }
+-
+-      return 0;
+-}
+-
+-static void __exit test_module_exit(void)
+-{
+-      printk(KERN_ALERT "Test kernel module 2 - exit\n");
+-
+-      unregister_chrdev(majorNumber, DEVICE_NAME);
+-}
+-
+-module_init(test_module_init);
+-module_exit(test_module_exit);
+-
+-MODULE_LICENSE("GPL");
+-MODULE_AUTHOR("Jacek Pielaszkiewicz");        /* Who wrote this module? */
+-MODULE_DESCRIPTION("Sample test kernel module.");     /* What does this module do */
+-MODULE_SUPPORTED_DEVICE("sample_test_module_2");
+diff --git a/abi-checker/src/abi-module-checker b/abi-checker/src/abi-module-checker
+deleted file mode 100755
+index 78e5a89..0000000
+--- a/abi-checker/src/abi-module-checker
++++ /dev/null
+@@ -1,29 +0,0 @@
+-#!/bin/sh
+-
+-echo ""
+-echo "Module ABI/API checker"
+-echo ""
+-echo ""
+-
+-if [ "${#}" != "1"  ]
+-then
+-      echo ""
+-      echo "ERROR: "
+-      echo "       Usage: ${0} _module_abi_fingerprint_"
+-      echo ""
+-      exit 1
+-fi
+-
+-kerne_abi_file="/boot/abi/current"
+-
+-if [ ! -f "${1}" -o ! -f "${kerne_abi_file}" ]
+-then
+-      echo ""
+-      echo "ERROR: Please check \"${1}\", \"${kerne_abi_file}\" files"
+-      echo ""
+-      exit 1
+-fi
+-
+-/usr/local/bin/abi-checker "test-module" "${kerne_abi_file}" "${1}"
+-
+-exit ${?}
+diff --git a/abi-checker/src/abi-module-dumper b/abi-checker/src/abi-module-dumper
+deleted file mode 100755
+index 783e02a..0000000
+--- a/abi-checker/src/abi-module-dumper
++++ /dev/null
+@@ -1,38 +0,0 @@
+-#!/bin/sh
+-
+-echo ""
+-echo "Module ABI/API fingerprint file generation"
+-echo ""
+-echo ""
+-
+-if [ "${#}" != "2"  ]
+-then
+-      echo ""
+-      echo "ERROR: "
+-      echo "       Usage: ${0} _module_ko_file_ _output_file_"
+-      echo ""
+-      exit 1
+-fi
+-
+-kerne_abi_file="/boot/abi/current"
+-
+-if [ ! -f "${kerne_abi_file}" ]
+-then
+-      echo ""
+-      echo "ERROR: Please check ${kerne_abi_file} file"
+-      echo "       Check if linux-kernel-uImage package is installed in development environment."
+-      echo ""
+-      exit 1
+-fi
+-
+-if [ ! -f "${1}" ]
+-then
+-      echo "ERROR: Please check input file ${1}"
+-      echo ""
+-      exit 1
+-      
+-fi
+-
+-/usr/local/bin/abi-checker "dump-module" "${kerne_abi_file}" "${1}" "${2}"
+-
+-exit ${?}
+diff --git a/abi-checker/src/abi-module-kernels-list b/abi-checker/src/abi-module-kernels-list
+deleted file mode 100755
+index 12105e1..0000000
+--- a/abi-checker/src/abi-module-kernels-list
++++ /dev/null
+@@ -1,31 +0,0 @@
+-#!/bin/sh
+-
+-echo ""
+-echo "List all comatible kernels."
+-echo ""
+-
+-if [ "${#}" != 1  ]
+-then
+-      echo ""
+-      echo "ERROR: "
+-      echo "       Usage: ${0} _module_fingerprint_"
+-      echo ""
+-      exit 1
+-fi
+-
+-#
+-# Check all historical abi kernel files
+-#
+-for file in /boot/abi/abi_*
+-do
+-      filename=`basename ${file}`
+-      version=`echo ${filename} | awk -F _ '{ print $2 }'`
+-      abi=`echo ${filename} | awk -F _ '{ print $3 }'`
+-
+-      /usr/local/bin/abi-checker "test-module" "${file}" "${1}" 2> /dev/null > /dev/null
+-      if [ "${?}" = "0" ]
+-      then
+-              echo "        Kernel:${version}, ABI/API:${abi} .... compatible"
+-      fi
+-done
+-
+diff --git a/abi-checker/src/kernel_abi_checker.c b/abi-checker/src/kernel_abi_checker.c
+index da396e1..ae362d6 100644
+--- a/abi-checker/src/kernel_abi_checker.c
++++ b/abi-checker/src/kernel_abi_checker.c
+@@ -638,7 +638,7 @@ int testModule( char *f1, char *f2 )
+       {
+               destroyHashTable( curr_hashTable );
+               PRINT_ERROR( "Error read input \"%s\" file.\n", f2 );
+-              return 1;
++        return 1;
+       }
+       /*
+diff --git a/packaging/linux-kernel.spec b/packaging/linux-kernel.spec
+index 485f06e..e199f9b 100644
+--- a/packaging/linux-kernel.spec
++++ b/packaging/linux-kernel.spec
+@@ -52,18 +52,10 @@ glibc package.
+ %package abi-tools
+ Summary: Kernael ABI tools
+ Group: Development/System
+-Requires: libelf
+ %description abi-tools
+ The package provide set of tools to test and create ABI/API dumps.
+-%package abi-devel
+-Summary: Kernael ABI development package
+-Group: Development/System
+-
+-%description abi-devel
+-The package provide ABI/API fingerprint developemnt repository
+-
+ %package sources
+ Summary: Full linux kernel sources for out-of-tree modules
+ Group: Development/System
+@@ -147,10 +139,6 @@ make INSTALL_PATH=%{buildroot} INSTALL_MOD_PATH=%{buildroot} O=%{kernel_build_di
+ # 4.1 Install ABI/API tools
+ cp abi-checker/src/abi-checker %{buildroot}/usr/local/bin
+-cp abi-checker/src/abi-module-checker %{buildroot}/usr/local/bin
+-cp abi-checker/src/abi-module-dumper %{buildroot}/usr/local/bin
+-cp abi-checker/src/abi-module-kernels-list %{buildroot}/usr/local/bin
+-chmod 755 %{buildroot}/usr/local/bin/*
+ # 4.2 Install abi_%{version} file
+ %if %{with abidev}
+@@ -193,8 +181,6 @@ rm -rf %{buildroot}/boot/vmlinux*
+ # 6. Create symbolic links
+ ln -sf /usr/src/linux-kernel-sources-%{version}-%{build_id} %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/source
+-ln -sf /usr/src/linux-kernel-build-%{version}-%{build_id}   %{buildroot}/usr/src/linux-kernel-build-current
+-ln -sf /usr/src/linux-kernel-sources-%{version}-%{build_id} %{buildroot}/usr/src/linux-kernel-sources-current
+ %clean
+ rm -rf %{buildroot}
+@@ -206,12 +192,10 @@ rm -rf %{buildroot}
+ %files sources
+ %defattr (-, root, root)
+ /usr/src/linux-kernel-sources-%{version}-%{build_id}
+-/usr/src/linux-kernel-sources-current
+ %files build
+ %defattr (-, root, root)
+ /usr/src/linux-kernel-build-%{version}-%{build_id}
+-/usr/src/linux-kernel-build-current
+ %files uImage
+ %if %{without abidev}
+@@ -227,6 +211,3 @@ rm -rf %{buildroot}
+ %files abi-dev
+ /boot/abi
+ %endif
+-
+-%files abi-devel
+-/boot/abi
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1065-Revert-linux-kernel-and-linux-kernel-modules-ABI-too.patch b/patches.tizen/1065-Revert-linux-kernel-and-linux-kernel-modules-ABI-too.patch
new file mode 100644 (file)
index 0000000..bc8d88e
--- /dev/null
@@ -0,0 +1,8286 @@
+From 78a64d1e3ecf499cc6faa3e2755930eaed8294a8 Mon Sep 17 00:00:00 2001
+From: Jacek Pielaszkiewicz <j.pielaszkie@samsung.com>
+Date: Thu, 2 Jan 2014 22:22:57 -0800
+Subject: [PATCH 1065/1302] Revert "linux-kernel and linux kernel modules ABI
+ tools."
+
+This reverts commit 23b22df7b6b7d91e7c1866dc760c2586ba161c43.
+
+Change-Id: I3ea15671a029e781a153d43201bf79118f66b148
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ abi-checker/data/abi_3.10.19_1              | 6900 ---------------------------
+ abi-checker/src/Makefile                    |   31 -
+ abi-checker/src/build_api_kernel_checker.sh |   24 -
+ abi-checker/src/kernel_abi_checker.c        |  834 ----
+ abi-checker/src/kernel_abi_checker.h        |   62 -
+ abi-checker/src/kernel_abi_checker_elf.c    |  172 -
+ packaging/linux-kernel.spec                 |  125 +-
+ 7 files changed, 19 insertions(+), 8129 deletions(-)
+ delete mode 100644 abi-checker/data/abi_3.10.19_1
+ delete mode 100644 abi-checker/src/Makefile
+ delete mode 100755 abi-checker/src/build_api_kernel_checker.sh
+ delete mode 100644 abi-checker/src/kernel_abi_checker.c
+ delete mode 100644 abi-checker/src/kernel_abi_checker.h
+ delete mode 100644 abi-checker/src/kernel_abi_checker_elf.c
+
+diff --git a/abi-checker/data/abi_3.10.19_1 b/abi-checker/data/abi_3.10.19_1
+deleted file mode 100644
+index eea3455..0000000
+--- a/abi-checker/data/abi_3.10.19_1
++++ /dev/null
+@@ -1,6900 +0,0 @@
+-0x80e54114    cfg80211_send_rx_assoc  vmlinux EXPORT_SYMBOL
+-0xd4dd4a5f    ipv6_chk_custom_prefix  vmlinux EXPORT_SYMBOL
+-0x765592d7    generic_file_splice_write       vmlinux EXPORT_SYMBOL
+-0x74f78b5f    set_anon_super  vmlinux EXPORT_SYMBOL
+-0x88ea56ef    kmem_cache_alloc        vmlinux EXPORT_SYMBOL
+-0x149d22ae    replace_page_cache_page vmlinux EXPORT_SYMBOL_GPL
+-0x70523a7a    __cond_resched_softirq  vmlinux EXPORT_SYMBOL
+-0x55417264    unregister_vt_notifier  vmlinux EXPORT_SYMBOL_GPL
+-0xc2ea8e64    snd_soc_platform_read   vmlinux EXPORT_SYMBOL_GPL
+-0x0a2487e0    unblock_all_signals     vmlinux EXPORT_SYMBOL
+-0x260cf8f8    of_get_property vmlinux EXPORT_SYMBOL
+-0x6ac315b3    v4l2_m2m_ioctl_dqbuf    vmlinux EXPORT_SYMBOL_GPL
+-0x5c421d9d    i2c_put_adapter vmlinux EXPORT_SYMBOL
+-0x4d8e0b9c    rtc_class_open  vmlinux EXPORT_SYMBOL_GPL
+-0x96cd2b04    scsi_sense_key_string   vmlinux EXPORT_SYMBOL
+-0xedf10a85    request_firmware        vmlinux EXPORT_SYMBOL
+-0x70230d35    __hci_cmd_sync  vmlinux EXPORT_SYMBOL
+-0x79dc2bec    dev_uc_sync     vmlinux EXPORT_SYMBOL
+-0xeb396e95    dev_mc_sync     vmlinux EXPORT_SYMBOL
+-0x80ca5026    _bin2bcd        vmlinux EXPORT_SYMBOL
+-0xfbaaf01e    console_lock    vmlinux EXPORT_SYMBOL
+-0xdf5311f6    hwmon_device_unregister vmlinux EXPORT_SYMBOL_GPL
+-0xe113bbbc    csum_partial    vmlinux EXPORT_SYMBOL
+-0x1ef4f43e    cfg80211_wext_siwscan   vmlinux EXPORT_SYMBOL_GPL
+-0xb343d54f    cfg80211_wext_giwscan   vmlinux EXPORT_SYMBOL_GPL
+-0xc068440e    __kfifo_alloc   vmlinux EXPORT_SYMBOL
+-0x376eb932    kmap_atomic     vmlinux EXPORT_SYMBOL
+-0xaadff4e7    nf_log_register vmlinux EXPORT_SYMBOL
+-0xc8276a79    nf_hooks_needed vmlinux EXPORT_SYMBOL
+-0x1b17e06c    kstrtoll        vmlinux EXPORT_SYMBOL
+-0xa7d57242    scsi_execute    vmlinux EXPORT_SYMBOL
+-0x9b757ebd    raw_seq_open    vmlinux EXPORT_SYMBOL_GPL
+-0x1b479d00    snd_soc_of_parse_audio_routing  vmlinux EXPORT_SYMBOL_GPL
+-0x3b2785b0    crypto_hash_walk_done   vmlinux EXPORT_SYMBOL_GPL
+-0xa1d55e90    _raw_spin_lock_bh       vmlinux EXPORT_SYMBOL
+-0xdd391eff    profile_event_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0xa724257f    init_uts_ns     vmlinux EXPORT_SYMBOL_GPL
+-0xc97d1140    cpufreq_cooling_get_level       vmlinux EXPORT_SYMBOL_GPL
+-0x5898fd79    device_add      vmlinux EXPORT_SYMBOL_GPL
+-0x5081d0b3    device_del      vmlinux EXPORT_SYMBOL_GPL
+-0x37246b6e    __inet6_hash    vmlinux EXPORT_SYMBOL
+-0xad3a5766    dst_release     vmlinux EXPORT_SYMBOL
+-0x1e254a30    sock_no_mmap    vmlinux EXPORT_SYMBOL
+-0x854e1c0b    sg_nents        vmlinux EXPORT_SYMBOL
+-0xb4c753a2    disk_map_sector_rcu     vmlinux EXPORT_SYMBOL_GPL
+-0x942da6f0    sysfs_update_group      vmlinux EXPORT_SYMBOL_GPL
+-0xa38602cd    drain_workqueue vmlinux EXPORT_SYMBOL_GPL
+-0xd4b5f202    led_trigger_store       vmlinux EXPORT_SYMBOL_GPL
+-0x80104269    tcp_initialize_rcv_mss  vmlinux EXPORT_SYMBOL
+-0x54e6fcdd    net_enable_timestamp    vmlinux EXPORT_SYMBOL
+-0xeb32f5c3    sockfd_lookup   vmlinux EXPORT_SYMBOL
+-0x02aa8f04    snd_soc_dapm_get_pin_switch     vmlinux EXPORT_SYMBOL_GPL
+-0x762265ad    snd_soc_dapm_put_pin_switch     vmlinux EXPORT_SYMBOL_GPL
+-0xb0ffda2f    blk_limits_max_hw_sectors       vmlinux EXPORT_SYMBOL
+-0x7cd8695d    directly_mappable_cdev_bdi      vmlinux EXPORT_SYMBOL
+-0x6bc3fbc0    __unregister_chrdev     vmlinux EXPORT_SYMBOL
+-0x6bb86c7d    srcu_notifier_chain_register    vmlinux EXPORT_SYMBOL_GPL
+-0x4b661f3f    v4l2_ctrl_grab  vmlinux EXPORT_SYMBOL
+-0xd2bbf775    fb_validate_mode        vmlinux EXPORT_SYMBOL
+-0xe8d75b12    nfc_target_lost vmlinux EXPORT_SYMBOL
+-0xb2d299a9    dev_graft_qdisc vmlinux EXPORT_SYMBOL
+-0xa851973a    raw_notifier_call_chain vmlinux EXPORT_SYMBOL_GPL
+-0x138709ec    scsi_get_command        vmlinux EXPORT_SYMBOL
+-0x174afb1a    __sg_page_iter_next     vmlinux EXPORT_SYMBOL
+-0x30cada8f    radix_tree_next_hole    vmlinux EXPORT_SYMBOL
+-0xc0412578    scsi_target_quiesce     vmlinux EXPORT_SYMBOL
+-0xd7a5d2f8    transport_class_register        vmlinux EXPORT_SYMBOL_GPL
+-0xd2335101    drm_fb_get_bpp_depth    vmlinux EXPORT_SYMBOL
+-0xa9a33fdf    jbd2_journal_try_to_free_buffers        vmlinux EXPORT_SYMBOL
+-0xffd5a395    default_wake_function   vmlinux EXPORT_SYMBOL
+-0xd6cb49e3    dm_put_device   vmlinux EXPORT_SYMBOL
+-0xb6e1e07d    dm_get_device   vmlinux EXPORT_SYMBOL
+-0x1f9218e9    input_handler_for_each_handle   vmlinux EXPORT_SYMBOL
+-0x560c6863    transport_class_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0x65f3ad9a    fb_videomode_to_var     vmlinux EXPORT_SYMBOL
+-0x79ad634c    nfc_hci_send_cmd_async  vmlinux EXPORT_SYMBOL
+-0x6bbf9530    mount_subtree   vmlinux EXPORT_SYMBOL
+-0x8f22ce41    iget_locked     vmlinux EXPORT_SYMBOL
+-0x6fba7c75    sdhci_runtime_suspend_host      vmlinux EXPORT_SYMBOL_GPL
+-0x7f923f2a    v4l2_of_parse_endpoint  vmlinux EXPORT_SYMBOL
+-0xaa2d0ca7    input_mt_assign_slots   vmlinux EXPORT_SYMBOL
+-0x167fd723    drm_mm_clean    vmlinux EXPORT_SYMBOL
+-0x9733c21d    sock_get_timestampns    vmlinux EXPORT_SYMBOL
+-0xf42e571f    snd_soc_dapm_put_enum_virt      vmlinux EXPORT_SYMBOL_GPL
+-0xcd16649c    snd_soc_dapm_get_enum_virt      vmlinux EXPORT_SYMBOL_GPL
+-0x38cb130f    iommu_group_add_device  vmlinux EXPORT_SYMBOL_GPL
+-0xe90d597e    class_interface_register        vmlinux EXPORT_SYMBOL_GPL
+-0x49ebacbd    _clear_bit      vmlinux EXPORT_SYMBOL
+-0x853b6dce    nfc_tm_activated        vmlinux EXPORT_SYMBOL
+-0xc617f82c    unregister_oom_notifier vmlinux EXPORT_SYMBOL_GPL
+-0x8da9fa20    spi_get_device_id       vmlinux EXPORT_SYMBOL_GPL
+-0x882f44c1    class_interface_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0x03757c9b    of_get_named_gpio_flags vmlinux EXPORT_SYMBOL
+-0x1b68aba6    pin_config_set  vmlinux EXPORT_SYMBOL
+-0x7505e34c    snd_power_wait  vmlinux EXPORT_SYMBOL
+-0x44366cfc    simple_write_to_buffer  vmlinux EXPORT_SYMBOL
+-0x3fec6133    read_code       vmlinux EXPORT_SYMBOL
+-0xf7bb3a63    __srcu_read_unlock      vmlinux EXPORT_SYMBOL_GPL
+-0xc2e587d1    reset_devices   vmlinux EXPORT_SYMBOL
+-0x07b991fc    iio_kfifo_free  vmlinux EXPORT_SYMBOL
+-0x36c38507    tty_register_device     vmlinux EXPORT_SYMBOL
+-0xa5a633b9    sg_last vmlinux EXPORT_SYMBOL
+-0x62c4e40d    __blk_run_queue vmlinux EXPORT_SYMBOL
+-0x3eaf291d    param_get_string        vmlinux EXPORT_SYMBOL
+-0x95cb929c    of_find_all_nodes       vmlinux EXPORT_SYMBOL
+-0xc2c5a45e    mmc_app_cmd     vmlinux EXPORT_SYMBOL_GPL
+-0xfa388487    usb_bus_list_lock       vmlinux EXPORT_SYMBOL_GPL
+-0xdbbaeb6e    regulator_map_voltage_linear    vmlinux EXPORT_SYMBOL_GPL
+-0x99bb8806    memmove vmlinux EXPORT_SYMBOL
+-0x9e6e25f9    jbd2_journal_start_commit       vmlinux EXPORT_SYMBOL
+-0x4c0f005a    __block_page_mkwrite    vmlinux EXPORT_SYMBOL
+-0x76d3cd60    laptop_mode     vmlinux EXPORT_SYMBOL
+-0x8fd01dea    generic_file_direct_write       vmlinux EXPORT_SYMBOL
+-0xa1f38f97    end_page_writeback      vmlinux EXPORT_SYMBOL
+-0xa75312bc    call_rcu_sched  vmlinux EXPORT_SYMBOL_GPL
+-0xb67b2219    cm_suspend_again        vmlinux EXPORT_SYMBOL_GPL
+-0x80311392    dmam_declare_coherent_memory    vmlinux EXPORT_SYMBOL
+-0xf2e8c6fe    skb_recv_datagram       vmlinux EXPORT_SYMBOL
+-0x4325cade    snd_soc_jack_add_pins   vmlinux EXPORT_SYMBOL_GPL
+-0x69cadac1    d_alloc_pseudo  vmlinux EXPORT_SYMBOL
+-0x871c0a7e    fiemap_check_flags      vmlinux EXPORT_SYMBOL
+-0xd0804fe2    generic_file_readonly_mmap      vmlinux EXPORT_SYMBOL
+-0xd06524ba    raw_notifier_chain_unregister   vmlinux EXPORT_SYMBOL_GPL
+-0x26448a56    usbnet_cdc_unbind       vmlinux EXPORT_SYMBOL_GPL
+-0x0bbae511    return_address  vmlinux EXPORT_SYMBOL_GPL
+-0x0d542439    __ipv6_addr_type        vmlinux EXPORT_SYMBOL
+-0xcf470397    unregister_qdisc        vmlinux EXPORT_SYMBOL
+-0x66a8c67c    crypto_shash_finup      vmlinux EXPORT_SYMBOL_GPL
+-0x5647361d    crypto_shash_final      vmlinux EXPORT_SYMBOL_GPL
+-0xf1c942f4    crypto_ahash_finup      vmlinux EXPORT_SYMBOL_GPL
+-0x17209ab0    crypto_ahash_final      vmlinux EXPORT_SYMBOL_GPL
+-0x8da17b42    scatterwalk_copychunks  vmlinux EXPORT_SYMBOL_GPL
+-0xd766d6a2    sdhci_suspend_host      vmlinux EXPORT_SYMBOL_GPL
+-0x9b05a0c7    usb_autopm_get_interface        vmlinux EXPORT_SYMBOL_GPL
+-0x8eff5a5b    phy_device_register     vmlinux EXPORT_SYMBOL
+-0xa2101833    sock_diag_put_meminfo   vmlinux EXPORT_SYMBOL_GPL
+-0xc8339e24    string_unescape vmlinux EXPORT_SYMBOL
+-0xeb55a931    __kfifo_max_r   vmlinux EXPORT_SYMBOL
+-0xe6511495    vm_insert_page  vmlinux EXPORT_SYMBOL
+-0x4396b273    irq_domain_add_legacy   vmlinux EXPORT_SYMBOL_GPL
+-0x24fdb0df    register_console        vmlinux EXPORT_SYMBOL
+-0x6ac76b42    pin_is_valid    vmlinux EXPORT_SYMBOL_GPL
+-0xe279ec34    nf_conntrack_l4proto_tcp4       vmlinux EXPORT_SYMBOL_GPL
+-0x512ce34d    sock_no_socketpair      vmlinux EXPORT_SYMBOL
+-0x236032ef    input_ff_event  vmlinux EXPORT_SYMBOL_GPL
+-0x1e5431bd    devm_gpio_request       vmlinux EXPORT_SYMBOL
+-0x86383d16    arpt_do_table   vmlinux EXPORT_SYMBOL
+-0x3c89040c    dev_addr_del    vmlinux EXPORT_SYMBOL
+-0xd900e010    gnet_stats_start_copy   vmlinux EXPORT_SYMBOL
+-0x33f0768c    cpufreq_quick_get_max   vmlinux EXPORT_SYMBOL
+-0xa88a70b0    tcp_tso_segment vmlinux EXPORT_SYMBOL
+-0xa652c4ef    __kfifo_dma_in_prepare_r        vmlinux EXPORT_SYMBOL
+-0xdfb895e4    __fat_fs_error  vmlinux EXPORT_SYMBOL_GPL
+-0x00438c43    bio_copy_kern   vmlinux EXPORT_SYMBOL
+-0xe0878bfe    __krealloc      vmlinux EXPORT_SYMBOL
+-0xa849b57b    devm_free_irq   vmlinux EXPORT_SYMBOL
+-0x995d1071    prof_on vmlinux EXPORT_SYMBOL_GPL
+-0x3328c21e    task_nice       vmlinux EXPORT_SYMBOL
+-0x84109a46    i2c_lock_adapter        vmlinux EXPORT_SYMBOL_GPL
+-0x76f824bb    usb_gadget_set_state    vmlinux EXPORT_SYMBOL_GPL
+-0x702c11cd    platform_device_del     vmlinux EXPORT_SYMBOL_GPL
+-0xccfe749d    platform_device_put     vmlinux EXPORT_SYMBOL_GPL
+-0x6499c2c3    kernel_accept   vmlinux EXPORT_SYMBOL
+-0x0147e076    kset_create_and_add     vmlinux EXPORT_SYMBOL_GPL
+-0xf60d1625    mm_kobj vmlinux EXPORT_SYMBOL_GPL
+-0x66561d40    set_bdi_congested       vmlinux EXPORT_SYMBOL
+-0xa064fc2f    gs_free_req     vmlinux EXPORT_SYMBOL_GPL
+-0xaf70f0bf    xt_proto_fini   vmlinux EXPORT_SYMBOL_GPL
+-0xc1e7bf31    devm_ioremap_resource   vmlinux EXPORT_SYMBOL
+-0x71d3571b    sg_miter_start  vmlinux EXPORT_SYMBOL
+-0xc5894dbd    blk_queue_unprep_rq     vmlinux EXPORT_SYMBOL
+-0x159c0774    lock_may_read   vmlinux EXPORT_SYMBOL
+-0x56d697ce    cpu_up  vmlinux EXPORT_SYMBOL_GPL
+-0xba406d79    usb_gadget_map_request  vmlinux EXPORT_SYMBOL_GPL
+-0xe2b9dcc5    wakeup_source_drop      vmlinux EXPORT_SYMBOL_GPL
+-0x19011c29    driver_find     vmlinux EXPORT_SYMBOL_GPL
+-0x13031824    devm_gpio_request_one   vmlinux EXPORT_SYMBOL
+-0x91db6962    snd_card_free   vmlinux EXPORT_SYMBOL
+-0x157b3f69    load_nls        vmlinux EXPORT_SYMBOL
+-0xffe5318c    dma_buf_map_attachment  vmlinux EXPORT_SYMBOL_GPL
+-0x10030de6    tty_mode_ioctl  vmlinux EXPORT_SYMBOL_GPL
+-0x00109670    fb_class        vmlinux EXPORT_SYMBOL
+-0x97999817    rfkill_set_hw_state     vmlinux EXPORT_SYMBOL
+-0x6597fe84    crypto_lookup_aead      vmlinux EXPORT_SYMBOL_GPL
+-0xd7b4b67a    bio_advance     vmlinux EXPORT_SYMBOL
+-0x4b8408ef    from_kuid       vmlinux EXPORT_SYMBOL
+-0xb65bd3fc    add_timer_on    vmlinux EXPORT_SYMBOL_GPL
+-0x4859b8bb    rtc_year_days   vmlinux EXPORT_SYMBOL
+-0xa064f393    ehci_cf_port_reset_rwsem        vmlinux EXPORT_SYMBOL_GPL
+-0x0c65e73c    scsi_normalize_sense    vmlinux EXPORT_SYMBOL
+-0x8e84b481    __pm_runtime_use_autosuspend    vmlinux EXPORT_SYMBOL_GPL
+-0xab2495da    drm_mode_connector_detach_encoder       vmlinux EXPORT_SYMBOL
+-0xbb11cfba    klist_iter_exit vmlinux EXPORT_SYMBOL_GPL
+-0x84044a12    ip6_local_out   vmlinux EXPORT_SYMBOL_GPL
+-0xc80b5684    snd_compress_deregister vmlinux EXPORT_SYMBOL_GPL
+-0x215ebd78    bitrev16        vmlinux EXPORT_SYMBOL
+-0x390def22    kstrtou16_from_user     vmlinux EXPORT_SYMBOL
+-0x9a74417e    kstrtoull_from_user     vmlinux EXPORT_SYMBOL
+-0x6949942d    pm_runtime_set_autosuspend_delay        vmlinux EXPORT_SYMBOL_GPL
+-0xfb6eedf9    power_group_name        vmlinux EXPORT_SYMBOL_GPL
+-0x7752eabc    snd_pcm_new_internal    vmlinux EXPORT_SYMBOL
+-0x59cdb28e    crypto_aead_type        vmlinux EXPORT_SYMBOL_GPL
+-0xeadf5b18    jbd2_journal_load       vmlinux EXPORT_SYMBOL
+-0xcd6a7390    v4l2_i2c_new_subdev     vmlinux EXPORT_SYMBOL_GPL
+-0x997574ce    device_unregister       vmlinux EXPORT_SYMBOL_GPL
+-0xedbfb39a    serial8250_request_dma  vmlinux EXPORT_SYMBOL_GPL
+-0x19a156ad    xfrm_state_add  vmlinux EXPORT_SYMBOL
+-0x4d4a6141    __netlink_kernel_create vmlinux EXPORT_SYMBOL
+-0x3ad82802    of_property_read_u32_index      vmlinux EXPORT_SYMBOL_GPL
+-0x96b53df6    mmc_cleanup_queue       vmlinux EXPORT_SYMBOL
+-0x7b9ee22c    v4l2_ctrl_notify        vmlinux EXPORT_SYMBOL
+-0xda3a7ca9    regulator_is_enabled    vmlinux EXPORT_SYMBOL_GPL
+-0x137def66    nf_ct_l4proto_put       vmlinux EXPORT_SYMBOL_GPL
+-0x7efdb4fb    nf_ct_l3proto_put       vmlinux EXPORT_SYMBOL_GPL
+-0x9948898e    dapm_mark_dirty vmlinux EXPORT_SYMBOL_GPL
+-0x2484d571    single_release_net      vmlinux EXPORT_SYMBOL_GPL
+-0x5612133a    I_BDEV  vmlinux EXPORT_SYMBOL
+-0x7729cbdd    task_handoff_register   vmlinux EXPORT_SYMBOL_GPL
+-0x19353b86    scsicam_bios_param      vmlinux EXPORT_SYMBOL
+-0xb6a76b8e    pn544_hci_probe vmlinux EXPORT_SYMBOL
+-0x476c3efa    drm_fill_in_dev vmlinux EXPORT_SYMBOL
+-0x4f1cd128    security_tun_dev_create vmlinux EXPORT_SYMBOL
+-0x76f29bbf    seq_release_net vmlinux EXPORT_SYMBOL_GPL
+-0x980420fb    tty_port_tty_set        vmlinux EXPORT_SYMBOL
+-0xc215715c    tty_port_tty_get        vmlinux EXPORT_SYMBOL
+-0xa8c74dc5    devm_regulator_get      vmlinux EXPORT_SYMBOL_GPL
+-0x3441c3d6    gpio_set_value_cansleep vmlinux EXPORT_SYMBOL_GPL
+-0xcd68dc1d    nfc_get_local_general_bytes     vmlinux EXPORT_SYMBOL
+-0xf617c0a1    inet_csk_route_child_sock       vmlinux EXPORT_SYMBOL_GPL
+-0xfce4d2e1    vfs_path_lookup vmlinux EXPORT_SYMBOL
+-0x326314e4    find_or_create_page     vmlinux EXPORT_SYMBOL
+-0x65bbbc78    schedule_hrtimeout_range        vmlinux EXPORT_SYMBOL_GPL
+-0x8d7b0a28    phy_stop_interrupts     vmlinux EXPORT_SYMBOL
+-0xe9e87de1    crypto_register_pcomp   vmlinux EXPORT_SYMBOL_GPL
+-0x2d7966fb    jbd2_journal_flush      vmlinux EXPORT_SYMBOL
+-0x1c4e8441    invalidate_bdev vmlinux EXPORT_SYMBOL
+-0x9aeacb87    ring_buffer_iter_empty  vmlinux EXPORT_SYMBOL_GPL
+-0x49eb1c4a    put_pid_ns      vmlinux EXPORT_SYMBOL_GPL
+-0xb7e67f9a    iio_sw_buffer_preenable vmlinux EXPORT_SYMBOL
+-0xeae6b2cc    usb_sg_init     vmlinux EXPORT_SYMBOL_GPL
+-0x2f33a47d    usb_sg_wait     vmlinux EXPORT_SYMBOL_GPL
+-0xba136537    scsi_reset_provider     vmlinux EXPORT_SYMBOL
+-0xa9170094    drm_kms_helper_hotplug_event    vmlinux EXPORT_SYMBOL
+-0xb007d3b8    tcp_twsk_unique vmlinux EXPORT_SYMBOL_GPL
+-0xd35091f2    netdev_info     vmlinux EXPORT_SYMBOL
+-0x3517b864    kobject_uevent  vmlinux EXPORT_SYMBOL_GPL
+-0x82a5ee54    mmc_try_claim_host      vmlinux EXPORT_SYMBOL
+-0x11267875    scsi_extd_sense_format  vmlinux EXPORT_SYMBOL
+-0x4f56540f    pm_wakeup_event vmlinux EXPORT_SYMBOL_GPL
+-0x6c61ce70    num_registered_fb       vmlinux EXPORT_SYMBOL
+-0xcc2f1602    st_sensors_sysfs_get_sampling_frequency vmlinux EXPORT_SYMBOL
+-0x0bf95cc0    st_sensors_sysfs_set_sampling_frequency vmlinux EXPORT_SYMBOL
+-0xa73fc98f    of_n_addr_cells vmlinux EXPORT_SYMBOL
+-0xaf5c2852    wakeup_source_add       vmlinux EXPORT_SYMBOL_GPL
+-0xc27732b1    snd_pcm_lib_default_mmap        vmlinux EXPORT_SYMBOL_GPL
+-0x3ca17104    __snd_printk    vmlinux EXPORT_SYMBOL_GPL
+-0xa6a59f23    blk_cleanup_queue       vmlinux EXPORT_SYMBOL
+-0xec3364ec    generic_setlease        vmlinux EXPORT_SYMBOL
+-0x440d8a62    tty_hung_up_p   vmlinux EXPORT_SYMBOL
+-0xfa2e4ead    ip6_tnl_dst_store       vmlinux EXPORT_SYMBOL_GPL
+-0x5a0647c1    ipv6_getsockopt vmlinux EXPORT_SYMBOL
+-0x329bbbde    timerqueue_del  vmlinux EXPORT_SYMBOL_GPL
+-0x34161524    st_sensors_read_event_value     vmlinux EXPORT_SYMBOL
+-0x3e16c1b5    v4l2_clk_put    vmlinux EXPORT_SYMBOL
+-0xdc047fc4    scsi_dev_info_list_add_keyed    vmlinux EXPORT_SYMBOL
+-0xdc97af2e    syscore_suspend vmlinux EXPORT_SYMBOL_GPL
+-0xaebbf521    cfg80211_ch_switch_notify       vmlinux EXPORT_SYMBOL
+-0x4fdb4cdf    proc_mkdir_data vmlinux EXPORT_SYMBOL_GPL
+-0x8ffad455    mpage_writepages        vmlinux EXPORT_SYMBOL
+-0x258f05ac    write_one_page  vmlinux EXPORT_SYMBOL
+-0x32b31a8c    ktime_get_boottime      vmlinux EXPORT_SYMBOL_GPL
+-0x15892417    async_synchronize_cookie        vmlinux EXPORT_SYMBOL_GPL
+-0x5a596330    v4l2_i2c_new_subdev_board       vmlinux EXPORT_SYMBOL_GPL
+-0xbd05974a    usb_driver_release_interface    vmlinux EXPORT_SYMBOL_GPL
+-0xce190a28    cfg80211_notify_new_peer_candidate      vmlinux EXPORT_SYMBOL
+-0x23c45e2a    inet_add_protocol       vmlinux EXPORT_SYMBOL
+-0xe19c66e3    sync_blockdev   vmlinux EXPORT_SYMBOL
+-0xd36667e2    nobh_write_end  vmlinux EXPORT_SYMBOL
+-0x815a1805    n_tty_ioctl_helper      vmlinux EXPORT_SYMBOL
+-0xedd9106d    __ashrdi3       vmlinux EXPORT_SYMBOL
+-0xff67b37f    __lshrdi3       vmlinux EXPORT_SYMBOL
+-0x85b5e625    rfkill_set_states       vmlinux EXPORT_SYMBOL
+-0x6e720ff2    rtnl_unlock     vmlinux EXPORT_SYMBOL
+-0x4c02a5f2    sock_rfree      vmlinux EXPORT_SYMBOL
+-0xe252485d    kernel_recvmsg  vmlinux EXPORT_SYMBOL
+-0x0693eedb    disk_part_iter_init     vmlinux EXPORT_SYMBOL_GPL
+-0x4019ac2a    freeze_bdev     vmlinux EXPORT_SYMBOL
+-0x9f1c66aa    srcu_batches_completed  vmlinux EXPORT_SYMBOL_GPL
+-0xa6ec6db0    sdhci_alloc_host        vmlinux EXPORT_SYMBOL_GPL
+-0x0bfba95f    usb_hub_find_child      vmlinux EXPORT_SYMBOL_GPL
+-0x9f83d040    __root_device_register  vmlinux EXPORT_SYMBOL_GPL
+-0x63b124fc    drm_bl_dpms     vmlinux EXPORT_SYMBOL_GPL
+-0xb35f8f7f    __hci_cmd_sync_ev       vmlinux EXPORT_SYMBOL
+-0xe177ecc2    skb_kill_datagram       vmlinux EXPORT_SYMBOL
+-0x985c6297    kfree_skb       vmlinux EXPORT_SYMBOL
+-0xdcb83c11    kernel_kobj     vmlinux EXPORT_SYMBOL_GPL
+-0x1bb5fc26    atomic_notifier_chain_register  vmlinux EXPORT_SYMBOL_GPL
+-0xab1d6cc1    param_get_long  vmlinux EXPORT_SYMBOL
+-0x75d68801    inet_twsk_schedule      vmlinux EXPORT_SYMBOL_GPL
+-0x68b83ac6    posix_acl_alloc vmlinux EXPORT_SYMBOL
+-0x306b23a8    drm_mm_takedown vmlinux EXPORT_SYMBOL
+-0x698be398    regulator_get_voltage   vmlinux EXPORT_SYMBOL_GPL
+-0xc8bed9c5    amba_driver_unregister  vmlinux EXPORT_SYMBOL
+-0x1db7dc40    pgprot_kernel   vmlinux EXPORT_SYMBOL
+-0x19e03378    cfg80211_get_p2p_attr   vmlinux EXPORT_SYMBOL
+-0x44a5de9b    nfnetlink_parse_nat_setup_hook  vmlinux EXPORT_SYMBOL_GPL
+-0x52d047db    skb_copy_datagram_iovec vmlinux EXPORT_SYMBOL
+-0x731f351a    __kfree_skb     vmlinux EXPORT_SYMBOL
+-0xd544b6fe    fuse_do_open    vmlinux EXPORT_SYMBOL_GPL
+-0xd98f64fc    tty_port_register_device        vmlinux EXPORT_SYMBOL_GPL
+-0xfd305341    walk_stackframe vmlinux EXPORT_SYMBOL
+-0x58378f4a    snd_soc_dapm_force_enable_pin   vmlinux EXPORT_SYMBOL_GPL
+-0x31b31f5c    csum_partial_copy_nocheck       vmlinux EXPORT_SYMBOL
+-0xeea82d10    ip_defrag       vmlinux EXPORT_SYMBOL
+-0xd75abd53    register_qdisc  vmlinux EXPORT_SYMBOL
+-0xe4bf323c    snd_soc_test_bits       vmlinux EXPORT_SYMBOL_GPL
+-0x5d891a64    idr_destroy     vmlinux EXPORT_SYMBOL
+-0xeb9e7cdd    ida_destroy     vmlinux EXPORT_SYMBOL
+-0x302b0f11    generic_file_aio_read   vmlinux EXPORT_SYMBOL
+-0x3fe00f7d    mmc_can_discard vmlinux EXPORT_SYMBOL
+-0x51246a07    mmc_interrupt_hpi       vmlinux EXPORT_SYMBOL
+-0xce55bca9    scsi_flush_work vmlinux EXPORT_SYMBOL_GPL
+-0x3ca53f5d    arpt_alloc_initial_table        vmlinux EXPORT_SYMBOL_GPL
+-0x3ab45d33    free_netdev     vmlinux EXPORT_SYMBOL
+-0xc9ec4e21    free_percpu     vmlinux EXPORT_SYMBOL_GPL
+-0x431fd1f6    v4l2_subdev_queryctrl   vmlinux EXPORT_SYMBOL
+-0x7c0f2bb5    drm_mm_create_block     vmlinux EXPORT_SYMBOL
+-0x3fa79dd5    ip6_datagram_recv_ctl   vmlinux EXPORT_SYMBOL_GPL
+-0xd56d7aae    sk_setup_caps   vmlinux EXPORT_SYMBOL_GPL
+-0x668da8d5    zlib_inflateIncomp      vmlinux EXPORT_SYMBOL
+-0xe0f99a2f    ida_pre_get     vmlinux EXPORT_SYMBOL
+-0xf932015f    __raw_notifier_call_chain       vmlinux EXPORT_SYMBOL_GPL
+-0x4d3c153f    sigprocmask     vmlinux EXPORT_SYMBOL
+-0xd1974639    spi_sync_locked vmlinux EXPORT_SYMBOL_GPL
+-0xdcbd7c06    scsi_host_get   vmlinux EXPORT_SYMBOL
+-0x8ccc342d    drm_helper_move_panel_connectors_to_head        vmlinux EXPORT_SYMBOL
+-0x98578bb6    regulator_bulk_get      vmlinux EXPORT_SYMBOL_GPL
+-0x85ddc629    sk_stream_wait_connect  vmlinux EXPORT_SYMBOL
+-0x4db49a03    vb2_ioctl_dqbuf vmlinux EXPORT_SYMBOL_GPL
+-0xf720d75c    drm_vblank_init vmlinux EXPORT_SYMBOL
+-0x8d551bef    sysctl_tcp_rmem vmlinux EXPORT_SYMBOL
+-0x6c8c2ae7    sock_no_sendmsg vmlinux EXPORT_SYMBOL
+-0x3b1b7e9f    snd_soc_bytes_get       vmlinux EXPORT_SYMBOL_GPL
+-0xf74dae0f    idr_alloc       vmlinux EXPORT_SYMBOL_GPL
+-0x7c666ca1    jbd2_journal_update_sb_errno    vmlinux EXPORT_SYMBOL
+-0x98d00f33    vfs_unlink      vmlinux EXPORT_SYMBOL
+-0x9ee85355    extcon_unregister_notifier      vmlinux EXPORT_SYMBOL_GPL
+-0xf9e3887b    i2c_master_recv vmlinux EXPORT_SYMBOL
+-0xaff711f1    drm_global_mutex        vmlinux EXPORT_SYMBOL
+-0x62c5828a    nfc_hci_set_param       vmlinux EXPORT_SYMBOL
+-0x52512e8e    nfc_hci_get_param       vmlinux EXPORT_SYMBOL
+-0x4c90a5a9    lro_flush_all   vmlinux EXPORT_SYMBOL
+-0xc5116125    pipe_unlock     vmlinux EXPORT_SYMBOL
+-0x2d6bcdcb    iio_trigger_generic_data_rdy_poll       vmlinux EXPORT_SYMBOL
+-0x48c6db53    of_get_child_by_name    vmlinux EXPORT_SYMBOL
+-0x4379f0a6    genlmsg_multicast_allns vmlinux EXPORT_SYMBOL
+-0x43e32587    __sock_recv_wifi_status vmlinux EXPORT_SYMBOL_GPL
+-0x83a5ae2e    __tracepoint_rpm_resume vmlinux EXPORT_SYMBOL_GPL
+-0xb2d48a2e    queue_work_on   vmlinux EXPORT_SYMBOL
+-0x59d8223a    ioport_resource vmlinux EXPORT_SYMBOL
+-0x73a25185    pm_generic_restore      vmlinux EXPORT_SYMBOL_GPL
+-0x401ad827    bus_rescan_devices      vmlinux EXPORT_SYMBOL_GPL
+-0x3b4e8e6c    serial8250_tx_dma       vmlinux EXPORT_SYMBOL_GPL
+-0xba9f64c5    put_tty_driver  vmlinux EXPORT_SYMBOL
+-0xa46a0fcf    backlight_force_update  vmlinux EXPORT_SYMBOL
+-0xc7a4fbed    rtnl_lock       vmlinux EXPORT_SYMBOL
+-0x27b3484e    debugfs_create_bool     vmlinux EXPORT_SYMBOL_GPL
+-0x3691702f    generic_file_splice_read        vmlinux EXPORT_SYMBOL
+-0xdd2efc0f    ring_buffer_reset_cpu   vmlinux EXPORT_SYMBOL_GPL
+-0x2c1d69dc    prepare_kernel_cred     vmlinux EXPORT_SYMBOL
+-0x897473df    mktime  vmlinux EXPORT_SYMBOL
+-0xa8721b97    system_state    vmlinux EXPORT_SYMBOL
+-0x2b768df3    iio_buffer_show_enable  vmlinux EXPORT_SYMBOL
+-0xc3070585    xfrm6_tunnel_alloc_spi  vmlinux EXPORT_SYMBOL
+-0x6e583bdd    udp_push_pending_frames vmlinux EXPORT_SYMBOL
+-0xead6dbe6    splice_from_pipe_next   vmlinux EXPORT_SYMBOL
+-0x6d044c26    param_ops_uint  vmlinux EXPORT_SYMBOL
+-0x6f0036d9    del_timer_sync  vmlinux EXPORT_SYMBOL
+-0xc9db98ec    hidinput_connect        vmlinux EXPORT_SYMBOL_GPL
+-0xa3a75748    sec_bulk_read   vmlinux EXPORT_SYMBOL_GPL
+-0x7c640527    bt_info vmlinux EXPORT_SYMBOL
+-0x00e8097b    csum_partial_copy_fromiovecend  vmlinux EXPORT_SYMBOL
+-0x098ef076    wm_hubs_vmid_ena        vmlinux EXPORT_SYMBOL_GPL
+-0xc29591b4    drm_framebuffer_unreference     vmlinux EXPORT_SYMBOL
+-0xdbfa4d5b    con_set_default_unimap  vmlinux EXPORT_SYMBOL
+-0x08b75c5b    inet_diag_bc_sk vmlinux EXPORT_SYMBOL_GPL
+-0x3dea553f    __qdisc_calculate_pkt_len       vmlinux EXPORT_SYMBOL
+-0xab5f8242    dev_get_by_index        vmlinux EXPORT_SYMBOL
+-0x3e9d0c22    wm8958_mic_detect       vmlinux EXPORT_SYMBOL_GPL
+-0x462a2e75    match_strlcpy   vmlinux EXPORT_SYMBOL
+-0xf768dabc    ioctl_by_bdev   vmlinux EXPORT_SYMBOL
+-0x426b04e4    dma_buf_unmap_attachment        vmlinux EXPORT_SYMBOL_GPL
+-0x27146b38    init_net        vmlinux EXPORT_SYMBOL
+-0x9fe06761    wm_hubs_update_class_w  vmlinux EXPORT_SYMBOL_GPL
+-0x8978d687    textsearch_find_continuous      vmlinux EXPORT_SYMBOL
+-0xf7b12aee    __next_cpu      vmlinux EXPORT_SYMBOL
+-0x96905151    crypto_larval_lookup    vmlinux EXPORT_SYMBOL_GPL
+-0xb14bfc6b    __crypto_alloc_tfm      vmlinux EXPORT_SYMBOL_GPL
+-0x3ca95bb3    configfs_unregister_subsystem   vmlinux EXPORT_SYMBOL
+-0xd820c283    eventfd_ctx_remove_wait_queue   vmlinux EXPORT_SYMBOL_GPL
+-0x699d1d6a    generic_delete_inode    vmlinux EXPORT_SYMBOL
+-0xb5f17edf    perf_register_guest_info_callbacks      vmlinux EXPORT_SYMBOL_GPL
+-0x1d209e24    mmc_power_restore_host  vmlinux EXPORT_SYMBOL
+-0x8c66045e    cpufreq_freq_attr_scaling_boost_freqs   vmlinux EXPORT_SYMBOL_GPL
+-0x6114d8a4    regulator_force_disable vmlinux EXPORT_SYMBOL_GPL
+-0x7e606130    snd_soc_calc_bclk       vmlinux EXPORT_SYMBOL_GPL
+-0xac480322    nf_nat_pptp_hook_expectfn       vmlinux EXPORT_SYMBOL_GPL
+-0x7f19e69f    blk_run_queue   vmlinux EXPORT_SYMBOL
+-0x98dbc3bc    mmc_wait_for_req        vmlinux EXPORT_SYMBOL
+-0xa0d2b347    regmap_init_spi vmlinux EXPORT_SYMBOL_GPL
+-0xff7a8968    regmap_init_i2c vmlinux EXPORT_SYMBOL_GPL
+-0x98cc564a    regulator_set_voltage   vmlinux EXPORT_SYMBOL_GPL
+-0xcd63c845    __aeabi_lasr    vmlinux EXPORT_SYMBOL
+-0x8a4fa83b    __aeabi_llsr    vmlinux EXPORT_SYMBOL
+-0x78cfc117    hci_register_dev        vmlinux EXPORT_SYMBOL
+-0xd458f195    __secpath_destroy       vmlinux EXPORT_SYMBOL
+-0xaf64ad0d    zlib_deflate    vmlinux EXPORT_SYMBOL
+-0x24fdac79    wake_bit_function       vmlinux EXPORT_SYMBOL
+-0x864f4a52    of_clk_add_provider     vmlinux EXPORT_SYMBOL_GPL
+-0x1de054d5    of_clk_del_provider     vmlinux EXPORT_SYMBOL_GPL
+-0x42c8e001    v4l2_ctrl_next  vmlinux EXPORT_SYMBOL
+-0x1e95b9ac    i2c_smbus_write_i2c_block_data  vmlinux EXPORT_SYMBOL
+-0xc61c11c2    inet_csk_route_req      vmlinux EXPORT_SYMBOL_GPL
+-0xed597524    qdisc_get_rtab  vmlinux EXPORT_SYMBOL
+-0x9a633fbd    fuse_request_send_background    vmlinux EXPORT_SYMBOL_GPL
+-0x578e47c8    locks_release_private   vmlinux EXPORT_SYMBOL_GPL
+-0x40ce485b    mempool_resize  vmlinux EXPORT_SYMBOL
+-0xc60f75ec    __ftrace_vprintk        vmlinux EXPORT_SYMBOL_GPL
+-0xb88fb22f    hid_set_field   vmlinux EXPORT_SYMBOL_GPL
+-0xd954e4a7    bus_remove_file vmlinux EXPORT_SYMBOL_GPL
+-0x6172f515    xfrm_unregister_km      vmlinux EXPORT_SYMBOL
+-0xc5e4258e    in_dev_finish_destroy   vmlinux EXPORT_SYMBOL
+-0xe094ef39    sg_next vmlinux EXPORT_SYMBOL
+-0x6b4be175    bio_map_user    vmlinux EXPORT_SYMBOL
+-0x0b07abe2    unshare_fs_struct       vmlinux EXPORT_SYMBOL_GPL
+-0x2ef6b5bf    smp_call_function_any   vmlinux EXPORT_SYMBOL_GPL
+-0xd0fb7cd4    __tasklet_hi_schedule_first     vmlinux EXPORT_SYMBOL
+-0xe35c5285    of_find_node_by_phandle vmlinux EXPORT_SYMBOL
+-0x55724b35    hid_destroy_device      vmlinux EXPORT_SYMBOL_GPL
+-0x85ad5803    cfg80211_wext_siwrts    vmlinux EXPORT_SYMBOL_GPL
+-0x87cfc6e0    cfg80211_wext_giwrts    vmlinux EXPORT_SYMBOL_GPL
+-0xd1b091c0    unix_inq_len    vmlinux EXPORT_SYMBOL_GPL
+-0xc4d21124    __nf_conntrack_confirm  vmlinux EXPORT_SYMBOL_GPL
+-0x452a56c2    __brelse        vmlinux EXPORT_SYMBOL
+-0xbddeca9d    pipe_lock       vmlinux EXPORT_SYMBOL
+-0x33bfdca2    gserial_alloc_line      vmlinux EXPORT_SYMBOL_GPL
+-0x4edb7421    config_ep_by_speed      vmlinux EXPORT_SYMBOL_GPL
+-0xa473e3d4    usbnet_suspend  vmlinux EXPORT_SYMBOL_GPL
+-0x06521223    mdiobus_scan    vmlinux EXPORT_SYMBOL
+-0xed8f1a2b    dmam_alloc_coherent     vmlinux EXPORT_SYMBOL
+-0x9535ce7b    tty_port_carrier_raised vmlinux EXPORT_SYMBOL
+-0x71280d73    regulator_set_voltage_time_sel  vmlinux EXPORT_SYMBOL_GPL
+-0x1e314b21    regulator_use_dummy_regulator   vmlinux EXPORT_SYMBOL_GPL
+-0x347fd4b3    eventfd_ctx_get vmlinux EXPORT_SYMBOL_GPL
+-0x941f2aaa    eventfd_ctx_put vmlinux EXPORT_SYMBOL_GPL
+-0xf9d18552    mark_buffer_async_write vmlinux EXPORT_SYMBOL
+-0x6c6cdd4d    wait_for_completion_interruptible_timeout       vmlinux EXPORT_SYMBOL
+-0xe5525b81    scsi_device_set_state   vmlinux EXPORT_SYMBOL
+-0x28e23139    xfrm_probe_algs vmlinux EXPORT_SYMBOL_GPL
+-0x9a9ff422    ip_route_me_harder      vmlinux EXPORT_SYMBOL
+-0xb7cbbafa    inet_sock_destruct      vmlinux EXPORT_SYMBOL
+-0xf26e8a56    nf_reinject     vmlinux EXPORT_SYMBOL
+-0x3a9b6fb9    blk_unregister_region   vmlinux EXPORT_SYMBOL
+-0x2a2c3036    unregister_nls  vmlinux EXPORT_SYMBOL
+-0x5358fc36    ring_buffer_discard_commit      vmlinux EXPORT_SYMBOL_GPL
+-0x555621fa    clk_enable      vmlinux EXPORT_SYMBOL_GPL
+-0xf25af73c    mmc_add_host    vmlinux EXPORT_SYMBOL
+-0x4b02b5ca    dev_pm_qos_update_request       vmlinux EXPORT_SYMBOL_GPL
+-0xe11c3bb2    tty_chars_in_buffer     vmlinux EXPORT_SYMBOL
+-0x4e60ec09    __serio_register_port   vmlinux EXPORT_SYMBOL
+-0xc17515d7    usb_hcds_loaded vmlinux EXPORT_SYMBOL_GPL
+-0xadfe5127    usbnet_write_cmd_nopm   vmlinux EXPORT_SYMBOL_GPL
+-0x9c6c1c9c    phy_exit        vmlinux EXPORT_SYMBOL_GPL
+-0x44da5d0f    __csum_ipv6_magic       vmlinux EXPORT_SYMBOL
+-0x2ef42c91    l2cap_register_user     vmlinux EXPORT_SYMBOL
+-0xa83b115e    skb_pull_rcsum  vmlinux EXPORT_SYMBOL_GPL
+-0xbaa490f8    snd_ctl_unregister_ioctl        vmlinux EXPORT_SYMBOL
+-0xe3df2eb1    v4l2_async_notifier_register    vmlinux EXPORT_SYMBOL
+-0x950c4994    __scsi_device_lookup_by_target  vmlinux EXPORT_SYMBOL
+-0xed3baf1d    tcp_fetch_timewait_stamp        vmlinux EXPORT_SYMBOL_GPL
+-0xebdbe48c    radix_tree_gang_lookup  vmlinux EXPORT_SYMBOL
+-0xc00b1f1e    register_nls    vmlinux EXPORT_SYMBOL
+-0x62543231    locks_alloc_lock        vmlinux EXPORT_SYMBOL_GPL
+-0x6585e310    alloc_pages_exact_nid   vmlinux EXPORT_SYMBOL
+-0xb121390a    probe_irq_on    vmlinux EXPORT_SYMBOL
+-0xc58f706b    usbnet_get_msglevel     vmlinux EXPORT_SYMBOL_GPL
+-0x1007becd    usbnet_set_msglevel     vmlinux EXPORT_SYMBOL_GPL
+-0xb9eb9d79    pm_generic_suspend      vmlinux EXPORT_SYMBOL_GPL
+-0xca860514    xfrm_state_lookup       vmlinux EXPORT_SYMBOL
+-0x795598eb    tcp_parse_options       vmlinux EXPORT_SYMBOL
+-0x17a3ce1e    rps_may_expire_flow     vmlinux EXPORT_SYMBOL
+-0x7b3d29ac    i2c_smbus_write_block_data      vmlinux EXPORT_SYMBOL
+-0x8164b1cc    ump_dd_handle_create_from_secure_id     vmlinux EXPORT_SYMBOL
+-0x7f04682a    of_gpio_simple_xlate    vmlinux EXPORT_SYMBOL
+-0xefd6cf06    __aeabi_unwind_cpp_pr0  vmlinux EXPORT_SYMBOL
+-0xb7ba76c7    __aeabi_unwind_cpp_pr2  vmlinux EXPORT_SYMBOL
+-0x43f0af31    snd_soc_codec_set_pll   vmlinux EXPORT_SYMBOL_GPL
+-0x6e46b07b    module_refcount vmlinux EXPORT_SYMBOL
+-0x455348d7    usb_composite_probe     vmlinux EXPORT_SYMBOL_GPL
+-0x0e8110c3    sec_reg_write   vmlinux EXPORT_SYMBOL_GPL
+-0xba0edce6    inet_ctl_sock_create    vmlinux EXPORT_SYMBOL_GPL
+-0x8454f899    dev_addr_add_multiple   vmlinux EXPORT_SYMBOL
+-0x62e4112b    _submit_bh      vmlinux EXPORT_SYMBOL_GPL
+-0x715622e2    handle_edge_irq vmlinux EXPORT_SYMBOL
+-0x0e639705    usbnet_link_change      vmlinux EXPORT_SYMBOL
+-0x8043eb8c    firmware_kobj   vmlinux EXPORT_SYMBOL_GPL
+-0x130bf78b    drm_mode_create_from_cmdline_mode       vmlinux EXPORT_SYMBOL
+-0xbdd37f04    usb_autopm_put_interface_async  vmlinux EXPORT_SYMBOL_GPL
+-0x63c46f03    usb_lock_device_for_reset       vmlinux EXPORT_SYMBOL_GPL
+-0x1bc5eebe    pinctrl_gpio_direction_input    vmlinux EXPORT_SYMBOL_GPL
+-0x519b061e    genl_register_mc_group  vmlinux EXPORT_SYMBOL
+-0xf81e0907    ___pskb_trim    vmlinux EXPORT_SYMBOL
+-0xd352e668    snd_timer_global_new    vmlinux EXPORT_SYMBOL
+-0x85df9b6c    strsep  vmlinux EXPORT_SYMBOL
+-0xe2d5255a    strcmp  vmlinux EXPORT_SYMBOL
+-0x788fe103    iomem_resource  vmlinux EXPORT_SYMBOL
+-0xe7a9a6a0    tty_driver_flush_buffer vmlinux EXPORT_SYMBOL
+-0xd648e564    fb_match_mode   vmlinux EXPORT_SYMBOL
+-0xbc10dd97    __put_user_4    vmlinux EXPORT_SYMBOL
+-0x353e3fa5    __get_user_4    vmlinux EXPORT_SYMBOL
+-0xe50ad8a8    snd_ctl_add     vmlinux EXPORT_SYMBOL
+-0x6323f87b    mnt_unpin       vmlinux EXPORT_SYMBOL
+-0xbb524006    vfs_create      vmlinux EXPORT_SYMBOL
+-0x2f47d8c7    cpufreq_frequency_get_table     vmlinux EXPORT_SYMBOL_GPL
+-0xda44cb37    setup_charger_manager   vmlinux EXPORT_SYMBOL_GPL
+-0x01ab74a6    devm_kfree      vmlinux EXPORT_SYMBOL_GPL
+-0x153be8a8    drm_fb_helper_pan_display       vmlinux EXPORT_SYMBOL
+-0xc676a007    __ablkcipher_walk_complete      vmlinux EXPORT_SYMBOL_GPL
+-0x868bf31d    sb_min_blocksize        vmlinux EXPORT_SYMBOL
+-0xaf5f7994    remove_conflicting_framebuffers vmlinux EXPORT_SYMBOL
+-0x49e5aa17    bt_procfs_init  vmlinux EXPORT_SYMBOL
+-0xf353a698    register_module_notifier        vmlinux EXPORT_SYMBOL
+-0x154c6338    dm_kcopyd_client_destroy        vmlinux EXPORT_SYMBOL
+-0xdd4cc94f    v4l2_device_set_name    vmlinux EXPORT_SYMBOL_GPL
+-0x703189d7    regulator_get_mode      vmlinux EXPORT_SYMBOL_GPL
+-0x43028a27    nfc_hci_result_to_errno vmlinux EXPORT_SYMBOL
+-0x0551f0ce    tick_nohz_idle_exit     vmlinux EXPORT_SYMBOL_GPL
+-0xc7208c3a    serial8250_resume_port  vmlinux EXPORT_SYMBOL
+-0xe91355f8    inet_csk_clone_lock     vmlinux EXPORT_SYMBOL_GPL
+-0xe912da6b    unregister_sysctl_table vmlinux EXPORT_SYMBOL
+-0xaf91d89f    __kernel_param_lock     vmlinux EXPORT_SYMBOL
+-0x31cdd70c    hid_input_report        vmlinux EXPORT_SYMBOL_GPL
+-0xd73ee981    cdc_ncm_fill_tx_frame   vmlinux EXPORT_SYMBOL_GPL
+-0xa01c6bfd    del_gendisk     vmlinux EXPORT_SYMBOL
+-0x4d74d134    block_write_full_page   vmlinux EXPORT_SYMBOL
+-0x43632d7d    of_find_property        vmlinux EXPORT_SYMBOL
+-0xa76550fa    xfrm_register_type      vmlinux EXPORT_SYMBOL
+-0xde08bdaf    nf_ct_invert_tuple      vmlinux EXPORT_SYMBOL_GPL
+-0xa61aa028    snd_pcm_format_unsigned vmlinux EXPORT_SYMBOL
+-0x0b51f3e2    fat_sync_inode  vmlinux EXPORT_SYMBOL_GPL
+-0xb3e441b1    clear_bdi_congested     vmlinux EXPORT_SYMBOL
+-0x9305f8e6    cpufreq_get     vmlinux EXPORT_SYMBOL
+-0x8708f581    usbnet_stop     vmlinux EXPORT_SYMBOL_GPL
+-0x581e0fb1    sock_no_setsockopt      vmlinux EXPORT_SYMBOL
+-0xdf40231d    sock_no_getsockopt      vmlinux EXPORT_SYMBOL
+-0xa3355ffa    snd_soc_default_writable_register       vmlinux EXPORT_SYMBOL_GPL
+-0xb8ba4a80    __blockdev_direct_IO    vmlinux EXPORT_SYMBOL
+-0x4f70015c    splice_from_pipe_end    vmlinux EXPORT_SYMBOL
+-0x93658a27    migrate_page    vmlinux EXPORT_SYMBOL
+-0x2e45e488    rcu_note_context_switch vmlinux EXPORT_SYMBOL_GPL
+-0xf0d68ed6    clk_register_clkdevs    vmlinux EXPORT_SYMBOL
+-0xec58fd46    ip6_route_me_harder     vmlinux EXPORT_SYMBOL
+-0xccec571a    thermal_zone_device_update      vmlinux EXPORT_SYMBOL_GPL
+-0x011c6bf0    regulator_map_voltage_iterate   vmlinux EXPORT_SYMBOL_GPL
+-0x44eabd85    km_new_mapping  vmlinux EXPORT_SYMBOL
+-0x4469fe89    lro_receive_skb vmlinux EXPORT_SYMBOL
+-0x6d54f969    napi_complete   vmlinux EXPORT_SYMBOL
+-0xb740018f    snd_device_new  vmlinux EXPORT_SYMBOL
+-0xab363caa    generic_block_bmap      vmlinux EXPORT_SYMBOL
+-0x868784cb    __symbol_get    vmlinux EXPORT_SYMBOL_GPL
+-0x142a8be4    of_clk_get_parent_name  vmlinux EXPORT_SYMBOL_GPL
+-0x991484c4    of_property_count_strings       vmlinux EXPORT_SYMBOL_GPL
+-0x5f3c8f5c    mmc_assume_removable    vmlinux EXPORT_SYMBOL
+-0xf9c1f53f    pm_generic_thaw_early   vmlinux EXPORT_SYMBOL_GPL
+-0x47229b5c    gpio_request    vmlinux EXPORT_SYMBOL_GPL
+-0x517deb22    __ip_dev_find   vmlinux EXPORT_SYMBOL
+-0x815fe221    snd_pcm_hw_constraint_list      vmlinux EXPORT_SYMBOL
+-0xbe0e5118    nla_memcmp      vmlinux EXPORT_SYMBOL
+-0xf1db1704    nla_memcpy      vmlinux EXPORT_SYMBOL
+-0x1f77b093    file_remove_suid        vmlinux EXPORT_SYMBOL
+-0xfd6794fe    d_materialise_unique    vmlinux EXPORT_SYMBOL_GPL
+-0x26622a2b    kmem_cache_free vmlinux EXPORT_SYMBOL
+-0x7aab19fb    vb2_ops_wait_prepare    vmlinux EXPORT_SYMBOL_GPL
+-0x5d22b406    rndis_register  vmlinux EXPORT_SYMBOL
+-0xd25dc9c5    cdc_ncm_rx_verify_nth16 vmlinux EXPORT_SYMBOL_GPL
+-0x8299a21a    ieee80211_data_from_8023        vmlinux EXPORT_SYMBOL
+-0x499cb58c    prepare_to_wait vmlinux EXPORT_SYMBOL
+-0xadf42bd5    __request_region        vmlinux EXPORT_SYMBOL
+-0x9f560253    get_cpu_device  vmlinux EXPORT_SYMBOL_GPL
+-0x923b1276    dmaengine_get   vmlinux EXPORT_SYMBOL
+-0x56d9b1de    amba_device_register    vmlinux EXPORT_SYMBOL
+-0x6fa16209    bdev_read_only  vmlinux EXPORT_SYMBOL
+-0xf0009fee    put_pages_list  vmlinux EXPORT_SYMBOL
+-0xdf73013e    from_kprojid    vmlinux EXPORT_SYMBOL
+-0x2609451c    sock_wfree      vmlinux EXPORT_SYMBOL
+-0x0de80eba    snd_soc_info_volsw      vmlinux EXPORT_SYMBOL_GPL
+-0xd7f77051    test_set_page_writeback vmlinux EXPORT_SYMBOL
+-0xa734a3e9    abort_exclusive_wait    vmlinux EXPORT_SYMBOL
+-0x091eb9b4    round_jiffies   vmlinux EXPORT_SYMBOL_GPL
+-0x99429b47    display_entity_unregister       vmlinux EXPORT_SYMBOL_GPL
+-0x40d0b751    qdisc_destroy   vmlinux EXPORT_SYMBOL
+-0x16445cb3    inet_proto_csum_replace16       vmlinux EXPORT_SYMBOL
+-0x5594be03    bitmap_remap    vmlinux EXPORT_SYMBOL
+-0x7fe04a49    truncate_inode_pages    vmlinux EXPORT_SYMBOL
+-0x42f865b4    fb_videomode_from_videomode     vmlinux EXPORT_SYMBOL_GPL
+-0x0422fe4a    inet_csk_timer_bug_msg  vmlinux EXPORT_SYMBOL
+-0x1b0c9510    sysfs_notify    vmlinux EXPORT_SYMBOL_GPL
+-0x0948cde9    num_physpages   vmlinux EXPORT_SYMBOL
+-0x7818fe23    input_flush_device      vmlinux EXPORT_SYMBOL
+-0x2da17677    regmap_bulk_write       vmlinux EXPORT_SYMBOL_GPL
+-0x03ba39b0    v7_flush_user_cache_all vmlinux EXPORT_SYMBOL
+-0x9d0403b2    inet_hash       vmlinux EXPORT_SYMBOL_GPL
+-0x9a1dfd65    strpbrk vmlinux EXPORT_SYMBOL
+-0xa040153b    sysfs_create_file       vmlinux EXPORT_SYMBOL_GPL
+-0x99cbae17    seq_lseek       vmlinux EXPORT_SYMBOL
+-0x092c2a7a    irq_domain_add_tree     vmlinux EXPORT_SYMBOL_GPL
+-0x23a42148    media_entity_pipeline_stop      vmlinux EXPORT_SYMBOL_GPL
+-0xd87b6687    ip6_frag_match  vmlinux EXPORT_SYMBOL
+-0x9e6d79f8    snd_info_get_str        vmlinux EXPORT_SYMBOL
+-0x1551dc51    bitmap_find_free_region vmlinux EXPORT_SYMBOL
+-0x9f491e5d    ftrace_print_symbols_seq_u64    vmlinux EXPORT_SYMBOL
+-0x9b6bedb6    sdhci_add_host  vmlinux EXPORT_SYMBOL_GPL
+-0x928f84b5    drm_crtc_init   vmlinux EXPORT_SYMBOL
+-0x56b63670    lzo1x_1_compress        vmlinux EXPORT_SYMBOL_GPL
+-0x637d3d6a    set_disk_ro     vmlinux EXPORT_SYMBOL
+-0x5053e2a6    leds_list_lock  vmlinux EXPORT_SYMBOL_GPL
+-0x19fc7f60    regulator_set_mode      vmlinux EXPORT_SYMBOL_GPL
+-0x7e703a3d    snd_soc_limit_volume    vmlinux EXPORT_SYMBOL_GPL
+-0x3bdbf275    sg_alloc_table_from_pages       vmlinux EXPORT_SYMBOL
+-0xb87bf605    blk_rq_unprep_clone     vmlinux EXPORT_SYMBOL_GPL
+-0xe04f7caa    dm_read_arg_group       vmlinux EXPORT_SYMBOL
+-0xb26725f8    bus_find_device vmlinux EXPORT_SYMBOL_GPL
+-0x7ff32312    drm_gem_handle_create   vmlinux EXPORT_SYMBOL
+-0xcd7edbe9    cfg80211_sched_scan_results     vmlinux EXPORT_SYMBOL
+-0x92dbc6c1    xfrm_aalg_get_byid      vmlinux EXPORT_SYMBOL_GPL
+-0x6fb14f17    tcp_create_openreq_child        vmlinux EXPORT_SYMBOL
+-0x2f368d4c    sk_common_release       vmlinux EXPORT_SYMBOL
+-0xd60281a9    st_sensors_set_fullscale_by_gain        vmlinux EXPORT_SYMBOL
+-0x228bec81    led_trigger_register    vmlinux EXPORT_SYMBOL_GPL
+-0x28c52e3f    video_device_release    vmlinux EXPORT_SYMBOL
+-0x3faac56f    drm_mode_set_config_internal    vmlinux EXPORT_SYMBOL
+-0xf86d3493    skb_queue_head  vmlinux EXPORT_SYMBOL
+-0x5fd1e756    skb_prepare_seq_read    vmlinux EXPORT_SYMBOL
+-0x02ff8c3e    sk_reset_timer  vmlinux EXPORT_SYMBOL
+-0xb08f47ec    snd_soc_resume  vmlinux EXPORT_SYMBOL_GPL
+-0x0f055dad    snd_pcm_hw_rule_noresample      vmlinux EXPORT_SYMBOL
+-0x9529f10a    fuse_conn_put   vmlinux EXPORT_SYMBOL_GPL
+-0xf6bb8bf1    irq_get_irq_data        vmlinux EXPORT_SYMBOL_GPL
+-0x02c3c736    v4l2_subdev_querymenu   vmlinux EXPORT_SYMBOL
+-0xfb42deb3    drm_helper_mode_fill_fb_struct  vmlinux EXPORT_SYMBOL
+-0x4920a692    regulator_bulk_enable   vmlinux EXPORT_SYMBOL_GPL
+-0x85963907    netdev_has_upper_dev    vmlinux EXPORT_SYMBOL
+-0x5f58f676    flex_array_get_ptr      vmlinux EXPORT_SYMBOL
+-0x3e6c012e    bio_alloc_bioset        vmlinux EXPORT_SYMBOL
+-0xb9ac0503    mali_set_user_setting   vmlinux EXPORT_SYMBOL
+-0xbd22a332    drm_pci_free    vmlinux EXPORT_SYMBOL
+-0x171addd2    ieee80211_get_hdrlen_from_skb   vmlinux EXPORT_SYMBOL
+-0xe41115b7    vfs_cancel_lock vmlinux EXPORT_SYMBOL_GPL
+-0x912c123d    pm_qos_remove_request   vmlinux EXPORT_SYMBOL_GPL
+-0x8e2d17cc    v4l2_clk_enable vmlinux EXPORT_SYMBOL
+-0xfe3150df    usb_driver_set_configuration    vmlinux EXPORT_SYMBOL_GPL
+-0x3b5bb4f2    mii_ethtool_sset        vmlinux EXPORT_SYMBOL
+-0xe9bc24c2    mii_ethtool_gset        vmlinux EXPORT_SYMBOL
+-0x62e1f48d    class_compat_create_link        vmlinux EXPORT_SYMBOL_GPL
+-0xb602c57e    nf_ct_l3proto_module_put        vmlinux EXPORT_SYMBOL_GPL
+-0xcd4b940c    release_sock    vmlinux EXPORT_SYMBOL
+-0x90e5450f    textsearch_destroy      vmlinux EXPORT_SYMBOL
+-0x50e7193a    __i2c_first_dynamic_bus_num     vmlinux EXPORT_SYMBOL_GPL
+-0xa2a8e81f    class_remove_file       vmlinux EXPORT_SYMBOL_GPL
+-0x95f56edb    drm_i2c_encoder_init    vmlinux EXPORT_SYMBOL
+-0xdd1dd3a7    snd_pcm_hw_constraint_msbits    vmlinux EXPORT_SYMBOL
+-0x23a574fd    security_secmark_relabel_packet vmlinux EXPORT_SYMBOL
+-0x3f01eca9    unmap_underlying_metadata       vmlinux EXPORT_SYMBOL
+-0x55feec9e    sync_inode      vmlinux EXPORT_SYMBOL
+-0xb859f38b    krealloc        vmlinux EXPORT_SYMBOL
+-0x9af5fc30    of_phy_connect_fixed_link       vmlinux EXPORT_SYMBOL
+-0xa2307653    v4l2_device_register_subdev_nodes       vmlinux EXPORT_SYMBOL_GPL
+-0x66e9dc03    usbnet_status_stop      vmlinux EXPORT_SYMBOL_GPL
+-0x419a9395    snd_card_create vmlinux EXPORT_SYMBOL
+-0x9edc4cdb    __invalidate_device     vmlinux EXPORT_SYMBOL
+-0x301fa826    seq_put_decimal_ull     vmlinux EXPORT_SYMBOL
+-0x8f7b5061    jack_event_handler      vmlinux EXPORT_SYMBOL_GPL
+-0xf8e6aed1    input_register_device   vmlinux EXPORT_SYMBOL
+-0xfba9b108    drm_fb_helper_fini      vmlinux EXPORT_SYMBOL
+-0x31266931    con_debug_leave vmlinux EXPORT_SYMBOL_GPL
+-0x2ba707a8    sysctl_tcp_low_latency  vmlinux EXPORT_SYMBOL
+-0x1163f0a7    blk_max_low_pfn vmlinux EXPORT_SYMBOL
+-0x94c6b808    blk_queue_free_tags     vmlinux EXPORT_SYMBOL
+-0xe0413655    elv_unregister_queue    vmlinux EXPORT_SYMBOL
+-0x3fab3ca9    register_sysctl_table   vmlinux EXPORT_SYMBOL
+-0x67b78eb3    seq_hlist_next_rcu      vmlinux EXPORT_SYMBOL
+-0x571767e3    led_classdev_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x9323826a    ipv4_redirect   vmlinux EXPORT_SYMBOL_GPL
+-0x495c96f8    posix_acl_init  vmlinux EXPORT_SYMBOL
+-0xd59c42a1    drm_idlelock_release    vmlinux EXPORT_SYMBOL
+-0x490355ba    tty_flip_buffer_push    vmlinux EXPORT_SYMBOL
+-0x3ef6c408    bio_copy_data   vmlinux EXPORT_SYMBOL
+-0x6fe3d8cf    ktime_add_safe  vmlinux EXPORT_SYMBOL_GPL
+-0xf9a482f9    msleep  vmlinux EXPORT_SYMBOL
+-0xc66b77b1    iommu_group_set_iommudata       vmlinux EXPORT_SYMBOL_GPL
+-0xd55ad93b    iommu_group_get_iommudata       vmlinux EXPORT_SYMBOL_GPL
+-0x0d0549e1    hidinput_calc_abs_res   vmlinux EXPORT_SYMBOL_GPL
+-0x07608656    uart_get_divisor        vmlinux EXPORT_SYMBOL
+-0xc8f72480    unregister_netdev       vmlinux EXPORT_SYMBOL
+-0x1ce42553    __bforget       vmlinux EXPORT_SYMBOL
+-0x8427e5bd    v4l2_event_subdev_unsubscribe   vmlinux EXPORT_SYMBOL_GPL
+-0x8e865d3c    arm_delay_ops   vmlinux EXPORT_SYMBOL
+-0x2f88c16b    inet6_add_protocol      vmlinux EXPORT_SYMBOL
+-0x9fda569e    raw_unhash_sk   vmlinux EXPORT_SYMBOL_GPL
+-0x1def6812    xt_register_table       vmlinux EXPORT_SYMBOL_GPL
+-0xe7e87d7a    set_h225_addr_hook      vmlinux EXPORT_SYMBOL_GPL
+-0xd2037371    sock_no_listen  vmlinux EXPORT_SYMBOL
+-0x33607e14    snd_soc_poweroff        vmlinux EXPORT_SYMBOL_GPL
+-0xab600421    probe_irq_off   vmlinux EXPORT_SYMBOL
+-0xfc8ace2f    input_mt_destroy_slots  vmlinux EXPORT_SYMBOL
+-0xf222f80f    usb_unpoison_anchored_urbs      vmlinux EXPORT_SYMBOL_GPL
+-0x4845cdbc    scsi_device_lookup_by_target    vmlinux EXPORT_SYMBOL
+-0x79aa04a2    get_random_bytes        vmlinux EXPORT_SYMBOL
+-0x9db44776    nfc_hci_connect_gate    vmlinux EXPORT_SYMBOL
+-0x4d2726f3    tcf_exts_destroy        vmlinux EXPORT_SYMBOL
+-0xbaa8249a    snd_ctl_activate_id     vmlinux EXPORT_SYMBOL_GPL
+-0x55ef85b4    blk_peek_request        vmlinux EXPORT_SYMBOL
+-0xc8b267ae    seq_vprintf     vmlinux EXPORT_SYMBOL
+-0xe6504df3    sdhci_get_of_property   vmlinux EXPORT_SYMBOL_GPL
+-0x3ad12077    regcache_sync_region    vmlinux EXPORT_SYMBOL_GPL
+-0x80af255f    pm_runtime_allow        vmlinux EXPORT_SYMBOL_GPL
+-0x16105b8e    do_unbind_con_driver    vmlinux EXPORT_SYMBOL_GPL
+-0xdaf4dfb3    fb_mode_option  vmlinux EXPORT_SYMBOL_GPL
+-0x1f5dd478    tcf_hash_lookup vmlinux EXPORT_SYMBOL
+-0x14965155    sock_no_poll    vmlinux EXPORT_SYMBOL
+-0xfcbe775e    blk_rq_prep_clone       vmlinux EXPORT_SYMBOL_GPL
+-0x53e6cd86    crypto_alloc_shash      vmlinux EXPORT_SYMBOL_GPL
+-0x93f84c0c    crypto_alloc_ahash      vmlinux EXPORT_SYMBOL_GPL
+-0xae1d4afd    sdio_unregister_driver  vmlinux EXPORT_SYMBOL_GPL
+-0x1b50682a    drm_mode_connector_attach_encoder       vmlinux EXPORT_SYMBOL
+-0x78bed30e    regulator_get   vmlinux EXPORT_SYMBOL_GPL
+-0xae4e6d07    inet6_register_icmp_sender      vmlinux EXPORT_SYMBOL
+-0xcd67300d    vlan_ioctl_set  vmlinux EXPORT_SYMBOL
+-0x4d9b6d35    snd_pcm_format_size     vmlinux EXPORT_SYMBOL
+-0xc11d8093    iov_shorten     vmlinux EXPORT_SYMBOL
+-0x6a037cf1    mempool_kfree   vmlinux EXPORT_SYMBOL
+-0x0cebb5a5    __ww_mutex_lock vmlinux EXPORT_SYMBOL
+-0x430e5257    of_alias_get_id vmlinux EXPORT_SYMBOL_GPL
+-0x5d9260a1    v4l2_ctrl_activate      vmlinux EXPORT_SYMBOL
+-0x17622c01    display_entity_set_state        vmlinux EXPORT_SYMBOL_GPL
+-0x26adb815    thread_notify_head      vmlinux EXPORT_SYMBOL_GPL
+-0xf0ef15b4    list_sort       vmlinux EXPORT_SYMBOL
+-0x958974d4    remove_arg_zero vmlinux EXPORT_SYMBOL
+-0x7b5c8440    vm_munmap       vmlinux EXPORT_SYMBOL
+-0x46178343    remap_pfn_range vmlinux EXPORT_SYMBOL
+-0x46608fa0    getnstimeofday  vmlinux EXPORT_SYMBOL
+-0x51a049e1    scsi_scan_target        vmlinux EXPORT_SYMBOL
+-0x61b31a8a    subsys_dev_iter_init    vmlinux EXPORT_SYMBOL_GPL
+-0x054aade6    subsys_dev_iter_exit    vmlinux EXPORT_SYMBOL_GPL
+-0x4099164a    skcipher_geniv_exit     vmlinux EXPORT_SYMBOL_GPL
+-0x9c144793    file_update_time        vmlinux EXPORT_SYMBOL
+-0x8a162c7d    bdi_unregister  vmlinux EXPORT_SYMBOL
+-0x755d68eb    iio_enum_read   vmlinux EXPORT_SYMBOL_GPL
+-0x03e593b9    vb2_wait_for_all_buffers        vmlinux EXPORT_SYMBOL_GPL
+-0xc06a30a4    phy_register_fixup      vmlinux EXPORT_SYMBOL
+-0x3c308a26    device_bind_driver      vmlinux EXPORT_SYMBOL_GPL
+-0x55010072    device_store_ulong      vmlinux EXPORT_SYMBOL_GPL
+-0x0b405d40    inet6_csk_search_req    vmlinux EXPORT_SYMBOL_GPL
+-0x7a1acc62    dev_mc_init     vmlinux EXPORT_SYMBOL
+-0x93fcc9bd    dev_uc_init     vmlinux EXPORT_SYMBOL
+-0x865029ac    __hw_addr_sync  vmlinux EXPORT_SYMBOL
+-0xb04359d9    snd_soc_bytes_info      vmlinux EXPORT_SYMBOL_GPL
+-0x11a13e31    _kstrtol        vmlinux EXPORT_SYMBOL
+-0x6e73746d    kobject_uevent_env      vmlinux EXPORT_SYMBOL_GPL
+-0x7d830ea5    mb_cache_entry_alloc    vmlinux EXPORT_SYMBOL
+-0xd702e480    _raw_read_unlock        vmlinux EXPORT_SYMBOL
+-0xfa2bcf10    init_timer_key  vmlinux EXPORT_SYMBOL
+-0xe03525ac    of_irq_map_raw  vmlinux EXPORT_SYMBOL_GPL
+-0xb39171d5    cdc_ncm_select_altsetting       vmlinux EXPORT_SYMBOL_GPL
+-0xec52c42e    scsi_setup_blk_pc_cmnd  vmlinux EXPORT_SYMBOL
+-0x337cce46    put_cmsg        vmlinux EXPORT_SYMBOL
+-0x655656dc    skb_free_datagram       vmlinux EXPORT_SYMBOL
+-0x2ad0e68c    sound_class     vmlinux EXPORT_SYMBOL
+-0x7a98596c    filp_close      vmlinux EXPORT_SYMBOL
+-0x4c39b01b    truncate_setsize        vmlinux EXPORT_SYMBOL
+-0xfd5683b9    wait_for_completion_interruptible       vmlinux EXPORT_SYMBOL
+-0xfc38a837    extcon_update_state     vmlinux EXPORT_SYMBOL_GPL
+-0xdba80fc1    of_fdt_unflatten_tree   vmlinux EXPORT_SYMBOL_GPL
+-0x3be54580    generic_readlink        vmlinux EXPORT_SYMBOL
+-0x6cee2e42    drm_object_property_get_value   vmlinux EXPORT_SYMBOL
+-0x67b27ec1    tty_std_termios vmlinux EXPORT_SYMBOL
+-0x4298b775    v7_flush_kern_cache_all vmlinux EXPORT_SYMBOL
+-0x66ac9af0    ether_setup     vmlinux EXPORT_SYMBOL
+-0xafb2d50e    __break_lease   vmlinux EXPORT_SYMBOL
+-0x9e6500de    get_task_comm   vmlinux EXPORT_SYMBOL_GPL
+-0xd5df9165    __get_vm_area   vmlinux EXPORT_SYMBOL_GPL
+-0x6b7589f4    param_set_bool  vmlinux EXPORT_SYMBOL
+-0xbfc407b4    param_ops_bint  vmlinux EXPORT_SYMBOL
+-0xadb5559d    param_ops_byte  vmlinux EXPORT_SYMBOL
+-0xd2a3a2e7    usb_deregister_device_driver    vmlinux EXPORT_SYMBOL_GPL
+-0x0264e273    usbnet_nway_reset       vmlinux EXPORT_SYMBOL_GPL
+-0xbc31af43    device_create_file      vmlinux EXPORT_SYMBOL_GPL
+-0x34bb0082    snd_soc_dapm_put_volsw  vmlinux EXPORT_SYMBOL_GPL
+-0xcec0e354    snd_soc_dapm_get_volsw  vmlinux EXPORT_SYMBOL_GPL
+-0xa3d6bc8a    would_dump      vmlinux EXPORT_SYMBOL
+-0x782cd0c9    truncate_inode_pages_range      vmlinux EXPORT_SYMBOL
+-0xefc7de8e    force_sig       vmlinux EXPORT_SYMBOL
+-0xb3b30554    fimc_find_remote_sensor vmlinux EXPORT_SYMBOL
+-0xf3be20f4    v4l2_m2m_querybuf       vmlinux EXPORT_SYMBOL_GPL
+-0x0fccafb1    drm_global_item_unref   vmlinux EXPORT_SYMBOL
+-0xe8d24f74    arm_coherent_dma_ops    vmlinux EXPORT_SYMBOL
+-0x05240ee7    percpu_counter_batch    vmlinux EXPORT_SYMBOL
+-0x5d75cd76    d_path  vmlinux EXPORT_SYMBOL
+-0x495426ee    v4l2_ctrl_get_name      vmlinux EXPORT_SYMBOL
+-0x6e89a560    regmap_irq_chip_get_base        vmlinux EXPORT_SYMBOL_GPL
+-0x587616f1    vfs_fstatat     vmlinux EXPORT_SYMBOL
+-0x162ccc0c    lg_local_lock   vmlinux EXPORT_SYMBOL
+-0x498225b6    v4l2_m2m_expbuf vmlinux EXPORT_SYMBOL_GPL
+-0x21b2c1ab    __pm_genpd_remove_callbacks     vmlinux EXPORT_SYMBOL_GPL
+-0x1516aa21    brcmf_sdio_probe        drivers/net/wireless/brcm80211/brcmfmac/brcmfmac        EXPORT_SYMBOL
+-0x36c61868    hci_free_dev    vmlinux EXPORT_SYMBOL
+-0xcfa46265    igrab   vmlinux EXPORT_SYMBOL
+-0x36150611    iio_validate_scan_mask_onehot   vmlinux EXPORT_SYMBOL_GPL
+-0x01ac01fc    usbnet_resume   vmlinux EXPORT_SYMBOL_GPL
+-0x43421b4f    sdev_evt_send   vmlinux EXPORT_SYMBOL_GPL
+-0x1fdcc615    rtnl_notify     vmlinux EXPORT_SYMBOL
+-0xe4ad075c    __rtnl_link_register    vmlinux EXPORT_SYMBOL_GPL
+-0x41366c3b    sock_recvmsg    vmlinux EXPORT_SYMBOL
+-0x3468cb4a    snd_soc_set_runtime_hwparams    vmlinux EXPORT_SYMBOL_GPL
+-0x308e4695    snd_pcm_open_substream  vmlinux EXPORT_SYMBOL
+-0x2ef9dbdc    blk_end_request_err     vmlinux EXPORT_SYMBOL_GPL
+-0x9b11d9bf    blk_end_request_all     vmlinux EXPORT_SYMBOL
+-0x2f5bf998    blk_queue_bio   vmlinux EXPORT_SYMBOL_GPL
+-0xd16712f3    crypto_check_attr_type  vmlinux EXPORT_SYMBOL_GPL
+-0x16305289    warn_slowpath_null      vmlinux EXPORT_SYMBOL
+-0xcb0288ea    ledtrig_cpu     vmlinux EXPORT_SYMBOL
+-0xe6431c3b    mmc_can_secure_erase_trim       vmlinux EXPORT_SYMBOL
+-0x916dbe7c    usb_hcd_unmap_urb_for_dma       vmlinux EXPORT_SYMBOL_GPL
+-0x8dc2569e    nf_ct_l3protos  vmlinux EXPORT_SYMBOL_GPL
+-0x1471e34e    linkwatch_fire_event    vmlinux EXPORT_SYMBOL
+-0x56db40e5    snd_device_free vmlinux EXPORT_SYMBOL
+-0xe1b524a3    fs_bio_set      vmlinux EXPORT_SYMBOL
+-0x8d522714    __rcu_read_lock vmlinux EXPORT_SYMBOL_GPL
+-0x4906a967    hid_snto32      vmlinux EXPORT_SYMBOL_GPL
+-0xfbf6bb67    watchdog_init_timeout   vmlinux EXPORT_SYMBOL_GPL
+-0xd37e13b4    regulator_set_optimum_mode      vmlinux EXPORT_SYMBOL_GPL
+-0x4fe1eddf    unregister_netevent_notifier    vmlinux EXPORT_SYMBOL_GPL
+-0x66af941c    snd_soc_debugfs_root    vmlinux EXPORT_SYMBOL_GPL
+-0x42c43759    input_mt_report_slot_state      vmlinux EXPORT_SYMBOL
+-0x8fccb56f    scsi_init_io    vmlinux EXPORT_SYMBOL
+-0x375fce7f    asoc_dma_platform_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0xa58dee99    _raw_write_unlock       vmlinux EXPORT_SYMBOL
+-0x252efd1e    sdhci_remove_host       vmlinux EXPORT_SYMBOL_GPL
+-0xb5128e67    v4l2_i2c_subdev_init    vmlinux EXPORT_SYMBOL_GPL
+-0x6d680e52    v4l2_i2c_subdev_addr    vmlinux EXPORT_SYMBOL_GPL
+-0xb56fc02f    fib_default_rule_pref   vmlinux EXPORT_SYMBOL
+-0x97359c5f    snd_pcm_period_elapsed  vmlinux EXPORT_SYMBOL
+-0x3df477d7    debugfs_create_x8       vmlinux EXPORT_SYMBOL_GPL
+-0x314d3160    kmap_to_page    vmlinux EXPORT_SYMBOL
+-0x8afbf7b1    irq_domain_xlate_onecell        vmlinux EXPORT_SYMBOL_GPL
+-0x6b264960    irq_domain_xlate_twocell        vmlinux EXPORT_SYMBOL_GPL
+-0xee3c209d    cgroup_next_descendant_pre      vmlinux EXPORT_SYMBOL_GPL
+-0x6776c27a    drm_av_sync_delay       vmlinux EXPORT_SYMBOL
+-0x0fe112dc    of_dma_controller_free  vmlinux EXPORT_SYMBOL_GPL
+-0xfccc95e9    pwm_put vmlinux EXPORT_SYMBOL_GPL
+-0xb8a5a2d7    iio_convert_raw_to_processed    vmlinux EXPORT_SYMBOL_GPL
+-0x8f7df3a7    drm_object_attach_property      vmlinux EXPORT_SYMBOL
+-0xd248fe40    uart_write_wakeup       vmlinux EXPORT_SYMBOL
+-0x0483a4c2    skb_append      vmlinux EXPORT_SYMBOL
+-0xb28d7c56    snd_soc_read    vmlinux EXPORT_SYMBOL_GPL
+-0x6f1f9555    read_cache_page_gfp     vmlinux EXPORT_SYMBOL
+-0xe12954af    pwm_can_sleep   vmlinux EXPORT_SYMBOL_GPL
+-0x333147c5    sk_stream_error vmlinux EXPORT_SYMBOL
+-0x37f30c3d    devm_request_and_ioremap        vmlinux EXPORT_SYMBOL
+-0x40d57aa3    audit_log_start vmlinux EXPORT_SYMBOL
+-0x3232306b    need_load_eval  vmlinux EXPORT_SYMBOL_GPL
+-0x27328cec    drm_fb_helper_debug_leave       vmlinux EXPORT_SYMBOL
+-0x2f4df599    arm_iommu_attach_device vmlinux EXPORT_SYMBOL_GPL
+-0x38ec6320    netdev_crit     vmlinux EXPORT_SYMBOL
+-0x7385ebdb    sysfs_create_files      vmlinux EXPORT_SYMBOL_GPL
+-0x0758ff61    sget    vmlinux EXPORT_SYMBOL
+-0xca20d111    v4l2_ctrl_cluster       vmlinux EXPORT_SYMBOL
+-0x5f754e5a    memset  vmlinux EXPORT_SYMBOL
+-0xbd70447e    ip_tunnel_setup vmlinux EXPORT_SYMBOL_GPL
+-0x2541a979    snd_soc_calc_frame_size vmlinux EXPORT_SYMBOL_GPL
+-0xdc3fcbc9    __sw_hweight8   vmlinux EXPORT_SYMBOL
+-0x02ee26c1    free_pages_exact        vmlinux EXPORT_SYMBOL
+-0x885bcec8    tasklet_hrtimer_init    vmlinux EXPORT_SYMBOL_GPL
+-0xe80bbfc6    v4l2_event_pending      vmlinux EXPORT_SYMBOL_GPL
+-0x356cb8d3    debugfs_create_atomic_t vmlinux EXPORT_SYMBOL_GPL
+-0x064db9a5    mark_mounts_for_expiry  vmlinux EXPORT_SYMBOL_GPL
+-0x8b43159b    register_cpu_notifier   vmlinux EXPORT_SYMBOL
+-0xd0d5f859    st_sensors_read_event_config    vmlinux EXPORT_SYMBOL
+-0xba490602    nci_to_errno    vmlinux EXPORT_SYMBOL
+-0x26cae22e    snd_soc_dapm_free       vmlinux EXPORT_SYMBOL_GPL
+-0x6b4f9016    d_set_d_op      vmlinux EXPORT_SYMBOL
+-0x6d340f64    tty_termios_input_baud_rate     vmlinux EXPORT_SYMBOL
+-0x0d3f57a2    _find_next_bit_le       vmlinux EXPORT_SYMBOL
+-0x74e1a843    xfrm_aalg_get_byidx     vmlinux EXPORT_SYMBOL_GPL
+-0x56b147ce    unregister_tcf_proto_ops        vmlinux EXPORT_SYMBOL
+-0xb6936ffe    _bcd2bin        vmlinux EXPORT_SYMBOL
+-0x707f5f40    vb2_fop_write   vmlinux EXPORT_SYMBOL_GPL
+-0x598cd828    udp_table       vmlinux EXPORT_SYMBOL
+-0x7d0e3e72    ida_get_new_above       vmlinux EXPORT_SYMBOL
+-0x2e2f1740    ring_buffer_record_disable_cpu  vmlinux EXPORT_SYMBOL_GPL
+-0xafe38346    mmc_erase_group_aligned vmlinux EXPORT_SYMBOL
+-0x1af8e94b    nla_put vmlinux EXPORT_SYMBOL
+-0xf23fcb99    __kfifo_in      vmlinux EXPORT_SYMBOL
+-0xf8ac3a16    revalidate_disk vmlinux EXPORT_SYMBOL
+-0xca5967e3    vm_stat vmlinux EXPORT_SYMBOL
+-0xd5b1376d    register_shrinker       vmlinux EXPORT_SYMBOL
+-0xa6c3a59e    power_supply_am_i_supplied      vmlinux EXPORT_SYMBOL_GPL
+-0x35aa9322    regcache_mark_dirty     vmlinux EXPORT_SYMBOL_GPL
+-0xbdb14b0b    transport_configure_device      vmlinux EXPORT_SYMBOL_GPL
+-0x391c8c77    drm_bl_register vmlinux EXPORT_SYMBOL_GPL
+-0x2c744386    ip_tunnel_dellink       vmlinux EXPORT_SYMBOL_GPL
+-0xc10022a2    register_sound_dsp      vmlinux EXPORT_SYMBOL
+-0x6d29349e    blk_post_runtime_suspend        vmlinux EXPORT_SYMBOL
+-0x803eda06    block_invalidatepage    vmlinux EXPORT_SYMBOL
+-0x22ba7f9f    may_umount_tree vmlinux EXPORT_SYMBOL
+-0x7a944007    rcu_idle_enter  vmlinux EXPORT_SYMBOL_GPL
+-0x3ce3f899    iio_device_register     vmlinux EXPORT_SYMBOL
+-0x624a6406    hwrng_register  vmlinux EXPORT_SYMBOL_GPL
+-0xa408cd5e    misc_register   vmlinux EXPORT_SYMBOL
+-0x636b12c8    nf_nat_need_gre vmlinux EXPORT_SYMBOL_GPL
+-0xe58ab676    ip_tunnel_init_net      vmlinux EXPORT_SYMBOL_GPL
+-0x38c6e66b    udp_lib_get_port        vmlinux EXPORT_SYMBOL
+-0x7cda3781    ip_route_input_noref    vmlinux EXPORT_SYMBOL
+-0x207ffd0a    kernel_write    vmlinux EXPORT_SYMBOL
+-0xbbabb724    tty_ldisc_ref   vmlinux EXPORT_SYMBOL_GPL
+-0x899a5d37    rtnl_af_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0x1c7f08a9    snd_soc_dapm_del_routes vmlinux EXPORT_SYMBOL_GPL
+-0xe71105e8    iget_failed     vmlinux EXPORT_SYMBOL
+-0x0fc01e9f    static_key_slow_inc     vmlinux EXPORT_SYMBOL_GPL
+-0xbfee3ad5    loop_unregister_transfer        vmlinux EXPORT_SYMBOL
+-0xaaef0fd2    class_dev_iter_exit     vmlinux EXPORT_SYMBOL_GPL
+-0xd2b18e1d    __of_phy_provider_register      vmlinux EXPORT_SYMBOL_GPL
+-0x1751de15    phy_create      vmlinux EXPORT_SYMBOL_GPL
+-0x25c677c4    mac_pton        vmlinux EXPORT_SYMBOL
+-0xc54cd128    filemap_fdatawait_range vmlinux EXPORT_SYMBOL
+-0x05afc379    mmc_cache_ctrl  vmlinux EXPORT_SYMBOL
+-0x814e4cf8    cfg80211_chandef_usable vmlinux EXPORT_SYMBOL
+-0x829865cd    inode_sub_bytes vmlinux EXPORT_SYMBOL
+-0xec602814    inode_set_bytes vmlinux EXPORT_SYMBOL
+-0x47e70229    v7_flush_user_cache_range       vmlinux EXPORT_SYMBOL
+-0x51cb6360    arp_xmit        vmlinux EXPORT_SYMBOL
+-0xc84ab6f8    __dev_getfirstbyhwtype  vmlinux EXPORT_SYMBOL
+-0xd499d564    __dev_get_by_index      vmlinux EXPORT_SYMBOL
+-0x66a67dab    flex_array_shrink       vmlinux EXPORT_SYMBOL
+-0xd41fe818    _raw_read_unlock_irqrestore     vmlinux EXPORT_SYMBOL
+-0x47fdbc4f    v4l2_ctrl_new_std       vmlinux EXPORT_SYMBOL
+-0xb2fe3cab    mdiobus_register        vmlinux EXPORT_SYMBOL
+-0xf70d473a    __inet6_lookup_established      vmlinux EXPORT_SYMBOL
+-0x8187321e    snd_timer_interrupt     vmlinux EXPORT_SYMBOL
+-0xec5d6a71    __nla_put_nohdr vmlinux EXPORT_SYMBOL
+-0xda5506a3    crypto_unregister_instance      vmlinux EXPORT_SYMBOL_GPL
+-0xfd361609    bdi_init        vmlinux EXPORT_SYMBOL
+-0xf8d88cd8    clk_get vmlinux EXPORT_SYMBOL
+-0x22df2dd3    sdio_claim_host vmlinux EXPORT_SYMBOL_GPL
+-0x40973662    sysctl_udp_mem  vmlinux EXPORT_SYMBOL
+-0x3b50ba06    cpufreq_cooling_register        vmlinux EXPORT_SYMBOL_GPL
+-0xb1c29e91    usbnet_probe    vmlinux EXPORT_SYMBOL_GPL
+-0x5e1176a3    nfc_hci_send_cmd        vmlinux EXPORT_SYMBOL
+-0x1bc8ce1b    inet_csk_accept vmlinux EXPORT_SYMBOL
+-0x35cdd9d0    inet_hash_connect       vmlinux EXPORT_SYMBOL_GPL
+-0x0334da4e    scsi_command_size_tbl   vmlinux EXPORT_SYMBOL
+-0xa843805a    get_unused_fd_flags     vmlinux EXPORT_SYMBOL
+-0xb1e25684    __trace_bputs   vmlinux EXPORT_SYMBOL_GPL
+-0xb58dcfa2    synchronize_sched_expedited     vmlinux EXPORT_SYMBOL_GPL
+-0x17cefda4    cpufreq_cooling_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0xc6fca5ad    v4l2_m2m_release        vmlinux EXPORT_SYMBOL_GPL
+-0x0614dd5a    v4l2_video_std_frame_period     vmlinux EXPORT_SYMBOL
+-0x08195a4e    generic_mii_ioctl       vmlinux EXPORT_SYMBOL
+-0xe64e4a5b    drm_select_eld  vmlinux EXPORT_SYMBOL
+-0xa3b4f14d    bt_accept_dequeue       vmlinux EXPORT_SYMBOL
+-0x8e20620c    tcf_unregister_action   vmlinux EXPORT_SYMBOL
+-0x52026cdf    security_sb_parse_opts_str      vmlinux EXPORT_SYMBOL
+-0xe82c33bd    usb_bulk_msg    vmlinux EXPORT_SYMBOL_GPL
+-0x876abdb2    xfrm_state_delete_tunnel        vmlinux EXPORT_SYMBOL
+-0xfdb4778c    sock_edemux     vmlinux EXPORT_SYMBOL
+-0x4688d7ec    pvclock_gtod_unregister_notifier        vmlinux EXPORT_SYMBOL_GPL
+-0xc6b72634    gserial_connect vmlinux EXPORT_SYMBOL_GPL
+-0x55046eb2    platform_device_add_resources   vmlinux EXPORT_SYMBOL_GPL
+-0x1b25d2b3    of_pwm_xlate_with_flags vmlinux EXPORT_SYMBOL_GPL
+-0x6e1ba077    in6_dev_finish_destroy  vmlinux EXPORT_SYMBOL
+-0xecd68a44    tcp_gro_receive vmlinux EXPORT_SYMBOL
+-0x922e5568    eth_header      vmlinux EXPORT_SYMBOL
+-0xf82ec573    rb_prev vmlinux EXPORT_SYMBOL
+-0xfe2f7b7e    jbd2_journal_init_dev   vmlinux EXPORT_SYMBOL
+-0xd4114894    bd_unlink_disk_holder   vmlinux EXPORT_SYMBOL_GPL
+-0xa9e18049    task_handoff_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x4b5366cf    down_killable   vmlinux EXPORT_SYMBOL
+-0x1129616d    scsi_rescan_device      vmlinux EXPORT_SYMBOL
+-0x9ed554b3    unregister_keyboard_notifier    vmlinux EXPORT_SYMBOL_GPL
+-0x3271e6e4    unregister_framebuffer  vmlinux EXPORT_SYMBOL
+-0x4acb9a7c    napi_gro_receive        vmlinux EXPORT_SYMBOL
+-0x38ed4ee7    netdev_master_upper_dev_get_rcu vmlinux EXPORT_SYMBOL
+-0x5ae87753    debugfs_print_regs32    vmlinux EXPORT_SYMBOL_GPL
+-0xeac5a47a    clk_notifier_register   vmlinux EXPORT_SYMBOL_GPL
+-0xdcc389f7    usb_get_phy     vmlinux EXPORT_SYMBOL_GPL
+-0x5cfbd179    phonet_stream_ops       vmlinux EXPORT_SYMBOL
+-0xd7ea7094    nf_unregister_queue_handler     vmlinux EXPORT_SYMBOL
+-0xa9b804f6    snd_soc_dapm_ignore_suspend     vmlinux EXPORT_SYMBOL_GPL
+-0xb04cf0fe    lg_local_unlock vmlinux EXPORT_SYMBOL
+-0x24eb7e32    leds_list       vmlinux EXPORT_SYMBOL_GPL
+-0xb2f2f502    dev_get_by_flags_rcu    vmlinux EXPORT_SYMBOL
+-0x996bdb64    _kstrtoul       vmlinux EXPORT_SYMBOL
+-0xd6f8cf35    __block_write_begin     vmlinux EXPORT_SYMBOL
+-0x3517383e    register_reboot_notifier        vmlinux EXPORT_SYMBOL
+-0x188a3dfb    timespec_trunc  vmlinux EXPORT_SYMBOL
+-0x7647726c    handle_sysrq    vmlinux EXPORT_SYMBOL
+-0x2a55c54a    l2cap_unregister_user   vmlinux EXPORT_SYMBOL
+-0xdaafc807    tcp_sockets_allocated   vmlinux EXPORT_SYMBOL
+-0x61618241    netlink_alloc_skb       vmlinux EXPORT_SYMBOL_GPL
+-0x883edc99    snd_soc_dapm_weak_routes        vmlinux EXPORT_SYMBOL_GPL
+-0x0b20ad4e    inode_owner_or_capable  vmlinux EXPORT_SYMBOL
+-0x5ddfdc97    generic_pipe_buf_confirm        vmlinux EXPORT_SYMBOL
+-0x27fede28    get_super_thawed        vmlinux EXPORT_SYMBOL
+-0x7ff20102    v4l2_s_ctrl     vmlinux EXPORT_SYMBOL
+-0x9745d638    drm_err vmlinux EXPORT_SYMBOL
+-0x1c1a727a    v4l2_ctrl_subdev_subscribe_event        vmlinux EXPORT_SYMBOL
+-0x157df959    usbnet_tx_timeout       vmlinux EXPORT_SYMBOL_GPL
+-0x33ca0b9d    scsi_device_quiesce     vmlinux EXPORT_SYMBOL
+-0x18a12a47    drm_modeset_unlock_all  vmlinux EXPORT_SYMBOL
+-0x59d29dab    v7_flush_kern_dcache_area       vmlinux EXPORT_SYMBOL
+-0x9ca80cdd    inet6_protos    vmlinux EXPORT_SYMBOL
+-0x58714dc9    snd_soc_jack_add_zones  vmlinux EXPORT_SYMBOL_GPL
+-0xdc9110f5    snd_pcm_hw_param_first  vmlinux EXPORT_SYMBOL
+-0xf184d189    kernel_power_off        vmlinux EXPORT_SYMBOL_GPL
+-0xc8a270a1    usb_put_function        vmlinux EXPORT_SYMBOL_GPL
+-0xdfe8f93c    display_entity_get_size vmlinux EXPORT_SYMBOL_GPL
+-0x0ef959a5    ip6t_unregister_table   vmlinux EXPORT_SYMBOL
+-0x5ee28af3    genl_register_ops       vmlinux EXPORT_SYMBOL
+-0xda91a719    snd_pcm_new     vmlinux EXPORT_SYMBOL
+-0x8731837f    debugfs_create_u64      vmlinux EXPORT_SYMBOL_GPL
+-0x0d350531    block_commit_write      vmlinux EXPORT_SYMBOL
+-0xcb62227b    con_copy_unimap vmlinux EXPORT_SYMBOL
+-0x9b90584e    tty_ldisc_ref_wait      vmlinux EXPORT_SYMBOL_GPL
+-0xf727c5be    __netdev_alloc_skb      vmlinux EXPORT_SYMBOL
+-0xf186dfad    wm_hubs_set_bias_level  vmlinux EXPORT_SYMBOL_GPL
+-0x5bc4fef5    snd_soc_get_dai_substream       vmlinux EXPORT_SYMBOL_GPL
+-0xabefee2b    _snd_pcm_lib_alloc_vmalloc_buffer       vmlinux EXPORT_SYMBOL
+-0x5a116367    perf_event_create_kernel_counter        vmlinux EXPORT_SYMBOL_GPL
+-0x0bfa3a19    rcu_idle_exit   vmlinux EXPORT_SYMBOL_GPL
+-0x90ff6c9f    nf_ct_invert_tuplepr    vmlinux EXPORT_SYMBOL_GPL
+-0xf3cd9688    snd_soc_dapm_sync       vmlinux EXPORT_SYMBOL_GPL
+-0x68fb4f69    locks_delete_block      vmlinux EXPORT_SYMBOL
+-0xdca2a7bb    dput    vmlinux EXPORT_SYMBOL
+-0x67a000fa    try_module_get  vmlinux EXPORT_SYMBOL
+-0x4790cc27    v4l2_s_ext_ctrls        vmlinux EXPORT_SYMBOL
+-0xf39c1176    tty_kref_put    vmlinux EXPORT_SYMBOL
+-0x56310925    regulator_mode_to_status        vmlinux EXPORT_SYMBOL_GPL
+-0x0825a4fe    regulator_list_voltage_linear   vmlinux EXPORT_SYMBOL_GPL
+-0x43db92ba    fb_set_suspend  vmlinux EXPORT_SYMBOL
+-0x4993cc2b    register_net_sysctl     vmlinux EXPORT_SYMBOL_GPL
+-0x8a490c90    rfkill_set_sw_state     vmlinux EXPORT_SYMBOL
+-0xaae97496    snd_soc_bulk_write_raw  vmlinux EXPORT_SYMBOL_GPL
+-0xb4dd257b    srcu_notifier_call_chain        vmlinux EXPORT_SYMBOL_GPL
+-0x4403ead3    usb_match_one_id        vmlinux EXPORT_SYMBOL_GPL
+-0x829a0b6c    screen_glyph    vmlinux EXPORT_SYMBOL_GPL
+-0xf7802486    __aeabi_uidivmod        vmlinux EXPORT_SYMBOL
+-0x4b8f110e    sk_free vmlinux EXPORT_SYMBOL
+-0x4fbbaedb    snd_soc_free_ac97_codec vmlinux EXPORT_SYMBOL_GPL
+-0xfd5566cf    scsi_is_sdev_device     vmlinux EXPORT_SYMBOL
+-0x17dc8b68    drm_vblank_pre_modeset  vmlinux EXPORT_SYMBOL
+-0x7ef39823    ieee80211_hdrlen        vmlinux EXPORT_SYMBOL
+-0xc8f36b20    kobject_init    vmlinux EXPORT_SYMBOL
+-0xb2e764e8    suspend_valid_only_mem  vmlinux EXPORT_SYMBOL_GPL
+-0xfaf9995e    sleep_on        vmlinux EXPORT_SYMBOL
+-0x42160169    flush_workqueue vmlinux EXPORT_SYMBOL_GPL
+-0xf3251e7b    v4l2_norm_to_name       vmlinux EXPORT_SYMBOL
+-0xd7b664df    regulator_list_voltage_table    vmlinux EXPORT_SYMBOL_GPL
+-0xfe13b82a    snd_soc_info_enum_ext   vmlinux EXPORT_SYMBOL_GPL
+-0x22a8b63d    bio_flush_dcache_pages  vmlinux EXPORT_SYMBOL
+-0x0c3d1edb    simple_lookup   vmlinux EXPORT_SYMBOL
+-0x4cbc159a    gether_set_dev_addr     vmlinux EXPORT_SYMBOL
+-0xdac8e102    gether_get_dev_addr     vmlinux EXPORT_SYMBOL
+-0xfa599bb2    netlink_register_notifier       vmlinux EXPORT_SYMBOL
+-0xb7e5c788    cgroup_next_descendant_post     vmlinux EXPORT_SYMBOL_GPL
+-0xd7dc295c    dm_io   vmlinux EXPORT_SYMBOL
+-0xb8698990    usb_match_id    vmlinux EXPORT_SYMBOL_GPL
+-0x91a5dbd2    drm_idlelock_take       vmlinux EXPORT_SYMBOL
+-0xba86f941    xfrm_policy_insert      vmlinux EXPORT_SYMBOL
+-0x2519a629    skb_segment     vmlinux EXPORT_SYMBOL_GPL
+-0x2f574814    blk_queue_max_segments  vmlinux EXPORT_SYMBOL
+-0xa17232f2    bio_clone_bioset        vmlinux EXPORT_SYMBOL
+-0xba2bc8de    unlock_rename   vmlinux EXPORT_SYMBOL
+-0x9820b644    warn_slowpath_fmt_taint vmlinux EXPORT_SYMBOL
+-0x184b82fb    mmc_vddrange_to_ocrmask vmlinux EXPORT_SYMBOL
+-0x0a67ddd9    dm_suspended    vmlinux EXPORT_SYMBOL_GPL
+-0xfc8bcbaf    usb_add_hcd     vmlinux EXPORT_SYMBOL_GPL
+-0x965d4e18    tcp_init_congestion_ops vmlinux EXPORT_SYMBOL_GPL
+-0xe587559a    skb_push        vmlinux EXPORT_SYMBOL
+-0x1a32c5c7    blk_run_queue_async     vmlinux EXPORT_SYMBOL
+-0x7fa439cd    simple_rmdir    vmlinux EXPORT_SYMBOL
+-0xe6790d49    alloc_file      vmlinux EXPORT_SYMBOL
+-0xe8214f7a    free_task       vmlinux EXPORT_SYMBOL
+-0x2b9e3380    samsung_dmadev_get_ops  vmlinux EXPORT_SYMBOL
+-0x8e671fe0    sdio_f0_writeb  vmlinux EXPORT_SYMBOL_GPL
+-0x919b5fa4    device_create   vmlinux EXPORT_SYMBOL_GPL
+-0x5cf4fc85    psched_ratecfg_precompute       vmlinux EXPORT_SYMBOL
+-0x96573b80    __kfifo_dma_in_finish_r vmlinux EXPORT_SYMBOL
+-0xf520f285    sysfs_get       vmlinux EXPORT_SYMBOL_GPL
+-0x543ef284    seq_hlist_start vmlinux EXPORT_SYMBOL
+-0xbfffc4e0    vb2_read        vmlinux EXPORT_SYMBOL_GPL
+-0x45f39483    i2c_del_adapter vmlinux EXPORT_SYMBOL
+-0x5838f6c9    rtc_valid_tm    vmlinux EXPORT_SYMBOL
+-0xb7a638f3    usb_register_driver     vmlinux EXPORT_SYMBOL_GPL
+-0xb83a9297    scsi_block_requests     vmlinux EXPORT_SYMBOL
+-0xd5d8b6b8    drm_dp_get_adjust_request_pre_emphasis  vmlinux EXPORT_SYMBOL
+-0x99c95fa5    unregister_sound_special        vmlinux EXPORT_SYMBOL
+-0x056b6c53    fat_dir_empty   vmlinux EXPORT_SYMBOL_GPL
+-0xb51c8891    __getblk        vmlinux EXPORT_SYMBOL
+-0x1d9658d5    cdev_alloc      vmlinux EXPORT_SYMBOL
+-0x1dd73224    st_sensors_i2c_configure        vmlinux EXPORT_SYMBOL
+-0x22379ca8    led_blink_set_oneshot   vmlinux EXPORT_SYMBOL
+-0xe7e76d97    mmc_release_host        vmlinux EXPORT_SYMBOL
+-0x6e04a077    usb_bind_phy    vmlinux EXPORT_SYMBOL_GPL
+-0x47d9cfba    sdev_disable_disk_events        vmlinux EXPORT_SYMBOL
+-0x142b8b35    drm_buffer_copy_from_user       vmlinux EXPORT_SYMBOL
+-0x55f04c21    trace_buffer_unlock_commit_regs vmlinux EXPORT_SYMBOL_GPL
+-0x8c333b2b    usb_hcd_unlink_urb_from_ep      vmlinux EXPORT_SYMBOL_GPL
+-0x1fa2251f    device_wakeup_enable    vmlinux EXPORT_SYMBOL_GPL
+-0xbbe4496d    dev_warn        vmlinux EXPORT_SYMBOL
+-0xab3d1f95    nf_ct_untracked_status_or       vmlinux EXPORT_SYMBOL_GPL
+-0x131c2452    snd_jack_set_key        vmlinux EXPORT_SYMBOL
+-0x74c134b9    __sw_hweight32  vmlinux EXPORT_SYMBOL
+-0x57674fd7    __sw_hweight16  vmlinux EXPORT_SYMBOL
+-0x9f46ced8    __sw_hweight64  vmlinux EXPORT_SYMBOL
+-0x93215e1d    __kfifo_skip_r  vmlinux EXPORT_SYMBOL
+-0x1ec4eb34    flex_array_prealloc     vmlinux EXPORT_SYMBOL
+-0x01e6b7fa    get_phy_device  vmlinux EXPORT_SYMBOL
+-0x391c17d1    wakeup_source_register  vmlinux EXPORT_SYMBOL_GPL
+-0xfe85236b    cpu_user        vmlinux EXPORT_SYMBOL
+-0x35e62033    pagevec_lookup_tag      vmlinux EXPORT_SYMBOL
+-0x34184afe    current_kernel_time     vmlinux EXPORT_SYMBOL
+-0x0eb2ceba    tcp_reno_cong_avoid     vmlinux EXPORT_SYMBOL_GPL
+-0x2fce25e3    print_tuple     vmlinux EXPORT_SYMBOL_GPL
+-0x62496fbf    snd_soc_dai_set_clkdiv  vmlinux EXPORT_SYMBOL_GPL
+-0x7505bdef    memchr_inv      vmlinux EXPORT_SYMBOL
+-0x3b21bfec    locks_copy_lock vmlinux EXPORT_SYMBOL
+-0xb47a0298    hid_dump_report vmlinux EXPORT_SYMBOL_GPL
+-0x391147d1    led_trigger_blink       vmlinux EXPORT_SYMBOL_GPL
+-0xb65a6bb8    usb_reset_device        vmlinux EXPORT_SYMBOL_GPL
+-0x007b6ccf    gnet_stats_start_copy_compat    vmlinux EXPORT_SYMBOL
+-0x7522f3ba    irq_modify_status       vmlinux EXPORT_SYMBOL_GPL
+-0xd9052a07    rtc_alarm_irq_enable    vmlinux EXPORT_SYMBOL_GPL
+-0xcb6dc422    usb_add_config_only     vmlinux EXPORT_SYMBOL_GPL
+-0xd38b2d79    inet6_del_protocol      vmlinux EXPORT_SYMBOL
+-0x98b8ddd3    xfrm_input_resume       vmlinux EXPORT_SYMBOL
+-0xf71914b4    udplite_prot    vmlinux EXPORT_SYMBOL
+-0xdc48464a    sock_create_kern        vmlinux EXPORT_SYMBOL
+-0x8260686f    bitmap_find_next_zero_area      vmlinux EXPORT_SYMBOL
+-0x354ac8ad    scsi_eh_restore_cmnd    vmlinux EXPORT_SYMBOL
+-0x6f988f59    transport_remove_device vmlinux EXPORT_SYMBOL_GPL
+-0x600f8836    drm_class_device_register       vmlinux EXPORT_SYMBOL_GPL
+-0xd589c1c3    sk_clone_lock   vmlinux EXPORT_SYMBOL_GPL
+-0xf8798032    d_find_any_alias        vmlinux EXPORT_SYMBOL
+-0x56e4cd15    ftrace_event_reg        vmlinux EXPORT_SYMBOL_GPL
+-0xab29d75c    thermal_zone_get_zone_by_name   vmlinux EXPORT_SYMBOL_GPL
+-0x2a678a13    __suspend_report_result vmlinux EXPORT_SYMBOL_GPL
+-0xe36d12fc    drm_gtf_mode    vmlinux EXPORT_SYMBOL
+-0x5a48534a    regulator_count_voltages        vmlinux EXPORT_SYMBOL_GPL
+-0x2edb3fd8    sk_attach_filter        vmlinux EXPORT_SYMBOL_GPL
+-0x8d107d70    sk_detach_filter        vmlinux EXPORT_SYMBOL_GPL
+-0x5da176fe    snd_timer_open  vmlinux EXPORT_SYMBOL
+-0xf741c793    zlib_deflateEnd vmlinux EXPORT_SYMBOL
+-0x7469fcfe    radix_tree_tagged       vmlinux EXPORT_SYMBOL
+-0x57c405a5    unload_nls      vmlinux EXPORT_SYMBOL
+-0xcaa97c6a    seq_open_private        vmlinux EXPORT_SYMBOL
+-0xf3d2b805    st_sensors_get_buffer_element   vmlinux EXPORT_SYMBOL
+-0x82286526    vb2_ioctl_create_bufs   vmlinux EXPORT_SYMBOL_GPL
+-0xfb7d95b7    fb_set_cmap     vmlinux EXPORT_SYMBOL
+-0xed46d9ec    kernel_listen   vmlinux EXPORT_SYMBOL
+-0xb1b16346    snd_jack_set_parent     vmlinux EXPORT_SYMBOL
+-0x76bf656d    __bitmap_shift_left     vmlinux EXPORT_SYMBOL
+-0x1979065a    serio_unregister_driver vmlinux EXPORT_SYMBOL
+-0x3a94c8e6    drm_modeset_lock_all    vmlinux EXPORT_SYMBOL
+-0xa093e7da    nat_rtp_rtcp_hook       vmlinux EXPORT_SYMBOL_GPL
+-0xe23ae481    blk_iopoll_complete     vmlinux EXPORT_SYMBOL
+-0x4f6172ff    crypto_chain    vmlinux EXPORT_SYMBOL_GPL
+-0xd66a562b    __scsi_device_lookup    vmlinux EXPORT_SYMBOL
+-0x9d669763    memcpy  vmlinux EXPORT_SYMBOL
+-0x15c5eea4    ip6t_do_table   vmlinux EXPORT_SYMBOL
+-0x6b6533af    bdevname        vmlinux EXPORT_SYMBOL
+-0x65d67a20    blk_start_plug  vmlinux EXPORT_SYMBOL
+-0xdd686f05    cdev_init       vmlinux EXPORT_SYMBOL
+-0xbe63ee40    request_resource        vmlinux EXPORT_SYMBOL
+-0xb2018900    inet_getname    vmlinux EXPORT_SYMBOL
+-0x01610153    nf_ct_expect_init       vmlinux EXPORT_SYMBOL_GPL
+-0x04e1b99f    snd_pcm_std_chmaps      vmlinux EXPORT_SYMBOL_GPL
+-0x24a42b51    snd_unregister_oss_device       vmlinux EXPORT_SYMBOL
+-0x85e7deb2    iov_iter_fault_in_readable      vmlinux EXPORT_SYMBOL
+-0x8f049b6c    module_mutex    vmlinux EXPORT_SYMBOL_GPL
+-0x931b242d    regcache_sync   vmlinux EXPORT_SYMBOL_GPL
+-0xb95f98d6    _memset_io      vmlinux EXPORT_SYMBOL
+-0xa98e796e    modify_user_hw_breakpoint       vmlinux EXPORT_SYMBOL_GPL
+-0xbf9bcc8d    __cap_empty_set vmlinux EXPORT_SYMBOL
+-0xfba8bb33    dm_get_mapinfo  vmlinux EXPORT_SYMBOL
+-0x988ad2a2    rndis_set_param_vendor  vmlinux EXPORT_SYMBOL
+-0xb67d6992    usb_ep_autoconfig_reset vmlinux EXPORT_SYMBOL_GPL
+-0xfbe5910d    drm_mode_config_init    vmlinux EXPORT_SYMBOL
+-0x6443df4e    videomode_from_timings  vmlinux EXPORT_SYMBOL_GPL
+-0xad059f21    ip_tunnel_changelink    vmlinux EXPORT_SYMBOL_GPL
+-0x2c7fb2d0    crypto_shoot_alg        vmlinux EXPORT_SYMBOL_GPL
+-0xac226765    iput    vmlinux EXPORT_SYMBOL
+-0x77fe4cb2    sleep_on_timeout        vmlinux EXPORT_SYMBOL
+-0x1d88a23f    platform_get_resource   vmlinux EXPORT_SYMBOL_GPL
+-0xb95beb55    drm_object_property_set_value   vmlinux EXPORT_SYMBOL
+-0x8481713b    pn_sock_unhash  vmlinux EXPORT_SYMBOL
+-0x28a82da4    snmp_mib_init   vmlinux EXPORT_SYMBOL_GPL
+-0x03fd2571    vm_unmap_ram    vmlinux EXPORT_SYMBOL
+-0x65466939    proc_doulongvec_ms_jiffies_minmax       vmlinux EXPORT_SYMBOL
+-0x23654452    input_ff_upload vmlinux EXPORT_SYMBOL_GPL
+-0x45bda0d5    system_serial_low       vmlinux EXPORT_SYMBOL
+-0xa682a886    xfrm_output     vmlinux EXPORT_SYMBOL_GPL
+-0xeea9dbaf    bitmap_bitremap vmlinux EXPORT_SYMBOL
+-0x71a50dbc    register_blkdev vmlinux EXPORT_SYMBOL
+-0x43c0e15b    fuse_sync_release       vmlinux EXPORT_SYMBOL_GPL
+-0x972213d1    of_phy_connect  vmlinux EXPORT_SYMBOL
+-0x95390328    __fimc_vidioc_querycap  vmlinux EXPORT_SYMBOL
+-0xe453b342    ipv6_select_ident       vmlinux EXPORT_SYMBOL
+-0xabca477d    nf_conntrack_alter_reply        vmlinux EXPORT_SYMBOL_GPL
+-0x72c09e90    neigh_event_ns  vmlinux EXPORT_SYMBOL
+-0x32590631    snd_soc_update_bits     vmlinux EXPORT_SYMBOL_GPL
+-0xb96df73b    elevator_change vmlinux EXPORT_SYMBOL
+-0xa30a6f34    jbd2_journal_blocks_per_page    vmlinux EXPORT_SYMBOL
+-0x6103b2f2    iterate_supers_type     vmlinux EXPORT_SYMBOL
+-0x0a311e2a    iio_read_channel_processed      vmlinux EXPORT_SYMBOL_GPL
+-0x89953a68    sdhci_free_host vmlinux EXPORT_SYMBOL_GPL
+-0xb8de0d37    dpm_for_each_dev        vmlinux EXPORT_SYMBOL_GPL
+-0xe35ba70f    drm_prime_destroy_file_private  vmlinux EXPORT_SYMBOL
+-0x1cb4683d    drm_framebuffer_lookup  vmlinux EXPORT_SYMBOL
+-0xbaa9e7e0    fb_firmware_edid        vmlinux EXPORT_SYMBOL
+-0xa2ede8b2    nf_queue_entry_get_refs vmlinux EXPORT_SYMBOL_GPL
+-0x0ff98044    jump_label_rate_limit   vmlinux EXPORT_SYMBOL_GPL
+-0x3fd9109b    v4l2_ctrl_subdev_log_status     vmlinux EXPORT_SYMBOL
+-0x78cf4589    usb_kill_anchored_urbs  vmlinux EXPORT_SYMBOL_GPL
+-0x3b79aef9    request_firmware_nowait vmlinux EXPORT_SYMBOL
+-0xab160376    create_syslog_header    vmlinux EXPORT_SYMBOL
+-0x6d42bb18    drm_gem_handle_delete   vmlinux EXPORT_SYMBOL
+-0x366d19ef    genericbl_limit_intensity       vmlinux EXPORT_SYMBOL
+-0x7380780d    cfg80211_unlink_bss     vmlinux EXPORT_SYMBOL
+-0xff6b7f32    netdev_change_features  vmlinux EXPORT_SYMBOL
+-0x5613414a    init_dummy_netdev       vmlinux EXPORT_SYMBOL_GPL
+-0xbd5cb8b9    ring_buffer_resize      vmlinux EXPORT_SYMBOL_GPL
+-0xa55e517c    ip_tunnel_xmit  vmlinux EXPORT_SYMBOL_GPL
+-0x3b870a79    dst_destroy     vmlinux EXPORT_SYMBOL
+-0xad6b883a    usbnet_get_drvinfo      vmlinux EXPORT_SYMBOL_GPL
+-0x5df7a89b    nf_ct_helper_expectfn_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0x275ef902    __init_waitqueue_head   vmlinux EXPORT_SYMBOL
+-0x472b2841    devm_usb_get_phy        vmlinux EXPORT_SYMBOL_GPL
+-0x790d8481    scsi_mode_sense vmlinux EXPORT_SYMBOL
+-0x2d89342a    scsi_show_sense_hdr     vmlinux EXPORT_SYMBOL
+-0xda7ca6cb    fb_mode_is_equal        vmlinux EXPORT_SYMBOL
+-0xdc4798d2    xfrm6_tunnel_register   vmlinux EXPORT_SYMBOL
+-0xd587e7b5    xfrm4_tunnel_register   vmlinux EXPORT_SYMBOL
+-0x360b01a3    nf_ct_get_tuple vmlinux EXPORT_SYMBOL_GPL
+-0x6c74c2ee    blk_insert_cloned_request       vmlinux EXPORT_SYMBOL_GPL
+-0x46cb2731    security_sb_set_mnt_opts        vmlinux EXPORT_SYMBOL
+-0x1b995ffb    iommu_domain_window_enable      vmlinux EXPORT_SYMBOL_GPL
+-0xa4ea04ee    of_property_read_u64    vmlinux EXPORT_SYMBOL_GPL
+-0x411e4ef5    brcmu_pktq_pdeq_tail    drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x422d82d0    brcmu_pktq_penq_head    drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x41cc94d0    brcmu_pktq_peek_tail    drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x0c6f118f    nf_nat_icmpv6_reply_translation vmlinux EXPORT_SYMBOL_GPL
+-0xa07842c6    skb_copy_datagram_from_iovec    vmlinux EXPORT_SYMBOL
+-0xc8269f94    snd_soc_params_to_frame_size    vmlinux EXPORT_SYMBOL_GPL
+-0x43eeb6cf    snd_pcm_lib_ioctl       vmlinux EXPORT_SYMBOL
+-0x9ac11b74    suspend_set_ops vmlinux EXPORT_SYMBOL_GPL
+-0xca16dbe7    regulator_enable        vmlinux EXPORT_SYMBOL_GPL
+-0xecc84eb2    dst_alloc       vmlinux EXPORT_SYMBOL
+-0xf0f5dbc2    timerqueue_iterate_next vmlinux EXPORT_SYMBOL_GPL
+-0xab4a5add    blk_put_queue   vmlinux EXPORT_SYMBOL
+-0x11bef8bd    single_release  vmlinux EXPORT_SYMBOL
+-0x7aad72c6    get_user_pages  vmlinux EXPORT_SYMBOL
+-0x6214aef2    cpufreq_unregister_notifier     vmlinux EXPORT_SYMBOL
+-0xe93e49c3    devres_free     vmlinux EXPORT_SYMBOL_GPL
+-0xd95fbe77    of_find_backlight_by_node       vmlinux EXPORT_SYMBOL
+-0xe3f553d9    ip6_append_data vmlinux EXPORT_SYMBOL_GPL
+-0xa108eb4d    sysctl_optmem_max       vmlinux EXPORT_SYMBOL
+-0xdc323ca6    jbd2_journal_destroy    vmlinux EXPORT_SYMBOL
+-0x3c7a1672    jbd2_journal_restart    vmlinux EXPORT_SYMBOL
+-0x9805d460    v4l2_device_register    vmlinux EXPORT_SYMBOL_GPL
+-0x1db6d990    display_entity_get_first        vmlinux EXPORT_SYMBOL
+-0xe57878a1    in6_pton        vmlinux EXPORT_SYMBOL
+-0xaccabc6a    in4_pton        vmlinux EXPORT_SYMBOL
+-0xd0181f4f    __bitmap_xor    vmlinux EXPORT_SYMBOL
+-0x208c317e    mnt_want_write  vmlinux EXPORT_SYMBOL_GPL
+-0xbcdedba7    of_get_mac_address      vmlinux EXPORT_SYMBOL
+-0x859bbb79    scsi_mode_select        vmlinux EXPORT_SYMBOL_GPL
+-0x48991892    cfb_copyarea    vmlinux EXPORT_SYMBOL
+-0x2455c156    __clear_user    vmlinux EXPORT_SYMBOL
+-0x42c7d35b    __dev_remove_pack       vmlinux EXPORT_SYMBOL
+-0x465cab34    secure_ipv6_port_ephemeral      vmlinux EXPORT_SYMBOL
+-0x5ddbac94    config_group_init       vmlinux EXPORT_SYMBOL
+-0x773c1fdc    posix_acl_to_xattr      vmlinux EXPORT_SYMBOL
+-0xb18429eb    suspend_device_irqs     vmlinux EXPORT_SYMBOL_GPL
+-0x50c52151    _raw_write_unlock_irq   vmlinux EXPORT_SYMBOL
+-0xf5bc65a3    iommu_unmap     vmlinux EXPORT_SYMBOL_GPL
+-0x710e2b07    tcf_hash_insert vmlinux EXPORT_SYMBOL
+-0xf13feb57    radix_tree_next_chunk   vmlinux EXPORT_SYMBOL
+-0x90a1004a    crypto_has_alg  vmlinux EXPORT_SYMBOL_GPL
+-0x8cd44e50    iget5_locked    vmlinux EXPORT_SYMBOL
+-0x3dcb88a0    irq_set_handler_data    vmlinux EXPORT_SYMBOL
+-0xaa7de358    yield_to        vmlinux EXPORT_SYMBOL_GPL
+-0xc54649ff    __starget_for_each_device       vmlinux EXPORT_SYMBOL
+-0x2bd1f745    drm_mode_config_cleanup vmlinux EXPORT_SYMBOL
+-0xa1425906    ieee80211_channel_to_frequency  vmlinux EXPORT_SYMBOL
+-0x59806cb9    sk_page_frag_refill     vmlinux EXPORT_SYMBOL
+-0xce90ef6b    debugfs_create_dir      vmlinux EXPORT_SYMBOL_GPL
+-0xa4827144    dcache_dir_lseek        vmlinux EXPORT_SYMBOL
+-0x0c2cdbf1    synchronize_sched       vmlinux EXPORT_SYMBOL_GPL
+-0x92a9c60c    time_to_tm      vmlinux EXPORT_SYMBOL
+-0x651a4139    test_taint      vmlinux EXPORT_SYMBOL
+-0x2b66e1b8    mii_check_media vmlinux EXPORT_SYMBOL
+-0xfb7d9c45    __udivsi3       vmlinux EXPORT_SYMBOL
+-0x633fafc5    netdev_printk   vmlinux EXPORT_SYMBOL
+-0xf5a691cd    invalidate_bh_lrus      vmlinux EXPORT_SYMBOL_GPL
+-0xe5524eab    of_address_to_resource  vmlinux EXPORT_SYMBOL_GPL
+-0xe22f01b0    thermal_zone_device_register    vmlinux EXPORT_SYMBOL_GPL
+-0x3fc8bae1    ipcomp_init_state       vmlinux EXPORT_SYMBOL_GPL
+-0xf5b5f1ec    xt_check_match  vmlinux EXPORT_SYMBOL_GPL
+-0x24aac4d9    crypto_aes_expand_key   vmlinux EXPORT_SYMBOL_GPL
+-0x6f798a9c    d_splice_alias  vmlinux EXPORT_SYMBOL
+-0x88196936    do_sync_read    vmlinux EXPORT_SYMBOL
+-0x4a18707e    mem_map vmlinux EXPORT_SYMBOL
+-0x0366307a    console_suspend_enabled vmlinux EXPORT_SYMBOL
+-0x204d506e    st_sensors_write_event_value    vmlinux EXPORT_SYMBOL
+-0x4c22a54d    usb_ep_autoconfig       vmlinux EXPORT_SYMBOL_GPL
+-0x32c3cb4e    class_compat_register   vmlinux EXPORT_SYMBOL_GPL
+-0x7b85f6f8    drm_mm_insert_node      vmlinux EXPORT_SYMBOL
+-0x78f9b710    nf_ct_l3proto_try_module_get    vmlinux EXPORT_SYMBOL_GPL
+-0x44594236    snd_soc_unregister_component    vmlinux EXPORT_SYMBOL_GPL
+-0x05e4e6be    register_sound_midi     vmlinux EXPORT_SYMBOL
+-0x07341a03    kobject_rename  vmlinux EXPORT_SYMBOL_GPL
+-0x35b6b772    param_ops_charp vmlinux EXPORT_SYMBOL
+-0xb4c1829e    clk_round_rate  vmlinux EXPORT_SYMBOL_GPL
+-0x1bb061cc    sdio_release_irq        vmlinux EXPORT_SYMBOL_GPL
+-0xe4c673df    mmc_wait_for_cmd        vmlinux EXPORT_SYMBOL
+-0x4d088d1f    drm_mm_replace_node     vmlinux EXPORT_SYMBOL
+-0xe24e09b0    cgroup_taskset_cur_cgroup       vmlinux EXPORT_SYMBOL_GPL
+-0x7c5cf140    cad_pid vmlinux EXPORT_SYMBOL
+-0xaea8b9a5    drm_get_encoder_name    vmlinux EXPORT_SYMBOL
+-0xe4c80097    cacheid vmlinux EXPORT_SYMBOL
+-0x5a5a94a6    kstrtou8        vmlinux EXPORT_SYMBOL
+-0x2b4aa9c9    get_task_pid    vmlinux EXPORT_SYMBOL_GPL
+-0x30f43c3b    sdhci_enable_irq_wakeups        vmlinux EXPORT_SYMBOL_GPL
+-0x3a6d4f22    rndis_free_response     vmlinux EXPORT_SYMBOL
+-0x85478a0b    inet6_hash_frag vmlinux EXPORT_SYMBOL_GPL
+-0x0efbc42d    snd_component_add       vmlinux EXPORT_SYMBOL
+-0x6605f97f    flex_array_clear        vmlinux EXPORT_SYMBOL
+-0x5a7bfe41    crypto_probing_notify   vmlinux EXPORT_SYMBOL_GPL
+-0x94fd7214    serial8250_rx_chars     vmlinux EXPORT_SYMBOL_GPL
+-0x13a6027a    ip6t_alloc_initial_table        vmlinux EXPORT_SYMBOL_GPL
+-0x03a9a7bd    netif_receive_skb       vmlinux EXPORT_SYMBOL
+-0xfb6af58d    recalc_sigpending       vmlinux EXPORT_SYMBOL
+-0x2d0ea593    spi_new_device  vmlinux EXPORT_SYMBOL_GPL
+-0xfbc4e14c    pm_runtime_enable       vmlinux EXPORT_SYMBOL_GPL
+-0xc583bf57    of_regulator_match      vmlinux EXPORT_SYMBOL_GPL
+-0xebfdcbdf    system_serial_high      vmlinux EXPORT_SYMBOL
+-0x28d7fc1f    nf_nat_mangle_udp_packet        vmlinux EXPORT_SYMBOL
+-0xf71016b7    snd_soc_dapm_get_pin_status     vmlinux EXPORT_SYMBOL_GPL
+-0xf05c8ab1    vb2_get_contig_userptr  vmlinux EXPORT_SYMBOL_GPL
+-0xd045db89    nfc_class       vmlinux EXPORT_SYMBOL
+-0x606340d3    disk_part_iter_exit     vmlinux EXPORT_SYMBOL_GPL
+-0xa1bd7822    __tracepoint_block_bio_complete vmlinux EXPORT_SYMBOL_GPL
+-0x16138f6f    follow_down_one vmlinux EXPORT_SYMBOL
+-0x7944e0fc    tracing_off     vmlinux EXPORT_SYMBOL_GPL
+-0xb1425b32    dm_table_add_target_callbacks   vmlinux EXPORT_SYMBOL_GPL
+-0xbdfb8830    anon_transport_class_register   vmlinux EXPORT_SYMBOL_GPL
+-0x911d700e    devm_phy_create vmlinux EXPORT_SYMBOL_GPL
+-0xeb908d00    raw_seq_next    vmlinux EXPORT_SYMBOL_GPL
+-0x30b265dd    ip_setsockopt   vmlinux EXPORT_SYMBOL
+-0x9f45de2c    ip_getsockopt   vmlinux EXPORT_SYMBOL
+-0x30322337    nf_ct_l3proto_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0x8106c2de    nf_ct_l4proto_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0x4b015768    snd_iprintf     vmlinux EXPORT_SYMBOL
+-0xec728ca6    blk_unprep_request      vmlinux EXPORT_SYMBOL_GPL
+-0x0bae62b1    ktime_get_monotonic_offset      vmlinux EXPORT_SYMBOL_GPL
+-0x6f8450af    tty_encode_baud_rate    vmlinux EXPORT_SYMBOL_GPL
+-0xead6a706    devm_phy_destroy        vmlinux EXPORT_SYMBOL_GPL
+-0x2cf3c356    ip6_redirect    vmlinux EXPORT_SYMBOL_GPL
+-0x2cdb55d1    ip_options_rcv_srr      vmlinux EXPORT_SYMBOL
+-0x105bdf9b    dentry_open     vmlinux EXPORT_SYMBOL
+-0x724bf4b2    i2c_bit_add_numbered_bus        vmlinux EXPORT_SYMBOL
+-0x2e09263f    usb_copy_descriptors    vmlinux EXPORT_SYMBOL_GPL
+-0xbec98305    device_register vmlinux EXPORT_SYMBOL_GPL
+-0xff519474    skb_checksum_help       vmlinux EXPORT_SYMBOL
+-0x293d87a4    unregister_netdevice_queue      vmlinux EXPORT_SYMBOL
+-0xa692560a    snd_soc_lookup_platform vmlinux EXPORT_SYMBOL_GPL
+-0x9545af6d    tasklet_init    vmlinux EXPORT_SYMBOL
+-0x87374f66    extcon_unregister_interest      vmlinux EXPORT_SYMBOL_GPL
+-0x40a27c37    scsi_dev_info_remove_list       vmlinux EXPORT_SYMBOL
+-0x42a2164f    regmap_write    vmlinux EXPORT_SYMBOL_GPL
+-0xe6f46e6e    drm_clflush_virt_range  vmlinux EXPORT_SYMBOL
+-0x17f8217b    nf_nat_setup_info       vmlinux EXPORT_SYMBOL
+-0xb3daf4bf    jbd2_journal_get_undo_access    vmlinux EXPORT_SYMBOL
+-0xe16591ab    stop_machine    vmlinux EXPORT_SYMBOL_GPL
+-0xb6261484    register_die_notifier   vmlinux EXPORT_SYMBOL_GPL
+-0x415838be    led_trigger_set_default vmlinux EXPORT_SYMBOL_GPL
+-0x843020c0    ip6_find_1stfragopt     vmlinux EXPORT_SYMBOL
+-0x062936ed    nf_ct_unlink_expect_report      vmlinux EXPORT_SYMBOL_GPL
+-0xa6d16c61    sock_no_recvmsg vmlinux EXPORT_SYMBOL
+-0x4b0ac955    hrtimer_cancel  vmlinux EXPORT_SYMBOL_GPL
+-0x3626ebf4    xt_unregister_matches   vmlinux EXPORT_SYMBOL
+-0x72ea7812    security_inode_setattr  vmlinux EXPORT_SYMBOL_GPL
+-0xfdfc0b3b    fiemap_fill_next_extent vmlinux EXPORT_SYMBOL
+-0x82d19daa    qdisc_watchdog_cancel   vmlinux EXPORT_SYMBOL
+-0xc0581ee5    crypto_shash_digest     vmlinux EXPORT_SYMBOL_GPL
+-0x78728b6b    crypto_ahash_digest     vmlinux EXPORT_SYMBOL_GPL
+-0x3de9cae1    crypto_remove_final     vmlinux EXPORT_SYMBOL_GPL
+-0x31faa864    media_entity_init       vmlinux EXPORT_SYMBOL_GPL
+-0xe827112b    rtnl_set_sk_err vmlinux EXPORT_SYMBOL
+-0x5b23591f    snd_soc_jack_new        vmlinux EXPORT_SYMBOL_GPL
+-0x7b6646bb    _raw_read_lock  vmlinux EXPORT_SYMBOL
+-0xd4669fad    complete        vmlinux EXPORT_SYMBOL
+-0x488882e7    downgrade_write vmlinux EXPORT_SYMBOL
+-0xbaac427c    get_mem_type    vmlinux EXPORT_SYMBOL
+-0xc4014b9d    ip_check_defrag vmlinux EXPORT_SYMBOL
+-0x6aaccee0    config_item_init_type_name      vmlinux EXPORT_SYMBOL
+-0x62822d05    iov_iter_single_seg_count       vmlinux EXPORT_SYMBOL
+-0xb1f1a6ea    gether_get_host_addr_u8 vmlinux EXPORT_SYMBOL
+-0xf7f652fe    dma_mmap_from_coherent  vmlinux EXPORT_SYMBOL
+-0xfa9720a0    rdev_get_dev    vmlinux EXPORT_SYMBOL_GPL
+-0x62186db5    brcmu_pkt_buf_get_skb   drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0xf7af6d75    snd_pcm_new_stream      vmlinux EXPORT_SYMBOL
+-0x17320c5c    dentry_update_name_case vmlinux EXPORT_SYMBOL
+-0x8a7d1c31    high_memory     vmlinux EXPORT_SYMBOL
+-0x0186e2de    smp_call_function_many  vmlinux EXPORT_SYMBOL
+-0xbdf098ae    scsi_test_unit_ready    vmlinux EXPORT_SYMBOL
+-0x119b50e7    elf_check_arch  vmlinux EXPORT_SYMBOL
+-0xbf6d5c21    inet6_csk_update_pmtu   vmlinux EXPORT_SYMBOL_GPL
+-0x6b9a4457    snd_soc_jack_free_gpios vmlinux EXPORT_SYMBOL_GPL
+-0xd28c735f    simple_link     vmlinux EXPORT_SYMBOL
+-0xbdd2f42a    rcu_bh_force_quiescent_state    vmlinux EXPORT_SYMBOL_GPL
+-0x7a3cd015    v4l2_ctrl_get_menu      vmlinux EXPORT_SYMBOL
+-0x97f5694d    page_cache_async_readahead      vmlinux EXPORT_SYMBOL_GPL
+-0x2b4e956e    mempool_create  vmlinux EXPORT_SYMBOL
+-0x57231f45    ring_buffer_record_on   vmlinux EXPORT_SYMBOL_GPL
+-0x8e311007    hidinput_find_field     vmlinux EXPORT_SYMBOL_GPL
+-0x7ae1ae8e    cpufreq_frequency_table_put_attr        vmlinux EXPORT_SYMBOL_GPL
+-0x6c6a4b95    scsi_remove_target      vmlinux EXPORT_SYMBOL
+-0xb6c5a973    scsi_show_result        vmlinux EXPORT_SYMBOL
+-0x1ec3bed9    hdmi_audio_infoframe_init       vmlinux EXPORT_SYMBOL
+-0x3244dece    kblockd_schedule_work   vmlinux EXPORT_SYMBOL
+-0xafac4a33    mem_section     vmlinux EXPORT_SYMBOL
+-0xfd044751    send_sig_info   vmlinux EXPORT_SYMBOL
+-0xc02cf69b    clkdev_drop     vmlinux EXPORT_SYMBOL
+-0x39c95e24    phy_init_eee    vmlinux EXPORT_SYMBOL
+-0xfc53eac8    drm_cvt_mode    vmlinux EXPORT_SYMBOL
+-0x6a5e6530    __neigh_event_send      vmlinux EXPORT_SYMBOL
+-0x6c4d4cfe    sk_stream_wait_close    vmlinux EXPORT_SYMBOL
+-0x3d1cdeca    read_cache_page_async   vmlinux EXPORT_SYMBOL
+-0xd0ee38b8    schedule_timeout_uninterruptible        vmlinux EXPORT_SYMBOL
+-0xd79b5a02    allow_signal    vmlinux EXPORT_SYMBOL
+-0xd14fa335    show_class_attr_string  vmlinux EXPORT_SYMBOL_GPL
+-0xacb2a583    ndo_dflt_fdb_add        vmlinux EXPORT_SYMBOL
+-0x49a39542    snd_timer_global_register       vmlinux EXPORT_SYMBOL
+-0x63407037    kill_anon_super vmlinux EXPORT_SYMBOL
+-0xdc2b4205    platform_get_irq        vmlinux EXPORT_SYMBOL_GPL
+-0xc777ecaa    xfrm6_rcv       vmlinux EXPORT_SYMBOL
+-0x2fee3a7e    xfrm4_rcv       vmlinux EXPORT_SYMBOL
+-0xe94fef47    nf_ct_delete_from_lists vmlinux EXPORT_SYMBOL_GPL
+-0x6d466653    snd_soc_unregister_platform     vmlinux EXPORT_SYMBOL_GPL
+-0xb61a0c3b    bt_err  vmlinux EXPORT_SYMBOL
+-0x79536600    snd_soc_dpcm_can_be_params      vmlinux EXPORT_SYMBOL_GPL
+-0x016c4bc3    cfg80211_put_bss        vmlinux EXPORT_SYMBOL
+-0x90922aec    inet_dgram_connect      vmlinux EXPORT_SYMBOL
+-0x103ea6ec    generic_pipe_buf_steal  vmlinux EXPORT_SYMBOL
+-0x5fe77756    generic_pipe_buf_unmap  vmlinux EXPORT_SYMBOL
+-0xe5d95985    param_ops_ulong vmlinux EXPORT_SYMBOL
+-0xb03c01e8    dbs_check_cpu   vmlinux EXPORT_SYMBOL_GPL
+-0xff15acd6    usb_put_function_instance       vmlinux EXPORT_SYMBOL_GPL
+-0x6406cdf0    usb_find_alt_setting    vmlinux EXPORT_SYMBOL_GPL
+-0x4626bf6d    phy_connect     vmlinux EXPORT_SYMBOL
+-0x7a9326c6    driver_unregister       vmlinux EXPORT_SYMBOL_GPL
+-0xc5570382    inet_frags_exit_net     vmlinux EXPORT_SYMBOL
+-0x08216276    kobject_get     vmlinux EXPORT_SYMBOL
+-0x006818a5    kobject_put     vmlinux EXPORT_SYMBOL
+-0x37b777df    param_set_copystring    vmlinux EXPORT_SYMBOL
+-0x54f21cff    __send_remote_softirq   vmlinux EXPORT_SYMBOL
+-0x7a925833    cpufreq_get_global_kobject      vmlinux EXPORT_SYMBOL
+-0x2c900d91    cpufreq_put_global_kobject      vmlinux EXPORT_SYMBOL
+-0xbac4a225    v4l2_ctrl_fill  vmlinux EXPORT_SYMBOL
+-0xf7e6e534    v4l2_ctrl_find  vmlinux EXPORT_SYMBOL
+-0xbc5671dc    v4l_printk_ioctl        vmlinux EXPORT_SYMBOL
+-0x17021c93    drm_i2c_encoder_commit  vmlinux EXPORT_SYMBOL
+-0x10e70fd2    display_entity_get_modes        vmlinux EXPORT_SYMBOL_GPL
+-0xf1deabf2    div64_u64       vmlinux EXPORT_SYMBOL
+-0x2488515b    vb2_put_vma     vmlinux EXPORT_SYMBOL_GPL
+-0xd2ea2134    usb_descriptor_fillbuf  vmlinux EXPORT_SYMBOL_GPL
+-0xdacd26c5    usb_scuttle_anchored_urbs       vmlinux EXPORT_SYMBOL_GPL
+-0xfc39e32f    ioport_unmap    vmlinux EXPORT_SYMBOL
+-0x348998d3    sysfs_merge_group       vmlinux EXPORT_SYMBOL_GPL
+-0xc84a0a7e    seq_hlist_start_rcu     vmlinux EXPORT_SYMBOL
+-0xdd51deeb    d_validate      vmlinux EXPORT_SYMBOL
+-0x88ea60db    __get_user_pages_fast   vmlinux EXPORT_SYMBOL_GPL
+-0xe9bff861    down_trylock    vmlinux EXPORT_SYMBOL
+-0xff9e0620    usb_reset_configuration vmlinux EXPORT_SYMBOL_GPL
+-0x00130217    pwm_free        vmlinux EXPORT_SYMBOL_GPL
+-0x8fedcd53    snd_soc_info_xr_sx      vmlinux EXPORT_SYMBOL_GPL
+-0xc256e762    __bitmap_equal  vmlinux EXPORT_SYMBOL
+-0x7d4e2276    __init_rwsem    vmlinux EXPORT_SYMBOL
+-0xee5a877d    page_zero_new_buffers   vmlinux EXPORT_SYMBOL
+-0x96710252    mntget  vmlinux EXPORT_SYMBOL
+-0xe85c78e2    mntput  vmlinux EXPORT_SYMBOL
+-0x038e97d3    fasync_helper   vmlinux EXPORT_SYMBOL
+-0xf75c7d80    wm8994_mic_detect       vmlinux EXPORT_SYMBOL_GPL
+-0x2f4113a2    dcookie_register        vmlinux EXPORT_SYMBOL_GPL
+-0xce37be95    locks_mandatory_area    vmlinux EXPORT_SYMBOL
+-0x8be294cd    iommu_domain_free       vmlinux EXPORT_SYMBOL_GPL
+-0x23b5b8d1    exynos_drm_subdrv_register      vmlinux EXPORT_SYMBOL_GPL
+-0x6867f405    inet_twsk_deschedule    vmlinux EXPORT_SYMBOL
+-0x244e2178    xt_table_unlock vmlinux EXPORT_SYMBOL_GPL
+-0x52b9d131    tcf_exts_dump_stats     vmlinux EXPORT_SYMBOL
+-0x48bb9eb5    sock_alloc_send_pskb    vmlinux EXPORT_SYMBOL
+-0x757206d5    wm_hubs_spkmix_tlv      vmlinux EXPORT_SYMBOL_GPL
+-0x0acb1a3c    __bitmap_shift_right    vmlinux EXPORT_SYMBOL
+-0xaaa918c9    ftrace_dump     vmlinux EXPORT_SYMBOL_GPL
+-0x402b8281    __request_module        vmlinux EXPORT_SYMBOL
+-0xe944ba87    st_sensors_set_axis_enable      vmlinux EXPORT_SYMBOL
+-0x822f9003    inet_register_protosw   vmlinux EXPORT_SYMBOL
+-0xbe3a4f06    __inet_inherit_port     vmlinux EXPORT_SYMBOL_GPL
+-0xb63f16de    dev_deactivate  vmlinux EXPORT_SYMBOL
+-0xa014da84    snd_soc_add_platform_controls   vmlinux EXPORT_SYMBOL_GPL
+-0xeaaee9e6    submit_bio_wait vmlinux EXPORT_SYMBOL
+-0x23fd3028    vmalloc_node    vmlinux EXPORT_SYMBOL
+-0xa58fea9d    mempool_destroy vmlinux EXPORT_SYMBOL
+-0x054e550b    kernel_halt     vmlinux EXPORT_SYMBOL_GPL
+-0xf4c770ec    v4l2_clk_disable        vmlinux EXPORT_SYMBOL
+-0xd597e74e    phy_find_first  vmlinux EXPORT_SYMBOL
+-0x50621015    xfrm6_tunnel_spi_lookup vmlinux EXPORT_SYMBOL
+-0xc0f8a5b0    set_binfmt      vmlinux EXPORT_SYMBOL
+-0x36075bb5    iommu_group_register_notifier   vmlinux EXPORT_SYMBOL_GPL
+-0x93b8b0d3    scsi_ioctl      vmlinux EXPORT_SYMBOL
+-0xd0dcdd90    drm_mm_insert_node_in_range_generic     vmlinux EXPORT_SYMBOL
+-0xb2eaff96    km_policy_expired       vmlinux EXPORT_SYMBOL
+-0xa9effda5    __first_cpu     vmlinux EXPORT_SYMBOL
+-0xc24ba3ed    elv_rb_find     vmlinux EXPORT_SYMBOL
+-0xf0619801    timekeeping_clocktai    vmlinux EXPORT_SYMBOL
+-0x9e4faeef    dm_io_client_destroy    vmlinux EXPORT_SYMBOL
+-0x95cbb942    usb_add_gadget_udc_release      vmlinux EXPORT_SYMBOL_GPL
+-0x14c3db3e    spi_unregister_master   vmlinux EXPORT_SYMBOL_GPL
+-0xbee90f2f    __kfifo_out_peek_r      vmlinux EXPORT_SYMBOL
+-0x2869ebaf    regulator_bulk_force_disable    vmlinux EXPORT_SYMBOL_GPL
+-0xa04a01bd    qdisc_class_hash_insert vmlinux EXPORT_SYMBOL
+-0x43a261a8    eth_commit_mac_addr_change      vmlinux EXPORT_SYMBOL
+-0xe5867808    dlci_ioctl_set  vmlinux EXPORT_SYMBOL
+-0xbae6da94    crypto_alg_lookup       vmlinux EXPORT_SYMBOL_GPL
+-0x330d748a    v4l2_subdev_init        vmlinux EXPORT_SYMBOL
+-0xc6ff1a7d    phonet_header_ops       vmlinux EXPORT_SYMBOL
+-0xfaefacf3    locks_free_lock vmlinux EXPORT_SYMBOL
+-0xcbfa0b41    scsi_report_device_reset        vmlinux EXPORT_SYMBOL
+-0xbe1e4cd0    scsi_print_sense        vmlinux EXPORT_SYMBOL
+-0xe87ed821    drm_mode_create_dirty_info_property     vmlinux EXPORT_SYMBOL
+-0xb6d97288    inet6_add_offload       vmlinux EXPORT_SYMBOL
+-0xa681ec81    snd_soc_jack_notifier_register  vmlinux EXPORT_SYMBOL_GPL
+-0xd64b88b6    register_sound_mixer    vmlinux EXPORT_SYMBOL
+-0x02701efc    simple_attr_release     vmlinux EXPORT_SYMBOL_GPL
+-0xf6e04730    event_storage   vmlinux EXPORT_SYMBOL_GPL
+-0x95b5af62    mmc_regulator_set_ocr   vmlinux EXPORT_SYMBOL_GPL
+-0x77e78218    regulator_allow_bypass  vmlinux EXPORT_SYMBOL_GPL
+-0xf1070592    cfg80211_wext_giwretry  vmlinux EXPORT_SYMBOL_GPL
+-0x8a0f4230    rename_lock     vmlinux EXPORT_SYMBOL
+-0xda259c5d    page_symlink_inode_operations   vmlinux EXPORT_SYMBOL
+-0x8bd0a3fd    _raw_write_unlock_bh    vmlinux EXPORT_SYMBOL
+-0x99b0f1ff    usb_submit_urb  vmlinux EXPORT_SYMBOL_GPL
+-0x1fbd16da    ip_tos2prio     vmlinux EXPORT_SYMBOL
+-0x060ea2d6    kstrtoull       vmlinux EXPORT_SYMBOL
+-0x5ac15bae    kstrtou16       vmlinux EXPORT_SYMBOL
+-0x1998d8b6    jbd2_inode_cache        vmlinux EXPORT_SYMBOL
+-0x94961283    vunmap  vmlinux EXPORT_SYMBOL
+-0x74c4a01e    write_cache_pages       vmlinux EXPORT_SYMBOL
+-0xc1ddc02b    pinctrl_register        vmlinux EXPORT_SYMBOL_GPL
+-0x0ca54fee    _test_and_set_bit       vmlinux EXPORT_SYMBOL
+-0x80dfa464    xfrm_policy_alloc       vmlinux EXPORT_SYMBOL
+-0xd04f8eb6    nf_conntrack_l4proto_tcp6       vmlinux EXPORT_SYMBOL_GPL
+-0xcf28b516    finish_open     vmlinux EXPORT_SYMBOL
+-0x10f734ff    led_blink_set   vmlinux EXPORT_SYMBOL
+-0xc9086110    dw_mci_pltfm_remove     vmlinux EXPORT_SYMBOL_GPL
+-0xe5c78a99    do_blank_screen vmlinux EXPORT_SYMBOL
+-0xf17c6528    cfg80211_remain_on_channel_expired      vmlinux EXPORT_SYMBOL
+-0x117093be    qdisc_class_hash_init   vmlinux EXPORT_SYMBOL
+-0x13e6a1a2    sk_prot_clear_portaddr_nulls    vmlinux EXPORT_SYMBOL
+-0xa2a2d730    task_current_syscall    vmlinux EXPORT_SYMBOL_GPL
+-0x4411c503    prandom_seed    vmlinux EXPORT_SYMBOL
+-0x547ba3f6    single_open_net vmlinux EXPORT_SYMBOL_GPL
+-0xb9012717    set_page_dirty_lock     vmlinux EXPORT_SYMBOL
+-0x9a37cbf4    tcp_v4_conn_request     vmlinux EXPORT_SYMBOL
+-0xc81ae040    snd_soc_codec_volatile_register vmlinux EXPORT_SYMBOL_GPL
+-0xbe52317a    blk_rq_init     vmlinux EXPORT_SYMBOL
+-0x9ef34ad4    cpufreq_frequency_table_cpuinfo vmlinux EXPORT_SYMBOL_GPL
+-0x5bcf159d    usb_get_descriptor      vmlinux EXPORT_SYMBOL_GPL
+-0xf2e5cabe    spi_async_locked        vmlinux EXPORT_SYMBOL_GPL
+-0x26e76fb8    sysctl_udp_wmem_min     vmlinux EXPORT_SYMBOL
+-0x1fb12a69    tcp_v4_syn_recv_sock    vmlinux EXPORT_SYMBOL
+-0x6d464175    __sg_free_table vmlinux EXPORT_SYMBOL
+-0x59056c08    kmem_cache_shrink       vmlinux EXPORT_SYMBOL
+-0xc3aef602    usb_put_dev     vmlinux EXPORT_SYMBOL_GPL
+-0x520a3baf    drm_vm_open_locked      vmlinux EXPORT_SYMBOL_GPL
+-0x711a004a    drm_dp_link_rate_to_bw_code     vmlinux EXPORT_SYMBOL
+-0x919029aa    __readwrite_bug vmlinux EXPORT_SYMBOL
+-0x49045426    icmp_err_convert        vmlinux EXPORT_SYMBOL
+-0xf087137d    __dynamic_pr_debug      vmlinux EXPORT_SYMBOL
+-0x1e5b03dc    pm_qos_add_notifier     vmlinux EXPORT_SYMBOL_GPL
+-0x5e9d9e1e    gov_queue_work  vmlinux EXPORT_SYMBOL_GPL
+-0x601f665f    dm_io_client_create     vmlinux EXPORT_SYMBOL
+-0x05c311c2    vb2_ioctl_prepare_buf   vmlinux EXPORT_SYMBOL_GPL
+-0x14f62d2b    mii_check_link  vmlinux EXPORT_SYMBOL
+-0x36c69db7    dma_common_mmap vmlinux EXPORT_SYMBOL
+-0x1072a394    csum_partial_copy_from_user     vmlinux EXPORT_SYMBOL
+-0x3f878645    inet_diag_dump_one_icsk vmlinux EXPORT_SYMBOL_GPL
+-0xd7b85107    tcp_hashinfo    vmlinux EXPORT_SYMBOL
+-0x2d140a58    genl_unlock     vmlinux EXPORT_SYMBOL
+-0xeed1b62f    crypto_aead_setauthsize vmlinux EXPORT_SYMBOL_GPL
+-0x5f7bdc58    fd_install      vmlinux EXPORT_SYMBOL
+-0xe11f3cbc    _raw_read_lock_bh       vmlinux EXPORT_SYMBOL
+-0x3fd55724    of_n_size_cells vmlinux EXPORT_SYMBOL
+-0xd17aae7c    hid_report_raw_event    vmlinux EXPORT_SYMBOL_GPL
+-0xe469207d    scsi_unregister vmlinux EXPORT_SYMBOL
+-0xbf5da77e    dma_buf_begin_cpu_access        vmlinux EXPORT_SYMBOL_GPL
+-0x47ed7ca1    inet6_unregister_icmp_sender    vmlinux EXPORT_SYMBOL
+-0xed8b1ab6    nf_nat_used_tuple       vmlinux EXPORT_SYMBOL
+-0x46e928cf    nf_nat_packet   vmlinux EXPORT_SYMBOL_GPL
+-0xdc854ee4    blk_init_tags   vmlinux EXPORT_SYMBOL
+-0x4b134056    vfs_fsync_range vmlinux EXPORT_SYMBOL
+-0x3ce4ca6f    disable_irq     vmlinux EXPORT_SYMBOL
+-0xdc9fa232    raw_notifier_chain_register     vmlinux EXPORT_SYMBOL_GPL
+-0x2b0d15d8    scsi_internal_device_unblock    vmlinux EXPORT_SYMBOL_GPL
+-0x09d12bc0    sysfs_remove_file       vmlinux EXPORT_SYMBOL_GPL
+-0x85a8465a    path_put        vmlinux EXPORT_SYMBOL
+-0xe0dec72b    apply_to_page_range     vmlinux EXPORT_SYMBOL_GPL
+-0xa0ceef51    out_of_line_wait_on_bit vmlinux EXPORT_SYMBOL
+-0x7f04e7d5    dm_set_target_max_io_len        vmlinux EXPORT_SYMBOL_GPL
+-0x84a26155    v4l2_ctrl_g_ctrl        vmlinux EXPORT_SYMBOL
+-0x1254f0e4    scsi_host_alloc vmlinux EXPORT_SYMBOL
+-0x0e09444b    bus_get_device_klist    vmlinux EXPORT_SYMBOL_GPL
+-0xbebc3cd2    dst_discard     vmlinux EXPORT_SYMBOL
+-0x8d25ae30    snd_soc_dapm_put_value_enum_double      vmlinux EXPORT_SYMBOL_GPL
+-0x8d02ccf1    snd_soc_dapm_get_value_enum_double      vmlinux EXPORT_SYMBOL_GPL
+-0xaa2a72bf    __iowrite64_copy        vmlinux EXPORT_SYMBOL_GPL
+-0x373d62c5    invalidate_partition    vmlinux EXPORT_SYMBOL
+-0xd217e9e6    trace_set_clr_event     vmlinux EXPORT_SYMBOL_GPL
+-0x00e86db4    kick_process    vmlinux EXPORT_SYMBOL_GPL
+-0xa625110d    kmsg_dump_rewind        vmlinux EXPORT_SYMBOL_GPL
+-0x17eb0eee    v4l2_m2m_init   vmlinux EXPORT_SYMBOL_GPL
+-0xd153a267    drm_irq_uninstall       vmlinux EXPORT_SYMBOL
+-0x6ccf7bd7    __pv_phys_offset        vmlinux EXPORT_SYMBOL
+-0x6cf45a72    sk_release_kernel       vmlinux EXPORT_SYMBOL
+-0x7cff72b3    sg_miter_stop   vmlinux EXPORT_SYMBOL
+-0x0da10ec3    security_sock_graft     vmlinux EXPORT_SYMBOL
+-0xe601743b    jbd2_journal_init_jbd_inode     vmlinux EXPORT_SYMBOL
+-0xdd3916ac    _raw_spin_unlock_bh     vmlinux EXPORT_SYMBOL
+-0xb5ab5fe9    usb_function_register   vmlinux EXPORT_SYMBOL_GPL
+-0xa20bbbd7    xt_proto_init   vmlinux EXPORT_SYMBOL_GPL
+-0x13b715e2    blk_finish_plug vmlinux EXPORT_SYMBOL
+-0x0b1beb31    vmalloc_32_user vmlinux EXPORT_SYMBOL
+-0x85dfe0aa    fget_light      vmlinux EXPORT_SYMBOL
+-0x8bebc4a8    drm_master_put  vmlinux EXPORT_SYMBOL
+-0xf073bd48    nfc_hci_target_discovered       vmlinux EXPORT_SYMBOL
+-0x878ab3ce    sysctl_tcp_adv_win_scale        vmlinux EXPORT_SYMBOL
+-0x11e11bef    ip_local_out    vmlinux EXPORT_SYMBOL_GPL
+-0xafe96047    generic_permission      vmlinux EXPORT_SYMBOL
+-0x96123b65    iio_trigger_unregister  vmlinux EXPORT_SYMBOL
+-0xf7b01b50    gether_get_host_addr_cdc        vmlinux EXPORT_SYMBOL
+-0x3324e6d2    ehci_suspend    vmlinux EXPORT_SYMBOL_GPL
+-0x7ef61596    usb_hcd_check_unlink_urb        vmlinux EXPORT_SYMBOL_GPL
+-0x7ced7048    phy_device_free vmlinux EXPORT_SYMBOL
+-0x9afda3df    regcache_cache_bypass   vmlinux EXPORT_SYMBOL_GPL
+-0xd59668e6    unlock_flocks   vmlinux EXPORT_SYMBOL_GPL
+-0xb818e055    usbnet_open     vmlinux EXPORT_SYMBOL_GPL
+-0x4683093b    snd_ctl_notify  vmlinux EXPORT_SYMBOL
+-0x9d3aa376    blk_iopoll_init vmlinux EXPORT_SYMBOL
+-0x226a674d    atomic_notifier_chain_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0x0144d325    regmap_async_complete   vmlinux EXPORT_SYMBOL_GPL
+-0x27f4cbdb    uart_get_baud_rate      vmlinux EXPORT_SYMBOL
+-0x878175c4    secpath_dup     vmlinux EXPORT_SYMBOL
+-0x7931d788    snd_pcm_hw_constraint_step      vmlinux EXPORT_SYMBOL
+-0x36170e28    set_user_nice   vmlinux EXPORT_SYMBOL
+-0x45de06d1    iio_buffer_write_length vmlinux EXPORT_SYMBOL
+-0x5babbf10    media_device_unregister_entity  vmlinux EXPORT_SYMBOL_GPL
+-0xe593d0c8    usbnet_disconnect       vmlinux EXPORT_SYMBOL_GPL
+-0xb7e8ce46    exynos_drm_subdrv_close vmlinux EXPORT_SYMBOL_GPL
+-0xc29dc1ad    drm_framebuffer_init    vmlinux EXPORT_SYMBOL
+-0x7fe1a403    cfg80211_find_ie        vmlinux EXPORT_SYMBOL
+-0xa8469c88    netdev_notify_peers     vmlinux EXPORT_SYMBOL
+-0xe81978c6    splice_direct_to_actor  vmlinux EXPORT_SYMBOL
+-0xb5cb8145    hrtimer_get_res vmlinux EXPORT_SYMBOL_GPL
+-0x9a70b0fd    nf_nat_pptp_hook_inbound        vmlinux EXPORT_SYMBOL_GPL
+-0x2b9da7a4    genl_lock       vmlinux EXPORT_SYMBOL
+-0xb72e58d6    qdisc_class_hash_grow   vmlinux EXPORT_SYMBOL
+-0x0e59e8cf    sock_setsockopt vmlinux EXPORT_SYMBOL
+-0x20df2681    ida_simple_remove       vmlinux EXPORT_SYMBOL
+-0xbdef23a2    unlock_buffer   vmlinux EXPORT_SYMBOL
+-0x3b231b68    simple_transaction_release      vmlinux EXPORT_SYMBOL
+-0xad098b64    usb_unlocked_enable_lpm vmlinux EXPORT_SYMBOL_GPL
+-0x4b05e7ed    tty_port_close_start    vmlinux EXPORT_SYMBOL
+-0x14789075    dma_find_channel        vmlinux EXPORT_SYMBOL
+-0x77c05b09    fb_find_mode    vmlinux EXPORT_SYMBOL
+-0x01010c6d    klist_add_before        vmlinux EXPORT_SYMBOL_GPL
+-0x292c29ad    nfulnl_log_packet       vmlinux EXPORT_SYMBOL_GPL
+-0x521b36b5    qdisc_put_rtab  vmlinux EXPORT_SYMBOL
+-0x69c66f79    crypto_attr_alg2        vmlinux EXPORT_SYMBOL_GPL
+-0x341dbfa3    __per_cpu_offset        vmlinux EXPORT_SYMBOL
+-0x8953f8ff    __tracepoint_kmem_cache_alloc   vmlinux EXPORT_SYMBOL
+-0x7e0ef97c    regmap_irq_get_domain   vmlinux EXPORT_SYMBOL_GPL
+-0x437ff921    subsys_find_device_by_id        vmlinux EXPORT_SYMBOL_GPL
+-0x975e0663    set_sig_addr_hook       vmlinux EXPORT_SYMBOL_GPL
+-0xe86f0da8    proto_register  vmlinux EXPORT_SYMBOL
+-0xb838d98e    event_storage_mutex     vmlinux EXPORT_SYMBOL_GPL
+-0x9ca1dc35    vb2_fop_mmap    vmlinux EXPORT_SYMBOL_GPL
+-0xde1a5959    rtc_irq_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0xbeca75ff    drm_crtc_helper_set_mode        vmlinux EXPORT_SYMBOL
+-0x65f850bc    tty_wakeup      vmlinux EXPORT_SYMBOL_GPL
+-0xf4743f88    amba_ahb_device_add     vmlinux EXPORT_SYMBOL_GPL
+-0xa994f545    check_disk_size_change  vmlinux EXPORT_SYMBOL
+-0x455293f6    down_read       vmlinux EXPORT_SYMBOL
+-0x7eaf8e7a    v4l2_detect_gtf vmlinux EXPORT_SYMBOL_GPL
+-0x53105839    v4l2_detect_cvt vmlinux EXPORT_SYMBOL_GPL
+-0x6a41ea71    v4l2_clk_get_rate       vmlinux EXPORT_SYMBOL
+-0xc50c3f79    v4l2_clk_set_rate       vmlinux EXPORT_SYMBOL
+-0x52bc9e2a    drm_plane_cleanup       vmlinux EXPORT_SYMBOL
+-0x0d4cb82a    km_report       vmlinux EXPORT_SYMBOL
+-0xcffe8e42    __napi_complete vmlinux EXPORT_SYMBOL
+-0xb17c5844    skb_copy_expand vmlinux EXPORT_SYMBOL
+-0xaaaa5788    blk_queue_softirq_done  vmlinux EXPORT_SYMBOL
+-0x43a762e5    d_lookup        vmlinux EXPORT_SYMBOL
+-0xebc525f4    iio_triggered_buffer_cleanup    vmlinux EXPORT_SYMBOL
+-0xabd0c91c    rtc_time_to_tm  vmlinux EXPORT_SYMBOL
+-0x70f3f9b2    dmam_free_coherent      vmlinux EXPORT_SYMBOL
+-0xba361646    transport_setup_device  vmlinux EXPORT_SYMBOL_GPL
+-0x950ee7d1    fb_find_logo    vmlinux EXPORT_SYMBOL_GPL
+-0x20294ce8    genl_unregister_mc_group        vmlinux EXPORT_SYMBOL
+-0x1d7aabfd    path_is_under   vmlinux EXPORT_SYMBOL
+-0x17975413    iio_map_array_register  vmlinux EXPORT_SYMBOL_GPL
+-0xf811e69d    scsi_eh_flush_done_q    vmlinux EXPORT_SYMBOL
+-0x8b95a59f    xt_hook_unlink  vmlinux EXPORT_SYMBOL_GPL
+-0x557cb7c6    skb_morph       vmlinux EXPORT_SYMBOL_GPL
+-0x02ef742b    percpu_counter_set      vmlinux EXPORT_SYMBOL
+-0x03ae21fb    mmc_erase       vmlinux EXPORT_SYMBOL
+-0x7c46233a    cpufreq_quick_get       vmlinux EXPORT_SYMBOL
+-0xa4f8a168    dm_underlying_device_busy       vmlinux EXPORT_SYMBOL_GPL
+-0x1d41eadc    v4l2_ctrl_s_ctrl        vmlinux EXPORT_SYMBOL
+-0xa11295ab    serio_unregister_port   vmlinux EXPORT_SYMBOL
+-0x11065515    drm_mode_equal  vmlinux EXPORT_SYMBOL
+-0x4c47ec15    klist_add_head  vmlinux EXPORT_SYMBOL_GPL
+-0x68a24153    snd_pcm_format_physical_width   vmlinux EXPORT_SYMBOL
+-0xb6822a33    radix_tree_gang_lookup_tag      vmlinux EXPORT_SYMBOL
+-0xdaa16b82    of_clk_get      vmlinux EXPORT_SYMBOL
+-0x5c625801    scsi_remove_host        vmlinux EXPORT_SYMBOL
+-0xa7de1327    flush_dcache_page       vmlinux EXPORT_SYMBOL
+-0x2d6507b5    _find_next_zero_bit_le  vmlinux EXPORT_SYMBOL
+-0xf26e1c06    snd_soc_suspend vmlinux EXPORT_SYMBOL_GPL
+-0xc213a12a    devm_ioremap_nocache    vmlinux EXPORT_SYMBOL
+-0xb43a5300    sync_dirty_buffer       vmlinux EXPORT_SYMBOL
+-0xd303fa4e    clk_notifier_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x496c3d67    v4l2_querymenu  vmlinux EXPORT_SYMBOL
+-0x02b44bb5    scsi_is_host_device     vmlinux EXPORT_SYMBOL
+-0x91c9a325    bt_to_errno     vmlinux EXPORT_SYMBOL
+-0x86a85b06    tcp_reno_ssthresh       vmlinux EXPORT_SYMBOL_GPL
+-0xfc5c6b3e    netlink_has_listeners   vmlinux EXPORT_SYMBOL_GPL
+-0xe075d6eb    iter_div_u64_rem        vmlinux EXPORT_SYMBOL
+-0xcf0e08ad    filter_current_check_discard    vmlinux EXPORT_SYMBOL_GPL
+-0x5afb47fc    of_irq_to_resource_table        vmlinux EXPORT_SYMBOL_GPL
+-0xf1421d13    drm_mode_sort   vmlinux EXPORT_SYMBOL
+-0xd06ec95f    dma_supported   vmlinux EXPORT_SYMBOL
+-0xf1b80226    nf_nat_seq_adjust_hook  vmlinux EXPORT_SYMBOL_GPL
+-0xf4c02b65    inode_init_once vmlinux EXPORT_SYMBOL
+-0x369fcd70    tracing_snapshot        vmlinux EXPORT_SYMBOL_GPL
+-0x73d69364    ring_buffer_change_overwrite    vmlinux EXPORT_SYMBOL_GPL
+-0x339d542a    __srcu_notifier_call_chain      vmlinux EXPORT_SYMBOL_GPL
+-0xe2d3d0b9    v4l2_ctrl_sub_ev_ops    vmlinux EXPORT_SYMBOL
+-0xee129bef    usb_alloc_urb   vmlinux EXPORT_SYMBOL_GPL
+-0x64a127a3    spi_setup       vmlinux EXPORT_SYMBOL_GPL
+-0x3a8da0aa    nf_ip6_checksum vmlinux EXPORT_SYMBOL
+-0xb46a6cbb    scsi_cmd_ioctl  vmlinux EXPORT_SYMBOL
+-0xf7d52055    iio_bus_type    vmlinux EXPORT_SYMBOL
+-0x75b9f8b8    device_move     vmlinux EXPORT_SYMBOL_GPL
+-0x34dc9b87    neigh_seq_stop  vmlinux EXPORT_SYMBOL
+-0x82b802b2    snd_soc_dai_set_pll     vmlinux EXPORT_SYMBOL_GPL
+-0x0f4c91ed    ns_to_timespec  vmlinux EXPORT_SYMBOL
+-0xca34e63d    iio_triggered_buffer_postenable vmlinux EXPORT_SYMBOL
+-0x8d3ecd41    drm_core_ioremapfree    vmlinux EXPORT_SYMBOL
+-0xed93f29e    __kunmap_atomic vmlinux EXPORT_SYMBOL
+-0xe7cd755a    nf_ct_dying_timeout     vmlinux EXPORT_SYMBOL_GPL
+-0xe5452cbf    dev_mc_del_global       vmlinux EXPORT_SYMBOL
+-0x1a77ed38    dev_mc_add_global       vmlinux EXPORT_SYMBOL
+-0x7b4901f5    snd_soc_add_platform    vmlinux EXPORT_SYMBOL_GPL
+-0xdff7c9ce    blocking_notifier_chain_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0x346127a7    drm_global_item_ref     vmlinux EXPORT_SYMBOL
+-0xf763bb6d    drm_framebuffer_cleanup vmlinux EXPORT_SYMBOL
+-0x4a6b641b    fifo_create_dflt        vmlinux EXPORT_SYMBOL
+-0x3a39f5ed    neigh_table_init        vmlinux EXPORT_SYMBOL
+-0xc7207cfe    blk_queue_segment_boundary      vmlinux EXPORT_SYMBOL
+-0x183b1236    blk_stop_queue  vmlinux EXPORT_SYMBOL
+-0x632b18ed    blkcipher_walk_virt_block       vmlinux EXPORT_SYMBOL_GPL
+-0x68ecff32    sysfs_create_link       vmlinux EXPORT_SYMBOL_GPL
+-0x2bc64f3b    task_active_pid_ns      vmlinux EXPORT_SYMBOL_GPL
+-0xda83d7a1    mmc_register_driver     vmlinux EXPORT_SYMBOL
+-0x85e9caff    exynos4x12_cpufreq_init vmlinux EXPORT_SYMBOL
+-0xf75603a3    exynos4210_cpufreq_init vmlinux EXPORT_SYMBOL
+-0x38a9c2c7    input_ff_effect_from_user       vmlinux EXPORT_SYMBOL_GPL
+-0x4f92c146    mfd_cell_enable vmlinux EXPORT_SYMBOL
+-0xeacc50bc    attribute_container_register    vmlinux EXPORT_SYMBOL_GPL
+-0x53465c39    drm_vblank_count_and_time       vmlinux EXPORT_SYMBOL
+-0xc0e23731    inetpeer_invalidate_tree        vmlinux EXPORT_SYMBOL
+-0x7d1904b2    __neigh_create  vmlinux EXPORT_SYMBOL
+-0x6d294e43    clock_t_to_jiffies      vmlinux EXPORT_SYMBOL
+-0x327bf883    of_can_translate_address        vmlinux EXPORT_SYMBOL
+-0x6232e48e    power_supply_powers     vmlinux EXPORT_SYMBOL_GPL
+-0x15b9125f    hdmi_avi_infoframe_pack vmlinux EXPORT_SYMBOL
+-0x48e7c422    fanout_mutex    vmlinux EXPORT_SYMBOL_GPL
+-0xdf050302    skb_mac_gso_segment     vmlinux EXPORT_SYMBOL
+-0x4afb74d0    snd_pcm_lib_preallocate_pages_for_all   vmlinux EXPORT_SYMBOL
+-0xf874d572    crypto_larval_alloc     vmlinux EXPORT_SYMBOL_GPL
+-0x540a73a6    seq_release     vmlinux EXPORT_SYMBOL
+-0xb3826d47    insert_inode_locked     vmlinux EXPORT_SYMBOL
+-0x1866cec2    ring_buffer_size        vmlinux EXPORT_SYMBOL_GPL
+-0x838b13e7    ring_buffer_free        vmlinux EXPORT_SYMBOL_GPL
+-0x41d8cf05    module_layout   vmlinux EXPORT_SYMBOL
+-0xdbb5a9f5    drm_ht_remove_item      vmlinux EXPORT_SYMBOL
+-0x654a5368    drm_vblank_off  vmlinux EXPORT_SYMBOL
+-0xb3e9e167    drm_vblank_get  vmlinux EXPORT_SYMBOL
+-0xa795c78d    pl330_filter    vmlinux EXPORT_SYMBOL
+-0x0335cb43    __sb_start_write        vmlinux EXPORT_SYMBOL
+-0x6955eb5f    hidinput_disconnect     vmlinux EXPORT_SYMBOL_GPL
+-0xd49dd4f4    cfg80211_cqm_txe_notify vmlinux EXPORT_SYMBOL
+-0xcc1fb551    baswap  vmlinux EXPORT_SYMBOL
+-0x653aa466    __blk_put_request       vmlinux EXPORT_SYMBOL_GPL
+-0x99401626    elv_rb_latter_request   vmlinux EXPORT_SYMBOL
+-0x0da68fbf    sysfs_create_bin_file   vmlinux EXPORT_SYMBOL_GPL
+-0x27fa66e1    nr_free_buffer_pages    vmlinux EXPORT_SYMBOL_GPL
+-0x7452437c    cgroup_taskset_next     vmlinux EXPORT_SYMBOL_GPL
+-0xd2e7fb21    mod_delayed_work_on     vmlinux EXPORT_SYMBOL_GPL
+-0x3d388324    dpm_resume_end  vmlinux EXPORT_SYMBOL_GPL
+-0xfda2fc6f    pinctrl_remove_gpio_range       vmlinux EXPORT_SYMBOL_GPL
+-0x98c9f584    klist_init      vmlinux EXPORT_SYMBOL_GPL
+-0x72e52881    xfrm_state_unregister_afinfo    vmlinux EXPORT_SYMBOL
+-0xec57ea15    snd_card_unref  vmlinux EXPORT_SYMBOL
+-0x6cdc5c6b    nla_strlcpy     vmlinux EXPORT_SYMBOL
+-0xa46f2f1b    kstrtouint      vmlinux EXPORT_SYMBOL
+-0x315c8d71    blk_init_queue_node     vmlinux EXPORT_SYMBOL
+-0x83211609    up_write        vmlinux EXPORT_SYMBOL
+-0x19610e1f    cpu_all_bits    vmlinux EXPORT_SYMBOL
+-0x4f248523    of_find_node_by_name    vmlinux EXPORT_SYMBOL
+-0x14d0738e    dm_noflush_suspending   vmlinux EXPORT_SYMBOL_GPL
+-0x488cee4b    serial8250_do_pm        vmlinux EXPORT_SYMBOL
+-0xe4e38519    tcf_hash_release        vmlinux EXPORT_SYMBOL
+-0xf1298271    free_buffer_head        vmlinux EXPORT_SYMBOL
+-0x08559b9a    fget    vmlinux EXPORT_SYMBOL
+-0x4a57b339    wait_for_completion_io_timeout  vmlinux EXPORT_SYMBOL
+-0xcccd9343    mmc_gpio_get_ro vmlinux EXPORT_SYMBOL
+-0xa3959367    mmc_gpio_get_cd vmlinux EXPORT_SYMBOL
+-0xbc3a2d91    cpufreq_cpu_put vmlinux EXPORT_SYMBOL_GPL
+-0x238dd120    cpufreq_cpu_get vmlinux EXPORT_SYMBOL_GPL
+-0xfe7c6819    scsi_target_block       vmlinux EXPORT_SYMBOL_GPL
+-0x42488405    scsi_prep_state_check   vmlinux EXPORT_SYMBOL
+-0xf4b2e991    drm_mm_put_block        vmlinux EXPORT_SYMBOL
+-0x688bd4c5    snd_ctl_boolean_mono_info       vmlinux EXPORT_SYMBOL
+-0xe1e281d6    jbd2_log_start_commit   vmlinux EXPORT_SYMBOL
+-0x9130f1c7    remove_proc_subtree     vmlinux EXPORT_SYMBOL
+-0xfa1eb910    unregister_syscore_ops  vmlinux EXPORT_SYMBOL_GPL
+-0x4d7f9839    snd_soc_of_parse_card_name      vmlinux EXPORT_SYMBOL_GPL
+-0x44e9a829    match_token     vmlinux EXPORT_SYMBOL
+-0x49b26c63    jbd2_journal_abort      vmlinux EXPORT_SYMBOL
+-0x1a323362    __ftrace_vbprintk       vmlinux EXPORT_SYMBOL_GPL
+-0x0a958ed4    down_write      vmlinux EXPORT_SYMBOL
+-0x706b3a33    cpufreq_frequency_table_get_attr        vmlinux EXPORT_SYMBOL_GPL
+-0xbdba9828    hdmi_audio_infoframe_pack       vmlinux EXPORT_SYMBOL
+-0x09c64fbd    ieee80211_frequency_to_channel  vmlinux EXPORT_SYMBOL
+-0x64d41d38    ip_route_output_flow    vmlinux EXPORT_SYMBOL_GPL
+-0xc23832c5    snd_soc_add_card_controls       vmlinux EXPORT_SYMBOL_GPL
+-0x43326227    posix_test_lock vmlinux EXPORT_SYMBOL
+-0xd7289dfe    kill_block_super        vmlinux EXPORT_SYMBOL
+-0x2b0f3b97    flush_signals   vmlinux EXPORT_SYMBOL
+-0x1b9e0ff1    scsilun_to_int  vmlinux EXPORT_SYMBOL
+-0x97a0de2c    drm_prime_pages_to_sg   vmlinux EXPORT_SYMBOL
+-0x0442abb5    __inet_stream_connect   vmlinux EXPORT_SYMBOL
+-0xc6f7d745    nf_ct_remove_expectations       vmlinux EXPORT_SYMBOL_GPL
+-0xecdea3ba    neigh_lookup_nodev      vmlinux EXPORT_SYMBOL
+-0x10c58227    kernel_setsockopt       vmlinux EXPORT_SYMBOL
+-0x8fd29b0f    kernel_getsockopt       vmlinux EXPORT_SYMBOL
+-0xed5cfaa9    kernel_sock_ioctl       vmlinux EXPORT_SYMBOL
+-0x8ffdb3b8    crc16   vmlinux EXPORT_SYMBOL
+-0xadc7f742    mb_cache_entry_insert   vmlinux EXPORT_SYMBOL
+-0x4e1e8913    kallsyms_on_each_symbol vmlinux EXPORT_SYMBOL_GPL
+-0xf82f3657    work_on_cpu     vmlinux EXPORT_SYMBOL_GPL
+-0x459e133f    v4l2_m2m_get_curr_priv  vmlinux EXPORT_SYMBOL
+-0x4dd51c13    phy_pm_runtime_allow    vmlinux EXPORT_SYMBOL_GPL
+-0xcbbaba0b    nf_tproxy_assign_sock   vmlinux EXPORT_SYMBOL_GPL
+-0x3e220367    nfnetlink_unicast       vmlinux EXPORT_SYMBOL_GPL
+-0x55504881    snd_mixer_oss_ioctl_card        vmlinux EXPORT_SYMBOL
+-0xab694444    bsearch vmlinux EXPORT_SYMBOL
+-0x662edc7c    blk_put_request vmlinux EXPORT_SYMBOL
+-0x6ca4bf88    async_synchronize_full_domain   vmlinux EXPORT_SYMBOL_GPL
+-0x12456a92    iommu_iova_to_phys      vmlinux EXPORT_SYMBOL_GPL
+-0xdc7b411a    dev_pm_qos_hide_latency_limit   vmlinux EXPORT_SYMBOL_GPL
+-0x28441b73    drm_get_last_vbltimestamp       vmlinux EXPORT_SYMBOL
+-0x83eab4ef    crypto_create_tfm       vmlinux EXPORT_SYMBOL_GPL
+-0x42e2c53b    nf_conntrack_in vmlinux EXPORT_SYMBOL_GPL
+-0x3ea1d70f    sock_queue_rcv_skb      vmlinux EXPORT_SYMBOL
+-0xe7820ad2    snd_pcm_lib_preallocate_free_for_all    vmlinux EXPORT_SYMBOL
+-0x754dac78    blk_limits_io_min       vmlinux EXPORT_SYMBOL
+-0x0cd9cfec    sysfs_remove_files      vmlinux EXPORT_SYMBOL_GPL
+-0xc237047a    mapping_tagged  vmlinux EXPORT_SYMBOL
+-0xd777c9b7    iio_device_alloc        vmlinux EXPORT_SYMBOL
+-0xd688716b    dm_kcopyd_client_create vmlinux EXPORT_SYMBOL
+-0x2502c67c    v4l2_fh_add     vmlinux EXPORT_SYMBOL_GPL
+-0x088675f7    usbnet_write_cmd_async  vmlinux EXPORT_SYMBOL_GPL
+-0xb35659de    drm_mode_remove vmlinux EXPORT_SYMBOL
+-0x16acff8a    devm_of_pwm_get vmlinux EXPORT_SYMBOL_GPL
+-0xd2bd22d2    s3c_gpio_getpull        vmlinux EXPORT_SYMBOL
+-0x5fbecd25    s3c_gpio_setpull        vmlinux EXPORT_SYMBOL
+-0x67c2fa54    __copy_to_user  vmlinux EXPORT_SYMBOL
+-0x7c6a49ce    unix_table_lock vmlinux EXPORT_SYMBOL_GPL
+-0x38d60861    put_disk        vmlinux EXPORT_SYMBOL
+-0x871bcaa4    irq_find_host   vmlinux EXPORT_SYMBOL_GPL
+-0xd9605d4c    add_timer       vmlinux EXPORT_SYMBOL
+-0xea97fb5e    usbhid_set_leds vmlinux EXPORT_SYMBOL_GPL
+-0x70915b51    serio_interrupt vmlinux EXPORT_SYMBOL
+-0x92a772c3    usbnet_purge_paused_rxq vmlinux EXPORT_SYMBOL_GPL
+-0xf6bb4729    color_table     vmlinux EXPORT_SYMBOL
+-0x8c637d43    irq_cpu_rmap_add        vmlinux EXPORT_SYMBOL
+-0x9ba7089d    argv_split      vmlinux EXPORT_SYMBOL
+-0x34f3484e    security_tun_dev_attach_queue   vmlinux EXPORT_SYMBOL
+-0x1a1431fd    _raw_spin_unlock_irq    vmlinux EXPORT_SYMBOL
+-0x7c08f605    hid_allocate_device     vmlinux EXPORT_SYMBOL_GPL
+-0xe5a8e6b5    spi_sync        vmlinux EXPORT_SYMBOL_GPL
+-0xcc69f0f8    dma_sync_wait   vmlinux EXPORT_SYMBOL
+-0x43e33157    blk_queue_max_hw_sectors        vmlinux EXPORT_SYMBOL
+-0x8ea0cdd5    drm_add_modes_noedid    vmlinux EXPORT_SYMBOL
+-0x9a8318ef    v7_coherent_kern_range  vmlinux EXPORT_SYMBOL
+-0x5de3ad52    cfg80211_ref_bss        vmlinux EXPORT_SYMBOL
+-0xdc1b2765    crypto_aes_set_key      vmlinux EXPORT_SYMBOL_GPL
+-0x5086ac3a    alg_test        vmlinux EXPORT_SYMBOL_GPL
+-0x9c35fb24    jbd2__journal_restart   vmlinux EXPORT_SYMBOL
+-0xbef43296    console_conditional_schedule    vmlinux EXPORT_SYMBOL
+-0xa71c1b98    bus_set_iommu   vmlinux EXPORT_SYMBOL_GPL
+-0x8e801428    bus_create_file vmlinux EXPORT_SYMBOL_GPL
+-0x8fc34c2d    drm_warn_on_modeset_not_all_locked      vmlinux EXPORT_SYMBOL
+-0x2e0a06e3    snd_unregister_device   vmlinux EXPORT_SYMBOL
+-0x9caaf6cf    blkdev_issue_discard    vmlinux EXPORT_SYMBOL
+-0x3e6444e8    crypto_unregister_pcomp vmlinux EXPORT_SYMBOL_GPL
+-0xc1d19fdd    debugfs_create_symlink  vmlinux EXPORT_SYMBOL_GPL
+-0x9bd7640e    fat_detach      vmlinux EXPORT_SYMBOL_GPL
+-0x698a899f    ring_buffer_peek        vmlinux EXPORT_SYMBOL_GPL
+-0xe2e7840d    regmap_init_mmio_clk    vmlinux EXPORT_SYMBOL_GPL
+-0xe556d687    xt_request_find_match   vmlinux EXPORT_SYMBOL_GPL
+-0xcf25e6b2    xattr_getsecurity       vmlinux EXPORT_SYMBOL_GPL
+-0x6228c21f    smp_call_function_single        vmlinux EXPORT_SYMBOL
+-0x5f324ec1    drm_ioctl       vmlinux EXPORT_SYMBOL
+-0x4d9b652b    rb_erase        vmlinux EXPORT_SYMBOL
+-0xcc71d484    drm_mode_duplicate      vmlinux EXPORT_SYMBOL
+-0x2b02560b    devm_pwm_put    vmlinux EXPORT_SYMBOL_GPL
+-0x3659d5ac    devm_phy_get    vmlinux EXPORT_SYMBOL_GPL
+-0xaafdc258    strcasecmp      vmlinux EXPORT_SYMBOL
+-0xc296567b    save_mount_options      vmlinux EXPORT_SYMBOL
+-0xbade32c7    clockevents_register_device     vmlinux EXPORT_SYMBOL_GPL
+-0xfb8a84a4    drm_mm_get_block_range_generic  vmlinux EXPORT_SYMBOL
+-0x058b582a    vt_get_leds     vmlinux EXPORT_SYMBOL_GPL
+-0xb2a0603e    nci_recv_frame  vmlinux EXPORT_SYMBOL
+-0xc0240dd4    nf_conntrack_set_hashsize       vmlinux EXPORT_SYMBOL_GPL
+-0x45c8cd86    ifla_policy     vmlinux EXPORT_SYMBOL
+-0xd251d7b0    security_socket_getpeersec_dgram        vmlinux EXPORT_SYMBOL
+-0xf05e203c    set_blocksize   vmlinux EXPORT_SYMBOL
+-0xc1c995a0    block_page_mkwrite      vmlinux EXPORT_SYMBOL
+-0x85b9e216    set_timer_slack vmlinux EXPORT_SYMBOL_GPL
+-0x2665c0a3    vb2_qbuf        vmlinux EXPORT_SYMBOL_GPL
+-0x9abe8d18    video_usercopy  vmlinux EXPORT_SYMBOL
+-0x1d93e603    tty_unthrottle  vmlinux EXPORT_SYMBOL
+-0x1142511d    crypto_spawn_tfm        vmlinux EXPORT_SYMBOL_GPL
+-0xeb9ddf6d    security_inode_notifysecctx     vmlinux EXPORT_SYMBOL
+-0x68df960a    generic_error_remove_page       vmlinux EXPORT_SYMBOL
+-0x7000dc34    class_compat_remove_link        vmlinux EXPORT_SYMBOL_GPL
+-0x816dee03    uart_unregister_driver  vmlinux EXPORT_SYMBOL
+-0x0acf7679    dma_issue_pending_all   vmlinux EXPORT_SYMBOL
+-0x8792d764    l2cap_conn_get  vmlinux EXPORT_SYMBOL
+-0xcf2890b2    ipv6_chk_prefix vmlinux EXPORT_SYMBOL
+-0x616ff33b    ip6_dst_lookup_flow     vmlinux EXPORT_SYMBOL_GPL
+-0x3e963d19    inet_csk_search_req     vmlinux EXPORT_SYMBOL_GPL
+-0xdd632e58    inet_unhash     vmlinux EXPORT_SYMBOL_GPL
+-0x98e40edf    nf_ct_nat_offset        vmlinux EXPORT_SYMBOL_GPL
+-0x0a7ed556    blk_execute_rq  vmlinux EXPORT_SYMBOL
+-0x44408a4a    mdio_bus_type   vmlinux EXPORT_SYMBOL
+-0xac74a2a9    ip6_xmit        vmlinux EXPORT_SYMBOL
+-0x411d75db    ip_tunnel_init  vmlinux EXPORT_SYMBOL_GPL
+-0x7a442539    tcf_exts_dump   vmlinux EXPORT_SYMBOL
+-0x13307fde    vsscanf vmlinux EXPORT_SYMBOL
+-0xcc368515    jbd2_journal_unlock_updates     vmlinux EXPORT_SYMBOL
+-0x21bfb720    seq_open_net    vmlinux EXPORT_SYMBOL_GPL
+-0x82d79b51    sysctl_vfs_cache_pressure       vmlinux EXPORT_SYMBOL_GPL
+-0x04486e88    rcu_batches_completed   vmlinux EXPORT_SYMBOL_GPL
+-0x7c1372e8    panic   vmlinux EXPORT_SYMBOL
+-0x9808f34e    dev_pm_qos_expose_flags vmlinux EXPORT_SYMBOL_GPL
+-0x544b5ea8    pwm_disable     vmlinux EXPORT_SYMBOL_GPL
+-0x5c265cba    sg_init_one     vmlinux EXPORT_SYMBOL
+-0x12da5bb2    __kmalloc       vmlinux EXPORT_SYMBOL
+-0x28d6861d    __vmalloc       vmlinux EXPORT_SYMBOL
+-0x5db7b0d3    led_trigger_remove      vmlinux EXPORT_SYMBOL_GPL
+-0x83b38ee6    kobject_init_and_add    vmlinux EXPORT_SYMBOL_GPL
+-0x757cdadf    usbnet_get_ethernet_addr        vmlinux EXPORT_SYMBOL_GPL
+-0x43a286d1    drm_prime_remove_buf_handle     vmlinux EXPORT_SYMBOL
+-0xea8ddd89    __ip_select_ident       vmlinux EXPORT_SYMBOL
+-0x1f984870    skb_gro_receive vmlinux EXPORT_SYMBOL_GPL
+-0x48f8aa53    flock_lock_file_wait    vmlinux EXPORT_SYMBOL
+-0x05e067d7    __media_entity_remove_links     vmlinux EXPORT_SYMBOL_GPL
+-0xe7cb87e4    xt_find_match   vmlinux EXPORT_SYMBOL
+-0x9d62c35b    nfq_ct_hook     vmlinux EXPORT_SYMBOL_GPL
+-0xe12b4adb    __skb_warn_lro_forwarding       vmlinux EXPORT_SYMBOL
+-0x471eeac6    snd_soc_platform_write  vmlinux EXPORT_SYMBOL_GPL
+-0x71c90087    memcmp  vmlinux EXPORT_SYMBOL
+-0x4881d505    idr_for_each    vmlinux EXPORT_SYMBOL
+-0x79b33953    shash_ahash_digest      vmlinux EXPORT_SYMBOL_GPL
+-0xcf1d92aa    locks_init_lock vmlinux EXPORT_SYMBOL
+-0x11cfbadb    bio_add_pc_page vmlinux EXPORT_SYMBOL
+-0x2917e251    split_page      vmlinux EXPORT_SYMBOL_GPL
+-0xda53403f    v4l2_m2m_ctx_init       vmlinux EXPORT_SYMBOL_GPL
+-0x4f4d910e    regmap_init     vmlinux EXPORT_SYMBOL_GPL
+-0xb2a9634b    regmap_exit     vmlinux EXPORT_SYMBOL_GPL
+-0xe16838c2    drm_mm_search_free_in_range_generic     vmlinux EXPORT_SYMBOL
+-0xf05ffa15    fb_var_to_videomode     vmlinux EXPORT_SYMBOL
+-0xab707907    inet6_del_offload       vmlinux EXPORT_SYMBOL
+-0x13e229c2    nf_ct_helper_expectfn_find_by_name      vmlinux EXPORT_SYMBOL_GPL
+-0x1f0547c1    netif_stacked_transfer_operstate        vmlinux EXPORT_SYMBOL
+-0xd435e67a    snd_card_set_id vmlinux EXPORT_SYMBOL
+-0xc7236f77    d_alloc_name    vmlinux EXPORT_SYMBOL
+-0x2f3857e2    _raw_write_lock_irqsave vmlinux EXPORT_SYMBOL
+-0x37c199e6    serio_reconnect vmlinux EXPORT_SYMBOL
+-0x6754f715    drm_fb_helper_fill_fix  vmlinux EXPORT_SYMBOL
+-0xc6df7ef6    cont_write_begin        vmlinux EXPORT_SYMBOL
+-0x1c97e3ec    vfs_readdir     vmlinux EXPORT_SYMBOL
+-0xbdd295f0    trace_vprintk   vmlinux EXPORT_SYMBOL_GPL
+-0x8faa4598    of_translate_address    vmlinux EXPORT_SYMBOL
+-0x0699040f    drm_encoder_cleanup     vmlinux EXPORT_SYMBOL
+-0x7f8c7b48    dma_async_memcpy_buf_to_buf     vmlinux EXPORT_SYMBOL
+-0x1ed85a8d    pinctrl_dev_get_drvdata vmlinux EXPORT_SYMBOL_GPL
+-0x881039d0    zlib_inflate    vmlinux EXPORT_SYMBOL
+-0x3771b461    crc_ccitt       vmlinux EXPORT_SYMBOL
+-0xa43b1297    vscnprintf      vmlinux EXPORT_SYMBOL
+-0x166e361d    blk_recount_segments    vmlinux EXPORT_SYMBOL
+-0x887ece4a    simple_statfs   vmlinux EXPORT_SYMBOL
+-0x617643a2    param_set_long  vmlinux EXPORT_SYMBOL
+-0x6c69a9be    xfrm6_tunnel_deregister vmlinux EXPORT_SYMBOL
+-0x3b850073    km_policy_notify        vmlinux EXPORT_SYMBOL
+-0x10cc1e43    xfrm4_tunnel_deregister vmlinux EXPORT_SYMBOL
+-0xc0f95b9e    ip_mc_join_group        vmlinux EXPORT_SYMBOL
+-0xdb760f52    __kfifo_free    vmlinux EXPORT_SYMBOL
+-0x3a288321    configfs_undepend_item  vmlinux EXPORT_SYMBOL
+-0x2cc83b45    usb_string      vmlinux EXPORT_SYMBOL_GPL
+-0x98442d13    inet_csk_reqsk_queue_hash_add   vmlinux EXPORT_SYMBOL_GPL
+-0x8d33679f    nf_ct_unexpect_related  vmlinux EXPORT_SYMBOL_GPL
+-0xe6e1c5fe    uuid_be_gen     vmlinux EXPORT_SYMBOL_GPL
+-0x289ea691    debugfs_remove  vmlinux EXPORT_SYMBOL_GPL
+-0xbb4e9599    lease_modify    vmlinux EXPORT_SYMBOL
+-0x2fb6e20e    drop_nlink      vmlinux EXPORT_SYMBOL
+-0xdfaa6b6b    v4l2_ctrl_radio_filter  vmlinux EXPORT_SYMBOL
+-0xa3675712    xfrm_dst_ifdown vmlinux EXPORT_SYMBOL
+-0x0d9bae4b    nf_nat_l4proto_nlattr_to_range  vmlinux EXPORT_SYMBOL_GPL
+-0xc17f8f83    neigh_seq_start vmlinux EXPORT_SYMBOL
+-0x6e7943ec    iommu_group_id  vmlinux EXPORT_SYMBOL_GPL
+-0x1aef1e27    eth_header_cache_update vmlinux EXPORT_SYMBOL
+-0xd800dc59    snd_pcm_hw_constraint_ratdens   vmlinux EXPORT_SYMBOL
+-0xd1157735    release_and_free_resource       vmlinux EXPORT_SYMBOL
+-0xb31526ee    sg_copy_from_buffer     vmlinux EXPORT_SYMBOL
+-0x73e20c1c    strlcpy vmlinux EXPORT_SYMBOL
+-0x328a05f1    strncpy vmlinux EXPORT_SYMBOL
+-0x8abacc47    get_max_files   vmlinux EXPORT_SYMBOL_GPL
+-0xae0f6b4e    regulator_unregister_notifier   vmlinux EXPORT_SYMBOL_GPL
+-0x386f5a4e    tcf_em_tree_destroy     vmlinux EXPORT_SYMBOL
+-0x97b4500c    __tracepoint_kmem_cache_free    vmlinux EXPORT_SYMBOL
+-0x4a69690c    scsi_release_buffers    vmlinux EXPORT_SYMBOL
+-0xf195c682    fb_invert_cmaps vmlinux EXPORT_SYMBOL
+-0xab156bb5    kern_mount_data vmlinux EXPORT_SYMBOL_GPL
+-0x1902f934    __init_kthread_worker   vmlinux EXPORT_SYMBOL_GPL
+-0xdac0df4a    driver_create_file      vmlinux EXPORT_SYMBOL_GPL
+-0x083eb21c    rfkill_unregister       vmlinux EXPORT_SYMBOL
+-0x3e52c876    blk_requeue_request     vmlinux EXPORT_SYMBOL
+-0xdca5d880    insert_inode_locked4    vmlinux EXPORT_SYMBOL
+-0x41482d8b    strndup_user    vmlinux EXPORT_SYMBOL
+-0xddd58dc0    ring_buffer_reset       vmlinux EXPORT_SYMBOL_GPL
+-0x6b172795    media_entity_graph_walk_next    vmlinux EXPORT_SYMBOL_GPL
+-0x0591a4d1    usb_ep_autoconfig_ss    vmlinux EXPORT_SYMBOL_GPL
+-0x4b076147    uncache_firmware        vmlinux EXPORT_SYMBOL_GPL
+-0x098b71c6    fb_dealloc_cmap vmlinux EXPORT_SYMBOL
+-0x83d1444a    crypto_init_spawn       vmlinux EXPORT_SYMBOL_GPL
+-0x60061dd7    mount_nodev     vmlinux EXPORT_SYMBOL
+-0x7bb32751    pagevec_lookup  vmlinux EXPORT_SYMBOL
+-0x47b6a10f    ftrace_print_symbols_seq        vmlinux EXPORT_SYMBOL
+-0x8664f62e    cpufreq_update_policy   vmlinux EXPORT_SYMBOL
+-0x29f39077    pwmchip_remove  vmlinux EXPORT_SYMBOL_GPL
+-0x905baf48    xfrm_find_acq   vmlinux EXPORT_SYMBOL
+-0x9487bc19    eth_mac_addr    vmlinux EXPORT_SYMBOL
+-0xad1ed84c    unregister_hw_breakpoint        vmlinux EXPORT_SYMBOL_GPL
+-0x993805c1    scsi_scan_host  vmlinux EXPORT_SYMBOL
+-0x7a77dfe4    scsi_setup_fs_cmnd      vmlinux EXPORT_SYMBOL
+-0xbbc9fd6e    cfg80211_wext_siwfrag   vmlinux EXPORT_SYMBOL_GPL
+-0x82c82c32    cfg80211_wext_giwfrag   vmlinux EXPORT_SYMBOL_GPL
+-0xe80dd06a    tcp_sendpage    vmlinux EXPORT_SYMBOL
+-0x47b3f862    radix_tree_lookup_slot  vmlinux EXPORT_SYMBOL
+-0x91621d6a    allocate_resource       vmlinux EXPORT_SYMBOL
+-0xb98a0185    rtc_tm_to_time  vmlinux EXPORT_SYMBOL
+-0xe5883bd9    class_compat_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x7bf9c108    serial8250_rx_dma       vmlinux EXPORT_SYMBOL_GPL
+-0xc7856a3d    inet6addr_notifier_call_chain   vmlinux EXPORT_SYMBOL
+-0xc08647ff    ring_buffer_bytes_cpu   vmlinux EXPORT_SYMBOL_GPL
+-0xcbbf0a6f    audit_log_task_context  vmlinux EXPORT_SYMBOL
+-0x0a0ab757    pm_schedule_suspend     vmlinux EXPORT_SYMBOL_GPL
+-0x617ae32f    of_get_display_timings  vmlinux EXPORT_SYMBOL_GPL
+-0xe442a492    splice_from_pipe_feed   vmlinux EXPORT_SYMBOL
+-0xf9a054b5    __round_jiffies vmlinux EXPORT_SYMBOL_GPL
+-0x38e20383    hid_alloc_report_buf    vmlinux EXPORT_SYMBOL_GPL
+-0x626ffd48    spi_write_then_read     vmlinux EXPORT_SYMBOL_GPL
+-0x7b5fc447    pinctrl_lookup_state    vmlinux EXPORT_SYMBOL_GPL
+-0x8c49e9fe    cfg80211_conn_failed    vmlinux EXPORT_SYMBOL
+-0x03c06156    bitmap_fold     vmlinux EXPORT_SYMBOL
+-0x04d5a096    security_sb_clone_mnt_opts      vmlinux EXPORT_SYMBOL
+-0x424b2fdf    vfs_rmdir       vmlinux EXPORT_SYMBOL
+-0x52856d8e    generic_shutdown_super  vmlinux EXPORT_SYMBOL
+-0xbd10541e    css_lookup      vmlinux EXPORT_SYMBOL_GPL
+-0x37e74642    get_jiffies_64  vmlinux EXPORT_SYMBOL
+-0xb8117014    cfg80211_rx_spurious_frame      vmlinux EXPORT_SYMBOL
+-0x790c2d9c    netdev_master_upper_dev_link    vmlinux EXPORT_SYMBOL
+-0x02a6ce5a    crc16_table     vmlinux EXPORT_SYMBOL
+-0xe280ea92    init_buffer     vmlinux EXPORT_SYMBOL
+-0xf21e1f9b    disable_percpu_irq      vmlinux EXPORT_SYMBOL_GPL
+-0xb5ae5758    scsi_track_queue_full   vmlinux EXPORT_SYMBOL
+-0xa26b1ba8    exynos_drm_device_register      vmlinux EXPORT_SYMBOL_GPL
+-0xbe55cd3e    __sock_recv_ts_and_drops        vmlinux EXPORT_SYMBOL_GPL
+-0xcedd3329    jbd2__journal_start     vmlinux EXPORT_SYMBOL
+-0x838a3169    pm_qos_request_active   vmlinux EXPORT_SYMBOL_GPL
+-0xbf7fd2f5    schedule_timeout_killable       vmlinux EXPORT_SYMBOL
+-0xd9c4cec4    sock_no_getname vmlinux EXPORT_SYMBOL
+-0x24678be3    snd_pcm_lib_readv       vmlinux EXPORT_SYMBOL
+-0x292a0b74    vfs_link        vmlinux EXPORT_SYMBOL
+-0x85050965    __irq_alloc_descs       vmlinux EXPORT_SYMBOL_GPL
+-0xe3e7dba0    from_kuid_munged        vmlinux EXPORT_SYMBOL
+-0x582bb484    call_usermodehelper_setup       vmlinux EXPORT_SYMBOL
+-0xe52c5e63    v4l2_event_subscribe    vmlinux EXPORT_SYMBOL_GPL
+-0xcd0fc417    drm_ht_just_insert_please       vmlinux EXPORT_SYMBOL
+-0xdacbc24d    netlink_rcv_skb vmlinux EXPORT_SYMBOL
+-0x33d23d14    sk_unattached_filter_create     vmlinux EXPORT_SYMBOL_GPL
+-0x1f07ae8f    crypto_alloc_pcomp      vmlinux EXPORT_SYMBOL_GPL
+-0x2447533c    ktime_get_real  vmlinux EXPORT_SYMBOL_GPL
+-0x68869bae    panic_notifier_list     vmlinux EXPORT_SYMBOL
+-0xdae1eb6a    of_clk_src_onecell_get  vmlinux EXPORT_SYMBOL_GPL
+-0x3444d892    phy_driver_unregister   vmlinux EXPORT_SYMBOL
+-0x107b31ec    __xfrm_state_delete     vmlinux EXPORT_SYMBOL
+-0x4e6165cf    d_delete        vmlinux EXPORT_SYMBOL
+-0x5f0e672b    find_get_pages_tag      vmlinux EXPORT_SYMBOL
+-0xc8fd727e    mod_timer       vmlinux EXPORT_SYMBOL
+-0xd2fe47b1    rndis_set_host_mac      vmlinux EXPORT_SYMBOL
+-0xd768e985    regulator_has_full_constraints  vmlinux EXPORT_SYMBOL_GPL
+-0x82f776b7    gpio_export     vmlinux EXPORT_SYMBOL_GPL
+-0xdf401846    idr_remove      vmlinux EXPORT_SYMBOL
+-0x29baff70    ida_remove      vmlinux EXPORT_SYMBOL
+-0x220b4b23    mnt_set_expiry  vmlinux EXPORT_SYMBOL
+-0x3dd9c200    use_mm  vmlinux EXPORT_SYMBOL_GPL
+-0x2d41e6f5    __trace_puts    vmlinux EXPORT_SYMBOL_GPL
+-0x5143c678    param_get_invbool       vmlinux EXPORT_SYMBOL
+-0x914a1c17    ip_tunnel_newlink       vmlinux EXPORT_SYMBOL_GPL
+-0xc5b6b555    genl_notify     vmlinux EXPORT_SYMBOL
+-0xada52470    wm_hubs_hpl_mux vmlinux EXPORT_SYMBOL_GPL
+-0x9393c812    add_page_wait_queue     vmlinux EXPORT_SYMBOL_GPL
+-0xb16abad2    devm_rtc_device_register        vmlinux EXPORT_SYMBOL_GPL
+-0xbd92ef65    devres_destroy  vmlinux EXPORT_SYMBOL_GPL
+-0x1297fa08    tty_hangup      vmlinux EXPORT_SYMBOL
+-0x580c94d2    seq_put_decimal_ll      vmlinux EXPORT_SYMBOL
+-0xb22596e0    devm_rtc_device_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0x1b95d5c1    mdiobus_read    vmlinux EXPORT_SYMBOL
+-0xea59b757    pm_runtime_forbid       vmlinux EXPORT_SYMBOL_GPL
+-0x30e74134    tty_termios_copy_hw     vmlinux EXPORT_SYMBOL
+-0x4455e1b3    regulator_disable_deferred      vmlinux EXPORT_SYMBOL_GPL
+-0x8e322129    dma_release_channel     vmlinux EXPORT_SYMBOL_GPL
+-0xcfd9a2c0    des_ekey        vmlinux EXPORT_SYMBOL_GPL
+-0x66c78bd2    irq_domain_remove       vmlinux EXPORT_SYMBOL_GPL
+-0x640c2da8    devm_clk_get    vmlinux EXPORT_SYMBOL
+-0xd02c73c7    drm_dp_link_train_clock_recovery_delay  vmlinux EXPORT_SYMBOL
+-0x2be0f12d    dql_completed   vmlinux EXPORT_SYMBOL
+-0xad3f5f91    read_cache_page vmlinux EXPORT_SYMBOL
+-0x4ca90996    rndis_signal_disconnect vmlinux EXPORT_SYMBOL
+-0x917229dc    drm_irq_install vmlinux EXPORT_SYMBOL
+-0x787bcffe    con_is_bound    vmlinux EXPORT_SYMBOL
+-0xefb6eb3f    dev_change_flags        vmlinux EXPORT_SYMBOL
+-0x0e352145    __skb_gso_segment       vmlinux EXPORT_SYMBOL
+-0xa5d14a5e    xfrm_state_walk vmlinux EXPORT_SYMBOL
+-0x6a0ae2ec    nla_put_nohdr   vmlinux EXPORT_SYMBOL
+-0x0411124a    pid_nr_ns       vmlinux EXPORT_SYMBOL_GPL
+-0x2133271d    phy_scan_fixups vmlinux EXPORT_SYMBOL
+-0x64d233c8    ioremap_page    vmlinux EXPORT_SYMBOL
+-0x8fea24bd    bt_sock_unregister      vmlinux EXPORT_SYMBOL
+-0x16c3cf65    napi_gro_flush  vmlinux EXPORT_SYMBOL
+-0xf001dc80    irq_domain_add_linear   vmlinux EXPORT_SYMBOL_GPL
+-0xec069709    scsi_set_medium_removal vmlinux EXPORT_SYMBOL
+-0xc0a98385    profile_pc      vmlinux EXPORT_SYMBOL
+-0x79a2f120    snd_timer_resolution    vmlinux EXPORT_SYMBOL
+-0x46c67b94    jbd2_journal_wipe       vmlinux EXPORT_SYMBOL
+-0x444f1735    cpu_pm_register_notifier        vmlinux EXPORT_SYMBOL_GPL
+-0xcc85fcb6    async_schedule  vmlinux EXPORT_SYMBOL_GPL
+-0x9caf61d6    __nla_put       vmlinux EXPORT_SYMBOL
+-0x4c2ae700    strnstr vmlinux EXPORT_SYMBOL
+-0x07bf12c5    perf_pmu_migrate_context        vmlinux EXPORT_SYMBOL_GPL
+-0x4268de2e    __css_put       vmlinux EXPORT_SYMBOL_GPL
+-0x32fdb1ea    usb_block_urb   vmlinux EXPORT_SYMBOL_GPL
+-0xd76e3ec9    fb_set_var      vmlinux EXPORT_SYMBOL
+-0x7c0643d0    inet_diag_register      vmlinux EXPORT_SYMBOL_GPL
+-0x598542b2    _raw_spin_lock_irqsave  vmlinux EXPORT_SYMBOL
+-0xd468cd0b    sdhci_pltfm_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0x44f93f86    vb2_ops_wait_finish     vmlinux EXPORT_SYMBOL_GPL
+-0x5be57447    dma_buf_kmap_atomic     vmlinux EXPORT_SYMBOL_GPL
+-0xfac68eba    arm_elf_read_implies_exec       vmlinux EXPORT_SYMBOL
+-0xca1e6f11    tcp_done        vmlinux EXPORT_SYMBOL_GPL
+-0x885f07c4    snd_pcm_hw_rule_add     vmlinux EXPORT_SYMBOL
+-0xb1c0c1c2    async_schedule_domain   vmlinux EXPORT_SYMBOL_GPL
+-0x65497c9a    wm8994_bulk_write       vmlinux EXPORT_SYMBOL_GPL
+-0x2fb6de5d    add_device_randomness   vmlinux EXPORT_SYMBOL
+-0xda8af7ad    fb_find_nearest_mode    vmlinux EXPORT_SYMBOL
+-0x0a575945    xfrm_count_pfkey_auth_supported vmlinux EXPORT_SYMBOL_GPL
+-0x3b91f3af    snd_free_pages  vmlinux EXPORT_SYMBOL
+-0xdf2278c1    snd_card_file_remove    vmlinux EXPORT_SYMBOL
+-0xc848d220    blk_free_tags   vmlinux EXPORT_SYMBOL
+-0xff492454    security_inode_getsecctx        vmlinux EXPORT_SYMBOL
+-0xce46e140    ktime_get_ts    vmlinux EXPORT_SYMBOL_GPL
+-0x3b0d157a    v4l2_m2m_ioctl_querybuf vmlinux EXPORT_SYMBOL_GPL
+-0x054177ad    usb_init_urb    vmlinux EXPORT_SYMBOL_GPL
+-0x1ad1f2e7    _memcpy_fromio  vmlinux EXPORT_SYMBOL
+-0x95dbe078    __get_user_2    vmlinux EXPORT_SYMBOL
+-0xb9acd3d9    __put_user_2    vmlinux EXPORT_SYMBOL
+-0xf3797152    snd_interval_ratnum     vmlinux EXPORT_SYMBOL
+-0x9d2edcd6    map_vm_area     vmlinux EXPORT_SYMBOL_GPL
+-0xbfd8d187    balloon_page_enqueue    vmlinux EXPORT_SYMBOL_GPL
+-0xb7e3198c    balloon_page_dequeue    vmlinux EXPORT_SYMBOL_GPL
+-0x0084e86d    unregister_shrinker     vmlinux EXPORT_SYMBOL
+-0x23424fab    usb_hcd_unmap_urb_setup_for_dma vmlinux EXPORT_SYMBOL_GPL
+-0x6c06c6f7    scsi_device_get vmlinux EXPORT_SYMBOL
+-0x970b4c98    scsi_device_put vmlinux EXPORT_SYMBOL
+-0x66109b05    __pm_runtime_set_status vmlinux EXPORT_SYMBOL_GPL
+-0x6d134a2a    drm_prime_sg_to_page_addr_arrays        vmlinux EXPORT_SYMBOL
+-0xbce458b3    drm_framebuffer_reference       vmlinux EXPORT_SYMBOL
+-0xa773e935    ipv6_dev_get_saddr      vmlinux EXPORT_SYMBOL
+-0x38308727    xfrm_policy_flush       vmlinux EXPORT_SYMBOL
+-0x6ebf58d8    skb_tx_error    vmlinux EXPORT_SYMBOL
+-0xea793efe    snd_soc_cache_sync      vmlinux EXPORT_SYMBOL_GPL
+-0xb8aa2342    __check_region  vmlinux EXPORT_SYMBOL
+-0x99638333    mmc_set_blocklen        vmlinux EXPORT_SYMBOL
+-0xc5e4da95    pn_sock_hash    vmlinux EXPORT_SYMBOL
+-0xf6388c56    sysctl_ip_default_ttl   vmlinux EXPORT_SYMBOL
+-0x0e7c2436    napi_gro_frags  vmlinux EXPORT_SYMBOL
+-0x217dda13    flex_array_get  vmlinux EXPORT_SYMBOL
+-0x09437748    ring_buffer_read_events_cpu     vmlinux EXPORT_SYMBOL_GPL
+-0xb974ccc1    inet_diag_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0x0423031f    sock_sendmsg    vmlinux EXPORT_SYMBOL
+-0xade88e76    snd_malloc_pages        vmlinux EXPORT_SYMBOL
+-0x7ca50cfa    disk_get_part   vmlinux EXPORT_SYMBOL_GPL
+-0xfed4d591    cfg80211_find_vendor_ie vmlinux EXPORT_SYMBOL
+-0xe45ee6f0    netlink_kernel_release  vmlinux EXPORT_SYMBOL
+-0xf310e4d9    __sock_create   vmlinux EXPORT_SYMBOL
+-0x4153512b    snd_hwdep_new   vmlinux EXPORT_SYMBOL
+-0x1afae5e7    down_interruptible      vmlinux EXPORT_SYMBOL
+-0x2051f1d8    rtc_set_mmss    vmlinux EXPORT_SYMBOL_GPL
+-0x23dfa3ab    netif_carrier_off       vmlinux EXPORT_SYMBOL
+-0x10895a2a    lease_get_mtime vmlinux EXPORT_SYMBOL
+-0x7cd8f487    sb_set_blocksize        vmlinux EXPORT_SYMBOL
+-0x0effeb6c    srcu_barrier    vmlinux EXPORT_SYMBOL_GPL
+-0xf3de55df    mmc_request_done        vmlinux EXPORT_SYMBOL
+-0x46074c17    sdev_evt_alloc  vmlinux EXPORT_SYMBOL_GPL
+-0x17077530    pinctrl_force_default   vmlinux EXPORT_SYMBOL_GPL
+-0x0d40713a    snd_ctl_boolean_stereo_info     vmlinux EXPORT_SYMBOL
+-0x3744cf36    vmalloc_to_pfn  vmlinux EXPORT_SYMBOL
+-0xc783b0e1    get_task_mm     vmlinux EXPORT_SYMBOL_GPL
+-0xa8950567    sdio_writew     vmlinux EXPORT_SYMBOL_GPL
+-0xca443371    inet_csk_prepare_forced_close   vmlinux EXPORT_SYMBOL
+-0x252f76b5    snd_soc_default_readable_register       vmlinux EXPORT_SYMBOL_GPL
+-0x551bd071    __rb_erase_color        vmlinux EXPORT_SYMBOL
+-0xfff8d451    fuse_request_send       vmlinux EXPORT_SYMBOL_GPL
+-0x88b5647c    trace_clock_local       vmlinux EXPORT_SYMBOL_GPL
+-0x683928de    nf_ct_expect_put        vmlinux EXPORT_SYMBOL_GPL
+-0x7c96bf14    register_tcf_proto_ops  vmlinux EXPORT_SYMBOL
+-0x76aea351    crypto_unregister_alg   vmlinux EXPORT_SYMBOL_GPL
+-0x5c24f853    dump_write      vmlinux EXPORT_SYMBOL
+-0x89485687    iommu_group_put vmlinux EXPORT_SYMBOL_GPL
+-0x00f4d0cf    iommu_group_get vmlinux EXPORT_SYMBOL_GPL
+-0xb4626765    v4l2_ctrl_new_custom    vmlinux EXPORT_SYMBOL
+-0x511746c1    dump_fpu        vmlinux EXPORT_SYMBOL
+-0x28927989    qdisc_watchdog_schedule_ns      vmlinux EXPORT_SYMBOL
+-0x57fec35a    fuse_conn_get   vmlinux EXPORT_SYMBOL_GPL
+-0xff3f1877    filp_open       vmlinux EXPORT_SYMBOL
+-0x7cb7e8a5    generic_file_aio_write  vmlinux EXPORT_SYMBOL
+-0x1d9317d8    smpboot_register_percpu_thread  vmlinux EXPORT_SYMBOL_GPL
+-0x426362dc    __class_create  vmlinux EXPORT_SYMBOL_GPL
+-0xebd6ff6e    xfrm6_prepare_output    vmlinux EXPORT_SYMBOL
+-0x7c30b8c7    xfrm_calg_get_byname    vmlinux EXPORT_SYMBOL_GPL
+-0xf23624a6    xfrm4_prepare_output    vmlinux EXPORT_SYMBOL
+-0x6e88e56f    snd_pcm_link_rwlock     vmlinux EXPORT_SYMBOL
+-0x2ebe3135    cpu_is_hotpluggable     vmlinux EXPORT_SYMBOL_GPL
+-0xd3dbfbc4    _find_first_zero_bit_le vmlinux EXPORT_SYMBOL
+-0x949f7fd6    snd_soc_unregister_codec        vmlinux EXPORT_SYMBOL_GPL
+-0x66b5d30a    get_disk        vmlinux EXPORT_SYMBOL
+-0xd5c3ad66    blk_pm_runtime_init     vmlinux EXPORT_SYMBOL
+-0x55737546    __free_pages    vmlinux EXPORT_SYMBOL
+-0xfa012fe7    tracepoint_probe_register       vmlinux EXPORT_SYMBOL_GPL
+-0xf8802492    print_stack_trace       vmlinux EXPORT_SYMBOL_GPL
+-0x50601122    of_property_match_string        vmlinux EXPORT_SYMBOL_GPL
+-0x70fde9b2    vb2_reqbufs     vmlinux EXPORT_SYMBOL_GPL
+-0x9b680a42    ump_dd_reference_release        vmlinux EXPORT_SYMBOL
+-0x13d5d619    cfg80211_crit_proto_stopped     vmlinux EXPORT_SYMBOL
+-0xd5a7d477    inet_bind       vmlinux EXPORT_SYMBOL
+-0xc5495840    nf_nat_amanda_hook      vmlinux EXPORT_SYMBOL_GPL
+-0xe08e58c9    qdisc_watchdog_init     vmlinux EXPORT_SYMBOL
+-0xe447fb89    __register_binfmt       vmlinux EXPORT_SYMBOL
+-0xbd3321ae    power_supply_class      vmlinux EXPORT_SYMBOL_GPL
+-0x0ce6d0b9    usb_gadget_probe_driver vmlinux EXPORT_SYMBOL_GPL
+-0xae544f3a    usb_hcd_end_port_resume vmlinux EXPORT_SYMBOL_GPL
+-0x8fd8a453    pm_genpd_dev_need_restore       vmlinux EXPORT_SYMBOL_GPL
+-0x7b95ab7d    class_find_device       vmlinux EXPORT_SYMBOL_GPL
+-0x21455002    xfrm_init_state vmlinux EXPORT_SYMBOL
+-0xf06e724d    snd_pcm_debug_name      vmlinux EXPORT_SYMBOL
+-0x89ca47bf    kstrtos8_from_user      vmlinux EXPORT_SYMBOL
+-0x68d0d389    crypto_init_spawn2      vmlinux EXPORT_SYMBOL_GPL
+-0x01c6cb0c    cpu_cluster_pm_enter    vmlinux EXPORT_SYMBOL_GPL
+-0xd1efa60f    st_accel_common_remove  vmlinux EXPORT_SYMBOL
+-0xf398c9eb    vb2_create_bufs vmlinux EXPORT_SYMBOL_GPL
+-0xc385cb58    perf_num_counters       vmlinux EXPORT_SYMBOL_GPL
+-0x87634adf    xfrm_user_policy        vmlinux EXPORT_SYMBOL
+-0xe0741a0a    netif_napi_add  vmlinux EXPORT_SYMBOL
+-0xf12cddd6    skb_split       vmlinux EXPORT_SYMBOL
+-0xdee12a28    input_grab_device       vmlinux EXPORT_SYMBOL
+-0x95e73973    tty_port_block_til_ready        vmlinux EXPORT_SYMBOL
+-0x53a3e486    regulator_get_current_limit     vmlinux EXPORT_SYMBOL_GPL
+-0x5dd18380    regulator_get_init_drvdata      vmlinux EXPORT_SYMBOL_GPL
+-0x8467a73f    netlink_broadcast       vmlinux EXPORT_SYMBOL
+-0x6d1a8997    block_write_full_page_endio     vmlinux EXPORT_SYMBOL
+-0x197519cc    shmem_file_setup        vmlinux EXPORT_SYMBOL_GPL
+-0x8b8059bd    in_group_p      vmlinux EXPORT_SYMBOL
+-0xc631580a    console_unlock  vmlinux EXPORT_SYMBOL
+-0xe8400441    of_property_read_string_index   vmlinux EXPORT_SYMBOL_GPL
+-0x0343bdf1    __i2c_board_list        vmlinux EXPORT_SYMBOL_GPL
+-0xa5dd6fae    arm_pm_restart  vmlinux EXPORT_SYMBOL_GPL
+-0x97fe8a2d    udp_sendmsg     vmlinux EXPORT_SYMBOL
+-0x35fbd6a1    __kfifo_dma_out_prepare_r       vmlinux EXPORT_SYMBOL
+-0xa3e220e7    elv_rb_former_request   vmlinux EXPORT_SYMBOL
+-0xdf76bbeb    iio_pollfunc_store_time vmlinux EXPORT_SYMBOL
+-0xfc30d3a1    mmc_start_req   vmlinux EXPORT_SYMBOL
+-0xf53d4c26    qdisc_class_hash_destroy        vmlinux EXPORT_SYMBOL
+-0x5e61da38    snd_timer_stop  vmlinux EXPORT_SYMBOL
+-0xa6e1a69d    kick_all_cpus_sync      vmlinux EXPORT_SYMBOL_GPL
+-0x68cb9861    sdio_register_driver    vmlinux EXPORT_SYMBOL_GPL
+-0xb575c1a1    usb_kill_urb    vmlinux EXPORT_SYMBOL_GPL
+-0x8ab265d2    usb_get_intf    vmlinux EXPORT_SYMBOL_GPL
+-0xdbd7794d    cfg80211_ready_on_channel       vmlinux EXPORT_SYMBOL
+-0xff112bd5    proc_get_parent_data    vmlinux EXPORT_SYMBOL_GPL
+-0x0bec8a3d    audit_log       vmlinux EXPORT_SYMBOL
+-0x5d9521f8    set_security_override_from_ctx  vmlinux EXPORT_SYMBOL
+-0x235d1d10    drm_gem_prime_import    vmlinux EXPORT_SYMBOL
+-0x7da24ff0    drm_helper_encoder_in_use       vmlinux EXPORT_SYMBOL
+-0x6f3c606d    nfc_hci_register_device vmlinux EXPORT_SYMBOL
+-0xf447e205    ip_tunnel_uninit        vmlinux EXPORT_SYMBOL_GPL
+-0x5055493c    sk_wait_data    vmlinux EXPORT_SYMBOL
+-0xb1b87423    crypto_remove_spawns    vmlinux EXPORT_SYMBOL_GPL
+-0x4fd4e89d    ring_buffer_empty_cpu   vmlinux EXPORT_SYMBOL_GPL
+-0xaa4704e1    usb_autopm_put_interface_no_suspend     vmlinux EXPORT_SYMBOL_GPL
+-0x50e28c07    drm_edid_to_sad vmlinux EXPORT_SYMBOL
+-0x6d57e7f8    drm_edid_to_eld vmlinux EXPORT_SYMBOL
+-0x3fe12ddc    xt_replace_table        vmlinux EXPORT_SYMBOL_GPL
+-0x9c3737fc    __percpu_counter_init   vmlinux EXPORT_SYMBOL
+-0xf846506f    irq_set_affinity_notifier       vmlinux EXPORT_SYMBOL_GPL
+-0x469a0b25    inet_hashinfo_init      vmlinux EXPORT_SYMBOL_GPL
+-0x3fbf68bd    ipv4_sk_redirect        vmlinux EXPORT_SYMBOL_GPL
+-0x151bc10b    end_buffer_read_sync    vmlinux EXPORT_SYMBOL
+-0xb013af25    set_cpus_allowed_ptr    vmlinux EXPORT_SYMBOL_GPL
+-0x227badd6    mod_timer_pinned        vmlinux EXPORT_SYMBOL
+-0xf37cfbf5    dm_dispatch_request     vmlinux EXPORT_SYMBOL_GPL
+-0x1d96bf04    input_mt_report_pointer_emulation       vmlinux EXPORT_SYMBOL
+-0x94289922    mali_pmu_powerdown      vmlinux EXPORT_SYMBOL
+-0xe9d6e0bd    pwm_request     vmlinux EXPORT_SYMBOL_GPL
+-0xd66a2750    tcf_em_tree_dump        vmlinux EXPORT_SYMBOL
+-0x790c22d3    neigh_for_each  vmlinux EXPORT_SYMBOL
+-0x3ed096c1    sg_miter_next   vmlinux EXPORT_SYMBOL
+-0x96b878b6    crypto_init_shash_spawn vmlinux EXPORT_SYMBOL_GPL
+-0x1fd19684    crypto_init_ahash_spawn vmlinux EXPORT_SYMBOL_GPL
+-0xedc85914    posix_timers_register_clock     vmlinux EXPORT_SYMBOL_GPL
+-0xc702156b    param_get_ushort        vmlinux EXPORT_SYMBOL
+-0x65bca4ff    vb2_plane_cookie        vmlinux EXPORT_SYMBOL_GPL
+-0x294a6993    rtc_initialize_alarm    vmlinux EXPORT_SYMBOL_GPL
+-0x6971447a    rtc_month_days  vmlinux EXPORT_SYMBOL
+-0x7e64181d    usb_calc_bus_time       vmlinux EXPORT_SYMBOL_GPL
+-0x5f1f36bc    drm_calc_vbltimestamp_from_scanoutpos   vmlinux EXPORT_SYMBOL
+-0xe0af2dc1    regulator_is_enabled_regmap     vmlinux EXPORT_SYMBOL_GPL
+-0x57c3621e    skb_pull        vmlinux EXPORT_SYMBOL
+-0xeb0a7f4c    clk_register    vmlinux EXPORT_SYMBOL_GPL
+-0xabc6dd63    cpufreq_sysfs_create_file       vmlinux EXPORT_SYMBOL
+-0x1eee0a80    usb_find_interface      vmlinux EXPORT_SYMBOL_GPL
+-0xb524d8dc    amba_find_device        vmlinux EXPORT_SYMBOL
+-0x8574ca6c    gpio_request_array      vmlinux EXPORT_SYMBOL_GPL
+-0x93d2422d    snmp_mib_free   vmlinux EXPORT_SYMBOL_GPL
+-0x5d51bcf7    scatterwalk_start       vmlinux EXPORT_SYMBOL_GPL
+-0x417e3755    sysfs_put       vmlinux EXPORT_SYMBOL_GPL
+-0x2ba54bff    irq_remove_generic_chip vmlinux EXPORT_SYMBOL_GPL
+-0x420c729a    vb2_fop_poll    vmlinux EXPORT_SYMBOL_GPL
+-0xe6d23987    phy_start_interrupts    vmlinux EXPORT_SYMBOL
+-0x1fb1615f    spi_master_resume       vmlinux EXPORT_SYMBOL_GPL
+-0xcd721bb7    scsi_get_vpd_page       vmlinux EXPORT_SYMBOL_GPL
+-0xac2bd611    pm_generic_restore_noirq        vmlinux EXPORT_SYMBOL_GPL
+-0xe0b7aa47    drm_i2c_encoder_dpms    vmlinux EXPORT_SYMBOL
+-0x9dfdf722    gpio_free_array vmlinux EXPORT_SYMBOL_GPL
+-0x7345660c    xfrm_state_check_expire vmlinux EXPORT_SYMBOL
+-0xd5dba10e    sock_diag_unregister_inet_compat        vmlinux EXPORT_SYMBOL_GPL
+-0xfd719be0    netdev_boot_setup_check vmlinux EXPORT_SYMBOL
+-0xa9c6e543    sock_i_uid      vmlinux EXPORT_SYMBOL
+-0x2dfe841c    sock_i_ino      vmlinux EXPORT_SYMBOL
+-0x4bc2dc22    seq_bitmap      vmlinux EXPORT_SYMBOL
+-0x4b8e839a    cpufreq_global_kobject  vmlinux EXPORT_SYMBOL
+-0xc12cf8f8    v4l2_ctrl_replace       vmlinux EXPORT_SYMBOL
+-0xf3dd036d    regulator_set_voltage_time      vmlinux EXPORT_SYMBOL_GPL
+-0x88826167    ip_build_and_send_pkt   vmlinux EXPORT_SYMBOL_GPL
+-0xd09ce8d0    register_gifconf        vmlinux EXPORT_SYMBOL
+-0xaa6901ac    __kfifo_out_r   vmlinux EXPORT_SYMBOL
+-0x64f7667b    crypto_rng_type vmlinux EXPORT_SYMBOL_GPL
+-0x457594fa    crypto_alg_list vmlinux EXPORT_SYMBOL_GPL
+-0x665b8183    sync_inode_metadata     vmlinux EXPORT_SYMBOL
+-0x03026722    mempool_alloc   vmlinux EXPORT_SYMBOL
+-0x0034f927    unregister_wide_hw_breakpoint   vmlinux EXPORT_SYMBOL_GPL
+-0x86f6b99d    synchronize_rcu_expedited       vmlinux EXPORT_SYMBOL_GPL
+-0xec4d9e3a    clk_get_sys     vmlinux EXPORT_SYMBOL
+-0x1b6b3f33    cpufreq_unregister_driver       vmlinux EXPORT_SYMBOL_GPL
+-0x56ca80ea    drm_mode_validate_clocks        vmlinux EXPORT_SYMBOL
+-0xa66a1f63    drm_rmmap_locked        vmlinux EXPORT_SYMBOL
+-0x6b07a31b    regulator_get_voltage_sel_regmap        vmlinux EXPORT_SYMBOL_GPL
+-0x5107f9ce    gpiochip_find   vmlinux EXPORT_SYMBOL_GPL
+-0x05365f80    cfg80211_cac_event      vmlinux EXPORT_SYMBOL
+-0xc05ac2c8    cfg80211_classify8021d  vmlinux EXPORT_SYMBOL
+-0x92be9264    snd_soc_register_platform       vmlinux EXPORT_SYMBOL_GPL
+-0xfaf79bc2    __srcu_read_lock        vmlinux EXPORT_SYMBOL_GPL
+-0xada5e980    media_entity_pipeline_start     vmlinux EXPORT_SYMBOL_GPL
+-0x74fbf451    drm_mm_init_scan_with_range     vmlinux EXPORT_SYMBOL
+-0xd03c7700    secure_ipv4_port_ephemeral      vmlinux EXPORT_SYMBOL_GPL
+-0x9c9ec2a0    proc_dointvec_minmax    vmlinux EXPORT_SYMBOL
+-0x8d772b8c    v4l2_clk_get    vmlinux EXPORT_SYMBOL
+-0x32680bfc    usb_function_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x6dd8ac23    dev_uc_add_excl vmlinux EXPORT_SYMBOL
+-0xced0fa87    dev_mc_add_excl vmlinux EXPORT_SYMBOL
+-0x51cc09c6    kmalloc_caches  vmlinux EXPORT_SYMBOL
+-0x3ef23944    i2c_bus_type    vmlinux EXPORT_SYMBOL_GPL
+-0x015f6d7d    kmap    vmlinux EXPORT_SYMBOL
+-0x0b9a5c65    icmpv6_send     vmlinux EXPORT_SYMBOL
+-0x6625c30d    blk_queue_make_request  vmlinux EXPORT_SYMBOL
+-0x25dd3b83    sysfs_add_link_to_group vmlinux EXPORT_SYMBOL_GPL
+-0x472d363a    truncate_pagecache_range        vmlinux EXPORT_SYMBOL
+-0x0bf3e830    put_page        vmlinux EXPORT_SYMBOL
+-0x74954462    timecounter_read        vmlinux EXPORT_SYMBOL_GPL
+-0x3aa9f288    iio_channel_get vmlinux EXPORT_SYMBOL_GPL
+-0x1fd6672b    video_device_release_empty      vmlinux EXPORT_SYMBOL
+-0x931dcc9d    usbnet_pause_rx vmlinux EXPORT_SYMBOL_GPL
+-0x4c83a264    do_take_over_console    vmlinux EXPORT_SYMBOL_GPL
+-0xe2dd67e5    regulator_set_current_limit     vmlinux EXPORT_SYMBOL_GPL
+-0xb23f3373    nf_conntrack_lock       vmlinux EXPORT_SYMBOL_GPL
+-0xebfa66fa    security_inode_setsecctx        vmlinux EXPORT_SYMBOL
+-0x819ed3be    vfs_getattr     vmlinux EXPORT_SYMBOL
+-0x2fad0dbe    led_classdev_resume     vmlinux EXPORT_SYMBOL_GPL
+-0xbc497919    rtc_device_register     vmlinux EXPORT_SYMBOL_GPL
+-0xd58c665a    input_reset_device      vmlinux EXPORT_SYMBOL
+-0x34c728d0    tty_ldisc_deref vmlinux EXPORT_SYMBOL_GPL
+-0xfb28827b    inet_del_protocol       vmlinux EXPORT_SYMBOL
+-0x95587915    neigh_update    vmlinux EXPORT_SYMBOL
+-0xc9b8c308    __kfifo_dma_out_prepare vmlinux EXPORT_SYMBOL
+-0xd9b9b70a    put_io_context  vmlinux EXPORT_SYMBOL
+-0xac7726b4    blk_queue_io_min        vmlinux EXPORT_SYMBOL
+-0xcf807506    nobh_truncate_page      vmlinux EXPORT_SYMBOL
+-0x43ec231b    iio_device_free vmlinux EXPORT_SYMBOL
+-0x95ae5064    phy_stop        vmlinux EXPORT_SYMBOL
+-0xb69d1c51    spi_bitbang_start       vmlinux EXPORT_SYMBOL_GPL
+-0x87876bed    drm_kms_helper_poll_enable      vmlinux EXPORT_SYMBOL
+-0x045072cd    nf_ct_port_nla_policy   vmlinux EXPORT_SYMBOL_GPL
+-0x4be7fb63    up      vmlinux EXPORT_SYMBOL
+-0xf8a32b55    icmp_send       vmlinux EXPORT_SYMBOL
+-0x69f7d81d    path_get        vmlinux EXPORT_SYMBOL
+-0xd715763b    iov_iter_copy_from_user_atomic  vmlinux EXPORT_SYMBOL
+-0xc7b9fe08    drm_property_create_bitmask     vmlinux EXPORT_SYMBOL
+-0x671a649b    xfrm_state_update       vmlinux EXPORT_SYMBOL
+-0xce3c5240    crypto_grab_aead        vmlinux EXPORT_SYMBOL_GPL
+-0xb590822d    hrtimer_start   vmlinux EXPORT_SYMBOL_GPL
+-0xaebe783e    get_pid_task    vmlinux EXPORT_SYMBOL_GPL
+-0xa8bcfa1a    usb_deregister_dev      vmlinux EXPORT_SYMBOL_GPL
+-0xc398c5f3    usb_hcd_is_primary_hcd  vmlinux EXPORT_SYMBOL_GPL
+-0x7c45fec1    pm_generic_resume_noirq vmlinux EXPORT_SYMBOL_GPL
+-0x6c702af7    sysctl_udp_rmem_min     vmlinux EXPORT_SYMBOL
+-0x9b3122cd    dev_open        vmlinux EXPORT_SYMBOL
+-0x7ee7a9f8    lock_sock_fast  vmlinux EXPORT_SYMBOL
+-0xc3b7e3fb    snd_cards       vmlinux EXPORT_SYMBOL
+-0x82bbf933    ilookup vmlinux EXPORT_SYMBOL
+-0x4302d0eb    free_pages      vmlinux EXPORT_SYMBOL
+-0xefc91531    irq_create_of_mapping   vmlinux EXPORT_SYMBOL_GPL
+-0xb90f9844    sdhci_resume_host       vmlinux EXPORT_SYMBOL_GPL
+-0x8ec22c0b    nat_q931_hook   vmlinux EXPORT_SYMBOL_GPL
+-0x03592ea0    security_unix_stream_connect    vmlinux EXPORT_SYMBOL
+-0x4397c48f    generic_file_fsync      vmlinux EXPORT_SYMBOL
+-0x5154c361    unlock_new_inode        vmlinux EXPORT_SYMBOL
+-0xa9b83487    __f_setown      vmlinux EXPORT_SYMBOL
+-0x9ccb1788    irq_create_direct_mapping       vmlinux EXPORT_SYMBOL_GPL
+-0xf82f16b3    execute_in_process_context      vmlinux EXPORT_SYMBOL_GPL
+-0xcd06de19    mdiobus_free    vmlinux EXPORT_SYMBOL
+-0xfd99623a    ip_frag_ecn_table       vmlinux EXPORT_SYMBOL
+-0x17ee142e    xt_find_table_lock      vmlinux EXPORT_SYMBOL_GPL
+-0x62737e1d    sock_unregister vmlinux EXPORT_SYMBOL
+-0x67095031    kset_register   vmlinux EXPORT_SYMBOL
+-0x84ffea8b    idr_preload     vmlinux EXPORT_SYMBOL
+-0xd29fb507    fput    vmlinux EXPORT_SYMBOL
+-0xe3d6f284    fb_find_mode_cvt        vmlinux EXPORT_SYMBOL
+-0x14d4a9c5    _change_bit     vmlinux EXPORT_SYMBOL
+-0x54411a42    posix_timer_event       vmlinux EXPORT_SYMBOL_GPL
+-0x2a79ac13    clkdev_add      vmlinux EXPORT_SYMBOL
+-0x3d6f446b    platform_device_alloc   vmlinux EXPORT_SYMBOL_GPL
+-0xf85bebf9    dev_printk_emit vmlinux EXPORT_SYMBOL
+-0xde36a037    ip6_frag_init   vmlinux EXPORT_SYMBOL
+-0x31e23d78    __fsnotify_parent       vmlinux EXPORT_SYMBOL_GPL
+-0xdea4fcaa    pm_qos_add_request      vmlinux EXPORT_SYMBOL_GPL
+-0x1976aa06    param_ops_bool  vmlinux EXPORT_SYMBOL
+-0x98ba0e88    pm_generic_suspend_noirq        vmlinux EXPORT_SYMBOL_GPL
+-0xecefd1b6    display_entity_get_params       vmlinux EXPORT_SYMBOL_GPL
+-0xdfb5c1e5    add_disk        vmlinux EXPORT_SYMBOL
+-0x5754706e    media_entity_get        vmlinux EXPORT_SYMBOL_GPL
+-0xbd008b38    media_entity_put        vmlinux EXPORT_SYMBOL_GPL
+-0x5d1e2494    usb_ep0_reinit  vmlinux EXPORT_SYMBOL_GPL
+-0x0ae4b94c    drm_ht_remove   vmlinux EXPORT_SYMBOL
+-0x6ab922b2    regulator_get_drvdata   vmlinux EXPORT_SYMBOL_GPL
+-0x4432d365    __udp6_lib_lookup       vmlinux EXPORT_SYMBOL_GPL
+-0x08696053    inet_shutdown   vmlinux EXPORT_SYMBOL
+-0x52212010    __tracepoint_block_bio_remap    vmlinux EXPORT_SYMBOL_GPL
+-0xc29afc9a    posix_lock_file_wait    vmlinux EXPORT_SYMBOL
+-0x01fd453e    usbhid_lookup_quirk     vmlinux EXPORT_SYMBOL_GPL
+-0x90705b7f    syscon_node_to_regmap   vmlinux EXPORT_SYMBOL_GPL
+-0xf72d56a2    regulator_set_voltage_sel_regmap        vmlinux EXPORT_SYMBOL_GPL
+-0xa308e150    nfc_hci_disconnect_gate vmlinux EXPORT_SYMBOL
+-0x7707c1b0    xt_unregister_table     vmlinux EXPORT_SYMBOL_GPL
+-0x4e830a3e    strnicmp        vmlinux EXPORT_SYMBOL
+-0x48f2cf7c    vmalloc_to_page vmlinux EXPORT_SYMBOL
+-0x3dca446d    drm_handle_vblank       vmlinux EXPORT_SYMBOL
+-0x22ca070b    uart_remove_one_port    vmlinux EXPORT_SYMBOL
+-0x1d027e4b    snd_pcm_format_signed   vmlinux EXPORT_SYMBOL
+-0x3535ae4a    blk_update_request      vmlinux EXPORT_SYMBOL_GPL
+-0x02649054    security_sock_rcv_skb   vmlinux EXPORT_SYMBOL
+-0x547077ec    __wake_up_bit   vmlinux EXPORT_SYMBOL
+-0x1c5541bd    cpufreq_boost_enabled   vmlinux EXPORT_SYMBOL_GPL
+-0x6d186427    usb_get_hcd     vmlinux EXPORT_SYMBOL_GPL
+-0x8eff9111    drm_ht_find_item        vmlinux EXPORT_SYMBOL
+-0xd9d18f03    fbcon_set_bitops        vmlinux EXPORT_SYMBOL
+-0xfaea036f    sock_release    vmlinux EXPORT_SYMBOL
+-0xa414882d    add_wait_queue_exclusive        vmlinux EXPORT_SYMBOL
+-0x06e80ae6    s3c_adc_register        vmlinux EXPORT_SYMBOL_GPL
+-0x63805ac9    usb_hcd_giveback_urb    vmlinux EXPORT_SYMBOL_GPL
+-0xf8d54998    ump_dd_handle_create_from_phys_blocks   vmlinux EXPORT_SYMBOL
+-0x44242685    drm_prime_gem_destroy   vmlinux EXPORT_SYMBOL
+-0x4faff87a    drm_i2c_encoder_mode_fixup      vmlinux EXPORT_SYMBOL
+-0x0f995f4e    tty_port_tty_wakeup     vmlinux EXPORT_SYMBOL_GPL
+-0x91b2790d    regulator_map_voltage_ascend    vmlinux EXPORT_SYMBOL_GPL
+-0x0e29d022    nf_nat_icmp_reply_translation   vmlinux EXPORT_SYMBOL_GPL
+-0x75811312    crc_ccitt_table vmlinux EXPORT_SYMBOL
+-0xe9eb0c04    d_add_ci        vmlinux EXPORT_SYMBOL
+-0x4c55b4df    led_trigger_rename_static       vmlinux EXPORT_SYMBOL_GPL
+-0x6f344bb9    v4l2_calc_aspect_ratio  vmlinux EXPORT_SYMBOL_GPL
+-0xc4f83bea    drm_debugfs_create_files        vmlinux EXPORT_SYMBOL
+-0x9ae51e43    tty_register_device_attr        vmlinux EXPORT_SYMBOL_GPL
+-0x80c70b19    phys_mem_access_prot    vmlinux EXPORT_SYMBOL
+-0x17770200    __skb_checksum_complete_head    vmlinux EXPORT_SYMBOL
+-0x1eeb848e    __percpu_counter_sum    vmlinux EXPORT_SYMBOL
+-0xd74289f9    __percpu_counter_add    vmlinux EXPORT_SYMBOL
+-0xa77a369d    idr_init        vmlinux EXPORT_SYMBOL
+-0x8e5c580a    ida_init        vmlinux EXPORT_SYMBOL
+-0xb99d677c    mpage_readpage  vmlinux EXPORT_SYMBOL
+-0x70bc17d7    inode_wait      vmlinux EXPORT_SYMBOL
+-0xd6ee688f    vmalloc vmlinux EXPORT_SYMBOL
+-0xf31b3fd1    workqueue_set_max_active        vmlinux EXPORT_SYMBOL_GPL
+-0x9745c52a    of_fixed_clk_setup      vmlinux EXPORT_SYMBOL_GPL
+-0xbfd6a20b    phy_ethtool_set_wol     vmlinux EXPORT_SYMBOL
+-0x64004900    phy_ethtool_get_wol     vmlinux EXPORT_SYMBOL
+-0x28492539    spi_bitbang_transfer    vmlinux EXPORT_SYMBOL_GPL
+-0x6552f2d8    unlink_framebuffer      vmlinux EXPORT_SYMBOL
+-0xbdf2580d    __raw_readsl    vmlinux EXPORT_SYMBOL
+-0xabe519d2    blk_queue_io_opt        vmlinux EXPORT_SYMBOL
+-0x05b2af42    bdgrab  vmlinux EXPORT_SYMBOL
+-0xd4c14632    system_unbound_wq       vmlinux EXPORT_SYMBOL_GPL
+-0x098859e1    usbnet_cdc_status       vmlinux EXPORT_SYMBOL_GPL
+-0xd1bd52ba    tty_port_raise_dtr_rts  vmlinux EXPORT_SYMBOL
+-0x4ea1f5a2    drm_gem_object_free     vmlinux EXPORT_SYMBOL
+-0x86d53c76    mb_cache_entry_find_first       vmlinux EXPORT_SYMBOL
+-0xf0b9f940    usb_function_activate   vmlinux EXPORT_SYMBOL_GPL
+-0x9d2ee507    scsi_adjust_queue_depth vmlinux EXPORT_SYMBOL
+-0x4bca6b0c    drm_get_edid    vmlinux EXPORT_SYMBOL
+-0x4a5d2ace    tcp_unregister_congestion_control       vmlinux EXPORT_SYMBOL_GPL
+-0x0274dc2b    netif_get_num_default_rss_queues        vmlinux EXPORT_SYMBOL
+-0x53be6f80    bio_split       vmlinux EXPORT_SYMBOL
+-0x1fc0da41    lock_rename     vmlinux EXPORT_SYMBOL
+-0xbe421975    __locks_copy_lock       vmlinux EXPORT_SYMBOL
+-0x69e3cb9f    mutex_lock_killable     vmlinux EXPORT_SYMBOL
+-0x9c612795    v4l2_chip_match_i2c_client      vmlinux EXPORT_SYMBOL
+-0xd2f84424    i2c_bit_add_bus vmlinux EXPORT_SYMBOL
+-0x421cdcbd    usb_function_deactivate vmlinux EXPORT_SYMBOL_GPL
+-0x63a86872    class_destroy   vmlinux EXPORT_SYMBOL_GPL
+-0x231d4001    fb_edid_add_monspecs    vmlinux EXPORT_SYMBOL
+-0xb01a37d3    gpiochip_remove vmlinux EXPORT_SYMBOL_GPL
+-0xcc2b7257    tcp_check_req   vmlinux EXPORT_SYMBOL
+-0x16270acd    tcp_init_sock   vmlinux EXPORT_SYMBOL
+-0x143dc3b0    netlink_unicast vmlinux EXPORT_SYMBOL
+-0x8452993c    neigh_sysctl_register   vmlinux EXPORT_SYMBOL
+-0xce602df6    cgroup_is_descendant    vmlinux EXPORT_SYMBOL_GPL
+-0xdddba0ab    exynos_g2d_get_ver_ioctl        vmlinux EXPORT_SYMBOL_GPL
+-0xf2c642ed    tty_port_tty_hangup     vmlinux EXPORT_SYMBOL_GPL
+-0x7d086e6f    snd_soc_put_volsw_range vmlinux EXPORT_SYMBOL_GPL
+-0xaf23bb74    snd_soc_get_volsw_range vmlinux EXPORT_SYMBOL_GPL
+-0x01b2facc    snd_timer_start vmlinux EXPORT_SYMBOL
+-0x1e693956    set_nlink       vmlinux EXPORT_SYMBOL
+-0xdcb0349b    sys_close       vmlinux EXPORT_SYMBOL
+-0xaf348da7    cpu_pm_exit     vmlinux EXPORT_SYMBOL_GPL
+-0x77d1afb4    kill_pgrp       vmlinux EXPORT_SYMBOL
+-0x3b9d009a    drm_format_plane_cpp    vmlinux EXPORT_SYMBOL
+-0x2acd3e60    fat_build_inode vmlinux EXPORT_SYMBOL_GPL
+-0x0f3ef271    seq_read        vmlinux EXPORT_SYMBOL
+-0x712fb5a8    is_bad_inode    vmlinux EXPORT_SYMBOL
+-0x253bdb78    param_get_int   vmlinux EXPORT_SYMBOL
+-0xd35fa891    st_sensors_write_event_config   vmlinux EXPORT_SYMBOL
+-0x203bef91    device_wakeup_disable   vmlinux EXPORT_SYMBOL_GPL
+-0xd454eabb    tcf_hash_new_index      vmlinux EXPORT_SYMBOL
+-0x235e7e6a    shash_ahash_finup       vmlinux EXPORT_SYMBOL_GPL
+-0x60384c87    start_tty       vmlinux EXPORT_SYMBOL
+-0x6513a3fa    fb_get_color_depth      vmlinux EXPORT_SYMBOL
+-0x7ffc8718    gpio_set_debounce       vmlinux EXPORT_SYMBOL_GPL
+-0x6c95cbd5    phonet_proto_register   vmlinux EXPORT_SYMBOL
+-0xa01cac38    nf_ct_get_tuplepr       vmlinux EXPORT_SYMBOL_GPL
+-0x3e872db6    __netdev_pick_tx        vmlinux EXPORT_SYMBOL
+-0x981f509d    skb_free_datagram_locked        vmlinux EXPORT_SYMBOL
+-0x93e0379d    kernel_sock_shutdown    vmlinux EXPORT_SYMBOL
+-0x878eae99    snd_pcm_add_chmap_ctls  vmlinux EXPORT_SYMBOL_GPL
+-0xd454865d    snd_pcm_notify  vmlinux EXPORT_SYMBOL
+-0xa735db59    prandom_u32     vmlinux EXPORT_SYMBOL
+-0x8e864a86    posix_acl_chmod vmlinux EXPORT_SYMBOL
+-0xf9910a86    notify_change   vmlinux EXPORT_SYMBOL
+-0x423b589c    follow_up       vmlinux EXPORT_SYMBOL
+-0xa577a850    param_get_short vmlinux EXPORT_SYMBOL
+-0x24b55d2b    of_find_i2c_adapter_by_node     vmlinux EXPORT_SYMBOL
+-0x6d0f1f89    dm_table_get_mode       vmlinux EXPORT_SYMBOL
+-0x2ca4ebcd    regulator_set_drvdata   vmlinux EXPORT_SYMBOL_GPL
+-0x02196324    __aeabi_idiv    vmlinux EXPORT_SYMBOL
+-0xf0e3bec8    nf_log_bind_pf  vmlinux EXPORT_SYMBOL
+-0xd12698d0    skb_copy_and_csum_datagram_iovec        vmlinux EXPORT_SYMBOL
+-0xd23bebab    sock_no_ioctl   vmlinux EXPORT_SYMBOL
+-0xf401a5f4    get_user_pages_fast     vmlinux EXPORT_SYMBOL_GPL
+-0xca85d8cf    tracepoint_probe_update_all     vmlinux EXPORT_SYMBOL_GPL
+-0x54740eb7    get_cpu_idle_time       vmlinux EXPORT_SYMBOL_GPL
+-0x2a3aa678    _test_and_clear_bit     vmlinux EXPORT_SYMBOL
+-0x694967d9    nf_conntrack_find_get   vmlinux EXPORT_SYMBOL_GPL
+-0x19a2badf    snd_soc_codec_set_sysclk        vmlinux EXPORT_SYMBOL_GPL
+-0x93a2419d    simple_empty    vmlinux EXPORT_SYMBOL
+-0x68a13545    vm_mmap vmlinux EXPORT_SYMBOL
+-0x224190b8    shmem_read_mapping_page_gfp     vmlinux EXPORT_SYMBOL_GPL
+-0xd859f1d5    dw_mci_pltfm_register   vmlinux EXPORT_SYMBOL_GPL
+-0xc955c267    serio_unregister_child_port     vmlinux EXPORT_SYMBOL
+-0xcbee09f7    scsi_remove_device      vmlinux EXPORT_SYMBOL
+-0xcd579f54    xfrm_cfg_mutex  vmlinux EXPORT_SYMBOL
+-0xb63be252    __sk_mem_schedule       vmlinux EXPORT_SYMBOL
+-0xcde172ac    radix_tree_gang_lookup_tag_slot vmlinux EXPORT_SYMBOL
+-0x61860fe5    blk_queue_merge_bvec    vmlinux EXPORT_SYMBOL
+-0xd223c00d    fuse_file_poll  vmlinux EXPORT_SYMBOL_GPL
+-0x4b6e004b    mnt_want_write_file     vmlinux EXPORT_SYMBOL_GPL
+-0x11ad8ba6    __hid_register_driver   vmlinux EXPORT_SYMBOL_GPL
+-0x3d8ed8f5    hid_disconnect  vmlinux EXPORT_SYMBOL_GPL
+-0x70cf032f    usb_hcd_irq     vmlinux EXPORT_SYMBOL_GPL
+-0xc0a9a9a1    hci_register_cb vmlinux EXPORT_SYMBOL
+-0x83b21051    ip_ct_attach    vmlinux EXPORT_SYMBOL
+-0x24eb8d39    dev_set_mtu     vmlinux EXPORT_SYMBOL
+-0xbd5c42d9    crypto_unregister_template      vmlinux EXPORT_SYMBOL_GPL
+-0x2deda4a1    security_sk_classify_flow       vmlinux EXPORT_SYMBOL
+-0xe694a9ce    bd_link_disk_holder     vmlinux EXPORT_SYMBOL_GPL
+-0xf1a33551    usb_string_ids_tab      vmlinux EXPORT_SYMBOL_GPL
+-0x565b6892    uuid_le_gen     vmlinux EXPORT_SYMBOL_GPL
+-0x68956406    static_key_slow_dec     vmlinux EXPORT_SYMBOL_GPL
+-0x335c570f    enable_percpu_irq       vmlinux EXPORT_SYMBOL_GPL
+-0x02e1a3ed    should_remove_suid      vmlinux EXPORT_SYMBOL
+-0x0626da5f    od_unregister_powersave_bias_handler    vmlinux EXPORT_SYMBOL_GPL
+-0x4dcfd46b    scsi_free_host_dev      vmlinux EXPORT_SYMBOL
+-0xfec445a3    driver_register vmlinux EXPORT_SYMBOL_GPL
+-0x3d1b2e32    find_lock_page  vmlinux EXPORT_SYMBOL
+-0x92ea202d    srcu_notifier_chain_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0xdb9d11d6    iio_buffer_store_enable vmlinux EXPORT_SYMBOL
+-0x2ceca451    input_ff_create vmlinux EXPORT_SYMBOL_GPL
+-0x6e3d17ac    device_destroy  vmlinux EXPORT_SYMBOL_GPL
+-0xb8d2fd38    wiphy_register  vmlinux EXPORT_SYMBOL
+-0xfa4d8a1f    unregister_pernet_device        vmlinux EXPORT_SYMBOL_GPL
+-0x4c86184b    remove_wait_queue       vmlinux EXPORT_SYMBOL
+-0x4845c423    param_array_ops vmlinux EXPORT_SYMBOL
+-0x2cd6eb8b    input_ff_destroy        vmlinux EXPORT_SYMBOL_GPL
+-0xb9500ec7    mfd_cell_disable        vmlinux EXPORT_SYMBOL
+-0x1a2759ff    platform_get_irq_byname vmlinux EXPORT_SYMBOL_GPL
+-0x8daf9344    napi_get_frags  vmlinux EXPORT_SYMBOL
+-0x60c805dd    sk_stream_write_space   vmlinux EXPORT_SYMBOL
+-0x570e3195    scsi_verify_blk_ioctl   vmlinux EXPORT_SYMBOL
+-0xecbe66b8    sysfs_notify_dirent     vmlinux EXPORT_SYMBOL_GPL
+-0x158df5f3    kill_bdev       vmlinux EXPORT_SYMBOL
+-0x3eb2b460    v4l2_event_unsubscribe  vmlinux EXPORT_SYMBOL_GPL
+-0x8e38bb44    ipv6_dup_options        vmlinux EXPORT_SYMBOL_GPL
+-0xe306f9d8    cgroup_attach_task_all  vmlinux EXPORT_SYMBOL_GPL
+-0x6b06fdce    delayed_work_timer_fn   vmlinux EXPORT_SYMBOL
+-0x8104c3bb    phy_register_fixup_for_id       vmlinux EXPORT_SYMBOL
+-0x46d3b28c    __div0  vmlinux EXPORT_SYMBOL
+-0x7ead817c    __idr_pre_get   vmlinux EXPORT_SYMBOL
+-0x6cc299a1    zap_vma_ptes    vmlinux EXPORT_SYMBOL_GPL
+-0x1f0972cb    drm_fasync      vmlinux EXPORT_SYMBOL
+-0x35c653fb    xfrm_policy_bysel_ctx   vmlinux EXPORT_SYMBOL
+-0x8e81d5af    tcp_sendmsg     vmlinux EXPORT_SYMBOL
+-0xf9ebc368    snd_soc_new_ac97_codec  vmlinux EXPORT_SYMBOL_GPL
+-0x4528c501    elv_rb_del      vmlinux EXPORT_SYMBOL
+-0x056bf03a    elv_rb_add      vmlinux EXPORT_SYMBOL
+-0x5b2c1c77    init_user_ns    vmlinux EXPORT_SYMBOL_GPL
+-0x0b5996ef    st_sensors_sysfs_sampling_frequency_avail       vmlinux EXPORT_SYMBOL
+-0x3a17a800    vb2_dqbuf       vmlinux EXPORT_SYMBOL_GPL
+-0xe55de32d    i2c_smbus_write_word_data       vmlinux EXPORT_SYMBOL
+-0xd1c2d294    ip_mc_leave_group       vmlinux EXPORT_SYMBOL
+-0x05843ade    netif_skb_features      vmlinux EXPORT_SYMBOL
+-0x00632780    work_busy       vmlinux EXPORT_SYMBOL_GPL
+-0x06d2c86e    pm_runtime_set_memalloc_noio    vmlinux EXPORT_SYMBOL_GPL
+-0x97c6c5dd    drm_pci_exit    vmlinux EXPORT_SYMBOL
+-0x1a1938a1    drm_pci_init    vmlinux EXPORT_SYMBOL
+-0xf7a0d470    __sk_mem_reclaim        vmlinux EXPORT_SYMBOL
+-0xc4f45210    d_prune_aliases vmlinux EXPORT_SYMBOL
+-0x498d293a    trace_buffer_unlock_commit      vmlinux EXPORT_SYMBOL_GPL
+-0x12a38747    usleep_range    vmlinux EXPORT_SYMBOL
+-0xef409b74    kmsg_dump_get_line      vmlinux EXPORT_SYMBOL_GPL
+-0xdd3202eb    lcd_device_unregister   vmlinux EXPORT_SYMBOL
+-0x1fa2ae70    tcf_hash_check  vmlinux EXPORT_SYMBOL
+-0xa43b9539    memcpy_fromiovecend     vmlinux EXPORT_SYMBOL
+-0x4b4f96c3    blk_make_request        vmlinux EXPORT_SYMBOL
+-0xe290713d    __pagevec_release       vmlinux EXPORT_SYMBOL
+-0x1e047854    warn_slowpath_fmt       vmlinux EXPORT_SYMBOL
+-0xbca701eb    vb2_ioctl_expbuf        vmlinux EXPORT_SYMBOL_GPL
+-0x01508e49    cfg80211_cqm_rssi_notify        vmlinux EXPORT_SYMBOL
+-0xff3e2712    nla_reserve_nohdr       vmlinux EXPORT_SYMBOL
+-0xc442fa87    ilookup5        vmlinux EXPORT_SYMBOL
+-0x1650bf27    rcutorture_record_progress      vmlinux EXPORT_SYMBOL_GPL
+-0x3507a132    _raw_spin_lock_irq      vmlinux EXPORT_SYMBOL
+-0x1b24bd6e    prepare_creds   vmlinux EXPORT_SYMBOL
+-0x97c03a7e    mutex_unlock    vmlinux EXPORT_SYMBOL
+-0x5bf35318    hid_unregister_driver   vmlinux EXPORT_SYMBOL_GPL
+-0xd989fc54    usb_autopm_put_interface        vmlinux EXPORT_SYMBOL_GPL
+-0x64d3db1a    dev_addr_flush  vmlinux EXPORT_SYMBOL
+-0x6d92d23c    snd_dma_reserve_buf     vmlinux EXPORT_SYMBOL
+-0x83a476ce    bitmap_scnlistprintf    vmlinux EXPORT_SYMBOL
+-0x61660b0f    thermal_notify_framework        vmlinux EXPORT_SYMBOL_GPL
+-0x1e925a2f    drm_unplug_dev  vmlinux EXPORT_SYMBOL
+-0xef76af89    wiphy_rfkill_set_hw_state       vmlinux EXPORT_SYMBOL
+-0x920aacca    nl_table_lock   vmlinux EXPORT_SYMBOL_GPL
+-0x69b0b6dd    blkdev_get_by_dev       vmlinux EXPORT_SYMBOL
+-0xd87601cc    ring_buffer_unlock_commit       vmlinux EXPORT_SYMBOL_GPL
+-0xee7e7bbe    simple_fill_super       vmlinux EXPORT_SYMBOL
+-0xf8fffd67    have_submounts  vmlinux EXPORT_SYMBOL
+-0x07cc4a5d    printk_timed_ratelimit  vmlinux EXPORT_SYMBOL
+-0x274944b3    sock_queue_err_skb      vmlinux EXPORT_SYMBOL
+-0x7b03f66f    snd_add_device_sysfs_file       vmlinux EXPORT_SYMBOL
+-0x1f8db7f9    ring_buffer_overrun_cpu vmlinux EXPORT_SYMBOL_GPL
+-0x0faef0ed    __tasklet_schedule      vmlinux EXPORT_SYMBOL
+-0x8ec68aa9    dev_load        vmlinux EXPORT_SYMBOL
+-0xf4f14de6    rtnl_trylock    vmlinux EXPORT_SYMBOL
+-0xac0ba8c1    blk_iopoll_disable      vmlinux EXPORT_SYMBOL
+-0x1bb201ff    debugfs_create_u16      vmlinux EXPORT_SYMBOL_GPL
+-0xcae7b03f    bio_add_page    vmlinux EXPORT_SYMBOL
+-0x61af42e6    init_pid_ns     vmlinux EXPORT_SYMBOL_GPL
+-0x3c420cae    v4l2_m2m_buf_queue      vmlinux EXPORT_SYMBOL_GPL
+-0x0fa2a45e    __memzero       vmlinux EXPORT_SYMBOL
+-0x674c71f7    ipt_unregister_table    vmlinux EXPORT_SYMBOL
+-0x77ecac9f    zlib_inflateEnd vmlinux EXPORT_SYMBOL
+-0x7ca5798f    contig_page_data        vmlinux EXPORT_SYMBOL
+-0x3b66dc5f    vb2_buffer_done vmlinux EXPORT_SYMBOL_GPL
+-0x07b291d1    usb_unlink_anchored_urbs        vmlinux EXPORT_SYMBOL_GPL
+-0x06fbba42    usbnet_write_cmd        vmlinux EXPORT_SYMBOL_GPL
+-0xc6b4b7b5    inet_frag_evictor       vmlinux EXPORT_SYMBOL
+-0x9d44f8f6    xt_unregister_target    vmlinux EXPORT_SYMBOL
+-0x0dca487b    led_trigger_show        vmlinux EXPORT_SYMBOL_GPL
+-0xb423dba1    console_blanked vmlinux EXPORT_SYMBOL
+-0x23679939    __iowrite32_copy        vmlinux EXPORT_SYMBOL_GPL
+-0x38361fbf    config_group_init_type_name     vmlinux EXPORT_SYMBOL
+-0x668fe138    __sb_end_write  vmlinux EXPORT_SYMBOL
+-0xd67296c6    from_kgid       vmlinux EXPORT_SYMBOL
+-0x2fd8e085    sdhci_pltfm_clk_get_max_clock   vmlinux EXPORT_SYMBOL_GPL
+-0x4222235b    v4l2_fh_is_singular     vmlinux EXPORT_SYMBOL_GPL
+-0x27cbc081    nf_conntrack_unregister_notifier        vmlinux EXPORT_SYMBOL_GPL
+-0x638eeb4d    fib_rules_register      vmlinux EXPORT_SYMBOL_GPL
+-0xfaf98462    bitrev32        vmlinux EXPORT_SYMBOL
+-0x0399203b    simple_transaction_read vmlinux EXPORT_SYMBOL
+-0x8a99a016    mempool_free_slab       vmlinux EXPORT_SYMBOL
+-0x41c72de9    generic_setxattr        vmlinux EXPORT_SYMBOL
+-0x75d94810    generic_getxattr        vmlinux EXPORT_SYMBOL
+-0xe384a102    usb_speed_string        vmlinux EXPORT_SYMBOL_GPL
+-0xf70fecd0    pm_generic_resume_early vmlinux EXPORT_SYMBOL_GPL
+-0x48cb14ac    pm_generic_thaw vmlinux EXPORT_SYMBOL_GPL
+-0x1d061186    cfg80211_connect_result vmlinux EXPORT_SYMBOL
+-0xdd8800ff    jbd2_journal_set_features       vmlinux EXPORT_SYMBOL
+-0xdadafdd7    mpage_readpages vmlinux EXPORT_SYMBOL
+-0x4045c494    filter_match_preds      vmlinux EXPORT_SYMBOL_GPL
+-0x5482fcef    usbnet_start_xmit       vmlinux EXPORT_SYMBOL_GPL
+-0x9e074139    __pm_runtime_resume     vmlinux EXPORT_SYMBOL_GPL
+-0x4df119fa    __bitmap_parse  vmlinux EXPORT_SYMBOL
+-0x2cfc8703    __wait_on_buffer        vmlinux EXPORT_SYMBOL
+-0x4a8907de    cancel_delayed_work_sync        vmlinux EXPORT_SYMBOL
+-0x4c5566c5    extcon_set_cable_state  vmlinux EXPORT_SYMBOL_GPL
+-0x1114ede2    extcon_get_cable_state  vmlinux EXPORT_SYMBOL_GPL
+-0xcac8aaf3    i2c_unlock_adapter      vmlinux EXPORT_SYMBOL_GPL
+-0xc3107f52    regmap_raw_read vmlinux EXPORT_SYMBOL_GPL
+-0x6b807a5f    gpio_sysfs_set_active_low       vmlinux EXPORT_SYMBOL_GPL
+-0xad4d490d    sock_create     vmlinux EXPORT_SYMBOL
+-0x1bcfb1fa    debugfs_create_x32      vmlinux EXPORT_SYMBOL_GPL
+-0xb0440408    bprm_change_interp      vmlinux EXPORT_SYMBOL
+-0xbf7f05c3    kill_litter_super       vmlinux EXPORT_SYMBOL
+-0xcb34aaf6    iommu_domain_window_disable     vmlinux EXPORT_SYMBOL_GPL
+-0x7c9e0f69    clk_add_alias   vmlinux EXPORT_SYMBOL
+-0xad84bef8    dm_table_event  vmlinux EXPORT_SYMBOL
+-0xc91b3468    class_dev_iter_next     vmlinux EXPORT_SYMBOL_GPL
+-0x64038eb3    inet_proto_csum_replace4        vmlinux EXPORT_SYMBOL
+-0xb6e03027    neigh_direct_output     vmlinux EXPORT_SYMBOL
+-0xce9a717b    blk_rq_check_limits     vmlinux EXPORT_SYMBOL_GPL
+-0x75bda77a    seq_hlist_next  vmlinux EXPORT_SYMBOL
+-0xb9c24bba    account_page_dirtied    vmlinux EXPORT_SYMBOL
+-0xde037eaa    __lock_page_killable    vmlinux EXPORT_SYMBOL_GPL
+-0x73c2d5f0    usb_free_urb    vmlinux EXPORT_SYMBOL_GPL
+-0x9faa8d4a    tty_prepare_flip_string_flags   vmlinux EXPORT_SYMBOL_GPL
+-0xb8de9394    tty_prepare_flip_string vmlinux EXPORT_SYMBOL_GPL
+-0x4db0cbcf    fib_rules_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0x5fe6f617    skb_copy_bits   vmlinux EXPORT_SYMBOL
+-0x71bf6cf0    __blk_end_request_all   vmlinux EXPORT_SYMBOL
+-0xede99a14    crypto_register_ahash   vmlinux EXPORT_SYMBOL_GPL
+-0xbdb3fd8c    sysfs_remove_link       vmlinux EXPORT_SYMBOL_GPL
+-0x8924eb1e    rcu_force_quiescent_state       vmlinux EXPORT_SYMBOL_GPL
+-0xe77924e8    drm_match_cea_mode      vmlinux EXPORT_SYMBOL
+-0x189868d7    get_random_bytes_arch   vmlinux EXPORT_SYMBOL
+-0x3aeef779    tcp_make_synack vmlinux EXPORT_SYMBOL
+-0xc1c0b09b    snd_soc_add_codec_controls      vmlinux EXPORT_SYMBOL_GPL
+-0xcc402882    find_get_page   vmlinux EXPORT_SYMBOL
+-0x7d59dd46    pm_wq   vmlinux EXPORT_SYMBOL_GPL
+-0x9a47820d    hrtimer_forward vmlinux EXPORT_SYMBOL_GPL
+-0xa1f0ebea    bit_waitqueue   vmlinux EXPORT_SYMBOL
+-0x52bd048a    iio_get_channel_type    vmlinux EXPORT_SYMBOL_GPL
+-0x37b330b1    mii_check_gmii_support  vmlinux EXPORT_SYMBOL
+-0x964bc3de    dma_async_device_register       vmlinux EXPORT_SYMBOL
+-0x0adc9704    display_timings_release vmlinux EXPORT_SYMBOL_GPL
+-0xe6c818f2    sock_common_recvmsg     vmlinux EXPORT_SYMBOL
+-0xb62a00b3    mem_cgroup_subsys       vmlinux EXPORT_SYMBOL
+-0x64652950    __video_register_device vmlinux EXPORT_SYMBOL
+-0x9572f9d0    inet_csk_addr2sockaddr  vmlinux EXPORT_SYMBOL_GPL
+-0xeda0d76e    gen_estimator_active    vmlinux EXPORT_SYMBOL
+-0x8251bcc3    bitmap_release_region   vmlinux EXPORT_SYMBOL
+-0x5567c227    kernel_cpustat  vmlinux EXPORT_SYMBOL
+-0x9133fe16    vb2_write       vmlinux EXPORT_SYMBOL_GPL
+-0x9bb89701    cfg80211_roamed vmlinux EXPORT_SYMBOL
+-0x5eb03c4c    ip_mc_inc_group vmlinux EXPORT_SYMBOL
+-0x06438115    tcp_orphan_count        vmlinux EXPORT_SYMBOL_GPL
+-0x43804ba2    fat_attach      vmlinux EXPORT_SYMBOL_GPL
+-0x30788c84    sysfs_remove_bin_file   vmlinux EXPORT_SYMBOL_GPL
+-0xb11bad4f    register_wide_hw_breakpoint     vmlinux EXPORT_SYMBOL_GPL
+-0xbd8b253c    tcf_exts_validate       vmlinux EXPORT_SYMBOL
+-0xb81960ca    snprintf        vmlinux EXPORT_SYMBOL
+-0x7cae600c    get_io_context  vmlinux EXPORT_SYMBOL
+-0x70bb651d    __tracepoint_block_rq_remap     vmlinux EXPORT_SYMBOL_GPL
+-0x9be42ea4    proc_mkdir_mode vmlinux EXPORT_SYMBOL
+-0xf0701cc6    tag_pages_for_writeback vmlinux EXPORT_SYMBOL
+-0x3cf525fb    hid_dump_device vmlinux EXPORT_SYMBOL_GPL
+-0x219e9575    wakeup_source_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0xff43d5b5    cfg80211_check_station_change   vmlinux EXPORT_SYMBOL
+-0x2296c00d    crypto_attr_u32 vmlinux EXPORT_SYMBOL_GPL
+-0x710eaf23    PDE_DATA        vmlinux EXPORT_SYMBOL
+-0xc1fac3b3    __bread vmlinux EXPORT_SYMBOL
+-0x55af945f    follow_pfn      vmlinux EXPORT_SYMBOL
+-0x275ae863    make_kuid       vmlinux EXPORT_SYMBOL
+-0x54d8b7ba    hrtimer_init    vmlinux EXPORT_SYMBOL_GPL
+-0x7c8f0303    dma_buf_export_named    vmlinux EXPORT_SYMBOL_GPL
+-0x079f8b38    devm_kzalloc    vmlinux EXPORT_SYMBOL_GPL
+-0x9ddbb3f6    tty_port_link_device    vmlinux EXPORT_SYMBOL_GPL
+-0x9e8d08a7    pinctrl_find_and_add_gpio_range vmlinux EXPORT_SYMBOL_GPL
+-0x9ceb163c    memcpy_toiovec  vmlinux EXPORT_SYMBOL
+-0x44c38935    v4l2_subdev_g_ext_ctrls vmlinux EXPORT_SYMBOL
+-0xc5fab8f0    v4l2_subdev_s_ext_ctrls vmlinux EXPORT_SYMBOL
+-0x4cf092e4    scsi_report_opcode      vmlinux EXPORT_SYMBOL
+-0x1b6314fd    in_aton vmlinux EXPORT_SYMBOL
+-0x1027ae8c    neigh_resolve_output    vmlinux EXPORT_SYMBOL
+-0xc492c2d9    snd_card_register       vmlinux EXPORT_SYMBOL
+-0xa3018431    posix_unblock_lock      vmlinux EXPORT_SYMBOL
+-0xf3d6e3aa    __mnt_is_readonly       vmlinux EXPORT_SYMBOL_GPL
+-0x87984b16    __tracepoint_cpu_idle   vmlinux EXPORT_SYMBOL_GPL
+-0x89205531    cfb_imageblit   vmlinux EXPORT_SYMBOL
+-0x3bbf46ea    vga_base        vmlinux EXPORT_SYMBOL
+-0x6fea34fd    tcp_close       vmlinux EXPORT_SYMBOL
+-0x7bd5c87c    inet_add_offload        vmlinux EXPORT_SYMBOL
+-0x024ea18c    nf_nat_irc_hook vmlinux EXPORT_SYMBOL_GPL
+-0x18d1ab6f    nf_nat_ftp_hook vmlinux EXPORT_SYMBOL_GPL
+-0xeb780f0e    nfq_ct_nat_hook vmlinux EXPORT_SYMBOL_GPL
+-0x06277150    __scm_send      vmlinux EXPORT_SYMBOL
+-0xc49eea50    skb_try_coalesce        vmlinux EXPORT_SYMBOL
+-0xec007de7    snd_soc_dapm_new_controls       vmlinux EXPORT_SYMBOL_GPL
+-0xa07ed110    xz_dec_init     vmlinux EXPORT_SYMBOL
+-0x3dd4d3a7    bprintf vmlinux EXPORT_SYMBOL_GPL
+-0xa4a0aeb8    try_to_free_buffers     vmlinux EXPORT_SYMBOL
+-0xe9f098a6    wait_iff_congested      vmlinux EXPORT_SYMBOL
+-0xcb5bf3f1    __put_cred      vmlinux EXPORT_SYMBOL
+-0x3f80e476    get_thermal_instance    vmlinux EXPORT_SYMBOL
+-0xb6979f60    usb_register_dev        vmlinux EXPORT_SYMBOL_GPL
+-0xe0d8227f    scsi_dma_map    vmlinux EXPORT_SYMBOL
+-0xa5de5bb1    blk_queue_bypass_start  vmlinux EXPORT_SYMBOL_GPL
+-0xb9617f29    dm_path_uevent  vmlinux EXPORT_SYMBOL_GPL
+-0xd909cae6    serial8250_clear_and_reinit_fifos       vmlinux EXPORT_SYMBOL_GPL
+-0x755da9a0    register_framebuffer    vmlinux EXPORT_SYMBOL
+-0x9ed685ee    iov_iter_advance        vmlinux EXPORT_SYMBOL
+-0xf86a3a9f    clk_gate_ops    vmlinux EXPORT_SYMBOL_GPL
+-0xfcc9ce6a    mmc_of_parse    vmlinux EXPORT_SYMBOL
+-0xb486e84e    mfd_remove_devices      vmlinux EXPORT_SYMBOL
+-0xc5a484ac    pm_generic_suspend_late vmlinux EXPORT_SYMBOL_GPL
+-0x3cd06035    add_input_randomness    vmlinux EXPORT_SYMBOL_GPL
+-0xf50d8f59    regulator_enable_regmap vmlinux EXPORT_SYMBOL_GPL
+-0x09774d0b    pinctrl_force_sleep     vmlinux EXPORT_SYMBOL_GPL
+-0xc7c3c6d2    ip6_tnl_dst_reset       vmlinux EXPORT_SYMBOL_GPL
+-0x225d0386    nf_ct_l4proto_pernet_register   vmlinux EXPORT_SYMBOL_GPL
+-0xf7d31a5d    nf_ct_l3proto_pernet_register   vmlinux EXPORT_SYMBOL_GPL
+-0x8401c62f    scsi_unblock_requests   vmlinux EXPORT_SYMBOL
+-0x8ca1a1dc    device_remove_bin_file  vmlinux EXPORT_SYMBOL_GPL
+-0xccb1ba6b    of_get_drm_display_mode vmlinux EXPORT_SYMBOL_GPL
+-0xe3f48cba    tty_port_free_xmit_buf  vmlinux EXPORT_SYMBOL
+-0xec1b043e    regulator_suspend_prepare       vmlinux EXPORT_SYMBOL_GPL
+-0xecbda9c5    display_entity_get      vmlinux EXPORT_SYMBOL_GPL
+-0x13b89dee    pinctrl_request_gpio    vmlinux EXPORT_SYMBOL_GPL
+-0xdcb3410a    nf_ct_deliver_cached_events     vmlinux EXPORT_SYMBOL_GPL
+-0x32ddd5b6    call_rcu        vmlinux EXPORT_SYMBOL_GPL
+-0xf1267848    usb_composite_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0x877509c0    crypto_nivaead_type     vmlinux EXPORT_SYMBOL_GPL
+-0x9263cf47    bdi_writeout_inc        vmlinux EXPORT_SYMBOL_GPL
+-0x26f6b499    iio_str_to_fixpoint     vmlinux EXPORT_SYMBOL_GPL
+-0x7267db00    hwrng_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0x19cbf31d    xfrm6_rcv_spi   vmlinux EXPORT_SYMBOL
+-0xe5a42822    ip_tunnel_change_mtu    vmlinux EXPORT_SYMBOL_GPL
+-0xf236a5de    tcf_exts_change vmlinux EXPORT_SYMBOL
+-0x058b95e3    snd_pcm_release_substream       vmlinux EXPORT_SYMBOL
+-0x9a6e183a    __idr_remove_all        vmlinux EXPORT_SYMBOL
+-0x7b9bf08e    disk_stack_limits       vmlinux EXPORT_SYMBOL
+-0x9879932b    crypto_register_notifier        vmlinux EXPORT_SYMBOL_GPL
+-0xd220cf8a    jiffies_to_timespec     vmlinux EXPORT_SYMBOL
+-0xce4f758e    dma_release_from_coherent       vmlinux EXPORT_SYMBOL
+-0xe238b99e    pskb_put        vmlinux EXPORT_SYMBOL_GPL
+-0xe11dd614    fib_table_lookup        vmlinux EXPORT_SYMBOL_GPL
+-0x3862b0a7    snd_soc_bytes_put       vmlinux EXPORT_SYMBOL_GPL
+-0xa5ed8e2c    inc_nlink       vmlinux EXPORT_SYMBOL
+-0xf43bdbf8    smpboot_unregister_percpu_thread        vmlinux EXPORT_SYMBOL_GPL
+-0x8a1ab4ee    timeval_to_jiffies      vmlinux EXPORT_SYMBOL
+-0x39375395    i2c_master_send vmlinux EXPORT_SYMBOL
+-0x3a517b2b    device_reprobe  vmlinux EXPORT_SYMBOL_GPL
+-0xb22e34bd    wiphy_free      vmlinux EXPORT_SYMBOL
+-0x76a01893    __netlink_dump_start    vmlinux EXPORT_SYMBOL
+-0xa96c3c3b    dev_kfree_skb_any       vmlinux EXPORT_SYMBOL
+-0xfdaeced1    snd_ctl_new1    vmlinux EXPORT_SYMBOL
+-0xb4f57a24    security_task_getsecid  vmlinux EXPORT_SYMBOL
+-0x09d71f87    seq_open        vmlinux EXPORT_SYMBOL
+-0x29a73c29    mnt_drop_write  vmlinux EXPORT_SYMBOL_GPL
+-0xbcdd5b99    iommu_group_set_name    vmlinux EXPORT_SYMBOL_GPL
+-0x7e394c4e    sysctl_local_reserved_ports     vmlinux EXPORT_SYMBOL
+-0x094bac5f    simple_readpage vmlinux EXPORT_SYMBOL
+-0x5a39720e    __lock_page     vmlinux EXPORT_SYMBOL
+-0xb140d14c    ring_buffer_read        vmlinux EXPORT_SYMBOL_GPL
+-0xf499fdb2    rcu_barrier_bh  vmlinux EXPORT_SYMBOL_GPL
+-0x03d9fff7    synchronize_srcu_expedited      vmlinux EXPORT_SYMBOL_GPL
+-0x1c0ae7d7    drm_mm_init_scan        vmlinux EXPORT_SYMBOL
+-0x8320bea8    __umodsi3       vmlinux EXPORT_SYMBOL
+-0xc3706dce    tcp_cong_avoid_ai       vmlinux EXPORT_SYMBOL_GPL
+-0xab6bde28    sysctl_max_syn_backlog  vmlinux EXPORT_SYMBOL
+-0x5d90d2ce    blk_delay_queue vmlinux EXPORT_SYMBOL
+-0xefdd70ce    security_secid_to_secctx        vmlinux EXPORT_SYMBOL
+-0x77d67659    follow_down     vmlinux EXPORT_SYMBOL
+-0x083eb1cc    __generic_file_aio_write        vmlinux EXPORT_SYMBOL
+-0x46646afc    filemap_write_and_wait_range    vmlinux EXPORT_SYMBOL
+-0xc72c4abb    usb_altnum_to_altsetting        vmlinux EXPORT_SYMBOL_GPL
+-0x0a98333a    snd_soc_dpcm_get_substream      vmlinux EXPORT_SYMBOL_GPL
+-0x360b1afe    probe_irq_mask  vmlinux EXPORT_SYMBOL
+-0x8f2154e4    cfg80211_rx_mgmt        vmlinux EXPORT_SYMBOL
+-0xafa574d0    snd_soc_jack_notifier_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0x93af86c9    get_write_access        vmlinux EXPORT_SYMBOL
+-0x2350c4a6    invalidate_mapping_pages        vmlinux EXPORT_SYMBOL
+-0x84c6c77a    genphy_read_status      vmlinux EXPORT_SYMBOL
+-0x96fb7fef    drm_mode_create_dithering_property      vmlinux EXPORT_SYMBOL
+-0xef56f51e    redraw_screen   vmlinux EXPORT_SYMBOL
+-0x2394545f    tty_unregister_driver   vmlinux EXPORT_SYMBOL
+-0xf3bf0bce    __bitmap_complement     vmlinux EXPORT_SYMBOL
+-0xe2e8065e    memdup_user     vmlinux EXPORT_SYMBOL
+-0x3bdd0f94    v4l2_prio_change        vmlinux EXPORT_SYMBOL
+-0x7ab9b430    drm_poll        vmlinux EXPORT_SYMBOL
+-0x760d494e    pinctrl_find_gpio_range_from_pin        vmlinux EXPORT_SYMBOL_GPL
+-0xcca27eeb    del_timer       vmlinux EXPORT_SYMBOL
+-0x39e773af    thermal_cooling_device_unregister       vmlinux EXPORT_SYMBOL_GPL
+-0xcba9dbcf    dma_get_required_mask   vmlinux EXPORT_SYMBOL_GPL
+-0x2fb1d233    nf_log_unbind_pf        vmlinux EXPORT_SYMBOL
+-0x460f7531    wait_rcu_gp     vmlinux EXPORT_SYMBOL_GPL
+-0x9bfaf424    usb_get_current_frame_number    vmlinux EXPORT_SYMBOL_GPL
+-0xad9bbf9f    hci_suspend_dev vmlinux EXPORT_SYMBOL
+-0x56c5a136    tcp_v4_send_check       vmlinux EXPORT_SYMBOL
+-0x0a4862b9    nf_ct_expect_find_get   vmlinux EXPORT_SYMBOL_GPL
+-0x30e3e930    dev_close       vmlinux EXPORT_SYMBOL
+-0xc3e46db4    snd_pcm_lib_free_pages  vmlinux EXPORT_SYMBOL
+-0x3b735a2b    __mark_inode_dirty      vmlinux EXPORT_SYMBOL
+-0x91437bc9    dma_buf_put     vmlinux EXPORT_SYMBOL_GPL
+-0x8e09c957    dma_buf_get     vmlinux EXPORT_SYMBOL_GPL
+-0x98aba977    ip6_update_pmtu vmlinux EXPORT_SYMBOL_GPL
+-0x019daa72    noop_qdisc      vmlinux EXPORT_SYMBOL
+-0x240646b9    sock_alloc_send_skb     vmlinux EXPORT_SYMBOL
+-0x871f2cb1    snd_soc_dapm_nc_pin     vmlinux EXPORT_SYMBOL_GPL
+-0x97440f69    snd_card_disconnect     vmlinux EXPORT_SYMBOL
+-0xd9ce8f0c    strnlen vmlinux EXPORT_SYMBOL
+-0xe7c9dbc0    unregister_filesystem   vmlinux EXPORT_SYMBOL
+-0x4abbe3c2    vm_brk  vmlinux EXPORT_SYMBOL
+-0x2439abc9    irq_domain_add_simple   vmlinux EXPORT_SYMBOL_GPL
+-0xd418e1c0    adjust_resource vmlinux EXPORT_SYMBOL
+-0x31c0c2d1    dm_put  vmlinux EXPORT_SYMBOL_GPL
+-0x140e371b    v4l2_of_get_remote_port_parent  vmlinux EXPORT_SYMBOL
+-0x3adbd595    v4l2_field_names        vmlinux EXPORT_SYMBOL
+-0xdcece020    xfrm_state_insert       vmlinux EXPORT_SYMBOL
+-0xf8fe3d0b    kmsg_dump_register      vmlinux EXPORT_SYMBOL_GPL
+-0x40728a63    xt_find_revision        vmlinux EXPORT_SYMBOL_GPL
+-0xcb534ec9    __destroy_inode vmlinux EXPORT_SYMBOL
+-0xea1f5b88    samsung_rev     vmlinux EXPORT_SYMBOL
+-0xd3dd145a    tcp_is_cwnd_limited     vmlinux EXPORT_SYMBOL_GPL
+-0x392697b4    nf_conntrack_l3proto_generic    vmlinux EXPORT_SYMBOL_GPL
+-0x2549013a    snd_soc_dai_set_channel_map     vmlinux EXPORT_SYMBOL_GPL
+-0x421e53cf    blk_rq_unmap_user       vmlinux EXPORT_SYMBOL
+-0xacf1d33d    crypto_mod_get  vmlinux EXPORT_SYMBOL_GPL
+-0x0bc477a2    irq_set_irq_type        vmlinux EXPORT_SYMBOL
+-0xce2840e7    irq_set_irq_wake        vmlinux EXPORT_SYMBOL
+-0x2650d835    sysctl_ip_early_demux   vmlinux EXPORT_SYMBOL
+-0x07e472e5    __remove_inode_hash     vmlinux EXPORT_SYMBOL
+-0x82b7cda8    __lru_cache_add vmlinux EXPORT_SYMBOL
+-0x457b77ca    of_fixed_factor_clk_setup       vmlinux EXPORT_SYMBOL_GPL
+-0x840b929e    v4l2_device_unregister_subdev   vmlinux EXPORT_SYMBOL_GPL
+-0x6128b5fc    __printk_ratelimit      vmlinux EXPORT_SYMBOL
+-0xcc1f1c3d    inet_twdr_hangman       vmlinux EXPORT_SYMBOL_GPL
+-0x71faed49    __blk_end_request_cur   vmlinux EXPORT_SYMBOL
+-0xab5cbfa1    __blk_end_request_err   vmlinux EXPORT_SYMBOL_GPL
+-0xb2682405    utf8_to_utf32   vmlinux EXPORT_SYMBOL
+-0x9621849f    ring_buffer_event_data  vmlinux EXPORT_SYMBOL_GPL
+-0x2761c400    pm_generic_restore_early        vmlinux EXPORT_SYMBOL_GPL
+-0x36d31f9e    crypto_sha1_update      vmlinux EXPORT_SYMBOL
+-0x8798e453    __tracepoint_kfree      vmlinux EXPORT_SYMBOL
+-0x247ba373    override_creds  vmlinux EXPORT_SYMBOL
+-0x131db64a    system_long_wq  vmlinux EXPORT_SYMBOL_GPL
+-0xc0d26387    kmsg_dump_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0x6b132713    __clk_register  vmlinux EXPORT_SYMBOL_GPL
+-0x5292f4ea    scsi_prep_return        vmlinux EXPORT_SYMBOL
+-0x34a13791    __pm_runtime_disable    vmlinux EXPORT_SYMBOL_GPL
+-0xa10db0ce    phy_pm_runtime_get_sync vmlinux EXPORT_SYMBOL_GPL
+-0x1b62df19    arm_iommu_create_mapping        vmlinux EXPORT_SYMBOL_GPL
+-0x606d0b09    secure_tcpv6_sequence_number    vmlinux EXPORT_SYMBOL
+-0xa75bc594    blkdev_issue_zeroout    vmlinux EXPORT_SYMBOL
+-0x8f12669a    irq_linear_revmap       vmlinux EXPORT_SYMBOL_GPL
+-0x938244d0    handle_level_irq        vmlinux EXPORT_SYMBOL_GPL
+-0xb336e1d2    extcon_set_cable_state_ vmlinux EXPORT_SYMBOL_GPL
+-0x067ef5d5    extcon_get_cable_state_ vmlinux EXPORT_SYMBOL_GPL
+-0x8d22bb58    iommu_group_alloc       vmlinux EXPORT_SYMBOL_GPL
+-0xa7e20df3    clk_mux_ops     vmlinux EXPORT_SYMBOL_GPL
+-0x7f9eeaae    input_register_handle   vmlinux EXPORT_SYMBOL
+-0x6cc78c5c    set_irq_flags   vmlinux EXPORT_SYMBOL_GPL
+-0xc781bd9f    rfkill_resume_polling   vmlinux EXPORT_SYMBOL
+-0x982e6b6d    ieee80211_radiotap_iterator_init        vmlinux EXPORT_SYMBOL
+-0xf30fda27    lzo1x_decompress_safe   vmlinux EXPORT_SYMBOL_GPL
+-0x42b364ef    scatterwalk_done        vmlinux EXPORT_SYMBOL_GPL
+-0x2158c0d7    kern_unmount    vmlinux EXPORT_SYMBOL
+-0xd31ccb06    of_machine_is_compatible        vmlinux EXPORT_SYMBOL
+-0xd6d49c42    sdio_writesb    vmlinux EXPORT_SYMBOL_GPL
+-0xe6fa2163    v4l2_async_notifier_unregister  vmlinux EXPORT_SYMBOL
+-0x20234f83    nla_append      vmlinux EXPORT_SYMBOL
+-0x4cf41ed3    skcipher_geniv_free     vmlinux EXPORT_SYMBOL_GPL
+-0x4bc07110    jbd2_journal_lock_updates       vmlinux EXPORT_SYMBOL
+-0xf37671d2    vfs_llseek      vmlinux EXPORT_SYMBOL
+-0x8720876b    __page_file_index       vmlinux EXPORT_SYMBOL_GPL
+-0x609d9c25    __irq_set_handler       vmlinux EXPORT_SYMBOL_GPL
+-0x2d17a0e1    cgroup_taskset_size     vmlinux EXPORT_SYMBOL_GPL
+-0xabe27502    v4l2_ctrl_query_fill    vmlinux EXPORT_SYMBOL
+-0x5b1a060c    usb_control_msg vmlinux EXPORT_SYMBOL_GPL
+-0xe59c5ea4    snd_dma_free_pages      vmlinux EXPORT_SYMBOL
+-0x85541e31    iterate_fd      vmlinux EXPORT_SYMBOL
+-0x7ceaf0d5    generic_handle_irq      vmlinux EXPORT_SYMBOL_GPL
+-0x46feb099    dm_read_arg     vmlinux EXPORT_SYMBOL
+-0xe8125c91    dev_set_drvdata vmlinux EXPORT_SYMBOL
+-0x8d60d310    dev_get_drvdata vmlinux EXPORT_SYMBOL
+-0x84510ec6    bt_sock_unlink  vmlinux EXPORT_SYMBOL
+-0x14f626f7    snd_soc_dapm_add_routes vmlinux EXPORT_SYMBOL_GPL
+-0x5d1c1bac    blocking_notifier_chain_cond_register   vmlinux EXPORT_SYMBOL_GPL
+-0xefd5b1f1    nfc_hci_disconnect_all_gates    vmlinux EXPORT_SYMBOL
+-0x009c0acf    __xfrm_state_destroy    vmlinux EXPORT_SYMBOL
+-0x256e5691    bfifo_qdisc_ops vmlinux EXPORT_SYMBOL
+-0x1f8544b8    panic_timeout   vmlinux EXPORT_SYMBOL_GPL
+-0x5b4e379c    of_prop_next_u32        vmlinux EXPORT_SYMBOL_GPL
+-0x8106095a    v4l2_prio_max   vmlinux EXPORT_SYMBOL
+-0xfff74a32    usb_unpoison_urb        vmlinux EXPORT_SYMBOL_GPL
+-0xc532db16    tty_port_init   vmlinux EXPORT_SYMBOL
+-0xa20ce1b8    net_msg_warn    vmlinux EXPORT_SYMBOL
+-0x2aa97a28    __sock_recv_timestamp   vmlinux EXPORT_SYMBOL_GPL
+-0x6225637e    md5_transform   vmlinux EXPORT_SYMBOL
+-0xa3301b08    noop_fsync      vmlinux EXPORT_SYMBOL
+-0x31ab0e28    extcon_dev_unregister   vmlinux EXPORT_SYMBOL_GPL
+-0xc5176fe9    usb_hcd_resume_root_hub vmlinux EXPORT_SYMBOL_GPL
+-0x13bdb1fd    cfg80211_ibss_joined    vmlinux EXPORT_SYMBOL
+-0x587763dd    blkdev_issue_write_same vmlinux EXPORT_SYMBOL
+-0x627b7988    crypto_hash_walk_first  vmlinux EXPORT_SYMBOL_GPL
+-0x85d438aa    scsi_add_host_with_dma  vmlinux EXPORT_SYMBOL
+-0x2b26ce97    devres_remove_group     vmlinux EXPORT_SYMBOL_GPL
+-0x8e007d5e    inet_sendpage   vmlinux EXPORT_SYMBOL
+-0xbb713e6d    sk_filter_release_rcu   vmlinux EXPORT_SYMBOL
+-0xf1dc9acb    dev_get_by_index_rcu    vmlinux EXPORT_SYMBOL
+-0x5364397d    dev_set_allmulti        vmlinux EXPORT_SYMBOL
+-0xd20a4e9e    snd_ctl_remove_id       vmlinux EXPORT_SYMBOL
+-0xea10655a    __bitmap_intersects     vmlinux EXPORT_SYMBOL
+-0xf313da4e    sha_transform   vmlinux EXPORT_SYMBOL
+-0x9b6eb137    ksize   vmlinux EXPORT_SYMBOL
+-0x38869d88    kstat   vmlinux EXPORT_SYMBOL
+-0x43caf714    mmc_can_erase   vmlinux EXPORT_SYMBOL
+-0xa42810a9    i2c_add_adapter vmlinux EXPORT_SYMBOL
+-0xaf5ddb02    input_mt_report_finger_count    vmlinux EXPORT_SYMBOL
+-0x3a09b033    drm_mmap        vmlinux EXPORT_SYMBOL
+-0xcc16f79c    drm_kms_helper_poll_fini        vmlinux EXPORT_SYMBOL
+-0xe707d823    __aeabi_uidiv   vmlinux EXPORT_SYMBOL
+-0xcd2a33d7    hci_conn_security       vmlinux EXPORT_SYMBOL
+-0xd456425d    kobject_set_name        vmlinux EXPORT_SYMBOL
+-0x60642a60    shmem_truncate_range    vmlinux EXPORT_SYMBOL_GPL
+-0xa3e7c113    ring_buffer_iter_peek   vmlinux EXPORT_SYMBOL_GPL
+-0xa5efbf4c    async_synchronize_full  vmlinux EXPORT_SYMBOL_GPL
+-0x3ac75973    dm_send_uevents vmlinux EXPORT_SYMBOL_GPL
+-0x47f757de    elf_platform    vmlinux EXPORT_SYMBOL
+-0x48994b32    bt_debugfs      vmlinux EXPORT_SYMBOL_GPL
+-0xc3f4c43b    set_device_ro   vmlinux EXPORT_SYMBOL
+-0xbb038ce4    perf_unregister_guest_info_callbacks    vmlinux EXPORT_SYMBOL_GPL
+-0x8cc44150    of_clk_src_simple_get   vmlinux EXPORT_SYMBOL_GPL
+-0x09378170    shash_attr_alg  vmlinux EXPORT_SYMBOL_GPL
+-0x63eb9355    panic_blink     vmlinux EXPORT_SYMBOL
+-0x37df5b58    usb_anchor_urb  vmlinux EXPORT_SYMBOL_GPL
+-0x665ccdb6    __sync_dirty_buffer     vmlinux EXPORT_SYMBOL
+-0xb370f2b0    kmap_high       vmlinux EXPORT_SYMBOL
+-0xc3042166    cancel_dirty_page       vmlinux EXPORT_SYMBOL
+-0xf4fc2d6c    __ring_buffer_alloc     vmlinux EXPORT_SYMBOL_GPL
+-0x82072614    tasklet_kill    vmlinux EXPORT_SYMBOL
+-0x653cd720    exynos_g2d_set_cmdlist_ioctl    vmlinux EXPORT_SYMBOL_GPL
+-0xa2a78b0e    blk_post_runtime_resume vmlinux EXPORT_SYMBOL
+-0xf7f02ddf    bio_endio       vmlinux EXPORT_SYMBOL
+-0x269b337f    account_page_redirty    vmlinux EXPORT_SYMBOL
+-0x85c7f674    ring_buffer_normalize_time_stamp        vmlinux EXPORT_SYMBOL_GPL
+-0xf4597085    i2c_use_client  vmlinux EXPORT_SYMBOL
+-0x2da746c5    scsi_print_command      vmlinux EXPORT_SYMBOL
+-0xd0e73a87    amba_driver_register    vmlinux EXPORT_SYMBOL
+-0x3810da45    nf_ct_expect_unregister_notifier        vmlinux EXPORT_SYMBOL_GPL
+-0x50b236e9    eth_prepare_mac_addr_change     vmlinux EXPORT_SYMBOL
+-0xd32c0bf4    sk_stop_timer   vmlinux EXPORT_SYMBOL
+-0xffdb82bc    sg_free_table   vmlinux EXPORT_SYMBOL
+-0xfcbba27f    locks_remove_posix      vmlinux EXPORT_SYMBOL
+-0xb0b85f47    ring_buffer_iter_reset  vmlinux EXPORT_SYMBOL_GPL
+-0x43b0c9c3    preempt_schedule        vmlinux EXPORT_SYMBOL
+-0x7c010229    of_platform_bus_probe   vmlinux EXPORT_SYMBOL
+-0xf74656ab    regulator_can_change_voltage    vmlinux EXPORT_SYMBOL_GPL
+-0x5d5b5a16    radix_tree_delete       vmlinux EXPORT_SYMBOL
+-0x4b37f24f    of_extcon_get_extcon_dev        vmlinux EXPORT_SYMBOL_GPL
+-0x728be72e    pm_generic_thaw_noirq   vmlinux EXPORT_SYMBOL_GPL
+-0x94de4a33    tcp_slow_start  vmlinux EXPORT_SYMBOL_GPL
+-0x4a73178a    dev_activate    vmlinux EXPORT_SYMBOL
+-0x7649cfce    __pneigh_lookup vmlinux EXPORT_SYMBOL_GPL
+-0xaafcd87b    devm_iounmap    vmlinux EXPORT_SYMBOL
+-0x3bfc99a5    devm_ioremap    vmlinux EXPORT_SYMBOL
+-0x5541ea93    on_each_cpu     vmlinux EXPORT_SYMBOL
+-0x176af8ec    cdc_ncm_rx_verify_ndp16 vmlinux EXPORT_SYMBOL_GPL
+-0x572d7fe7    pn544_hci_remove        vmlinux EXPORT_SYMBOL
+-0x74e5ff1a    udpv6_encap_enable      vmlinux EXPORT_SYMBOL
+-0x7a08f61d    snd_pcm_set_sync        vmlinux EXPORT_SYMBOL
+-0x164b50d3    nla_reserve     vmlinux EXPORT_SYMBOL
+-0x08758d9c    bioset_create   vmlinux EXPORT_SYMBOL
+-0x08365975    drm_gem_object_lookup   vmlinux EXPORT_SYMBOL
+-0x862b9816    cpu_topology    vmlinux EXPORT_SYMBOL_GPL
+-0x3722cf9f    rtnl_put_cacheinfo      vmlinux EXPORT_SYMBOL_GPL
+-0xea124bd1    gcd     vmlinux EXPORT_SYMBOL_GPL
+-0xce3e95d0    ihold   vmlinux EXPORT_SYMBOL
+-0xd11031b4    names_cachep    vmlinux EXPORT_SYMBOL
+-0x8890cade    invalidate_inode_pages2_range   vmlinux EXPORT_SYMBOL_GPL
+-0x83130f62    cancel_delayed_work     vmlinux EXPORT_SYMBOL
+-0xcbc428db    __cpufreq_driver_target vmlinux EXPORT_SYMBOL_GPL
+-0xd6233445    xfrm_policy_register_afinfo     vmlinux EXPORT_SYMBOL
+-0xc8afb46b    snd_info_create_card_entry      vmlinux EXPORT_SYMBOL
+-0xb7850524    crypto_unregister_shashes       vmlinux EXPORT_SYMBOL_GPL
+-0x4acc9be5    dentry_path_raw vmlinux EXPORT_SYMBOL
+-0x475ea860    xfrm_sad_getinfo        vmlinux EXPORT_SYMBOL
+-0x9429e18f    netif_napi_del  vmlinux EXPORT_SYMBOL
+-0x03a3ce75    crypto_register_alg     vmlinux EXPORT_SYMBOL_GPL
+-0x1a3e0511    debugfs_rename  vmlinux EXPORT_SYMBOL_GPL
+-0xb69186d9    simple_open     vmlinux EXPORT_SYMBOL
+-0xe513ed5c    single_open     vmlinux EXPORT_SYMBOL
+-0x9072472b    page_follow_link_light  vmlinux EXPORT_SYMBOL
+-0xdbbd4688    __page_file_mapping     vmlinux EXPORT_SYMBOL_GPL
+-0x0f751aea    input_event_from_user   vmlinux EXPORT_SYMBOL_GPL
+-0x4484a5a4    wait_for_device_probe   vmlinux EXPORT_SYMBOL_GPL
+-0xd53e17fd    tty_port_put    vmlinux EXPORT_SYMBOL
+-0xa1b759ce    fb_add_videomode        vmlinux EXPORT_SYMBOL
+-0x3c831441    arm_check_condition     vmlinux EXPORT_SYMBOL_GPL
+-0x44fa52dd    brcmu_pktq_mdeq drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x471d6f83    brcmu_pktq_mlen drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x6af410ae    cfg80211_send_disassoc  vmlinux EXPORT_SYMBOL
+-0x1baa3892    xfrm6_find_1stfragopt   vmlinux EXPORT_SYMBOL
+-0x198788b4    snd_lookup_oss_minor_data       vmlinux EXPORT_SYMBOL
+-0x4a3ea5c0    snd_request_card        vmlinux EXPORT_SYMBOL
+-0x56451890    register_ftrace_event   vmlinux EXPORT_SYMBOL_GPL
+-0x4ae313f9    kthread_stop    vmlinux EXPORT_SYMBOL
+-0x1438fff0    st_sensors_sysfs_scale_avail    vmlinux EXPORT_SYMBOL
+-0x31178006    clk_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0x083c2cbe    of_get_next_parent      vmlinux EXPORT_SYMBOL
+-0xfef96e23    __scsi_print_command    vmlinux EXPORT_SYMBOL
+-0x670cff67    drm_helper_disable_unused_functions     vmlinux EXPORT_SYMBOL
+-0xe7048594    cfg80211_chandef_create vmlinux EXPORT_SYMBOL
+-0x020d1750    cfg80211_tdls_oper_request      vmlinux EXPORT_SYMBOL
+-0xbec63ca7    security_inode_create   vmlinux EXPORT_SYMBOL_GPL
+-0xfe72e11b    dm_register_target      vmlinux EXPORT_SYMBOL
+-0xaa4a7797    hex2bin vmlinux EXPORT_SYMBOL
+-0xe924fd45    crypto_default_rng      vmlinux EXPORT_SYMBOL_GPL
+-0xddab6b08    d_make_root     vmlinux EXPORT_SYMBOL
+-0xa3b40cfd    hid_register_report     vmlinux EXPORT_SYMBOL_GPL
+-0xcda04a5b    v4l2_prio_close vmlinux EXPORT_SYMBOL
+-0x2e12216c    rtc_set_alarm   vmlinux EXPORT_SYMBOL_GPL
+-0xaefe5034    __scsi_get_command      vmlinux EXPORT_SYMBOL_GPL
+-0x31547da3    __scsi_put_command      vmlinux EXPORT_SYMBOL
+-0x0fa5f996    inet_csk_listen_start   vmlinux EXPORT_SYMBOL_GPL
+-0xfcc2a43c    utf32_to_utf8   vmlinux EXPORT_SYMBOL
+-0xeef161aa    groups_free     vmlinux EXPORT_SYMBOL
+-0xc5a25ce7    cleanup_srcu_struct     vmlinux EXPORT_SYMBOL_GPL
+-0xac1a55be    unregister_reboot_notifier      vmlinux EXPORT_SYMBOL
+-0x4557930f    regmap_update_bits_check        vmlinux EXPORT_SYMBOL_GPL
+-0x0e0eb67f    ip6_flush_pending_frames        vmlinux EXPORT_SYMBOL_GPL
+-0xb670b4cf    tcf_destroy_chain       vmlinux EXPORT_SYMBOL
+-0x5fa48b4e    generic_file_remap_pages        vmlinux EXPORT_SYMBOL
+-0xe13fa8ed    regmap_register_patch   vmlinux EXPORT_SYMBOL_GPL
+-0x18c77c17    tty_perform_flush       vmlinux EXPORT_SYMBOL_GPL
+-0x5ece6555    debugfs_remove_recursive        vmlinux EXPORT_SYMBOL_GPL
+-0x1fcf4d4b    _raw_read_unlock_bh     vmlinux EXPORT_SYMBOL
+-0x04cabed9    rfkill_register vmlinux EXPORT_SYMBOL
+-0x774a552a    cfg80211_send_deauth    vmlinux EXPORT_SYMBOL
+-0xc1691764    neigh_parms_alloc       vmlinux EXPORT_SYMBOL
+-0x75fac20b    mount_single    vmlinux EXPORT_SYMBOL
+-0x9ecc6a7a    interruptible_sleep_on  vmlinux EXPORT_SYMBOL
+-0x19a304ba    usb_disabled    vmlinux EXPORT_SYMBOL_GPL
+-0x48f20051    __ip_route_output_key   vmlinux EXPORT_SYMBOL_GPL
+-0x5e7f4920    snd_pcm_format_set_silence      vmlinux EXPORT_SYMBOL
+-0x9ef5a297    blk_queue_invalidate_tags       vmlinux EXPORT_SYMBOL
+-0xffb6db4a    remove_irq      vmlinux EXPORT_SYMBOL_GPL
+-0x93a6e0b2    io_schedule     vmlinux EXPORT_SYMBOL
+-0xa604bba5    cpufreq_notify_transition       vmlinux EXPORT_SYMBOL_GPL
+-0xb9c425de    register_syscore_ops    vmlinux EXPORT_SYMBOL_GPL
+-0x7317fc49    disk_part_iter_next     vmlinux EXPORT_SYMBOL_GPL
+-0xc4c6c770    block_write_end vmlinux EXPORT_SYMBOL
+-0x437e0be6    pid_vnr vmlinux EXPORT_SYMBOL_GPL
+-0xcb476f4a    cfb_fillrect    vmlinux EXPORT_SYMBOL
+-0xc6241aec    cfg80211_roamed_bss     vmlinux EXPORT_SYMBOL
+-0x44336387    __xfrm_decode_session   vmlinux EXPORT_SYMBOL
+-0xf803fe39    bitmap_set      vmlinux EXPORT_SYMBOL
+-0x1bbcbb78    __pagevec_lru_add       vmlinux EXPORT_SYMBOL
+-0xd1b2db37    tracepoint_probe_register_noupdate      vmlinux EXPORT_SYMBOL_GPL
+-0x230e0698    __clocksource_updatefreq_scale  vmlinux EXPORT_SYMBOL_GPL
+-0xd8004073    sdhci_runtime_resume_host       vmlinux EXPORT_SYMBOL_GPL
+-0x04369954    devm_regmap_init        vmlinux EXPORT_SYMBOL_GPL
+-0xa2a36526    tty_port_lower_dtr_rts  vmlinux EXPORT_SYMBOL
+-0xf369df34    wiphy_rfkill_stop_polling       vmlinux EXPORT_SYMBOL
+-0x253ec879    netlink_set_err vmlinux EXPORT_SYMBOL
+-0x71d7bf40    alloc_netdev_mqs        vmlinux EXPORT_SYMBOL
+-0x336154ca    rcutorture_record_test_transition       vmlinux EXPORT_SYMBOL_GPL
+-0x1aa1c9f2    make_kprojid    vmlinux EXPORT_SYMBOL
+-0xa42a123d    bus_register_notifier   vmlinux EXPORT_SYMBOL_GPL
+-0xd2cf977d    gpiochip_add    vmlinux EXPORT_SYMBOL_GPL
+-0xd3c40b56    inet_listen     vmlinux EXPORT_SYMBOL
+-0xfdc9a24f    __dst_destroy_metrics_generic   vmlinux EXPORT_SYMBOL
+-0x44e276d8    skb_queue_purge vmlinux EXPORT_SYMBOL
+-0x588eccde    get_unmapped_area       vmlinux EXPORT_SYMBOL
+-0x0f29f7c9    add_to_page_cache_lru   vmlinux EXPORT_SYMBOL_GPL
+-0xb7d4b252    iommu_present   vmlinux EXPORT_SYMBOL_GPL
+-0x01c483a9    v4l2_get_timestamp      vmlinux EXPORT_SYMBOL_GPL
+-0xbf041102    register_vt_notifier    vmlinux EXPORT_SYMBOL_GPL
+-0xf85885d1    nci_unregister_device   vmlinux EXPORT_SYMBOL
+-0x07b52e38    rtnl_unregister vmlinux EXPORT_SYMBOL_GPL
+-0xe3bc40f6    dpcm_be_dai_trigger     vmlinux EXPORT_SYMBOL_GPL
+-0xfbed2f3c    snd_soc_info_volsw_range        vmlinux EXPORT_SYMBOL_GPL
+-0x9545974d    blk_rq_map_user vmlinux EXPORT_SYMBOL
+-0x693ca44e    jbd2_journal_clear_features     vmlinux EXPORT_SYMBOL
+-0x538410d3    generic_pipe_buf_release        vmlinux EXPORT_SYMBOL
+-0x8878cfa6    gether_cleanup  vmlinux EXPORT_SYMBOL
+-0xc1c72997    platform_bus_type       vmlinux EXPORT_SYMBOL_GPL
+-0x2c61162c    drm_fb_helper_check_var vmlinux EXPORT_SYMBOL
+-0x7a8cea07    bt_accept_unlink        vmlinux EXPORT_SYMBOL
+-0x61812beb    nf_ct_gre_keymap_add    vmlinux EXPORT_SYMBOL_GPL
+-0xcf596042    d_find_alias    vmlinux EXPORT_SYMBOL
+-0x81d10f5f    trace_seq_putc  vmlinux EXPORT_SYMBOL
+-0x760a0f4f    yield   vmlinux EXPORT_SYMBOL
+-0xac472389    iio_buffer_register     vmlinux EXPORT_SYMBOL
+-0x5dd590c3    sdhci_pltfm_pmops       vmlinux EXPORT_SYMBOL_GPL
+-0x0c5b9900    xt_check_target vmlinux EXPORT_SYMBOL_GPL
+-0xb67c64fd    __tracepoint_kfree_skb  vmlinux EXPORT_SYMBOL_GPL
+-0xd6c2e04b    __tracepoint_napi_poll  vmlinux EXPORT_SYMBOL_GPL
+-0x01bb81cc    netdev_upper_dev_unlink vmlinux EXPORT_SYMBOL
+-0x5bb9daec    __sg_page_iter_start    vmlinux EXPORT_SYMBOL
+-0xac3d64d9    fsstack_copy_attr_all   vmlinux EXPORT_SYMBOL_GPL
+-0xda48e711    sdio_claim_irq  vmlinux EXPORT_SYMBOL_GPL
+-0x1dc36131    fb_destroy_modedb       vmlinux EXPORT_SYMBOL
+-0xca2159d7    udp6_lib_lookup vmlinux EXPORT_SYMBOL_GPL
+-0xbf58f5e7    xfrm_init_replay        vmlinux EXPORT_SYMBOL
+-0xfb74be78    udp4_lib_lookup vmlinux EXPORT_SYMBOL_GPL
+-0x419cfeed    __nf_ct_try_assign_helper       vmlinux EXPORT_SYMBOL_GPL
+-0x610dbc32    genl_unregister_ops     vmlinux EXPORT_SYMBOL
+-0x9e2000a7    memcpy_toiovecend       vmlinux EXPORT_SYMBOL
+-0x3fc5d39f    snd_jack_report vmlinux EXPORT_SYMBOL
+-0x93949c2a    inode_sb_list_add       vmlinux EXPORT_SYMBOL_GPL
+-0x3d4ee67b    inode_init_always       vmlinux EXPORT_SYMBOL
+-0x38883d79    d_invalidate    vmlinux EXPORT_SYMBOL
+-0xa0b04675    vmalloc_32      vmlinux EXPORT_SYMBOL
+-0xedca9389    pid_task        vmlinux EXPORT_SYMBOL
+-0xc1c2b8e5    scsi_command_normalize_sense    vmlinux EXPORT_SYMBOL
+-0x4d0d163d    copy_page       vmlinux EXPORT_SYMBOL
+-0xe0becdbc    set_h245_addr_hook      vmlinux EXPORT_SYMBOL_GPL
+-0xd9a79782    seq_print_acct  vmlinux EXPORT_SYMBOL_GPL
+-0xbc9f30d7    textsearch_unregister   vmlinux EXPORT_SYMBOL
+-0xf54c51a2    dma_pool_free   vmlinux EXPORT_SYMBOL
+-0x32fd447a    monotonic_to_bootbased  vmlinux EXPORT_SYMBOL_GPL
+-0x45a6be13    cpufreq_sysfs_remove_file       vmlinux EXPORT_SYMBOL
+-0x9a5723c8    input_register_handler  vmlinux EXPORT_SYMBOL
+-0x0f618e15    drm_class_device_unregister     vmlinux EXPORT_SYMBOL_GPL
+-0xbae73813    inet6_csk_bind_conflict vmlinux EXPORT_SYMBOL_GPL
+-0xa35de80f    ipv4_config     vmlinux EXPORT_SYMBOL
+-0x7411b488    netif_carrier_on        vmlinux EXPORT_SYMBOL
+-0x1212d241    fib_rules_lookup        vmlinux EXPORT_SYMBOL_GPL
+-0xb0b847ac    __bitmap_full   vmlinux EXPORT_SYMBOL
+-0x4059792f    print_hex_dump  vmlinux EXPORT_SYMBOL
+-0x99d40bce    cfg80211_del_sta        vmlinux EXPORT_SYMBOL
+-0xe8068f48    ip6_route_output        vmlinux EXPORT_SYMBOL
+-0xb57e5e86    __dst_free      vmlinux EXPORT_SYMBOL
+-0x9fb986a9    inode_newsize_ok        vmlinux EXPORT_SYMBOL
+-0xf39a1727    dev_pm_qos_add_notifier vmlinux EXPORT_SYMBOL_GPL
+-0xbb6297fd    drm_mode_group_init_legacy_group        vmlinux EXPORT_SYMBOL
+-0xd3ce735a    drm_crtc_helper_set_config      vmlinux EXPORT_SYMBOL
+-0xa68b2c0b    pn_sock_get_port        vmlinux EXPORT_SYMBOL
+-0x04797338    inet_csk_destroy_sock   vmlinux EXPORT_SYMBOL
+-0x050e881c    inet_peer_base_init     vmlinux EXPORT_SYMBOL_GPL
+-0x84b183ae    strncmp vmlinux EXPORT_SYMBOL
+-0xb6f24459    crypto_register_shashes vmlinux EXPORT_SYMBOL_GPL
+-0x1e26be3b    get_anon_bdev   vmlinux EXPORT_SYMBOL
+-0x6b29a1fa    ring_buffer_event_length        vmlinux EXPORT_SYMBOL_GPL
+-0x5634e278    __clk_get_flags vmlinux EXPORT_SYMBOL_GPL
+-0x2e1ca751    clk_put vmlinux EXPORT_SYMBOL
+-0xf474a207    usb_gadget_config_buf   vmlinux EXPORT_SYMBOL_GPL
+-0x20838fc5    __pm_runtime_idle       vmlinux EXPORT_SYMBOL_GPL
+-0x062de44d    sock_kfree_s    vmlinux EXPORT_SYMBOL
+-0x3796bdcc    snd_pcm_format_little_endian    vmlinux EXPORT_SYMBOL
+-0xa34f1ef5    crc32_le        vmlinux EXPORT_SYMBOL
+-0xf54bd49b    lcm     vmlinux EXPORT_SYMBOL_GPL
+-0x13354608    scatterwalk_map_and_copy        vmlinux EXPORT_SYMBOL_GPL
+-0xf2bec139    empty_aops      vmlinux EXPORT_SYMBOL
+-0x45755a66    __task_pid_nr_ns        vmlinux EXPORT_SYMBOL
+-0xcbc23c9a    ethtool_op_get_link     vmlinux EXPORT_SYMBOL
+-0x5735fbd5    read_cache_pages        vmlinux EXPORT_SYMBOL
+-0x4aadeb9a    ring_buffer_alloc_read_page     vmlinux EXPORT_SYMBOL_GPL
+-0x2f3f62cd    v4l2_try_ext_ctrls      vmlinux EXPORT_SYMBOL
+-0x5d12e48f    input_event_to_user     vmlinux EXPORT_SYMBOL_GPL
+-0x6947468c    input_unregister_device vmlinux EXPORT_SYMBOL
+-0x91600a8e    usb_string_id   vmlinux EXPORT_SYMBOL_GPL
+-0xcc924d52    regulator_disable_regmap        vmlinux EXPORT_SYMBOL_GPL
+-0x3a4402b4    ip_generic_getfrag      vmlinux EXPORT_SYMBOL
+-0x6308d2cf    call_netdevice_notifiers        vmlinux EXPORT_SYMBOL
+-0xc02df0b8    snd_soc_pm_ops  vmlinux EXPORT_SYMBOL_GPL
+-0xf9436986    crypto_dequeue_request  vmlinux EXPORT_SYMBOL_GPL
+-0xb6555d54    crypto_enqueue_request  vmlinux EXPORT_SYMBOL_GPL
+-0x6c2dc956    fat_add_entries vmlinux EXPORT_SYMBOL_GPL
+-0xb7fc7a60    thaw_bdev       vmlinux EXPORT_SYMBOL
+-0x99a170f8    kmem_cache_alloc_trace  vmlinux EXPORT_SYMBOL
+-0x06f22ca2    irq_create_mapping      vmlinux EXPORT_SYMBOL_GPL
+-0x992e5dbd    mii_nway_restart        vmlinux EXPORT_SYMBOL
+-0xa6a0a273    max77693_write_reg      vmlinux EXPORT_SYMBOL_GPL
+-0xa6b21ef2    dpm_suspend_end vmlinux EXPORT_SYMBOL_GPL
+-0x27f9262d    sk_run_filter   vmlinux EXPORT_SYMBOL
+-0x8bfe698b    netdev_rx_csum_fault    vmlinux EXPORT_SYMBOL
+-0x9e61bb05    set_freezable   vmlinux EXPORT_SYMBOL
+-0xd5418207    devres_release_group    vmlinux EXPORT_SYMBOL_GPL
+-0x45669e2c    drm_fb_helper_restore_fbdev_mode        vmlinux EXPORT_SYMBOL
+-0x93fcb0ed    bt_sock_reclassify_lock vmlinux EXPORT_SYMBOL
+-0xb6d8be2d    ipv6_push_nfrag_opts    vmlinux EXPORT_SYMBOL
+-0x8cdb54d7    ipt_register_table      vmlinux EXPORT_SYMBOL
+-0xcc0aef97    neigh_sysctl_unregister vmlinux EXPORT_SYMBOL
+-0xe56a9336    snd_pcm_format_width    vmlinux EXPORT_SYMBOL
+-0x9077c297    blk_abort_request       vmlinux EXPORT_SYMBOL_GPL
+-0x6ed8eb1f    extcon_register_notifier        vmlinux EXPORT_SYMBOL_GPL
+-0xc9561772    fb_destroy_modelist     vmlinux EXPORT_SYMBOL_GPL
+-0xf494fae4    tcp_peer_is_proven      vmlinux EXPORT_SYMBOL_GPL
+-0xdc70cab5    __scm_destroy   vmlinux EXPORT_SYMBOL
+-0xfb2acf00    snd_mixer_oss_notify_callback   vmlinux EXPORT_SYMBOL
+-0x3a016c77    d_move  vmlinux EXPORT_SYMBOL
+-0x5091b823    ring_buffer_read_start  vmlinux EXPORT_SYMBOL_GPL
+-0x171751ed    sdio_writeb_readb       vmlinux EXPORT_SYMBOL_GPL
+-0x3d94fdae    usb_put_phy     vmlinux EXPORT_SYMBOL_GPL
+-0xfbf7bde5    drm_crtc_cleanup        vmlinux EXPORT_SYMBOL
+-0x52aaee97    amba_ahb_device_add_res vmlinux EXPORT_SYMBOL_GPL
+-0xd0706e35    phy_pm_runtime_put      vmlinux EXPORT_SYMBOL_GPL
+-0x0ff178f6    __aeabi_idivmod vmlinux EXPORT_SYMBOL
+-0xfb11005b    ipcomp_destroy  vmlinux EXPORT_SYMBOL_GPL
+-0x6f81b189    dev_addr_del_multiple   vmlinux EXPORT_SYMBOL
+-0xf5ce8c40    touch_atime     vmlinux EXPORT_SYMBOL
+-0x53614269    get_cpu_idle_time_us    vmlinux EXPORT_SYMBOL_GPL
+-0x61c243fc    mod_timer_pending       vmlinux EXPORT_SYMBOL
+-0xf821b501    device_set_wakeup_capable       vmlinux EXPORT_SYMBOL_GPL
+-0x80bbfeb1    s3c_gpio_cfgall_range   vmlinux EXPORT_SYMBOL_GPL
+-0x10081d73    s3c_gpio_cfgpin_range   vmlinux EXPORT_SYMBOL_GPL
+-0x75464443    phonet_proto_unregister vmlinux EXPORT_SYMBOL
+-0x7d6fed76    rtnl_configure_link     vmlinux EXPORT_SYMBOL
+-0x8c844510    sock_wmalloc    vmlinux EXPORT_SYMBOL
+-0xbaf75338    snd_soc_codec_writable_register vmlinux EXPORT_SYMBOL_GPL
+-0x1e6d26a8    strstr  vmlinux EXPORT_SYMBOL
+-0xea6f9ca2    task_user_regset_view   vmlinux EXPORT_SYMBOL_GPL
+-0x4de17ab3    usb_state_string        vmlinux EXPORT_SYMBOL_GPL
+-0x349cba85    strchr  vmlinux EXPORT_SYMBOL
+-0xb83a0cc6    perf_event_disable      vmlinux EXPORT_SYMBOL_GPL
+-0x3b5965e0    inet_csk_listen_stop    vmlinux EXPORT_SYMBOL_GPL
+-0x6be59bed    kobject_create_and_add  vmlinux EXPORT_SYMBOL_GPL
+-0xdced71ac    setup_new_exec  vmlinux EXPORT_SYMBOL
+-0xdb8a1b3f    usermodehelper_read_trylock     vmlinux EXPORT_SYMBOL_GPL
+-0x7c9ad2eb    usb_wait_anchor_empty_timeout   vmlinux EXPORT_SYMBOL_GPL
+-0xf2fca922    uart_parse_options      vmlinux EXPORT_SYMBOL_GPL
+-0x7f63b31e    _memcpy_toio    vmlinux EXPORT_SYMBOL
+-0x3e3fcdf2    xfrm_state_lookup_byaddr        vmlinux EXPORT_SYMBOL
+-0x2b538790    pskb_expand_head        vmlinux EXPORT_SYMBOL
+-0xdb67d9bb    of_i2c_register_devices vmlinux EXPORT_SYMBOL
+-0x9f7314d6    wakeup_source_prepare   vmlinux EXPORT_SYMBOL_GPL
+-0x2a828cb7    drm_noop        vmlinux EXPORT_SYMBOL
+-0x3d3c540f    elf_hwcap       vmlinux EXPORT_SYMBOL
+-0xa045219b    fuse_do_ioctl   vmlinux EXPORT_SYMBOL_GPL
+-0x8fa5cf61    pm_qos_update_request   vmlinux EXPORT_SYMBOL_GPL
+-0x73514fba    i2c_release_client      vmlinux EXPORT_SYMBOL
+-0x168db450    take_over_console       vmlinux EXPORT_SYMBOL
+-0x0aa13d05    __raw_readsw    vmlinux EXPORT_SYMBOL
+-0x816a1ee5    rtnl_link_register      vmlinux EXPORT_SYMBOL_GPL
+-0x9fd1a952    sk_set_memalloc vmlinux EXPORT_SYMBOL_GPL
+-0x8605ed02    lock_may_write  vmlinux EXPORT_SYMBOL
+-0xb24e73ff    bh_submit_read  vmlinux EXPORT_SYMBOL
+-0x455db47d    dma_mark_declared_memory_occupied       vmlinux EXPORT_SYMBOL
+-0x1a65f4ad    __arm_ioremap_pfn       vmlinux EXPORT_SYMBOL
+-0x955e8436    eth_change_mtu  vmlinux EXPORT_SYMBOL
+-0xa300e599    eth_header_parse        vmlinux EXPORT_SYMBOL
+-0x42977ad4    __hw_addr_del_multiple  vmlinux EXPORT_SYMBOL
+-0xf57de517    bdev_stack_limits       vmlinux EXPORT_SYMBOL
+-0x25bed5a1    static_key_slow_dec_deferred    vmlinux EXPORT_SYMBOL_GPL
+-0xd2aaeb4e    kmsg_dump_get_buffer    vmlinux EXPORT_SYMBOL_GPL
+-0xedb320d6    nf_nat_pptp_hook_exp_gre        vmlinux EXPORT_SYMBOL_GPL
+-0xdc0a9f66    sock_wake_async vmlinux EXPORT_SYMBOL
+-0x68e05d57    getrawmonotonic vmlinux EXPORT_SYMBOL
+-0xee715ef8    lg_global_unlock        vmlinux EXPORT_SYMBOL
+-0xbebb2820    crypto_register_algs    vmlinux EXPORT_SYMBOL_GPL
+-0xccc2bc05    fat_free_clusters       vmlinux EXPORT_SYMBOL_GPL
+-0xde99c012    jbd2_complete_transaction       vmlinux EXPORT_SYMBOL
+-0x60599993    __set_page_dirty_buffers        vmlinux EXPORT_SYMBOL
+-0x8b775d3a    __wake_up_locked        vmlinux EXPORT_SYMBOL_GPL
+-0x93eb18c6    of_platform_device_create       vmlinux EXPORT_SYMBOL
+-0x9e5bfa34    bt_sock_poll    vmlinux EXPORT_SYMBOL
+-0x7e98f5ff    sock_prot_inuse_add     vmlinux EXPORT_SYMBOL_GPL
+-0xf9e73082    scnprintf       vmlinux EXPORT_SYMBOL
+-0xa1b4cc6a    aead_geniv_exit vmlinux EXPORT_SYMBOL_GPL
+-0xa7001f92    mod_zone_page_state     vmlinux EXPORT_SYMBOL
+-0x92e79788    perf_event_refresh      vmlinux EXPORT_SYMBOL_GPL
+-0x77e7babf    usb_hcd_platform_shutdown       vmlinux EXPORT_SYMBOL_GPL
+-0x6d4d6df5    s3c_gpio_cfgpin vmlinux EXPORT_SYMBOL
+-0x7f250a18    tcf_register_action     vmlinux EXPORT_SYMBOL
+-0x41852af3    blk_add_request_payload vmlinux EXPORT_SYMBOL_GPL
+-0x8bf05477    pm_runtime_autosuspend_expiration       vmlinux EXPORT_SYMBOL_GPL
+-0xea25f714    rtnl_link_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0x5f75b2b7    snd_soc_dapm_enable_pin vmlinux EXPORT_SYMBOL_GPL
+-0x87879778    copy_strings_kernel     vmlinux EXPORT_SYMBOL
+-0x731b81f1    __wait_on_bit   vmlinux EXPORT_SYMBOL
+-0x18838e93    hrtimer_get_remaining   vmlinux EXPORT_SYMBOL_GPL
+-0x0be4ca5a    extcon_set_state        vmlinux EXPORT_SYMBOL_GPL
+-0xacdf7eb6    led_trigger_register_simple     vmlinux EXPORT_SYMBOL_GPL
+-0x20645642    drm_debug       vmlinux EXPORT_SYMBOL
+-0x5f41d1f8    rdev_get_id     vmlinux EXPORT_SYMBOL_GPL
+-0xf6f440a6    tcp_enter_memory_pressure       vmlinux EXPORT_SYMBOL
+-0x3b9a9d19    skb_add_rx_frag vmlinux EXPORT_SYMBOL
+-0x32b2bc89    snd_soc_write   vmlinux EXPORT_SYMBOL_GPL
+-0x5b44d926    snd_soc_get_xr_sx       vmlinux EXPORT_SYMBOL_GPL
+-0xf1395b13    snd_soc_put_xr_sx       vmlinux EXPORT_SYMBOL_GPL
+-0x4982a57f    probe_kernel_write      vmlinux EXPORT_SYMBOL_GPL
+-0x811dc334    usb_unregister_notify   vmlinux EXPORT_SYMBOL_GPL
+-0xa6f7283b    arp_create      vmlinux EXPORT_SYMBOL
+-0x660b5392    jbd2_journal_get_create_access  vmlinux EXPORT_SYMBOL
+-0x99dd4a27    no_llseek       vmlinux EXPORT_SYMBOL
+-0x72532806    _raw_read_unlock_irq    vmlinux EXPORT_SYMBOL
+-0xe4719990    rt_mutex_timed_lock     vmlinux EXPORT_SYMBOL_GPL
+-0xb5d9454c    printk_emit     vmlinux EXPORT_SYMBOL
+-0x801e5a15    st_sensors_check_device_support vmlinux EXPORT_SYMBOL
+-0xeec77f6d    iio_map_array_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0x6390efda    of_modalias_node        vmlinux EXPORT_SYMBOL_GPL
+-0x7ac03539    tty_port_alloc_xmit_buf vmlinux EXPORT_SYMBOL
+-0x5cebb76e    vfs_truncate    vmlinux EXPORT_SYMBOL_GPL
+-0xfc52a8aa    mmc_gpio_request_cd     vmlinux EXPORT_SYMBOL
+-0xf7a4e432    mmc_gpio_request_ro     vmlinux EXPORT_SYMBOL
+-0x74d52889    rtc_irq_set_freq        vmlinux EXPORT_SYMBOL_GPL
+-0x8e9efd84    dma_declare_coherent_memory     vmlinux EXPORT_SYMBOL
+-0xfcfa03ff    fb_videomode_to_modelist        vmlinux EXPORT_SYMBOL
+-0x789c0277    nfc_unregister_device   vmlinux EXPORT_SYMBOL
+-0x48744ce2    lro_receive_frags       vmlinux EXPORT_SYMBOL
+-0xf6851d5f    register_sysctl_paths   vmlinux EXPORT_SYMBOL
+-0x90a4a466    generic_show_options    vmlinux EXPORT_SYMBOL
+-0x74dd4a76    pagecache_write_begin   vmlinux EXPORT_SYMBOL
+-0x7b42b5d4    drm_mode_copy   vmlinux EXPORT_SYMBOL
+-0x6a7c03c7    asoc_dma_platform_register      vmlinux EXPORT_SYMBOL_GPL
+-0xc6cbbc89    capable vmlinux EXPORT_SYMBOL
+-0xd07125d9    spi_finalize_current_message    vmlinux EXPORT_SYMBOL_GPL
+-0xf5514ce6    dev_pm_qos_add_request  vmlinux EXPORT_SYMBOL_GPL
+-0xb316e246    nf_afinfo       vmlinux EXPORT_SYMBOL
+-0x4ef5bcf4    perf_swevent_get_recursion_context      vmlinux EXPORT_SYMBOL_GPL
+-0xab7e3362    irq_find_mapping        vmlinux EXPORT_SYMBOL_GPL
+-0xbcf89ab6    __wake_up_sync  vmlinux EXPORT_SYMBOL_GPL
+-0xc8b57c27    autoremove_wake_function        vmlinux EXPORT_SYMBOL
+-0x36aa3266    hid_debug_event vmlinux EXPORT_SYMBOL_GPL
+-0x9ed21fce    mmc_can_trim    vmlinux EXPORT_SYMBOL
+-0x5658ad69    v4l2_async_register_subdev      vmlinux EXPORT_SYMBOL
+-0x99781445    input_set_capability    vmlinux EXPORT_SYMBOL
+-0xf3343f80    drm_mode_create_tv_properties   vmlinux EXPORT_SYMBOL
+-0x69fefbb6    nf_ct_port_tuple_to_nlattr      vmlinux EXPORT_SYMBOL_GPL
+-0xd9a9bb30    getname vmlinux EXPORT_SYMBOL
+-0xe7ffe877    pcpu_base_addr  vmlinux EXPORT_SYMBOL_GPL
+-0x131e7ee8    drm_fb_helper_hotplug_event     vmlinux EXPORT_SYMBOL
+-0x983f0520    drm_fb_helper_initial_config    vmlinux EXPORT_SYMBOL
+-0x469972c2    give_up_console vmlinux EXPORT_SYMBOL
+-0x300573d1    nf_conntrack_helper_register    vmlinux EXPORT_SYMBOL_GPL
+-0x2597c27d    snd_seq_root    vmlinux EXPORT_SYMBOL
+-0x9a11a0fc    crypto_attr_alg_name    vmlinux EXPORT_SYMBOL_GPL
+-0xa0f2a42b    debugfs_create_regset32 vmlinux EXPORT_SYMBOL_GPL
+-0x3e08c129    drm_mode_find_dmt       vmlinux EXPORT_SYMBOL
+-0xbc8b0f41    xfrm_calg_get_byid      vmlinux EXPORT_SYMBOL_GPL
+-0xf20dabd8    free_irq        vmlinux EXPORT_SYMBOL
+-0x9073a3d4    usb_hc_died     vmlinux EXPORT_SYMBOL_GPL
+-0xe61a6d2f    gpio_unexport   vmlinux EXPORT_SYMBOL_GPL
+-0xdf58d91e    pinctrl_dev_get_name    vmlinux EXPORT_SYMBOL_GPL
+-0x4c3b5878    ieee80211_get_response_rate     vmlinux EXPORT_SYMBOL
+-0xa6b9609a    jbd2_journal_init_inode vmlinux EXPORT_SYMBOL
+-0xe91ef2b5    deactivate_locked_super vmlinux EXPORT_SYMBOL
+-0x0280cf55    filemap_fdatawait       vmlinux EXPORT_SYMBOL
+-0x134178d9    v4l2_m2m_fop_mmap       vmlinux EXPORT_SYMBOL_GPL
+-0x9091c717    netdev_class_create_file        vmlinux EXPORT_SYMBOL
+-0x4f816e9b    snd_pcm_format_big_endian       vmlinux EXPORT_SYMBOL
+-0x09d44df9    in_lock_functions       vmlinux EXPORT_SYMBOL
+-0x509817cf    vprintk_emit    vmlinux EXPORT_SYMBOL
+-0x4c571d12    cfg80211_cqm_pktloss_notify     vmlinux EXPORT_SYMBOL
+-0x8b260b7f    ip6_tnl_xmit_ctl        vmlinux EXPORT_SYMBOL_GPL
+-0x7b9e609a    ip6_sk_update_pmtu      vmlinux EXPORT_SYMBOL_GPL
+-0x199db92b    netdev_rx_handler_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0x4cdf24a6    skb_copy_datagram_const_iovec   vmlinux EXPORT_SYMBOL
+-0xb994401f    kernel_getpeername      vmlinux EXPORT_SYMBOL
+-0x7b10e656    sysfs_chmod_file        vmlinux EXPORT_SYMBOL_GPL
+-0x55d7c934    find_module     vmlinux EXPORT_SYMBOL_GPL
+-0x548b482c    rt_mutex_lock   vmlinux EXPORT_SYMBOL_GPL
+-0x39533602    media_entity_graph_walk_start   vmlinux EXPORT_SYMBOL_GPL
+-0x51ef2459    platform_driver_probe   vmlinux EXPORT_SYMBOL_GPL
+-0xeb93a8ee    serial8250_do_set_termios       vmlinux EXPORT_SYMBOL
+-0x8afc7ce3    __devm_of_phy_provider_register vmlinux EXPORT_SYMBOL_GPL
+-0x548fedb9    skb_complete_wifi_ack   vmlinux EXPORT_SYMBOL_GPL
+-0x11f7ed4c    hex_to_bin      vmlinux EXPORT_SYMBOL
+-0x9aeecd64    simple_pin_fs   vmlinux EXPORT_SYMBOL
+-0x5635a60a    vmalloc_user    vmlinux EXPORT_SYMBOL
+-0xd36ab13e    posix_clock_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0x1fe9f800    unregister_cpu_notifier vmlinux EXPORT_SYMBOL
+-0xb59a9548    vb2_expbuf      vmlinux EXPORT_SYMBOL_GPL
+-0xf6eb0d71    input_event     vmlinux EXPORT_SYMBOL
+-0xfc3a261f    dev_get_regmap  vmlinux EXPORT_SYMBOL_GPL
+-0x89d145ed    pin_config_get  vmlinux EXPORT_SYMBOL
+-0xc54fc2d7    devm_pinctrl_put        vmlinux EXPORT_SYMBOL_GPL
+-0x9671e047    devm_pinctrl_get        vmlinux EXPORT_SYMBOL_GPL
+-0x4d45d89e    udp_memory_allocated    vmlinux EXPORT_SYMBOL
+-0x3e8b4fda    tc_classify     vmlinux EXPORT_SYMBOL
+-0x98509e55    sock_no_sendpage        vmlinux EXPORT_SYMBOL
+-0x7bd6700d    blk_pre_runtime_suspend vmlinux EXPORT_SYMBOL
+-0x6444b7bb    iio_read_channel_raw    vmlinux EXPORT_SYMBOL_GPL
+-0x70120108    thermal_generate_netlink_event  vmlinux EXPORT_SYMBOL_GPL
+-0x800e4ffa    __muldi3        vmlinux EXPORT_SYMBOL
+-0x4c1182cb    bitmap_scnprintf        vmlinux EXPORT_SYMBOL
+-0xd7b4599b    __idr_get_new_above     vmlinux EXPORT_SYMBOL
+-0x368dc456    proc_create_data        vmlinux EXPORT_SYMBOL
+-0x4d405db8    param_ops_string        vmlinux EXPORT_SYMBOL
+-0xdd021b6b    get_current_tty vmlinux EXPORT_SYMBOL_GPL
+-0xabbaaf4c    kernel_getsockname      vmlinux EXPORT_SYMBOL
+-0x5caf4413    kernel_sendmsg  vmlinux EXPORT_SYMBOL
+-0x3971b4df    snd_ecards_limit        vmlinux EXPORT_SYMBOL
+-0xd77a5aa5    __bitmap_and    vmlinux EXPORT_SYMBOL
+-0xfac05b29    unregister_gadget_item  vmlinux EXPORT_SYMBOL
+-0x268930d0    uart_register_driver    vmlinux EXPORT_SYMBOL
+-0xace7ae5c    xfrm_alloc_spi  vmlinux EXPORT_SYMBOL
+-0x0a4a1a2f    blk_rq_err_bytes        vmlinux EXPORT_SYMBOL_GPL
+-0x6d414f53    crypto_blkcipher_type   vmlinux EXPORT_SYMBOL_GPL
+-0x2ffe9a6b    crypto_givcipher_type   vmlinux EXPORT_SYMBOL_GPL
+-0xe5ddcbd8    nfc_targets_found       vmlinux EXPORT_SYMBOL
+-0x028f3057    nf_log_packet   vmlinux EXPORT_SYMBOL
+-0xc8949349    qdisc_tree_decrease_qlen        vmlinux EXPORT_SYMBOL
+-0x7d16c025    dev_remove_pack vmlinux EXPORT_SYMBOL
+-0xf88eb7f2    rq_flush_dcache_pages   vmlinux EXPORT_SYMBOL_GPL
+-0x2d8764e5    blkcipher_walk_virt     vmlinux EXPORT_SYMBOL_GPL
+-0x5fce0dc6    posix_lock_file vmlinux EXPORT_SYMBOL
+-0x71a672ef    dmam_pool_destroy       vmlinux EXPORT_SYMBOL
+-0x3832da09    set_page_dirty  vmlinux EXPORT_SYMBOL
+-0xe4937b31    i2c_bit_algo    vmlinux EXPORT_SYMBOL
+-0x2c256e1f    input_scancode_to_scalar        vmlinux EXPORT_SYMBOL
+-0x758978d2    spi_get_next_queued_message     vmlinux EXPORT_SYMBOL_GPL
+-0xde9360ba    totalram_pages  vmlinux EXPORT_SYMBOL
+-0xacc53440    video_device_alloc      vmlinux EXPORT_SYMBOL
+-0x331f6073    udp_disconnect  vmlinux EXPORT_SYMBOL
+-0x8a5c060e    nf_conntrack_l4proto_udp4       vmlinux EXPORT_SYMBOL_GPL
+-0x492ab82c    dev_uc_unsync   vmlinux EXPORT_SYMBOL
+-0xb1615d69    dev_mc_unsync   vmlinux EXPORT_SYMBOL
+-0xa73acb8d    dump_seek       vmlinux EXPORT_SYMBOL
+-0xea63afac    usb_free_streams        vmlinux EXPORT_SYMBOL_GPL
+-0x0fb8623c    regcache_cache_only     vmlinux EXPORT_SYMBOL_GPL
+-0xb89f40b3    __register_chrdev       vmlinux EXPORT_SYMBOL
+-0x4ed5e0d7    v4l2_chip_match_host    vmlinux EXPORT_SYMBOL
+-0x78272b1e    bus_get_kset    vmlinux EXPORT_SYMBOL_GPL
+-0x87c0bce8    net_dma_find_channel    vmlinux EXPORT_SYMBOL
+-0xc31f408b    __display_entity_register       vmlinux EXPORT_SYMBOL_GPL
+-0x5b1cfbcd    of_get_fb_videomode     vmlinux EXPORT_SYMBOL_GPL
+-0xe6775a2f    fb_show_logo    vmlinux EXPORT_SYMBOL
+-0xa290f4a9    fb_pan_display  vmlinux EXPORT_SYMBOL
+-0x61c2dac6    kstrtoll_from_user      vmlinux EXPORT_SYMBOL
+-0x83904bc7    st_sensors_deallocate_trigger   vmlinux EXPORT_SYMBOL
+-0x7bc41c7c    rtc_class_close vmlinux EXPORT_SYMBOL_GPL
+-0x218b226c    sec_bulk_write  vmlinux EXPORT_SYMBOL_GPL
+-0xf09de776    get_random_int  vmlinux EXPORT_SYMBOL
+-0x5a937d99    blk_queue_stack_limits  vmlinux EXPORT_SYMBOL
+-0x174b7df6    free_vm_area    vmlinux EXPORT_SYMBOL_GPL
+-0x8ffa3ccd    devres_alloc    vmlinux EXPORT_SYMBOL_GPL
+-0x956a91ba    gpio_get_value_cansleep vmlinux EXPORT_SYMBOL_GPL
+-0x92886ef2    udp_lib_setsockopt      vmlinux EXPORT_SYMBOL
+-0xc4a35da7    udp_lib_getsockopt      vmlinux EXPORT_SYMBOL
+-0xdb1ed3be    nf_conntrack_free       vmlinux EXPORT_SYMBOL_GPL
+-0x96898769    sysfs_format_mac        vmlinux EXPORT_SYMBOL
+-0x15604324    sk_send_sigurg  vmlinux EXPORT_SYMBOL
+-0x8fca87b8    proc_set_size   vmlinux EXPORT_SYMBOL
+-0x4b5fd49e    dm_kcopyd_do_callback   vmlinux EXPORT_SYMBOL
+-0x289bc356    mdiobus_alloc_size      vmlinux EXPORT_SYMBOL
+-0xf36e7280    spi_bus_lock    vmlinux EXPORT_SYMBOL_GPL
+-0x0c060ece    cfg80211_sched_scan_stopped     vmlinux EXPORT_SYMBOL
+-0xab2289f2    drop_super      vmlinux EXPORT_SYMBOL
+-0x27e1a049    printk  vmlinux EXPORT_SYMBOL
+-0x3194878b    pm_generic_poweroff_noirq       vmlinux EXPORT_SYMBOL_GPL
+-0x688f09be    dev_crit        vmlinux EXPORT_SYMBOL
+-0xfd94d6cb    drm_get_connector_status_name   vmlinux EXPORT_SYMBOL
+-0xbdef1e6b    drm_gem_object_release  vmlinux EXPORT_SYMBOL
+-0x36fa2c4a    cfg80211_get_bss        vmlinux EXPORT_SYMBOL
+-0xef2e65fd    sk_alloc        vmlinux EXPORT_SYMBOL
+-0x096e7523    try_to_release_page     vmlinux EXPORT_SYMBOL
+-0xa61b1477    tracepoint_iter_start   vmlinux EXPORT_SYMBOL_GPL
+-0x9d05f6c4    ktime_get_clocktai      vmlinux EXPORT_SYMBOL
+-0x6a87a478    synchronize_srcu        vmlinux EXPORT_SYMBOL_GPL
+-0xa3afa3ce    bus_unregister_notifier vmlinux EXPORT_SYMBOL_GPL
+-0xbe001c53    drm_property_add_enum   vmlinux EXPORT_SYMBOL
+-0x48c2a99d    drm_helper_resume_force_mode    vmlinux EXPORT_SYMBOL
+-0x1258d9d9    regulator_disable       vmlinux EXPORT_SYMBOL_GPL
+-0x1b3261e0    klist_iter_init vmlinux EXPORT_SYMBOL_GPL
+-0xaeec4fd1    hci_conn_switch_role    vmlinux EXPORT_SYMBOL
+-0x8809bdee    kobject_add     vmlinux EXPORT_SYMBOL
+-0x10138352    tracing_on      vmlinux EXPORT_SYMBOL_GPL
+-0x39aa4754    dma_buf_mmap    vmlinux EXPORT_SYMBOL_GPL
+-0x58c6fc51    dma_buf_kmap    vmlinux EXPORT_SYMBOL_GPL
+-0x299bbc21    dma_buf_vmap    vmlinux EXPORT_SYMBOL_GPL
+-0x5a2579f9    platform_driver_register        vmlinux EXPORT_SYMBOL_GPL
+-0xa8d6809d    drm_dp_bw_code_to_link_rate     vmlinux EXPORT_SYMBOL
+-0xfd86731b    drm_fb_helper_init      vmlinux EXPORT_SYMBOL
+-0xd4880725    __video_source_register vmlinux EXPORT_SYMBOL_GPL
+-0xe08f4a3d    devm_of_phy_provider_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x61634f05    lock_flocks     vmlinux EXPORT_SYMBOL_GPL
+-0x3843f6b8    queue_kthread_work      vmlinux EXPORT_SYMBOL_GPL
+-0x8e332478    thermal_zone_get_temp   vmlinux EXPORT_SYMBOL_GPL
+-0xdd64085c    platform_driver_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0xaa6f23ad    rfkill_get_led_trigger_name     vmlinux EXPORT_SYMBOL
+-0x9cab34a6    rfkill_set_led_trigger_name     vmlinux EXPORT_SYMBOL
+-0x23b075bd    gnet_stats_copy_queue   vmlinux EXPORT_SYMBOL
+-0x12e85778    kstrtol_from_user       vmlinux EXPORT_SYMBOL
+-0x331504fa    simple_dir_operations   vmlinux EXPORT_SYMBOL
+-0x3eabdee4    of_match_device vmlinux EXPORT_SYMBOL
+-0x610e908e    hid_ignore      vmlinux EXPORT_SYMBOL_GPL
+-0x3838d3de    usb_get_urb     vmlinux EXPORT_SYMBOL_GPL
+-0xd400a944    cfg80211_gtk_rekey_notify       vmlinux EXPORT_SYMBOL
+-0x6403e338    tcp_memory_pressure     vmlinux EXPORT_SYMBOL
+-0x23a650aa    setattr_copy    vmlinux EXPORT_SYMBOL
+-0x6b6b3081    iommu_domain_has_cap    vmlinux EXPORT_SYMBOL_GPL
+-0xdd9fe08e    nfc_hci_driver_failure  vmlinux EXPORT_SYMBOL
+-0x091cae50    cfg80211_probe_status   vmlinux EXPORT_SYMBOL
+-0xa5e8f497    inet_frags_fini vmlinux EXPORT_SYMBOL
+-0xff048999    snd_register_oss_device vmlinux EXPORT_SYMBOL
+-0x24a94b26    snd_info_get_line       vmlinux EXPORT_SYMBOL
+-0x7ba9873c    elv_dispatch_sort       vmlinux EXPORT_SYMBOL
+-0x1471fd44    elv_add_request vmlinux EXPORT_SYMBOL
+-0x9be7bde4    security_tun_dev_attach vmlinux EXPORT_SYMBOL
+-0xf346231f    seq_list_start_head     vmlinux EXPORT_SYMBOL
+-0x65d9e877    cpufreq_register_notifier       vmlinux EXPORT_SYMBOL
+-0x399ed296    v4l2_subdev_link_validate_default       vmlinux EXPORT_SYMBOL_GPL
+-0xfb974dd4    v4l2_ctrl_auto_cluster  vmlinux EXPORT_SYMBOL
+-0xd9097364    v4l2_event_dequeue      vmlinux EXPORT_SYMBOL_GPL
+-0xd9a8b315    scsi_queue_work vmlinux EXPORT_SYMBOL_GPL
+-0xf564412a    __aeabi_ulcmp   vmlinux EXPORT_SYMBOL
+-0x67e6edc4    netif_device_attach     vmlinux EXPORT_SYMBOL
+-0x6c3962d5    netif_device_detach     vmlinux EXPORT_SYMBOL
+-0x7464ec66    netdev_set_default_ethtool_ops  vmlinux EXPORT_SYMBOL_GPL
+-0x08cf6c97    snd_soc_dai_digital_mute        vmlinux EXPORT_SYMBOL_GPL
+-0x47628784    simple_attr_read        vmlinux EXPORT_SYMBOL_GPL
+-0xe4bad1e4    sdhci_pltfm_init        vmlinux EXPORT_SYMBOL_GPL
+-0xe3b2bc37    gether_connect  vmlinux EXPORT_SYMBOL
+-0x2fe1cc7e    device_rename   vmlinux EXPORT_SYMBOL_GPL
+-0xc147be94    drm_i2c_encoder_restore vmlinux EXPORT_SYMBOL
+-0x56f369aa    kernel_bind     vmlinux EXPORT_SYMBOL
+-0xcd279169    nla_find        vmlinux EXPORT_SYMBOL
+-0x5cdf6de2    kernel_read     vmlinux EXPORT_SYMBOL
+-0xfcc43f3f    vfs_read        vmlinux EXPORT_SYMBOL
+-0xc8add232    ring_buffer_record_disable      vmlinux EXPORT_SYMBOL_GPL
+-0xf2e84b50    __devm_release_region   vmlinux EXPORT_SYMBOL
+-0xd4292ec2    dev_notice      vmlinux EXPORT_SYMBOL
+-0x02e6e099    drm_mode_width  vmlinux EXPORT_SYMBOL
+-0xcc248d26    serial8250_suspend_port vmlinux EXPORT_SYMBOL
+-0x4e6e8ea7    fg_console      vmlinux EXPORT_SYMBOL
+-0xbb9cc562    fl6_merge_options       vmlinux EXPORT_SYMBOL_GPL
+-0x20bf8fa2    __inet_hash_nolisten    vmlinux EXPORT_SYMBOL_GPL
+-0x9fb3dd30    memcpy_fromiovec        vmlinux EXPORT_SYMBOL
+-0x9cde26bf    blk_queue_prep_rq       vmlinux EXPORT_SYMBOL
+-0x262f20a8    local_clock     vmlinux EXPORT_SYMBOL_GPL
+-0x7ebf0ef8    __nf_nat_l4proto_find   vmlinux EXPORT_SYMBOL_GPL
+-0x503bc70a    drm_gem_prime_export    vmlinux EXPORT_SYMBOL
+-0x8d6f81b4    __div64_32      vmlinux EXPORT_SYMBOL
+-0x93fca811    __get_free_pages        vmlinux EXPORT_SYMBOL
+-0xbb189cad    disallow_signal vmlinux EXPORT_SYMBOL
+-0xefe5a9bf    usbnet_resume_rx        vmlinux EXPORT_SYMBOL_GPL
+-0x1c4116bc    __class_register        vmlinux EXPORT_SYMBOL_GPL
+-0x72cae0c9    nfc_driver_failure      vmlinux EXPORT_SYMBOL
+-0xc3d70f22    rawv6_mh_filter_register        vmlinux EXPORT_SYMBOL
+-0xdbcd416e    sysctl_ip_nonlocal_bind vmlinux EXPORT_SYMBOL
+-0xa675804c    utf8s_to_utf16s vmlinux EXPORT_SYMBOL
+-0xb4b97c90    pvclock_gtod_register_notifier  vmlinux EXPORT_SYMBOL_GPL
+-0xdf9d0875    ns_capable      vmlinux EXPORT_SYMBOL
+-0x13ba72ba    usb_free_coherent       vmlinux EXPORT_SYMBOL_GPL
+-0x4671c723    rawv6_mh_filter_unregister      vmlinux EXPORT_SYMBOL
+-0x5855bb11    blk_queue_resize_tags   vmlinux EXPORT_SYMBOL
+-0x5159ff6c    mmc_fixup_device        vmlinux EXPORT_SYMBOL
+-0x186b8590    ipv4_specific   vmlinux EXPORT_SYMBOL
+-0x9d5e9b60    nf_ct_l3proto_find_get  vmlinux EXPORT_SYMBOL_GPL
+-0x3f2c16f1    nf_ct_l4proto_find_get  vmlinux EXPORT_SYMBOL_GPL
+-0xe20a528d    nf_queue_entry_release_refs     vmlinux EXPORT_SYMBOL_GPL
+-0x4335fafb    proto_unregister        vmlinux EXPORT_SYMBOL
+-0x5762296f    fuse_conn_kill  vmlinux EXPORT_SYMBOL_GPL
+-0xe473e06d    __fsnotify_inode_delete vmlinux EXPORT_SYMBOL_GPL
+-0xe2ed7067    i2c_new_dummy   vmlinux EXPORT_SYMBOL_GPL
+-0x3cac21b9    regulator_sync_voltage  vmlinux EXPORT_SYMBOL_GPL
+-0x71e7aab0    from_kprojid_munged     vmlinux EXPORT_SYMBOL
+-0x3ca7e128    tty_unlock_pair vmlinux EXPORT_SYMBOL
+-0x146d2f0c    rtnl_af_register        vmlinux EXPORT_SYMBOL_GPL
+-0x97ecf37c    kunmap_high     vmlinux EXPORT_SYMBOL
+-0x4470a79b    param_ops_long  vmlinux EXPORT_SYMBOL
+-0x45bd9efd    dm_table_put    vmlinux EXPORT_SYMBOL
+-0xf2a353ac    v4l2_i2c_tuner_addrs    vmlinux EXPORT_SYMBOL_GPL
+-0xc7fd39bb    drm_dp_channel_eq_ok    vmlinux EXPORT_SYMBOL
+-0xa0472547    inet_csk_update_pmtu    vmlinux EXPORT_SYMBOL_GPL
+-0xacf4d843    match_strdup    vmlinux EXPORT_SYMBOL
+-0x870bf928    radix_tree_lookup       vmlinux EXPORT_SYMBOL
+-0x4672e88b    __crypto_dequeue_request        vmlinux EXPORT_SYMBOL_GPL
+-0x7b0f1ab3    ring_buffer_free_read_page      vmlinux EXPORT_SYMBOL_GPL
+-0x9745b34c    rt_mutex_unlock vmlinux EXPORT_SYMBOL_GPL
+-0xac745cfe    s3c_adc_read    vmlinux EXPORT_SYMBOL_GPL
+-0x4dc817ff    usb_composite_overwrite_options vmlinux EXPORT_SYMBOL_GPL
+-0xcd8ff108    neigh_seq_next  vmlinux EXPORT_SYMBOL
+-0xb4062ffd    vfs_rename      vmlinux EXPORT_SYMBOL
+-0xdc4ed03b    generic_ro_fops vmlinux EXPORT_SYMBOL
+-0x1300b437    nci_register_device     vmlinux EXPORT_SYMBOL
+-0xbcfcecc3    user_path_create        vmlinux EXPORT_SYMBOL
+-0xcf71a180    kthread_bind    vmlinux EXPORT_SYMBOL
+-0x4571f8be    usb_string_ids_n        vmlinux EXPORT_SYMBOL_GPL
+-0xf1ea24f2    ipv6_setsockopt vmlinux EXPORT_SYMBOL
+-0x2d97bed6    dm_kcopyd_zero  vmlinux EXPORT_SYMBOL
+-0xa1f5edea    drm_property_destroy    vmlinux EXPORT_SYMBOL
+-0x3548305a    inet_frag_find  vmlinux EXPORT_SYMBOL
+-0xf937428d    inetdev_by_index        vmlinux EXPORT_SYMBOL
+-0x33f234ad    __sk_backlog_rcv        vmlinux EXPORT_SYMBOL
+-0xb0fbdabc    crypto_lookup_skcipher  vmlinux EXPORT_SYMBOL_GPL
+-0xdf0f75c6    eventfd_signal  vmlinux EXPORT_SYMBOL_GPL
+-0x21f678b9    clocksource_unregister  vmlinux EXPORT_SYMBOL
+-0xe3b5bb1e    usb_poison_anchored_urbs        vmlinux EXPORT_SYMBOL_GPL
+-0x36003409    nfc_hci_send_event      vmlinux EXPORT_SYMBOL
+-0xd26c8ac5    bt_sock_wait_state      vmlinux EXPORT_SYMBOL
+-0x8bd1c81c    fifo_set_limit  vmlinux EXPORT_SYMBOL
+-0xe630ebe9    snd_soc_get_pcm_runtime vmlinux EXPORT_SYMBOL_GPL
+-0x9f7af994    writeback_in_progress   vmlinux EXPORT_SYMBOL
+-0x94048818    filemap_fdatawrite      vmlinux EXPORT_SYMBOL
+-0x9cc4f70a    register_pm_notifier    vmlinux EXPORT_SYMBOL_GPL
+-0xdf6f4023    phy_drivers_unregister  vmlinux EXPORT_SYMBOL
+-0x4cc1d9d6    con_debug_enter vmlinux EXPORT_SYMBOL_GPL
+-0x807d2b2c    xt_recseq       vmlinux EXPORT_SYMBOL_GPL
+-0x089e2060    __ethtool_get_settings  vmlinux EXPORT_SYMBOL
+-0xcdd9e311    dev_add_offload vmlinux EXPORT_SYMBOL
+-0x90ac3102    dev_base_lock   vmlinux EXPORT_SYMBOL
+-0xfcc256a6    css_id  vmlinux EXPORT_SYMBOL_GPL
+-0x2e7be112    _raw_read_lock_irqsave  vmlinux EXPORT_SYMBOL
+-0x284633c4    devm_clk_register       vmlinux EXPORT_SYMBOL_GPL
+-0x440982c5    usb_del_gadget_udc      vmlinux EXPORT_SYMBOL_GPL
+-0x0d7b25d8    drm_i2c_encoder_destroy vmlinux EXPORT_SYMBOL
+-0xd25d4f74    console_blank_hook      vmlinux EXPORT_SYMBOL
+-0x968b41f8    nfc_hci_unregister_device       vmlinux EXPORT_SYMBOL
+-0x71917221    xt_request_find_target  vmlinux EXPORT_SYMBOL_GPL
+-0x14ccc8d6    sg_scsi_ioctl   vmlinux EXPORT_SYMBOL_GPL
+-0xc22a3091    vm_unmap_aliases        vmlinux EXPORT_SYMBOL_GPL
+-0x936d3888    dm_kill_unmapped_request        vmlinux EXPORT_SYMBOL_GPL
+-0x56f3f495    vb2_querybuf    vmlinux EXPORT_SYMBOL
+-0xcd773fe8    gnet_stats_finish_copy  vmlinux EXPORT_SYMBOL
+-0x75ffa405    blk_fetch_request       vmlinux EXPORT_SYMBOL
+-0xc51700fb    free_inode_nonrcu       vmlinux EXPORT_SYMBOL
+-0x87471cdc    dma_pool_create vmlinux EXPORT_SYMBOL
+-0x4b34fbf5    block_all_signals       vmlinux EXPORT_SYMBOL
+-0x1910bed7    v4l2_m2m_next_buf       vmlinux EXPORT_SYMBOL_GPL
+-0xda6389c8    scsi_get_device_flags_keyed     vmlinux EXPORT_SYMBOL
+-0x384fda7f    device_show_int vmlinux EXPORT_SYMBOL_GPL
+-0x853ce11c    uart_handle_cts_change  vmlinux EXPORT_SYMBOL_GPL
+-0x2167989c    uart_handle_dcd_change  vmlinux EXPORT_SYMBOL_GPL
+-0x832c7303    cfg80211_chandef_compatible     vmlinux EXPORT_SYMBOL
+-0xb5aa7165    dma_pool_destroy        vmlinux EXPORT_SYMBOL
+-0x3a81993a    irq_create_strict_mappings      vmlinux EXPORT_SYMBOL_GPL
+-0xf7951d2a    sdio_writeb     vmlinux EXPORT_SYMBOL_GPL
+-0x73286449    gether_set_gadget       vmlinux EXPORT_SYMBOL
+-0x0958f0a1    gether_disconnect       vmlinux EXPORT_SYMBOL
+-0xc7141639    tty_name        vmlinux EXPORT_SYMBOL
+-0x52e54a99    udp6_csum_init  vmlinux EXPORT_SYMBOL
+-0x20c95ebb    __dev_remove_offload    vmlinux EXPORT_SYMBOL
+-0xff6104d0    snd_pcm_rate_bit_to_rate        vmlinux EXPORT_SYMBOL
+-0xcfa8d57b    sysfs_get_dirent        vmlinux EXPORT_SYMBOL_GPL
+-0x8e0d66f4    __tracepoint_kmalloc    vmlinux EXPORT_SYMBOL
+-0x3bfcc1f8    perf_event_release_kernel       vmlinux EXPORT_SYMBOL_GPL
+-0x8c03d20c    destroy_workqueue       vmlinux EXPORT_SYMBOL_GPL
+-0x7e36685b    of_dev_put      vmlinux EXPORT_SYMBOL
+-0x379d3e07    of_dev_get      vmlinux EXPORT_SYMBOL
+-0xf494f618    mmc_regulator_get_ocrmask       vmlinux EXPORT_SYMBOL_GPL
+-0xd9fb5e67    power_supply_register   vmlinux EXPORT_SYMBOL_GPL
+-0x3697b3a2    usb_assign_descriptors  vmlinux EXPORT_SYMBOL_GPL
+-0x6789d290    serial8250_register_8250_port   vmlinux EXPORT_SYMBOL
+-0xa34d0cc4    inet6_csk_reqsk_queue_hash_add  vmlinux EXPORT_SYMBOL_GPL
+-0x81de8eb2    inet_twsk_put   vmlinux EXPORT_SYMBOL_GPL
+-0x687019ad    fib_default_rule_add    vmlinux EXPORT_SYMBOL
+-0x8eef430a    fat_get_dotdot_entry    vmlinux EXPORT_SYMBOL_GPL
+-0x2a3f1eb3    check_disk_change       vmlinux EXPORT_SYMBOL
+-0xd5325933    default_file_splice_read        vmlinux EXPORT_SYMBOL
+-0xd83215e5    writeback_inodes_sb     vmlinux EXPORT_SYMBOL
+-0x506cc085    tracepoint_iter_stop    vmlinux EXPORT_SYMBOL_GPL
+-0xe200d2d5    param_get_uint  vmlinux EXPORT_SYMBOL
+-0x79cb0ce1    pm_generic_runtime_suspend      vmlinux EXPORT_SYMBOL_GPL
+-0x364477d8    do_SAK  vmlinux EXPORT_SYMBOL
+-0x8d9c96ee    elv_register    vmlinux EXPORT_SYMBOL_GPL
+-0x0c77c871    page_put_link   vmlinux EXPORT_SYMBOL
+-0x8f03ba03    release_pages   vmlinux EXPORT_SYMBOL
+-0xa4a39c18    v4l2_m2m_streamon       vmlinux EXPORT_SYMBOL_GPL
+-0xa2d6eedc    bt_sock_stream_recvmsg  vmlinux EXPORT_SYMBOL
+-0xb1bed25d    dpm_resume_start        vmlinux EXPORT_SYMBOL_GPL
+-0x10291853    devm_regulator_put      vmlinux EXPORT_SYMBOL_GPL
+-0xcf618a57    cfg80211_calculate_bitrate      vmlinux EXPORT_SYMBOL
+-0xa9f48f53    km_state_expired        vmlinux EXPORT_SYMBOL
+-0x6417850b    qdisc_list_del  vmlinux EXPORT_SYMBOL
+-0xb0e10781    get_option      vmlinux EXPORT_SYMBOL
+-0x6a3d6744    drm_property_create     vmlinux EXPORT_SYMBOL
+-0x60352082    register_inet6addr_notifier     vmlinux EXPORT_SYMBOL
+-0x7cabb84d    inet_accept     vmlinux EXPORT_SYMBOL
+-0x49b07aec    tcp_select_initial_window       vmlinux EXPORT_SYMBOL
+-0xd41766d2    nf_ct_gre_keymap_destroy        vmlinux EXPORT_SYMBOL_GPL
+-0x0b225b92    register_pernet_device  vmlinux EXPORT_SYMBOL_GPL
+-0xe697d108    __blk_iopoll_complete   vmlinux EXPORT_SYMBOL
+-0xa1c76e0a    _cond_resched   vmlinux EXPORT_SYMBOL
+-0x22e1ae6f    up_read vmlinux EXPORT_SYMBOL
+-0x9fbe4605    class_for_each_device   vmlinux EXPORT_SYMBOL_GPL
+-0x4c1e4dba    unbind_con_driver       vmlinux EXPORT_SYMBOL
+-0x352cbaad    empty_zero_page vmlinux EXPORT_SYMBOL
+-0x66f6b51b    nfnetlink_subsys_register       vmlinux EXPORT_SYMBOL_GPL
+-0x2de03b66    ndo_dflt_bridge_getlink vmlinux EXPORT_SYMBOL
+-0x1f404818    __pskb_pull_tail        vmlinux EXPORT_SYMBOL
+-0x848618a1    snd_pcm_lib_free_vmalloc_buffer vmlinux EXPORT_SYMBOL
+-0x11575bf3    bioset_free     vmlinux EXPORT_SYMBOL
+-0x2acf0feb    vfs_fstat       vmlinux EXPORT_SYMBOL
+-0x0c45fc96    vfs_lstat       vmlinux EXPORT_SYMBOL
+-0x20bc3470    orderly_poweroff        vmlinux EXPORT_SYMBOL_GPL
+-0xd0c74120    cpufreq_frequency_table_verify  vmlinux EXPORT_SYMBOL_GPL
+-0x93af794b    dev_alert       vmlinux EXPORT_SYMBOL
+-0x96cd86f2    tty_wait_until_sent     vmlinux EXPORT_SYMBOL
+-0x4384f1be    gether_setup_name       vmlinux EXPORT_SYMBOL
+-0xa598e29c    vesa_modes      vmlinux EXPORT_SYMBOL
+-0x4ead0283    pn_skb_send     vmlinux EXPORT_SYMBOL
+-0xc01a92eb    __netif_schedule        vmlinux EXPORT_SYMBOL
+-0xd42d86c0    generic_fh_to_parent    vmlinux EXPORT_SYMBOL_GPL
+-0x9eaba82f    generic_fillattr        vmlinux EXPORT_SYMBOL
+-0x183fa88b    mempool_alloc_slab      vmlinux EXPORT_SYMBOL
+-0x5d0b1892    param_set_invbool       vmlinux EXPORT_SYMBOL
+-0xe103ee04    gpio_export_link        vmlinux EXPORT_SYMBOL_GPL
+-0x24bfaf10    d_instantiate_unique    vmlinux EXPORT_SYMBOL
+-0xd6b8e852    request_threaded_irq    vmlinux EXPORT_SYMBOL
+-0x18bd76a4    _raw_spin_trylock       vmlinux EXPORT_SYMBOL
+-0xc2ffd5d5    iio_trigger_alloc       vmlinux EXPORT_SYMBOL
+-0xa749c072    i2c_register_driver     vmlinux EXPORT_SYMBOL
+-0x6ea05e17    of_phy_provider_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0xc359fb65    abort   vmlinux EXPORT_SYMBOL
+-0x9f0f5d05    cfg80211_send_unprot_disassoc   vmlinux EXPORT_SYMBOL
+-0xc575c737    debug_locks_off vmlinux EXPORT_SYMBOL_GPL
+-0xab2f97aa    jbd2_journal_forget     vmlinux EXPORT_SYMBOL
+-0xffea14aa    mutex_lock_interruptible        vmlinux EXPORT_SYMBOL
+-0xdb9cfd07    skb_clone       vmlinux EXPORT_SYMBOL
+-0x0cdd5fd1    crypto_find_alg vmlinux EXPORT_SYMBOL_GPL
+-0x076aff85    set_task_ioprio vmlinux EXPORT_SYMBOL_GPL
+-0x773522a8    setup_arg_pages vmlinux EXPORT_SYMBOL
+-0x430348ff    input_get_keycode       vmlinux EXPORT_SYMBOL
+-0x3c50bfc9    regmap_can_raw_write    vmlinux EXPORT_SYMBOL_GPL
+-0x8209afe6    wakeup_source_destroy   vmlinux EXPORT_SYMBOL_GPL
+-0x0487f831    fb_find_best_display    vmlinux EXPORT_SYMBOL
+-0x83dab696    inode_dio_wait  vmlinux EXPORT_SYMBOL
+-0xa3a19433    of_get_regulator_init_data      vmlinux EXPORT_SYMBOL_GPL
+-0x43ca0eb7    amba_request_regions    vmlinux EXPORT_SYMBOL
+-0xc34efe27    snmp_fold_field vmlinux EXPORT_SYMBOL_GPL
+-0x3e48e980    tcp_init_xmit_timers    vmlinux EXPORT_SYMBOL
+-0x267c8e5b    snd_soc_register_card   vmlinux EXPORT_SYMBOL_GPL
+-0x2d13dc4b    jbd2_journal_start      vmlinux EXPORT_SYMBOL
+-0xd67364f7    eventfd_ctx_fdget       vmlinux EXPORT_SYMBOL_GPL
+-0xaefaecb4    phy_ethtool_gset        vmlinux EXPORT_SYMBOL
+-0x86dded2c    phy_ethtool_sset        vmlinux EXPORT_SYMBOL
+-0x1b15cf75    drm_encoder_init        vmlinux EXPORT_SYMBOL
+-0x540ef2af    vfs_lock_file   vmlinux EXPORT_SYMBOL_GPL
+-0x56fcacd4    bio_uncopy_user vmlinux EXPORT_SYMBOL
+-0x9401ec10    make_bad_inode  vmlinux EXPORT_SYMBOL
+-0x8ec007a4    __d_drop        vmlinux EXPORT_SYMBOL
+-0x7f39e9f3    __mmdrop        vmlinux EXPORT_SYMBOL_GPL
+-0x731e1d9d    thermal_zone_device_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0x31528994    __i2c_transfer  vmlinux EXPORT_SYMBOL
+-0x33dbfd93    tcp_memory_allocated    vmlinux EXPORT_SYMBOL
+-0xa8232c78    strtobool       vmlinux EXPORT_SYMBOL
+-0xbe744811    jbd2_journal_force_commit_nested        vmlinux EXPORT_SYMBOL
+-0xce03751f    seq_release_private     vmlinux EXPORT_SYMBOL
+-0xd788742d    perf_trace_buf_prepare  vmlinux EXPORT_SYMBOL_GPL
+-0x269f017e    st_sensors_set_dataready_irq    vmlinux EXPORT_SYMBOL
+-0x379ea057    hid_check_keys_pressed  vmlinux EXPORT_SYMBOL_GPL
+-0xe19a7489    scsi_bus_type   vmlinux EXPORT_SYMBOL_GPL
+-0x11f13f3f    snd_ctl_remove  vmlinux EXPORT_SYMBOL
+-0xb7a5a52f    writeback_inodes_sb_nr  vmlinux EXPORT_SYMBOL
+-0x8efefdc1    vfs_removexattr vmlinux EXPORT_SYMBOL_GPL
+-0xbd7c9ac7    find_symbol     vmlinux EXPORT_SYMBOL_GPL
+-0xc6ca6078    __mutex_init    vmlinux EXPORT_SYMBOL
+-0xe8349cd8    uart_console_write      vmlinux EXPORT_SYMBOL_GPL
+-0x2e5810c6    __aeabi_unwind_cpp_pr1  vmlinux EXPORT_SYMBOL
+-0x80f711c7    jbd2_journal_check_used_features        vmlinux EXPORT_SYMBOL
+-0xcd91b127    system_highpri_wq       vmlinux EXPORT_SYMBOL_GPL
+-0x5d2137b0    sdio_readsb     vmlinux EXPORT_SYMBOL_GPL
+-0x6883e0d5    rtc_set_time    vmlinux EXPORT_SYMBOL_GPL
+-0xf753d6ff    drm_i2c_encoder_mode_set        vmlinux EXPORT_SYMBOL
+-0x0b0d888b    icmpv6_err_convert      vmlinux EXPORT_SYMBOL
+-0x908cb3fc    vfs_readv       vmlinux EXPORT_SYMBOL
+-0x3e467689    do_sync_write   vmlinux EXPORT_SYMBOL
+-0xe01edb1a    vb2_plane_vaddr vmlinux EXPORT_SYMBOL_GPL
+-0xff9c7899    fb_get_mode     vmlinux EXPORT_SYMBOL
+-0x63923641    crypto_shash_setkey     vmlinux EXPORT_SYMBOL_GPL
+-0x66c159c0    crypto_ahash_setkey     vmlinux EXPORT_SYMBOL_GPL
+-0xb2c17922    search_binary_handler   vmlinux EXPORT_SYMBOL
+-0x07438699    rt_mutex_trylock        vmlinux EXPORT_SYMBOL_GPL
+-0x559b763f    mmc_detect_change       vmlinux EXPORT_SYMBOL
+-0xed2c3cec    drm_debugfs_remove_files        vmlinux EXPORT_SYMBOL
+-0xea5c6ccb    rtnl_link_get_net       vmlinux EXPORT_SYMBOL
+-0x420c7411    ahash_attr_alg  vmlinux EXPORT_SYMBOL_GPL
+-0xc690866c    irq_work_queue  vmlinux EXPORT_SYMBOL_GPL
+-0x22640142    sdio_readw      vmlinux EXPORT_SYMBOL_GPL
+-0x246e1a87    sdio_readl      vmlinux EXPORT_SYMBOL_GPL
+-0xafb35b17    sdio_readb      vmlinux EXPORT_SYMBOL_GPL
+-0x713125bd    cpufreq_freq_attr_scaling_available_freqs       vmlinux EXPORT_SYMBOL_GPL
+-0xd7095481    usb_remove_phy  vmlinux EXPORT_SYMBOL_GPL
+-0x76d878f8    usb_remove_hcd  vmlinux EXPORT_SYMBOL_GPL
+-0x7e543e70    device_store_bool       vmlinux EXPORT_SYMBOL_GPL
+-0x407136b1    __put_user_8    vmlinux EXPORT_SYMBOL
+-0x1567020f    tcp_disconnect  vmlinux EXPORT_SYMBOL
+-0x1f615e38    bio_pair_release        vmlinux EXPORT_SYMBOL
+-0x2469810f    __rcu_read_unlock       vmlinux EXPORT_SYMBOL_GPL
+-0xea51d53a    extcon_get_extcon_dev   vmlinux EXPORT_SYMBOL_GPL
+-0x52c47236    put_device      vmlinux EXPORT_SYMBOL_GPL
+-0x194eadaa    drm_edid_header_is_valid        vmlinux EXPORT_SYMBOL
+-0x7d89e34a    drm_gtf_mode_complex    vmlinux EXPORT_SYMBOL
+-0x75c2b9f1    memalloc_socks  vmlinux EXPORT_SYMBOL_GPL
+-0xb10dfa5a    register_filesystem     vmlinux EXPORT_SYMBOL
+-0x758a782e    blk_fill_rwbs   vmlinux EXPORT_SYMBOL_GPL
+-0xba497f13    loops_per_jiffy vmlinux EXPORT_SYMBOL
+-0xc657abdc    v4l2_ctrl_subscribe_event       vmlinux EXPORT_SYMBOL
+-0xc7472c0b    devm_input_allocate_device      vmlinux EXPORT_SYMBOL
+-0xdb2c2fbf    spi_alloc_device        vmlinux EXPORT_SYMBOL_GPL
+-0xa33be4ce    inet_confirm_addr       vmlinux EXPORT_SYMBOL
+-0x48eb98d1    eth_validate_addr       vmlinux EXPORT_SYMBOL
+-0xc5718627    sg_copy_to_buffer       vmlinux EXPORT_SYMBOL
+-0x7ab88a45    system_freezing_cnt     vmlinux EXPORT_SYMBOL
+-0x7d0db45c    jiffies_to_clock_t      vmlinux EXPORT_SYMBOL
+-0x2c208607    power_supply_is_system_supplied vmlinux EXPORT_SYMBOL_GPL
+-0xc9422c05    devm_usb_get_phy_dev    vmlinux EXPORT_SYMBOL_GPL
+-0xba3a6941    drm_getsarea    vmlinux EXPORT_SYMBOL
+-0x1ffe8e3f    nfc_register_device     vmlinux EXPORT_SYMBOL
+-0x0478373c    generic_make_request    vmlinux EXPORT_SYMBOL
+-0x0b9a91be    generic_file_llseek_size        vmlinux EXPORT_SYMBOL
+-0x1c87a811    __round_jiffies_up      vmlinux EXPORT_SYMBOL_GPL
+-0x93d6ad2c    usb_debug_root  vmlinux EXPORT_SYMBOL_GPL
+-0xd3ce47fe    drm_mode_crtc_set_gamma_size    vmlinux EXPORT_SYMBOL
+-0xbe16ad70    drm_addbufs_pci vmlinux EXPORT_SYMBOL
+-0xd5dae19f    regulator_get_exclusive vmlinux EXPORT_SYMBOL_GPL
+-0x02124474    ip_send_check   vmlinux EXPORT_SYMBOL
+-0x628cbfaa    rtmsg_ifinfo    vmlinux EXPORT_SYMBOL
+-0xb0d3bca5    __rtnl_register vmlinux EXPORT_SYMBOL_GPL
+-0x23b9d6e2    mangle_path     vmlinux EXPORT_SYMBOL
+-0xe7c52663    v4l2_m2m_create_bufs    vmlinux EXPORT_SYMBOL_GPL
+-0x63625aaa    usb_composite_setup_continue    vmlinux EXPORT_SYMBOL_GPL
+-0x41f53df0    anon_inode_getfd        vmlinux EXPORT_SYMBOL_GPL
+-0x24d5ba21    filemap_flush   vmlinux EXPORT_SYMBOL
+-0xb49f6bea    iio_enum_write  vmlinux EXPORT_SYMBOL_GPL
+-0x1bfbfeeb    mc1n2_set_mclk_source   vmlinux EXPORT_SYMBOL
+-0x95e6e500    blk_stack_limits        vmlinux EXPORT_SYMBOL
+-0xeb46c362    fuse_conn_init  vmlinux EXPORT_SYMBOL_GPL
+-0x0e9003db    pm_generic_freeze_late  vmlinux EXPORT_SYMBOL_GPL
+-0xf2fa6c7e    drm_gem_vm_close        vmlinux EXPORT_SYMBOL
+-0x5bbc0a12    __fib_lookup    vmlinux EXPORT_SYMBOL_GPL
+-0x1dd6e42b    tcp_set_state   vmlinux EXPORT_SYMBOL_GPL
+-0xa77d88f6    strnlen_user    vmlinux EXPORT_SYMBOL
+-0x191ef206    i2c_smbus_read_i2c_block_data   vmlinux EXPORT_SYMBOL
+-0x52b992dc    drm_kms_helper_poll_disable     vmlinux EXPORT_SYMBOL
+-0x6fc997a4    tty_mutex       vmlinux EXPORT_SYMBOL
+-0x3973c5f8    kunmap  vmlinux EXPORT_SYMBOL
+-0xb28f5ef1    xt_free_table_info      vmlinux EXPORT_SYMBOL
+-0x1d0b568b    mnt_pin vmlinux EXPORT_SYMBOL
+-0x50ba53b9    set_create_files_as     vmlinux EXPORT_SYMBOL
+-0xcbd3dbd0    serial8250_modem_status vmlinux EXPORT_SYMBOL_GPL
+-0xe38dd51c    dev_get_by_name vmlinux EXPORT_SYMBOL
+-0x69458fd5    snd_dma_alloc_pages_fallback    vmlinux EXPORT_SYMBOL
+-0xb3fda4b7    __page_symlink  vmlinux EXPORT_SYMBOL
+-0x400fb79c    install_exec_creds      vmlinux EXPORT_SYMBOL
+-0xbed3ae54    sched_setscheduler      vmlinux EXPORT_SYMBOL_GPL
+-0xeb923e09    power_supply_set_battery_charged        vmlinux EXPORT_SYMBOL_GPL
+-0xfdab6de3    unregister_sound_midi   vmlinux EXPORT_SYMBOL
+-0x30a80826    __kfifo_from_user       vmlinux EXPORT_SYMBOL
+-0x6923ce63    irq_work_sync   vmlinux EXPORT_SYMBOL_GPL
+-0xe7197773    drm_ht_insert_item      vmlinux EXPORT_SYMBOL
+-0xdf75f3c9    ipcomp_input    vmlinux EXPORT_SYMBOL_GPL
+-0xac966a6d    udp_prot        vmlinux EXPORT_SYMBOL
+-0xc6531cd4    inet_putpeer    vmlinux EXPORT_SYMBOL_GPL
+-0xe2b955e2    nat_h245_hook   vmlinux EXPORT_SYMBOL_GPL
+-0xf34732f2    netif_set_xps_queue     vmlinux EXPORT_SYMBOL
+-0x7681d145    snd_ctl_register_ioctl  vmlinux EXPORT_SYMBOL
+-0xaae48971    mmc_card_sleep  vmlinux EXPORT_SYMBOL
+-0x58fe6474    v4l2_m2m_ioctl_qbuf     vmlinux EXPORT_SYMBOL_GPL
+-0x00d1d0d0    i2c_adapter_type        vmlinux EXPORT_SYMBOL_GPL
+-0xb971ebca    rndis_get_next_response vmlinux EXPORT_SYMBOL
+-0xc88b565d    inet6_sk_rebuild_header vmlinux EXPORT_SYMBOL_GPL
+-0x83a4c277    mb_cache_shrink vmlinux EXPORT_SYMBOL
+-0xf1e98c74    avenrun vmlinux EXPORT_SYMBOL
+-0x1318fa1c    __ww_mutex_lock_interruptible   vmlinux EXPORT_SYMBOL
+-0x2d3385d3    system_wq       vmlinux EXPORT_SYMBOL
+-0x94e4e64e    v4l2_event_queue        vmlinux EXPORT_SYMBOL_GPL
+-0x76fd0937    device_init_wakeup      vmlinux EXPORT_SYMBOL_GPL
+-0x40a6f522    __arm_ioremap   vmlinux EXPORT_SYMBOL
+-0xc2165d85    __arm_iounmap   vmlinux EXPORT_SYMBOL
+-0xaf50e76d    elf_set_personality     vmlinux EXPORT_SYMBOL
+-0xd9f8f32d    nf_ct_extend_register   vmlinux EXPORT_SYMBOL_GPL
+-0x6ceb8cf4    mark_page_accessed      vmlinux EXPORT_SYMBOL
+-0x17f36c02    mmc_calc_max_discard    vmlinux EXPORT_SYMBOL
+-0x0d45c48f    v4l2_clk_register       vmlinux EXPORT_SYMBOL
+-0x123959a1    v4l2_type_names vmlinux EXPORT_SYMBOL
+-0x02a18c74    nf_conntrack_destroy    vmlinux EXPORT_SYMBOL
+-0x679f4b6b    scsi_report_bus_reset   vmlinux EXPORT_SYMBOL
+-0xf8224b12    mali_get_user_setting   vmlinux EXPORT_SYMBOL
+-0x3c93ad98    tty_port_install        vmlinux EXPORT_SYMBOL_GPL
+-0x63fb81e4    brcmu_pktq_penq drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x723a1683    brcmu_pktq_pdeq drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0xfa595453    ip6_sk_dst_lookup_flow  vmlinux EXPORT_SYMBOL_GPL
+-0xa76f7e50    snd_dma_get_reserved_buf        vmlinux EXPORT_SYMBOL
+-0x61ed1c8e    cdev_add        vmlinux EXPORT_SYMBOL
+-0x69447467    ring_buffer_write       vmlinux EXPORT_SYMBOL_GPL
+-0xfcd7bc0b    ring_buffer_empty       vmlinux EXPORT_SYMBOL_GPL
+-0x82939ebd    rcu_batches_completed_sched     vmlinux EXPORT_SYMBOL_GPL
+-0x9e44b9b7    of_get_next_available_child     vmlinux EXPORT_SYMBOL
+-0x1010f1ee    hid_output_report       vmlinux EXPORT_SYMBOL_GPL
+-0x59e5070d    __do_div64      vmlinux EXPORT_SYMBOL
+-0xa2d91fcc    xfrm_input      vmlinux EXPORT_SYMBOL
+-0x07a62853    dev_mc_add      vmlinux EXPORT_SYMBOL
+-0x40908b29    dev_mc_del      vmlinux EXPORT_SYMBOL
+-0x2eed048e    dev_uc_add      vmlinux EXPORT_SYMBOL
+-0x69dba7f4    dev_uc_del      vmlinux EXPORT_SYMBOL
+-0x15361516    register_pernet_subsys  vmlinux EXPORT_SYMBOL_GPL
+-0x915be34a    snd_timer_new   vmlinux EXPORT_SYMBOL
+-0x3c45a56f    blk_queue_update_dma_pad        vmlinux EXPORT_SYMBOL
+-0x069d40a0    blkdev_get_by_path      vmlinux EXPORT_SYMBOL
+-0xa440bdfe    open_exec       vmlinux EXPORT_SYMBOL
+-0x374682ce    rtc_update_irq  vmlinux EXPORT_SYMBOL_GPL
+-0xba2d0719    drm_mode_hsync  vmlinux EXPORT_SYMBOL
+-0x2d7a787f    drm_dp_clock_recovery_ok        vmlinux EXPORT_SYMBOL
+-0xd59b2bb0    fb_blank        vmlinux EXPORT_SYMBOL
+-0x0b48677a    __kfifo_init    vmlinux EXPORT_SYMBOL
+-0x249c96e2    mb_cache_entry_find_next        vmlinux EXPORT_SYMBOL
+-0xaee2539e    inode_init_owner        vmlinux EXPORT_SYMBOL
+-0x7b24ccb3    file_ns_capable vmlinux EXPORT_SYMBOL
+-0x37c0412f    cpu_subsys      vmlinux EXPORT_SYMBOL_GPL
+-0x9993bf08    rt_mutex_destroy        vmlinux EXPORT_SYMBOL_GPL
+-0xd4034828    system_freezable_wq     vmlinux EXPORT_SYMBOL_GPL
+-0x9963a089    queue_delayed_work_on   vmlinux EXPORT_SYMBOL
+-0x1284891b    iio_trigger_notify_done vmlinux EXPORT_SYMBOL
+-0x03212586    v4l2_m2m_streamoff      vmlinux EXPORT_SYMBOL_GPL
+-0x5b19634d    div_s64_rem     vmlinux EXPORT_SYMBOL
+-0xb110bb66    __set_page_dirty_nobuffers      vmlinux EXPORT_SYMBOL
+-0xd7d79132    put_online_cpus vmlinux EXPORT_SYMBOL_GPL
+-0x121e3c12    devres_open_group       vmlinux EXPORT_SYMBOL_GPL
+-0x8eae4744    __nf_ct_kill_acct       vmlinux EXPORT_SYMBOL_GPL
+-0xcf88625f    mempool_create_node     vmlinux EXPORT_SYMBOL
+-0x222fa684    lg_global_lock  vmlinux EXPORT_SYMBOL
+-0x7cb2eca1    find_get_pid    vmlinux EXPORT_SYMBOL_GPL
+-0x971ad8d8    usbnet_unlink_rx_urbs   vmlinux EXPORT_SYMBOL_GPL
+-0xa551b417    devm_pwm_get    vmlinux EXPORT_SYMBOL_GPL
+-0xb138607d    dev_set_promiscuity     vmlinux EXPORT_SYMBOL
+-0xc8ca31af    timed_output_dev_register       vmlinux EXPORT_SYMBOL_GPL
+-0x2967cbf7    dm_get_rq_mapinfo       vmlinux EXPORT_SYMBOL_GPL
+-0x07013243    scsi_bios_ptable        vmlinux EXPORT_SYMBOL
+-0x9780e683    pm_generic_resume       vmlinux EXPORT_SYMBOL_GPL
+-0x3074f033    drm_order       vmlinux EXPORT_SYMBOL
+-0xa87f4ece    neigh_connected_output  vmlinux EXPORT_SYMBOL
+-0xe9f7149c    zlib_deflate_workspacesize      vmlinux EXPORT_SYMBOL
+-0x2d03c10d    posix_acl_create        vmlinux EXPORT_SYMBOL
+-0xbe254e92    param_set_ushort        vmlinux EXPORT_SYMBOL
+-0xf0ca36cf    drm_prime_init_file_private     vmlinux EXPORT_SYMBOL
+-0xb001e18c    drm_plane_init  vmlinux EXPORT_SYMBOL
+-0xb2922319    bt_sock_recvmsg vmlinux EXPORT_SYMBOL
+-0xe7f38f6d    udp_flush_pending_frames        vmlinux EXPORT_SYMBOL
+-0xf0726368    dev_get_stats   vmlinux EXPORT_SYMBOL
+-0xd3f7e5cc    snd_soc_default_volatile_register       vmlinux EXPORT_SYMBOL_GPL
+-0x92c5fcb5    snd_timer_notify        vmlinux EXPORT_SYMBOL
+-0x86fb9b05    bitmap_parse_user       vmlinux EXPORT_SYMBOL
+-0x01000e51    schedule        vmlinux EXPORT_SYMBOL
+-0xbd597aa3    usb_add_function        vmlinux EXPORT_SYMBOL_GPL
+-0x460e4737    pm_generic_poweroff     vmlinux EXPORT_SYMBOL_GPL
+-0x6920e885    nlmsg_notify    vmlinux EXPORT_SYMBOL
+-0x247a1d7a    ww_mutex_unlock vmlinux EXPORT_SYMBOL
+-0x1498f6af    mmput   vmlinux EXPORT_SYMBOL_GPL
+-0x709eb78b    init_task       vmlinux EXPORT_SYMBOL
+-0x3052a0ee    watchdog_unregister_device      vmlinux EXPORT_SYMBOL_GPL
+-0x80eaa56e    drm_i2c_encoder_save    vmlinux EXPORT_SYMBOL
+-0xe540813f    drm_property_create_enum        vmlinux EXPORT_SYMBOL
+-0x6c642207    drm_get_connector_name  vmlinux EXPORT_SYMBOL
+-0x42151efa    balloon_devinfo_alloc   vmlinux EXPORT_SYMBOL_GPL
+-0xfa544711    video_devdata   vmlinux EXPORT_SYMBOL
+-0x8e9618cd    wakeup_source_create    vmlinux EXPORT_SYMBOL_GPL
+-0x72f12e79    drm_probe_ddc   vmlinux EXPORT_SYMBOL
+-0x89d66811    build_ehash_secret      vmlinux EXPORT_SYMBOL
+-0xf4329926    __inet_twsk_hashdance   vmlinux EXPORT_SYMBOL_GPL
+-0xd0e13603    gnet_stats_copy_app     vmlinux EXPORT_SYMBOL
+-0x1b015d25    bitmap_parselist        vmlinux EXPORT_SYMBOL
+-0xf91bf3db    __insert_inode_hash     vmlinux EXPORT_SYMBOL
+-0x308b733a    getboottime     vmlinux EXPORT_SYMBOL_GPL
+-0x69f04aa3    revert_creds    vmlinux EXPORT_SYMBOL
+-0xdf929370    fs_overflowgid  vmlinux EXPORT_SYMBOL
+-0xa1177bf1    i2c_verify_client       vmlinux EXPORT_SYMBOL
+-0x0e5358d0    input_allocate_device   vmlinux EXPORT_SYMBOL
+-0x4fed4ee0    pm_runtime_barrier      vmlinux EXPORT_SYMBOL_GPL
+-0xb939d297    dev_printk      vmlinux EXPORT_SYMBOL
+-0x090849e3    phy_power_on    vmlinux EXPORT_SYMBOL_GPL
+-0x47416e14    cpu_rmap_add    vmlinux EXPORT_SYMBOL
+-0x08fbaf94    xfrm_policy_walk        vmlinux EXPORT_SYMBOL
+-0x774846b4    nf_log_unset    vmlinux EXPORT_SYMBOL
+-0x00aaf0d4    wm_hubs_add_analogue_routes     vmlinux EXPORT_SYMBOL_GPL
+-0xe9d7e477    snd_card_proc_new       vmlinux EXPORT_SYMBOL
+-0x97de2b83    debug_locks_silent      vmlinux EXPORT_SYMBOL_GPL
+-0x3e452a00    blocking_notifier_call_chain    vmlinux EXPORT_SYMBOL_GPL
+-0xae83dc8c    spi_bitbang_setup_transfer      vmlinux EXPORT_SYMBOL_GPL
+-0x8d871961    cpu_tlb vmlinux EXPORT_SYMBOL
+-0xfe694f5b    regmap_read     vmlinux EXPORT_SYMBOL_GPL
+-0x594bf15b    ioport_map      vmlinux EXPORT_SYMBOL
+-0x2d3abae7    __skb_checksum_complete vmlinux EXPORT_SYMBOL
+-0xb5a459dc    unregister_blkdev       vmlinux EXPORT_SYMBOL
+-0xd0a8eac3    write_inode_now vmlinux EXPORT_SYMBOL
+-0x7d3a11d4    tty_lock        vmlinux EXPORT_SYMBOL
+-0xa6dea12e    regulator_register      vmlinux EXPORT_SYMBOL_GPL
+-0x0ce021b8    ieee80211_amsdu_to_8023s        vmlinux EXPORT_SYMBOL
+-0xe0088286    fat_search_long vmlinux EXPORT_SYMBOL_GPL
+-0x08ca5b31    seq_path        vmlinux EXPORT_SYMBOL
+-0xcc5005fe    msleep_interruptible    vmlinux EXPORT_SYMBOL
+-0x2f0d9053    usb_otg_state_string    vmlinux EXPORT_SYMBOL_GPL
+-0xf2997713    tty_termios_hw_change   vmlinux EXPORT_SYMBOL
+-0x53893194    dev_addr_add    vmlinux EXPORT_SYMBOL
+-0x0dd3fd84    netdev_err      vmlinux EXPORT_SYMBOL
+-0x62849ac7    dev_valid_name  vmlinux EXPORT_SYMBOL
+-0x193466be    kfree_skb_partial       vmlinux EXPORT_SYMBOL
+-0xd2a941d4    sg_init_table   vmlinux EXPORT_SYMBOL
+-0x5642793a    radix_tree_tag_clear    vmlinux EXPORT_SYMBOL
+-0xc3bb6d9e    blk_pre_runtime_resume  vmlinux EXPORT_SYMBOL
+-0xd3a7747d    fsnotify        vmlinux EXPORT_SYMBOL_GPL
+-0x4f3b569c    generic_file_open       vmlinux EXPORT_SYMBOL
+-0xc87c1f84    ktime_get       vmlinux EXPORT_SYMBOL_GPL
+-0x89bbafc6    usb_register_notify     vmlinux EXPORT_SYMBOL_GPL
+-0x19ac480a    cfg80211_new_sta        vmlinux EXPORT_SYMBOL
+-0xd18ba458    generic_cont_expand_simple      vmlinux EXPORT_SYMBOL
+-0x5cf6467f    d_instantiate   vmlinux EXPORT_SYMBOL
+-0xd1ef6f16    genphy_update_link      vmlinux EXPORT_SYMBOL
+-0x4a77677a    nfc_hci_recv_frame      vmlinux EXPORT_SYMBOL
+-0xc2a19d85    register_sound_special_device   vmlinux EXPORT_SYMBOL
+-0x5b3060c4    blk_queue_rq_timed_out  vmlinux EXPORT_SYMBOL_GPL
+-0x2cbfd99b    vb2_queue_init  vmlinux EXPORT_SYMBOL_GPL
+-0x955d725c    drm_mm_scan_remove_block        vmlinux EXPORT_SYMBOL
+-0x6d346792    pin_config_group_get    vmlinux EXPORT_SYMBOL
+-0xf82a1863    pin_config_group_set    vmlinux EXPORT_SYMBOL
+-0x08c473b7    xt_alloc_table_info     vmlinux EXPORT_SYMBOL
+-0xb7b61546    crc32_be        vmlinux EXPORT_SYMBOL
+-0x26520970    vm_memory_committed     vmlinux EXPORT_SYMBOL_GPL
+-0xcf283b4f    iommu_domain_alloc      vmlinux EXPORT_SYMBOL_GPL
+-0x52ffd07f    xfrm_output_resume      vmlinux EXPORT_SYMBOL_GPL
+-0x4c21e163    skb_find_text   vmlinux EXPORT_SYMBOL
+-0x5279b639    current_fs_time vmlinux EXPORT_SYMBOL
+-0x04cc0a21    i2c_unregister_device   vmlinux EXPORT_SYMBOL_GPL
+-0x13fc56de    drm_helper_crtc_in_use  vmlinux EXPORT_SYMBOL
+-0x6d399587    regulator_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0x6b037ba6    nf_nat_l4proto_unregister       vmlinux EXPORT_SYMBOL_GPL
+-0x8231a8bd    nf_nat_l3proto_unregister       vmlinux EXPORT_SYMBOL_GPL
+-0x6350314b    tcf_hash_create vmlinux EXPORT_SYMBOL
+-0xf339287c    skb_queue_tail  vmlinux EXPORT_SYMBOL
+-0x5409775b    free_irq_cpu_rmap       vmlinux EXPORT_SYMBOL
+-0x65771426    crypto_lookup_template  vmlinux EXPORT_SYMBOL_GPL
+-0xd61347c6    register_sysctl vmlinux EXPORT_SYMBOL
+-0xd8c37e37    vfs_test_lock   vmlinux EXPORT_SYMBOL_GPL
+-0x952664c5    do_exit vmlinux EXPORT_SYMBOL_GPL
+-0xcb07e4af    tcf_hash_destroy        vmlinux EXPORT_SYMBOL
+-0x78953de6    mark_buffer_dirty_inode vmlinux EXPORT_SYMBOL
+-0x3109b751    cpu_clock       vmlinux EXPORT_SYMBOL_GPL
+-0xdf842e2b    drm_vblank_cleanup      vmlinux EXPORT_SYMBOL
+-0x57810201    ip_tunnel_lookup        vmlinux EXPORT_SYMBOL_GPL
+-0xb1c3a01a    oops_in_progress        vmlinux EXPORT_SYMBOL
+-0x0fca29c0    dev_pm_qos_remove_request       vmlinux EXPORT_SYMBOL_GPL
+-0xc407a137    dma_wait_for_async_tx   vmlinux EXPORT_SYMBOL_GPL
+-0x046a9d1b    backlight_device_register       vmlinux EXPORT_SYMBOL
+-0x2a36b31a    nf_ct_helper_log        vmlinux EXPORT_SYMBOL_GPL
+-0xb442919d    blk_get_backing_dev_info        vmlinux EXPORT_SYMBOL
+-0x0ed2f3b5    elevator_init   vmlinux EXPORT_SYMBOL
+-0x21bda10a    kill_fasync     vmlinux EXPORT_SYMBOL
+-0x622dacba    tick_nohz_idle_enter    vmlinux EXPORT_SYMBOL_GPL
+-0xdd4a5569    param_get_byte  vmlinux EXPORT_SYMBOL
+-0x764d38f1    tty_insert_flip_string_fixed_flag       vmlinux EXPORT_SYMBOL
+-0xcf5bc354    tty_register_ldisc      vmlinux EXPORT_SYMBOL
+-0x88f68355    tty_throttle    vmlinux EXPORT_SYMBOL
+-0x335e720e    tty_check_change        vmlinux EXPORT_SYMBOL
+-0x1d5568cb    dev_disable_lro vmlinux EXPORT_SYMBOL
+-0xb2be6e92    netdev_stats_to_stats64 vmlinux EXPORT_SYMBOL
+-0x728261ca    kblockd_schedule_delayed_work   vmlinux EXPORT_SYMBOL
+-0x5c959646    debugfs_create_u8       vmlinux EXPORT_SYMBOL_GPL
+-0x0c150d31    cgroup_taskset_first    vmlinux EXPORT_SYMBOL_GPL
+-0xec690544    attribute_container_classdev_to_container       vmlinux EXPORT_SYMBOL_GPL
+-0xda1613df    drm_put_dev     vmlinux EXPORT_SYMBOL
+-0x157667da    drm_gem_vm_open vmlinux EXPORT_SYMBOL
+-0x8ad8d79e    drm_fb_helper_setcmap   vmlinux EXPORT_SYMBOL
+-0x5550f136    snd_soc_dapm_info_pin_switch    vmlinux EXPORT_SYMBOL_GPL
+-0xcb08eeba    drm_core_ioremap        vmlinux EXPORT_SYMBOL
+-0x6aba167a    regulator_list_voltage  vmlinux EXPORT_SYMBOL_GPL
+-0x1b0ac272    __tracepoint_kmalloc_node       vmlinux EXPORT_SYMBOL
+-0xd62c833f    schedule_timeout        vmlinux EXPORT_SYMBOL
+-0x432fd7f6    __gpio_set_value        vmlinux EXPORT_SYMBOL_GPL
+-0x6c8d5ae8    __gpio_get_value        vmlinux EXPORT_SYMBOL_GPL
+-0x65ccb6f0    call_netevent_notifiers vmlinux EXPORT_SYMBOL_GPL
+-0x4a7fb243    percpu_counter_compare  vmlinux EXPORT_SYMBOL
+-0xced58760    crypto_alloc_base       vmlinux EXPORT_SYMBOL_GPL
+-0xfcf2f8c0    aio_put_req     vmlinux EXPORT_SYMBOL
+-0x6f3a36eb    dw_mci_pltfm_pmops      vmlinux EXPORT_SYMBOL_GPL
+-0xe6c3ebb0    __raw_writesw   vmlinux EXPORT_SYMBOL
+-0x51908eb8    __raw_writesl   vmlinux EXPORT_SYMBOL
+-0x75fee7fd    __raw_writesb   vmlinux EXPORT_SYMBOL
+-0xef35b0c3    cfg80211_report_wowlan_wakeup   vmlinux EXPORT_SYMBOL
+-0x99591a7a    ipv6_ext_hdr    vmlinux EXPORT_SYMBOL
+-0x65396d44    neigh_destroy   vmlinux EXPORT_SYMBOL
+-0x405b485b    netdev_warn     vmlinux EXPORT_SYMBOL
+-0xf45f8934    blk_end_request_cur     vmlinux EXPORT_SYMBOL
+-0x9a682368    replace_mount_options   vmlinux EXPORT_SYMBOL
+-0x5a7c0586    hid_validate_values     vmlinux EXPORT_SYMBOL_GPL
+-0x88618588    mmc_wait_for_app_cmd    vmlinux EXPORT_SYMBOL
+-0xccbbfe3b    v4l2_fh_del     vmlinux EXPORT_SYMBOL_GPL
+-0xcefcd99a    serial8250_unregister_port      vmlinux EXPORT_SYMBOL
+-0x0bed6399    __xfrm_policy_check     vmlinux EXPORT_SYMBOL
+-0xf1947b5c    snd_ctl_rename_id       vmlinux EXPORT_SYMBOL
+-0xb9220639    blk_lld_busy    vmlinux EXPORT_SYMBOL_GPL
+-0x4178eee3    blk_sync_queue  vmlinux EXPORT_SYMBOL
+-0x32b0e045    usbnet_get_link vmlinux EXPORT_SYMBOL_GPL
+-0xd578f42c    fat_alloc_new_dir       vmlinux EXPORT_SYMBOL_GPL
+-0x0eacb23a    simple_write_end        vmlinux EXPORT_SYMBOL
+-0xcbee20b2    get_cpu_iowait_time_us  vmlinux EXPORT_SYMBOL_GPL
+-0xea01bd2a    st_sensors_init_sensor  vmlinux EXPORT_SYMBOL
+-0xb7433944    hid_open_report vmlinux EXPORT_SYMBOL_GPL
+-0x2d339a62    scsi_schedule_eh        vmlinux EXPORT_SYMBOL_GPL
+-0xc6544448    pm_runtime_irq_safe     vmlinux EXPORT_SYMBOL_GPL
+-0xa5afacf6    class_unregister        vmlinux EXPORT_SYMBOL_GPL
+-0xedf69cd6    drm_gem_private_object_init     vmlinux EXPORT_SYMBOL
+-0x999c3148    __raw_readsb    vmlinux EXPORT_SYMBOL
+-0xfb268a5f    ip_mc_rejoin_groups     vmlinux EXPORT_SYMBOL
+-0xafe4c25e    netdev_update_features  vmlinux EXPORT_SYMBOL
+-0xd75c79df    smp_call_function       vmlinux EXPORT_SYMBOL
+-0xef6c3f70    round_jiffies_up_relative       vmlinux EXPORT_SYMBOL_GPL
+-0x64420947    spi_async       vmlinux EXPORT_SYMBOL_GPL
+-0xe62c2cf6    regmap_raw_write_async  vmlinux EXPORT_SYMBOL_GPL
+-0x226a057d    eth_header_cache        vmlinux EXPORT_SYMBOL
+-0xb9d025c9    llist_del_first vmlinux EXPORT_SYMBOL_GPL
+-0xb678366f    int_sqrt        vmlinux EXPORT_SYMBOL
+-0x9d28f747    dec_zone_page_state     vmlinux EXPORT_SYMBOL
+-0x0799aca4    local_bh_enable vmlinux EXPORT_SYMBOL
+-0x8d07023c    i2c_smbus_read_byte_data        vmlinux EXPORT_SYMBOL
+-0xca5dbc50    scsi_print_sense_hdr    vmlinux EXPORT_SYMBOL
+-0x3da076a8    scsi_host_lookup        vmlinux EXPORT_SYMBOL
+-0xf54ff64f    uart_set_options        vmlinux EXPORT_SYMBOL_GPL
+-0x47ff399f    regulator_is_supported_voltage  vmlinux EXPORT_SYMBOL_GPL
+-0x585469ee    of_get_videomode        vmlinux EXPORT_SYMBOL_GPL
+-0x852786a9    phy_get vmlinux EXPORT_SYMBOL_GPL
+-0xaf8aa518    system_rev      vmlinux EXPORT_SYMBOL
+-0x6c3d2a02    tcp_syn_flood_action    vmlinux EXPORT_SYMBOL
+-0xf38bcdf3    nf_conntrack_max        vmlinux EXPORT_SYMBOL_GPL
+-0x44de5177    snd_pcm_suspend vmlinux EXPORT_SYMBOL
+-0xb23ef570    blk_bio_map_sg  vmlinux EXPORT_SYMBOL
+-0x4c5e7289    config_item_get vmlinux EXPORT_SYMBOL
+-0xea12473b    config_item_put vmlinux EXPORT_SYMBOL
+-0xbe68ef11    mnt_drop_write_file     vmlinux EXPORT_SYMBOL
+-0x381144a9    __tracepoint_module_get vmlinux EXPORT_SYMBOL
+-0xc5fdef94    call_usermodehelper     vmlinux EXPORT_SYMBOL
+-0x1eb9516e    round_jiffies_relative  vmlinux EXPORT_SYMBOL_GPL
+-0x7cc035a7    __ucmpdi2       vmlinux EXPORT_SYMBOL
+-0xe42e1f70    klist_iter_init_node    vmlinux EXPORT_SYMBOL_GPL
+-0x5c440c21    hci_conn_check_secure   vmlinux EXPORT_SYMBOL
+-0x5b34d4b0    snd_soc_codec_readable_register vmlinux EXPORT_SYMBOL_GPL
+-0x0634100a    bitmap_parselist_user   vmlinux EXPORT_SYMBOL
+-0x5b72009f    ida_simple_get  vmlinux EXPORT_SYMBOL
+-0x11a6ce4b    blk_queue_update_dma_alignment  vmlinux EXPORT_SYMBOL
+-0x3e0dd939    blk_start_request       vmlinux EXPORT_SYMBOL
+-0x51749fc8    _raw_read_lock_irq      vmlinux EXPORT_SYMBOL
+-0x757bbc48    hrtimer_try_to_cancel   vmlinux EXPORT_SYMBOL_GPL
+-0x70899e95    v4l2_m2m_buf_remove     vmlinux EXPORT_SYMBOL_GPL
+-0x5f96a661    v4l2_ctrl_check vmlinux EXPORT_SYMBOL
+-0x42bf1c34    video_unregister_device vmlinux EXPORT_SYMBOL
+-0xcd914413    drm_get_minor   vmlinux EXPORT_SYMBOL
+-0xa0e5202d    nf_register_hook        vmlinux EXPORT_SYMBOL
+-0x86d5e343    __dev_get_by_name       vmlinux EXPORT_SYMBOL
+-0x2cc749f6    skb_copy_and_csum_dev   vmlinux EXPORT_SYMBOL
+-0x9613509a    idr_replace     vmlinux EXPORT_SYMBOL
+-0x82acfb70    blk_iopoll_sched        vmlinux EXPORT_SYMBOL
+-0x2c7db649    irq_dispose_mapping     vmlinux EXPORT_SYMBOL_GPL
+-0x530b1e98    pm_suspend      vmlinux EXPORT_SYMBOL
+-0xae69b1c1    usermodehelper_read_unlock      vmlinux EXPORT_SYMBOL_GPL
+-0x39f4b0d2    s3c_adc_release vmlinux EXPORT_SYMBOL_GPL
+-0xc2f16e25    input_unregister_handle vmlinux EXPORT_SYMBOL
+-0x67326732    usb_hcd_map_urb_for_dma vmlinux EXPORT_SYMBOL_GPL
+-0xd125790d    drm_hdmi_avi_infoframe_from_display_mode        vmlinux EXPORT_SYMBOL
+-0xe10a472d    drm_mm_pre_get  vmlinux EXPORT_SYMBOL
+-0xf082ddf3    register_netdev vmlinux EXPORT_SYMBOL
+-0x935b5da0    snd_timer_continue      vmlinux EXPORT_SYMBOL
+-0xcc37f55c    blk_limits_io_opt       vmlinux EXPORT_SYMBOL
+-0xd4c5def3    inet_twsk_purge vmlinux EXPORT_SYMBOL_GPL
+-0x9e9f1714    __bitmap_andnot vmlinux EXPORT_SYMBOL
+-0x737de5e9    radix_tree_tag_get      vmlinux EXPORT_SYMBOL
+-0xed1e0a03    posix_acl_from_xattr    vmlinux EXPORT_SYMBOL
+-0x5256cd6e    clear_nlink     vmlinux EXPORT_SYMBOL
+-0xc9f0ae5d    nf_xfrm_me_harder       vmlinux EXPORT_SYMBOL
+-0x4751c2af    dev_loopback_xmit       vmlinux EXPORT_SYMBOL
+-0x74bd982c    skb_seq_read    vmlinux EXPORT_SYMBOL
+-0x798c5110    snd_soc_platform_trigger        vmlinux EXPORT_SYMBOL_GPL
+-0x5362ae46    config_item_init        vmlinux EXPORT_SYMBOL
+-0x83c8a355    param_set_int   vmlinux EXPORT_SYMBOL
+-0x8099b954    i2c_transfer    vmlinux EXPORT_SYMBOL
+-0x61e262f1    scsi_device_lookup      vmlinux EXPORT_SYMBOL
+-0xfbb86a51    drm_i2c_encoder_prepare vmlinux EXPORT_SYMBOL
+-0x4090c0fe    snd_card_file_add       vmlinux EXPORT_SYMBOL
+-0x559879f5    crypto_drop_spawn       vmlinux EXPORT_SYMBOL_GPL
+-0x27c2197f    param_set_short vmlinux EXPORT_SYMBOL
+-0xcc4c1be7    nf_nat_tftp_hook        vmlinux EXPORT_SYMBOL_GPL
+-0xc9a3b093    get_h225_addr   vmlinux EXPORT_SYMBOL_GPL
+-0x59e9d996    skb_pad vmlinux EXPORT_SYMBOL
+-0x77bc13a0    strim   vmlinux EXPORT_SYMBOL
+-0x4c2a94b4    shash_register_instance vmlinux EXPORT_SYMBOL_GPL
+-0x33c77d65    seq_write       vmlinux EXPORT_SYMBOL
+-0x44aec3a4    generic_file_llseek     vmlinux EXPORT_SYMBOL
+-0x12d60b5f    v4l2_ctrl_handler_free  vmlinux EXPORT_SYMBOL
+-0x19f0c50a    ip6_tnl_parse_tlv_enc_lim       vmlinux EXPORT_SYMBOL
+-0x1cea8d0a    snd_soc_dapm_new_widgets        vmlinux EXPORT_SYMBOL_GPL
+-0xe1f4606d    snd_info_create_module_entry    vmlinux EXPORT_SYMBOL
+-0x999e8297    vfree   vmlinux EXPORT_SYMBOL
+-0x841575f5    wait_on_page_bit        vmlinux EXPORT_SYMBOL
+-0x51205d4b    mutex_lock      vmlinux EXPORT_SYMBOL
+-0xe97c74fd    rtc_update_irq_enable   vmlinux EXPORT_SYMBOL_GPL
+-0x849722db    dma_request_slave_channel       vmlinux EXPORT_SYMBOL_GPL
+-0x120b336a    __rb_insert_augmented   vmlinux EXPORT_SYMBOL
+-0x6359b128    elv_rq_merge_ok vmlinux EXPORT_SYMBOL
+-0xee3496c3    dma_pool_alloc  vmlinux EXPORT_SYMBOL
+-0xa835f402    mmc_detect_card_removed vmlinux EXPORT_SYMBOL
+-0xbe1b0b72    scsi_get_host_dev       vmlinux EXPORT_SYMBOL
+-0xaf4e166f    dma_async_memcpy_pg_to_pg       vmlinux EXPORT_SYMBOL
+-0xe34d76a6    l2cap_is_socket vmlinux EXPORT_SYMBOL
+-0xd875e3e2    ip6_route_lookup        vmlinux EXPORT_SYMBOL_GPL
+-0xd58c5fcb    tcp_v4_do_rcv   vmlinux EXPORT_SYMBOL
+-0x3413b5de    blk_dump_rq_flags       vmlinux EXPORT_SYMBOL
+-0xc8449f3c    sysfs_create_group      vmlinux EXPORT_SYMBOL_GPL
+-0xf3e42ab4    get_device      vmlinux EXPORT_SYMBOL_GPL
+-0xf147dcb2    hdmi_spd_infoframe_init vmlinux EXPORT_SYMBOL
+-0x1776281f    xfrm_unregister_mode    vmlinux EXPORT_SYMBOL
+-0x4737cc63    consume_skb     vmlinux EXPORT_SYMBOL
+-0x72081296    extcon_find_cable_index vmlinux EXPORT_SYMBOL_GPL
+-0x641d5fb6    usbnet_status_start     vmlinux EXPORT_SYMBOL_GPL
+-0x8f2c5edc    scsi_add_device vmlinux EXPORT_SYMBOL
+-0x8652db9f    __pm_stay_awake vmlinux EXPORT_SYMBOL_GPL
+-0xb9d3a88c    tcf_action_dump_1       vmlinux EXPORT_SYMBOL
+-0xb6f19e98    snd_pcm_lib_get_vmalloc_page    vmlinux EXPORT_SYMBOL
+-0x29e5e6f3    poll_schedule_timeout   vmlinux EXPORT_SYMBOL
+-0x99f58330    lg_local_lock_cpu       vmlinux EXPORT_SYMBOL
+-0x58862e69    v4l2_m2m_ioctl_streamon vmlinux EXPORT_SYMBOL_GPL
+-0xa340fae0    i2c_add_numbered_adapter        vmlinux EXPORT_SYMBOL_GPL
+-0x806c2801    usb_unanchor_urb        vmlinux EXPORT_SYMBOL_GPL
+-0x485b3745    dma_get_slave_channel   vmlinux EXPORT_SYMBOL_GPL
+-0x1d0a43c3    phy_power_off   vmlinux EXPORT_SYMBOL_GPL
+-0x0fd14a9d    tcp_prot        vmlinux EXPORT_SYMBOL
+-0x4bfdc9e2    textsearch_prepare      vmlinux EXPORT_SYMBOL
+-0x988958ef    fuse_direct_io  vmlinux EXPORT_SYMBOL_GPL
+-0x996c4d30    proc_dointvec_ms_jiffies        vmlinux EXPORT_SYMBOL
+-0x785d494b    rndis_msg_parser        vmlinux EXPORT_SYMBOL
+-0xcea853d2    root_device_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0xf13f5821    inet_frag_kill  vmlinux EXPORT_SYMBOL
+-0x8f4f1272    simple_setattr  vmlinux EXPORT_SYMBOL
+-0x9c0dba49    simple_getattr  vmlinux EXPORT_SYMBOL
+-0x2232a8a5    mempool_free    vmlinux EXPORT_SYMBOL
+-0xc72ca946    v4l2_fh_release vmlinux EXPORT_SYMBOL_GPL
+-0x2a0afd5e    videomode_from_timing   vmlinux EXPORT_SYMBOL_GPL
+-0xaf157b0c    nfc_dep_link_is_up      vmlinux EXPORT_SYMBOL
+-0x20efc937    tcf_em_tree_validate    vmlinux EXPORT_SYMBOL
+-0xd05683cc    cred_to_ucred   vmlinux EXPORT_SYMBOL_GPL
+-0xa1ac0050    sock_tx_timestamp       vmlinux EXPORT_SYMBOL
+-0x48bd992d    bdget_disk      vmlinux EXPORT_SYMBOL
+-0x50985501    configfs_register_subsystem     vmlinux EXPORT_SYMBOL
+-0x041a8568    attribute_container_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0x3de4b634    driver_for_each_device  vmlinux EXPORT_SYMBOL_GPL
+-0xc1984867    drm_vblank_put  vmlinux EXPORT_SYMBOL
+-0xc8c20253    tcp_rcv_state_process   vmlinux EXPORT_SYMBOL
+-0x280525ed    skb_to_sgvec    vmlinux EXPORT_SYMBOL_GPL
+-0x20c55ae0    sscanf  vmlinux EXPORT_SYMBOL
+-0xe3dd61a6    __breadahead    vmlinux EXPORT_SYMBOL
+-0x1b42a36f    vb2_dma_contig_init_ctx vmlinux EXPORT_SYMBOL_GPL
+-0xc326f752    v4l2_g_ctrl     vmlinux EXPORT_SYMBOL
+-0x3adca4e5    pfifo_fast_ops  vmlinux EXPORT_SYMBOL
+-0x67677183    snd_pcm_hw_constraint_integer   vmlinux EXPORT_SYMBOL
+-0x1fab5905    wait_for_completion     vmlinux EXPORT_SYMBOL
+-0x0b972255    led_classdev_suspend    vmlinux EXPORT_SYMBOL_GPL
+-0xd617281d    wm8994_set_bits vmlinux EXPORT_SYMBOL_GPL
+-0x4ad196c8    wm8994_reg_read vmlinux EXPORT_SYMBOL_GPL
+-0xb3f0ca49    platform_device_register_full   vmlinux EXPORT_SYMBOL_GPL
+-0x13bfa97e    devm_gpio_free  vmlinux EXPORT_SYMBOL
+-0xe5646321    dev_get_by_name_rcu     vmlinux EXPORT_SYMBOL
+-0x8fed35b2    snd_soc_dpcm_can_be_free_stop   vmlinux EXPORT_SYMBOL_GPL
+-0x30a4f4ca    bstr_printf     vmlinux EXPORT_SYMBOL_GPL
+-0x72350130    ___ratelimit    vmlinux EXPORT_SYMBOL
+-0x0e5d4fe1    i2c_smbus_write_byte_data       vmlinux EXPORT_SYMBOL
+-0xe7d93ea1    usb_unlink_urb  vmlinux EXPORT_SYMBOL_GPL
+-0xaf141636    __nf_nat_mangle_tcp_packet      vmlinux EXPORT_SYMBOL
+-0x584e1dcb    wm_hubs_add_analogue_controls   vmlinux EXPORT_SYMBOL_GPL
+-0x15e14e37    snd_dma_alloc_pages     vmlinux EXPORT_SYMBOL
+-0x3a26ed11    sched_clock     vmlinux EXPORT_SYMBOL_GPL
+-0x6f5d8c04    iio_device_unregister   vmlinux EXPORT_SYMBOL
+-0x9e672ff6    scsi_kmap_atomic_sg     vmlinux EXPORT_SYMBOL
+-0xe8d95e86    platform_device_add_data        vmlinux EXPORT_SYMBOL_GPL
+-0x1fcece42    inet_twdr_twcal_tick    vmlinux EXPORT_SYMBOL_GPL
+-0xd1f0ea5e    sk_unattached_filter_destroy    vmlinux EXPORT_SYMBOL_GPL
+-0xdb647fcf    sock_create_lite        vmlinux EXPORT_SYMBOL
+-0x82b125fb    mmc_hw_reset_check      vmlinux EXPORT_SYMBOL
+-0x45db3821    drm_gem_create_mmap_offset      vmlinux EXPORT_SYMBOL
+-0x4eca00d2    nfc_proto_register      vmlinux EXPORT_SYMBOL
+-0x8b69cf06    d_obtain_alias  vmlinux EXPORT_SYMBOL
+-0xc7462fc5    cpufreq_unregister_governor     vmlinux EXPORT_SYMBOL_GPL
+-0xc7280d53    v4l2_g_ext_ctrls        vmlinux EXPORT_SYMBOL
+-0xb3b58737    ip6_datagram_connect    vmlinux EXPORT_SYMBOL_GPL
+-0x365bf841    ip4_datagram_connect    vmlinux EXPORT_SYMBOL
+-0x4a8cb865    tcp_timewait_state_process      vmlinux EXPORT_SYMBOL
+-0xa34e2838    nf_conntrack_helper_try_module_get      vmlinux EXPORT_SYMBOL_GPL
+-0x26dcd9ac    security_inode_init_security    vmlinux EXPORT_SYMBOL
+-0xd705b4c7    schedule_hrtimeout      vmlinux EXPORT_SYMBOL_GPL
+-0x44643b93    __aeabi_lmul    vmlinux EXPORT_SYMBOL
+-0x824efa53    nobh_writepage  vmlinux EXPORT_SYMBOL
+-0x78eb3b6d    clear_page_dirty_for_io vmlinux EXPORT_SYMBOL
+-0xad6bf99a    srcu_init_notifier_head vmlinux EXPORT_SYMBOL_GPL
+-0x9a1fc4b4    jiffies_to_timeval      vmlinux EXPORT_SYMBOL
+-0xf1823632    clk_disable     vmlinux EXPORT_SYMBOL_GPL
+-0x69da85e3    v4l2_ctrl_poll  vmlinux EXPORT_SYMBOL
+-0xdcd7d2a3    starget_for_each_device vmlinux EXPORT_SYMBOL
+-0x4dd58b53    subsys_interface_register       vmlinux EXPORT_SYMBOL_GPL
+-0xf3916987    global_cursor_default   vmlinux EXPORT_SYMBOL
+-0x3d2b2b9f    tcp_reno_min_cwnd       vmlinux EXPORT_SYMBOL_GPL
+-0xf3bd26cd    vfs_follow_link vmlinux EXPORT_SYMBOL
+-0xc11bd00f    tracepoint_probe_unregister     vmlinux EXPORT_SYMBOL_GPL
+-0xb5532b8b    spi_bitbang_stop        vmlinux EXPORT_SYMBOL_GPL
+-0x4deb10c3    tty_schedule_flip       vmlinux EXPORT_SYMBOL
+-0x2dc227f8    brcmu_d11_attach        drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0xc009330d    sysfs_rename_link       vmlinux EXPORT_SYMBOL_GPL
+-0xce0b9b59    max77693_read_reg       vmlinux EXPORT_SYMBOL_GPL
+-0xc0c44856    tty_devnum      vmlinux EXPORT_SYMBOL
+-0x4f391d0e    nla_parse       vmlinux EXPORT_SYMBOL
+-0xc39a1e2a    write_dirty_buffer      vmlinux EXPORT_SYMBOL
+-0xc8a154f9    noop_llseek     vmlinux EXPORT_SYMBOL
+-0xc65d3eed    ring_buffer_entries_cpu vmlinux EXPORT_SYMBOL_GPL
+-0x16807034    iommu_group_for_each_dev        vmlinux EXPORT_SYMBOL_GPL
+-0x76829e1b    nfc_proto_unregister    vmlinux EXPORT_SYMBOL
+-0x21ac8b77    iommu_group_get_by_id   vmlinux EXPORT_SYMBOL_GPL
+-0x60601d69    input_free_device       vmlinux EXPORT_SYMBOL
+-0x3a03067b    regulator_notifier_call_chain   vmlinux EXPORT_SYMBOL_GPL
+-0x3e9110fa    __hw_addr_unsync        vmlinux EXPORT_SYMBOL
+-0x7d11c268    jiffies vmlinux EXPORT_SYMBOL
+-0x3987712e    iio_read_channel_scale  vmlinux EXPORT_SYMBOL_GPL
+-0x7deff673    dm_consume_args vmlinux EXPORT_SYMBOL
+-0xc092d57b    i2c_verify_adapter      vmlinux EXPORT_SYMBOL
+-0x2e7a4300    drm_rgb_quant_range_selectable  vmlinux EXPORT_SYMBOL
+-0x594e1317    __modsi3        vmlinux EXPORT_SYMBOL
+-0x211331fa    __divsi3        vmlinux EXPORT_SYMBOL
+-0xa3482467    dev_queue_xmit  vmlinux EXPORT_SYMBOL
+-0x13d0adf7    __kfifo_out     vmlinux EXPORT_SYMBOL
+-0xe06141e9    security_sk_clone       vmlinux EXPORT_SYMBOL
+-0x75d5b827    proc_mkdir      vmlinux EXPORT_SYMBOL
+-0x6f6ac78c    dummy_irq_chip  vmlinux EXPORT_SYMBOL_GPL
+-0x3efb35c9    get_online_cpus vmlinux EXPORT_SYMBOL_GPL
+-0x5907773b    of_device_alloc vmlinux EXPORT_SYMBOL
+-0x1c00411e    blk_rq_map_sg   vmlinux EXPORT_SYMBOL
+-0x09cf1b46    proc_dointvec_jiffies   vmlinux EXPORT_SYMBOL
+-0x5db2254a    devm_usb_get_phy_by_phandle     vmlinux EXPORT_SYMBOL_GPL
+-0x85caf365    usb_hcd_start_port_resume       vmlinux EXPORT_SYMBOL_GPL
+-0x0a469d23    mfd_clone_cell  vmlinux EXPORT_SYMBOL
+-0x93e85c29    dmam_free_noncoherent   vmlinux EXPORT_SYMBOL
+-0x241ab4c2    phy_destroy     vmlinux EXPORT_SYMBOL_GPL
+-0x408b2c52    __napi_schedule vmlinux EXPORT_SYMBOL
+-0xc911f7d5    dev_change_carrier      vmlinux EXPORT_SYMBOL
+-0xbfaa31e1    sk_stream_wait_memory   vmlinux EXPORT_SYMBOL
+-0x0d3cb182    kstrtos16_from_user     vmlinux EXPORT_SYMBOL
+-0x9f2bdaac    __bitmap_or     vmlinux EXPORT_SYMBOL
+-0xae729e59    security_req_classify_flow      vmlinux EXPORT_SYMBOL
+-0x273cbba4    get_dcookie     vmlinux EXPORT_SYMBOL_GPL
+-0x9b7510d1    trace_event_raw_init    vmlinux EXPORT_SYMBOL_GPL
+-0xb24585bc    usb_set_interface       vmlinux EXPORT_SYMBOL_GPL
+-0x08cbe96c    tty_unlock      vmlinux EXPORT_SYMBOL
+-0x07e3f668    netlink_broadcast_filtered      vmlinux EXPORT_SYMBOL
+-0x4761f17c    register_netevent_notifier      vmlinux EXPORT_SYMBOL_GPL
+-0xc7ec6c27    strspn  vmlinux EXPORT_SYMBOL
+-0x97255bdf    strlen  vmlinux EXPORT_SYMBOL
+-0xcdb399d4    cgroup_rightmost_descendant     vmlinux EXPORT_SYMBOL_GPL
+-0x4bc7787e    iio_trigger_register    vmlinux EXPORT_SYMBOL
+-0x05d7e32a    pm_generic_runtime_idle vmlinux EXPORT_SYMBOL_GPL
+-0xcb0b5e8e    of_display_timings_exist        vmlinux EXPORT_SYMBOL_GPL
+-0xdb68bbad    rfkill_destroy  vmlinux EXPORT_SYMBOL
+-0x2e6a04e3    hci_recv_frame  vmlinux EXPORT_SYMBOL
+-0xedbaee5e    nla_strcmp      vmlinux EXPORT_SYMBOL
+-0x26bb950b    __kfifo_from_user_r     vmlinux EXPORT_SYMBOL
+-0xca2ff6df    crypto_ahash_type       vmlinux EXPORT_SYMBOL_GPL
+-0x2c41c751    v4l2_m2m_ctx_release    vmlinux EXPORT_SYMBOL_GPL
+-0x99213409    scsi_allocate_command   vmlinux EXPORT_SYMBOL
+-0x6827603e    skb_trim        vmlinux EXPORT_SYMBOL
+-0x5cca80cf    perf_tp_event   vmlinux EXPORT_SYMBOL_GPL
+-0xa6961e25    vb2_common_vm_ops       vmlinux EXPORT_SYMBOL_GPL
+-0x72856c9e    v4l2_m2m_ioctl_expbuf   vmlinux EXPORT_SYMBOL_GPL
+-0xb8acff80    usb_enable_autosuspend  vmlinux EXPORT_SYMBOL_GPL
+-0x403f9529    gpio_request_one        vmlinux EXPORT_SYMBOL_GPL
+-0x06d549e6    pinctrl_free_gpio       vmlinux EXPORT_SYMBOL_GPL
+-0x02ae8433    xfrm_policy_delete      vmlinux EXPORT_SYMBOL
+-0x6e71c6be    inet_frags_init vmlinux EXPORT_SYMBOL
+-0x4e3567f7    match_int       vmlinux EXPORT_SYMBOL
+-0x054434d6    radix_tree_tag_set      vmlinux EXPORT_SYMBOL
+-0x31f956eb    blk_queue_lld_busy      vmlinux EXPORT_SYMBOL_GPL
+-0x26565c84    shash_free_instance     vmlinux EXPORT_SYMBOL_GPL
+-0x38668bab    debugfs_create_x64      vmlinux EXPORT_SYMBOL_GPL
+-0xbf1f9a9b    bdi_setup_and_register  vmlinux EXPORT_SYMBOL
+-0xfc64abed    power_supply_changed    vmlinux EXPORT_SYMBOL_GPL
+-0x19326753    rtc_irq_register        vmlinux EXPORT_SYMBOL_GPL
+-0xaf3cc095    nfc_hci_free_device     vmlinux EXPORT_SYMBOL
+-0x86f38980    skb_cow_data    vmlinux EXPORT_SYMBOL_GPL
+-0xe0c0d2af    snd_pcm_kernel_ioctl    vmlinux EXPORT_SYMBOL
+-0xdfb01a80    cpu_v7_dcache_clean_area        vmlinux EXPORT_SYMBOL
+-0x1879fcbd    bridge_tunnel_header    vmlinux EXPORT_SYMBOL
+-0x9a011a6b    l2cap_conn_put  vmlinux EXPORT_SYMBOL
+-0x6b3ee85a    ip4_datagram_release_cb vmlinux EXPORT_SYMBOL_GPL
+-0xdd07d415    snd_card_free_when_closed       vmlinux EXPORT_SYMBOL
+-0x868acba5    get_options     vmlinux EXPORT_SYMBOL
+-0xa2409544    setup_irq       vmlinux EXPORT_SYMBOL_GPL
+-0x567b73f9    i2c_get_adapter vmlinux EXPORT_SYMBOL
+-0x7a4e7297    drm_edid_block_valid    vmlinux EXPORT_SYMBOL
+-0x2ec524ad    __kfifo_in_r    vmlinux EXPORT_SYMBOL
+-0x66f9da32    bh_uptodate_or_lock     vmlinux EXPORT_SYMBOL
+-0xf9ffcd69    input_unregister_handler        vmlinux EXPORT_SYMBOL
+-0x51dce73b    xfrm_state_walk_init    vmlinux EXPORT_SYMBOL
+-0x113554e9    __skb_dst_set_noref     vmlinux EXPORT_SYMBOL
+-0x3c9d1211    string_get_size vmlinux EXPORT_SYMBOL
+-0xe654362e    fat_fill_super  vmlinux EXPORT_SYMBOL_GPL
+-0xea5a46e7    register_exec_domain    vmlinux EXPORT_SYMBOL
+-0xaf473214    iio_channel_get_all     vmlinux EXPORT_SYMBOL_GPL
+-0xf8a9d6b2    rtc_read_alarm  vmlinux EXPORT_SYMBOL_GPL
+-0xa0c8e0ed    usbnet_set_settings     vmlinux EXPORT_SYMBOL_GPL
+-0x170bb6a9    usbnet_get_settings     vmlinux EXPORT_SYMBOL_GPL
+-0xe0701fe6    fl6_sock_lookup vmlinux EXPORT_SYMBOL_GPL
+-0x9330cb9f    sg_alloc_table  vmlinux EXPORT_SYMBOL
+-0x5873f4c0    handle_simple_irq       vmlinux EXPORT_SYMBOL_GPL
+-0xf27977e2    async_synchronize_cookie_domain vmlinux EXPORT_SYMBOL_GPL
+-0xcf732e49    call_usermodehelper_exec        vmlinux EXPORT_SYMBOL
+-0xd789a39d    cpufreq_governor_dbs    vmlinux EXPORT_SYMBOL_GPL
+-0x4ff0c84f    of_mdio_find_bus        vmlinux EXPORT_SYMBOL
+-0xe7a664c4    nf_hooks        vmlinux EXPORT_SYMBOL
+-0xd366806d    snd_info_free_entry     vmlinux EXPORT_SYMBOL
+-0xbcac6160    pm_qos_remove_notifier  vmlinux EXPORT_SYMBOL_GPL
+-0x698d1e98    v4l2_ctrl_handler_init_class    vmlinux EXPORT_SYMBOL
+-0x79c0d5a3    drm_gem_prime_fd_to_handle      vmlinux EXPORT_SYMBOL
+-0xff1e9dd8    seq_list_start  vmlinux EXPORT_SYMBOL
+-0x01accd73    __clk_get_name  vmlinux EXPORT_SYMBOL_GPL
+-0x3e92b3d3    power_supply_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x71590103    drm_release     vmlinux EXPORT_SYMBOL
+-0x0b9e5852    xfrm_aead_get_byname    vmlinux EXPORT_SYMBOL_GPL
+-0xb7b856bf    km_state_notify vmlinux EXPORT_SYMBOL
+-0x3f5b1415    nf_ct_port_nlattr_to_tuple      vmlinux EXPORT_SYMBOL_GPL
+-0x98b6628a    snd_pcm_set_ops vmlinux EXPORT_SYMBOL
+-0x1ea06663    _raw_write_lock vmlinux EXPORT_SYMBOL
+-0x44dd3d8d    completion_done vmlinux EXPORT_SYMBOL
+-0xa1eabd87    drm_mode_list_concat    vmlinux EXPORT_SYMBOL
+-0x581ed292    drm_mm_get_block_generic        vmlinux EXPORT_SYMBOL
+-0xefa98e30    dma_run_dependencies    vmlinux EXPORT_SYMBOL_GPL
+-0xe8bea3bc    qdisc_put_stab  vmlinux EXPORT_SYMBOL
+-0x2247cba2    seq_printf      vmlinux EXPORT_SYMBOL
+-0x7e646f56    media_entity_remove_links       vmlinux EXPORT_SYMBOL_GPL
+-0xa0e05fb1    drm_connector_cleanup   vmlinux EXPORT_SYMBOL
+-0xb1cf44df    fb_find_best_mode       vmlinux EXPORT_SYMBOL
+-0x0b742fd7    simple_strtol   vmlinux EXPORT_SYMBOL
+-0xd709e32c    ilookup5_nowait vmlinux EXPORT_SYMBOL
+-0x25865b31    mmc_free_host   vmlinux EXPORT_SYMBOL
+-0x054063e9    devres_release  vmlinux EXPORT_SYMBOL_GPL
+-0xc9b2045b    drm_mode_validate_size  vmlinux EXPORT_SYMBOL
+-0xac6855b0    gen_kill_estimator      vmlinux EXPORT_SYMBOL
+-0xc32b07a0    blk_queue_alignment_offset      vmlinux EXPORT_SYMBOL
+-0x630c9194    fuse_dev_operations     vmlinux EXPORT_SYMBOL_GPL
+-0xa4824580    devm_add_action vmlinux EXPORT_SYMBOL_GPL
+-0xd8fe5b35    drm_mm_init     vmlinux EXPORT_SYMBOL
+-0x9b9b05b4    __bio_clone     vmlinux EXPORT_SYMBOL
+-0x5fda0227    vfs_stat        vmlinux EXPORT_SYMBOL
+-0xa0fbac79    wake_up_bit     vmlinux EXPORT_SYMBOL
+-0x796fc5ce    scsi_get_sense_info_fld vmlinux EXPORT_SYMBOL
+-0x699ffdcd    nf_conntrack_flush_report       vmlinux EXPORT_SYMBOL_GPL
+-0x89e6edac    snd_pcm_lib_malloc_pages        vmlinux EXPORT_SYMBOL
+-0x48034724    zlib_deflateReset       vmlinux EXPORT_SYMBOL
+-0xcdca3691    nr_irqs vmlinux EXPORT_SYMBOL_GPL
+-0xcff6b676    _raw_spin_trylock_bh    vmlinux EXPORT_SYMBOL
+-0xca45efbc    drm_format_horz_chroma_subsampling      vmlinux EXPORT_SYMBOL
+-0xb6f4cc92    tty_do_resize   vmlinux EXPORT_SYMBOL
+-0x51e77c97    pfn_valid       vmlinux EXPORT_SYMBOL
+-0xa2446605    jbd2_journal_set_triggers       vmlinux EXPORT_SYMBOL
+-0xebbb44c8    f_setown        vmlinux EXPORT_SYMBOL
+-0xdfef3371    v4l2_m2m_ioctl_streamoff        vmlinux EXPORT_SYMBOL_GPL
+-0x56c8799d    scsi_kunmap_atomic_sg   vmlinux EXPORT_SYMBOL
+-0xaae1593e    scsi_block_when_processing_errors       vmlinux EXPORT_SYMBOL
+-0xe330bf1f    ip6_dst_hoplimit        vmlinux EXPORT_SYMBOL
+-0xf8996ee4    arp_invalidate  vmlinux EXPORT_SYMBOL
+-0x6d27ef64    __bitmap_empty  vmlinux EXPORT_SYMBOL
+-0xbfa789ca    elv_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0x06ae2b19    mmc_can_sanitize        vmlinux EXPORT_SYMBOL
+-0xdd3dc2ce    usb_clear_halt  vmlinux EXPORT_SYMBOL_GPL
+-0xfe0b2aae    amba_device_unregister  vmlinux EXPORT_SYMBOL
+-0xc3771b21    of_pwm_get      vmlinux EXPORT_SYMBOL_GPL
+-0x21b7d56d    dev_mc_sync_multiple    vmlinux EXPORT_SYMBOL
+-0x1dfc5292    dev_uc_sync_multiple    vmlinux EXPORT_SYMBOL
+-0xde7da8e3    submit_bh       vmlinux EXPORT_SYMBOL
+-0xc15d05d9    mnt_clone_write vmlinux EXPORT_SYMBOL_GPL
+-0x25fa84a3    page_mkclean    vmlinux EXPORT_SYMBOL_GPL
+-0x405c1144    get_seconds     vmlinux EXPORT_SYMBOL
+-0xf0f1246c    kvasprintf      vmlinux EXPORT_SYMBOL
+-0xa5526619    rb_insert_color vmlinux EXPORT_SYMBOL
+-0x7bb12a75    v4l2_m2m_get_vq vmlinux EXPORT_SYMBOL
+-0x5819c8aa    usb_anchor_empty        vmlinux EXPORT_SYMBOL_GPL
+-0x4e3d273c    __xfrm_init_state       vmlinux EXPORT_SYMBOL
+-0xa2a69edc    __module_text_address   vmlinux EXPORT_SYMBOL_GPL
+-0x66d87d38    symbol_put_addr vmlinux EXPORT_SYMBOL_GPL
+-0xe45cc839    hrtimer_start_range_ns  vmlinux EXPORT_SYMBOL_GPL
+-0xd3e6f60d    cpu_possible_mask       vmlinux EXPORT_SYMBOL
+-0x52451ffe    hid_dump_field  vmlinux EXPORT_SYMBOL_GPL
+-0xbd5a9986    drm_helper_probe_single_connector_modes vmlinux EXPORT_SYMBOL
+-0xb694ce34    tcf_hash_search vmlinux EXPORT_SYMBOL
+-0xaaefb815    d_alloc vmlinux EXPORT_SYMBOL
+-0xaca38c86    unuse_mm        vmlinux EXPORT_SYMBOL_GPL
+-0x5de3d7af    __alloc_pages_nodemask  vmlinux EXPORT_SYMBOL
+-0xe2142ad8    i2c_smbus_read_word_data        vmlinux EXPORT_SYMBOL
+-0xbfe4cfe6    tty_buffer_request_room vmlinux EXPORT_SYMBOL_GPL
+-0xa6089679    elv_abort_queue vmlinux EXPORT_SYMBOL
+-0x918ad429    ring_buffer_lock_reserve        vmlinux EXPORT_SYMBOL_GPL
+-0xdc461430    irq_set_affinity_hint   vmlinux EXPORT_SYMBOL_GPL
+-0x37258879    iio_channel_release     vmlinux EXPORT_SYMBOL_GPL
+-0x1a082d69    max77693_update_reg     vmlinux EXPORT_SYMBOL_GPL
+-0x4b0bd573    wiphy_unregister        vmlinux EXPORT_SYMBOL
+-0x575d8c47    inet_sk_rx_dst_set      vmlinux EXPORT_SYMBOL
+-0x3c6f5a97    snd_soc_register_component      vmlinux EXPORT_SYMBOL_GPL
+-0xb9e03943    blk_execute_rq_nowait   vmlinux EXPORT_SYMBOL_GPL
+-0x15f571ec    blk_set_stacking_limits vmlinux EXPORT_SYMBOL
+-0x721585fd    security_inode_mkdir    vmlinux EXPORT_SYMBOL_GPL
+-0xbf16ef9a    clk_get_rate    vmlinux EXPORT_SYMBOL_GPL
+-0x22b79dae    clk_set_rate    vmlinux EXPORT_SYMBOL_GPL
+-0x0dbd0e20    of_property_read_u8_array       vmlinux EXPORT_SYMBOL_GPL
+-0xe6fce6f2    v4l2_ctrl_merge vmlinux EXPORT_SYMBOL
+-0x12f1d8d3    dev_err vmlinux EXPORT_SYMBOL
+-0x1c3e0368    drm_gem_object_handle_free      vmlinux EXPORT_SYMBOL
+-0xfda9ed46    udp_proc_register       vmlinux EXPORT_SYMBOL
+-0xccf2974f    kernel_sendpage vmlinux EXPORT_SYMBOL
+-0x4b77922a    delete_from_page_cache  vmlinux EXPORT_SYMBOL
+-0x3f5b67d5    wait_for_completion_killable    vmlinux EXPORT_SYMBOL
+-0xa62fb61a    usb_gstrings_attach     vmlinux EXPORT_SYMBOL_GPL
+-0x5cabdced    dev_pm_qos_remove_global_notifier       vmlinux EXPORT_SYMBOL_GPL
+-0x27b864a9    s5p_gpio_get_drvstr     vmlinux EXPORT_SYMBOL
+-0xc828d2a3    s5p_gpio_set_drvstr     vmlinux EXPORT_SYMBOL
+-0xd9cf81bd    cfg80211_send_assoc_timeout     vmlinux EXPORT_SYMBOL
+-0x693c3961    nf_ct_helper_hash       vmlinux EXPORT_SYMBOL_GPL
+-0x487ef8ba    snd_soc_dai_set_sysclk  vmlinux EXPORT_SYMBOL_GPL
+-0x50c89f23    __alloc_percpu  vmlinux EXPORT_SYMBOL_GPL
+-0x09469482    kfree_call_rcu  vmlinux EXPORT_SYMBOL_GPL
+-0x177d5d5e    uart_insert_char        vmlinux EXPORT_SYMBOL_GPL
+-0xb17c2f9b    clear_inode     vmlinux EXPORT_SYMBOL
+-0x3b733a7c    led_trigger_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0x16000a3c    dm_device_name  vmlinux EXPORT_SYMBOL_GPL
+-0x0465ca31    scsi_cmd_get_serial     vmlinux EXPORT_SYMBOL
+-0x0f52944d    drm_helper_hpd_irq_event        vmlinux EXPORT_SYMBOL
+-0x99517682    udp_encap_enable        vmlinux EXPORT_SYMBOL
+-0x1e43dec1    neigh_parms_release     vmlinux EXPORT_SYMBOL
+-0x572e85d4    blk_lookup_devt vmlinux EXPORT_SYMBOL
+-0xf7bb06b2    crypto_grab_skcipher    vmlinux EXPORT_SYMBOL_GPL
+-0xe953b21f    get_next_ino    vmlinux EXPORT_SYMBOL
+-0xdb225b82    pm_vt_switch_required   vmlinux EXPORT_SYMBOL
+-0xe1a4b69f    mmc_card_awake  vmlinux EXPORT_SYMBOL
+-0x33234a30    usb_hcd_link_urb_to_ep  vmlinux EXPORT_SYMBOL_GPL
+-0xb61a0dba    dmam_release_declared_memory    vmlinux EXPORT_SYMBOL
+-0x6865b5f6    device_release_driver   vmlinux EXPORT_SYMBOL_GPL
+-0x920accbd    ump_dd_secure_id_get    vmlinux EXPORT_SYMBOL
+-0xffb94ef0    _test_and_change_bit    vmlinux EXPORT_SYMBOL
+-0xb7a1ff6d    tcp_prequeue    vmlinux EXPORT_SYMBOL
+-0xce3ca308    copy_from_user_toio     vmlinux EXPORT_SYMBOL
+-0xd08137e8    vfs_setlease    vmlinux EXPORT_SYMBOL_GPL
+-0x89eabc8c    from_kgid_munged        vmlinux EXPORT_SYMBOL
+-0x40d04664    console_trylock vmlinux EXPORT_SYMBOL
+-0x0955d1f2    iommu_attach_device     vmlinux EXPORT_SYMBOL_GPL
+-0x9cf3e94a    dm_kcopyd_copy  vmlinux EXPORT_SYMBOL
+-0x1cec399d    v4l2_m2m_ioctl_create_bufs      vmlinux EXPORT_SYMBOL_GPL
+-0x8cae11ac    usb_alloc_streams       vmlinux EXPORT_SYMBOL_GPL
+-0xd3299096    scsi_register_interface vmlinux EXPORT_SYMBOL
+-0x885369a2    dma_common_get_sgtable  vmlinux EXPORT_SYMBOL
+-0x2251d13d    blk_queue_dma_pad       vmlinux EXPORT_SYMBOL
+-0x07cf9099    wait_for_completion_timeout     vmlinux EXPORT_SYMBOL
+-0x0efcbb1b    set_current_groups      vmlinux EXPORT_SYMBOL
+-0xea9b0ab7    v4l2_ctrl_add_handler   vmlinux EXPORT_SYMBOL
+-0x79aaab2b    i2c_smbus_read_block_data       vmlinux EXPORT_SYMBOL
+-0x964ff64a    usb_put_intf    vmlinux EXPORT_SYMBOL_GPL
+-0x9f97bf25    xfrm6_input_addr        vmlinux EXPORT_SYMBOL
+-0x81db6ebb    xz_dec_reset    vmlinux EXPORT_SYMBOL
+-0x661601de    sprint_symbol   vmlinux EXPORT_SYMBOL_GPL
+-0x1e59773c    st_gyro_common_remove   vmlinux EXPORT_SYMBOL
+-0x921e453c    drm_get_platform_dev    vmlinux EXPORT_SYMBOL
+-0x720b245e    update_region   vmlinux EXPORT_SYMBOL
+-0x2bda5922    hci_get_route   vmlinux EXPORT_SYMBOL
+-0xaa939a8b    tcf_em_unregister       vmlinux EXPORT_SYMBOL
+-0x590cf866    scm_fp_dup      vmlinux EXPORT_SYMBOL
+-0x2ce98559    kcrypto_wq      vmlinux EXPORT_SYMBOL_GPL
+-0x5351af17    shrink_dcache_parent    vmlinux EXPORT_SYMBOL
+-0x1ad83009    trace_seq_vprintf       vmlinux EXPORT_SYMBOL_GPL
+-0x8fcafa61    led_stop_software_blink vmlinux EXPORT_SYMBOL_GPL
+-0xd4a7943a    mmc_card_can_sleep      vmlinux EXPORT_SYMBOL
+-0x52f378a8    devres_remove   vmlinux EXPORT_SYMBOL_GPL
+-0x6288b8b9    serial8250_release_dma  vmlinux EXPORT_SYMBOL_GPL
+-0x63556dea    tty_vhangup     vmlinux EXPORT_SYMBOL
+-0x75c8a11c    inet_twdr_twkill_work   vmlinux EXPORT_SYMBOL_GPL
+-0x609f1c7e    synchronize_net vmlinux EXPORT_SYMBOL
+-0x6091797f    synchronize_rcu vmlinux EXPORT_SYMBOL_GPL
+-0x42825ce2    rcu_scheduler_active    vmlinux EXPORT_SYMBOL_GPL
+-0xe523ad75    synchronize_irq vmlinux EXPORT_SYMBOL
+-0xb77b0159    v4l2_prio_init  vmlinux EXPORT_SYMBOL
+-0x840dd143    rndis_deregister        vmlinux EXPORT_SYMBOL
+-0x7464ea38    dev_pm_qos_add_global_notifier  vmlinux EXPORT_SYMBOL_GPL
+-0xd325a885    bus_for_each_dev        vmlinux EXPORT_SYMBOL_GPL
+-0x3ec3d061    bus_for_each_drv        vmlinux EXPORT_SYMBOL_GPL
+-0xb2823478    pneigh_lookup   vmlinux EXPORT_SYMBOL
+-0x7037aaf0    kern_path_create        vmlinux EXPORT_SYMBOL
+-0x85061b76    _raw_write_lock_bh      vmlinux EXPORT_SYMBOL
+-0xb90cbedf    v4l2_of_get_next_endpoint       vmlinux EXPORT_SYMBOL
+-0x9d2ed0a8    snd_timer_close vmlinux EXPORT_SYMBOL
+-0x1057d320    blk_queue_find_tag      vmlinux EXPORT_SYMBOL
+-0x1e3a88fb    trace_seq_printf        vmlinux EXPORT_SYMBOL_GPL
+-0x4bc62a81    audit_enabled   vmlinux EXPORT_SYMBOL_GPL
+-0x39461d6a    in_egroup_p     vmlinux EXPORT_SYMBOL
+-0xccefabad    drm_mode_create_scaling_mode_property   vmlinux EXPORT_SYMBOL
+-0x43384bd9    drm_buffer_alloc        vmlinux EXPORT_SYMBOL
+-0x184e6c85    radix_tree_gang_lookup_slot     vmlinux EXPORT_SYMBOL
+-0xdf347b52    sec_reg_read    vmlinux EXPORT_SYMBOL_GPL
+-0x409873e3    tty_termios_baud_rate   vmlinux EXPORT_SYMBOL
+-0x07a890c8    fb_alloc_cmap   vmlinux EXPORT_SYMBOL
+-0x7d04aaa6    nf_conntrack_broadcast_help     vmlinux EXPORT_SYMBOL_GPL
+-0x5cdc7a62    skb_append_datato_frags vmlinux EXPORT_SYMBOL
+-0x9e0c711d    vzalloc_node    vmlinux EXPORT_SYMBOL
+-0x7f24de73    jiffies_to_usecs        vmlinux EXPORT_SYMBOL
+-0x37befc70    jiffies_to_msecs        vmlinux EXPORT_SYMBOL
+-0xe9807d5b    input_mt_sync_frame     vmlinux EXPORT_SYMBOL
+-0x0c0c8520    release_firmware        vmlinux EXPORT_SYMBOL
+-0x442aa46d    tcp_child_process       vmlinux EXPORT_SYMBOL
+-0x67663177    sock_diag_put_filterinfo        vmlinux EXPORT_SYMBOL
+-0xa250c838    param_get_charp vmlinux EXPORT_SYMBOL
+-0xf0b613ad    __pm_runtime_suspend    vmlinux EXPORT_SYMBOL_GPL
+-0x1a770ac3    drm_detect_hdmi_monitor vmlinux EXPORT_SYMBOL
+-0x70d7e40d    prepare_binprm  vmlinux EXPORT_SYMBOL
+-0x36d7b11a    of_find_matching_node_and_match vmlinux EXPORT_SYMBOL
+-0x8e30ad82    mdiobus_write   vmlinux EXPORT_SYMBOL
+-0xeb6173b8    tty_port_destroy        vmlinux EXPORT_SYMBOL
+-0x6c0154da    tcp_v4_destroy_sock     vmlinux EXPORT_SYMBOL
+-0x5afe3100    snd_soc_add_dai_controls        vmlinux EXPORT_SYMBOL_GPL
+-0xdf2c2742    rb_last vmlinux EXPORT_SYMBOL
+-0x7ab3ca18    eventfd_ctx_read        vmlinux EXPORT_SYMBOL_GPL
+-0xeb32e3af    mount_bdev      vmlinux EXPORT_SYMBOL
+-0xe6fbe430    can_do_mlock    vmlinux EXPORT_SYMBOL
+-0x60a13e90    rcu_barrier     vmlinux EXPORT_SYMBOL_GPL
+-0xdf60cc27    __print_symbol  vmlinux EXPORT_SYMBOL
+-0xa2a2031e    ehci_setup      vmlinux EXPORT_SYMBOL_GPL
+-0x686f8200    ndisc_mc_map    vmlinux EXPORT_SYMBOL
+-0xab8647cf    nf_ct_helper_expectfn_find_by_symbol    vmlinux EXPORT_SYMBOL_GPL
+-0x91715312    sprintf vmlinux EXPORT_SYMBOL
+-0xda3d10a8    security_tun_dev_open   vmlinux EXPORT_SYMBOL
+-0xa4a91e54    simple_unlink   vmlinux EXPORT_SYMBOL
+-0xf377a0b5    simple_attr_write       vmlinux EXPORT_SYMBOL_GPL
+-0x97263968    generic_listxattr       vmlinux EXPORT_SYMBOL
+-0x53c9394f    v4l2_ctrl_query_menu    vmlinux EXPORT_SYMBOL
+-0xf6ebc03b    net_ratelimit   vmlinux EXPORT_SYMBOL
+-0x3977cbea    dev_addr_init   vmlinux EXPORT_SYMBOL
+-0x2789cd4f    snd_soc_put_strobe      vmlinux EXPORT_SYMBOL_GPL
+-0x719074ee    snd_soc_get_strobe      vmlinux EXPORT_SYMBOL_GPL
+-0xdace599d    shash_ahash_update      vmlinux EXPORT_SYMBOL_GPL
+-0x7add44b5    posix_acl_valid vmlinux EXPORT_SYMBOL
+-0xe8fbe1c9    invalidate_inode_buffers        vmlinux EXPORT_SYMBOL
+-0x5442b464    media_device_register_entity    vmlinux EXPORT_SYMBOL_GPL
+-0xa279bad0    usb_add_config  vmlinux EXPORT_SYMBOL_GPL
+-0x1d77b0f8    unix_socket_table       vmlinux EXPORT_SYMBOL_GPL
+-0x7932f1fc    ip_tunnel_ioctl vmlinux EXPORT_SYMBOL_GPL
+-0x153b7ac0    nl_table        vmlinux EXPORT_SYMBOL_GPL
+-0xfdfcdc90    crypto_shash_update     vmlinux EXPORT_SYMBOL_GPL
+-0xa376521b    find_vma        vmlinux EXPORT_SYMBOL
+-0xe57f0426    vb2_dma_contig_cleanup_ctx      vmlinux EXPORT_SYMBOL_GPL
+-0x0f53690e    usb_autopm_get_interface_async  vmlinux EXPORT_SYMBOL_GPL
+-0xe97e3624    scsi_register   vmlinux EXPORT_SYMBOL
+-0x07d4567b    max8997_write_reg       vmlinux EXPORT_SYMBOL_GPL
+-0x24f2d831    regulator_register_notifier     vmlinux EXPORT_SYMBOL_GPL
+-0x85ab9275    nf_ct_extend_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x7721fbd2    kernel_connect  vmlinux EXPORT_SYMBOL
+-0x3095e489    single_open_size        vmlinux EXPORT_SYMBOL
+-0x54ff695a    inet_stream_connect     vmlinux EXPORT_SYMBOL
+-0xa05c03df    mempool_kmalloc vmlinux EXPORT_SYMBOL
+-0xd6df7b3f    dma_buf_end_cpu_access  vmlinux EXPORT_SYMBOL_GPL
+-0x2d5eac78    qdisc_warn_nonwc        vmlinux EXPORT_SYMBOL
+-0x7bc477d0    splice_from_pipe_begin  vmlinux EXPORT_SYMBOL
+-0xfd6293c2    boot_tvec_bases vmlinux EXPORT_SYMBOL
+-0x6d662533    _find_first_bit_le      vmlinux EXPORT_SYMBOL
+-0xd41f3207    netdev_class_remove_file        vmlinux EXPORT_SYMBOL
+-0xdf48a0eb    flex_array_put  vmlinux EXPORT_SYMBOL
+-0xcf048d93    blk_queue_physical_block_size   vmlinux EXPORT_SYMBOL
+-0xd5790350    dio_end_io      vmlinux EXPORT_SYMBOL_GPL
+-0xc0bf6ead    timecounter_cyc2time    vmlinux EXPORT_SYMBOL_GPL
+-0x303087f1    v4l2_queryctrl  vmlinux EXPORT_SYMBOL
+-0x506691f1    sock_diag_check_cookie  vmlinux EXPORT_SYMBOL_GPL
+-0x307c2fd0    generic_check_addressable       vmlinux EXPORT_SYMBOL
+-0x40b313d1    perf_event_read_value   vmlinux EXPORT_SYMBOL_GPL
+-0x04482cdb    __refrigerator  vmlinux EXPORT_SYMBOL
+-0x7cb1ae69    cpu_down        vmlinux EXPORT_SYMBOL
+-0xc9aca11e    v4l2_ctrl_handler_log_status    vmlinux EXPORT_SYMBOL
+-0xb7f77027    rtc_tm_to_ktime vmlinux EXPORT_SYMBOL_GPL
+-0x70c8201b    tty_lock_pair   vmlinux EXPORT_SYMBOL
+-0x1565add4    inet6_csk_addr2sockaddr vmlinux EXPORT_SYMBOL_GPL
+-0x72a112d9    netdev_refcnt_read      vmlinux EXPORT_SYMBOL
+-0xacc6730b    __blk_end_request       vmlinux EXPORT_SYMBOL
+-0xbe54542c    input_mt_init_slots     vmlinux EXPORT_SYMBOL
+-0xca3920b5    usb_disable_lpm vmlinux EXPORT_SYMBOL_GPL
+-0x0cd967c3    usb_disable_ltm vmlinux EXPORT_SYMBOL_GPL
+-0x3b66b0c1    __pm_wakeup_event       vmlinux EXPORT_SYMBOL_GPL
+-0x0f480178    devres_close_group      vmlinux EXPORT_SYMBOL_GPL
+-0xf0bd9740    drm_mode_parse_command_line_for_connector       vmlinux EXPORT_SYMBOL
+-0x12c6276a    drm_buffer_read_object  vmlinux EXPORT_SYMBOL
+-0xc3b93bba    klist_next      vmlinux EXPORT_SYMBOL_GPL
+-0x3d342d92    tcp_rcv_established     vmlinux EXPORT_SYMBOL
+-0x540c6f94    inet_getpeer    vmlinux EXPORT_SYMBOL_GPL
+-0x153c8015    ipv4_update_pmtu        vmlinux EXPORT_SYMBOL_GPL
+-0x0c4bfb03    xt_unregister_targets   vmlinux EXPORT_SYMBOL
+-0x5cd7eb9b    wm_hubs_dcs_done        vmlinux EXPORT_SYMBOL_GPL
+-0xd7e56a4e    simple_strtoll  vmlinux EXPORT_SYMBOL
+-0x20000329    simple_strtoul  vmlinux EXPORT_SYMBOL
+-0x9e784e44    balance_dirty_pages_ratelimited vmlinux EXPORT_SYMBOL
+-0x11195d33    usb_enable_lpm  vmlinux EXPORT_SYMBOL_GPL
+-0xd7f91a45    usb_enable_ltm  vmlinux EXPORT_SYMBOL_GPL
+-0x39e2b6d2    spi_alloc_master        vmlinux EXPORT_SYMBOL_GPL
+-0x82eb671b    scsi_prep_fn    vmlinux EXPORT_SYMBOL
+-0x4473fccc    nf_register_afinfo      vmlinux EXPORT_SYMBOL_GPL
+-0xd1e13a97    net_ns_type_operations  vmlinux EXPORT_SYMBOL_GPL
+-0x1bf69c17    proc_symlink    vmlinux EXPORT_SYMBOL
+-0x651c3828    usb_add_phy_dev vmlinux EXPORT_SYMBOL_GPL
+-0xf571b062    drm_addmap      vmlinux EXPORT_SYMBOL
+-0xb41150b4    pwm_enable      vmlinux EXPORT_SYMBOL_GPL
+-0x8c52195f    __rtnl_link_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0xe2cb9278    snd_soc_dai_set_tdm_slot        vmlinux EXPORT_SYMBOL_GPL
+-0x4de34a07    cpu_rmap_put    vmlinux EXPORT_SYMBOL
+-0xb51797f0    blk_queue_dma_alignment vmlinux EXPORT_SYMBOL
+-0xdab3304e    remap_vmalloc_range     vmlinux EXPORT_SYMBOL
+-0x5113c626    noop_backing_dev_info   vmlinux EXPORT_SYMBOL_GPL
+-0xd985dc99    mempool_free_pages      vmlinux EXPORT_SYMBOL
+-0xfcec0987    enable_irq      vmlinux EXPORT_SYMBOL
+-0x1e7bbcb3    kernel_restart  vmlinux EXPORT_SYMBOL_GPL
+-0xa26c3f65    mmc_gpio_free_cd        vmlinux EXPORT_SYMBOL
+-0x6461806d    max8997_bulk_write      vmlinux EXPORT_SYMBOL_GPL
+-0x2ff9c227    filemap_page_mkwrite    vmlinux EXPORT_SYMBOL
+-0xd2917bd3    v4l2_m2m_fop_poll       vmlinux EXPORT_SYMBOL_GPL
+-0xc11159cc    drm_mode_create vmlinux EXPORT_SYMBOL
+-0xdd27fa87    memchr  vmlinux EXPORT_SYMBOL
+-0x10329729    inet6_release   vmlinux EXPORT_SYMBOL
+-0xc18ac88d    nf_ct_expect_hsize      vmlinux EXPORT_SYMBOL_GPL
+-0x005e9828    vfs_kern_mount  vmlinux EXPORT_SYMBOL_GPL
+-0xd5bd7dac    ring_buffer_record_enable_cpu   vmlinux EXPORT_SYMBOL_GPL
+-0x00cf4a7f    of_get_parent   vmlinux EXPORT_SYMBOL
+-0xd6097597    v4l2_ctrl_new_int_menu  vmlinux EXPORT_SYMBOL
+-0x3cdbf719    drm_mode_destroy        vmlinux EXPORT_SYMBOL
+-0xb03e9a0f    nfc_set_remote_general_bytes    vmlinux EXPORT_SYMBOL
+-0x2059c814    sock_diag_register      vmlinux EXPORT_SYMBOL_GPL
+-0x315c65fd    zlib_deflateInit2       vmlinux EXPORT_SYMBOL
+-0x1ab8c624    submit_bio      vmlinux EXPORT_SYMBOL
+-0xd070d52e    alloc_page_buffers      vmlinux EXPORT_SYMBOL_GPL
+-0x622c7922    register_oom_notifier   vmlinux EXPORT_SYMBOL_GPL
+-0xe806f5a2    trace_event_buffer_lock_reserve vmlinux EXPORT_SYMBOL_GPL
+-0xcfc68341    synchronize_rcu_bh      vmlinux EXPORT_SYMBOL_GPL
+-0x549525ef    handle_nested_irq       vmlinux EXPORT_SYMBOL_GPL
+-0x20421305    on_each_cpu_mask        vmlinux EXPORT_SYMBOL
+-0xa1bb9fb1    spi_bus_type    vmlinux EXPORT_SYMBOL_GPL
+-0x8a627eb3    anon_transport_class_unregister vmlinux EXPORT_SYMBOL_GPL
+-0xd8525ea7    fl6_update_dst  vmlinux EXPORT_SYMBOL_GPL
+-0xbac1a16b    tcp_valid_rtt_meas      vmlinux EXPORT_SYMBOL
+-0xb67cd6f1    neigh_lookup    vmlinux EXPORT_SYMBOL
+-0xc2c639ae    debugfs_create_u32_array        vmlinux EXPORT_SYMBOL_GPL
+-0xd4a33b98    mmc_remove_host vmlinux EXPORT_SYMBOL
+-0x1f65abdf    usb_put_hcd     vmlinux EXPORT_SYMBOL_GPL
+-0x2ef63ad6    scsi_dev_info_list_del_keyed    vmlinux EXPORT_SYMBOL
+-0x0bf18882    tcp_mtup_init   vmlinux EXPORT_SYMBOL
+-0x0ea07ec7    kstrtou8_from_user      vmlinux EXPORT_SYMBOL
+-0x973d0f9e    kstrtoul_from_user      vmlinux EXPORT_SYMBOL
+-0x7c8db884    devm_clk_unregister     vmlinux EXPORT_SYMBOL_GPL
+-0x46066e5b    perf_pmu_name   vmlinux EXPORT_SYMBOL_GPL
+-0x951ac153    snd_soc_jack_report     vmlinux EXPORT_SYMBOL_GPL
+-0x7c1464a6    snd_soc_dapm_get_enum_double    vmlinux EXPORT_SYMBOL_GPL
+-0xd36af700    snd_soc_dapm_put_enum_double    vmlinux EXPORT_SYMBOL_GPL
+-0x222e7ce2    sysfs_streq     vmlinux EXPORT_SYMBOL
+-0xca72b2e9    alloc_buffer_head       vmlinux EXPORT_SYMBOL
+-0x364d71cb    iio_scan_mask_set       vmlinux EXPORT_SYMBOL_GPL
+-0x813f3de4    v4l2_find_nearest_format        vmlinux EXPORT_SYMBOL_GPL
+-0xb37a0603    drm_dp_link_train_channel_eq_delay      vmlinux EXPORT_SYMBOL
+-0x1fe912f1    netdev_alloc_frag       vmlinux EXPORT_SYMBOL
+-0x7bdee655    usbnet_get_endpoints    vmlinux EXPORT_SYMBOL_GPL
+-0x589e4569    syscon_regmap_lookup_by_pdevname        vmlinux EXPORT_SYMBOL_GPL
+-0x60506751    unmap_kernel_range_noflush      vmlinux EXPORT_SYMBOL_GPL
+-0x224b5740    device_remove_file      vmlinux EXPORT_SYMBOL_GPL
+-0x1b8822d8    pinctrl_gpio_direction_output   vmlinux EXPORT_SYMBOL_GPL
+-0x985e0b7d    ipv6_skip_exthdr        vmlinux EXPORT_SYMBOL
+-0xa0e33feb    ip_options_compile      vmlinux EXPORT_SYMBOL
+-0x289c3714    nf_ct_alloc_hashtable   vmlinux EXPORT_SYMBOL_GPL
+-0xc33e401a    sock_diag_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0xba86c38e    aio_complete    vmlinux EXPORT_SYMBOL
+-0x03bd889d    param_get_ulong vmlinux EXPORT_SYMBOL
+-0xa4ca666e    kill_pid        vmlinux EXPORT_SYMBOL
+-0xe56cb560    rt6_lookup      vmlinux EXPORT_SYMBOL
+-0xc8fb75a8    unix_outq_len   vmlinux EXPORT_SYMBOL_GPL
+-0xd5c5ff75    inet_frags_init_net     vmlinux EXPORT_SYMBOL
+-0x64999478    congestion_wait vmlinux EXPORT_SYMBOL
+-0x59eae699    ring_buffer_read_prepare        vmlinux EXPORT_SYMBOL_GPL
+-0xa23061f8    mmc_read_bkops_status   vmlinux EXPORT_SYMBOL
+-0xa1c46bd3    spi_bitbang_cleanup     vmlinux EXPORT_SYMBOL_GPL
+-0x4d126acf    device_store_int        vmlinux EXPORT_SYMBOL_GPL
+-0x5b546bbb    drm_gem_mmap    vmlinux EXPORT_SYMBOL
+-0xd37d6496    hci_recv_fragment       vmlinux EXPORT_SYMBOL
+-0x1c86d31e    ip_tunnel_delete_net    vmlinux EXPORT_SYMBOL_GPL
+-0x9684e8c6    blk_queue_dma_drain     vmlinux EXPORT_SYMBOL_GPL
+-0xf89e28e9    config_item_set_name    vmlinux EXPORT_SYMBOL
+-0x9d8331c0    ring_buffer_read_page   vmlinux EXPORT_SYMBOL_GPL
+-0x572d0104    _raw_write_unlock_irqrestore    vmlinux EXPORT_SYMBOL
+-0x8e7894bd    __atomic_notifier_call_chain    vmlinux EXPORT_SYMBOL_GPL
+-0xb202dbc6    i2c_del_driver  vmlinux EXPORT_SYMBOL
+-0x057ce975    hex_dump_to_buffer      vmlinux EXPORT_SYMBOL
+-0xe09f5fdd    file_ra_state_init      vmlinux EXPORT_SYMBOL_GPL
+-0x011c93d4    v4l2_m2m_reqbufs        vmlinux EXPORT_SYMBOL_GPL
+-0x5b185975    __dma_request_channel   vmlinux EXPORT_SYMBOL_GPL
+-0xe02299ef    nfc_hci_send_response   vmlinux EXPORT_SYMBOL
+-0xe8beb828    crypto_larval_kill      vmlinux EXPORT_SYMBOL_GPL
+-0x8704eb06    irq_set_default_host    vmlinux EXPORT_SYMBOL_GPL
+-0x7ac1d551    vb2_prepare_buf vmlinux EXPORT_SYMBOL_GPL
+-0xfcab3072    media_entity_cleanup    vmlinux EXPORT_SYMBOL_GPL
+-0x75d69d69    usb_alloc_coherent      vmlinux EXPORT_SYMBOL_GPL
+-0x2f3857a0    xfrm_register_mode      vmlinux EXPORT_SYMBOL
+-0x09c1fbfd    inet_csk_get_port       vmlinux EXPORT_SYMBOL_GPL
+-0x1e6fd62f    kiocb_set_cancel_fn     vmlinux EXPORT_SYMBOL
+-0xb20a8d04    mmc_flush_cache vmlinux EXPORT_SYMBOL
+-0xb321b21c    i2c_clients_command     vmlinux EXPORT_SYMBOL
+-0xd77c0bc8    klist_remove    vmlinux EXPORT_SYMBOL_GPL
+-0x8cfe5489    dev_get_flags   vmlinux EXPORT_SYMBOL
+-0x8022b19a    crypto_sha256_update    vmlinux EXPORT_SYMBOL
+-0x0adfab73    __wait_on_bit_lock      vmlinux EXPORT_SYMBOL
+-0x4a169d0b    usb_get_status  vmlinux EXPORT_SYMBOL_GPL
+-0xe5122890    flow_cache_genid        vmlinux EXPORT_SYMBOL
+-0x31cef011    gen_new_estimator       vmlinux EXPORT_SYMBOL
+-0xbb6bebbd    crypto_alg_mod_lookup   vmlinux EXPORT_SYMBOL_GPL
+-0xe208f5c9    freeze_super    vmlinux EXPORT_SYMBOL
+-0xbf5b2016    __devm_request_region   vmlinux EXPORT_SYMBOL
+-0x7cd6f042    cpufreq_get_current_driver      vmlinux EXPORT_SYMBOL_GPL
+-0x946f789a    input_class     vmlinux EXPORT_SYMBOL_GPL
+-0x33abb76e    usb_remove_function     vmlinux EXPORT_SYMBOL_GPL
+-0x54c41f03    __cfg80211_send_disassoc        vmlinux EXPORT_SYMBOL
+-0x886bcea3    hid_connect     vmlinux EXPORT_SYMBOL_GPL
+-0x1d4cf31c    mmc_set_data_timeout    vmlinux EXPORT_SYMBOL
+-0x020bb7c4    v4l2_m2m_qbuf   vmlinux EXPORT_SYMBOL_GPL
+-0xf5ef842e    v4l_bound_align_image   vmlinux EXPORT_SYMBOL_GPL
+-0x628c65bc    usb_set_device_state    vmlinux EXPORT_SYMBOL_GPL
+-0x1d182b56    scsi_autopm_get_device  vmlinux EXPORT_SYMBOL_GPL
+-0xa8b77259    scsi_autopm_put_device  vmlinux EXPORT_SYMBOL_GPL
+-0x2641488c    scsi_eh_finish_cmd      vmlinux EXPORT_SYMBOL
+-0x773650a0    vc_cons vmlinux EXPORT_SYMBOL
+-0x6d203b02    dma_async_device_unregister     vmlinux EXPORT_SYMBOL
+-0x18c2227f    cpu_rmap_update vmlinux EXPORT_SYMBOL
+-0xdd0a2ba2    strlcat vmlinux EXPORT_SYMBOL
+-0xd627480b    strncat vmlinux EXPORT_SYMBOL
+-0x0dd47f83    blk_queue_max_discard_sectors   vmlinux EXPORT_SYMBOL
+-0xb3f7646e    kthread_should_stop     vmlinux EXPORT_SYMBOL
+-0x8d335f49    mmc_can_reset   vmlinux EXPORT_SYMBOL
+-0x474576c2    v4l2_ctrl_new_std_menu  vmlinux EXPORT_SYMBOL
+-0x735d80ef    drm_add_edid_modes      vmlinux EXPORT_SYMBOL
+-0xbfdbe956    nfnetlink_set_err       vmlinux EXPORT_SYMBOL_GPL
+-0xc0891ac5    netdev_notice   vmlinux EXPORT_SYMBOL
+-0x03b5c8d0    blk_rq_map_kern vmlinux EXPORT_SYMBOL
+-0x20f6c302    sync_mapping_buffers    vmlinux EXPORT_SYMBOL
+-0x5610de90    pm_generic_freeze_noirq vmlinux EXPORT_SYMBOL_GPL
+-0x33186585    drm_prime_lookup_buf_handle     vmlinux EXPORT_SYMBOL
+-0x5c746654    bt_sock_register        vmlinux EXPORT_SYMBOL
+-0x1f2ca4fa    fat_scan        vmlinux EXPORT_SYMBOL_GPL
+-0x4ade2e74    inode_change_ok vmlinux EXPORT_SYMBOL
+-0x2b2264c1    __scsi_add_device       vmlinux EXPORT_SYMBOL
+-0x3a8903bb    datagram_poll   vmlinux EXPORT_SYMBOL
+-0x75767b6f    snd_pcm_hw_constraint_minmax    vmlinux EXPORT_SYMBOL
+-0xe623e6db    blk_queue_end_tag       vmlinux EXPORT_SYMBOL
+-0x1e9edfb7    seq_hlist_start_head_rcu        vmlinux EXPORT_SYMBOL
+-0x69d38ed9    __scsi_print_sense      vmlinux EXPORT_SYMBOL
+-0xc6de7303    __tty_alloc_driver      vmlinux EXPORT_SYMBOL
+-0xcdb5f930    __tcf_em_tree_match     vmlinux EXPORT_SYMBOL
+-0x7a0a2470    dev_uc_flush    vmlinux EXPORT_SYMBOL
+-0x6c8f0d30    dev_mc_flush    vmlinux EXPORT_SYMBOL
+-0x067d8d35    security_release_secctx vmlinux EXPORT_SYMBOL
+-0xb10e668e    jbd2_journal_check_available_features   vmlinux EXPORT_SYMBOL
+-0xe2e8ac87    flush_old_exec  vmlinux EXPORT_SYMBOL
+-0x00c4dc87    timecounter_init        vmlinux EXPORT_SYMBOL_GPL
+-0xeb793d66    media_device_register   vmlinux EXPORT_SYMBOL_GPL
+-0x694be42a    usb_show_dynids vmlinux EXPORT_SYMBOL_GPL
+-0xdf3ec432    drm_gem_object_alloc    vmlinux EXPORT_SYMBOL
+-0xa3d3ab7e    inet_addr_type  vmlinux EXPORT_SYMBOL
+-0x97a2e370    inet_recvmsg    vmlinux EXPORT_SYMBOL
+-0x0b59390b    __tracepoint_rpm_suspend        vmlinux EXPORT_SYMBOL_GPL
+-0xa4701e9e    timekeeping_inject_offset       vmlinux EXPORT_SYMBOL
+-0x1f54f1b4    do_trace_rcu_torture_read       vmlinux EXPORT_SYMBOL_GPL
+-0x6275fa23    mdiobus_unregister      vmlinux EXPORT_SYMBOL
+-0x639399b9    ump_dd_phys_block_count_get     vmlinux EXPORT_SYMBOL
+-0x6812cf8d    __tracepoint_rpm_idle   vmlinux EXPORT_SYMBOL_GPL
+-0xaa90f5bc    phy_detach      vmlinux EXPORT_SYMBOL
+-0x8ded75c5    mii_link_ok     vmlinux EXPORT_SYMBOL
+-0xa6dd4938    cfg80211_inform_bss_frame       vmlinux EXPORT_SYMBOL
+-0xd4cc3c98    bt_procfs_cleanup       vmlinux EXPORT_SYMBOL
+-0xd856b532    tcp_proc_register       vmlinux EXPORT_SYMBOL
+-0xb86a648c    nf_conntrack_l4proto_udp6       vmlinux EXPORT_SYMBOL_GPL
+-0x2c81ec75    __irq_regs      vmlinux EXPORT_SYMBOL
+-0x3f182756    generic_write_sync      vmlinux EXPORT_SYMBOL
+-0x48bd4a65    wakeup_source_remove    vmlinux EXPORT_SYMBOL_GPL
+-0x027c2c52    stop_tty        vmlinux EXPORT_SYMBOL
+-0xc18578ed    process_srcu    vmlinux EXPORT_SYMBOL_GPL
+-0xf3cf07b0    sdio_writel     vmlinux EXPORT_SYMBOL_GPL
+-0x9b54326d    xfrm_policy_destroy     vmlinux EXPORT_SYMBOL
+-0x667cc3f3    inet_del_offload        vmlinux EXPORT_SYMBOL
+-0xbc9cfb6e    jbd2_journal_stop       vmlinux EXPORT_SYMBOL
+-0x43aec82a    sdhci_pltfm_register    vmlinux EXPORT_SYMBOL_GPL
+-0x1db8867b    sdio_memcpy_toio        vmlinux EXPORT_SYMBOL_GPL
+-0x48499aa5    neigh_ifdown    vmlinux EXPORT_SYMBOL
+-0x4b53ee2c    snd_pcm_hw_constraint_ratnums   vmlinux EXPORT_SYMBOL
+-0x9650df0b    snd_ctl_replace vmlinux EXPORT_SYMBOL
+-0x6c1ce5ce    strcspn vmlinux EXPORT_SYMBOL
+-0xa68698f6    jbd2_journal_extend     vmlinux EXPORT_SYMBOL
+-0x7eb6d1eb    thermal_zone_unbind_cooling_device      vmlinux EXPORT_SYMBOL_GPL
+-0x81328587    blkdev_aio_write        vmlinux EXPORT_SYMBOL_GPL
+-0xf8bec8e3    seq_bitmap_list vmlinux EXPORT_SYMBOL
+-0xaec655c7    alloc_pages_exact       vmlinux EXPORT_SYMBOL
+-0x6ce5ade9    hid_parse_report        vmlinux EXPORT_SYMBOL_GPL
+-0x66f7b07e    ehci_resume     vmlinux EXPORT_SYMBOL_GPL
+-0x95c578a0    ioremap_page_range      vmlinux EXPORT_SYMBOL_GPL
+-0x498dcb5e    drm_ut_debug_printk     vmlinux EXPORT_SYMBOL
+-0x6c1f6c7e    drm_rmmap       vmlinux EXPORT_SYMBOL
+-0x8b55de97    devm_regulator_bulk_get vmlinux EXPORT_SYMBOL_GPL
+-0x8190aef3    register_sound_special  vmlinux EXPORT_SYMBOL
+-0x6c255d20    __nla_reserve   vmlinux EXPORT_SYMBOL
+-0x29537c9e    alloc_chrdev_region     vmlinux EXPORT_SYMBOL
+-0x05273827    inc_zone_page_state     vmlinux EXPORT_SYMBOL
+-0xc665d6d7    of_parse_phandle_with_args      vmlinux EXPORT_SYMBOL
+-0x01f7b595    usbnet_skb_return       vmlinux EXPORT_SYMBOL_GPL
+-0x0740687f    arp_find        vmlinux EXPORT_SYMBOL
+-0x269fbd1b    nf_ct_iterate_cleanup   vmlinux EXPORT_SYMBOL_GPL
+-0x22ce6bb8    skb_checksum    vmlinux EXPORT_SYMBOL
+-0x669f1bc1    kfree_skb_list  vmlinux EXPORT_SYMBOL
+-0xca9360b5    rb_next vmlinux EXPORT_SYMBOL
+-0x3c010e48    inode_permission        vmlinux EXPORT_SYMBOL
+-0xba34ed58    buffer_migrate_page     vmlinux EXPORT_SYMBOL
+-0x1cfb04fa    finish_wait     vmlinux EXPORT_SYMBOL
+-0xcb0b79fb    max8997_read_reg        vmlinux EXPORT_SYMBOL_GPL
+-0x564f1dca    klist_add_after vmlinux EXPORT_SYMBOL_GPL
+-0x4cbbd171    __bitmap_weight vmlinux EXPORT_SYMBOL
+-0x61b7b126    simple_strtoull vmlinux EXPORT_SYMBOL
+-0x528c709d    simple_read_from_buffer vmlinux EXPORT_SYMBOL
+-0x10c9d678    irq_domain_simple_ops   vmlinux EXPORT_SYMBOL_GPL
+-0x5d8d802b    clockevent_delta2ns     vmlinux EXPORT_SYMBOL_GPL
+-0xe8731295    gether_get_ifname       vmlinux EXPORT_SYMBOL
+-0x8619c1c9    phy_start_aneg  vmlinux EXPORT_SYMBOL
+-0x2a1c0adc    scsi_print_result       vmlinux EXPORT_SYMBOL
+-0x6eb85693    nf_defrag_ipv6_enable   vmlinux EXPORT_SYMBOL_GPL
+-0x6b6c3d10    nf_defrag_ipv4_enable   vmlinux EXPORT_SYMBOL_GPL
+-0xa681fe88    generate_random_uuid    vmlinux EXPORT_SYMBOL
+-0x3147857d    default_red     vmlinux EXPORT_SYMBOL
+-0xff9ca065    fb_edid_to_monspecs     vmlinux EXPORT_SYMBOL
+-0x22e14acd    gpiochip_add_pin_range  vmlinux EXPORT_SYMBOL_GPL
+-0xad1bb027    nf_ct_free_hashtable    vmlinux EXPORT_SYMBOL_GPL
+-0xaf509095    get_net_ns_by_pid       vmlinux EXPORT_SYMBOL_GPL
+-0xcff75292    vfs_statfs      vmlinux EXPORT_SYMBOL
+-0x2756ceb6    mmc_power_save_host     vmlinux EXPORT_SYMBOL
+-0x438610bd    security_tun_dev_alloc_security vmlinux EXPORT_SYMBOL
+-0xb1d9068c    ip6_datagram_send_ctl   vmlinux EXPORT_SYMBOL_GPL
+-0x365c213d    udp_ioctl       vmlinux EXPORT_SYMBOL
+-0x53877b9f    __nla_reserve_nohdr     vmlinux EXPORT_SYMBOL
+-0xd64146c4    __get_page_tail vmlinux EXPORT_SYMBOL
+-0x9b1bc5fa    i2c_new_probed_device   vmlinux EXPORT_SYMBOL_GPL
+-0x3c787bd5    rtnetlink_put_metrics   vmlinux EXPORT_SYMBOL
+-0xcb5c97f9    blk_queue_max_write_same_sectors        vmlinux EXPORT_SYMBOL
+-0x3b909e7e    may_umount      vmlinux EXPORT_SYMBOL
+-0x0c8099b1    v4l2_spi_new_subdev     vmlinux EXPORT_SYMBOL_GPL
+-0xd00b0085    v4l2_ctrl_handler_setup vmlinux EXPORT_SYMBOL
+-0xea10212a    int_to_scsilun  vmlinux EXPORT_SYMBOL
+-0xcb0944d8    pwm_set_chip_data       vmlinux EXPORT_SYMBOL_GPL
+-0xde5846c4    pwm_get_chip_data       vmlinux EXPORT_SYMBOL_GPL
+-0x915917a3    block_read_full_page    vmlinux EXPORT_SYMBOL
+-0xe5d61b91    console_drivers vmlinux EXPORT_SYMBOL_GPL
+-0xb776298b    iommu_detach_device     vmlinux EXPORT_SYMBOL_GPL
+-0xeb711ae7    snd_soc_params_to_bclk  vmlinux EXPORT_SYMBOL_GPL
+-0x90ed601f    mmc_hw_reset    vmlinux EXPORT_SYMBOL
+-0x1cbd340b    cdc_ncm_unbind  vmlinux EXPORT_SYMBOL_GPL
+-0x9caab5b6    __scsi_alloc_queue      vmlinux EXPORT_SYMBOL
+-0x2506e85a    bus_sort_breadthfirst   vmlinux EXPORT_SYMBOL_GPL
+-0xd6769f27    ipt_alloc_initial_table vmlinux EXPORT_SYMBOL_GPL
+-0x439fe23e    tcp_v4_connect  vmlinux EXPORT_SYMBOL
+-0x02de3eaf    tcp_sync_mss    vmlinux EXPORT_SYMBOL
+-0x4be85a03    memweight       vmlinux EXPORT_SYMBOL
+-0x93021b18    jbd2_journal_ack_err    vmlinux EXPORT_SYMBOL
+-0xd0c05159    emergency_restart       vmlinux EXPORT_SYMBOL_GPL
+-0x3ff62317    local_bh_disable        vmlinux EXPORT_SYMBOL
+-0xd88781bd    regmap_raw_write        vmlinux EXPORT_SYMBOL_GPL
+-0xada38534    regulator_bulk_disable  vmlinux EXPORT_SYMBOL_GPL
+-0x2ad4daf6    tcp_death_row   vmlinux EXPORT_SYMBOL_GPL
+-0x87751cba    netdev_upper_dev_link   vmlinux EXPORT_SYMBOL
+-0xe187693c    kstrtouint_from_user    vmlinux EXPORT_SYMBOL
+-0xbe797e8f    bio_get_nr_vecs vmlinux EXPORT_SYMBOL
+-0x2373352a    clk_fixed_factor_ops    vmlinux EXPORT_SYMBOL_GPL
+-0xccbee9bd    mmc_set_blockcount      vmlinux EXPORT_SYMBOL
+-0x9ebb3718    v4l2_clk_unregister     vmlinux EXPORT_SYMBOL
+-0xe28ade94    serio_rescan    vmlinux EXPORT_SYMBOL
+-0x1b5c713f    drm_send_vblank_event   vmlinux EXPORT_SYMBOL
+-0xa257d9cd    framebuffer_alloc       vmlinux EXPORT_SYMBOL
+-0x0916cc54    xfrm_policy_byid        vmlinux EXPORT_SYMBOL
+-0x07319ef1    ahash_register_instance vmlinux EXPORT_SYMBOL_GPL
+-0x11c55999    load_nls_default        vmlinux EXPORT_SYMBOL
+-0xcae08d66    nonseekable_open        vmlinux EXPORT_SYMBOL
+-0x3651150d    kmem_cache_create       vmlinux EXPORT_SYMBOL
+-0xfd26424e    cpufreq_driver_target   vmlinux EXPORT_SYMBOL_GPL
+-0x66adff69    vb2_fop_read    vmlinux EXPORT_SYMBOL_GPL
+-0x09a5b743    amba_apb_device_add     vmlinux EXPORT_SYMBOL_GPL
+-0x475100c2    inet_get_local_port_range       vmlinux EXPORT_SYMBOL
+-0x8c1e0ffe    __seq_open_private      vmlinux EXPORT_SYMBOL
+-0xd60c8ab0    seq_escape      vmlinux EXPORT_SYMBOL
+-0xc81ec7cb    phy_get_eee_err vmlinux EXPORT_SYMBOL
+-0x00778770    xfrm_ealg_get_byname    vmlinux EXPORT_SYMBOL_GPL
+-0x5bc722fb    sock_alloc_file vmlinux EXPORT_SYMBOL
+-0xddf821b8    page_address    vmlinux EXPORT_SYMBOL
+-0x9771ccf0    of_mdiobus_register     vmlinux EXPORT_SYMBOL
+-0x5eb24829    dm_shift_arg    vmlinux EXPORT_SYMBOL
+-0x119e8920    v4l2_async_unregister_subdev    vmlinux EXPORT_SYMBOL
+-0x7bc3e7c1    xfrm_lookup     vmlinux EXPORT_SYMBOL
+-0xae0410db    skb_store_bits  vmlinux EXPORT_SYMBOL
+-0xf86deaaa    page_cache_sync_readahead       vmlinux EXPORT_SYMBOL_GPL
+-0x7681946c    unregister_pm_notifier  vmlinux EXPORT_SYMBOL_GPL
+-0x3d98d961    inet_unregister_protosw vmlinux EXPORT_SYMBOL
+-0x82108639    snd_soc_get_volsw       vmlinux EXPORT_SYMBOL_GPL
+-0x286d040c    snd_soc_put_volsw       vmlinux EXPORT_SYMBOL_GPL
+-0x371c0db7    blk_queue_bypass_end    vmlinux EXPORT_SYMBOL_GPL
+-0x8589f760    mb_cache_entry_free     vmlinux EXPORT_SYMBOL
+-0x87a795d4    i2c_probe_func_quick_read       vmlinux EXPORT_SYMBOL_GPL
+-0xb05661a7    i2c_smbus_read_byte     vmlinux EXPORT_SYMBOL
+-0x167977e6    platform_create_bundle  vmlinux EXPORT_SYMBOL_GPL
+-0xb626c977    _dev_info       vmlinux EXPORT_SYMBOL
+-0x0d5db696    arm_iommu_detach_device vmlinux EXPORT_SYMBOL_GPL
+-0x001f6379    blkcipher_walk_phys     vmlinux EXPORT_SYMBOL_GPL
+-0x3dfc897c    seq_hlist_start_head    vmlinux EXPORT_SYMBOL
+-0xc34ff0bb    clocksource_change_rating       vmlinux EXPORT_SYMBOL
+-0x5ace7e88    devres_for_each_res     vmlinux EXPORT_SYMBOL_GPL
+-0xd4390384    __ieee80211_get_channel vmlinux EXPORT_SYMBOL
+-0xe55e04a1    ip6_tnl_rcv_ctl vmlinux EXPORT_SYMBOL_GPL
+-0xa389a49a    profile_event_register  vmlinux EXPORT_SYMBOL_GPL
+-0x5ef37944    sdio_set_block_size     vmlinux EXPORT_SYMBOL_GPL
+-0x9924c496    __usb_get_extra_descriptor      vmlinux EXPORT_SYMBOL_GPL
+-0xcfa57ce1    __nf_conntrack_helper_find      vmlinux EXPORT_SYMBOL_GPL
+-0x5460c8d8    fsnotify_get_cookie     vmlinux EXPORT_SYMBOL_GPL
+-0xf5f58a7b    gether_register_netdev  vmlinux EXPORT_SYMBOL
+-0xe774e9e4    register_netdevice      vmlinux EXPORT_SYMBOL
+-0x9209f545    blkdev_put      vmlinux EXPORT_SYMBOL
+-0x6a1c9c55    blkdev_get      vmlinux EXPORT_SYMBOL
+-0x4d0cbb95    finish_no_open  vmlinux EXPORT_SYMBOL
+-0xa1ef69b9    unregister_ftrace_event vmlinux EXPORT_SYMBOL_GPL
+-0x09d6a08d    v4l2_device_disconnect  vmlinux EXPORT_SYMBOL_GPL
+-0x613a7741    scsi_finish_command     vmlinux EXPORT_SYMBOL
+-0x11f447ce    __gpio_to_irq   vmlinux EXPORT_SYMBOL_GPL
+-0xb8a9ab06    hci_unregister_cb       vmlinux EXPORT_SYMBOL
+-0xca0741ee    nf_nat_l4proto_register vmlinux EXPORT_SYMBOL_GPL
+-0x70f09a3d    nf_nat_l3proto_register vmlinux EXPORT_SYMBOL_GPL
+-0x10447797    build_skb       vmlinux EXPORT_SYMBOL
+-0xf2b1ac8e    __getnstimeofday        vmlinux EXPORT_SYMBOL
+-0x8923ab21    get_tz_trend    vmlinux EXPORT_SYMBOL
+-0x450e1fb7    gs_alloc_req    vmlinux EXPORT_SYMBOL_GPL
+-0x176df204    tcp_get_info    vmlinux EXPORT_SYMBOL_GPL
+-0x4c2a5480    __alloc_skb     vmlinux EXPORT_SYMBOL
+-0x90814050    snd_soc_cache_write     vmlinux EXPORT_SYMBOL_GPL
+-0xa4ba4393    snd_soc_dai_set_fmt     vmlinux EXPORT_SYMBOL_GPL
+-0x2d98d3e7    jbd2_journal_begin_ordered_truncate     vmlinux EXPORT_SYMBOL
+-0x5b79185b    jbd2_trans_will_send_data_barrier       vmlinux EXPORT_SYMBOL
+-0xc200914d    mutex_trylock   vmlinux EXPORT_SYMBOL
+-0xe24d3a97    jiffies_64      vmlinux EXPORT_SYMBOL
+-0x7eb7b3f8    of_get_dma_window       vmlinux EXPORT_SYMBOL_GPL
+-0xc5c9bb41    regmap_get_val_bytes    vmlinux EXPORT_SYMBOL_GPL
+-0x8226642f    __gpio_cansleep vmlinux EXPORT_SYMBOL_GPL
+-0x6def2db2    half_md4_transform      vmlinux EXPORT_SYMBOL
+-0xb835b3e4    radix_tree_prev_hole    vmlinux EXPORT_SYMBOL
+-0xbed06655    dcache_readdir  vmlinux EXPORT_SYMBOL
+-0x980c6433    inode_add_bytes vmlinux EXPORT_SYMBOL
+-0xdc092d5b    thaw_super      vmlinux EXPORT_SYMBOL
+-0x1ef192c5    generic_file_mmap       vmlinux EXPORT_SYMBOL
+-0x9075cea3    abort_creds     vmlinux EXPORT_SYMBOL
+-0x4ef8e23f    led_set_brightness      vmlinux EXPORT_SYMBOL
+-0x48a5b067    __machine_arch_type     vmlinux EXPORT_SYMBOL
+-0x4188d439    neigh_rand_reach_time   vmlinux EXPORT_SYMBOL
+-0x7eef21b4    dev_forward_skb vmlinux EXPORT_SYMBOL_GPL
+-0x5825f0e7    sock_common_getsockopt  vmlinux EXPORT_SYMBOL
+-0x2de67218    sock_common_setsockopt  vmlinux EXPORT_SYMBOL
+-0x65408378    zlib_inflate_blob       vmlinux EXPORT_SYMBOL
+-0xc6d9568b    try_to_writeback_inodes_sb      vmlinux EXPORT_SYMBOL
+-0x5ad87de6    vfs_mknod       vmlinux EXPORT_SYMBOL
+-0x6f5c943e    rndis_add_hdr   vmlinux EXPORT_SYMBOL
+-0x6a91e934    drm_mode_create_dvi_i_properties        vmlinux EXPORT_SYMBOL
+-0x3eb37b9d    drm_ht_create   vmlinux EXPORT_SYMBOL
+-0xcdf8626d    n_tty_inherit_ops       vmlinux EXPORT_SYMBOL_GPL
+-0x65d6d0f0    gpio_direction_input    vmlinux EXPORT_SYMBOL_GPL
+-0x74acd28a    nfc_hci_set_clientdata  vmlinux EXPORT_SYMBOL
+-0x6c6a3e69    nfc_hci_get_clientdata  vmlinux EXPORT_SYMBOL
+-0x8e235e9b    cfg80211_disconnected   vmlinux EXPORT_SYMBOL
+-0x2d6b040a    cfg80211_send_rx_auth   vmlinux EXPORT_SYMBOL
+-0x987f5e85    skb_dequeue     vmlinux EXPORT_SYMBOL
+-0x413461c0    filemap_write_and_wait  vmlinux EXPORT_SYMBOL
+-0x27bbf221    disable_irq_nosync      vmlinux EXPORT_SYMBOL
+-0x00000000    softirq_work_list       vmlinux EXPORT_SYMBOL
+-0x8c298b56    vb2_ioctl_querybuf      vmlinux EXPORT_SYMBOL_GPL
+-0x94d7075a    usb_gadget_get_string   vmlinux EXPORT_SYMBOL_GPL
+-0x19ef30a6    usbnet_manage_power     vmlinux EXPORT_SYMBOL
+-0x967e7ec8    inet_rtx_syn_ack        vmlinux EXPORT_SYMBOL
+-0x9b9e05f9    alloc_cpu_rmap  vmlinux EXPORT_SYMBOL
+-0xa7f92105    add_uevent_var  vmlinux EXPORT_SYMBOL_GPL
+-0x6e6c5939    dma_buf_kunmap_atomic   vmlinux EXPORT_SYMBOL_GPL
+-0x3723eb08    __pm_relax      vmlinux EXPORT_SYMBOL_GPL
+-0x1ae74b3a    drm_framebuffer_unregister_private      vmlinux EXPORT_SYMBOL
+-0xf7584a9c    find_font       vmlinux EXPORT_SYMBOL
+-0x88e316d7    netdev_features_change  vmlinux EXPORT_SYMBOL
+-0xf19e9355    cpu_online_mask vmlinux EXPORT_SYMBOL
+-0xaa8195e9    media_entity_remote_pad vmlinux EXPORT_SYMBOL_GPL
+-0x19ec698c    platform_get_resource_byname    vmlinux EXPORT_SYMBOL_GPL
+-0x62813e5c    nf_ct_port_nlattr_tuple_size    vmlinux EXPORT_SYMBOL_GPL
+-0x4ff4a58a    nfnetlink_alloc_skb     vmlinux EXPORT_SYMBOL_GPL
+-0xeed3635b    proc_dostring   vmlinux EXPORT_SYMBOL
+-0xb54533f7    usecs_to_jiffies        vmlinux EXPORT_SYMBOL
+-0x0b56117f    of_find_node_by_path    vmlinux EXPORT_SYMBOL
+-0xcc4b84da    of_find_node_by_type    vmlinux EXPORT_SYMBOL
+-0xf9fd4da3    phy_start       vmlinux EXPORT_SYMBOL
+-0x5ea42ad5    devres_find     vmlinux EXPORT_SYMBOL_GPL
+-0x598a2261    drm_mode_probed_add     vmlinux EXPORT_SYMBOL
+-0xc35b2a18    xt_hook_link    vmlinux EXPORT_SYMBOL_GPL
+-0xc1c24fbc    genlmsg_put     vmlinux EXPORT_SYMBOL
+-0xf177aba7    sysfs_schedule_callback vmlinux EXPORT_SYMBOL_GPL
+-0xabcaa577    free_anon_bdev  vmlinux EXPORT_SYMBOL
+-0x6d289788    pwm_set_polarity        vmlinux EXPORT_SYMBOL_GPL
+-0x2546de76    raw_hash_sk     vmlinux EXPORT_SYMBOL_GPL
+-0xa2ef34d7    rps_sock_flow_table     vmlinux EXPORT_SYMBOL
+-0x3730910b    skb_insert      vmlinux EXPORT_SYMBOL
+-0xb8b7395a    snd_compress_new        vmlinux EXPORT_SYMBOL_GPL
+-0x1c132024    request_any_context_irq vmlinux EXPORT_SYMBOL_GPL
+-0x5aba52ab    iio_trigger_poll        vmlinux EXPORT_SYMBOL
+-0xe9b6f3f3    dev_emerg       vmlinux EXPORT_SYMBOL
+-0xfacd2e14    pgprot_user     vmlinux EXPORT_SYMBOL
+-0x0a0786de    udplite_table   vmlinux EXPORT_SYMBOL
+-0xd9bbcf52    tc_classify_compat      vmlinux EXPORT_SYMBOL
+-0x72f15b74    blk_queue_max_segment_size      vmlinux EXPORT_SYMBOL
+-0x544aab61    klist_add_tail  vmlinux EXPORT_SYMBOL_GPL
+-0x490434ad    dev_kfree_skb_irq       vmlinux EXPORT_SYMBOL
+-0xdb3a9b04    jbd2_journal_file_inode vmlinux EXPORT_SYMBOL
+-0x6e9dd606    __symbol_put    vmlinux EXPORT_SYMBOL
+-0x40a2d1dd    dm_table_get_size       vmlinux EXPORT_SYMBOL
+-0xceee316a    gether_set_host_addr    vmlinux EXPORT_SYMBOL
+-0x32f81723    gether_get_host_addr    vmlinux EXPORT_SYMBOL
+-0xae387af1    usb_gadget_unmap_request        vmlinux EXPORT_SYMBOL_GPL
+-0x8dfb019d    drm_buffer_free vmlinux EXPORT_SYMBOL
+-0x600683d3    do_unblank_screen       vmlinux EXPORT_SYMBOL
+-0xc1ebf6fe    get_kernel_page vmlinux EXPORT_SYMBOL_GPL
+-0x9b388444    get_zeroed_page vmlinux EXPORT_SYMBOL
+-0x53b69429    vb2_streamon    vmlinux EXPORT_SYMBOL_GPL
+-0x211aedde    genphy_restart_aneg     vmlinux EXPORT_SYMBOL
+-0xebdba37a    ndo_dflt_fdb_dump       vmlinux EXPORT_SYMBOL
+-0x604ef7b4    snd_pcm_lib_read        vmlinux EXPORT_SYMBOL
+-0x60541cbf    st_sensors_set_odr      vmlinux EXPORT_SYMBOL
+-0xe53d1faa    of_translate_dma_address        vmlinux EXPORT_SYMBOL
+-0xaf05b91b    of_device_is_available  vmlinux EXPORT_SYMBOL
+-0x1a426d0c    input_close_device      vmlinux EXPORT_SYMBOL
+-0xe720411b    rtnl_create_link        vmlinux EXPORT_SYMBOL
+-0x650f8603    snd_pcm_format_silence_64       vmlinux EXPORT_SYMBOL
+-0x7164c04b    address_space_init_once vmlinux EXPORT_SYMBOL
+-0xfda0dbe8    ftrace_print_hex_seq    vmlinux EXPORT_SYMBOL
+-0x2c988955    prepare_to_wait_exclusive       vmlinux EXPORT_SYMBOL
+-0x9c3206d8    v4l2_device_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0xd5c2bed3    phy_connect_direct      vmlinux EXPORT_SYMBOL
+-0xed2b0677    drm_mode_connector_update_edid_property vmlinux EXPORT_SYMBOL
+-0xbf17b32e    tty_insert_flip_string_flags    vmlinux EXPORT_SYMBOL
+-0xadc9ed27    bt_sock_ioctl   vmlinux EXPORT_SYMBOL
+-0x33ea8640    inet_dev_addr_type      vmlinux EXPORT_SYMBOL
+-0xd265ad57    tcf_action_exec vmlinux EXPORT_SYMBOL
+-0xec8d9205    snd_soc_register_codec  vmlinux EXPORT_SYMBOL_GPL
+-0x5e8ff943    debugfs_create_size_t   vmlinux EXPORT_SYMBOL_GPL
+-0x5b968338    remove_proc_entry       vmlinux EXPORT_SYMBOL
+-0x4717eaaf    platform_device_add     vmlinux EXPORT_SYMBOL_GPL
+-0x44a0c113    drm_mode_height vmlinux EXPORT_SYMBOL
+-0xe219d715    ipv6_opt_accepted       vmlinux EXPORT_SYMBOL_GPL
+-0x503ed988    xfrm_spd_getinfo        vmlinux EXPORT_SYMBOL
+-0x1fd1fabe    arpt_register_table     vmlinux EXPORT_SYMBOL
+-0xf9ed2e31    block_is_partially_uptodate     vmlinux EXPORT_SYMBOL
+-0xd9ecb670    ring_buffer_overruns    vmlinux EXPORT_SYMBOL_GPL
+-0x5e911cf3    exynos_g2d_exec_ioctl   vmlinux EXPORT_SYMBOL_GPL
+-0xbf69cda1    drm_connector_unplug_all        vmlinux EXPORT_SYMBOL
+-0xafe3eb1b    alloc_etherdev_mqs      vmlinux EXPORT_SYMBOL
+-0x39bf9301    _snd_pcm_hw_param_setempty      vmlinux EXPORT_SYMBOL
+-0xd81836ce    uart_resume_port        vmlinux EXPORT_SYMBOL
+-0x46931864    nfc_tm_data_received    vmlinux EXPORT_SYMBOL
+-0xfac8865f    sysctl_wmem_max vmlinux EXPORT_SYMBOL
+-0xb05fc310    sysctl_rmem_max vmlinux EXPORT_SYMBOL
+-0xe9b673fa    dapm_mark_io_dirty      vmlinux EXPORT_SYMBOL_GPL
+-0xbf0046d7    ahash_free_instance     vmlinux EXPORT_SYMBOL_GPL
+-0x825a0923    jbd2_journal_errno      vmlinux EXPORT_SYMBOL
+-0x03cb2c1a    bdi_register_dev        vmlinux EXPORT_SYMBOL
+-0x018f7433    pm_relax        vmlinux EXPORT_SYMBOL_GPL
+-0x63e0cc67    pagecache_write_end     vmlinux EXPORT_SYMBOL
+-0x8a04b9fe    tracepoint_iter_reset   vmlinux EXPORT_SYMBOL_GPL
+-0x5cf53ce2    input_free_minor        vmlinux EXPORT_SYMBOL
+-0x17bfef6c    drm_clflush_pages       vmlinux EXPORT_SYMBOL
+-0x5f14861d    pwm_get vmlinux EXPORT_SYMBOL_GPL
+-0xb8a5d4ee    cfg80211_ft_event       vmlinux EXPORT_SYMBOL
+-0xb9da2997    snmp_fold_field64       vmlinux EXPORT_SYMBOL_GPL
+-0x87925ca6    kstrtoint_from_user     vmlinux EXPORT_SYMBOL
+-0x6e891ea0    clk_unprepare   vmlinux EXPORT_SYMBOL_GPL
+-0x3d41904f    of_get_next_child       vmlinux EXPORT_SYMBOL
+-0x687835e7    hidinput_get_led_field  vmlinux EXPORT_SYMBOL_GPL
+-0x36859243    hid_resolv_usage        vmlinux EXPORT_SYMBOL_GPL
+-0x995dedd6    sdio_f0_readb   vmlinux EXPORT_SYMBOL_GPL
+-0x19f5809b    dm_ratelimit_state      vmlinux EXPORT_SYMBOL
+-0xe684f045    v4l2_subdev_try_ext_ctrls       vmlinux EXPORT_SYMBOL
+-0x41f62b69    spi_register_master     vmlinux EXPORT_SYMBOL_GPL
+-0x49428bcb    drm_read        vmlinux EXPORT_SYMBOL
+-0xb12cbacb    fb_unregister_client    vmlinux EXPORT_SYMBOL
+-0x7c53b814    xfrm_inner_extract_output       vmlinux EXPORT_SYMBOL_GPL
+-0x86dd59c8    inet_csk_init_xmit_timers       vmlinux EXPORT_SYMBOL
+-0x51e297e3    __nf_ct_l4proto_find    vmlinux EXPORT_SYMBOL_GPL
+-0x1b52db1c    probe_kernel_read       vmlinux EXPORT_SYMBOL_GPL
+-0xd4e65e28    irq_set_chip_and_handler_name   vmlinux EXPORT_SYMBOL_GPL
+-0x9c7a3b79    drm_fb_helper_debug_enter       vmlinux EXPORT_SYMBOL
+-0xc25d1133    vfs_readlink    vmlinux EXPORT_SYMBOL
+-0x7e9efe8e    complete_and_exit       vmlinux EXPORT_SYMBOL
+-0xd8d64478    v4l2_ctrl_new_std_menu_items    vmlinux EXPORT_SYMBOL
+-0xb6652875    gserial_free_line       vmlinux EXPORT_SYMBOL_GPL
+-0xd4adf602    dev_pm_get_subsys_data  vmlinux EXPORT_SYMBOL_GPL
+-0x1f335345    dev_pm_put_subsys_data  vmlinux EXPORT_SYMBOL_GPL
+-0x30399f8a    transport_add_device    vmlinux EXPORT_SYMBOL_GPL
+-0x44c2d1be    drm_mode_prune_invalid  vmlinux EXPORT_SYMBOL
+-0x3e9d6f44    cfg80211_unregister_wdev        vmlinux EXPORT_SYMBOL
+-0xfb5bb3ee    inet6_lookup    vmlinux EXPORT_SYMBOL_GPL
+-0x535cfa1f    sysfs_remove_group      vmlinux EXPORT_SYMBOL_GPL
+-0x795b1ab0    sysfs_remove_file_from_group    vmlinux EXPORT_SYMBOL_GPL
+-0x9aca444b    get_monotonic_boottime  vmlinux EXPORT_SYMBOL_GPL
+-0x91aec064    down_read_trylock       vmlinux EXPORT_SYMBOL
+-0x87e148ee    v4l2_m2m_poll   vmlinux EXPORT_SYMBOL_GPL
+-0xfcb34391    scsi_execute_req_flags  vmlinux EXPORT_SYMBOL
+-0x19391863    regmap_reinit_cache     vmlinux EXPORT_SYMBOL_GPL
+-0xff6878cf    fb_default_cmap vmlinux EXPORT_SYMBOL
+-0x38524c14    cpufreq_register_driver vmlinux EXPORT_SYMBOL_GPL
+-0x4ca0e0e5    v4l2_ctrl_modify_range  vmlinux EXPORT_SYMBOL
+-0x4f6f28fb    serial8250_handle_irq   vmlinux EXPORT_SYMBOL_GPL
+-0x7b56a1b0    nf_nat_set_seq_adjust   vmlinux EXPORT_SYMBOL_GPL
+-0x63df94bc    nf_nat_tcp_seq_adjust   vmlinux EXPORT_SYMBOL_GPL
+-0x8ffb22a4    nf_setsockopt   vmlinux EXPORT_SYMBOL
+-0xefd0fb67    nf_getsockopt   vmlinux EXPORT_SYMBOL
+-0x579e0bf5    rtnl_unregister_all     vmlinux EXPORT_SYMBOL_GPL
+-0x87e5d976    netif_rx_ni     vmlinux EXPORT_SYMBOL
+-0xe27cea7b    alloc_disk      vmlinux EXPORT_SYMBOL
+-0x1f867001    blk_rq_map_user_iov     vmlinux EXPORT_SYMBOL
+-0xa3829135    ioc_lookup_icq  vmlinux EXPORT_SYMBOL
+-0xd2ce469a    seq_puts        vmlinux EXPORT_SYMBOL
+-0xf29942b3    seq_putc        vmlinux EXPORT_SYMBOL
+-0xf268be24    dw_mci_remove   vmlinux EXPORT_SYMBOL
+-0xb7ef4006    i2c_smbus_xfer  vmlinux EXPORT_SYMBOL
+-0xb8a16d46    dev_pm_qos_remove_notifier      vmlinux EXPORT_SYMBOL_GPL
+-0x37afc4f0    device_attach   vmlinux EXPORT_SYMBOL_GPL
+-0x581e8240    tty_port_open   vmlinux EXPORT_SYMBOL
+-0xa4583858    snd_pcm_hw_param_last   vmlinux EXPORT_SYMBOL
+-0x43497fcc    part_round_stats        vmlinux EXPORT_SYMBOL_GPL
+-0x0cd23659    d_genocide      vmlinux EXPORT_SYMBOL
+-0x328995b5    tracing_generic_entry_update    vmlinux EXPORT_SYMBOL_GPL
+-0xfe24d1c7    __module_put_and_exit   vmlinux EXPORT_SYMBOL
+-0x43a53735    __alloc_workqueue_key   vmlinux EXPORT_SYMBOL_GPL
+-0x2a902f32    usb_create_shared_hcd   vmlinux EXPORT_SYMBOL_GPL
+-0xdbdbb6e7    uart_update_timeout     vmlinux EXPORT_SYMBOL
+-0xf71617c1    cfg80211_report_obss_beacon     vmlinux EXPORT_SYMBOL
+-0x3e5d6dc3    snd_soc_put_value_enum_double   vmlinux EXPORT_SYMBOL_GPL
+-0xef67a6d3    snd_soc_get_value_enum_double   vmlinux EXPORT_SYMBOL_GPL
+-0x81b69e41    snd_ctl_enum_info       vmlinux EXPORT_SYMBOL
+-0xb2b94674    __crc32c_le     vmlinux EXPORT_SYMBOL
+-0xc61cc06d    elv_dispatch_add_tail   vmlinux EXPORT_SYMBOL
+-0x85e0bce2    end_buffer_write_sync   vmlinux EXPORT_SYMBOL
+-0x3cc671ae    d_drop  vmlinux EXPORT_SYMBOL
+-0x7469f641    d_rehash        vmlinux EXPORT_SYMBOL
+-0xddcebac8    file_open_root  vmlinux EXPORT_SYMBOL
+-0x310308c3    flush_kthread_work      vmlinux EXPORT_SYMBOL_GPL
+-0x40f07981    __ashldi3       vmlinux EXPORT_SYMBOL
+-0x88e83ca7    snd_soc_dpcm_be_set_state       vmlinux EXPORT_SYMBOL_GPL
+-0x5eca39b9    snd_soc_dpcm_be_get_state       vmlinux EXPORT_SYMBOL_GPL
+-0x6b1b67d3    __bdevname      vmlinux EXPORT_SYMBOL
+-0xe4315493    vfs_write       vmlinux EXPORT_SYMBOL
+-0x99fab0b8    __mmc_claim_host        vmlinux EXPORT_SYMBOL
+-0x2c8e9ced    usb_poison_urb  vmlinux EXPORT_SYMBOL_GPL
+-0x33a8a5f0    netif_rx        vmlinux EXPORT_SYMBOL
+-0x1d54bb24    snd_pcm_hw_refine       vmlinux EXPORT_SYMBOL
+-0x955b0e2e    kthread_worker_fn       vmlinux EXPORT_SYMBOL_GPL
+-0x276ad369    dm_set_device_limits    vmlinux EXPORT_SYMBOL_GPL
+-0x9e61f179    xfrm_stateonly_find     vmlinux EXPORT_SYMBOL
+-0x972bcca5    usb_create_hcd  vmlinux EXPORT_SYMBOL_GPL
+-0x72ea7b2d    scsi_device_type        vmlinux EXPORT_SYMBOL
+-0x318cadb1    reciprocal_value        vmlinux EXPORT_SYMBOL
+-0x22f77bec    unregister_binfmt       vmlinux EXPORT_SYMBOL
+-0xafceeb25    alloc_vm_area   vmlinux EXPORT_SYMBOL_GPL
+-0xcfe980c6    make_kgid       vmlinux EXPORT_SYMBOL
+-0xb71fb74f    _raw_read_trylock       vmlinux EXPORT_SYMBOL
+-0x9dadbb88    cpufreq_boost_supported vmlinux EXPORT_SYMBOL_GPL
+-0xab9e471e    usb_autopm_get_interface_no_resume      vmlinux EXPORT_SYMBOL_GPL
+-0x42453e50    sk_reset_txq    vmlinux EXPORT_SYMBOL
+-0x05d48045    sock_no_accept  vmlinux EXPORT_SYMBOL
+-0xb511dcf5    set_groups      vmlinux EXPORT_SYMBOL
+-0x5f0abc76    pinctrl_dev_get_devname vmlinux EXPORT_SYMBOL_GPL
+-0xec25f967    klist_del       vmlinux EXPORT_SYMBOL_GPL
+-0x530ed62b    tcf_generic_walker      vmlinux EXPORT_SYMBOL
+-0xacd392a0    sock_diag_register_inet_compat  vmlinux EXPORT_SYMBOL_GPL
+-0x2509c465    dev_remove_offload      vmlinux EXPORT_SYMBOL
+-0x8ee1a28d    elevator_exit   vmlinux EXPORT_SYMBOL
+-0xcd357308    __lock_buffer   vmlinux EXPORT_SYMBOL
+-0xd85139d2    mmc_unregister_driver   vmlinux EXPORT_SYMBOL
+-0xb53559bb    brcmu_pktq_pflush       drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0xbb0ab47b    debug_locks     vmlinux EXPORT_SYMBOL_GPL
+-0x56b2a97f    ablkcipher_walk_done    vmlinux EXPORT_SYMBOL_GPL
+-0xd3630b88    ablkcipher_walk_phys    vmlinux EXPORT_SYMBOL_GPL
+-0x3116987e    aead_geniv_alloc        vmlinux EXPORT_SYMBOL_GPL
+-0x20a789ac    irq_set_chip_data       vmlinux EXPORT_SYMBOL
+-0xeda65ce1    dma_release_declared_memory     vmlinux EXPORT_SYMBOL
+-0xa984aab8    cfg80211_scan_done      vmlinux EXPORT_SYMBOL
+-0x254c40cf    inet6_csk_xmit  vmlinux EXPORT_SYMBOL_GPL
+-0xca805e0b    tcp_ioctl       vmlinux EXPORT_SYMBOL
+-0x4ebc74b2    vfs_symlink     vmlinux EXPORT_SYMBOL
+-0xefcf3143    wait_for_completion_io  vmlinux EXPORT_SYMBOL
+-0xa9efcc8b    find_vpid       vmlinux EXPORT_SYMBOL_GPL
+-0xd273b1b1    __round_jiffies_up_relative     vmlinux EXPORT_SYMBOL_GPL
+-0xb8973764    iommu_attach_group      vmlinux EXPORT_SYMBOL_GPL
+-0x5d550c4d    scsi_sd_probe_domain    vmlinux EXPORT_SYMBOL
+-0x52f9bd8e    registered_fb   vmlinux EXPORT_SYMBOL
+-0xe67d81ba    strlen_user     vmlinux EXPORT_SYMBOL
+-0x480f1913    unmap_mapping_range     vmlinux EXPORT_SYMBOL
+-0x8b618d08    overflowuid     vmlinux EXPORT_SYMBOL
+-0x7171121c    overflowgid     vmlinux EXPORT_SYMBOL
+-0xb3514b24    cfg80211_radar_event    vmlinux EXPORT_SYMBOL
+-0xf06154af    inet_select_addr        vmlinux EXPORT_SYMBOL
+-0x340854b4    dev_getbyhwaddr_rcu     vmlinux EXPORT_SYMBOL
+-0x4ce033c8    skb_flow_dissect        vmlinux EXPORT_SYMBOL
+-0x465757c3    cpu_present_mask        vmlinux EXPORT_SYMBOL
+-0xb3a37086    dma_async_tx_descriptor_init    vmlinux EXPORT_SYMBOL
+-0x955eec37    wireless_send_event     vmlinux EXPORT_SYMBOL
+-0x7954e502    ipv6_recv_error vmlinux EXPORT_SYMBOL_GPL
+-0xcebcfddd    snd_soc_get_enum_double vmlinux EXPORT_SYMBOL_GPL
+-0x1c9728c6    snd_soc_put_enum_double vmlinux EXPORT_SYMBOL_GPL
+-0xb4711532    get_task_io_context     vmlinux EXPORT_SYMBOL
+-0x6cce08e5    dcache_dir_close        vmlinux EXPORT_SYMBOL
+-0x3e884f4b    vm_get_page_prot        vmlinux EXPORT_SYMBOL
+-0x20886a16    v4l2_subdev_g_ctrl      vmlinux EXPORT_SYMBOL
+-0xd56dcf8e    v4l2_subdev_s_ctrl      vmlinux EXPORT_SYMBOL
+-0x0465a073    regmap_reg_in_ranges    vmlinux EXPORT_SYMBOL_GPL
+-0x74bc0dea    extcon_register_interest        vmlinux EXPORT_SYMBOL_GPL
+-0x59c427c5    rtc_irq_set_state       vmlinux EXPORT_SYMBOL_GPL
+-0x3302f88f    phy_driver_register     vmlinux EXPORT_SYMBOL
+-0x848dd958    scsi_dma_unmap  vmlinux EXPORT_SYMBOL
+-0xfbc74f64    __copy_from_user        vmlinux EXPORT_SYMBOL
+-0xc9bb229b    inet_put_port   vmlinux EXPORT_SYMBOL
+-0x73ac2c51    nf_conntrack_register_notifier  vmlinux EXPORT_SYMBOL_GPL
+-0xbdca8444    sock_no_connect vmlinux EXPORT_SYMBOL
+-0xe85a9fd3    cpu_cluster_pm_exit     vmlinux EXPORT_SYMBOL_GPL
+-0xcb466063    wait_for_completion_killable_timeout    vmlinux EXPORT_SYMBOL
+-0x9205953f    send_remote_softirq     vmlinux EXPORT_SYMBOL
+-0x1852156d    phy_print_status        vmlinux EXPORT_SYMBOL
+-0x486517f6    pinctrl_select_state    vmlinux EXPORT_SYMBOL_GPL
+-0xfec26b4f    skcipher_geniv_alloc    vmlinux EXPORT_SYMBOL_GPL
+-0x24094dc0    xfrm_garbage_collect    vmlinux EXPORT_SYMBOL
+-0x6e224a7a    need_conntrack  vmlinux EXPORT_SYMBOL_GPL
+-0x4a358252    __bitmap_subset vmlinux EXPORT_SYMBOL
+-0x785d8ef0    ftrace_raw_output_prep  vmlinux EXPORT_SYMBOL
+-0x697c5d0d    tracing_snapshot_alloc  vmlinux EXPORT_SYMBOL_GPL
+-0x0e6da44a    set_normalized_timespec vmlinux EXPORT_SYMBOL
+-0x789aafbd    iommu_map       vmlinux EXPORT_SYMBOL_GPL
+-0x3a5f1e17    cfg80211_chandef_valid  vmlinux EXPORT_SYMBOL
+-0xa11c9c1a    eth_type_trans  vmlinux EXPORT_SYMBOL
+-0xe0f1fc5d    debugfs_create_blob     vmlinux EXPORT_SYMBOL_GPL
+-0xd0f2dba2    mb_cache_entry_get      vmlinux EXPORT_SYMBOL
+-0x233ed03d    vm_insert_mixed vmlinux EXPORT_SYMBOL
+-0xa96bca8e    send_sig        vmlinux EXPORT_SYMBOL
+-0x97cdf185    iio_buffer_read_length  vmlinux EXPORT_SYMBOL
+-0x58d1070a    of_get_address  vmlinux EXPORT_SYMBOL
+-0x620868cc    tcp_shutdown    vmlinux EXPORT_SYMBOL
+-0x602c96f0    copy_to_user_fromio     vmlinux EXPORT_SYMBOL
+-0x6d31e93b    tracepoint_iter_next    vmlinux EXPORT_SYMBOL_GPL
+-0xe8b53ecc    down_write_trylock      vmlinux EXPORT_SYMBOL
+-0x8bfe8c57    param_set_uint  vmlinux EXPORT_SYMBOL
+-0x39422b14    usbnet_change_mtu       vmlinux EXPORT_SYMBOL_GPL
+-0x4bd9c5ed    scsi_nonblockable_ioctl vmlinux EXPORT_SYMBOL
+-0xcd319eaa    drm_vblank_count        vmlinux EXPORT_SYMBOL
+-0x58413099    ipv6_fixup_options      vmlinux EXPORT_SYMBOL_GPL
+-0xf389fe60    __hw_addr_init  vmlinux EXPORT_SYMBOL
+-0x199ed0cd    net_disable_timestamp   vmlinux EXPORT_SYMBOL
+-0x5ad8bb47    sdio_set_host_pm_flags  vmlinux EXPORT_SYMBOL_GPL
+-0xdbbdaaf8    gether_get_qmult        vmlinux EXPORT_SYMBOL
+-0x3d6846fc    gether_set_qmult        vmlinux EXPORT_SYMBOL
+-0x14b14b7a    usb_get_function        vmlinux EXPORT_SYMBOL_GPL
+-0x28fca1f1    pwmchip_add     vmlinux EXPORT_SYMBOL_GPL
+-0xfbbedefd    of_prop_next_string     vmlinux EXPORT_SYMBOL_GPL
+-0x4afe9a77    scsi_partsize   vmlinux EXPORT_SYMBOL
+-0x14f875ce    devm_regmap_init_mmio_clk       vmlinux EXPORT_SYMBOL_GPL
+-0x695aa696    __genl_register_family  vmlinux EXPORT_SYMBOL
+-0x36bd681b    groups_alloc    vmlinux EXPORT_SYMBOL
+-0x6a5b121d    of_find_device_by_node  vmlinux EXPORT_SYMBOL
+-0x0dd989e3    vb2_streamoff   vmlinux EXPORT_SYMBOL_GPL
+-0xa82de4f7    drm_pci_alloc   vmlinux EXPORT_SYMBOL
+-0xdf54a8f7    netlink_unregister_notifier     vmlinux EXPORT_SYMBOL
+-0xc4388843    dapm_regulator_event    vmlinux EXPORT_SYMBOL_GPL
+-0x7a6fa714    __dynamic_dev_dbg       vmlinux EXPORT_SYMBOL
+-0xfa4d00bd    simple_release_fs       vmlinux EXPORT_SYMBOL
+-0xf473ffaf    down    vmlinux EXPORT_SYMBOL
+-0xac6539ec    cm_notify_event vmlinux EXPORT_SYMBOL_GPL
+-0xf49484e8    blk_end_request vmlinux EXPORT_SYMBOL
+-0xb72a3fdb    drm_sysfs_connector_add vmlinux EXPORT_SYMBOL
+-0x76cf47f6    __aeabi_llsl    vmlinux EXPORT_SYMBOL
+-0x0573e568    inet_diag_dump_icsk     vmlinux EXPORT_SYMBOL_GPL
+-0xc6a360e4    skb_put vmlinux EXPORT_SYMBOL
+-0xf76b0a59    read_current_timer      vmlinux EXPORT_SYMBOL_GPL
+-0xf1d6f94c    v4l2_m2m_ioctl_reqbufs  vmlinux EXPORT_SYMBOL_GPL
+-0x5411bf06    scsi_host_put   vmlinux EXPORT_SYMBOL
+-0xbca0b4fd    nfc_hci_sak_to_protocol vmlinux EXPORT_SYMBOL
+-0x37386cac    nf_conntrack_hash_rnd   vmlinux EXPORT_SYMBOL_GPL
+-0xdb065657    nfnl_unlock     vmlinux EXPORT_SYMBOL_GPL
+-0xc5bd3b96    ethtool_op_get_ts_info  vmlinux EXPORT_SYMBOL
+-0x5f8ed047    configfs_depend_item    vmlinux EXPORT_SYMBOL
+-0x77fa6486    generic_block_fiemap    vmlinux EXPORT_SYMBOL
+-0xc7bcbc8d    add_wait_queue  vmlinux EXPORT_SYMBOL
+-0x046c1f16    param_ops_invbool       vmlinux EXPORT_SYMBOL
+-0x4fe5c427    pinctrl_put     vmlinux EXPORT_SYMBOL_GPL
+-0x547101cd    pinctrl_get     vmlinux EXPORT_SYMBOL_GPL
+-0xdcc5846a    brcmu_pktq_flush        drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x4075ad18    dev_add_pack    vmlinux EXPORT_SYMBOL
+-0x0a3131f6    strnchr vmlinux EXPORT_SYMBOL
+-0xd20bf6ba    dcookie_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0x9e2be04d    vb2_poll        vmlinux EXPORT_SYMBOL_GPL
+-0xa8f0aba7    usb_hub_clear_tt_buffer vmlinux EXPORT_SYMBOL_GPL
+-0x2698ff67    drm_helper_connector_dpms       vmlinux EXPORT_SYMBOL
+-0x48d34903    arm_dma_ops     vmlinux EXPORT_SYMBOL
+-0x9f984513    strrchr vmlinux EXPORT_SYMBOL
+-0x7afa89fc    vsnprintf       vmlinux EXPORT_SYMBOL
+-0x7fe32873    rb_replace_node vmlinux EXPORT_SYMBOL
+-0x6ff607b6    crypto_get_default_rng  vmlinux EXPORT_SYMBOL_GPL
+-0x668402aa    crypto_put_default_rng  vmlinux EXPORT_SYMBOL_GPL
+-0x850ff7d2    crypto_mod_put  vmlinux EXPORT_SYMBOL_GPL
+-0x1db21259    mount_pseudo    vmlinux EXPORT_SYMBOL
+-0x304ec72b    _raw_write_trylock      vmlinux EXPORT_SYMBOL
+-0x4205ad24    cancel_work_sync        vmlinux EXPORT_SYMBOL_GPL
+-0x99cdc86b    sysctl_tcp_reordering   vmlinux EXPORT_SYMBOL
+-0x19d94b34    nf_ct_gre_keymap_flush  vmlinux EXPORT_SYMBOL
+-0x356bcd72    nf_log_set      vmlinux EXPORT_SYMBOL
+-0xd9e69bb2    dapm_reg_event  vmlinux EXPORT_SYMBOL_GPL
+-0xb2959203    snd_pcm_hw_constraint_pow2      vmlinux EXPORT_SYMBOL
+-0x9754ec10    radix_tree_preload      vmlinux EXPORT_SYMBOL
+-0xc8cd27b8    blkdev_ioctl    vmlinux EXPORT_SYMBOL_GPL
+-0xd11c0dc1    __kernel_param_unlock   vmlinux EXPORT_SYMBOL
+-0xcda686ec    input_set_keycode       vmlinux EXPORT_SYMBOL
+-0xc69c2d23    subsys_virtual_register vmlinux EXPORT_SYMBOL_GPL
+-0x4eb8fe91    drm_gem_free_mmap_offset        vmlinux EXPORT_SYMBOL
+-0x61cdf6e6    nfc_hci_allocate_device vmlinux EXPORT_SYMBOL
+-0x2dda642f    __dynamic_netdev_dbg    vmlinux EXPORT_SYMBOL
+-0x890dc2ed    idr_alloc_cyclic        vmlinux EXPORT_SYMBOL
+-0x5cf6db68    crypto_register_instance        vmlinux EXPORT_SYMBOL_GPL
+-0x93bd657f    crypto_alloc_tfm        vmlinux EXPORT_SYMBOL_GPL
+-0x9c48a3ba    bdi_destroy     vmlinux EXPORT_SYMBOL
+-0x29047f1a    __i2c_board_lock        vmlinux EXPORT_SYMBOL_GPL
+-0x02e49d29    tty_ldisc_flush vmlinux EXPORT_SYMBOL_GPL
+-0xb06d489b    skb_tstamp_tx   vmlinux EXPORT_SYMBOL_GPL
+-0xe66452ab    dql_init        vmlinux EXPORT_SYMBOL
+-0x69e27c7a    bitmap_copy_le  vmlinux EXPORT_SYMBOL
+-0x4dec6038    memscan vmlinux EXPORT_SYMBOL
+-0xa9148d85    mark_buffer_dirty       vmlinux EXPORT_SYMBOL
+-0x304b568f    get_super       vmlinux EXPORT_SYMBOL
+-0x00801678    flush_scheduled_work    vmlinux EXPORT_SYMBOL
+-0xb6115ca3    tty_set_operations      vmlinux EXPORT_SYMBOL
+-0x6d6cb9ad    ieee80211_operating_class_to_band       vmlinux EXPORT_SYMBOL
+-0x32e1f29c    skb_copy_and_csum_bits  vmlinux EXPORT_SYMBOL
+-0x776c599d    idma_reg_addr_init      vmlinux EXPORT_SYMBOL_GPL
+-0xef9f2dc8    ll_rw_block     vmlinux EXPORT_SYMBOL
+-0x13014091    block_write_begin       vmlinux EXPORT_SYMBOL
+-0x93226faa    irq_domain_associate_many       vmlinux EXPORT_SYMBOL_GPL
+-0x756a4248    st_sensors_read_info_raw        vmlinux EXPORT_SYMBOL
+-0x04339915    iio_update_buffers      vmlinux EXPORT_SYMBOL_GPL
+-0x55784228    regmap_irq_get_virq     vmlinux EXPORT_SYMBOL_GPL
+-0xbc25aac9    ump_dd_phys_blocks_get  vmlinux EXPORT_SYMBOL
+-0xe1761617    security_inet_conn_request      vmlinux EXPORT_SYMBOL
+-0x1268f357    resume_device_irqs      vmlinux EXPORT_SYMBOL_GPL
+-0xbe2e3b75    kstrtos8        vmlinux EXPORT_SYMBOL
+-0x124f2056    crypto_get_attr_type    vmlinux EXPORT_SYMBOL_GPL
+-0x2fc54b62    nfnetlink_send  vmlinux EXPORT_SYMBOL_GPL
+-0x9479479b    wm_hubs_hpr_mux vmlinux EXPORT_SYMBOL_GPL
+-0x49e22268    snd_soc_info_volsw_s8   vmlinux EXPORT_SYMBOL_GPL
+-0x329aef1b    crypto_alloc_aead       vmlinux EXPORT_SYMBOL_GPL
+-0x851d17d2    crypto_spawn_tfm2       vmlinux EXPORT_SYMBOL_GPL
+-0xce6a9d9a    trace_current_buffer_discard_commit     vmlinux EXPORT_SYMBOL_GPL
+-0x50fad434    round_jiffies_up        vmlinux EXPORT_SYMBOL_GPL
+-0xf7f16b3f    input_get_new_minor     vmlinux EXPORT_SYMBOL
+-0x26c90ea4    scsi_eh_get_sense       vmlinux EXPORT_SYMBOL_GPL
+-0x75e49326    device_create_bin_file  vmlinux EXPORT_SYMBOL_GPL
+-0x113c622e    dev_set_mac_address     vmlinux EXPORT_SYMBOL
+-0xe13ad642    sk_receive_skb  vmlinux EXPORT_SYMBOL
+-0xf5c05914    generic_segment_checks  vmlinux EXPORT_SYMBOL
+-0xd0f36f0d    audit_log_format        vmlinux EXPORT_SYMBOL
+-0xdbaf59ef    v4l2_m2m_mmap   vmlinux EXPORT_SYMBOL
+-0xde520229    serio_open      vmlinux EXPORT_SYMBOL
+-0xc5714a65    spi_master_suspend      vmlinux EXPORT_SYMBOL_GPL
+-0x22b325d5    kd_mksound      vmlinux EXPORT_SYMBOL
+-0x6d2fc5a6    net_namespace_list      vmlinux EXPORT_SYMBOL_GPL
+-0x9f6381e8    sock_register   vmlinux EXPORT_SYMBOL
+-0xf1806da9    idr_find_slowpath       vmlinux EXPORT_SYMBOL
+-0x5ae5be44    lg_lock_init    vmlinux EXPORT_SYMBOL
+-0x2d307e05    vb2_ioctl_qbuf  vmlinux EXPORT_SYMBOL_GPL
+-0xaad6c827    serio_close     vmlinux EXPORT_SYMBOL
+-0x8b092f05    loop_register_transfer  vmlinux EXPORT_SYMBOL
+-0x3c967a5a    device_set_wakeup_enable        vmlinux EXPORT_SYMBOL_GPL
+-0xc34b9b1f    regulator_get_bypass_regmap     vmlinux EXPORT_SYMBOL_GPL
+-0xde9cc521    pinctrl_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0xd1c5bc52    __cfg80211_send_deauth  vmlinux EXPORT_SYMBOL
+-0x126ad73c    inet6_register_protosw  vmlinux EXPORT_SYMBOL
+-0x5ce3b588    nfnl_lock       vmlinux EXPORT_SYMBOL_GPL
+-0xdc197993    netif_set_real_num_tx_queues    vmlinux EXPORT_SYMBOL
+-0xd4d07dc9    netif_set_real_num_rx_queues    vmlinux EXPORT_SYMBOL
+-0xbdc3f3e4    dev_set_group   vmlinux EXPORT_SYMBOL
+-0xb4176982    proc_remove     vmlinux EXPORT_SYMBOL
+-0x663e9182    end_buffer_async_write  vmlinux EXPORT_SYMBOL
+-0x3d517179    phy_register_fixup_for_uid      vmlinux EXPORT_SYMBOL
+-0xb4709322    scsi_dev_info_add_list  vmlinux EXPORT_SYMBOL
+-0x9dd34b62    drm_mm_insert_node_in_range     vmlinux EXPORT_SYMBOL
+-0x69b18f43    rfc1042_header  vmlinux EXPORT_SYMBOL
+-0x50097088    security_tun_dev_free_security  vmlinux EXPORT_SYMBOL
+-0x050c08c1    vfs_writev      vmlinux EXPORT_SYMBOL
+-0xd6b5a293    iio_buffer_init vmlinux EXPORT_SYMBOL
+-0x811e0359    sdio_get_host_pm_caps   vmlinux EXPORT_SYMBOL_GPL
+-0x9062c322    ring_buffer_consume     vmlinux EXPORT_SYMBOL_GPL
+-0x1c5b1f28    irq_free_descs  vmlinux EXPORT_SYMBOL_GPL
+-0xf2791baa    cgroup_unload_subsys    vmlinux EXPORT_SYMBOL_GPL
+-0xe43274bc    proc_dointvec   vmlinux EXPORT_SYMBOL
+-0xe8948e95    mmc_stop_bkops  vmlinux EXPORT_SYMBOL
+-0xa2a5fd77    inet_ehash_secret       vmlinux EXPORT_SYMBOL
+-0x2363e5bf    __inet_lookup_established       vmlinux EXPORT_SYMBOL_GPL
+-0x3eeb1d5e    netdev_alert    vmlinux EXPORT_SYMBOL
+-0x26ad413b    netdev_has_any_upper_dev        vmlinux EXPORT_SYMBOL
+-0x7604b234    udp_lib_rehash  vmlinux EXPORT_SYMBOL
+-0x5e5d53d3    udp_lib_unhash  vmlinux EXPORT_SYMBOL
+-0x2b12925d    cpumask_next_and        vmlinux EXPORT_SYMBOL
+-0x05495392    hid_debug       vmlinux EXPORT_SYMBOL_GPL
+-0x1d1ca867    pm_stay_awake   vmlinux EXPORT_SYMBOL_GPL
+-0x8c1a19df    device_show_ulong       vmlinux EXPORT_SYMBOL_GPL
+-0x46940ff4    set_ras_addr_hook       vmlinux EXPORT_SYMBOL_GPL
+-0x6088da85    nf_hook_slow    vmlinux EXPORT_SYMBOL
+-0xce5ac24f    zlib_inflate_workspacesize      vmlinux EXPORT_SYMBOL
+-0x2e73d9a1    v4l2_chip_ident_i2c_client      vmlinux EXPORT_SYMBOL
+-0x3783cdae    drm_open        vmlinux EXPORT_SYMBOL
+-0x5404b1e7    tcp_recvmsg     vmlinux EXPORT_SYMBOL
+-0x47b90df9    snd_pcm_limit_hw_rates  vmlinux EXPORT_SYMBOL
+-0x63baba6b    irq_alloc_generic_chip  vmlinux EXPORT_SYMBOL_GPL
+-0xace5c0fc    usb_bus_list    vmlinux EXPORT_SYMBOL_GPL
+-0xe8b63ace    radix_tree_range_tag_if_tagged  vmlinux EXPORT_SYMBOL
+-0x8d8b6353    proc_dointvec_userhz_jiffies    vmlinux EXPORT_SYMBOL
+-0x7ec5c02b    console_start   vmlinux EXPORT_SYMBOL
+-0x1a1aebf8    s3c_adc_start   vmlinux EXPORT_SYMBOL_GPL
+-0xffc6c87a    drm_detect_monitor_audio        vmlinux EXPORT_SYMBOL
+-0xe1371ad4    tcp_simple_retransmit   vmlinux EXPORT_SYMBOL
+-0x0f18b144    inet_csk_bind_conflict  vmlinux EXPORT_SYMBOL_GPL
+-0x708e56bd    xt_register_match       vmlinux EXPORT_SYMBOL
+-0xf3526269    proc_set_user   vmlinux EXPORT_SYMBOL
+-0x752dff9d    anon_inode_getfile      vmlinux EXPORT_SYMBOL_GPL
+-0xcd10fb11    simple_dir_inode_operations     vmlinux EXPORT_SYMBOL
+-0x708bd95d    irq_domain_xlate_onetwocell     vmlinux EXPORT_SYMBOL_GPL
+-0x122043a8    of_find_node_with_property      vmlinux EXPORT_SYMBOL
+-0xb3453966    vb2_fop_release vmlinux EXPORT_SYMBOL_GPL
+-0x59dddb40    ump_dd_reference_add    vmlinux EXPORT_SYMBOL
+-0xe8bcc079    snd_soc_codec_set_cache_io      vmlinux EXPORT_SYMBOL_GPL
+-0x67ae5cfb    dmam_pool_create        vmlinux EXPORT_SYMBOL
+-0x1e7f65cb    vb2_mmap        vmlinux EXPORT_SYMBOL_GPL
+-0xb33ff162    __find_get_block        vmlinux EXPORT_SYMBOL
+-0x23a997f4    dcache_dir_open vmlinux EXPORT_SYMBOL
+-0x3f4547a7    put_unused_fd   vmlinux EXPORT_SYMBOL
+-0xd2555f19    jiffies_64_to_clock_t   vmlinux EXPORT_SYMBOL
+-0xef969c64    input_mt_get_slot_by_key        vmlinux EXPORT_SYMBOL
+-0x2b547fec    genphy_suspend  vmlinux EXPORT_SYMBOL
+-0x0a04ac5b    subsys_system_register  vmlinux EXPORT_SYMBOL_GPL
+-0x919a5e62    inet6_lookup_listener   vmlinux EXPORT_SYMBOL_GPL
+-0xece784c2    rb_first        vmlinux EXPORT_SYMBOL
+-0xc72e1233    __trace_bprintk vmlinux EXPORT_SYMBOL_GPL
+-0x6a5ecb18    unregister_module_notifier      vmlinux EXPORT_SYMBOL
+-0x19f115c3    flush_delayed_work      vmlinux EXPORT_SYMBOL
+-0xf82f5060    usbnet_read_cmd vmlinux EXPORT_SYMBOL_GPL
+-0xf3e09d59    dev_pm_qos_expose_latency_limit vmlinux EXPORT_SYMBOL_GPL
+-0xfc4cb906    exynos_drm_subdrv_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0x04911106    of_dma_simple_xlate     vmlinux EXPORT_SYMBOL_GPL
+-0x7211e749    nf_conntrack_hash_check_insert  vmlinux EXPORT_SYMBOL_GPL
+-0x68b80336    zero_fill_bio   vmlinux EXPORT_SYMBOL
+-0xe83fad56    mmc_switch      vmlinux EXPORT_SYMBOL_GPL
+-0xa5a8337c    scsi_cmd_print_sense_hdr        vmlinux EXPORT_SYMBOL
+-0x8b08c5c1    unix_peer_get   vmlinux EXPORT_SYMBOL_GPL
+-0xef3b173b    audit_log_task_info     vmlinux EXPORT_SYMBOL
+-0xacc26098    iio_read_const_attr     vmlinux EXPORT_SYMBOL
+-0x47d7d62e    mmc_resume_host vmlinux EXPORT_SYMBOL
+-0x323758b8    v4l2_spi_subdev_init    vmlinux EXPORT_SYMBOL_GPL
+-0xbaa5b6b2    bus_register    vmlinux EXPORT_SYMBOL_GPL
+-0xf39ab86b    tcp_syn_ack_timeout     vmlinux EXPORT_SYMBOL
+-0xe73dda41    __nf_ct_ext_add_length  vmlinux EXPORT_SYMBOL
+-0xc4ff89ae    nf_log_unregister       vmlinux EXPORT_SYMBOL
+-0xd8e38717    d_hash_and_lookup       vmlinux EXPORT_SYMBOL
+-0x63193a50    generic_file_buffered_write     vmlinux EXPORT_SYMBOL
+-0xcce7df45    iio_alloc_pollfunc      vmlinux EXPORT_SYMBOL_GPL
+-0x24b0f90c    of_clk_get_by_name      vmlinux EXPORT_SYMBOL
+-0x3fb35146    mmc_alloc_host  vmlinux EXPORT_SYMBOL
+-0xe6099979    scsi_eh_ready_devs      vmlinux EXPORT_SYMBOL_GPL
+-0x986e6135    fb_pad_unaligned_buffer vmlinux EXPORT_SYMBOL
+-0xc1c2dd09    __hw_addr_flush vmlinux EXPORT_SYMBOL
+-0xae249a24    snd_register_device_for_dev     vmlinux EXPORT_SYMBOL
+-0xea054b22    nla_policy_len  vmlinux EXPORT_SYMBOL
+-0xd92afabe    bitmap_clear    vmlinux EXPORT_SYMBOL
+-0x80f48353    fsync_bdev      vmlinux EXPORT_SYMBOL
+-0x71930ed3    of_property_read_string vmlinux EXPORT_SYMBOL_GPL
+-0x570f339b    thermal_cooling_device_register vmlinux EXPORT_SYMBOL_GPL
+-0xcfcdd86a    input_open_device       vmlinux EXPORT_SYMBOL
+-0x84ac53cc    drm_fb_helper_single_add_all_connectors vmlinux EXPORT_SYMBOL
+-0x0e3edf75    regulator_set_bypass_regmap     vmlinux EXPORT_SYMBOL_GPL
+-0xfe990052    gpio_free       vmlinux EXPORT_SYMBOL_GPL
+-0x0b63a348    cfg80211_wext_giwrange  vmlinux EXPORT_SYMBOL_GPL
+-0x6d815a8f    ip6_dst_lookup  vmlinux EXPORT_SYMBOL_GPL
+-0x40a9b349    vzalloc vmlinux EXPORT_SYMBOL
+-0xc2f9c045    timespec_to_jiffies     vmlinux EXPORT_SYMBOL
+-0x54159824    iio_push_event  vmlinux EXPORT_SYMBOL
+-0x94f95b4e    i2c_new_device  vmlinux EXPORT_SYMBOL_GPL
+-0xe04e6d60    device_for_each_child   vmlinux EXPORT_SYMBOL_GPL
+-0x5eafb8e9    drm_mode_set_name       vmlinux EXPORT_SYMBOL
+-0x3b0a974f    arm_iommu_release_mapping       vmlinux EXPORT_SYMBOL_GPL
+-0xed76ba4a    hci_resume_dev  vmlinux EXPORT_SYMBOL
+-0x9cfaab5e    media_device_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x5783d440    pm_generic_poweroff_late        vmlinux EXPORT_SYMBOL_GPL
+-0x59c8991b    nci_allocate_device     vmlinux EXPORT_SYMBOL
+-0x11089ac7    _ctype  vmlinux EXPORT_SYMBOL
+-0x66d480cb    blk_get_queue   vmlinux EXPORT_SYMBOL
+-0x60b78a66    bd_set_size     vmlinux EXPORT_SYMBOL
+-0x71f34013    __mem_cgroup_count_vm_event     vmlinux EXPORT_SYMBOL
+-0x2d45b494    pm_vt_switch_unregister vmlinux EXPORT_SYMBOL
+-0xca7d8764    kthread_freezable_should_stop   vmlinux EXPORT_SYMBOL_GPL
+-0x03b3002e    st_sensors_enable_events        vmlinux EXPORT_SYMBOL
+-0xfc937fcb    usb_add_gadget_udc      vmlinux EXPORT_SYMBOL_GPL
+-0x420323e6    i2c_dp_aux_add_bus      vmlinux EXPORT_SYMBOL
+-0xd6ef94db    udp_proc_unregister     vmlinux EXPORT_SYMBOL
+-0x37f614b7    __kfifo_len_r   vmlinux EXPORT_SYMBOL
+-0xac6e0f5a    power_supply_get_by_name        vmlinux EXPORT_SYMBOL_GPL
+-0x86047552    inet_sk_rebuild_header  vmlinux EXPORT_SYMBOL
+-0x3c878c55    skb_copy        vmlinux EXPORT_SYMBOL
+-0xe5b6e62e    snd_pcm_stop    vmlinux EXPORT_SYMBOL
+-0x7593d385    div64_s64       vmlinux EXPORT_SYMBOL
+-0x27864d57    memparse        vmlinux EXPORT_SYMBOL
+-0xe8f9c617    block_truncate_page     vmlinux EXPORT_SYMBOL
+-0xbc036e9e    generic_write_checks    vmlinux EXPORT_SYMBOL
+-0x4f68e5c9    do_gettimeofday vmlinux EXPORT_SYMBOL
+-0xa6715115    do_settimeofday vmlinux EXPORT_SYMBOL
+-0xd9efbe4c    input_inject_event      vmlinux EXPORT_SYMBOL
+-0x3dc565d9    drm_mm_insert_node_generic      vmlinux EXPORT_SYMBOL
+-0x0c58a8cd    netdev_increment_features       vmlinux EXPORT_SYMBOL
+-0xb3c487b6    uart_match_port vmlinux EXPORT_SYMBOL
+-0x208f2017    brcmu_pktq_pdeq_match   drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0xbc455bde    cfg80211_pmksa_candidate_notify vmlinux EXPORT_SYMBOL
+-0x3bef03b9    flow_cache_lookup       vmlinux EXPORT_SYMBOL
+-0x5002ec2f    __splice_from_pipe      vmlinux EXPORT_SYMBOL
+-0x863c552c    cache_firmware  vmlinux EXPORT_SYMBOL_GPL
+-0xe5274b72    unregister_net_sysctl_table     vmlinux EXPORT_SYMBOL_GPL
+-0xa197b1ff    ieee80211_get_mesh_hdrlen       vmlinux EXPORT_SYMBOL
+-0x3a9592df    __nf_ct_ext_destroy     vmlinux EXPORT_SYMBOL
+-0xa2c640f9    sysfs_add_file_to_group vmlinux EXPORT_SYMBOL_GPL
+-0x487d9343    param_ops_ushort        vmlinux EXPORT_SYMBOL
+-0x58804ca9    sdio_align_size vmlinux EXPORT_SYMBOL_GPL
+-0xa09e1f4c    cpufreq_register_governor       vmlinux EXPORT_SYMBOL_GPL
+-0x8ee7279a    ump_dd_size_get vmlinux EXPORT_SYMBOL
+-0xfb858f46    tty_write_room  vmlinux EXPORT_SYMBOL
+-0x3d715445    dev_trans_start vmlinux EXPORT_SYMBOL
+-0xa381944f    dql_reset       vmlinux EXPORT_SYMBOL
+-0x8f99ae4c    blk_register_region     vmlinux EXPORT_SYMBOL
+-0xa8242495    bio_put vmlinux EXPORT_SYMBOL
+-0x488d1fd7    task_tgid_nr_ns vmlinux EXPORT_SYMBOL
+-0xc8d55b31    usb_unlocked_disable_lpm        vmlinux EXPORT_SYMBOL_GPL
+-0x10ee20bb    default_blu     vmlinux EXPORT_SYMBOL
+-0x57575f08    dmaengine_put   vmlinux EXPORT_SYMBOL
+-0x60577ee3    ip6_expire_frag_queue   vmlinux EXPORT_SYMBOL
+-0xdb5d34e0    rcu_batches_completed_preempt   vmlinux EXPORT_SYMBOL_GPL
+-0xec6f4d80    each_symbol_section     vmlinux EXPORT_SYMBOL_GPL
+-0xea6e3003    of_find_compatible_node vmlinux EXPORT_SYMBOL
+-0x0d95dc3b    video_ioctl2    vmlinux EXPORT_SYMBOL
+-0x26156aad    input_alloc_absinfo     vmlinux EXPORT_SYMBOL
+-0x244b53b3    scsi_is_target_device   vmlinux EXPORT_SYMBOL
+-0xd0cf28c6    sk_dst_check    vmlinux EXPORT_SYMBOL
+-0xa5dd45f3    prandom_bytes_state     vmlinux EXPORT_SYMBOL
+-0x6a76f3ac    blk_iopoll_enable       vmlinux EXPORT_SYMBOL
+-0x17e1907b    inode_needs_sync        vmlinux EXPORT_SYMBOL
+-0x9c6ac1ed    grab_cache_page_nowait  vmlinux EXPORT_SYMBOL
+-0xe7a81967    audit_log_secctx        vmlinux EXPORT_SYMBOL
+-0x2babe81f    __wake_up_sync_key      vmlinux EXPORT_SYMBOL_GPL
+-0x4adaf0f3    v4l2_ctrl_query_menu_valid_items        vmlinux EXPORT_SYMBOL
+-0xcb6f482d    dev_getfirstbyhwtype    vmlinux EXPORT_SYMBOL
+-0xb23df37e    wake_up_process vmlinux EXPORT_SYMBOL
+-0x25820c64    fs_overflowuid  vmlinux EXPORT_SYMBOL
+-0x24ddf922    scsi_internal_device_block      vmlinux EXPORT_SYMBOL_GPL
+-0x1079ac8f    drm_framebuffer_remove  vmlinux EXPORT_SYMBOL
+-0x160f2f7e    of_phy_simple_xlate     vmlinux EXPORT_SYMBOL_GPL
+-0xe669c8a2    __nf_ct_refresh_acct    vmlinux EXPORT_SYMBOL_GPL
+-0xa2f20d05    skb_dequeue_tail        vmlinux EXPORT_SYMBOL
+-0x19a025aa    __get_user_pages        vmlinux EXPORT_SYMBOL
+-0x286acd69    free_css_id     vmlinux EXPORT_SYMBOL_GPL
+-0x404c4f08    __module_address        vmlinux EXPORT_SYMBOL_GPL
+-0x195d329a    hidinput_count_leds     vmlinux EXPORT_SYMBOL_GPL
+-0x280c859a    input_ff_erase  vmlinux EXPORT_SYMBOL_GPL
+-0x886d02da    scsi_target_resume      vmlinux EXPORT_SYMBOL
+-0x8f31e347    inet_stream_ops vmlinux EXPORT_SYMBOL
+-0x9b0dcfa2    qdisc_reset     vmlinux EXPORT_SYMBOL
+-0xd2da1048    register_netdevice_notifier     vmlinux EXPORT_SYMBOL
+-0x1b5fff19    blk_complete_request    vmlinux EXPORT_SYMBOL
+-0x808ec1a3    crypto_alg_tested       vmlinux EXPORT_SYMBOL_GPL
+-0xda920cd9    bio_unmap_user  vmlinux EXPORT_SYMBOL
+-0xe769232e    sprint_symbol_no_offset vmlinux EXPORT_SYMBOL_GPL
+-0x2b7a6de8    syscon_regmap_lookup_by_phandle vmlinux EXPORT_SYMBOL_GPL
+-0x9728e93f    of_dma_controller_register      vmlinux EXPORT_SYMBOL_GPL
+-0x1b61c5b3    pwm_config      vmlinux EXPORT_SYMBOL_GPL
+-0x39bdf0f0    nci_free_device vmlinux EXPORT_SYMBOL
+-0xe3a306b5    udp_seq_open    vmlinux EXPORT_SYMBOL
+-0x38c97d50    idr_get_next    vmlinux EXPORT_SYMBOL
+-0xeaacc92f    fail_migrate_page       vmlinux EXPORT_SYMBOL
+-0x4cdb3178    ns_to_timeval   vmlinux EXPORT_SYMBOL
+-0xc78d0953    ehci_init_driver        vmlinux EXPORT_SYMBOL_GPL
+-0xcd6ff125    nf_ct_expect_register_notifier  vmlinux EXPORT_SYMBOL_GPL
+-0x721b1851    skip_spaces     vmlinux EXPORT_SYMBOL
+-0x0c0c015e    ring_buffer_swap_cpu    vmlinux EXPORT_SYMBOL_GPL
+-0x76d451c4    add_taint       vmlinux EXPORT_SYMBOL
+-0x1c2596ba    regmap_async_complete_cb        vmlinux EXPORT_SYMBOL_GPL
+-0x60a32ea9    pm_power_off    vmlinux EXPORT_SYMBOL
+-0x2b911208    __neigh_for_each_release        vmlinux EXPORT_SYMBOL
+-0x0bc7e6ff    blk_queue_init_tags     vmlinux EXPORT_SYMBOL
+-0xa666946b    bdget   vmlinux EXPORT_SYMBOL
+-0x885a4cc9    bdput   vmlinux EXPORT_SYMBOL
+-0x2517dbbb    fsstack_copy_inode_size vmlinux EXPORT_SYMBOL_GPL
+-0x7d4ed855    iio_trigger_poll_chained        vmlinux EXPORT_SYMBOL
+-0x561e4b77    irq_of_parse_and_map    vmlinux EXPORT_SYMBOL_GPL
+-0x308efc55    spi_busnum_to_master    vmlinux EXPORT_SYMBOL_GPL
+-0xe862c4b7    dpm_suspend_start       vmlinux EXPORT_SYMBOL_GPL
+-0xd728282d    device_initialize       vmlinux EXPORT_SYMBOL_GPL
+-0xf6b77868    nf_conntrack_untracked  vmlinux EXPORT_SYMBOL
+-0xed9f8e6d    kstrtos16       vmlinux EXPORT_SYMBOL
+-0xfb32b30f    ring_buffer_read_prepare_sync   vmlinux EXPORT_SYMBOL_GPL
+-0x846bcc01    dm_table_get    vmlinux EXPORT_SYMBOL
+-0x1416333b    tcf_em_register vmlinux EXPORT_SYMBOL
+-0x19546cac    snd_soc_cache_read      vmlinux EXPORT_SYMBOL_GPL
+-0xfd2f4f20    snd_soc_info_volsw_ext  vmlinux EXPORT_SYMBOL_GPL
+-0x6c749afe    __tracepoint_block_unplug       vmlinux EXPORT_SYMBOL_GPL
+-0x9c86ede0    fs_kobj vmlinux EXPORT_SYMBOL_GPL
+-0x796c2d48    dm_get_md       vmlinux EXPORT_SYMBOL_GPL
+-0xf8fbb4f0    __bad_xchg      vmlinux EXPORT_SYMBOL
+-0xc40f284c    nf_ct_helper_hsize      vmlinux EXPORT_SYMBOL_GPL
+-0x24428be5    strncpy_from_user       vmlinux EXPORT_SYMBOL
+-0x6d74d462    crypto_alloc_ablkcipher vmlinux EXPORT_SYMBOL_GPL
+-0x0b96efa8    bio_init        vmlinux EXPORT_SYMBOL
+-0x7278d328    all_vm_events   vmlinux EXPORT_SYMBOL_GPL
+-0x41814cb8    dirty_writeback_interval        vmlinux EXPORT_SYMBOL_GPL
+-0x1c32da2a    iio_enum_available_read vmlinux EXPORT_SYMBOL_GPL
+-0xcda91c46    drm_mode_debug_printmodeline    vmlinux EXPORT_SYMBOL
+-0xa9cae71a    inet6_hash_connect      vmlinux EXPORT_SYMBOL_GPL
+-0x92f5d840    gnet_stats_copy_rate_est        vmlinux EXPORT_SYMBOL
+-0x17f61c70    skb_partial_csum_set    vmlinux EXPORT_SYMBOL_GPL
+-0xb86cf818    create_empty_buffers    vmlinux EXPORT_SYMBOL
+-0x26332c2f    init_special_inode      vmlinux EXPORT_SYMBOL
+-0xd0720a17    on_each_cpu_cond        vmlinux EXPORT_SYMBOL
+-0x870713f0    iommu_detach_group      vmlinux EXPORT_SYMBOL_GPL
+-0x00c8b1c1    sdio_enable_func        vmlinux EXPORT_SYMBOL_GPL
+-0x22f907ec    pm_runtime_no_callbacks vmlinux EXPORT_SYMBOL_GPL
+-0x8d4234e8    subsys_dev_iter_next    vmlinux EXPORT_SYMBOL_GPL
+-0x706fc943    mali_pmu_powerup        vmlinux EXPORT_SYMBOL
+-0xf24fbd54    cfg80211_mgmt_tx_status vmlinux EXPORT_SYMBOL
+-0xa8bae0ab    inet_frag_destroy       vmlinux EXPORT_SYMBOL
+-0xca1aff2d    ipv4_sk_update_pmtu     vmlinux EXPORT_SYMBOL_GPL
+-0x539973c5    skb_make_writable       vmlinux EXPORT_SYMBOL
+-0x2eeceb42    sk_chk_filter   vmlinux EXPORT_SYMBOL
+-0x8f595b11    snd_major       vmlinux EXPORT_SYMBOL
+-0xf8433bfd    pipe_to_file    vmlinux EXPORT_SYMBOL
+-0x0dc1d65b    __dec_zone_page_state   vmlinux EXPORT_SYMBOL
+-0x95ce193b    __inc_zone_page_state   vmlinux EXPORT_SYMBOL
+-0x736c2d7c    __mod_zone_page_state   vmlinux EXPORT_SYMBOL
+-0xab6babaf    pm_qos_request  vmlinux EXPORT_SYMBOL_GPL
+-0xeed6cc4b    flush_kthread_worker    vmlinux EXPORT_SYMBOL_GPL
+-0xa5cef8ad    release_resource        vmlinux EXPORT_SYMBOL
+-0x4584b8a3    iio_push_to_buffers     vmlinux EXPORT_SYMBOL_GPL
+-0xc79bcd36    dm_vcalloc      vmlinux EXPORT_SYMBOL
+-0xa7dd8c46    ump_dd_phys_block_get   vmlinux EXPORT_SYMBOL
+-0x83bd3297    brioctl_set     vmlinux EXPORT_SYMBOL
+-0x09e913c1    snd_pcm_alt_chmaps      vmlinux EXPORT_SYMBOL_GPL
+-0xbf33e600    vm_insert_pfn   vmlinux EXPORT_SYMBOL
+-0xda050109    irq_domain_add_nomap    vmlinux EXPORT_SYMBOL_GPL
+-0xfcaa04a0    out_of_line_wait_on_bit_lock    vmlinux EXPORT_SYMBOL
+-0xa7bb71ae    input_set_abs_params    vmlinux EXPORT_SYMBOL
+-0x22f9a7f4    spi_bus_unlock  vmlinux EXPORT_SYMBOL_GPL
+-0x2ea5ad9c    device_schedule_callback_owner  vmlinux EXPORT_SYMBOL_GPL
+-0x4c511235    drm_edid_is_valid       vmlinux EXPORT_SYMBOL
+-0x3939f8f0    rfkill_pause_polling    vmlinux EXPORT_SYMBOL
+-0xebc7bcd9    xfrm_state_alloc        vmlinux EXPORT_SYMBOL
+-0x85670f1d    rtnl_is_locked  vmlinux EXPORT_SYMBOL
+-0x726d45d3    fat_remove_entries      vmlinux EXPORT_SYMBOL_GPL
+-0xd963ea55    page_symlink    vmlinux EXPORT_SYMBOL
+-0xa26d9b4f    workqueue_congested     vmlinux EXPORT_SYMBOL_GPL
+-0xf7cd6b11    freq_reg_info   vmlinux EXPORT_SYMBOL
+-0x764dafa5    __xfrm_route_forward    vmlinux EXPORT_SYMBOL
+-0xd317cce2    snd_soc_put_volsw_sx    vmlinux EXPORT_SYMBOL_GPL
+-0x587ba0c8    snd_soc_get_volsw_s8    vmlinux EXPORT_SYMBOL_GPL
+-0x5dda7051    snd_soc_put_volsw_s8    vmlinux EXPORT_SYMBOL_GPL
+-0xd6b61c7b    snd_soc_get_volsw_sx    vmlinux EXPORT_SYMBOL_GPL
+-0x9f0664bf    dm_get_queue_limits     vmlinux EXPORT_SYMBOL_GPL
+-0x0364983f    gen_replace_estimator   vmlinux EXPORT_SYMBOL
+-0x2f03fc4b    security_secmark_refcount_inc   vmlinux EXPORT_SYMBOL
+-0x19bd383b    security_secmark_refcount_dec   vmlinux EXPORT_SYMBOL
+-0xc22b50ad    param_set_bint  vmlinux EXPORT_SYMBOL
+-0x21315700    param_get_bool  vmlinux EXPORT_SYMBOL
+-0x3eae292f    param_set_byte  vmlinux EXPORT_SYMBOL
+-0xcea1a019    dw_mci_suspend  vmlinux EXPORT_SYMBOL
+-0x8657c2d4    spi_bitbang_setup       vmlinux EXPORT_SYMBOL_GPL
+-0xb13fbb9a    scsi_target_unblock     vmlinux EXPORT_SYMBOL_GPL
+-0xbf3a015f    brcmf_sdio_remove       drivers/net/wireless/brcm80211/brcmfmac/brcmfmac        EXPORT_SYMBOL
+-0xeb1c3628    nf_ipv6_ops     vmlinux EXPORT_SYMBOL_GPL
+-0x9fdecc31    unregister_netdevice_many       vmlinux EXPORT_SYMBOL
+-0x75308bb0    blk_queue_logical_block_size    vmlinux EXPORT_SYMBOL
+-0x2fe50bdf    init_srcu_struct        vmlinux EXPORT_SYMBOL_GPL
+-0xfba64859    rtc_device_unregister   vmlinux EXPORT_SYMBOL_GPL
+-0xbd10afa1    drm_platform_init       vmlinux EXPORT_SYMBOL
+-0xa1ceb496    drm_platform_exit       vmlinux EXPORT_SYMBOL
+-0xd10d7d37    arp_tbl vmlinux EXPORT_SYMBOL
+-0x9aa6cefb    __skb_recv_datagram     vmlinux EXPORT_SYMBOL
+-0x0430401c    snd_soc_remove_platform vmlinux EXPORT_SYMBOL_GPL
+-0xfe7c4287    nr_cpu_ids      vmlinux EXPORT_SYMBOL
+-0x18b6fa40    v4l2_ctrl_add_ctrl      vmlinux EXPORT_SYMBOL
+-0xb21d34e2    phy_attach      vmlinux EXPORT_SYMBOL
+-0x67f7fd01    gpiochip_remove_pin_ranges      vmlinux EXPORT_SYMBOL_GPL
+-0x5c9284a0    processor_id    vmlinux EXPORT_SYMBOL
+-0x688e3c72    tcp_splice_read vmlinux EXPORT_SYMBOL
+-0x9f7f32fe    xt_unregister_match     vmlinux EXPORT_SYMBOL
+-0x2822f8fe    irq_setup_generic_chip  vmlinux EXPORT_SYMBOL_GPL
+-0x8763d790    pm_genpd_syscore_switch vmlinux EXPORT_SYMBOL_GPL
+-0xc898f9f7    css_depth       vmlinux EXPORT_SYMBOL_GPL
+-0x95d97984    devm_regmap_init_spi    vmlinux EXPORT_SYMBOL_GPL
+-0x32108723    devm_regmap_init_i2c    vmlinux EXPORT_SYMBOL_GPL
+-0x824028e1    drm_master_get  vmlinux EXPORT_SYMBOL
+-0x36e360e3    __hw_addr_add_multiple  vmlinux EXPORT_SYMBOL
+-0x92e42550    snd_soc_jack_add_gpios  vmlinux EXPORT_SYMBOL_GPL
+-0x9552bd34    crypto_unregister_algs  vmlinux EXPORT_SYMBOL_GPL
+-0x70bd3119    simple_transaction_set  vmlinux EXPORT_SYMBOL
+-0x5cf1e7e1    simple_transaction_get  vmlinux EXPORT_SYMBOL
+-0x86b57862    find_pid_ns     vmlinux EXPORT_SYMBOL_GPL
+-0x0b59c21c    st_gyro_common_probe    vmlinux EXPORT_SYMBOL
+-0x3a4c6000    of_irq_to_resource      vmlinux EXPORT_SYMBOL_GPL
+-0xcbc9557f    unregister_sysrq_key    vmlinux EXPORT_SYMBOL
+-0xd85ac634    regulator_put   vmlinux EXPORT_SYMBOL_GPL
+-0x56e75d47    klist_node_attached     vmlinux EXPORT_SYMBOL_GPL
+-0xf0d6c49d    rfkill_alloc    vmlinux EXPORT_SYMBOL
+-0xe118d3ca    __nf_conntrack_find     vmlinux EXPORT_SYMBOL_GPL
+-0x67fa9d64    __nlmsg_put     vmlinux EXPORT_SYMBOL
+-0xc5f839f2    lock_sock_nested        vmlinux EXPORT_SYMBOL
+-0x92b57248    flush_work      vmlinux EXPORT_SYMBOL_GPL
+-0x63aecd53    hid_add_device  vmlinux EXPORT_SYMBOL_GPL
+-0x870e11ef    sdio_disable_func       vmlinux EXPORT_SYMBOL_GPL
+-0xd6c99af7    devm_usb_put_phy        vmlinux EXPORT_SYMBOL_GPL
+-0x60652b23    usbnet_cdc_bind vmlinux EXPORT_SYMBOL_GPL
+-0x0f1fd032    scsi_free_command       vmlinux EXPORT_SYMBOL
+-0x150d593e    platform_add_devices    vmlinux EXPORT_SYMBOL_GPL
+-0xdc2235fd    device_show_bool        vmlinux EXPORT_SYMBOL_GPL
+-0xe800ece3    __mmc_switch    vmlinux EXPORT_SYMBOL_GPL
+-0x8650b7ba    usb_deregister  vmlinux EXPORT_SYMBOL_GPL
+-0x83a82050    phy_ethtool_get_eee     vmlinux EXPORT_SYMBOL
+-0xccb94d1a    phy_ethtool_set_eee     vmlinux EXPORT_SYMBOL
+-0x1a81168a    drm_mm_dump_table       vmlinux EXPORT_SYMBOL
+-0x04cda566    snd_interval_refine     vmlinux EXPORT_SYMBOL
+-0x6b2dc060    dump_stack      vmlinux EXPORT_SYMBOL
+-0x23476dca    crypto_alloc_instance   vmlinux EXPORT_SYMBOL_GPL
+-0x31cd11aa    mpage_writepage vmlinux EXPORT_SYMBOL
+-0xa219c44e    try_to_writeback_inodes_sb_nr   vmlinux EXPORT_SYMBOL
+-0xd942d353    ring_buffer_record_off  vmlinux EXPORT_SYMBOL_GPL
+-0x178768e1    set_security_override   vmlinux EXPORT_SYMBOL
+-0x7930d225    of_device_is_compatible vmlinux EXPORT_SYMBOL
+-0xa1fb703c    drm_mm_remove_node      vmlinux EXPORT_SYMBOL
+-0x3fce0784    rdev_get_drvdata        vmlinux EXPORT_SYMBOL_GPL
+-0x193f9832    nfc_allocate_device     vmlinux EXPORT_SYMBOL
+-0xcefba9ae    raw_seq_start   vmlinux EXPORT_SYMBOL_GPL
+-0x353b4dcf    nfnetlink_subsys_unregister     vmlinux EXPORT_SYMBOL_GPL
+-0x1db53c10    dst_cow_metrics_generic vmlinux EXPORT_SYMBOL
+-0x884c205c    mount_ns        vmlinux EXPORT_SYMBOL
+-0x26b0e339    sdhci_disable_irq_wakeups       vmlinux EXPORT_SYMBOL_GPL
+-0x69e3154c    rtc_read_time   vmlinux EXPORT_SYMBOL_GPL
+-0xde6ff4ec    usb_get_function_instance       vmlinux EXPORT_SYMBOL_GPL
+-0x0c29207f    netdev_master_upper_dev_get     vmlinux EXPORT_SYMBOL
+-0x62d34ec2    kobject_del     vmlinux EXPORT_SYMBOL
+-0x7489664f    crypto_unregister_shash vmlinux EXPORT_SYMBOL_GPL
+-0x5ca7f0f8    crypto_unregister_ahash vmlinux EXPORT_SYMBOL_GPL
+-0x86a4889a    kmalloc_order_trace     vmlinux EXPORT_SYMBOL
+-0x0698cb23    drm_core_reclaim_buffers        vmlinux EXPORT_SYMBOL
+-0x94478b76    nat_callforwarding_hook vmlinux EXPORT_SYMBOL_GPL
+-0x6e4b8906    snd_ctl_find_numid      vmlinux EXPORT_SYMBOL
+-0xb6a68816    find_last_bit   vmlinux EXPORT_SYMBOL
+-0xc8d47bdb    inode_dio_done  vmlinux EXPORT_SYMBOL
+-0xb9ca066f    poll_initwait   vmlinux EXPORT_SYMBOL
+-0x193d48e0    trace_current_buffer_unlock_commit      vmlinux EXPORT_SYMBOL_GPL
+-0x46a36032    unregister_console      vmlinux EXPORT_SYMBOL
+-0xd0fbc335    vb2_get_vma     vmlinux EXPORT_SYMBOL_GPL
+-0x6ebd302d    usb_reset_endpoint      vmlinux EXPORT_SYMBOL_GPL
+-0x38a4f7ae    drm_format_num_planes   vmlinux EXPORT_SYMBOL
+-0xc414c422    drm_vblank_offdelay     vmlinux EXPORT_SYMBOL
+-0x96554810    register_keyboard_notifier      vmlinux EXPORT_SYMBOL_GPL
+-0x2ec0f25c    nf_ct_helper_ext_add    vmlinux EXPORT_SYMBOL_GPL
+-0xe745ec59    aead_geniv_free vmlinux EXPORT_SYMBOL_GPL
+-0xd8e484f0    register_chrdev_region  vmlinux EXPORT_SYMBOL
+-0xc58b6dd5    led_trigger_unregister_simple   vmlinux EXPORT_SYMBOL_GPL
+-0x068f1d12    phy_disconnect  vmlinux EXPORT_SYMBOL
+-0x9c518b55    regmap_update_bits      vmlinux EXPORT_SYMBOL_GPL
+-0xc63f1b81    ieee80211_radiotap_iterator_next        vmlinux EXPORT_SYMBOL
+-0x9744e080    inet_csk_reqsk_queue_prune      vmlinux EXPORT_SYMBOL_GPL
+-0xb9ff0fd7    netdev_state_change     vmlinux EXPORT_SYMBOL
+-0x310917fe    sort    vmlinux EXPORT_SYMBOL
+-0xa8fef7bb    security_unix_may_send  vmlinux EXPORT_SYMBOL
+-0x541bd60a    irq_work_run    vmlinux EXPORT_SYMBOL_GPL
+-0x6c49c4f2    clockevents_notify      vmlinux EXPORT_SYMBOL_GPL
+-0xe208ea98    hci_recv_stream_fragment        vmlinux EXPORT_SYMBOL
+-0xe6c68334    ddebug_remove_module    vmlinux EXPORT_SYMBOL_GPL
+-0xf8ae0cbf    kern_path       vmlinux EXPORT_SYMBOL
+-0x6e9dd7bc    usb_sg_cancel   vmlinux EXPORT_SYMBOL_GPL
+-0x7c05fd17    nf_register_queue_handler       vmlinux EXPORT_SYMBOL
+-0x2a8db409    snd_soc_dai_set_tristate        vmlinux EXPORT_SYMBOL_GPL
+-0x29b1c366    __sg_alloc_table        vmlinux EXPORT_SYMBOL
+-0x9c3889f4    shrink_dcache_sb        vmlinux EXPORT_SYMBOL
+-0x15692c87    param_ops_int   vmlinux EXPORT_SYMBOL
+-0xd04e04f7    iio_update_demux        vmlinux EXPORT_SYMBOL_GPL
+-0x105a7a58    dma_alloc_from_coherent vmlinux EXPORT_SYMBOL
+-0xe4309905    syscore_resume  vmlinux EXPORT_SYMBOL_GPL
+-0xab482a65    blkdev_issue_flush      vmlinux EXPORT_SYMBOL
+-0x499043d3    crypto_init_queue       vmlinux EXPORT_SYMBOL_GPL
+-0xca871be2    default_backing_dev_info        vmlinux EXPORT_SYMBOL_GPL
+-0x3d5120d1    st_accel_common_probe   vmlinux EXPORT_SYMBOL
+-0x44f5e8b5    of_allnodes     vmlinux EXPORT_SYMBOL
+-0xf563353a    v4l2_subdev_link_validate       vmlinux EXPORT_SYMBOL_GPL
+-0x011cf028    regulator_suspend_finish        vmlinux EXPORT_SYMBOL_GPL
+-0x1b88e3fa    find_inode_number       vmlinux EXPORT_SYMBOL
+-0xb2d307de    param_ops_short vmlinux EXPORT_SYMBOL
+-0x0b586662    drm_gem_object_init     vmlinux EXPORT_SYMBOL
+-0xaad6d92f    rfkill_init_sw_state    vmlinux EXPORT_SYMBOL
+-0x4f4d4dc8    hci_unregister_dev      vmlinux EXPORT_SYMBOL
+-0xa6970398    __kfifo_to_user_r       vmlinux EXPORT_SYMBOL
+-0xf7f92f26    st_sensors_set_enable   vmlinux EXPORT_SYMBOL
+-0x236bcb52    unregister_con_driver   vmlinux EXPORT_SYMBOL
+-0x39898017    amba_device_put vmlinux EXPORT_SYMBOL_GPL
+-0x8d28fc98    amba_device_add vmlinux EXPORT_SYMBOL_GPL
+-0x3169d518    softnet_data    vmlinux EXPORT_SYMBOL
+-0x5fc56a46    _raw_spin_unlock        vmlinux EXPORT_SYMBOL
+-0xfe5d4bb2    sys_tz  vmlinux EXPORT_SYMBOL
+-0x81ced62d    ip6_sk_redirect vmlinux EXPORT_SYMBOL_GPL
+-0x9ffa3a75    netdev_max_backlog      vmlinux EXPORT_SYMBOL
+-0xfa237e15    __skb_tx_hash   vmlinux EXPORT_SYMBOL
+-0x1b701804    blk_init_queue  vmlinux EXPORT_SYMBOL
+-0x474d3122    unlock_page     vmlinux EXPORT_SYMBOL
+-0x4f98d766    cpu_pm_unregister_notifier      vmlinux EXPORT_SYMBOL_GPL
+-0x76963409    lock_fb_info    vmlinux EXPORT_SYMBOL
+-0x11e2ec12    flex_array_free_parts   vmlinux EXPORT_SYMBOL
+-0x5ecb52ac    sdio_memcpy_fromio      vmlinux EXPORT_SYMBOL_GPL
+-0xa4480afe    drm_sysfs_hotplug_event vmlinux EXPORT_SYMBOL
+-0xeaab7f82    lcd_device_register     vmlinux EXPORT_SYMBOL
+-0x0c12eee9    xfrm_unregister_type    vmlinux EXPORT_SYMBOL
+-0x297f1a00    nf_ip_checksum  vmlinux EXPORT_SYMBOL
+-0xd14bc4d9    sock_diag_save_cookie   vmlinux EXPORT_SYMBOL_GPL
+-0xdd810ba9    snd_info_register       vmlinux EXPORT_SYMBOL
+-0x773a9c94    blk_iopoll_enabled      vmlinux EXPORT_SYMBOL
+-0xd704f458    jbd2_log_wait_commit    vmlinux EXPORT_SYMBOL
+-0x22e82b9e    hrtimer_init_sleeper    vmlinux EXPORT_SYMBOL_GPL
+-0x437e0518    eth_rebuild_header      vmlinux EXPORT_SYMBOL
+-0x47fb2e90    neigh_compat_output     vmlinux EXPORT_SYMBOL
+-0x0283dfe3    _snd_pcm_hw_params_any  vmlinux EXPORT_SYMBOL
+-0xe2407fb6    user_path_at    vmlinux EXPORT_SYMBOL
+-0x35d93ce8    cgroup_add_cftypes      vmlinux EXPORT_SYMBOL_GPL
+-0x4ac62273    module_put      vmlinux EXPORT_SYMBOL
+-0x2459bbcc    console_set_on_cmdline  vmlinux EXPORT_SYMBOL
+-0xbec530ad    max8997_update_reg      vmlinux EXPORT_SYMBOL_GPL
+-0x3255972d    hdmi_vendor_infoframe_pack      vmlinux EXPORT_SYMBOL
+-0x8da61397    ip_tunnel_rcv   vmlinux EXPORT_SYMBOL_GPL
+-0x3c44f68c    inode_get_bytes vmlinux EXPORT_SYMBOL
+-0xd85cd67e    __wake_up       vmlinux EXPORT_SYMBOL
+-0xcefe5c3b    usb_get_from_anchor     vmlinux EXPORT_SYMBOL_GPL
+-0x9a858808    genphy_resume   vmlinux EXPORT_SYMBOL
+-0x606ae2bc    drm_mm_debug_table      vmlinux EXPORT_SYMBOL
+-0xed636ddf    nf_conntrack_helper_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0xc7a1840e    llist_add_batch vmlinux EXPORT_SYMBOL_GPL
+-0x2787db00    vbin_printf     vmlinux EXPORT_SYMBOL_GPL
+-0xfe59fc1b    security_d_instantiate  vmlinux EXPORT_SYMBOL
+-0x6b8286e4    bio_reset       vmlinux EXPORT_SYMBOL
+-0x86414ad5    vfs_mkdir       vmlinux EXPORT_SYMBOL
+-0x87b883c7    i2c_for_each_dev        vmlinux EXPORT_SYMBOL_GPL
+-0x26f81b6a    dev_driver_string       vmlinux EXPORT_SYMBOL
+-0x1c787b32    eventfd_ctx_fileget     vmlinux EXPORT_SYMBOL_GPL
+-0x01139ffc    max_mapnr       vmlinux EXPORT_SYMBOL
+-0xec17ebb0    of_match_node   vmlinux EXPORT_SYMBOL
+-0x69ce0071    usb_driver_claim_interface      vmlinux EXPORT_SYMBOL_GPL
+-0x9cfd56c5    scsi_print_status       vmlinux EXPORT_SYMBOL
+-0xdce6abcd    drm_gem_prime_handle_to_fd      vmlinux EXPORT_SYMBOL
+-0x020f03b7    drm_sysfs_connector_remove      vmlinux EXPORT_SYMBOL
+-0x2a8aa04e    pinctrl_add_gpio_range  vmlinux EXPORT_SYMBOL_GPL
+-0x981dcc58    eventfd_fget    vmlinux EXPORT_SYMBOL_GPL
+-0x7c995f04    dget_parent     vmlinux EXPORT_SYMBOL
+-0x9a932b80    of_find_i2c_device_by_node      vmlinux EXPORT_SYMBOL
+-0x2b460363    led_trigger_set vmlinux EXPORT_SYMBOL_GPL
+-0x107733e3    wiphy_new       vmlinux EXPORT_SYMBOL
+-0xd7b7598e    snd_pcm_mmap_data       vmlinux EXPORT_SYMBOL
+-0x4e1636f1    mb_cache_create vmlinux EXPORT_SYMBOL
+-0x70bec618    iunique vmlinux EXPORT_SYMBOL
+-0x121d958a    unregister_die_notifier vmlinux EXPORT_SYMBOL_GPL
+-0xbef4c852    hid_dump_input  vmlinux EXPORT_SYMBOL_GPL
+-0x55423fc4    dm_requeue_unmapped_request     vmlinux EXPORT_SYMBOL_GPL
+-0x2e67fc27    matrix_keypad_build_keymap      vmlinux EXPORT_SYMBOL
+-0xe7c7c6b0    usb_disable_autosuspend vmlinux EXPORT_SYMBOL_GPL
+-0x783194cd    usb_get_dev     vmlinux EXPORT_SYMBOL_GPL
+-0x5614b010    xfrm_policy_walk_done   vmlinux EXPORT_SYMBOL
+-0x6d5a6c10    inet_dgram_ops  vmlinux EXPORT_SYMBOL
+-0x42e7ca3d    blk_alloc_queue vmlinux EXPORT_SYMBOL
+-0xfdbd0a9b    mb_cache_destroy        vmlinux EXPORT_SYMBOL
+-0x59cbc3ca    input_release_device    vmlinux EXPORT_SYMBOL
+-0xd0e5d6d2    scsi_put_command        vmlinux EXPORT_SYMBOL
+-0x480dca40    sec_reg_update  vmlinux EXPORT_SYMBOL_GPL
+-0x28a73d8e    snd_soc_unregister_card vmlinux EXPORT_SYMBOL_GPL
+-0x05fc144e    get_gendisk     vmlinux EXPORT_SYMBOL
+-0xfef8a166    trace_current_buffer_lock_reserve       vmlinux EXPORT_SYMBOL_GPL
+-0x7dccc294    proc_doulongvec_minmax  vmlinux EXPORT_SYMBOL
+-0x92c0c538    ieee80211_bss_get_ie    vmlinux EXPORT_SYMBOL
+-0x386ec802    tcp_proc_unregister     vmlinux EXPORT_SYMBOL
+-0xb327256f    simple_attr_open        vmlinux EXPORT_SYMBOL_GPL
+-0x56e9103b    cpu_pm_enter    vmlinux EXPORT_SYMBOL_GPL
+-0x1e48b59d    __css_tryget    vmlinux EXPORT_SYMBOL_GPL
+-0xbcbaa80a    __wake_up_locked_key    vmlinux EXPORT_SYMBOL_GPL
+-0x2d1b02d2    usermodehelper_read_lock_wait   vmlinux EXPORT_SYMBOL_GPL
+-0x72bfae4f    hwmon_device_register   vmlinux EXPORT_SYMBOL_GPL
+-0x3db7f213    v4l2_of_get_remote_port vmlinux EXPORT_SYMBOL
+-0x5de3f132    usb_interface_id        vmlinux EXPORT_SYMBOL_GPL
+-0x9ca5592b    usb_store_new_id        vmlinux EXPORT_SYMBOL_GPL
+-0x90fb0fa6    sdev_evt_send_simple    vmlinux EXPORT_SYMBOL_GPL
+-0x25892d59    drm_vblank_post_modeset vmlinux EXPORT_SYMBOL
+-0x8ecafd4a    drm_fb_helper_blank     vmlinux EXPORT_SYMBOL
+-0x590d45c1    sk_clear_memalloc       vmlinux EXPORT_SYMBOL_GPL
+-0x4578f528    __kfifo_to_user vmlinux EXPORT_SYMBOL
+-0xf7ddfd4e    done_path_create        vmlinux EXPORT_SYMBOL
+-0x85c10896    rcu_batches_completed_bh        vmlinux EXPORT_SYMBOL_GPL
+-0x036dd11a    cgroup_path     vmlinux EXPORT_SYMBOL_GPL
+-0xcc7fa952    local_bh_enable_ip      vmlinux EXPORT_SYMBOL
+-0xa90054ee    rndis_uninit    vmlinux EXPORT_SYMBOL
+-0x15407a03    usb_root_hub_lost_power vmlinux EXPORT_SYMBOL_GPL
+-0x06fc143d    xfrm4_rcv_encap vmlinux EXPORT_SYMBOL
+-0xa0c5538e    udp_poll        vmlinux EXPORT_SYMBOL
+-0xd9f41f16    skb_copy_ubufs  vmlinux EXPORT_SYMBOL_GPL
+-0xc83b4d5b    posix_acl_from_mode     vmlinux EXPORT_SYMBOL
+-0x51ef33b8    kstrndup        vmlinux EXPORT_SYMBOL
+-0x0bed814c    irq_set_chip    vmlinux EXPORT_SYMBOL
+-0xd0f6cf25    console_stop    vmlinux EXPORT_SYMBOL
+-0xd955eb7d    iommu_group_remove_device       vmlinux EXPORT_SYMBOL_GPL
+-0xfb5dc251    gserial_disconnect      vmlinux EXPORT_SYMBOL_GPL
+-0x42252607    inet6_getname   vmlinux EXPORT_SYMBOL
+-0xe65b1e97    nf_conntrack_tuple_taken        vmlinux EXPORT_SYMBOL_GPL
+-0x7abbee1e    wm_hubs_handle_analogue_pdata   vmlinux EXPORT_SYMBOL_GPL
+-0x06dceffb    snd_soc_of_parse_daifmt vmlinux EXPORT_SYMBOL_GPL
+-0xf4439247    snd_device_register     vmlinux EXPORT_SYMBOL
+-0xebcea57f    evict_bh_lrus   vmlinux EXPORT_SYMBOL_GPL
+-0x9714253c    mfd_add_devices vmlinux EXPORT_SYMBOL
+-0x26256356    drm_mode_equal_no_clocks        vmlinux EXPORT_SYMBOL
+-0x1be7f7c8    debugfs_create_file     vmlinux EXPORT_SYMBOL_GPL
+-0xdbb607c7    new_inode       vmlinux EXPORT_SYMBOL
+-0xa576c92e    drm_mode_config_reset   vmlinux EXPORT_SYMBOL
+-0x832ca829    snd_ctl_find_id vmlinux EXPORT_SYMBOL
+-0x65dccf13    xz_dec_end      vmlinux EXPORT_SYMBOL
+-0xf9348cbc    xz_dec_run      vmlinux EXPORT_SYMBOL
+-0xe0b13336    argv_free       vmlinux EXPORT_SYMBOL
+-0x8815b870    jbd2_journal_clear_err  vmlinux EXPORT_SYMBOL
+-0x861359ed    of_get_phy_mode vmlinux EXPORT_SYMBOL_GPL
+-0x28a2ed02    scsi_build_sense_buffer vmlinux EXPORT_SYMBOL
+-0x86240fb6    tty_port_close  vmlinux EXPORT_SYMBOL
+-0x8d3e24c6    genl_unregister_family  vmlinux EXPORT_SYMBOL
+-0x9d0d6206    unregister_netdevice_notifier   vmlinux EXPORT_SYMBOL
+-0x18640d1b    mmc_suspend_host        vmlinux EXPORT_SYMBOL
+-0x9082ce2b    tty_register_driver     vmlinux EXPORT_SYMBOL
+-0x71f65175    hdmi_spd_infoframe_pack vmlinux EXPORT_SYMBOL
+-0x3d6f0d06    ndo_dflt_fdb_del        vmlinux EXPORT_SYMBOL
+-0xaeefbeed    kset_unregister vmlinux EXPORT_SYMBOL
+-0xa498b92e    debugfs_create_u32      vmlinux EXPORT_SYMBOL_GPL
+-0x7ed8eb88    sdio_release_host       vmlinux EXPORT_SYMBOL_GPL
+-0xd1e4eed4    v4l2_fh_init    vmlinux EXPORT_SYMBOL_GPL
+-0x5b42ed42    v4l2_fh_exit    vmlinux EXPORT_SYMBOL_GPL
+-0x5947abbe    max77693_bulk_write     vmlinux EXPORT_SYMBOL_GPL
+-0x7afa1fc2    driver_remove_file      vmlinux EXPORT_SYMBOL_GPL
+-0xacefc84d    netdev_rx_handler_register      vmlinux EXPORT_SYMBOL_GPL
+-0xd2e829b5    jbd2_journal_release_jbd_inode  vmlinux EXPORT_SYMBOL
+-0xcd343f41    mmc_gpio_free_ro        vmlinux EXPORT_SYMBOL
+-0x26f37f1a    inet_csk_reset_keepalive_timer  vmlinux EXPORT_SYMBOL
+-0x49603fb8    security_sb_copy_data   vmlinux EXPORT_SYMBOL
+-0x53326531    mempool_alloc_pages     vmlinux EXPORT_SYMBOL
+-0x2b49351d    trace_define_field      vmlinux EXPORT_SYMBOL_GPL
+-0x47939e0d    __tasklet_hi_schedule   vmlinux EXPORT_SYMBOL
+-0x78c5a239    clk_prepare     vmlinux EXPORT_SYMBOL_GPL
+-0x1a36f8fd    udc_attach_driver       vmlinux EXPORT_SYMBOL_GPL
+-0xcb56fc45    dev_vprintk_emit        vmlinux EXPORT_SYMBOL
+-0xed2817be    arp_send        vmlinux EXPORT_SYMBOL
+-0x7d903146    xt_register_matches     vmlinux EXPORT_SYMBOL
+-0x3ed63055    zlib_inflateReset       vmlinux EXPORT_SYMBOL
+-0x281823c5    __kfifo_out_peek        vmlinux EXPORT_SYMBOL
+-0xb19760c3    bitmap_onto     vmlinux EXPORT_SYMBOL
+-0xaf9b8476    cdev_del        vmlinux EXPORT_SYMBOL
+-0xbc8da552    tcp_seq_open    vmlinux EXPORT_SYMBOL
+-0x35224ff2    pneigh_enqueue  vmlinux EXPORT_SYMBOL
+-0x0d2e0ab9    dev_alloc_name  vmlinux EXPORT_SYMBOL
+-0xebd8aaa8    iov_iter_copy_from_user vmlinux EXPORT_SYMBOL
+-0x134dc23b    v4l2_m2m_dqbuf  vmlinux EXPORT_SYMBOL_GPL
+-0x1cfa672b    soft_cursor     vmlinux EXPORT_SYMBOL
+-0xac8f37b2    outer_cache     vmlinux EXPORT_SYMBOL
+-0x744bfef9    generic_fh_to_dentry    vmlinux EXPORT_SYMBOL_GPL
+-0xa3225eb1    try_to_del_timer_sync   vmlinux EXPORT_SYMBOL
+-0x6a1733eb    iommu_group_unregister_notifier vmlinux EXPORT_SYMBOL_GPL
+-0xc84dae86    matrix_keypad_parse_of_params   vmlinux EXPORT_SYMBOL_GPL
+-0x404403a9    usb_free_all_descriptors        vmlinux EXPORT_SYMBOL_GPL
+-0x50eca283    ipcomp_output   vmlinux EXPORT_SYMBOL_GPL
+-0xe482d673    nf_ct_expect_related_report     vmlinux EXPORT_SYMBOL_GPL
+-0x26e58975    __pskb_copy     vmlinux EXPORT_SYMBOL
+-0xd3dcab0b    flex_array_alloc        vmlinux EXPORT_SYMBOL
+-0x247f1878    blk_queue_bounce        vmlinux EXPORT_SYMBOL
+-0x97b13dad    __clocksource_register_scale    vmlinux EXPORT_SYMBOL_GPL
+-0xdc73e48f    dm_unregister_target    vmlinux EXPORT_SYMBOL
+-0xfe0f06c0    tty_init_termios        vmlinux EXPORT_SYMBOL_GPL
+-0xb8356d30    dma_async_memcpy_buf_to_pg      vmlinux EXPORT_SYMBOL
+-0xd8d3cf00    read_dev_sector vmlinux EXPORT_SYMBOL
+-0x220669c4    scsi_cmd_blk_ioctl      vmlinux EXPORT_SYMBOL
+-0x03c91b88    crypto_alloc_instance2  vmlinux EXPORT_SYMBOL_GPL
+-0x4d9c0e6d    jbd2_journal_revoke     vmlinux EXPORT_SYMBOL
+-0xaca5e909    config_group_find_item  vmlinux EXPORT_SYMBOL
+-0xe01ba49b    iio_kfifo_allocate      vmlinux EXPORT_SYMBOL
+-0xe170917a    timed_output_dev_unregister     vmlinux EXPORT_SYMBOL_GPL
+-0x4f689046    brcmu_pkt_buf_free_skb  drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x932f03cb    security_old_inode_init_security        vmlinux EXPORT_SYMBOL
+-0xa4e5092b    debugfs_create_x16      vmlinux EXPORT_SYMBOL_GPL
+-0x1826f089    __tracepoint_kmem_cache_alloc_node      vmlinux EXPORT_SYMBOL
+-0xd81de62c    ring_buffer_record_enable       vmlinux EXPORT_SYMBOL_GPL
+-0xc7fe94dd    usb_ifnum_to_if vmlinux EXPORT_SYMBOL_GPL
+-0xc2af811e    inet6_destroy_sock      vmlinux EXPORT_SYMBOL_GPL
+-0x061651be    strcat  vmlinux EXPORT_SYMBOL
+-0xb39ec138    mb_cache_entry_release  vmlinux EXPORT_SYMBOL
+-0x51d559d1    _raw_spin_unlock_irqrestore     vmlinux EXPORT_SYMBOL
+-0xa6eb0e39    phy_device_create       vmlinux EXPORT_SYMBOL
+-0xf92c66be    drm_mm_search_free_generic      vmlinux EXPORT_SYMBOL
+-0x97270fcf    crypto_register_shash   vmlinux EXPORT_SYMBOL_GPL
+-0x495f2be4    jbd2_journal_get_write_access   vmlinux EXPORT_SYMBOL
+-0x3826f483    jbd2_journal_invalidatepage     vmlinux EXPORT_SYMBOL
+-0xd8a12f4d    iio_scan_mask_query     vmlinux EXPORT_SYMBOL_GPL
+-0x09b069ea    v4l2_ctrl_log_status    vmlinux EXPORT_SYMBOL
+-0x0a513c7c    usb_gadget_unregister_driver    vmlinux EXPORT_SYMBOL_GPL
+-0x39ef8cc9    dma_buf_kunmap  vmlinux EXPORT_SYMBOL_GPL
+-0xd28b5dda    dma_buf_vunmap  vmlinux EXPORT_SYMBOL_GPL
+-0x3fcf2826    inet6_unregister_protosw        vmlinux EXPORT_SYMBOL
+-0x551c3633    nf_nat_l4proto_unique_tuple     vmlinux EXPORT_SYMBOL_GPL
+-0x86700640    nf_register_hooks       vmlinux EXPORT_SYMBOL
+-0x44e94d6c    pfifo_qdisc_ops vmlinux EXPORT_SYMBOL
+-0xf202c5cb    radix_tree_insert       vmlinux EXPORT_SYMBOL
+-0x24ffe755    vfs_listxattr   vmlinux EXPORT_SYMBOL_GPL
+-0x52428cc8    parent_mem_cgroup       vmlinux EXPORT_SYMBOL
+-0x9d59c0f2    find_get_pages_contig   vmlinux EXPORT_SYMBOL
+-0x80f3268f    __trace_printk  vmlinux EXPORT_SYMBOL_GPL
+-0x22a27a85    st_sensors_spi_configure        vmlinux EXPORT_SYMBOL
+-0x7880c781    dm_kcopyd_prepare_callback      vmlinux EXPORT_SYMBOL
+-0xc53f0876    vb2_dma_contig_memops   vmlinux EXPORT_SYMBOL_GPL
+-0x388f9128    xfrm_state_walk_done    vmlinux EXPORT_SYMBOL
+-0x6d6888a7    qdisc_create_dflt       vmlinux EXPORT_SYMBOL
+-0x194ccf46    bmap    vmlinux EXPORT_SYMBOL
+-0xe2fae716    kmemdup vmlinux EXPORT_SYMBOL
+-0x07ed48c3    __blocking_notifier_call_chain  vmlinux EXPORT_SYMBOL_GPL
+-0x074d7047    st_sensors_trigger_handler      vmlinux EXPORT_SYMBOL
+-0x33883929    clk_divider_ops vmlinux EXPORT_SYMBOL_GPL
+-0xe2b92059    v4l2_video_std_construct        vmlinux EXPORT_SYMBOL
+-0x06ea1593    usbnet_defer_kevent     vmlinux EXPORT_SYMBOL_GPL
+-0x6650ad3e    uart_add_one_port       vmlinux EXPORT_SYMBOL
+-0x5dda183c    snd_soc_dapm_disable_pin        vmlinux EXPORT_SYMBOL_GPL
+-0x7a188791    prandom_bytes   vmlinux EXPORT_SYMBOL
+-0xc25a61ec    drm_mode_set_crtcinfo   vmlinux EXPORT_SYMBOL
+-0xcb1beab5    drm_mode_vrefresh       vmlinux EXPORT_SYMBOL
+-0x4a94168c    tcp_register_congestion_control vmlinux EXPORT_SYMBOL_GPL
+-0x4f5836c8    tcp_release_cb  vmlinux EXPORT_SYMBOL
+-0x2f366d34    tcp_gro_complete        vmlinux EXPORT_SYMBOL
+-0x1eba8ee6    nf_conntrack_alloc      vmlinux EXPORT_SYMBOL_GPL
+-0x28a903c8    timerqueue_add  vmlinux EXPORT_SYMBOL_GPL
+-0x96cea50b    sync_filesystem vmlinux EXPORT_SYMBOL_GPL
+-0x68c0685a    media_entity_setup_link vmlinux EXPORT_SYMBOL_GPL
+-0x69b83c18    usb_get_phy_dev vmlinux EXPORT_SYMBOL_GPL
+-0x7e6bf1b2    dma_buf_fd      vmlinux EXPORT_SYMBOL_GPL
+-0x4d974b9c    register_sysrq_key      vmlinux EXPORT_SYMBOL
+-0xf79531f4    tcp_connect     vmlinux EXPORT_SYMBOL
+-0x3f45ea36    neigh_table_clear       vmlinux EXPORT_SYMBOL
+-0xf6de842c    clk_get_parent  vmlinux EXPORT_SYMBOL_GPL
+-0x4782eebf    clk_set_parent  vmlinux EXPORT_SYMBOL_GPL
+-0x45a20c5a    of_phy_find_device      vmlinux EXPORT_SYMBOL
+-0xcbbedfcb    led_trigger_event       vmlinux EXPORT_SYMBOL_GPL
+-0x69281b40    thermal_zone_bind_cooling_device        vmlinux EXPORT_SYMBOL_GPL
+-0xe122af95    xfrm_aalg_get_byname    vmlinux EXPORT_SYMBOL_GPL
+-0x74b1375e    xfrm_state_flush        vmlinux EXPORT_SYMBOL
+-0x94098ff8    snd_interval_list       vmlinux EXPORT_SYMBOL
+-0x64f01d42    fuse_put_request        vmlinux EXPORT_SYMBOL_GPL
+-0x1811ac2f    fat_flush_inodes        vmlinux EXPORT_SYMBOL_GPL
+-0x73198f14    mmc_align_data_size     vmlinux EXPORT_SYMBOL
+-0xa70df32d    drm_fb_helper_fill_var  vmlinux EXPORT_SYMBOL
+-0x209e95ea    xfrm_find_acq_byseq     vmlinux EXPORT_SYMBOL
+-0x4b9e2d58    xfrm_policy_unregister_afinfo   vmlinux EXPORT_SYMBOL
+-0x461a1d6a    __rtnl_af_register      vmlinux EXPORT_SYMBOL_GPL
+-0x09c55cec    schedule_timeout_interruptible  vmlinux EXPORT_SYMBOL
+-0xf512c668    iio_trigger_free        vmlinux EXPORT_SYMBOL
+-0xdac28b43    dw_mci_resume   vmlinux EXPORT_SYMBOL
+-0x361e2bcc    save_stack_trace        vmlinux EXPORT_SYMBOL_GPL
+-0x25e6af56    snd_compress_register   vmlinux EXPORT_SYMBOL_GPL
+-0x1ace138d    bitmap_allocate_region  vmlinux EXPORT_SYMBOL
+-0x250113b4    memory_read_from_buffer vmlinux EXPORT_SYMBOL
+-0x4ae22649    iommu_set_fault_handler vmlinux EXPORT_SYMBOL_GPL
+-0x3ca38e3a    rndis_signal_connect    vmlinux EXPORT_SYMBOL
+-0x9d01b017    dma_buf_attach  vmlinux EXPORT_SYMBOL_GPL
+-0x3930a5b6    dma_buf_detach  vmlinux EXPORT_SYMBOL_GPL
+-0x2aec4354    hci_alloc_dev   vmlinux EXPORT_SYMBOL
+-0xbb5d343d    xfrm_get_acqseq vmlinux EXPORT_SYMBOL
+-0x4082abfe    __scsi_iterate_devices  vmlinux EXPORT_SYMBOL
+-0x6b6d7375    drm_timestamp_precision vmlinux EXPORT_SYMBOL
+-0x7ffcb57f    ip6_tnl_get_cap vmlinux EXPORT_SYMBOL
+-0xccc812c3    dapm_clock_event        vmlinux EXPORT_SYMBOL_GPL
+-0x1a47bf65    blk_queue_bounce_limit  vmlinux EXPORT_SYMBOL
+-0xcc13c782    vb2_ioctl_streamon      vmlinux EXPORT_SYMBOL_GPL
+-0x8afddc98    spi_register_driver     vmlinux EXPORT_SYMBOL_GPL
+-0x17ae6853    platform_bus    vmlinux EXPORT_SYMBOL_GPL
+-0x72ac0290    exynos_drm_device_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0xf71ca112    skb_abort_seq_read      vmlinux EXPORT_SYMBOL
+-0x18bbe186    snd_soc_cnew    vmlinux EXPORT_SYMBOL_GPL
+-0x2b0ba2b0    scsi_sense_desc_find    vmlinux EXPORT_SYMBOL
+-0x8de13715    drm_format_vert_chroma_subsampling      vmlinux EXPORT_SYMBOL
+-0x06fe3b14    default_grn     vmlinux EXPORT_SYMBOL
+-0xee683d16    inet6_ioctl     vmlinux EXPORT_SYMBOL
+-0x47252a20    tcp_getsockopt  vmlinux EXPORT_SYMBOL
+-0x7027c3ad    tcp_setsockopt  vmlinux EXPORT_SYMBOL
+-0xb7f74966    rtnl_unicast    vmlinux EXPORT_SYMBOL
+-0x525971d4    snd_soc_update_bits_locked      vmlinux EXPORT_SYMBOL_GPL
+-0x6ef8fcd8    snd_pcm_format_linear   vmlinux EXPORT_SYMBOL
+-0x8f8f6e19    alloc_disk_node vmlinux EXPORT_SYMBOL
+-0x71c445f5    fuse_get_req    vmlinux EXPORT_SYMBOL_GPL
+-0xc41cff79    dequeue_signal  vmlinux EXPORT_SYMBOL_GPL
+-0x5d9d3491    v4l_match_dv_timings    vmlinux EXPORT_SYMBOL_GPL
+-0x829a8cac    drm_property_create_range       vmlinux EXPORT_SYMBOL
+-0xf3189246    __rtnl_af_unregister    vmlinux EXPORT_SYMBOL_GPL
+-0x0d7e8390    crypto_ablkcipher_type  vmlinux EXPORT_SYMBOL_GPL
+-0xaf8e1608    ip6t_register_table     vmlinux EXPORT_SYMBOL
+-0xb1a1e40e    crypto_tfm_in_queue     vmlinux EXPORT_SYMBOL_GPL
+-0xc73f3f9a    fget_raw        vmlinux EXPORT_SYMBOL
+-0x71008581    atomic_notifier_call_chain      vmlinux EXPORT_SYMBOL_GPL
+-0x12bf1d5c    usbnet_device_suggests_idle     vmlinux EXPORT_SYMBOL
+-0x79b993ef    cfg80211_send_unprot_deauth     vmlinux EXPORT_SYMBOL
+-0xdacc53b2    spi_add_device  vmlinux EXPORT_SYMBOL_GPL
+-0xf5a5c913    backlight_device_unregister     vmlinux EXPORT_SYMBOL
+-0xadce320f    pinctrl_add_gpio_ranges vmlinux EXPORT_SYMBOL_GPL
+-0x0f8342e1    phy_pm_runtime_forbid   vmlinux EXPORT_SYMBOL_GPL
+-0xc0763484    rfkill_blocked  vmlinux EXPORT_SYMBOL
+-0xb0bad0e8    ip6_push_pending_frames vmlinux EXPORT_SYMBOL_GPL
+-0xfc02b7ad    sysctl_tcp_wmem vmlinux EXPORT_SYMBOL
+-0xac782342    nf_unregister_hook      vmlinux EXPORT_SYMBOL
+-0xa08421e0    dev_change_net_namespace        vmlinux EXPORT_SYMBOL_GPL
+-0x47c6d038    blk_queue_flush_queueable       vmlinux EXPORT_SYMBOL_GPL
+-0x2db8f309    blk_queue_rq_timeout    vmlinux EXPORT_SYMBOL_GPL
+-0x6fb277a1    flush_kernel_dcache_page        vmlinux EXPORT_SYMBOL
+-0x1d633e6a    tcp_twsk_destructor     vmlinux EXPORT_SYMBOL_GPL
+-0x7611866b    scm_detach_fds  vmlinux EXPORT_SYMBOL
+-0xd3b02cea    put_pid vmlinux EXPORT_SYMBOL_GPL
+-0xed20e404    iio_dealloc_pollfunc    vmlinux EXPORT_SYMBOL_GPL
+-0xba706bd7    samsung_pwm_lock        vmlinux EXPORT_SYMBOL
+-0x158b7724    media_entity_create_link        vmlinux EXPORT_SYMBOL_GPL
+-0x1172ce54    rtc_ktime_to_tm vmlinux EXPORT_SYMBOL_GPL
+-0xa286a234    snd_pcm_format_name     vmlinux EXPORT_SYMBOL_GPL
+-0xc7e39bca    ring_buffer_dropped_events_cpu  vmlinux EXPORT_SYMBOL_GPL
+-0xaa957320    posix_clock_register    vmlinux EXPORT_SYMBOL_GPL
+-0xad46dec2    of_count_phandle_with_args      vmlinux EXPORT_SYMBOL
+-0x7120d717    regmap_bulk_read        vmlinux EXPORT_SYMBOL_GPL
+-0xca56dea4    driver_find_device      vmlinux EXPORT_SYMBOL_GPL
+-0x9c9d19e7    blk_get_request vmlinux EXPORT_SYMBOL
+-0x2c790eff    usbnet_read_cmd_nopm    vmlinux EXPORT_SYMBOL_GPL
+-0xbb99125c    get_default_font        vmlinux EXPORT_SYMBOL
+-0x6e5cf115    cfg80211_inform_bss     vmlinux EXPORT_SYMBOL
+-0xce7a55c1    xfrm_ealg_get_byid      vmlinux EXPORT_SYMBOL_GPL
+-0x0cc1e40f    crypto_it_tab   vmlinux EXPORT_SYMBOL_GPL
+-0x3dc916b6    crypto_fl_tab   vmlinux EXPORT_SYMBOL_GPL
+-0x40d46b21    crypto_ft_tab   vmlinux EXPORT_SYMBOL_GPL
+-0x71dc9998    crypto_il_tab   vmlinux EXPORT_SYMBOL_GPL
+-0x837d0f0a    down_timeout    vmlinux EXPORT_SYMBOL
+-0x2cd7dd71    __cpufreq_driver_getavg vmlinux EXPORT_SYMBOL_GPL
+-0xee6b71c4    syscon_regmap_lookup_by_compatible      vmlinux EXPORT_SYMBOL_GPL
+-0xae77b400    device_pm_wait_for_dev  vmlinux EXPORT_SYMBOL_GPL
+-0x1d5a2494    nfnetlink_has_listeners vmlinux EXPORT_SYMBOL_GPL
+-0x3bd1b1f6    msecs_to_jiffies        vmlinux EXPORT_SYMBOL
+-0xfb09f255    cpufreq_frequency_table_target  vmlinux EXPORT_SYMBOL_GPL
+-0xb52e203b    snd_pcm_suspend_all     vmlinux EXPORT_SYMBOL
+-0xc1ec3550    blkdev_fsync    vmlinux EXPORT_SYMBOL
+-0x0ebe6f54    lookup_one_len  vmlinux EXPORT_SYMBOL
+-0x151404f6    misc_deregister vmlinux EXPORT_SYMBOL
+-0xb2856c71    inet6_bind      vmlinux EXPORT_SYMBOL
+-0xf68285c0    register_inetaddr_notifier      vmlinux EXPORT_SYMBOL
+-0x7afc9d8a    unregister_sound_mixer  vmlinux EXPORT_SYMBOL
+-0xd5d80496    atomic_dec_and_mutex_lock       vmlinux EXPORT_SYMBOL
+-0x4351577a    fb_parse_edid   vmlinux EXPORT_SYMBOL
+-0x68beb163    nf_ct_l3proto_pernet_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x7751fba7    nf_ct_l4proto_pernet_unregister vmlinux EXPORT_SYMBOL_GPL
+-0x5cbe0b31    snd_pcm_lib_write       vmlinux EXPORT_SYMBOL
+-0x6cecc98a    devres_get      vmlinux EXPORT_SYMBOL_GPL
+-0x20925954    devres_add      vmlinux EXPORT_SYMBOL_GPL
+-0x99a9dfa6    ieee80211_data_to_8023  vmlinux EXPORT_SYMBOL
+-0x21036b2c    bt_accept_enqueue       vmlinux EXPORT_SYMBOL
+-0x0cd5a88b    sync_inodes_sb  vmlinux EXPORT_SYMBOL
+-0x7485e15e    unregister_chrdev_region        vmlinux EXPORT_SYMBOL
+-0x7e8ad403    generic_writepages      vmlinux EXPORT_SYMBOL
+-0x07cf3227    clk_fixed_rate_ops      vmlinux EXPORT_SYMBOL_GPL
+-0xf5463be8    led_trigger_blink_oneshot       vmlinux EXPORT_SYMBOL_GPL
+-0xdbf18207    v4l2_device_register_subdev     vmlinux EXPORT_SYMBOL_GPL
+-0x131a5ed7    regmap_del_irq_chip     vmlinux EXPORT_SYMBOL_GPL
+-0xb09c8d37    regmap_add_irq_chip     vmlinux EXPORT_SYMBOL_GPL
+-0x26f0453a    blk_set_default_limits  vmlinux EXPORT_SYMBOL
+-0xf21f8a44    blk_init_allocated_queue        vmlinux EXPORT_SYMBOL
+-0x60df1e3b    posix_acl_equiv_mode    vmlinux EXPORT_SYMBOL
+-0xc131c5dd    usb_add_phy     vmlinux EXPORT_SYMBOL_GPL
+-0x211c5b26    cdc_ncm_bind_common     vmlinux EXPORT_SYMBOL_GPL
+-0x61f6939e    drm_i2c_encoder_detect  vmlinux EXPORT_SYMBOL
+-0xd9f310b2    gpiochip_is_requested   vmlinux EXPORT_SYMBOL_GPL
+-0xb9639d32    rtnl_register   vmlinux EXPORT_SYMBOL_GPL
+-0xf2254dc3    sock_from_file  vmlinux EXPORT_SYMBOL
+-0x0f5455e2    snd_soc_info_enum_double        vmlinux EXPORT_SYMBOL_GPL
+-0xdd89a6bf    lookup_bdev     vmlinux EXPORT_SYMBOL
+-0x55704318    clockevents_config_and_register vmlinux EXPORT_SYMBOL_GPL
+-0x2fd8cba9    freeze_wake     vmlinux EXPORT_SYMBOL_GPL
+-0x071b7eea    irq_stat        vmlinux EXPORT_SYMBOL
+-0x7a8ca627    xfrm_count_pfkey_enc_supported  vmlinux EXPORT_SYMBOL_GPL
+-0x1ff2a733    raw_seq_stop    vmlinux EXPORT_SYMBOL_GPL
+-0x85b825e7    gnet_stats_copy_basic   vmlinux EXPORT_SYMBOL
+-0x0cfefe1e    percpu_counter_destroy  vmlinux EXPORT_SYMBOL
+-0x02ea69e2    vm_map_ram      vmlinux EXPORT_SYMBOL
+-0x36eb3583    filemap_fdatawrite_range        vmlinux EXPORT_SYMBOL
+-0xb977cf42    inet_sendmsg    vmlinux EXPORT_SYMBOL
+-0xddbcead7    ip_cmsg_recv    vmlinux EXPORT_SYMBOL
+-0xb9a64b20    elevator_alloc  vmlinux EXPORT_SYMBOL
+-0xbcaf3971    crypto_alg_sem  vmlinux EXPORT_SYMBOL_GPL
+-0xe71dab2c    bio_sector_offset       vmlinux EXPORT_SYMBOL
+-0x2c44797e    hidinput_report_event   vmlinux EXPORT_SYMBOL_GPL
+-0x5d9e8570    drm_display_mode_from_videomode vmlinux EXPORT_SYMBOL_GPL
+-0x2b8e67cd    fuse_get_req_for_background     vmlinux EXPORT_SYMBOL_GPL
+-0x2b1c6816    extcon_dev_register     vmlinux EXPORT_SYMBOL_GPL
+-0xdef26358    dw_mci_probe    vmlinux EXPORT_SYMBOL
+-0xcbde0d9d    inverse_translate       vmlinux EXPORT_SYMBOL_GPL
+-0x056ee730    ipv6_hash_secret        vmlinux EXPORT_SYMBOL
+-0xfe029963    unregister_inetaddr_notifier    vmlinux EXPORT_SYMBOL
+-0x650a6767    prandom_u32_state       vmlinux EXPORT_SYMBOL
+-0x4148a5ff    get_kernel_pages        vmlinux EXPORT_SYMBOL_GPL
+-0x24d3448d    perf_event_enable       vmlinux EXPORT_SYMBOL_GPL
+-0x1c5a04e0    irq_domain_generate_simple      vmlinux EXPORT_SYMBOL_GPL
+-0xb7b4232a    unregister_exec_domain  vmlinux EXPORT_SYMBOL
+-0xd6f86c04    amba_release_regions    vmlinux EXPORT_SYMBOL
+-0x89d5538d    fb_pad_aligned_buffer   vmlinux EXPORT_SYMBOL
+-0x93237692    nobh_write_begin        vmlinux EXPORT_SYMBOL
+-0x920eb90c    interruptible_sleep_on_timeout  vmlinux EXPORT_SYMBOL
+-0x3a36ce8c    od_register_powersave_bias_handler      vmlinux EXPORT_SYMBOL_GPL
+-0x946b8b6c    netlink_ack     vmlinux EXPORT_SYMBOL
+-0x1000be5b    sock_no_bind    vmlinux EXPORT_SYMBOL
+-0x1e5479ed    sock_get_timestamp      vmlinux EXPORT_SYMBOL
+-0x4211c3c1    zlib_inflateInit2       vmlinux EXPORT_SYMBOL
+-0x2486141e    bio_alloc_pages vmlinux EXPORT_SYMBOL
+-0x62fd6207    param_set_charp vmlinux EXPORT_SYMBOL
+-0x0862d814    v4l2_event_unsubscribe_all      vmlinux EXPORT_SYMBOL_GPL
+-0x2f10e618    v4l2_event_queue_fh     vmlinux EXPORT_SYMBOL_GPL
+-0x6bdcfd99    qdisc_class_hash_remove vmlinux EXPORT_SYMBOL
+-0xf070e888    __put_net       vmlinux EXPORT_SYMBOL_GPL
+-0x8df3789f    snd_oss_info_register   vmlinux EXPORT_SYMBOL
+-0x68c73797    fuse_request_alloc      vmlinux EXPORT_SYMBOL_GPL
+-0x2342f1ae    v4l2_prio_open  vmlinux EXPORT_SYMBOL
+-0x4ddaa6ea    dmam_alloc_noncoherent  vmlinux EXPORT_SYMBOL
+-0x7dfdf9a1    transport_destroy_device        vmlinux EXPORT_SYMBOL_GPL
+-0x8c510862    drm_find_cea_extension  vmlinux EXPORT_SYMBOL
+-0x7c0267ee    serial8250_tx_chars     vmlinux EXPORT_SYMBOL_GPL
+-0x6879e81d    display_entity_put      vmlinux EXPORT_SYMBOL_GPL
+-0xf19a455d    lro_flush_pkt   vmlinux EXPORT_SYMBOL
+-0xbf8ba54a    vprintk vmlinux EXPORT_SYMBOL
+-0x7bd1de14    thermal_cdev_update     vmlinux EXPORT_SYMBOL
+-0x2631d719    tty_unregister_device   vmlinux EXPORT_SYMBOL
+-0xa7e7f050    __udp4_lib_lookup       vmlinux EXPORT_SYMBOL_GPL
+-0x2e2ce9e0    sysctl_tcp_syncookies   vmlinux EXPORT_SYMBOL
+-0xd5a8fd58    tcp_poll        vmlinux EXPORT_SYMBOL
+-0x3f74afb9    nf_ct_l3proto_register  vmlinux EXPORT_SYMBOL_GPL
+-0xb4998fd0    nf_ct_l4proto_register  vmlinux EXPORT_SYMBOL_GPL
+-0x2482e688    vsprintf        vmlinux EXPORT_SYMBOL
+-0x59e4b703    generic_splice_sendpage vmlinux EXPORT_SYMBOL
+-0x1795a16b    __genl_register_family_with_ops vmlinux EXPORT_SYMBOL
+-0xcb469d2b    ddebug_add_module       vmlinux EXPORT_SYMBOL_GPL
+-0xa2d83f8b    grab_cache_page_write_begin     vmlinux EXPORT_SYMBOL
+-0x8c930a68    rt_mutex_lock_interruptible     vmlinux EXPORT_SYMBOL_GPL
+-0xcc0871f2    attribute_container_find_class_device   vmlinux EXPORT_SYMBOL_GPL
+-0x13b52797    pwm_request_from_chip   vmlinux EXPORT_SYMBOL_GPL
+-0x28118cb6    __get_user_1    vmlinux EXPORT_SYMBOL
+-0xbb72d4fe    __put_user_1    vmlinux EXPORT_SYMBOL
+-0x0cae232b    utf16s_to_utf8s vmlinux EXPORT_SYMBOL
+-0x617a218d    __cond_resched_lock     vmlinux EXPORT_SYMBOL
+-0x44224883    __put_task_struct       vmlinux EXPORT_SYMBOL_GPL
+-0xbc65845b    class_create_file       vmlinux EXPORT_SYMBOL_GPL
+-0xe459c49b    unregister_pernet_subsys        vmlinux EXPORT_SYMBOL_GPL
+-0xd882a162    wait_on_sync_kiocb      vmlinux EXPORT_SYMBOL
+-0x28acb0e5    simple_write_begin      vmlinux EXPORT_SYMBOL
+-0x5c1cb07e    redirty_page_for_writepage      vmlinux EXPORT_SYMBOL
+-0x6070a6fb    bdi_set_max_ratio       vmlinux EXPORT_SYMBOL
+-0xfee43a69    drm_dp_get_adjust_request_voltage       vmlinux EXPORT_SYMBOL
+-0x8ffe7e89    nf_conntrack_htable_size        vmlinux EXPORT_SYMBOL_GPL
+-0x79c527b0    netdev_emerg    vmlinux EXPORT_SYMBOL
+-0x0bc7142a    sk_stream_kill_queues   vmlinux EXPORT_SYMBOL
+-0xeb37101c    audit_log_end   vmlinux EXPORT_SYMBOL
+-0xc3577d50    dev_set_name    vmlinux EXPORT_SYMBOL_GPL
+-0x6d40a921    need_ipv4_conntrack     vmlinux EXPORT_SYMBOL_GPL
+-0x6b98f5bd    __sk_dst_check  vmlinux EXPORT_SYMBOL
+-0x003ed69a    __kfifo_dma_in_prepare  vmlinux EXPORT_SYMBOL
+-0xd27b25dd    blk_check_plugged       vmlinux EXPORT_SYMBOL
+-0x9e093f78    elv_register_queue      vmlinux EXPORT_SYMBOL
+-0x716265c7    debugfs_initialized     vmlinux EXPORT_SYMBOL_GPL
+-0x8e19dd86    of_platform_populate    vmlinux EXPORT_SYMBOL_GPL
+-0x2a4ee199    v4l2_m2m_job_finish     vmlinux EXPORT_SYMBOL
+-0x8c62225c    usb_queue_reset_device  vmlinux EXPORT_SYMBOL_GPL
+-0x1e837252    drm_mm_scan_add_block   vmlinux EXPORT_SYMBOL
+-0x6c9424d9    snd_pcm_lib_preallocate_pages   vmlinux EXPORT_SYMBOL
+-0x4c759827    byte_rev_table  vmlinux EXPORT_SYMBOL_GPL
+-0xdf7090e0    __elv_add_request       vmlinux EXPORT_SYMBOL
+-0x911010cb    skcipher_geniv_init     vmlinux EXPORT_SYMBOL_GPL
+-0x9bd700dd    set_bh_page     vmlinux EXPORT_SYMBOL
+-0x13a2a2e3    free_user_ns    vmlinux EXPORT_SYMBOL
+-0x4fe8770d    usb_interrupt_msg       vmlinux EXPORT_SYMBOL_GPL
+-0x0d7dd3fc    pm_generic_runtime_resume       vmlinux EXPORT_SYMBOL_GPL
+-0x3df0b6c5    bus_unregister  vmlinux EXPORT_SYMBOL_GPL
+-0x131f636c    nf_nat_l4proto_in_range vmlinux EXPORT_SYMBOL_GPL
+-0xe6643a60    snd_soc_dpcm_be_can_update      vmlinux EXPORT_SYMBOL_GPL
+-0x059c8bf5    snd_soc_dpcm_fe_can_update      vmlinux EXPORT_SYMBOL_GPL
+-0xe914e41e    strcpy  vmlinux EXPORT_SYMBOL
+-0x27235c89    crypto_destroy_tfm      vmlinux EXPORT_SYMBOL_GPL
+-0xe44b1603    sysfs_remove_link_from_group    vmlinux EXPORT_SYMBOL_GPL
+-0x1dff6af1    filemap_fault   vmlinux EXPORT_SYMBOL
+-0xb1d9aabd    lg_local_unlock_cpu     vmlinux EXPORT_SYMBOL
+-0x59d9c8d7    jack_get_data   vmlinux EXPORT_SYMBOL_GPL
+-0x7a91726b    clkdev_alloc    vmlinux EXPORT_SYMBOL
+-0x6138cad8    nfc_tm_deactivated      vmlinux EXPORT_SYMBOL
+-0xe50e65bf    blocking_notifier_chain_register        vmlinux EXPORT_SYMBOL_GPL
+-0x9acf72e4    rndis_set_param_medium  vmlinux EXPORT_SYMBOL
+-0x677428bf    sdev_enable_disk_events vmlinux EXPORT_SYMBOL
+-0x45ef1157    tty_pair_get_tty        vmlinux EXPORT_SYMBOL
+-0x4338e523    tty_pair_get_pty        vmlinux EXPORT_SYMBOL
+-0x51c0d211    fb_get_buffer_offset    vmlinux EXPORT_SYMBOL
+-0xe7f26347    skb_unlink      vmlinux EXPORT_SYMBOL
+-0xc3f69ac2    crypto_register_template        vmlinux EXPORT_SYMBOL_GPL
+-0x00fe8031    fuse_abort_conn vmlinux EXPORT_SYMBOL_GPL
+-0x3dc45692    vm_iomap_memory vmlinux EXPORT_SYMBOL
+-0xc41f0516    node_states     vmlinux EXPORT_SYMBOL
+-0x6a5fb566    rcu_sched_force_quiescent_state vmlinux EXPORT_SYMBOL_GPL
+-0xc89e91fb    irq_setup_alt_chip      vmlinux EXPORT_SYMBOL_GPL
+-0xe8a39d68    vb2_ioctl_streamoff     vmlinux EXPORT_SYMBOL_GPL
+-0xb2e5ae4a    snd_lookup_minor_data   vmlinux EXPORT_SYMBOL
+-0xaafd1f6c    iio_triggered_buffer_setup      vmlinux EXPORT_SYMBOL
+-0x4b17b645    of_property_read_u16_array      vmlinux EXPORT_SYMBOL_GPL
+-0xdac11bae    of_property_read_u32_array      vmlinux EXPORT_SYMBOL_GPL
+-0x5641485b    tty_termios_encode_baud_rate    vmlinux EXPORT_SYMBOL_GPL
+-0x85d549dc    s3c_gpio_getcfg vmlinux EXPORT_SYMBOL
+-0x1189692c    inet_csk_delete_keepalive_timer vmlinux EXPORT_SYMBOL
+-0xbec25473    of_parse_phandle        vmlinux EXPORT_SYMBOL
+-0x53f0b470    dev_pm_qos_add_ancestor_request vmlinux EXPORT_SYMBOL_GPL
+-0x0ddc826c    drm_fb_helper_set_par   vmlinux EXPORT_SYMBOL
+-0x64bb0960    cfg80211_wext_giwmode   vmlinux EXPORT_SYMBOL_GPL
+-0xd4cc3fbd    cfg80211_wext_giwname   vmlinux EXPORT_SYMBOL_GPL
+-0x8697617d    cfg80211_wext_siwmode   vmlinux EXPORT_SYMBOL_GPL
+-0xe3643cca    cfg80211_send_auth_timeout      vmlinux EXPORT_SYMBOL
+-0x377db989    xfrm_state_register_afinfo      vmlinux EXPORT_SYMBOL
+-0x2cdca56b    usb_register_device_driver      vmlinux EXPORT_SYMBOL_GPL
+-0x7f9066b4    subsys_interface_unregister     vmlinux EXPORT_SYMBOL_GPL
+-0xfbc8e9a2    regulatory_hint vmlinux EXPORT_SYMBOL
+-0xbdf0ff3a    wiphy_rfkill_start_polling      vmlinux EXPORT_SYMBOL
+-0x74631c0e    inet_ioctl      vmlinux EXPORT_SYMBOL
+-0x5cbe31bd    snd_soc_dapm_mixer_update_power vmlinux EXPORT_SYMBOL_GPL
+-0x5a3c2afd    kobject_get_path        vmlinux EXPORT_SYMBOL_GPL
+-0xd8ce7e67    clocksource_register    vmlinux EXPORT_SYMBOL
+-0x802c194a    of_device_register      vmlinux EXPORT_SYMBOL
+-0x0c8c9e99    scsi_show_extd_sense    vmlinux EXPORT_SYMBOL
+-0x2155f85c    bt_sock_link    vmlinux EXPORT_SYMBOL
+-0x0ccfae80    xt_register_target      vmlinux EXPORT_SYMBOL
+-0x6f20960a    full_name_hash  vmlinux EXPORT_SYMBOL
+-0xcded9074    phy_drivers_register    vmlinux EXPORT_SYMBOL
+-0xae5ba460    ping_prot       vmlinux EXPORT_SYMBOL
+-0x814e7730    nf_ct_destroy   vmlinux EXPORT_SYMBOL
+-0xe8279caa    nf_unregister_hooks     vmlinux EXPORT_SYMBOL
+-0x8810ad5e    crypto_xor      vmlinux EXPORT_SYMBOL_GPL
+-0x45bf1ff3    crypto_inc      vmlinux EXPORT_SYMBOL_GPL
+-0x5ac71347    wait_for_stable_page    vmlinux EXPORT_SYMBOL_GPL
+-0xe07ca631    cpu_bit_bitmap  vmlinux EXPORT_SYMBOL_GPL
+-0x9c5bf378    pm_generic_freeze       vmlinux EXPORT_SYMBOL_GPL
+-0x50bd1b27    device_create_vargs     vmlinux EXPORT_SYMBOL_GPL
+-0x30775773    drm_bl_unregister       vmlinux EXPORT_SYMBOL_GPL
+-0xf4f3abb6    tty_port_hangup vmlinux EXPORT_SYMBOL
+-0xca0bdf70    framebuffer_release     vmlinux EXPORT_SYMBOL
+-0x86743fc9    touch_buffer    vmlinux EXPORT_SYMBOL
+-0x5671b6e0    iio_triggered_buffer_predisable vmlinux EXPORT_SYMBOL
+-0x2eb9cd44    brcmu_pktq_init drivers/net/wireless/brcm80211/brcmutil/brcmutil        EXPORT_SYMBOL
+-0x77c7a73e    wiphy_apply_custom_regulatory   vmlinux EXPORT_SYMBOL
+-0xd796d321    fat_getattr     vmlinux EXPORT_SYMBOL_GPL
+-0x41e95f70    fat_setattr     vmlinux EXPORT_SYMBOL_GPL
+-0x2750ffee    generic_read_dir        vmlinux EXPORT_SYMBOL
+-0x00c3b7ed    dentry_unhash   vmlinux EXPORT_SYMBOL
+-0xe007de41    kallsyms_lookup_name    vmlinux EXPORT_SYMBOL_GPL
+-0x43f23311    dm_table_get_md vmlinux EXPORT_SYMBOL
+-0x9db747a3    usb_hcd_poll_rh_status  vmlinux EXPORT_SYMBOL_GPL
+-0xfd1cd45b    dev_pm_qos_hide_flags   vmlinux EXPORT_SYMBOL_GPL
+-0xe15b1685    device_find_child       vmlinux EXPORT_SYMBOL_GPL
+-0x1a022e5e    truncate_pagecache      vmlinux EXPORT_SYMBOL
+-0x26b71fb4    ring_buffer_time_stamp  vmlinux EXPORT_SYMBOL_GPL
+-0x4e6a500f    phy_pm_runtime_get      vmlinux EXPORT_SYMBOL_GPL
+-0x056bb269    xfrm_ealg_get_byidx     vmlinux EXPORT_SYMBOL_GPL
+-0x094585f4    sock_no_shutdown        vmlinux EXPORT_SYMBOL
+-0x0a5ea478    __generic_block_fiemap  vmlinux EXPORT_SYMBOL
+-0xb1acbcce    rcu_barrier_sched       vmlinux EXPORT_SYMBOL_GPL
+-0x3924dd56    try_wait_for_completion vmlinux EXPORT_SYMBOL
+-0x8f7014a1    param_set_ulong vmlinux EXPORT_SYMBOL
+-0xee2d0fc7    _local_bh_enable        vmlinux EXPORT_SYMBOL
+-0x34e8e0a0    of_device_unregister    vmlinux EXPORT_SYMBOL
+-0xbed3ee5e    watchdog_register_device        vmlinux EXPORT_SYMBOL_GPL
+-0x16244fe5    v4l2_prio_check vmlinux EXPORT_SYMBOL
+-0x324a8332    vc_resize       vmlinux EXPORT_SYMBOL
+-0xb410d84f    phy_put vmlinux EXPORT_SYMBOL_GPL
+-0xa41b1e49    phy_pm_runtime_put_sync vmlinux EXPORT_SYMBOL_GPL
+-0xb3d5242c    nf_ct_expect_alloc      vmlinux EXPORT_SYMBOL_GPL
+-0xbdfe32cf    sysfs_unmerge_group     vmlinux EXPORT_SYMBOL_GPL
+-0xdb04cacc    tracepoint_probe_unregister_noupdate    vmlinux EXPORT_SYMBOL_GPL
+-0x481ce6ce    cpu_active_mask vmlinux EXPORT_SYMBOL
+-0x78f47a5c    drm_kms_helper_poll_init        vmlinux EXPORT_SYMBOL
+-0x62827bec    security_secctx_to_secid        vmlinux EXPORT_SYMBOL
+-0xcb97ad8c    bus_find_device_by_name vmlinux EXPORT_SYMBOL_GPL
+-0x427dce2d    drm_put_minor   vmlinux EXPORT_SYMBOL
+-0xf7b743b5    drm_calc_timestamping_constants vmlinux EXPORT_SYMBOL
+-0x62746f06    video_source_unregister vmlinux EXPORT_SYMBOL_GPL
+-0xacde6340    inet_peer_xrlim_allow   vmlinux EXPORT_SYMBOL
+-0xd4b0b600    nf_ct_attach    vmlinux EXPORT_SYMBOL
+-0x3e1314f1    snd_timer_global_free   vmlinux EXPORT_SYMBOL
+-0xd37725bb    register_user_hw_breakpoint     vmlinux EXPORT_SYMBOL_GPL
+-0x4f741917    devm_phy_put    vmlinux EXPORT_SYMBOL_GPL
+-0xe5ed5467    xfrm_policy_walk_init   vmlinux EXPORT_SYMBOL
+-0xfd6eefb8    nf_nat_decode_session_hook      vmlinux EXPORT_SYMBOL
+-0x82627707    snd_pcm_lib_writev      vmlinux EXPORT_SYMBOL
+-0x28b2dd21    textsearch_register     vmlinux EXPORT_SYMBOL
+-0x74baf17a    tracing_is_on   vmlinux EXPORT_SYMBOL_GPL
+-0x381a798a    setup_max_cpus  vmlinux EXPORT_SYMBOL
+-0xf442e8f8    commit_creds    vmlinux EXPORT_SYMBOL
+-0xab598227    driver_attach   vmlinux EXPORT_SYMBOL_GPL
+-0xa1d5de65    drm_mode_connector_list_update  vmlinux EXPORT_SYMBOL
+-0xf3f5690b    __nf_ct_expect_find     vmlinux EXPORT_SYMBOL_GPL
+-0xad0413d4    match_hex       vmlinux EXPORT_SYMBOL
+-0xbfdbee53    usbnet_generic_cdc_bind vmlinux EXPORT_SYMBOL_GPL
+-0x329edb99    platform_device_register        vmlinux EXPORT_SYMBOL_GPL
+-0x80d68d3e    fb_register_client      vmlinux EXPORT_SYMBOL
+-0x3638b44e    __inet_lookup_listener  vmlinux EXPORT_SYMBOL_GPL
+-0x89636597    nf_unregister_sockopt   vmlinux EXPORT_SYMBOL
+-0xadac214f    __skb_get_rxhash        vmlinux EXPORT_SYMBOL
+-0x10ae54ba    skb_realloc_headroom    vmlinux EXPORT_SYMBOL
+-0xdaa5b6fe    generic_pipe_buf_get    vmlinux EXPORT_SYMBOL
+-0x461fff7e    generic_pipe_buf_map    vmlinux EXPORT_SYMBOL
+-0x36f9cd94    rcu_is_cpu_idle vmlinux EXPORT_SYMBOL
+-0x4102e3db    media_entity_find_link  vmlinux EXPORT_SYMBOL_GPL
+-0xcd0e7389    platform_device_unregister      vmlinux EXPORT_SYMBOL_GPL
+-0xf86dc7d7    serial8250_set_isa_configurator vmlinux EXPORT_SYMBOL
+-0xbe1c5d4d    ipv6_find_hdr   vmlinux EXPORT_SYMBOL
+-0xc6ed2b40    jbd2_journal_dirty_metadata     vmlinux EXPORT_SYMBOL
+-0x77df0847    __set_personality       vmlinux EXPORT_SYMBOL
+-0x92c6523d    tty_port_close_end      vmlinux EXPORT_SYMBOL
+-0x78843287    blkcipher_walk_done     vmlinux EXPORT_SYMBOL_GPL
+-0x96f90809    page_readlink   vmlinux EXPORT_SYMBOL
+-0xc7c4f4ed    account_page_writeback  vmlinux EXPORT_SYMBOL
+-0xa1edf7f3    drm_core_ioremap_wc     vmlinux EXPORT_SYMBOL
+-0x08ad3fc2    register_con_driver     vmlinux EXPORT_SYMBOL
+-0x676bbc0f    _set_bit        vmlinux EXPORT_SYMBOL
+-0xd46c9ca5    nf_unregister_afinfo    vmlinux EXPORT_SYMBOL_GPL
+-0xf5eb86ea    blk_verify_command      vmlinux EXPORT_SYMBOL
+-0xc499ae1e    kstrdup vmlinux EXPORT_SYMBOL
+-0x2aa1ad41    _raw_write_lock_irq     vmlinux EXPORT_SYMBOL
+-0xb5b7345d    freezing_slow_path      vmlinux EXPORT_SYMBOL
+-0xe505e34f    mmc_start_bkops vmlinux EXPORT_SYMBOL
+-0x1dd571e6    fb_copy_cmap    vmlinux EXPORT_SYMBOL
+-0x0d4d7a32    _atomic_dec_and_lock    vmlinux EXPORT_SYMBOL
+-0x11c9185c    of_iomap        vmlinux EXPORT_SYMBOL
+-0xf918f7de    xfrm_register_km        vmlinux EXPORT_SYMBOL
+-0xde4bc28c    ip_mc_dec_group vmlinux EXPORT_SYMBOL
+-0x03f12ac0    snd_soc_dapm_mux_update_power   vmlinux EXPORT_SYMBOL_GPL
+-0x733c3b54    kasprintf       vmlinux EXPORT_SYMBOL
+-0x8aaa8b57    simple_rename   vmlinux EXPORT_SYMBOL
+-0x512579ee    vfs_setxattr    vmlinux EXPORT_SYMBOL_GPL
+-0x3d8f75d6    vfs_getxattr    vmlinux EXPORT_SYMBOL_GPL
+-0xcb7131fb    fb_get_options  vmlinux EXPORT_SYMBOL
+-0xd49c7d00    phy_init        vmlinux EXPORT_SYMBOL_GPL
+-0xf8c54a02    sock_init_data  vmlinux EXPORT_SYMBOL
+-0x1209a558    snd_ctl_free_one        vmlinux EXPORT_SYMBOL
+-0xe02eb6d0    ring_buffer_commit_overrun_cpu  vmlinux EXPORT_SYMBOL_GPL
+-0x3a536bd7    ring_buffer_read_finish vmlinux EXPORT_SYMBOL_GPL
+-0x9c0bd51f    _raw_spin_lock  vmlinux EXPORT_SYMBOL
+-0xcf7c760d    mmc_send_ext_csd        vmlinux EXPORT_SYMBOL_GPL
+-0x0f7cb7fa    tty_set_termios vmlinux EXPORT_SYMBOL_GPL
+-0x86ffe7d1    ip_queue_xmit   vmlinux EXPORT_SYMBOL
+-0xc30b3a36    scatterwalk_map vmlinux EXPORT_SYMBOL_GPL
+-0x23532c4d    ftrace_print_flags_seq  vmlinux EXPORT_SYMBOL
+-0x3500818d    v4l2_fh_open    vmlinux EXPORT_SYMBOL_GPL
+-0xadc7d94a    class_dev_iter_init     vmlinux EXPORT_SYMBOL_GPL
+-0xb95ec685    km_query        vmlinux EXPORT_SYMBOL
+-0xf569d921    inet_release    vmlinux EXPORT_SYMBOL
+-0x4251ff78    nf_ct_helper_expectfn_register  vmlinux EXPORT_SYMBOL_GPL
+-0xa3f35bf5    rwsem_is_locked vmlinux EXPORT_SYMBOL
+-0x518c4113    blk_queue_start_tag     vmlinux EXPORT_SYMBOL
+-0x299f45b9    jbd2_journal_force_commit       vmlinux EXPORT_SYMBOL
+-0x373db350    kstrtoint       vmlinux EXPORT_SYMBOL
+-0xfffad96c    call_srcu       vmlinux EXPORT_SYMBOL_GPL
+-0x4806c9d5    drm_connector_init      vmlinux EXPORT_SYMBOL
+-0x9fce80db    fb_notifier_call_chain  vmlinux EXPORT_SYMBOL_GPL
+-0x856629e7    __tracepoint_rpm_return_int     vmlinux EXPORT_SYMBOL_GPL
+-0x8f6cee77    __round_jiffies_relative        vmlinux EXPORT_SYMBOL_GPL
+-0xb992cdc2    cpufreq_get_policy      vmlinux EXPORT_SYMBOL
+-0x9a7784ef    v4l2_device_put vmlinux EXPORT_SYMBOL_GPL
+-0xab2d53fe    wm8994_reg_write        vmlinux EXPORT_SYMBOL_GPL
+-0xa7c124ba    inet_frag_maybe_warn_overflow   vmlinux EXPORT_SYMBOL
+-0x81cbdbae    inet_twsk_alloc vmlinux EXPORT_SYMBOL_GPL
+-0x037a0cba    kfree   vmlinux EXPORT_SYMBOL
+-0xfb0c30cd    __rt_mutex_init vmlinux EXPORT_SYMBOL_GPL
+-0x578a9e0d    kill_pid_info_as_cred   vmlinux EXPORT_SYMBOL_GPL
+-0xa8ca80b5    __serio_register_driver vmlinux EXPORT_SYMBOL
+-0x182a39a6    max8997_bulk_read       vmlinux EXPORT_SYMBOL_GPL
+-0x2fd9648c    pm_genpd_add_callbacks  vmlinux EXPORT_SYMBOL_GPL
+-0xc5c2a452    tty_put_char    vmlinux EXPORT_SYMBOL_GPL
+-0x49b60948    xfrm_state_delete       vmlinux EXPORT_SYMBOL
+-0x0693c220    nf_register_sockopt     vmlinux EXPORT_SYMBOL
+-0x8c9e0cae    sock_kmalloc    vmlinux EXPORT_SYMBOL
+-0xb9638db4    snd_pcm_rate_to_rate_bit        vmlinux EXPORT_SYMBOL
+-0xf3b3adff    cgroup_load_subsys      vmlinux EXPORT_SYMBOL_GPL
+-0x75911fdf    ip_tunnel_get_stats64   vmlinux EXPORT_SYMBOL_GPL
+-0xe7d4daac    seq_list_next   vmlinux EXPORT_SYMBOL
+-0x2fe252cc    unregister_inet6addr_notifier   vmlinux EXPORT_SYMBOL
+-0xa06df9e1    __kfifo_dma_out_finish_r        vmlinux EXPORT_SYMBOL
+-0x01e0e788    st_sensors_allocate_trigger     vmlinux EXPORT_SYMBOL
+-0xcdd15087    of_irq_map_one  vmlinux EXPORT_SYMBOL_GPL
+-0xea97422f    vb2_queue_release       vmlinux EXPORT_SYMBOL_GPL
+-0xb37c3615    cfg80211_rx_unexpected_4addr_frame      vmlinux EXPORT_SYMBOL
+-0xbc2271b2    ipv6_chk_addr   vmlinux EXPORT_SYMBOL
+-0x9e9ab99d    __blkdev_driver_ioctl   vmlinux EXPORT_SYMBOL_GPL
+-0x54f3cc64    blk_alloc_queue_node    vmlinux EXPORT_SYMBOL
+-0xd20b9da2    iio_buffer_unregister   vmlinux EXPORT_SYMBOL
+-0xa8f8abd2    v4l2_ctrl_g_ctrl_int64  vmlinux EXPORT_SYMBOL
+-0xc2aa0765    dev_pm_qos_flags        vmlinux EXPORT_SYMBOL_GPL
+-0xf5f14859    uart_suspend_port       vmlinux EXPORT_SYMBOL
+-0xe7722171    flex_array_free vmlinux EXPORT_SYMBOL
+-0xa27aead4    blk_queue_flush vmlinux EXPORT_SYMBOL_GPL
+-0x713c83fa    bio_phys_segments       vmlinux EXPORT_SYMBOL
+-0xdaa57ec3    totalhigh_pages vmlinux EXPORT_SYMBOL
+-0x2a2a7a3b    rndis_set_param_dev     vmlinux EXPORT_SYMBOL
+-0x54fd2e8d    scsi_device_resume      vmlinux EXPORT_SYMBOL
+-0x7a060e19    ipv6_find_tlv   vmlinux EXPORT_SYMBOL_GPL
+-0x8fe6ac1e    neigh_changeaddr        vmlinux EXPORT_SYMBOL
+-0xa38c2c00    snd_soc_jack_get_type   vmlinux EXPORT_SYMBOL_GPL
+-0x710c73b6    crypto_unregister_notifier      vmlinux EXPORT_SYMBOL_GPL
+-0xda0c24cc    invalidate_inode_pages2 vmlinux EXPORT_SYMBOL_GPL
+-0x72741f25    trace_vbprintk  vmlinux EXPORT_SYMBOL_GPL
+-0xccb0efda    do_unregister_con_driver        vmlinux EXPORT_SYMBOL_GPL
+-0xa120d33c    tty_unregister_ldisc    vmlinux EXPORT_SYMBOL
+-0xd644f377    tty_standard_install    vmlinux EXPORT_SYMBOL_GPL
+-0x31222024    amba_apb_device_add_res vmlinux EXPORT_SYMBOL_GPL
+-0xf8299259    cfg80211_michael_mic_failure    vmlinux EXPORT_SYMBOL
+-0xbe53b873    ipt_do_table    vmlinux EXPORT_SYMBOL
+-0xc96046ab    kmem_cache_destroy      vmlinux EXPORT_SYMBOL
+-0x79105e99    add_to_page_cache_locked        vmlinux EXPORT_SYMBOL
+-0x4e109192    ring_buffer_entries     vmlinux EXPORT_SYMBOL_GPL
+-0x82a5e5e7    led_classdev_register   vmlinux EXPORT_SYMBOL_GPL
+-0xd952a550    vb2_ioctl_reqbufs       vmlinux EXPORT_SYMBOL_GPL
+-0xcb929a3c    scsi_calculate_bounce_limit     vmlinux EXPORT_SYMBOL
+-0x33746f3f    xfrm_prepare_input      vmlinux EXPORT_SYMBOL
+-0xd1dc81ae    xt_find_target  vmlinux EXPORT_SYMBOL
+-0x92f468ad    drm_mode_object_find    vmlinux EXPORT_SYMBOL
+-0x5a268d54    drm_clflush_sg  vmlinux EXPORT_SYMBOL
+-0x827cc6a1    pptp_msg_name   vmlinux EXPORT_SYMBOL
+-0xd4433787    vm_event_states vmlinux EXPORT_SYMBOL
+-0x488b605d    __module_get    vmlinux EXPORT_SYMBOL
+-0x081f3afb    complete_all    vmlinux EXPORT_SYMBOL
+-0x9bce482f    __release_region        vmlinux EXPORT_SYMBOL
+-0xd007f03b    phy_mii_ioctl   vmlinux EXPORT_SYMBOL
+-0x5ef79e43    exynos_drm_subdrv_open  vmlinux EXPORT_SYMBOL_GPL
+-0x34b60845    nfc_alloc_recv_skb      vmlinux EXPORT_SYMBOL
+-0x075af6c0    cfg80211_reg_can_beacon vmlinux EXPORT_SYMBOL
+-0x347013de    nla_validate    vmlinux EXPORT_SYMBOL
+-0x70f6100f    bdi_register    vmlinux EXPORT_SYMBOL
+-0xcf54ea93    async_unregister_domain vmlinux EXPORT_SYMBOL_GPL
+-0xb6efaccd    rndis_rm_hdr    vmlinux EXPORT_SYMBOL
+-0x5ed040b0    pm_set_vt_switch        vmlinux EXPORT_SYMBOL
+-0x3ad0517a    tty_free_termios        vmlinux EXPORT_SYMBOL
+-0x5fa643a3    amba_device_alloc       vmlinux EXPORT_SYMBOL_GPL
+-0x73abc38f    inet_csk_clear_xmit_timers      vmlinux EXPORT_SYMBOL
+-0x52e3e4a5    snd_pcm_hw_param_value  vmlinux EXPORT_SYMBOL
+-0x7129e5f8    hex_asc vmlinux EXPORT_SYMBOL
+-0xa0973520    fat_time_unix2fat       vmlinux EXPORT_SYMBOL_GPL
+-0x522a28d0    mmc_regulator_get_supply        vmlinux EXPORT_SYMBOL_GPL
+-0xac84055a    nf_nat_follow_master    vmlinux EXPORT_SYMBOL
+-0x2aa0e4fc    strncasecmp     vmlinux EXPORT_SYMBOL
+-0x9d5dfdfe    fuse_dev_release        vmlinux EXPORT_SYMBOL_GPL
+-0xf54fdd41    default_llseek  vmlinux EXPORT_SYMBOL
+-0xebec57c4    ring_buffer_oldest_event_ts     vmlinux EXPORT_SYMBOL_GPL
+-0x329318c8    iio_channel_release_all vmlinux EXPORT_SYMBOL_GPL
+-0xfc9a70ae    tty_get_pgrp    vmlinux EXPORT_SYMBOL_GPL
+-0xdbf66d36    tcp_read_sock   vmlinux EXPORT_SYMBOL
+-0xc18db9a3    snd_jack_new    vmlinux EXPORT_SYMBOL
+-0x5df2ea54    sdhci_pltfm_free        vmlinux EXPORT_SYMBOL_GPL
+-0x137901ef    ip_fragment     vmlinux EXPORT_SYMBOL
+-0x815b5dd4    match_octal     vmlinux EXPORT_SYMBOL
+-0x6b475280    bio_map_kern    vmlinux EXPORT_SYMBOL
+-0x3abac74c    scsi_eh_prep_cmnd       vmlinux EXPORT_SYMBOL
+-0xd162929f    tty_port_register_device_attr   vmlinux EXPORT_SYMBOL_GPL
+-0x296f9f79    xt_register_targets     vmlinux EXPORT_SYMBOL
+-0x27000b29    crc32c  vmlinux EXPORT_SYMBOL
+-0x2956cef1    vfs_fsync       vmlinux EXPORT_SYMBOL
+-0x18ae03d3    poll_freewait   vmlinux EXPORT_SYMBOL
+-0x40c7247c    si_meminfo      vmlinux EXPORT_SYMBOL
+-0x0034e52c    kthread_create_on_node  vmlinux EXPORT_SYMBOL
+-0xeecb608e    i2c_smbus_write_byte    vmlinux EXPORT_SYMBOL
+-0x907ada97    scsi_register_driver    vmlinux EXPORT_SYMBOL
+-0x7cc1b7fd    max77693_bulk_read      vmlinux EXPORT_SYMBOL_GPL
+-0x3274b08e    hdmi_avi_infoframe_init vmlinux EXPORT_SYMBOL
+-0xde8c763d    cpu_v7_set_pte_ext      vmlinux EXPORT_SYMBOL
+-0x2294b28a    snd_timer_pause vmlinux EXPORT_SYMBOL
+-0x5e95b1cd    current_umask   vmlinux EXPORT_SYMBOL
+-0xd2091a52    get_fs_type     vmlinux EXPORT_SYMBOL
+-0x94893493    ref_module      vmlinux EXPORT_SYMBOL_GPL
+-0x657ca634    iommu_domain_get_attr   vmlinux EXPORT_SYMBOL_GPL
+-0x6b758637    iommu_domain_set_attr   vmlinux EXPORT_SYMBOL_GPL
+-0xe835dcde    nf_nat_pptp_hook_outbound       vmlinux EXPORT_SYMBOL_GPL
+-0x3ac1fef9    drm_mode_legacy_fb_format       vmlinux EXPORT_SYMBOL
+-0x7cc88e22    tty_driver_kref_put     vmlinux EXPORT_SYMBOL
+-0x24fc46b6    regulator_bulk_free     vmlinux EXPORT_SYMBOL_GPL
+-0x776bea60    ip6_tnl_dst_check       vmlinux EXPORT_SYMBOL_GPL
+-0x80690fc4    sock_prot_inuse_get     vmlinux EXPORT_SYMBOL_GPL
+-0xb8aa9e8f    aead_geniv_init vmlinux EXPORT_SYMBOL_GPL
+-0x35bac202    generic_write_end       vmlinux EXPORT_SYMBOL
+-0x59e2743e    call_rcu_bh     vmlinux EXPORT_SYMBOL_GPL
+-0x639f9176    devm_request_threaded_irq       vmlinux EXPORT_SYMBOL
+-0x67955ce6    profile_hits    vmlinux EXPORT_SYMBOL_GPL
+-0xa53a0240    usb_wakeup_notification vmlinux EXPORT_SYMBOL_GPL
+-0xf5e3c0cf    scsi_host_set_state     vmlinux EXPORT_SYMBOL
+-0x31b21f37    nat_t120_hook   vmlinux EXPORT_SYMBOL_GPL
+-0xcd083b10    unregister_sound_dsp    vmlinux EXPORT_SYMBOL
+-0xda529e9e    blk_start_queue vmlinux EXPORT_SYMBOL
+-0xd84ce699    bio_copy_user   vmlinux EXPORT_SYMBOL
+-0x7a4497db    kzfree  vmlinux EXPORT_SYMBOL
+-0x91bbc6b9    genphy_config_aneg      vmlinux EXPORT_SYMBOL
+-0x1c251434    of_mm_gpiochip_add      vmlinux EXPORT_SYMBOL
+-0x8e10854d    inet_sk_diag_fill       vmlinux EXPORT_SYMBOL_GPL
+-0x07d2ea7a    arpt_unregister_table   vmlinux EXPORT_SYMBOL
+-0x2c038769    sk_filter       vmlinux EXPORT_SYMBOL
+-0x57e267af    generic_removexattr     vmlinux EXPORT_SYMBOL
+-0x643b400e    deactivate_super        vmlinux EXPORT_SYMBOL
+-0xcf241a0c    vmap    vmlinux EXPORT_SYMBOL
+-0x31f0bb78    __kmap_atomic_idx       vmlinux EXPORT_SYMBOL
+-0x4e32f63f    devm_clk_put    vmlinux EXPORT_SYMBOL
+-0x77f2c351    v4l2_ctrl_s_ctrl_int64  vmlinux EXPORT_SYMBOL
+-0xed9fdd16    gether_setup_name_default       vmlinux EXPORT_SYMBOL
+-0x6f572dd2    devm_remove_action      vmlinux EXPORT_SYMBOL_GPL
+-0xa8f59416    gpio_direction_output   vmlinux EXPORT_SYMBOL_GPL
+diff --git a/abi-checker/src/Makefile b/abi-checker/src/Makefile
+deleted file mode 100644
+index b020bc6..0000000
+--- a/abi-checker/src/Makefile
++++ /dev/null
+@@ -1,31 +0,0 @@
+-PROGRAM = abi-checker
+-GCC = gcc
+-LDD = gcc
+-
+-CFLAGS = $(shell pkg-config --cflags glib-2.0 libelf) -I.
+-
+-LDFLAGS = $(shell pkg-config --libs glib-2.0 libelf)
+-
+-SRC = kernel_abi_checker.c kernel_abi_checker_elf.c
+-
+-HEADER = kernel_abi_checker.h
+-
+-DEST_DIR = /usr/local/bin
+-
+-OBJECTS = kernel_abi_checker.o kernel_abi_checker_elf.o
+-
+-all : $(PROGRAM)
+-
+-.c.o : $(HEADER)
+-      $(GCC) -c $(CFLAGS) $< -o $@
+-
+-$(PROGRAM) : $(OBJECTS)
+-      $(LDD) $(OBJECTS) -o $@ $(LDFLAGS)
+-
+-install :
+-      mkdir -p $(DEST_DIR)
+-      cp $(PROGRAM) $(DEST_DIR)
+-
+-clean :
+-      rm -f $(PROGRAM)
+-      rm -f $(OBJECTS)
+diff --git a/abi-checker/src/build_api_kernel_checker.sh b/abi-checker/src/build_api_kernel_checker.sh
+deleted file mode 100755
+index d9e348b..0000000
+--- a/abi-checker/src/build_api_kernel_checker.sh
++++ /dev/null
+@@ -1,24 +0,0 @@
+-#!/bin/sh
+-
+-# Find abi_version file
+-ksymver=`find ../.. -name "Module.symvers"`
+-
+-# compare abi fingerprint file with kernel abi file
+-./abi-checker test-kernel "${ksymver}" "../data/abi_${1}_${2}"
+-rc="${?}"
+-
+-# Test result
+-if [ ${rc} != "0" ]
+-then
+-      echo ""
+-      echo "----------------------------------------------------------------------------------------------------------------------------"
+-      echo ""
+-      echo "The kernel ABI/API has changed. Please update kernel version and add a new abi-checker/data/abi_VERSION_ABIVER file "
+-      echo "(example abi-checker/data/abi_${1}_${2} )."
+-      echo "The kernel sources build will abort."
+-      echo ""
+-      echo ""
+-      exit 1
+-fi
+-
+-exit 0
+diff --git a/abi-checker/src/kernel_abi_checker.c b/abi-checker/src/kernel_abi_checker.c
+deleted file mode 100644
+index ae362d6..0000000
+--- a/abi-checker/src/kernel_abi_checker.c
++++ /dev/null
+@@ -1,834 +0,0 @@
+-/*
+- * Build command
+- *
+- * gcc `pkg-config --cflags glib-2.0` kernel_abi_checker.c kernel_abi_checker_elf.c -lglib-2.0 -lelf
+- */
+-
+-#include <stdio.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <glib.h>
+-
+-#include "kernel_abi_checker.h"
+-
+-/*
+- * Functions write single record into ouptu symver file
+- */
+-int writeKernelSymbolsFile( FILE *ptr, char *symbolNameCrc, char *symbolName, char *symbolModule, char *flag )
+-{
+-      return fprintf( ptr, "%s\t%s\t%s\t%s\n", symbolNameCrc, symbolName, symbolModule, flag );
+-}
+-
+-/*
+- * Function open *symver file
+- */
+-FILE *getFile( char *fileName )
+-{
+-      FILE *fPtr = fopen( fileName, "r" );
+-
+-      if( fPtr == (FILE *)NULL )
+-      {
+-              PRINT_ERROR( "Canniot open : %s\n", fileName );
+-              return (FILE *)NULL;
+-      }
+-
+-      return fPtr;
+-}
+-
+-FILE *getOutputFile( char *fileName )
+-{
+-      FILE *fPtr = fopen( fileName, "w" );
+-
+-      if( fPtr == (FILE *)NULL )
+-      {
+-              PRINT_ERROR( "Canniot open : %s\n", fileName );
+-              return (FILE *)NULL;
+-      }
+-
+-      return fPtr;
+-}
+-
+-void releaseFile( FILE *fptr )
+-{
+-      if( fptr != (FILE *)NULL )
+-              fclose( fptr );
+-}
+-
+-void freeHashElement( gpointer data )
+-{
+-      free( (void *)data );
+-}
+-
+-/*
+- * Function creates hash table
+- */
+-GHashTable *createHashTable( void )
+-{
+-      return g_hash_table_new_full( g_str_hash, g_str_equal, NULL, freeHashElement );
+-}
+-
+-/*
+- * Function destroy hash table
+- */
+-void destroyHashTable( GHashTable *tab )
+-{
+-      if( tab != (GHashTable *)NULL )
+-              g_hash_table_destroy( tab );
+-}
+-
+-/*
+- * Function read i mput file.
+- * Function return single KernelSymbol structure.
+- *
+- * Return (KernelSymbol *)-1 - if errora
+-          (KernelSymbol *)NULL - eof
+- *
+- */
+-
+-KernelSymbol *readFileLine( FILE *fptr )
+-{
+-      KernelSymbol *symbolPtr = (KernelSymbol *)NULL;
+-      char inputLine[_LINE_LENGTH_ + 1];
+-      char *crcPtr;
+-      char *symNamePtr;
+-      char *moduleNamePtr;
+-      char *flag;
+-      char *ptr;
+-      int len;
+-      int i;
+-
+-      memset( inputLine, 0, sizeof( inputLine ) );
+-      ptr = fgets( inputLine, _LINE_LENGTH_, fptr );
+-      if( ptr == (char *) NULL )
+-              return (KernelSymbol *)NULL;
+-
+-      i = 0;
+-
+-      /* CRC */
+-      crcPtr = inputLine + i;
+-      for( ;inputLine[i] != '\0' && inputLine[i] != '\t' && i < _LINE_LENGTH_; i ++ );
+-
+-      if( i >= _LINE_LENGTH_ )
+-      {
+-              PRINT_ERROR( "Incorect input record format : \"%s\"\n", inputLine );
+-              return (KernelSymbol *)-1;
+-      }
+-      inputLine[i] = '\0';
+-      i++;
+-
+-      /* Symbol name */
+-      symNamePtr = inputLine + i;
+-
+-      for( ;inputLine[i] != '\0' && inputLine[i] != '\t' && i < _LINE_LENGTH_; i ++ );
+-      if( i >= _LINE_LENGTH_ )
+-      {
+-              PRINT_ERROR( "Incorect input record format : \"%s\"\n", inputLine );
+-              return (KernelSymbol *)-1;
+-      }
+-      inputLine[i] = '\0';
+-      i ++;
+-
+-      /* Module name */
+-      moduleNamePtr = inputLine + i;
+-
+-
+-      for( ;inputLine[i] != '\0' && inputLine[i] != '\t' && i < _LINE_LENGTH_; i ++ );
+-      if( i >= _LINE_LENGTH_ )
+-      {
+-              PRINT_ERROR( "Incorect input record format : \"%s\"\n", inputLine );
+-              return (KernelSymbol *)-1;
+-      }
+-      inputLine[i] = '\0';
+-      i ++;
+-
+-      /* Flag */
+-      flag = inputLine + i;
+-
+-
+-      len = strlen( flag );
+-      flag[len ==  0 ? 0 : len -1] = '\0';
+-
+-      /* Allocate new KernelSymbol */
+-      symbolPtr = (KernelSymbol *)malloc( sizeof( KernelSymbol ) );
+-      if( symbolPtr == (KernelSymbol *)NULL )
+-              return (KernelSymbol *)-1;
+-
+-      for( i = 0; moduleNamePtr[i] != '\0' && moduleNamePtr[i] != '\n'; i ++ );
+-      moduleNamePtr[i] = '\0';
+-
+-      /* Polulate output structure */
+-      strncpy( symbolPtr -> symbolName, symNamePtr, KERNEL_SYMBOL_NAME_LENGTH );
+-      strncpy( symbolPtr -> symbolNameCrc, crcPtr, KERNEL_SYMBOL_NAME_CRC );
+-      strncpy( symbolPtr -> symbolModule, moduleNamePtr, KERNEL_SYMBOL_MODULE );
+-      strncpy( symbolPtr -> flag, flag, KERNEL_SYMBOL_FLAG );
+-      symbolPtr -> status = KERNEL_SYMBOL_STATUS_NO_TESTED;
+-
+-      /* Return KernModule structure */
+-      return symbolPtr;
+-}
+-
+-/*
+- * Function adds single kernel symbol into hashtable.
+- * Functions assumes that hash table is correctlly allocated.
+- *
+- * Returns:
+- * -1 - duplicated key
+- *  0 - success
+- */
+-
+-int addKernelSymboltoHashBase( void *s, char *key, GHashTable *tab )
+-{
+-      void *testSym;
+-
+-      /* Check duplicates */
+-      testSym = (void *)g_hash_table_lookup( tab, key );
+-      if( testSym != (void *)NULL )
+-              return -1;
+-
+-      /* Add new symbol into hash table */
+-      g_hash_table_insert( tab, key, s );
+-      return 0;
+-}
+-
+-int addKernelSymboltoHash( KernelSymbol *s, GHashTable *tab )
+-{
+-      return addKernelSymboltoHashBase( (void *)s, s -> symbolName, tab );
+-}
+-
+-int readFile( FILE *fptr, GHashTable *tab )
+-{
+-        KernelSymbol *sym = (KernelSymbol *)NULL;
+-        while( 1 == 1 )
+-        {
+-                sym = readFileLine( fptr );
+-              if( sym == (KernelSymbol *)NULL )
+-              {
+-                      /* Koniec pliku */
+-                      break;
+-              }
+-
+-              if( sym == (KernelSymbol *)-1 )
+-              {
+-                      /* Error */
+-                      return -1;
+-              }
+-
+-              if( addKernelSymboltoHash( sym, tab ) < 0 )
+-              {
+-                      /* Error - duplicated value */
+-                      return -1;
+-              }
+-        }
+-
+-      /* Success */
+-      return 0;
+-}
+-
+-GHashTable *procesInputFile( char *name )
+-{
+-      GHashTable *hashTable = (GHashTable *)NULL;
+-      FILE *fptr = (FILE *)NULL;
+-
+-      /* Open input file */
+-      fptr = getFile( name );
+-      if( fptr == (FILE *)NULL )
+-              return (GHashTable *)NULL;
+-
+-      /* Create hash table for current symver */
+-      hashTable = createHashTable();
+-      if( hashTable == (GHashTable *)NULL )
+-      {
+-              PRINT_ERROR( "Error creating hash table \n" );
+-              releaseFile( fptr );
+-              return (GHashTable *)NULL;
+-      }
+-
+-      /* Read and create current hash table */
+-      if( readFile( fptr, hashTable ) != 0 )
+-      {
+-              PRINT_ERROR( "Error reading %s\n", name );
+-              destroyHashTable( hashTable );
+-              releaseFile( fptr );
+-              return (GHashTable *)NULL;
+-      }
+-
+-      /* Close input file */
+-      releaseFile( fptr );
+-
+-      return hashTable;
+-}
+-
+-typedef struct _foreachHashData_
+-{
+-      KernelSymbolStatistics *stat;
+-      GHashTable *curr;
+-      GHashTable *new;
+-} _foreachHashData_;
+-
+-void calculateStatistics_1( gpointer key_, gpointer value_, gpointer user_data_ )
+-{
+-      KernelSymbol *value = (KernelSymbol *)value_;
+-      _foreachHashData_ *user_data = (_foreachHashData_ *)user_data_;
+-      KernelSymbol *newSym;
+-
+-      /* Update current hash table symbols count */
+-      user_data -> stat -> symver_current_count ++;
+-
+-      /* Search for symbol in new hash table */
+-      newSym = (KernelSymbol *)g_hash_table_lookup( user_data -> new, key_ );
+-
+-      if( newSym == (KernelSymbol *)NULL )
+-      {
+-              /* Symbol was removed */
+-
+-              /* Set status */
+-              value -> status = KERNEL_SYMBOL_STATUS_REMOVED;
+-
+-              user_data -> stat -> removed_symbols_count ++;
+-              return;
+-      }
+-
+-      newSym -> status = KERNEL_SYMBOL_STATUS_VIEWED;
+-
+-      if( strcmp( value -> symbolNameCrc, newSym -> symbolNameCrc ) == 0 )
+-      {
+-              user_data -> stat -> no_changed_symbols_count ++;
+-              value -> status = KERNEL_SYMBOL_STATUS_NO_CHANGES;
+-      }
+-      else
+-      {
+-              user_data -> stat -> changed_symbols_count ++;
+-              value -> status = KERNEL_SYMBOL_STATUS_CHANGED;
+-      }
+-}
+-
+-void calculateStatistics_2( gpointer key_, gpointer value_, gpointer user_data_ )
+-{
+-      KernelSymbol *value = (KernelSymbol *)value_;
+-      _foreachHashData_ *user_data = (_foreachHashData_ *)user_data_;
+-
+-      /* Update current hash table symbols count */
+-      user_data -> stat -> symver_new_count ++;
+-
+-      if( value -> status == KERNEL_SYMBOL_STATUS_NO_TESTED )
+-      {
+-              user_data -> stat -> new_symbols_count ++;
+-              value -> status = KERNEL_SYMBOL_STATUS_NEW;
+-      }
+-}
+-
+-void collectStatistics( GHashTable *curr, GHashTable *new, KernelSymbolStatistics *statistics )
+-{
+-      _foreachHashData_ foreachdata;
+-
+-      /* Init foreach data */
+-      memset( (void *)statistics, 0, sizeof( KernelSymbolStatistics ) );
+-      foreachdata.stat = statistics;
+-      foreachdata.curr = curr;
+-      foreachdata.new = new;
+-
+-      /* Scan current hash table */
+-      g_hash_table_foreach( curr, calculateStatistics_1, (gpointer)&foreachdata );
+-
+-      /* Scan new hash table */
+-      g_hash_table_foreach( new, calculateStatistics_2, (gpointer)&foreachdata );
+-}
+-
+-void reportSymbolsDetails( gpointer key_, gpointer value_, gpointer user_data_ )
+-{
+-      KernelSymbol *value = (KernelSymbol *)value_;
+-
+-      switch( *((int *)user_data_) )
+-      {
+-      case 0 :        /* New */
+-              if( value -> status == KERNEL_SYMBOL_STATUS_NEW )
+-                      PRINT_INFO_RAW( "\t| NEW     | %40s | %10s | %s\n", value -> symbolName, value -> symbolNameCrc, value -> symbolModule );
+-              break;
+-
+-      case 1 :        /* Changed */
+-              if( value -> status == KERNEL_SYMBOL_STATUS_CHANGED )
+-                      PRINT_INFO_RAW( "\t| CHANGED | %40s | %10s | %s\n", value -> symbolName, value -> symbolNameCrc, value -> symbolModule );
+-              break;
+-
+-      case 2 :        /* Removed */
+-              if( value -> status == KERNEL_SYMBOL_STATUS_REMOVED )
+-                      PRINT_INFO_RAW( "\t| REMOVED | %40s | %10s | %s\n", value -> symbolName, value -> symbolNameCrc, value -> symbolModule );
+-              break;
+-      }
+-}
+-//[CHANGED]         cfg80211_send_rx_assoc         0x80e54114                  vmlinux
+-
+-void listChangedSymbols( GHashTable *curr, GHashTable *new, KernelSymbolStatistics *statistics )
+-{
+-      int mode = 0;
+-      int printFooter = 0;
+-
+-      if( statistics -> new_symbols_count == 0 && statistics -> changed_symbols_count == 0 && statistics -> removed_symbols_count == 0 )
+-              return;
+-
+-      PRINT_INFO_RAW( "\n" );
+-
+-      PRINT_INFO_RAW( "\tNew symbols in kernel\n" );
+-      PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
+-      PRINT_INFO_RAW( "\t| Change  |                 Linux kernel symbol name |        CRC | Module name \n" );
+-      PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
+-
+-      if( statistics -> new_symbols_count != 0 && new != (GHashTable *)NULL )
+-      {
+-              mode = 0;
+-              g_hash_table_foreach( new, reportSymbolsDetails, (gpointer)&mode );
+-              printFooter = 1;
+-      }
+-
+-      if( statistics -> changed_symbols_count != 0 && curr != (GHashTable *)NULL )
+-      {
+-              if( statistics -> new_symbols_count != 0 )
+-                      PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
+-
+-              mode = 1;
+-              g_hash_table_foreach( curr, reportSymbolsDetails, (gpointer)&mode );
+-              printFooter = 1;
+-      }
+-
+-      if( statistics -> removed_symbols_count != 0 && curr != (GHashTable *)NULL )
+-      {
+-              if( statistics -> new_symbols_count != 0 || statistics -> changed_symbols_count != 0 )
+-                      PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
+-
+-              mode = 2;
+-              g_hash_table_foreach( curr, reportSymbolsDetails, (gpointer)&mode );
+-              printFooter = 1;
+-      }
+-
+-      if( printFooter == 1 )
+-              PRINT_INFO_RAW( "\t+---------+------------------------------------------+------------+--------------------------------\n" );
+-}
+-
+-void reportsStatistics( GHashTable *curr, GHashTable *new, KernelSymbolStatistics *statistics )
+-{
+-      listChangedSymbols( curr, new, statistics );
+-
+-      PRINT_INFO_RAW( "\n" );
+-      PRINT_INFO_RAW( "\tKernel symbols version statistics \n" );
+-      PRINT_INFO_RAW( "\t-------------------------------------------------\n" );
+-      PRINT_INFO_RAW( "\tSymbols in actual kernel/module . %d\n", statistics -> symver_current_count );
+-      if( new != (GHashTable *)NULL )
+-              PRINT_INFO_RAW( "\tSymbols in new kernel/module .... %d\n", statistics -> symver_new_count );
+-      PRINT_INFO_RAW( "\tNew symbols ..................... %d\n", statistics -> new_symbols_count );
+-      PRINT_INFO_RAW( "\tRemoved symbols ................. %d\n", statistics -> removed_symbols_count );
+-      PRINT_INFO_RAW( "\tChanged symbols ................. %d\n", statistics -> changed_symbols_count );
+-      PRINT_INFO_RAW( "\tUnchanged symbols ............... %d\n", statistics -> no_changed_symbols_count );
+-      PRINT_INFO_RAW( "\n" );
+-}
+-
+-void printUsage( char *progName, int type )
+-{
+-      switch( type )
+-      {
+-      case 0 :
+-              PRINT_INFO_RAW( "\tUsage: %s test-kernel in_symver_file_1 in_symver_file_2\n", progName );
+-              break;
+-
+-      case 1 :
+-              PRINT_INFO_RAW( "\tUsage: %s build-list in_module_symbols_file in_kernel_symver_file outt_module_symver_file\n", progName );
+-              break;
+-
+-      case 2 :
+-              PRINT_INFO_RAW( "\tUsage: %s dump-module kernel_symver_file ko_module_file output_module_symver_file\n", progName );
+-              break;
+-
+-      case 4 :
+-              PRINT_INFO_RAW( "\tUsage: %s test-module kernel_symver_file ko_module_file \n", progName );
+-              break;
+-
+-      default :
+-              PRINT_INFO_RAW( "\tUsage: %s test|build-list file1 file2 [output_file] \n", progName );
+-              break;
+-      }
+-}
+-
+-/*
+- * Function parses input parameters and return.
+- * Return:
+- *            -1 - error
+- *             0 - test mode  - the program will compare two symver files
+- *             1 - build mode - for given module sybmbols file and kernel symver creates files
+- *                              with list kernel symbols used by the module.
+- */
+-int parsInputParameters( int argc, char **argv, char **f1, char **f2, char **f3 )
+-{
+-      char *toolName = argv[0];
+-
+-      if( argc < 2 )
+-      {
+-              printUsage( toolName, -1 );
+-              return -1;
+-      }
+-
+-      if( strcmp( argv[1], "test-kernel" ) == 0 )
+-      {
+-              /* Test mode */
+-              if( argc < 4 )
+-              {
+-                      printUsage( toolName, 0 );
+-                      return -1;
+-              }
+-              *f1 = argv[2];
+-              *f2 = argv[3];
+-              *f3 = (char *)NULL;
+-
+-              return 0;
+-
+-      }
+-      else
+-      if( strcmp( argv[1], "build-list" ) == 0 )
+-      {
+-              /* Build mode */
+-              if( argc < 5 )
+-              {
+-                      printUsage( toolName, 1 );
+-                      return -1;
+-              }
+-              *f1 = argv[2];
+-              *f2 = argv[3];
+-              *f3 = argv[4];
+-
+-              return 1;
+-      }
+-      else
+-      if( strcmp( argv[1], "dump-module" ) == 0 )
+-      {
+-              /* Build mode */
+-              if( argc < 5 )
+-              {
+-                      printUsage( toolName, 2 );
+-                      return -1;
+-              }
+-              *f1 = argv[2];
+-              *f2 = argv[3];
+-              *f3 = argv[4];
+-
+-              return 2;
+-      }
+-      else
+-      if( strcmp( argv[1], "usage" ) == 0 )
+-      {
+-              return 3;
+-      }
+-      else
+-      if( strcmp( argv[1], "test-module" ) == 0 )
+-      {
+-              /* Test mode */
+-              if( argc < 4 )
+-              {
+-                      printUsage( toolName, 4 );
+-                      return -1;
+-              }
+-              *f1 = argv[2];
+-              *f2 = argv[3];
+-              *f3 = (char *)NULL;
+-
+-              return 4;
+-      }
+-
+-
+-      printUsage( toolName, -1 );
+-      return -1;
+-}
+-
+-int testKernel( char *f1, char *f2 )
+-{
+-      GHashTable *curr_hashTable = (GHashTable *)NULL;
+-      GHashTable *new_hashTable = (GHashTable *)NULL;
+-      KernelSymbolStatistics statistics;
+-
+-      /*
+-       * ----------------------------------------------
+-       * Read current symver file
+-       * ----------------------------------------------
+-       */
+-      curr_hashTable = procesInputFile( f1 );
+-      if( curr_hashTable == (GHashTable *)NULL )
+-      {
+-              PRINT_ERROR( "Error read input \"%s\" file.\n", f1 );
+-              return 1;
+-      }
+-
+-      /*
+-       * ----------------------------------------------
+-       * Read new symver file
+-       * ----------------------------------------------
+-      */
+-      new_hashTable = procesInputFile( f2 );
+-      if( new_hashTable == (GHashTable *)NULL )
+-      {
+-              destroyHashTable( curr_hashTable );
+-              PRINT_ERROR( "Error read input \"%s\" file.\n", f2 );
+-        return 1;
+-      }
+-
+-      /*
+-       * ----------------------------------------------
+-       * Compute statistics
+-       * ----------------------------------------------
+-       */
+-      collectStatistics( curr_hashTable, new_hashTable, &statistics );
+-
+-      /*
+-       * ---------------------------------------------
+-       * Report changes
+-       * ---------------------------------------------
+-       */
+-      reportsStatistics( curr_hashTable, new_hashTable, &statistics );
+-
+-      /*
+-       * --------------------------------------------
+-       * Free hash tables
+-       * --------------------------------------------
+-       */
+-      destroyHashTable( curr_hashTable );
+-      destroyHashTable( new_hashTable );
+-
+-      if( statistics.changed_symbols_count != 0 || statistics.removed_symbols_count != 0 || statistics.new_symbols_count != 0 )
+-              return 2;
+-
+-      return 0;
+-}
+-
+-void collectStatisticsModule( GHashTable *curr, GHashTable *module, KernelSymbolStatistics *statistics )
+-{
+-      _foreachHashData_ foreachdata;
+-
+-      /* Init foreach data */
+-      memset( (void *)statistics, 0, sizeof( KernelSymbolStatistics ) );
+-      foreachdata.stat = statistics;
+-      foreachdata.curr = module;
+-      foreachdata.new = curr;
+-
+-      /* Scan current hash table */
+-      g_hash_table_foreach( module, calculateStatistics_1, (gpointer)&foreachdata );
+-}
+-
+-
+-int testModule( char *f1, char *f2 )
+-{
+-      GHashTable *curr_hashTable = (GHashTable *)NULL;
+-      GHashTable *module_hashTable = (GHashTable *)NULL;
+-      KernelSymbolStatistics statistics;
+-
+-      /*
+-       * ----------------------------------------------
+-       * Read current symver file
+-       * ----------------------------------------------
+-       */
+-      curr_hashTable = procesInputFile( f1 );
+-      if( curr_hashTable == (GHashTable *)NULL )
+-      {
+-              PRINT_ERROR( "Error read input \"%s\" file.\n", f1 );
+-              return 1;
+-      }
+-
+-      /*
+-       * ----------------------------------------------
+-       * Read module symbols
+-       * ----------------------------------------------
+-      */
+-      module_hashTable = procesInputFile( f2 );
+-      if( module_hashTable == (GHashTable *)NULL )
+-      {
+-              destroyHashTable( curr_hashTable );
+-              PRINT_ERROR( "Error read input \"%s\" file.\n", f2 );
+-        return 1;
+-      }
+-
+-      /*
+-       * ----------------------------------------------
+-       * Compute statistics
+-       * ----------------------------------------------
+-       */
+-      collectStatisticsModule( curr_hashTable, module_hashTable, &statistics );
+-
+-      /*
+-       * ---------------------------------------------
+-       * Report changes
+-       * ---------------------------------------------
+-       */
+-      reportsStatistics( module_hashTable, (GHashTable *)NULL, &statistics );
+-
+-      /*
+-       * --------------------------------------------
+-       * Free hash tables
+-       * --------------------------------------------
+-       */
+-      destroyHashTable( curr_hashTable );
+-      destroyHashTable( module_hashTable );
+-
+-      if( statistics.changed_symbols_count != 0 || statistics.removed_symbols_count != 0 )
+-              return 2;
+-
+-      return 0;
+-}
+-
+-int buildListMode( char *f1, char *f2, char *f3 )
+-{
+-      GHashTable *curr_hashTable = (GHashTable *)NULL;
+-      char inputLine[_LINE_LENGTH_ + 1];
+-      FILE *symListFptr = (FILE *)NULL;
+-      FILE *outFptr = (FILE *)NULL;
+-      KernelSymbol *kSym;
+-      int size;
+-
+-      /*
+-       * ----------------------------------------------
+-       * Read current symver file
+-       * ----------------------------------------------
+-       */
+-      curr_hashTable = procesInputFile( f1 );
+-      if( curr_hashTable == (GHashTable *)NULL )
+-      {
+-              PRINT_ERROR( "Error read input \"%s\" file.\n", f1 );
+-              return 1;
+-      }
+-
+-      /*
+-       * Open files
+-       */
+-      outFptr = getOutputFile( f3 );
+-      symListFptr = getFile( f2 );
+-
+-      if( symListFptr == (FILE *)NULL || outFptr == (FILE *)NULL )
+-      {
+-              destroyHashTable( curr_hashTable );
+-              releaseFile( symListFptr );
+-              releaseFile( outFptr );
+-              PRINT_ERROR( "Error open files : \"%s\", \"%s\".\n", f2, f3 );
+-              return 1;
+-      }
+-
+-      while( fgets( inputLine, _LINE_LENGTH_, symListFptr ) )
+-      {
+-              size = strlen( inputLine );
+-              inputLine[size == 0 ? 0 :size - 1] = '\0';
+-
+-              /* Search for symbol in new hash table */
+-              kSym = (KernelSymbol *)g_hash_table_lookup( curr_hashTable, inputLine );
+-
+-              if( kSym != (KernelSymbol *)NULL )
+-                      writeKernelSymbolsFile( outFptr, kSym -> symbolNameCrc, kSym -> symbolName, kSym -> symbolModule, kSym -> flag );
+-      }
+-
+-      destroyHashTable( curr_hashTable );
+-      releaseFile( symListFptr );
+-      releaseFile( outFptr );
+-
+-      return 0;
+-}
+-
+-int callDumpModuleSymbols( char *f1, char *f2, char *f3 )
+-{
+-      GHashTable *curr_hashTable = (GHashTable *)NULL;
+-      GHashTable *module_hashTable = (GHashTable *)NULL;
+-
+-      /*
+-       * ----------------------------------------------
+-       * Read current symver file
+-       * ----------------------------------------------
+-       */
+-      curr_hashTable = procesInputFile( f1 );
+-      if( curr_hashTable == (GHashTable *)NULL )
+-      {
+-              PRINT_ERROR( "Error read input \"%s\" file.\n", f1 );
+-              return 1;
+-      }
+-
+-      /*
+-       * ----------------------------------------------
+-       * Read kernel module *.ko file
+-       * ----------------------------------------------
+-       */
+-      module_hashTable = readEfl( f2 );
+-      if( module_hashTable == (GHashTable *)NULL )
+-      {
+-              PRINT_ERROR( "Error read input \"%s\" file.\n", f2 );
+-              destroyHashTable( curr_hashTable );
+-              return 1;
+-      }
+-
+-      /*
+-       * Dump module symbols into output file
+-       */
+-      if( dumpModuleSymbols( f3, module_hashTable, curr_hashTable ) < 0 )
+-      {
+-              PRINT_ERROR( "Error creating dump file \"%s\"\n", f3 );
+-              destroyHashTable( curr_hashTable );
+-              return 1;
+-      }
+-
+-      /*
+-       * Free hash tables
+-       */
+-      destroyHashTable( module_hashTable );
+-      destroyHashTable( curr_hashTable );
+-
+-      return 0;
+-}
+-
+-int printUsageInfo( char *f1 )
+-{
+-      PRINT_INFO_RAW( "\n" );
+-      PRINT_INFO_RAW( "\tProgram usage\n" );
+-      PRINT_INFO_RAW( "\t-----------------------------------------------\n" );
+-      PRINT_INFO_RAW( "\n" );
+-      printUsage( f1, 0 );
+-      printUsage( f1, 1 );
+-      printUsage( f1, 2 );
+-
+-      return 0;
+-}
+-
+-int main(int argc, char** argv)
+-{
+-      char *f1 = (char *)NULL;
+-      char *f2 = (char *)NULL;
+-      char *f3 = (char *)NULL;
+-      int rc = -1;
+-
+-      int mode = parsInputParameters( argc, argv, &f1, &f2, &f3 );
+-
+-      switch( mode )
+-      {
+-      case 0 :
+-              rc = testKernel( f1, f2 );
+-              break;
+-
+-      case 1 :
+-              rc = buildListMode( f1, f2, f3 );
+-              break;
+-
+-      case 2 :
+-              rc = callDumpModuleSymbols( f1, f2, f3 );
+-              break;
+-
+-      case 3 :
+-              rc = printUsageInfo( argv[0] );
+-              break;
+-
+-      case 4 :
+-              rc = testModule( f1, f2 );
+-              break;
+-      }
+-
+-      PRINT_INFO_RAW( "\n" );
+-
+-      if( rc == 2 )
+-              PRINT_INFO_RAW( "\tChanges !!!\n" );
+-      else
+-      if( rc == 1 )
+-              PRINT_INFO_RAW( "\tError !!!\n" );
+-      else
+-              PRINT_INFO_RAW( "\tDone\n" );
+-
+-      PRINT_INFO_RAW( "\n" );
+-
+-      return ( rc != 0 ) ? 1 : 0;
+-}
+diff --git a/abi-checker/src/kernel_abi_checker.h b/abi-checker/src/kernel_abi_checker.h
+deleted file mode 100644
+index 8df231e..0000000
+--- a/abi-checker/src/kernel_abi_checker.h
++++ /dev/null
+@@ -1,62 +0,0 @@
+-#ifndef _kernel_abi_checker_h_
+-#define _kernel_abi_checker_h_
+-
+-#include <stdio.h>
+-#include <glib.h>
+-
+-/*
+- * Definitions
+- */
+-#define KERNEL_SYMBOL_NAME_LENGTH     64
+-#define KERNEL_SYMBOL_NAME_CRC                32
+-#define KERNEL_SYMBOL_MODULE          256
+-#define KERNEL_SYMBOL_FLAG                    256
+-
+-#define KERNEL_SYMBOL_STATUS_NO_TESTED        0
+-#define KERNEL_SYMBOL_STATUS_NO_CHANGES       1
+-#define KERNEL_SYMBOL_STATUS_NEW              2
+-#define KERNEL_SYMBOL_STATUS_REMOVED  3
+-#define KERNEL_SYMBOL_STATUS_CHANGED  4
+-#define KERNEL_SYMBOL_STATUS_VIEWED           5
+-
+-#define _LINE_LENGTH_ 4096
+-
+-/*
+- * Data types
+- */
+-typedef struct KernelSymbol
+-{
+-      char symbolName[KERNEL_SYMBOL_NAME_LENGTH + 1];
+-      char symbolNameCrc[KERNEL_SYMBOL_NAME_CRC + 1];
+-      char symbolModule[KERNEL_SYMBOL_MODULE + 1];
+-      char flag[KERNEL_SYMBOL_FLAG + 1];
+-      int status;
+-
+-} KernelSymbol;
+-
+-typedef struct KernelSymbolStatistics
+-{
+-      int symver_current_count;
+-      int symver_new_count;
+-
+-      int new_symbols_count;
+-      int removed_symbols_count;
+-      int changed_symbols_count;
+-      int no_changed_symbols_count;
+-
+-} KernelSymbolStatistics;
+-
+-extern int writeKernelSymbolsFile( FILE *, char *, char *, char *, char * );
+-extern int addKernelSymboltoHashBase( void *, char *, GHashTable * );
+-extern int dumpModuleSymbols( char *, GHashTable *, GHashTable * );
+-extern void destroyHashTable( GHashTable * );
+-extern GHashTable *createHashTable( void );
+-extern FILE *getOutputFile( char * );
+-extern void releaseFile( FILE * );
+-GHashTable *readEfl( char * );
+-
+-#define PRINT_ERROR(...)  do { fprintf( stderr, "ERROR : " ); fprintf( stderr, __VA_ARGS__ ); } while( 0 )
+-#define PRINT_INFO_RAW(...)   do { fprintf( stdout, __VA_ARGS__ ); } while( 0 )
+-#define PRINT_INFO(...)   do { fprintf( stderr, "INFO  : " ); fprintf( stdout, __VA_ARGS__ ); } while( 0 )
+-
+-#endif
+diff --git a/abi-checker/src/kernel_abi_checker_elf.c b/abi-checker/src/kernel_abi_checker_elf.c
+deleted file mode 100644
+index 6f4f28c..0000000
+--- a/abi-checker/src/kernel_abi_checker_elf.c
++++ /dev/null
+@@ -1,172 +0,0 @@
+-#include "kernel_abi_checker.h"
+-
+-#include <sys/types.h>
+-#include <sys/stat.h>
+-#include <unistd.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <libelf.h>
+-#include <stdio.h>
+-#include <fcntl.h>
+-#include <gelf.h>
+-
+-GHashTable *readEfl( char *file )
+-{
+-      GHashTable *outputHashTable = (GHashTable *)NULL;
+-      Elf_Data *edata = (Elf_Data *)NULL;
+-      Elf_Scn *scn = (Elf_Scn *)NULL;
+-      char *base_ptr = (char *)NULL;
+-      char *sname = (char *)NULL;
+-      Elf *elf = (Elf *)NULL;
+-      struct stat elf_stats;
+-      int symbol_count;
+-      GElf_Shdr shdr;
+-      GElf_Sym sym;
+-      int size;
+-      int fd;
+-      int i;
+-
+-      fd = open( file, O_RDONLY );
+-      if( fd < 0 )
+-      {
+-              PRINT_ERROR( "Cannot open efl file : %s\n", file );
+-              return (GHashTable *)NULL;
+-      }
+-
+-      if( ( fstat( fd, &elf_stats ) ) )
+-      {
+-              PRINT_ERROR( "Cannot stat efl file : %s\n", file );
+-              close(fd );
+-              return (GHashTable *)NULL;
+-      }
+-
+-      base_ptr = (char *) malloc( elf_stats.st_size );
+-      if( base_ptr == (char *)NULL )
+-      {
+-              PRINT_ERROR( "Memory allocation error.\n" );
+-              close( fd );
+-              return (GHashTable *)NULL;
+-      }
+-
+-      if( ( read( fd, base_ptr, elf_stats.st_size ) ) < elf_stats.st_size )
+-      {
+-              PRINT_ERROR( "Cannot read input efl file : %s\n", file );
+-        free( base_ptr );
+-        close( fd );
+-              return (GHashTable *)NULL;
+-      }
+-      free( base_ptr );
+-
+-      /* Create output hash table */
+-      outputHashTable = createHashTable();
+-      if( outputHashTable == (GHashTable *)NULL )
+-      {
+-              PRINT_ERROR( "Memory allocation for hash table error : %s\n", file );
+-        free( base_ptr );
+-        close( fd );
+-              return (GHashTable *)NULL;
+-      }
+-
+-      if( elf_version( EV_CURRENT ) == EV_NONE )
+-              fprintf( stderr, "WARNING Elf Library is out of date!\n" );
+-
+-      // Iterate through section headers again this time well stop when we find symbols
+-      elf = elf_begin( fd, ELF_C_READ, NULL );
+-
+-      while( ( scn = elf_nextscn( elf, scn ) ) != (Elf_Scn *)NULL )
+-      {
+-              gelf_getshdr( scn, &shdr );
+-
+-              // When we find a section header marked SHT_SYMTAB stop and get symbols
+-              if(shdr.sh_type == SHT_SYMTAB)
+-              {
+-                      // edata points to our symbol table
+-                      edata = elf_getdata(scn, edata);
+-
+-                      symbol_count = shdr.sh_size / shdr.sh_entsize;
+-
+-                      for( i = 0; i < symbol_count; i++ )
+-                      {
+-                              /* Get symbol */
+-                              gelf_getsym( edata, i, &sym );
+-
+-                              /* Get symbol name length */
+-                              size = strlen( elf_strptr( elf, shdr.sh_link, sym.st_name ) );
+-                              if( size != 0 )
+-                              {
+-                                      /* allocate memory for symbol name */
+-                                      sname = (char *)malloc( sizeof( char ) * ( size + 1 ) );
+-                                      if( sname == (char *)NULL )
+-                                      {
+-                                              PRINT_ERROR( "Memory allocation for hash table error : %s\n", file );
+-                                              destroyHashTable( outputHashTable );
+-                                      close( fd );
+-                                              return (GHashTable *)NULL;
+-                                      }
+-
+-                                      strcpy( sname, elf_strptr( elf, shdr.sh_link, sym.st_name ) );
+-
+-                                      // Add symbol to hash
+-                                      if( addKernelSymboltoHashBase( (void *)sname, sname, outputHashTable ) < 0 )
+-                                      {
+-                                              // If duplicated key free memory
+-                                              free( sname );
+-                                      }
+-
+-                              }
+-                      }
+-              }
+-      }
+-
+-      /* Close file */
+-      close( fd );
+-
+-      /* Return hash table */
+-      return outputHashTable;
+-}
+-
+-/*
+- * Private user data definition.
+- */
+-
+-typedef struct _efl_user_data_
+-{
+-      GHashTable *kernelHash;
+-      FILE *outFilePtr;
+-} _efl_user_data_;
+-
+-
+-void dumpModuleSymbolsIteration( gpointer key_, gpointer value_, gpointer user_data_ )
+-{
+-      char *key = (char *)key_;
+-      _efl_user_data_ *user_data = (_efl_user_data_ *)user_data_;
+-      KernelSymbol *ptr = (KernelSymbol *)NULL;
+-
+-      ptr = (KernelSymbol *)g_hash_table_lookup( user_data -> kernelHash, key );
+-      if( ptr != (void *)NULL )
+-              writeKernelSymbolsFile( user_data -> outFilePtr, ptr -> symbolNameCrc, ptr -> symbolName, ptr -> symbolModule, ptr -> flag );
+-}
+-
+-/*
+- * Function dumps into output files kernel symbols that
+- * are use in the module
+- */
+-int dumpModuleSymbols( char *outoutFile, GHashTable *moduleSymbols, GHashTable *kernelSymbols )
+-{
+-      FILE *outputFilePtr = getOutputFile( outoutFile );
+-      _efl_user_data_ userData;
+-
+-      if( outputFilePtr == (FILE *)NULL )
+-              return -1;
+-
+-      userData.outFilePtr = outputFilePtr;
+-      userData.kernelHash = kernelSymbols;
+-
+-      /* Loob module symbols */
+-      g_hash_table_foreach( moduleSymbols, dumpModuleSymbolsIteration, (gpointer)&userData );
+-
+-      /* Close output file */
+-      releaseFile( outputFilePtr );
+-
+-      return 0;
+-}
+diff --git a/packaging/linux-kernel.spec b/packaging/linux-kernel.spec
+index e199f9b..5e64441 100644
+--- a/packaging/linux-kernel.spec
++++ b/packaging/linux-kernel.spec
+@@ -1,6 +1,5 @@
+-%bcond_with abidev
+ %define config_name tizen_defconfig
+-%define abiver 1
++%define abiver current
+ %define build_id %{config_name}.%{abiver}
+ Name: linux-kernel
+@@ -13,12 +12,7 @@ Vendor: The Linux Community
+ URL: http://www.kernel.org
+ Source0:   %{name}-%{version}-%{build_id}.tar.gz
+ BuildRoot: %{_tmppath}/%{name}-%{PACKAGE_VERSION}-root
+-
+-BuildRequires: pkgconfig(glib-2.0)
+-BuildRequires: pkgconfig(libelf)
+-
+ BuildRequires: linux-glibc-devel
+-BuildRequires: u-boot-tools
+ BuildRequires: bc
+ %define kernel_build_dir_name .%{name}-%{version}-%{build_id}
+@@ -27,15 +21,6 @@ BuildRequires: bc
+ %description
+ The Linux Kernel, the operating system core itself
+-%if %{with abidev}
+-%package abi-dev
+-Summary: Header files for the Linux kernel for use by glibc
+-Group: Development/System
+-
+-%description abi-dev
+-The package provide linux kernel API/ABI development file.
+-%endif
+-
+ %package headers
+ Summary: Header files for the Linux kernel for use by glibc
+ Group: Development/System
+@@ -44,18 +29,11 @@ Provides: kernel-headers = %{version}
+ %description headers
+ Kernel-headers includes the C header files that specify the interface
+-between the Linux kernel and userspace libraries and programs. The
++between the Linux kernel and userspace libraries and programs.  The
+ header files define structures and constants that are needed for
+ building most standard programs and are also needed for rebuilding the
+ glibc package.
+-%package abi-tools
+-Summary: Kernael ABI tools
+-Group: Development/System
+-
+-%description abi-tools
+-The package provide set of tools to test and create ABI/API dumps.
+-
+ %package sources
+ Summary: Full linux kernel sources for out-of-tree modules
+ Group: Development/System
+@@ -72,20 +50,10 @@ Requires: kernel-sources = %{version}-%{build_id}
+ %description build
+ Prebuilt linux kernel for out-of-tree modules.
+-%package uImage
+-Summary: Linux kernel image
+-Group: Development/System
+-
+-%description uImage
+-Linux kernel uImage
+-
+ %prep
+ %setup -q
+ %build
+-# 0. Build abi checker
+-make -C abi-checker/src
+-
+ # 1. Create main build directory
+ rm -rf %{kernel_build_dir}
+ mkdir -p %{kernel_build_dir}
+@@ -100,15 +68,6 @@ mkdir -p %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}
+ make EXTRAVERSION="-%{build_id}" O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} %{config_name}
+ make EXTRAVERSION="-%{build_id}" O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} %{?_smp_mflags}
+-# 4.1 Test ABI/API kernel change
+-%if %{with abidev}
+-echo "No linuks kernel ABI/API checks"
+-%else
+-( cd abi-checker/src; chmod 755 build_api_kernel_checker.sh; ./build_api_kernel_checker.sh "%{version}" "%{abiver}" )
+-%endif
+-
+-make EXTRAVERSION="-%{build_id}" O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} uImage %{?jobs:-j%jobs}
+-
+ # 5. Update Makefile in output build
+ cat %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/Makefile | sed 's/\/home\/abuild\/rpmbuild\/BUILD\/%{name}-%{version}/\/usr\/src\/linux-kernel-sources-%{version}-%{build_id}/' > %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/Makefile.new
+ mv %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/Makefile.new %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/Makefile
+@@ -123,63 +82,32 @@ QA_SKIP_BUILD_ROOT="DO_NOT_WANT"; export QA_SKIP_BUILD_ROOT
+ # 1. Destynation directories
+ mkdir -p %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}
+ mkdir -p %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}
+-mkdir -p %{buildroot}/boot/abi/
+-mkdir -p %{buildroot}/usr/local/bin
+-# 2. Install uImage
+-cp %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/arch/arm/boot/uImage %{buildroot}/boot/
+-
+-# 3. Restore source and build irectory
++# 2. Restore source and build irectory
+ tar -xf %{kernel_build_dir}/linux-kernel-sources-%{version}-%{build_id}.tar -C %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}
+ tar -xf %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}.tar   -C %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}
+-# 4. Install kernel headers
+-make INSTALL_PATH=%{buildroot}/boot INSTALL_MOD_PATH=%{buildroot} O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} install
++# 3. Install kernel headers
+ make INSTALL_PATH=%{buildroot} INSTALL_MOD_PATH=%{buildroot} O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} INSTALL_HDR_PATH=%{buildroot}/usr headers_install
+-# 4.1 Install ABI/API tools
+-cp abi-checker/src/abi-checker %{buildroot}/usr/local/bin
+-
+-# 4.2 Install abi_%{version} file
+-%if %{with abidev}
+-find ../.. -name "Module.symvers" -exec cp {} %{buildroot}/boot/abi/abi_devel \;
+-%else
+-cp abi-checker/data/abi* %{buildroot}/boot/abi/.
+-ln -sf /boot/abi/abi_%{version}_%{abiver} %{buildroot}/boot/abi/current
+-%endif
+-
+-# 5. Remove files
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name ".tmp_vmlinux1" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name ".tmp_vmlinux2" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "vmlinux" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "uImage" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "zImage" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*.cmd" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.o" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "\.*dtb*tmp" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.*tmp" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.c" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.S" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.ko" -exec rm -f {} \;
+-
+-find %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id} -name "*.c" -exec rm -f {} \;
+-
+-find %{buildroot}/usr -name "\.\.install.cmd"  -exec rm -f {} \;
+-find %{buildroot}/usr -name "\.install"  -exec rm -f {} \;
+-
+-rm -rf %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}/%{kernel_build_dir_name}
+-rm -f  %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}/source
+-rm -f  %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/source
++# 4. Remove files
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name ".tmp_vmlinux1" -exec rm -f {} +
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name ".tmp_vmlinux2" -exec rm -f {} +
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "vmlinux" -exec rm -f {} +
++find %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id} -name "*.c" -exec rm -f {} +
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*.cmd" -exec rm -f {} +
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.o" -exec rm -f {} +
++find %{buildroot}/usr -name "..install.cmd" -exec rm -f {} +
+-rm -rf %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}/abi-checker
++find %{buildroot}/usr/include -name "\.\.install.cmd"  -exec rm -f {} +
++find %{buildroot}/usr/include -name "\.install"  -exec rm -f {} +
+-rm -rf %{buildroot}/System.map*
+-rm -rf %{buildroot}/vmlinux*
+-
+-rm -rf %{buildroot}/boot/System.map*
+-rm -rf %{buildroot}/boot/vmlinux*
++rm -rf %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}/%{kernel_build_dir_name}
++rm -f %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}/source
++rm -f %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/source
++rm -f %{buildroot}/System.map-3.10.0 %{buildroot}/vmlinux-3.10.0
+-# 6. Create symbolic links
++# 5. Create symbolic links
+ ln -sf /usr/src/linux-kernel-sources-%{version}-%{build_id} %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/source
+ %clean
+@@ -196,18 +124,3 @@ rm -rf %{buildroot}
+ %files build
+ %defattr (-, root, root)
+ /usr/src/linux-kernel-build-%{version}-%{build_id}
+-
+-%files uImage
+-%if %{without abidev}
+-/boot/
+-%else
+-/boot/uImage
+-%endif
+-
+-%files abi-tools
+-/usr/local/bin
+-
+-%if %{with abidev}
+-%files abi-dev
+-/boot/abi
+-%endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1066-video-display-s6e8aa0-adjust-brightness-value-to-dri.patch b/patches.tizen/1066-video-display-s6e8aa0-adjust-brightness-value-to-dri.patch
new file mode 100644 (file)
index 0000000..06f117d
--- /dev/null
@@ -0,0 +1,71 @@
+From 164e4879bd307c451c57642769e108d2b9cbbad0 Mon Sep 17 00:00:00 2001
+From: Donghwa Lee <dh09.lee@samsung.com>
+Date: Fri, 3 Jan 2014 10:03:34 +0900
+Subject: [PATCH 1066/1302] video: display: s6e8aa0: adjust brightness value to
+ driver level
+
+Nevertheless there is only support 24 brightness steps in driver,
+platform brightness status bar is suitable maximum size for 100.
+Operation about brightness bar on the tizen looks that there is
+something wrong. So I would adjust brightness value to driver's
+brightness level.
+
+Change-Id: Ia653a127b470208b0da9bc448f58422005e05d72
+Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/video/display/panel-s6e8aa0.c | 17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/video/display/panel-s6e8aa0.c b/drivers/video/display/panel-s6e8aa0.c
+index 1bfa30f..9f82a9c 100644
+--- a/drivers/video/display/panel-s6e8aa0.c
++++ b/drivers/video/display/panel-s6e8aa0.c
+@@ -35,6 +35,7 @@
+ #include <video/panel-s6e8aa0.h>
+ #define LDI_MTP_LENGTH                        24
++#define MAX_BRIGHTNESS                        100
+ #define GAMMA_LEVEL_NUM                       25
+ #define GAMMA_TABLE_LEN                       26
+ #define S6E8AA0_PANEL_COND_LEN                39
+@@ -906,6 +907,16 @@ static int s6e8aa0_get_brightness(struct backlight_device *bd)
+       return bd->props.brightness;
+ }
++static int s6e8aa0_convert_brightness(int brightness)
++{
++      if (brightness >= MAX_BRIGHTNESS)
++              return GAMMA_LEVEL_NUM - 1;
++      else if (brightness > 0)
++              return (brightness / 4);
++      else
++              return 0;
++}
++
+ static int s6e8aa0_update_status(struct backlight_device *bd)
+ {
+       struct s6e8aa0 *lcd = bl_get_data(bd);
+@@ -914,7 +925,7 @@ static int s6e8aa0_update_status(struct backlight_device *bd)
+       mutex_lock(&lcd->mutex);
+-      lcd->brightness = bd->props.brightness;
++      lcd->brightness = s6e8aa0_convert_brightness(bd->props.brightness);
+       if (lcd->entity.state != DISPLAY_ENTITY_STATE_ON)
+               goto unlock;
+@@ -1342,8 +1353,8 @@ static int s6e8aa0_probe(struct platform_device *pdev)
+       mutex_init(&lcd->mutex);
+-      lcd->bd->props.max_brightness = GAMMA_LEVEL_NUM - 1;
+-      lcd->bd->props.brightness = GAMMA_LEVEL_NUM - 1;
++      lcd->bd->props.max_brightness = MAX_BRIGHTNESS;
++      lcd->bd->props.brightness = MAX_BRIGHTNESS;
+       lcd->brightness = GAMMA_LEVEL_NUM - 1;
+       lcd->entity.of_node = pdev->dev.of_node;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1067-spec-file-update-to-build-output-uImage-and-Device-T.patch b/patches.tizen/1067-spec-file-update-to-build-output-uImage-and-Device-T.patch
new file mode 100644 (file)
index 0000000..2560c04
--- /dev/null
@@ -0,0 +1,159 @@
+From e6ab8dbe1a3057b7dbc41836383cc026a043ddde Mon Sep 17 00:00:00 2001
+From: Jacek Pielaszkiewicz <j.pielaszkie@samsung.com>
+Date: Fri, 3 Jan 2014 12:56:59 +0100
+Subject: [PATCH 1067/1302] *spec file update to build output uImage and Device
+ Tree
+
+The following changes have been implemented:
+1. A new linux-kernel-uImage package was added. The package provide kernel uImage.
+2. Additional cleanup linux-kernel-sources and linux-kernel-build packages
+   was added.
+3. Symbolic links linux-kernel-build-current and linux-kernel-sources-current were
+   added. Links points current kernel sources and build directories.
+
+Change-Id: Ifa889d42fca69cce4d458d9ac7e0514cfdf1caef
+Signed-off-by: Jacek Pielaszkiewicz <j.pielaszkie@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ packaging/linux-kernel.spec | 73 +++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 57 insertions(+), 16 deletions(-)
+
+diff --git a/packaging/linux-kernel.spec b/packaging/linux-kernel.spec
+index 5e64441..84a4db8 100644
+--- a/packaging/linux-kernel.spec
++++ b/packaging/linux-kernel.spec
+@@ -1,18 +1,21 @@
+ %define config_name tizen_defconfig
+-%define abiver current
++%define abiver 1
+ %define build_id %{config_name}.%{abiver}
++%define defaultDtb exynos4412-m0.dtb
+ Name: linux-kernel
+ Summary: The Linux Kernel
+ Version: 3.10.19
+ Release: 1
+-License: GPL
++License: GPL-2.0
+ Group: System Environment/Kernel
+ Vendor: The Linux Community
+ URL: http://www.kernel.org
+ Source0:   %{name}-%{version}-%{build_id}.tar.gz
+ BuildRoot: %{_tmppath}/%{name}-%{PACKAGE_VERSION}-root
++
+ BuildRequires: linux-glibc-devel
++BuildRequires: u-boot-tools
+ BuildRequires: bc
+ %define kernel_build_dir_name .%{name}-%{version}-%{build_id}
+@@ -50,6 +53,13 @@ Requires: kernel-sources = %{version}-%{build_id}
+ %description build
+ Prebuilt linux kernel for out-of-tree modules.
++%package uImage
++Summary: Linux kernel image
++Group: Development/System
++
++%description uImage
++Linux kernel uImage
++
+ %prep
+ %setup -q
+@@ -68,6 +78,12 @@ mkdir -p %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}
+ make EXTRAVERSION="-%{build_id}" O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} %{config_name}
+ make EXTRAVERSION="-%{build_id}" O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} %{?_smp_mflags}
++# 4.1 Build uImage
++make EXTRAVERSION="-%{build_id}" O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} zImage %{?_smp_mflags}
++make EXTRAVERSION="-%{build_id}" O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} dtbs %{?_smp_mflags}
++cat %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/arch/arm/boot/zImage %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/arch/arm/boot/dts/%{defaultDtb}  > bImage
++mkimage -A arm -C none -O linux -a 40008000 -e 40008000 -n 'Linux 3.10 Tizen kernel' -d bImage uImage
++
+ # 5. Update Makefile in output build
+ cat %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/Makefile | sed 's/\/home\/abuild\/rpmbuild\/BUILD\/%{name}-%{version}/\/usr\/src\/linux-kernel-sources-%{version}-%{build_id}/' > %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/Makefile.new
+ mv %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/Makefile.new %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/Makefile
+@@ -82,33 +98,53 @@ QA_SKIP_BUILD_ROOT="DO_NOT_WANT"; export QA_SKIP_BUILD_ROOT
+ # 1. Destynation directories
+ mkdir -p %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}
+ mkdir -p %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}
++mkdir -p %{buildroot}/boot/
++
++# 2. Install uImage
++install uImage %{buildroot}/boot/
+-# 2. Restore source and build irectory
++# 3. Restore source and build irectory
+ tar -xf %{kernel_build_dir}/linux-kernel-sources-%{version}-%{build_id}.tar -C %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}
+ tar -xf %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}.tar   -C %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}
+-# 3. Install kernel headers
++# 4. Install kernel headers
+ make INSTALL_PATH=%{buildroot} INSTALL_MOD_PATH=%{buildroot} O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} INSTALL_HDR_PATH=%{buildroot}/usr headers_install
+-# 4. Remove files
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name ".tmp_vmlinux1" -exec rm -f {} +
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name ".tmp_vmlinux2" -exec rm -f {} +
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "vmlinux" -exec rm -f {} +
+-find %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id} -name "*.c" -exec rm -f {} +
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*.cmd" -exec rm -f {} +
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.o" -exec rm -f {} +
+-find %{buildroot}/usr -name "..install.cmd" -exec rm -f {} +
++# 5. Remove files
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name ".tmp_vmlinux1" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name ".tmp_vmlinux2" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "vmlinux" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "uImage" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "zImage" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*.cmd" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.o" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "\.*dtb*tmp" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.*tmp" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.S" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.ko" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.o" -exec rm -f {} \;
+-find %{buildroot}/usr/include -name "\.\.install.cmd"  -exec rm -f {} +
+-find %{buildroot}/usr/include -name "\.install"  -exec rm -f {} +
++find %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id} -name "*.c" -exec rm -f {} \;
++
++find %{buildroot}/usr -name "..install.cmd" -exec rm -f {} \;
++
++find %{buildroot}/usr/include -name "\.\.install.cmd"  -exec rm -f {} \;
++find %{buildroot}/usr/include -name "\.install"  -exec rm -f {} \;
+ rm -rf %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}/%{kernel_build_dir_name}
+ rm -f %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}/source
+ rm -f %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/source
+-rm -f %{buildroot}/System.map-3.10.0 %{buildroot}/vmlinux-3.10.0
+-# 5. Create symbolic links
++rm -rf %{buildroot}/System.map*
++rm -rf %{buildroot}/vmlinux*
++
++rm -rf %{buildroot}/boot/System.map*
++rm -rf %{buildroot}/boot/vmlinux*
++
++# 6. Create symbolic links
+ ln -sf /usr/src/linux-kernel-sources-%{version}-%{build_id} %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/source
++ln -sf /usr/src/linux-kernel-build-%{version}-%{build_id}   %{buildroot}/usr/src/linux-kernel-build-current
++ln -sf /usr/src/linux-kernel-sources-%{version}-%{build_id} %{buildroot}/usr/src/linux-kernel-sources-current
+ %clean
+ rm -rf %{buildroot}
+@@ -120,7 +156,12 @@ rm -rf %{buildroot}
+ %files sources
+ %defattr (-, root, root)
+ /usr/src/linux-kernel-sources-%{version}-%{build_id}
++/usr/src/linux-kernel-sources-current
+ %files build
+ %defattr (-, root, root)
+ /usr/src/linux-kernel-build-%{version}-%{build_id}
++/usr/src/linux-kernel-build-current
++
++%files uImage
++/boot/uImage
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1068-video-display-s6e8aa0-remove-duplicated-mtp-read-fun.patch b/patches.tizen/1068-video-display-s6e8aa0-remove-duplicated-mtp-read-fun.patch
new file mode 100644 (file)
index 0000000..98c7ea4
--- /dev/null
@@ -0,0 +1,75 @@
+From 1142ee7900b30882b771259413d7ce584cd46be3 Mon Sep 17 00:00:00 2001
+From: Donghwa Lee <dh09.lee@samsung.com>
+Date: Fri, 10 Jan 2014 11:24:33 +0900
+Subject: [PATCH 1068/1302] video: display: s6e8aa0: remove duplicated mtp read
+ function
+
+There is no need to call mtp check function whenever lcd power on.
+It is sufficient just called once at booting time because mtp data
+is fixed values.
+
+Change-Id: I3f37633821c83089cb516eeb9810c4ae435d5cc1
+Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/video/display/panel-s6e8aa0.c | 17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/video/display/panel-s6e8aa0.c b/drivers/video/display/panel-s6e8aa0.c
+index 9f82a9c..dce22d9 100644
+--- a/drivers/video/display/panel-s6e8aa0.c
++++ b/drivers/video/display/panel-s6e8aa0.c
+@@ -116,6 +116,8 @@ struct s6e8aa0 {
+       int power;
+       int brightness;
+       struct mutex mutex;
++
++      bool probed;
+ };
+ struct s6e8aa0_variant {
+@@ -1101,10 +1103,11 @@ static int s6e8aa0_set_sequence(struct s6e8aa0 *lcd)
+ {
+       int ret;
+-      ret = s6e8aa0_check_mtp(lcd);
+-      if (ret < 0)
+-              return ret;
+-
++      if (!lcd->probed) {
++              ret = s6e8aa0_check_mtp(lcd);
++              if (ret < 0)
++                      return ret;
++      }
+       s6e8aa0_panel_init(lcd);
+       s6e8aa0_display_on(lcd);
+@@ -1212,14 +1215,14 @@ static void s6e8aa0_power_on(struct s6e8aa0 *panel)
+       msleep(panel->pdata->power_on_delay);
++      src->ops.dsi->enable(src);
++
+       /* lcd reset */
+       if (panel->pdata->reset)
+               panel->pdata->reset(panel->dev);
+       msleep(panel->pdata->reset_delay);
+-      src->ops.dsi->enable(src);
+-
+       s6e8aa0_set_sequence(panel);
+ }
+@@ -1370,6 +1373,8 @@ static int s6e8aa0_probe(struct platform_device *pdev)
+       display_entity_set_state(&lcd->entity, DISPLAY_ENTITY_STATE_ON);
++      lcd->probed = true;
++
+       dev_dbg(&pdev->dev, "probed s6e8aa0 panel driver.\n");
+       return 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1069-video-display-s6e8aa0-change-power-off-sequence-to-r.patch b/patches.tizen/1069-video-display-s6e8aa0-change-power-off-sequence-to-r.patch
new file mode 100644 (file)
index 0000000..9039bb9
--- /dev/null
@@ -0,0 +1,49 @@
+From 7487ca3f5671466c88a26fb7b5a6b49b107a769f Mon Sep 17 00:00:00 2001
+From: Donghwa Lee <dh09.lee@samsung.com>
+Date: Fri, 10 Jan 2014 13:19:49 +0900
+Subject: [PATCH 1069/1302] video: display: s6e8aa0: change power off sequence
+ to remove noise
+
+It is need to turn off the panel more earlier than mipi dsi
+to remove noise and switch the sequence of display_off and sleep_in
+command following manufacturer's instruction.
+
+Change-Id: Id2e7bf63fb84a12673fa56d572ad63ae5cf80539
+Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/video/display/panel-s6e8aa0.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/video/display/panel-s6e8aa0.c b/drivers/video/display/panel-s6e8aa0.c
+index dce22d9..d6dbfef 100644
+--- a/drivers/video/display/panel-s6e8aa0.c
++++ b/drivers/video/display/panel-s6e8aa0.c
+@@ -1230,10 +1230,10 @@ static void s6e8aa0_power_off(struct s6e8aa0 *panel)
+ {
+       struct video_source *src = panel->entity.source;
+-      s6e8aa0_sleep_in(panel);
+       s6e8aa0_display_off(panel);
+-
+-      src->ops.dsi->disable(src);
++      s6e8aa0_sleep_in(panel);
++      /* power off delay */
++      msleep(120);
+       regulator_bulk_disable(ARRAY_SIZE(panel->supplies),
+                                               panel->supplies);
+@@ -1250,8 +1250,9 @@ static int s6e8aa0_set_state(struct display_entity *entity,
+       case DISPLAY_ENTITY_STATE_OFF:
+               if (entity->state != DISPLAY_ENTITY_STATE_ON)
+                       break;
+-              src->common_ops->set_stream(src, DISPLAY_ENTITY_STREAM_STOPPED);
+               s6e8aa0_power_off(panel);
++              src->common_ops->set_stream(src, DISPLAY_ENTITY_STREAM_STOPPED);
++              src->ops.dsi->disable(src);
+               break;
+       case DISPLAY_ENTITY_STATE_ON:
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1070-iio-st_gyro-Prevent-register-threshold-events.patch b/patches.tizen/1070-iio-st_gyro-Prevent-register-threshold-events.patch
new file mode 100644 (file)
index 0000000..c6c8943
--- /dev/null
@@ -0,0 +1,42 @@
+From 4774c5e717cfb69c40bbf46a122e5a72c9635236 Mon Sep 17 00:00:00 2001
+From: Beomho Seo <beomho.seo@samsung.com>
+Date: Fri, 10 Jan 2014 17:32:05 +0900
+Subject: [PATCH 1070/1302] iio:st_gyro: Prevent register threshold events
+
+Currently, st_gyro sensor driver doesn't support threshold events.
+If event_mask is not zero, driver is register threshold events.
+As a result, Null pointer dereference at iio_ev_* functions.
+This patch set zero event_mask of st_gyro sensor.
+
+Change-Id: Ie39b43624ef764d3c8626f41dc4611ad09d72302
+Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iio/gyro/st_gyro_core.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/iio/gyro/st_gyro_core.c b/drivers/iio/gyro/st_gyro_core.c
+index fa9b242..419c838 100644
+--- a/drivers/iio/gyro/st_gyro_core.c
++++ b/drivers/iio/gyro/st_gyro_core.c
+@@ -300,6 +300,7 @@ static const struct iio_trigger_ops st_gyro_trigger_ops = {
+ int st_gyro_common_probe(struct iio_dev *indio_dev)
+ {
+       int err;
++      int i;
+       struct st_sensor_data *gdata = iio_priv(indio_dev);
+       indio_dev->modes = INDIO_DIRECT_MODE;
+@@ -331,6 +332,9 @@ int st_gyro_common_probe(struct iio_dev *indio_dev)
+                                                 ST_GYRO_TRIGGER_OPS);
+               if (err < 0)
+                       goto st_gyro_probe_trigger_error;
++
++              for (i = 0; i < indio_dev->num_channels; i++)
++                      gdata->sensor->ch[i].event_mask = 0;
+       }
+       err = iio_device_register(indio_dev);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1071-iio-cm36651-Rebased-light-proximity-sensor-driver.patch b/patches.tizen/1071-iio-cm36651-Rebased-light-proximity-sensor-driver.patch
new file mode 100644 (file)
index 0000000..d7af60b
--- /dev/null
@@ -0,0 +1,982 @@
+From e6521734cb61524bfa05c534265a6f86e3012c1f Mon Sep 17 00:00:00 2001
+From: Beomho Seo <beomho.seo@samsung.com>
+Date: Fri, 10 Jan 2014 17:56:22 +0900
+Subject: [PATCH 1071/1302] iio: cm36651: Rebased light/proximity sensor driver
+
+This patch is rebased on mainline.
+
+The driver exposes five channels: Red, Green, Blue, Clear and Proximity.
+It also support detection proximity event.
+
+Change-Id: Ifb152f4c3dafad2524d58396866781297346d8da
+Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iio/light/cm36651.c | 708 ++++++++++++++++++++------------------------
+ 1 file changed, 318 insertions(+), 390 deletions(-)
+
+diff --git a/drivers/iio/light/cm36651.c b/drivers/iio/light/cm36651.c
+index 92a837b..e4fefd8 100644
+--- a/drivers/iio/light/cm36651.c
++++ b/drivers/iio/light/cm36651.c
+@@ -1,13 +1,14 @@
+ /*
+  * Copyright (C) 2013 Samsung Electronics Co., Ltd.
++ * Author: Beomho Seo <beomho.seo@samsung.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.
++ * under  the terms of  the GNU General Public License version 2, as published
++ * by the Free Software Foundation.
+  */
+ #include <linux/delay.h>
++#include <linux/err.h>
+ #include <linux/i2c.h>
+ #include <linux/mutex.h>
+ #include <linux/module.h>
+@@ -17,288 +18,212 @@
+ #include <linux/iio/sysfs.h>
+ #include <linux/iio/events.h>
+-#define       CM36651_VENDOR          "CAPELLA"
+-#define       CHIP_ID                 "CM36651"
+-
+-#define I2C_M_WR      0 /* for i2c Write */
+-#define I2c_M_RD      1 /* for i2c Read */
+-
+-/* slave addresses */
+-#define CM36651_ALS   0x30 /* 7bits : 0x18 */
+-#define CM36651_PS    0x32 /* 7bits : 0x19 */
++/* Slave address 0x19 for PS of 7 bit addressing protocol for I2C */
++#define CM36651_I2C_ADDR_PS           0x19
++/* Alert Response Address */
++#define CM36651_ARA                   0x0C
+ /* Ambient light sensor */
+-#define CS_CONF1      0x00
+-#define CS_CONF2      0x01
+-#define CS_CONF3      0x06
+-
+-#define RED           0x00
+-#define GREEN         0x01
+-#define BLUE          0x02
+-#define WHITE         0x03
++#define CM36651_CS_CONF1              0x00
++#define CM36651_CS_CONF2              0x01
++#define CM36651_ALS_WH_M              0x02
++#define CM36651_ALS_WH_L              0x03
++#define CM36651_ALS_WL_M              0x04
++#define CM36651_ALS_WL_L              0x05
++#define CM36651_CS_CONF3              0x06
++#define CM36651_CS_CONF_REG_NUM               0x02
+ /* Proximity sensor */
+-#define PS_CONF1      0x00
+-#define PS_THD                0x01
+-#define PS_CANC               0x02
+-#define PS_CONF2      0x03
+-
+-#define ALS_REG_NUM   3
+-#define PS_REG_NUM    4
+-#define ALS_CHANNEL_NUM       4
+-#define INITIAL_THD   0x09
+-#define SCAN_MODE_LIGHT       0
+-#define SCAN_MODE_PROX        1
+-
+-enum {
+-      LIGHT_EN,
+-      PROXIMITY_EN,
+-      PROXIMITY_EV_EN,
++#define CM36651_PS_CONF1              0x00
++#define CM36651_PS_THD                        0x01
++#define CM36651_PS_CANC                       0x02
++#define CM36651_PS_CONF2              0x03
++#define CM36651_PS_REG_NUM            0x04
++
++/* CS_CONF1 command code */
++#define CM36651_ALS_ENABLE            0x00
++#define CM36651_ALS_DISABLE           0x01
++#define CM36651_ALS_INT_EN            0x02
++#define CM36651_ALS_THRES             0x04
++
++/* CS_CONF2 command code */
++#define CM36651_CS_CONF2_DEFAULT_BIT  0x08
++
++/* CS_CONF3 channel integration time */
++#define CM36651_CS_IT1                        0x00 /* Integration time 80000 usec */
++#define CM36651_CS_IT2                        0x40 /* Integration time 160000 usec */
++#define CM36651_CS_IT3                        0x80 /* Integration time 320000 usec */
++#define CM36651_CS_IT4                        0xC0 /* Integration time 640000 usec */
++
++/* PS_CONF1 command code */
++#define CM36651_PS_ENABLE             0x00
++#define CM36651_PS_DISABLE            0x01
++#define CM36651_PS_INT_EN             0x02
++#define CM36651_PS_PERS2              0x04
++#define CM36651_PS_PERS3              0x08
++#define CM36651_PS_PERS4              0x0C
++
++/* PS_CONF1 command code: integration time */
++#define CM36651_PS_IT1                        0x00 /* Integration time 320 usec */
++#define CM36651_PS_IT2                        0x10 /* Integration time 420 usec */
++#define CM36651_PS_IT3                        0x20 /* Integration time 520 usec */
++#define CM36651_PS_IT4                        0x30 /* Integration time 640 usec */
++
++/* PS_CONF1 command code: duty ratio */
++#define CM36651_PS_DR1                        0x00 /* Duty ratio 1/80 */
++#define CM36651_PS_DR2                        0x40 /* Duty ratio 1/160 */
++#define CM36651_PS_DR3                        0x80 /* Duty ratio 1/320 */
++#define CM36651_PS_DR4                        0xC0 /* Duty ratio 1/640 */
++
++/* PS_THD command code */
++#define CM36651_PS_INITIAL_THD                0x05
++
++/* PS_CANC command code */
++#define CM36651_PS_CANC_DEFAULT               0x00
++
++/* PS_CONF2 command code */
++#define CM36651_PS_HYS1                       0x00
++#define CM36651_PS_HYS2                       0x01
++#define CM36651_PS_SMART_PERS_EN      0x02
++#define CM36651_PS_DIR_INT            0x04
++#define CM36651_PS_MS                 0x10
++
++#define CM36651_CS_COLOR_NUM          4
++
++#define CM36651_CLOSE_PROXIMITY               0x32
++#define CM36651_FAR_PROXIMITY                 0x33
++
++enum cm36651_operation_mode {
++      CM36651_LIGHT_EN,
++      CM36651_PROXIMITY_EN,
++      CM36651_PROXIMITY_EV_EN,
+ };
+-enum cm36651_cmd {
+-      READ_RAW_LIGHT,
+-      READ_RAW_PROXIMITY,
+-      PROX_EV_EN,
+-      PROX_EV_DIS,
++enum cm36651_light_channel_idx {
++      CM36651_LIGHT_CHANNEL_IDX_RED,
++      CM36651_LIGHT_CHANNEL_IDX_GREEN,
++      CM36651_LIGHT_CHANNEL_IDX_BLUE,
++      CM36651_LIGHT_CHANNEL_IDX_CLEAR,
+ };
+-enum {
+-      CLOSE_PROXIMITY,
+-      FAR_PROXIMITY,
++enum cm36651_command {
++      CM36651_CMD_READ_RAW_LIGHT,
++      CM36651_CMD_READ_RAW_PROXIMITY,
++      CM36651_CMD_PROX_EV_EN,
++      CM36651_CMD_PROX_EV_DIS,
+ };
+-/* register settings */
+-static u8 als_reg_setting[ALS_REG_NUM][2] = {
+-      {0x00, 0x04},   /* CS_CONF1 */
+-      {0x01, 0x08},   /* CS_CONF2 */
+-      {0x06, 0x00}    /* CS_CONF3 */
++static const u8 cm36651_cs_reg[CM36651_CS_CONF_REG_NUM] = {
++      CM36651_CS_CONF1,
++      CM36651_CS_CONF2,
+ };
+-static u8 ps_reg_setting[PS_REG_NUM][2] = {
+-      {0x00, 0x3C},   /* PS_CONF1 */
+-      {0x01, 0x09},   /* PS_THD */
+-      {0x02, 0x00},   /* PS_CANC */
+-      {0x03, 0x13},   /* PS_CONF2 */
++static const u8 cm36651_ps_reg[CM36651_PS_REG_NUM] = {
++      CM36651_PS_CONF1,
++      CM36651_PS_THD,
++      CM36651_PS_CANC,
++      CM36651_PS_CONF2,
+ };
+ struct cm36651_data {
+       const struct cm36651_platform_data *pdata;
+       struct i2c_client *client;
++      struct i2c_client *ps_client;
++      struct i2c_client *ara_client;
+       struct mutex lock;
+       struct regulator *vled_reg;
+       unsigned long flags;
+-      wait_queue_head_t data_ready_queue;
+-      u8 temp;
+-      u16 color[4];
++      int cs_int_time[CM36651_CS_COLOR_NUM];
++      int ps_int_time;
++      u8 cs_ctrl_regs[CM36651_CS_CONF_REG_NUM];
++      u8 ps_ctrl_regs[CM36651_PS_REG_NUM];
++      u16 color[CM36651_CS_COLOR_NUM];
+ };
+-int cm36651_i2c_read_byte(struct cm36651_data *cm36651, u8 addr, u8 *val)
+-{
+-      int ret = 0;
+-      struct i2c_msg msg[1];
+-      struct i2c_client *client = cm36651->client;
+-
+-      if ((client == NULL) || (!client->adapter))
+-              return -ENODEV;
+-
+-      /* send slave address & command */
+-      msg->addr = addr >> 1;
+-      msg->flags = I2C_M_RD;
+-      msg->len = 1;
+-      msg->buf = val;
+-
+-      ret = i2c_transfer(client->adapter, msg, 1);
+-      if (ret != 1) {
+-              dev_err(&client->dev, "i2c transfer error ret=%d\n", ret);
+-              ret = -EIO;
+-      }
+-
+-      return 0;
+-}
+-
+-int cm36651_i2c_read_word(struct cm36651_data *cm36651, u8 addr,
+-                                                      u8 command, u16 *val)
+-{
+-      int ret = 0;
+-      struct i2c_client *client = cm36651->client;
+-      struct i2c_msg msg[2];
+-      unsigned char data[2] = {0,};
+-      u16 value = 0;
+-
+-      if ((client == NULL) || (!client->adapter))
+-              return -ENODEV;
+-
+-      /* send slave address & command */
+-      msg[0].addr = addr >> 1;
+-      msg[0].flags = I2C_M_WR;
+-      msg[0].len = 1;
+-      msg[0].buf = &command;
+-
+-      /* read word data */
+-      msg[1].addr = addr >> 1;
+-      msg[1].flags = I2C_M_RD;
+-      msg[1].len = 2;
+-      msg[1].buf = data;
+-
+-      ret = i2c_transfer(client->adapter, msg, 2);
+-      if (ret != 2) {
+-              dev_err(&client->dev, "i2c transfer error ret=%d\n", ret);
+-              ret = -EIO;
+-      }
+-      value = (u16)data[1];
+-      *val = (value << 8) | (u16)data[0];
+-
+-      return 0;
+-}
+-
+-int cm36651_i2c_write_byte(struct cm36651_data *cm36651, u8 addr,
+-                                                       u8 command, u8 val)
+-{
+-      int ret = 0;
+-      struct i2c_client *client = cm36651->client;
+-      struct i2c_msg msg[1];
+-      unsigned char data[2];
+-
+-      if ((client == NULL) || (!client->adapter))
+-              return -ENODEV;
+-
+-      data[0] = command;
+-      data[1] = val;
+-
+-      /* send slave address & command */
+-      msg->addr = addr >> 1;
+-      msg->flags = I2C_M_WR;
+-      msg->len = 2;
+-      msg->buf = data;
+-
+-      ret = i2c_transfer(client->adapter, msg, 1);
+-      if (ret != 1) {
+-              dev_err(&client->dev, "i2c transfer error ret=%d\n", ret);
+-              ret = -EIO;
+-      }
+-
+-      return 0;
+-}
+-
+ static int cm36651_setup_reg(struct cm36651_data *cm36651)
+ {
+       struct i2c_client *client = cm36651->client;
+-      int ret = 0, i = 0;
+-      u8 tmp = 0;
++      struct i2c_client *ps_client = cm36651->ps_client;
++      int i, ret;
+-      /* ALS initialization */
+-      for (i = 0; i < ALS_REG_NUM; i++) {
+-              ret = cm36651_i2c_write_byte(cm36651, CM36651_ALS,
+-                      als_reg_setting[i][0], als_reg_setting[i][1]);
++      /* CS initialization */
++      cm36651->cs_ctrl_regs[CM36651_CS_CONF1] = CM36651_ALS_ENABLE |
++                                                           CM36651_ALS_THRES;
++      cm36651->cs_ctrl_regs[CM36651_CS_CONF2] = CM36651_CS_CONF2_DEFAULT_BIT;
++
++      for (i = 0; i < CM36651_CS_CONF_REG_NUM; i++) {
++              ret = i2c_smbus_write_byte_data(client, cm36651_cs_reg[i],
++                                                   cm36651->cs_ctrl_regs[i]);
+               if (ret < 0)
+-                      goto err_setup_reg;
++                      return ret;
+       }
+       /* PS initialization */
+-      for (i = 0; i < PS_REG_NUM; i++) {
+-              ret = cm36651_i2c_write_byte(cm36651, CM36651_PS,
+-                      ps_reg_setting[i][0], ps_reg_setting[i][1]);
++      cm36651->ps_ctrl_regs[CM36651_PS_CONF1] = CM36651_PS_ENABLE |
++                                                              CM36651_PS_IT2;
++      cm36651->ps_ctrl_regs[CM36651_PS_THD] = CM36651_PS_INITIAL_THD;
++      cm36651->ps_ctrl_regs[CM36651_PS_CANC] = CM36651_PS_CANC_DEFAULT;
++      cm36651->ps_ctrl_regs[CM36651_PS_CONF2] = CM36651_PS_HYS2 |
++                              CM36651_PS_DIR_INT | CM36651_PS_SMART_PERS_EN;
++
++      for (i = 0; i < CM36651_PS_REG_NUM; i++) {
++              ret = i2c_smbus_write_byte_data(ps_client, cm36651_ps_reg[i],
++                                                   cm36651->ps_ctrl_regs[i]);
+               if (ret < 0)
+-                      goto err_setup_reg;
++                      return ret;
+       }
+-      /* printing the inital proximity value with no contact */
+-      ret = cm36651_i2c_read_byte(cm36651, CM36651_PS, &tmp);
++      /* Set shutdown mode */
++      ret = i2c_smbus_write_byte_data(client, CM36651_CS_CONF1,
++                                                        CM36651_ALS_DISABLE);
+       if (ret < 0)
+-              goto err_setup_reg;
+-
+-      dev_dbg(&client->dev, "initial proximity value = %d\n", tmp);
++              return ret;
+-      /* turn off */
+-      cm36651_i2c_write_byte(cm36651, CM36651_ALS, CS_CONF1, 0x01);
+-      cm36651_i2c_write_byte(cm36651, CM36651_PS, PS_CONF1, 0x01);
++      ret = i2c_smbus_write_byte_data(cm36651->ps_client,
++                                       CM36651_PS_CONF1, CM36651_PS_DISABLE);
++      if (ret < 0)
++              return ret;
+       return 0;
+-
+-err_setup_reg:
+-      dev_err(&client->dev, "cm36651 register failed. %d\n", ret);
+-      return ret;
+-}
+-
+-static ssize_t cm36651_vendor_show(struct device *dev,
+-              struct device_attribute *attr, char *buf)
+-{
+-      return sprintf(buf, "%s\n", CM36651_VENDOR);
+ }
+-static ssize_t proximity_thresh_show(struct device *dev,
+-              struct device_attribute *attr, char *buf)
+-{
+-      return sprintf(buf, "prox_threshold = %d\n", ps_reg_setting[1][1]);
+-}
+-
+-static ssize_t proximity_thresh_store(struct device *dev,
+-              struct device_attribute *attr, const char *buf, size_t size)
++static int cm36651_read_output(struct cm36651_data *cm36651,
++                              struct iio_chan_spec const *chan, int *val)
+ {
+-      struct iio_dev *dev_info = dev_to_iio_dev(dev);
+-      struct cm36651_data *cm36651 = iio_priv(dev_info);
+       struct i2c_client *client = cm36651->client;
+-      u8 thresh_value = INITIAL_THD;
+-      int ret = 0;
+-
+-      ret = kstrtou8(buf, 10, &thresh_value);
+-      if (ret < 0)
+-              dev_err(dev, "kstrtoint failed\n");
++      int ret = -EINVAL;
+-      ps_reg_setting[1][1] = thresh_value;
+-      ret = cm36651_i2c_write_byte(cm36651, CM36651_PS,
+-                      PS_THD, ps_reg_setting[1][1]);
+-      if (ret < 0) {
+-              dev_err(dev, "PS reg is failed. %d\n", ret);
+-              return ret;
+-      }
+-      dev_info(&client->dev, "new threshold = 0x%x\n", ps_reg_setting[1][1]);
+-      msleep(150);
++      switch (chan->type) {
++      case IIO_LIGHT:
++              *val = i2c_smbus_read_word_data(client, chan->address);
++              if (*val < 0)
++                      return ret;
+-      return size;
+-}
++              ret = i2c_smbus_write_byte_data(client, CM36651_CS_CONF1,
++                                                      CM36651_ALS_DISABLE);
++              if (ret < 0)
++                      return ret;
+-static int cm36651_read_output(struct cm36651_data *cm36651,
+-                                              u8 address, int *val)
+-{
+-      struct i2c_client *client = cm36651->client;
+-      int i = 0, ret = -EINVAL;
+-      u8 prox_val;
+-
+-      switch (address) {
+-      case CM36651_ALS:
+-              for (i = 0; i < ALS_CHANNEL_NUM; i++) {
+-                      ret = cm36651_i2c_read_word(cm36651, address,
+-                                                      i, &cm36651->color[i]);
++              ret = IIO_VAL_INT;
++              break;
++      case IIO_PROXIMITY:
++              *val = i2c_smbus_read_byte(cm36651->ps_client);
++              if (*val < 0)
++                      return ret;
++
++              if (!test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags)) {
++                      ret = i2c_smbus_write_byte_data(cm36651->ps_client,
++                                      CM36651_PS_CONF1, CM36651_PS_DISABLE);
+                       if (ret < 0)
+-                              goto read_err;
++                              return ret;
+               }
+-              dev_info(&client->dev, "%d, %d, %d, %d\n",
+-                      cm36651->color[0]+1, cm36651->color[1]+1,
+-                      cm36651->color[2]+1, cm36651->color[3]+1);
++              ret = IIO_VAL_INT;
+               break;
+-      case CM36651_PS:
+-              ret = cm36651_i2c_read_byte(cm36651, address, &prox_val);
+-              if (ret < 0)
+-                      goto read_err;
+-
+-              dev_info(&client->dev, "%d\n", prox_val);
++      default:
+               break;
+       }
+-      ret = cm36651_i2c_write_byte(cm36651, address, 0x00, 0x01);
+-      if (ret < 0)
+-              goto write_err;
+-
+-      return ret;
+-
+-read_err:
+-      dev_err(&client->dev, "fail to read sensor value");
+-      return ret;
+-write_err:
+-      dev_err(&client->dev, "fail to write register value");
+       return ret;
+ }
+@@ -307,76 +232,94 @@ static irqreturn_t cm36651_irq_handler(int irq, void *data)
+       struct iio_dev *indio_dev = data;
+       struct cm36651_data *cm36651 = iio_priv(indio_dev);
+       struct i2c_client *client = cm36651->client;
+-      int ev_dir, val, ret;
++      int ev_dir, ret;
+       u64 ev_code;
+-      ret =  cm36651_i2c_read_byte(cm36651, CM36651_PS, &cm36651->temp);
++      /*
++       * The PS INT pin is an active low signal that PS INT move logic low
++       * when the object is detect. Once the MCU host received the PS INT
++       * "LOW" signal, the Host needs to read the data at Alert Response
++       * Address(ARA) to clear the PS INT signal. After clearing the PS
++       * INT pin, the PS INT signal toggles from low to high.
++       */
++      ret = i2c_smbus_read_byte(cm36651->ara_client);
+       if (ret < 0) {
+-              dev_err(&client->dev, "read data is failed. %d\n", ret);
+-              return ret;
++              dev_err(&client->dev,
++                              "%s: Data read failed: %d\n", __func__, ret);
++              return IRQ_HANDLED;
+       }
+-
+-      if (cm36651->temp < ps_reg_setting[1][1]) {
++      switch (ret) {
++      case CM36651_CLOSE_PROXIMITY:
+               ev_dir = IIO_EV_DIR_RISING;
+-              val = FAR_PROXIMITY;
+-      } else {
++              break;
++      case CM36651_FAR_PROXIMITY:
+               ev_dir = IIO_EV_DIR_FALLING;
+-              val = CLOSE_PROXIMITY;
++              break;
++      default:
++              dev_err(&client->dev,
++                      "%s: Data read wrong: %d\n", __func__, ret);
++              return IRQ_HANDLED;
+       }
+-      ev_code = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, READ_RAW_PROXIMITY,
+-                                              IIO_EV_TYPE_THRESH, ev_dir);
++      ev_code = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY,
++                              CM36651_CMD_READ_RAW_PROXIMITY,
++                              IIO_EV_TYPE_THRESH, ev_dir);
+       iio_push_event(indio_dev, ev_code, iio_get_time_ns());
+-      cm36651_i2c_read_byte(cm36651, CM36651_PS, &cm36651->temp);
+-      dev_info(&client->dev, "val: %d, ps_data: %d(close:0, far:1)\n",
+-                                                      val, cm36651->temp);
+       return IRQ_HANDLED;
+ }
+-static int cm36651_set_operation_mode(struct cm36651_data *cm36651,
+-                                              enum cm36651_cmd cmd)
++static int cm36651_set_operation_mode(struct cm36651_data *cm36651, int cmd)
+ {
+       struct i2c_client *client = cm36651->client;
+-      int ret = 0;
+-      int i;
++      struct i2c_client *ps_client = cm36651->ps_client;
++      int ret = -EINVAL;
+       switch (cmd) {
+-      case READ_RAW_LIGHT:
+-              ret = cm36651_i2c_write_byte(cm36651, CM36651_ALS,
+-                                                      CS_CONF1, 0x04);
++      case CM36651_CMD_READ_RAW_LIGHT:
++              ret = i2c_smbus_write_byte_data(client, CM36651_CS_CONF1,
++                              cm36651->cs_ctrl_regs[CM36651_CS_CONF1]);
+               break;
+-      case READ_RAW_PROXIMITY:
+-              ret = cm36651_i2c_write_byte(cm36651, CM36651_PS,
+-                                                      PS_CONF1, 0x3C);
++      case CM36651_CMD_READ_RAW_PROXIMITY:
++              if (test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags))
++                      return CM36651_PROXIMITY_EV_EN;
++
++              ret = i2c_smbus_write_byte_data(ps_client, CM36651_PS_CONF1,
++                              cm36651->ps_ctrl_regs[CM36651_PS_CONF1]);
+               break;
+-      case PROX_EV_EN:
+-              if (test_bit(PROXIMITY_EV_EN, &cm36651->flags)) {
+-                      dev_err(&client->dev, "Aleady enable state\n");
+-                      return -EINVAL;
++      case CM36651_CMD_PROX_EV_EN:
++              if (test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags)) {
++                      dev_err(&client->dev,
++                              "Already proximity event enable state\n");
++                      return ret;
+               }
+-              set_bit(PROXIMITY_EV_EN, &cm36651->flags);
++              set_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags);
+-              /* enable setting */
+-              for (i = 0; i < 4; i++) {
+-                      cm36651_i2c_write_byte(cm36651, CM36651_PS,
+-                              ps_reg_setting[i][0], ps_reg_setting[i][1]);
++              ret = i2c_smbus_write_byte_data(ps_client,
++                      cm36651_ps_reg[CM36651_PS_CONF1],
++                      CM36651_PS_INT_EN | CM36651_PS_PERS2 | CM36651_PS_IT2);
++
++              if (ret < 0) {
++                      dev_err(&client->dev, "Proximity enable event failed\n");
++                      return ret;
+               }
+-              enable_irq(client->irq);
+               break;
+-      case PROX_EV_DIS:
+-              if (!test_bit(PROXIMITY_EV_EN, &cm36651->flags)) {
+-                      dev_err(&client->dev, "Aleady disable state\n");
+-                      return -EINVAL;
++      case CM36651_CMD_PROX_EV_DIS:
++              if (!test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags)) {
++                      dev_err(&client->dev,
++                              "Already proximity event disable state\n");
++                      return ret;
+               }
+-              clear_bit(PROXIMITY_EV_EN, &cm36651->flags);
+-              disable_irq(client->irq);
+-
+-              /* disable setting */
+-              cm36651_i2c_write_byte(cm36651, CM36651_PS, PS_CONF1, 0x01);
++              clear_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags);
++              ret = i2c_smbus_write_byte_data(ps_client,
++                                      CM36651_PS_CONF1, CM36651_PS_DISABLE);
+               break;
+       }
++
++      if (ret < 0)
++              dev_err(&client->dev, "Write register failed\n");
++
+       return ret;
+ }
+@@ -384,32 +327,29 @@ static int cm36651_read_channel(struct cm36651_data *cm36651,
+                               struct iio_chan_spec const *chan, int *val)
+ {
+       struct i2c_client *client = cm36651->client;
+-      enum cm36651_cmd cmd = 0;
+-      int ret;
++      int cmd, ret;
+-      switch (chan->scan_index) {
+-      case SCAN_MODE_LIGHT:
+-              cmd = READ_RAW_LIGHT;
+-              break;
+-      case SCAN_MODE_PROX:
+-              cmd = READ_RAW_PROXIMITY;
+-              break;
+-      }
++      if (chan->type == IIO_LIGHT)
++              cmd = CM36651_CMD_READ_RAW_LIGHT;
++      else if (chan->type == IIO_PROXIMITY)
++              cmd = CM36651_CMD_READ_RAW_PROXIMITY;
++      else
++              return -EINVAL;
+       ret = cm36651_set_operation_mode(cm36651, cmd);
+       if (ret < 0) {
+-              dev_err(&client->dev, "cm36651 set operation mode failed\n");
++              dev_err(&client->dev, "CM36651 set operation mode failed\n");
+               return ret;
+       }
+-
++      /* Delay for work after enable operation */
+       msleep(50);
+-      ret = cm36651_read_output(cm36651, chan->address, val);
++      ret = cm36651_read_output(cm36651, chan, val);
+       if (ret < 0) {
+-              dev_err(&client->dev, "cm36651 read output failed\n");
++              dev_err(&client->dev, "CM36651 read output failed\n");
+               return ret;
+       }
+-      return 0;
++      return ret;
+ }
+ static int cm36651_read_raw(struct iio_dev *indio_dev,
+@@ -417,7 +357,7 @@ static int cm36651_read_raw(struct iio_dev *indio_dev,
+                           int *val, int *val2, long mask)
+ {
+       struct cm36651_data *cm36651 = iio_priv(indio_dev);
+-      int ret = -EINVAL;
++      int ret;
+       mutex_lock(&cm36651->lock);
+@@ -425,111 +365,104 @@ static int cm36651_read_raw(struct iio_dev *indio_dev,
+       case IIO_CHAN_INFO_RAW:
+               ret = cm36651_read_channel(cm36651, chan, val);
+               break;
++      default:
++              ret = -EINVAL;
+       }
++
+       mutex_unlock(&cm36651->lock);
+       return ret;
+ }
+-static int cm36651_read_event_val(struct iio_dev *indio_dev,
++static int cm36651_read_prox_thresh(struct iio_dev *indio_dev,
+                                       u64 event_code, int *val)
+ {
+       struct cm36651_data *cm36651 = iio_priv(indio_dev);
+-      int chan_type = IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code);
+-      int event_type = IIO_EVENT_CODE_EXTRACT_TYPE(event_code);
+-      if (event_type != IIO_EV_TYPE_THRESH || chan_type != IIO_PROXIMITY)
++      *val = cm36651->ps_ctrl_regs[CM36651_PS_THD];
++
++      return 0;
++}
++
++static int cm36651_write_prox_thresh(struct iio_dev *indio_dev,
++                                      u64 event_code, int val)
++{
++      struct cm36651_data *cm36651 = iio_priv(indio_dev);
++      struct i2c_client *client = cm36651->client;
++      int ret;
++
++      if (val < 3 || val > 255)
+               return -EINVAL;
+-      *val = cm36651->temp;
++      cm36651->ps_ctrl_regs[CM36651_PS_THD] = val;
++      ret = i2c_smbus_write_byte_data(cm36651->ps_client, CM36651_PS_THD,
++                                      cm36651->ps_ctrl_regs[CM36651_PS_THD]);
++
++      if (ret < 0) {
++              dev_err(&client->dev, "PS threshold write failed: %d\n", ret);
++              return ret;
++      }
++
+       return 0;
+ }
+-static int cm36651_write_event_config(struct iio_dev *indio_dev,
+-                                      u64 event_code, int state)
++static int cm36651_write_prox_event_config(struct iio_dev *indio_dev,
++                                              u64 event_code, int state)
+ {
+       struct cm36651_data *cm36651 = iio_priv(indio_dev);
+-      enum cm36651_cmd cmd;
+-      int chan_type = IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code);
+-      int ret = -EINVAL;
++      int cmd, ret = -EINVAL;
+       mutex_lock(&cm36651->lock);
+-      if (chan_type == IIO_PROXIMITY) {
+-              cmd = state ? PROX_EV_EN : PROX_EV_DIS;
+-              ret = cm36651_set_operation_mode(cm36651, cmd);
+-      }
++      cmd = state ? CM36651_CMD_PROX_EV_EN : CM36651_CMD_PROX_EV_DIS;
++      ret = cm36651_set_operation_mode(cm36651, cmd);
+       mutex_unlock(&cm36651->lock);
+       return ret;
+ }
+-static int cm36651_read_event_config(struct iio_dev *indio_dev, u64 event_code)
++static int cm36651_read_prox_event_config(struct iio_dev *indio_dev, u64 event_code)
+ {
+       struct cm36651_data *cm36651 = iio_priv(indio_dev);
+-      int chan_type = IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code);
+-      int event_en = -EINVAL;
++      int event_en;
+       mutex_lock(&cm36651->lock);
+-      if (chan_type == IIO_PROXIMITY)
+-              event_en = test_bit(PROXIMITY_EV_EN, &cm36651->flags);
++      event_en = test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags);
+       mutex_unlock(&cm36651->lock);
+       return event_en;
+ }
+-static IIO_DEVICE_ATTR(vendor, 0644, cm36651_vendor_show, NULL, 0);
+-static IIO_DEVICE_ATTR(prox_thresh, 0644, proximity_thresh_show,
+-                                      proximity_thresh_store, 1);
+-
+-static struct attribute *cm36651_attributes[] = {
+-      &iio_dev_attr_vendor.dev_attr.attr,
+-      &iio_dev_attr_prox_thresh.dev_attr.attr,
+-      NULL
+-};
+-
+-static struct attribute_group cm36651_attribute_group = {
+-      .attrs = cm36651_attributes,
+-};
++#define CM36651_LIGHT_CHANNEL(_color, _idx) {         \
++      .type = IIO_LIGHT,                              \
++      .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
++      .address = _idx,                                \
++      .modified = 1,                                  \
++      .channel2 = IIO_MOD_LIGHT_##_color,             \
++}                                                     \
+ static const struct iio_chan_spec cm36651_channels[] = {
+       {
+-              .type = IIO_LIGHT,
+-              .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+-              .scan_type = {
+-                      .sign = 'u',
+-                      .realbits = 16,
+-                      .shift = 0,
+-                      .storagebits = 16,
+-              },
+-              .address = CM36651_ALS,
+-              .scan_index = SCAN_MODE_LIGHT
+-      },
+-      {
+               .type = IIO_PROXIMITY,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+-              .scan_type = {
+-                      .sign = 'u',
+-                      .realbits = 8,
+-                      .shift = 0,
+-                      .storagebits = 8,
+-              },
+-              .address = CM36651_PS,
+-              .scan_index = SCAN_MODE_PROX,
+-              .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER)
++              .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER),
+       },
++      CM36651_LIGHT_CHANNEL(RED, CM36651_LIGHT_CHANNEL_IDX_RED),
++      CM36651_LIGHT_CHANNEL(GREEN, CM36651_LIGHT_CHANNEL_IDX_GREEN),
++      CM36651_LIGHT_CHANNEL(BLUE, CM36651_LIGHT_CHANNEL_IDX_BLUE),
++      CM36651_LIGHT_CHANNEL(CLEAR, CM36651_LIGHT_CHANNEL_IDX_CLEAR),
+ };
+ static const struct iio_info cm36651_info = {
+-      .driver_module = THIS_MODULE,
+-      .read_raw = &cm36651_read_raw,
+-      .read_event_value = &cm36651_read_event_val,
+-      .read_event_config = &cm36651_read_event_config,
+-      .write_event_config = &cm36651_write_event_config,
+-      .attrs = &cm36651_attribute_group,
++      .driver_module          = THIS_MODULE,
++      .read_raw               = &cm36651_read_raw,
++      .read_event_value       = &cm36651_read_prox_thresh,
++      .write_event_value      = &cm36651_write_prox_thresh,
++      .read_event_config      = &cm36651_read_prox_event_config,
++      .write_event_config     = &cm36651_write_prox_event_config,
+ };
+ static int cm36651_probe(struct i2c_client *client,
+@@ -537,39 +470,32 @@ static int cm36651_probe(struct i2c_client *client,
+ {
+       struct cm36651_data *cm36651;
+       struct iio_dev *indio_dev;
+-      unsigned long irqflag;
+       int ret;
+-      dev_info(&client->dev, "cm36651 light/proxymity sensor probe\n");
+-
+       indio_dev = iio_device_alloc(sizeof(*cm36651));
+-      if (indio_dev == NULL) {
+-              ret = -ENOMEM;
+-              goto error_ret;
+-      }
++      if (!indio_dev)
++              return -ENOMEM;
+       cm36651 = iio_priv(indio_dev);
+       cm36651->vled_reg = devm_regulator_get(&client->dev, "vled");
+       if (IS_ERR(cm36651->vled_reg)) {
+-              dev_err(&client->dev, "failed to get regulator vled\n");
+-              ret =  PTR_ERR(cm36651->vled_reg);
+-              return ret;
++              dev_err(&client->dev, "get regulator vled failed\n");
++              return PTR_ERR(cm36651->vled_reg);
+       }
+       ret = regulator_enable(cm36651->vled_reg);
+       if (ret) {
+-              dev_err(&client->dev, "faile to enable regulator\n");
+-              goto error_put_reg;
++              dev_err(&client->dev, "enable regulator vled failed\n");
++              return ret;
+       }
+       i2c_set_clientdata(client, indio_dev);
+       cm36651->client = client;
+-      init_waitqueue_head(&cm36651->data_ready_queue);
+-
+-      ret = cm36651_setup_reg(cm36651);
+-
++      cm36651->ps_client = i2c_new_dummy(client->adapter,
++                                                   CM36651_I2C_ADDR_PS);
++      cm36651->ara_client = i2c_new_dummy(client->adapter, CM36651_ARA);
+       mutex_init(&cm36651->lock);
+       indio_dev->dev.parent = &client->dev;
+       indio_dev->channels = cm36651_channels;
+@@ -578,29 +504,32 @@ static int cm36651_probe(struct i2c_client *client,
+       indio_dev->name = id->name;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+-      irqflag = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
+-      ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
+-              &cm36651_irq_handler, irqflag, "proximity_int", indio_dev);
++      ret = cm36651_setup_reg(cm36651);
+       if (ret) {
+-              dev_err(&client->dev, "failed to request irq\n");
+-              goto error_ret;
++              dev_err(&client->dev, "%s: register setup failed\n", __func__);
++              goto error_disable_reg;
+       }
+-      disable_irq(client->irq);
++      ret = request_threaded_irq(client->irq, NULL, cm36651_irq_handler,
++                                      IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
++                                                      "cm36651", indio_dev);
++      if (ret) {
++              dev_err(&client->dev, "%s: request irq failed\n", __func__);
++              goto error_disable_reg;
++      }
+       ret = iio_device_register(indio_dev);
+-      if (ret)
+-              goto exit_free_iio;
++      if (ret) {
++              dev_err(&client->dev, "%s: regist device failed\n", __func__);
++              goto error_free_irq;
++      }
+       return 0;
+-error_ret:
+-      return ret;
+-error_put_reg:
+-      regulator_put(cm36651->vled_reg);
+-      return ret;
+-exit_free_iio:
+-      iio_device_free(indio_dev);
++error_free_irq:
++      free_irq(client->irq, indio_dev);
++error_disable_reg:
++      regulator_disable(cm36651->vled_reg);
+       return ret;
+ }
+@@ -611,29 +540,28 @@ static int cm36651_remove(struct i2c_client *client)
+       iio_device_unregister(indio_dev);
+       regulator_disable(cm36651->vled_reg);
+-
++      free_irq(client->irq, indio_dev);
+       iio_device_free(indio_dev);
+       return 0;
+ }
+ static const struct i2c_device_id cm36651_id[] = {
+-      {"cm36651", 0},
+-      {}
++      { "cm36651", 0 },
++      { }
+ };
+ MODULE_DEVICE_TABLE(i2c, cm36651_id);
+ static const struct of_device_id cm36651_of_match[] = {
+       { .compatible = "capella,cm36651" },
+-      { .compatible = "cm36651"},
+       { }
+ };
+ static struct i2c_driver cm36651_driver = {
+       .driver = {
+               .name   = "cm36651",
+-              .of_match_table = of_match_ptr(cm36651_of_match),
++              .of_match_table = cm36651_of_match,
+               .owner  = THIS_MODULE,
+       },
+       .probe          = cm36651_probe,
+@@ -643,6 +571,6 @@ static struct i2c_driver cm36651_driver = {
+ module_i2c_driver(cm36651_driver);
+-MODULE_AUTHOR("Samsung Electronics");
+-MODULE_DESCRIPTION("Light/Proximity Sensor device driver for cm36651");
++MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
++MODULE_DESCRIPTION("CM36651 proximity/ambient light sensor driver");
+ MODULE_LICENSE("GPL v2");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1072-USB-gadget-s3c-hsotg-skip-suspend-and-resume-when-us.patch b/patches.tizen/1072-USB-gadget-s3c-hsotg-skip-suspend-and-resume-when-us.patch
new file mode 100644 (file)
index 0000000..6ca405e
--- /dev/null
@@ -0,0 +1,44 @@
+From d7af913f71bf83dd0875593ba372f04bb886ba62 Mon Sep 17 00:00:00 2001
+From: Byungsoo Kim <bs1770.kim@samsung.com>
+Date: Fri, 25 Oct 2013 21:37:19 +0900
+Subject: [PATCH 1072/1302] USB: gadget: s3c-hsotg: skip suspend and resume
+ when usb cable wasn't inserted
+
+Although we didn't insert usb cable, s3c_hsotg_suspend and s3c_hsotg_resume were always called and failed.
+
+[  519.686485] s3c-hsotg 12480000.hsotg: Failed to get CSftRst asserted
+[  519.686539] s3c-hsotg 12480000.hsotg: ep0: failed to become enabled (DxEPCTL=0x00000000)
+
+Signed-off-by: Byungsoo Kim <bs1770.kim@samsung.com>
+Change-Id: I084c0436992e5be76b0dd692da44d5a45761c934
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/s3c-hsotg.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
+index 175f35a..7360106 100644
+--- a/drivers/usb/gadget/s3c-hsotg.c
++++ b/drivers/usb/gadget/s3c-hsotg.c
+@@ -3690,6 +3690,8 @@ static int s3c_hsotg_suspend(struct platform_device *pdev, pm_message_t state)
+       if (hsotg->driver)
+               dev_info(hsotg->dev, "suspending usb gadget %s\n", hsotg->driver->driver.name);
++      else
++              return ret;
+       spin_lock_irqsave(&hsotg->lock, flags);
+       s3c_hsotg_disconnect(hsotg);
+@@ -3718,7 +3720,8 @@ static int s3c_hsotg_resume(struct platform_device *pdev)
+               dev_info(hsotg->dev, "resuming usb gadget %s\n", hsotg->driver->driver.name);
+               ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
+                                     hsotg->supplies);
+-      }
++      } else
++              return ret;
+       spin_lock_irqsave(&hsotg->lock, flags);
+       hsotg->last_rst = jiffies;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1073-usb-gadget-slp-fix-wrong-destory-function.patch b/patches.tizen/1073-usb-gadget-slp-fix-wrong-destory-function.patch
new file mode 100644 (file)
index 0000000..73f8339
--- /dev/null
@@ -0,0 +1,74 @@
+From a8afd34a0a2d279cc6a435cacee95261a080a7e2 Mon Sep 17 00:00:00 2001
+From: Seung-Woo Kim <sw0312.kim@samsung.com>
+Date: Fri, 8 Nov 2013 20:48:18 +0900
+Subject: [PATCH 1073/1302] usb: gadget: slp: fix wrong destory function
+
+The device_destroy() unregisters and destroys the struct dev
+created by device_create(). But in destroy function, it calls for
+each file created by device_create_file(). So this causes wrong
+memory access like following.
+
+[    2.804348] usb_mode: can't probe composite
+[    2.808239] Unable to handle kernel NULL pointer dereference at virtual address 00000034
+[    2.816064] pgd = c0004000
+[    2.818713] [00000034] *pgd=00000000
+[    2.822289] Internal error: Oops: 5 [#1] PREEMPT SMP ARM
+[    2.827570] Modules linked in:
+[    2.830612] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 3.10.14-g86225b5 #89
+[    2.837465] task: df9f8000 ti: df9f4000 task.ti: df9f4000
+[    2.842859] PC is at sysfs_find_dirent+0x8/0xf0
+[    2.847358] LR is at sysfs_get_dirent+0x28/0x78
+[    2.851873] pc : [<c0158ee4>]    lr : [<c01590ac>]    psr: 40000113
+[    2.851873] sp : df9f5ea0  ip : 00000000  fp : 00000000
+[    2.863329] r10: 00000077  r9 : c0735d90  r8 : c071bc84
+[    2.868537] r7 : df209000  r6 : 00000000  r5 : c04f52d0  r4 : 00000000
+[    2.875046] r3 : 00000000  r2 : c04f52d0  r1 : 00000000  r0 : 00000000
+[    2.881558] Flags: nZcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
+[    2.888848] Control: 10c53c7d  Table: 4000404a  DAC: 00000015
+[    2.894577] Process swapper/0 (pid: 1, stack limit = 0xdf9f4238)
+[    2.900568] Stack: (0xdf9f5ea0 to 0xdf9f6000)
+[    2.904912] 5ea0: 00000000 c04f52d0 00000000 df209000 c071bc84 c01590ac c0783420 df209008
+[    2.913069] 5ec0: c0857f34 c015a6b0 df9f8000 df209000 df209008 c02b596c df209000 df209008
+[    2.921228] 5ee0: c0857f34 c078531c c071bc84 c02b491c 00000000 df209000 df209200 c02ac504
+[    2.929387] 5f00: df209000 ffffffed c0857f34 c02ac668 df208e00 c071be80 c0668e70 c02af718
+[    2.937546] 5f20: df9f4000 c07a4e00 c0726f18 00000000 c071bc84 c00086d4 00000000 00000000
+[    2.945706] 5f40: c062bed8 c06ca4ec 00000007 00000007 c06f74d0 c0726f38 00000007 c0726f18
+[    2.953864] 5f60: c07a4e00 c06f74d0 c0735d90 00000077 00000000 c06f7b98 00000007 00000007
+[    2.962023] 5f80: c06f74d0 c004ed8c 00000000 c04b0f20 00000000 00000000 00000000 00000000
+[    2.970183] 5fa0: 00000000 c04b0f28 00000000 c000eb28 00000000 00000000 00000000 00000000
+[    2.974920] ymu831 irq_handler
+[    2.974944] ymu831 irq_func
+[    2.984158] 5fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
+[    2.992317] 5fe0: 00000000 00000000 00000000 00000000 00000013 00000000 08800040 05008140
+[    3.000500] [<c0158ee4>] (sysfs_find_dirent+0x8/0xf0) from [<df209008>] (0xdf209008)
+[    3.008205] Code: e5838000 eafffff6 e92d41f0 e2913000 (e1d0e3b4)
+[    3.014323] ---[ end trace a753dab553aa7e18 ]---
+
+Change-Id: I58924574a3673dc8eaaea8556cd64f453344cdf3
+Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/slp.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/gadget/slp.c b/drivers/usb/gadget/slp.c
+index 0a5fec4..45536b4 100644
+--- a/drivers/usb/gadget/slp.c
++++ b/drivers/usb/gadget/slp.c
+@@ -1249,11 +1249,11 @@ static void slp_multi_destroy_device(struct slp_multi_dev *smdev)
+       struct device_attribute *attr;
+       while ((attr = *attrs++))
+-              device_destroy(slp_multi_class, smdev->dev->devt);
++              device_remove_file(smdev->dev, attr);
+       dev_set_drvdata(smdev->dev, NULL);
+-      device_unregister(smdev->dev);
++      device_destroy(slp_multi_class, smdev->dev->devt);
+ }
+ static CLASS_ATTR_STRING(version, S_IRUSR | S_IRGRP | S_IROTH,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1074-USB-gadget-s3c-hsotg-fix-maxpacket-size-in-s3c_hsotg.patch b/patches.tizen/1074-USB-gadget-s3c-hsotg-fix-maxpacket-size-in-s3c_hsotg.patch
new file mode 100644 (file)
index 0000000..5e465fd
--- /dev/null
@@ -0,0 +1,41 @@
+From b39ef9dd4f4f229b6856149badafaf90c8d91e17 Mon Sep 17 00:00:00 2001
+From: Robert Baldyga <r.baldyga@samsung.com>
+Date: Thu, 5 Dec 2013 11:32:22 +0100
+Subject: [PATCH 1074/1302] USB: gadget: s3c-hsotg: fix maxpacket size in
+ s3c_hsotg_irq_enumdone
+
+This patch set maximum possible maxpacket value for each speed. Previous
+values didn't allow to use maxpacket sizes greater than 64 in full speed
+and 512 in high speed, although hardware is able to handle up to 1023 in fs
+and 1024 in hs.
+
+Signed-off-by: Robert Baldyga <r.baldyga@samsung.com>
+Change-Id: I5a1b687958afb08000d3a86e68c5df7b343cc08d
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/s3c-hsotg.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
+index 7360106..3bab054 100644
+--- a/drivers/usb/gadget/s3c-hsotg.c
++++ b/drivers/usb/gadget/s3c-hsotg.c
+@@ -2054,13 +2054,13 @@ static void s3c_hsotg_irq_enumdone(struct s3c_hsotg *hsotg)
+       case DSTS_EnumSpd_FS48:
+               hsotg->gadget.speed = USB_SPEED_FULL;
+               ep0_mps = EP0_MPS_LIMIT;
+-              ep_mps = 64;
++              ep_mps = 1023;
+               break;
+       case DSTS_EnumSpd_HS:
+               hsotg->gadget.speed = USB_SPEED_HIGH;
+               ep0_mps = EP0_MPS_LIMIT;
+-              ep_mps = 512;
++              ep_mps = 1024;
+               break;
+       case DSTS_EnumSpd_LS:
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1075-USB-gadget-s3c-hsotg-add-flush-TX-FIFO-when-kill-all.patch b/patches.tizen/1075-USB-gadget-s3c-hsotg-add-flush-TX-FIFO-when-kill-all.patch
new file mode 100644 (file)
index 0000000..63ae9e7
--- /dev/null
@@ -0,0 +1,36 @@
+From 4a19d28091034dc7d6a028139bcf578a6a1d8d70 Mon Sep 17 00:00:00 2001
+From: Robert Baldyga <r.baldyga@samsung.com>
+Date: Thu, 5 Dec 2013 15:04:19 +0100
+Subject: [PATCH 1075/1302] USB: gadget: s3c-hsotg: add flush TX FIFO when kill
+ all requests
+
+This patch adds flushing TX FIFO in kill_all_requests() function in
+dedicated-fifo mode. It's because when requests are killed (when endpoint is
+disabled or in case of device reset/disconnection) in FIFO can stay some
+unsent data. In the worst case FIFO can stay full, and then if endpoint will
+be back enabled, sending new data will be impossible.
+
+Signed-off-by: Robert Baldyga <r.baldyga@samsung.com>
+Change-Id: Ibdb3d3f14f665d096ad944fb3ad79d25ff11625a
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/s3c-hsotg.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
+index 3bab054..6e4aefe 100644
+--- a/drivers/usb/gadget/s3c-hsotg.c
++++ b/drivers/usb/gadget/s3c-hsotg.c
+@@ -2124,6 +2124,9 @@ static void kill_all_requests(struct s3c_hsotg *hsotg,
+               s3c_hsotg_complete_request(hsotg, ep, req,
+                                          result);
+       }
++      if (hsotg->dedicated_fifos)
++              if ((readl(hsotg->regs + DTXFSTS(ep->index)) & 0xffff) * 4 < 3072)
++                      s3c_hsotg_txfifo_flush(hsotg, ep->index);
+ }
+ #define call_gadget(_hs, _entry) \
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1076-drivers-clk-samsung-fix-build-dependency-for-exynos4.patch b/patches.tizen/1076-drivers-clk-samsung-fix-build-dependency-for-exynos4.patch
new file mode 100644 (file)
index 0000000..5cdacdc
--- /dev/null
@@ -0,0 +1,28 @@
+From 9d22d94e4eb14d828b2f224c0b4e5ff8da02532f Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Mon, 13 Jan 2014 08:39:19 +0100
+Subject: [PATCH 1076/1302] drivers: clk: samsung: fix build dependency for
+ exynos4 audss clocks
+
+Fix build break for non-exynos Samsung builds.
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-Id: Ib954cffbfd249e4122598171566123b8d5f24deb
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/samsung/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
+index ec86c33..5d70a6c 100644
+--- a/drivers/clk/samsung/Makefile
++++ b/drivers/clk/samsung/Makefile
+@@ -6,4 +6,4 @@ obj-$(CONFIG_COMMON_CLK)       += clk.o clk-pll.o
+ obj-$(CONFIG_ARCH_EXYNOS4)    += clk-exynos4.o
+ obj-$(CONFIG_SOC_EXYNOS5250)  += clk-exynos5250.o
+ obj-$(CONFIG_SOC_EXYNOS5440)  += clk-exynos5440.o
+-obj-$(CONFIG_PLAT_SAMSUNG)    += clk-exynos4-audss.o
++obj-$(CONFIG_ARCH_EXYNOS4)    += clk-exynos4-audss.o
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1077-drivers-mmc-s3c-sdhci-select-required-sdhci-platform.patch b/patches.tizen/1077-drivers-mmc-s3c-sdhci-select-required-sdhci-platform.patch
new file mode 100644 (file)
index 0000000..e1cb9ae
--- /dev/null
@@ -0,0 +1,31 @@
+From 29499efdc03b06579469ba33af071794e87decef Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Mon, 13 Jan 2014 08:40:05 +0100
+Subject: [PATCH 1077/1302] drivers: mmc: s3c-sdhci: select required sdhci
+ platform driver
+
+s3c-sdhci requires sdhci platform driver, so add this dependency to
+Kcofig entry.
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-Id: I62c834664a154f38f19b0597673748bad98f7640
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mmc/host/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
+index 9ab8f8d..485f178 100644
+--- a/drivers/mmc/host/Kconfig
++++ b/drivers/mmc/host/Kconfig
+@@ -181,6 +181,7 @@ config MMC_SDHCI_TEGRA
+ config MMC_SDHCI_S3C
+       tristate "SDHCI support on Samsung S3C SoC"
+       depends on MMC_SDHCI && PLAT_SAMSUNG
++      select MMC_SDHCI_PLTFM
+       help
+         This selects the Secure Digital Host Controller Interface (SDHCI)
+         often referrered to as the HSMMC block in some of the Samsung S3C
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1078-extcon-max77693-Differentiate-info-message-for-easie.patch b/patches.tizen/1078-extcon-max77693-Differentiate-info-message-for-easie.patch
new file mode 100644 (file)
index 0000000..8dd3fdc
--- /dev/null
@@ -0,0 +1,60 @@
+From 04eacfb107cb0d68ee960ab7e7336e6e88d0c694 Mon Sep 17 00:00:00 2001
+From: Dmitry Kasatkin <d.kasatkin@samsung.com>
+Date: Fri, 10 Jan 2014 20:04:42 +0900
+Subject: [PATCH 1078/1302] extcon: max77693: Differentiate info message for
+ easier debugging
+
+Change-Id: Ie02b0c71100815601e40391c67cb176dca67e683
+Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+[Author information corrected]
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/extcon/extcon-max77693.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c
+index eda131c..3cde41b4 100644
+--- a/drivers/extcon/extcon-max77693.c
++++ b/drivers/extcon/extcon-max77693.c
+@@ -488,7 +488,7 @@ static int max77693_muic_dock_handler(struct max77693_muic_info *info,
+       char dock_name[CABLE_NAME_MAX];
+       dev_info(info->dev,
+-              "external connector is %s (adc:0x%02x)\n",
++              "external connector (doc) is %s (adc:0x%02x)\n",
+               attached ? "attached" : "detached", cable_type);
+       switch (cable_type) {
+@@ -651,7 +651,7 @@ static int max77693_muic_jig_handler(struct max77693_muic_info *info,
+       u8 path = CONTROL1_SW_OPEN;
+       dev_info(info->dev,
+-              "external connector is %s (adc:0x%02x)\n",
++              "external connector (jig) is %s (adc:0x%02x)\n",
+               attached ? "attached" : "detached", cable_type);
+       switch (cable_type) {
+@@ -697,7 +697,7 @@ static int max77693_muic_adc_handler(struct max77693_muic_info *info)
+                               MAX77693_CABLE_GROUP_ADC, &attached);
+       dev_info(info->dev,
+-              "external connector is %s (adc:0x%02x, prev_adc:0x%x)\n",
++              "external connector (adc) is %s (adc:0x%02x, prev_adc:0x%x)\n",
+               attached ? "attached" : "detached", cable_type,
+               info->prev_cable_type);
+@@ -806,7 +806,7 @@ static int max77693_muic_chg_handler(struct max77693_muic_info *info)
+                               MAX77693_CABLE_GROUP_CHG, &attached);
+       dev_info(info->dev,
+-              "external connector is %s(chg_type:0x%x, prev_chg_type:0x%x)\n",
++              "external connector (chg) is %s(chg_type:0x%x, prev_chg_type:0x%x)\n",
+                       attached ? "attached" : "detached",
+                       chg_type, info->prev_chg_type);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1079-extcon-max77693-Force-using-UART-path-for-jig.patch b/patches.tizen/1079-extcon-max77693-Force-using-UART-path-for-jig.patch
new file mode 100644 (file)
index 0000000..f222dc4
--- /dev/null
@@ -0,0 +1,49 @@
+From ec05e8de55043b87a1dafccec5477db9a6ecf9a1 Mon Sep 17 00:00:00 2001
+From: Dmitry Kasatkin <d.kasatkin@samsung.com>
+Date: Fri, 10 Jan 2014 20:13:40 +0900
+Subject: [PATCH 1079/1302] extcon: max77693: Force using UART path for jig
+
+When USB cable is connected to jig, device disables console.
+This patch forces using UART when jig cable is connected.
+It allows to charge the device, which also prevents it from sleeping.
+
+Change-Id: Ie0c8c29f40cdbed5cdad608950a6c5c428cd0fab
+Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+[Author information corrected and style fixed.]
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/extcon/extcon-max77693.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c
+index 3cde41b4..903c507 100644
+--- a/drivers/extcon/extcon-max77693.c
++++ b/drivers/extcon/extcon-max77693.c
+@@ -293,10 +293,18 @@ static int max77693_muic_set_path(struct max77693_muic_info *info,
+               return ret;
+       }
+-      if (attached)
+-              ctrl1 = val;
+-      else
++      if (attached) {
++              if (info->prev_cable_type ==
++                  MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF) {
++                      /* if cable_type is jig, then force UART */
++                      dev_info(info->dev, "For jig force using UART path\n");
++                      ctrl1 = CONTROL1_SW_UART;
++              } else {
++                      ctrl1 = val;
++              }
++      } else {
+               ctrl1 = CONTROL1_SW_OPEN;
++      }
+       ret = max77693_update_reg(info->max77693->regmap_muic,
+                       MAX77693_MUIC_REG_CTRL1, ctrl1, COMP_SW_MASK);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1080-mmc-dw_mmc-change-the-blk-setting-value-for-eMMC.patch b/patches.tizen/1080-mmc-dw_mmc-change-the-blk-setting-value-for-eMMC.patch
new file mode 100644 (file)
index 0000000..916e773
--- /dev/null
@@ -0,0 +1,41 @@
+From c7581cc54899f53610c83dcbfbc2fec33feba494 Mon Sep 17 00:00:00 2001
+From: Jaehoon Chung <jh80.chung@samsung.com>
+Date: Mon, 20 Jan 2014 12:46:10 +0900
+Subject: [PATCH 1080/1302] mmc: dw_mmc: change the blk-setting value for eMMC
+
+Change the blk-setting value.
+
+(benchmark : iozone, tiotest)
+Before applied this patch,
+      Read : 17MB/s, Write : 71MB/s
+After applied this patch,
+      Read : 30MB/s, Write : 72MB/s
+
+Increased the Read performance.
+
+Change-Id: I64142e97aea3aa7ac3d1ca78726f8dd3c133692d
+Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/mmc/host/dw_mmc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
+index 95e6ba8..3044395 100644
+--- a/drivers/mmc/host/dw_mmc.c
++++ b/drivers/mmc/host/dw_mmc.c
+@@ -2021,9 +2021,9 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
+ #ifdef CONFIG_MMC_DW_IDMAC
+               mmc->max_segs = host->ring_size;
+               mmc->max_blk_size = 65536;
+-              mmc->max_blk_count = host->ring_size;
+               mmc->max_seg_size = 0x1000;
+-              mmc->max_req_size = mmc->max_seg_size * mmc->max_blk_count;
++              mmc->max_req_size = mmc->max_seg_size * host->ring_size;
++              mmc->max_blk_count = mmc->max_req_size / 512;
+ #else
+               mmc->max_segs = 64;
+               mmc->max_blk_size = 65536; /* BLKSIZ is 16 bits */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1081-spec-file-cleanup-and-linux-kernel-sources-package-r.patch b/patches.tizen/1081-spec-file-cleanup-and-linux-kernel-sources-package-r.patch
new file mode 100644 (file)
index 0000000..1f28368
--- /dev/null
@@ -0,0 +1,230 @@
+From 6dfeb8242bb16bc48c13738b9d4f28a8a558f8b0 Mon Sep 17 00:00:00 2001
+From: Jacek Pielaszkiewicz <j.pielaszkie@samsung.com>
+Date: Fri, 10 Jan 2014 17:25:10 +0100
+Subject: [PATCH 1081/1302] *spec file cleanup and linux-kernel-sources package
+ removal.
+
+The following changes have been implemented:
+1. linux-kernel-sources package has been removed. devel package
+   is enough to correctly linux-kernel-build external kernel modules.
+
+2. Symbolic link that points pre-build kernel sources has been added.
+   The link is located in /lib/modules/__kernel_version__.
+
+3. Rename linux-kernel-headers package on linux-kernel-user-headers.
+
+Change-Id: I6e1a4283d832a5fced7fafbb8fefc9c369364f59
+Signed-off-by: Jacek Pielaszkiewicz <j.pielaszkie@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ packaging/linux-kernel.spec | 117 ++++++++++++++++++--------------------------
+ 1 file changed, 47 insertions(+), 70 deletions(-)
+
+diff --git a/packaging/linux-kernel.spec b/packaging/linux-kernel.spec
+index 84a4db8..06ac61a 100644
+--- a/packaging/linux-kernel.spec
++++ b/packaging/linux-kernel.spec
+@@ -2,6 +2,7 @@
+ %define abiver 1
+ %define build_id %{config_name}.%{abiver}
+ %define defaultDtb exynos4412-m0.dtb
++%define buildarch arm
+ Name: linux-kernel
+ Summary: The Linux Kernel
+@@ -18,99 +19,82 @@ BuildRequires: linux-glibc-devel
+ BuildRequires: u-boot-tools
+ BuildRequires: bc
+-%define kernel_build_dir_name .%{name}-%{version}-%{build_id}
+-%define kernel_build_dir %{_builddir}/%{name}-%{version}/%{kernel_build_dir_name}
+-
+ %description
+ The Linux Kernel, the operating system core itself
+-%package headers
++%package user-headers
+ Summary: Header files for the Linux kernel for use by glibc
+ Group: Development/System
+ Obsoletes: kernel-headers
+ Provides: kernel-headers = %{version}
+-%description headers
++%description user-headers
+ Kernel-headers includes the C header files that specify the interface
+ between the Linux kernel and userspace libraries and programs.  The
+ header files define structures and constants that are needed for
+ building most standard programs and are also needed for rebuilding the
+ glibc package.
+-%package sources
+-Summary: Full linux kernel sources for out-of-tree modules
+-Group: Development/System
+-Provides: kernel-sources = %{version}-%{build_id}
+-
+-%description sources
+-Full linux kernel sources for out-of-tree modules.
+-
+-%package build
++%package devel
+ Summary: Prebuilt linux kernel for out-of-tree modules
+ Group: Development/System
+-Requires: kernel-sources = %{version}-%{build_id}
+-%description build
++%description devel
+ Prebuilt linux kernel for out-of-tree modules.
+-%package uImage
++%package image
+ Summary: Linux kernel image
+ Group: Development/System
+-%description uImage
++%description image
+ Linux kernel uImage
+ %prep
+ %setup -q
+ %build
+-# 1. Create main build directory
+-rm -rf %{kernel_build_dir}
+-mkdir -p %{kernel_build_dir}
+-
+-# 2. Create tar archive for sources
+-tar cpsf %{kernel_build_dir}/linux-kernel-sources-%{version}-%{build_id}.tar . --one-file-system --exclude ".git*"
+-
+-# 3. Create kernel build directory
+-mkdir -p %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}
+-
+-# 4. Compile sources
+-make EXTRAVERSION="-%{build_id}" O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} %{config_name}
+-make EXTRAVERSION="-%{build_id}" O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} %{?_smp_mflags}
+-
+-# 4.1 Build uImage
+-make EXTRAVERSION="-%{build_id}" O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} zImage %{?_smp_mflags}
+-make EXTRAVERSION="-%{build_id}" O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} dtbs %{?_smp_mflags}
+-cat %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/arch/arm/boot/zImage %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/arch/arm/boot/dts/%{defaultDtb}  > bImage
++# 1. Compile sources
++make EXTRAVERSION="-%{build_id}" %{config_name}
++make EXTRAVERSION="-%{build_id}" %{?_smp_mflags}
++
++# 2. Build uImage
++make EXTRAVERSION="-%{build_id}" zImage %{?_smp_mflags}
++make EXTRAVERSION="-%{build_id}" dtbs %{?_smp_mflags}
++cat arch/arm/boot/zImage arch/arm/boot/dts/%{defaultDtb}  > bImage
+ mkimage -A arm -C none -O linux -a 40008000 -e 40008000 -n 'Linux 3.10 Tizen kernel' -d bImage uImage
+-# 5. Update Makefile in output build
+-cat %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/Makefile | sed 's/\/home\/abuild\/rpmbuild\/BUILD\/%{name}-%{version}/\/usr\/src\/linux-kernel-sources-%{version}-%{build_id}/' > %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/Makefile.new
+-mv %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/Makefile.new %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/Makefile
+-rm -f %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}/Makefile.new
++# 3. Build modules
++#make EXTRAVERSION="-%{build_id}" modules %{?_smp_mflags}
+-# 6. Create tar repo for build directory
+-( cd %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} ; tar cpsf %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}.tar . )
++# 4. Create tar repo for build directory
++tar cpsf linux-kernel-build-%{version}-%{build_id}.tar .
+ %install
+ QA_SKIP_BUILD_ROOT="DO_NOT_WANT"; export QA_SKIP_BUILD_ROOT
+ # 1. Destynation directories
+-mkdir -p %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}
+ mkdir -p %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}
++mkdir -p %{buildroot}/lib/modules/%{version}-%{build_id}
+ mkdir -p %{buildroot}/boot/
+ # 2. Install uImage
+ install uImage %{buildroot}/boot/
+-# 3. Restore source and build irectory
+-tar -xf %{kernel_build_dir}/linux-kernel-sources-%{version}-%{build_id}.tar -C %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}
+-tar -xf %{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id}.tar   -C %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}
++# 3. Install modules
++#make INSTALL_MOD_PATH=%{buildroot} modules_install
+ # 4. Install kernel headers
+-make INSTALL_PATH=%{buildroot} INSTALL_MOD_PATH=%{buildroot} O=%{kernel_build_dir}/linux-kernel-build-%{version}-%{build_id} INSTALL_HDR_PATH=%{buildroot}/usr headers_install
++make INSTALL_PATH=%{buildroot} INSTALL_MOD_PATH=%{buildroot} INSTALL_HDR_PATH=%{buildroot}/usr headers_install
+-# 5. Remove files
++# 5. Restore source and build irectory
++tar -xf linux-kernel-build-%{version}-%{build_id}.tar -C %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}
++mv %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/arch/%{buildarch} .
++mv %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/arch/Kconfig .
++rm -rf %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/arch/*
++mv %{buildarch} %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/arch/
++mv Kconfig      %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/arch/
++
++# 6. Remove files
+ find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name ".tmp_vmlinux1" -exec rm -f {} \;
+ find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name ".tmp_vmlinux2" -exec rm -f {} \;
+ find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "vmlinux" -exec rm -f {} \;
+@@ -122,46 +106,39 @@ find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "\.*dt
+ find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.*tmp" -exec rm -f {} \;
+ find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.S" -exec rm -f {} \;
+ find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.ko" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.o" -exec rm -f {} \;
+-
+-find %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id} -name "*.c" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.c" -exec rm -f {} \;
+ find %{buildroot}/usr -name "..install.cmd" -exec rm -f {} \;
+-
+ find %{buildroot}/usr/include -name "\.\.install.cmd"  -exec rm -f {} \;
+ find %{buildroot}/usr/include -name "\.install"  -exec rm -f {} \;
+-rm -rf %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}/%{kernel_build_dir_name}
+-rm -f %{buildroot}/usr/src/linux-kernel-sources-%{version}-%{build_id}/source
+-rm -f %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/source
+-
++rm -f  %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/source
+ rm -rf %{buildroot}/System.map*
+ rm -rf %{buildroot}/vmlinux*
+-
+ rm -rf %{buildroot}/boot/System.map*
+ rm -rf %{buildroot}/boot/vmlinux*
+-# 6. Create symbolic links
+-ln -sf /usr/src/linux-kernel-sources-%{version}-%{build_id} %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/source
+-ln -sf /usr/src/linux-kernel-build-%{version}-%{build_id}   %{buildroot}/usr/src/linux-kernel-build-current
+-ln -sf /usr/src/linux-kernel-sources-%{version}-%{build_id} %{buildroot}/usr/src/linux-kernel-sources-current
++# 7. Create symbolic links
++rm -f %{buildroot}/usr/src/linux-kernel-build-current
++rm -f %{buildroot}/lib/modules/%{version}-%{build_id}/build
++rm -f %{buildroot}/lib/modules/%{version}-%{build_id}/source
++ln -sf /usr/src/linux-kernel-build-%{version}-%{build_id} %{buildroot}/lib/modules/%{version}-%{build_id}/build
+ %clean
+ rm -rf %{buildroot}
+-%files headers
++%files user-headers
+ %defattr (-, root, root)
+ /usr/include
+-%files sources
+-%defattr (-, root, root)
+-/usr/src/linux-kernel-sources-%{version}-%{build_id}
+-/usr/src/linux-kernel-sources-current
+-
+-%files build
++%files devel
+ %defattr (-, root, root)
+ /usr/src/linux-kernel-build-%{version}-%{build_id}
+-/usr/src/linux-kernel-build-current
++#/lib/modules/%{version}-%{build_id}/kernel
++/lib/modules/%{version}-%{build_id}/build
++#/lib/modules/%{version}-%{build_id}/modules.*
+-%files uImage
++%files image
+ /boot/uImage
++#/lib/modules/%{version}-%{build_id}/kernel
++#/lib/modules/%{version}-%{build_id}/modules.*
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1082-Bring-kernel-packaging-in-line-with-ivi-s-kernel.patch b/patches.tizen/1082-Bring-kernel-packaging-in-line-with-ivi-s-kernel.patch
new file mode 100644 (file)
index 0000000..4e8d660
--- /dev/null
@@ -0,0 +1,205 @@
+From 25d4523d0734e4fb0598487127619058a5f63363 Mon Sep 17 00:00:00 2001
+From: Jacek Pielaszkiewicz <j.pielaszkie@samsung.com>
+Date: Mon, 13 Jan 2014 12:58:43 +0100
+Subject: [PATCH 1082/1302] Bring kernel packaging in line with ivi's kernel.
+
+The following changes have been implemented:
+
+1. Add provides to for linux-kernel, linux-kernel-devel packages.
+
+  The following "Provides" have been added:
+  - kernel               - package linux-kernel
+  - kernel-uname-r       - package linux-kernel
+  - kernel-devel         - package linux-kernel-devel
+  - kernel-devel-uname-r - package linux-kernel-devel
+
+2. Remove linux-kernel-uImage package.
+
+3. linux-kernel package has been extended to deliver uImage and
+   kernel modules (in /boot directory)
+
+4. Rename linux-kenrel-build package to linux-kernel-devel.
+
+4. Extend linux-kernel-devel by the content of /lib/modules/kernel
+   directory.
+
+Change-Id: I824a307327d56c63c7cfc7eb6124d4fa10e1f49a
+Signed-off-by: Jacek Pielaszkiewicz <j.pielaszkie@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ packaging/linux-kernel.spec | 100 ++++++++++++++++++++++----------------------
+ 1 file changed, 50 insertions(+), 50 deletions(-)
+
+diff --git a/packaging/linux-kernel.spec b/packaging/linux-kernel.spec
+index 06ac61a..935e62f 100644
+--- a/packaging/linux-kernel.spec
++++ b/packaging/linux-kernel.spec
+@@ -15,10 +15,15 @@ URL: http://www.kernel.org
+ Source0:   %{name}-%{version}-%{build_id}.tar.gz
+ BuildRoot: %{_tmppath}/%{name}-%{PACKAGE_VERSION}-root
++%define fullVersion %{version}-%{build_id}
++
+ BuildRequires: linux-glibc-devel
+ BuildRequires: u-boot-tools
+ BuildRequires: bc
++Provides: kernel = %{version}-%{release}
++Provides: kernel-uname-r = %{fullVersion}
++
+ %description
+ The Linux Kernel, the operating system core itself
+@@ -26,7 +31,7 @@ The Linux Kernel, the operating system core itself
+ Summary: Header files for the Linux kernel for use by glibc
+ Group: Development/System
+ Obsoletes: kernel-headers
+-Provides: kernel-headers = %{version}
++Provides: kernel-headers = %{version}-%{release}
+ %description user-headers
+ Kernel-headers includes the C header files that specify the interface
+@@ -38,17 +43,12 @@ glibc package.
+ %package devel
+ Summary: Prebuilt linux kernel for out-of-tree modules
+ Group: Development/System
++Provides: kernel-devel = %{fullVersion}
++Provides: kernel-devel-uname-r = %{fullVersion}
+ %description devel
+ Prebuilt linux kernel for out-of-tree modules.
+-%package image
+-Summary: Linux kernel image
+-Group: Development/System
+-
+-%description image
+-Linux kernel uImage
+-
+ %prep
+ %setup -q
+@@ -64,65 +64,63 @@ cat arch/arm/boot/zImage arch/arm/boot/dts/%{defaultDtb}  > bImage
+ mkimage -A arm -C none -O linux -a 40008000 -e 40008000 -n 'Linux 3.10 Tizen kernel' -d bImage uImage
+ # 3. Build modules
+-#make EXTRAVERSION="-%{build_id}" modules %{?_smp_mflags}
++make EXTRAVERSION="-%{build_id}" modules %{?_smp_mflags}
+ # 4. Create tar repo for build directory
+-tar cpsf linux-kernel-build-%{version}-%{build_id}.tar .
++tar cpsf linux-kernel-build-%{fullVersion}.tar .
+ %install
+ QA_SKIP_BUILD_ROOT="DO_NOT_WANT"; export QA_SKIP_BUILD_ROOT
+ # 1. Destynation directories
+-mkdir -p %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}
+-mkdir -p %{buildroot}/lib/modules/%{version}-%{build_id}
++mkdir -p %{buildroot}/usr/src/linux-kernel-build-%{fullVersion}
++mkdir -p %{buildroot}/lib/modules/%{fullVersion}
+ mkdir -p %{buildroot}/boot/
+-# 2. Install uImage
+-install uImage %{buildroot}/boot/
++# 2. Install uImage, System.map, ...
++install -m 755 uImage %{buildroot}/boot/
++install -m 644 System.map %{buildroot}/boot/System.map-%{fullVersion}
++install -m 644 .config %{buildroot}/boot/config-%{fullVersion}
+ # 3. Install modules
+-#make INSTALL_MOD_PATH=%{buildroot} modules_install
++make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=%{buildroot} modules_install
+ # 4. Install kernel headers
+ make INSTALL_PATH=%{buildroot} INSTALL_MOD_PATH=%{buildroot} INSTALL_HDR_PATH=%{buildroot}/usr headers_install
+ # 5. Restore source and build irectory
+-tar -xf linux-kernel-build-%{version}-%{build_id}.tar -C %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}
+-mv %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/arch/%{buildarch} .
+-mv %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/arch/Kconfig .
+-rm -rf %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/arch/*
+-mv %{buildarch} %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/arch/
+-mv Kconfig      %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/arch/
++tar -xf linux-kernel-build-%{fullVersion}.tar -C %{buildroot}/usr/src/linux-kernel-build-%{fullVersion}
++mv %{buildroot}/usr/src/linux-kernel-build-%{fullVersion}/arch/%{buildarch} .
++mv %{buildroot}/usr/src/linux-kernel-build-%{fullVersion}/arch/Kconfig .
++rm -rf %{buildroot}/usr/src/linux-kernel-build-%{fullVersion}/arch/*
++mv %{buildarch} %{buildroot}/usr/src/linux-kernel-build-%{fullVersion}/arch/
++mv Kconfig      %{buildroot}/usr/src/linux-kernel-build-%{fullVersion}/arch/
+ # 6. Remove files
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name ".tmp_vmlinux1" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name ".tmp_vmlinux2" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "vmlinux" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "uImage" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "zImage" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*.cmd" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.o" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "\.*dtb*tmp" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.*tmp" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.S" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.ko" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id} -name "*\.c" -exec rm -f {} \;
+-
+-find %{buildroot}/usr -name "..install.cmd" -exec rm -f {} \;
+-find %{buildroot}/usr/include -name "\.\.install.cmd"  -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name ".tmp_vmlinux*" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "\.*dtb*tmp" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "*\.*tmp" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "vmlinux" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "uImage" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "zImage" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "*.cmd" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "*\.ko" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "*\.o" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "*\.S" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "*\.c" -exec rm -f {} \;
+ find %{buildroot}/usr/include -name "\.install"  -exec rm -f {} \;
++find %{buildroot}/usr -name "..install.cmd" -exec rm -f {} \;
+-rm -f  %{buildroot}/usr/src/linux-kernel-build-%{version}-%{build_id}/source
++rm -rf %{buildroot}/boot/vmlinux*
+ rm -rf %{buildroot}/System.map*
+ rm -rf %{buildroot}/vmlinux*
+-rm -rf %{buildroot}/boot/System.map*
+-rm -rf %{buildroot}/boot/vmlinux*
+ # 7. Create symbolic links
+-rm -f %{buildroot}/usr/src/linux-kernel-build-current
+-rm -f %{buildroot}/lib/modules/%{version}-%{build_id}/build
+-rm -f %{buildroot}/lib/modules/%{version}-%{build_id}/source
+-ln -sf /usr/src/linux-kernel-build-%{version}-%{build_id} %{buildroot}/lib/modules/%{version}-%{build_id}/build
++rm -f %{buildroot}/lib/modules/%{fullVersion}/build
++rm -f %{buildroot}/lib/modules/%{fullVersion}/source
++ln -sf /usr/src/linux-kernel-build-%{fullVersion} %{buildroot}/lib/modules/%{fullVersion}/build
++
++find %{buildroot}/lib/modules/ -name "*.ko" -type f -exec chmod 755 {} \;
+ %clean
+ rm -rf %{buildroot}
+@@ -133,12 +131,14 @@ rm -rf %{buildroot}
+ %files devel
+ %defattr (-, root, root)
+-/usr/src/linux-kernel-build-%{version}-%{build_id}
+-#/lib/modules/%{version}-%{build_id}/kernel
+-/lib/modules/%{version}-%{build_id}/build
+-#/lib/modules/%{version}-%{build_id}/modules.*
++/usr/src/linux-kernel-build-%{fullVersion}
++/lib/modules/%{fullVersion}/modules.*
++/lib/modules/%{fullVersion}/build
+-%files image
++%files
++%license COPYING
+ /boot/uImage
+-#/lib/modules/%{version}-%{build_id}/kernel
+-#/lib/modules/%{version}-%{build_id}/modules.*
++/boot/System.map*
++/boot/config*
++/lib/modules/%{fullVersion}/kernel
++/lib/modules/%{fullVersion}/modules.*
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1083-Split-uImage-on-clean-uImage-and-Device-Tree-blob.patch b/patches.tizen/1083-Split-uImage-on-clean-uImage-and-Device-Tree-blob.patch
new file mode 100644 (file)
index 0000000..62d81b8
--- /dev/null
@@ -0,0 +1,62 @@
+From ad51c9152b1784bc7fbee5d52775fc974b8a49ea Mon Sep 17 00:00:00 2001
+From: Jacek Pielaszkiewicz <j.pielaszkie@samsung.com>
+Date: Wed, 15 Jan 2014 15:07:54 +0100
+Subject: [PATCH 1083/1302] Split uImage on "clean" uImage and Device Tree
+ blob.
+
+1. The change is due to upgrade u-boot to latest upstream version
+   which support separate uImage and DTB.
+   Addtionally current defult u-boot configuration for trats2 assumes
+   that kernel image and DTB are delivered as separat files.
+
+2. DTB files are located in /boot directory.
+
+3. Together with uImage are delivered all DTBs which are compatible with
+   tizen_defconfig kernel configuration.
+
+Change-Id: I60a581edb4edccbf2ef704de525409da6572c4f8
+Signed-off-by: Jacek Pielaszkiewicz <j.pielaszkie@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ packaging/linux-kernel.spec | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/packaging/linux-kernel.spec b/packaging/linux-kernel.spec
+index 935e62f..211efd8 100644
+--- a/packaging/linux-kernel.spec
++++ b/packaging/linux-kernel.spec
+@@ -58,10 +58,8 @@ make EXTRAVERSION="-%{build_id}" %{config_name}
+ make EXTRAVERSION="-%{build_id}" %{?_smp_mflags}
+ # 2. Build uImage
+-make EXTRAVERSION="-%{build_id}" zImage %{?_smp_mflags}
++make EXTRAVERSION="-%{build_id}" uImage %{?_smp_mflags}
+ make EXTRAVERSION="-%{build_id}" dtbs %{?_smp_mflags}
+-cat arch/arm/boot/zImage arch/arm/boot/dts/%{defaultDtb}  > bImage
+-mkimage -A arm -C none -O linux -a 40008000 -e 40008000 -n 'Linux 3.10 Tizen kernel' -d bImage uImage
+ # 3. Build modules
+ make EXTRAVERSION="-%{build_id}" modules %{?_smp_mflags}
+@@ -78,7 +76,10 @@ mkdir -p %{buildroot}/lib/modules/%{fullVersion}
+ mkdir -p %{buildroot}/boot/
+ # 2. Install uImage, System.map, ...
+-install -m 755 uImage %{buildroot}/boot/
++install -m 755 arch/arm/boot/uImage %{buildroot}/boot/
++install -m 644 arch/arm/boot/dts/*.dtb %{buildroot}/boot/
++mv %{buildroot}/boot/exynos4412-m0.dtb %{buildroot}/boot/exynos4412-trats2.dtb
++
+ install -m 644 System.map %{buildroot}/boot/System.map-%{fullVersion}
+ install -m 644 .config %{buildroot}/boot/config-%{fullVersion}
+@@ -138,6 +139,7 @@ rm -rf %{buildroot}
+ %files
+ %license COPYING
+ /boot/uImage
++/boot/*.dtb
+ /boot/System.map*
+ /boot/config*
+ /lib/modules/%{fullVersion}/kernel
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1084-Revert-usb-gadget-mass_storage-merge-usb_f_mass_stor.patch b/patches.tizen/1084-Revert-usb-gadget-mass_storage-merge-usb_f_mass_stor.patch
new file mode 100644 (file)
index 0000000..1697033
--- /dev/null
@@ -0,0 +1,78 @@
+From 6e4b32497259b1e09a6703b80211029b9f192766 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 14 Jan 2014 14:26:04 +0100
+Subject: [PATCH 1084/1302] Revert "usb/gadget: mass_storage: merge
+ usb_f_mass_storage module with u_ms module"
+
+This reverts commit 2e3f33eddfca46f0d4909d496f6309454b8da298.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig  | 7 +++++++
+ drivers/usb/gadget/Makefile | 4 +++-
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 93dfc90..df9c040 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -537,6 +537,9 @@ config USB_F_SUBSET
+ config USB_F_RNDIS
+       tristate
++config USB_U_MS
++      tristate
++
+ config USB_F_MASS_STORAGE
+       tristate
+@@ -680,6 +683,7 @@ config USB_CONFIGFS_PHONET
+ config USB_CONFIGFS_MASS_STORAGE
+       boolean "Mass storage"
+       depends on USB_CONFIGFS
++      select USB_U_MS
+       select USB_F_MASS_STORAGE
+       help
+         The Mass Storage Gadget acts as a USB Mass Storage disk drive.
+@@ -903,6 +907,7 @@ config USB_MASS_STORAGE
+       tristate "Mass Storage Gadget"
+       depends on BLOCK
+       select USB_LIBCOMPOSITE
++      select USB_U_MS
+       select USB_F_MASS_STORAGE
+       help
+         The Mass Storage Gadget acts as a USB Mass Storage disk drive.
+@@ -1039,6 +1044,7 @@ config USB_G_ACM_MS
+       select USB_LIBCOMPOSITE
+       select USB_U_SERIAL
+       select USB_F_ACM
++      select USB_U_MS
+       select USB_F_MASS_STORAGE
+       help
+         This driver provides two functions in one configuration:
+@@ -1055,6 +1061,7 @@ config USB_G_MULTI
+       select USB_U_SERIAL
+       select USB_U_ETHER
+       select USB_F_ACM
++      select USB_U_MS
+       select USB_F_MASS_STORAGE
+       help
+         The Multifunction Composite Gadget provides Ethernet (RNDIS
+diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
+index 345a49c..62ccbda 100644
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -60,7 +60,9 @@ usb_f_ecm_subset-y           := f_subset.o
+ obj-$(CONFIG_USB_F_SUBSET)    += usb_f_ecm_subset.o
+ usb_f_rndis-y                 := f_rndis.o
+ obj-$(CONFIG_USB_F_RNDIS)     += usb_f_rndis.o
+-usb_f_mass_storage-y          := f_mass_storage.o storage_common.o
++u_ms-y                                := storage_common.o
++obj-$(CONFIG_USB_U_MS)                += u_ms.o
++usb_f_mass_storage-y          := f_mass_storage.o
+ obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o
+ #
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1085-Revert-usb-gadget-f_mass_storage-remove-compatibilit.patch b/patches.tizen/1085-Revert-usb-gadget-f_mass_storage-remove-compatibilit.patch
new file mode 100644 (file)
index 0000000..a966f0c
--- /dev/null
@@ -0,0 +1,369 @@
+From af2ddc568dc8e6ccfc6da70ceca428d2acdbb2da Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 14 Jan 2014 14:26:14 +0100
+Subject: [PATCH 1085/1302] Revert "usb/gadget: f_mass_storage: remove
+ compatibility layer"
+
+This reverts commit 59aad79c1789c338321789307105f676b8c8b427.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 154 +++++++++++++++++++++++++++++++++++-
+ drivers/usb/gadget/f_mass_storage.h |  21 +++++
+ 2 files changed, 174 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 3e9a03b..f1aa6c0 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -2651,13 +2651,17 @@ void fsg_common_get(struct fsg_common *common)
+ {
+       kref_get(&common->ref);
+ }
++#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_get);
++#endif
+ void fsg_common_put(struct fsg_common *common)
+ {
+       kref_put(&common->ref, fsg_common_release);
+ }
++#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_put);
++#endif
+ /* check if fsg_num_buffers is within a valid range */
+ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
+@@ -2695,7 +2699,9 @@ void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs)
+ {
+       common->sysfs = sysfs;
+ }
++#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_set_sysfs);
++#endif
+ static void _fsg_common_free_buffers(struct fsg_buffhd *buffhds, unsigned n)
+ {
+@@ -2747,14 +2753,18 @@ error_release:
+       return -ENOMEM;
+ }
++#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_set_num_buffers);
++#endif
+ void fsg_common_free_buffers(struct fsg_common *common)
+ {
+       _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
+       common->buffhds = NULL;
+ }
++#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_free_buffers);
++#endif
+ int fsg_common_set_nluns(struct fsg_common *common, int nluns)
+ {
+@@ -2780,7 +2790,9 @@ int fsg_common_set_nluns(struct fsg_common *common, int nluns)
+       return 0;
+ }
++#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_set_nluns);
++#endif
+ void fsg_common_free_luns(struct fsg_common *common)
+ {
+@@ -2788,20 +2800,26 @@ void fsg_common_free_luns(struct fsg_common *common)
+       kfree(common->luns);
+       common->luns = NULL;
+ }
++#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_free_luns);
++#endif
+ void fsg_common_set_ops(struct fsg_common *common,
+                       const struct fsg_operations *ops)
+ {
+       common->ops = ops;
+ }
++#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_set_ops);
++#endif
+ void fsg_common_set_private_data(struct fsg_common *common, void *priv)
+ {
+       common->private_data = priv;
+ }
++#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_set_private_data);
++#endif
+ int fsg_common_set_cdev(struct fsg_common *common,
+                        struct usb_composite_dev *cdev, bool can_stall)
+@@ -2831,7 +2849,9 @@ int fsg_common_set_cdev(struct fsg_common *common,
+       return 0;
+ }
++#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_set_cdev);
++#endif
+ static inline int fsg_common_add_sysfs(struct fsg_common *common,
+                                      struct fsg_lun *lun)
+@@ -2896,7 +2916,9 @@ void fsg_common_remove_lun(struct fsg_lun *lun, bool sysfs)
+       kfree(lun->name);
+       kfree(lun);
+ }
++#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_remove_lun);
++#endif
+ void _fsg_common_remove_luns(struct fsg_common *common, int n)
+ {
+@@ -2913,7 +2935,9 @@ void fsg_common_remove_luns(struct fsg_common *common)
+ {
+       _fsg_common_remove_luns(common, common->nluns);
+ }
++#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_remove_luns);
++#endif
+ #define MAX_LUN_NAME_LEN 80
+@@ -3010,7 +3034,9 @@ error_name:
+       kfree(lun);
+       return rc;
+ }
++#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_create_lun);
++#endif
+ int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg)
+ {
+@@ -3032,7 +3058,9 @@ fail:
+       _fsg_common_remove_luns(common, i);
+       return rc;
+ }
++#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_create_luns);
++#endif
+ void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
+                                  const char *pn)
+@@ -3049,7 +3077,9 @@ void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
+                    : "File-Stor Gadget"),
+                i);
+ }
++#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_set_inquiry_string);
++#endif
+ int fsg_common_run_thread(struct fsg_common *common)
+ {
+@@ -3068,7 +3098,66 @@ int fsg_common_run_thread(struct fsg_common *common)
+       return 0;
+ }
++#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_common_run_thread);
++#endif
++
++struct fsg_common *fsg_common_init(struct fsg_common *common,
++                                 struct usb_composite_dev *cdev,
++                                 struct fsg_config *cfg)
++{
++      int rc;
++
++      common = fsg_common_setup(common, !!common);
++      if (IS_ERR(common))
++              return common;
++      common->sysfs = true;
++      common->state = FSG_STATE_IDLE;
++
++      rc = fsg_common_set_num_buffers(common, cfg->fsg_num_buffers);
++      if (rc) {
++              if (common->free_storage_on_release)
++                      kfree(common);
++              return ERR_PTR(rc);
++      }
++
++      fsg_common_set_ops(common, cfg->ops);
++      fsg_common_set_private_data(common, cfg->private_data);
++
++      rc = fsg_common_set_cdev(common, cdev, cfg->can_stall);
++      if (rc)
++              goto error_release;
++
++      rc = fsg_common_set_nluns(common, cfg->nluns);
++      if (rc)
++              goto error_release;
++
++      rc = fsg_common_create_luns(common, cfg);
++      if (rc)
++              goto error_release;
++
++
++      fsg_common_set_inquiry_string(common, cfg->vendor_name,
++                                    cfg->product_name);
++
++      /* Information */
++      INFO(common, FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
++
++      rc = fsg_common_run_thread(common);
++      if (rc)
++              goto error_release;
++
++      return common;
++
++error_release:
++      common->state = FSG_STATE_TERMINATED;   /* The thread is dead */
++      /* Call fsg_common_release() directly, ref might be not initialised. */
++      fsg_common_release(&common->ref);
++      return ERR_PTR(rc);
++}
++#ifndef USB_FMS_INCLUDED
++EXPORT_SYMBOL(fsg_common_init);
++#endif
+ static void fsg_common_release(struct kref *ref)
+ {
+@@ -3119,8 +3208,9 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
+       struct usb_ep           *ep;
+       unsigned                max_burst;
+       int                     ret;
+-      struct fsg_opts         *opts;
++#ifndef USB_FMS_INCLUDED
++      struct fsg_opts         *opts;
+       opts = container_of(f->fi, struct fsg_opts, func_inst);
+       if (!opts->no_configfs) {
+               ret = fsg_common_set_cdev(fsg->common, c->cdev,
+@@ -3132,6 +3222,7 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
+               if (ret)
+                       return ret;
+       }
++#endif
+       fsg->gadget = gadget;
+@@ -3186,6 +3277,63 @@ autoconf_fail:
+ /****************************** ALLOCATE FUNCTION *************************/
++#ifdef USB_FMS_INCLUDED
++
++static void old_fsg_unbind(struct usb_configuration *c, struct usb_function *f)
++{
++      struct fsg_dev          *fsg = fsg_from_func(f);
++      struct fsg_common       *common = fsg->common;
++
++      DBG(fsg, "unbind\n");
++      if (fsg->common->fsg == fsg) {
++              fsg->common->new_fsg = NULL;
++              raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
++              /* FIXME: make interruptible or killable somehow? */
++              wait_event(common->fsg_wait, common->fsg != fsg);
++      }
++
++      fsg_common_put(common);
++      usb_free_all_descriptors(&fsg->function);
++      kfree(fsg);
++}
++
++static int fsg_bind_config(struct usb_composite_dev *cdev,
++                         struct usb_configuration *c,
++                         struct fsg_common *common)
++{
++      struct fsg_dev *fsg;
++      int rc;
++
++      fsg = kzalloc(sizeof *fsg, GFP_KERNEL);
++      if (unlikely(!fsg))
++              return -ENOMEM;
++
++      fsg->function.name        = FSG_DRIVER_DESC;
++      fsg->function.bind        = fsg_bind;
++      fsg->function.unbind      = old_fsg_unbind;
++      fsg->function.setup       = fsg_setup;
++      fsg->function.set_alt     = fsg_set_alt;
++      fsg->function.disable     = fsg_disable;
++
++      fsg->common               = common;
++      /*
++       * Our caller holds a reference to common structure so we
++       * don't have to be worry about it being freed until we return
++       * from this function.  So instead of incrementing counter now
++       * and decrement in error recovery we increment it only when
++       * call to usb_add_function() was successful.
++       */
++
++      rc = usb_add_function(c, &fsg->function);
++      if (unlikely(rc))
++              kfree(fsg);
++      else
++              fsg_common_get(fsg->common);
++      return rc;
++}
++
++#else
++
+ static inline struct fsg_lun_opts *to_fsg_lun_opts(struct config_item *item)
+ {
+       return container_of(to_config_group(item), struct fsg_lun_opts, group);
+@@ -3655,6 +3803,8 @@ DECLARE_USB_FUNCTION_INIT(mass_storage, fsg_alloc_inst, fsg_alloc);
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Michal Nazarewicz");
++#endif
++
+ /************************* Module parameters *************************/
+@@ -3690,5 +3840,7 @@ void fsg_config_from_params(struct fsg_config *cfg,
+       cfg->can_stall = params->stall;
+       cfg->fsg_num_buffers = fsg_num_buffers;
+ }
++#ifndef USB_FMS_INCLUDED
+ EXPORT_SYMBOL(fsg_config_from_params);
++#endif
+diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h
+index a16c2a9..62b4b8f 100644
+--- a/drivers/usb/gadget/f_mass_storage.h
++++ b/drivers/usb/gadget/f_mass_storage.h
+@@ -122,6 +122,10 @@ void fsg_common_get(struct fsg_common *common);
+ void fsg_common_put(struct fsg_common *common);
++struct fsg_common *fsg_common_init(struct fsg_common *common,
++                                 struct usb_composite_dev *cdev,
++                                 struct fsg_config *cfg);
++
+ void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs);
+ int fsg_common_set_num_buffers(struct fsg_common *common, unsigned int n);
+@@ -159,4 +163,21 @@ void fsg_config_from_params(struct fsg_config *cfg,
+                           const struct fsg_module_parameters *params,
+                           unsigned int fsg_num_buffers);
++static inline struct fsg_common *
++fsg_common_from_params(struct fsg_common *common,
++                     struct usb_composite_dev *cdev,
++                     const struct fsg_module_parameters *params,
++                     unsigned int fsg_num_buffers)
++      __attribute__((unused));
++static inline struct fsg_common *
++fsg_common_from_params(struct fsg_common *common,
++                     struct usb_composite_dev *cdev,
++                     const struct fsg_module_parameters *params,
++                     unsigned int fsg_num_buffers)
++{
++      struct fsg_config cfg;
++      fsg_config_from_params(&cfg, params, fsg_num_buffers);
++      return fsg_common_init(common, cdev, &cfg);
++}
++
+ #endif /* USB_F_MASS_STORAGE_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1086-Revert-usb-gadget-multi-convert-to-new-interface-of-.patch b/patches.tizen/1086-Revert-usb-gadget-multi-convert-to-new-interface-of-.patch
new file mode 100644 (file)
index 0000000..cbc0889
--- /dev/null
@@ -0,0 +1,243 @@
+From abd6579c4d7a38967827e534c5c01dc4729921c5 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 14 Jan 2014 14:26:19 +0100
+Subject: [PATCH 1086/1302] Revert "usb/gadget: multi: convert to new interface
+ of f_mass_storage"
+
+This reverts commit dd7e1f875183653d9a6c94148e19a06bfc81f4ad.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig |   1 -
+ drivers/usb/gadget/multi.c | 112 ++++++++++++---------------------------------
+ 2 files changed, 30 insertions(+), 83 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index df9c040..9a67faf 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -1062,7 +1062,6 @@ config USB_G_MULTI
+       select USB_U_ETHER
+       select USB_F_ACM
+       select USB_U_MS
+-      select USB_F_MASS_STORAGE
+       help
+         The Multifunction Composite Gadget provides Ethernet (RNDIS
+         and/or CDC Ethernet), mass storage and ACM serial link
+diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
+index 7f84efa..be62bea 100644
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -33,7 +33,17 @@ MODULE_AUTHOR("Michal Nazarewicz");
+ MODULE_LICENSE("GPL");
+-#include "f_mass_storage.h"
++/***************************** All the files... *****************************/
++
++/*
++ * kbuild is not very cooperative with respect to linking separately
++ * compiled library objects into one module.  So for now we won't use
++ * separate compilation ... ensuring init/exit sections work to shrink
++ * the runtime footprint, and giving us at least some parts of what
++ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
++ */
++#define USB_FMS_INCLUDED
++#include "f_mass_storage.c"
+ #include "u_ecm.h"
+ #ifdef USB_ETH_RNDIS
+@@ -138,8 +148,9 @@ static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
+ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
++static struct fsg_common fsg_common;
++
+ static struct usb_function_instance *fi_acm;
+-static struct usb_function_instance *fi_msg;
+ /********** RNDIS **********/
+@@ -147,11 +158,9 @@ static struct usb_function_instance *fi_msg;
+ static struct usb_function_instance *fi_rndis;
+ static struct usb_function *f_acm_rndis;
+ static struct usb_function *f_rndis;
+-static struct usb_function *f_msg_rndis;
+ static __init int rndis_do_config(struct usb_configuration *c)
+ {
+-      struct fsg_opts *fsg_opts;
+       int ret;
+       if (gadget_is_otg(c->cdev->gadget)) {
+@@ -177,24 +186,11 @@ static __init int rndis_do_config(struct usb_configuration *c)
+       if (ret)
+               goto err_conf;
+-      f_msg_rndis = usb_get_function(fi_msg);
+-      if (IS_ERR(f_msg_rndis)) {
+-              ret = PTR_ERR(f_msg_rndis);
++      ret = fsg_bind_config(c->cdev, c, &fsg_common);
++      if (ret < 0)
+               goto err_fsg;
+-      }
+-
+-      fsg_opts = container_of(fi_msg, struct fsg_opts, func_inst);
+-      ret = fsg_common_run_thread(fsg_opts->common);
+-      if (ret)
+-              goto err_run;
+-
+-      ret = usb_add_function(c, f_msg_rndis);
+-      if (ret)
+-              goto err_run;
+       return 0;
+-err_run:
+-      usb_put_function(f_msg_rndis);
+ err_fsg:
+       usb_remove_function(c, f_acm_rndis);
+ err_conf:
+@@ -235,11 +231,9 @@ static int rndis_config_register(struct usb_composite_dev *cdev)
+ static struct usb_function_instance *fi_ecm;
+ static struct usb_function *f_acm_multi;
+ static struct usb_function *f_ecm;
+-static struct usb_function *f_msg_multi;
+ static __init int cdc_do_config(struct usb_configuration *c)
+ {
+-      struct fsg_opts *fsg_opts;
+       int ret;
+       if (gadget_is_otg(c->cdev->gadget)) {
+@@ -266,24 +260,11 @@ static __init int cdc_do_config(struct usb_configuration *c)
+       if (ret)
+               goto err_conf;
+-      f_msg_multi = usb_get_function(fi_msg);
+-      if (IS_ERR(f_msg_multi)) {
+-              ret = PTR_ERR(f_msg_multi);
++      ret = fsg_bind_config(c->cdev, c, &fsg_common);
++      if (ret < 0)
+               goto err_fsg;
+-      }
+-
+-      fsg_opts = container_of(fi_msg, struct fsg_opts, func_inst);
+-      ret = fsg_common_run_thread(fsg_opts->common);
+-      if (ret)
+-              goto err_run;
+-
+-      ret = usb_add_function(c, f_msg_multi);
+-      if (ret)
+-              goto err_run;
+       return 0;
+-err_run:
+-      usb_put_function(f_msg_multi);
+ err_fsg:
+       usb_remove_function(c, f_acm_multi);
+ err_conf:
+@@ -330,8 +311,6 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
+ #ifdef USB_ETH_RNDIS
+       struct f_rndis_opts *rndis_opts;
+ #endif
+-      struct fsg_opts *fsg_opts;
+-      struct fsg_config config;
+       int status;
+       if (!can_support_ecm(cdev->gadget)) {
+@@ -394,65 +373,41 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
+       }
+       /* set up mass storage function */
+-      fi_msg = usb_get_function_instance("mass_storage");
+-      if (IS_ERR(fi_msg)) {
+-              status = PTR_ERR(fi_msg);
+-              goto fail1;
++      {
++              void *retp;
++              retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data,
++                                            fsg_num_buffers);
++              if (IS_ERR(retp)) {
++                      status = PTR_ERR(retp);
++                      goto fail1;
++              }
+       }
+-      fsg_config_from_params(&config, &fsg_mod_data, fsg_num_buffers);
+-      fsg_opts = container_of(fi_msg, struct fsg_opts, func_inst);
+-
+-      fsg_opts->no_configfs = true;
+-      status = fsg_common_set_num_buffers(fsg_opts->common, fsg_num_buffers);
+-      if (status)
+-              goto fail2;
+-
+-      status = fsg_common_set_nluns(fsg_opts->common, config.nluns);
+-      if (status)
+-              goto fail_set_nluns;
+-
+-      status = fsg_common_set_cdev(fsg_opts->common, cdev, config.can_stall);
+-      if (status)
+-              goto fail_set_cdev;
+-
+-      fsg_common_set_sysfs(fsg_opts->common, true);
+-      status = fsg_common_create_luns(fsg_opts->common, &config);
+-      if (status)
+-              goto fail_set_cdev;
+-
+-      fsg_common_set_inquiry_string(fsg_opts->common, config.vendor_name,
+-                                    config.product_name);
+       /* allocate string IDs */
+       status = usb_string_ids_tab(cdev, strings_dev);
+       if (unlikely(status < 0))
+-              goto fail_string_ids;
++              goto fail2;
+       device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id;
+       /* register configurations */
+       status = rndis_config_register(cdev);
+       if (unlikely(status < 0))
+-              goto fail_string_ids;
++              goto fail2;
+       status = cdc_config_register(cdev);
+       if (unlikely(status < 0))
+-              goto fail_string_ids;
++              goto fail2;
+       usb_composite_overwrite_options(cdev, &coverwrite);
+       /* we're done */
+       dev_info(&gadget->dev, DRIVER_DESC "\n");
++      fsg_common_put(&fsg_common);
+       return 0;
+       /* error recovery */
+-fail_string_ids:
+-      fsg_common_remove_luns(fsg_opts->common);
+-fail_set_cdev:
+-      fsg_common_free_luns(fsg_opts->common);
+-fail_set_nluns:
+-      fsg_common_free_buffers(fsg_opts->common);
+ fail2:
+-      usb_put_function_instance(fi_msg);
++      fsg_common_put(&fsg_common);
+ fail1:
+       usb_put_function_instance(fi_acm);
+ fail0:
+@@ -469,13 +424,6 @@ fail:
+ static int __exit multi_unbind(struct usb_composite_dev *cdev)
+ {
+ #ifdef CONFIG_USB_G_MULTI_CDC
+-      usb_put_function(f_msg_multi);
+-#endif
+-#ifdef USB_ETH_RNDIS
+-      usb_put_function(f_msg_rndis);
+-#endif
+-      usb_put_function_instance(fi_msg);
+-#ifdef CONFIG_USB_G_MULTI_CDC
+       usb_put_function(f_acm_multi);
+ #endif
+ #ifdef USB_ETH_RNDIS
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1087-Revert-usb-gadget-multi-convert-to-new-interface-of-.patch b/patches.tizen/1087-Revert-usb-gadget-multi-convert-to-new-interface-of-.patch
new file mode 100644 (file)
index 0000000..9a1dc1d
--- /dev/null
@@ -0,0 +1,199 @@
+From e56fa297b2eccb2ca8c36bdddc375c7adf4f8c2d Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 14 Jan 2014 14:26:23 +0100
+Subject: [PATCH 1087/1302] Revert "usb/gadget: multi: convert to new interface
+ of f_rndis"
+
+This reverts commit 341030a348bb6faa52e0b69a3ba17f827aae2af2.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig |  3 +-
+ drivers/usb/gadget/multi.c | 73 +++++++++++++++-------------------------------
+ 2 files changed, 24 insertions(+), 52 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 9a67faf..33ba3ec 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -1060,6 +1060,7 @@ config USB_G_MULTI
+       select USB_LIBCOMPOSITE
+       select USB_U_SERIAL
+       select USB_U_ETHER
++      select USB_U_RNDIS
+       select USB_F_ACM
+       select USB_U_MS
+       help
+@@ -1080,8 +1081,6 @@ config USB_G_MULTI
+ config USB_G_MULTI_RNDIS
+       bool "RNDIS + CDC Serial + Storage configuration"
+       depends on USB_G_MULTI
+-      select USB_U_RNDIS
+-      select USB_F_RNDIS
+       default y
+       help
+         This option enables a configuration with RNDIS, CDC Serial and
+diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
+index be62bea..0d1d132 100644
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -47,7 +47,8 @@ MODULE_LICENSE("GPL");
+ #include "u_ecm.h"
+ #ifdef USB_ETH_RNDIS
+-#  include "u_rndis.h"
++#  define USB_FRNDIS_INCLUDED
++#  include "f_rndis.c"
+ #  include "rndis.h"
+ #endif
+ #include "u_ether.h"
+@@ -151,13 +152,14 @@ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
+ static struct fsg_common fsg_common;
+ static struct usb_function_instance *fi_acm;
++static struct eth_dev *the_dev;
+ /********** RNDIS **********/
+ #ifdef USB_ETH_RNDIS
+-static struct usb_function_instance *fi_rndis;
++static u8 host_mac[ETH_ALEN];
++
+ static struct usb_function *f_acm_rndis;
+-static struct usb_function *f_rndis;
+ static __init int rndis_do_config(struct usb_configuration *c)
+ {
+@@ -168,19 +170,13 @@ static __init int rndis_do_config(struct usb_configuration *c)
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+-      f_rndis = usb_get_function(fi_rndis);
+-      if (IS_ERR(f_rndis))
+-              return PTR_ERR(f_rndis);
+-
+-      ret = usb_add_function(c, f_rndis);
++      ret = rndis_bind_config(c, host_mac, the_dev);
+       if (ret < 0)
+-              goto err_func_rndis;
++              return ret;
+       f_acm_rndis = usb_get_function(fi_acm);
+-      if (IS_ERR(f_acm_rndis)) {
+-              ret = PTR_ERR(f_acm_rndis);
+-              goto err_func_acm;
+-      }
++      if (IS_ERR(f_acm_rndis))
++              return PTR_ERR(f_acm_rndis);
+       ret = usb_add_function(c, f_acm_rndis);
+       if (ret)
+@@ -195,10 +191,6 @@ err_fsg:
+       usb_remove_function(c, f_acm_rndis);
+ err_conf:
+       usb_put_function(f_acm_rndis);
+-err_func_acm:
+-      usb_remove_function(c, f_rndis);
+-err_func_rndis:
+-      usb_put_function(f_rndis);
+       return ret;
+ }
+@@ -308,14 +300,11 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
+ #ifdef CONFIG_USB_G_MULTI_CDC
+       struct f_ecm_opts *ecm_opts;
+ #endif
+-#ifdef USB_ETH_RNDIS
+-      struct f_rndis_opts *rndis_opts;
+-#endif
+       int status;
+       if (!can_support_ecm(cdev->gadget)) {
+               dev_err(&gadget->dev, "controller '%s' not usable\n",
+-                      gadget->name);
++                      gadget->name);
+               return -EINVAL;
+       }
+@@ -331,38 +320,26 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
+               pr_info("using host ethernet address: %s", host_addr);
+       if (!gether_set_dev_addr(ecm_opts->net, dev_addr))
+               pr_info("using self ethernet address: %s", dev_addr);
+-#endif
+-#ifdef USB_ETH_RNDIS
+-      fi_rndis = usb_get_function_instance("rndis");
+-      if (IS_ERR(fi_rndis)) {
+-              status = PTR_ERR(fi_rndis);
+-              goto fail;
+-      }
++      the_dev = netdev_priv(ecm_opts->net);
+-      rndis_opts = container_of(fi_rndis, struct f_rndis_opts, func_inst);
++#elif defined USB_ETH_RNDIS
+-      gether_set_qmult(rndis_opts->net, qmult);
+-      if (!gether_set_host_addr(rndis_opts->net, host_addr))
+-              pr_info("using host ethernet address: %s", host_addr);
+-      if (!gether_set_dev_addr(rndis_opts->net, dev_addr))
+-              pr_info("using self ethernet address: %s", dev_addr);
++      /* set up network link layer */
++      the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, host_mac,
++                             qmult);
++      if (IS_ERR(the_dev))
++              return PTR_ERR(the_dev);
+ #endif
+ #if (defined CONFIG_USB_G_MULTI_CDC && defined USB_ETH_RNDIS)
+-      /*
+-       * If both ecm and rndis are selected then:
+-       *      1) rndis borrows the net interface from ecm
+-       *      2) since the interface is shared it must not be bound
+-       *      twice - in ecm's _and_ rndis' binds, so do it here.
+-       */
+       gether_set_gadget(ecm_opts->net, cdev->gadget);
+       status = gether_register_netdev(ecm_opts->net);
+       if (status)
+               goto fail0;
+-
+-      rndis_borrow_net(fi_rndis, ecm_opts->net);
+       ecm_opts->bound = true;
++
++      gether_get_host_addr_u8(ecm_opts->net, host_mac);
+ #endif
+       /* set up serial link layer */
+@@ -411,12 +388,10 @@ fail2:
+ fail1:
+       usb_put_function_instance(fi_acm);
+ fail0:
+-#ifdef USB_ETH_RNDIS
+-      usb_put_function_instance(fi_rndis);
+-fail:
+-#endif
+ #ifdef CONFIG_USB_G_MULTI_CDC
+       usb_put_function_instance(fi_ecm);
++#else
++      gether_cleanup(the_dev);
+ #endif
+       return status;
+ }
+@@ -430,13 +405,11 @@ static int __exit multi_unbind(struct usb_composite_dev *cdev)
+       usb_put_function(f_acm_rndis);
+ #endif
+       usb_put_function_instance(fi_acm);
+-#ifdef USB_ETH_RNDIS
+-      usb_put_function(f_rndis);
+-      usb_put_function_instance(fi_rndis);
+-#endif
+ #ifdef CONFIG_USB_G_MULTI_CDC
+       usb_put_function(f_ecm);
+       usb_put_function_instance(fi_ecm);
++#else
++      gether_cleanup(the_dev);
+ #endif
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1088-Revert-usb-gadget-multi-convert-to-new-interface-of-.patch b/patches.tizen/1088-Revert-usb-gadget-multi-convert-to-new-interface-of-.patch
new file mode 100644 (file)
index 0000000..20eb421
--- /dev/null
@@ -0,0 +1,189 @@
+From ea36224d910da7abbe97bcc85011979917ddf558 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 14 Jan 2014 14:26:26 +0100
+Subject: [PATCH 1088/1302] Revert "usb/gadget: multi: convert to new interface
+ of f_ecm"
+
+This reverts commit 0f51ef4507d61692afe5de4598b8f5df82f1ada1.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig |  1 -
+ drivers/usb/gadget/multi.c | 68 ++++++----------------------------------------
+ 2 files changed, 8 insertions(+), 61 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 33ba3ec..e327cc3 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -1094,7 +1094,6 @@ config USB_G_MULTI_CDC
+       bool "CDC Ethernet + CDC Serial + Storage configuration"
+       depends on USB_G_MULTI
+       default n
+-      select USB_F_ECM
+       help
+         This option enables a configuration with CDC Ethernet (ECM), CDC
+         Serial and Mass Storage functions available in the Multifunction
+diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
+index 0d1d132..c232f76 100644
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -15,7 +15,6 @@
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+-#include <linux/netdevice.h>
+ #include "u_serial.h"
+ #if defined USB_ETH_RNDIS
+@@ -45,7 +44,8 @@ MODULE_LICENSE("GPL");
+ #define USB_FMS_INCLUDED
+ #include "f_mass_storage.c"
+-#include "u_ecm.h"
++#define USBF_ECM_INCLUDED
++#include "f_ecm.c"
+ #ifdef USB_ETH_RNDIS
+ #  define USB_FRNDIS_INCLUDED
+ #  include "f_rndis.c"
+@@ -151,14 +151,14 @@ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
+ static struct fsg_common fsg_common;
++static u8 host_mac[ETH_ALEN];
++
+ static struct usb_function_instance *fi_acm;
+ static struct eth_dev *the_dev;
+ /********** RNDIS **********/
+ #ifdef USB_ETH_RNDIS
+-static u8 host_mac[ETH_ALEN];
+-
+ static struct usb_function *f_acm_rndis;
+ static __init int rndis_do_config(struct usb_configuration *c)
+@@ -220,9 +220,7 @@ static int rndis_config_register(struct usb_composite_dev *cdev)
+ /********** CDC ECM **********/
+ #ifdef CONFIG_USB_G_MULTI_CDC
+-static struct usb_function_instance *fi_ecm;
+ static struct usb_function *f_acm_multi;
+-static struct usb_function *f_ecm;
+ static __init int cdc_do_config(struct usb_configuration *c)
+ {
+@@ -233,20 +231,14 @@ static __init int cdc_do_config(struct usb_configuration *c)
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+-      f_ecm = usb_get_function(fi_ecm);
+-      if (IS_ERR(f_ecm))
+-              return PTR_ERR(f_ecm);
+-
+-      ret = usb_add_function(c, f_ecm);
++      ret = ecm_bind_config(c, host_mac, the_dev);
+       if (ret < 0)
+-              goto err_func_ecm;
++              return ret;
+       /* implicit port_num is zero */
+       f_acm_multi = usb_get_function(fi_acm);
+-      if (IS_ERR(f_acm_multi)) {
+-              ret = PTR_ERR(f_acm_multi);
+-              goto err_func_acm;
+-      }
++      if (IS_ERR(f_acm_multi))
++              return PTR_ERR(f_acm_multi);
+       ret = usb_add_function(c, f_acm_multi);
+       if (ret)
+@@ -261,10 +253,6 @@ err_fsg:
+       usb_remove_function(c, f_acm_multi);
+ err_conf:
+       usb_put_function(f_acm_multi);
+-err_func_acm:
+-      usb_remove_function(c, f_ecm);
+-err_func_ecm:
+-      usb_put_function(f_ecm);
+       return ret;
+ }
+@@ -297,9 +285,6 @@ static int cdc_config_register(struct usb_composite_dev *cdev)
+ static int __ref multi_bind(struct usb_composite_dev *cdev)
+ {
+       struct usb_gadget *gadget = cdev->gadget;
+-#ifdef CONFIG_USB_G_MULTI_CDC
+-      struct f_ecm_opts *ecm_opts;
+-#endif
+       int status;
+       if (!can_support_ecm(cdev->gadget)) {
+@@ -308,39 +293,11 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
+               return -EINVAL;
+       }
+-#ifdef CONFIG_USB_G_MULTI_CDC
+-      fi_ecm = usb_get_function_instance("ecm");
+-      if (IS_ERR(fi_ecm))
+-              return PTR_ERR(fi_ecm);
+-
+-      ecm_opts = container_of(fi_ecm, struct f_ecm_opts, func_inst);
+-
+-      gether_set_qmult(ecm_opts->net, qmult);
+-      if (!gether_set_host_addr(ecm_opts->net, host_addr))
+-              pr_info("using host ethernet address: %s", host_addr);
+-      if (!gether_set_dev_addr(ecm_opts->net, dev_addr))
+-              pr_info("using self ethernet address: %s", dev_addr);
+-
+-      the_dev = netdev_priv(ecm_opts->net);
+-
+-#elif defined USB_ETH_RNDIS
+-
+       /* set up network link layer */
+       the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, host_mac,
+                              qmult);
+       if (IS_ERR(the_dev))
+               return PTR_ERR(the_dev);
+-#endif
+-
+-#if (defined CONFIG_USB_G_MULTI_CDC && defined USB_ETH_RNDIS)
+-      gether_set_gadget(ecm_opts->net, cdev->gadget);
+-      status = gether_register_netdev(ecm_opts->net);
+-      if (status)
+-              goto fail0;
+-      ecm_opts->bound = true;
+-
+-      gether_get_host_addr_u8(ecm_opts->net, host_mac);
+-#endif
+       /* set up serial link layer */
+       fi_acm = usb_get_function_instance("acm");
+@@ -388,11 +345,7 @@ fail2:
+ fail1:
+       usb_put_function_instance(fi_acm);
+ fail0:
+-#ifdef CONFIG_USB_G_MULTI_CDC
+-      usb_put_function_instance(fi_ecm);
+-#else
+       gether_cleanup(the_dev);
+-#endif
+       return status;
+ }
+@@ -405,12 +358,7 @@ static int __exit multi_unbind(struct usb_composite_dev *cdev)
+       usb_put_function(f_acm_rndis);
+ #endif
+       usb_put_function_instance(fi_acm);
+-#ifdef CONFIG_USB_G_MULTI_CDC
+-      usb_put_function(f_ecm);
+-      usb_put_function_instance(fi_ecm);
+-#else
+       gether_cleanup(the_dev);
+-#endif
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1089-Revert-usb-gadget-acm_ms-convert-to-new-interface-of.patch b/patches.tizen/1089-Revert-usb-gadget-acm_ms-convert-to-new-interface-of.patch
new file mode 100644 (file)
index 0000000..cfc7497
--- /dev/null
@@ -0,0 +1,221 @@
+From f0e4de92e626a9db654d0e35304e38d725285488 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 14 Jan 2014 14:26:29 +0100
+Subject: [PATCH 1089/1302] Revert "usb/gadget: acm_ms: convert to new
+ interface of f_mass_storage"
+
+This reverts commit 7ab27e2ab83e3d760dd4ebb8175eac0f04f776f2.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig  |   1 -
+ drivers/usb/gadget/acm_ms.c | 113 +++++++++++++++-----------------------------
+ 2 files changed, 39 insertions(+), 75 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index e327cc3..bef6e86 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -1045,7 +1045,6 @@ config USB_G_ACM_MS
+       select USB_U_SERIAL
+       select USB_F_ACM
+       select USB_U_MS
+-      select USB_F_MASS_STORAGE
+       help
+         This driver provides two functions in one configuration:
+         a mass storage, and a CDC ACM (serial port) link.
+diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c
+index b405bc4..31aae8f 100644
+--- a/drivers/usb/gadget/acm_ms.c
++++ b/drivers/usb/gadget/acm_ms.c
+@@ -31,7 +31,17 @@
+ #define ACM_MS_VENDOR_NUM     0x1d6b  /* Linux Foundation */
+ #define ACM_MS_PRODUCT_NUM    0x0106  /* Composite Gadget: ACM + MS*/
+-#include "f_mass_storage.h"
++/*-------------------------------------------------------------------------*/
++
++/*
++ * Kbuild is not very cooperative with respect to linking separately
++ * compiled library objects into one module.  So for now we won't use
++ * separate compilation ... ensuring init/exit sections work to shrink
++ * the runtime footprint, and giving us at least some parts of what
++ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
++ */
++#define USB_FMS_INCLUDED
++#include "f_mass_storage.c"
+ /*-------------------------------------------------------------------------*/
+ USB_GADGET_COMPOSITE_OPTIONS();
+@@ -111,19 +121,16 @@ static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
+ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
++static struct fsg_common fsg_common;
++
+ /*-------------------------------------------------------------------------*/
+ static struct usb_function *f_acm;
+ static struct usb_function_instance *f_acm_inst;
+-
+-static struct usb_function_instance *fi_msg;
+-static struct usb_function *f_msg;
+-
+ /*
+  * We _always_ have both ACM and mass storage functions.
+  */
+ static int __init acm_ms_do_config(struct usb_configuration *c)
+ {
+-      struct fsg_opts *opts;
+       int     status;
+       if (gadget_is_otg(c->cdev->gadget)) {
+@@ -131,37 +138,31 @@ static int __init acm_ms_do_config(struct usb_configuration *c)
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+-      opts = container_of(fi_msg, struct fsg_opts, func_inst);
++      f_acm_inst = usb_get_function_instance("acm");
++      if (IS_ERR(f_acm_inst))
++              return PTR_ERR(f_acm_inst);
+       f_acm = usb_get_function(f_acm_inst);
+-      if (IS_ERR(f_acm))
+-              return PTR_ERR(f_acm);
+-
+-      f_msg = usb_get_function(fi_msg);
+-      if (IS_ERR(f_msg)) {
+-              status = PTR_ERR(f_msg);
+-              goto put_acm;
++      if (IS_ERR(f_acm)) {
++              status = PTR_ERR(f_acm);
++              goto err_func;
+       }
+       status = usb_add_function(c, f_acm);
+       if (status < 0)
+-              goto put_msg;
+-
+-      status = fsg_common_run_thread(opts->common);
+-      if (status)
+-              goto remove_acm;
++              goto err_conf;
+-      status = usb_add_function(c, f_msg);
+-      if (status)
+-              goto remove_acm;
++      status = fsg_bind_config(c->cdev, c, &fsg_common);
++      if (status < 0)
++              goto err_fsg;
+       return 0;
+-remove_acm:
++err_fsg:
+       usb_remove_function(c, f_acm);
+-put_msg:
+-      usb_put_function(f_msg);
+-put_acm:
++err_conf:
+       usb_put_function(f_acm);
++err_func:
++      usb_put_function_instance(f_acm_inst);
+       return status;
+ }
+@@ -177,82 +178,46 @@ static struct usb_configuration acm_ms_config_driver = {
+ static int __init acm_ms_bind(struct usb_composite_dev *cdev)
+ {
+       struct usb_gadget       *gadget = cdev->gadget;
+-      struct fsg_opts         *opts;
+-      struct fsg_config       config;
+       int                     status;
+-
+-      f_acm_inst = usb_get_function_instance("acm");
+-      if (IS_ERR(f_acm_inst))
+-              return PTR_ERR(f_acm_inst);
+-
+-      fi_msg = usb_get_function_instance("mass_storage");
+-      if (IS_ERR(fi_msg)) {
+-              status = PTR_ERR(fi_msg);
+-              goto fail_get_msg;
+-      }
++      void                    *retp;
+       /* set up mass storage function */
+-      fsg_config_from_params(&config, &fsg_mod_data, fsg_num_buffers);
+-      opts = container_of(fi_msg, struct fsg_opts, func_inst);
+-
+-      opts->no_configfs = true;
+-      status = fsg_common_set_num_buffers(opts->common, fsg_num_buffers);
+-      if (status)
+-              goto fail;
+-
+-      status = fsg_common_set_nluns(opts->common, config.nluns);
+-      if (status)
+-              goto fail_set_nluns;
+-
+-      status = fsg_common_set_cdev(opts->common, cdev, config.can_stall);
+-      if (status)
+-              goto fail_set_cdev;
+-
+-      fsg_common_set_sysfs(opts->common, true);
+-      status = fsg_common_create_luns(opts->common, &config);
+-      if (status)
+-              goto fail_set_cdev;
++      retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data,
++                                    fsg_num_buffers);
++      if (IS_ERR(retp)) {
++              status = PTR_ERR(retp);
++              return PTR_ERR(retp);
++      }
+-      fsg_common_set_inquiry_string(opts->common, config.vendor_name,
+-                                    config.product_name);
+       /*
+        * Allocate string descriptor numbers ... note that string
+        * contents can be overridden by the composite_dev glue.
+        */
+       status = usb_string_ids_tab(cdev, strings_dev);
+       if (status < 0)
+-              goto fail_string_ids;
++              goto fail1;
+       device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id;
+       device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id;
+       /* register our configuration */
+       status = usb_add_config(cdev, &acm_ms_config_driver, acm_ms_do_config);
+       if (status < 0)
+-              goto fail_string_ids;
++              goto fail1;
+       usb_composite_overwrite_options(cdev, &coverwrite);
+       dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n",
+                       DRIVER_DESC);
++      fsg_common_put(&fsg_common);
+       return 0;
+       /* error recovery */
+-fail_string_ids:
+-      fsg_common_remove_luns(opts->common);
+-fail_set_cdev:
+-      fsg_common_free_luns(opts->common);
+-fail_set_nluns:
+-      fsg_common_free_buffers(opts->common);
+-fail:
+-      usb_put_function_instance(fi_msg);
+-fail_get_msg:
+-      usb_put_function_instance(f_acm_inst);
++fail1:
++      fsg_common_put(&fsg_common);
+       return status;
+ }
+ static int __exit acm_ms_unbind(struct usb_composite_dev *cdev)
+ {
+-      usb_put_function(f_msg);
+-      usb_put_function_instance(fi_msg);
+       usb_put_function(f_acm);
+       usb_put_function_instance(f_acm_inst);
+       return 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1090-Revert-usb-gadget-f_mass_storage-add-configfs-suppor.patch b/patches.tizen/1090-Revert-usb-gadget-f_mass_storage-add-configfs-suppor.patch
new file mode 100644 (file)
index 0000000..f07bfdb
--- /dev/null
@@ -0,0 +1,532 @@
+From 13b2c667a3490a8157c6539cb3fc9a2e1ccfa34b Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 14 Jan 2014 14:26:37 +0100
+Subject: [PATCH 1090/1302] Revert "usb/gadget: f_mass_storage: add configfs
+ support"
+
+This reverts commit d1e1911c9b87f7c8aa7cf22ce76dd4cb5a669cdf.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../ABI/testing/configfs-usb-gadget-mass-storage   |  31 --
+ drivers/usb/gadget/Kconfig                         |  11 -
+ drivers/usb/gadget/f_mass_storage.c                | 368 ---------------------
+ drivers/usb/gadget/f_mass_storage.h                |  17 -
+ 4 files changed, 427 deletions(-)
+ delete mode 100644 Documentation/ABI/testing/configfs-usb-gadget-mass-storage
+
+diff --git a/Documentation/ABI/testing/configfs-usb-gadget-mass-storage b/Documentation/ABI/testing/configfs-usb-gadget-mass-storage
+deleted file mode 100644
+index e1e918e..0000000
+--- a/Documentation/ABI/testing/configfs-usb-gadget-mass-storage
++++ /dev/null
+@@ -1,31 +0,0 @@
+-What:         /config/usb-gadget/gadget/functions/mass_storage.name
+-Date:         Jul 2013
+-KenelVersion: 3.12
+-Description:
+-              The attributes:
+-
+-              stall           - Set to permit function to halt bulk endpoints.
+-                              Disabled on some USB devices known not to work
+-                              correctly. You should set it to true.
+-              num_buffers     - Number of pipeline buffers. Valid numbers
+-                              are 2..4. Available only if
+-                              CONFIG_USB_GADGET_DEBUG_FILES is set.
+-
+-What:         /config/usb-gadget/gadget/functions/mass_storage.name/lun.name
+-Date:         Jul 2013
+-KenelVersion: 3.12
+-Description:
+-              The attributes:
+-
+-              file            - The path to the backing file for the LUN.
+-                              Required if LUN is not marked as removable.
+-              ro              - Flag specifying access to the LUN shall be
+-                              read-only. This is implied if CD-ROM emulation
+-                              is enabled as well as when it was impossible
+-                              to open "filename" in R/W mode.
+-              removable       - Flag specifying that LUN shall be indicated as
+-                              being removable.
+-              cdrom           - Flag specifying that LUN shall be reported as
+-                              being a CD-ROM.
+-              nofua           - Flag specifying that FUA flag
+-                              in SCSI WRITE(10,12)
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index bef6e86..6214b79 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -680,17 +680,6 @@ config USB_CONFIGFS_PHONET
+       help
+         The Phonet protocol implementation for USB device.
+-config USB_CONFIGFS_MASS_STORAGE
+-      boolean "Mass storage"
+-      depends on USB_CONFIGFS
+-      select USB_U_MS
+-      select USB_F_MASS_STORAGE
+-      help
+-        The Mass Storage Gadget acts as a USB Mass Storage disk drive.
+-        As its storage repository it can use a regular file or a block
+-        device (in much the same way as the "loop" device driver),
+-        specified as a module parameter or sysfs option.
+-
+ config USB_ZERO
+       tristate "Gadget Zero (DEVELOPMENT)"
+       select USB_LIBCOMPOSITE
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index f1aa6c0..aaa8349 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -220,7 +220,6 @@
+ #include <linux/usb/composite.h>
+ #include "gadget_chips.h"
+-#include "configfs.h"
+ /*------------------------------------------------------------------------*/
+@@ -3334,350 +3333,6 @@ static int fsg_bind_config(struct usb_composite_dev *cdev,
+ #else
+-static inline struct fsg_lun_opts *to_fsg_lun_opts(struct config_item *item)
+-{
+-      return container_of(to_config_group(item), struct fsg_lun_opts, group);
+-}
+-
+-static inline struct fsg_opts *to_fsg_opts(struct config_item *item)
+-{
+-      return container_of(to_config_group(item), struct fsg_opts,
+-                          func_inst.group);
+-}
+-
+-CONFIGFS_ATTR_STRUCT(fsg_lun_opts);
+-CONFIGFS_ATTR_OPS(fsg_lun_opts);
+-
+-static void fsg_lun_attr_release(struct config_item *item)
+-{
+-      struct fsg_lun_opts *lun_opts;
+-
+-      lun_opts = to_fsg_lun_opts(item);
+-      kfree(lun_opts);
+-}
+-
+-static struct configfs_item_operations fsg_lun_item_ops = {
+-      .release        = fsg_lun_attr_release,
+-      .show_attribute = fsg_lun_opts_attr_show,
+-      .store_attribute = fsg_lun_opts_attr_store,
+-};
+-
+-static ssize_t fsg_lun_opts_file_show(struct fsg_lun_opts *opts, char *page)
+-{
+-      struct fsg_opts *fsg_opts;
+-
+-      fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
+-
+-      return fsg_show_file(opts->lun, &fsg_opts->common->filesem, page);
+-}
+-
+-static ssize_t fsg_lun_opts_file_store(struct fsg_lun_opts *opts,
+-                                     const char *page, size_t len)
+-{
+-      struct fsg_opts *fsg_opts;
+-
+-      fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
+-
+-      return fsg_store_file(opts->lun, &fsg_opts->common->filesem, page, len);
+-}
+-
+-static struct fsg_lun_opts_attribute fsg_lun_opts_file =
+-      __CONFIGFS_ATTR(file, S_IRUGO | S_IWUSR, fsg_lun_opts_file_show,
+-                      fsg_lun_opts_file_store);
+-
+-static ssize_t fsg_lun_opts_ro_show(struct fsg_lun_opts *opts, char *page)
+-{
+-      return fsg_show_ro(opts->lun, page);
+-}
+-
+-static ssize_t fsg_lun_opts_ro_store(struct fsg_lun_opts *opts,
+-                                     const char *page, size_t len)
+-{
+-      struct fsg_opts *fsg_opts;
+-
+-      fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
+-
+-      return fsg_store_ro(opts->lun, &fsg_opts->common->filesem, page, len);
+-}
+-
+-static struct fsg_lun_opts_attribute fsg_lun_opts_ro =
+-      __CONFIGFS_ATTR(ro, S_IRUGO | S_IWUSR, fsg_lun_opts_ro_show,
+-                      fsg_lun_opts_ro_store);
+-
+-static ssize_t fsg_lun_opts_removable_show(struct fsg_lun_opts *opts,
+-                                         char *page)
+-{
+-      return fsg_show_removable(opts->lun, page);
+-}
+-
+-static ssize_t fsg_lun_opts_removable_store(struct fsg_lun_opts *opts,
+-                                     const char *page, size_t len)
+-{
+-      return fsg_store_removable(opts->lun, page, len);
+-}
+-
+-static struct fsg_lun_opts_attribute fsg_lun_opts_removable =
+-      __CONFIGFS_ATTR(removable, S_IRUGO | S_IWUSR,
+-                      fsg_lun_opts_removable_show,
+-                      fsg_lun_opts_removable_store);
+-
+-static ssize_t fsg_lun_opts_cdrom_show(struct fsg_lun_opts *opts, char *page)
+-{
+-      return fsg_show_cdrom(opts->lun, page);
+-}
+-
+-static ssize_t fsg_lun_opts_cdrom_store(struct fsg_lun_opts *opts,
+-                                     const char *page, size_t len)
+-{
+-      return fsg_store_cdrom(opts->lun, page, len);
+-}
+-
+-static struct fsg_lun_opts_attribute fsg_lun_opts_cdrom =
+-      __CONFIGFS_ATTR(cdrom, S_IRUGO | S_IWUSR, fsg_lun_opts_cdrom_show,
+-                      fsg_lun_opts_cdrom_store);
+-
+-static ssize_t fsg_lun_opts_nofua_show(struct fsg_lun_opts *opts, char *page)
+-{
+-      return fsg_show_nofua(opts->lun, page);
+-}
+-
+-static ssize_t fsg_lun_opts_nofua_store(struct fsg_lun_opts *opts,
+-                                     const char *page, size_t len)
+-{
+-      return fsg_store_nofua(opts->lun, page, len);
+-}
+-
+-static struct fsg_lun_opts_attribute fsg_lun_opts_nofua =
+-      __CONFIGFS_ATTR(nofua, S_IRUGO | S_IWUSR, fsg_lun_opts_nofua_show,
+-                      fsg_lun_opts_nofua_store);
+-
+-static struct configfs_attribute *fsg_lun_attrs[] = {
+-      &fsg_lun_opts_file.attr,
+-      &fsg_lun_opts_ro.attr,
+-      &fsg_lun_opts_removable.attr,
+-      &fsg_lun_opts_cdrom.attr,
+-      &fsg_lun_opts_nofua.attr,
+-      NULL,
+-};
+-
+-static struct config_item_type fsg_lun_type = {
+-      .ct_item_ops    = &fsg_lun_item_ops,
+-      .ct_attrs       = fsg_lun_attrs,
+-      .ct_owner       = THIS_MODULE,
+-};
+-
+-#define MAX_NAME_LEN  40
+-
+-static struct config_group *fsg_lun_make(struct config_group *group,
+-                                       const char *name)
+-{
+-      struct fsg_lun_opts *opts;
+-      struct fsg_opts *fsg_opts;
+-      char buf[MAX_NAME_LEN];
+-      char lun_name[MAX_LUN_NAME_LEN];
+-      struct fsg_lun_config config;
+-      char *num_str;
+-      u8 num;
+-      int ret;
+-
+-      ret = snprintf(buf, MAX_NAME_LEN, "%s", name);
+-      if (ret >= MAX_NAME_LEN)
+-              return ERR_PTR(-ENAMETOOLONG);
+-
+-      num_str = strchr(buf, '.');
+-      if (!num_str) {
+-              pr_err("Unable to locate . in LUN.NUMBER\n");
+-              return ERR_PTR(-EINVAL);
+-      }
+-      *num_str = '\0';
+-      num_str++;
+-
+-      ret = kstrtou8(num_str, 0, &num);
+-      if (ret)
+-              return ERR_PTR(ret);
+-
+-      fsg_opts = to_fsg_opts(&group->cg_item);
+-      if (num >= FSG_MAX_LUNS)
+-              return ERR_PTR(-ENODEV);
+-      mutex_lock(&fsg_opts->lock);
+-      if (fsg_opts->refcnt || fsg_opts->common->luns[num]) {
+-              ret = -EBUSY;
+-              goto out;
+-      }
+-
+-      opts = kzalloc(sizeof(*opts), GFP_KERNEL);
+-      if (!opts) {
+-              ret = -ENOMEM;
+-              goto out;
+-      }
+-
+-      memset(&config, 0, sizeof(config));
+-      config.removable = true;
+-
+-      snprintf(lun_name, MAX_LUN_NAME_LEN, "%s/%s",
+-               group->cg_item.ci_name, name);
+-      ret = fsg_common_create_lun(fsg_opts->common, &config, num, lun_name,
+-                                  NULL);
+-      if (ret) {
+-              kfree(opts);
+-              goto out;
+-      }
+-      opts->lun = fsg_opts->common->luns[num];
+-      opts->lun_id = num;
+-      mutex_unlock(&fsg_opts->lock);
+-
+-      config_group_init_type_name(&opts->group, name, &fsg_lun_type);
+-
+-      return &opts->group;
+-out:
+-      mutex_unlock(&fsg_opts->lock);
+-      return ERR_PTR(ret);
+-}
+-
+-static void fsg_lun_drop(struct config_group *group, struct config_item *item)
+-{
+-      struct fsg_lun_opts *lun_opts;
+-      struct fsg_opts *fsg_opts;
+-
+-      lun_opts = to_fsg_lun_opts(item);
+-      fsg_opts = to_fsg_opts(&group->cg_item);
+-
+-      mutex_lock(&fsg_opts->lock);
+-      if (fsg_opts->refcnt) {
+-              struct config_item *gadget;
+-
+-              gadget = group->cg_item.ci_parent->ci_parent;
+-              unregister_gadget_item(gadget);
+-      }
+-
+-      fsg_common_remove_lun(lun_opts->lun, fsg_opts->common->sysfs);
+-      fsg_opts->common->luns[lun_opts->lun_id] = NULL;
+-      lun_opts->lun_id = 0;
+-      mutex_unlock(&fsg_opts->lock);
+-
+-      config_item_put(item);
+-}
+-
+-CONFIGFS_ATTR_STRUCT(fsg_opts);
+-CONFIGFS_ATTR_OPS(fsg_opts);
+-
+-static void fsg_attr_release(struct config_item *item)
+-{
+-      struct fsg_opts *opts = to_fsg_opts(item);
+-
+-      usb_put_function_instance(&opts->func_inst);
+-}
+-
+-static struct configfs_item_operations fsg_item_ops = {
+-      .release        = fsg_attr_release,
+-      .show_attribute = fsg_opts_attr_show,
+-      .store_attribute = fsg_opts_attr_store,
+-};
+-
+-static ssize_t fsg_opts_stall_show(struct fsg_opts *opts, char *page)
+-{
+-      int result;
+-
+-      mutex_lock(&opts->lock);
+-      result = sprintf(page, "%d", opts->common->can_stall);
+-      mutex_unlock(&opts->lock);
+-
+-      return result;
+-}
+-
+-static ssize_t fsg_opts_stall_store(struct fsg_opts *opts, const char *page,
+-                                  size_t len)
+-{
+-      int ret;
+-      u8 num;
+-
+-      mutex_lock(&opts->lock);
+-      if (opts->refcnt) {
+-              ret = -EBUSY;
+-              goto end;
+-      }
+-      ret = kstrtou8(page, 0, &num);
+-      if (ret)
+-              goto end;
+-
+-      opts->common->can_stall = num != 0;
+-      ret = len;
+-
+-end:
+-      mutex_unlock(&opts->lock);
+-      return ret;
+-}
+-
+-static struct fsg_opts_attribute fsg_opts_stall =
+-      __CONFIGFS_ATTR(stall, S_IRUGO | S_IWUSR, fsg_opts_stall_show,
+-                      fsg_opts_stall_store);
+-
+-#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+-static ssize_t fsg_opts_num_buffers_show(struct fsg_opts *opts, char *page)
+-{
+-      int result;
+-
+-      mutex_lock(&opts->lock);
+-      result = sprintf(page, "%d", opts->common->fsg_num_buffers);
+-      mutex_unlock(&opts->lock);
+-
+-      return result;
+-}
+-
+-static ssize_t fsg_opts_num_buffers_store(struct fsg_opts *opts,
+-                                        const char *page, size_t len)
+-{
+-      int ret;
+-      u8 num;
+-
+-      mutex_lock(&opts->lock);
+-      if (opts->refcnt) {
+-              ret = -EBUSY;
+-              goto end;
+-      }
+-      ret = kstrtou8(page, 0, &num);
+-      if (ret)
+-              goto end;
+-
+-      ret = fsg_num_buffers_validate(num);
+-      if (ret)
+-              goto end;
+-
+-      fsg_common_set_num_buffers(opts->common, num);
+-      ret = len;
+-
+-end:
+-      mutex_unlock(&opts->lock);
+-      return ret;
+-}
+-
+-static struct fsg_opts_attribute fsg_opts_num_buffers =
+-      __CONFIGFS_ATTR(num_buffers, S_IRUGO | S_IWUSR,
+-                      fsg_opts_num_buffers_show,
+-                      fsg_opts_num_buffers_store);
+-
+-#endif
+-
+-static struct configfs_attribute *fsg_attrs[] = {
+-      &fsg_opts_stall.attr,
+-#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+-      &fsg_opts_num_buffers.attr,
+-#endif
+-      NULL,
+-};
+-
+-static struct configfs_group_operations fsg_group_ops = {
+-      .make_group     = fsg_lun_make,
+-      .drop_item      = fsg_lun_drop,
+-};
+-
+-static struct config_item_type fsg_func_type = {
+-      .ct_item_ops    = &fsg_item_ops,
+-      .ct_group_ops   = &fsg_group_ops,
+-      .ct_attrs       = fsg_attrs,
+-      .ct_owner       = THIS_MODULE,
+-};
+-
+ static void fsg_free_inst(struct usb_function_instance *fi)
+ {
+       struct fsg_opts *opts;
+@@ -3690,13 +3345,11 @@ static void fsg_free_inst(struct usb_function_instance *fi)
+ static struct usb_function_instance *fsg_alloc_inst(void)
+ {
+       struct fsg_opts *opts;
+-      struct fsg_lun_config config;
+       int ret;
+       opts = kzalloc(sizeof(*opts), GFP_KERNEL);
+       if (!opts)
+               return ERR_PTR(-ENOMEM);
+-      mutex_init(&opts->lock);
+       opts->func_inst.free_func_inst = fsg_free_inst;
+       opts->common = fsg_common_setup(opts->common, false);
+       if (IS_ERR(opts->common)) {
+@@ -3714,18 +3367,6 @@ static struct usb_function_instance *fsg_alloc_inst(void)
+       pr_info(FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
+-      memset(&config, 0, sizeof(config));
+-      config.removable = true;
+-      ret = fsg_common_create_lun(opts->common, &config, 0, "lun.0",
+-                      (const char **)&opts->func_inst.group.cg_item.ci_name);
+-      opts->lun0.lun = opts->common->luns[0];
+-      opts->lun0.lun_id = 0;
+-      config_group_init_type_name(&opts->lun0.group, "lun.0", &fsg_lun_type);
+-      opts->default_groups[0] = &opts->lun0.group;
+-      opts->func_inst.group.default_groups = opts->default_groups;
+-
+-      config_group_init_type_name(&opts->func_inst.group, "", &fsg_func_type);
+-
+       return &opts->func_inst;
+ release_luns:
+@@ -3738,14 +3379,8 @@ release_opts:
+ static void fsg_free(struct usb_function *f)
+ {
+       struct fsg_dev *fsg;
+-      struct fsg_opts *opts;
+       fsg = container_of(f, struct fsg_dev, function);
+-      opts = container_of(f->fi, struct fsg_opts, func_inst);
+-
+-      mutex_lock(&opts->lock);
+-      opts->refcnt--;
+-      mutex_unlock(&opts->lock);
+       kfree(fsg);
+ }
+@@ -3776,9 +3411,6 @@ static struct usb_function *fsg_alloc(struct usb_function_instance *fi)
+       if (unlikely(!fsg))
+               return ERR_PTR(-ENOMEM);
+-      mutex_lock(&opts->lock);
+-      opts->refcnt++;
+-      mutex_unlock(&opts->lock);
+       fsg->function.name        = FSG_DRIVER_DESC;
+       fsg->function.bind        = fsg_bind;
+       fsg->function.unbind      = fsg_unbind;
+diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h
+index 62b4b8f..7aed1d9 100644
+--- a/drivers/usb/gadget/f_mass_storage.h
++++ b/drivers/usb/gadget/f_mass_storage.h
+@@ -71,27 +71,10 @@ struct fsg_operations {
+       int (*thread_exits)(struct fsg_common *common);
+ };
+-struct fsg_lun_opts {
+-      struct config_group group;
+-      struct fsg_lun *lun;
+-      int lun_id;
+-};
+-
+ struct fsg_opts {
+       struct fsg_common *common;
+       struct usb_function_instance func_inst;
+-      struct fsg_lun_opts lun0;
+-      struct config_group *default_groups[2];
+       bool no_configfs; /* for legacy gadgets */
+-
+-      /*
+-       * Read/write access to configfs attributes is handled by configfs.
+-       *
+-       * This is to protect the data from concurrent access by read/write
+-       * and create symlink/remove symlink.
+-       */
+-      struct mutex                    lock;
+-      int                             refcnt;
+ };
+ struct fsg_lun_config {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1091-Revert-usb-gadget-storage_common-add-methods-to-show.patch b/patches.tizen/1091-Revert-usb-gadget-storage_common-add-methods-to-show.patch
new file mode 100644 (file)
index 0000000..888a83e
--- /dev/null
@@ -0,0 +1,95 @@
+From 52ab80c1f746a5564bd119074166e139024c2711 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 14 Jan 2014 14:26:40 +0100
+Subject: [PATCH 1091/1302] Revert "usb/gadget: storage_common: add methods to
+ show/store 'cdrom' and 'removable'"
+
+This reverts commit 80b546ca2f7a1d6714022e3c791635d7b6ba9766.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/storage_common.c | 42 -------------------------------------
+ drivers/usb/gadget/storage_common.h |  5 -----
+ 2 files changed, 47 deletions(-)
+
+diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
+index d59b555..ab83d11 100644
+--- a/drivers/usb/gadget/storage_common.c
++++ b/drivers/usb/gadget/storage_common.c
+@@ -359,17 +359,6 @@ ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+ }
+ EXPORT_SYMBOL(fsg_show_file);
+-ssize_t fsg_show_cdrom(struct fsg_lun *curlun, char *buf)
+-{
+-      return sprintf(buf, "%u\n", curlun->cdrom);
+-}
+-EXPORT_SYMBOL(fsg_show_cdrom);
+-
+-ssize_t fsg_show_removable(struct fsg_lun *curlun, char *buf)
+-{
+-      return sprintf(buf, "%u\n", curlun->removable);
+-}
+-EXPORT_SYMBOL(fsg_show_removable);
+ ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                           const char *buf, size_t count)
+@@ -450,35 +439,4 @@ ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+ }
+ EXPORT_SYMBOL(fsg_store_file);
+-ssize_t fsg_store_cdrom(struct fsg_lun *curlun, const char *buf, size_t count)
+-{
+-      unsigned        cdrom;
+-      int             ret;
+-
+-      ret = kstrtouint(buf, 2, &cdrom);
+-      if (ret)
+-              return ret;
+-
+-      curlun->cdrom = cdrom;
+-
+-      return count;
+-}
+-EXPORT_SYMBOL(fsg_store_cdrom);
+-
+-ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf,
+-                          size_t count)
+-{
+-      unsigned        removable;
+-      int             ret;
+-
+-      ret = kstrtouint(buf, 2, &removable);
+-      if (ret)
+-              return ret;
+-
+-      curlun->removable = removable;
+-
+-      return count;
+-}
+-EXPORT_SYMBOL(fsg_store_removable);
+-
+ MODULE_LICENSE("GPL");
+diff --git a/drivers/usb/gadget/storage_common.h b/drivers/usb/gadget/storage_common.h
+index ca7b479..aa8bf94 100644
+--- a/drivers/usb/gadget/storage_common.h
++++ b/drivers/usb/gadget/storage_common.h
+@@ -214,15 +214,10 @@ ssize_t fsg_show_ro(struct fsg_lun *curlun, char *buf);
+ ssize_t fsg_show_nofua(struct fsg_lun *curlun, char *buf);
+ ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                     char *buf);
+-ssize_t fsg_show_cdrom(struct fsg_lun *curlun, char *buf);
+-ssize_t fsg_show_removable(struct fsg_lun *curlun, char *buf);
+ ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                    const char *buf, size_t count);
+ ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count);
+ ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                      const char *buf, size_t count);
+-ssize_t fsg_store_cdrom(struct fsg_lun *curlun, const char *buf, size_t count);
+-ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf,
+-                          size_t count);
+ #endif /* USB_STORAGE_COMMON_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1092-Revert-usb-gadget-storage_common-make-attribute-oper.patch b/patches.tizen/1092-Revert-usb-gadget-storage_common-make-attribute-oper.patch
new file mode 100644 (file)
index 0000000..80bcc8f
--- /dev/null
@@ -0,0 +1,233 @@
+From 949e592a88d733ae7c69e297937a79e7a3cf7ecb Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 14 Jan 2014 14:26:43 +0100
+Subject: [PATCH 1092/1302] Revert "usb/gadget: storage_common: make attribute
+ operations more generic"
+
+This reverts commit 724a908e741cbd713c95f2a2cedb6a4c7d97ed38.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 67 +++----------------------------------
+ drivers/usb/gadget/storage_common.c | 36 +++++++++++++++-----
+ drivers/usb/gadget/storage_common.h | 21 ++++++------
+ 3 files changed, 43 insertions(+), 81 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index aaa8349..0a2b3ae 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -2570,71 +2570,14 @@ static int fsg_main_thread(void *common_)
+ /*************************** DEVICE ATTRIBUTES ***************************/
+-static ssize_t sysfs_fsg_show_ro(struct device *dev,
+-                               struct device_attribute *attr,
+-                               char *buf)
+-{
+-      struct fsg_lun          *curlun = fsg_lun_from_dev(dev);
+-
+-      return fsg_show_ro(curlun, buf);
+-}
+-
+-static ssize_t sysfs_fsg_show_nofua(struct device *dev,
+-                                  struct device_attribute *attr,
+-                                  char *buf)
+-{
+-      struct fsg_lun          *curlun = fsg_lun_from_dev(dev);
+-
+-      return fsg_show_nofua(curlun, buf);
+-}
+-
+-static ssize_t sysfs_fsg_show_file(struct device *dev,
+-                                 struct device_attribute *attr,
+-                                 char *buf)
+-{
+-      struct fsg_lun          *curlun = fsg_lun_from_dev(dev);
+-      struct rw_semaphore     *filesem = dev_get_drvdata(dev);
+-
+-      return fsg_show_file(curlun, filesem, buf);
+-}
+-
+-static ssize_t sysfs_fsg_store_ro(struct device *dev,
+-                                struct device_attribute *attr,
+-                                const char *buf, size_t count)
+-{
+-      struct fsg_lun          *curlun = fsg_lun_from_dev(dev);
+-      struct rw_semaphore     *filesem = dev_get_drvdata(dev);
+-
+-      return fsg_store_ro(curlun, filesem, buf, count);
+-}
+-
+-static ssize_t sysfs_fsg_store_nofua(struct device *dev,
+-                                   struct device_attribute *attr,
+-                                   const char *buf, size_t count)
+-{
+-      struct fsg_lun          *curlun = fsg_lun_from_dev(dev);
+-
+-      return fsg_store_nofua(curlun, buf, count);
+-}
+-
+-static ssize_t sysfs_fsg_store_file(struct device *dev,
+-                                  struct device_attribute *attr,
+-                                  const char *buf, size_t count)
+-{
+-      struct fsg_lun          *curlun = fsg_lun_from_dev(dev);
+-      struct rw_semaphore     *filesem = dev_get_drvdata(dev);
+-
+-      return fsg_store_file(curlun, filesem, buf, count);
+-}
+-
+-static DEVICE_ATTR(ro, 0644, sysfs_fsg_show_ro, sysfs_fsg_store_ro);
+-static DEVICE_ATTR(nofua, 0644, sysfs_fsg_show_nofua, sysfs_fsg_store_nofua);
+-static DEVICE_ATTR(file, 0644, sysfs_fsg_show_file, sysfs_fsg_store_file);
++static DEVICE_ATTR(ro, 0644, fsg_show_ro, fsg_store_ro);
++static DEVICE_ATTR(nofua, 0644, fsg_show_nofua, fsg_store_nofua);
++static DEVICE_ATTR(file, 0644, fsg_show_file, fsg_store_file);
+ static struct device_attribute dev_attr_ro_cdrom =
+-      __ATTR(ro, 0444, sysfs_fsg_show_ro, NULL);
++      __ATTR(ro, 0444, fsg_show_ro, NULL);
+ static struct device_attribute dev_attr_file_nonremovable =
+-      __ATTR(file, 0444, sysfs_fsg_show_file, NULL);
++      __ATTR(file, 0444, fsg_show_file, NULL);
+ /****************************** FSG COMMON ******************************/
+diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
+index ab83d11..942324c 100644
+--- a/drivers/usb/gadget/storage_common.c
++++ b/drivers/usb/gadget/storage_common.c
+@@ -31,6 +31,11 @@
+ #include "storage_common.h"
++static inline struct fsg_lun *fsg_lun_from_dev(struct device *dev)
++{
++      return container_of(dev, struct fsg_lun, dev);
++}
++
+ /* There is only one interface. */
+ struct usb_interface_descriptor fsg_intf_desc = {
+@@ -319,23 +324,31 @@ EXPORT_SYMBOL(store_cdrom_address);
+ /*-------------------------------------------------------------------------*/
+-ssize_t fsg_show_ro(struct fsg_lun *curlun, char *buf)
++ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr,
++                         char *buf)
+ {
++      struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
++
+       return sprintf(buf, "%d\n", fsg_lun_is_open(curlun)
+                                 ? curlun->ro
+                                 : curlun->initially_ro);
+ }
+ EXPORT_SYMBOL(fsg_show_ro);
+-ssize_t fsg_show_nofua(struct fsg_lun *curlun, char *buf)
++ssize_t fsg_show_nofua(struct device *dev, struct device_attribute *attr,
++                            char *buf)
+ {
++      struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
++
+       return sprintf(buf, "%u\n", curlun->nofua);
+ }
+ EXPORT_SYMBOL(fsg_show_nofua);
+-ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+-                    char *buf)
++ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
++                           char *buf)
+ {
++      struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
++      struct rw_semaphore     *filesem = dev_get_drvdata(dev);
+       char            *p;
+       ssize_t         rc;
+@@ -360,10 +373,12 @@ ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+ EXPORT_SYMBOL(fsg_show_file);
+-ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem,
++ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr,
+                           const char *buf, size_t count)
+ {
+       ssize_t         rc;
++      struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
++      struct rw_semaphore     *filesem = dev_get_drvdata(dev);
+       unsigned        ro;
+       rc = kstrtouint(buf, 2, &ro);
+@@ -389,8 +404,11 @@ ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+ }
+ EXPORT_SYMBOL(fsg_store_ro);
+-ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count)
++ssize_t fsg_store_nofua(struct device *dev,
++                             struct device_attribute *attr,
++                             const char *buf, size_t count)
+ {
++      struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+       unsigned        nofua;
+       int             ret;
+@@ -408,9 +426,11 @@ ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count)
+ }
+ EXPORT_SYMBOL(fsg_store_nofua);
+-ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+-                     const char *buf, size_t count)
++ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr,
++                            const char *buf, size_t count)
+ {
++      struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
++      struct rw_semaphore     *filesem = dev_get_drvdata(dev);
+       int             rc = 0;
+       if (curlun->prevent_medium_removal && fsg_lun_is_open(curlun)) {
+diff --git a/drivers/usb/gadget/storage_common.h b/drivers/usb/gadget/storage_common.h
+index aa8bf94..9955477 100644
+--- a/drivers/usb/gadget/storage_common.h
++++ b/drivers/usb/gadget/storage_common.h
+@@ -181,11 +181,6 @@ static inline u32 get_unaligned_be24(u8 *buf)
+       return 0xffffff & (u32) get_unaligned_be32(buf - 1);
+ }
+-static inline struct fsg_lun *fsg_lun_from_dev(struct device *dev)
+-{
+-      return container_of(dev, struct fsg_lun, dev);
+-}
+-
+ enum {
+       FSG_STRING_INTERFACE
+ };
+@@ -210,14 +205,18 @@ void fsg_lun_close(struct fsg_lun *curlun);
+ int fsg_lun_open(struct fsg_lun *curlun, const char *filename);
+ int fsg_lun_fsync_sub(struct fsg_lun *curlun);
+ void store_cdrom_address(u8 *dest, int msf, u32 addr);
+-ssize_t fsg_show_ro(struct fsg_lun *curlun, char *buf);
+-ssize_t fsg_show_nofua(struct fsg_lun *curlun, char *buf);
+-ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
++ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr,
++                  char *buf);
++ssize_t fsg_show_nofua(struct device *dev, struct device_attribute *attr,
++                     char *buf);
++ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
+                     char *buf);
+-ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem,
++ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr,
+                    const char *buf, size_t count);
+-ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count);
+-ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
++ssize_t fsg_store_nofua(struct device *dev,
++                      struct device_attribute *attr,
++                      const char *buf, size_t count);
++ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr,
+                      const char *buf, size_t count);
+ #endif /* USB_STORAGE_COMMON_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1093-Revert-usb-gadget-mass_storage-convert-to-new-interf.patch b/patches.tizen/1093-Revert-usb-gadget-mass_storage-convert-to-new-interf.patch
new file mode 100644 (file)
index 0000000..f99e0ae
--- /dev/null
@@ -0,0 +1,199 @@
+From 3e86794e078359b8b74558cf647a121606686fa5 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 14 Jan 2014 14:26:46 +0100
+Subject: [PATCH 1093/1302] Revert "usb/gadget: mass_storage: convert to new
+ interface of f_mass_storage"
+
+This reverts commit d42b40a01037255c0609cfae1607bdf7524c8c75.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig        |   1 -
+ drivers/usb/gadget/mass_storage.c | 107 ++++++++++----------------------------
+ 2 files changed, 27 insertions(+), 81 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 6214b79..99a9f04 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -897,7 +897,6 @@ config USB_MASS_STORAGE
+       depends on BLOCK
+       select USB_LIBCOMPOSITE
+       select USB_U_MS
+-      select USB_F_MASS_STORAGE
+       help
+         The Mass Storage Gadget acts as a USB Mass Storage disk drive.
+         As its storage repository it can use a regular file or a block
+diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c
+index 39a5316..6b79814 100644
+--- a/drivers/usb/gadget/mass_storage.c
++++ b/drivers/usb/gadget/mass_storage.c
+@@ -46,7 +46,17 @@
+ #define FSG_VENDOR_ID 0x0525  /* NetChip */
+ #define FSG_PRODUCT_ID        0xa4a5  /* Linux-USB File-backed Storage Gadget */
+-#include "f_mass_storage.h"
++/*-------------------------------------------------------------------------*/
++
++/*
++ * kbuild is not very cooperative with respect to linking separately
++ * compiled library objects into one module.  So for now we won't use
++ * separate compilation ... ensuring init/exit sections work to shrink
++ * the runtime footprint, and giving us at least some parts of what
++ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
++ */
++#define USB_FMS_INCLUDED
++#include "f_mass_storage.c"
+ /*-------------------------------------------------------------------------*/
+ USB_GADGET_COMPOSITE_OPTIONS();
+@@ -97,9 +107,6 @@ static struct usb_gadget_strings *dev_strings[] = {
+       NULL,
+ };
+-static struct usb_function_instance *fi_msg;
+-static struct usb_function *f_msg;
+-
+ /****************************** Configurations ******************************/
+ static struct fsg_module_parameters mod_data = {
+@@ -132,7 +139,13 @@ static int msg_thread_exits(struct fsg_common *common)
+ static int __init msg_do_config(struct usb_configuration *c)
+ {
+-      struct fsg_opts *opts;
++      static const struct fsg_operations ops = {
++              .thread_exits = msg_thread_exits,
++      };
++      static struct fsg_common common;
++
++      struct fsg_common *retp;
++      struct fsg_config config;
+       int ret;
+       if (gadget_is_otg(c->cdev->gadget)) {
+@@ -140,24 +153,15 @@ static int __init msg_do_config(struct usb_configuration *c)
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+-      opts = container_of(fi_msg, struct fsg_opts, func_inst);
+-
+-      f_msg = usb_get_function(fi_msg);
+-      if (IS_ERR(f_msg))
+-              return PTR_ERR(f_msg);
+-
+-      ret = fsg_common_run_thread(opts->common);
+-      if (ret)
+-              goto put_func;
++      fsg_config_from_params(&config, &mod_data, fsg_num_buffers);
++      config.ops = &ops;
+-      ret = usb_add_function(c, f_msg);
+-      if (ret)
+-              goto put_func;
++      retp = fsg_common_init(&common, c->cdev, &config);
++      if (IS_ERR(retp))
++              return PTR_ERR(retp);
+-      return 0;
+-
+-put_func:
+-      usb_put_function(f_msg);
++      ret = fsg_bind_config(c->cdev, c, &common);
++      fsg_common_put(&common);
+       return ret;
+ }
+@@ -172,79 +176,23 @@ static struct usb_configuration msg_config_driver = {
+ static int __init msg_bind(struct usb_composite_dev *cdev)
+ {
+-      static const struct fsg_operations ops = {
+-              .thread_exits = msg_thread_exits,
+-      };
+-      struct fsg_opts *opts;
+-      struct fsg_config config;
+       int status;
+-      fi_msg = usb_get_function_instance("mass_storage");
+-      if (IS_ERR(fi_msg))
+-              return PTR_ERR(fi_msg);
+-
+-      fsg_config_from_params(&config, &mod_data, fsg_num_buffers);
+-      opts = container_of(fi_msg, struct fsg_opts, func_inst);
+-
+-      opts->no_configfs = true;
+-      status = fsg_common_set_num_buffers(opts->common, fsg_num_buffers);
+-      if (status)
+-              goto fail;
+-
+-      status = fsg_common_set_nluns(opts->common, config.nluns);
+-      if (status)
+-              goto fail_set_nluns;
+-
+-      fsg_common_set_ops(opts->common, &ops);
+-
+-      status = fsg_common_set_cdev(opts->common, cdev, config.can_stall);
+-      if (status)
+-              goto fail_set_cdev;
+-
+-      fsg_common_set_sysfs(opts->common, true);
+-      status = fsg_common_create_luns(opts->common, &config);
+-      if (status)
+-              goto fail_set_cdev;
+-
+-      fsg_common_set_inquiry_string(opts->common, config.vendor_name,
+-                                    config.product_name);
+-
+       status = usb_string_ids_tab(cdev, strings_dev);
+       if (status < 0)
+-              goto fail_string_ids;
++              return status;
+       msg_device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id;
+       status = usb_add_config(cdev, &msg_config_driver, msg_do_config);
+       if (status < 0)
+-              goto fail_string_ids;
+-
++              return status;
+       usb_composite_overwrite_options(cdev, &coverwrite);
+       dev_info(&cdev->gadget->dev,
+                DRIVER_DESC ", version: " DRIVER_VERSION "\n");
+       set_bit(0, &msg_registered);
+       return 0;
+-
+-fail_string_ids:
+-      fsg_common_remove_luns(opts->common);
+-fail_set_cdev:
+-      fsg_common_free_luns(opts->common);
+-fail_set_nluns:
+-      fsg_common_free_buffers(opts->common);
+-fail:
+-      usb_put_function_instance(fi_msg);
+-      return status;
+ }
+-static int msg_unbind(struct usb_composite_dev *cdev)
+-{
+-      if (!IS_ERR(f_msg))
+-              usb_put_function(f_msg);
+-
+-      if (!IS_ERR(fi_msg))
+-              usb_put_function_instance(fi_msg);
+-
+-      return 0;
+-}
+ /****************************** Some noise ******************************/
+@@ -255,7 +203,6 @@ static __refdata struct usb_composite_driver msg_driver = {
+       .needs_serial   = 1,
+       .strings        = dev_strings,
+       .bind           = msg_bind,
+-      .unbind         = msg_unbind,
+ };
+ MODULE_DESCRIPTION(DRIVER_DESC);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1094-Revert-usb-gadget-f_mass_storage-convert-to-new-func.patch b/patches.tizen/1094-Revert-usb-gadget-f_mass_storage-convert-to-new-func.patch
new file mode 100644 (file)
index 0000000..7ae179a
--- /dev/null
@@ -0,0 +1,491 @@
+From e60b7fc8327002cd5ea7c5a9631a144d8ee41453 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 14 Jan 2014 14:26:50 +0100
+Subject: [PATCH 1094/1302] Revert "usb/gadget: f_mass_storage: convert to new
+ function interface with backward compatibility"
+
+This reverts commit 2cac3870c00b16a061c42fc4bbd2fd67e957d147.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig          |   3 -
+ drivers/usb/gadget/Makefile         |   2 -
+ drivers/usb/gadget/acm_ms.c         |   1 -
+ drivers/usb/gadget/f_mass_storage.c | 217 ++++--------------------------------
+ drivers/usb/gadget/f_mass_storage.h |   7 --
+ drivers/usb/gadget/mass_storage.c   |   1 -
+ drivers/usb/gadget/multi.c          |   1 -
+ 7 files changed, 20 insertions(+), 212 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 99a9f04..ecfcbab 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -540,9 +540,6 @@ config USB_F_RNDIS
+ config USB_U_MS
+       tristate
+-config USB_F_MASS_STORAGE
+-      tristate
+-
+ choice
+       tristate "USB Gadget Drivers"
+       default USB_ETH
+diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
+index 62ccbda..295df78 100644
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -62,8 +62,6 @@ usb_f_rndis-y                        := f_rndis.o
+ obj-$(CONFIG_USB_F_RNDIS)     += usb_f_rndis.o
+ u_ms-y                                := storage_common.o
+ obj-$(CONFIG_USB_U_MS)                += u_ms.o
+-usb_f_mass_storage-y          := f_mass_storage.o
+-obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o
+ #
+ # USB gadget drivers
+diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c
+index 31aae8f..992ffb0 100644
+--- a/drivers/usb/gadget/acm_ms.c
++++ b/drivers/usb/gadget/acm_ms.c
+@@ -40,7 +40,6 @@
+  * the runtime footprint, and giving us at least some parts of what
+  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+  */
+-#define USB_FMS_INCLUDED
+ #include "f_mass_storage.c"
+ /*-------------------------------------------------------------------------*/
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 0a2b3ae..7ef99f1 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -213,7 +213,6 @@
+ #include <linux/spinlock.h>
+ #include <linux/string.h>
+ #include <linux/freezer.h>
+-#include <linux/module.h>
+ #include <linux/usb/ch9.h>
+ #include <linux/usb/gadget.h>
+@@ -2593,17 +2592,11 @@ void fsg_common_get(struct fsg_common *common)
+ {
+       kref_get(&common->ref);
+ }
+-#ifndef USB_FMS_INCLUDED
+-EXPORT_SYMBOL(fsg_common_get);
+-#endif
+ void fsg_common_put(struct fsg_common *common)
+ {
+       kref_put(&common->ref, fsg_common_release);
+ }
+-#ifndef USB_FMS_INCLUDED
+-EXPORT_SYMBOL(fsg_common_put);
+-#endif
+ /* check if fsg_num_buffers is within a valid range */
+ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
+@@ -2641,9 +2634,6 @@ void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs)
+ {
+       common->sysfs = sysfs;
+ }
+-#ifndef USB_FMS_INCLUDED
+-EXPORT_SYMBOL(fsg_common_set_sysfs);
+-#endif
+ static void _fsg_common_free_buffers(struct fsg_buffhd *buffhds, unsigned n)
+ {
+@@ -2695,18 +2685,12 @@ error_release:
+       return -ENOMEM;
+ }
+-#ifndef USB_FMS_INCLUDED
+-EXPORT_SYMBOL(fsg_common_set_num_buffers);
+-#endif
+ void fsg_common_free_buffers(struct fsg_common *common)
+ {
+       _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
+       common->buffhds = NULL;
+ }
+-#ifndef USB_FMS_INCLUDED
+-EXPORT_SYMBOL(fsg_common_free_buffers);
+-#endif
+ int fsg_common_set_nluns(struct fsg_common *common, int nluns)
+ {
+@@ -2732,9 +2716,6 @@ int fsg_common_set_nluns(struct fsg_common *common, int nluns)
+       return 0;
+ }
+-#ifndef USB_FMS_INCLUDED
+-EXPORT_SYMBOL(fsg_common_set_nluns);
+-#endif
+ void fsg_common_free_luns(struct fsg_common *common)
+ {
+@@ -2742,26 +2723,17 @@ void fsg_common_free_luns(struct fsg_common *common)
+       kfree(common->luns);
+       common->luns = NULL;
+ }
+-#ifndef USB_FMS_INCLUDED
+-EXPORT_SYMBOL(fsg_common_free_luns);
+-#endif
+ void fsg_common_set_ops(struct fsg_common *common,
+                       const struct fsg_operations *ops)
+ {
+       common->ops = ops;
+ }
+-#ifndef USB_FMS_INCLUDED
+-EXPORT_SYMBOL(fsg_common_set_ops);
+-#endif
+ void fsg_common_set_private_data(struct fsg_common *common, void *priv)
+ {
+       common->private_data = priv;
+ }
+-#ifndef USB_FMS_INCLUDED
+-EXPORT_SYMBOL(fsg_common_set_private_data);
+-#endif
+ int fsg_common_set_cdev(struct fsg_common *common,
+                        struct usb_composite_dev *cdev, bool can_stall)
+@@ -2791,9 +2763,6 @@ int fsg_common_set_cdev(struct fsg_common *common,
+       return 0;
+ }
+-#ifndef USB_FMS_INCLUDED
+-EXPORT_SYMBOL(fsg_common_set_cdev);
+-#endif
+ static inline int fsg_common_add_sysfs(struct fsg_common *common,
+                                      struct fsg_lun *lun)
+@@ -2858,9 +2827,6 @@ void fsg_common_remove_lun(struct fsg_lun *lun, bool sysfs)
+       kfree(lun->name);
+       kfree(lun);
+ }
+-#ifndef USB_FMS_INCLUDED
+-EXPORT_SYMBOL(fsg_common_remove_lun);
+-#endif
+ void _fsg_common_remove_luns(struct fsg_common *common, int n)
+ {
+@@ -2877,9 +2843,6 @@ void fsg_common_remove_luns(struct fsg_common *common)
+ {
+       _fsg_common_remove_luns(common, common->nluns);
+ }
+-#ifndef USB_FMS_INCLUDED
+-EXPORT_SYMBOL(fsg_common_remove_luns);
+-#endif
+ #define MAX_LUN_NAME_LEN 80
+@@ -2976,9 +2939,6 @@ error_name:
+       kfree(lun);
+       return rc;
+ }
+-#ifndef USB_FMS_INCLUDED
+-EXPORT_SYMBOL(fsg_common_create_lun);
+-#endif
+ int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg)
+ {
+@@ -3000,9 +2960,6 @@ fail:
+       _fsg_common_remove_luns(common, i);
+       return rc;
+ }
+-#ifndef USB_FMS_INCLUDED
+-EXPORT_SYMBOL(fsg_common_create_luns);
+-#endif
+ void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
+                                  const char *pn)
+@@ -3019,9 +2976,6 @@ void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
+                    : "File-Stor Gadget"),
+                i);
+ }
+-#ifndef USB_FMS_INCLUDED
+-EXPORT_SYMBOL(fsg_common_set_inquiry_string);
+-#endif
+ int fsg_common_run_thread(struct fsg_common *common)
+ {
+@@ -3040,9 +2994,6 @@ int fsg_common_run_thread(struct fsg_common *common)
+       return 0;
+ }
+-#ifndef USB_FMS_INCLUDED
+-EXPORT_SYMBOL(fsg_common_run_thread);
+-#endif
+ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                  struct usb_composite_dev *cdev,
+@@ -3097,9 +3048,6 @@ error_release:
+       fsg_common_release(&common->ref);
+       return ERR_PTR(rc);
+ }
+-#ifndef USB_FMS_INCLUDED
+-EXPORT_SYMBOL(fsg_common_init);
+-#endif
+ static void fsg_common_release(struct kref *ref)
+ {
+@@ -3142,6 +3090,24 @@ static void fsg_common_release(struct kref *ref)
+ /*-------------------------------------------------------------------------*/
++static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
++{
++      struct fsg_dev          *fsg = fsg_from_func(f);
++      struct fsg_common       *common = fsg->common;
++
++      DBG(fsg, "unbind\n");
++      if (fsg->common->fsg == fsg) {
++              fsg->common->new_fsg = NULL;
++              raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
++              /* FIXME: make interruptible or killable somehow? */
++              wait_event(common->fsg_wait, common->fsg != fsg);
++      }
++
++      fsg_common_put(common);
++      usb_free_all_descriptors(&fsg->function);
++      kfree(fsg);
++}
++
+ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
+ {
+       struct fsg_dev          *fsg = fsg_from_func(f);
+@@ -3151,21 +3117,6 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
+       unsigned                max_burst;
+       int                     ret;
+-#ifndef USB_FMS_INCLUDED
+-      struct fsg_opts         *opts;
+-      opts = container_of(f->fi, struct fsg_opts, func_inst);
+-      if (!opts->no_configfs) {
+-              ret = fsg_common_set_cdev(fsg->common, c->cdev,
+-                                        fsg->common->can_stall);
+-              if (ret)
+-                      return ret;
+-              fsg_common_set_inquiry_string(fsg->common, 0, 0);
+-              ret = fsg_common_run_thread(fsg->common);
+-              if (ret)
+-                      return ret;
+-      }
+-#endif
+-
+       fsg->gadget = gadget;
+       /* New interface */
+@@ -3217,27 +3168,7 @@ autoconf_fail:
+       return -ENOTSUPP;
+ }
+-/****************************** ALLOCATE FUNCTION *************************/
+-
+-#ifdef USB_FMS_INCLUDED
+-
+-static void old_fsg_unbind(struct usb_configuration *c, struct usb_function *f)
+-{
+-      struct fsg_dev          *fsg = fsg_from_func(f);
+-      struct fsg_common       *common = fsg->common;
+-
+-      DBG(fsg, "unbind\n");
+-      if (fsg->common->fsg == fsg) {
+-              fsg->common->new_fsg = NULL;
+-              raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
+-              /* FIXME: make interruptible or killable somehow? */
+-              wait_event(common->fsg_wait, common->fsg != fsg);
+-      }
+-
+-      fsg_common_put(common);
+-      usb_free_all_descriptors(&fsg->function);
+-      kfree(fsg);
+-}
++/****************************** ADD FUNCTION ******************************/
+ static int fsg_bind_config(struct usb_composite_dev *cdev,
+                          struct usb_configuration *c,
+@@ -3252,7 +3183,7 @@ static int fsg_bind_config(struct usb_composite_dev *cdev,
+       fsg->function.name        = FSG_DRIVER_DESC;
+       fsg->function.bind        = fsg_bind;
+-      fsg->function.unbind      = old_fsg_unbind;
++      fsg->function.unbind      = fsg_unbind;
+       fsg->function.setup       = fsg_setup;
+       fsg->function.set_alt     = fsg_set_alt;
+       fsg->function.disable     = fsg_disable;
+@@ -3274,111 +3205,6 @@ static int fsg_bind_config(struct usb_composite_dev *cdev,
+       return rc;
+ }
+-#else
+-
+-static void fsg_free_inst(struct usb_function_instance *fi)
+-{
+-      struct fsg_opts *opts;
+-
+-      opts = container_of(fi, struct fsg_opts, func_inst);
+-      fsg_common_put(opts->common);
+-      kfree(opts);
+-}
+-
+-static struct usb_function_instance *fsg_alloc_inst(void)
+-{
+-      struct fsg_opts *opts;
+-      int ret;
+-
+-      opts = kzalloc(sizeof(*opts), GFP_KERNEL);
+-      if (!opts)
+-              return ERR_PTR(-ENOMEM);
+-      opts->func_inst.free_func_inst = fsg_free_inst;
+-      opts->common = fsg_common_setup(opts->common, false);
+-      if (IS_ERR(opts->common)) {
+-              ret = PTR_ERR(opts->common);
+-              goto release_opts;
+-      }
+-      ret = fsg_common_set_nluns(opts->common, FSG_MAX_LUNS);
+-      if (ret)
+-              goto release_opts;
+-
+-      ret = fsg_common_set_num_buffers(opts->common,
+-                                       CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS);
+-      if (ret)
+-              goto release_luns;
+-
+-      pr_info(FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
+-
+-      return &opts->func_inst;
+-
+-release_luns:
+-      kfree(opts->common->luns);
+-release_opts:
+-      kfree(opts);
+-      return ERR_PTR(ret);
+-}
+-
+-static void fsg_free(struct usb_function *f)
+-{
+-      struct fsg_dev *fsg;
+-
+-      fsg = container_of(f, struct fsg_dev, function);
+-
+-      kfree(fsg);
+-}
+-
+-static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
+-{
+-      struct fsg_dev          *fsg = fsg_from_func(f);
+-      struct fsg_common       *common = fsg->common;
+-
+-      DBG(fsg, "unbind\n");
+-      if (fsg->common->fsg == fsg) {
+-              fsg->common->new_fsg = NULL;
+-              raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
+-              /* FIXME: make interruptible or killable somehow? */
+-              wait_event(common->fsg_wait, common->fsg != fsg);
+-      }
+-
+-      usb_free_all_descriptors(&fsg->function);
+-}
+-
+-static struct usb_function *fsg_alloc(struct usb_function_instance *fi)
+-{
+-      struct fsg_opts *opts = container_of(fi, struct fsg_opts, func_inst);
+-      struct fsg_common *common = opts->common;
+-      struct fsg_dev *fsg;
+-
+-      fsg = kzalloc(sizeof(*fsg), GFP_KERNEL);
+-      if (unlikely(!fsg))
+-              return ERR_PTR(-ENOMEM);
+-
+-      fsg->function.name        = FSG_DRIVER_DESC;
+-      fsg->function.bind        = fsg_bind;
+-      fsg->function.unbind      = fsg_unbind;
+-      fsg->function.setup       = fsg_setup;
+-      fsg->function.set_alt     = fsg_set_alt;
+-      fsg->function.disable     = fsg_disable;
+-      fsg->function.free_func   = fsg_free;
+-
+-      fsg->common               = common;
+-      /*
+-       * Our caller holds a reference to common structure so we
+-       * don't have to be worry about it being freed until we return
+-       * from this function.  So instead of incrementing counter now
+-       * and decrement in error recovery we increment it only when
+-       * call to usb_add_function() was successful.
+-       */
+-
+-      return &fsg->function;
+-}
+-
+-DECLARE_USB_FUNCTION_INIT(mass_storage, fsg_alloc_inst, fsg_alloc);
+-MODULE_LICENSE("GPL");
+-MODULE_AUTHOR("Michal Nazarewicz");
+-
+-#endif
+ /************************* Module parameters *************************/
+@@ -3415,7 +3241,4 @@ void fsg_config_from_params(struct fsg_config *cfg,
+       cfg->can_stall = params->stall;
+       cfg->fsg_num_buffers = fsg_num_buffers;
+ }
+-#ifndef USB_FMS_INCLUDED
+-EXPORT_SYMBOL(fsg_config_from_params);
+-#endif
+diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h
+index 7aed1d9..4445e82 100644
+--- a/drivers/usb/gadget/f_mass_storage.h
++++ b/drivers/usb/gadget/f_mass_storage.h
+@@ -1,7 +1,6 @@
+ #ifndef USB_F_MASS_STORAGE_H
+ #define USB_F_MASS_STORAGE_H
+-#include <linux/usb/composite.h>
+ #include "storage_common.h"
+ struct fsg_module_parameters {
+@@ -71,12 +70,6 @@ struct fsg_operations {
+       int (*thread_exits)(struct fsg_common *common);
+ };
+-struct fsg_opts {
+-      struct fsg_common *common;
+-      struct usb_function_instance func_inst;
+-      bool no_configfs; /* for legacy gadgets */
+-};
+-
+ struct fsg_lun_config {
+       const char *filename;
+       char ro;
+diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c
+index 6b79814..bf60a9a 100644
+--- a/drivers/usb/gadget/mass_storage.c
++++ b/drivers/usb/gadget/mass_storage.c
+@@ -55,7 +55,6 @@
+  * the runtime footprint, and giving us at least some parts of what
+  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+  */
+-#define USB_FMS_INCLUDED
+ #include "f_mass_storage.c"
+ /*-------------------------------------------------------------------------*/
+diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
+index c232f76..f610d01 100644
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -41,7 +41,6 @@ MODULE_LICENSE("GPL");
+  * the runtime footprint, and giving us at least some parts of what
+  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+  */
+-#define USB_FMS_INCLUDED
+ #include "f_mass_storage.c"
+ #define USBF_ECM_INCLUDED
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1095-Revert-usb-gadget-f_mass_storage-use-fsg_common_run_.patch b/patches.tizen/1095-Revert-usb-gadget-f_mass_storage-use-fsg_common_run_.patch
new file mode 100644 (file)
index 0000000..d5e5da9
--- /dev/null
@@ -0,0 +1,45 @@
+From 2a4849f334b830ca09bfe267a4240cca658c7fa3 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 14 Jan 2014 14:26:58 +0100
+Subject: [PATCH 1095/1302] Revert "usb/gadget: f_mass_storage: use
+ fsg_common_run_thread in fsg_common_init"
+
+This reverts commit 9fc1ddf14878e584464ab110ee5150d6ac3151ef.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 7ef99f1..fcc6409 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -3032,13 +3032,21 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       fsg_common_set_inquiry_string(common, cfg->vendor_name,
+                                     cfg->product_name);
++      /* Tell the thread to start working */
++      common->thread_task =
++              kthread_create(fsg_main_thread, common, "file-storage");
++      if (IS_ERR(common->thread_task)) {
++              rc = PTR_ERR(common->thread_task);
++              goto error_release;
++      }
+       /* Information */
+       INFO(common, FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
++      INFO(common, "Number of LUNs=%d\n", common->nluns);
+-      rc = fsg_common_run_thread(common);
+-      if (rc)
+-              goto error_release;
++      DBG(common, "I/O thread pid: %d\n", task_pid_nr(common->thread_task));
++
++      wake_up_process(common->thread_task);
+       return common;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1096-Revert-usb-gadget-f_mass_storage-use-fsg_common_set_.patch b/patches.tizen/1096-Revert-usb-gadget-f_mass_storage-use-fsg_common_set_.patch
new file mode 100644 (file)
index 0000000..111406e
--- /dev/null
@@ -0,0 +1,48 @@
+From 149b5e39c9f947eb5f971873b9ca264ad515e3d5 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 14 Jan 2014 14:27:01 +0100
+Subject: [PATCH 1096/1302] Revert "usb/gadget: f_mass_storage: use
+ fsg_common_set_inquiry_string in fsg_common_init"
+
+This reverts commit 2e9cc80a04c3f5c46640f7a4d347ce37c6f26953.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index fcc6409..41a94a1 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -2999,7 +2999,7 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                  struct usb_composite_dev *cdev,
+                                  struct fsg_config *cfg)
+ {
+-      int rc;
++      int i, rc;
+       common = fsg_common_setup(common, !!common);
+       if (IS_ERR(common))
+@@ -3029,9 +3029,16 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       if (rc)
+               goto error_release;
++      /* Prepare inquiryString */
++      i = get_default_bcdDevice();
++      snprintf(common->inquiry_string, sizeof common->inquiry_string,
++               "%-8s%-16s%04x", cfg->vendor_name ?: "Linux",
++               /* Assume product name dependent on the first LUN */
++               cfg->product_name ?: ((*common->luns)->cdrom
++                                   ? "File-CD Gadget"
++                                   : "File-Stor Gadget"),
++               i);
+-      fsg_common_set_inquiry_string(common, cfg->vendor_name,
+-                                    cfg->product_name);
+       /* Tell the thread to start working */
+       common->thread_task =
+               kthread_create(fsg_main_thread, common, "file-storage");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1097-Revert-usb-gadget-f_mass_storage-use-fsg_common_crea.patch b/patches.tizen/1097-Revert-usb-gadget-f_mass_storage-use-fsg_common_crea.patch
new file mode 100644 (file)
index 0000000..8a38f79
--- /dev/null
@@ -0,0 +1,156 @@
+From c0f2fb8eda19387f29bcfe9811c608b86c65a34c Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 14 Jan 2014 14:27:04 +0100
+Subject: [PATCH 1097/1302] Revert "usb/gadget: f_mass_storage: use
+ fsg_common_create_luns in fsg_common_init"
+
+This reverts commit 681ab95e2320cb629954939a867c61de7d7b8372.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 101 ++++++++++++++++++++++++++++++++++--
+ 1 file changed, 97 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 41a94a1..9dde453 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -2999,7 +2999,12 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                  struct usb_composite_dev *cdev,
+                                  struct fsg_config *cfg)
+ {
+-      int i, rc;
++      struct usb_gadget *gadget = cdev->gadget;
++      struct fsg_lun **curlun_it;
++      struct fsg_lun_config *lcfg;
++      int nluns, i, rc;
++      char *pathbuf;
++
+       common = fsg_common_setup(common, !!common);
+       if (IS_ERR(common))
+@@ -3024,10 +3029,72 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       rc = fsg_common_set_nluns(common, cfg->nluns);
+       if (rc)
+               goto error_release;
++      curlun_it = common->luns;
++      nluns = cfg->nluns;
++      for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun_it, ++lcfg) {
++              struct fsg_lun *curlun;
++
++              curlun = kzalloc(sizeof(*curlun), GFP_KERNEL);
++              if (!curlun) {
++                      rc = -ENOMEM;
++                      common->nluns = i;
++                      goto error_release;
++              }
++              *curlun_it = curlun;
++
++              curlun->name = kzalloc(MAX_LUN_NAME_LEN, GFP_KERNEL);
++              if (!curlun->name) {
++                      rc = -ENOMEM;
++                      common->nluns = i;
++                      goto error_release;
++              }
++              curlun->cdrom = !!lcfg->cdrom;
++              curlun->ro = lcfg->cdrom || lcfg->ro;
++              curlun->initially_ro = curlun->ro;
++              curlun->removable = lcfg->removable;
++              curlun->dev.release = fsg_lun_release;
++              curlun->dev.parent = &gadget->dev;
++              /* curlun->dev.driver = &fsg_driver.driver; XXX */
++              dev_set_drvdata(&curlun->dev, &common->filesem);
++              dev_set_name(&curlun->dev, "lun%d", i);
++              strlcpy(curlun->name, dev_name(&curlun->dev), MAX_LUN_NAME_LEN);
++
++              rc = device_register(&curlun->dev);
++              if (rc) {
++                      INFO(common, "failed to register LUN%d: %d\n", i, rc);
++                      common->nluns = i;
++                      put_device(&curlun->dev);
++                      kfree(curlun);
++                      goto error_release;
++              }
++
++              rc = device_create_file(&curlun->dev,
++                                      curlun->cdrom
++                                    ? &dev_attr_ro_cdrom
++                                    : &dev_attr_ro);
++              if (rc)
++                      goto error_luns;
++              rc = device_create_file(&curlun->dev,
++                                      curlun->removable
++                                    ? &dev_attr_file
++                                    : &dev_attr_file_nonremovable);
++              if (rc)
++                      goto error_luns;
++              rc = device_create_file(&curlun->dev, &dev_attr_nofua);
++              if (rc)
++                      goto error_luns;
++
++              if (lcfg->filename) {
++                      rc = fsg_lun_open(curlun, lcfg->filename);
++                      if (rc)
++                              goto error_luns;
++              } else if (!curlun->removable) {
++                      ERROR(common, "no file given for LUN%d\n", i);
++                      rc = -EINVAL;
++                      goto error_luns;
++              }
++      }
+-      rc = fsg_common_create_luns(common, cfg);
+-      if (rc)
+-              goto error_release;
+       /* Prepare inquiryString */
+       i = get_default_bcdDevice();
+@@ -3039,6 +3106,7 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                    : "File-Stor Gadget"),
+                i);
++
+       /* Tell the thread to start working */
+       common->thread_task =
+               kthread_create(fsg_main_thread, common, "file-storage");
+@@ -3051,12 +3119,37 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       INFO(common, FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
+       INFO(common, "Number of LUNs=%d\n", common->nluns);
++      pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
++      for (i = 0, nluns = common->nluns, curlun_it = common->luns;
++           i < nluns;
++           ++curlun_it, ++i) {
++              struct fsg_lun *curlun = *curlun_it;
++              char *p = "(no medium)";
++              if (fsg_lun_is_open(curlun)) {
++                      p = "(error)";
++                      if (pathbuf) {
++                              p = d_path(&curlun->filp->f_path,
++                                         pathbuf, PATH_MAX);
++                              if (IS_ERR(p))
++                                      p = "(error)";
++                      }
++              }
++              LINFO(curlun, "LUN: %s%s%sfile: %s\n",
++                    curlun->removable ? "removable " : "",
++                    curlun->ro ? "read only " : "",
++                    curlun->cdrom ? "CD-ROM " : "",
++                    p);
++      }
++      kfree(pathbuf);
++
+       DBG(common, "I/O thread pid: %d\n", task_pid_nr(common->thread_task));
+       wake_up_process(common->thread_task);
+       return common;
++error_luns:
++      common->nluns = i + 1;
+ error_release:
+       common->state = FSG_STATE_TERMINATED;   /* The thread is dead */
+       /* Call fsg_common_release() directly, ref might be not initialised. */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1098-Revert-usb-gadget-f_mass_storage-use-fsg_common_set_.patch b/patches.tizen/1098-Revert-usb-gadget-f_mass_storage-use-fsg_common_set_.patch
new file mode 100644 (file)
index 0000000..a941258
--- /dev/null
@@ -0,0 +1,65 @@
+From a049580b53afb5c80afe867e41a5e2b129418565 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 14 Jan 2014 14:27:07 +0100
+Subject: [PATCH 1098/1302] Revert "usb/gadget: f_mass_storage: use
+ fsg_common_set_cdev in fsg_common_init"
+
+This reverts commit 03aec556a53d26977be1c16b3307eae731960cd8.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 23 +++++++++++++++++++++--
+ 1 file changed, 21 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 9dde453..8aa6c86 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -3002,6 +3002,7 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       struct usb_gadget *gadget = cdev->gadget;
+       struct fsg_lun **curlun_it;
+       struct fsg_lun_config *lcfg;
++      struct usb_string *us;
+       int nluns, i, rc;
+       char *pathbuf;
+@@ -3022,9 +3023,19 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       fsg_common_set_ops(common, cfg->ops);
+       fsg_common_set_private_data(common, cfg->private_data);
+-      rc = fsg_common_set_cdev(common, cdev, cfg->can_stall);
+-      if (rc)
++      common->gadget = gadget;
++      common->ep0 = gadget->ep0;
++      common->ep0req = cdev->req;
++      common->cdev = cdev;
++
++      us = usb_gstrings_attach(cdev, fsg_strings_array,
++                               ARRAY_SIZE(fsg_strings));
++      if (IS_ERR(us)) {
++              rc = PTR_ERR(us);
+               goto error_release;
++      }
++      fsg_intf_desc.iInterface = us[FSG_STRING_INTERFACE].id;
++
+       rc = fsg_common_set_nluns(common, cfg->nluns);
+       if (rc)
+@@ -3106,6 +3117,14 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                    : "File-Stor Gadget"),
+                i);
++      /*
++       * Some peripheral controllers are known not to be able to
++       * halt bulk endpoints correctly.  If one of them is present,
++       * disable stalls.
++       */
++      common->can_stall = cfg->can_stall &&
++              !(gadget_is_at91(common->gadget));
++
+       /* Tell the thread to start working */
+       common->thread_task =
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1099-Revert-usb-gadget-f_mass_storage-use-fsg_common_set_.patch b/patches.tizen/1099-Revert-usb-gadget-f_mass_storage-use-fsg_common_set_.patch
new file mode 100644 (file)
index 0000000..e4e88f8
--- /dev/null
@@ -0,0 +1,32 @@
+From 42988f3ff39f9a7250b7919783455cc8bae133de Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 14 Jan 2014 14:27:10 +0100
+Subject: [PATCH 1099/1302] Revert "usb/gadget: f_mass_storage: use
+ fsg_common_set_ops/_private_data in fsg_common_init"
+
+This reverts commit 51c5313aa631785326cf16c39e941edd50b2832f.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 8aa6c86..691fb51 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -3019,9 +3019,8 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                       kfree(common);
+               return ERR_PTR(rc);
+       }
+-
+-      fsg_common_set_ops(common, cfg->ops);
+-      fsg_common_set_private_data(common, cfg->private_data);
++      common->ops = cfg->ops;
++      common->private_data = cfg->private_data;
+       common->gadget = gadget;
+       common->ep0 = gadget->ep0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1100-Revert-usb-gadget-f_mass_storage-use-fsg_common_set_.patch b/patches.tizen/1100-Revert-usb-gadget-f_mass_storage-use-fsg_common_set_.patch
new file mode 100644 (file)
index 0000000..ae4c6c1
--- /dev/null
@@ -0,0 +1,64 @@
+From 56910ad70300775739cf00d7e75f8e58c2ae9406 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 14 Jan 2014 14:27:13 +0100
+Subject: [PATCH 1100/1302] Revert "usb/gadget: f_mass_storage: use
+ fsg_common_set_nluns in fsg_common_init"
+
+This reverts commit 988ececeab73edfa2e4f27ad7167034d8908aa74.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 22 +++++++++++++++++-----
+ 1 file changed, 17 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 691fb51..2a71540 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -3006,6 +3006,12 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       int nluns, i, rc;
+       char *pathbuf;
++      /* Find out how many LUNs there should be */
++      nluns = cfg->nluns;
++      if (nluns < 1 || nluns > FSG_MAX_LUNS) {
++              dev_err(&gadget->dev, "invalid number of LUNs: %u\n", nluns);
++              return ERR_PTR(-EINVAL);
++      }
+       common = fsg_common_setup(common, !!common);
+       if (IS_ERR(common))
+@@ -3035,12 +3041,17 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       }
+       fsg_intf_desc.iInterface = us[FSG_STRING_INTERFACE].id;
+-
+-      rc = fsg_common_set_nluns(common, cfg->nluns);
+-      if (rc)
++      /*
++       * Create the LUNs, open their backing files, and register the
++       * LUN devices in sysfs.
++       */
++      curlun_it = kcalloc(nluns, sizeof(*curlun_it), GFP_KERNEL);
++      if (unlikely(!curlun_it)) {
++              rc = -ENOMEM;
+               goto error_release;
+-      curlun_it = common->luns;
+-      nluns = cfg->nluns;
++      }
++      common->luns = curlun_it;
++
+       for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun_it, ++lcfg) {
+               struct fsg_lun *curlun;
+@@ -3104,6 +3115,7 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                       goto error_luns;
+               }
+       }
++      common->nluns = nluns;
+       /* Prepare inquiryString */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1101-Revert-usb-gadget-f_mass_storage-use-fsg_common_set_.patch b/patches.tizen/1101-Revert-usb-gadget-f_mass_storage-use-fsg_common_set_.patch
new file mode 100644 (file)
index 0000000..137f865
--- /dev/null
@@ -0,0 +1,79 @@
+From 053e09af22359427c2b020c16a20f1e14ba4278b Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 14 Jan 2014 14:27:15 +0100
+Subject: [PATCH 1101/1302] Revert "usb/gadget: f_mass_storage: use
+ fsg_common_set_num_buffers in fsg_common_init"
+
+This reverts commit 378d601a3457e66ee10ba1770bfbe9d42d8361da.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 29 ++++++++++++++++++++++++++---
+ 1 file changed, 26 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 2a71540..2f6e3c3 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -3000,12 +3000,17 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                  struct fsg_config *cfg)
+ {
+       struct usb_gadget *gadget = cdev->gadget;
++      struct fsg_buffhd *bh;
+       struct fsg_lun **curlun_it;
+       struct fsg_lun_config *lcfg;
+       struct usb_string *us;
+       int nluns, i, rc;
+       char *pathbuf;
++      rc = fsg_num_buffers_validate(cfg->fsg_num_buffers);
++      if (rc != 0)
++              return ERR_PTR(rc);
++
+       /* Find out how many LUNs there should be */
+       nluns = cfg->nluns;
+       if (nluns < 1 || nluns > FSG_MAX_LUNS) {
+@@ -3019,12 +3024,15 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       common->sysfs = true;
+       common->state = FSG_STATE_IDLE;
+-      rc = fsg_common_set_num_buffers(common, cfg->fsg_num_buffers);
+-      if (rc) {
++      common->fsg_num_buffers = cfg->fsg_num_buffers;
++      common->buffhds = kcalloc(common->fsg_num_buffers,
++                                sizeof *(common->buffhds), GFP_KERNEL);
++      if (!common->buffhds) {
+               if (common->free_storage_on_release)
+                       kfree(common);
+-              return ERR_PTR(rc);
++              return ERR_PTR(-ENOMEM);
+       }
++
+       common->ops = cfg->ops;
+       common->private_data = cfg->private_data;
+@@ -3117,6 +3125,21 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       }
+       common->nluns = nluns;
++      /* Data buffers cyclic list */
++      bh = common->buffhds;
++      i = common->fsg_num_buffers;
++      goto buffhds_first_it;
++      do {
++              bh->next = bh + 1;
++              ++bh;
++buffhds_first_it:
++              bh->buf = kmalloc(FSG_BUFLEN, GFP_KERNEL);
++              if (unlikely(!bh->buf)) {
++                      rc = -ENOMEM;
++                      goto error_release;
++              }
++      } while (--i);
++      bh->next = common->buffhds;
+       /* Prepare inquiryString */
+       i = get_default_bcdDevice();
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1102-Revert-usb-gadget-f_mass_storage-use-fsg_common_setu.patch b/patches.tizen/1102-Revert-usb-gadget-f_mass_storage-use-fsg_common_setu.patch
new file mode 100644 (file)
index 0000000..d0736be
--- /dev/null
@@ -0,0 +1,67 @@
+From 7416fbee5544de4007942cf0b073159e7f6ec8c2 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 14 Jan 2014 14:27:18 +0100
+Subject: [PATCH 1102/1302] Revert "usb/gadget: f_mass_storage: use
+ fsg_common_setup in fsg_common_init"
+
+This reverts commit 6da409d4af402599d135f22d4f0273c42aee5d9c.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 2f6e3c3..ef4733c 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -3018,9 +3018,16 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+               return ERR_PTR(-EINVAL);
+       }
+-      common = fsg_common_setup(common, !!common);
+-      if (IS_ERR(common))
+-              return common;
++      /* Allocate? */
++      if (!common) {
++              common = kzalloc(sizeof *common, GFP_KERNEL);
++              if (!common)
++                      return ERR_PTR(-ENOMEM);
++              common->free_storage_on_release = 1;
++      } else {
++              memset(common, 0, sizeof *common);
++              common->free_storage_on_release = 0;
++      }
+       common->sysfs = true;
+       common->state = FSG_STATE_IDLE;
+@@ -3060,6 +3067,8 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       }
+       common->luns = curlun_it;
++      init_rwsem(&common->filesem);
++
+       for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun_it, ++lcfg) {
+               struct fsg_lun *curlun;
+@@ -3159,6 +3168,8 @@ buffhds_first_it:
+       common->can_stall = cfg->can_stall &&
+               !(gadget_is_at91(common->gadget));
++      spin_lock_init(&common->lock);
++      kref_init(&common->ref);
+       /* Tell the thread to start working */
+       common->thread_task =
+@@ -3167,6 +3178,8 @@ buffhds_first_it:
+               rc = PTR_ERR(common->thread_task);
+               goto error_release;
+       }
++      init_completion(&common->thread_notifier);
++      init_waitqueue_head(&common->fsg_wait);
+       /* Information */
+       INFO(common, FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1103-Revert-usb-gadget-f_mass_storage-split-fsg_common-in.patch b/patches.tizen/1103-Revert-usb-gadget-f_mass_storage-split-fsg_common-in.patch
new file mode 100644 (file)
index 0000000..b754672
--- /dev/null
@@ -0,0 +1,577 @@
+From cc53bf921cf7b490e624685bcd1be422edacab5a Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 14 Jan 2014 14:27:20 +0100
+Subject: [PATCH 1103/1302] Revert "usb/gadget: f_mass_storage: split
+ fsg_common initialization into a number of functions"
+
+This reverts commit 4198374d675f23cc00a4ebd61f99ef2c8bb4ad82.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 424 ++----------------------------------
+ drivers/usb/gadget/f_mass_storage.h |  33 ---
+ drivers/usb/gadget/storage_common.h |  20 +-
+ 3 files changed, 23 insertions(+), 454 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index ef4733c..04ee635 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -299,7 +299,6 @@ struct fsg_common {
+       unsigned int            short_packet_received:1;
+       unsigned int            bad_lun_okay:1;
+       unsigned int            running:1;
+-      unsigned int            sysfs:1;
+       int                     thread_wakeup_needed;
+       struct completion       thread_notifier;
+@@ -2608,393 +2607,6 @@ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
+       return -EINVAL;
+ }
+-static struct fsg_common *fsg_common_setup(struct fsg_common *common, bool zero)
+-{
+-      if (!common) {
+-              common = kzalloc(sizeof(*common), GFP_KERNEL);
+-              if (!common)
+-                      return ERR_PTR(-ENOMEM);
+-              common->free_storage_on_release = 1;
+-      } else {
+-              if (zero)
+-                      memset(common, 0, sizeof(*common));
+-              common->free_storage_on_release = 0;
+-      }
+-      init_rwsem(&common->filesem);
+-      spin_lock_init(&common->lock);
+-      kref_init(&common->ref);
+-      init_completion(&common->thread_notifier);
+-      init_waitqueue_head(&common->fsg_wait);
+-      common->state = FSG_STATE_TERMINATED;
+-
+-      return common;
+-}
+-
+-void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs)
+-{
+-      common->sysfs = sysfs;
+-}
+-
+-static void _fsg_common_free_buffers(struct fsg_buffhd *buffhds, unsigned n)
+-{
+-      if (buffhds) {
+-              struct fsg_buffhd *bh = buffhds;
+-              while (n--) {
+-                      kfree(bh->buf);
+-                      ++bh;
+-              }
+-              kfree(buffhds);
+-      }
+-}
+-
+-int fsg_common_set_num_buffers(struct fsg_common *common, unsigned int n)
+-{
+-      struct fsg_buffhd *bh, *new_buffhds;
+-      int i, rc;
+-
+-      rc = fsg_num_buffers_validate(n);
+-      if (rc != 0)
+-              return rc;
+-
+-      new_buffhds = kcalloc(n, sizeof *(new_buffhds), GFP_KERNEL);
+-      if (!new_buffhds)
+-              return -ENOMEM;
+-
+-      /* Data buffers cyclic list */
+-      bh = new_buffhds;
+-      i = n;
+-      goto buffhds_first_it;
+-      do {
+-              bh->next = bh + 1;
+-              ++bh;
+-buffhds_first_it:
+-              bh->buf = kmalloc(FSG_BUFLEN, GFP_KERNEL);
+-              if (unlikely(!bh->buf))
+-                      goto error_release;
+-      } while (--i);
+-      bh->next = new_buffhds;
+-
+-      _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
+-      common->fsg_num_buffers = n;
+-      common->buffhds = new_buffhds;
+-
+-      return 0;
+-
+-error_release:
+-      _fsg_common_free_buffers(new_buffhds, n - i);
+-
+-      return -ENOMEM;
+-}
+-
+-void fsg_common_free_buffers(struct fsg_common *common)
+-{
+-      _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
+-      common->buffhds = NULL;
+-}
+-
+-int fsg_common_set_nluns(struct fsg_common *common, int nluns)
+-{
+-      struct fsg_lun **curlun;
+-
+-      /* Find out how many LUNs there should be */
+-      if (nluns < 1 || nluns > FSG_MAX_LUNS) {
+-              pr_err("invalid number of LUNs: %u\n", nluns);
+-              return -EINVAL;
+-      }
+-
+-      curlun = kcalloc(nluns, sizeof(*curlun), GFP_KERNEL);
+-      if (unlikely(!curlun))
+-              return -ENOMEM;
+-
+-      if (common->luns)
+-              fsg_common_free_luns(common);
+-
+-      common->luns = curlun;
+-      common->nluns = nluns;
+-
+-      pr_info("Number of LUNs=%d\n", common->nluns);
+-
+-      return 0;
+-}
+-
+-void fsg_common_free_luns(struct fsg_common *common)
+-{
+-      fsg_common_remove_luns(common);
+-      kfree(common->luns);
+-      common->luns = NULL;
+-}
+-
+-void fsg_common_set_ops(struct fsg_common *common,
+-                      const struct fsg_operations *ops)
+-{
+-      common->ops = ops;
+-}
+-
+-void fsg_common_set_private_data(struct fsg_common *common, void *priv)
+-{
+-      common->private_data = priv;
+-}
+-
+-int fsg_common_set_cdev(struct fsg_common *common,
+-                       struct usb_composite_dev *cdev, bool can_stall)
+-{
+-      struct usb_string *us;
+-      int rc;
+-
+-      common->gadget = cdev->gadget;
+-      common->ep0 = cdev->gadget->ep0;
+-      common->ep0req = cdev->req;
+-      common->cdev = cdev;
+-
+-      us = usb_gstrings_attach(cdev, fsg_strings_array,
+-                               ARRAY_SIZE(fsg_strings));
+-      if (IS_ERR(us)) {
+-              rc = PTR_ERR(us);
+-              return rc;
+-      }
+-      fsg_intf_desc.iInterface = us[FSG_STRING_INTERFACE].id;
+-
+-      /*
+-       * Some peripheral controllers are known not to be able to
+-       * halt bulk endpoints correctly.  If one of them is present,
+-       * disable stalls.
+-       */
+-      common->can_stall = can_stall && !(gadget_is_at91(common->gadget));
+-
+-      return 0;
+-}
+-
+-static inline int fsg_common_add_sysfs(struct fsg_common *common,
+-                                     struct fsg_lun *lun)
+-{
+-      int rc;
+-
+-      rc = device_register(&lun->dev);
+-      if (rc) {
+-              put_device(&lun->dev);
+-              return rc;
+-      }
+-
+-      rc = device_create_file(&lun->dev,
+-                              lun->cdrom
+-                            ? &dev_attr_ro_cdrom
+-                            : &dev_attr_ro);
+-      if (rc)
+-              goto error_cdrom;
+-      rc = device_create_file(&lun->dev,
+-                              lun->removable
+-                            ? &dev_attr_file
+-                            : &dev_attr_file_nonremovable);
+-      if (rc)
+-              goto error_removable;
+-      rc = device_create_file(&lun->dev, &dev_attr_nofua);
+-      if (rc)
+-              goto error_nofua;
+-
+-      return 0;
+-
+-error_nofua:
+-      device_remove_file(&lun->dev,
+-                         lun->removable
+-                       ? &dev_attr_file
+-                       : &dev_attr_file_nonremovable);
+-error_removable:
+-      device_remove_file(&lun->dev,
+-                         lun->cdrom
+-                       ? &dev_attr_ro_cdrom
+-                       : &dev_attr_ro);
+-error_cdrom:
+-      device_unregister(&lun->dev);
+-      return rc;
+-}
+-
+-static inline void fsg_common_remove_sysfs(struct fsg_lun *lun)
+-{
+-      device_remove_file(&lun->dev, &dev_attr_nofua);
+-      device_remove_file(&lun->dev, lun->cdrom
+-                         ? &dev_attr_ro_cdrom : &dev_attr_ro);
+-      device_remove_file(&lun->dev, lun->removable
+-                         ? &dev_attr_file : &dev_attr_file_nonremovable);
+-}
+-
+-void fsg_common_remove_lun(struct fsg_lun *lun, bool sysfs)
+-{
+-      if (sysfs) {
+-              fsg_common_remove_sysfs(lun);
+-              device_unregister(&lun->dev);
+-      }
+-      fsg_lun_close(lun);
+-      kfree(lun->name);
+-      kfree(lun);
+-}
+-
+-void _fsg_common_remove_luns(struct fsg_common *common, int n)
+-{
+-      int i;
+-
+-      for (i = 0; i < n; ++i)
+-              if (common->luns[i]) {
+-                      fsg_common_remove_lun(common->luns[i], common->sysfs);
+-                      common->luns[i] = NULL;
+-              }
+-}
+-
+-void fsg_common_remove_luns(struct fsg_common *common)
+-{
+-      _fsg_common_remove_luns(common, common->nluns);
+-}
+-
+-#define MAX_LUN_NAME_LEN 80
+-
+-int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg,
+-                        unsigned int id, const char *name,
+-                        const char **name_pfx)
+-{
+-      struct fsg_lun *lun;
+-      char *pathbuf;
+-      int rc = -ENOMEM;
+-      int name_len;
+-
+-      if (!common->nluns || !common->luns)
+-              return -ENODEV;
+-
+-      if (common->luns[id])
+-              return -EBUSY;
+-
+-      name_len = strlen(name) + 1;
+-      if (name_len > MAX_LUN_NAME_LEN)
+-              return -ENAMETOOLONG;
+-
+-      lun = kzalloc(sizeof(*lun), GFP_KERNEL);
+-      if (!lun)
+-              return -ENOMEM;
+-
+-      lun->name = kstrndup(name, name_len, GFP_KERNEL);
+-      if (!lun->name)
+-              goto error_name;
+-      lun->name_pfx = name_pfx;
+-
+-      lun->cdrom = !!cfg->cdrom;
+-      lun->ro = cfg->cdrom || cfg->ro;
+-      lun->initially_ro = lun->ro;
+-      lun->removable = !!cfg->removable;
+-
+-      common->luns[id] = lun;
+-
+-      if (common->sysfs) {
+-              lun->dev.release = fsg_lun_release;
+-              lun->dev.parent = &common->gadget->dev;
+-              dev_set_drvdata(&lun->dev, &common->filesem);
+-              dev_set_name(&lun->dev, name);
+-
+-              rc = fsg_common_add_sysfs(common, lun);
+-              if (rc) {
+-                      pr_info("failed to register LUN%d: %d\n", id, rc);
+-                      goto error_sysfs;
+-              }
+-      }
+-
+-      if (cfg->filename) {
+-              rc = fsg_lun_open(lun, cfg->filename);
+-              if (rc)
+-                      goto error_lun;
+-      } else if (!lun->removable) {
+-              pr_err("no file given for LUN%d\n", id);
+-              rc = -EINVAL;
+-              goto error_lun;
+-      }
+-
+-      pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
+-      {
+-              char *p = "(no medium)";
+-              if (fsg_lun_is_open(lun)) {
+-                      p = "(error)";
+-                      if (pathbuf) {
+-                              p = d_path(&lun->filp->f_path,
+-                                         pathbuf, PATH_MAX);
+-                              if (IS_ERR(p))
+-                                      p = "(error)";
+-                      }
+-              }
+-              pr_info("LUN: %s%s%sfile: %s\n",
+-                    lun->removable ? "removable " : "",
+-                    lun->ro ? "read only " : "",
+-                    lun->cdrom ? "CD-ROM " : "",
+-                    p);
+-      }
+-      kfree(pathbuf);
+-
+-      return 0;
+-
+-error_lun:
+-      if (common->sysfs) {
+-              fsg_common_remove_sysfs(lun);
+-              device_unregister(&lun->dev);
+-      }
+-      fsg_lun_close(lun);
+-error_sysfs:
+-      common->luns[id] = NULL;
+-      kfree(lun->name);
+-error_name:
+-      kfree(lun);
+-      return rc;
+-}
+-
+-int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg)
+-{
+-      char buf[40]; /* enough for 2^128 decimal */
+-      int i, rc;
+-
+-      for (i = 0; i < common->nluns; ++i) {
+-              snprintf(buf, sizeof(buf), "lun%d", i);
+-              rc = fsg_common_create_lun(common, &cfg->luns[i], i, buf, NULL);
+-              if (rc)
+-                      goto fail;
+-      }
+-
+-      pr_info("Number of LUNs=%d\n", common->nluns);
+-
+-      return 0;
+-
+-fail:
+-      _fsg_common_remove_luns(common, i);
+-      return rc;
+-}
+-
+-void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
+-                                 const char *pn)
+-{
+-      int i;
+-
+-      /* Prepare inquiryString */
+-      i = get_default_bcdDevice();
+-      snprintf(common->inquiry_string, sizeof(common->inquiry_string),
+-               "%-8s%-16s%04x", vn ?: "Linux",
+-               /* Assume product name dependent on the first LUN */
+-               pn ?: ((*common->luns)->cdrom
+-                   ? "File-CD Gadget"
+-                   : "File-Stor Gadget"),
+-               i);
+-}
+-
+-int fsg_common_run_thread(struct fsg_common *common)
+-{
+-      common->state = FSG_STATE_IDLE;
+-      /* Tell the thread to start working */
+-      common->thread_task =
+-              kthread_create(fsg_main_thread, common, "file-storage");
+-      if (IS_ERR(common->thread_task)) {
+-              common->state = FSG_STATE_TERMINATED;
+-              return PTR_ERR(common->thread_task);
+-      }
+-
+-      DBG(common, "I/O thread pid: %d\n", task_pid_nr(common->thread_task));
+-
+-      wake_up_process(common->thread_task);
+-
+-      return 0;
+-}
+-
+ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                  struct usb_composite_dev *cdev,
+                                  struct fsg_config *cfg)
+@@ -3028,8 +2640,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+               memset(common, 0, sizeof *common);
+               common->free_storage_on_release = 0;
+       }
+-      common->sysfs = true;
+-      common->state = FSG_STATE_IDLE;
+       common->fsg_num_buffers = cfg->fsg_num_buffers;
+       common->buffhds = kcalloc(common->fsg_num_buffers,
+@@ -3080,12 +2690,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+               }
+               *curlun_it = curlun;
+-              curlun->name = kzalloc(MAX_LUN_NAME_LEN, GFP_KERNEL);
+-              if (!curlun->name) {
+-                      rc = -ENOMEM;
+-                      common->nluns = i;
+-                      goto error_release;
+-              }
+               curlun->cdrom = !!lcfg->cdrom;
+               curlun->ro = lcfg->cdrom || lcfg->ro;
+               curlun->initially_ro = curlun->ro;
+@@ -3095,7 +2699,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+               /* curlun->dev.driver = &fsg_driver.driver; XXX */
+               dev_set_drvdata(&curlun->dev, &common->filesem);
+               dev_set_name(&curlun->dev, "lun%d", i);
+-              strlcpy(curlun->name, dev_name(&curlun->dev), MAX_LUN_NAME_LEN);
+               rc = device_register(&curlun->dev);
+               if (rc) {
+@@ -3242,21 +2845,32 @@ static void fsg_common_release(struct kref *ref)
+                       struct fsg_lun *lun = *lun_it;
+                       if (!lun)
+                               continue;
+-                      if (common->sysfs)
+-                              fsg_common_remove_sysfs(lun);
++                      device_remove_file(&lun->dev, &dev_attr_nofua);
++                      device_remove_file(&lun->dev,
++                                         lun->cdrom
++                                       ? &dev_attr_ro_cdrom
++                                       : &dev_attr_ro);
++                      device_remove_file(&lun->dev,
++                                         lun->removable
++                                       ? &dev_attr_file
++                                       : &dev_attr_file_nonremovable);
+                       fsg_lun_close(lun);
+-                      if (common->sysfs)
+-                              device_unregister(&lun->dev);
+-                      kfree(lun->name);
++                      device_unregister(&lun->dev);
+                       kfree(lun);
+               }
+               kfree(common->luns);
+       }
+-      if (likely(common->buffhds))
+-              _fsg_common_free_buffers(common->buffhds,
+-                                       common->fsg_num_buffers);
++      {
++              struct fsg_buffhd *bh = common->buffhds;
++              unsigned i = common->fsg_num_buffers;
++              do {
++                      kfree(bh->buf);
++              } while (++bh, --i);
++      }
++
++      kfree(common->buffhds);
+       if (common->free_storage_on_release)
+               kfree(common);
+ }
+diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h
+index 4445e82..b64761d 100644
+--- a/drivers/usb/gadget/f_mass_storage.h
++++ b/drivers/usb/gadget/f_mass_storage.h
+@@ -102,39 +102,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                  struct usb_composite_dev *cdev,
+                                  struct fsg_config *cfg);
+-void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs);
+-
+-int fsg_common_set_num_buffers(struct fsg_common *common, unsigned int n);
+-
+-void fsg_common_free_buffers(struct fsg_common *common);
+-
+-int fsg_common_set_nluns(struct fsg_common *common, int nluns);
+-
+-void fsg_common_free_luns(struct fsg_common *common);
+-
+-void fsg_common_set_ops(struct fsg_common *common,
+-                      const struct fsg_operations *ops);
+-
+-void fsg_common_set_private_data(struct fsg_common *common, void *priv);
+-
+-int fsg_common_set_cdev(struct fsg_common *common,
+-                      struct usb_composite_dev *cdev, bool can_stall);
+-
+-void fsg_common_remove_lun(struct fsg_lun *lun, bool sysfs);
+-
+-void fsg_common_remove_luns(struct fsg_common *common);
+-
+-int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg,
+-                        unsigned int id, const char *name,
+-                        const char **name_pfx);
+-
+-int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg);
+-
+-void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
+-                                 const char *pn);
+-
+-int fsg_common_run_thread(struct fsg_common *common);
+-
+ void fsg_config_from_params(struct fsg_config *cfg,
+                           const struct fsg_module_parameters *params,
+                           unsigned int fsg_num_buffers);
+diff --git a/drivers/usb/gadget/storage_common.h b/drivers/usb/gadget/storage_common.h
+index 9955477..1fcda2b 100644
+--- a/drivers/usb/gadget/storage_common.h
++++ b/drivers/usb/gadget/storage_common.h
+@@ -17,20 +17,10 @@
+ #define VLDBG(lun, fmt, args...) do { } while (0)
+ #endif /* VERBOSE_DEBUG */
+-#define _LMSG(func, lun, fmt, args...)                                        \
+-      do {                                                            \
+-              if ((lun)->name_pfx && *(lun)->name_pfx)                \
+-                      func("%s/%s: " fmt, *(lun)->name_pfx,           \
+-                               (lun)->name, ## args);                 \
+-              else                                                    \
+-                      func("%s: " fmt, (lun)->name, ## args);         \
+-      } while (0)
+-
+-#define LDBG(lun, fmt, args...)               _LMSG(pr_debug, lun, fmt, ## args)
+-#define LERROR(lun, fmt, args...)     _LMSG(pr_err, lun, fmt, ## args)
+-#define LWARN(lun, fmt, args...)      _LMSG(pr_warn, lun, fmt, ## args)
+-#define LINFO(lun, fmt, args...)      _LMSG(pr_info, lun, fmt, ## args)
+-
++#define LDBG(lun, fmt, args...)   dev_dbg(&(lun)->dev, fmt, ## args)
++#define LERROR(lun, fmt, args...) dev_err(&(lun)->dev, fmt, ## args)
++#define LWARN(lun, fmt, args...)  dev_warn(&(lun)->dev, fmt, ## args)
++#define LINFO(lun, fmt, args...)  dev_info(&(lun)->dev, fmt, ## args)
+ #ifdef DUMP_MSGS
+@@ -110,8 +100,6 @@ struct fsg_lun {
+                                                      of bound block device */
+       unsigned int    blksize; /* logical block size of bound block device */
+       struct device   dev;
+-      char            *name; /* "function.name/lun.name" */
+-      const char      **name_pfx;
+ };
+ static inline bool fsg_lun_is_open(struct fsg_lun *curlun)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1104-Revert-usb-gadget-f_mass_storage-use-usb_gstrings_at.patch b/patches.tizen/1104-Revert-usb-gadget-f_mass_storage-use-usb_gstrings_at.patch
new file mode 100644 (file)
index 0000000..f7a5d61
--- /dev/null
@@ -0,0 +1,81 @@
+From f8bf4a554d0e7f042ff7beab4dddee40c0c4ab48 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 14 Jan 2014 14:27:23 +0100
+Subject: [PATCH 1104/1302] Revert "usb/gadget: f_mass_storage: use
+ usb_gstrings_attach"
+
+This reverts commit 2089c2070341b55b6476907100bfe2fd04467edd.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 25 +++++++++++++------------
+ 1 file changed, 13 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 04ee635..05d34a0 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -242,11 +242,6 @@ static struct usb_gadget_strings  fsg_stringtab = {
+       .strings        = fsg_strings,
+ };
+-static struct usb_gadget_strings *fsg_strings_array[] = {
+-      &fsg_stringtab,
+-      NULL,
+-};
+-
+ /*-------------------------------------------------------------------------*/
+ struct fsg_dev;
+@@ -2615,7 +2610,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       struct fsg_buffhd *bh;
+       struct fsg_lun **curlun_it;
+       struct fsg_lun_config *lcfg;
+-      struct usb_string *us;
+       int nluns, i, rc;
+       char *pathbuf;
+@@ -2658,13 +2652,14 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       common->ep0req = cdev->req;
+       common->cdev = cdev;
+-      us = usb_gstrings_attach(cdev, fsg_strings_array,
+-                               ARRAY_SIZE(fsg_strings));
+-      if (IS_ERR(us)) {
+-              rc = PTR_ERR(us);
+-              goto error_release;
++      /* Maybe allocate device-global string IDs, and patch descriptors */
++      if (fsg_strings[FSG_STRING_INTERFACE].id == 0) {
++              rc = usb_string_id(cdev);
++              if (unlikely(rc < 0))
++                      goto error_release;
++              fsg_strings[FSG_STRING_INTERFACE].id = rc;
++              fsg_intf_desc.iInterface = rc;
+       }
+-      fsg_intf_desc.iInterface = us[FSG_STRING_INTERFACE].id;
+       /*
+        * Create the LUNs, open their backing files, and register the
+@@ -2958,6 +2953,11 @@ autoconf_fail:
+ /****************************** ADD FUNCTION ******************************/
++static struct usb_gadget_strings *fsg_strings_array[] = {
++      &fsg_stringtab,
++      NULL,
++};
++
+ static int fsg_bind_config(struct usb_composite_dev *cdev,
+                          struct usb_configuration *c,
+                          struct fsg_common *common)
+@@ -2970,6 +2970,7 @@ static int fsg_bind_config(struct usb_composite_dev *cdev,
+               return -ENOMEM;
+       fsg->function.name        = FSG_DRIVER_DESC;
++      fsg->function.strings     = fsg_strings_array;
+       fsg->function.bind        = fsg_bind;
+       fsg->function.unbind      = fsg_unbind;
+       fsg->function.setup       = fsg_setup;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1105-Revert-usb-gadget-f_mass_storage-add-a-level-of-indi.patch b/patches.tizen/1105-Revert-usb-gadget-f_mass_storage-add-a-level-of-indi.patch
new file mode 100644 (file)
index 0000000..369fd96
--- /dev/null
@@ -0,0 +1,184 @@
+From 186b5584c9af26975ab2a0c91286771d8753f6ec Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 14 Jan 2014 14:27:26 +0100
+Subject: [PATCH 1105/1302] Revert "usb/gadget: f_mass_storage: add a level of
+ indirection for luns storage"
+
+This reverts commit 51717e532d24736b2813cfc49e4c48374b2fbd12.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 60 ++++++++++++-------------------------
+ 1 file changed, 19 insertions(+), 41 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 05d34a0..c36e208 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -274,7 +274,7 @@ struct fsg_common {
+       unsigned int            nluns;
+       unsigned int            lun;
+-      struct fsg_lun          **luns;
++      struct fsg_lun          *luns;
+       struct fsg_lun          *curlun;
+       unsigned int            bulk_out_maxpacket;
+@@ -2151,7 +2151,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
+               common->data_dir = DATA_DIR_NONE;
+       common->lun = cbw->Lun;
+       if (common->lun < common->nluns)
+-              common->curlun = common->luns[common->lun];
++              common->curlun = &common->luns[common->lun];
+       else
+               common->curlun = NULL;
+       common->tag = cbw->Tag;
+@@ -2297,9 +2297,7 @@ reset:
+       common->running = 1;
+       for (i = 0; i < common->nluns; ++i)
+-              if (common->luns[i])
+-                      common->luns[i]->unit_attention_data =
+-                              SS_RESET_OCCURRED;
++              common->luns[i].unit_attention_data = SS_RESET_OCCURRED;
+       return rc;
+ }
+@@ -2399,9 +2397,7 @@ static void handle_exception(struct fsg_common *common)
+               common->state = FSG_STATE_STATUS_PHASE;
+       else {
+               for (i = 0; i < common->nluns; ++i) {
+-                      curlun = common->luns[i];
+-                      if (!curlun)
+-                              continue;
++                      curlun = &common->luns[i];
+                       curlun->prevent_medium_removal = 0;
+                       curlun->sense_data = SS_NO_SENSE;
+                       curlun->unit_attention_data = SS_NO_SENSE;
+@@ -2443,9 +2439,8 @@ static void handle_exception(struct fsg_common *common)
+                * CONFIG_CHANGE cases.
+                */
+               /* for (i = 0; i < common->nluns; ++i) */
+-              /*      if (common->luns[i]) */
+-              /*              common->luns[i]->unit_attention_data = */
+-              /*                      SS_RESET_OCCURRED;  */
++              /*      common->luns[i].unit_attention_data = */
++              /*              SS_RESET_OCCURRED;  */
+               break;
+       case FSG_STATE_CONFIG_CHANGE:
+@@ -2541,13 +2536,12 @@ static int fsg_main_thread(void *common_)
+       if (!common->ops || !common->ops->thread_exits
+        || common->ops->thread_exits(common) < 0) {
+-              struct fsg_lun **curlun_it = common->luns;
++              struct fsg_lun *curlun = common->luns;
+               unsigned i = common->nluns;
+               down_write(&common->filesem);
+-              for (; i--; ++curlun_it) {
+-                      struct fsg_lun *curlun = *curlun_it;
+-                      if (!curlun || !fsg_lun_is_open(curlun))
++              for (; i--; ++curlun) {
++                      if (!fsg_lun_is_open(curlun))
+                               continue;
+                       fsg_lun_close(curlun);
+@@ -2608,7 +2602,7 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+ {
+       struct usb_gadget *gadget = cdev->gadget;
+       struct fsg_buffhd *bh;
+-      struct fsg_lun **curlun_it;
++      struct fsg_lun *curlun;
+       struct fsg_lun_config *lcfg;
+       int nluns, i, rc;
+       char *pathbuf;
+@@ -2665,26 +2659,16 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+        * Create the LUNs, open their backing files, and register the
+        * LUN devices in sysfs.
+        */
+-      curlun_it = kcalloc(nluns, sizeof(*curlun_it), GFP_KERNEL);
+-      if (unlikely(!curlun_it)) {
++      curlun = kcalloc(nluns, sizeof(*curlun), GFP_KERNEL);
++      if (unlikely(!curlun)) {
+               rc = -ENOMEM;
+               goto error_release;
+       }
+-      common->luns = curlun_it;
++      common->luns = curlun;
+       init_rwsem(&common->filesem);
+-      for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun_it, ++lcfg) {
+-              struct fsg_lun *curlun;
+-
+-              curlun = kzalloc(sizeof(*curlun), GFP_KERNEL);
+-              if (!curlun) {
+-                      rc = -ENOMEM;
+-                      common->nluns = i;
+-                      goto error_release;
+-              }
+-              *curlun_it = curlun;
+-
++      for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun, ++lcfg) {
+               curlun->cdrom = !!lcfg->cdrom;
+               curlun->ro = lcfg->cdrom || lcfg->ro;
+               curlun->initially_ro = curlun->ro;
+@@ -2700,7 +2684,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                       INFO(common, "failed to register LUN%d: %d\n", i, rc);
+                       common->nluns = i;
+                       put_device(&curlun->dev);
+-                      kfree(curlun);
+                       goto error_release;
+               }
+@@ -2753,7 +2736,7 @@ buffhds_first_it:
+       snprintf(common->inquiry_string, sizeof common->inquiry_string,
+                "%-8s%-16s%04x", cfg->vendor_name ?: "Linux",
+                /* Assume product name dependent on the first LUN */
+-               cfg->product_name ?: ((*common->luns)->cdrom
++               cfg->product_name ?: (common->luns->cdrom
+                                    ? "File-CD Gadget"
+                                    : "File-Stor Gadget"),
+                i);
+@@ -2784,10 +2767,9 @@ buffhds_first_it:
+       INFO(common, "Number of LUNs=%d\n", common->nluns);
+       pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
+-      for (i = 0, nluns = common->nluns, curlun_it = common->luns;
++      for (i = 0, nluns = common->nluns, curlun = common->luns;
+            i < nluns;
+-           ++curlun_it, ++i) {
+-              struct fsg_lun *curlun = *curlun_it;
++           ++curlun, ++i) {
+               char *p = "(no medium)";
+               if (fsg_lun_is_open(curlun)) {
+                       p = "(error)";
+@@ -2832,14 +2814,11 @@ static void fsg_common_release(struct kref *ref)
+       }
+       if (likely(common->luns)) {
+-              struct fsg_lun **lun_it = common->luns;
++              struct fsg_lun *lun = common->luns;
+               unsigned i = common->nluns;
+               /* In error recovery common->nluns may be zero. */
+-              for (; i; --i, ++lun_it) {
+-                      struct fsg_lun *lun = *lun_it;
+-                      if (!lun)
+-                              continue;
++              for (; i; --i, ++lun) {
+                       device_remove_file(&lun->dev, &dev_attr_nofua);
+                       device_remove_file(&lun->dev,
+                                          lun->cdrom
+@@ -2851,7 +2830,6 @@ static void fsg_common_release(struct kref *ref)
+                                        : &dev_attr_file_nonremovable);
+                       fsg_lun_close(lun);
+                       device_unregister(&lun->dev);
+-                      kfree(lun);
+               }
+               kfree(common->luns);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1106-Revert-usb-gadget-f_mass_storage-factor-out-a-header.patch b/patches.tizen/1106-Revert-usb-gadget-f_mass_storage-factor-out-a-header.patch
new file mode 100644 (file)
index 0000000..a582e46
--- /dev/null
@@ -0,0 +1,322 @@
+From 38facb63e8cf67b585c52ad0c65ad978619cd4b4 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 14 Jan 2014 14:27:56 +0100
+Subject: [PATCH 1106/1302] Revert "usb/gadget: f_mass_storage: factor out a
+ header file"
+
+This reverts commit aa42314c87dd9ba2b17aa1cb49d76d95d988dffe.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 117 +++++++++++++++++++++++++++++++--
+ drivers/usb/gadget/f_mass_storage.h | 126 ------------------------------------
+ 2 files changed, 110 insertions(+), 133 deletions(-)
+ delete mode 100644 drivers/usb/gadget/f_mass_storage.h
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index c36e208..163d911 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -229,7 +229,6 @@
+ static const char fsg_string_interface[] = "Mass Storage";
+ #include "storage_common.h"
+-#include "f_mass_storage.h"
+ /* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
+ static struct usb_string              fsg_strings[] = {
+@@ -247,6 +246,18 @@ static struct usb_gadget_strings  fsg_stringtab = {
+ struct fsg_dev;
+ struct fsg_common;
++/* FSF callback functions */
++struct fsg_operations {
++      /*
++       * Callback function to call when thread exits.  If no
++       * callback is set or it returns value lower then zero MSF
++       * will force eject all LUNs it operates on (including those
++       * marked as non-removable or with prevent_medium_removal flag
++       * set).
++       */
++      int (*thread_exits)(struct fsg_common *common);
++};
++
+ /* Data shared by all the FSG instances. */
+ struct fsg_common {
+       struct usb_gadget       *gadget;
+@@ -313,6 +324,28 @@ struct fsg_common {
+       struct kref             ref;
+ };
++struct fsg_config {
++      unsigned nluns;
++      struct fsg_lun_config {
++              const char *filename;
++              char ro;
++              char removable;
++              char cdrom;
++              char nofua;
++      } luns[FSG_MAX_LUNS];
++
++      /* Callback functions. */
++      const struct fsg_operations     *ops;
++      /* Gadget's private data. */
++      void                    *private_data;
++
++      const char *vendor_name;                /*  8 characters or less */
++      const char *product_name;               /* 16 characters or less */
++
++      char                    can_stall;
++      unsigned int            fsg_num_buffers;
++};
++
+ struct fsg_dev {
+       struct usb_function     function;
+       struct usb_gadget       *gadget;        /* Copy of cdev->gadget */
+@@ -2576,12 +2609,12 @@ static void fsg_lun_release(struct device *dev)
+       /* Nothing needs to be done */
+ }
+-void fsg_common_get(struct fsg_common *common)
++static inline void fsg_common_get(struct fsg_common *common)
+ {
+       kref_get(&common->ref);
+ }
+-void fsg_common_put(struct fsg_common *common)
++static inline void fsg_common_put(struct fsg_common *common)
+ {
+       kref_put(&common->ref, fsg_common_release);
+ }
+@@ -2596,9 +2629,9 @@ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
+       return -EINVAL;
+ }
+-struct fsg_common *fsg_common_init(struct fsg_common *common,
+-                                 struct usb_composite_dev *cdev,
+-                                 struct fsg_config *cfg)
++static struct fsg_common *fsg_common_init(struct fsg_common *common,
++                                        struct usb_composite_dev *cdev,
++                                        struct fsg_config *cfg)
+ {
+       struct usb_gadget *gadget = cdev->gadget;
+       struct fsg_buffhd *bh;
+@@ -2975,8 +3008,62 @@ static int fsg_bind_config(struct usb_composite_dev *cdev,
+ /************************* Module parameters *************************/
++struct fsg_module_parameters {
++      char            *file[FSG_MAX_LUNS];
++      bool            ro[FSG_MAX_LUNS];
++      bool            removable[FSG_MAX_LUNS];
++      bool            cdrom[FSG_MAX_LUNS];
++      bool            nofua[FSG_MAX_LUNS];
++
++      unsigned int    file_count, ro_count, removable_count, cdrom_count;
++      unsigned int    nofua_count;
++      unsigned int    luns;   /* nluns */
++      bool            stall;  /* can_stall */
++};
++
++#define _FSG_MODULE_PARAM_ARRAY(prefix, params, name, type, desc)     \
++      module_param_array_named(prefix ## name, params.name, type,     \
++                               &prefix ## params.name ## _count,      \
++                               S_IRUGO);                              \
++      MODULE_PARM_DESC(prefix ## name, desc)
++
++#define _FSG_MODULE_PARAM(prefix, params, name, type, desc)           \
++      module_param_named(prefix ## name, params.name, type,           \
++                         S_IRUGO);                                    \
++      MODULE_PARM_DESC(prefix ## name, desc)
++
++#define __FSG_MODULE_PARAMETERS(prefix, params)                               \
++      _FSG_MODULE_PARAM_ARRAY(prefix, params, file, charp,            \
++                              "names of backing files or devices");   \
++      _FSG_MODULE_PARAM_ARRAY(prefix, params, ro, bool,               \
++                              "true to force read-only");             \
++      _FSG_MODULE_PARAM_ARRAY(prefix, params, removable, bool,        \
++                              "true to simulate removable media");    \
++      _FSG_MODULE_PARAM_ARRAY(prefix, params, cdrom, bool,            \
++                              "true to simulate CD-ROM instead of disk"); \
++      _FSG_MODULE_PARAM_ARRAY(prefix, params, nofua, bool,            \
++                              "true to ignore SCSI WRITE(10,12) FUA bit"); \
++      _FSG_MODULE_PARAM(prefix, params, luns, uint,                   \
++                        "number of LUNs");                            \
++      _FSG_MODULE_PARAM(prefix, params, stall, bool,                  \
++                        "false to prevent bulk stalls")
++
++#ifdef CONFIG_USB_GADGET_DEBUG_FILES
++
++#define FSG_MODULE_PARAMETERS(prefix, params)                         \
++      __FSG_MODULE_PARAMETERS(prefix, params);                        \
++      module_param_named(num_buffers, fsg_num_buffers, uint, S_IRUGO);\
++      MODULE_PARM_DESC(num_buffers, "Number of pipeline buffers")
++#else
++
++#define FSG_MODULE_PARAMETERS(prefix, params)                         \
++      __FSG_MODULE_PARAMETERS(prefix, params)
++
++#endif
++
+-void fsg_config_from_params(struct fsg_config *cfg,
++static void
++fsg_config_from_params(struct fsg_config *cfg,
+                      const struct fsg_module_parameters *params,
+                      unsigned int fsg_num_buffers)
+ {
+@@ -3009,3 +3096,19 @@ void fsg_config_from_params(struct fsg_config *cfg,
+       cfg->fsg_num_buffers = fsg_num_buffers;
+ }
++static inline struct fsg_common *
++fsg_common_from_params(struct fsg_common *common,
++                     struct usb_composite_dev *cdev,
++                     const struct fsg_module_parameters *params,
++                     unsigned int fsg_num_buffers)
++      __attribute__((unused));
++static inline struct fsg_common *
++fsg_common_from_params(struct fsg_common *common,
++                     struct usb_composite_dev *cdev,
++                     const struct fsg_module_parameters *params,
++                     unsigned int fsg_num_buffers)
++{
++      struct fsg_config cfg;
++      fsg_config_from_params(&cfg, params, fsg_num_buffers);
++      return fsg_common_init(common, cdev, &cfg);
++}
+diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h
+deleted file mode 100644
+index b64761d..0000000
+--- a/drivers/usb/gadget/f_mass_storage.h
++++ /dev/null
+@@ -1,126 +0,0 @@
+-#ifndef USB_F_MASS_STORAGE_H
+-#define USB_F_MASS_STORAGE_H
+-
+-#include "storage_common.h"
+-
+-struct fsg_module_parameters {
+-      char            *file[FSG_MAX_LUNS];
+-      bool            ro[FSG_MAX_LUNS];
+-      bool            removable[FSG_MAX_LUNS];
+-      bool            cdrom[FSG_MAX_LUNS];
+-      bool            nofua[FSG_MAX_LUNS];
+-
+-      unsigned int    file_count, ro_count, removable_count, cdrom_count;
+-      unsigned int    nofua_count;
+-      unsigned int    luns;   /* nluns */
+-      bool            stall;  /* can_stall */
+-};
+-
+-#define _FSG_MODULE_PARAM_ARRAY(prefix, params, name, type, desc)     \
+-      module_param_array_named(prefix ## name, params.name, type,     \
+-                               &prefix ## params.name ## _count,      \
+-                               S_IRUGO);                              \
+-      MODULE_PARM_DESC(prefix ## name, desc)
+-
+-#define _FSG_MODULE_PARAM(prefix, params, name, type, desc)           \
+-      module_param_named(prefix ## name, params.name, type,           \
+-                         S_IRUGO);                                    \
+-      MODULE_PARM_DESC(prefix ## name, desc)
+-
+-#define __FSG_MODULE_PARAMETERS(prefix, params)                               \
+-      _FSG_MODULE_PARAM_ARRAY(prefix, params, file, charp,            \
+-                              "names of backing files or devices");   \
+-      _FSG_MODULE_PARAM_ARRAY(prefix, params, ro, bool,               \
+-                              "true to force read-only");             \
+-      _FSG_MODULE_PARAM_ARRAY(prefix, params, removable, bool,        \
+-                              "true to simulate removable media");    \
+-      _FSG_MODULE_PARAM_ARRAY(prefix, params, cdrom, bool,            \
+-                              "true to simulate CD-ROM instead of disk"); \
+-      _FSG_MODULE_PARAM_ARRAY(prefix, params, nofua, bool,            \
+-                              "true to ignore SCSI WRITE(10,12) FUA bit"); \
+-      _FSG_MODULE_PARAM(prefix, params, luns, uint,                   \
+-                        "number of LUNs");                            \
+-      _FSG_MODULE_PARAM(prefix, params, stall, bool,                  \
+-                        "false to prevent bulk stalls")
+-
+-#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+-
+-#define FSG_MODULE_PARAMETERS(prefix, params)                         \
+-      __FSG_MODULE_PARAMETERS(prefix, params);                        \
+-      module_param_named(num_buffers, fsg_num_buffers, uint, S_IRUGO);\
+-      MODULE_PARM_DESC(num_buffers, "Number of pipeline buffers")
+-#else
+-
+-#define FSG_MODULE_PARAMETERS(prefix, params)                         \
+-      __FSG_MODULE_PARAMETERS(prefix, params)
+-
+-#endif
+-
+-struct fsg_common;
+-
+-/* FSF callback functions */
+-struct fsg_operations {
+-      /*
+-       * Callback function to call when thread exits.  If no
+-       * callback is set or it returns value lower then zero MSF
+-       * will force eject all LUNs it operates on (including those
+-       * marked as non-removable or with prevent_medium_removal flag
+-       * set).
+-       */
+-      int (*thread_exits)(struct fsg_common *common);
+-};
+-
+-struct fsg_lun_config {
+-      const char *filename;
+-      char ro;
+-      char removable;
+-      char cdrom;
+-      char nofua;
+-};
+-
+-struct fsg_config {
+-      unsigned nluns;
+-      struct fsg_lun_config luns[FSG_MAX_LUNS];
+-
+-      /* Callback functions. */
+-      const struct fsg_operations     *ops;
+-      /* Gadget's private data. */
+-      void                    *private_data;
+-
+-      const char *vendor_name;                /*  8 characters or less */
+-      const char *product_name;               /* 16 characters or less */
+-
+-      char                    can_stall;
+-      unsigned int            fsg_num_buffers;
+-};
+-
+-void fsg_common_get(struct fsg_common *common);
+-
+-void fsg_common_put(struct fsg_common *common);
+-
+-struct fsg_common *fsg_common_init(struct fsg_common *common,
+-                                 struct usb_composite_dev *cdev,
+-                                 struct fsg_config *cfg);
+-
+-void fsg_config_from_params(struct fsg_config *cfg,
+-                          const struct fsg_module_parameters *params,
+-                          unsigned int fsg_num_buffers);
+-
+-static inline struct fsg_common *
+-fsg_common_from_params(struct fsg_common *common,
+-                     struct usb_composite_dev *cdev,
+-                     const struct fsg_module_parameters *params,
+-                     unsigned int fsg_num_buffers)
+-      __attribute__((unused));
+-static inline struct fsg_common *
+-fsg_common_from_params(struct fsg_common *common,
+-                     struct usb_composite_dev *cdev,
+-                     const struct fsg_module_parameters *params,
+-                     unsigned int fsg_num_buffers)
+-{
+-      struct fsg_config cfg;
+-      fsg_config_from_params(&cfg, params, fsg_num_buffers);
+-      return fsg_common_init(common, cdev, &cfg);
+-}
+-
+-#endif /* USB_F_MASS_STORAGE_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1107-Revert-usb-gadget-create-a-utility-module-for-mass_s.patch b/patches.tizen/1107-Revert-usb-gadget-create-a-utility-module-for-mass_s.patch
new file mode 100644 (file)
index 0000000..bbe6af2
--- /dev/null
@@ -0,0 +1,1141 @@
+From 0d96bd5e6f81f09f744f669123ce432523ce30ec Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 14 Jan 2014 14:28:02 +0100
+Subject: [PATCH 1107/1302] Revert "usb/gadget: create a utility module for
+ mass_storage"
+
+This reverts commit 999eab4c72b5afbb59bdb5668a03118ea79e4455.
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig          |   6 -
+ drivers/usb/gadget/Makefile         |   2 -
+ drivers/usb/gadget/acm_ms.c         |  17 +-
+ drivers/usb/gadget/f_mass_storage.c |  71 ++------
+ drivers/usb/gadget/mass_storage.c   |  25 +--
+ drivers/usb/gadget/multi.c          |  17 +-
+ drivers/usb/gadget/storage_common.c | 319 ++++++++++++++++++++++++++++++------
+ drivers/usb/gadget/storage_common.h | 210 ------------------------
+ 8 files changed, 285 insertions(+), 382 deletions(-)
+ delete mode 100644 drivers/usb/gadget/storage_common.h
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index ecfcbab..8205354 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -537,9 +537,6 @@ config USB_F_SUBSET
+ config USB_F_RNDIS
+       tristate
+-config USB_U_MS
+-      tristate
+-
+ choice
+       tristate "USB Gadget Drivers"
+       default USB_ETH
+@@ -893,7 +890,6 @@ config USB_MASS_STORAGE
+       tristate "Mass Storage Gadget"
+       depends on BLOCK
+       select USB_LIBCOMPOSITE
+-      select USB_U_MS
+       help
+         The Mass Storage Gadget acts as a USB Mass Storage disk drive.
+         As its storage repository it can use a regular file or a block
+@@ -1029,7 +1025,6 @@ config USB_G_ACM_MS
+       select USB_LIBCOMPOSITE
+       select USB_U_SERIAL
+       select USB_F_ACM
+-      select USB_U_MS
+       help
+         This driver provides two functions in one configuration:
+         a mass storage, and a CDC ACM (serial port) link.
+@@ -1046,7 +1041,6 @@ config USB_G_MULTI
+       select USB_U_ETHER
+       select USB_U_RNDIS
+       select USB_F_ACM
+-      select USB_U_MS
+       help
+         The Multifunction Composite Gadget provides Ethernet (RNDIS
+         and/or CDC Ethernet), mass storage and ACM serial link
+diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
+index 295df78..0becdfa 100644
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -60,8 +60,6 @@ usb_f_ecm_subset-y           := f_subset.o
+ obj-$(CONFIG_USB_F_SUBSET)    += usb_f_ecm_subset.o
+ usb_f_rndis-y                 := f_rndis.o
+ obj-$(CONFIG_USB_F_RNDIS)     += usb_f_rndis.o
+-u_ms-y                                := storage_common.o
+-obj-$(CONFIG_USB_U_MS)                += u_ms.o
+ #
+ # USB gadget drivers
+diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c
+index 992ffb0..4b947bb 100644
+--- a/drivers/usb/gadget/acm_ms.c
++++ b/drivers/usb/gadget/acm_ms.c
+@@ -104,20 +104,6 @@ static struct usb_gadget_strings *dev_strings[] = {
+ /****************************** Configurations ******************************/
+ static struct fsg_module_parameters fsg_mod_data = { .stall = 1 };
+-#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+-
+-static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
+-
+-#else
+-
+-/*
+- * Number of buffers we will use.
+- * 2 is usually enough for good buffering pipeline
+- */
+-#define fsg_num_buffers       CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
+-
+-#endif /* CONFIG_USB_DEBUG */
+-
+ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
+ static struct fsg_common fsg_common;
+@@ -181,8 +167,7 @@ static int __init acm_ms_bind(struct usb_composite_dev *cdev)
+       void                    *retp;
+       /* set up mass storage function */
+-      retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data,
+-                                    fsg_num_buffers);
++      retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data);
+       if (IS_ERR(retp)) {
+               status = PTR_ERR(retp);
+               return PTR_ERR(retp);
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 163d911..56f1fd1 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -228,18 +228,8 @@
+ static const char fsg_string_interface[] = "Mass Storage";
+-#include "storage_common.h"
++#include "storage_common.c"
+-/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
+-static struct usb_string              fsg_strings[] = {
+-      {FSG_STRING_INTERFACE,          fsg_string_interface},
+-      {}
+-};
+-
+-static struct usb_gadget_strings      fsg_stringtab = {
+-      .language       = 0x0409,               /* en-us */
+-      .strings        = fsg_strings,
+-};
+ /*-------------------------------------------------------------------------*/
+@@ -278,7 +268,6 @@ struct fsg_common {
+       struct fsg_buffhd       *next_buffhd_to_fill;
+       struct fsg_buffhd       *next_buffhd_to_drain;
+       struct fsg_buffhd       *buffhds;
+-      unsigned int            fsg_num_buffers;
+       int                     cmnd_size;
+       u8                      cmnd[MAX_COMMAND_SIZE];
+@@ -343,7 +332,6 @@ struct fsg_config {
+       const char *product_name;               /* 16 characters or less */
+       char                    can_stall;
+-      unsigned int            fsg_num_buffers;
+ };
+ struct fsg_dev {
+@@ -2256,7 +2244,7 @@ reset:
+       if (common->fsg) {
+               fsg = common->fsg;
+-              for (i = 0; i < common->fsg_num_buffers; ++i) {
++              for (i = 0; i < fsg_num_buffers; ++i) {
+                       struct fsg_buffhd *bh = &common->buffhds[i];
+                       if (bh->inreq) {
+@@ -2313,7 +2301,7 @@ reset:
+       clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
+       /* Allocate the requests */
+-      for (i = 0; i < common->fsg_num_buffers; ++i) {
++      for (i = 0; i < fsg_num_buffers; ++i) {
+               struct fsg_buffhd       *bh = &common->buffhds[i];
+               rc = alloc_request(common, fsg->bulk_in, &bh->inreq);
+@@ -2382,7 +2370,7 @@ static void handle_exception(struct fsg_common *common)
+       /* Cancel all the pending transfers */
+       if (likely(common->fsg)) {
+-              for (i = 0; i < common->fsg_num_buffers; ++i) {
++              for (i = 0; i < fsg_num_buffers; ++i) {
+                       bh = &common->buffhds[i];
+                       if (bh->inreq_busy)
+                               usb_ep_dequeue(common->fsg->bulk_in, bh->inreq);
+@@ -2394,7 +2382,7 @@ static void handle_exception(struct fsg_common *common)
+               /* Wait until everything is idle */
+               for (;;) {
+                       int num_active = 0;
+-                      for (i = 0; i < common->fsg_num_buffers; ++i) {
++                      for (i = 0; i < fsg_num_buffers; ++i) {
+                               bh = &common->buffhds[i];
+                               num_active += bh->inreq_busy + bh->outreq_busy;
+                       }
+@@ -2417,7 +2405,7 @@ static void handle_exception(struct fsg_common *common)
+        */
+       spin_lock_irq(&common->lock);
+-      for (i = 0; i < common->fsg_num_buffers; ++i) {
++      for (i = 0; i < fsg_num_buffers; ++i) {
+               bh = &common->buffhds[i];
+               bh->state = BUF_STATE_EMPTY;
+       }
+@@ -2619,16 +2607,6 @@ static inline void fsg_common_put(struct fsg_common *common)
+       kref_put(&common->ref, fsg_common_release);
+ }
+-/* check if fsg_num_buffers is within a valid range */
+-static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
+-{
+-      if (fsg_num_buffers >= 2 && fsg_num_buffers <= 4)
+-              return 0;
+-      pr_err("fsg_num_buffers %u is out of range (%d to %d)\n",
+-             fsg_num_buffers, 2, 4);
+-      return -EINVAL;
+-}
+-
+ static struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                         struct usb_composite_dev *cdev,
+                                         struct fsg_config *cfg)
+@@ -2640,7 +2618,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
+       int nluns, i, rc;
+       char *pathbuf;
+-      rc = fsg_num_buffers_validate(cfg->fsg_num_buffers);
++      rc = fsg_num_buffers_validate();
+       if (rc != 0)
+               return ERR_PTR(rc);
+@@ -2662,8 +2640,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
+               common->free_storage_on_release = 0;
+       }
+-      common->fsg_num_buffers = cfg->fsg_num_buffers;
+-      common->buffhds = kcalloc(common->fsg_num_buffers,
++      common->buffhds = kcalloc(fsg_num_buffers,
+                                 sizeof *(common->buffhds), GFP_KERNEL);
+       if (!common->buffhds) {
+               if (common->free_storage_on_release)
+@@ -2750,7 +2727,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
+       /* Data buffers cyclic list */
+       bh = common->buffhds;
+-      i = common->fsg_num_buffers;
++      i = fsg_num_buffers;
+       goto buffhds_first_it;
+       do {
+               bh->next = bh + 1;
+@@ -2870,7 +2847,7 @@ static void fsg_common_release(struct kref *ref)
+       {
+               struct fsg_buffhd *bh = common->buffhds;
+-              unsigned i = common->fsg_num_buffers;
++              unsigned i = fsg_num_buffers;
+               do {
+                       kfree(bh->buf);
+               } while (++bh, --i);
+@@ -3032,7 +3009,7 @@ struct fsg_module_parameters {
+                          S_IRUGO);                                    \
+       MODULE_PARM_DESC(prefix ## name, desc)
+-#define __FSG_MODULE_PARAMETERS(prefix, params)                               \
++#define FSG_MODULE_PARAMETERS(prefix, params)                         \
+       _FSG_MODULE_PARAM_ARRAY(prefix, params, file, charp,            \
+                               "names of backing files or devices");   \
+       _FSG_MODULE_PARAM_ARRAY(prefix, params, ro, bool,               \
+@@ -3048,24 +3025,9 @@ struct fsg_module_parameters {
+       _FSG_MODULE_PARAM(prefix, params, stall, bool,                  \
+                         "false to prevent bulk stalls")
+-#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+-
+-#define FSG_MODULE_PARAMETERS(prefix, params)                         \
+-      __FSG_MODULE_PARAMETERS(prefix, params);                        \
+-      module_param_named(num_buffers, fsg_num_buffers, uint, S_IRUGO);\
+-      MODULE_PARM_DESC(num_buffers, "Number of pipeline buffers")
+-#else
+-
+-#define FSG_MODULE_PARAMETERS(prefix, params)                         \
+-      __FSG_MODULE_PARAMETERS(prefix, params)
+-
+-#endif
+-
+-
+ static void
+ fsg_config_from_params(struct fsg_config *cfg,
+-                     const struct fsg_module_parameters *params,
+-                     unsigned int fsg_num_buffers)
++                     const struct fsg_module_parameters *params)
+ {
+       struct fsg_lun_config *lun;
+       unsigned i;
+@@ -3093,22 +3055,19 @@ fsg_config_from_params(struct fsg_config *cfg,
+       /* Finalise */
+       cfg->can_stall = params->stall;
+-      cfg->fsg_num_buffers = fsg_num_buffers;
+ }
+ static inline struct fsg_common *
+ fsg_common_from_params(struct fsg_common *common,
+                      struct usb_composite_dev *cdev,
+-                     const struct fsg_module_parameters *params,
+-                     unsigned int fsg_num_buffers)
++                     const struct fsg_module_parameters *params)
+       __attribute__((unused));
+ static inline struct fsg_common *
+ fsg_common_from_params(struct fsg_common *common,
+                      struct usb_composite_dev *cdev,
+-                     const struct fsg_module_parameters *params,
+-                     unsigned int fsg_num_buffers)
++                     const struct fsg_module_parameters *params)
+ {
+       struct fsg_config cfg;
+-      fsg_config_from_params(&cfg, params, fsg_num_buffers);
++      fsg_config_from_params(&cfg, params);
+       return fsg_common_init(common, cdev, &cfg);
+ }
+diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c
+index bf60a9a..080e577 100644
+--- a/drivers/usb/gadget/mass_storage.c
++++ b/drivers/usb/gadget/mass_storage.c
+@@ -37,15 +37,6 @@
+ #define DRIVER_DESC           "Mass Storage Gadget"
+ #define DRIVER_VERSION                "2009/09/11"
+-/*
+- * Thanks to NetChip Technologies for donating this product ID.
+- *
+- * DO NOT REUSE THESE IDs with any other driver!!  Ever!!
+- * Instead:  allocate your own, using normal USB-IF procedures.
+- */
+-#define FSG_VENDOR_ID 0x0525  /* NetChip */
+-#define FSG_PRODUCT_ID        0xa4a5  /* Linux-USB File-backed Storage Gadget */
+-
+ /*-------------------------------------------------------------------------*/
+ /*
+@@ -111,20 +102,6 @@ static struct usb_gadget_strings *dev_strings[] = {
+ static struct fsg_module_parameters mod_data = {
+       .stall = 1
+ };
+-#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+-
+-static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
+-
+-#else
+-
+-/*
+- * Number of buffers we will use.
+- * 2 is usually enough for good buffering pipeline
+- */
+-#define fsg_num_buffers       CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
+-
+-#endif /* CONFIG_USB_DEBUG */
+-
+ FSG_MODULE_PARAMETERS(/* no prefix */, mod_data);
+ static unsigned long msg_registered;
+@@ -152,7 +129,7 @@ static int __init msg_do_config(struct usb_configuration *c)
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+-      fsg_config_from_params(&config, &mod_data, fsg_num_buffers);
++      fsg_config_from_params(&config, &mod_data);
+       config.ops = &ops;
+       retp = fsg_common_init(&common, c->cdev, &config);
+diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
+index f610d01..2a1ebef 100644
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -132,20 +132,6 @@ static struct usb_gadget_strings *dev_strings[] = {
+ /****************************** Configurations ******************************/
+ static struct fsg_module_parameters fsg_mod_data = { .stall = 1 };
+-#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+-
+-static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
+-
+-#else
+-
+-/*
+- * Number of buffers we will use.
+- * 2 is usually enough for good buffering pipeline
+- */
+-#define fsg_num_buffers       CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
+-
+-#endif /* CONFIG_USB_DEBUG */
+-
+ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
+ static struct fsg_common fsg_common;
+@@ -308,8 +294,7 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
+       /* set up mass storage function */
+       {
+               void *retp;
+-              retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data,
+-                                            fsg_num_buffers);
++              retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data);
+               if (IS_ERR(retp)) {
+                       status = PTR_ERR(retp);
+                       goto fail1;
+diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
+index 942324c..dbce3a9 100644
+--- a/drivers/usb/gadget/storage_common.c
++++ b/drivers/usb/gadget/storage_common.c
+@@ -23,22 +23,242 @@
+  * The valid range of num_buffers is: num >= 2 && num <= 4.
+  */
+-#include <linux/module.h>
+-#include <linux/blkdev.h>
+-#include <linux/file.h>
+-#include <linux/fs.h>
+-#include <linux/usb/composite.h>
+-#include "storage_common.h"
++#include <linux/usb/storage.h>
++#include <scsi/scsi.h>
++#include <asm/unaligned.h>
++
++
++/*
++ * Thanks to NetChip Technologies for donating this product ID.
++ *
++ * DO NOT REUSE THESE IDs with any other driver!!  Ever!!
++ * Instead:  allocate your own, using normal USB-IF procedures.
++ */
++#define FSG_VENDOR_ID 0x0525  /* NetChip */
++#define FSG_PRODUCT_ID        0xa4a5  /* Linux-USB File-backed Storage Gadget */
++
++
++/*-------------------------------------------------------------------------*/
++
++
++#ifndef DEBUG
++#undef VERBOSE_DEBUG
++#undef DUMP_MSGS
++#endif /* !DEBUG */
++
++#ifdef VERBOSE_DEBUG
++#define VLDBG LDBG
++#else
++#define VLDBG(lun, fmt, args...) do { } while (0)
++#endif /* VERBOSE_DEBUG */
++
++#define LDBG(lun, fmt, args...)   dev_dbg (&(lun)->dev, fmt, ## args)
++#define LERROR(lun, fmt, args...) dev_err (&(lun)->dev, fmt, ## args)
++#define LWARN(lun, fmt, args...)  dev_warn(&(lun)->dev, fmt, ## args)
++#define LINFO(lun, fmt, args...)  dev_info(&(lun)->dev, fmt, ## args)
++
++
++#ifdef DUMP_MSGS
++
++#  define dump_msg(fsg, /* const char * */ label,                     \
++                 /* const u8 * */ buf, /* unsigned */ length) do {    \
++      if (length < 512) {                                             \
++              DBG(fsg, "%s, length %u:\n", label, length);            \
++              print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET,      \
++                             16, 1, buf, length, 0);                  \
++      }                                                               \
++} while (0)
++
++#  define dump_cdb(fsg) do { } while (0)
++
++#else
++
++#  define dump_msg(fsg, /* const char * */ label, \
++                 /* const u8 * */ buf, /* unsigned */ length) do { } while (0)
++
++#  ifdef VERBOSE_DEBUG
++
++#    define dump_cdb(fsg)                                             \
++      print_hex_dump(KERN_DEBUG, "SCSI CDB: ", DUMP_PREFIX_NONE,      \
++                     16, 1, (fsg)->cmnd, (fsg)->cmnd_size, 0)         \
++
++#  else
++
++#    define dump_cdb(fsg) do { } while (0)
++
++#  endif /* VERBOSE_DEBUG */
++
++#endif /* DUMP_MSGS */
++
++/*-------------------------------------------------------------------------*/
++
++/* Length of a SCSI Command Data Block */
++#define MAX_COMMAND_SIZE      16
++
++/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */
++#define SS_NO_SENSE                           0
++#define SS_COMMUNICATION_FAILURE              0x040800
++#define SS_INVALID_COMMAND                    0x052000
++#define SS_INVALID_FIELD_IN_CDB                       0x052400
++#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x052100
++#define SS_LOGICAL_UNIT_NOT_SUPPORTED         0x052500
++#define SS_MEDIUM_NOT_PRESENT                 0x023a00
++#define SS_MEDIUM_REMOVAL_PREVENTED           0x055302
++#define SS_NOT_READY_TO_READY_TRANSITION      0x062800
++#define SS_RESET_OCCURRED                     0x062900
++#define SS_SAVING_PARAMETERS_NOT_SUPPORTED    0x053900
++#define SS_UNRECOVERED_READ_ERROR             0x031100
++#define SS_WRITE_ERROR                                0x030c02
++#define SS_WRITE_PROTECTED                    0x072700
++
++#define SK(x)         ((u8) ((x) >> 16))      /* Sense Key byte, etc. */
++#define ASC(x)                ((u8) ((x) >> 8))
++#define ASCQ(x)               ((u8) (x))
++
++
++/*-------------------------------------------------------------------------*/
++
++
++struct fsg_lun {
++      struct file     *filp;
++      loff_t          file_length;
++      loff_t          num_sectors;
++
++      unsigned int    initially_ro:1;
++      unsigned int    ro:1;
++      unsigned int    removable:1;
++      unsigned int    cdrom:1;
++      unsigned int    prevent_medium_removal:1;
++      unsigned int    registered:1;
++      unsigned int    info_valid:1;
++      unsigned int    nofua:1;
++
++      u32             sense_data;
++      u32             sense_data_info;
++      u32             unit_attention_data;
++
++      unsigned int    blkbits;        /* Bits of logical block size of bound block device */
++      unsigned int    blksize;        /* logical block size of bound block device */
++      struct device   dev;
++};
++
++static inline bool fsg_lun_is_open(struct fsg_lun *curlun)
++{
++      return curlun->filp != NULL;
++}
+ static inline struct fsg_lun *fsg_lun_from_dev(struct device *dev)
+ {
+       return container_of(dev, struct fsg_lun, dev);
+ }
++
++/* Big enough to hold our biggest descriptor */
++#define EP0_BUFSIZE   256
++#define DELAYED_STATUS        (EP0_BUFSIZE + 999)     /* An impossibly large value */
++
++#ifdef CONFIG_USB_GADGET_DEBUG_FILES
++
++static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
++module_param_named(num_buffers, fsg_num_buffers, uint, S_IRUGO);
++MODULE_PARM_DESC(num_buffers, "Number of pipeline buffers");
++
++#else
++
++/*
++ * Number of buffers we will use.
++ * 2 is usually enough for good buffering pipeline
++ */
++#define fsg_num_buffers       CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
++
++#endif /* CONFIG_USB_DEBUG */
++
++/* check if fsg_num_buffers is within a valid range */
++static inline int fsg_num_buffers_validate(void)
++{
++      if (fsg_num_buffers >= 2 && fsg_num_buffers <= 4)
++              return 0;
++      pr_err("fsg_num_buffers %u is out of range (%d to %d)\n",
++             fsg_num_buffers, 2 ,4);
++      return -EINVAL;
++}
++
++/* Default size of buffer length. */
++#define FSG_BUFLEN    ((u32)16384)
++
++/* Maximal number of LUNs supported in mass storage function */
++#define FSG_MAX_LUNS  8
++
++enum fsg_buffer_state {
++      BUF_STATE_EMPTY = 0,
++      BUF_STATE_FULL,
++      BUF_STATE_BUSY
++};
++
++struct fsg_buffhd {
++      void                            *buf;
++      enum fsg_buffer_state           state;
++      struct fsg_buffhd               *next;
++
++      /*
++       * The NetChip 2280 is faster, and handles some protocol faults
++       * better, if we don't submit any short bulk-out read requests.
++       * So we will record the intended request length here.
++       */
++      unsigned int                    bulk_out_intended_length;
++
++      struct usb_request              *inreq;
++      int                             inreq_busy;
++      struct usb_request              *outreq;
++      int                             outreq_busy;
++};
++
++enum fsg_state {
++      /* This one isn't used anywhere */
++      FSG_STATE_COMMAND_PHASE = -10,
++      FSG_STATE_DATA_PHASE,
++      FSG_STATE_STATUS_PHASE,
++
++      FSG_STATE_IDLE = 0,
++      FSG_STATE_ABORT_BULK_OUT,
++      FSG_STATE_RESET,
++      FSG_STATE_INTERFACE_CHANGE,
++      FSG_STATE_CONFIG_CHANGE,
++      FSG_STATE_DISCONNECT,
++      FSG_STATE_EXIT,
++      FSG_STATE_TERMINATED
++};
++
++enum data_direction {
++      DATA_DIR_UNKNOWN = 0,
++      DATA_DIR_FROM_HOST,
++      DATA_DIR_TO_HOST,
++      DATA_DIR_NONE
++};
++
++
++/*-------------------------------------------------------------------------*/
++
++
++static inline u32 get_unaligned_be24(u8 *buf)
++{
++      return 0xffffff & (u32) get_unaligned_be32(buf - 1);
++}
++
++
++/*-------------------------------------------------------------------------*/
++
++
++enum {
++      FSG_STRING_INTERFACE
++};
++
++
+ /* There is only one interface. */
+-struct usb_interface_descriptor fsg_intf_desc = {
++static struct usb_interface_descriptor
++fsg_intf_desc = {
+       .bLength =              sizeof fsg_intf_desc,
+       .bDescriptorType =      USB_DT_INTERFACE,
+@@ -48,14 +268,14 @@ struct usb_interface_descriptor fsg_intf_desc = {
+       .bInterfaceProtocol =   USB_PR_BULK,    /* Adjusted during fsg_bind() */
+       .iInterface =           FSG_STRING_INTERFACE,
+ };
+-EXPORT_SYMBOL(fsg_intf_desc);
+ /*
+  * Three full-speed endpoint descriptors: bulk-in, bulk-out, and
+  * interrupt-in.
+  */
+-struct usb_endpoint_descriptor fsg_fs_bulk_in_desc = {
++static struct usb_endpoint_descriptor
++fsg_fs_bulk_in_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -63,9 +283,9 @@ struct usb_endpoint_descriptor fsg_fs_bulk_in_desc = {
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       /* wMaxPacketSize set by autoconfiguration */
+ };
+-EXPORT_SYMBOL(fsg_fs_bulk_in_desc);
+-struct usb_endpoint_descriptor fsg_fs_bulk_out_desc = {
++static struct usb_endpoint_descriptor
++fsg_fs_bulk_out_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -73,15 +293,13 @@ struct usb_endpoint_descriptor fsg_fs_bulk_out_desc = {
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       /* wMaxPacketSize set by autoconfiguration */
+ };
+-EXPORT_SYMBOL(fsg_fs_bulk_out_desc);
+-struct usb_descriptor_header *fsg_fs_function[] = {
++static struct usb_descriptor_header *fsg_fs_function[] = {
+       (struct usb_descriptor_header *) &fsg_intf_desc,
+       (struct usb_descriptor_header *) &fsg_fs_bulk_in_desc,
+       (struct usb_descriptor_header *) &fsg_fs_bulk_out_desc,
+       NULL,
+ };
+-EXPORT_SYMBOL(fsg_fs_function);
+ /*
+@@ -92,7 +310,8 @@ EXPORT_SYMBOL(fsg_fs_function);
+  * and a "device qualifier" ... plus more construction options
+  * for the configuration descriptor.
+  */
+-struct usb_endpoint_descriptor fsg_hs_bulk_in_desc = {
++static struct usb_endpoint_descriptor
++fsg_hs_bulk_in_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -100,9 +319,9 @@ struct usb_endpoint_descriptor fsg_hs_bulk_in_desc = {
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       cpu_to_le16(512),
+ };
+-EXPORT_SYMBOL(fsg_hs_bulk_in_desc);
+-struct usb_endpoint_descriptor fsg_hs_bulk_out_desc = {
++static struct usb_endpoint_descriptor
++fsg_hs_bulk_out_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -111,18 +330,17 @@ struct usb_endpoint_descriptor fsg_hs_bulk_out_desc = {
+       .wMaxPacketSize =       cpu_to_le16(512),
+       .bInterval =            1,      /* NAK every 1 uframe */
+ };
+-EXPORT_SYMBOL(fsg_hs_bulk_out_desc);
+-struct usb_descriptor_header *fsg_hs_function[] = {
++static struct usb_descriptor_header *fsg_hs_function[] = {
+       (struct usb_descriptor_header *) &fsg_intf_desc,
+       (struct usb_descriptor_header *) &fsg_hs_bulk_in_desc,
+       (struct usb_descriptor_header *) &fsg_hs_bulk_out_desc,
+       NULL,
+ };
+-EXPORT_SYMBOL(fsg_hs_function);
+-struct usb_endpoint_descriptor fsg_ss_bulk_in_desc = {
++static struct usb_endpoint_descriptor
++fsg_ss_bulk_in_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -130,17 +348,16 @@ struct usb_endpoint_descriptor fsg_ss_bulk_in_desc = {
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       cpu_to_le16(1024),
+ };
+-EXPORT_SYMBOL(fsg_ss_bulk_in_desc);
+-struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc = {
++static struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc = {
+       .bLength =              sizeof(fsg_ss_bulk_in_comp_desc),
+       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
+       /*.bMaxBurst =          DYNAMIC, */
+ };
+-EXPORT_SYMBOL(fsg_ss_bulk_in_comp_desc);
+-struct usb_endpoint_descriptor fsg_ss_bulk_out_desc = {
++static struct usb_endpoint_descriptor
++fsg_ss_bulk_out_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -148,17 +365,15 @@ struct usb_endpoint_descriptor fsg_ss_bulk_out_desc = {
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       cpu_to_le16(1024),
+ };
+-EXPORT_SYMBOL(fsg_ss_bulk_out_desc);
+-struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = {
++static struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = {
+       .bLength =              sizeof(fsg_ss_bulk_in_comp_desc),
+       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
+       /*.bMaxBurst =          DYNAMIC, */
+ };
+-EXPORT_SYMBOL(fsg_ss_bulk_out_comp_desc);
+-struct usb_descriptor_header *fsg_ss_function[] = {
++static struct usb_descriptor_header *fsg_ss_function[] = {
+       (struct usb_descriptor_header *) &fsg_intf_desc,
+       (struct usb_descriptor_header *) &fsg_ss_bulk_in_desc,
+       (struct usb_descriptor_header *) &fsg_ss_bulk_in_comp_desc,
+@@ -166,7 +381,17 @@ struct usb_descriptor_header *fsg_ss_function[] = {
+       (struct usb_descriptor_header *) &fsg_ss_bulk_out_comp_desc,
+       NULL,
+ };
+-EXPORT_SYMBOL(fsg_ss_function);
++
++/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
++static struct usb_string              fsg_strings[] = {
++      {FSG_STRING_INTERFACE,          fsg_string_interface},
++      {}
++};
++
++static struct usb_gadget_strings      fsg_stringtab = {
++      .language       = 0x0409,               /* en-us */
++      .strings        = fsg_strings,
++};
+  /*-------------------------------------------------------------------------*/
+@@ -176,7 +401,7 @@ EXPORT_SYMBOL(fsg_ss_function);
+  * the caller must own fsg->filesem for writing.
+  */
+-void fsg_lun_close(struct fsg_lun *curlun)
++static void fsg_lun_close(struct fsg_lun *curlun)
+ {
+       if (curlun->filp) {
+               LDBG(curlun, "close backing file\n");
+@@ -184,9 +409,9 @@ void fsg_lun_close(struct fsg_lun *curlun)
+               curlun->filp = NULL;
+       }
+ }
+-EXPORT_SYMBOL(fsg_lun_close);
+-int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
++
++static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
+ {
+       int                             ro;
+       struct file                     *filp = NULL;
+@@ -283,7 +508,6 @@ out:
+       fput(filp);
+       return rc;
+ }
+-EXPORT_SYMBOL(fsg_lun_open);
+ /*-------------------------------------------------------------------------*/
+@@ -292,7 +516,7 @@ EXPORT_SYMBOL(fsg_lun_open);
+  * Sync the file data, don't bother with the metadata.
+  * This code was copied from fs/buffer.c:sys_fdatasync().
+  */
+-int fsg_lun_fsync_sub(struct fsg_lun *curlun)
++static int fsg_lun_fsync_sub(struct fsg_lun *curlun)
+ {
+       struct file     *filp = curlun->filp;
+@@ -300,9 +524,8 @@ int fsg_lun_fsync_sub(struct fsg_lun *curlun)
+               return 0;
+       return vfs_fsync(filp, 1);
+ }
+-EXPORT_SYMBOL(fsg_lun_fsync_sub);
+-void store_cdrom_address(u8 *dest, int msf, u32 addr)
++static void store_cdrom_address(u8 *dest, int msf, u32 addr)
+ {
+       if (msf) {
+               /* Convert to Minutes-Seconds-Frames */
+@@ -319,12 +542,12 @@ void store_cdrom_address(u8 *dest, int msf, u32 addr)
+               put_unaligned_be32(addr, dest);
+       }
+ }
+-EXPORT_SYMBOL(store_cdrom_address);
++
+ /*-------------------------------------------------------------------------*/
+-ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr,
++static ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr,
+                          char *buf)
+ {
+       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+@@ -333,18 +556,16 @@ ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr,
+                                 ? curlun->ro
+                                 : curlun->initially_ro);
+ }
+-EXPORT_SYMBOL(fsg_show_ro);
+-ssize_t fsg_show_nofua(struct device *dev, struct device_attribute *attr,
++static ssize_t fsg_show_nofua(struct device *dev, struct device_attribute *attr,
+                             char *buf)
+ {
+       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+       return sprintf(buf, "%u\n", curlun->nofua);
+ }
+-EXPORT_SYMBOL(fsg_show_nofua);
+-ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
++static ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
+                            char *buf)
+ {
+       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+@@ -370,10 +591,9 @@ ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
+       up_read(filesem);
+       return rc;
+ }
+-EXPORT_SYMBOL(fsg_show_file);
+-ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr,
++static ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr,
+                           const char *buf, size_t count)
+ {
+       ssize_t         rc;
+@@ -402,9 +622,8 @@ ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr,
+       up_read(filesem);
+       return rc;
+ }
+-EXPORT_SYMBOL(fsg_store_ro);
+-ssize_t fsg_store_nofua(struct device *dev,
++static ssize_t fsg_store_nofua(struct device *dev,
+                              struct device_attribute *attr,
+                              const char *buf, size_t count)
+ {
+@@ -424,9 +643,8 @@ ssize_t fsg_store_nofua(struct device *dev,
+       return count;
+ }
+-EXPORT_SYMBOL(fsg_store_nofua);
+-ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr,
++static ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr,
+                             const char *buf, size_t count)
+ {
+       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+@@ -457,6 +675,3 @@ ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr,
+       up_write(filesem);
+       return (rc < 0 ? rc : count);
+ }
+-EXPORT_SYMBOL(fsg_store_file);
+-
+-MODULE_LICENSE("GPL");
+diff --git a/drivers/usb/gadget/storage_common.h b/drivers/usb/gadget/storage_common.h
+deleted file mode 100644
+index 1fcda2b..0000000
+--- a/drivers/usb/gadget/storage_common.h
++++ /dev/null
+@@ -1,210 +0,0 @@
+-#ifndef USB_STORAGE_COMMON_H
+-#define USB_STORAGE_COMMON_H
+-
+-#include <linux/device.h>
+-#include <linux/usb/storage.h>
+-#include <scsi/scsi.h>
+-#include <asm/unaligned.h>
+-
+-#ifndef DEBUG
+-#undef VERBOSE_DEBUG
+-#undef DUMP_MSGS
+-#endif /* !DEBUG */
+-
+-#ifdef VERBOSE_DEBUG
+-#define VLDBG LDBG
+-#else
+-#define VLDBG(lun, fmt, args...) do { } while (0)
+-#endif /* VERBOSE_DEBUG */
+-
+-#define LDBG(lun, fmt, args...)   dev_dbg(&(lun)->dev, fmt, ## args)
+-#define LERROR(lun, fmt, args...) dev_err(&(lun)->dev, fmt, ## args)
+-#define LWARN(lun, fmt, args...)  dev_warn(&(lun)->dev, fmt, ## args)
+-#define LINFO(lun, fmt, args...)  dev_info(&(lun)->dev, fmt, ## args)
+-
+-#ifdef DUMP_MSGS
+-
+-#  define dump_msg(fsg, /* const char * */ label,                     \
+-                 /* const u8 * */ buf, /* unsigned */ length)         \
+-do {                                                                  \
+-      if (length < 512) {                                             \
+-              DBG(fsg, "%s, length %u:\n", label, length);            \
+-              print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET,      \
+-                             16, 1, buf, length, 0);                  \
+-      }                                                               \
+-} while (0)
+-
+-#  define dump_cdb(fsg) do { } while (0)
+-
+-#else
+-
+-#  define dump_msg(fsg, /* const char * */ label, \
+-                 /* const u8 * */ buf, /* unsigned */ length) do { } while (0)
+-
+-#  ifdef VERBOSE_DEBUG
+-
+-#    define dump_cdb(fsg)                                             \
+-      print_hex_dump(KERN_DEBUG, "SCSI CDB: ", DUMP_PREFIX_NONE,      \
+-                     16, 1, (fsg)->cmnd, (fsg)->cmnd_size, 0)         \
+-
+-#  else
+-
+-#    define dump_cdb(fsg) do { } while (0)
+-
+-#  endif /* VERBOSE_DEBUG */
+-
+-#endif /* DUMP_MSGS */
+-
+-/* Length of a SCSI Command Data Block */
+-#define MAX_COMMAND_SIZE      16
+-
+-/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */
+-#define SS_NO_SENSE                           0
+-#define SS_COMMUNICATION_FAILURE              0x040800
+-#define SS_INVALID_COMMAND                    0x052000
+-#define SS_INVALID_FIELD_IN_CDB                       0x052400
+-#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x052100
+-#define SS_LOGICAL_UNIT_NOT_SUPPORTED         0x052500
+-#define SS_MEDIUM_NOT_PRESENT                 0x023a00
+-#define SS_MEDIUM_REMOVAL_PREVENTED           0x055302
+-#define SS_NOT_READY_TO_READY_TRANSITION      0x062800
+-#define SS_RESET_OCCURRED                     0x062900
+-#define SS_SAVING_PARAMETERS_NOT_SUPPORTED    0x053900
+-#define SS_UNRECOVERED_READ_ERROR             0x031100
+-#define SS_WRITE_ERROR                                0x030c02
+-#define SS_WRITE_PROTECTED                    0x072700
+-
+-#define SK(x)         ((u8) ((x) >> 16))      /* Sense Key byte, etc. */
+-#define ASC(x)                ((u8) ((x) >> 8))
+-#define ASCQ(x)               ((u8) (x))
+-
+-struct fsg_lun {
+-      struct file     *filp;
+-      loff_t          file_length;
+-      loff_t          num_sectors;
+-
+-      unsigned int    initially_ro:1;
+-      unsigned int    ro:1;
+-      unsigned int    removable:1;
+-      unsigned int    cdrom:1;
+-      unsigned int    prevent_medium_removal:1;
+-      unsigned int    registered:1;
+-      unsigned int    info_valid:1;
+-      unsigned int    nofua:1;
+-
+-      u32             sense_data;
+-      u32             sense_data_info;
+-      u32             unit_attention_data;
+-
+-      unsigned int    blkbits; /* Bits of logical block size
+-                                                     of bound block device */
+-      unsigned int    blksize; /* logical block size of bound block device */
+-      struct device   dev;
+-};
+-
+-static inline bool fsg_lun_is_open(struct fsg_lun *curlun)
+-{
+-      return curlun->filp != NULL;
+-}
+-
+-/* Big enough to hold our biggest descriptor */
+-#define EP0_BUFSIZE   256
+-#define DELAYED_STATUS        (EP0_BUFSIZE + 999)     /* An impossibly large value */
+-
+-/* Default size of buffer length. */
+-#define FSG_BUFLEN    ((u32)16384)
+-
+-/* Maximal number of LUNs supported in mass storage function */
+-#define FSG_MAX_LUNS  8
+-
+-enum fsg_buffer_state {
+-      BUF_STATE_EMPTY = 0,
+-      BUF_STATE_FULL,
+-      BUF_STATE_BUSY
+-};
+-
+-struct fsg_buffhd {
+-      void                            *buf;
+-      enum fsg_buffer_state           state;
+-      struct fsg_buffhd               *next;
+-
+-      /*
+-       * The NetChip 2280 is faster, and handles some protocol faults
+-       * better, if we don't submit any short bulk-out read requests.
+-       * So we will record the intended request length here.
+-       */
+-      unsigned int                    bulk_out_intended_length;
+-
+-      struct usb_request              *inreq;
+-      int                             inreq_busy;
+-      struct usb_request              *outreq;
+-      int                             outreq_busy;
+-};
+-
+-enum fsg_state {
+-      /* This one isn't used anywhere */
+-      FSG_STATE_COMMAND_PHASE = -10,
+-      FSG_STATE_DATA_PHASE,
+-      FSG_STATE_STATUS_PHASE,
+-
+-      FSG_STATE_IDLE = 0,
+-      FSG_STATE_ABORT_BULK_OUT,
+-      FSG_STATE_RESET,
+-      FSG_STATE_INTERFACE_CHANGE,
+-      FSG_STATE_CONFIG_CHANGE,
+-      FSG_STATE_DISCONNECT,
+-      FSG_STATE_EXIT,
+-      FSG_STATE_TERMINATED
+-};
+-
+-enum data_direction {
+-      DATA_DIR_UNKNOWN = 0,
+-      DATA_DIR_FROM_HOST,
+-      DATA_DIR_TO_HOST,
+-      DATA_DIR_NONE
+-};
+-
+-static inline u32 get_unaligned_be24(u8 *buf)
+-{
+-      return 0xffffff & (u32) get_unaligned_be32(buf - 1);
+-}
+-
+-enum {
+-      FSG_STRING_INTERFACE
+-};
+-
+-extern struct usb_interface_descriptor fsg_intf_desc;
+-
+-extern struct usb_endpoint_descriptor fsg_fs_bulk_in_desc;
+-extern struct usb_endpoint_descriptor fsg_fs_bulk_out_desc;
+-extern struct usb_descriptor_header *fsg_fs_function[];
+-
+-extern struct usb_endpoint_descriptor fsg_hs_bulk_in_desc;
+-extern struct usb_endpoint_descriptor fsg_hs_bulk_out_desc;
+-extern struct usb_descriptor_header *fsg_hs_function[];
+-
+-extern struct usb_endpoint_descriptor fsg_ss_bulk_in_desc;
+-extern struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc;
+-extern struct usb_endpoint_descriptor fsg_ss_bulk_out_desc;
+-extern struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc;
+-extern struct usb_descriptor_header *fsg_ss_function[];
+-
+-void fsg_lun_close(struct fsg_lun *curlun);
+-int fsg_lun_open(struct fsg_lun *curlun, const char *filename);
+-int fsg_lun_fsync_sub(struct fsg_lun *curlun);
+-void store_cdrom_address(u8 *dest, int msf, u32 addr);
+-ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr,
+-                  char *buf);
+-ssize_t fsg_show_nofua(struct device *dev, struct device_attribute *attr,
+-                     char *buf);
+-ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
+-                    char *buf);
+-ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr,
+-                   const char *buf, size_t count);
+-ssize_t fsg_store_nofua(struct device *dev,
+-                      struct device_attribute *attr,
+-                      const char *buf, size_t count);
+-ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr,
+-                     const char *buf, size_t count);
+-
+-#endif /* USB_STORAGE_COMMON_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1108-USB-gadget-fix-up-comment.patch b/patches.tizen/1108-USB-gadget-fix-up-comment.patch
new file mode 100644 (file)
index 0000000..29d110f
--- /dev/null
@@ -0,0 +1,31 @@
+From 8fb42f6c2a1e30ff2fb0869a5bfe4aed09a6d2d3 Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Fri, 28 Jun 2013 11:32:57 -0700
+Subject: [PATCH 1108/1302] USB: gadget: fix up comment
+
+This endif is for CONFIG_USB_GADGET_DEBUG_FILES, not CONFIG_USB_DEBUG,
+so document it properly.
+
+Acked-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/storage_common.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
+index dbce3a9..8c71212 100644
+--- a/drivers/usb/gadget/storage_common.c
++++ b/drivers/usb/gadget/storage_common.c
+@@ -172,7 +172,7 @@ MODULE_PARM_DESC(num_buffers, "Number of pipeline buffers");
+  */
+ #define fsg_num_buffers       CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
+-#endif /* CONFIG_USB_DEBUG */
++#endif /* CONFIG_USB_GADGET_DEBUG_FILES */
+ /* check if fsg_num_buffers is within a valid range */
+ static inline int fsg_num_buffers_validate(void)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1109-usb-gadget-f_mass_storage-use-NULL-instead-of-0.patch b/patches.tizen/1109-usb-gadget-f_mass_storage-use-NULL-instead-of-0.patch
new file mode 100644 (file)
index 0000000..bd5c4db
--- /dev/null
@@ -0,0 +1,43 @@
+From b7999561d987fd56497c0948d8de3b007f585e3b Mon Sep 17 00:00:00 2001
+From: Jingoo Han <jg1.han@samsung.com>
+Date: Mon, 5 Aug 2013 12:11:05 +0900
+Subject: [PATCH 1109/1302] usb: gadget: f_mass_storage: use NULL instead of 0
+
+The local variables such as 'filename', 'vendor_name', and
+'product_name' are pointers; thus, use NULL instead of 0 to fix
+the following sparse warnings
+
+drivers/usb/gadget/f_mass_storage.c:3046:27: warning: Using plain integer as NULL pointer
+drivers/usb/gadget/f_mass_storage.c:3050:28: warning: Using plain integer as NULL pointer
+drivers/usb/gadget/f_mass_storage.c:3051:29: warning: Using plain integer as NULL pointer
+
+Signed-off-by: Jingoo Han <jg1.han@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 56f1fd1..4d4e96a 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -3043,12 +3043,12 @@ fsg_config_from_params(struct fsg_config *cfg,
+               lun->filename =
+                       params->file_count > i && params->file[i][0]
+                       ? params->file[i]
+-                      : 0;
++                      : NULL;
+       }
+       /* Let MSF use defaults */
+-      cfg->vendor_name = 0;
+-      cfg->product_name = 0;
++      cfg->vendor_name = NULL;
++      cfg->product_name = NULL;
+       cfg->ops = NULL;
+       cfg->private_data = NULL;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1110-usb-gadget-rndis-Staticize-rndis_init-rndis_exit.patch b/patches.tizen/1110-usb-gadget-rndis-Staticize-rndis_init-rndis_exit.patch
new file mode 100644 (file)
index 0000000..22f529c
--- /dev/null
@@ -0,0 +1,44 @@
+From 8c46b9e2cc7896332a09d0b5d3b630c9836559ff Mon Sep 17 00:00:00 2001
+From: Jingoo Han <jg1.han@samsung.com>
+Date: Mon, 5 Aug 2013 12:12:42 +0900
+Subject: [PATCH 1110/1302] usb: gadget: rndis: Staticize
+ rndis_init()/rndis_exit()
+
+rndis_init() and rndis_exit() are used only in this file.
+Fix the following sparse warnings:
+
+drivers/usb/gadget/rndis.c:1145:5: warning: symbol 'rndis_init' was not declared. Should it be static?
+drivers/usb/gadget/rndis.c:1179:6: warning: symbol 'rndis_exit' was not declared. Should it be static?
+
+Signed-off-by: Jingoo Han <jg1.han@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/rndis.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
+index 3e3ea72..9575085 100644
+--- a/drivers/usb/gadget/rndis.c
++++ b/drivers/usb/gadget/rndis.c
+@@ -1142,7 +1142,7 @@ static struct proc_dir_entry *rndis_connect_state [RNDIS_MAX_CONFIGS];
+ #endif /* CONFIG_USB_GADGET_DEBUG_FILES */
+-int rndis_init(void)
++static int rndis_init(void)
+ {
+       u8 i;
+@@ -1176,7 +1176,7 @@ int rndis_init(void)
+ }
+ module_init(rndis_init);
+-void rndis_exit(void)
++static void rndis_exit(void)
+ {
+ #ifdef CONFIG_USB_GADGET_DEBUG_FILES
+       u8 i;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1111-sysfs.h-add-__ATTR_RW-macro.patch b/patches.tizen/1111-sysfs.h-add-__ATTR_RW-macro.patch
new file mode 100644 (file)
index 0000000..9991bf1
--- /dev/null
@@ -0,0 +1,49 @@
+From 71a11f764ae2a00a23491bed5da20d893690aa08 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 15 Jan 2014 10:45:17 +0100
+Subject: [PATCH 1111/1302] sysfs.h: add __ATTR_RW() macro
+
+A number of parts of the kernel created their own version of this, might
+as well have the sysfs core provide it instead.
+
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[mainline backport]
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/sysfs.h | 2 ++
+ mm/backing-dev.c      | 2 --
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
+index e2cee22..9cd20c8 100644
+--- a/include/linux/sysfs.h
++++ b/include/linux/sysfs.h
+@@ -79,6 +79,8 @@ struct attribute_group {
+       .show   = _name##_show,                                 \
+ }
++#define __ATTR_RW(_name) __ATTR(_name, 0644, _name##_show, _name##_store)
++
+ #define __ATTR_NULL { .attr = { .name = NULL } }
+ #ifdef CONFIG_DEBUG_LOCK_ALLOC
+diff --git a/mm/backing-dev.c b/mm/backing-dev.c
+index 5025174..8623cea 100644
+--- a/mm/backing-dev.c
++++ b/mm/backing-dev.c
+@@ -232,8 +232,6 @@ static ssize_t stable_pages_required_show(struct device *dev,
+                       bdi_cap_stable_pages_required(bdi) ? 1 : 0);
+ }
+-#define __ATTR_RW(attr) __ATTR(attr, 0644, attr##_show, attr##_store)
+-
+ static struct device_attribute bdi_dev_attrs[] = {
+       __ATTR_RW(read_ahead_kb),
+       __ATTR_RW(min_ratio),
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1112-driver-core-device.h-add-RW-and-RO-attribute-macros.patch b/patches.tizen/1112-driver-core-device.h-add-RW-and-RO-attribute-macros.patch
new file mode 100644 (file)
index 0000000..2a30ac8
--- /dev/null
@@ -0,0 +1,87 @@
+From 6d19f18a24062c075bec45cc2c5608c46f2632f1 Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Sun, 14 Jul 2013 16:05:54 -0700
+Subject: [PATCH 1112/1302] driver core: device.h: add RW and RO attribute
+ macros
+
+Make it easier to create attributes without having to always audit the
+mode settings.
+
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/device.h | 28 +++++++++++++++++++++-------
+ 1 file changed, 21 insertions(+), 7 deletions(-)
+
+diff --git a/include/linux/device.h b/include/linux/device.h
+index 1ce409f..9510baf 100644
+--- a/include/linux/device.h
++++ b/include/linux/device.h
+@@ -47,7 +47,11 @@ struct bus_attribute {
+ };
+ #define BUS_ATTR(_name, _mode, _show, _store) \
+-struct bus_attribute bus_attr_##_name = __ATTR(_name, _mode, _show, _store)
++      struct bus_attribute bus_attr_##_name = __ATTR(_name, _mode, _show, _store)
++#define BUS_ATTR_RW(_name) \
++      struct bus_attribute bus_attr_##_name = __ATTR_RW(_name)
++#define BUS_ATTR_RO(_name) \
++      struct bus_attribute bus_attr_##_name = __ATTR_RO(_name)
+ extern int __must_check bus_create_file(struct bus_type *,
+                                       struct bus_attribute *);
+@@ -255,9 +259,12 @@ struct driver_attribute {
+                        size_t count);
+ };
+-#define DRIVER_ATTR(_name, _mode, _show, _store)      \
+-struct driver_attribute driver_attr_##_name =         \
+-      __ATTR(_name, _mode, _show, _store)
++#define DRIVER_ATTR(_name, _mode, _show, _store) \
++      struct driver_attribute driver_attr_##_name = __ATTR(_name, _mode, _show, _store)
++#define DRIVER_ATTR_RW(_name) \
++      struct driver_attribute driver_attr_##_name = __ATTR_RW(_name)
++#define DRIVER_ATTR_RO(_name) \
++      struct driver_attribute driver_attr_##_name = __ATTR_RO(_name)
+ extern int __must_check driver_create_file(struct device_driver *driver,
+                                       const struct driver_attribute *attr);
+@@ -408,8 +415,12 @@ struct class_attribute {
+                                const struct class_attribute *attr);
+ };
+-#define CLASS_ATTR(_name, _mode, _show, _store)                       \
+-struct class_attribute class_attr_##_name = __ATTR(_name, _mode, _show, _store)
++#define CLASS_ATTR(_name, _mode, _show, _store) \
++      struct class_attribute class_attr_##_name = __ATTR(_name, _mode, _show, _store)
++#define CLASS_ATTR_RW(_name) \
++      struct class_attribute class_attr_##_name = __ATTR_RW(_name)
++#define CLASS_ATTR_RO(_name) \
++      struct class_attribute class_attr_##_name = __ATTR_RO(_name)
+ extern int __must_check class_create_file(struct class *class,
+                                         const struct class_attribute *attr);
+@@ -417,7 +428,6 @@ extern void class_remove_file(struct class *class,
+                             const struct class_attribute *attr);
+ /* Simple class attribute that is just a static string */
+-
+ struct class_attribute_string {
+       struct class_attribute attr;
+       char *str;
+@@ -506,6 +516,10 @@ ssize_t device_store_bool(struct device *dev, struct device_attribute *attr,
+ #define DEVICE_ATTR(_name, _mode, _show, _store) \
+       struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
++#define DEVICE_ATTR_RW(_name) \
++      struct device_attribute dev_attr_##_name = __ATTR_RW(_name)
++#define DEVICE_ATTR_RO(_name) \
++      struct device_attribute dev_attr_##_name = __ATTR_RO(_name)
+ #define DEVICE_ULONG_ATTR(_name, _mode, _var) \
+       struct dev_ext_attribute dev_attr_##_name = \
+               { __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1113-USB-gadget-audit-sysfs-attribute-permissions.patch b/patches.tizen/1113-USB-gadget-audit-sysfs-attribute-permissions.patch
new file mode 100644 (file)
index 0000000..560f5cd
--- /dev/null
@@ -0,0 +1,326 @@
+From 9b756fabc71063044959f7246cf6c5ffbcda8aeb Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Fri, 23 Aug 2013 16:34:43 -0700
+Subject: [PATCH 1113/1302] USB: gadget: audit sysfs attribute permissions
+
+Convert all USB gadget sysfs attributes to use the _RO or _RW variants,
+to make them easier to audit and ensure that the permissions are
+correct.
+
+Note, two are left using the DEVICE_ATTR() macro, as there is no
+DEVICE_ATTR_WO() in Linus's tree, that will happen after 3.12-rc1 is
+out, a follow-on patch will be sent then.
+
+Reviewed-by: Felipe Balbi <balbi@ti.com>
+Acked-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+--
+ drivers/usb/gadget/composite.c      |    8 +++-----
+ drivers/usb/gadget/dummy_hcd.c      |    8 ++++----
+ drivers/usb/gadget/f_mass_storage.c |   14 ++++++--------
+ drivers/usb/gadget/net2272.c        |    4 ++--
+ drivers/usb/gadget/net2280.c        |   18 +++++++++---------
+ drivers/usb/gadget/storage_common.c |   25 ++++++++++++-------------
+ drivers/usb/gadget/udc-core.c       |   14 +++++++-------
+ 7 files changed, 43 insertions(+), 48 deletions(-)
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/composite.c      |  8 +++-----
+ drivers/usb/gadget/dummy_hcd.c      |  8 ++++----
+ drivers/usb/gadget/f_mass_storage.c | 14 ++++++--------
+ drivers/usb/gadget/net2272.c        |  4 ++--
+ drivers/usb/gadget/net2280.c        | 18 +++++++++---------
+ drivers/usb/gadget/storage_common.c | 25 ++++++++++++-------------
+ drivers/usb/gadget/udc-core.c       | 14 +++++++-------
+ 7 files changed, 43 insertions(+), 48 deletions(-)
+
+diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
+index 55f4df6..d4f0f33 100644
+--- a/drivers/usb/gadget/composite.c
++++ b/drivers/usb/gadget/composite.c
+@@ -1497,17 +1497,15 @@ void composite_disconnect(struct usb_gadget *gadget)
+ /*-------------------------------------------------------------------------*/
+-static ssize_t composite_show_suspended(struct device *dev,
+-                                      struct device_attribute *attr,
+-                                      char *buf)
++static ssize_t suspended_show(struct device *dev, struct device_attribute *attr,
++                            char *buf)
+ {
+       struct usb_gadget *gadget = dev_to_usb_gadget(dev);
+       struct usb_composite_dev *cdev = get_gadget_data(gadget);
+       return sprintf(buf, "%d\n", cdev->suspended);
+ }
+-
+-static DEVICE_ATTR(suspended, 0444, composite_show_suspended, NULL);
++static DEVICE_ATTR_RO(suspended);
+ static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver)
+ {
+diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
+index ac0e79e..b8a2376 100644
+--- a/drivers/usb/gadget/dummy_hcd.c
++++ b/drivers/usb/gadget/dummy_hcd.c
+@@ -868,7 +868,7 @@ static const struct usb_gadget_ops dummy_ops = {
+ /*-------------------------------------------------------------------------*/
+ /* "function" sysfs attribute */
+-static ssize_t show_function(struct device *dev, struct device_attribute *attr,
++static ssize_t function_show(struct device *dev, struct device_attribute *attr,
+               char *buf)
+ {
+       struct dummy    *dum = gadget_dev_to_dummy(dev);
+@@ -877,7 +877,7 @@ static ssize_t show_function(struct device *dev, struct device_attribute *attr,
+               return 0;
+       return scnprintf(buf, PAGE_SIZE, "%s\n", dum->driver->function);
+ }
+-static DEVICE_ATTR(function, S_IRUGO, show_function, NULL);
++static DEVICE_ATTR_RO(function);
+ /*-------------------------------------------------------------------------*/
+@@ -2291,7 +2291,7 @@ static inline ssize_t show_urb(char *buf, size_t size, struct urb *urb)
+               urb->actual_length, urb->transfer_buffer_length);
+ }
+-static ssize_t show_urbs(struct device *dev, struct device_attribute *attr,
++static ssize_t urbs_show(struct device *dev, struct device_attribute *attr,
+               char *buf)
+ {
+       struct usb_hcd          *hcd = dev_get_drvdata(dev);
+@@ -2312,7 +2312,7 @@ static ssize_t show_urbs(struct device *dev, struct device_attribute *attr,
+       return size;
+ }
+-static DEVICE_ATTR(urbs, S_IRUGO, show_urbs, NULL);
++static DEVICE_ATTR_RO(urbs);
+ static int dummy_start_ss(struct dummy_hcd *dum_hcd)
+ {
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 4d4e96a..313b835 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -2578,14 +2578,12 @@ static int fsg_main_thread(void *common_)
+ /*************************** DEVICE ATTRIBUTES ***************************/
+-static DEVICE_ATTR(ro, 0644, fsg_show_ro, fsg_store_ro);
+-static DEVICE_ATTR(nofua, 0644, fsg_show_nofua, fsg_store_nofua);
+-static DEVICE_ATTR(file, 0644, fsg_show_file, fsg_store_file);
+-
+-static struct device_attribute dev_attr_ro_cdrom =
+-      __ATTR(ro, 0444, fsg_show_ro, NULL);
+-static struct device_attribute dev_attr_file_nonremovable =
+-      __ATTR(file, 0444, fsg_show_file, NULL);
++static DEVICE_ATTR_RW(ro);
++static DEVICE_ATTR_RW(nofua);
++static DEVICE_ATTR_RW(file);
++
++static struct device_attribute dev_attr_ro_cdrom = __ATTR_RO(ro);
++static struct device_attribute dev_attr_file_nonremovable = __ATTR_RO(file);
+ /****************************** FSG COMMON ******************************/
+diff --git a/drivers/usb/gadget/net2272.c b/drivers/usb/gadget/net2272.c
+index f1e50a3..bf2bb39 100644
+--- a/drivers/usb/gadget/net2272.c
++++ b/drivers/usb/gadget/net2272.c
+@@ -1184,7 +1184,7 @@ static const struct usb_gadget_ops net2272_ops = {
+ /*---------------------------------------------------------------------------*/
+ static ssize_t
+-net2272_show_registers(struct device *_dev, struct device_attribute *attr, char *buf)
++registers_show(struct device *_dev, struct device_attribute *attr, char *buf)
+ {
+       struct net2272 *dev;
+       char *next;
+@@ -1308,7 +1308,7 @@ net2272_show_registers(struct device *_dev, struct device_attribute *attr, char
+       return PAGE_SIZE - size;
+ }
+-static DEVICE_ATTR(registers, S_IRUGO, net2272_show_registers, NULL);
++static DEVICE_ATTR_RO(registers);
+ /*---------------------------------------------------------------------------*/
+diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
+index fbd006a..0781bff 100644
+--- a/drivers/usb/gadget/net2280.c
++++ b/drivers/usb/gadget/net2280.c
+@@ -1424,8 +1424,8 @@ static const struct usb_gadget_ops net2280_ops = {
+  */
+ /* "function" sysfs attribute */
+-static ssize_t
+-show_function (struct device *_dev, struct device_attribute *attr, char *buf)
++static ssize_t function_show(struct device *_dev, struct device_attribute *attr,
++                           char *buf)
+ {
+       struct net2280  *dev = dev_get_drvdata (_dev);
+@@ -1435,10 +1435,10 @@ show_function (struct device *_dev, struct device_attribute *attr, char *buf)
+               return 0;
+       return scnprintf (buf, PAGE_SIZE, "%s\n", dev->driver->function);
+ }
+-static DEVICE_ATTR (function, S_IRUGO, show_function, NULL);
++static DEVICE_ATTR_RO(function);
+-static ssize_t net2280_show_registers(struct device *_dev,
+-                              struct device_attribute *attr, char *buf)
++static ssize_t registers_show(struct device *_dev,
++                            struct device_attribute *attr, char *buf)
+ {
+       struct net2280          *dev;
+       char                    *next;
+@@ -1590,10 +1590,10 @@ static ssize_t net2280_show_registers(struct device *_dev,
+       return PAGE_SIZE - size;
+ }
+-static DEVICE_ATTR(registers, S_IRUGO, net2280_show_registers, NULL);
++static DEVICE_ATTR_RO(registers);
+-static ssize_t
+-show_queues (struct device *_dev, struct device_attribute *attr, char *buf)
++static ssize_t queues_show(struct device *_dev, struct device_attribute *attr,
++                         char *buf)
+ {
+       struct net2280          *dev;
+       char                    *next;
+@@ -1690,7 +1690,7 @@ done:
+       spin_unlock_irqrestore (&dev->lock, flags);
+       return PAGE_SIZE - size;
+ }
+-static DEVICE_ATTR (queues, S_IRUGO, show_queues, NULL);
++static DEVICE_ATTR_RO(queues);
+ #else
+diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
+index 8c71212..08a1a32 100644
+--- a/drivers/usb/gadget/storage_common.c
++++ b/drivers/usb/gadget/storage_common.c
+@@ -547,8 +547,8 @@ static void store_cdrom_address(u8 *dest, int msf, u32 addr)
+ /*-------------------------------------------------------------------------*/
+-static ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr,
+-                         char *buf)
++static ssize_t ro_show(struct device *dev, struct device_attribute *attr,
++                     char *buf)
+ {
+       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+@@ -557,16 +557,16 @@ static ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr,
+                                 : curlun->initially_ro);
+ }
+-static ssize_t fsg_show_nofua(struct device *dev, struct device_attribute *attr,
+-                            char *buf)
++static ssize_t nofua_show(struct device *dev, struct device_attribute *attr,
++                        char *buf)
+ {
+       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+       return sprintf(buf, "%u\n", curlun->nofua);
+ }
+-static ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
+-                           char *buf)
++static ssize_t file_show(struct device *dev, struct device_attribute *attr,
++                       char *buf)
+ {
+       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+       struct rw_semaphore     *filesem = dev_get_drvdata(dev);
+@@ -593,8 +593,8 @@ static ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
+ }
+-static ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr,
+-                          const char *buf, size_t count)
++static ssize_t ro_store(struct device *dev, struct device_attribute *attr,
++                      const char *buf, size_t count)
+ {
+       ssize_t         rc;
+       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+@@ -623,9 +623,8 @@ static ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr,
+       return rc;
+ }
+-static ssize_t fsg_store_nofua(struct device *dev,
+-                             struct device_attribute *attr,
+-                             const char *buf, size_t count)
++static ssize_t nofua_store(struct device *dev, struct device_attribute *attr,
++                         const char *buf, size_t count)
+ {
+       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+       unsigned        nofua;
+@@ -644,8 +643,8 @@ static ssize_t fsg_store_nofua(struct device *dev,
+       return count;
+ }
+-static ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr,
+-                            const char *buf, size_t count)
++static ssize_t file_store(struct device *dev, struct device_attribute *attr,
++                        const char *buf, size_t count)
+ {
+       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+       struct rw_semaphore     *filesem = dev_get_drvdata(dev);
+diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
+index dcaa5bf..b42edf1 100644
+--- a/drivers/usb/gadget/udc-core.c
++++ b/drivers/usb/gadget/udc-core.c
+@@ -539,31 +539,31 @@ static ssize_t usb_udc_softconn_store(struct device *dev,
+ }
+ static DEVICE_ATTR(soft_connect, S_IWUSR, NULL, usb_udc_softconn_store);
+-static ssize_t usb_gadget_state_show(struct device *dev,
+-              struct device_attribute *attr, char *buf)
++static ssize_t state_show(struct device *dev, struct device_attribute *attr,
++                        char *buf)
+ {
+       struct usb_udc          *udc = container_of(dev, struct usb_udc, dev);
+       struct usb_gadget       *gadget = udc->gadget;
+       return sprintf(buf, "%s\n", usb_state_string(gadget->state));
+ }
+-static DEVICE_ATTR(state, S_IRUGO, usb_gadget_state_show, NULL);
++static DEVICE_ATTR_RO(state);
+ #define USB_UDC_SPEED_ATTR(name, param)                                       \
+-ssize_t usb_udc_##param##_show(struct device *dev,                    \
++ssize_t name##_show(struct device *dev,                                       \
+               struct device_attribute *attr, char *buf)               \
+ {                                                                     \
+       struct usb_udc *udc = container_of(dev, struct usb_udc, dev);   \
+       return snprintf(buf, PAGE_SIZE, "%s\n",                         \
+                       usb_speed_string(udc->gadget->param));          \
+ }                                                                     \
+-static DEVICE_ATTR(name, S_IRUGO, usb_udc_##param##_show, NULL)
++static DEVICE_ATTR_RO(name)
+ static USB_UDC_SPEED_ATTR(current_speed, speed);
+ static USB_UDC_SPEED_ATTR(maximum_speed, max_speed);
+ #define USB_UDC_ATTR(name)                                    \
+-ssize_t usb_udc_##name##_show(struct device *dev,             \
++ssize_t name##_show(struct device *dev,                               \
+               struct device_attribute *attr, char *buf)       \
+ {                                                             \
+       struct usb_udc          *udc = container_of(dev, struct usb_udc, dev); \
+@@ -571,7 +571,7 @@ ssize_t usb_udc_##name##_show(struct device *dev,          \
+                                                               \
+       return snprintf(buf, PAGE_SIZE, "%d\n", gadget->name);  \
+ }                                                             \
+-static DEVICE_ATTR(name, S_IRUGO, usb_udc_##name##_show, NULL)
++static DEVICE_ATTR_RO(name)
+ static USB_UDC_ATTR(is_otg);
+ static USB_UDC_ATTR(is_a_peripheral);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1114-usb-gadget-gadgetfs-potential-use-after-free-in-unbi.patch b/patches.tizen/1114-usb-gadget-gadgetfs-potential-use-after-free-in-unbi.patch
new file mode 100644 (file)
index 0000000..0adbbb7
--- /dev/null
@@ -0,0 +1,33 @@
+From 9321f0d3e2813f0da32cf22d2e65402c42133252 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Fri, 23 Aug 2013 11:16:15 +0300
+Subject: [PATCH 1114/1302] usb: gadget: gadgetfs: potential use after free in
+ unbind()
+
+ffs_data_put() can sometimes free "ffs" so I have moved the call down
+a line below the dereference.
+
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_fs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
+index b6e9d91..0658908 100644
+--- a/drivers/usb/gadget/f_fs.c
++++ b/drivers/usb/gadget/f_fs.c
+@@ -1409,8 +1409,8 @@ static void functionfs_unbind(struct ffs_data *ffs)
+               usb_ep_free_request(ffs->gadget->ep0, ffs->ep0req);
+               ffs->ep0req = NULL;
+               ffs->gadget = NULL;
+-              ffs_data_put(ffs);
+               clear_bit(FFS_FL_BOUND, &ffs->flags);
++              ffs_data_put(ffs);
+       }
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1115-usb-gadget-add-__ref-for-rndis_config_register-and-c.patch b/patches.tizen/1115-usb-gadget-add-__ref-for-rndis_config_register-and-c.patch
new file mode 100644 (file)
index 0000000..9e88088
--- /dev/null
@@ -0,0 +1,73 @@
+From a6e0c8630d5258b67ec255fdfe3209d39936a80b Mon Sep 17 00:00:00 2001
+From: Chen Gang <gang.chen@asianux.com>
+Date: Mon, 2 Sep 2013 18:14:42 +0800
+Subject: [PATCH 1115/1302] usb: gadget: add '__ref' for
+ rndis_config_register() and cdc_config_register()
+
+They are only called by '__ref' function multi_bind(), and they will
+call '__init' functions, so recommend to let them '__ref' too.
+
+The related warnings:
+
+  WARNING: drivers/usb/gadget/g_multi.o(.text+0xded6): Section mismatch in reference from the variable .LM2921 to the variable .init.text:_rndis_do_config
+  The function .LM2921() references
+  the variable __init _rndis_do_config.
+  This is often because .LM2921 lacks a __init
+  annotation or the annotation of _rndis_do_config is wrong.
+
+  WARNING: drivers/usb/gadget/g_multi.o(.text+0xdf16): Section mismatch in reference from the variable .LM2953 to the variable .init.text:_cdc_do_config
+  The function .LM2953() references
+  the variable __init _cdc_do_config.
+  This is often because .LM2953 lacks a __init
+  annotation or the annotation of _cdc_do_config is wrong.
+
+Signed-off-by: Chen Gang <gang.chen@asianux.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/multi.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
+index 2a1ebef..23393254 100644
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -179,7 +179,7 @@ err_conf:
+       return ret;
+ }
+-static int rndis_config_register(struct usb_composite_dev *cdev)
++static __ref int rndis_config_register(struct usb_composite_dev *cdev)
+ {
+       static struct usb_configuration config = {
+               .bConfigurationValue    = MULTI_RNDIS_CONFIG_NUM,
+@@ -194,7 +194,7 @@ static int rndis_config_register(struct usb_composite_dev *cdev)
+ #else
+-static int rndis_config_register(struct usb_composite_dev *cdev)
++static __ref int rndis_config_register(struct usb_composite_dev *cdev)
+ {
+       return 0;
+ }
+@@ -241,7 +241,7 @@ err_conf:
+       return ret;
+ }
+-static int cdc_config_register(struct usb_composite_dev *cdev)
++static __ref int cdc_config_register(struct usb_composite_dev *cdev)
+ {
+       static struct usb_configuration config = {
+               .bConfigurationValue    = MULTI_CDC_CONFIG_NUM,
+@@ -256,7 +256,7 @@ static int cdc_config_register(struct usb_composite_dev *cdev)
+ #else
+-static int cdc_config_register(struct usb_composite_dev *cdev)
++static __ref int cdc_config_register(struct usb_composite_dev *cdev)
+ {
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1116-usb-gadget-f_ecm-Staticize-ecm_alloc.patch b/patches.tizen/1116-usb-gadget-f_ecm-Staticize-ecm_alloc.patch
new file mode 100644 (file)
index 0000000..1578e53
--- /dev/null
@@ -0,0 +1,30 @@
+From 82656ff98b6babda9920286aa72e2bc204c0455f Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Mon, 16 Sep 2013 11:44:45 +0530
+Subject: [PATCH 1116/1302] usb: gadget: f_ecm: Staticize ecm_alloc
+
+'ecm_alloc' is local to this file. Make it static.
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_ecm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c
+index edab45d..8d9e6f7 100644
+--- a/drivers/usb/gadget/f_ecm.c
++++ b/drivers/usb/gadget/f_ecm.c
+@@ -995,7 +995,7 @@ static void ecm_unbind(struct usb_configuration *c, struct usb_function *f)
+       usb_ep_free_request(ecm->notify, ecm->notify_req);
+ }
+-struct usb_function *ecm_alloc(struct usb_function_instance *fi)
++static struct usb_function *ecm_alloc(struct usb_function_instance *fi)
+ {
+       struct f_ecm    *ecm;
+       struct f_ecm_opts *opts;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1117-usb-gadget-f_eem-Staticize-eem_alloc.patch b/patches.tizen/1117-usb-gadget-f_eem-Staticize-eem_alloc.patch
new file mode 100644 (file)
index 0000000..a1b1986
--- /dev/null
@@ -0,0 +1,30 @@
+From c5d7596824754cc57f6f3c18a03e2edb1be39217 Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Mon, 16 Sep 2013 11:44:46 +0530
+Subject: [PATCH 1117/1302] usb: gadget: f_eem: Staticize eem_alloc
+
+'eem_alloc' is local to this file. Make it static.
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_eem.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c
+index d00392d..d61c11d 100644
+--- a/drivers/usb/gadget/f_eem.c
++++ b/drivers/usb/gadget/f_eem.c
+@@ -624,7 +624,7 @@ static void eem_unbind(struct usb_configuration *c, struct usb_function *f)
+       usb_free_all_descriptors(f);
+ }
+-struct usb_function *eem_alloc(struct usb_function_instance *fi)
++static struct usb_function *eem_alloc(struct usb_function_instance *fi)
+ {
+       struct f_eem    *eem;
+       struct f_eem_opts *opts;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1118-usb-gadget-f_mass_storage-reset-endpoint-driver-data.patch b/patches.tizen/1118-usb-gadget-f_mass_storage-reset-endpoint-driver-data.patch
new file mode 100644 (file)
index 0000000..a4d2784
--- /dev/null
@@ -0,0 +1,43 @@
+From b167f97efd2100612ff19393d99906c67799c880 Mon Sep 17 00:00:00 2001
+From: Peter Oh <poh@broadcom.com>
+Date: Mon, 16 Sep 2013 14:21:14 -0700
+Subject: [PATCH 1118/1302] usb: gadget: f_mass_storage: reset endpoint driver
+ data when disabled
+
+Gadgets endpoint driver data is a criteria to judge that
+whether the endpoints are in use or not. When gadget gets
+assigned an endpoint from endpoint list, they check its
+driver data if the driver data is NULL.
+
+If the driver data is not NULL then they regard it as in use.
+Therefore all of gadgets should reset their endpoints driver
+data to NULL as they are disabled. Otherwise it causes a leak
+of endpoint resource.
+
+Signed-off-by: Peter Oh <poh@broadcom.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 313b835..a01d7d3 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -2260,10 +2260,12 @@ reset:
+               /* Disable the endpoints */
+               if (fsg->bulk_in_enabled) {
+                       usb_ep_disable(fsg->bulk_in);
++                      fsg->bulk_in->driver_data = NULL;
+                       fsg->bulk_in_enabled = 0;
+               }
+               if (fsg->bulk_out_enabled) {
+                       usb_ep_disable(fsg->bulk_out);
++                      fsg->bulk_out->driver_data = NULL;
+                       fsg->bulk_out_enabled = 0;
+               }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1119-usb-g_ffs-fix-compilation-warning.patch b/patches.tizen/1119-usb-g_ffs-fix-compilation-warning.patch
new file mode 100644 (file)
index 0000000..f791700
--- /dev/null
@@ -0,0 +1,47 @@
+From 4e6e6fddf7fafde43a84200ff26f676e553b0769 Mon Sep 17 00:00:00 2001
+From: David Cohen <david.a.cohen@linux.intel.com>
+Date: Fri, 4 Oct 2013 15:30:21 -0700
+Subject: [PATCH 1119/1302] usb: g_ffs: fix compilation warning
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+If USB_FUNCTIONFS is selected without USB_FUNCTIONFS_ETH and
+USB_FUNCTIONFS_RNIS, u_ether.h won't be included and then
+USB_ETHERNET_MODULE_PARAMAETERS macro won't be available causing the
+following warning compilation:
+
+drivers/usb/gadget/g_ffs.c:81:1: warning: data definition has no type or
+storage class [enabled by default]
+drivers/usb/gadget/g_ffs.c:81:1: warning: type defaults to ‘int’ in
+declaration of ‘USB_ETHERNET_MODULE_PARAMETERS’ [-Wimplicit-int]
+drivers/usb/gadget/g_ffs.c:81:1: warning: function declaration isn’t a
+prototype [-Wstrict-prototypes]
+
+This patch fixes the warning by making USB_ETHERNET_MODULE_PARAMETERS to
+be used iff u_ether.h is included, otherwise it is not needed.
+
+Signed-off-by: David Cohen <david.a.cohen@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/g_ffs.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
+index 5327c82..2344efe 100644
+--- a/drivers/usb/gadget/g_ffs.c
++++ b/drivers/usb/gadget/g_ffs.c
+@@ -76,7 +76,9 @@ struct gfs_ffs_obj {
+ USB_GADGET_COMPOSITE_OPTIONS();
++#if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS
+ USB_ETHERNET_MODULE_PARAMETERS();
++#endif
+ static struct usb_device_descriptor gfs_dev_desc = {
+       .bLength                = sizeof gfs_dev_desc,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1120-usb-gadget-f_fs-fix-error-handling.patch b/patches.tizen/1120-usb-gadget-f_fs-fix-error-handling.patch
new file mode 100644 (file)
index 0000000..c68422f
--- /dev/null
@@ -0,0 +1,36 @@
+From 1032c128dc58fa12cc0e23c0f73754e2b1845306 Mon Sep 17 00:00:00 2001
+From: Robert Baldyga <r.baldyga@samsung.com>
+Date: Fri, 27 Sep 2013 12:28:54 +0200
+Subject: [PATCH 1120/1302] usb: gadget: f_fs: fix error handling
+
+This patch add missing error check in ffs_func_bind() function, after
+ffs_do_descs() function call for high speed descriptors. Without this
+check it's possible that the module will try dereference incorrect
+pointer.
+
+[ balbi@ti.com : removed trailing empty line ]
+
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Robert Baldyga <r.baldyga@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_fs.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
+index 0658908..44cf775 100644
+--- a/drivers/usb/gadget/f_fs.c
++++ b/drivers/usb/gadget/f_fs.c
+@@ -2256,6 +2256,8 @@ static int ffs_func_bind(struct usb_configuration *c,
+                                  data->raw_descs + ret,
+                                  (sizeof data->raw_descs) - ret,
+                                  __ffs_func_bind_do_descs, func);
++              if (unlikely(ret < 0))
++                      goto error;
+       }
+       /*
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1121-usb-gadget-zero-Add-flexible-auto-remote-wakeup-test.patch b/patches.tizen/1121-usb-gadget-zero-Add-flexible-auto-remote-wakeup-test.patch
new file mode 100644 (file)
index 0000000..5ae74b1
--- /dev/null
@@ -0,0 +1,71 @@
+From 2782a4b2b0decfbc7246bf1fe77331bebe88bc62 Mon Sep 17 00:00:00 2001
+From: Peter Chen <peter.chen@freescale.com>
+Date: Mon, 9 Sep 2013 16:48:29 +0800
+Subject: [PATCH 1121/1302] usb: gadget: zero: Add flexible auto remote wakeup
+ test method
+
+In order to increase test coverage, we can change the interval between
+two remote wakeups every time, and the interval can be any user defined
+value. This change will no affect current behavior if the user does not
+use two introduced module paramters.
+
+Signed-off-by: Peter Chen <peter.chen@freescale.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/zero.c | 25 +++++++++++++++++++++++--
+ 1 file changed, 23 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
+index 0deb9d6..0dd07ae 100644
+--- a/drivers/usb/gadget/zero.c
++++ b/drivers/usb/gadget/zero.c
+@@ -95,6 +95,18 @@ unsigned autoresume = DEFAULT_AUTORESUME;
+ module_param(autoresume, uint, S_IRUGO);
+ MODULE_PARM_DESC(autoresume, "zero, or seconds before remote wakeup");
++/* Maximum Autoresume time */
++unsigned max_autoresume;
++module_param(max_autoresume, uint, S_IRUGO);
++MODULE_PARM_DESC(max_autoresume, "maximum seconds before remote wakeup");
++
++/* Interval between two remote wakeups */
++unsigned autoresume_interval_ms;
++module_param(autoresume_interval_ms, uint, S_IRUGO);
++MODULE_PARM_DESC(autoresume_interval_ms,
++              "milliseconds to increase successive wakeup delays");
++
++static unsigned autoresume_step_ms;
+ /*-------------------------------------------------------------------------*/
+ static struct usb_device_descriptor device_desc = {
+@@ -183,8 +195,16 @@ static void zero_suspend(struct usb_composite_dev *cdev)
+               return;
+       if (autoresume) {
+-              mod_timer(&autoresume_timer, jiffies + (HZ * autoresume));
+-              DBG(cdev, "suspend, wakeup in %d seconds\n", autoresume);
++              if (max_autoresume &&
++                      (autoresume_step_ms > max_autoresume * 1000))
++                              autoresume_step_ms = autoresume * 1000;
++
++              mod_timer(&autoresume_timer, jiffies +
++                      msecs_to_jiffies(autoresume_step_ms));
++              DBG(cdev, "suspend, wakeup in %d milliseconds\n",
++                      autoresume_step_ms);
++
++              autoresume_step_ms += autoresume_interval_ms;
+       } else
+               DBG(cdev, "%s\n", __func__);
+ }
+@@ -316,6 +336,7 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
+       if (autoresume) {
+               sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+               loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
++              autoresume_step_ms = autoresume * 1000;
+       }
+       /* support OTG systems */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1122-usb-gadget-Use-ERR_CAST-inlined-function-instead-of-.patch b/patches.tizen/1122-usb-gadget-Use-ERR_CAST-inlined-function-instead-of-.patch
new file mode 100644 (file)
index 0000000..dc2cc03
--- /dev/null
@@ -0,0 +1,32 @@
+From 48e124d11ca66af97c83d77ad66fdccccc220099 Mon Sep 17 00:00:00 2001
+From: Duan Jiong <duanj.fnst@cn.fujitsu.com>
+Date: Thu, 26 Sep 2013 15:55:25 +0800
+Subject: [PATCH 1122/1302] usb: gadget: Use ERR_CAST inlined function instead
+ of ERR_PTR(PTR_ERR(...))
+
+trivial patch converting ERR_PTR(PTR_ERR()) into ERR_CAST().
+No functional changes.
+
+Signed-off-by: Duan Jiong <duanj.fnst@cn.fujitsu.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/configfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
+index 37e475b..2588511 100644
+--- a/drivers/usb/gadget/configfs.c
++++ b/drivers/usb/gadget/configfs.c
+@@ -557,7 +557,7 @@ static struct config_group *function_make(
+       fi = usb_get_function_instance(func_name);
+       if (IS_ERR(fi))
+-              return ERR_PTR(PTR_ERR(fi));
++              return ERR_CAST(fi);
+       ret = config_item_set_name(&fi->group.cg_item, name);
+       if (ret) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1123-usb-gadget-create-a-utility-module-for-mass_storage.patch b/patches.tizen/1123-usb-gadget-create-a-utility-module-for-mass_storage.patch
new file mode 100644 (file)
index 0000000..41872c9
--- /dev/null
@@ -0,0 +1,1216 @@
+From 88318ec7e04239395ae5e32604b3754f733eb97b Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 26 Sep 2013 14:38:16 +0200
+Subject: [PATCH 1123/1302] usb: gadget: create a utility module for
+ mass_storage
+
+Converting to configfs requires making the f_mass_storage.c a module.
+
+But first we need to get rid of "#include "storage_common.c".
+
+This patch makes storage_common.c a separately compiled file, which is
+built as a utility module named u_ms.ko. After all mass storage users are
+converted to the new function interface this module can be eliminated
+by merging it with the mass storage function's module.
+
+USB descriptors are exported so that they can be accessed from
+f_mass_storage.
+
+FSG_VENDOR_ID and FSG_PRODUCT_ID are moved to their only user.
+
+Handling of CONFIG_USB_GADGET_DEBUG_FILES is moved to f_mass_storage.c.
+The fsg_num_buffers static is moved to FSG_MODULE_PARAMETER users, so
+instead of using a global variable the f_mass_storage introduces
+fsg_num_buffers member in fsg_common (and fsg_config).
+
+fsg_strings and fsg_stringtab are moved to f_mass_storage.c.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig          |   6 +
+ drivers/usb/gadget/Makefile         |   2 +
+ drivers/usb/gadget/acm_ms.c         |  17 +-
+ drivers/usb/gadget/f_mass_storage.c | 106 ++++++++++--
+ drivers/usb/gadget/mass_storage.c   |  25 ++-
+ drivers/usb/gadget/multi.c          |  17 +-
+ drivers/usb/gadget/storage_common.c | 331 +++++++-----------------------------
+ drivers/usb/gadget/storage_common.h | 210 +++++++++++++++++++++++
+ 8 files changed, 423 insertions(+), 291 deletions(-)
+ create mode 100644 drivers/usb/gadget/storage_common.h
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 8205354..ecfcbab 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -537,6 +537,9 @@ config USB_F_SUBSET
+ config USB_F_RNDIS
+       tristate
++config USB_U_MS
++      tristate
++
+ choice
+       tristate "USB Gadget Drivers"
+       default USB_ETH
+@@ -890,6 +893,7 @@ config USB_MASS_STORAGE
+       tristate "Mass Storage Gadget"
+       depends on BLOCK
+       select USB_LIBCOMPOSITE
++      select USB_U_MS
+       help
+         The Mass Storage Gadget acts as a USB Mass Storage disk drive.
+         As its storage repository it can use a regular file or a block
+@@ -1025,6 +1029,7 @@ config USB_G_ACM_MS
+       select USB_LIBCOMPOSITE
+       select USB_U_SERIAL
+       select USB_F_ACM
++      select USB_U_MS
+       help
+         This driver provides two functions in one configuration:
+         a mass storage, and a CDC ACM (serial port) link.
+@@ -1041,6 +1046,7 @@ config USB_G_MULTI
+       select USB_U_ETHER
+       select USB_U_RNDIS
+       select USB_F_ACM
++      select USB_U_MS
+       help
+         The Multifunction Composite Gadget provides Ethernet (RNDIS
+         and/or CDC Ethernet), mass storage and ACM serial link
+diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
+index 0becdfa..295df78 100644
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -60,6 +60,8 @@ usb_f_ecm_subset-y           := f_subset.o
+ obj-$(CONFIG_USB_F_SUBSET)    += usb_f_ecm_subset.o
+ usb_f_rndis-y                 := f_rndis.o
+ obj-$(CONFIG_USB_F_RNDIS)     += usb_f_rndis.o
++u_ms-y                                := storage_common.o
++obj-$(CONFIG_USB_U_MS)                += u_ms.o
+ #
+ # USB gadget drivers
+diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c
+index 4b947bb..992ffb0 100644
+--- a/drivers/usb/gadget/acm_ms.c
++++ b/drivers/usb/gadget/acm_ms.c
+@@ -104,6 +104,20 @@ static struct usb_gadget_strings *dev_strings[] = {
+ /****************************** Configurations ******************************/
+ static struct fsg_module_parameters fsg_mod_data = { .stall = 1 };
++#ifdef CONFIG_USB_GADGET_DEBUG_FILES
++
++static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
++
++#else
++
++/*
++ * Number of buffers we will use.
++ * 2 is usually enough for good buffering pipeline
++ */
++#define fsg_num_buffers       CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
++
++#endif /* CONFIG_USB_DEBUG */
++
+ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
+ static struct fsg_common fsg_common;
+@@ -167,7 +181,8 @@ static int __init acm_ms_bind(struct usb_composite_dev *cdev)
+       void                    *retp;
+       /* set up mass storage function */
+-      retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data);
++      retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data,
++                                    fsg_num_buffers);
+       if (IS_ERR(retp)) {
+               status = PTR_ERR(retp);
+               return PTR_ERR(retp);
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index a01d7d3..def3426 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -228,8 +228,18 @@
+ static const char fsg_string_interface[] = "Mass Storage";
+-#include "storage_common.c"
++#include "storage_common.h"
++/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
++static struct usb_string              fsg_strings[] = {
++      {FSG_STRING_INTERFACE,          fsg_string_interface},
++      {}
++};
++
++static struct usb_gadget_strings      fsg_stringtab = {
++      .language       = 0x0409,               /* en-us */
++      .strings        = fsg_strings,
++};
+ /*-------------------------------------------------------------------------*/
+@@ -268,6 +278,7 @@ struct fsg_common {
+       struct fsg_buffhd       *next_buffhd_to_fill;
+       struct fsg_buffhd       *next_buffhd_to_drain;
+       struct fsg_buffhd       *buffhds;
++      unsigned int            fsg_num_buffers;
+       int                     cmnd_size;
+       u8                      cmnd[MAX_COMMAND_SIZE];
+@@ -332,6 +343,7 @@ struct fsg_config {
+       const char *product_name;               /* 16 characters or less */
+       char                    can_stall;
++      unsigned int            fsg_num_buffers;
+ };
+ struct fsg_dev {
+@@ -2244,7 +2256,7 @@ reset:
+       if (common->fsg) {
+               fsg = common->fsg;
+-              for (i = 0; i < fsg_num_buffers; ++i) {
++              for (i = 0; i < common->fsg_num_buffers; ++i) {
+                       struct fsg_buffhd *bh = &common->buffhds[i];
+                       if (bh->inreq) {
+@@ -2303,7 +2315,7 @@ reset:
+       clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
+       /* Allocate the requests */
+-      for (i = 0; i < fsg_num_buffers; ++i) {
++      for (i = 0; i < common->fsg_num_buffers; ++i) {
+               struct fsg_buffhd       *bh = &common->buffhds[i];
+               rc = alloc_request(common, fsg->bulk_in, &bh->inreq);
+@@ -2372,7 +2384,7 @@ static void handle_exception(struct fsg_common *common)
+       /* Cancel all the pending transfers */
+       if (likely(common->fsg)) {
+-              for (i = 0; i < fsg_num_buffers; ++i) {
++              for (i = 0; i < common->fsg_num_buffers; ++i) {
+                       bh = &common->buffhds[i];
+                       if (bh->inreq_busy)
+                               usb_ep_dequeue(common->fsg->bulk_in, bh->inreq);
+@@ -2384,7 +2396,7 @@ static void handle_exception(struct fsg_common *common)
+               /* Wait until everything is idle */
+               for (;;) {
+                       int num_active = 0;
+-                      for (i = 0; i < fsg_num_buffers; ++i) {
++                      for (i = 0; i < common->fsg_num_buffers; ++i) {
+                               bh = &common->buffhds[i];
+                               num_active += bh->inreq_busy + bh->outreq_busy;
+                       }
+@@ -2407,7 +2419,7 @@ static void handle_exception(struct fsg_common *common)
+        */
+       spin_lock_irq(&common->lock);
+-      for (i = 0; i < fsg_num_buffers; ++i) {
++      for (i = 0; i < common->fsg_num_buffers; ++i) {
+               bh = &common->buffhds[i];
+               bh->state = BUF_STATE_EMPTY;
+       }
+@@ -2580,6 +2592,41 @@ static int fsg_main_thread(void *common_)
+ /*************************** DEVICE ATTRIBUTES ***************************/
++static ssize_t ro_show(struct device *dev, struct device_attribute *attr, char *buf)
++{
++      return fsg_show_ro(dev, attr, buf);
++}
++
++static ssize_t nofua_show(struct device *dev, struct device_attribute *attr,
++                        char *buf)
++{
++      return fsg_show_nofua(dev, attr, buf);
++}
++
++static ssize_t file_show(struct device *dev, struct device_attribute *attr,
++                       char *buf)
++{
++      return fsg_show_file(dev, attr, buf);
++}
++
++static ssize_t ro_store(struct device *dev, struct device_attribute *attr,
++                      const char *buf, size_t count)
++{
++      return fsg_store_ro(dev, attr, buf, count);
++}
++
++static ssize_t nofua_store(struct device *dev, struct device_attribute *attr,
++                         const char *buf, size_t count)
++{
++      return fsg_store_nofua(dev, attr, buf, count);
++}
++
++static ssize_t file_store(struct device *dev, struct device_attribute *attr,
++                        const char *buf, size_t count)
++{
++      return fsg_store_file(dev, attr, buf, count);
++}
++
+ static DEVICE_ATTR_RW(ro);
+ static DEVICE_ATTR_RW(nofua);
+ static DEVICE_ATTR_RW(file);
+@@ -2607,6 +2654,16 @@ static inline void fsg_common_put(struct fsg_common *common)
+       kref_put(&common->ref, fsg_common_release);
+ }
++/* check if fsg_num_buffers is within a valid range */
++static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
++{
++      if (fsg_num_buffers >= 2 && fsg_num_buffers <= 4)
++              return 0;
++      pr_err("fsg_num_buffers %u is out of range (%d to %d)\n",
++             fsg_num_buffers, 2, 4);
++      return -EINVAL;
++}
++
+ static struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                         struct usb_composite_dev *cdev,
+                                         struct fsg_config *cfg)
+@@ -2618,7 +2675,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
+       int nluns, i, rc;
+       char *pathbuf;
+-      rc = fsg_num_buffers_validate();
++      rc = fsg_num_buffers_validate(cfg->fsg_num_buffers);
+       if (rc != 0)
+               return ERR_PTR(rc);
+@@ -2640,7 +2697,8 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
+               common->free_storage_on_release = 0;
+       }
+-      common->buffhds = kcalloc(fsg_num_buffers,
++      common->fsg_num_buffers = cfg->fsg_num_buffers;
++      common->buffhds = kcalloc(common->fsg_num_buffers,
+                                 sizeof *(common->buffhds), GFP_KERNEL);
+       if (!common->buffhds) {
+               if (common->free_storage_on_release)
+@@ -2727,7 +2785,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
+       /* Data buffers cyclic list */
+       bh = common->buffhds;
+-      i = fsg_num_buffers;
++      i = common->fsg_num_buffers;
+       goto buffhds_first_it;
+       do {
+               bh->next = bh + 1;
+@@ -2847,7 +2905,7 @@ static void fsg_common_release(struct kref *ref)
+       {
+               struct fsg_buffhd *bh = common->buffhds;
+-              unsigned i = fsg_num_buffers;
++              unsigned i = common->fsg_num_buffers;
+               do {
+                       kfree(bh->buf);
+               } while (++bh, --i);
+@@ -3009,7 +3067,7 @@ struct fsg_module_parameters {
+                          S_IRUGO);                                    \
+       MODULE_PARM_DESC(prefix ## name, desc)
+-#define FSG_MODULE_PARAMETERS(prefix, params)                         \
++#define __FSG_MODULE_PARAMETERS(prefix, params)                               \
+       _FSG_MODULE_PARAM_ARRAY(prefix, params, file, charp,            \
+                               "names of backing files or devices");   \
+       _FSG_MODULE_PARAM_ARRAY(prefix, params, ro, bool,               \
+@@ -3025,9 +3083,24 @@ struct fsg_module_parameters {
+       _FSG_MODULE_PARAM(prefix, params, stall, bool,                  \
+                         "false to prevent bulk stalls")
++#ifdef CONFIG_USB_GADGET_DEBUG_FILES
++
++#define FSG_MODULE_PARAMETERS(prefix, params)                         \
++      __FSG_MODULE_PARAMETERS(prefix, params);                        \
++      module_param_named(num_buffers, fsg_num_buffers, uint, S_IRUGO);\
++      MODULE_PARM_DESC(num_buffers, "Number of pipeline buffers")
++#else
++
++#define FSG_MODULE_PARAMETERS(prefix, params)                         \
++      __FSG_MODULE_PARAMETERS(prefix, params)
++
++#endif
++
++
+ static void
+ fsg_config_from_params(struct fsg_config *cfg,
+-                     const struct fsg_module_parameters *params)
++                     const struct fsg_module_parameters *params,
++                     unsigned int fsg_num_buffers)
+ {
+       struct fsg_lun_config *lun;
+       unsigned i;
+@@ -3055,19 +3128,22 @@ fsg_config_from_params(struct fsg_config *cfg,
+       /* Finalise */
+       cfg->can_stall = params->stall;
++      cfg->fsg_num_buffers = fsg_num_buffers;
+ }
+ static inline struct fsg_common *
+ fsg_common_from_params(struct fsg_common *common,
+                      struct usb_composite_dev *cdev,
+-                     const struct fsg_module_parameters *params)
++                     const struct fsg_module_parameters *params,
++                     unsigned int fsg_num_buffers)
+       __attribute__((unused));
+ static inline struct fsg_common *
+ fsg_common_from_params(struct fsg_common *common,
+                      struct usb_composite_dev *cdev,
+-                     const struct fsg_module_parameters *params)
++                     const struct fsg_module_parameters *params,
++                     unsigned int fsg_num_buffers)
+ {
+       struct fsg_config cfg;
+-      fsg_config_from_params(&cfg, params);
++      fsg_config_from_params(&cfg, params, fsg_num_buffers);
+       return fsg_common_init(common, cdev, &cfg);
+ }
+diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c
+index 080e577..4723d1b 100644
+--- a/drivers/usb/gadget/mass_storage.c
++++ b/drivers/usb/gadget/mass_storage.c
+@@ -37,6 +37,15 @@
+ #define DRIVER_DESC           "Mass Storage Gadget"
+ #define DRIVER_VERSION                "2009/09/11"
++/*
++ * Thanks to NetChip Technologies for donating this product ID.
++ *
++ * DO NOT REUSE THESE IDs with any other driver!!  Ever!!
++ * Instead:  allocate your own, using normal USB-IF procedures.
++ */
++#define FSG_VENDOR_ID 0x0525  /* NetChip */
++#define FSG_PRODUCT_ID        0xa4a5  /* Linux-USB File-backed Storage Gadget */
++
+ /*-------------------------------------------------------------------------*/
+ /*
+@@ -102,6 +111,20 @@ static struct usb_gadget_strings *dev_strings[] = {
+ static struct fsg_module_parameters mod_data = {
+       .stall = 1
+ };
++#ifdef CONFIG_USB_GADGET_DEBUG_FILES
++
++static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
++
++#else
++
++/*
++ * Number of buffers we will use.
++ * 2 is usually enough for good buffering pipeline
++ */
++#define fsg_num_buffers       CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
++
++#endif /* CONFIG_USB_GADGET_DEBUG_FILES */
++
+ FSG_MODULE_PARAMETERS(/* no prefix */, mod_data);
+ static unsigned long msg_registered;
+@@ -129,7 +152,7 @@ static int __init msg_do_config(struct usb_configuration *c)
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+-      fsg_config_from_params(&config, &mod_data);
++      fsg_config_from_params(&config, &mod_data, fsg_num_buffers);
+       config.ops = &ops;
+       retp = fsg_common_init(&common, c->cdev, &config);
+diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
+index 23393254..6867d9d 100644
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -132,6 +132,20 @@ static struct usb_gadget_strings *dev_strings[] = {
+ /****************************** Configurations ******************************/
+ static struct fsg_module_parameters fsg_mod_data = { .stall = 1 };
++#ifdef CONFIG_USB_GADGET_DEBUG_FILES
++
++static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
++
++#else
++
++/*
++ * Number of buffers we will use.
++ * 2 is usually enough for good buffering pipeline
++ */
++#define fsg_num_buffers       CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
++
++#endif /* CONFIG_USB_DEBUG */
++
+ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
+ static struct fsg_common fsg_common;
+@@ -294,7 +308,8 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
+       /* set up mass storage function */
+       {
+               void *retp;
+-              retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data);
++              retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data,
++                                            fsg_num_buffers);
+               if (IS_ERR(retp)) {
+                       status = PTR_ERR(retp);
+                       goto fail1;
+diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
+index 08a1a32..3e2500f 100644
+--- a/drivers/usb/gadget/storage_common.c
++++ b/drivers/usb/gadget/storage_common.c
+@@ -23,242 +23,22 @@
+  * The valid range of num_buffers is: num >= 2 && num <= 4.
+  */
++#include <linux/module.h>
++#include <linux/blkdev.h>
++#include <linux/file.h>
++#include <linux/fs.h>
++#include <linux/usb/composite.h>
+-#include <linux/usb/storage.h>
+-#include <scsi/scsi.h>
+-#include <asm/unaligned.h>
+-
+-
+-/*
+- * Thanks to NetChip Technologies for donating this product ID.
+- *
+- * DO NOT REUSE THESE IDs with any other driver!!  Ever!!
+- * Instead:  allocate your own, using normal USB-IF procedures.
+- */
+-#define FSG_VENDOR_ID 0x0525  /* NetChip */
+-#define FSG_PRODUCT_ID        0xa4a5  /* Linux-USB File-backed Storage Gadget */
+-
+-
+-/*-------------------------------------------------------------------------*/
+-
+-
+-#ifndef DEBUG
+-#undef VERBOSE_DEBUG
+-#undef DUMP_MSGS
+-#endif /* !DEBUG */
+-
+-#ifdef VERBOSE_DEBUG
+-#define VLDBG LDBG
+-#else
+-#define VLDBG(lun, fmt, args...) do { } while (0)
+-#endif /* VERBOSE_DEBUG */
+-
+-#define LDBG(lun, fmt, args...)   dev_dbg (&(lun)->dev, fmt, ## args)
+-#define LERROR(lun, fmt, args...) dev_err (&(lun)->dev, fmt, ## args)
+-#define LWARN(lun, fmt, args...)  dev_warn(&(lun)->dev, fmt, ## args)
+-#define LINFO(lun, fmt, args...)  dev_info(&(lun)->dev, fmt, ## args)
+-
+-
+-#ifdef DUMP_MSGS
+-
+-#  define dump_msg(fsg, /* const char * */ label,                     \
+-                 /* const u8 * */ buf, /* unsigned */ length) do {    \
+-      if (length < 512) {                                             \
+-              DBG(fsg, "%s, length %u:\n", label, length);            \
+-              print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET,      \
+-                             16, 1, buf, length, 0);                  \
+-      }                                                               \
+-} while (0)
+-
+-#  define dump_cdb(fsg) do { } while (0)
+-
+-#else
+-
+-#  define dump_msg(fsg, /* const char * */ label, \
+-                 /* const u8 * */ buf, /* unsigned */ length) do { } while (0)
+-
+-#  ifdef VERBOSE_DEBUG
+-
+-#    define dump_cdb(fsg)                                             \
+-      print_hex_dump(KERN_DEBUG, "SCSI CDB: ", DUMP_PREFIX_NONE,      \
+-                     16, 1, (fsg)->cmnd, (fsg)->cmnd_size, 0)         \
+-
+-#  else
+-
+-#    define dump_cdb(fsg) do { } while (0)
+-
+-#  endif /* VERBOSE_DEBUG */
+-
+-#endif /* DUMP_MSGS */
+-
+-/*-------------------------------------------------------------------------*/
+-
+-/* Length of a SCSI Command Data Block */
+-#define MAX_COMMAND_SIZE      16
+-
+-/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */
+-#define SS_NO_SENSE                           0
+-#define SS_COMMUNICATION_FAILURE              0x040800
+-#define SS_INVALID_COMMAND                    0x052000
+-#define SS_INVALID_FIELD_IN_CDB                       0x052400
+-#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x052100
+-#define SS_LOGICAL_UNIT_NOT_SUPPORTED         0x052500
+-#define SS_MEDIUM_NOT_PRESENT                 0x023a00
+-#define SS_MEDIUM_REMOVAL_PREVENTED           0x055302
+-#define SS_NOT_READY_TO_READY_TRANSITION      0x062800
+-#define SS_RESET_OCCURRED                     0x062900
+-#define SS_SAVING_PARAMETERS_NOT_SUPPORTED    0x053900
+-#define SS_UNRECOVERED_READ_ERROR             0x031100
+-#define SS_WRITE_ERROR                                0x030c02
+-#define SS_WRITE_PROTECTED                    0x072700
+-
+-#define SK(x)         ((u8) ((x) >> 16))      /* Sense Key byte, etc. */
+-#define ASC(x)                ((u8) ((x) >> 8))
+-#define ASCQ(x)               ((u8) (x))
+-
+-
+-/*-------------------------------------------------------------------------*/
+-
+-
+-struct fsg_lun {
+-      struct file     *filp;
+-      loff_t          file_length;
+-      loff_t          num_sectors;
+-
+-      unsigned int    initially_ro:1;
+-      unsigned int    ro:1;
+-      unsigned int    removable:1;
+-      unsigned int    cdrom:1;
+-      unsigned int    prevent_medium_removal:1;
+-      unsigned int    registered:1;
+-      unsigned int    info_valid:1;
+-      unsigned int    nofua:1;
+-
+-      u32             sense_data;
+-      u32             sense_data_info;
+-      u32             unit_attention_data;
+-
+-      unsigned int    blkbits;        /* Bits of logical block size of bound block device */
+-      unsigned int    blksize;        /* logical block size of bound block device */
+-      struct device   dev;
+-};
+-
+-static inline bool fsg_lun_is_open(struct fsg_lun *curlun)
+-{
+-      return curlun->filp != NULL;
+-}
++#include "storage_common.h"
+ static inline struct fsg_lun *fsg_lun_from_dev(struct device *dev)
+ {
+       return container_of(dev, struct fsg_lun, dev);
+ }
+-
+-/* Big enough to hold our biggest descriptor */
+-#define EP0_BUFSIZE   256
+-#define DELAYED_STATUS        (EP0_BUFSIZE + 999)     /* An impossibly large value */
+-
+-#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+-
+-static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
+-module_param_named(num_buffers, fsg_num_buffers, uint, S_IRUGO);
+-MODULE_PARM_DESC(num_buffers, "Number of pipeline buffers");
+-
+-#else
+-
+-/*
+- * Number of buffers we will use.
+- * 2 is usually enough for good buffering pipeline
+- */
+-#define fsg_num_buffers       CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
+-
+-#endif /* CONFIG_USB_GADGET_DEBUG_FILES */
+-
+-/* check if fsg_num_buffers is within a valid range */
+-static inline int fsg_num_buffers_validate(void)
+-{
+-      if (fsg_num_buffers >= 2 && fsg_num_buffers <= 4)
+-              return 0;
+-      pr_err("fsg_num_buffers %u is out of range (%d to %d)\n",
+-             fsg_num_buffers, 2 ,4);
+-      return -EINVAL;
+-}
+-
+-/* Default size of buffer length. */
+-#define FSG_BUFLEN    ((u32)16384)
+-
+-/* Maximal number of LUNs supported in mass storage function */
+-#define FSG_MAX_LUNS  8
+-
+-enum fsg_buffer_state {
+-      BUF_STATE_EMPTY = 0,
+-      BUF_STATE_FULL,
+-      BUF_STATE_BUSY
+-};
+-
+-struct fsg_buffhd {
+-      void                            *buf;
+-      enum fsg_buffer_state           state;
+-      struct fsg_buffhd               *next;
+-
+-      /*
+-       * The NetChip 2280 is faster, and handles some protocol faults
+-       * better, if we don't submit any short bulk-out read requests.
+-       * So we will record the intended request length here.
+-       */
+-      unsigned int                    bulk_out_intended_length;
+-
+-      struct usb_request              *inreq;
+-      int                             inreq_busy;
+-      struct usb_request              *outreq;
+-      int                             outreq_busy;
+-};
+-
+-enum fsg_state {
+-      /* This one isn't used anywhere */
+-      FSG_STATE_COMMAND_PHASE = -10,
+-      FSG_STATE_DATA_PHASE,
+-      FSG_STATE_STATUS_PHASE,
+-
+-      FSG_STATE_IDLE = 0,
+-      FSG_STATE_ABORT_BULK_OUT,
+-      FSG_STATE_RESET,
+-      FSG_STATE_INTERFACE_CHANGE,
+-      FSG_STATE_CONFIG_CHANGE,
+-      FSG_STATE_DISCONNECT,
+-      FSG_STATE_EXIT,
+-      FSG_STATE_TERMINATED
+-};
+-
+-enum data_direction {
+-      DATA_DIR_UNKNOWN = 0,
+-      DATA_DIR_FROM_HOST,
+-      DATA_DIR_TO_HOST,
+-      DATA_DIR_NONE
+-};
+-
+-
+-/*-------------------------------------------------------------------------*/
+-
+-
+-static inline u32 get_unaligned_be24(u8 *buf)
+-{
+-      return 0xffffff & (u32) get_unaligned_be32(buf - 1);
+-}
+-
+-
+-/*-------------------------------------------------------------------------*/
+-
+-
+-enum {
+-      FSG_STRING_INTERFACE
+-};
+-
+-
+ /* There is only one interface. */
+-static struct usb_interface_descriptor
+-fsg_intf_desc = {
++struct usb_interface_descriptor fsg_intf_desc = {
+       .bLength =              sizeof fsg_intf_desc,
+       .bDescriptorType =      USB_DT_INTERFACE,
+@@ -268,14 +48,14 @@ fsg_intf_desc = {
+       .bInterfaceProtocol =   USB_PR_BULK,    /* Adjusted during fsg_bind() */
+       .iInterface =           FSG_STRING_INTERFACE,
+ };
++EXPORT_SYMBOL(fsg_intf_desc);
+ /*
+  * Three full-speed endpoint descriptors: bulk-in, bulk-out, and
+  * interrupt-in.
+  */
+-static struct usb_endpoint_descriptor
+-fsg_fs_bulk_in_desc = {
++struct usb_endpoint_descriptor fsg_fs_bulk_in_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -283,9 +63,9 @@ fsg_fs_bulk_in_desc = {
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       /* wMaxPacketSize set by autoconfiguration */
+ };
++EXPORT_SYMBOL(fsg_fs_bulk_in_desc);
+-static struct usb_endpoint_descriptor
+-fsg_fs_bulk_out_desc = {
++struct usb_endpoint_descriptor fsg_fs_bulk_out_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -293,13 +73,15 @@ fsg_fs_bulk_out_desc = {
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       /* wMaxPacketSize set by autoconfiguration */
+ };
++EXPORT_SYMBOL(fsg_fs_bulk_out_desc);
+-static struct usb_descriptor_header *fsg_fs_function[] = {
++struct usb_descriptor_header *fsg_fs_function[] = {
+       (struct usb_descriptor_header *) &fsg_intf_desc,
+       (struct usb_descriptor_header *) &fsg_fs_bulk_in_desc,
+       (struct usb_descriptor_header *) &fsg_fs_bulk_out_desc,
+       NULL,
+ };
++EXPORT_SYMBOL(fsg_fs_function);
+ /*
+@@ -310,8 +92,7 @@ static struct usb_descriptor_header *fsg_fs_function[] = {
+  * and a "device qualifier" ... plus more construction options
+  * for the configuration descriptor.
+  */
+-static struct usb_endpoint_descriptor
+-fsg_hs_bulk_in_desc = {
++struct usb_endpoint_descriptor fsg_hs_bulk_in_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -319,9 +100,9 @@ fsg_hs_bulk_in_desc = {
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       cpu_to_le16(512),
+ };
++EXPORT_SYMBOL(fsg_hs_bulk_in_desc);
+-static struct usb_endpoint_descriptor
+-fsg_hs_bulk_out_desc = {
++struct usb_endpoint_descriptor fsg_hs_bulk_out_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -330,17 +111,18 @@ fsg_hs_bulk_out_desc = {
+       .wMaxPacketSize =       cpu_to_le16(512),
+       .bInterval =            1,      /* NAK every 1 uframe */
+ };
++EXPORT_SYMBOL(fsg_hs_bulk_out_desc);
+-static struct usb_descriptor_header *fsg_hs_function[] = {
++struct usb_descriptor_header *fsg_hs_function[] = {
+       (struct usb_descriptor_header *) &fsg_intf_desc,
+       (struct usb_descriptor_header *) &fsg_hs_bulk_in_desc,
+       (struct usb_descriptor_header *) &fsg_hs_bulk_out_desc,
+       NULL,
+ };
++EXPORT_SYMBOL(fsg_hs_function);
+-static struct usb_endpoint_descriptor
+-fsg_ss_bulk_in_desc = {
++struct usb_endpoint_descriptor fsg_ss_bulk_in_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -348,16 +130,17 @@ fsg_ss_bulk_in_desc = {
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       cpu_to_le16(1024),
+ };
++EXPORT_SYMBOL(fsg_ss_bulk_in_desc);
+-static struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc = {
++struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc = {
+       .bLength =              sizeof(fsg_ss_bulk_in_comp_desc),
+       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
+       /*.bMaxBurst =          DYNAMIC, */
+ };
++EXPORT_SYMBOL(fsg_ss_bulk_in_comp_desc);
+-static struct usb_endpoint_descriptor
+-fsg_ss_bulk_out_desc = {
++struct usb_endpoint_descriptor fsg_ss_bulk_out_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -365,15 +148,17 @@ fsg_ss_bulk_out_desc = {
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       cpu_to_le16(1024),
+ };
++EXPORT_SYMBOL(fsg_ss_bulk_out_desc);
+-static struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = {
++struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = {
+       .bLength =              sizeof(fsg_ss_bulk_in_comp_desc),
+       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
+       /*.bMaxBurst =          DYNAMIC, */
+ };
++EXPORT_SYMBOL(fsg_ss_bulk_out_comp_desc);
+-static struct usb_descriptor_header *fsg_ss_function[] = {
++struct usb_descriptor_header *fsg_ss_function[] = {
+       (struct usb_descriptor_header *) &fsg_intf_desc,
+       (struct usb_descriptor_header *) &fsg_ss_bulk_in_desc,
+       (struct usb_descriptor_header *) &fsg_ss_bulk_in_comp_desc,
+@@ -381,17 +166,7 @@ static struct usb_descriptor_header *fsg_ss_function[] = {
+       (struct usb_descriptor_header *) &fsg_ss_bulk_out_comp_desc,
+       NULL,
+ };
+-
+-/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
+-static struct usb_string              fsg_strings[] = {
+-      {FSG_STRING_INTERFACE,          fsg_string_interface},
+-      {}
+-};
+-
+-static struct usb_gadget_strings      fsg_stringtab = {
+-      .language       = 0x0409,               /* en-us */
+-      .strings        = fsg_strings,
+-};
++EXPORT_SYMBOL(fsg_ss_function);
+  /*-------------------------------------------------------------------------*/
+@@ -401,7 +176,7 @@ static struct usb_gadget_strings   fsg_stringtab = {
+  * the caller must own fsg->filesem for writing.
+  */
+-static void fsg_lun_close(struct fsg_lun *curlun)
++void fsg_lun_close(struct fsg_lun *curlun)
+ {
+       if (curlun->filp) {
+               LDBG(curlun, "close backing file\n");
+@@ -409,9 +184,9 @@ static void fsg_lun_close(struct fsg_lun *curlun)
+               curlun->filp = NULL;
+       }
+ }
++EXPORT_SYMBOL(fsg_lun_close);
+-
+-static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
++int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
+ {
+       int                             ro;
+       struct file                     *filp = NULL;
+@@ -508,6 +283,7 @@ out:
+       fput(filp);
+       return rc;
+ }
++EXPORT_SYMBOL(fsg_lun_open);
+ /*-------------------------------------------------------------------------*/
+@@ -516,7 +292,7 @@ out:
+  * Sync the file data, don't bother with the metadata.
+  * This code was copied from fs/buffer.c:sys_fdatasync().
+  */
+-static int fsg_lun_fsync_sub(struct fsg_lun *curlun)
++int fsg_lun_fsync_sub(struct fsg_lun *curlun)
+ {
+       struct file     *filp = curlun->filp;
+@@ -524,8 +300,9 @@ static int fsg_lun_fsync_sub(struct fsg_lun *curlun)
+               return 0;
+       return vfs_fsync(filp, 1);
+ }
++EXPORT_SYMBOL(fsg_lun_fsync_sub);
+-static void store_cdrom_address(u8 *dest, int msf, u32 addr)
++void store_cdrom_address(u8 *dest, int msf, u32 addr)
+ {
+       if (msf) {
+               /* Convert to Minutes-Seconds-Frames */
+@@ -542,13 +319,13 @@ static void store_cdrom_address(u8 *dest, int msf, u32 addr)
+               put_unaligned_be32(addr, dest);
+       }
+ }
+-
++EXPORT_SYMBOL(store_cdrom_address);
+ /*-------------------------------------------------------------------------*/
+-static ssize_t ro_show(struct device *dev, struct device_attribute *attr,
+-                     char *buf)
++ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr,
++                  char *buf)
+ {
+       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+@@ -556,17 +333,19 @@ static ssize_t ro_show(struct device *dev, struct device_attribute *attr,
+                                 ? curlun->ro
+                                 : curlun->initially_ro);
+ }
++EXPORT_SYMBOL(fsg_show_ro);
+-static ssize_t nofua_show(struct device *dev, struct device_attribute *attr,
+-                        char *buf)
++ssize_t fsg_show_nofua(struct device *dev, struct device_attribute *attr,
++                     char *buf)
+ {
+       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+       return sprintf(buf, "%u\n", curlun->nofua);
+ }
++EXPORT_SYMBOL(fsg_show_nofua);
+-static ssize_t file_show(struct device *dev, struct device_attribute *attr,
+-                       char *buf)
++ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
++                    char *buf)
+ {
+       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+       struct rw_semaphore     *filesem = dev_get_drvdata(dev);
+@@ -591,10 +370,11 @@ static ssize_t file_show(struct device *dev, struct device_attribute *attr,
+       up_read(filesem);
+       return rc;
+ }
++EXPORT_SYMBOL(fsg_show_file);
+-static ssize_t ro_store(struct device *dev, struct device_attribute *attr,
+-                      const char *buf, size_t count)
++ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr,
++                   const char *buf, size_t count)
+ {
+       ssize_t         rc;
+       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+@@ -622,9 +402,10 @@ static ssize_t ro_store(struct device *dev, struct device_attribute *attr,
+       up_read(filesem);
+       return rc;
+ }
++EXPORT_SYMBOL(fsg_store_ro);
+-static ssize_t nofua_store(struct device *dev, struct device_attribute *attr,
+-                         const char *buf, size_t count)
++ssize_t fsg_store_nofua(struct device *dev, struct device_attribute *attr,
++                      const char *buf, size_t count)
+ {
+       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+       unsigned        nofua;
+@@ -642,9 +423,10 @@ static ssize_t nofua_store(struct device *dev, struct device_attribute *attr,
+       return count;
+ }
++EXPORT_SYMBOL(fsg_store_nofua);
+-static ssize_t file_store(struct device *dev, struct device_attribute *attr,
+-                        const char *buf, size_t count)
++ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr,
++                     const char *buf, size_t count)
+ {
+       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+       struct rw_semaphore     *filesem = dev_get_drvdata(dev);
+@@ -674,3 +456,6 @@ static ssize_t file_store(struct device *dev, struct device_attribute *attr,
+       up_write(filesem);
+       return (rc < 0 ? rc : count);
+ }
++EXPORT_SYMBOL(fsg_store_file);
++
++MODULE_LICENSE("GPL");
+diff --git a/drivers/usb/gadget/storage_common.h b/drivers/usb/gadget/storage_common.h
+new file mode 100644
+index 0000000..1fcda2b
+--- /dev/null
++++ b/drivers/usb/gadget/storage_common.h
+@@ -0,0 +1,210 @@
++#ifndef USB_STORAGE_COMMON_H
++#define USB_STORAGE_COMMON_H
++
++#include <linux/device.h>
++#include <linux/usb/storage.h>
++#include <scsi/scsi.h>
++#include <asm/unaligned.h>
++
++#ifndef DEBUG
++#undef VERBOSE_DEBUG
++#undef DUMP_MSGS
++#endif /* !DEBUG */
++
++#ifdef VERBOSE_DEBUG
++#define VLDBG LDBG
++#else
++#define VLDBG(lun, fmt, args...) do { } while (0)
++#endif /* VERBOSE_DEBUG */
++
++#define LDBG(lun, fmt, args...)   dev_dbg(&(lun)->dev, fmt, ## args)
++#define LERROR(lun, fmt, args...) dev_err(&(lun)->dev, fmt, ## args)
++#define LWARN(lun, fmt, args...)  dev_warn(&(lun)->dev, fmt, ## args)
++#define LINFO(lun, fmt, args...)  dev_info(&(lun)->dev, fmt, ## args)
++
++#ifdef DUMP_MSGS
++
++#  define dump_msg(fsg, /* const char * */ label,                     \
++                 /* const u8 * */ buf, /* unsigned */ length)         \
++do {                                                                  \
++      if (length < 512) {                                             \
++              DBG(fsg, "%s, length %u:\n", label, length);            \
++              print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET,      \
++                             16, 1, buf, length, 0);                  \
++      }                                                               \
++} while (0)
++
++#  define dump_cdb(fsg) do { } while (0)
++
++#else
++
++#  define dump_msg(fsg, /* const char * */ label, \
++                 /* const u8 * */ buf, /* unsigned */ length) do { } while (0)
++
++#  ifdef VERBOSE_DEBUG
++
++#    define dump_cdb(fsg)                                             \
++      print_hex_dump(KERN_DEBUG, "SCSI CDB: ", DUMP_PREFIX_NONE,      \
++                     16, 1, (fsg)->cmnd, (fsg)->cmnd_size, 0)         \
++
++#  else
++
++#    define dump_cdb(fsg) do { } while (0)
++
++#  endif /* VERBOSE_DEBUG */
++
++#endif /* DUMP_MSGS */
++
++/* Length of a SCSI Command Data Block */
++#define MAX_COMMAND_SIZE      16
++
++/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */
++#define SS_NO_SENSE                           0
++#define SS_COMMUNICATION_FAILURE              0x040800
++#define SS_INVALID_COMMAND                    0x052000
++#define SS_INVALID_FIELD_IN_CDB                       0x052400
++#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x052100
++#define SS_LOGICAL_UNIT_NOT_SUPPORTED         0x052500
++#define SS_MEDIUM_NOT_PRESENT                 0x023a00
++#define SS_MEDIUM_REMOVAL_PREVENTED           0x055302
++#define SS_NOT_READY_TO_READY_TRANSITION      0x062800
++#define SS_RESET_OCCURRED                     0x062900
++#define SS_SAVING_PARAMETERS_NOT_SUPPORTED    0x053900
++#define SS_UNRECOVERED_READ_ERROR             0x031100
++#define SS_WRITE_ERROR                                0x030c02
++#define SS_WRITE_PROTECTED                    0x072700
++
++#define SK(x)         ((u8) ((x) >> 16))      /* Sense Key byte, etc. */
++#define ASC(x)                ((u8) ((x) >> 8))
++#define ASCQ(x)               ((u8) (x))
++
++struct fsg_lun {
++      struct file     *filp;
++      loff_t          file_length;
++      loff_t          num_sectors;
++
++      unsigned int    initially_ro:1;
++      unsigned int    ro:1;
++      unsigned int    removable:1;
++      unsigned int    cdrom:1;
++      unsigned int    prevent_medium_removal:1;
++      unsigned int    registered:1;
++      unsigned int    info_valid:1;
++      unsigned int    nofua:1;
++
++      u32             sense_data;
++      u32             sense_data_info;
++      u32             unit_attention_data;
++
++      unsigned int    blkbits; /* Bits of logical block size
++                                                     of bound block device */
++      unsigned int    blksize; /* logical block size of bound block device */
++      struct device   dev;
++};
++
++static inline bool fsg_lun_is_open(struct fsg_lun *curlun)
++{
++      return curlun->filp != NULL;
++}
++
++/* Big enough to hold our biggest descriptor */
++#define EP0_BUFSIZE   256
++#define DELAYED_STATUS        (EP0_BUFSIZE + 999)     /* An impossibly large value */
++
++/* Default size of buffer length. */
++#define FSG_BUFLEN    ((u32)16384)
++
++/* Maximal number of LUNs supported in mass storage function */
++#define FSG_MAX_LUNS  8
++
++enum fsg_buffer_state {
++      BUF_STATE_EMPTY = 0,
++      BUF_STATE_FULL,
++      BUF_STATE_BUSY
++};
++
++struct fsg_buffhd {
++      void                            *buf;
++      enum fsg_buffer_state           state;
++      struct fsg_buffhd               *next;
++
++      /*
++       * The NetChip 2280 is faster, and handles some protocol faults
++       * better, if we don't submit any short bulk-out read requests.
++       * So we will record the intended request length here.
++       */
++      unsigned int                    bulk_out_intended_length;
++
++      struct usb_request              *inreq;
++      int                             inreq_busy;
++      struct usb_request              *outreq;
++      int                             outreq_busy;
++};
++
++enum fsg_state {
++      /* This one isn't used anywhere */
++      FSG_STATE_COMMAND_PHASE = -10,
++      FSG_STATE_DATA_PHASE,
++      FSG_STATE_STATUS_PHASE,
++
++      FSG_STATE_IDLE = 0,
++      FSG_STATE_ABORT_BULK_OUT,
++      FSG_STATE_RESET,
++      FSG_STATE_INTERFACE_CHANGE,
++      FSG_STATE_CONFIG_CHANGE,
++      FSG_STATE_DISCONNECT,
++      FSG_STATE_EXIT,
++      FSG_STATE_TERMINATED
++};
++
++enum data_direction {
++      DATA_DIR_UNKNOWN = 0,
++      DATA_DIR_FROM_HOST,
++      DATA_DIR_TO_HOST,
++      DATA_DIR_NONE
++};
++
++static inline u32 get_unaligned_be24(u8 *buf)
++{
++      return 0xffffff & (u32) get_unaligned_be32(buf - 1);
++}
++
++enum {
++      FSG_STRING_INTERFACE
++};
++
++extern struct usb_interface_descriptor fsg_intf_desc;
++
++extern struct usb_endpoint_descriptor fsg_fs_bulk_in_desc;
++extern struct usb_endpoint_descriptor fsg_fs_bulk_out_desc;
++extern struct usb_descriptor_header *fsg_fs_function[];
++
++extern struct usb_endpoint_descriptor fsg_hs_bulk_in_desc;
++extern struct usb_endpoint_descriptor fsg_hs_bulk_out_desc;
++extern struct usb_descriptor_header *fsg_hs_function[];
++
++extern struct usb_endpoint_descriptor fsg_ss_bulk_in_desc;
++extern struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc;
++extern struct usb_endpoint_descriptor fsg_ss_bulk_out_desc;
++extern struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc;
++extern struct usb_descriptor_header *fsg_ss_function[];
++
++void fsg_lun_close(struct fsg_lun *curlun);
++int fsg_lun_open(struct fsg_lun *curlun, const char *filename);
++int fsg_lun_fsync_sub(struct fsg_lun *curlun);
++void store_cdrom_address(u8 *dest, int msf, u32 addr);
++ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr,
++                  char *buf);
++ssize_t fsg_show_nofua(struct device *dev, struct device_attribute *attr,
++                     char *buf);
++ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
++                    char *buf);
++ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr,
++                   const char *buf, size_t count);
++ssize_t fsg_store_nofua(struct device *dev,
++                      struct device_attribute *attr,
++                      const char *buf, size_t count);
++ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr,
++                     const char *buf, size_t count);
++
++#endif /* USB_STORAGE_COMMON_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1124-usb-gadget-f_mass_storage-factor-out-a-header-file.patch b/patches.tizen/1124-usb-gadget-f_mass_storage-factor-out-a-header-file.patch
new file mode 100644 (file)
index 0000000..47fb7c0
--- /dev/null
@@ -0,0 +1,328 @@
+From 39c7961f2ab59cd2cbaaf64792f16081785a06c4 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 26 Sep 2013 14:38:17 +0200
+Subject: [PATCH 1124/1302] usb: gadget: f_mass_storage: factor out a header
+ file
+
+In order to prepare for the new function interface the f_mass_storage.c
+needs to be compiled as a module, and so a header file will be required.
+
+This patch factors out some code to a new f_mass_storage.h.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 117 ++-------------------------------
+ drivers/usb/gadget/f_mass_storage.h | 126 ++++++++++++++++++++++++++++++++++++
+ 2 files changed, 133 insertions(+), 110 deletions(-)
+ create mode 100644 drivers/usb/gadget/f_mass_storage.h
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index def3426..3cdd835 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -229,6 +229,7 @@
+ static const char fsg_string_interface[] = "Mass Storage";
+ #include "storage_common.h"
++#include "f_mass_storage.h"
+ /* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
+ static struct usb_string              fsg_strings[] = {
+@@ -246,18 +247,6 @@ static struct usb_gadget_strings  fsg_stringtab = {
+ struct fsg_dev;
+ struct fsg_common;
+-/* FSF callback functions */
+-struct fsg_operations {
+-      /*
+-       * Callback function to call when thread exits.  If no
+-       * callback is set or it returns value lower then zero MSF
+-       * will force eject all LUNs it operates on (including those
+-       * marked as non-removable or with prevent_medium_removal flag
+-       * set).
+-       */
+-      int (*thread_exits)(struct fsg_common *common);
+-};
+-
+ /* Data shared by all the FSG instances. */
+ struct fsg_common {
+       struct usb_gadget       *gadget;
+@@ -324,28 +313,6 @@ struct fsg_common {
+       struct kref             ref;
+ };
+-struct fsg_config {
+-      unsigned nluns;
+-      struct fsg_lun_config {
+-              const char *filename;
+-              char ro;
+-              char removable;
+-              char cdrom;
+-              char nofua;
+-      } luns[FSG_MAX_LUNS];
+-
+-      /* Callback functions. */
+-      const struct fsg_operations     *ops;
+-      /* Gadget's private data. */
+-      void                    *private_data;
+-
+-      const char *vendor_name;                /*  8 characters or less */
+-      const char *product_name;               /* 16 characters or less */
+-
+-      char                    can_stall;
+-      unsigned int            fsg_num_buffers;
+-};
+-
+ struct fsg_dev {
+       struct usb_function     function;
+       struct usb_gadget       *gadget;        /* Copy of cdev->gadget */
+@@ -2644,12 +2611,12 @@ static void fsg_lun_release(struct device *dev)
+       /* Nothing needs to be done */
+ }
+-static inline void fsg_common_get(struct fsg_common *common)
++void fsg_common_get(struct fsg_common *common)
+ {
+       kref_get(&common->ref);
+ }
+-static inline void fsg_common_put(struct fsg_common *common)
++void fsg_common_put(struct fsg_common *common)
+ {
+       kref_put(&common->ref, fsg_common_release);
+ }
+@@ -2664,9 +2631,9 @@ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
+       return -EINVAL;
+ }
+-static struct fsg_common *fsg_common_init(struct fsg_common *common,
+-                                        struct usb_composite_dev *cdev,
+-                                        struct fsg_config *cfg)
++struct fsg_common *fsg_common_init(struct fsg_common *common,
++                                 struct usb_composite_dev *cdev,
++                                 struct fsg_config *cfg)
+ {
+       struct usb_gadget *gadget = cdev->gadget;
+       struct fsg_buffhd *bh;
+@@ -3043,62 +3010,8 @@ static int fsg_bind_config(struct usb_composite_dev *cdev,
+ /************************* Module parameters *************************/
+-struct fsg_module_parameters {
+-      char            *file[FSG_MAX_LUNS];
+-      bool            ro[FSG_MAX_LUNS];
+-      bool            removable[FSG_MAX_LUNS];
+-      bool            cdrom[FSG_MAX_LUNS];
+-      bool            nofua[FSG_MAX_LUNS];
+-
+-      unsigned int    file_count, ro_count, removable_count, cdrom_count;
+-      unsigned int    nofua_count;
+-      unsigned int    luns;   /* nluns */
+-      bool            stall;  /* can_stall */
+-};
+-
+-#define _FSG_MODULE_PARAM_ARRAY(prefix, params, name, type, desc)     \
+-      module_param_array_named(prefix ## name, params.name, type,     \
+-                               &prefix ## params.name ## _count,      \
+-                               S_IRUGO);                              \
+-      MODULE_PARM_DESC(prefix ## name, desc)
+-
+-#define _FSG_MODULE_PARAM(prefix, params, name, type, desc)           \
+-      module_param_named(prefix ## name, params.name, type,           \
+-                         S_IRUGO);                                    \
+-      MODULE_PARM_DESC(prefix ## name, desc)
+-
+-#define __FSG_MODULE_PARAMETERS(prefix, params)                               \
+-      _FSG_MODULE_PARAM_ARRAY(prefix, params, file, charp,            \
+-                              "names of backing files or devices");   \
+-      _FSG_MODULE_PARAM_ARRAY(prefix, params, ro, bool,               \
+-                              "true to force read-only");             \
+-      _FSG_MODULE_PARAM_ARRAY(prefix, params, removable, bool,        \
+-                              "true to simulate removable media");    \
+-      _FSG_MODULE_PARAM_ARRAY(prefix, params, cdrom, bool,            \
+-                              "true to simulate CD-ROM instead of disk"); \
+-      _FSG_MODULE_PARAM_ARRAY(prefix, params, nofua, bool,            \
+-                              "true to ignore SCSI WRITE(10,12) FUA bit"); \
+-      _FSG_MODULE_PARAM(prefix, params, luns, uint,                   \
+-                        "number of LUNs");                            \
+-      _FSG_MODULE_PARAM(prefix, params, stall, bool,                  \
+-                        "false to prevent bulk stalls")
+-
+-#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+-
+-#define FSG_MODULE_PARAMETERS(prefix, params)                         \
+-      __FSG_MODULE_PARAMETERS(prefix, params);                        \
+-      module_param_named(num_buffers, fsg_num_buffers, uint, S_IRUGO);\
+-      MODULE_PARM_DESC(num_buffers, "Number of pipeline buffers")
+-#else
+-
+-#define FSG_MODULE_PARAMETERS(prefix, params)                         \
+-      __FSG_MODULE_PARAMETERS(prefix, params)
+-
+-#endif
+-
+-static void
+-fsg_config_from_params(struct fsg_config *cfg,
++void fsg_config_from_params(struct fsg_config *cfg,
+                      const struct fsg_module_parameters *params,
+                      unsigned int fsg_num_buffers)
+ {
+@@ -3131,19 +3044,3 @@ fsg_config_from_params(struct fsg_config *cfg,
+       cfg->fsg_num_buffers = fsg_num_buffers;
+ }
+-static inline struct fsg_common *
+-fsg_common_from_params(struct fsg_common *common,
+-                     struct usb_composite_dev *cdev,
+-                     const struct fsg_module_parameters *params,
+-                     unsigned int fsg_num_buffers)
+-      __attribute__((unused));
+-static inline struct fsg_common *
+-fsg_common_from_params(struct fsg_common *common,
+-                     struct usb_composite_dev *cdev,
+-                     const struct fsg_module_parameters *params,
+-                     unsigned int fsg_num_buffers)
+-{
+-      struct fsg_config cfg;
+-      fsg_config_from_params(&cfg, params, fsg_num_buffers);
+-      return fsg_common_init(common, cdev, &cfg);
+-}
+diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h
+new file mode 100644
+index 0000000..b64761d
+--- /dev/null
++++ b/drivers/usb/gadget/f_mass_storage.h
+@@ -0,0 +1,126 @@
++#ifndef USB_F_MASS_STORAGE_H
++#define USB_F_MASS_STORAGE_H
++
++#include "storage_common.h"
++
++struct fsg_module_parameters {
++      char            *file[FSG_MAX_LUNS];
++      bool            ro[FSG_MAX_LUNS];
++      bool            removable[FSG_MAX_LUNS];
++      bool            cdrom[FSG_MAX_LUNS];
++      bool            nofua[FSG_MAX_LUNS];
++
++      unsigned int    file_count, ro_count, removable_count, cdrom_count;
++      unsigned int    nofua_count;
++      unsigned int    luns;   /* nluns */
++      bool            stall;  /* can_stall */
++};
++
++#define _FSG_MODULE_PARAM_ARRAY(prefix, params, name, type, desc)     \
++      module_param_array_named(prefix ## name, params.name, type,     \
++                               &prefix ## params.name ## _count,      \
++                               S_IRUGO);                              \
++      MODULE_PARM_DESC(prefix ## name, desc)
++
++#define _FSG_MODULE_PARAM(prefix, params, name, type, desc)           \
++      module_param_named(prefix ## name, params.name, type,           \
++                         S_IRUGO);                                    \
++      MODULE_PARM_DESC(prefix ## name, desc)
++
++#define __FSG_MODULE_PARAMETERS(prefix, params)                               \
++      _FSG_MODULE_PARAM_ARRAY(prefix, params, file, charp,            \
++                              "names of backing files or devices");   \
++      _FSG_MODULE_PARAM_ARRAY(prefix, params, ro, bool,               \
++                              "true to force read-only");             \
++      _FSG_MODULE_PARAM_ARRAY(prefix, params, removable, bool,        \
++                              "true to simulate removable media");    \
++      _FSG_MODULE_PARAM_ARRAY(prefix, params, cdrom, bool,            \
++                              "true to simulate CD-ROM instead of disk"); \
++      _FSG_MODULE_PARAM_ARRAY(prefix, params, nofua, bool,            \
++                              "true to ignore SCSI WRITE(10,12) FUA bit"); \
++      _FSG_MODULE_PARAM(prefix, params, luns, uint,                   \
++                        "number of LUNs");                            \
++      _FSG_MODULE_PARAM(prefix, params, stall, bool,                  \
++                        "false to prevent bulk stalls")
++
++#ifdef CONFIG_USB_GADGET_DEBUG_FILES
++
++#define FSG_MODULE_PARAMETERS(prefix, params)                         \
++      __FSG_MODULE_PARAMETERS(prefix, params);                        \
++      module_param_named(num_buffers, fsg_num_buffers, uint, S_IRUGO);\
++      MODULE_PARM_DESC(num_buffers, "Number of pipeline buffers")
++#else
++
++#define FSG_MODULE_PARAMETERS(prefix, params)                         \
++      __FSG_MODULE_PARAMETERS(prefix, params)
++
++#endif
++
++struct fsg_common;
++
++/* FSF callback functions */
++struct fsg_operations {
++      /*
++       * Callback function to call when thread exits.  If no
++       * callback is set or it returns value lower then zero MSF
++       * will force eject all LUNs it operates on (including those
++       * marked as non-removable or with prevent_medium_removal flag
++       * set).
++       */
++      int (*thread_exits)(struct fsg_common *common);
++};
++
++struct fsg_lun_config {
++      const char *filename;
++      char ro;
++      char removable;
++      char cdrom;
++      char nofua;
++};
++
++struct fsg_config {
++      unsigned nluns;
++      struct fsg_lun_config luns[FSG_MAX_LUNS];
++
++      /* Callback functions. */
++      const struct fsg_operations     *ops;
++      /* Gadget's private data. */
++      void                    *private_data;
++
++      const char *vendor_name;                /*  8 characters or less */
++      const char *product_name;               /* 16 characters or less */
++
++      char                    can_stall;
++      unsigned int            fsg_num_buffers;
++};
++
++void fsg_common_get(struct fsg_common *common);
++
++void fsg_common_put(struct fsg_common *common);
++
++struct fsg_common *fsg_common_init(struct fsg_common *common,
++                                 struct usb_composite_dev *cdev,
++                                 struct fsg_config *cfg);
++
++void fsg_config_from_params(struct fsg_config *cfg,
++                          const struct fsg_module_parameters *params,
++                          unsigned int fsg_num_buffers);
++
++static inline struct fsg_common *
++fsg_common_from_params(struct fsg_common *common,
++                     struct usb_composite_dev *cdev,
++                     const struct fsg_module_parameters *params,
++                     unsigned int fsg_num_buffers)
++      __attribute__((unused));
++static inline struct fsg_common *
++fsg_common_from_params(struct fsg_common *common,
++                     struct usb_composite_dev *cdev,
++                     const struct fsg_module_parameters *params,
++                     unsigned int fsg_num_buffers)
++{
++      struct fsg_config cfg;
++      fsg_config_from_params(&cfg, params, fsg_num_buffers);
++      return fsg_common_init(common, cdev, &cfg);
++}
++
++#endif /* USB_F_MASS_STORAGE_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1125-usb-gadget-f_mass_storage-add-a-level-of-indirection.patch b/patches.tizen/1125-usb-gadget-f_mass_storage-add-a-level-of-indirection.patch
new file mode 100644 (file)
index 0000000..0cb24b5
--- /dev/null
@@ -0,0 +1,212 @@
+From 28078ebfde6132df6b6c76b2d12c1fe97058b31e Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 26 Sep 2013 14:38:18 +0200
+Subject: [PATCH 1125/1302] usb: gadget: f_mass_storage: add a level of
+ indirection for luns storage
+
+This is needed to prepare for configfs integration.
+
+So far the luns have been allocated during gadget's initialization, based
+on the nluns module parameter's value; the exact number is known when the
+gadget is initialized and that number of luns is allocated in one go; they
+all will be used.
+
+When configfs is in place, the luns will be created one-by-one by the user.
+Once the user is satisfied with the number of luns, they activate the
+gadget. The number of luns must be <= FSG_MAX_LUN (currently 8), but other
+than that it is not known up front and the user need not use contiguous
+numbering (apart from the default lun #0). On the other hand, the function
+code uses lun numbers to identify them and the number needs to be used
+as an index into an array.
+
+Given the above, an array needs to be allocated, but it might happen that
+7 out of its 8 elements will not be used. On my machine
+sizeof(struct fsg_lun) == 462, so > 3k of memory is allocated but not used
+in the worst case.
+
+By adding another level of indirection (allocating an array of pointers
+to struct fsg_lun and then allocating individual luns instead of an array
+of struct fsg_luns) at most 7 pointers are wasted, which is much less.
+
+This patch also changes some for/while loops to cope with the fact
+that in the luns array some entries are potentially empty.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 60 +++++++++++++++++++++++++------------
+ 1 file changed, 41 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 3cdd835..6b6c7f1 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -274,7 +274,7 @@ struct fsg_common {
+       unsigned int            nluns;
+       unsigned int            lun;
+-      struct fsg_lun          *luns;
++      struct fsg_lun          **luns;
+       struct fsg_lun          *curlun;
+       unsigned int            bulk_out_maxpacket;
+@@ -2151,7 +2151,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
+               common->data_dir = DATA_DIR_NONE;
+       common->lun = cbw->Lun;
+       if (common->lun < common->nluns)
+-              common->curlun = &common->luns[common->lun];
++              common->curlun = common->luns[common->lun];
+       else
+               common->curlun = NULL;
+       common->tag = cbw->Tag;
+@@ -2299,7 +2299,9 @@ reset:
+       common->running = 1;
+       for (i = 0; i < common->nluns; ++i)
+-              common->luns[i].unit_attention_data = SS_RESET_OCCURRED;
++              if (common->luns[i])
++                      common->luns[i]->unit_attention_data =
++                              SS_RESET_OCCURRED;
+       return rc;
+ }
+@@ -2399,7 +2401,9 @@ static void handle_exception(struct fsg_common *common)
+               common->state = FSG_STATE_STATUS_PHASE;
+       else {
+               for (i = 0; i < common->nluns; ++i) {
+-                      curlun = &common->luns[i];
++                      curlun = common->luns[i];
++                      if (!curlun)
++                              continue;
+                       curlun->prevent_medium_removal = 0;
+                       curlun->sense_data = SS_NO_SENSE;
+                       curlun->unit_attention_data = SS_NO_SENSE;
+@@ -2441,8 +2445,9 @@ static void handle_exception(struct fsg_common *common)
+                * CONFIG_CHANGE cases.
+                */
+               /* for (i = 0; i < common->nluns; ++i) */
+-              /*      common->luns[i].unit_attention_data = */
+-              /*              SS_RESET_OCCURRED;  */
++              /*      if (common->luns[i]) */
++              /*              common->luns[i]->unit_attention_data = */
++              /*                      SS_RESET_OCCURRED;  */
+               break;
+       case FSG_STATE_CONFIG_CHANGE:
+@@ -2538,12 +2543,13 @@ static int fsg_main_thread(void *common_)
+       if (!common->ops || !common->ops->thread_exits
+        || common->ops->thread_exits(common) < 0) {
+-              struct fsg_lun *curlun = common->luns;
++              struct fsg_lun **curlun_it = common->luns;
+               unsigned i = common->nluns;
+               down_write(&common->filesem);
+-              for (; i--; ++curlun) {
+-                      if (!fsg_lun_is_open(curlun))
++              for (; i--; ++curlun_it) {
++                      struct fsg_lun *curlun = *curlun_it;
++                      if (!curlun || !fsg_lun_is_open(curlun))
+                               continue;
+                       fsg_lun_close(curlun);
+@@ -2637,7 +2643,7 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+ {
+       struct usb_gadget *gadget = cdev->gadget;
+       struct fsg_buffhd *bh;
+-      struct fsg_lun *curlun;
++      struct fsg_lun **curlun_it;
+       struct fsg_lun_config *lcfg;
+       int nluns, i, rc;
+       char *pathbuf;
+@@ -2694,16 +2700,26 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+        * Create the LUNs, open their backing files, and register the
+        * LUN devices in sysfs.
+        */
+-      curlun = kcalloc(nluns, sizeof(*curlun), GFP_KERNEL);
+-      if (unlikely(!curlun)) {
++      curlun_it = kcalloc(nluns, sizeof(*curlun_it), GFP_KERNEL);
++      if (unlikely(!curlun_it)) {
+               rc = -ENOMEM;
+               goto error_release;
+       }
+-      common->luns = curlun;
++      common->luns = curlun_it;
+       init_rwsem(&common->filesem);
+-      for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun, ++lcfg) {
++      for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun_it, ++lcfg) {
++              struct fsg_lun *curlun;
++
++              curlun = kzalloc(sizeof(*curlun), GFP_KERNEL);
++              if (!curlun) {
++                      rc = -ENOMEM;
++                      common->nluns = i;
++                      goto error_release;
++              }
++              *curlun_it = curlun;
++
+               curlun->cdrom = !!lcfg->cdrom;
+               curlun->ro = lcfg->cdrom || lcfg->ro;
+               curlun->initially_ro = curlun->ro;
+@@ -2719,6 +2735,7 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                       INFO(common, "failed to register LUN%d: %d\n", i, rc);
+                       common->nluns = i;
+                       put_device(&curlun->dev);
++                      kfree(curlun);
+                       goto error_release;
+               }
+@@ -2771,7 +2788,7 @@ buffhds_first_it:
+       snprintf(common->inquiry_string, sizeof common->inquiry_string,
+                "%-8s%-16s%04x", cfg->vendor_name ?: "Linux",
+                /* Assume product name dependent on the first LUN */
+-               cfg->product_name ?: (common->luns->cdrom
++               cfg->product_name ?: ((*common->luns)->cdrom
+                                    ? "File-CD Gadget"
+                                    : "File-Stor Gadget"),
+                i);
+@@ -2802,9 +2819,10 @@ buffhds_first_it:
+       INFO(common, "Number of LUNs=%d\n", common->nluns);
+       pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
+-      for (i = 0, nluns = common->nluns, curlun = common->luns;
++      for (i = 0, nluns = common->nluns, curlun_it = common->luns;
+            i < nluns;
+-           ++curlun, ++i) {
++           ++curlun_it, ++i) {
++              struct fsg_lun *curlun = *curlun_it;
+               char *p = "(no medium)";
+               if (fsg_lun_is_open(curlun)) {
+                       p = "(error)";
+@@ -2849,11 +2867,14 @@ static void fsg_common_release(struct kref *ref)
+       }
+       if (likely(common->luns)) {
+-              struct fsg_lun *lun = common->luns;
++              struct fsg_lun **lun_it = common->luns;
+               unsigned i = common->nluns;
+               /* In error recovery common->nluns may be zero. */
+-              for (; i; --i, ++lun) {
++              for (; i; --i, ++lun_it) {
++                      struct fsg_lun *lun = *lun_it;
++                      if (!lun)
++                              continue;
+                       device_remove_file(&lun->dev, &dev_attr_nofua);
+                       device_remove_file(&lun->dev,
+                                          lun->cdrom
+@@ -2865,6 +2886,7 @@ static void fsg_common_release(struct kref *ref)
+                                        : &dev_attr_file_nonremovable);
+                       fsg_lun_close(lun);
+                       device_unregister(&lun->dev);
++                      kfree(lun);
+               }
+               kfree(common->luns);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1126-usb-gadget-f_mass_storage-use-usb_gstrings_attach.patch b/patches.tizen/1126-usb-gadget-f_mass_storage-use-usb_gstrings_attach.patch
new file mode 100644 (file)
index 0000000..4a5589d
--- /dev/null
@@ -0,0 +1,84 @@
+From 9604df639c5e142e80a4871c63ff15938c544285 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 26 Sep 2013 14:38:19 +0200
+Subject: [PATCH 1126/1302] usb: gadget: f_mass_storage: use
+ usb_gstrings_attach
+
+Prepare for handling with configfs.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 25 ++++++++++++-------------
+ 1 file changed, 12 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 6b6c7f1..32e5ab7 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -242,6 +242,11 @@ static struct usb_gadget_strings  fsg_stringtab = {
+       .strings        = fsg_strings,
+ };
++static struct usb_gadget_strings *fsg_strings_array[] = {
++      &fsg_stringtab,
++      NULL,
++};
++
+ /*-------------------------------------------------------------------------*/
+ struct fsg_dev;
+@@ -2645,6 +2650,7 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       struct fsg_buffhd *bh;
+       struct fsg_lun **curlun_it;
+       struct fsg_lun_config *lcfg;
++      struct usb_string *us;
+       int nluns, i, rc;
+       char *pathbuf;
+@@ -2687,14 +2693,13 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       common->ep0req = cdev->req;
+       common->cdev = cdev;
+-      /* Maybe allocate device-global string IDs, and patch descriptors */
+-      if (fsg_strings[FSG_STRING_INTERFACE].id == 0) {
+-              rc = usb_string_id(cdev);
+-              if (unlikely(rc < 0))
+-                      goto error_release;
+-              fsg_strings[FSG_STRING_INTERFACE].id = rc;
+-              fsg_intf_desc.iInterface = rc;
++      us = usb_gstrings_attach(cdev, fsg_strings_array,
++                               ARRAY_SIZE(fsg_strings));
++      if (IS_ERR(us)) {
++              rc = PTR_ERR(us);
++              goto error_release;
+       }
++      fsg_intf_desc.iInterface = us[FSG_STRING_INTERFACE].id;
+       /*
+        * Create the LUNs, open their backing files, and register the
+@@ -2988,11 +2993,6 @@ autoconf_fail:
+ /****************************** ADD FUNCTION ******************************/
+-static struct usb_gadget_strings *fsg_strings_array[] = {
+-      &fsg_stringtab,
+-      NULL,
+-};
+-
+ static int fsg_bind_config(struct usb_composite_dev *cdev,
+                          struct usb_configuration *c,
+                          struct fsg_common *common)
+@@ -3005,7 +3005,6 @@ static int fsg_bind_config(struct usb_composite_dev *cdev,
+               return -ENOMEM;
+       fsg->function.name        = FSG_DRIVER_DESC;
+-      fsg->function.strings     = fsg_strings_array;
+       fsg->function.bind        = fsg_bind;
+       fsg->function.unbind      = fsg_unbind;
+       fsg->function.setup       = fsg_setup;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1127-usb-gadget-f_mass_storage-create-_fsg_common_free_bu.patch b/patches.tizen/1127-usb-gadget-f_mass_storage-create-_fsg_common_free_bu.patch
new file mode 100644 (file)
index 0000000..1606817
--- /dev/null
@@ -0,0 +1,61 @@
+From 3a759d33baa4aeb5aee82486b75f9696ca8fa107 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 9 Oct 2013 10:05:52 +0200
+Subject: [PATCH 1127/1302] usb: gadget: f_mass_storage: create
+ _fsg_common_free_buffers
+
+When configfs is in place, gadgets will have to be able to free
+fsg buffers. Add a helper function.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 22 +++++++++++++---------
+ 1 file changed, 13 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 32e5ab7..59a12c1 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -2642,6 +2642,18 @@ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
+       return -EINVAL;
+ }
++static void _fsg_common_free_buffers(struct fsg_buffhd *buffhds, unsigned n)
++{
++      if (buffhds) {
++              struct fsg_buffhd *bh = buffhds;
++              while (n--) {
++                      kfree(bh->buf);
++                      ++bh;
++              }
++              kfree(buffhds);
++      }
++}
++
+ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                  struct usb_composite_dev *cdev,
+                                  struct fsg_config *cfg)
+@@ -2897,15 +2909,7 @@ static void fsg_common_release(struct kref *ref)
+               kfree(common->luns);
+       }
+-      {
+-              struct fsg_buffhd *bh = common->buffhds;
+-              unsigned i = common->fsg_num_buffers;
+-              do {
+-                      kfree(bh->buf);
+-              } while (++bh, --i);
+-      }
+-
+-      kfree(common->buffhds);
++      _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
+       if (common->free_storage_on_release)
+               kfree(common);
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1128-usb-gadget-f_mass_storage-make-sysfs-interface-optio.patch b/patches.tizen/1128-usb-gadget-f_mass_storage-make-sysfs-interface-optio.patch
new file mode 100644 (file)
index 0000000..82d1031
--- /dev/null
@@ -0,0 +1,187 @@
+From 2ab8fc781e2906270daf0cc6e848aae6f07849e6 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 9 Oct 2013 10:05:53 +0200
+Subject: [PATCH 1128/1302] usb: gadget: f_mass_storage: make sysfs interface
+ optional
+
+When configfs is in place, the luns will not be represented in sysfs,
+so there will be no struct device associated with a lun.
+In order to maintain compatibility and allow configfs adoption
+sysfs is made optional in this patch.
+
+As a consequence some debug macros need to be adjusted. Two new
+fields are added to struct fsg_lun: name and name_pfx.
+The "name" is for storing a string which is presented to the user
+instead of the dev_name. The "name_pfx", if non-NULL, is prepended
+to the "name" at printing time.
+
+The name_pfx is for a future lun.0, which will be a default group in
+mass_storage.<name>. By design at USB function configfs group's creation
+time its name is not known (but instead set a bit later in
+drivers/usb/gadget/configfs.c:function_make) and it is this name that
+serves the purpose of the said name prefix. So instead of copying
+a yet-unknown string a pointer to it is stored in struct fsg_lun.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 51 +++++++++++++++++++++++++++++--------
+ drivers/usb/gadget/f_mass_storage.h |  2 ++
+ drivers/usb/gadget/storage_common.h | 20 ++++++++++++---
+ 3 files changed, 59 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 59a12c1..7034d9c 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -299,6 +299,7 @@ struct fsg_common {
+       unsigned int            short_packet_received:1;
+       unsigned int            bad_lun_okay:1;
+       unsigned int            running:1;
++      unsigned int            sysfs:1;
+       int                     thread_wakeup_needed;
+       struct completion       thread_notifier;
+@@ -2642,6 +2643,11 @@ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
+       return -EINVAL;
+ }
++void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs)
++{
++      common->sysfs = sysfs;
++}
++
+ static void _fsg_common_free_buffers(struct fsg_buffhd *buffhds, unsigned n)
+ {
+       if (buffhds) {
+@@ -2654,6 +2660,34 @@ static void _fsg_common_free_buffers(struct fsg_buffhd *buffhds, unsigned n)
+       }
+ }
++static inline void fsg_common_remove_sysfs(struct fsg_lun *lun)
++{
++      device_remove_file(&lun->dev, &dev_attr_nofua);
++      /*
++       * device_remove_file() =>
++       *
++       * here the attr (e.g. dev_attr_ro) is only used to be passed to:
++       *
++       *      sysfs_remove_file() =>
++       *
++       *      here e.g. both dev_attr_ro_cdrom and dev_attr_ro are in
++       *      the same namespace and
++       *      from here only attr->name is passed to:
++       *
++       *              sysfs_hash_and_remove()
++       *
++       *              attr->name is the same for dev_attr_ro_cdrom and
++       *              dev_attr_ro
++       *              attr->name is the same for dev_attr_file and
++       *              dev_attr_file_nonremovable
++       *
++       * so we don't differentiate between removing e.g. dev_attr_ro_cdrom
++       * and dev_attr_ro
++       */
++      device_remove_file(&lun->dev, &dev_attr_ro);
++      device_remove_file(&lun->dev, &dev_attr_file);
++}
++
+ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                  struct usb_composite_dev *cdev,
+                                  struct fsg_config *cfg)
+@@ -2687,6 +2721,8 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+               memset(common, 0, sizeof *common);
+               common->free_storage_on_release = 0;
+       }
++      fsg_common_set_sysfs(common, true);
++      common->state = FSG_STATE_IDLE;
+       common->fsg_num_buffers = cfg->fsg_num_buffers;
+       common->buffhds = kcalloc(common->fsg_num_buffers,
+@@ -2746,6 +2782,7 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+               /* curlun->dev.driver = &fsg_driver.driver; XXX */
+               dev_set_drvdata(&curlun->dev, &common->filesem);
+               dev_set_name(&curlun->dev, "lun%d", i);
++              curlun->name = dev_name(&curlun->dev);
+               rc = device_register(&curlun->dev);
+               if (rc) {
+@@ -2892,17 +2929,11 @@ static void fsg_common_release(struct kref *ref)
+                       struct fsg_lun *lun = *lun_it;
+                       if (!lun)
+                               continue;
+-                      device_remove_file(&lun->dev, &dev_attr_nofua);
+-                      device_remove_file(&lun->dev,
+-                                         lun->cdrom
+-                                       ? &dev_attr_ro_cdrom
+-                                       : &dev_attr_ro);
+-                      device_remove_file(&lun->dev,
+-                                         lun->removable
+-                                       ? &dev_attr_file
+-                                       : &dev_attr_file_nonremovable);
++                      if (common->sysfs)
++                              fsg_common_remove_sysfs(lun);
+                       fsg_lun_close(lun);
+-                      device_unregister(&lun->dev);
++                      if (common->sysfs)
++                              device_unregister(&lun->dev);
+                       kfree(lun);
+               }
+diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h
+index b64761d..1b88eae 100644
+--- a/drivers/usb/gadget/f_mass_storage.h
++++ b/drivers/usb/gadget/f_mass_storage.h
+@@ -102,6 +102,8 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                  struct usb_composite_dev *cdev,
+                                  struct fsg_config *cfg);
++void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs);
++
+ void fsg_config_from_params(struct fsg_config *cfg,
+                           const struct fsg_module_parameters *params,
+                           unsigned int fsg_num_buffers);
+diff --git a/drivers/usb/gadget/storage_common.h b/drivers/usb/gadget/storage_common.h
+index 1fcda2b..d8cc090 100644
+--- a/drivers/usb/gadget/storage_common.h
++++ b/drivers/usb/gadget/storage_common.h
+@@ -17,10 +17,20 @@
+ #define VLDBG(lun, fmt, args...) do { } while (0)
+ #endif /* VERBOSE_DEBUG */
+-#define LDBG(lun, fmt, args...)   dev_dbg(&(lun)->dev, fmt, ## args)
+-#define LERROR(lun, fmt, args...) dev_err(&(lun)->dev, fmt, ## args)
+-#define LWARN(lun, fmt, args...)  dev_warn(&(lun)->dev, fmt, ## args)
+-#define LINFO(lun, fmt, args...)  dev_info(&(lun)->dev, fmt, ## args)
++#define _LMSG(func, lun, fmt, args...)                                        \
++      do {                                                            \
++              if ((lun)->name_pfx && *(lun)->name_pfx)                \
++                      func("%s/%s: " fmt, *(lun)->name_pfx,           \
++                               (lun)->name, ## args);                 \
++              else                                                    \
++                      func("%s: " fmt, (lun)->name, ## args);         \
++      } while (0)
++
++#define LDBG(lun, fmt, args...)               _LMSG(pr_debug, lun, fmt, ## args)
++#define LERROR(lun, fmt, args...)     _LMSG(pr_err, lun, fmt, ## args)
++#define LWARN(lun, fmt, args...)      _LMSG(pr_warn, lun, fmt, ## args)
++#define LINFO(lun, fmt, args...)      _LMSG(pr_info, lun, fmt, ## args)
++
+ #ifdef DUMP_MSGS
+@@ -100,6 +110,8 @@ struct fsg_lun {
+                                                      of bound block device */
+       unsigned int    blksize; /* logical block size of bound block device */
+       struct device   dev;
++      const char      *name;          /* "lun.name" */
++      const char      **name_pfx;     /* "function.name" */
+ };
+ static inline bool fsg_lun_is_open(struct fsg_lun *curlun)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1129-usb-gadget-f_mass_storage-create-fsg_common_setup-fo.patch b/patches.tizen/1129-usb-gadget-f_mass_storage-create-fsg_common_setup-fo.patch
new file mode 100644 (file)
index 0000000..5b75ede
--- /dev/null
@@ -0,0 +1,99 @@
+From a9ab37990a00e14ea42020f74da75d4d07482a29 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 9 Oct 2013 10:05:54 +0200
+Subject: [PATCH 1129/1302] usb: gadget: f_mass_storage: create
+ fsg_common_setup for use in fsg_common_init
+
+fsg_common_init is a lengthy function. Factor a portion of it out.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 40 ++++++++++++++++++++++---------------
+ 1 file changed, 24 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 7034d9c..da87ffe 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -2643,6 +2643,27 @@ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
+       return -EINVAL;
+ }
++static struct fsg_common *fsg_common_setup(struct fsg_common *common)
++{
++      if (!common) {
++              common = kzalloc(sizeof(*common), GFP_KERNEL);
++              if (!common)
++                      return ERR_PTR(-ENOMEM);
++              common->free_storage_on_release = 1;
++      } else {
++              memset(common, 0, sizeof(*common));
++              common->free_storage_on_release = 0;
++      }
++      init_rwsem(&common->filesem);
++      spin_lock_init(&common->lock);
++      kref_init(&common->ref);
++      init_completion(&common->thread_notifier);
++      init_waitqueue_head(&common->fsg_wait);
++      common->state = FSG_STATE_TERMINATED;
++
++      return common;
++}
++
+ void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs)
+ {
+       common->sysfs = sysfs;
+@@ -2711,16 +2732,9 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+               return ERR_PTR(-EINVAL);
+       }
+-      /* Allocate? */
+-      if (!common) {
+-              common = kzalloc(sizeof *common, GFP_KERNEL);
+-              if (!common)
+-                      return ERR_PTR(-ENOMEM);
+-              common->free_storage_on_release = 1;
+-      } else {
+-              memset(common, 0, sizeof *common);
+-              common->free_storage_on_release = 0;
+-      }
++      common = fsg_common_setup(common);
++      if (IS_ERR(common))
++              return common;
+       fsg_common_set_sysfs(common, true);
+       common->state = FSG_STATE_IDLE;
+@@ -2760,8 +2774,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       }
+       common->luns = curlun_it;
+-      init_rwsem(&common->filesem);
+-
+       for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun_it, ++lcfg) {
+               struct fsg_lun *curlun;
+@@ -2855,8 +2867,6 @@ buffhds_first_it:
+       common->can_stall = cfg->can_stall &&
+               !(gadget_is_at91(common->gadget));
+-      spin_lock_init(&common->lock);
+-      kref_init(&common->ref);
+       /* Tell the thread to start working */
+       common->thread_task =
+@@ -2865,8 +2875,6 @@ buffhds_first_it:
+               rc = PTR_ERR(common->thread_task);
+               goto error_release;
+       }
+-      init_completion(&common->thread_notifier);
+-      init_waitqueue_head(&common->fsg_wait);
+       /* Information */
+       INFO(common, FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1130-usb-gadget-f_mass_storage-create-fsg_common_set_num_.patch b/patches.tizen/1130-usb-gadget-f_mass_storage-create-fsg_common_set_num_.patch
new file mode 100644 (file)
index 0000000..101f923
--- /dev/null
@@ -0,0 +1,147 @@
+From 6def2116d6ec7479f57bd5f12ed51472dc879b1d Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 9 Oct 2013 10:05:55 +0200
+Subject: [PATCH 1130/1302] usb: gadget: f_mass_storage: create
+ fsg_common_set_num_buffers for use in fsg_common_init
+
+fsg_common_init is a lengthy function. Factor a portion of it out.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 72 +++++++++++++++++++++++--------------
+ drivers/usb/gadget/f_mass_storage.h |  2 ++
+ 2 files changed, 48 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index da87ffe..79d98997 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -2681,6 +2681,49 @@ static void _fsg_common_free_buffers(struct fsg_buffhd *buffhds, unsigned n)
+       }
+ }
++int fsg_common_set_num_buffers(struct fsg_common *common, unsigned int n)
++{
++      struct fsg_buffhd *bh, *buffhds;
++      int i, rc;
++
++      rc = fsg_num_buffers_validate(n);
++      if (rc != 0)
++              return rc;
++
++      buffhds = kcalloc(n, sizeof(*buffhds), GFP_KERNEL);
++      if (!buffhds)
++              return -ENOMEM;
++
++      /* Data buffers cyclic list */
++      bh = buffhds;
++      i = n;
++      goto buffhds_first_it;
++      do {
++              bh->next = bh + 1;
++              ++bh;
++buffhds_first_it:
++              bh->buf = kmalloc(FSG_BUFLEN, GFP_KERNEL);
++              if (unlikely(!bh->buf))
++                      goto error_release;
++      } while (--i);
++      bh->next = buffhds;
++
++      _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
++      common->fsg_num_buffers = n;
++      common->buffhds = buffhds;
++
++      return 0;
++
++error_release:
++      /*
++       * "buf"s pointed to by heads after n - i are NULL
++       * so releasing them won't hurt
++       */
++      _fsg_common_free_buffers(buffhds, n);
++
++      return -ENOMEM;
++}
++
+ static inline void fsg_common_remove_sysfs(struct fsg_lun *lun)
+ {
+       device_remove_file(&lun->dev, &dev_attr_nofua);
+@@ -2714,17 +2757,12 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                  struct fsg_config *cfg)
+ {
+       struct usb_gadget *gadget = cdev->gadget;
+-      struct fsg_buffhd *bh;
+       struct fsg_lun **curlun_it;
+       struct fsg_lun_config *lcfg;
+       struct usb_string *us;
+       int nluns, i, rc;
+       char *pathbuf;
+-      rc = fsg_num_buffers_validate(cfg->fsg_num_buffers);
+-      if (rc != 0)
+-              return ERR_PTR(rc);
+-
+       /* Find out how many LUNs there should be */
+       nluns = cfg->nluns;
+       if (nluns < 1 || nluns > FSG_MAX_LUNS) {
+@@ -2738,15 +2776,12 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       fsg_common_set_sysfs(common, true);
+       common->state = FSG_STATE_IDLE;
+-      common->fsg_num_buffers = cfg->fsg_num_buffers;
+-      common->buffhds = kcalloc(common->fsg_num_buffers,
+-                                sizeof *(common->buffhds), GFP_KERNEL);
+-      if (!common->buffhds) {
++      rc = fsg_common_set_num_buffers(common, cfg->fsg_num_buffers);
++      if (rc) {
+               if (common->free_storage_on_release)
+                       kfree(common);
+-              return ERR_PTR(-ENOMEM);
++              return ERR_PTR(rc);
+       }
+-
+       common->ops = cfg->ops;
+       common->private_data = cfg->private_data;
+@@ -2833,21 +2868,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       }
+       common->nluns = nluns;
+-      /* Data buffers cyclic list */
+-      bh = common->buffhds;
+-      i = common->fsg_num_buffers;
+-      goto buffhds_first_it;
+-      do {
+-              bh->next = bh + 1;
+-              ++bh;
+-buffhds_first_it:
+-              bh->buf = kmalloc(FSG_BUFLEN, GFP_KERNEL);
+-              if (unlikely(!bh->buf)) {
+-                      rc = -ENOMEM;
+-                      goto error_release;
+-              }
+-      } while (--i);
+-      bh->next = common->buffhds;
+       /* Prepare inquiryString */
+       i = get_default_bcdDevice();
+diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h
+index 1b88eae..a00f51a 100644
+--- a/drivers/usb/gadget/f_mass_storage.h
++++ b/drivers/usb/gadget/f_mass_storage.h
+@@ -104,6 +104,8 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+ void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs);
++int fsg_common_set_num_buffers(struct fsg_common *common, unsigned int n);
++
+ void fsg_config_from_params(struct fsg_config *cfg,
+                           const struct fsg_module_parameters *params,
+                           unsigned int fsg_num_buffers);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1131-usb-gadget-f_mass_storage-create-lun-handling-helper.patch b/patches.tizen/1131-usb-gadget-f_mass_storage-create-lun-handling-helper.patch
new file mode 100644 (file)
index 0000000..eeea3e8
--- /dev/null
@@ -0,0 +1,153 @@
+From 9c9c989baca50c583b20785371bc466f89b924bd Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 9 Oct 2013 10:05:56 +0200
+Subject: [PATCH 1131/1302] usb: gadget: f_mass_storage: create lun handling
+ helpers for use in fsg_common_init
+
+fsg_common_init is a lengthy function. Factor portions of it out.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 80 +++++++++++++++++++++++++++++--------
+ drivers/usb/gadget/f_mass_storage.h |  8 ++++
+ 2 files changed, 71 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 79d98997..cb789fa 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -2752,6 +2752,64 @@ static inline void fsg_common_remove_sysfs(struct fsg_lun *lun)
+       device_remove_file(&lun->dev, &dev_attr_file);
+ }
++void fsg_common_remove_lun(struct fsg_lun *lun, bool sysfs)
++{
++      if (sysfs) {
++              fsg_common_remove_sysfs(lun);
++              device_unregister(&lun->dev);
++      }
++      fsg_lun_close(lun);
++      kfree(lun);
++}
++
++static void _fsg_common_remove_luns(struct fsg_common *common, int n)
++{
++      int i;
++
++      for (i = 0; i < n; ++i)
++              if (common->luns[i]) {
++                      fsg_common_remove_lun(common->luns[i], common->sysfs);
++                      common->luns[i] = NULL;
++              }
++}
++
++void fsg_common_remove_luns(struct fsg_common *common)
++{
++      _fsg_common_remove_luns(common, common->nluns);
++}
++
++void fsg_common_free_luns(struct fsg_common *common)
++{
++      fsg_common_remove_luns(common);
++      kfree(common->luns);
++      common->luns = NULL;
++}
++
++int fsg_common_set_nluns(struct fsg_common *common, int nluns)
++{
++      struct fsg_lun **curlun;
++
++      /* Find out how many LUNs there should be */
++      if (nluns < 1 || nluns > FSG_MAX_LUNS) {
++              pr_err("invalid number of LUNs: %u\n", nluns);
++              return -EINVAL;
++      }
++
++      curlun = kcalloc(nluns, sizeof(*curlun), GFP_KERNEL);
++      if (unlikely(!curlun))
++              return -ENOMEM;
++
++      if (common->luns)
++              fsg_common_free_luns(common);
++
++      common->luns = curlun;
++      common->nluns = nluns;
++
++      pr_info("Number of LUNs=%d\n", common->nluns);
++
++      return 0;
++}
++
+ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                  struct usb_composite_dev *cdev,
+                                  struct fsg_config *cfg)
+@@ -2763,12 +2821,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       int nluns, i, rc;
+       char *pathbuf;
+-      /* Find out how many LUNs there should be */
+-      nluns = cfg->nluns;
+-      if (nluns < 1 || nluns > FSG_MAX_LUNS) {
+-              dev_err(&gadget->dev, "invalid number of LUNs: %u\n", nluns);
+-              return ERR_PTR(-EINVAL);
+-      }
+       common = fsg_common_setup(common);
+       if (IS_ERR(common))
+@@ -2798,17 +2850,12 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       }
+       fsg_intf_desc.iInterface = us[FSG_STRING_INTERFACE].id;
+-      /*
+-       * Create the LUNs, open their backing files, and register the
+-       * LUN devices in sysfs.
+-       */
+-      curlun_it = kcalloc(nluns, sizeof(*curlun_it), GFP_KERNEL);
+-      if (unlikely(!curlun_it)) {
+-              rc = -ENOMEM;
+-              goto error_release;
+-      }
+-      common->luns = curlun_it;
++      rc = fsg_common_set_nluns(common, cfg->nluns);
++      if (rc)
++              goto error_release;
++      curlun_it = common->luns;
++      nluns = cfg->nluns;
+       for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun_it, ++lcfg) {
+               struct fsg_lun *curlun;
+@@ -2866,7 +2913,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                       goto error_luns;
+               }
+       }
+-      common->nluns = nluns;
+       /* Prepare inquiryString */
+diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h
+index a00f51a..f98c792 100644
+--- a/drivers/usb/gadget/f_mass_storage.h
++++ b/drivers/usb/gadget/f_mass_storage.h
+@@ -106,6 +106,14 @@ void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs);
+ int fsg_common_set_num_buffers(struct fsg_common *common, unsigned int n);
++void fsg_common_remove_lun(struct fsg_lun *lun, bool sysfs);
++
++void fsg_common_remove_luns(struct fsg_common *common);
++
++void fsg_common_free_luns(struct fsg_common *common);
++
++int fsg_common_set_nluns(struct fsg_common *common, int nluns);
++
+ void fsg_config_from_params(struct fsg_config *cfg,
+                           const struct fsg_module_parameters *params,
+                           unsigned int fsg_num_buffers);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1132-usb-gadget-f_mass_storage-create-fsg_common_set_cdev.patch b/patches.tizen/1132-usb-gadget-f_mass_storage-create-fsg_common_set_cdev.patch
new file mode 100644 (file)
index 0000000..6eb121a
--- /dev/null
@@ -0,0 +1,118 @@
+From b56a6d0959d745a23464f33ee9ae754d6c1b4606 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 9 Oct 2013 10:05:57 +0200
+Subject: [PATCH 1132/1302] usb: gadget: f_mass_storage: create
+ fsg_common_set_cdev for use in fsg_common_init
+
+fsg_common_init is a lengthy function. Factor a portion of it out.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 50 +++++++++++++++++++++----------------
+ drivers/usb/gadget/f_mass_storage.h |  3 +++
+ 2 files changed, 32 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index cb789fa..e61c066 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -2810,6 +2810,33 @@ int fsg_common_set_nluns(struct fsg_common *common, int nluns)
+       return 0;
+ }
++int fsg_common_set_cdev(struct fsg_common *common,
++                       struct usb_composite_dev *cdev, bool can_stall)
++{
++      struct usb_string *us;
++
++      common->gadget = cdev->gadget;
++      common->ep0 = cdev->gadget->ep0;
++      common->ep0req = cdev->req;
++      common->cdev = cdev;
++
++      us = usb_gstrings_attach(cdev, fsg_strings_array,
++                               ARRAY_SIZE(fsg_strings));
++      if (IS_ERR(us))
++              return PTR_ERR(us);
++
++      fsg_intf_desc.iInterface = us[FSG_STRING_INTERFACE].id;
++
++      /*
++       * Some peripheral controllers are known not to be able to
++       * halt bulk endpoints correctly.  If one of them is present,
++       * disable stalls.
++       */
++      common->can_stall = can_stall && !(gadget_is_at91(common->gadget));
++
++      return 0;
++}
++
+ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                  struct usb_composite_dev *cdev,
+                                  struct fsg_config *cfg)
+@@ -2817,7 +2844,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       struct usb_gadget *gadget = cdev->gadget;
+       struct fsg_lun **curlun_it;
+       struct fsg_lun_config *lcfg;
+-      struct usb_string *us;
+       int nluns, i, rc;
+       char *pathbuf;
+@@ -2837,19 +2863,9 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       common->ops = cfg->ops;
+       common->private_data = cfg->private_data;
+-      common->gadget = gadget;
+-      common->ep0 = gadget->ep0;
+-      common->ep0req = cdev->req;
+-      common->cdev = cdev;
+-
+-      us = usb_gstrings_attach(cdev, fsg_strings_array,
+-                               ARRAY_SIZE(fsg_strings));
+-      if (IS_ERR(us)) {
+-              rc = PTR_ERR(us);
++      rc = fsg_common_set_cdev(common, cdev, cfg->can_stall);
++      if (rc)
+               goto error_release;
+-      }
+-      fsg_intf_desc.iInterface = us[FSG_STRING_INTERFACE].id;
+-
+       rc = fsg_common_set_nluns(common, cfg->nluns);
+       if (rc)
+@@ -2925,14 +2941,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                    : "File-Stor Gadget"),
+                i);
+-      /*
+-       * Some peripheral controllers are known not to be able to
+-       * halt bulk endpoints correctly.  If one of them is present,
+-       * disable stalls.
+-       */
+-      common->can_stall = cfg->can_stall &&
+-              !(gadget_is_at91(common->gadget));
+-
+       /* Tell the thread to start working */
+       common->thread_task =
+diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h
+index f98c792..de7aa32 100644
+--- a/drivers/usb/gadget/f_mass_storage.h
++++ b/drivers/usb/gadget/f_mass_storage.h
+@@ -106,6 +106,9 @@ void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs);
+ int fsg_common_set_num_buffers(struct fsg_common *common, unsigned int n);
++int fsg_common_set_cdev(struct fsg_common *common,
++                      struct usb_composite_dev *cdev, bool can_stall);
++
+ void fsg_common_remove_lun(struct fsg_lun *lun, bool sysfs);
+ void fsg_common_remove_luns(struct fsg_common *common);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1133-usb-gadget-f_mass_storage-create-lun-creation-helper.patch b/patches.tizen/1133-usb-gadget-f_mass_storage-create-lun-creation-helper.patch
new file mode 100644 (file)
index 0000000..0594467
--- /dev/null
@@ -0,0 +1,319 @@
+From 7177fdf56826f3d1681f07f9e015adbb4f5e98d9 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 9 Oct 2013 10:05:58 +0200
+Subject: [PATCH 1133/1302] usb: gadget: f_mass_storage: create lun creation
+ helpers for use in fsg_common_init
+
+fsg_common_init is a lengthy function. Factor portions of it out.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 238 ++++++++++++++++++++++--------------
+ drivers/usb/gadget/f_mass_storage.h |   6 +
+ 2 files changed, 153 insertions(+), 91 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index e61c066..6a67e2e 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -2837,16 +2837,154 @@ int fsg_common_set_cdev(struct fsg_common *common,
+       return 0;
+ }
++static inline int fsg_common_add_sysfs(struct fsg_common *common,
++                                     struct fsg_lun *lun)
++{
++      int rc;
++
++      rc = device_register(&lun->dev);
++      if (rc) {
++              put_device(&lun->dev);
++              return rc;
++      }
++
++      rc = device_create_file(&lun->dev,
++                              lun->cdrom
++                            ? &dev_attr_ro_cdrom
++                            : &dev_attr_ro);
++      if (rc)
++              goto error;
++      rc = device_create_file(&lun->dev,
++                              lun->removable
++                            ? &dev_attr_file
++                            : &dev_attr_file_nonremovable);
++      if (rc)
++              goto error;
++      rc = device_create_file(&lun->dev, &dev_attr_nofua);
++      if (rc)
++              goto error;
++
++      return 0;
++
++error:
++      /* removing nonexistent files is a no-op */
++      fsg_common_remove_sysfs(lun);
++      device_unregister(&lun->dev);
++      return rc;
++}
++
++int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg,
++                        unsigned int id, const char *name,
++                        const char **name_pfx)
++{
++      struct fsg_lun *lun;
++      char *pathbuf, *p;
++      int rc = -ENOMEM;
++
++      if (!common->nluns || !common->luns)
++              return -ENODEV;
++
++      if (common->luns[id])
++              return -EBUSY;
++
++      if (!cfg->filename && !cfg->removable) {
++              pr_err("no file given for LUN%d\n", id);
++              return -EINVAL;
++      }
++
++      lun = kzalloc(sizeof(*lun), GFP_KERNEL);
++      if (!lun)
++              return -ENOMEM;
++
++      lun->name_pfx = name_pfx;
++
++      lun->cdrom = !!cfg->cdrom;
++      lun->ro = cfg->cdrom || cfg->ro;
++      lun->initially_ro = lun->ro;
++      lun->removable = !!cfg->removable;
++
++      if (!common->sysfs) {
++              /* we DON'T own the name!*/
++              lun->name = name;
++      } else {
++              lun->dev.release = fsg_lun_release;
++              lun->dev.parent = &common->gadget->dev;
++              dev_set_drvdata(&lun->dev, &common->filesem);
++              dev_set_name(&lun->dev, name);
++              lun->name = dev_name(&lun->dev);
++
++              rc = fsg_common_add_sysfs(common, lun);
++              if (rc) {
++                      pr_info("failed to register LUN%d: %d\n", id, rc);
++                      goto error_sysfs;
++              }
++      }
++
++      common->luns[id] = lun;
++
++      if (cfg->filename) {
++              rc = fsg_lun_open(lun, cfg->filename);
++              if (rc)
++                      goto error_lun;
++      }
++
++      pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
++      p = "(no medium)";
++      if (fsg_lun_is_open(lun)) {
++              p = "(error)";
++              if (pathbuf) {
++                      p = d_path(&lun->filp->f_path, pathbuf, PATH_MAX);
++                      if (IS_ERR(p))
++                              p = "(error)";
++              }
++      }
++      pr_info("LUN: %s%s%sfile: %s\n",
++            lun->removable ? "removable " : "",
++            lun->ro ? "read only " : "",
++            lun->cdrom ? "CD-ROM " : "",
++            p);
++      kfree(pathbuf);
++
++      return 0;
++
++error_lun:
++      if (common->sysfs) {
++              fsg_common_remove_sysfs(lun);
++              device_unregister(&lun->dev);
++      }
++      fsg_lun_close(lun);
++      common->luns[id] = NULL;
++error_sysfs:
++      kfree(lun);
++      return rc;
++}
++
++int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg)
++{
++      char buf[8]; /* enough for 100000000 different numbers, decimal */
++      int i, rc;
++
++      for (i = 0; i < common->nluns; ++i) {
++              snprintf(buf, sizeof(buf), "lun%d", i);
++              rc = fsg_common_create_lun(common, &cfg->luns[i], i, buf, NULL);
++              if (rc)
++                      goto fail;
++      }
++
++      pr_info("Number of LUNs=%d\n", common->nluns);
++
++      return 0;
++
++fail:
++      _fsg_common_remove_luns(common, i);
++      return rc;
++}
++
+ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                  struct usb_composite_dev *cdev,
+                                  struct fsg_config *cfg)
+ {
+-      struct usb_gadget *gadget = cdev->gadget;
+-      struct fsg_lun **curlun_it;
+-      struct fsg_lun_config *lcfg;
+-      int nluns, i, rc;
+-      char *pathbuf;
+-
++      int i, rc;
+       common = fsg_common_setup(common);
+       if (IS_ERR(common))
+@@ -2870,66 +3008,10 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       rc = fsg_common_set_nluns(common, cfg->nluns);
+       if (rc)
+               goto error_release;
+-      curlun_it = common->luns;
+-      nluns = cfg->nluns;
+-      for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun_it, ++lcfg) {
+-              struct fsg_lun *curlun;
+-
+-              curlun = kzalloc(sizeof(*curlun), GFP_KERNEL);
+-              if (!curlun) {
+-                      rc = -ENOMEM;
+-                      common->nluns = i;
+-                      goto error_release;
+-              }
+-              *curlun_it = curlun;
+-
+-              curlun->cdrom = !!lcfg->cdrom;
+-              curlun->ro = lcfg->cdrom || lcfg->ro;
+-              curlun->initially_ro = curlun->ro;
+-              curlun->removable = lcfg->removable;
+-              curlun->dev.release = fsg_lun_release;
+-              curlun->dev.parent = &gadget->dev;
+-              /* curlun->dev.driver = &fsg_driver.driver; XXX */
+-              dev_set_drvdata(&curlun->dev, &common->filesem);
+-              dev_set_name(&curlun->dev, "lun%d", i);
+-              curlun->name = dev_name(&curlun->dev);
+-
+-              rc = device_register(&curlun->dev);
+-              if (rc) {
+-                      INFO(common, "failed to register LUN%d: %d\n", i, rc);
+-                      common->nluns = i;
+-                      put_device(&curlun->dev);
+-                      kfree(curlun);
+-                      goto error_release;
+-              }
+-
+-              rc = device_create_file(&curlun->dev,
+-                                      curlun->cdrom
+-                                    ? &dev_attr_ro_cdrom
+-                                    : &dev_attr_ro);
+-              if (rc)
+-                      goto error_luns;
+-              rc = device_create_file(&curlun->dev,
+-                                      curlun->removable
+-                                    ? &dev_attr_file
+-                                    : &dev_attr_file_nonremovable);
+-              if (rc)
+-                      goto error_luns;
+-              rc = device_create_file(&curlun->dev, &dev_attr_nofua);
+-              if (rc)
+-                      goto error_luns;
+-
+-              if (lcfg->filename) {
+-                      rc = fsg_lun_open(curlun, lcfg->filename);
+-                      if (rc)
+-                              goto error_luns;
+-              } else if (!curlun->removable) {
+-                      ERROR(common, "no file given for LUN%d\n", i);
+-                      rc = -EINVAL;
+-                      goto error_luns;
+-              }
+-      }
++      rc = fsg_common_create_luns(common, cfg);
++      if (rc)
++              goto error_release;
+       /* Prepare inquiryString */
+       i = get_default_bcdDevice();
+@@ -2941,7 +3023,6 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                    : "File-Stor Gadget"),
+                i);
+-
+       /* Tell the thread to start working */
+       common->thread_task =
+               kthread_create(fsg_main_thread, common, "file-storage");
+@@ -2954,37 +3035,12 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       INFO(common, FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
+       INFO(common, "Number of LUNs=%d\n", common->nluns);
+-      pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
+-      for (i = 0, nluns = common->nluns, curlun_it = common->luns;
+-           i < nluns;
+-           ++curlun_it, ++i) {
+-              struct fsg_lun *curlun = *curlun_it;
+-              char *p = "(no medium)";
+-              if (fsg_lun_is_open(curlun)) {
+-                      p = "(error)";
+-                      if (pathbuf) {
+-                              p = d_path(&curlun->filp->f_path,
+-                                         pathbuf, PATH_MAX);
+-                              if (IS_ERR(p))
+-                                      p = "(error)";
+-                      }
+-              }
+-              LINFO(curlun, "LUN: %s%s%sfile: %s\n",
+-                    curlun->removable ? "removable " : "",
+-                    curlun->ro ? "read only " : "",
+-                    curlun->cdrom ? "CD-ROM " : "",
+-                    p);
+-      }
+-      kfree(pathbuf);
+-
+       DBG(common, "I/O thread pid: %d\n", task_pid_nr(common->thread_task));
+       wake_up_process(common->thread_task);
+       return common;
+-error_luns:
+-      common->nluns = i + 1;
+ error_release:
+       common->state = FSG_STATE_TERMINATED;   /* The thread is dead */
+       /* Call fsg_common_release() directly, ref might be not initialised. */
+diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h
+index de7aa32..2a51e7b 100644
+--- a/drivers/usb/gadget/f_mass_storage.h
++++ b/drivers/usb/gadget/f_mass_storage.h
+@@ -117,6 +117,12 @@ void fsg_common_free_luns(struct fsg_common *common);
+ int fsg_common_set_nluns(struct fsg_common *common, int nluns);
++int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg,
++                        unsigned int id, const char *name,
++                        const char **name_pfx);
++
++int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg);
++
+ void fsg_config_from_params(struct fsg_config *cfg,
+                           const struct fsg_module_parameters *params,
+                           unsigned int fsg_num_buffers);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1134-usb-gadget-f_mass_storage-create-fsg_common_set_inqu.patch b/patches.tizen/1134-usb-gadget-f_mass_storage-create-fsg_common_set_inqu.patch
new file mode 100644 (file)
index 0000000..ec1c877
--- /dev/null
@@ -0,0 +1,87 @@
+From 523fb5e38a9b5bff68b4b3ad414ade8eee29dbc7 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 9 Oct 2013 10:05:59 +0200
+Subject: [PATCH 1134/1302] usb: gadget: f_mass_storage: create
+ fsg_common_set_inquiry_string for use in fsg_common_init
+
+fsg_common_init is a lengthy function. Factor a portion of it out.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 29 +++++++++++++++++++----------
+ drivers/usb/gadget/f_mass_storage.h |  3 +++
+ 2 files changed, 22 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 6a67e2e..93a26b3 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -2980,11 +2980,27 @@ fail:
+       return rc;
+ }
++void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
++                                 const char *pn)
++{
++      int i;
++
++      /* Prepare inquiryString */
++      i = get_default_bcdDevice();
++      snprintf(common->inquiry_string, sizeof(common->inquiry_string),
++               "%-8s%-16s%04x", vn ?: "Linux",
++               /* Assume product name dependent on the first LUN */
++               pn ?: ((*common->luns)->cdrom
++                   ? "File-CD Gadget"
++                   : "File-Stor Gadget"),
++               i);
++}
++
+ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                  struct usb_composite_dev *cdev,
+                                  struct fsg_config *cfg)
+ {
+-      int i, rc;
++      int rc;
+       common = fsg_common_setup(common);
+       if (IS_ERR(common))
+@@ -3013,16 +3029,9 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       if (rc)
+               goto error_release;
+-      /* Prepare inquiryString */
+-      i = get_default_bcdDevice();
+-      snprintf(common->inquiry_string, sizeof common->inquiry_string,
+-               "%-8s%-16s%04x", cfg->vendor_name ?: "Linux",
+-               /* Assume product name dependent on the first LUN */
+-               cfg->product_name ?: ((*common->luns)->cdrom
+-                                   ? "File-CD Gadget"
+-                                   : "File-Stor Gadget"),
+-               i);
++      fsg_common_set_inquiry_string(common, cfg->vendor_name,
++                                    cfg->product_name);
+       /* Tell the thread to start working */
+       common->thread_task =
+               kthread_create(fsg_main_thread, common, "file-storage");
+diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h
+index 2a51e7b..34a15d6 100644
+--- a/drivers/usb/gadget/f_mass_storage.h
++++ b/drivers/usb/gadget/f_mass_storage.h
+@@ -123,6 +123,9 @@ int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg,
+ int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg);
++void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
++                                 const char *pn);
++
+ void fsg_config_from_params(struct fsg_config *cfg,
+                           const struct fsg_module_parameters *params,
+                           unsigned int fsg_num_buffers);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1135-usb-gadget-f_mass_storage-create-fsg_common_run_thre.patch b/patches.tizen/1135-usb-gadget-f_mass_storage-create-fsg_common_run_thre.patch
new file mode 100644 (file)
index 0000000..4a7e9ec
--- /dev/null
@@ -0,0 +1,88 @@
+From 4b8fe9c2b2ba1a4f31cd0870aa0397be7982adaa Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 9 Oct 2013 10:06:00 +0200
+Subject: [PATCH 1135/1302] usb: gadget: f_mass_storage: create
+ fsg_common_run_thread for use in fsg_common_init
+
+fsg_common_init is a lengthy function. Factor a portion of it out.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 32 +++++++++++++++++++++-----------
+ drivers/usb/gadget/f_mass_storage.h |  2 ++
+ 2 files changed, 23 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 93a26b3..5b99aa1 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -2996,6 +2996,24 @@ void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
+                i);
+ }
++int fsg_common_run_thread(struct fsg_common *common)
++{
++      common->state = FSG_STATE_IDLE;
++      /* Tell the thread to start working */
++      common->thread_task =
++              kthread_create(fsg_main_thread, common, "file-storage");
++      if (IS_ERR(common->thread_task)) {
++              common->state = FSG_STATE_TERMINATED;
++              return PTR_ERR(common->thread_task);
++      }
++
++      DBG(common, "I/O thread pid: %d\n", task_pid_nr(common->thread_task));
++
++      wake_up_process(common->thread_task);
++
++      return 0;
++}
++
+ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                  struct usb_composite_dev *cdev,
+                                  struct fsg_config *cfg)
+@@ -3032,21 +3050,13 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+       fsg_common_set_inquiry_string(common, cfg->vendor_name,
+                                     cfg->product_name);
+-      /* Tell the thread to start working */
+-      common->thread_task =
+-              kthread_create(fsg_main_thread, common, "file-storage");
+-      if (IS_ERR(common->thread_task)) {
+-              rc = PTR_ERR(common->thread_task);
+-              goto error_release;
+-      }
+       /* Information */
+       INFO(common, FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
+-      INFO(common, "Number of LUNs=%d\n", common->nluns);
+-
+-      DBG(common, "I/O thread pid: %d\n", task_pid_nr(common->thread_task));
+-      wake_up_process(common->thread_task);
++      rc = fsg_common_run_thread(common);
++      if (rc)
++              goto error_release;
+       return common;
+diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h
+index 34a15d6..7d9e0bc 100644
+--- a/drivers/usb/gadget/f_mass_storage.h
++++ b/drivers/usb/gadget/f_mass_storage.h
+@@ -126,6 +126,8 @@ int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg);
+ void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
+                                  const char *pn);
++int fsg_common_run_thread(struct fsg_common *common);
++
+ void fsg_config_from_params(struct fsg_config *cfg,
+                           const struct fsg_module_parameters *params,
+                           unsigned int fsg_num_buffers);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1136-usb-gadget-f_mass_storage-convert-to-new-function-in.patch b/patches.tizen/1136-usb-gadget-f_mass_storage-convert-to-new-function-in.patch
new file mode 100644 (file)
index 0000000..112ae52
--- /dev/null
@@ -0,0 +1,487 @@
+From 82b6b4d4ade6c9bc8a1159671e4f661e48966165 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 9 Oct 2013 10:06:01 +0200
+Subject: [PATCH 1136/1302] usb: gadget: f_mass_storage: convert to new
+ function interface with backward compatibility
+
+Converting mass storage to the new function interface requires converting
+the USB mass storage's function code and its users.
+This patch converts the f_mass_storage.c to the new function interface.
+The file is now compiled into a separate usb_f_mass_storage.ko module.
+The old function interface is provided by means of a preprocessor conditional
+directives. After all users are converted, the old interface can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig          |   3 +
+ drivers/usb/gadget/Makefile         |   2 +
+ drivers/usb/gadget/acm_ms.c         |   1 +
+ drivers/usb/gadget/f_mass_storage.c | 178 +++++++++++++++++++++++++++++++-----
+ drivers/usb/gadget/f_mass_storage.h |  15 +++
+ drivers/usb/gadget/mass_storage.c   |   1 +
+ drivers/usb/gadget/multi.c          |   1 +
+ 7 files changed, 179 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index ecfcbab..99a9f04 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -540,6 +540,9 @@ config USB_F_RNDIS
+ config USB_U_MS
+       tristate
++config USB_F_MASS_STORAGE
++      tristate
++
+ choice
+       tristate "USB Gadget Drivers"
+       default USB_ETH
+diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
+index 295df78..62ccbda 100644
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -62,6 +62,8 @@ usb_f_rndis-y                        := f_rndis.o
+ obj-$(CONFIG_USB_F_RNDIS)     += usb_f_rndis.o
+ u_ms-y                                := storage_common.o
+ obj-$(CONFIG_USB_U_MS)                += u_ms.o
++usb_f_mass_storage-y          := f_mass_storage.o
++obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o
+ #
+ # USB gadget drivers
+diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c
+index 992ffb0..31aae8f 100644
+--- a/drivers/usb/gadget/acm_ms.c
++++ b/drivers/usb/gadget/acm_ms.c
+@@ -40,6 +40,7 @@
+  * the runtime footprint, and giving us at least some parts of what
+  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+  */
++#define USB_FMS_INCLUDED
+ #include "f_mass_storage.c"
+ /*-------------------------------------------------------------------------*/
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 5b99aa1..a063cd5 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -213,6 +213,7 @@
+ #include <linux/spinlock.h>
+ #include <linux/string.h>
+ #include <linux/freezer.h>
++#include <linux/module.h>
+ #include <linux/usb/ch9.h>
+ #include <linux/usb/gadget.h>
+@@ -226,6 +227,13 @@
+ #define FSG_DRIVER_DESC               "Mass Storage Function"
+ #define FSG_DRIVER_VERSION    "2009/09/11"
++/* to avoid a lot of #ifndef-#endif in the temporary compatibility layer */
++#ifndef USB_FMS_INCLUDED
++#define EXPORT_SYMBOL_GPL_IF_MODULE(m) EXPORT_SYMBOL_GPL(m);
++#else
++#define EXPORT_SYMBOL_GPL_IF_MODULE(m)
++#endif
++
+ static const char fsg_string_interface[] = "Mass Storage";
+ #include "storage_common.h"
+@@ -2627,11 +2635,13 @@ void fsg_common_get(struct fsg_common *common)
+ {
+       kref_get(&common->ref);
+ }
++EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_get);
+ void fsg_common_put(struct fsg_common *common)
+ {
+       kref_put(&common->ref, fsg_common_release);
+ }
++EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_put);
+ /* check if fsg_num_buffers is within a valid range */
+ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
+@@ -2643,7 +2653,7 @@ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
+       return -EINVAL;
+ }
+-static struct fsg_common *fsg_common_setup(struct fsg_common *common)
++static struct fsg_common *fsg_common_setup(struct fsg_common *common, bool zero)
+ {
+       if (!common) {
+               common = kzalloc(sizeof(*common), GFP_KERNEL);
+@@ -2651,7 +2661,8 @@ static struct fsg_common *fsg_common_setup(struct fsg_common *common)
+                       return ERR_PTR(-ENOMEM);
+               common->free_storage_on_release = 1;
+       } else {
+-              memset(common, 0, sizeof(*common));
++              if (zero)
++                      memset(common, 0, sizeof(*common));
+               common->free_storage_on_release = 0;
+       }
+       init_rwsem(&common->filesem);
+@@ -2668,6 +2679,7 @@ void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs)
+ {
+       common->sysfs = sysfs;
+ }
++EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_set_sysfs);
+ static void _fsg_common_free_buffers(struct fsg_buffhd *buffhds, unsigned n)
+ {
+@@ -2723,6 +2735,7 @@ error_release:
+       return -ENOMEM;
+ }
++EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_set_num_buffers);
+ static inline void fsg_common_remove_sysfs(struct fsg_lun *lun)
+ {
+@@ -2761,6 +2774,7 @@ void fsg_common_remove_lun(struct fsg_lun *lun, bool sysfs)
+       fsg_lun_close(lun);
+       kfree(lun);
+ }
++EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_remove_lun);
+ static void _fsg_common_remove_luns(struct fsg_common *common, int n)
+ {
+@@ -2772,6 +2786,7 @@ static void _fsg_common_remove_luns(struct fsg_common *common, int n)
+                       common->luns[i] = NULL;
+               }
+ }
++EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_remove_luns);
+ void fsg_common_remove_luns(struct fsg_common *common)
+ {
+@@ -2784,6 +2799,7 @@ void fsg_common_free_luns(struct fsg_common *common)
+       kfree(common->luns);
+       common->luns = NULL;
+ }
++EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_free_luns);
+ int fsg_common_set_nluns(struct fsg_common *common, int nluns)
+ {
+@@ -2809,6 +2825,14 @@ int fsg_common_set_nluns(struct fsg_common *common, int nluns)
+       return 0;
+ }
++EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_set_nluns);
++
++void fsg_common_free_buffers(struct fsg_common *common)
++{
++      _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
++      common->buffhds = NULL;
++}
++EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_free_buffers);
+ int fsg_common_set_cdev(struct fsg_common *common,
+                        struct usb_composite_dev *cdev, bool can_stall)
+@@ -2836,6 +2860,7 @@ int fsg_common_set_cdev(struct fsg_common *common,
+       return 0;
+ }
++EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_set_cdev);
+ static inline int fsg_common_add_sysfs(struct fsg_common *common,
+                                      struct fsg_lun *lun)
+@@ -2958,6 +2983,7 @@ error_sysfs:
+       kfree(lun);
+       return rc;
+ }
++EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_create_lun);
+ int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg)
+ {
+@@ -2979,6 +3005,7 @@ fail:
+       _fsg_common_remove_luns(common, i);
+       return rc;
+ }
++EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_create_luns);
+ void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
+                                  const char *pn)
+@@ -2995,6 +3022,7 @@ void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
+                    : "File-Stor Gadget"),
+                i);
+ }
++EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_set_inquiry_string);
+ int fsg_common_run_thread(struct fsg_common *common)
+ {
+@@ -3013,6 +3041,7 @@ int fsg_common_run_thread(struct fsg_common *common)
+       return 0;
+ }
++EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_run_thread);
+ struct fsg_common *fsg_common_init(struct fsg_common *common,
+                                  struct usb_composite_dev *cdev,
+@@ -3020,7 +3049,7 @@ struct fsg_common *fsg_common_init(struct fsg_common *common,
+ {
+       int rc;
+-      common = fsg_common_setup(common);
++      common = fsg_common_setup(common, !!common);
+       if (IS_ERR(common))
+               return common;
+       fsg_common_set_sysfs(common, true);
+@@ -3066,6 +3095,7 @@ error_release:
+       fsg_common_release(&common->ref);
+       return ERR_PTR(rc);
+ }
++EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_init);
+ static void fsg_common_release(struct kref *ref)
+ {
+@@ -3105,24 +3135,6 @@ static void fsg_common_release(struct kref *ref)
+ /*-------------------------------------------------------------------------*/
+-static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
+-{
+-      struct fsg_dev          *fsg = fsg_from_func(f);
+-      struct fsg_common       *common = fsg->common;
+-
+-      DBG(fsg, "unbind\n");
+-      if (fsg->common->fsg == fsg) {
+-              fsg->common->new_fsg = NULL;
+-              raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
+-              /* FIXME: make interruptible or killable somehow? */
+-              wait_event(common->fsg_wait, common->fsg != fsg);
+-      }
+-
+-      fsg_common_put(common);
+-      usb_free_all_descriptors(&fsg->function);
+-      kfree(fsg);
+-}
+-
+ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
+ {
+       struct fsg_dev          *fsg = fsg_from_func(f);
+@@ -3132,6 +3144,21 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
+       unsigned                max_burst;
+       int                     ret;
++#ifndef USB_FMS_INCLUDED
++      struct fsg_opts         *opts;
++      opts = fsg_opts_from_func_inst(f->fi);
++      if (!opts->no_configfs) {
++              ret = fsg_common_set_cdev(fsg->common, c->cdev,
++                                        fsg->common->can_stall);
++              if (ret)
++                      return ret;
++              fsg_common_set_inquiry_string(fsg->common, 0, 0);
++              ret = fsg_common_run_thread(fsg->common);
++              if (ret)
++                      return ret;
++      }
++#endif
++
+       fsg->gadget = gadget;
+       /* New interface */
+@@ -3183,7 +3210,31 @@ autoconf_fail:
+       return -ENOTSUPP;
+ }
+-/****************************** ADD FUNCTION ******************************/
++/****************************** ALLOCATE FUNCTION *************************/
++
++static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
++{
++      struct fsg_dev          *fsg = fsg_from_func(f);
++      struct fsg_common       *common = fsg->common;
++
++      DBG(fsg, "unbind\n");
++      if (fsg->common->fsg == fsg) {
++              fsg->common->new_fsg = NULL;
++              raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
++              /* FIXME: make interruptible or killable somehow? */
++              wait_event(common->fsg_wait, common->fsg != fsg);
++      }
++
++#ifdef USB_FMS_INCLUDED
++      fsg_common_put(common);
++#endif
++      usb_free_all_descriptors(&fsg->function);
++#ifdef USB_FMS_INCLUDED
++      kfree(fsg);
++#endif
++}
++
++#ifdef USB_FMS_INCLUDED
+ static int fsg_bind_config(struct usb_composite_dev *cdev,
+                          struct usb_configuration *c,
+@@ -3220,6 +3271,88 @@ static int fsg_bind_config(struct usb_composite_dev *cdev,
+       return rc;
+ }
++#else
++
++static void fsg_free_inst(struct usb_function_instance *fi)
++{
++      struct fsg_opts *opts;
++
++      opts = fsg_opts_from_func_inst(fi);
++      fsg_common_put(opts->common);
++      kfree(opts);
++}
++
++static struct usb_function_instance *fsg_alloc_inst(void)
++{
++      struct fsg_opts *opts;
++      int rc;
++
++      opts = kzalloc(sizeof(*opts), GFP_KERNEL);
++      if (!opts)
++              return ERR_PTR(-ENOMEM);
++      opts->func_inst.free_func_inst = fsg_free_inst;
++      opts->common = fsg_common_setup(opts->common, false);
++      if (IS_ERR(opts->common)) {
++              rc = PTR_ERR(opts->common);
++              goto release_opts;
++      }
++      rc = fsg_common_set_nluns(opts->common, FSG_MAX_LUNS);
++      if (rc)
++              goto release_opts;
++
++      rc = fsg_common_set_num_buffers(opts->common,
++                                      CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS);
++      if (rc)
++              goto release_luns;
++
++      pr_info(FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
++
++      return &opts->func_inst;
++
++release_luns:
++      kfree(opts->common->luns);
++release_opts:
++      kfree(opts);
++      return ERR_PTR(rc);
++}
++
++static void fsg_free(struct usb_function *f)
++{
++      struct fsg_dev *fsg;
++
++      fsg = container_of(f, struct fsg_dev, function);
++
++      kfree(fsg);
++}
++
++static struct usb_function *fsg_alloc(struct usb_function_instance *fi)
++{
++      struct fsg_opts *opts = fsg_opts_from_func_inst(fi);
++      struct fsg_common *common = opts->common;
++      struct fsg_dev *fsg;
++
++      fsg = kzalloc(sizeof(*fsg), GFP_KERNEL);
++      if (unlikely(!fsg))
++              return ERR_PTR(-ENOMEM);
++
++      fsg->function.name      = FSG_DRIVER_DESC;
++      fsg->function.bind      = fsg_bind;
++      fsg->function.unbind    = fsg_unbind;
++      fsg->function.setup     = fsg_setup;
++      fsg->function.set_alt   = fsg_set_alt;
++      fsg->function.disable   = fsg_disable;
++      fsg->function.free_func = fsg_free;
++
++      fsg->common               = common;
++
++      return &fsg->function;
++}
++
++DECLARE_USB_FUNCTION_INIT(mass_storage, fsg_alloc_inst, fsg_alloc);
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Michal Nazarewicz");
++
++#endif
+ /************************* Module parameters *************************/
+@@ -3256,4 +3389,5 @@ void fsg_config_from_params(struct fsg_config *cfg,
+       cfg->can_stall = params->stall;
+       cfg->fsg_num_buffers = fsg_num_buffers;
+ }
++EXPORT_SYMBOL_GPL_IF_MODULE(fsg_config_from_params);
+diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h
+index 7d9e0bc..42f7db4 100644
+--- a/drivers/usb/gadget/f_mass_storage.h
++++ b/drivers/usb/gadget/f_mass_storage.h
+@@ -1,6 +1,7 @@
+ #ifndef USB_F_MASS_STORAGE_H
+ #define USB_F_MASS_STORAGE_H
++#include <linux/usb/composite.h>
+ #include "storage_common.h"
+ struct fsg_module_parameters {
+@@ -70,6 +71,12 @@ struct fsg_operations {
+       int (*thread_exits)(struct fsg_common *common);
+ };
++struct fsg_opts {
++      struct fsg_common *common;
++      struct usb_function_instance func_inst;
++      bool no_configfs; /* for legacy gadgets */
++};
++
+ struct fsg_lun_config {
+       const char *filename;
+       char ro;
+@@ -94,6 +101,12 @@ struct fsg_config {
+       unsigned int            fsg_num_buffers;
+ };
++static inline struct fsg_opts *
++fsg_opts_from_func_inst(const struct usb_function_instance *fi)
++{
++      return container_of(fi, struct fsg_opts, func_inst);
++}
++
+ void fsg_common_get(struct fsg_common *common);
+ void fsg_common_put(struct fsg_common *common);
+@@ -106,6 +119,8 @@ void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs);
+ int fsg_common_set_num_buffers(struct fsg_common *common, unsigned int n);
++void fsg_common_free_buffers(struct fsg_common *common);
++
+ int fsg_common_set_cdev(struct fsg_common *common,
+                       struct usb_composite_dev *cdev, bool can_stall);
+diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c
+index 4723d1b..f670251 100644
+--- a/drivers/usb/gadget/mass_storage.c
++++ b/drivers/usb/gadget/mass_storage.c
+@@ -55,6 +55,7 @@
+  * the runtime footprint, and giving us at least some parts of what
+  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+  */
++#define USB_FMS_INCLUDED
+ #include "f_mass_storage.c"
+ /*-------------------------------------------------------------------------*/
+diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
+index 6867d9d..42a5bed 100644
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -41,6 +41,7 @@ MODULE_LICENSE("GPL");
+  * the runtime footprint, and giving us at least some parts of what
+  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+  */
++#define USB_FMS_INCLUDED
+ #include "f_mass_storage.c"
+ #define USBF_ECM_INCLUDED
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1137-usb-gadget-mass_storage-convert-to-new-interface-of-.patch b/patches.tizen/1137-usb-gadget-mass_storage-convert-to-new-interface-of-.patch
new file mode 100644 (file)
index 0000000..651ea11
--- /dev/null
@@ -0,0 +1,240 @@
+From 28673968fdcf31c31f04b0f7f2ed11a97c7929c6 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 9 Oct 2013 10:06:02 +0200
+Subject: [PATCH 1137/1302] usb: gadget: mass_storage: convert to new interface
+ of f_mass_storage
+
+Convert old mass_storage gadget to use the new interface of f_mass_storage
+so that later the compatibility layer in f_mass_storage can be removed.
+
+struct fsg_common is not known to mass_storage.c, so a setter method
+is added to f_mass_storage.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig          |   1 +
+ drivers/usb/gadget/f_mass_storage.c |   7 +++
+ drivers/usb/gadget/f_mass_storage.h |   3 +
+ drivers/usb/gadget/mass_storage.c   | 107 +++++++++++++++++++++++++++---------
+ 4 files changed, 91 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 99a9f04..6214b79 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -897,6 +897,7 @@ config USB_MASS_STORAGE
+       depends on BLOCK
+       select USB_LIBCOMPOSITE
+       select USB_U_MS
++      select USB_F_MASS_STORAGE
+       help
+         The Mass Storage Gadget acts as a USB Mass Storage disk drive.
+         As its storage repository it can use a regular file or a block
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index a063cd5..d6c2da0 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -2827,6 +2827,13 @@ int fsg_common_set_nluns(struct fsg_common *common, int nluns)
+ }
+ EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_set_nluns);
++void fsg_common_set_ops(struct fsg_common *common,
++                      const struct fsg_operations *ops)
++{
++      common->ops = ops;
++}
++EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_set_ops);
++
+ void fsg_common_free_buffers(struct fsg_common *common)
+ {
+       _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
+diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h
+index 42f7db4..b53cf8c 100644
+--- a/drivers/usb/gadget/f_mass_storage.h
++++ b/drivers/usb/gadget/f_mass_storage.h
+@@ -132,6 +132,9 @@ void fsg_common_free_luns(struct fsg_common *common);
+ int fsg_common_set_nluns(struct fsg_common *common, int nluns);
++void fsg_common_set_ops(struct fsg_common *common,
++                      const struct fsg_operations *ops);
++
+ int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg,
+                         unsigned int id, const char *name,
+                         const char **name_pfx);
+diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c
+index f670251..8e27a8c 100644
+--- a/drivers/usb/gadget/mass_storage.c
++++ b/drivers/usb/gadget/mass_storage.c
+@@ -46,17 +46,7 @@
+ #define FSG_VENDOR_ID 0x0525  /* NetChip */
+ #define FSG_PRODUCT_ID        0xa4a5  /* Linux-USB File-backed Storage Gadget */
+-/*-------------------------------------------------------------------------*/
+-
+-/*
+- * kbuild is not very cooperative with respect to linking separately
+- * compiled library objects into one module.  So for now we won't use
+- * separate compilation ... ensuring init/exit sections work to shrink
+- * the runtime footprint, and giving us at least some parts of what
+- * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+- */
+-#define USB_FMS_INCLUDED
+-#include "f_mass_storage.c"
++#include "f_mass_storage.h"
+ /*-------------------------------------------------------------------------*/
+ USB_GADGET_COMPOSITE_OPTIONS();
+@@ -107,6 +97,9 @@ static struct usb_gadget_strings *dev_strings[] = {
+       NULL,
+ };
++static struct usb_function_instance *fi_msg;
++static struct usb_function *f_msg;
++
+ /****************************** Configurations ******************************/
+ static struct fsg_module_parameters mod_data = {
+@@ -139,13 +132,7 @@ static int msg_thread_exits(struct fsg_common *common)
+ static int __init msg_do_config(struct usb_configuration *c)
+ {
+-      static const struct fsg_operations ops = {
+-              .thread_exits = msg_thread_exits,
+-      };
+-      static struct fsg_common common;
+-
+-      struct fsg_common *retp;
+-      struct fsg_config config;
++      struct fsg_opts *opts;
+       int ret;
+       if (gadget_is_otg(c->cdev->gadget)) {
+@@ -153,15 +140,24 @@ static int __init msg_do_config(struct usb_configuration *c)
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+-      fsg_config_from_params(&config, &mod_data, fsg_num_buffers);
+-      config.ops = &ops;
++      opts = fsg_opts_from_func_inst(fi_msg);
++
++      f_msg = usb_get_function(fi_msg);
++      if (IS_ERR(f_msg))
++              return PTR_ERR(f_msg);
+-      retp = fsg_common_init(&common, c->cdev, &config);
+-      if (IS_ERR(retp))
+-              return PTR_ERR(retp);
++      ret = fsg_common_run_thread(opts->common);
++      if (ret)
++              goto put_func;
+-      ret = fsg_bind_config(c->cdev, c, &common);
+-      fsg_common_put(&common);
++      ret = usb_add_function(c, f_msg);
++      if (ret)
++              goto put_func;
++
++      return 0;
++
++put_func:
++      usb_put_function(f_msg);
+       return ret;
+ }
+@@ -176,23 +172,79 @@ static struct usb_configuration msg_config_driver = {
+ static int __init msg_bind(struct usb_composite_dev *cdev)
+ {
++      static const struct fsg_operations ops = {
++              .thread_exits = msg_thread_exits,
++      };
++      struct fsg_opts *opts;
++      struct fsg_config config;
+       int status;
++      fi_msg = usb_get_function_instance("mass_storage");
++      if (IS_ERR(fi_msg))
++              return PTR_ERR(fi_msg);
++
++      fsg_config_from_params(&config, &mod_data, fsg_num_buffers);
++      opts = fsg_opts_from_func_inst(fi_msg);
++
++      opts->no_configfs = true;
++      status = fsg_common_set_num_buffers(opts->common, fsg_num_buffers);
++      if (status)
++              goto fail;
++
++      status = fsg_common_set_nluns(opts->common, config.nluns);
++      if (status)
++              goto fail_set_nluns;
++
++      fsg_common_set_ops(opts->common, &ops);
++
++      status = fsg_common_set_cdev(opts->common, cdev, config.can_stall);
++      if (status)
++              goto fail_set_cdev;
++
++      fsg_common_set_sysfs(opts->common, true);
++      status = fsg_common_create_luns(opts->common, &config);
++      if (status)
++              goto fail_set_cdev;
++
++      fsg_common_set_inquiry_string(opts->common, config.vendor_name,
++                                    config.product_name);
++
+       status = usb_string_ids_tab(cdev, strings_dev);
+       if (status < 0)
+-              return status;
++              goto fail_string_ids;
+       msg_device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id;
+       status = usb_add_config(cdev, &msg_config_driver, msg_do_config);
+       if (status < 0)
+-              return status;
++              goto fail_string_ids;
++
+       usb_composite_overwrite_options(cdev, &coverwrite);
+       dev_info(&cdev->gadget->dev,
+                DRIVER_DESC ", version: " DRIVER_VERSION "\n");
+       set_bit(0, &msg_registered);
+       return 0;
++
++fail_string_ids:
++      fsg_common_remove_luns(opts->common);
++fail_set_cdev:
++      fsg_common_free_luns(opts->common);
++fail_set_nluns:
++      fsg_common_free_buffers(opts->common);
++fail:
++      usb_put_function_instance(fi_msg);
++      return status;
+ }
++static int msg_unbind(struct usb_composite_dev *cdev)
++{
++      if (!IS_ERR(f_msg))
++              usb_put_function(f_msg);
++
++      if (!IS_ERR(fi_msg))
++              usb_put_function_instance(fi_msg);
++
++      return 0;
++}
+ /****************************** Some noise ******************************/
+@@ -203,6 +255,7 @@ static __refdata struct usb_composite_driver msg_driver = {
+       .needs_serial   = 1,
+       .strings        = dev_strings,
+       .bind           = msg_bind,
++      .unbind         = msg_unbind,
+ };
+ MODULE_DESCRIPTION(DRIVER_DESC);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1138-usb-gadget-storage_common-make-attribute-operations-.patch b/patches.tizen/1138-usb-gadget-storage_common-make-attribute-operations-.patch
new file mode 100644 (file)
index 0000000..4726b65
--- /dev/null
@@ -0,0 +1,217 @@
+From 219aa3514e98ed0e2c7063154734022e27dbc0bb Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 9 Oct 2013 10:06:03 +0200
+Subject: [PATCH 1138/1302] usb: gadget: storage_common: make attribute
+ operations more generic
+
+Show/store methods for sysfs attributes contain code which can be used
+also by configfs. Make them abstract the source the lun and rw_semaphore
+are taken from.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 27 +++++++++++++++++++++------
+ drivers/usb/gadget/storage_common.c | 31 ++++++-------------------------
+ drivers/usb/gadget/storage_common.h | 21 +++++++++++----------
+ 3 files changed, 38 insertions(+), 41 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index d6c2da0..d80be5f 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -2581,37 +2581,52 @@ static int fsg_main_thread(void *common_)
+ static ssize_t ro_show(struct device *dev, struct device_attribute *attr, char *buf)
+ {
+-      return fsg_show_ro(dev, attr, buf);
++      struct fsg_lun          *curlun = fsg_lun_from_dev(dev);
++
++      return fsg_show_ro(curlun, buf);
+ }
+ static ssize_t nofua_show(struct device *dev, struct device_attribute *attr,
+                         char *buf)
+ {
+-      return fsg_show_nofua(dev, attr, buf);
++      struct fsg_lun          *curlun = fsg_lun_from_dev(dev);
++
++      return fsg_show_nofua(curlun, buf);
+ }
+ static ssize_t file_show(struct device *dev, struct device_attribute *attr,
+                        char *buf)
+ {
+-      return fsg_show_file(dev, attr, buf);
++      struct fsg_lun          *curlun = fsg_lun_from_dev(dev);
++      struct rw_semaphore     *filesem = dev_get_drvdata(dev);
++
++      return fsg_show_file(curlun, filesem, buf);
+ }
+ static ssize_t ro_store(struct device *dev, struct device_attribute *attr,
+                       const char *buf, size_t count)
+ {
+-      return fsg_store_ro(dev, attr, buf, count);
++      struct fsg_lun          *curlun = fsg_lun_from_dev(dev);
++      struct rw_semaphore     *filesem = dev_get_drvdata(dev);
++
++      return fsg_store_ro(curlun, filesem, buf, count);
+ }
+ static ssize_t nofua_store(struct device *dev, struct device_attribute *attr,
+                          const char *buf, size_t count)
+ {
+-      return fsg_store_nofua(dev, attr, buf, count);
++      struct fsg_lun          *curlun = fsg_lun_from_dev(dev);
++
++      return fsg_store_nofua(curlun, buf, count);
+ }
+ static ssize_t file_store(struct device *dev, struct device_attribute *attr,
+                         const char *buf, size_t count)
+ {
+-      return fsg_store_file(dev, attr, buf, count);
++      struct fsg_lun          *curlun = fsg_lun_from_dev(dev);
++      struct rw_semaphore     *filesem = dev_get_drvdata(dev);
++
++      return fsg_store_file(curlun, filesem, buf, count);
+ }
+ static DEVICE_ATTR_RW(ro);
+diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
+index 3e2500f..969948d 100644
+--- a/drivers/usb/gadget/storage_common.c
++++ b/drivers/usb/gadget/storage_common.c
+@@ -31,11 +31,6 @@
+ #include "storage_common.h"
+-static inline struct fsg_lun *fsg_lun_from_dev(struct device *dev)
+-{
+-      return container_of(dev, struct fsg_lun, dev);
+-}
+-
+ /* There is only one interface. */
+ struct usb_interface_descriptor fsg_intf_desc = {
+@@ -324,31 +319,23 @@ EXPORT_SYMBOL(store_cdrom_address);
+ /*-------------------------------------------------------------------------*/
+-ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr,
+-                  char *buf)
++ssize_t fsg_show_ro(struct fsg_lun *curlun, char *buf)
+ {
+-      struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+-
+       return sprintf(buf, "%d\n", fsg_lun_is_open(curlun)
+                                 ? curlun->ro
+                                 : curlun->initially_ro);
+ }
+ EXPORT_SYMBOL(fsg_show_ro);
+-ssize_t fsg_show_nofua(struct device *dev, struct device_attribute *attr,
+-                     char *buf)
++ssize_t fsg_show_nofua(struct fsg_lun *curlun, char *buf)
+ {
+-      struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+-
+       return sprintf(buf, "%u\n", curlun->nofua);
+ }
+ EXPORT_SYMBOL(fsg_show_nofua);
+-ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
++ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                     char *buf)
+ {
+-      struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+-      struct rw_semaphore     *filesem = dev_get_drvdata(dev);
+       char            *p;
+       ssize_t         rc;
+@@ -373,12 +360,10 @@ ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
+ EXPORT_SYMBOL(fsg_show_file);
+-ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr,
++ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                    const char *buf, size_t count)
+ {
+       ssize_t         rc;
+-      struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+-      struct rw_semaphore     *filesem = dev_get_drvdata(dev);
+       unsigned        ro;
+       rc = kstrtouint(buf, 2, &ro);
+@@ -404,10 +389,8 @@ ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr,
+ }
+ EXPORT_SYMBOL(fsg_store_ro);
+-ssize_t fsg_store_nofua(struct device *dev, struct device_attribute *attr,
+-                      const char *buf, size_t count)
++ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count)
+ {
+-      struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+       unsigned        nofua;
+       int             ret;
+@@ -425,11 +408,9 @@ ssize_t fsg_store_nofua(struct device *dev, struct device_attribute *attr,
+ }
+ EXPORT_SYMBOL(fsg_store_nofua);
+-ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr,
++ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                      const char *buf, size_t count)
+ {
+-      struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
+-      struct rw_semaphore     *filesem = dev_get_drvdata(dev);
+       int             rc = 0;
+       if (curlun->prevent_medium_removal && fsg_lun_is_open(curlun)) {
+diff --git a/drivers/usb/gadget/storage_common.h b/drivers/usb/gadget/storage_common.h
+index d8cc090..16cf07b 100644
+--- a/drivers/usb/gadget/storage_common.h
++++ b/drivers/usb/gadget/storage_common.h
+@@ -181,6 +181,11 @@ static inline u32 get_unaligned_be24(u8 *buf)
+       return 0xffffff & (u32) get_unaligned_be32(buf - 1);
+ }
++static inline struct fsg_lun *fsg_lun_from_dev(struct device *dev)
++{
++      return container_of(dev, struct fsg_lun, dev);
++}
++
+ enum {
+       FSG_STRING_INTERFACE
+ };
+@@ -205,18 +210,14 @@ void fsg_lun_close(struct fsg_lun *curlun);
+ int fsg_lun_open(struct fsg_lun *curlun, const char *filename);
+ int fsg_lun_fsync_sub(struct fsg_lun *curlun);
+ void store_cdrom_address(u8 *dest, int msf, u32 addr);
+-ssize_t fsg_show_ro(struct device *dev, struct device_attribute *attr,
+-                  char *buf);
+-ssize_t fsg_show_nofua(struct device *dev, struct device_attribute *attr,
+-                     char *buf);
+-ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
++ssize_t fsg_show_ro(struct fsg_lun *curlun, char *buf);
++ssize_t fsg_show_nofua(struct fsg_lun *curlun, char *buf);
++ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                     char *buf);
+-ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr,
++ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                    const char *buf, size_t count);
+-ssize_t fsg_store_nofua(struct device *dev,
+-                      struct device_attribute *attr,
+-                      const char *buf, size_t count);
+-ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr,
++ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count);
++ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                      const char *buf, size_t count);
+ #endif /* USB_STORAGE_COMMON_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1139-usb-gadget-storage_common-add-methods-to-show-store-.patch b/patches.tizen/1139-usb-gadget-storage_common-add-methods-to-show-store-.patch
new file mode 100644 (file)
index 0000000..894bb58
--- /dev/null
@@ -0,0 +1,98 @@
+From d6bc6adee8be77ec8e29d031dfcdc5311ad64fa4 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 9 Oct 2013 10:06:04 +0200
+Subject: [PATCH 1139/1302] usb: gadget: storage_common: add methods to
+ show/store 'cdrom' and 'removable'
+
+This will be required by configfs integration.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/storage_common.c | 42 +++++++++++++++++++++++++++++++++++++
+ drivers/usb/gadget/storage_common.h |  5 +++++
+ 2 files changed, 47 insertions(+)
+
+diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
+index 969948d..c7b78a1 100644
+--- a/drivers/usb/gadget/storage_common.c
++++ b/drivers/usb/gadget/storage_common.c
+@@ -359,6 +359,17 @@ ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+ }
+ EXPORT_SYMBOL(fsg_show_file);
++ssize_t fsg_show_cdrom(struct fsg_lun *curlun, char *buf)
++{
++      return sprintf(buf, "%u\n", curlun->cdrom);
++}
++EXPORT_SYMBOL(fsg_show_cdrom);
++
++ssize_t fsg_show_removable(struct fsg_lun *curlun, char *buf)
++{
++      return sprintf(buf, "%u\n", curlun->removable);
++}
++EXPORT_SYMBOL(fsg_show_removable);
+ ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                    const char *buf, size_t count)
+@@ -439,4 +450,35 @@ ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+ }
+ EXPORT_SYMBOL(fsg_store_file);
++ssize_t fsg_store_cdrom(struct fsg_lun *curlun, const char *buf, size_t count)
++{
++      unsigned        cdrom;
++      int             ret;
++
++      ret = kstrtouint(buf, 2, &cdrom);
++      if (ret)
++              return ret;
++
++      curlun->cdrom = cdrom;
++
++      return count;
++}
++EXPORT_SYMBOL(fsg_store_cdrom);
++
++ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf,
++                          size_t count)
++{
++      unsigned        removable;
++      int             ret;
++
++      ret = kstrtouint(buf, 2, &removable);
++      if (ret)
++              return ret;
++
++      curlun->removable = removable;
++
++      return count;
++}
++EXPORT_SYMBOL(fsg_store_removable);
++
+ MODULE_LICENSE("GPL");
+diff --git a/drivers/usb/gadget/storage_common.h b/drivers/usb/gadget/storage_common.h
+index 16cf07b..e0f7aa6 100644
+--- a/drivers/usb/gadget/storage_common.h
++++ b/drivers/usb/gadget/storage_common.h
+@@ -214,10 +214,15 @@ ssize_t fsg_show_ro(struct fsg_lun *curlun, char *buf);
+ ssize_t fsg_show_nofua(struct fsg_lun *curlun, char *buf);
+ ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                     char *buf);
++ssize_t fsg_show_cdrom(struct fsg_lun *curlun, char *buf);
++ssize_t fsg_show_removable(struct fsg_lun *curlun, char *buf);
+ ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                    const char *buf, size_t count);
+ ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count);
+ ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                      const char *buf, size_t count);
++ssize_t fsg_store_cdrom(struct fsg_lun *curlun, const char *buf, size_t count);
++ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf,
++                          size_t count);
+ #endif /* USB_STORAGE_COMMON_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1140-usb-gadget-f_mass_storage-add-configfs-support.patch b/patches.tizen/1140-usb-gadget-f_mass_storage-add-configfs-support.patch
new file mode 100644 (file)
index 0000000..ef55e17
--- /dev/null
@@ -0,0 +1,526 @@
+From 8fc023846b2c3d6d8c779ebd9ed354e518d42b1d Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 9 Oct 2013 10:06:05 +0200
+Subject: [PATCH 1140/1302] usb: gadget: f_mass_storage: add configfs support
+
+From this commit on f_mass_storage is available through configfs.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../ABI/testing/configfs-usb-gadget-mass-storage   |  31 ++
+ drivers/usb/gadget/Kconfig                         |  11 +
+ drivers/usb/gadget/f_mass_storage.c                | 360 +++++++++++++++++++++
+ drivers/usb/gadget/f_mass_storage.h                |  17 +
+ 4 files changed, 419 insertions(+)
+ create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-mass-storage
+
+diff --git a/Documentation/ABI/testing/configfs-usb-gadget-mass-storage b/Documentation/ABI/testing/configfs-usb-gadget-mass-storage
+new file mode 100644
+index 0000000..ad72a37
+--- /dev/null
++++ b/Documentation/ABI/testing/configfs-usb-gadget-mass-storage
+@@ -0,0 +1,31 @@
++What:         /config/usb-gadget/gadget/functions/mass_storage.name
++Date:         Oct 2013
++KenelVersion: 3.13
++Description:
++              The attributes:
++
++              stall           - Set to permit function to halt bulk endpoints.
++                              Disabled on some USB devices known not to work
++                              correctly. You should set it to true.
++              num_buffers     - Number of pipeline buffers. Valid numbers
++                              are 2..4. Available only if
++                              CONFIG_USB_GADGET_DEBUG_FILES is set.
++
++What:         /config/usb-gadget/gadget/functions/mass_storage.name/lun.name
++Date:         Oct 2013
++KenelVersion: 3.13
++Description:
++              The attributes:
++
++              file            - The path to the backing file for the LUN.
++                              Required if LUN is not marked as removable.
++              ro              - Flag specifying access to the LUN shall be
++                              read-only. This is implied if CD-ROM emulation
++                              is enabled as well as when it was impossible
++                              to open "filename" in R/W mode.
++              removable       - Flag specifying that LUN shall be indicated as
++                              being removable.
++              cdrom           - Flag specifying that LUN shall be reported as
++                              being a CD-ROM.
++              nofua           - Flag specifying that FUA flag
++                              in SCSI WRITE(10,12)
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 6214b79..bef6e86 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -680,6 +680,17 @@ config USB_CONFIGFS_PHONET
+       help
+         The Phonet protocol implementation for USB device.
++config USB_CONFIGFS_MASS_STORAGE
++      boolean "Mass storage"
++      depends on USB_CONFIGFS
++      select USB_U_MS
++      select USB_F_MASS_STORAGE
++      help
++        The Mass Storage Gadget acts as a USB Mass Storage disk drive.
++        As its storage repository it can use a regular file or a block
++        device (in much the same way as the "loop" device driver),
++        specified as a module parameter or sysfs option.
++
+ config USB_ZERO
+       tristate "Gadget Zero (DEVELOPMENT)"
+       select USB_LIBCOMPOSITE
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index d80be5f..00d3687 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -220,6 +220,7 @@
+ #include <linux/usb/composite.h>
+ #include "gadget_chips.h"
++#include "configfs.h"
+ /*------------------------------------------------------------------------*/
+@@ -3295,6 +3296,342 @@ static int fsg_bind_config(struct usb_composite_dev *cdev,
+ #else
++static inline struct fsg_lun_opts *to_fsg_lun_opts(struct config_item *item)
++{
++      return container_of(to_config_group(item), struct fsg_lun_opts, group);
++}
++
++static inline struct fsg_opts *to_fsg_opts(struct config_item *item)
++{
++      return container_of(to_config_group(item), struct fsg_opts,
++                          func_inst.group);
++}
++
++CONFIGFS_ATTR_STRUCT(fsg_lun_opts);
++CONFIGFS_ATTR_OPS(fsg_lun_opts);
++
++static void fsg_lun_attr_release(struct config_item *item)
++{
++      struct fsg_lun_opts *lun_opts;
++
++      lun_opts = to_fsg_lun_opts(item);
++      kfree(lun_opts);
++}
++
++static struct configfs_item_operations fsg_lun_item_ops = {
++      .release        = fsg_lun_attr_release,
++      .show_attribute = fsg_lun_opts_attr_show,
++      .store_attribute = fsg_lun_opts_attr_store,
++};
++
++static ssize_t fsg_lun_opts_file_show(struct fsg_lun_opts *opts, char *page)
++{
++      struct fsg_opts *fsg_opts;
++
++      fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
++
++      return fsg_show_file(opts->lun, &fsg_opts->common->filesem, page);
++}
++
++static ssize_t fsg_lun_opts_file_store(struct fsg_lun_opts *opts,
++                                     const char *page, size_t len)
++{
++      struct fsg_opts *fsg_opts;
++
++      fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
++
++      return fsg_store_file(opts->lun, &fsg_opts->common->filesem, page, len);
++}
++
++static struct fsg_lun_opts_attribute fsg_lun_opts_file =
++      __CONFIGFS_ATTR(file, S_IRUGO | S_IWUSR, fsg_lun_opts_file_show,
++                      fsg_lun_opts_file_store);
++
++static ssize_t fsg_lun_opts_ro_show(struct fsg_lun_opts *opts, char *page)
++{
++      return fsg_show_ro(opts->lun, page);
++}
++
++static ssize_t fsg_lun_opts_ro_store(struct fsg_lun_opts *opts,
++                                     const char *page, size_t len)
++{
++      struct fsg_opts *fsg_opts;
++
++      fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
++
++      return fsg_store_ro(opts->lun, &fsg_opts->common->filesem, page, len);
++}
++
++static struct fsg_lun_opts_attribute fsg_lun_opts_ro =
++      __CONFIGFS_ATTR(ro, S_IRUGO | S_IWUSR, fsg_lun_opts_ro_show,
++                      fsg_lun_opts_ro_store);
++
++static ssize_t fsg_lun_opts_removable_show(struct fsg_lun_opts *opts,
++                                         char *page)
++{
++      return fsg_show_removable(opts->lun, page);
++}
++
++static ssize_t fsg_lun_opts_removable_store(struct fsg_lun_opts *opts,
++                                     const char *page, size_t len)
++{
++      return fsg_store_removable(opts->lun, page, len);
++}
++
++static struct fsg_lun_opts_attribute fsg_lun_opts_removable =
++      __CONFIGFS_ATTR(removable, S_IRUGO | S_IWUSR,
++                      fsg_lun_opts_removable_show,
++                      fsg_lun_opts_removable_store);
++
++static ssize_t fsg_lun_opts_cdrom_show(struct fsg_lun_opts *opts, char *page)
++{
++      return fsg_show_cdrom(opts->lun, page);
++}
++
++static ssize_t fsg_lun_opts_cdrom_store(struct fsg_lun_opts *opts,
++                                     const char *page, size_t len)
++{
++      return fsg_store_cdrom(opts->lun, page, len);
++}
++
++static struct fsg_lun_opts_attribute fsg_lun_opts_cdrom =
++      __CONFIGFS_ATTR(cdrom, S_IRUGO | S_IWUSR, fsg_lun_opts_cdrom_show,
++                      fsg_lun_opts_cdrom_store);
++
++static ssize_t fsg_lun_opts_nofua_show(struct fsg_lun_opts *opts, char *page)
++{
++      return fsg_show_nofua(opts->lun, page);
++}
++
++static ssize_t fsg_lun_opts_nofua_store(struct fsg_lun_opts *opts,
++                                     const char *page, size_t len)
++{
++      return fsg_store_nofua(opts->lun, page, len);
++}
++
++static struct fsg_lun_opts_attribute fsg_lun_opts_nofua =
++      __CONFIGFS_ATTR(nofua, S_IRUGO | S_IWUSR, fsg_lun_opts_nofua_show,
++                      fsg_lun_opts_nofua_store);
++
++static struct configfs_attribute *fsg_lun_attrs[] = {
++      &fsg_lun_opts_file.attr,
++      &fsg_lun_opts_ro.attr,
++      &fsg_lun_opts_removable.attr,
++      &fsg_lun_opts_cdrom.attr,
++      &fsg_lun_opts_nofua.attr,
++      NULL,
++};
++
++static struct config_item_type fsg_lun_type = {
++      .ct_item_ops    = &fsg_lun_item_ops,
++      .ct_attrs       = fsg_lun_attrs,
++      .ct_owner       = THIS_MODULE,
++};
++
++#define MAX_NAME_LEN  40
++
++static struct config_group *fsg_lun_make(struct config_group *group,
++                                       const char *name)
++{
++      struct fsg_lun_opts *opts;
++      struct fsg_opts *fsg_opts;
++      struct fsg_lun_config config;
++      char *num_str;
++      u8 num;
++      int ret;
++
++      num_str = strchr(name, '.');
++      if (!num_str) {
++              pr_err("Unable to locate . in LUN.NUMBER\n");
++              return ERR_PTR(-EINVAL);
++      }
++      num_str++;
++
++      ret = kstrtou8(num_str, 0, &num);
++      if (ret)
++              return ERR_PTR(ret);
++
++      fsg_opts = to_fsg_opts(&group->cg_item);
++      if (num >= FSG_MAX_LUNS)
++              return ERR_PTR(-ENODEV);
++      mutex_lock(&fsg_opts->lock);
++      if (fsg_opts->refcnt || fsg_opts->common->luns[num]) {
++              ret = -EBUSY;
++              goto out;
++      }
++
++      opts = kzalloc(sizeof(*opts), GFP_KERNEL);
++      if (!opts) {
++              ret = -ENOMEM;
++              goto out;
++      }
++
++      memset(&config, 0, sizeof(config));
++      config.removable = true;
++
++
++      ret = fsg_common_create_lun(fsg_opts->common, &config, num, name,
++                                  (const char **)&group->cg_item.ci_name);
++      if (ret) {
++              kfree(opts);
++              goto out;
++      }
++      opts->lun = fsg_opts->common->luns[num];
++      opts->lun_id = num;
++      mutex_unlock(&fsg_opts->lock);
++
++      config_group_init_type_name(&opts->group, name, &fsg_lun_type);
++
++      return &opts->group;
++out:
++      mutex_unlock(&fsg_opts->lock);
++      return ERR_PTR(ret);
++}
++
++static void fsg_lun_drop(struct config_group *group, struct config_item *item)
++{
++      struct fsg_lun_opts *lun_opts;
++      struct fsg_opts *fsg_opts;
++
++      lun_opts = to_fsg_lun_opts(item);
++      fsg_opts = to_fsg_opts(&group->cg_item);
++
++      mutex_lock(&fsg_opts->lock);
++      if (fsg_opts->refcnt) {
++              struct config_item *gadget;
++
++              gadget = group->cg_item.ci_parent->ci_parent;
++              unregister_gadget_item(gadget);
++      }
++
++      fsg_common_remove_lun(lun_opts->lun, fsg_opts->common->sysfs);
++      fsg_opts->common->luns[lun_opts->lun_id] = NULL;
++      lun_opts->lun_id = 0;
++      mutex_unlock(&fsg_opts->lock);
++
++      config_item_put(item);
++}
++
++CONFIGFS_ATTR_STRUCT(fsg_opts);
++CONFIGFS_ATTR_OPS(fsg_opts);
++
++static void fsg_attr_release(struct config_item *item)
++{
++      struct fsg_opts *opts = to_fsg_opts(item);
++
++      usb_put_function_instance(&opts->func_inst);
++}
++
++static struct configfs_item_operations fsg_item_ops = {
++      .release        = fsg_attr_release,
++      .show_attribute = fsg_opts_attr_show,
++      .store_attribute = fsg_opts_attr_store,
++};
++
++static ssize_t fsg_opts_stall_show(struct fsg_opts *opts, char *page)
++{
++      int result;
++
++      mutex_lock(&opts->lock);
++      result = sprintf(page, "%d", opts->common->can_stall);
++      mutex_unlock(&opts->lock);
++
++      return result;
++}
++
++static ssize_t fsg_opts_stall_store(struct fsg_opts *opts, const char *page,
++                                  size_t len)
++{
++      int ret;
++      u8 num;
++
++      mutex_lock(&opts->lock);
++      if (opts->refcnt) {
++              ret = -EBUSY;
++              goto end;
++      }
++      ret = kstrtou8(page, 0, &num);
++      if (ret)
++              goto end;
++
++      opts->common->can_stall = num != 0;
++      ret = len;
++
++end:
++      mutex_unlock(&opts->lock);
++      return ret;
++}
++
++static struct fsg_opts_attribute fsg_opts_stall =
++      __CONFIGFS_ATTR(stall, S_IRUGO | S_IWUSR, fsg_opts_stall_show,
++                      fsg_opts_stall_store);
++
++#ifdef CONFIG_USB_GADGET_DEBUG_FILES
++static ssize_t fsg_opts_num_buffers_show(struct fsg_opts *opts, char *page)
++{
++      int result;
++
++      mutex_lock(&opts->lock);
++      result = sprintf(page, "%d", opts->common->fsg_num_buffers);
++      mutex_unlock(&opts->lock);
++
++      return result;
++}
++
++static ssize_t fsg_opts_num_buffers_store(struct fsg_opts *opts,
++                                        const char *page, size_t len)
++{
++      int ret;
++      u8 num;
++
++      mutex_lock(&opts->lock);
++      if (opts->refcnt) {
++              ret = -EBUSY;
++              goto end;
++      }
++      ret = kstrtou8(page, 0, &num);
++      if (ret)
++              goto end;
++
++      ret = fsg_num_buffers_validate(num);
++      if (ret)
++              goto end;
++
++      fsg_common_set_num_buffers(opts->common, num);
++      ret = len;
++
++end:
++      mutex_unlock(&opts->lock);
++      return ret;
++}
++
++static struct fsg_opts_attribute fsg_opts_num_buffers =
++      __CONFIGFS_ATTR(num_buffers, S_IRUGO | S_IWUSR,
++                      fsg_opts_num_buffers_show,
++                      fsg_opts_num_buffers_store);
++
++#endif
++
++static struct configfs_attribute *fsg_attrs[] = {
++      &fsg_opts_stall.attr,
++#ifdef CONFIG_USB_GADGET_DEBUG_FILES
++      &fsg_opts_num_buffers.attr,
++#endif
++      NULL,
++};
++
++static struct configfs_group_operations fsg_group_ops = {
++      .make_group     = fsg_lun_make,
++      .drop_item      = fsg_lun_drop,
++};
++
++static struct config_item_type fsg_func_type = {
++      .ct_item_ops    = &fsg_item_ops,
++      .ct_group_ops   = &fsg_group_ops,
++      .ct_attrs       = fsg_attrs,
++      .ct_owner       = THIS_MODULE,
++};
++
+ static void fsg_free_inst(struct usb_function_instance *fi)
+ {
+       struct fsg_opts *opts;
+@@ -3307,11 +3644,13 @@ static void fsg_free_inst(struct usb_function_instance *fi)
+ static struct usb_function_instance *fsg_alloc_inst(void)
+ {
+       struct fsg_opts *opts;
++      struct fsg_lun_config config;
+       int rc;
+       opts = kzalloc(sizeof(*opts), GFP_KERNEL);
+       if (!opts)
+               return ERR_PTR(-ENOMEM);
++      mutex_init(&opts->lock);
+       opts->func_inst.free_func_inst = fsg_free_inst;
+       opts->common = fsg_common_setup(opts->common, false);
+       if (IS_ERR(opts->common)) {
+@@ -3329,6 +3668,18 @@ static struct usb_function_instance *fsg_alloc_inst(void)
+       pr_info(FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
++      memset(&config, 0, sizeof(config));
++      config.removable = true;
++      rc = fsg_common_create_lun(opts->common, &config, 0, "lun.0",
++                      (const char **)&opts->func_inst.group.cg_item.ci_name);
++      opts->lun0.lun = opts->common->luns[0];
++      opts->lun0.lun_id = 0;
++      config_group_init_type_name(&opts->lun0.group, "lun.0", &fsg_lun_type);
++      opts->default_groups[0] = &opts->lun0.group;
++      opts->func_inst.group.default_groups = opts->default_groups;
++
++      config_group_init_type_name(&opts->func_inst.group, "", &fsg_func_type);
++
+       return &opts->func_inst;
+ release_luns:
+@@ -3341,8 +3692,14 @@ release_opts:
+ static void fsg_free(struct usb_function *f)
+ {
+       struct fsg_dev *fsg;
++      struct fsg_opts *opts;
+       fsg = container_of(f, struct fsg_dev, function);
++      opts = container_of(f->fi, struct fsg_opts, func_inst);
++
++      mutex_lock(&opts->lock);
++      opts->refcnt--;
++      mutex_unlock(&opts->lock);
+       kfree(fsg);
+ }
+@@ -3357,6 +3714,9 @@ static struct usb_function *fsg_alloc(struct usb_function_instance *fi)
+       if (unlikely(!fsg))
+               return ERR_PTR(-ENOMEM);
++      mutex_lock(&opts->lock);
++      opts->refcnt++;
++      mutex_unlock(&opts->lock);
+       fsg->function.name      = FSG_DRIVER_DESC;
+       fsg->function.bind      = fsg_bind;
+       fsg->function.unbind    = fsg_unbind;
+diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h
+index b53cf8c..7d421d2 100644
+--- a/drivers/usb/gadget/f_mass_storage.h
++++ b/drivers/usb/gadget/f_mass_storage.h
+@@ -71,10 +71,27 @@ struct fsg_operations {
+       int (*thread_exits)(struct fsg_common *common);
+ };
++struct fsg_lun_opts {
++      struct config_group group;
++      struct fsg_lun *lun;
++      int lun_id;
++};
++
+ struct fsg_opts {
+       struct fsg_common *common;
+       struct usb_function_instance func_inst;
++      struct fsg_lun_opts lun0;
++      struct config_group *default_groups[2];
+       bool no_configfs; /* for legacy gadgets */
++
++      /*
++       * Read/write access to configfs attributes is handled by configfs.
++       *
++       * This is to protect the data from concurrent access by read/write
++       * and create symlink/remove symlink.
++       */
++      struct mutex                    lock;
++      int                             refcnt;
+ };
+ struct fsg_lun_config {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1141-usb-gadget-acm_ms-convert-to-new-interface-of-f_mass.patch b/patches.tizen/1141-usb-gadget-acm_ms-convert-to-new-interface-of-f_mass.patch
new file mode 100644 (file)
index 0000000..1bea9d3
--- /dev/null
@@ -0,0 +1,226 @@
+From 0c2d640b146c3cd9ddc2ed4b90eebf86ec180483 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 9 Oct 2013 10:07:29 +0200
+Subject: [PATCH 1141/1302] usb: gadget: acm_ms: convert to new interface of
+ f_mass_storage
+
+Convert the legacy acm_ms gadget to use the new function interface
+of f_mass_storage, so that later the compatibility layer in
+f_mass_storage can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig  |   1 +
+ drivers/usb/gadget/acm_ms.c | 113 +++++++++++++++++++++++++++++---------------
+ 2 files changed, 75 insertions(+), 39 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index bef6e86..e327cc3 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -1045,6 +1045,7 @@ config USB_G_ACM_MS
+       select USB_U_SERIAL
+       select USB_F_ACM
+       select USB_U_MS
++      select USB_F_MASS_STORAGE
+       help
+         This driver provides two functions in one configuration:
+         a mass storage, and a CDC ACM (serial port) link.
+diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c
+index 31aae8f..7bfa134 100644
+--- a/drivers/usb/gadget/acm_ms.c
++++ b/drivers/usb/gadget/acm_ms.c
+@@ -31,17 +31,7 @@
+ #define ACM_MS_VENDOR_NUM     0x1d6b  /* Linux Foundation */
+ #define ACM_MS_PRODUCT_NUM    0x0106  /* Composite Gadget: ACM + MS*/
+-/*-------------------------------------------------------------------------*/
+-
+-/*
+- * Kbuild is not very cooperative with respect to linking separately
+- * compiled library objects into one module.  So for now we won't use
+- * separate compilation ... ensuring init/exit sections work to shrink
+- * the runtime footprint, and giving us at least some parts of what
+- * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+- */
+-#define USB_FMS_INCLUDED
+-#include "f_mass_storage.c"
++#include "f_mass_storage.h"
+ /*-------------------------------------------------------------------------*/
+ USB_GADGET_COMPOSITE_OPTIONS();
+@@ -121,16 +111,19 @@ static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
+ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
+-static struct fsg_common fsg_common;
+-
+ /*-------------------------------------------------------------------------*/
+ static struct usb_function *f_acm;
+ static struct usb_function_instance *f_acm_inst;
++
++static struct usb_function_instance *fi_msg;
++static struct usb_function *f_msg;
++
+ /*
+  * We _always_ have both ACM and mass storage functions.
+  */
+ static int __init acm_ms_do_config(struct usb_configuration *c)
+ {
++      struct fsg_opts *opts;
+       int     status;
+       if (gadget_is_otg(c->cdev->gadget)) {
+@@ -138,31 +131,37 @@ static int __init acm_ms_do_config(struct usb_configuration *c)
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+-      f_acm_inst = usb_get_function_instance("acm");
+-      if (IS_ERR(f_acm_inst))
+-              return PTR_ERR(f_acm_inst);
++      opts = fsg_opts_from_func_inst(fi_msg);
+       f_acm = usb_get_function(f_acm_inst);
+-      if (IS_ERR(f_acm)) {
+-              status = PTR_ERR(f_acm);
+-              goto err_func;
++      if (IS_ERR(f_acm))
++              return PTR_ERR(f_acm);
++
++      f_msg = usb_get_function(fi_msg);
++      if (IS_ERR(f_msg)) {
++              status = PTR_ERR(f_msg);
++              goto put_acm;
+       }
+       status = usb_add_function(c, f_acm);
+       if (status < 0)
+-              goto err_conf;
++              goto put_msg;
+-      status = fsg_bind_config(c->cdev, c, &fsg_common);
+-      if (status < 0)
+-              goto err_fsg;
++      status = fsg_common_run_thread(opts->common);
++      if (status)
++              goto remove_acm;
++
++      status = usb_add_function(c, f_msg);
++      if (status)
++              goto remove_acm;
+       return 0;
+-err_fsg:
++remove_acm:
+       usb_remove_function(c, f_acm);
+-err_conf:
++put_msg:
++      usb_put_function(f_msg);
++put_acm:
+       usb_put_function(f_acm);
+-err_func:
+-      usb_put_function_instance(f_acm_inst);
+       return status;
+ }
+@@ -178,46 +177,82 @@ static struct usb_configuration acm_ms_config_driver = {
+ static int __init acm_ms_bind(struct usb_composite_dev *cdev)
+ {
+       struct usb_gadget       *gadget = cdev->gadget;
++      struct fsg_opts         *opts;
++      struct fsg_config       config;
+       int                     status;
+-      void                    *retp;
+-      /* set up mass storage function */
+-      retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data,
+-                                    fsg_num_buffers);
+-      if (IS_ERR(retp)) {
+-              status = PTR_ERR(retp);
+-              return PTR_ERR(retp);
++      f_acm_inst = usb_get_function_instance("acm");
++      if (IS_ERR(f_acm_inst))
++              return PTR_ERR(f_acm_inst);
++
++      fi_msg = usb_get_function_instance("mass_storage");
++      if (IS_ERR(fi_msg)) {
++              status = PTR_ERR(fi_msg);
++              goto fail_get_msg;
+       }
++      /* set up mass storage function */
++      fsg_config_from_params(&config, &fsg_mod_data, fsg_num_buffers);
++      opts = fsg_opts_from_func_inst(fi_msg);
++
++      opts->no_configfs = true;
++      status = fsg_common_set_num_buffers(opts->common, fsg_num_buffers);
++      if (status)
++              goto fail;
++
++      status = fsg_common_set_nluns(opts->common, config.nluns);
++      if (status)
++              goto fail_set_nluns;
++
++      status = fsg_common_set_cdev(opts->common, cdev, config.can_stall);
++      if (status)
++              goto fail_set_cdev;
++
++      fsg_common_set_sysfs(opts->common, true);
++      status = fsg_common_create_luns(opts->common, &config);
++      if (status)
++              goto fail_set_cdev;
++
++      fsg_common_set_inquiry_string(opts->common, config.vendor_name,
++                                    config.product_name);
+       /*
+        * Allocate string descriptor numbers ... note that string
+        * contents can be overridden by the composite_dev glue.
+        */
+       status = usb_string_ids_tab(cdev, strings_dev);
+       if (status < 0)
+-              goto fail1;
++              goto fail_string_ids;
+       device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id;
+       device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id;
+       /* register our configuration */
+       status = usb_add_config(cdev, &acm_ms_config_driver, acm_ms_do_config);
+       if (status < 0)
+-              goto fail1;
++              goto fail_string_ids;
+       usb_composite_overwrite_options(cdev, &coverwrite);
+       dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n",
+                       DRIVER_DESC);
+-      fsg_common_put(&fsg_common);
+       return 0;
+       /* error recovery */
+-fail1:
+-      fsg_common_put(&fsg_common);
++fail_string_ids:
++      fsg_common_remove_luns(opts->common);
++fail_set_cdev:
++      fsg_common_free_luns(opts->common);
++fail_set_nluns:
++      fsg_common_free_buffers(opts->common);
++fail:
++      usb_put_function_instance(fi_msg);
++fail_get_msg:
++      usb_put_function_instance(f_acm_inst);
+       return status;
+ }
+ static int __exit acm_ms_unbind(struct usb_composite_dev *cdev)
+ {
++      usb_put_function(f_msg);
++      usb_put_function_instance(fi_msg);
+       usb_put_function(f_acm);
+       usb_put_function_instance(f_acm_inst);
+       return 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1142-usb-gadget-multi-convert-to-new-interface-of-f_ecm.patch b/patches.tizen/1142-usb-gadget-multi-convert-to-new-interface-of-f_ecm.patch
new file mode 100644 (file)
index 0000000..e5867ae
--- /dev/null
@@ -0,0 +1,193 @@
+From 8948de491eb9afacef024a31115da817f62267d7 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 9 Oct 2013 10:08:25 +0200
+Subject: [PATCH 1142/1302] usb: gadget: multi: convert to new interface of
+ f_ecm
+
+Convert the legacy multi gadget to the new interface of f_ecm,
+so that later the compatibility layer in f_ecm can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig |  1 +
+ drivers/usb/gadget/multi.c | 68 ++++++++++++++++++++++++++++++++++++++++------
+ 2 files changed, 61 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index e327cc3..33ba3ec 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -1094,6 +1094,7 @@ config USB_G_MULTI_CDC
+       bool "CDC Ethernet + CDC Serial + Storage configuration"
+       depends on USB_G_MULTI
+       default n
++      select USB_F_ECM
+       help
+         This option enables a configuration with CDC Ethernet (ECM), CDC
+         Serial and Mass Storage functions available in the Multifunction
+diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
+index 42a5bed..7dd5544 100644
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -15,6 +15,7 @@
+ #include <linux/kernel.h>
+ #include <linux/module.h>
++#include <linux/netdevice.h>
+ #include "u_serial.h"
+ #if defined USB_ETH_RNDIS
+@@ -44,8 +45,7 @@ MODULE_LICENSE("GPL");
+ #define USB_FMS_INCLUDED
+ #include "f_mass_storage.c"
+-#define USBF_ECM_INCLUDED
+-#include "f_ecm.c"
++#include "u_ecm.h"
+ #ifdef USB_ETH_RNDIS
+ #  define USB_FRNDIS_INCLUDED
+ #  include "f_rndis.c"
+@@ -151,14 +151,14 @@ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
+ static struct fsg_common fsg_common;
+-static u8 host_mac[ETH_ALEN];
+-
+ static struct usb_function_instance *fi_acm;
+ static struct eth_dev *the_dev;
+ /********** RNDIS **********/
+ #ifdef USB_ETH_RNDIS
++static u8 host_mac[ETH_ALEN];
++
+ static struct usb_function *f_acm_rndis;
+ static __init int rndis_do_config(struct usb_configuration *c)
+@@ -220,7 +220,9 @@ static __ref int rndis_config_register(struct usb_composite_dev *cdev)
+ /********** CDC ECM **********/
+ #ifdef CONFIG_USB_G_MULTI_CDC
++static struct usb_function_instance *fi_ecm;
+ static struct usb_function *f_acm_multi;
++static struct usb_function *f_ecm;
+ static __init int cdc_do_config(struct usb_configuration *c)
+ {
+@@ -231,14 +233,20 @@ static __init int cdc_do_config(struct usb_configuration *c)
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+-      ret = ecm_bind_config(c, host_mac, the_dev);
++      f_ecm = usb_get_function(fi_ecm);
++      if (IS_ERR(f_ecm))
++              return PTR_ERR(f_ecm);
++
++      ret = usb_add_function(c, f_ecm);
+       if (ret < 0)
+-              return ret;
++              goto err_func_ecm;
+       /* implicit port_num is zero */
+       f_acm_multi = usb_get_function(fi_acm);
+-      if (IS_ERR(f_acm_multi))
+-              return PTR_ERR(f_acm_multi);
++      if (IS_ERR(f_acm_multi)) {
++              ret = PTR_ERR(f_acm_multi);
++              goto err_func_acm;
++      }
+       ret = usb_add_function(c, f_acm_multi);
+       if (ret)
+@@ -253,6 +261,10 @@ err_fsg:
+       usb_remove_function(c, f_acm_multi);
+ err_conf:
+       usb_put_function(f_acm_multi);
++err_func_acm:
++      usb_remove_function(c, f_ecm);
++err_func_ecm:
++      usb_put_function(f_ecm);
+       return ret;
+ }
+@@ -285,6 +297,9 @@ static __ref int cdc_config_register(struct usb_composite_dev *cdev)
+ static int __ref multi_bind(struct usb_composite_dev *cdev)
+ {
+       struct usb_gadget *gadget = cdev->gadget;
++#ifdef CONFIG_USB_G_MULTI_CDC
++      struct f_ecm_opts *ecm_opts;
++#endif
+       int status;
+       if (!can_support_ecm(cdev->gadget)) {
+@@ -293,11 +308,39 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
+               return -EINVAL;
+       }
++#ifdef CONFIG_USB_G_MULTI_CDC
++      fi_ecm = usb_get_function_instance("ecm");
++      if (IS_ERR(fi_ecm))
++              return PTR_ERR(fi_ecm);
++
++      ecm_opts = container_of(fi_ecm, struct f_ecm_opts, func_inst);
++
++      gether_set_qmult(ecm_opts->net, qmult);
++      if (!gether_set_host_addr(ecm_opts->net, host_addr))
++              pr_info("using host ethernet address: %s", host_addr);
++      if (!gether_set_dev_addr(ecm_opts->net, dev_addr))
++              pr_info("using self ethernet address: %s", dev_addr);
++
++      the_dev = netdev_priv(ecm_opts->net);
++
++#elif defined USB_ETH_RNDIS
++
+       /* set up network link layer */
+       the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, host_mac,
+                              qmult);
+       if (IS_ERR(the_dev))
+               return PTR_ERR(the_dev);
++#endif
++
++#if (defined CONFIG_USB_G_MULTI_CDC && defined USB_ETH_RNDIS)
++      gether_set_gadget(ecm_opts->net, cdev->gadget);
++      status = gether_register_netdev(ecm_opts->net);
++      if (status)
++              goto fail0;
++      ecm_opts->bound = true;
++
++      gether_get_host_addr_u8(ecm_opts->net, host_mac);
++#endif
+       /* set up serial link layer */
+       fi_acm = usb_get_function_instance("acm");
+@@ -345,7 +388,11 @@ fail2:
+ fail1:
+       usb_put_function_instance(fi_acm);
+ fail0:
++#ifdef CONFIG_USB_G_MULTI_CDC
++      usb_put_function_instance(fi_ecm);
++#else
+       gether_cleanup(the_dev);
++#endif
+       return status;
+ }
+@@ -358,7 +405,12 @@ static int __exit multi_unbind(struct usb_composite_dev *cdev)
+       usb_put_function(f_acm_rndis);
+ #endif
+       usb_put_function_instance(fi_acm);
++#ifdef CONFIG_USB_G_MULTI_CDC
++      usb_put_function(f_ecm);
++      usb_put_function_instance(fi_ecm);
++#else
+       gether_cleanup(the_dev);
++#endif
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1143-usb-gadget-multi-convert-to-new-interface-of-f_rndis.patch b/patches.tizen/1143-usb-gadget-multi-convert-to-new-interface-of-f_rndis.patch
new file mode 100644 (file)
index 0000000..5ad2377
--- /dev/null
@@ -0,0 +1,203 @@
+From 79aecf18905e9a86347c1540ebd23aa8cc157024 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 9 Oct 2013 10:08:26 +0200
+Subject: [PATCH 1143/1302] usb: gadget: multi: convert to new interface of
+ f_rndis
+
+Convert the legacy multi gadget to the new interface of f_rndis,
+so that later the compatibility layer in f_rndis can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig |  3 +-
+ drivers/usb/gadget/multi.c | 73 +++++++++++++++++++++++++++++++---------------
+ 2 files changed, 52 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 33ba3ec..9a67faf 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -1060,7 +1060,6 @@ config USB_G_MULTI
+       select USB_LIBCOMPOSITE
+       select USB_U_SERIAL
+       select USB_U_ETHER
+-      select USB_U_RNDIS
+       select USB_F_ACM
+       select USB_U_MS
+       help
+@@ -1081,6 +1080,8 @@ config USB_G_MULTI
+ config USB_G_MULTI_RNDIS
+       bool "RNDIS + CDC Serial + Storage configuration"
+       depends on USB_G_MULTI
++      select USB_U_RNDIS
++      select USB_F_RNDIS
+       default y
+       help
+         This option enables a configuration with RNDIS, CDC Serial and
+diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
+index 7dd5544..fceef0f 100644
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -47,8 +47,7 @@ MODULE_LICENSE("GPL");
+ #include "u_ecm.h"
+ #ifdef USB_ETH_RNDIS
+-#  define USB_FRNDIS_INCLUDED
+-#  include "f_rndis.c"
++#  include "u_rndis.h"
+ #  include "rndis.h"
+ #endif
+ #include "u_ether.h"
+@@ -152,14 +151,13 @@ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
+ static struct fsg_common fsg_common;
+ static struct usb_function_instance *fi_acm;
+-static struct eth_dev *the_dev;
+ /********** RNDIS **********/
+ #ifdef USB_ETH_RNDIS
+-static u8 host_mac[ETH_ALEN];
+-
++static struct usb_function_instance *fi_rndis;
+ static struct usb_function *f_acm_rndis;
++static struct usb_function *f_rndis;
+ static __init int rndis_do_config(struct usb_configuration *c)
+ {
+@@ -170,13 +168,19 @@ static __init int rndis_do_config(struct usb_configuration *c)
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+-      ret = rndis_bind_config(c, host_mac, the_dev);
++      f_rndis = usb_get_function(fi_rndis);
++      if (IS_ERR(f_rndis))
++              return PTR_ERR(f_rndis);
++
++      ret = usb_add_function(c, f_rndis);
+       if (ret < 0)
+-              return ret;
++              goto err_func_rndis;
+       f_acm_rndis = usb_get_function(fi_acm);
+-      if (IS_ERR(f_acm_rndis))
+-              return PTR_ERR(f_acm_rndis);
++      if (IS_ERR(f_acm_rndis)) {
++              ret = PTR_ERR(f_acm_rndis);
++              goto err_func_acm;
++      }
+       ret = usb_add_function(c, f_acm_rndis);
+       if (ret)
+@@ -191,6 +195,10 @@ err_fsg:
+       usb_remove_function(c, f_acm_rndis);
+ err_conf:
+       usb_put_function(f_acm_rndis);
++err_func_acm:
++      usb_remove_function(c, f_rndis);
++err_func_rndis:
++      usb_put_function(f_rndis);
+       return ret;
+ }
+@@ -300,11 +308,14 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
+ #ifdef CONFIG_USB_G_MULTI_CDC
+       struct f_ecm_opts *ecm_opts;
+ #endif
++#ifdef USB_ETH_RNDIS
++      struct f_rndis_opts *rndis_opts;
++#endif
+       int status;
+       if (!can_support_ecm(cdev->gadget)) {
+               dev_err(&gadget->dev, "controller '%s' not usable\n",
+-                      gadget->name);
++                      gadget->name);
+               return -EINVAL;
+       }
+@@ -320,26 +331,38 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
+               pr_info("using host ethernet address: %s", host_addr);
+       if (!gether_set_dev_addr(ecm_opts->net, dev_addr))
+               pr_info("using self ethernet address: %s", dev_addr);
++#endif
+-      the_dev = netdev_priv(ecm_opts->net);
++#ifdef USB_ETH_RNDIS
++      fi_rndis = usb_get_function_instance("rndis");
++      if (IS_ERR(fi_rndis)) {
++              status = PTR_ERR(fi_rndis);
++              goto fail;
++      }
+-#elif defined USB_ETH_RNDIS
++      rndis_opts = container_of(fi_rndis, struct f_rndis_opts, func_inst);
+-      /* set up network link layer */
+-      the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, host_mac,
+-                             qmult);
+-      if (IS_ERR(the_dev))
+-              return PTR_ERR(the_dev);
++      gether_set_qmult(rndis_opts->net, qmult);
++      if (!gether_set_host_addr(rndis_opts->net, host_addr))
++              pr_info("using host ethernet address: %s", host_addr);
++      if (!gether_set_dev_addr(rndis_opts->net, dev_addr))
++              pr_info("using self ethernet address: %s", dev_addr);
+ #endif
+ #if (defined CONFIG_USB_G_MULTI_CDC && defined USB_ETH_RNDIS)
++      /*
++       * If both ecm and rndis are selected then:
++       *      1) rndis borrows the net interface from ecm
++       *      2) since the interface is shared it must not be bound
++       *      twice - in ecm's _and_ rndis' binds, so do it here.
++       */
+       gether_set_gadget(ecm_opts->net, cdev->gadget);
+       status = gether_register_netdev(ecm_opts->net);
+       if (status)
+               goto fail0;
+-      ecm_opts->bound = true;
+-      gether_get_host_addr_u8(ecm_opts->net, host_mac);
++      rndis_borrow_net(fi_rndis, ecm_opts->net);
++      ecm_opts->bound = true;
+ #endif
+       /* set up serial link layer */
+@@ -388,10 +411,12 @@ fail2:
+ fail1:
+       usb_put_function_instance(fi_acm);
+ fail0:
++#ifdef USB_ETH_RNDIS
++      usb_put_function_instance(fi_rndis);
++fail:
++#endif
+ #ifdef CONFIG_USB_G_MULTI_CDC
+       usb_put_function_instance(fi_ecm);
+-#else
+-      gether_cleanup(the_dev);
+ #endif
+       return status;
+ }
+@@ -405,11 +430,13 @@ static int __exit multi_unbind(struct usb_composite_dev *cdev)
+       usb_put_function(f_acm_rndis);
+ #endif
+       usb_put_function_instance(fi_acm);
++#ifdef USB_ETH_RNDIS
++      usb_put_function(f_rndis);
++      usb_put_function_instance(fi_rndis);
++#endif
+ #ifdef CONFIG_USB_G_MULTI_CDC
+       usb_put_function(f_ecm);
+       usb_put_function_instance(fi_ecm);
+-#else
+-      gether_cleanup(the_dev);
+ #endif
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1144-usb-gadget-multi-convert-to-new-interface-of-f_mass_.patch b/patches.tizen/1144-usb-gadget-multi-convert-to-new-interface-of-f_mass_.patch
new file mode 100644 (file)
index 0000000..3357d54
--- /dev/null
@@ -0,0 +1,247 @@
+From 1c4486b65e6729a5e5761b44ad9b51109af19705 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 9 Oct 2013 10:08:27 +0200
+Subject: [PATCH 1144/1302] usb: gadget: multi: convert to new interface of
+ f_mass_storage
+
+Convert the legacy multi gadget to the new interface of f_mass_storage,
+so that later the compatibility layer in f_mass_storage can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig |   1 +
+ drivers/usb/gadget/multi.c | 112 +++++++++++++++++++++++++++++++++------------
+ 2 files changed, 83 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 9a67faf..df9c040 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -1062,6 +1062,7 @@ config USB_G_MULTI
+       select USB_U_ETHER
+       select USB_F_ACM
+       select USB_U_MS
++      select USB_F_MASS_STORAGE
+       help
+         The Multifunction Composite Gadget provides Ethernet (RNDIS
+         and/or CDC Ethernet), mass storage and ACM serial link
+diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
+index fceef0f..4fdaa54 100644
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -33,17 +33,7 @@ MODULE_AUTHOR("Michal Nazarewicz");
+ MODULE_LICENSE("GPL");
+-/***************************** All the files... *****************************/
+-
+-/*
+- * kbuild is not very cooperative with respect to linking separately
+- * compiled library objects into one module.  So for now we won't use
+- * separate compilation ... ensuring init/exit sections work to shrink
+- * the runtime footprint, and giving us at least some parts of what
+- * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+- */
+-#define USB_FMS_INCLUDED
+-#include "f_mass_storage.c"
++#include "f_mass_storage.h"
+ #include "u_ecm.h"
+ #ifdef USB_ETH_RNDIS
+@@ -148,9 +138,8 @@ static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
+ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
+-static struct fsg_common fsg_common;
+-
+ static struct usb_function_instance *fi_acm;
++static struct usb_function_instance *fi_msg;
+ /********** RNDIS **********/
+@@ -158,9 +147,11 @@ static struct usb_function_instance *fi_acm;
+ static struct usb_function_instance *fi_rndis;
+ static struct usb_function *f_acm_rndis;
+ static struct usb_function *f_rndis;
++static struct usb_function *f_msg_rndis;
+ static __init int rndis_do_config(struct usb_configuration *c)
+ {
++      struct fsg_opts *fsg_opts;
+       int ret;
+       if (gadget_is_otg(c->cdev->gadget)) {
+@@ -186,11 +177,24 @@ static __init int rndis_do_config(struct usb_configuration *c)
+       if (ret)
+               goto err_conf;
+-      ret = fsg_bind_config(c->cdev, c, &fsg_common);
+-      if (ret < 0)
++      f_msg_rndis = usb_get_function(fi_msg);
++      if (IS_ERR(f_msg_rndis)) {
++              ret = PTR_ERR(f_msg_rndis);
+               goto err_fsg;
++      }
++
++      fsg_opts = fsg_opts_from_func_inst(fi_msg);
++      ret = fsg_common_run_thread(fsg_opts->common);
++      if (ret)
++              goto err_run;
++
++      ret = usb_add_function(c, f_msg_rndis);
++      if (ret)
++              goto err_run;
+       return 0;
++err_run:
++      usb_put_function(f_msg_rndis);
+ err_fsg:
+       usb_remove_function(c, f_acm_rndis);
+ err_conf:
+@@ -231,9 +235,11 @@ static __ref int rndis_config_register(struct usb_composite_dev *cdev)
+ static struct usb_function_instance *fi_ecm;
+ static struct usb_function *f_acm_multi;
+ static struct usb_function *f_ecm;
++static struct usb_function *f_msg_multi;
+ static __init int cdc_do_config(struct usb_configuration *c)
+ {
++      struct fsg_opts *fsg_opts;
+       int ret;
+       if (gadget_is_otg(c->cdev->gadget)) {
+@@ -260,11 +266,24 @@ static __init int cdc_do_config(struct usb_configuration *c)
+       if (ret)
+               goto err_conf;
+-      ret = fsg_bind_config(c->cdev, c, &fsg_common);
+-      if (ret < 0)
++      f_msg_multi = usb_get_function(fi_msg);
++      if (IS_ERR(f_msg_multi)) {
++              ret = PTR_ERR(f_msg_multi);
+               goto err_fsg;
++      }
++
++      fsg_opts = fsg_opts_from_func_inst(fi_msg);
++      ret = fsg_common_run_thread(fsg_opts->common);
++      if (ret)
++              goto err_run;
++
++      ret = usb_add_function(c, f_msg_multi);
++      if (ret)
++              goto err_run;
+       return 0;
++err_run:
++      usb_put_function(f_msg_multi);
+ err_fsg:
+       usb_remove_function(c, f_acm_multi);
+ err_conf:
+@@ -311,6 +330,8 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
+ #ifdef USB_ETH_RNDIS
+       struct f_rndis_opts *rndis_opts;
+ #endif
++      struct fsg_opts *fsg_opts;
++      struct fsg_config config;
+       int status;
+       if (!can_support_ecm(cdev->gadget)) {
+@@ -373,41 +394,65 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
+       }
+       /* set up mass storage function */
+-      {
+-              void *retp;
+-              retp = fsg_common_from_params(&fsg_common, cdev, &fsg_mod_data,
+-                                            fsg_num_buffers);
+-              if (IS_ERR(retp)) {
+-                      status = PTR_ERR(retp);
+-                      goto fail1;
+-              }
++      fi_msg = usb_get_function_instance("mass_storage");
++      if (IS_ERR(fi_msg)) {
++              status = PTR_ERR(fi_msg);
++              goto fail1;
+       }
++      fsg_config_from_params(&config, &fsg_mod_data, fsg_num_buffers);
++      fsg_opts = fsg_opts_from_func_inst(fi_msg);
++
++      fsg_opts->no_configfs = true;
++      status = fsg_common_set_num_buffers(fsg_opts->common, fsg_num_buffers);
++      if (status)
++              goto fail2;
++
++      status = fsg_common_set_nluns(fsg_opts->common, config.nluns);
++      if (status)
++              goto fail_set_nluns;
++
++      status = fsg_common_set_cdev(fsg_opts->common, cdev, config.can_stall);
++      if (status)
++              goto fail_set_cdev;
++
++      fsg_common_set_sysfs(fsg_opts->common, true);
++      status = fsg_common_create_luns(fsg_opts->common, &config);
++      if (status)
++              goto fail_set_cdev;
++
++      fsg_common_set_inquiry_string(fsg_opts->common, config.vendor_name,
++                                    config.product_name);
+       /* allocate string IDs */
+       status = usb_string_ids_tab(cdev, strings_dev);
+       if (unlikely(status < 0))
+-              goto fail2;
++              goto fail_string_ids;
+       device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id;
+       /* register configurations */
+       status = rndis_config_register(cdev);
+       if (unlikely(status < 0))
+-              goto fail2;
++              goto fail_string_ids;
+       status = cdc_config_register(cdev);
+       if (unlikely(status < 0))
+-              goto fail2;
++              goto fail_string_ids;
+       usb_composite_overwrite_options(cdev, &coverwrite);
+       /* we're done */
+       dev_info(&gadget->dev, DRIVER_DESC "\n");
+-      fsg_common_put(&fsg_common);
+       return 0;
+       /* error recovery */
++fail_string_ids:
++      fsg_common_remove_luns(fsg_opts->common);
++fail_set_cdev:
++      fsg_common_free_luns(fsg_opts->common);
++fail_set_nluns:
++      fsg_common_free_buffers(fsg_opts->common);
+ fail2:
+-      fsg_common_put(&fsg_common);
++      usb_put_function_instance(fi_msg);
+ fail1:
+       usb_put_function_instance(fi_acm);
+ fail0:
+@@ -424,6 +469,13 @@ fail:
+ static int __exit multi_unbind(struct usb_composite_dev *cdev)
+ {
+ #ifdef CONFIG_USB_G_MULTI_CDC
++      usb_put_function(f_msg_multi);
++#endif
++#ifdef USB_ETH_RNDIS
++      usb_put_function(f_msg_rndis);
++#endif
++      usb_put_function_instance(fi_msg);
++#ifdef CONFIG_USB_G_MULTI_CDC
+       usb_put_function(f_acm_multi);
+ #endif
+ #ifdef USB_ETH_RNDIS
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1145-usb-gadget-f_mass_storage-remove-compatibility-layer.patch b/patches.tizen/1145-usb-gadget-f_mass_storage-remove-compatibility-layer.patch
new file mode 100644 (file)
index 0000000..fb0d474
--- /dev/null
@@ -0,0 +1,377 @@
+From ba0f3b566267c31deaa99b9dd55c629cdaa0ca0c Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 9 Oct 2013 10:08:28 +0200
+Subject: [PATCH 1145/1302] usb: gadget: f_mass_storage: remove compatibility
+ layer
+
+There are no more old interface users left. Remove it.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 150 +++++-------------------------------
+ drivers/usb/gadget/f_mass_storage.h |  21 -----
+ 2 files changed, 19 insertions(+), 152 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 00d3687..6e5a6da 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -228,13 +228,6 @@
+ #define FSG_DRIVER_DESC               "Mass Storage Function"
+ #define FSG_DRIVER_VERSION    "2009/09/11"
+-/* to avoid a lot of #ifndef-#endif in the temporary compatibility layer */
+-#ifndef USB_FMS_INCLUDED
+-#define EXPORT_SYMBOL_GPL_IF_MODULE(m) EXPORT_SYMBOL_GPL(m);
+-#else
+-#define EXPORT_SYMBOL_GPL_IF_MODULE(m)
+-#endif
+-
+ static const char fsg_string_interface[] = "Mass Storage";
+ #include "storage_common.h"
+@@ -2651,13 +2644,13 @@ void fsg_common_get(struct fsg_common *common)
+ {
+       kref_get(&common->ref);
+ }
+-EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_get);
++EXPORT_SYMBOL_GPL(fsg_common_get);
+ void fsg_common_put(struct fsg_common *common)
+ {
+       kref_put(&common->ref, fsg_common_release);
+ }
+-EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_put);
++EXPORT_SYMBOL_GPL(fsg_common_put);
+ /* check if fsg_num_buffers is within a valid range */
+ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
+@@ -2669,7 +2662,7 @@ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
+       return -EINVAL;
+ }
+-static struct fsg_common *fsg_common_setup(struct fsg_common *common, bool zero)
++static struct fsg_common *fsg_common_setup(struct fsg_common *common)
+ {
+       if (!common) {
+               common = kzalloc(sizeof(*common), GFP_KERNEL);
+@@ -2677,8 +2670,6 @@ static struct fsg_common *fsg_common_setup(struct fsg_common *common, bool zero)
+                       return ERR_PTR(-ENOMEM);
+               common->free_storage_on_release = 1;
+       } else {
+-              if (zero)
+-                      memset(common, 0, sizeof(*common));
+               common->free_storage_on_release = 0;
+       }
+       init_rwsem(&common->filesem);
+@@ -2695,7 +2686,7 @@ void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs)
+ {
+       common->sysfs = sysfs;
+ }
+-EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_set_sysfs);
++EXPORT_SYMBOL_GPL(fsg_common_set_sysfs);
+ static void _fsg_common_free_buffers(struct fsg_buffhd *buffhds, unsigned n)
+ {
+@@ -2751,7 +2742,7 @@ error_release:
+       return -ENOMEM;
+ }
+-EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_set_num_buffers);
++EXPORT_SYMBOL_GPL(fsg_common_set_num_buffers);
+ static inline void fsg_common_remove_sysfs(struct fsg_lun *lun)
+ {
+@@ -2790,7 +2781,7 @@ void fsg_common_remove_lun(struct fsg_lun *lun, bool sysfs)
+       fsg_lun_close(lun);
+       kfree(lun);
+ }
+-EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_remove_lun);
++EXPORT_SYMBOL_GPL(fsg_common_remove_lun);
+ static void _fsg_common_remove_luns(struct fsg_common *common, int n)
+ {
+@@ -2802,7 +2793,7 @@ static void _fsg_common_remove_luns(struct fsg_common *common, int n)
+                       common->luns[i] = NULL;
+               }
+ }
+-EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_remove_luns);
++EXPORT_SYMBOL_GPL(fsg_common_remove_luns);
+ void fsg_common_remove_luns(struct fsg_common *common)
+ {
+@@ -2815,7 +2806,7 @@ void fsg_common_free_luns(struct fsg_common *common)
+       kfree(common->luns);
+       common->luns = NULL;
+ }
+-EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_free_luns);
++EXPORT_SYMBOL_GPL(fsg_common_free_luns);
+ int fsg_common_set_nluns(struct fsg_common *common, int nluns)
+ {
+@@ -2841,21 +2832,21 @@ int fsg_common_set_nluns(struct fsg_common *common, int nluns)
+       return 0;
+ }
+-EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_set_nluns);
++EXPORT_SYMBOL_GPL(fsg_common_set_nluns);
+ void fsg_common_set_ops(struct fsg_common *common,
+                       const struct fsg_operations *ops)
+ {
+       common->ops = ops;
+ }
+-EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_set_ops);
++EXPORT_SYMBOL_GPL(fsg_common_set_ops);
+ void fsg_common_free_buffers(struct fsg_common *common)
+ {
+       _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
+       common->buffhds = NULL;
+ }
+-EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_free_buffers);
++EXPORT_SYMBOL_GPL(fsg_common_free_buffers);
+ int fsg_common_set_cdev(struct fsg_common *common,
+                        struct usb_composite_dev *cdev, bool can_stall)
+@@ -2883,7 +2874,7 @@ int fsg_common_set_cdev(struct fsg_common *common,
+       return 0;
+ }
+-EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_set_cdev);
++EXPORT_SYMBOL_GPL(fsg_common_set_cdev);
+ static inline int fsg_common_add_sysfs(struct fsg_common *common,
+                                      struct fsg_lun *lun)
+@@ -3006,7 +2997,7 @@ error_sysfs:
+       kfree(lun);
+       return rc;
+ }
+-EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_create_lun);
++EXPORT_SYMBOL_GPL(fsg_common_create_lun);
+ int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg)
+ {
+@@ -3028,7 +3019,7 @@ fail:
+       _fsg_common_remove_luns(common, i);
+       return rc;
+ }
+-EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_create_luns);
++EXPORT_SYMBOL_GPL(fsg_common_create_luns);
+ void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
+                                  const char *pn)
+@@ -3045,7 +3036,7 @@ void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
+                    : "File-Stor Gadget"),
+                i);
+ }
+-EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_set_inquiry_string);
++EXPORT_SYMBOL_GPL(fsg_common_set_inquiry_string);
+ int fsg_common_run_thread(struct fsg_common *common)
+ {
+@@ -3064,61 +3055,7 @@ int fsg_common_run_thread(struct fsg_common *common)
+       return 0;
+ }
+-EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_run_thread);
+-
+-struct fsg_common *fsg_common_init(struct fsg_common *common,
+-                                 struct usb_composite_dev *cdev,
+-                                 struct fsg_config *cfg)
+-{
+-      int rc;
+-
+-      common = fsg_common_setup(common, !!common);
+-      if (IS_ERR(common))
+-              return common;
+-      fsg_common_set_sysfs(common, true);
+-      common->state = FSG_STATE_IDLE;
+-
+-      rc = fsg_common_set_num_buffers(common, cfg->fsg_num_buffers);
+-      if (rc) {
+-              if (common->free_storage_on_release)
+-                      kfree(common);
+-              return ERR_PTR(rc);
+-      }
+-      common->ops = cfg->ops;
+-      common->private_data = cfg->private_data;
+-
+-      rc = fsg_common_set_cdev(common, cdev, cfg->can_stall);
+-      if (rc)
+-              goto error_release;
+-
+-      rc = fsg_common_set_nluns(common, cfg->nluns);
+-      if (rc)
+-              goto error_release;
+-
+-      rc = fsg_common_create_luns(common, cfg);
+-      if (rc)
+-              goto error_release;
+-
+-
+-      fsg_common_set_inquiry_string(common, cfg->vendor_name,
+-                                    cfg->product_name);
+-
+-      /* Information */
+-      INFO(common, FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
+-
+-      rc = fsg_common_run_thread(common);
+-      if (rc)
+-              goto error_release;
+-
+-      return common;
+-
+-error_release:
+-      common->state = FSG_STATE_TERMINATED;   /* The thread is dead */
+-      /* Call fsg_common_release() directly, ref might be not initialised. */
+-      fsg_common_release(&common->ref);
+-      return ERR_PTR(rc);
+-}
+-EXPORT_SYMBOL_GPL_IF_MODULE(fsg_common_init);
++EXPORT_SYMBOL_GPL(fsg_common_run_thread);
+ static void fsg_common_release(struct kref *ref)
+ {
+@@ -3166,9 +3103,8 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
+       struct usb_ep           *ep;
+       unsigned                max_burst;
+       int                     ret;
+-
+-#ifndef USB_FMS_INCLUDED
+       struct fsg_opts         *opts;
++
+       opts = fsg_opts_from_func_inst(f->fi);
+       if (!opts->no_configfs) {
+               ret = fsg_common_set_cdev(fsg->common, c->cdev,
+@@ -3180,7 +3116,6 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
+               if (ret)
+                       return ret;
+       }
+-#endif
+       fsg->gadget = gadget;
+@@ -3248,54 +3183,9 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
+               wait_event(common->fsg_wait, common->fsg != fsg);
+       }
+-#ifdef USB_FMS_INCLUDED
+-      fsg_common_put(common);
+-#endif
+       usb_free_all_descriptors(&fsg->function);
+-#ifdef USB_FMS_INCLUDED
+-      kfree(fsg);
+-#endif
+-}
+-
+-#ifdef USB_FMS_INCLUDED
+-
+-static int fsg_bind_config(struct usb_composite_dev *cdev,
+-                         struct usb_configuration *c,
+-                         struct fsg_common *common)
+-{
+-      struct fsg_dev *fsg;
+-      int rc;
+-
+-      fsg = kzalloc(sizeof *fsg, GFP_KERNEL);
+-      if (unlikely(!fsg))
+-              return -ENOMEM;
+-
+-      fsg->function.name        = FSG_DRIVER_DESC;
+-      fsg->function.bind        = fsg_bind;
+-      fsg->function.unbind      = fsg_unbind;
+-      fsg->function.setup       = fsg_setup;
+-      fsg->function.set_alt     = fsg_set_alt;
+-      fsg->function.disable     = fsg_disable;
+-
+-      fsg->common               = common;
+-      /*
+-       * Our caller holds a reference to common structure so we
+-       * don't have to be worry about it being freed until we return
+-       * from this function.  So instead of incrementing counter now
+-       * and decrement in error recovery we increment it only when
+-       * call to usb_add_function() was successful.
+-       */
+-
+-      rc = usb_add_function(c, &fsg->function);
+-      if (unlikely(rc))
+-              kfree(fsg);
+-      else
+-              fsg_common_get(fsg->common);
+-      return rc;
+ }
+-#else
+-
+ static inline struct fsg_lun_opts *to_fsg_lun_opts(struct config_item *item)
+ {
+       return container_of(to_config_group(item), struct fsg_lun_opts, group);
+@@ -3652,7 +3542,7 @@ static struct usb_function_instance *fsg_alloc_inst(void)
+               return ERR_PTR(-ENOMEM);
+       mutex_init(&opts->lock);
+       opts->func_inst.free_func_inst = fsg_free_inst;
+-      opts->common = fsg_common_setup(opts->common, false);
++      opts->common = fsg_common_setup(opts->common);
+       if (IS_ERR(opts->common)) {
+               rc = PTR_ERR(opts->common);
+               goto release_opts;
+@@ -3734,8 +3624,6 @@ DECLARE_USB_FUNCTION_INIT(mass_storage, fsg_alloc_inst, fsg_alloc);
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Michal Nazarewicz");
+-#endif
+-
+ /************************* Module parameters *************************/
+@@ -3771,5 +3659,5 @@ void fsg_config_from_params(struct fsg_config *cfg,
+       cfg->can_stall = params->stall;
+       cfg->fsg_num_buffers = fsg_num_buffers;
+ }
+-EXPORT_SYMBOL_GPL_IF_MODULE(fsg_config_from_params);
++EXPORT_SYMBOL_GPL(fsg_config_from_params);
+diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h
+index 7d421d2..b4866fc 100644
+--- a/drivers/usb/gadget/f_mass_storage.h
++++ b/drivers/usb/gadget/f_mass_storage.h
+@@ -128,10 +128,6 @@ void fsg_common_get(struct fsg_common *common);
+ void fsg_common_put(struct fsg_common *common);
+-struct fsg_common *fsg_common_init(struct fsg_common *common,
+-                                 struct usb_composite_dev *cdev,
+-                                 struct fsg_config *cfg);
+-
+ void fsg_common_set_sysfs(struct fsg_common *common, bool sysfs);
+ int fsg_common_set_num_buffers(struct fsg_common *common, unsigned int n);
+@@ -167,21 +163,4 @@ void fsg_config_from_params(struct fsg_config *cfg,
+                           const struct fsg_module_parameters *params,
+                           unsigned int fsg_num_buffers);
+-static inline struct fsg_common *
+-fsg_common_from_params(struct fsg_common *common,
+-                     struct usb_composite_dev *cdev,
+-                     const struct fsg_module_parameters *params,
+-                     unsigned int fsg_num_buffers)
+-      __attribute__((unused));
+-static inline struct fsg_common *
+-fsg_common_from_params(struct fsg_common *common,
+-                     struct usb_composite_dev *cdev,
+-                     const struct fsg_module_parameters *params,
+-                     unsigned int fsg_num_buffers)
+-{
+-      struct fsg_config cfg;
+-      fsg_config_from_params(&cfg, params, fsg_num_buffers);
+-      return fsg_common_init(common, cdev, &cfg);
+-}
+-
+ #endif /* USB_F_MASS_STORAGE_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1146-usb-gadget-mass_storage-merge-usb_f_mass_storage-mod.patch b/patches.tizen/1146-usb-gadget-mass_storage-merge-usb_f_mass_storage-mod.patch
new file mode 100644 (file)
index 0000000..6763fa2
--- /dev/null
@@ -0,0 +1,81 @@
+From ba3521fba7a16b385e34da91f73b4876db2d4bef Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 9 Oct 2013 10:08:29 +0200
+Subject: [PATCH 1146/1302] usb: gadget: mass_storage: merge usb_f_mass_storage
+ module with u_ms module
+
+u_ms.ko is needed only together with usb_f_mass_storage.ko. Merge them.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig  | 7 -------
+ drivers/usb/gadget/Makefile | 4 +---
+ 2 files changed, 1 insertion(+), 10 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index df9c040..93dfc90 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -537,9 +537,6 @@ config USB_F_SUBSET
+ config USB_F_RNDIS
+       tristate
+-config USB_U_MS
+-      tristate
+-
+ config USB_F_MASS_STORAGE
+       tristate
+@@ -683,7 +680,6 @@ config USB_CONFIGFS_PHONET
+ config USB_CONFIGFS_MASS_STORAGE
+       boolean "Mass storage"
+       depends on USB_CONFIGFS
+-      select USB_U_MS
+       select USB_F_MASS_STORAGE
+       help
+         The Mass Storage Gadget acts as a USB Mass Storage disk drive.
+@@ -907,7 +903,6 @@ config USB_MASS_STORAGE
+       tristate "Mass Storage Gadget"
+       depends on BLOCK
+       select USB_LIBCOMPOSITE
+-      select USB_U_MS
+       select USB_F_MASS_STORAGE
+       help
+         The Mass Storage Gadget acts as a USB Mass Storage disk drive.
+@@ -1044,7 +1039,6 @@ config USB_G_ACM_MS
+       select USB_LIBCOMPOSITE
+       select USB_U_SERIAL
+       select USB_F_ACM
+-      select USB_U_MS
+       select USB_F_MASS_STORAGE
+       help
+         This driver provides two functions in one configuration:
+@@ -1061,7 +1055,6 @@ config USB_G_MULTI
+       select USB_U_SERIAL
+       select USB_U_ETHER
+       select USB_F_ACM
+-      select USB_U_MS
+       select USB_F_MASS_STORAGE
+       help
+         The Multifunction Composite Gadget provides Ethernet (RNDIS
+diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
+index 62ccbda..345a49c 100644
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -60,9 +60,7 @@ usb_f_ecm_subset-y           := f_subset.o
+ obj-$(CONFIG_USB_F_SUBSET)    += usb_f_ecm_subset.o
+ usb_f_rndis-y                 := f_rndis.o
+ obj-$(CONFIG_USB_F_RNDIS)     += usb_f_rndis.o
+-u_ms-y                                := storage_common.o
+-obj-$(CONFIG_USB_U_MS)                += u_ms.o
+-usb_f_mass_storage-y          := f_mass_storage.o
++usb_f_mass_storage-y          := f_mass_storage.o storage_common.o
+ obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o
+ #
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1147-usb-gadget-storage_common-use-strtobool-instead-of-k.patch b/patches.tizen/1147-usb-gadget-storage_common-use-strtobool-instead-of-k.patch
new file mode 100644 (file)
index 0000000..6cf4f36
--- /dev/null
@@ -0,0 +1,76 @@
+From 11b507b7e86967ce345240b5df9c7891f2c0f784 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 15 Oct 2013 08:33:12 +0200
+Subject: [PATCH 1147/1302] usb: gadget: storage_common: use strtobool instead
+ of kstrtouint
+
+strtobool is more flexible for the user and is more appropriate in the
+context.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/storage_common.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
+index c7b78a1..8bd5f2d 100644
+--- a/drivers/usb/gadget/storage_common.c
++++ b/drivers/usb/gadget/storage_common.c
+@@ -375,9 +375,9 @@ ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                    const char *buf, size_t count)
+ {
+       ssize_t         rc;
+-      unsigned        ro;
++      bool            ro;
+-      rc = kstrtouint(buf, 2, &ro);
++      rc = strtobool(buf, &ro);
+       if (rc)
+               return rc;
+@@ -402,10 +402,10 @@ EXPORT_SYMBOL(fsg_store_ro);
+ ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count)
+ {
+-      unsigned        nofua;
++      bool            nofua;
+       int             ret;
+-      ret = kstrtouint(buf, 2, &nofua);
++      ret = strtobool(buf, &nofua);
+       if (ret)
+               return ret;
+@@ -452,10 +452,10 @@ EXPORT_SYMBOL(fsg_store_file);
+ ssize_t fsg_store_cdrom(struct fsg_lun *curlun, const char *buf, size_t count)
+ {
+-      unsigned        cdrom;
++      bool            cdrom;
+       int             ret;
+-      ret = kstrtouint(buf, 2, &cdrom);
++      ret = strtobool(buf, &cdrom);
+       if (ret)
+               return ret;
+@@ -468,10 +468,10 @@ EXPORT_SYMBOL(fsg_store_cdrom);
+ ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf,
+                           size_t count)
+ {
+-      unsigned        removable;
++      bool            removable;
+       int             ret;
+-      ret = kstrtouint(buf, 2, &removable);
++      ret = strtobool(buf, &removable);
+       if (ret)
+               return ret;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1148-usb-gadget-storage_common-pass-filesem-to-fsg_store_.patch b/patches.tizen/1148-usb-gadget-storage_common-pass-filesem-to-fsg_store_.patch
new file mode 100644 (file)
index 0000000..c366156
--- /dev/null
@@ -0,0 +1,132 @@
+From 89f0b369bd38406e53ca51c87012a5daf788c51b Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 15 Oct 2013 08:33:13 +0200
+Subject: [PATCH 1148/1302] usb: gadget: storage_common: pass filesem to
+ fsg_store_cdrom
+
+If cdrom flag is set ro flag is implied. Try setting the ro first, and
+only if it succeeds set the cdrom flag.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c |  7 ++++++-
+ drivers/usb/gadget/storage_common.c | 42 +++++++++++++++++++++++++++----------
+ drivers/usb/gadget/storage_common.h |  3 ++-
+ 3 files changed, 39 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 6e5a6da..6b5f451 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -3281,7 +3281,12 @@ static ssize_t fsg_lun_opts_cdrom_show(struct fsg_lun_opts *opts, char *page)
+ static ssize_t fsg_lun_opts_cdrom_store(struct fsg_lun_opts *opts,
+                                      const char *page, size_t len)
+ {
+-      return fsg_store_cdrom(opts->lun, page, len);
++      struct fsg_opts *fsg_opts;
++
++      fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
++
++      return fsg_store_cdrom(opts->lun, &fsg_opts->common->filesem, page,
++                             len);
+ }
+ static struct fsg_lun_opts_attribute fsg_lun_opts_cdrom =
+diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
+index 8bd5f2d..ec20a1f 100644
+--- a/drivers/usb/gadget/storage_common.c
++++ b/drivers/usb/gadget/storage_common.c
+@@ -371,6 +371,23 @@ ssize_t fsg_show_removable(struct fsg_lun *curlun, char *buf)
+ }
+ EXPORT_SYMBOL(fsg_show_removable);
++/*
++ * The caller must hold fsg->filesem for reading when calling this function.
++ */
++static ssize_t _fsg_store_ro(struct fsg_lun *curlun, bool ro)
++{
++      if (fsg_lun_is_open(curlun)) {
++              LDBG(curlun, "read-only status change prevented\n");
++              return -EBUSY;
++      }
++
++      curlun->ro = ro;
++      curlun->initially_ro = ro;
++      LDBG(curlun, "read-only status set to %d\n", curlun->ro);
++
++      return 0;
++}
++
+ ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                    const char *buf, size_t count)
+ {
+@@ -386,16 +403,11 @@ ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+        * backing file is closed.
+        */
+       down_read(filesem);
+-      if (fsg_lun_is_open(curlun)) {
+-              LDBG(curlun, "read-only status change prevented\n");
+-              rc = -EBUSY;
+-      } else {
+-              curlun->ro = ro;
+-              curlun->initially_ro = ro;
+-              LDBG(curlun, "read-only status set to %d\n", curlun->ro);
++      rc = _fsg_store_ro(curlun, ro);
++      if (!rc)
+               rc = count;
+-      }
+       up_read(filesem);
++
+       return rc;
+ }
+ EXPORT_SYMBOL(fsg_store_ro);
+@@ -450,7 +462,8 @@ ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+ }
+ EXPORT_SYMBOL(fsg_store_file);
+-ssize_t fsg_store_cdrom(struct fsg_lun *curlun, const char *buf, size_t count)
++ssize_t fsg_store_cdrom(struct fsg_lun *curlun, struct rw_semaphore *filesem,
++                      const char *buf, size_t count)
+ {
+       bool            cdrom;
+       int             ret;
+@@ -459,9 +472,16 @@ ssize_t fsg_store_cdrom(struct fsg_lun *curlun, const char *buf, size_t count)
+       if (ret)
+               return ret;
+-      curlun->cdrom = cdrom;
++      down_read(filesem);
++      ret = cdrom ? _fsg_store_ro(curlun, true) : 0;
+-      return count;
++      if (!ret) {
++              curlun->cdrom = cdrom;
++              ret = count;
++      }
++      up_read(filesem);
++
++      return ret;
+ }
+ EXPORT_SYMBOL(fsg_store_cdrom);
+diff --git a/drivers/usb/gadget/storage_common.h b/drivers/usb/gadget/storage_common.h
+index e0f7aa6..c74c2fd 100644
+--- a/drivers/usb/gadget/storage_common.h
++++ b/drivers/usb/gadget/storage_common.h
+@@ -221,7 +221,8 @@ ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+ ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count);
+ ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                      const char *buf, size_t count);
+-ssize_t fsg_store_cdrom(struct fsg_lun *curlun, const char *buf, size_t count);
++ssize_t fsg_store_cdrom(struct fsg_lun *curlun, struct rw_semaphore *filesem,
++                      const char *buf, size_t count);
+ ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf,
+                           size_t count);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1149-usb-gadget-f_mass_storage-style-corrections-cleanup-.patch b/patches.tizen/1149-usb-gadget-f_mass_storage-style-corrections-cleanup-.patch
new file mode 100644 (file)
index 0000000..ba5c8fb
--- /dev/null
@@ -0,0 +1,111 @@
+From 9b78a9717d0e5c013aada03734afdfd30c5842b4 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 16 Oct 2013 08:34:51 +0200
+Subject: [PATCH 1149/1302] usb: gadget: f_mass_storage: style corrections,
+ cleanup & simplification
+
+Fix spacing, improve error code returned, remove unused #define,
+use strtobool() instead of kstrtou8().
+
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 37 ++++++++++++++++++-------------------
+ 1 file changed, 18 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 6b5f451..8fa8b1f7 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -3209,9 +3209,9 @@ static void fsg_lun_attr_release(struct config_item *item)
+ }
+ static struct configfs_item_operations fsg_lun_item_ops = {
+-      .release        = fsg_lun_attr_release,
+-      .show_attribute = fsg_lun_opts_attr_show,
+-      .store_attribute = fsg_lun_opts_attr_store,
++      .release                = fsg_lun_attr_release,
++      .show_attribute         = fsg_lun_opts_attr_show,
++      .store_attribute        = fsg_lun_opts_attr_store,
+ };
+ static ssize_t fsg_lun_opts_file_show(struct fsg_lun_opts *opts, char *page)
+@@ -3323,8 +3323,6 @@ static struct config_item_type fsg_lun_type = {
+       .ct_owner       = THIS_MODULE,
+ };
+-#define MAX_NAME_LEN  40
+-
+ static struct config_group *fsg_lun_make(struct config_group *group,
+                                        const char *name)
+ {
+@@ -3348,7 +3346,8 @@ static struct config_group *fsg_lun_make(struct config_group *group,
+       fsg_opts = to_fsg_opts(&group->cg_item);
+       if (num >= FSG_MAX_LUNS)
+-              return ERR_PTR(-ENODEV);
++              return ERR_PTR(-ERANGE);
++
+       mutex_lock(&fsg_opts->lock);
+       if (fsg_opts->refcnt || fsg_opts->common->luns[num]) {
+               ret = -EBUSY;
+@@ -3364,7 +3363,6 @@ static struct config_group *fsg_lun_make(struct config_group *group,
+       memset(&config, 0, sizeof(config));
+       config.removable = true;
+-
+       ret = fsg_common_create_lun(fsg_opts->common, &config, num, name,
+                                   (const char **)&group->cg_item.ci_name);
+       if (ret) {
+@@ -3418,9 +3416,9 @@ static void fsg_attr_release(struct config_item *item)
+ }
+ static struct configfs_item_operations fsg_item_ops = {
+-      .release        = fsg_attr_release,
+-      .show_attribute = fsg_opts_attr_show,
+-      .store_attribute = fsg_opts_attr_store,
++      .release                = fsg_attr_release,
++      .show_attribute         = fsg_opts_attr_show,
++      .store_attribute        = fsg_opts_attr_store,
+ };
+ static ssize_t fsg_opts_stall_show(struct fsg_opts *opts, char *page)
+@@ -3438,22 +3436,23 @@ static ssize_t fsg_opts_stall_store(struct fsg_opts *opts, const char *page,
+                                   size_t len)
+ {
+       int ret;
+-      u8 num;
++      bool stall;
+       mutex_lock(&opts->lock);
++
+       if (opts->refcnt) {
+-              ret = -EBUSY;
+-              goto end;
++              mutex_unlock(&opts->lock);
++              return -EBUSY;
+       }
+-      ret = kstrtou8(page, 0, &num);
+-      if (ret)
+-              goto end;
+-      opts->common->can_stall = num != 0;
+-      ret = len;
++      ret = strtobool(page, &stall);
++      if (!ret) {
++              opts->common->can_stall = stall;
++              ret = len;
++      }
+-end:
+       mutex_unlock(&opts->lock);
++
+       return ret;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1150-usb-gadget-f_mass_storage-use-string-literal-as-form.patch b/patches.tizen/1150-usb-gadget-f_mass_storage-use-string-literal-as-form.patch
new file mode 100644 (file)
index 0000000..0d64f24
--- /dev/null
@@ -0,0 +1,36 @@
+From 930117c1edccba0329f341e5846aa23e57590614 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Fri, 25 Oct 2013 09:09:27 +0200
+Subject: [PATCH 1150/1302] usb/gadget: f_mass_storage: use string literal as
+ format in dev_set_name
+
+Fix commit b27c08c953e994f792a03d9b7cbc5cf3f9844135 where dev_set_name()
+is used without a string literal as format.
+
+Reported-by: Fengguang Wu <fengguang.wu@intel.com>
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Cc: Kees Cook <keescook@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 8fa8b1f7..a03ba2c 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -2949,7 +2949,7 @@ int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg,
+               lun->dev.release = fsg_lun_release;
+               lun->dev.parent = &common->gadget->dev;
+               dev_set_drvdata(&lun->dev, &common->filesem);
+-              dev_set_name(&lun->dev, name);
++              dev_set_name(&lun->dev, "%s", name);
+               lun->name = dev_name(&lun->dev);
+               rc = fsg_common_add_sysfs(common, lun);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1151-usb-gadget-update-some-out-of-date-comments.patch b/patches.tizen/1151-usb-gadget-update-some-out-of-date-comments.patch
new file mode 100644 (file)
index 0000000..ebc43cc
--- /dev/null
@@ -0,0 +1,46 @@
+From a8e27dfa96ac009532faa6025753256768487581 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Thu, 14 Nov 2013 11:42:11 +0300
+Subject: [PATCH 1151/1302] usb: gadget: update some out of date comments
+
+These functions used to return negative errror codes but now they return
+ERR_PTRs.
+
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Acked-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/u_ether.c | 2 +-
+ drivers/usb/gadget/u_ether.h | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
+index 2aae0d6..b7d4f82 100644
+--- a/drivers/usb/gadget/u_ether.c
++++ b/drivers/usb/gadget/u_ether.c
+@@ -753,7 +753,7 @@ static struct device_type gadget_type = {
+  * gadget driver using this framework.  The link layer addresses are
+  * set up using module parameters.
+  *
+- * Returns negative errno, or zero on success
++ * Returns an eth_dev pointer on success, or an ERR_PTR on failure.
+  */
+ struct eth_dev *gether_setup_name(struct usb_gadget *g,
+               const char *dev_addr, const char *host_addr,
+diff --git a/drivers/usb/gadget/u_ether.h b/drivers/usb/gadget/u_ether.h
+index fb23d1f..a32b41e 100644
+--- a/drivers/usb/gadget/u_ether.h
++++ b/drivers/usb/gadget/u_ether.h
+@@ -106,7 +106,7 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g,
+  * gadget driver using this framework.  The link layer addresses are
+  * set up using module parameters.
+  *
+- * Returns negative errno, or zero on success
++ * Returns a eth_dev pointer on success, or an ERR_PTR on failure
+  */
+ static inline struct eth_dev *gether_setup(struct usb_gadget *g,
+               const char *dev_addr, const char *host_addr,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1152-usb-gadget-composite-redirect-setup-requests.patch b/patches.tizen/1152-usb-gadget-composite-redirect-setup-requests.patch
new file mode 100644 (file)
index 0000000..9c5f43f
--- /dev/null
@@ -0,0 +1,58 @@
+From 4ed27bd51c9c8bb18aa37b1508948d0b3f21545b Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 7 Nov 2013 08:41:25 +0100
+Subject: [PATCH 1152/1302] usb: gadget: composite: redirect setup requests
+
+If there are setup requests not directed to an endpont or an interface,
+current config's setup() has been attempted so far.
+This patch, in case the above fails, adds code which tries the setup() of
+configuration's function if there is only one function in the configuration.
+
+This behavior is required to provide equivalent of gadget zero with configfs.
+
+The gadget zero has a "config driver" for sourcesink, but all it does is
+delegating the request to the function proper. So when the equivalent gadget
+is set up with configfs it needs to handle requests directed to
+"config driver", but with configfs it is not possible to specify
+"config drivers".
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/composite.c | 16 +++++++++++++++-
+ 1 file changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
+index d4f0f33..6c0d25d 100644
+--- a/drivers/usb/gadget/composite.c
++++ b/drivers/usb/gadget/composite.c
+@@ -1451,8 +1451,22 @@ unknown:
+                       struct usb_configuration        *c;
+                       c = cdev->config;
+-                      if (c && c->setup)
++                      if (!c)
++                              goto done;
++
++                      /* try current config's setup */
++                      if (c->setup) {
+                               value = c->setup(c, ctrl);
++                              goto done;
++                      }
++
++                      /* try the only function in the current config */
++                      if (!list_is_singular(&c->functions))
++                              goto done;
++                      f = list_first_entry(&c->functions, struct usb_function,
++                                           list);
++                      if (f->setup)
++                              value = f->setup(f, ctrl);
+               }
+               goto done;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1153-usb-gadget-factor-out-alloc_ep_req.patch b/patches.tizen/1153-usb-gadget-factor-out-alloc_ep_req.patch
new file mode 100644 (file)
index 0000000..a08cbc1
--- /dev/null
@@ -0,0 +1,300 @@
+From d58d2f708974a16cd318fabff0a7f2d0fb6fcff0 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 7 Nov 2013 08:41:26 +0100
+Subject: [PATCH 1153/1302] usb: gadget: factor out alloc_ep_req
+
+alloc_ep_req() is a function repeated in several modules.
+Make a common implementation and use it.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Makefile       |  2 +-
+ drivers/usb/gadget/f_hid.c        | 18 +++++-------------
+ drivers/usb/gadget/f_loopback.c   |  8 +++++++-
+ drivers/usb/gadget/f_midi.c       | 22 +++++++---------------
+ drivers/usb/gadget/f_sourcesink.c | 23 +++++------------------
+ drivers/usb/gadget/g_zero.h       |  1 -
+ drivers/usb/gadget/u_f.c          | 32 ++++++++++++++++++++++++++++++++
+ drivers/usb/gadget/u_f.h          | 26 ++++++++++++++++++++++++++
+ 8 files changed, 83 insertions(+), 49 deletions(-)
+ create mode 100644 drivers/usb/gadget/u_f.c
+ create mode 100644 drivers/usb/gadget/u_f.h
+
+diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
+index 345a49c..e43af2e 100644
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -6,7 +6,7 @@ ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG
+ obj-$(CONFIG_USB_GADGET)      += udc-core.o
+ obj-$(CONFIG_USB_LIBCOMPOSITE)        += libcomposite.o
+ libcomposite-y                        := usbstring.o config.o epautoconf.o
+-libcomposite-y                        += composite.o functions.o configfs.o
++libcomposite-y                        += composite.o functions.o configfs.o u_f.o
+ obj-$(CONFIG_USB_DUMMY_HCD)   += dummy_hcd.o
+ obj-$(CONFIG_USB_NET2272)     += net2272.o
+ obj-$(CONFIG_USB_NET2280)     += net2280.o
+diff --git a/drivers/usb/gadget/f_hid.c b/drivers/usb/gadget/f_hid.c
+index 6e69a8e..a95290a 100644
+--- a/drivers/usb/gadget/f_hid.c
++++ b/drivers/usb/gadget/f_hid.c
+@@ -20,6 +20,8 @@
+ #include <linux/sched.h>
+ #include <linux/usb/g_hid.h>
++#include "u_f.h"
++
+ static int major, minors;
+ static struct class *hidg_class;
+@@ -334,20 +336,10 @@ static int f_hidg_open(struct inode *inode, struct file *fd)
+ /*-------------------------------------------------------------------------*/
+ /*                                usb_function                             */
+-static struct usb_request *hidg_alloc_ep_req(struct usb_ep *ep, unsigned length)
++static inline struct usb_request *hidg_alloc_ep_req(struct usb_ep *ep,
++                                                  unsigned length)
+ {
+-      struct usb_request *req;
+-
+-      req = usb_ep_alloc_request(ep, GFP_ATOMIC);
+-      if (req) {
+-              req->length = length;
+-              req->buf = kmalloc(length, GFP_ATOMIC);
+-              if (!req->buf) {
+-                      usb_ep_free_request(ep, req);
+-                      req = NULL;
+-              }
+-      }
+-      return req;
++      return alloc_ep_req(ep, length, length);
+ }
+ static void hidg_set_report_complete(struct usb_ep *ep, struct usb_request *req)
+diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c
+index 4a3873a..b790653 100644
+--- a/drivers/usb/gadget/f_loopback.c
++++ b/drivers/usb/gadget/f_loopback.c
+@@ -20,6 +20,7 @@
+ #include <linux/usb/composite.h>
+ #include "g_zero.h"
++#include "u_f.h"
+ /*
+  * LOOPBACK FUNCTION ... a testing vehicle for USB peripherals,
+@@ -293,6 +294,11 @@ static void disable_loopback(struct f_loopback *loop)
+       VDBG(cdev, "%s disabled\n", loop->function.name);
+ }
++static inline struct usb_request *lb_alloc_ep_req(struct usb_ep *ep, int len)
++{
++      return alloc_ep_req(ep, len, buflen);
++}
++
+ static int
+ enable_loopback(struct usb_composite_dev *cdev, struct f_loopback *loop)
+ {
+@@ -332,7 +338,7 @@ fail0:
+        * than 'buflen' bytes each.
+        */
+       for (i = 0; i < qlen && result == 0; i++) {
+-              req = alloc_ep_req(ep, 0);
++              req = lb_alloc_ep_req(ep, 0);
+               if (req) {
+                       req->complete = loopback_complete;
+                       result = usb_ep_queue(ep, req, GFP_ATOMIC);
+diff --git a/drivers/usb/gadget/f_midi.c b/drivers/usb/gadget/f_midi.c
+index 263e721..36d4bb2 100644
+--- a/drivers/usb/gadget/f_midi.c
++++ b/drivers/usb/gadget/f_midi.c
+@@ -32,6 +32,8 @@
+ #include <linux/usb/audio.h>
+ #include <linux/usb/midi.h>
++#include "u_f.h"
++
+ MODULE_AUTHOR("Ben Williamson");
+ MODULE_LICENSE("GPL v2");
+@@ -191,20 +193,10 @@ static struct usb_gadget_strings *midi_strings[] = {
+       NULL,
+ };
+-static struct usb_request *alloc_ep_req(struct usb_ep *ep, unsigned length)
++static inline struct usb_request *midi_alloc_ep_req(struct usb_ep *ep,
++                                                  unsigned length)
+ {
+-      struct usb_request *req;
+-
+-      req = usb_ep_alloc_request(ep, GFP_ATOMIC);
+-      if (req) {
+-              req->length = length;
+-              req->buf = kmalloc(length, GFP_ATOMIC);
+-              if (!req->buf) {
+-                      usb_ep_free_request(ep, req);
+-                      req = NULL;
+-              }
+-      }
+-      return req;
++      return alloc_ep_req(ep, length, length);
+ }
+ static void free_ep_req(struct usb_ep *ep, struct usb_request *req)
+@@ -365,7 +357,7 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
+       /* allocate a bunch of read buffers and queue them all at once. */
+       for (i = 0; i < midi->qlen && err == 0; i++) {
+               struct usb_request *req =
+-                      alloc_ep_req(midi->out_ep, midi->buflen);
++                      midi_alloc_ep_req(midi->out_ep, midi->buflen);
+               if (req == NULL)
+                       return -ENOMEM;
+@@ -546,7 +538,7 @@ static void f_midi_transmit(struct f_midi *midi, struct usb_request *req)
+               return;
+       if (!req)
+-              req = alloc_ep_req(ep, midi->buflen);
++              req = midi_alloc_ep_req(ep, midi->buflen);
+       if (!req) {
+               ERROR(midi, "gmidi_transmit: alloc_ep_request failed\n");
+diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c
+index a889585..c5ad4a1 100644
+--- a/drivers/usb/gadget/f_sourcesink.c
++++ b/drivers/usb/gadget/f_sourcesink.c
+@@ -21,6 +21,7 @@
+ #include "g_zero.h"
+ #include "gadget_chips.h"
++#include "u_f.h"
+ /*
+  * SOURCE/SINK FUNCTION ... a primary testing vehicle for USB peripheral
+@@ -301,23 +302,9 @@ static struct usb_gadget_strings *sourcesink_strings[] = {
+ /*-------------------------------------------------------------------------*/
+-struct usb_request *alloc_ep_req(struct usb_ep *ep, int len)
++static inline struct usb_request *ss_alloc_ep_req(struct usb_ep *ep, int len)
+ {
+-      struct usb_request      *req;
+-
+-      req = usb_ep_alloc_request(ep, GFP_ATOMIC);
+-      if (req) {
+-              if (len)
+-                      req->length = len;
+-              else
+-                      req->length = buflen;
+-              req->buf = kmalloc(req->length, GFP_ATOMIC);
+-              if (!req->buf) {
+-                      usb_ep_free_request(ep, req);
+-                      req = NULL;
+-              }
+-      }
+-      return req;
++      return alloc_ep_req(ep, len, buflen);
+ }
+ void free_ep_req(struct usb_ep *ep, struct usb_request *req)
+@@ -628,10 +615,10 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in,
+                               break;
+                       }
+                       ep = is_in ? ss->iso_in_ep : ss->iso_out_ep;
+-                      req = alloc_ep_req(ep, size);
++                      req = ss_alloc_ep_req(ep, size);
+               } else {
+                       ep = is_in ? ss->in_ep : ss->out_ep;
+-                      req = alloc_ep_req(ep, 0);
++                      req = ss_alloc_ep_req(ep, 0);
+               }
+               if (!req)
+diff --git a/drivers/usb/gadget/g_zero.h b/drivers/usb/gadget/g_zero.h
+index ef3e851..a1c1a97 100644
+--- a/drivers/usb/gadget/g_zero.h
++++ b/drivers/usb/gadget/g_zero.h
+@@ -36,7 +36,6 @@ void lb_modexit(void);
+ int lb_modinit(void);
+ /* common utilities */
+-struct usb_request *alloc_ep_req(struct usb_ep *ep, int len);
+ void free_ep_req(struct usb_ep *ep, struct usb_request *req);
+ void disable_endpoints(struct usb_composite_dev *cdev,
+               struct usb_ep *in, struct usb_ep *out,
+diff --git a/drivers/usb/gadget/u_f.c b/drivers/usb/gadget/u_f.c
+new file mode 100644
+index 0000000..63b6642
+--- /dev/null
++++ b/drivers/usb/gadget/u_f.c
+@@ -0,0 +1,32 @@
++/*
++ * u_f.c -- USB function utilities for Gadget stack
++ *
++ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
++ *            http://www.samsung.com
++ *
++ * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.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/usb/gadget.h>
++#include "u_f.h"
++
++struct usb_request *alloc_ep_req(struct usb_ep *ep, int len, int default_len)
++{
++      struct usb_request      *req;
++
++      req = usb_ep_alloc_request(ep, GFP_ATOMIC);
++      if (req) {
++              req->length = len ?: default_len;
++              req->buf = kmalloc(req->length, GFP_ATOMIC);
++              if (!req->buf) {
++                      usb_ep_free_request(ep, req);
++                      req = NULL;
++              }
++      }
++      return req;
++}
++EXPORT_SYMBOL(alloc_ep_req);
+diff --git a/drivers/usb/gadget/u_f.h b/drivers/usb/gadget/u_f.h
+new file mode 100644
+index 0000000..71034c0
+--- /dev/null
++++ b/drivers/usb/gadget/u_f.h
+@@ -0,0 +1,26 @@
++/*
++ * u_f.h
++ *
++ * Utility definitions for USB functions
++ *
++ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
++ *            http://www.samsung.com
++ *
++ * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.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 __U_F_H__
++#define __U_F_H__
++
++struct usb_ep;
++struct usb_request;
++
++struct usb_request *alloc_ep_req(struct usb_ep *ep, int len, int default_len);
++
++#endif /* __U_F_H__ */
++
++
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1154-usb-gadget-f_loopback-add-configfs-support.patch b/patches.tizen/1154-usb-gadget-f_loopback-add-configfs-support.patch
new file mode 100644 (file)
index 0000000..5465e05
--- /dev/null
@@ -0,0 +1,271 @@
+From da7bcc85a6906e80da706bef57d1687f942e3910 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 7 Nov 2013 08:41:27 +0100
+Subject: [PATCH 1154/1302] usb: gadget: f_loopback: add configfs support
+
+Add support for using the loopback USB function in gadgets composed with
+configfs.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../ABI/testing/configfs-usb-gadget-loopback       |   8 ++
+ drivers/usb/gadget/Kconfig                         |  12 ++
+ drivers/usb/gadget/f_loopback.c                    | 132 +++++++++++++++++++++
+ drivers/usb/gadget/g_zero.h                        |  12 ++
+ drivers/usb/gadget/zero.c                          |   4 +-
+ 5 files changed, 166 insertions(+), 2 deletions(-)
+ create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-loopback
+
+diff --git a/Documentation/ABI/testing/configfs-usb-gadget-loopback b/Documentation/ABI/testing/configfs-usb-gadget-loopback
+new file mode 100644
+index 0000000..852b236
+--- /dev/null
++++ b/Documentation/ABI/testing/configfs-usb-gadget-loopback
+@@ -0,0 +1,8 @@
++What:         /config/usb-gadget/gadget/functions/Loopback.name
++Date:         Nov 2013
++KenelVersion: 3.13
++Description:
++              The attributes:
++
++              qlen            - depth of loopback queue
++              bulk_buflen     - buffer length
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 93dfc90..6baddd5 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -687,6 +687,18 @@ config USB_CONFIGFS_MASS_STORAGE
+         device (in much the same way as the "loop" device driver),
+         specified as a module parameter or sysfs option.
++config USB_CONFIGFS_F_LB
++      boolean "Loopback function (for testing)"
++      depends on USB_CONFIGFS
++      select USB_F_SS_LB
++      help
++        It loops back a configurable number of transfers.
++        It also implements control requests, for "chapter 9" conformance.
++        Make this be the first driver you try using on top of any new
++        USB peripheral controller driver.  Then you can use host-side
++        test software, like the "usbtest" driver, to put your hardware
++        and its driver through a basic set of functional tests.
++
+ config USB_ZERO
+       tristate "Gadget Zero (DEVELOPMENT)"
+       select USB_LIBCOMPOSITE
+diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c
+index b790653..c35bb40 100644
+--- a/drivers/usb/gadget/f_loopback.c
++++ b/drivers/usb/gadget/f_loopback.c
+@@ -231,6 +231,14 @@ autoconf_fail:
+ static void lb_free_func(struct usb_function *f)
+ {
++      struct f_lb_opts *opts;
++
++      opts = container_of(f->fi, struct f_lb_opts, func_inst);
++
++      mutex_lock(&opts->lock);
++      opts->refcnt--;
++      mutex_unlock(&opts->lock);
++
+       usb_free_all_descriptors(f);
+       kfree(func_to_loop(f));
+ }
+@@ -386,6 +394,11 @@ static struct usb_function *loopback_alloc(struct usb_function_instance *fi)
+               return ERR_PTR(-ENOMEM);
+       lb_opts = container_of(fi, struct f_lb_opts, func_inst);
++
++      mutex_lock(&lb_opts->lock);
++      lb_opts->refcnt++;
++      mutex_unlock(&lb_opts->lock);
++
+       buflen = lb_opts->bulk_buflen;
+       qlen = lb_opts->qlen;
+       if (!qlen)
+@@ -402,6 +415,118 @@ static struct usb_function *loopback_alloc(struct usb_function_instance *fi)
+       return &loop->function;
+ }
++static inline struct f_lb_opts *to_f_lb_opts(struct config_item *item)
++{
++      return container_of(to_config_group(item), struct f_lb_opts,
++                          func_inst.group);
++}
++
++CONFIGFS_ATTR_STRUCT(f_lb_opts);
++CONFIGFS_ATTR_OPS(f_lb_opts);
++
++static void lb_attr_release(struct config_item *item)
++{
++      struct f_lb_opts *lb_opts = to_f_lb_opts(item);
++
++      usb_put_function_instance(&lb_opts->func_inst);
++}
++
++static struct configfs_item_operations lb_item_ops = {
++      .release                = lb_attr_release,
++      .show_attribute         = f_lb_opts_attr_show,
++      .store_attribute        = f_lb_opts_attr_store,
++};
++
++static ssize_t f_lb_opts_qlen_show(struct f_lb_opts *opts, char *page)
++{
++      int result;
++
++      mutex_lock(&opts->lock);
++      result = sprintf(page, "%d", opts->qlen);
++      mutex_unlock(&opts->lock);
++
++      return result;
++}
++
++static ssize_t f_lb_opts_qlen_store(struct f_lb_opts *opts,
++                                  const char *page, size_t len)
++{
++      int ret;
++      u32 num;
++
++      mutex_lock(&opts->lock);
++      if (opts->refcnt) {
++              ret = -EBUSY;
++              goto end;
++      }
++
++      ret = kstrtou32(page, 0, &num);
++      if (ret)
++              goto end;
++
++      opts->qlen = num;
++      ret = len;
++end:
++      mutex_unlock(&opts->lock);
++      return ret;
++}
++
++static struct f_lb_opts_attribute f_lb_opts_qlen =
++      __CONFIGFS_ATTR(qlen, S_IRUGO | S_IWUSR,
++                      f_lb_opts_qlen_show,
++                      f_lb_opts_qlen_store);
++
++static ssize_t f_lb_opts_bulk_buflen_show(struct f_lb_opts *opts, char *page)
++{
++      int result;
++
++      mutex_lock(&opts->lock);
++      result = sprintf(page, "%d", opts->bulk_buflen);
++      mutex_unlock(&opts->lock);
++
++      return result;
++}
++
++static ssize_t f_lb_opts_bulk_buflen_store(struct f_lb_opts *opts,
++                                  const char *page, size_t len)
++{
++      int ret;
++      u32 num;
++
++      mutex_lock(&opts->lock);
++      if (opts->refcnt) {
++              ret = -EBUSY;
++              goto end;
++      }
++
++      ret = kstrtou32(page, 0, &num);
++      if (ret)
++              goto end;
++
++      opts->bulk_buflen = num;
++      ret = len;
++end:
++      mutex_unlock(&opts->lock);
++      return ret;
++}
++
++static struct f_lb_opts_attribute f_lb_opts_bulk_buflen =
++      __CONFIGFS_ATTR(buflen, S_IRUGO | S_IWUSR,
++                      f_lb_opts_bulk_buflen_show,
++                      f_lb_opts_bulk_buflen_store);
++
++static struct configfs_attribute *lb_attrs[] = {
++      &f_lb_opts_qlen.attr,
++      &f_lb_opts_bulk_buflen.attr,
++      NULL,
++};
++
++static struct config_item_type lb_func_type = {
++      .ct_item_ops    = &lb_item_ops,
++      .ct_attrs       = lb_attrs,
++      .ct_owner       = THIS_MODULE,
++};
++
+ static void lb_free_instance(struct usb_function_instance *fi)
+ {
+       struct f_lb_opts *lb_opts;
+@@ -417,7 +542,14 @@ static struct usb_function_instance *loopback_alloc_instance(void)
+       lb_opts = kzalloc(sizeof(*lb_opts), GFP_KERNEL);
+       if (!lb_opts)
+               return ERR_PTR(-ENOMEM);
++      mutex_init(&lb_opts->lock);
+       lb_opts->func_inst.free_func_inst = lb_free_instance;
++      lb_opts->bulk_buflen = GZERO_BULK_BUFLEN;
++      lb_opts->qlen = GZERO_QLEN;
++
++      config_group_init_type_name(&lb_opts->func_inst.group, "",
++                                  &lb_func_type);
++
+       return  &lb_opts->func_inst;
+ }
+ DECLARE_USB_FUNCTION(Loopback, loopback_alloc_instance, loopback_alloc);
+diff --git a/drivers/usb/gadget/g_zero.h b/drivers/usb/gadget/g_zero.h
+index a1c1a97..19ec50a 100644
+--- a/drivers/usb/gadget/g_zero.h
++++ b/drivers/usb/gadget/g_zero.h
+@@ -6,6 +6,9 @@
+ #ifndef __G_ZERO_H
+ #define __G_ZERO_H
++#define GZERO_BULK_BUFLEN     4096
++#define GZERO_QLEN            32
++
+ struct usb_zero_options {
+       unsigned pattern;
+       unsigned isoc_interval;
+@@ -30,6 +33,15 @@ struct f_lb_opts {
+       struct usb_function_instance func_inst;
+       unsigned bulk_buflen;
+       unsigned qlen;
++
++      /*
++       * Read/write access to configfs attributes is handled by configfs.
++       *
++       * This is to protect the data from concurrent access by read/write
++       * and create symlink/remove symlink.
++       */
++      struct mutex                    lock;
++      int                             refcnt;
+ };
+ void lb_modexit(void);
+diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
+index 0dd07ae..d954bba 100644
+--- a/drivers/usb/gadget/zero.c
++++ b/drivers/usb/gadget/zero.c
+@@ -66,8 +66,8 @@ module_param(loopdefault, bool, S_IRUGO|S_IWUSR);
+ static struct usb_zero_options gzero_options = {
+       .isoc_interval = 4,
+       .isoc_maxpacket = 1024,
+-      .bulk_buflen = 4096,
+-      .qlen = 32,
++      .bulk_buflen = GZERO_BULK_BUFLEN,
++      .qlen = GZERO_QLEN,
+ };
+ /*-------------------------------------------------------------------------*/
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1155-usb-gadget-f_sourcesink-add-configfs-support.patch b/patches.tizen/1155-usb-gadget-f_sourcesink-add-configfs-support.patch
new file mode 100644 (file)
index 0000000..b2741e0
--- /dev/null
@@ -0,0 +1,458 @@
+From 4d1809440f234253100c3a4f75b9aec7f00b04ee Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 7 Nov 2013 08:41:28 +0100
+Subject: [PATCH 1155/1302] usb: gadget: f_sourcesink: add configfs support
+
+Add support for using the sourcesink function in gadgets composed with
+configfs.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../ABI/testing/configfs-usb-gadget-sourcesink     |  12 +
+ drivers/usb/gadget/Kconfig                         |   7 +-
+ drivers/usb/gadget/f_sourcesink.c                  | 318 +++++++++++++++++++++
+ drivers/usb/gadget/g_zero.h                        |  11 +
+ drivers/usb/gadget/zero.c                          |   4 +-
+ 5 files changed, 347 insertions(+), 5 deletions(-)
+ create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-sourcesink
+
+diff --git a/Documentation/ABI/testing/configfs-usb-gadget-sourcesink b/Documentation/ABI/testing/configfs-usb-gadget-sourcesink
+new file mode 100644
+index 0000000..a30f309
+--- /dev/null
++++ b/Documentation/ABI/testing/configfs-usb-gadget-sourcesink
+@@ -0,0 +1,12 @@
++What:         /config/usb-gadget/gadget/functions/SourceSink.name
++Date:         Nov 2013
++KenelVersion: 3.13
++Description:
++              The attributes:
++
++              pattern         - 0 (all zeros), 1 (mod63), 2 (none)
++              isoc_interval   - 1..16
++              isoc_maxpacket  - 0 - 1023 (fs), 0 - 1024 (hs/ss)
++              isoc_mult       - 0..2 (hs/ss only)
++              isoc_maxburst   - 0..15 (ss only)
++              qlen            - buffer length
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 6baddd5..17890bc 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -687,12 +687,13 @@ config USB_CONFIGFS_MASS_STORAGE
+         device (in much the same way as the "loop" device driver),
+         specified as a module parameter or sysfs option.
+-config USB_CONFIGFS_F_LB
+-      boolean "Loopback function (for testing)"
++config USB_CONFIGFS_F_LB_SS
++      boolean "Loopback and sourcesink function (for testing)"
+       depends on USB_CONFIGFS
+       select USB_F_SS_LB
+       help
+-        It loops back a configurable number of transfers.
++        Loopback function loops back a configurable number of transfers.
++        Sourcesink function either sinks and sources bulk data.
+         It also implements control requests, for "chapter 9" conformance.
+         Make this be the first driver you try using on top of any new
+         USB peripheral controller driver.  Then you can use host-side
+diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c
+index c5ad4a1..5d4251e 100644
+--- a/drivers/usb/gadget/f_sourcesink.c
++++ b/drivers/usb/gadget/f_sourcesink.c
+@@ -477,6 +477,14 @@ no_iso:
+ static void
+ sourcesink_free_func(struct usb_function *f)
+ {
++      struct f_ss_opts *opts;
++
++      opts = container_of(f->fi, struct f_ss_opts, func_inst);
++
++      mutex_lock(&opts->lock);
++      opts->refcnt--;
++      mutex_unlock(&opts->lock);
++
+       usb_free_all_descriptors(f);
+       kfree(func_to_ss(f));
+ }
+@@ -865,6 +873,11 @@ static struct usb_function *source_sink_alloc_func(
+               return NULL;
+       ss_opts =  container_of(fi, struct f_ss_opts, func_inst);
++
++      mutex_lock(&ss_opts->lock);
++      ss_opts->refcnt++;
++      mutex_unlock(&ss_opts->lock);
++
+       pattern = ss_opts->pattern;
+       isoc_interval = ss_opts->isoc_interval;
+       isoc_maxpacket = ss_opts->isoc_maxpacket;
+@@ -885,6 +898,303 @@ static struct usb_function *source_sink_alloc_func(
+       return &ss->function;
+ }
++static inline struct f_ss_opts *to_f_ss_opts(struct config_item *item)
++{
++      return container_of(to_config_group(item), struct f_ss_opts,
++                          func_inst.group);
++}
++
++CONFIGFS_ATTR_STRUCT(f_ss_opts);
++CONFIGFS_ATTR_OPS(f_ss_opts);
++
++static void ss_attr_release(struct config_item *item)
++{
++      struct f_ss_opts *ss_opts = to_f_ss_opts(item);
++
++      usb_put_function_instance(&ss_opts->func_inst);
++}
++
++static struct configfs_item_operations ss_item_ops = {
++      .release                = ss_attr_release,
++      .show_attribute         = f_ss_opts_attr_show,
++      .store_attribute        = f_ss_opts_attr_store,
++};
++
++static ssize_t f_ss_opts_pattern_show(struct f_ss_opts *opts, char *page)
++{
++      int result;
++
++      mutex_lock(&opts->lock);
++      result = sprintf(page, "%d", opts->pattern);
++      mutex_unlock(&opts->lock);
++
++      return result;
++}
++
++static ssize_t f_ss_opts_pattern_store(struct f_ss_opts *opts,
++                                     const char *page, size_t len)
++{
++      int ret;
++      u8 num;
++
++      mutex_lock(&opts->lock);
++      if (opts->refcnt) {
++              ret = -EBUSY;
++              goto end;
++      }
++
++      ret = kstrtou8(page, 0, &num);
++      if (ret)
++              goto end;
++
++      if (num != 0 && num != 1 && num != 2) {
++              ret = -EINVAL;
++              goto end;
++      }
++
++      opts->pattern = num;
++      ret = len;
++end:
++      mutex_unlock(&opts->lock);
++      return ret;
++}
++
++static struct f_ss_opts_attribute f_ss_opts_pattern =
++      __CONFIGFS_ATTR(pattern, S_IRUGO | S_IWUSR,
++                      f_ss_opts_pattern_show,
++                      f_ss_opts_pattern_store);
++
++static ssize_t f_ss_opts_isoc_interval_show(struct f_ss_opts *opts, char *page)
++{
++      int result;
++
++      mutex_lock(&opts->lock);
++      result = sprintf(page, "%d", opts->isoc_interval);
++      mutex_unlock(&opts->lock);
++
++      return result;
++}
++
++static ssize_t f_ss_opts_isoc_interval_store(struct f_ss_opts *opts,
++                                     const char *page, size_t len)
++{
++      int ret;
++      u8 num;
++
++      mutex_lock(&opts->lock);
++      if (opts->refcnt) {
++              ret = -EBUSY;
++              goto end;
++      }
++
++      ret = kstrtou8(page, 0, &num);
++      if (ret)
++              goto end;
++
++      if (num > 16) {
++              ret = -EINVAL;
++              goto end;
++      }
++
++      opts->isoc_interval = num;
++      ret = len;
++end:
++      mutex_unlock(&opts->lock);
++      return ret;
++}
++
++static struct f_ss_opts_attribute f_ss_opts_isoc_interval =
++      __CONFIGFS_ATTR(isoc_interval, S_IRUGO | S_IWUSR,
++                      f_ss_opts_isoc_interval_show,
++                      f_ss_opts_isoc_interval_store);
++
++static ssize_t f_ss_opts_isoc_maxpacket_show(struct f_ss_opts *opts, char *page)
++{
++      int result;
++
++      mutex_lock(&opts->lock);
++      result = sprintf(page, "%d", opts->isoc_maxpacket);
++      mutex_unlock(&opts->lock);
++
++      return result;
++}
++
++static ssize_t f_ss_opts_isoc_maxpacket_store(struct f_ss_opts *opts,
++                                     const char *page, size_t len)
++{
++      int ret;
++      u16 num;
++
++      mutex_lock(&opts->lock);
++      if (opts->refcnt) {
++              ret = -EBUSY;
++              goto end;
++      }
++
++      ret = kstrtou16(page, 0, &num);
++      if (ret)
++              goto end;
++
++      if (num > 1024) {
++              ret = -EINVAL;
++              goto end;
++      }
++
++      opts->isoc_maxpacket = num;
++      ret = len;
++end:
++      mutex_unlock(&opts->lock);
++      return ret;
++}
++
++static struct f_ss_opts_attribute f_ss_opts_isoc_maxpacket =
++      __CONFIGFS_ATTR(isoc_maxpacket, S_IRUGO | S_IWUSR,
++                      f_ss_opts_isoc_maxpacket_show,
++                      f_ss_opts_isoc_maxpacket_store);
++
++static ssize_t f_ss_opts_isoc_mult_show(struct f_ss_opts *opts, char *page)
++{
++      int result;
++
++      mutex_lock(&opts->lock);
++      result = sprintf(page, "%d", opts->isoc_mult);
++      mutex_unlock(&opts->lock);
++
++      return result;
++}
++
++static ssize_t f_ss_opts_isoc_mult_store(struct f_ss_opts *opts,
++                                     const char *page, size_t len)
++{
++      int ret;
++      u8 num;
++
++      mutex_lock(&opts->lock);
++      if (opts->refcnt) {
++              ret = -EBUSY;
++              goto end;
++      }
++
++      ret = kstrtou8(page, 0, &num);
++      if (ret)
++              goto end;
++
++      if (num > 2) {
++              ret = -EINVAL;
++              goto end;
++      }
++
++      opts->isoc_mult = num;
++      ret = len;
++end:
++      mutex_unlock(&opts->lock);
++      return ret;
++}
++
++static struct f_ss_opts_attribute f_ss_opts_isoc_mult =
++      __CONFIGFS_ATTR(isoc_mult, S_IRUGO | S_IWUSR,
++                      f_ss_opts_isoc_mult_show,
++                      f_ss_opts_isoc_mult_store);
++
++static ssize_t f_ss_opts_isoc_maxburst_show(struct f_ss_opts *opts, char *page)
++{
++      int result;
++
++      mutex_lock(&opts->lock);
++      result = sprintf(page, "%d", opts->isoc_maxburst);
++      mutex_unlock(&opts->lock);
++
++      return result;
++}
++
++static ssize_t f_ss_opts_isoc_maxburst_store(struct f_ss_opts *opts,
++                                     const char *page, size_t len)
++{
++      int ret;
++      u8 num;
++
++      mutex_lock(&opts->lock);
++      if (opts->refcnt) {
++              ret = -EBUSY;
++              goto end;
++      }
++
++      ret = kstrtou8(page, 0, &num);
++      if (ret)
++              goto end;
++
++      if (num > 15) {
++              ret = -EINVAL;
++              goto end;
++      }
++
++      opts->isoc_maxburst = num;
++      ret = len;
++end:
++      mutex_unlock(&opts->lock);
++      return ret;
++}
++
++static struct f_ss_opts_attribute f_ss_opts_isoc_maxburst =
++      __CONFIGFS_ATTR(isoc_maxburst, S_IRUGO | S_IWUSR,
++                      f_ss_opts_isoc_maxburst_show,
++                      f_ss_opts_isoc_maxburst_store);
++
++static ssize_t f_ss_opts_bulk_buflen_show(struct f_ss_opts *opts, char *page)
++{
++      int result;
++
++      mutex_lock(&opts->lock);
++      result = sprintf(page, "%d", opts->bulk_buflen);
++      mutex_unlock(&opts->lock);
++
++      return result;
++}
++
++static ssize_t f_ss_opts_bulk_buflen_store(struct f_ss_opts *opts,
++                                         const char *page, size_t len)
++{
++      int ret;
++      u32 num;
++
++      mutex_lock(&opts->lock);
++      if (opts->refcnt) {
++              ret = -EBUSY;
++              goto end;
++      }
++
++      ret = kstrtou32(page, 0, &num);
++      if (ret)
++              goto end;
++
++      opts->bulk_buflen = num;
++      ret = len;
++end:
++      mutex_unlock(&opts->lock);
++      return ret;
++}
++
++static struct f_ss_opts_attribute f_ss_opts_bulk_buflen =
++      __CONFIGFS_ATTR(buflen, S_IRUGO | S_IWUSR,
++                      f_ss_opts_bulk_buflen_show,
++                      f_ss_opts_bulk_buflen_store);
++
++static struct configfs_attribute *ss_attrs[] = {
++      &f_ss_opts_pattern.attr,
++      &f_ss_opts_isoc_interval.attr,
++      &f_ss_opts_isoc_maxpacket.attr,
++      &f_ss_opts_isoc_mult.attr,
++      &f_ss_opts_isoc_maxburst.attr,
++      &f_ss_opts_bulk_buflen.attr,
++      NULL,
++};
++
++static struct config_item_type ss_func_type = {
++      .ct_item_ops    = &ss_item_ops,
++      .ct_attrs       = ss_attrs,
++      .ct_owner       = THIS_MODULE,
++};
++
+ static void source_sink_free_instance(struct usb_function_instance *fi)
+ {
+       struct f_ss_opts *ss_opts;
+@@ -900,7 +1210,15 @@ static struct usb_function_instance *source_sink_alloc_inst(void)
+       ss_opts = kzalloc(sizeof(*ss_opts), GFP_KERNEL);
+       if (!ss_opts)
+               return ERR_PTR(-ENOMEM);
++      mutex_init(&ss_opts->lock);
+       ss_opts->func_inst.free_func_inst = source_sink_free_instance;
++      ss_opts->isoc_interval = GZERO_ISOC_INTERVAL;
++      ss_opts->isoc_maxpacket = GZERO_ISOC_MAXPACKET;
++      ss_opts->bulk_buflen = GZERO_BULK_BUFLEN;
++
++      config_group_init_type_name(&ss_opts->func_inst.group, "",
++                                  &ss_func_type);
++
+       return &ss_opts->func_inst;
+ }
+ DECLARE_USB_FUNCTION(SourceSink, source_sink_alloc_inst,
+diff --git a/drivers/usb/gadget/g_zero.h b/drivers/usb/gadget/g_zero.h
+index 19ec50a..15f1809 100644
+--- a/drivers/usb/gadget/g_zero.h
++++ b/drivers/usb/gadget/g_zero.h
+@@ -8,6 +8,8 @@
+ #define GZERO_BULK_BUFLEN     4096
+ #define GZERO_QLEN            32
++#define GZERO_ISOC_INTERVAL   4
++#define GZERO_ISOC_MAXPACKET  1024
+ struct usb_zero_options {
+       unsigned pattern;
+@@ -27,6 +29,15 @@ struct f_ss_opts {
+       unsigned isoc_mult;
+       unsigned isoc_maxburst;
+       unsigned bulk_buflen;
++
++      /*
++       * Read/write access to configfs attributes is handled by configfs.
++       *
++       * This is to protect the data from concurrent access by read/write
++       * and create symlink/remove symlink.
++       */
++      struct mutex                    lock;
++      int                             refcnt;
+ };
+ struct f_lb_opts {
+diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
+index d954bba..00b4019 100644
+--- a/drivers/usb/gadget/zero.c
++++ b/drivers/usb/gadget/zero.c
+@@ -64,8 +64,8 @@ static bool loopdefault = 0;
+ module_param(loopdefault, bool, S_IRUGO|S_IWUSR);
+ static struct usb_zero_options gzero_options = {
+-      .isoc_interval = 4,
+-      .isoc_maxpacket = 1024,
++      .isoc_interval = GZERO_ISOC_INTERVAL,
++      .isoc_maxpacket = GZERO_ISOC_MAXPACKET,
+       .bulk_buflen = GZERO_BULK_BUFLEN,
+       .qlen = GZERO_QLEN,
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1156-usb-gadget-move-bitflags-to-the-end-of-usb_gadget-st.patch b/patches.tizen/1156-usb-gadget-move-bitflags-to-the-end-of-usb_gadget-st.patch
new file mode 100644 (file)
index 0000000..f46cbe5
--- /dev/null
@@ -0,0 +1,74 @@
+From 21722ed17ddbecdda49389258c389a87bae8c40f Mon Sep 17 00:00:00 2001
+From: David Cohen <david.a.cohen@linux.intel.com>
+Date: Tue, 10 Dec 2013 00:55:34 +0100
+Subject: [PATCH 1156/1302] usb: gadget: move bitflags to the end of usb_gadget
+ struct
+
+This patch moves all bitflags to the end of usb_gadget struct in order
+to improve readability.
+
+Signed-off-by: David Cohen <david.a.cohen@linux.intel.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+[backport from mainline]
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/usb/gadget.h | 19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
+index 16892ab..6241ace 100644
+--- a/include/linux/usb/gadget.h
++++ b/include/linux/usb/gadget.h
+@@ -483,6 +483,11 @@ struct usb_gadget_ops {
+  * @max_speed: Maximal speed the UDC can handle.  UDC must support this
+  *      and all slower speeds.
+  * @state: the state we are now (attached, suspended, configured, etc)
++ * @name: Identifies the controller hardware type.  Used in diagnostics
++ *    and sometimes configuration.
++ * @dev: Driver model state for this abstract device.
++ * @out_epnum: last used out ep number
++ * @in_epnum: last used in ep number
+  * @sg_supported: true if we can handle scatter-gather
+  * @is_otg: True if the USB device port uses a Mini-AB jack, so that the
+  *    gadget driver must provide a USB OTG descriptor.
+@@ -495,11 +500,6 @@ struct usb_gadget_ops {
+  *    only supports HNP on a different root port.
+  * @b_hnp_enable: OTG device feature flag, indicating that the A-Host
+  *    enabled HNP support.
+- * @name: Identifies the controller hardware type.  Used in diagnostics
+- *    and sometimes configuration.
+- * @dev: Driver model state for this abstract device.
+- * @out_epnum: last used out ep number
+- * @in_epnum: last used in ep number
+  *
+  * Gadgets have a mostly-portable "gadget driver" implementing device
+  * functions, handling all usb configurations and interfaces.  Gadget
+@@ -527,6 +527,11 @@ struct usb_gadget {
+       enum usb_device_speed           speed;
+       enum usb_device_speed           max_speed;
+       enum usb_device_state           state;
++      const char                      *name;
++      struct device                   dev;
++      unsigned                        out_epnum;
++      unsigned                        in_epnum;
++
+       unsigned                        sg_supported:1;
+       unsigned                        is_otg:1;
+       unsigned                        is_a_peripheral:1;
+@@ -534,10 +539,6 @@ struct usb_gadget {
+       unsigned                        a_hnp_support:1;
+       unsigned                        a_alt_hnp_support:1;
+       atomic_t                        connect_count;
+-      const char                      *name;
+-      struct device                   dev;
+-      unsigned                        out_epnum;
+-      unsigned                        in_epnum;
+ };
+ static inline void set_gadget_data(struct usb_gadget *gadget, void *data)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1157-usb-gadget-add-quirk_ep_out_aligned_size-field-to-st.patch b/patches.tizen/1157-usb-gadget-add-quirk_ep_out_aligned_size-field-to-st.patch
new file mode 100644 (file)
index 0000000..2fe8396
--- /dev/null
@@ -0,0 +1,75 @@
+From 2148003e5af1b424c6e677d248f79c2e30ea2c85 Mon Sep 17 00:00:00 2001
+From: David Cohen <david.a.cohen@linux.intel.com>
+Date: Tue, 10 Dec 2013 00:55:35 +0100
+Subject: [PATCH 1157/1302] usb: gadget: add quirk_ep_out_aligned_size field to
+ struct usb_gadget
+
+Due to USB controllers may have different restrictions, usb gadget layer
+needs to provide a generic way to inform gadget functions to complain
+with non-standard requirements.
+
+This patch adds 'quirk_ep_out_aligned_size' field to struct usb_gadget
+to inform when controller's epout requires buffer size to be aligned to
+MaxPacketSize. A helper is also provided to align buffer size when
+necessary.
+
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: David Cohen <david.a.cohen@linux.intel.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+[backport from mainline]
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/usb/gadget.h | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
+index 6241ace..1b7a4fe 100644
+--- a/include/linux/usb/gadget.h
++++ b/include/linux/usb/gadget.h
+@@ -500,6 +500,8 @@ struct usb_gadget_ops {
+  *    only supports HNP on a different root port.
+  * @b_hnp_enable: OTG device feature flag, indicating that the A-Host
+  *    enabled HNP support.
++ * @quirk_ep_out_aligned_size: epout requires buffer size to be aligned to
++ *    MaxPacketSize.
+  *
+  * Gadgets have a mostly-portable "gadget driver" implementing device
+  * functions, handling all usb configurations and interfaces.  Gadget
+@@ -539,6 +541,7 @@ struct usb_gadget {
+       unsigned                        a_hnp_support:1;
+       unsigned                        a_alt_hnp_support:1;
+       atomic_t                        connect_count;
++      unsigned                        quirk_ep_out_aligned_size:1;
+ };
+ static inline void set_gadget_data(struct usb_gadget *gadget, void *data)
+@@ -556,6 +559,23 @@ static inline struct usb_gadget *dev_to_usb_gadget(struct device *dev)
+ /**
++ * usb_ep_align_maybe - returns @len aligned to ep's maxpacketsize if gadget
++ *    requires quirk_ep_out_aligned_size, otherwise reguens len.
++ * @g: controller to check for quirk
++ * @ep: the endpoint whose maxpacketsize is used to align @len
++ * @len: buffer size's length to align to @ep's maxpacketsize
++ *
++ * This helper is used in case it's required for any reason to check and maybe
++ * align buffer's size to an ep's maxpacketsize.
++ */
++static inline size_t
++usb_ep_align_maybe(struct usb_gadget *g, struct usb_ep *ep, size_t len)
++{
++      return !g->quirk_ep_out_aligned_size ? len :
++                      round_up(len, (size_t)ep->desc->wMaxPacketSize);
++}
++
++/**
+  * gadget_is_dualspeed - return true iff the hardware handles high speed
+  * @g: controller that might support both high and full speeds
+  */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1158-usb-gadget-f_fs-remove-loop-from-I-O-function.patch b/patches.tizen/1158-usb-gadget-f_fs-remove-loop-from-I-O-function.patch
new file mode 100644 (file)
index 0000000..412711d
--- /dev/null
@@ -0,0 +1,138 @@
+From 33e41cb2265fda0c30468b6c848ce224dbad5869 Mon Sep 17 00:00:00 2001
+From: Michal Nazarewicz <mina86@mina86.com>
+Date: Mon, 9 Dec 2013 15:55:36 -0800
+Subject: [PATCH 1158/1302] usb: gadget: f_fs: remove loop from I/O function
+
+When endpoint changes (due to it being disabled or alt setting changed),
+mimic the action as if the change happened after the request has been
+queued, instead of retrying with the new endpoint.
+
+Signed-off-by: Michal Nazarewicz <mina86@mina86.com>
+Cc: David Cohen <david.a.cohen@linux.intel.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_fs.c | 94 ++++++++++++++++++++---------------------------
+ 1 file changed, 40 insertions(+), 54 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
+index 44cf775..53a6f01 100644
+--- a/drivers/usb/gadget/f_fs.c
++++ b/drivers/usb/gadget/f_fs.c
+@@ -758,73 +758,59 @@ static ssize_t ffs_epfile_io(struct file *file,
+       ssize_t ret;
+       int halt;
+-      goto first_try;
+-      do {
+-              spin_unlock_irq(&epfile->ffs->eps_lock);
+-              mutex_unlock(&epfile->mutex);
++      /* Are we still active? */
++      if (WARN_ON(epfile->ffs->state != FFS_ACTIVE)) {
++              ret = -ENODEV;
++              goto error;
++      }
+-first_try:
+-              /* Are we still active? */
+-              if (WARN_ON(epfile->ffs->state != FFS_ACTIVE)) {
+-                      ret = -ENODEV;
++      /* Wait for endpoint to be enabled */
++      ep = epfile->ep;
++      if (!ep) {
++              if (file->f_flags & O_NONBLOCK) {
++                      ret = -EAGAIN;
+                       goto error;
+               }
+-              /* Wait for endpoint to be enabled */
+-              ep = epfile->ep;
+-              if (!ep) {
+-                      if (file->f_flags & O_NONBLOCK) {
+-                              ret = -EAGAIN;
+-                              goto error;
+-                      }
+-
+-                      if (wait_event_interruptible(epfile->wait,
+-                                                   (ep = epfile->ep))) {
+-                              ret = -EINTR;
+-                              goto error;
+-                      }
+-              }
+-
+-              /* Do we halt? */
+-              halt = !read == !epfile->in;
+-              if (halt && epfile->isoc) {
+-                      ret = -EINVAL;
++              ret = wait_event_interruptible(epfile->wait, (ep = epfile->ep));
++              if (ret) {
++                      ret = -EINTR;
+                       goto error;
+               }
++      }
+-              /* Allocate & copy */
+-              if (!halt && !data) {
+-                      data = kzalloc(len, GFP_KERNEL);
+-                      if (unlikely(!data))
+-                              return -ENOMEM;
++      /* Do we halt? */
++      halt = !read == !epfile->in;
++      if (halt && epfile->isoc) {
++              ret = -EINVAL;
++              goto error;
++      }
+-                      if (!read &&
+-                          unlikely(__copy_from_user(data, buf, len))) {
+-                              ret = -EFAULT;
+-                              goto error;
+-                      }
+-              }
++      /* Allocate & copy */
++      if (!halt) {
++              data = kmalloc(len, GFP_KERNEL);
++              if (unlikely(!data))
++                      return -ENOMEM;
+-              /* We will be using request */
+-              ret = ffs_mutex_lock(&epfile->mutex,
+-                                   file->f_flags & O_NONBLOCK);
+-              if (unlikely(ret))
++              if (!read && unlikely(copy_from_user(data, buf, len))) {
++                      ret = -EFAULT;
+                       goto error;
++              }
++      }
+-              /*
+-               * We're called from user space, we can use _irq rather then
+-               * _irqsave
+-               */
+-              spin_lock_irq(&epfile->ffs->eps_lock);
++      /* We will be using request */
++      ret = ffs_mutex_lock(&epfile->mutex, file->f_flags & O_NONBLOCK);
++      if (unlikely(ret))
++              goto error;
+-              /*
+-               * While we were acquiring mutex endpoint got disabled
+-               * or changed?
+-               */
+-      } while (unlikely(epfile->ep != ep));
++      spin_lock_irq(&epfile->ffs->eps_lock);
+-      /* Halt */
+-      if (unlikely(halt)) {
++      if (epfile->ep != ep) {
++              /* In the meantime, endpoint got disabled or changed. */
++              ret = -ESHUTDOWN;
++              spin_unlock_irq(&epfile->ffs->eps_lock);
++      } else if (halt) {
++              /* Halt */
+               if (likely(epfile->ep == ep) && !WARN_ON(!ep->ep))
+                       usb_ep_set_halt(ep->ep);
+               spin_unlock_irq(&epfile->ffs->eps_lock);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1159-usb-f_fs-check-quirk-to-pad-epout-buf-size-when-not-.patch b/patches.tizen/1159-usb-f_fs-check-quirk-to-pad-epout-buf-size-when-not-.patch
new file mode 100644 (file)
index 0000000..4da3d95
--- /dev/null
@@ -0,0 +1,80 @@
+From 9d9c8a83b7e8f345ba240e2cb064f9f19ff26b03 Mon Sep 17 00:00:00 2001
+From: Michal Nazarewicz <mina86@mina86.com>
+Date: Mon, 9 Dec 2013 15:55:37 -0800
+Subject: [PATCH 1159/1302] usb: f_fs: check quirk to pad epout buf size when
+ not aligned to maxpacketsize
+
+Check gadget.quirk_ep_out_aligned_size to decide if buffer size requires
+to be aligned to maxpacketsize of an out endpoint.  ffs_epfile_io() needs
+to pad epout buffer to match above condition if quirk is found.
+
+Signed-off-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: David Cohen <david.a.cohen@linux.intel.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_fs.c | 23 +++++++++++++++++++----
+ 1 file changed, 19 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
+index 53a6f01..6453304 100644
+--- a/drivers/usb/gadget/f_fs.c
++++ b/drivers/usb/gadget/f_fs.c
+@@ -753,9 +753,10 @@ static ssize_t ffs_epfile_io(struct file *file,
+                            char __user *buf, size_t len, int read)
+ {
+       struct ffs_epfile *epfile = file->private_data;
++      struct usb_gadget *gadget = epfile->ffs->gadget;
+       struct ffs_ep *ep;
+       char *data = NULL;
+-      ssize_t ret;
++      ssize_t ret, data_len;
+       int halt;
+       /* Are we still active? */
+@@ -788,7 +789,13 @@ static ssize_t ffs_epfile_io(struct file *file,
+       /* Allocate & copy */
+       if (!halt) {
+-              data = kmalloc(len, GFP_KERNEL);
++              /*
++               * Controller may require buffer size to be aligned to
++               * maxpacketsize of an out endpoint.
++               */
++              data_len = read ? usb_ep_align_maybe(gadget, ep->ep, len) : len;
++
++              data = kmalloc(data_len, GFP_KERNEL);
+               if (unlikely(!data))
+                       return -ENOMEM;
+@@ -823,7 +830,7 @@ static ssize_t ffs_epfile_io(struct file *file,
+               req->context  = &done;
+               req->complete = ffs_epfile_io_complete;
+               req->buf      = data;
+-              req->length   = len;
++              req->length   = data_len;
+               ret = usb_ep_queue(ep->ep, req, GFP_ATOMIC);
+@@ -835,9 +842,17 @@ static ssize_t ffs_epfile_io(struct file *file,
+                       ret = -EINTR;
+                       usb_ep_dequeue(ep->ep, req);
+               } else {
++                      /*
++                       * XXX We may end up silently droping data here.
++                       * Since data_len (i.e. req->length) may be bigger
++                       * than len (after being rounded up to maxpacketsize),
++                       * we may end up with more data then user space has
++                       * space for.
++                       */
+                       ret = ep->status;
+                       if (read && ret > 0 &&
+-                          unlikely(copy_to_user(buf, data, ret)))
++                          unlikely(copy_to_user(buf, data,
++                                                min_t(size_t, ret, len))))
+                               ret = -EFAULT;
+               }
+       }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1160-usb-gadget-configfs-allow-setting-function-instance-.patch b/patches.tizen/1160-usb-gadget-configfs-allow-setting-function-instance-.patch
new file mode 100644 (file)
index 0000000..545d91b
--- /dev/null
@@ -0,0 +1,73 @@
+From c5249b3167b246b85fd62b78d9e2763d5c7c8f40 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 3 Dec 2013 15:15:21 +0100
+Subject: [PATCH 1160/1302] usb: gadget: configfs: allow setting function
+ instance's name
+
+USB function's configfs config group is created in a generic way in
+usb/gadget/configfs.c:function_make(), which in turn delegates actual
+allocation and setup of the USB function instance to a particular
+implementation, e.g. in f_acm.c. The said implementation does its job
+in a parameter-less function e.g. acm_alloc_instance(), which results
+in creating an unnamed config group, whose name is set later in
+function_make(). function_make() creates the name by parsing a string
+of the form:
+
+<function name>.<instance name>
+
+which comes from userspace as a parameter to mkdir invocation.
+
+Up to now only <function name> has been used, while <instance name>
+has been ignored. This patch adds a set_inst_name() operation to
+struct usb_function_instance which allows passing the <instance name>
+from function_make() so that it is not ignored. It is entirely up to the
+implementor of set_inst_name() what to do with the <instance name>.
+
+In a typical case, the struct usb_function_instance is embedded in a
+larger struct which is retrieved in set_inst_name() with container_of(),
+and the larger struct contains a field to store the <instance name>.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/configfs.c | 7 +++++++
+ include/linux/usb/composite.h | 2 ++
+ 2 files changed, 9 insertions(+)
+
+diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
+index 2588511..d6c8ab4 100644
+--- a/drivers/usb/gadget/configfs.c
++++ b/drivers/usb/gadget/configfs.c
+@@ -564,6 +564,13 @@ static struct config_group *function_make(
+               usb_put_function_instance(fi);
+               return ERR_PTR(ret);
+       }
++      if (fi->set_inst_name) {
++              ret = fi->set_inst_name(fi, instance_name);
++              if (ret) {
++                      usb_put_function_instance(fi);
++                      return ERR_PTR(ret);
++              }
++      }
+       gi = container_of(group, struct gadget_info, functions_group);
+diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
+index 5e61589..dba63f5 100644
+--- a/include/linux/usb/composite.h
++++ b/include/linux/usb/composite.h
+@@ -468,6 +468,8 @@ struct usb_function_instance {
+       struct config_group group;
+       struct list_head cfs_list;
+       struct usb_function_driver *fd;
++      int (*set_inst_name)(struct usb_function_instance *inst,
++                            const char *name);
+       void (*free_func_inst)(struct usb_function_instance *inst);
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1161-usb-gadget-g_ffs-remove-a-reduntant-gfs_ether_setup-.patch b/patches.tizen/1161-usb-gadget-g_ffs-remove-a-reduntant-gfs_ether_setup-.patch
new file mode 100644 (file)
index 0000000..478677e
--- /dev/null
@@ -0,0 +1,79 @@
+From 61b1784e9910768505f64c114015c5373fc29f95 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 3 Dec 2013 15:15:22 +0100
+Subject: [PATCH 1161/1302] usb: gadget: g_ffs: remove a reduntant
+ gfs_ether_setup variable
+
+Since d6a0143985489e470a118605352f4b18df0ce142
+usb: gadget: move the global the_dev variable to their users
+"the_dev" variable can be used as a "setup done" flag; non-NULL
+meaning "setup done", NULL meaning "setup not done". Moreover,
+gether_cleanup() can be safely called with a NULL argument.
+
+Corrected a comment to be consistent with the code.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/g_ffs.c | 13 +++++--------
+ 1 file changed, 5 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
+index 2344efe..e954082 100644
+--- a/drivers/usb/gadget/g_ffs.c
++++ b/drivers/usb/gadget/g_ffs.c
+@@ -182,7 +182,6 @@ static __refdata struct usb_composite_driver gfs_driver = {
+ static DEFINE_MUTEX(gfs_lock);
+ static unsigned int missing_funcs;
+-static bool gfs_ether_setup;
+ static bool gfs_registered;
+ static bool gfs_single_func;
+ static struct gfs_ffs_obj *ffs_tab;
+@@ -364,7 +363,6 @@ static int gfs_bind(struct usb_composite_dev *cdev)
+               ret = PTR_ERR(the_dev);
+               goto error_quick;
+       }
+-      gfs_ether_setup = true;
+       ret = usb_string_ids_tab(cdev, gfs_strings);
+       if (unlikely(ret < 0))
+@@ -401,8 +399,8 @@ error_unbind:
+               functionfs_unbind(ffs_tab[i].ffs_data);
+ error:
+       gether_cleanup(the_dev);
++      the_dev = NULL;
+ error_quick:
+-      gfs_ether_setup = false;
+       return ret;
+ }
+@@ -415,18 +413,17 @@ static int gfs_unbind(struct usb_composite_dev *cdev)
+       ENTER();
++      gether_cleanup(the_dev);
++      the_dev = NULL;
++
+       /*
+        * We may have been called in an error recovery from
+        * composite_bind() after gfs_unbind() failure so we need to
+-       * check if gfs_ffs_data is not NULL since gfs_bind() handles
++       * check if instance's ffs_data is not NULL since gfs_bind() handles
+        * all error recovery itself.  I'd rather we werent called
+        * from composite on orror recovery, but what you're gonna
+        * do...?
+        */
+-      if (gfs_ether_setup)
+-              gether_cleanup(the_dev);
+-      gfs_ether_setup = false;
+-
+       for (i = func_num; i--; )
+               if (ffs_tab[i].ffs_data)
+                       functionfs_unbind(ffs_tab[i].ffs_data);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1162-usb-gadget-g_ffs-convert-to-new-interface-of-f_ecm.patch b/patches.tizen/1162-usb-gadget-g_ffs-convert-to-new-interface-of-f_ecm.patch
new file mode 100644 (file)
index 0000000..17b54e8
--- /dev/null
@@ -0,0 +1,192 @@
+From 6c5cfcc81bf4cdd696c3841aeab808e67f2ef41d Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 3 Dec 2013 15:15:23 +0100
+Subject: [PATCH 1162/1302] usb: gadget: g_ffs: convert to new interface of
+ f_ecm
+
+There is a new funtion interface and g_ffs is the last gadget to use the old.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig |  1 +
+ drivers/usb/gadget/g_ffs.c | 93 +++++++++++++++++++++++++++++++++++++++-------
+ 2 files changed, 80 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 17890bc..27dcada 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -893,6 +893,7 @@ config USB_FUNCTIONFS_ETH
+       bool "Include configuration with CDC ECM (Ethernet)"
+       depends on USB_FUNCTIONFS && NET
+       select USB_U_ETHER
++      select USB_F_ECM
+       help
+         Include a configuration with CDC ECM function (Ethernet) and the
+         Function Filesystem.
+diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
+index e954082..cda4c5d 100644
+--- a/drivers/usb/gadget/g_ffs.c
++++ b/drivers/usb/gadget/g_ffs.c
+@@ -28,8 +28,7 @@
+ #    define USB_ETH_RNDIS y
+ #  endif
+-#define USBF_ECM_INCLUDED
+-#  include "f_ecm.c"
++#  include "u_ecm.h"
+ #define USB_FSUBSET_INCLUDED
+ #  include "f_subset.c"
+ #  ifdef USB_ETH_RNDIS
+@@ -39,11 +38,15 @@
+ #  endif
+ #  include "u_ether.h"
++USB_ETHERNET_MODULE_PARAMETERS();
++
+ static u8 gfs_host_mac[ETH_ALEN];
+ static struct eth_dev *the_dev;
+ #  ifdef CONFIG_USB_FUNCTIONFS_ETH
+ static int eth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+               struct eth_dev *dev);
++static struct usb_function_instance *fi_ecm;
++static struct usb_function *f_ecm;
+ #  endif
+ #else
+ #  define the_dev     NULL
+@@ -76,10 +79,6 @@ struct gfs_ffs_obj {
+ USB_GADGET_COMPOSITE_OPTIONS();
+-#if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS
+-USB_ETHERNET_MODULE_PARAMETERS();
+-#endif
+-
+ static struct usb_device_descriptor gfs_dev_desc = {
+       .bLength                = sizeof gfs_dev_desc,
+       .bDescriptorType        = USB_DT_DEVICE,
+@@ -355,14 +354,50 @@ static int gfs_bind(struct usb_composite_dev *cdev)
+       if (missing_funcs)
+               return -ENODEV;
+-#if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS
++#if defined CONFIG_USB_FUNCTIONFS_ETH
++      if (can_support_ecm(cdev->gadget)) {
++              struct f_ecm_opts *ecm_opts;
++
++              fi_ecm = usb_get_function_instance("ecm");
++              if (IS_ERR(fi_ecm))
++                      return PTR_ERR(fi_ecm);
++              ecm_opts = container_of(fi_ecm, struct f_ecm_opts, func_inst);
++
++              gether_set_qmult(ecm_opts->net, qmult);
++
++              if (!gether_set_host_addr(ecm_opts->net, host_addr))
++                      pr_info("using host ethernet address: %s", host_addr);
++              if (!gether_set_dev_addr(ecm_opts->net, dev_addr))
++                      pr_info("using self ethernet address: %s", dev_addr);
++
++              the_dev = netdev_priv(ecm_opts->net);
++      } else {
++              the_dev = gether_setup(cdev->gadget, dev_addr, host_addr,
++                                     gfs_host_mac, qmult);
++      }
++
++#elif defined CONFIG_USB_FUNCTIONFS_RNDIS
++
+       the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, gfs_host_mac,
+                              qmult);
+ #endif
+-      if (IS_ERR(the_dev)) {
+-              ret = PTR_ERR(the_dev);
+-              goto error_quick;
++      if (IS_ERR(the_dev))
++              return PTR_ERR(the_dev);
++
++#if defined CONFIG_USB_FUNCTIONFS_RNDIS && defined CONFIG_USB_FUNCTIONFS_ETH
++      if (can_support_ecm(cdev->gadget)) {
++              struct f_ecm_opts *ecm_opts;
++
++              ecm_opts = container_of(fi_ecm, struct f_ecm_opts, func_inst);
++
++              gether_set_gadget(ecm_opts->net, cdev->gadget);
++              ret = gether_register_netdev(ecm_opts->net);
++              if (ret)
++                      goto error;
++              ecm_opts->bound = true;
++              gether_get_host_addr_u8(ecm_opts->net, gfs_host_mac);
+       }
++#endif
+       ret = usb_string_ids_tab(cdev, gfs_strings);
+       if (unlikely(ret < 0))
+@@ -398,9 +433,16 @@ error_unbind:
+       for (i = 0; i < func_num; i++)
+               functionfs_unbind(ffs_tab[i].ffs_data);
+ error:
++#if defined CONFIG_USB_FUNCTIONFS_ETH
++      if (can_support_ecm(cdev->gadget))
++              usb_put_function_instance(fi_ecm);
++      else
++              gether_cleanup(the_dev);
++      the_dev = NULL;
++#elif defined CONFIG_USB_FUNCTIONFS_RNDIS
+       gether_cleanup(the_dev);
+       the_dev = NULL;
+-error_quick:
++#endif
+       return ret;
+ }
+@@ -413,8 +455,19 @@ static int gfs_unbind(struct usb_composite_dev *cdev)
+       ENTER();
++
++#if defined CONFIG_USB_FUNCTIONFS_ETH
++      if (can_support_ecm(cdev->gadget)) {
++              usb_put_function(f_ecm);
++              usb_put_function_instance(fi_ecm);
++      } else {
++              gether_cleanup(the_dev);
++      }
++      the_dev = NULL;
++#elif defined CONFIG_USB_FUNCTIONFS_RNDIS
+       gether_cleanup(the_dev);
+       the_dev = NULL;
++#endif
+       /*
+        * We may have been called in an error recovery from
+@@ -483,9 +536,21 @@ static int gfs_do_config(struct usb_configuration *c)
+ static int eth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+               struct eth_dev *dev)
+ {
+-      return can_support_ecm(c->cdev->gadget)
+-              ? ecm_bind_config(c, ethaddr, dev)
+-              : geth_bind_config(c, ethaddr, dev);
++      int status = 0;
++
++      if (can_support_ecm(c->cdev->gadget)) {
++              f_ecm = usb_get_function(fi_ecm);
++              if (IS_ERR(f_ecm))
++                      return PTR_ERR(f_ecm);
++
++              status = usb_add_function(c, f_ecm);
++              if (status < 0)
++                      usb_put_function(f_ecm);
++
++      } else {
++              status = geth_bind_config(c, ethaddr, dev);
++      }
++      return status;
+ }
+ #endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1163-usb-gadget-f_ecm-remove-compatibility-layer.patch b/patches.tizen/1163-usb-gadget-f_ecm-remove-compatibility-layer.patch
new file mode 100644 (file)
index 0000000..cb5e84c
--- /dev/null
@@ -0,0 +1,136 @@
+From f676b0fdce859c1502f3e3c053c4781fa8a00026 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 3 Dec 2013 15:15:24 +0100
+Subject: [PATCH 1163/1302] usb: gadget: f_ecm: remove compatibility layer
+
+There are no old function interface users left, so the old interface
+can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmim Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_ecm.c   | 73 +-------------------------------------------
+ drivers/usb/gadget/u_ether.h |  2 --
+ 2 files changed, 1 insertion(+), 74 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c
+index 8d9e6f7..798760f 100644
+--- a/drivers/usb/gadget/f_ecm.c
++++ b/drivers/usb/gadget/f_ecm.c
+@@ -691,7 +691,6 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
+       int                     status;
+       struct usb_ep           *ep;
+-#ifndef USBF_ECM_INCLUDED
+       struct f_ecm_opts       *ecm_opts;
+       if (!can_support_ecm(cdev->gadget))
+@@ -715,7 +714,7 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
+                       return status;
+               ecm_opts->bound = true;
+       }
+-#endif
++
+       us = usb_gstrings_attach(cdev, ecm_strings,
+                                ARRAY_SIZE(ecm_string_defs));
+       if (IS_ERR(us))
+@@ -834,74 +833,6 @@ fail:
+       return status;
+ }
+-#ifdef USBF_ECM_INCLUDED
+-
+-static void
+-ecm_old_unbind(struct usb_configuration *c, struct usb_function *f)
+-{
+-      struct f_ecm            *ecm = func_to_ecm(f);
+-
+-      DBG(c->cdev, "ecm unbind\n");
+-
+-      usb_free_all_descriptors(f);
+-
+-      kfree(ecm->notify_req->buf);
+-      usb_ep_free_request(ecm->notify, ecm->notify_req);
+-      kfree(ecm);
+-}
+-
+-/**
+- * ecm_bind_config - add CDC Ethernet network link to a configuration
+- * @c: the configuration to support the network link
+- * @ethaddr: a buffer in which the ethernet address of the host side
+- *    side of the link was recorded
+- * @dev: eth_dev structure
+- * Context: single threaded during gadget setup
+- *
+- * Returns zero on success, else negative errno.
+- *
+- * Caller must have called @gether_setup().  Caller is also responsible
+- * for calling @gether_cleanup() before module unload.
+- */
+-int
+-ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+-              struct eth_dev *dev)
+-{
+-      struct f_ecm    *ecm;
+-      int             status;
+-
+-      if (!can_support_ecm(c->cdev->gadget) || !ethaddr)
+-              return -EINVAL;
+-
+-      /* allocate and initialize one new instance */
+-      ecm = kzalloc(sizeof *ecm, GFP_KERNEL);
+-      if (!ecm)
+-              return -ENOMEM;
+-
+-      /* export host's Ethernet address in CDC format */
+-      snprintf(ecm->ethaddr, sizeof ecm->ethaddr, "%pm", ethaddr);
+-      ecm_string_defs[1].s = ecm->ethaddr;
+-
+-      ecm->port.ioport = dev;
+-      ecm->port.cdc_filter = DEFAULT_FILTER;
+-
+-      ecm->port.func.name = "cdc_ethernet";
+-      /* descriptors are per-instance copies */
+-      ecm->port.func.bind = ecm_bind;
+-      ecm->port.func.unbind = ecm_old_unbind;
+-      ecm->port.func.set_alt = ecm_set_alt;
+-      ecm->port.func.get_alt = ecm_get_alt;
+-      ecm->port.func.setup = ecm_setup;
+-      ecm->port.func.disable = ecm_disable;
+-
+-      status = usb_add_function(c, &ecm->port.func);
+-      if (status)
+-              kfree(ecm);
+-      return status;
+-}
+-
+-#else
+-
+ static inline struct f_ecm_opts *to_f_ecm_opts(struct config_item *item)
+ {
+       return container_of(to_config_group(item), struct f_ecm_opts,
+@@ -1040,5 +971,3 @@ static struct usb_function *ecm_alloc(struct usb_function_instance *fi)
+ DECLARE_USB_FUNCTION_INIT(ecm, ecm_alloc_inst, ecm_alloc);
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("David Brownell");
+-
+-#endif
+diff --git a/drivers/usb/gadget/u_ether.h b/drivers/usb/gadget/u_ether.h
+index a32b41e..c060595 100644
+--- a/drivers/usb/gadget/u_ether.h
++++ b/drivers/usb/gadget/u_ether.h
+@@ -270,8 +270,6 @@ static inline bool can_support_ecm(struct usb_gadget *gadget)
+ /* each configuration may bind one instance of an ethernet link */
+ int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+               struct eth_dev *dev);
+-int ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+-              struct eth_dev *dev);
+ #ifdef USB_ETH_RNDIS
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1164-usb-gadget-g_ffs-convert-to-new-interface-of-f_subse.patch b/patches.tizen/1164-usb-gadget-g_ffs-convert-to-new-interface-of-f_subse.patch
new file mode 100644 (file)
index 0000000..747a52a
--- /dev/null
@@ -0,0 +1,178 @@
+From c5a1782daec70f1543f10fe920d59633d655d4bc Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 3 Dec 2013 15:15:25 +0100
+Subject: [PATCH 1164/1302] usb: gadget: g_ffs: convert to new interface of
+ f_subset
+
+There is a new function interface of f_subset and g_ffs is the last to use
+the old one.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig |  1 +
+ drivers/usb/gadget/g_ffs.c | 69 +++++++++++++++++++++++++++++++---------------
+ 2 files changed, 48 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 27dcada..a30bbee 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -894,6 +894,7 @@ config USB_FUNCTIONFS_ETH
+       depends on USB_FUNCTIONFS && NET
+       select USB_U_ETHER
+       select USB_F_ECM
++      select USB_F_SUBSET
+       help
+         Include a configuration with CDC ECM function (Ethernet) and the
+         Function Filesystem.
+diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
+index cda4c5d..99ae8ec 100644
+--- a/drivers/usb/gadget/g_ffs.c
++++ b/drivers/usb/gadget/g_ffs.c
+@@ -21,6 +21,8 @@
+  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+  */
+ #if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS
++#include <linux/netdevice.h>
++
+ #  if defined USB_ETH_RNDIS
+ #    undef USB_ETH_RNDIS
+ #  endif
+@@ -29,8 +31,7 @@
+ #  endif
+ #  include "u_ecm.h"
+-#define USB_FSUBSET_INCLUDED
+-#  include "f_subset.c"
++#  include "u_gether.h"
+ #  ifdef USB_ETH_RNDIS
+ #    define USB_FRNDIS_INCLUDED
+ #    include "f_rndis.c"
+@@ -47,6 +48,8 @@ static int eth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+               struct eth_dev *dev);
+ static struct usb_function_instance *fi_ecm;
+ static struct usb_function *f_ecm;
++static struct usb_function_instance *fi_geth;
++static struct usb_function *f_geth;
+ #  endif
+ #else
+ #  define the_dev     NULL
+@@ -348,6 +351,9 @@ static void functionfs_release_dev_callback(struct ffs_data *ffs_data)
+  */
+ static int gfs_bind(struct usb_composite_dev *cdev)
+ {
++#if defined CONFIG_USB_FUNCTIONFS_ETH
++      struct net_device *net;
++#endif
+       int ret, i;
+       ENTER();
+@@ -362,19 +368,25 @@ static int gfs_bind(struct usb_composite_dev *cdev)
+               if (IS_ERR(fi_ecm))
+                       return PTR_ERR(fi_ecm);
+               ecm_opts = container_of(fi_ecm, struct f_ecm_opts, func_inst);
+-
+-              gether_set_qmult(ecm_opts->net, qmult);
+-
+-              if (!gether_set_host_addr(ecm_opts->net, host_addr))
+-                      pr_info("using host ethernet address: %s", host_addr);
+-              if (!gether_set_dev_addr(ecm_opts->net, dev_addr))
+-                      pr_info("using self ethernet address: %s", dev_addr);
+-
+-              the_dev = netdev_priv(ecm_opts->net);
++              net = ecm_opts->net;
+       } else {
+-              the_dev = gether_setup(cdev->gadget, dev_addr, host_addr,
+-                                     gfs_host_mac, qmult);
++              struct f_gether_opts *geth_opts;
++
++              fi_geth = usb_get_function_instance("geth");
++              if (IS_ERR(fi_geth))
++                      return PTR_ERR(fi_geth);
++              geth_opts = container_of(fi_geth, struct f_gether_opts,
++                                       func_inst);
++              net = geth_opts->net;
+       }
++      gether_set_qmult(net, qmult);
++
++      if (!gether_set_host_addr(net, host_addr))
++              pr_info("using host ethernet address: %s", host_addr);
++      if (!gether_set_dev_addr(net, dev_addr))
++              pr_info("using self ethernet address: %s", dev_addr);
++
++      the_dev = netdev_priv(net);
+ #elif defined CONFIG_USB_FUNCTIONFS_RNDIS
+@@ -385,18 +397,24 @@ static int gfs_bind(struct usb_composite_dev *cdev)
+               return PTR_ERR(the_dev);
+ #if defined CONFIG_USB_FUNCTIONFS_RNDIS && defined CONFIG_USB_FUNCTIONFS_ETH
++      gether_set_gadget(net, cdev->gadget);
++      ret = gether_register_netdev(net);
++      if (ret)
++              goto error;
++
+       if (can_support_ecm(cdev->gadget)) {
+               struct f_ecm_opts *ecm_opts;
+               ecm_opts = container_of(fi_ecm, struct f_ecm_opts, func_inst);
+-
+-              gether_set_gadget(ecm_opts->net, cdev->gadget);
+-              ret = gether_register_netdev(ecm_opts->net);
+-              if (ret)
+-                      goto error;
+               ecm_opts->bound = true;
+-              gether_get_host_addr_u8(ecm_opts->net, gfs_host_mac);
++      } else {
++              struct f_gether_opts *geth_opts;
++
++              geth_opts = container_of(fi_geth, struct f_gether_opts,
++                                       func_inst);
++              geth_opts->bound = true;
+       }
++      gether_get_host_addr_u8(net, gfs_host_mac);
+ #endif
+       ret = usb_string_ids_tab(cdev, gfs_strings);
+@@ -437,7 +455,7 @@ error:
+       if (can_support_ecm(cdev->gadget))
+               usb_put_function_instance(fi_ecm);
+       else
+-              gether_cleanup(the_dev);
++              usb_put_function_instance(fi_geth);
+       the_dev = NULL;
+ #elif defined CONFIG_USB_FUNCTIONFS_RNDIS
+       gether_cleanup(the_dev);
+@@ -461,7 +479,8 @@ static int gfs_unbind(struct usb_composite_dev *cdev)
+               usb_put_function(f_ecm);
+               usb_put_function_instance(fi_ecm);
+       } else {
+-              gether_cleanup(the_dev);
++              usb_put_function(f_geth);
++              usb_put_function_instance(fi_geth);
+       }
+       the_dev = NULL;
+ #elif defined CONFIG_USB_FUNCTIONFS_RNDIS
+@@ -548,7 +567,13 @@ static int eth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+                       usb_put_function(f_ecm);
+       } else {
+-              status = geth_bind_config(c, ethaddr, dev);
++              f_geth = usb_get_function(fi_geth);
++              if (IS_ERR(f_geth))
++                      return PTR_ERR(f_geth);
++
++              status = usb_add_function(c, f_geth);
++              if (status < 0)
++                      usb_put_function(f_geth);
+       }
+       return status;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1165-usb-gadget-f_subset-remove-compatibility-layer.patch b/patches.tizen/1165-usb-gadget-f_subset-remove-compatibility-layer.patch
new file mode 100644 (file)
index 0000000..6e59dc9
--- /dev/null
@@ -0,0 +1,124 @@
+From fc7df157ea6fd63ca34541f3ec6e6525d77e5bc6 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 3 Dec 2013 15:15:26 +0100
+Subject: [PATCH 1165/1302] usb: gadget: f_subset: remove compatibility layer
+
+There are no old function interface users left, so the old interface
+can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_subset.c | 60 +------------------------------------------
+ drivers/usb/gadget/u_ether.h  |  3 ---
+ 2 files changed, 1 insertion(+), 62 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c
+index 7c8674f..f1a5919 100644
+--- a/drivers/usb/gadget/f_subset.c
++++ b/drivers/usb/gadget/f_subset.c
+@@ -301,7 +301,6 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
+       int                     status;
+       struct usb_ep           *ep;
+-#ifndef USB_FSUBSET_INCLUDED
+       struct f_gether_opts    *gether_opts;
+       gether_opts = container_of(f->fi, struct f_gether_opts, func_inst);
+@@ -322,7 +321,7 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
+                       return status;
+               gether_opts->bound = true;
+       }
+-#endif
++
+       us = usb_gstrings_attach(cdev, geth_strings,
+                                ARRAY_SIZE(geth_string_defs));
+       if (IS_ERR(us))
+@@ -393,61 +392,6 @@ fail:
+       return status;
+ }
+-#ifdef USB_FSUBSET_INCLUDED
+-
+-static void
+-geth_old_unbind(struct usb_configuration *c, struct usb_function *f)
+-{
+-      geth_string_defs[0].id = 0;
+-      usb_free_all_descriptors(f);
+-      kfree(func_to_geth(f));
+-}
+-
+-/**
+- * geth_bind_config - add CDC Subset network link to a configuration
+- * @c: the configuration to support the network link
+- * @ethaddr: a buffer in which the ethernet address of the host side
+- *    side of the link was recorded
+- * @dev: eth_dev structure
+- * Context: single threaded during gadget setup
+- *
+- * Returns zero on success, else negative errno.
+- *
+- * Caller must have called @gether_setup().  Caller is also responsible
+- * for calling @gether_cleanup() before module unload.
+- */
+-int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+-              struct eth_dev *dev)
+-{
+-      struct f_gether *geth;
+-      int             status;
+-
+-      /* allocate and initialize one new instance */
+-      geth = kzalloc(sizeof *geth, GFP_KERNEL);
+-      if (!geth)
+-              return -ENOMEM;
+-
+-      /* export host's Ethernet address in CDC format */
+-      snprintf(geth->ethaddr, sizeof geth->ethaddr, "%pm", ethaddr);
+-      geth_string_defs[1].s = geth->ethaddr;
+-
+-      geth->port.ioport = dev;
+-      geth->port.cdc_filter = DEFAULT_FILTER;
+-
+-      geth->port.func.name = "cdc_subset";
+-      geth->port.func.bind = geth_bind;
+-      geth->port.func.unbind = geth_old_unbind;
+-      geth->port.func.set_alt = geth_set_alt;
+-      geth->port.func.disable = geth_disable;
+-
+-      status = usb_add_function(c, &geth->port.func);
+-      if (status)
+-              kfree(geth);
+-      return status;
+-}
+-
+-#else
+-
+ static inline struct f_gether_opts *to_f_gether_opts(struct config_item *item)
+ {
+       return container_of(to_config_group(item), struct f_gether_opts,
+@@ -573,5 +517,3 @@ static struct usb_function *geth_alloc(struct usb_function_instance *fi)
+ DECLARE_USB_FUNCTION_INIT(geth, geth_alloc_inst, geth_alloc);
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("David Brownell");
+-
+-#endif
+diff --git a/drivers/usb/gadget/u_ether.h b/drivers/usb/gadget/u_ether.h
+index c060595..72b6fac 100644
+--- a/drivers/usb/gadget/u_ether.h
++++ b/drivers/usb/gadget/u_ether.h
+@@ -268,9 +268,6 @@ static inline bool can_support_ecm(struct usb_gadget *gadget)
+ }
+ /* each configuration may bind one instance of an ethernet link */
+-int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+-              struct eth_dev *dev);
+-
+ #ifdef USB_ETH_RNDIS
+ int rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1166-usb-gadget-g_ffs-convert-to-new-interface-of-f_rndis.patch b/patches.tizen/1166-usb-gadget-g_ffs-convert-to-new-interface-of-f_rndis.patch
new file mode 100644 (file)
index 0000000..dbfd0bb
--- /dev/null
@@ -0,0 +1,259 @@
+From 14f62496481428011747c59097151f0d0ff1f75a Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 3 Dec 2013 15:15:27 +0100
+Subject: [PATCH 1166/1302] usb: gadget: g_ffs: convert to new interface of
+ f_rndis
+
+There is a new interface of f_rndis and g_ffs is the last to use the old one.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig |   1 +
+ drivers/usb/gadget/g_ffs.c | 105 ++++++++++++++++++++++++++++-----------------
+ 2 files changed, 66 insertions(+), 40 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index a30bbee..60e00cf 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -904,6 +904,7 @@ config USB_FUNCTIONFS_RNDIS
+       depends on USB_FUNCTIONFS && NET
+       select USB_U_ETHER
+       select USB_U_RNDIS
++      select USB_F_RNDIS
+       help
+         Include a configuration with RNDIS function (Ethernet) and the Filesystem.
+diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
+index 99ae8ec..7099a11 100644
+--- a/drivers/usb/gadget/g_ffs.c
++++ b/drivers/usb/gadget/g_ffs.c
+@@ -33,29 +33,25 @@
+ #  include "u_ecm.h"
+ #  include "u_gether.h"
+ #  ifdef USB_ETH_RNDIS
+-#    define USB_FRNDIS_INCLUDED
+-#    include "f_rndis.c"
++#    include "u_rndis.h"
+ #    include "rndis.h"
+ #  endif
+ #  include "u_ether.h"
+ USB_ETHERNET_MODULE_PARAMETERS();
+-static u8 gfs_host_mac[ETH_ALEN];
+-static struct eth_dev *the_dev;
+ #  ifdef CONFIG_USB_FUNCTIONFS_ETH
+-static int eth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+-              struct eth_dev *dev);
++static int eth_bind_config(struct usb_configuration *c);
+ static struct usb_function_instance *fi_ecm;
+ static struct usb_function *f_ecm;
+ static struct usb_function_instance *fi_geth;
+ static struct usb_function *f_geth;
+ #  endif
+-#else
+-#  define the_dev     NULL
+-#  define gether_cleanup(dev) do { } while (0)
+-#  define gfs_host_mac NULL
+-struct eth_dev;
++#  ifdef CONFIG_USB_FUNCTIONFS_RNDIS
++static int bind_rndis_config(struct usb_configuration *c);
++static struct usb_function_instance *fi_rndis;
++static struct usb_function *f_rndis;
++#  endif
+ #endif
+ #include "f_fs.c"
+@@ -148,12 +144,11 @@ static struct usb_gadget_strings *gfs_dev_strings[] = {
+ struct gfs_configuration {
+       struct usb_configuration c;
+-      int (*eth)(struct usb_configuration *c, u8 *ethaddr,
+-                      struct eth_dev *dev);
++      int (*eth)(struct usb_configuration *c);
+ } gfs_configurations[] = {
+ #ifdef CONFIG_USB_FUNCTIONFS_RNDIS
+       {
+-              .eth            = rndis_bind_config,
++              .eth            = bind_rndis_config,
+       },
+ #endif
+@@ -351,7 +346,7 @@ static void functionfs_release_dev_callback(struct ffs_data *ffs_data)
+  */
+ static int gfs_bind(struct usb_composite_dev *cdev)
+ {
+-#if defined CONFIG_USB_FUNCTIONFS_ETH
++#if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS
+       struct net_device *net;
+ #endif
+       int ret, i;
+@@ -379,28 +374,38 @@ static int gfs_bind(struct usb_composite_dev *cdev)
+                                        func_inst);
+               net = geth_opts->net;
+       }
+-      gether_set_qmult(net, qmult);
++#endif
++
++#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
++      {
++              struct f_rndis_opts *rndis_opts;
++
++              fi_rndis = usb_get_function_instance("rndis");
++              if (IS_ERR(fi_rndis)) {
++                      ret = PTR_ERR(fi_rndis);
++                      goto error;
++              }
++              rndis_opts = container_of(fi_rndis, struct f_rndis_opts,
++                                        func_inst);
++#ifndef CONFIG_USB_FUNCTIONFS_ETH
++              net = rndis_opts->net;
++#endif
++      }
++#endif
++#if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS
++      gether_set_qmult(net, qmult);
+       if (!gether_set_host_addr(net, host_addr))
+               pr_info("using host ethernet address: %s", host_addr);
+       if (!gether_set_dev_addr(net, dev_addr))
+               pr_info("using self ethernet address: %s", dev_addr);
+-
+-      the_dev = netdev_priv(net);
+-
+-#elif defined CONFIG_USB_FUNCTIONFS_RNDIS
+-
+-      the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, gfs_host_mac,
+-                             qmult);
+ #endif
+-      if (IS_ERR(the_dev))
+-              return PTR_ERR(the_dev);
+ #if defined CONFIG_USB_FUNCTIONFS_RNDIS && defined CONFIG_USB_FUNCTIONFS_ETH
+       gether_set_gadget(net, cdev->gadget);
+       ret = gether_register_netdev(net);
+       if (ret)
+-              goto error;
++              goto error_rndis;
+       if (can_support_ecm(cdev->gadget)) {
+               struct f_ecm_opts *ecm_opts;
+@@ -414,12 +419,13 @@ static int gfs_bind(struct usb_composite_dev *cdev)
+                                        func_inst);
+               geth_opts->bound = true;
+       }
+-      gether_get_host_addr_u8(net, gfs_host_mac);
++
++      rndis_borrow_net(fi_rndis, net);
+ #endif
+       ret = usb_string_ids_tab(cdev, gfs_strings);
+       if (unlikely(ret < 0))
+-              goto error;
++              goto error_rndis;
+       gfs_dev_desc.iProduct = gfs_strings[USB_GADGET_PRODUCT_IDX].id;
+       for (i = func_num; i--; ) {
+@@ -427,7 +433,7 @@ static int gfs_bind(struct usb_composite_dev *cdev)
+               if (unlikely(ret < 0)) {
+                       while (++i < func_num)
+                               functionfs_unbind(ffs_tab[i].ffs_data);
+-                      goto error;
++                      goto error_rndis;
+               }
+       }
+@@ -450,16 +456,16 @@ static int gfs_bind(struct usb_composite_dev *cdev)
+ error_unbind:
+       for (i = 0; i < func_num; i++)
+               functionfs_unbind(ffs_tab[i].ffs_data);
++error_rndis:
++#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
++      usb_put_function_instance(fi_rndis);
+ error:
++#endif
+ #if defined CONFIG_USB_FUNCTIONFS_ETH
+       if (can_support_ecm(cdev->gadget))
+               usb_put_function_instance(fi_ecm);
+       else
+               usb_put_function_instance(fi_geth);
+-      the_dev = NULL;
+-#elif defined CONFIG_USB_FUNCTIONFS_RNDIS
+-      gether_cleanup(the_dev);
+-      the_dev = NULL;
+ #endif
+       return ret;
+ }
+@@ -474,6 +480,11 @@ static int gfs_unbind(struct usb_composite_dev *cdev)
+       ENTER();
++#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
++      usb_put_function(f_rndis);
++      usb_put_function_instance(fi_rndis);
++#endif
++
+ #if defined CONFIG_USB_FUNCTIONFS_ETH
+       if (can_support_ecm(cdev->gadget)) {
+               usb_put_function(f_ecm);
+@@ -482,10 +493,6 @@ static int gfs_unbind(struct usb_composite_dev *cdev)
+               usb_put_function(f_geth);
+               usb_put_function_instance(fi_geth);
+       }
+-      the_dev = NULL;
+-#elif defined CONFIG_USB_FUNCTIONFS_RNDIS
+-      gether_cleanup(the_dev);
+-      the_dev = NULL;
+ #endif
+       /*
+@@ -523,7 +530,7 @@ static int gfs_do_config(struct usb_configuration *c)
+       }
+       if (gc->eth) {
+-              ret = gc->eth(c, gfs_host_mac, the_dev);
++              ret = gc->eth(c);
+               if (unlikely(ret < 0))
+                       return ret;
+       }
+@@ -552,8 +559,7 @@ static int gfs_do_config(struct usb_configuration *c)
+ #ifdef CONFIG_USB_FUNCTIONFS_ETH
+-static int eth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+-              struct eth_dev *dev)
++static int eth_bind_config(struct usb_configuration *c)
+ {
+       int status = 0;
+@@ -579,3 +585,22 @@ static int eth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+ }
+ #endif
++
++#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
++
++static int bind_rndis_config(struct usb_configuration *c)
++{
++      int status = 0;
++
++      f_rndis = usb_get_function(fi_rndis);
++      if (IS_ERR(f_rndis))
++              return PTR_ERR(f_rndis);
++
++      status = usb_add_function(c, f_rndis);
++      if (status < 0)
++              usb_put_function(f_rndis);
++
++      return status;
++}
++
++#endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1167-usb-gadget-f_rndis-remove-compatibility-layer.patch b/patches.tizen/1167-usb-gadget-f_rndis-remove-compatibility-layer.patch
new file mode 100644 (file)
index 0000000..82e35c5
--- /dev/null
@@ -0,0 +1,174 @@
+From 9a0ace18f547c8e1b2a493686ab6ef4bfbaf0faf Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 3 Dec 2013 15:15:28 +0100
+Subject: [PATCH 1167/1302] usb: gadget: f_rndis: remove compatibility layer
+
+There are no old function interface users left, so the old interface
+can be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_rndis.c | 72 +-------------------------------------------
+ drivers/usb/gadget/u_ether.h | 36 ----------------------
+ 2 files changed, 1 insertion(+), 107 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
+index 717ed7f..9d7c995 100644
+--- a/drivers/usb/gadget/f_rndis.c
++++ b/drivers/usb/gadget/f_rndis.c
+@@ -675,7 +675,6 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
+       int                     status;
+       struct usb_ep           *ep;
+-#ifndef USB_FRNDIS_INCLUDED
+       struct f_rndis_opts *rndis_opts;
+       if (!can_support_rndis(c))
+@@ -697,7 +696,7 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
+                       return status;
+               rndis_opts->bound = true;
+       }
+-#endif
++
+       us = usb_gstrings_attach(cdev, rndis_strings,
+                                ARRAY_SIZE(rndis_string_defs));
+       if (IS_ERR(us))
+@@ -782,13 +781,6 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
+       rndis->port.open = rndis_open;
+       rndis->port.close = rndis_close;
+-#ifdef USB_FRNDIS_INCLUDED
+-      status = rndis_register(rndis_response_available, rndis);
+-      if (status < 0)
+-              goto fail;
+-      rndis->config = status;
+-#endif
+-
+       rndis_set_param_medium(rndis->config, RNDIS_MEDIUM_802_3, 0);
+       rndis_set_host_mac(rndis->config, rndis->ethaddr);
+@@ -830,66 +822,6 @@ fail:
+       return status;
+ }
+-#ifdef USB_FRNDIS_INCLUDED
+-
+-static void
+-rndis_old_unbind(struct usb_configuration *c, struct usb_function *f)
+-{
+-      struct f_rndis          *rndis = func_to_rndis(f);
+-
+-      rndis_deregister(rndis->config);
+-
+-      usb_free_all_descriptors(f);
+-
+-      kfree(rndis->notify_req->buf);
+-      usb_ep_free_request(rndis->notify, rndis->notify_req);
+-
+-      kfree(rndis);
+-}
+-
+-int
+-rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+-              u32 vendorID, const char *manufacturer, struct eth_dev *dev)
+-{
+-      struct f_rndis  *rndis;
+-      int             status;
+-
+-      /* allocate and initialize one new instance */
+-      status = -ENOMEM;
+-      rndis = kzalloc(sizeof *rndis, GFP_KERNEL);
+-      if (!rndis)
+-              goto fail;
+-
+-      memcpy(rndis->ethaddr, ethaddr, ETH_ALEN);
+-      rndis->vendorID = vendorID;
+-      rndis->manufacturer = manufacturer;
+-
+-      rndis->port.ioport = dev;
+-      /* RNDIS activates when the host changes this filter */
+-      rndis->port.cdc_filter = 0;
+-
+-      /* RNDIS has special (and complex) framing */
+-      rndis->port.header_len = sizeof(struct rndis_packet_msg_type);
+-      rndis->port.wrap = rndis_add_header;
+-      rndis->port.unwrap = rndis_rm_hdr;
+-
+-      rndis->port.func.name = "rndis";
+-      /* descriptors are per-instance copies */
+-      rndis->port.func.bind = rndis_bind;
+-      rndis->port.func.unbind = rndis_old_unbind;
+-      rndis->port.func.set_alt = rndis_set_alt;
+-      rndis->port.func.setup = rndis_setup;
+-      rndis->port.func.disable = rndis_disable;
+-
+-      status = usb_add_function(c, &rndis->port.func);
+-      if (status)
+-              kfree(rndis);
+-fail:
+-      return status;
+-}
+-
+-#else
+-
+ void rndis_borrow_net(struct usb_function_instance *f, struct net_device *net)
+ {
+       struct f_rndis_opts *opts;
+@@ -1050,5 +982,3 @@ static struct usb_function *rndis_alloc(struct usb_function_instance *fi)
+ DECLARE_USB_FUNCTION_INIT(rndis, rndis_alloc_inst, rndis_alloc);
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("David Brownell");
+-
+-#endif
+diff --git a/drivers/usb/gadget/u_ether.h b/drivers/usb/gadget/u_ether.h
+index 72b6fac..0f0290a 100644
+--- a/drivers/usb/gadget/u_ether.h
++++ b/drivers/usb/gadget/u_ether.h
+@@ -267,40 +267,4 @@ static inline bool can_support_ecm(struct usb_gadget *gadget)
+       return true;
+ }
+-/* each configuration may bind one instance of an ethernet link */
+-#ifdef USB_ETH_RNDIS
+-
+-int rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+-              u32 vendorID, const char *manufacturer, struct eth_dev *dev);
+-
+-#else
+-
+-static inline int
+-rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+-              u32 vendorID, const char *manufacturer, struct eth_dev *dev)
+-{
+-      return 0;
+-}
+-
+-#endif
+-
+-/**
+- * rndis_bind_config - add RNDIS network link to a configuration
+- * @c: the configuration to support the network link
+- * @ethaddr: a buffer in which the ethernet address of the host side
+- *    side of the link was recorded
+- * Context: single threaded during gadget setup
+- *
+- * Returns zero on success, else negative errno.
+- *
+- * Caller must have called @gether_setup().  Caller is also responsible
+- * for calling @gether_cleanup() before module unload.
+- */
+-static inline int rndis_bind_config(struct usb_configuration *c,
+-              u8 ethaddr[ETH_ALEN], struct eth_dev *dev)
+-{
+-      return rndis_bind_config_vendor(c, ethaddr, 0, NULL, dev);
+-}
+-
+-
+ #endif /* __U_ETHER_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1168-usb-gadget-rndis-merge-u_rndis.ko-with-usb_f_rndis.k.patch b/patches.tizen/1168-usb-gadget-rndis-merge-u_rndis.ko-with-usb_f_rndis.k.patch
new file mode 100644 (file)
index 0000000..fb9419d
--- /dev/null
@@ -0,0 +1,169 @@
+From f0d8d1efe8bc705a9fb474d0fc44dde703ca440d Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 3 Dec 2013 15:15:29 +0100
+Subject: [PATCH 1168/1302] usb: gadget: rndis: merge u_rndis.ko with
+ usb_f_rndis.ko
+
+The rndis function's users use only the new interface, so the two modules
+can be merged.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig   |  7 -------
+ drivers/usb/gadget/Makefile  |  4 +---
+ drivers/usb/gadget/f_rndis.c | 22 +++++++++++++++++++++-
+ drivers/usb/gadget/rndis.c   |  7 ++-----
+ drivers/usb/gadget/u_rndis.h |  2 ++
+ 5 files changed, 26 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 60e00cf..0ba106c 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -510,9 +510,6 @@ config USB_U_SERIAL
+ config USB_U_ETHER
+       tristate
+-config USB_U_RNDIS
+-      tristate
+-
+ config USB_F_SERIAL
+       tristate
+@@ -640,7 +637,6 @@ config USB_CONFIGFS_RNDIS
+       depends on USB_CONFIGFS
+       depends on NET
+       select USB_U_ETHER
+-      select USB_U_RNDIS
+       select USB_F_RNDIS
+       help
+          Microsoft Windows XP bundles the "Remote NDIS" (RNDIS) protocol,
+@@ -770,7 +766,6 @@ config USB_ETH
+       depends on NET
+       select USB_LIBCOMPOSITE
+       select USB_U_ETHER
+-      select USB_U_RNDIS
+       select USB_F_ECM
+       select USB_F_SUBSET
+       select CRC32
+@@ -903,7 +898,6 @@ config USB_FUNCTIONFS_RNDIS
+       bool "Include configuration with RNDIS (Ethernet)"
+       depends on USB_FUNCTIONFS && NET
+       select USB_U_ETHER
+-      select USB_U_RNDIS
+       select USB_F_RNDIS
+       help
+         Include a configuration with RNDIS function (Ethernet) and the Filesystem.
+@@ -1090,7 +1084,6 @@ config USB_G_MULTI
+ config USB_G_MULTI_RNDIS
+       bool "RNDIS + CDC Serial + Storage configuration"
+       depends on USB_G_MULTI
+-      select USB_U_RNDIS
+       select USB_F_RNDIS
+       default y
+       help
+diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
+index e43af2e..47646b6 100644
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -46,8 +46,6 @@ obj-$(CONFIG_USB_F_SERIAL)   += usb_f_serial.o
+ usb_f_obex-y                  := f_obex.o
+ obj-$(CONFIG_USB_F_OBEX)      += usb_f_obex.o
+ obj-$(CONFIG_USB_U_ETHER)     += u_ether.o
+-u_rndis-y                     := rndis.o
+-obj-$(CONFIG_USB_U_RNDIS)     += u_rndis.o
+ usb_f_ncm-y                   := f_ncm.o
+ obj-$(CONFIG_USB_F_NCM)               += usb_f_ncm.o
+ usb_f_ecm-y                   := f_ecm.o
+@@ -58,7 +56,7 @@ usb_f_eem-y                  := f_eem.o
+ obj-$(CONFIG_USB_F_EEM)               += usb_f_eem.o
+ usb_f_ecm_subset-y            := f_subset.o
+ obj-$(CONFIG_USB_F_SUBSET)    += usb_f_ecm_subset.o
+-usb_f_rndis-y                 := f_rndis.o
++usb_f_rndis-y                 := f_rndis.o rndis.o
+ obj-$(CONFIG_USB_F_RNDIS)     += usb_f_rndis.o
+ usb_f_mass_storage-y          := f_mass_storage.o storage_common.o
+ obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o
+diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
+index 9d7c995..c11761c 100644
+--- a/drivers/usb/gadget/f_rndis.c
++++ b/drivers/usb/gadget/f_rndis.c
+@@ -979,6 +979,26 @@ static struct usb_function *rndis_alloc(struct usb_function_instance *fi)
+       return &rndis->port.func;
+ }
+-DECLARE_USB_FUNCTION_INIT(rndis, rndis_alloc_inst, rndis_alloc);
++DECLARE_USB_FUNCTION(rndis, rndis_alloc_inst, rndis_alloc);
++
++static int __init rndis_mod_init(void)
++{
++      int ret;
++
++      ret = rndis_init();
++      if (ret)
++              return ret;
++
++      return usb_function_register(&rndisusb_func);
++}
++module_init(rndis_mod_init);
++
++static void __exit rndis_mod_exit(void)
++{
++      usb_function_unregister(&rndisusb_func);
++      rndis_exit();
++}
++module_exit(rndis_mod_exit);
++
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("David Brownell");
+diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
+index 9575085..3184a13 100644
+--- a/drivers/usb/gadget/rndis.c
++++ b/drivers/usb/gadget/rndis.c
+@@ -1142,7 +1142,7 @@ static struct proc_dir_entry *rndis_connect_state [RNDIS_MAX_CONFIGS];
+ #endif /* CONFIG_USB_GADGET_DEBUG_FILES */
+-static int rndis_init(void)
++int rndis_init(void)
+ {
+       u8 i;
+@@ -1174,9 +1174,8 @@ static int rndis_init(void)
+       return 0;
+ }
+-module_init(rndis_init);
+-static void rndis_exit(void)
++void rndis_exit(void)
+ {
+ #ifdef CONFIG_USB_GADGET_DEBUG_FILES
+       u8 i;
+@@ -1188,6 +1187,4 @@ static void rndis_exit(void)
+       }
+ #endif
+ }
+-module_exit(rndis_exit);
+-MODULE_LICENSE("GPL");
+diff --git a/drivers/usb/gadget/u_rndis.h b/drivers/usb/gadget/u_rndis.h
+index c62ba82..7291b15 100644
+--- a/drivers/usb/gadget/u_rndis.h
++++ b/drivers/usb/gadget/u_rndis.h
+@@ -36,6 +36,8 @@ struct f_rndis_opts {
+       int                             refcnt;
+ };
++int rndis_init(void);
++void rndis_exit(void);
+ void rndis_borrow_net(struct usb_function_instance *f, struct net_device *net);
+ #endif /* U_RNDIS_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1169-usb-gadget-FunctionFS-Remove-VLAIS-usage-from-gadget.patch b/patches.tizen/1169-usb-gadget-FunctionFS-Remove-VLAIS-usage-from-gadget.patch
new file mode 100644 (file)
index 0000000..8b16186
--- /dev/null
@@ -0,0 +1,220 @@
+From 07849f42588dc9517c871579cd0a3f7f373e0a7c Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 3 Dec 2013 15:15:30 +0100
+Subject: [PATCH 1169/1302] usb: gadget: FunctionFS: Remove VLAIS usage from
+ gadget code
+
+The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
+precludes the use of compilers which don't implement VLAIS (for instance the
+Clang compiler). This alternate patch calculates offsets into the kmalloc-ed
+memory buffer using macros. The previous patch required multiple kmalloc and
+kfree calls. This version uses "group" vs "struct" since it really is not a
+struct and is essentially a group of VLA in a common allocated block. This
+version also fixes the issues pointed out by Andrzej Pietrasiewicz and
+Michal Nazarewicz.
+
+Signed-off-by: Mark Charlebois <charlebm@gmail.com>
+Signed-off-by: Behan Webster <behanw@converseincode.com>
+
+[elimination of miexed declaration and code, checkpatch cleanup]
+[fixes after Michal's review]
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_fs.c | 116 ++++++++++++++++++++++++++++++----------------
+ 1 file changed, 76 insertions(+), 40 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
+index 6453304..609ed50 100644
+--- a/drivers/usb/gadget/f_fs.c
++++ b/drivers/usb/gadget/f_fs.c
+@@ -30,6 +30,31 @@
+ #define FUNCTIONFS_MAGIC      0xa647361 /* Chosen by a honest dice roll ;) */
++/* Variable Length Array Macros **********************************************/
++#define vla_group(groupname) size_t groupname##__next = 0
++#define vla_group_size(groupname) groupname##__next
++
++#define vla_item(groupname, type, name, n) \
++      size_t groupname##_##name##__offset = ({                               \
++              size_t align_mask = __alignof__(type) - 1;                     \
++              size_t offset = (groupname##__next + align_mask) & ~align_mask;\
++              size_t size = (n) * sizeof(type);                              \
++              groupname##__next = offset + size;                             \
++              offset;                                                        \
++      })
++
++#define vla_item_with_sz(groupname, type, name, n) \
++      size_t groupname##_##name##__sz = (n) * sizeof(type);                  \
++      size_t groupname##_##name##__offset = ({                               \
++              size_t align_mask = __alignof__(type) - 1;                     \
++              size_t offset = (groupname##__next + align_mask) & ~align_mask;\
++              size_t size = groupname##_##name##__sz;                        \
++              groupname##__next = offset + size;                             \
++              offset;                                                        \
++      })
++
++#define vla_ptr(ptr, groupname, name) \
++      ((void *) ((char *)ptr + groupname##_##name##__offset))
+ /* Debugging ****************************************************************/
+@@ -1902,30 +1927,34 @@ static int __ffs_data_got_strings(struct ffs_data *ffs,
+       /* Allocate everything in one chunk so there's less maintenance. */
+       {
+-              struct {
+-                      struct usb_gadget_strings *stringtabs[lang_count + 1];
+-                      struct usb_gadget_strings stringtab[lang_count];
+-                      struct usb_string strings[lang_count*(needed_count+1)];
+-              } *d;
+               unsigned i = 0;
++              vla_group(d);
++              vla_item(d, struct usb_gadget_strings *, stringtabs,
++                      lang_count + 1);
++              vla_item(d, struct usb_gadget_strings, stringtab, lang_count);
++              vla_item(d, struct usb_string, strings,
++                      lang_count*(needed_count+1));
+-              d = kmalloc(sizeof *d, GFP_KERNEL);
+-              if (unlikely(!d)) {
++              char *vlabuf = kmalloc(vla_group_size(d), GFP_KERNEL);
++
++              if (unlikely(!vlabuf)) {
+                       kfree(_data);
+                       return -ENOMEM;
+               }
+-              stringtabs = d->stringtabs;
+-              t = d->stringtab;
++              /* Initialize the VLA pointers */
++              stringtabs = vla_ptr(vlabuf, d, stringtabs);
++              t = vla_ptr(vlabuf, d, stringtab);
+               i = lang_count;
+               do {
+                       *stringtabs++ = t++;
+               } while (--i);
+               *stringtabs = NULL;
+-              stringtabs = d->stringtabs;
+-              t = d->stringtab;
+-              s = d->strings;
++              /* stringtabs = vlabuf = d_stringtabs for later kfree */
++              stringtabs = vla_ptr(vlabuf, d, stringtabs);
++              t = vla_ptr(vlabuf, d, stringtab);
++              s = vla_ptr(vlabuf, d, strings);
+               strings = s;
+       }
+@@ -2201,16 +2230,16 @@ static int ffs_func_bind(struct usb_configuration *c,
+       int ret;
+       /* Make it a single chunk, less management later on */
+-      struct {
+-              struct ffs_ep eps[ffs->eps_count];
+-              struct usb_descriptor_header
+-                      *fs_descs[full ? ffs->fs_descs_count + 1 : 0];
+-              struct usb_descriptor_header
+-                      *hs_descs[high ? ffs->hs_descs_count + 1 : 0];
+-              short inums[ffs->interfaces_count];
+-              char raw_descs[high ? ffs->raw_descs_length
+-                                  : ffs->raw_fs_descs_length];
+-      } *data;
++      vla_group(d);
++      vla_item_with_sz(d, struct ffs_ep, eps, ffs->eps_count);
++      vla_item_with_sz(d, struct usb_descriptor_header *, fs_descs,
++              full ? ffs->fs_descs_count + 1 : 0);
++      vla_item_with_sz(d, struct usb_descriptor_header *, hs_descs,
++              high ? ffs->hs_descs_count + 1 : 0);
++      vla_item_with_sz(d, short, inums, ffs->interfaces_count);
++      vla_item_with_sz(d, char, raw_descs,
++              high ? ffs->raw_descs_length : ffs->raw_fs_descs_length);
++      char *vlabuf;
+       ENTER();
+@@ -2218,21 +2247,28 @@ static int ffs_func_bind(struct usb_configuration *c,
+       if (unlikely(!(full | high)))
+               return -ENOTSUPP;
+-      /* Allocate */
+-      data = kmalloc(sizeof *data, GFP_KERNEL);
+-      if (unlikely(!data))
++      /* Allocate a single chunk, less management later on */
++      vlabuf = kmalloc(vla_group_size(d), GFP_KERNEL);
++      if (unlikely(!vlabuf))
+               return -ENOMEM;
+       /* Zero */
+-      memset(data->eps, 0, sizeof data->eps);
+-      memcpy(data->raw_descs, ffs->raw_descs + 16, sizeof data->raw_descs);
+-      memset(data->inums, 0xff, sizeof data->inums);
+-      for (ret = ffs->eps_count; ret; --ret)
+-              data->eps[ret].num = -1;
++      memset(vla_ptr(vlabuf, d, eps), 0, d_eps__sz);
++      memcpy(vla_ptr(vlabuf, d, raw_descs), ffs->raw_descs + 16,
++             d_raw_descs__sz);
++      memset(vla_ptr(vlabuf, d, inums), 0xff, d_inums__sz);
++      for (ret = ffs->eps_count; ret; --ret) {
++              struct ffs_ep *ptr;
++
++              ptr = vla_ptr(vlabuf, d, eps);
++              ptr[ret].num = -1;
++      }
+-      /* Save pointers */
+-      func->eps             = data->eps;
+-      func->interfaces_nums = data->inums;
++      /* Save pointers
++       * d_eps == vlabuf, func->eps used to kfree vlabuf later
++      */
++      func->eps             = vla_ptr(vlabuf, d, eps);
++      func->interfaces_nums = vla_ptr(vlabuf, d, inums);
+       /*
+        * Go through all the endpoint descriptors and allocate
+@@ -2240,10 +2276,10 @@ static int ffs_func_bind(struct usb_configuration *c,
+        * numbers without worrying that it may be described later on.
+        */
+       if (likely(full)) {
+-              func->function.fs_descriptors = data->fs_descs;
++              func->function.fs_descriptors = vla_ptr(vlabuf, d, fs_descs);
+               ret = ffs_do_descs(ffs->fs_descs_count,
+-                                 data->raw_descs,
+-                                 sizeof data->raw_descs,
++                                 vla_ptr(vlabuf, d, raw_descs),
++                                 d_raw_descs__sz,
+                                  __ffs_func_bind_do_descs, func);
+               if (unlikely(ret < 0))
+                       goto error;
+@@ -2252,10 +2288,10 @@ static int ffs_func_bind(struct usb_configuration *c,
+       }
+       if (likely(high)) {
+-              func->function.hs_descriptors = data->hs_descs;
++              func->function.hs_descriptors = vla_ptr(vlabuf, d, hs_descs);
+               ret = ffs_do_descs(ffs->hs_descs_count,
+-                                 data->raw_descs + ret,
+-                                 (sizeof data->raw_descs) - ret,
++                                 vla_ptr(vlabuf, d, raw_descs) + ret,
++                                 d_raw_descs__sz - ret,
+                                  __ffs_func_bind_do_descs, func);
+               if (unlikely(ret < 0))
+                       goto error;
+@@ -2268,7 +2304,7 @@ static int ffs_func_bind(struct usb_configuration *c,
+        */
+       ret = ffs_do_descs(ffs->fs_descs_count +
+                          (high ? ffs->hs_descs_count : 0),
+-                         data->raw_descs, sizeof data->raw_descs,
++                         vla_ptr(vlabuf, d, raw_descs), d_raw_descs__sz,
+                          __ffs_func_bind_do_nums, func);
+       if (unlikely(ret < 0))
+               goto error;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1170-usb-gadget-FunctionFS-create-utility-file.patch b/patches.tizen/1170-usb-gadget-FunctionFS-create-utility-file.patch
new file mode 100644 (file)
index 0000000..db9c49b
--- /dev/null
@@ -0,0 +1,141 @@
+From e931410b74f7a4e1dab28c4f9c39e0f19512719d Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 3 Dec 2013 15:15:31 +0100
+Subject: [PATCH 1170/1302] usb: gadget: FunctionFS: create utility file
+
+A header file to be used by f_fs.c and g_ffs.c will be required when
+f_fs.c is converted into a module.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_fs.c  |  1 +
+ drivers/usb/gadget/g_ffs.c | 19 ++++++-------------
+ drivers/usb/gadget/u_fs.h  | 28 ++++++++++++++++++++++++++++
+ 3 files changed, 35 insertions(+), 13 deletions(-)
+ create mode 100644 drivers/usb/gadget/u_fs.h
+
+diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
+index 609ed50..b955cf3 100644
+--- a/drivers/usb/gadget/f_fs.c
++++ b/drivers/usb/gadget/f_fs.c
+@@ -27,6 +27,7 @@
+ #include <linux/usb/composite.h>
+ #include <linux/usb/functionfs.h>
++#include "u_fs.h"
+ #define FUNCTIONFS_MAGIC      0xa647361 /* Chosen by a honest dice roll ;) */
+diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
+index 7099a11..1aaa103 100644
+--- a/drivers/usb/gadget/g_ffs.c
++++ b/drivers/usb/gadget/g_ffs.c
+@@ -69,13 +69,6 @@ MODULE_LICENSE("GPL");
+ #define GFS_MAX_DEVS  10
+-struct gfs_ffs_obj {
+-      const char *name;
+-      bool mounted;
+-      bool desc_ready;
+-      struct ffs_data *ffs_data;
+-};
+-
+ USB_GADGET_COMPOSITE_OPTIONS();
+ static struct usb_device_descriptor gfs_dev_desc = {
+@@ -181,7 +174,7 @@ static DEFINE_MUTEX(gfs_lock);
+ static unsigned int missing_funcs;
+ static bool gfs_registered;
+ static bool gfs_single_func;
+-static struct gfs_ffs_obj *ffs_tab;
++static struct ffs_dev *ffs_tab;
+ static int __init gfs_init(void)
+ {
+@@ -224,7 +217,7 @@ static void __exit gfs_exit(void)
+ }
+ module_exit(gfs_exit);
+-static struct gfs_ffs_obj *gfs_find_dev(const char *dev_name)
++static struct ffs_dev *gfs_find_dev(const char *dev_name)
+ {
+       int i;
+@@ -242,7 +235,7 @@ static struct gfs_ffs_obj *gfs_find_dev(const char *dev_name)
+ static int functionfs_ready_callback(struct ffs_data *ffs)
+ {
+-      struct gfs_ffs_obj *ffs_obj;
++      struct ffs_dev *ffs_obj;
+       int ret;
+       ENTER();
+@@ -283,7 +276,7 @@ done:
+ static void functionfs_closed_callback(struct ffs_data *ffs)
+ {
+-      struct gfs_ffs_obj *ffs_obj;
++      struct ffs_dev *ffs_obj;
+       ENTER();
+       mutex_lock(&gfs_lock);
+@@ -305,7 +298,7 @@ done:
+ static void *functionfs_acquire_dev_callback(const char *dev_name)
+ {
+-      struct gfs_ffs_obj *ffs_dev;
++      struct ffs_dev *ffs_dev;
+       ENTER();
+       mutex_lock(&gfs_lock);
+@@ -329,7 +322,7 @@ done:
+ static void functionfs_release_dev_callback(struct ffs_data *ffs_data)
+ {
+-      struct gfs_ffs_obj *ffs_dev;
++      struct ffs_dev *ffs_dev;
+       ENTER();
+       mutex_lock(&gfs_lock);
+diff --git a/drivers/usb/gadget/u_fs.h b/drivers/usb/gadget/u_fs.h
+new file mode 100644
+index 0000000..5d9229a
+--- /dev/null
++++ b/drivers/usb/gadget/u_fs.h
+@@ -0,0 +1,28 @@
++/*
++ * u_fs.h
++ *
++ * Utility definitions for the FunctionFS
++ *
++ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
++ *            http://www.samsung.com
++ *
++ * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.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 U_FFS_H
++#define U_FFS_H
++
++#include <linux/usb/composite.h>
++
++struct ffs_dev {
++      const char *name;
++      bool mounted;
++      bool desc_ready;
++      struct ffs_data *ffs_data;
++};
++
++#endif /* U_FFS_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1171-usb-gadget-FunctionFS-add-devices-management-code.patch b/patches.tizen/1171-usb-gadget-FunctionFS-add-devices-management-code.patch
new file mode 100644 (file)
index 0000000..32e7699
--- /dev/null
@@ -0,0 +1,694 @@
+From 12884d4a37302e3740ef496f87aee11324c17147 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 3 Dec 2013 15:15:32 +0100
+Subject: [PATCH 1171/1302] usb: gadget: FunctionFS: add devices management
+ code
+
+This will be required in order to use the new function interface
+(usb_get_function_instance/usb_put_function_instance)
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyunmgin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_fs.c      | 238 +++++++++++++++++++++++++++++++++++++++--
+ drivers/usb/gadget/g_ffs.c     | 175 ++++++++++--------------------
+ drivers/usb/gadget/u_fs.h      |  24 +++++
+ include/linux/usb/functionfs.h |  14 ---
+ 4 files changed, 314 insertions(+), 137 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
+index b955cf3..f2188ad 100644
+--- a/drivers/usb/gadget/f_fs.c
++++ b/drivers/usb/gadget/f_fs.c
+@@ -90,7 +90,7 @@ enum ffs_state {
+       /*
+        * We've got descriptors and strings.  We are or have called
+-       * functionfs_ready_callback().  functionfs_bind() may have
++       * ffs_ready().  functionfs_bind() may have
+        * been called but we don't know.
+        *
+        * This is the only state in which operations on epfiles may
+@@ -103,7 +103,7 @@ enum ffs_state {
+        * we encounter an unrecoverable error.  The only
+        * unrecoverable error is situation when after reading strings
+        * from user space we fail to initialise epfiles or
+-       * functionfs_ready_callback() returns with error (<0).
++       * ffs_ready() returns with error (<0).
+        *
+        * In this state no open(2), read(2) or write(2) (both on ep0
+        * as well as epfile) may succeed (at this point epfiles are
+@@ -361,6 +361,15 @@ ffs_sb_create_file(struct super_block *sb, const char *name, void *data,
+                  const struct file_operations *fops,
+                  struct dentry **dentry_p);
++/* Devices management *******************************************************/
++
++DEFINE_MUTEX(ffs_lock);
++
++static struct ffs_dev *ffs_find_dev(const char *name);
++static void *ffs_acquire_dev(const char *dev_name);
++static void ffs_release_dev(struct ffs_data *ffs_data);
++static int ffs_ready(struct ffs_data *ffs);
++static void ffs_closed(struct ffs_data *ffs);
+ /* Misc helper functions ****************************************************/
+@@ -486,7 +495,7 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf,
+                       ffs->state = FFS_ACTIVE;
+                       mutex_unlock(&ffs->mutex);
+-                      ret = functionfs_ready_callback(ffs);
++                      ret = ffs_ready(ffs);
+                       if (unlikely(ret < 0)) {
+                               ffs->state = FFS_CLOSING;
+                               return ret;
+@@ -1218,7 +1227,7 @@ ffs_fs_mount(struct file_system_type *t, int flags,
+               return ERR_PTR(-ENOMEM);
+       }
+-      ffs_dev = functionfs_acquire_dev_callback(dev_name);
++      ffs_dev = ffs_acquire_dev(dev_name);
+       if (IS_ERR(ffs_dev)) {
+               ffs_data_put(ffs);
+               return ERR_CAST(ffs_dev);
+@@ -1228,7 +1237,7 @@ ffs_fs_mount(struct file_system_type *t, int flags,
+       rv = mount_nodev(t, flags, &data, ffs_sb_fill);
+       if (IS_ERR(rv) && data.ffs_data) {
+-              functionfs_release_dev_callback(data.ffs_data);
++              ffs_release_dev(data.ffs_data);
+               ffs_data_put(data.ffs_data);
+       }
+       return rv;
+@@ -1241,7 +1250,7 @@ ffs_fs_kill_sb(struct super_block *sb)
+       kill_litter_super(sb);
+       if (sb->s_fs_info) {
+-              functionfs_release_dev_callback(sb->s_fs_info);
++              ffs_release_dev(sb->s_fs_info);
+               ffs_data_put(sb->s_fs_info);
+       }
+ }
+@@ -1354,7 +1363,7 @@ static void ffs_data_clear(struct ffs_data *ffs)
+       ENTER();
+       if (test_and_clear_bit(FFS_FL_CALL_CLOSED_CALLBACK, &ffs->flags))
+-              functionfs_closed_callback(ffs);
++              ffs_closed(ffs);
+       BUG_ON(ffs->gadget);
+@@ -2466,6 +2475,221 @@ static int ffs_func_revmap_intf(struct ffs_function *func, u8 intf)
+ }
++/* Devices management *******************************************************/
++
++static LIST_HEAD(ffs_devices);
++
++static struct ffs_dev *_ffs_find_dev(const char *name)
++{
++      struct ffs_dev *dev;
++
++      list_for_each_entry(dev, &ffs_devices, entry) {
++              if (!dev->name || !name)
++                      continue;
++              if (strcmp(dev->name, name) == 0)
++                      return dev;
++      }
++      
++      return NULL;
++}
++
++/*
++ * ffs_lock must be taken by the caller of this function
++ */
++static struct ffs_dev *ffs_get_single_dev(void)
++{
++      struct ffs_dev *dev;
++
++      if (list_is_singular(&ffs_devices)) {
++              dev = list_first_entry(&ffs_devices, struct ffs_dev, entry);
++              if (dev->single)
++                      return dev;
++      }
++
++      return NULL;
++}
++
++/*
++ * ffs_lock must be taken by the caller of this function
++ */
++static struct ffs_dev *ffs_find_dev(const char *name)
++{
++      struct ffs_dev *dev;
++
++      dev = ffs_get_single_dev();
++      if (dev)
++              return dev;
++
++      return _ffs_find_dev(name);
++}
++
++/*
++ * ffs_lock must be taken by the caller of this function
++ */
++struct ffs_dev *ffs_alloc_dev(void)
++{
++      struct ffs_dev *dev;
++      int ret;
++
++      if (ffs_get_single_dev())
++                      return ERR_PTR(-EBUSY);
++
++      dev = kzalloc(sizeof(*dev), GFP_KERNEL);
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      if (list_empty(&ffs_devices)) {
++              ret = functionfs_init();
++              if (ret) {
++                      kfree(dev);
++                      return ERR_PTR(ret);
++              }
++      }
++
++      list_add(&dev->entry, &ffs_devices);
++
++      return dev;
++}
++
++/*
++ * ffs_lock must be taken by the caller of this function
++ * The caller is responsible for "name" being available whenever f_fs needs it
++ */
++static int _ffs_name_dev(struct ffs_dev *dev, const char *name)
++{
++      struct ffs_dev *existing;
++
++      existing = _ffs_find_dev(name);
++      if (existing)
++              return -EBUSY;
++      
++      dev->name = name;
++
++      return 0;
++}
++
++/*
++ * The caller is responsible for "name" being available whenever f_fs needs it
++ */
++int ffs_name_dev(struct ffs_dev *dev, const char *name)
++{
++      int ret;
++
++      ffs_dev_lock();
++      ret = _ffs_name_dev(dev, name);
++      ffs_dev_unlock();
++
++      return ret;
++}
++
++int ffs_single_dev(struct ffs_dev *dev)
++{
++      int ret;
++
++      ret = 0;
++      ffs_dev_lock();
++
++      if (!list_is_singular(&ffs_devices))
++              ret = -EBUSY;
++      else
++              dev->single = true;
++
++      ffs_dev_unlock();
++      return ret;
++}
++
++/*
++ * ffs_lock must be taken by the caller of this function
++ */
++void ffs_free_dev(struct ffs_dev *dev)
++{
++      list_del(&dev->entry);
++      kfree(dev);
++      if (list_empty(&ffs_devices))
++              functionfs_cleanup();
++}
++
++static void *ffs_acquire_dev(const char *dev_name)
++{
++      struct ffs_dev *ffs_dev;
++
++      ENTER();
++      ffs_dev_lock();
++
++      ffs_dev = ffs_find_dev(dev_name);
++      if (!ffs_dev)
++              ffs_dev = ERR_PTR(-ENODEV);
++      else if (ffs_dev->mounted)
++              ffs_dev = ERR_PTR(-EBUSY);
++      else
++              ffs_dev->mounted = true;
++
++      ffs_dev_unlock();
++      return ffs_dev;
++}
++
++static void ffs_release_dev(struct ffs_data *ffs_data)
++{
++      struct ffs_dev *ffs_dev;
++
++      ENTER();
++      ffs_dev_lock();
++
++      ffs_dev = ffs_data->private_data;
++      if (ffs_dev)
++              ffs_dev->mounted = false;
++
++      ffs_dev_unlock();
++}
++
++static int ffs_ready(struct ffs_data *ffs)
++{
++      struct ffs_dev *ffs_obj;
++      int ret = 0;
++
++      ENTER();
++      ffs_dev_lock();
++
++      ffs_obj = ffs->private_data;
++      if (!ffs_obj) {
++              ret = -EINVAL;
++              goto done;
++      }
++      if (WARN_ON(ffs_obj->desc_ready)) {
++              ret = -EBUSY;
++              goto done;
++      }
++
++      ffs_obj->desc_ready = true;
++      ffs_obj->ffs_data = ffs;
++
++      if (ffs_obj->ffs_ready_callback)
++              ret = ffs_obj->ffs_ready_callback(ffs);
++
++done:
++      ffs_dev_unlock();
++      return ret;
++}
++
++static void ffs_closed(struct ffs_data *ffs)
++{
++      struct ffs_dev *ffs_obj;
++
++      ENTER();
++      ffs_dev_lock();
++
++      ffs_obj = ffs->private_data;
++      if (!ffs_obj)
++              goto done;
++
++      ffs_obj->desc_ready = false;
++
++      if (ffs_obj->ffs_closed_callback)
++              ffs_obj->ffs_closed_callback(ffs);
++done:
++      ffs_dev_unlock();
++}
++
+ /* Misc helper functions ****************************************************/
+ static int ffs_mutex_lock(struct mutex *mutex, unsigned nonblock)
+diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
+index 1aaa103..074df0d 100644
+--- a/drivers/usb/gadget/g_ffs.c
++++ b/drivers/usb/gadget/g_ffs.c
+@@ -157,6 +157,8 @@ struct gfs_configuration {
+ #endif
+ };
++static int functionfs_ready_callback(struct ffs_data *ffs);
++static void functionfs_closed_callback(struct ffs_data *ffs);
+ static int gfs_bind(struct usb_composite_dev *cdev);
+ static int gfs_unbind(struct usb_composite_dev *cdev);
+ static int gfs_do_config(struct usb_configuration *c);
+@@ -170,172 +172,113 @@ static __refdata struct usb_composite_driver gfs_driver = {
+       .unbind         = gfs_unbind,
+ };
+-static DEFINE_MUTEX(gfs_lock);
+ static unsigned int missing_funcs;
+ static bool gfs_registered;
+ static bool gfs_single_func;
+-static struct ffs_dev *ffs_tab;
++static struct ffs_dev **ffs_tab;
+ static int __init gfs_init(void)
+ {
+       int i;
++      int ret = 0;
+       ENTER();
+-      if (!func_num) {
++      if (func_num < 2) {
+               gfs_single_func = true;
+               func_num = 1;
+       }
+-      ffs_tab = kcalloc(func_num, sizeof *ffs_tab, GFP_KERNEL);
++      ffs_tab = kcalloc(func_num, sizeof(*ffs_tab), GFP_KERNEL);
+       if (!ffs_tab)
+               return -ENOMEM;
+-      if (!gfs_single_func)
+-              for (i = 0; i < func_num; i++)
+-                      ffs_tab[i].name = func_names[i];
++      for (i = 0; i < func_num; i++) {
++              ffs_dev_lock();
++              ffs_tab[i] = ffs_alloc_dev();
++              ffs_dev_unlock();
++              if (IS_ERR(ffs_tab[i])) {
++                      ret = PTR_ERR(ffs_tab[i]);
++                      --i;
++                      goto no_dev;
++              }
++              if (gfs_single_func)
++                      ret = ffs_single_dev(ffs_tab[i]);
++              else
++                      ret = ffs_name_dev(ffs_tab[i], func_names[i]);
++              if (ret)
++                      goto no_dev;
++              ffs_tab[i]->ffs_ready_callback = functionfs_ready_callback;
++              ffs_tab[i]->ffs_closed_callback = functionfs_closed_callback;
++      }
+       missing_funcs = func_num;
+-      return functionfs_init();
++      return 0;
++no_dev:
++      ffs_dev_lock();
++      while (i >= 0)
++              ffs_free_dev(ffs_tab[i--]);
++      ffs_dev_unlock();
++      kfree(ffs_tab);
++      return ret;
+ }
+ module_init(gfs_init);
+ static void __exit gfs_exit(void)
+ {
++      int i;
++
+       ENTER();
+-      mutex_lock(&gfs_lock);
++      ffs_dev_lock();
+       if (gfs_registered)
+               usb_composite_unregister(&gfs_driver);
+       gfs_registered = false;
+-      functionfs_cleanup();
+-
+-      mutex_unlock(&gfs_lock);
++      for (i = 0; i < func_num; i++)
++              ffs_free_dev(ffs_tab[i]);
++      ffs_dev_unlock();
+       kfree(ffs_tab);
+ }
+ module_exit(gfs_exit);
+-static struct ffs_dev *gfs_find_dev(const char *dev_name)
+-{
+-      int i;
+-
+-      ENTER();
+-
+-      if (gfs_single_func)
+-              return &ffs_tab[0];
+-
+-      for (i = 0; i < func_num; i++)
+-              if (strcmp(ffs_tab[i].name, dev_name) == 0)
+-                      return &ffs_tab[i];
+-
+-      return NULL;
+-}
+-
++/*
++ * The caller of this function takes ffs_lock 
++ */
+ static int functionfs_ready_callback(struct ffs_data *ffs)
+ {
+-      struct ffs_dev *ffs_obj;
+-      int ret;
+-
+-      ENTER();
+-      mutex_lock(&gfs_lock);
++      int ret = 0;
+-      ffs_obj = ffs->private_data;
+-      if (!ffs_obj) {
+-              ret = -EINVAL;
+-              goto done;
+-      }
+-
+-      if (WARN_ON(ffs_obj->desc_ready)) {
+-              ret = -EBUSY;
+-              goto done;
+-      }
+-      ffs_obj->desc_ready = true;
+-      ffs_obj->ffs_data = ffs;
++      if (--missing_funcs)
++              return 0;
+-      if (--missing_funcs) {
+-              ret = 0;
+-              goto done;
+-      }
++      if (gfs_registered)
++              return -EBUSY;
+-      if (gfs_registered) {
+-              ret = -EBUSY;
+-              goto done;
+-      }
+       gfs_registered = true;
+       ret = usb_composite_probe(&gfs_driver);
+       if (unlikely(ret < 0))
+               gfs_registered = false;
+-
+-done:
+-      mutex_unlock(&gfs_lock);
++      
+       return ret;
+ }
++/*
++ * The caller of this function takes ffs_lock 
++ */
+ static void functionfs_closed_callback(struct ffs_data *ffs)
+ {
+-      struct ffs_dev *ffs_obj;
+-
+-      ENTER();
+-      mutex_lock(&gfs_lock);
+-
+-      ffs_obj = ffs->private_data;
+-      if (!ffs_obj)
+-              goto done;
+-
+-      ffs_obj->desc_ready = false;
+       missing_funcs++;
+       if (gfs_registered)
+               usb_composite_unregister(&gfs_driver);
+       gfs_registered = false;
+-
+-done:
+-      mutex_unlock(&gfs_lock);
+-}
+-
+-static void *functionfs_acquire_dev_callback(const char *dev_name)
+-{
+-      struct ffs_dev *ffs_dev;
+-
+-      ENTER();
+-      mutex_lock(&gfs_lock);
+-
+-      ffs_dev = gfs_find_dev(dev_name);
+-      if (!ffs_dev) {
+-              ffs_dev = ERR_PTR(-ENODEV);
+-              goto done;
+-      }
+-
+-      if (ffs_dev->mounted) {
+-              ffs_dev = ERR_PTR(-EBUSY);
+-              goto done;
+-      }
+-      ffs_dev->mounted = true;
+-
+-done:
+-      mutex_unlock(&gfs_lock);
+-      return ffs_dev;
+-}
+-
+-static void functionfs_release_dev_callback(struct ffs_data *ffs_data)
+-{
+-      struct ffs_dev *ffs_dev;
+-
+-      ENTER();
+-      mutex_lock(&gfs_lock);
+-
+-      ffs_dev = ffs_data->private_data;
+-      if (ffs_dev)
+-              ffs_dev->mounted = false;
+-
+-      mutex_unlock(&gfs_lock);
+ }
+ /*
+- * It is assumed that gfs_bind is called from a context where gfs_lock is held
++ * It is assumed that gfs_bind is called from a context where ffs_lock is held
+  */
+ static int gfs_bind(struct usb_composite_dev *cdev)
+ {
+@@ -422,10 +365,10 @@ static int gfs_bind(struct usb_composite_dev *cdev)
+       gfs_dev_desc.iProduct = gfs_strings[USB_GADGET_PRODUCT_IDX].id;
+       for (i = func_num; i--; ) {
+-              ret = functionfs_bind(ffs_tab[i].ffs_data, cdev);
++              ret = functionfs_bind(ffs_tab[i]->ffs_data, cdev);
+               if (unlikely(ret < 0)) {
+                       while (++i < func_num)
+-                              functionfs_unbind(ffs_tab[i].ffs_data);
++                              functionfs_unbind(ffs_tab[i]->ffs_data);
+                       goto error_rndis;
+               }
+       }
+@@ -448,7 +391,7 @@ static int gfs_bind(struct usb_composite_dev *cdev)
+ error_unbind:
+       for (i = 0; i < func_num; i++)
+-              functionfs_unbind(ffs_tab[i].ffs_data);
++              functionfs_unbind(ffs_tab[i]->ffs_data);
+ error_rndis:
+ #ifdef CONFIG_USB_FUNCTIONFS_RNDIS
+       usb_put_function_instance(fi_rndis);
+@@ -464,7 +407,7 @@ error:
+ }
+ /*
+- * It is assumed that gfs_unbind is called from a context where gfs_lock is held
++ * It is assumed that gfs_unbind is called from a context where ffs_lock is held
+  */
+ static int gfs_unbind(struct usb_composite_dev *cdev)
+ {
+@@ -497,15 +440,15 @@ static int gfs_unbind(struct usb_composite_dev *cdev)
+        * do...?
+        */
+       for (i = func_num; i--; )
+-              if (ffs_tab[i].ffs_data)
+-                      functionfs_unbind(ffs_tab[i].ffs_data);
++              if (ffs_tab[i]->ffs_data)
++                      functionfs_unbind(ffs_tab[i]->ffs_data);
+       return 0;
+ }
+ /*
+  * It is assumed that gfs_do_config is called from a context where
+- * gfs_lock is held
++ * ffs_lock is held
+  */
+ static int gfs_do_config(struct usb_configuration *c)
+ {
+@@ -529,7 +472,7 @@ static int gfs_do_config(struct usb_configuration *c)
+       }
+       for (i = 0; i < func_num; i++) {
+-              ret = functionfs_bind_config(c->cdev, c, ffs_tab[i].ffs_data);
++              ret = functionfs_bind_config(c->cdev, c, ffs_tab[i]->ffs_data);
+               if (unlikely(ret < 0))
+                       return ret;
+       }
+diff --git a/drivers/usb/gadget/u_fs.h b/drivers/usb/gadget/u_fs.h
+index 5d9229a..2d00f9d 100644
+--- a/drivers/usb/gadget/u_fs.h
++++ b/drivers/usb/gadget/u_fs.h
+@@ -17,12 +17,36 @@
+ #define U_FFS_H
+ #include <linux/usb/composite.h>
++#include <linux/list.h>
++#include <linux/mutex.h>
+ struct ffs_dev {
+       const char *name;
+       bool mounted;
+       bool desc_ready;
++      bool single;
+       struct ffs_data *ffs_data;
++      struct list_head entry;
++
++      int (*ffs_ready_callback)(struct ffs_data *ffs);
++      void (*ffs_closed_callback)(struct ffs_data *ffs);
+ };
++extern struct mutex ffs_lock;
++
++static inline void ffs_dev_lock(void)
++{
++      mutex_lock(&ffs_lock);
++}
++
++static inline void ffs_dev_unlock(void)
++{
++      mutex_unlock(&ffs_lock);
++}
++
++struct ffs_dev *ffs_alloc_dev(void);
++int ffs_name_dev(struct ffs_dev *dev, const char *name);
++int ffs_single_dev(struct ffs_dev *dev);
++void ffs_free_dev(struct ffs_dev *dev);
++
+ #endif /* U_FFS_H */
+diff --git a/include/linux/usb/functionfs.h b/include/linux/usb/functionfs.h
+index 65d0a88..9c1e926 100644
+--- a/include/linux/usb/functionfs.h
++++ b/include/linux/usb/functionfs.h
+@@ -8,10 +8,6 @@ struct ffs_data;
+ struct usb_composite_dev;
+ struct usb_configuration;
+-
+-static int  functionfs_init(void) __attribute__((warn_unused_result));
+-static void functionfs_cleanup(void);
+-
+ static int functionfs_bind(struct ffs_data *ffs, struct usb_composite_dev *cdev)
+       __attribute__((warn_unused_result, nonnull));
+ static void functionfs_unbind(struct ffs_data *ffs)
+@@ -23,14 +19,4 @@ static int functionfs_bind_config(struct usb_composite_dev *cdev,
+       __attribute__((warn_unused_result, nonnull));
+-static int functionfs_ready_callback(struct ffs_data *ffs)
+-      __attribute__((warn_unused_result, nonnull));
+-static void functionfs_closed_callback(struct ffs_data *ffs)
+-      __attribute__((nonnull));
+-static void *functionfs_acquire_dev_callback(const char *dev_name)
+-      __attribute__((warn_unused_result, nonnull));
+-static void functionfs_release_dev_callback(struct ffs_data *ffs_data)
+-      __attribute__((nonnull));
+-
+-
+ #endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1172-usb-gadget-FunctionFS-convert-to-new-function-interf.patch b/patches.tizen/1172-usb-gadget-FunctionFS-convert-to-new-function-interf.patch
new file mode 100644 (file)
index 0000000..b0b189e
--- /dev/null
@@ -0,0 +1,865 @@
+From d37c6c402606925ac4ab7dcac0b8809f7d0c7ef1 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 3 Dec 2013 15:15:33 +0100
+Subject: [PATCH 1172/1302] usb: gadget: FunctionFS: convert to new function
+ interface with backward compatibility
+
+This is required in order to integrate configfs support.
+f_fs needs to be a separately compiled module and so it needs to use the new
+interface.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig     |   3 +
+ drivers/usb/gadget/Makefile    |   2 +
+ drivers/usb/gadget/f_fs.c      | 422 +++++++++++++++++++++--------------------
+ drivers/usb/gadget/g_ffs.c     |   1 +
+ drivers/usb/gadget/u_fs.h      | 214 +++++++++++++++++++++
+ include/linux/usb/functionfs.h |   2 +
+ 6 files changed, 435 insertions(+), 209 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 0ba106c..3407f56 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -537,6 +537,9 @@ config USB_F_RNDIS
+ config USB_F_MASS_STORAGE
+       tristate
++config USB_F_FS
++      tristate
++
+ choice
+       tristate "USB Gadget Drivers"
+       default USB_ETH
+diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
+index 47646b6..85bfe98 100644
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -60,6 +60,8 @@ usb_f_rndis-y                        := f_rndis.o rndis.o
+ obj-$(CONFIG_USB_F_RNDIS)     += usb_f_rndis.o
+ usb_f_mass_storage-y          := f_mass_storage.o storage_common.o
+ obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o
++usb_f_fs-y                    := f_fs.o
++obj-$(CONFIG_USB_F_FS)                += usb_f_fs.o
+ #
+ # USB gadget drivers
+diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
+index f2188ad..1a5ffa5 100644
+--- a/drivers/usb/gadget/f_fs.c
++++ b/drivers/usb/gadget/f_fs.c
+@@ -22,6 +22,7 @@
+ #include <linux/pagemap.h>
+ #include <linux/export.h>
+ #include <linux/hid.h>
++#include <linux/module.h>
+ #include <asm/unaligned.h>
+ #include <linux/usb/composite.h>
+@@ -57,210 +58,6 @@
+ #define vla_ptr(ptr, groupname, name) \
+       ((void *) ((char *)ptr + groupname##_##name##__offset))
+-/* Debugging ****************************************************************/
+-
+-#ifdef VERBOSE_DEBUG
+-#ifndef pr_vdebug
+-#  define pr_vdebug pr_debug
+-#endif /* pr_vdebug */
+-#  define ffs_dump_mem(prefix, ptr, len) \
+-      print_hex_dump_bytes(pr_fmt(prefix ": "), DUMP_PREFIX_NONE, ptr, len)
+-#else
+-#ifndef pr_vdebug
+-#  define pr_vdebug(...)                 do { } while (0)
+-#endif /* pr_vdebug */
+-#  define ffs_dump_mem(prefix, ptr, len) do { } while (0)
+-#endif /* VERBOSE_DEBUG */
+-
+-#define ENTER()    pr_vdebug("%s()\n", __func__)
+-
+-
+-/* The data structure and setup file ****************************************/
+-
+-enum ffs_state {
+-      /*
+-       * Waiting for descriptors and strings.
+-       *
+-       * In this state no open(2), read(2) or write(2) on epfiles
+-       * may succeed (which should not be the problem as there
+-       * should be no such files opened in the first place).
+-       */
+-      FFS_READ_DESCRIPTORS,
+-      FFS_READ_STRINGS,
+-
+-      /*
+-       * We've got descriptors and strings.  We are or have called
+-       * ffs_ready().  functionfs_bind() may have
+-       * been called but we don't know.
+-       *
+-       * This is the only state in which operations on epfiles may
+-       * succeed.
+-       */
+-      FFS_ACTIVE,
+-
+-      /*
+-       * All endpoints have been closed.  This state is also set if
+-       * we encounter an unrecoverable error.  The only
+-       * unrecoverable error is situation when after reading strings
+-       * from user space we fail to initialise epfiles or
+-       * ffs_ready() returns with error (<0).
+-       *
+-       * In this state no open(2), read(2) or write(2) (both on ep0
+-       * as well as epfile) may succeed (at this point epfiles are
+-       * unlinked and all closed so this is not a problem; ep0 is
+-       * also closed but ep0 file exists and so open(2) on ep0 must
+-       * fail).
+-       */
+-      FFS_CLOSING
+-};
+-
+-
+-enum ffs_setup_state {
+-      /* There is no setup request pending. */
+-      FFS_NO_SETUP,
+-      /*
+-       * User has read events and there was a setup request event
+-       * there.  The next read/write on ep0 will handle the
+-       * request.
+-       */
+-      FFS_SETUP_PENDING,
+-      /*
+-       * There was event pending but before user space handled it
+-       * some other event was introduced which canceled existing
+-       * setup.  If this state is set read/write on ep0 return
+-       * -EIDRM.  This state is only set when adding event.
+-       */
+-      FFS_SETUP_CANCELED
+-};
+-
+-
+-
+-struct ffs_epfile;
+-struct ffs_function;
+-
+-struct ffs_data {
+-      struct usb_gadget               *gadget;
+-
+-      /*
+-       * Protect access read/write operations, only one read/write
+-       * at a time.  As a consequence protects ep0req and company.
+-       * While setup request is being processed (queued) this is
+-       * held.
+-       */
+-      struct mutex                    mutex;
+-
+-      /*
+-       * Protect access to endpoint related structures (basically
+-       * usb_ep_queue(), usb_ep_dequeue(), etc. calls) except for
+-       * endpoint zero.
+-       */
+-      spinlock_t                      eps_lock;
+-
+-      /*
+-       * XXX REVISIT do we need our own request? Since we are not
+-       * handling setup requests immediately user space may be so
+-       * slow that another setup will be sent to the gadget but this
+-       * time not to us but another function and then there could be
+-       * a race.  Is that the case? Or maybe we can use cdev->req
+-       * after all, maybe we just need some spinlock for that?
+-       */
+-      struct usb_request              *ep0req;                /* P: mutex */
+-      struct completion               ep0req_completion;      /* P: mutex */
+-      int                             ep0req_status;          /* P: mutex */
+-
+-      /* reference counter */
+-      atomic_t                        ref;
+-      /* how many files are opened (EP0 and others) */
+-      atomic_t                        opened;
+-
+-      /* EP0 state */
+-      enum ffs_state                  state;
+-
+-      /*
+-       * Possible transitions:
+-       * + FFS_NO_SETUP       -> FFS_SETUP_PENDING  -- P: ev.waitq.lock
+-       *               happens only in ep0 read which is P: mutex
+-       * + FFS_SETUP_PENDING  -> FFS_NO_SETUP       -- P: ev.waitq.lock
+-       *               happens only in ep0 i/o  which is P: mutex
+-       * + FFS_SETUP_PENDING  -> FFS_SETUP_CANCELED -- P: ev.waitq.lock
+-       * + FFS_SETUP_CANCELED -> FFS_NO_SETUP       -- cmpxchg
+-       */
+-      enum ffs_setup_state            setup_state;
+-
+-#define FFS_SETUP_STATE(ffs)                                  \
+-      ((enum ffs_setup_state)cmpxchg(&(ffs)->setup_state,     \
+-                                     FFS_SETUP_CANCELED, FFS_NO_SETUP))
+-
+-      /* Events & such. */
+-      struct {
+-              u8                              types[4];
+-              unsigned short                  count;
+-              /* XXX REVISIT need to update it in some places, or do we? */
+-              unsigned short                  can_stall;
+-              struct usb_ctrlrequest          setup;
+-
+-              wait_queue_head_t               waitq;
+-      } ev; /* the whole structure, P: ev.waitq.lock */
+-
+-      /* Flags */
+-      unsigned long                   flags;
+-#define FFS_FL_CALL_CLOSED_CALLBACK 0
+-#define FFS_FL_BOUND                1
+-
+-      /* Active function */
+-      struct ffs_function             *func;
+-
+-      /*
+-       * Device name, write once when file system is mounted.
+-       * Intended for user to read if she wants.
+-       */
+-      const char                      *dev_name;
+-      /* Private data for our user (ie. gadget).  Managed by user. */
+-      void                            *private_data;
+-
+-      /* filled by __ffs_data_got_descs() */
+-      /*
+-       * Real descriptors are 16 bytes after raw_descs (so you need
+-       * to skip 16 bytes (ie. ffs->raw_descs + 16) to get to the
+-       * first full speed descriptor).  raw_descs_length and
+-       * raw_fs_descs_length do not have those 16 bytes added.
+-       */
+-      const void                      *raw_descs;
+-      unsigned                        raw_descs_length;
+-      unsigned                        raw_fs_descs_length;
+-      unsigned                        fs_descs_count;
+-      unsigned                        hs_descs_count;
+-
+-      unsigned short                  strings_count;
+-      unsigned short                  interfaces_count;
+-      unsigned short                  eps_count;
+-      unsigned short                  _pad1;
+-
+-      /* filled by __ffs_data_got_strings() */
+-      /* ids in stringtabs are set in functionfs_bind() */
+-      const void                      *raw_strings;
+-      struct usb_gadget_strings       **stringtabs;
+-
+-      /*
+-       * File system's super block, write once when file system is
+-       * mounted.
+-       */
+-      struct super_block              *sb;
+-
+-      /* File permissions, written once when fs is mounted */
+-      struct ffs_file_perms {
+-              umode_t                         mode;
+-              kuid_t                          uid;
+-              kgid_t                          gid;
+-      }                               file_perms;
+-
+-      /*
+-       * The endpoint files, filled by ffs_epfiles_create(),
+-       * destroyed by ffs_epfiles_destroy().
+-       */
+-      struct ffs_epfile               *epfiles;
+-};
+-
+ /* Reference counter handling */
+ static void ffs_data_get(struct ffs_data *ffs);
+ static void ffs_data_put(struct ffs_data *ffs);
+@@ -300,15 +97,19 @@ static struct ffs_function *ffs_func_from_usb(struct usb_function *f)
+       return container_of(f, struct ffs_function, function);
+ }
++#ifdef USB_FFS_INCLUDED
+ static void ffs_func_free(struct ffs_function *func);
++#endif
+ static void ffs_func_eps_disable(struct ffs_function *func);
+ static int __must_check ffs_func_eps_enable(struct ffs_function *func);
+ static int ffs_func_bind(struct usb_configuration *,
+                        struct usb_function *);
+-static void ffs_func_unbind(struct usb_configuration *,
++#ifdef USB_FFS_INCLUDED
++static void old_ffs_func_unbind(struct usb_configuration *,
+                           struct usb_function *);
++#endif
+ static int ffs_func_set_alt(struct usb_function *, unsigned, unsigned);
+ static void ffs_func_disable(struct usb_function *);
+ static int ffs_func_setup(struct usb_function *,
+@@ -364,6 +165,9 @@ ffs_sb_create_file(struct super_block *sb, const char *name, void *data,
+ /* Devices management *******************************************************/
+ DEFINE_MUTEX(ffs_lock);
++#ifndef USB_FFS_INCLUDED
++EXPORT_SYMBOL(ffs_lock);
++#endif
+ static struct ffs_dev *ffs_find_dev(const char *name);
+ static void *ffs_acquire_dev(const char *dev_name);
+@@ -1499,6 +1303,8 @@ static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count)
+       kfree(epfiles);
+ }
++#ifdef USB_FFS_INCLUDED
++
+ static int functionfs_bind_config(struct usb_composite_dev *cdev,
+                                 struct usb_configuration *c,
+                                 struct ffs_data *ffs)
+@@ -1516,7 +1322,7 @@ static int functionfs_bind_config(struct usb_composite_dev *cdev,
+       func->function.strings = ffs->stringtabs;
+       func->function.bind    = ffs_func_bind;
+-      func->function.unbind  = ffs_func_unbind;
++      func->function.unbind  = old_ffs_func_unbind;
+       func->function.set_alt = ffs_func_set_alt;
+       func->function.disable = ffs_func_disable;
+       func->function.setup   = ffs_func_setup;
+@@ -1565,6 +1371,8 @@ static void ffs_func_free(struct ffs_function *func)
+       kfree(func);
+ }
++#endif
++
+ static void ffs_func_eps_disable(struct ffs_function *func)
+ {
+       struct ffs_ep *ep         = func->eps;
+@@ -2227,8 +2035,59 @@ static int __ffs_func_bind_do_nums(enum ffs_entity_type type, u8 *valuep,
+       return 0;
+ }
+-static int ffs_func_bind(struct usb_configuration *c,
+-                       struct usb_function *f)
++#ifndef USB_FFS_INCLUDED
++static inline struct f_fs_opts *ffs_do_functionfs_bind(struct usb_function *f,
++                                              struct usb_configuration *c)
++{
++      struct ffs_function *func = ffs_func_from_usb(f);
++      struct f_fs_opts *ffs_opts =
++              container_of(f->fi, struct f_fs_opts, func_inst);
++      int ret;
++
++      ENTER();
++
++      /*
++       * Legacy gadget triggers binding in functionfs_ready_callback,
++       * which already uses locking; taking the same lock here would
++       * cause a deadlock.
++       *
++       * Configfs-enabled gadgets however do need ffs_dev_lock.
++       */
++      if (!ffs_opts->no_configfs)
++              ffs_dev_lock();
++      ret = ffs_opts->dev->desc_ready ? 0 : -ENODEV;
++      func->ffs = ffs_opts->dev->ffs_data;
++      if (!ffs_opts->no_configfs)
++              ffs_dev_unlock();
++      if (ret)
++              return ERR_PTR(ret);
++
++      func->conf = c;
++      func->gadget = c->cdev->gadget;
++
++      ffs_data_get(func->ffs);
++
++      /*
++       * in drivers/usb/gadget/configfs.c:configfs_composite_bind()
++       * configurations are bound in sequence with list_for_each_entry,
++       * in each configuration its functions are bound in sequence
++       * with list_for_each_entry, so we assume no race condition
++       * with regard to ffs_opts->bound access
++       */
++      if (!ffs_opts->refcnt) {
++              ret = functionfs_bind(func->ffs, c->cdev);
++              if (ret)
++                      return ERR_PTR(ret);
++      }
++      ffs_opts->refcnt++;
++      func->function.strings = func->ffs->stringtabs;
++
++      return ffs_opts;
++}
++#endif
++
++static int _ffs_func_bind(struct usb_configuration *c,
++                        struct usb_function *f)
+ {
+       struct ffs_function *func = ffs_func_from_usb(f);
+       struct ffs_data *ffs = func->ffs;
+@@ -2328,10 +2187,25 @@ error:
+       return ret;
+ }
++static int ffs_func_bind(struct usb_configuration *c,
++                       struct usb_function *f)
++{
++#ifndef USB_FFS_INCLUDED
++      struct f_fs_opts *ffs_opts = ffs_do_functionfs_bind(f, c);
++
++      if (IS_ERR(ffs_opts))
++              return PTR_ERR(ffs_opts);
++#endif
++
++      return _ffs_func_bind(c, f);
++}
++
+ /* Other USB function hooks *************************************************/
+-static void ffs_func_unbind(struct usb_configuration *c,
++#ifdef USB_FFS_INCLUDED
++
++static void old_ffs_func_unbind(struct usb_configuration *c,
+                           struct usb_function *f)
+ {
+       struct ffs_function *func = ffs_func_from_usb(f);
+@@ -2349,6 +2223,8 @@ static void ffs_func_unbind(struct usb_configuration *c,
+       ffs_func_free(func);
+ }
++#endif
++
+ static int ffs_func_set_alt(struct usb_function *f,
+                           unsigned interface, unsigned alt)
+ {
+@@ -2523,6 +2399,116 @@ static struct ffs_dev *ffs_find_dev(const char *name)
+       return _ffs_find_dev(name);
+ }
++/* Function registration interface ******************************************/
++
++#ifndef USB_FFS_INCLUDED
++
++static void ffs_free_inst(struct usb_function_instance *f)
++{
++      struct f_fs_opts *opts;
++
++      opts = to_f_fs_opts(f);
++      ffs_dev_lock();
++      ffs_free_dev(opts->dev);
++      ffs_dev_unlock();
++      kfree(opts);
++}
++
++static struct usb_function_instance *ffs_alloc_inst(void)
++{
++      struct f_fs_opts *opts;
++      struct ffs_dev *dev;
++
++      opts = kzalloc(sizeof(*opts), GFP_KERNEL);
++      if (!opts)
++              return ERR_PTR(-ENOMEM);
++
++      opts->func_inst.free_func_inst = ffs_free_inst;
++      ffs_dev_lock();
++      dev = ffs_alloc_dev();
++      ffs_dev_unlock();
++      if (IS_ERR(dev)) {
++              kfree(opts);
++              return ERR_CAST(dev);
++      }
++      opts->dev = dev;
++
++      return &opts->func_inst;
++}
++
++static void ffs_free(struct usb_function *f)
++{
++      kfree(ffs_func_from_usb(f));
++}
++
++static void ffs_func_unbind(struct usb_configuration *c,
++                          struct usb_function *f)
++{
++      struct ffs_function *func = ffs_func_from_usb(f);
++      struct ffs_data *ffs = func->ffs;
++      struct f_fs_opts *opts =
++              container_of(f->fi, struct f_fs_opts, func_inst);
++      struct ffs_ep *ep = func->eps;
++      unsigned count = ffs->eps_count;
++      unsigned long flags;
++
++      ENTER();
++      if (ffs->func == func) {
++              ffs_func_eps_disable(func);
++              ffs->func = NULL;
++      }
++
++      if (!--opts->refcnt)
++              functionfs_unbind(ffs);
++
++      /* cleanup after autoconfig */
++      spin_lock_irqsave(&func->ffs->eps_lock, flags);
++      do {
++              if (ep->ep && ep->req)
++                      usb_ep_free_request(ep->ep, ep->req);
++              ep->req = NULL;
++              ++ep;
++      } while (--count);
++      spin_unlock_irqrestore(&func->ffs->eps_lock, flags);
++      kfree(func->eps);
++      func->eps = NULL;
++      /*
++       * eps, descriptors and interfaces_nums are allocated in the
++       * same chunk so only one free is required.
++       */
++      func->function.fs_descriptors = NULL;
++      func->function.hs_descriptors = NULL;
++      func->interfaces_nums = NULL;
++
++      ffs_event_add(ffs, FUNCTIONFS_UNBIND);
++}
++
++static struct usb_function *ffs_alloc(struct usb_function_instance *fi)
++{
++      struct ffs_function *func;
++
++      ENTER();
++
++      func = kzalloc(sizeof(*func), GFP_KERNEL);
++      if (unlikely(!func))
++              return ERR_PTR(-ENOMEM);
++
++      func->function.name    = "Function FS Gadget";
++
++      func->function.bind    = ffs_func_bind;
++      func->function.unbind  = ffs_func_unbind;
++      func->function.set_alt = ffs_func_set_alt;
++      func->function.disable = ffs_func_disable;
++      func->function.setup   = ffs_func_setup;
++      func->function.suspend = ffs_func_suspend;
++      func->function.resume  = ffs_func_resume;
++      func->function.free_func = ffs_free;
++
++      return &func->function;
++}
++
++#endif
++
+ /*
+  * ffs_lock must be taken by the caller of this function
+  */
+@@ -2581,6 +2567,9 @@ int ffs_name_dev(struct ffs_dev *dev, const char *name)
+       return ret;
+ }
++#ifndef USB_FFS_INCLUDED
++EXPORT_SYMBOL(ffs_name_dev);
++#endif
+ int ffs_single_dev(struct ffs_dev *dev)
+ {
+@@ -2597,6 +2586,9 @@ int ffs_single_dev(struct ffs_dev *dev)
+       ffs_dev_unlock();
+       return ret;
+ }
++#ifndef USB_FFS_INCLUDED
++EXPORT_SYMBOL(ffs_single_dev);
++#endif
+ /*
+  * ffs_lock must be taken by the caller of this function
+@@ -2621,6 +2613,9 @@ static void *ffs_acquire_dev(const char *dev_name)
+               ffs_dev = ERR_PTR(-ENODEV);
+       else if (ffs_dev->mounted)
+               ffs_dev = ERR_PTR(-EBUSY);
++      else if (ffs_dev->ffs_acquire_dev_callback &&
++          ffs_dev->ffs_acquire_dev_callback(ffs_dev))
++              ffs_dev = ERR_PTR(-ENODEV);
+       else
+               ffs_dev->mounted = true;
+@@ -2638,6 +2633,9 @@ static void ffs_release_dev(struct ffs_data *ffs_data)
+       ffs_dev = ffs_data->private_data;
+       if (ffs_dev)
+               ffs_dev->mounted = false;
++      
++      if (ffs_dev->ffs_release_dev_callback)
++              ffs_dev->ffs_release_dev_callback(ffs_dev);
+       ffs_dev_unlock();
+ }
+@@ -2720,3 +2718,9 @@ static char *ffs_prepare_buffer(const char __user *buf, size_t len)
+       return data;
+ }
++
++#ifndef USB_FFS_INCLUDED
++DECLARE_USB_FUNCTION_INIT(ffs, ffs_alloc_inst, ffs_alloc);
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Michal Nazarewicz");
++#endif
+diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
+index 074df0d..ffde36f 100644
+--- a/drivers/usb/gadget/g_ffs.c
++++ b/drivers/usb/gadget/g_ffs.c
+@@ -54,6 +54,7 @@ static struct usb_function *f_rndis;
+ #  endif
+ #endif
++#define USB_FFS_INCLUDED
+ #include "f_fs.c"
+ #define DRIVER_NAME   "g_ffs"
+diff --git a/drivers/usb/gadget/u_fs.h b/drivers/usb/gadget/u_fs.h
+index 2d00f9d..d60a9dd 100644
+--- a/drivers/usb/gadget/u_fs.h
++++ b/drivers/usb/gadget/u_fs.h
+@@ -20,6 +20,22 @@
+ #include <linux/list.h>
+ #include <linux/mutex.h>
++#ifdef VERBOSE_DEBUG
++#ifndef pr_vdebug
++#  define pr_vdebug pr_debug
++#endif /* pr_vdebug */
++#  define ffs_dump_mem(prefix, ptr, len) \
++      print_hex_dump_bytes(pr_fmt(prefix ": "), DUMP_PREFIX_NONE, ptr, len)
++#else
++#ifndef pr_vdebug
++#  define pr_vdebug(...)                 do { } while (0)
++#endif /* pr_vdebug */
++#  define ffs_dump_mem(prefix, ptr, len) do { } while (0)
++#endif /* VERBOSE_DEBUG */
++
++#define ENTER()    pr_vdebug("%s()\n", __func__)
++
++
+ struct ffs_dev {
+       const char *name;
+       bool mounted;
+@@ -30,6 +46,8 @@ struct ffs_dev {
+       int (*ffs_ready_callback)(struct ffs_data *ffs);
+       void (*ffs_closed_callback)(struct ffs_data *ffs);
++      void *(*ffs_acquire_dev_callback)(struct ffs_dev *dev);
++      void (*ffs_release_dev_callback)(struct ffs_dev *dev);
+ };
+ extern struct mutex ffs_lock;
+@@ -49,4 +67,200 @@ int ffs_name_dev(struct ffs_dev *dev, const char *name);
+ int ffs_single_dev(struct ffs_dev *dev);
+ void ffs_free_dev(struct ffs_dev *dev);
++struct ffs_epfile;
++struct ffs_function;
++
++enum ffs_state {
++      /*
++       * Waiting for descriptors and strings.
++       *
++       * In this state no open(2), read(2) or write(2) on epfiles
++       * may succeed (which should not be the problem as there
++       * should be no such files opened in the first place).
++       */
++      FFS_READ_DESCRIPTORS,
++      FFS_READ_STRINGS,
++
++      /*
++       * We've got descriptors and strings.  We are or have called
++       * functionfs_ready_callback().  functionfs_bind() may have
++       * been called but we don't know.
++       *
++       * This is the only state in which operations on epfiles may
++       * succeed.
++       */
++      FFS_ACTIVE,
++
++      /*
++       * All endpoints have been closed.  This state is also set if
++       * we encounter an unrecoverable error.  The only
++       * unrecoverable error is situation when after reading strings
++       * from user space we fail to initialise epfiles or
++       * functionfs_ready_callback() returns with error (<0).
++       *
++       * In this state no open(2), read(2) or write(2) (both on ep0
++       * as well as epfile) may succeed (at this point epfiles are
++       * unlinked and all closed so this is not a problem; ep0 is
++       * also closed but ep0 file exists and so open(2) on ep0 must
++       * fail).
++       */
++      FFS_CLOSING
++};
++
++enum ffs_setup_state {
++      /* There is no setup request pending. */
++      FFS_NO_SETUP,
++      /*
++       * User has read events and there was a setup request event
++       * there.  The next read/write on ep0 will handle the
++       * request.
++       */
++      FFS_SETUP_PENDING,
++      /*
++       * There was event pending but before user space handled it
++       * some other event was introduced which canceled existing
++       * setup.  If this state is set read/write on ep0 return
++       * -EIDRM.  This state is only set when adding event.
++       */
++      FFS_SETUP_CANCELED
++};
++
++struct ffs_data {
++      struct usb_gadget               *gadget;
++
++      /*
++       * Protect access read/write operations, only one read/write
++       * at a time.  As a consequence protects ep0req and company.
++       * While setup request is being processed (queued) this is
++       * held.
++       */
++      struct mutex                    mutex;
++
++      /*
++       * Protect access to endpoint related structures (basically
++       * usb_ep_queue(), usb_ep_dequeue(), etc. calls) except for
++       * endpoint zero.
++       */
++      spinlock_t                      eps_lock;
++
++      /*
++       * XXX REVISIT do we need our own request? Since we are not
++       * handling setup requests immediately user space may be so
++       * slow that another setup will be sent to the gadget but this
++       * time not to us but another function and then there could be
++       * a race.  Is that the case? Or maybe we can use cdev->req
++       * after all, maybe we just need some spinlock for that?
++       */
++      struct usb_request              *ep0req;                /* P: mutex */
++      struct completion               ep0req_completion;      /* P: mutex */
++      int                             ep0req_status;          /* P: mutex */
++
++      /* reference counter */
++      atomic_t                        ref;
++      /* how many files are opened (EP0 and others) */
++      atomic_t                        opened;
++
++      /* EP0 state */
++      enum ffs_state                  state;
++
++      /*
++       * Possible transitions:
++       * + FFS_NO_SETUP       -> FFS_SETUP_PENDING  -- P: ev.waitq.lock
++       *               happens only in ep0 read which is P: mutex
++       * + FFS_SETUP_PENDING  -> FFS_NO_SETUP       -- P: ev.waitq.lock
++       *               happens only in ep0 i/o  which is P: mutex
++       * + FFS_SETUP_PENDING  -> FFS_SETUP_CANCELED -- P: ev.waitq.lock
++       * + FFS_SETUP_CANCELED -> FFS_NO_SETUP       -- cmpxchg
++       */
++      enum ffs_setup_state            setup_state;
++
++#define FFS_SETUP_STATE(ffs)                                  \
++      ((enum ffs_setup_state)cmpxchg(&(ffs)->setup_state,     \
++                                     FFS_SETUP_CANCELED, FFS_NO_SETUP))
++
++      /* Events & such. */
++      struct {
++              u8                              types[4];
++              unsigned short                  count;
++              /* XXX REVISIT need to update it in some places, or do we? */
++              unsigned short                  can_stall;
++              struct usb_ctrlrequest          setup;
++
++              wait_queue_head_t               waitq;
++      } ev; /* the whole structure, P: ev.waitq.lock */
++
++      /* Flags */
++      unsigned long                   flags;
++#define FFS_FL_CALL_CLOSED_CALLBACK 0
++#define FFS_FL_BOUND                1
++
++      /* Active function */
++      struct ffs_function             *func;
++
++      /*
++       * Device name, write once when file system is mounted.
++       * Intended for user to read if she wants.
++       */
++      const char                      *dev_name;
++      /* Private data for our user (ie. gadget).  Managed by user. */
++      void                            *private_data;
++
++      /* filled by __ffs_data_got_descs() */
++      /*
++       * Real descriptors are 16 bytes after raw_descs (so you need
++       * to skip 16 bytes (ie. ffs->raw_descs + 16) to get to the
++       * first full speed descriptor).  raw_descs_length and
++       * raw_fs_descs_length do not have those 16 bytes added.
++       */
++      const void                      *raw_descs;
++      unsigned                        raw_descs_length;
++      unsigned                        raw_fs_descs_length;
++      unsigned                        fs_descs_count;
++      unsigned                        hs_descs_count;
++
++      unsigned short                  strings_count;
++      unsigned short                  interfaces_count;
++      unsigned short                  eps_count;
++      unsigned short                  _pad1;
++
++      /* filled by __ffs_data_got_strings() */
++      /* ids in stringtabs are set in functionfs_bind() */
++      const void                      *raw_strings;
++      struct usb_gadget_strings       **stringtabs;
++
++      /*
++       * File system's super block, write once when file system is
++       * mounted.
++       */
++      struct super_block              *sb;
++
++      /* File permissions, written once when fs is mounted */
++      struct ffs_file_perms {
++              umode_t                         mode;
++              kuid_t                          uid;
++              kgid_t                          gid;
++      }                               file_perms;
++
++      /*
++       * The endpoint files, filled by ffs_epfiles_create(),
++       * destroyed by ffs_epfiles_destroy().
++       */
++      struct ffs_epfile               *epfiles;
++};
++
++
++#ifndef USB_FFS_INCLUDED
++struct f_fs_opts {
++      struct usb_function_instance    func_inst;
++      struct ffs_dev                  *dev;
++      unsigned                        refcnt;
++      bool                            no_configfs;
++};
++
++static inline struct f_fs_opts *to_f_fs_opts(struct usb_function_instance *fi)
++{
++      return container_of(fi, struct f_fs_opts, func_inst);
++}
++#endif
++
+ #endif /* U_FFS_H */
+diff --git a/include/linux/usb/functionfs.h b/include/linux/usb/functionfs.h
+index 9c1e926..3448efb 100644
+--- a/include/linux/usb/functionfs.h
++++ b/include/linux/usb/functionfs.h
+@@ -3,6 +3,7 @@
+ #include <uapi/linux/usb/functionfs.h>
++#ifdef USB_FFS_INCLUDED
+ struct ffs_data;
+ struct usb_composite_dev;
+@@ -20,3 +21,4 @@ static int functionfs_bind_config(struct usb_composite_dev *cdev,
+ #endif
++#endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1173-usb-gadget-g_ffs-convert-to-new-interface-of-f_fs.patch b/patches.tizen/1173-usb-gadget-g_ffs-convert-to-new-interface-of-f_fs.patch
new file mode 100644 (file)
index 0000000..e7abd10
--- /dev/null
@@ -0,0 +1,320 @@
+From d7ab1d8264ff67d2824c0d9c5ba1062b14ad8d0b Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 3 Dec 2013 15:15:34 +0100
+Subject: [PATCH 1173/1302] usb: gadget: g_ffs: convert to new interface of
+ f_fs
+
+Prepare for configfs integration. Use the new interface so that f_fs can be
+made a module.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig |   1 +
+ drivers/usb/gadget/g_ffs.c | 151 ++++++++++++++++++++++++++++-----------------
+ 2 files changed, 96 insertions(+), 56 deletions(-)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 3407f56..4e57d24 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -872,6 +872,7 @@ config USB_GADGETFS
+ config USB_FUNCTIONFS
+       tristate "Function Filesystem"
+       select USB_LIBCOMPOSITE
++      select USB_F_FS
+       select USB_FUNCTIONFS_GENERIC if !(USB_FUNCTIONFS_ETH || USB_FUNCTIONFS_RNDIS)
+       help
+         The Function Filesystem (FunctionFS) lets one create USB
+diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
+index ffde36f..fe12e6a 100644
+--- a/drivers/usb/gadget/g_ffs.c
++++ b/drivers/usb/gadget/g_ffs.c
+@@ -13,13 +13,7 @@
+ #define pr_fmt(fmt) "g_ffs: " fmt
+ #include <linux/module.h>
+-/*
+- * kbuild is not very cooperative with respect to linking separately
+- * compiled library objects into one module.  So for now we won't use
+- * separate compilation ... ensuring init/exit sections work to shrink
+- * the runtime footprint, and giving us at least some parts of what
+- * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+- */
++
+ #if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS
+ #include <linux/netdevice.h>
+@@ -54,8 +48,7 @@ static struct usb_function *f_rndis;
+ #  endif
+ #endif
+-#define USB_FFS_INCLUDED
+-#include "f_fs.c"
++#include "u_fs.h"
+ #define DRIVER_NAME   "g_ffs"
+ #define DRIVER_DESC   "USB Function Filesystem"
+@@ -139,6 +132,7 @@ static struct usb_gadget_strings *gfs_dev_strings[] = {
+ struct gfs_configuration {
+       struct usb_configuration c;
+       int (*eth)(struct usb_configuration *c);
++      int num;
+ } gfs_configurations[] = {
+ #ifdef CONFIG_USB_FUNCTIONFS_RNDIS
+       {
+@@ -158,12 +152,15 @@ struct gfs_configuration {
+ #endif
+ };
++static void *functionfs_acquire_dev(struct ffs_dev *dev);
++static void functionfs_release_dev(struct ffs_dev *dev);
+ static int functionfs_ready_callback(struct ffs_data *ffs);
+ static void functionfs_closed_callback(struct ffs_data *ffs);
+ static int gfs_bind(struct usb_composite_dev *cdev);
+ static int gfs_unbind(struct usb_composite_dev *cdev);
+ static int gfs_do_config(struct usb_configuration *c);
++
+ static __refdata struct usb_composite_driver gfs_driver = {
+       .name           = DRIVER_NAME,
+       .dev            = &gfs_dev_desc,
+@@ -176,10 +173,26 @@ static __refdata struct usb_composite_driver gfs_driver = {
+ static unsigned int missing_funcs;
+ static bool gfs_registered;
+ static bool gfs_single_func;
+-static struct ffs_dev **ffs_tab;
++static struct usb_function_instance **fi_ffs;
++static struct usb_function **f_ffs[] = {
++#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
++      NULL,
++#endif
++
++#ifdef CONFIG_USB_FUNCTIONFS_ETH
++      NULL,
++#endif
++
++#ifdef CONFIG_USB_FUNCTIONFS_GENERIC
++      NULL,
++#endif
++};
++
++#define N_CONF ARRAY_SIZE(f_ffs)
+ static int __init gfs_init(void)
+ {
++      struct f_fs_opts *opts;
+       int i;
+       int ret = 0;
+@@ -190,38 +203,53 @@ static int __init gfs_init(void)
+               func_num = 1;
+       }
+-      ffs_tab = kcalloc(func_num, sizeof(*ffs_tab), GFP_KERNEL);
+-      if (!ffs_tab)
+-              return -ENOMEM;
++      /*
++       * Allocate in one chunk for easier maintenance
++       */
++      f_ffs[0] = kcalloc(func_num * N_CONF, sizeof(*f_ffs), GFP_KERNEL);
++      if (!f_ffs[0]) {
++              ret = -ENOMEM;
++              goto no_func;
++      }
++      for (i = 1; i < N_CONF; ++i)
++              f_ffs[i] = f_ffs[0] + i * func_num;
++
++      fi_ffs = kcalloc(func_num, sizeof(*fi_ffs), GFP_KERNEL);
++      if (!fi_ffs) {
++              ret = -ENOMEM;
++              goto no_func;
++      }
+       for (i = 0; i < func_num; i++) {
+-              ffs_dev_lock();
+-              ffs_tab[i] = ffs_alloc_dev();
+-              ffs_dev_unlock();
+-              if (IS_ERR(ffs_tab[i])) {
+-                      ret = PTR_ERR(ffs_tab[i]);
++              fi_ffs[i] = usb_get_function_instance("ffs");
++              if (IS_ERR(fi_ffs[i])) {
++                      ret = PTR_ERR(fi_ffs[i]);
+                       --i;
+                       goto no_dev;
+               }
++              opts = to_f_fs_opts(fi_ffs[i]);
+               if (gfs_single_func)
+-                      ret = ffs_single_dev(ffs_tab[i]);
++                      ret = ffs_single_dev(opts->dev);
+               else
+-                      ret = ffs_name_dev(ffs_tab[i], func_names[i]);
++                      ret = ffs_name_dev(opts->dev, func_names[i]);
+               if (ret)
+                       goto no_dev;
+-              ffs_tab[i]->ffs_ready_callback = functionfs_ready_callback;
+-              ffs_tab[i]->ffs_closed_callback = functionfs_closed_callback;
++              opts->dev->ffs_ready_callback = functionfs_ready_callback;
++              opts->dev->ffs_closed_callback = functionfs_closed_callback;
++              opts->dev->ffs_acquire_dev_callback = functionfs_acquire_dev;
++              opts->dev->ffs_release_dev_callback = functionfs_release_dev;
++              opts->no_configfs = true;
+       }
+       missing_funcs = func_num;
+       return 0;
+ no_dev:
+-      ffs_dev_lock();
+       while (i >= 0)
+-              ffs_free_dev(ffs_tab[i--]);
+-      ffs_dev_unlock();
+-      kfree(ffs_tab);
++              usb_put_function_instance(fi_ffs[i--]);
++      kfree(fi_ffs);
++no_func:
++      kfree(f_ffs[0]);
+       return ret;
+ }
+ module_init(gfs_init);
+@@ -231,19 +259,33 @@ static void __exit gfs_exit(void)
+       int i;
+       ENTER();
+-      ffs_dev_lock();
+       if (gfs_registered)
+               usb_composite_unregister(&gfs_driver);
+       gfs_registered = false;
++      kfree(f_ffs[0]);
++
+       for (i = 0; i < func_num; i++)
+-              ffs_free_dev(ffs_tab[i]);
+-      ffs_dev_unlock();
+-      kfree(ffs_tab);
++              usb_put_function_instance(fi_ffs[i]);
++
++      kfree(fi_ffs);
+ }
+ module_exit(gfs_exit);
++static void *functionfs_acquire_dev(struct ffs_dev *dev)
++{
++      if (!try_module_get(THIS_MODULE))
++              return ERR_PTR(-ENODEV);
++      
++      return 0;
++}
++
++static void functionfs_release_dev(struct ffs_dev *dev)
++{
++      module_put(THIS_MODULE);
++}
++
+ /*
+  * The caller of this function takes ffs_lock 
+  */
+@@ -360,20 +402,12 @@ static int gfs_bind(struct usb_composite_dev *cdev)
+       rndis_borrow_net(fi_rndis, net);
+ #endif
++      /* TODO: gstrings_attach? */
+       ret = usb_string_ids_tab(cdev, gfs_strings);
+       if (unlikely(ret < 0))
+               goto error_rndis;
+       gfs_dev_desc.iProduct = gfs_strings[USB_GADGET_PRODUCT_IDX].id;
+-      for (i = func_num; i--; ) {
+-              ret = functionfs_bind(ffs_tab[i]->ffs_data, cdev);
+-              if (unlikely(ret < 0)) {
+-                      while (++i < func_num)
+-                              functionfs_unbind(ffs_tab[i]->ffs_data);
+-                      goto error_rndis;
+-              }
+-      }
+-
+       for (i = 0; i < ARRAY_SIZE(gfs_configurations); ++i) {
+               struct gfs_configuration *c = gfs_configurations + i;
+               int sid = USB_GADGET_FIRST_AVAIL_IDX + i;
+@@ -383,6 +417,8 @@ static int gfs_bind(struct usb_composite_dev *cdev)
+               c->c.bConfigurationValue        = 1 + i;
+               c->c.bmAttributes               = USB_CONFIG_ATT_SELFPOWER;
++              c->num = i;
++
+               ret = usb_add_config(cdev, &c->c, gfs_do_config);
+               if (unlikely(ret < 0))
+                       goto error_unbind;
+@@ -390,9 +426,8 @@ static int gfs_bind(struct usb_composite_dev *cdev)
+       usb_composite_overwrite_options(cdev, &coverwrite);
+       return 0;
++/* TODO */
+ error_unbind:
+-      for (i = 0; i < func_num; i++)
+-              functionfs_unbind(ffs_tab[i]->ffs_data);
+ error_rndis:
+ #ifdef CONFIG_USB_FUNCTIONFS_RNDIS
+       usb_put_function_instance(fi_rndis);
+@@ -431,18 +466,8 @@ static int gfs_unbind(struct usb_composite_dev *cdev)
+               usb_put_function_instance(fi_geth);
+       }
+ #endif
+-
+-      /*
+-       * We may have been called in an error recovery from
+-       * composite_bind() after gfs_unbind() failure so we need to
+-       * check if instance's ffs_data is not NULL since gfs_bind() handles
+-       * all error recovery itself.  I'd rather we werent called
+-       * from composite on orror recovery, but what you're gonna
+-       * do...?
+-       */
+-      for (i = func_num; i--; )
+-              if (ffs_tab[i]->ffs_data)
+-                      functionfs_unbind(ffs_tab[i]->ffs_data);
++      for (i = 0; i < N_CONF * func_num; ++i)
++              usb_put_function(*(f_ffs[0] + i));
+       return 0;
+ }
+@@ -473,9 +498,16 @@ static int gfs_do_config(struct usb_configuration *c)
+       }
+       for (i = 0; i < func_num; i++) {
+-              ret = functionfs_bind_config(c->cdev, c, ffs_tab[i]->ffs_data);
+-              if (unlikely(ret < 0))
+-                      return ret;
++              f_ffs[gc->num][i] = usb_get_function(fi_ffs[i]);
++              if (IS_ERR(f_ffs[gc->num][i])) {
++                      ret = PTR_ERR(f_ffs[gc->num][i]);
++                      goto error;
++              }
++              ret = usb_add_function(c, f_ffs[gc->num][i]);
++              if (ret < 0) {
++                      usb_put_function(f_ffs[gc->num][i]);
++                      goto error;
++              }
+       }
+       /*
+@@ -492,6 +524,13 @@ static int gfs_do_config(struct usb_configuration *c)
+               c->interface[c->next_interface_id] = NULL;
+       return 0;
++error:
++      while (--i >= 0) {
++              if (!IS_ERR(f_ffs[gc->num][i]))
++                      usb_remove_function(c, f_ffs[gc->num][i]);
++              usb_put_function(f_ffs[gc->num][i]);
++      }
++      return ret;
+ }
+ #ifdef CONFIG_USB_FUNCTIONFS_ETH
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1174-usb-gadget-FunctionFS-Remove-compatibility-layer.patch b/patches.tizen/1174-usb-gadget-FunctionFS-Remove-compatibility-layer.patch
new file mode 100644 (file)
index 0000000..ebcd4a0
--- /dev/null
@@ -0,0 +1,283 @@
+From 9f7a9d27575f02e16de4d03c4e6bc126c32f0efa Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 3 Dec 2013 15:15:35 +0100
+Subject: [PATCH 1174/1302] usb: gadget: FunctionFS: Remove compatibility layer
+
+There are no old function interface users left, so the old interface can
+be removed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_fs.c      | 114 -----------------------------------------
+ drivers/usb/gadget/u_fs.h      |   2 -
+ include/linux/usb/functionfs.h |  18 -------
+ 3 files changed, 134 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
+index 1a5ffa5..1c362a6 100644
+--- a/drivers/usb/gadget/f_fs.c
++++ b/drivers/usb/gadget/f_fs.c
+@@ -97,19 +97,12 @@ static struct ffs_function *ffs_func_from_usb(struct usb_function *f)
+       return container_of(f, struct ffs_function, function);
+ }
+-#ifdef USB_FFS_INCLUDED
+-static void ffs_func_free(struct ffs_function *func);
+-#endif
+ static void ffs_func_eps_disable(struct ffs_function *func);
+ static int __must_check ffs_func_eps_enable(struct ffs_function *func);
+ static int ffs_func_bind(struct usb_configuration *,
+                        struct usb_function *);
+-#ifdef USB_FFS_INCLUDED
+-static void old_ffs_func_unbind(struct usb_configuration *,
+-                          struct usb_function *);
+-#endif
+ static int ffs_func_set_alt(struct usb_function *, unsigned, unsigned);
+ static void ffs_func_disable(struct usb_function *);
+ static int ffs_func_setup(struct usb_function *,
+@@ -165,9 +158,7 @@ ffs_sb_create_file(struct super_block *sb, const char *name, void *data,
+ /* Devices management *******************************************************/
+ DEFINE_MUTEX(ffs_lock);
+-#ifndef USB_FFS_INCLUDED
+ EXPORT_SYMBOL(ffs_lock);
+-#endif
+ static struct ffs_dev *ffs_find_dev(const char *name);
+ static void *ffs_acquire_dev(const char *dev_name);
+@@ -1303,75 +1294,6 @@ static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count)
+       kfree(epfiles);
+ }
+-#ifdef USB_FFS_INCLUDED
+-
+-static int functionfs_bind_config(struct usb_composite_dev *cdev,
+-                                struct usb_configuration *c,
+-                                struct ffs_data *ffs)
+-{
+-      struct ffs_function *func;
+-      int ret;
+-
+-      ENTER();
+-
+-      func = kzalloc(sizeof *func, GFP_KERNEL);
+-      if (unlikely(!func))
+-              return -ENOMEM;
+-
+-      func->function.name    = "Function FS Gadget";
+-      func->function.strings = ffs->stringtabs;
+-
+-      func->function.bind    = ffs_func_bind;
+-      func->function.unbind  = old_ffs_func_unbind;
+-      func->function.set_alt = ffs_func_set_alt;
+-      func->function.disable = ffs_func_disable;
+-      func->function.setup   = ffs_func_setup;
+-      func->function.suspend = ffs_func_suspend;
+-      func->function.resume  = ffs_func_resume;
+-
+-      func->conf   = c;
+-      func->gadget = cdev->gadget;
+-      func->ffs = ffs;
+-      ffs_data_get(ffs);
+-
+-      ret = usb_add_function(c, &func->function);
+-      if (unlikely(ret))
+-              ffs_func_free(func);
+-
+-      return ret;
+-}
+-
+-static void ffs_func_free(struct ffs_function *func)
+-{
+-      struct ffs_ep *ep         = func->eps;
+-      unsigned count            = func->ffs->eps_count;
+-      unsigned long flags;
+-
+-      ENTER();
+-
+-      /* cleanup after autoconfig */
+-      spin_lock_irqsave(&func->ffs->eps_lock, flags);
+-      do {
+-              if (ep->ep && ep->req)
+-                      usb_ep_free_request(ep->ep, ep->req);
+-              ep->req = NULL;
+-              ++ep;
+-      } while (--count);
+-      spin_unlock_irqrestore(&func->ffs->eps_lock, flags);
+-
+-      ffs_data_put(func->ffs);
+-
+-      kfree(func->eps);
+-      /*
+-       * eps and interfaces_nums are allocated in the same chunk so
+-       * only one free is required.  Descriptors are also allocated
+-       * in the same chunk.
+-       */
+-
+-      kfree(func);
+-}
+-
+-#endif
+ static void ffs_func_eps_disable(struct ffs_function *func)
+ {
+@@ -2035,7 +1957,6 @@ static int __ffs_func_bind_do_nums(enum ffs_entity_type type, u8 *valuep,
+       return 0;
+ }
+-#ifndef USB_FFS_INCLUDED
+ static inline struct f_fs_opts *ffs_do_functionfs_bind(struct usb_function *f,
+                                               struct usb_configuration *c)
+ {
+@@ -2084,7 +2005,6 @@ static inline struct f_fs_opts *ffs_do_functionfs_bind(struct usb_function *f,
+       return ffs_opts;
+ }
+-#endif
+ static int _ffs_func_bind(struct usb_configuration *c,
+                         struct usb_function *f)
+@@ -2190,12 +2110,10 @@ error:
+ static int ffs_func_bind(struct usb_configuration *c,
+                        struct usb_function *f)
+ {
+-#ifndef USB_FFS_INCLUDED
+       struct f_fs_opts *ffs_opts = ffs_do_functionfs_bind(f, c);
+       if (IS_ERR(ffs_opts))
+               return PTR_ERR(ffs_opts);
+-#endif
+       return _ffs_func_bind(c, f);
+ }
+@@ -2203,28 +2121,6 @@ static int ffs_func_bind(struct usb_configuration *c,
+ /* Other USB function hooks *************************************************/
+-#ifdef USB_FFS_INCLUDED
+-
+-static void old_ffs_func_unbind(struct usb_configuration *c,
+-                          struct usb_function *f)
+-{
+-      struct ffs_function *func = ffs_func_from_usb(f);
+-      struct ffs_data *ffs = func->ffs;
+-
+-      ENTER();
+-
+-      if (ffs->func == func) {
+-              ffs_func_eps_disable(func);
+-              ffs->func = NULL;
+-      }
+-
+-      ffs_event_add(ffs, FUNCTIONFS_UNBIND);
+-
+-      ffs_func_free(func);
+-}
+-
+-#endif
+-
+ static int ffs_func_set_alt(struct usb_function *f,
+                           unsigned interface, unsigned alt)
+ {
+@@ -2401,8 +2297,6 @@ static struct ffs_dev *ffs_find_dev(const char *name)
+ /* Function registration interface ******************************************/
+-#ifndef USB_FFS_INCLUDED
+-
+ static void ffs_free_inst(struct usb_function_instance *f)
+ {
+       struct f_fs_opts *opts;
+@@ -2507,8 +2401,6 @@ static struct usb_function *ffs_alloc(struct usb_function_instance *fi)
+       return &func->function;
+ }
+-#endif
+-
+ /*
+  * ffs_lock must be taken by the caller of this function
+  */
+@@ -2567,9 +2459,7 @@ int ffs_name_dev(struct ffs_dev *dev, const char *name)
+       return ret;
+ }
+-#ifndef USB_FFS_INCLUDED
+ EXPORT_SYMBOL(ffs_name_dev);
+-#endif
+ int ffs_single_dev(struct ffs_dev *dev)
+ {
+@@ -2586,9 +2476,7 @@ int ffs_single_dev(struct ffs_dev *dev)
+       ffs_dev_unlock();
+       return ret;
+ }
+-#ifndef USB_FFS_INCLUDED
+ EXPORT_SYMBOL(ffs_single_dev);
+-#endif
+ /*
+  * ffs_lock must be taken by the caller of this function
+@@ -2719,8 +2607,6 @@ static char *ffs_prepare_buffer(const char __user *buf, size_t len)
+       return data;
+ }
+-#ifndef USB_FFS_INCLUDED
+ DECLARE_USB_FUNCTION_INIT(ffs, ffs_alloc_inst, ffs_alloc);
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Michal Nazarewicz");
+-#endif
+diff --git a/drivers/usb/gadget/u_fs.h b/drivers/usb/gadget/u_fs.h
+index d60a9dd..0931375 100644
+--- a/drivers/usb/gadget/u_fs.h
++++ b/drivers/usb/gadget/u_fs.h
+@@ -249,7 +249,6 @@ struct ffs_data {
+ };
+-#ifndef USB_FFS_INCLUDED
+ struct f_fs_opts {
+       struct usb_function_instance    func_inst;
+       struct ffs_dev                  *dev;
+@@ -261,6 +260,5 @@ static inline struct f_fs_opts *to_f_fs_opts(struct usb_function_instance *fi)
+ {
+       return container_of(fi, struct f_fs_opts, func_inst);
+ }
+-#endif
+ #endif /* U_FFS_H */
+diff --git a/include/linux/usb/functionfs.h b/include/linux/usb/functionfs.h
+index 3448efb..7119066 100644
+--- a/include/linux/usb/functionfs.h
++++ b/include/linux/usb/functionfs.h
+@@ -3,22 +3,4 @@
+ #include <uapi/linux/usb/functionfs.h>
+-#ifdef USB_FFS_INCLUDED
+-
+-struct ffs_data;
+-struct usb_composite_dev;
+-struct usb_configuration;
+-
+-static int functionfs_bind(struct ffs_data *ffs, struct usb_composite_dev *cdev)
+-      __attribute__((warn_unused_result, nonnull));
+-static void functionfs_unbind(struct ffs_data *ffs)
+-      __attribute__((nonnull));
+-
+-static int functionfs_bind_config(struct usb_composite_dev *cdev,
+-                                struct usb_configuration *c,
+-                                struct ffs_data *ffs)
+-      __attribute__((warn_unused_result, nonnull));
+-
+-
+-#endif
+ #endif
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1175-usb-gadget-FunctionFS-add-configfs-support.patch b/patches.tizen/1175-usb-gadget-FunctionFS-add-configfs-support.patch
new file mode 100644 (file)
index 0000000..dd3d70d
--- /dev/null
@@ -0,0 +1,233 @@
+From ad16d5436e519b8c0336a65bf3f4788432090b03 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Tue, 3 Dec 2013 15:15:36 +0100
+Subject: [PATCH 1175/1302] usb: gadget: FunctionFS: add configfs support
+
+Add support for using FunctionFS in configfs-based USB gadgets.
+
+[ balbi@ti.com : removed redefinition of VERBOSE_DEBUG and few
+       trailing whitespaces ]
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/ABI/testing/configfs-usb-gadget-ffs |  9 +++
+ drivers/usb/gadget/Kconfig                        | 12 ++++
+ drivers/usb/gadget/f_fs.c                         | 80 ++++++++++++++++++++++-
+ drivers/usb/gadget/u_fs.h                         |  3 +
+ 4 files changed, 103 insertions(+), 1 deletion(-)
+ create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-ffs
+
+diff --git a/Documentation/ABI/testing/configfs-usb-gadget-ffs b/Documentation/ABI/testing/configfs-usb-gadget-ffs
+new file mode 100644
+index 0000000..14343e2
+--- /dev/null
++++ b/Documentation/ABI/testing/configfs-usb-gadget-ffs
+@@ -0,0 +1,9 @@
++What:         /config/usb-gadget/gadget/functions/ffs.name
++Date:         Nov 2013
++KenelVersion: 3.13
++Description:  The purpose of this directory is to create and remove it.
++
++              A corresponding USB function instance is created/removed.
++              There are no attributes here.
++
++              All parameters are set through FunctionFS.
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index 4e57d24..c864c884 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -699,6 +699,18 @@ config USB_CONFIGFS_F_LB_SS
+         test software, like the "usbtest" driver, to put your hardware
+         and its driver through a basic set of functional tests.
++config USB_CONFIGFS_F_FS
++      boolean "Function filesystem (FunctionFS)"
++      depends on USB_CONFIGFS
++      select USB_F_FS
++      help
++        The Function Filesystem (FunctionFS) lets one create USB
++        composite functions in user space in the same way GadgetFS
++        lets one create USB gadgets in user space.  This allows creation
++        of composite gadgets such that some of the functions are
++        implemented in kernel space (for instance Ethernet, serial or
++        mass storage) and other are implemented in user space.
++
+ config USB_ZERO
+       tristate "Gadget Zero (DEVELOPMENT)"
+       select USB_LIBCOMPOSITE
+diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
+index 1c362a6..cb9330d 100644
+--- a/drivers/usb/gadget/f_fs.c
++++ b/drivers/usb/gadget/f_fs.c
+@@ -29,6 +29,7 @@
+ #include <linux/usb/functionfs.h>
+ #include "u_fs.h"
++#include "configfs.h"
+ #define FUNCTIONFS_MAGIC      0xa647361 /* Chosen by a honest dice roll ;) */
+@@ -161,6 +162,7 @@ DEFINE_MUTEX(ffs_lock);
+ EXPORT_SYMBOL(ffs_lock);
+ static struct ffs_dev *ffs_find_dev(const char *name);
++static int _ffs_name_dev(struct ffs_dev *dev, const char *name);
+ static void *ffs_acquire_dev(const char *dev_name);
+ static void ffs_release_dev(struct ffs_data *ffs_data);
+ static int ffs_ready(struct ffs_data *ffs);
+@@ -2261,7 +2263,7 @@ static struct ffs_dev *_ffs_find_dev(const char *name)
+               if (strcmp(dev->name, name) == 0)
+                       return dev;
+       }
+-      
++
+       return NULL;
+ }
+@@ -2295,6 +2297,31 @@ static struct ffs_dev *ffs_find_dev(const char *name)
+       return _ffs_find_dev(name);
+ }
++/* Configfs support *********************************************************/
++
++static inline struct f_fs_opts *to_ffs_opts(struct config_item *item)
++{
++      return container_of(to_config_group(item), struct f_fs_opts,
++                          func_inst.group);
++}
++
++static void ffs_attr_release(struct config_item *item)
++{
++      struct f_fs_opts *opts = to_ffs_opts(item);
++
++      usb_put_function_instance(&opts->func_inst);
++}
++
++static struct configfs_item_operations ffs_item_ops = {
++      .release        = ffs_attr_release,
++};
++
++static struct config_item_type ffs_func_type = {
++      .ct_item_ops    = &ffs_item_ops,
++      .ct_owner       = THIS_MODULE,
++};
++
++
+ /* Function registration interface ******************************************/
+ static void ffs_free_inst(struct usb_function_instance *f)
+@@ -2308,6 +2335,44 @@ static void ffs_free_inst(struct usb_function_instance *f)
+       kfree(opts);
+ }
++#define MAX_INST_NAME_LEN     40
++
++static int ffs_set_inst_name(struct usb_function_instance *fi, const char *name)
++{
++      struct f_fs_opts *opts;
++      char *ptr;
++      const char *tmp;
++      int name_len, ret;
++
++      name_len = strlen(name) + 1;
++      if (name_len > MAX_INST_NAME_LEN)
++              return -ENAMETOOLONG;
++
++      ptr = kstrndup(name, name_len, GFP_KERNEL);
++      if (!ptr)
++              return -ENOMEM;
++
++      opts = to_f_fs_opts(fi);
++      tmp = NULL;
++
++      ffs_dev_lock();
++
++      tmp = opts->dev->name_allocated ? opts->dev->name : NULL;
++      ret = _ffs_name_dev(opts->dev, ptr);
++      if (ret) {
++              kfree(ptr);
++              ffs_dev_unlock();
++              return ret;
++      }
++      opts->dev->name_allocated = true;
++
++      ffs_dev_unlock();
++
++      kfree(tmp);
++
++      return 0;
++}
++
+ static struct usb_function_instance *ffs_alloc_inst(void)
+ {
+       struct f_fs_opts *opts;
+@@ -2317,6 +2382,7 @@ static struct usb_function_instance *ffs_alloc_inst(void)
+       if (!opts)
+               return ERR_PTR(-ENOMEM);
++      opts->func_inst.set_inst_name = ffs_set_inst_name;
+       opts->func_inst.free_func_inst = ffs_free_inst;
+       ffs_dev_lock();
+       dev = ffs_alloc_dev();
+@@ -2326,7 +2392,10 @@ static struct usb_function_instance *ffs_alloc_inst(void)
+               return ERR_CAST(dev);
+       }
+       opts->dev = dev;
++      dev->opts = opts;
++      config_group_init_type_name(&opts->func_inst.group, "",
++                                  &ffs_func_type);
+       return &opts->func_inst;
+ }
+@@ -2484,6 +2553,8 @@ EXPORT_SYMBOL(ffs_single_dev);
+ void ffs_free_dev(struct ffs_dev *dev)
+ {
+       list_del(&dev->entry);
++      if (dev->name_allocated)
++              kfree(dev->name);
+       kfree(dev);
+       if (list_empty(&ffs_devices))
+               functionfs_cleanup();
+@@ -2572,6 +2643,13 @@ static void ffs_closed(struct ffs_data *ffs)
+       if (ffs_obj->ffs_closed_callback)
+               ffs_obj->ffs_closed_callback(ffs);
++
++      if (!ffs_obj->opts || ffs_obj->opts->no_configfs
++          || !ffs_obj->opts->func_inst.group.cg_item.ci_parent)
++              goto done;
++
++      unregister_gadget_item(ffs_obj->opts->
++                             func_inst.group.cg_item.ci_parent->ci_parent);
+ done:
+       ffs_dev_unlock();
+ }
+diff --git a/drivers/usb/gadget/u_fs.h b/drivers/usb/gadget/u_fs.h
+index 0931375..bc2d371 100644
+--- a/drivers/usb/gadget/u_fs.h
++++ b/drivers/usb/gadget/u_fs.h
+@@ -35,13 +35,16 @@
+ #define ENTER()    pr_vdebug("%s()\n", __func__)
++struct f_fs_opts;
+ struct ffs_dev {
+       const char *name;
++      bool name_allocated;
+       bool mounted;
+       bool desc_ready;
+       bool single;
+       struct ffs_data *ffs_data;
++      struct f_fs_opts *opts;
+       struct list_head entry;
+       int (*ffs_ready_callback)(struct ffs_data *ffs);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1176-usb-gadget-f_fs-fix-sparse-warning.patch b/patches.tizen/1176-usb-gadget-f_fs-fix-sparse-warning.patch
new file mode 100644 (file)
index 0000000..04fcec3
--- /dev/null
@@ -0,0 +1,29 @@
+From 720484732d047c4730760dce22287ed57ea47d6d Mon Sep 17 00:00:00 2001
+From: Felipe Balbi <balbi@ti.com>
+Date: Thu, 12 Dec 2013 12:15:43 -0600
+Subject: [PATCH 1176/1302] usb: gadget: f_fs: fix sparse warning
+
+use NULL when returning NULL pointers, not 0.
+
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_fs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
+index cb9330d..7ede285 100644
+--- a/drivers/usb/gadget/f_fs.c
++++ b/drivers/usb/gadget/f_fs.c
+@@ -1137,7 +1137,7 @@ static struct ffs_data *ffs_data_new(void)
+ {
+       struct ffs_data *ffs = kzalloc(sizeof *ffs, GFP_KERNEL);
+       if (unlikely(!ffs))
+-              return 0;
++              return NULL;
+       ENTER();
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1177-usb-gadget-nokia-fix-error-recovery-path-for-optiona.patch b/patches.tizen/1177-usb-gadget-nokia-fix-error-recovery-path-for-optiona.patch
new file mode 100644 (file)
index 0000000..04f17f9
--- /dev/null
@@ -0,0 +1,53 @@
+From a495523ccaace3cd1ac85ce1a3eb27e59c3b1478 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Fri, 13 Dec 2013 14:46:40 +0100
+Subject: [PATCH 1177/1302] usb: gadget: nokia: fix error recovery path for
+ optional functions
+
+In the nokia gadget some USB functions (obex 1 and 2, phonet) are optional.
+
+If at the start of nokia_bind_config e.g. fi_phonet is an error pointer,
+which can happen because we don't fail the bind process if
+usb_get_function_instance() fails for fi_phonet, then f_phonet is NULL, and
+
+phonet_stat = usb_add_function(c, f_phonet);
+
+is never called and phonet_stat remains 0.
+
+If, in these circumstances, we hit the err_conf label then !phonet_stat
+evaluates to true and we try usb_remove_function() with its second
+parameter being f_phonet which is NULL and it causes NULL pointer
+dereference.
+
+This patch changes the initial values of (obex1|obex2|phonet)_stat to a
+nonzero value so that if the err_conf label is hit while the respective
+functions have not been acquired the usb_remove_function() is not called
+for those functions.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/nokia.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c
+index 0a8099a..3ab3861 100644
+--- a/drivers/usb/gadget/nokia.c
++++ b/drivers/usb/gadget/nokia.c
+@@ -126,9 +126,9 @@ static int __init nokia_bind_config(struct usb_configuration *c)
+       struct usb_function *f_ecm;
+       struct usb_function *f_obex2 = NULL;
+       int status = 0;
+-      int obex1_stat = 0;
+-      int obex2_stat = 0;
+-      int phonet_stat = 0;
++      int obex1_stat = -1;
++      int obex2_stat = -1;
++      int phonet_stat = -1;
+       if (!IS_ERR(fi_phonet)) {
+               f_phonet = usb_get_function(fi_phonet);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1178-usb-gadget-f_loopback-Fix-sparse-warning.patch b/patches.tizen/1178-usb-gadget-f_loopback-Fix-sparse-warning.patch
new file mode 100644 (file)
index 0000000..1763d8f
--- /dev/null
@@ -0,0 +1,43 @@
+From c638c305b24f7824ac3f1aed3644e97f9c57c2f0 Mon Sep 17 00:00:00 2001
+From: Jingoo Han <jg1.han@samsung.com>
+Date: Mon, 16 Dec 2013 18:40:49 +0900
+Subject: [PATCH 1178/1302] usb: gadget: f_loopback: Fix sparse warning
+
+Make local symbols static in order to fix the following sparse
+warnings.
+
+drivers/usb/gadget/f_loopback.c:123:34: warning: symbol 'ss_loop_source_comp_desc' was not declared. Should it be static?
+drivers/usb/gadget/f_loopback.c:139:34: warning: symbol 'ss_loop_sink_comp_desc' was not declared. Should it be static?
+
+Signed-off-by: Jingoo Han <jg1.han@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_loopback.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c
+index c35bb40..4557cd0 100644
+--- a/drivers/usb/gadget/f_loopback.c
++++ b/drivers/usb/gadget/f_loopback.c
+@@ -120,7 +120,7 @@ static struct usb_endpoint_descriptor ss_loop_source_desc = {
+       .wMaxPacketSize =       cpu_to_le16(1024),
+ };
+-struct usb_ss_ep_comp_descriptor ss_loop_source_comp_desc = {
++static struct usb_ss_ep_comp_descriptor ss_loop_source_comp_desc = {
+       .bLength =              USB_DT_SS_EP_COMP_SIZE,
+       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
+       .bMaxBurst =            0,
+@@ -136,7 +136,7 @@ static struct usb_endpoint_descriptor ss_loop_sink_desc = {
+       .wMaxPacketSize =       cpu_to_le16(1024),
+ };
+-struct usb_ss_ep_comp_descriptor ss_loop_sink_comp_desc = {
++static struct usb_ss_ep_comp_descriptor ss_loop_sink_comp_desc = {
+       .bLength =              USB_DT_SS_EP_COMP_SIZE,
+       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
+       .bMaxBurst =            0,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1179-usb-gadget-f_mass_storage-Fix-sparse-warning.patch b/patches.tizen/1179-usb-gadget-f_mass_storage-Fix-sparse-warning.patch
new file mode 100644 (file)
index 0000000..d5cca6c
--- /dev/null
@@ -0,0 +1,34 @@
+From 57e7fc14e6fe5cc0b689f9df768e1322e30c6def Mon Sep 17 00:00:00 2001
+From: Jingoo Han <jg1.han@samsung.com>
+Date: Mon, 16 Dec 2013 18:42:48 +0900
+Subject: [PATCH 1179/1302] usb: gadget: f_mass_storage: Fix sparse warning
+
+Use NULL instead of 0 when returning pointer, to fix the following
+sparse warnings.
+
+drivers/usb/gadget/f_mass_storage.c:3114:60: warning: Using plain integer as NULL pointer
+drivers/usb/gadget/f_mass_storage.c:3114:63: warning: Using plain integer as NULL pointer
+
+Signed-off-by: Jingoo Han <jg1.han@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index a03ba2c..1dfecdf 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -3111,7 +3111,7 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
+                                         fsg->common->can_stall);
+               if (ret)
+                       return ret;
+-              fsg_common_set_inquiry_string(fsg->common, 0, 0);
++              fsg_common_set_inquiry_string(fsg->common, NULL, NULL);
+               ret = fsg_common_run_thread(fsg->common);
+               if (ret)
+                       return ret;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1180-usb-gadget-f_ncm-Fix-sparse-warning.patch b/patches.tizen/1180-usb-gadget-f_ncm-Fix-sparse-warning.patch
new file mode 100644 (file)
index 0000000..e497a85
--- /dev/null
@@ -0,0 +1,33 @@
+From afa5763b6c6d0c242856586ac499c34bad1550da Mon Sep 17 00:00:00 2001
+From: Jingoo Han <jg1.han@samsung.com>
+Date: Mon, 16 Dec 2013 18:43:32 +0900
+Subject: [PATCH 1180/1302] usb: gadget: f_ncm: Fix sparse warning
+
+Make local symbol static in order to fix the following sparse
+warning.
+
+drivers/usb/gadget/f_ncm.c:1389:21: warning: symbol 'ncm_alloc' was not declared. Should it be static?
+
+Signed-off-by: Jingoo Han <jg1.han@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_ncm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c
+index 1c28fe1..a9499fd 100644
+--- a/drivers/usb/gadget/f_ncm.c
++++ b/drivers/usb/gadget/f_ncm.c
+@@ -1386,7 +1386,7 @@ static void ncm_unbind(struct usb_configuration *c, struct usb_function *f)
+       usb_ep_free_request(ncm->notify, ncm->notify_req);
+ }
+-struct usb_function *ncm_alloc(struct usb_function_instance *fi)
++static struct usb_function *ncm_alloc(struct usb_function_instance *fi)
+ {
+       struct f_ncm            *ncm;
+       struct f_ncm_opts       *opts;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1181-usb-gadget-f_obex-Fix-sparse-warning.patch b/patches.tizen/1181-usb-gadget-f_obex-Fix-sparse-warning.patch
new file mode 100644 (file)
index 0000000..f0cdebb
--- /dev/null
@@ -0,0 +1,33 @@
+From 658b307f2588487671d64d534a5f0ce83a8e8ecb Mon Sep 17 00:00:00 2001
+From: Jingoo Han <jg1.han@samsung.com>
+Date: Mon, 16 Dec 2013 18:43:50 +0900
+Subject: [PATCH 1181/1302] usb: gadget: f_obex: Fix sparse warning
+
+Make local symbol static in order to fix the following sparse
+warning.
+
+drivers/usb/gadget/f_obex.c:502:21: warning: symbol 'obex_alloc' was not declared. Should it be static?
+
+Signed-off-by: Jingoo Han <jg1.han@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_obex.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c
+index ad39f1d..aebae18 100644
+--- a/drivers/usb/gadget/f_obex.c
++++ b/drivers/usb/gadget/f_obex.c
+@@ -499,7 +499,7 @@ static void obex_unbind(struct usb_configuration *c, struct usb_function *f)
+       usb_free_all_descriptors(f);
+ }
+-struct usb_function *obex_alloc(struct usb_function_instance *fi)
++static struct usb_function *obex_alloc(struct usb_function_instance *fi)
+ {
+       struct f_obex   *obex;
+       struct f_serial_opts *opts;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1182-usb-gadget-f_phonet-Fix-sparse-warning.patch b/patches.tizen/1182-usb-gadget-f_phonet-Fix-sparse-warning.patch
new file mode 100644 (file)
index 0000000..0cae399
--- /dev/null
@@ -0,0 +1,33 @@
+From e7292d364333ade288c57e60c6db9b5a267c5889 Mon Sep 17 00:00:00 2001
+From: Jingoo Han <jg1.han@samsung.com>
+Date: Mon, 16 Dec 2013 18:44:07 +0900
+Subject: [PATCH 1182/1302] usb: gadget: f_phonet: Fix sparse warning
+
+Make local symbol static in order to fix the following sparse
+warning.
+
+drivers/usb/gadget/f_phonet.c:692:21: warning: symbol 'phonet_alloc' was not declared. Should it be static?
+
+Signed-off-by: Jingoo Han <jg1.han@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_phonet.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c
+index eb3aa81..f2b7817 100644
+--- a/drivers/usb/gadget/f_phonet.c
++++ b/drivers/usb/gadget/f_phonet.c
+@@ -689,7 +689,7 @@ static void pn_unbind(struct usb_configuration *c, struct usb_function *f)
+       usb_free_all_descriptors(f);
+ }
+-struct usb_function *phonet_alloc(struct usb_function_instance *fi)
++static struct usb_function *phonet_alloc(struct usb_function_instance *fi)
+ {
+       struct f_phonet *fp;
+       struct f_phonet_opts *opts;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1183-usb-gadget-f_serial-Fix-sparse-warning.patch b/patches.tizen/1183-usb-gadget-f_serial-Fix-sparse-warning.patch
new file mode 100644 (file)
index 0000000..4ab8b63
--- /dev/null
@@ -0,0 +1,33 @@
+From 043f16d01229402cf8c74c1ea2836b9b8ce2acda Mon Sep 17 00:00:00 2001
+From: Jingoo Han <jg1.han@samsung.com>
+Date: Mon, 16 Dec 2013 18:44:25 +0900
+Subject: [PATCH 1183/1302] usb: gadget: f_serial: Fix sparse warning
+
+Make local symbol static in order to fix the following sparse
+warning.
+
+drivers/usb/gadget/f_serial.c:357:21: warning: symbol 'gser_alloc' was not declared. Should it be static?
+
+Signed-off-by: Jingoo Han <jg1.han@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_serial.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c
+index 981113c..9ecbcbf 100644
+--- a/drivers/usb/gadget/f_serial.c
++++ b/drivers/usb/gadget/f_serial.c
+@@ -354,7 +354,7 @@ static void gser_unbind(struct usb_configuration *c, struct usb_function *f)
+       usb_free_all_descriptors(f);
+ }
+-struct usb_function *gser_alloc(struct usb_function_instance *fi)
++static struct usb_function *gser_alloc(struct usb_function_instance *fi)
+ {
+       struct f_gser   *gser;
+       struct f_serial_opts *opts;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1184-usb-gadget-f_sourcesink-Fix-sparse-warning.patch b/patches.tizen/1184-usb-gadget-f_sourcesink-Fix-sparse-warning.patch
new file mode 100644 (file)
index 0000000..8cb5ba3
--- /dev/null
@@ -0,0 +1,63 @@
+From 1c970dee7446774a8c2603a97d5704819e539990 Mon Sep 17 00:00:00 2001
+From: Jingoo Han <jg1.han@samsung.com>
+Date: Mon, 16 Dec 2013 18:44:43 +0900
+Subject: [PATCH 1184/1302] usb: gadget: f_sourcesink: Fix sparse warning
+
+Make local symbols static in order to fix the following sparse
+warnings.
+
+drivers/usb/gadget/f_sourcesink.c:205:34: warning: symbol 'ss_source_comp_desc' was not declared. Should it be static?
+drivers/usb/gadget/f_sourcesink.c:222:34: warning: symbol 'ss_sink_comp_desc' was not declared. Should it be static?
+drivers/usb/gadget/f_sourcesink.c:240:34: warning: symbol 'ss_iso_source_comp_desc' was not declared. Should it be static?
+drivers/usb/gadget/f_sourcesink.c:258:34: warning: symbol 'ss_iso_sink_comp_desc' was not declared. Should it be static?
+
+Signed-off-by: Jingoo Han <jg1.han@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_sourcesink.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c
+index 5d4251e..d3cd52d 100644
+--- a/drivers/usb/gadget/f_sourcesink.c
++++ b/drivers/usb/gadget/f_sourcesink.c
+@@ -202,7 +202,7 @@ static struct usb_endpoint_descriptor ss_source_desc = {
+       .wMaxPacketSize =       cpu_to_le16(1024),
+ };
+-struct usb_ss_ep_comp_descriptor ss_source_comp_desc = {
++static struct usb_ss_ep_comp_descriptor ss_source_comp_desc = {
+       .bLength =              USB_DT_SS_EP_COMP_SIZE,
+       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
+@@ -219,7 +219,7 @@ static struct usb_endpoint_descriptor ss_sink_desc = {
+       .wMaxPacketSize =       cpu_to_le16(1024),
+ };
+-struct usb_ss_ep_comp_descriptor ss_sink_comp_desc = {
++static struct usb_ss_ep_comp_descriptor ss_sink_comp_desc = {
+       .bLength =              USB_DT_SS_EP_COMP_SIZE,
+       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
+@@ -237,7 +237,7 @@ static struct usb_endpoint_descriptor ss_iso_source_desc = {
+       .bInterval =            4,
+ };
+-struct usb_ss_ep_comp_descriptor ss_iso_source_comp_desc = {
++static struct usb_ss_ep_comp_descriptor ss_iso_source_comp_desc = {
+       .bLength =              USB_DT_SS_EP_COMP_SIZE,
+       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
+@@ -255,7 +255,7 @@ static struct usb_endpoint_descriptor ss_iso_sink_desc = {
+       .bInterval =            4,
+ };
+-struct usb_ss_ep_comp_descriptor ss_iso_sink_comp_desc = {
++static struct usb_ss_ep_comp_descriptor ss_iso_sink_comp_desc = {
+       .bLength =              USB_DT_SS_EP_COMP_SIZE,
+       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1185-usb-gadget-composite-reset-delayed_status-on-reset_c.patch b/patches.tizen/1185-usb-gadget-composite-reset-delayed_status-on-reset_c.patch
new file mode 100644 (file)
index 0000000..d8924f4
--- /dev/null
@@ -0,0 +1,34 @@
+From 70edd181d55a4d91c43af22282f4ac881a46f960 Mon Sep 17 00:00:00 2001
+From: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Date: Mon, 11 Nov 2013 23:43:32 +0100
+Subject: [PATCH 1185/1302] usb: gadget: composite: reset delayed_status on
+ reset_config
+
+The delayed_status value is used to keep track of status response
+packets on ep0. It needs to be reset or the set_config function would
+still delay the answer, if the usb device got unplugged while waiting
+for setup_continue to be called.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/composite.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
+index 6c0d25d..03abdb5 100644
+--- a/drivers/usb/gadget/composite.c
++++ b/drivers/usb/gadget/composite.c
+@@ -593,6 +593,7 @@ static void reset_config(struct usb_composite_dev *cdev)
+               bitmap_zero(f->endpoints, 32);
+       }
+       cdev->config = NULL;
++      cdev->delayed_status = 0;
+ }
+ static int set_config(struct usb_composite_dev *cdev,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1186-usb-gadget-f_mass_storage-fix-mass-storage-dependenc.patch b/patches.tizen/1186-usb-gadget-f_mass_storage-fix-mass-storage-dependenc.patch
new file mode 100644 (file)
index 0000000..a274803
--- /dev/null
@@ -0,0 +1,35 @@
+From 54989ea0736973221ce9055d2c63c23887eef12b Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Mon, 4 Nov 2013 13:46:17 +0100
+Subject: [PATCH 1186/1302] usb: gadget: f_mass_storage: fix mass storage
+ dependency
+
+Legacy gadgets supporting mass storage (g_mass_storage, g_acm_ms, g_multi)
+all depend on BLOCK.
+
+Make the standalone compilation of f_mass_storage (without any legacy
+gadget) dependent no BLOCK, too.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index c864c884..085b11e 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -679,6 +679,7 @@ config USB_CONFIGFS_PHONET
+ config USB_CONFIGFS_MASS_STORAGE
+       boolean "Mass storage"
+       depends on USB_CONFIGFS
++      depends on BLOCK
+       select USB_F_MASS_STORAGE
+       help
+         The Mass Storage Gadget acts as a USB Mass Storage disk drive.
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1187-usb-gadget-mass-storage-fix-return-of-delayed-status.patch b/patches.tizen/1187-usb-gadget-mass-storage-fix-return-of-delayed-status.patch
new file mode 100644 (file)
index 0000000..0b17c11
--- /dev/null
@@ -0,0 +1,56 @@
+From 86b9ba81c0853eea326b5ca8e61c87b332cfe781 Mon Sep 17 00:00:00 2001
+From: Pratyush Anand <pratyush.anand@st.com>
+Date: Mon, 4 Nov 2013 22:13:54 +0530
+Subject: [PATCH 1187/1302] usb: gadget: mass storage: fix return of delayed
+ status
+
+Mass storage gadget returns DELAYED_STATUS in stead of
+USB_GADGET_DELAYED_STATUS while handling bulk reset request. Since
+peripheral driver uses USB_GADGET_DELAYED_STATUS for delayed status
+handling, therefore replace DELAYED_STATUS by USB_GADGET_DELAYED_STATUS
+in mass storage driver.
+
+Since, DELAYED_STATUS and hence EP0_BUFSIZE will no longer be used now,
+so remove them.
+
+Signed-off-by: Pratyush Anand <pratyush.anand@st.com>
+Cc: Paul Zimmerman <Paul.Zimmerman@synopsys.com>
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 2 +-
+ drivers/usb/gadget/storage_common.h | 4 ----
+ 2 files changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 1dfecdf..1b2c19b 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -523,7 +523,7 @@ static int fsg_setup(struct usb_function *f,
+                */
+               DBG(fsg, "bulk reset request\n");
+               raise_exception(fsg->common, FSG_STATE_RESET);
+-              return DELAYED_STATUS;
++              return USB_GADGET_DELAYED_STATUS;
+       case US_BULK_GET_MAX_LUN:
+               if (ctrl->bRequestType !=
+diff --git a/drivers/usb/gadget/storage_common.h b/drivers/usb/gadget/storage_common.h
+index c74c2fd..70c8914 100644
+--- a/drivers/usb/gadget/storage_common.h
++++ b/drivers/usb/gadget/storage_common.h
+@@ -119,10 +119,6 @@ static inline bool fsg_lun_is_open(struct fsg_lun *curlun)
+       return curlun->filp != NULL;
+ }
+-/* Big enough to hold our biggest descriptor */
+-#define EP0_BUFSIZE   256
+-#define DELAYED_STATUS        (EP0_BUFSIZE + 999)     /* An impossibly large value */
+-
+ /* Default size of buffer length. */
+ #define FSG_BUFLEN    ((u32)16384)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1188-usb-gadget-zero-module-parameters-can-be-static.patch b/patches.tizen/1188-usb-gadget-zero-module-parameters-can-be-static.patch
new file mode 100644 (file)
index 0000000..fa753d8
--- /dev/null
@@ -0,0 +1,44 @@
+From 3df9d32c6a24f4c47e1afaeda9b831c93f132f45 Mon Sep 17 00:00:00 2001
+From: Fengguang Wu <fengguang.wu@intel.com>
+Date: Mon, 25 Nov 2013 11:10:59 -0600
+Subject: [PATCH 1188/1302] usb: gadget: zero: module parameters can be static
+
+g_zero's module parameters can, and should, be
+static. This fixes sparse warnings.
+
+Cc: Peter Chen <peter.chen@freescale.com>
+Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/zero.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
+index 00b4019..9f170c5 100644
+--- a/drivers/usb/gadget/zero.c
++++ b/drivers/usb/gadget/zero.c
+@@ -91,17 +91,17 @@ static struct usb_zero_options gzero_options = {
+  * functional coverage for the "USBCV" test harness from USB-IF.
+  * It's always set if OTG mode is enabled.
+  */
+-unsigned autoresume = DEFAULT_AUTORESUME;
++static unsigned autoresume = DEFAULT_AUTORESUME;
+ module_param(autoresume, uint, S_IRUGO);
+ MODULE_PARM_DESC(autoresume, "zero, or seconds before remote wakeup");
+ /* Maximum Autoresume time */
+-unsigned max_autoresume;
++static unsigned max_autoresume;
+ module_param(max_autoresume, uint, S_IRUGO);
+ MODULE_PARM_DESC(max_autoresume, "maximum seconds before remote wakeup");
+ /* Interval between two remote wakeups */
+-unsigned autoresume_interval_ms;
++static unsigned autoresume_interval_ms;
+ module_param(autoresume_interval_ms, uint, S_IRUGO);
+ MODULE_PARM_DESC(autoresume_interval_ms,
+               "milliseconds to increase successive wakeup delays");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1189-usb-gadget-f_mass_storage-call-try_to_freeze-only-wh.patch b/patches.tizen/1189-usb-gadget-f_mass_storage-call-try_to_freeze-only-wh.patch
new file mode 100644 (file)
index 0000000..d4ab35e
--- /dev/null
@@ -0,0 +1,129 @@
+From 58f9a09b26a9988f09cdc1222fe9cf1bba9a1aa8 Mon Sep 17 00:00:00 2001
+From: George Cherian <george.cherian@ti.com>
+Date: Fri, 8 Nov 2013 10:50:52 +0530
+Subject: [PATCH 1189/1302] usb: gadget: f_mass_storage: call try_to_freeze
+ only when its safe
+
+Call try_to_freeze() in sleep_thread() only when it's safe to sleep.
+do_read() and do_write() calls sleep_thread with lock held.
+Make sure these won't call try_to_freeze() by passing can_freeze flag
+to sleep_thread.
+
+Calling try_to_freeze() with a lock hold was done since day one in
+f_mass_storage but since commit 0f9548ca1 ("lockdep: check that no
+locks held at freeze time") lockdep complains about it.
+
+Signed-off-by: George Cherian <george.cherian@ti.com>
+Acked-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_mass_storage.c | 23 ++++++++++++-----------
+ 1 file changed, 12 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
+index 1b2c19b..b963939 100644
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -602,13 +602,14 @@ static bool start_out_transfer(struct fsg_common *common, struct fsg_buffhd *bh)
+       return true;
+ }
+-static int sleep_thread(struct fsg_common *common)
++static int sleep_thread(struct fsg_common *common, bool can_freeze)
+ {
+       int     rc = 0;
+       /* Wait until a signal arrives or we are woken up */
+       for (;;) {
+-              try_to_freeze();
++              if (can_freeze)
++                      try_to_freeze();
+               set_current_state(TASK_INTERRUPTIBLE);
+               if (signal_pending(current)) {
+                       rc = -EINTR;
+@@ -682,7 +683,7 @@ static int do_read(struct fsg_common *common)
+               /* Wait for the next buffer to become available */
+               bh = common->next_buffhd_to_fill;
+               while (bh->state != BUF_STATE_EMPTY) {
+-                      rc = sleep_thread(common);
++                      rc = sleep_thread(common, false);
+                       if (rc)
+                               return rc;
+               }
+@@ -937,7 +938,7 @@ static int do_write(struct fsg_common *common)
+               }
+               /* Wait for something to happen */
+-              rc = sleep_thread(common);
++              rc = sleep_thread(common, false);
+               if (rc)
+                       return rc;
+       }
+@@ -1504,7 +1505,7 @@ static int throw_away_data(struct fsg_common *common)
+               }
+               /* Otherwise wait for something to happen */
+-              rc = sleep_thread(common);
++              rc = sleep_thread(common, true);
+               if (rc)
+                       return rc;
+       }
+@@ -1625,7 +1626,7 @@ static int send_status(struct fsg_common *common)
+       /* Wait for the next buffer to become available */
+       bh = common->next_buffhd_to_fill;
+       while (bh->state != BUF_STATE_EMPTY) {
+-              rc = sleep_thread(common);
++              rc = sleep_thread(common, true);
+               if (rc)
+                       return rc;
+       }
+@@ -1828,7 +1829,7 @@ static int do_scsi_command(struct fsg_common *common)
+       bh = common->next_buffhd_to_fill;
+       common->next_buffhd_to_drain = bh;
+       while (bh->state != BUF_STATE_EMPTY) {
+-              rc = sleep_thread(common);
++              rc = sleep_thread(common, true);
+               if (rc)
+                       return rc;
+       }
+@@ -2174,7 +2175,7 @@ static int get_next_command(struct fsg_common *common)
+       /* Wait for the next buffer to become available */
+       bh = common->next_buffhd_to_fill;
+       while (bh->state != BUF_STATE_EMPTY) {
+-              rc = sleep_thread(common);
++              rc = sleep_thread(common, true);
+               if (rc)
+                       return rc;
+       }
+@@ -2193,7 +2194,7 @@ static int get_next_command(struct fsg_common *common)
+       /* Wait for the CBW to arrive */
+       while (bh->state != BUF_STATE_FULL) {
+-              rc = sleep_thread(common);
++              rc = sleep_thread(common, true);
+               if (rc)
+                       return rc;
+       }
+@@ -2379,7 +2380,7 @@ static void handle_exception(struct fsg_common *common)
+                       }
+                       if (num_active == 0)
+                               break;
+-                      if (sleep_thread(common))
++                      if (sleep_thread(common, true))
+                               return;
+               }
+@@ -2516,7 +2517,7 @@ static int fsg_main_thread(void *common_)
+               }
+               if (!common->running) {
+-                      sleep_thread(common);
++                      sleep_thread(common, true);
+                       continue;
+               }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1190-usb-gadget-configfs-include-appropriate-header-file-.patch b/patches.tizen/1190-usb-gadget-configfs-include-appropriate-header-file-.patch
new file mode 100644 (file)
index 0000000..750123a
--- /dev/null
@@ -0,0 +1,39 @@
+From a81af38ead3c4e9606be6980448d14d63ddcfda3 Mon Sep 17 00:00:00 2001
+From: Rashika Kheria <rashika.kheria@gmail.com>
+Date: Thu, 19 Dec 2013 15:37:37 +0530
+Subject: [PATCH 1190/1302] usb: gadget: configfs: include appropriate header
+ file in configfs.c
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Include appropriate header file drivers/usb/gadget/configfs.h in
+gadget/configfs.c because function unregister_gadget_item() has its
+prototype declaration in gadget/configfs.h.
+
+This eliminates the following warning in gadget/configfs.c:
+drivers/usb/gadget/configfs.c:994:6: warning: no previous prototype for ‘unregister_gadget_item’ [-Wmissing-prototypes]
+
+Signed-off-by: Rashika Kheria <rashika.kheria@gmail.com>
+Reviewed-by: Josh Triplett <josh@joshtriplett.org>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/configfs.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
+index d6c8ab4..7d1cc01 100644
+--- a/drivers/usb/gadget/configfs.c
++++ b/drivers/usb/gadget/configfs.c
+@@ -4,6 +4,7 @@
+ #include <linux/device.h>
+ #include <linux/usb/composite.h>
+ #include <linux/usb/gadget_configfs.h>
++#include "configfs.h"
+ int check_user_usb_string(const char *name,
+               struct usb_gadget_strings *stringtab_dev)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1191-usb-gadget-should-use-u16-type-variable-to-store-Max.patch b/patches.tizen/1191-usb-gadget-should-use-u16-type-variable-to-store-Max.patch
new file mode 100644 (file)
index 0000000..7c3087b
--- /dev/null
@@ -0,0 +1,37 @@
+From 610826db72ad617fae74d1efa13b45b9408dd1c5 Mon Sep 17 00:00:00 2001
+From: "Du, ChangbinX" <changbinx.du@intel.com>
+Date: Tue, 17 Dec 2013 11:47:42 +0000
+Subject: [PATCH 1191/1302] usb: gadget: should use u16 type variable to store
+ MaxPower
+
+From 7e827a0d300e084f74c65122baa5e3193f9a7f18 Mon Sep 17 00:00:00 2001
+From: "Du, Changbin" <changbinx.du@intel.com>
+Date: Mon, 16 Dec 2013 20:32:13 +0800
+Subject: [PATCH] usb/gadget: should use u16 type variable to store MaxPower
+
+The MaxPower field is of u16 type. So using u8 type variable can break
+data (high byte lost).
+
+Signed-off-by: Du, Changbin <changbinx.du@intel.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/composite.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
+index 03abdb5..d41103e 100644
+--- a/drivers/usb/gadget/composite.c
++++ b/drivers/usb/gadget/composite.c
+@@ -1728,7 +1728,7 @@ composite_resume(struct usb_gadget *gadget)
+ {
+       struct usb_composite_dev        *cdev = get_gadget_data(gadget);
+       struct usb_function             *f;
+-      u8                              maxpower;
++      u16                             maxpower;
+       /* REVISIT:  should we have config level
+        * suspend/resume callbacks?
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1192-usb-gadget-fix-up-some-comments-about-CONFIG_USB_DEB.patch b/patches.tizen/1192-usb-gadget-fix-up-some-comments-about-CONFIG_USB_DEB.patch
new file mode 100644 (file)
index 0000000..1defc41
--- /dev/null
@@ -0,0 +1,47 @@
+From 58d8fd5ef33d6863c63f6d96ebb2bda1840f7e20 Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Thu, 19 Dec 2013 15:43:10 -0800
+Subject: [PATCH 1192/1302] usb: gadget: fix up some comments about
+ CONFIG_USB_DEBUG
+
+These two gadget drivers said that their #endif was for
+CONFIG_USB_DEBUG, but they really were not, so fix them up to be
+correct.
+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/acm_ms.c | 2 +-
+ drivers/usb/gadget/multi.c  | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c
+index 7bfa134..a252444 100644
+--- a/drivers/usb/gadget/acm_ms.c
++++ b/drivers/usb/gadget/acm_ms.c
+@@ -107,7 +107,7 @@ static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
+  */
+ #define fsg_num_buffers       CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
+-#endif /* CONFIG_USB_DEBUG */
++#endif /* CONFIG_USB_GADGET_DEBUG_FILES */
+ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
+diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
+index 4fdaa54..940f6cd 100644
+--- a/drivers/usb/gadget/multi.c
++++ b/drivers/usb/gadget/multi.c
+@@ -134,7 +134,7 @@ static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
+  */
+ #define fsg_num_buffers       CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
+-#endif /* CONFIG_USB_DEBUG */
++#endif /* CONFIG_USB_GADGET_DEBUG_FILES */
+ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1193-usb-gadget-FunctionFS-dereference-ffs_dev-conditiona.patch b/patches.tizen/1193-usb-gadget-FunctionFS-dereference-ffs_dev-conditiona.patch
new file mode 100644 (file)
index 0000000..45c20a1
--- /dev/null
@@ -0,0 +1,39 @@
+From cdc9149d44f2a0e1200c0ad08c63732751edd569 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Mon, 13 Jan 2014 16:41:22 +0100
+Subject: [PATCH 1193/1302] usb: gadget: FunctionFS: dereference ffs_dev
+ conditionally
+
+ffs_dev->ffs_release_dev_callback should be accessed only if ffs_dev
+is not NULL.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_fs.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
+index 7ede285..52fd0c1 100644
+--- a/drivers/usb/gadget/f_fs.c
++++ b/drivers/usb/gadget/f_fs.c
+@@ -2590,11 +2590,12 @@ static void ffs_release_dev(struct ffs_data *ffs_data)
+       ffs_dev_lock();
+       ffs_dev = ffs_data->private_data;
+-      if (ffs_dev)
++      if (ffs_dev) {
+               ffs_dev->mounted = false;
+-      
+-      if (ffs_dev->ffs_release_dev_callback)
+-              ffs_dev->ffs_release_dev_callback(ffs_dev);
++
++              if (ffs_dev->ffs_release_dev_callback)
++                      ffs_dev->ffs_release_dev_callback(ffs_dev);
++      }
+       ffs_dev_unlock();
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1194-usb-gadget-code-cleanup.patch b/patches.tizen/1194-usb-gadget-code-cleanup.patch
new file mode 100644 (file)
index 0000000..89eb166
--- /dev/null
@@ -0,0 +1,29 @@
+From 6b97c82c039d36dd3131eaefa159c557f071a5c0 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Mon, 13 Jan 2014 16:42:02 +0100
+Subject: [PATCH 1194/1302] usb: gadget: code cleanup
+
+Remove trailing whitespace
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_fs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
+index 52fd0c1..075250a 100644
+--- a/drivers/usb/gadget/f_fs.c
++++ b/drivers/usb/gadget/f_fs.c
+@@ -2509,7 +2509,7 @@ static int _ffs_name_dev(struct ffs_dev *dev, const char *name)
+       existing = _ffs_find_dev(name);
+       if (existing)
+               return -EBUSY;
+-      
++
+       dev->name = name;
+       return 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1195-usb-gadget-FunctionFS-staticize-functions-used-only-.patch b/patches.tizen/1195-usb-gadget-FunctionFS-staticize-functions-used-only-.patch
new file mode 100644 (file)
index 0000000..88a4efc
--- /dev/null
@@ -0,0 +1,66 @@
+From e5dfa4d6c704b03e639d074eb4ce56c744e75310 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Mon, 13 Jan 2014 13:20:25 +0100
+Subject: [PATCH 1195/1302] usb: gadget: FunctionFS: staticize functions used
+ only in f_fs.c
+
+ffs_alloc_dev and ffs_free_dev are used only in f_fs.c,
+so make them static.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_fs.c | 6 ++++--
+ drivers/usb/gadget/u_fs.h | 2 --
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
+index 075250a..30fcc75 100644
+--- a/drivers/usb/gadget/f_fs.c
++++ b/drivers/usb/gadget/f_fs.c
+@@ -162,7 +162,9 @@ DEFINE_MUTEX(ffs_lock);
+ EXPORT_SYMBOL(ffs_lock);
+ static struct ffs_dev *ffs_find_dev(const char *name);
++static struct ffs_dev *ffs_alloc_dev(void);
+ static int _ffs_name_dev(struct ffs_dev *dev, const char *name);
++static void ffs_free_dev(struct ffs_dev *dev);
+ static void *ffs_acquire_dev(const char *dev_name);
+ static void ffs_release_dev(struct ffs_data *ffs_data);
+ static int ffs_ready(struct ffs_data *ffs);
+@@ -2473,7 +2475,7 @@ static struct usb_function *ffs_alloc(struct usb_function_instance *fi)
+ /*
+  * ffs_lock must be taken by the caller of this function
+  */
+-struct ffs_dev *ffs_alloc_dev(void)
++static struct ffs_dev *ffs_alloc_dev(void)
+ {
+       struct ffs_dev *dev;
+       int ret;
+@@ -2550,7 +2552,7 @@ EXPORT_SYMBOL(ffs_single_dev);
+ /*
+  * ffs_lock must be taken by the caller of this function
+  */
+-void ffs_free_dev(struct ffs_dev *dev)
++static void ffs_free_dev(struct ffs_dev *dev)
+ {
+       list_del(&dev->entry);
+       if (dev->name_allocated)
+diff --git a/drivers/usb/gadget/u_fs.h b/drivers/usb/gadget/u_fs.h
+index bc2d371..f418c25 100644
+--- a/drivers/usb/gadget/u_fs.h
++++ b/drivers/usb/gadget/u_fs.h
+@@ -65,10 +65,8 @@ static inline void ffs_dev_unlock(void)
+       mutex_unlock(&ffs_lock);
+ }
+-struct ffs_dev *ffs_alloc_dev(void);
+ int ffs_name_dev(struct ffs_dev *dev, const char *name);
+ int ffs_single_dev(struct ffs_dev *dev);
+-void ffs_free_dev(struct ffs_dev *dev);
+ struct ffs_epfile;
+ struct ffs_function;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1196-usb-gadget-FunctionFS-use-consistent-naming-with-reg.patch b/patches.tizen/1196-usb-gadget-FunctionFS-use-consistent-naming-with-reg.patch
new file mode 100644 (file)
index 0000000..3c69e54
--- /dev/null
@@ -0,0 +1,133 @@
+From 3c4774b51a16c8ed10abcf9e122deee3eaacc87c Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Mon, 13 Jan 2014 13:48:05 +0100
+Subject: [PATCH 1196/1302] usb: gadget: FunctionFS: use consistent naming with
+ regard to ffs_lock
+
+Consistently prefix function name with underscore if the function has to
+be called with ffs_lock taken.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_fs.c | 30 +++++++++++++++---------------
+ 1 file changed, 15 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
+index 30fcc75..b28d62f 100644
+--- a/drivers/usb/gadget/f_fs.c
++++ b/drivers/usb/gadget/f_fs.c
+@@ -161,10 +161,10 @@ ffs_sb_create_file(struct super_block *sb, const char *name, void *data,
+ DEFINE_MUTEX(ffs_lock);
+ EXPORT_SYMBOL(ffs_lock);
+-static struct ffs_dev *ffs_find_dev(const char *name);
+-static struct ffs_dev *ffs_alloc_dev(void);
++static struct ffs_dev *_ffs_find_dev(const char *name);
++static struct ffs_dev *_ffs_alloc_dev(void);
+ static int _ffs_name_dev(struct ffs_dev *dev, const char *name);
+-static void ffs_free_dev(struct ffs_dev *dev);
++static void _ffs_free_dev(struct ffs_dev *dev);
+ static void *ffs_acquire_dev(const char *dev_name);
+ static void ffs_release_dev(struct ffs_data *ffs_data);
+ static int ffs_ready(struct ffs_data *ffs);
+@@ -2255,7 +2255,7 @@ static int ffs_func_revmap_intf(struct ffs_function *func, u8 intf)
+ static LIST_HEAD(ffs_devices);
+-static struct ffs_dev *_ffs_find_dev(const char *name)
++static struct ffs_dev *_ffs_do_find_dev(const char *name)
+ {
+       struct ffs_dev *dev;
+@@ -2272,7 +2272,7 @@ static struct ffs_dev *_ffs_find_dev(const char *name)
+ /*
+  * ffs_lock must be taken by the caller of this function
+  */
+-static struct ffs_dev *ffs_get_single_dev(void)
++static struct ffs_dev *_ffs_get_single_dev(void)
+ {
+       struct ffs_dev *dev;
+@@ -2288,15 +2288,15 @@ static struct ffs_dev *ffs_get_single_dev(void)
+ /*
+  * ffs_lock must be taken by the caller of this function
+  */
+-static struct ffs_dev *ffs_find_dev(const char *name)
++static struct ffs_dev *_ffs_find_dev(const char *name)
+ {
+       struct ffs_dev *dev;
+-      dev = ffs_get_single_dev();
++      dev = _ffs_get_single_dev();
+       if (dev)
+               return dev;
+-      return _ffs_find_dev(name);
++      return _ffs_do_find_dev(name);
+ }
+ /* Configfs support *********************************************************/
+@@ -2332,7 +2332,7 @@ static void ffs_free_inst(struct usb_function_instance *f)
+       opts = to_f_fs_opts(f);
+       ffs_dev_lock();
+-      ffs_free_dev(opts->dev);
++      _ffs_free_dev(opts->dev);
+       ffs_dev_unlock();
+       kfree(opts);
+ }
+@@ -2387,7 +2387,7 @@ static struct usb_function_instance *ffs_alloc_inst(void)
+       opts->func_inst.set_inst_name = ffs_set_inst_name;
+       opts->func_inst.free_func_inst = ffs_free_inst;
+       ffs_dev_lock();
+-      dev = ffs_alloc_dev();
++      dev = _ffs_alloc_dev();
+       ffs_dev_unlock();
+       if (IS_ERR(dev)) {
+               kfree(opts);
+@@ -2475,12 +2475,12 @@ static struct usb_function *ffs_alloc(struct usb_function_instance *fi)
+ /*
+  * ffs_lock must be taken by the caller of this function
+  */
+-static struct ffs_dev *ffs_alloc_dev(void)
++static struct ffs_dev *_ffs_alloc_dev(void)
+ {
+       struct ffs_dev *dev;
+       int ret;
+-      if (ffs_get_single_dev())
++      if (_ffs_get_single_dev())
+                       return ERR_PTR(-EBUSY);
+       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+@@ -2508,7 +2508,7 @@ static int _ffs_name_dev(struct ffs_dev *dev, const char *name)
+ {
+       struct ffs_dev *existing;
+-      existing = _ffs_find_dev(name);
++      existing = _ffs_do_find_dev(name);
+       if (existing)
+               return -EBUSY;
+@@ -2552,7 +2552,7 @@ EXPORT_SYMBOL(ffs_single_dev);
+ /*
+  * ffs_lock must be taken by the caller of this function
+  */
+-static void ffs_free_dev(struct ffs_dev *dev)
++static void _ffs_free_dev(struct ffs_dev *dev)
+ {
+       list_del(&dev->entry);
+       if (dev->name_allocated)
+@@ -2569,7 +2569,7 @@ static void *ffs_acquire_dev(const char *dev_name)
+       ENTER();
+       ffs_dev_lock();
+-      ffs_dev = ffs_find_dev(dev_name);
++      ffs_dev = _ffs_find_dev(dev_name);
+       if (!ffs_dev)
+               ffs_dev = ERR_PTR(-ENODEV);
+       else if (ffs_dev->mounted)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1197-usb-gadget-fix-NULL-pointer-dereference.patch b/patches.tizen/1197-usb-gadget-fix-NULL-pointer-dereference.patch
new file mode 100644 (file)
index 0000000..79377f6
--- /dev/null
@@ -0,0 +1,62 @@
+From d648cb17fd2bd010ca1d9d9aedf88f9bcf44c414 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Mon, 20 Jan 2014 08:32:43 +0100
+Subject: [PATCH 1197/1302] usb: gadget: fix NULL pointer dereference
+
+Fix possible NULL pointer dereference introduced in
+
+219580e64f035bb9018dbb08d340f90b0ac50f8c
+usb: f_fs: check quirk to pad epout buf size when not aligned to
+maxpacketsize
+
+In cases we do wait with:
+
+wait_event_interruptible(epfile->wait, (ep = epfile->ep));
+
+for endpoint to be enabled, functionfs_bind() has not been called yet
+and epfile->ffs->gadget is still NULL and the automatic variable 'gadget'
+has been initialized with NULL at the point of its definition.
+Later on it is used as a parameter to:
+
+usb_ep_align_maybe(gadget, ep->ep, len)
+
+which in turn dereferences it.
+
+This patch fixes it by moving the actual assignment to the local 'gadget'
+variable after the potential waiting has completed.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_fs.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
+index b28d62f..984374e 100644
+--- a/drivers/usb/gadget/f_fs.c
++++ b/drivers/usb/gadget/f_fs.c
+@@ -587,7 +587,6 @@ static ssize_t ffs_epfile_io(struct file *file,
+                            char __user *buf, size_t len, int read)
+ {
+       struct ffs_epfile *epfile = file->private_data;
+-      struct usb_gadget *gadget = epfile->ffs->gadget;
+       struct ffs_ep *ep;
+       char *data = NULL;
+       ssize_t ret, data_len;
+@@ -624,6 +623,12 @@ static ssize_t ffs_epfile_io(struct file *file,
+       /* Allocate & copy */
+       if (!halt) {
+               /*
++               * if we _do_ wait above, the epfile->ffs->gadget might be NULL
++               * before the waiting completes, so do not assign to 'gadget' earlier
++               */
++              struct usb_gadget *gadget = epfile->ffs->gadget;
++
++              /*
+                * Controller may require buffer size to be aligned to
+                * maxpacketsize of an out endpoint.
+                */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1198-Add-dependency-on-kernel-package-in-kernel-devel-pac.patch b/patches.tizen/1198-Add-dependency-on-kernel-package-in-kernel-devel-pac.patch
new file mode 100644 (file)
index 0000000..bf302af
--- /dev/null
@@ -0,0 +1,28 @@
+From 99f31937216299fad107910423ee52d5a42f1d81 Mon Sep 17 00:00:00 2001
+From: Jacek Pielaszkiewicz <j.pielaszkie@samsung.com>
+Date: Mon, 20 Jan 2014 10:20:35 +0100
+Subject: [PATCH 1198/1302] Add dependency on kernel package in kernel-devel
+ package.
+
+Change-Id: Iba7d12ecac46b3e5985f412f4cc3f623162cf728
+Signed-off-by: Jacek Pielaszkiewicz <j.pielaszkie@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ packaging/linux-kernel.spec | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/packaging/linux-kernel.spec b/packaging/linux-kernel.spec
+index 211efd8..bc789fe 100644
+--- a/packaging/linux-kernel.spec
++++ b/packaging/linux-kernel.spec
+@@ -45,6 +45,7 @@ Summary: Prebuilt linux kernel for out-of-tree modules
+ Group: Development/System
+ Provides: kernel-devel = %{fullVersion}
+ Provides: kernel-devel-uname-r = %{fullVersion}
++Requires: %{name} = %{version}-%{release}
+ %description devel
+ Prebuilt linux kernel for out-of-tree modules.
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1199-tizen-packaging-support-perf-build.patch b/patches.tizen/1199-tizen-packaging-support-perf-build.patch
new file mode 100644 (file)
index 0000000..1cea49c
--- /dev/null
@@ -0,0 +1,84 @@
+From 843343985e329ab18bafec74c062cf42c3ef4dcd Mon Sep 17 00:00:00 2001
+From: Chanho Park <chanho61.park@samsung.com>
+Date: Tue, 21 Jan 2014 10:11:34 +0900
+Subject: [PATCH 1199/1302] tizen: packaging: support perf build
+
+Change-Id: Idc375608e3bde344347de6ad37c434b5f16aefbc
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ packaging/linux-kernel.spec | 33 +++++++++++++++++++++++++++++++++
+ 1 file changed, 33 insertions(+)
+
+diff --git a/packaging/linux-kernel.spec b/packaging/linux-kernel.spec
+index bc789fe..ce062c8 100644
+--- a/packaging/linux-kernel.spec
++++ b/packaging/linux-kernel.spec
+@@ -20,6 +20,12 @@ BuildRoot: %{_tmppath}/%{name}-%{PACKAGE_VERSION}-root
+ BuildRequires: linux-glibc-devel
+ BuildRequires: u-boot-tools
+ BuildRequires: bc
++# The below is required for building perf
++BuildRequires: libelf-devel
++BuildRequires: flex
++BuildRequires: bison
++BuildRequires: libdw-devel
++BuildRequires: python-devel
+ Provides: kernel = %{version}-%{release}
+ Provides: kernel-uname-r = %{fullVersion}
+@@ -50,6 +56,15 @@ Requires: %{name} = %{version}-%{release}
+ %description devel
+ Prebuilt linux kernel for out-of-tree modules.
++%package -n perf
++Summary: The 'perf' performance counter tool
++Group: Development/System
++Provides: perf = %{kernel_full_version}
++
++%description -n perf
++This package provides the "perf" tool that can be used to monitor performance
++counter events as well as various kernel internal events.
++
+ %prep
+ %setup -q
+@@ -65,6 +80,10 @@ make EXTRAVERSION="-%{build_id}" dtbs %{?_smp_mflags}
+ # 3. Build modules
+ make EXTRAVERSION="-%{build_id}" modules %{?_smp_mflags}
++# 3.1 Build perf
++make -s -C tools/lib/traceevent ARCH=%{buildarch} %{?_smp_mflags}
++make -s -C tools/perf WERROR=0 ARCH=%{buildarch}
++
+ # 4. Create tar repo for build directory
+ tar cpsf linux-kernel-build-%{fullVersion}.tar .
+@@ -90,6 +109,15 @@ make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=%{buildroot} modules_install
+ # 4. Install kernel headers
+ make INSTALL_PATH=%{buildroot} INSTALL_MOD_PATH=%{buildroot} INSTALL_HDR_PATH=%{buildroot}/usr headers_install
++# 4.1 Install perf
++install -d %{buildroot}
++make -s -C tools/perf DESTDIR=%{buildroot} install
++install -d  %{buildroot}/usr/bin
++install -d  %{buildroot}/usr/libexec
++mv %{buildroot}/bin/* %{buildroot}/usr/bin/
++mv %{buildroot}/libexec/* %{buildroot}/usr/libexec/
++rm %{buildroot}/etc/bash_completion.d/perf
++
+ # 5. Restore source and build irectory
+ tar -xf linux-kernel-build-%{fullVersion}.tar -C %{buildroot}/usr/src/linux-kernel-build-%{fullVersion}
+ mv %{buildroot}/usr/src/linux-kernel-build-%{fullVersion}/arch/%{buildarch} .
+@@ -145,3 +173,8 @@ rm -rf %{buildroot}
+ /boot/config*
+ /lib/modules/%{fullVersion}/kernel
+ /lib/modules/%{fullVersion}/modules.*
++
++%files -n perf
++%license COPYING
++/usr/bin/perf
++/usr/libexec/perf-core
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1200-usb-gadget-temporarily-turn-off-rndis-from-slp-gadge.patch b/patches.tizen/1200-usb-gadget-temporarily-turn-off-rndis-from-slp-gadge.patch
new file mode 100644 (file)
index 0000000..e384a93
--- /dev/null
@@ -0,0 +1,58 @@
+From 7ca93af1e28792259a3b38cb43de67eea28d7352 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Wed, 22 Jan 2014 14:58:04 +0100
+Subject: [PATCH 1200/1302] usb: gadget: temporarily turn off rndis from slp
+ gadget
+
+This fixes build break caused by recently merged removal
+of compatibility layer in rndis.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Change-Id: I11c2d02e2d491f30f8c9936916f627389787a1e5
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/slp.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/gadget/slp.c b/drivers/usb/gadget/slp.c
+index 45536b4..06ac801 100644
+--- a/drivers/usb/gadget/slp.c
++++ b/drivers/usb/gadget/slp.c
+@@ -154,7 +154,7 @@ struct slp_multi_dev {
+ };
+ /* TODO: only enabled 'rndis' and 'sdb'. need to verify more functions */
+-static const char *default_funcs[] = {"rndis", "sdb"};
++static const char *default_funcs[] = {"sdb"};
+ static unsigned slp_multi_nluns;
+ static struct class *slp_multi_class;
+ static struct slp_multi_dev *_slp_multi_dev;
+@@ -372,6 +372,7 @@ static struct slp_multi_usb_function acm_function = {
+       .attributes     = acm_function_attributes,
+ };
++#if 0
+ struct rndis_function_config {
+       u8 ethaddr[ETH_ALEN];
+       u32 vendorID;
+@@ -612,14 +613,16 @@ static struct slp_multi_usb_function rndis_function = {
+       .unbind_config = rndis_function_unbind_config,
+       .attributes = rndis_function_attributes,
+ };
+-
++#endif
+ /*-------------------------------------------------------------------------*/
+ /* Supported functions initialization */
+ static struct slp_multi_usb_function *supported_functions[] = {
+       &sdb_function,
+       &acm_function,
++#if 0
+       &rndis_function,
++#endif
+       NULL,
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1201-usb-gadget-adapt-slp-to-new-interface-of-rndis.patch b/patches.tizen/1201-usb-gadget-adapt-slp-to-new-interface-of-rndis.patch
new file mode 100644 (file)
index 0000000..339e5f9
--- /dev/null
@@ -0,0 +1,149 @@
+From 65c9d04f37805a4c1f5c77f6a6a3c7202d9face4 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 23 Jan 2014 11:08:57 +0100
+Subject: [PATCH 1201/1302] usb: gadget: adapt slp to new interface of rndis
+
+f_rndis has a new interface. Use it.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Change-Id: I4cd8baf2180cc69fb372c6cce018ecf3a5729a38
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/slp.c | 54 +++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 35 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/usb/gadget/slp.c b/drivers/usb/gadget/slp.c
+index 06ac801..3ca9202 100644
+--- a/drivers/usb/gadget/slp.c
++++ b/drivers/usb/gadget/slp.c
+@@ -372,14 +372,14 @@ static struct slp_multi_usb_function acm_function = {
+       .attributes     = acm_function_attributes,
+ };
+-#if 0
+ struct rndis_function_config {
+       u8 ethaddr[ETH_ALEN];
+       u32 vendorID;
+       char manufacturer[256];
+       bool wceis;
+       u8 rndis_string_defs0_id;
+-      struct eth_dev *edev;
++      struct usb_function *f_rndis;
++      struct usb_function_instance *fi_rndis;
+ };
+ static char host_addr_string[18];
+@@ -393,6 +393,12 @@ static int rndis_function_init(struct slp_multi_usb_function *f,
+       if (!config)
+               return -ENOMEM;
++      config->fi_rndis = usb_get_function_instance("rndis");
++      if (IS_ERR(config->fi_rndis)) {
++              status = PTR_ERR(config->fi_rndis);
++              goto rndis_alloc_inst_error;
++      }
++
+       /* maybe allocate device-global string IDs */
+       if (rndis_string_defs[0].id == 0) {
+@@ -437,13 +443,18 @@ static int rndis_function_init(struct slp_multi_usb_function *f,
+       return 0;
+  rndis_init_error:
++      usb_put_function_instance(config->fi_rndis);
++rndis_alloc_inst_error:
+       kfree(config);
+       return status;
+ }
+ static void rndis_function_cleanup(struct slp_multi_usb_function *f)
+ {
+-      kfree(f->config);
++      struct rndis_function_config *rndis = f->config;
++
++      usb_put_function_instance(rndis->fi_rndis);
++      kfree(rndis);
+       f->config = NULL;
+ }
+@@ -452,19 +463,23 @@ static int rndis_function_bind_config(struct slp_multi_usb_function *f,
+ {
+       int ret = -EINVAL;
+       struct rndis_function_config *rndis = f->config;
++      struct f_rndis_opts *rndis_opts;
++      struct net_device *net;
+       if (!rndis) {
+               dev_err(f->dev, "error rndis_pdata is null\n");
+               return ret;
+       }
+-      rndis->edev = gether_setup(c->cdev->gadget, rndis->ethaddr,
+-                                 host_addr_string, rndis->ethaddr,
+-                                 QMULT_DEFAULT);
+-      if (IS_ERR(rndis->edev)) {
+-              dev_err(f->dev, "gether_setup failed\n");
+-              return ret;
+-      }
++      rndis_opts =
++              container_of(rndis->fi_rndis, struct f_rndis_opts, func_inst);
++      net = rndis_opts->net;
++
++      gether_set_qmult(net, QMULT_DEFAULT);
++      gether_set_host_addr(net, host_addr_string);
++      gether_set_dev_addr(net, host_addr_string);
++      rndis_opts->vendor_id = rndis->vendorID;
++      rndis_opts->manufacturer = rndis->manufacturer;
+       if (rndis->wceis) {
+               /* "Wireless" RNDIS; auto-detected by Windows */
+@@ -489,11 +504,13 @@ static int rndis_function_bind_config(struct slp_multi_usb_function *f,
+       if (rndis_string_defs[0].id == 0)
+               rndis_string_defs[0].id = rndis->rndis_string_defs0_id;
+-      ret = rndis_bind_config_vendor(c, rndis->ethaddr, rndis->vendorID,
+-                               rndis->manufacturer, rndis->edev);
+-      if (ret) {
+-              rndis_exit();
+-              gether_cleanup(rndis->edev);
++      rndis->f_rndis = usb_get_function(rndis->fi_rndis);
++      if (IS_ERR(rndis->f_rndis))
++              return PTR_ERR(rndis->f_rndis);
++
++      ret = usb_add_function(c, rndis->f_rndis);
++      if (ret < 0) {
++              usb_put_function(rndis->f_rndis);
+               dev_err(f->dev, "rndis_bind_config failed(ret:%d)\n", ret);
+       }
+@@ -504,7 +521,8 @@ static void rndis_function_unbind_config(struct slp_multi_usb_function *f,
+                                        struct usb_configuration *c)
+ {
+       struct rndis_function_config *rndis = f->config;
+-      gether_cleanup(rndis->edev);
++
++      usb_put_function(rndis->f_rndis);
+ }
+ static ssize_t rndis_manufacturer_show(struct device *dev,
+@@ -613,16 +631,14 @@ static struct slp_multi_usb_function rndis_function = {
+       .unbind_config = rndis_function_unbind_config,
+       .attributes = rndis_function_attributes,
+ };
+-#endif
++
+ /*-------------------------------------------------------------------------*/
+ /* Supported functions initialization */
+ static struct slp_multi_usb_function *supported_functions[] = {
+       &sdb_function,
+       &acm_function,
+-#if 0
+       &rndis_function,
+-#endif
+       NULL,
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1202-usb-gadget-eliminate-memory-leak-in-slp-gadget.patch b/patches.tizen/1202-usb-gadget-eliminate-memory-leak-in-slp-gadget.patch
new file mode 100644 (file)
index 0000000..04912df
--- /dev/null
@@ -0,0 +1,30 @@
+From 60c20313e213ca00ecff63d79eb718777149f935 Mon Sep 17 00:00:00 2001
+From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Date: Thu, 23 Jan 2014 11:18:36 +0100
+Subject: [PATCH 1202/1302] usb: gadget: eliminate memory leak in slp gadget
+
+Free the allocated acm_function_config struct in case of error.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+Change-Id: Ie935cf67beccc2071d1ecd74437cffbe6a6827b8
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/slp.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/usb/gadget/slp.c b/drivers/usb/gadget/slp.c
+index 3ca9202..70b7d2f 100644
+--- a/drivers/usb/gadget/slp.c
++++ b/drivers/usb/gadget/slp.c
+@@ -282,6 +282,8 @@ err_usb_get_function_instance:
+ err_usb_get_function:
+               usb_put_function_instance(config->f_acm_inst[i]);
+       }
++      kfree(f->config);
++      f->config = NULL;
+       return ret;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1203-spec-add-missing-build-dependences-and-output-packag.patch b/patches.tizen/1203-spec-add-missing-build-dependences-and-output-packag.patch
new file mode 100644 (file)
index 0000000..9354291
--- /dev/null
@@ -0,0 +1,86 @@
+From c67d2e81d7a60302c03995b5c263570a9ab09058 Mon Sep 17 00:00:00 2001
+From: Jacek Pielaszkiewicz <j.pielaszkie@samsung.com>
+Date: Mon, 27 Jan 2014 15:19:59 +0100
+Subject: [PATCH 1203/1302] spec: add missing build dependences and output
+ packages cleanup.
+
+The following changes have been implemeneted:
+1. Add BuildRequires on module-init-tools
+2. Cleanup  Documentation directory from *.txt files
+3. Update file permisions for executable files (*.sh, *pl)
+
+Change-Id: I06a9348f6220ce2383b6f788635acbd0fe5ef78e
+Signed-off-by: Jacek Pielaszkiewicz <j.pielaszkie@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ packaging/linux-kernel.spec | 32 +++++++++++++++++++++++---------
+ 1 file changed, 23 insertions(+), 9 deletions(-)
+
+diff --git a/packaging/linux-kernel.spec b/packaging/linux-kernel.spec
+index ce062c8..41c7be1 100644
+--- a/packaging/linux-kernel.spec
++++ b/packaging/linux-kernel.spec
+@@ -18,6 +18,7 @@ BuildRoot: %{_tmppath}/%{name}-%{PACKAGE_VERSION}-root
+ %define fullVersion %{version}-%{build_id}
+ BuildRequires: linux-glibc-devel
++BuildRequires: module-init-tools
+ BuildRequires: u-boot-tools
+ BuildRequires: bc
+ # The below is required for building perf
+@@ -128,30 +129,43 @@ mv Kconfig      %{buildroot}/usr/src/linux-kernel-build-%{fullVersion}/arch/
+ # 6. Remove files
+ find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name ".tmp_vmlinux*" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "\.*dtb*tmp" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "*\.*tmp" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name ".gitignore" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name ".*dtb*tmp" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "*.*tmp" -exec rm -f {} \;
+ find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "vmlinux" -exec rm -f {} \;
+ find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "uImage" -exec rm -f {} \;
+ find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "zImage" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "test-*" -exec rm -f {} \;
+ find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "*.cmd" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "*\.ko" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "*\.o" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "*\.S" -exec rm -f {} \;
+-find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "*\.c" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "*.ko" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "*.o" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "*.S" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "*.s" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -name "*.c" -exec rm -f {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion} -size 0c -exec rm -f {} \;
+ find %{buildroot}/usr/include -name "\.install"  -exec rm -f {} \;
+ find %{buildroot}/usr -name "..install.cmd" -exec rm -f {} \;
++# 6.1 Clean Documentation directory
++find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion}/Documentation -type f ! -name "Makefile" ! -name "*.sh" ! -name "*.pl" -exec rm -f {} \;
++
+ rm -rf %{buildroot}/boot/vmlinux*
+ rm -rf %{buildroot}/System.map*
+ rm -rf %{buildroot}/vmlinux*
+-# 7. Create symbolic links
++# 7. Update file permisions
++%define excluded_files ! -name "*.h" ! -name "*.cocci" ! -name "*.tst" ! -name "*.y" ! -name "*.in" ! -name "*.gperf" ! -name "*.PL" ! -name "lex*" ! -name "check-perf-tracei.pl" ! -name "*.*shipped" ! -name "*asm-generic" ! -name "Makefile*" ! -name "*.lds" ! -name "mkversion" ! -name "zconf.l" ! -name "README" ! -name "*.py" ! -name "gconf.glade" ! -name "*.cc" ! -name "dbus_contexts" ! -name "*.pm" ! -name "*.xs" ! -name "*.l" ! -name "EventClass.py" ! -name "typemap" ! -name "net_dropmonitor.py"
++
++find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion}/tools/perf/scripts/ -type f %{excluded_files} -exec chmod 755 {} \;
++find %{buildroot}/usr/src/linux-kernel-build-%{fullVersion}/scripts/            -type f %{excluded_files} -exec chmod 755 {} \;
++find %{buildroot}/usr                                                           -type f ! -name "check-perf-tracei.pl" -name "*.sh" -name "*.pl" -exec chmod 755 {} \;
++find %{buildroot}/lib/modules/ -name "*.ko"                                     -type f -exec chmod 755 {} \;
++
++# 8. Create symbolic links
+ rm -f %{buildroot}/lib/modules/%{fullVersion}/build
+ rm -f %{buildroot}/lib/modules/%{fullVersion}/source
+ ln -sf /usr/src/linux-kernel-build-%{fullVersion} %{buildroot}/lib/modules/%{fullVersion}/build
+-find %{buildroot}/lib/modules/ -name "*.ko" -type f -exec chmod 755 {} \;
+-
+ %clean
+ rm -rf %{buildroot}
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1204-Revert-WORKAROUND-Temporary-workaround-for-Suspend-T.patch b/patches.tizen/1204-Revert-WORKAROUND-Temporary-workaround-for-Suspend-T.patch
new file mode 100644 (file)
index 0000000..1feaba1
--- /dev/null
@@ -0,0 +1,31 @@
+From 0c06fe0c19e1b4f259c0876f4ed54da0a5a5a54f Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Mon, 3 Feb 2014 17:29:25 +0900
+Subject: [PATCH 1204/1302] Revert "WORKAROUND: Temporary workaround for
+ Suspend-To-Ram."
+
+This reverts commit 682061cb597d5174de6fee211a2ad565c33680f7.
+
+Change-Id: I4ac3f3b86ecd6a8b15ea2d266ab84b16aeb69dda
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 0867ada..9f268f4 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -806,7 +806,7 @@
+                                       regulator-max-microvolt = <1500000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+-                                      regulator-mem-on;
++                                      regulator-mem-off;
+                               };
+                               buck3_reg: buck@3 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1205-clk-exynos4-Keep-chipid-clock-enabled.patch b/patches.tizen/1205-clk-exynos4-Keep-chipid-clock-enabled.patch
new file mode 100644 (file)
index 0000000..7a45d00
--- /dev/null
@@ -0,0 +1,42 @@
+From 74437f33fc34ffb442b70cbfb67002402e43e630 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Mon, 3 Feb 2014 17:31:33 +0900
+Subject: [PATCH 1205/1302] clk: exynos4: Keep 'chipid' clock enabled
+
+During STR, we needed to access CHIP_ID, thus its clock should be online.
+It's better to keep it enabled even in runtime for later suspend.
+
+Change-Id: I057471e0aac3a9343b0ca8a73d4c8abf0ae36812
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/samsung/clk-exynos4.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
+index a9be318..ed29bf5 100644
+--- a/drivers/clk/samsung/clk-exynos4.c
++++ b/drivers/clk/samsung/clk-exynos4.c
+@@ -807,7 +807,8 @@ struct samsung_gate_clock exynos4210_gate_clks[] __initdata = {
+       GATE(pcie, "pcie", "aclk133", GATE_IP_FSYS, 14, 0, 0),
+       GATE(smmu_pcie, "smmu_pcie", "aclk133", GATE_IP_FSYS, 18, 0, 0),
+       GATE(modemif, "modemif", "aclk100", GATE_IP_PERIL, 28, 0, 0),
+-      GATE(chipid, "chipid", "aclk100", E4210_GATE_IP_PERIR, 0, 0, 0),
++      GATE(chipid, "chipid", "aclk100", E4210_GATE_IP_PERIR, 0,
++                      CLK_IGNORE_UNUSED, 0),
+       GATE(sysreg, "sysreg", "aclk100", E4210_GATE_IP_PERIR, 0,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(hdmi_cec, "hdmi_cec", "aclk100", E4210_GATE_IP_PERIR, 11, 0, 0),
+@@ -837,7 +838,8 @@ struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = {
+       GATE(mdma2, "mdma2", "aclk200", E4X12_GATE_IP_IMAGE, 2, 0, 0),
+       GATE(smmu_mdma, "smmu_mdma", "aclk200", E4X12_GATE_IP_IMAGE, 5, 0, 0),
+       GATE(mipi_hsi, "mipi_hsi", "aclk133", GATE_IP_FSYS, 10, 0, 0),
+-      GATE(chipid, "chipid", "aclk100", E4X12_GATE_IP_PERIR, 0, 0, 0),
++      GATE(chipid, "chipid", "aclk100", E4X12_GATE_IP_PERIR, 0,
++                      CLK_IGNORE_UNUSED, 0),
+       GATE(sysreg, "sysreg", "aclk100", E4X12_GATE_IP_PERIR, 1,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(hdmi_cec, "hdmi_cec", "aclk100", E4X12_GATE_IP_PERIR, 11, 0, 0),
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1206-pm-exynos-Skip-re-enabling-L2-cache-for-early-waking.patch b/patches.tizen/1206-pm-exynos-Skip-re-enabling-L2-cache-for-early-waking.patch
new file mode 100644 (file)
index 0000000..b47d366
--- /dev/null
@@ -0,0 +1,58 @@
+From 04eecaa551d25b0c614c7a7fcdf9febc9aa4afcc Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Mon, 3 Feb 2014 17:37:04 +0900
+Subject: [PATCH 1206/1302] pm: exynos: Skip re-enabling L2 cache for early
+ waking-up.
+
+If L2 cache is powered on, accessing L2 cache's control register is
+forbidden. Ohterwise system will hang up.
+So, when system fails to go to sleep, we have to avoid reset L2 cache
+because it still be powered on.
+
+Change-Id: Ie0271619116012627477e332b0cd5e60a27882ff
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/mach-exynos/pm.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
+index d5bac0d..e5421fa 100644
+--- a/arch/arm/mach-exynos/pm.c
++++ b/arch/arm/mach-exynos/pm.c
+@@ -273,10 +273,7 @@ static int exynos_pm_suspend(void)
+ static void exynos_pm_resume(void)
+ {
+       unsigned long tmp;
+-#ifdef CONFIG_CACHE_L2X0
+-      if (call_firmware_op(l2x0_resume) < 0)
+-              outer_resume();
+-#endif
++
+       /*
+        * If PMU failed while entering sleep mode, WFI will be
+        * ignored by PMU and then exiting cpu_do_idle().
+@@ -292,6 +289,7 @@ static void exynos_pm_resume(void)
+               /* No need to perform below restore code */
+               goto early_wakeup;
+       }
++
+       if (!soc_is_exynos5250()
+           && call_firmware_op(c15resume, save_arm_register) == -ENOSYS)
+       {
+@@ -330,6 +328,12 @@ static void exynos_pm_resume(void)
+ #ifdef CONFIG_SMP
+               scu_enable(S5P_VA_SCU);
+ #endif
++
++#ifdef CONFIG_CACHE_L2X0
++      if (call_firmware_op(l2x0_resume) < 0)
++              outer_resume();
++#endif
++
+       }
+ early_wakeup:
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1207-iio-ak8975-Fix-calculation-formula-for-convert-micro.patch b/patches.tizen/1207-iio-ak8975-Fix-calculation-formula-for-convert-micro.patch
new file mode 100644 (file)
index 0000000..0f07e0f
--- /dev/null
@@ -0,0 +1,66 @@
+From bcc9b4777f47905eb7578502d7430ef76d96f22b Mon Sep 17 00:00:00 2001
+From: Beomho Seo <beomho.seo@samsung.com>
+Date: Mon, 10 Feb 2014 09:52:28 +0900
+Subject: [PATCH 1207/1302] iio: ak8975: Fix calculation formula for convert
+ micro tesla to gauss unit
+
+Oen micro tesla equal 0.01 gauss. So I have fixed calculation formula And add RAW_TO_GAUSS macro.
+ASA is in the range of 0 to 255. If multiply 0.003, calculation result(in_magn_[*]_scale) is
+always 0. So multiply 3000 and return IIO_VAL_INT_PLUS_MICRO.
+As a result read_raw call back function return accurate scale value.
+
+Change-Id: Ia00b801d4867955eef661b64add82ca634f0256c
+Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iio/magnetometer/ak8975.c | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c
+index 7105f22..9edf4c9 100644
+--- a/drivers/iio/magnetometer/ak8975.c
++++ b/drivers/iio/magnetometer/ak8975.c
+@@ -85,6 +85,7 @@
+ #define AK8975_MAX_CONVERSION_TIMEOUT 500
+ #define AK8975_CONVERSION_DONE_POLL_TIME 10
+ #define AK8975_DATA_READY_TIMEOUT     ((100*HZ)/1000)
++#define RAW_TO_GAUSS(asa) ((((asa) + 128) * 3000) / 256)
+ /*
+  * Per-instance context data for the device.
+@@ -265,15 +266,15 @@ static int ak8975_setup(struct i2c_client *client)
+  *
+  * Since 1uT = 100 gauss, our final scale factor becomes:
+  *
+- * Hadj = H * ((ASA + 128) / 256) * 3/10 * 100
+- * Hadj = H * ((ASA + 128) * 30 / 256
++ * Hadj = H * ((ASA + 128) / 256) * 3/10 * 1/100
++ * Hadj = H * ((ASA + 128) * 0.003) / 256
+  *
+  * Since ASA doesn't change, we cache the resultant scale factor into the
+  * device context in ak8975_setup().
+  */
+-      data->raw_to_gauss[0] = ((data->asa[0] + 128) * 30) >> 8;
+-      data->raw_to_gauss[1] = ((data->asa[1] + 128) * 30) >> 8;
+-      data->raw_to_gauss[2] = ((data->asa[2] + 128) * 30) >> 8;
++      data->raw_to_gauss[0] = RAW_TO_GAUSS(data->asa[0]);
++      data->raw_to_gauss[1] = RAW_TO_GAUSS(data->asa[1]);
++      data->raw_to_gauss[2] = RAW_TO_GAUSS(data->asa[2]);
+       return 0;
+ }
+@@ -428,8 +429,9 @@ static int ak8975_read_raw(struct iio_dev *indio_dev,
+       case IIO_CHAN_INFO_RAW:
+               return ak8975_read_axis(indio_dev, chan->address, val);
+       case IIO_CHAN_INFO_SCALE:
+-              *val = data->raw_to_gauss[chan->address];
+-              return IIO_VAL_INT;
++              *val = 0;
++              *val2 = data->raw_to_gauss[chan->address];
++              return IIO_VAL_INT_PLUS_MICRO;
+       }
+       return -EINVAL;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1208-iio-ak8975-Add-device-name.patch b/patches.tizen/1208-iio-ak8975-Add-device-name.patch
new file mode 100644 (file)
index 0000000..1c4b7ea
--- /dev/null
@@ -0,0 +1,29 @@
+From ddedf296eeedd11c474cb7aae491e98c73f828f5 Mon Sep 17 00:00:00 2001
+From: Beomho Seo <beomho.seo@samsung.com>
+Date: Mon, 10 Feb 2014 10:01:57 +0900
+Subject: [PATCH 1208/1302] iio: ak8975: Add device name
+
+This patch add device name.
+
+Change-Id: Icda321686ee9c9809463592bddfbaa87563aeae4
+Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iio/magnetometer/ak8975.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c
+index 9edf4c9..fb3aefe 100644
+--- a/drivers/iio/magnetometer/ak8975.c
++++ b/drivers/iio/magnetometer/ak8975.c
+@@ -513,6 +513,7 @@ static int ak8975_probe(struct i2c_client *client,
+       indio_dev->channels = ak8975_channels;
+       indio_dev->num_channels = ARRAY_SIZE(ak8975_channels);
+       indio_dev->info = &ak8975_info;
++      indio_dev->name = id->name;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       err = iio_device_register(indio_dev);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1209-video-display-s6e8aa0-fix-a-erratum-in-gamma-table.patch b/patches.tizen/1209-video-display-s6e8aa0-fix-a-erratum-in-gamma-table.patch
new file mode 100644 (file)
index 0000000..9b3929b
--- /dev/null
@@ -0,0 +1,31 @@
+From 87b762c907e9dbda7005e98124b61538642c8766 Mon Sep 17 00:00:00 2001
+From: Hyungwon Hwang <human.hwang@samsung.com>
+Date: Thu, 6 Feb 2014 10:22:26 +0900
+Subject: [PATCH 1209/1302] video: display: s6e8aa0: fix a erratum in gamma
+ table
+
+Fix a erratum in gamma table.
+
+Change-Id: I88f9220de98fe34c5e47ae076f850de603dab8fe
+Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/video/display/panel-s6e8aa0.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/video/display/panel-s6e8aa0.c b/drivers/video/display/panel-s6e8aa0.c
+index d6dbfef..cec8b83 100644
+--- a/drivers/video/display/panel-s6e8aa0.c
++++ b/drivers/video/display/panel-s6e8aa0.c
+@@ -609,7 +609,7 @@ static const s6e8aa0_gamma_table s6e8aa0_gamma_tables_v96[GAMMA_LEVEL_NUM] = {
+               0xb9, 0xd0, 0xd1, 0xcd, 0x00, 0x63, 0x00, 0x54,
+               0x00, 0x7a,
+       }, {
+-              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x00, 0xffF,
++              0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x00, 0xff,
+               0xd1, 0x9e, 0xd5, 0xda, 0xcd, 0xdd, 0xbb, 0xb7,
+               0xb9, 0xce, 0xce, 0xc9, 0x00, 0x68, 0x00, 0x59,
+               0x00, 0x81,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1210-cpufreq-boost-Provide-support-for-BOOST-on-linux-3.1.patch b/patches.tizen/1210-cpufreq-boost-Provide-support-for-BOOST-on-linux-3.1.patch
new file mode 100644 (file)
index 0000000..97ff423
--- /dev/null
@@ -0,0 +1,104 @@
+From a63694a185a20e52d2f13d687a30108cffee4e6a Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Mon, 10 Feb 2014 15:42:51 +0100
+Subject: [PATCH 1210/1302] cpufreq: boost: Provide support for BOOST on
+ linux-3.10-tizen
+
+This code reads from device tree the boost_freq attribute and properly
+modify the cpufreq table to support BOOST framework.
+
+This attribute is only read when CONFIG_CPU_FREQ_BOOST_SW flag is set.
+
+Change-Id: I16fcba69b16c29434e3ec1a8a0ef1bc8bdebc0ca
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/exynos-cpufreq.c     | 38 ++++++++++++++++++++++++++++++++++--
+ drivers/cpufreq/exynos-cpufreq.h     |  2 ++
+ drivers/cpufreq/exynos4x12-cpufreq.c |  4 ++++
+ 3 files changed, 42 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c
+index 249d19b..0ecb7c9 100644
+--- a/drivers/cpufreq/exynos-cpufreq.c
++++ b/drivers/cpufreq/exynos-cpufreq.c
+@@ -288,6 +288,36 @@ static struct cpufreq_driver exynos_driver = {
+ /* Device Tree Support for CPU freq */
++int exynos_of_parse_boost(struct exynos_dvfs_info *info,
++                        const char *property_name)
++{
++      struct cpufreq_frequency_table *ft = info->freq_table;
++      struct device_node *node = info->dev->of_node;
++      unsigned int boost_freq;
++
++      if (of_property_read_u32(node, property_name, &boost_freq)) {
++              pr_err("%s: Property: %s not found\n", __func__,
++                     property_name);
++              return -ENODEV;
++      }
++
++      /*
++       * Adjust the BOOST setting code to the current cpufreq code
++       * Now we have static table definitions for frequencies, dividers
++       * and PLL parameters (like P M S)
++       *
++       * In the current cpufreq code base only the change of one entry at
++       * frequency table is required.
++       */
++
++      ft[0].index = CPUFREQ_BOOST_FREQ;
++      ft[0].frequency = boost_freq;
++
++      pr_debug("%s: BOOST frequency: %d\n", __func__, ft[0].frequency);
++
++      return 0;
++}
++
+ struct cpufreq_frequency_table *exynos_of_parse_freq_table(
+               struct exynos_dvfs_info *info, const char *property_name)
+ {
+@@ -326,8 +356,12 @@ struct cpufreq_frequency_table *exynos_of_parse_freq_table(
+               goto err_of_f_tab;
+       }
+-      /* Here + 2 is required for CPUFREQ_ENTRY_INVALID and
+-         CPUFREQ_TABLE_END  */
++      /*
++       * Here + 2 is required for CPUFREQ_ENTRY_INVALID  and
++       * CPUFREQ_TABLE_END
++       *
++       * Number of those entries must correspond to the apll_freq_4412 table
++       */
+       ft = kzalloc(sizeof(struct cpufreq_frequency_table) * (num + 2),
+                    GFP_KERNEL);
+       if (!ft) {
+diff --git a/drivers/cpufreq/exynos-cpufreq.h b/drivers/cpufreq/exynos-cpufreq.h
+index 12b2b66..cb08d28 100644
+--- a/drivers/cpufreq/exynos-cpufreq.h
++++ b/drivers/cpufreq/exynos-cpufreq.h
+@@ -51,3 +51,5 @@ struct cpufreq_frequency_table *exynos_of_parse_freq_table(
+        struct exynos_dvfs_info *info, const char *property_name);
+ unsigned int *exynos_of_parse_volt_table(struct exynos_dvfs_info *info,
+                                        const char *property_name);
++int exynos_of_parse_boost(struct exynos_dvfs_info *info,
++                        const char *property_name);
+diff --git a/drivers/cpufreq/exynos4x12-cpufreq.c b/drivers/cpufreq/exynos4x12-cpufreq.c
+index 410d087..e92d19b 100644
+--- a/drivers/cpufreq/exynos4x12-cpufreq.c
++++ b/drivers/cpufreq/exynos4x12-cpufreq.c
+@@ -203,6 +203,10 @@ int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
+       info->freq_table = exynos_of_parse_freq_table(info, "freq_table");
+       if (!info->freq_table)
+               info->freq_table = exynos4x12_freq_table;
++#ifdef CONFIG_CPU_FREQ_BOOST_SW
++      else
++              exynos_of_parse_boost(info, "boost_freq");
++#endif
+       info->set_freq = exynos4x12_set_frequency;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1211-cpufreq-boost-trats2-Define-boost_freq-attribute-for.patch b/patches.tizen/1211-cpufreq-boost-trats2-Define-boost_freq-attribute-for.patch
new file mode 100644 (file)
index 0000000..74669d7
--- /dev/null
@@ -0,0 +1,31 @@
+From 67da975629ad9c36efdd1a1dc36b6bc469265dbf Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Mon, 10 Feb 2014 15:44:31 +0100
+Subject: [PATCH 1211/1302] cpufreq: boost: trats2: Define boost_freq attribute
+ for cpufreq node.
+
+The Trats2 board (Exynos 4412 rev.1) is now able to work with 1.5 GHz
+BOOST frequency.
+
+Change-Id: Ic7da854dda7b99c9381708c54ff2528bd45a0cd9
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-m0.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-m0.dts b/arch/arm/boot/dts/exynos4412-m0.dts
+index c6120bb..9aefa58 100644
+--- a/arch/arm/boot/dts/exynos4412-m0.dts
++++ b/arch/arm/boot/dts/exynos4412-m0.dts
+@@ -220,6 +220,7 @@
+               freq_table = <1400000 1300000 1200000 1100000 1000000
+                            900000 800000 700000 600000 500000 400000 300000
+                            200000>;
++              boost_freq = <1500000>;
+       };
+       thermistor-ap@0 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1212-usb-gadget-functionfs-fix-typo-in-the-enum-variable.patch b/patches.tizen/1212-usb-gadget-functionfs-fix-typo-in-the-enum-variable.patch
new file mode 100644 (file)
index 0000000..572360c
--- /dev/null
@@ -0,0 +1,136 @@
+From d18dab294a1630f14e1387d88fde1c3b6640c37d Mon Sep 17 00:00:00 2001
+From: Michal Nazarewicz <mina86@mina86.com>
+Date: Mon, 10 Feb 2014 10:42:40 +0100
+Subject: [PATCH 1212/1302] usb: gadget: functionfs: fix typo in the enum
+ variable
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Since “cancelled” is spelled with two “l”s, rename FFS_SETUP_CANCELED
+to FFS_SETUP_CANCELLED.
+
+Signed-off-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Robert Baldyga <r.baldyga@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_fs.c | 16 ++++++++--------
+ drivers/usb/gadget/u_fs.h | 12 ++++++------
+ 2 files changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
+index 984374e..bfb52f6 100644
+--- a/drivers/usb/gadget/f_fs.c
++++ b/drivers/usb/gadget/f_fs.c
+@@ -246,7 +246,7 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf,
+       ENTER();
+       /* Fast check if setup was canceled */
+-      if (FFS_SETUP_STATE(ffs) == FFS_SETUP_CANCELED)
++      if (FFS_SETUP_STATE(ffs) == FFS_SETUP_CANCELLED)
+               return -EIDRM;
+       /* Acquire mutex */
+@@ -313,7 +313,7 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf,
+                */
+               spin_lock_irq(&ffs->ev.waitq.lock);
+               switch (FFS_SETUP_STATE(ffs)) {
+-              case FFS_SETUP_CANCELED:
++              case FFS_SETUP_CANCELLED:
+                       ret = -EIDRM;
+                       goto done_spin;
+@@ -348,7 +348,7 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf,
+               /*
+                * We are guaranteed to be still in FFS_ACTIVE state
+                * but the state of setup could have changed from
+-               * FFS_SETUP_PENDING to FFS_SETUP_CANCELED so we need
++               * FFS_SETUP_PENDING to FFS_SETUP_CANCELLED so we need
+                * to check for that.  If that happened we copied data
+                * from user space in vain but it's unlikely.
+                *
+@@ -357,7 +357,7 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf,
+                * transition can be performed and it's protected by
+                * mutex.
+                */
+-              if (FFS_SETUP_STATE(ffs) == FFS_SETUP_CANCELED) {
++              if (FFS_SETUP_STATE(ffs) == FFS_SETUP_CANCELLED) {
+                       ret = -EIDRM;
+ done_spin:
+                       spin_unlock_irq(&ffs->ev.waitq.lock);
+@@ -423,7 +423,7 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf,
+       ENTER();
+       /* Fast check if setup was canceled */
+-      if (FFS_SETUP_STATE(ffs) == FFS_SETUP_CANCELED)
++      if (FFS_SETUP_STATE(ffs) == FFS_SETUP_CANCELLED)
+               return -EIDRM;
+       /* Acquire mutex */
+@@ -444,7 +444,7 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf,
+       spin_lock_irq(&ffs->ev.waitq.lock);
+       switch (FFS_SETUP_STATE(ffs)) {
+-      case FFS_SETUP_CANCELED:
++      case FFS_SETUP_CANCELLED:
+               ret = -EIDRM;
+               break;
+@@ -491,7 +491,7 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf,
+               spin_lock_irq(&ffs->ev.waitq.lock);
+               /* See ffs_ep0_write() */
+-              if (FFS_SETUP_STATE(ffs) == FFS_SETUP_CANCELED) {
++              if (FFS_SETUP_STATE(ffs) == FFS_SETUP_CANCELLED) {
+                       ret = -EIDRM;
+                       break;
+               }
+@@ -1791,7 +1791,7 @@ static void __ffs_event_add(struct ffs_data *ffs,
+        * the source does nothing.
+        */
+       if (ffs->setup_state == FFS_SETUP_PENDING)
+-              ffs->setup_state = FFS_SETUP_CANCELED;
++              ffs->setup_state = FFS_SETUP_CANCELLED;
+       switch (type) {
+       case FUNCTIONFS_RESUME:
+diff --git a/drivers/usb/gadget/u_fs.h b/drivers/usb/gadget/u_fs.h
+index f418c25..38012bc 100644
+--- a/drivers/usb/gadget/u_fs.h
++++ b/drivers/usb/gadget/u_fs.h
+@@ -123,7 +123,7 @@ enum ffs_setup_state {
+        * setup.  If this state is set read/write on ep0 return
+        * -EIDRM.  This state is only set when adding event.
+        */
+-      FFS_SETUP_CANCELED
++      FFS_SETUP_CANCELLED
+ };
+ struct ffs_data {
+@@ -166,18 +166,18 @@ struct ffs_data {
+       /*
+        * Possible transitions:
+-       * + FFS_NO_SETUP       -> FFS_SETUP_PENDING  -- P: ev.waitq.lock
++       * + FFS_NO_SETUP        -> FFS_SETUP_PENDING  -- P: ev.waitq.lock
+        *               happens only in ep0 read which is P: mutex
+-       * + FFS_SETUP_PENDING  -> FFS_NO_SETUP       -- P: ev.waitq.lock
++       * + FFS_SETUP_PENDING   -> FFS_NO_SETUP       -- P: ev.waitq.lock
+        *               happens only in ep0 i/o  which is P: mutex
+-       * + FFS_SETUP_PENDING  -> FFS_SETUP_CANCELED -- P: ev.waitq.lock
+-       * + FFS_SETUP_CANCELED -> FFS_NO_SETUP       -- cmpxchg
++       * + FFS_SETUP_PENDING   -> FFS_SETUP_CANCELLED -- P: ev.waitq.lock
++       * + FFS_SETUP_CANCELLED -> FFS_NO_SETUP        -- cmpxchg
+        */
+       enum ffs_setup_state            setup_state;
+ #define FFS_SETUP_STATE(ffs)                                  \
+       ((enum ffs_setup_state)cmpxchg(&(ffs)->setup_state,     \
+-                                     FFS_SETUP_CANCELED, FFS_NO_SETUP))
++                                     FFS_SETUP_CANCELLED, FFS_NO_SETUP))
+       /* Events & such. */
+       struct {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1213-usb-gadget-functionfs-replace-FFS_SETUP_STATUS-with-.patch b/patches.tizen/1213-usb-gadget-functionfs-replace-FFS_SETUP_STATUS-with-.patch
new file mode 100644 (file)
index 0000000..bb6cc0c
--- /dev/null
@@ -0,0 +1,121 @@
+From cccccde3f66399d92c226271da2a9614e0e54dbb Mon Sep 17 00:00:00 2001
+From: Michal Nazarewicz <mina86@mina86.com>
+Date: Mon, 10 Feb 2014 10:42:41 +0100
+Subject: [PATCH 1213/1302] usb: gadget: functionfs: replace FFS_SETUP_STATUS
+ with an inline function
+
+The FFS_SETUP_STATUS macro could be trivialy replaced with an static
+inline function but more importantly its name was tad confusing.
+The name suggested it was a simple accessor macro but it actually
+did change the state of the ffs_data structure perfomring
+a FFS_SETUP_CANCELLED -> FFS_NO_SETUP transition.  The name of the
+function -- ffs_setup_state_clear_cancelled -- should better
+describe what the function actually does.
+
+Signed-off-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Robert Baldyga <r.baldyga@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_fs.c | 22 ++++++++++++++++------
+ drivers/usb/gadget/u_fs.h |  7 +++----
+ 2 files changed, 19 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
+index bfb52f6..169067c 100644
+--- a/drivers/usb/gadget/f_fs.c
++++ b/drivers/usb/gadget/f_fs.c
+@@ -99,6 +99,14 @@ static struct ffs_function *ffs_func_from_usb(struct usb_function *f)
+ }
++static inline enum ffs_setup_state
++ffs_setup_state_clear_cancelled(struct ffs_data *ffs)
++{
++      return (enum ffs_setup_state)
++              cmpxchg(&ffs->setup_state, FFS_SETUP_CANCELLED, FFS_NO_SETUP);
++}
++
++
+ static void ffs_func_eps_disable(struct ffs_function *func);
+ static int __must_check ffs_func_eps_enable(struct ffs_function *func);
+@@ -246,7 +254,7 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf,
+       ENTER();
+       /* Fast check if setup was canceled */
+-      if (FFS_SETUP_STATE(ffs) == FFS_SETUP_CANCELLED)
++      if (ffs_setup_state_clear_cancelled(ffs) == FFS_SETUP_CANCELLED)
+               return -EIDRM;
+       /* Acquire mutex */
+@@ -312,7 +320,7 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf,
+                * rather then _irqsave
+                */
+               spin_lock_irq(&ffs->ev.waitq.lock);
+-              switch (FFS_SETUP_STATE(ffs)) {
++              switch (ffs_setup_state_clear_cancelled(ffs)) {
+               case FFS_SETUP_CANCELLED:
+                       ret = -EIDRM;
+                       goto done_spin;
+@@ -357,7 +365,8 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf,
+                * transition can be performed and it's protected by
+                * mutex.
+                */
+-              if (FFS_SETUP_STATE(ffs) == FFS_SETUP_CANCELLED) {
++              if (ffs_setup_state_clear_cancelled(ffs) ==
++                  FFS_SETUP_CANCELLED) {
+                       ret = -EIDRM;
+ done_spin:
+                       spin_unlock_irq(&ffs->ev.waitq.lock);
+@@ -423,7 +432,7 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf,
+       ENTER();
+       /* Fast check if setup was canceled */
+-      if (FFS_SETUP_STATE(ffs) == FFS_SETUP_CANCELLED)
++      if (ffs_setup_state_clear_cancelled(ffs) == FFS_SETUP_CANCELLED)
+               return -EIDRM;
+       /* Acquire mutex */
+@@ -443,7 +452,7 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf,
+        */
+       spin_lock_irq(&ffs->ev.waitq.lock);
+-      switch (FFS_SETUP_STATE(ffs)) {
++      switch (ffs_setup_state_clear_cancelled(ffs)) {
+       case FFS_SETUP_CANCELLED:
+               ret = -EIDRM;
+               break;
+@@ -491,7 +500,8 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf,
+               spin_lock_irq(&ffs->ev.waitq.lock);
+               /* See ffs_ep0_write() */
+-              if (FFS_SETUP_STATE(ffs) == FFS_SETUP_CANCELLED) {
++              if (ffs_setup_state_clear_cancelled(ffs) ==
++                  FFS_SETUP_CANCELLED) {
+                       ret = -EIDRM;
+                       break;
+               }
+diff --git a/drivers/usb/gadget/u_fs.h b/drivers/usb/gadget/u_fs.h
+index 38012bc..78263cc 100644
+--- a/drivers/usb/gadget/u_fs.h
++++ b/drivers/usb/gadget/u_fs.h
+@@ -172,13 +172,12 @@ struct ffs_data {
+        *               happens only in ep0 i/o  which is P: mutex
+        * + FFS_SETUP_PENDING   -> FFS_SETUP_CANCELLED -- P: ev.waitq.lock
+        * + FFS_SETUP_CANCELLED -> FFS_NO_SETUP        -- cmpxchg
++       *
++       * This field should never be accessed directly and instead
++       * ffs_setup_state_clear_cancelled function should be used.
+        */
+       enum ffs_setup_state            setup_state;
+-#define FFS_SETUP_STATE(ffs)                                  \
+-      ((enum ffs_setup_state)cmpxchg(&(ffs)->setup_state,     \
+-                                     FFS_SETUP_CANCELLED, FFS_NO_SETUP))
+-
+       /* Events & such. */
+       struct {
+               u8                              types[4];
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1214-usb-gadget-f_fs-fix-setup-request-handling.patch b/patches.tizen/1214-usb-gadget-f_fs-fix-setup-request-handling.patch
new file mode 100644 (file)
index 0000000..a328449
--- /dev/null
@@ -0,0 +1,47 @@
+From e3e86eb3680ca70c21d13a25ceb4370d9501c788 Mon Sep 17 00:00:00 2001
+From: Robert Baldyga <r.baldyga@samsung.com>
+Date: Mon, 10 Feb 2014 10:42:42 +0100
+Subject: [PATCH 1214/1302] usb: gadget: f_fs: fix setup request handling
+
+This patch fixes __ffs_ep0_queue_wait() function, which now returns number of
+bytes transferred in USB request or error code in case of failure. This is
+needed by ffs_ep0_read() function, when read data is copied to userspace.
+
+It also cleans up code by removing usused variable ep0req_status.
+
+Signed-off-by: Robert Baldyga <r.baldyga@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_fs.c | 2 +-
+ drivers/usb/gadget/u_fs.h | 1 -
+ 2 files changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
+index 169067c..849a095 100644
+--- a/drivers/usb/gadget/f_fs.c
++++ b/drivers/usb/gadget/f_fs.c
+@@ -228,7 +228,7 @@ static int __ffs_ep0_queue_wait(struct ffs_data *ffs, char *data, size_t len)
+       }
+       ffs->setup_state = FFS_NO_SETUP;
+-      return ffs->ep0req_status;
++      return req->status ? req->status : req->actual;
+ }
+ static int __ffs_ep0_stall(struct ffs_data *ffs)
+diff --git a/drivers/usb/gadget/u_fs.h b/drivers/usb/gadget/u_fs.h
+index 78263cc..c39e805 100644
+--- a/drivers/usb/gadget/u_fs.h
++++ b/drivers/usb/gadget/u_fs.h
+@@ -154,7 +154,6 @@ struct ffs_data {
+        */
+       struct usb_request              *ep0req;                /* P: mutex */
+       struct completion               ep0req_completion;      /* P: mutex */
+-      int                             ep0req_status;          /* P: mutex */
+       /* reference counter */
+       atomic_t                        ref;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1215-usb-gadget-f_fs-add-poll-for-endpoint-0.patch b/patches.tizen/1215-usb-gadget-f_fs-add-poll-for-endpoint-0.patch
new file mode 100644 (file)
index 0000000..c485f09
--- /dev/null
@@ -0,0 +1,92 @@
+From b82afb0ea71ab41e32c624d0841d993400f20389 Mon Sep 17 00:00:00 2001
+From: Robert Baldyga <r.baldyga@samsung.com>
+Date: Mon, 10 Feb 2014 10:42:43 +0100
+Subject: [PATCH 1215/1302] usb: gadget: f_fs: add poll for endpoint 0
+
+This patch adds poll function for file representing ep0.
+
+Ability of read from or write to ep0 file is related with actual state of ffs:
+- When desctiptors or strings are not written yet, POLLOUT flag is set.
+- If there is any event to read, POLLIN flag is set.
+- If setup request was read, POLLIN and POLLOUT flag is set, to allow
+  send response (by performing I/O operation consistent with setup request
+  direction) or set stall (by performing I/O operation opposite  setup
+  request direction).
+
+Signed-off-by: Robert Baldyga <r.baldyga@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_fs.c | 42 ++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 42 insertions(+)
+
+diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
+index 849a095..2a75601 100644
+--- a/drivers/usb/gadget/f_fs.c
++++ b/drivers/usb/gadget/f_fs.c
+@@ -28,6 +28,8 @@
+ #include <linux/usb/composite.h>
+ #include <linux/usb/functionfs.h>
++#include <linux/poll.h>
++
+ #include "u_fs.h"
+ #include "configfs.h"
+@@ -570,6 +572,45 @@ static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value)
+       return ret;
+ }
++static unsigned int ffs_ep0_poll(struct file *file, poll_table *wait)
++{
++      struct ffs_data *ffs = file->private_data;
++      unsigned int mask = POLLWRNORM;
++      int ret;
++
++      poll_wait(file, &ffs->ev.waitq, wait);
++
++      ret = ffs_mutex_lock(&ffs->mutex, file->f_flags & O_NONBLOCK);
++      if (unlikely(ret < 0))
++              return mask;
++
++      switch (ffs->state) {
++      case FFS_READ_DESCRIPTORS:
++      case FFS_READ_STRINGS:
++              mask |= POLLOUT;
++              break;
++
++      case FFS_ACTIVE:
++              switch (ffs->setup_state) {
++              case FFS_NO_SETUP:
++                      if (ffs->ev.count)
++                              mask |= POLLIN;
++                      break;
++
++              case FFS_SETUP_PENDING:
++              case FFS_SETUP_CANCELLED:
++                      mask |= (POLLIN | POLLOUT);
++                      break;
++              }
++      case FFS_CLOSING:
++              break;
++      }
++
++      mutex_unlock(&ffs->mutex);
++
++      return mask;
++}
++
+ static const struct file_operations ffs_ep0_operations = {
+       .llseek =       no_llseek,
+@@ -578,6 +619,7 @@ static const struct file_operations ffs_ep0_operations = {
+       .read =         ffs_ep0_read,
+       .release =      ffs_ep0_release,
+       .unlocked_ioctl =       ffs_ep0_ioctl,
++      .poll =         ffs_ep0_poll,
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1216-usb-gadget-f_fs-add-aio-support.patch b/patches.tizen/1216-usb-gadget-f_fs-add-aio-support.patch
new file mode 100644 (file)
index 0000000..f54dc9e
--- /dev/null
@@ -0,0 +1,397 @@
+From 02a2285739334e267f13df5f066321e6c4e5c009 Mon Sep 17 00:00:00 2001
+From: Robert Baldyga <r.baldyga@samsung.com>
+Date: Mon, 10 Feb 2014 10:42:44 +0100
+Subject: [PATCH 1216/1302] usb: gadget: f_fs: add aio support
+
+This patch adds asynchronous I/O support for FunctionFS endpoint files.
+It adds ffs_epfile_aio_write() and ffs_epfile_aio_read() functions responsible
+for preparing AIO operations.
+
+It also modifies ffs_epfile_io() function, adding aio handling code. Instead
+of extending list of parameters of this function, there is new struct
+ffs_io_data which contains all information needed to perform I/O operation.
+Pointer to this struct replaces "buf" and "len" parameters of ffs_epfile_io()
+function. Allocated buffer is freed immediately only after sync operation,
+because in async IO it's freed in complete funcion. For each async operation
+an USB request is allocated, because it allows to have more than one request
+queued on single endpoint.
+
+According to changes in ffs_epfile_io() function, functions ffs_epfile_write()
+and ffs_epfile_read() are updated to use new API.
+
+For asynchronous I/O operations there is new request complete function named
+ffs_epfile_async_io_complete(), which completes AIO operation, and frees
+used memory.
+
+Signed-off-by: Robert Baldyga <r.baldyga@samsung.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/f_fs.c | 265 +++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 239 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
+index 2a75601..ffc41e4 100644
+--- a/drivers/usb/gadget/f_fs.c
++++ b/drivers/usb/gadget/f_fs.c
+@@ -28,6 +28,8 @@
+ #include <linux/usb/composite.h>
+ #include <linux/usb/functionfs.h>
++#include <linux/aio.h>
++#include <linux/mmu_context.h>
+ #include <linux/poll.h>
+ #include "u_fs.h"
+@@ -158,6 +160,25 @@ struct ffs_epfile {
+       unsigned char                   _pad;
+ };
++/*  ffs_io_data structure ***************************************************/
++
++struct ffs_io_data {
++      bool aio;
++      bool read;
++
++      struct kiocb *kiocb;
++      const struct iovec *iovec;
++      unsigned long nr_segs;
++      char __user *buf;
++      size_t len;
++
++      struct mm_struct *mm;
++      struct work_struct work;
++
++      struct usb_ep *ep;
++      struct usb_request *req;
++};
++
+ static int  __must_check ffs_epfiles_create(struct ffs_data *ffs);
+ static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count);
+@@ -635,8 +656,52 @@ static void ffs_epfile_io_complete(struct usb_ep *_ep, struct usb_request *req)
+       }
+ }
+-static ssize_t ffs_epfile_io(struct file *file,
+-                           char __user *buf, size_t len, int read)
++static void ffs_user_copy_worker(struct work_struct *work)
++{
++      struct ffs_io_data *io_data = container_of(work, struct ffs_io_data,
++                                                 work);
++      int ret = io_data->req->status ? io_data->req->status :
++                                       io_data->req->actual;
++
++      if (io_data->read && ret > 0) {
++              int i;
++              size_t pos = 0;
++              use_mm(io_data->mm);
++              for (i = 0; i < io_data->nr_segs; i++) {
++                      if (unlikely(copy_to_user(io_data->iovec[i].iov_base,
++                                               &io_data->buf[pos],
++                                               io_data->iovec[i].iov_len))) {
++                              ret = -EFAULT;
++                              break;
++                      }
++                      pos += io_data->iovec[i].iov_len;
++              }
++              unuse_mm(io_data->mm);
++      }
++
++      aio_complete(io_data->kiocb, ret, ret);
++
++      usb_ep_free_request(io_data->ep, io_data->req);
++
++      io_data->kiocb->private = NULL;
++      if (io_data->read)
++              kfree(io_data->iovec);
++      kfree(io_data->buf);
++      kfree(io_data);
++}
++
++static void ffs_epfile_async_io_complete(struct usb_ep *_ep,
++                                       struct usb_request *req)
++{
++      struct ffs_io_data *io_data = req->context;
++
++      ENTER();
++
++      INIT_WORK(&io_data->work, ffs_user_copy_worker);
++      schedule_work(&io_data->work);
++}
++
++static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
+ {
+       struct ffs_epfile *epfile = file->private_data;
+       struct ffs_ep *ep;
+@@ -666,7 +731,7 @@ static ssize_t ffs_epfile_io(struct file *file,
+       }
+       /* Do we halt? */
+-      halt = !read == !epfile->in;
++      halt = (!io_data->read == !epfile->in);
+       if (halt && epfile->isoc) {
+               ret = -EINVAL;
+               goto error;
+@@ -684,15 +749,32 @@ static ssize_t ffs_epfile_io(struct file *file,
+                * Controller may require buffer size to be aligned to
+                * maxpacketsize of an out endpoint.
+                */
+-              data_len = read ? usb_ep_align_maybe(gadget, ep->ep, len) : len;
++              data_len = io_data->read ?
++                         usb_ep_align_maybe(gadget, ep->ep, io_data->len) :
++                         io_data->len;
+               data = kmalloc(data_len, GFP_KERNEL);
+               if (unlikely(!data))
+                       return -ENOMEM;
+-
+-              if (!read && unlikely(copy_from_user(data, buf, len))) {
+-                      ret = -EFAULT;
+-                      goto error;
++              if (io_data->aio && !io_data->read) {
++                      int i;
++                      size_t pos = 0;
++                      for (i = 0; i < io_data->nr_segs; i++) {
++                              if (unlikely(copy_from_user(&data[pos],
++                                           io_data->iovec[i].iov_base,
++                                           io_data->iovec[i].iov_len))) {
++                                      ret = -EFAULT;
++                                      goto error;
++                              }
++                              pos += io_data->iovec[i].iov_len;
++                      }
++              } else {
++                      if (!io_data->read &&
++                          unlikely(__copy_from_user(data, io_data->buf,
++                                                    io_data->len))) {
++                              ret = -EFAULT;
++                              goto error;
++                      }
+               }
+       }
+@@ -715,24 +797,52 @@ static ssize_t ffs_epfile_io(struct file *file,
+               ret = -EBADMSG;
+       } else {
+               /* Fire the request */
+-              DECLARE_COMPLETION_ONSTACK(done);
++              struct usb_request *req;
+-              struct usb_request *req = ep->req;
+-              req->context  = &done;
+-              req->complete = ffs_epfile_io_complete;
+-              req->buf      = data;
+-              req->length   = data_len;
++              if (io_data->aio) {
++                      req = usb_ep_alloc_request(ep->ep, GFP_KERNEL);
++                      if (unlikely(!req))
++                              goto error;
+-              ret = usb_ep_queue(ep->ep, req, GFP_ATOMIC);
++                      req->buf      = data;
++                      req->length   = io_data->len;
+-              spin_unlock_irq(&epfile->ffs->eps_lock);
++                      io_data->buf = data;
++                      io_data->ep = ep->ep;
++                      io_data->req = req;
+-              if (unlikely(ret < 0)) {
+-                      /* nop */
+-              } else if (unlikely(wait_for_completion_interruptible(&done))) {
+-                      ret = -EINTR;
+-                      usb_ep_dequeue(ep->ep, req);
++                      req->context  = io_data;
++                      req->complete = ffs_epfile_async_io_complete;
++
++                      ret = usb_ep_queue(ep->ep, req, GFP_ATOMIC);
++                      if (unlikely(ret)) {
++                              usb_ep_free_request(ep->ep, req);
++                              goto error;
++                      }
++                      ret = -EIOCBQUEUED;
++
++                      spin_unlock_irq(&epfile->ffs->eps_lock);
+               } else {
++                      DECLARE_COMPLETION_ONSTACK(done);
++
++                      req = ep->req;
++                      req->buf      = data;
++                      req->length   = io_data->len;
++
++                      req->context  = &done;
++                      req->complete = ffs_epfile_io_complete;
++
++                      ret = usb_ep_queue(ep->ep, req, GFP_ATOMIC);
++
++                      spin_unlock_irq(&epfile->ffs->eps_lock);
++
++                      if (unlikely(ret < 0)) {
++                              /* nop */
++                      } else if (unlikely(
++                                 wait_for_completion_interruptible(&done))) {
++                              ret = -EINTR;
++                              usb_ep_dequeue(ep->ep, req);
++                      } else {
+                       /*
+                        * XXX We may end up silently droping data here.
+                        * Since data_len (i.e. req->length) may be bigger
+@@ -741,14 +851,18 @@ static ssize_t ffs_epfile_io(struct file *file,
+                        * space for.
+                        */
+                       ret = ep->status;
+-                      if (read && ret > 0 &&
+-                          unlikely(copy_to_user(buf, data,
+-                                                min_t(size_t, ret, len))))
++                      if (io_data->read && ret > 0 &&
++                          unlikely(copy_to_user(io_data->buf, data,
++                                                min_t(size_t, ret,
++                                                io_data->len))))
+                               ret = -EFAULT;
++                      }
++                      kfree(data);
+               }
+       }
+       mutex_unlock(&epfile->mutex);
++      return ret;
+ error:
+       kfree(data);
+       return ret;
+@@ -758,17 +872,31 @@ static ssize_t
+ ffs_epfile_write(struct file *file, const char __user *buf, size_t len,
+                loff_t *ptr)
+ {
++      struct ffs_io_data io_data;
++
+       ENTER();
+-      return ffs_epfile_io(file, (char __user *)buf, len, 0);
++      io_data.aio = false;
++      io_data.read = false;
++      io_data.buf = (char * __user)buf;
++      io_data.len = len;
++
++      return ffs_epfile_io(file, &io_data);
+ }
+ static ssize_t
+ ffs_epfile_read(struct file *file, char __user *buf, size_t len, loff_t *ptr)
+ {
++      struct ffs_io_data io_data;
++
+       ENTER();
+-      return ffs_epfile_io(file, buf, len, 1);
++      io_data.aio = false;
++      io_data.read = true;
++      io_data.buf = buf;
++      io_data.len = len;
++
++      return ffs_epfile_io(file, &io_data);
+ }
+ static int
+@@ -787,6 +915,89 @@ ffs_epfile_open(struct inode *inode, struct file *file)
+       return 0;
+ }
++static int ffs_aio_cancel(struct kiocb *kiocb)
++{
++      struct ffs_io_data *io_data = kiocb->private;
++      struct ffs_epfile *epfile = kiocb->ki_filp->private_data;
++      int value;
++
++      ENTER();
++
++      spin_lock_irq(&epfile->ffs->eps_lock);
++
++      if (likely(io_data && io_data->ep && io_data->req))
++              value = usb_ep_dequeue(io_data->ep, io_data->req);
++      else
++              value = -EINVAL;
++
++      spin_unlock_irq(&epfile->ffs->eps_lock);
++
++      return value;
++}
++
++static ssize_t ffs_epfile_aio_write(struct kiocb *kiocb,
++                                  const struct iovec *iovec,
++                                  unsigned long nr_segs, loff_t loff)
++{
++      struct ffs_io_data *io_data;
++
++      ENTER();
++
++      io_data = kmalloc(sizeof(*io_data), GFP_KERNEL);
++      if (unlikely(!io_data))
++              return -ENOMEM;
++
++      io_data->aio = true;
++      io_data->read = false;
++      io_data->kiocb = kiocb;
++      io_data->iovec = iovec;
++      io_data->nr_segs = nr_segs;
++      io_data->len = kiocb->ki_nbytes;
++      io_data->mm = current->mm;
++
++      kiocb->private = io_data;
++
++      kiocb_set_cancel_fn(kiocb, ffs_aio_cancel);
++
++      return ffs_epfile_io(kiocb->ki_filp, io_data);
++}
++
++static ssize_t ffs_epfile_aio_read(struct kiocb *kiocb,
++                                 const struct iovec *iovec,
++                                 unsigned long nr_segs, loff_t loff)
++{
++      struct ffs_io_data *io_data;
++      struct iovec *iovec_copy;
++
++      ENTER();
++
++      iovec_copy = kmalloc_array(nr_segs, sizeof(*iovec_copy), GFP_KERNEL);
++      if (unlikely(!iovec_copy))
++              return -ENOMEM;
++
++      memcpy(iovec_copy, iovec, sizeof(struct iovec)*nr_segs);
++
++      io_data = kmalloc(sizeof(*io_data), GFP_KERNEL);
++      if (unlikely(!io_data)) {
++              kfree(iovec_copy);
++              return -ENOMEM;
++      }
++
++      io_data->aio = true;
++      io_data->read = true;
++      io_data->kiocb = kiocb;
++      io_data->iovec = iovec_copy;
++      io_data->nr_segs = nr_segs;
++      io_data->len = kiocb->ki_nbytes;
++      io_data->mm = current->mm;
++
++      kiocb->private = io_data;
++
++      kiocb_set_cancel_fn(kiocb, ffs_aio_cancel);
++
++      return ffs_epfile_io(kiocb->ki_filp, io_data);
++}
++
+ static int
+ ffs_epfile_release(struct inode *inode, struct file *file)
+ {
+@@ -843,6 +1054,8 @@ static const struct file_operations ffs_epfile_operations = {
+       .open =         ffs_epfile_open,
+       .write =        ffs_epfile_write,
+       .read =         ffs_epfile_read,
++      .aio_write =    ffs_epfile_aio_write,
++      .aio_read =     ffs_epfile_aio_read,
+       .release =      ffs_epfile_release,
+       .unlocked_ioctl =       ffs_epfile_ioctl,
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1217-tools-usb-aio-example-applications.patch b/patches.tizen/1217-tools-usb-aio-example-applications.patch
new file mode 100644 (file)
index 0000000..818f51d
--- /dev/null
@@ -0,0 +1,1073 @@
+From 8417c3d096a607df4af07c3cc433c28c958606de Mon Sep 17 00:00:00 2001
+From: Robert Baldyga <r.baldyga@samsung.com>
+Date: Tue, 11 Feb 2014 11:43:03 +0100
+Subject: [PATCH 1217/1302] tools: usb: aio example applications
+
+This patch adds two example applications showing usage of Asynchronous I/O API
+of FunctionFS. First one (aio_simple) is simple example of bidirectional data
+transfer. Second one (aio_multibuff) shows multi-buffer data transfer, which
+may to be used in high performance applications.
+
+Both examples contains userspace applications for device and for host.
+It needs libaio library on the device, and libusb library on host.
+
+Signed-off-by: Robert Baldyga <r.baldyga@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ .../multibuff/device_app/aio_multibuff.c           | 349 +++++++++++++++++++++
+ .../ffs-aio-example/multibuff/host_app/Makefile    |  13 +
+ .../usb/ffs-aio-example/multibuff/host_app/test.c  | 146 +++++++++
+ .../ffs-aio-example/simple/device_app/aio_simple.c | 335 ++++++++++++++++++++
+ tools/usb/ffs-aio-example/simple/host_app/Makefile |  13 +
+ tools/usb/ffs-aio-example/simple/host_app/test.c   | 148 +++++++++
+ 6 files changed, 1004 insertions(+)
+ create mode 100644 tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c
+ create mode 100644 tools/usb/ffs-aio-example/multibuff/host_app/Makefile
+ create mode 100644 tools/usb/ffs-aio-example/multibuff/host_app/test.c
+ create mode 100644 tools/usb/ffs-aio-example/simple/device_app/aio_simple.c
+ create mode 100644 tools/usb/ffs-aio-example/simple/host_app/Makefile
+ create mode 100644 tools/usb/ffs-aio-example/simple/host_app/test.c
+
+diff --git a/tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c b/tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c
+new file mode 100644
+index 0000000..87216a0
+--- /dev/null
++++ b/tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c
+@@ -0,0 +1,349 @@
++#define _BSD_SOURCE /* for endian.h */
++
++#include <endian.h>
++#include <errno.h>
++#include <fcntl.h>
++#include <stdarg.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <sys/ioctl.h>
++#include <sys/stat.h>
++#include <sys/types.h>
++#include <sys/poll.h>
++#include <unistd.h>
++#include <stdbool.h>
++#include <sys/eventfd.h>
++
++#include "libaio.h"
++#define IOCB_FLAG_RESFD         (1 << 0)
++
++#include <linux/usb/functionfs.h>
++
++#define BUF_LEN               8192
++#define BUFS_MAX      128
++#define AIO_MAX               (BUFS_MAX*2)
++
++/******************** Descriptors and Strings *******************************/
++
++static const struct {
++      struct usb_functionfs_descs_head header;
++      struct {
++              struct usb_interface_descriptor intf;
++              struct usb_endpoint_descriptor_no_audio bulk_sink;
++              struct usb_endpoint_descriptor_no_audio bulk_source;
++      } __attribute__ ((__packed__)) fs_descs, hs_descs;
++} __attribute__ ((__packed__)) descriptors = {
++      .header = {
++              .magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC),
++              .length = htole32(sizeof(descriptors)),
++              .fs_count = 3,
++              .hs_count = 3,
++      },
++      .fs_descs = {
++              .intf = {
++                      .bLength = sizeof(descriptors.fs_descs.intf),
++                      .bDescriptorType = USB_DT_INTERFACE,
++                      .bNumEndpoints = 2,
++                      .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
++                      .iInterface = 1,
++              },
++              .bulk_sink = {
++                      .bLength = sizeof(descriptors.fs_descs.bulk_sink),
++                      .bDescriptorType = USB_DT_ENDPOINT,
++                      .bEndpointAddress = 1 | USB_DIR_IN,
++                      .bmAttributes = USB_ENDPOINT_XFER_BULK,
++              },
++              .bulk_source = {
++                      .bLength = sizeof(descriptors.fs_descs.bulk_source),
++                      .bDescriptorType = USB_DT_ENDPOINT,
++                      .bEndpointAddress = 2 | USB_DIR_OUT,
++                      .bmAttributes = USB_ENDPOINT_XFER_BULK,
++              },
++      },
++      .hs_descs = {
++              .intf = {
++                      .bLength = sizeof(descriptors.hs_descs.intf),
++                      .bDescriptorType = USB_DT_INTERFACE,
++                      .bNumEndpoints = 2,
++                      .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
++                      .iInterface = 1,
++              },
++              .bulk_sink = {
++                      .bLength = sizeof(descriptors.hs_descs.bulk_sink),
++                      .bDescriptorType = USB_DT_ENDPOINT,
++                      .bEndpointAddress = 1 | USB_DIR_IN,
++                      .bmAttributes = USB_ENDPOINT_XFER_BULK,
++                      .wMaxPacketSize = htole16(512),
++              },
++              .bulk_source = {
++                      .bLength = sizeof(descriptors.hs_descs.bulk_source),
++                      .bDescriptorType = USB_DT_ENDPOINT,
++                      .bEndpointAddress = 2 | USB_DIR_OUT,
++                      .bmAttributes = USB_ENDPOINT_XFER_BULK,
++                      .wMaxPacketSize = htole16(512),
++              },
++      },
++};
++
++#define STR_INTERFACE "AIO Test"
++
++static const struct {
++      struct usb_functionfs_strings_head header;
++      struct {
++              __le16 code;
++              const char str1[sizeof(STR_INTERFACE)];
++      } __attribute__ ((__packed__)) lang0;
++} __attribute__ ((__packed__)) strings = {
++      .header = {
++              .magic = htole32(FUNCTIONFS_STRINGS_MAGIC),
++              .length = htole32(sizeof(strings)),
++              .str_count = htole32(1),
++              .lang_count = htole32(1),
++      },
++      .lang0 = {
++              htole16(0x0409), /* en-us */
++              STR_INTERFACE,
++      },
++};
++
++/********************** Buffer structure *******************************/
++
++struct io_buffer {
++      struct iocb **iocb;
++      unsigned char **buf;
++      unsigned cnt;
++      unsigned len;
++      unsigned requested;
++};
++
++/******************** Endpoints handling *******************************/
++
++static void display_event(struct usb_functionfs_event *event)
++{
++      static const char *const names[] = {
++              [FUNCTIONFS_BIND] = "BIND",
++              [FUNCTIONFS_UNBIND] = "UNBIND",
++              [FUNCTIONFS_ENABLE] = "ENABLE",
++              [FUNCTIONFS_DISABLE] = "DISABLE",
++              [FUNCTIONFS_SETUP] = "SETUP",
++              [FUNCTIONFS_SUSPEND] = "SUSPEND",
++              [FUNCTIONFS_RESUME] = "RESUME",
++      };
++      switch (event->type) {
++      case FUNCTIONFS_BIND:
++      case FUNCTIONFS_UNBIND:
++      case FUNCTIONFS_ENABLE:
++      case FUNCTIONFS_DISABLE:
++      case FUNCTIONFS_SETUP:
++      case FUNCTIONFS_SUSPEND:
++      case FUNCTIONFS_RESUME:
++              printf("Event %s\n", names[event->type]);
++      }
++}
++
++static void handle_ep0(int ep0, bool *ready)
++{
++      int ret;
++      struct usb_functionfs_event event;
++
++      ret = read(ep0, &event, sizeof(event));
++      if (!ret) {
++              perror("unable to read event from ep0");
++              return;
++      }
++      display_event(&event);
++      switch (event.type) {
++      case FUNCTIONFS_SETUP:
++              if (event.u.setup.bRequestType & USB_DIR_IN)
++                      write(ep0, NULL, 0);
++              else
++                      read(ep0, NULL, 0);
++              break;
++
++      case FUNCTIONFS_ENABLE:
++              *ready = true;
++              break;
++
++      case FUNCTIONFS_DISABLE:
++              *ready = false;
++              break;
++
++      default:
++              break;
++      }
++}
++
++void init_bufs(struct io_buffer *iobuf, unsigned n, unsigned len)
++{
++      unsigned i;
++      iobuf->buf = malloc(n*sizeof(*iobuf->buf));
++      iobuf->iocb = malloc(n*sizeof(*iobuf->iocb));
++      iobuf->cnt = n;
++      iobuf->len = len;
++      iobuf->requested = 0;
++      for (i = 0; i < n; ++i) {
++              iobuf->buf[i] = malloc(len*sizeof(**iobuf->buf));
++              iobuf->iocb[i] = malloc(sizeof(**iobuf->iocb));
++      }
++      iobuf->cnt = n;
++}
++
++void delete_bufs(struct io_buffer *iobuf)
++{
++      unsigned i;
++      for (i = 0; i < iobuf->cnt; ++i) {
++              free(iobuf->buf[i]);
++              free(iobuf->iocb[i]);
++      }
++      free(iobuf->buf);
++      free(iobuf->iocb);
++}
++
++int main(int argc, char *argv[])
++{
++      int ret;
++      unsigned i, j;
++      char *ep_path;
++
++      int ep0, ep1;
++
++      io_context_t ctx;
++
++      int evfd;
++      fd_set rfds;
++
++      struct io_buffer iobuf[2];
++      int actual = 0;
++      bool ready;
++
++      if (argc != 2) {
++              printf("ffs directory not specified!\n");
++              return 1;
++      }
++
++      ep_path = malloc(strlen(argv[1]) + 4 /* "/ep#" */ + 1 /* '\0' */);
++      if (!ep_path) {
++              perror("malloc");
++              return 1;
++      }
++
++      /* open endpoint files */
++      sprintf(ep_path, "%s/ep0", argv[1]);
++      ep0 = open(ep_path, O_RDWR);
++      if (ep0 < 0) {
++              perror("unable to open ep0");
++              return 1;
++      }
++      if (write(ep0, &descriptors, sizeof(descriptors)) < 0) {
++              perror("unable do write descriptors");
++              return 1;
++      }
++      if (write(ep0, &strings, sizeof(strings)) < 0) {
++              perror("unable to write strings");
++              return 1;
++      }
++      sprintf(ep_path, "%s/ep1", argv[1]);
++      ep1 = open(ep_path, O_RDWR);
++      if (ep1 < 0) {
++              perror("unable to open ep1");
++              return 1;
++      }
++
++      free(ep_path);
++
++      memset(&ctx, 0, sizeof(ctx));
++      /* setup aio context to handle up to AIO_MAX requests */
++      if (io_setup(AIO_MAX, &ctx) < 0) {
++              perror("unable to setup aio");
++              return 1;
++      }
++
++      evfd = eventfd(0, 0);
++      if (evfd < 0) {
++              perror("unable to open eventfd");
++              return 1;
++      }
++
++      for (i = 0; i < sizeof(iobuf)/sizeof(*iobuf); ++i)
++              init_bufs(&iobuf[i], BUFS_MAX, BUF_LEN);
++
++      while (1) {
++              FD_ZERO(&rfds);
++              FD_SET(ep0, &rfds);
++              FD_SET(evfd, &rfds);
++
++              ret = select(((ep0 > evfd) ? ep0 : evfd)+1,
++                           &rfds, NULL, NULL, NULL);
++              if (ret < 0) {
++                      if (errno == EINTR)
++                              continue;
++                      perror("select");
++                      break;
++              }
++
++              if (FD_ISSET(ep0, &rfds))
++                      handle_ep0(ep0, &ready);
++
++              /* we are waiting for function ENABLE */
++              if (!ready)
++                      continue;
++
++              /*
++               * when we're preparing new data to submit,
++               * second buffer being transmitted
++               */
++              for (i = 0; i < sizeof(iobuf)/sizeof(*iobuf); ++i) {
++                      if (iobuf[i].requested)
++                              continue;
++                      /* prepare requests */
++                      for (j = 0; j < iobuf[i].cnt; ++j) {
++                              io_prep_pwrite(iobuf[i].iocb[j], ep1,
++                                             iobuf[i].buf[j],
++                                             iobuf[i].len, 0);
++                              /* enable eventfd notification */
++                              iobuf[i].iocb[j]->u.c.flags |= IOCB_FLAG_RESFD;
++                              iobuf[i].iocb[j]->u.c.resfd = evfd;
++                      }
++                      /* submit table of requests */
++                      ret = io_submit(ctx, iobuf[i].cnt, iobuf[i].iocb);
++                      if (ret >= 0) {
++                              iobuf[i].requested = ret;
++                              printf("submit: %d requests buf: %d\n", ret, i);
++                      } else
++                              perror("unable to submit reqests");
++              }
++
++              /* if event is ready to read */
++              if (!FD_ISSET(evfd, &rfds))
++                      continue;
++
++              uint64_t ev_cnt;
++              ret = read(evfd, &ev_cnt, sizeof(ev_cnt));
++              if (ret < 0) {
++                      perror("unable to read eventfd");
++                      break;
++              }
++
++              struct io_event e[BUFS_MAX];
++              /* we read aio events */
++              ret = io_getevents(ctx, 1, BUFS_MAX, e, NULL);
++              if (ret > 0) /* if we got events */
++                      iobuf[actual].requested -= ret;
++
++              /* if all req's from iocb completed */
++              if (!iobuf[actual].requested)
++                      actual = (actual + 1)%(sizeof(iobuf)/sizeof(*iobuf));
++      }
++
++      /* free resources */
++
++      for (i = 0; i < sizeof(iobuf)/sizeof(*iobuf); ++i)
++              delete_bufs(&iobuf[i]);
++      io_destroy(ctx);
++
++      close(ep1);
++      close(ep0);
++
++      return 0;
++}
+diff --git a/tools/usb/ffs-aio-example/multibuff/host_app/Makefile b/tools/usb/ffs-aio-example/multibuff/host_app/Makefile
+new file mode 100644
+index 0000000..8c4a6f0
+--- /dev/null
++++ b/tools/usb/ffs-aio-example/multibuff/host_app/Makefile
+@@ -0,0 +1,13 @@
++CC = gcc
++LIBUSB_CFLAGS = $(shell pkg-config --cflags libusb-1.0)
++LIBUSB_LIBS = $(shell pkg-config --libs libusb-1.0)
++WARNINGS = -Wall -Wextra
++CFLAGS = $(LIBUSB_CFLAGS) $(WARNINGS)
++LDFLAGS = $(LIBUSB_LIBS)
++
++all: test
++%: %.c
++      $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
++
++clean:
++      $(RM) test
+diff --git a/tools/usb/ffs-aio-example/multibuff/host_app/test.c b/tools/usb/ffs-aio-example/multibuff/host_app/test.c
+new file mode 100644
+index 0000000..b0ad874
+--- /dev/null
++++ b/tools/usb/ffs-aio-example/multibuff/host_app/test.c
+@@ -0,0 +1,146 @@
++#include <libusb.h>
++#include <stdio.h>
++#include <string.h>
++#include <unistd.h>
++
++#define VENDOR        0x1d6b
++#define PRODUCT       0x0105
++
++/* endpoints indexes */
++
++#define EP_BULK_IN    (1 | LIBUSB_ENDPOINT_IN)
++#define EP_BULK_OUT   (2 | LIBUSB_ENDPOINT_OUT)
++
++#define BUF_LEN               8192
++
++/*
++ * struct test_state - describes test program state
++ * @list: list of devices returned by libusb_get_device_list function
++ * @found: pointer to struct describing tested device
++ * @ctx: context, set to NULL
++ * @handle: handle of tested device
++ * @attached: indicates that device was attached to kernel, and has to be
++ *            reattached at the end of test program
++ */
++
++struct test_state {
++      libusb_device *found;
++      libusb_context *ctx;
++      libusb_device_handle *handle;
++      int attached;
++};
++
++/*
++ * test_init - initialize test program
++ */
++
++int test_init(struct test_state *state)
++{
++      int i, ret;
++      ssize_t cnt;
++      libusb_device **list;
++
++      state->found = NULL;
++      state->ctx = NULL;
++      state->handle = NULL;
++      state->attached = 0;
++
++      ret = libusb_init(&state->ctx);
++      if (ret) {
++              printf("cannot init libusb: %s\n", libusb_error_name(ret));
++              return 1;
++      }
++
++      cnt = libusb_get_device_list(state->ctx, &list);
++      if (cnt <= 0) {
++              printf("no devices found\n");
++              goto error1;
++      }
++
++      for (i = 0; i < cnt; ++i) {
++              libusb_device *dev = list[i];
++              struct libusb_device_descriptor desc;
++              ret = libusb_get_device_descriptor(dev, &desc);
++              if (ret) {
++                      printf("unable to get device descriptor: %s\n",
++                             libusb_error_name(ret));
++                      goto error2;
++              }
++              if (desc.idVendor == VENDOR && desc.idProduct == PRODUCT) {
++                      state->found = dev;
++                      break;
++              }
++      }
++
++      if (!state->found) {
++              printf("no devices found\n");
++              goto error2;
++      }
++
++      ret = libusb_open(state->found, &state->handle);
++      if (ret) {
++              printf("cannot open device: %s\n", libusb_error_name(ret));
++              goto error2;
++      }
++
++      if (libusb_claim_interface(state->handle, 0)) {
++              ret = libusb_detach_kernel_driver(state->handle, 0);
++              if (ret) {
++                      printf("unable to detach kernel driver: %s\n",
++                             libusb_error_name(ret));
++                      goto error3;
++              }
++              state->attached = 1;
++              ret = libusb_claim_interface(state->handle, 0);
++              if (ret) {
++                      printf("cannot claim interface: %s\n",
++                             libusb_error_name(ret));
++                      goto error4;
++              }
++      }
++
++      return 0;
++
++error4:
++      if (state->attached == 1)
++              libusb_attach_kernel_driver(state->handle, 0);
++
++error3:
++      libusb_close(state->handle);
++
++error2:
++      libusb_free_device_list(list, 1);
++
++error1:
++      libusb_exit(state->ctx);
++      return 1;
++}
++
++/*
++ * test_exit - cleanup test program
++ */
++
++void test_exit(struct test_state *state)
++{
++      libusb_release_interface(state->handle, 0);
++      if (state->attached == 1)
++              libusb_attach_kernel_driver(state->handle, 0);
++      libusb_close(state->handle);
++      libusb_exit(state->ctx);
++}
++
++int main(void)
++{
++      struct test_state state;
++
++      if (test_init(&state))
++              return 1;
++
++      while (1) {
++              static unsigned char buffer[BUF_LEN];
++              int bytes;
++              libusb_bulk_transfer(state.handle, EP_BULK_IN, buffer, BUF_LEN,
++                                   &bytes, 500);
++      }
++      test_exit(&state);
++}
+diff --git a/tools/usb/ffs-aio-example/simple/device_app/aio_simple.c b/tools/usb/ffs-aio-example/simple/device_app/aio_simple.c
+new file mode 100644
+index 0000000..f558664
+--- /dev/null
++++ b/tools/usb/ffs-aio-example/simple/device_app/aio_simple.c
+@@ -0,0 +1,335 @@
++#define _BSD_SOURCE /* for endian.h */
++
++#include <endian.h>
++#include <errno.h>
++#include <fcntl.h>
++#include <stdarg.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <sys/ioctl.h>
++#include <sys/stat.h>
++#include <sys/types.h>
++#include <sys/poll.h>
++#include <unistd.h>
++#include <stdbool.h>
++#include <sys/eventfd.h>
++
++#include "libaio.h"
++#define IOCB_FLAG_RESFD         (1 << 0)
++
++#include <linux/usb/functionfs.h>
++
++#define BUF_LEN               8192
++
++/******************** Descriptors and Strings *******************************/
++
++static const struct {
++      struct usb_functionfs_descs_head header;
++      struct {
++              struct usb_interface_descriptor intf;
++              struct usb_endpoint_descriptor_no_audio bulk_sink;
++              struct usb_endpoint_descriptor_no_audio bulk_source;
++      } __attribute__ ((__packed__)) fs_descs, hs_descs;
++} __attribute__ ((__packed__)) descriptors = {
++      .header = {
++              .magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC),
++              .length = htole32(sizeof(descriptors)),
++              .fs_count = 3,
++              .hs_count = 3,
++      },
++      .fs_descs = {
++              .intf = {
++                      .bLength = sizeof(descriptors.fs_descs.intf),
++                      .bDescriptorType = USB_DT_INTERFACE,
++                      .bNumEndpoints = 2,
++                      .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
++                      .iInterface = 1,
++              },
++              .bulk_sink = {
++                      .bLength = sizeof(descriptors.fs_descs.bulk_sink),
++                      .bDescriptorType = USB_DT_ENDPOINT,
++                      .bEndpointAddress = 1 | USB_DIR_IN,
++                      .bmAttributes = USB_ENDPOINT_XFER_BULK,
++              },
++              .bulk_source = {
++                      .bLength = sizeof(descriptors.fs_descs.bulk_source),
++                      .bDescriptorType = USB_DT_ENDPOINT,
++                      .bEndpointAddress = 2 | USB_DIR_OUT,
++                      .bmAttributes = USB_ENDPOINT_XFER_BULK,
++              },
++      },
++      .hs_descs = {
++              .intf = {
++                      .bLength = sizeof(descriptors.hs_descs.intf),
++                      .bDescriptorType = USB_DT_INTERFACE,
++                      .bNumEndpoints = 2,
++                      .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
++                      .iInterface = 1,
++              },
++              .bulk_sink = {
++                      .bLength = sizeof(descriptors.hs_descs.bulk_sink),
++                      .bDescriptorType = USB_DT_ENDPOINT,
++                      .bEndpointAddress = 1 | USB_DIR_IN,
++                      .bmAttributes = USB_ENDPOINT_XFER_BULK,
++              },
++              .bulk_source = {
++                      .bLength = sizeof(descriptors.hs_descs.bulk_source),
++                      .bDescriptorType = USB_DT_ENDPOINT,
++                      .bEndpointAddress = 2 | USB_DIR_OUT,
++                      .bmAttributes = USB_ENDPOINT_XFER_BULK,
++              },
++      },
++};
++
++#define STR_INTERFACE "AIO Test"
++
++static const struct {
++      struct usb_functionfs_strings_head header;
++      struct {
++              __le16 code;
++              const char str1[sizeof(STR_INTERFACE)];
++      } __attribute__ ((__packed__)) lang0;
++} __attribute__ ((__packed__)) strings = {
++      .header = {
++              .magic = htole32(FUNCTIONFS_STRINGS_MAGIC),
++              .length = htole32(sizeof(strings)),
++              .str_count = htole32(1),
++              .lang_count = htole32(1),
++      },
++      .lang0 = {
++              htole16(0x0409), /* en-us */
++              STR_INTERFACE,
++      },
++};
++
++/******************** Endpoints handling *******************************/
++
++static void display_event(struct usb_functionfs_event *event)
++{
++      static const char *const names[] = {
++              [FUNCTIONFS_BIND] = "BIND",
++              [FUNCTIONFS_UNBIND] = "UNBIND",
++              [FUNCTIONFS_ENABLE] = "ENABLE",
++              [FUNCTIONFS_DISABLE] = "DISABLE",
++              [FUNCTIONFS_SETUP] = "SETUP",
++              [FUNCTIONFS_SUSPEND] = "SUSPEND",
++              [FUNCTIONFS_RESUME] = "RESUME",
++      };
++      switch (event->type) {
++      case FUNCTIONFS_BIND:
++      case FUNCTIONFS_UNBIND:
++      case FUNCTIONFS_ENABLE:
++      case FUNCTIONFS_DISABLE:
++      case FUNCTIONFS_SETUP:
++      case FUNCTIONFS_SUSPEND:
++      case FUNCTIONFS_RESUME:
++              printf("Event %s\n", names[event->type]);
++      }
++}
++
++static void handle_ep0(int ep0, bool *ready)
++{
++      struct usb_functionfs_event event;
++      int ret;
++
++      struct pollfd pfds[1];
++      pfds[0].fd = ep0;
++      pfds[0].events = POLLIN;
++
++      ret = poll(pfds, 1, 0);
++
++      if (ret && (pfds[0].revents & POLLIN)) {
++              ret = read(ep0, &event, sizeof(event));
++              if (!ret) {
++                      perror("unable to read event from ep0");
++                      return;
++              }
++              display_event(&event);
++              switch (event.type) {
++              case FUNCTIONFS_SETUP:
++                      if (event.u.setup.bRequestType & USB_DIR_IN)
++                              write(ep0, NULL, 0);
++                      else
++                              read(ep0, NULL, 0);
++                      break;
++
++              case FUNCTIONFS_ENABLE:
++                      *ready = true;
++                      break;
++
++              case FUNCTIONFS_DISABLE:
++                      *ready = false;
++                      break;
++
++              default:
++                      break;
++              }
++      }
++}
++
++int main(int argc, char *argv[])
++{
++      int i, ret;
++      char *ep_path;
++
++      int ep0;
++      int ep[2];
++
++      io_context_t ctx;
++
++      int evfd;
++      fd_set rfds;
++
++      char *buf_in, *buf_out;
++      struct iocb *iocb_in, *iocb_out;
++      int req_in = 0, req_out = 0;
++      bool ready;
++
++      if (argc != 2) {
++              printf("ffs directory not specified!\n");
++              return 1;
++      }
++
++      ep_path = malloc(strlen(argv[1]) + 4 /* "/ep#" */ + 1 /* '\0' */);
++      if (!ep_path) {
++              perror("malloc");
++              return 1;
++      }
++
++      /* open endpoint files */
++      sprintf(ep_path, "%s/ep0", argv[1]);
++      ep0 = open(ep_path, O_RDWR);
++      if (ep0 < 0) {
++              perror("unable to open ep0");
++              return 1;
++      }
++      if (write(ep0, &descriptors, sizeof(descriptors)) < 0) {
++              perror("unable do write descriptors");
++              return 1;
++      }
++      if (write(ep0, &strings, sizeof(strings)) < 0) {
++              perror("unable to write strings");
++              return 1;
++      }
++      for (i = 0; i < 2; ++i) {
++              sprintf(ep_path, "%s/ep%d", argv[1], i+1);
++              ep[i] = open(ep_path, O_RDWR);
++              if (ep[i] < 0) {
++                      printf("unable to open ep%d: %s\n", i+1,
++                             strerror(errno));
++                      return 1;
++              }
++      }
++
++      free(ep_path);
++
++      memset(&ctx, 0, sizeof(ctx));
++      /* setup aio context to handle up to 2 requests */
++      if (io_setup(2, &ctx) < 0) {
++              perror("unable to setup aio");
++              return 1;
++      }
++
++      evfd = eventfd(0, 0);
++      if (evfd < 0) {
++              perror("unable to open eventfd");
++              return 1;
++      }
++
++      /* alloc buffers and requests */
++      buf_in = malloc(BUF_LEN);
++      buf_out = malloc(BUF_LEN);
++      iocb_in = malloc(sizeof(*iocb_in));
++      iocb_out = malloc(sizeof(*iocb_out));
++
++      while (1) {
++              FD_ZERO(&rfds);
++              FD_SET(ep0, &rfds);
++              FD_SET(evfd, &rfds);
++
++              ret = select(((ep0 > evfd) ? ep0 : evfd)+1,
++                           &rfds, NULL, NULL, NULL);
++              if (ret < 0) {
++                      if (errno == EINTR)
++                              continue;
++                      perror("select");
++                      break;
++              }
++
++              if (FD_ISSET(ep0, &rfds))
++                      handle_ep0(ep0, &ready);
++
++              /* we are waiting for function ENABLE */
++              if (!ready)
++                      continue;
++
++              /* if something was submitted we wait for event */
++              if (FD_ISSET(evfd, &rfds)) {
++                      uint64_t ev_cnt;
++                      ret = read(evfd, &ev_cnt, sizeof(ev_cnt));
++                      if (ret < 0) {
++                              perror("unable to read eventfd");
++                              break;
++                      }
++
++                      struct io_event e[2];
++                      /* we wait for one event */
++                      ret = io_getevents(ctx, 1, 2, e, NULL);
++                      /* if we got event */
++                      for (i = 0; i < ret; ++i) {
++                              if (e[i].obj->aio_fildes == ep[0]) {
++                                      printf("ev=in; ret=%lu\n", e[i].res);
++                                      req_in = 0;
++                              } else if (e[i].obj->aio_fildes == ep[1]) {
++                                      printf("ev=out; ret=%lu\n", e[i].res);
++                                      req_out = 0;
++                              }
++                      }
++              }
++
++              if (!req_in) { /* if IN transfer not requested*/
++                      /* prepare write request */
++                      io_prep_pwrite(iocb_in, ep[0], buf_in, BUF_LEN, 0);
++                      /* enable eventfd notification */
++                      iocb_in->u.c.flags |= IOCB_FLAG_RESFD;
++                      iocb_in->u.c.resfd = evfd;
++                      /* submit table of requests */
++                      ret = io_submit(ctx, 1, &iocb_in);
++                      if (ret >= 0) { /* if ret > 0 request is queued */
++                              req_in = 1;
++                              printf("submit: in\n");
++                      } else
++                              perror("unable to submit request");
++              }
++              if (!req_out) { /* if OUT transfer not requested */
++                      /* prepare read request */
++                      io_prep_pread(iocb_out, ep[1], buf_out, BUF_LEN, 0);
++                      /* enable eventfs notification */
++                      iocb_out->u.c.flags |= IOCB_FLAG_RESFD;
++                      iocb_out->u.c.resfd = evfd;
++                      /* submit table of requests */
++                      ret = io_submit(ctx, 1, &iocb_out);
++                      if (ret >= 0) { /* if ret > 0 request is queued */
++                              req_out = 1;
++                              printf("submit: out\n");
++                      } else
++                              perror("unable to submit request");
++              }
++      }
++
++      /* free resources */
++
++      io_destroy(ctx);
++
++      free(buf_in);
++      free(buf_out);
++      free(iocb_in);
++      free(iocb_out);
++
++      for (i = 0; i < 2; ++i)
++              close(ep[i]);
++      close(ep0);
++
++      return 0;
++}
+diff --git a/tools/usb/ffs-aio-example/simple/host_app/Makefile b/tools/usb/ffs-aio-example/simple/host_app/Makefile
+new file mode 100644
+index 0000000..8c4a6f0
+--- /dev/null
++++ b/tools/usb/ffs-aio-example/simple/host_app/Makefile
+@@ -0,0 +1,13 @@
++CC = gcc
++LIBUSB_CFLAGS = $(shell pkg-config --cflags libusb-1.0)
++LIBUSB_LIBS = $(shell pkg-config --libs libusb-1.0)
++WARNINGS = -Wall -Wextra
++CFLAGS = $(LIBUSB_CFLAGS) $(WARNINGS)
++LDFLAGS = $(LIBUSB_LIBS)
++
++all: test
++%: %.c
++      $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
++
++clean:
++      $(RM) test
+diff --git a/tools/usb/ffs-aio-example/simple/host_app/test.c b/tools/usb/ffs-aio-example/simple/host_app/test.c
+new file mode 100644
+index 0000000..64b6a57
+--- /dev/null
++++ b/tools/usb/ffs-aio-example/simple/host_app/test.c
+@@ -0,0 +1,148 @@
++#include <libusb.h>
++#include <stdio.h>
++#include <string.h>
++#include <unistd.h>
++
++#define VENDOR        0x1d6b
++#define PRODUCT       0x0105
++
++/* endpoints indexes */
++
++#define EP_BULK_IN    (1 | LIBUSB_ENDPOINT_IN)
++#define EP_BULK_OUT   (2 | LIBUSB_ENDPOINT_OUT)
++
++#define BUF_LEN               8192
++
++/*
++ * struct test_state - describes test program state
++ * @list: list of devices returned by libusb_get_device_list function
++ * @found: pointer to struct describing tested device
++ * @ctx: context, set to NULL
++ * @handle: handle of tested device
++ * @attached: indicates that device was attached to kernel, and has to be
++ *            reattached at the end of test program
++ */
++
++struct test_state {
++      libusb_device *found;
++      libusb_context *ctx;
++      libusb_device_handle *handle;
++      int attached;
++};
++
++/*
++ * test_init - initialize test program
++ */
++
++int test_init(struct test_state *state)
++{
++      int i, ret;
++      ssize_t cnt;
++      libusb_device **list;
++
++      state->found = NULL;
++      state->ctx = NULL;
++      state->handle = NULL;
++      state->attached = 0;
++
++      ret = libusb_init(&state->ctx);
++      if (ret) {
++              printf("cannot init libusb: %s\n", libusb_error_name(ret));
++              return 1;
++      }
++
++      cnt = libusb_get_device_list(state->ctx, &list);
++      if (cnt <= 0) {
++              printf("no devices found\n");
++              goto error1;
++      }
++
++      for (i = 0; i < cnt; ++i) {
++              libusb_device *dev = list[i];
++              struct libusb_device_descriptor desc;
++              ret = libusb_get_device_descriptor(dev, &desc);
++              if (ret) {
++                      printf("unable to get device descriptor: %s\n",
++                             libusb_error_name(ret));
++                      goto error2;
++              }
++              if (desc.idVendor == VENDOR && desc.idProduct == PRODUCT) {
++                      state->found = dev;
++                      break;
++              }
++      }
++
++      if (!state->found) {
++              printf("no devices found\n");
++              goto error2;
++      }
++
++      ret = libusb_open(state->found, &state->handle);
++      if (ret) {
++              printf("cannot open device: %s\n", libusb_error_name(ret));
++              goto error2;
++      }
++
++      if (libusb_claim_interface(state->handle, 0)) {
++              ret = libusb_detach_kernel_driver(state->handle, 0);
++              if (ret) {
++                      printf("unable to detach kernel driver: %s\n",
++                             libusb_error_name(ret));
++                      goto error3;
++              }
++              state->attached = 1;
++              ret = libusb_claim_interface(state->handle, 0);
++              if (ret) {
++                      printf("cannot claim interface: %s\n",
++                             libusb_error_name(ret));
++                      goto error4;
++              }
++      }
++
++      return 0;
++
++error4:
++      if (state->attached == 1)
++              libusb_attach_kernel_driver(state->handle, 0);
++
++error3:
++      libusb_close(state->handle);
++
++error2:
++      libusb_free_device_list(list, 1);
++
++error1:
++      libusb_exit(state->ctx);
++      return 1;
++}
++
++/*
++ * test_exit - cleanup test program
++ */
++
++void test_exit(struct test_state *state)
++{
++      libusb_release_interface(state->handle, 0);
++      if (state->attached == 1)
++              libusb_attach_kernel_driver(state->handle, 0);
++      libusb_close(state->handle);
++      libusb_exit(state->ctx);
++}
++
++int main(void)
++{
++      struct test_state state;
++
++      if (test_init(&state))
++              return 1;
++
++      while (1) {
++              static unsigned char buffer[BUF_LEN];
++              int bytes;
++              libusb_bulk_transfer(state.handle, EP_BULK_IN, buffer, BUF_LEN,
++                                   &bytes, 500);
++              libusb_bulk_transfer(state.handle, EP_BULK_OUT, buffer, BUF_LEN,
++                                   &bytes, 500);
++      }
++      test_exit(&state);
++}
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1218-phy-Add-exynos-phy-driver.patch b/patches.tizen/1218-phy-Add-exynos-phy-driver.patch
new file mode 100644 (file)
index 0000000..ffae49c
--- /dev/null
@@ -0,0 +1,202 @@
+From 0801037a6e7c6b36eb56ff8be8515b2c639c873b Mon Sep 17 00:00:00 2001
+From: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Date: Mon, 30 Sep 2013 17:46:53 +0200
+Subject: [PATCH 1218/1302] phy: Add exynos-phy driver
+
+Add exynos-phy driver to support a single register
+PHY interfaces present on Exynos4 SoC.
+
+Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Change-Id: I1a2eeab876507e1e427fcb26782d060a1614852a
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/phy/Kconfig      |   5 ++
+ drivers/phy/Makefile     |   1 +
+ drivers/phy/exynos-phy.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 158 insertions(+)
+ create mode 100644 drivers/phy/exynos-phy.c
+
+diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
+index bf63eb8..62bd2cb 100644
+--- a/drivers/phy/Kconfig
++++ b/drivers/phy/Kconfig
+@@ -42,4 +42,9 @@ config PHY_EXYNOS4212_USB
+       help
+         Enable USB PHY support for Exynos 4212
+         
++config EXYNOS_PHY
++      tristate "Exynos PHY driver"
++      help
++        Support for PHY controllers on SoCs from Exynos family.
++
+ endmenu
+diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
+index d75f932..e56dd72 100644
+--- a/drivers/phy/Makefile
++++ b/drivers/phy/Makefile
+@@ -7,3 +7,4 @@ obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO)    += phy-exynos-mipi-video.o
+ obj-$(CONFIG_PHY_EXYNOS_USB)          += phy-exynos-usb.o
+ obj-$(CONFIG_PHY_EXYNOS4210_USB)      += phy-exynos4210-usb.o
+ obj-$(CONFIG_PHY_EXYNOS4212_USB)      += phy-exynos4212-usb.o
++obj-$(CONFIG_EXYNOS_PHY)      += exynos-phy.o
+diff --git a/drivers/phy/exynos-phy.c b/drivers/phy/exynos-phy.c
+new file mode 100644
+index 0000000..46d5603
+--- /dev/null
++++ b/drivers/phy/exynos-phy.c
+@@ -0,0 +1,152 @@
++/*
++ * Exynos PHY driver
++ *
++ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
++ * Author: Tomasz Stanislawski <t.stanislaws@samsung.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/io.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/of_device.h>
++#include <linux/phy/phy.h>
++
++#define EXYNOS_PHY_ENABLE     (1 << 0)
++
++static int exynos_phy_power_on(struct phy *phy)
++{
++      void __iomem *reg = phy_get_drvdata(phy);
++      u32 val;
++
++      val = readl(reg);
++      val |= EXYNOS_PHY_ENABLE;
++      writel(val, reg);
++
++      return 0;
++}
++
++static int exynos_phy_power_off(struct phy *phy)
++{
++      void __iomem *reg = phy_get_drvdata(phy);
++      u32 val;
++
++      val = readl(reg);
++      val &= ~EXYNOS_PHY_ENABLE;
++      writel(val, reg);
++
++      return 0;
++}
++
++static struct phy_ops exynos_phy_ops = {
++      .power_on       = exynos_phy_power_on,
++      .power_off      = exynos_phy_power_off,
++      .owner          = THIS_MODULE,
++};
++
++static const u32 exynos4210_offsets[] = {
++      0x0700, /* HDMI_PHY */
++      0x070C, /* DAC_PHY */
++      0x0718, /* ADC_PHY */
++      0x071C, /* PCIE_PHY */
++      0x0720, /* SATA_PHY */
++      ~0, /* end mark */
++};
++
++static const u32 exynos4412_offsets[] = {
++      0x0700, /* HDMI_PHY */
++      0x0718, /* ADC_PHY */
++      ~0, /* end mark */
++};
++
++static const struct of_device_id exynos_phy_of_match[] = {
++      { .compatible = "exynos4210-phy", .data = exynos4210_offsets},
++      { .compatible = "exynos4412-phy", .data = exynos4412_offsets},
++      { },
++};
++MODULE_DEVICE_TABLE(of, exynos_phy_of_match);
++
++static struct phy *exynos_phy_xlate(struct device *dev,
++                                      struct of_phandle_args *args)
++{
++      struct phy **phys = dev_get_drvdata(dev);
++      int index = args->args[0];
++      int i;
++
++      /* verify if index is valid */
++      for (i = 0; i <= index; ++i)
++              if (!phys[i])
++                      return ERR_PTR(-ENODEV);
++
++      return phys[index];
++}
++
++static int exynos_phy_probe(struct platform_device *pdev)
++{
++      const struct of_device_id *of_id = of_match_device(
++              of_match_ptr(exynos_phy_of_match), &pdev->dev);
++      const u32 *offsets = of_id->data;
++      int count;
++      struct device *dev = &pdev->dev;
++      struct phy **phys;
++      struct resource *res;
++      void __iomem *regs;
++      int i;
++      struct phy_provider *phy_provider;
++
++      /* count number of phys to create */
++      for (count = 0; offsets[count] != ~0; ++count)
++              ;
++
++      phys = devm_kzalloc(dev, (count + 1) * sizeof(phys[0]), GFP_KERNEL);
++      if (!phys)
++              return -ENOMEM;
++
++      dev_set_drvdata(dev, phys);
++      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++
++      regs = devm_ioremap(dev, res->start, res->end - res->start);
++      if (!regs) {
++              dev_err(dev, "failed to ioremap registers\n");
++              return -EFAULT;
++      }
++
++      /* NOTE: last entry in phys[] is NULL */
++      for (i = 0; i < count; ++i) {
++              phys[i] = devm_phy_create(dev, &exynos_phy_ops, NULL);
++              if (IS_ERR(phys[i])) {
++                      dev_err(dev, "failed to create PHY %d\n", i);
++                      return PTR_ERR(phys[i]);
++              }
++              phy_set_drvdata(phys[i], regs + offsets[i]);
++      }
++
++      phy_provider = devm_of_phy_provider_register(dev, exynos_phy_xlate);
++      if (IS_ERR(phy_provider)) {
++              dev_err(dev, "failed to register PHY provider\n");
++              return PTR_ERR(phy_provider);
++      }
++
++      dev_info(dev, "added %d phys\n", count);
++
++      return 0;
++}
++
++static struct platform_driver exynos_phy_driver = {
++      .probe  = exynos_phy_probe,
++      .driver = {
++              .of_match_table = exynos_phy_of_match,
++              .name  = "exynos-phy",
++              .owner = THIS_MODULE,
++      }
++};
++module_platform_driver(exynos_phy_driver);
++
++MODULE_DESCRIPTION("Exynos PHY driver");
++MODULE_AUTHOR("Tomasz Stanislawski <t.stanislaws@samsung.com>");
++MODULE_LICENSE("GPL v2");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1219-misc-add-sii9234-driver.patch b/patches.tizen/1219-misc-add-sii9234-driver.patch
new file mode 100644 (file)
index 0000000..89942c7
--- /dev/null
@@ -0,0 +1,1135 @@
+From 79061ffc69e811c1dc6f1cd897eafeee66d8a735 Mon Sep 17 00:00:00 2001
+From: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Date: Fri, 20 Dec 2013 12:30:43 +0100
+Subject: [PATCH 1219/1302] misc: add sii9234 driver
+
+Add driver for HDMI bridge usnig MHL connection.
+Contains refactored MHL driver developed by:
+
+Adam Hampson <ahampson@sta.samsung.com>
+Erik Gilling <konkers@android.com>
+Shankar Bandal <shankar.b@samsung.com>
+Dharam Kumar <dharam.kr@samsung.com>
+
+Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Change-Id: I7fed88ab786a4fef8fb97dca6c7336d11eb806c5
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/misc/Kconfig   |    8 +
+ drivers/misc/Makefile  |    1 +
+ drivers/misc/sii9234.c | 1075 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 1084 insertions(+)
+ create mode 100644 drivers/misc/sii9234.c
+
+diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
+index 0341677..28feeae 100644
+--- a/drivers/misc/Kconfig
++++ b/drivers/misc/Kconfig
+@@ -532,6 +532,14 @@ config SRAM
+         the genalloc API. It is supposed to be used for small on-chip SRAM
+         areas found on many SoCs.
++config SII9234
++      tristate "Silicon Image SII9234 Driver"
++      depends on I2C
++      help
++        Say Y here if you want support for the MHL interface.
++        It is an I2C driver, that detects connection of MHL bridge
++        and starts encapsulation of HDMI signal.
++
+ source "drivers/misc/c2port/Kconfig"
+ source "drivers/misc/eeprom/Kconfig"
+ source "drivers/misc/cb710/Kconfig"
+diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
+index 97e46bb..39807ac 100644
+--- a/drivers/misc/Makefile
++++ b/drivers/misc/Makefile
+@@ -55,3 +55,4 @@ obj-$(CONFIG_LATTICE_ECP3_CONFIG)    += lattice-ecp3-config.o
+ obj-$(CONFIG_SLP_GLOBAL_LOCK) += slp_global_lock.o
+ obj-$(CONFIG_SRAM)            += sram.o
+ obj-$(CONFIG_SEC_MODEM)               += modem_if/
++obj-$(CONFIG_SII9234)         += sii9234.o
+diff --git a/drivers/misc/sii9234.c b/drivers/misc/sii9234.c
+new file mode 100644
+index 0000000..8d051c4
+--- /dev/null
++++ b/drivers/misc/sii9234.c
+@@ -0,0 +1,1075 @@
++/*
++ * Copyright (C) 2014 Samsung Electronics
++ *
++ * Author: Tomasz Stanislawski <t.stanislaws@samsung.com>
++ *
++ * Based on sii9234 driver created by:
++ *    Adam Hampson <ahampson@sta.samsung.com>
++ *    Erik Gilling <konkers@android.com>
++ *    Shankar Bandal <shankar.b@samsung.com>
++ *    Dharam Kumar <dharam.kr@samsung.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
++ *
++ */
++
++#include <linux/delay.h>
++#include <linux/err.h>
++#include <linux/gpio.h>
++#include <linux/i2c.h>
++#include <linux/interrupt.h>
++#include <linux/irq.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/mutex.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++#include <linux/wait.h>
++#include <linux/file.h>
++#include <linux/uaccess.h>
++#include <linux/proc_fs.h>
++#include <linux/extcon.h>
++#include <linux/of.h>
++#include <linux/of_gpio.h>
++#include <linux/extcon/of_extcon.h>
++#include <linux/regulator/machine.h>
++
++/* MHL Tx registers and bits */
++#define MHL_TX_SRST                     0x05
++#define MHL_TX_SYSSTAT_REG              0x09
++#define         RSEN_STATUS             (1<<2)
++#define MHL_TX_INTR1_REG                0x71
++#define         HPD_CHANGE_INT          (1<<6)
++#define         RSEN_CHANGE_INT         (1<<5)
++#define MHL_TX_INTR4_REG                0x74
++#define         RGND_READY_INT          (1<<6)
++#define         VBUS_LOW_INT            (1<<5)
++#define         CBUS_LKOUT_INT          (1<<4)
++#define         MHL_DISC_FAIL_INT       (1<<3)
++#define         MHL_EST_INT             (1<<2)
++#define MHL_TX_INTR1_ENABLE_REG         0x75
++#define         HPD_CHANGE_INT_MASK     (1<<6)
++#define         RSEN_CHANGE_INT_MASK    (1<<5)
++#define MHL_TX_INTR4_ENABLE_REG         0x78
++#define         RGND_READY_MASK         (1<<6)
++#define         CBUS_LKOUT_MASK         (1<<4)
++#define         MHL_DISC_FAIL_MASK      (1<<3)
++#define         MHL_EST_MASK            (1<<2)
++#define MHL_TX_INT_CTRL_REG             0x79
++#define MHL_TX_TMDS_CCTRL               0x80
++#define MHL_TX_DISC_CTRL1_REG           0x90
++#define MHL_TX_DISC_CTRL2_REG           0x91
++#define         SKIP_GND                (1<<6)
++#define         ATT_THRESH_SHIFT        0x04
++#define         ATT_THRESH_MASK         (0x03 << ATT_THRESH_SHIFT)
++#define         USB_D_OEN               (1<<3)
++#define         DEGLITCH_TIME_MASK      0x07
++#define         DEGLITCH_TIME_2MS       0
++#define         DEGLITCH_TIME_4MS       1
++#define         DEGLITCH_TIME_8MS       2
++#define         DEGLITCH_TIME_16MS      3
++#define         DEGLITCH_TIME_40MS      4
++#define         DEGLITCH_TIME_50MS      5
++#define         DEGLITCH_TIME_60MS      6
++#define         DEGLITCH_TIME_128MS     7
++#define MHL_TX_DISC_CTRL3_REG           0x92
++#define MHL_TX_DISC_CTRL4_REG         0x93
++#define MHL_TX_DISC_CTRL5_REG           0x94
++#define MHL_TX_DISC_CTRL6_REG           0x95
++#define         USB_D_OVR               (1<<7)
++#define         USB_ID_OVR              (1<<6)
++#define         DVRFLT_SEL              (1<<5)
++#define         BLOCK_RGND_INT          (1<<4)
++#define         SKIP_DEG                (1<<3)
++#define         CI2CA_POL               (1<<2)
++#define         CI2CA_WKUP              (1<<1)
++#define         SINGLE_ATT              (1<<0)
++#define MHL_TX_DISC_CTRL7_REG           0x96
++#define         USB_D_ODN               (1<<5)
++#define         VBUS_CHECK              (1<<2)
++#define         RGND_INTP_MASK          0x03
++#define         RGND_INTP_OPEN          0
++#define         RGND_INTP_2K            1
++#define         RGND_INTP_1K            2
++#define         RGND_INTP_SHORT         3
++#define MHL_TX_DISC_CTRL8_REG         0x97
++#define MHL_TX_STAT2_REG                0x99
++#define MHL_TX_MHLTX_CTL1_REG           0xA0
++#define MHL_TX_MHLTX_CTL2_REG           0xA1
++#define MHL_TX_MHLTX_CTL4_REG           0xA3
++#define MHL_TX_MHLTX_CTL6_REG           0xA5
++#define MHL_TX_MHLTX_CTL7_REG           0xA6
++
++/* HDMI registers */
++#define HDMI_RX_TMDS0_CCTRL1_REG        0x10
++#define HDMI_RX_TMDS_CLK_EN_REG         0x11
++#define HDMI_RX_TMDS_CH_EN_REG          0x12
++#define HDMI_RX_PLL_CALREFSEL_REG       0x17
++#define HDMI_RX_PLL_VCOCAL_REG          0x1A
++#define HDMI_RX_EQ_DATA0_REG            0x22
++#define HDMI_RX_EQ_DATA1_REG            0x23
++#define HDMI_RX_EQ_DATA2_REG            0x24
++#define HDMI_RX_EQ_DATA3_REG            0x25
++#define HDMI_RX_EQ_DATA4_REG            0x26
++#define HDMI_RX_TMDS_ZONE_CTRL_REG      0x4C
++#define HDMI_RX_TMDS_MODE_CTRL_REG      0x4D
++
++/* CBUS registers */
++#define CBUS_INT_STATUS_1_REG           0x08
++#define CBUS_INTR1_ENABLE_REG         0x09
++#define CBUS_MSC_REQ_ABORT_REASON_REG   0x0D
++#define         SET_HPD_DOWNSTREAM      (1<<6)
++#define CBUS_INT_STATUS_2_REG           0x1E
++#define CBUS_INTR2_ENABLE_REG         0x1F
++#define CBUS_LINK_CONTROL_2_REG         0x31
++#define CBUS_DEVCAP_DEV_STATE         0x80
++#define CBUS_DEVCAP_MHL_VERSION               0x81
++#define CBUS_DEVCAP_DEV_CAT             0x82
++#define CBUS_DEVCAP_ADOPTER_ID_H      0x83
++#define CBUS_DEVCAP_ADOPTER_ID_L      0x84
++#define CBUS_DEVCAP_VID_LINK_MODE     0x85
++#define CBUS_DEVCAP_AUD_LINK_MODE     0x86
++#define CBUS_DEVCAP_VIDEO_TYPE                0x87
++#define CBUS_DEVCAP_LOG_DEV_MAP               0x88
++#define CBUS_DEVCAP_BANDWIDTH         0x89
++#define CBUS_DEVCAP_DEV_FEATURE_FLAG    0x8A
++#define CBUS_DEVCAP_DEVICE_ID_H         0x8B
++#define CBUS_DEVCAP_DEVICE_ID_L         0x8C
++#define CBUS_DEVCAP_SCRATCHPAD_SIZE   0x8D
++#define CBUS_DEVCAP_INT_STAT_SIZE     0x8E
++#define CBUS_DEVCAP_RESERVED          0x8F
++#define CBUS_MHL_STATUS_REG_0           0xB0
++#define CBUS_MHL_STATUS_REG_1           0xB1
++
++/* TPI registers */
++#define TPI_DPD_REG                     0x3D
++
++/* timeouts */
++#define T_SRC_VBUS_CBUS_TO_STABLE     200
++#define T_SRC_CBUS_FLOAT              100
++#define T_SRC_CBUS_DEGLITCH           2
++#define T_SRC_RXSENSE_DEGLITCH                110
++
++enum sii9234_state {
++      ST_OFF,
++      ST_D3,
++      ST_RGND_INIT,
++      ST_RGND_1K,
++      ST_RSEN_HIGH,
++      ST_MHL_ESTABLISHED,
++      ST_FAILURE_DISCOVERY,
++      ST_FAILURE,
++};
++
++struct sii9234 {
++      struct i2c_client *client[4];
++      int i2c_error;
++      int gpio_n_reset;
++      int gpio_int;
++      struct regulator *vcc_supply;
++      int irq;
++
++      enum sii9234_state              state;
++      struct mutex                    lock;
++
++      /* Extcon */
++      struct extcon_specific_cable_nb extcon_dev;
++      struct notifier_block extcon_nb;
++      struct work_struct extcon_wq;
++      bool extcon_attached;
++};
++
++enum sii9234_client_id {
++      I2C_MHL,
++      I2C_TPI,
++      I2C_HDMI,
++      I2C_CBUS,
++};
++
++#define sii9234_dev(sii9234) (&(sii9234)->client[I2C_MHL]->dev)
++
++static char *sii9234_client_name[] = {
++      [I2C_MHL] = "MHL",
++      [I2C_TPI] = "TPI",
++      [I2C_HDMI] = "HDMI",
++      [I2C_CBUS] = "CBUS",
++};
++
++static int sii9234_writeb(struct sii9234 *sii9234, int id, int offset,
++                          int value)
++{
++      int ret;
++      struct i2c_client *client = sii9234->client[id];
++      struct device *dev = sii9234_dev(sii9234);
++
++      if (sii9234->i2c_error)
++              return sii9234->i2c_error;
++
++      ret = i2c_smbus_write_byte_data(client, offset, value);
++      if (ret < 0)
++              dev_err(dev, "writeb: %4s[0x%02x] <- 0x%02x\n",
++                      sii9234_client_name[id], offset, value);
++      sii9234->i2c_error = ret;
++      return ret;
++}
++
++static int sii9234_writebm(struct sii9234 *sii9234, int id, int offset,
++                          int value, int mask)
++{
++      int ret;
++      struct i2c_client *client = sii9234->client[id];
++      struct device *dev = sii9234_dev(sii9234);
++
++      if (sii9234->i2c_error)
++              return sii9234->i2c_error;
++
++      ret = i2c_smbus_write_byte(client, offset);
++      if (ret < 0) {
++              dev_err(dev, "writebm: %4s[0x%02x] <- 0x%02x\n",
++                      sii9234_client_name[id], offset, value);
++              sii9234->i2c_error = ret;
++              return ret;
++      }
++
++      ret = i2c_smbus_read_byte(client);
++      if (ret < 0) {
++              dev_err(dev, "writebm: %4s[0x%02x] <- 0x%02x\n",
++                      sii9234_client_name[id], offset, value);
++              sii9234->i2c_error = ret;
++              return ret;
++      }
++
++      value = (value & mask) | (ret & ~mask);
++
++      ret = i2c_smbus_write_byte_data(client, offset, value);
++      if (ret < 0) {
++              dev_err(dev, "writebm: %4s[0x%02x] <- 0x%02x\n",
++                      sii9234_client_name[id], offset, value);
++              sii9234->i2c_error = ret;
++      }
++      return ret;
++}
++
++static int sii9234_readb(struct sii9234 *sii9234, int id, int offset)
++{
++      int ret;
++      struct i2c_client *client = sii9234->client[id];
++      struct device *dev = sii9234_dev(sii9234);
++
++      if (sii9234->i2c_error)
++              return sii9234->i2c_error;
++
++      ret = i2c_smbus_write_byte(client, offset);
++      if (ret < 0) {
++              dev_err(dev, "readb: %4s[0x%02x]\n",
++                      sii9234_client_name[id], offset);
++              sii9234->i2c_error = ret;
++              return ret;
++      }
++
++      ret = i2c_smbus_read_byte(client);
++      if (ret < 0) {
++              dev_err(dev, "readb: %4s[0x%02x]\n",
++                      sii9234_client_name[id], offset);
++              sii9234->i2c_error = ret;
++      }
++
++      return ret;
++}
++
++static int sii9234_clear_error(struct sii9234 *sii9234)
++{
++      int ret = sii9234->i2c_error;
++
++      sii9234->i2c_error = 0;
++      return ret;
++}
++
++#define mhl_tx_writeb(sii9234, offset, value) \
++      sii9234_writeb(sii9234, I2C_MHL, offset, value)
++#define mhl_tx_writebm(sii9234, offset, value, mask) \
++      sii9234_writebm(sii9234, I2C_MHL, offset, value, mask)
++#define mhl_tx_readb(sii9234, offset) \
++      sii9234_readb(sii9234, I2C_MHL, offset)
++#define cbus_writeb(sii9234, offset, value) \
++      sii9234_writeb(sii9234, I2C_CBUS, offset, value)
++#define cbus_writebm(sii9234, offset, value, mask) \
++      sii9234_writebm(sii9234, I2C_CBUS, offset, value, mask)
++#define cbus_readb(sii9234, offset) \
++      sii9234_readb(sii9234, I2C_CBUS, offset)
++#define hdmi_writeb(sii9234, offset, value) \
++      sii9234_writeb(sii9234, I2C_HDMI, offset, value)
++#define hdmi_writebm(sii9234, offset, value, mask) \
++      sii9234_writebm(sii9234, I2C_HDMI, offset, value, mask)
++#define hdmi_readb(sii9234, offset) \
++      sii9234_readb(sii9234, I2C_HDMI, offset)
++#define tpi_writeb(sii9234, offset, value) \
++      sii9234_writeb(sii9234, I2C_TPI, offset, value)
++#define tpi_writebm(sii9234, offset, value, mask) \
++      sii9234_writebm(sii9234, I2C_TPI, offset, value, mask)
++#define tpi_readb(sii9234, offset) \
++      sii9234_readb(sii9234, I2C_TPI, offset)
++
++static u8 sii9234_tmds_control(struct sii9234 *sii9234, bool enable)
++{
++      mhl_tx_writebm(sii9234, MHL_TX_TMDS_CCTRL, enable ? ~0 : 0, 0x10);
++      mhl_tx_writebm(sii9234, MHL_TX_INT_CTRL_REG, enable ? ~0 : 0, 0x30);
++      return sii9234_clear_error(sii9234);
++}
++
++static int sii9234_cbus_reset(struct sii9234 *sii9234)
++{
++      int i;
++
++      /* Reset CBUS */
++      mhl_tx_writebm(sii9234, MHL_TX_SRST, ~0, 1 << 3);
++      /* CBUS deglitch - 2ms */
++      msleep(T_SRC_CBUS_DEGLITCH);
++      mhl_tx_writebm(sii9234, MHL_TX_SRST, 0, 1 << 3);
++
++      for (i = 0; i < 4; i++) {
++              /* Enable WRITE_STAT interrupt for writes to all
++                 4 MSC Status registers. */
++              cbus_writeb(sii9234, 0xE0 + i, 0xF2);
++              /*Enable SET_INT interrupt for writes to all
++                 4 MSC Interrupt registers. */
++              cbus_writeb(sii9234, 0xF0 + i, 0xF2);
++      }
++
++      return sii9234_clear_error(sii9234);
++}
++
++/* require to chek mhl imformation of samsung in cbus_init_register*/
++static int sii9234_cbus_init(struct sii9234 *sii9234)
++{
++      cbus_writeb(sii9234, 0x07, 0xF2);
++      cbus_writeb(sii9234, 0x40, 0x03);
++      cbus_writeb(sii9234, 0x42, 0x06);
++      cbus_writeb(sii9234, 0x36, 0x0C);
++      cbus_writeb(sii9234, 0x3D, 0xFD);
++      cbus_writeb(sii9234, 0x1C, 0x01);
++      cbus_writeb(sii9234, 0x1D, 0x0F);
++      cbus_writeb(sii9234, 0x44, 0x02);
++      /* Setup our devcap */
++      /* To meet cts 6.3.10.1 spec */
++      cbus_writeb(sii9234, CBUS_DEVCAP_DEV_STATE, 0x00);
++      /* mhl version 1.1 */
++      cbus_writeb(sii9234, CBUS_DEVCAP_MHL_VERSION, 0x11);
++      cbus_writeb(sii9234, CBUS_DEVCAP_DEV_CAT, 0x02);
++      cbus_writeb(sii9234, CBUS_DEVCAP_ADOPTER_ID_H, 0x01);
++      cbus_writeb(sii9234, CBUS_DEVCAP_ADOPTER_ID_L, 0x41);
++      /* YCbCr444, RGB444 */
++      cbus_writeb(sii9234, CBUS_DEVCAP_VID_LINK_MODE, 0x03);
++      cbus_writeb(sii9234, CBUS_DEVCAP_VIDEO_TYPE, 0);
++      cbus_writeb(sii9234, CBUS_DEVCAP_LOG_DEV_MAP, 0x80);
++      cbus_writeb(sii9234, CBUS_DEVCAP_BANDWIDTH, 0x0F);
++      cbus_writeb(sii9234, CBUS_DEVCAP_DEV_FEATURE_FLAG, 0x07);
++      cbus_writeb(sii9234, CBUS_DEVCAP_DEVICE_ID_H, 0x0);
++      cbus_writeb(sii9234, CBUS_DEVCAP_DEVICE_ID_L, 0x0);
++      cbus_writeb(sii9234, CBUS_DEVCAP_SCRATCHPAD_SIZE, 0x10);
++      cbus_writeb(sii9234, CBUS_DEVCAP_INT_STAT_SIZE, 0x33);
++      cbus_writeb(sii9234, CBUS_DEVCAP_RESERVED, 0);
++      cbus_writebm(sii9234, 0x31, 0x0C, 0x0C);
++      cbus_writeb(sii9234, 0x30, 0x01);
++      cbus_writebm(sii9234, 0x3C, 0x30, 0x38);
++      cbus_writebm(sii9234, 0x22, 0x0D, 0x0F);
++      cbus_writebm(sii9234, 0x2E, 0x15, 0x15);
++      cbus_writeb(sii9234, CBUS_INTR1_ENABLE_REG, 0);
++      cbus_writeb(sii9234, CBUS_INTR2_ENABLE_REG, 0);
++
++      return sii9234_clear_error(sii9234);
++}
++
++static void force_usb_id_switch_open(struct sii9234 *sii9234)
++{
++      /*Disable CBUS discovery */
++      mhl_tx_writebm(sii9234, MHL_TX_DISC_CTRL1_REG, 0, 0x01);
++      /*Force USB ID switch to open */
++      mhl_tx_writebm(sii9234, MHL_TX_DISC_CTRL6_REG, ~0, USB_ID_OVR);
++      mhl_tx_writebm(sii9234, MHL_TX_DISC_CTRL3_REG, ~0, 0x86);
++      /*Force upstream HPD to 0 when not in MHL mode. */
++      mhl_tx_writebm(sii9234, MHL_TX_INT_CTRL_REG, 0, 0x30);
++}
++
++static void release_usb_id_switch_open(struct sii9234 *sii9234)
++{
++      msleep(T_SRC_CBUS_FLOAT);
++      /* clear USB ID switch to open */
++      mhl_tx_writebm(sii9234, MHL_TX_DISC_CTRL6_REG, 0, USB_ID_OVR);
++      /* Enable CBUS discovery */
++      mhl_tx_writebm(sii9234, MHL_TX_DISC_CTRL1_REG, ~0, 0x01);
++}
++
++static int sii9234_power_init(struct sii9234 *sii9234)
++{
++      /* Force the SiI9234 into the D0 state. */
++      tpi_writeb(sii9234, TPI_DPD_REG, 0x3F);
++      /* Enable TxPLL Clock */
++      hdmi_writeb(sii9234, HDMI_RX_TMDS_CLK_EN_REG, 0x01);
++      /* Enable Tx Clock Path & Equalizer */
++      hdmi_writeb(sii9234, HDMI_RX_TMDS_CH_EN_REG, 0x15);
++      /* Power Up TMDS */
++      mhl_tx_writeb(sii9234, 0x08, 0x35);
++      return sii9234_clear_error(sii9234);
++}
++
++static int sii9234_hdmi_init(struct sii9234 *sii9234)
++{
++      /* Analog PLL Control bits 5:4 = 2b00 as per char. team. */
++      hdmi_writeb(sii9234, HDMI_RX_TMDS0_CCTRL1_REG, 0xC1);
++      /* PLL Calrefsel */
++      hdmi_writeb(sii9234, HDMI_RX_PLL_CALREFSEL_REG, 0x03);
++      /* VCO Cal */
++      hdmi_writeb(sii9234, HDMI_RX_PLL_VCOCAL_REG, 0x20);
++      /* Auto EQ */
++      hdmi_writeb(sii9234, HDMI_RX_EQ_DATA0_REG, 0x8A);
++      /* Auto EQ */
++      hdmi_writeb(sii9234, HDMI_RX_EQ_DATA1_REG, 0x6A);
++      /* Auto EQ */
++      hdmi_writeb(sii9234, HDMI_RX_EQ_DATA2_REG, 0xAA);
++      /* Auto EQ */
++      hdmi_writeb(sii9234, HDMI_RX_EQ_DATA3_REG, 0xCA);
++      /* Auto EQ */
++      hdmi_writeb(sii9234, HDMI_RX_EQ_DATA4_REG, 0xEA);
++      /* Manual zone */
++      hdmi_writeb(sii9234, HDMI_RX_TMDS_ZONE_CTRL_REG, 0xA0);
++      /* PLL Mode Value */
++      hdmi_writeb(sii9234, HDMI_RX_TMDS_MODE_CTRL_REG, 0x00);
++      mhl_tx_writeb(sii9234, MHL_TX_TMDS_CCTRL, 0x34);
++      hdmi_writeb(sii9234, 0x45, 0x44);
++      /* Rx PLL BW ~ 4MHz */
++      hdmi_writeb(sii9234, 0x31, 0x0A);
++      /* Analog PLL Control * bits 5:4 = 2b00 as per char. team. */
++      hdmi_writeb(sii9234, HDMI_RX_TMDS0_CCTRL1_REG, 0xC1);
++
++      return sii9234_clear_error(sii9234);
++}
++
++static int sii9234_mhl_tx_ctl_int(struct sii9234 *sii9234)
++{
++      mhl_tx_writeb(sii9234, MHL_TX_MHLTX_CTL1_REG, 0xD0);
++      mhl_tx_writeb(sii9234, MHL_TX_MHLTX_CTL2_REG, 0xFC);
++      mhl_tx_writeb(sii9234, MHL_TX_MHLTX_CTL4_REG, 0xEB);
++      mhl_tx_writeb(sii9234, MHL_TX_MHLTX_CTL7_REG, 0x0C);
++      return sii9234_clear_error(sii9234);
++}
++
++static int sii9234_reset(struct sii9234 *sii9234)
++{
++      int ret;
++
++      sii9234_clear_error(sii9234);
++
++      ret = sii9234_power_init(sii9234);
++      if (ret < 0)
++              return ret;
++      ret = sii9234_cbus_reset(sii9234);
++      if (ret < 0)
++              return ret;
++      ret = sii9234_hdmi_init(sii9234);
++      if (ret < 0)
++              return ret;
++      ret = sii9234_mhl_tx_ctl_int(sii9234);
++      if (ret < 0)
++              return ret;
++
++      /* Enable HDCP Compliance safety */
++      mhl_tx_writeb(sii9234, 0x2B, 0x01);
++      /* CBUS discovery cycle time for each drive and float = 150us */
++      mhl_tx_writebm(sii9234, MHL_TX_DISC_CTRL1_REG, 0x04, 0x06);
++      /* Clear bit 6 (reg_skip_rgnd) */
++      mhl_tx_writeb(sii9234, MHL_TX_DISC_CTRL2_REG, (1 << 7) /* Reserved */
++              | 2 << ATT_THRESH_SHIFT | DEGLITCH_TIME_50MS);
++      /* Changed from 66 to 65 for 94[1:0] = 01 = 5k reg_cbusmhl_pup_sel */
++      /* 1.8V CBUS VTH & GND threshold */
++      /*To meet CTS 3.3.7.2 spec */
++      mhl_tx_writeb(sii9234, MHL_TX_DISC_CTRL5_REG, 0x77);
++      /* set bit 2 and 3, which is Initiator Timeout */
++      cbus_writebm(sii9234, CBUS_LINK_CONTROL_2_REG, ~0, 0x0C);
++      mhl_tx_writeb(sii9234, MHL_TX_MHLTX_CTL6_REG, 0xA0);
++      /* RGND & single discovery attempt (RGND blocking) */
++      mhl_tx_writeb(sii9234, MHL_TX_DISC_CTRL6_REG, BLOCK_RGND_INT |
++                             DVRFLT_SEL | SINGLE_ATT);
++      /* Use VBUS path of discovery state machine */
++      mhl_tx_writeb(sii9234, MHL_TX_DISC_CTRL8_REG, 0);
++      /* 0x92[3] sets the CBUS / ID switch */
++      mhl_tx_writebm(sii9234, MHL_TX_DISC_CTRL6_REG, ~0, USB_ID_OVR);
++      /* To allow RGND engine to operate correctly.
++       * When moving the chip from D2 to D0 (power up, init regs)
++       * the values should be
++       * 94[1:0] = 01  reg_cbusmhl_pup_sel[1:0] should be set for 5k
++       * 93[7:6] = 10  reg_cbusdisc_pup_sel[1:0] should be
++       * set for 10k (default)
++       * 93[5:4] = 00  reg_cbusidle_pup_sel[1:0] = open (default)
++       */
++      mhl_tx_writebm(sii9234, MHL_TX_DISC_CTRL3_REG, ~0, 0x86);
++      /* change from CC to 8C to match 5K */
++      /*To meet CTS 3.3.72 spec */
++      mhl_tx_writebm(sii9234, MHL_TX_DISC_CTRL4_REG, ~0, 0x8C);
++      /* Configure the interrupt as active high */
++      mhl_tx_writebm(sii9234, MHL_TX_INT_CTRL_REG, 0, 0x06);
++
++      msleep(25);
++
++      /* release usb_id switch */
++      mhl_tx_writebm(sii9234, MHL_TX_DISC_CTRL6_REG, 0,  USB_ID_OVR);
++      mhl_tx_writeb(sii9234, MHL_TX_DISC_CTRL1_REG, 0x27);
++
++      ret = sii9234_clear_error(sii9234);
++      if (ret < 0)
++              return ret;
++      ret = sii9234_cbus_init(sii9234);
++      if (ret < 0)
++              return ret;
++
++      /* Enable Auto soft reset on SCDT = 0 */
++      mhl_tx_writeb(sii9234, 0x05, 0x04);
++      /* HDMI Transcode mode enable */
++      mhl_tx_writeb(sii9234, 0x0D, 0x1C);
++      mhl_tx_writeb(sii9234, MHL_TX_INTR4_ENABLE_REG,
++                             RGND_READY_MASK | CBUS_LKOUT_MASK |
++                             MHL_DISC_FAIL_MASK | MHL_EST_MASK);
++      mhl_tx_writeb(sii9234, MHL_TX_INTR1_ENABLE_REG, 0x60);
++
++      /* this point is very importand before megsure RGND impedance */
++      force_usb_id_switch_open(sii9234);
++      mhl_tx_writebm(sii9234, MHL_TX_DISC_CTRL4_REG, 0, 0xF0);
++      mhl_tx_writebm(sii9234, MHL_TX_DISC_CTRL5_REG, 0, 0x03);
++      release_usb_id_switch_open(sii9234);
++      /*end of this */
++
++      /* Force upstream HPD to 0 when not in MHL mode */
++      mhl_tx_writebm(sii9234, MHL_TX_INT_CTRL_REG, 0, 1 << 5);
++      mhl_tx_writebm(sii9234, MHL_TX_INT_CTRL_REG, ~0, 1 << 4);
++
++      return sii9234_clear_error(sii9234);
++}
++
++static int sii9234_goto_d3(struct sii9234 *sii9234)
++{
++      int ret;
++      struct device *dev = sii9234_dev(sii9234);
++
++      dev_dbg(dev, "sii9234: detection started d3\n");
++
++      ret = sii9234_reset(sii9234);
++      if (ret < 0)
++              goto exit;
++
++      hdmi_writeb(sii9234, 0x01, 0x03);
++      tpi_writebm(sii9234, TPI_DPD_REG, 0, 1);
++      /* I2C above is expected to fail because power goes down */
++      sii9234_clear_error(sii9234);
++
++      sii9234->state = ST_D3;
++
++      return 0;
++ exit:
++      dev_err(dev, "sii9234_goto_d3() failed\n");
++      return -1;
++}
++
++#define sii9234_hw_on(sii9234) \
++      regulator_enable((sii9234)->vcc_supply)
++
++static void sii9234_hw_off(struct sii9234 *sii9234)
++{
++      gpio_direction_output(sii9234->gpio_n_reset, 0);
++      usleep_range(10000, 20000);
++      gpio_direction_output(sii9234->gpio_n_reset, 1);
++      regulator_disable(sii9234->vcc_supply);
++      gpio_direction_output(sii9234->gpio_n_reset, 0);
++}
++
++static void sii9234_hw_reset(struct sii9234 *sii9234)
++{
++      gpio_direction_output(sii9234->gpio_n_reset, 0);
++      usleep_range(10000, 20000);
++      gpio_direction_output(sii9234->gpio_n_reset, 1);
++}
++
++static void sii9234_cable_in(struct sii9234 *sii9234)
++{
++      int ret;
++
++      mutex_lock(&sii9234->lock);
++      if (sii9234->state != ST_OFF)
++              goto unlock;
++      ret = sii9234_hw_on(sii9234);
++      if (ret < 0)
++              goto unlock;
++
++      sii9234_hw_reset(sii9234);
++      sii9234_goto_d3(sii9234);
++      enable_irq(sii9234->irq);
++
++unlock:
++      mutex_unlock(&sii9234->lock);
++}
++
++static void sii9234_cable_out(struct sii9234 *sii9234)
++{
++      mutex_lock(&sii9234->lock);
++
++      if (sii9234->state == ST_OFF)
++              goto unlock;
++
++      disable_irq_nosync(sii9234->irq);
++      tpi_writeb(sii9234, TPI_DPD_REG, 0);
++      /*turn on&off hpd festure for only QCT HDMI */
++      sii9234_hw_off(sii9234);
++
++      sii9234->state = ST_OFF;
++
++unlock:
++      mutex_unlock(&sii9234->lock);
++}
++
++static enum sii9234_state sii9234_rgnd_ready_irq(struct sii9234 *sii9234)
++{
++      int value;
++      struct device *dev = sii9234_dev(sii9234);
++
++      if (sii9234->state == ST_D3) {
++              int ret;
++
++              dev_dbg(dev, "RGND_READY_INT\n");
++              sii9234_hw_reset(sii9234);
++
++              ret = sii9234_reset(sii9234);
++              if (ret < 0) {
++                      dev_err(dev, "sii9234_reset() failed\n");
++                      return ST_FAILURE;
++              }
++
++              return ST_RGND_INIT;
++      }
++
++      /* got interrupt in inappropriate state */
++      if (sii9234->state != ST_RGND_INIT)
++              return ST_FAILURE;
++
++      value = mhl_tx_readb(sii9234, MHL_TX_STAT2_REG);
++      if (sii9234_clear_error(sii9234))
++              return ST_FAILURE;
++
++      if ((value & RGND_INTP_MASK) != RGND_INTP_1K) {
++              dev_warn(dev, "RGND is not 1k\n");
++              return ST_RGND_INIT;
++      }
++      dev_dbg(dev, "RGND 1K!!\n");
++      /* After applying RGND patch, there is some issue
++         about discovry failure
++         This point is add to fix that problem */
++      mhl_tx_writebm(sii9234, MHL_TX_DISC_CTRL4_REG, ~0, 0x8C);
++      mhl_tx_writeb(sii9234, MHL_TX_DISC_CTRL5_REG, 0x77);
++      mhl_tx_writebm(sii9234, MHL_TX_DISC_CTRL6_REG, ~0, 0x05);
++      if (sii9234_clear_error(sii9234))
++              return ST_FAILURE;
++
++      usleep_range(T_SRC_VBUS_CBUS_TO_STABLE * USEC_PER_MSEC,
++                   T_SRC_VBUS_CBUS_TO_STABLE * USEC_PER_MSEC);
++
++      return ST_RGND_1K;
++}
++
++static enum sii9234_state sii9234_mhl_established(struct sii9234 *sii9234)
++{
++      dev_dbg(sii9234_dev(sii9234), "mhl est interrupt\n");
++
++      /* discovery override */
++      mhl_tx_writeb(sii9234, MHL_TX_MHLTX_CTL1_REG, 0x10);
++      /* increase DDC translation layer timer (byte mode) */
++      cbus_writeb(sii9234, 0x07, 0x32);
++      cbus_writebm(sii9234, 0x44, ~0, 1 << 1);
++      /* Keep the discovery enabled. Need RGND interrupt */
++      mhl_tx_writebm(sii9234, MHL_TX_DISC_CTRL1_REG, ~0, 1);
++      mhl_tx_writeb(sii9234, MHL_TX_INTR1_ENABLE_REG,
++             RSEN_CHANGE_INT_MASK | HPD_CHANGE_INT_MASK);
++
++      if (sii9234_clear_error(sii9234))
++              return ST_FAILURE;
++
++      return ST_MHL_ESTABLISHED;
++}
++
++static enum sii9234_state sii9234_hpd_change(struct sii9234 *sii9234)
++{
++      int value;
++
++      value = cbus_readb(sii9234, CBUS_MSC_REQ_ABORT_REASON_REG);
++      if (sii9234_clear_error(sii9234))
++              return ST_FAILURE;
++
++      if (value & SET_HPD_DOWNSTREAM) {
++              dev_info(sii9234_dev(sii9234), "HPD High\n");
++              /* Downstream HPD High, Enable TMDS */
++              sii9234_tmds_control(sii9234, true);
++              /*turn on&off hpd festure for only QCT HDMI */
++      } else {
++              dev_info(sii9234_dev(sii9234), "HPD Low\n");
++              /* Downstream HPD Low, Disable TMDS */
++              sii9234_tmds_control(sii9234, false);
++      }
++
++      return sii9234->state;
++}
++
++static enum sii9234_state sii9234_rsen_change(struct sii9234 *sii9234)
++{
++      int value;
++      struct device *dev = sii9234_dev(sii9234);
++
++      /* work_around code to handle worng interrupt */
++      if (sii9234->state != ST_RGND_1K) {
++              dev_err(dev, "RSEN_HIGH without RGND_1K\n");
++              return ST_FAILURE;
++      }
++      value = mhl_tx_readb(sii9234, MHL_TX_SYSSTAT_REG);
++      if (value < 0)
++              return ST_FAILURE;
++
++      if (value & RSEN_STATUS) {
++              dev_info(dev, "MHL cable connected.. RSEN High\n");
++              return ST_RSEN_HIGH;
++      }
++      dev_info(dev, "RSEN lost\n");
++      /* Once RSEN loss is confirmed,we need to check
++       * based on cable status and chip power status,whether
++       * it is SINK Loss(HDMI cable not connected, TV Off)
++       * or MHL cable disconnection
++       * TODO: Define the below mhl_disconnection()
++       */
++      msleep(T_SRC_RXSENSE_DEGLITCH);
++      value = mhl_tx_readb(sii9234, MHL_TX_SYSSTAT_REG);
++      if (value < 0)
++              return ST_FAILURE;
++      dev_dbg(dev, "sys_stat: %x\n", value);
++
++      if (value & RSEN_STATUS) {
++              dev_info(dev, "RSEN recovery\n");
++              return ST_RSEN_HIGH;
++      }
++      dev_info(dev, "RSEN Really LOW\n");
++      /*To meet CTS 3.3.22.2 spec */
++      sii9234_tmds_control(sii9234, false);
++      force_usb_id_switch_open(sii9234);
++      release_usb_id_switch_open(sii9234);
++
++      return ST_FAILURE;
++}
++
++static irqreturn_t sii9234_irq_thread(int irq, void *data)
++{
++      struct sii9234 *sii9234 = data;
++      int intr1, intr4;
++      int intr1_en, intr4_en;
++      int cbus_intr1, cbus_intr2;
++      struct device *dev = sii9234_dev(sii9234);
++
++      dev_dbg(dev, "%s\n", __func__);
++
++      msleep(30);
++
++      mutex_lock(&sii9234->lock);
++
++      intr1 = mhl_tx_readb(sii9234, MHL_TX_INTR1_REG);
++      intr4 = mhl_tx_readb(sii9234, MHL_TX_INTR4_REG);
++      intr1_en = mhl_tx_readb(sii9234, MHL_TX_INTR1_ENABLE_REG);
++      intr4_en = mhl_tx_readb(sii9234, MHL_TX_INTR4_ENABLE_REG);
++      cbus_intr1 = cbus_readb(sii9234, CBUS_INT_STATUS_1_REG);
++      cbus_intr2 = cbus_readb(sii9234, CBUS_INT_STATUS_2_REG);
++
++      if (sii9234_clear_error(sii9234))
++              goto done;
++
++      dev_dbg(dev, "irq %02x/%02x %02x/%02x %02x/%02x\n",
++               intr1, intr1_en, intr4, intr4_en, cbus_intr1, cbus_intr2);
++
++      if (intr4 & RGND_READY_INT)
++              sii9234->state = sii9234_rgnd_ready_irq(sii9234);
++      if (intr1 & RSEN_CHANGE_INT)
++              sii9234->state = sii9234_rsen_change(sii9234);
++      if (intr4 & MHL_EST_INT)
++              sii9234->state = sii9234_mhl_established(sii9234);
++      if (intr1 & HPD_CHANGE_INT)
++              sii9234->state = sii9234_hpd_change(sii9234);
++      if (intr4 & CBUS_LKOUT_INT)
++              sii9234->state = ST_FAILURE;
++      if (intr4 & MHL_DISC_FAIL_INT)
++              sii9234->state = ST_FAILURE_DISCOVERY;
++
++ done:
++      /* clean interrupt status and pending flags */
++      mhl_tx_writeb(sii9234, MHL_TX_INTR1_REG, intr1);
++      mhl_tx_writeb(sii9234, MHL_TX_INTR4_REG, intr4);
++      cbus_writeb(sii9234, CBUS_MHL_STATUS_REG_0, 0xFF);
++      cbus_writeb(sii9234, CBUS_MHL_STATUS_REG_1, 0xFF);
++      cbus_writeb(sii9234, CBUS_INT_STATUS_1_REG, cbus_intr1);
++      cbus_writeb(sii9234, CBUS_INT_STATUS_2_REG, cbus_intr2);
++
++      sii9234_clear_error(sii9234);
++
++      if (sii9234->state == ST_FAILURE) {
++              dev_info(dev, "try to reset after failure\n");
++              sii9234_hw_reset(sii9234);
++              sii9234_goto_d3(sii9234);
++      }
++
++      if (sii9234->state == ST_FAILURE_DISCOVERY) {
++              dev_err(dev, "discovery failed, no power for MHL?\n");
++              tpi_writebm(sii9234, TPI_DPD_REG, 0, 1);
++              sii9234->state = ST_D3;
++      }
++
++      mutex_unlock(&sii9234->lock);
++
++      return IRQ_HANDLED;
++}
++
++static void sii9234_extcon_work(struct work_struct *work)
++{
++      struct sii9234 *sii9234 =
++              container_of(work, struct sii9234, extcon_wq);
++
++      dev_info(sii9234_dev(sii9234), "MHL is %s\n",
++              sii9234->extcon_attached ? "attached" : "detached");
++
++      if (sii9234->extcon_attached)
++              sii9234_cable_in(sii9234);
++      else
++              sii9234_cable_out(sii9234);
++}
++
++static int sii9234_extcon_notifier(struct notifier_block *self,
++                      unsigned long event, void *ptr)
++{
++      struct sii9234 *sii9234 =
++              container_of(self, struct sii9234, extcon_nb);
++
++      sii9234->extcon_attached = event;
++      schedule_work(&sii9234->extcon_wq);
++
++      return NOTIFY_DONE;
++}
++
++static int sii9234_extcon_init(struct sii9234 *sii9234)
++{
++      struct device *dev = &sii9234->client[I2C_MHL]->dev;
++      struct extcon_dev *edev;
++      int ret;
++
++      if (of_property_read_bool(dev->of_node, "extcon")) {
++              edev = of_extcon_get_extcon_dev(dev, 0);
++              if (IS_ERR(edev)) {
++                      dev_err(dev, "failed to acquire extcon device\n");
++                      return PTR_ERR(edev);
++              }
++
++              sii9234->extcon_attached = extcon_get_cable_state(edev, "MHL");
++              dev_info(dev, "extcon(MHL) = %d\n", sii9234->extcon_attached);
++
++              sii9234->extcon_nb.notifier_call = sii9234_extcon_notifier;
++              ret = extcon_register_interest(&sii9234->extcon_dev, edev->name,
++                      "MHL", &sii9234->extcon_nb);
++
++              if (ret) {
++                      dev_err(dev, "failed to register notifier for MHL\n");
++                      return ret;
++              }
++              INIT_WORK(&sii9234->extcon_wq, sii9234_extcon_work);
++      } else {
++              dev_info(dev, "no extcon found, switching to 'always on' mode\n");
++              sii9234->extcon_attached = true;
++      }
++      return 0;
++}
++
++static int sii9234_init_resources(struct sii9234 *sii9234,
++      struct i2c_client *client)
++{
++      struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
++      struct device *dev = &client->dev;
++      int ret;
++
++      if (!dev->of_node) {
++              dev_err(dev, "not DT device\n");
++              return -ENODEV;
++      }
++
++      sii9234->gpio_n_reset = of_get_named_gpio(dev->of_node,
++              "gpio-reset", 0);
++      if (!gpio_is_valid(sii9234->gpio_n_reset)) {
++              dev_err(dev, "failed to get gpio-reset from DT\n");
++              return -ENODEV;
++      }
++      sii9234->gpio_int = of_get_named_gpio(dev->of_node, "gpio-int", 0);
++      if (!gpio_is_valid(sii9234->gpio_int)) {
++              dev_err(dev, "failed to get gpio-int from DT\n");
++              return -ENODEV;
++      }
++
++      ret = devm_gpio_request(dev, sii9234->gpio_n_reset, "MHL_RST");
++      if (ret) {
++              dev_err(dev, "failed to acquire MHL_RST gpio\n");
++              return ret;
++      }
++
++      ret = devm_gpio_request(dev, sii9234->gpio_int, "MHL_INT");
++      if (ret) {
++              dev_err(dev, "failed to request MHL_INT gpio\n");
++              return ret;
++      }
++
++      sii9234->vcc_supply = devm_regulator_get(dev, "vcc");
++      if (IS_ERR(sii9234->vcc_supply)) {
++              dev_err(dev, "failed to acquire regulator vcc\n");
++              return PTR_ERR(sii9234->vcc_supply);
++      }
++
++      sii9234->client[I2C_MHL] = client;
++
++      sii9234->client[I2C_TPI] = i2c_new_dummy(adapter, 0x7A >> 1);
++      if (!sii9234->client[I2C_TPI]) {
++              dev_err(dev, "failed to create TPI client\n");
++              return -ENODEV;
++      }
++
++      sii9234->client[I2C_HDMI] = i2c_new_dummy(adapter, 0x92 >> 1);
++      if (!sii9234->client[I2C_HDMI]) {
++              dev_err(dev, "failed to create HDMI RX client\n");
++              goto fail_tpi;
++      }
++
++      sii9234->client[I2C_CBUS] = i2c_new_dummy(adapter, 0xC8 >> 1);
++      if (!sii9234->client[I2C_CBUS]) {
++              dev_err(dev, "failed to create CBUS client\n");
++              goto fail_hdmi;
++      }
++
++      return 0;
++
++fail_hdmi:
++      i2c_unregister_device(sii9234->client[I2C_HDMI]);
++fail_tpi:
++      i2c_unregister_device(sii9234->client[I2C_TPI]);
++
++      return -ENODEV;
++}
++
++static void sii9234_deinit_resources(struct sii9234 *sii9234)
++{
++      i2c_unregister_device(sii9234->client[I2C_CBUS]);
++      i2c_unregister_device(sii9234->client[I2C_HDMI]);
++      i2c_unregister_device(sii9234->client[I2C_TPI]);
++}
++
++static int sii9234_mhl_tx_i2c_probe(struct i2c_client *client,
++                                            const struct i2c_device_id *id)
++{
++      struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
++      struct sii9234 *sii9234;
++      struct device *dev = &client->dev;
++      int ret;
++
++      if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
++              dev_err(dev, "I2C adapter lacks SMBUS feature\n");
++              return -EIO;
++      }
++
++      sii9234 = devm_kzalloc(dev, sizeof(struct sii9234), GFP_KERNEL);
++      if (!sii9234) {
++              dev_err(dev, "not enough memory\n");
++              return -ENOMEM;
++      }
++
++      mutex_init(&sii9234->lock);
++
++      ret = sii9234_init_resources(sii9234, client);
++      if (ret < 0) {
++              dev_err(&client->dev, "failed to initialize sii9234 resources\n");
++              return ret;
++      }
++      sii9234_hw_on(sii9234);
++      sii9234_hw_reset(sii9234);
++
++      i2c_set_clientdata(client, sii9234);
++
++      sii9234->irq = gpio_to_irq(sii9234->gpio_int);
++      ret = devm_request_threaded_irq(dev, sii9234->irq, NULL,
++              sii9234_irq_thread, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
++              "sii9234", sii9234);
++      if (ret < 0) {
++              dev_err(dev, "failed to request MHL interrupt\n");
++              goto err_resource;
++      }
++
++      disable_irq(sii9234->irq);
++
++      ret = sii9234_extcon_init(sii9234);
++      if (ret < 0) {
++              dev_err(dev, "failed to initialize EXTCON\n");
++              goto err_resource;
++      }
++
++      /* Force MHL connect EVENT for platforms with no EXTCON */
++      if (sii9234->extcon_attached)
++              sii9234_cable_in(sii9234);
++
++      return 0;
++
++err_resource:
++      sii9234_deinit_resources(sii9234);
++
++      return ret;
++}
++
++static int sii9234_mhl_tx_i2c_remove(struct i2c_client *client)
++{
++      struct sii9234 *sii9234 = i2c_get_clientdata(client);
++
++      extcon_unregister_interest(&sii9234->extcon_dev);
++      if (sii9234->extcon_attached)
++              sii9234_cable_out(sii9234);
++      sii9234_deinit_resources(sii9234);
++
++      return 0;
++}
++
++static const struct of_device_id sii9234_dt_match[] = {
++      { .compatible = "sii,sii9234" },
++      { },
++};
++MODULE_DEVICE_TABLE(of, sii9234_dt_match);
++
++static const struct i2c_device_id sii9234_id[] = {
++      { "SII9234", 0 },
++      { },
++};
++
++MODULE_DEVICE_TABLE(i2c, sii9234_id);
++static struct i2c_driver sii9234_driver = {
++      .driver = {
++              .name   = "sii9234",
++              .owner  = THIS_MODULE,
++              .of_match_table = of_match_ptr(sii9234_dt_match),
++      },
++      .probe          = sii9234_mhl_tx_i2c_probe,
++      .remove         = sii9234_mhl_tx_i2c_remove,
++      .id_table = sii9234_id,
++};
++
++module_i2c_driver(sii9234_driver);
++MODULE_LICENSE("GPL");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1220-clk-exynos4-export-sclk_hdmiphy-clock.patch b/patches.tizen/1220-clk-exynos4-export-sclk_hdmiphy-clock.patch
new file mode 100644 (file)
index 0000000..471074a
--- /dev/null
@@ -0,0 +1,52 @@
+From 7a25bffba239ef5ebfc3461952fc607ee3fd8e38 Mon Sep 17 00:00:00 2001
+From: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Date: Mon, 7 Oct 2013 14:27:52 +0200
+Subject: [PATCH 1220/1302] clk: exynos4: export sclk_hdmiphy clock
+
+Export sclk_hdmiphy clock to be usable from DT.
+
+Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Change-Id: I0d1c8d0c2e2e93bd34f9fcdf82154208c2381a73
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/devicetree/bindings/clock/exynos4-clock.txt | 1 +
+ drivers/clk/samsung/clk-exynos4.c                         | 4 ++--
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/clock/exynos4-clock.txt b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
+index d7a4bc9..4c62832 100644
+--- a/Documentation/devicetree/bindings/clock/exynos4-clock.txt
++++ b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
+@@ -47,6 +47,7 @@ Exynos4 SoC and this is specified where applicable.
+   mout_core           19
+   mout_apll           20
+   clkout              21
++  sclk_hdmiphy        22
+             [Clock Gate for Special Clocks]
+diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
+index ed29bf5..02ab6cc 100644
+--- a/drivers/clk/samsung/clk-exynos4.c
++++ b/drivers/clk/samsung/clk-exynos4.c
+@@ -143,7 +143,7 @@ enum exynos4_clks {
+       xxti, xusbxti, fin_pll, fout_apll, fout_mpll, fout_epll, fout_vpll,
+       sclk_apll, sclk_mpll, sclk_epll, sclk_vpll, arm_clk, aclk200, aclk100,
+       aclk160, aclk133, mout_mpll_user_t, mout_mpll_user_c, mout_core,
+-      mout_apll, clkout, /* 21 */
++      mout_apll, clkout, sclk_hdmiphy, /* 22 */
+       /* gate for special clocks (sclk) */
+       sclk_fimc0 = 128, sclk_fimc1, sclk_fimc2, sclk_fimc3, sclk_cam0,
+@@ -351,7 +351,7 @@ struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] __initdata = {
+ /* fixed rate clocks generated inside the soc */
+ struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] __initdata = {
+       FRATE(none, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000),
+-      FRATE(none, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000),
++      FRATE(sclk_hdmiphy, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000),
+       FRATE(none, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000),
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1221-clk-propagate-parent-change-up-one-level.patch b/patches.tizen/1221-clk-propagate-parent-change-up-one-level.patch
new file mode 100644 (file)
index 0000000..3c69c8e
--- /dev/null
@@ -0,0 +1,60 @@
+From b9ca3843017d7ea99a25db73198257b05f090217 Mon Sep 17 00:00:00 2001
+From: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Date: Tue, 15 Oct 2013 17:59:11 +0200
+Subject: [PATCH 1221/1302] clk: propagate parent change up one level
+
+This patch adds support for propagation of setup of clock's parent one level
+up.
+
+This feature is helpful when a driver changes topology of its clocks using
+clk_set_parent().  The problem occurs when on one platform/SoC driver's clock
+is located at MUX output but on the other platform/SoC there is a gated proxy
+clock between the MUX and driver's clock.  In such a case, driver's code has to
+be modified to use one clock for enabling and the other clock for setup of a
+parent.
+
+The code updates are avoided by propagating setup of a parent up one level.
+
+Additionally, this patch adds CLK_SET_PARENT_PARENT (sorry for naming) flag to
+inform clk-core that clk_set_parent() should be propagated.
+
+Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Change-Id: I206d23fb86cc09bce943ef9971a710876e3a7744
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/clk.c            | 6 ++++++
+ include/linux/clk-provider.h | 1 +
+ 2 files changed, 7 insertions(+)
+
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
+index a9abf1b..ba2f31b 100644
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -1506,6 +1506,12 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
+       /* try finding the new parent index */
+       if (parent) {
++              if ((clk->flags & CLK_SET_PARENT_PARENT)
++                  && clk->num_parents == 1) {
++                      ret = clk_set_parent(clk->parent, parent);
++                      goto out;
++              }
++
+               p_index = clk_fetch_parent_index(clk, parent);
+               p_rate = parent->rate;
+               if (p_index == clk->num_parents) {
+diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
+index 1186098..061052f 100644
+--- a/include/linux/clk-provider.h
++++ b/include/linux/clk-provider.h
+@@ -27,6 +27,7 @@
+ #define CLK_IS_ROOT           BIT(4) /* root clk, has no parent */
+ #define CLK_IS_BASIC          BIT(5) /* Basic clk, can't do a to_clk_foo() */
+ #define CLK_GET_RATE_NOCACHE  BIT(6) /* do not use the cached clk rate */
++#define CLK_SET_PARENT_PARENT BIT(7) /* propagate parent change up one level */
+ struct clk_hw;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1222-clk-exynos4-enable-clk_set_parent-propagation-for-sc.patch b/patches.tizen/1222-clk-exynos4-enable-clk_set_parent-propagation-for-sc.patch
new file mode 100644 (file)
index 0000000..60d4974
--- /dev/null
@@ -0,0 +1,43 @@
+From 06a47b88b19042cee349e7a2615258a1efdccf9d Mon Sep 17 00:00:00 2001
+From: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Date: Wed, 16 Oct 2013 13:08:55 +0200
+Subject: [PATCH 1222/1302] clk: exynos4: enable clk_set_parent() propagation
+ for sclk_hdmi and sclk_mixer clocks
+
+This patch enables clk_set_parent() propagation for clocks used
+by s5p-tv and exynos-drm drivers.
+
+Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Change-Id: I8f91dcd73a43291297def7f69eb35950afd45c55
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clk/samsung/clk-exynos4.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
+index 02ab6cc..3736a93 100644
+--- a/drivers/clk/samsung/clk-exynos4.c
++++ b/drivers/clk/samsung/clk-exynos4.c
+@@ -608,7 +608,8 @@ struct samsung_gate_clock exynos4_gate_clks[] __initdata = {
+        * the device name and clock alias names specified below for some
+        * of the clocks can be removed.
+        */
+-      GATE(sclk_hdmi, "sclk_hdmi", "mout_hdmi", SRC_MASK_TV, 0, 0, 0),
++      GATE(sclk_hdmi, "sclk_hdmi", "mout_hdmi", SRC_MASK_TV, 0,
++                      CLK_SET_PARENT_PARENT, 0),
+       GATE(sclk_spdif, "sclk_spdif", "mout_spdif", SRC_MASK_PERIL1, 8, 0, 0),
+       GATE(jpeg, "jpeg", "aclk160", GATE_IP_CAM, 6, 0, 0),
+       GATE(mie0, "mie0", "aclk160", GATE_IP_LCD0, 1, 0, 0),
+@@ -818,7 +819,8 @@ struct samsung_gate_clock exynos4210_gate_clks[] __initdata = {
+                       E4210_SRC_MASK_LCD1, 12, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_sata, "sclk_sata", "div_sata",
+                       SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0),
+-      GATE(sclk_mixer, "sclk_mixer", "mout_mixer", SRC_MASK_TV, 4, 0, 0),
++      GATE(sclk_mixer, "sclk_mixer", "mout_mixer", SRC_MASK_TV, 4,
++                      CLK_SET_PARENT_PARENT, 0),
+       GATE(sclk_dac, "sclk_dac", "mout_dac", SRC_MASK_TV, 8, 0, 0),
+       GATE_A(tsadc, "tsadc", "aclk100", GATE_IP_PERIL, 15, 0, 0, "adc"),
+       GATE_A(mct, "mct", "aclk100", E4210_GATE_IP_PERIR, 13, 0, 0, "mct"),
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1223-drm-exynos-hdmi-use-hdmiphy-as-PHY.patch b/patches.tizen/1223-drm-exynos-hdmi-use-hdmiphy-as-PHY.patch
new file mode 100644 (file)
index 0000000..21d57fe
--- /dev/null
@@ -0,0 +1,72 @@
+From 47fda3e2ac0fc9ad689b2b6bc46da2bf1bd51437 Mon Sep 17 00:00:00 2001
+From: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Date: Thu, 3 Oct 2013 16:04:53 +0200
+Subject: [PATCH 1223/1302] drm: exynos: hdmi: use hdmiphy as PHY
+
+The HDMIPHY (physical interface) is controlled by a single
+bit in a power controller's regiter. It was implemented
+as clock. It was a simple but effective hack.
+
+This patch makes HDMI driver to control HDMIPHY via PHY interface.
+
+Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Change-Id: I7e4729b61c7e71f7e411d423794420893f99f384
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_hdmi.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
+index 05b24f9..9b52b4f 100644
+--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
++++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
+@@ -34,6 +34,7 @@
+ #include <linux/io.h>
+ #include <linux/of.h>
+ #include <linux/of_gpio.h>
++#include <linux/phy/phy.h>
+ #include <drm/exynos_drm.h>
+@@ -82,7 +83,7 @@ struct hdmi_resources {
+       struct clk                      *sclk_hdmi;
+       struct clk                      *sclk_pixel;
+       struct clk                      *sclk_hdmiphy;
+-      struct clk                      *hdmiphy;
++      struct phy                      *hdmiphy;
+       struct regulator_bulk_data      *regul_bulk;
+       int                             regul_count;
+ };
+@@ -1683,7 +1684,7 @@ static void hdmi_poweron(struct hdmi_context *hdata)
+       if (regulator_bulk_enable(res->regul_count, res->regul_bulk))
+               DRM_DEBUG_KMS("failed to enable regulator bulk\n");
+-      clk_enable(res->hdmiphy);
++      phy_power_on(res->hdmiphy);
+       clk_enable(res->hdmi);
+       clk_enable(res->sclk_hdmi);
+@@ -1708,7 +1709,7 @@ static void hdmi_poweroff(struct hdmi_context *hdata)
+       clk_disable(res->sclk_hdmi);
+       clk_disable(res->hdmi);
+-      clk_disable(res->hdmiphy);
++      phy_power_off(res->hdmiphy);
+       regulator_bulk_disable(res->regul_count, res->regul_bulk);
+       mutex_lock(&hdata->hdmi_mutex);
+@@ -1807,9 +1808,9 @@ static int hdmi_resources_init(struct hdmi_context *hdata)
+               DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
+               goto fail;
+       }
+-      res->hdmiphy = devm_clk_get(dev, "hdmiphy");
++      res->hdmiphy = devm_phy_get(dev, "hdmiphy");
+       if (IS_ERR(res->hdmiphy)) {
+-              DRM_ERROR("failed to get clock 'hdmiphy'\n");
++              DRM_ERROR("failed to get phy 'hdmiphy'\n");
+               goto fail;
+       }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1224-drm-exynos-hdmi-simplify-extracting-hpd-gpio-from-DT.patch b/patches.tizen/1224-drm-exynos-hdmi-simplify-extracting-hpd-gpio-from-DT.patch
new file mode 100644 (file)
index 0000000..2dfab25
--- /dev/null
@@ -0,0 +1,52 @@
+From ec8ae0fb250dd356a1ee4e534acda63e0d60d038 Mon Sep 17 00:00:00 2001
+From: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Date: Tue, 15 Oct 2013 16:40:07 +0200
+Subject: [PATCH 1224/1302] drm: exynos: hdmi: simplify extracting hpd-gpio
+ from DT
+
+This patch eliminates redundant checks while retrieving HPD gpio from DT during
+HDMI's probe().
+
+Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Change-Id: I1f2312291bd7c2334783c8067889b95db305377f
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_hdmi.c | 14 ++++----------
+ 1 file changed, 4 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
+index 9b52b4f..77f09ed 100644
+--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
++++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
+@@ -1857,24 +1857,18 @@ static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
+ {
+       struct device_node *np = dev->of_node;
+       struct s5p_hdmi_platform_data *pd;
+-      enum of_gpio_flags flags;
+-      u32 value;
+       pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
+       if (!pd)
+-              goto err_data;
++              return NULL;
+-      if (!of_find_property(np, "hpd-gpio", &value)) {
++      pd->hpd_gpio = of_get_named_gpio_flags(np, "hpd-gpio", 0, NULL);
++      if (pd->hpd_gpio < 0) {
+               DRM_ERROR("no hpd gpio property found\n");
+-              goto err_data;
++              return NULL;
+       }
+-      pd->hpd_gpio = of_get_named_gpio_flags(np, "hpd-gpio", 0, &flags);
+-
+       return pd;
+-
+-err_data:
+-      return NULL;
+ }
+ #else
+ static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1225-drm-exynos-migrate-to-Common-Clock-Framework.patch b/patches.tizen/1225-drm-exynos-migrate-to-Common-Clock-Framework.patch
new file mode 100644 (file)
index 0000000..d48b534
--- /dev/null
@@ -0,0 +1,113 @@
+From 0a704bea4be5d89d68f574630339c644cd5e0554 Mon Sep 17 00:00:00 2001
+From: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Date: Wed, 9 Oct 2013 15:51:00 +0200
+Subject: [PATCH 1225/1302] drm: exynos: migrate to Common Clock Framework
+
+Transform all clk_enable() to clk_prepare_enable() and
+all clk_disable() to clk_disable_unprepare().
+
+Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Change-Id: Iaf66f2229677234273c7b66f6d9f0f17c74bf2ff
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_hdmi.c  | 20 ++++++++++----------
+ drivers/gpu/drm/exynos/exynos_mixer.c | 12 ++++++------
+ 2 files changed, 16 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
+index 77f09ed..b8eca91 100644
+--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
++++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
+@@ -1112,9 +1112,9 @@ static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
+               hdmi_regs_dump(hdata, "timing apply");
+       }
+-      clk_disable(hdata->res.sclk_hdmi);
++      clk_disable_unprepare(hdata->res.sclk_hdmi);
+       clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
+-      clk_enable(hdata->res.sclk_hdmi);
++      clk_prepare_enable(hdata->res.sclk_hdmi);
+       /* enable HDMI and timing generator */
+       hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN);
+@@ -1279,9 +1279,9 @@ static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
+               hdmi_regs_dump(hdata, "timing apply");
+       }
+-      clk_disable(hdata->res.sclk_hdmi);
++      clk_disable_unprepare(hdata->res.sclk_hdmi);
+       clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
+-      clk_enable(hdata->res.sclk_hdmi);
++      clk_prepare_enable(hdata->res.sclk_hdmi);
+       /* enable HDMI and timing generator */
+       hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN);
+@@ -1305,9 +1305,9 @@ static void hdmiphy_conf_reset(struct hdmi_context *hdata)
+       u8 buffer[2];
+       u32 reg;
+-      clk_disable(hdata->res.sclk_hdmi);
++      clk_disable_unprepare(hdata->res.sclk_hdmi);
+       clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_pixel);
+-      clk_enable(hdata->res.sclk_hdmi);
++      clk_prepare_enable(hdata->res.sclk_hdmi);
+       /* operation mode */
+       buffer[0] = 0x1f;
+@@ -1685,8 +1685,8 @@ static void hdmi_poweron(struct hdmi_context *hdata)
+               DRM_DEBUG_KMS("failed to enable regulator bulk\n");
+       phy_power_on(res->hdmiphy);
+-      clk_enable(res->hdmi);
+-      clk_enable(res->sclk_hdmi);
++      clk_prepare_enable(res->hdmi);
++      clk_prepare_enable(res->sclk_hdmi);
+       hdmiphy_poweron(hdata);
+ }
+@@ -1707,8 +1707,8 @@ static void hdmi_poweroff(struct hdmi_context *hdata)
+       hdmiphy_conf_reset(hdata);
+       hdmiphy_poweroff(hdata);
+-      clk_disable(res->sclk_hdmi);
+-      clk_disable(res->hdmi);
++      clk_disable_unprepare(res->sclk_hdmi);
++      clk_disable_unprepare(res->hdmi);
+       phy_power_off(res->hdmiphy);
+       regulator_bulk_disable(res->regul_count, res->regul_bulk);
+diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
+index 7b41942..f853e584 100644
+--- a/drivers/gpu/drm/exynos/exynos_mixer.c
++++ b/drivers/gpu/drm/exynos/exynos_mixer.c
+@@ -892,10 +892,10 @@ static void mixer_poweron(struct mixer_context *ctx)
+       ctx->powered = true;
+       mutex_unlock(&ctx->mixer_mutex);
+-      clk_enable(res->mixer);
++      clk_prepare_enable(res->mixer);
+       if (ctx->vp_enabled) {
+-              clk_enable(res->vp);
+-              clk_enable(res->sclk_mixer);
++              clk_prepare_enable(res->vp);
++              clk_prepare_enable(res->sclk_mixer);
+       }
+       mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
+@@ -917,10 +917,10 @@ static void mixer_poweroff(struct mixer_context *ctx)
+       ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
+-      clk_disable(res->mixer);
++      clk_disable_unprepare(res->mixer);
+       if (ctx->vp_enabled) {
+-              clk_disable(res->vp);
+-              clk_disable(res->sclk_mixer);
++              clk_disable_unprepare(res->vp);
++              clk_disable_unprepare(res->sclk_mixer);
+       }
+       mutex_lock(&ctx->mixer_mutex);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1226-drm-exynos-add-compatibles-for-HDMI-and-Mixer-chips-.patch b/patches.tizen/1226-drm-exynos-add-compatibles-for-HDMI-and-Mixer-chips-.patch
new file mode 100644 (file)
index 0000000..3153898
--- /dev/null
@@ -0,0 +1,48 @@
+From fc65ef082636665f453848a82d8379d72f749e75 Mon Sep 17 00:00:00 2001
+From: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Date: Wed, 16 Oct 2013 13:41:14 +0200
+Subject: [PATCH 1226/1302] drm: exynos: add compatibles for HDMI and Mixer
+ chips and exynos4210 SoC
+
+This patch add proper compatibles for Mixer and HDMI chip
+available on exynos4210 SoCs.
+
+Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Change-Id: I5ca49ea9f95b139834de9ed8bba79b37b685bf3a
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_hdmi.c  | 3 +++
+ drivers/gpu/drm/exynos/exynos_mixer.c | 3 +++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
+index b8eca91..87c3f42 100644
+--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
++++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
+@@ -1899,6 +1899,9 @@ static struct platform_device_id hdmi_driver_types[] = {
+ #ifdef CONFIG_OF
+ static struct of_device_id hdmi_match_types[] = {
+       {
++              .compatible = "samsung,exynos4210-hdmi",
++              .data   = (void *)HDMI_TYPE13,
++      }, {
+               .compatible = "samsung,exynos5-hdmi",
+               .data   = (void *)HDMI_TYPE14,
+       }, {
+diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
+index f853e584..77faced 100644
+--- a/drivers/gpu/drm/exynos/exynos_mixer.c
++++ b/drivers/gpu/drm/exynos/exynos_mixer.c
+@@ -1139,6 +1139,9 @@ static struct platform_device_id mixer_driver_types[] = {
+ static struct of_device_id mixer_match_types[] = {
+       {
++              .compatible = "samsung,exynos4-mixer",
++              .data   = &exynos4_mxr_drv_data,
++      }, {
+               .compatible = "samsung,exynos5-mixer",
+               .data   = &exynos5_mxr_drv_data,
+       }, {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1227-drm-exynos-hdmi-add-support-for-pixel-clock-limitati.patch b/patches.tizen/1227-drm-exynos-hdmi-add-support-for-pixel-clock-limitati.patch
new file mode 100644 (file)
index 0000000..58ec0c3
--- /dev/null
@@ -0,0 +1,83 @@
+From b0e5279f26ee004363cc83edd012aa3036b06140 Mon Sep 17 00:00:00 2001
+From: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Date: Thu, 19 Dec 2013 16:24:07 +0100
+Subject: [PATCH 1227/1302] drm: exynos: hdmi: add support for pixel clock
+ limitation
+
+Adds support for limitation of maximal pixel clock of HDMI
+signal. This feature is needed on boards that contains
+lines or bridges with frequency limitations.
+
+Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Change-Id: I4cc38e995feeaca77b73e9ea0197d67f99d57715
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/gpu/drm/exynos/exynos_hdmi.c | 11 +++++++++++
+ include/media/s5p_hdmi.h             |  1 +
+ 2 files changed, 12 insertions(+)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
+index 87c3f42..a48cf75 100644
+--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
++++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
+@@ -201,6 +201,7 @@ struct hdmi_context {
+       struct hdmi_resources           res;
+       int                             hpd_gpio;
++      u32                             max_pixel_clock;
+       enum hdmi_type                  type;
+ };
+@@ -801,6 +802,8 @@ static int hdmi_check_mode(void *ctx, struct drm_display_mode *mode)
+               (mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
+               false, mode->clock * 1000);
++      if (mode->clock * 1000 > hdata->max_pixel_clock)
++              return -E2BIG;
+       ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
+       if (ret < 0)
+               return ret;
+@@ -1868,6 +1871,8 @@ static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
+               return NULL;
+       }
++      of_property_read_u32(np, "max-pixel-clock", &pd->max_pixel_clock);
++
+       return pd;
+ }
+ #else
+@@ -1934,6 +1939,11 @@ static int hdmi_probe(struct platform_device *pdev)
+               return -EINVAL;
+       }
++      if (!pdata->max_pixel_clock) {
++              DRM_LOG("max-pixel-clock is zero, using INF\n");
++              pdata->max_pixel_clock = ULONG_MAX;
++      }
++
+       drm_hdmi_ctx = devm_kzalloc(dev, sizeof(*drm_hdmi_ctx),
+                                                               GFP_KERNEL);
+       if (!drm_hdmi_ctx)
+@@ -1964,6 +1974,7 @@ static int hdmi_probe(struct platform_device *pdev)
+       }
+       hdata->hpd_gpio = pdata->hpd_gpio;
++      hdata->max_pixel_clock = pdata->max_pixel_clock;
+       hdata->dev = dev;
+       ret = hdmi_resources_init(hdata);
+diff --git a/include/media/s5p_hdmi.h b/include/media/s5p_hdmi.h
+index 181642b..7272d65 100644
+--- a/include/media/s5p_hdmi.h
++++ b/include/media/s5p_hdmi.h
+@@ -31,6 +31,7 @@ struct s5p_hdmi_platform_data {
+       int mhl_bus;
+       struct i2c_board_info *mhl_info;
+       int hpd_gpio;
++      u32 max_pixel_clock;
+ };
+ #endif /* S5P_HDMI_H */
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1228-arm-dts-exynos4-add-i2c-controller-for-HDMIPHY.patch b/patches.tizen/1228-arm-dts-exynos4-add-i2c-controller-for-HDMIPHY.patch
new file mode 100644 (file)
index 0000000..5ebc716
--- /dev/null
@@ -0,0 +1,51 @@
+From de39496c51970dfce9d2cca00b5328788cf76474 Mon Sep 17 00:00:00 2001
+From: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Date: Thu, 17 Oct 2013 13:56:04 +0200
+Subject: [PATCH 1228/1302] arm: dts: exynos4: add i2c controller for HDMIPHY
+
+This patch adds DT nodes for I2C controller dedicated for HDMIPHY.
+
+Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Change-Id: Ia45c9fc0594b534036175deaee5562ca66dcbcc0
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index 47605f1..b3798ce 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -36,6 +36,7 @@
+               i2c5 = &i2c_5;
+               i2c6 = &i2c_6;
+               i2c7 = &i2c_7;
++              i2c8 = &i2c_8;
+               csis0 = &csis_0;
+               csis1 = &csis_1;
+               fimc0 = &fimc_0;
+@@ -440,6 +441,21 @@
+               status = "disabled";
+       };
++      i2c_8: i2c@138E0000 {
++              #address-cells = <1>;
++              #size-cells = <0>;
++              compatible = "samsung,s3c2440-hdmiphy-i2c";
++              reg = <0x138E0000 0x100>;
++              interrupts = <0 93 0>;
++              clocks = <&clock 325>;
++              clock-names = "i2c";
++
++              hdmiphy@38 {
++                      compatible = "samsung,exynos5-hdmiphy";
++                      reg = <0x38>;
++              };
++      };
++
+       spi_0: spi@13920000 {
+               compatible = "samsung,exynos4210-spi";
+               reg = <0x13920000 0x100>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1229-arm-dts-exynos4-add-HDMI-devices.patch b/patches.tizen/1229-arm-dts-exynos4-add-HDMI-devices.patch
new file mode 100644 (file)
index 0000000..5491ff6
--- /dev/null
@@ -0,0 +1,89 @@
+From ec33e7cd05886957ccfeff317c9563d4ca0a8202 Mon Sep 17 00:00:00 2001
+From: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Date: Thu, 17 Oct 2013 13:56:04 +0200
+Subject: [PATCH 1229/1302] arm: dts: exynos4: add HDMI devices
+
+This patch adds DT nodes for HDMI related devices on SoCs from Exynos4 family.
+
+Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Change-Id: I92462470abd05ce14635b33a37b3f1e50e463085
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi    | 19 +++++++++++++++++++
+ arch/arm/boot/dts/exynos4210.dtsi | 12 ++++++++++++
+ arch/arm/boot/dts/exynos4412.dtsi | 12 ++++++++++++
+ 3 files changed, 43 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index b3798ce..2ec0547 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -744,4 +744,23 @@
+       cpufreq {
+               compatible = "samsung,exynos-cpufreq";
+       };
++
++      hdmi: hdmi@12D00000 {
++              reg = <0x12D00000 0x70000>;
++              interrupts = <0 92 0>;
++              clock-names = "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy";
++              clocks = <&clock 271>, <&clock 136>, <&clock 139>, <&clock 22>;
++              status = "disabled";
++              samsung,power-domain = <&pd_tv>;
++      };
++
++      mixer: mixer@12C10000 {
++              compatible = "samsung,exynos4-mixer";
++              interrupts = <0 91 0>;
++              reg = <0x12C10000 0x2100>, <0x12c00000 0x300>;
++              clock-names = "mixer", "sclk_hdmi", "vp", "sclk_dac", "sclk_mixer";
++              clocks = <&clock 269>, <&clock 136>, <&clock 268>, <&clock 138>, <&clock 137>;
++              samsung,power-domain = <&pd_tv>;
++              iommu = <&sysmmu_tv>;
++      };
+ };
+diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
+index 165e1e7..f6989aa 100644
+--- a/arch/arm/boot/dts/exynos4210.dtsi
++++ b/arch/arm/boot/dts/exynos4210.dtsi
+@@ -223,4 +223,16 @@
+               clock-names = "armclk", "moutcore", "mout_mpll", "mout_apll";
+               status = "disabled";
+       };
++
++      exynos_phy: exynos-phy@10020000 {
++              compatible = "exynos4210-phy";
++              reg = <0x10020000 0x1000>;
++              #phy-cells = <1>;
++      };
++
++      hdmi: hdmi@12D00000 {
++              phys = <&exynos_phy 0>;
++              phy-names = "hdmiphy";
++              compatible = "samsung,exynos4210-hdmi";
++      };
+ };
+diff --git a/arch/arm/boot/dts/exynos4412.dtsi b/arch/arm/boot/dts/exynos4412.dtsi
+index 2f4ca6f..b0fde4a 100644
+--- a/arch/arm/boot/dts/exynos4412.dtsi
++++ b/arch/arm/boot/dts/exynos4412.dtsi
+@@ -74,4 +74,16 @@
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
++
++      exynos_phy: exynos-phy@10020000 {
++              compatible = "exynos4412-phy";
++              reg = <0x10020000 0x1000>;
++              #phy-cells = <1>;
++      };
++
++      hdmi: hdmi@12D00000 {
++              phys = <&exynos_phy 0>;
++              phy-names = "hdmiphy";
++              compatible = "samsung,exynos5-hdmi";
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1230-arm-dts-universal_c210-add-HDMI-devices.patch b/patches.tizen/1230-arm-dts-universal_c210-add-HDMI-devices.patch
new file mode 100644 (file)
index 0000000..63801f3
--- /dev/null
@@ -0,0 +1,79 @@
+From 437b814567a2f8b99b78dc965e8ae069eb409ece Mon Sep 17 00:00:00 2001
+From: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Date: Thu, 17 Oct 2013 14:58:06 +0200
+Subject: [PATCH 1230/1302] arm: dts: universal_c210: add HDMI devices
+
+This patch adds configuration of HDMI devices on Universal C210 board.
+
+Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Change-Id: Ic391e351309d99dc5f7fef48f78ec08a89819cc9
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4210-universal_c210.dts | 53 +++++++++++++++++++++++++
+ 1 file changed, 53 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts
+index 045221e..558e36e 100644
+--- a/arch/arm/boot/dts/exynos4210-universal_c210.dts
++++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts
+@@ -458,4 +458,57 @@
+               status = "okay";
+               #phy-cells = <1>;
+       };
++
++      hdmi_en: voltage-regulator-hdmi-5v {
++              compatible = "regulator-fixed";
++              regulator-name = "HDMI_5V";
++              regulator-min-microvolt = <5000000>;
++              regulator-max-microvolt = <5000000>;
++              gpio = <&gpe0 1 0>;
++              enable-active-high;
++      };
++
++      i2c-ddc {
++              compatible = "i2c-gpio";
++              gpios = <&gpe4 2 0 &gpe4 3 0>;
++              i2c-gpio,delay-us = <100>;
++              #address-cells = <1>;
++              #size-cells = <0>;
++
++              pinctrl-0 = <&i2c_ddc_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              hdmiddc@72 {
++                      compatible = "samsung,exynos5-hdmiddc";
++                      reg = <0x72>;
++              };
++      };
++
++      hdmi: hdmi@12D00000 {
++              hpd-gpio = <&gpx3 7 0>;
++              pinctrl-names = "default";
++              pinctrl-0 = <&hdmi_hpd>;
++              hdmi-en-supply = <&hdmi_en>;
++              vdd-supply = <&ldo3_reg>;
++              vdd_osc-supply = <&ldo4_reg>;
++              vdd_pll-supply = <&ldo3_reg>;
++              status = "okay";
++      };
++};
++
++&pinctrl_1 {
++      hdmi_hpd: hdmi-hpd {
++              samsung,pins = "gpx3-7";
++              samsung,pin-pud = <0>;
++      };
++};
++
++&pinctrl_0 {
++      i2c_ddc_bus: i2c-ddc-bus {
++              samsung,pins = "gpe4-2", "gpe4-3";
++              samsung,pin-function = <2>;
++              samsung,pin-pud = <3>;
++              samsung,pin-drv = <0>;
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1231-arm-dts-exynos4412-slp-pq-add-HDMI-devices.patch b/patches.tizen/1231-arm-dts-exynos4412-slp-pq-add-HDMI-devices.patch
new file mode 100644 (file)
index 0000000..41c29ea
--- /dev/null
@@ -0,0 +1,106 @@
+From 42676260da9fc7a51084e9abb83da679b2e42b80 Mon Sep 17 00:00:00 2001
+From: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Date: Fri, 20 Dec 2013 12:33:58 +0100
+Subject: [PATCH 1231/1302] arm: dts: exynos4412-slp-pq: add HDMI devices
+
+This patch adds configuration of HDMI devices on SLP-PQ board.
+
+Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Change-Id: Ib2992887d3e0054d14dfba1872a575a707249849
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-slp_pq.dts | 73 +++++++++++++++++++++++++++++++++
+ 1 file changed, 73 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 9f268f4..281c7e7 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -1400,6 +1400,61 @@
+               vtmu-supply = <&ldo10_reg>;
+               status = "okay";
+       };
++
++      vsil: voltage-regulator-vsil {
++              compatible = "regulator-fixed";
++              regulator-name = "HDMI_5V";
++              regulator-min-microvolt = <5000000>;
++              regulator-max-microvolt = <5000000>;
++              gpio = <&gpl0 4 0>;
++              enable-active-high;
++              vin-supply = <&buck7_reg>;
++      };
++
++      i2c-mhl {
++              compatible = "i2c-gpio";
++              gpios = <&gpf0 4 0 &gpf0 6 0>;
++              i2c-gpio,delay-us = <100>;
++              #address-cells = <1>;
++              #size-cells = <0>;
++
++              pinctrl-0 = <&i2c_mhl_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              sii9234: sii9234@39 {
++                      compatible = "sii,sii9234";
++                      vcc-supply = <&vsil>;
++                      gpio-reset = <&gpf3 4 0>;
++                      gpio-int = <&gpf3 5 0>;
++                      reg = <0x39>;
++                      extcon = <&max_muic>;
++              };
++      };
++
++      i2c@138B0000 {
++              hdmiddc@37 {
++                      compatible = "samsung,exynos5-hdmiddc";
++                      reg = <0x37>;
++              };
++      };
++
++      hdmi@12D00000 {
++              hpd-gpio = <&gpx3 7 0>;
++              pinctrl-names = "default";
++              pinctrl-0 = <&hdmi_hpd>;
++              /*
++               * HDMI_EN gpio is controlled by SII9234, so hdmi-en should
++               * be a dummy regulator. Therefore LDO3 is used instead
++               * because it is enabled at the same time as hdmi-en
++               */
++              hdmi-en-supply = <&ldo3_reg>;
++              vdd-supply = <&ldo3_reg>;
++              vdd_osc-supply = <&ldo4_reg>;
++              vdd_pll-supply = <&ldo3_reg>;
++              status = "okay";
++              max-pixel-clock = <75000000>;
++      };
+ };
+ &pinctrl_1 {
+@@ -1416,4 +1471,22 @@
+               samsung,pins = "gpx2-5";
+               samsung,pin-pud = <1>;
+       };
++
++      hdmi_hpd: hdmi-hpd {
++              samsung,pins = "gpx3-7";
++              samsung,pin-pud = <1>;
++      };
++};
++
++&pinctrl_0 {
++      mhl_int: mhl-int {
++              samsung,pins = "gpf3-5";
++              samsung,pin-pud = <0>;
++      };
++      i2c_mhl_bus: i2c-mhl-bus {
++              samsung,pins = "gpf0-4", "gpf0-6";
++              samsung,pin-function = <2>;
++              samsung,pin-pud = <1>;
++              samsung,pin-drv = <0>;
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1232-arm-config-tizen-enable-HDMI-drivers.patch b/patches.tizen/1232-arm-config-tizen-enable-HDMI-drivers.patch
new file mode 100644 (file)
index 0000000..43d326b
--- /dev/null
@@ -0,0 +1,53 @@
+From 580aed482d6755e865c723a61cef68b148354cd6 Mon Sep 17 00:00:00 2001
+From: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Date: Wed, 12 Feb 2014 16:03:51 +0100
+Subject: [PATCH 1232/1302] arm: config: tizen: enable HDMI drivers
+
+This patch enables HDMI drivers including:
+- DRM HDMI
+- SII9234 HDMI-to-MHL bridge
+- Exynos PHY
+
+Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Change-Id: I8d9d6d6163bdda2c8d299bcd8048b10fa7bb2f35
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_defconfig | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index 1b89de4..73702f2 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -1138,6 +1138,7 @@ CONFIG_BLK_DEV_RAM_SIZE=16384
+ # CONFIG_LATTICE_ECP3_CONFIG is not set
+ CONFIG_SLP_GLOBAL_LOCK=y
+ # CONFIG_SRAM is not set
++CONFIG_SII9234=y
+ # CONFIG_C2PORT is not set
+ #
+@@ -2215,10 +2216,10 @@ CONFIG_DRM_KMS_HELPER=y
+ # CONFIG_DRM_I2C_SIL164 is not set
+ # CONFIG_DRM_I2C_NXP_TDA998X is not set
+ CONFIG_DRM_EXYNOS=y
+-CONFIG_DRM_EXYNOS_IOMMU=y
++# CONFIG_DRM_EXYNOS_IOMMU is not set
+ CONFIG_DRM_EXYNOS_DMABUF=y
+ CONFIG_DRM_EXYNOS_FIMD=y
+-# CONFIG_DRM_EXYNOS_HDMI is not set
++CONFIG_DRM_EXYNOS_HDMI=y
+ CONFIG_DRM_EXYNOS_VIDI=y
+ CONFIG_DRM_EXYNOS_G2D=y
+ CONFIG_DRM_EXYNOS_IPP=y
+@@ -3109,6 +3110,7 @@ CONFIG_PHY_EXYNOS_MIPI_VIDEO=y
+ CONFIG_PHY_EXYNOS_USB=y
+ CONFIG_PHY_EXYNOS4210_USB=y
+ CONFIG_PHY_EXYNOS4212_USB=y
++CONFIG_EXYNOS_PHY=y
+ #
+ # File systems
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1233-usb-gadget-Enable-rndis-in-the-slp-gadget-driver.patch b/patches.tizen/1233-usb-gadget-Enable-rndis-in-the-slp-gadget-driver.patch
new file mode 100644 (file)
index 0000000..832d9b2
--- /dev/null
@@ -0,0 +1,32 @@
+From 887a1becf23f74a5882426a449da3c4595fa1e4d Mon Sep 17 00:00:00 2001
+From: Jacek Bukarewicz <j.bukarewicz@samsung.com>
+Date: Fri, 14 Feb 2014 15:22:16 +0100
+Subject: [PATCH 1233/1302] usb: gadget: Enable rndis in the slp gadget driver
+
+Rndis was disabled temporarily in commit 7ca93af to fix build break.
+It can be enabled now as commit 65c9d04 adapted slp driver to the new interface
+of rndis.
+
+Change-Id: Id28413de771818cf1a358664d637aa989615fe26
+Signed-off-by: Jacek Bukarewicz <j.bukarewicz@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/gadget/slp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/slp.c b/drivers/usb/gadget/slp.c
+index 70b7d2f..bc96492 100644
+--- a/drivers/usb/gadget/slp.c
++++ b/drivers/usb/gadget/slp.c
+@@ -154,7 +154,7 @@ struct slp_multi_dev {
+ };
+ /* TODO: only enabled 'rndis' and 'sdb'. need to verify more functions */
+-static const char *default_funcs[] = {"sdb"};
++static const char *default_funcs[] = {"rndis", "sdb"};
+ static unsigned slp_multi_nluns;
+ static struct class *slp_multi_class;
+ static struct slp_multi_dev *_slp_multi_dev;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1234-arm-dts-cleanup-entries-for-usb-phy-for-Exynos4.patch b/patches.tizen/1234-arm-dts-cleanup-entries-for-usb-phy-for-Exynos4.patch
new file mode 100644 (file)
index 0000000..dbd4ff6
--- /dev/null
@@ -0,0 +1,271 @@
+From ca0f41d5be1d74e991e8a163a9bf317d64d374a2 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Tue, 18 Feb 2014 09:07:09 +0100
+Subject: [PATCH 1234/1302] arm: dts: cleanup entries for usb phy for Exynos4
+
+Remove old, obsoleted entries for usb phy and move new common nodes to
+exynos4x12/exynos4.dtsi files.
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-Id: Ie73f5d365dd72ee4cf4f39c7b07706ec286356fe
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi                  |  2 ++
+ arch/arm/boot/dts/exynos4210-origen.dts         | 10 +---------
+ arch/arm/boot/dts/exynos4210-trats.dts          | 10 +---------
+ arch/arm/boot/dts/exynos4210-universal_c210.dts | 10 +---------
+ arch/arm/boot/dts/exynos4210.dtsi               | 10 ++++++++++
+ arch/arm/boot/dts/exynos4212-slp_pd.dts         | 10 +---------
+ arch/arm/boot/dts/exynos4412-odroidx2.dts       | 10 +---------
+ arch/arm/boot/dts/exynos4412-redwoodlte.dts     |  2 +-
+ arch/arm/boot/dts/exynos4412-slp_pq.dts         | 11 +----------
+ arch/arm/boot/dts/exynos4x12.dtsi               | 19 +++++++------------
+ 10 files changed, 26 insertions(+), 68 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index 2ec0547..751847e 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -518,6 +518,8 @@
+               interrupts = <0 71 0>;
+               clocks = <&clock 305>;
+               clock-names = "otg";
++              phys = <&exynos_usbphy 0>;
++              phy-names = "device";
+               status = "disabled";
+       };
+diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts
+index 862463b..42240f3 100644
+--- a/arch/arm/boot/dts/exynos4210-origen.dts
++++ b/arch/arm/boot/dts/exynos4210-origen.dts
+@@ -170,8 +170,6 @@
+               status = "okay";
+               vusb_d-supply = <&ldo8_reg>;
+               vusb_a-supply = <&ldo3_reg>;
+-              phys = <&exynos_usbphy 0>;
+-              phy-names = "device";
+       };
+       ehci@12580000 {
+@@ -331,13 +329,7 @@
+               };
+       };
+-      exynos_usbphy: exynos-usbphy@125B0000 {
+-              compatible = "samsung,exynos4210-usbphy";
+-              reg = <0x125B0000 0x100 0x10020704 0x0c 0x1001021c 0x4>;
+-              clocks = <&clock 305>, <&clock 2>, <&clock 2>, <&clock 2>,
+-                                                              <&clock 2>;
+-              clock-names = "phy", "device", "host", "hsic0", "hsic1";
++      exynos-usbphy@125B0000 {
+               status = "okay";
+-              #phy-cells = <1>;
+       };
+ };
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index e783c05..0e2e165 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -527,8 +527,6 @@
+               status = "okay";
+               vusb_d-supply = <&vusb_reg>;
+               vusb_a-supply = <&vusbdac_reg>;
+-              phys = <&exynos_usbphy 0>;
+-              phy-names = "device";
+               status = "okay";
+       };
+@@ -703,13 +701,7 @@
+               vusb_a-supply = <&vusbdac_reg>;
+       };
+-      exynos_usbphy: exynos-usbphy@125B0000 {
+-              compatible = "samsung,exynos4210-usbphy";
+-              reg = <0x125B0000 0x100 0x10020704 0x0c 0x1001021c 0x4>;
+-              clocks = <&clock 305>, <&clock 2>, <&clock 2>, <&clock 2>,
+-                                                              <&clock 2>;
+-              clock-names = "phy", "device", "host", "hsic0", "hsic1";
++      exynos-usbphy@125B0000 {
+               status = "okay";
+-              #phy-cells = <1>;
+       };
+ };
+diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts
+index 558e36e..67479eb 100644
+--- a/arch/arm/boot/dts/exynos4210-universal_c210.dts
++++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts
+@@ -77,8 +77,6 @@
+       hsotg@12480000 {
+               vusb_d-supply = <&ldo3_reg>;
+               vusb_a-supply = <&ldo8_reg>;
+-              phys = <&exynos_usbphy 0>;
+-              phy-names = "device";
+               status = "okay";
+       };
+@@ -449,14 +447,8 @@
+               vusb_a-supply = <&ldo8_reg>;
+       };
+-      exynos_usbphy: exynos-usbphy@125B0000 {
+-              compatible = "samsung,exynos4210-usbphy";
+-              reg = <0x125B0000 0x100 0x10020704 0x0c 0x1001021c 0x4>;
+-              clocks = <&clock 305>, <&clock 2>, <&clock 2>, <&clock 2>,
+-                                                              <&clock 2>;
+-              clock-names = "phy", "device", "host", "hsic0", "hsic1";
++      exynos-usbphy@125B0000 {
+               status = "okay";
+-              #phy-cells = <1>;
+       };
+       hdmi_en: voltage-regulator-hdmi-5v {
+diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
+index f6989aa..3fdfaf3 100644
+--- a/arch/arm/boot/dts/exynos4210.dtsi
++++ b/arch/arm/boot/dts/exynos4210.dtsi
+@@ -235,4 +235,14 @@
+               phy-names = "hdmiphy";
+               compatible = "samsung,exynos4210-hdmi";
+       };
++
++      exynos_usbphy: exynos-usbphy@125B0000 {
++              compatible = "samsung,exynos4210-usbphy";
++              reg = <0x125B0000 0x100 0x10020704 0x0c 0x1001021c 0x4>;
++              clocks = <&clock 305>, <&clock 2>, <&clock 2>, <&clock 2>,
++                                                              <&clock 2>;
++              clock-names = "phy", "device", "host", "hsic0", "hsic1";
++              status = "disabled";
++              #phy-cells = <1>;
++      };
+ };
+diff --git a/arch/arm/boot/dts/exynos4212-slp_pd.dts b/arch/arm/boot/dts/exynos4212-slp_pd.dts
+index cdf5cc3..01a2383 100644
+--- a/arch/arm/boot/dts/exynos4212-slp_pd.dts
++++ b/arch/arm/boot/dts/exynos4212-slp_pd.dts
+@@ -332,18 +332,10 @@
+               status = "okay";
+               vusb_d-supply = <&ldo8_reg>;
+               vusb_a-supply = <&ldo11_reg>;
+-              phys = <&exynos_usbphy 0>;
+-              phy-names = "device";
+       };
+-      exynos_usbphy: exynos-usbphy@125B0000 {
+-              compatible = "samsung,exynos4212-usbphy";
+-              reg = <0x125B0000 0x100>, <0x10020704 0x0c>, <0x1001021c 0x4>;
+-              clocks = <&clock 305>, <&clock 2>, <&clock 2>, <&clock 2>,
+-                                                              <&clock 2>;
+-              clock-names = "phy", "device", "host", "hsic0", "hsic1";
++      exynos-usbphy@125B0000 {
+               status = "okay";
+-              #phy-cells = <1>;
+       };
+       cpufreq {
+diff --git a/arch/arm/boot/dts/exynos4412-odroidx2.dts b/arch/arm/boot/dts/exynos4412-odroidx2.dts
+index 05fea1b..c522ee6 100644
+--- a/arch/arm/boot/dts/exynos4412-odroidx2.dts
++++ b/arch/arm/boot/dts/exynos4412-odroidx2.dts
+@@ -433,8 +433,6 @@
+               status = "okay";
+               vusb_d-supply = <&ldo15_reg>;
+               vusb_a-supply = <&ldo12_reg>;
+-              phys = <&exynos_usbphy 0>;
+-              phy-names = "device";
+       };
+       ehci@12580000 {
+@@ -445,14 +443,8 @@
+               phy-names = "hsic0";
+       };
+-      exynos_usbphy: exynos-usbphy@125B0000 {
+-              compatible = "samsung,exynos4212-usbphy";
+-              reg = <0x125B0000 0x100 0x10020704 0x0c 0x1001021c 0x4>;
+-              clocks = <&clock 305>, <&clock 2>, <&clock 2>, <&clock 2>,
+-                                                              <&clock 2>;
+-              clock-names = "phy", "device", "host", "hsic0", "hsic1";
++      exynos-usbphy@125B0000 {
+               status = "okay";
+-              #phy-cells = <1>;
+       };
+       register-debug {
+diff --git a/arch/arm/boot/dts/exynos4412-redwoodlte.dts b/arch/arm/boot/dts/exynos4412-redwoodlte.dts
+index 6d38430..da1e7df 100644
+--- a/arch/arm/boot/dts/exynos4412-redwoodlte.dts
++++ b/arch/arm/boot/dts/exynos4412-redwoodlte.dts
+@@ -647,7 +647,7 @@
+               mmu-master = <&g2d>;
+       };
+-      usbphy@125B0000 {
++      exynos-usbphy@125B0000 {
+               status = "okay";
+       };
+diff --git a/arch/arm/boot/dts/exynos4412-slp_pq.dts b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+index 281c7e7..7566367 100644
+--- a/arch/arm/boot/dts/exynos4412-slp_pq.dts
++++ b/arch/arm/boot/dts/exynos4412-slp_pq.dts
+@@ -1069,8 +1069,6 @@
+               vusb_d-supply = <&ldo15_reg>;
+               vusb_a-supply = <&ldo12_reg>;
+               extcon = <&max_muic>;
+-              phys = <&exynos_usbphy 0>;
+-              phy-names = "device";
+       };
+       ehci@12580000 {
+@@ -1373,15 +1371,8 @@
+               status = "okay";
+       };
+-
+-      exynos_usbphy: exynos-usbphy@125B0000 {
+-              compatible = "samsung,exynos4212-usbphy";
+-              reg = <0x125B0000 0x100>, <0x10020704 0x0c>, <0x1001021c 0x4>;
+-              clocks = <&clock 305>, <&clock 2>, <&clock 2>, <&clock 2>,
+-                                                              <&clock 2>;
+-              clock-names = "phy", "device", "host", "hsic0", "hsic1";
++      exynos-usbphy@125B0000 {
+               status = "okay";
+-              #phy-cells = <1>;
+       };
+       adc: adc@126C0000 {
+diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
+index f47b326..f7b96ba 100644
+--- a/arch/arm/boot/dts/exynos4x12.dtsi
++++ b/arch/arm/boot/dts/exynos4x12.dtsi
+@@ -194,19 +194,14 @@
+               status = "ok";
+       };
+-      usbphy@125B0000 {
+-              compatible = "samsung,exynos4x12-usb2phy";
+-              reg = <0x125B0000 0x100>;
+-              ranges;
+-              #address-cells = <1>;
+-              #size-cells = <1>;
+-              clocks = <&clock 305>;
+-              clock-names = "otg";
++      exynos_usbphy: exynos-usbphy@125B0000 {
++              compatible = "samsung,exynos4212-usbphy";
++              reg = <0x125B0000 0x100>, <0x10020704 0x0c>, <0x1001021c 0x4>;
++              clocks = <&clock 305>, <&clock 2>, <&clock 2>, <&clock 2>,
++                                                              <&clock 2>;
++              clock-names = "phy", "device", "host", "hsic0", "hsic1";
+               status = "disabled";
+-
+-              usbphy-sys {
+-                      reg = <0x10020704 0x0c>;
+-              };
++              #phy-cells = <1>;
+       };
+       camera {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1235-ARM-exynos-dts-cleanup-the-dts-file-for-trats2.patch b/patches.tizen/1235-ARM-exynos-dts-cleanup-the-dts-file-for-trats2.patch
new file mode 100644 (file)
index 0000000..d3084bc
--- /dev/null
@@ -0,0 +1,3195 @@
+From 34dc81e8c1185d6d8127ef3cf654c78b752a8ed2 Mon Sep 17 00:00:00 2001
+From: Jaehoon Chung <jh80.chung@samsung.com>
+Date: Mon, 17 Feb 2014 17:28:43 +0900
+Subject: [PATCH 1235/1302] ARM: exynos: dts: cleanup the dts file for trats2
+
+Unused dts file is removed, and trats2.dts file is created.
+It's maintained more better than before.
+
+Change-Id: Ie51a02044a988fd0e2c8deac2c5fd407f5e374da
+Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/Makefile                  |    5 +-
+ arch/arm/boot/dts/exynos4212-slp_pd.dts     |  353 ------
+ arch/arm/boot/dts/exynos4412-m0.dts         |  247 -----
+ arch/arm/boot/dts/exynos4412-redwood.dts    |  162 ---
+ arch/arm/boot/dts/exynos4412-redwoodlte.dts |  756 -------------
+ arch/arm/boot/dts/exynos4412-trats2.dts     | 1601 +++++++++++++++++++++++++++
+ 6 files changed, 1602 insertions(+), 1522 deletions(-)
+ delete mode 100644 arch/arm/boot/dts/exynos4212-slp_pd.dts
+ delete mode 100644 arch/arm/boot/dts/exynos4412-m0.dts
+ delete mode 100644 arch/arm/boot/dts/exynos4412-redwood.dts
+ delete mode 100644 arch/arm/boot/dts/exynos4412-redwoodlte.dts
+ create mode 100644 arch/arm/boot/dts/exynos4412-trats2.dts
+
+diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
+index b17a6dc..ec83818 100644
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -50,12 +50,9 @@ dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \
+       exynos4210-smdkv310.dtb \
+       exynos4210-trats.dtb \
+       exynos4210-universal_c210.dtb \
+-      exynos4212-slp_pd.dtb \
+-      exynos4412-m0.dtb \
++      exynos4412-trats2.dtb \
+       exynos4412-odroidx.dtb \
+       exynos4412-odroidx2.dtb \
+-      exynos4412-redwood.dtb \
+-      exynos4412-redwoodlte.dtb \
+       exynos4412-smdk4412.dtb \
+       exynos4412-slp_pq.dtb \
+       exynos4412-origen.dtb \
+diff --git a/arch/arm/boot/dts/exynos4212-slp_pd.dts b/arch/arm/boot/dts/exynos4212-slp_pd.dts
+deleted file mode 100644
+index 01a2383..0000000
+--- a/arch/arm/boot/dts/exynos4212-slp_pd.dts
++++ /dev/null
+@@ -1,353 +0,0 @@
+-/*
+- * Samsung's Exynos4412 based SMDK board device tree source
+- *
+- * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+- *            http://www.samsung.com
+- *
+- * Device tree source file for Samsung's SMDK4412 board which is based on
+- * Samsung's Exynos4412 SoC.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License version 2 as
+- * published by the Free Software Foundation.
+-*/
+-
+-/dts-v1/;
+-/include/ "exynos4212.dtsi"
+-
+-/ {
+-      model = "Samsung PegasusD evaluation board based on Exynos4212";
+-      compatible = "samsung,slp_pd", "samsung,exynos4412";
+-
+-      aliases {
+-      };
+-
+-      memory {
+-              reg = <0x40000000 0x40000000>;
+-
+-              reserved-memory {
+-                      #address-cells = <1>;
+-                      #size-cells = <1>;
+-
+-                      contig_mem: region@71000000 {
+-                              compatible = "linux,contiguous-memory-region";
+-                              reg = <0x71000000 0x0c000000>;
+-                              linux,default-contiguous-region;
+-                      };
+-              };
+-      };
+-
+-      chosen {
+-              bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc";
+-      };
+-
+-      vemmc_reg: voltage-regulator@0 {
+-              compatible = "regulator-fixed";
+-              regulator-name = "VMEM_VDD_2.8V";
+-              regulator-min-microvolt = <2800000>;
+-              regulator-max-microvolt = <2800000>;
+-              gpio = <&gpk0 2 0>;
+-              enable-active-high;
+-      };
+-
+-      mshc@12550000 {
+-              num-slots = <1>;
+-              supports-highspeed;
+-              broken-cd;
+-              non-removable;
+-              fifo-depth = <0x80>;
+-              card-detect-delay = <200>;
+-              clocks = <&clock 351>, <&clock 132>;
+-              clock-name = "biu", "ciu";
+-              vmmc-supply = <&vemmc_reg>;
+-              clock-frequency = <400000000>;
+-              samsung,dw-mshc-ciu-div = <0>;
+-              samsung,dw-mshc-sdr-timing = <2 3>;
+-              samsung,dw-mshc-ddr-timing = <1 2>;
+-              pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>;
+-              pinctrl-names = "default";
+-              status = "disabled";
+-
+-              slot@0 {
+-                      reg = <0>;
+-                      bus-width = <8>;
+-              };
+-      };
+-
+-      sdhci_emmc: sdhci@12510000 {
+-              bus-width = <8>;
+-              non-removable;
+-              pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus8>;
+-              pinctrl-names = "default";
+-              vmmc-supply = <&vemmc_reg>;
+-              status = "okay";
+-      };
+-
+-      sdhci_sd: sdhci@12530000 {
+-              bus-width = <4>;
+-              cd-gpios = <&gpx3 4 0>;
+-              cd-inverted;
+-              interrupts = <0 75 0>;
+-              pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4>;
+-              pinctrl-names = "default";
+-              status = "okay";
+-      };
+-
+-      serial@13800000 {
+-              status = "okay";
+-      };
+-
+-      serial@13810000 {
+-              status = "okay";
+-      };
+-
+-      serial@13820000 {
+-              status = "okay";
+-      };
+-
+-      serial@13830000 {
+-              status = "okay";
+-      };
+-
+-      fixed-rate-clocks {
+-              xxti {
+-                      compatible = "samsung,clock-xxti";
+-                      clock-frequency = <0>;
+-              };
+-
+-              xusbxti {
+-                      compatible = "samsung,clock-xusbxti";
+-                      clock-frequency = <24000000>;
+-              };
+-      };
+-
+-      i2c@138B0000 {
+-              samsung,i2c-sda-delay = <100>;
+-              samsung,i2c-slave-addr = <0x10>;
+-              samsung,i2c-max-bus-freq = <100000>;
+-              pinctrl-0 = <&i2c5_bus>;
+-              pinctrl-names = "default";
+-              status = "okay";
+-
+-              max8997: max8997_pmic@66 {
+-                      compatible = "maxim,max8997-pmic";
+-                      interrupt-parent = <&gpx0>;
+-                      interrupts = <7 0>;
+-                      reg = <0x66>;
+-
+-                      max8997,pmic-buck1-uses-gpio-dvs;
+-                      max8997,pmic-buck2-uses-gpio-dvs;
+-                      max8997,pmic-buck5-uses-gpio-dvs;
+-
+-                      max8997,pmic-ignore-gpiodvs-side-effect;
+-                      max8997,pmic-buck125-default-dvs-idx = <0>;
+-
+-                      max8997,pmic-buck125-dvs-gpios = <&gpj1 1 0>,
+-                                                       <&gpj1 2 0>,
+-                                                       <&gpl0 0 0>;
+-
+-                      max8997,pmic-buck1-dvs-voltage = <1350000>, <1300000>,
+-                                                       <1250000>, <1200000>,
+-                                                       <1150000>, <1100000>,
+-                                                       <1000000>, <950000>;
+-
+-                      max8997,pmic-buck2-dvs-voltage = <1100000>, <1000000>,
+-                                                       <950000>,  <900000>,
+-                                                       <1100000>, <1000000>,
+-                                                       <950000>,  <900000>;
+-
+-                      max8997,pmic-buck5-dvs-voltage = <1200000>, <1200000>,
+-                                                       <1200000>, <1200000>,
+-                                                       <1200000>, <1200000>,
+-                                                       <1200000>, <1200000>;
+-
+-                      regulators {
+-
+-                              ldo1_reg: LDO1 {
+-                                      regulator-name = "VMIPI_1.8V_AP";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo2_reg: LDO2 {
+-                                      regulator-name = "VALIVE_1.0A_AP";
+-                                      regulator-min-microvolt = <1000000>;
+-                                      regulator-max-microvolt = <1000000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo3_reg: LDO3 {
+-                                      regulator-name = "VMPLL_1.0V_AP";
+-                                      regulator-min-microvolt = <1000000>;
+-                                      regulator-max-microvolt = <1000000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo4_reg: LDO4 {
+-                                      regulator-name = "VABB02_1.8V_AP";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo5_reg: LDO5 {
+-                                      regulator-name = "VABB1_1.8V_AP";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo6_reg: LDO6 {
+-                                      regulator-name = "VCC_1.8V_AP";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo7_reg: LDO7 {
+-                                      regulator-name = "CAM_ISP_1.8V";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo8_reg: LDO8 {
+-                                      regulator-name = "VUOTG_3.0V_AP";
+-                                      regulator-min-microvolt = <3000000>;
+-                                      regulator-max-microvolt = <3000000>;
+-                              };
+-
+-                              ldo9_reg: LDO9 {
+-                                      regulator-name = "VCC_2.8V_AP";
+-                                      regulator-min-microvolt = <2800000>;
+-                                      regulator-max-microvolt = <2800000>;
+-                              };
+-
+-                              ldo10_reg: LDO10 {
+-                                      regulator-name = "VPLL_1.0V_AP";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo11_reg: LDO11 {
+-                                      regulator-name = "VMIPI_1.0V_AP";
+-                                      regulator-min-microvolt = <1000000>;
+-                                      regulator-max-microvolt = <1000000>;
+-                              };
+-
+-                              ldo12_reg: LDO12 {
+-                                      regulator-name = "VT_CAM_1.8";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                              };
+-
+-                              ldo13_reg: LDO13 {
+-                                      regulator-name = "VCC_3.3V_LCD";
+-                                      regulator-min-microvolt = <3300000>;
+-                                      regulator-max-microvolt = <3300000>;
+-                              };
+-
+-                              ldo14_reg: LDO14 {
+-                                      regulator-name = "VCC_1.8V_IO";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                              };
+-
+-                              ldo15_reg: LDO15 {
+-                                      regulator-name = "LCD_VDD_2.2V";
+-                                      regulator-min-microvolt = <2200000>;
+-                                      regulator-max-microvolt = <2200000>;
+-                              };
+-
+-                              ldo16_reg: LDO16 {
+-                                      regulator-name = "CAM_SENSOR_IO_1.8V";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                              };
+-
+-                              ldo17_reg: LDO17 {
+-                                      regulator-name = "CAM_AF_2.8V";
+-                                      regulator-min-microvolt = <2800000>;
+-                                      regulator-max-microvolt = <2800000>;
+-                                      regulator-mem-idle;
+-                              };
+-
+-                              ldo18_reg: LDO18 {
+-                                      regulator-name = "TSP_AVDD_3.3V";
+-                                      regulator-min-microvolt = <3300000>;
+-                                      regulator-max-microvolt = <3300000>;
+-                              };
+-
+-                              vddq_reg: LDO21 {
+-                                   regulator-name = "VM1M2_1.2V_AP";
+-                                   regulator-min-microvolt = <1200000>;
+-                                   regulator-max-microvolt = <1200000>;
+-                                   regulator-always-on;
+-                              };
+-
+-                              buck1_reg: BUCK1 {
+-                                      regulator-name = "vdd_arm";
+-                                      regulator-min-microvolt = <900000>;
+-                                      regulator-max-microvolt = <1350000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              buck2_reg: BUCK2 {
+-                                      regulator-name = "vdd_int";
+-                                      regulator-min-microvolt = <900000>;
+-                                      regulator-max-microvolt = <1100000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              buck3_reg: BUCK3 {
+-                                      regulator-name = "VG3D_1.0V_AP";
+-                                      regulator-min-microvolt = <850000>;
+-                                      regulator-max-microvolt = <1100000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              buck4_reg: BUCK4 {
+-                                      regulator-name = "CAM_ISO_CORE_1.2V";
+-                                      regulator-min-microvolt = <1200000>;
+-                                      regulator-max-microvolt = <1200000>;
+-                              };
+-
+-                              safe1_sreg: ESAFEOUT1 {
+-                                   regulator-name = "SAFEOUT1";
+-                                   regulator-always-on;
+-                              };
+-
+-                              safe2_sreg: ESAFEOUT2 {
+-                                   regulator-name = "SAFEOUT2";
+-                                   regulator-boot-on;
+-                              };
+-
+-                      };
+-              };
+-      };
+-
+-      hsotg@12480000 {
+-              status = "okay";
+-              vusb_d-supply = <&ldo8_reg>;
+-              vusb_a-supply = <&ldo11_reg>;
+-      };
+-
+-      exynos-usbphy@125B0000 {
+-              status = "okay";
+-      };
+-
+-      cpufreq {
+-              freq_table;
+-              volt_table = <1350000 1300000 1300000 1250000 1250000 1200000
+-                           1200000 1150000 1100000 1000000 1000000 950000
+-                           950000 950000>;
+-              status = "okay";
+-      };
+-
+-      tmu@100C0000 {
+-              vtmu-supply = <&ldo4_reg>;
+-              status = "okay";
+-      };
+-};
+diff --git a/arch/arm/boot/dts/exynos4412-m0.dts b/arch/arm/boot/dts/exynos4412-m0.dts
+deleted file mode 100644
+index 9aefa58..0000000
+--- a/arch/arm/boot/dts/exynos4412-m0.dts
++++ /dev/null
+@@ -1,247 +0,0 @@
+-/*
+- * Samsung's Exynos4412 based M0 board device tree source
+- *
+- * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+- *            http://www.samsung.com
+- *
+- * Device tree source file for Samsung's M0 board which is based on
+- * Samsung's Exynos4412 SoC.
+- *
+- * 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/ "exynos4412-slp_pq.dts"
+-
+-/ {
+-      model = "Samsung M0 based on Exynos4412";
+-      compatible = "samsung,m0", "samsung,exynos4412";
+-
+-      aliases {
+-              i2c20 = &i2c_touch_key;
+-              i2c21 = &i2c_cm36651;
+-      };
+-
+-      pinctrl@11400000 {
+-              vt_cam_id: vt-cam-id {
+-                      samsung,pins = "gpf1-2";
+-                      samsung,pin-function = <2>;
+-                      samsung,pin-pud = <1>;
+-                      samsung,pin-drv = <3>;
+-              };
+-      };
+-
+-      gpio-keys@0 {
+-              compatible = "gpio-keys";
+-
+-              key@114 {
+-                      interrupt-parent = <&gpx3>;
+-                      interrupts = <3 0>;
+-                      gpios = <&gpx3 3 1>;
+-                      linux,code = <114>;
+-                      label = "volume down";
+-                      debounce-interval = <10>;
+-              };
+-
+-              key@115 {
+-                      interrupt-parent = <&gpx2>;
+-                      interrupts = <2 0>;
+-                      gpios = <&gpx2 2 1>;
+-                      linux,code = <115>;
+-                      label = "volume up";
+-                      debounce-interval = <10>;
+-              };
+-
+-              key@116 {
+-                      interrupt-parent = <&gpx2>;
+-                      interrupts = <7 0>;
+-                      gpios = <&gpx2 7 1>;
+-                      linux,code = <116>;
+-                      label = "power";
+-                      debounce-interval = <10>;
+-                      gpio-key,wakeup;
+-              };
+-
+-              key@139 {
+-                      interrupt-parent = <&gpx0>;
+-                      interrupts = <1 0>;
+-                      gpios = <&gpx0 1 1>;
+-                      linux,code = <139>;
+-                      label = "ok";
+-                      debounce-interval = <10>;
+-                      gpio-key,wakeup;
+-              };
+-      };
+-
+-      i2c_touch_key: i2c-gpio-3 {
+-              compatible = "i2c-gpio";
+-              gpios = <&gpl0 2 0>, <&gpl0 1 0>;
+-              i2c-gpio,delay-us = <2>;
+-              #address-cells = <1>;
+-              #size-cells = <0>;
+-              status = "okay";
+-
+-              touch_key@20 {
+-                      compatible = "mcs5080_touchkey";
+-                      reg = <0x20>;
+-                      interrupt-parent = <&gpj0>;
+-                      interrupts = <3 0>;
+-                      key_maxval = <2>;
+-                      linux,code = <0x0000009e        /* KEY_BACK */
+-                                    0x000000a9>;      /* KEY_MENU */
+-              };
+-      };
+-
+-      i2c_cm36651: i2c-gpio-2 {
+-              compatible = "i2c-gpio";
+-              gpios = <&gpf0 0 0>, <&gpf0 1 0>;
+-              i2c-gpio,delay-us = <2>;
+-              #address-cells = <1>;
+-              #size-cells = <0>;
+-              status = "okay";
+-
+-              cm36651@18 {
+-                      compatible = "cm36651";
+-                      reg = <0x18>;
+-                      interrupt-parent = <&gpx0>;
+-                      interrupts = <2 0>;
+-                      vled-supply = <&ps_als_reg>;
+-              };
+-      };
+-
+-      camera {
+-              status = "okay";
+-
+-              pinctrl-names = "default";
+-              pinctrl-0 = <&cam_port_a_clk_active &cam_port_b_clk_active>;
+-
+-              fimc_0: fimc@11800000 {
+-                      clock-frequency = <160000000>;
+-                      status = "okay";
+-              };
+-
+-              fimc_1: fimc@11810000 {
+-                      clock-frequency = <160000000>;
+-                      status = "okay";
+-              };
+-
+-              fimc_2: fimc@11820000 {
+-                      clock-frequency = <160000000>;
+-                      status = "okay";
+-              };
+-
+-              fimc_3: fimc@11830000 {
+-                      clock-frequency = <160000000>;
+-                      status = "okay";
+-              };
+-
+-              csis_0: csis@11880000 {
+-                      status = "okay";
+-                      vddcore-supply = <&ldo8_reg>;
+-                      vddio-supply = <&ldo10_reg>;
+-                      clock-frequency = <160000000>;
+-                      #address-cells = <1>;
+-                      #size-cells = <0>;
+-
+-                      /* Camera C (3) MIPI CSI-2 (CSIS0) */
+-                      port@3 {
+-                              reg = <3>;
+-                              csis0_ep: endpoint {
+-                                      remote-endpoint = <&s5c73m3_ep>;
+-                                      data-lanes = <1 2 3 4>;
+-                                      samsung,csis-hs-settle = <12>;
+-                                      samsung,csis-wclk;
+-                              };
+-                      };
+-              };
+-
+-              csis_1: csis@11890000 {
+-                      status = "okay";
+-                      vddcore-supply = <&ldo8_reg>;
+-                      vddio-supply = <&ldo10_reg>;
+-                      clock-frequency = <160000000>;
+-                      #address-cells = <1>;
+-                      #size-cells = <0>;
+-
+-                      /* Camera D (4) MIPI CSI-2 (CSIS1) */
+-                      port@4 {
+-                              reg = <4>;
+-                              csis1_ep: endpoint {
+-                                      remote-endpoint = <&is_s5k6a3_ep>;
+-                                      data-lanes = <1>;
+-                                      samsung,csis-hs-settle = <18>;
+-                                      samsung,csis-wclk;
+-                              };
+-                      };
+-              };
+-
+-              fimc-is@12000000 {
+-                      linux,contiguous-region = <&fimc_mem>;
+-                      status = "okay";
+-                      pinctrl-0 = <&fimc_is_uart>;
+-                      pinctrl-names = "default";
+-
+-                      fimc_lite_0: fimc-lite@12390000 {
+-                              status = "okay";
+-                      };
+-
+-                      fimc_lite_1: fimc-lite@123A0000 {
+-                              status = "okay";
+-                      };
+-
+-                      i2c1_isp: i2c-isp@12140000 {
+-                              pinctrl-0 = <&fimc_is_i2c1>;
+-                              pinctrl-names = "default";
+-
+-                              s5k6a3@10 {
+-                                      compatible = "samsung,s5k6a3";
+-                                      reg = <0x10>;
+-                                      svdda-supply = <&cam_io_reg>;
+-                                      svddio-supply = <&ldo19_reg>;
+-                                      gpios = <&gpm1 6 0>;
+-                                      pinctrl-names = "default";
+-                                      pinctrl-0 = <&vt_cam_id>;
+-                                      clocks = <&camera 1>; /* CAM_B_CLKOUT */
+-                                      clock-names = "extclk";
+-                                      clock-frequency = <24000000>;
+-                                      port {
+-                                              is_s5k6a3_ep: endpoint {
+-                                                      remote-endpoint = <&csis1_ep>;
+-                                                      data-lanes = <1>;
+-                                              };
+-                                      };
+-                              };
+-                      };
+-              };
+-      };
+-
+-      cpufreq {
+-              freq_table = <1400000 1300000 1200000 1100000 1000000
+-                           900000 800000 700000 600000 500000 400000 300000
+-                           200000>;
+-              boost_freq = <1500000>;
+-      };
+-
+-      thermistor-ap@0 {
+-              compatible = "ntc,ncp03wb473";
+-              status = "ok";
+-              pullup-uv = <1800000>;
+-              pullup-ohm = <100000>;
+-              pulldown-ohm = <100000> ;
+-              io-channels = <&adc 1>;
+-      };
+-
+-      thermistor-batt@0 {
+-              compatible = "ntc,ncp03wb473";
+-              status = "ok";
+-              pullup-uv = <1800000>;
+-              pullup-ohm = <100000>;
+-              pulldown-ohm = <100000> ;
+-              io-channels = <&adc 2>;
+-      };
+-
+-      rtc@10070000 {
+-              status = "okay";
+-      };
+-};
+diff --git a/arch/arm/boot/dts/exynos4412-redwood.dts b/arch/arm/boot/dts/exynos4412-redwood.dts
+deleted file mode 100644
+index 09cf22c..0000000
+--- a/arch/arm/boot/dts/exynos4412-redwood.dts
++++ /dev/null
+@@ -1,162 +0,0 @@
+-/*
+- * Samsung's Exynos4412 based  board device tree source
+- *
+- * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+- *            http://www.samsung.com
+- *
+- * Device tree source file for Samsung's Redwood board which is based on
+- * Samsung's Exynos4412 SoC.
+- *
+- * 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/ "exynos4412-slp_pq.dts"
+-
+-/ {
+-      model = "Samsung Redwood based on Exynos4412";
+-      compatible = "samsung,redwood", "samsung,exynos4412";
+-
+-      chosen {
+-              bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rootwait earlyprintk panic=5";
+-      };
+-
+-      sdhci_emmc: sdhci@12510000 {
+-              bus-width = <8>;
+-              non-removable;
+-              pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus8>;
+-              pinctrl-names = "default";
+-              vmmc-supply = <&vemmc_reg>;
+-              status = "okay";
+-      };
+-
+-      gpio-keys@0 {
+-              compatible = "gpio-keys";
+-
+-              key@114 {
+-                      interrupt-parent = <&gpx3>;
+-                      interrupts = <3 0>;
+-                      gpios = <&gpx3 3 1>;
+-                      linux,code = <114>;
+-                      label = "volume down";
+-                      debounce-interval = <10>;
+-              };
+-
+-              key@115 {
+-                      interrupt-parent = <&gpx2>;
+-                      interrupts = <2 0>;
+-                      gpios = <&gpx2 2 1>;
+-                      linux,code = <115>;
+-                      label = "volume up";
+-                      debounce-interval = <10>;
+-              };
+-
+-              key@116 {
+-                      interrupt-parent = <&gpx2>;
+-                      interrupts = <7 0>;
+-                      gpios = <&gpx2 7 1>;
+-                      linux,code = <116>;
+-                      label = "power";
+-                      debounce-interval = <10>;
+-                      gpio-key,wakeup;
+-              };
+-
+-              key@139 {
+-                      interrupt-parent = <&gpx0>;
+-                      interrupts = <1 0>;
+-                      gpios = <&gpx0 1 1>;
+-                      linux,code = <139>;
+-                      label = "menu";
+-                      debounce-interval = <10>;
+-                      gpio-key,wakeup;
+-              };
+-      };
+-
+-      lcd_vdd_reg: voltage-regulator@1 {
+-              compatible = "regulator-fixed";
+-              regulator-name = "LCD_VDD_5.0V";
+-              regulator-min-microvolt = <5000000>;
+-              regulator-max-microvolt = <5000000>;
+-              gpio = <&gpm0 0 0>;
+-              enable-active-high;
+-      };
+-
+-      fimd0_lcd: panel {
+-              compatible = "samsung,s6d6aa1";
+-              reset-gpio = <&gpf2 1 0>;
+-              reset-delay = <100>;
+-              power-on-delay= <50>;
+-              vdd-supply = <&lcd_vdd_reg>;
+-              vddi-supply = <&ldo5_reg>;
+-              video-source = <&dsi_0>;
+-              flip-horizontal;
+-              flip-vertical;
+-              samsung,panel-width-mm = <59>; /* FIXME */
+-              samsung,panel-height-mm = <105>; /* FIXME */
+-
+-              display-timings {
+-                      native-mode = <&timing0>;
+-
+-                      timing0: timing-0 {
+-                              clock-frequency = <0>;
+-                              hactive = <720>;
+-                              vactive = <1280>;
+-                              hfront-porch = <60>;
+-                              hback-porch = <60>;
+-                              hsync-len = <3>;
+-                              vfront-porch = <36>;
+-                              vback-porch = <2>;
+-                              vsync-len = <2>;
+-                      };
+-              };
+-      };
+-
+-      dsi_0: dsi@11C80000 {
+-              samsung,pll-stable-time = <500>;
+-              samsung,stop-holding-count = <0x7ff>;
+-              samsung,bta-timeout = <0xff>;
+-              samsung,rx-timeout = <0xffff>;
+-              samsung,pll-clk-freq = <24000000>;
+-              samsung,cmd-allow = <0xf>;
+-              vdd11-supply = <&ldo8_reg>;
+-              vdd18-supply = <&ldo10_reg>;
+-              status = "okay";
+-      };
+-
+-      fimd@11c00000 {
+-              samsung,fimd-display = <&fimd0_lcd>;
+-              samsung,fimd-vidout-rgb;
+-              samsung,fimd-inv-vclk;
+-              samsung,fimd-frame-rate = <60>;
+-              samsung,default-window = <3>;
+-              samsung,fimd-win-bpp = <32>;
+-              status = "okay";
+-      };
+-
+-      rotator: rotator@12810000 {
+-              status = "okay";
+-      };
+-
+-      cpufreq {
+-              freq_table;
+-              status = "okay";
+-      };
+-
+-      ehci@12580000 {
+-              status = "okay";
+-      };
+-
+-
+-};
+-
+-&pinctrl_1 {
+-      modem_state_active: modem-state-active {
+-              samsung,pins = "gpx1-6", "gpx1-1", "gpx1-2";
+-              samsung,pin-pud = <0>;
+-      };
+-      modem_state_off: modem-state-off {
+-              samsung,pins = "gpx1-6", "gpx1-1", "gpx1-2";
+-              samsung,pin-pud = <1>;
+-      };
+-};
+diff --git a/arch/arm/boot/dts/exynos4412-redwoodlte.dts b/arch/arm/boot/dts/exynos4412-redwoodlte.dts
+deleted file mode 100644
+index da1e7df..0000000
+--- a/arch/arm/boot/dts/exynos4412-redwoodlte.dts
++++ /dev/null
+@@ -1,756 +0,0 @@
+-/*
+- * Samsung's Exynos4412 based  board device tree source
+- *
+- * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+- *            http://www.samsung.com
+- *
+- * Device tree source file for Samsung's Redwood board which is based on
+- * Samsung's Exynos4412 SoC.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License version 2 as
+- * published by the Free Software Foundation.
+-*/
+-
+-/dts-v1/;
+-/include/ "exynos4412.dtsi"
+-
+-/ {
+-      model = "Samsung Redwood based on Exynos4412";
+-      compatible = "samsung,redwood", "samsung,exynos4412";
+-
+-      memory {
+-              reg =  <0x40000000 0x10000000
+-                      0x50000000 0x10000000
+-                      0x60000000 0x10000000
+-                      0x70000000 0x10000000>;
+-
+-              reserved-memory {
+-                      #address-cells = <1>;
+-                      #size-cells = <1>;
+-
+-                      contig_mem: region@71000000 {
+-                              compatible = "linux,contiguous-memory-region";
+-                              reg = <0x71000000 0x0c000000>;
+-                              linux,default-contiguous-region;
+-                      };
+-
+-                      fimc_mem: region@70000000 {
+-                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
+-                              reg = <0x70000000 0x1000000>;
+-                      };
+-
+-                      mfc_l_mem: mfc_l_region@43000000 {
+-                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
+-                              reg = <0x43000000 0x1000000>;
+-                      };
+-
+-                      mfc_r_mem: mfc_r_region@51000000 {
+-                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
+-                              reg = <0x51000000 0x1000000>;
+-                      };
+-              };
+-      };
+-
+-      chosen {
+-              bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rootwait earlyprintk panic=5";
+-      };
+-
+-      firmware@0204F000 {
+-              compatible = "samsung,secure-firmware";
+-              reg = <0x0204F000 0x1000>;
+-      };
+-
+-      fixed-rate-clocks {
+-              xxti {
+-                      compatible = "samsung,clock-xxti", "fixed-clock";
+-                      clock-frequency = <0>;
+-              };
+-
+-              xusbxti {
+-                      compatible = "samsung,clock-xusbxti", "fixed-clock";
+-                      clock-frequency = <24000000>;
+-              };
+-      };
+-
+-      vemmc_reg: voltage-regulator@0 {
+-              compatible = "regulator-fixed";
+-              regulator-name = "VMEM_VDD_2.8V";
+-              regulator-min-microvolt = <2800000>;
+-              regulator-max-microvolt = <2800000>;
+-              gpio = <&gpk0 2 0>;
+-              enable-active-high;
+-      };
+-
+-      sdhci_emmc: sdhci@12510000 {
+-              bus-width = <8>;
+-              non-removable;
+-              pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus8>;
+-              pinctrl-names = "default";
+-              vmmc-supply = <&vemmc_reg>;
+-              status = "okay";
+-      };
+-
+-      serial@13800000 {
+-              status = "okay";
+-      };
+-
+-      serial@13810000 {
+-              status = "okay";
+-      };
+-
+-      serial@13820000 {
+-              status = "okay";
+-      };
+-
+-      serial@13830000 {
+-              status = "okay";
+-      };
+-
+-      gpio-keys@0 {
+-              compatible = "gpio-keys";
+-
+-              key@114 {
+-                      interrupt-parent = <&gpj1>;
+-                      interrupts = <2 0>;
+-                      gpios = <&gpj1 2 1>;
+-                      linux,code = <114>;
+-                      label = "volume down";
+-                      debounce-interval = <10>;
+-              };
+-
+-              key@115 {
+-                      interrupt-parent = <&gpj1>;
+-                      interrupts = <1 0>;
+-                      gpios = <&gpj1 1 1>;
+-                      linux,code = <115>;
+-                      label = "volume up";
+-                      debounce-interval = <10>;
+-              };
+-
+-              key@116 {
+-                      interrupt-parent = <&gpx2>;
+-                      interrupts = <7 0>;
+-                      gpios = <&gpx2 7 1>;
+-                      linux,code = <116>;
+-                      label = "power";
+-                      debounce-interval = <10>;
+-                      gpio-key,wakeup;
+-              };
+-
+-              key@139 {
+-                      interrupt-parent = <&gpx0>;
+-                      interrupts = <1 0>;
+-                      gpios = <&gpx0 1 1>;
+-                      linux,code = <139>;
+-                      label = "menu";
+-                      debounce-interval = <10>;
+-                      gpio-key,wakeup;
+-              };
+-      };
+-
+-      i2c_0: i2c@13860000 {
+-              samsung,i2c-sda-delay = <100>;
+-              samsung,i2c-slave-addr = <0x10>;
+-              samsung,i2c-max-bus-freq = <400000>;
+-              pinctrl-0 = <&i2c0_bus>;
+-              pinctrl-names = "default";
+-              status = "okay";
+-
+-              s5c73m3@3c {
+-                      compatible = "samsung,s5c73m3";
+-                      reg = <0x3c>;
+-                      standby-gpios = <&gpm0 1 1>;    /* ISP_STANDBY */
+-                      xshutdown-gpios = <&gpf1 3 1>;  /* ISP_RESET */
+-                      vdd-int-supply = <&buck9_reg>;
+-                      vddio-cis-supply = <&ldo9_reg>;
+-                      vdda-supply = <&ldo17_reg>;
+-                      vddio-host-supply = <&ldo18_reg>;
+-                      vdd-af-supply = <&cam_af_reg>;
+-                      vdd-reg-supply = <&cam_io_reg>;
+-                      clock-frequency = <24000000>;
+-                      clocks = <&camera 0>;           /* CAM_A_CLKOUT */
+-                      clock-names = "cis_extclk";
+-                      port {
+-                              s5c73m3_ep: endpoint {
+-                                      remote-endpoint = <&csis0_ep>;
+-                                      data-lanes = <1 2 3 4>;
+-                              };
+-                      };
+-              };
+-      };
+-
+-      i2c@13870000 {
+-              samsung,i2c-sda-delay = <100>;
+-              samsung,i2c-slave-addr = <0x10>;
+-              samsung,i2c-max-bus-freq = <400000>;
+-              pinctrl-0 = <&i2c1_bus>;
+-              pinctrl-names = "default";
+-              status = "okay";
+-
+-              lsm330dlc_gyro@6b {
+-                      compatible = "st,lsm330dlc-gyro";
+-                      reg = <0x6b>;
+-                      irq-map-policy = <1>;
+-                      interrupt-controller;
+-                      #interrups-cells = <2>;
+-                      interrupt-parent = <&lsm330dlc_gyro_map>;
+-                      interrupts= <1 0>;
+-
+-                      lsm330dlc_gyro_map: lsm330dlc-gyro-map {
+-                              compatible = "samsung,lsm330dlc-gyro-map";
+-                              #interrupt-cells = <2>;
+-                              #address-cells = <0>;
+-                              #size-cells = <0>;
+-                              interrupt-map = <0x1 0 &gpf0 3 0>;
+-                      };
+-              };
+-
+-              lsm330dlc_accel@19 {
+-                      compatible = "st,lsm330dlc-accel";
+-                      reg = <0x19>;
+-                      irq-map-policy = <2>;
+-                      interrupt-controller;
+-                      #interrups-cells = <2>;
+-                      interrupt-parent = <&lsm330dlc_accel_map>;
+-                      interrupts= <1 0>;
+-
+-                      lsm330dlc_accel_map: lsm330dlc-accel-map {
+-                              compatible = "samsung,lsm330dlc-accel-map";
+-                              #interrupt-cells = <2>;
+-                              #address-cells = <0>;
+-                              #size-cells = <0>;
+-                              interrupt-map = <0x1 0 &gpx0 0 0>;
+-                      };
+-              };
+-      };
+-
+-      i2c@13890000 {
+-              samsung,i2c-sda-delay = <100>;
+-              samsung,i2c-slave-addr = <0x10>;
+-              samsung,i2c-max-bus-freq = <400000>;
+-              pinctrl-0 = <&i2c3_bus>;
+-              pinctrl-names = "default";
+-              status = "okay";
+-
+-              mms114-touchscreen@48 {
+-                      compatible = "melfas,mms114";
+-                      reg = <0x48>;
+-                      interrupt-parent = <&gpm2>;
+-                      interrupts = <3 2>;
+-                      x-size = <720>;
+-                      y-size = <1280>;
+-                      avdd-supply = <&ldo23_reg>;
+-                      vdd-supply = <&ldo24_reg>;
+-              };
+-      };
+-
+-      i2c@138D0000 {
+-              samsung,i2c-sda-delay = <100>;
+-              samsung,i2c-slave-addr = <0x10>;
+-              samsung,i2c-max-bus-freq = <100000>;
+-              pinctrl-0 = <&i2c7_bus>;
+-              pinctrl-names = "default";
+-              status = "okay";
+-
+-              max77686_pmic@09 {
+-                      compatible = "maxim,max77686";
+-                      interrupt-parent = <&gpx0>;
+-                      interrupts = <7 0>;
+-                      reg = <0x09>;
+-
+-                      voltage-regulators {
+-                              ldo1_reg: ldo@1 {
+-                                      regulator-compatible = "LDO1";
+-                                      regulator-name = "VALIVE_1.0V_AP";
+-                                      regulator-min-microvolt = <1000000>;
+-                                      regulator-max-microvolt = <1000000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo2_reg: ldo@2 {
+-                                      regulator-compatible = "LDO2";
+-                                      regulator-name = "VM1M2_1.2V_AP";
+-                                      regulator-min-microvolt = <1200000>;
+-                                      regulator-max-microvolt = <1200000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo3_reg: ldo@3 {
+-                                      regulator-compatible = "LDO3";
+-                                      regulator-name = "VCC_1.8V_AP";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo4_reg: ldo@4 {
+-                                      regulator-compatible = "LDO4";
+-                                      regulator-name = "VCC_2.8V_AP";
+-                                      regulator-min-microvolt = <2800000>;
+-                                      regulator-max-microvolt = <2800000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo5_reg: ldo@5 {
+-                                      regulator-compatible = "LDO5";
+-                                      regulator-name = "VCC_1.8V_IO";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo6_reg: ldo@6 {
+-                                      regulator-compatible = "LDO6";
+-                                      regulator-name = "VMPLL_1.0V_AP";
+-                                      regulator-min-microvolt = <1000000>;
+-                                      regulator-max-microvolt = <1000000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo7_reg: ldo@7 {
+-                                      regulator-compatible = "LDO7";
+-                                      regulator-name = "VPLL_1.0V_AP";
+-                                      regulator-min-microvolt = <1000000>;
+-                                      regulator-max-microvolt = <1000000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo8_reg: ldo@8 {
+-                                      regulator-compatible = "LDO8";
+-                                      regulator-name = "VMIPI_1.0V";
+-                                      regulator-min-microvolt = <1000000>;
+-                                      regulator-max-microvolt = <1000000>;
+-                              };
+-
+-                              ldo9_reg: ldo@9 {
+-                                      regulator-compatible = "LDO9";
+-                                      regulator-name = "CAM_ISP_MIPI_1.2V";
+-                                      regulator-min-microvolt = <1200000>;
+-                                      regulator-max-microvolt = <1200000>;
+-                              };
+-
+-                              ldo10_reg: ldo@10 {
+-                                      regulator-compatible = "LDO10";
+-                                      regulator-name = "VMIPI_1.8V";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                              };
+-
+-                              ldo11_reg: ldo@11 {
+-                                      regulator-compatible = "LDO11";
+-                                      regulator-name = "VABB1_1.8V";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo12_reg: ldo@12 {
+-                                      regulator-compatible = "LDO12";
+-                                      regulator-name = "VUOTG_3.0V";
+-                                      regulator-min-microvolt = <3000000>;
+-                                      regulator-max-microvolt = <3000000>;
+-                              };
+-
+-                              ldo13_reg: ldo@13 {
+-                                      regulator-compatible = "LDO13";
+-                                      regulator-name = "NFC_AVDD_1.8V";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                              };
+-
+-                              ldo14_reg: ldo@14 {
+-                                      regulator-compatible = "LDO14";
+-                                      regulator-name = "VABB2_1.8V";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo15_reg: ldo@15 {
+-                                      regulator-compatible = "LDO15";
+-                                      regulator-name = "VHSIC_1.0V";
+-                                      regulator-min-microvolt = <1000000>;
+-                                      regulator-max-microvolt = <1000000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo16_reg: ldo@16 {
+-                                      regulator-compatible = "LDO16";
+-                                      regulator-name = "VHSIC_1.8V";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo17_reg: ldo@17 {
+-                                      regulator-compatible = "LDO17";
+-                                      regulator-name = "CAM_SENSOR_CORE_1.2V";
+-                                      regulator-min-microvolt = <1200000>;
+-                                      regulator-max-microvolt = <1200000>;
+-                              };
+-
+-                              ldo18_reg: ldo@18 {
+-                                      regulator-compatible = "LDO18";
+-                                      regulator-name = "CAM_ISP_SENSOR_1.8V";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                              };
+-
+-                              ldo19_reg: ldo@19 {
+-                                      regulator-compatible = "LDO19";
+-                                      regulator-name = "VT_CAM_1.8V";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                              };
+-
+-                              ldo20_reg: ldo@20 {
+-                                      regulator-compatible = "LDO20";
+-                                      regulator-name = "VDDQ_PRE_1.8V";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                              };
+-
+-                              ldo21_reg: ldo@21 {
+-                                      regulator-compatible = "LDO21";
+-                                      regulator-name = "VTF_2.8V";
+-                                      regulator-min-microvolt = <2800000>;
+-                                      regulator-max-microvolt = <2800000>;
+-                              };
+-
+-                              ldo22_reg: ldo@22 {
+-                                      regulator-compatible = "LDO22";
+-                                      regulator-name = "VMEM_VDD_2.8V";
+-                                      regulator-min-microvolt = <2800000>;
+-                                      regulator-max-microvolt = <2800000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              ldo23_reg: ldo@23 {
+-                                      regulator-compatible = "LDO23";
+-                                      regulator-name = "TSP_AVDD_3.3V";
+-                                      regulator-min-microvolt = <3300000>;
+-                                      regulator-max-microvolt = <3300000>;
+-                              };
+-
+-                              ldo24_reg: ldo@24 {
+-                                      regulator-compatible = "LDO24";
+-                                      regulator-name = "VDD_1.8V_TSP";
+-                                      regulator-min-microvolt = <1800000>;
+-                                      regulator-max-microvolt = <1800000>;
+-                              };
+-
+-                              ldo25_reg: ldo@25 {
+-                                      regulator-compatible = "LDO25";
+-                                      regulator-name = "LED_A_2.8V";
+-                                      regulator-min-microvolt = <2800000>;
+-                                      regulator-max-microvolt = <2800000>;
+-                              };
+-
+-                              ldo26_reg: ldo@26 {
+-                                      regulator-compatible = "LDO26";
+-                                      regulator-name = "MOTOR_VCC_3.0V";
+-                                      regulator-min-microvolt = <3000000>;
+-                                      regulator-max-microvolt = <3000000>;
+-                              };
+-
+-                              buck1_reg: buck@1 {
+-                                      regulator-compatible = "BUCK1";
+-                                      regulator-name = "vdd_mif";
+-                                      regulator-min-microvolt = <850000>;
+-                                      regulator-max-microvolt = <1100000>;
+-                                      regulator-always-on;
+-                                      regulator-boot-on;
+-                              };
+-
+-                              buck2_reg: buck@2 {
+-                                      regulator-compatible = "BUCK2";
+-                                      regulator-name = "vdd_arm";
+-                                      regulator-min-microvolt = <850000>;
+-                                      regulator-max-microvolt = <1500000>;
+-                                      regulator-always-on;
+-                                      regulator-boot-on;
+-                              };
+-
+-                              buck3_reg: buck@3 {
+-                                      regulator-compatible = "BUCK3";
+-                                      regulator-name = "vdd_int";
+-                                      regulator-min-microvolt = <850000>;
+-                                      regulator-max-microvolt = <1150000>;
+-                                      regulator-always-on;
+-                                      regulator-boot-on;
+-                              };
+-
+-                              buck4_reg: buck@4 {
+-                                      regulator-compatible = "BUCK4";
+-                                      regulator-name = "vdd_g3d";
+-                                      regulator-min-microvolt = <850000>;
+-                                      regulator-max-microvolt = <1150000>;
+-                                      regulator-boot-on;
+-                              };
+-
+-                              buck5_reg: buck@5 {
+-                                      regulator-compatible = "BUCK5";
+-                                      regulator-name = "VMEM_1.2V_AP";
+-                                      regulator-min-microvolt = <1200000>;
+-                                      regulator-max-microvolt = <1200000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              buck6_reg: buck@6 {
+-                                      regulator-compatible = "BUCK6";
+-                                      regulator-name = "VCC_SUB_1.35V";
+-                                      regulator-min-microvolt = <1350000>;
+-                                      regulator-max-microvolt = <1350000>;
+-                                      regulator-always-on;
+-                              };
+-                              buck7_reg: buck@7 {
+-                                      regulator-compatible = "BUCK7";
+-                                      regulator-name = "VCC_SUB_2.0V";
+-                                      regulator-min-microvolt = <2000000>;
+-                                      regulator-max-microvolt = <2000000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              buck8_reg: buck@8 {
+-                                      regulator-compatible = "BUCK8";
+-                                      regulator-name = "VMEM_VDDF_3.0V";
+-                                      regulator-min-microvolt = <2850000>;
+-                                      regulator-max-microvolt = <2850000>;
+-                                      regulator-always-on;
+-                              };
+-
+-                              buck9_reg: buck@9 {
+-                                      regulator-compatible = "BUCK9";
+-                                      regulator-name = "CAM_ISP_CORE_1.2V";
+-                                      regulator-min-microvolt = <1000000>;
+-                                      regulator-max-microvolt = <1200000>;
+-                              };
+-                      };
+-              };
+-      };
+-
+-      i2c_if_pmic: i2c@0 {
+-              compatible = "i2c-gpio";
+-              gpios = <&gpm2 0 0
+-                       &gpm2 1 0
+-                      >;
+-              #address-cells = <1>;
+-              #size-cells = <0>;
+-      };
+-
+-      lcd_vdd_reg: voltage-regulator@1 {
+-              compatible = "regulator-fixed";
+-              regulator-name = "LCD_VDD_5.0V";
+-              regulator-min-microvolt = <5000000>;
+-              regulator-max-microvolt = <5000000>;
+-              gpio = <&gpm0 0 0>;
+-              enable-active-high;
+-      };
+-
+-      cam_af_reg: voltage-regulator@2 {
+-              compatible = "regulator-fixed";
+-              regulator-name = "CAM_AF";
+-              regulator-min-microvolt = <2800000>;
+-              regulator-max-microvolt = <2800000>;
+-              gpio = <&gpm0 4 0>;
+-              enable-active-high;
+-      };
+-
+-      cam_io_reg: voltage-regulator@3 {
+-              compatible = "regulator-fixed";
+-              regulator-name = "CAM_SENSOR_A";
+-              regulator-min-microvolt = <2800000>;
+-              regulator-max-microvolt = <2800000>;
+-              gpio = <&gpm0 2 0>;
+-              enable-active-high;
+-      };
+-
+-      cam_isp_core_reg: voltage-regulator@4 {
+-              compatible = "regulator-fixed";
+-              regulator-name = "CAM_ISP_CORE_1.2V_EN";
+-              regulator-min-microvolt = <1200000>;
+-              regulator-max-microvolt = <1200000>;
+-              gpio = <&gpm0 3 0>;
+-              enable-active-high;
+-              regulator-always-on;
+-      };
+-
+-      fimd0_lcd: panel {
+-              compatible = "samsung,l5f31188";
+-              width = <720>;
+-              height = <1280>;
+-              reset-gpio = <&gpf2 1 0>;
+-              reset-delay1 = <15>;
+-              reset-delay2 = <180>;
+-              power-on-delay = <120>;
+-              power-off-delay1 = <100>;
+-              power-off-delay2 = <200>;
+-              vdd-supply = <&ldo25_reg>;
+-              vddi-supply = <&ldo5_reg>;
+-              video-source = <&dsi_0>;
+-              samsung,panel-width-mm = <59>; /* FIXME */
+-              samsung,panel-height-mm = <105>; /* FIXME */
+-
+-              display-timings {
+-                      native-mode = <&timing0>;
+-
+-                      timing0: timing-0 {
+-                              clock-frequency = <0>;
+-                              hactive = <720>;
+-                              vactive = <1280>;
+-                              hfront-porch = <81>;
+-                              hback-porch = <81>;
+-                              hsync-len = <27>;
+-                              vfront-porch = <11>;
+-                              vback-porch = <4>;
+-                              vsync-len = <2>;
+-                      };
+-              };
+-      };
+-
+-      dsi_0: dsi@11C80000 {
+-              samsung,pll-stable-time = <500>;
+-              samsung,stop-holding-count = <0x7ff>;
+-              samsung,bta-timeout = <0xff>;
+-              samsung,rx-timeout = <0xffff>;
+-              samsung,pll-clk-freq = <24000000>;
+-              samsung,cmd-allow = <0xf>;
+-              vdd11-supply = <&ldo8_reg>;
+-              vdd18-supply = <&ldo10_reg>;
+-              status = "okay";
+-      };
+-
+-      fimd@11c00000 {
+-              samsung,fimd-display = <&fimd0_lcd>;
+-              samsung,fimd-vidout-rgb;
+-              samsung,fimd-inv-vclk;
+-              samsung,fimd-frame-rate = <60>;
+-              samsung,default-window = <3>;
+-              samsung,fimd-win-bpp = <32>;
+-              status = "okay";
+-      };
+-
+-      vidi {
+-              compatible = "samsung,exynos-drm-vidi";
+-      };
+-
+-      sysmmu-fimd0 {
+-              clock-names = "sysmmu";
+-              clocks = <&clock 287>;
+-              mmu-master = <&fimd>;
+-      };
+-
+-      sysmmu-g2d {
+-              clock-names = "sysmmu";
+-              clocks = <&clock 280>;
+-              mmu-master = <&g2d>;
+-      };
+-
+-      exynos-usbphy@125B0000 {
+-              status = "okay";
+-      };
+-
+-      hsotg@12480000 {
+-              status = "okay";
+-              vusb_d-supply = <&ldo15_reg>;
+-              vusb_a-supply = <&ldo12_reg>;
+-      };
+-
+-      spi_1: spi@13930000 {
+-              pinctrl-names = "default";
+-              pinctrl-0 = <&spi1_bus>;
+-              status = "okay";
+-
+-              s5c73m3_spi: s5c73m3 {
+-                      compatible = "samsung,s5c73m3";
+-                      spi-max-frequency = <50000000>;
+-                      reg = <0>;
+-                      controller-data {
+-                              cs-gpio = <&gpb 5 0>;
+-                              samsung,spi-feedback-delay = <2>;
+-                      };
+-              };
+-      };
+-
+-      g2d@10800000 {
+-              status = "okay";
+-      };
+-
+-      rotator: rotator@12810000 {
+-              status = "okay";
+-      };
+-
+-      camera {
+-              status = "okay";
+-
+-              pinctrl-names = "default";
+-              pinctrl-0 = <&cam_port_a_clk_active>;
+-
+-              fimc_0: fimc@11800000 {
+-                      clock-frequency = <176000000>;
+-                      status = "okay";
+-              };
+-
+-              fimc_1: fimc@11810000 {
+-                      clock-frequency = <176000000>;
+-                      status = "okay";
+-              };
+-
+-              fimc_2: fimc@11820000 {
+-                      clock-frequency = <176000000>;
+-                      status = "okay";
+-              };
+-
+-              fimc_3: fimc@11830000 {
+-                      clock-frequency = <176000000>;
+-                      status = "okay";
+-              };
+-
+-              csis_0: csis@11880000 {
+-                      status = "okay";
+-                      vddcore-supply = <&ldo8_reg>;
+-                      vddio-supply = <&ldo10_reg>;
+-                      clock-frequency = <160000000>;
+-                      #address-cells = <1>;
+-                      #size-cells = <0>;
+-
+-                      /* Camera C (3) MIPI CSI-2 (CSIS0) */
+-                      port@3 {
+-                              reg = <3>;
+-                              csis0_ep: endpoint {
+-                                      remote-endpoint = <&s5c73m3_ep>;
+-                                      data-lanes = <1 2 3 4>;
+-                                      samsung,csis-hs-settle = <12>;
+-                              };
+-                      };
+-              };
+-      };
+-
+-      mfc: codec@13400000 {
+-              status = "okay";
+-
+-              memport@0 {
+-                      memory-region = <&mfc_l_mem>;
+-              };
+-
+-              memport@1 {
+-                      memory-region = <&mfc_r_mem>;
+-              };
+-      };
+-
+-      gpu@13000000 {
+-              status = "okay";
+-              vdd_g3d-supply = <&buck4_reg>;
+-      };
+-
+-      cpufreq {
+-              status = "okay";
+-              overclocking = "okay";
+-              max_overclocking_freq = <1500000>;
+-      };
+-
+-      ehci@12580000 {
+-              status = "okay";
+-      };
+-};
+diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts
+new file mode 100644
+index 0000000..208e15f
+--- /dev/null
++++ b/arch/arm/boot/dts/exynos4412-trats2.dts
+@@ -0,0 +1,1601 @@
++/*
++ * Samsung's Exynos4412 based Trats2 board device tree source
++ *
++ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
++ *            http://www.samsung.com
++ *
++ * Device tree source file for Samsung's Trats2 board which is based on
++ * Samsung's Exynos4412 SoC.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++*/
++
++/dts-v1/;
++/include/ "exynos4412.dtsi"
++
++&pinctrl_0 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&pdn_group_low_0>,
++                      <&pdn_group_high_0>,
++                      <&pdn_group_in_nopull_0>,
++                      <&pdn_group_in_down_0>,
++                      <&pdn_group_in_up_0>,
++                      <&pdn_group_prev_0>;
++
++      pdn_group_low_0: pdn-group-low {
++              samsung,pins = "gpa0-1";
++              samsung,pin-con-pdn = <0>;
++              samsung,pin-pud-pdn = <0>;
++      };
++
++      pdn_group_high_0: pdn-group-high {
++              samsung,pins = "gpf3-4";
++              samsung,pin-con-pdn = <1>;
++              samsung,pin-pud-pdn = <0>;
++      };
++
++      pdn_group_in_nopull_0: pdn-group-in-nopull {
++              samsung,pins = "gpa0-0", "gpa0-2", "gpa0-4", "gpb-0",
++                              "gpb-1", "gpb-2", "gpb-3", "gpc1-0",
++                              "gpc1-2", "gpc1-3", "gpc1-4", "gpd0-2",
++                              "gpd0-3", "gpd1-2", "gpd1-3", "gpf0-0",
++                              "gpf0-1", "gpf0-4", "gpf0-6", "gpf1-4",
++                              "gpf1-5", "gpf2-6", "gpf2-7", "gpf3-0";
++              samsung,pin-con-pdn = <2>;
++              samsung,pin-pud-pdn = <0>;
++      };
++
++      pdn_group_in_down_0: pdn-group-in-down {
++              samsung,pins = "gpa0-5", "gpa0-6", "gpa1-0", "gpa1-1",
++                              "gpa1-2", "gpa1-3", "gpa1-4", "gpa1-5",
++                              "gpb-4", "gpb-6", "gpb-7", "gpc0-0",
++                              "gpc0-1", "gpc0-2", "gpc0-3", "gpc0-4",
++                              "gpd0-0", "gpd0-1", "gpd1-0", "gpd1-1",
++                              "gpf0-2", "gpf0-3", "gpf0-5", "gpf0-7",
++                              "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3",
++                              "gpf1-6", "gpf2-1", "gpf2-2", "gpf2-3",
++                              "gpf2-4", "gpf2-5", "gpf3-5", "gpj0-3",
++                              "gpj0-6", "gpj0-7", "gpj1-0", "gpj1-3",
++                              "gpj1-4";
++              samsung,pin-con-pdn = <2>;
++              samsung,pin-pud-pdn = <1>;
++      };
++
++      pdn_group_in_up_0: pdn-group-in-up {
++              samsung,pins = "gpa0-3", "gpa0-7", "gpb-5";
++              samsung,pin-con-pdn = <2>;
++              samsung,pin-pud-pdn = <2>;
++      };
++
++      pdn_group_prev_0: pdn-group-prev {
++              samsung,pins = "gpc1-1", "gpf1-7", "gpf2-0", "gpf3-1",
++                              "gpf3-2", "gpf3-3", "gpj0-0", "gpj0-1",
++                              "gpj0-2", "gpj0-4", "gpj0-5", "gpj1-1",
++                              "gpj1-2";
++              samsung,pin-con-pdn = <3>;
++              samsung,pin-pud-pdn = <0>;
++      };
++};
++
++&pinctrl_1 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&pdn_group_low_1>,
++                      <&pdn_group_high_1>,
++                      <&pdn_group_in_nopull_1>,
++                      <&pdn_group_in_down_1>,
++                      <&pdn_group_prev_1>;
++
++      pdn_group_low_1: pdn-group-low {
++              samsung,pins = "gpk3-0", "gpk0-2";
++              samsung,pin-con-pdn = <0>;
++              samsung,pin-pud-pdn = <0>;
++      };
++
++      pdn_group_high_1: pdn-group-high {
++              samsung,pins = "gpm3-3";
++              samsung,pin-con-pdn = <1>;
++              samsung,pin-pud-pdn = <0>;
++      };
++
++      pdn_group_in_nopull_1: pdn-group-in-nopull {
++              samsung,pins = "gpk3-1", "gpk3-3", "gpk3-4", "gpk3-5",
++                              "gpk3-6", "gpy2-2", "gpy2-3", "gpy2-4",
++                              "gpy2-5", "gpm1-2", "gpm1-3", "gpm1-4",
++                              "gpm1-5", "gpm2-0", "gpm2-1";
++              samsung,pin-con-pdn = <2>;
++              samsung,pin-pud-pdn = <0>;
++      };
++
++      pdn_group_in_down_1: pdn-group-in-down {
++              samsung,pins = "gpk1-0", "gpk1-1", "gpk1-2", "gpk2-0",
++                              "gpk2-1", "gpk2-2", "gpk2-3", "gpk2-4",
++                              "gpk2-5", "gpk2-6", "gpk3-2", "gpl0-0",
++                              "gpl0-1", "gpl0-2", "gpl0-3", "gpl1-0",
++                              "gpl1-1", "gpl2-0", "gpl2-1", "gpl2-2",
++                              "gpl2-3", "gpl2-4", "gpl2-5", "gpl2-7",
++                              "gpm0-0", "gpm0-1", "gpm0-2", "gpm0-3",
++                              "gpm0-4", "gpm0-5", "gpm0-6", "gpm0-7",
++                              "gpm1-0", "gpm1-1", "gpm1-6", "gpm2-2",
++                              "gpm2-3", "gpm2-4", "gpm3-4", "gpm3-5",
++                              "gpm3-6", "gpm3-7", "gpm4-0", "gpm4-1",
++                              "gpm4-2", "gpm4-3", "gpm4-4", "gpm4-5",
++                              "gpm4-6", "gpm4-7", "gpy0-0", "gpy0-1",
++                              "gpy0-2", "gpy0-3", "gpy0-4", "gpy0-5",
++                              "gpy1-0", "gpy1-1", "gpy1-2", "gpy1-3",
++                              "gpy2-1", "gpy3-0", "gpy3-1", "gpy3-2",
++                              "gpy3-3", "gpy3-4", "gpy3-5", "gpy3-6",
++                              "gpy3-7", "gpy4-0", "gpy4-1", "gpy4-2",
++                              "gpy4-3", "gpy4-4", "gpy4-5", "gpy4-6",
++                              "gpy4-7", "gpy5-0", "gpy5-1", "gpy5-2",
++                              "gpy5-3", "gpy5-4", "gpy5-5", "gpy5-6",
++                              "gpy5-7", "gpy6-0", "gpy6-1", "gpy6-2",
++                              "gpy6-3", "gpy6-4", "gpy6-5", "gpy6-6",
++                              "gpy6-7";
++              samsung,pin-con-pdn = <2>;
++              samsung,pin-pud-pdn = <1>;
++      };
++
++      pdn_group_prev_1: pdn-group-prev {
++              samsung,pins = "gpk0-0", "gpk0-1", "gpk0-3", "gpk0-4",
++                              "gpk0-5", "gpk0-6", "gpk1-3", "gpk1-4",
++                              "gpk1-5", "gpk1-6", "gpl0-4", "gpl0-6",
++                              "gpl2-6", "gpy2-0", "gpm3-0", "gpm3-1",
++                              "gpm3-2";
++              samsung,pin-con-pdn = <3>;
++              samsung,pin-pud-pdn = <0>;
++      };
++};
++
++&pinctrl_2 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&pdn_group_in_down_2>;
++
++      pdn_group_in_down_2: pdn-group-in-down {
++              samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
++                              "gpz-4", "gpz-5", "gpz-6";
++              samsung,pin-con-pdn = <2>;
++              samsung,pin-pud-pdn = <1>;
++      };
++};
++
++&pinctrl_3 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&pdn_group_in_down_3>;
++
++      pdn_group_in_down_3: pdn-group-in-down {
++              samsung,pins = "gpv0-0", "gpv0-1", "gpv0-2", "gpv0-3",
++                              "gpv0-4", "gpv0-5", "gpv0-6", "gpv0-7",
++                              "gpv1-0", "gpv1-1", "gpv1-2", "gpv1-3",
++                              "gpv1-4", "gpv1-5", "gpv1-6", "gpv1-7",
++                              "gpv2-0", "gpv2-1", "gpv2-2", "gpv2-3",
++                              "gpv2-4", "gpv2-5", "gpv2-6", "gpv2-7",
++                              "gpv3-0", "gpv3-1", "gpv3-2", "gpv3-3",
++                              "gpv3-4", "gpv3-5", "gpv3-6", "gpv3-7",
++                              "gpv4-0";
++              samsung,pin-con-pdn = <2>;
++              samsung,pin-pud-pdn = <1>;
++      };
++};
++
++/ {
++      model = "Samsung TRATS2 based on Exynos4412";
++      compatible = "samsung,trats2", "samsung,exynos4412";
++
++      aliases {
++              i2c8 = &i2c_ak8975;
++              i2c9 = &i2c_lps331ap;
++              i2c10 = &i2c_if_pmic;
++              i2c11 = &i2c_fuel;
++              i2c12 = &i2c_gp2ap020a00f;
++              /* 15...16 reserved for i2c0_isp, i2c1_isp */
++              i2c16 = &i2c1_isp;
++              i2c20 = &i2c_touch_key;
++              i2c21 = &i2c_cm36651;
++      };
++
++      pinctrl@11400000 {
++              vt_cam_id: vt-cam-id {
++                      samsung,pins = "gpf1-2";
++                      samsung,pin-function = <2>;
++                      samsung,pin-pud = <1>;
++                      samsung,pin-drv = <3>;
++              };
++      };
++
++      gpio-keys@0 {
++              compatible = "gpio-keys";
++
++              key@114 {
++                      interrupt-parent = <&gpx3>;
++                      interrupts = <3 0>;
++                      gpios = <&gpx3 3 1>;
++                      linux,code = <114>;
++                      label = "volume down";
++                      debounce-interval = <10>;
++              };
++
++              key@115 {
++                      interrupt-parent = <&gpx2>;
++                      interrupts = <2 0>;
++                      gpios = <&gpx2 2 1>;
++                      linux,code = <115>;
++                      label = "volume up";
++                      debounce-interval = <10>;
++              };
++
++              key@116 {
++                      interrupt-parent = <&gpx2>;
++                      interrupts = <7 0>;
++                      gpios = <&gpx2 7 1>;
++                      linux,code = <116>;
++                      label = "power";
++                      debounce-interval = <10>;
++                      gpio-key,wakeup;
++              };
++
++              key@139 {
++                      interrupt-parent = <&gpx0>;
++                      interrupts = <1 0>;
++                      gpios = <&gpx0 1 1>;
++                      linux,code = <139>;
++                      label = "ok";
++                      debounce-interval = <10>;
++                      gpio-key,wakeup;
++              };
++      };
++
++      i2c_touch_key: i2c-gpio-3 {
++              compatible = "i2c-gpio";
++              gpios = <&gpl0 2 0>, <&gpl0 1 0>;
++              i2c-gpio,delay-us = <2>;
++              #address-cells = <1>;
++              #size-cells = <0>;
++              status = "okay";
++
++              touch_key@20 {
++                      compatible = "mcs5080_touchkey";
++                      reg = <0x20>;
++                      interrupt-parent = <&gpj0>;
++                      interrupts = <3 0>;
++                      key_maxval = <2>;
++                      linux,code = <0x0000009e        /* KEY_BACK */
++                                    0x000000a9>;      /* KEY_MENU */
++              };
++      };
++
++      i2c_cm36651: i2c-gpio-2 {
++              compatible = "i2c-gpio";
++              gpios = <&gpf0 0 0>, <&gpf0 1 0>;
++              i2c-gpio,delay-us = <2>;
++              #address-cells = <1>;
++              #size-cells = <0>;
++              status = "okay";
++
++              cm36651@18 {
++                      compatible = "cm36651";
++                      reg = <0x18>;
++                      interrupt-parent = <&gpx0>;
++                      interrupts = <2 0>;
++                      vled-supply = <&ps_als_reg>;
++              };
++      };
++
++      cpufreq {
++              freq_table = <1400000 1300000 1200000 1100000 1000000
++                           900000 800000 700000 600000 500000 400000 300000
++                           200000>;
++      };
++
++      thermistor-ap@0 {
++              compatible = "ntc,ncp03wb473";
++              status = "ok";
++              pullup-uv = <1800000>;
++              pullup-ohm = <100000>;
++              pulldown-ohm = <100000> ;
++              io-channels = <&adc 1>;
++      };
++
++      thermistor-batt@0 {
++              compatible = "ntc,ncp03wb473";
++              status = "ok";
++              pullup-uv = <1800000>;
++              pullup-ohm = <100000>;
++              pulldown-ohm = <100000> ;
++              io-channels = <&adc 2>;
++      };
++
++      rtc@10070000 {
++              status = "okay";
++      };
++
++      memory {
++              reg =  <0x40000000 0x10000000
++                      0x50000000 0x10000000
++                      0x60000000 0x10000000
++                      0x70000000 0x10000000>;
++
++              reserved-memory {
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      contig_mem: region@71000000 {
++                              compatible = "linux,contiguous-memory-region";
++                              reg = <0x71000000 0x0c000000>;
++                              linux,default-contiguous-region;
++                      };
++
++                      fimc_mem: region@70000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x70000000 0x1000000>;
++                      };
++
++                      mfc_l_mem: mfc_l_region@43000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x43000000 0x1000000>;
++                              status = "disabled";
++                      };
++
++                      mfc_r_mem: mfc_r_region@51000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x51000000 0x1000000>;
++                              status = "disabled";
++                      };
++              };
++      };
++
++      chosen {
++              bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rootwait earlyprintk panic=5";
++      };
++
++      firmware@0204F000 {
++              compatible = "samsung,secure-firmware";
++              reg = <0x0204F000 0x1000>;
++      };
++
++      fixed-rate-clocks {
++              xxti {
++                      compatible = "samsung,clock-xxti", "fixed-clock";
++                      clock-frequency = <0>;
++              };
++
++              xusbxti {
++                      compatible = "samsung,clock-xusbxti", "fixed-clock";
++                      clock-frequency = <24000000>;
++              };
++      };
++
++      vemmc_reg: voltage-regulator@0 {
++              compatible = "regulator-fixed";
++              regulator-name = "MASSMEMORY_EN";
++              regulator-min-microvolt = <2800000>;
++              regulator-max-microvolt = <2800000>;
++              gpio = <&gpk0 2 0>;
++              enable-active-high;
++      };
++
++      mshc@12550000 {
++              num-slots = <1>;
++              supports-highspeed;
++              broken-cd;
++              non-removable;
++              fifo-depth = <0x80>;
++              desc-num = <4>;
++              card-detect-delay = <200>;
++              vmmc-supply = <&vemmc_reg>;
++              clock-frequency = <400000000>;
++              samsung,dw-mshc-ciu-div = <0>;
++              samsung,dw-mshc-sdr-timing = <2 3>;
++              samsung,dw-mshc-ddr-timing = <1 2>;
++              pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              slot@0 {
++                      reg = <0>;
++                      bus-width = <8>;
++              };
++      };
++
++      sdhci_sd: sdhci@12530000 {
++              bus-width = <4>;
++              cd-gpios = <&gpx3 4 0>;
++              cd-inverted;
++              interrupts = <0 75 0>;
++              pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4>;
++              pinctrl-names = "default";
++              vmmc-supply = <&ldo21_reg>;
++              status = "okay";
++      };
++
++      serial@13800000 {
++              status = "okay";
++      };
++
++      serial@13810000 {
++              status = "okay";
++      };
++
++      serial@13820000 {
++              status = "okay";
++      };
++
++      serial@13830000 {
++              status = "okay";
++      };
++
++      gpio-keys@0 {
++              compatible = "gpio-keys";
++
++              key@114 {
++                      interrupt-parent = <&gpj1>;
++                      interrupts = <2 0>;
++                      gpios = <&gpj1 2 1>;
++                      linux,code = <114>;
++                      label = "volume down";
++                      debounce-interval = <10>;
++              };
++
++              key@115 {
++                      interrupt-parent = <&gpj1>;
++                      interrupts = <1 0>;
++                      gpios = <&gpj1 1 1>;
++                      linux,code = <115>;
++                      label = "volume up";
++                      debounce-interval = <10>;
++              };
++
++              key@116 {
++                      interrupt-parent = <&gpx2>;
++                      interrupts = <7 0>;
++                      gpios = <&gpx2 7 1>;
++                      linux,code = <116>;
++                      label = "power";
++                      debounce-interval = <10>;
++                      gpio-key,wakeup;
++              };
++      };
++
++      i2c_ak8975: i2c-gpio-0 {
++              compatible = "i2c-gpio";
++              gpios = <&gpy2 4 0>, <&gpy2 5 0>;
++              i2c-gpio,delay-us = <2>;
++              #address-cells = <1>;
++              #size-cells = <0>;
++              status = "okay";
++
++              ak8975@0C {
++                      compatible = "ak8975";
++                      reg = <0x0C>;
++                      gpios = <&gpj0 7 0>;
++                      position = <2>;
++              };
++      };
++
++      i2c_lps331ap: i2c-gpio-1 {
++              compatible = "i2c-gpio";
++              gpios = <&gpy2 2 0>, <&gpy2 3 0>;
++              i2c-gpio,delay-us = <2>;
++              #address-cells = <1>;
++              #size-cells = <0>;
++              status = "okay";
++
++              lps331ap@5d {
++                      compatible = "lps331ap";
++                      reg = <0x5d>;
++                      gpios = <&gpf0 5 0>; /* Used only by legacy driver */
++                      interrupt-parent = <&irq_map>;
++                      interrupts = <0>, <1>;
++
++                      irq_map: irq-map {
++                              #interrupt-cells = <1>;
++                              #address-cells = <0>;
++                              #size-cells = <0>;
++                              interrupt-map = <1 &gpf0 5 0>;
++                      };
++              };
++      };
++
++      i2c_gp2ap020a00f: i2c-gpio-2 {
++              compatible = "i2c-gpio";
++              gpios = <&gpk1 1 0>, <&gpk2 2 0>;
++              i2c-gpio,delay-us = <2>;
++              #address-cells = <1>;
++              #size-cells = <0>;
++              status = "okay";
++
++              gp2ap002a00f@39 {
++                      compatible = "gp2ap002a00f";
++                      reg = <0x39>;
++                      interrupt-parent = <&gpx0>;
++                      interrupts = <2 0>;
++                      vled-supply = <&ps_als_reg>;
++              };
++      };
++
++      i2c_0: i2c@13860000 {
++              samsung,i2c-sda-delay = <100>;
++              samsung,i2c-slave-addr = <0x10>;
++              samsung,i2c-max-bus-freq = <400000>;
++              pinctrl-0 = <&i2c0_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              s5c73m3@3c {
++                      compatible = "samsung,s5c73m3";
++                      reg = <0x3c>;
++                      standby-gpios = <&gpm0 1 1>;    /* ISP_STANDBY */
++                      xshutdown-gpios = <&gpf1 3 1>;  /* ISP_RESET */
++                      vdd-int-supply = <&buck9_reg>;
++                      vddio-cis-supply = <&ldo9_reg>;
++                      vdda-supply = <&ldo17_reg>;
++                      vddio-host-supply = <&ldo18_reg>;
++                      vdd-af-supply = <&cam_af_reg>;
++                      vdd-reg-supply = <&cam_io_reg>;
++                      clocks = <&camera 0>;           /* CAM_A_CLKOUT */
++                      clock-names = "cis_extclk";
++                      clock-frequency = <24000000>;
++                      port {
++                              s5c73m3_ep: endpoint {
++                                      remote-endpoint = <&csis0_ep>;
++                                      data-lanes = <1 2 3 4>;
++                              };
++                      };
++              };
++      };
++
++      i2c@13870000 {
++              samsung,i2c-sda-delay = <100>;
++              samsung,i2c-slave-addr = <0x10>;
++              samsung,i2c-max-bus-freq = <400000>;
++              pinctrl-0 = <&i2c1_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              lsm330dlc_gyro@6b {
++                      compatible = "st,lsm330dlc-gyro";
++                      reg = <0x6b>;
++                      irq-map-policy = <1>;
++                      interrupt-controller;
++                      #interrups-cells = <2>;
++                      interrupt-parent = <&lsm330dlc_gyro_map>;
++                      interrupts= <1 0>;
++
++                      lsm330dlc_gyro_map: lsm330dlc-gyro-map {
++                              compatible = "samsung,lsm330dlc-gyro-map";
++                              #interrupt-cells = <2>;
++                              #address-cells = <0>;
++                              #size-cells = <0>;
++                              interrupt-map = <0x1 0 &gpf0 3 0>;
++                      };
++              };
++
++              lsm330dlc_accel@19 {
++                      compatible = "st,lsm330dlc-accel";
++                      reg = <0x19>;
++                      irq-map-policy = <2>;
++                      interrupt-controller;
++                      #interrups-cells = <2>;
++                      interrupt-parent = <&lsm330dlc_accel_map>;
++                      interrupts= <1 0>;
++
++                      lsm330dlc_accel_map: lsm330dlc-accel-map {
++                              compatible = "samsung,lsm330dlc-accel-map";
++                              #interrupt-cells = <2>;
++                              #address-cells = <0>;
++                              #size-cells = <0>;
++                              interrupt-map = <0x1 0 &gpx0 0 0>;
++                      };
++              };
++      };
++
++      i2c@13890000 {
++              samsung,i2c-sda-delay = <100>;
++              samsung,i2c-slave-addr = <0x10>;
++              samsung,i2c-max-bus-freq = <400000>;
++              pinctrl-0 = <&i2c3_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              mms114-touchscreen@48 {
++                      compatible = "melfas,mms114";
++                      reg = <0x48>;
++                      interrupt-parent = <&gpm2>;
++                      interrupts = <3 2>;
++                      x-size = <720>;
++                      y-size = <1280>;
++                      avdd-supply = <&ldo23_reg>;
++                      vdd-supply = <&ldo24_reg>;
++              };
++      };
++
++      i2c@138A0000 {
++              samsung,i2c-sda-delay = <100>;
++              samsung,i2c-max-bus-freq = <100000>;
++              pinctrl-0 = <&i2c4_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              wm1811: wm1811@1a {
++                      compatible = "wlf,wm1811";
++                      reg = <0x1a>;
++                      interrupt-parent = <&gpx3>;
++                      interrupts = <6 4>;
++
++                      wlf,gpio-cfg = <0x3 0x0 0x0 0x0 0x0 0x0
++                                      0x0 0x8000 0x0 0x0 0x0>;
++                      wlf,micbias-cfg = <0x2f 0x2b>;
++
++                      wlf,lineout2-feedback;
++                      wlf,lineout1-se;
++                      wlf,lineout2-se;
++
++                      AVDD2-supply = <&vbatt_reg>;
++                      DBVDD1-supply = <&ldo3_reg>;
++                      DBVDD2-supply = <&vbatt_reg>;
++                      DBVDD3-supply = <&vbatt_reg>;
++                      CPVDD-supply = <&vbatt_reg>;
++                      SPKVDD1-supply = <&vbatt_reg>;
++                      SPKVDD2-supply = <&vbatt_reg>;
++
++                      wlf,ldo1ena = <&gpj0 4 0>;
++              };
++      };
++
++      i2c@138B0000 {
++              samsung,i2c-sda-delay = <100>;
++              samsung,i2c-slave-addr = <0x10>;
++              samsung,i2c-max-bus-freq = <100000>;
++              pinctrl-0 = <&i2c5_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              pn544@2b {
++                      compatible = "nxp,pn544-hci-i2c";
++                      reg = <0x2b>;
++                      interrupt-parent = <&gpx1>;
++                      interrupts = <7 1>;
++                      gpios = <&gpl2 6 0>,    /* GPIO_ENABLE */
++                              <&gpl2 7 0>;    /* GPIO_FW_RESET */
++              };
++      };
++
++      i2c@138D0000 {
++              samsung,i2c-sda-delay = <100>;
++              samsung,i2c-slave-addr = <0x10>;
++              samsung,i2c-max-bus-freq = <100000>;
++              pinctrl-0 = <&i2c7_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              max77686: max77686_pmic@09 {
++                      compatible = "maxim,max77686";
++                      interrupt-parent = <&gpx0>;
++                      interrupts = <7 0>;
++                      reg = <0x09>;
++                      #clock-cells = <1>;
++
++                      max77686,selb_gpios = <&gpf3 1 0>,
++                                           <&gpf3 2 0>,
++                                           <&gpf3 3 0>;
++
++                      max77686,dvs_gpios = <&gpm3 0 0>,
++                                            <&gpm3 1 0>,
++                                            <&gpm3 2 0>;
++
++                      max77686,default_dvs_idx = <1>;
++
++                      voltage-regulators {
++                              ldo1_reg: ldo@1 {
++                                      regulator-compatible = "LDO1";
++                                      regulator-name = "VALIVE_1.0V_AP";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                                      regulator-mem-on;
++                              };
++
++                              ldo2_reg: ldo@2 {
++                                      regulator-compatible = "LDO2";
++                                      regulator-name = "VM1M2_1.2V_AP";
++                                      regulator-min-microvolt = <1200000>;
++                                      regulator-max-microvolt = <1200000>;
++                                      regulator-always-on;
++                                      regulator-mem-on;
++                              };
++
++                              ldo3_reg: ldo@3 {
++                                      regulator-compatible = "LDO3";
++                                      regulator-name = "VCC_1.8V_AP";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                                      regulator-mem-on;
++                              };
++
++                              ldo4_reg: ldo@4 {
++                                      regulator-compatible = "LDO4";
++                                      regulator-name = "VCC_2.8V_AP";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
++                                      regulator-always-on;
++                                      regulator-mem-on;
++                              };
++
++                              ldo5_reg: ldo@5 {
++                                      regulator-compatible = "LDO5";
++                                      regulator-name = "VCC_1.8V_IO";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                                      regulator-mem-on;
++                              };
++
++                              ldo6_reg: ldo@6 {
++                                      regulator-compatible = "LDO6";
++                                      regulator-name = "VMPLL_1.0V_AP";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                                      regulator-mem-on;
++                              };
++
++                              ldo7_reg: ldo@7 {
++                                      regulator-compatible = "LDO7";
++                                      regulator-name = "VPLL_1.0V_AP";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-always-on;
++                                      regulator-mem-on;
++                              };
++
++                              ldo8_reg: ldo@8 {
++                                      regulator-compatible = "LDO8";
++                                      regulator-name = "VMIPI_1.0V";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-mem-off;
++                              };
++
++                              ldo9_reg: ldo@9 {
++                                      regulator-compatible = "LDO9";
++                                      regulator-name = "CAM_ISP_MIPI_1.2V";
++                                      regulator-min-microvolt = <1200000>;
++                                      regulator-max-microvolt = <1200000>;
++                                      regulator-mem-idle;
++                              };
++
++                              ldo10_reg: ldo@10 {
++                                      regulator-compatible = "LDO10";
++                                      regulator-name = "VMIPI_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-mem-off;
++                              };
++
++                              ldo11_reg: ldo@11 {
++                                      regulator-compatible = "LDO11";
++                                      regulator-name = "VABB1_1.95V";
++                                      regulator-min-microvolt = <1950000>;
++                                      regulator-max-microvolt = <1950000>;
++                                      regulator-always-on;
++                                      regulator-mem-off;
++                              };
++
++                              ldo12_reg: ldo@12 {
++                                      regulator-compatible = "LDO12";
++                                      regulator-name = "VUOTG_3.0V";
++                                      regulator-min-microvolt = <3000000>;
++                                      regulator-max-microvolt = <3000000>;
++                                      regulator-mem-off;
++                              };
++
++                              ldo13_reg: ldo@13 {
++                                      regulator-compatible = "LDO13";
++                                      regulator-name = "NFC_AVDD_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-mem-idle;
++                              };
++
++                              ldo14_reg: ldo@14 {
++                                      regulator-compatible = "LDO14";
++                                      regulator-name = "VABB2_1.95V";
++                                      regulator-min-microvolt = <1950000>;
++                                      regulator-max-microvolt = <1950000>;
++                                      regulator-always-on;
++                                      regulator-mem-off;
++                              };
++
++                              ldo15_reg: ldo@15 {
++                                      regulator-compatible = "LDO15";
++                                      regulator-name = "VHSIC_1.0V";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1000000>;
++                                      regulator-mem-off;
++                              };
++
++                              ldo16_reg: ldo@16 {
++                                      regulator-compatible = "LDO16";
++                                      regulator-name = "VHSIC_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-always-on;
++                                      regulator-mem-off;
++                              };
++
++                              ldo17_reg: ldo@17 {
++                                      regulator-compatible = "LDO17";
++                                      regulator-name = "CAM_SENSOR_CORE_1.2V";
++                                      regulator-min-microvolt = <1200000>;
++                                      regulator-max-microvolt = <1200000>;
++                                      regulator-mem-idle;
++                              };
++
++                              ldo18_reg: ldo@18 {
++                                      regulator-compatible = "LDO18";
++                                      regulator-name = "CAM_ISP_SEN_IO_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-mem-idle;
++                              };
++
++                              ldo19_reg: ldo@19 {
++                                      regulator-compatible = "LDO19";
++                                      regulator-name = "VT_CAM_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-mem-idle;
++                              };
++
++                              ldo20_reg: ldo@20 {
++                                      regulator-compatible = "LDO20";
++                                      regulator-name = "VDDQ_PRE_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-mem-idle;
++                              };
++
++                              ldo21_reg: ldo@21 {
++                                      regulator-compatible = "LDO21";
++                                      regulator-name = "VTF_2.8V";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
++                                      regulator-mem-idle;
++                              };
++
++                              ldo22_reg: ldo@22 {
++                                      regulator-compatible = "LDO22";
++                                      regulator-name = "VMEM_VDD_2.8V";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
++                                      regulator-always-on;
++                                      regulator-mem-off;
++                              };
++
++                              ldo23_reg: ldo@23 {
++                                      regulator-compatible = "LDO23";
++                                      regulator-name = "TSP_AVDD_3.3V";
++                                      regulator-min-microvolt = <3300000>;
++                                      regulator-max-microvolt = <3300000>;
++                                      regulator-mem-idle;
++                              };
++
++                              ldo24_reg: ldo@24 {
++                                      regulator-compatible = "LDO24";
++                                      regulator-name = "TSP_VDD_1.8V";
++                                      regulator-min-microvolt = <1800000>;
++                                      regulator-max-microvolt = <1800000>;
++                                      regulator-mem-idle;
++                              };
++
++                              ldo25_reg: ldo@25 {
++                                      regulator-compatible = "LDO25";
++                                      regulator-name = "LCD_VCC_3.3V";
++                                      regulator-min-microvolt = <2800000>;
++                                      regulator-max-microvolt = <2800000>;
++                                      regulator-mem-idle;
++                              };
++
++                              ldo26_reg: ldo@26 {
++                                      regulator-compatible = "LDO26";
++                                      regulator-name = "MOTOR_VCC_3.0V";
++                                      regulator-min-microvolt = <3000000>;
++                                      regulator-max-microvolt = <3000000>;
++                                      regulator-mem-idle;
++                              };
++
++                              buck1_reg: buck@1 {
++                                      regulator-compatible = "BUCK1";
++                                      regulator-name = "vdd_mif";
++                                      regulator-min-microvolt = <850000>;
++                                      regulator-max-microvolt = <1100000>;
++                                      regulator-always-on;
++                                      regulator-boot-on;
++                                      regulator-mem-off;
++                              };
++
++                              buck2_reg: buck@2 {
++                                      regulator-compatible = "BUCK2";
++                                      regulator-name = "vdd_arm";
++                                      regulator-min-microvolt = <850000>;
++                                      regulator-max-microvolt = <1500000>;
++                                      regulator-always-on;
++                                      regulator-boot-on;
++                                      regulator-mem-off;
++                              };
++
++                              buck3_reg: buck@3 {
++                                      regulator-compatible = "BUCK3";
++                                      regulator-name = "vdd_int";
++                                      regulator-min-microvolt = <850000>;
++                                      regulator-max-microvolt = <1150000>;
++                                      regulator-always-on;
++                                      regulator-boot-on;
++                                      regulator-mem-off;
++                              };
++
++                              buck4_reg: buck@4 {
++                                      regulator-compatible = "BUCK4";
++                                      regulator-name = "vdd_g3d";
++                                      regulator-min-microvolt = <850000>;
++                                      regulator-max-microvolt = <1150000>;
++                                      regulator-boot-on;
++                                      regulator-mem-off;
++                              };
++
++                              buck5_reg: buck@5 {
++                                      regulator-compatible = "BUCK5";
++                                      regulator-name = "VMEM_1.2V_AP";
++                                      regulator-min-microvolt = <1200000>;
++                                      regulator-max-microvolt = <1200000>;
++                                      regulator-always-on;
++                              };
++
++                              buck6_reg: buck@6 {
++                                      regulator-compatible = "BUCK6";
++                                      regulator-name = "VCC_SUB_1.35V";
++                                      regulator-min-microvolt = <1350000>;
++                                      regulator-max-microvolt = <1350000>;
++                                      regulator-always-on;
++                              };
++
++                              buck7_reg: buck@7 {
++                                      regulator-compatible = "BUCK7";
++                                      regulator-name = "VCC_SUB_2.0V";
++                                      regulator-min-microvolt = <2000000>;
++                                      regulator-max-microvolt = <2000000>;
++                                      regulator-always-on;
++                              };
++
++                              buck8_reg: buck@8 {
++                                      regulator-compatible = "BUCK8";
++                                      regulator-name = "VMEM_VDDF_3.0V";
++                                      regulator-min-microvolt = <2850000>;
++                                      regulator-max-microvolt = <2850000>;
++                                      regulator-always-on;
++                                      regulator-mem-off;
++                              };
++
++                              buck9_reg: buck@9 {
++                                      regulator-compatible = "BUCK9";
++                                      regulator-name = "CAM_ISP_CORE_1.2V";
++                                      regulator-min-microvolt = <1000000>;
++                                      regulator-max-microvolt = <1200000>;
++                                      regulator-mem-off;
++                              };
++                      };
++              };
++      };
++
++      i2c_if_pmic: i2c@0 {
++              compatible = "i2c-gpio";
++              gpios = <&gpm2 0 0
++                       &gpm2 1 0
++                      >;
++              #address-cells = <1>;
++              #size-cells = <0>;
++
++              max77693@66 {
++                      compatible = "maxim,max77693";
++                      interrupt-parent = <&gpx1>;
++                      interrupts = <5 2>;
++                      wakeup = <1>;
++                      reg = <0x66>;
++
++                      regulators {
++                              esafeout1_reg: esafeout@1 {
++                                      regulator-compatible = "ESAFEOUT1";
++                                      regulator-name = "ESAFEOUT1";
++                                      regulator-always-on;
++                                      regulator-boot-on;
++                              };
++                              esafeout2_reg: esafeout@2 {
++                                      regulator-compatible = "ESAFEOUT2";
++                                      regulator-name = "ESAFEOUT2";
++                              };
++                              charger_reg: charger@0 {
++                                      regulator-compatible = "CHARGER";
++                                      regulator-name = "CHARGER";
++                                      regulator-min-microamp = <60000>;
++                                      regulator-max-microamp = <2580000>;
++                                      regulator-boot-on;
++                              };
++                      };
++
++                      max_muic: max77693-muic {
++                              compatible = "maxim,max77693-muic";
++                              intmask@1 {
++                                      addr = <0x7>;
++                                      data = <0x9>;
++                              };
++                              intmask@2 {
++                                      addr = <0x8>;
++                                      data = <0x1>;
++                              };
++
++                      };
++              };
++      };
++
++      i2c_fuel: i2c@1 {
++              compatible = "i2c-gpio";
++              gpios = <&gpf1 5 0
++                       &gpf1 4 0
++                      >;
++              #address-cells = <1>;
++              #size-cells = <0>;
++
++              max17047@36 {
++                      compatible = "maxim,max17047";
++                      interrupt-parent = <&gpx2>;
++                      interrupts = <3 2>;
++                      reg = <0x36>;
++              };
++      };
++
++      lcd_vdd3_reg: voltage-regulator@1 {
++              compatible = "regulator-fixed";
++              regulator-name = "LCD_VDD_2.2V";
++              regulator-min-microvolt = <2200000>;
++              regulator-max-microvolt = <2200000>;
++              gpio = <&gpc0 1 0>;
++              enable-active-high;
++      };
++
++      cam_af_reg: voltage-regulator@2 {
++              compatible = "regulator-fixed";
++              regulator-name = "CAM_AF";
++              regulator-min-microvolt = <2800000>;
++              regulator-max-microvolt = <2800000>;
++              gpio = <&gpm0 4 0>;
++              enable-active-high;
++      };
++
++      cam_io_reg: voltage-regulator@3 {
++              compatible = "regulator-fixed";
++              regulator-name = "CAM_SENSOR_A";
++              regulator-min-microvolt = <2800000>;
++              regulator-max-microvolt = <2800000>;
++              gpio = <&gpm0 2 0>;
++              enable-active-high;
++      };
++
++      cam_isp_core_reg: voltage-regulator@4 {
++              compatible = "regulator-fixed";
++              regulator-name = "CAM_ISP_CORE_1.2V_EN";
++              regulator-min-microvolt = <1200000>;
++              regulator-max-microvolt = <1200000>;
++              gpio = <&gpm0 3 0>;
++              enable-active-high;
++              regulator-always-on;
++      };
++
++      vbatt_reg: voltage-regulator@5 {
++              compatible = "regulator-fixed";
++              regulator-name = "VBATT";
++              regulator-min-microvolt = <5000000>;
++              regulator-max-microvolt = <5000000>;
++              gpio = <>;
++              regulator-always-on;
++      };
++
++      ps_als_reg: voltage-regulator@6 {
++              compatible = "regulator-fixed";
++              regulator-name = "LED_A_3.0V";
++              regulator-min-microvolt = <3000000>;
++              regulator-max-microvolt = <3000000>;
++              gpio = <&gpj0 5 0>;
++              enable-active-high;
++      };
++
++      fimd0_lcd: panel {
++              compatible = "samsung,s6e8aa0";
++              reset-gpio = <&gpy4 5 0>;
++              power-on-delay= <50>;
++              reset-delay = <100>;
++              init-delay = <100>;
++              vdd3-supply = <&lcd_vdd3_reg>;
++              vci-supply = <&ldo25_reg>;
++              video-source = <&dsi_0>;
++              samsung,panel-width-mm = <58>; /* FIXME */
++              samsung,panel-height-mm = <103>; /* FIXME */
++
++              display-timings {
++                      native-mode = <&timing0>;
++
++                      timing0: timing-0 {
++                              clock-frequency = <0>;
++                              hactive = <720>;
++                              vactive = <1280>;
++                              hfront-porch = <5>;
++                              hback-porch = <5>;
++                              hsync-len = <5>;
++                              vfront-porch = <13>;
++                              vback-porch = <1>;
++                              vsync-len = <2>;
++                      };
++              };
++      };
++
++      dsi_0: dsi@11C80000 {
++              samsung,pll-stable-time = <500>;
++              samsung,stop-holding-count = <0x7ff>;
++              samsung,bta-timeout = <0xff>;
++              samsung,rx-timeout = <0xffff>;
++              samsung,pll-clk-freq = <24000000>;
++              samsung,cmd-allow = <0xf>;
++              vdd11-supply = <&ldo8_reg>;
++              vdd18-supply = <&ldo10_reg>;
++              status = "okay";
++      };
++
++      fimd@11c00000 {
++              samsung,fimd-display = <&fimd0_lcd>;
++              samsung,fimd-vidout-rgb;
++              samsung,fimd-inv-vclk;
++              samsung,fimd-frame-rate = <60>;
++              samsung,default-window = <3>;
++              samsung,fimd-win-bpp = <32>;
++              status = "okay";
++      };
++
++      g2d@10800000 {
++              status = "okay";
++      };
++
++      vidi {
++              compatible = "samsung,exynos-drm-vidi";
++      };
++
++      sysmmu-fimd0 {
++              clock-names = "sysmmu";
++              clocks = <&clock 287>;
++              mmu-master = <&fimd>;
++      };
++
++      sysmmu-g2d {
++              clock-names = "sysmmu";
++              clocks = <&clock 280>;
++              mmu-master = <&g2d>;
++      };
++
++      hsotg@12480000 {
++              status = "okay";
++              vusb_d-supply = <&ldo15_reg>;
++              vusb_a-supply = <&ldo12_reg>;
++              extcon = <&max_muic>;
++      };
++
++      ehci@12580000 {
++              status = "okay";
++              vusb_d-supply = <&ldo15_reg>;
++              vusb_a-supply = <&ldo12_reg>;
++              phys = <&exynos_usbphy 2>;
++              phy-names = "hsic0";
++      };
++
++      spi_1: spi@13930000 {
++              pinctrl-names = "default";
++              pinctrl-0 = <&spi1_bus>;
++              status = "okay";
++
++              s5c73m3_spi: s5c73m3 {
++                      compatible = "samsung,s5c73m3";
++                      spi-max-frequency = <50000000>;
++                      reg = <0>;
++                      controller-data {
++                              cs-gpio = <&gpb 5 0>;
++                              samsung,spi-feedback-delay = <2>;
++                      };
++              };
++      };
++
++      camera {
++              status = "okay";
++
++              pinctrl-names = "default";
++              pinctrl-0 = <&cam_port_a_clk_active>;
++
++              fimc_0: fimc@11800000 {
++                      clock-frequency = <176000000>;
++                      status = "okay";
++              };
++
++              fimc_1: fimc@11810000 {
++                      clock-frequency = <176000000>;
++                      status = "okay";
++              };
++
++              fimc_2: fimc@11820000 {
++                      clock-frequency = <176000000>;
++                      status = "okay";
++              };
++
++              fimc_3: fimc@11830000 {
++                      clock-frequency = <176000000>;
++                      status = "okay";
++              };
++
++              csis_0: csis@11880000 {
++                      status = "okay";
++                      vddcore-supply = <&ldo8_reg>;
++                      vddio-supply = <&ldo10_reg>;
++                      clock-frequency = <176000000>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++
++                      /* Camera C (3) MIPI CSI-2 (CSIS0) */
++                      port@3 {
++                              reg = <3>;
++                              csis0_ep: endpoint {
++                                      remote-endpoint = <&s5c73m3_ep>;
++                                      data-lanes = <1 2 3 4>;
++                                      samsung,csis-hs-settle = <12>;
++                              };
++                      };
++              };
++
++              csis_1: csis@11890000 {
++                      status = "okay";
++                      vddcore-supply = <&ldo8_reg>;
++                      vddio-supply = <&ldo10_reg>;
++                      clock-frequency = <176000000>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++
++                      /* Camera D (4) MIPI CSI-2 (CSIS1) */
++                      port@4 {
++                              reg = <4>;
++                              csis1_ep: endpoint {
++                                      remote-endpoint = <&is_s5k6a3_ep>;
++                                      data-lanes = <1>;
++                                      samsung,csis-hs-settle = <18>;
++                                      samsung,csis-wclk;
++                              };
++                      };
++              };
++
++              fimc-is@12000000 {
++                      status = "okay";
++                      pinctrl-0 = <&fimc_is_uart>;
++                      pinctrl-names = "default";
++                      memory-region = <&fimc_mem>;
++
++                      fimc_lite_0: fimc-lite@12390000 {
++                              status = "okay";
++                      };
++
++                      fimc_lite_1: fimc-lite@123A0000 {
++                              status = "okay";
++                      };
++
++                      i2c1_isp: i2c-isp@12140000 {
++                              pinctrl-0 = <&fimc_is_i2c1>;
++                              pinctrl-names = "default";
++
++                              s5k6a3@10 {
++                                      compatible = "samsung,s5k6a3";
++                                      reg = <0x10>;
++                                      svdda-supply = <&cam_io_reg>;
++                                      svddio-supply = <&ldo19_reg>;
++                                      gpios = <&gpm1 6 0>;
++                                      clocks = <&camera 0>; /* CAM_A_CLKOUT */
++                                      clock-names = "extclk";
++                                      clock-frequency = <24000000>;
++
++                                      port {
++                                              is_s5k6a3_ep: endpoint {
++                                                      remote-endpoint = <&csis1_ep>;
++                                                      data-lanes = <1>;
++                                              };
++                                      };
++                              };
++                      };
++              };
++      };
++
++      codec@13400000 {
++              status = "okay";
++
++              memport@0 {
++                      memory-region = <&mfc_l_mem>;
++              };
++
++              memport@1 {
++                      memory-region = <&mfc_r_mem>;
++              };
++      };
++
++      i2s0: i2s@03830000 {
++              pinctrl-0 = <&i2s0_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++      };
++
++      sound {
++              compatible = "samsung,exynos4-wm1811";
++              clocks = <&clock 2>, <&clock 396>, <&clock 21>, <&clock 6>;
++              clock-names = "parent", "out-mux", "out", "pll" /* EPLL */;
++              samsung,i2s-controller = <&i2s0>;
++              samsung,audio-codec = <&wm1811>;
++              samsung,model = "wm1811";
++              samsung,mic-availability = <1 1>;
++              samsung,mic-en-gpios = <&gpf1 7 0>, <&gpf2 0 0>;
++      };
++
++      gpu@13000000 {
++              status = "okay";
++              vdd_g3d-supply = <&buck4_reg>;
++      };
++
++      cpufreq {
++              freq_table = <0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 1100000 1000000
++                           900000 800000 700000 600000 500000 400000 300000
++                           200000>;
++              vdd_arm-supply = <&buck2_reg>;
++              status = "okay";
++      };
++
++      modem_if {
++              compatible = "samsung,modem_if";
++              reset-req-gpio = <&gpm3 3 0>;
++              cp-on-gpio = <&gpl2 5 0>;
++              cp-reset-gpio = <&gpx3 2 0>;
++              pda-active-gpio = <&gpf1 6 0>;
++
++              phone-active-gpio = <&gpx1 6 0>;
++              cp-dump-int-gpio = <&gpx1 2 0>;
++
++              ap-dump-int-gpio = <0>;
++              flm_uart_sel = <0>;
++              cp_warm_reset = <0>;
++              sim_detect = <0>;
++
++              link-slavewake-gpio = <&gpx1 0 0>;
++              link-hostwake-gpio = <&gpx1 1 0>;
++              link-active-gpio = <&gpf1 1 0>;
++              link-enable-gpio = <0>;
++
++              modem-type = "xmm6262";
++              link-type = "hsic";
++              modem-net = "umts";
++              use-handover = <0>;
++
++              pinctrl-names = "default", "active";
++              pinctrl-0 = <&modem_state_off>;
++              pinctrl-1 = <&modem_state_active>;
++      };
++
++      charger-manager@0 {
++              compatible = "charger-manager";
++              status = "okay";
++              vinchg1-supply = <&charger_reg>;
++
++              cm-name = "battery";
++              cm-poll-mode = <2>;
++              cm-poll-interval = <30000>;
++
++              cm-fullbatt-vchkdrop-ms = <30000>;
++              cm-fullbatt-vchkdrop-volt = <150000>;
++              cm-fullbatt-soc = <100>;
++
++              cm-battery-stat = <3>;
++
++              cm-battery-cold = <50>;
++              cm-battery-cold-in-minus;
++              cm-battery-hot = <650>;
++              cm-battery-temp-diff = <150>;
++
++              cm-num-chargers = <1>;
++              cm-chargers = "max77693-charger";
++
++              cm-fuel-gauge = "max170xx_battery";
++              cm-battery-has-therm;
++
++              cm-charging-max = <21600000>;
++              cm-discharging-max = <540000>;
++
++              regulator@0 {
++                      cm-regulator-name = "vinchg1";
++                      cable@0 {
++                              cm-cable-name = "USB";
++                              cm-cable-extcon = "max77693-muic";
++                              cm-cable-min = <475000>;
++                              cm-cable-max = <500000>;
++                      };
++                      cable@1 {
++                              cm-cable-name = "TA";
++                              cm-cable-extcon = "max77693-muic";
++                              cm-cable-min = <650000>;
++                              cm-cable-max = <675000>;
++                      };
++                      cable@2 {
++                              cm-cable-name = "Slow-charger";
++                              cm-cable-extcon = "max77693-muic";
++                              cm-cable-min = <650000>;
++                              cm-cable-max = <675000>;
++                      };
++                      cable@3 {
++                              cm-cable-name = "Fast-charger";
++                              cm-cable-extcon = "max77693-muic";
++                              cm-cable-min = <650000>;
++                              cm-cable-max = <675000>;
++                      };
++                      cable@4 {
++                              cm-cable-name = "MHL";
++                              cm-cable-extcon = "max77693-muic";
++                              cm-cable-min = <475000>;
++                              cm-cable-max = <500000>;
++                      };
++              };
++
++      };
++
++      fixed-regulators {
++              compatible = "simple-bus";
++              #address-cells = <1>;
++              #size-cells = <0>;
++
++              wlan_reg: voltage-regulator@7 {
++                      compatible = "regulator-fixed";
++                      reg = <7>;
++                      regulator-name = "WL_REG_ON";
++                      regulator-min-microvolt = <1800000>;
++                      regulator-max-microvolt = <1800000>;
++                      gpio = <&gpj0 0 0>;
++                      enable-active-high;
++              };
++      };
++
++      wlan {
++              compatible = "brcm,bcm4334";
++              wlan-supply = <&wlan_reg>;
++              interrupt-parent = <&gpx2>;
++              interrupts = <5 4>;
++              clocks = <&max77686 2>;
++              clock-names = "32khz";
++              pinctrl-names = "default";
++              pinctrl-0 = <&wlan_int>;
++      };
++
++      sdhci@12540000 {
++              bus-width = <4>;
++              broken-cd;
++              pinctrl-0 = <&sd3_clk &sd3_cmd &sd3_bus4>;
++              pinctrl-names = "default";
++              status = "okay";
++      };
++
++
++      exynos-usbphy@125B0000 {
++              status = "okay";
++      };
++
++      adc: adc@126C0000 {
++              compatible = "samsung,exynos-adc-v1";
++              reg = <0x126C0000 0x20>, <0x10020718 0x4>;
++              interrupt-parent = <&combiner>;
++              interrupts = <10 3>;
++              #io-channel-cells = <1>;
++              clocks = <&clock 326>;
++              clock-names = "adc";
++              vdd-supply = <&ldo3_reg>;
++              status = "ok";
++      };
++
++      tmu@100C0000 {
++              vtmu-supply = <&ldo10_reg>;
++              status = "okay";
++      };
++
++      vsil: voltage-regulator-vsil {
++              compatible = "regulator-fixed";
++              regulator-name = "HDMI_5V";
++              regulator-min-microvolt = <5000000>;
++              regulator-max-microvolt = <5000000>;
++              gpio = <&gpl0 4 0>;
++              enable-active-high;
++              vin-supply = <&buck7_reg>;
++      };
++
++      i2c-mhl {
++              compatible = "i2c-gpio";
++              gpios = <&gpf0 4 0 &gpf0 6 0>;
++              i2c-gpio,delay-us = <100>;
++              #address-cells = <1>;
++              #size-cells = <0>;
++
++              pinctrl-0 = <&i2c_mhl_bus>;
++              pinctrl-names = "default";
++              status = "okay";
++
++              sii9234: sii9234@39 {
++                      compatible = "sii,sii9234";
++                      vcc-supply = <&vsil>;
++                      gpio-reset = <&gpf3 4 0>;
++                      gpio-int = <&gpf3 5 0>;
++                      reg = <0x39>;
++                      extcon = <&max_muic>;
++              };
++      };
++
++      i2c@138B0000 {
++              hdmiddc@37 {
++                      compatible = "samsung,exynos5-hdmiddc";
++                      reg = <0x37>;
++              };
++      };
++
++      hdmi@12D00000 {
++              hpd-gpio = <&gpx3 7 0>;
++              pinctrl-names = "default";
++              pinctrl-0 = <&hdmi_hpd>;
++              /*
++               * HDMI_EN gpio is controlled by SII9234, so hdmi-en should
++               * be a dummy regulator. Therefore LDO3 is used instead
++               * because it is enabled at the same time as hdmi-en
++               */
++              hdmi-en-supply = <&ldo3_reg>;
++              vdd-supply = <&ldo3_reg>;
++              vdd_osc-supply = <&ldo4_reg>;
++              vdd_pll-supply = <&ldo3_reg>;
++              status = "okay";
++              max-pixel-clock = <75000000>;
++      };
++};
++
++&pinctrl_1 {
++      modem_state_active: modem-state-active {
++              samsung,pins = "gpx1-6", "gpx1-1", "gpx1-2";
++              samsung,pin-pud = <0>;
++      };
++      modem_state_off: modem-state-off {
++              samsung,pins = "gpx1-6", "gpx1-1", "gpx1-2";
++              samsung,pin-pud = <1>;
++      };
++
++      wlan_int: wlan-irq {
++              samsung,pins = "gpx2-5";
++              samsung,pin-pud = <1>;
++      };
++
++      hdmi_hpd: hdmi-hpd {
++              samsung,pins = "gpx3-7";
++              samsung,pin-pud = <1>;
++      };
++};
++
++&pinctrl_0 {
++      mhl_int: mhl-int {
++              samsung,pins = "gpf3-5";
++              samsung,pin-pud = <0>;
++      };
++      i2c_mhl_bus: i2c-mhl-bus {
++              samsung,pins = "gpf0-4", "gpf0-6";
++              samsung,pin-function = <2>;
++              samsung,pin-pud = <1>;
++              samsung,pin-drv = <0>;
++      };
++};
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1236-mm-page_alloc-fix-freeing-of-MIGRATE_RESERVE-migrate.patch b/patches.tizen/1236-mm-page_alloc-fix-freeing-of-MIGRATE_RESERVE-migrate.patch
new file mode 100644 (file)
index 0000000..bbdd43f
--- /dev/null
@@ -0,0 +1,86 @@
+From 019af219dcafc0ada7d4d9bc7dffbb58ee9d10b2 Mon Sep 17 00:00:00 2001
+From: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
+Date: Fri, 14 Feb 2014 19:34:17 +0100
+Subject: [PATCH 1236/1302] mm/page_alloc: fix freeing of MIGRATE_RESERVE
+ migratetype pages
+
+Pages allocated from MIGRATE_RESERVE migratetype pageblocks
+are not freed back to MIGRATE_RESERVE migratetype free
+lists in free_pcppages_bulk()->__free_one_page() if we got
+to free_pcppages_bulk() through drain_[zone_]pages().
+The freeing through free_hot_cold_page() is okay because
+freepage migratetype is set to pageblock migratetype before
+calling free_pcppages_bulk().  If pages of MIGRATE_RESERVE
+migratetype end up on the free lists of other migratetype
+whole Reserved pageblock may be later changed to the other
+migratetype in __rmqueue_fallback() and it will be never
+changed back to be a Reserved pageblock.  Fix the issue by
+preserving freepage migratetype as a pageblock migratetype
+(instead of overriding it to the requested migratetype)
+for MIGRATE_RESERVE migratetype pages in rmqueue_bulk().
+
+The problem was introduced in v2.6.31 by commit ed0ae21
+("page allocator: do not call get_pageblock_migratetype()
+more than necessary").
+
+Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
+Reported-by: Yong-Taek Lee <ytk.lee@samsung.com>
+Cc: Marek Szyprowski <m.szyprowski@samsung.com>
+Cc: Mel Gorman <mgorman@suse.de>
+Cc: Hugh Dickins <hughd@google.com>
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-Id: I1d4ab2a3241387160dd376b0ead864cd2b0c59f0
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/mmzone.h |  5 +++++
+ mm/page_alloc.c        | 10 +++++++---
+ 2 files changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
+index 5c76737..dc40e42 100644
+--- a/include/linux/mmzone.h
++++ b/include/linux/mmzone.h
+@@ -63,6 +63,11 @@ enum {
+       MIGRATE_TYPES
+ };
++static inline bool is_migrate_reserve(int migratetype)
++{
++      return unlikely(migratetype == MIGRATE_RESERVE);
++}
++
+ #ifdef CONFIG_CMA
+ #  define is_migrate_cma(migratetype) unlikely((migratetype) == MIGRATE_CMA)
+ #else
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index bb92575..1138c55 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -1138,7 +1138,7 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order,
+                       unsigned long count, struct list_head *list,
+                       int migratetype, int cold)
+ {
+-      int mt = migratetype, i;
++      int mt, i;
+       spin_lock(&zone->lock);
+       for (i = 0; i < count; ++i) {
+@@ -1159,9 +1159,13 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order,
+                       list_add(&page->lru, list);
+               else
+                       list_add_tail(&page->lru, list);
++              mt = get_pageblock_migratetype(page);
+               if (IS_ENABLED(CONFIG_CMA)) {
+-                      mt = get_pageblock_migratetype(page);
+-                      if (!is_migrate_cma(mt) && !is_migrate_isolate(mt))
++                      if (!is_migrate_cma(mt) && !is_migrate_isolate(mt) &&
++                          !is_migrate_reserve(mt))
++                              mt = migratetype;
++              } else {
++                      if (!is_migrate_reserve(mt))
+                               mt = migratetype;
+               }
+               set_freepage_migratetype(page, mt);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1237-userns-Allow-PR_CAPBSET_DROP-in-a-user-namespace.patch b/patches.tizen/1237-userns-Allow-PR_CAPBSET_DROP-in-a-user-namespace.patch
new file mode 100644 (file)
index 0000000..d40009d
--- /dev/null
@@ -0,0 +1,35 @@
+From 202699cb7072a5d4f770ddf17805c40d8d4a453e Mon Sep 17 00:00:00 2001
+From: "Eric W. Biederman" <ebiederm@xmission.com>
+Date: Tue, 2 Jul 2013 10:04:54 -0700
+Subject: [PATCH 1237/1302] userns: Allow PR_CAPBSET_DROP in a user namespace.
+
+As the capabilites and capability bounding set are per user namespace
+properties it is safe to allow changing them with just CAP_SETPCAP
+permission in the user namespace.
+
+Change-Id: I65d5c6ef80d4196cc6b8cbc86a9661764c5b3ab1
+Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
+Tested-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
+Signed-off-by: Dariusz Michaluk <d.michaluk@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ security/commoncap.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/security/commoncap.c b/security/commoncap.c
+index c44b6fe..9fccf71 100644
+--- a/security/commoncap.c
++++ b/security/commoncap.c
+@@ -824,7 +824,7 @@ int cap_task_setnice(struct task_struct *p, int nice)
+  */
+ static long cap_prctl_drop(struct cred *new, unsigned long cap)
+ {
+-      if (!capable(CAP_SETPCAP))
++      if (!ns_capable(current_user_ns(), CAP_SETPCAP))
+               return -EPERM;
+       if (!cap_valid(cap))
+               return -EINVAL;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1238-clocksource-exynos4-Fix-wrong-bit-operation-in-exyno.patch b/patches.tizen/1238-clocksource-exynos4-Fix-wrong-bit-operation-in-exyno.patch
new file mode 100644 (file)
index 0000000..87b6fd3
--- /dev/null
@@ -0,0 +1,34 @@
+From 9ef5271400101d5d82c1638ebbe6c9e321f931dc Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Tue, 4 Feb 2014 18:54:23 +0900
+Subject: [PATCH 1238/1302] clocksource: exynos4: Fix wrong bit operation in
+ exynos4_mct_write()
+
+There is a faulty bit operation during checking offset in exyno4_mct_write().
+This patch fixes it correctly.
+
+Change-Id: Ifbe30007bc378d8ab0585a70c0c343dbbc350415
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/clocksource/exynos_mct.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
+index 9c2f9ab..119917d 100644
+--- a/drivers/clocksource/exynos_mct.c
++++ b/drivers/clocksource/exynos_mct.c
+@@ -95,8 +95,8 @@ static void exynos4_mct_write(unsigned int value, unsigned long offset)
+       __raw_writel(value, reg_base + offset);
+       if (likely(offset >= EXYNOS4_MCT_L_BASE(0))) {
+-              stat_addr = (offset & ~EXYNOS4_MCT_L_MASK) + MCT_L_WSTAT_OFFSET;
+-              switch (offset & EXYNOS4_MCT_L_MASK) {
++              stat_addr = (offset & EXYNOS4_MCT_L_MASK) + MCT_L_WSTAT_OFFSET;
++              switch (offset & ~EXYNOS4_MCT_L_MASK) {
+               case MCT_L_TCON_OFFSET:
+                       mask = 1 << 3;          /* L_TCON write status */
+                       break;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1239-cpufreq-ondemand-Change-the-calculation-of-target-fr.patch b/patches.tizen/1239-cpufreq-ondemand-Change-the-calculation-of-target-fr.patch
new file mode 100644 (file)
index 0000000..ab797e2
--- /dev/null
@@ -0,0 +1,192 @@
+From 0f15ad7d150188fc33934ef62c02ff5ae169a93c Mon Sep 17 00:00:00 2001
+From: Stratos Karafotis <stratosk@semaphore.gr>
+Date: Wed, 5 Jun 2013 19:01:25 +0300
+Subject: [PATCH 1239/1302] cpufreq: ondemand: Change the calculation of target
+ frequency
+
+The ondemand governor calculates load in terms of frequency and
+increases it only if load_freq is greater than up_threshold
+multiplied by the current or average frequency.  This appears to
+produce oscillations of frequency between min and max because,
+for example, a relatively small load can easily saturate minimum
+frequency and lead the CPU to the max.  Then, it will decrease
+back to the min due to small load_freq.
+
+Change the calculation method of load and target frequency on the
+basis of the following two observations:
+
+ - Load computation should not depend on the current or average
+   measured frequency.  For example, absolute load of 80% at 100MHz
+   is not necessarily equivalent to 8% at 1000MHz in the next
+   sampling interval.
+
+ - It should be possible to increase the target frequency to any
+   value present in the frequency table proportional to the absolute
+   load, rather than to the max only, so that:
+
+   Target frequency = C * load
+
+   where we take C = policy->cpuinfo.max_freq / 100.
+
+Tested on Intel i7-3770 CPU @ 3.40GHz and on Quad core 1500MHz Krait.
+Phoronix benchmark of Linux Kernel Compilation 3.1 test shows an
+increase ~1.5% in performance. cpufreq_stats (time_in_state) shows
+that middle frequencies are used more, with this patch.  Highest
+and lowest frequencies were used less by ~9%.
+
+[rjw: We have run multiple other tests on kernels with this
+ change applied and in the vast majority of cases it turns out
+ that the resulting performance improvement also leads to reduced
+ consumption of energy.  The change is additionally justified by
+ the overall simplification of the code in question.]
+
+Change-Id: I26399d5d61616ee9157baa7eb8b337bacab5b892
+Signed-off-by: Stratos Karafotis <stratosk@semaphore.gr>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/cpufreq_governor.c | 10 +---------
+ drivers/cpufreq/cpufreq_governor.h |  1 -
+ drivers/cpufreq/cpufreq_ondemand.c | 39 +++++++-------------------------------
+ 3 files changed, 8 insertions(+), 42 deletions(-)
+
+diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
+index f45f6a4..dabb888 100644
+--- a/drivers/cpufreq/cpufreq_governor.c
++++ b/drivers/cpufreq/cpufreq_governor.c
+@@ -100,7 +100,7 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu)
+       policy = cdbs->cur_policy;
+-      /* Get Absolute Load (in terms of freq for ondemand gov) */
++      /* Get Absolute Load */
+       for_each_cpu(j, policy->cpus) {
+               struct cpu_dbs_common_info *j_cdbs;
+               u64 cur_wall_time, cur_idle_time;
+@@ -161,14 +161,6 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu)
+                       lb_dbs_info->idle_time = (100 * idle_time) / wall_time;
+               }
+-              if (dbs_data->cdata->governor == GOV_ONDEMAND) {
+-                      int freq_avg = __cpufreq_driver_getavg(policy, j);
+-                      if (freq_avg <= 0)
+-                              freq_avg = policy->cur;
+-
+-                      load *= freq_avg;
+-              }
+-
+               if (load > max_load)
+                       max_load = load;
+       }
+diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h
+index 09d9603..3886a18 100644
+--- a/drivers/cpufreq/cpufreq_governor.h
++++ b/drivers/cpufreq/cpufreq_governor.h
+@@ -177,7 +177,6 @@ struct od_dbs_tuners {
+       unsigned int sampling_rate;
+       unsigned int sampling_down_factor;
+       unsigned int up_threshold;
+-      unsigned int adj_up_threshold;
+       unsigned int powersave_bias;
+       unsigned int io_is_busy;
+ };
+diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
+index c087347..25438bb 100644
+--- a/drivers/cpufreq/cpufreq_ondemand.c
++++ b/drivers/cpufreq/cpufreq_ondemand.c
+@@ -29,11 +29,9 @@
+ #include "cpufreq_governor.h"
+ /* On-demand governor macros */
+-#define DEF_FREQUENCY_DOWN_DIFFERENTIAL               (10)
+ #define DEF_FREQUENCY_UP_THRESHOLD            (80)
+ #define DEF_SAMPLING_DOWN_FACTOR              (1)
+ #define MAX_SAMPLING_DOWN_FACTOR              (100000)
+-#define MICRO_FREQUENCY_DOWN_DIFFERENTIAL     (3)
+ #define MICRO_FREQUENCY_UP_THRESHOLD          (95)
+ #define MICRO_FREQUENCY_MIN_SAMPLE_RATE               (10000)
+ #define MIN_FREQUENCY_UP_THRESHOLD            (11)
+@@ -161,14 +159,10 @@ static void dbs_freq_increase(struct cpufreq_policy *p, unsigned int freq)
+ /*
+  * Every sampling_rate, we check, if current idle time is less than 20%
+- * (default), then we try to increase frequency. Every sampling_rate, we look
+- * for the lowest frequency which can sustain the load while keeping idle time
+- * over 30%. If such a frequency exist, we try to decrease to this frequency.
+- *
+- * Any frequency increase takes it to the maximum frequency. Frequency reduction
+- * happens at minimum steps of 5% (default) of current frequency
++ * (default), then we try to increase frequency. Else, we adjust the frequency
++ * proportional to load.
+  */
+-static void od_check_cpu(int cpu, unsigned int load_freq)
++static void od_check_cpu(int cpu, unsigned int load)
+ {
+       struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu);
+       struct cpufreq_policy *policy = dbs_info->cdbs.cur_policy;
+@@ -178,29 +172,17 @@ static void od_check_cpu(int cpu, unsigned int load_freq)
+       dbs_info->freq_lo = 0;
+       /* Check for frequency increase */
+-      if (load_freq > od_tuners->up_threshold * policy->cur) {
++      if (load > od_tuners->up_threshold) {
+               /* If switching to max speed, apply sampling_down_factor */
+               if (policy->cur < policy->max)
+                       dbs_info->rate_mult =
+                               od_tuners->sampling_down_factor;
+               dbs_freq_increase(policy, policy->max);
+               return;
+-      }
+-
+-      /* Check for frequency decrease */
+-      /* if we cannot reduce the frequency anymore, break out early */
+-      if (policy->cur == policy->min)
+-              return;
+-
+-      /*
+-       * The optimal frequency is the frequency that is the lowest that can
+-       * support the current CPU usage without triggering the up policy. To be
+-       * safe, we focus 10 points under the threshold.
+-       */
+-      if (load_freq < od_tuners->adj_up_threshold
+-                      * policy->cur) {
++      } else {
++              /* Calculate the next frequency proportional to load */
+               unsigned int freq_next;
+-              freq_next = load_freq / od_tuners->adj_up_threshold;
++              freq_next = load * policy->cpuinfo.max_freq / 100;
+               /* No longer fully busy, reset rate_mult */
+               dbs_info->rate_mult = 1;
+@@ -374,9 +356,6 @@ static ssize_t store_up_threshold(struct dbs_data *dbs_data, const char *buf,
+                       input < MIN_FREQUENCY_UP_THRESHOLD) {
+               return -EINVAL;
+       }
+-      /* Calculate the new adj_up_threshold */
+-      od_tuners->adj_up_threshold += input;
+-      od_tuners->adj_up_threshold -= od_tuners->up_threshold;
+       od_tuners->up_threshold = input;
+       return count;
+@@ -525,8 +504,6 @@ static int od_init(struct dbs_data *dbs_data)
+       if (idle_time != -1ULL) {
+               /* Idle micro accounting is supported. Use finer thresholds */
+               tuners->up_threshold = MICRO_FREQUENCY_UP_THRESHOLD;
+-              tuners->adj_up_threshold = MICRO_FREQUENCY_UP_THRESHOLD -
+-                      MICRO_FREQUENCY_DOWN_DIFFERENTIAL;
+               /*
+                * In nohz/micro accounting case we set the minimum frequency
+                * not depending on HZ, but fixed (very low). The deferred
+@@ -535,8 +512,6 @@ static int od_init(struct dbs_data *dbs_data)
+               dbs_data->min_sampling_rate = MICRO_FREQUENCY_MIN_SAMPLE_RATE;
+       } else {
+               tuners->up_threshold = DEF_FREQUENCY_UP_THRESHOLD;
+-              tuners->adj_up_threshold = DEF_FREQUENCY_UP_THRESHOLD -
+-                      DEF_FREQUENCY_DOWN_DIFFERENTIAL;
+               /* For correct statistics, we need 10 ticks for each measure */
+               dbs_data->min_sampling_rate = MIN_SAMPLING_RATE_RATIO *
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1240-cpufreq-dts-trats2-Remove-redundant-definitions-of-c.patch b/patches.tizen/1240-cpufreq-dts-trats2-Remove-redundant-definitions-of-c.patch
new file mode 100644 (file)
index 0000000..49b3d1c
--- /dev/null
@@ -0,0 +1,46 @@
+From 040dee1bb9c2ed8a6fa458e0eb8d10b7f941ed63 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Wed, 19 Feb 2014 12:56:13 +0100
+Subject: [PATCH 1240/1302] cpufreq: dts: trats2: Remove redundant definitions
+ of cpufreq node
+
+After the dts cleanup the cpufreq nodes were duplicated for trats2.
+As a result the trats2 had freq_table definition corresponding to
+SLP_PQ (Proxima PQ) target.
+
+Change-Id: I63a7f627c448caa163df5e915b91cd0979da468e
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-trats2.dts | 8 +-------
+ 1 file changed, 1 insertion(+), 7 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts
+index 208e15f..4f2683c 100644
+--- a/arch/arm/boot/dts/exynos4412-trats2.dts
++++ b/arch/arm/boot/dts/exynos4412-trats2.dts
+@@ -282,12 +282,6 @@
+               };
+       };
+-      cpufreq {
+-              freq_table = <1400000 1300000 1200000 1100000 1000000
+-                           900000 800000 700000 600000 500000 400000 300000
+-                           200000>;
+-      };
+-
+       thermistor-ap@0 {
+               compatible = "ntc,ncp03wb473";
+               status = "ok";
+@@ -1351,7 +1345,7 @@
+       };
+       cpufreq {
+-              freq_table = <0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 1100000 1000000
++              freq_table = <1400000 1300000 1200000 1100000 1000000
+                            900000 800000 700000 600000 500000 400000 300000
+                            200000>;
+               vdd_arm-supply = <&buck2_reg>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1241-boost-dts-trats2-Define-boost_freq-attribute-for-cpu.patch b/patches.tizen/1241-boost-dts-trats2-Define-boost_freq-attribute-for-cpu.patch
new file mode 100644 (file)
index 0000000..46bbda2
--- /dev/null
@@ -0,0 +1,31 @@
+From 6c59e76d9af6d8a7a5ac6c6f5544530dc345737a Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Wed, 19 Feb 2014 13:02:58 +0100
+Subject: [PATCH 1241/1302] boost: dts: trats2: Define boost_freq attribute for
+ cpufreq node
+
+This commit explicitly enables the boost frequency support for Exynos4412
+based Trats2 board.
+
+Change-Id: Ie51ad5c5d983578c33ede442d3f9d67ee9dfb4f7
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-trats2.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts
+index 4f2683c..7068328 100644
+--- a/arch/arm/boot/dts/exynos4412-trats2.dts
++++ b/arch/arm/boot/dts/exynos4412-trats2.dts
+@@ -1348,6 +1348,7 @@
+               freq_table = <1400000 1300000 1200000 1100000 1000000
+                            900000 800000 700000 600000 500000 400000 300000
+                            200000>;
++              boost_freq = <1500000>;
+               vdd_arm-supply = <&buck2_reg>;
+               status = "okay";
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1242-cpufreq-conservative-Provide-correct-pointer-for-con.patch b/patches.tizen/1242-cpufreq-conservative-Provide-correct-pointer-for-con.patch
new file mode 100644 (file)
index 0000000..0b8371c
--- /dev/null
@@ -0,0 +1,41 @@
+From 140eb39b9b6630a667f14aa50601b607a5fc25a4 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Fri, 21 Feb 2014 17:42:57 +0100
+Subject: [PATCH 1242/1302] cpufreq: conservative: Provide correct pointer for
+ conservative governor
+
+This patch restores correct value of cs_dbs_info pointer for conservative
+governor at CPUFREQ_GOV_STOP event.
+
+Without this patch the NULL pointer dereference error shows up and cpufreq
+subsystem hangs.
+To trigger the behavior one needs to compile ondemand as default one. Then
+enable conservative governor and afterwards enable ondemand again.
+
+Change-Id: Iefd933f5984abb1a46d15357b9ea5f8492deeb08
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/cpufreq_governor.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
+index dabb888..a393e2a 100644
+--- a/drivers/cpufreq/cpufreq_governor.c
++++ b/drivers/cpufreq/cpufreq_governor.c
+@@ -409,9 +409,10 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
+               break;
+       case CPUFREQ_GOV_STOP:
+-              if (governor == GOV_CONSERVATIVE)
++              if (governor == GOV_CONSERVATIVE) {
++                      cs_dbs_info = dbs_data->cdata->get_cpu_dbs_info_s(cpu);
+                       cs_dbs_info->enable = 0;
+-
++              }
+               gov_cancel_work(dbs_data, policy);
+               mutex_lock(&dbs_data->mutex);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1243-dts-odroid-x2-add-support-for-multimedia-blocks.patch b/patches.tizen/1243-dts-odroid-x2-add-support-for-multimedia-blocks.patch
new file mode 100644 (file)
index 0000000..1c403f4
--- /dev/null
@@ -0,0 +1,88 @@
+From 0daeffbd599f6770a98797a68e4ab532886c12d7 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Tue, 18 Feb 2014 09:07:33 +0100
+Subject: [PATCH 1243/1302] dts: odroid x2: add support for multimedia blocks
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-id: I7332d504ad79e866ee5e12cca09f8da3416101d5
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-odroidx2.dts | 54 +++++++++++++++++++++++++++++--
+ 1 file changed, 52 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-odroidx2.dts b/arch/arm/boot/dts/exynos4412-odroidx2.dts
+index c522ee6..814f943 100644
+--- a/arch/arm/boot/dts/exynos4412-odroidx2.dts
++++ b/arch/arm/boot/dts/exynos4412-odroidx2.dts
+@@ -23,6 +23,27 @@
+                       0x50000000 0x10000000
+                       0x60000000 0x10000000
+                       0x70000000 0x10000000>;
++
++              reserved-memory {
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      contig_mem: region@0 {
++                              compatible = "linux,contiguous-memory-region";
++                              reg = <0x0 0x4000000>;
++                              linux,default-contiguous-region;
++                      };
++
++                      mfc_l_mem: mfc_l_region@43000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x43000000 0x1000000>;
++                      };
++
++                      mfc_r_mem: mfc_r_region@51000000 {
++                              compatible = "linux,contiguous-memory-region", "reserved-memory-region";
++                              reg = <0x51000000 0x1000000>;
++                      };
++              };
+       };
+       chosen {
+@@ -452,9 +473,38 @@
+               status = "okay";
+       };
++      camera {
++              status = "okay";
++
++              pinctrl-names = "default";
++              pinctrl-0 = <&cam_port_a_clk_idle>;
++
++              fimc_0: fimc@11800000 {
++                      status = "okay";
++              };
++
++              fimc_1: fimc@11810000 {
++                      status = "okay";
++              };
++
++              fimc_2: fimc@11820000 {
++                      status = "okay";
++              };
++
++              fimc_3: fimc@11830000 {
++                      status = "okay";
++              };
++      };
++
+       mfc: codec@13400000 {
+               status = "okay";
+-              samsung,mfc-r = <0x43000000 0x800000>;
+-              samsung,mfc-l = <0x51000000 0x800000>;
++
++              memport@0 {
++                      memory-region = <&mfc_l_mem>;
++              };
++
++              memport@1 {
++                      memory-region = <&mfc_r_mem>;
++              };
+       };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1244-arm-dts-exynos4412-odroidx2-add-HDMI-devices.patch b/patches.tizen/1244-arm-dts-exynos4412-odroidx2-add-HDMI-devices.patch
new file mode 100644 (file)
index 0000000..927a193
--- /dev/null
@@ -0,0 +1,88 @@
+From cdc86f29775b57b2e00daad4e4846cdc56c20d67 Mon Sep 17 00:00:00 2001
+From: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Date: Thu, 20 Feb 2014 15:47:44 +0100
+Subject: [PATCH 1244/1302] arm: dts: exynos4412-odroidx2: add HDMI devices
+
+This patch adds configuration of HDMI devices on OdroidX2 board.
+Moreover, FIMD is enabled as workaround for ia bug caused by
+unintialized size of framebuffer.
+
+Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
+Change-Id: I8fa76980f35644f886ffc971a4ced1ae03300d12
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-odroidx2.dts | 60 +++++++++++++++++++++++++++++++
+ 1 file changed, 60 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-odroidx2.dts b/arch/arm/boot/dts/exynos4412-odroidx2.dts
+index 814f943..9ce1768 100644
+--- a/arch/arm/boot/dts/exynos4412-odroidx2.dts
++++ b/arch/arm/boot/dts/exynos4412-odroidx2.dts
+@@ -507,4 +507,64 @@
+                       memory-region = <&mfc_r_mem>;
+               };
+       };
++
++      i2c@13880000 {
++              pinctrl-names = "default";
++              pinctrl-0 = <&i2c2_bus>;
++              status = "okay";
++              hdmiddc@37 {
++                      compatible = "samsung,exynos5-hdmiddc";
++                      reg = <0x37>;
++              };
++      };
++
++      hdmi@12D00000 {
++              hpd-gpio = <&gpx3 7 0>;
++              pinctrl-names = "default";
++              pinctrl-0 = <&hdmi_hpd>;
++              /*
++               * HDMI_EN is a dummy regulator on Origen.
++               * Therefore LDO8 is used instead because
++               * it is enabled at the same time as hdmi-en
++               */
++              hdmi-en-supply = <&ldo8_reg>;
++              vdd-supply = <&ldo8_reg>;
++              vdd_osc-supply = <&ldo10_reg>;
++              vdd_pll-supply = <&ldo8_reg>;
++              status = "okay";
++      };
++
++      /*
++       * FIMD node is required for DRM subsystem to initialize framebuffer
++       * It should be considered as hack until DRM/HDMI subsystem is fixed
++       */
++      fimd@11c00000 {
++              samsung,fimd-vidout-rgb;
++              samsung,fimd-inv-vclk;
++              samsung,fimd-frame-rate = <60>;
++              samsung,default-window = <3>;
++              samsung,fimd-win-bpp = <32>;
++              status = "okay";
++              display-timings {
++                      native-mode = <&timing0>;
++                      timing0: timing {
++                              clock-frequency = <0>;
++                              hfront-porch = <0>;
++                              hback-porch = <0>;
++                              hactive = <1920>;
++                              vactive = <1080>;
++                              hsync-len = <0>;
++                              vback-porch = <0>;
++                              vfront-porch = <0>;
++                              vsync-len = <0>;
++                      };
++              };
++      };
++};
++
++&pinctrl_1 {
++      hdmi_hpd: hdmi-hpd {
++              samsung,pins = "gpx3-7";
++              samsung,pin-pud = <1>;
++      };
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1245-ARM-defconfig-Add-tizen_odroidx2_defconfig.patch b/patches.tizen/1245-ARM-defconfig-Add-tizen_odroidx2_defconfig.patch
new file mode 100644 (file)
index 0000000..8b07b51
--- /dev/null
@@ -0,0 +1,2684 @@
+From 3ebbb5c16c676cbf0237d98470d40cef4caa1ad3 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Mon, 24 Feb 2014 12:40:02 +0100
+Subject: [PATCH 1245/1302] ARM: defconfig: Add tizen_odroidx2_defconfig
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-Id: Ic1fb103c9620aedc1bfee0de5906f58d437db19c
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_odroidx2_defconfig | 2662 +++++++++++++++++++++++++++++
+ 1 file changed, 2662 insertions(+)
+ create mode 100644 arch/arm/configs/tizen_odroidx2_defconfig
+
+diff --git a/arch/arm/configs/tizen_odroidx2_defconfig b/arch/arm/configs/tizen_odroidx2_defconfig
+new file mode 100644
+index 0000000..d209f19
+--- /dev/null
++++ b/arch/arm/configs/tizen_odroidx2_defconfig
+@@ -0,0 +1,2662 @@
++#
++# Automatically generated file; DO NOT EDIT.
++# Linux/arm 3.10.19 Kernel Configuration
++#
++CONFIG_ARM=y
++CONFIG_ARM_HAS_SG_CHAIN=y
++CONFIG_NEED_SG_DMA_LENGTH=y
++CONFIG_ARM_DMA_USE_IOMMU=y
++CONFIG_ARM_DMA_IOMMU_ALIGNMENT=8
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_HAVE_PROC_CPU=y
++CONFIG_NO_IOPORT=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++CONFIG_ARCH_HAS_CPUFREQ=y
++CONFIG_ARCH_HAS_BANDGAP=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_NEED_DMA_MAP_STATE=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_ARM_PATCH_PHYS_VIRT=y
++CONFIG_NEED_MACH_GPIO_H=y
++CONFIG_NEED_MACH_MEMORY_H=y
++CONFIG_GENERIC_BUG=y
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++CONFIG_IRQ_WORK=y
++CONFIG_BUILDTIME_EXTABLE_SORT=y
++
++#
++# General setup
++#
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_CROSS_COMPILE=""
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_HAVE_KERNEL_GZIP=y
++CONFIG_HAVE_KERNEL_LZMA=y
++CONFIG_HAVE_KERNEL_XZ=y
++CONFIG_HAVE_KERNEL_LZO=y
++CONFIG_KERNEL_GZIP=y
++# CONFIG_KERNEL_LZMA is not set
++# CONFIG_KERNEL_XZ is not set
++# CONFIG_KERNEL_LZO is not set
++CONFIG_DEFAULT_HOSTNAME="(none)"
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_FHANDLE is not set
++# CONFIG_AUDIT is not set
++CONFIG_HAVE_GENERIC_HARDIRQS=y
++
++#
++# IRQ subsystem
++#
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_GENERIC_IRQ_SHOW=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_CHIP=y
++CONFIG_IRQ_DOMAIN=y
++# CONFIG_IRQ_DOMAIN_DEBUG is not set
++CONFIG_KTIME_SCALAR=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++CONFIG_ARCH_HAS_TICK_BROADCAST=y
++CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
++
++#
++# Timers subsystem
++#
++CONFIG_TICK_ONESHOT=y
++CONFIG_NO_HZ_COMMON=y
++# CONFIG_HZ_PERIODIC is not set
++CONFIG_NO_HZ_IDLE=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
++
++#
++# CPU/Task time and stats accounting
++#
++CONFIG_TICK_CPU_ACCOUNTING=y
++# CONFIG_IRQ_TIME_ACCOUNTING is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++
++#
++# RCU Subsystem
++#
++CONFIG_TREE_PREEMPT_RCU=y
++CONFIG_PREEMPT_RCU=y
++CONFIG_RCU_STALL_COMMON=y
++# CONFIG_RCU_USER_QS is not set
++CONFIG_RCU_FANOUT=32
++CONFIG_RCU_FANOUT_LEAF=16
++# CONFIG_RCU_FANOUT_EXACT is not set
++# CONFIG_RCU_FAST_NO_HZ is not set
++# CONFIG_TREE_RCU_TRACE is not set
++# CONFIG_RCU_BOOST is not set
++# CONFIG_RCU_NOCB_CPU is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=17
++# CONFIG_CGROUPS is not set
++# CONFIG_CHECKPOINT_RESTORE is not set
++CONFIG_NAMESPACES=y
++CONFIG_UTS_NS=y
++CONFIG_IPC_NS=y
++# CONFIG_USER_NS is not set
++CONFIG_PID_NS=y
++CONFIG_NET_NS=y
++CONFIG_UIDGID_CONVERTED=y
++# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
++# CONFIG_SCHED_AUTOGROUP is not set
++# CONFIG_SYSFS_DEPRECATED is not set
++# CONFIG_RELAY is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_RD_GZIP=y
++CONFIG_RD_BZIP2=y
++CONFIG_RD_LZMA=y
++CONFIG_RD_XZ=y
++CONFIG_RD_LZO=y
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++CONFIG_HAVE_UID16=y
++CONFIG_HOTPLUG=y
++# CONFIG_EXPERT is not set
++CONFIG_UID16=y
++# CONFIG_SYSCTL_SYSCALL is not set
++CONFIG_KALLSYMS=y
++CONFIG_KALLSYMS_ALL=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++# CONFIG_EMBEDDED is not set
++CONFIG_HAVE_PERF_EVENTS=y
++CONFIG_PERF_USE_VMALLOC=y
++
++#
++# Kernel Performance Events And Counters
++#
++# CONFIG_PERF_EVENTS is not set
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++CONFIG_COMPAT_BRK=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_PROFILING is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++# CONFIG_JUMP_LABEL is not set
++# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_ARCH_TRACEHOOK=y
++CONFIG_HAVE_DMA_ATTRS=y
++CONFIG_HAVE_DMA_CONTIGUOUS=y
++CONFIG_USE_GENERIC_SMP_HELPERS=y
++CONFIG_GENERIC_SMP_IDLE_THREAD=y
++CONFIG_GENERIC_IDLE_POLL_SETUP=y
++CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
++CONFIG_HAVE_CLK=y
++CONFIG_HAVE_DMA_API_DEBUG=y
++CONFIG_HAVE_ARCH_JUMP_LABEL=y
++CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
++CONFIG_HAVE_CONTEXT_TRACKING=y
++CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
++CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
++CONFIG_MODULES_USE_ELF_REL=y
++CONFIG_CLONE_BACKWARDS=y
++CONFIG_OLD_SIGSUSPEND3=y
++CONFIG_OLD_SIGACTION=y
++
++#
++# GCOV-based kernel profiling
++#
++# CONFIG_GCOV_KERNEL is not set
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++# CONFIG_MODULE_SIG is not set
++CONFIG_STOP_MACHINE=y
++CONFIG_BLOCK=y
++CONFIG_LBDAF=y
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_BSGLIB is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# Partition Types
++#
++CONFIG_PARTITION_ADVANCED=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++# CONFIG_MAC_PARTITION is not set
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++# CONFIG_LDM_PARTITION is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++CONFIG_EFI_PARTITION=y
++# CONFIG_SYSV68_PARTITION is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_UNINLINE_SPIN_UNLOCK=y
++CONFIG_FREEZER=y
++
++#
++# System Type
++#
++CONFIG_MMU=y
++# CONFIG_ARCH_MULTIPLATFORM is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_GEMINI is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_DOVE is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_MMP is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_W90X900 is not set
++# CONFIG_ARCH_LPC32XX is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_MSM is not set
++# CONFIG_ARCH_SHMOBILE is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C24XX is not set
++# CONFIG_ARCH_S3C64XX is not set
++# CONFIG_ARCH_S5P64X0 is not set
++# CONFIG_ARCH_S5PC100 is not set
++# CONFIG_ARCH_S5PV210 is not set
++CONFIG_ARCH_EXYNOS=y
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_U300 is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP1 is not set
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_KEYBOARD_GPIO_POLLED is not set
++CONFIG_PLAT_SAMSUNG=y
++CONFIG_PLAT_S5P=y
++
++#
++# Boot options
++#
++# CONFIG_S3C_BOOT_ERROR_RESET is not set
++CONFIG_S3C_BOOT_UART_FORCE_FIFO=y
++CONFIG_S3C_LOWLEVEL_UART_PORT=1
++# CONFIG_S5P_CLOCK is not set
++CONFIG_SAMSUNG_IRQ_VIC_TIMER=y
++# CONFIG_S5P_IRQ is not set
++CONFIG_SAMSUNG_GPIOLIB_4BIT=y
++CONFIG_S5P_GPIO_DRVSTR=y
++CONFIG_SAMSUNG_GPIO_EXTRA=16
++CONFIG_S3C_GPIO_SPACE=0
++CONFIG_S3C_GPIO_TRACK=y
++# CONFIG_S3C_ADC is not set
++CONFIG_S5P_DEV_MFC=y
++# CONFIG_S3C24XX_PWM is not set
++CONFIG_SAMSUNG_DMADEV=y
++
++#
++# Power management
++#
++# CONFIG_SAMSUNG_PM_DEBUG is not set
++# CONFIG_SAMSUNG_PM_CHECK is not set
++CONFIG_S5P_PM=y
++CONFIG_S5P_SLEEP=y
++CONFIG_DEBUG_S3C_UART=1
++# CONFIG_PLAT_SPEAR is not set
++
++#
++# SAMSUNG EXYNOS SoCs Support
++#
++CONFIG_ARCH_EXYNOS4=y
++# CONFIG_ARCH_EXYNOS5 is not set
++
++#
++# EXYNOS SoCs
++#
++CONFIG_CPU_EXYNOS4210=y
++CONFIG_SOC_EXYNOS4212=y
++CONFIG_SOC_EXYNOS4412=y
++CONFIG_EXYNOS_ATAGS=y
++# CONFIG_SEC_DEBUG is not set
++
++#
++# EXYNOS4210 Boards
++#
++# CONFIG_MACH_SMDKC210 is not set
++# CONFIG_MACH_SMDKV310 is not set
++# CONFIG_MACH_ARMLEX4210 is not set
++# CONFIG_MACH_UNIVERSAL_C210 is not set
++# CONFIG_MACH_NURI is not set
++# CONFIG_MACH_ORIGEN is not set
++
++#
++# EXYNOS4212 Boards
++#
++# CONFIG_MACH_SMDK4212 is not set
++
++#
++# EXYNOS4412 Boards
++#
++# CONFIG_MACH_SMDK4412 is not set
++
++#
++# Flattened Device Tree based board for EXYNOS SoCs
++#
++CONFIG_MACH_EXYNOS4_DT=y
++
++#
++# Configuration for HSMMC 8-bit bus width
++#
++# CONFIG_EXYNOS4_SDHCI_CH0_8BIT is not set
++# CONFIG_EXYNOS4_SDHCI_CH2_8BIT is not set
++
++#
++# Processor Type
++#
++CONFIG_CPU_V7=y
++CONFIG_CPU_32v6K=y
++CONFIG_CPU_32v7=y
++CONFIG_CPU_ABRT_EV7=y
++CONFIG_CPU_PABRT_V7=y
++CONFIG_CPU_CACHE_V7=y
++CONFIG_CPU_CACHE_VIPT=y
++CONFIG_CPU_COPY_V6=y
++CONFIG_CPU_TLB_V7=y
++CONFIG_CPU_HAS_ASID=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++# CONFIG_ARM_LPAE is not set
++# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
++CONFIG_ARM_THUMB=y
++# CONFIG_ARM_THUMBEE is not set
++CONFIG_ARM_VIRT_EXT=y
++CONFIG_SWP_EMULATE=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_BPREDICT_DISABLE is not set
++CONFIG_KUSER_HELPERS=y
++CONFIG_MIGHT_HAVE_CACHE_L2X0=y
++# CONFIG_CACHE_L2X0 is not set
++CONFIG_ARM_L1_CACHE_SHIFT_6=y
++CONFIG_ARM_L1_CACHE_SHIFT=6
++CONFIG_ARM_DMA_MEM_BUFFERABLE=y
++CONFIG_ARM_NR_BANKS=8
++CONFIG_MULTI_IRQ_HANDLER=y
++# CONFIG_ARM_ERRATA_430973 is not set
++# CONFIG_ARM_ERRATA_458693 is not set
++# CONFIG_ARM_ERRATA_460075 is not set
++# CONFIG_ARM_ERRATA_742230 is not set
++# CONFIG_ARM_ERRATA_742231 is not set
++# CONFIG_ARM_ERRATA_643719 is not set
++# CONFIG_ARM_ERRATA_720789 is not set
++# CONFIG_ARM_ERRATA_743622 is not set
++# CONFIG_ARM_ERRATA_751472 is not set
++# CONFIG_ARM_ERRATA_754322 is not set
++# CONFIG_ARM_ERRATA_754327 is not set
++# CONFIG_ARM_ERRATA_764369 is not set
++# CONFIG_ARM_ERRATA_775420 is not set
++# CONFIG_ARM_ERRATA_798181 is not set
++
++#
++# Bus support
++#
++CONFIG_ARM_AMBA=y
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_HAVE_SMP=y
++CONFIG_SMP=y
++CONFIG_SMP_ON_UP=y
++CONFIG_ARM_CPU_TOPOLOGY=y
++# CONFIG_SCHED_MC is not set
++# CONFIG_SCHED_SMT is not set
++CONFIG_HAVE_ARM_SCU=y
++CONFIG_HAVE_ARM_ARCH_TIMER=y
++# CONFIG_MCPM is not set
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
++CONFIG_NR_CPUS=2
++CONFIG_HOTPLUG_CPU=y
++# CONFIG_ARM_PSCI is not set
++CONFIG_LOCAL_TIMERS=y
++CONFIG_ARCH_NR_GPIO=0
++# CONFIG_PREEMPT_NONE is not set
++# CONFIG_PREEMPT_VOLUNTARY is not set
++CONFIG_PREEMPT=y
++CONFIG_PREEMPT_COUNT=y
++CONFIG_HZ=200
++CONFIG_SCHED_HRTICK=y
++# CONFIG_THUMB2_KERNEL is not set
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y
++CONFIG_ARCH_SPARSEMEM_ENABLE=y
++CONFIG_ARCH_SPARSEMEM_DEFAULT=y
++CONFIG_ARCH_SELECT_MEMORY_MODEL=y
++CONFIG_HAVE_ARCH_PFN_VALID=y
++CONFIG_HIGHMEM=y
++# CONFIG_HIGHPTE is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_SPARSEMEM_MANUAL=y
++CONFIG_SPARSEMEM=y
++CONFIG_HAVE_MEMORY_PRESENT=y
++CONFIG_SPARSEMEM_EXTREME=y
++CONFIG_HAVE_MEMBLOCK=y
++CONFIG_MEMORY_ISOLATION=y
++# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=999999
++CONFIG_COMPACTION=y
++CONFIG_MIGRATION=y
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_BOUNCE=y
++# CONFIG_KSM is not set
++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
++CONFIG_CROSS_MEMORY_ATTACH=y
++# CONFIG_CLEANCACHE is not set
++# CONFIG_FRONTSWAP is not set
++# CONFIG_ZBUD is not set
++CONFIG_FORCE_MAX_ZONEORDER=11
++CONFIG_ALIGNMENT_TRAP=y
++# CONFIG_UACCESS_WITH_MEMCPY is not set
++# CONFIG_SECCOMP is not set
++# CONFIG_CC_STACKPROTECTOR is not set
++# CONFIG_XEN is not set
++
++#
++# Boot options
++#
++CONFIG_USE_OF=y
++CONFIG_ATAGS=y
++# CONFIG_DEPRECATED_PARAM_STRUCT is not set
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_ARM_APPENDED_DTB=y
++CONFIG_ARM_ATAG_DTB_COMPAT=y
++CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y
++# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set
++CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc mem=256M"
++CONFIG_CMDLINE_FROM_BOOTLOADER=y
++# CONFIG_CMDLINE_EXTEND is not set
++# CONFIG_CMDLINE_FORCE is not set
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++# CONFIG_CRASH_DUMP is not set
++CONFIG_AUTO_ZRELADDR=y
++
++#
++# CPU Power Management
++#
++
++#
++# CPU Frequency scaling
++#
++# CONFIG_CPU_FREQ is not set
++# CONFIG_CPU_IDLE is not set
++# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++# CONFIG_FPE_NWFPE is not set
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_VFP=y
++CONFIG_VFPv3=y
++CONFIG_NEON=y
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
++CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
++CONFIG_BINFMT_SCRIPT=y
++# CONFIG_HAVE_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++CONFIG_COREDUMP=y
++
++#
++# Power management options
++#
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++CONFIG_PM_SLEEP=y
++CONFIG_PM_SLEEP_SMP=y
++# CONFIG_PM_AUTOSLEEP is not set
++# CONFIG_PM_WAKELOCKS is not set
++CONFIG_PM_RUNTIME=y
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++# CONFIG_APM_EMULATION is not set
++CONFIG_PM_CLK=y
++CONFIG_PM_GENERIC_DOMAINS=y
++CONFIG_PM_GENERIC_DOMAINS_SLEEP=y
++CONFIG_PM_GENERIC_DOMAINS_RUNTIME=y
++CONFIG_CPU_PM=y
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_ARM_CPU_SUSPEND=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_DIAG is not set
++CONFIG_UNIX=y
++# CONFIG_UNIX_DIAG is not set
++CONFIG_XFRM=y
++CONFIG_XFRM_ALGO=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++CONFIG_NET_KEY=y
++# CONFIG_NET_KEY_MIGRATE is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++# CONFIG_IP_PNP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE_DEMUX is not set
++CONFIG_NET_IP_TUNNEL=m
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_NET_IPVTI is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++CONFIG_INET_TUNNEL=m
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++CONFIG_INET_LRO=y
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_INET_UDP_DIAG is not set
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++CONFIG_IPV6=m
++# CONFIG_IPV6_PRIVACY is not set
++# CONFIG_IPV6_ROUTER_PREF is not set
++# CONFIG_IPV6_OPTIMISTIC_DAD is not set
++# CONFIG_INET6_AH is not set
++# CONFIG_INET6_ESP is not set
++# CONFIG_INET6_IPCOMP is not set
++# CONFIG_IPV6_MIP6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++CONFIG_INET6_XFRM_MODE_TRANSPORT=m
++CONFIG_INET6_XFRM_MODE_TUNNEL=m
++CONFIG_INET6_XFRM_MODE_BEET=m
++# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
++CONFIG_IPV6_SIT=m
++# CONFIG_IPV6_SIT_6RD is not set
++CONFIG_IPV6_NDISC_NODETYPE=y
++# CONFIG_IPV6_TUNNEL is not set
++# CONFIG_IPV6_GRE is not set
++# CONFIG_IPV6_MULTIPLE_TABLES is not set
++# CONFIG_IPV6_MROUTE is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_RDS is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_L2TP is not set
++# CONFIG_BRIDGE is not set
++CONFIG_HAVE_NET_DSA=y
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_PHONET is not set
++# CONFIG_IEEE802154 is not set
++# CONFIG_NET_SCHED is not set
++# CONFIG_DCB is not set
++# CONFIG_BATMAN_ADV is not set
++# CONFIG_OPENVSWITCH is not set
++# CONFIG_VSOCKETS is not set
++# CONFIG_NETLINK_MMAP is not set
++# CONFIG_NETLINK_DIAG is not set
++CONFIG_RPS=y
++CONFIG_RFS_ACCEL=y
++CONFIG_XPS=y
++CONFIG_BQL=y
++# CONFIG_BPF_JIT is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++CONFIG_WIRELESS=y
++# CONFIG_CFG80211 is not set
++# CONFIG_LIB80211 is not set
++
++#
++# CFG80211 needs to be enabled for MAC80211
++#
++# CONFIG_WIMAX is not set
++# CONFIG_RFKILL is not set
++CONFIG_RFKILL_REGULATOR=y
++# CONFIG_NET_9P is not set
++# CONFIG_CAIF is not set
++# CONFIG_CEPH_LIB is not set
++# CONFIG_NFC is not set
++CONFIG_HAVE_BPF_JIT=y
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_DEVTMPFS=y
++CONFIG_DEVTMPFS_MOUNT=y
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
++CONFIG_FW_LOADER_USER_HELPER=y
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_DEBUG_DEVRES is not set
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_GENERIC_CPU_DEVICES is not set
++CONFIG_REGMAP=y
++CONFIG_REGMAP_I2C=y
++CONFIG_REGMAP_MMIO=y
++CONFIG_REGMAP_IRQ=y
++CONFIG_DMA_SHARED_BUFFER=y
++# CONFIG_DMABUF_SYNC is not set
++CONFIG_CMA=y
++CONFIG_CMA_DEBUG=y
++
++#
++# Default contiguous memory area size:
++#
++CONFIG_CMA_SIZE_MBYTES=16
++CONFIG_CMA_SIZE_SEL_MBYTES=y
++# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
++# CONFIG_CMA_SIZE_SEL_MIN is not set
++# CONFIG_CMA_SIZE_SEL_MAX is not set
++CONFIG_CMA_ALIGNMENT=8
++CONFIG_CMA_AREAS=7
++
++#
++# Bus devices
++#
++# CONFIG_CONNECTOR is not set
++# CONFIG_MTD is not set
++CONFIG_DTC=y
++CONFIG_OF=y
++
++#
++# Device Tree and Open Firmware support
++#
++CONFIG_PROC_DEVICETREE=y
++# CONFIG_OF_SELFTEST is not set
++CONFIG_OF_FLATTREE=y
++CONFIG_OF_EARLY_FLATTREE=y
++CONFIG_OF_ADDRESS=y
++CONFIG_OF_IRQ=y
++CONFIG_OF_DEVICE=y
++CONFIG_OF_I2C=y
++CONFIG_OF_NET=y
++CONFIG_OF_MDIO=y
++CONFIG_OF_RESERVED_MEM=y
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
++CONFIG_BLK_DEV_CRYPTOLOOP=y
++# CONFIG_BLK_DEV_DRBD is not set
++# CONFIG_BLK_DEV_NBD is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=8192
++# CONFIG_BLK_DEV_XIP is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_MG_DISK is not set
++# CONFIG_BLK_DEV_RBD is not set
++
++#
++# Misc devices
++#
++# CONFIG_SENSORS_LIS3LV02D is not set
++# CONFIG_AD525X_DPOT is not set
++# CONFIG_ATMEL_PWM is not set
++# CONFIG_DUMMY_IRQ is not set
++# CONFIG_ICS932S401 is not set
++# CONFIG_ATMEL_SSC is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_APDS9802ALS is not set
++# CONFIG_ISL29003 is not set
++# CONFIG_ISL29020 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_SENSORS_BH1780 is not set
++# CONFIG_SENSORS_BH1770 is not set
++# CONFIG_SENSORS_APDS990X is not set
++# CONFIG_HMC6352 is not set
++# CONFIG_DS1682 is not set
++# CONFIG_TI_DAC7512 is not set
++# CONFIG_BMP085_I2C is not set
++# CONFIG_BMP085_SPI is not set
++# CONFIG_USB_SWITCH_FSA9480 is not set
++# CONFIG_LATTICE_ECP3_CONFIG is not set
++# CONFIG_SLP_GLOBAL_LOCK is not set
++# CONFIG_SRAM is not set
++# CONFIG_SII9234 is not set
++# CONFIG_C2PORT is not set
++
++#
++# EEPROM support
++#
++# CONFIG_EEPROM_AT24 is not set
++# CONFIG_EEPROM_AT25 is not set
++# CONFIG_EEPROM_LEGACY is not set
++# CONFIG_EEPROM_MAX6875 is not set
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_EEPROM_93XX46 is not set
++
++#
++# Texas Instruments shared transport line discipline
++#
++# CONFIG_TI_ST is not set
++# CONFIG_SENSORS_LIS3_SPI is not set
++# CONFIG_SENSORS_LIS3_I2C is not set
++
++#
++# Altera FPGA firmware download module
++#
++# CONFIG_ALTERA_STAPL is not set
++# CONFIG_SEC_MODEM is not set
++
++#
++# SCSI device support
++#
++CONFIG_SCSI_MOD=y
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++# CONFIG_SCSI_TGT is not set
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_ISCSI_BOOT_SYSFS is not set
++# CONFIG_SCSI_UFSHCD is not set
++# CONFIG_LIBFC is not set
++# CONFIG_LIBFCOE is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_SCSI_OSD_INITIATOR is not set
++# CONFIG_ATA is not set
++CONFIG_MD=y
++# CONFIG_BLK_DEV_MD is not set
++# CONFIG_BCACHE is not set
++CONFIG_BLK_DEV_DM=y
++# CONFIG_DM_DEBUG is not set
++CONFIG_DM_CRYPT=m
++# CONFIG_DM_SNAPSHOT is not set
++# CONFIG_DM_THIN_PROVISIONING is not set
++# CONFIG_DM_CACHE is not set
++# CONFIG_DM_MIRROR is not set
++# CONFIG_DM_RAID is not set
++# CONFIG_DM_ZERO is not set
++# CONFIG_DM_MULTIPATH is not set
++# CONFIG_DM_DELAY is not set
++# CONFIG_DM_UEVENT is not set
++# CONFIG_DM_FLAKEY is not set
++# CONFIG_DM_VERITY is not set
++# CONFIG_TARGET_CORE is not set
++CONFIG_NETDEVICES=y
++CONFIG_NET_CORE=y
++# CONFIG_BONDING is not set
++# CONFIG_DUMMY is not set
++# CONFIG_EQUALIZER is not set
++CONFIG_MII=y
++# CONFIG_NET_TEAM is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_VXLAN is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++
++#
++# CAIF transport drivers
++#
++
++#
++# Distributed Switch Architecture drivers
++#
++# CONFIG_NET_DSA_MV88E6XXX is not set
++# CONFIG_NET_DSA_MV88E6060 is not set
++# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
++# CONFIG_NET_DSA_MV88E6131 is not set
++# CONFIG_NET_DSA_MV88E6123_61_65 is not set
++CONFIG_ETHERNET=y
++CONFIG_NET_CADENCE=y
++# CONFIG_ARM_AT91_ETHER is not set
++# CONFIG_MACB is not set
++CONFIG_NET_VENDOR_BROADCOM=y
++# CONFIG_B44 is not set
++# CONFIG_NET_CALXEDA_XGMAC is not set
++CONFIG_NET_VENDOR_CIRRUS=y
++# CONFIG_CS89x0 is not set
++# CONFIG_DM9000 is not set
++# CONFIG_DNET is not set
++CONFIG_NET_VENDOR_FARADAY=y
++# CONFIG_FTMAC100 is not set
++# CONFIG_FTGMAC100 is not set
++CONFIG_NET_VENDOR_INTEL=y
++CONFIG_NET_VENDOR_I825XX=y
++CONFIG_NET_VENDOR_MARVELL=y
++# CONFIG_MVMDIO is not set
++CONFIG_NET_VENDOR_MICREL=y
++# CONFIG_KS8842 is not set
++# CONFIG_KS8851 is not set
++# CONFIG_KS8851_MLL is not set
++CONFIG_NET_VENDOR_MICROCHIP=y
++# CONFIG_ENC28J60 is not set
++CONFIG_NET_VENDOR_NATSEMI=y
++CONFIG_NET_VENDOR_8390=y
++# CONFIG_AX88796 is not set
++# CONFIG_ETHOC is not set
++CONFIG_NET_VENDOR_SEEQ=y
++CONFIG_NET_VENDOR_SMSC=y
++# CONFIG_SMC91X is not set
++# CONFIG_SMC911X is not set
++CONFIG_SMSC911X=y
++# CONFIG_SMSC911X_ARCH_HOOKS is not set
++CONFIG_NET_VENDOR_STMICRO=y
++# CONFIG_STMMAC_ETH is not set
++CONFIG_NET_VENDOR_WIZNET=y
++# CONFIG_WIZNET_W5100 is not set
++# CONFIG_WIZNET_W5300 is not set
++CONFIG_PHYLIB=y
++
++#
++# MII PHY device drivers
++#
++# CONFIG_AT803X_PHY is not set
++# CONFIG_AMD_PHY is not set
++# CONFIG_MARVELL_PHY is not set
++# CONFIG_DAVICOM_PHY is not set
++# CONFIG_QSEMI_PHY is not set
++# CONFIG_LXT_PHY is not set
++# CONFIG_CICADA_PHY is not set
++# CONFIG_VITESSE_PHY is not set
++# CONFIG_SMSC_PHY is not set
++# CONFIG_BROADCOM_PHY is not set
++# CONFIG_BCM87XX_PHY is not set
++# CONFIG_ICPLUS_PHY is not set
++# CONFIG_REALTEK_PHY is not set
++# CONFIG_NATIONAL_PHY is not set
++# CONFIG_STE10XP is not set
++# CONFIG_LSI_ET1011C_PHY is not set
++# CONFIG_MICREL_PHY is not set
++# CONFIG_FIXED_PHY is not set
++# CONFIG_MDIO_BITBANG is not set
++# CONFIG_MDIO_BUS_MUX_GPIO is not set
++# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
++# CONFIG_MICREL_KS8995MA is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_RTL8152 is not set
++CONFIG_USB_USBNET=y
++CONFIG_USB_NET_AX8817X=y
++CONFIG_USB_NET_AX88179_178A=y
++CONFIG_USB_NET_CDCETHER=y
++# CONFIG_USB_NET_CDC_EEM is not set
++CONFIG_USB_NET_CDC_NCM=y
++# CONFIG_USB_NET_CDC_MBIM is not set
++# CONFIG_USB_NET_DM9601 is not set
++CONFIG_USB_NET_SMSC75XX=y
++CONFIG_USB_NET_SMSC95XX=y
++# CONFIG_USB_NET_GL620A is not set
++CONFIG_USB_NET_NET1080=y
++# CONFIG_USB_NET_PLUSB is not set
++# CONFIG_USB_NET_MCS7830 is not set
++# CONFIG_USB_NET_RNDIS_HOST is not set
++CONFIG_USB_NET_CDC_SUBSET=y
++# CONFIG_USB_ALI_M5632 is not set
++# CONFIG_USB_AN2720 is not set
++CONFIG_USB_BELKIN=y
++CONFIG_USB_ARMLINUX=y
++# CONFIG_USB_EPSON2888 is not set
++# CONFIG_USB_KC2190 is not set
++CONFIG_USB_NET_ZAURUS=y
++# CONFIG_USB_NET_CX82310_ETH is not set
++# CONFIG_USB_NET_KALMIA is not set
++# CONFIG_USB_NET_QMI_WWAN is not set
++# CONFIG_USB_NET_INT51X1 is not set
++# CONFIG_USB_IPHETH is not set
++# CONFIG_USB_SIERRA_NET is not set
++# CONFIG_USB_VL600 is not set
++CONFIG_WLAN=y
++# CONFIG_USB_ZD1201 is not set
++# CONFIG_HOSTAP is not set
++# CONFIG_WL_TI is not set
++
++#
++# Enable WiMAX (Networking options) to see the WiMAX drivers
++#
++# CONFIG_WAN is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++# CONFIG_INPUT_SPARSEKMAP is not set
++CONFIG_INPUT_MATRIXKMAP=y
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++# CONFIG_KEYBOARD_ADP5588 is not set
++# CONFIG_KEYBOARD_ADP5589 is not set
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_QT1070 is not set
++# CONFIG_KEYBOARD_QT2160 is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++CONFIG_KEYBOARD_GPIO=y
++# CONFIG_KEYBOARD_TCA6416 is not set
++# CONFIG_KEYBOARD_TCA8418 is not set
++# CONFIG_KEYBOARD_MATRIX is not set
++# CONFIG_KEYBOARD_LM8333 is not set
++# CONFIG_KEYBOARD_MAX7359 is not set
++# CONFIG_KEYBOARD_MCS is not set
++# CONFIG_KEYBOARD_MPR121 is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_OPENCORES is not set
++CONFIG_KEYBOARD_SAMSUNG=y
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++CONFIG_KEYBOARD_CROS_EC=y
++CONFIG_INPUT_MOUSE=y
++# CONFIG_MOUSE_PS2 is not set
++# CONFIG_MOUSE_SERIAL is not set
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_BCM5974 is not set
++CONFIG_MOUSE_CYAPA=y
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_MOUSE_SYNAPTICS_I2C is not set
++# CONFIG_MOUSE_SYNAPTICS_USB is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++# CONFIG_TOUCHSCREEN_ADS7846 is not set
++# CONFIG_TOUCHSCREEN_AD7877 is not set
++# CONFIG_TOUCHSCREEN_AD7879 is not set
++# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set
++# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set
++# CONFIG_TOUCHSCREEN_BU21013 is not set
++# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set
++# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set
++# CONFIG_TOUCHSCREEN_DYNAPRO is not set
++# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
++# CONFIG_TOUCHSCREEN_EETI is not set
++# CONFIG_TOUCHSCREEN_EGALAX is not set
++# CONFIG_TOUCHSCREEN_FUJITSU is not set
++# CONFIG_TOUCHSCREEN_ILI210X is not set
++# CONFIG_TOUCHSCREEN_GUNZE is not set
++# CONFIG_TOUCHSCREEN_ELO is not set
++# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
++# CONFIG_TOUCHSCREEN_WACOM_I2C is not set
++# CONFIG_TOUCHSCREEN_MAX11801 is not set
++# CONFIG_TOUCHSCREEN_MCS5000 is not set
++CONFIG_TOUCHSCREEN_MMS114=y
++# CONFIG_TOUCHSCREEN_MTOUCH is not set
++# CONFIG_TOUCHSCREEN_INEXIO is not set
++# CONFIG_TOUCHSCREEN_MK712 is not set
++# CONFIG_TOUCHSCREEN_PENMOUNT is not set
++# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set
++# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
++# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
++# CONFIG_TOUCHSCREEN_PIXCIR is not set
++# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
++# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
++# CONFIG_TOUCHSCREEN_TSC_SERIO is not set
++# CONFIG_TOUCHSCREEN_TSC2005 is not set
++# CONFIG_TOUCHSCREEN_TSC2007 is not set
++# CONFIG_TOUCHSCREEN_W90X900 is not set
++# CONFIG_TOUCHSCREEN_ST1232 is not set
++# CONFIG_TOUCHSCREEN_TPS6507X is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_AMBAKMI is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_SERIO_ALTERA_PS2 is not set
++# CONFIG_SERIO_PS2MULT is not set
++# CONFIG_SERIO_ARC_PS2 is not set
++# CONFIG_SERIO_APBPS2 is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_TTY=y
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_VT_CONSOLE_SLEEP=y
++CONFIG_HW_CONSOLE=y
++CONFIG_VT_HW_CONSOLE_BINDING=y
++CONFIG_UNIX98_PTYS=y
++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_SERIAL_NONSTANDARD is not set
++# CONFIG_N_GSM is not set
++# CONFIG_TRACE_SINK is not set
++CONFIG_DEVKMEM=y
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
++# CONFIG_SERIAL_8250_CONSOLE is not set
++CONFIG_SERIAL_8250_DMA=y
++CONFIG_SERIAL_8250_NR_UARTS=4
++CONFIG_SERIAL_8250_RUNTIME_UARTS=4
++# CONFIG_SERIAL_8250_EXTENDED is not set
++# CONFIG_SERIAL_8250_DW is not set
++# CONFIG_SERIAL_8250_EM is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_AMBA_PL010 is not set
++# CONFIG_SERIAL_AMBA_PL011 is not set
++CONFIG_SERIAL_SAMSUNG=y
++CONFIG_SERIAL_SAMSUNG_UARTS_4=y
++CONFIG_SERIAL_SAMSUNG_UARTS=4
++CONFIG_SERIAL_SAMSUNG_DEBUG=y
++CONFIG_SERIAL_SAMSUNG_CONSOLE=y
++# CONFIG_SERIAL_MAX3100 is not set
++# CONFIG_SERIAL_MAX310X is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_SERIAL_OF_PLATFORM=y
++# CONFIG_SERIAL_SCCNXP is not set
++# CONFIG_SERIAL_TIMBERDALE is not set
++# CONFIG_SERIAL_ALTERA_JTAGUART is not set
++# CONFIG_SERIAL_ALTERA_UART is not set
++# CONFIG_SERIAL_IFX6X60 is not set
++# CONFIG_SERIAL_XILINX_PS_UART is not set
++# CONFIG_SERIAL_ARC is not set
++# CONFIG_HVC_DCC is not set
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=y
++# CONFIG_HW_RANDOM_TIMERIOMEM is not set
++# CONFIG_HW_RANDOM_ATMEL is not set
++# CONFIG_HW_RANDOM_EXYNOS is not set
++CONFIG_HW_RANDOM_TPM=y
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++CONFIG_TCG_TPM=y
++CONFIG_TCG_TIS_I2C_INFINEON=y
++# CONFIG_TCG_ST33_I2C is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_COMPAT=y
++# CONFIG_I2C_CHARDEV is not set
++CONFIG_I2C_MUX=y
++
++#
++# Multiplexer I2C Chip support
++#
++CONFIG_I2C_ARB_GPIO_CHALLENGE=y
++# CONFIG_I2C_MUX_GPIO is not set
++# CONFIG_I2C_MUX_PCA9541 is not set
++# CONFIG_I2C_MUX_PCA954x is not set
++# CONFIG_I2C_MUX_PINCTRL is not set
++CONFIG_I2C_HELPER_AUTO=y
++CONFIG_I2C_ALGOBIT=y
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++# CONFIG_I2C_CBUS_GPIO is not set
++# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
++CONFIG_I2C_GPIO=y
++# CONFIG_I2C_NOMADIK is not set
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_PXA_PCI is not set
++CONFIG_HAVE_S3C2410_I2C=y
++CONFIG_I2C_S3C2410=y
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_XILINX is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_DIOLAN_U2C is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++CONFIG_SPI=y
++# CONFIG_SPI_DEBUG is not set
++CONFIG_SPI_MASTER=y
++
++#
++# SPI Master Controller Drivers
++#
++# CONFIG_SPI_ALTERA is not set
++# CONFIG_SPI_BITBANG is not set
++# CONFIG_SPI_GPIO is not set
++# CONFIG_SPI_FSL_SPI is not set
++# CONFIG_SPI_OC_TINY is not set
++# CONFIG_SPI_PL022 is not set
++# CONFIG_SPI_PXA2XX_PCI is not set
++# CONFIG_SPI_S3C64XX is not set
++# CONFIG_SPI_SC18IS602 is not set
++# CONFIG_SPI_XCOMM is not set
++# CONFIG_SPI_XILINX is not set
++# CONFIG_SPI_DESIGNWARE is not set
++
++#
++# SPI Protocol Masters
++#
++# CONFIG_SPI_SPIDEV is not set
++# CONFIG_SPI_TLE62X0 is not set
++
++#
++# Qualcomm MSM SSBI bus support
++#
++# CONFIG_SSBI is not set
++# CONFIG_HSI is not set
++
++#
++# PPS support
++#
++# CONFIG_PPS is not set
++
++#
++# PPS generators support
++#
++
++#
++# PTP clock support
++#
++# CONFIG_PTP_1588_CLOCK is not set
++
++#
++# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
++#
++# CONFIG_PTP_1588_CLOCK_PCH is not set
++CONFIG_PINCTRL=y
++
++#
++# Pin controllers
++#
++CONFIG_PINMUX=y
++CONFIG_PINCONF=y
++# CONFIG_DEBUG_PINCTRL is not set
++# CONFIG_PINCTRL_SINGLE is not set
++CONFIG_PINCTRL_SAMSUNG=y
++CONFIG_PINCTRL_EXYNOS=y
++CONFIG_PINCTRL_EXYNOS5440=y
++CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIO_DEVRES=y
++CONFIG_GPIOLIB=y
++CONFIG_OF_GPIO=y
++CONFIG_DEBUG_GPIO=y
++# CONFIG_GPIO_SYSFS is not set
++
++#
++# Memory mapped GPIO drivers:
++#
++# CONFIG_GPIO_GENERIC_PLATFORM is not set
++# CONFIG_GPIO_EM is not set
++# CONFIG_GPIO_PL061 is not set
++# CONFIG_GPIO_RCAR is not set
++# CONFIG_GPIO_TS5500 is not set
++# CONFIG_GPIO_GRGPIO is not set
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX7300 is not set
++# CONFIG_GPIO_MAX732X is not set
++# CONFIG_GPIO_PCF857X is not set
++# CONFIG_GPIO_SX150X is not set
++# CONFIG_GPIO_WM8994 is not set
++# CONFIG_GPIO_ADP5588 is not set
++# CONFIG_GPIO_ADNP is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_GPIO_MC33880 is not set
++# CONFIG_GPIO_74X164 is not set
++
++#
++# AC97 GPIO expanders:
++#
++
++#
++# MODULbus GPIO expanders:
++#
++
++#
++# USB GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_POWER_AVS is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++# CONFIG_WATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++CONFIG_BCMA_POSSIBLE=y
++
++#
++# Broadcom specific AMBA
++#
++# CONFIG_BCMA is not set
++
++#
++# Multifunction device drivers
++#
++CONFIG_MFD_CORE=y
++# CONFIG_MFD_AS3711 is not set
++# CONFIG_PMIC_ADP5520 is not set
++# CONFIG_MFD_AAT2870_CORE is not set
++CONFIG_MFD_CROS_EC=y
++CONFIG_MFD_CROS_EC_I2C=y
++# CONFIG_MFD_CROS_EC_SPI is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_DA9052_SPI is not set
++# CONFIG_MFD_DA9052_I2C is not set
++# CONFIG_MFD_DA9055 is not set
++# CONFIG_MFD_MC13XXX_SPI is not set
++# CONFIG_MFD_MC13XXX_I2C is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_HTC_I2CPLD is not set
++# CONFIG_MFD_88PM800 is not set
++# CONFIG_MFD_88PM805 is not set
++# CONFIG_MFD_88PM860X is not set
++CONFIG_MFD_MAX77686=y
++CONFIG_MFD_MAX77693=y
++# CONFIG_MFD_MAX8907 is not set
++# CONFIG_MFD_MAX8925 is not set
++CONFIG_MFD_MAX8997=y
++# CONFIG_MFD_MAX8998 is not set
++# CONFIG_EZX_PCAP is not set
++# CONFIG_MFD_VIPERBOARD is not set
++# CONFIG_MFD_RETU is not set
++# CONFIG_MFD_PCF50633 is not set
++# CONFIG_MFD_RC5T583 is not set
++CONFIG_MFD_SEC_CORE=y
++# CONFIG_MFD_SI476X_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_SMSC is not set
++# CONFIG_ABX500_CORE is not set
++# CONFIG_MFD_STMPE is not set
++CONFIG_MFD_SYSCON=y
++# CONFIG_MFD_TI_AM335X_TSCADC is not set
++# CONFIG_MFD_LP8788 is not set
++# CONFIG_MFD_PALMAS is not set
++# CONFIG_TPS6105X is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_TPS6507X is not set
++CONFIG_MFD_TPS65090=y
++# CONFIG_MFD_TPS65217 is not set
++# CONFIG_MFD_TPS6586X is not set
++# CONFIG_MFD_TPS65910 is not set
++# CONFIG_MFD_TPS65912 is not set
++# CONFIG_MFD_TPS65912_I2C is not set
++# CONFIG_MFD_TPS65912_SPI is not set
++# CONFIG_MFD_TPS80031 is not set
++# CONFIG_TWL4030_CORE is not set
++# CONFIG_TWL6040_CORE is not set
++# CONFIG_MFD_WL1273_CORE is not set
++# CONFIG_MFD_LM3533 is not set
++# CONFIG_MFD_TC3589X is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_T7L66XB is not set
++# CONFIG_MFD_TC6387XB is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_MFD_ARIZONA_I2C is not set
++# CONFIG_MFD_ARIZONA_SPI is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM831X_I2C is not set
++# CONFIG_MFD_WM831X_SPI is not set
++# CONFIG_MFD_WM8350_I2C is not set
++CONFIG_MFD_WM8994=y
++CONFIG_REGULATOR=y
++# CONFIG_REGULATOR_DEBUG is not set
++# CONFIG_REGULATOR_DUMMY is not set
++CONFIG_REGULATOR_FIXED_VOLTAGE=y
++# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
++# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
++CONFIG_REGULATOR_GPIO=y
++# CONFIG_REGULATOR_AD5398 is not set
++# CONFIG_REGULATOR_FAN53555 is not set
++# CONFIG_REGULATOR_ANATOP is not set
++# CONFIG_REGULATOR_ISL6271A is not set
++# CONFIG_REGULATOR_MAX1586 is not set
++# CONFIG_REGULATOR_MAX8649 is not set
++# CONFIG_REGULATOR_MAX8660 is not set
++# CONFIG_REGULATOR_MAX8952 is not set
++# CONFIG_REGULATOR_MAX8973 is not set
++CONFIG_REGULATOR_MAX8997=y
++CONFIG_REGULATOR_MAX77686=y
++# CONFIG_REGULATOR_MAX77693 is not set
++# CONFIG_REGULATOR_LP3971 is not set
++# CONFIG_REGULATOR_LP3972 is not set
++# CONFIG_REGULATOR_LP872X is not set
++# CONFIG_REGULATOR_LP8755 is not set
++# CONFIG_REGULATOR_S2MPS11 is not set
++CONFIG_REGULATOR_S5M8767=y
++# CONFIG_REGULATOR_TPS51632 is not set
++# CONFIG_REGULATOR_TPS62360 is not set
++# CONFIG_REGULATOR_TPS65023 is not set
++# CONFIG_REGULATOR_TPS6507X is not set
++CONFIG_REGULATOR_TPS65090=y
++# CONFIG_REGULATOR_TPS6524X is not set
++CONFIG_REGULATOR_WM8994=y
++CONFIG_MEDIA_SUPPORT=y
++
++#
++# Multimedia core support
++#
++CONFIG_MEDIA_CAMERA_SUPPORT=y
++# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set
++# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set
++# CONFIG_MEDIA_RADIO_SUPPORT is not set
++# CONFIG_MEDIA_RC_SUPPORT is not set
++CONFIG_MEDIA_CONTROLLER=y
++CONFIG_VIDEO_DEV=y
++CONFIG_VIDEO_V4L2_SUBDEV_API=y
++CONFIG_VIDEO_V4L2=y
++# CONFIG_VIDEO_ADV_DEBUG is not set
++# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
++CONFIG_V4L2_MEM2MEM_DEV=y
++CONFIG_VIDEOBUF2_CORE=y
++CONFIG_VIDEOBUF2_MEMOPS=y
++CONFIG_VIDEOBUF2_DMA_CONTIG=y
++# CONFIG_VIDEO_V4L2_INT_DEVICE is not set
++# CONFIG_TTPCI_EEPROM is not set
++
++#
++# Media drivers
++#
++# CONFIG_MEDIA_USB_SUPPORT is not set
++CONFIG_V4L_PLATFORM_DRIVERS=y
++# CONFIG_VIDEO_TIMBERDALE is not set
++# CONFIG_SOC_CAMERA is not set
++CONFIG_VIDEO_SAMSUNG_EXYNOS4_IS=y
++CONFIG_VIDEO_EXYNOS4_IS_COMMON=y
++CONFIG_VIDEO_S5P_FIMC=y
++CONFIG_VIDEO_S5P_MIPI_CSIS=y
++CONFIG_VIDEO_EXYNOS_FIMC_LITE=y
++CONFIG_VIDEO_EXYNOS4_FIMC_IS=y
++CONFIG_VIDEO_EXYNOS4_ISP_DMA_CAPTURE=y
++# CONFIG_VIDEO_SAMSUNG_S5P_TV is not set
++CONFIG_V4L_MEM2MEM_DRIVERS=y
++# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set
++# CONFIG_VIDEO_SAMSUNG_S5P_G2D is not set
++CONFIG_VIDEO_SAMSUNG_S5P_JPEG=y
++CONFIG_VIDEO_SAMSUNG_S5P_MFC=y
++# CONFIG_VIDEO_SH_VEU is not set
++# CONFIG_V4L_TEST_DRIVERS is not set
++
++#
++# Supported MMC/SDIO adapters
++#
++# CONFIG_CYPRESS_FIRMWARE is not set
++
++#
++# Media ancillary drivers (tuners, sensors, i2c, frontends)
++#
++# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
++
++#
++# Encoders, decoders, sensors and other helper chips
++#
++
++#
++# Audio decoders, processors and mixers
++#
++# CONFIG_VIDEO_TVAUDIO is not set
++# CONFIG_VIDEO_TDA7432 is not set
++# CONFIG_VIDEO_TDA9840 is not set
++# CONFIG_VIDEO_TEA6415C is not set
++# CONFIG_VIDEO_TEA6420 is not set
++# CONFIG_VIDEO_MSP3400 is not set
++# CONFIG_VIDEO_CS5345 is not set
++# CONFIG_VIDEO_CS53L32A is not set
++# CONFIG_VIDEO_TLV320AIC23B is not set
++# CONFIG_VIDEO_UDA1342 is not set
++# CONFIG_VIDEO_WM8775 is not set
++# CONFIG_VIDEO_WM8739 is not set
++# CONFIG_VIDEO_VP27SMPX is not set
++# CONFIG_VIDEO_SONY_BTF_MPX is not set
++
++#
++# RDS decoders
++#
++# CONFIG_VIDEO_SAA6588 is not set
++
++#
++# Video decoders
++#
++# CONFIG_VIDEO_ADV7180 is not set
++# CONFIG_VIDEO_ADV7183 is not set
++# CONFIG_VIDEO_ADV7604 is not set
++# CONFIG_VIDEO_BT819 is not set
++# CONFIG_VIDEO_BT856 is not set
++# CONFIG_VIDEO_BT866 is not set
++# CONFIG_VIDEO_KS0127 is not set
++# CONFIG_VIDEO_SAA7110 is not set
++# CONFIG_VIDEO_SAA711X is not set
++# CONFIG_VIDEO_SAA7191 is not set
++# CONFIG_VIDEO_TVP514X is not set
++# CONFIG_VIDEO_TVP5150 is not set
++# CONFIG_VIDEO_TVP7002 is not set
++# CONFIG_VIDEO_TW2804 is not set
++# CONFIG_VIDEO_TW9903 is not set
++# CONFIG_VIDEO_TW9906 is not set
++# CONFIG_VIDEO_VPX3220 is not set
++
++#
++# Video and audio decoders
++#
++# CONFIG_VIDEO_SAA717X is not set
++# CONFIG_VIDEO_CX25840 is not set
++
++#
++# Video encoders
++#
++# CONFIG_VIDEO_SAA7127 is not set
++# CONFIG_VIDEO_SAA7185 is not set
++# CONFIG_VIDEO_ADV7170 is not set
++# CONFIG_VIDEO_ADV7175 is not set
++# CONFIG_VIDEO_ADV7343 is not set
++# CONFIG_VIDEO_ADV7393 is not set
++# CONFIG_VIDEO_AD9389B is not set
++# CONFIG_VIDEO_AK881X is not set
++
++#
++# Camera sensor devices
++#
++# CONFIG_VIDEO_OV7640 is not set
++# CONFIG_VIDEO_OV7670 is not set
++# CONFIG_VIDEO_OV9650 is not set
++# CONFIG_VIDEO_VS6624 is not set
++# CONFIG_VIDEO_MT9M032 is not set
++# CONFIG_VIDEO_MT9P031 is not set
++# CONFIG_VIDEO_MT9T001 is not set
++# CONFIG_VIDEO_MT9V011 is not set
++# CONFIG_VIDEO_MT9V032 is not set
++# CONFIG_VIDEO_SR030PC30 is not set
++# CONFIG_VIDEO_NOON010PC30 is not set
++CONFIG_VIDEO_M5MOLS=m
++CONFIG_VIDEO_S5K6AA=m
++# CONFIG_VIDEO_S5K6A3 is not set
++# CONFIG_VIDEO_S5K4ECGX is not set
++CONFIG_VIDEO_S5K5BAF=m
++# CONFIG_VIDEO_SMIAPP is not set
++CONFIG_VIDEO_S5C73M3=m
++
++#
++# Flash devices
++#
++# CONFIG_VIDEO_ADP1653 is not set
++# CONFIG_VIDEO_AS3645A is not set
++
++#
++# Video improvement chips
++#
++# CONFIG_VIDEO_UPD64031A is not set
++# CONFIG_VIDEO_UPD64083 is not set
++
++#
++# Miscelaneous helper chips
++#
++# CONFIG_VIDEO_THS7303 is not set
++# CONFIG_VIDEO_M52790 is not set
++
++#
++# Sensors used on soc_camera driver
++#
++
++#
++# Customise DVB Frontends
++#
++CONFIG_DVB_AU8522=m
++CONFIG_DVB_AU8522_V4L=m
++CONFIG_DVB_TUNER_DIB0070=m
++CONFIG_DVB_TUNER_DIB0090=m
++
++#
++# Tools to develop new frontends
++#
++# CONFIG_DVB_DUMMY_FE is not set
++
++#
++# Graphics support
++#
++
++#
++# ARM GPU Configuration
++#
++# CONFIG_MALI400 is not set
++CONFIG_DRM=y
++CONFIG_DRM_KMS_HELPER=y
++# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set
++
++#
++# I2C encoder or helper chips
++#
++# CONFIG_DRM_I2C_CH7006 is not set
++# CONFIG_DRM_I2C_SIL164 is not set
++# CONFIG_DRM_I2C_NXP_TDA998X is not set
++CONFIG_DRM_EXYNOS=y
++# CONFIG_DRM_EXYNOS_IOMMU is not set
++# CONFIG_DRM_EXYNOS_DMABUF is not set
++CONFIG_DRM_EXYNOS_FIMD=y
++CONFIG_DRM_EXYNOS_HDMI=y
++# CONFIG_DRM_EXYNOS_VIDI is not set
++# CONFIG_DRM_EXYNOS_G2D is not set
++# CONFIG_DRM_EXYNOS_IPP is not set
++# CONFIG_DRM_UDL is not set
++# CONFIG_DRM_TILCDC is not set
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_VIDEOMODE_HELPERS=y
++CONFIG_HDMI=y
++CONFIG_FB=y
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB_DDC is not set
++# CONFIG_FB_BOOT_VESA_SUPPORT is not set
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++# CONFIG_FB_SYS_FILLRECT is not set
++# CONFIG_FB_SYS_COPYAREA is not set
++# CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_FOREIGN_ENDIAN is not set
++# CONFIG_FB_SYS_FOPS is not set
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++CONFIG_FB_MODE_HELPERS=y
++# CONFIG_FB_TILEBLITTING is not set
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_ARMCLCD is not set
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_TMIO is not set
++# CONFIG_FB_S3C is not set
++# CONFIG_FB_SMSCUFX is not set
++# CONFIG_FB_UDL is not set
++# CONFIG_FB_GOLDFISH is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_BROADSHEET is not set
++# CONFIG_FB_AUO_K190X is not set
++CONFIG_FB_SIMPLE=y
++CONFIG_EXYNOS_VIDEO=y
++CONFIG_EXYNOS_MIPI_DSI=y
++CONFIG_EXYNOS_DP=y
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++# CONFIG_DISPLAY_CORE is not set
++
++#
++# Console display driver support
++#
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
++# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
++CONFIG_FONTS=y
++# CONFIG_FONT_8x8 is not set
++# CONFIG_FONT_8x16 is not set
++# CONFIG_FONT_6x11 is not set
++CONFIG_FONT_7x14=y
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++# CONFIG_FONT_MINI_4x6 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_10x18 is not set
++CONFIG_LOGO=y
++CONFIG_LOGO_LINUX_MONO=y
++CONFIG_LOGO_LINUX_VGA16=y
++CONFIG_LOGO_LINUX_CLUT224=y
++# CONFIG_FB_SSD1307 is not set
++# CONFIG_SOUND is not set
++
++#
++# HID support
++#
++CONFIG_HID=y
++# CONFIG_HIDRAW is not set
++# CONFIG_UHID is not set
++CONFIG_HID_GENERIC=y
++
++#
++# Special HID drivers
++#
++CONFIG_HID_A4TECH=y
++# CONFIG_HID_ACRUX is not set
++CONFIG_HID_APPLE=y
++# CONFIG_HID_APPLEIR is not set
++# CONFIG_HID_AUREAL is not set
++CONFIG_HID_BELKIN=y
++CONFIG_HID_CHERRY=y
++CONFIG_HID_CHICONY=y
++CONFIG_HID_CYPRESS=y
++# CONFIG_HID_DRAGONRISE is not set
++# CONFIG_HID_EMS_FF is not set
++# CONFIG_HID_ELECOM is not set
++CONFIG_HID_EZKEY=y
++# CONFIG_HID_HOLTEK is not set
++# CONFIG_HID_KEYTOUCH is not set
++# CONFIG_HID_KYE is not set
++# CONFIG_HID_UCLOGIC is not set
++# CONFIG_HID_WALTOP is not set
++# CONFIG_HID_GYRATION is not set
++# CONFIG_HID_ICADE is not set
++# CONFIG_HID_TWINHAN is not set
++CONFIG_HID_KENSINGTON=y
++# CONFIG_HID_LCPOWER is not set
++# CONFIG_HID_LENOVO_TPKBD is not set
++CONFIG_HID_LOGITECH=y
++# CONFIG_HID_LOGITECH_DJ is not set
++# CONFIG_LOGITECH_FF is not set
++# CONFIG_LOGIRUMBLEPAD2_FF is not set
++# CONFIG_LOGIG940_FF is not set
++# CONFIG_LOGIWHEELS_FF is not set
++# CONFIG_HID_MAGICMOUSE is not set
++CONFIG_HID_MICROSOFT=y
++CONFIG_HID_MONTEREY=y
++# CONFIG_HID_MULTITOUCH is not set
++# CONFIG_HID_NTRIG is not set
++# CONFIG_HID_ORTEK is not set
++# CONFIG_HID_PANTHERLORD is not set
++# CONFIG_HID_PETALYNX is not set
++# CONFIG_HID_PICOLCD is not set
++# CONFIG_HID_PRIMAX is not set
++# CONFIG_HID_PS3REMOTE is not set
++# CONFIG_HID_ROCCAT is not set
++# CONFIG_HID_SAITEK is not set
++# CONFIG_HID_SAMSUNG is not set
++# CONFIG_HID_SONY is not set
++# CONFIG_HID_SPEEDLINK is not set
++# CONFIG_HID_STEELSERIES is not set
++# CONFIG_HID_SUNPLUS is not set
++# CONFIG_HID_GREENASIA is not set
++# CONFIG_HID_SMARTJOYPLUS is not set
++# CONFIG_HID_TIVO is not set
++# CONFIG_HID_TOPSEED is not set
++# CONFIG_HID_THRUSTMASTER is not set
++# CONFIG_HID_ZEROPLUS is not set
++# CONFIG_HID_ZYDACRON is not set
++# CONFIG_HID_SENSOR_HUB is not set
++
++#
++# USB HID support
++#
++CONFIG_USB_HID=y
++# CONFIG_HID_PID is not set
++# CONFIG_USB_HIDDEV is not set
++
++#
++# I2C HID support
++#
++# CONFIG_I2C_HID is not set
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++# CONFIG_USB_ARCH_HAS_XHCI is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_COMMON=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB=y
++# CONFIG_USB_DEBUG is not set
++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEFAULT_PERSIST=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++CONFIG_USB_EHCI_HCD=y
++# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
++CONFIG_USB_EHCI_TT_NEWSCHED=y
++CONFIG_USB_EHCI_S5P=y
++# CONFIG_USB_EHCI_HCD_PLATFORM is not set
++# CONFIG_USB_OXU210HP_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_ISP1760_HCD is not set
++# CONFIG_USB_ISP1362_HCD is not set
++# CONFIG_USB_OHCI_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_MUSB_HDRC is not set
++# CONFIG_USB_RENESAS_USBHS is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
++#
++
++#
++# also be needed; see USB_STORAGE Help for more info
++#
++CONFIG_USB_STORAGE=y
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_REALTEK is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
++# CONFIG_USB_STORAGE_ENE_UB6250 is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++# CONFIG_USB_DWC3 is not set
++# CONFIG_USB_CHIPIDEA is not set
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_SEVSEG is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_SISUSBVGA is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_YUREX is not set
++# CONFIG_USB_EZUSB_FX2 is not set
++# CONFIG_USB_HSIC_USB3503 is not set
++CONFIG_USB_PHY=y
++# CONFIG_NOP_USB_XCEIV is not set
++# CONFIG_OMAP_CONTROL_USB is not set
++# CONFIG_OMAP_USB3 is not set
++CONFIG_SAMSUNG_USBPHY=y
++CONFIG_SAMSUNG_USB2PHY=y
++CONFIG_SAMSUNG_USB3PHY=y
++# CONFIG_USB_GPIO_VBUS is not set
++# CONFIG_USB_ISP1301 is not set
++# CONFIG_USB_RCAR_PHY is not set
++# CONFIG_USB_ULPI is not set
++CONFIG_USB_GADGET=y
++# CONFIG_USB_GADGET_DEBUG is not set
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++# CONFIG_USB_GADGET_DEBUG_FS is not set
++CONFIG_USB_GADGET_VBUS_DRAW=2
++CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
++
++#
++# USB Peripheral Controller
++#
++# CONFIG_USB_FUSB300 is not set
++# CONFIG_USB_R8A66597 is not set
++# CONFIG_USB_PXA27X is not set
++CONFIG_USB_S3C_HSOTG=y
++# CONFIG_USB_MV_UDC is not set
++# CONFIG_USB_MV_U3D is not set
++# CONFIG_USB_M66592 is not set
++# CONFIG_USB_NET2272 is not set
++# CONFIG_USB_DUMMY_HCD is not set
++CONFIG_USB_LIBCOMPOSITE=y
++CONFIG_USB_U_ETHER=y
++CONFIG_USB_F_ECM=y
++CONFIG_USB_F_SUBSET=y
++CONFIG_USB_F_RNDIS=y
++# CONFIG_USB_CONFIGFS is not set
++# CONFIG_USB_ZERO is not set
++CONFIG_USB_ETH=y
++CONFIG_USB_ETH_RNDIS=y
++# CONFIG_USB_ETH_EEM is not set
++# CONFIG_USB_G_NCM is not set
++# CONFIG_USB_GADGETFS is not set
++# CONFIG_USB_FUNCTIONFS is not set
++# CONFIG_USB_MASS_STORAGE is not set
++# CONFIG_USB_G_SERIAL is not set
++# CONFIG_USB_G_PRINTER is not set
++# CONFIG_USB_G_SLP is not set
++# CONFIG_USB_CDC_COMPOSITE is not set
++# CONFIG_USB_G_ACM_MS is not set
++# CONFIG_USB_G_MULTI is not set
++# CONFIG_USB_G_HID is not set
++# CONFIG_USB_G_DBGP is not set
++# CONFIG_USB_G_WEBCAM is not set
++CONFIG_MMC=y
++# CONFIG_MMC_DEBUG is not set
++# CONFIG_MMC_UNSAFE_RESUME is not set
++# CONFIG_MMC_CLKGATE is not set
++
++#
++# MMC/SD/SDIO Card Drivers
++#
++CONFIG_MMC_BLOCK=y
++CONFIG_MMC_BLOCK_MINORS=8
++CONFIG_MMC_BLOCK_BOUNCE=y
++# CONFIG_SDIO_UART is not set
++# CONFIG_MMC_TEST is not set
++
++#
++# MMC/SD/SDIO Host Controller Drivers
++#
++# CONFIG_MMC_ARMMMCI is not set
++CONFIG_MMC_SDHCI=y
++CONFIG_MMC_SDHCI_PLTFM=y
++CONFIG_MMC_SDHCI_S3C=y
++# CONFIG_MMC_SDHCI_PXAV3 is not set
++# CONFIG_MMC_SDHCI_PXAV2 is not set
++# CONFIG_MMC_SDHCI_S3C_DMA is not set
++CONFIG_MMC_DW=y
++CONFIG_MMC_DW_IDMAC=y
++CONFIG_MMC_DW_PLTFM=y
++CONFIG_MMC_DW_EXYNOS=y
++# CONFIG_MMC_VUB300 is not set
++# CONFIG_MMC_USHC is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_NEW_LEDS is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_EDAC is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_HCTOSYS=y
++CONFIG_RTC_SYSTOHC=y
++CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++# CONFIG_RTC_DRV_DS1307 is not set
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_DS3232 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_MAX8997 is not set
++# CONFIG_RTC_DRV_MAX77686 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_ISL12022 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8523 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_BQ32K is not set
++# CONFIG_RTC_DRV_S35390A is not set
++# CONFIG_RTC_DRV_FM3130 is not set
++# CONFIG_RTC_DRV_RX8581 is not set
++# CONFIG_RTC_DRV_RX8025 is not set
++# CONFIG_RTC_DRV_EM3027 is not set
++# CONFIG_RTC_DRV_RV3029C2 is not set
++
++#
++# SPI RTC drivers
++#
++# CONFIG_RTC_DRV_M41T93 is not set
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
++# CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
++# CONFIG_RTC_DRV_PCF2123 is not set
++# CONFIG_RTC_DRV_RX4581 is not set
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_MSM6242 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_RP5C01 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++# CONFIG_RTC_DRV_DS2404 is not set
++
++#
++# on-CPU RTC drivers
++#
++CONFIG_HAVE_S3C_RTC=y
++CONFIG_RTC_DRV_S3C=y
++# CONFIG_RTC_DRV_PL030 is not set
++# CONFIG_RTC_DRV_PL031 is not set
++# CONFIG_RTC_DRV_SNVS is not set
++
++#
++# HID Sensor RTC drivers
++#
++# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
++CONFIG_DMADEVICES=y
++CONFIG_DMADEVICES_DEBUG=y
++CONFIG_DMADEVICES_VDEBUG=y
++
++#
++# DMA Devices
++#
++# CONFIG_AMBA_PL08X is not set
++# CONFIG_DW_DMAC is not set
++# CONFIG_TIMB_DMA is not set
++CONFIG_PL330_DMA=y
++CONFIG_DMA_ENGINE=y
++CONFIG_DMA_OF=y
++
++#
++# DMA Clients
++#
++# CONFIG_NET_DMA is not set
++# CONFIG_ASYNC_TX_DMA is not set
++# CONFIG_DMATEST is not set
++# CONFIG_AUXDISPLAY is not set
++# CONFIG_UIO is not set
++# CONFIG_VFIO is not set
++# CONFIG_VIRT_DRIVERS is not set
++
++#
++# Virtio drivers
++#
++# CONFIG_VIRTIO_MMIO is not set
++
++#
++# Microsoft Hyper-V guest support
++#
++# CONFIG_STAGING is not set
++CONFIG_CLKDEV_LOOKUP=y
++CONFIG_HAVE_CLK_PREPARE=y
++CONFIG_COMMON_CLK=y
++
++#
++# Common Clock Framework
++#
++CONFIG_COMMON_CLK_DEBUG=y
++CONFIG_COMMON_CLK_MAX77686=y
++# CONFIG_COMMON_CLK_SI5351 is not set
++
++#
++# Hardware Spinlock drivers
++#
++CONFIG_CLKSRC_OF=y
++CONFIG_CLKSRC_MMIO=y
++CONFIG_ARM_ARCH_TIMER=y
++CONFIG_CLKSRC_EXYNOS_MCT=y
++CONFIG_CLKSRC_SAMSUNG_PWM=y
++# CONFIG_MAILBOX is not set
++CONFIG_IOMMU_API=y
++CONFIG_IOMMU_SUPPORT=y
++CONFIG_OF_IOMMU=y
++CONFIG_EXYNOS_IOMMU=y
++# CONFIG_EXYNOS_IOMMU_DEBUG is not set
++
++#
++# Remoteproc drivers
++#
++# CONFIG_STE_MODEM_RPROC is not set
++
++#
++# Rpmsg drivers
++#
++# CONFIG_PM_DEVFREQ is not set
++# CONFIG_EXTCON is not set
++# CONFIG_MEMORY is not set
++# CONFIG_IIO is not set
++# CONFIG_PWM is not set
++CONFIG_IRQCHIP=y
++CONFIG_ARM_GIC=y
++CONFIG_GIC_NON_BANKED=y
++# CONFIG_IPACK_BUS is not set
++# CONFIG_RESET_CONTROLLER is not set
++
++#
++# PHY Subsystem
++#
++CONFIG_GENERIC_PHY=y
++# CONFIG_PHY_EXYNOS_MIPI_VIDEO is not set
++CONFIG_PHY_EXYNOS_USB=y
++CONFIG_PHY_EXYNOS4210_USB=y
++CONFIG_PHY_EXYNOS4212_USB=y
++CONFIG_EXYNOS_PHY=y
++
++#
++# File systems
++#
++CONFIG_DCACHE_WORD_ACCESS=y
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++CONFIG_EXT3_DEFAULTS_TO_ORDERED=y
++CONFIG_EXT3_FS_XATTR=y
++# CONFIG_EXT3_FS_POSIX_ACL is not set
++# CONFIG_EXT3_FS_SECURITY is not set
++CONFIG_EXT4_FS=y
++# CONFIG_EXT4_FS_POSIX_ACL is not set
++# CONFIG_EXT4_FS_SECURITY is not set
++# CONFIG_EXT4_DEBUG is not set
++CONFIG_JBD=y
++# CONFIG_JBD_DEBUG is not set
++CONFIG_JBD2=y
++# CONFIG_JBD2_DEBUG is not set
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_BTRFS_FS is not set
++# CONFIG_NILFS2_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_FILE_LOCKING=y
++CONFIG_FSNOTIFY=y
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_FANOTIFY is not set
++# CONFIG_QUOTA is not set
++# CONFIG_QUOTACTL is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++CONFIG_GENERIC_ACL=y
++
++#
++# Caches
++#
++# CONFIG_FSCACHE is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++CONFIG_TMPFS_XATTR=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=y
++CONFIG_MISC_FILESYSTEMS=y
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_LOGFS is not set
++CONFIG_CRAMFS=y
++# CONFIG_SQUASHFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_QNX6FS_FS is not set
++CONFIG_ROMFS_FS=y
++CONFIG_ROMFS_BACKED_BY_BLOCK=y
++CONFIG_ROMFS_ON_BLOCK=y
++# CONFIG_PSTORE is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++# CONFIG_F2FS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++# CONFIG_NFS_FS is not set
++# CONFIG_NFSD is not set
++# CONFIG_CEPH_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++# CONFIG_NLS_CODEPAGE_936 is not set
++# CONFIG_NLS_CODEPAGE_950 is not set
++# CONFIG_NLS_CODEPAGE_932 is not set
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++# CONFIG_NLS_MAC_ROMAN is not set
++# CONFIG_NLS_MAC_CELTIC is not set
++# CONFIG_NLS_MAC_CENTEURO is not set
++# CONFIG_NLS_MAC_CROATIAN is not set
++# CONFIG_NLS_MAC_CYRILLIC is not set
++# CONFIG_NLS_MAC_GAELIC is not set
++# CONFIG_NLS_MAC_GREEK is not set
++# CONFIG_NLS_MAC_ICELAND is not set
++# CONFIG_NLS_MAC_INUIT is not set
++# CONFIG_NLS_MAC_ROMANIAN is not set
++# CONFIG_NLS_MAC_TURKISH is not set
++# CONFIG_NLS_UTF8 is not set
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++CONFIG_PRINTK_TIME=y
++CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_STRIP_ASM_SYMS is not set
++# CONFIG_READABLE_ASM is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++CONFIG_DEBUG_FS=y
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_SECTION_MISMATCH is not set
++CONFIG_DEBUG_KERNEL=y
++# CONFIG_DEBUG_SHIRQ is not set
++# CONFIG_LOCKUP_DETECTOR is not set
++# CONFIG_PANIC_ON_OOPS is not set
++CONFIG_PANIC_ON_OOPS_VALUE=0
++CONFIG_DETECT_HUNG_TASK=y
++CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
++# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
++CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
++CONFIG_SCHED_DEBUG=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_TIMER_STATS is not set
++# CONFIG_DEBUG_OBJECTS is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++CONFIG_HAVE_DEBUG_KMEMLEAK=y
++# CONFIG_DEBUG_KMEMLEAK is not set
++CONFIG_DEBUG_PREEMPT=y
++CONFIG_DEBUG_RT_MUTEXES=y
++CONFIG_DEBUG_PI_LIST=y
++# CONFIG_RT_MUTEX_TESTER is not set
++CONFIG_DEBUG_SPINLOCK=y
++CONFIG_DEBUG_MUTEXES=y
++# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
++# CONFIG_DEBUG_LOCK_ALLOC is not set
++# CONFIG_PROVE_LOCKING is not set
++# CONFIG_LOCK_STAT is not set
++# CONFIG_DEBUG_ATOMIC_SLEEP is not set
++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
++# CONFIG_DEBUG_STACK_USAGE is not set
++# CONFIG_DEBUG_KOBJECT is not set
++# CONFIG_DEBUG_HIGHMEM is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_INFO=y
++# CONFIG_DEBUG_INFO_REDUCED is not set
++# CONFIG_DEBUG_VM is not set
++# CONFIG_DEBUG_WRITECOUNT is not set
++CONFIG_DEBUG_MEMORY_INIT=y
++# CONFIG_DEBUG_LIST is not set
++# CONFIG_TEST_LIST_SORT is not set
++# CONFIG_DEBUG_SG is not set
++# CONFIG_DEBUG_NOTIFIERS is not set
++# CONFIG_DEBUG_CREDENTIALS is not set
++# CONFIG_BOOT_PRINTK_DELAY is not set
++
++#
++# RCU Debugging
++#
++# CONFIG_PROVE_RCU_DELAY is not set
++# CONFIG_SPARSE_RCU_POINTER is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++CONFIG_RCU_CPU_STALL_TIMEOUT=21
++CONFIG_RCU_CPU_STALL_VERBOSE=y
++# CONFIG_RCU_CPU_STALL_INFO is not set
++# CONFIG_RCU_TRACE is not set
++# CONFIG_BACKTRACE_SELF_TEST is not set
++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
++# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
++# CONFIG_DEBUG_PER_CPU_MAPS is not set
++# CONFIG_LKDTM is not set
++# CONFIG_NOTIFIER_ERROR_INJECTION is not set
++# CONFIG_FAULT_INJECTION is not set
++# CONFIG_DEBUG_PAGEALLOC is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
++CONFIG_HAVE_DYNAMIC_FTRACE=y
++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
++CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
++CONFIG_HAVE_C_RECORDMCOUNT=y
++CONFIG_TRACING_SUPPORT=y
++CONFIG_FTRACE=y
++# CONFIG_FUNCTION_TRACER is not set
++# CONFIG_IRQSOFF_TRACER is not set
++# CONFIG_PREEMPT_TRACER is not set
++# CONFIG_SCHED_TRACER is not set
++# CONFIG_ENABLE_DEFAULT_TRACERS is not set
++# CONFIG_FTRACE_SYSCALLS is not set
++# CONFIG_TRACER_SNAPSHOT is not set
++CONFIG_BRANCH_PROFILE_NONE=y
++# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
++# CONFIG_PROFILE_ALL_BRANCHES is not set
++# CONFIG_STACK_TRACER is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_PROBE_EVENTS is not set
++# CONFIG_RBTREE_TEST is not set
++# CONFIG_INTERVAL_TREE_TEST is not set
++# CONFIG_DYNAMIC_DEBUG is not set
++# CONFIG_DMA_API_DEBUG is not set
++# CONFIG_ATOMIC64_SELFTEST is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_KGDB is not set
++# CONFIG_TEST_STRING_HELPERS is not set
++# CONFIG_TEST_KSTRTOX is not set
++# CONFIG_STRICT_DEVMEM is not set
++CONFIG_ARM_UNWIND=y
++CONFIG_DEBUG_USER=y
++CONFIG_DEBUG_LL=y
++# CONFIG_DEBUG_S3C_UART0 is not set
++CONFIG_DEBUG_S3C_UART1=y
++# CONFIG_DEBUG_S3C_UART2 is not set
++# CONFIG_DEBUG_S3C_UART3 is not set
++# CONFIG_DEBUG_LL_UART_NONE is not set
++# CONFIG_DEBUG_ICEDCC is not set
++# CONFIG_DEBUG_SEMIHOSTING is not set
++CONFIG_DEBUG_EXYNOS_UART=y
++CONFIG_DEBUG_LL_INCLUDE="debug/exynos.S"
++CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"
++CONFIG_EARLY_PRINTK=y
++# CONFIG_OC_ETM is not set
++# CONFIG_PID_IN_CONTEXTIDR is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY_DMESG_RESTRICT is not set
++# CONFIG_SECURITY is not set
++CONFIG_SECURITYFS=y
++CONFIG_DEFAULT_SECURITY_DAC=y
++CONFIG_DEFAULT_SECURITY=""
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG=m
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_PCOMP2=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_USER is not set
++CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_PCRYPT is not set
++CONFIG_CRYPTO_WORKQUEUE=y
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++# CONFIG_CRYPTO_ECB is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++# CONFIG_CRYPTO_CMAC is not set
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_VMAC is not set
++
++#
++# Digest
++#
++CONFIG_CRYPTO_CRC32C=y
++# CONFIG_CRYPTO_CRC32 is not set
++# CONFIG_CRYPTO_GHASH is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA1_ARM is not set
++CONFIG_CRYPTO_SHA256=y
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++CONFIG_CRYPTO_AES=y
++# CONFIG_CRYPTO_AES_ARM is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_ZLIB is not set
++# CONFIG_CRYPTO_LZO is not set
++
++#
++# Random Number Generation
++#
++CONFIG_CRYPTO_ANSI_CPRNG=m
++# CONFIG_CRYPTO_USER_API_HASH is not set
++# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
++CONFIG_CRYPTO_HW=y
++# CONFIG_BINARY_PRINTF is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_GENERIC_STRNCPY_FROM_USER=y
++CONFIG_GENERIC_STRNLEN_USER=y
++CONFIG_GENERIC_PCI_IOMAP=y
++CONFIG_GENERIC_IO=y
++CONFIG_CRC_CCITT=y
++CONFIG_CRC16=y
++# CONFIG_CRC_T10DIF is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC32_SELFTEST is not set
++CONFIG_CRC32_SLICEBY8=y
++# CONFIG_CRC32_SLICEBY4 is not set
++# CONFIG_CRC32_SARWATE is not set
++# CONFIG_CRC32_BIT is not set
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++# CONFIG_CRC8 is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_LZO_COMPRESS=y
++CONFIG_LZO_DECOMPRESS=y
++CONFIG_XZ_DEC=y
++# CONFIG_XZ_DEC_X86 is not set
++# CONFIG_XZ_DEC_POWERPC is not set
++# CONFIG_XZ_DEC_IA64 is not set
++CONFIG_XZ_DEC_ARM=y
++CONFIG_XZ_DEC_ARMTHUMB=y
++# CONFIG_XZ_DEC_SPARC is not set
++CONFIG_XZ_DEC_BCJ=y
++# CONFIG_XZ_DEC_TEST is not set
++CONFIG_DECOMPRESS_GZIP=y
++CONFIG_DECOMPRESS_BZIP2=y
++CONFIG_DECOMPRESS_LZMA=y
++CONFIG_DECOMPRESS_XZ=y
++CONFIG_DECOMPRESS_LZO=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_DMA=y
++CONFIG_CPU_RMAP=y
++CONFIG_DQL=y
++CONFIG_NLATTR=y
++CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
++# CONFIG_AVERAGE is not set
++# CONFIG_CORDIC is not set
++# CONFIG_DDR is not set
++# CONFIG_VIRTUALIZATION is not set
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1246-exynos4-is-Register-v4l2_async-notifier-only-when-se.patch b/patches.tizen/1246-exynos4-is-Register-v4l2_async-notifier-only-when-se.patch
new file mode 100644 (file)
index 0000000..e596483
--- /dev/null
@@ -0,0 +1,55 @@
+From 69eac2ef99ee43c951bdac7ee9f85861f28e5975 Mon Sep 17 00:00:00 2001
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Date: Mon, 24 Feb 2014 13:48:41 +0100
+Subject: [PATCH 1246/1302] exynos4-is: Register v4l2_async notifier only when
+ sensors are available
+
+This allows driver initialization again if no camera sensors are
+specified. It fixes regression introduced in commit 9cb4cf023f4d793ca
+"exynos4-is: Add support for asynchronous sensor subddevs registration"
+
+Change-Id: I02379781ff51142f02dc3a4c3f0bc7b0da999e1f
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/exynos4-is/media-dev.c | 24 ++++++++++++++----------
+ 1 file changed, 14 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
+index 55a0900..4b40dbd 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.c
++++ b/drivers/media/platform/exynos4-is/media-dev.c
+@@ -1661,16 +1661,20 @@ static int fimc_md_probe(struct platform_device *pdev)
+               goto err_attr;
+       }
+-      fmd->subdev_notifier.subdevs = fmd->async_subdevs;
+-      fmd->subdev_notifier.num_subdevs = fmd->num_sensors;
+-      fmd->subdev_notifier.bound = subdev_notifier_bound;
+-      fmd->subdev_notifier.complete = subdev_notifier_complete;
+-      fmd->num_sensors = 0;
+-
+-      ret = v4l2_async_notifier_register(&fmd->v4l2_dev,
+-                                         &fmd->subdev_notifier);
+-      if (ret)
+-              goto err_clk_p;
++
++      if (fmd->num_sensors > 0) {
++              fmd->subdev_notifier.subdevs = fmd->async_subdevs;
++              fmd->subdev_notifier.num_subdevs = fmd->num_sensors;
++              fmd->subdev_notifier.bound = subdev_notifier_bound;
++              fmd->subdev_notifier.complete = subdev_notifier_complete;
++              fmd->num_sensors = 0;
++
++              ret = v4l2_async_notifier_register(&fmd->v4l2_dev,
++                                                 &fmd->subdev_notifier);
++
++              if (ret)
++                      goto err_clk_p;
++      }
+       return 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1247-Fix-building-RPM-with-tar-1.27-and-renamed-m0-dtb.patch b/patches.tizen/1247-Fix-building-RPM-with-tar-1.27-and-renamed-m0-dtb.patch
new file mode 100644 (file)
index 0000000..4a63439
--- /dev/null
@@ -0,0 +1,45 @@
+From c45aa714cd5b5e754b9439901259929a3bb61d5d Mon Sep 17 00:00:00 2001
+From: Maciej Wereski <m.wereski@partner.samsung.com>
+Date: Tue, 25 Feb 2014 11:23:55 +0100
+Subject: [PATCH 1247/1302] Fix building RPM with tar 1.27 and renamed m0 dtb
+
+Change-Id: I50a01f8a005ed958e0d2d00f8033eb1a9a2340ec
+Signed-off-by: Maciej Wereski <m.wereski@partner.samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ packaging/linux-kernel.spec | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/packaging/linux-kernel.spec b/packaging/linux-kernel.spec
+index 41c7be1..367079d 100644
+--- a/packaging/linux-kernel.spec
++++ b/packaging/linux-kernel.spec
+@@ -1,7 +1,7 @@
+ %define config_name tizen_defconfig
+ %define abiver 1
+ %define build_id %{config_name}.%{abiver}
+-%define defaultDtb exynos4412-m0.dtb
++%define defaultDtb exynos4412-trats2.dtb
+ %define buildarch arm
+ Name: linux-kernel
+@@ -86,7 +86,7 @@ make -s -C tools/lib/traceevent ARCH=%{buildarch} %{?_smp_mflags}
+ make -s -C tools/perf WERROR=0 ARCH=%{buildarch}
+ # 4. Create tar repo for build directory
+-tar cpsf linux-kernel-build-%{fullVersion}.tar .
++tar cpf linux-kernel-build-%{fullVersion}.tar .
+ %install
+ QA_SKIP_BUILD_ROOT="DO_NOT_WANT"; export QA_SKIP_BUILD_ROOT
+@@ -99,7 +99,6 @@ mkdir -p %{buildroot}/boot/
+ # 2. Install uImage, System.map, ...
+ install -m 755 arch/arm/boot/uImage %{buildroot}/boot/
+ install -m 644 arch/arm/boot/dts/*.dtb %{buildroot}/boot/
+-mv %{buildroot}/boot/exynos4412-m0.dtb %{buildroot}/boot/exynos4412-trats2.dtb
+ install -m 644 System.map %{buildroot}/boot/System.map-%{fullVersion}
+ install -m 644 .config %{buildroot}/boot/config-%{fullVersion}
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1248-math64-New-separate-div64_u64_rem-helper.patch b/patches.tizen/1248-math64-New-separate-div64_u64_rem-helper.patch
new file mode 100644 (file)
index 0000000..6f16513
--- /dev/null
@@ -0,0 +1,116 @@
+From b096cf6613077c26f60281d5188a09ff8643d38d Mon Sep 17 00:00:00 2001
+From: Mike Snitzer <snitzer@redhat.com>
+Date: Tue, 20 Aug 2013 15:05:17 -0400
+Subject: [PATCH 1248/1302] math64: New separate div64_u64_rem helper
+
+Commit f792685006274a850e6cc0ea9ade275ccdfc90bc ("math64: New
+div64_u64_rem helper") implemented div64_u64 in terms of div64_u64_rem.
+But div64_u64_rem was removed because it slowed down div64_u64 (and
+there were no other users of div64_u64_rem).
+
+Device Mapper's I/O statistics support has a need for div64_u64_rem;
+reintroduce this helper as a separate method that doesn't slow down
+div64_u64, especially on 32-bit systems.
+
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Cc: Stanislaw Gruszka <sgruszka@redhat.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Cc: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Alasdair G Kergon <agk@redhat.com>
+
+[backport]
+Signed-off-by: Maciej Wereski <m.wereski@partner.samsung.com>
+Change-Id: Icd721ff57c6d127e7acb0bf17d233d0a50ff24da
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ include/linux/math64.h | 13 +++++++++++++
+ lib/div64.c            | 40 ++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 53 insertions(+)
+
+diff --git a/include/linux/math64.h b/include/linux/math64.h
+index 2913b86..69ed5f5 100644
+--- a/include/linux/math64.h
++++ b/include/linux/math64.h
+@@ -31,6 +31,15 @@ static inline s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder)
+ }
+ /**
++ * div64_u64_rem - unsigned 64bit divide with 64bit divisor and remainder
++ */
++static inline u64 div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder)
++{
++      *remainder = dividend % divisor;
++      return dividend / divisor;
++}
++
++/**
+  * div64_u64 - unsigned 64bit divide with 64bit divisor
+  */
+ static inline u64 div64_u64(u64 dividend, u64 divisor)
+@@ -63,6 +72,10 @@ static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
+ extern s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder);
+ #endif
++#ifndef div64_u64_rem
++extern u64 div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder);
++#endif
++
+ #ifndef div64_u64
+ extern u64 div64_u64(u64 dividend, u64 divisor);
+ #endif
+diff --git a/lib/div64.c b/lib/div64.c
+index a163b6c..4382ad7 100644
+--- a/lib/div64.c
++++ b/lib/div64.c
+@@ -79,6 +79,46 @@ EXPORT_SYMBOL(div_s64_rem);
+ #endif
+ /**
++ * div64_u64_rem - unsigned 64bit divide with 64bit divisor and remainder
++ * @dividend: 64bit dividend
++ * @divisor:  64bit divisor
++ * @remainder:  64bit remainder
++ *
++ * This implementation is a comparable to algorithm used by div64_u64.
++ * But this operation, which includes math for calculating the remainder,
++ * is kept distinct to avoid slowing down the div64_u64 operation on 32bit
++ * systems.
++ */
++#ifndef div64_u64_rem
++u64 div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder)
++{
++      u32 high = divisor >> 32;
++      u64 quot;
++
++      if (high == 0) {
++              u32 rem32;
++              quot = div_u64_rem(dividend, divisor, &rem32);
++              *remainder = rem32;
++      } else {
++              int n = 1 + fls(high);
++              quot = div_u64(dividend >> n, divisor >> n);
++
++              if (quot != 0)
++                      quot--;
++
++              *remainder = dividend - quot * divisor;
++              if (*remainder >= divisor) {
++                      quot++;
++                      *remainder -= divisor;
++              }
++      }
++
++      return quot;
++}
++EXPORT_SYMBOL(div64_u64_rem);
++#endif
++
++/**
+  * div64_u64 - unsigned 64bit divide with 64bit divisor
+  * @dividend: 64bit dividend
+  * @divisor:  64bit divisor
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1249-Enable-FHANDLE-needed-by-systemd-209.patch b/patches.tizen/1249-Enable-FHANDLE-needed-by-systemd-209.patch
new file mode 100644 (file)
index 0000000..277c819
--- /dev/null
@@ -0,0 +1,28 @@
+From 9e5fefcfa8b3c3d260fbe5f6b3cbc86c71e1f288 Mon Sep 17 00:00:00 2001
+From: Maciej Wereski <m.wereski@partner.samsung.com>
+Date: Wed, 26 Feb 2014 17:14:34 +0100
+Subject: [PATCH 1249/1302] Enable FHANDLE, needed by systemd >= 209
+
+Change-Id: Ic01e9ad45ff6241ba451742857f5808f56deb970
+Signed-off-by: Maciej Wereski <m.wereski@partner.samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_defconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/configs/tizen_defconfig b/arch/arm/configs/tizen_defconfig
+index 73702f2..b04638d 100644
+--- a/arch/arm/configs/tizen_defconfig
++++ b/arch/arm/configs/tizen_defconfig
+@@ -48,7 +48,7 @@ CONFIG_SWAP=y
+ CONFIG_SYSVIPC=y
+ CONFIG_SYSVIPC_SYSCTL=y
+ # CONFIG_POSIX_MQUEUE is not set
+-# CONFIG_FHANDLE is not set
++CONFIG_FHANDLE=y
+ CONFIG_AUDIT=y
+ # CONFIG_AUDIT_LOGINUID_IMMUTABLE is not set
+ CONFIG_HAVE_GENERIC_HARDIRQS=y
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1250-ARM-defconfig-update-tizen_odroidx2_defconfig.patch b/patches.tizen/1250-ARM-defconfig-update-tizen_odroidx2_defconfig.patch
new file mode 100644 (file)
index 0000000..6cd81b4
--- /dev/null
@@ -0,0 +1,40 @@
+From 4bcb05501656f358b9c730bb7393adbc8a9bbb6a Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Thu, 27 Feb 2014 11:40:41 +0100
+Subject: [PATCH 1250/1302] ARM: defconfig: update tizen_odroidx2_defconfig
+
+Add missing USB3503 HSIC chip driver (enables host usb support) and
+disable UART debug.
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-id: I5ba5ef112a0fb02c8a38673a3bf3dfcefa28f696
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_odroidx2_defconfig | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/configs/tizen_odroidx2_defconfig b/arch/arm/configs/tizen_odroidx2_defconfig
+index d209f19..97272e1 100644
+--- a/arch/arm/configs/tizen_odroidx2_defconfig
++++ b/arch/arm/configs/tizen_odroidx2_defconfig
+@@ -1171,7 +1171,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+ CONFIG_SERIAL_SAMSUNG=y
+ CONFIG_SERIAL_SAMSUNG_UARTS_4=y
+ CONFIG_SERIAL_SAMSUNG_UARTS=4
+-CONFIG_SERIAL_SAMSUNG_DEBUG=y
++# CONFIG_SERIAL_SAMSUNG_DEBUG is not set
+ CONFIG_SERIAL_SAMSUNG_CONSOLE=y
+ # CONFIG_SERIAL_MAX3100 is not set
+ # CONFIG_SERIAL_MAX310X is not set
+@@ -1945,7 +1945,7 @@ CONFIG_USB_STORAGE=y
+ # CONFIG_USB_ISIGHTFW is not set
+ # CONFIG_USB_YUREX is not set
+ # CONFIG_USB_EZUSB_FX2 is not set
+-# CONFIG_USB_HSIC_USB3503 is not set
++CONFIG_USB_HSIC_USB3503=y
+ CONFIG_USB_PHY=y
+ # CONFIG_NOP_USB_XCEIV is not set
+ # CONFIG_OMAP_CONTROL_USB is not set
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1251-ARM-odroidx2-enable-P3V3-fixed-regulator-to-always-o.patch b/patches.tizen/1251-ARM-odroidx2-enable-P3V3-fixed-regulator-to-always-o.patch
new file mode 100644 (file)
index 0000000..2c1488b
--- /dev/null
@@ -0,0 +1,39 @@
+From 9dc0dce150909bb582752191b3a36cebb6ee03c6 Mon Sep 17 00:00:00 2001
+From: Joonyoung Shim <jy0922.shim@samsung.com>
+Date: Fri, 28 Feb 2014 15:38:00 +0900
+Subject: [PATCH 1251/1302] ARM: odroidx2: enable P3V3 fixed regulator to
+ always on
+
+This fixed regulator is used at usb module mainly, not mmc. Just use to
+always on it.
+
+Change-Id: Ib43ea87aa85cd21aca9f44937c7c7a70c0e916f4
+Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-odroidx2.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-odroidx2.dts b/arch/arm/boot/dts/exynos4412-odroidx2.dts
+index 9ce1768..c4c01bb 100644
+--- a/arch/arm/boot/dts/exynos4412-odroidx2.dts
++++ b/arch/arm/boot/dts/exynos4412-odroidx2.dts
+@@ -98,6 +98,7 @@
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpa1 1 1>;
+               enable-active-high;
++              regulator-always-on;
+               regulator-boot-on;
+       };
+@@ -105,7 +106,6 @@
+               bus-width = <4>;
+               pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>;
+               pinctrl-names = "default";
+-              vmmc-supply = <&regulator_p3v3>;
+               status = "okay";
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1252-ARM-odroidx2-update-defconfig.patch b/patches.tizen/1252-ARM-odroidx2-update-defconfig.patch
new file mode 100644 (file)
index 0000000..627a986
--- /dev/null
@@ -0,0 +1,195 @@
+From b1116fdcf1ac8701e61f461974dd73564d59bdf0 Mon Sep 17 00:00:00 2001
+From: Joonyoung Shim <jy0922.shim@samsung.com>
+Date: Fri, 28 Feb 2014 16:00:39 +0900
+Subject: [PATCH 1252/1302] ARM: odroidx2: update defconfig
+
+Enable cgroup, ipv6, nfs and disable serial8250. This will enable to
+boot until console login prompt on tizen platform.
+
+Change-Id: Ie29ee730c4a1f30d1fe201b16aab689f03453d5b
+Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_odroidx2_defconfig | 68 ++++++++++++++++++++-----------
+ 1 file changed, 45 insertions(+), 23 deletions(-)
+
+diff --git a/arch/arm/configs/tizen_odroidx2_defconfig b/arch/arm/configs/tizen_odroidx2_defconfig
+index 97272e1..338cc2d 100644
+--- a/arch/arm/configs/tizen_odroidx2_defconfig
++++ b/arch/arm/configs/tizen_odroidx2_defconfig
+@@ -102,7 +102,18 @@ CONFIG_RCU_FANOUT_LEAF=16
+ # CONFIG_RCU_NOCB_CPU is not set
+ # CONFIG_IKCONFIG is not set
+ CONFIG_LOG_BUF_SHIFT=17
+-# CONFIG_CGROUPS is not set
++CONFIG_CGROUPS=y
++# CONFIG_CGROUP_DEBUG is not set
++# CONFIG_CGROUP_FREEZER is not set
++# CONFIG_CGROUP_DEVICE is not set
++# CONFIG_CPUSETS is not set
++# CONFIG_CGROUP_CPUACCT is not set
++# CONFIG_RESOURCE_COUNTERS is not set
++CONFIG_CGROUP_SCHED=y
++CONFIG_FAIR_GROUP_SCHED=y
++# CONFIG_CFS_BANDWIDTH is not set
++# CONFIG_RT_GROUP_SCHED is not set
++# CONFIG_BLK_CGROUP is not set
+ # CONFIG_CHECKPOINT_RESTORE is not set
+ CONFIG_NAMESPACES=y
+ CONFIG_UTS_NS=y
+@@ -112,7 +123,7 @@ CONFIG_PID_NS=y
+ CONFIG_NET_NS=y
+ CONFIG_UIDGID_CONVERTED=y
+ # CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
+-# CONFIG_SCHED_AUTOGROUP is not set
++CONFIG_SCHED_AUTOGROUP=y
+ # CONFIG_SYSFS_DEPRECATED is not set
+ # CONFIG_RELAY is not set
+ CONFIG_BLK_DEV_INITRD=y
+@@ -583,7 +594,7 @@ CONFIG_INET=y
+ # CONFIG_IP_PNP is not set
+ # CONFIG_NET_IPIP is not set
+ # CONFIG_NET_IPGRE_DEMUX is not set
+-CONFIG_NET_IP_TUNNEL=m
++# CONFIG_NET_IP_TUNNEL is not set
+ # CONFIG_ARPD is not set
+ # CONFIG_SYN_COOKIES is not set
+ # CONFIG_NET_IPVTI is not set
+@@ -591,7 +602,7 @@ CONFIG_NET_IP_TUNNEL=m
+ # CONFIG_INET_ESP is not set
+ # CONFIG_INET_IPCOMP is not set
+ # CONFIG_INET_XFRM_TUNNEL is not set
+-CONFIG_INET_TUNNEL=m
++# CONFIG_INET_TUNNEL is not set
+ CONFIG_INET_XFRM_MODE_TRANSPORT=y
+ CONFIG_INET_XFRM_MODE_TUNNEL=y
+ CONFIG_INET_XFRM_MODE_BEET=y
+@@ -603,7 +614,7 @@ CONFIG_INET_TCP_DIAG=y
+ CONFIG_TCP_CONG_CUBIC=y
+ CONFIG_DEFAULT_TCP_CONG="cubic"
+ # CONFIG_TCP_MD5SIG is not set
+-CONFIG_IPV6=m
++CONFIG_IPV6=y
+ # CONFIG_IPV6_PRIVACY is not set
+ # CONFIG_IPV6_ROUTER_PREF is not set
+ # CONFIG_IPV6_OPTIMISTIC_DAD is not set
+@@ -613,13 +624,11 @@ CONFIG_IPV6=m
+ # CONFIG_IPV6_MIP6 is not set
+ # CONFIG_INET6_XFRM_TUNNEL is not set
+ # CONFIG_INET6_TUNNEL is not set
+-CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+-CONFIG_INET6_XFRM_MODE_TUNNEL=m
+-CONFIG_INET6_XFRM_MODE_BEET=m
++# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET6_XFRM_MODE_BEET is not set
+ # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+-CONFIG_IPV6_SIT=m
+-# CONFIG_IPV6_SIT_6RD is not set
+-CONFIG_IPV6_NDISC_NODETYPE=y
++# CONFIG_IPV6_SIT is not set
+ # CONFIG_IPV6_TUNNEL is not set
+ # CONFIG_IPV6_GRE is not set
+ # CONFIG_IPV6_MULTIPLE_TABLES is not set
+@@ -646,6 +655,7 @@ CONFIG_HAVE_NET_DSA=y
+ # CONFIG_IEEE802154 is not set
+ # CONFIG_NET_SCHED is not set
+ # CONFIG_DCB is not set
++CONFIG_DNS_RESOLVER=y
+ # CONFIG_BATMAN_ADV is not set
+ # CONFIG_OPENVSWITCH is not set
+ # CONFIG_VSOCKETS is not set
+@@ -654,6 +664,7 @@ CONFIG_HAVE_NET_DSA=y
+ CONFIG_RPS=y
+ CONFIG_RFS_ACCEL=y
+ CONFIG_XPS=y
++# CONFIG_NETPRIO_CGROUP is not set
+ CONFIG_BQL=y
+ # CONFIG_BPF_JIT is not set
+@@ -1153,15 +1164,7 @@ CONFIG_DEVKMEM=y
+ #
+ # Serial drivers
+ #
+-CONFIG_SERIAL_8250=y
+-CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
+-# CONFIG_SERIAL_8250_CONSOLE is not set
+-CONFIG_SERIAL_8250_DMA=y
+-CONFIG_SERIAL_8250_NR_UARTS=4
+-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+-# CONFIG_SERIAL_8250_EXTENDED is not set
+-# CONFIG_SERIAL_8250_DW is not set
+-# CONFIG_SERIAL_8250_EM is not set
++# CONFIG_SERIAL_8250 is not set
+ #
+ # Non-8250 serial port support
+@@ -1177,7 +1180,6 @@ CONFIG_SERIAL_SAMSUNG_CONSOLE=y
+ # CONFIG_SERIAL_MAX310X is not set
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
+-CONFIG_SERIAL_OF_PLATFORM=y
+ # CONFIG_SERIAL_SCCNXP is not set
+ # CONFIG_SERIAL_TIMBERDALE is not set
+ # CONFIG_SERIAL_ALTERA_JTAGUART is not set
+@@ -2285,6 +2287,7 @@ CONFIG_CONFIGFS_FS=y
+ CONFIG_MISC_FILESYSTEMS=y
+ # CONFIG_ADFS_FS is not set
+ # CONFIG_AFFS_FS is not set
++# CONFIG_ECRYPT_FS is not set
+ # CONFIG_HFS_FS is not set
+ # CONFIG_HFSPLUS_FS is not set
+ # CONFIG_BEFS_FS is not set
+@@ -2307,8 +2310,22 @@ CONFIG_ROMFS_ON_BLOCK=y
+ # CONFIG_UFS_FS is not set
+ # CONFIG_F2FS_FS is not set
+ CONFIG_NETWORK_FILESYSTEMS=y
+-# CONFIG_NFS_FS is not set
++CONFIG_NFS_FS=y
++CONFIG_NFS_V2=y
++CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
++CONFIG_NFS_V4=y
++# CONFIG_NFS_SWAP is not set
++# CONFIG_NFS_V4_1 is not set
++# CONFIG_NFS_USE_LEGACY_DNS is not set
++CONFIG_NFS_USE_KERNEL_DNS=y
+ # CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_LOCKD_V4=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++CONFIG_SUNRPC_GSS=y
++# CONFIG_SUNRPC_DEBUG is not set
+ # CONFIG_CEPH_FS is not set
+ # CONFIG_CIFS is not set
+ # CONFIG_NCP_FS is not set
+@@ -2497,7 +2514,10 @@ CONFIG_EARLY_PRINTK=y
+ #
+ # Security options
+ #
+-# CONFIG_KEYS is not set
++CONFIG_KEYS=y
++# CONFIG_TRUSTED_KEYS is not set
++# CONFIG_ENCRYPTED_KEYS is not set
++# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
+ # CONFIG_SECURITY_DMESG_RESTRICT is not set
+ # CONFIG_SECURITY is not set
+ CONFIG_SECURITYFS=y
+@@ -2610,6 +2630,7 @@ CONFIG_CRYPTO_ANSI_CPRNG=m
+ # CONFIG_CRYPTO_USER_API_HASH is not set
+ # CONFIG_CRYPTO_USER_API_SKCIPHER is not set
+ CONFIG_CRYPTO_HW=y
++# CONFIG_ASYMMETRIC_KEY_TYPE is not set
+ # CONFIG_BINARY_PRINTF is not set
+ #
+@@ -2659,4 +2680,5 @@ CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+ # CONFIG_AVERAGE is not set
+ # CONFIG_CORDIC is not set
+ # CONFIG_DDR is not set
++CONFIG_OID_REGISTRY=y
+ # CONFIG_VIRTUALIZATION is not set
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1253-au0828-fix-i2c-clock-speed-for-DViCO-FusionHDTV7.patch b/patches.tizen/1253-au0828-fix-i2c-clock-speed-for-DViCO-FusionHDTV7.patch
new file mode 100644 (file)
index 0000000..72b3b4f
--- /dev/null
@@ -0,0 +1,37 @@
+From 023f57bb00678ee04f588275c1a04e7a88e09c39 Mon Sep 17 00:00:00 2001
+From: Joonyoung Shim <jy0922.shim@samsung.com>
+Date: Tue, 11 Feb 2014 10:54:34 +0900
+Subject: [PATCH 1253/1302] au0828: fix i2c clock speed for DViCO FusionHDTV7
+
+DViCO FusionHDTV7 device that use au0828 can fail to communicate with
+xc5000 using i2c interface because of high i2c clock speed - i2c clock
+stretching bug. It causes to fail xc5000 firmware loading normally at
+the current driver.
+
+Already this problem fixed as changing to low i2c clock speed at
+HVR-950q device, also DViCO FusionHDTV7 device can solve it as using low
+i2c clock speed - 20KHz.
+
+Change-Id: Ie6fed3673081970a7d6aceeda584433f95c092a2
+Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/usb/au0828/au0828-cards.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/usb/au0828/au0828-cards.c b/drivers/media/usb/au0828/au0828-cards.c
+index dd32dec..6b569f4 100644
+--- a/drivers/media/usb/au0828/au0828-cards.c
++++ b/drivers/media/usb/au0828/au0828-cards.c
+@@ -108,7 +108,7 @@ struct au0828_board au0828_boards[] = {
+               .name   = "DViCO FusionHDTV USB",
+               .tuner_type = UNSET,
+               .tuner_addr = ADDR_UNSET,
+-              .i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
++              .i2c_clk_divider = AU0828_I2C_CLK_20KHZ,
+       },
+       [AU0828_BOARD_HAUPPAUGE_WOODBURY] = {
+               .name = "Hauppauge Woodbury",
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1254-ARM-odroidx2-update-defconfig-for-DViCO-FusionHDTV-U.patch b/patches.tizen/1254-ARM-odroidx2-update-defconfig-for-DViCO-FusionHDTV-U.patch
new file mode 100644 (file)
index 0000000..3432fcc
--- /dev/null
@@ -0,0 +1,276 @@
+From 83ee8379a9abe237b006b09261b101169296c514 Mon Sep 17 00:00:00 2001
+From: Joonyoung Shim <jy0922.shim@samsung.com>
+Date: Mon, 3 Mar 2014 20:43:06 +0900
+Subject: [PATCH 1254/1302] ARM: odroidx2: update defconfig for DViCO
+ FusionHDTV USB
+
+This enables au0828 bridge, au8522 dvb frontend and xc5000 tuner for
+DViCO FusionHDTV USB.
+
+Change-Id: I2dcac4f9d543da95de6fe07e80088684b5ae8ad9
+Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_odroidx2_defconfig | 208 +++++++++++++++++++++++++++++-
+ 1 file changed, 202 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm/configs/tizen_odroidx2_defconfig b/arch/arm/configs/tizen_odroidx2_defconfig
+index 338cc2d..79fdc8c 100644
+--- a/arch/arm/configs/tizen_odroidx2_defconfig
++++ b/arch/arm/configs/tizen_odroidx2_defconfig
+@@ -1493,7 +1493,7 @@ CONFIG_MEDIA_SUPPORT=y
+ #
+ CONFIG_MEDIA_CAMERA_SUPPORT=y
+ # CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set
+-# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set
++CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
+ # CONFIG_MEDIA_RADIO_SUPPORT is not set
+ # CONFIG_MEDIA_RC_SUPPORT is not set
+ CONFIG_MEDIA_CONTROLLER=y
+@@ -1503,16 +1503,52 @@ CONFIG_VIDEO_V4L2=y
+ # CONFIG_VIDEO_ADV_DEBUG is not set
+ # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+ CONFIG_V4L2_MEM2MEM_DEV=y
++CONFIG_VIDEOBUF_GEN=y
++CONFIG_VIDEOBUF_VMALLOC=y
+ CONFIG_VIDEOBUF2_CORE=y
+ CONFIG_VIDEOBUF2_MEMOPS=y
+ CONFIG_VIDEOBUF2_DMA_CONTIG=y
+ # CONFIG_VIDEO_V4L2_INT_DEVICE is not set
++CONFIG_DVB_CORE=y
++CONFIG_DVB_NET=y
+ # CONFIG_TTPCI_EEPROM is not set
++CONFIG_DVB_MAX_ADAPTERS=8
++# CONFIG_DVB_DYNAMIC_MINORS is not set
+ #
+ # Media drivers
+ #
+-# CONFIG_MEDIA_USB_SUPPORT is not set
++CONFIG_MEDIA_USB_SUPPORT=y
++
++#
++# Webcam devices
++#
++# CONFIG_USB_VIDEO_CLASS is not set
++# CONFIG_USB_GSPCA is not set
++# CONFIG_USB_PWC is not set
++# CONFIG_VIDEO_CPIA2 is not set
++# CONFIG_USB_ZR364XX is not set
++# CONFIG_USB_STKWEBCAM is not set
++# CONFIG_USB_S2255 is not set
++# CONFIG_USB_SN9C102 is not set
++
++#
++# Analog/digital TV USB devices
++#
++CONFIG_VIDEO_AU0828=y
++CONFIG_VIDEO_AU0828_V4L2=y
++
++#
++# Digital TV USB devices
++#
++# CONFIG_DVB_USB_V2 is not set
++# CONFIG_SMS_USB_DRV is not set
++# CONFIG_DVB_B2C2_FLEXCOP_USB is not set
++
++#
++# Webcam, TV (analog/digital) USB devices
++#
++# CONFIG_VIDEO_EM28XX is not set
+ CONFIG_V4L_PLATFORM_DRIVERS=y
+ # CONFIG_VIDEO_TIMBERDALE is not set
+ # CONFIG_SOC_CAMERA is not set
+@@ -1535,12 +1571,15 @@ CONFIG_VIDEO_SAMSUNG_S5P_MFC=y
+ #
+ # Supported MMC/SDIO adapters
+ #
++# CONFIG_SMS_SDIO_DRV is not set
++CONFIG_VIDEO_TVEEPROM=y
+ # CONFIG_CYPRESS_FIRMWARE is not set
+ #
+ # Media ancillary drivers (tuners, sensors, i2c, frontends)
+ #
+ # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
++CONFIG_MEDIA_ATTACH=y
+ #
+ # Encoders, decoders, sensors and other helper chips
+@@ -1653,12 +1692,169 @@ CONFIG_VIDEO_S5C73M3=m
+ #
+ #
++# Customize TV tuners
++#
++# CONFIG_MEDIA_TUNER_SIMPLE is not set
++# CONFIG_MEDIA_TUNER_TDA8290 is not set
++# CONFIG_MEDIA_TUNER_TDA827X is not set
++# CONFIG_MEDIA_TUNER_TDA18271 is not set
++# CONFIG_MEDIA_TUNER_TDA9887 is not set
++# CONFIG_MEDIA_TUNER_TEA5761 is not set
++# CONFIG_MEDIA_TUNER_TEA5767 is not set
++# CONFIG_MEDIA_TUNER_MT20XX is not set
++# CONFIG_MEDIA_TUNER_MT2060 is not set
++# CONFIG_MEDIA_TUNER_MT2063 is not set
++# CONFIG_MEDIA_TUNER_MT2266 is not set
++# CONFIG_MEDIA_TUNER_MT2131 is not set
++# CONFIG_MEDIA_TUNER_QT1010 is not set
++# CONFIG_MEDIA_TUNER_XC2028 is not set
++CONFIG_MEDIA_TUNER_XC5000=y
++# CONFIG_MEDIA_TUNER_XC4000 is not set
++# CONFIG_MEDIA_TUNER_MXL5005S is not set
++# CONFIG_MEDIA_TUNER_MXL5007T is not set
++# CONFIG_MEDIA_TUNER_MC44S803 is not set
++# CONFIG_MEDIA_TUNER_MAX2165 is not set
++# CONFIG_MEDIA_TUNER_TDA18218 is not set
++# CONFIG_MEDIA_TUNER_FC0011 is not set
++# CONFIG_MEDIA_TUNER_FC0012 is not set
++# CONFIG_MEDIA_TUNER_FC0013 is not set
++# CONFIG_MEDIA_TUNER_TDA18212 is not set
++# CONFIG_MEDIA_TUNER_E4000 is not set
++# CONFIG_MEDIA_TUNER_FC2580 is not set
++# CONFIG_MEDIA_TUNER_TUA9001 is not set
++# CONFIG_MEDIA_TUNER_IT913X is not set
++# CONFIG_MEDIA_TUNER_R820T is not set
++
++#
+ # Customise DVB Frontends
+ #
+-CONFIG_DVB_AU8522=m
+-CONFIG_DVB_AU8522_V4L=m
+-CONFIG_DVB_TUNER_DIB0070=m
+-CONFIG_DVB_TUNER_DIB0090=m
++
++#
++# Multistandard (satellite) frontends
++#
++# CONFIG_DVB_STB0899 is not set
++# CONFIG_DVB_STB6100 is not set
++# CONFIG_DVB_STV090x is not set
++# CONFIG_DVB_STV6110x is not set
++
++#
++# Multistandard (cable + terrestrial) frontends
++#
++# CONFIG_DVB_DRXK is not set
++# CONFIG_DVB_TDA18271C2DD is not set
++
++#
++# DVB-S (satellite) frontends
++#
++# CONFIG_DVB_CX24110 is not set
++# CONFIG_DVB_CX24123 is not set
++# CONFIG_DVB_MT312 is not set
++# CONFIG_DVB_ZL10036 is not set
++# CONFIG_DVB_ZL10039 is not set
++# CONFIG_DVB_S5H1420 is not set
++# CONFIG_DVB_STV0288 is not set
++# CONFIG_DVB_STB6000 is not set
++# CONFIG_DVB_STV0299 is not set
++# CONFIG_DVB_STV6110 is not set
++# CONFIG_DVB_STV0900 is not set
++# CONFIG_DVB_TDA8083 is not set
++# CONFIG_DVB_TDA10086 is not set
++# CONFIG_DVB_TDA8261 is not set
++# CONFIG_DVB_VES1X93 is not set
++# CONFIG_DVB_TUNER_ITD1000 is not set
++# CONFIG_DVB_TUNER_CX24113 is not set
++# CONFIG_DVB_TDA826X is not set
++# CONFIG_DVB_TUA6100 is not set
++# CONFIG_DVB_CX24116 is not set
++# CONFIG_DVB_SI21XX is not set
++# CONFIG_DVB_TS2020 is not set
++# CONFIG_DVB_DS3000 is not set
++# CONFIG_DVB_MB86A16 is not set
++# CONFIG_DVB_TDA10071 is not set
++
++#
++# DVB-T (terrestrial) frontends
++#
++# CONFIG_DVB_SP8870 is not set
++# CONFIG_DVB_SP887X is not set
++# CONFIG_DVB_CX22700 is not set
++# CONFIG_DVB_CX22702 is not set
++# CONFIG_DVB_S5H1432 is not set
++# CONFIG_DVB_DRXD is not set
++# CONFIG_DVB_L64781 is not set
++# CONFIG_DVB_TDA1004X is not set
++# CONFIG_DVB_NXT6000 is not set
++# CONFIG_DVB_MT352 is not set
++# CONFIG_DVB_ZL10353 is not set
++# CONFIG_DVB_DIB3000MB is not set
++# CONFIG_DVB_DIB3000MC is not set
++# CONFIG_DVB_DIB7000M is not set
++# CONFIG_DVB_DIB7000P is not set
++# CONFIG_DVB_DIB9000 is not set
++# CONFIG_DVB_TDA10048 is not set
++# CONFIG_DVB_AF9013 is not set
++# CONFIG_DVB_EC100 is not set
++# CONFIG_DVB_HD29L2 is not set
++# CONFIG_DVB_STV0367 is not set
++# CONFIG_DVB_CXD2820R is not set
++# CONFIG_DVB_RTL2830 is not set
++# CONFIG_DVB_RTL2832 is not set
++
++#
++# DVB-C (cable) frontends
++#
++# CONFIG_DVB_VES1820 is not set
++# CONFIG_DVB_TDA10021 is not set
++# CONFIG_DVB_TDA10023 is not set
++# CONFIG_DVB_STV0297 is not set
++
++#
++# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
++#
++# CONFIG_DVB_NXT200X is not set
++# CONFIG_DVB_OR51211 is not set
++# CONFIG_DVB_OR51132 is not set
++# CONFIG_DVB_BCM3510 is not set
++# CONFIG_DVB_LGDT330X is not set
++# CONFIG_DVB_LGDT3305 is not set
++# CONFIG_DVB_LG2160 is not set
++# CONFIG_DVB_S5H1409 is not set
++CONFIG_DVB_AU8522=y
++CONFIG_DVB_AU8522_DTV=y
++CONFIG_DVB_AU8522_V4L=y
++# CONFIG_DVB_S5H1411 is not set
++
++#
++# ISDB-T (terrestrial) frontends
++#
++# CONFIG_DVB_S921 is not set
++# CONFIG_DVB_DIB8000 is not set
++# CONFIG_DVB_MB86A20S is not set
++
++#
++# Digital terrestrial only tuners/PLL
++#
++# CONFIG_DVB_PLL is not set
++# CONFIG_DVB_TUNER_DIB0070 is not set
++# CONFIG_DVB_TUNER_DIB0090 is not set
++
++#
++# SEC control devices for DVB-S
++#
++# CONFIG_DVB_LNBP21 is not set
++# CONFIG_DVB_LNBP22 is not set
++# CONFIG_DVB_ISL6405 is not set
++# CONFIG_DVB_ISL6421 is not set
++# CONFIG_DVB_ISL6423 is not set
++# CONFIG_DVB_A8293 is not set
++# CONFIG_DVB_LGS8GL5 is not set
++# CONFIG_DVB_LGS8GXX is not set
++# CONFIG_DVB_ATBM8830 is not set
++# CONFIG_DVB_TDA665x is not set
++# CONFIG_DVB_IX2505V is not set
++# CONFIG_DVB_IT913X_FE is not set
++# CONFIG_DVB_M88RS2000 is not set
++# CONFIG_DVB_AF9033 is not set
+ #
+ # Tools to develop new frontends
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1255-phy-exynos-add-delay-after-reset-phy-for-usb-host.patch b/patches.tizen/1255-phy-exynos-add-delay-after-reset-phy-for-usb-host.patch
new file mode 100644 (file)
index 0000000..d5b4297
--- /dev/null
@@ -0,0 +1,33 @@
+From e542f3631ac83f7dbeaa8f8f41d91865762e36f8 Mon Sep 17 00:00:00 2001
+From: Joonyoung Shim <jy0922.shim@samsung.com>
+Date: Tue, 4 Mar 2014 15:38:14 +0900
+Subject: [PATCH 1255/1302] phy: exynos : add delay after reset phy for usb
+ host
+
+The commit 2b431ff74a850db3d5b804be3ac466b6ed7f516d(ARM: EXYNOS4:
+Increase reset delay for USB HOST PHY) uses 80 usec delay time after
+reset phy for usb host, so this adds delay for reset. If isn't this
+delay, it will cause any problem to set usb host register.
+
+Change-Id: I1410dacc6939218bc26510cd45ebd4c0d37dbc62
+Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/phy/phy-exynos4212-usb.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/phy/phy-exynos4212-usb.c b/drivers/phy/phy-exynos4212-usb.c
+index a9fa15d..c6af66d 100644
+--- a/drivers/phy/phy-exynos4212-usb.c
++++ b/drivers/phy/phy-exynos4212-usb.c
+@@ -233,6 +233,7 @@ static void exynos4212_phy_pwr(struct uphy_instance *inst, bool on)
+               udelay(10);
+               rst &= ~rstbits;
+               writel(rst, drv->reg_phy + EXYNOS_4212_UPHYRST);
++              udelay(80);
+       } else {
+               pwr = readl(drv->reg_phy + EXYNOS_4212_UPHYPWR);
+               pwr |= phypwr;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1256-usb-misc-usb3503-Add-to-select-the-ports-to-disable.patch b/patches.tizen/1256-usb-misc-usb3503-Add-to-select-the-ports-to-disable.patch
new file mode 100644 (file)
index 0000000..cf1a7ce
--- /dev/null
@@ -0,0 +1,107 @@
+From bd9b411c1e33ed863b6d9c75ea1ece38a0b03d03 Mon Sep 17 00:00:00 2001
+From: Dongjin Kim <tobetter@gmail.com>
+Date: Wed, 22 May 2013 05:20:08 +0900
+Subject: [PATCH 1256/1302] usb: misc: usb3503: Add to select the ports to
+ disable
+
+This patch is to disable the USB ports unconnected to USB3503. In order to
+disable the port, 'port_off_mask' must be set.
+
+* Disable PORT1 only
+       .port_off_mask = USB3503_OFF_PORT1;
+
+* Disable PORT1 and PORT3 only
+       .port_off_mask = USB3503_OFF_PORT1 | USB3503_OFF_PORT3;
+
+* Enables all ports
+       .port_off_mask = 0;
+
+Signed-off-by: Dongjin Kim <tobetter@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[mszyprow: mainline commit e8e44a4896a5f0bde1af36a31b7ec662bdaa44ef]
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-Id: Ie8e44a4896a5f0bde1af36a31b7ec662bdaa44ef
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/misc/usb3503.c            | 19 ++++++++++---------
+ include/linux/platform_data/usb3503.h |  5 +++++
+ 2 files changed, 15 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c
+index d3a1cce..ab24bb3 100644
+--- a/drivers/usb/misc/usb3503.c
++++ b/drivers/usb/misc/usb3503.c
+@@ -42,9 +42,6 @@
+ #define USB3503_NRD           0x09
+ #define USB3503_PDS           0x0a
+-#define USB3503_PORT1         (1 << 1)
+-#define USB3503_PORT2         (1 << 2)
+-#define USB3503_PORT3         (1 << 3)
+ #define USB3503_SP_ILOCK      0xe7
+ #define USB3503_SPILOCK_CONNECT       (1 << 1)
+@@ -56,6 +53,7 @@
+ struct usb3503 {
+       enum usb3503_mode       mode;
+       struct i2c_client       *client;
++      u8      port_off_mask;
+       int     gpio_intn;
+       int     gpio_reset;
+       int     gpio_connect;
+@@ -134,12 +132,14 @@ static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode)
+                       goto err_hubmode;
+               }
+-              /* PDS : Port2,3 Disable For Self Powered Operation */
+-              err = usb3503_set_bits(i2c, USB3503_PDS,
+-                              (USB3503_PORT2 | USB3503_PORT3));
+-              if (err < 0) {
+-                      dev_err(&i2c->dev, "PDS failed (%d)\n", err);
+-                      goto err_hubmode;
++              /* PDS : Disable For Self Powered Operation */
++              if (hub->port_off_mask) {
++                      err = usb3503_set_bits(i2c, USB3503_PDS,
++                                      hub->port_off_mask);
++                      if (err < 0) {
++                              dev_err(&i2c->dev, "PDS failed (%d)\n", err);
++                              goto err_hubmode;
++                      }
+               }
+               /* CFG1 : SELF_BUS_PWR -> Self-Powerd operation */
+@@ -197,6 +197,7 @@ static int usb3503_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+       hub->client = i2c;
+       if (pdata) {
++              hub->port_off_mask      = pdata->port_off_mask;
+               hub->gpio_intn          = pdata->gpio_intn;
+               hub->gpio_connect       = pdata->gpio_connect;
+               hub->gpio_reset         = pdata->gpio_reset;
+diff --git a/include/linux/platform_data/usb3503.h b/include/linux/platform_data/usb3503.h
+index 85dcc70..1d1b6ef 100644
+--- a/include/linux/platform_data/usb3503.h
++++ b/include/linux/platform_data/usb3503.h
+@@ -3,6 +3,10 @@
+ #define USB3503_I2C_NAME      "usb3503"
++#define USB3503_OFF_PORT1     (1 << 1)
++#define USB3503_OFF_PORT2     (1 << 2)
++#define USB3503_OFF_PORT3     (1 << 3)
++
+ enum usb3503_mode {
+       USB3503_MODE_UNKNOWN,
+       USB3503_MODE_HUB,
+@@ -11,6 +15,7 @@ enum usb3503_mode {
+ struct usb3503_platform_data {
+       enum usb3503_mode       initial_mode;
++      u8      port_off_mask;
+       int     gpio_intn;
+       int     gpio_connect;
+       int     gpio_reset;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1257-usb-misc-usb3503-Adding-device-tree-entry-disabled-p.patch b/patches.tizen/1257-usb-misc-usb3503-Adding-device-tree-entry-disabled-p.patch
new file mode 100644 (file)
index 0000000..65511de
--- /dev/null
@@ -0,0 +1,89 @@
+From 48f657fe3878e33de79d1fa912b2411e8815e687 Mon Sep 17 00:00:00 2001
+From: Dongjin Kim <tobetter@gmail.com>
+Date: Wed, 22 May 2013 05:20:09 +0900
+Subject: [PATCH 1257/1302] usb: misc: usb3503: Adding device tree entry
+ 'disabled-ports'
+
+This patch is to add a property 'disabled-ports' representing the unused port
+of USB3503. USB3503 can support up to 3 USB host port and each ports can be
+controlled to be enabled or disabled. Do not describe this property if all
+ports must be enabled.
+
+You can represent the ports to disable in the device tree.
+
+       usb3503@08{
+               ...
+               disabled-ports = <2 3>;
+               ...
+       };
+
+Signed-off-by: Dongjin Kim <tobetter@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[mszyprow: mainline commit e8b58b49130f40c29bb95cd5d9b36955ff703822]
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-Id: Ie8b58b49130f40c29bb95cd5d9b36955ff703822
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/devicetree/bindings/usb/usb3503.txt |  5 +++++
+ drivers/usb/misc/usb3503.c                        | 14 ++++++++++++++
+ 2 files changed, 19 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/usb/usb3503.txt b/Documentation/devicetree/bindings/usb/usb3503.txt
+index 6813a71..8c5be48 100644
+--- a/Documentation/devicetree/bindings/usb/usb3503.txt
++++ b/Documentation/devicetree/bindings/usb/usb3503.txt
+@@ -4,6 +4,10 @@ Required properties:
+ - compatible: Should be "smsc,usb3503".
+ - reg: Specifies the i2c slave address, it should be 0x08.
+ - connect-gpios: Should specify GPIO for connect.
++- disabled-ports: Should specify the ports unused.
++      '1' or '2' or '3' are availe for this property to describe the port
++      number. 1~3 property values are possible to be desribed.
++      Do not describe this property if all ports have to be enabled.
+ - intn-gpios: Should specify GPIO for interrupt.
+ - reset-gpios: Should specify GPIO for reset.
+ - initial-mode: Should specify initial mode.
+@@ -14,6 +18,7 @@ Examples:
+               compatible = "smsc,usb3503";
+               reg = <0x08>;
+               connect-gpios = <&gpx3 0 1>;
++              disabled-ports = <2 3>;
+               intn-gpios = <&gpx3 4 1>;
+               reset-gpios = <&gpx3 5 1>;
+               initial-mode = <1>;
+diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c
+index ab24bb3..1908ec6 100644
+--- a/drivers/usb/misc/usb3503.c
++++ b/drivers/usb/misc/usb3503.c
+@@ -186,6 +186,8 @@ static int usb3503_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+       struct usb3503 *hub;
+       int err = -ENOMEM;
+       u32 mode = USB3503_MODE_UNKNOWN;
++      const u32 *property;
++      int len;
+       hub = kzalloc(sizeof(struct usb3503), GFP_KERNEL);
+       if (!hub) {
+@@ -203,6 +205,18 @@ static int usb3503_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+               hub->gpio_reset         = pdata->gpio_reset;
+               hub->mode               = pdata->initial_mode;
+       } else if (np) {
++              hub->port_off_mask = 0;
++
++              property = of_get_property(np, "disabled-ports", &len);
++              if (property && (len / sizeof(u32)) > 0) {
++                      int i;
++                      for (i = 0; i < len / sizeof(u32); i++) {
++                              u32 port = be32_to_cpu(property[i]);
++                              if ((1 <= port) && (port <= 3))
++                                      hub->port_off_mask |= (1 << port);
++                      }
++              }
++
+               hub->gpio_intn  = of_get_named_gpio(np, "connect-gpios", 0);
+               if (hub->gpio_intn == -EPROBE_DEFER)
+                       return -EPROBE_DEFER;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1258-usb-misc-usb3503-Fix-up-whitespace.patch b/patches.tizen/1258-usb-misc-usb3503-Fix-up-whitespace.patch
new file mode 100644 (file)
index 0000000..a33856e
--- /dev/null
@@ -0,0 +1,36 @@
+From 003e73e7a01d03ede8801cd8fa1ef91bb152dd67 Mon Sep 17 00:00:00 2001
+From: Julius Werner <jwerner@chromium.org>
+Date: Fri, 31 May 2013 18:34:50 -0700
+Subject: [PATCH 1258/1302] usb: misc: usb3503: Fix up whitespace
+
+Remove an erroneous tab that should be a space.
+
+Signed-off-by: Julius Werner <jwerner@chromium.org>
+Signed-off-by: Dongjin Kim <tobetter@gmail.com>
+Acked-by: Olof Johansson <olof@lixom.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[mszyprow: mainline commit ccf92c94135059c2fa7ee67bbd19af5103547510]
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-Id: Iccf92c94135059c2fa7ee67bbd19af5103547510
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/misc/usb3503.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c
+index 1908ec6..a56299d 100644
+--- a/drivers/usb/misc/usb3503.c
++++ b/drivers/usb/misc/usb3503.c
+@@ -223,7 +223,7 @@ static int usb3503_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+               hub->gpio_connect = of_get_named_gpio(np, "intn-gpios", 0);
+               if (hub->gpio_connect == -EPROBE_DEFER)
+                       return -EPROBE_DEFER;
+-              hub->gpio_reset = of_get_named_gpio(np, "reset-gpios", 0);
++              hub->gpio_reset = of_get_named_gpio(np, "reset-gpios", 0);
+               if (hub->gpio_reset == -EPROBE_DEFER)
+                       return -EPROBE_DEFER;
+               of_property_read_u32(np, "initial-mode", &mode);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1259-usb-misc-usb3503-Remove-100ms-sleep-on-reset-conform.patch b/patches.tizen/1259-usb-misc-usb3503-Remove-100ms-sleep-on-reset-conform.patch
new file mode 100644 (file)
index 0000000..b0c55eb
--- /dev/null
@@ -0,0 +1,49 @@
+From bf3e9832241d93a60d04fa9e34f8a6604373eddd Mon Sep 17 00:00:00 2001
+From: Julius Werner <jwerner@chromium.org>
+Date: Fri, 31 May 2013 18:34:52 -0700
+Subject: [PATCH 1259/1302] usb: misc: usb3503: Remove 100ms sleep on reset,
+ conform to data sheet
+
+The usb3503 driver sleeps a flat 100ms when resetting the chip, with a
+comment about waiting for the reference clock. This seems to be a
+board-specific detail that should not hold up boot across all platforms.
+This patch reduces the sleep to the 4ms initialization delay that the
+chip itself actually requires (as per its data sheet). If certain boards
+require more time to set up the reference clock, they should change this
+through local patches or add a proper, configurable synchronization
+mechanism.
+
+Signed-off-by: Julius Werner <jwerner@chromium.org>
+Signed-off-by: Dongjin Kim <tobetter@gmail.com>
+Acked-by: Olof Johansson <olof@lixom.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[mszyprow: mainline commit 06a962fa7f9bf068eb1238d7aa20453b9e11a9fd]
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-Id: I06a962fa7f9bf068eb1238d7aa20453b9e11a9fd
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/misc/usb3503.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c
+index a56299d..c357839 100644
+--- a/drivers/usb/misc/usb3503.c
++++ b/drivers/usb/misc/usb3503.c
+@@ -105,11 +105,9 @@ static int usb3503_reset(int gpio_reset, int state)
+       if (gpio_is_valid(gpio_reset))
+               gpio_set_value(gpio_reset, state);
+-      /* Wait RefClk when RESET_N is released, otherwise Hub will
+-       * not transition to Hub Communication Stage.
+-       */
++      /* Wait T_HUBINIT == 4ms for hub logic to stabilize */
+       if (state)
+-              msleep(100);
++              usleep_range(4000, 10000);
+       return 0;
+ }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1260-usb-misc-usb3503-use-dev_get_platdata.patch b/patches.tizen/1260-usb-misc-usb3503-use-dev_get_platdata.patch
new file mode 100644 (file)
index 0000000..c4b37d9
--- /dev/null
@@ -0,0 +1,35 @@
+From 4fa42afbfefd6a94ff6517ba0c81dbd236918a61 Mon Sep 17 00:00:00 2001
+From: Jingoo Han <jg1.han@samsung.com>
+Date: Tue, 30 Jul 2013 17:05:28 +0900
+Subject: [PATCH 1260/1302] usb: misc: usb3503: use dev_get_platdata()
+
+Use the wrapper function for retrieving the platform data instead of
+accessing dev->platform_data directly.
+
+Signed-off-by: Jingoo Han <jg1.han@samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[mszyprow: mainline commit b977a3068a284b2ad4612cdb8ca326cbd2a7ffc9]
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-Id: Ib977a3068a284b2ad4612cdb8ca326cbd2a7ffc9
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/misc/usb3503.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c
+index c357839..cbb6b78 100644
+--- a/drivers/usb/misc/usb3503.c
++++ b/drivers/usb/misc/usb3503.c
+@@ -179,7 +179,7 @@ err_hubmode:
+ static int usb3503_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+ {
+-      struct usb3503_platform_data *pdata = i2c->dev.platform_data;
++      struct usb3503_platform_data *pdata = dev_get_platdata(&i2c->dev);
+       struct device_node *np = i2c->dev.of_node;
+       struct usb3503 *hub;
+       int err = -ENOMEM;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1261-usb-misc-Fix-swapped-properties-in-usb3503-DT-parsin.patch b/patches.tizen/1261-usb-misc-Fix-swapped-properties-in-usb3503-DT-parsin.patch
new file mode 100644 (file)
index 0000000..98398fb
--- /dev/null
@@ -0,0 +1,43 @@
+From 84c7ed9fedac60f7a10fd7601bea775f9e1c5c15 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@linaro.org>
+Date: Wed, 7 Aug 2013 20:28:24 +0100
+Subject: [PATCH 1261/1302] usb: misc: Fix swapped properties in usb3503 DT
+ parsing
+
+The intn and connect GPIO properties are swapped in the code which will
+cause failures at runtime if these are connected, fix the code.
+
+There are currently no in-tree users of this device to check or update.
+
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Acked-by: Olof Johansson <olof@lixom.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[mszyprow: mainline commit 42416cc81f4990ad8d425b41a0fc8cd985eb5fa5]
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-Id: I42416cc81f4990ad8d425b41a0fc8cd985eb5fa5
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/misc/usb3503.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c
+index cbb6b78..4e3a2d2 100644
+--- a/drivers/usb/misc/usb3503.c
++++ b/drivers/usb/misc/usb3503.c
+@@ -215,10 +215,10 @@ static int usb3503_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+                       }
+               }
+-              hub->gpio_intn  = of_get_named_gpio(np, "connect-gpios", 0);
++              hub->gpio_intn  = of_get_named_gpio(np, "intn-gpios", 0);
+               if (hub->gpio_intn == -EPROBE_DEFER)
+                       return -EPROBE_DEFER;
+-              hub->gpio_connect = of_get_named_gpio(np, "intn-gpios", 0);
++              hub->gpio_connect = of_get_named_gpio(np, "connect-gpios", 0);
+               if (hub->gpio_connect == -EPROBE_DEFER)
+                       return -EPROBE_DEFER;
+               hub->gpio_reset = of_get_named_gpio(np, "reset-gpios", 0);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1262-ARM-dts-exynos4412-fix-usb3503-swapped-gpio-properti.patch b/patches.tizen/1262-ARM-dts-exynos4412-fix-usb3503-swapped-gpio-properti.patch
new file mode 100644 (file)
index 0000000..d1be74c
--- /dev/null
@@ -0,0 +1,35 @@
+From 9dd207548abf27493dca0c73954dc021ab2ed30d Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Tue, 4 Mar 2014 08:18:06 +0100
+Subject: [PATCH 1262/1302] ARM: dts: exynos4412: fix usb3503 swapped gpio
+ properties
+
+GPIO properties were swapped in the USB3503 driver. This has been fixed
+by mainline commit 42416cc81f4990ad8d425b41a0fc8cd985eb5fa5, so now also
+fix the DTS using this driver.
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-Id: I42416cc81f4990ad8d425b41a0fc8cd985eb5fa6
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-odroidx2.dts | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-odroidx2.dts b/arch/arm/boot/dts/exynos4412-odroidx2.dts
+index c4c01bb..e10200b 100644
+--- a/arch/arm/boot/dts/exynos4412-odroidx2.dts
++++ b/arch/arm/boot/dts/exynos4412-odroidx2.dts
+@@ -149,8 +149,8 @@
+                       compatible = "smsc,usb3503";
+                       reg = <0x08>;
+-                      connect-gpios = <&gpx3 0 0>;
+-                      intn-gpios = <&gpx3 4 0>;
++                      connect-gpios = <&gpx3 4 0>;
++                      intn-gpios = <&gpx3 0 0>;
+                       reset-gpios = <&gpx3 5 0>;
+                       initial-mode = <1>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1263-usb-misc-usb3503-Convert-to-devm_-APIs.patch b/patches.tizen/1263-usb-misc-usb3503-Convert-to-devm_-APIs.patch
new file mode 100644 (file)
index 0000000..a7e110c
--- /dev/null
@@ -0,0 +1,118 @@
+From 5c22ceef0dc5fb40da47ca6b4d645adcbdabbe69 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@linaro.org>
+Date: Wed, 7 Aug 2013 22:02:54 +0100
+Subject: [PATCH 1263/1302] usb: misc: usb3503: Convert to devm_ APIs
+
+Saves us a bit of code.
+
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[mszyprow: mainline commit cffedd6794bb32c4fbc03600fac61beca7950f08]
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-Id: Icffedd6794bb32c4fbc03600fac61beca7950f08
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/misc/usb3503.c | 42 +++++++-----------------------------------
+ 1 file changed, 7 insertions(+), 35 deletions(-)
+
+diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c
+index 4e3a2d2..41b4228 100644
+--- a/drivers/usb/misc/usb3503.c
++++ b/drivers/usb/misc/usb3503.c
+@@ -187,7 +187,7 @@ static int usb3503_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+       const u32 *property;
+       int len;
+-      hub = kzalloc(sizeof(struct usb3503), GFP_KERNEL);
++      hub = devm_kzalloc(&i2c->dev, sizeof(struct usb3503), GFP_KERNEL);
+       if (!hub) {
+               dev_err(&i2c->dev, "private data alloc fail\n");
+               return err;
+@@ -229,35 +229,35 @@ static int usb3503_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+       }
+       if (gpio_is_valid(hub->gpio_intn)) {
+-              err = gpio_request_one(hub->gpio_intn,
++              err = devm_gpio_request_one(&i2c->dev, hub->gpio_intn,
+                               GPIOF_OUT_INIT_HIGH, "usb3503 intn");
+               if (err) {
+                       dev_err(&i2c->dev,
+                                       "unable to request GPIO %d as connect pin (%d)\n",
+                                       hub->gpio_intn, err);
+-                      goto err_out;
++                      return err;
+               }
+       }
+       if (gpio_is_valid(hub->gpio_connect)) {
+-              err = gpio_request_one(hub->gpio_connect,
++              err = devm_gpio_request_one(&i2c->dev, hub->gpio_connect,
+                               GPIOF_OUT_INIT_HIGH, "usb3503 connect");
+               if (err) {
+                       dev_err(&i2c->dev,
+                                       "unable to request GPIO %d as connect pin (%d)\n",
+                                       hub->gpio_connect, err);
+-                      goto err_gpio_connect;
++                      return err;
+               }
+       }
+       if (gpio_is_valid(hub->gpio_reset)) {
+-              err = gpio_request_one(hub->gpio_reset,
++              err = devm_gpio_request_one(&i2c->dev, hub->gpio_reset,
+                               GPIOF_OUT_INIT_LOW, "usb3503 reset");
+               if (err) {
+                       dev_err(&i2c->dev,
+                                       "unable to request GPIO %d as reset pin (%d)\n",
+                                       hub->gpio_reset, err);
+-                      goto err_gpio_reset;
++                      return err;
+               }
+       }
+@@ -267,33 +267,6 @@ static int usb3503_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+                       (hub->mode == USB3503_MODE_HUB) ? "hub" : "standby");
+       return 0;
+-
+-err_gpio_reset:
+-      if (gpio_is_valid(hub->gpio_connect))
+-              gpio_free(hub->gpio_connect);
+-err_gpio_connect:
+-      if (gpio_is_valid(hub->gpio_intn))
+-              gpio_free(hub->gpio_intn);
+-err_out:
+-      kfree(hub);
+-
+-      return err;
+-}
+-
+-static int usb3503_remove(struct i2c_client *i2c)
+-{
+-      struct usb3503 *hub = i2c_get_clientdata(i2c);
+-
+-      if (gpio_is_valid(hub->gpio_intn))
+-              gpio_free(hub->gpio_intn);
+-      if (gpio_is_valid(hub->gpio_connect))
+-              gpio_free(hub->gpio_connect);
+-      if (gpio_is_valid(hub->gpio_reset))
+-              gpio_free(hub->gpio_reset);
+-
+-      kfree(hub);
+-
+-      return 0;
+ }
+ static const struct i2c_device_id usb3503_id[] = {
+@@ -316,7 +289,6 @@ static struct i2c_driver usb3503_driver = {
+               .of_match_table = of_match_ptr(usb3503_of_match),
+       },
+       .probe          = usb3503_probe,
+-      .remove         = usb3503_remove,
+       .id_table       = usb3503_id,
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1264-usb-misc-usb3503-Use-gpio_set_value_cansleep.patch b/patches.tizen/1264-usb-misc-usb3503-Use-gpio_set_value_cansleep.patch
new file mode 100644 (file)
index 0000000..6c3708c
--- /dev/null
@@ -0,0 +1,34 @@
+From 16231740a1003ef03fa6ec5ad7c7f9ebfbc2ecda Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@linaro.org>
+Date: Fri, 9 Aug 2013 11:41:49 +0100
+Subject: [PATCH 1264/1302] usb: misc: usb3503: Use gpio_set_value_cansleep()
+
+The /RESET GPIO is not manipulated from atomic context so support GPIOs
+that can't be written from atomic context by using _cansleep().
+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[mszyprow: mainline commit 24455b09b4838cdc0165af0f24ca63ec9ad54e44]
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-Id: I24455b09b4838cdc0165af0f24ca63ec9ad54e44
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/misc/usb3503.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c
+index 41b4228..2e9e100 100644
+--- a/drivers/usb/misc/usb3503.c
++++ b/drivers/usb/misc/usb3503.c
+@@ -103,7 +103,7 @@ static int usb3503_clear_bits(struct i2c_client *client, char reg, char req)
+ static int usb3503_reset(int gpio_reset, int state)
+ {
+       if (gpio_is_valid(gpio_reset))
+-              gpio_set_value(gpio_reset, state);
++              gpio_set_value_cansleep(gpio_reset, state);
+       /* Wait T_HUBINIT == 4ms for hub logic to stabilize */
+       if (state)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1265-usb-misc-usb3503-Actively-manage-Hub-Connect-GPIO.patch b/patches.tizen/1265-usb-misc-usb3503-Actively-manage-Hub-Connect-GPIO.patch
new file mode 100644 (file)
index 0000000..123b1ac
--- /dev/null
@@ -0,0 +1,81 @@
+From 69d693b2152e83a3ef3d94e4554e2bad1203d5b0 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@linaro.org>
+Date: Fri, 9 Aug 2013 11:41:51 +0100
+Subject: [PATCH 1265/1302] usb: misc: usb3503: Actively manage Hub Connect
+ GPIO
+
+If the connect signal is pulled high then the device will start up meaning
+that if we just pull it high on probe then the device will start running
+prior to the configuration being written out. Fix this by pulling the GPIO
+low when we reset and only pulling it high when configuration is finished.
+
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[mszyprow: mainline commit 8e7245b8386cb1dc941e10a4c97307e3f48da5da]
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-Id: I8e7245b8386cb1dc941e10a4c97307e3f48da5da
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/misc/usb3503.c | 18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c
+index 2e9e100..4b6572a 100644
+--- a/drivers/usb/misc/usb3503.c
++++ b/drivers/usb/misc/usb3503.c
+@@ -100,10 +100,13 @@ static int usb3503_clear_bits(struct i2c_client *client, char reg, char req)
+       return 0;
+ }
+-static int usb3503_reset(int gpio_reset, int state)
++static int usb3503_reset(struct usb3503 *hub, int state)
+ {
+-      if (gpio_is_valid(gpio_reset))
+-              gpio_set_value_cansleep(gpio_reset, state);
++      if (!state && gpio_is_valid(hub->gpio_connect))
++              gpio_set_value_cansleep(hub->gpio_connect, 0);
++
++      if (gpio_is_valid(hub->gpio_reset))
++              gpio_set_value_cansleep(hub->gpio_reset, state);
+       /* Wait T_HUBINIT == 4ms for hub logic to stabilize */
+       if (state)
+@@ -119,7 +122,7 @@ static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode)
+       switch (mode) {
+       case USB3503_MODE_HUB:
+-              usb3503_reset(hub->gpio_reset, 1);
++              usb3503_reset(hub, 1);
+               /* SP_ILOCK: set connect_n, config_n for config */
+               err = usb3503_write_register(i2c, USB3503_SP_ILOCK,
+@@ -156,12 +159,15 @@ static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode)
+                       goto err_hubmode;
+               }
++              if (gpio_is_valid(hub->gpio_connect))
++                      gpio_set_value_cansleep(hub->gpio_connect, 1);
++
+               hub->mode = mode;
+               dev_info(&i2c->dev, "switched to HUB mode\n");
+               break;
+       case USB3503_MODE_STANDBY:
+-              usb3503_reset(hub->gpio_reset, 0);
++              usb3503_reset(hub, 0);
+               hub->mode = mode;
+               dev_info(&i2c->dev, "switched to STANDBY mode\n");
+@@ -241,7 +247,7 @@ static int usb3503_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+       if (gpio_is_valid(hub->gpio_connect)) {
+               err = devm_gpio_request_one(&i2c->dev, hub->gpio_connect,
+-                              GPIOF_OUT_INIT_HIGH, "usb3503 connect");
++                              GPIOF_OUT_INIT_LOW, "usb3503 connect");
+               if (err) {
+                       dev_err(&i2c->dev,
+                                       "unable to request GPIO %d as connect pin (%d)\n",
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1266-usb-misc-usb3503-Convert-to-regmap.patch b/patches.tizen/1266-usb-misc-usb3503-Convert-to-regmap.patch
new file mode 100644 (file)
index 0000000..6e2ae61
--- /dev/null
@@ -0,0 +1,218 @@
+From 233ce9ba0b969d69613c9807cb5ce7351c187d9a Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@linaro.org>
+Date: Fri, 9 Aug 2013 11:41:52 +0100
+Subject: [PATCH 1266/1302] usb: misc: usb3503: Convert to regmap
+
+This will give access to the diagnostic infrastructure regmap has but
+the main point is to support future refactoring.
+
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[mszyprow: mainline commit 68b14134be55eca7340b9a8b3ec4cb8f79622a3c]
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-Id: I68b14134be55eca7340b9a8b3ec4cb8f79622a3c
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/misc/Kconfig   |  1 +
+ drivers/usb/misc/usb3503.c | 93 ++++++++++++++++++----------------------------
+ 2 files changed, 37 insertions(+), 57 deletions(-)
+
+diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
+index a51e7d6..56d5f03 100644
+--- a/drivers/usb/misc/Kconfig
++++ b/drivers/usb/misc/Kconfig
+@@ -233,5 +233,6 @@ config USB_EZUSB_FX2
+ config USB_HSIC_USB3503
+        tristate "USB3503 HSIC to USB20 Driver"
+        depends on I2C
++       select REGMAP
+        help
+          This option enables support for SMSC USB3503 HSIC to USB 2.0 Driver.
+diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c
+index 4b6572a..f2c0356 100644
+--- a/drivers/usb/misc/usb3503.c
++++ b/drivers/usb/misc/usb3503.c
+@@ -26,6 +26,7 @@
+ #include <linux/of_gpio.h>
+ #include <linux/platform_device.h>
+ #include <linux/platform_data/usb3503.h>
++#include <linux/regmap.h>
+ #define USB3503_VIDL          0x00
+ #define USB3503_VIDM          0x01
+@@ -50,56 +51,18 @@
+ #define USB3503_CFGP          0xee
+ #define USB3503_CLKSUSP               (1 << 7)
++#define USB3503_RESET         0xff
++
+ struct usb3503 {
+       enum usb3503_mode       mode;
+-      struct i2c_client       *client;
++      struct regmap           *regmap;
++      struct device           *dev;
+       u8      port_off_mask;
+       int     gpio_intn;
+       int     gpio_reset;
+       int     gpio_connect;
+ };
+-static int usb3503_write_register(struct i2c_client *client,
+-              char reg, char data)
+-{
+-      return i2c_smbus_write_byte_data(client, reg, data);
+-}
+-
+-static int usb3503_read_register(struct i2c_client *client, char reg)
+-{
+-      return i2c_smbus_read_byte_data(client, reg);
+-}
+-
+-static int usb3503_set_bits(struct i2c_client *client, char reg, char req)
+-{
+-      int err;
+-
+-      err = usb3503_read_register(client, reg);
+-      if (err < 0)
+-              return err;
+-
+-      err = usb3503_write_register(client, reg, err | req);
+-      if (err < 0)
+-              return err;
+-
+-      return 0;
+-}
+-
+-static int usb3503_clear_bits(struct i2c_client *client, char reg, char req)
+-{
+-      int err;
+-
+-      err = usb3503_read_register(client, reg);
+-      if (err < 0)
+-              return err;
+-
+-      err = usb3503_write_register(client, reg, err & ~req);
+-      if (err < 0)
+-              return err;
+-
+-      return 0;
+-}
+-
+ static int usb3503_reset(struct usb3503 *hub, int state)
+ {
+       if (!state && gpio_is_valid(hub->gpio_connect))
+@@ -117,7 +80,7 @@ static int usb3503_reset(struct usb3503 *hub, int state)
+ static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode)
+ {
+-      struct i2c_client *i2c = hub->client;
++      struct device *dev = hub->dev;
+       int err = 0;
+       switch (mode) {
+@@ -125,37 +88,40 @@ static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode)
+               usb3503_reset(hub, 1);
+               /* SP_ILOCK: set connect_n, config_n for config */
+-              err = usb3503_write_register(i2c, USB3503_SP_ILOCK,
++              err = regmap_write(hub->regmap, USB3503_SP_ILOCK,
+                               (USB3503_SPILOCK_CONNECT
+                                | USB3503_SPILOCK_CONFIG));
+               if (err < 0) {
+-                      dev_err(&i2c->dev, "SP_ILOCK failed (%d)\n", err);
++                      dev_err(dev, "SP_ILOCK failed (%d)\n", err);
+                       goto err_hubmode;
+               }
+               /* PDS : Disable For Self Powered Operation */
+               if (hub->port_off_mask) {
+-                      err = usb3503_set_bits(i2c, USB3503_PDS,
++                      err = regmap_update_bits(hub->regmap, USB3503_PDS,
++                                      hub->port_off_mask,
+                                       hub->port_off_mask);
+                       if (err < 0) {
+-                              dev_err(&i2c->dev, "PDS failed (%d)\n", err);
++                              dev_err(dev, "PDS failed (%d)\n", err);
+                               goto err_hubmode;
+                       }
+               }
+               /* CFG1 : SELF_BUS_PWR -> Self-Powerd operation */
+-              err = usb3503_set_bits(i2c, USB3503_CFG1, USB3503_SELF_BUS_PWR);
++              err = regmap_update_bits(hub->regmap, USB3503_CFG1,
++                                       USB3503_SELF_BUS_PWR,
++                                       USB3503_SELF_BUS_PWR);
+               if (err < 0) {
+-                      dev_err(&i2c->dev, "CFG1 failed (%d)\n", err);
++                      dev_err(dev, "CFG1 failed (%d)\n", err);
+                       goto err_hubmode;
+               }
+               /* SP_LOCK: clear connect_n, config_n for hub connect */
+-              err = usb3503_clear_bits(i2c, USB3503_SP_ILOCK,
+-                              (USB3503_SPILOCK_CONNECT
+-                               | USB3503_SPILOCK_CONFIG));
++              err = regmap_update_bits(hub->regmap, USB3503_SP_ILOCK,
++                                       (USB3503_SPILOCK_CONNECT
++                                        | USB3503_SPILOCK_CONFIG), 0);
+               if (err < 0) {
+-                      dev_err(&i2c->dev, "SP_ILOCK failed (%d)\n", err);
++                      dev_err(dev, "SP_ILOCK failed (%d)\n", err);
+                       goto err_hubmode;
+               }
+@@ -163,18 +129,18 @@ static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode)
+                       gpio_set_value_cansleep(hub->gpio_connect, 1);
+               hub->mode = mode;
+-              dev_info(&i2c->dev, "switched to HUB mode\n");
++              dev_info(dev, "switched to HUB mode\n");
+               break;
+       case USB3503_MODE_STANDBY:
+               usb3503_reset(hub, 0);
+               hub->mode = mode;
+-              dev_info(&i2c->dev, "switched to STANDBY mode\n");
++              dev_info(dev, "switched to STANDBY mode\n");
+               break;
+       default:
+-              dev_err(&i2c->dev, "unknown mode is request\n");
++              dev_err(dev, "unknown mode is request\n");
+               err = -EINVAL;
+               break;
+       }
+@@ -183,6 +149,13 @@ err_hubmode:
+       return err;
+ }
++static const struct regmap_config usb3503_regmap_config = {
++      .reg_bits = 8,
++      .val_bits = 8,
++
++      .max_register = USB3503_RESET,
++};
++
+ static int usb3503_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+ {
+       struct usb3503_platform_data *pdata = dev_get_platdata(&i2c->dev);
+@@ -200,7 +173,13 @@ static int usb3503_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+       }
+       i2c_set_clientdata(i2c, hub);
+-      hub->client = i2c;
++      hub->regmap = devm_regmap_init_i2c(i2c, &usb3503_regmap_config);
++      if (IS_ERR(hub->regmap)) {
++              err = PTR_ERR(hub->regmap);
++              dev_err(&i2c->dev, "Failed to initialise regmap: %d\n", err);
++              return err;
++      }
++      hub->dev = &i2c->dev;
+       if (pdata) {
+               hub->port_off_mask      = pdata->port_off_mask;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1267-usb-misc-usb3503-Factor-out-I2C-probe.patch b/patches.tizen/1267-usb-misc-usb3503-Factor-out-I2C-probe.patch
new file mode 100644 (file)
index 0000000..345808e
--- /dev/null
@@ -0,0 +1,157 @@
+From cc2217e57590563c1fd023ce1672bd7e14a0ed8c Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@linaro.org>
+Date: Fri, 9 Aug 2013 11:41:53 +0100
+Subject: [PATCH 1267/1302] usb: misc: usb3503: Factor out I2C probe
+
+In preparation for supporting operation without an I2C control interface
+factor out the I2C-specific parts of the probe routine from those that
+don't do any register I/O.
+
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[mszyprow: mainline commit 2487e3ee33dd6c4fa3dabbe11bc988883be81f1e]
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-Id: I2487e3ee33dd6c4fa3dabbe11bc988883be81f1e
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/misc/usb3503.c | 77 ++++++++++++++++++++++++++--------------------
+ 1 file changed, 43 insertions(+), 34 deletions(-)
+
+diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c
+index f2c0356..ca0f789 100644
+--- a/drivers/usb/misc/usb3503.c
++++ b/drivers/usb/misc/usb3503.c
+@@ -156,31 +156,16 @@ static const struct regmap_config usb3503_regmap_config = {
+       .max_register = USB3503_RESET,
+ };
+-static int usb3503_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
++static int usb3503_probe(struct usb3503 *hub)
+ {
+-      struct usb3503_platform_data *pdata = dev_get_platdata(&i2c->dev);
+-      struct device_node *np = i2c->dev.of_node;
+-      struct usb3503 *hub;
+-      int err = -ENOMEM;
++      struct device *dev = hub->dev;
++      struct usb3503_platform_data *pdata = dev_get_platdata(dev);
++      struct device_node *np = dev->of_node;
++      int err;
+       u32 mode = USB3503_MODE_UNKNOWN;
+       const u32 *property;
+       int len;
+-      hub = devm_kzalloc(&i2c->dev, sizeof(struct usb3503), GFP_KERNEL);
+-      if (!hub) {
+-              dev_err(&i2c->dev, "private data alloc fail\n");
+-              return err;
+-      }
+-
+-      i2c_set_clientdata(i2c, hub);
+-      hub->regmap = devm_regmap_init_i2c(i2c, &usb3503_regmap_config);
+-      if (IS_ERR(hub->regmap)) {
+-              err = PTR_ERR(hub->regmap);
+-              dev_err(&i2c->dev, "Failed to initialise regmap: %d\n", err);
+-              return err;
+-      }
+-      hub->dev = &i2c->dev;
+-
+       if (pdata) {
+               hub->port_off_mask      = pdata->port_off_mask;
+               hub->gpio_intn          = pdata->gpio_intn;
+@@ -214,46 +199,70 @@ static int usb3503_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+       }
+       if (gpio_is_valid(hub->gpio_intn)) {
+-              err = devm_gpio_request_one(&i2c->dev, hub->gpio_intn,
++              err = devm_gpio_request_one(dev, hub->gpio_intn,
+                               GPIOF_OUT_INIT_HIGH, "usb3503 intn");
+               if (err) {
+-                      dev_err(&i2c->dev,
+-                                      "unable to request GPIO %d as connect pin (%d)\n",
+-                                      hub->gpio_intn, err);
++                      dev_err(dev,
++                              "unable to request GPIO %d as connect pin (%d)\n",
++                              hub->gpio_intn, err);
+                       return err;
+               }
+       }
+       if (gpio_is_valid(hub->gpio_connect)) {
+-              err = devm_gpio_request_one(&i2c->dev, hub->gpio_connect,
++              err = devm_gpio_request_one(dev, hub->gpio_connect,
+                               GPIOF_OUT_INIT_LOW, "usb3503 connect");
+               if (err) {
+-                      dev_err(&i2c->dev,
+-                                      "unable to request GPIO %d as connect pin (%d)\n",
+-                                      hub->gpio_connect, err);
++                      dev_err(dev,
++                              "unable to request GPIO %d as connect pin (%d)\n",
++                              hub->gpio_connect, err);
+                       return err;
+               }
+       }
+       if (gpio_is_valid(hub->gpio_reset)) {
+-              err = devm_gpio_request_one(&i2c->dev, hub->gpio_reset,
++              err = devm_gpio_request_one(dev, hub->gpio_reset,
+                               GPIOF_OUT_INIT_LOW, "usb3503 reset");
+               if (err) {
+-                      dev_err(&i2c->dev,
+-                                      "unable to request GPIO %d as reset pin (%d)\n",
+-                                      hub->gpio_reset, err);
++                      dev_err(dev,
++                              "unable to request GPIO %d as reset pin (%d)\n",
++                              hub->gpio_reset, err);
+                       return err;
+               }
+       }
+       usb3503_switch_mode(hub, hub->mode);
+-      dev_info(&i2c->dev, "%s: probed on  %s mode\n", __func__,
++      dev_info(dev, "%s: probed on  %s mode\n", __func__,
+                       (hub->mode == USB3503_MODE_HUB) ? "hub" : "standby");
+       return 0;
+ }
++static int usb3503_i2c_probe(struct i2c_client *i2c,
++                           const struct i2c_device_id *id)
++{
++      struct usb3503 *hub;
++      int err;
++
++      hub = devm_kzalloc(&i2c->dev, sizeof(struct usb3503), GFP_KERNEL);
++      if (!hub) {
++              dev_err(&i2c->dev, "private data alloc fail\n");
++              return -ENOMEM;
++      }
++
++      i2c_set_clientdata(i2c, hub);
++      hub->regmap = devm_regmap_init_i2c(i2c, &usb3503_regmap_config);
++      if (IS_ERR(hub->regmap)) {
++              err = PTR_ERR(hub->regmap);
++              dev_err(&i2c->dev, "Failed to initialise regmap: %d\n", err);
++              return err;
++      }
++      hub->dev = &i2c->dev;
++
++      return usb3503_probe(hub);
++}
++
+ static const struct i2c_device_id usb3503_id[] = {
+       { USB3503_I2C_NAME, 0 },
+       { }
+@@ -273,7 +282,7 @@ static struct i2c_driver usb3503_driver = {
+               .name = USB3503_I2C_NAME,
+               .of_match_table = of_match_ptr(usb3503_of_match),
+       },
+-      .probe          = usb3503_probe,
++      .probe          = usb3503_i2c_probe,
+       .id_table       = usb3503_id,
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1268-usb-misc-usb3503-Fix-typos-in-error-messages.patch b/patches.tizen/1268-usb-misc-usb3503-Fix-typos-in-error-messages.patch
new file mode 100644 (file)
index 0000000..7ce27a4
--- /dev/null
@@ -0,0 +1,41 @@
+From cd616375589afb2aa05f24a04a1388c878a6152b Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@linaro.org>
+Date: Fri, 9 Aug 2013 11:41:54 +0100
+Subject: [PATCH 1268/1302] usb: misc: usb3503: Fix typos in error messages
+
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[mszyprow: mainline commit dd8e670d2775c02169a3b9e4c8d84c8652342836]
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-Id: Idd8e670d2775c02169a3b9e4c8d84c8652342836
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/misc/usb3503.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c
+index ca0f789..777102e0 100644
+--- a/drivers/usb/misc/usb3503.c
++++ b/drivers/usb/misc/usb3503.c
+@@ -140,7 +140,7 @@ static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode)
+               break;
+       default:
+-              dev_err(dev, "unknown mode is request\n");
++              dev_err(dev, "unknown mode is requested\n");
+               err = -EINVAL;
+               break;
+       }
+@@ -233,7 +233,7 @@ static int usb3503_probe(struct usb3503 *hub)
+       usb3503_switch_mode(hub, hub->mode);
+-      dev_info(dev, "%s: probed on  %s mode\n", __func__,
++      dev_info(dev, "%s: probed in %s mode\n", __func__,
+                       (hub->mode == USB3503_MODE_HUB) ? "hub" : "standby");
+       return 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1269-usb-misc-usb3503-Default-to-hub-mode.patch b/patches.tizen/1269-usb-misc-usb3503-Default-to-hub-mode.patch
new file mode 100644 (file)
index 0000000..3de4bce
--- /dev/null
@@ -0,0 +1,35 @@
+From f37b8f3e92134160113b4ac0c6836e382a2f49eb Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@linaro.org>
+Date: Fri, 9 Aug 2013 11:41:55 +0100
+Subject: [PATCH 1269/1302] usb: misc: usb3503: Default to hub mode
+
+Since there is no runtime interface for changing modes this is probably
+the most sensible default.
+
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[mszyprow: mainline commit e5a0c874ec7babc1931a67489b292de152d2a641]
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-Id: Ie5a0c874ec7babc1931a67489b292de152d2a641
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/usb/misc/usb3503.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c
+index 777102e0..8f5dff2 100644
+--- a/drivers/usb/misc/usb3503.c
++++ b/drivers/usb/misc/usb3503.c
+@@ -162,7 +162,7 @@ static int usb3503_probe(struct usb3503 *hub)
+       struct usb3503_platform_data *pdata = dev_get_platdata(dev);
+       struct device_node *np = dev->of_node;
+       int err;
+-      u32 mode = USB3503_MODE_UNKNOWN;
++      u32 mode = USB3503_MODE_HUB;
+       const u32 *property;
+       int len;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1270-usb-misc-usb3503-Add-USB3503A-to-the-compatible-list.patch b/patches.tizen/1270-usb-misc-usb3503-Add-USB3503A-to-the-compatible-list.patch
new file mode 100644 (file)
index 0000000..3e91d6d
--- /dev/null
@@ -0,0 +1,50 @@
+From 001a91293536afa9edb533b08ce223d553fae397 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@linaro.org>
+Date: Fri, 9 Aug 2013 11:41:56 +0100
+Subject: [PATCH 1270/1302] usb: misc: usb3503: Add USB3503A to the compatible
+ list
+
+There are no software visible differences that I am aware of but in case
+any are discovered allow the DTS to specify exactly which device is
+present.
+
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[mszyprow: mainline commit 5bdd1f4a1daf398042203b72430891dfc40c0fa6]
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-Id: I5bdd1f4a1daf398042203b72430891dfc40c0fa6
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/devicetree/bindings/usb/usb3503.txt | 2 +-
+ drivers/usb/misc/usb3503.c                        | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/Documentation/devicetree/bindings/usb/usb3503.txt b/Documentation/devicetree/bindings/usb/usb3503.txt
+index 8c5be48..cd60f7e 100644
+--- a/Documentation/devicetree/bindings/usb/usb3503.txt
++++ b/Documentation/devicetree/bindings/usb/usb3503.txt
+@@ -1,7 +1,7 @@
+ SMSC USB3503 High-Speed Hub Controller
+ Required properties:
+-- compatible: Should be "smsc,usb3503".
++- compatible: Should be "smsc,usb3503" or "smsc,usb3503a".
+ - reg: Specifies the i2c slave address, it should be 0x08.
+ - connect-gpios: Should specify GPIO for connect.
+ - disabled-ports: Should specify the ports unused.
+diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c
+index 8f5dff2..da45ed9 100644
+--- a/drivers/usb/misc/usb3503.c
++++ b/drivers/usb/misc/usb3503.c
+@@ -272,6 +272,7 @@ MODULE_DEVICE_TABLE(i2c, usb3503_id);
+ #ifdef CONFIG_OF
+ static const struct of_device_id usb3503_of_match[] = {
+       { .compatible = "smsc,usb3503", },
++      { .compatible = "smsc,usb3503a", },
+       {},
+ };
+ MODULE_DEVICE_TABLE(of, usb3503_of_match);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1271-usb-misc-usb3503-Support-operation-with-no-I2C-contr.patch b/patches.tizen/1271-usb-misc-usb3503-Support-operation-with-no-I2C-contr.patch
new file mode 100644 (file)
index 0000000..2434b90
--- /dev/null
@@ -0,0 +1,216 @@
+From 37ca4e6bcc0da456e094ed323020963bcea7cef0 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@linaro.org>
+Date: Fri, 9 Aug 2013 11:41:58 +0100
+Subject: [PATCH 1271/1302] usb: misc: usb3503: Support operation with no I2C
+ control
+
+Refactor so that register writes for configuration are only performed if
+the device has a regmap provided and also register as a platform driver.
+This allows the driver to be used to manage GPIO based control of the
+device.
+
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Cc: devicetree@vger.kernel.org
+Reviewed-by: Dongjin Kim <tobetter@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[mszyprow: mainline commit 3f0d1c67fa20d524fdcb4a7dcda19ed76c59be44]
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-Id: I3f0d1c67fa20d524fdcb4a7dcda19ed76c59be44
+
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ Documentation/devicetree/bindings/usb/usb3503.txt |  5 +-
+ drivers/usb/misc/usb3503.c                        | 93 ++++++++++++++++++-----
+ 2 files changed, 80 insertions(+), 18 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/usb/usb3503.txt b/Documentation/devicetree/bindings/usb/usb3503.txt
+index cd60f7e..a018da4 100644
+--- a/Documentation/devicetree/bindings/usb/usb3503.txt
++++ b/Documentation/devicetree/bindings/usb/usb3503.txt
+@@ -2,7 +2,10 @@ SMSC USB3503 High-Speed Hub Controller
+ Required properties:
+ - compatible: Should be "smsc,usb3503" or "smsc,usb3503a".
+-- reg: Specifies the i2c slave address, it should be 0x08.
++
++Optional properties:
++- reg: Specifies the i2c slave address, it is required and should be 0x08
++       if I2C is used.
+ - connect-gpios: Should specify GPIO for connect.
+ - disabled-ports: Should specify the ports unused.
+       '1' or '2' or '3' are availe for this property to describe the port
+diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c
+index da45ed9..a31641e 100644
+--- a/drivers/usb/misc/usb3503.c
++++ b/drivers/usb/misc/usb3503.c
+@@ -78,22 +78,21 @@ static int usb3503_reset(struct usb3503 *hub, int state)
+       return 0;
+ }
+-static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode)
++static int usb3503_connect(struct usb3503 *hub)
+ {
+       struct device *dev = hub->dev;
+-      int err = 0;
++      int err;
+-      switch (mode) {
+-      case USB3503_MODE_HUB:
+-              usb3503_reset(hub, 1);
++      usb3503_reset(hub, 1);
++      if (hub->regmap) {
+               /* SP_ILOCK: set connect_n, config_n for config */
+               err = regmap_write(hub->regmap, USB3503_SP_ILOCK,
+-                              (USB3503_SPILOCK_CONNECT
++                         (USB3503_SPILOCK_CONNECT
+                                | USB3503_SPILOCK_CONFIG));
+               if (err < 0) {
+                       dev_err(dev, "SP_ILOCK failed (%d)\n", err);
+-                      goto err_hubmode;
++                      return err;
+               }
+               /* PDS : Disable For Self Powered Operation */
+@@ -103,7 +102,7 @@ static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode)
+                                       hub->port_off_mask);
+                       if (err < 0) {
+                               dev_err(dev, "PDS failed (%d)\n", err);
+-                              goto err_hubmode;
++                              return err;
+                       }
+               }
+@@ -113,7 +112,7 @@ static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode)
+                                        USB3503_SELF_BUS_PWR);
+               if (err < 0) {
+                       dev_err(dev, "CFG1 failed (%d)\n", err);
+-                      goto err_hubmode;
++                      return err;
+               }
+               /* SP_LOCK: clear connect_n, config_n for hub connect */
+@@ -122,14 +121,27 @@ static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode)
+                                         | USB3503_SPILOCK_CONFIG), 0);
+               if (err < 0) {
+                       dev_err(dev, "SP_ILOCK failed (%d)\n", err);
+-                      goto err_hubmode;
++                      return err;
+               }
++      }
+-              if (gpio_is_valid(hub->gpio_connect))
+-                      gpio_set_value_cansleep(hub->gpio_connect, 1);
++      if (gpio_is_valid(hub->gpio_connect))
++              gpio_set_value_cansleep(hub->gpio_connect, 1);
+-              hub->mode = mode;
+-              dev_info(dev, "switched to HUB mode\n");
++      hub->mode = USB3503_MODE_HUB;
++      dev_info(dev, "switched to HUB mode\n");
++
++      return 0;
++}
++
++static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode)
++{
++      struct device *dev = hub->dev;
++      int err = 0;
++
++      switch (mode) {
++      case USB3503_MODE_HUB:
++              err = usb3503_connect(hub);
+               break;
+       case USB3503_MODE_STANDBY:
+@@ -145,7 +157,6 @@ static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode)
+               break;
+       }
+-err_hubmode:
+       return err;
+ }
+@@ -198,6 +209,9 @@ static int usb3503_probe(struct usb3503 *hub)
+               hub->mode = mode;
+       }
++      if (hub->port_off_mask && !hub->regmap)
++              dev_err(dev, "Ports disabled with no control interface\n");
++
+       if (gpio_is_valid(hub->gpio_intn)) {
+               err = devm_gpio_request_one(dev, hub->gpio_intn,
+                               GPIOF_OUT_INIT_HIGH, "usb3503 intn");
+@@ -263,6 +277,20 @@ static int usb3503_i2c_probe(struct i2c_client *i2c,
+       return usb3503_probe(hub);
+ }
++static int usb3503_platform_probe(struct platform_device *pdev)
++{
++      struct usb3503 *hub;
++
++      hub = devm_kzalloc(&pdev->dev, sizeof(struct usb3503), GFP_KERNEL);
++      if (!hub) {
++              dev_err(&pdev->dev, "private data alloc fail\n");
++              return -ENOMEM;
++      }
++      hub->dev = &pdev->dev;
++
++      return usb3503_probe(hub);
++}
++
+ static const struct i2c_device_id usb3503_id[] = {
+       { USB3503_I2C_NAME, 0 },
+       { }
+@@ -278,7 +306,7 @@ static const struct of_device_id usb3503_of_match[] = {
+ MODULE_DEVICE_TABLE(of, usb3503_of_match);
+ #endif
+-static struct i2c_driver usb3503_driver = {
++static struct i2c_driver usb3503_i2c_driver = {
+       .driver = {
+               .name = USB3503_I2C_NAME,
+               .of_match_table = of_match_ptr(usb3503_of_match),
+@@ -287,7 +315,38 @@ static struct i2c_driver usb3503_driver = {
+       .id_table       = usb3503_id,
+ };
+-module_i2c_driver(usb3503_driver);
++static struct platform_driver usb3503_platform_driver = {
++      .driver = {
++              .name = USB3503_I2C_NAME,
++              .of_match_table = of_match_ptr(usb3503_of_match),
++              .owner = THIS_MODULE,
++      },
++      .probe          = usb3503_platform_probe,
++};
++
++static int __init usb3503_init(void)
++{
++      int err;
++
++      err = i2c_register_driver(THIS_MODULE, &usb3503_i2c_driver);
++      if (err != 0)
++              pr_err("usb3503: Failed to register I2C driver: %d\n", err);
++
++      err = platform_driver_register(&usb3503_platform_driver);
++      if (err != 0)
++              pr_err("usb3503: Failed to register platform driver: %d\n",
++                     err);
++
++      return 0;
++}
++module_init(usb3503_init);
++
++static void __exit usb3503_exit(void)
++{
++      platform_driver_unregister(&usb3503_platform_driver);
++      i2c_del_driver(&usb3503_i2c_driver);
++}
++module_exit(usb3503_exit);
+ MODULE_AUTHOR("Dongjin Kim <tobetter@gmail.com>");
+ MODULE_DESCRIPTION("USB3503 USB HUB driver");
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1272-drivers-power-hide-some-excessive-debugs.patch b/patches.tizen/1272-drivers-power-hide-some-excessive-debugs.patch
new file mode 100644 (file)
index 0000000..ee80424
--- /dev/null
@@ -0,0 +1,51 @@
+From a7b567ec118f3845b2a9d9eef4aafd7a9aca4488 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Tue, 4 Mar 2014 08:17:46 +0100
+Subject: [PATCH 1272/1302] drivers: power: hide some excessive debugs
+
+Hide following excessive debug messages, which are really not helpful
+for anything:
+device xyz: start latency exceeded, new value XXX ns
+device xyz: state restore latency exceeded, new value YYY ns
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-Id: Idab765ebd307ac40af1a556c0b08e26938a1c9cf
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/base/power/domain.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
+index 7072404..0c1e841 100644
+--- a/drivers/base/power/domain.c
++++ b/drivers/base/power/domain.c
+@@ -42,7 +42,7 @@
+       struct gpd_timing_data *__td = &dev_gpd_data(dev)->td;                  \
+       if (!__retval && __elapsed > __td->field) {                             \
+               __td->field = __elapsed;                                        \
+-              dev_warn(dev, name " latency exceeded, new value %lld ns\n",    \
++              dev_dbg(dev, name " latency exceeded, new value %lld ns\n",     \
+                       __elapsed);                                             \
+               genpd->max_off_time_changed = true;                             \
+               __td->constraint_changed = true;                                \
+@@ -242,7 +242,7 @@ static int __pm_genpd_poweron(struct generic_pm_domain *genpd)
+                       genpd->max_off_time_changed = true;
+                       genpd_recalc_cpu_exit_latency(genpd);
+                       if (genpd->name)
+-                              pr_warning("%s: Power-on latency exceeded, "
++                              pr_debug("%s: Power-on latency exceeded, "
+                                       "new value %lld ns\n", genpd->name,
+                                       elapsed_ns);
+               }
+@@ -566,7 +566,7 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
+                       genpd->power_off_latency_ns = elapsed_ns;
+                       genpd->max_off_time_changed = true;
+                       if (genpd->name)
+-                              pr_warning("%s: Power-off latency exceeded, "
++                              pr_debug("%s: Power-off latency exceeded, "
+                                       "new value %lld ns\n", genpd->name,
+                                       elapsed_ns);
+               }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1273-iio-common-st-Prevent-disable-after-read-info-raw-da.patch b/patches.tizen/1273-iio-common-st-Prevent-disable-after-read-info-raw-da.patch
new file mode 100644 (file)
index 0000000..c48f715
--- /dev/null
@@ -0,0 +1,37 @@
+From 578c3f5aacf4d7bcd6d54739a3c5da25acae452b Mon Sep 17 00:00:00 2001
+From: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Date: Wed, 5 Mar 2014 08:52:56 +0100
+Subject: [PATCH 1273/1302] iio:common:st: Prevent disable after read info raw
+ data
+
+This patch prevents disable sensor after read info raw data when
+events are enabled.
+
+Change-Id: Ifc160e7aa5a633c5dc976ea8b775a790a0efaf69
+Signed-off-by: Lukasz Czerwinski <l.czerwinski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/iio/common/st_sensors/st_sensors_core.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c
+index 53fbc50..085eb7d 100644
+--- a/drivers/iio/common/st_sensors/st_sensors_core.c
++++ b/drivers/iio/common/st_sensors/st_sensors_core.c
+@@ -315,7 +315,12 @@ int st_sensors_read_info_raw(struct iio_dev *indio_dev,
+               *val = *val >> ch->scan_type.shift;
+-              err = st_sensors_set_enable(indio_dev, false);
++              /*
++                * When events are enabled sensor should be always enabled.
++                * It prevents unnecessary sensor off.
++                */
++                if (!sdata->events_flag)
++                      err = st_sensors_set_enable(indio_dev, false);
+       }
+       mutex_unlock(&indio_dev->mlock);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1274-cpufreq-LAB-Kconfig-Make-LAB-dependent-on-the-ONDEMA.patch b/patches.tizen/1274-cpufreq-LAB-Kconfig-Make-LAB-dependent-on-the-ONDEMA.patch
new file mode 100644 (file)
index 0000000..eb3326b
--- /dev/null
@@ -0,0 +1,42 @@
+From 448d0110b8916758b6b6c9af07fc8f4b30f56de6 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Wed, 26 Feb 2014 13:53:23 +0100
+Subject: [PATCH 1274/1302] cpufreq:LAB:Kconfig: Make LAB dependent on the
+ ONDEMAND governor
+
+The LAB is supposed to be an extension of the ONDEMAND governor.
+For this reason it shall be not possible to compile in LAB without
+ONDEMAND in the system.
+
+Change-Id: I8c9e46b535bb7452782c21163703a4e73bdaf96d
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/Kconfig | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
+index 9ee9d3c..4e11aac 100644
+--- a/drivers/cpufreq/Kconfig
++++ b/drivers/cpufreq/Kconfig
+@@ -214,13 +214,15 @@ config CPU_FREQ_GOV_LAB
+       tristate "'lab' cpufreq policy governor"
+       select CPU_FREQ_TABLE
+       select CPU_FREQ_GOV_COMMON
++      select CPU_FREQ_GOV_ONDEMAND
+       help
+         'lab' - This driver adds a dynamic cpufreq policy governor.
+         To compile this driver as a module, choose M here: the
+-        module will be called cpufreq_ondemand.
++        module will be called cpufreq_lab.
+-        For details, take a look at linux/Documentation/cpu-freq.
++        LAB governor shall be regarded as an extension of the ONDEMAND on
++        platforms with very weak HW support for power management.
+         If in doubt, say N.
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1275-cpufreq-LAB-Kconfig-Do-not-allow-LAB-to-be-build-as-.patch b/patches.tizen/1275-cpufreq-LAB-Kconfig-Do-not-allow-LAB-to-be-build-as-.patch
new file mode 100644 (file)
index 0000000..b69eae8
--- /dev/null
@@ -0,0 +1,47 @@
+From c0487c2bfff971f598ce8f2f7453ff375ed55415 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Thu, 27 Feb 2014 13:38:51 +0100
+Subject: [PATCH 1275/1302] cpufreq:LAB:Kconfig: Do not allow LAB to be build
+ as a module
+
+Since LAB depends on ONDEMAND, one needs to prevent situation when both
+governors are compiled as modules.
+
+Change-Id: I5e4f65a856d548397ef53338a8949879bd34051c
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/Kconfig | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
+index 4e11aac..08fbc96 100644
+--- a/drivers/cpufreq/Kconfig
++++ b/drivers/cpufreq/Kconfig
+@@ -211,19 +211,19 @@ config CPU_FREQ_GOV_CONSERVATIVE
+         If in doubt, say N.
+ config CPU_FREQ_GOV_LAB
+-      tristate "'lab' cpufreq policy governor"
++      bool "'lab' cpufreq policy governor - ONDEMAND extension"
+       select CPU_FREQ_TABLE
+       select CPU_FREQ_GOV_COMMON
+       select CPU_FREQ_GOV_ONDEMAND
+       help
+         'lab' - This driver adds a dynamic cpufreq policy governor.
+-        To compile this driver as a module, choose M here: the
+-        module will be called cpufreq_lab.
+-
+         LAB governor shall be regarded as an extension of the ONDEMAND on
+         platforms with very weak HW support for power management.
++        LAB governor can be either compiled in or not. It is not possible to
++        compile it as module because of explicit ONDEMAND dependency.
++
+         If in doubt, say N.
+ config GENERIC_CPUFREQ_CPU0
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1276-cpufreq-LAB-core-Remove-code-responsible-for-removin.patch b/patches.tizen/1276-cpufreq-LAB-core-Remove-code-responsible-for-removin.patch
new file mode 100644 (file)
index 0000000..7e959cf
--- /dev/null
@@ -0,0 +1,40 @@
+From 18bc5c759869d40cb58e172a53df99eaed3c494d Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Thu, 27 Feb 2014 10:01:03 +0100
+Subject: [PATCH 1276/1302] cpufreq:LAB:core: Remove code responsible for
+ removing LAB module
+
+Since we don't support LAB compiled in as module this code shall be
+regarded as a dead one.
+
+Change-Id: I8aba33449e08aabed38393e15519f30ccf27ab0f
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/cpufreq_lab.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/drivers/cpufreq/cpufreq_lab.c b/drivers/cpufreq/cpufreq_lab.c
+index 28f4932..8549be2 100644
+--- a/drivers/cpufreq/cpufreq_lab.c
++++ b/drivers/cpufreq/cpufreq_lab.c
+@@ -365,11 +365,6 @@ static int __init cpufreq_gov_dbs_init(void)
+       return cpufreq_register_governor(&cpufreq_gov_lab);
+ }
+-static void __exit cpufreq_gov_dbs_exit(void)
+-{
+-      cpufreq_unregister_governor(&cpufreq_gov_lab);
+-}
+-
+ MODULE_AUTHOR("Jonghwa Lee <jonghwa3.lee@samsung.com>");
+ MODULE_AUTHOR("Lukasz Majewski <l.majewski@samsung.com>");
+ MODULE_DESCRIPTION("'cpufreq_lab' - A dynamic cpufreq governor for "
+@@ -381,4 +376,3 @@ fs_initcall(cpufreq_gov_dbs_init);
+ #else
+ module_init(cpufreq_gov_dbs_init);
+ #endif
+-module_exit(cpufreq_gov_dbs_exit);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1277-cpufreq-LAB-ondemand-REMOVE-from-LAB-governor-code-d.patch b/patches.tizen/1277-cpufreq-LAB-ondemand-REMOVE-from-LAB-governor-code-d.patch
new file mode 100644 (file)
index 0000000..07689de
--- /dev/null
@@ -0,0 +1,201 @@
+From fce38954de801f6761e468d6df2f4b40e48f4289 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Wed, 26 Feb 2014 14:07:17 +0100
+Subject: [PATCH 1277/1302] cpufreq:LAB:ondemand: REMOVE from LAB governor code
+ duplicated at ondemand
+
+LAB is very similar to ondemand governor in its structure.
+Both use the same code for:
+- governor init and exit
+- demand based switching timer code
+- governor specific ops
+
+In this way the LAB can be stacked on top of ondemand governor and hence it
+is possible to reuse its logic when needed.
+
+Change-Id: I78e0da90bb2f07677fe6f8d451139107994f5a6f
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/cpufreq_governor.h |  8 ++++
+ drivers/cpufreq/cpufreq_lab.c      | 77 ++------------------------------------
+ drivers/cpufreq/cpufreq_ondemand.c | 10 ++---
+ 3 files changed, 17 insertions(+), 78 deletions(-)
+
+diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h
+index 3886a18..2387f38 100644
+--- a/drivers/cpufreq/cpufreq_governor.h
++++ b/drivers/cpufreq/cpufreq_governor.h
+@@ -284,4 +284,12 @@ void od_register_powersave_bias_handler(unsigned int (*f)
+               (struct cpufreq_policy *, unsigned int, unsigned int),
+               unsigned int powersave_bias);
+ void od_unregister_powersave_bias_handler(void);
++
++/* COMMON CODE FOR DEMAND BASED SWITCHING */
++void od_dbs_timer(struct work_struct *work);
++int od_init(struct dbs_data *dbs_data);
++void od_exit(struct dbs_data *dbs_data);
++
++extern struct od_ops od_ops;
++
+ #endif /* _CPUFREQ_GOVERNOR_H */
+diff --git a/drivers/cpufreq/cpufreq_lab.c b/drivers/cpufreq/cpufreq_lab.c
+index 8549be2..e9aa1c9 100644
+--- a/drivers/cpufreq/cpufreq_lab.c
++++ b/drivers/cpufreq/cpufreq_lab.c
+@@ -150,35 +150,6 @@ static void lb_check_cpu(int cpu, unsigned int load_freq)
+       dbs_freq_increase(policy, freq);
+ }
+-static void lb_dbs_timer(struct work_struct *work)
+-{
+-      struct lb_cpu_dbs_info_s *dbs_info =
+-              container_of(work, struct lb_cpu_dbs_info_s, cdbs.work.work);
+-      unsigned int cpu = dbs_info->cdbs.cur_policy->cpu;
+-      struct lb_cpu_dbs_info_s *core_dbs_info = &per_cpu(lb_cpu_dbs_info,
+-                      cpu);
+-      struct dbs_data *dbs_data = dbs_info->cdbs.cur_policy->governor_data;
+-      struct lb_dbs_tuners *lb_tuners = dbs_data->tuners;
+-      int delay;
+-
+-      /* Enable overclocking always for LAB governor */
+-      if (cpufreq_boost_supported() && unlikely(!cpufreq_boost_enabled())) {
+-              /* To avoid deadlock, mutex_lock() is called
+-               * after cpufreq_boost_trigger_state().
+-               */
+-              cpufreq_boost_trigger_state(1);
+-              mutex_lock(&core_dbs_info->cdbs.timer_mutex);
+-      } else {
+-              mutex_lock(&core_dbs_info->cdbs.timer_mutex);
+-              dbs_check_cpu(dbs_data, cpu);
+-      }
+-
+-      delay = delay_for_sampling_rate(lb_tuners->sampling_rate
+-                                              * core_dbs_info->rate_mult);
+-      gov_queue_work(dbs_data, dbs_info->cdbs.cur_policy, delay, false);
+-      mutex_unlock(&core_dbs_info->cdbs.timer_mutex);
+-}
+-
+ /************************** sysfs interface ************************/
+ static struct common_dbs_data lb_dbs_cdata;
+@@ -283,53 +254,12 @@ static struct attribute_group lb_attr_group_gov_pol = {
+ static int lb_init(struct dbs_data *dbs_data)
+ {
+-      struct lb_dbs_tuners *tuners;
+-      u64 idle_time;
+-      int cpu;
+-      tuners = kzalloc(sizeof(struct lb_dbs_tuners), GFP_KERNEL);
+-      if (!tuners) {
+-              pr_err("%s: kzalloc failed\n", __func__);
+-              return -ENOMEM;
+-      }
++      od_init(dbs_data);
+-      cpu = get_cpu();
+-      idle_time = get_cpu_idle_time_us(cpu, NULL);
+-      put_cpu();
+-      if (idle_time != -1ULL) {
+-              /* Idle micro accounting is supported. Use finer thresholds */
+-              tuners->up_threshold = MICRO_FREQUENCY_UP_THRESHOLD;
+-              tuners->adj_up_threshold = MICRO_FREQUENCY_UP_THRESHOLD -
+-                      MICRO_FREQUENCY_DOWN_DIFFERENTIAL;
+-              /*
+-               * In nohz/micro accounting case we set the minimum frequency
+-               * not depending on HZ, but fixed (very low). The deferred
+-               * timer might skip some samples if idle/sleeping as needed.
+-              */
+-              dbs_data->min_sampling_rate = MICRO_FREQUENCY_MIN_SAMPLE_RATE;
+-      } else {
+-              tuners->up_threshold = DEF_FREQUENCY_UP_THRESHOLD;
+-              tuners->adj_up_threshold = DEF_FREQUENCY_UP_THRESHOLD -
+-                      DEF_FREQUENCY_DOWN_DIFFERENTIAL;
+-
+-              /* For correct statistics, we need 10 ticks for each measure */
+-              dbs_data->min_sampling_rate = MIN_SAMPLING_RATE_RATIO *
+-                      jiffies_to_usecs(10);
+-      }
+-
+-      tuners->sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR;
+-      tuners->ignore_nice = 0;
+-
+-      dbs_data->tuners = tuners;
+-      mutex_init(&dbs_data->mutex);
+       return 0;
+ }
+-static void lb_exit(struct dbs_data *dbs_data)
+-{
+-      kfree(dbs_data->tuners);
+-}
+-
+ define_get_cpu_dbs_routines(lb_cpu_dbs_info);
+ static struct common_dbs_data lb_dbs_cdata = {
+@@ -338,10 +268,11 @@ static struct common_dbs_data lb_dbs_cdata = {
+       .attr_group_gov_pol = &lb_attr_group_gov_pol,
+       .get_cpu_cdbs = get_cpu_cdbs,
+       .get_cpu_dbs_info_s = get_cpu_dbs_info_s,
+-      .gov_dbs_timer = lb_dbs_timer,
++      .gov_dbs_timer = od_dbs_timer,
+       .gov_check_cpu = lb_check_cpu,
++      .gov_ops = &od_ops,
+       .init = lb_init,
+-      .exit = lb_exit,
++      .exit = od_exit,
+ };
+ static int lb_cpufreq_governor_dbs(struct cpufreq_policy *policy,
+diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
+index 25438bb..d49855d 100644
+--- a/drivers/cpufreq/cpufreq_ondemand.c
++++ b/drivers/cpufreq/cpufreq_ondemand.c
+@@ -39,7 +39,7 @@
+ static DEFINE_PER_CPU(struct od_cpu_dbs_info_s, od_cpu_dbs_info);
+-static struct od_ops od_ops;
++struct od_ops od_ops;
+ #ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND
+ static struct cpufreq_governor cpufreq_gov_ondemand;
+@@ -202,7 +202,7 @@ static void od_check_cpu(int cpu, unsigned int load)
+       }
+ }
+-static void od_dbs_timer(struct work_struct *work)
++void od_dbs_timer(struct work_struct *work)
+ {
+       struct od_cpu_dbs_info_s *dbs_info =
+               container_of(work, struct od_cpu_dbs_info_s, cdbs.work.work);
+@@ -486,7 +486,7 @@ static struct attribute_group od_attr_group_gov_pol = {
+ /************************** sysfs end ************************/
+-static int od_init(struct dbs_data *dbs_data)
++int od_init(struct dbs_data *dbs_data)
+ {
+       struct od_dbs_tuners *tuners;
+       u64 idle_time;
+@@ -528,14 +528,14 @@ static int od_init(struct dbs_data *dbs_data)
+       return 0;
+ }
+-static void od_exit(struct dbs_data *dbs_data)
++void od_exit(struct dbs_data *dbs_data)
+ {
+       kfree(dbs_data->tuners);
+ }
+ define_get_cpu_dbs_routines(od_cpu_dbs_info);
+-static struct od_ops od_ops = {
++struct od_ops od_ops = {
+       .powersave_bias_init_cpu = ondemand_powersave_bias_init_cpu,
+       .powersave_bias_target = generic_powersave_bias_target,
+       .freq_increase = dbs_freq_increase,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1278-cpufreq-LAB-core-Redesign-of-LAB-code-to-work-on-top.patch b/patches.tizen/1278-cpufreq-LAB-core-Redesign-of-LAB-code-to-work-on-top.patch
new file mode 100644 (file)
index 0000000..db00f94
--- /dev/null
@@ -0,0 +1,547 @@
+From d0d76bc032020d557d5596b211983f487ac9df38 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Thu, 27 Feb 2014 13:30:06 +0100
+Subject: [PATCH 1278/1302] cpufreq:LAB:core: Redesign of LAB code to work on
+ top of ONDEMAND governor
+
+The code for LAB has been redesigned to be able to work on top of Ondemand
+governor.
+Previous version of LAB - the one which used the polynomial approximation
+has been replaced with more readable approach.
+The LAB control approach is now read from device tree.
+
+User is allowed to specify following operations (based on load and number of
+idle CPUs):
+- Force a particular frequency
+- Explicitly enable boost for a specific kind of load
+- Use ondemand governor
+
+By using ondemand one can be sure that for non critical frequencies correct
+value will be chosen.
+LAB, which works on top of it, can clamp the freq (an thereof power management)
+or explicitly enable boost.
+
+Change-Id: Ieaf84d245463edf90fb2baaf825c0534970eab7e
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/cpufreq_governor.h |   1 +
+ drivers/cpufreq/cpufreq_lab.c      | 370 +++++++++++++++++++++++--------------
+ 2 files changed, 231 insertions(+), 140 deletions(-)
+
+diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h
+index 2387f38..a3cf7a8 100644
+--- a/drivers/cpufreq/cpufreq_governor.h
++++ b/drivers/cpufreq/cpufreq_governor.h
+@@ -153,6 +153,7 @@ struct od_cpu_dbs_info_s {
+       unsigned int freq_lo_jiffies;
+       unsigned int freq_hi_jiffies;
+       unsigned int rate_mult;
++      unsigned int idle_time;
+       unsigned int sample_type:1;
+ };
+diff --git a/drivers/cpufreq/cpufreq_lab.c b/drivers/cpufreq/cpufreq_lab.c
+index e9aa1c9..8939a6e 100644
+--- a/drivers/cpufreq/cpufreq_lab.c
++++ b/drivers/cpufreq/cpufreq_lab.c
+@@ -1,19 +1,16 @@
+ /*
+- *  drivers/cpufreq/cpufreq_lab.c
+- *
+- *  LAB(Legacy Application Boost) cpufreq governor
+- *
+- *  Copyright (C) SAMSUNG Electronics. CO.
++ * Copyright (c) 2013-2014 Samsung Electronics Co., Ltd.
++ *            http://www.samsung.com
+  *            Jonghwa Lee <jonghw3.lee@samusng.com>
+  *            Lukasz Majewski <l.majewski@samsung.com>
+  *
++ * LAB (Legacy Application Boost) cpufreq governor
++ *
+  * 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.
+  */
+-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+-
+ #include <linux/cpufreq.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+@@ -27,19 +24,15 @@
+ #include <linux/types.h>
+ #include <linux/cpuidle.h>
+ #include <linux/slab.h>
++#include <linux/of.h>
+ #include "cpufreq_governor.h"
+-#define DEF_FREQUENCY_DOWN_DIFFERENTIAL               (10)
+-#define DEF_FREQUENCY_UP_THRESHOLD            (80)
+-#define DEF_SAMPLING_DOWN_FACTOR              (1)
+-#define MICRO_FREQUENCY_DOWN_DIFFERENTIAL     (3)
+-#define MICRO_FREQUENCY_UP_THRESHOLD          (95)
+-#define MICRO_FREQUENCY_MIN_SAMPLE_RATE               (10000)
+-
+ #define MAX_HIST              5
+-#define FREQ_STEP             50000
+-#define IDLE_THRESHOLD                90
++
++#define LB_BOOST_ENABLE        ~0UL
++#define LB_MIN_FREQ            ~1UL
++#define LB_ONDEMAND             0
+ /* Pre-calculated summation of weight, 0.5
+  * 1
+@@ -52,29 +45,21 @@ static int history_weight_sum[] = { 100, 150, 175, 187, 193 };
+ static unsigned int idle_avg[NR_CPUS];
+ static unsigned int idle_hist[NR_CPUS][MAX_HIST];
++static int idle_cpus, lb_threshold = 90;
++static unsigned int *lb_ctrl_table, lb_load;
++static int lb_ctrl_table_size, lb_num_of_states;
++static bool boost_init_state;
+-static DEFINE_PER_CPU(struct lb_cpu_dbs_info_s, lb_cpu_dbs_info);
++static DECLARE_BITMAP(boost_hist, MAX_HIST);
++static DEFINE_PER_CPU(struct od_cpu_dbs_info_s, od_cpu_dbs_info);
+-#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_LAB
+-static struct cpufreq_governor cpufreq_gov_lab;
+-#endif
++struct cpufreq_governor cpufreq_gov_lab;
+-/* Single polynomial approx -> all CPUs busy */
+-static int a_all = -6, b_all = 1331;
+-/* Single polynomial approx -> one CPUs busy */
+-static int a_one = 10, b_one = 205;
+-/* Single polynomial approx -> 2,3... CPUs busy */
+-static int a_rest = 4, b_rest1 = 100, b_rest2 = 300;
+-/* Polynomial divider */
+-static int poly_div = 1024;
+-static void dbs_freq_increase(struct cpufreq_policy *p, unsigned int freq)
+-{
+-      if (p->cur == freq)
+-              return;
+-
+-      __cpufreq_driver_target(p, freq, CPUFREQ_RELATION_L);
+-}
++static struct lb_wq_boost_data {
++      bool state;
++      struct work_struct work;
++} lb_boost_data;
+ /* Calculate average of idle time with weighting 50% less to older one.
+  * With weight, average can be affected by current phase more rapidly than
+@@ -96,142 +81,174 @@ static inline int cpu_idle_calc_avg(unsigned int *p, int size)
+       return (int) (sum / history_weight_sum[size - 1]);
+ }
++static unsigned int lb_chose_freq(unsigned int load, int idle_cpus)
++{
++      unsigned int p, q = 100 / lb_num_of_states;
++      int idx;
++
++      for (idx = 0, p = q; idx < lb_num_of_states; idx++, p += q)
++              if (load <= p)
++                      break;
++
++      return *(lb_ctrl_table + (lb_num_of_states * idle_cpus) + idx);
++}
++
++static void lb_cpufreq_boost_work(struct work_struct *work)
++{
++      struct lb_wq_boost_data *d = container_of(work,
++                                                struct lb_wq_boost_data,
++                                                work);
++      cpufreq_boost_trigger_state(d->state);
++}
++
++static struct common_dbs_data lb_dbs_cdata;
+ /*
+  * LAB governor policy adjustement
+  */
+-static void lb_check_cpu(int cpu, unsigned int load_freq)
++static void lb_check_cpu(int cpu, unsigned int load)
+ {
+-      struct lb_cpu_dbs_info_s *dbs_info = &per_cpu(lb_cpu_dbs_info, cpu);
++      struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu);
+       struct cpufreq_policy *policy = dbs_info->cdbs.cur_policy;
+-      int i, idx, idle_cpus = 0, b = 0;
++      unsigned int freq = 0, op;
+       static int cnt = 0;
+-      unsigned int freq = 0;
++      int i, idx, bs;
++      idle_cpus = 0;
++      lb_load = load;
+       idx = cnt++ % MAX_HIST;
+       for_each_possible_cpu(i) {
+-              struct lb_cpu_dbs_info_s *dbs_cpu_info =
+-                      &per_cpu(lb_cpu_dbs_info, i);
++              struct od_cpu_dbs_info_s *dbs_cpu_info =
++                      &per_cpu(od_cpu_dbs_info, i);
+               idle_hist[i][idx] = dbs_cpu_info->idle_time;
+               idle_avg[i] = cpu_idle_calc_avg(idle_hist[i],
+                                       cnt < MAX_HIST ? cnt : MAX_HIST);
+-              if (idle_avg[i] > IDLE_THRESHOLD)
++              if (idle_avg[i] > lb_threshold)
+                       idle_cpus++;
+       }
+       if (idle_cpus < 0 || idle_cpus > NR_CPUS) {
+-              pr_warn("idle_cpus: %d out of range\n", idle_cpus);
++              pr_warn("%s: idle_cpus: %d out of range\n", __func__,
++                      idle_cpus);
+               return;
+       }
+-      if (idle_cpus == 0) {
+-              /* Full load -> reduce freq */
+-              freq = policy->max * (a_all * load_freq + b_all) / poly_div;
+-      } else if (idle_cpus == NR_CPUS) {
+-              /* Idle cpus */
+-              freq = policy->min;
+-      } else if (idle_cpus == (NR_CPUS - 1)) {
+-              freq = policy->max * (a_one * load_freq + b_one) / poly_div;
+-      } else {
+-              /* Adjust frequency with number of available CPUS */
+-              /* smaller idle_cpus -> smaller frequency */
+-              b = ((idle_cpus - 1) * b_rest1) + b_rest2;
+-              freq = policy->max * (a_rest * load_freq + b) / poly_div;
++      if (!lb_ctrl_table)
++              return;
++
++      op = lb_chose_freq(load, idle_cpus);
++      if (op == LB_BOOST_ENABLE)
++              set_bit(idx, boost_hist);
++      else
++              clear_bit(idx, boost_hist);
++
++      bs = cpufreq_boost_enabled();
++      /*
++       * - To disable boost -
++       *
++       * Operation different than LB_BOOST_ENABLE is
++       * required for at least MAX_HIST previous operations
++       */
++      if (bs && bitmap_empty(boost_hist, MAX_HIST)) {
++              lb_boost_data.state = false;
++              schedule_work_on(cpu, &lb_boost_data.work);
+       }
+-#if 0 
+-      if (!idx)
+-              pr_info("p->max:%d,freq: %d,idle_cpus: %d,avg : %d %d %d %d load_f: %d\n",
+-                     policy->max, freq, idle_cpus, idle_avg[0], idle_avg[1],
+-                      idle_avg[2], idle_avg[3], load_freq);
+-#endif
+-      dbs_freq_increase(policy, freq);
+-}
++      /*
++       * - To enable boost -
++       *
++       * Only (MAX_HIST - 1) bits are required. This allows entering
++       * BOOST mode earlier, since we skip one "round" of LAB operation
++       * before work is executed.
++       */
++      if (!bs &&
++          (bitmap_weight(boost_hist, MAX_HIST) == (MAX_HIST - 1))) {
++              lb_boost_data.state = true;
++              schedule_work_on(cpu, &lb_boost_data.work);
++      }
+-/************************** sysfs interface ************************/
+-static struct common_dbs_data lb_dbs_cdata;
++      switch (op) {
++      case LB_BOOST_ENABLE:
++              freq = policy->max;
++              break;
+-/**
+- * update_sampling_rate - update sampling rate effective immediately if needed.
+- * @new_rate: new sampling rate
+- *
+- * If new rate is smaller than the old, simply updating
+- * dbs_tuners_int.sampling_rate might not be appropriate. For example, if the
+- * original sampling_rate was 1 second and the requested new sampling rate is 10
+- * ms because the user needs immediate reaction from lab governor, but not
+- * sure if higher frequency will be required or not, then, the governor may
+- * change the sampling rate too late; up to 1 second later. Thus, if we are
+- * reducing the sampling rate, we need to make the new value effective
+- * immediately.
+- */
+-static void update_sampling_rate(struct dbs_data *dbs_data,
+-                      unsigned int new_rate)
+-{
+-      struct lb_dbs_tuners *lb_tuners = dbs_data->tuners;
+-      int cpu;
++      case LB_MIN_FREQ:
++              freq = policy->min;
++              break;
+-      lb_tuners->sampling_rate = new_rate = max(new_rate,
+-                      dbs_data->min_sampling_rate);
++      default:
++              freq = op;
++      }
+-      for_each_online_cpu(cpu) {
+-              struct cpufreq_policy *policy;
+-              struct lb_cpu_dbs_info_s *dbs_info;
+-              unsigned long next_sampling, appointed_at;
++      if (policy->cur == freq)
++              return;
+-              policy = cpufreq_cpu_get(cpu);
+-              if (!policy)
+-                      continue;
+-              if (policy->governor != &cpufreq_gov_lab) {
+-                      cpufreq_cpu_put(policy);
+-                      continue;
+-              }
+-              dbs_info = &per_cpu(lb_cpu_dbs_info, cpu);
+-              cpufreq_cpu_put(policy);
++      __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L);
++}
+-              mutex_lock(&dbs_info->cdbs.timer_mutex);
++static ssize_t show_load(struct kobject *kobj,
++                       struct attribute *attr, char *buf)
++{
++      return sprintf(buf, "%u\n", lb_load);
++}
++define_one_global_ro(load);
+-              if (!delayed_work_pending(&dbs_info->cdbs.work)) {
+-                      mutex_unlock(&dbs_info->cdbs.timer_mutex);
+-                      continue;
+-              }
++static ssize_t show_idle_cpus_num(struct kobject *kobj,
++                                struct attribute *attr, char *buf)
++{
++      return sprintf(buf, "%u\n", idle_cpus);
++}
++define_one_global_ro(idle_cpus_num);
+-              next_sampling = jiffies + usecs_to_jiffies(new_rate);
+-              appointed_at = dbs_info->cdbs.work.timer.expires;
++static ssize_t show_idle_avg_cpus_val(struct kobject *kobj,
++                                    struct attribute *attr, char *buf)
++{
++      char off;
++      int i;
+-              if (time_before(next_sampling, appointed_at)) {
++      for (i = 0, off = 0; i < NR_CPUS; i++)
++              off += sprintf(buf + off, "%u ", idle_avg[i]);
+-                      mutex_unlock(&dbs_info->cdbs.timer_mutex);
+-                      cancel_delayed_work_sync(&dbs_info->cdbs.work);
+-                      mutex_lock(&dbs_info->cdbs.timer_mutex);
++      *(buf + off - 1) = '\n';
+-                      schedule_delayed_work_on(cpu, &dbs_info->cdbs.work,
+-                                      usecs_to_jiffies(new_rate));
++      return off;
++}
++define_one_global_ro(idle_avg_cpus_val);
+-              }
+-              mutex_unlock(&dbs_info->cdbs.timer_mutex);
+-      }
++static ssize_t show_idle_threshold(struct kobject *kobj,
++                                 struct attribute *attr, char *buf)
++{
++      return sprintf(buf, "%u\n", lb_threshold);
+ }
+-static ssize_t store_sampling_rate(struct dbs_data *dbs_data, const char *buf,
+-                              size_t count)
++static ssize_t store_idle_threshold(struct kobject *a, struct attribute *b,
++                                  const char *buf, size_t count)
+ {
+-      unsigned int input;
++      unsigned int val;
+       int ret;
+-      ret = sscanf(buf, "%u", &input);
++
++      ret = sscanf(buf, "%u", &val);
+       if (ret != 1)
+               return -EINVAL;
+-      update_sampling_rate(dbs_data, input);
++      if (val < 0 || val > 100) {
++              pr_err("%s: Only value in a range 0 to 100 accepted\n",
++                     __func__);
++              return -EINVAL;
++      }
++
++      lb_threshold = val;
+       return count;
+ }
+-
+-show_store_one(lb, sampling_rate);
+-gov_sys_pol_attr_rw(sampling_rate);
++define_one_global_rw(idle_threshold);
+ static struct attribute *dbs_attributes_gov_sys[] = {
+-      &sampling_rate_gov_sys.attr,
++      &idle_avg_cpus_val.attr,
++      &idle_threshold.attr,
++      &idle_cpus_num.attr,
++      &load.attr,
+       NULL
+ };
+@@ -240,39 +257,115 @@ static struct attribute_group lb_attr_group_gov_sys = {
+       .name = "lab",
+ };
+-static struct attribute *dbs_attributes_gov_pol[] = {
+-      &sampling_rate_gov_pol.attr,
+-      NULL
+-};
++static int lb_ctrl_table_of_init(struct device_node *dn,
++                               unsigned int **ctrl_tab, int size)
++{
++      struct property *pp;
++      int len;
+-static struct attribute_group lb_attr_group_gov_pol = {
+-      .attrs = dbs_attributes_gov_pol,
+-      .name = "lab",
+-};
++      pp = of_find_property(dn, "lab-ctrl-freq", &len);
++      if (!pp) {
++              pr_err("%s: Property: 'lab-ctrl-freq'  not found\n", __func__);
++              return -ENODEV;
++      }
++
++      if (len != (size * sizeof(**ctrl_tab))) {
++              pr_err("%s: Wrong 'lab-ctrl-freq' size\n", __func__);
++              return -EINVAL;
++      }
++
++      *ctrl_tab = kzalloc(len, GFP_KERNEL);
++      if (!*ctrl_tab) {
++              pr_err("%s: Not enough memory for LAB control structure\n",
++                     __func__);
++              return -ENOMEM;
++      }
++
++      if (of_property_read_u32_array(dn, pp->name, *ctrl_tab, size)) {
++              pr_err("Property: %s cannot be read!\n", pp->name);
++              return -ENODEV;
++      }
+-/************************** sysfs end ************************/
++      return 0;
++}
++
++static int lb_of_init(void)
++{
++      struct device_node *dn;
++      struct property *pp;
++      int ret;
++
++      dn = of_find_node_by_path("/cpufreq");
++      if (!dn) {
++              pr_err("%s: Node: '/cpufreq/' not found\n", __func__);
++              return -ENODEV;
++      }
++
++      pp = of_find_property(dn, "lab-num-of-states", NULL);
++      if (!pp) {
++              pr_err("%s: Property: 'lab-num-of-states'  not found\n",
++                     __func__);
++              ret = -ENODEV;
++              goto dn_err;
++      }
++      lb_num_of_states = be32_to_cpup(pp->value);
++
++      lb_ctrl_table_size = lb_num_of_states * (NR_CPUS + 1);
++      ret = lb_ctrl_table_of_init(dn, &lb_ctrl_table, lb_ctrl_table_size);
++      if (ret) {
++              kfree(lb_ctrl_table);
++              lb_ctrl_table = NULL;
++              pr_err("%s: Cannot parse LAB control structure from OF\n",
++                     __func__);
++              return ret;
++      }
++
++dn_err:
++      of_node_put(dn);
++      return ret;
++}
+ static int lb_init(struct dbs_data *dbs_data)
+ {
++      int ret;
++
++      ret = lb_of_init();
++      if (ret)
++              return ret;
++
++      boost_init_state = cpufreq_boost_enabled();
++      if (boost_init_state)
++              cpufreq_boost_trigger_state(false);
+       od_init(dbs_data);
++      INIT_WORK(&lb_boost_data.work, lb_cpufreq_boost_work);
++
+       return 0;
+ }
+-define_get_cpu_dbs_routines(lb_cpu_dbs_info);
++void lb_exit(struct dbs_data *dbs_data)
++{
++      od_exit(dbs_data);
++
++      kfree(lb_ctrl_table);
++      lb_ctrl_table = NULL;
++
++      cpufreq_boost_trigger_state(boost_init_state);
++}
++
++define_get_cpu_dbs_routines(od_cpu_dbs_info);
+ static struct common_dbs_data lb_dbs_cdata = {
+       .governor = GOV_LAB,
+       .attr_group_gov_sys = &lb_attr_group_gov_sys,
+-      .attr_group_gov_pol = &lb_attr_group_gov_pol,
+       .get_cpu_cdbs = get_cpu_cdbs,
+       .get_cpu_dbs_info_s = get_cpu_dbs_info_s,
+       .gov_dbs_timer = od_dbs_timer,
+       .gov_check_cpu = lb_check_cpu,
+       .gov_ops = &od_ops,
+       .init = lb_init,
+-      .exit = od_exit,
++      .exit = lb_exit,
+ };
+ static int lb_cpufreq_governor_dbs(struct cpufreq_policy *policy,
+@@ -281,13 +374,10 @@ static int lb_cpufreq_governor_dbs(struct cpufreq_policy *policy,
+       return cpufreq_governor_dbs(policy, &lb_dbs_cdata, event);
+ }
+-#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_LAB
+-static
+-#endif
+ struct cpufreq_governor cpufreq_gov_lab = {
+       .name                   = "lab",
+       .governor               = lb_cpufreq_governor_dbs,
+-      .max_transition_latency = TRANSITION_LATENCY_LIMIT,
++      .max_transition_latency = TRANSITION_LATENCY_LIMIT,
+       .owner                  = THIS_MODULE,
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1279-cpufreq-LAB-ondemand-Ondemand-governor-adjustments-n.patch b/patches.tizen/1279-cpufreq-LAB-ondemand-Ondemand-governor-adjustments-n.patch
new file mode 100644 (file)
index 0000000..09aab2e
--- /dev/null
@@ -0,0 +1,89 @@
+From 6cbc26d24b93e3607a66525df06eaf4cf8691d26 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Wed, 26 Feb 2014 13:42:04 +0100
+Subject: [PATCH 1279/1302] cpufreq:LAB:ondemand: Ondemand governor adjustments
+ necessary for correct LAB operation
+
+Ondemand code needs to be slightly modified for LAB governor operation.
+The biggest problem is with the update_sampling_rate function, which shall
+not be executed with wrong governor.
+
+Change-Id: I149204bda15b11546c57a77a75a51c4f4f8522b8
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/cpufreq_governor.h |  3 +++
+ drivers/cpufreq/cpufreq_ondemand.c | 14 +++++++++++---
+ 2 files changed, 14 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h
+index a3cf7a8..256c50d4 100644
+--- a/drivers/cpufreq/cpufreq_governor.h
++++ b/drivers/cpufreq/cpufreq_governor.h
+@@ -290,6 +290,9 @@ void od_unregister_powersave_bias_handler(void);
+ void od_dbs_timer(struct work_struct *work);
+ int od_init(struct dbs_data *dbs_data);
+ void od_exit(struct dbs_data *dbs_data);
++void od_check_cpu(int cpu, unsigned int load_freq);
++void update_sampling_rate(struct dbs_data *dbs_data,
++                        unsigned int new_rate);
+ extern struct od_ops od_ops;
+diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
+index d49855d..85c4f56 100644
+--- a/drivers/cpufreq/cpufreq_ondemand.c
++++ b/drivers/cpufreq/cpufreq_ondemand.c
+@@ -37,7 +37,7 @@
+ #define MIN_FREQUENCY_UP_THRESHOLD            (11)
+ #define MAX_FREQUENCY_UP_THRESHOLD            (100)
+-static DEFINE_PER_CPU(struct od_cpu_dbs_info_s, od_cpu_dbs_info);
++DEFINE_PER_CPU(struct od_cpu_dbs_info_s, od_cpu_dbs_info);
+ struct od_ops od_ops;
+@@ -162,7 +162,7 @@ static void dbs_freq_increase(struct cpufreq_policy *p, unsigned int freq)
+  * (default), then we try to increase frequency. Else, we adjust the frequency
+  * proportional to load.
+  */
+-static void od_check_cpu(int cpu, unsigned int load)
++void od_check_cpu(int cpu, unsigned int load)
+ {
+       struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu);
+       struct cpufreq_policy *policy = dbs_info->cdbs.cur_policy;
+@@ -247,6 +247,9 @@ max_delay:
+ /************************** sysfs interface ************************/
+ static struct common_dbs_data od_dbs_cdata;
++#ifdef CONFIG_CPU_FREQ_GOV_LAB
++extern struct cpufreq_governor cpufreq_gov_lab;
++#endif
+ /**
+  * update_sampling_rate - update sampling rate effective immediately if needed.
+  * @new_rate: new sampling rate
+@@ -260,7 +263,7 @@ static struct common_dbs_data od_dbs_cdata;
+  * reducing the sampling rate, we need to make the new value effective
+  * immediately.
+  */
+-static void update_sampling_rate(struct dbs_data *dbs_data,
++void update_sampling_rate(struct dbs_data *dbs_data,
+               unsigned int new_rate)
+ {
+       struct od_dbs_tuners *od_tuners = dbs_data->tuners;
+@@ -277,7 +280,12 @@ static void update_sampling_rate(struct dbs_data *dbs_data,
+               policy = cpufreq_cpu_get(cpu);
+               if (!policy)
+                       continue;
++#ifdef CONFIG_CPU_FREQ_GOV_LAB
++              if (policy->governor != &cpufreq_gov_ondemand &&
++                  policy->governor != &cpufreq_gov_lab) {
++#else
+               if (policy->governor != &cpufreq_gov_ondemand) {
++#endif
+                       cpufreq_cpu_put(policy);
+                       continue;
+               }
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1280-cpufreq-LAB-cpufreq_governor-Remove-redundant-LAB-co.patch b/patches.tizen/1280-cpufreq-LAB-cpufreq_governor-Remove-redundant-LAB-co.patch
new file mode 100644 (file)
index 0000000..b78f5d9
--- /dev/null
@@ -0,0 +1,138 @@
+From d7f97d21f23cbaf02de6e42142ffa1d44ed3251a Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Wed, 26 Feb 2014 15:50:05 +0100
+Subject: [PATCH 1280/1302] cpufreq:LAB:cpufreq_governor: Remove redundant LAB
+ code from cpufreq_governor.[h|c]
+
+Since the Ondemand code has been reused for LAB, it is now possible to remove
+code specially defined for LAB governor at the cpufreq_governor.[h|c] code.
+
+Change-Id: I9c48eade8ffe6a94efd0145b7d48afb405961155
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/cpufreq_governor.c | 24 +++++-------------------
+ drivers/cpufreq/cpufreq_governor.h | 16 ----------------
+ 2 files changed, 5 insertions(+), 35 deletions(-)
+
+diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
+index a393e2a..c1704fa 100644
+--- a/drivers/cpufreq/cpufreq_governor.c
++++ b/drivers/cpufreq/cpufreq_governor.c
+@@ -85,7 +85,6 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu)
+       struct cpu_dbs_common_info *cdbs = dbs_data->cdata->get_cpu_cdbs(cpu);
+       struct od_dbs_tuners *od_tuners = dbs_data->tuners;
+       struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
+-      struct lb_dbs_tuners *lb_tuners = dbs_data->tuners;
+       struct cpufreq_policy *policy;
+       unsigned int max_load = 0;
+       unsigned int ignore_nice;
+@@ -93,8 +92,6 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu)
+       if (dbs_data->cdata->governor == GOV_ONDEMAND)
+               ignore_nice = od_tuners->ignore_nice_load;
+-      else if (dbs_data->cdata->governor == GOV_LAB)
+-              ignore_nice = lb_tuners->ignore_nice;
+       else
+               ignore_nice = cs_tuners->ignore_nice_load;
+@@ -155,10 +152,10 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu)
+               load = 100 * (wall_time - idle_time) / wall_time;
+               if (dbs_data->cdata->governor == GOV_LAB) {
+-                      struct lb_cpu_dbs_info_s *lb_dbs_info =
++                      struct od_cpu_dbs_info_s *od_dbs_info =
+                               dbs_data->cdata->get_cpu_dbs_info_s(j);
+-                      lb_dbs_info->idle_time = (100 * idle_time) / wall_time;
++                      od_dbs_info->idle_time = (100 * idle_time) / wall_time;
+               }
+               if (load > max_load)
+@@ -228,9 +225,6 @@ static void set_sampling_rate(struct dbs_data *dbs_data,
+       if (dbs_data->cdata->governor == GOV_CONSERVATIVE) {
+               struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
+               cs_tuners->sampling_rate = sampling_rate;
+-      } else if(dbs_data->cdata->governor == GOV_LAB) {
+-              struct lb_dbs_tuners *lb_tuners = dbs_data->tuners;
+-              lb_tuners->sampling_rate = sampling_rate;
+       } else {
+               struct od_dbs_tuners *od_tuners = dbs_data->tuners;
+               od_tuners->sampling_rate = sampling_rate;
+@@ -243,13 +237,12 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
+       struct dbs_data *dbs_data;
+       struct od_cpu_dbs_info_s *od_dbs_info = NULL;
+       struct cs_cpu_dbs_info_s *cs_dbs_info = NULL;
+-      struct lb_cpu_dbs_info_s *lb_dbs_info = NULL;
+       struct od_ops *od_ops = NULL;
+       struct od_dbs_tuners *od_tuners = NULL;
+       struct cs_dbs_tuners *cs_tuners = NULL;
+-      struct lb_dbs_tuners *lb_tuners = NULL;
+       struct cpu_dbs_common_info *cpu_cdbs;
+-      unsigned int sampling_rate = 0, ignore_nice = 0, latency, j, cpu = policy->cpu;
++      unsigned int sampling_rate = 0, ignore_nice = 0;
++      unsigned int latency, j, cpu = policy->cpu;
+       int io_busy = 0;
+       int rc;
+       int governor = cdata->governor;
+@@ -362,7 +355,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
+                       sampling_rate = cs_tuners->sampling_rate;
+                       ignore_nice = cs_tuners->ignore_nice_load;
+                       cs_dbs_info->enable = 1;
+-              } else if (governor == GOV_ONDEMAND) {
++              } else {
+                       od_tuners = dbs_data->tuners;
+                       od_dbs_info = dbs_data->cdata->get_cpu_dbs_info_s(cpu);
+                       od_dbs_info->rate_mult = 1;
+@@ -372,14 +365,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
+                       od_ops = dbs_data->cdata->gov_ops;
+                       io_busy = od_tuners->io_is_busy;
+                       od_ops->powersave_bias_init_cpu(cpu);
+-              } else {
+-                      lb_tuners = dbs_data->tuners;
+-                      lb_dbs_info = dbs_data->cdata->get_cpu_dbs_info_s(cpu);
+-                      lb_dbs_info->rate_mult = 1;
+-                      sampling_rate = lb_tuners->sampling_rate;
+-                      ignore_nice = lb_tuners->ignore_nice;
+               }
+-
+               mutex_lock(&dbs_data->mutex);
+               for_each_cpu(j, policy->cpus) {
+diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h
+index 256c50d4..6732ea6 100644
+--- a/drivers/cpufreq/cpufreq_governor.h
++++ b/drivers/cpufreq/cpufreq_governor.h
+@@ -164,14 +164,6 @@ struct cs_cpu_dbs_info_s {
+       unsigned int enable:1;
+ };
+-struct lb_cpu_dbs_info_s {
+-      struct cpu_dbs_common_info cdbs;
+-      u64 prev_cpu_iowait;
+-      struct cpufreq_frequency_table *freq_table;
+-      unsigned int rate_mult;
+-      unsigned int idle_time;
+-};
+-
+ /* Per policy Governers sysfs tunables */
+ struct od_dbs_tuners {
+       unsigned int ignore_nice_load;
+@@ -191,14 +183,6 @@ struct cs_dbs_tuners {
+       unsigned int freq_step;
+ };
+-struct lb_dbs_tuners {
+-      unsigned int ignore_nice;
+-      unsigned int sampling_rate;
+-      unsigned int sampling_down_factor;
+-      unsigned int up_threshold;
+-      unsigned int adj_up_threshold;
+-};
+-
+ /* Common Governer data across policies */
+ struct dbs_data;
+ struct common_dbs_data {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1281-cpufreq-LAB-ondemand-Enable-usage-of-ONDEMAND-specif.patch b/patches.tizen/1281-cpufreq-LAB-ondemand-Enable-usage-of-ONDEMAND-specif.patch
new file mode 100644 (file)
index 0000000..7d8cd37
--- /dev/null
@@ -0,0 +1,91 @@
+From ab6785da8cd1eaa81c4233b6876156a4426e6abb Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Thu, 27 Feb 2014 13:35:03 +0100
+Subject: [PATCH 1281/1302] cpufreq:LAB:ondemand: Enable usage of ONDEMAND
+ specific methods at LAB governor
+
+Two methods from ondemand, namely store_sampling_rate() and od_check_cpu()
+are now utilized in LAB governor.
+
+Moreover the od_cpu_dbs_info_s structure shall be regarded as a common one.
+Therefore in LAB only its declaration is necessary.
+
+Change-Id: I3408b2f8cfdb292cd69568c931da46d8f957099c
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/cpufreq_lab.c | 40 +++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 39 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/cpufreq/cpufreq_lab.c b/drivers/cpufreq/cpufreq_lab.c
+index 8939a6e..76f6b20 100644
+--- a/drivers/cpufreq/cpufreq_lab.c
++++ b/drivers/cpufreq/cpufreq_lab.c
+@@ -51,7 +51,7 @@ static int lb_ctrl_table_size, lb_num_of_states;
+ static bool boost_init_state;
+ static DECLARE_BITMAP(boost_hist, MAX_HIST);
+-static DEFINE_PER_CPU(struct od_cpu_dbs_info_s, od_cpu_dbs_info);
++DECLARE_PER_CPU(struct od_cpu_dbs_info_s, od_cpu_dbs_info);
+ struct cpufreq_governor cpufreq_gov_lab;
+@@ -178,6 +178,10 @@ static void lb_check_cpu(int cpu, unsigned int load)
+               freq = policy->min;
+               break;
++      case LB_ONDEMAND:
++              od_check_cpu(cpu, load);
++              return;
++
+       default:
+               freq = op;
+       }
+@@ -244,10 +248,44 @@ static ssize_t store_idle_threshold(struct kobject *a, struct attribute *b,
+ }
+ define_one_global_rw(idle_threshold);
++ssize_t store_sampling_rate(struct kobject *a, struct attribute *b,
++                                 const char *buf, size_t count)
++{
++      struct dbs_data *dbs_data = lb_dbs_cdata.gdbs_data;
++      unsigned int input;
++      int ret;
++      ret = sscanf(buf, "%u", &input);
++      if (ret != 1)
++              return -EINVAL;
++
++      update_sampling_rate(dbs_data, input);
++      return count;
++}
++
++static ssize_t show_sampling_rate(struct kobject *kobj, struct attribute *attr,
++                                char *buf)
++{
++      struct od_dbs_tuners *tuners = lb_dbs_cdata.gdbs_data->tuners;
++
++      return sprintf(buf, "%u\n", tuners->sampling_rate);
++}
++define_one_global_rw(sampling_rate);
++
++static ssize_t show_sampling_rate_min(struct kobject *kobj,
++                                    struct attribute *attr, char *buf)
++{
++      struct dbs_data *dbs_data = lb_dbs_cdata.gdbs_data;
++
++      return sprintf(buf, "%u\n", dbs_data->min_sampling_rate);
++}
++define_one_global_ro(sampling_rate_min);
++
+ static struct attribute *dbs_attributes_gov_sys[] = {
++      &sampling_rate_min.attr,
+       &idle_avg_cpus_val.attr,
+       &idle_threshold.attr,
+       &idle_cpus_num.attr,
++      &sampling_rate.attr,
+       &load.attr,
+       NULL
+ };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1282-cpufreq-LAB-dts-trats2-Add-attributes-necessary-for-.patch b/patches.tizen/1282-cpufreq-LAB-dts-trats2-Add-attributes-necessary-for-.patch
new file mode 100644 (file)
index 0000000..289405e
--- /dev/null
@@ -0,0 +1,44 @@
+From 621cbe7aa8240161604086d4d7494fff713bdd08 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Wed, 26 Feb 2014 13:12:36 +0100
+Subject: [PATCH 1282/1302] cpufreq:LAB:dts:trats2: Add attributes necessary
+ for correct LAB operation
+
+Two extra attributes have been added. The "lab-num-of-states" describes how
+many ranges will be used during LAB operation. Now the span of it equals to
+20 (100 / 5).
+The lab-ctrl-freq attribute maps number of idle CPUs and workload (from
+scheduler) to LAB operations.
+
+It is possible to specify exact freq (e.g. 1300000), enable boost
+(e.g. 0xFFFFFFFF), set frequency to minimum (0xFFFFFFFE) or rely on
+ONDEMAND governor to find suitable frequency.
+
+Change-Id: I0ea6ffd8626aded5bed34166c59b9d34278feef2
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-trats2.dts | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts
+index 7068328..f25a37f 100644
+--- a/arch/arm/boot/dts/exynos4412-trats2.dts
++++ b/arch/arm/boot/dts/exynos4412-trats2.dts
+@@ -1349,6 +1349,13 @@
+                            900000 800000 700000 600000 500000 400000 300000
+                            200000>;
+               boost_freq = <1500000>;
++              lab-num-of-states = <5>;
++              lab-ctrl-freq = < 0          0          0          1300000    1200000
++                                0          0          0          0          1300000
++                                0          0          0          0          0xFFFFFFFF
++                                0          0          0          0xFFFFFFFF 0xFFFFFFFF
++                                0xFFFFFFFE 0xFFFFFFFE 0xFFFFFFFE 0xFFFFFFFE 0xFFFFFFFE
++                              >;
+               vdd_arm-supply = <&buck2_reg>;
+               status = "okay";
+       };
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1283-cpufreq-LAB-cosmetic-Cosmetic-code-cleanup.patch b/patches.tizen/1283-cpufreq-LAB-cosmetic-Cosmetic-code-cleanup.patch
new file mode 100644 (file)
index 0000000..225c0cb
--- /dev/null
@@ -0,0 +1,53 @@
+From d3c20448e801ec91812a21291c30a89f173288b9 Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Tue, 4 Mar 2014 12:20:34 +0100
+Subject: [PATCH 1283/1302] cpufreq:LAB:cosmetic: Cosmetic code cleanup
+
+Initialization of static variable is not necessary, since it will be placed
+at BSS section.
+
+Also proper format comments have been added.
+
+Change-Id: Id5e30a97d7d3cdb851f09a69e944c77223fa8a82
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/cpufreq_lab.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/cpufreq/cpufreq_lab.c b/drivers/cpufreq/cpufreq_lab.c
+index 76f6b20..215f322 100644
+--- a/drivers/cpufreq/cpufreq_lab.c
++++ b/drivers/cpufreq/cpufreq_lab.c
+@@ -34,7 +34,8 @@
+ #define LB_MIN_FREQ            ~1UL
+ #define LB_ONDEMAND             0
+-/* Pre-calculated summation of weight, 0.5
++/*
++ * Pre-calculated summation of weight, 0.5
+  * 1
+  * 1 + 0.5^1 = 1.5
+  * 1 + 0.5^1 + 0.5^2 = 1.75
+@@ -61,7 +62,8 @@ static struct lb_wq_boost_data {
+       struct work_struct work;
+ } lb_boost_data;
+-/* Calculate average of idle time with weighting 50% less to older one.
++/*
++ * Calculate average of idle time with weighting 50% less to older one.
+  * With weight, average can be affected by current phase more rapidly than
+  * normal average. And it also has tolerance for temporary fluctuation of
+  * idle time as normal average has.
+@@ -110,7 +112,7 @@ static void lb_check_cpu(int cpu, unsigned int load)
+       struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu);
+       struct cpufreq_policy *policy = dbs_info->cdbs.cur_policy;
+       unsigned int freq = 0, op;
+-      static int cnt = 0;
++      static int cnt;
+       int i, idx, bs;
+       idle_cpus = 0;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1284-cpufreq-LAB-Replace-NR_CPUS-with-num_possible_cpus-f.patch b/patches.tizen/1284-cpufreq-LAB-Replace-NR_CPUS-with-num_possible_cpus-f.patch
new file mode 100644 (file)
index 0000000..5579cab
--- /dev/null
@@ -0,0 +1,125 @@
+From 77900299ba69d04ae3c20f54cc4d991775dda67d Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Tue, 4 Mar 2014 12:27:50 +0100
+Subject: [PATCH 1284/1302] cpufreq:LAB: Replace NR_CPUS with
+ num_possible_cpus() function
+
+The usage of NR_CPUS constant is deprecated, since this value can be the
+maximal possible number of cores on a SMP machine.
+
+The num_possible_cpus() represents the number of available cores on the
+system.
+This change has caused replacement of global tables by ones allocated with
+kzalloc().
+
+Change-Id: Ib0bfa27296740a91a25b1af0ece0e573a9756846
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/cpufreq_lab.c | 40 ++++++++++++++++++++++++++++++++--------
+ 1 file changed, 32 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/cpufreq/cpufreq_lab.c b/drivers/cpufreq/cpufreq_lab.c
+index 215f322..26360c3 100644
+--- a/drivers/cpufreq/cpufreq_lab.c
++++ b/drivers/cpufreq/cpufreq_lab.c
+@@ -44,8 +44,8 @@
+  */
+ static int history_weight_sum[] = { 100, 150, 175, 187, 193 };
+-static unsigned int idle_avg[NR_CPUS];
+-static unsigned int idle_hist[NR_CPUS][MAX_HIST];
++static unsigned int *idle_avg;
++static unsigned int *idle_hist;
+ static int idle_cpus, lb_threshold = 90;
+ static unsigned int *lb_ctrl_table, lb_load;
+ static int lb_ctrl_table_size, lb_num_of_states;
+@@ -123,15 +123,15 @@ static void lb_check_cpu(int cpu, unsigned int load)
+               struct od_cpu_dbs_info_s *dbs_cpu_info =
+                       &per_cpu(od_cpu_dbs_info, i);
+-              idle_hist[i][idx] = dbs_cpu_info->idle_time;
+-              idle_avg[i] = cpu_idle_calc_avg(idle_hist[i],
++              idle_hist[i * MAX_HIST + idx] = dbs_cpu_info->idle_time;
++              idle_avg[i] = cpu_idle_calc_avg(&idle_hist[i * MAX_HIST],
+                                       cnt < MAX_HIST ? cnt : MAX_HIST);
+               if (idle_avg[i] > lb_threshold)
+                       idle_cpus++;
+       }
+-      if (idle_cpus < 0 || idle_cpus > NR_CPUS) {
++      if (idle_cpus < 0 || idle_cpus > num_possible_cpus()) {
+               pr_warn("%s: idle_cpus: %d out of range\n", __func__,
+                       idle_cpus);
+               return;
+@@ -214,7 +214,7 @@ static ssize_t show_idle_avg_cpus_val(struct kobject *kobj,
+       char off;
+       int i;
+-      for (i = 0, off = 0; i < NR_CPUS; i++)
++      for (i = 0, off = 0; i < num_possible_cpus(); i++)
+               off += sprintf(buf + off, "%u ", idle_avg[i]);
+       *(buf + off - 1) = '\n';
+@@ -350,7 +350,7 @@ static int lb_of_init(void)
+       }
+       lb_num_of_states = be32_to_cpup(pp->value);
+-      lb_ctrl_table_size = lb_num_of_states * (NR_CPUS + 1);
++      lb_ctrl_table_size = lb_num_of_states * (num_possible_cpus() + 1);
+       ret = lb_ctrl_table_of_init(dn, &lb_ctrl_table, lb_ctrl_table_size);
+       if (ret) {
+               kfree(lb_ctrl_table);
+@@ -369,9 +369,23 @@ static int lb_init(struct dbs_data *dbs_data)
+ {
+       int ret;
++      idle_avg = kzalloc(num_possible_cpus() * sizeof(*idle_avg), GFP_KERNEL);
++      if (!idle_avg) {
++              pr_err("%s: Not enough memory", __func__);
++              return -ENOMEM;
++      }
++
++      idle_hist = kzalloc(num_possible_cpus() * MAX_HIST * sizeof(*idle_hist),
++                          GFP_KERNEL);
++      if (!idle_hist) {
++              pr_err("%s: Not enough memory", __func__);
++              ret = -ENOMEM;
++              goto err_idle_avg;
++      }
++
+       ret = lb_of_init();
+       if (ret)
+-              return ret;
++              goto err_idle_hist;
+       boost_init_state = cpufreq_boost_enabled();
+       if (boost_init_state)
+@@ -382,6 +396,13 @@ static int lb_init(struct dbs_data *dbs_data)
+       INIT_WORK(&lb_boost_data.work, lb_cpufreq_boost_work);
+       return 0;
++
++err_idle_hist:
++      kfree(idle_hist);
++err_idle_avg:
++      kfree(idle_avg);
++
++      return ret;
+ }
+ void lb_exit(struct dbs_data *dbs_data)
+@@ -392,6 +413,9 @@ void lb_exit(struct dbs_data *dbs_data)
+       lb_ctrl_table = NULL;
+       cpufreq_boost_trigger_state(boost_init_state);
++
++      kfree(idle_avg);
++      kfree(idle_hist);
+ }
+ define_get_cpu_dbs_routines(od_cpu_dbs_info);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1285-ARM-dts-odroidx2-remove-obsoleted-register-debug-nod.patch b/patches.tizen/1285-ARM-dts-odroidx2-remove-obsoleted-register-debug-nod.patch
new file mode 100644 (file)
index 0000000..7663e71
--- /dev/null
@@ -0,0 +1,35 @@
+From 6d84c7146e8fc2520da70a084d3a85bc81befdb0 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Tue, 4 Mar 2014 12:27:53 +0100
+Subject: [PATCH 1285/1302] ARM: dts: odroidx2: remove obsoleted register debug
+ node
+
+Register-debug node was used for some internal debug, it is not needed
+at in release code.
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-Id: I3cefb94755850a9c3caa609ed0fb5c5e56d1fc94
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-odroidx2.dts | 5 -----
+ 1 file changed, 5 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-odroidx2.dts b/arch/arm/boot/dts/exynos4412-odroidx2.dts
+index e10200b..9aa7f34 100644
+--- a/arch/arm/boot/dts/exynos4412-odroidx2.dts
++++ b/arch/arm/boot/dts/exynos4412-odroidx2.dts
+@@ -468,11 +468,6 @@
+               status = "okay";
+       };
+-      register-debug {
+-              compatible = "generic,register-debug";
+-              status = "okay";
+-      };
+-
+       camera {
+               status = "okay";
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1286-ARM-dts-odroidx2-add-mali-gpu-and-cpu-freq.patch b/patches.tizen/1286-ARM-dts-odroidx2-add-mali-gpu-and-cpu-freq.patch
new file mode 100644 (file)
index 0000000..8b230c5
--- /dev/null
@@ -0,0 +1,42 @@
+From fc51f62e7f40bb89a6b070055386464e63b3183e Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Tue, 4 Mar 2014 12:28:51 +0100
+Subject: [PATCH 1286/1302] ARM: dts: odroidx2: add mali gpu and cpu freq
+
+Add nodes to enable MALI gpu and CPU freq drivers.
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-Id: Id1cc80e7b4278698603422da8e8a7a07fca38904
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-odroidx2.dts | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-odroidx2.dts b/arch/arm/boot/dts/exynos4412-odroidx2.dts
+index 9aa7f34..063243d 100644
+--- a/arch/arm/boot/dts/exynos4412-odroidx2.dts
++++ b/arch/arm/boot/dts/exynos4412-odroidx2.dts
+@@ -513,6 +513,20 @@
+               };
+       };
++      gpu@13000000 {
++              status = "okay";
++              vdd_g3d-supply = <&buck4_reg>;
++      };
++
++      cpufreq {
++              freq_table = <1400000 1300000 1200000 1100000 1000000
++                           900000 800000 700000 600000 500000 400000 300000
++                           200000>;
++              boost_freq = <1500000>;
++              vdd_arm-supply = <&buck2_reg>;
++              status = "okay";
++      };
++
+       hdmi@12D00000 {
+               hpd-gpio = <&gpx3 7 0>;
+               pinctrl-names = "default";
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1287-ARM-odroidx2-update-defconfig.patch b/patches.tizen/1287-ARM-odroidx2-update-defconfig.patch
new file mode 100644 (file)
index 0000000..faf95e6
--- /dev/null
@@ -0,0 +1,95 @@
+From ee8e820df9bb345565eeccf249be4bbfc4893307 Mon Sep 17 00:00:00 2001
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+Date: Tue, 4 Mar 2014 12:30:01 +0100
+Subject: [PATCH 1287/1302] ARM: odroidx2: update defconfig
+
+Added drivers for MALI GPU, DMAbuf, DMAbuf-sync, exynos drm iommu and
+cpufreq.
+
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Change-Id: I427332db24aa52daf4d4addbf9fbad8bc116b62e
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_odroidx2_defconfig | 45 ++++++++++++++++++++++++++-----
+ 1 file changed, 39 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm/configs/tizen_odroidx2_defconfig b/arch/arm/configs/tizen_odroidx2_defconfig
+index 79fdc8c..5de4ff2 100644
+--- a/arch/arm/configs/tizen_odroidx2_defconfig
++++ b/arch/arm/configs/tizen_odroidx2_defconfig
+@@ -523,8 +523,35 @@ CONFIG_AUTO_ZRELADDR=y
+ #
+ # CPU Frequency scaling
+ #
+-# CONFIG_CPU_FREQ is not set
+-# CONFIG_CPU_IDLE is not set
++CONFIG_CPU_FREQ=y
++CONFIG_CPU_FREQ_TABLE=y
++CONFIG_CPU_FREQ_GOV_COMMON=y
++CONFIG_CPU_FREQ_STAT=y
++# CONFIG_CPU_FREQ_STAT_DETAILS is not set
++CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
++# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
++# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
++# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
++# CONFIG_CPU_FREQ_DEFAULT_GOV_LAB is not set
++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
++# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
++# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
++CONFIG_CPU_FREQ_GOV_ONDEMAND=y
++# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
++# CONFIG_CPU_FREQ_GOV_LAB is not set
++
++#
++# ARM CPU frequency scaling drivers
++#
++CONFIG_ARM_EXYNOS_CPUFREQ=y
++CONFIG_ARM_EXYNOS4210_CPUFREQ=y
++CONFIG_ARM_EXYNOS4X12_CPUFREQ=y
++# CONFIG_ARM_EXYNOS5250_CPUFREQ is not set
++# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set
++CONFIG_CPU_IDLE=y
++# CONFIG_CPU_IDLE_MULTIPLE_DRIVERS is not set
++CONFIG_CPU_IDLE_GOV_LADDER=y
++CONFIG_CPU_IDLE_GOV_MENU=y
+ # CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
+ #
+@@ -718,7 +745,7 @@ CONFIG_REGMAP_I2C=y
+ CONFIG_REGMAP_MMIO=y
+ CONFIG_REGMAP_IRQ=y
+ CONFIG_DMA_SHARED_BUFFER=y
+-# CONFIG_DMABUF_SYNC is not set
++CONFIG_DMABUF_SYNC=y
+ CONFIG_CMA=y
+ CONFIG_CMA_DEBUG=y
+@@ -1868,7 +1895,13 @@ CONFIG_DVB_AU8522_V4L=y
+ #
+ # ARM GPU Configuration
+ #
+-# CONFIG_MALI400 is not set
++CONFIG_MALI400=y
++# CONFIG_MALI400_DEBUG is not set
++# CONFIG_MALI400_PROFILING is not set
++CONFIG_MALI400_UMP=y
++# CONFIG_UMP_DEBUG is not set
++CONFIG_MALI_DVFS=y
++CONFIG_SLP_MALI_DBG=y
+ CONFIG_DRM=y
+ CONFIG_DRM_KMS_HELPER=y
+ # CONFIG_DRM_LOAD_EDID_FIRMWARE is not set
+@@ -1880,8 +1913,8 @@ CONFIG_DRM_KMS_HELPER=y
+ # CONFIG_DRM_I2C_SIL164 is not set
+ # CONFIG_DRM_I2C_NXP_TDA998X is not set
+ CONFIG_DRM_EXYNOS=y
+-# CONFIG_DRM_EXYNOS_IOMMU is not set
+-# CONFIG_DRM_EXYNOS_DMABUF is not set
++CONFIG_DRM_EXYNOS_IOMMU=y
++CONFIG_DRM_EXYNOS_DMABUF=y
+ CONFIG_DRM_EXYNOS_FIMD=y
+ CONFIG_DRM_EXYNOS_HDMI=y
+ # CONFIG_DRM_EXYNOS_VIDI is not set
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1288-dts-arm-odroidx2-add-support-for-external-buttons.patch b/patches.tizen/1288-dts-arm-odroidx2-add-support-for-external-buttons.patch
new file mode 100644 (file)
index 0000000..fb82353
--- /dev/null
@@ -0,0 +1,75 @@
+From 5085ace810f31331e88a681ce4c8c126a5a96533 Mon Sep 17 00:00:00 2001
+From: Hyungwon Hwang <human.hwang@samsung.com>
+Date: Wed, 5 Mar 2014 14:44:41 +0900
+Subject: [PATCH 1288/1302] dts: arm: odroidx2: add support for external
+ buttons
+
+Add support for two external buttons (power & home buttons)
+
+Change-Id: I90544bf89c804329dfc78709d48d9eedc2c4a181
+Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-odroidx2.dts | 37 +++++++++++++++++++++++++++++++
+ 1 file changed, 37 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412-odroidx2.dts b/arch/arm/boot/dts/exynos4412-odroidx2.dts
+index 063243d..d3339fd 100644
+--- a/arch/arm/boot/dts/exynos4412-odroidx2.dts
++++ b/arch/arm/boot/dts/exynos4412-odroidx2.dts
+@@ -71,6 +71,32 @@
+               };
+       };
++      gpio_keys {
++              compatible = "gpio-keys";
++              pinctrl-names = "default";
++              pinctrl-0 = <&gpio_power_key &gpio_home_key>;
++
++              power_key {
++                      interrupt-parent = <&gpx1>;
++                      interrupts = <3 0>;
++                      gpios = <&gpx1 3 1>;
++                      linux,code = <116>;
++                      label = "power key";
++                      debounce-interval = <10>;
++                      gpio-key,wakeup;
++              };
++
++              home_key {
++                      interrupt-parent = <&gpx2>;
++                      interrupts = <2 0>;
++                      gpios = <&gpx2 2 0>;
++                      linux,code = <139>;
++                      label = "home key";
++                      debounce-interval = <10>;
++                      gpio-key,wakeup;
++              };
++      };
++
+       mshc@12550000 {
+               pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>;
+               pinctrl-names = "default";
+@@ -572,8 +598,19 @@
+ };
+ &pinctrl_1 {
++      gpio_power_key: power_key {
++              samsung,pins = "gpx1-3";
++              samsung,pin-pud = <0>;
++      };
++
++      gpio_home_key: home_key {
++              samsung,pins = "gpx2-2";
++              samsung,pin-pud = <1>;
++      };
++
+       hdmi_hpd: hdmi-hpd {
+               samsung,pins = "gpx3-7";
+               samsung,pin-pud = <1>;
+       };
+ };
++
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1289-ARM-odroidx2-update-defconfig-to-fix-the-number-of-c.patch b/patches.tizen/1289-ARM-odroidx2-update-defconfig-to-fix-the-number-of-c.patch
new file mode 100644 (file)
index 0000000..b440e77
--- /dev/null
@@ -0,0 +1,32 @@
+From 9339e05cb68065e49e538d3c6d06a01f284994a2 Mon Sep 17 00:00:00 2001
+From: Hyungwon Hwang <human.hwang@samsung.com>
+Date: Wed, 5 Mar 2014 15:37:26 +0900
+Subject: [PATCH 1289/1302] ARM: odroidx2: update defconfig to fix the number
+ of cores
+
+The processor on Odroid X2 is Exynos4412 which has 4 processing cores.
+The number of cores on the config file was 2, not 4.
+
+Change-Id: Ia153c28e5c00a7a8cec2cda9ee0d24caa0d0c1ba
+Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_odroidx2_defconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/configs/tizen_odroidx2_defconfig b/arch/arm/configs/tizen_odroidx2_defconfig
+index 5de4ff2..0a8cce0 100644
+--- a/arch/arm/configs/tizen_odroidx2_defconfig
++++ b/arch/arm/configs/tizen_odroidx2_defconfig
+@@ -447,7 +447,7 @@ CONFIG_VMSPLIT_3G=y
+ # CONFIG_VMSPLIT_2G is not set
+ # CONFIG_VMSPLIT_1G is not set
+ CONFIG_PAGE_OFFSET=0xC0000000
+-CONFIG_NR_CPUS=2
++CONFIG_NR_CPUS=4
+ CONFIG_HOTPLUG_CPU=y
+ # CONFIG_ARM_PSCI is not set
+ CONFIG_LOCAL_TIMERS=y
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1290-cpufreq-LAB-Remove-MODULE_-macros-since-it-is-not-po.patch b/patches.tizen/1290-cpufreq-LAB-Remove-MODULE_-macros-since-it-is-not-po.patch
new file mode 100644 (file)
index 0000000..2980b50
--- /dev/null
@@ -0,0 +1,36 @@
+From 039ca2d460d05a007139f664b6185d6e8a85e53d Mon Sep 17 00:00:00 2001
+From: Lukasz Majewski <l.majewski@samsung.com>
+Date: Tue, 4 Mar 2014 12:29:04 +0100
+Subject: [PATCH 1290/1302] cpufreq:LAB: Remove MODULE_* macros since it is not
+ possible to compile LAB as a module
+
+LAB cannot be compiled as a module, so MODULE_* macros are in fact a dead
+code.
+
+Change-Id: I10f8e5650631b00850631aea1295c1d88e53104a
+Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/cpufreq/cpufreq_lab.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/drivers/cpufreq/cpufreq_lab.c b/drivers/cpufreq/cpufreq_lab.c
+index 26360c3..1738a7a 100644
+--- a/drivers/cpufreq/cpufreq_lab.c
++++ b/drivers/cpufreq/cpufreq_lab.c
+@@ -450,12 +450,6 @@ static int __init cpufreq_gov_dbs_init(void)
+       return cpufreq_register_governor(&cpufreq_gov_lab);
+ }
+-MODULE_AUTHOR("Jonghwa Lee <jonghwa3.lee@samsung.com>");
+-MODULE_AUTHOR("Lukasz Majewski <l.majewski@samsung.com>");
+-MODULE_DESCRIPTION("'cpufreq_lab' - A dynamic cpufreq governor for "
+-              "Legacy Application Boosting");
+-MODULE_LICENSE("GPL");
+-
+ #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_LAB
+ fs_initcall(cpufreq_gov_dbs_init);
+ #else
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1291-dts-exynos4412-trats2-Remove-unused-device-node-on-t.patch b/patches.tizen/1291-dts-exynos4412-trats2-Remove-unused-device-node-on-t.patch
new file mode 100644 (file)
index 0000000..c738cc7
--- /dev/null
@@ -0,0 +1,54 @@
+From e58ed38cfcefbcadd3c90ec47d65ca9b095ac932 Mon Sep 17 00:00:00 2001
+From: Beomho Seo <beomho.seo@samsung.com>
+Date: Thu, 6 Mar 2014 11:44:40 +0900
+Subject: [PATCH 1291/1302] dts: exynos4412-trats2: Remove unused  device node
+ on trats2 board
+
+GP2AP002A00F ligth/proximity sensor is unused on trats2 board.
+
+Change-Id: I4ef414eea4aaf336200ec0b97485fcfde2645c2f
+Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-trats2.dts | 18 ------------------
+ 1 file changed, 18 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts
+index f25a37f..77eaf18 100644
+--- a/arch/arm/boot/dts/exynos4412-trats2.dts
++++ b/arch/arm/boot/dts/exynos4412-trats2.dts
+@@ -188,7 +188,6 @@
+               i2c9 = &i2c_lps331ap;
+               i2c10 = &i2c_if_pmic;
+               i2c11 = &i2c_fuel;
+-              i2c12 = &i2c_gp2ap020a00f;
+               /* 15...16 reserved for i2c0_isp, i2c1_isp */
+               i2c16 = &i2c1_isp;
+               i2c20 = &i2c_touch_key;
+@@ -491,23 +490,6 @@
+               };
+       };
+-      i2c_gp2ap020a00f: i2c-gpio-2 {
+-              compatible = "i2c-gpio";
+-              gpios = <&gpk1 1 0>, <&gpk2 2 0>;
+-              i2c-gpio,delay-us = <2>;
+-              #address-cells = <1>;
+-              #size-cells = <0>;
+-              status = "okay";
+-
+-              gp2ap002a00f@39 {
+-                      compatible = "gp2ap002a00f";
+-                      reg = <0x39>;
+-                      interrupt-parent = <&gpx0>;
+-                      interrupts = <2 0>;
+-                      vled-supply = <&ps_als_reg>;
+-              };
+-      };
+-
+       i2c_0: i2c@13860000 {
+               samsung,i2c-sda-delay = <100>;
+               samsung,i2c-slave-addr = <0x10>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1292-ARM-dts-fix-base-address-of-sysmmu_tv-for-exynos4.patch b/patches.tizen/1292-ARM-dts-fix-base-address-of-sysmmu_tv-for-exynos4.patch
new file mode 100644 (file)
index 0000000..3d7939e
--- /dev/null
@@ -0,0 +1,36 @@
+From 09087f75e16ca4d24599b7051672ae5847d16ce2 Mon Sep 17 00:00:00 2001
+From: Joonyoung Shim <jy0922.shim@samsung.com>
+Date: Sat, 8 Mar 2014 13:55:56 +0900
+Subject: [PATCH 1292/1302] ARM: dts: fix base address of sysmmu_tv for exynos4
+
+The base address of sysmmu_tv is 0x12E20000, not 0x13E20000. Wrong base
+address problem causes below error when kernel boots.
+
+[    2.450988] Unhandled fault: imprecise external abort (0xc06) at 0xb6fd2068
+
+Change-Id: Icc896d02e25800b18659c66cad853fdbf54cae9c
+Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
+index 751847e..d97dd98 100644
+--- a/arch/arm/boot/dts/exynos4.dtsi
++++ b/arch/arm/boot/dts/exynos4.dtsi
+@@ -647,9 +647,9 @@
+               status = "ok";
+       };
+-      sysmmu_tv: sysmmu@13E20000 {
++      sysmmu_tv: sysmmu@12E20000 {
+               compatible = "samsung,exynos4210-sysmmu";
+-              reg = <0x13E20000 0x1000>;
++              reg = <0x12E20000 0x1000>;
+               interrupt-parent = <&combiner>;
+               interrupt-names = "sysmmu-tv";
+               interrupts = <5 4>;
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1293-ARM-odroidx2-update-defconfig-to-enable-ANDROID_LOGG.patch b/patches.tizen/1293-ARM-odroidx2-update-defconfig-to-enable-ANDROID_LOGG.patch
new file mode 100644 (file)
index 0000000..e6f3b2d
--- /dev/null
@@ -0,0 +1,68 @@
+From 76dd2038da95de855c9d3b666f80f6dd7342727a Mon Sep 17 00:00:00 2001
+From: Joonyoung Shim <jy0922.shim@samsung.com>
+Date: Sat, 8 Mar 2014 14:04:57 +0900
+Subject: [PATCH 1293/1302] ARM: odroidx2: update defconfig to enable
+ ANDROID_LOGGER
+
+ANDROID_LOGGER needs to use dlogutil at tizen.
+
+Change-Id: Ibcad389c6edf8216441948931e9733aa45b04aa1
+Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_odroidx2_defconfig | 39 ++++++++++++++++++++++++++++++-
+ 1 file changed, 38 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/configs/tizen_odroidx2_defconfig b/arch/arm/configs/tizen_odroidx2_defconfig
+index 0a8cce0..7c4d7aa 100644
+--- a/arch/arm/configs/tizen_odroidx2_defconfig
++++ b/arch/arm/configs/tizen_odroidx2_defconfig
+@@ -2384,7 +2384,44 @@ CONFIG_DMA_OF=y
+ #
+ # Microsoft Hyper-V guest support
+ #
+-# CONFIG_STAGING is not set
++CONFIG_STAGING=y
++# CONFIG_USBIP_CORE is not set
++# CONFIG_ECHO is not set
++# CONFIG_COMEDI is not set
++# CONFIG_ASUS_OLED is not set
++# CONFIG_RTLLIB is not set
++# CONFIG_R8712U is not set
++# CONFIG_RTS5139 is not set
++# CONFIG_TRANZPORT is not set
++# CONFIG_VT6656 is not set
++# CONFIG_ZSMALLOC is not set
++# CONFIG_USB_ENESTORAGE is not set
++# CONFIG_BCM_WIMAX is not set
++# CONFIG_FT1000 is not set
++
++#
++# Speakup console speech
++#
++# CONFIG_SPEAKUP is not set
++# CONFIG_TOUCHSCREEN_CLEARPAD_TM1217 is not set
++# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set
++# CONFIG_STAGING_MEDIA is not set
++
++#
++# Android
++#
++CONFIG_ANDROID=y
++# CONFIG_ANDROID_BINDER_IPC is not set
++# CONFIG_ASHMEM is not set
++CONFIG_ANDROID_LOGGER=y
++# CONFIG_ANDROID_TIMED_OUTPUT is not set
++# CONFIG_ANDROID_LOW_MEMORY_KILLER is not set
++# CONFIG_ANDROID_INTF_ALARM_DEV is not set
++# CONFIG_SYNC is not set
++# CONFIG_USB_WPAN_HCD is not set
++# CONFIG_WIMAX_GDM72XX is not set
++# CONFIG_CED1401 is not set
++# CONFIG_DGRP is not set
+ CONFIG_CLKDEV_LOOKUP=y
+ CONFIG_HAVE_CLK_PREPARE=y
+ CONFIG_COMMON_CLK=y
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1294-media-s5p-mfc-Add-support-for-V4L2_MEMORY_DMABUF-typ.patch b/patches.tizen/1294-media-s5p-mfc-Add-support-for-V4L2_MEMORY_DMABUF-typ.patch
new file mode 100644 (file)
index 0000000..3dc5472
--- /dev/null
@@ -0,0 +1,239 @@
+From 74767391fd525554c73b83cb1a3b6c290ab22c33 Mon Sep 17 00:00:00 2001
+From: Seung-Woo Kim <sw0312.kim@samsung.com>
+Date: Fri, 29 Nov 2013 16:57:34 +0900
+Subject: [PATCH 1294/1302] media: s5p-mfc: Add support for V4L2_MEMORY_DMABUF
+ type
+
+There is memory constraint that it should be within 128MB from
+firmware address. But if IOMMU is supported, then this constraint
+is meaningless and DMABUF importing can be used.
+So this patch adds V4L2_MEMORY_DMABUF type support for both decoder
+and encoder.
+
+Change-Id: I2c893da31f906fcd3f26edeed67ad1e4667e6081
+Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
+Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/media/platform/s5p-mfc/s5p_mfc.c        | 12 ++++
+ drivers/media/platform/s5p-mfc/s5p_mfc_common.h |  5 ++
+ drivers/media/platform/s5p-mfc/s5p_mfc_dec.c    | 75 ++++++++++++++++++++-----
+ drivers/media/platform/s5p-mfc/s5p_mfc_enc.c    | 10 ++--
+ 4 files changed, 83 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
+index 264830c..fb11b92 100644
+--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
++++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
+@@ -796,9 +796,15 @@ static int s5p_mfc_open(struct file *file)
+       q->drv_priv = &ctx->fh;
+       if (s5p_mfc_get_node_type(file) == MFCNODE_DECODER) {
+               q->io_modes = VB2_MMAP;
++#ifdef CONFIG_EXYNOS_IOMMU
++              q->io_modes = q->io_modes | VB2_USERPTR | VB2_DMABUF;
++#endif
+               q->ops = get_dec_queue_ops();
+       } else if (s5p_mfc_get_node_type(file) == MFCNODE_ENCODER) {
+               q->io_modes = VB2_MMAP | VB2_USERPTR;
++#ifdef CONFIG_EXYNOS_IOMMU
++              q->io_modes = q->io_modes | VB2_DMABUF;
++#endif
+               q->ops = get_enc_queue_ops();
+       } else {
+               ret = -ENOENT;
+@@ -818,9 +824,15 @@ static int s5p_mfc_open(struct file *file)
+       q->drv_priv = &ctx->fh;
+       if (s5p_mfc_get_node_type(file) == MFCNODE_DECODER) {
+               q->io_modes = VB2_MMAP;
++#ifdef CONFIG_EXYNOS_IOMMU
++              q->io_modes = q->io_modes | VB2_USERPTR | VB2_DMABUF;
++#endif
+               q->ops = get_dec_queue_ops();
+       } else if (s5p_mfc_get_node_type(file) == MFCNODE_ENCODER) {
+               q->io_modes = VB2_MMAP | VB2_USERPTR;
++#ifdef CONFIG_EXYNOS_IOMMU
++              q->io_modes = q->io_modes | VB2_DMABUF;
++#endif
+               q->ops = get_enc_queue_ops();
+       } else {
+               ret = -ENOENT;
+diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
+index ef4074c..ea3ce1b 100644
+--- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
++++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
+@@ -685,4 +685,9 @@ void set_work_bit_irqsave(struct s5p_mfc_ctx *ctx);
+ #define IS_TWOPORT(dev)               (dev->variant->port_num == 2 ? 1 : 0)
+ #define IS_MFCV6(dev)         (dev->variant->version >= 0x60 ? 1 : 0)
++#define s5p_mfc_supported_mem_type(mem)       \
++      ((mem == V4L2_MEMORY_MMAP || \
++       mem == V4L2_MEMORY_USERPTR || \
++       mem == V4L2_MEMORY_DMABUF) ? 1 : 0)
++
+ #endif /* S5P_MFC_COMMON_H_ */
+diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
+index 00b0703..2825727 100644
+--- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
++++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
+@@ -486,10 +486,17 @@ static int vidioc_reqbufs(struct file *file, void *priv,
+       struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+       int ret = 0;
++#ifdef CONFIG_EXYNOS_IOMMU
++      if (!s5p_mfc_supported_mem_type(reqbufs->memory)) {
++              mfc_err("Memory type %d is not supported\n", reqbufs->memory);
++              return -EINVAL;
++      }
++#else
+       if (reqbufs->memory != V4L2_MEMORY_MMAP) {
+               mfc_err("Only V4L2_MEMORY_MAP is supported\n");
+               return -EINVAL;
+       }
++#endif
+       if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               /* Can only request buffers after an instance has been opened.*/
+               if (ctx->state == MFCINST_INIT) {
+@@ -555,23 +562,27 @@ static int vidioc_reqbufs(struct file *file, void *priv,
+                       s5p_mfc_clock_off();
+                       return -ENOMEM;
+               }
+-              if (ctx->dst_bufs_cnt == ctx->total_dpb_count) {
+-                      ctx->capture_state = QUEUE_BUFS_MMAPED;
+-              } else {
+-                      mfc_err("Not all buffers passed to buf_init\n");
+-                      reqbufs->count = 0;
+-                      s5p_mfc_clock_on();
+-                      ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
+-                      s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers,
+-                                      ctx);
+-                      s5p_mfc_clock_off();
+-                      return -ENOMEM;
++              if (reqbufs->memory == V4L2_MEMORY_MMAP) {
++                      if (ctx->dst_bufs_cnt == ctx->total_dpb_count) {
++                              ctx->capture_state = QUEUE_BUFS_MMAPED;
++                      } else {
++                              mfc_err("Not all buffers passed to buf_init\n");
++                              reqbufs->count = 0;
++                              s5p_mfc_clock_on();
++                              ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
++                              s5p_mfc_hw_call(dev->mfc_ops,
++                                              release_codec_buffers, ctx);
++                              s5p_mfc_clock_off();
++                              return -ENOMEM;
++                      }
+               }
+               if (s5p_mfc_ctx_ready(ctx))
+                       set_work_bit_irqsave(ctx);
+               s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
+-              s5p_mfc_wait_for_done_ctx(ctx,
++              if (reqbufs->memory == V4L2_MEMORY_MMAP) {
++                      s5p_mfc_wait_for_done_ctx(ctx,
+                                       S5P_MFC_R2H_CMD_INIT_BUFFERS_RET, 0);
++              }
+       }
+       return ret;
+ }
+@@ -1027,6 +1038,28 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
+       return 0;
+ }
++static int s5p_mfc_buf_prepare(struct vb2_buffer *vb)
++{
++      struct vb2_queue *vq = vb->vb2_queue;
++      struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
++      unsigned int index = vb->v4l2_buf.index;
++
++      if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
++              if (vb2_plane_size(vb, 0) < ctx->luma_size ||
++                      vb2_plane_size(vb, 1) < ctx->chroma_size) {
++                      mfc_err("Plane buffer (CAPTURE) is too small.\n");
++                      return -EINVAL;
++              }
++      } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
++              if (vb2_plane_size(vb, 0) < ctx->dec_src_buf_size) {
++                      mfc_err("Plane buffer (OUTPUT) is too small.\n");
++                      return -EINVAL;
++              }
++      }
++
++      return 0;
++}
++
+ static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count)
+ {
+       struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
+@@ -1098,6 +1131,7 @@ static void s5p_mfc_buf_queue(struct vb2_buffer *vb)
+       struct s5p_mfc_dev *dev = ctx->dev;
+       unsigned long flags;
+       struct s5p_mfc_buf *mfc_buf;
++      int wait_flag = 0;
+       if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               mfc_buf = &ctx->src_bufs[vb->v4l2_buf.index];
+@@ -1115,12 +1149,26 @@ static void s5p_mfc_buf_queue(struct vb2_buffer *vb)
+               list_add_tail(&mfc_buf->list, &ctx->dst_queue);
+               ctx->dst_queue_cnt++;
+               spin_unlock_irqrestore(&dev->irqlock, flags);
++              if ((vq->memory == V4L2_MEMORY_USERPTR ||
++                      vq->memory == V4L2_MEMORY_DMABUF) &&
++                      ctx->dst_queue_cnt == ctx->total_dpb_count)
++                      ctx->capture_state = QUEUE_BUFS_MMAPED;
++
+       } else {
+               mfc_err("Unsupported buffer type (%d)\n", vq->type);
+       }
+-      if (s5p_mfc_ctx_ready(ctx))
++      if (s5p_mfc_ctx_ready(ctx)) {
+               set_work_bit_irqsave(ctx);
++              if ((vq->memory == V4L2_MEMORY_USERPTR ||
++                      vq->memory == V4L2_MEMORY_DMABUF) &&
++                      ctx->state == MFCINST_HEAD_PARSED &&
++                      ctx->capture_state == QUEUE_BUFS_MMAPED)
++                      wait_flag = 1;
++      }
+       s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
++      if (wait_flag)
++              s5p_mfc_wait_for_done_ctx(ctx,
++                              S5P_MFC_R2H_CMD_INIT_BUFFERS_RET, 0);
+ }
+ static struct vb2_ops s5p_mfc_dec_qops = {
+@@ -1128,6 +1176,7 @@ static struct vb2_ops s5p_mfc_dec_qops = {
+       .wait_prepare           = s5p_mfc_unlock,
+       .wait_finish            = s5p_mfc_lock,
+       .buf_init               = s5p_mfc_buf_init,
++      .buf_prepare            = s5p_mfc_buf_prepare,
+       .start_streaming        = s5p_mfc_start_streaming,
+       .stop_streaming         = s5p_mfc_stop_streaming,
+       .buf_queue              = s5p_mfc_buf_queue,
+diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
+index 2549967..6d9d037 100644
+--- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
++++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
+@@ -1040,9 +1040,8 @@ static int vidioc_reqbufs(struct file *file, void *priv,
+       struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+       int ret = 0;
+-      /* if memory is not mmp or userptr return error */
+-      if ((reqbufs->memory != V4L2_MEMORY_MMAP) &&
+-              (reqbufs->memory != V4L2_MEMORY_USERPTR))
++      /* if memory is not mmp, userptr or dmabuf return error */
++      if (!s5p_mfc_supported_mem_type(reqbufs->memory))
+               return -EINVAL;
+       if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+               if (ctx->capture_state != QUEUE_FREE) {
+@@ -1103,9 +1102,8 @@ static int vidioc_querybuf(struct file *file, void *priv,
+       struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+       int ret = 0;
+-      /* if memory is not mmp or userptr return error */
+-      if ((buf->memory != V4L2_MEMORY_MMAP) &&
+-              (buf->memory != V4L2_MEMORY_USERPTR))
++      /* if memory is not mmp, userptr or dmabuf return error */
++      if (!s5p_mfc_supported_mem_type(buf->memory))
+               return -EINVAL;
+       if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+               if (ctx->state != MFCINST_GOT_INST) {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1295-ARM-odroidx2-update-defconfig-to-enable-DRM_EXYNOS_F.patch b/patches.tizen/1295-ARM-odroidx2-update-defconfig-to-enable-DRM_EXYNOS_F.patch
new file mode 100644 (file)
index 0000000..a0a6127
--- /dev/null
@@ -0,0 +1,33 @@
+From f12025a8ab2f8c93a2bcd2bf9c5fc5c35aaf0497 Mon Sep 17 00:00:00 2001
+From: Joonyoung Shim <jy0922.shim@samsung.com>
+Date: Tue, 11 Mar 2014 11:49:32 +0900
+Subject: [PATCH 1295/1302] ARM: odroidx2: update defconfig to enable
+ DRM_EXYNOS_FIMC
+
+DRM_EXYNOS_FIMC needs to use FIMC from DRM.
+
+Change-Id: I854807ae13d356761b68a19860a0d618eb4f14fc
+Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/configs/tizen_odroidx2_defconfig | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/configs/tizen_odroidx2_defconfig b/arch/arm/configs/tizen_odroidx2_defconfig
+index 7c4d7aa..387935c 100644
+--- a/arch/arm/configs/tizen_odroidx2_defconfig
++++ b/arch/arm/configs/tizen_odroidx2_defconfig
+@@ -1919,7 +1919,9 @@ CONFIG_DRM_EXYNOS_FIMD=y
+ CONFIG_DRM_EXYNOS_HDMI=y
+ # CONFIG_DRM_EXYNOS_VIDI is not set
+ # CONFIG_DRM_EXYNOS_G2D is not set
+-# CONFIG_DRM_EXYNOS_IPP is not set
++CONFIG_DRM_EXYNOS_IPP=y
++CONFIG_DRM_EXYNOS_FIMC=y
++# CONFIG_DRM_EXYNOS_ROTATOR is not set
+ # CONFIG_DRM_UDL is not set
+ # CONFIG_DRM_TILCDC is not set
+ # CONFIG_VGASTATE is not set
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1296-ARM-EXYNOS-register-master-power-domain-for-genpd-fr.patch b/patches.tizen/1296-ARM-EXYNOS-register-master-power-domain-for-genpd-fr.patch
new file mode 100644 (file)
index 0000000..02e7e1d
--- /dev/null
@@ -0,0 +1,68 @@
+From 560b021404616a7494c107c1f37f9925c911a6dc Mon Sep 17 00:00:00 2001
+From: Joonyoung Shim <jy0922.shim@samsung.com>
+Date: Tue, 11 Mar 2014 13:44:20 +0900
+Subject: [PATCH 1296/1302] ARM: EXYNOS: register master power domain for genpd
+ from DT
+
+There is one case for EXYNOS4412 that mixer needs LCD0 power domain as
+well as TV power domain. If disable LCD0 power domain, mixer occurs
+underflow of mixer graphic layer0 line buffer and we can't output normal
+data from hdmi. I don't know why mixer has dependency of LCD0 power
+domain.
+
+We can control the dependency as LCD0 power domain register to master of
+TV power domain on genpd framework.
+
+Change-Id: I71ef5bba37393d2e00c4dd7ea3f7da09d72e8db7
+Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412.dtsi |  4 ++++
+ arch/arm/mach-exynos/pm_domains.c | 11 +++++++++++
+ 2 files changed, 15 insertions(+)
+
+diff --git a/arch/arm/boot/dts/exynos4412.dtsi b/arch/arm/boot/dts/exynos4412.dtsi
+index b0fde4a..bf78f61 100644
+--- a/arch/arm/boot/dts/exynos4412.dtsi
++++ b/arch/arm/boot/dts/exynos4412.dtsi
+@@ -86,4 +86,8 @@
+               phy-names = "hdmiphy";
+               compatible = "samsung,exynos5-hdmi";
+       };
++
++      mixer: mixer@12C10000 {
++              samsung,power-domain-master = <&pd_lcd0>;
++      };
+ };
+diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c
+index 435e396..5a7eb8ec 100644
+--- a/arch/arm/mach-exynos/pm_domains.c
++++ b/arch/arm/mach-exynos/pm_domains.c
+@@ -124,6 +124,7 @@ static void exynos_read_domain_from_dt(struct device *dev)
+ {
+       struct platform_device *pd_pdev;
+       struct exynos_pm_domain *pd;
++      struct exynos_pm_domain *master_pd;
+       struct device_node *node;
+       node = of_parse_phandle(dev->of_node, "samsung,power-domain", 0);
+@@ -134,6 +135,16 @@ static void exynos_read_domain_from_dt(struct device *dev)
+               return;
+       pd = platform_get_drvdata(pd_pdev);
+       exynos_add_device_to_domain(pd, dev);
++
++      /* make master and slave hierarchy */
++      node = of_parse_phandle(dev->of_node, "samsung,power-domain-master", 0);
++      if (!node)
++              return;
++      pd_pdev = of_find_device_by_node(node);
++      if (!pd_pdev)
++              return;
++      master_pd = platform_get_drvdata(pd_pdev);
++      pm_genpd_add_subdomain(&master_pd->pd, &pd->pd);
+ }
+ static int exynos_pm_notifier_call(struct notifier_block *nb,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1297-ARM-dts-odroidx2-remove-fimd-node.patch b/patches.tizen/1297-ARM-dts-odroidx2-remove-fimd-node.patch
new file mode 100644 (file)
index 0000000..8640926
--- /dev/null
@@ -0,0 +1,56 @@
+From 8bb430b75ff8ada5e3b666169f391badd5d84ffd Mon Sep 17 00:00:00 2001
+From: Joonyoung Shim <jy0922.shim@samsung.com>
+Date: Tue, 11 Mar 2014 14:07:29 +0900
+Subject: [PATCH 1297/1302] ARM: dts: odroidx2: remove fimd node
+
+Our odroidx2 board doesn't have any LCD panel, so it is unnecessary to
+use fimd.
+
+Change-Id: I1924ee52cd34d5763aab989035c51b387de98311
+Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ arch/arm/boot/dts/exynos4412-odroidx2.dts | 27 ---------------------------
+ 1 file changed, 27 deletions(-)
+
+diff --git a/arch/arm/boot/dts/exynos4412-odroidx2.dts b/arch/arm/boot/dts/exynos4412-odroidx2.dts
+index d3339fd..bf9b204 100644
+--- a/arch/arm/boot/dts/exynos4412-odroidx2.dts
++++ b/arch/arm/boot/dts/exynos4412-odroidx2.dts
+@@ -568,33 +568,6 @@
+               vdd_pll-supply = <&ldo8_reg>;
+               status = "okay";
+       };
+-
+-      /*
+-       * FIMD node is required for DRM subsystem to initialize framebuffer
+-       * It should be considered as hack until DRM/HDMI subsystem is fixed
+-       */
+-      fimd@11c00000 {
+-              samsung,fimd-vidout-rgb;
+-              samsung,fimd-inv-vclk;
+-              samsung,fimd-frame-rate = <60>;
+-              samsung,default-window = <3>;
+-              samsung,fimd-win-bpp = <32>;
+-              status = "okay";
+-              display-timings {
+-                      native-mode = <&timing0>;
+-                      timing0: timing {
+-                              clock-frequency = <0>;
+-                              hfront-porch = <0>;
+-                              hback-porch = <0>;
+-                              hactive = <1920>;
+-                              vactive = <1080>;
+-                              hsync-len = <0>;
+-                              vback-porch = <0>;
+-                              vfront-porch = <0>;
+-                              vsync-len = <0>;
+-                      };
+-              };
+-      };
+ };
+ &pinctrl_1 {
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1298-extcon-max77693-Fix-inaccurate-extcon-event-for-JIG-.patch b/patches.tizen/1298-extcon-max77693-Fix-inaccurate-extcon-event-for-JIG-.patch
new file mode 100644 (file)
index 0000000..4cd2d80
--- /dev/null
@@ -0,0 +1,66 @@
+From 36bdb901c8c61448d9e1320641c3debebde03321 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Mon, 17 Mar 2014 17:44:06 +0900
+Subject: [PATCH 1298/1302] extcon: max77693: Fix inaccurate extcon event for
+ JIG with USB cable
+
+Dmitry's patch 'extcon: max77693: Force using UART~' fixes problem when
+device is connected JIG with USB cable. However, with the patch, driver
+sends inaccurate event "USB" even muic keeps path to UART not USB. This
+would make users confused.
+
+This patch keeps Dmitry's modification working and also bypasses signaling
+event "USB" when device is connected to JIG with USB cable.
+
+Change-Id: Ia5f3328e5b0827378178502c70cb90da48e9e3f7
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/extcon/extcon-max77693.c | 23 ++++++++++++-----------
+ 1 file changed, 12 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c
+index 903c507..b08a1e8 100644
+--- a/drivers/extcon/extcon-max77693.c
++++ b/drivers/extcon/extcon-max77693.c
+@@ -293,18 +293,10 @@ static int max77693_muic_set_path(struct max77693_muic_info *info,
+               return ret;
+       }
+-      if (attached) {
+-              if (info->prev_cable_type ==
+-                  MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF) {
+-                      /* if cable_type is jig, then force UART */
+-                      dev_info(info->dev, "For jig force using UART path\n");
+-                      ctrl1 = CONTROL1_SW_UART;
+-              } else {
+-                      ctrl1 = val;
+-              }
+-      } else {
++      if (attached)
++              ctrl1 = val;
++      else
+               ctrl1 = CONTROL1_SW_OPEN;
+-      }
+       ret = max77693_update_reg(info->max77693->regmap_muic,
+                       MAX77693_MUIC_REG_CTRL1, ctrl1, COMP_SW_MASK);
+@@ -922,6 +914,15 @@ static int max77693_muic_chg_handler(struct max77693_muic_info *info)
+                        */
+                       break;
+               case MAX77693_CHARGER_TYPE_USB:
++                      /* If UART is still connected, do not set path to USB */
++                      if (cable_type == MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF) {
++                              ret = max77693_muic_set_path(info, info->path_uart,
++                                                  attached);
++                              if (ret < 0)
++                                      return ret;
++                              break;
++                      }
++
+                       /* Only USB cable, PATH:AP_USB */
+                       ret = max77693_muic_set_path(info, info->path_usb, attached);
+                       if (ret < 0)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1299-Revert-extcon-max77693-Fix-inaccurate-extcon-event-f.patch b/patches.tizen/1299-Revert-extcon-max77693-Fix-inaccurate-extcon-event-f.patch
new file mode 100644 (file)
index 0000000..db3c9e2
--- /dev/null
@@ -0,0 +1,61 @@
+From 493f719cc607e205bb9257f8f90e5cc0969054f7 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Wed, 19 Mar 2014 00:41:04 +0900
+Subject: [PATCH 1299/1302] Revert "extcon: max77693: Fix inaccurate extcon
+ event for JIG with USB cable"
+
+This reverts commit 36bdb901c8c61448d9e1320641c3debebde03321.
+Upcoming patch will fix a bug thus all related workaournds are now purged.
+
+Change-Id: Idafdbcadff0d99320502676ef371d6bc0bd1fcf7
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/extcon/extcon-max77693.c | 23 +++++++++++------------
+ 1 file changed, 11 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c
+index b08a1e8..903c507 100644
+--- a/drivers/extcon/extcon-max77693.c
++++ b/drivers/extcon/extcon-max77693.c
+@@ -293,10 +293,18 @@ static int max77693_muic_set_path(struct max77693_muic_info *info,
+               return ret;
+       }
+-      if (attached)
+-              ctrl1 = val;
+-      else
++      if (attached) {
++              if (info->prev_cable_type ==
++                  MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF) {
++                      /* if cable_type is jig, then force UART */
++                      dev_info(info->dev, "For jig force using UART path\n");
++                      ctrl1 = CONTROL1_SW_UART;
++              } else {
++                      ctrl1 = val;
++              }
++      } else {
+               ctrl1 = CONTROL1_SW_OPEN;
++      }
+       ret = max77693_update_reg(info->max77693->regmap_muic,
+                       MAX77693_MUIC_REG_CTRL1, ctrl1, COMP_SW_MASK);
+@@ -914,15 +922,6 @@ static int max77693_muic_chg_handler(struct max77693_muic_info *info)
+                        */
+                       break;
+               case MAX77693_CHARGER_TYPE_USB:
+-                      /* If UART is still connected, do not set path to USB */
+-                      if (cable_type == MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF) {
+-                              ret = max77693_muic_set_path(info, info->path_uart,
+-                                                  attached);
+-                              if (ret < 0)
+-                                      return ret;
+-                              break;
+-                      }
+-
+                       /* Only USB cable, PATH:AP_USB */
+                       ret = max77693_muic_set_path(info, info->path_usb, attached);
+                       if (ret < 0)
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1300-Revert-extcon-max77693-Force-using-UART-path-for-jig.patch b/patches.tizen/1300-Revert-extcon-max77693-Force-using-UART-path-for-jig.patch
new file mode 100644 (file)
index 0000000..e19017a
--- /dev/null
@@ -0,0 +1,45 @@
+From 16a29892a94a6addcf6817c2e1256d9fd4e4dfb9 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Wed, 19 Mar 2014 00:41:20 +0900
+Subject: [PATCH 1300/1302] Revert "extcon: max77693: Force using UART path for
+ jig"
+
+This reverts commit ec05e8de55043b87a1dafccec5477db9a6ecf9a1.
+Upcoming patch will fix a bug thus all related workaournds are now purged.
+
+Change-Id: I52b4456867dd887c7d29a4f485c952860c6dc45c
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/extcon/extcon-max77693.c | 14 +++-----------
+ 1 file changed, 3 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c
+index 903c507..3cde41b4 100644
+--- a/drivers/extcon/extcon-max77693.c
++++ b/drivers/extcon/extcon-max77693.c
+@@ -293,18 +293,10 @@ static int max77693_muic_set_path(struct max77693_muic_info *info,
+               return ret;
+       }
+-      if (attached) {
+-              if (info->prev_cable_type ==
+-                  MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF) {
+-                      /* if cable_type is jig, then force UART */
+-                      dev_info(info->dev, "For jig force using UART path\n");
+-                      ctrl1 = CONTROL1_SW_UART;
+-              } else {
+-                      ctrl1 = val;
+-              }
+-      } else {
++      if (attached)
++              ctrl1 = val;
++      else
+               ctrl1 = CONTROL1_SW_OPEN;
+-      }
+       ret = max77693_update_reg(info->max77693->regmap_muic,
+                       MAX77693_MUIC_REG_CTRL1, ctrl1, COMP_SW_MASK);
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1301-Revert-extcon-max77693-Fix-bug-related-to-MAX77693-i.patch b/patches.tizen/1301-Revert-extcon-max77693-Fix-bug-related-to-MAX77693-i.patch
new file mode 100644 (file)
index 0000000..35f7bb3
--- /dev/null
@@ -0,0 +1,47 @@
+From 50122f3e5a56ec3ebf17e89ec870fbcee0fb5939 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Wed, 19 Mar 2014 00:41:36 +0900
+Subject: [PATCH 1301/1302] Revert "extcon: max77693: Fix bug related to
+ MAX77693 irq when set ADC debounce time"
+
+This reverts commit b64315125400f4eec9f74f7536acca3e8eeca720.
+Upcoming patch will fix a bug thus all related workaournds are now purged.
+
+Change-Id: Iab88c25ef9470a5167be73990ceb7859e076ddd8
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/extcon/extcon-max77693.c | 10 +---------
+ 1 file changed, 1 insertion(+), 9 deletions(-)
+
+diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c
+index 3cde41b4..077296d 100644
+--- a/drivers/extcon/extcon-max77693.c
++++ b/drivers/extcon/extcon-max77693.c
+@@ -285,14 +285,6 @@ static int max77693_muic_set_path(struct max77693_muic_info *info,
+       int ret = 0;
+       u8 ctrl1, ctrl2 = 0;
+-      /* Set open state to path before changing hw path */
+-      ret = max77693_update_reg(info->max77693->regmap_muic,
+-              MAX77693_MUIC_REG_CTRL1, CONTROL1_SW_OPEN, COMP_SW_MASK);
+-      if (ret < 0) {
+-              dev_err(info->dev, "failed to update MUIC register\n");
+-              return ret;
+-      }
+-
+       if (attached)
+               ctrl1 = val;
+       else
+@@ -1254,7 +1246,7 @@ static int max77693_muic_probe(struct platform_device *pdev)
+       }
+       /* Set initial path for UART */
+-      max77693_muic_set_path(info, info->path_uart, true);
++       max77693_muic_set_path(info, info->path_uart, true);
+       /* Check revision number of MUIC device*/
+       ret = max77693_read_reg(info->max77693->regmap_muic,
+-- 
+1.8.3.2
+
diff --git a/patches.tizen/1302-extcon-max77693-Fix-a-bug-occured-at-changing-ADC-de.patch b/patches.tizen/1302-extcon-max77693-Fix-a-bug-occured-at-changing-ADC-de.patch
new file mode 100644 (file)
index 0000000..596f34b
--- /dev/null
@@ -0,0 +1,52 @@
+From 7464f7e4fed02c10aa619746890bdd96b1b43fc3 Mon Sep 17 00:00:00 2001
+From: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Date: Wed, 19 Mar 2014 00:55:10 +0900
+Subject: [PATCH 1302/1302] extcon: max77693: Fix a bug occured at changing ADC
+ debounce time.
+
+During the initialzation of max77693 muic device, it has been suffered from
+abnormal interrupt and accidental reset of certain register when it changes
+ADC debounce time. All these happens occured by mistakenly writing some value
+to BLTDset and JIGset from CONTROL3 register.
+BLTDset and JIGset are not configurable and only reflect actual pin status.
+If you write some value other than 0 to them, muic device will return false
+information.
+
+To set ADC debounce time properly, give 0 to BLTDset and JIGset when writing
+CONTORL3 register.
+
+Previous workaround patches are now purged.
+
+Change-Id: If87e01785115d460b1153e24271a50125d1631fb
+Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
+Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
+---
+ drivers/extcon/extcon-max77693.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c
+index 077296d..f29148b 100644
+--- a/drivers/extcon/extcon-max77693.c
++++ b/drivers/extcon/extcon-max77693.c
+@@ -252,10 +252,15 @@ static int max77693_muic_set_debounce_time(struct max77693_muic_info *info,
+       case ADC_DEBOUNCE_TIME_10MS:
+       case ADC_DEBOUNCE_TIME_25MS:
+       case ADC_DEBOUNCE_TIME_38_62MS:
+-              ret = max77693_update_reg(info->max77693->regmap_muic,
++              /*
++               * Don't touch BTLDset, JIGset when you want to change adc
++               * debounce time. BTLDset, JIGset reflects actual pin status
++               * and are not configurable.
++               */
++              ret = max77693_write_reg(info->max77693->regmap_muic,
+                                         MAX77693_MUIC_REG_CTRL3,
+-                                        time << CONTROL3_ADCDBSET_SHIFT,
+-                                        CONTROL3_ADCDBSET_MASK);
++                                        ((time << CONTROL3_ADCDBSET_SHIFT) &
++                                        CONTROL3_ADCDBSET_MASK));
+               if (ret) {
+                       dev_err(info->dev, "failed to set ADC debounce time\n");
+                       return ret;
+-- 
+1.8.3.2
+